Index: tags/2.3.0/AUTHORS =================================================================== --- tags/2.3.0/AUTHORS (nonexistent) +++ tags/2.3.0/AUTHORS (revision 33253) @@ -0,0 +1,12 @@ +pcb-rnd maintainer: Tibor 'Igor2' Palinkas +contact: http://repo.hu/projects/pcb-rnd/contact.html + +An always up-to-date list of developers and contributors can be found at +http://repo.hu/cgi-bin/pcb-rnd-people.cgi + +PCB was originally written by Thomas Nau +Development was later taken over by harry eaton +The port to GTK was done by Bill Wilson +Dan McMahill converted the build system from imake to autoconf/automake. +DJ Delorie wrote the trace optimizer, added symbolic flag support and +many other improvements. Index: tags/2.3.0/COPYING =================================================================== --- tags/2.3.0/COPYING (nonexistent) +++ tags/2.3.0/COPYING (revision 33253) @@ -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/2.3.0/Changelog =================================================================== --- tags/2.3.0/Changelog (nonexistent) +++ tags/2.3.0/Changelog (revision 33253) @@ -0,0 +1,417 @@ +pcb-rnd 2.3.0 (r33250/r32452) +~~~~~~~~~~~~~~~~~~~~~~ +pcb-rnd part: + + [act_draw] + -Cleanup: remove global PCB dependency + + [act_read] + -Cleanup: remove global PCB dependency + -Add: idplist(print) + + [asm] + -Add: menu for the feature plugin + + [ch_editpoint] + -Add: plugin to indicate object editpoints and terminal names on hover + + [ch_onpoint] + -Cleanup: don't calculate arc endpoints locally, call the dedicated function + -Cleanup: move onpoint object lists from core/crosshair to ch_onpoint + -Move: onpoint related code from core to plugin ch_onpoint to make core smaller and cleaner + -Fix: don't crash if there's no tool + -Add: allow indication only for tools that can edit geometry + + [core] + -Cleanup: use vtp0 and pcb_any_obj_t for on-point highlight instead of a locally defined type+obj* struct to reduce code size (pcb_any_obj_t has a type field) + -Cleanup: on-point: DrawLineOrArc(): don't need to pass type+obj, pcb_any_obj_t does include the type + -Cleanup: on-point: DrawLineOrArc(): no need to do trickery with the layer argument, lines and arcs do remember their parent layers in pcb_any_obj_t + -Cleanup: on-point: make DrawLineOrArc() static - needed by onpoint only; rename to remove CamelCase + -Cleanup: decouple pcb_board_set_changed_flag() from PCB, adding a pcb_board_t * context pointer first arg + -Cleanup: remove global PCB dependency from padstack actions + -Cleanup: remove global PCB dependency from conf actions + -Cleanup: remove global PCB dependency from font actions + -Cleanup: remove global PCB dependency from file actions + -Cleanup: pcb_xordraw_movecopy() grew too large, split it up to a per object type function + -Cleanup: onpoint indication should be an obj common bit, not a flag - it's temporary data never to be saved + -Fix: get low level text scale X,Y change undoable + -Fix: make ChangePinName() undoable + -Fix: make ChangeNonetlist() undoable + -Fix: padstack undoable change hole shall call the proto updater to keep caches and hashes in sync + -Fix: arc wireframe draw: never call the hid with negative radius (that resulted in artifacts) + -Fix: RouteStyle() action help text did not reflect how the code worked + -Fix: route style: text scale is really an int, not a coord + -Fix: hole diameter change in padstack op shouldn't use old drc setting to limit minimum size; the padstack editor and the property editor already allows the user to set any size, don't do arbitrary limiting here either + -Fix: pcb_text_draw_string_simple() shall set up xform and info to avoid crash + -Fix: don't crash on pcb==NULL in text mirroring in buffer + -Fix: don't use PCB from some actions, that's not available while new board is created + -Fix: move crosshair out to the limit before removing the old board - this should trigger all ch_ plugins to release their old data, to avoid stale pointers + -Fix: drc print: don't print measured or expected value if it is FGW_INVALID + -Fix: when removing/destroying a polygon, remove it from parent subc term list + -Fix: footprint parameter split: find and remove the trailing ')' even if there are spaces after it + -Fix: set rendering to positive before drawing the fab layer (might be the first thing drawn on an empty board) + -Fix: ChangeFlag doesn't have thermal anymore (thermal is not a flag bit) + -Fix: SetThermal() with value non-zero should also turn on thermal + -Fix: update library entry parent after sort or array relocation so it doesn't point to invalid/free'd memory + -Fix: clear_buffer should reset buffer origin as well so it is not inherited between operations + -Fix: new board creation crosshair state mismatch caused sw render HIDs to lose xor draw after creating a new board + -Fix: low level label draw: separate x and y text mirroring is possible now, use it (fixes ctrl+tab text mirror bug) + -Fix: turn off clearance optimization for line/arc/poly vs. poly intersection check if bloat != 0 (it caused shorts missed) + -Fix: make subc flag change undoable (affects the lock tool) + -Fix: SetThermal(): wrong description on the meaning of the numeric style values + -Fix: SetThermal(): allow value 6 as well + -Fix: pcb_net_find_by_obj() shouldn't crash on a terminal whose subc has no refdes attribute + -Update: default boards are of lihata board v7, so plain save will not downgrade new boards to v6 + -Change: use style clearance for 'show drc clearance' instead of bloat + -Change: conf field descriptions of the old DRC fields, which are now either obsolete or repurposed to limiting sizes + -Add: tool infra: flag to mark tools that can edit object geometry + -Add: generic, undoable attribute set function + -Add: generalized subc layer allocation based on copying an existing subc layer + -Add: respect rnd_render's ->override_render so loghid works + -Add: padstack proto update makes a cache in tr[0] about which shapes are connected to the hole or slot + -Add: padstack proto update calculates a cached prototype bit that indicates if all copper shapes are connected by the hole/slot + -Add: RouteStyle(): undoable on set + -Add: RouteStyle(): undoable route style name change (and query) + -Add: RouteStyle(): commands for setting and querying text scale and text thickness + -Add: RouteStyle(): undoable new and del commands + -Add: extend the footprint API with an option for copying tags + -Add: plug_io for saving and loading padstacks + -Add: crosshair code: build a cache for attached object drawing: publish a clean() function that needs to be called before any crosshair attached object change so a cache can be maintained + -Add: if a polygon has the clearpolypoly flag and showing the clearance is enabled, calculate the clearance offset poly and draw it while the poly is being moved or copied + -Add: polygon helper: calculate the clearance polygon of a text object, without subtracting it + -Add: when a text object is being moved, indicate the true clearance when clearance indication is on + -Add: draw the clearance (union on all copper layers) around the padstack when it's being moved + -Add: throw an error if no drc rule got executed + -Add: crosshair: generate an event for updating screen indications when crosshair changed position + -Add: editpoint indication on line, arc, polygon, padstack objects + -Add: layer pointer to ID conversion (helper function) + -Add: in-place subc replacement: keep thermal flags on terminals (map and apply thermals) + -Add: subc in-place replacement: make a map of floaters, attempt to match them up and move/rotate new floaters accordingly + -Add: find.c: publish low level pcb_isc_pstk_line_shp(), lib_polyhelp needs it for hole-on-contour + -Add: find.c: padstack shape to polyarea converter (helper function) + -Add: SetThermal(): support the 'noshape' style + + [dialogs] + -Del: preferences: half of the old DRC sizes - use the new DRC definitions + -Cleanup: rename DRC sizes to limit sizes in the code to reflect change in the code logic + -Fix: flag changes from the flag edit dialog are undoable + -Fix: when the padstack editor changes the hole or local clearance in a prototype, make sure the prototype is updated (for the hash and caches) + -Fix: padstack proto save file name memory leak + -Fix: library dialog, refresh button: print an error message if parent/root can not be found + -Fix: don't crash when library window preview is called with NULL footprint name (may be a result of a broken parametric footprint), just clean the buffer so that nothing is shown in the preview + -Fix: dlg_confval_edit(): uninitialized default value for optional argument 'modal' (may cause crash on drc definition edit) + -Change: merge limiting sizes and misc sizes, by now they are the same as limiting sizes are no longer DRC-related + -Add: padstack lib dialog: load and save buttons for padstack prototypes + -Add: default file name for padtsack save is padstack.lht + -Add: preferences, sizes&drc: print an error message if there is 0 drc plugins available + -Add: convert the manage plugins dialog into a non-modal dialog box that presents an alphabetically sorted list of plugins in a list + -Add: manage plugins: button for unloading plugins + -Add: plugins dialog: print reference count of each plugin (useful for debugging) + -Add: make layer comb flag change undoable + + [doc] + -Fix: packager's doc: grammar about diagnosing (in package desc); missing punctuation in package desc + -Fix: use both pcb-rnd's own plugins and librnd's svn extern'd plugins when mapping for packager's doc + -Fix: plated slots can be represented already + -Update: renumberblock description for subcircuits + -Update: conf tree for the drc "show/enforce" change + -Add: mention imagemagick as soft dependency for running some tests + -Add: clarify what ChangeSize() does to subcircuits + -Add: action doc for RouteStyle(); document 'del' and 'new' + -Add: document the low level ttf import action + -Add: lihata format doc: document the new file format for padstack protos: pcb-rnd-subcircuit-v* + -Add: developer doc: plugin development howto for local, per plugin menu files + -Add: query: document coord(), netlen(), isvoid(), layer_setup(), int(), double() and .net + -Add: query: document user functions + -Add: refine the nonetlist flag sentence explaining the actual effects + -Add: explain how openscad-transformation attribute is not used for subcircuit rotation + -Add: INSTALL references the packaging doc - maybe this will help new packagers figure where to look + -Add: link regex syntax from the appendix and from the feature doc + + [drc_query] + -Fix: invalid drc value is FGW_INVALID, not FGW_VOID + -Fix: action that sets drc def should create the conf node and set the default value even tho the def is created in multiple steps when done in actions + -Fix: make sure definition default value is set only once, not overwriting exisitng value + -Add: refine stock drc rule violation report with expected/measured values + + [export_openscad] + -Fix: respect options set from the GUI + + [export_stl] + -Fix: do not apply holes/slots that fall on the board contour, that'd result in invalid model + -Fix: use clipped contour poly instead of the as-drawn one, so all sort of tweaks (like half-hole cutouts) appear in the output + + [export_test] + -Del: plugin removed in favor of the more generic loghid plugin (in librnd): the actual sequence of calls HID heavily depends on the do_export() implementation of the GUI/export hid chosen, so even if export_test worked, it would not have shown the same sequence as any actual export/screen-render + + [extobj] + -Cleanup: remove code duplication on subc layer object copy + -Cleanup: use the central subc layer allocation helper function instead of a local implementation + -Fix: handle buffer copy/cut/move corner case: make sure the subcircuit is not added to the rtree twice + -Fix: when (all) floaters are selected, also select the parent subc so it can be copied/moved to the buffer + + [find] + -Cleanup: remove direct fctx->mark mark test and sets where it matters: wrap them in inline functions so they can be extended for the multi-component objects + -Fix: don't assume hole/slot connection within a padstack if the hole/slot is not plated; special case: if term ID is set on a padstack with disjoint copper shapes, it should be taken as connected; rationale: each shape has the same terminal ID and we generally assume same-terminal-IDs are connected within the part soldered on + -Add: make the padstack shape vs. padstack shape intersection (geo code) API public, padstack prototype code caching the shape overlaps with holes will need it + -Add: maintain a multimark hash table in find context and allocate it for padstacks when needed (when not all copper shapes are connected) + + [font] + -Fix: when unlinking a font (e.g. for fontedit()), re-link the parent of all symbol arcs and polys to avoid invalid ref + + [fp_fs] + -Add: configurable prefix based file name ignores on lib mapping + -Add: suffix based file name ignore from config (during lib mapping) + + [gsch2pcb-rnd] + -Fix: wrong program name in help text + + [import_accel_net] + -Add: atomic netlist import: undo undoes all at once + + [import_calay] + -Add: atomic netlist import: undo undoes all at once + + [import_fpcb_nl] + -Add: atomic netlist import: undo undoes all at once + + [import_gnetlist] + -Add: atomic netlist import: undo undoes all at once + + [import_ipcd356] + -Add: atomic netlist import: undo undoes all at once + + [import_ltspice] + -Add: atomic netlist import: undo undoes all at once + + [import_mentor_sch] + -Add: atomic netlist import: undo undoes all at once + + [import_net_action] + -Add: atomic netlist import: undo undoes all at once + + [import_net_cmd] + -Fix: don't crash if there's no board file name available + -Add: atomic netlist import: undo undoes all at once + + [import_netlist] + -Add: atomic netlist import: undo undoes all at once + + [import_orcad_net] + -Add: atomic netlist import: undo undoes all at once + + [import_pads_net] + -Add: atomic netlist import: undo undoes all at once + + [import_protel_net] + -Add: atomic netlist import: undo undoes all at once + + [import_pxm_pnm] + -Add: pick up transparent color from custom "transparent pixel:" comment when present + + [import_sch2] + -Add: atomic netlist import: undo undoes all at once (wrapper around any format/method) + + [import_tinycad] + -Add: atomic netlist import: undo undoes all at once + + [import_ttf] + -Add: Erich's patch on cubic + -Add: action, dialog box and menu item for the dialog for interactive glyph import + -Add: handle self-intersecting poly contours + + [io_kicad] + -Fix: segfault on redundant arc removal vs. term attribute set + -Fix: apply poly clipping inhibit around board parse to speed up + + [io_lihata] + -Cleanup: read: group all global states in a struct (reduce global vars) + -Cleanup: read: do not depend on a global variable for the context, pass the read context struct down in every call that needs it + -Fix: do not accept negative arc radius on load, change it to 0 and throw an error + -Fix: buffer load shall set read version from the header, else padstacks won't work (as they did not exist in v1) + -Update: make v7 the default format to use by extedit + -Add: save padstack file: write a new header and the padstack proto subtree with ID 0 + -Add: parse pcb-rnd-padstack-v* for the padstack proto in it + + [io_pcb] + -Add: long, detailed error message about non-undoable layer swaps + -Add: io incompatibility warning for non-mod-90-degree text rotation + + [io_tedax] + -Fix: clip poly before saving it in a footprint, to avoid a crash + -Fix: error message on loading footprint objects on invalid layer + -Fix: footprint load: throw an error on invalid objects + -Fix: off-by-one bug on footprint polygon minimum number of fields + -Fix: footprint terminal ID doesn't need to be an integer, it can be any string + -Fix: allow trailing \\ when parsing lines + -Fix: when called back from plug_footprint to load a footprint from the lib, use the lib fopen to apply the search path + -Fix: \ parsing corner case on last escaped char in a field + -Add: atomic netlist import: undo undoes all at once + + [lib_compat_help] + -Fix: layer swap, used only by old geda/pcb save on silk not being the last layer, should also update padstack thermals + + [lib_hid_pcbui] + -Fix: route style: text scale is really an int, not a coord + -Fix: don't assume sizeof(int) == sizeof(long) + -Fix: don't use PCB, that's not available while new board is created + -Add: make route style field changes undoable (except for obsolete via fields) + -Add: make style name change timed so it's less frequent + -Add: make route style dialog name changes undoable + -Add: make del and new buttons on the route style docked dialog undoable + -Add: icon buttons for all layer visible/invisible + + [lib_polyhelp] + -Cleanup: use pcb_board_set_changed_flag() instead of directly setting the changed flag + -Fix: contour-to-poly: don't crash if board contour is not found, just return NULL + -Add: contour to poly conversion: find and mark padstacks crossing the poly contour + -Add: subtract intersecting holes and slots from board contour poly + + [libcdtr] + -Fix: make local tester compilable + -Fix: make local Makefile portable + -Fix: make coord type configurable + -Add: license banner: LGPL2 with permission from Wojciech via email + -Add: make clean + -Add: proper object deps in local compilation + -Add: rule to compile a .a + + [librnd] + -Cleanup: remove per plugin svn extern to librnd, use one, central extern + -Del: local copy of map_plugins - use librnd's + -Del: local scconfig templates for the build - use librnd's + -Del: rnd_r_end() - dummy call to empty function, the iterator doesn't allocate anything + -Move: box direction enum and macros to from librnd to local box_dir.h (needed by autoplace and autorouter only) + + [menu] + -Fix: buffer content load, {b f l}, should clear the buffer before the load so only the new content is in the buffer by the end of the operation + -Change: we don't enforce/show DRC clearance but style clearance + -Add: {e g g} for padstack geometry edit + -Add: {l v} and {l h} for all layer visible/inivisible + -Add: convert-to-extobj in context popup for layer objects + + [openscad] + -Move: Alexey's smd diode and tantalum models from work to the standard lib + -Add: pcblib footprints reference their openscad models + + [pcblib] + -Fix: make sure silkmark never writes arc with negative radius (or even close to zero) + + [propedit] + -Fix: make flag changes undoable + -Fix: throw an error for invalid prop path (missing p/ or a/ prefix) so the user has a chance to figure + -Fix: layer comb property didn't get set + -Fix: layer comb bits are not integers but booleans + + [puller] + -Fix: don't use the bbox but corners of poly shaped padstacks for tighter pulling + -Fix: use the true shape for line padstacks (both square and round cap) for tight pulling + + [qparse] + -Fix: wrong fsf address in license banner + + [query] + -Fix: type promotion bug between long and double + -Fix: violation() returns numeric values properly + -Fix: advanced search dialog missing object types: padstack, subc, gfx + -Fix: advanced search dialog: gui->text string creation: use quotes + -Add: coord() function that attempts to convert a string to coordinates (useful for reading coords from attributes) + -Add: (cached) netlen() function that works by netname or by net object (requires simple, 2-terminal networks) + -Add: isvoid() function for safe check if a value (e.g. function return value) is invalid/void + -Add: user functions + -Add: qry_run_() passes back last evaluation result as the final result if the caller needs it + -Add: list() works on any variable, not only on @ + -Add: .net evaluates to the net parent of an object + -Add: layer_setup() for checking the layer stack around an object + -Add: allow any expression to be suffixed with fields/attributes - relevant for user function returns + -Add: .layergroup for layer objects + -Add: int() + -Add: double() + + [renumber] + -Fix: missing action descriptions + + [rubberband_orig] + -Change: use style clearance for 'show drc clearance' instead of bloat + + [scconfig] + -Change: move librnd extern from src/ and scconfig/ in a common single extern in src_3rd/ + -Fix: don't assume libs/ldl exists (it doesn't, on windows) + + [script] + -Fix: delay permascript loading until the main loop has started - premature loading of scripts will lead to script compilation error since not all actions are registered + + [shape] + -Add: menu for the feature plugin + + [tests] + -Fix: RTT: handle missing convert(1) or compare(1) by really skipping the corresponding tests + -Del: librnd test - it's in the now separate librnd project + -Add: menu patch automated testing: typical plugin insertion in sumbenu and at anchor, overwrites + + [tool_std] + -Fix: rat lines can be drawn from/to heavy terminal too, not only padstacks + -Fix: shift-click in-place footprint replacement from buffer shall keep rotation and side of the original footprint + -Fix: thermal tool should work when clicking on subc padstack + -Fix: changing the lock state of an object shall mark the board changed + -Fix: tool_move calls extobj float_pre and float_geo in pair so the extended object is not messed up + -Fix: escape in arc and rectangle tools shouldn't immediately switch to the arrow tool but first fall back to the arc or rectangle initial state + -Fix: lock: increase undo serial after locking/unlocking so they don't batch with random other operations + -Change: use style clearance for 'show drc clearance' instead of bloat + -Add: thermal tool: better fallback mechanism on multiple objects found and indicate if didn't do anything because all candidates were locked + + + +librnd part: + + [librnd/build] + -Del: tests left over from pcb-rnd + -Del: remove pcb-rnd leftovers from Makefiles + -Move: scconfig lib from scconfig/ to src/ so it is part of the single install subtree for reuse by apps + -Move: gen_conf.sh to librnd/scconfig (with installation) so apps can reuse it + -Move: scconfig templates from scconfig to src/librnd/scconfig as it's becoming installable for apps to reuse + -Cleanup: detach building the plugins from $(PLUDGID) so the temporary in-pcb-rnd build still works + -Cleanup: move src_plugins to src/librnd/plugins for easier svn externs and consistency with the installation later + -Cleanup: plugin headers should be #included as for portabilirty + -Fix: make sure make dep generates the dependencies with full relative path (requires an extra step of 'sed' to work around gcc's shortcomings) + -Fix: broken installation of buildin.hidlib.h + -Fix: missing dependency on test-rnd executable to buildin.hidlib.h + -Fix: use the same path notation for buildin.hidlib.h dep as for the build rule + -Fix: mark all plugins part of $hidlib + -Change: install doc and data in /librnd, not in /pcb-rnd + -Add: #define LIBRND_ROOT so configure compiles + -Add: install minimal libfungw headers and genht headers (apps will need these) + -Add: make map_plugins.sh more generic so ringdove apps can reuse it without having to copy it + -Add: install map_plugins.sh so apps don't need to copy it + -Add: temporary branch in the internal conf generator template for pcb-rnd, as long as it needs to compile librnd locally + -Add: set librnd plugin root from the Makefile so plugins are found + + [librnd/core] + -Cleanup: dedoxygen comments + -Cleanup: code formatting + -Del: RND_BOX_ROTATE_CW() - no user + -Del: box direction flags and macros - required by pcb-rnd autorouter only + -Del: pcb-rnd related docs + -Del: rnd_r_end() - useless dummy + -Del: remove vcs comment mentioning multiple crosshair shapes from the copyright banner - that piece of code got removed + -Fix: RND_ACT_CALL_C() needs to get hidlib as first argument and set up the call properly because action code depend on the hidlib context pointer + -Fix: can't pass function pointer in low level C action call because there's no place the temporary func wrapper could be allocated + -Fix: indicate error on action not found in parse action also in the case of action with arguments + -Fix: str2coord for action arg conversion: do not crash on empty coord + -Fix: don't crash if menu file did not parse + -Fix: hid uninit sequence: keep hid structs until after pup unload so plugin uninit cals won't address into already free'd memory + -Fix: don't crash if rnd_tool_get() is called before tool init + -Fix: DAD: coord spin: accept 0.00 as legal value even without unit (special case) + -Add: global var indicating if librnd is running the main loop + -Add: generate an event when main loop state changes + -Add: rnd_printf %mw prints an fgw_arg_t; prints coord with units + -Add: MenuDebug() action with a command to save the menu + -Add: MenuDebug(force-enable) for menu debugging with the batch HID + + [librnd/hid_gtk2_gdk] + -Fix: limit poly draw coords to 32767, gdk seems to misbehave with larger coordinates + + [librnd/loghid] + -Fix: mark plugin a hidlib plugin + -Fix: preserve override_render bit after setting up the delegation + -Add: set HID bit 'override render' to capture rendering calls Index: tags/2.3.0/Changelog.1.0.x.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/Changelog.1.0.x.gz =================================================================== --- tags/2.3.0/Changelog.1.0.x.gz (nonexistent) +++ tags/2.3.0/Changelog.1.0.x.gz (revision 33253) Property changes on: tags/2.3.0/Changelog.1.0.x.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/Changelog.1.1.x.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/Changelog.1.1.x.gz =================================================================== --- tags/2.3.0/Changelog.1.1.x.gz (nonexistent) +++ tags/2.3.0/Changelog.1.1.x.gz (revision 33253) Property changes on: tags/2.3.0/Changelog.1.1.x.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/Changelog.1.2.x.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/Changelog.1.2.x.gz =================================================================== --- tags/2.3.0/Changelog.1.2.x.gz (nonexistent) +++ tags/2.3.0/Changelog.1.2.x.gz (revision 33253) Property changes on: tags/2.3.0/Changelog.1.2.x.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/Changelog.2.0.x.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/Changelog.2.0.x.gz =================================================================== --- tags/2.3.0/Changelog.2.0.x.gz (nonexistent) +++ tags/2.3.0/Changelog.2.0.x.gz (revision 33253) Property changes on: tags/2.3.0/Changelog.2.0.x.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/Changelog.2.1.x.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/Changelog.2.1.x.gz =================================================================== --- tags/2.3.0/Changelog.2.1.x.gz (nonexistent) +++ tags/2.3.0/Changelog.2.1.x.gz (revision 33253) Property changes on: tags/2.3.0/Changelog.2.1.x.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/Changelog.2.2.x.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/Changelog.2.2.x.gz =================================================================== --- tags/2.3.0/Changelog.2.2.x.gz (nonexistent) +++ tags/2.3.0/Changelog.2.2.x.gz (revision 33253) Property changes on: tags/2.3.0/Changelog.2.2.x.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/INSTALL =================================================================== --- tags/2.3.0/INSTALL (nonexistent) +++ tags/2.3.0/INSTALL (revision 33253) @@ -0,0 +1,79 @@ +1. Configure + +Run ./configure. + +Run make. + +Run make install. + +For compile-time options run ./configure --help. + +Dependencies: almost none. For GUI, install the (-dev or -devel) libs +Read the summary table and the warnings at the end of ./configure output +and decide if you need the features missing. If there was no error, only +warnings, pcb-rnd cab be compiled, even if some dependencies were missing. + +Summary of dependencies: +For users: + - mandatory: C compiler + - mandatory: make + - optional: glib and gtk2 if you are using the GTK GUI + - optional: gtkglext if you need opengl rendering + - optional: motif or lesstif if you are using the lesstif frontend + - optional: gdlib if you want to export/import to/from png, jpg or gif + - optional: imagemagick for running the pixmap export tests + +For developers: + - flex + - bison + +NOTE: if you did not install any GUI lib dependency, pcb-rnd will be +compiled with command line interface only. + +./configure will try to static link most plugins and disable ones that +have missing dependencies. This process can be controlled using configure +command line switches, see ./configure --help. + + +2. Compiling + +Run make. + +Optionally also run make test. + + +3. Running from source + +cd src && ./pcb-rnd + +(Note: it is important to cd to src to run pcb-rnd from source; src/pcb-rnd +won't work unless pcb-rnd is installed). + +If this doesn't work, please refer to doc/UNIX.txt or doc/mac.txt + + +4. Installation + +To install PCB after it has been built run: + + make install + +from the top level directory. An alternative installation method +is the link-install, which places symlinks instead of copying files so +no subsequent make install is needed after a recompilation if no new +files appeared (useful for developers): + + make linstall + + +5. Packaging + +If you are planning to package pcb-rnd, please read +doc/developer/packaging.txt and if it is binary packaging, please consider +following the package naming and layout documented in +doc/developer/packaging/packaging/packages.html - this way different +distros will have similar packages which will make both users' and developers' +life easier while supporting the software. + + + Index: tags/2.3.0/Makefile =================================================================== --- tags/2.3.0/Makefile (nonexistent) +++ tags/2.3.0/Makefile (revision 33253) @@ -0,0 +1,58 @@ +all: FORCE + cd src_3rd/puplug/util && $(MAKE) CC=$(PCB_RND_HOST_CC) + cd src && $(MAKE) + cd util && $(MAKE) + cd pcblib && $(MAKE) +# cd doc && $(MAKE) + +test: FORCE + cd tests && $(MAKE) test + +clean: FORCE + cd src && $(MAKE) clean + cd util && $(MAKE) clean + cd pcblib && $(MAKE) clean +# cd doc && $(MAKE) clean + cd tests && $(MAKE) clean + cd src_3rd/sphash && $(MAKE) clean + cd src_3rd/puplug && $(MAKE) clean + cd src_3rd/libminuid && $(MAKE) clean ; true + cd src_3rd/libuundo && $(MAKE) clean ; true + +# Note: have to distclean utils (and tests) before src because of hidlib deps +distclean: FORCE + $(MAKE) clean ; true +# cd doc && $(MAKE) distclean + cd util/gsch2pcb-rnd && $(MAKE) distclean + cd src && $(MAKE) distclean + cd src_3rd/genlist && $(MAKE) clean ; true + cd src_3rd/genregex && $(MAKE) clean ; true + cd src_3rd/genvector && $(MAKE) clean ; true + cd src_3rd/liblihata && $(MAKE) clean ; true + cd src_3rd/liblihata/genht && $(MAKE) clean ; true + cd src_3rd/qparse && $(MAKE) clean ; true + cd src_3rd/libporty_net && $(MAKE) distclean ; true + cd scconfig && $(MAKE) distclean ; true + + +install: FORCE + cd src && $(MAKE) install + cd util && $(MAKE) install + cd pcblib && $(MAKE) install + cd doc && $(MAKE) install + +linstall: FORCE + cd src && $(MAKE) linstall + cd util && $(MAKE) linstall + cd pcblib && $(MAKE) linstall + cd doc && $(MAKE) linstall + +uninstall: FORCE + cd src && $(MAKE) uninstall + cd util && $(MAKE) uninstall + cd pcblib && $(MAKE) uninstall + cd doc && $(MAKE) uninstall + +include Makefile.conf + +FORCE: Index: tags/2.3.0/Makefile.conf.in =================================================================== --- tags/2.3.0/Makefile.conf.in (nonexistent) +++ tags/2.3.0/Makefile.conf.in (revision 33253) @@ -0,0 +1,51 @@ +put /tmpasm/OFS { } +put /local/pcb/CFLAGS_GENERIC cc/cflags +append /local/pcb/CFLAGS_GENERIC cc/fpic +append /local/pcb/CFLAGS_GENERIC ?/local/pcb/cflags_profile +put /local/pcb/CFLAGS /local/pcb/CFLAGS_GENERIC +uniq /local/pcb/CFLAGS +uniq /local/pcb/CFLAGS_GENERIC + +# calculate the /local/confdir: either specified conf-time or compatibility fallback +switch /local/confdir + case {^$} put /local/confdir_final_m [@@/local/prefix@/share/pcb-rnd@]; end + default put /local/confdir_final_m /local/confdir; end +end + +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 @/local/prefix@ +DOCDIR=$(Install_root)@/local/prefix@/share/doc/pcb-rnd +LIBDIR=$(Install_root)@/local/prefix@/lib/pcb-rnd +BINDIR=$(Install_root)@/local/prefix@/bin +DATADIR=$(Install_root)@/local/prefix@/share/pcb-rnd +MAN1DIR=$(Install_root)@/local/prefix@@/local/man1dir@ +CONFDIR=$(Install_root)@/local/confdir_final_m@ +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@ +PCB_RND_HOST_CC=@/host/cc/cc@ +PCB_RND_VER=@/local/version@ +PCB_RND_VER_MAJOR=@/local/version_major@ + +PCB_RND_CFLAGS=@?cc/argstd/std_c99@ @/local/pcb/CFLAGS@ +PCB_RND_C89FLAGS=@/local/pcb/c89flags@ @/local/pcb/CFLAGS@ + +# hidlib installation directories +HL_LIBDIR=$(Install_root)@/local/prefix@/@/local/libarchdir@ +HL_SHAREDIR=$(Install_root)@/local/prefix@/share/librnd +HL_INCDIR=$(Install_root)@/local/prefix@/include/librnd + + +# The installation directoried to be used from within binaries (with +# install_root/DESTDIR removed) +LIBDIR_INSTALLED=@/local/prefix@/lib/pcb-rnd + +@] Index: tags/2.3.0/README =================================================================== --- tags/2.3.0/README (nonexistent) +++ tags/2.3.0/README (revision 33253) @@ -0,0 +1,43 @@ +pcb-rnd is a modular PCB layout editor. + +It is hosted at http://repo.hu/projects/pcb-rnd +Source code: svn://repo.hu/pcb-rnd/trunk + +** THERE IS NO GIT SUPPORT ** - do not make pull requests, don't +send git URLs. pcb-rnd is hosted in svn on repo.hu and +the only one way to contribute is using the above repository. + +For installing the release refer to the file 'INSTALL'. +For additional information read the manual (doc/user/index.html) + +If you are updating you may wish to read the Changelog + +Contact: + email: http://repo.hu/projects/pcb-rnd/contact.html + chat & IRC: http://repo.hu/projects/pcb-rnd/irc.html + + +pcb-rnd source distribution is organized into: + src/ a core program that deals with all of the internal + database procedures + src_plugins/ a collection of plugins + src_3rd/ third-party minilibs (dependencies, not integral parts) + pcblib/ a basic footprint library + tests/ automated tests to check whether pcb-rnd works properly + util/ utility programs like gsch2pcb-rnd + + + +Pcb-rnd was forked from gEDA/PCB in 2013, that had the following copyright: +------------------------------------------------------------------------- + COPYRIGHT + +PCB is covered by the GNU General Public License. See the individual +files for the exact copyright notices. + + Contact addresses for paper mail and Email: + harry eaton + 6697 Buttonhole Court + Columbia, MD 21044 + haceaton@aplcomm.jhuapl.edu + Index: tags/2.3.0/Release_notes =================================================================== --- tags/2.3.0/Release_notes (nonexistent) +++ tags/2.3.0/Release_notes (revision 33253) @@ -0,0 +1,32 @@ +pcb-rnd 2.3.0 +~~~~~~~~~~~~~ + +The main objective of this release is to go further in librnd separation: +by now, librnd is a single directory, imported from an external repository. +Furthermore this is also a feature release. + +Feature highlight: + +1. Padstack prototypes can be saved to file and loaded from file, using the + board's or subcircuit's padstacks dialog. File format is the native + lihata format. + +2. Font support: with an optional plugin, ttf glyphs can be imported and + converted to native font symbols, using actions or a dialog box. + +3. ch_editpoint: optional (default enabled) highlight feature of object + editpoints (e.g. line endpoints) on mouse hover. + +4. Undo: made many actions undoable: text scale, ChangePinName(), + ChangeNonetlist(), padstack hole changes, subc flags (including lock), + attributes, RouteStyle(), creating and removing route styles, changing + layer combining flags + +5. New "manage plugins" dialog box with more details and more control over + the plugins, including unloading plugins on the fly + +6. Query: user functions and more builtin accessor/utility functions; most + notably: a built-in function that can do advanced layer stackup queries + and checks around an object. + +7. Layer selector widget: all layer visible/invisible buttons and hotkeys Index: tags/2.3.0/config.h.in =================================================================== --- tags/2.3.0/config.h.in (nonexistent) +++ tags/2.3.0/config.h.in (revision 33253) @@ -0,0 +1,69 @@ +print [@ /***** Generated by scconfig - DO NOT EDIT *****/ + +/* Source: config.h.in; to regenerate run ./configure */ + +#ifndef PCB_CONFIG_H +#define PCB_CONFIG_H + +#include + +/****************************************************************************/ +/* Package properties */ + +/* Name of package */ +#define PCB_PACKAGE "pcb-rnd" + +/****************************************************************************/ +/* These ones are already autodetected by scconfig */ +@] + +# calculate the /local/confdir: either specified conf-time or compatibility fallback +switch /local/confdir + case {^$} put /local/confdir_final {PCBSHAREDIR}; end + default put /local/confdir_final [@"@/local/confdir@"@]; end +end + +print [@ +/****************************************************************************/ +/* Paths */ +@] + +switch sys/class + case {win32} + print [@ +#define PCB_PREFIX rnd_w32_root +#define PCBSHAREDIR rnd_w32_sharedir +#define PCBLIBDIR rnd_w32_libdir +#define BINDIR rnd_w32_bindir +#define PCBCONFDIR @/local/confdir_final@ +@] + end; + default + print [@ +#define PCB_PREFIX "@/local/prefix@" +#define PCBSHAREDIR PCB_PREFIX "/share/pcb-rnd" +#define PCBLIBDIR PCB_PREFIX "/lib/pcb-rnd" +#define BINDIR PCB_PREFIX "/bin" +#define PCBCONFDIR @/local/confdir_final@ +@] + end; +end; + +print [@ + +/* Relative path from bindir to exec_prefix */ +#define BINDIR_TO_EXECPREFIX ".." + +/* Version number of package */ +#define PCB_VERSION "@/local/version@" +#define PCB_REVISION "@/local/revision@" + +/* the dot-dir: where to save user config under ther user's home; it's used + as ~/DOT_PCB_RND/ */ +#define DOT_PCB_RND "@/local/pcb/dot_pcb_rnd@" + +/* librnd transition */ +#define RND_DAD_CFG_NOLABEL 1 + +#endif +@] Index: tags/2.3.0/configure =================================================================== --- tags/2.3.0/configure (nonexistent) +++ tags/2.3.0/configure (revision 33253) @@ -0,0 +1,4 @@ +#!/bin/sh +cd scconfig +make +./configure "$@" Property changes on: tags/2.3.0/configure ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/data/Makefile =================================================================== --- tags/2.3.0/data/Makefile (nonexistent) +++ tags/2.3.0/data/Makefile (revision 33253) @@ -0,0 +1,64 @@ +# This Makefile is a plain old hand written one; all configuration settings +# are included from ../Makefile.conf which is scconfig generated + +theme = hicolor + +app_icon = pcb + +mime_icons = \ + application-x-pcb-layout \ + application-x-pcb-footprint \ + application-x-pcb-netlist \ + application-x-gerber \ + application-x-excellon + +app_icon_files = \ + $(app_icon:%=%-48.png) \ + $(app_icon:%=%.svg) +# $(app_icon:%=%-16.png) +# $(app_icon:%=%-22.png) +# $(app_icon:%=%-24.png) +# $(app_icon:%=%-32.png) + +mime_icon_files = \ + $(mime_icons:%=%-16.png) \ + $(mime_icons:%=%-22.png) \ + $(mime_icons:%=%-24.png) \ + $(mime_icons:%=%-32.png) \ + $(mime_icons:%=%-48.png) \ + $(mime_icons:%=%.svg) + +mime_icon_sources = \ + $(mime_icons:%=%-16.svg) \ + $(mime_icons:%=%-22.svg) \ + $(mime_icons:%=%-32.svg) \ + $(mime_icons:%=%-48.svg) + +theme_icons = \ + $(mime_icon_files:%=mimetypes,%) \ + $(app_icon_files:%=apps,%) + +all: + +install_: + ./icon-theme-installer \ + -t $(theme) \ + -m "$(MKDIR)" \ + -s `pwd` \ + -d x \ + -b "$(themedir)" \ + -x "$(CPC)" \ + -i $(theme_icons) + +install: + $(MAKE) install_ CPC="$(CP)" + +linstall: + $(MAKE) install_ CPC="$(LN)" + +uninstall: + $(RM) $(DOCDIR)/examples/tut1.pcb + +include ../Makefile.conf +themedir=$(DATADIR)/icons/$(theme) + Index: tags/2.3.0/data/README =================================================================== --- tags/2.3.0/data/README (nonexistent) +++ tags/2.3.0/data/README (revision 33253) @@ -0,0 +1,56 @@ + +PCB +------------------------------------------------------------------------------ + +README for icon data + +This file describes where the various icons came from and their license. + +The PCB layout and gerber icons and mime registration data were contributed +by Tomaz Solc, and subsequently modified by Peter Clifton, including +creation of an excellon icon file with a ruler element taken from +Tomaz's gerber icon. The footprint and netlist icons were drawn by +Peter Clifton. + +The page outline featured in all the above icons is from the GNOME icon +theme's text-x-generic icon by Jakub Steiner. + +The icons are licensed under the GPL2 license. + +Scalable versions: (128x128 canvas for the "hicolor" fallback theme). +These were scaled up from the 48x48 pixel targeted version. + +application-x-excellon.svg +application-x-gerber.svg +application-x-pcb-footprint.svg +application-x-pcb-layout.svg +application-x-pcb-netlist.svg + +Pixel targeted varients: + +application-x-excellon-{16,22,32,48}.svg +application-x-gerber-{16,22,32,48}.svg +application-x-pcb-footprint-{16,22,32,48}.svg +application-x-pcb-layout-{16,22,32,48}.svg +application-x-pcb-netlist-{16,22,32,48}.svg + + +PNG versions of the above icons were exported from Inkscape. The 24x24 pixel +versions are copied from the 22x22 version, with a 1 pixel border added: + +application-x-excellon-{16,22,24,32,48}.png +application-x-gerber-{16,22,24,32,48}.png +application-x-pcb-footprint-{16,22,24,32,48}.png +application-x-pcb-layout-{16,22,24,32,48}.png +application-x-pcb-netlist-{16,22,24,32,48}.png + +The script "regen_files" will re-export the SVG drawings to PNG and also +regenerate the windows icon file. + +The PCB application icons were created by Peter Clifton, based upon the +Gnome "text-editor" icon created by Lapo Calamandrei. The PCB specific +additions are from the mime-type icons by Tomaz Solc. +These icons are licensed under the GPL2 license. + +pcb.svg +pcb-48.png Index: tags/2.3.0/data/application-x-excellon-16.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-excellon-16.png =================================================================== --- tags/2.3.0/data/application-x-excellon-16.png (nonexistent) +++ tags/2.3.0/data/application-x-excellon-16.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-excellon-16.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-excellon-16.svg =================================================================== --- tags/2.3.0/data/application-x-excellon-16.svg (nonexistent) +++ tags/2.3.0/data/application-x-excellon-16.svg (revision 33253) @@ -0,0 +1,1271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Excellon file + + + + + + + Peter Clifton, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-excellon-22.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-excellon-22.png =================================================================== --- tags/2.3.0/data/application-x-excellon-22.png (nonexistent) +++ tags/2.3.0/data/application-x-excellon-22.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-excellon-22.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-excellon-22.svg =================================================================== --- tags/2.3.0/data/application-x-excellon-22.svg (nonexistent) +++ tags/2.3.0/data/application-x-excellon-22.svg (revision 33253) @@ -0,0 +1,1571 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Excellon file + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-excellon-24.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-excellon-24.png =================================================================== --- tags/2.3.0/data/application-x-excellon-24.png (nonexistent) +++ tags/2.3.0/data/application-x-excellon-24.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-excellon-24.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-excellon-32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-excellon-32.png =================================================================== --- tags/2.3.0/data/application-x-excellon-32.png (nonexistent) +++ tags/2.3.0/data/application-x-excellon-32.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-excellon-32.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-excellon-32.svg =================================================================== --- tags/2.3.0/data/application-x-excellon-32.svg (nonexistent) +++ tags/2.3.0/data/application-x-excellon-32.svg (revision 33253) @@ -0,0 +1,1406 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Excellon file + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-excellon-48.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-excellon-48.png =================================================================== --- tags/2.3.0/data/application-x-excellon-48.png (nonexistent) +++ tags/2.3.0/data/application-x-excellon-48.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-excellon-48.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-excellon-48.svg =================================================================== --- tags/2.3.0/data/application-x-excellon-48.svg (nonexistent) +++ tags/2.3.0/data/application-x-excellon-48.svg (revision 33253) @@ -0,0 +1,1283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Excellon file + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-excellon.svg =================================================================== --- tags/2.3.0/data/application-x-excellon.svg (nonexistent) +++ tags/2.3.0/data/application-x-excellon.svg (revision 33253) @@ -0,0 +1,1289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Excellon file + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-gerber-16.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-gerber-16.png =================================================================== --- tags/2.3.0/data/application-x-gerber-16.png (nonexistent) +++ tags/2.3.0/data/application-x-gerber-16.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-gerber-16.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-gerber-16.svg =================================================================== --- tags/2.3.0/data/application-x-gerber-16.svg (nonexistent) +++ tags/2.3.0/data/application-x-gerber-16.svg (revision 33253) @@ -0,0 +1,543 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Gerber file + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-gerber-22.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-gerber-22.png =================================================================== --- tags/2.3.0/data/application-x-gerber-22.png (nonexistent) +++ tags/2.3.0/data/application-x-gerber-22.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-gerber-22.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-gerber-22.svg =================================================================== --- tags/2.3.0/data/application-x-gerber-22.svg (nonexistent) +++ tags/2.3.0/data/application-x-gerber-22.svg (revision 33253) @@ -0,0 +1,608 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Gerber file + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-gerber-24.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-gerber-24.png =================================================================== --- tags/2.3.0/data/application-x-gerber-24.png (nonexistent) +++ tags/2.3.0/data/application-x-gerber-24.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-gerber-24.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-gerber-32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-gerber-32.png =================================================================== --- tags/2.3.0/data/application-x-gerber-32.png (nonexistent) +++ tags/2.3.0/data/application-x-gerber-32.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-gerber-32.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-gerber-32.svg =================================================================== --- tags/2.3.0/data/application-x-gerber-32.svg (nonexistent) +++ tags/2.3.0/data/application-x-gerber-32.svg (revision 33253) @@ -0,0 +1,544 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Gerber file + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-gerber-48.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-gerber-48.png =================================================================== --- tags/2.3.0/data/application-x-gerber-48.png (nonexistent) +++ tags/2.3.0/data/application-x-gerber-48.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-gerber-48.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-gerber-48.svg =================================================================== --- tags/2.3.0/data/application-x-gerber-48.svg (nonexistent) +++ tags/2.3.0/data/application-x-gerber-48.svg (revision 33253) @@ -0,0 +1,707 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Gerber file + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-gerber.svg =================================================================== --- tags/2.3.0/data/application-x-gerber.svg (nonexistent) +++ tags/2.3.0/data/application-x-gerber.svg (revision 33253) @@ -0,0 +1,712 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Gerber file + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-footprint-16.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-footprint-16.png =================================================================== --- tags/2.3.0/data/application-x-pcb-footprint-16.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-footprint-16.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-footprint-16.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-footprint-16.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-footprint-16.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-footprint-16.svg (revision 33253) @@ -0,0 +1,554 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB footprint + + + + + + + Peter Clifton, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-footprint-22.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-footprint-22.png =================================================================== --- tags/2.3.0/data/application-x-pcb-footprint-22.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-footprint-22.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-footprint-22.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-footprint-22.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-footprint-22.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-footprint-22.svg (revision 33253) @@ -0,0 +1,573 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB footprint + + + + + + + Peter Clifton, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-footprint-24.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-footprint-24.png =================================================================== --- tags/2.3.0/data/application-x-pcb-footprint-24.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-footprint-24.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-footprint-24.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-footprint-32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-footprint-32.png =================================================================== --- tags/2.3.0/data/application-x-pcb-footprint-32.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-footprint-32.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-footprint-32.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-footprint-32.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-footprint-32.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-footprint-32.svg (revision 33253) @@ -0,0 +1,2302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB footprint + + + + + + + Peter Clifton, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-footprint-48.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-footprint-48.png =================================================================== --- tags/2.3.0/data/application-x-pcb-footprint-48.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-footprint-48.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-footprint-48.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-footprint-48.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-footprint-48.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-footprint-48.svg (revision 33253) @@ -0,0 +1,674 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB footprint + + + + + + + Peter Clifton, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-footprint.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-footprint.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-footprint.svg (revision 33253) @@ -0,0 +1,680 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB footprint + + + + + + + Peter Clifton, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-layout-16.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-layout-16.png =================================================================== --- tags/2.3.0/data/application-x-pcb-layout-16.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-layout-16.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-layout-16.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-layout-16.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-layout-16.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-layout-16.svg (revision 33253) @@ -0,0 +1,1333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB layout + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-layout-22.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-layout-22.png =================================================================== --- tags/2.3.0/data/application-x-pcb-layout-22.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-layout-22.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-layout-22.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-layout-22.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-layout-22.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-layout-22.svg (revision 33253) @@ -0,0 +1,1423 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB layout + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-layout-24.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-layout-24.png =================================================================== --- tags/2.3.0/data/application-x-pcb-layout-24.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-layout-24.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-layout-24.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-layout-32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-layout-32.png =================================================================== --- tags/2.3.0/data/application-x-pcb-layout-32.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-layout-32.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-layout-32.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-layout-32.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-layout-32.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-layout-32.svg (revision 33253) @@ -0,0 +1,1362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB layout + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-layout-48.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-layout-48.png =================================================================== --- tags/2.3.0/data/application-x-pcb-layout-48.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-layout-48.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-layout-48.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-layout-48.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-layout-48.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-layout-48.svg (revision 33253) @@ -0,0 +1,1341 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB layout + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-layout.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-layout.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-layout.svg (revision 33253) @@ -0,0 +1,1346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB layout + + + + + + + Peter Clifton, Tomaz Solc, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-netlist-16.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-netlist-16.png =================================================================== --- tags/2.3.0/data/application-x-pcb-netlist-16.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-netlist-16.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-netlist-16.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-netlist-16.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-netlist-16.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-netlist-16.svg (revision 33253) @@ -0,0 +1,530 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB netlist + + + + + + + Peter Clifton, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-netlist-22.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-netlist-22.png =================================================================== --- tags/2.3.0/data/application-x-pcb-netlist-22.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-netlist-22.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-netlist-22.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-netlist-22.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-netlist-22.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-netlist-22.svg (revision 33253) @@ -0,0 +1,567 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB netlist + + + + + + + Peter Clifton, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-netlist-24.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-netlist-24.png =================================================================== --- tags/2.3.0/data/application-x-pcb-netlist-24.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-netlist-24.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-netlist-24.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-netlist-32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-netlist-32.png =================================================================== --- tags/2.3.0/data/application-x-pcb-netlist-32.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-netlist-32.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-netlist-32.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-netlist-32.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-netlist-32.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-netlist-32.svg (revision 33253) @@ -0,0 +1,1310 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB netlist + + + + + + + Peter Clifton, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-netlist-48.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/application-x-pcb-netlist-48.png =================================================================== --- tags/2.3.0/data/application-x-pcb-netlist-48.png (nonexistent) +++ tags/2.3.0/data/application-x-pcb-netlist-48.png (revision 33253) Property changes on: tags/2.3.0/data/application-x-pcb-netlist-48.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/application-x-pcb-netlist-48.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-netlist-48.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-netlist-48.svg (revision 33253) @@ -0,0 +1,451 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB netlist + + + + + + + Peter Clifton, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/application-x-pcb-netlist.svg =================================================================== --- tags/2.3.0/data/application-x-pcb-netlist.svg (nonexistent) +++ tags/2.3.0/data/application-x-pcb-netlist.svg (revision 33253) @@ -0,0 +1,459 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + PCB netlist + + + + + + + Peter Clifton, Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/icon-theme-installer =================================================================== --- tags/2.3.0/data/icon-theme-installer (nonexistent) +++ tags/2.3.0/data/icon-theme-installer (revision 33253) @@ -0,0 +1,183 @@ +#!/bin/sh + +# icon-theme-installer +# Copyright (C) 2006 Novell, Inc. +# Written by Aaron Bockover +# Licensed under the MIT/X11 license +# +# Modified by Peter Clifton to allow icons with numerals in the filename +# +# This script is meant to be invoked from within a Makefile/Makefile.am +# in the install-data-local and uninstall-data sections. It handles the +# task of properly installing icons into the icon theme. It requires a +# few arguments to set up its environment, and a list of files to be +# installed. The format of the file list is critical: +# +# , +# +# apps,music-player-banshee.svg +# apps,music-player-banshee-16.png +# apps,music-player-banshee-22.png +# +# is the icon theme category, for instance, apps, devices, +# actions, emblems... +# +# must have a basename in the form of: +# +# proper-theme-name[-]. +# +# Where should be either nothing, which will default to scalable +# or \-[0-9]{2}, which will expand to x. For example: +# +# music-player-banshee-16.png +# +# The here is -16 and will expand to 16x16 per the icon theme spec +# +# What follows is an example Makefile.am for icon theme installation: +# +# --------------- +# theme=hicolor +# themedir=$(datadir)/icons/$(theme) +# theme_icons = \ +# apps,music-player-banshee.svg \ +# apps,music-player-banshee-16.png \ +# apps,music-player-banshee-22.png \ +# apps,music-player-banshee-24.png \ +# apps,music-player-banshee-32.png +# +# install_icon_exec = $(top_srcdir)/build/icon-theme-installer -t $(theme) -s $(srcdir) -d "x$(DESTDIR)" -b $(themedir) -m "$(mkinstalldirs)" -x "$(INSTALL_DATA)" +# install-data-local: +# $(install_icon_exec) -i $(theme_icons) +# +# uninstall-hook: +# $(install_icon_exec) -u $(theme_icons) +# +# MAINTAINERCLEANFILES = Makefile.in +# EXTRA_DIST = $(wildcard *.svg *.png) +# --------------- +# +# Arguments to this program: +# +# -i : Install +# -u : Uninstall +# -t : Theme name (hicolor) +# -b : Theme installation dest directory [x$(DESTDIR)] - Always prefix +# this argument with x; it will be stripped but will act as a +# placeholder for zero $DESTDIRs (only set by packagers) +# -d : Theme installation directory [$(hicolordir)] +# -s : Source directory [$(srcdir)] +# -m : Command to exec for directory creation [$(mkinstalldirs)] +# -x : Command to exec for single file installation [$(INSTALL_DATA)] +# : All remainging should be category,filename pairs + +while getopts "iut:b:d:s:m:x:" flag; do + case "$flag" in + i) INSTALL=yes ;; + u) UNINSTALL=yes ;; + t) THEME_NAME=$OPTARG ;; + d) INSTALL_DEST_DIR="`echo $OPTARG | sed 's;^x;;'`" ;; + b) INSTALL_BASE_DIR=$OPTARG ;; + s) SRC_DIR=$OPTARG ;; + m) MKINSTALLDIRS_EXEC=$OPTARG ;; + x) INSTALL_DATA_EXEC=$OPTARG ;; + esac +done + +shift `expr $OPTIND - 1` + +if test "x$INSTALL" = "xyes" -a "x$UNINSTALL" = "xyes"; then + echo "Cannot pass both -i and -u" + exit 1 +elif test "x$INSTALL" = "x" -a "x$UNINSTALL" = "x"; then + echo "Must path either -i or -u" + exit 1 +fi + +if test -z "$THEME_NAME"; then + echo "Theme name required (-t hicolor)" + exit 1 +fi + +if test -z "$INSTALL_BASE_DIR"; then + echo "Base theme directory required [-d \$(hicolordir)]" + exit 1 +fi + +#if test ! -x `echo "$MKINSTALLDIRS_EXEC" | cut -f1 -d' '`; then +# echo "Cannot find '$MKINSTALLDIRS_EXEC'; You probably want to pass -m \$(mkinstalldirs)" +# exit 1 +#fi + +#if test ! -x `echo "$INSTALL_DATA_EXEC" | cut -f1 -d' '`; then +# echo "Cannot find '$INSTALL_DATA_EXEC'; You probably want to pass -x \$(INSTALL_DATA)" +# exit 1 +#fi + +if test -z "$SRC_DIR"; then + SRC_DIR=. +fi + +for icon in $@; do + size=`echo $icon | sed -n 's/.*-\([0-9]*\).*/\1/p'` + category=`echo $icon | cut -d, -f1` + build_name=`echo $icon | cut -d, -f2` + install_name=`echo $build_name | sed 's/-[0-9]\+//g'` + install_name=`basename $install_name` + + if test -z $size; then + size=scalable; + else + size=${size}x${size}; + fi + + install_dir=${INSTALL_DEST_DIR}${INSTALL_BASE_DIR}/$size/$category + install_path=$install_dir/$install_name + + if test "x$INSTALL" = "xyes"; then + echo "Installing $size $install_name into $THEME_NAME icon theme" + + $MKINSTALLDIRS_EXEC $install_dir || { + echo "Failed to create directory $install_dir" + exit 1 + } + + $INSTALL_DATA_EXEC $SRC_DIR/$build_name $install_path || { + echo "Failed to install $SRC_DIR/$build_name into $install_path" + exit 1 + } + + if test ! -e $install_path; then + echo "Failed to install $SRC_DIR/$build_name into $install_path" + exit 1 + fi + else + if test -e $install_path; then + echo "Removing $size $install_name from $THEME_NAME icon theme" + + rm $install_path || { + echo "Failed to remove $install_path" + exit 1 + } + fi + fi +done + +if test "x$INSTALL" = "xyes"; then + gtk_update_icon_cache_bin="`(which gtk-update-icon-cache || echo /opt/gnome/bin/gtk-update-icon-cache)2>/dev/null`" + gtk_update_icon_cache_bin="${GTK_UPDATE_ICON_CACHE_BIN:-$gtk_update_icon_cache_bin}" + + gtk_update_icon_cache="$gtk_update_icon_cache_bin -f -t $INSTALL_BASE_DIR" + + if test -z "$INSTALL_DEST_DIR"; then + if test -x $gtk_update_icon_cache_bin; then + echo "Updating GTK icon cache" + $gtk_update_icon_cache + else + echo "*** Icon cache not updated. Could not execute $gtk_update_icon_cache_bin" + fi + else + echo "*** Icon cache not updated. After install, run this:" + echo "*** $gtk_update_icon_cache" + fi +fi + Property changes on: tags/2.3.0/data/icon-theme-installer ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/data/pcb-48.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/pcb-48.png =================================================================== --- tags/2.3.0/data/pcb-48.png (nonexistent) +++ tags/2.3.0/data/pcb-48.png (revision 33253) Property changes on: tags/2.3.0/data/pcb-48.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/pcb.desktop =================================================================== --- tags/2.3.0/data/pcb.desktop (nonexistent) +++ tags/2.3.0/data/pcb.desktop (revision 33253) @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Name=pcb-rnd PCB Designer +GenericName=PCB Design +Comment=Create and edit printed circuit board designs +Type=Application +Exec=pcb-rnd %f +Icon=pcb +MimeType=application/x-pcb-layout;application/x-pcb-footprint; +Categories=Engineering;Electronics; Index: tags/2.3.0/data/pcb.svg =================================================================== --- tags/2.3.0/data/pcb.svg (nonexistent) +++ tags/2.3.0/data/pcb.svg (revision 33253) @@ -0,0 +1,1070 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Lapo Calamandrei + + + + Text editor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/data/pcb.xml =================================================================== --- tags/2.3.0/data/pcb.xml (nonexistent) +++ tags/2.3.0/data/pcb.xml (revision 33253) @@ -0,0 +1,40 @@ + + + + + PCB layout + + + + + + + + PCB footprint + + + + + + + + PCB netlist + + + + + Gerber file + + + + + + + + Excellon drill file + + + + + + Index: tags/2.3.0/data/pcb_icon.ico =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/data/pcb_icon.ico =================================================================== --- tags/2.3.0/data/pcb_icon.ico (nonexistent) +++ tags/2.3.0/data/pcb_icon.ico (revision 33253) Property changes on: tags/2.3.0/data/pcb_icon.ico ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/data/regen_files =================================================================== --- tags/2.3.0/data/regen_files (nonexistent) +++ tags/2.3.0/data/regen_files (revision 33253) @@ -0,0 +1,165 @@ +#!/bin/sh +# + +CONVERT=${CONVERT:-convert} +COMPOSITE=${COMPOSITE:-composite} +INKSCAPE=${INKSCAPE:-inkscape} +PPMTOWINICON=${PPMTOWINICON:-ppmtowinicon} + +do_inkscape=yes +do_convert=yes +do_winicon=yes + +usage() { +cat << EOF + +$0 -- Regenerate desktop icon files and windows icon files + +Options + + --help Displays this message and exits + + --skip-png Skips the regeneration of the .png file(s) + + --skip-winicon Skips the regneration of the Windows icon file(s) + +EOF + +} + +while test $# -ne 0 ; do + case $1 in + --help) + usage + exit 0 + ;; + + --skip-png) + do_inkscape=no + shift + ;; + + --skip-winicon) + do_convert=no + do_winicon=no + shift + ;; + + -*) + echo "$0: Unknown option $1" + usage + exit 1 + ;; + + *) + break + ;; + esac +done + +if test $? -ne 0 ; then + usage + exit 1 +fi + +## +## Export the SVG graphics +## + +# see if we have inkscape +if test $do_inkscape = yes ; then +${INKSCAPE} --version 2>&1 >/dev/null +if test $? -ne 0 ; then + echo "\"${INKSCAPE} --version\" failed." + echo "Make sure that inkscape is installed and functional on your system." + echo "Skipping the SVG -> PNG conversion." + do_inkscape=no +fi +fi + +if test $do_inkscape = yes ; then + echo "Export SVG graphics to png..." + + for r in 16 22 24 32 48 ; do + case ${r} in + 24) + x=-1 + y=23 + rs=22 + ;; + *) + x=0 + y=${r} + rs=${r} + ;; + esac + for f in *-${rs}.svg ; do + fb=`basename ${f} ${rs}.svg` + p="${fb}${r}.png" + echo "${f} -> ${p}" + ${INKSCAPE} --export-png=${p} --export-area=${x}:${x}:${y}:${y} ${f} + done + done +fi + +## +## Generate the windows icon file +## + +app_icon="application-x-pcb-layout" + +if test $do_convert = yes ; then +# see if we have ImageMagick +${CONVERT} --version 2>&1 >/dev/null +if test $? -ne 0 ; then + echo "\"${CONVERT} --version\" failed." + echo "Make sure that ImageMagick is installed and functional on your system." + echo "Skipping the PNG -> PPM conversion." + do_convert=no +fi +fi + +if test $do_convert = yes ; then +echo "Creating windows pbm mask files..." +${CONVERT} -channel matte -separate +matte ${app_icon}-48.png - | + ${CONVERT} -threshold 65534 -negate - 48_mask.pbm +${CONVERT} -channel matte -separate +matte ${app_icon}-32.png - | + ${CONVERT} -threshold 65534 -negate - 32_mask.pbm +${CONVERT} -channel matte -separate +matte ${app_icon}-16.png - | + ${CONVERT} -threshold 65534 -negate - 16_mask.pbm + +echo "Creating windows ppm flattened files..." +${CONVERT} -flatten -colors 16 ${app_icon}-48.png 48_16.ppm +${CONVERT} -flatten -colors 256 ${app_icon}-48.png 48_256.ppm +${CONVERT} -flatten -colors 16 ${app_icon}-32.png 32_16.ppm +${CONVERT} -flatten -colors 256 ${app_icon}-32.png 32_256.ppm +${CONVERT} -flatten -colors 16 ${app_icon}-16.png 16_16.ppm +${CONVERT} -flatten -colors 256 ${app_icon}-16.png 16_256.ppm +fi + +# see if we have netpbm +if test $do_winicon = yes ; then +${PPMTOWINICON} --version 2>&1 >/dev/null +if test $? -ne 0 ; then + echo "\"${PPMTOWINICON} --version\" failed." + echo "Make sure that netpbm is installed and functional on your system." + echo "Skipping the pbm -> windows icon conversion." + do_winicon=no +fi +fi + +if test $do_winicon = yes ; then +echo "Creating windows icon file..." +${PPMTOWINICON} -output pcb_icon.ico -andpgms\ + 48_16.ppm 48_mask.pbm 48_256.ppm 48_mask.pbm\ + 32_16.ppm 32_mask.pbm 32_256.ppm 32_mask.pbm\ + 16_16.ppm 16_mask.pbm 16_256.ppm 16_mask.pbm +fi + +rm -f \ + 48_16.ppm 48_256.ppm 48_mask.pbm\ + 32_16.ppm 32_256.ppm 32_mask.pbm\ + 16_16.ppm 16_256.ppm 16_mask.pbm + +echo "All done" + Property changes on: tags/2.3.0/data/regen_files ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/data/x-excellon.desktop =================================================================== --- tags/2.3.0/data/x-excellon.desktop (nonexistent) +++ tags/2.3.0/data/x-excellon.desktop (revision 33253) @@ -0,0 +1,8 @@ +[Desktop Entry] +Encoding=UTF-8 +Comment=Excellon drill file +MimeType=application/x-excellon +Type=MimeType +Icon=application-x-excellon +Patterns=*.cnc +X-KDE-IsAlso=text/plain Index: tags/2.3.0/data/x-gerber.desktop =================================================================== --- tags/2.3.0/data/x-gerber.desktop (nonexistent) +++ tags/2.3.0/data/x-gerber.desktop (revision 33253) @@ -0,0 +1,8 @@ +[Desktop Entry] +Encoding=UTF-8 +Comment=Gerber file +MimeType=application/x-gerber +Type=MimeType +Icon=application-x-gerber +Patterns=*.gbr +X-KDE-IsAlso=text/plain Index: tags/2.3.0/data/x-pcb-footprint.desktop =================================================================== --- tags/2.3.0/data/x-pcb-footprint.desktop (nonexistent) +++ tags/2.3.0/data/x-pcb-footprint.desktop (revision 33253) @@ -0,0 +1,8 @@ +[Desktop Entry] +Encoding=UTF-8 +Comment=PCB footprint +MimeType=application/x-pcb-footprint +Type=MimeType +Icon=application-x-pcb-footprint +Patterns=*.fp +X-KDE-IsAlso=text/plain Index: tags/2.3.0/data/x-pcb-layout.desktop =================================================================== --- tags/2.3.0/data/x-pcb-layout.desktop (nonexistent) +++ tags/2.3.0/data/x-pcb-layout.desktop (revision 33253) @@ -0,0 +1,8 @@ +[Desktop Entry] +Encoding=UTF-8 +Comment=PCB layout +MimeType=application/x-pcb-layout +Type=MimeType +Icon=application-x-pcb-layout +Patterns=*.pcb +X-KDE-IsAlso=text/plain Index: tags/2.3.0/data/x-pcb-netlist.desktop =================================================================== --- tags/2.3.0/data/x-pcb-netlist.desktop (nonexistent) +++ tags/2.3.0/data/x-pcb-netlist.desktop (revision 33253) @@ -0,0 +1,8 @@ +[Desktop Entry] +Encoding=UTF-8 +Comment=PCB netlist +MimeType=application/x-pcb-netlist +Type=MimeType +Icon=application-x-pcb-netlist +Patterns=*.net +X-KDE-IsAlso=text/plain Index: tags/2.3.0/doc/Autostyle.html =================================================================== --- tags/2.3.0/doc/Autostyle.html (nonexistent) +++ tags/2.3.0/doc/Autostyle.html (revision 33253) @@ -0,0 +1,16 @@ + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ Index: tags/2.3.0/doc/Autostyle.sh =================================================================== --- tags/2.3.0/doc/Autostyle.sh (nonexistent) +++ tags/2.3.0/doc/Autostyle.sh (revision 33253) @@ -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/2.3.0/doc/Autostyle.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/Makefile =================================================================== --- tags/2.3.0/doc/Makefile (nonexistent) +++ tags/2.3.0/doc/Makefile (revision 33253) @@ -0,0 +1,68 @@ +MENU_RES=../src/pcb-menu-default.lht +KEYLIST=../util/keylist.sh +DEBLIST=../util/devhelpers/deblist.sh +ROOT=.. + +all: keys.html user/05_ui/04_common/keytree.svg user/05_ui/04_common/keytree.txt + ROOT="" ./Autostyle.sh *.html + ./datasheet.sh + +include ../Makefile.conf + +user/05_ui/04_common/keytree.svg: $(MENU_RES) $(KEYLIST) + $(KEYLIST) --dot user/05_ui/04_common/src/node_names.txt $(MENU_RES) > user/05_ui/04_common/keytree.dot + dot -Tsvg < user/05_ui/04_common/keytree.dot >user/05_ui/04_common/keytree.svg + +user/05_ui/04_common/keytree.txt: $(MENU_RES) $(KEYLIST) + $(KEYLIST) --lst $(MENU_RES) > user/05_ui/04_common/keytree.txt + + +keys.html: $(MENU_RES) $(KEYLIST) + $(KEYLIST) $(MENU_RES) > keys.html + +install_main: + $(SCCBOX) $(HOW) *.html *.txt TODO $(DOCDIR)/ + +install: + $(SCCBOX) mkdir -p "$(DOCDIR)" + cd man && $(MAKE) install + cd user && $(MAKE) install + cd tutorials && $(MAKE) install + cd security && $(MAKE) install + cd conf && $(MAKE) install + cd developer && $(MAKE) install + $(MAKE) install_main HOW="install -f -d" + +linstall: + cd man && $(MAKE) linstall + cd user && $(MAKE) linstall + cd tutorials && $(MAKE) linstall + cd security && $(MAKE) linstall + cd conf && $(MAKE) linstall + cd developer && $(MAKE) linstall + $(MAKE) install_main HOW="install -f -l -d" + +uninstall: + cd man && $(MAKE) uninstall + cd user && $(MAKE) uninstall + cd tutorials && $(MAKE) uninstall + cd security && $(MAKE) uninstall + cd conf && $(MAKE) uninstall + cd developer && $(MAKE) uninstall + $(MAKE) install_main HOW="install -f -u -d" + +clean: + cd man && $(MAKE) clean + cd user && $(MAKE) clean + cd tutorials && $(MAKE) clean + cd security && $(MAKE) clean + cd conf && $(MAKE) clean + cd developer && $(MAKE) clean + +distclean: + cd man && $(MAKE) distclean + cd user && $(MAKE) distclean + cd tutorials && $(MAKE) distclean + cd security && $(MAKE) distclean + cd conf && $(MAKE) distclean + cd developer && $(MAKE) distclean Index: tags/2.3.0/doc/README =================================================================== --- tags/2.3.0/doc/README (nonexistent) +++ tags/2.3.0/doc/README (revision 33253) @@ -0,0 +1,12 @@ +pcb-rnd documentation: work in progress. + +Most notable subdirectories: + conf/ documentation of the configuration system + developer/ documentation for developers + devlog/ random thoughts and articles + man/ UNIX manual pages + resources/ logos, screenshots, artwork + security/ notifications about security-critical bugs + tutorials/ my-first-board tutorials + user/ user reference manual + Index: tags/2.3.0/doc/TODO =================================================================== --- tags/2.3.0/doc/TODO (nonexistent) +++ tags/2.3.0/doc/TODO (revision 33253) @@ -0,0 +1,108 @@ +0. old, still waiting for ack + +1. For the upcoming release =============================================================================== + +2. For later releases =============================================================================== +- CLEANUP/BUG: bom export: load a board from menu, {f e} export; load another board from menu, {f e} export: output is set to the old file name; rnd_hid_parse_command_line() shouldn't mess with the default value but should use the value field (keep default for compatibility?) plus bug_files/export.patch [report: Igor2] +- CLEANUP: TODO39: replace vtlib with vtp0 because relocating arrays mess with pointers badly; qsort will get faster too [report: Igor2] +- CLEANUP: TODO27: undo's removed list shouldn't depend on object IDs but probably remove list index because IDs are not unique if we want our operations to retrain IDs. Repro: shift-click subc replace twice, then undo; or drag&drop move selected object and undo [report: Igor2] +- CLEANUP/BUG: undo operation while drawing a multiple segment line doesn't change segment attached to the crosshair [report:wojciechk8] + - tool_line.c depends on pcb_undo()'s return value; can be fixed only when the old undo system is removed +- CLEANUP: think over how to handle subc selection: selecting all parts automatically is bad for propedit; bug_files/subcsel.bug [report: Wojciech] + - BUG: propedit adding/deleting attributes inconsistency; search depth problem (see TODO#28) bug_files/subcsel.bug [report: Ade] +- CLEANUP: layer order from data + - central code for building a list of layer groups ordered by draw from front to back (omit disabled/invisible layers) + - rewrite both the draw_everything() and pcb_search_obj_by_location_() layer loop to use this list + - FEATURE: holes should be drawn below silk and mask - this could be a config setting +- FEATURE: make grid pixel size configurable [report: thet] +- FEATURE: tedax netlist parser: load comptag (and nettag) in a second pass [report: Bdale] +- FEATURE: auto enforce style clearance should be applied not only on drawing new lines but moving existing line endpoints as well [report: TwisteR] +- FEATURE: think over style clearance indication: on editing exisitng object it should probably be the clearance of the object [report: Ade] +- FEATURE: new breadboard + - FEATURE: gfx rotated pixmap scale adjustment: missing in lesstif, partly done (buggy on corner resize) in gtk ghid_draw_pixmap() + - FEATURE: hidlib: render pixmap: test in gl + - DOC: pool node on how to use pixmap for breadboading +- FEATURE: library window: allow long tags and long location text to split: rich text widget +- FEATURE: (TT) route style upgrade to prototypes - requires lihata v8: + - BUG: set same {e s s} doesn't work on padstacks [report: Igor2] + - BUG: padstack doesn't show drc xor shape while moving - because the whole drawing is a cheat for old vias [report: igor2] + - replace the route style dialog box's via part + - proto copy to buffer - a buffer with a single padstack should also serve as a prototype copy vehicle? or just import by a list from the buffer + - load/import from buffer and file + - CLEANUP: remove PCB_MIN_PINORVIA* PCB_DEFAULT_DRILLINGHOLE macros - nothing should use them anymore + - add text font, update the pool node text_edit [report: Igor2] +- FEATURE: DOC: new examples + - blinking led with parametric footprints + - example of nonetlist: 1206 jumpers and logos +- FEATURE: export_dsn/new io_dsn (with King Kevin and celem) (NGI0): + - missing global padstack (via) export: + - FEATURE: need to think over and check the spec for how to do this with no-hole padstacks + - RTT tests: thermal_layer.dsn, comp1.dsn, padstack.dsn + - BUG: elem_pads_ds: do not export line shape in padstacks as polygons, that kills round cap lines +- BUG: draw a bus, draw a polygin around the bus, cut bus to buffer, paste bus -> poly is not clipped ml4504 [report: Majenko] +- BUG: {w d}, config, drc_query, edit definitions, change min drill value -> value on the change button doesn't refresh [report: bdale] +- BUG: built-in irc client: pick a nick too long and the client will never recognize itself after connect (can't send messages); also test nick collision on connect [report: aron] +- BUG: edakrill: loading micro-usb-U-F-M5DD-Y-1 from wget@edakrill fails because the .fp version is loaded while the conversion failed [report: aron] +- BUG: Lihata persistent save: + - flag compatibility: save unknown, string-flags as loaded by io_pcb + - ind: FONTS: second font indents incorrectly + - ind: indentation bug in inline struct therm: closing } is preceded by indentation whitespace for some reason + - keep numeric format: test all + - keep unknown subtrees + - doc/user/02_model/src/obj_arc.lht: Open/Save : Font section is embedded. Once manually removed, the file shows many diffs w.r.t original. Lihata V1 file. + - BUG: lhtpers indentation: bug_files/lhtpers_ins/; breakpoint in pers_table.c:34 and debug why the newline is getting in [report: Igor2] +- BUG: I/O bugs: + - eagle: + - BUG: xml: eagle XML import fails on polygon import reported by miloh, test file pcb-rnd-aux poly_selfi/eagle_polygon_crash.brd [report: erich], due to input file containing an invalid polygon: a self intersecting poly in line 156 - consider handling "width"? + - bin: eagle binary format v3 and libraries do not have a DRC block specifying restring or minimum feature widths. Binary loader should add a DRC block in these cases to the tree with the minimum settings needed for padstacks and features to load sensibly. [erich]. + - bin: padstack clearances for element pins will rely on connectivity to other polygons layer by layer defined in the netlist + - bin: need to add support for non top silk (tPlace), tDocu and top copper text in read.c + - revise all I/O plugins for: + - upgrade autotrax with standard text for rotation, scale_x, scale_y anbd mirror_x (need test cases) + - padstacks + - new outline/mech layers and slots + - new doc layers + - polygon side clearance (e.g. CUCP#38 provided by Karl) +- BUG: Rubberband move line endpoints ignores connected arc endpoints. [Fixing:Ade] + +3. Long term =============================================================================== +- version 3.0.0: + - rename pcblib to footprint-rnd! rename pcblib/tru-hole to fix the typo; update configs + - ./configure --config should default to /etc +- BUG: in poly lib rewrite: bug_files/polyclpoly.lht: excess clearing into the corner of the outer poly; move the line a bit and it tends to disappear ml=3493 [report: gpaubert] +- BUG: in poly lib rewrite: bug_files/phatch.lht: maybe {m d t} and PolyHatch(0, c) -> poly offseting bug on sharp corners ml=4159 [report: Majenko] +- FEATURE: "thermal recipe" so a padstack thermal can be put in a padstack or subc and it is changed with the layer binding [report: jg] +- FEATURE: a {c f}-like feature that doesn't flag the network but prints the net name on objects large enough ; alternative: net name caching and display when zoomed in [report: Majenko] +- FEATURE: netlist2: bug_files/ratside.txt optional rats constraints [report: Vuokko] +- FEATURE: openems mesher: do not ignore padstack copper [report: Evan] +- FEATURE: padstack bbox: + - per layer: keep a bbox per transformed shape per prototype, then getting the bbox of a padstack ref on a specific layer is looking up the shape, then 4 integer additions [report: Wojciech] + - when calculating overall padstack bbox, ignore layers that are not present? but then a layer change would require a recalc (but this is true for subcs too!) [report: Wojciech] +- FEATURE: depth controlled mech layers (routed) for internal cavities: http://www.saturnelectronics.com/products_capabilities/internal-cavity_boards.html -> user script, similar to on_every_layer: convert lines into bbvia slot padstacks; only when we already export bbvia in excellon; alternative: layer attribute on mech layers +- XOR rendering upgrade: + - experiment with 'emboss' kind of drawing instead of xor so rendering can stay 'direct' + - if worked: allow padstack xor draw to draw all shapes on all layers +- CLEANUP: layer group rewrite: remove PCB_MAX_LAYERGRP and PCB_MAX_LAYER and make them dynamic +- CLEANUP: reduce: get rid of autorouter/vector.[ch] +- vendor drill plugin: + - CLEANUP: check if we want to keep vendor name + - CLEANUP: search for /units, replace it with pcb-printf something + - CLEANUP: replace ignore_refdes, ignore_value and ignore_descr with genvector + - FEATURE: vendor: be able to load multiple vendor files (project spec for skips, central for vendor) [report: celem] + - FEATURE: add round down +- FEATURE: lihata v8 + - load/save text clearance (and make sure the GUI can set it), then remove the 0.5mm hardwired value from polygon.c + - deprecate saving rats [report: Igor2] + - make saving selected, found and warn flags optional to reduce VCS noise [report: Igor2] + - remove netlist net ->style, should be a plain attribute (but keep the dedicated field in old versions) + - remove via geometry from route style + - manual layer binding (to LID) + +4. Low prio =============================================================================== +- BUG?: Far-side silk text can be selected and moved when the mouse is over front-side subcircuit. (but this is what we had with elements too! -> rewrite search.c to be a 'script' config) bug_files/farsilk.lht [report: Ade] +- BUG: elliptic: gtk2_gl: RTT/arc_sizes.lht - elliptical arc corner case render bug [report: Wed] +- BUG: elliptic: RTT/arc_sizes.lht - unable to move arcs which have different width and height [report: Ade] - rewrite pcb_is_point_on_arc() elliptical case at the bottom +- FEATURE: improve locking: consider a move-only lock? +- FEATURE: DRC should warn for thin poly hair +- FEATURE: io_pcb: new, optional "layer tag" field in mainline's file format +- FEATURE: scconfig: menuconfig and a config file for scconfig: requires a more declarative dependency handling system Index: tags/2.3.0/doc/TODO.drc_query =================================================================== --- tags/2.3.0/doc/TODO.drc_query (nonexistent) +++ tags/2.3.0/doc/TODO.drc_query (revision 33253) @@ -0,0 +1,12 @@ +User requested (accepted): + - silk over mask or paste [Vuokko] + + zone poly based short/broken test; ml=3926 [Vuokko] + +Cheap tests, need custom func: + - text containing non-render chars + +Possible tests (old): + - non-pstk paste object over mask or silk + - non-pstk paste object over hole? + - polygon hair, polygon too thin - Gabriel's example: mask being too thin between smd pads + - top/bottom copper keep-away from outline layers (peel-off on cutting with some fabs) Index: tags/2.3.0/doc/TODO.lesstif =================================================================== --- tags/2.3.0/doc/TODO.lesstif (nonexistent) +++ tags/2.3.0/doc/TODO.lesstif (revision 33253) @@ -0,0 +1,120 @@ +**** lesstif blockers **** + +- lesstif blockers: + - BUG: lesstif hbox/vbox allocation issues: test with bug_files/ltf_fillbox/ patches applied, with the fontsel action; opening it multiple times will randomly show or hide the button + / hvbox: fontsel, about dialog: resize to smaller doesn't re-layout -> missing concept of mininum size vs. current size + - tabbed: redisplay bug in the about box (box opens broken, first tab switch fixes it) + - re-enable HPANE: pstklib(), netlistdialog(), propedit(), BrowseScripts, preferences dialog config tab + - tree-table bugs; see below; preferences dialog: library, layers tabs are unusable + - BUG: { s s } doesn't hide frames of unused expressions, issues 94 lines to stderr Warning: Null child found in argument list to unmanage [report: Miloh] + - FEATURE: lesstif DAD support for toggle pushbuttons (with label or picture, see existing infra) -> motif does not support this! + +**** lesstif low prio **** + +- FEATURE: lesstif: implement/enable local grid in lesstif (menu option is disabled) + + +**** tree table detailed bugreports **** + +1. [critical] handling resize + +pcb-rnd does rely on dynamic layouts, which means widgets need to be able +to resize. + +Mechanism: when EXPFILL is disabled, the widget needs to be as big as its +children wants it to be. Without scroll bar, that means as big as the +content says. So if I do a table with only 2 rows, it should be exactly as +big as needed for hosting those 2 rows, and no bigger. When EXPFILL is +enabled, the parent dialog resizes the widget to the correct size, so that +it fills up all remaining space in the dialog. This means the widget must +react to resize requests properly and grow. + +2. [major] scroll + +This is somewhat related to scrollbars: please never draw the scrollbar if +it is not needed. If the widget is large enough to host all items without +scrolling, please hide the scrollbars. + +In EXPFILL mode disabled this means we will never have a scroll bar, +because the widget will just grow large enough to host all children, +without scrolling. We also have a SCROLL flag, so if there's enough API, +we can pass that on too, and limit this: if the widget is larger than some +maximum value (that we should be able through SetValues), it stops growing +and adds the scroll bar. But we definitely needs a mode where the widget +really just grows exactly as big as needed, for layout reasons, for small, +static tables. + +When EXPFILL mode is enabled, the widget must be exactly as big as the +parent says. If this size is smaller than the content, it should add the +scrollbars; if this size is larger than the content, it should hide scroll +bars, grow as requested and leave unused space empty. + +I think we need a boolean property for this, that we can set with +SetValue. It should be not be EXPFILL, because that's a boxing thing, but +should control whether minimum size request reported by the widget does +include all content (so we never get a scroll bar) or not (we get +automatic scroll bars depending on widget size vs. content size). + +3. [minor] header col padding doesn't work + +{e p} with no object: if there's no content, only the header, the +columns are not separated by anything. I think the same spacing should +apply that we have for the non-header cells. + +4. [minor] header background color + +at the moment the header background color is the same as the selection +background color, this way it is not possible to distinguish between +header and selection. I think we should use a different background color +for the header. + +5. [critical] on ett_mouse_btn_down, the current_cell field is always 0. + +Please note: I'd like to get a special value (different from 0) here if +the user clicked on the indentation/tree-pixmap part, so I know when I +need to do the collapse/expand. + + +6. [major] shouldn't a xm_extent_prediction() call be part of the xm_draw_tree_table_widget() call? + +I'm adding (inserting, appending) new rows on the run. I need to call +xm_extend_prediction() to get the rows in the right spot on the screen, +but this call is in the priv header. Or is there another API call I should +do after making modifications to the tree model? + +7. [normal] global sym prefix + +public, global symbols must be prefixed, and xm_ is not a good prefix +e.g. for extend_prediction(). The other prefix, "xm_tree_table_" is way +too long for a namespace prefix. + +Please rename any non-static function and variable to have the same, short +prefix: Pxmtt_. I started to use Pxm for our other locally implemented +widgets, I think it is in-line with motif naming conventions. P stands for +"pcb-rnd", xm is for motif, and then we should have something for the +widget. If that something is always very short, one word, like with +the FillBox implementation, the prefix can be longer, but the tree table +names are long, so I'd prefer to have just tt as widget-specific prefix +there to keep names short. + +8. [minor] pixmaps + +We also need to revise the pixmap part, it pollutes the +gobal namespace with unprefixed things like "make_pixmap_data". + + +9. [normal] row location computation error + +please open the preferences with {i c p}, click the last tab (config), +place the cursor on the first node on the large tree on the left, then +start pressing the 'down' arrow key. After each cursor change, I call +xm_tree_table_focus_row() to adjust the scroll if needed. + +It seems on long trees there is some error in the calculation and the +lower we go the bigger the difference between the scroll and the actual +row location is. + + +10. [minor] compiler warning + +event pointer vs. enum: ../src_plugins/hid_lesstif/xm_tree_table_widget.c:337:25: warning: expression which evaluates to zero treated as a null pointer constant of type 'XEvent *' (aka 'union _XEvent *') [-Wnon-literal-null-conversion]: tp->event_data.event = ett_none; Index: tags/2.3.0/doc/TODO.opengl =================================================================== --- tags/2.3.0/doc/TODO.opengl (nonexistent) +++ tags/2.3.0/doc/TODO.opengl (revision 33253) @@ -0,0 +1,2 @@ +- BUG: different padstack color with default settingsbetween gtk2_gl: bug_files/gl_pstk/* (sw render) and gtk2_gdk may make hole disappear (private mailing, 2019-06-24) +- BUG: xor draw (e.g. selection box or tool's crosshair attached line) does not result in the same color as in gdk Index: tags/2.3.0/doc/UNIX.txt =================================================================== --- tags/2.3.0/doc/UNIX.txt (nonexistent) +++ tags/2.3.0/doc/UNIX.txt (revision 33253) @@ -0,0 +1,31 @@ +State on UNIX systems +~~~~~~~~~~~~~~~~~~~~~ + +Source releases starting from 1.1.2 should compile and run out-of-the-box +on old UNIX systems, such as IRIX. Does NOT require any GNU installed. + +Requirements: + - x11 and motif (for the GUI) + - an awk implementation that supports gsub(), e.g. nawk + +1. If your C compiler does not support #warning, run a script to patch + the source: + + # cwd is the root of the distribution + util/workarounds/unwarn_all.sh + + This will take a while and will modify a lot of .c files. + +2. ./configure + +3. make + +Considerations listed in ../INSTALL apply. + +The above procedure has been tested on IRIX 5.3 on IP22. + +Expected compilation times [minute:second]: + +./configure compile, -O0 compile -O3 system +------------------------------------------------------------------------------- +1:55 7:40 14:27 IRIX 5.3, IP22 @ 100 MHz Index: tags/2.3.0/doc/conf/Makefile =================================================================== --- tags/2.3.0/doc/conf/Makefile (nonexistent) +++ tags/2.3.0/doc/conf/Makefile (revision 33253) @@ -0,0 +1,27 @@ +ROOT=../.. +CFDIR=$(DOCDIR)/conf + + +all: + +install_all: + $(SCCBOX) mkdir -p $(CFDIR)/tree + $(SCCBOX) $(HOW) *.html *.png $(CFDIR)/ + $(SCCBOX) $(HOW) tree/*.html $(CFDIR)/tree/ + + +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/2.3.0/doc/conf/groups.html =================================================================== --- tags/2.3.0/doc/conf/groups.html (nonexistent) +++ tags/2.3.0/doc/conf/groups.html (revision 33253) @@ -0,0 +1,129 @@ + + + + pcb-rnd - config groups + + + +

The new config system in pcb-rnd

+

grouping - flat vs. tree

+The original settings and HID attribute system in pcb were both flat: +basically a list of type:key=val triplets. All settings in a few big bags; +which bag sometimes doesn't depend on some logical categorizing, but +historical reasons (e.g. which part of the code needs the given setting). +

+This works well for a small amount of settings but lack of categories or +hierarchy (or sets or groups) makes it harder to understand what setting does +what and orients users to just accept defaults. After a while it also +makes programmers think twice before adding a new setting, increasing the +crowd in a bag. This in turn results in a less configurable +system. +

+Introducing a hierarchy of settings can solve these problems by grouping +and categorizing settings. If the user is interested in how footprints are +searched, they can ignore the settings the editor/ subtree has. It is also +easier to save and reload selectively: when the hierarchy is done right, +closely related settings end up in the same category (thus the same subtree). +Thus saving or loading a subtree can fully save or restore a property of the +program, even if that property is affected by multiple settings. + +

pcb-rnd config tree

+The config tree, the full tree is, something that exists in memory. Actual +config files often contain only a subset of the tree. Multiple config files +(e.g. system level, user level, settings from the board file) are loaded and +merged to form the final config tree. The hierarchy of the tree is represented +by setting groups, which are like directories on a file system. Actual settings +are always leaves of the tree, placed in a specific group at any level (just +like in file systems). A full path to a setting is written like a +path on a file system: group1/group2/item, where group1 and group2 are +names of setting groups and item is the name of the setting. Note: unlike +with real file systems, the leading slash (representing the root) is omitted. +

+Details/constraints: +A valid path unambiguously identifies a setting (or a setting group). Settings +and groups always have exactly one parent (except for the root group that +has no parent). There is only one root of the config tree. +

+The main groups in the logical tree are: + +

+ +
(root)   (config root) +
|       +
+- rc run control (program startup) +
|       +
|   |   +
|   +- path paths automatically set up by the program at startup - do not specify these +
|       +
+- design some default settings of a new design; minimum/maximum value of some design settings +
|       +
+- editor how the pcb editor behaves - independent of HIDs or the GUI +
|   |   +
|   +- increments_mm interactive increment/decrement steps when active unit is mm +
|   |   +
|   +- increments_mil interactive increment/decrement steps when active unit is mil +
|   |   +
|   +- view default view parameters +
|       +
+- appearance how the GUI looks like - common to all GUI HIDs +
|   |   +
|   +- color layer colors, GUI colors, misc design colors +
|   |   +
|   +- pinout pin label properties +
|   |   +
|   +- messages message window properties +
|   |   +
|   +- misc non-GUI settings handled by the GUI HIDs +
|       +
+- plugins dynamic subtree for various plugin settings +
|   |   +
|   +- foo all settings of the imaginary foo plugin are registered in this group +
|       +
+- utils dynamic subtree for various plugin settings +
  |   +
  +- bar all settings of the imaginary bar utility are registered in this group +
+
+ +

dynamic subtrees

+ +The plugins/ and utils/ subtree are dynamic, which means their contents +are not defined by core pcb. +

+In plugins/ each plugin should create a group for its own settings. What +this subtree should contain depends on what plugins are actually loaded. +The benefit of this approach is that plugins can use the central config +infrastructure instead of inventing their own config files. This makes +user's life easier on many levels: single config syntax to learn; uniform +GUI (preferences dialog) to change all settings; uniform way to +save/restore parts of the settings. +

+The utils/ subtree is very similar in all aspects except that it is for +external utility programs. Utils that are closely related to pcb-rnd, such +as gsch2pcb-rnd, should work from the same configuration. +If they already load the +pcb-rnd config files it's easier to keep their settings in the same tree, +in the same format. +

+Pcb-rnd doesn't generate warning for unrecognized settings in dynamic subtrees. +This lets the user configure plugins that are not always loaded and let util +settings sit in their subtree. + +

what happens to all these settings

+ +After loading all config files they are merged: if the same setting is +described in multiple files, the higher priority wins or if the setting is +a list (e.g. library search paths) the items are merged in a final list. +At this point the full logical config tree is built. Next the textual values +from the logical tree are converted into binary (native C values like +"long int" or "double") and are saved in C variables for the code to +access them directly. + +

[hidlib] settings

+

+Settings marked with [hidlib] are those that are shared among all +applications based on pcb-rnd's hidlib. They have the same syntax +and meaning in all those applications. + + + Index: tags/2.3.0/doc/conf/history.html =================================================================== --- tags/2.3.0/doc/conf/history.html (nonexistent) +++ tags/2.3.0/doc/conf/history.html (revision 33253) @@ -0,0 +1,71 @@ + + + + pcb-rnd - config system - why + + + +

The config system in pcb-rnd - why

+ +

Why, what was wrong with the old one?

+The old config system had several limitations that would have been +hard to fix keeping the original design: +
    +
  • config settings were specified in a flat list - no grouping +
  • the core had a rather static system - HIDs or plugins couldn't extend it, thus they had to invent their own config files +
  • ... this led to a variety of configuration formats; using one format not always because it was better suited for the task, but for historical reasons +
  • ... this also led to a collection of config files - again not always split by boundaries of settings, but often by arbitrary boundaries of code +
  • the old system didn't support lists or arrays well +
  • it didn't have a coherent concept of how settings from different sources would override each other +
  • ... this resulted in the rigid structure that most of the settings could come from only one place (e.g. if it's an user setting, the design won't be able to override it) +
+ +

What the new system offers

+
    +
  • unified format: lihata ... +
  • ... more future proof: generic markup language - easier to extend without having to worry about breaking the syntax +
  • ... the configuration is represented in a tree, grouped by the nature of settings +
  • ... there are arrays and lists +
  • ... a config file can overwrite a list or prepend/append to it (e.g. design-level config prepending an extra library path keeping system set paths as well) +
  • there are different sources of configuration, e.g. system-wise, user-wise, project-wise, etc. +
  • the user has the power to change default config priority per setting; e.g. normally design config overrides user config, but it's possible to mark a setting from user config so strong that it overrides even the setting read from the board file +
  • the way settings are stored is flexible and extensible so that a plugin can define their subtree of settings +
  • ... since the API even makes it easier to access such settings (vs. parsing your own config file), plugins will tend to use the unified config format/system instead of inventing their own +
  • ... the GUI (preferences dialog) thus can automatically handle the new settings +
  • ... plugins don't have to implement actions to set/toggle/query their settings for the menu system, there are generic config set/toggle/query actions the menu config can use +
  • ... plugins also get the multi-source, priority-based config mechanism +
  • ... which also means plugin settings can be automatically saved as user setting, project setting or even design setting +
  • all these are true for all kind of settings, be them GUI preferences, paths, layer colors, grid settings; there should be no exception +
+ +

But isn't this more complicated for the user?

+Hopefully not much. There are a few extra features, like +multiple sources with levels that did not +exist in pcb and lists with prepend/append. Some of these +features present in other software so users should be comfortable with the ideas. +The learning curve is probably compensated by the more orthogonal system. +The syntax is also geared for simplicity and easy use with text editors. +Finally, the new preferences dialog and config actions help +the user to explore how settings got used from all the config sources. There's +an intended layering in complexity: simple things can be done easily without +having to understand the whole system. +

+All in all, the extra features the user needs to learn is comparable with +the old customs that he/she can forget. + +

And did it make the code more complicated?

+The size of the code did not change much after the initial config rewrite. +The new system has new features, some of which brought in a few hundred lines of +code, but a similar amount of old code could be removed. What came in is +infrastructure, what had to go was a bunch of repetitive config parsing, +boolean-setting-accessor-action code. This means on the long run, the more +settings are added, the more the new system pays back. +

+Read access, which is far the most common way to use the config in the +code (e.g. if (setting == true) { }) is very similar to the old Settings +system. Write access needs to go through a function call API, but this +is usually a single call per setting (instead of directly modifying a +variable). +

+For plugin programmers, the new system makes life much easier as they can +plug their settings in. Index: tags/2.3.0/doc/conf/index.html =================================================================== --- tags/2.3.0/doc/conf/index.html (nonexistent) +++ tags/2.3.0/doc/conf/index.html (revision 33253) @@ -0,0 +1,20 @@ + + + + pcb-rnd - config system + + + +

The config system in pcb-rnd

+ +

How to get started

+ + + + Index: tags/2.3.0/doc/conf/index_prog.html =================================================================== --- tags/2.3.0/doc/conf/index_prog.html (nonexistent) +++ tags/2.3.0/doc/conf/index_prog.html (revision 33253) @@ -0,0 +1,14 @@ + + + + pcb-rnd - config programmer's index + + + +

The new config system in pcb-rnd

+

Programmer's documentation

+ +TODO + + + Index: tags/2.3.0/doc/conf/index_user.html =================================================================== --- tags/2.3.0/doc/conf/index_user.html (nonexistent) +++ tags/2.3.0/doc/conf/index_user.html (revision 33253) @@ -0,0 +1,99 @@ + + + + pcb-rnd - config for users + + + +

The pcb-rnd config system

+

User documentation

+As of 1.1.0, pcb-rnd switched to a lihata based configuration system. +The purpose of this document is to describes the basic system design going into +enough details to provide the user with full control over the configuration. +The other side, how the system is implemented is described in the + programmer's manual and there is also a +checklist to assist plugin programmers. + +

Architecture: data flows, merging, dispatching

+The final configuration is a collection of values for + all known settings, arranged in a tree. The config +tree is a theoretical concept; different representations of the tree are +actually built runtime, in-memory. Pcb-rnd code, plugins and utilities +are constantly reading these in-memory representations to decide how to +carry out their tasks. +

+Config settings are imported from multiple sources: from different files, +from environment variables, from command line arguments, from the opened (.pcb +or .lht) board files on load. Any source can define any part of the config tree. +When the configuration is processed, each source is read into a temporary +tree and then all the temporary trees are merged into the final +config tree. The following diagram demonstrates all configuration +related data flows. +

+[diagram] +

+The leftmost column of nodes are the sources. (Note: paths mentioned there are +the default paths, for reference, it is possible to change them compile-time.) +Along the black arrows, from left to right, each source is imported into a +tree representing a role: the role or +purpose of the source. The next +step is following the red arrows in two steps: +
    +
  • first merge all the role trees into a flat list; this determines the value of each setting; +
  • then dispatch the values to the right component of the code. +
+Some components may change some of the settings run-time. The trivial example +is the GUI (preferences dialog on this diagram) that provides menus and dialog boxes for +the user to change settings. Such a change is always fed back (blue arrow) +to the design role tree directly, from where the new value is again merged +and dispatched along the red arrows. Changes in the design role are saved +with the board file (thus the bidirectional black arrow between the source and +the in-memory tree for the design role). Occasionally the user wants to +save parts of the setting as a project setting or +as an user setting - in this case, along the dashed blue lines, the +corresponding project or user roles are modified. This again results in updating +the hash and the binary representation; these roles also have +bidirectional black arrows and their changes are also saved in the original +source. + +

Merge details

+In the new system it is up to the user to decide what settings are +system-level and what settings are user- or project-level. This is possible +because any source can define any setting. In the merging step (red arrows +between roles and the hash) it may turn out that there are overlaps (multiple +sources defining value for the same setting) or blind spots (no source +sets a given item). + +

overlaps

+Each setting in each source has a priority. The +priority can be defined in the source, or if it is not defined, each source +inherits a fallback default priority. The fallback is designed to provide +the intuitive order: cli > design > project > user > system. +

+When multiple sources are describing a value for the same setting, +priority decides the final value. Most settings are scalar: +a single integer, string or a single "yes/no" or "on/off" value (e.g. +the background color or whether polygons are thin-drawn). For scalars +the rule is simple: the higher priority value wins and all lower priority +values are discarded when putting the values into the hash. More +details: how different roles and priorities +can be used with scalars. + +

+There are some settings that are represented as an array or list of +values. They are described in a lihata list item ("li:") in the config +files and are generally called lists in this document. How lists +are merged is controlled by the merging policy, which can be +in each source, just like the priority is set. Check out the +list merging section for more details. + +

blind spots

+At the end the code does need a value for each setting, so in the final +render (after the hash) every setting must have a value. To avoid blind spots, +values not initialized, there is a built-in configuration file, compiled into +the executable. This file is loaded into role CFR_INTERNAL, and has +the lowest priority. This configuration file contains the default value for +all settings. + + + Index: tags/2.3.0/doc/conf/lists.html =================================================================== --- tags/2.3.0/doc/conf/lists.html (nonexistent) +++ tags/2.3.0/doc/conf/lists.html (revision 33253) @@ -0,0 +1,147 @@ + + + + pcb-rnd - config lists + + + +

The new config system in pcb-rnd

+

Lists and arrays

+ +Non-scalar settings are arrays or lists. Arrays can be explicitly indexed + +The default policy is always overwrite. +

+There are three active policies: overwrite, prepend and append. +When dealing with lists: +

    +
  • step 1: the output list is reset to empty +
  • step 2: all sources that describe the list are sorted by priority +
  • step 3: sources are applied in order +
+Step 3 is straight-forward: if policy is overwrite, reset the output +list and copy the source's list into the output list. If policy is +prepend (or append), keep the current output list and prepend +(or append) the list provided by the source. +

+In practice this means the user can replace, prepend or append ordered lists +from various sources. A common example is setting the library search paths. + +

examples

+ +

simple overwrite

+Config sources (ordered by priority): + +
role priority policy content +
system 200 overwrite A,B,C +
user 400 overwrite (not defined) +
project 600 overwrite D,E +
+

Merge iterations: + +
step description output list after executing this step remarks +
0. reset the output (empty)   +
1. apply system A,B,C   +
2. apply user A,B,C "not defined" doesn't mean "empty", so the list is not deleted - no change +
3. apply project D,E replace the original output because of the overwrite policy +
+

Example scenario: the project is restricted to local footprint libs; this setup +makes sure no system or user configuration injects external footprint paths. + +

empty overwrite

+Config sources (ordered by priority): + +
role priority policy content +
system 200 overwrite A,B,C +
user 400 overwrite (not defined) +
project 600 overwrite defined to be an empty list +
+

Merge iterations: + +
step description output list after executing this step remarks +
0. reset the output (empty)   +
1. apply system A,B,C   +
2. apply user A,B,C "not defined" doesn't mean "empty", so the list is not deleted - no change +
3. apply project (empty) replace the original output because of the overwrite policy +
+ +

prepend

+Config sources (ordered by priority): + +
role priority policy content +
system 200 overwrite A,B,C +
user 400 prepend (not defined) +
project 600 prepend D,E +
+

Merge iterations: + +
step description output list after executing this step remarks +
0. reset the output (empty)   +
1. apply system A,B,C   +
2. apply user A,B,C "not defined" doesn't mean "empty", so the list is not deleted - no change +
3. apply project D,E,A,B,C   +
+

Example scenario: the project has its own footprint libs with two paths; these +should be searched before system and user paths, still, system path is also +kept so stock footprints can be found. +

+This is better than hardwiring A,B,C in the project's list: A, B and C may +depend on the installation on a given system. A project file has no idea +about how the system is installed but it is assumed system installation +and the system configuration file are consistent. + +

append

+Config sources (ordered by priority): + +
role priority policy content +
system 200 overwrite A,B,C +
user 400 append (not defined) +
project 600 append D,E +
+

Merge iterations: + +
step description output list after executing this step remarks +
0. reset the output (empty)   +
1. apply system A,B,C   +
2. apply user A,B,C "not defined" doesn't mean "empty", so the list is not deleted - no change +
3. apply project A,B,C,D,E   +
+

Example scenario: the project has its own footprint libs with two paths; these +should be searched after system and user paths. This means the local footprint +lib has lower priority than the stock footprints. See system-dependent +installation remarks in the previous point. + + +

prepend+append

+Config sources (ordered by priority): + +
role priority policy content +
system 200 overwrite A,B,C +
user 400 prepend X,Y,Z +
project 600 append D,E +
+

Merge iterations: + +
step description output list after executing this step remarks +
0. reset the output (empty)   +
1. apply system A,B,C   +
2. apply user X,Y,Z,A,B,C   +
3. apply project X,Y,Z,A,B,C,D,E   +
+ + +

list and hlist

+

+There are two kinds of lists: string list (simply called list) and hash-list +(called hlist). +

+Each element of a hlist is a hash node in the lihata conf file. These hash +nodes are opaque to the conf system and must be processed by the plugin that +uses the hlist. Normal merging still works on hlists: opaque elements can be +prepended or appended and the whole list can be overwritten. +

+Each element of a plain (string) list is a text node in the lihata conf file, +which is stored as a string in the memory by the conf system. + + + Index: tags/2.3.0/doc/conf/merging.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/conf/merging.png =================================================================== --- tags/2.3.0/doc/conf/merging.png (nonexistent) +++ tags/2.3.0/doc/conf/merging.png (revision 33253) Property changes on: tags/2.3.0/doc/conf/merging.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/conf/noextend.html =================================================================== --- tags/2.3.0/doc/conf/noextend.html (nonexistent) +++ tags/2.3.0/doc/conf/noextend.html (revision 33253) @@ -0,0 +1,67 @@ + + + + pcb-rnd - old config + + + +

The OLD config system in pcb-rnd

+

If the config system is too static

+ +This document describes the old situation, focusing on drawbacks for +a purpose: to give a hint on why some of the design decisions are made +the way they are, in the new conf system. + +

Settings, preferences, colors, and...

+The core implemented a so called Settings. It was a flat list of items, +each bound to a C variable. There was a bunch of metadata attached to +the items: name, type, description. Generic code could query or change +the value of any setting, the C code could read and write them directly +too. The content was saved to ~/.pcb/settings. +

+On the downside, the actual items this system knew about was pretty much +static, hardwired in core. A plugin could not register its own settings. +Multiple parallel methods were present in the code to overcome this +limitation: +

    +
  • HID attributes: another way to describe name-type-metadata lists; this + was used to pass on some rc-like parameters to the GUI HIDs. It's also the + main API to describe export parameters for the export HIDs. However, + HID attributes is not well suited for saving plugin (or HID) user + preferences, it is more about a per action configuration. + +
  • The gtk HID also saved its own settings to a separate file called + ~/.pcb/preferences. + +
  • Some gtk HID settings didn't quiet fit in the preferences - the color + scheme can be saved in another file, usually under ~/.pcb/colors + +
  • A random plugin could either use the HID attributes to get a limited + service or like the gtk HID did, had to implement its own save-restore of + persistent settings. +
+ +

Meta-drawbacks

+This also introduced a more subtle drawback: the configuration was now +scattered into different files, randomly (looking from the +user's point of view). In other words, the actual structure did not reflect +some logical grouping, but mostly historical or source code organizational +reasons. +

+In turn, this also limited (again somewhat randomly) what settings can be +stored system-wise, user-wise, or on project or design level. +

+Finally, handling of file search paths was not very sophisticated. There +was the system and user configuration that reflected where the stock +library or the user's generic library were installed. And then +there was the per-project local footprint libs that had to be somehow +added too. +

+There was a hardwired way of handling the situation where multiple set +of paths were specified. In practice it was usually possible to get this +to work for the simpler cases, but it was not powerful enough to express +things like "use all system and user libraries first, then the project's local +library" vs. "the project's local library has priority over system libraries". + + + Index: tags/2.3.0/doc/conf/plugin_chk.html =================================================================== --- tags/2.3.0/doc/conf/plugin_chk.html (nonexistent) +++ tags/2.3.0/doc/conf/plugin_chk.html (revision 33253) @@ -0,0 +1,14 @@ + + + + pcb-rnd - config plugin checklist + + + +

The new config system in pcb-rnd

+

Plugin programmer's checklist

+ +TODO + + + Index: tags/2.3.0/doc/conf/prio.html =================================================================== --- tags/2.3.0/doc/conf/prio.html (nonexistent) +++ tags/2.3.0/doc/conf/prio.html (revision 33253) @@ -0,0 +1,27 @@ + + + + pcb-rnd - config priorities + + + +

The new config system in pcb-rnd

+

Priorities

+ +Priority is an integer property of each config root. +Syntax-wise it is part of the name of the config +root. In the lihata config file it is either specified or omitted. When +omitted, a role dependent default value is +used. The default values are chosen in an intuitive way, thus most +commonly the priority value is omitted. +

+For scalar settings, the highest priority +value determines the final value of a setting after the merge. If there +is a tie, role decides: the role closer to the CLI is stronger. +

+For lists and arrays, priority determines the +order of merge, which changes the order of items in the final list as +config roots prepend and append items. + + + Index: tags/2.3.0/doc/conf/scalars.html =================================================================== --- tags/2.3.0/doc/conf/scalars.html (nonexistent) +++ tags/2.3.0/doc/conf/scalars.html (revision 33253) @@ -0,0 +1,61 @@ + + + + pcb-rnd - config scalars + + + +

The new config system in pcb-rnd

+

Scalars

+ +Scalar settings have only one value after the merge. The only policy +available is overwrite - this policy is applied regardless of the +current policy setting. + +

examples

+ +

simple overwrite

+Config sources: + +
role priority policy content +
system 200 overwrite A +
user 400 overwrite (not defined) +
project 600 overwrite Q +
+

+Merge iterations: + +
step description output list after executing this step remarks +
0. reset the output (empty)   +
1. apply system A   +
2. apply user A "not defined" doesn't mean "empty", so the list is not deleted - no change +
3. apply project Q replace the original output because of the overwrite policy +
+

Example scenario: system default overridden by a project setting. + +

user-forced value

+Config sources append: + +
role priority policy content +
system 200 overwrite A +
user 650 overwrite E +
project 600 overwrite Q +
+

+Merge iterations: + +
step description output list after executing this step remarks +
0. reset the output (empty)   +
1. apply system A   +
2. apply project Q   +
3. apply user E   +
+

Example scenario: user preference enforced: even if the project file would use +'Q' for the given setting, the user prefers 'E'. This affects runtime +(the value of the setting after the merge, in other words how pcb-rnd works), +but does not change the project configuration. This allows the given user to +always use 'E' for the given setting while lets other users working on the +same project use the value set in the project file. + + + Index: tags/2.3.0/doc/conf/sources.html =================================================================== --- tags/2.3.0/doc/conf/sources.html (nonexistent) +++ tags/2.3.0/doc/conf/sources.html (revision 33253) @@ -0,0 +1,89 @@ + + + + pcb-rnd - config sources + + + +

The new config system in pcb-rnd

+

Sources

+There are different sources of configuration settings. These are +different configuration files, sometimes located on the file system. +The full list of config sources is: + + +
role default
setting
prio
location presence remarks +
internal + 100 + (compiled into the executable) + always + the ultimate fallback; allows pcb-rnd even if no other configuration file is found + + +
system + 200 + /usr/share/pcb-rnd/pcb-conf.lht + recommended + should hold system and installation specific settings, e.g. path to the system-wise installed footprint library + +
default board + 300 + /usr/share/pcb-rnd/default4.lht1 + deprecated2 + pcb editable defaults + +
user + 400 + ~/.pcb-rnd/pcb-conf.lht + recommended + store user preferences, user's common footprint lib path, etc; this is the first file the user can modify (even from the GUI) + +
environment + 500 + environment variables (TODO) + occasional + inject the same (temporary) settings in multiple pcb-rnd sessions without having to change config files + +
project + 600 + project.lht in the project directory + optional + local project settings - useful for large projects with multiple board (.lht) files + +
design + 700 + saved in the board (.lht) file + optional, common + per design deviation from the user+system config + +
cli + 800 + command line argument + occasional + inject/change a setting for a single session; useful in batch/automated processing +
+ +

+Pcb-rnd reads them all, then merges all settings into a master binary +representation. If a setting is specified in multiple sources, the one +with the higher priority wins, except for lists where it is also possible +to prepend/append items. Default priorities are designed to result +precedence in an intuitive way (e.g. design settings overwrite user settings). +However, priority can be changed per setting, resulting +in weak settings ("use this value if it was not already set") or strong settings +("I always want to use mincut, so I enable it from my user's config with high +priority and a version controlled project setting can not turn it off") + +

+Footnotes: +

    +
  • 1: the name of the default board is default4.lht for + the default 4 layer board. The standard installation also ships default2.lht + as a similar 2 layer board. The name of the default boardfile is configured + in config node rc/default_pcb_file. +
  • 2: default pcb should not contain a config subtree; it is + easier to maintain the config tree if default configuration is coming from + config files only. +
+ + Index: tags/2.3.0/doc/conf/src/Makefile =================================================================== --- tags/2.3.0/doc/conf/src/Makefile (nonexistent) +++ tags/2.3.0/doc/conf/src/Makefile (revision 33253) @@ -0,0 +1,2 @@ +../merging.png: merging.dot + dot -Tpng merging.dot > ../merging.png \ No newline at end of file Index: tags/2.3.0/doc/conf/src/merging.dot =================================================================== --- tags/2.3.0/doc/conf/src/merging.dot (nonexistent) +++ tags/2.3.0/doc/conf/src/merging.dot (revision 33253) @@ -0,0 +1,103 @@ +digraph g { + rankdir=LR; + + subgraph cluster_memtree { + label="in-memory lihata trees" + bgcolor=grey + rank=same + CFR_INTERNAL [label="CFR_INTERNAL\nultimate fallback"] + CFR_SYSTEM [label="CFR_SYSTEM\nsystem level configuration"] + CFR_DEFAULTPCB [label="CFR_DEFAULTPCB"] + CFR_USER [label="CFR_USER\nuser level configuration"] + CFR_ENV [label="CFR_ENV"] + CFR_PROJECT [label="CFR_PROJECT\nproject level configuration"] + CFR_DESIGN [label="CFR_DESIGN"] + CFR_CLI [label="CFR_CLI"] + } + + subgraph cluster_fields { + label="string -> conf_native_t hash" + bgcolor=grey + conf_fields [label="conf_fields\ncentral hash\nof all\nknown settings"] + } + + subgraph cluster_native { + label="native C structures\nper module" + bgcolor=grey + conf_core [label="conf_core\npcb-rnd core settings"] + conf_hid_gtk [label="conf_hid_gtk\nthe hid_gtk plugin's settings"] + conf_mincut [label="conf_mincut\nthe mincut plugin's settings"] + conf_report [label="conf_report\nthe report plugin's settings"] + conf_other [label="...\nother plugin's settings"] + } + + CFR_INTERNAL -> conf_fields [color=red] + CFR_SYSTEM -> conf_fields [color=red] + CFR_DEFAULTPCB -> conf_fields [color=red] + CFR_USER -> conf_fields [color=red] + CFR_ENV -> conf_fields [color=red] + CFR_PROJECT -> conf_fields [color=red] + CFR_DESIGN -> conf_fields [color=red] + CFR_CLI -> conf_fields [color=red] + + +# CFR_INTERNAL -> CFR_SYSTEM +# CFR_SYSTEM -> CFR_DEFAULTPCB +# CFR_DEFAULTPCB -> CFR_USER +# CFR_USER -> CFR_ENV +# CFR_ENV -> CFR_PROJECT +# CFR_PROJECT -> CFR_DESIGN +# CFR_DESIGN -> CFR_CLI + + conf_fields -> conf_core [color=red] + conf_fields -> conf_hid_gtk [color=red] + conf_fields -> conf_mincut [color=red] + conf_fields -> conf_report [color=red] + conf_fields -> conf_other [color=red] + + + + subgraph cluster_files { + label="config files" + bgcolor=grey + lht_system [label="/usr/share/pcb-rnd/pcb-conf.lht" shape=hexagon] + pcb_default [label="default board, e.g.\n/usr/share/pcb-rnd/default4.lht" shape=hexagon] + project [label="./project.lht" shape=hexagon] + lht_user [label="~/.pcb-rnd/pcb-conf.lht" shape=hexagon] + } + + subgraph cluster_exec_env { + label="execution environment" + bgcolor=grey + env [label="environmental variables"] + cli [label="command line arguments\ne.g. -c or\npluginspecific args"] + } + + lht_internal [label="hardwired\nin the\nexecutable"] + design [label="settings\nin the\nboard file\n(.lht and .pcb)" shape=hexagon] + + lht_internal -> CFR_INTERNAL [label="program startup"] + lht_system -> CFR_SYSTEM [label="loaded at startup"] + pcb_default -> CFR_DEFAULTPCB [label="loadad in CreateNewPCB()"] + lht_user -> CFR_USER [label="loaded at startup" dir=both] + env -> CFR_ENV [label="built at startup"] + project -> CFR_PROJECT [label="loaded when a\nnew board or project\nis loaded" dir=both] + design -> CFR_DESIGN [label="extracted when loading a design" dir=both] + cli -> CFR_CLI [label="built during\ncommand line argument\nparsing"] + + + hid_gtk [label="the preferences dialog"] + + conf_core -> hid_gtk [weight=100] + conf_hid_gtk -> hid_gtk + + hid_gtk -> CFR_DESIGN [color=blue weigth=0] + hid_gtk -> CFR_PROJECT [color=blue weigth=0 style=dashed] + hid_gtk -> CFR_USER [color=blue weigth=0 style=dashed] + + + editor [label="core:\nediting pcb"] + conf_core -> editor [weight=100] + editor -> CFR_DESIGN [color=blue weigth=0] + +} \ No newline at end of file Index: tags/2.3.0/doc/conf/syntax.html =================================================================== --- tags/2.3.0/doc/conf/syntax.html (nonexistent) +++ tags/2.3.0/doc/conf/syntax.html (revision 33253) @@ -0,0 +1,53 @@ + + + + pcb-rnd - config syntax + + + +

The new config system in pcb-rnd

+

Config file syntax

+ +The config file syntax is lihata. +Most users don't need to understand most of the syntax, just follow the +patterns seen in the examples. A few thumb of rules: +
    +
  • structural nodes usually start with a ha: or li: prefix; which one needs to be used is pretty much tied to the node name; thus casual users don't need to care about what they are for, just remember them as part of the name +
  • non-structural nodes are usually given in the form of name = value; use braces around the value if it contains any non-alphanumeric, non-whitespace character +
  • list and array members should better be braced +
  • list and array separator should be semicolon (not comma) +
+ +

config root syntax

+

+A pcb-rnd config file, (or document for short) has a single root +node whose name must be li:pcb-rnd-conf-v1 - this is the signature of the +document. It is a flat list of one or more config root/ subtrees. +TODO: is this really a list or a hash? +

+Each config root is a partial description of the + config tree (which is the logical +configuration of all possible settings). Config roots have a policy and +a priority attached. This is done in the name +of the config root, which must be of the form of policy-priority, +e.g. "overwrite-300" or "append-125". The priority part (with the dash) +can be omitted (and then the per role default priority is used), e.g. +"overwrite" or "append" are valid config root names. +

+Under the config root, a tree of sections (hashes) and setting values +(text nodes) are built. These structures and values are in 1:1 +correspondence with the config tree. Excess +(unknown) keys are considered a warning (except in the plugin/ and +utils/ subtrees). Missing keys or missing subtrees is normal because a config +root can be partial. +

+TODO: examples + +

list syntax

+TODO: list syntax + +

in project files

+TODO + + + Index: tags/2.3.0/doc/conf/tree/CFN_BOOLEAN.html =================================================================== --- tags/2.3.0/doc/conf/tree/CFN_BOOLEAN.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/CFN_BOOLEAN.html (revision 33253) @@ -0,0 +1,8 @@ + + +

pcb-rnd conf tree

+

type: boolean

+Boolean value: true or false. Most often used for determining whether a +feature or a (display mode) is enabled. +

+Example values: true, false, on, off, yes, no, 1, 0. Index: tags/2.3.0/doc/conf/tree/CFN_COLOR.html =================================================================== --- tags/2.3.0/doc/conf/tree/CFN_COLOR.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/CFN_COLOR.html (revision 33253) @@ -0,0 +1,9 @@ + + +

pcb-rnd conf tree

+

type: color

+A color description. Use the "webcolor" format: #rrggbb, where +rr, gg and bb are 2 digit hexadecimal values for red, green and blue +components. +

+Example values: #ff0000 for red, #555555 for grey. Index: tags/2.3.0/doc/conf/tree/CFN_COORD.html =================================================================== --- tags/2.3.0/doc/conf/tree/CFN_COORD.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/CFN_COORD.html (revision 33253) @@ -0,0 +1,10 @@ + + +

pcb-rnd conf tree

+

type: coord

+A coordinate: size, distance, spacing. A decimal number with an unit. Unit +can be metric (e.g. mm, cm, m) or imperial (e.g. mil). +

+Example values: 1.5mm, 15 mil + + Index: tags/2.3.0/doc/conf/tree/CFN_INCREMENTS.html =================================================================== --- tags/2.3.0/doc/conf/tree/CFN_INCREMENTS.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/CFN_INCREMENTS.html (revision 33253) @@ -0,0 +1,8 @@ + + +

pcb-rnd conf tree

+

type: increments

+A collection of coordinates representing an increment configuration. +

+TODO + Index: tags/2.3.0/doc/conf/tree/CFN_INTEGER.html =================================================================== --- tags/2.3.0/doc/conf/tree/CFN_INTEGER.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/CFN_INTEGER.html (revision 33253) @@ -0,0 +1,10 @@ + + +

pcb-rnd conf tree

+

type: integer

+A decimal integer value without unit. The value might be stored in a +32 bit integer; safe range is approximately -2^31 .. 2^31. +

+Example values: 4, 1500, 2545343, -6 + + Index: tags/2.3.0/doc/conf/tree/CFN_LIST.html =================================================================== --- tags/2.3.0/doc/conf/tree/CFN_LIST.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/CFN_LIST.html (revision 33253) @@ -0,0 +1,10 @@ + + +

pcb-rnd conf tree

+

type: list

+An ordered list of strings. +

+Example values: +

+li:{ foo; bar; {foo/bar/with-punctuation}; 123}
+
Index: tags/2.3.0/doc/conf/tree/CFN_REAL.html =================================================================== --- tags/2.3.0/doc/conf/tree/CFN_REAL.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/CFN_REAL.html (revision 33253) @@ -0,0 +1,9 @@ + + +

pcb-rnd conf tree

+

type: real

+A decimal numeric value without unit. +

+Example values: 3.141592654, 5, -12, 0 + + Index: tags/2.3.0/doc/conf/tree/CFN_STRING.html =================================================================== --- tags/2.3.0/doc/conf/tree/CFN_STRING.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/CFN_STRING.html (revision 33253) @@ -0,0 +1,13 @@ + + +

pcb-rnd conf tree

+

type: string

+Text value. +

+Example values: +

+foo
+bar
+{long text with / punctuation?}
+
+ Index: tags/2.3.0/doc/conf/tree/CFN_UNIT.html =================================================================== --- tags/2.3.0/doc/conf/tree/CFN_UNIT.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/CFN_UNIT.html (revision 33253) @@ -0,0 +1,9 @@ + + +

pcb-rnd conf tree

+

type: unit

+Name of a unit. +

+Example values: mm, cm, m, mil + + Index: tags/2.3.0/doc/conf/tree/appearance.html =================================================================== --- tags/2.3.0/doc/conf/tree/appearance.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/appearance.html (revision 33253) @@ -0,0 +1,18 @@ + +

pcb-rnd conf tree

+

subtree: appearance

+ +
node name type flags description +
compact rnd_cfn_boolean 0 when set: optimize GUI widget arrangement for small screen; may be wasting some screen space on large screen +
rat_thickness rnd_cfn_coord 0 +
mark_size rnd_cfn_coord 0 relative marker size +
text_host_bbox rnd_cfn_boolean 0 when moving a text object, the outline thin-draw should also include the bounding box +
term_label_size rnd_cfn_real 0 size of terminal labels, in pcb font scale (100 is for the normal size) +
subc_layer_per_side rnd_cfn_boolean 0 hide top or bottom placed subcircuit annotations if the view is showing the other side +
invis_other_groups rnd_cfn_boolean 0 render non-current group layers with the inivisble color +
black_current_group rnd_cfn_boolean 0 render all layers of the current group black, for maximum contrast +
smart_labels rnd_cfn_boolean 0 attempt to place terminal labels in a way they don't overlap (costs extra CPU cycles, may slow down on-screen rendering) +
label_thickness rnd_cfn_coord 0 font thickness for labels (e.g. terminal labels); thinnest possible is 1nm +
layer_alpha rnd_cfn_real 0 [hidlib] alpha value for layer drawing +
drill_alpha rnd_cfn_real 0 [hidlib] alpha value for drill drawing +
Index: tags/2.3.0/doc/conf/tree/appearance_color.html =================================================================== --- tags/2.3.0/doc/conf/tree/appearance_color.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/appearance_color.html (revision 33253) @@ -0,0 +1,32 @@ + +

pcb-rnd conf tree

+

subtree: appearance/color

+ +
node name type flags description +
crosshair rnd_cfn_color 0 obsolete - DO NOT USE - kept for compatibility (use appearance/color/cross instead) +
attached rnd_cfn_color 0 color of the non-layer corsshair-attached objects drawn in XOR (e.g. when padstack or buffer outline before placed; layer-objects like lines and arcs typically onherit the layer color) +
drc rnd_cfn_color 0 color of the on-screen drc clearance indication while routing +
mark rnd_cfn_color 0 color of the on-screen marks (user placed mark and automatic 'grabbed' mark) +
selected rnd_cfn_color 0 generic object selection color +
via rnd_cfn_color 0 non-terminal padstack shape on current layer +
via_far rnd_cfn_color 0 non-terminal padstack shape on non-current ('far side') layer +
pin rnd_cfn_color 0 terminal padstack shape on current layer +
pin_far rnd_cfn_color 0 terminal padstack shape on non-current ('far side') layer +
pin_name rnd_cfn_color 0 on-screen terminal number/name labels +
subc rnd_cfn_color 0 on-screen subcircuit marks +
subc_nonetlist rnd_cfn_color 0 on-screen subcircuit marks for subcircuits with the nonetlist flag +
extobj rnd_cfn_color 0 on-screen marks of extended objects +
padstackmark rnd_cfn_color 0 on-screen center mark cross for padstacks +
rat rnd_cfn_color 0 on-screen rat lines +
invisible_objects rnd_cfn_color 0 other-side objects and padstack shapes on non-current layer +
connected rnd_cfn_color 0 'connected' highlight (galvanic connections found) +
warn rnd_cfn_color 0 warning highlight (e.g. object found to cause a short) +
layer rnd_cfn_color 0 default layer colors; when a new layer is created, a color from this list is assigned initially +
mask rnd_cfn_color 0 default mask layer color (when a new mask layer is created) +
paste rnd_cfn_color 0 default paste layer color (when a new paste layer is created) +
element rnd_cfn_color 0 default silk layer color (when a new silk layer is created) +
background rnd_cfn_color 0 [hidlib] background and cursor color ... +
off_limit rnd_cfn_color 0 [hidlib] on-screen background beyond the configured drawing area +
grid rnd_cfn_color 0 [hidlib] on-screen grid +
cross rnd_cfn_color 0 [hidlib] on-screen crosshair color (inverted) +
Index: tags/2.3.0/doc/conf/tree/appearance_loglevels.html =================================================================== --- tags/2.3.0/doc/conf/tree/appearance_loglevels.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/appearance_loglevels.html (revision 33253) @@ -0,0 +1,14 @@ + +

pcb-rnd conf tree

+

subtree: appearance/loglevels

+ +
node name type flags description +
debug_tag rnd_cfn_string 0 [hidlib] log style tag of debug messages +
debug_popup rnd_cfn_boolean 0 [hidlib] whether a debug line should pop up the log window +
info_tag rnd_cfn_string 0 [hidlib] log style tag of info messages +
info_popup rnd_cfn_boolean 0 [hidlib] whether an info line should pop up the log window +
warning_tag rnd_cfn_string 0 [hidlib] log style tag of warnings +
warning_popup rnd_cfn_boolean 0 [hidlib] whether a warning should pop up the log window +
error_tag rnd_cfn_string 0 [hidlib] log style tag of errors +
error_popup rnd_cfn_boolean 0 [hidlib] whether an error should pop up the log window +
Index: tags/2.3.0/doc/conf/tree/appearance_messages.html =================================================================== --- tags/2.3.0/doc/conf/tree/appearance_messages.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/appearance_messages.html (revision 33253) @@ -0,0 +1,7 @@ + +

pcb-rnd conf tree

+

subtree: appearance/messages

+ +
node name type flags description +
char_per_line rnd_cfn_integer 0 width of an output line in characters (used by separator drawing in find.c) +
Index: tags/2.3.0/doc/conf/tree/appearance_misc.html =================================================================== --- tags/2.3.0/doc/conf/tree/appearance_misc.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/appearance_misc.html (revision 33253) @@ -0,0 +1,7 @@ + +

pcb-rnd conf tree

+

subtree: appearance/misc

+ +
node name type flags description +
volume rnd_cfn_integer 0 the speakers volume -100..100 +
Index: tags/2.3.0/doc/conf/tree/appearance_padstack.html =================================================================== --- tags/2.3.0/doc/conf/tree/appearance_padstack.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/appearance_padstack.html (revision 33253) @@ -0,0 +1,8 @@ + +

pcb-rnd conf tree

+

subtree: appearance/padstack

+ +
node name type flags description +
cross_thick rnd_cfn_integer 0 cross thickness in pixels - 0 means disable crosses +
cross_size rnd_cfn_coord 0 cross size in word coords - size of one arm of the cross (minus the hole radius) +
Index: tags/2.3.0/doc/conf/tree/appearance_subc.html =================================================================== --- tags/2.3.0/doc/conf/tree/appearance_subc.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/appearance_subc.html (revision 33253) @@ -0,0 +1,7 @@ + +

pcb-rnd conf tree

+

subtree: appearance/subc

+ +
node name type flags description +
dash_freq rnd_cfn_integer 0 how dense the dashed outline should be; -1 means do not display the dashed outline; 0 means solid outline; 1..32 means dashed outline +
Index: tags/2.3.0/doc/conf/tree/design.html =================================================================== --- tags/2.3.0/doc/conf/tree/design.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/design.html (revision 33253) @@ -0,0 +1,23 @@ + +

pcb-rnd conf tree

+

subtree: design

+ +
node name type flags description +
via_thickness rnd_cfn_coord 0 +
via_drilling_hole rnd_cfn_coord 0 +
line_thickness rnd_cfn_coord 0 +
clearance rnd_cfn_coord 0 +
bloat rnd_cfn_coord 0 core: size of box-style clearance around text objects; old plugins: gap between copper features on different nets +
shrink rnd_cfn_coord 0 [OBSOLETE] minimum overlap between connected copper features +
min_wid rnd_cfn_coord 0 core: minimum copper thickness in stroked text, core+plugins: implicit outline rectangle thickness +
min_slk rnd_cfn_coord 0 core: minimum silk thickness in stroked text, core+plugins: implicit outline rectangle thickness on silk layers +
min_drill rnd_cfn_coord 0 [OBSOLETE] minimum drill diameter +
min_ring rnd_cfn_coord 0 [OBSOLETE] minimum annular ring +
text_scale rnd_cfn_integer 0 text scaling in % +
text_thickness rnd_cfn_coord 0 override stroke font text thickness +
text_font_id rnd_cfn_integer 0 +
poly_isle_area rnd_cfn_real 0 polygon min area +
fab_author rnd_cfn_string 0 Full name of author for FAB drawings +
initial_layer_stack rnd_cfn_string 0 deprecated. +
paste_adjust rnd_cfn_coord 0 Adjust paste thickness +
Index: tags/2.3.0/doc/conf/tree/design_drc.html =================================================================== --- tags/2.3.0/doc/conf/tree/design_drc.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/design_drc.html (revision 33253) @@ -0,0 +1,8 @@ + +

pcb-rnd conf tree

+

subtree: design/drc

+ +
node name type flags description +
min_copper_clearance rnd_cfn_coord 0 minimum space between copper features on different networks (default when the net attributes or other settings don't specify a different value) +
min_copper_overlap rnd_cfn_coord 0 minimum overlap between connected copper features (default when the net attributes or other settings don't specify a different value) +
Index: tags/2.3.0/doc/conf/tree/design_drc_disable.html =================================================================== --- tags/2.3.0/doc/conf/tree/design_drc_disable.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/design_drc_disable.html (revision 33253) @@ -0,0 +1,7 @@ + +

pcb-rnd conf tree

+

subtree: design/drc_disable

+ +
node name type flags description +
dummy rnd_cfn_boolean 0 placeholder, not used +
Index: tags/2.3.0/doc/conf/tree/design_thermal.html =================================================================== --- tags/2.3.0/doc/conf/tree/design_thermal.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/design_thermal.html (revision 33253) @@ -0,0 +1,7 @@ + +

pcb-rnd conf tree

+

subtree: design/thermal

+ +
node name type flags description +
poly_scale rnd_cfn_real 0 scale thermal bridges around polygons; 1.000 is the original size - DO NOT USE YET +
Index: tags/2.3.0/doc/conf/tree/editor.html =================================================================== --- tags/2.3.0/doc/conf/tree/editor.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/editor.html (revision 33253) @@ -0,0 +1,67 @@ + +

pcb-rnd conf tree

+

subtree: editor

+ +
node name type flags description +
zoom rnd_cfn_real 0 default zoom +
buffer_number rnd_cfn_integer 0 number of the current buffer +
clear_line rnd_cfn_boolean 0 new lines/arc clear polygons. +
clear_polypoly rnd_cfn_boolean 0 new polygons clear polygons. +
full_poly rnd_cfn_boolean 0 new polygons are full polygons. +
unique_names rnd_cfn_boolean 0 OBSOLETE: force unique names +
snap_pin rnd_cfn_boolean 0 snap to pins and pads +
snap_offgrid_line rnd_cfn_boolean 0 Snap to certain off-grid points along a line. +
marker_snaps rnd_cfn_boolean 0 marker snaps to grid or snap points, as any other click +
highlight_on_point rnd_cfn_boolean 0 Highlight if crosshair is on endpoints. +
show_solder_side rnd_cfn_boolean 0 mirror output +
save_last_command rnd_cfn_boolean 0 OBSOLETE: use the session-persistent command line history instead (press the up arrow) +
line_refraction rnd_cfn_integer 0 value for line lookahead setting +
save_in_tmp rnd_cfn_boolean 0 emergency save unsaved PCB data (despite the user clicks don't save) when: user starts a new PCB; user quits pcb-rnd. Does not affect the on-crash emergency save. +
all_direction_lines rnd_cfn_boolean 0 enable lines to all directions +
rubber_band_mode rnd_cfn_boolean 0 move, rotate use rubberband connections +
rubber_band_keep_midlinedir rnd_cfn_boolean 0 keep line direction when a middle line is moved +
swap_start_direction rnd_cfn_boolean 0 change starting direction after each click +
show_drc rnd_cfn_boolean 0 (misnomer) show style clearance on crosshair +
auto_drc rnd_cfn_boolean 0 (misnomer) block drawing traces that get too close (according to style clearance) to other nets +
conn_find_rat rnd_cfn_boolean 0 connection find includes rats; when off, only existing galvanic connections are mapped +
show_number rnd_cfn_boolean 0 OBSOLETE: pinout shows number +
orthogonal_moves rnd_cfn_boolean 0 move items orthogonally. +
reset_after_element rnd_cfn_boolean 0 OBSOLETE: reset connections after each element while saving all connections +
lock_names rnd_cfn_boolean 0 lock down text so they can not be moved or selected +
only_names rnd_cfn_boolean 0 lock down everything else but text so only text objects can be moved or selected +
thin_draw rnd_cfn_boolean 0 if set, objects on the screen are drawn as outlines (lines are drawn as center-lines). This lets you see line endpoints hidden under pins, for example. +
thin_draw_poly rnd_cfn_boolean 0 if set, polygons on the screen are drawn as outlines. +
as_drawn_poly rnd_cfn_boolean 0 if set, also draw the as-drawn outline of polygons +
wireframe_draw rnd_cfn_boolean 0 if set, lines and arcs on the screen are drawn as outlines. +
local_ref rnd_cfn_boolean 0 use local reference for moves, by setting the mark at the beginning of each move. +
check_planes rnd_cfn_boolean 0 when set, only polygons and their clearances are drawn, to see if polygons have isolated regions. +
hide_names rnd_cfn_boolean 0 when set, subc floater text objects (typical use case: refdes text) are not drawn. +
description rnd_cfn_boolean 0 obsolete - DO NOT USE - kept for compatibility +
name_on_pcb rnd_cfn_boolean 0 obsolete - DO NOT USE - kept for compatibility +
trace_auto_merge rnd_cfn_boolean 0 automatically merge trace overlapping trace lines while drawing or moving traces +
subc_id rnd_cfn_string 0 subcircuit ID template for diplaying the subcircuit label on the subcircuit layer; default to displaying the refes, if empty; syntax if the same as for DYNTEXT +
term_id rnd_cfn_string 0 terminal ID template for diplaying the subcircuit label on the subcircuit layer; default to displaying termid[intconn], if empty; syntax if the same as for DYNTEXT +
move_linepoint_uses_route rnd_cfn_boolean 0 Moving a line point calculates a new line route. This allows 45/90 line modes when editing lines. +
auto_via rnd_cfn_boolean 0 when drawing traces and switching layers or when moving an object from one layer to another, try to keep connections by automatically inserting vias. +
route_radius rnd_cfn_real 0 temporary: route draw helper's arc radius at corners (factor of the trace thickness) +
drc_inclusive_bbox rnd_cfn_boolean 0 when enabled, the drc view will always include all red and blue objects (turns off optimization that focuses on red objects) +
io_incomp_popup rnd_cfn_boolean 0 wether to enable popping up the io incompatibility list dialog on save incompatibility errors +
io_incomp_style rnd_cfn_string 0 view listing style (list or simple), when io_incomp_popup is true +
click_time rnd_cfn_integer 0 default time for click expiration, in ms +
click_objlist rnd_cfn_boolean 0 if there are multiple objects available upon a click, present a modal dialog box to select from them +
live_routing rnd_cfn_boolean 0 autorouter shows tracks in progress +
beep_when_finished rnd_cfn_boolean 0 flag if a signal should be produced when searching of connections is done +
undo_warning_size rnd_cfn_integer 0 warn the user when undo list exceeds this amount of kilobytes in memory +
subc_conv_refdes rnd_cfn_string 0 automatic refdes value assigned to new subcircuits on conversion from objects - if empty, no refdes text or attribute is added; if the value is , the refdes text object is added but no refdes attribute is created +
mode rnd_cfn_integer 0 [hidlib] currently active tool +
grid_unit rnd_cfn_unit 0 [hidlib] select whether you draw in mm or mil +
grid rnd_cfn_coord 0 [hidlib] grid in pcb-units +
grids rnd_cfn_list 0 [hidlib] grid in grid-string format +
grids_idx rnd_cfn_integer 0 [hidlib] the index of the currently active grid from grids +
draw_grid rnd_cfn_boolean 0 [hidlib] draw grid points +
auto_place rnd_cfn_boolean 0 [hidlib] force placement of GUI windows (dialogs), trying to override the window manager +
fullscreen rnd_cfn_boolean 0 [hidlib] hide widgets to make more room for the drawing +
crosshair_shape_idx rnd_cfn_integer 0 [hidlib] OBSOLETE: do not use +
enable_stroke rnd_cfn_boolean 0 [hidlib] Enable libstroke gestures on middle mouse button when non-zero +
translate_key rnd_cfn_list 0 [hidlib] +
Index: tags/2.3.0/doc/conf/tree/editor_selection.html =================================================================== --- tags/2.3.0/doc/conf/tree/editor_selection.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/editor_selection.html (revision 33253) @@ -0,0 +1,8 @@ + +

pcb-rnd conf tree

+

subtree: editor/selection

+ +
node name type flags description +
disable_negative rnd_cfn_boolean 0 selection box behaviour: disable the negative-direction selection - any selection box will select only what's fully within the box +
symmetric_negative rnd_cfn_boolean 0 selection box behaviour: when set, the selection direction is considered negative only if the box has negative size in the X direction +
Index: tags/2.3.0/doc/conf/tree/editor_view.html =================================================================== --- tags/2.3.0/doc/conf/tree/editor_view.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/editor_view.html (revision 33253) @@ -0,0 +1,8 @@ + +

pcb-rnd conf tree

+

subtree: editor/view

+ +
node name type flags description +
flip_x rnd_cfn_boolean 0 [hidlib] view: flip the board along the X (horizontal) axis +
flip_y rnd_cfn_boolean 0 [hidlib] view: flip the board along the Y (vertical) axis +
Index: tags/2.3.0/doc/conf/tree/import_footprint_placement.html =================================================================== --- tags/2.3.0/doc/conf/tree/import_footprint_placement.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/import_footprint_placement.html (revision 33253) @@ -0,0 +1,11 @@ + +

pcb-rnd conf tree

+

subtree: import/footprint_placement

+ +
node name type flags description +
method rnd_cfn_string 0 method/strategy of placement; one of: disperse, frame, fit +
location rnd_cfn_string 0 placement coordinate for methods that require it; if empty, use fixed coordinates at x,y; if non-empty, it may be: mark, center +
x rnd_cfn_coord 0 for some methods if location is empty, X coordinate of placement +
y rnd_cfn_coord 0 for some methods if location is empty, Y coordinate of placement +
disperse rnd_cfn_coord 0 dispersion distance for the disperse method +
Index: tags/2.3.0/doc/conf/tree/import_footprint_removal.html =================================================================== --- tags/2.3.0/doc/conf/tree/import_footprint_removal.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/import_footprint_removal.html (revision 33253) @@ -0,0 +1,7 @@ + +

pcb-rnd conf tree

+

subtree: import/footprint_removal

+ +
node name type flags description +
method rnd_cfn_string 0 method/strategy of removal; one of: select, remove, list +
Index: tags/2.3.0/doc/conf/tree/rc.html =================================================================== --- tags/2.3.0/doc/conf/tree/rc.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/rc.html (revision 33253) @@ -0,0 +1,40 @@ + +

pcb-rnd conf tree

+

subtree: rc

+ +
node name type flags description +
file_changed_interval rnd_cfn_real 0 how often to check if the file has changed on the disk (in seconds); 0 or negative means no check at all +
backup_interval rnd_cfn_integer 0 time between two backups in seconds; 0 means disabled (no backups) +
brave rnd_cfn_string 0 brave mode flags: when non-empty, enable various experimental (unstable) features - useful for testers +
font_command rnd_cfn_string 0 file name template; if not empty, run this command and read its output for loading the font; %f is the file name +
file_command rnd_cfn_string 0 file name template; if not empty, run this command and read its output for loading a pcb file; %f is the file name, %p is the conf setting rc.file_path +
file_path rnd_cfn_string 0 +
library_shell rnd_cfn_string 0 +
library_search_paths rnd_cfn_list 0 +
emergency_name rnd_cfn_string 0 file name template for emergency save anonymous .pcb files (when pcb-rnd crashes); optional field: %ld --> pid; must be shorter than 240 characters. Don't do emergency save if this item is empty. +
emergency_format rnd_cfn_string 0 if set, use this format for the backups; if unset, use the default format +
backup_name rnd_cfn_string 0 file name template for periodic backup of board files; optional fields (the usual % substitutions work) +
backup_format rnd_cfn_string 0 if set, use this format for the backups; if unset or set to 'original', use the original format +
save_command rnd_cfn_string 0 command to pipe the pcb, footprint or buffer file into, when saving (makes lihata persist impossible) +
keep_save_backups rnd_cfn_boolean 0 a copy is made before a save operation overwrites an existing file; if this setting is true, keep the copy even after a successful save +
default_font_file rnd_cfn_list 0 name of default font file (list of names to search) +
default_pcb_file rnd_cfn_list 0 +
silently_create_on_load rnd_cfn_boolean 0 do not generate an error message if the board does not exist on load from command line argument, silently create it in memory +
script_filename rnd_cfn_string 0 PCB Actions script to execute on startup +
action_string rnd_cfn_string 0 PCB Actions string to execute on startup +
rat_path rnd_cfn_string 0 +
rat_command rnd_cfn_string 0 file name template; if not empty, run this command and read its output for loading a rats; %f is the file name, %p is the rc.rat_path conf setting +
save_final_fallback_fmt rnd_cfn_string 0 when a new file is created (by running pcb-rnd with the file name) there won't be a known format; pcb-rnd will guess from the file name (extension) but eventhat may fail. This format is the final fallback that'll be used if no other guessing mechanism worked. The user can override this by save as. +
save_fp_fmt rnd_cfn_string 0 when saving a buffer element/subcircuit, prefer this format by default +
have_regex rnd_cfn_boolean 0 whether we have regex compiled in +
verbose rnd_cfn_integer 0 [hidlib] +
quiet rnd_cfn_integer 0 [hidlib] print only errors on stderr +
dup_log_to_stderr rnd_cfn_boolean 0 [hidlib] copy log messages to stderr even if there is a HID that can show them +
cli_prompt rnd_cfn_string 0 [hidlib] plain text prompt to prefix the command entry +
cli_backend rnd_cfn_string 0 [hidlib] command parser action +
export_basename rnd_cfn_boolean 0 [hidlib] if an exported file contains the source file name, remove path from it, keeping the basename only +
menu_file rnd_cfn_string 0 [hidlib] where to load the default menu file from. If empty/unset, fall back to the legacy 'per hid ow menu file' setup. If contains slash, take it as a full path, if no slash, do a normal menu search for pcb-menu-NAME.lht +
menu_patches rnd_cfn_list 0 [hidlib] file paths to extra menu patches to load +
preferred_gui rnd_cfn_list 0 [hidlib] if set, try GUI HIDs in this order when no GUI is explicitly selected +
hid_fallback rnd_cfn_boolean 0 [hidlib] if there is no explicitly specified HID (--gui) and the preferred GUI fails, automatically fall back on other HIDs, eventually running in batch mode +
Index: tags/2.3.0/doc/conf/tree/rc_path.html =================================================================== --- tags/2.3.0/doc/conf/tree/rc_path.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/rc_path.html (revision 33253) @@ -0,0 +1,13 @@ + +

pcb-rnd conf tree

+

subtree: rc/path

+ +
node name type flags description +
prefix rnd_cfn_string 0 e.g. /usr/local +
lib rnd_cfn_string 0 e.g. /usr/lib/pcb-rnd +
bin rnd_cfn_string 0 e.g. /usr/bin +
share rnd_cfn_string 0 e.g. /usr/share/pcb-rnd +
design rnd_cfn_string 0 directory path of the current design, or if the current design doesn't have a file name yet +
home rnd_cfn_string 0 [hidlib] user's home dir, determined run-time +
exec_prefix rnd_cfn_string 0 [hidlib] exec prefix path (extracted from argv[0]) +
Index: tags/2.3.0/doc/conf/tree/temp.html =================================================================== --- tags/2.3.0/doc/conf/tree/temp.html (nonexistent) +++ tags/2.3.0/doc/conf/tree/temp.html (revision 33253) @@ -0,0 +1,9 @@ + +

pcb-rnd conf tree

+

subtree: temp

+ +
node name type flags description +
rat_warn rnd_cfn_boolean 0 rats nest has set warnings +
clip_inhibit_chg rnd_cfn_boolean 0 dummy node to inform the menu about clip inhibit change +
click_cmd_entry_active rnd_cfn_boolean 0 [hidlib] true if the command line is active when the user click - this gives the command interpreter a chance to capture the click and use the coords +
Index: tags/2.3.0/doc/contact.html =================================================================== --- tags/2.3.0/doc/contact.html (nonexistent) +++ tags/2.3.0/doc/contact.html (revision 33253) @@ -0,0 +1,57 @@ + + + + + pcb-rnd - contact + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +

pcb-rnd - contact

+ +

Contact the project

+

+Please subscribe to the mailing list by sending "subscribe" to +pcb-rnd list.repo.hu 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. + + +
+

+PRIVACY NOTICE: +

+This email address is provided only for personal use, exclusively for +topics directly related to the pcb-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/2.3.0/doc/contrib.html =================================================================== --- tags/2.3.0/doc/contrib.html (nonexistent) +++ tags/2.3.0/doc/contrib.html (revision 33253) @@ -0,0 +1,72 @@ + + + + + pcb-rnd - contribution + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +

pcb-rnd - contribution

+ +If you are interested to help out, please +contact the lead developer. + + +

Contributing as a user

+Using pcb-rnd in production and just reporting bugs is already a huge contribution. +

+We also have a list of tasks that can be contributed by users. +

+More dedicated users can join in scheduled, systematic testing. Such testing +is split up into independent chunks that each can be done in an hour. +

+Even more dedicated users can join developing the documentation. +

+None of the above requires or assumes any programming skill. + +

Contributing as a developer

+

+The project is lead in an autocratic way by Igor2. +

+Developer freedom taken away: +

    +
  • the basic concept of pcb-rnd is set and won't change +
  • the toolchain is chosen, and won't change; the usual hot topics: svn, scconfig, C. +
  • don't add code that restricts usability for others; add code that increases usability for some; thus prefer to add code in plugins! +
+

+Developer freedom promptly granted: +

    +
  • svn commit access from day 0 +
  • work together in trunk/, not alone in a branch +
  • pcb-rnd has a strong plugin support; want to implement a strange/controversial feature? In a plugin, almost anything goes +
  • especially in plugins, work on whatever you want, even if noone else needs that feature +
+

+Coding style/indentation: there's an unified style +in core and core plugins. If you work on those parts, try to stick to it. If you +are working on a new plugin, it's still the preferred style but you can use +a different style. However, the rule is that if someone else starts hacking +that part too, he is allowed to convert the code to the unified format; but +unified format can not be converted to anything else. So it's a one way +process which long term grants unified style while not demotivates a plugin +developer by forcing a style on him in the early, "when the bulk of the code +is written" phase. + + Index: tags/2.3.0/doc/datasheet.html =================================================================== --- tags/2.3.0/doc/datasheet.html (nonexistent) +++ tags/2.3.0/doc/datasheet.html (revision 33253) @@ -0,0 +1,149 @@ + + + + pcb-rnd - datasheet + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +

pcb-rnd - datasheet

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
layout characteristics + multiple layers (16 copper, compile time tunable limit) +
smd and through-hole components +
editable solder mask, paste, assembly, keepout, documentation drawings +
board size up to 2x2 meter at nanometer precision +
arbitrary amount of routing styles +
Design Rule Checker +
native file format + lihata (structured text tree); support for loading and saving all old file versions +
board file formats + lihata (native), tEDAx board, KiCad's s-expr kicad_pcb, geda/PCB's .pcb, Eagle (binary and xml, read-only), Protel/Autotrax (read-only), Mentor Graphics Hyperlynx +
footprint formats + lihata (native), tEDAx footprint, KiCad s-expression modules, geda/PCB's .fp +
import formats + tEDAx netlist, gEDA/gaf sch, gEDA/gaf netlist, EasyEDA netlist, dsn, edif, ipcd356, HP-GL, tEDAx, PADS ASCII netlist, Orcad netlist, Accel EDA netlist, Protel netlist 2.0 +
data model: layers + copper, silk, mask, paste, plated route/cut, unplated route/cut, arbitrary documentation/misc layers +
data model: padstacks + holes, slots, blind/buried vias, different shape on different layers (including non-copper layers), arbitrary polygon shape +
data model: footprint + any object and layer supported in footprint; rich metadata; option for run-time generated footprints +
data model: netlist + named networks, rats nest, deliberate netlist changes + back annotation +
netlist support +
draw using netlist/footprints imported from schematics +
back annotation to schematics editor +
alternatively create netlist from scratch while drawing the PCB +
altnenatively draw without netlist +
DRC + powerful, user scriptable DRC that has full access to all board data (including logical such as networks and physical such as layer stackup and object geometry) +
File formats:
Load/import board +
+ + autotrax PCB board, version 4
autotrax PCB board, version 5
dsn board
eagle xml board version 6, 7, 8
eagle binary board version 3, 4, 5
hyperlynx board, version 2 and above
kicad board, version 3, 4 and 5 (s-expr)
lihata pcb-rnd board (any version)
gEDA/PCB .pcb board (any version up to 2017) + +
File formats:
Load/import footprint +
+ + BXL footprints
eagle xml footprint lib
eagle binary footprint lib
lihata pcb-rnd footprint (any version)
Mentor Graphics cell footprints
gEDA/PCB .fp footprints
tEDAx footprint (any version) + +
File formats:
Import netlist +
+ + Accel ASCII netlists + footprint info
calay (netlists + footprint info)
flat netlist from EDIF
freepcb netlist + footprint info
gEDA/gschem (netlist + footpritn info, running gnetlist)
import ltspice .net and .asc (netlist and footprint info)
flat .edf (netlist+footprint, produced by Mentor Graphics Design Capture)
pcb-rnd action script (netlist + footprint info)
schematics import by running a commandline
netlist import by running a commandline
gEDA netlist (plain text, no footprint info)
Orcad PCB II (netlist + footprint info)
PADS ascii (.asc, netlists + footprint info)
Protel netlists 2.0 + footprint info
tinycad .net (netlists + footprint info)
eeschema netlist and footprint info
tEDAx netlist (any version) + +
File formats:
Import misc +
+ + specctra .dsn (wires and vias)
HPGL plot (lines, arcs, polygons)
MUCS unixplot .pl (lines and vias)
ttf font
eagle DRU (design rules)
lihata pcb-rnd font (any version)
gEDA/PCB font
tEDAx drc
tEDAx pcb-rnd drc script + +
File formats:
Save/export board +
+ + anonimized board statistics in lihata
autotrax PCB board, version 4
dsn board
hyperlynx board, version 2.0
kicad board, version 3 (s-expr)
kicad pcbnew-board, version 1 (legacy plain text format)
lihata pcb-rnd board (any version)
gEDA/PCB .pcb board (various version up to 2017 ) + +
File formats:
Save/export footprint +
+ + kicad module (s-expr, according to version 3)
kicad pcbnew-module (legacy plain text format)
lihata pcb-rnd footprint (any version)
gEDA/PCB .fp footprints
tEDAx footprint (any version) + +
File formats:
Export netlist +
+ + tEDAx netlist (any version) + +
File formats:
Export misc +
+ + bom (Bill of Materials, text)
specctra .dsn (padstacks and subcircuits, works with freerouting.net)
.dxf (2D drawing for mech CADs)
excellon drill/cnc (for PCB fabbing)
fidocad .fcd (partial export)
export gcode (for milling)
gerber for PCB fabbing
IPC-D-356 Netlist (for automated testing)
printer (using ps)
list of terminal connections (old, custom format)
OpenEMS (simulation, matlab files)
openscad script (colored 3D model)
stl (3d triangulated surface model)
geda/PCB xy
gxyrs
Macrofab's pick&place
pick&place file for the TM220/TM240 device
KiCad .pos file
IPC-D-356 Netlist (from automated testing)
lihata pcb-rnd font (any version)
tEDAx etest
tEDAx drc
tEDAx pcb-rnd drc script + +
UI options + gtk2, lesstif (motif), batch (automated processing) +
configurable menus, keyboard and mouse actions +
footprint library + parametric footprints written in any programming language +
optionally per system, per user, per project libs +
footprints from local files +
footprints from the web (edakrill, gedasymbols.org) +
scripting + embedded scripting using fungw (awk, python, lua, tcl, ruby, perl, javascript, lisp, shell, pascal, BASIC) +
layout helpers + basic autorouter, basic autoplace, place objects in aligned grid, + asymmetric pin shapes, back annotation tracking, + trace puller, teardrops +
understands internal connections in footprints +
query mini-language for finding and selecting objects by rules +
command line mode for 2d drafting +
manual board assembly helper GUI +
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/2.3.0/doc/datasheet.sh =================================================================== --- tags/2.3.0/doc/datasheet.sh (nonexistent) +++ tags/2.3.0/doc/datasheet.sh (revision 33253) @@ -0,0 +1,16 @@ +#!/bin/sh + +ROOT=.. +. $ROOT/util/devhelpers/awk_on_formats.sh + +awk_on_formats ' +($1 == " + + + + + + + + +
Main + News + Doc + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +

pcb-rnd - reporting bugs

+Pcb-rnd, like any other biggish piece of software, is not a free of bugs. +When you find a bug, please report it and we will try to fix it as soon as +possible.For reporting bugs you can use any medium you can reach us on: +mostly IRC and email, whichever is easier for you. +

+Using the below table you can optionally increase the efficiency of your +bugreport by sending enough data in the initial report that we won't need +to ask for clarification. + + +
what went wrong optional extra info to help debugging + +
+ 0. For any report, please include + + what version of pcb-rnd are you using: release tarball version + number or the output of "svn info" in trunk/. + +
+ 1. Configuration problems: +
    +
  • ./configure failed +
  • ./configure didn't find a optional package XY +
  • ./configure didn't do what I wanted it to do +
      +
+ include your scconfig/config.log + +
+ 2. Build problems: + make fails + +
    +
  • include your scconfig/config.log +
  • run make clean; make >make.log 2>&1 ; send the resulting make.log +
+ +
+ 3. Installation problems: + make install fails + +
    +
  • include your scconfig/config.log +
  • run make install >makei.log 2>&1 ; send the resulting makei.log +
  • if the error is not an obvious failure of an operation with a clear error + message, please explain, in details, what you expected to happen + (what files should have copied/linked where) and what happened instead. +
+ +
+ 4. pcb-rnd doesn't find a file + + Please make sure you have installed pcb-rnd before running it, or if + you are running it from source, make sure to cd to trunk/src and + running it as ./pcb-rnd. Only these two ways are supported. If it still + fails running by one of those two, please jump to point 5. + +
+ 5. pcb-rnd run time error, non-gui-related + +
    +
  • run pcb-rnd from the command line; append >run.log 2>&1 to the command line, reproduce the error and include run.log +
  • if the error is not an obvious failure of an operation with a clear error + message, please explain, in details, what you expected to happen + and what happened instead. +
+ +
+ 6. pcb-rnd run time error, gui-related + +
    +
  • if you are using the gtk-gl hid, please also try the gdk hid with + the command line argument --gui gtk2_gdk . Please include + a sentence about whether the bug affects both HIDs or is gl-only. +
  • even for the most obvious-looking problem, please explain, in + details, what you expected to happen and what happened instead. +
+ +
+ 7. pcb-rnd crashes (segfault, assertion, abortion) + +
    +
  • Re-run ./configure with --debug and recompile (and reinstall). +
  • Run pcb-rnd from gdb: +
    • +
    • if you are running the installed version: gdb pcb-rnd +
    • if you are running from source: cd trunk/src; gdb ./pcb-rnd +
    +
  • Type this in the gdb prompt: run (optionally append a space + and the command line arguments you would have used for starting pcb-rnd) +
  • reproduce the problem +
  • type bt, copy&paste the result and include it in the bugreport +
  • if the problem is reproducible, please include a description how to + trigger it, preferrably on an empty board on a fresh start, alternatively + with an example file included +
+ + Altnerative method with core dumps: +
    +
  • ./configure --debug +
  • ulimit -c unlimited +
  • on Linux, check your core pattern (man 5 core , search for pattern; changing the core pattern requires root) +
  • in src/ run ./pcb-rnd, trigger the bug +
  • in src gdb ./pcb-rnd core (core is the default core file name, you may have a different name depending on the core pattern, see above) +
+ If you are on MacOSX, you may need to use lldb instead of gdb: lldb --core /cores/core.52381 + and the backtrace command is bt all instead od just bt. +
+ +
+ 8. pcb-rnd can't load my file + + Please include the file in your bugreport + +
+ 9. pcb-rnd loads my file but it doesn't look good + + Please include the file in your bugreport; please include a screenshot + of the file (even open in another software) to demonstrate how it + should look and a screenshot how it looked in pcb-rnd; please mark + the difference visually. + +
+ 10. pcb-rnd produces broken export + +
    +
  • Please include the input board file in your bugreport +
  • Explain the steps of exporting (expecially export settings) +
  • Describe how exactly it is broken (which detail is off, how should + it look like instead); best if you can reproduce it with command + line argument -x +
  • Try to submit a minimal example: if it happens on a large board, + erase half of the board and see if it still happens; repeat this + until reaching the smallest board that still produces the problem. +
+
+ + + Index: tags/2.3.0/doc/developer/c89.html =================================================================== --- tags/2.3.0/doc/developer/c89.html (nonexistent) +++ tags/2.3.0/doc/developer/c89.html (revision 33253) @@ -0,0 +1,12 @@ + + +

pcb-rnd - C89

+ +Most of the code base is written in C89, with a few exceptions +written in C99 (gtk, because it's not C89-compatible). When adding +new code, keep it C89. Especially watch out for these: +
    +
  • comment: always use /* */, never // +
  • don't mix variable declaration with code - open a new {} block, which will also scope your new variables, or better yet, split up the function into smaller, static functions, the compiler will inline them anyway +
  • try to avoid vararg macros, use vararg functions instead +
Index: tags/2.3.0/doc/developer/dad/TEMPLATE.c =================================================================== --- tags/2.3.0/doc/developer/dad/TEMPLATE.c (nonexistent) +++ tags/2.3.0/doc/developer/dad/TEMPLATE.c (revision 33253) @@ -0,0 +1,94 @@ +/* + HOW TO USE THE TEMPLATE: + 1. decide about the name of your dialog box, e.g. foo in this example + 2. svn copy this file to dlg_foo.c - do not use plain fs copy, use svn copy! + 3. rename functions in this file to + 4. add '#include "dlg_foo.c"' in dialogs.c at the end of the list where + all the other dlg_*.c files are included + 5. add an action to pcb_act*_Foo in dialogs.c + 6. edit the parts marked with '<<<- edit this' or 'EDIT THIS' - do not + yet add the implementation + 7. run 'make dep' in src/ + 8. remove this comment block so copyright is on top + 9. edit the copyright message: year and author + 10. test compile + 11. in trunk/: 'svn commit src_plugins/dialogs src/Makefile.dep' + 12. start implementing the dialog box + + This simplistic example is a single-instance non-modal dialog; + there should be only one global variable, created out of the + context struct. This ensures it is easy to convert the dialog + to multi-instance in the future, if needed. + + If you need a multi-instance dialog, there should be no global variable + at all and the context struct should be allocated. A good example + on this is the shape dialog in ../shape/shape_dialog.c +*/ + +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "core headers this file depends on (even if other dialogs include them)" + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ + int whatever; +} foo_ctx_t; <<<- rename this + +foo_ctx_t foo_ctx; + +static void foo_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) <<<- rename this +{ + foo_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(foo_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void pcb_dlg_foo(whatever args) <<<- edit this +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + if (foo_ctx.active) + return; /* do not open another */ + + RND_DAD_BEGIN_VBOX(foo_ctx.dlg); + RND_DAD_COMPFLAG(foo_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(foo_ctx.dlg, "foo"); + RND_DAD_BUTTON_CLOSES(foo_ctx.dlg, clbtn); + RND_DAD_END(foo_ctx.dlg); + + /* set up the context */ + foo_ctx.active = 1; + + RND_DAD_NEW("EDIT_THIS_ID", foo_ctx.dlg, "EDIT THIS: title", &foo_ctx, rnd_false, foo_close_cb); +} + +static const char pcb_acts_Foo[] = "Foo(object)\n"; <<<- edit this +static const char pcb_acth_Foo[] = ""; <<<- edit this +static fgw_error_t pcb_act_Foo(fgw_arg_t *res, int argc, fgw_arg_t *argv) <<<- edit this +{ + return 0; +} Index: tags/2.3.0/doc/developer/dad/TEMPLATE_MODAL.c =================================================================== --- tags/2.3.0/doc/developer/dad/TEMPLATE_MODAL.c (nonexistent) +++ tags/2.3.0/doc/developer/dad/TEMPLATE_MODAL.c (revision 33253) @@ -0,0 +1,77 @@ +/* + HOW TO USE THE TEMPLATE: + 0. reconsider: does this dialog have to be modal? + 1. decide about the name of your dialog box, e.g. foo in this example + 2. svn copy this file to dlg_foo.c - do not use plain fs copy, use svn copy! + 3. rename functions in this file to + 4. add '#include "dlg_foo.c"' in dialogs.c at the end of the list where + all the other dlg_*.c files are included + 5. add an action to pcb_act*_Foo in dialogs.c + 6. edit the parts marked with '<<<- edit this' or 'EDIT THIS' - do not + yet add the implementation + 7. run 'make dep' in src/ + 8. remove this comment block so copyright is on top + 9. edit the copyright message: year and author + 10. test compile + 11. in trunk/: 'svn commit src_plugins/dialogs src/Makefile.dep' + 12. start implementing the dialog box +*/ + +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "core headers this file depends on (even if other dialogs include them)" + +typedef struct{ + rnd_hid_attribute_t *attrs; +} foo_ctx_t; <<<- rename this + +static void pcb_dlg_foo(whatever args) <<<- edit this +{ + foo_ctx_t ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"ok", 0}, {NULL, 0}}; + RND_DAD_DECL(dlg); + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(dlg, "foo"); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + /* set up the context */ + ctx.attrs = dlg; + + RND_DAD_NEW("EDIT_THIS_ID", dlg, "EDIT THIS: title", &ctx, rnd_true, NULL); + RND_DAD_RUN(dlg); + RND_DAD_FREE(dlg); +} + +static const char pcb_acts_Foo[] = "Foo(object)\n"; <<<- edit this +static const char pcb_acth_Foo[] = ""; <<<- edit this +static fgw_error_t pcb_act_Foo(fgw_arg_t *res, int argc, fgw_arg_t *argv) <<<- edit this +{ + return 0; +} Index: tags/2.3.0/doc/developer/dad/closing.html =================================================================== --- tags/2.3.0/doc/developer/dad/closing.html (nonexistent) +++ tags/2.3.0/doc/developer/dad/closing.html (revision 33253) @@ -0,0 +1,73 @@ + + + +

DAD: Dynamic Attribute Dialogs: closing sequence

+

+There are two ways a DAD can be closed: +

    +
  • GUI close: the widget gets destroyed (e.g. the WM closes the dialog + after the user closes the window) +
  • code close: the code decides to close the dialog (e.g. from a + button callback or because of some non-gui async event happened) +
+

+There are four sets of structures/allocations associated with a DAD: +

    +
  • user data: whatever data the [caller] (the code that created the DAD) + is keeping for the dialog; typically states or the content to be + displayed +
  • dad ctx: the widget table created using hid_dad.h, by the [dad] code +
  • hid ctx: the data behind hid_ctx maintained by the GUI [HID] +
  • widgets: the actual widgets maintained by the GUI [toolkit] +
+

+ +There is only one allocation sequence: +

    +
  1. [caller] allocates the user data +
  2. [caller] calls [dad] to allocate the dad ctx: PCB_DAD_NEW() +
  3. [dad] calls [HID] to allocate the hid ctx +
  4. [HID] calls the [toolkit] to allocate widgets +
  5. the [caller] calls PCB_DAD_RUN() or PCB_DAD_AUTORUN() +
+ +There are many different free sequences possible, the three most +typical ones are: +
    +
  • non-blocking dialog, GUI close, free'd from the close callback +
      +
    1. the [toolkit] calls [HID] in a widget destroy callback; the + [HID] free's the wigets and initiates the user callback to the + [caller] +
    2. from the close callback: the [caller] reads out the results +
    3. from the close callback: the [caller] calls PCB_DAD_FREE(table), + which frees the dad ctx and the hid ctx +
    4. from the close callback: the [caller] frees user data +
    +
  • non-blocking dialog, code close, free'd from the close callback +
      +
    1. the [caller] reads out the results +
    2. the [caller] calls PCB_DAD_FREE(table), which frees widgets, + the dad ctx and the hid ctx +
    3. the [caller] frees user data +
    +
  • modal (blocking) dialog, GUI close, free'd from where PCB_DAD_RUN() is called +
      +
    1. the [toolkit] calls [HID] in a widget destroy callback; the + [HID] free's the wigets and initiates the user callback to the + [caller] +
    2. PCB_DAD_RUN() returns at the caller +
    3. the [caller] reads out the results +
    4. the [caller] calls PCB_DAD_FREE(table), which frees the dad ctx and + the hid ctx +
    5. the [caller] frees user data +
    +
+ +

+In other words, one PCB_DAD_NEW() needs to have exactly one PCB_DAD_FREE() +pair. If PCB_DAD_FREE() is called while the dialog is on (code close), +the dialog is closed and the callback function is called (unless it is +already running). The [caller] can access DAD widget states and values +only between PCB_DAD_NEW() and PCB_DAD_FREE(). + Index: tags/2.3.0/doc/developer/dad/index.html =================================================================== --- tags/2.3.0/doc/developer/dad/index.html (nonexistent) +++ tags/2.3.0/doc/developer/dad/index.html (revision 33253) @@ -0,0 +1,14 @@ + + + +

DAD: Dynamic Attribute Dialogs

+ +

Table of Contents

+ + Index: tags/2.3.0/doc/developer/dad/intro.html =================================================================== --- tags/2.3.0/doc/developer/dad/intro.html (nonexistent) +++ tags/2.3.0/doc/developer/dad/intro.html (revision 33253) @@ -0,0 +1,56 @@ + + + +

DAD: Dynamic Attribute Dialogs

+ +

History

+

+Attribute Dialogs were originally invented around the early/mid 2000s for export +HIDs to store a static, flat list of options that are then presented both +as command line options and as the GUI dialog box for export parameters. + +

Intro

+

+DAD is the dyamically allocated version, extended with new widget types for +providing tools for building more complex dialog boxes. It is not connected +with command line options in any way at the moment. +

+The list of widgets is still a flat, growing C array, often called the +table. But inside the table, widgets build as a logical tree +structure. Widgets with name that includes "BEGIN" will open a new +logical layout level that has to be closed with a PCB_DAD_END(). + +

Calling conventions

+

+A table is always built incrementally and sequentially. In this sense +the dialog box is static: once build and created, the number and +type of widgets can not be modified. The dynamic aspect is that the code +may create (and destroy) arbitrary DAD boxes, even with loops and +runtime conditions on what widgets end up in the box. +

+There are two kind of widget calls: widget creation and property set. +Property set calls always change the last created widget. This, by +convention, is often indicated by code indentation as well. For example: +

+	PCB_DAD_INTEGER(dlg, "foo");
+		PCB_DAD_MINVAL(dlg, 1);
+		PCB_DAD_MAXVAL(dlg, 10);
+		PCB_DAD_DEFAULT_NUM(dlg, 3);
+		widget_id_foo = PCB_DAD_CURRENT(dlg);
+	PCB_DAD_BUTTON(dlg, "update!");
+		PCB_DAD_CHANGE_CB(dlg, pcb_act_attr_chg);
+
+

+PCB_DAD_INTEGER() and PCB_DAD_BUTTON() are (macro) calls to create +new widgets (an integer entry and a button), the rest of the calls +change the last created widget's properties. +

+The main widget of the box, the root widget of the widget tree is +any widget. It is practical to make it a container widget (e.g. a HBOX, VBOX, +TABLE, PANE, or TABBED) so that it can host children widgets. +

+After each creation, the caller can query and store the integer widget +identifier using the PCB_DAD_CURRENT() macro. The widget identifier can +be used, together with the table, to query or change widget properties +and current value any time the dialog box is active. + Index: tags/2.3.0/doc/developer/dad/run.html =================================================================== --- tags/2.3.0/doc/developer/dad/run.html (nonexistent) +++ tags/2.3.0/doc/developer/dad/run.html (revision 33253) @@ -0,0 +1,75 @@ + + + +

DAD: running the dialog box

+ +

From C

+

+Dialog box data is created in memory using either PCB_DAD_DECL(table) or +PCB_DAD_DECL_NOINIT(table). The first call declares and initializes all +variables and is suitable for when the dialog box is hosted directly in +(static) global variables or as local variables of a function. The _NOINIT +version omits the initialization and is suitable for declaring the dialog box +as part of a struct. In the latter case the caller needs to make sure all +dialog box fields are initialized to zero. +

+How user attached data and memory allocation is managed is described in +the DAD closing sequence document. + +

Running non-modal dialogs

+

+The typical sequence of running a non-modal dialog is: +

+(declaration)
+(filling in with widgets)
+PCB_DAD_NEW();
+
+

+The modal argument of PCB_DAD_NEW() is pcb_false. The dialog box +is created in the PCB_DAD_NEW() call, which returns immediately, leaving +the dialog box running in the background. +

+example code template + +

Running modal dialogs

+

+The typical sequence of running a modal dialog is: +

+(declaration)
+(filling in with widgets)
+PCB_DAD_NEW();
+PCB_DAD_RUN();
+(process the return value of PCB_DAD_RUN())
+PCB_DAD_FREE();
+
+

+The modal argument of PCB_DAD_NEW() is pcb_true. PCB_DAD_RUN() +will not return until the user gets the modal dialog box closed (either +by the VM or by the code). +

+example code template + +

Running modal dialogs - shorthand

+

+There is an alternative sequence using PCB_DAD_AUTORUN() but it saves +only one line compared to the above code and makes handling the return +value somewhat more complicated. Thus the above sequence should be +preferred. + + +

From user scripts

+

+After creating the dialog box widgets in memory, the actual GUI can be +started up by a call to action dad(dialog_name, run, title) or +dad(dlgname, run_modal, title). +

+The difference between run and run_modal is when the +call returns: +

    +
  • in case of run, the dialog box is created and the action + call returns immediatley, leaving the dialog box running async to + the rest of the current script function. +
  • in case of run_modal the call returns only when the dialog + box is closed and the dialog box is modal (no other dialog boxes + work until this one is closed) +
Index: tags/2.3.0/doc/developer/dad/text.html =================================================================== --- tags/2.3.0/doc/developer/dad/text.html (nonexistent) +++ tags/2.3.0/doc/developer/dad/text.html (revision 33253) @@ -0,0 +1,21 @@ + + + +

DAD: Dynamic Attribute Dialogs

+

+The text widget is a text viewer/editor that operates on a string +that may contain multiple lines. + +

Helper macro for widget creation

+

+PCB_DAD_TEXT(table, user_ctx) +creates a new text widget and installs user context. + +

User callbacks

+

+The only callback the user may provide is user_free_cb which is called +when the text widget is destroyed. Other than this, DAD caller code can not +react on events happening in the text. + + + Index: tags/2.3.0/doc/developer/dad/tree.html =================================================================== --- tags/2.3.0/doc/developer/dad/tree.html (nonexistent) +++ tags/2.3.0/doc/developer/dad/tree.html (revision 33253) @@ -0,0 +1,32 @@ + + + +

DAD: Dynamic Attribute Dialogs

+

+The table tree widget is a table containint cells arranged in a +fixed number of columns. Each cell is a dynamically allocated +char * string. + +

Helper macros for widget creation

+

+These macros, defined in hid_dad.h, are used to fill up the last +created (tree) widget with initial data. They return a row pointer. If the +row pointer is NULL, root is used - in this case insert means inserting at +the beginning of the row list, append means append at the end of the row list. +

    +
  • PCB_DAD_TREE_APPEND - append a sibling row after an existing row +
  • PCB_DAD_TREE_APPEND_UNDER - append a child node (at the end of the child list) under an existing row. +
  • PCB_DAD_TREE_INSERT - insert a new sibling row before an existing row +
  • PCB_DAD_TREE_SET_CB - install an user callback function on a tree event +
+ +

Inline functions for manipulating the tree runtime

+

+When the tree widget is already created, typically when the dialog box +is already running, the code can use hid_dad_tree.h for reading or +changing cells or rows of the tree. Any change is immediately reflected +on the GUI. Please refer to the comments in hid_dad_tree.h for details +on the functions and arguments. + + + Index: tags/2.3.0/doc/developer/dad/wbool.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wbool.png =================================================================== --- tags/2.3.0/doc/developer/dad/wbool.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wbool.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wbool.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wbutton.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wbutton.png =================================================================== --- tags/2.3.0/doc/developer/dad/wbutton.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wbutton.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wbutton.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wcoord.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wcoord.png =================================================================== --- tags/2.3.0/doc/developer/dad/wcoord.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wcoord.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wcoord.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wenum.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wenum.png =================================================================== --- tags/2.3.0/doc/developer/dad/wenum.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wenum.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wenum.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/whbox.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/whbox.png =================================================================== --- tags/2.3.0/doc/developer/dad/whbox.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/whbox.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/whbox.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/whpane.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/whpane.png =================================================================== --- tags/2.3.0/doc/developer/dad/whpane.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/whpane.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/whpane.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/widgets.html =================================================================== --- tags/2.3.0/doc/developer/dad/widgets.html (nonexistent) +++ tags/2.3.0/doc/developer/dad/widgets.html (revision 33253) @@ -0,0 +1,275 @@ + + + +

DAD: Dynamic Attribute Dialogs

+ +

Input widgets

+

+Input widgets are leaf widgets in the widget tree that typically +implement a field where user input takes place. Available +input widgets are: + +
creation call screenshot (gtk2) description +
PCB_DAD_LABEL single line or multi line of plain text, from a string +
PCB_DAD_LABELF single line or multi line of plain text, using printf formatting +
PCB_DAD_ENUM select one value from a fixed set (typical implementation is a combo box) +
PCB_DAD_BOOL checkbox +
PCB_DAD_INTEGER set an integer value +
PCB_DAD_REAL set a real (floating point) value +
PCB_DAD_COORD set a coordinate value +
PCB_DAD_STRING input single line string value (plain text) +
PCB_DAD_BUTTON clickable push button +
PCB_DAD_PROGRESS progress bar +
PCB_DAD_TREE a list, table or tree of text data +
PCB_DAD_PREVIEW drawing area +
PCB_DAD_PICTURE static bitmap image +
PCB_DAD_PICBUTTON static bitmap button +
PCB_DAD_COLOR color button and selector +
PCB_DAD_TEXT text box (text editor) +
+ + + +

PCB_DAD_LABEL(table, text)

+

+Draw a label, which is not an input field (unmodifiable by the user). +text is copied by the call into a new allocation. The only +control text accepts is '\n', which is line break. + +

PCB_DAD_LABELF(table, (printf_args))

+

+Same as PCB_DAD_LABEL() but the text is rendered using printf. Note: +printf args, including the format string, shall be in parenthesis, e.g. +

+PCB_DAD_LABELF(dlg, ("Cats: %d", num_cats))
+
+ +

PCB_DAD_ENUM(table, choices)

+

+The user can choose one value out of an ordered list of strings. The list +is passed as a NULL terminalte char * array. The value +of the enum is an integer index into that array, 0 being the first string. +

+Typical GUI implementation is a combo box, without text editing. + +

PCB_DAD_BOOL(table, label)

+

+Ask the user about a boolean value, typically using a checkbox. The value +of the bool is an integer which is either 0 or 1. + +

PCB_DAD_INTEGER(table, label)

+

+Ask for an integer value, between a minval and a maxval. +The value is an int, which is not guaranteed to be wider than a +16 bit signed value. +

+Typical GUI implementation is a text entry, often upgraded with small buttons +to increase or decrease the value ("spinbox"). + +

PCB_DAD_REAL(table, label)

+

+Ask for a REAL (double precision floating point value), between a minval +and a maxval. +

+Typical GUI implementation is a text entry, often upgraded with small buttons +to increase or decrease the value ("spinbox"). + + +

PCB_DAD_COORD(table, label)

+

+Ask for a coordinate value, between a minval and a maxval. +The value is pcb_coord_t. +

+Typical GUI implementation is a text entry that understands unit suffix, +often upgraded with small buttons to increase or decrease the value ("spinbox"). + + +

PCB_DAD_STRING(table)

+

+Ask for a single line of plain text input. +

+The value is a dynamically allocated string. + +

PCB_DAD_BUTTON(table, text)

+

+A push button the user can click on. text is not allocated or copied +(shall be a static const string or allocated/free'd by the user). +

+There is no value, the only interface is the change callback. + + +

PCB_DAD_PROGRESS(table)

+

+Present a progress bar which is not an user input. value is a +REAL value between 0.0 and 1.0. When the code changes the value, the +GUI makes sure the dialog box is drawn and flushed, because typical use +is in a busy loop calculation. + +

PCB_DAD_TREE(table, cols, first_col_is_tree, opt_header)

+

+Present a tree-table with cols columns of text objects. When +first_col_is_tree is 1, the first column works as a tree, with +indentation and/or tree graphics and logics for collapsing/expanding subtrees. +If opt_header is not NULL, it is a NULL terminated static const +array of header strings describing the table header to be displayed, in as +many strings as cols specified. +

+A special cases: +

+ +
case parameters +
plain flat list cols=1, first_col_is_tree=0 +
tree-only cols=1, first_col_is_tree=1 +
table-only cols>1, first_col_is_tree=0 +
+

+Manipulating the data and the view are both done using + special tree-table macros. + +

PCB_DAD_PREVIEW(table, expose_cb, mouse_cb, free_cb, initial_view_box, user_ctx)

+

+Present a drawing area with callbacks to the host code to handle drawing: + +
argument meaning +
expose_cb called when (parts of) the preview needs to be redrawn +
mouse_cb called on mouse events +
free_cb called before the widget is destroyed +
initial_view_box set the initial zoom/pan to match the view box specified in drawing units +
min_sizex_px widget minimum size in x direction (width), in pixels +
min_sizey_px widget minimum size in y direction (height), in pixels +
user_ctx opaque pointer that is passed to every callback +
+ +

PCB_DAD_PICTURE(table, xpm)

+

+The pointer to a static xpm image is stored in the enumerations field. The image +is displayed in a widget without any other decoration. + +

PCB_DAD_PICBUTTON(table, xpm)

+

+The pointer to a static xpm image is stored in the enumerations field. The image +is displayed in a button tat behaves exaclty as a normal BUTTON in all other +regards. + +

PCB_DAD_COLOR(table)

+

+A button that has a solid region of the color specified in value. Unless +read-only (PCB_HATF_CLR_STATIC), when the user clicks the button a +HID-specific color selector dialog is popped up where the user can +specify a new color. + +

PCB_DAD_TEXT(table, cols, first_col_is_tree, opt_header)

+

+Free form multiline text string, edited using a HID-builtin text editor. Line +terminator is \n. +

+TODO: accessor macros + +

Layout widgets

+ + +
creation call screenshot (gtk2) description +
PCB_DAD_BEGIN_HBOX arrange children widgets in a horizontal list +
PCB_DAD_BEGIN_VBOX arrange children widgets in a vertical list +
PCB_DAD_BEGIN_HPANE split the parent box horizontally into two sections; the split ratio is adjustable
Note: "left" and "right" are the first and second children (left and right sibling) of the widget tree +
PCB_DAD_BEGIN_VPANE split the parent box vertically into two sections; the split ratio is adjustable
Note: on the screenshot "left" and "right" are the first and second children (left and right sibling) of the widget tree +
PCB_DAD_BEGIN_TABLE arrange children widgets into a n*m matrix, allocate each cell the same size
Note: on the screenshot the table is set up to have 3 columns +
PCB_DAD_BEGIN_TABBED create a "tabbed notebook" view, each children is a new tab +
+ +

Box common flags

+

+hbox, vbox and table share a few common compflags, that are defined in +hid_attrib.h, pcb_hatt_compflags_t. The explanation of what each flag does +can be found there. The most commonly used ones are PCB_HATF_FRAME, +PCB_HATF_SCROLL, PCB_HATF_EXPFILL. +

+If PCB_HATF_EXPFILL is set, the given box tries to expannd and fill, using +up all available space in its parent widget. If multiple sibling boxes +have this flag set the behaviour is unspecified; some HIDs may prefer +to grow only one box, others may evenly distribute the avaialble space +among boxes. If this flag is not set, the box uses only as much space +as its children widgets require. + + +

PCB_DAD_BEGIN_HBOX(table) and PCB_DAD_BEGIN_VBOX(table)

+

+Arrange children widgets in a horizontal or vertical row. + +

PCB_DAD_BEGIN_HPANE(table)

+

+Expect exactly two child widgets. Arrange them horizontally, with +a widget in between them that allows the user to change the space allocation +between the sides. + +

PCB_DAD_BEGIN_VPANE(table)

+

+Expect exactly two child widgets. Arrange them vertically, with +a widget in between them that allows the user to change the space allocation +between the sides. + +

PCB_DAD_BEGIN_TABLE(table, cols)

+

+Place children widgets in a table with cols columns. Widgets are +placed by filling up rows first. If there are not enough widget to finish +the last row, rightmost columns are left empty. +

+The table is homogenous, which means the cell size is the same for all cells +and is either determined by the size of the smallest cell content or if +the table fills in a larger widget space than its minimal size, then cell +space is evenly distributed. + +

PCB_DAD_BEGIN_TABBED(table, tabs)

+

+Creates a "tabbed notebook": each child widget ends up on a new +page, there is only one page shown at a time and there is a GUI way +to switch page (the tab). The list of tab names is passed as tabs, +as a NULL terminalte char * array. The number of tab names must match +the number of children widgets. The value +of is an integer index into that array, 0 being the first tab. +

+If compflag includes PCB_HATF_HIDE_TABLAB, the tab graphics are hidden - +no tab labels printed and the user can not click to switch tab. This is +useful for dialog boxes where the code needs to present different tabs +using the same screen estate. +

+If compflag PCB_HATF_LEFT_TAB is set, tab labels are presented in a vertical +row on the left side of the widget. This is useful if there are a lot of +tabs with short names. + +

PCB_DAD_DUP_ATTR(table, attr)

+

+Create a new widget by duplicating an existing one. attr is the +widget ID of the existing widget. If the widget being duplicated is a +BEGIN*, it will need a corresponding PCB_DAD_END. + + +

Property sets

+

+The raw macro call is PCB_DAD_SET_VALUE, which can change (overwrite) a named +field of the current (last created) widget. The following table lists high +level macros that usually call PCB_DAD_SET_VALUE on a specific field. +

+ +
name description +
PCB_DAD_COMPFLAG(table, val) set all compflags +
PCB_DAD_MINVAL(table, val) change the minimal value for numeric input +
PCB_DAD_MAXVAL(table, val) change the maximal value for numeric input +
PCB_DAD_DEFAULT_NUM(table, val) set the default (initial) value for numeric fields (integers, coords, bools, floats) +
PCB_DAD_DEFAULT_PTR(table, val) set the default (initial) value for pointer fields (e.g. strings) +
PCB_DAD_MINMAX(table, min, max) hange both the minimal and the maximal value for numeric input +
PCB_DAD_CHANGE_CB(table, cb) cb is a function that shall be called upon any change to the widget value +
PCB_DAD_HELP(table, val) set the help text (typically presented as a tooltip) +
+ +

Actions and scripting

+

+There is a dad() action in the dialogd plugin that exposes all the above macros. +The dialog table ID is am arbitrary unique string and commands are the macro +names without PCB_DAD, written in lowercase. +

+Please refer to scripting rosetta +project for examples. An example of a typical small dialog box is the +unit conveter +script. + Index: tags/2.3.0/doc/developer/dad/winteger.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/winteger.png =================================================================== --- tags/2.3.0/doc/developer/dad/winteger.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/winteger.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/winteger.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wlabel.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wlabel.png =================================================================== --- tags/2.3.0/doc/developer/dad/wlabel.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wlabel.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wlabel.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wpicbtn.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wpicbtn.png =================================================================== --- tags/2.3.0/doc/developer/dad/wpicbtn.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wpicbtn.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wpicbtn.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wpicture.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wpicture.png =================================================================== --- tags/2.3.0/doc/developer/dad/wpicture.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wpicture.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wpicture.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wprogress.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wprogress.png =================================================================== --- tags/2.3.0/doc/developer/dad/wprogress.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wprogress.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wprogress.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wreal.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wreal.png =================================================================== --- tags/2.3.0/doc/developer/dad/wreal.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wreal.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wreal.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wstring.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wstring.png =================================================================== --- tags/2.3.0/doc/developer/dad/wstring.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wstring.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wstring.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wtabbed.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wtabbed.png =================================================================== --- tags/2.3.0/doc/developer/dad/wtabbed.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wtabbed.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wtabbed.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wtable.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wtable.png =================================================================== --- tags/2.3.0/doc/developer/dad/wtable.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wtable.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wtable.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wtree.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wtree.png =================================================================== --- tags/2.3.0/doc/developer/dad/wtree.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wtree.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wtree.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wvbox.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wvbox.png =================================================================== --- tags/2.3.0/doc/developer/dad/wvbox.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wvbox.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wvbox.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/dad/wvpane.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/dad/wvpane.png =================================================================== --- tags/2.3.0/doc/developer/dad/wvpane.png (nonexistent) +++ tags/2.3.0/doc/developer/dad/wvpane.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/dad/wvpane.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/data.html =================================================================== --- tags/2.3.0/doc/developer/data.html (nonexistent) +++ tags/2.3.0/doc/developer/data.html (revision 33253) @@ -0,0 +1,214 @@ + + + +

pcb-rnd internals

+ +

concepts

+ +

+Convention: typedef'd types are called pcb_*_t - the corresponding struct +is pcb_*_s. + +

board

+

+There is only one board being edited. A board is the model of the whole world +for pcb-rnd - any other, auxiliary data is only a partial description of a board. +The data struct for board is pcb_board_t. As of now, pcb-rnd edits only one +board at a time, and it is stored in a global variable called PCB. +The code is single threaded and is not reentrant. +

+Half of the board structure describes global board properties: +

    +
  • layer stack +
  • netlist +
  • editor settings (e.g. routing styles, which layers are visible) +
  • metadata (such as name of the author, size of the board). +
+The other half is the actual board data, stored in a pcb_data_t field. +

+Relevant structs, variables and functions are in board.[ch]. + +

data

+

+A pcb_data_t contains everything to describe the 2d geometry of +an existing board: +

    +
  • per-layer objects (lines, arcs, polygons, text objects) +
  • global objects (subcircuits, padstacks) +
  • temporary logical connections (rat lines) +
  • padstack prototypes (padstack shapes referenced by padstack references/instances) +
+

+Relevant structs, variables and functions are in data.[ch]. +

+However, it does not contain the layer stackup, but references to it. +This means a data_t can be copied or moved from within one board to +another, even with mismatching layer stack. When a pcb_data_t is within a +pcb_board_t, the layer references are fixed, pointing to actual layers +within the board's layer stack (e.g. "layer 3 in the stack"). Such a layer is +also called a real layer. When a +pcb_data_t is used outside of a board (e.g. as a buffer), a generalized, +recipe-like layer description is used (e.g. "second copper layer counted +from the top"). Such a layer is not a real layer, but can be bound +to a real layer. The binding means that while it keeps it's recipe-like +description, it is also referring to an actual layer of the stack of the +current PCB structure. (This happens to subcircuits: they are specified +with generalized, recipe-like layers that are bound to the board's layer stack +once the subcircuit is placed on the board.) + +

buffers

+

+Paste buffers are pcb_buffer_t; the main field is pcb_data_t. +

+Relevant structs, variables and functions are in buffer.[ch]. +

+A paste buffer doesn't have a layer stack. When data is copied from a board +to a buffer, the layer references are generalized. + +

terminology: layers and layer groups

+

+Layers are abstract canvases also serving as a logical grouping +of drawing primitives. Every layer is part of exactly one layer +group. A layer group is close to what a physical layer is on +the FR4. +

+Limitations: +

    +
  • as of now pcb-rnd does not have Z-coordinate: layers have no thickness; +
  • substrate is not represented at all in the layers stack. +
+

+The location of a layer group on of (flags are in layer.h): +

    +
  • top (component) side - PCB_LYT_TOP +
  • bottom (solder) side - PCB_LYT_BOTTOM +
  • inner or internal (e.g. signal) - PCB_LYT_INTERN +
  • global (affects all locations, e.g. the outline layer for routing) - 0 +
+

+In pcb-rnd most layer types are fully explicit: +

    +
  • copper - PCB_LYT_COPPER (not composite) +
  • silk screen - PCB_LYT_SILK +
  • mask - PCB_LYT_MASK +
  • paste - PCB_LYT_PASTE +
  • outline - PCB_LYT_OUTLINE (not composite) +
+

+The layers of a composite layer group are combined + and -, depending +on the PCB_LYC_SUB in their comb field. +

+Assumptions: there are two silk layers, one for the top and one for the bottom +side and there are always a top and a bottom copper layer. (Long term +assumptions will be removed.) The outline layer has to be global. +

+The rest of the layers are virtual layers, often just GUI hacks, e.g.: +

    +
  • Subcircuit dashed outline, subcricuit parts - no layer struct, calculated on-the-fly from the subc list +
  • fab - no layer struct, calculated on-the-fly from drill/hole data +
+ +

pcb_data_t: global data

+

+Global data affect all layers. The most trivial example is +padstack: it has a hole and potentially a copper ring on all +layers. A padstack +directly under the board's pcb_data_t is considered a "via" (by convention, +by purpose), a padstack under subcircuit's pcb_data_t is usually a "pin" +or "pad" (when has a term ID) or a "via". The quoted terms don't exist +in the code, they are just conventions. Padtsacks are vertical constructions, +they may affect multiple layers. +

+The other global object is subcircuit; using its own layer list, it potentially +can affect all layers of the board. The children objects of a subcircuit is +a pcb_data_t, which allows arbitrary (loop-free) recursion in data. + +

pcb_data_t: layer-local data

+

+The data struct has a pcb_layer_t for each logical layer, to host +the per layer objects (drawing primitives). + +

the layer struct

+

+Layer data is stored in struct pcb_layer_t. A layer has a list +for each object type (drawing primitive type): arcs, lines, polygons, etc. +These lists are local: in a tree of subcircuits, the layer list contains only +what's strictly directly on the given layer, there's no recursion. +

+Relevant structs, variables and functions are in layer.[ch]. + +

map

+ + + +

tree

+

+A tree can be built using subcircuits. The top level is always a board or +a buffer, which are essentially just different wrappers around pcb_data_t. +Then pcb_data_t can host subcircuits in it global data. A subcircuit +is also just a 3rd kind of wrapper around a pcb_data_t, which means it +opens a new level of the tree. +

+When we will start supporting subc-in-sunc this means the root is: +

    +
  • a PCB board: pcb_board_t +
  • a paste buffer: pcb_buffer_t +
+

+(When the user opens a subcircuit for editing, the root is still a pcb_board_t, +it just has a field that tells it is a fake board for a single subc. Still +the real subc to edit is in the fake board's pcb_data_t. This is needed so +we have all the global states stored in pcb_baord_t.) +

+Then the next levels are arbitrary encapsulation of subcircuits. + + +

list vs. rtree

+

+Each level of pcb_data_t has its own lists storing the local objects. +

+The root of the tree also ha an rtrees for each object type. An rtree is +a spatial data structure that provides efficient coordinate lookups. All objects, +recursively, are added in these rtrees. That means, if there's a line on the +board, that's really a line stored on a pcb_layer_t's list, and the +full tree path is somehting like this: +

+	pcb_board_t -> pcb_data_t -> pcb_layer_t -> linelist_t
+
+

+The same line is also added in the same layer's rtree (called line_tree for lines): +

+	pcb_board_t -> pcb_data_t -> pcb_layer_t -> pcb_rtree_t
+
+

+On subsequent levels, the list is the same. If a line is part of +a subcircuit, it's sitting on one of the linelists on one of the bound +layers provided by the subc: +

+	pcb_board_t -> pcb_data_t -> pcb_subclist_t -> pcb_data_t -> pcb_layer_t -> pcb_linelist_t
+
+

+The subcircuit's pcb_layer_t would also have an rtree. But instead of having +it's own rtree, it's rather linked to the root's rtree. Which means any access +to any rtree under a subc is really access to the corresponding rtree of the root! +In other words, object lists are level-local, but rtrees are tree-global. +

+This also means as a programmer, you can alsways do two kind of searches or +iterations: +

    +
  • level-local (only linear iteration is possible) +
  • global (both linear iteration and efficient, bounding box based, geometrical rtree lookups are possible) +
+

+Rationale: this way if we need to look up what's on a specific coord +(e.g. the user clicks or find.c needs to check what is connected to a given +point), we can use the global rtree's and we will get the answers without having +to recurse into subcircuits. +

+Note: layer bindings complicate this a bit. A subc layer is bound to one of +the root's real layers. When that binding is created, the rtrees are also +linked together, and all subc layer objects on the given layer are added +in the common rtree. When the layer binding needs to change, that means +we first need to unbind the subcircuit's bound layer from the root's real +layer: when we do that, we need to unlink the rtrees and remove all +the objects we added to the global tree from our subcircuit layer. Index: tags/2.3.0/doc/developer/data1.svg =================================================================== --- tags/2.3.0/doc/developer/data1.svg (nonexistent) +++ tags/2.3.0/doc/developer/data1.svg (revision 33253) @@ -0,0 +1,434 @@ + + + + + + +pcb_data + + +cluster_1 + +LEGEND + + + +PCBType_misc + +misc fields: +ID +Name +FileName +colors +drc settings +cursor coords +grid +layergroups +route styles +padstack protos +... + + + +PCBType_flags + +flags: +Changed +ViaOn (vias drawn?) +... + + + +pcb_board_t + +pcb_board_t + + + +pcb_board_t->PCBType_misc + + + + + +pcb_board_t->PCBType_flags + + + + + +pcb_data_t + +pcb_data_t + + + +pcb_board_t->pcb_data_t + + + + + +DataType_listrt + +layer-independent lists and rtrees + + + +pcb_data_t:s->DataType_listrt + + + + + +DataType_LayerN + +LayerN: number of +layers in use + + + +pcb_data_t:s->DataType_LayerN + + + + + +DataType_layers + +an array of layers + + + +pcb_data_t:s->DataType_layers + + + + + +DataType_misc + +misc fields + + + +pcb_data_t:s->DataType_misc + + + + + +DataType_rtrees + +DataType_rtrees + + + +pcb_data_t:s->DataType_rtrees + + + + + +pcb_data_t2 +another level of +pcb_data_t +... + + + +pcb_subc_t + +pcb_subc_t + + + +pcb_subc_t->pcb_data_t2 + + + + + +pcb_rat_line_t + +pcb_rat_line_t + + + +pcb_pstk_t + +pcb_pstk_t + + + +pcb_padstack_proto_t + +pcb_padstack_proto_t + + + +pcb_pstk_t->pcb_padstack_proto_t + + +id +ref. + + + +pcb_arc_t + +pcb_arc_t + + + +pcb_gfx_t + +pcb_gfx_t + + + +pcb_line_t + +pcb_line_t + + + +pcb_text_t + +pcb_text_t + + + +pcb_poly_t + +pcb_poly_t + + + +struct + +box: +struct + + + + +PCB + +extern pcb_board_t PCB +global variable +holding the current +board + + + +PCB->pcb_board_t + + + + + +Buffers + +extern pcb_buffer_t Buffers[] +global variable holding +all paste buffers + + + +pcb_buffer_t + +pcb_buffer_t + + + +Buffers->pcb_buffer_t + + + + + +pcb_buffer_t->pcb_data_t + + + + + +BufferType_misc + +misc fields: +bounding box +offset + + + +pcb_buffer_t->BufferType_misc + + + + + +DataType_listrt->pcb_subc_t + + + + + +DataType_listrt->pcb_rat_line_t + + + + + +DataType_listrt->pcb_pstk_t + + + + + +DataType_listrt->pcb_padstack_proto_t + + + + + +pcb_layer_t + +pcb_layer_t + + + +DataType_layers->pcb_layer_t + + + + + +LayerType_lines + +list and rtree of lines + + + +pcb_layer_t->LayerType_lines + + + + + +LayerType_arcs + +list and rtree of arcs + + + +pcb_layer_t->LayerType_arcs + + + + + +LayerType_gfxs + +list and rtree of gfxs + + + +pcb_layer_t->LayerType_gfxs + + + + + +LayerType_texts + +list and rtree of text objects + + + +pcb_layer_t->LayerType_texts + + + + + +LayerType_polygons + +list and rtree of polygons + + + +pcb_layer_t->LayerType_polygons + + + + + +LayerType_misc + +misc fields: +flags +colors + + + +pcb_layer_t->LayerType_misc + + + + + +LayerType_lines->pcb_line_t + + + + + +LayerType_arcs->pcb_arc_t + + + + + +LayerType_gfxs->pcb_gfx_t + + + + + +LayerType_texts->pcb_text_t + + + + + +LayerType_polygons->pcb_poly_t + + + + + +round + +round: +struct field + + + +diamond + +diamond: +global variable + + + +grn + +green: +drawing primitive + + + Index: tags/2.3.0/doc/developer/ddrc/drc_query_tdx.html =================================================================== --- tags/2.3.0/doc/developer/ddrc/drc_query_tdx.html (nonexistent) +++ tags/2.3.0/doc/developer/ddrc/drc_query_tdx.html (revision 33253) @@ -0,0 +1,81 @@ + + + + tEDAx - pcb-rnd drc_query + + + +

tEDAx - pcb-rnd drc_query scripts

+ +

purpose

+

+This pcb-rnd specific block describes drc rules for the drc_query plugin. +Other software should ignore this block. +

+The main use case for the block is allowing schematics editors to +translate design/layout requirements extracted from the schematics into +a rule set that then can be checked by pcb-rnd. + +

blocks

+

+Block type is "drc_query_rule" and "drc_query_def", version is "v1". +The unique identifier should be single word rule name or constant name. +

+Commands for drc_query_rule are: + +
command parameter names explanation + +
type str... + Rule type (for grouping on the DRC list). Only one instance per rule allowed. + +
tilte str... + Rule title (summary). Only one instance per rule allowed. + +
desc str... + Detailed description of the violation and suggestions how to resolve it + Only one instance per rule allowed. + +
query str... + The next line of the query script. Multiple instances per rule allowed. +
+ + +

+Commands for drc_query_def are: + +
command parameter names explanation + +
type typename + Constant data type (anything the conf system accepts; typically coord, real or boolean). Only one instance per const allowed. Must be the first command. + +
desc str... + Human readable description of the constant. Only one instance per const allowed. + +
default val + Default value in case the config node is not filled in, in the format required by the data type. Only one instance per const allowed. +
+ +

Examples

+

+Below is the hole overlap rule (standard drc_query script from the stock +config) translated into tEDAx drc_query_* blocks: +

+tEDAx v1
+begin drc_query_def v1 hole_overlap_factor
+	type real
+	default 0.0
+	desc How much drilled holes may overlap [-1..+1]; 0 means touching holes are reported; positive numbers allow more overlap, negative numbers report non-overlapping but close holes
+end drc_query_def
+
+begin drc_query_rule v1 hole_overlap
+	type pair hole
+	title overlapping holes
+	desc padstack holes overlap
+
+	query rule overlap
+	query let A @.type==PSTK
+	query let B A
+	query assert (A.ID > B.ID) && (distance(A.x, A.y, B.x, B.y) < (A.hole + B.hole)/(2*(1+$hole_overlap_factor))) thus violation(DRCGRP1, A, DRCGRP2, B, DRCMEASURE, distance(A.x, A.y, B.x, B.y), DRCEXPECT, (A.hole + B.hole)/(2*(1+$hole_overlap_factor)))
+end drc_query_rule
+
+
Index: tags/2.3.0/doc/developer/ddrc/proposal1.txt =================================================================== --- tags/2.3.0/doc/developer/ddrc/proposal1.txt (nonexistent) +++ tags/2.3.0/doc/developer/ddrc/proposal1.txt (revision 33253) @@ -0,0 +1,5 @@ +Dynamic DRC proposal 1: a Declarative DRC language. + +The final/revised version of this document got moved to +the user documentation at ../../user/06_feature/query/lang.html because +the query language is now officially the engine for the DRC. Index: tags/2.3.0/doc/developer/ddrc/requirements.txt =================================================================== --- tags/2.3.0/doc/developer/ddrc/requirements.txt (nonexistent) +++ tags/2.3.0/doc/developer/ddrc/requirements.txt (revision 33253) @@ -0,0 +1,22 @@ +The Dynamic DRC should be able to solve at least these tasks: + - check star grounding + + require subcircuit placement on same layer + + specify subcircuit proximity to each other on same layer + + specify subcircuit proximity to the edge + + specify subcircuit proximity to network or other copper feature on the same layer + + perform copper vs. copper checks + + minimal gap between an object or network and anything else + + minimal gap between high voltage and low voltage networks + + perform copper geometry checks + + detect minimal width (high current) + - detect poly hairpin + - number and length of stubs (hight freq) + - "via cage": a given network needs to be surrounded by a set of gnd vias + - network related copper checks + + matched length lines (e.g. fast dram bus) + - balanced transmission line (distance between the tracks) + - match and/or limit number of vias + - limit layer usage + - require layer stackup properties, e.g. microstrip, stripline + - e.g. require ground poly on the next layer + - e.g. number of gaps in the ground poly the line jumps Index: tags/2.3.0/doc/developer/distros.txt =================================================================== --- tags/2.3.0/doc/developer/distros.txt (nonexistent) +++ tags/2.3.0/doc/developer/distros.txt (revision 33253) @@ -0,0 +1,47 @@ +How to request packaging (distros sorted by popularity, 2016): + +Ubuntu: + easiest is to get in Debian, Ubuntu picks up packages from sid + alternative: ubuntu-devel-discuss@lists.ubuntu.com (pending) + alternative: https://bugs.launchpad.net/ubuntu/+filebug?no-redirect&field.tag=needs-packaging + +linux mint + https://blueprints.launchpad.net/linuxmint + (same maintainer as debian?) + +slackware: + Promised (AFK, ask again in 3rd week of sept) + geda/pcb maintainer: pfeifer[dot]felix[at]googlemail[dot]com (sent mail) + https://slackbuilds.org/guidelines/ + needs an existing package + since the slackbuild needs slackware's pkgtools usually at the end of a ./configure --prefix=/usr --extrastuff..make.. make install DESTDIR=/tmp/NAMEOFPACKAGE..cd /tmp/NAMEOFPACKAGE..makepkg -l y -c n ../NAMEOFPACKAGE-123.txz + installwatch can build a package + check out #slackbuilds + +Debian: + Bdale? + (alternative: pkg-electronics-devel@lists.alioth.debian.org - pending) + (alternative: RFP through reportbug) + +fedora: + https://fedoraproject.org/wiki/Package_maintainers_wishlist?rd=PackageMaintainers/WishList + (wrote mail to cicku) + +OpenSuse: + adrian [at] suse.de (mail sent) + +Arch: + DONE! needs to be modularized + Kyle Keen (mail sent) + +Manjaro: + Same as arch + +---- +FreeBSD: + hrs [at] freebsd.org (Hiroki Sato - mail sent) + +OpenBSD: + andreas.bihlmaier [at] gmx.de -> ENOTIME, he suggests ports@openbsd.org + + Index: tags/2.3.0/doc/developer/export_openems/mesh_z.txt =================================================================== --- tags/2.3.0/doc/developer/export_openems/mesh_z.txt (nonexistent) +++ tags/2.3.0/doc/developer/export_openems/mesh_z.txt (revision 33253) @@ -0,0 +1,16 @@ +The bottom of the board by default always lands at z=0. The top is the +thicknesses of all the substrate layers added together. It is only the +substrate layers because right now the copper is just a change in +attribute on the surface of the substrate (2D) not a 3D object. + +So for the hairpinfilter example which is just 1 substrate layer of +1.5mm. It would be z=0mm for the bottom, and z=1.5mm for the top. + +That adjustment we have for z-mesh "num in substrate" is meant to +select how many lines fit inbetween those two lines. + +Technically my pcb2csx library can do both full 3D where all objects +have real thickness and the thing we do now but it eats a lot of +processing power for marginal benifit in most cases. In other words +it's not worth supporting at this point. + Index: tags/2.3.0/doc/developer/fungw_actions.txt =================================================================== --- tags/2.3.0/doc/developer/fungw_actions.txt (nonexistent) +++ tags/2.3.0/doc/developer/fungw_actions.txt (revision 33253) @@ -0,0 +1,129 @@ +Actions implemented as fungw functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Intro + +All pcb-rnd actions are fungw functions by now. This helps the code to do +all the data type conversions easier, save a few conversions where we +don't need conversions. More importantly, this makes a more seamless +integration between user scripts and C code, whether scripts are calling +C actions or the user is executing script defined actions. + +To stay compatible with the old action mechanism, the current version +applies the following restrictions: + +- we have only one large fungw object (pcb_fgw_obj) that hosts all + functions; this emulates the old central hash of functions + +- before a function enters the object or a function is looked up in the + object, the function name is converted to lowercase; this emulates the + case intensity of the old action system, which is still essential for + the user interface (GUI or CLI command entry and menu). + +- temporarily, for the transition, there are two helper macros + PCB_OLD_ACT_BEGIN and PCB_OLD_ACT_END that can wrap old function + code, converting all arguments to a char **argv. Such old actions + should return non-zero on error, while the value of ores will always be + FGW_INT/0. New action code shall NOT use the compatibility API. + +- a single action call will result in a single fungw function call; that + is, the fungw function that serves the action is free to convert any + of the arguments. + +2. converting arguments + +Arguments are normally converted using PCB_ACT_CONVARG(); the last +argument is a statement that can make the value assignment to a local +variable if the conversion was succesful. For example fetching the 2nd +argument into a local coord: + +{ + pcb_coord_t c; + PCB_ACT_CONVARG(2, FGW_COORD, ActioName, c = fgw_coord(&argv[2])); +} + +If conversion fails or the argument is not available, the macro returns +from the function with error. Anoter variant of the macro called +PCB_ACT_MAY_CONVARG() omits the error-return part, allowing the code +to have optional arguments. + +When the coordinate conversion needs to keep extra info, e.g. whether +the coordinate was specified in absolute or relative, the special type +fgw_coords_t shall be used: + +{ + fgw_coords_t *crd; + PCB_ACT_CONVARG(1, FGW_COORDS, d1, crd = fgw_coords(&argv[1])); +} + + +3. returning + +An action function has two return values: the C function return value +and the "res" argument. If the action could not start executing code +because of a calling error, e.g. there are not enough arguments or +arguments can not be converted or the function is invoked out-of-context, +it should retrun a fungw error using the C return value. This indicates +that performing the call itself failed. + +Else, if actual action code runs, the C return value should be 0 and the +res argument should be loaded with the return value of the action. This +indicates that the call took place, the action was executed and the conclusion +is stored in res. The semantic of the result is action-specifiec. The common +convention is returning int, 0 meaning success. The shortnad for this: + +{ + PCB_ACT_IRES(0); + return 0; +} + +PCB_ACT_IRES() loads res with type and value. There are other similar, +type-specific macros available. + +4. multi-call + +Currently pcb-rnd does not depend on fungw's multi-call, thus actions are +free to convert their arguments - the same arguments will not be reused in +other actions. + +5. calling an action from another action + +There are two common cases: wrapping/dispatching and invoking. + +In the wrap/dispatch setup an outer action is called that does not alter +the arguments (not even converting them!), but has to call another action +with exactly the same arguments. This can be done by using the macro +PCB_ACT_CALL_C(). + +When an action code needs to invoke another action, there are three ways +doing it. + +5.1. string call + +The slow, string parsing way using pcb_actionl() or the more +efficient direct call. + + +5.2. direct C call + +Direct C function call is possible only if both the caller and callee +actions are in core, or are in the same plugin. Before the direct call +the caller needs to set up a fungw argv array and after the call the +array members need to be free'd using fgw_argv_free() to avoid +leaking argument memory. This needs to be done even if the caller did +not allocate any memory for argv members - the callee can allocate memory +by converting arguments. + +5.3. indirect C call + +Call pcb_find_action() to get an fgw_func_t * to the action - this holds +the C function pointer. Set up argv, make sure argv[0] is set up to be +the target function: + + fgw_func_t *fn = pcb_find_action(...); + argv[0].type = FGW_FUNC; + argv[0].val.func = fn; + +Call pcb_actionv_() with fn and the arguments. Always call fgw_argv_free() +afterward. Also call fgw_arg_free() on the res. + Index: tags/2.3.0/doc/developer/hid_remote/Makefile =================================================================== --- tags/2.3.0/doc/developer/hid_remote/Makefile (nonexistent) +++ tags/2.3.0/doc/developer/hid_remote/Makefile (revision 33253) @@ -0,0 +1,9 @@ +proto_parse.svg: proto_parse.dot fixlab.sh + ./fixlab.sh < proto_parse.dot > .proto_parse.dot + dot -Tsvg .proto_parse.dot > proto_parse.svg + + +proto_parse.png: proto_parse.dot fixlab.sh + ./fixlab.sh < proto_parse.dot > .proto_parse.dot + dot -Tpng .proto_parse.dot > proto_parse.png + Index: tags/2.3.0/doc/developer/hid_remote/fixlab.sh =================================================================== --- tags/2.3.0/doc/developer/hid_remote/fixlab.sh (nonexistent) +++ tags/2.3.0/doc/developer/hid_remote/fixlab.sh (revision 33253) @@ -0,0 +1,43 @@ +#!/bin/sh +awk ' +($2 == "->") { + + if (NF > 3) { + attr=$0 + if (!(attr ~ "[[]")) + attr = attr "[]" + } + else + attr = "[]" + + tmp = "lbl" (++lbl) + if (attr ~ "label") + extra_label="" + else + extra_label="label=\"\"" + + tmp_attr = attr + attr1=attr + attr2=attr + + if (extra_label == "") + sub("^[^[]*[[]", "[style=filled fillcolor=\"#fefefe\" shape=plaintext ", tmp_attr) + else { +# tmp_attr = "[fixedsize=true width=0 shape=plaintext " extra_label "]" + print $0 + next + } + + sub("^[^[]*[[]", "[", attr1) + sub("^[^[]*[[]", "[", attr2) + sub("label=\".*\"", "", attr1) + sub("label=\".*\"", "", attr2) + sub("[[]", "[arrowhead=none ", attr1) + + print tmp, tmp_attr + print $1, "->", tmp, attr1 + print tmp, "->", $3, attr2 + next +} +{ print $0 } +' \ No newline at end of file Property changes on: tags/2.3.0/doc/developer/hid_remote/fixlab.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/developer/hid_remote/proto_high.html =================================================================== --- tags/2.3.0/doc/developer/hid_remote/proto_high.html (nonexistent) +++ tags/2.3.0/doc/developer/hid_remote/proto_high.html (revision 33253) @@ -0,0 +1,237 @@ + + +

remote HID protocol, high level

+ +

reference

+ +

ver(protver)

+Sends the protocol version the server will speak. If the client doesn't +support that version, it should break the connection. +

+Arguments: +

    +
  • protver: an integer value; 1 for the current version +
+ +

unit(abbrev)

+Sends the coordinate unit used in subsequent communication. This is not +necessarily the unit used for displaying values on the user interface, +but the unit used to interpret numeric coordinate values sent in commands. +

+Arguments: +

    +
  • abbrev: unit name abbreviation; e.g. mm or nm or mil +
+ +

ready()

+Informs the client that the server is ready to start the session. The +client needs to answer with a Ready() message before the server proceeds. +

+Arguments: none. + + +

brddim(w h)

+Announce board dimensions. Some layers may extend beyond the board. +

+Arguments: +

    +
  • w: width (x size) in coordinate units +
  • h: height (y size) in coordinate units +
+ +

inval(x1 x2 y1 y2)

+Invalidate a rectangular section of the screen; the client should redraw +this area. Clients implementing their own mechanism to keep track on +drawing are free to ignore these requests +

+Arguments: +

    +
  • x1: left coordinate +
  • x2: right coordinate +
  • y1: top coordinate +
  • y2: bottom coordinate +
+ +

inval()

+Same as inval(x1 x2 y1 y2) but invalidates the whole screen. +

+Arguments: none + +

newlg(name group_id flags)

+Create a new layer group. +

+Arguments: +

    +
  • name: name of the layer group - names are not unique +
  • group_id: unique group ID (decimal integer, may be large) +
  • flags: a list of 3 items: location, purpose and properties. Each item is a list of values (or an empty list). +
+

+Example: +

+newlg(topassembly 16777219 ((top) (assy) (virtual)))
+
+Creates the top assembly virtual layer with ID 16777219 with the name +of "topassembly" + +

newly(name layer_id group_id)

+Create a new layer within an existing layer group. +

+Arguments: +

    +
  • name: name of the layer (can be empty, not unique) +
  • layer_id: unique ID of this layer (decimal integer, may be large) +
  • group_id: reference to a previously created layer group which this layer is part of +
+

+Example: +

+newly(soldergnd 3 11)
+
+Creates a layer 3 called "soldergnd" in group 11. + +

setlg(group_id is_empty purpose)

+Inform the client that the next set of drawing commands are for a specific +layer group. (Note: the reason for announcing groups and not layers: +all layers in that group are drawn at once; visibility +of layers within the same group are switched together.) +

+Arguments: +

    +
  • group_id: unique ID of the layer group +
  • is_empty: 1 if the layer group may be empty, 0 if the layer is not empty (TODO: this bit is not 100% reliable yet) +
  • purpose: layer group purpose field (usefil in mech/doc groups) +
+ +

makeGC()

+Request the client to make a new graphical context. The client should +allocate a GC and return an integer ID using the MadeGC(ID) message. +The ID uniquely identifies the GC; it should be small positive integer +(between 0 and 31 for now). +

+Arguments: none + +

delGC(ID)

+Inform the client that a given GC is not needed anymore. The server +will not reference the GC again and the GC can be destroyed (but graphics +drawn on the screen should not be affected). The ID may be reused by the +client in a subsequent madeGC() message). +

+Arguments: +

    +
  • ID: integer ID of the GC +
+ +

clr(gci colorstring)

+Change the color subsequent drawing commands of a given GC will use. +

+Arguments: +

    +
  • gci: ID of the GC +
  • colorstring: name of the color, specified in the usual "web" format: #rrggbb (with 3 hex numbers) +
+ +

cap(gci style)

+Set the line ending cap style. Note: the cap extends half-line-width beyond +the end coordinates, e.g. the end point of a line is the center of the round-cap +circle. +

+Arguments: +

    +
  • gci: ID of the GC +
  • style: r for round cap (circle), s for square cap, b for beveled (octagon) +
+ + +

linwid(gci width)

+Sets line width (pen tip diameter). +

+Arguments: +

    +
  • gci: ID of the GC +
  • width: diameter of the circular aperture of the pen in coord units +
+ +

setxor(gci state)

+Sets whether to perform "xor-drawing" for subsequent drawing commands in +the selected GC. +

+Arguments: +

    +
  • gci: ID of the GC +
  • xor: 0 means normal drawing, 1 means xor drawing +
+ + +

line(gci x1 y1 x2 y2)

+Draw a line using the current GC. The line inherits line width, color +and cap style from the GC. +

+Arguments: +

    +
  • gci: ID of the GC +
  • x1: 1st endpoint's X coord (in coord units) +
  • y1: 1st endpoint's Y coord (in coord units) +
  • x2: 2nd endpoint's X coord (in coord units) +
  • y2: 2nd endpoint's Y coord (in coord units) +
+ +

rect(gci x1 y1 x2 y2 filled)

+Draw a rectangle. The rectangle inherits only color from the GC. +

+Arguments: +

    +
  • gci: ID of the GC +
  • x1: 1st corner X coord (in coord units); x1 <= x2 +
  • y1: 1st corner Y coord (in coord units); y1 <= y2 +
  • x2: 2nd corner X coord (in coord units) +
  • y2: 2nd corner Y coord (in coord units) +
  • filled: 1 if the rectangle should be filled; a non-filled rectangle is a frame of 1 pixel wide lines +
+ + +

fcirc(gci cx cy r)

+Draw a filled circle. The circle inherits only color from the GC. +

+Arguments: +

    +
  • gci: ID of the GC +
  • cx1: center X coord (in coord units) +
  • cy1: center Y coord (in coord units) +
  • r: radius (in coord units) +
+ +

poly(gci len ptlist)

+Draw a filled polygon. The polygon inherits only color from the GC. +

+Arguments: +

    +
  • gci: ID of the GC +
  • len: number of contour points +
  • ptlist: an ordered list of (x y) coordinates (all in coord units) +
+ +

umask(m)

+"use mask" m. The server uses this message to make an announcement before it +starts drawing certain things. +

+Arguments: +

    +
  • m: mask name: +
      +
    • off: flush the buffer and return to non-mask operation. +
    • before: Polygons being drawn before clears. +
    • clear: Clearances being drawn. +
    • after: Polygons being drawn after clears. +
    +
+ + + Index: tags/2.3.0/doc/developer/hid_remote/proto_low.html =================================================================== --- tags/2.3.0/doc/developer/hid_remote/proto_low.html (nonexistent) +++ tags/2.3.0/doc/developer/hid_remote/proto_low.html (revision 33253) @@ -0,0 +1,146 @@ + + +

remote HID protocol, low level

+ +In this document bold words are tokens and italic words +are grammatic constructs. +

+The protocol is designed with the following goals in mind: +

    +
  • for simple/text data: compact, text format +
  • for simple/text data: easy to read/write manually +
  • for text with special characters: avoid quoting and escaping +
  • be able to embed binary data without having to recode it (e.g. in base64) +
  • to some extent be able to mix simple text and binary fields even within a single message +
  • predictable parsing: always know how much memory to allocate in advance +
  • minimalism - keep things as simple as possible +
+ + +

Tokens

+ +
token description +
( start a generic list +
) end a generic list +
{ start a binary list +
} end a binary list +
space element separator: space (ASCII dec 32) +
\n message separator: newline (ASCII dec 10) +
text-string short, alphanumeric string +
binary-string long and/or non-alnum string +
+ +

Grammar

+The communication is a pair of asynchronous message stream. The message +format is: +
+text-string generic-list \n
+or
+text-string binary-list \n
+or
+# comment \n
+
+

+where text-string is a command and generic-list is a list and holds +the arguments of. The command name can not start with a hash mark ('#') and +can not be empty. The list is the argument tree of the command. +

+As a special exception, a line may start with a hash mark ('#') to indicate +a comment. Characters up to the first newline are ignored. +

+Optional: a tolerant parser also accepts empty lines and whitespace before +a message. +

+The language has two type of lists: generic and binary. +A generic list is wrapped in parenthesis () and its children are: +

    +
  • text-string, +
  • generic-list, +
  • binary-list. +
+A binary-list is wrapped in braces {} and its children are: +
    +
  • binary-string, +
  • binary-list. +
+

+Any list can be empty. There's no whitespace after the opening token and +before the closing token, so the empty generic-list and the empty binary-list +are written as, respectively: +

+()
+{}
+
+Subsequent fields of a list has a single space in between, for +separation (this is an intentional redundancy for a binary-list). +

+Note: a generic-list can host text and binary children, but a +binary list can not host only binary children. This means if a node +of the parse tree is a binary list, the subtree will contain only binary nodes. +

+A text-string contains only English alphanumeric characters (A..Z, a..z, +0..9), underscores (_), plus and minus signs (+, -) periods (.) and +the hash mark ('#') and is at most 16 characters long. +

+A binary string encodes the length of the payload in base64 (A..Z, a..z, +, /), +has a '=' for separator then the payload in binary format. For example +

+F=hello
+
+means the 5 characters long string "hello". The maximum size of the base64 +encoded length field is 5, thus the longest binary data that can be +packed in a single field is 1 gigabyte. + +

Examples

+ +

empty-argument messages

+
+hello()\n
+foo{}\n
+
+ +

single-argument messages

+Text and binary alternative for the same content: +
+hello(world)\n
+hello{F=world}\n
+
+ +

multi-argument messages

+Text and binary alternative for the same content: +
+print(hello world !)\n
+print{E=hello F=world B=!}\n
+
+ +Note: using space between list items; don't space +before the first or after the last argument. Always emit one space between +any two list items. + +

lists in list

+Text and binary alternatives for the same content: +
+line((14.55 3.1) (44.2 0) 5)\n
+line({F=14.55 D=3.1} (44.2 0) 5)\n
+line((14.55 3.1) {E=44.2 B=0} 5)\n
+line({F=14.55 D=3.1} {E=44.2 B=0} 5)\n
+line{{F=14.55 D=3.1} {E=44.2 B=0} B=5}\n
+
+The subtree assumed in this fictional message is two x;y coordinate pairs +and a line width. In other words the arguments of line is a list (start +point), another list (end point) and a scalar (width). +

+Since all data comply to the text-string token format, +the first, simplest format is recommended. The other 4 lines demonstrate all +other valid variants. +

+It is important to note that there are constraints (derived from +the grammar) on choosing which list items can be encoded in binary: +

    +
  • a binary-string can be only on a binary-list +
  • a text-string can be only on a generic-list +
  • a generic-list can not be only under a binary-list +
+Thus if the 3rd argument, (width in this example), must be encoded as a +binary-string, it will turn it's parent, line's argument list +binary too, which in turn enforces all arguments to be binary. Index: tags/2.3.0/doc/developer/hid_remote/proto_parse.dot =================================================================== --- tags/2.3.0/doc/developer/hid_remote/proto_parse.dot (nonexistent) +++ tags/2.3.0/doc/developer/hid_remote/proto_parse.dot (revision 33253) @@ -0,0 +1,84 @@ +digraph parse_state_macine { + + +MSG [label="MSG:\nmessage lead-in\nor\nbetween\nmessages" shape=box style=filled fillcolor=yellow] +COMMENT [label="COMMENT:\nskipping comment" shape=box style=filled fillcolor=yellow] +CMD [label="CMD:\nparsing command name" shape=box style=filled fillcolor=yellow] +TSTR [label="TSTR:\nparsing test string" shape=box style=filled fillcolor=yellow] +BSTR [label="BSTR:\nparsing bin string" shape=box style=filled fillcolor=yellow] +LIST [label="LIST:\nin list" shape=box style=filled fillcolor=yellow] +ERROR [label="ERROR:\nbad input" shape=box style=filled fillcolor=red] + +######## MSG + +init [shape="diamond" style=filled fillcolor=yellow] +init -> MSG + +msg_append [label="store 1st\ncommand char"] + +MSG -> COMMENT [label="input==#" color=blue] +MSG -> MSG [label="input==\\r\\n\\t\nspace" color=blue] +MSG -> ERROR [label="input==binary"] +MSG -> msg_append [label="input==text"] +msg_append -> CMD + +######## COMMENT + +COMMENT -> MSG [label="input==\\n" color=blue] +COMMENT -> COMMENT [color=blue] + + +######## CMD +cmd_list_new [label="create new list\nmake it arg tree\nroot and current"] +cmd_list_new -> LIST +cmd_append [label="append a character\nto command name"] +cmd_append -> CMD [label="command name length\nis less than 16"] +cmd_append -> ERROR [label="command name length\nis more than 16"] +CMD -> cmd_list_new [label="input==({"] +CMD -> ERROR [label="input==binary"] +CMD -> cmd_append [label="input==text"] + +######## LIST +got_msg [label="message fully parsed\nexecute message" style=filled fillcolor=cyan] +got_msg -> MSG +pop [label="pop:\ncurrent_list = current_list->parent"] +pop -> got_msg [label="input=\\n\nand\ncurrent_list == NULL\n(arg root closed)"] +pop -> ERROR [label="input!=\\n\nand\ncurrent_list == NULL\n(unbalanced parenthesis)"] +pop -> LIST +push [label="push:\create new list\nappend it as current's sibling\nmake it current"] +push->LIST +new_str [label="create a new bin or text string\nnode and append it to\nthe current list"] +new_str -> tstr_append [label="current is generic list"] +new_str -> bstr_append [label="current is binary list"] + +LIST -> pop [label="input==)}"] +LIST -> push [label="input==({"] +LIST -> LIST [label="input==space\n(ignore)"] +LIST -> ERROR [label="input!=\\n and current == NULL\n(unbalanced parenthesis)"] +LIST -> new_str [label="input==text"] + +######## TSTR +str_fin [label="finish current string\n"] +str_fin -> LIST +str_fin_pop [label="finish current string\n"] +str_fin_pop -> pop +tstr_append [label="append to current string\n"] +tstr_append -> ERROR [label="string length > 16"] +tstr_append -> TSTR +TSTR -> str_fin [label="input==space"] +TSTR -> str_fin_pop [label="input==)}"] +TSTR -> ERROR [label="input==binary"] +TSTR -> tstr_append [label="input==text"] + +######## BSTR +read_base64 [label="store next digit\nof string length"] +read_base64 -> BSTR +bstr_append -> BSTR +BSTR -> read_base64 [label="before the ="] +BSTR -> bstr_append [label="after the ="] +BSTR -> str_fin_pop [label="last char of the string"] + +######## ERR +ERROR -> ERROR [label="can't recover"] + +} Index: tags/2.3.0/doc/developer/hid_remote/proto_parse.html =================================================================== --- tags/2.3.0/doc/developer/hid_remote/proto_parse.html (nonexistent) +++ tags/2.3.0/doc/developer/hid_remote/proto_parse.html (revision 33253) @@ -0,0 +1,38 @@ + + +Protocol parser state machine of the reference implementation: + +Legend: +
    +
  • yellow boxes are states +
  • blue arrows are optional features for a more tolerant parser +
  • round nodes are actions that shall be taken +
  • arrow with text: execute action or switch state if condition is true +
  • arrow without text: do this if no other condition is met +
+

Notes on the reference implementation

+The reference implementation builds a tree of nodes for the arguments. +Each node is either a list or a text. A node has a pointer to its parent, its +first child and its next sibling. While parsing list-of-lists, the parser +keeps a current node. A new node is either added as the last sibling of +the current node (new argument on a list) or as the first +child of the current node (first argument of a new list when the list is +open). +

+When a list is closed, the parent of the current node becomes the +new current node. +

+When parsing a new message, the current node is NULL until the argument list +is open; the new current node also becomes the argument tree root. +If the argument tree root is closed, a newline shall follow, because that's +how a message is terminated. +

+The binary string part of the state machine has 2 more internal +states: +

    +
  • a boolean indicating whether we are parsing the length or the string (before or after the '=') +
  • an integer string length +
+ + + Index: tags/2.3.0/doc/developer/hid_remote/proto_parse.svg =================================================================== --- tags/2.3.0/doc/developer/hid_remote/proto_parse.svg (nonexistent) +++ tags/2.3.0/doc/developer/hid_remote/proto_parse.svg (revision 33253) @@ -0,0 +1,597 @@ + + + + + + +parse_state_macine + + +MSG + +MSG: +message lead-in +or +between +messages + + +lbl2 + +input==# + + +MSG->lbl2 + + + +lbl3 + +input==\r\n\t +space + + +MSG->lbl3 + + + +lbl4 + +input==binary + + +MSG->lbl4 + + + +lbl5 + +input==text + + +MSG->lbl5 + + + +COMMENT + +COMMENT: +skipping comment + + +COMMENT->COMMENT + + + + +lbl7 + +input==\n + + +COMMENT->lbl7 + + + +CMD + +CMD: +parsing command name + + +lbl12 + +input==({ + + +CMD->lbl12 + + + +lbl13 + +input==binary + + +CMD->lbl13 + + + +lbl14 + +input==text + + +CMD->lbl14 + + + +TSTR + +TSTR: +parsing test string + + +lbl30 + +input==space + + +TSTR->lbl30 + + + +lbl31 + +input==)} + + +TSTR->lbl31 + + + +lbl32 + +input==binary + + +TSTR->lbl32 + + + +lbl33 + +input==text + + +TSTR->lbl33 + + + +BSTR + +BSTR: +parsing bin string + + +lbl36 + +before the = + + +BSTR->lbl36 + + + +lbl37 + +after the = + + +BSTR->lbl37 + + + +lbl38 + +last char of the string + + +BSTR->lbl38 + + + +LIST + +LIST: +in list + + +lbl21 + +input==)} + + +LIST->lbl21 + + + +lbl22 + +input==({ + + +LIST->lbl22 + + + +lbl23 + +input==space +(ignore) + + +LIST->lbl23 + + + +lbl24 + +input!=\n and current == NULL +(unbalanced parenthesis) + + +LIST->lbl24 + + + +lbl25 + +input==text + + +LIST->lbl25 + + + +ERROR + +ERROR: +bad input + + +lbl39 + +can't recover + + +ERROR->lbl39 + + + +init + +init + + +init->MSG + + + + +msg_append + +store 1st +command char + + +msg_append->CMD + + + + +lbl2->COMMENT + + + + +lbl3->MSG + + + + +lbl4->ERROR + + + + +lbl5->msg_append + + + + +lbl7->MSG + + + + +cmd_list_new + +create new list +make it arg tree +root and current + + +cmd_list_new->LIST + + + + +cmd_append + +append a character +to command name + + +lbl10 + +command name length +is less than 16 + + +cmd_append->lbl10 + + + +lbl11 + +command name length +is more than 16 + + +cmd_append->lbl11 + + + +lbl10->CMD + + + + +lbl11->ERROR + + + + +lbl12->cmd_list_new + + + + +lbl13->ERROR + + + + +lbl14->cmd_append + + + + +got_msg + +message fully parsed +execute message + + +got_msg->MSG + + + + +pop + +pop: +current_list = current_list->parent + + +pop->LIST + + + + +lbl16 + +input=\n +and +current_list == NULL +(arg root closed) + + +pop->lbl16 + + + +lbl17 + +input!=\n +and +current_list == NULL +(unbalanced parenthesis) + + +pop->lbl17 + + + +lbl16->got_msg + + + + +lbl17->ERROR + + + + +push + +push:create new list +append it as current's sibling +make it current + + +push->LIST + + + + +new_str + +create a new bin or text string +node and append it to +the current list + + +lbl19 + +current is generic list + + +new_str->lbl19 + + + +lbl20 + +current is binary list + + +new_str->lbl20 + + + +tstr_append + +append to current string + + +lbl19->tstr_append + + + + +tstr_append->TSTR + + + + +lbl28 + +string length > 16 + + +tstr_append->lbl28 + + + +bstr_append + +bstr_append + + +lbl20->bstr_append + + + + +bstr_append->BSTR + + + + +lbl21->pop + + + + +lbl22->push + + + + +lbl23->LIST + + + + +lbl24->ERROR + + + + +lbl25->new_str + + + + +str_fin + +finish current string + + +str_fin->LIST + + + + +str_fin_pop + +finish current string + + +str_fin_pop->pop + + + + +lbl28->ERROR + + + + +lbl30->str_fin + + + + +lbl31->str_fin_pop + + + + +lbl32->ERROR + + + + +lbl33->tstr_append + + + + +read_base64 + +store next digit +of string length + + +read_base64->BSTR + + + + +lbl36->read_base64 + + + + +lbl37->bstr_append + + + + +lbl38->str_fin_pop + + + + +lbl39->ERROR + + + + + Index: tags/2.3.0/doc/developer/hid_render_comp.html =================================================================== --- tags/2.3.0/doc/developer/hid_render_comp.html (nonexistent) +++ tags/2.3.0/doc/developer/hid_render_comp.html (revision 33253) @@ -0,0 +1,128 @@ + + +

HID: rendering vs. composite layers

+

+All rendering is driven by the core. The core understands the PCB stackup, +layers, layer groups, compositions within the layer groups, extra labels, +layer visibility, etc. The HID is a slave device that takes drawing +instructions and blindly executes them. +

+However, the HID has a chance to alter which layer groups are drawn, using +the set_layer_group hooks return value. + +

Bursts and layer groups

+

+The rendering is done in bursts. A burst may redraw only a small window +of the screen. Each bursts draws multiple layer groups, in Z-order, from +bottom (furthest from the eye of the user) to up (closest to the eye of +the user). Each layer group is drawn on a transparent sketch canvas. In positive mode, +objects are drawn with multiple colors on each sketch canvas. In negative mode +pixels are erased from the sketch canvas, making the affected pixels transparent again. Drawing +on a layer group (either positively or negatively) should +overwrite pixels on the same layer group. In other words, there's +no translucency between two overlapping objects drawn on the same layer +group. + +

+There is a so called output canvas, which shall be cleared to +the background color upon render_burst / start. The background +color shall be fetched from the config tree (appearance/color/background). +

+The following steps are taken by the core in a burst: +

    +
  • 1. call to the render_burst hook with start +
  • 2. set_layer_group is called for the next layer; depending on the return value, the core will skip to step 7. +
  • 3. set_drawing_mode is called with reset (also indicates start of a composite layer) +
  • 4. set_drawing_mode is called with positive or negative to set draw or erase +
  • 5. objects are drawn +
  • 6. if there are subsequent composite layers, the core will jump back to 4. +
  • 7. set_drawing_mode is called with flush (also indicates end of a composite layer) +
  • 8. if there are further groups, the core jumps back to step 3. +
  • 9. call to the render_burst hook with end +
+

+When set_drawing_mode / reset is called, the HID needs to +create a new sketch canvas, all pixels initialized to transparent. The +core may switch between positive and negative draw any time. When +set_drawing_mode / flush is called, the current sketch +canvas needs to be blitted onto the output (in a HID-specific way) and +the sketch canvas can be destroyed. The output canvas shall be flushed to +the screen upon render_burst / end. +

+Optional optimization: the most common case is when only positively drawn +layers are used to draw the final output. Drawing on separate sketch canvases and +blitting them onto an output buffer is a waste in this setup. To give HIDs a +chance to avoid the extra copies, set_drawing_mode calls have an +argument called direct. When the direct is set, it is safe +to directly draw on the output canvas, without allocating a sketch canvas. The +core guarantees the followings: +

    +
  • all calls of set_drawing_mode within drawing a layer group will have the same direct argument +
  • if direct is set for a layer group, set_drawing_mode will not be called with negative +
  • only the first N consecutive layer groups can be direct; once a group is drawn with direct unset, all subsequent groups will be drawn with direct unset +
+

+It is possible that the core would draw the whole board in direct +mode. It is safe to ignore the direct argument and always use the +more expensive, sketch-canvas+blitting method. + +

GCs

+

+The API contains Graphic Context, or GC for short. A GC is a pen with +properties like color and tip shape. The core will initialize multiple +GCs for the drawing and will pass a GC pointer with each drawing command. +

+Note: this concept is orthogonal to the above canvas based drawing. +Regardless of which GC is used, the object being drawn always ends up +making modifications to the currently active (sketch) canvas. +

+A GC can be initialized only after render_burst / start +and all GCs will be uninitialized before render_burst / end. + +

colors

+

+In negative drawing mode, drawing an object always clear on the current canvas, +regardless of the GC color. +

+In positive drawing mode, objects are drawn with whatever color the +current GC has. The special color "drill" is used to draw holes that go thru +all layers of the board. It is possible that a drill is drawn over existing +objects and new objects are drawn on top of a drilled hole. To get the +proper order, the HID shall set the .holes_after to 1. +

+(Note: there's no "erase" color anymore.) + + +

transition

+

+When switching over an existing HID from the old use_mask() API to the new +composite API: +

    +
  • set .poly_before to 0 +
  • set .poly_after to 0 +
  • set .enable_fake_composite to 0 +
  • set .holes_after to 1 +
  • use an empty function for .use_mask for now +
+ +

XOR drawing

+

+XOR draw is used as a mean to make an object always visible, no matter +over what background it is drawns. It is not used as a cheap draw/erase +mechanism, so HIDs are free to implement it with a different algorithm - as +long as it is guaranteed that objects drawn on the same colored background +will stick out. +

+There are two places XOR draw takes place: +

    +
  • in core's normal draw procedures (pcb_hid_expose*()), as the very last + compsiting canvas (after everything else had been drawn) +
  • in pcb_draw_attached(), whenever it is called by the HID +
+

+In both cases the drawing mode is set to PCB_HID_COMP_POSITIVE_XOR, which does +not clear the direct flag. The GC that is used for drawing the actual +objects also has its xor mode set. + + + Index: tags/2.3.0/doc/developer/hidlib/TODO =================================================================== --- tags/2.3.0/doc/developer/hidlib/TODO (nonexistent) +++ tags/2.3.0/doc/developer/hidlib/TODO (revision 33253) @@ -0,0 +1,22 @@ +What the user code needs to implement + +1. actions (optional) + StatusSetText() + DescribeLocation() + +2. docked DAD subwindows (optional) + bottom status line + top right coord readout + top left toolbar + +3. conventions + all calls have access to the current (pcb_hidlib_t *) + there's a design (pcb_board_t) + recommendation: the design struct's first field should be pcb_hildib_t so they can be casted forth and back + +4. icon colors: + + None - transparent + #000000 - black + #7A8584 - light grey + #6EA5D7 - cyan/blue Index: tags/2.3.0/doc/developer/hidlib/init_seq.txt =================================================================== --- tags/2.3.0/doc/developer/hidlib/init_seq.txt (nonexistent) +++ tags/2.3.0/doc/developer/hidlib/init_seq.txt (revision 33253) @@ -0,0 +1,117 @@ +1. simplified (custom) init sequence + +This method is useful for the simplest, gui-only applications that +potentially do not have plugins. + +int main(int argc, char *argv[]) +{ + pcb_fix_locale_and_env(); + + /* set up non-hidlib related app states */ + ... + + pcb_hidlib_init1(conf_core_init); + + /* process command line args */ + ... + + pcb_hidlib_init2(pup_buildins); + + /* set up hidlib related app states - all main infrastructure is up by now */ + ... + + /* initialize the gui and run the main loop */ + pcb_gui = pcb_hid_find_gui(gui_name); + if (pcb_gui == NULL) { + pcb_message(PCB_MSG_ERROR, "can't find HID '%s'\n", gui_name); + pcbhl_log_print_uninit_errs(""); + exit(1); + } + if (pcb_gui->parse_arguments(&argc, &argv) != 0) { + pcb_message(PCB_MSG_ERROR, "can't init HID '%s'\n", gui_name); + pcbhl_log_print_uninit_errs(""); + exit(1); + } + pcb_gui->do_export(&camv.hidlib, 0); + + /* application state uninit */ + ... +} + + +2. standard init sequence + +Hidlib calls help to initialize the plugin system, parse the command line +argument, choose command line action, exporter or GUI in a standard way. +Full featured hidlib applications with feature and export plugins should +use this sequence. + +static const char *camv_action_args[] = { +/*short, -long, action, help, hint-on-error */ + "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 */ +}; + +int main(int argc, char *argv[]) +{ + pcbhl_main_args_t ga; + + pcb_fix_locale_and_env(); + + pcbhl_main_args_init(&ga, argc, camv_action_args); + + pcb_hidlib_init1(conf_core_init); + for(n = 1; n < argc; n++) { + /* process application-specific arguments here and skip the next line for those */ + n += pcbhl_main_args_add(&ga, argv[n], argv[n+1]); + } + pcb_hidlib_init2(pup_buildins); + + /* direct exporting via -x */ + if (pcbhl_main_args_setup1(&ga) != 0) { + camv_main_uninit(); + pcbhl_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). */ +#include "generated_lists.h" + + if (pcbhl_main_args_setup2(&ga, &n) != 0) { + camv_main_uninit(); + pcbhl_main_args_uninit(&ga); + exit(n); + } + + if (ga.hid_argc > 0) { + /* command line leftover: typically file name(s) to load, in + ga.hid_argv[0 .. ga.hid_argc-1]; */ + } + + /* do the export if -x was specified */ + if (pcbhl_main_exported(&ga, ...)) { + camv_main_uninit(); + pcbhl_main_args_uninit(&ga); + exit(0); + } + + /* main loop */ + do { + /* optional: if a plugin is required for basic GUI operation, load it here */ + if (PCB_HAVE_GUI_ATTR_DLG) + gui_support_plugins(1); + pcbhl_mainloop_interactive(&ga, ...); + } while(pcb_gui != NULL); + + /* application specific uninit */ + ... + + pcbhl_main_args_uninit(&ga); + return 0; +} + + + Index: tags/2.3.0/doc/developer/import.html =================================================================== --- tags/2.3.0/doc/developer/import.html (nonexistent) +++ tags/2.3.0/doc/developer/import.html (revision 33253) @@ -0,0 +1,64 @@ + + +

pcb-rnd hacking - how importers work

+ +

Introduction

+This document describes the common aspects of import code, be it an +import_ plugin or the load part of an io_plugin, importing a footprint, +loading a board or a netlist. + +

Data structures

+ +The board is stored in pcb_board_t *. Some import code, like the one +that loads a design (an io plugin's ->parse_pcb function), gets the +target in an argument. (Other, non-import code usually operate on +the global variable that represents the current board: +pcb_board_t *PCB.). +

+In either case, pcb_board_t's most important field is pcb_data_t *data, +which holds lists and vectors to store all objects on the board. When +the target is a buffer (e.g. io plugin's ->parse_element function), it's +a pcb_buffer_t *buf which also have a pcb_data_t *data containing +the same data a board could. +

+A pcb_data_t struct in turn has three sets of important fields: +

    +
  • lists for layer-independent objects (e.g. rat lines, padstacks, subcircuits) +
  • number of layers in use (LayerN) and an array of layers (see later) +
  • rtree structures - these are used for looking up objects for locations +
+Each layer is a pcb_layer_t structure. A layer has the following fields: +
    +
  • lists for lines, texts, arcs, polygons +
  • some generic layer attributes (colors, flags, key-value pairs) +
  • an rtree struct for each object type. +
+

+Any code that needs to create objects should use the functions in obj_*.h. +The functions that operate layer-independently usually get a destination as +pcb_data_t, so they can operate both on boards and buffers. A typical +example is pcb_pstk_t *pcb_pstk_new(pcb_data_t *data, ...) that returns +NULL or the pointer to the new via that is already added to the corresponding list +of data and in the rtree. +

+Layer object creation is done referencing the layer as pcb_layer_t *. A +typical example is pcb_line_t *pcb_line_new(pcb_layer_t *layer...) +which returns NULL on error or a pointer to the new line object created (inserted +in the layer's line list, added to the rtree). +

+Code should avoid manipulating the lists and rtree structures directly. + +
+
+Figure 1. simplified map of object related data structures +
+diamond: variable; rectangle: struct; round: struct field; green: drawing primitive +
+ + +

Extra steps around creating a new board

+TODO: postproc, post*, other setup + + + + Index: tags/2.3.0/doc/developer/indent.html =================================================================== --- tags/2.3.0/doc/developer/indent.html (nonexistent) +++ tags/2.3.0/doc/developer/indent.html (revision 33253) @@ -0,0 +1,36 @@ + + +

pcb-rnd - indentation

+ +As of r1022 all old code is converted using indent(1). Our preferred +coding style is close to what the following command line produces, using +our patched version of indent(1): +
+indent --line-length256 -brs -br -nce --tab-size2 -ut -npsl  -npcs -hnl -cli2 -nsaf -sai -nsaw -ncs -c0 -cd0 -cp0
+
+

+Contributors are kindly asked to follow this style or run the above +commandline on their new code before sending a patch or committing +to svn. The style of existing code lines should not be changed, +not even the "surrounding" lines to a largish patch, especially not in the +same patch/commit with actual code changes. +

+We do not put space between the pointer-asterisk and name; indent(1) +unfortunately does this in function declaration: + + +
right wrong +
int foo(char *bar); + int foo(char * bar); +
+

+We have a patch against indent 2.2.11 to +fix this. +

+We do not use tabs for aligning code in columns; we use tabs exclusively +to indicate levels logical alignment. indent(1) attempts to align the +right-side comments using tabs. We have a patch +against indent 2.2.11 to change this when column is set to 0. + + + Index: tags/2.3.0/doc/developer/indent_cmt.patch =================================================================== --- tags/2.3.0/doc/developer/indent_cmt.patch (nonexistent) +++ tags/2.3.0/doc/developer/indent_cmt.patch (revision 33253) @@ -0,0 +1,18 @@ +diff -uri indent-2.2.11.orig/src/comments.c indent-2.2.11/src/comments.c +--- indent-2.2.11.orig/src/comments.c 2018-01-26 13:45:48.474640060 +0100 ++++ indent-2.2.11/src/comments.c 2018-01-26 14:47:06.867653819 +0100 +@@ -339,7 +339,13 @@ + start_column = count_columns (compute_label_target (), s_lab, NULL_CHAR); + } + +- if (start_column < target) ++ if (target == 0) ++ { ++ /* 0 means start right after the end of the line, adding a space, no alignment */ ++ *e_com++ = ' '; ++ column++; ++ } ++ else if (start_column < target) + { + start_column = target; + } Index: tags/2.3.0/doc/developer/indent_fdecl.patch =================================================================== --- tags/2.3.0/doc/developer/indent_fdecl.patch (nonexistent) +++ tags/2.3.0/doc/developer/indent_fdecl.patch (revision 33253) @@ -0,0 +1,17 @@ +diff -uri indent-2.2.11.orig/src/handletoken.c indent-2.2.11/src/handletoken.c +--- indent-2.2.11.orig/src/handletoken.c 2018-01-26 13:45:48.477640023 +0100 ++++ indent-2.2.11/src/handletoken.c 2018-01-26 14:23:38.923255546 +0100 +@@ -677,8 +677,11 @@ + + } + #endif +- +- parser_state_tos->want_blank = true; ++ if (parser_state_tos->in_decl) ++ parser_state_tos->want_blank = false; ++ else ++ parser_state_tos->want_blank = true; ++ + } + + /** Index: tags/2.3.0/doc/developer/io_lihata_ver.html =================================================================== --- tags/2.3.0/doc/developer/io_lihata_ver.html (nonexistent) +++ tags/2.3.0/doc/developer/io_lihata_ver.html (revision 33253) @@ -0,0 +1,120 @@ + + + + pcb-rnd - io_lihata versions + + + + + +

pcb-rnd - io_lihata versions

+

+History of io_lihata, per format version. + +

lihata board

+

v1

+

+ Feature-compatible with the gEDA/PCB file format, plus allows multiple + fonts. Same assumptions on layers: last two must be the silk layers. + +

v2

+

+ Introduce the layer stack subtree and remove layer assumptions. Save + the combining field of layers. + +

v3

+

+ New global object subtree: subcircuit. Global object element has been removed. +

+ Intconn is not a flag, but a pin/pad/terminal attribute. + +

v4

+

+ New subtree under data: padstack_prototypes, for storing padstack prototypes. + ID is the place of the padstack within the list. +

+ New object type under : ha:padstack_ref.id. + +

v5

+

+ Removed drc and isle_area_nm from the board header in favor of the config + subtree. Removed the cursor section from board header - cursor position and + zoom should not be saved or loaded. +

+ Warn for the intnoconn attribute when saving pre-v5 - pcb-rnd versions + supporting v4 or lower will most probably not understand it. +

+ Layer group and network attributes. Layer colors. +

+ Optional route style via prototype ID. +

+ Optional padstack prototype name for easier user identification of prototypes. +

+ Remove old model objects: elements, element-lines, element-arcs, + pins, pads, vias. They are still loaded if they are found in v5, + but a warning is generated and the objects are force-converted to + the new model on save. + +

v6

+

+ Extended the text object fields with optional thickness and rot fields that + will be able to override the default mechanism for determining the thickness + or the n*90 degree rotation angle (with an arbitrary value). +

+ Removed the direction field from text - use the rot field instead. +

+ New route style entries for default text thickness and text scale. +

+ New layer group types PCB_LYT_DOC and PCB_LYT_MECH are handled on load + and save. +

+ Load and save purpose field in layer groups and bound layers. +

+ The layer visibility bit is not saved any more - it was reset after load so + it only added noise to the file. +

+ When saving PCB_THERMAL_NOSHAPE, mark + it explicitly by writing "noshape" instead of just leaving the + thermal shape empty. + +

v7

+

+ Polygon enforce_clearance (when non-zero, enforces minimum clearance + on clearing objects within the polygon). +

+ Informal change: text attribute tight_clearance is interpreted to change + the clearance style of a text object. +

+ Informal change: text attribute mirror_x is interpreted to mirror the + X coordunates of the text object (text mirror over the Y axis). +

+ The pixmap subtree with ulzw entries and gfx layer objects - provides + on-screen pixel graphics. +

+ Rat anchor objects are saved with idpath so the exact connections of + a rat is preserved. +

+ Text objects optionally have separate scale_x and scale_y fields for + different width/height scaling. + +

lihata subcircuit

+

v4

+ Initial version, used before board v6. + +

v6

+ Used from board v6. Allows ps_proto_v6. + +

v7

+ Used from board v7. Allows polygon enforce_clearance, tight_clearance + attribute for text objects, mirror_x attribute for text objects, + gfx/pixmap and text scale_x/scale_y. + +

ps_proto

+

v4

+ Initial version, used before board v6. + +

v6

+ Used from board v6. Features new layer type: PCB_LYT_MECH and + new pad shape: hshadow. + + Index: tags/2.3.0/doc/developer/lihata_format/Makefile =================================================================== --- tags/2.3.0/doc/developer/lihata_format/Makefile (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/Makefile (revision 33253) @@ -0,0 +1,24 @@ +DOTS = \ + data.dot \ + geda-project-v1.dot \ + pcb-rnd-board-v.dot \ + pcb-rnd-conf-v1.dot \ + pcb-rnd-font-v1.dot \ + pcb-rnd-subcircuit-v.dot \ + submenu.dot \ + padstack.dot + +all: tree.html tree.txt $(DOTS) + +%.dot: render/render.sh render/*.awk *.lht + cd render && ./render.sh dot + for n in *.dot; do dot -Tsvg $$n > $${n%%.dot}.svg; done + +tree.html: render/render.sh render/*.awk *.lht + cd render && ./render.sh html > ../tree.html + +tree.txt: tree.html + w3m -cols 256 tree.html > tree.txt + +comm_flags.lht: ../../../src/pcb-rnd render/gen_flags.sh + cd render && ./gen_flags.sh > ../comm_flags.lht Index: tags/2.3.0/doc/developer/lihata_format/comm_attribs.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/comm_attribs.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/comm_attribs.lht (revision 33253) @@ -0,0 +1,22 @@ +ha:lht_tree_doc { ha:comm { + + ha:attributes { + type=ha + hide=1 + desc { a hash of attribute key=value pairs } + li:children { + ha:attrib-key { valtype=string; desc={attribute value}} + } + } + ha:attributes_v5p { + name=attributes + hide=1 + type=ha + desc { a hash of attribute key=value pairs } + ver={>=5} + li:children { + ha:attrib-key { valtype=string; desc={attribute value}} + } + } + +}} Index: tags/2.3.0/doc/developer/lihata_format/comm_data.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/comm_data.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/comm_data.lht (revision 33253) @@ -0,0 +1,315 @@ +ha:lht_tree_doc { ha:comm { + + ha:data { + type=ha + desc { Layers and global objects of the board } + li:children { + ha:objects { + type=li + desc { List of global (non-layer/multi-layer) objects } + li:children { + ha:padstack_ref.ID { + type=ha + ver={>=4} + desc { a padstack reference (instance) placed on the board (e.g. used as a via) } + li:children { + ha:proto = { valtype=integer; desc={padstack prototype ID to use, from the parent data's proto list }} + ha:x = { valtype=coord; desc={place padstack with origin at this horizontal coordinate }} + ha:y = { valtype=coord; desc={place padstack with origin at this vertical coordinate }} + ha:clearance = { valtype=coord; desc={global clearance; if non-zero, overrides local (per shape) clearance }} + ha:rot = { valtype=angle; desc={rotation angle in degrees }} + ha:xmirror = { valtype=integer; desc={0 or 1; if 1, mirror all shapes over the x (horizontal) axis (so that y coords are flipped)}} + ha:smirror = { valtype=integer; desc={0 or 1; if 1, mirror the layer stackup: bottom becomes top, top becomes bottom (a.k.a. "place on the other side")}} + sy:attr@dup = {/lht_tree_doc/comm/attributes} + sy:flags@dup = {/lht_tree_doc/comm/flags_padstack} + ha:thermal { + type=li + desc { list of thermal shapes, per layer } + li:children { + ha:LAYERID { + type=li + desc { integer layer ID the thermal affects; each word is a boolean flag that is either present on the list or is missing; only one shape may be present } + li:children { + ha:on = { valtype=none; desc={ thermal is present on this layer; if not present, all other thermal flags are ignored on this layer }} + ha:diag = { valtype=none; desc={ thermal graphics is not axis aligned but diagonal (rotated by 45 degrees) }} + ha:round = { valtype=none; desc={ shape: rounded edge fingers }} + ha:sharp = { valtype=none; desc={ shape: sharp edge fingers }} + ha:solid = { valtype=none; desc={ shape: no thermal relief, solid connection without clearance }} + ha:noshape = { valtype=none; ver={>=6} desc={ shape: special: omit copper shape of the padstack on this layer }} + } + } + } + } + } + } + ha:via.ID { + type=ha + ver={<=4} + desc { an old via object (loaded as padstack in the new model) } + li:children { + ha:x = { valtype=coord; desc={place padstack with origin at this horizontal coordinate }} + ha:y = { valtype=coord; desc={place padstack with origin at this vertical coordinate }} + ha:thickness = { valtype=coord; desc={copper shape dimension (diameter) }} + ha:clearance = { valtype=coord; desc={copper clearance around the copper shape }} + ha:mask = { valtype=coord; desc={mask cutout shape dimension (diameter) }} + ha:hole = { valtype=coord; desc={drill/hole diameter }} + ha:name = { valtype=string; desc={optional name attribute }} + ha:number = { valtype=string; desc={for a pin (or to-be-pin) this is the terminal ID }} + sy:attr@dup = {/lht_tree_doc/comm/attributes} + sy:flags@dup = {/lht_tree_doc/comm/flags_pinvia} + } + } + } + } + ha:layers { + type=li + desc={ordered list of layers; v1 required the order to be top-bottom physically; v1 also required silk layers to be at the end (same resrtictions as in the old .pcb format; only real (non-bound) layers have attributes)} + li:children { + ha:NAME { + type=ha + desc={a logical layer} + li:children { + ha:lid = { valtype=integer; ver={>=2} desc={layer ID}} + ha:visible = { valtype=integer; ver={<6} desc={only in real (non-boud) layers: 1 if the layer is visible, 0 if not (UI setting)}} + ha:group = { valtype=integer; desc={only in real (non-boud) layers: "parent" layer group ID }} + ha:color = { valtype=string; ver={>=5} desc={ layer color on UI, in #rrggbb format }} + ha:stack_offs = { valtype=integer; desc={only in bound layers: match offset e.g. for internal copper layers}} + ha:type { + type=ha + desc={only for bound layers: try to bind to this type of layer on the host board} + sy:children {/lht_tree_doc/comm/layer_mask/children} + } + ha:purpose = { valtype=integer; ver={>=6} desc={only in bound layers: match layer group purpose}} + ha:combining { + ver={>=2} + desc={layer combination (compositing) flags} + sy:children {/lht_tree_doc/comm/combining/children} + } + sy:attr@dup = {/lht_tree_doc/comm/attributes} + ha:objects { + type=li + desc={list of drawing primitives put on this layer} + li:children { + ha:line.ID { + type=ha + desc={round cap line} + li:children { + ha:x1 = { valtype=coord; desc={line first endpoint, horizontal offset }} + ha:y1 = { valtype=coord; desc={line first endpoint, vertical offset }} + ha:x2 = { valtype=coord; desc={line second endpoint, horizontal offset }} + ha:y2 = { valtype=coord; desc={line second endpoint, vertical offset }} + ha:thickness = { valtype=coord; desc={width of the line }} + ha:clearance = { valtype=coord; desc={copper clearance around the object }} + sy:attr@dup = {/lht_tree_doc/comm/attributes} + sy:flags@dup = {/lht_tree_doc/comm/flags_line} + sy:hvthr@dup = {/lht_tree_doc/comm/thermal_heavy} + } + } + ha:arc.ID { + type=ha + desc={round cap elliptic arc (only width==height is fully supported at the moment)} + li:children { + ha:x = { valtype=coord; desc={center, X coord}} + ha:y = { valtype=coord; desc={center, Y coord}} + ha:width = { valtype=coord; desc={radius (of the centerline of the arc) in X direction }} + ha:height = { valtype=coord; desc={radius (of the centerline of the arc) in Y direction }} + ha:thickness = { valtype=coord; desc={width of the pen the arc is drawn with }} + ha:clearance = { valtype=coord; desc={copper clearance around the object }} + ha:astart = { valtype=angle; desc={ start angle}} + ha:adelta = { valtype=angle; desc={ delta angle}} + sy:attr@dup = {/lht_tree_doc/comm/attributes} + sy:flags@dup = {/lht_tree_doc/comm/flags_arc} + sy:hvthr@dup = {/lht_tree_doc/comm/thermal_heavy} + } + } + ha:gfx.ID { + type=ha + ver={>=7} + desc={rectangular custom pixmap graphics} + li:children { + ha:sx = { valtype=coord; desc={visible size, X direction}} + ha:sy = { valtype=coord; desc={visible size, Y direction}} + ha:cx = { valtype=coord; desc={center, X coord}} + ha:cy = { valtype=coord; desc={center, Y coord}} + ha:rot = { valtype=angle; desc={rotation angle, CCW}} + ha:xmirror = { valtype=ingteger; desc={0 or 1, whether the pixmap should be mirrored (x coord mirror, which means mirror against the y axis}} + ha:ymirror = { valtype=ingteger; desc={0 or 1, whether the pixmap should be mirrored (y coord mirror, which means mirror against the x axis}} + ha:pixmap_ref = { valtype=ingteger; desc={ID of the pixmap to use from the pixmaps subtree; this pixmap represents the neutral state (no rotation, no mirror) pixmap of the object}} + sy:attr@dup = {/lht_tree_doc/comm/attributes} + sy:flags@dup = {/lht_tree_doc/comm/flags_arc} + sy:hvthr@dup = {/lht_tree_doc/comm/thermal_heavy} + } + } + ha:polygon.ID { + type=ha + desc={polygon, as drawn (unclipped)} + li:children { + ha:clearance = { valtype=coord; ver={>=3} desc={copper clearance around the object }} + ha:enforce_clearance = { valtype=coord; ver={>=7} desc={enforce minimum clearance on clearing objects within the polygon }} + sy:attr@dup = {/lht_tree_doc/comm/attributes} + sy:flags@dup = {/lht_tree_doc/comm/flags_polygon} + sy:hvthr@dup = {/lht_tree_doc/comm/thermal_heavy} + ha:geometry { + type=li + desc={first item is the outer contour, subsequent, optional items are holes} + li:children { + ha:contour = { valtype=coordtbl; desc={2 column table of x;y coords for the outer contour}} + ha:hole = { valtype=coordtbl; desc={2 column table of x;y coords for a hole}} + } + } + } + } + ha:text.ID { + type=ha + desc={single line text object} + li:children { + ha:x = { valtype=coord; desc={placement: X coord}} + ha:y = { valtype=coord; desc={placement: Y coord}} + ha:role = { valtype=string; desc={when part of an old element, determines which of the three hardwired text object role is used (footprint, refdes or value)}} + ha:string = { valtype=string; desc={text string (payload)}} + ha:fid = { valtype=integer; desc={font ID}} + ha:scale = { valtype=integer; desc={text size scale in %}} + ha:scale_x = { valtype=double; desc={text size scale in X direction (width), as a multiplier; if 0, use scale/100}} + ha:scale_y = { valtype=double; desc={text size scale in Y direction (height), as a multiplier; if 0, use scale/100}} + ha:direction = { valtype=integer; ver={<=5} desc={rotation in 90 degree steps (0 is horizontal); between -3 and +3, inclusive. Starting from v6, the rot field shall be used instead of direction}} + ha:rot = { valtype=angle; ver={>=6} desc={rotation angle in degrees, [0..360), CCW}} + ha:thickness = { valtype=coord; ver={>=6} desc={if zero, use the default width algorithm; if non-zero use this value as rotation angle in degrees}} + sy:attr@dup = {/lht_tree_doc/comm/attributes} + sy:flags@dup = {/lht_tree_doc/comm/flags_text} + } + } + } + } + } + } + } + } + ha:padstack_prototypes { + type=li + ver = {>=4} + li:children { + ha:unused = { valtype=none; desc={placeholder for marking unused slot to keep slot indices for early lihata v4 }} + ha:ps_proto_v4.PID { + type=ha + desc={padstack prototype specification, as introduced in lihata board v4} + li:children { + ha:hdia = { valtype=coord; desc={hole diameter; 0 means no hole }} + ha:htop = { valtype=integer; desc={hole start: copper layer index from the top (positive) or bottom (negative) copper layer (0 means top copper layer)}} + ha:hbottom = { valtype=integer; desc={hole start: copper layer index from the bottom (positive) or top (negative) copper layer (0 means bottom copper layer)}} + ha:hplated = { valtype=integer; desc={0=hole and/or slot is unplated; 1=hole and/or slot is plated}} + ha:name = { valtype=string; ver={>=5} desc={optional user assigned prototype name}} + ha:shape { + type=li + desc={shape per layer type definition} + li:children { + ha:ps_shape_v4 { + type=ha + desc={shape on a specific layer type (specified by layer_mask and combining), as specifie in lihata board v4; shape is either ps_poly, ps_line or ps_circ (only one of these will present per layer type); shape coords are relative to padstack origin; layer mask shall contain one material and at most one location bit} + li:children { + sy:layer_mask@dup = {/lht_tree_doc/comm/layer_mask} + ha:combining { + desc={layer compositing match} + sy:children = {/lht_tree_doc/comm/combining/children} + } + ha:clearance = { valtype=coord; desc={local, per-layer-type clearance; applied if global padstack clearance is 0 }} + ha:ps_poly { + type=li + desc={arbitrary convex polygon shape; contains a list of x;y coordinates } + } + ha:ps_line { + type=ha + desc={straight line shape, round or square cap} + li:children { + ha:x1 = { valtype=coord; desc={line first endpoint, horizontal offset }} + ha:y1 = { valtype=coord; desc={line first endpoint, vertical offset }} + ha:x2 = { valtype=coord; desc={line second endpoint, horizontal offset }} + ha:y2 = { valtype=coord; desc={line second endpoint, vertical offset }} + ha:thickness = { valtype=coord; desc={width of the line }} + ha:square = { valtype=integer; desc={0=round cap; 1=square cap }} + } + } + ha:ps_circ { + type=ha + desc={filled circle shape} + li:children { + ha:x = { valtype=coord; desc={center, horizontal offset }} + ha:y = { valtype=coord; desc={center, vertical offset }} + ha:dia = { valtype=coord; desc={circle diameter }} + } + } + ha:ps_hshadow { + type=te + desc={hole/slot shadow} + ver={>=6} + } + } + } + } + } + } + } + } + } + sy:subc.ID@dup {/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID} + ha:element.ID { + type=ha + desc={an instance (full copy) of an obsolete element footprint} + ver = {<3} + li:children { + ha:x = { valtype=coord; desc={element origin (diamond), horizontal offset }} + ha:y = { valtype=coord; desc={element origin (diamond), vertical offset }} + sy:attr@dup = {/lht_tree_doc/comm/attributes} + sy:flags@dup = {/lht_tree_doc/comm/flags_element} + ha:objects { + type=li + desc={list of special objects that make up the element; lines and arcs are always on a silk layer} + li:children { + sy:line.ID = {/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID} + sy:arc.ID = {/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID} + sy:text.ID = {/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID} + ha:pad.ID { + type=ha + desc={SMD pad emulated using a line object; becomes a rectangle (but watch out for the cap-extended length!) when the square flag is set} + li:children { + ha:x1 = { valtype=coord; desc={line first endpoint, horizontal offset }} + ha:y1 = { valtype=coord; desc={line first endpoint, vertical offset }} + ha:x2 = { valtype=coord; desc={line second endpoint, horizontal offset }} + ha:y2 = { valtype=coord; desc={line second endpoint, vertical offset }} + ha:thickness = { valtype=coord; desc={width of the line}} + ha:clearance = { valtype=coord; desc={clearance around the line}} + ha:mask = { valtype=coord; desc={size of the mask cutout, as interpreted by gEDA/PCB}} + ha:name = { valtype=string; desc={symbolic name of the pad}} + ha:number = { valtype=string; desc={"pin number" for the netlist}} + sy:attr@dup = {/lht_tree_doc/comm/attributes} + sy:flags@dup = {/lht_tree_doc/comm/flags_pad} + } + } + ha:pin.ID { + type=ha + desc={thru-hole pin; emulated as an old-style via } + sy:children = {/lht_tree_doc/comm/data/children/objects/children/via.ID} + } + } + } + } + } + ha:rat.ID { + type=ha + desc={global rat line} + li:children { + ha:x1 = { valtype=coord; desc={line first endpoint, horizontal offset }} + ha:y1 = { valtype=coord; desc={line first endpoint, vertical offset }} + ha:x2 = { valtype=coord; desc={line second endpoint, horizontal offset }} + ha:y2 = { valtype=coord; desc={line second endpoint, vertical offset }} + ha:lgrp1 = { valtype=integer; desc={first endpoint's layer group ID }} + ha:lgrp2 = { valtype=integer; desc={second endpoint's layer group ID }} + ha:anchor1 = { valtype=string; ver={>=7}; desc={first endpoint's objet anchor written as an absolute idpath }} + ha:anchor2 = { valtype=string; ver={>=7}; desc={second endpoint's objet anchor written as an absolute idpath }} + sy:attr@dup = {/lht_tree_doc/comm/attributes} + sy:flags@dup = {/lht_tree_doc/comm/flags_line} + } + } + } + } + +}} Index: tags/2.3.0/doc/developer/lihata_format/comm_flags.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/comm_flags.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/comm_flags.lht (revision 33253) @@ -0,0 +1,146 @@ +ha:lht_tree_doc { ha:comm { + ha:flags_arc { + hide=1 + name=flags + dot_group=1 + desc={flag bits of a arc} + type=ha + li:children { + ha:found { valtype=flag; desc={If set, this object has been found by FindConnection()}} + ha:clearline { valtype=flag; desc={For lines and arcs, the line/arc will clear polygons instead of connecting to them.}} + ha:selected { valtype=flag; desc={Set when the object is selected.}} + ha:auto { valtype=flag; desc={For lines and vias, indicates that these were created by the autorouter.}} + ha:rubberend { valtype=flag; desc={For lines, used internally for rubber band moves: indicates one end already rubber banding.}} + ha:drc { valtype=flag; desc={Set for objects that fail DRC: flag like FOUND flag for DRC checking.}} + ha:exportsel { valtype=flag; desc={Set for objects that should be exported in a partial export.}} + ha:lock { valtype=flag; desc={Set for locked objects.}} + ha:termname { valtype=flag; desc={when set the names of pins are shown.}} + ha:floater { valtype=flag; desc={subc part can be moved after subc placing}} + } + } + ha:flags_line { + hide=1 + name=flags + dot_group=1 + desc={flag bits of a line} + type=ha + li:children { + ha:found { valtype=flag; desc={If set, this object has been found by FindConnection()}} + ha:clearline { valtype=flag; desc={For lines and arcs, the line/arc will clear polygons instead of connecting to them.}} + ha:selected { valtype=flag; desc={Set when the object is selected.}} + ha:auto { valtype=flag; desc={For lines and vias, indicates that these were created by the autorouter.}} + ha:rubberend { valtype=flag; desc={For lines, used internally for rubber band moves: indicates one end already rubber banding.}} + ha:drc { valtype=flag; desc={Set for objects that fail DRC: flag like FOUND flag for DRC checking.}} + ha:exportsel { valtype=flag; desc={Set for objects that should be exported in a partial export.}} + ha:lock { valtype=flag; desc={Set for locked objects.}} + ha:termname { valtype=flag; desc={when set the names of pins are shown.}} + ha:floater { valtype=flag; desc={subc part can be moved after subc placing}} + } + } + ha:flags_polygon { + hide=1 + name=flags + dot_group=1 + desc={flag bits of a polygon} + type=ha + li:children { + ha:found { valtype=flag; desc={If set, this object has been found by FindConnection()}} + ha:clearpoly { valtype=flag; desc={For polygons, this flag means that pins and vias will normally clear these polygons (thus, thermals are required for electrical connection). When clear, polygons will solidly connect to pins and vias. }} + ha:fullpoly { valtype=flag; desc={For polygons, the full polygon is drawn (i.e. all parts instead of only the biggest one).}} + ha:selected { valtype=flag; desc={Set when the object is selected.}} + ha:drc { valtype=flag; desc={Set for objects that fail DRC: flag like FOUND flag for DRC checking.}} + ha:exportsel { valtype=flag; desc={Set for objects that should be exported in a partial export.}} + ha:lock { valtype=flag; desc={Set for locked objects.}} + ha:termname { valtype=flag; desc={when set the names of pins are shown.}} + ha:clearpolypoly { valtype=flag; desc={For polygons, apply clearance to nearby polygons}} + ha:floater { valtype=flag; desc={subc part can be moved after subc placing}} + } + } + ha:flags_text { + hide=1 + name=flags + dot_group=1 + desc={flag bits of a text} + type=ha + li:children { + ha:found { valtype=flag; desc={If set, this object has been found by FindConnection()}} + ha:clearline { valtype=flag; desc={For lines and arcs, the line/arc will clear polygons instead of connecting to them.}} + ha:selected { valtype=flag; desc={Set when the object is selected.}} + ha:onsolder { valtype=flag; desc={For text, indicates that it is on the solder side.}} + ha:drc { valtype=flag; desc={Set for objects that fail DRC: flag like FOUND flag for DRC checking.}} + ha:exportsel { valtype=flag; desc={Set for objects that should be exported in a partial export.}} + ha:lock { valtype=flag; desc={Set for locked objects.}} + ha:termname { valtype=flag; desc={when set the names of pins are shown.}} + ha:dyntext { valtype=flag; desc={For text: dynamic string (substitute %patterns%)}} + ha:floater { valtype=flag; desc={subc part can be moved after subc placing}} + } + } + ha:flags_subcircuit { + hide=1 + name=flags + dot_group=1 + desc={flag bits of a subcircuit} + type=ha + li:children { + ha:found { valtype=flag; desc={If set, this object has been found by FindConnection()}} + ha:selected { valtype=flag; desc={Set when the object is selected.}} + ha:drc { valtype=flag; desc={Set for objects that fail DRC: flag like FOUND flag for DRC checking.}} + ha:exportsel { valtype=flag; desc={Set for objects that should be exported in a partial export.}} + ha:lock { valtype=flag; desc={Set for locked objects.}} + ha:nonetlist { valtype=flag; desc={subcircuit is not on the netlist and should not interfere with the netlist }} + ha:termname { valtype=flag; desc={when set the names of pins are shown.}} + ha:floater { valtype=flag; desc={subc part can be moved after subc placing}} + } + } + ha:flags_padstack { + hide=1 + name=flags + dot_group=1 + desc={flag bits of a padstack} + type=ha + li:children { + ha:found { valtype=flag; desc={If set, this object has been found by FindConnection()}} + ha:hole { valtype=flag; desc={For pins and vias, this flag means that the pin or via is a hole without a copper annulus.}} + ha:clearline { valtype=flag; desc={For lines and arcs, the line/arc will clear polygons instead of connecting to them.}} + ha:selected { valtype=flag; desc={Set when the object is selected.}} + ha:auto { valtype=flag; desc={For lines and vias, indicates that these were created by the autorouter.}} + ha:warn { valtype=flag; desc={For pins, vias, and pads, set to indicate a warning.}} + ha:drc { valtype=flag; desc={Set for objects that fail DRC: flag like FOUND flag for DRC checking.}} + ha:exportsel { valtype=flag; desc={Set for objects that should be exported in a partial export.}} + ha:lock { valtype=flag; desc={Set for locked objects.}} + ha:termname { valtype=flag; desc={when set the names of pins are shown.}} + ha:floater { valtype=flag; desc={subc part can be moved after subc placing}} + } + } + ha:flags_ratline { + hide=1 + name=flags + dot_group=1 + desc={flag bits of a ratline} + type=ha + li:children { + ha:found { valtype=flag; desc={If set, this object has been found by FindConnection()}} + ha:rat { valtype=flag; desc={If set for a line, indicates that this line is a rat line instead of a copper trace.}} + ha:selected { valtype=flag; desc={Set when the object is selected.}} + ha:drc { valtype=flag; desc={Set for objects that fail DRC: flag like FOUND flag for DRC checking.}} + ha:exportsel { valtype=flag; desc={Set for objects that should be exported in a partial export.}} + ha:lock { valtype=flag; desc={Set for locked objects.}} + ha:floater { valtype=flag; desc={subc part can be moved after subc placing}} + } + } + ha:flags_gfx { + hide=1 + name=flags + dot_group=1 + desc={flag bits of a gfx} + type=ha + li:children { + ha:found { valtype=flag; desc={If set, this object has been found by FindConnection()}} + ha:selected { valtype=flag; desc={Set when the object is selected.}} + ha:drc { valtype=flag; desc={Set for objects that fail DRC: flag like FOUND flag for DRC checking.}} + ha:exportsel { valtype=flag; desc={Set for objects that should be exported in a partial export.}} + ha:lock { valtype=flag; desc={Set for locked objects.}} + ha:floater { valtype=flag; desc={subc part can be moved after subc placing}} + } + } +} } Index: tags/2.3.0/doc/developer/lihata_format/comm_flags_old.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/comm_flags_old.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/comm_flags_old.lht (revision 33253) @@ -0,0 +1,69 @@ +ha:lht_tree_doc { ha:comm { + +# these obsolete flags are only relevant in compatibility mode; +# they are not generated by the flag dump but they will not change +# thus this file is hand-written + + ha:flags_element { + hide=1 + desc={flag bits of an element} + type=ha + dot_group=1 + li:children { + ha:found { valtype=flag; desc={If set, this object has been found by FindConnection()}} + ha:selected { valtype=flag; desc={Set when the object is selected.}} + ha:auto { valtype=flag; desc={For lines and vias, indicates that these were created by the autorouter.}} + ha:drc { valtype=flag; desc={Set for objects that fail DRC: flag like FOUND flag for DRC checking.}} + ha:lock { valtype=flag; desc={Set for locked objects.}} + ha:nonetlist { valtype=flag; desc={subcircuit is not on the netlist and should not interfere with the netlist }} + ha:termname { valtype=flag; desc={when set the names of pins are shown.}} + ha:floater { valtype=flag; desc={subc part can be moved after subc placing}} + ha:onsolder { valtype=flag; desc={element is placed on the solder side}} + } + } + ha:flags_pinvia { + hide=1 + desc={flag bits of a pin or via} + type=ha + dot_group=1 + li:children { + ha:found { valtype=flag; desc={If set, this object has been found by FindConnection()}} + ha:hole { valtype=flag; desc={For pins and vias, this flag means that the pin or via is a hole without a copper annulus.}} + ha:clearline { valtype=flag; desc={For lines and arcs, the line/arc will clear polygons instead of connecting to them.}} + ha:selected { valtype=flag; desc={Set when the object is selected.}} + ha:auto { valtype=flag; desc={For lines and vias, indicates that these were created by the autorouter.}} + ha:warn { valtype=flag; desc={For pins, vias, and pads, set to indicate a warning.}} + ha:usetherm { valtype=flag; desc={Obsolete, indicates that pins/vias should be drawn with thermal fingers.}} + ha:drc { valtype=flag; desc={Set for objects that fail DRC: flag like FOUND flag for DRC checking.}} + ha:lock { valtype=flag; desc={Set for locked objects.}} + ha:nonetlist { valtype=flag; desc={subcircuit is not on the netlist and should not interfere with the netlist }} + ha:termname { valtype=flag; desc={when set the names of pins are shown.}} + ha:floater { valtype=flag; desc={subc part can be moved after subc placing}} + ha:pin { valtype=flag; desc={object is a pin (in an element)}} + ha:via { valtype=flag; desc={object is a via}} + } + } + + ha:flags_pad { + hide=1 + desc={flag bits of a pad} + type=ha + dot_group=1 + li:children { + ha:found { valtype=flag; desc={If set, this object has been found by FindConnection()}} + ha:hole { valtype=flag; desc={For pins and vias, this flag means that the pin or via is a hole without a copper annulus.}} + ha:clearline { valtype=flag; desc={For lines and arcs, the line/arc will clear polygons instead of connecting to them.}} + ha:selected { valtype=flag; desc={Set when the object is selected.}} + ha:auto { valtype=flag; desc={For lines and vias, indicates that these were created by the autorouter.}} + ha:warn { valtype=flag; desc={For pins, vias, and pads, set to indicate a warning.}} + ha:usetherm { valtype=flag; desc={Obsolete, indicates that pins/vias should be drawn with thermal fingers.}} + ha:drc { valtype=flag; desc={Set for objects that fail DRC: flag like FOUND flag for DRC checking.}} + ha:lock { valtype=flag; desc={Set for locked objects.}} + ha:nonetlist { valtype=flag; desc={subcircuit is not on the netlist and should not interfere with the netlist }} + ha:termname { valtype=flag; desc={when set the names of pins are shown.}} + ha:floater { valtype=flag; desc={subc part can be moved after subc placing}} + ha:pin { valtype=flag; desc={object is a pin (in an element)}} + ha:via { valtype=flag; desc={object is a via}} + } + } +} } Index: tags/2.3.0/doc/developer/lihata_format/comm_lyt.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/comm_lyt.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/comm_lyt.lht (revision 33253) @@ -0,0 +1,43 @@ +ha:lht_tree_doc { ha:comm { + + ha:layer_mask { + hide=1 + type=ha + desc={layer type and location} + dot_group=1 + li:children { + ha:top { valtype=flag; desc={location: top side}} + ha:bottom { valtype=flag; desc={location: bottom side}} + ha:intern { valtype=flag; desc={location: internal}} + ha:logical { valtype=flag; desc={location: logical (not in the actual stackup)}} + ha:copper { valtype=flag; desc={material: copper}} + ha:silk { valtype=flag; desc={material: silk}} + ha:mask { valtype=flag; desc={material: mask}} + ha:paste { valtype=flag; desc={material: paste}} + ha:outline { valtype=flag; desc={"material": router path for board outline; normally for the outer contour, sometimes for biggish inner cutouts as well) }} + ha:mech { valtype=flag; desc={"material": various mechanical fabbing instructions, e.g. slots; the purpose field provides more detail about the use }} + ha:doc { valtype=flag; desc={"material": documentation, either for the user and for pcb-rnd or both (the purpose field shoudl tell); e.g. assembly documentation for the user, keepout for the user and DRC }} + ha:substrate { valtype=flag; desc={material: substrate or insulator}} + +# ha:rat { valtype=flag; desc={(virtual: rat lines)}} +# ha:invis { valtype=flag; desc={(virtual: invisible)}} +# ha:assy { valtype=flag; desc={(virtual: assembly drawing)}} +# ha:fab { valtype=flag; desc={(virtual: fab drawing)}} +# ha:plateddrill { valtype=flag; desc={(drills: plated)}} +# ha:unplateddrill { valtype=flag; desc={(drills: unplated)}} +# ha:cross-section { valtype=flag; desc={(virtual: cross section drawing)}} +# ha:misc { valtype=flag; desc={(virtual: virtual misc layer)}} +# ha:virtual { valtype=flag; desc={(if set, the layer is not a physical layer but a drawing or documentation)}} + } + } + + ha:combining { + hide=1 + dot_group=1 + li:children { + ha:sub { valtype=flag; desc={draw in negative}} + ha:auto { valtype=flag; desc={padstacks draw their paste, mask and silk objects on the first layer (of matching type) that features the auto flag}} + } + } + +}} Index: tags/2.3.0/doc/developer/lihata_format/comm_pixmaps.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/comm_pixmaps.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/comm_pixmaps.lht (revision 33253) @@ -0,0 +1,20 @@ +ha:lht_tree_doc { ha:comm { + + ha:pixmaps { + type=ha + ver={>=7} + desc { Collection of all unique pixmaps used by the board or footprint } + li:children { + ha:ulzw.ID { + type=ha + desc { pixmap with payload ulzw-compressed } + li:children { + ha:sx = { valtype=integer; desc={size in X direction (width), in pixels }} + ha:sy = { valtype=integer; desc={size in Y direction (height), in pixels }} + ha:transparent = { valtype=string; desc={color of the transparent pixel in #rrggbb form; omit node if there is no transparent pixel in the pixmap }} + ha:pixmap = { valtype=string; desc={ base64 encoded version of the ulzw compressed raw pixmap, whih is in 24 bit RGB format, stored row-major }} + } + } + } + } +}} Index: tags/2.3.0/doc/developer/lihata_format/comm_thermal.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/comm_thermal.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/comm_thermal.lht (revision 33253) @@ -0,0 +1,17 @@ +ha:lht_tree_doc { ha:comm { + + ha:thermal_heavy { + name=thermal + type=li + hide=1 + desc { list of thermal flags for heavy terminals, on the single layer the object is on } + li:children { + ha:on { valtype=none; desc={draw any thermal only if this string is present; else normal clearance is applied}} + ha:diag { valtype=none; desc={if present, the thermal is diagonal (45 degree rotated)}} + ha:round { valtype=none; desc={if present, thermal shape is rounded}} + ha:sharp { valtype=none; desc={if present, thermal shape is sharp}} + ha:solid { valtype=none; desc={if present, there is no thermal but a solid connection ("join")}} + } + } + +}} Index: tags/2.3.0/doc/developer/lihata_format/coraleda-project-v1.svg =================================================================== --- tags/2.3.0/doc/developer/lihata_format/coraleda-project-v1.svg (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/coraleda-project-v1.svg (revision 33253) @@ -0,0 +1,303 @@ + + + + + + +ha:coraleda-project-v1 + + + +/lht_tree_doc/roots/coraleda-project-v1 + + +ha:coraleda-project-v1 + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common + + +ha:common + + + + + +/lht_tree_doc/roots/coraleda-project-v1->/lht_tree_doc/roots/coraleda-project-v1/children/common + + + + + +dup24_/lht_tree_doc/roots/coraleda-project-v1/children/pcb-rnd-conf-v1 + +pcb-rnd-conf-v1 -> + + + + + +/lht_tree_doc/roots/coraleda-project-v1->dup24_/lht_tree_doc/roots/coraleda-project-v1/children/pcb-rnd-conf-v1 + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/name + + +name +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/name + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/desc + + +desc +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/desc + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/url + + +url +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/url + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/vcs + + +vcs +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/vcs + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/contact + + +contact +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/contact + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files + + +li:files + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs + + +li:libs + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files/children/NAME + + +ha:NAME + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files/children/NAME + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files/children/NAME/children/path + + +path +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files/children/NAME->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files/children/NAME/children/path + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files/children/NAME/children/desc + + +desc +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files/children/NAME->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files/children/NAME/children/desc + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files/children/NAME/children/type + + +type +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files/children/NAME->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/files/children/NAME/children/type + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME + + +ha:NAME + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME/children/path + + +path +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME/children/path + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME/children/url + + +url +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME/children/url + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME/children/desc + + +desc +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME/children/desc + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME/children/type + + +type +string + + + + + +/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME->/lht_tree_doc/roots/coraleda-project-v1/children/common/children/libs/children/NAME/children/type + + + + + Index: tags/2.3.0/doc/developer/lihata_format/data.svg =================================================================== --- tags/2.3.0/doc/developer/lihata_format/data.svg (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/data.svg (revision 33253) @@ -0,0 +1,5940 @@ + + + + + + +ha:data + + + +/lht_tree_doc/comm/data + + +ha:data + + + + + +/lht_tree_doc/comm/data/children/objects + + +li:objects + + + + + +/lht_tree_doc/comm/data->/lht_tree_doc/comm/data/children/objects + + + + + +/lht_tree_doc/comm/data/children/layers + + +li:layers + + + + + +/lht_tree_doc/comm/data->/lht_tree_doc/comm/data/children/layers + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes + + +li:padstack_prototypes +>=4 + + + + + +/lht_tree_doc/comm/data->/lht_tree_doc/comm/data/children/padstack_prototypes + + + + + +dup52_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID + + +ha:subc.ID +>=3 + + + + + +/lht_tree_doc/comm/data->dup52_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID + + + + + +/lht_tree_doc/comm/data/children/element.ID + + +ha:element.ID +<3 + + + + + +/lht_tree_doc/comm/data->/lht_tree_doc/comm/data/children/element.ID + + + + + +/lht_tree_doc/comm/data/children/rat.ID + + +ha:rat.ID + + + + + +/lht_tree_doc/comm/data->/lht_tree_doc/comm/data/children/rat.ID + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID + + +ha:padstack_ref.ID +>=4 + + + + + +/lht_tree_doc/comm/data/children/objects->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID + + +ha:via.ID +<=4 + + + + + +/lht_tree_doc/comm/data/children/objects->/lht_tree_doc/comm/data/children/objects/children/via.ID + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/proto + + +proto +integer + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/proto + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/x + + +x +coord + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/x + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/y + + +y +coord + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/y + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/clearance + + +clearance +coord + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/clearance + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/rot + + +rot +angle + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/rot + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/xmirror + + +xmirror +integer + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/xmirror + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/smirror + + +smirror +integer + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/smirror + + + + + +dup29_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID->dup29_/lht_tree_doc/comm/attributes + + + + + +dup30_/lht_tree_doc/comm/flags_padstack + + +ha:flags + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID->dup30_/lht_tree_doc/comm/flags_padstack + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal + + +li:thermal + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal + + + + + +dup29_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup29_/lht_tree_doc/comm/attributes->dup29_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup30_/lht_tree_doc/comm/flags_padstack/children/found + + +found +flag + + + + + +dup30_/lht_tree_doc/comm/flags_padstack->dup30_/lht_tree_doc/comm/flags_padstack/children/found + + + + + +dup30_/lht_tree_doc/comm/flags_padstack/children/hole + + +hole +flag + + + + + +dup30_/lht_tree_doc/comm/flags_padstack->dup30_/lht_tree_doc/comm/flags_padstack/children/hole + + + + + +dup30_/lht_tree_doc/comm/flags_padstack/children/clearline + + +clearline +flag + + + + + +dup30_/lht_tree_doc/comm/flags_padstack->dup30_/lht_tree_doc/comm/flags_padstack/children/clearline + + + + + +dup30_/lht_tree_doc/comm/flags_padstack/children/selected + + +selected +flag + + + + + +dup30_/lht_tree_doc/comm/flags_padstack->dup30_/lht_tree_doc/comm/flags_padstack/children/selected + + + + + +dup30_/lht_tree_doc/comm/flags_padstack/children/auto + + +auto +flag + + + + + +dup30_/lht_tree_doc/comm/flags_padstack->dup30_/lht_tree_doc/comm/flags_padstack/children/auto + + + + + +dup30_/lht_tree_doc/comm/flags_padstack/children/warn + + +warn +flag + + + + + +dup30_/lht_tree_doc/comm/flags_padstack->dup30_/lht_tree_doc/comm/flags_padstack/children/warn + + + + + +dup30_/lht_tree_doc/comm/flags_padstack/children/drc + + +drc +flag + + + + + +dup30_/lht_tree_doc/comm/flags_padstack->dup30_/lht_tree_doc/comm/flags_padstack/children/drc + + + + + +dup30_/lht_tree_doc/comm/flags_padstack/children/exportsel + + +exportsel +flag + + + + + +dup30_/lht_tree_doc/comm/flags_padstack->dup30_/lht_tree_doc/comm/flags_padstack/children/exportsel + + + + + +dup30_/lht_tree_doc/comm/flags_padstack/children/lock + + +lock +flag + + + + + +dup30_/lht_tree_doc/comm/flags_padstack->dup30_/lht_tree_doc/comm/flags_padstack/children/lock + + + + + +dup30_/lht_tree_doc/comm/flags_padstack/children/termname + + +termname +flag + + + + + +dup30_/lht_tree_doc/comm/flags_padstack->dup30_/lht_tree_doc/comm/flags_padstack/children/termname + + + + + +dup30_/lht_tree_doc/comm/flags_padstack/children/floater + + +floater +flag + + + + + +dup30_/lht_tree_doc/comm/flags_padstack->dup30_/lht_tree_doc/comm/flags_padstack/children/floater + + + + + + + + + + + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID + + +li:LAYERID + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/on + + +on +none + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/on + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/diag + + +diag +none + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/diag + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/round + + +round +none + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/round + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/sharp + + +sharp +none + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/sharp + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/solid + + +solid +none + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/solid + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/noshape + + +noshape +none +>=6 + + + + + +/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID->/lht_tree_doc/comm/data/children/objects/children/padstack_ref.ID/children/thermal/children/LAYERID/children/noshape + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID/children/x + + +x +coord + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID->/lht_tree_doc/comm/data/children/objects/children/via.ID/children/x + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID/children/y + + +y +coord + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID->/lht_tree_doc/comm/data/children/objects/children/via.ID/children/y + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID/children/thickness + + +thickness +coord + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID->/lht_tree_doc/comm/data/children/objects/children/via.ID/children/thickness + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID/children/clearance + + +clearance +coord + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID->/lht_tree_doc/comm/data/children/objects/children/via.ID/children/clearance + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID/children/mask + + +mask +coord + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID->/lht_tree_doc/comm/data/children/objects/children/via.ID/children/mask + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID/children/hole + + +hole +coord + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID->/lht_tree_doc/comm/data/children/objects/children/via.ID/children/hole + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID/children/name + + +name +string + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID->/lht_tree_doc/comm/data/children/objects/children/via.ID/children/name + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID/children/number + + +number +string + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID->/lht_tree_doc/comm/data/children/objects/children/via.ID/children/number + + + + + +dup31_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID->dup31_/lht_tree_doc/comm/attributes + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia + + +ha:flags_pinvia + + + + + +/lht_tree_doc/comm/data/children/objects/children/via.ID->dup32_/lht_tree_doc/comm/flags_pinvia + + + + + +dup31_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup31_/lht_tree_doc/comm/attributes->dup31_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/found + + +found +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/found + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/hole + + +hole +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/hole + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/clearline + + +clearline +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/clearline + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/selected + + +selected +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/selected + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/auto + + +auto +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/auto + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/warn + + +warn +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/warn + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/usetherm + + +usetherm +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/usetherm + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/drc + + +drc +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/drc + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/lock + + +lock +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/lock + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/nonetlist + + +nonetlist +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/nonetlist + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/termname + + +termname +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/termname + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/floater + + +floater +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/floater + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/pin + + +pin +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/pin + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia/children/via + + +via +flag + + + + + +dup32_/lht_tree_doc/comm/flags_pinvia->dup32_/lht_tree_doc/comm/flags_pinvia/children/via + + + + + + + + + + + + + + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME + + +ha:NAME + + + + + +/lht_tree_doc/comm/data/children/layers->/lht_tree_doc/comm/data/children/layers/children/NAME + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/lid + + +lid +integer +>=2 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME->/lht_tree_doc/comm/data/children/layers/children/NAME/children/lid + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/visible + + +visible +integer +<6 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME->/lht_tree_doc/comm/data/children/layers/children/NAME/children/visible + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/group + + +group +integer + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME->/lht_tree_doc/comm/data/children/layers/children/NAME/children/group + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/color + + +color +string +>=5 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME->/lht_tree_doc/comm/data/children/layers/children/NAME/children/color + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/stack_offs + + +stack_offs +integer + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME->/lht_tree_doc/comm/data/children/layers/children/NAME/children/stack_offs + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type + + +ha:type + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME->/lht_tree_doc/comm/data/children/layers/children/NAME/children/type + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/purpose + + +purpose +integer +>=6 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME->/lht_tree_doc/comm/data/children/layers/children/NAME/children/purpose + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/combining + + +combining +>=2 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME->/lht_tree_doc/comm/data/children/layers/children/NAME/children/combining + + + + + +dup35_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME->dup35_/lht_tree_doc/comm/attributes + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects + + +li:objects + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/top + + +top +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/top + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/bottom + + +bottom +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/bottom + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/intern + + +intern +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/intern + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/logical + + +logical +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/logical + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/copper + + +copper +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/copper + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/silk + + +silk +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/silk + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/mask + + +mask +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/mask + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/paste + + +paste +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/paste + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/outline + + +outline +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/outline + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/mech + + +mech +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/mech + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/doc + + +doc +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/doc + + + + + +dup33_/lht_tree_doc/comm/layer_mask/children/substrate + + +substrate +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/type->dup33_/lht_tree_doc/comm/layer_mask/children/substrate + + + + + + + + + + + + + + + + +dup34_/lht_tree_doc/comm/combining/children/sub + + +sub +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/combining->dup34_/lht_tree_doc/comm/combining/children/sub + + + + + +dup34_/lht_tree_doc/comm/combining/children/auto + + +auto +flag + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/combining->dup34_/lht_tree_doc/comm/combining/children/auto + + + + + + +dup35_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup35_/lht_tree_doc/comm/attributes->dup35_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID + + +ha:line.ID + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID + + +ha:arc.ID + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID + + +ha:gfx.ID +>=7 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID + + +ha:polygon.ID + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID + + +ha:text.ID + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/x1 + + +x1 +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/x1 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/y1 + + +y1 +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/y1 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/x2 + + +x2 +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/x2 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/y2 + + +y2 +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/y2 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/thickness + + +thickness +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/thickness + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/clearance + + +clearance +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID/children/clearance + + + + + +dup36_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID->dup36_/lht_tree_doc/comm/attributes + + + + + +dup37_/lht_tree_doc/comm/flags_line + + +ha:flags + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID->dup37_/lht_tree_doc/comm/flags_line + + + + + +dup38_/lht_tree_doc/comm/thermal_heavy + + +li:thermal + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/line.ID->dup38_/lht_tree_doc/comm/thermal_heavy + + + + + +dup36_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup36_/lht_tree_doc/comm/attributes->dup36_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup37_/lht_tree_doc/comm/flags_line/children/found + + +found +flag + + + + + +dup37_/lht_tree_doc/comm/flags_line->dup37_/lht_tree_doc/comm/flags_line/children/found + + + + + +dup37_/lht_tree_doc/comm/flags_line/children/clearline + + +clearline +flag + + + + + +dup37_/lht_tree_doc/comm/flags_line->dup37_/lht_tree_doc/comm/flags_line/children/clearline + + + + + +dup37_/lht_tree_doc/comm/flags_line/children/selected + + +selected +flag + + + + + +dup37_/lht_tree_doc/comm/flags_line->dup37_/lht_tree_doc/comm/flags_line/children/selected + + + + + +dup37_/lht_tree_doc/comm/flags_line/children/auto + + +auto +flag + + + + + +dup37_/lht_tree_doc/comm/flags_line->dup37_/lht_tree_doc/comm/flags_line/children/auto + + + + + +dup37_/lht_tree_doc/comm/flags_line/children/rubberend + + +rubberend +flag + + + + + +dup37_/lht_tree_doc/comm/flags_line->dup37_/lht_tree_doc/comm/flags_line/children/rubberend + + + + + +dup37_/lht_tree_doc/comm/flags_line/children/drc + + +drc +flag + + + + + +dup37_/lht_tree_doc/comm/flags_line->dup37_/lht_tree_doc/comm/flags_line/children/drc + + + + + +dup37_/lht_tree_doc/comm/flags_line/children/exportsel + + +exportsel +flag + + + + + +dup37_/lht_tree_doc/comm/flags_line->dup37_/lht_tree_doc/comm/flags_line/children/exportsel + + + + + +dup37_/lht_tree_doc/comm/flags_line/children/lock + + +lock +flag + + + + + +dup37_/lht_tree_doc/comm/flags_line->dup37_/lht_tree_doc/comm/flags_line/children/lock + + + + + +dup37_/lht_tree_doc/comm/flags_line/children/termname + + +termname +flag + + + + + +dup37_/lht_tree_doc/comm/flags_line->dup37_/lht_tree_doc/comm/flags_line/children/termname + + + + + +dup37_/lht_tree_doc/comm/flags_line/children/floater + + +floater +flag + + + + + +dup37_/lht_tree_doc/comm/flags_line->dup37_/lht_tree_doc/comm/flags_line/children/floater + + + + + + + + + + + + + + +dup38_/lht_tree_doc/comm/thermal_heavy/children/on + + +on +none + + + + + +dup38_/lht_tree_doc/comm/thermal_heavy->dup38_/lht_tree_doc/comm/thermal_heavy/children/on + + + + + +dup38_/lht_tree_doc/comm/thermal_heavy/children/diag + + +diag +none + + + + + +dup38_/lht_tree_doc/comm/thermal_heavy->dup38_/lht_tree_doc/comm/thermal_heavy/children/diag + + + + + +dup38_/lht_tree_doc/comm/thermal_heavy/children/round + + +round +none + + + + + +dup38_/lht_tree_doc/comm/thermal_heavy->dup38_/lht_tree_doc/comm/thermal_heavy/children/round + + + + + +dup38_/lht_tree_doc/comm/thermal_heavy/children/sharp + + +sharp +none + + + + + +dup38_/lht_tree_doc/comm/thermal_heavy->dup38_/lht_tree_doc/comm/thermal_heavy/children/sharp + + + + + +dup38_/lht_tree_doc/comm/thermal_heavy/children/solid + + +solid +none + + + + + +dup38_/lht_tree_doc/comm/thermal_heavy->dup38_/lht_tree_doc/comm/thermal_heavy/children/solid + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/x + + +x +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/x + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/y + + +y +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/y + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/width + + +width +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/width + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/height + + +height +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/height + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/thickness + + +thickness +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/thickness + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/clearance + + +clearance +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/clearance + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/astart + + +astart +angle + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/astart + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/adelta + + +adelta +angle + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID/children/adelta + + + + + +dup39_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID->dup39_/lht_tree_doc/comm/attributes + + + + + +dup40_/lht_tree_doc/comm/flags_arc + + +ha:flags + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID->dup40_/lht_tree_doc/comm/flags_arc + + + + + +dup41_/lht_tree_doc/comm/thermal_heavy + + +li:thermal + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/arc.ID->dup41_/lht_tree_doc/comm/thermal_heavy + + + + + +dup39_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup39_/lht_tree_doc/comm/attributes->dup39_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup40_/lht_tree_doc/comm/flags_arc/children/found + + +found +flag + + + + + +dup40_/lht_tree_doc/comm/flags_arc->dup40_/lht_tree_doc/comm/flags_arc/children/found + + + + + +dup40_/lht_tree_doc/comm/flags_arc/children/clearline + + +clearline +flag + + + + + +dup40_/lht_tree_doc/comm/flags_arc->dup40_/lht_tree_doc/comm/flags_arc/children/clearline + + + + + +dup40_/lht_tree_doc/comm/flags_arc/children/selected + + +selected +flag + + + + + +dup40_/lht_tree_doc/comm/flags_arc->dup40_/lht_tree_doc/comm/flags_arc/children/selected + + + + + +dup40_/lht_tree_doc/comm/flags_arc/children/auto + + +auto +flag + + + + + +dup40_/lht_tree_doc/comm/flags_arc->dup40_/lht_tree_doc/comm/flags_arc/children/auto + + + + + +dup40_/lht_tree_doc/comm/flags_arc/children/rubberend + + +rubberend +flag + + + + + +dup40_/lht_tree_doc/comm/flags_arc->dup40_/lht_tree_doc/comm/flags_arc/children/rubberend + + + + + +dup40_/lht_tree_doc/comm/flags_arc/children/drc + + +drc +flag + + + + + +dup40_/lht_tree_doc/comm/flags_arc->dup40_/lht_tree_doc/comm/flags_arc/children/drc + + + + + +dup40_/lht_tree_doc/comm/flags_arc/children/exportsel + + +exportsel +flag + + + + + +dup40_/lht_tree_doc/comm/flags_arc->dup40_/lht_tree_doc/comm/flags_arc/children/exportsel + + + + + +dup40_/lht_tree_doc/comm/flags_arc/children/lock + + +lock +flag + + + + + +dup40_/lht_tree_doc/comm/flags_arc->dup40_/lht_tree_doc/comm/flags_arc/children/lock + + + + + +dup40_/lht_tree_doc/comm/flags_arc/children/termname + + +termname +flag + + + + + +dup40_/lht_tree_doc/comm/flags_arc->dup40_/lht_tree_doc/comm/flags_arc/children/termname + + + + + +dup40_/lht_tree_doc/comm/flags_arc/children/floater + + +floater +flag + + + + + +dup40_/lht_tree_doc/comm/flags_arc->dup40_/lht_tree_doc/comm/flags_arc/children/floater + + + + + + + + + + + + + + +dup41_/lht_tree_doc/comm/thermal_heavy/children/on + + +on +none + + + + + +dup41_/lht_tree_doc/comm/thermal_heavy->dup41_/lht_tree_doc/comm/thermal_heavy/children/on + + + + + +dup41_/lht_tree_doc/comm/thermal_heavy/children/diag + + +diag +none + + + + + +dup41_/lht_tree_doc/comm/thermal_heavy->dup41_/lht_tree_doc/comm/thermal_heavy/children/diag + + + + + +dup41_/lht_tree_doc/comm/thermal_heavy/children/round + + +round +none + + + + + +dup41_/lht_tree_doc/comm/thermal_heavy->dup41_/lht_tree_doc/comm/thermal_heavy/children/round + + + + + +dup41_/lht_tree_doc/comm/thermal_heavy/children/sharp + + +sharp +none + + + + + +dup41_/lht_tree_doc/comm/thermal_heavy->dup41_/lht_tree_doc/comm/thermal_heavy/children/sharp + + + + + +dup41_/lht_tree_doc/comm/thermal_heavy/children/solid + + +solid +none + + + + + +dup41_/lht_tree_doc/comm/thermal_heavy->dup41_/lht_tree_doc/comm/thermal_heavy/children/solid + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/sx + + +sx +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/sx + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/sy + + +sy +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/sy + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/cx + + +cx +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/cx + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/cy + + +cy +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/cy + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/rot + + +rot +angle + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/rot + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/xmirror + + +xmirror +ingteger + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/xmirror + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/ymirror + + +ymirror +ingteger + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/ymirror + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/pixmap_ref + + +pixmap_ref +ingteger + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID/children/pixmap_ref + + + + + +dup42_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID->dup42_/lht_tree_doc/comm/attributes + + + + + +dup43_/lht_tree_doc/comm/flags_arc + + +ha:flags + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID->dup43_/lht_tree_doc/comm/flags_arc + + + + + +dup44_/lht_tree_doc/comm/thermal_heavy + + +li:thermal + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/gfx.ID->dup44_/lht_tree_doc/comm/thermal_heavy + + + + + +dup42_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup42_/lht_tree_doc/comm/attributes->dup42_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup43_/lht_tree_doc/comm/flags_arc/children/found + + +found +flag + + + + + +dup43_/lht_tree_doc/comm/flags_arc->dup43_/lht_tree_doc/comm/flags_arc/children/found + + + + + +dup43_/lht_tree_doc/comm/flags_arc/children/clearline + + +clearline +flag + + + + + +dup43_/lht_tree_doc/comm/flags_arc->dup43_/lht_tree_doc/comm/flags_arc/children/clearline + + + + + +dup43_/lht_tree_doc/comm/flags_arc/children/selected + + +selected +flag + + + + + +dup43_/lht_tree_doc/comm/flags_arc->dup43_/lht_tree_doc/comm/flags_arc/children/selected + + + + + +dup43_/lht_tree_doc/comm/flags_arc/children/auto + + +auto +flag + + + + + +dup43_/lht_tree_doc/comm/flags_arc->dup43_/lht_tree_doc/comm/flags_arc/children/auto + + + + + +dup43_/lht_tree_doc/comm/flags_arc/children/rubberend + + +rubberend +flag + + + + + +dup43_/lht_tree_doc/comm/flags_arc->dup43_/lht_tree_doc/comm/flags_arc/children/rubberend + + + + + +dup43_/lht_tree_doc/comm/flags_arc/children/drc + + +drc +flag + + + + + +dup43_/lht_tree_doc/comm/flags_arc->dup43_/lht_tree_doc/comm/flags_arc/children/drc + + + + + +dup43_/lht_tree_doc/comm/flags_arc/children/exportsel + + +exportsel +flag + + + + + +dup43_/lht_tree_doc/comm/flags_arc->dup43_/lht_tree_doc/comm/flags_arc/children/exportsel + + + + + +dup43_/lht_tree_doc/comm/flags_arc/children/lock + + +lock +flag + + + + + +dup43_/lht_tree_doc/comm/flags_arc->dup43_/lht_tree_doc/comm/flags_arc/children/lock + + + + + +dup43_/lht_tree_doc/comm/flags_arc/children/termname + + +termname +flag + + + + + +dup43_/lht_tree_doc/comm/flags_arc->dup43_/lht_tree_doc/comm/flags_arc/children/termname + + + + + +dup43_/lht_tree_doc/comm/flags_arc/children/floater + + +floater +flag + + + + + +dup43_/lht_tree_doc/comm/flags_arc->dup43_/lht_tree_doc/comm/flags_arc/children/floater + + + + + + + + + + + + + + +dup44_/lht_tree_doc/comm/thermal_heavy/children/on + + +on +none + + + + + +dup44_/lht_tree_doc/comm/thermal_heavy->dup44_/lht_tree_doc/comm/thermal_heavy/children/on + + + + + +dup44_/lht_tree_doc/comm/thermal_heavy/children/diag + + +diag +none + + + + + +dup44_/lht_tree_doc/comm/thermal_heavy->dup44_/lht_tree_doc/comm/thermal_heavy/children/diag + + + + + +dup44_/lht_tree_doc/comm/thermal_heavy/children/round + + +round +none + + + + + +dup44_/lht_tree_doc/comm/thermal_heavy->dup44_/lht_tree_doc/comm/thermal_heavy/children/round + + + + + +dup44_/lht_tree_doc/comm/thermal_heavy/children/sharp + + +sharp +none + + + + + +dup44_/lht_tree_doc/comm/thermal_heavy->dup44_/lht_tree_doc/comm/thermal_heavy/children/sharp + + + + + +dup44_/lht_tree_doc/comm/thermal_heavy/children/solid + + +solid +none + + + + + +dup44_/lht_tree_doc/comm/thermal_heavy->dup44_/lht_tree_doc/comm/thermal_heavy/children/solid + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/clearance + + +clearance +coord +>=3 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/clearance + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/enforce_clearance + + +enforce_clearance +coord +>=7 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/enforce_clearance + + + + + +dup45_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID->dup45_/lht_tree_doc/comm/attributes + + + + + +dup46_/lht_tree_doc/comm/flags_polygon + + +ha:flags + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID->dup46_/lht_tree_doc/comm/flags_polygon + + + + + +dup47_/lht_tree_doc/comm/thermal_heavy + + +li:thermal + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID->dup47_/lht_tree_doc/comm/thermal_heavy + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/geometry + + +li:geometry + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/geometry + + + + + +dup45_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup45_/lht_tree_doc/comm/attributes->dup45_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup46_/lht_tree_doc/comm/flags_polygon/children/found + + +found +flag + + + + + +dup46_/lht_tree_doc/comm/flags_polygon->dup46_/lht_tree_doc/comm/flags_polygon/children/found + + + + + +dup46_/lht_tree_doc/comm/flags_polygon/children/clearpoly + + +clearpoly +flag + + + + + +dup46_/lht_tree_doc/comm/flags_polygon->dup46_/lht_tree_doc/comm/flags_polygon/children/clearpoly + + + + + +dup46_/lht_tree_doc/comm/flags_polygon/children/fullpoly + + +fullpoly +flag + + + + + +dup46_/lht_tree_doc/comm/flags_polygon->dup46_/lht_tree_doc/comm/flags_polygon/children/fullpoly + + + + + +dup46_/lht_tree_doc/comm/flags_polygon/children/selected + + +selected +flag + + + + + +dup46_/lht_tree_doc/comm/flags_polygon->dup46_/lht_tree_doc/comm/flags_polygon/children/selected + + + + + +dup46_/lht_tree_doc/comm/flags_polygon/children/drc + + +drc +flag + + + + + +dup46_/lht_tree_doc/comm/flags_polygon->dup46_/lht_tree_doc/comm/flags_polygon/children/drc + + + + + +dup46_/lht_tree_doc/comm/flags_polygon/children/exportsel + + +exportsel +flag + + + + + +dup46_/lht_tree_doc/comm/flags_polygon->dup46_/lht_tree_doc/comm/flags_polygon/children/exportsel + + + + + +dup46_/lht_tree_doc/comm/flags_polygon/children/lock + + +lock +flag + + + + + +dup46_/lht_tree_doc/comm/flags_polygon->dup46_/lht_tree_doc/comm/flags_polygon/children/lock + + + + + +dup46_/lht_tree_doc/comm/flags_polygon/children/termname + + +termname +flag + + + + + +dup46_/lht_tree_doc/comm/flags_polygon->dup46_/lht_tree_doc/comm/flags_polygon/children/termname + + + + + +dup46_/lht_tree_doc/comm/flags_polygon/children/clearpolypoly + + +clearpolypoly +flag + + + + + +dup46_/lht_tree_doc/comm/flags_polygon->dup46_/lht_tree_doc/comm/flags_polygon/children/clearpolypoly + + + + + +dup46_/lht_tree_doc/comm/flags_polygon/children/floater + + +floater +flag + + + + + +dup46_/lht_tree_doc/comm/flags_polygon->dup46_/lht_tree_doc/comm/flags_polygon/children/floater + + + + + + + + + + + + + + +dup47_/lht_tree_doc/comm/thermal_heavy/children/on + + +on +none + + + + + +dup47_/lht_tree_doc/comm/thermal_heavy->dup47_/lht_tree_doc/comm/thermal_heavy/children/on + + + + + +dup47_/lht_tree_doc/comm/thermal_heavy/children/diag + + +diag +none + + + + + +dup47_/lht_tree_doc/comm/thermal_heavy->dup47_/lht_tree_doc/comm/thermal_heavy/children/diag + + + + + +dup47_/lht_tree_doc/comm/thermal_heavy/children/round + + +round +none + + + + + +dup47_/lht_tree_doc/comm/thermal_heavy->dup47_/lht_tree_doc/comm/thermal_heavy/children/round + + + + + +dup47_/lht_tree_doc/comm/thermal_heavy/children/sharp + + +sharp +none + + + + + +dup47_/lht_tree_doc/comm/thermal_heavy->dup47_/lht_tree_doc/comm/thermal_heavy/children/sharp + + + + + +dup47_/lht_tree_doc/comm/thermal_heavy/children/solid + + +solid +none + + + + + +dup47_/lht_tree_doc/comm/thermal_heavy->dup47_/lht_tree_doc/comm/thermal_heavy/children/solid + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/geometry/children/contour + + +contour +coordtbl + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/geometry->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/geometry/children/contour + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/geometry/children/hole + + +hole +coordtbl + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/geometry->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/polygon.ID/children/geometry/children/hole + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/x + + +x +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/x + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/y + + +y +coord + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/y + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/role + + +role +string + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/role + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/string + + +string +string + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/string + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/fid + + +fid +integer + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/fid + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/scale + + +scale +integer + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/scale + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/scale_x + + +scale_x +double + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/scale_x + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/scale_y + + +scale_y +double + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/scale_y + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/direction + + +direction +integer +<=5 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/direction + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/rot + + +rot +angle +>=6 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/rot + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/thickness + + +thickness +coord +>=6 + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID/children/thickness + + + + + +dup48_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->dup48_/lht_tree_doc/comm/attributes + + + + + +dup49_/lht_tree_doc/comm/flags_text + + +ha:flags + + + + + +/lht_tree_doc/comm/data/children/layers/children/NAME/children/objects/children/text.ID->dup49_/lht_tree_doc/comm/flags_text + + + + + +dup48_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup48_/lht_tree_doc/comm/attributes->dup48_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup49_/lht_tree_doc/comm/flags_text/children/found + + +found +flag + + + + + +dup49_/lht_tree_doc/comm/flags_text->dup49_/lht_tree_doc/comm/flags_text/children/found + + + + + +dup49_/lht_tree_doc/comm/flags_text/children/clearline + + +clearline +flag + + + + + +dup49_/lht_tree_doc/comm/flags_text->dup49_/lht_tree_doc/comm/flags_text/children/clearline + + + + + +dup49_/lht_tree_doc/comm/flags_text/children/selected + + +selected +flag + + + + + +dup49_/lht_tree_doc/comm/flags_text->dup49_/lht_tree_doc/comm/flags_text/children/selected + + + + + +dup49_/lht_tree_doc/comm/flags_text/children/onsolder + + +onsolder +flag + + + + + +dup49_/lht_tree_doc/comm/flags_text->dup49_/lht_tree_doc/comm/flags_text/children/onsolder + + + + + +dup49_/lht_tree_doc/comm/flags_text/children/drc + + +drc +flag + + + + + +dup49_/lht_tree_doc/comm/flags_text->dup49_/lht_tree_doc/comm/flags_text/children/drc + + + + + +dup49_/lht_tree_doc/comm/flags_text/children/exportsel + + +exportsel +flag + + + + + +dup49_/lht_tree_doc/comm/flags_text->dup49_/lht_tree_doc/comm/flags_text/children/exportsel + + + + + +dup49_/lht_tree_doc/comm/flags_text/children/lock + + +lock +flag + + + + + +dup49_/lht_tree_doc/comm/flags_text->dup49_/lht_tree_doc/comm/flags_text/children/lock + + + + + +dup49_/lht_tree_doc/comm/flags_text/children/termname + + +termname +flag + + + + + +dup49_/lht_tree_doc/comm/flags_text->dup49_/lht_tree_doc/comm/flags_text/children/termname + + + + + +dup49_/lht_tree_doc/comm/flags_text/children/dyntext + + +dyntext +flag + + + + + +dup49_/lht_tree_doc/comm/flags_text->dup49_/lht_tree_doc/comm/flags_text/children/dyntext + + + + + +dup49_/lht_tree_doc/comm/flags_text/children/floater + + +floater +flag + + + + + +dup49_/lht_tree_doc/comm/flags_text->dup49_/lht_tree_doc/comm/flags_text/children/floater + + + + + + + + + + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/unused + + +unused +none + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes->/lht_tree_doc/comm/data/children/padstack_prototypes/children/unused + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID + + +ha:ps_proto_v4.PID + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/hdia + + +hdia +coord + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/hdia + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/htop + + +htop +integer + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/htop + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/hbottom + + +hbottom +integer + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/hbottom + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/hplated + + +hplated +integer + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/hplated + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/name + + +name +string +>=5 + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/name + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape + + +li:shape + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4 + + +ha:ps_shape_v4 + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4 + + + + + +dup50_/lht_tree_doc/comm/layer_mask + + +ha:layer_mask + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4->dup50_/lht_tree_doc/comm/layer_mask + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/combining + + +combining + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/combining + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/clearance + + +clearance +coord + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/clearance + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_poly + + +li:ps_poly + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_poly + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line + + +ha:ps_line + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_circ + + +ha:ps_circ + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_circ + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_hshadow + + +te:ps_hshadow +>=6 + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_hshadow + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/top + + +top +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/top + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/bottom + + +bottom +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/bottom + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/intern + + +intern +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/intern + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/logical + + +logical +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/logical + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/copper + + +copper +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/copper + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/silk + + +silk +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/silk + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/mask + + +mask +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/mask + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/paste + + +paste +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/paste + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/outline + + +outline +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/outline + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/mech + + +mech +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/mech + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/doc + + +doc +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/doc + + + + + +dup50_/lht_tree_doc/comm/layer_mask/children/substrate + + +substrate +flag + + + + + +dup50_/lht_tree_doc/comm/layer_mask->dup50_/lht_tree_doc/comm/layer_mask/children/substrate + + + + + + + + + + + + + + + + +dup51_/lht_tree_doc/comm/combining/children/sub + + +sub +flag + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/combining->dup51_/lht_tree_doc/comm/combining/children/sub + + + + + +dup51_/lht_tree_doc/comm/combining/children/auto + + +auto +flag + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/combining->dup51_/lht_tree_doc/comm/combining/children/auto + + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/x1 + + +x1 +coord + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/x1 + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/y1 + + +y1 +coord + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/y1 + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/x2 + + +x2 +coord + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/x2 + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/y2 + + +y2 +coord + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/y2 + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/thickness + + +thickness +coord + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/thickness + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/square + + +square +integer + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_line/children/square + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_circ/children/x + + +x +coord + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_circ->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_circ/children/x + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_circ/children/y + + +y +coord + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_circ->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_circ/children/y + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_circ/children/dia + + +dia +coord + + + + + +/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_circ->/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID/children/shape/children/ps_shape_v4/children/ps_circ/children/dia + + + + + +dup52_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID/children/uid + + +uid +minuid + + + + + +dup52_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID->dup52_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID/children/uid + + + + + +dup52_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +dup52_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID->dup52_/lht_tree_doc/comm/attributes + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit + + +ha:flags + + + + + +dup52_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID->dup52_/lht_tree_doc/comm/flags_subcircuit + + + + + +dup52_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID/children/data + +data -> + + + + + +dup52_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID->dup52_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID/children/data + + + + + +dup52_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup52_/lht_tree_doc/comm/attributes->dup52_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit/children/found + + +found +flag + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit->dup52_/lht_tree_doc/comm/flags_subcircuit/children/found + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit/children/selected + + +selected +flag + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit->dup52_/lht_tree_doc/comm/flags_subcircuit/children/selected + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit/children/drc + + +drc +flag + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit->dup52_/lht_tree_doc/comm/flags_subcircuit/children/drc + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit/children/exportsel + + +exportsel +flag + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit->dup52_/lht_tree_doc/comm/flags_subcircuit/children/exportsel + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit/children/lock + + +lock +flag + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit->dup52_/lht_tree_doc/comm/flags_subcircuit/children/lock + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit/children/nonetlist + + +nonetlist +flag + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit->dup52_/lht_tree_doc/comm/flags_subcircuit/children/nonetlist + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit/children/termname + + +termname +flag + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit->dup52_/lht_tree_doc/comm/flags_subcircuit/children/termname + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit/children/floater + + +floater +flag + + + + + +dup52_/lht_tree_doc/comm/flags_subcircuit->dup52_/lht_tree_doc/comm/flags_subcircuit/children/floater + + + + + + + + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/x + + +x +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID->/lht_tree_doc/comm/data/children/element.ID/children/x + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/y + + +y +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID->/lht_tree_doc/comm/data/children/element.ID/children/y + + + + + +dup53_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/element.ID->dup53_/lht_tree_doc/comm/attributes + + + + + +dup54_/lht_tree_doc/comm/flags_element + + +ha:flags_element + + + + + +/lht_tree_doc/comm/data/children/element.ID->dup54_/lht_tree_doc/comm/flags_element + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects + + +li:objects + + + + + +/lht_tree_doc/comm/data/children/element.ID->/lht_tree_doc/comm/data/children/element.ID/children/objects + + + + + +dup53_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup53_/lht_tree_doc/comm/attributes->dup53_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup54_/lht_tree_doc/comm/flags_element/children/found + + +found +flag + + + + + +dup54_/lht_tree_doc/comm/flags_element->dup54_/lht_tree_doc/comm/flags_element/children/found + + + + + +dup54_/lht_tree_doc/comm/flags_element/children/selected + + +selected +flag + + + + + +dup54_/lht_tree_doc/comm/flags_element->dup54_/lht_tree_doc/comm/flags_element/children/selected + + + + + +dup54_/lht_tree_doc/comm/flags_element/children/auto + + +auto +flag + + + + + +dup54_/lht_tree_doc/comm/flags_element->dup54_/lht_tree_doc/comm/flags_element/children/auto + + + + + +dup54_/lht_tree_doc/comm/flags_element/children/drc + + +drc +flag + + + + + +dup54_/lht_tree_doc/comm/flags_element->dup54_/lht_tree_doc/comm/flags_element/children/drc + + + + + +dup54_/lht_tree_doc/comm/flags_element/children/lock + + +lock +flag + + + + + +dup54_/lht_tree_doc/comm/flags_element->dup54_/lht_tree_doc/comm/flags_element/children/lock + + + + + +dup54_/lht_tree_doc/comm/flags_element/children/nonetlist + + +nonetlist +flag + + + + + +dup54_/lht_tree_doc/comm/flags_element->dup54_/lht_tree_doc/comm/flags_element/children/nonetlist + + + + + +dup54_/lht_tree_doc/comm/flags_element/children/termname + + +termname +flag + + + + + +dup54_/lht_tree_doc/comm/flags_element->dup54_/lht_tree_doc/comm/flags_element/children/termname + + + + + +dup54_/lht_tree_doc/comm/flags_element/children/floater + + +floater +flag + + + + + +dup54_/lht_tree_doc/comm/flags_element->dup54_/lht_tree_doc/comm/flags_element/children/floater + + + + + +dup54_/lht_tree_doc/comm/flags_element/children/onsolder + + +onsolder +flag + + + + + +dup54_/lht_tree_doc/comm/flags_element->dup54_/lht_tree_doc/comm/flags_element/children/onsolder + + + + + + + + + + + + + +dup55_/lht_tree_doc/comm/data/children/element.ID/children/objects/children/line.ID + +line.ID -> + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects->dup55_/lht_tree_doc/comm/data/children/element.ID/children/objects/children/line.ID + + + + + +dup56_/lht_tree_doc/comm/data/children/element.ID/children/objects/children/arc.ID + +arc.ID -> + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects->dup56_/lht_tree_doc/comm/data/children/element.ID/children/objects/children/arc.ID + + + + + +dup57_/lht_tree_doc/comm/data/children/element.ID/children/objects/children/text.ID + +text.ID -> + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects->dup57_/lht_tree_doc/comm/data/children/element.ID/children/objects/children/text.ID + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID + + +ha:pad.ID + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects->/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID + + +ha:pin.ID + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects->/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/x1 + + +x1 +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID->/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/x1 + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/y1 + + +y1 +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID->/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/y1 + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/x2 + + +x2 +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID->/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/x2 + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/y2 + + +y2 +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID->/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/y2 + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/thickness + + +thickness +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID->/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/thickness + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/clearance + + +clearance +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID->/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/clearance + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/mask + + +mask +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID->/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/mask + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/name + + +name +string + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID->/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/name + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/number + + +number +string + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID->/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID/children/number + + + + + +dup58_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID->dup58_/lht_tree_doc/comm/attributes + + + + + +dup59_/lht_tree_doc/comm/flags_pad + + +ha:flags_pad + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pad.ID->dup59_/lht_tree_doc/comm/flags_pad + + + + + +dup58_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup58_/lht_tree_doc/comm/attributes->dup58_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/found + + +found +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/found + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/hole + + +hole +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/hole + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/clearline + + +clearline +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/clearline + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/selected + + +selected +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/selected + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/auto + + +auto +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/auto + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/warn + + +warn +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/warn + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/usetherm + + +usetherm +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/usetherm + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/drc + + +drc +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/drc + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/lock + + +lock +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/lock + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/nonetlist + + +nonetlist +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/nonetlist + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/termname + + +termname +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/termname + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/floater + + +floater +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/floater + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/pin + + +pin +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/pin + + + + + +dup59_/lht_tree_doc/comm/flags_pad/children/via + + +via +flag + + + + + +dup59_/lht_tree_doc/comm/flags_pad->dup59_/lht_tree_doc/comm/flags_pad/children/via + + + + + + + + + + + + + + + + + + +dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/x + + +x +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID->dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/x + + + + + +dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/y + + +y +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID->dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/y + + + + + +dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/thickness + + +thickness +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID->dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/thickness + + + + + +dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/clearance + + +clearance +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID->dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/clearance + + + + + +dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/mask + + +mask +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID->dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/mask + + + + + +dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/hole + + +hole +coord + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID->dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/hole + + + + + +dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/name + + +name +string + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID->dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/name + + + + + +dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/number + + +number +string + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID->dup60_/lht_tree_doc/comm/data/children/objects/children/via.ID/children/number + + + + + +dup60_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID->dup60_/lht_tree_doc/comm/attributes + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia + + +ha:flags_pinvia + + + + + +/lht_tree_doc/comm/data/children/element.ID/children/objects/children/pin.ID->dup60_/lht_tree_doc/comm/flags_pinvia + + + + + +dup60_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup60_/lht_tree_doc/comm/attributes->dup60_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/found + + +found +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/found + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/hole + + +hole +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/hole + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/clearline + + +clearline +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/clearline + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/selected + + +selected +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/selected + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/auto + + +auto +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/auto + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/warn + + +warn +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/warn + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/usetherm + + +usetherm +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/usetherm + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/drc + + +drc +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/drc + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/lock + + +lock +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/lock + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/nonetlist + + +nonetlist +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/nonetlist + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/termname + + +termname +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/termname + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/floater + + +floater +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/floater + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/pin + + +pin +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/pin + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia/children/via + + +via +flag + + + + + +dup60_/lht_tree_doc/comm/flags_pinvia->dup60_/lht_tree_doc/comm/flags_pinvia/children/via + + + + + + + + + + + + + + + + + + +/lht_tree_doc/comm/data/children/rat.ID/children/x1 + + +x1 +coord + + + + + +/lht_tree_doc/comm/data/children/rat.ID->/lht_tree_doc/comm/data/children/rat.ID/children/x1 + + + + + +/lht_tree_doc/comm/data/children/rat.ID/children/y1 + + +y1 +coord + + + + + +/lht_tree_doc/comm/data/children/rat.ID->/lht_tree_doc/comm/data/children/rat.ID/children/y1 + + + + + +/lht_tree_doc/comm/data/children/rat.ID/children/x2 + + +x2 +coord + + + + + +/lht_tree_doc/comm/data/children/rat.ID->/lht_tree_doc/comm/data/children/rat.ID/children/x2 + + + + + +/lht_tree_doc/comm/data/children/rat.ID/children/y2 + + +y2 +coord + + + + + +/lht_tree_doc/comm/data/children/rat.ID->/lht_tree_doc/comm/data/children/rat.ID/children/y2 + + + + + +/lht_tree_doc/comm/data/children/rat.ID/children/lgrp1 + + +lgrp1 +integer + + + + + +/lht_tree_doc/comm/data/children/rat.ID->/lht_tree_doc/comm/data/children/rat.ID/children/lgrp1 + + + + + +/lht_tree_doc/comm/data/children/rat.ID/children/lgrp2 + + +lgrp2 +integer + + + + + +/lht_tree_doc/comm/data/children/rat.ID->/lht_tree_doc/comm/data/children/rat.ID/children/lgrp2 + + + + + +/lht_tree_doc/comm/data/children/rat.ID/children/anchor1 + + +anchor1 +string +>=7 + + + + + +/lht_tree_doc/comm/data/children/rat.ID->/lht_tree_doc/comm/data/children/rat.ID/children/anchor1 + + + + + +/lht_tree_doc/comm/data/children/rat.ID/children/anchor2 + + +anchor2 +string +>=7 + + + + + +/lht_tree_doc/comm/data/children/rat.ID->/lht_tree_doc/comm/data/children/rat.ID/children/anchor2 + + + + + +dup61_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/comm/data/children/rat.ID->dup61_/lht_tree_doc/comm/attributes + + + + + +dup62_/lht_tree_doc/comm/flags_line + + +ha:flags + + + + + +/lht_tree_doc/comm/data/children/rat.ID->dup62_/lht_tree_doc/comm/flags_line + + + + + +dup61_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup61_/lht_tree_doc/comm/attributes->dup61_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup62_/lht_tree_doc/comm/flags_line/children/found + + +found +flag + + + + + +dup62_/lht_tree_doc/comm/flags_line->dup62_/lht_tree_doc/comm/flags_line/children/found + + + + + +dup62_/lht_tree_doc/comm/flags_line/children/clearline + + +clearline +flag + + + + + +dup62_/lht_tree_doc/comm/flags_line->dup62_/lht_tree_doc/comm/flags_line/children/clearline + + + + + +dup62_/lht_tree_doc/comm/flags_line/children/selected + + +selected +flag + + + + + +dup62_/lht_tree_doc/comm/flags_line->dup62_/lht_tree_doc/comm/flags_line/children/selected + + + + + +dup62_/lht_tree_doc/comm/flags_line/children/auto + + +auto +flag + + + + + +dup62_/lht_tree_doc/comm/flags_line->dup62_/lht_tree_doc/comm/flags_line/children/auto + + + + + +dup62_/lht_tree_doc/comm/flags_line/children/rubberend + + +rubberend +flag + + + + + +dup62_/lht_tree_doc/comm/flags_line->dup62_/lht_tree_doc/comm/flags_line/children/rubberend + + + + + +dup62_/lht_tree_doc/comm/flags_line/children/drc + + +drc +flag + + + + + +dup62_/lht_tree_doc/comm/flags_line->dup62_/lht_tree_doc/comm/flags_line/children/drc + + + + + +dup62_/lht_tree_doc/comm/flags_line/children/exportsel + + +exportsel +flag + + + + + +dup62_/lht_tree_doc/comm/flags_line->dup62_/lht_tree_doc/comm/flags_line/children/exportsel + + + + + +dup62_/lht_tree_doc/comm/flags_line/children/lock + + +lock +flag + + + + + +dup62_/lht_tree_doc/comm/flags_line->dup62_/lht_tree_doc/comm/flags_line/children/lock + + + + + +dup62_/lht_tree_doc/comm/flags_line/children/termname + + +termname +flag + + + + + +dup62_/lht_tree_doc/comm/flags_line->dup62_/lht_tree_doc/comm/flags_line/children/termname + + + + + +dup62_/lht_tree_doc/comm/flags_line/children/floater + + +floater +flag + + + + + +dup62_/lht_tree_doc/comm/flags_line->dup62_/lht_tree_doc/comm/flags_line/children/floater + + + + + + + + + + + + + + Index: tags/2.3.0/doc/developer/lihata_format/examples/board.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/examples/board.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/examples/board.lht (revision 33253) @@ -0,0 +1,284 @@ +ha:pcb-rnd-board-v5 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 2.0mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1.0mm + clearance = 20.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 500.0mil + y = 150.0mil + } + 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 { } + visible=1 + + li:objects { + ha:line.8 { + x1=50.0mil; y1=75.0mil; x2=450.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + visible=1 + + li:objects { + } + color = {#104e8b} + } + + ha:bottom-gnd { + lid=3 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + color = {#cd3700} + } + + ha:int-sig2 { + lid=4 + group=7 + ha:combining { } + visible=1 + + li:objects { + } + color = {#548b54} + } + + ha:int-sig1 { + lid=5 + group=5 + ha:combining { } + visible=1 + + li:objects { + } + color = {#8b7355} + } + + ha:outline { + lid=6 + group=9 + ha:combining { } + visible=1 + + li:objects { + } + color = {#00868b} + } + + ha:bottom-silk { + lid=7 + group=12 + ha:combining { auto=1; } + visible=1 + + li:objects { + } + color = {#cccccc} + } + + ha:top-silk { + lid=8 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + } + color = {#000000} + } + + ha:top-paste { + lid=9 + group=0 + ha:combining { auto=1; } + visible=0 + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-mask { + lid=10 + group=2 + ha:combining { sub=1; auto=1; } + visible=0 + + li:objects { + } + color = {#104e8b} + } + + ha:bottom-mask { + lid=11 + group=11 + ha:combining { sub=1; auto=1; } + visible=0 + + li:objects { + } + color = {#cd3700} + } + + ha:bottom-paste { + lid=12 + group=13 + ha:combining { auto=1; } + visible=0 + + li:objects { + } + color = {#548b54} + } + } + } + + 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 { outline=1; } + li:layers { 6; } + } + 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; } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + line_thickness = 10.00 mil + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + poly_isle_area = 200000000.0 + clearance = 20.00 mil + } + ha:editor { + grids_idx = 4 + grid = 25.00 mil + grid_unit = mil + } + } + } +} Index: tags/2.3.0/doc/developer/lihata_format/examples/conf.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/examples/conf.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/examples/conf.lht (revision 33253) @@ -0,0 +1,26 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:hid_gtk { + ha:window_geometry { + library_x = 1342 + library_y = 316 + library_width = 580 + library_height = 448 + } + } + } + ha:editor { + auto_place = { 1 } + save_in_tmp = { 0 } + } + ha:rc { + li:library_search_paths { + ?../pcblib + ?~/pcblib/ + $(rc.path.share)/pcblib + } + backup_interval = { 60 } + } + } +} Index: tags/2.3.0/doc/developer/lihata_format/examples/drc_query.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/examples/drc_query.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/examples/drc_query.lht (revision 33253) @@ -0,0 +1,22 @@ +li:pcb-rnd-drc-query-v1 { + li:definitions { + ha:hole_overlap_factor { + default = 0.0 + type = real + desc = {How much drilled holes may overlap [-1..+1]; 0 means touching holes are reported; positive numbers allow more overlap, negative numbers report non-overlapping but close holes} + } + } + li:rules { + ha:hole_overlap { + type = pair hole + title = overlapping holes + desc = padstack holes overlap + query = { +rule overlap +let A @.type==PSTK +let B A +assert (A.IID > B.IID) && (distance(A.x, A.y, B.x, B.y) < (A.hole + B.hole)/(2*(1+$hole_overlap_factor))) thus violation(DRCGRP1, A, DRCGRP2, B, DRCMEASURE, distance(A.x, A.y, B.x, B.y), DRCEXPECT, (A.hole + B.hole)/(2*(1+$hole_overlap_factor))) + } + } + } +} Index: tags/2.3.0/doc/developer/lihata_format/examples/subc.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/examples/subc.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/examples/subc.lht (revision 33253) @@ -0,0 +1,236 @@ +li:pcb-rnd-subcircuit-v4 { + ha:subc.4 { + ha:attributes { + value = 1206 + footprint = Standard SMT resistor, capacitor etc + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v4.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.726186mm + -1.02616mm + -0.726186mm + -1.02616mm + -0.726186mm + 1.02616mm + 0.726186mm + 1.02616mm + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.6 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = -1.49987mm + rot = 0.000000 + y = 0.0 + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 1.49987mm + rot = 0.000000 + y = 0.0 + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.8 { + clearance = 0.0 + y2 = -0.94996mm + thickness = 8.0mil + ha:attributes { + } + x1 = -23.62mil + x2 = 23.62mil + ha:flags { + } + y1 = -0.94996mm + } + ha:line.11 { + clearance = 0.0 + y2 = 0.94996mm + thickness = 8.0mil + ha:attributes { + } + x1 = -23.62mil + x2 = 23.62mil + ha:flags { + } + y1 = 0.94996mm + } + ha:text.5 { + scale = 100 + ha:attributes { + } + direction = 0 + x = -31.5mil + y = -31.5mil + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.14 { + clearance = 0.0 + y2 = 0.0 + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 0.0 + x2 = 0.0 + ha:flags { + } + y1 = 0.0 + } + ha:line.17 { + clearance = 0.0 + y2 = 0.0 + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 0.0 + x2 = 0.0 + ha:flags { + } + y1 = 0.0 + } + ha:line.20 { + clearance = 0.0 + y2 = 0.0 + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 0.0 + x2 = 1.0mm + ha:flags { + } + y1 = 0.0 + } + ha:line.23 { + clearance = 0.0 + y2 = 1.0mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 0.0 + x2 = 0.0 + ha:flags { + } + y1 = 0.0 + } + } + ha:combining { + } + } + } + } + uid = kazsgcWF3uqvvuDCYMsAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/doc/developer/lihata_format/geda-project-v1.svg =================================================================== --- tags/2.3.0/doc/developer/lihata_format/geda-project-v1.svg (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/geda-project-v1.svg (revision 33253) @@ -0,0 +1,303 @@ + + + + + + +ha:geda-project-v1 + + + +/lht_tree_doc/roots/geda-project-v1 + + +ha:geda-project-v1 + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common + + +ha:common + + + + + +/lht_tree_doc/roots/geda-project-v1->/lht_tree_doc/roots/geda-project-v1/children/common + + + + + +dup16_/lht_tree_doc/roots/geda-project-v1/children/pcb-rnd-conf-v1 + +pcb-rnd-conf-v1 -> + + + + + +/lht_tree_doc/roots/geda-project-v1->dup16_/lht_tree_doc/roots/geda-project-v1/children/pcb-rnd-conf-v1 + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/name + + +name +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common->/lht_tree_doc/roots/geda-project-v1/children/common/children/name + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/desc + + +desc +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common->/lht_tree_doc/roots/geda-project-v1/children/common/children/desc + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/url + + +url +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common->/lht_tree_doc/roots/geda-project-v1/children/common/children/url + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/vcs + + +vcs +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common->/lht_tree_doc/roots/geda-project-v1/children/common/children/vcs + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/contact + + +contact +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common->/lht_tree_doc/roots/geda-project-v1/children/common/children/contact + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/files + + +li:files + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common->/lht_tree_doc/roots/geda-project-v1/children/common/children/files + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/libs + + +li:libs + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common->/lht_tree_doc/roots/geda-project-v1/children/common/children/libs + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/files/children/NAME + + +ha:NAME + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/files->/lht_tree_doc/roots/geda-project-v1/children/common/children/files/children/NAME + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/files/children/NAME/children/path + + +path +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/files/children/NAME->/lht_tree_doc/roots/geda-project-v1/children/common/children/files/children/NAME/children/path + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/files/children/NAME/children/desc + + +desc +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/files/children/NAME->/lht_tree_doc/roots/geda-project-v1/children/common/children/files/children/NAME/children/desc + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/files/children/NAME/children/type + + +type +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/files/children/NAME->/lht_tree_doc/roots/geda-project-v1/children/common/children/files/children/NAME/children/type + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME + + +ha:NAME + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/libs->/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME/children/path + + +path +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME->/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME/children/path + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME/children/url + + +url +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME->/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME/children/url + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME/children/desc + + +desc +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME->/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME/children/desc + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME/children/type + + +type +string + + + + + +/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME->/lht_tree_doc/roots/geda-project-v1/children/common/children/libs/children/NAME/children/type + + + + + Index: tags/2.3.0/doc/developer/lihata_format/index.html =================================================================== --- tags/2.3.0/doc/developer/lihata_format/index.html (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/index.html (revision 33253) @@ -0,0 +1,65 @@ + + + + pcb-rnd developer manual - lihata file formats + + + +

pcb-rnd native file formats

+

+The native file format of pcb-rnd is +lihata based. Lihata is a generic markup language that describes how +a tree can be serialized into a file format. What the tree contains and +what each node means is up to the user (pcb-rnd in this case). This document +describes how the lihata trees are interpreted by pcb-rnd. +

+This document is halfway in between the low level lihata document and the +high level data model +specification. It is assumed that the reader is familiar with both: the +lihata interface plugin doesn't do anything on its own, it only takes +the data model from the memory and the lihata document on disk and +converts the syntax between the two. +

+The following table is a summary of the native file formats the core +handles. Various plugins will handle their own file formats, often also +lihata based - those are each documented at the corresponding. Note: +pcb-rnd does not try to recognize the purpose of the file by the file name, +but by the root node name - files can be named anything, there's no +"extension"; there are some files that are found by name (typically config +files) - these are marked with bold. +

+ + +
typical filename root node + purpose (and documentation) + +
foo.lht ha:pcb-rnd-board-v* + Printed circuit board, self-contained +
(struct drawing) +
(sample file) + +
bar.lht, bar.fp li:pcb-rnd-subcircuit-v* + A subcircuit, self-contained, most often used as a footprint +
(struct drawing) +
(sample file) + +
times.lht li:pcb-rnd-font-v1 + Vector font +
(struct drawing) + +
pcb-conf.lht li:pcb-rnd-conf-v1 + A configuration subtree: system config (e.g. /usr/share/pcb-rnd/pcb-conf.lht) or user config (~/.pcb-rnd/pcb-conf.lht) +
(struct drawing) +
(sample file) + +
project.lht ha:geda-project-v1 + A project file that describes configuration and source file names for various software +
(struct drawing) + +
pcb-menu-default.lht ha: + The main menu system, including popup menus, all key and mouse bindings + +
+ + + Index: tags/2.3.0/doc/developer/lihata_format/pcb-rnd-board-v.svg =================================================================== --- tags/2.3.0/doc/developer/lihata_format/pcb-rnd-board-v.svg (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/pcb-rnd-board-v.svg (revision 33253) @@ -0,0 +1,1115 @@ + + + + + + +ha:pcb-rnd-board-v* + + + +/lht_tree_doc/roots/pcb-rnd-board-v* + + +ha:pcb-rnd-board-v* + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta + + +ha:meta + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack + + +ha:layer_stack + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*->/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/font + + +ha:font + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*->/lht_tree_doc/roots/pcb-rnd-board-v*/children/font + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/styles + + +ha:styles + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*->/lht_tree_doc/roots/pcb-rnd-board-v*/children/styles + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists + + +ha:netlists + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists + + + + + +dup4_/lht_tree_doc/roots/pcb-rnd-board-v*/children/conf + +conf -> + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*->dup4_/lht_tree_doc/roots/pcb-rnd-board-v*/children/conf + + + + + +dup5_/lht_tree_doc/roots/pcb-rnd-board-v*/children/data + +data -> + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*->dup5_/lht_tree_doc/roots/pcb-rnd-board-v*/children/data + + + + + +dup6_/lht_tree_doc/roots/pcb-rnd-board-v*/children/pixmaps + +pixmaps -> + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*->dup6_/lht_tree_doc/roots/pcb-rnd-board-v*/children/pixmaps + + + + + +dup7_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*->dup7_/lht_tree_doc/comm/attributes + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/board_name + + +board_name +string + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/board_name + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/grid + + +ha:grid + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/grid + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size + + +ha:size + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc + + +ha:drc +<5 + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/cursor + + +ha:cursor + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/cursor + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/grid/children/offs_x + + +offs_x +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/grid->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/grid/children/offs_x + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/grid/children/offs_y + + +offs_y +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/grid->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/grid/children/offs_y + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/grid/children/spacing + + +spacing +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/grid->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/grid/children/spacing + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size/children/x + + +x +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size/children/x + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size/children/y + + +y +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size/children/y + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size/children/isle_area_nm2 + + +isle_area_nm2 +double + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size/children/isle_area_nm2 + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size/children/thermal_scale + + +thermal_scale +double + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/size/children/thermal_scale + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/bloat + + +bloat +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/bloat + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/shrink + + +shrink +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/shrink + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/min_width + + +min_width +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/min_width + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/min_silk + + +min_silk +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/min_silk + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/min_drill + + +min_drill +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/min_drill + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/min_ring + + +min_ring +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/drc/children/min_ring + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/cursor/children/x + + +x +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/cursor->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/cursor/children/x + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/cursor/children/y + + +y +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/cursor->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/cursor/children/y + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/cursor/children/zoom + + +zoom +double + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/cursor->/lht_tree_doc/roots/pcb-rnd-board-v*/children/meta/children/cursor/children/zoom + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups + + +li:groups + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack->/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER + + +ha:INTEGER + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups->/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/name + + +name +string +>=6 + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER->/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/name + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER->/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/name + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type + + +ha:type + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER->/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/layers + + +li:layers + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER->/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/layers + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/top + + +top +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/top + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/bottom + + +bottom +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/bottom + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/intern + + +intern +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/intern + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/logical + + +logical +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/logical + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/copper + + +copper +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/copper + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/silk + + +silk +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/silk + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/mask + + +mask +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/mask + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/paste + + +paste +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/paste + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/outline + + +outline +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/outline + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/mech + + +mech +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/mech + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/doc + + +doc +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/doc + + + + + +dup1_/lht_tree_doc/comm/layer_mask/children/substrate + + +substrate +flag + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/layer_stack/children/groups/children/INTEGER/children/type->dup1_/lht_tree_doc/comm/layer_mask/children/substrate + + + + + + + + + + + + + + + + +dup2_/lht_tree_doc/roots/pcb-rnd-board-v*/children/font/children/FONT-ID + +FONT-ID -> + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/font->dup2_/lht_tree_doc/roots/pcb-rnd-board-v*/children/font/children/FONT-ID + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist + + +li:netlist + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch + + +li:netlist_patch + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist/children/NETNAME + + +ha:NETNAME + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist/children/NETNAME + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist/children/NETNAME/children/conn + + +li:conn + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist/children/NETNAME->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist/children/NETNAME/children/conn + + + + + +dup3_/lht_tree_doc/comm/attributes_v5p + + +ha:attributes +>=5 + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist/children/NETNAME->dup3_/lht_tree_doc/comm/attributes_v5p + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist/children/NETNAME/children/conn/children/diameter + + +diameter +string + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist/children/NETNAME/children/conn->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist/children/NETNAME/children/conn/children/diameter + + + + + +dup3_/lht_tree_doc/comm/attributes_v5p/children/attrib-key + + +attrib-key +string + + + + + +dup3_/lht_tree_doc/comm/attributes_v5p->dup3_/lht_tree_doc/comm/attributes_v5p/children/attrib-key + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/net_info + + +li:net_info + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/net_info + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/add_conn + + +ha:add_conn + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/add_conn + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/del_conn + + +ha:del_conn + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/del_conn + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/change_attrib + + +ha:change_attrib + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/change_attrib + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/net_info/children/net + + +net +string + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/net_info->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/net_info/children/net + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/net_info/children/term + + +term +string + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/net_info->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/net_info/children/term + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/add_conn/children/net + + +net +string + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/add_conn->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/add_conn/children/net + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/add_conn/children/term + + +term +string + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/add_conn->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/add_conn/children/term + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/del_conn/children/net + + +net +string + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/del_conn->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/del_conn/children/net + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/del_conn/children/term + + +term +string + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/del_conn->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/del_conn/children/term + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/change_attrib/children/net + + +net +string + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/change_attrib->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/change_attrib/children/net + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/change_attrib/children/key + + +key +string + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/change_attrib->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/change_attrib/children/key + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/change_attrib/children/val + + +val +string + + + + + +/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/change_attrib->/lht_tree_doc/roots/pcb-rnd-board-v*/children/netlists/children/netlist_patch/children/change_attrib/children/val + + + + + +dup7_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup7_/lht_tree_doc/comm/attributes->dup7_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + Index: tags/2.3.0/doc/developer/lihata_format/pcb-rnd-conf-v1.svg =================================================================== --- tags/2.3.0/doc/developer/lihata_format/pcb-rnd-conf-v1.svg (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/pcb-rnd-conf-v1.svg (revision 33253) @@ -0,0 +1,67 @@ + + + + + + +li:pcb-rnd-conf-v1 + + + +/lht_tree_doc/roots/pcb-rnd-conf-v1 + + +li:pcb-rnd-conf-v1 + + + + + +/lht_tree_doc/roots/pcb-rnd-conf-v1/children/overwrite + + +ha:overwrite + + + + + +/lht_tree_doc/roots/pcb-rnd-conf-v1->/lht_tree_doc/roots/pcb-rnd-conf-v1/children/overwrite + + + + + +/lht_tree_doc/roots/pcb-rnd-conf-v1/children/prepend + + +ha:prepend + + + + + +/lht_tree_doc/roots/pcb-rnd-conf-v1->/lht_tree_doc/roots/pcb-rnd-conf-v1/children/prepend + + + + + +/lht_tree_doc/roots/pcb-rnd-conf-v1/children/append + + +ha:append + + + + + +/lht_tree_doc/roots/pcb-rnd-conf-v1->/lht_tree_doc/roots/pcb-rnd-conf-v1/children/append + + + + + Index: tags/2.3.0/doc/developer/lihata_format/pcb-rnd-font-v1.svg =================================================================== --- tags/2.3.0/doc/developer/lihata_format/pcb-rnd-font-v1.svg (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/pcb-rnd-font-v1.svg (revision 33253) @@ -0,0 +1,415 @@ + + + + + + +li:pcb-rnd-font-v1 + + + +/lht_tree_doc/roots/pcb-rnd-font-v1 + + +li:pcb-rnd-font-v1 + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID + + +ha:FONT-ID + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/cell_height + + +cell_height +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/cell_height + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/cell_width + + +cell_width +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/cell_width + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/id + + +id +integer + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/id + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/name + + +name +string + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/name + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols + + +ha:symbols + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER + + +ha:CHARACTER + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/height + + +height +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/height + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/width + + +width +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/width + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/delta + + +delta +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/delta + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects + + +li:objects + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID + + +ha:line.ID + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID + + +ha:simplearc.ID + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplepoly.ID + + +li:simplepoly.ID + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplepoly.ID + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID/children/x1 + + +x1 +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID/children/x1 + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID/children/y1 + + +y1 +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID/children/y1 + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID/children/x2 + + +x2 +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID/children/x2 + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID/children/y2 + + +y2 +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID/children/y2 + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID/children/thickness + + +thickness +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/line.ID/children/thickness + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/x + + +x +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/x + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/y + + +y +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/y + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/r + + +r +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/r + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/thickness + + +thickness +coord + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/thickness + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/astart + + +astart +angle + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/astart + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/adelta + + +adelta +angle + + + + + +/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID->/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID/children/symbols/children/CHARACTER/children/objects/children/simplearc.ID/children/adelta + + + + + Index: tags/2.3.0/doc/developer/lihata_format/pcb-rnd-log-v.svg =================================================================== --- tags/2.3.0/doc/developer/lihata_format/pcb-rnd-log-v.svg (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/pcb-rnd-log-v.svg (revision 33253) @@ -0,0 +1,116 @@ + + + + + + +ha:pcb-rnd-log-v* + + + +/lht_tree_doc/roots/pcb-rnd-log-v* + + +ha:pcb-rnd-log-v* + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries + + +li:entries + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*->/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID + + +ha:ID + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries->/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID/children/stamp + + +stamp +string + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID->/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID/children/stamp + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID/children/level + + +level +integer + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID->/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID/children/level + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID/children/seen + + +seen +integer + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID->/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID/children/seen + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID/children/str + + +str +string + + + + + +/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID->/lht_tree_doc/roots/pcb-rnd-log-v*/children/entries/children/ID/children/str + + + + + Index: tags/2.3.0/doc/developer/lihata_format/pcb-rnd-subcircuit-v.svg =================================================================== --- tags/2.3.0/doc/developer/lihata_format/pcb-rnd-subcircuit-v.svg (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/pcb-rnd-subcircuit-v.svg (revision 33253) @@ -0,0 +1,263 @@ + + + + + + +li:pcb-rnd-subcircuit-v* + + + +/lht_tree_doc/roots/pcb-rnd-subcircuit-v* + + +li:pcb-rnd-subcircuit-v* + + + + + +/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID + + +ha:subc.ID +>=3 + + + + + +/lht_tree_doc/roots/pcb-rnd-subcircuit-v*->/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID + + + + + +dup28_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/pixmaps + +pixmaps -> + + + + + +/lht_tree_doc/roots/pcb-rnd-subcircuit-v*->dup28_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/pixmaps + + + + + +/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID/children/uid + + +uid +minuid + + + + + +/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID->/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID/children/uid + + + + + +dup25_/lht_tree_doc/comm/attributes + + +ha:attributes + + + + + +/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID->dup25_/lht_tree_doc/comm/attributes + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit + + +ha:flags + + + + + +/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID->dup26_/lht_tree_doc/comm/flags_subcircuit + + + + + +dup27_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID/children/data + +data -> + + + + + +/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID->dup27_/lht_tree_doc/roots/pcb-rnd-subcircuit-v*/children/subc.ID/children/data + + + + + +dup25_/lht_tree_doc/comm/attributes/children/attrib-key + + +attrib-key +string + + + + + +dup25_/lht_tree_doc/comm/attributes->dup25_/lht_tree_doc/comm/attributes/children/attrib-key + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit/children/found + + +found +flag + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit->dup26_/lht_tree_doc/comm/flags_subcircuit/children/found + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit/children/selected + + +selected +flag + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit->dup26_/lht_tree_doc/comm/flags_subcircuit/children/selected + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit/children/drc + + +drc +flag + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit->dup26_/lht_tree_doc/comm/flags_subcircuit/children/drc + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit/children/exportsel + + +exportsel +flag + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit->dup26_/lht_tree_doc/comm/flags_subcircuit/children/exportsel + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit/children/lock + + +lock +flag + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit->dup26_/lht_tree_doc/comm/flags_subcircuit/children/lock + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit/children/nonetlist + + +nonetlist +flag + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit->dup26_/lht_tree_doc/comm/flags_subcircuit/children/nonetlist + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit/children/termname + + +termname +flag + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit->dup26_/lht_tree_doc/comm/flags_subcircuit/children/termname + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit/children/floater + + +floater +flag + + + + + +dup26_/lht_tree_doc/comm/flags_subcircuit->dup26_/lht_tree_doc/comm/flags_subcircuit/children/floater + + + + + + + + + + + + Index: tags/2.3.0/doc/developer/lihata_format/render/common.awk =================================================================== --- tags/2.3.0/doc/developer/lihata_format/render/common.awk (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/render/common.awk (revision 33253) @@ -0,0 +1,69 @@ +function get_name(node, ty, level) +{ + if (node "/name" in DATA) + nm = DATA[node "/name"] + else + nm = qstrip(NAME[node]) + if (ty != "") + nm = ty ":" nm + while(level > 0) { + nm = " " nm + level-- + } + return nm +} + +function dup_begin(DUPSAV) +{ + DUPSAV[1] = dupd_prefix + if (DUPSAV[1] == "") + dupd_prefix = "dup" ++uniq_node_name "_" +} + +function dup_end(DUPSAV) +{ + dupd_prefix = DUPSAV[1] +} + +function gen_sub(root, level, parent, v, n, N, node, dst_children, DUPSAV) +{ + if (!(root in NAME)) { + print "Error: path not found: " root > "/dev/stderr" + return + } + if (parent == "") + parent = root + v = children(N, root "/children") + for(n = 1; n <= v; n++) { + node = N[n] + if (TYPE[node] == "symlink") { + # normal node symlink: generate a link +# print "SY:" node " " DATA[node] "^^^" sy_is_recursive(node) > "/dev/stderr" + dup_begin(DUPSAV) + if (NAME[node] ~ "@dup") { + tbl_entry(DATA[node], level, parent) + gen_sub(DATA[node], level+1) + } + else + tbl_entry_link(node, DATA[node], level, parent) + dup_end(DUPSAV) + } + else if ((node "/children") in NAME) { + tbl_entry(node, level, parent) + if (TYPE[node "/children"] == "symlink") { + dup_begin(DUPSAV) + dst_children = DATA[node "/children"] + sub("/children$", "", dst_children) + gen_sub(dst_children, level+1, node) + dup_end(DUPSAV) + } + else { + gen_sub(node, level+1) + } + } + else if (TYPE[node] == "hash") + tbl_entry(node, level, parent) + else + print "Unhandled child (unknown type): " node > "/dev/stderr" + } +} Index: tags/2.3.0/doc/developer/lihata_format/render/dot.awk =================================================================== --- tags/2.3.0/doc/developer/lihata_format/render/dot.awk (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/render/dot.awk (revision 33253) @@ -0,0 +1,99 @@ +BEGIN { + nl = "\\n" +} + +function tbl_entry(node, level, nparent ,nm,vt,dsc,ty,vr, url, tip,duppar,grp,grp_parent) +{ + ty = DATA[node "/type"] + nm = get_name(node, ty, 0) + vt = DATA[node "/valtype"] + vr = DATA[node "/ver"] + grp_parent = parent(parent(node)) + grp = DATA[grp_parent "/dot_group"] + dsc = qstrip(DATA[node "/desc"]) + gsub("\"", "\\\"", dsc) + tip=" tooltip=" q dsc q + url=" URL=" q "tree.html#" node q + + if (dupd_prefix != "") { + node = dupd_prefix node + DUPD[node] ++ + + if (nparent != "") { + duppar = dupd_prefix nparent + if (duppar in DUPD) + nparent = duppar + } + } + + print " " q node q " [label=" q nm nl vt nl vr q url tip "]" >fn + if (nparent != "") + print " " q nparent q " -> " q node q > fn + if (grp != "") { + if (LAST_GRP_SIBL[nparent] != "") { + print " " q LAST_GRP_SIBL[nparent] q " -> " q node q "[style=invis]" > fn + } + LAST_GRP_SIBL[nparent] = node + } +} + +function tbl_entry_link(node, dst, level, parent ,nm,vt,dsc,ty,vr,contid,url,tip,dr) +{ + ty = DATA[node "/type"] + nm = get_name(node, ty, 0) + vt = DATA[node "/valtype"] + vr = DATA[node "/ver"] + dsc = qstrip(DATA[node "/desc"]) + gsub("\"", "\\\"", dsc) + dr = dst + sub("^.*/", "", dr) + url=" URL=" q dr ".svg" q + tip=" tooltip=" q dsc q + + + if (dupd_prefix != "") { + node = dupd_prefix node + DUPD[node] ++ + + if (parent != "") { + duppar = dupd_prefix parent + if (duppar in DUPD) + parent = duppar + } + } + + + print " " q node q " [label=" q nm " ->" nl vt nl vr nl q url tip " shape=plaintext]" >fn + if (parent != "") + print " " q parent q " -> " q node q > fn +} + +function gen_graph(rpath, v, n, N, name) +{ + name = get_name(rpath, DATA[rpath "/type"]) + fn=name + sub(".*[:/]", "", fn) + gsub("[*]", "", fn) + fn = "../" fn ".dot" + + print "digraph " q name q " {" > fn + tbl_entry(rpath, 0) + gen_sub(rpath, 1) + print "}" > fn + close(fn) +} + +function gen_graphs(rpath, v, n, N, name) +{ + v = children(N, rpath) + for(n = 1; n <= v; n++) { + if (N[n] "/hide" in NAME) + continue + gen_graph(N[n]) + } +} + +END { + gen_graphs("/lht_tree_doc/roots") + gen_graphs("/lht_tree_doc/comm") +} Index: tags/2.3.0/doc/developer/lihata_format/render/gen_flags.sh =================================================================== --- tags/2.3.0/doc/developer/lihata_format/render/gen_flags.sh (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/render/gen_flags.sh (revision 33253) @@ -0,0 +1,40 @@ +../../../../src/pcb-rnd --dump-oflags | awk ' +BEGIN { + print "ha:lht_tree_doc { ha:comm {" +} + +function close_last() +{ + if (is_open) { + print " }" + print " }" + } + is_open = 0; +} + +/^[^\t]/ { + close_last() + print " ha:flags_" $1 " {" + print " hide=1" + print " name=flags" + print " dot_group=1" + print " desc={flag bits of a " $1 "}" + print " type=ha" + print " li:children {" + is_open=1 +} + +/^[\t]/ { + bit=$1 + name=$2 + help=$0 + sub("^[\t ]*" $1 "[\t ]*" $2 "[\t ]*", "", help) + print " ha:" name " { valtype=flag; desc={" help "}}" +} + +END { + close_last() + print "} }" +} + +' Property changes on: tags/2.3.0/doc/developer/lihata_format/render/gen_flags.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/developer/lihata_format/render/html.awk =================================================================== --- tags/2.3.0/doc/developer/lihata_format/render/html.awk (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/render/html.awk (revision 33253) @@ -0,0 +1,117 @@ +BEGIN { + print "" + print "" + print "" + print " pcb-rnd developer manual - lihata file formats" + print "" + print "" + print "" +} + +function tbl_hdr(node, level) +{ + print " type:name value ver description" +} + +function get_valtype(node, vt) +{ + vt = DATA[node "/valtype"] + if (vt != "") + vt = "" vt "" + else + vt = " " + return vt +} + +function tbl_entry(node, level, parent ,nm,vt,dsc,ty,vr) +{ + if (!(node in NAME)) { + print "Error: path not found: " node > "/dev/stderr" + return + } + ty = DATA[node "/type"] + nm = get_name(node, ty, level) + vt = get_valtype(node) + vr = DATA[node "/ver"] + if (vr == "") vr = " " + dsc = qstrip(DATA[node "/desc"]) + print " " nm " " vt " " vr " " dsc +} + +function tbl_entry_link(node, dst, level, parent ,nm,vt,dsc,ty,vr) +{ + if (!(node in NAME)) { + print "Error: path not found: " node > "/dev/stderr" + return + } + if (!(dst in NAME)) { + print "Error: path not found: " dst > "/dev/stderr" + return + } + + ty = DATA[dst "/type"] + nm = get_name(node, ty, level) + vt = get_valtype(dst) + vr = DATA[dst "/ver"] + if (vr == "") vr = " " + dsc = qstrip(DATA[dst "/desc"]) + print " " nm " " vt " " vr " " dsc " -> " +} + +function gen_main(path, v, n, N) +{ + print "

" DATA[path "/type"] ":" NAME[path] "

" +# print "

" +# print qstrip(DATA[path "/desc"]) + print "

" + print "" + tbl_hdr() + tbl_entry(path, 0) + gen_sub(path, 1) + print "
" +} + +function gen_roots(rpath, v, n, N) +{ + v = children(N, rpath) + for(n = 1; n <= v; n++) { + if (N[n] "/hide" in NAME) + continue + gen_main(N[n]) + } +} + +function gen_types(path, v, n, N, node) +{ + print "" + print "" + print "
type description" + + v = children(N, path) + for(n = 1; n <= v; n++) { + node = N[n] + print "
" NAME[node] + print " " qstripnl(DATA[node]) + } + print "
" +} + + +END { + print "

File format root nodes

" + print "

Each table below describes the full tree of one of the pcb-rnd file formats, from the root." + gen_roots("/lht_tree_doc/roots") + + print "

Common subtrees

" + print "

Each table below describes a subtree that usually does not specify a whole tree (thus they are usually not a valid file on their own). These subtrees are described in a separate table because they are used from multiple other trees." + gen_roots("/lht_tree_doc/comm") + + print "

Types

" + print "

" + gen_types("/lht_tree_doc/types") + + print "

Comments

" + print "

ver column: Format version range the subtree may appear in." + print "" + print "" +} Index: tags/2.3.0/doc/developer/lihata_format/render/lht.awk =================================================================== --- tags/2.3.0/doc/developer/lihata_format/render/lht.awk (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/render/lht.awk (revision 33253) @@ -0,0 +1,62 @@ +BEGIN { + q="\"" +} + +function parent(path) +{ + sub("/[^/]*$", "", path) + return path +} + +function children(DST, path) +{ + return split(CHILDREN[path], DST, "[|]") +} + +function sy_is_recursive(path, dp) +{ + dp = DATA[path] + gsub("/[0-9]::", "/", path) + if (path ~ dp) + rturn 1 + return 0 +} + +function sy_href(path) +{ + return "#" path +} + +(($1 == "open") || ($1 == "data")) { + path=$3 + gsub("[0-9]+::", "", path) + TYPE[path] = $2 + p = parent(path) + if (CHILDREN[p] == "") + CHILDREN[p] = path + else + CHILDREN[p] = CHILDREN[p] "|" path + data=$4 + gsub("\\\\057", "/", data) + DATA[path] = data + + name=$3 + sub("^.*/", "", name) + sub(".*::", "", name) + NAME[path] = name +} + +function qstrip(s) +{ + gsub("[\\\\]+164", " ", s) + gsub("[\\\\]n", " ", s) + return s +} + +function qstripnl(s) +{ + gsub("[\\\\]+164", " ", s) + gsub("[\\\\]n", "\n", s) + return s +} + Index: tags/2.3.0/doc/developer/lihata_format/render/render.sh =================================================================== --- tags/2.3.0/doc/developer/lihata_format/render/render.sh (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/render/render.sh (revision 33253) @@ -0,0 +1,6 @@ +#!/bin/sh + +for n in ../*.lht +do + lhtflat < $n +done | tee Flat | awk -F "[\t]" -f lht.awk -f common.awk -f $1.awk Property changes on: tags/2.3.0/doc/developer/lihata_format/render/render.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/developer/lihata_format/root_board.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/root_board.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/root_board.lht (revision 33253) @@ -0,0 +1,186 @@ +ha:lht_tree_doc { ha:roots { + + ha:pcb-rnd-board-v* { + type=ha + desc { + The full, self-contained description of a printed circuit board. + This is the root of a board .lht file. The * after the v in the name + is an integer which is the format version. + } + li:children { + ha:meta { + type=ha + desc { Any meta-data that won't directly turn into physical material (e.g. copper). } + li:children { + ha:board_name { valtype=string; desc={User assigned name of the board}} + ha:grid { + type=ha + desc { User interface last grid settings } + li:children { + ha:offs_x { valtype=coord; desc={grid origin: X offset from 0;0}} + ha:offs_y { valtype=coord; desc={grid origin: Y offset from 0;0}} + ha:spacing { valtype=coord; desc={distance between two grid points both in X and Y directions }} + } + } + ha:size { + type=ha + desc { object size related settings } + li:children { + ha:x { valtype=coord; desc={drawing area size X (width)}} + ha:y { valtype=coord; desc={drawing area size Y (height)}} + ha:isle_area_nm2 { valtype=double; desc={remove polygon islands smaller than this value, specified in nm2}} + ha:thermal_scale { valtype=double; desc={scale all thermals on the board by this factor}} + } + } + ha:drc { + type=ha + desc { design rule checker settings for the old DRC } + ver {<5} + li:children { + ha:bloat { valtype=coord; desc={Minimum copper spacing}} + ha:shrink { valtype=coord; desc={Minimum overlap between validly touching copper objects}} + ha:min_width { valtype=coord; desc={Minimum copper width}} + ha:min_silk { valtype=coord; desc={Minimum silk width}} + ha:min_drill { valtype=coord; desc={Minimum drill diameter}} + ha:min_ring { valtype=coord; desc={Minimum annular ring width}} + } + } + ha:cursor { + type=ha + desc { obsolete cursor/view state } + li:children { + ha:x { valtype=coord; obs=1; desc={last position, X (horizontal)}} + ha:y { valtype=coord; obs=1; desc={last position, Y (horizontal)}} + ha:zoom { valtype=double; obs=1; desc={last view zoom factor}} + } + } + } + } + ha:layer_stack { + type=ha + desc { physical layer stack information: geometry and properties of physical layers } + li:children { + ha:groups { + type=li + desc { ordered list of physical layers from top to bottom } + li:children { + ha:INTEGER { + li:name_patterns={p={[0-9]+}} + type=ha + desc { a layer group (a physical layer of the board); the ID of the layer group is the integer in the name of the node } + li:children { + ha:name { valtype=string; desc={user assigned name of the layer group, e.g. "top copper"}} + ha:type { + type=ha + desc { a flag-list of layer type flag bits } + sy:children = {/lht_tree_doc/comm/layer_mask/children} + } + ha:name { valtype=string; ver={>=6} desc={purpose of layer groups (useful with mechanical/documentation groups}} + ha:layers { + type=li + desc { ordered list of logical layer IDs hosted by this layer group } + } + } + } + } + } + } + } + ha:font { + type=ha + desc { font kit: all fonts used on the board (if no font specified, default font will be used) } + li:children { + sy:FONT-ID {/lht_tree_doc/roots/pcb-rnd-font-v1/children/FONT-ID} + } + } + ha:styles { + type=ha + desc { routing styles hash: collection of all available routing syles } + ha:ROUTE-STYLE-NAME { + type=ha + desc { routing style: a collection of pen settings } + li:children { + ha:thickness { valtype=coord; desc={default trace thickness (affects lines and arcs)}} + ha:text_thick { valtype=coord; ver={>=6} desc={default text stroke thickness (0 means pick thickness automatically using the original algorithm)}} + ha:text_scale { valtype=coord; ver={>=6} desc={default text scaling (0 means 100%, for backward compatibility)}} + ha:clearance { valtype=coord; desc={default clearance (affects lines, arcs and polygons)}} + ha:diameter { valtype=coord; ver={<=5} desc={old round via outer diameter; removed in favor of padstack prototype based vias, see via_proto}} + ha:hole { valtype=coord; ver={<=5} desc={old round via hole diameter; removed in favor of padstack prototype based vias, see via_proto}} + ha:via_proto { valtype=integer; ver={>5} desc={padstack prototype ID used for placing new vias}} + sy:attr@dup {/lht_tree_doc/comm/attributes} + } + } + } + ha:netlists { + type=ha + desc { all available netlists } + li:children { + ha:netlist { + type=li + desc { the input netlist (as seen in the last netlist import, a.k.a. forward annotation) } + li:children { + ha:NETNAME { + type=ha + desc { a network } + li:children { + ha:conn { + type=li + desc { list of terminals connected to the network } + li:children { + ha:diameter { valtype=string; desc={refdes-terminal}} + } + } + sy:attr@dup = {/lht_tree_doc/comm/attributes_v5p} + } + } + } + } + ha:netlist_patch { + type=li + desc { a list of intentional deviations from the input netlist, a.k.a. material for back annotation } + li:children { + ha:net_info { + type=li + desc { describe the current state of a net, as seen on the input } + li:children { + ha:net { valtype=string; desc={net name; first item on the list, only once}} + ha:term { valtype=string; desc={terminal name; zero or more items starting from the second item}} + } + } + ha:add_conn { + type=ha + desc { the 'as built' network requires a new connection to be created during the back annotation } + li:children { + ha:net { valtype=string; desc={net name the terminal should be added to}} + ha:term { valtype=string; desc={terminal name}} + } + } + ha:del_conn { + type=ha + desc { the 'as built' network requires an existing connection to be removed during the back annotation } + li:children { + ha:net { valtype=string; desc={net name the terminal should be removed from}} + ha:term { valtype=string; desc={terminal name}} + } + } + ha:change_attrib { + type=ha + desc { the 'as built' network requires an attribute to be set or changed } + li:children { + ha:net { valtype=string; desc={net name whose attribute needs to be changed }} + ha:key { valtype=string; desc={key (name) of the attribute}} + ha:val { valtype=string; desc={new value of the attribute}} + } + } + } + } + } + } + sy:conf = {/lht_tree_doc/roots/pcb-rnd-conf-v1} + sy:data = {/lht_tree_doc/comm/data} + sy:pixmaps = {/lht_tree_doc/comm/pixmaps} + sy:attributes@dup = {/lht_tree_doc/comm/attributes} + } + } + +}} Index: tags/2.3.0/doc/developer/lihata_format/root_buffer.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/root_buffer.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/root_buffer.lht (revision 33253) @@ -0,0 +1,13 @@ +ha:lht_tree_doc { ha:roots { + + ha:pcb-rnd-buffer-v* { + type=li + desc={buffer file containing a whole paste buffer with bound layers} + ver = {>=6} + li:children { + ha:x = { valtype=coord; desc={buffer origin point, X coordinate}} + ha:y = { valtype=coord; desc={buffer origin point, Y coordinate}} + sy:data = {/lht_tree_doc/comm/data} + } + } +}} Index: tags/2.3.0/doc/developer/lihata_format/root_conf.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/root_conf.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/root_conf.lht (revision 33253) @@ -0,0 +1,22 @@ +ha:lht_tree_doc { ha:roots { + + ha:pcb-rnd-conf-v1 { + type=li + desc=complete pcb-rnd configuration tree + li:children { + ha:overwrite { + type=ha + desc={overwrite values while merging; children: a full or partial config tree} + } + ha:prepend { + type=ha + desc={prepend values while merging; children: a full or partial config tree} + } + ha:append { + type=ha + desc={append values while merging; children: a full or partial config tree} + } + } + } + +}} Index: tags/2.3.0/doc/developer/lihata_format/root_drc_query.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/root_drc_query.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/root_drc_query.lht (revision 33253) @@ -0,0 +1,41 @@ +ha:lht_tree_doc { ha:roots { + + ha:pcb-rnd-drc-query-v* { + type=ha + desc={pcb-rnd drc_query script} + li:children { + ha:defs { + type=li + desc={Definitions of user tunable constants} + li:children { + ha:name { + type=ha + desc={each entry is identified by an unique name} + li:children { + ha:default { valtype=string; desc={default value} } + ha:type { valtype=string; desc={data type of the constant (a valid conf system type name, e.g. real, coord)} } + ha:desc { valtype=string; desc={human readable description of the purpose of the constant} } + } + } + } + } + ha:rules { + type=li + desc={DRC rules} + li:children { + ha:name { + type=ha + desc={each entry is identified by an unique name} + li:children { + ha:type { valtype=string; desc={violation type (for grouping violations in the drc report)} } + ha:title { valtype=string; desc={title (short summary) of the violation} } + ha:desc { valtype=string; desc={human readable description of the violation, with hints on how to resolve it} } + ha:query { valtype=string; desc={query script to execute for finding violations} } + } + } + } + } + } + } + +}} Index: tags/2.3.0/doc/developer/lihata_format/root_font.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/root_font.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/root_font.lht (revision 33253) @@ -0,0 +1,69 @@ +ha:lht_tree_doc { ha:roots { + + ha:pcb-rnd-font-v1 { + type=li + desc={font description} + li:children { + ha:FONT-ID { + type=ha + li:name_patterns={p={geda_pcb}; p={[0-9]+}} + desc { the full description of a font; the node name is the integer font id or "geda_pcb" for font 0 (for historical reasons); the name is used only to make each node unique, the ID is also a field below } + li:children { + ha:cell_height { valtype=coord; desc={height of the tallest glyph}} + ha:cell_width { valtype=coord; desc={width of the widest glyph}} + ha:id { valtype=integer; desc={unique font ID within the fontkit; fonts are referenced by ID}} + ha:name { valtype=string; desc={user specified, user readable font name}} + ha:symbols { + type=ha + desc { a collections of glyphs availbale in the font } + li:children { + ha:CHARACTER { + type=ha + li:name_patterns={p={.}} + desc { Description of a glyph (symbol). Node name is a signel ASCII character or is of format &xx where xx is a hex digit of the ASCII code of the character. Characters that must use the hex version are: codes below 33 or over 126, &, #, {, \}, /, :, ;, =, \\, :} + li:children { + ha:height { valtype=coord; desc={height of the glyph}} + ha:width { valtype=coord; desc={width of the glyph}} + ha:delta { valtype=coord; desc={extra space always inserted after the current symbol, before the next character}} + ha:objects { + type=li + desc={objects that make up the symbol; IDs are per symbol local IDs counted from 0} + li:children { + ha:line.ID { + type=ha + desc={round cap line, simplified} + li:children { + ha:x1 = { valtype=coord; desc={line first endpoint, horizontal offset }} + ha:y1 = { valtype=coord; desc={line first endpoint, vertical offset }} + ha:x2 = { valtype=coord; desc={line second endpoint, horizontal offset }} + ha:y2 = { valtype=coord; desc={line second endpoint, vertical offset }} + ha:thickness = { valtype=coord; desc={width of the line }} + } + } + ha:simplearc.ID { + type=ha + desc={round cap arc, simplified } + li:children { + ha:x = { valtype=coord; desc={center, X coord}} + ha:y = { valtype=coord; desc={center, Y coord}} + ha:r = { valtype=coord; desc={radius (of the centerline of the arc) }} + ha:thickness = { valtype=coord; desc={width of the pen the arc is drawn with }} + ha:astart = { valtype=angle; desc={ start angle}} + ha:adelta = { valtype=angle; desc={ delta angle}} + } + } + ha:simplepoly.ID { + type=li + desc={round cap arc, simplified; contains a flat list of coords; each coord pair is an x;y corner of the outline of the polygon (odd indices are x coords, even indices are y coords) } + } + } + } + } + } + } + } + } + } + } + } +}} \ No newline at end of file Index: tags/2.3.0/doc/developer/lihata_format/root_log.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/root_log.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/root_log.lht (revision 33253) @@ -0,0 +1,26 @@ +ha:lht_tree_doc { ha:roots { + + ha:pcb-rnd-log-v* { + type=ha + desc={pcb-rnd message log dump} + li:children { + ha:entries { + type=li + desc={list of message log entries} + li:children { + ha:ID { + type=ha + desc={each entry is identified by an unique unsigned long int ID} + li:children { + ha:stamp { valtype=string; desc={UNIX time stamp of entry creation} } + ha:level { valtype=integer; desc={log level enum value (see error.h)} } + ha:seen { valtype=integer; desc={1 if the message got displayed} } + ha:str { valtype=string; desc={log message} } + } + } + } + } + } + } + +}} Index: tags/2.3.0/doc/developer/lihata_format/root_menu.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/root_menu.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/root_menu.lht (revision 33253) @@ -0,0 +1,232 @@ +ha:lht_tree_doc { + +ha:roots { + ha:menu { + type=ha + name={rnd-menu-v1} + desc={Menu file} + li:children { + ha:mouse { + type=li + desc={mouse bindings} + li:children { + ha:left { + type=li + desc={actions to execute on left button click} + sy:children = {/lht_tree_doc/comm/mouse_actions/children} + } + ha:middle { + type=li + desc={actions to execute on middle button click} + sy:children = {/lht_tree_doc/comm/mouse_actions/children} + } + ha:right { + type=li + desc={actions to execute on right button click} + sy:children = {/lht_tree_doc/comm/mouse_actions/children} + } + ha:scroll-up { + type=li + desc={actions to execute on scroll wheel scolling up event} + sy:children = {/lht_tree_doc/comm/mouse_actions_scroll/children} + } + ha:scroll-down { + type=li + desc={actions to execute on scroll wheel scolling down event} + sy:children = {/lht_tree_doc/comm/mouse_actions_scroll/children} + } + } + } + ha:main_menu { + type=li + desc={root of the main pull-down menu system; ordered list of main menus} + li:children { + ha:MENUNAME { + type=ha + desc={main menu name, e.g. "File"} + li:children { + sy:m@dup = {/lht_tree_doc/comm/submenu/children/m} + sy:submenu = {/lht_tree_doc/comm/submenu} + } + } + } + } + ha:popups { + type=li + desc={collection of popup menus} + li:children { + ha:POPUPNAME { + type=ha + desc={popup menu name, e.g. "layer" for layer context menu} + li:children { + sy:m@dup = {/lht_tree_doc/comm/submenu/children/m} + sy:submenu = {/lht_tree_doc/comm/submenu} + } + } + } + } + ha:toolbar_static { + type=li + desc={ordered list (from left to right) of toolbar icons} + li:children { + ha:TOOLNAME { + type=ha + desc={tool menu name, e.g. "polyhole" for the polygon hole draw tool} + li:children { + ha:tip { type=te; desc={tooltip for the icon button} } + } + } + } + } + ha:anchored { + type=li + desc={list of submenus; child of submenu would be copied and appended after ever occurance of the ANCHORNAME } + li:children { + ha:@ANCHORNAME { + type=ha + desc={list menu items/subtrees to be copied after each @ANCHORNAME in the menu system} + li:children { + sy:submenu = {/lht_tree_doc/comm/submenu} + } + } + } + } + ha:scripts { + type=ha + desc={ a collection of named action scripts that can be symnlinked from elsewhere in the menu file } + li:children { + ha:SCRIPTNAME { + type=li + desc={action script} + } + } + } + } + } + + ha:menu_patch { + type=ha + name={rnd-menu-patch-v1} + desc={Menu patch instructions} + li:children { + ha:prio { + type=te + desc={optional; integer priority value used in ordering the menu files/patches before merging } + } + ha:patch { + type=li + desc={ordered list of patch instructions} + li:children { + ha:append_menu { + type=ha + desc={append (or overwrite) a submenu tree at a given path} + li:children { + sy:path = {/lht_tree_doc/comm/path} + sy:submenu = {/lht_tree_doc/comm/submenu} + } + } + ha:remove_menu { + type=ha + desc={remove a submenu or menu item at a given path} + li:children { + sy:path = {/lht_tree_doc/comm/path} + } + } + ha:overwrite_menu_props { + type=ha + desc={overwrite properties of an existing menu} + li:children { + sy:path = {/lht_tree_doc/comm/path} + ha:props = {type=ha; desc={same as menu properties documented at LEAFSUBMENUNAME}} + } + } + } + } + } + } +} + +ha:comm { + ha:mouse_actions { + hide=1 + li:children { + ha:press { type=li; desc={actions to execute on mouse button press when no modifier is pressed} } + ha:press-shift { type=li; desc={actions to execute on mouse button press when shift is pressed} } + ha:press-ctrl { type=li; desc={actions to execute on mouse button press when control is pressed} } + ha:release { type=li; desc={actions to execute on mouse button release when no modifier is pressed} } + ha:release-shift { type=li; desc={actions to execute on mouse button release when shift is pressed} } + ha:release-ctrl { type=li; desc={actions to execute on mouse button release when control is pressed} } + } + } + ha:mouse_actions_scroll { + hide=1 + li:children { + ha:press { type=li; desc={actions to execute on mouse button press when no modifier is pressed} } + ha:press-shift { type=li; desc={actions to execute on mouse button press when shift is pressed} } + ha:press-ctrl { type=li; desc={actions to execute on mouse button press when control is pressed} } + } + } + + ha:submenu { + type=li + desc={ordered list of menu items for a submenu} + li:children { + ha:m = {valtype=string; desc={mnemonic: single character that should be underlined and used as a hot key in the menu name}} + ha:- = {valtype=none; desc={horizontal separator}} + ha:@ANCHOR = {valtype=none; desc={an anchor is an invisible placeholder where a dynamically generated set of menu items should be inserted runtime}} + ha:SUBSUBMENUNAME = { + type=ha + desc={sub-submenu item: opens a new level of submenu when clicked} + li:children { + sy:m@dup = {/lht_tree_doc/comm/submenu/children/m} + sy:submenu = {/lht_tree_doc/comm/submenu} + } + } + ha:LEAFSUBMENUNAME = { + type=ha + desc={leaf submenu item: executes an action when clicked} + li:children { + sy:m@dup = {/lht_tree_doc/comm/submenu/children/m} + ha:a1 { + type=li + name=a + desc={list of alternative hotkey sequences to activate the menu} + } + ha:a2 { + valtype=string + name=a + desc={a single hotkey sequences to activate the menu} + } + ha:action1 { + type=li + name=action + desc={list of actions to execute when the menu is activated} + } + ha:action2 { + valtype=string + name=action + desc={a single action to execute when the menu is activated} + } + ha:tip { + valtype=string + desc={tooltip text} + } + ha:checked { + valtype=string + desc={the menu item has a checkbox; value is the action to execute to determine whether the menu item's checkbox is checked or not} + } + ha:update_on { + valtype=string + desc={path of a conf node that triggers re-evaluation of the checkbox state} + } + } + } + } + } + ha:path { + type=te + desc={path to a menu item, starting from the menu tree root; e.g. /main_menu/File/Revert } + } +} +} + Index: tags/2.3.0/doc/developer/lihata_format/root_padstack.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/root_padstack.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/root_padstack.lht (revision 33253) @@ -0,0 +1,11 @@ +ha:lht_tree_doc { ha:roots { + + ha:pcb-rnd-padstack-v* { + type=li + desc={A singe padstack prototype} + ver = {>=6} + li:children { + sy:ps_proto_v6.0 = {/lht_tree_doc/comm/data/children/padstack_prototypes/children/ps_proto_v4.PID} + } + } +}} Index: tags/2.3.0/doc/developer/lihata_format/root_project.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/root_project.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/root_project.lht (revision 33253) @@ -0,0 +1,54 @@ +ha:lht_tree_doc { ha:roots { + + ha:coraleda-project-v1 { + type=ha + desc={Project file root. Except for "common", each software package should create a single subtree under the root; the subtree shall be named after the software package } + li:children { + ha:common { + type=ha + desc={project settings that should be common to all software packages} + li:children { + ha:name { valtype=string; desc={long name of the project }} + ha:desc { valtype=string; desc={description of the project }} + ha:url { valtype=string; desc={homepage of the project }} + ha:vcs { valtype=string; desc={main vcs url for the project }} + ha:contact { valtype=string; desc={author/maintainer contact info }} + ha:files { + type=li + desc={ordered list of source files being used by the project} + li:children { + ha:NAME { + type=ha + desc={a project member file} + li:children { + ha:path { valtype=string; desc={path to the file, relative to the project file }} + ha:desc { valtype=string; desc={description of the file }} + ha:type { valtype=string; desc={optional: type of the file; one of: "pcb", "schematic", "doc" }} + } + } + } + } + ha:libs { + type=li + desc={ordered list of libraries the project depends on} + li:children { + ha:NAME { + type=ha + desc={a library} + li:children { + ha:path { valtype=string; desc={path to the library, relative to the project file; all files and subdirectories under the root, recursively, are considered part of the library (must not be used together with url) }} + ha:url { valtype=string; desc={url to the library (must not be used together with path) }} + ha:desc { valtype=string; desc={description of the library }} + ha:type { valtype=string; desc={optional: type of the library; one of: "footprint" (for pcb design), "symbol" (for schematic), "sim" (models and subcircuits for e.g. spice simulation) }} + } + } + } + } + } + } + sy:pcb-rnd-conf-v1 = {/lht_tree_doc/roots/pcb-rnd-conf-v1} + } + } + +}} + Index: tags/2.3.0/doc/developer/lihata_format/root_subc.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/root_subc.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/root_subc.lht (revision 33253) @@ -0,0 +1,21 @@ +ha:lht_tree_doc { ha:roots { + + ha:pcb-rnd-subcircuit-v* { + type=li + desc={footprint file containing a single subcircuit} + li:children { + ha:subc.ID { + type=ha + desc={an instance (full copy) of a subcircuit} + ver = {>=3} + li:children { + ha:uid = { valtype=minuid; desc={UID assigned by the user to track subc history }} + sy:attr@dup = {/lht_tree_doc/comm/attributes} + sy:flags@dup = {/lht_tree_doc/comm/flags_subcircuit} + sy:data = {/lht_tree_doc/comm/data} + } + } + sy:pixmaps = {/lht_tree_doc/comm/pixmaps} + } + } +}} \ No newline at end of file Index: tags/2.3.0/doc/developer/lihata_format/root_view.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/root_view.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/root_view.lht (revision 33253) @@ -0,0 +1,31 @@ +ha:lht_tree_doc { ha:roots { + + ha:view-list-v* { + type=li + desc={a list of view items (locations and objects to highlight on the board, e.g. for DRC violations)} + li:children { + ha:view.ID { + type=ha + desc={a view item; ID is a 32 bit signed integer, unique within the view list} + li:children { + ha:type { valtype=string; desc={free form short text for type of the entry; the GUI may group items by type} } + ha:title { valtype=string; desc={free form short text for the title of the entry; the GUI typically uses this in brief listings} } + ha:description { valtype=string; desc={free form long text for the detailed description of the entry } } + ha:bbox { type=li; valtype=coord; desc={optional: 4 coordinates in x1;y1;x2;y2 order that describes the bounding box of the view in board space coordinates; when available, the preview or go-to will use this for view box} } + ha:xy { type=li; valtype=coord; desc={optional: 2 coordinates in x;y order that describes a specific board location} } + ha:objs.ID { + type=li + desc={a group of related objects; there should be at most two groups with ID 0 and 1. These objects are often highlighted in red and blue.} + li:children { + ha:id { + type=li + desc={objects are specified as a list of object IDs (32 bit integers)} + } + } + } + } + } + } + } + +}} Index: tags/2.3.0/doc/developer/lihata_format/submenu.svg =================================================================== --- tags/2.3.0/doc/developer/lihata_format/submenu.svg (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/submenu.svg (revision 33253) @@ -0,0 +1,256 @@ + + + + + + +li:submenu + + + +/lht_tree_doc/comm/submenu + + +li:submenu + + + + + +/lht_tree_doc/comm/submenu/children/m + + +m +string + + + + + +/lht_tree_doc/comm/submenu->/lht_tree_doc/comm/submenu/children/m + + + + + +/lht_tree_doc/comm/submenu/children/- + + +- +none + + + + + +/lht_tree_doc/comm/submenu->/lht_tree_doc/comm/submenu/children/- + + + + + +/lht_tree_doc/comm/submenu/children/@ANCHOR + + +@ANCHOR +none + + + + + +/lht_tree_doc/comm/submenu->/lht_tree_doc/comm/submenu/children/@ANCHOR + + + + + +/lht_tree_doc/comm/submenu/children/SUBSUBMENUNAME + + +ha:SUBSUBMENUNAME + + + + + +/lht_tree_doc/comm/submenu->/lht_tree_doc/comm/submenu/children/SUBSUBMENUNAME + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME + + +ha:LEAFSUBMENUNAME + + + + + +/lht_tree_doc/comm/submenu->/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME + + + + + +dup63_/lht_tree_doc/comm/submenu/children/m + + +m +string + + + + + +/lht_tree_doc/comm/submenu/children/SUBSUBMENUNAME->dup63_/lht_tree_doc/comm/submenu/children/m + + + + + +dup64_/lht_tree_doc/comm/submenu/children/SUBSUBMENUNAME/children/submenu + +submenu -> + + + + + +/lht_tree_doc/comm/submenu/children/SUBSUBMENUNAME->dup64_/lht_tree_doc/comm/submenu/children/SUBSUBMENUNAME/children/submenu + + + + + +dup65_/lht_tree_doc/comm/submenu/children/m + + +m +string + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME->dup65_/lht_tree_doc/comm/submenu/children/m + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/a1 + + +li:a + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME->/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/a1 + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/a2 + + +a +string + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME->/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/a2 + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/action1 + + +li:action + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME->/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/action1 + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/action2 + + +action +string + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME->/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/action2 + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/tip + + +tip +string + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME->/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/tip + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/checked + + +checked +string + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME->/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/checked + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/update_on + + +update_on +string + + + + + +/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME->/lht_tree_doc/comm/submenu/children/LEAFSUBMENUNAME/children/update_on + + + + + Index: tags/2.3.0/doc/developer/lihata_format/tree.html =================================================================== --- tags/2.3.0/doc/developer/lihata_format/tree.html (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/tree.html (revision 33253) @@ -0,0 +1,786 @@ + + + + pcb-rnd developer manual - lihata file formats + + + +

File format root nodes

+

Each table below describes the full tree of one of the pcb-rnd file formats, from the root. +

ha:pcb-rnd-board-v*

+

+ +
type:name value ver description +
ha:pcb-rnd-board-v*     The full, self-contained description of a printed circuit board. This is the root of a board .lht file. The * after the v in the name is an integer which is the format version. +
 ha:meta     Any meta-data that won't directly turn into physical material (e.g. copper). +
  board_name string   User assigned name of the board +
  ha:grid     User interface last grid settings +
   offs_x coord   grid origin: X offset from 0;0 +
   offs_y coord   grid origin: Y offset from 0;0 +
   spacing coord   distance between two grid points both in X and Y directions +
  ha:size     object size related settings +
   x coord   drawing area size X (width) +
   y coord   drawing area size Y (height) +
   isle_area_nm2 double   remove polygon islands smaller than this value, specified in nm2 +
   thermal_scale double   scale all thermals on the board by this factor +
  ha:drc   <5 design rule checker settings for the old DRC +
   bloat coord   Minimum copper spacing +
   shrink coord   Minimum overlap between validly touching copper objects +
   min_width coord   Minimum copper width +
   min_silk coord   Minimum silk width +
   min_drill coord   Minimum drill diameter +
   min_ring coord   Minimum annular ring width +
  ha:cursor     obsolete cursor/view state +
   x coord   last position, X (horizontal) +
   y coord   last position, Y (horizontal) +
   zoom double   last view zoom factor +
 ha:layer_stack     physical layer stack information: geometry and properties of physical layers +
  li:groups     ordered list of physical layers from top to bottom +
   ha:INTEGER     a layer group (a physical layer of the board); the ID of the layer group is the integer in the name of the node +
    name string >=6 purpose of layer groups (useful with mechanical/documentation groups +
    ha:type     a flag-list of layer type flag bits +
     top flag   location: top side +
     bottom flag   location: bottom side +
     intern flag   location: internal +
     logical flag   location: logical (not in the actual stackup) +
     copper flag   material: copper +
     silk flag   material: silk +
     mask flag   material: mask +
     paste flag   material: paste +
     outline flag   "material": router path for board outline; normally for the outer contour, sometimes for biggish inner cutouts as well) +
     mech flag   "material": various mechanical fabbing instructions, e.g. slots; the purpose field provides more detail about the use +
     doc flag   "material": documentation, either for the user and for pcb-rnd or both (the purpose field shoudl tell); e.g. assembly documentation for the user, keepout for the user and DRC +
     substrate flag   material: substrate or insulator +
    name string >=6 purpose of layer groups (useful with mechanical/documentation groups +
    li:layers     ordered list of logical layer IDs hosted by this layer group +
 ha:font     font kit: all fonts used on the board (if no font specified, default font will be used) +
  ha:FONT-ID     the full description of a font; the node name is the integer font id or "geda_pcb" for font 0 (for historical reasons); the name is used only to make each node unique, the ID is also a field below -> +
 ha:styles     routing styles hash: collection of all available routing syles +
 ha:netlists     all available netlists +
  li:netlist     the input netlist (as seen in the last netlist import, a.k.a. forward annotation) +
   ha:NETNAME     a network +
    li:conn     list of terminals connected to the network +
     diameter string   refdes-terminal +
    ha:attributes   >=5 a hash of attribute key=value pairs +
     attrib-key string   attribute value +
  li:netlist_patch     a list of intentional deviations from the input netlist, a.k.a. material for back annotation +
   li:net_info     describe the current state of a net, as seen on the input +
    net string   net name; first item on the list, only once +
    term string   terminal name; zero or more items starting from the second item +
   ha:add_conn     the 'as built' network requires a new connection to be created during the back annotation +
    net string   net name the terminal should be added to +
    term string   terminal name +
   ha:del_conn     the 'as built' network requires an existing connection to be removed during the back annotation +
    net string   net name the terminal should be removed from +
    term string   terminal name +
   ha:change_attrib     the 'as built' network requires an attribute to be set or changed +
    net string   net name whose attribute needs to be changed +
    key string   key (name) of the attribute +
    val string   new value of the attribute +
 li:conf     complete pcb-rnd configuration tree -> +
 ha:data     Layers and global objects of the board -> +
 ha:pixmaps   >=7 Collection of all unique pixmaps used by the board or footprint -> +
 ha:attributes     a hash of attribute key=value pairs +
  attrib-key string   attribute value +
+

li:pcb-rnd-buffer-v*

+

+ +
type:name value ver description +
li:pcb-rnd-buffer-v*   >=6 buffer file containing a whole paste buffer with bound layers +
 x coord   buffer origin point, X coordinate +
 y coord   buffer origin point, Y coordinate +
 ha:data     Layers and global objects of the board -> +
+

li:pcb-rnd-conf-v1

+

+ +
type:name value ver description +
li:pcb-rnd-conf-v1     complete pcb-rnd configuration tree +
 ha:overwrite     overwrite values while merging; children: a full or partial config tree +
 ha:prepend     prepend values while merging; children: a full or partial config tree +
 ha:append     append values while merging; children: a full or partial config tree +
+

ha:pcb-rnd-drc-query-v*

+

+ +
type:name value ver description +
ha:pcb-rnd-drc-query-v*     pcb-rnd drc_query script +
 li:defs     Definitions of user tunable constants +
  ha:name     each entry is identified by an unique name +
   default string   default value +
   type string   data type of the constant (a valid conf system type name, e.g. real, coord) +
   desc string   human readable description of the purpose of the constant +
 li:rules     DRC rules +
  ha:name     each entry is identified by an unique name +
   type string   violation type (for grouping violations in the drc report) +
   title string   title (short summary) of the violation +
   desc string   human readable description of the violation, with hints on how to resolve it +
   query string   query script to execute for finding violations +
+

li:pcb-rnd-font-v1

+

+ +
type:name value ver description +
li:pcb-rnd-font-v1     font description +
 ha:FONT-ID     the full description of a font; the node name is the integer font id or "geda_pcb" for font 0 (for historical reasons); the name is used only to make each node unique, the ID is also a field below +
  cell_height coord   height of the tallest glyph +
  cell_width coord   width of the widest glyph +
  id integer   unique font ID within the fontkit; fonts are referenced by ID +
  name string   user specified, user readable font name +
  ha:symbols     a collections of glyphs availbale in the font +
   ha:CHARACTER     Description of a glyph (symbol). Node name is a signel ASCII character or is of format &xx where xx is a hex digit of the ASCII code of the character. Characters that must use the hex version are: codes below 33 or over 126, &, #, {, }, /, :, ;, =, \, : +
    height coord   height of the glyph +
    width coord   width of the glyph +
    delta coord   extra space always inserted after the current symbol, before the next character +
    li:objects     objects that make up the symbol; IDs are per symbol local IDs counted from 0 +
     ha:line.ID     round cap line, simplified +
      x1 coord   line first endpoint, horizontal offset +
      y1 coord   line first endpoint, vertical offset +
      x2 coord   line second endpoint, horizontal offset +
      y2 coord   line second endpoint, vertical offset +
      thickness coord   width of the line +
     ha:simplearc.ID     round cap arc, simplified +
      x coord   center, X coord +
      y coord   center, Y coord +
      r coord   radius (of the centerline of the arc) +
      thickness coord   width of the pen the arc is drawn with +
      astart angle   start angle +
      adelta angle   delta angle +
     li:simplepoly.ID     round cap arc, simplified; contains a flat list of coords; each coord pair is an x;y corner of the outline of the polygon (odd indices are x coords, even indices are y coords) +
+

ha:pcb-rnd-log-v*

+

+ +
type:name value ver description +
ha:pcb-rnd-log-v*     pcb-rnd message log dump +
 li:entries     list of message log entries +
  ha:ID     each entry is identified by an unique unsigned long int ID +
   stamp string   UNIX time stamp of entry creation +
   level integer   log level enum value (see error.h) +
   seen integer   1 if the message got displayed +
   str string   log message +
+

ha:menu

+

+ +
type:name value ver description +
ha:rnd-menu-v1     Menu file +
 li:mouse     mouse bindings +
  li:left     actions to execute on left button click +
   li:press     actions to execute on mouse button press when no modifier is pressed +
   li:press-shift     actions to execute on mouse button press when shift is pressed +
   li:press-ctrl     actions to execute on mouse button press when control is pressed +
   li:release     actions to execute on mouse button release when no modifier is pressed +
   li:release-shift     actions to execute on mouse button release when shift is pressed +
   li:release-ctrl     actions to execute on mouse button release when control is pressed +
  li:middle     actions to execute on middle button click +
   li:press     actions to execute on mouse button press when no modifier is pressed +
   li:press-shift     actions to execute on mouse button press when shift is pressed +
   li:press-ctrl     actions to execute on mouse button press when control is pressed +
   li:release     actions to execute on mouse button release when no modifier is pressed +
   li:release-shift     actions to execute on mouse button release when shift is pressed +
   li:release-ctrl     actions to execute on mouse button release when control is pressed +
  li:right     actions to execute on right button click +
   li:press     actions to execute on mouse button press when no modifier is pressed +
   li:press-shift     actions to execute on mouse button press when shift is pressed +
   li:press-ctrl     actions to execute on mouse button press when control is pressed +
   li:release     actions to execute on mouse button release when no modifier is pressed +
   li:release-shift     actions to execute on mouse button release when shift is pressed +
   li:release-ctrl     actions to execute on mouse button release when control is pressed +
  li:scroll-up     actions to execute on scroll wheel scolling up event +
   li:press     actions to execute on mouse button press when no modifier is pressed +
   li:press-shift     actions to execute on mouse button press when shift is pressed +
   li:press-ctrl     actions to execute on mouse button press when control is pressed +
  li:scroll-down     actions to execute on scroll wheel scolling down event +
   li:press     actions to execute on mouse button press when no modifier is pressed +
   li:press-shift     actions to execute on mouse button press when shift is pressed +
   li:press-ctrl     actions to execute on mouse button press when control is pressed +
 li:main_menu     root of the main pull-down menu system; ordered list of main menus +
  ha:MENUNAME     main menu name, e.g. "File" +
   m string   mnemonic: single character that should be underlined and used as a hot key in the menu name +
   li:submenu     ordered list of menu items for a submenu -> +
 li:popups     collection of popup menus +
  ha:POPUPNAME     popup menu name, e.g. "layer" for layer context menu +
   m string   mnemonic: single character that should be underlined and used as a hot key in the menu name +
   li:submenu     ordered list of menu items for a submenu -> +
 li:toolbar_static     ordered list (from left to right) of toolbar icons +
  ha:TOOLNAME     tool menu name, e.g. "polyhole" for the polygon hole draw tool +
   te:tip     tooltip for the icon button +
 li:anchored     list of submenus; child of submenu would be copied and appended after ever occurance of the ANCHORNAME +
  ha:@ANCHORNAME     list menu items/subtrees to be copied after each @ANCHORNAME in the menu system +
   li:submenu     ordered list of menu items for a submenu -> +
 ha:scripts     a collection of named action scripts that can be symnlinked from elsewhere in the menu file +
  li:SCRIPTNAME     action script +
+

ha:menu_patch

+

+ +
type:name value ver description +
ha:rnd-menu-patch-v1     Menu patch instructions +
 te:prio     optional; integer priority value used in ordering the menu files/patches before merging +
 li:patch     ordered list of patch instructions +
  ha:append_menu     append (or overwrite) a submenu tree at a given path +
   te:path     path to a menu item, starting from the menu tree root; e.g. /main_menu/File/Revert -> +
   li:submenu     ordered list of menu items for a submenu -> +
  ha:remove_menu     remove a submenu or menu item at a given path +
   te:path     path to a menu item, starting from the menu tree root; e.g. /main_menu/File/Revert -> +
  ha:overwrite_menu_props     overwrite properties of an existing menu +
   te:path     path to a menu item, starting from the menu tree root; e.g. /main_menu/File/Revert -> +
   ha:props     same as menu properties documented at LEAFSUBMENUNAME +
+

li:pcb-rnd-padstack-v*

+

+ +
type:name value ver description +
li:pcb-rnd-padstack-v*   >=6 A singe padstack prototype +
 ha:ps_proto_v6.0     padstack prototype specification, as introduced in lihata board v4 -> +
+

ha:coraleda-project-v1

+

+ +
type:name value ver description +
ha:coraleda-project-v1     Project file root. Except for "common", each software package should create a single subtree under the root; the subtree shall be named after the software package +
 ha:common     project settings that should be common to all software packages +
  name string   long name of the project +
  desc string   description of the project +
  url string   homepage of the project +
  vcs string   main vcs url for the project +
  contact string   author/maintainer contact info +
  li:files     ordered list of source files being used by the project +
   ha:NAME     a project member file +
    path string   path to the file, relative to the project file +
    desc string   description of the file +
    type string   optional: type of the file; one of: "pcb", "schematic", "doc" +
  li:libs     ordered list of libraries the project depends on +
   ha:NAME     a library +
    path string   path to the library, relative to the project file; all files and subdirectories under the root, recursively, are considered part of the library (must not be used together with url) +
    url string   url to the library (must not be used together with path) +
    desc string   description of the library +
    type string   optional: type of the library; one of: "footprint" (for pcb design), "symbol" (for schematic), "sim" (models and subcircuits for e.g. spice simulation) +
 li:pcb-rnd-conf-v1     complete pcb-rnd configuration tree -> +
+

li:pcb-rnd-subcircuit-v*

+

+ +
type:name value ver description +
li:pcb-rnd-subcircuit-v*     footprint file containing a single subcircuit +
 ha:subc.ID   >=3 an instance (full copy) of a subcircuit +
  uid minuid   UID assigned by the user to track subc history +
  ha:attributes     a hash of attribute key=value pairs +
   attrib-key string   attribute value +
  ha:flags     flag bits of a subcircuit +
   found flag   If set, this object has been found by FindConnection() +
   selected flag   Set when the object is selected. +
   drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
   exportsel flag   Set for objects that should be exported in a partial export. +
   lock flag   Set for locked objects. +
   nonetlist flag   subcircuit is not on the netlist and should not interfere with the netlist +
   termname flag   when set the names of pins are shown. +
   floater flag   subc part can be moved after subc placing +
  ha:data     Layers and global objects of the board -> +
 ha:pixmaps   >=7 Collection of all unique pixmaps used by the board or footprint -> +
+

li:view-list-v*

+

+ +
type:name value ver description +
li:view-list-v*     a list of view items (locations and objects to highlight on the board, e.g. for DRC violations) +
 ha:view.ID     a view item; ID is a 32 bit signed integer, unique within the view list +
  type string   free form short text for type of the entry; the GUI may group items by type +
  title string   free form short text for the title of the entry; the GUI typically uses this in brief listings +
  description string   free form long text for the detailed description of the entry +
  li:bbox coord   optional: 4 coordinates in x1;y1;x2;y2 order that describes the bounding box of the view in board space coordinates; when available, the preview or go-to will use this for view box +
  li:xy coord   optional: 2 coordinates in x;y order that describes a specific board location +
  li:objs.ID     a group of related objects; there should be at most two groups with ID 0 and 1. These objects are often highlighted in red and blue. +
   li:id     objects are specified as a list of object IDs (32 bit integers) +
+

Common subtrees

+

Each table below describes a subtree that usually does not specify a whole tree (thus they are usually not a valid file on their own). These subtrees are described in a separate table because they are used from multiple other trees. +

ha:data

+

+ +
type:name value ver description +
ha:data     Layers and global objects of the board +
 li:objects     List of global (non-layer/multi-layer) objects +
  ha:padstack_ref.ID   >=4 a padstack reference (instance) placed on the board (e.g. used as a via) +
   proto integer   padstack prototype ID to use, from the parent data's proto list +
   x coord   place padstack with origin at this horizontal coordinate +
   y coord   place padstack with origin at this vertical coordinate +
   clearance coord   global clearance; if non-zero, overrides local (per shape) clearance +
   rot angle   rotation angle in degrees +
   xmirror integer   0 or 1; if 1, mirror all shapes over the x (horizontal) axis (so that y coords are flipped) +
   smirror integer   0 or 1; if 1, mirror the layer stackup: bottom becomes top, top becomes bottom (a.k.a. "place on the other side") +
   ha:attributes     a hash of attribute key=value pairs +
    attrib-key string   attribute value +
   ha:flags     flag bits of a padstack +
    found flag   If set, this object has been found by FindConnection() +
    hole flag   For pins and vias, this flag means that the pin or via is a hole without a copper annulus. +
    clearline flag   For lines and arcs, the line/arc will clear polygons instead of connecting to them. +
    selected flag   Set when the object is selected. +
    auto flag   For lines and vias, indicates that these were created by the autorouter. +
    warn flag   For pins, vias, and pads, set to indicate a warning. +
    drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
    exportsel flag   Set for objects that should be exported in a partial export. +
    lock flag   Set for locked objects. +
    termname flag   when set the names of pins are shown. +
    floater flag   subc part can be moved after subc placing +
   li:thermal     list of thermal shapes, per layer +
    li:LAYERID     integer layer ID the thermal affects; each word is a boolean flag that is either present on the list or is missing; only one shape may be present +
     on none   thermal is present on this layer; if not present, all other thermal flags are ignored on this layer +
     diag none   thermal graphics is not axis aligned but diagonal (rotated by 45 degrees) +
     round none   shape: rounded edge fingers +
     sharp none   shape: sharp edge fingers +
     solid none   shape: no thermal relief, solid connection without clearance +
     noshape none >=6 shape: special: omit copper shape of the padstack on this layer +
  ha:via.ID   <=4 an old via object (loaded as padstack in the new model) +
   x coord   place padstack with origin at this horizontal coordinate +
   y coord   place padstack with origin at this vertical coordinate +
   thickness coord   copper shape dimension (diameter) +
   clearance coord   copper clearance around the copper shape +
   mask coord   mask cutout shape dimension (diameter) +
   hole coord   drill/hole diameter +
   name string   optional name attribute +
   number string   for a pin (or to-be-pin) this is the terminal ID +
   ha:attributes     a hash of attribute key=value pairs +
    attrib-key string   attribute value +
   ha:flags_pinvia     flag bits of a pin or via +
    found flag   If set, this object has been found by FindConnection() +
    hole flag   For pins and vias, this flag means that the pin or via is a hole without a copper annulus. +
    clearline flag   For lines and arcs, the line/arc will clear polygons instead of connecting to them. +
    selected flag   Set when the object is selected. +
    auto flag   For lines and vias, indicates that these were created by the autorouter. +
    warn flag   For pins, vias, and pads, set to indicate a warning. +
    usetherm flag   Obsolete, indicates that pins/vias should be drawn with thermal fingers. +
    drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
    lock flag   Set for locked objects. +
    nonetlist flag   subcircuit is not on the netlist and should not interfere with the netlist +
    termname flag   when set the names of pins are shown. +
    floater flag   subc part can be moved after subc placing +
    pin flag   object is a pin (in an element) +
    via flag   object is a via +
 li:layers     ordered list of layers; v1 required the order to be top-bottom physically; v1 also required silk layers to be at the end (same resrtictions as in the old .pcb format; only real (non-bound) layers have attributes) +
  ha:NAME     a logical layer +
   lid integer >=2 layer ID +
   visible integer <6 only in real (non-boud) layers: 1 if the layer is visible, 0 if not (UI setting) +
   group integer   only in real (non-boud) layers: "parent" layer group ID +
   color string >=5 layer color on UI, in #rrggbb format +
   stack_offs integer   only in bound layers: match offset e.g. for internal copper layers +
   ha:type     only for bound layers: try to bind to this type of layer on the host board +
    top flag   location: top side +
    bottom flag   location: bottom side +
    intern flag   location: internal +
    logical flag   location: logical (not in the actual stackup) +
    copper flag   material: copper +
    silk flag   material: silk +
    mask flag   material: mask +
    paste flag   material: paste +
    outline flag   "material": router path for board outline; normally for the outer contour, sometimes for biggish inner cutouts as well) +
    mech flag   "material": various mechanical fabbing instructions, e.g. slots; the purpose field provides more detail about the use +
    doc flag   "material": documentation, either for the user and for pcb-rnd or both (the purpose field shoudl tell); e.g. assembly documentation for the user, keepout for the user and DRC +
    substrate flag   material: substrate or insulator +
   purpose integer >=6 only in bound layers: match layer group purpose +
   combining   >=2 layer combination (compositing) flags +
    sub flag   draw in negative +
    auto flag   padstacks draw their paste, mask and silk objects on the first layer (of matching type) that features the auto flag +
   ha:attributes     a hash of attribute key=value pairs +
    attrib-key string   attribute value +
   li:objects     list of drawing primitives put on this layer +
    ha:line.ID     round cap line +
     x1 coord   line first endpoint, horizontal offset +
     y1 coord   line first endpoint, vertical offset +
     x2 coord   line second endpoint, horizontal offset +
     y2 coord   line second endpoint, vertical offset +
     thickness coord   width of the line +
     clearance coord   copper clearance around the object +
     ha:attributes     a hash of attribute key=value pairs +
      attrib-key string   attribute value +
     ha:flags     flag bits of a line +
      found flag   If set, this object has been found by FindConnection() +
      clearline flag   For lines and arcs, the line/arc will clear polygons instead of connecting to them. +
      selected flag   Set when the object is selected. +
      auto flag   For lines and vias, indicates that these were created by the autorouter. +
      rubberend flag   For lines, used internally for rubber band moves: indicates one end already rubber banding. +
      drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
      exportsel flag   Set for objects that should be exported in a partial export. +
      lock flag   Set for locked objects. +
      termname flag   when set the names of pins are shown. +
      floater flag   subc part can be moved after subc placing +
     li:thermal     list of thermal flags for heavy terminals, on the single layer the object is on +
      on none   draw any thermal only if this string is present; else normal clearance is applied +
      diag none   if present, the thermal is diagonal (45 degree rotated) +
      round none   if present, thermal shape is rounded +
      sharp none   if present, thermal shape is sharp +
      solid none   if present, there is no thermal but a solid connection ("join") +
    ha:arc.ID     round cap elliptic arc (only width==height is fully supported at the moment) +
     x coord   center, X coord +
     y coord   center, Y coord +
     width coord   radius (of the centerline of the arc) in X direction +
     height coord   radius (of the centerline of the arc) in Y direction +
     thickness coord   width of the pen the arc is drawn with +
     clearance coord   copper clearance around the object +
     astart angle   start angle +
     adelta angle   delta angle +
     ha:attributes     a hash of attribute key=value pairs +
      attrib-key string   attribute value +
     ha:flags     flag bits of a arc +
      found flag   If set, this object has been found by FindConnection() +
      clearline flag   For lines and arcs, the line/arc will clear polygons instead of connecting to them. +
      selected flag   Set when the object is selected. +
      auto flag   For lines and vias, indicates that these were created by the autorouter. +
      rubberend flag   For lines, used internally for rubber band moves: indicates one end already rubber banding. +
      drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
      exportsel flag   Set for objects that should be exported in a partial export. +
      lock flag   Set for locked objects. +
      termname flag   when set the names of pins are shown. +
      floater flag   subc part can be moved after subc placing +
     li:thermal     list of thermal flags for heavy terminals, on the single layer the object is on +
      on none   draw any thermal only if this string is present; else normal clearance is applied +
      diag none   if present, the thermal is diagonal (45 degree rotated) +
      round none   if present, thermal shape is rounded +
      sharp none   if present, thermal shape is sharp +
      solid none   if present, there is no thermal but a solid connection ("join") +
    ha:gfx.ID   >=7 rectangular custom pixmap graphics +
     sx coord   visible size, X direction +
     sy coord   visible size, Y direction +
     cx coord   center, X coord +
     cy coord   center, Y coord +
     rot angle   rotation angle, CCW +
     xmirror ingteger   0 or 1, whether the pixmap should be mirrored (x coord mirror, which means mirror against the y axis +
     ymirror ingteger   0 or 1, whether the pixmap should be mirrored (y coord mirror, which means mirror against the x axis +
     pixmap_ref ingteger   ID of the pixmap to use from the pixmaps subtree; this pixmap represents the neutral state (no rotation, no mirror) pixmap of the object +
     ha:attributes     a hash of attribute key=value pairs +
      attrib-key string   attribute value +
     ha:flags     flag bits of a arc +
      found flag   If set, this object has been found by FindConnection() +
      clearline flag   For lines and arcs, the line/arc will clear polygons instead of connecting to them. +
      selected flag   Set when the object is selected. +
      auto flag   For lines and vias, indicates that these were created by the autorouter. +
      rubberend flag   For lines, used internally for rubber band moves: indicates one end already rubber banding. +
      drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
      exportsel flag   Set for objects that should be exported in a partial export. +
      lock flag   Set for locked objects. +
      termname flag   when set the names of pins are shown. +
      floater flag   subc part can be moved after subc placing +
     li:thermal     list of thermal flags for heavy terminals, on the single layer the object is on +
      on none   draw any thermal only if this string is present; else normal clearance is applied +
      diag none   if present, the thermal is diagonal (45 degree rotated) +
      round none   if present, thermal shape is rounded +
      sharp none   if present, thermal shape is sharp +
      solid none   if present, there is no thermal but a solid connection ("join") +
    ha:polygon.ID     polygon, as drawn (unclipped) +
     clearance coord >=3 copper clearance around the object +
     enforce_clearance coord >=7 enforce minimum clearance on clearing objects within the polygon +
     ha:attributes     a hash of attribute key=value pairs +
      attrib-key string   attribute value +
     ha:flags     flag bits of a polygon +
      found flag   If set, this object has been found by FindConnection() +
      clearpoly flag   For polygons, this flag means that pins and vias will normally clear these polygons (thus, thermals are required for electrical connection). When clear, polygons will solidly connect to pins and vias. +
      fullpoly flag   For polygons, the full polygon is drawn (i.e. all parts instead of only the biggest one). +
      selected flag   Set when the object is selected. +
      drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
      exportsel flag   Set for objects that should be exported in a partial export. +
      lock flag   Set for locked objects. +
      termname flag   when set the names of pins are shown. +
      clearpolypoly flag   For polygons, apply clearance to nearby polygons +
      floater flag   subc part can be moved after subc placing +
     li:thermal     list of thermal flags for heavy terminals, on the single layer the object is on +
      on none   draw any thermal only if this string is present; else normal clearance is applied +
      diag none   if present, the thermal is diagonal (45 degree rotated) +
      round none   if present, thermal shape is rounded +
      sharp none   if present, thermal shape is sharp +
      solid none   if present, there is no thermal but a solid connection ("join") +
     li:geometry     first item is the outer contour, subsequent, optional items are holes +
      contour coordtbl   2 column table of x;y coords for the outer contour +
      hole coordtbl   2 column table of x;y coords for a hole +
    ha:text.ID     single line text object +
     x coord   placement: X coord +
     y coord   placement: Y coord +
     role string   when part of an old element, determines which of the three hardwired text object role is used (footprint, refdes or value) +
     string string   text string (payload) +
     fid integer   font ID +
     scale integer   text size scale in % +
     scale_x double   text size scale in X direction (width), as a multiplier; if 0, use scale/100 +
     scale_y double   text size scale in Y direction (height), as a multiplier; if 0, use scale/100 +
     direction integer <=5 rotation in 90 degree steps (0 is horizontal); between -3 and +3, inclusive. Starting from v6, the rot field shall be used instead of direction +
     rot angle >=6 rotation angle in degrees, [0..360), CCW +
     thickness coord >=6 if zero, use the default width algorithm; if non-zero use this value as rotation angle in degrees +
     ha:attributes     a hash of attribute key=value pairs +
      attrib-key string   attribute value +
     ha:flags     flag bits of a text +
      found flag   If set, this object has been found by FindConnection() +
      clearline flag   For lines and arcs, the line/arc will clear polygons instead of connecting to them. +
      selected flag   Set when the object is selected. +
      onsolder flag   For text, indicates that it is on the solder side. +
      drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
      exportsel flag   Set for objects that should be exported in a partial export. +
      lock flag   Set for locked objects. +
      termname flag   when set the names of pins are shown. +
      dyntext flag   For text: dynamic string (substitute %patterns%) +
      floater flag   subc part can be moved after subc placing +
 li:padstack_prototypes   >=4 +
  unused none   placeholder for marking unused slot to keep slot indices for early lihata v4 +
  ha:ps_proto_v4.PID     padstack prototype specification, as introduced in lihata board v4 +
   hdia coord   hole diameter; 0 means no hole +
   htop integer   hole start: copper layer index from the top (positive) or bottom (negative) copper layer (0 means top copper layer) +
   hbottom integer   hole start: copper layer index from the bottom (positive) or top (negative) copper layer (0 means bottom copper layer) +
   hplated integer   0=hole and/or slot is unplated; 1=hole and/or slot is plated +
   name string >=5 optional user assigned prototype name +
   li:shape     shape per layer type definition +
    ha:ps_shape_v4     shape on a specific layer type (specified by layer_mask and combining), as specifie in lihata board v4; shape is either ps_poly, ps_line or ps_circ (only one of these will present per layer type); shape coords are relative to padstack origin; layer mask shall contain one material and at most one location bit +
     ha:layer_mask     layer type and location +
      top flag   location: top side +
      bottom flag   location: bottom side +
      intern flag   location: internal +
      logical flag   location: logical (not in the actual stackup) +
      copper flag   material: copper +
      silk flag   material: silk +
      mask flag   material: mask +
      paste flag   material: paste +
      outline flag   "material": router path for board outline; normally for the outer contour, sometimes for biggish inner cutouts as well) +
      mech flag   "material": various mechanical fabbing instructions, e.g. slots; the purpose field provides more detail about the use +
      doc flag   "material": documentation, either for the user and for pcb-rnd or both (the purpose field shoudl tell); e.g. assembly documentation for the user, keepout for the user and DRC +
      substrate flag   material: substrate or insulator +
     combining     layer compositing match +
      sub flag   draw in negative +
      auto flag   padstacks draw their paste, mask and silk objects on the first layer (of matching type) that features the auto flag +
     clearance coord   local, per-layer-type clearance; applied if global padstack clearance is 0 +
     li:ps_poly     arbitrary convex polygon shape; contains a list of x;y coordinates +
     ha:ps_line     straight line shape, round or square cap +
      x1 coord   line first endpoint, horizontal offset +
      y1 coord   line first endpoint, vertical offset +
      x2 coord   line second endpoint, horizontal offset +
      y2 coord   line second endpoint, vertical offset +
      thickness coord   width of the line +
      square integer   0=round cap; 1=square cap +
     ha:ps_circ     filled circle shape +
      x coord   center, horizontal offset +
      y coord   center, vertical offset +
      dia coord   circle diameter +
     te:ps_hshadow   >=6 hole/slot shadow +
 ha:subc.ID   >=3 an instance (full copy) of a subcircuit +
  uid minuid   UID assigned by the user to track subc history +
  ha:attributes     a hash of attribute key=value pairs +
   attrib-key string   attribute value +
  ha:flags     flag bits of a subcircuit +
   found flag   If set, this object has been found by FindConnection() +
   selected flag   Set when the object is selected. +
   drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
   exportsel flag   Set for objects that should be exported in a partial export. +
   lock flag   Set for locked objects. +
   nonetlist flag   subcircuit is not on the netlist and should not interfere with the netlist +
   termname flag   when set the names of pins are shown. +
   floater flag   subc part can be moved after subc placing +
  ha:data     Layers and global objects of the board -> +
 ha:element.ID   <3 an instance (full copy) of an obsolete element footprint +
  x coord   element origin (diamond), horizontal offset +
  y coord   element origin (diamond), vertical offset +
  ha:attributes     a hash of attribute key=value pairs +
   attrib-key string   attribute value +
  ha:flags_element     flag bits of an element +
   found flag   If set, this object has been found by FindConnection() +
   selected flag   Set when the object is selected. +
   auto flag   For lines and vias, indicates that these were created by the autorouter. +
   drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
   lock flag   Set for locked objects. +
   nonetlist flag   subcircuit is not on the netlist and should not interfere with the netlist +
   termname flag   when set the names of pins are shown. +
   floater flag   subc part can be moved after subc placing +
   onsolder flag   element is placed on the solder side +
  li:objects     list of special objects that make up the element; lines and arcs are always on a silk layer +
   ha:line.ID     round cap line -> +
   ha:arc.ID     round cap elliptic arc (only width==height is fully supported at the moment) -> +
   ha:text.ID     single line text object -> +
   ha:pad.ID     SMD pad emulated using a line object; becomes a rectangle (but watch out for the cap-extended length!) when the square flag is set +
    x1 coord   line first endpoint, horizontal offset +
    y1 coord   line first endpoint, vertical offset +
    x2 coord   line second endpoint, horizontal offset +
    y2 coord   line second endpoint, vertical offset +
    thickness coord   width of the line +
    clearance coord   clearance around the line +
    mask coord   size of the mask cutout, as interpreted by gEDA/PCB +
    name string   symbolic name of the pad +
    number string   "pin number" for the netlist +
    ha:attributes     a hash of attribute key=value pairs +
     attrib-key string   attribute value +
    ha:flags_pad     flag bits of a pad +
     found flag   If set, this object has been found by FindConnection() +
     hole flag   For pins and vias, this flag means that the pin or via is a hole without a copper annulus. +
     clearline flag   For lines and arcs, the line/arc will clear polygons instead of connecting to them. +
     selected flag   Set when the object is selected. +
     auto flag   For lines and vias, indicates that these were created by the autorouter. +
     warn flag   For pins, vias, and pads, set to indicate a warning. +
     usetherm flag   Obsolete, indicates that pins/vias should be drawn with thermal fingers. +
     drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
     lock flag   Set for locked objects. +
     nonetlist flag   subcircuit is not on the netlist and should not interfere with the netlist +
     termname flag   when set the names of pins are shown. +
     floater flag   subc part can be moved after subc placing +
     pin flag   object is a pin (in an element) +
     via flag   object is a via +
   ha:pin.ID     thru-hole pin; emulated as an old-style via +
    x coord   place padstack with origin at this horizontal coordinate +
    y coord   place padstack with origin at this vertical coordinate +
    thickness coord   copper shape dimension (diameter) +
    clearance coord   copper clearance around the copper shape +
    mask coord   mask cutout shape dimension (diameter) +
    hole coord   drill/hole diameter +
    name string   optional name attribute +
    number string   for a pin (or to-be-pin) this is the terminal ID +
    ha:attributes     a hash of attribute key=value pairs +
     attrib-key string   attribute value +
    ha:flags_pinvia     flag bits of a pin or via +
     found flag   If set, this object has been found by FindConnection() +
     hole flag   For pins and vias, this flag means that the pin or via is a hole without a copper annulus. +
     clearline flag   For lines and arcs, the line/arc will clear polygons instead of connecting to them. +
     selected flag   Set when the object is selected. +
     auto flag   For lines and vias, indicates that these were created by the autorouter. +
     warn flag   For pins, vias, and pads, set to indicate a warning. +
     usetherm flag   Obsolete, indicates that pins/vias should be drawn with thermal fingers. +
     drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
     lock flag   Set for locked objects. +
     nonetlist flag   subcircuit is not on the netlist and should not interfere with the netlist +
     termname flag   when set the names of pins are shown. +
     floater flag   subc part can be moved after subc placing +
     pin flag   object is a pin (in an element) +
     via flag   object is a via +
 ha:rat.ID     global rat line +
  x1 coord   line first endpoint, horizontal offset +
  y1 coord   line first endpoint, vertical offset +
  x2 coord   line second endpoint, horizontal offset +
  y2 coord   line second endpoint, vertical offset +
  lgrp1 integer   first endpoint's layer group ID +
  lgrp2 integer   second endpoint's layer group ID +
  anchor1 string >=7 first endpoint's objet anchor written as an absolute idpath +
  anchor2 string >=7 second endpoint's objet anchor written as an absolute idpath +
  ha:attributes     a hash of attribute key=value pairs +
   attrib-key string   attribute value +
  ha:flags     flag bits of a line +
   found flag   If set, this object has been found by FindConnection() +
   clearline flag   For lines and arcs, the line/arc will clear polygons instead of connecting to them. +
   selected flag   Set when the object is selected. +
   auto flag   For lines and vias, indicates that these were created by the autorouter. +
   rubberend flag   For lines, used internally for rubber band moves: indicates one end already rubber banding. +
   drc flag   Set for objects that fail DRC: flag like FOUND flag for DRC checking. +
   exportsel flag   Set for objects that should be exported in a partial export. +
   lock flag   Set for locked objects. +
   termname flag   when set the names of pins are shown. +
   floater flag   subc part can be moved after subc placing +
+

ha:pixmaps

+

+ +
type:name value ver description +
ha:pixmaps   >=7 Collection of all unique pixmaps used by the board or footprint +
 ha:ulzw.ID     pixmap with payload ulzw-compressed +
  sx integer   size in X direction (width), in pixels +
  sy integer   size in Y direction (height), in pixels +
  transparent string   color of the transparent pixel in #rrggbb form; omit node if there is no transparent pixel in the pixmap +
  pixmap string   base64 encoded version of the ulzw compressed raw pixmap, whih is in 24 bit RGB format, stored row-major +
+

li:submenu

+

+ +
type:name value ver description +
li:submenu     ordered list of menu items for a submenu +
 m string   mnemonic: single character that should be underlined and used as a hot key in the menu name +
 - none   horizontal separator +
 @ANCHOR none   an anchor is an invisible placeholder where a dynamically generated set of menu items should be inserted runtime +
 ha:SUBSUBMENUNAME     sub-submenu item: opens a new level of submenu when clicked +
  m string   mnemonic: single character that should be underlined and used as a hot key in the menu name +
  li:submenu     ordered list of menu items for a submenu -> +
 ha:LEAFSUBMENUNAME     leaf submenu item: executes an action when clicked +
  m string   mnemonic: single character that should be underlined and used as a hot key in the menu name +
  li:a     list of alternative hotkey sequences to activate the menu +
  a string   a single hotkey sequences to activate the menu +
  li:action     list of actions to execute when the menu is activated +
  action string   a single action to execute when the menu is activated +
  tip string   tooltip text +
  checked string   the menu item has a checkbox; value is the action to execute to determine whether the menu item's checkbox is checked or not +
  update_on string   path of a conf node that triggers re-evaluation of the checkbox state +
+

te:path

+

+ +
type:name value ver description +
te:path     path to a menu item, starting from the menu tree root; e.g. /main_menu/File/Revert +
+

Types

+

+ + + + + + + + + + +
type description +
angle + + A decimal number without unit, representing an angle in degree. Can + be positive or negative. + +
coord + + A decimal number with a unit suffix. If the unit suffix is missing, + the coordinate is loaded in the internal units (which is nanometer as of 2018, + but could change in the future, thus files shall not depend on it). Depending + on the context, coordinates may have a sign (positive or negative). +

+ Examples: +

+x=10mil;
+y=1.5mm;
+dia=12cm;
+
+ +
coordtbl + + A two-column table of coords. First column are X, second column are Y + coordinates. +

+ Examples: +

+ta:contour {
+ 1mm;   2.1mm;
+ 5mm;   5.2mm;
+ 3.7mm; 12mil;
+}
+ta:foo = { 1mm; 2.1mm;  5mm;   5.2mm;  3.7mm; 12mil; }
+
+ +
double + + Unitless numeric value in decimal format. Depending on context it is + sometimes signed. + +
flag + + If the flag is set, the value is "1", if the flag is not set, the + whole key=value pair is omitted. + +
integer + + Unitless integer value in decimal format. Depending on context it is + sometimes signed. + +
minuid + + An unique ID as generated by libminuid (24 ASCII characters). + +
none + + No value. + +
string + + Free form text data + +
+

Comments

+

ver column: Format version range the subtree may appear in. + + Index: tags/2.3.0/doc/developer/lihata_format/tree.txt =================================================================== --- tags/2.3.0/doc/developer/lihata_format/tree.txt (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/tree.txt (revision 33253) @@ -0,0 +1,737 @@ +File format root nodes + +Each table below describes the full tree of one of the pcb-rnd file formats, from the root. + +ha:pcb-rnd-board-v* + +type:name value ver description +ha:pcb-rnd-board-v* The full, self-contained description of a printed circuit board. This is the root of a board .lht file. The * after the v in the name is an integer which is the format version. + ha:meta Any meta-data that won't directly turn into physical material (e.g. copper). + board_name string User assigned name of the board + ha:grid User interface last grid settings + offs_x coord grid origin: X offset from 0;0 + offs_y coord grid origin: Y offset from 0;0 + spacing coord distance between two grid points both in X and Y directions + ha:size object size related settings + x coord drawing area size X (width) + y coord drawing area size Y (height) + isle_area_nm2 double remove polygon islands smaller than this value, specified in nm^2 + thermal_scale double scale all thermals on the board by this factor + ha:drc <5 design rule checker settings for the old DRC + bloat coord Minimum copper spacing + shrink coord Minimum overlap between validly touching copper objects + min_width coord Minimum copper width + min_silk coord Minimum silk width + min_drill coord Minimum drill diameter + min_ring coord Minimum annular ring width + ha:cursor obsolete cursor/view state + x coord last position, X (horizontal) + y coord last position, Y (horizontal) + zoom double last view zoom factor + ha:layer_stack physical layer stack information: geometry and properties of physical layers + li:groups ordered list of physical layers from top to bottom + ha:INTEGER a layer group (a physical layer of the board); the ID of the layer group is the integer in the name of the node + name string >=6 purpose of layer groups (useful with mechanical/documentation groups + ha:type a flag-list of layer type flag bits + top flag location: top side + bottom flag location: bottom side + intern flag location: internal + logical flag location: logical (not in the actual stackup) + copper flag material: copper + silk flag material: silk + mask flag material: mask + paste flag material: paste + outline flag "material": router path for board outline; normally for the outer contour, sometimes for biggish inner cutouts as well) + mech flag "material": various mechanical fabbing instructions, e.g. slots; the purpose field provides more detail about the use + doc flag "material": documentation, either for the user and for pcb-rnd or both (the purpose field shoudl tell); e.g. assembly documentation for the user, keepout for the user and DRC + substrate flag material: substrate or insulator + name string >=6 purpose of layer groups (useful with mechanical/documentation groups + li:layers ordered list of logical layer IDs hosted by this layer group + ha:font font kit: all fonts used on the board (if no font specified, default font will be used) + ha:FONT-ID the full description of a font; the node name is the integer font id or "geda_pcb" for font 0 (for historical reasons); the name is used only to make each node unique, the ID is also a field below -> + ha:styles routing styles hash: collection of all available routing syles + ha:netlists all available netlists + li:netlist the input netlist (as seen in the last netlist import, a.k.a. forward annotation) + ha:NETNAME a network + li:conn list of terminals connected to the network + diameter string refdes-terminal + ha:attributes >=5 a hash of attribute key=value pairs + attrib-key string attribute value + li:netlist_patch a list of intentional deviations from the input netlist, a.k.a. material for back annotation + li:net_info describe the current state of a net, as seen on the input + net string net name; first item on the list, only once + term string terminal name; zero or more items starting from the second item + ha:add_conn the 'as built' network requires a new connection to be created during the back annotation + net string net name the terminal should be added to + term string terminal name + ha:del_conn the 'as built' network requires an existing connection to be removed during the back annotation + net string net name the terminal should be removed from + term string terminal name + ha:change_attrib the 'as built' network requires an attribute to be set or changed + net string net name whose attribute needs to be changed + key string key (name) of the attribute + val string new value of the attribute + li:conf complete pcb-rnd configuration tree -> + ha:data Layers and global objects of the board -> + ha:pixmaps >=7 Collection of all unique pixmaps used by the board or footprint -> + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + +li:pcb-rnd-buffer-v* + +type:name value ver description +li:pcb-rnd-buffer-v* >=6 buffer file containing a whole paste buffer with bound layers + x coord buffer origin point, X coordinate + y coord buffer origin point, Y coordinate + ha:data Layers and global objects of the board -> + +li:pcb-rnd-conf-v1 + +type:name value ver description +li:pcb-rnd-conf-v1 complete pcb-rnd configuration tree + ha:overwrite overwrite values while merging; children: a full or partial config tree + ha:prepend prepend values while merging; children: a full or partial config tree + ha:append append values while merging; children: a full or partial config tree + +ha:pcb-rnd-drc-query-v* + +type:name value ver description +ha:pcb-rnd-drc-query-v* pcb-rnd drc_query script + li:defs Definitions of user tunable constants + ha:name each entry is identified by an unique name + default string default value + type string data type of the constant (a valid conf system type name, e.g. real, coord) + desc string human readable description of the purpose of the constant + li:rules DRC rules + ha:name each entry is identified by an unique name + type string violation type (for grouping violations in the drc report) + title string title (short summary) of the violation + desc string human readable description of the violation, with hints on how to resolve it + query string query script to execute for finding violations + +li:pcb-rnd-font-v1 + +type:name value ver description +li:pcb-rnd-font-v1 font description + ha:FONT-ID the full description of a font; the node name is the integer font id or "geda_pcb" for font 0 (for historical reasons); the name is used only to make each node unique, the ID is also a field below + cell_height coord height of the tallest glyph + cell_width coord width of the widest glyph + id integer unique font ID within the fontkit; fonts are referenced by ID + name string user specified, user readable font name + ha:symbols a collections of glyphs availbale in the font + ha:CHARACTER Description of a glyph (symbol). Node name is a signel ASCII character or is of format &xx where xx is a hex digit of the ASCII code of the character. Characters that must use the hex version are: codes below 33 or over + 126, &, #, {, }, /, :, ;, =, \, : + height coord height of the glyph + width coord width of the glyph + delta coord extra space always inserted after the current symbol, before the next character + li:objects objects that make up the symbol; IDs are per symbol local IDs counted from 0 + ha:line.ID round cap line, simplified + x1 coord line first endpoint, horizontal offset + y1 coord line first endpoint, vertical offset + x2 coord line second endpoint, horizontal offset + y2 coord line second endpoint, vertical offset + thickness coord width of the line + ha:simplearc.ID round cap arc, simplified + x coord center, X coord + y coord center, Y coord + r coord radius (of the centerline of the arc) + thickness coord width of the pen the arc is drawn with + astart angle start angle + adelta angle delta angle + li:simplepoly.ID round cap arc, simplified; contains a flat list of coords; each coord pair is an x;y corner of the outline of the polygon (odd indices are x coords, even indices are y coords) + +ha:pcb-rnd-log-v* + +type:name value ver description +ha:pcb-rnd-log-v* pcb-rnd message log dump + li:entries list of message log entries + ha:ID each entry is identified by an unique unsigned long int ID + stamp string UNIX time stamp of entry creation + level integer log level enum value (see error.h) + seen integer 1 if the message got displayed + str string log message + +ha:menu + +type:name value ver description +ha:rnd-menu-v1 Menu file + li:mouse mouse bindings + li:left actions to execute on left button click + li:press actions to execute on mouse button press when no modifier is pressed + li:press-shift actions to execute on mouse button press when shift is pressed + li:press-ctrl actions to execute on mouse button press when control is pressed + li:release actions to execute on mouse button release when no modifier is pressed + li:release-shift actions to execute on mouse button release when shift is pressed + li:release-ctrl actions to execute on mouse button release when control is pressed + li:middle actions to execute on middle button click + li:press actions to execute on mouse button press when no modifier is pressed + li:press-shift actions to execute on mouse button press when shift is pressed + li:press-ctrl actions to execute on mouse button press when control is pressed + li:release actions to execute on mouse button release when no modifier is pressed + li:release-shift actions to execute on mouse button release when shift is pressed + li:release-ctrl actions to execute on mouse button release when control is pressed + li:right actions to execute on right button click + li:press actions to execute on mouse button press when no modifier is pressed + li:press-shift actions to execute on mouse button press when shift is pressed + li:press-ctrl actions to execute on mouse button press when control is pressed + li:release actions to execute on mouse button release when no modifier is pressed + li:release-shift actions to execute on mouse button release when shift is pressed + li:release-ctrl actions to execute on mouse button release when control is pressed + li:scroll-up actions to execute on scroll wheel scolling up event + li:press actions to execute on mouse button press when no modifier is pressed + li:press-shift actions to execute on mouse button press when shift is pressed + li:press-ctrl actions to execute on mouse button press when control is pressed + li:scroll-down actions to execute on scroll wheel scolling down event + li:press actions to execute on mouse button press when no modifier is pressed + li:press-shift actions to execute on mouse button press when shift is pressed + li:press-ctrl actions to execute on mouse button press when control is pressed + li:main_menu root of the main pull-down menu system; ordered list of main menus + ha:MENUNAME main menu name, e.g. "File" + m string mnemonic: single character that should be underlined and used as a hot key in the menu name + li:submenu ordered list of menu items for a submenu -> + li:popups collection of popup menus + ha:POPUPNAME popup menu name, e.g. "layer" for layer context menu + m string mnemonic: single character that should be underlined and used as a hot key in the menu name + li:submenu ordered list of menu items for a submenu -> + li:toolbar_static ordered list (from left to right) of toolbar icons + ha:TOOLNAME tool menu name, e.g. "polyhole" for the polygon hole draw tool + te:tip tooltip for the icon button + li:anchored list of submenus; child of submenu would be copied and appended after ever occurance of the ANCHORNAME + ha:@ANCHORNAME list menu items/subtrees to be copied after each @ANCHORNAME in the menu system + li:submenu ordered list of menu items for a submenu -> + ha:scripts a collection of named action scripts that can be symnlinked from elsewhere in the menu file + li:SCRIPTNAME action script + +ha:menu_patch + +type:name value ver description +ha:rnd-menu-patch-v1 Menu patch instructions + te:prio optional; integer priority value used in ordering the menu files/patches before merging + li:patch ordered list of patch instructions + ha:append_menu append (or overwrite) a submenu tree at a given path + te:path path to a menu item, starting from the menu tree root; e.g. /main_menu/File/Revert -> + li:submenu ordered list of menu items for a submenu -> + ha:remove_menu remove a submenu or menu item at a given path + te:path path to a menu item, starting from the menu tree root; e.g. /main_menu/File/Revert -> + ha:overwrite_menu_props overwrite properties of an existing menu + te:path path to a menu item, starting from the menu tree root; e.g. /main_menu/File/Revert -> + ha:props same as menu properties documented at LEAFSUBMENUNAME + +li:pcb-rnd-padstack-v* + +type:name value ver description +li:pcb-rnd-padstack-v* >=6 A singe padstack prototype + ha:ps_proto_v6.0 padstack prototype specification, as introduced in lihata board v4 -> + +ha:coraleda-project-v1 + +type:name value ver description +ha:coraleda-project-v1 Project file root. Except for "common", each software package should create a single subtree under the root; the subtree shall be named after the software package + ha:common project settings that should be common to all software packages + name string long name of the project + desc string description of the project + url string homepage of the project + vcs string main vcs url for the project + contact string author/maintainer contact info + li:files ordered list of source files being used by the project + ha:NAME a project member file + path string path to the file, relative to the project file + desc string description of the file + type string optional: type of the file; one of: "pcb", "schematic", "doc" + li:libs ordered list of libraries the project depends on + ha:NAME a library + path string path to the library, relative to the project file; all files and subdirectories under the root, recursively, are considered part of the library (must not be used together with url) + url string url to the library (must not be used together with path) + desc string description of the library + type string optional: type of the library; one of: "footprint" (for pcb design), "symbol" (for schematic), "sim" (models and subcircuits for e.g. spice simulation) + li:pcb-rnd-conf-v1 complete pcb-rnd configuration tree -> + +li:pcb-rnd-subcircuit-v* + +type:name value ver description +li:pcb-rnd-subcircuit-v* footprint file containing a single subcircuit + ha:subc.ID >=3 an instance (full copy) of a subcircuit + uid minuid UID assigned by the user to track subc history + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags flag bits of a subcircuit + found flag If set, this object has been found by FindConnection() + selected flag Set when the object is selected. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + exportsel flag Set for objects that should be exported in a partial export. + lock flag Set for locked objects. + nonetlist flag subcircuit is not on the netlist and should not interfere with the netlist + termname flag when set the names of pins are shown. + floater flag subc part can be moved after subc placing + ha:data Layers and global objects of the board -> + ha:pixmaps >=7 Collection of all unique pixmaps used by the board or footprint -> + +li:view-list-v* + +type:name value ver description +li:view-list-v* a list of view items (locations and objects to highlight on the board, e.g. for DRC violations) + ha:view.ID a view item; ID is a 32 bit signed integer, unique within the view list + type string free form short text for type of the entry; the GUI may group items by type + title string free form short text for the title of the entry; the GUI typically uses this in brief listings + description string free form long text for the detailed description of the entry + li:bbox coord optional: 4 coordinates in x1;y1;x2;y2 order that describes the bounding box of the view in board space coordinates; when available, the preview or go-to will use this for view box + li:xy coord optional: 2 coordinates in x;y order that describes a specific board location + li:objs.ID a group of related objects; there should be at most two groups with ID 0 and 1. These objects are often highlighted in red and blue. + li:id objects are specified as a list of object IDs (32 bit integers) + +Common subtrees + +Each table below describes a subtree that usually does not specify a whole tree (thus they are usually not a valid file on their own). These subtrees are described in a separate table because they are used from multiple other trees. + +ha:data + +type:name value ver description +ha:data Layers and global objects of the board + li:objects List of global (non-layer/multi-layer) objects + ha:padstack_ref.ID >=4 a padstack reference (instance) placed on the board (e.g. used as a via) + proto integer padstack prototype ID to use, from the parent data's proto list + x coord place padstack with origin at this horizontal coordinate + y coord place padstack with origin at this vertical coordinate + clearance coord global clearance; if non-zero, overrides local (per shape) clearance + rot angle rotation angle in degrees + xmirror integer 0 or 1; if 1, mirror all shapes over the x (horizontal) axis (so that y coords are flipped) + smirror integer 0 or 1; if 1, mirror the layer stackup: bottom becomes top, top becomes bottom (a.k.a. "place on the other side") + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags flag bits of a padstack + found flag If set, this object has been found by FindConnection() + hole flag For pins and vias, this flag means that the pin or via is a hole without a copper annulus. + clearline flag For lines and arcs, the line/arc will clear polygons instead of connecting to them. + selected flag Set when the object is selected. + auto flag For lines and vias, indicates that these were created by the autorouter. + warn flag For pins, vias, and pads, set to indicate a warning. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + exportsel flag Set for objects that should be exported in a partial export. + lock flag Set for locked objects. + termname flag when set the names of pins are shown. + floater flag subc part can be moved after subc placing + li:thermal list of thermal shapes, per layer + li:LAYERID integer layer ID the thermal affects; each word is a boolean flag that is either present on the list or is missing; only one shape may be present + on none thermal is present on this layer; if not present, all other thermal flags are ignored on this layer + diag none thermal graphics is not axis aligned but diagonal (rotated by 45 degrees) + round none shape: rounded edge fingers + sharp none shape: sharp edge fingers + solid none shape: no thermal relief, solid connection without clearance + noshape none >=6 shape: special: omit copper shape of the padstack on this layer + ha:via.ID <=4 an old via object (loaded as padstack in the new model) + x coord place padstack with origin at this horizontal coordinate + y coord place padstack with origin at this vertical coordinate + thickness coord copper shape dimension (diameter) + clearance coord copper clearance around the copper shape + mask coord mask cutout shape dimension (diameter) + hole coord drill/hole diameter + name string optional name attribute + number string for a pin (or to-be-pin) this is the terminal ID + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags_pinvia flag bits of a pin or via + found flag If set, this object has been found by FindConnection() + hole flag For pins and vias, this flag means that the pin or via is a hole without a copper annulus. + clearline flag For lines and arcs, the line/arc will clear polygons instead of connecting to them. + selected flag Set when the object is selected. + auto flag For lines and vias, indicates that these were created by the autorouter. + warn flag For pins, vias, and pads, set to indicate a warning. + usetherm flag Obsolete, indicates that pins/vias should be drawn with thermal fingers. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + lock flag Set for locked objects. + nonetlist flag subcircuit is not on the netlist and should not interfere with the netlist + termname flag when set the names of pins are shown. + floater flag subc part can be moved after subc placing + pin flag object is a pin (in an element) + via flag object is a via + li:layers ordered list of layers; v1 required the order to be top-bottom physically; v1 also required silk layers to be at the end (same resrtictions as in the old .pcb format; only real (non-bound) layers have attributes) + ha:NAME a logical layer + lid integer >=2 layer ID + visible integer <6 only in real (non-boud) layers: 1 if the layer is visible, 0 if not (UI setting) + group integer only in real (non-boud) layers: "parent" layer group ID + color string >=5 layer color on UI, in #rrggbb format + stack_offs integer only in bound layers: match offset e.g. for internal copper layers + ha:type only for bound layers: try to bind to this type of layer on the host board + top flag location: top side + bottom flag location: bottom side + intern flag location: internal + logical flag location: logical (not in the actual stackup) + copper flag material: copper + silk flag material: silk + mask flag material: mask + paste flag material: paste + outline flag "material": router path for board outline; normally for the outer contour, sometimes for biggish inner cutouts as well) + mech flag "material": various mechanical fabbing instructions, e.g. slots; the purpose field provides more detail about the use + doc flag "material": documentation, either for the user and for pcb-rnd or both (the purpose field shoudl tell); e.g. assembly documentation for the user, keepout for the user and DRC + substrate flag material: substrate or insulator + purpose integer >=6 only in bound layers: match layer group purpose + combining >=2 layer combination (compositing) flags + sub flag draw in negative + auto flag padstacks draw their paste, mask and silk objects on the first layer (of matching type) that features the auto flag + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + li:objects list of drawing primitives put on this layer + ha:line.ID round cap line + x1 coord line first endpoint, horizontal offset + y1 coord line first endpoint, vertical offset + x2 coord line second endpoint, horizontal offset + y2 coord line second endpoint, vertical offset + thickness coord width of the line + clearance coord copper clearance around the object + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags flag bits of a line + found flag If set, this object has been found by FindConnection() + clearline flag For lines and arcs, the line/arc will clear polygons instead of connecting to them. + selected flag Set when the object is selected. + auto flag For lines and vias, indicates that these were created by the autorouter. + rubberend flag For lines, used internally for rubber band moves: indicates one end already rubber banding. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + exportsel flag Set for objects that should be exported in a partial export. + lock flag Set for locked objects. + termname flag when set the names of pins are shown. + floater flag subc part can be moved after subc placing + li:thermal list of thermal flags for heavy terminals, on the single layer the object is on + on none draw any thermal only if this string is present; else normal clearance is applied + diag none if present, the thermal is diagonal (45 degree rotated) + round none if present, thermal shape is rounded + sharp none if present, thermal shape is sharp + solid none if present, there is no thermal but a solid connection ("join") + ha:arc.ID round cap elliptic arc (only width==height is fully supported at the moment) + x coord center, X coord + y coord center, Y coord + width coord radius (of the centerline of the arc) in X direction + height coord radius (of the centerline of the arc) in Y direction + thickness coord width of the pen the arc is drawn with + clearance coord copper clearance around the object + astart angle start angle + adelta angle delta angle + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags flag bits of a arc + found flag If set, this object has been found by FindConnection() + clearline flag For lines and arcs, the line/arc will clear polygons instead of connecting to them. + selected flag Set when the object is selected. + auto flag For lines and vias, indicates that these were created by the autorouter. + rubberend flag For lines, used internally for rubber band moves: indicates one end already rubber banding. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + exportsel flag Set for objects that should be exported in a partial export. + lock flag Set for locked objects. + termname flag when set the names of pins are shown. + floater flag subc part can be moved after subc placing + li:thermal list of thermal flags for heavy terminals, on the single layer the object is on + on none draw any thermal only if this string is present; else normal clearance is applied + diag none if present, the thermal is diagonal (45 degree rotated) + round none if present, thermal shape is rounded + sharp none if present, thermal shape is sharp + solid none if present, there is no thermal but a solid connection ("join") + ha:gfx.ID >=7 rectangular custom pixmap graphics + sx coord visible size, X direction + sy coord visible size, Y direction + cx coord center, X coord + cy coord center, Y coord + rot angle rotation angle, CCW + xmirror ingteger 0 or 1, whether the pixmap should be mirrored (x coord mirror, which means mirror against the y axis + ymirror ingteger 0 or 1, whether the pixmap should be mirrored (y coord mirror, which means mirror against the x axis + pixmap_ref ingteger ID of the pixmap to use from the pixmaps subtree; this pixmap represents the neutral state (no rotation, no mirror) pixmap of the object + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags flag bits of a arc + found flag If set, this object has been found by FindConnection() + clearline flag For lines and arcs, the line/arc will clear polygons instead of connecting to them. + selected flag Set when the object is selected. + auto flag For lines and vias, indicates that these were created by the autorouter. + rubberend flag For lines, used internally for rubber band moves: indicates one end already rubber banding. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + exportsel flag Set for objects that should be exported in a partial export. + lock flag Set for locked objects. + termname flag when set the names of pins are shown. + floater flag subc part can be moved after subc placing + li:thermal list of thermal flags for heavy terminals, on the single layer the object is on + on none draw any thermal only if this string is present; else normal clearance is applied + diag none if present, the thermal is diagonal (45 degree rotated) + round none if present, thermal shape is rounded + sharp none if present, thermal shape is sharp + solid none if present, there is no thermal but a solid connection ("join") + ha:polygon.ID polygon, as drawn (unclipped) + clearance coord >=3 copper clearance around the object + enforce_clearance coord >=7 enforce minimum clearance on clearing objects within the polygon + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags flag bits of a polygon + found flag If set, this object has been found by FindConnection() + clearpoly flag For polygons, this flag means that pins and vias will normally clear these polygons (thus, thermals are required for electrical connection). When clear, polygons will solidly connect to pins and vias. + fullpoly flag For polygons, the full polygon is drawn (i.e. all parts instead of only the biggest one). + selected flag Set when the object is selected. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + exportsel flag Set for objects that should be exported in a partial export. + lock flag Set for locked objects. + termname flag when set the names of pins are shown. + clearpolypoly flag For polygons, apply clearance to nearby polygons + floater flag subc part can be moved after subc placing + li:thermal list of thermal flags for heavy terminals, on the single layer the object is on + on none draw any thermal only if this string is present; else normal clearance is applied + diag none if present, the thermal is diagonal (45 degree rotated) + round none if present, thermal shape is rounded + sharp none if present, thermal shape is sharp + solid none if present, there is no thermal but a solid connection ("join") + li:geometry first item is the outer contour, subsequent, optional items are holes + contour coordtbl 2 column table of x;y coords for the outer contour + hole coordtbl 2 column table of x;y coords for a hole + ha:text.ID single line text object + x coord placement: X coord + y coord placement: Y coord + role string when part of an old element, determines which of the three hardwired text object role is used (footprint, refdes or value) + string string text string (payload) + fid integer font ID + scale integer text size scale in % + scale_x double text size scale in X direction (width), as a multiplier; if 0, use scale/100 + scale_y double text size scale in Y direction (height), as a multiplier; if 0, use scale/100 + direction integer <=5 rotation in 90 degree steps (0 is horizontal); between -3 and +3, inclusive. Starting from v6, the rot field shall be used instead of direction + rot angle >=6 rotation angle in degrees, [0..360), CCW + thickness coord >=6 if zero, use the default width algorithm; if non-zero use this value as rotation angle in degrees + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags flag bits of a text + found flag If set, this object has been found by FindConnection() + clearline flag For lines and arcs, the line/arc will clear polygons instead of connecting to them. + selected flag Set when the object is selected. + onsolder flag For text, indicates that it is on the solder side. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + exportsel flag Set for objects that should be exported in a partial export. + lock flag Set for locked objects. + termname flag when set the names of pins are shown. + dyntext flag For text: dynamic string (substitute %patterns%) + floater flag subc part can be moved after subc placing + li:padstack_prototypes >=4 + unused none placeholder for marking unused slot to keep slot indices for early lihata v4 + ha:ps_proto_v4.PID padstack prototype specification, as introduced in lihata board v4 + hdia coord hole diameter; 0 means no hole + htop integer hole start: copper layer index from the top (positive) or bottom (negative) copper layer (0 means top copper layer) + hbottom integer hole start: copper layer index from the bottom (positive) or top (negative) copper layer (0 means bottom copper layer) + hplated integer 0=hole and/or slot is unplated; 1=hole and/or slot is plated + name string >=5 optional user assigned prototype name + li:shape shape per layer type definition + ha:ps_shape_v4 shape on a specific layer type (specified by layer_mask and combining), as specifie in lihata board v4; shape is either ps_poly, ps_line or ps_circ (only one of these will present per layer type); shape coords are + relative to padstack origin; layer mask shall contain one material and at most one location bit + ha:layer_mask layer type and location + top flag location: top side + bottom flag location: bottom side + intern flag location: internal + logical flag location: logical (not in the actual stackup) + copper flag material: copper + silk flag material: silk + mask flag material: mask + paste flag material: paste + outline flag "material": router path for board outline; normally for the outer contour, sometimes for biggish inner cutouts as well) + mech flag "material": various mechanical fabbing instructions, e.g. slots; the purpose field provides more detail about the use + doc flag "material": documentation, either for the user and for pcb-rnd or both (the purpose field shoudl tell); e.g. assembly documentation for the user, keepout for the user and DRC + substrate flag material: substrate or insulator + combining layer compositing match + sub flag draw in negative + auto flag padstacks draw their paste, mask and silk objects on the first layer (of matching type) that features the auto flag + clearance coord local, per-layer-type clearance; applied if global padstack clearance is 0 + li:ps_poly arbitrary convex polygon shape; contains a list of x;y coordinates + ha:ps_line straight line shape, round or square cap + x1 coord line first endpoint, horizontal offset + y1 coord line first endpoint, vertical offset + x2 coord line second endpoint, horizontal offset + y2 coord line second endpoint, vertical offset + thickness coord width of the line + square integer 0=round cap; 1=square cap + ha:ps_circ filled circle shape + x coord center, horizontal offset + y coord center, vertical offset + dia coord circle diameter + te:ps_hshadow >=6 hole/slot shadow + ha:subc.ID >=3 an instance (full copy) of a subcircuit + uid minuid UID assigned by the user to track subc history + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags flag bits of a subcircuit + found flag If set, this object has been found by FindConnection() + selected flag Set when the object is selected. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + exportsel flag Set for objects that should be exported in a partial export. + lock flag Set for locked objects. + nonetlist flag subcircuit is not on the netlist and should not interfere with the netlist + termname flag when set the names of pins are shown. + floater flag subc part can be moved after subc placing + ha:data Layers and global objects of the board -> + ha:element.ID <3 an instance (full copy) of an obsolete element footprint + x coord element origin (diamond), horizontal offset + y coord element origin (diamond), vertical offset + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags_element flag bits of an element + found flag If set, this object has been found by FindConnection() + selected flag Set when the object is selected. + auto flag For lines and vias, indicates that these were created by the autorouter. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + lock flag Set for locked objects. + nonetlist flag subcircuit is not on the netlist and should not interfere with the netlist + termname flag when set the names of pins are shown. + floater flag subc part can be moved after subc placing + onsolder flag element is placed on the solder side + li:objects list of special objects that make up the element; lines and arcs are always on a silk layer + ha:line.ID round cap line -> + ha:arc.ID round cap elliptic arc (only width==height is fully supported at the moment) -> + ha:text.ID single line text object -> + ha:pad.ID SMD pad emulated using a line object; becomes a rectangle (but watch out for the cap-extended length!) when the square flag is set + x1 coord line first endpoint, horizontal offset + y1 coord line first endpoint, vertical offset + x2 coord line second endpoint, horizontal offset + y2 coord line second endpoint, vertical offset + thickness coord width of the line + clearance coord clearance around the line + mask coord size of the mask cutout, as interpreted by gEDA/PCB + name string symbolic name of the pad + number string "pin number" for the netlist + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags_pad flag bits of a pad + found flag If set, this object has been found by FindConnection() + hole flag For pins and vias, this flag means that the pin or via is a hole without a copper annulus. + clearline flag For lines and arcs, the line/arc will clear polygons instead of connecting to them. + selected flag Set when the object is selected. + auto flag For lines and vias, indicates that these were created by the autorouter. + warn flag For pins, vias, and pads, set to indicate a warning. + usetherm flag Obsolete, indicates that pins/vias should be drawn with thermal fingers. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + lock flag Set for locked objects. + nonetlist flag subcircuit is not on the netlist and should not interfere with the netlist + termname flag when set the names of pins are shown. + floater flag subc part can be moved after subc placing + pin flag object is a pin (in an element) + via flag object is a via + ha:pin.ID thru-hole pin; emulated as an old-style via + x coord place padstack with origin at this horizontal coordinate + y coord place padstack with origin at this vertical coordinate + thickness coord copper shape dimension (diameter) + clearance coord copper clearance around the copper shape + mask coord mask cutout shape dimension (diameter) + hole coord drill/hole diameter + name string optional name attribute + number string for a pin (or to-be-pin) this is the terminal ID + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags_pinvia flag bits of a pin or via + found flag If set, this object has been found by FindConnection() + hole flag For pins and vias, this flag means that the pin or via is a hole without a copper annulus. + clearline flag For lines and arcs, the line/arc will clear polygons instead of connecting to them. + selected flag Set when the object is selected. + auto flag For lines and vias, indicates that these were created by the autorouter. + warn flag For pins, vias, and pads, set to indicate a warning. + usetherm flag Obsolete, indicates that pins/vias should be drawn with thermal fingers. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + lock flag Set for locked objects. + nonetlist flag subcircuit is not on the netlist and should not interfere with the netlist + termname flag when set the names of pins are shown. + floater flag subc part can be moved after subc placing + pin flag object is a pin (in an element) + via flag object is a via + ha:rat.ID global rat line + x1 coord line first endpoint, horizontal offset + y1 coord line first endpoint, vertical offset + x2 coord line second endpoint, horizontal offset + y2 coord line second endpoint, vertical offset + lgrp1 integer first endpoint's layer group ID + lgrp2 integer second endpoint's layer group ID + anchor1 string >=7 first endpoint's objet anchor written as an absolute idpath + anchor2 string >=7 second endpoint's objet anchor written as an absolute idpath + ha:attributes a hash of attribute key=value pairs + attrib-key string attribute value + ha:flags flag bits of a line + found flag If set, this object has been found by FindConnection() + clearline flag For lines and arcs, the line/arc will clear polygons instead of connecting to them. + selected flag Set when the object is selected. + auto flag For lines and vias, indicates that these were created by the autorouter. + rubberend flag For lines, used internally for rubber band moves: indicates one end already rubber banding. + drc flag Set for objects that fail DRC: flag like FOUND flag for DRC checking. + exportsel flag Set for objects that should be exported in a partial export. + lock flag Set for locked objects. + termname flag when set the names of pins are shown. + floater flag subc part can be moved after subc placing + +ha:pixmaps + +type:name value ver description +ha:pixmaps >=7 Collection of all unique pixmaps used by the board or footprint + ha:ulzw.ID pixmap with payload ulzw-compressed + sx integer size in X direction (width), in pixels + sy integer size in Y direction (height), in pixels + transparent string color of the transparent pixel in #rrggbb form; omit node if there is no transparent pixel in the pixmap + pixmap string base64 encoded version of the ulzw compressed raw pixmap, whih is in 24 bit RGB format, stored row-major + +li:submenu + +type:name value ver description +li:submenu ordered list of menu items for a submenu + m string mnemonic: single character that should be underlined and used as a hot key in the menu name + - none horizontal separator + @ANCHOR none an anchor is an invisible placeholder where a dynamically generated set of menu items should be inserted runtime + ha:SUBSUBMENUNAME sub-submenu item: opens a new level of submenu when clicked + m string mnemonic: single character that should be underlined and used as a hot key in the menu name + li:submenu ordered list of menu items for a submenu -> + ha:LEAFSUBMENUNAME leaf submenu item: executes an action when clicked + m string mnemonic: single character that should be underlined and used as a hot key in the menu name + li:a list of alternative hotkey sequences to activate the menu + a string a single hotkey sequences to activate the menu + li:action list of actions to execute when the menu is activated + action string a single action to execute when the menu is activated + tip string tooltip text + checked string the menu item has a checkbox; value is the action to execute to determine whether the menu item's checkbox is checked or not + update_on string path of a conf node that triggers re-evaluation of the checkbox state + +te:path + +type:name value ver description +te:path path to a menu item, starting from the menu tree root; e.g. /main_menu/File/Revert + +Types + ++--------------------------------------------------------------------------------------------------+ +| type | description | +|--------+-----------------------------------------------------------------------------------------| +|angle |A decimal number without unit, representing an angle in degree. Can be positive or | +| |negative. | +|--------+-----------------------------------------------------------------------------------------| +| |A decimal number with a unit suffix. If the unit suffix is missing, the coordinate is | +| |loaded in the internal units (which is nanometer as of 2018, but could change in the | +| |future, thus files shall not depend on it). Depending on the context, coordinates may | +| |have a sign (positive or negative). | +|coord | | +| |Examples: | +| | | +| |x=10mil; | +| |y=1.5mm; | +| |dia=12cm; | +|--------+-----------------------------------------------------------------------------------------| +| |A two-column table of coords. First column are X, second column are Y coordinates. | +| | | +| |Examples: | +| | | +|coordtbl|ta:contour { | +| | 1mm; 2.1mm; | +| | 5mm; 5.2mm; | +| | 3.7mm; 12mil; | +| |} | +| |ta:foo = { 1mm; 2.1mm; 5mm; 5.2mm; 3.7mm; 12mil; } | +|--------+-----------------------------------------------------------------------------------------| +|double |Unitless numeric value in decimal format. Depending on context it is sometimes signed. | +|--------+-----------------------------------------------------------------------------------------| +|flag |If the flag is set, the value is "1", if the flag is not set, the whole key=value pair is| +| |omitted. | +|--------+-----------------------------------------------------------------------------------------| +|integer |Unitless integer value in decimal format. Depending on context it is sometimes signed. | +|--------+-----------------------------------------------------------------------------------------| +|minuid |An unique ID as generated by libminuid (24 ASCII characters). | +|--------+-----------------------------------------------------------------------------------------| +|none |No value. | +|--------+-----------------------------------------------------------------------------------------| +|string |Free form text data | ++--------------------------------------------------------------------------------------------------+ + +Comments + +ver column: Format version range the subtree may appear in. Index: tags/2.3.0/doc/developer/lihata_format/types.lht =================================================================== --- tags/2.3.0/doc/developer/lihata_format/types.lht (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/types.lht (revision 33253) @@ -0,0 +1,65 @@ +ha:lht_tree_doc { ha:types { + +angle { + A decimal number without unit, representing an angle in degree. Can + be positive or negative. +} + +coord { + A decimal number with a unit suffix. If the unit suffix is missing, + the coordinate is loaded in the internal units (which is nanometer as of 2018, + but could change in the future, thus files shall not depend on it). Depending + on the context, coordinates may have a sign (positive or negative). +

+ Examples: +

+x=10mil;
+y=1.5mm;
+dia=12cm;
+
+} + +coordtbl { + A two-column table of coords. First column are X, second column are Y + coordinates. +

+ Examples: +

+ta:contour {
+	1mm;   2.1mm;
+	5mm;   5.2mm;
+	3.7mm; 12mil;
+\}
+ta:foo = { 1mm; 2.1mm;  5mm;   5.2mm;  3.7mm; 12mil; \}
+
+} + +double { + Unitless numeric value in decimal format. Depending on context it is + sometimes signed. +} + +flag { + If the flag is set, the value is "1", if the flag is not set, the + whole key=value pair is omitted. +} + +integer { + Unitless integer value in decimal format. Depending on context it is + sometimes signed. +} + +minuid { + An unique ID as generated by libminuid (24 ASCII characters). +} + +none { + No value. +} + +string { + Free form text data +} + +}} + Index: tags/2.3.0/doc/developer/lihata_format/view-list-v.svg =================================================================== --- tags/2.3.0/doc/developer/lihata_format/view-list-v.svg (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/view-list-v.svg (revision 33253) @@ -0,0 +1,147 @@ + + + + + + +li:view-list-v* + + + +/lht_tree_doc/roots/view-list-v* + + +li:view-list-v* + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID + + +ha:view.ID + + + + + +/lht_tree_doc/roots/view-list-v*->/lht_tree_doc/roots/view-list-v*/children/view.ID + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID/children/type + + +type +string + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID->/lht_tree_doc/roots/view-list-v*/children/view.ID/children/type + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID/children/title + + +title +string + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID->/lht_tree_doc/roots/view-list-v*/children/view.ID/children/title + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID/children/description + + +description +string + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID->/lht_tree_doc/roots/view-list-v*/children/view.ID/children/description + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID/children/bbox + + +li:bbox +coord + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID->/lht_tree_doc/roots/view-list-v*/children/view.ID/children/bbox + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID/children/xy + + +li:xy +coord + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID->/lht_tree_doc/roots/view-list-v*/children/view.ID/children/xy + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID/children/objs.ID + + +li:objs.ID + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID->/lht_tree_doc/roots/view-list-v*/children/view.ID/children/objs.ID + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID/children/objs.ID/children/id + + +li:id + + + + + +/lht_tree_doc/roots/view-list-v*/children/view.ID/children/objs.ID->/lht_tree_doc/roots/view-list-v*/children/view.ID/children/objs.ID/children/id + + + + + Index: tags/2.3.0/doc/developer/lihata_format/view-list-v1.dot =================================================================== --- tags/2.3.0/doc/developer/lihata_format/view-list-v1.dot (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/view-list-v1.dot (revision 33253) @@ -0,0 +1,19 @@ +digraph "li:view-list-v1" { + "/lht_tree_doc/roots/view-list-v1" [label="li:view-list-v1\n\n" URL="tree.html#/lht_tree_doc/roots/view-list-v1" tooltip="a list of view items (locations and objects to highlight on the board, e.g. for DRC violations)"] + "/lht_tree_doc/roots/view-list-v1/children/view.ID" [label="ha:view.ID\n\n" URL="tree.html#/lht_tree_doc/roots/view-list-v1/children/view.ID" tooltip="a view item; ID is a 32 bit signed integer, unique within the view list"] + "/lht_tree_doc/roots/view-list-v1" -> "/lht_tree_doc/roots/view-list-v1/children/view.ID" + "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/type" [label="type\nstring\n" URL="tree.html#/lht_tree_doc/roots/view-list-v1/children/view.ID/children/type" tooltip="free form short text for type of the entry; the GUI may group items by type"] + "/lht_tree_doc/roots/view-list-v1/children/view.ID" -> "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/type" + "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/title" [label="title\nstring\n" URL="tree.html#/lht_tree_doc/roots/view-list-v1/children/view.ID/children/title" tooltip="free form short text for the title of the entry; the GUI typically uses this in brief listings"] + "/lht_tree_doc/roots/view-list-v1/children/view.ID" -> "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/title" + "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/description" [label="description\nstring\n" URL="tree.html#/lht_tree_doc/roots/view-list-v1/children/view.ID/children/description" tooltip="free form long text for the detailed description of the entry "] + "/lht_tree_doc/roots/view-list-v1/children/view.ID" -> "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/description" + "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/bbox" [label="li:bbox\ncoord\n" URL="tree.html#/lht_tree_doc/roots/view-list-v1/children/view.ID/children/bbox" tooltip="optional: 4 coordinates in x1;y1;x2;y2 order that describes the bounding box of the view in board space coordinates; when available, the preview or go-to will use this for view box"] + "/lht_tree_doc/roots/view-list-v1/children/view.ID" -> "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/bbox" + "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/xy" [label="li:xy\ncoord\n" URL="tree.html#/lht_tree_doc/roots/view-list-v1/children/view.ID/children/xy" tooltip="optional: 2 coordinates in x;y order that describes a specific board location"] + "/lht_tree_doc/roots/view-list-v1/children/view.ID" -> "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/xy" + "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID" [label="li:objs.ID\n\n" URL="tree.html#/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID" tooltip="a group of related objects; there should be at most two groups with ID 0 and 1. These objects are often highlighted in red and blue."] + "/lht_tree_doc/roots/view-list-v1/children/view.ID" -> "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID" + "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID/children/id" [label="li:id\n\n" URL="tree.html#/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID/children/id" tooltip="objects are specified as a list of object IDs (32 bit integers)"] + "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID" -> "/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID/children/id" +} Index: tags/2.3.0/doc/developer/lihata_format/view-list-v1.svg =================================================================== --- tags/2.3.0/doc/developer/lihata_format/view-list-v1.svg (nonexistent) +++ tags/2.3.0/doc/developer/lihata_format/view-list-v1.svg (revision 33253) @@ -0,0 +1,147 @@ + + + + + + +li:view-list-v1 + + + +/lht_tree_doc/roots/view-list-v1 + + +li:view-list-v1 + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID + + +ha:view.ID + + + + + +/lht_tree_doc/roots/view-list-v1->/lht_tree_doc/roots/view-list-v1/children/view.ID + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID/children/type + + +type +string + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID->/lht_tree_doc/roots/view-list-v1/children/view.ID/children/type + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID/children/title + + +title +string + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID->/lht_tree_doc/roots/view-list-v1/children/view.ID/children/title + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID/children/description + + +description +string + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID->/lht_tree_doc/roots/view-list-v1/children/view.ID/children/description + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID/children/bbox + + +li:bbox +coord + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID->/lht_tree_doc/roots/view-list-v1/children/view.ID/children/bbox + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID/children/xy + + +li:xy +coord + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID->/lht_tree_doc/roots/view-list-v1/children/view.ID/children/xy + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID + + +li:objs.ID + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID->/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID/children/id + + +li:id + + + + + +/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID->/lht_tree_doc/roots/view-list-v1/children/view.ID/children/objs.ID/children/id + + + + + Index: tags/2.3.0/doc/developer/mods3/README =================================================================== --- tags/2.3.0/doc/developer/mods3/README (nonexistent) +++ tags/2.3.0/doc/developer/mods3/README (revision 33253) @@ -0,0 +1,10 @@ +Run ./gne.sh to regenerate index.html. + +It depends on the following tools to be installed: + +- shell, awk +- sloccount +- netpbm +- animator (svn://repo.hu/animator/trunk) +- animpie - needs to be symlinked or copied to path from animator/test (sorry) + Index: tags/2.3.0/doc/developer/mods3/after.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/mods3/after.png =================================================================== --- tags/2.3.0/doc/developer/mods3/after.png (nonexistent) +++ tags/2.3.0/doc/developer/mods3/after.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/mods3/after.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/mods3/before.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/mods3/before.png =================================================================== --- tags/2.3.0/doc/developer/mods3/before.png (nonexistent) +++ tags/2.3.0/doc/developer/mods3/before.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/mods3/before.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/mods3/deps.svg =================================================================== --- tags/2.3.0/doc/developer/mods3/deps.svg (nonexistent) +++ tags/2.3.0/doc/developer/mods3/deps.svg (revision 33253) @@ -0,0 +1,1663 @@ + + + + + + +plugin_deps + + + +user + +user + + + +acompnet + +acompnet + + + +user->acompnet + + + + + +act_draw + +act_draw + + + +user->act_draw + + + + + +act_read + +act_read + + + +user->act_read + + + + + +ar_cpcb + +ar_cpcb + + + +user->ar_cpcb + + + + + +asm + +asm + + + +user->asm + + + + + +autocrop + +autocrop + + + +user->autocrop + + + + + +autoplace + +autoplace + + + +user->autoplace + + + + + +autoroute + +autoroute + + + +user->autoroute + + + + + +cam + +cam + + + +user->cam + + + + + +query + +query + + + +user->query + + + + + +ddraft + +ddraft + + + +user->ddraft + + + + + +diag + +diag + + + +user->diag + + + + + +dialogs + +dialogs + + + +user->dialogs + + + + + +distalign + +distalign + + + +user->distalign + + + + + +distaligntext + +distaligntext + + + +user->distaligntext + + + + + +djopt + +djopt + + + +user->djopt + + + + + +draw_fab + +draw_fab + + + +user->draw_fab + + + + + +report + +report + + + +user->report + + + + + +drc_orig + +drc_orig + + + +user->drc_orig + + + + + +expfeat + +expfeat + + + +user->expfeat + + + + + +export_bom + +export_bom + + + +user->export_bom + + + + + +export_dsn + +export_dsn + + + +user->export_dsn + + + + + +export_dxf + +export_dxf + + + +user->export_dxf + + + + + +export_excellon + +export_excellon + + + +user->export_excellon + + + + + +export_fidocadj + +export_fidocadj + + + +user->export_fidocadj + + + + + +export_gcode + +export_gcode + + + +user->export_gcode + + + + + +millpath + +millpath + + + +user->millpath + + + + + +export_gerber + +export_gerber + + + +user->export_gerber + + + + + +export_ipcd356 + +export_ipcd356 + + + +user->export_ipcd356 + + + + + +export_lpr + +export_lpr + + + +user->export_lpr + + + + + +export_ps + +export_ps + + + +user->export_ps + + + + + +export_oldconn + +export_oldconn + + + +user->export_oldconn + + + + + +export_openems + +export_openems + + + +user->export_openems + + + + + +export_openscad + +export_openscad + + + +user->export_openscad + + + + + +export_png + +export_png + + + +user->export_png + + + + + +export_stat + +export_stat + + + +user->export_stat + + + + + +export_stl + +export_stl + + + +user->export_stl + + + + + +export_svg + +export_svg + + + +user->export_svg + + + + + +export_test + +export_test + + + +user->export_test + + + + + +export_vfs_fuse + +export_vfs_fuse + + + +user->export_vfs_fuse + + + + + +export_vfs_mc + +export_vfs_mc + + + +user->export_vfs_mc + + + + + +export_xy + +export_xy + + + +user->export_xy + + + + + +extedit + +extedit + + + +user->extedit + + + + + +io_lihata + +io_lihata + + + +user->io_lihata + + + + + +exto_std + +exto_std + + + +user->exto_std + + + + + +fontmode + +fontmode + + + +user->fontmode + + + + + +fp_board + +fp_board + + + +user->fp_board + + + + + +fp_fs + +fp_fs + + + +user->fp_fs + + + + + +fp_wget + +fp_wget + + + +user->fp_wget + + + + + +hid_batch + +hid_batch + + + +user->hid_batch + + + + + +hid_gtk2_gdk + +hid_gtk2_gdk + + + +user->hid_gtk2_gdk + + + + + +hid_gtk2_gl + +hid_gtk2_gl + + + +user->hid_gtk2_gl + + + + + +hid_lesstif + +hid_lesstif + + + +user->hid_lesstif + + + + + +hid_remote + +hid_remote + + + +user->hid_remote + + + + + +import_calay + +import_calay + + + +user->import_calay + + + + + +import_dsn + +import_dsn + + + +user->import_dsn + + + + + +import_edif + +import_edif + + + +user->import_edif + + + + + +import_fpcb_nl + +import_fpcb_nl + + + +user->import_fpcb_nl + + + + + +import_gnetlist + +import_gnetlist + + + +user->import_gnetlist + + + + + +import_hpgl + +import_hpgl + + + +user->import_hpgl + + + + + +import_ipcd356 + +import_ipcd356 + + + +user->import_ipcd356 + + + + + +import_ltspice + +import_ltspice + + + +user->import_ltspice + + + + + +import_mentor_sch + +import_mentor_sch + + + +user->import_mentor_sch + + + + + +import_mucs + +import_mucs + + + +user->import_mucs + + + + + +import_net_action + +import_net_action + + + +user->import_net_action + + + + + +import_net_cmd + +import_net_cmd + + + +user->import_net_cmd + + + + + +import_netlist + +import_netlist + + + +user->import_netlist + + + + + +import_pxm_gd + +import_pxm_gd + + + +user->import_pxm_gd + + + + + +import_pxm_pnm + +import_pxm_pnm + + + +user->import_pxm_pnm + + + + + +import_sch + +import_sch + + + +user->import_sch + + + + + +import_sch2 + +import_sch2 + + + +user->import_sch2 + + + + + +import_tinycad + +import_tinycad + + + +user->import_tinycad + + + + + +import_ttf + +import_ttf + + + +user->import_ttf + + + + + +io_autotrax + +io_autotrax + + + +user->io_autotrax + + + + + +io_dsn + +io_dsn + + + +user->io_dsn + + + + + +io_eagle + +io_eagle + + + +user->io_eagle + + + + + +shape + +shape + + + +user->shape + + + + + +io_hyp + +io_hyp + + + +user->io_hyp + + + + + +io_kicad + +io_kicad + + + +user->io_kicad + + + + + +io_kicad_legacy + +io_kicad_legacy + + + +user->io_kicad_legacy + + + + + +io_mentor_cell + +io_mentor_cell + + + +user->io_mentor_cell + + + + + +io_pcb + +io_pcb + + + +user->io_pcb + + + + + +io_tedax + +io_tedax + + + +user->io_tedax + + + + + +jostle + +jostle + + + +user->jostle + + + + + +propedit + +propedit + + + +user->propedit + + + + + +loghid + +loghid + + + +user->loghid + + + + + +mincut + +mincut + + + +user->mincut + + + + + +oldactions + +oldactions + + + +user->oldactions + + + + + +order + +order + + + +user->order + + + + + +order_pcbway + +order_pcbway + + + +user->order_pcbway + + + + + +polycombine + +polycombine + + + +user->polycombine + + + + + +polystitch + +polystitch + + + +user->polystitch + + + + + +puller + +puller + + + +user->puller + + + + + +renumber + +renumber + + + +user->renumber + + + + + +rubberband_orig + +rubberband_orig + + + +user->rubberband_orig + + + + + +script + +script + + + +user->script + + + + + +serpentine + +serpentine + + + +user->serpentine + + + + + +shand_cmd + +shand_cmd + + + +user->shand_cmd + + + + + +sketch_route + +sketch_route + + + +user->sketch_route + + + + + +smartdisperse + +smartdisperse + + + +user->smartdisperse + + + + + +stroke + +stroke + + + +user->stroke + + + + + +teardrops + +teardrops + + + +user->teardrops + + + + + +tool_std + +tool_std + + + +user->tool_std + + + + + +vendordrill + +vendordrill + + + +user->vendordrill + + + + + +lib_gensexpr + +lib_gensexpr + + + +ar_cpcb->lib_gensexpr + + + + + +lib_compat_help + +lib_compat_help + + + +ar_cpcb->lib_compat_help + + + + + +lib_netmap + +lib_netmap + + + +ar_cpcb->lib_netmap + + + + + +autoroute->lib_compat_help + + + + + +cam->query + + + + + +draw_fontsel + +draw_fontsel + + + +dialogs->draw_fontsel + + + + + +draw_csect + +draw_csect + + + +dialogs->draw_csect + + + + + +lib_hid_common + +lib_hid_common + + + +dialogs->lib_hid_common + + + + + +lib_hid_pcbui + +lib_hid_pcbui + + + +dialogs->lib_hid_pcbui + + + + + +lib_hid_pcbui->lib_hid_common + + + + + +draw_fab->report + + + + + +export_fidocadj->lib_compat_help + + + + + +export_gcode->millpath + + + + + +lib_polyhelp + +lib_polyhelp + + + +millpath->lib_polyhelp + + + + + +export_gerber->export_excellon + + + + + +export_ipcd356->lib_compat_help + + + + + +export_lpr->export_ps + + + + + +export_ps->lib_compat_help + + + + + +export_openems->lib_polyhelp + + + + + +export_openscad->lib_polyhelp + + + + + +lib_vfs + +lib_vfs + + + +export_vfs_fuse->lib_vfs + + + + + +lib_vfs->propedit + + + + + +export_vfs_mc->lib_vfs + + + + + +export_xy->export_bom + + + + + +extedit->io_lihata + + + + + +io_lihata->lib_compat_help + + + + + +exto_std->lib_compat_help + + + + + +fp_wget->fp_fs + + + + + +lib_wget + +lib_wget + + + +fp_wget->lib_wget + + + + + +lib_gtk_common + +lib_gtk_common + + + +hid_gtk2_gdk->lib_gtk_common + + + + + +lib_gtk_common->lib_hid_common + + + + + +hid_gtk2_gl->lib_gtk_common + + + + + +lib_hid_gl + +lib_hid_gl + + + +hid_gtk2_gl->lib_hid_gl + + + + + +hid_lesstif->lib_hid_common + + + + + +import_dsn->lib_gensexpr + + + + + +import_dsn->lib_compat_help + + + + + +import_ipcd356->lib_compat_help + + + + + +import_mentor_sch->lib_gensexpr + + + + + +import_mucs->lib_compat_help + + + + + +io_autotrax->lib_polyhelp + + + + + +io_dsn->lib_gensexpr + + + + + +io_dsn->lib_netmap + + + + + +io_eagle->lib_compat_help + + + + + +io_eagle->shape + + + + + +io_hyp->lib_netmap + + + + + +io_kicad->lib_gensexpr + + + + + +io_kicad->lib_compat_help + + + + + +io_kicad->shape + + + + + +io_kicad_legacy->io_kicad + + + + + +io_pcb->lib_compat_help + + + + + +io_tedax->lib_compat_help + + + + + +io_tedax->lib_netmap + + + + + +order_pcbway->lib_wget + + + + + +order_pcbway->order + + + + + Index: tags/2.3.0/doc/developer/mods3/export.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/mods3/export.png =================================================================== --- tags/2.3.0/doc/developer/mods3/export.png (nonexistent) +++ tags/2.3.0/doc/developer/mods3/export.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/mods3/export.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/mods3/feature.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/mods3/feature.png =================================================================== --- tags/2.3.0/doc/developer/mods3/feature.png (nonexistent) +++ tags/2.3.0/doc/developer/mods3/feature.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/mods3/feature.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/mods3/fp.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/mods3/fp.png =================================================================== --- tags/2.3.0/doc/developer/mods3/fp.png (nonexistent) +++ tags/2.3.0/doc/developer/mods3/fp.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/mods3/fp.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/mods3/gen.sh =================================================================== --- tags/2.3.0/doc/developer/mods3/gen.sh (nonexistent) +++ tags/2.3.0/doc/developer/mods3/gen.sh (revision 33253) @@ -0,0 +1,188 @@ +#!/bin/sh + +path=../../../src_plugins + +sloc() +{ + (cd "$1" && sloccount .) | awk '/^Total Phys/ { size=$9; sub(",", "", size); print size }' +} + +gen_pie() +{ + local bn=$1 code_size=$2 color=$3 + echo "" + echo "@slice" + echo "$code_size" + echo "@label" + echo "$bn ($code_size)" + if test ! -z "$color" + then + echo "@color" + echo "$color" + fi +} + +rm -f *.pie *.lines + +echo "#autogenerated by gen.sh" > mods.pie +echo "#autogenerated by gen.sh" > after.pie + +echo Core >&2 +tmp=/tmp/pcb-mods-stat +mkdir $tmp +cp -r ../../../src/*.c ../../../src/*.h ../../../src/Makefile* $tmp +code_size=`sloc $tmp` +gen_pie "core" $code_size "#00ff88" >> after.pie + +#echo 3rd >&2 +#code_size=`sloc ../../src_3rd` +#gen_pie "3rd" $code_size >> after.pie + +echo "" > classes +echo ' +digraph plugin_deps { +overlap=scale +'> deps.dot + +( +cat pre.html +for n in $path/* +do + if test -d "$n" + then + echo $n >&2 + bn=`basename $n` + code_size=`sloc $n` + total=$(($total + $code_size)) + class=`cat $n/*.pup | sed ' + /^$class/ { + s/$class *// + s/[()]//g + p + } + { d } + ' ` + echo "$class" >> classes + + echo "$code_size" >> $class.lines + gen_pie $bn $code_size >> $class.pie + +# case $bn in +# gpmi) echo "@pull" >> mods.pie; echo "0.1" >> mods.pie;; +# esac + + echo "$bn$code_size" + cat $n/*.pup | awk -v "plugin=$n" ' + BEGIN { + q = "\"" + dep="/dev/fd/3" + sub(".*/", "", plugin) + } + /^[$]/ { + key=$1 + sub("[$]", "", key) + $1="" + DB[key]=$0 + next + } + + /^dep/ { + print q plugin q "->" q $2 q >> dep + } + + /^[A-Za-z]/ { + key=$1 + $1="" + DB[key]=$0 + next + } + + function strip(s) { + sub("^[ \t]*", "", s) + sub("[ \t]*$", "", s) + return s + } + + END { + st = DB["state"] + if (st ~ "partial") + clr = "bgcolor=\"yellow\"" + else if (st ~ "works") + clr = "bgcolor=\"lightgreen\"" + else if ((st ~ "fail") || (st ~ "disable")) + clr = "bgcolor=\"red\"" + else + clr="" + + clr2 = clr + if (clr2 != "") { + sub("bgcolor=\"", "", clr2) + sub("\"", "", clr2) + print "@color" >> "mods.pie" + print clr2 >> "mods.pie" + } + + print "" st + if (DB["lstate"] != "") + print "
(" strip(DB["lstate"]) ")" + + dfl = DB["default"] + if (dfl ~ "buildin") + clr = "bgcolor=\"lightgreen\"" + else if (dfl ~ "plugin") + clr = "bgcolor=\"yellow\"" + else if ((dfl ~ "disable-all") || (dfl ~ "disable")) + clr = "bgcolor=\"red\"" + else + clr="" + + print "" dfl + if (DB["ldefault"] != "") + print "
(" strip(DB["ldefault"]) ")" + print "" DB["class"] + print "" DB["long"] + if (int(DB["autoload"])) + print q "user" q "->" q plugin q " [color=\"#a0a0a0\"]" >> dep + + class = DB["class"] + if (class ~ "io") + clr = "fillcolor=\"#ffa0a0\"" + else if (class ~ "import") + clr = "fillcolor=\"#a0ffff\"" + else if (class ~ "export") + clr = "fillcolor=\"#a0ffff\"" + else if (class ~ "lib") + clr = "fillcolor=\"#a0a0a0\"" + else if (class ~ "hid") + clr = "fillcolor=\"#a0a0ff\"" + print q plugin q " [style=filled " clr "]" >> dep + } + ' + fi +done +cat post.html +gen_pie "plugins" "$total" "#0088ff" >> after.pie +) > index.html 3>>deps.dot +echo "}" >>deps.dot + +twopi -Tsvg deps.dot > deps.svg + +for n in *.lines +do + lines=`awk '{ sum += $1 } END { print sum }' < $n` + bn=${n%%.lines} + gen_pie $bn $lines >> mods.pie +done + + +classes=`sort < classes | uniq` + +for n in $classes after mods +do + animpie < $n.pie | animator -H -d $n + pngtopnm ${n}0000.png | pnmcrop | pnmtopng > $n.png + rm ${n}0000.png +done + + +rm classes Property changes on: tags/2.3.0/doc/developer/mods3/gen.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/developer/mods3/hid.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/mods3/hid.png =================================================================== --- tags/2.3.0/doc/developer/mods3/hid.png (nonexistent) +++ tags/2.3.0/doc/developer/mods3/hid.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/mods3/hid.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/mods3/import.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/mods3/import.png =================================================================== --- tags/2.3.0/doc/developer/mods3/import.png (nonexistent) +++ tags/2.3.0/doc/developer/mods3/import.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/mods3/import.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/mods3/index.html =================================================================== --- tags/2.3.0/doc/developer/mods3/index.html (nonexistent) +++ tags/2.3.0/doc/developer/mods3/index.html (revision 33253) @@ -0,0 +1,701 @@ + + + pcb-rnd modularization + + +

pcb-rnd modularization

+

Why bother...

+I believe good software should be modular. This is especially important in +the context of large software, such as CAD applications. There should be +a thin core that can model the world and provide the basic operations defined +on it but anything else should go in separate modules. +

+Fortunately PCB already had a strong infrastructure supporting this idea. +It has dynamic loadable plugins and the GUI and exporters are in separate +HID modules. While working on pcb-gpmi and later pcb-rnd, I added the +gpmi module as a separate plugin. +

+In version 1.0.8 to 1.1.0 a considerable chunk of core code has been moved into +core plugins. A core plugin is just a plugin that is +maintained together with the core, in the same repository, still the code is +somewhat detached from the core. More importantly, the user can choose, for +each plugin, separately: +

    +
  • to compile it as a buildin (static-link it into the pcb executable) +
  • to compile it as a plugin (dynamic-link it runtime, if the .so is installed in the plugins/ directory) +
  • to disable the plugin, so it is not compiled at all +
+

+I believe such modularization has benefits on multiple levels: +

    +
  • it is possible to compile smaller, potentially faster executables by omitting features the specific user would never use anyway +
  • in a distribution dynamic-link plugins can be distributed as separate packages providing the user with the option to decide what features to install +
  • such plugins have to have some sort of APIs if they want to reference each other or if the code needs to reference them; such an API may not (and often did not) exist when the code is part of the core +
+ +

Progress in charts

+

Before-after

+All numbers are in SLOC +and are acquired running sloccount on the given directory. While lines of +code alone is not a true measure of complexity, it's a good estimation. The +slices of pie charts are the major components of the pcb-rnd executable. +
+ +
        +
Before modularization: pcb-rnd version 1.0.7 +
Note: gpmi was already a plugin +
+ After modularization: current pcb-rnd +
Note: gpmi is part of the "plugins" slice +
+
+

Zooming on to the plugins

+

+ + + +
total size per class
+
IO plugins
+
+ + + + +
feature plugins
+
export plugins
+
+ + + +
HID plugins
+
import plugins
+
+ + + +
library plugins
+
footprint plugins
+
+ +

+(Red means the plugin doesn't really work). + +

Progress in numbers

+Below is a table with the summary of core plugins. + +
module size [sloc] status configure
default
class description + + +
acompnet304 + WIP + disable + feature + Auto-complete the current network. A very limited autorouter/assistant. +
act_draw603 + works + buildin + feature + Expose drawing related API as actions +
act_read416 + works + buildin + feature + Data access related API as actions +
ar_cpcb319 + WIP + buildin + feature + Autoroute using external tool c-pcb +
asm559 + works + buildin + feature + hand assembly assistant GUI +
autocrop51 + works + buildin + feature + Reduce the board dimensions to just enclose the objects on the board. +
autoplace645 + works + buildin + feature + Automatically place subcircuits. +
autoroute4385 + works + buildin + feature + Automatically route selected or all rats. This is the original autorouter. +
cam1595 + works + buildin + export + Configurable output job based batch exporting +
ddraft2129 + WIP + buildin + export + Actions and a command interpreter for supporting advanced/precise 2 dimensional drafting +
diag803 + works + disable + feature + Actions for pcb-rnd core diagnostics, intended for developers. These are not in core because end users normally don't need these. As a plugin, due to dynamic loading, it can be dropped on an existing pcb-rnd installation with minimal risk of scaring away a reproducible bug. +
dialogs8918 + works + disable + feature + Interactive core functionality: HID-independent GUI dialogs (enabled by GUI HIDs) +
distalign443 + works + buildin + feature + Introducing Align() and Distribute(), which work much like the similarly named functions in Visio. Given that PCB does not have the concept of "first selected object" to draw on, the reference points can be selected by arguments. +
distaligntext474 + works + buildin + feature + Same as distalign, operates on text objects. +
djopt2250 + works + buildin + feature + Various board optimization algorithms. +
draw_csect800 + works + disable + feature + Draw cross section and layer map. +
draw_fab290 + works + buildin + feature + Draw the fab layer (for various exporters). +
draw_fontsel143 + works + disable + feature + Draw the font selector GUI +
drc_orig352 + + buildin + feature + A few simple, hardwired Design Rule Checks. +
expfeat31 + works + disable + feature + Staging plugin for experimenting with new actions and dialogs before getting them into core or other plugins +
export_bom218 + works + buildin + export + Export bom (Bill of Materials) +
export_dsn445 + works + buildin + export + Export specctra .dsn files +
export_dxf2340 + works + buildin + export + Export dxf +
export_excellon583 + works + buildin + export + Export to excellon drill/cnc files +
export_fidocadj274 + WIP + buildin + export + Export to FidoCadJ format (.fcd) +
export_gcode309 + WIP + buildin + export + Export to gcode +
export_gerber1198 + works + buildin + export + Export to gerber +
export_ipcd356383 + works + buildin + export + IPC-D-356 Netlist export. +
export_lpr104 + works + buildin + export + Export to lpr (using export_ps to generate postscript) +
export_oldconn240 + works + buildin + export + Export subc/terminal connection map in an old, custom file format +
export_openems2186 + WIP + buildin + export + Export copper to OpenEMS simulation +
export_openscad719 + WIP + buildin + export + Export openscad +
export_png1457 + works + buildin + export + Export to png, gif and jpeg +
export_ps1566 + works + buildin + export + Export postscript or embedded postscript. +
export_stat320 + works + buildin + export + Export various board statistics in lihata format +
export_stl189 + WIP + buildin + export + Export stl (triangulated surface) +
export_svg719 + works + buildin + export + Scalable Vector Graphics (SVG) exporter +
export_test90 + WIP + disable + export + A thin layer of code to dump exporter calls for testing the HID exporter API. +
export_vfs_fuse311 + WIP + disable + export + Export all data and config of a board to a FUSE mountable filesystem +
export_vfs_mc149 + WIP + disable + export + Export all data and config of a board to GNU mc +
export_xy987 + works + buildin + export + Template based export of XY centroid subcircuit data e.g. for pick & place. +
extedit352 + works + buildin + feature + invoke external program to edit parts of the current board +
exto_std1261 + WIP + buildin + feature + Extended objects for: line-of-vias, dimension +
fontmode257 + works + buildin + feature + Font editing actions. +
fp_board120 + WIP + buildin + fp + Footprint: load a board and expose all the unique subcircuits on that board as a footprint library +
fp_fs439 + works + buildin + fp + Footprint: file system based implementation. Used to be called Newlib: load footprints from directories. Run external processes for the parametric footprints. +
fp_wget686 + works + buildin + fp + Footprint: get static (file) footprints from the web, e.g. from http://gedasymbols.org +
hid_batch325 + works + buildin + hid + HID without GUI: read actions from stdin. +
hid_gtk2_gdk1288 + works + buildin + hid + GUI: GTK2 HID with GDK software rendering. +
hid_gtk2_gl769 + works + buildin + hid + GUI: GTK2 with opengl rendering +
hid_lesstif9199 + works + buildin + hid + GUI: the lesstif HID. +
hid_remote1100 + WIP + disable-all + hid + Remote access HID: implement a protocol and use it to relay between a core and a remote HID implementation. +
import_calay213 + works + buildin + import + Import the netlist and footprints from a calay netlist. +
import_dsn268 + works + buildin + import + Import specctra .dsn files +
import_edif3637 + works + buildin + import + Import plugin for netlists in the EDIF format. +
import_fpcb_nl192 + works + buildin + import + Import the netlist and footprints from freepcb format (exported by e.g. easyeda) +
import_gnetlist135 + works + buildin + import + Import gEDA/gschem schematics running gnetlist +
import_hpgl131 + works + buildin + import + Emulate a plotter and import the plot as lines, arcs and polygons. +
import_ipcd356430 + works + buildin + import + IPC-D-356 Netlist and pad centroid import +
import_ltspice566 + works + buildin + import + Import the netlist and footprints from an ltspice .asc and .net pair of files +
import_mentor_sch522 + works + buildin + import + Import Mentor Graphics Design Capture from flattened .edf netlist, using a parts conversion table. +
import_mucs122 + works + buildin + import + Import lines and vias from MUCS unixplot .pl files +
import_net_action75 + works + buildin + import + Import the netlist and footprints from an action script. +
import_net_cmd68 + works + buildin + import + Import schematics/netlist by running a commandline +
import_netlist142 + works + buildin + import + Import plugin for netlists in the classic pcb netlist format. +
import_pxm_gd103 + works + buildin + import + Import png, gif and jpeg using libgd +
import_pxm_pnm119 + works + buildin + import + Import pnm P4, P5 and P6 into pcb-rnd pixmaps +
import_sch321 + works + buildin + import + Imports footprints and netlist data from the schematics (or some other source). +
import_sch2496 + WIP + buildin + import + Imports footprints and netlist data from the schematics (or some other source). +
import_tinycad199 + works + buildin + import + Import the netlist and footprints from a tinycad netlist. +
import_ttf163 + WIP + buildin + import + Import outline ttf glyphs into the current font, either as polygons or lines +
io_autotrax1584 + works + buildin + io + Import and export autotrax layouts and footprints. +
io_dsn1673 + works + disable + io + Load and save specctra DSN files +
io_eagle4116 + works + buildin + io + Load the design from eagle's xml and binary formats. +
io_hyp4097 + works + buildin + io + Import plugin for hyperlynx geometry (no polygons yet). +
io_kicad3572 + works + buildin + io + Load and save the design and footprints in Kicad's s-expression format - this is the new, currently preferred format in Kicad. +
io_kicad_legacy901 + works + buildin + io + Export the design and footprints in Kicad's legacy format. +
io_lihata4338 + works + buildin + io + Load and save the design and footprints in the lihata board format. +
io_mentor_cell1875 + WIP + disable + io + Load Mentor Graphics cell footprint library and make footprints available (e.g. for fp_board) +
io_pcb2948 + works + buildin + io + Load and save the design and footprints in the original gEDA/PCB text format. +
io_tedax2565 + works + buildin + io + Import and export tEDAx netlists and footprints. +
jostle420 + works + buildin + feature + Pushes lines out of the way. +
lib_compat_help1254 + works + buildin + lib + a library of functions providing a simplified API compatibility layer, mainly for I/O plugins +
lib_gensexpr13 + works + disable-all + lib + S-expression parser lib +
lib_gtk_common5689 + works + disable-all + lib + hid_gtk* common code (regardless of rendering mechanism: for both gdk sw rendering and gl) +
lib_hid_common2389 + works + disable-all + lib + hidlib common helper functions for non-PCB GUI +
lib_hid_gl1083 + works + disable-all + lib + generic openGL renderer shared among GUI HIDs +
lib_hid_pcbui2268 + works + disable-all + lib + PCB related helper functions for GUI HIDs +
lib_netmap218 + works + disable-all + lib + create disposable cross-reference maps between all objects and all nets +
lib_polyhelp766 + works + buildin + lib + functions to help plugins processing polygons and PolyHatch() action +
lib_vfs458 + works + disable-all + lib + Retrieve, sort and query data under VFS export plugins +
lib_wget67 + works + disable-all + lib + retrieve files from the web using wget(1) +
loghid295 + WIP + disable + feature + Sits between a HID (or exporter) and the core and logs all core->plugin calls made through the HID structure. +
millpath491 + WIP + disable + feature + Calculate and simulate toolpath for milling away opper +
mincut889 + works + buildin + feature + Use the minimal cut algorithm to indicate shorts: instead of highlighting two random pins/pads, try to highlight the least number of objects that connect the two networks. +
oldactions289 + works + disable + feature + Random collection of old/obsolete actions. Bell(): audible feedback, DumpLibrary(): print footprint library on stdout, a set of debug actions useful for writing pcb scripts: Debug(), DebugXY(), Return(). Old plugin actions to toggle or set settings that are now accessible via the unified config system (vendordrill, djopt) +
order309 + WIP + disable + feature + order boards through the Internet +
order_pcbway612 + WIP + disable + feature + order from PCBWay through the Internet +
polycombine206 + works + buildin + feature + The selected polygons are combined together according to the ordering of their points. +
polystitch95 + works + buildin + feature + The polygon under the cursor (based on closest-corner) is stitched together with the polygon surrounding it on the same layer. Use with pstoedit conversions where there's a "hole" in the shape - select the hole. +
propedit1984 + works + buildin + feature + List and edit properties of a group of objects. +
puller1747 + works + buildin + feature + Pull traces to minimize their length. +
query2318 + works + buildin + feature + pcb-rnd query language: execute expressions on objects and rules for the programmed drc. +
renumber321 + works + buildin + feature + Renumber subcircuits (renaming them) and generate a text file for back annotation. +
report896 + works + buildin + feature + Report() and ReportObject() actions - print a report about design objects. +
rubberband_orig1219 + works + buildin + feature + The original rubberband code. +
script1503 + works + buildin + feature + Load and execute scripts written in any language supported by fungw +
serpentine369 + WIP + disable-all + feature + Create serpentines on existing lines. +
shand_cmd165 + works + buildin + feature + vi-like command shorthands (1..3 character long commands) +
shape860 + works + buildin + feature + Generate objects of regular shape (regular polygons, circle, round rect) +
sketch_route2702 + WIP + disable + feature + TODO +
smartdisperse164 + works + buildin + feature + Improve the initial dispersion of subcircuits by choosing an order based on the netlist, rather than the arbitrary subcircuit order. This isn't the same as a global autoplace, it's more of a linear autoplace. It might make some useful local groupings. For example, you should not have to chase all over the board to find the resistor that goes with a given LED. +
stroke290 + works + buildin + feature + Configurable gesture recognition with libstroke. +
teardrops215 + works + buildin + feature + Draw teardrops on pins. +
tool_std2255 + works + buildin + feature + The basic set of PCB drawing tools +
vendordrill514 + works + buildin + feature + Vendor drill mapping. +
+ +

Classes

+

+Each plugin implements a class (rarely a set of classes). Classes are: + +
name description +
feature random features directly accessible for the user, usually actions +
lib support code library for other plugins (core doesn't depend on these); functionality not directly accessible for the user but other plugins may depend on it +
hid Human Interface Device: interactive user interface, usually GUI +
import load alien formats into the design space +
export save (parts of) the design space in alien formats +
fp footprint (element) library implementation +
io native file format (save & load) implementation +
+ +

Status

+

+Common status column values mean: + +
name description +
works production quality code - configures, compiles, tested +
WIP work in progress: the plugin may be avaialble for testing but is not yet production quality +
abandoned unmaintained plugin; may be in working condition but there is no developer supporting it +
deprecated legacy plugin scheduled for removal; may still work but will soon be removed; if your workflow depends on it, please report ASAP +
+ +

Plugin dependency map

+

+pcb-rnd plugin dependency graph + + + Index: tags/2.3.0/doc/developer/mods3/io.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/mods3/io.png =================================================================== --- tags/2.3.0/doc/developer/mods3/io.png (nonexistent) +++ tags/2.3.0/doc/developer/mods3/io.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/mods3/io.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/mods3/lib.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/mods3/lib.png =================================================================== --- tags/2.3.0/doc/developer/mods3/lib.png (nonexistent) +++ tags/2.3.0/doc/developer/mods3/lib.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/mods3/lib.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/mods3/mods.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/developer/mods3/mods.png =================================================================== --- tags/2.3.0/doc/developer/mods3/mods.png (nonexistent) +++ tags/2.3.0/doc/developer/mods3/mods.png (revision 33253) Property changes on: tags/2.3.0/doc/developer/mods3/mods.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/developer/mods3/post.html =================================================================== --- tags/2.3.0/doc/developer/mods3/post.html (nonexistent) +++ tags/2.3.0/doc/developer/mods3/post.html (revision 33253) @@ -0,0 +1,33 @@ + + +

Classes

+

+Each plugin implements a class (rarely a set of classes). Classes are: + +
name description +
feature random features directly accessible for the user, usually actions +
lib support code library for other plugins (core doesn't depend on these); functionality not directly accessible for the user but other plugins may depend on it +
hid Human Interface Device: interactive user interface, usually GUI +
import load alien formats into the design space +
export save (parts of) the design space in alien formats +
fp footprint (element) library implementation +
io native file format (save & load) implementation +
+ +

Status

+

+Common status column values mean: + +
name description +
works production quality code - configures, compiles, tested +
WIP work in progress: the plugin may be avaialble for testing but is not yet production quality +
abandoned unmaintained plugin; may be in working condition but there is no developer supporting it +
deprecated legacy plugin scheduled for removal; may still work but will soon be removed; if your workflow depends on it, please report ASAP +
+ +

Plugin dependency map

+

+pcb-rnd plugin dependency graph + + + Index: tags/2.3.0/doc/developer/mods3/pre.html =================================================================== --- tags/2.3.0/doc/developer/mods3/pre.html (nonexistent) +++ tags/2.3.0/doc/developer/mods3/pre.html (revision 33253) @@ -0,0 +1,88 @@ + + + pcb-rnd modularization + + +

pcb-rnd modularization

+

Why bother...

+I believe good software should be modular. This is especially important in +the context of large software, such as CAD applications. There should be +a thin core that can model the world and provide the basic operations defined +on it but anything else should go in separate modules. +

+Fortunately PCB already had a strong infrastructure supporting this idea. +It has dynamic loadable plugins and the GUI and exporters are in separate +HID modules. While working on pcb-gpmi and later pcb-rnd, I added the +gpmi module as a separate plugin. +

+In version 1.0.8 to 1.1.0 a considerable chunk of core code has been moved into +core plugins. A core plugin is just a plugin that is +maintained together with the core, in the same repository, still the code is +somewhat detached from the core. More importantly, the user can choose, for +each plugin, separately: +

    +
  • to compile it as a buildin (static-link it into the pcb executable) +
  • to compile it as a plugin (dynamic-link it runtime, if the .so is installed in the plugins/ directory) +
  • to disable the plugin, so it is not compiled at all +
+

+I believe such modularization has benefits on multiple levels: +

    +
  • it is possible to compile smaller, potentially faster executables by omitting features the specific user would never use anyway +
  • in a distribution dynamic-link plugins can be distributed as separate packages providing the user with the option to decide what features to install +
  • such plugins have to have some sort of APIs if they want to reference each other or if the code needs to reference them; such an API may not (and often did not) exist when the code is part of the core +
+ +

Progress in charts

+

Before-after

+All numbers are in SLOC +and are acquired running sloccount on the given directory. While lines of +code alone is not a true measure of complexity, it's a good estimation. The +slices of pie charts are the major components of the pcb-rnd executable. +
+ +
        +
Before modularization: pcb-rnd version 1.0.7 +
Note: gpmi was already a plugin +
+ After modularization: current pcb-rnd +
Note: gpmi is part of the "plugins" slice +
+
+

Zooming on to the plugins

+

+ + + +
total size per class
+
IO plugins
+
+ + + + +
feature plugins
+
export plugins
+
+ + + +
HID plugins
+
import plugins
+
+ + + +
library plugins
+
footprint plugins
+
+ +

+(Red means the plugin doesn't really work). + +

Progress in numbers

+Below is a table with the summary of core plugins. + +
module size [sloc] status configure
default
class description + + Index: tags/2.3.0/doc/developer/new_model_progress/Makefile =================================================================== --- tags/2.3.0/doc/developer/new_model_progress/Makefile (nonexistent) +++ tags/2.3.0/doc/developer/new_model_progress/Makefile (revision 33253) @@ -0,0 +1,2 @@ +roadmap.svg: roadmap.dot + dot -Tsvg < roadmap.dot > roadmap.svg Index: tags/2.3.0/doc/developer/new_model_progress/remove_stats.txt =================================================================== --- tags/2.3.0/doc/developer/new_model_progress/remove_stats.txt (nonexistent) +++ tags/2.3.0/doc/developer/new_model_progress/remove_stats.txt (revision 33253) @@ -0,0 +1,8 @@ +with old model: 1.2.8 +SLOC=200842 +#warnings: 326 +c and h files in src/ and src_plugins/: 817 + +after removal: +SLOC=189893 (removed 10949 sloc, 5.4515% of the code in 1.2.8) + Index: tags/2.3.0/doc/developer/new_model_progress/roadmap.dot =================================================================== --- tags/2.3.0/doc/developer/new_model_progress/roadmap.dot (nonexistent) +++ tags/2.3.0/doc/developer/new_model_progress/roadmap.dot (revision 33253) @@ -0,0 +1,72 @@ +digraph roadmap { + "2016_4" [label="2016\n4th\nquarter" shape=plaintext] + "2017_1" [label="2017\n1st\nquarter" shape=plaintext] + "2017_2" [label="2017\n2nd\nquarter" shape=plaintext] + "2017_3" [label="2017\n3rd\nquarter" shape=plaintext] + "2017_3b" [label="" shape=plaintext] + "2017_4" [label="2017\n4th\nquarter" shape=plaintext] + "2018_1" [label="2018\n1st\nquarter" shape=plaintext] + "2018_2" [label="2018\n2nd\nquarter" shape=plaintext] + + "2016_4" -> "2017_1" [style=invisible arrowhead=none] + "2017_1" -> "2017_2" [style=invisible arrowhead=none] + "2017_2" -> "2017_3" [style=invisible arrowhead=none] + "2017_3" -> "2017_3b" [style=invisible arrowhead=none] + "2017_3b" -> "2017_4" [style=invisible arrowhead=none] + "2017_4" -> "2018_1" [style=invisible arrowhead=none] + "2018_1" -> "2018_2" [style=invisible arrowhead=none] + + lihata [color=green label="Lihata:\nNew native file format\nso we can make our changes\nwithout breaking compatibilty\nor having to wait for mainline"] + layer [color=green label="layer rewrite:\nmuch more detailed model of\nphysical and logical layers"] + subcircuit [color=green label="subcircuit:\nfootprints without special objects"] + binding [color=green label="layer binding:\nabstract layer recipes\nthat are board-independent\nand can be applied on a\ngiven board's stackup"] + compositing [color=green label="layer compositing:\npositive/nagative drawn layers within a group\nallows drawing paste, mask, inverse silk, etc."] + term [color=green label="subcircuit terminals:\ngeneralized pin/pad idea\nthat allows any drawing primitive\nto be a pin or pad"] + elem_replace [color=green label="element replacement:\nreplace the old element model\nwith subcircuits\nmake sure subcircuits can do\nanything an element could do"] + elem_remove [color=red label="element removal:\nremove elements, element-lines, element-arcs\npins, pads and the old circular-only vias\nin favor of subcircuits and pad stacks"] + padstacks [color=green label="pad stacks:\na via (or pin or pad)\nthat can have different,\narbitrary copper shape\non different layer groups"] + bbvia [color=green label="blind/buried via:\na pad stack has per layer info on\ncopper shape, it can\nalso have such info about the drill ends"] + + fp_nolimit [color=green shape=box label="goal:\nfootprints without limitations"] + clean [color=red shape=box label="goal:\nclean, tree based data structure"] + + recur [color=red label="subcircuit in subcircuit"] + hier [color=red label="hierarchical netlists"] + + { rank=same; "2016_4" lihata} + { rank=same; "2017_1" layer} + { rank=same; "2017_2" compositing} + { rank=same; "2017_3" subcircuit} + { rank=same; "2017_3b" binding term} + { rank=same; "2017_4" padstacks} + { rank=same; "2018_1" elem_replace} + { rank=same; "2018_2" elem_remove} + + lihata -> layer + layer -> subcircuit + layer -> binding + layer -> compositing + subcircuit -> binding + subcircuit -> term + subcircuit -> elem_replace + padstacks -> elem_replace + padstacks -> bbvia + binding -> elem_replace + elem_replace -> elem_remove + elem_remove -> clean + + + compositing -> fp_nolimit + binding -> fp_nolimit + term -> fp_nolimit + + compositing -> clean + binding -> clean + term -> clean + + clean -> recur + recur -> hier + + + +} Index: tags/2.3.0/doc/developer/new_model_progress/roadmap.svg =================================================================== --- tags/2.3.0/doc/developer/new_model_progress/roadmap.svg (nonexistent) +++ tags/2.3.0/doc/developer/new_model_progress/roadmap.svg (revision 33253) @@ -0,0 +1,281 @@ + + + + + + +roadmap + + +2016_4 +2016 +4th +quarter + + +2017_1 +2017 +1st +quarter + + +2016_4->2017_1 + + +2017_2 +2017 +2nd +quarter + + +2017_1->2017_2 + + +2017_3 +2017 +3rd +quarter + + +2017_2->2017_3 + + +2017_3b + + +2017_3->2017_3b + + +2017_4 +2017 +4th +quarter + + +2017_3b->2017_4 + + +2018_1 +2018 +1st +quarter + + +2017_4->2018_1 + + +2018_2 +2018 +2nd +quarter + + +2018_1->2018_2 + + +lihata + +Lihata: +New native file format +so we can make our changes +without breaking compatibilty +or having to wait for mainline + + +layer + +layer rewrite: +much more detailed model of +physical and logical layers + + +lihata->layer + + + + +subcircuit + +subcircuit: +footprints without special objects + + +layer->subcircuit + + + + +binding + +layer binding: +abstract layer recipes +that are board-independent +and can be applied on a +given board's stackup + + +layer->binding + + + + +compositing + +layer compositing: +positive/nagative drawn layers within a group +allows drawing paste, mask, inverse silk, etc. + + +layer->compositing + + + + +subcircuit->binding + + + + +term + +subcircuit terminals: +generalized pin/pad idea +that allows any drawing primitive +to be a pin or pad + + +subcircuit->term + + + + +elem_replace + +element replacement: +replace the old element model +with subcircuits +make sure subcircuits can do +anything an element could do + + +subcircuit->elem_replace + + + + +binding->elem_replace + + + + +fp_nolimit + +goal: +footprints without limitations + + +binding->fp_nolimit + + + + +clean + +goal: +clean, tree based data structure + + +binding->clean + + + + +compositing->fp_nolimit + + + + +compositing->clean + + + + +term->fp_nolimit + + + + +term->clean + + + + +elem_remove + +element removal: +remove elements, element-lines, element-arcs +pins, pads and the old circular-only vias +in favor of subcircuits and pad stacks + + +elem_replace->elem_remove + + + + +elem_remove->clean + + + + +padstacks + +pad stacks: +a via (or pin or pad) +that can have different, +arbitrary copper shape +on different layer groups + + +padstacks->elem_replace + + + + +bbvia + +blind/buried via: +a pad stack has per layer info on +copper shape, it can +also have such info about the drill ends + + +padstacks->bbvia + + + + +recur + +subcircuit in subcircuit + + +clean->recur + + + + +hier + +hierarchical netlists + + +recur->hier + + + + + Index: tags/2.3.0/doc/developer/obj_func_naming.txt =================================================================== --- tags/2.3.0/doc/developer/obj_func_naming.txt (nonexistent) +++ tags/2.3.0/doc/developer/obj_func_naming.txt (revision 33253) @@ -0,0 +1,98 @@ +obj_* function naming conventions + + +High level (new/destroy): + + This is the recommended way of creating new objects. + + pcb_*_new(): + Calls pcb_*_alloc(), fills in fields from parameters and calls the post + processing (pcb_add_*_on_layer()) function as needed. Makes sanity checks + on the parameters and may fail upon that. + + pcb_*_new_*(): + Same as pcb_*_new(), but may do clever things so the object created may + not be 1:1 what was requested or may not even be a new object (e.g. + overlapping line merging) + + pcb_*_destroy() + free all fields of an object and properly remove it from the parent + (including rtree removal) + +Low level (alloc/free): + + Use this in some special cases (like loading a file) when the extra checks + of a _new may interfere. + + pcb_*_alloc(): + allocate a new objects within a parent (as of now: layer). Allocates + the struct of a new objects with all fields clean and links the object + in the parent list. Returns a pointer to the object. NOTE: some post + processing may be needed after filling in the fields + (see also: pcb_add_*_on_layer()). Calls pcb_*_reg() automatically. + + pcb_*_alloc_id(): + same as pcb_*_alloc(), but instead of automatically pick the next id, + uses the user supplied ID + + pcb_*_free(): + free the struct memory (but not the fields!) of an object and remove + it from the parent list. Calls pcb_*_unreg() automatically. + + pcb_*_reg(): + register an object in data; this includes adding the object in the right + object list and in the id hash, but does not include any rtree operation + (so coords/sizes may change later). Also sets the object's parent. + + pcb_*_unreg(): + unregister an object from its data; this includes removing the object from + the right object list and from the id hash, but does not include any + rtree operation. Also clears the object's parent. + + pcb_add_*_on_layer(): + Postprocessing: call this after a new object is allocated and fields are + filled in. It mainly updates the rtree. + + pcb_*_copy(): + copy fields of a complex obj to a pre-allocated target obj + + pcb_*_pre() and pcb_*_post(): + when an object needs to be moved/changed within its own context (e.g. layer + object moved within layer, global object moved within data), it first needs + to be removed from the rtree and uncleared from any sorrunding polygon. + After the changes are done, the object should be put back in the rtree and + the affected polygons should be cleared. These two steps are done by + pcb_*_pre() and pcb_*_post(). Call pre() before the operation, call post() + after the operation. + +Accessors: + pcb_*_get_*(): + Return data that are not directly accessible as object struct fields but + require some sort of calculation + + pcb_*_set_*(): + Set object fields that require postprocessing because of side effects. + Use these instead of direct writes to the fields to get side effects + properly executed. + + pcb_*_change_*(): + Similar to pcb_*_set_*(), but instead of setting a field to a value + specified as a parameter, change the field to comply with some global + state, e.g. "change side" would move the object to the currently viewed + side. + +Transformations: + pcb_*_move(): + move the object within its parent (x;y); it's often implemented as a + macro + + pcb_*_mirror(): + mirror the object within its parent (x;y) + + +Misc: + pcb_*_bbox(): + calculate and update the bounding box of an object + + pcb_*_rotate90() + Rotate the object by n*90 degrees Index: tags/2.3.0/doc/developer/old_netlist.txt =================================================================== --- tags/2.3.0/doc/developer/old_netlist.txt (nonexistent) +++ tags/2.3.0/doc/developer/old_netlist.txt (revision 33253) @@ -0,0 +1,38 @@ +This file describes the old netlist model. The old model seems to be +deisgned from a GUI perspective, probably from the Xaw times. This old +model will eventually be replaced by a more proper tree structure that +will be able to represent hierarchic netlists. + +Moved from the gtk sources: + + -------- The netlist nodes (pcb_lib_entry_t) data model ---------- + Each time a net is selected in the left treeview, this node model + is recreated containing all the nodes (pins/pads) that are connected + to the net. Loading the new model will update the right treeview with + all the new node names (C100-1, R100-1, etc). + + The terminology is a bit confusing because the PCB netlist data + structures are generic structures used for library elements, netlist + data, and possibly other things also. The mapping is that + the layout netlist data structure is a pcb_lib_t which + contains an allocated array of pcb_lib_menu_t structs. Each of these + structs represents a net in the netlist and contains an array + of pcb_lib_entry_t structs which represent the nodes connecting to + the net. So we have: + + | Nets Nodes + | pcb_lib_t pcb_lib_menu_t pcb_lib_entry_t + | ------------------------------------------------------- + | PCB->NetlistLib------Menu[0]-----------Entry[0] + | | Entry[1] + | | ... + | | + | --Menu[1]-----------Entry[0] + | | Entry[1] + | | ... + | | + | -- ... + | + | Where for example Menu[] names would be nets GND, Vcc, etc and Entry[] + | names would be nodes C101-1, R101-2, etc + Index: tags/2.3.0/doc/developer/openems.txt =================================================================== --- tags/2.3.0/doc/developer/openems.txt (nonexistent) +++ tags/2.3.0/doc/developer/openems.txt (revision 33253) @@ -0,0 +1,15 @@ +Temporary doc draft for openems usage. + +For ports, place padstacks with either top or bottom copper shape and _no_ +hole. Then set the attribute openems::vport on the padstack. The value +should be the name of the port as to be seen in openems. + +List of openems-related attributes: + +openems::vport - mandatory: port name +openems::resistance - optional: overrides default port resistance +openems::active - optional: either true or false; default=true +openems::vport-reverse - optional: when present, swap start/end + + + Index: tags/2.3.0/doc/developer/order_pcbway/example_wget/country.sh =================================================================== --- tags/2.3.0/doc/developer/order_pcbway/example_wget/country.sh (nonexistent) +++ tags/2.3.0/doc/developer/order_pcbway/example_wget/country.sh (revision 33253) @@ -0,0 +1,14 @@ +#!/bin/sh + +# insert API key here: +key="" + +server=api-partner.pcbway.com +URL="http://$server/api/Address/GetCountry" + + +wget $URL \ + --header "api-key: $key" \ + --header "Content-Type: application/xml" \ + --header "Accept: application/xml" \ + --post-file=/dev/null Property changes on: tags/2.3.0/doc/developer/order_pcbway/example_wget/country.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/developer/order_pcbway/example_wget/query.xml =================================================================== --- tags/2.3.0/doc/developer/order_pcbway/example_wget/query.xml (nonexistent) +++ tags/2.3.0/doc/developer/order_pcbway/example_wget/query.xml (revision 33253) @@ -0,0 +1,26 @@ + + 1 + TG130 + 1 oz Cu + No + 2 + 100.0 + FR-4 + 0.3 + 6/6mil + 10 + White + Green + HASL with lead + 1.6 + Tenting vias + 100.0000 + + n/a + n/a + GB + 0 + DHL + + + Index: tags/2.3.0/doc/developer/order_pcbway/example_wget/quote.sh =================================================================== --- tags/2.3.0/doc/developer/order_pcbway/example_wget/quote.sh (nonexistent) +++ tags/2.3.0/doc/developer/order_pcbway/example_wget/quote.sh (revision 33253) @@ -0,0 +1,14 @@ +#!/bin/sh + +# insert API key here: +key="" + +server=api-partner.pcbway.com +URL="http://$server/api/Pcb/PcbQuotation" +fn="query.xml" + +wget $URL \ + --header "api-key: $key" \ + --header "Content-Type: application/xml" \ + --header "Accept: application/xml" \ + --post-file="$fn" Property changes on: tags/2.3.0/doc/developer/order_pcbway/example_wget/quote.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/developer/order_pcbway/xml_api.txt =================================================================== --- tags/2.3.0/doc/developer/order_pcbway/xml_api.txt (nonexistent) +++ tags/2.3.0/doc/developer/order_pcbway/xml_api.txt (revision 33253) @@ -0,0 +1,21 @@ +The xml API has a few design choices that might be regarded as unusual. + +1. order of fields + +The quotation request, , is a flat list of mostly +independent children. However, it is very strict about the order +of those children. Fortunately the order matches the one in PCBWay_API.xml. +The ruleset seems to be: + - divide the children into two groups: board-specific and shipping + - output board first, shipping next + - nodes within a group must be alphabetically ordered + +2. case sensitivity + +Every tag name and enum text fields are case sensitive. The parser will +not accept "no" if the enum value is said to be "No". + + +3. computer readable API spec + +The API is at http://api-partner.pcbway.com/xml/PCBWay_Api.xml Index: tags/2.3.0/doc/developer/packaging/Changelog =================================================================== --- tags/2.3.0/doc/developer/packaging/Changelog (nonexistent) +++ tags/2.3.0/doc/developer/packaging/Changelog (revision 33253) @@ -0,0 +1,304 @@ +How to get a release candidate tarball in /tmp: + + ver=2.3.0 + cd /tmp + svn export svn://repo.hu/pcb-rnd/trunk pcb-rnd-$ver + tar -cf pcb-rnd-$ver.tar pcb-rnd-$ver + +Packaging changes between 2.3.0 and 2.2.4 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +1. new config file: $C/fp_fs.conf + +B. changes that probably DO need action + +1. new plugins in already existing package pcb-rnd-core: + ch_editpoint ch_onpoint + These will add a couple of new files, as listed in packages.html, please + make sure they are included in the pcb-rnd-core package. + +2. Grammar fixed in the description of the pcb-rnd-debug package + +3. ./configure options changed for the new plugins + +Packaging changes between 2.2.4 and 2.2.3 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +(Sorry, all changes will need your action in this release) + +B. changes that probably DO need action + +1. new plugins in already existing package pcb-rnd-import-net: + import_accel_net, import_orcad_net, import_pads_net, import_protel_net + These will add a couple of new files, as listed in packages.html, please + make sure they are included in the pcb-rnd-import-net package. + +2. new dependency: pcb-rnd-auto now depends on pcb-rnd-io-standard + +3. new plugin in pcb-rnd-auto: ar_extern + +4. ./configure arguments changed for the new plugins + +5. The description of the main package changed: the manually written part + on file formats got replaced with an autogenerated list. The new list + is much longer as it now really includes all file formats pcb-rnd supports. + Please make sure to include the new package description: it is important + that the end user finds pcb-rnd when he has a file of some exotic + file format and is searching for a tool for it. I've also removed + a redundant DRC item from the feature list. + + +Packaging changes between 2.2.3 and 2.2.2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +They are the same. + +Packaging changes between 2.2.1 and 2.2.2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +1. plugin removed: import_sch from package pcb-rnd-import-net + +2. plugin removed: distaligntext from package pcb-rnd-extra + +3. plugin removed: drc_orig from package core + +B. changes that probably DO need action + +1. as always, the ./configure line has changed for plugin changes, see packages.html + +2. the description of pcb-rnd has changed, please copy it from description.txt + +3. new plugin: irc in package pcb-rnd-lib-gui + +4. new plugins: lib_formula and lib_portynet in package pcb-rnd-core + +5. new plugin: io_bxl in pcb-rnd-io-alien + +6. new util: pcb-rnd-svg; has an executable and a manual page in the install + Should be in package pcb-rnd-export + +6. new util: bxl2txt and txt2bxl; executable and manual pages + Should be in package pcb-rnd-io-alien + +Packaging changes between 2.2.0 and 2.2.1 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +1. New plugins in existing packages: the import_sch splitup & rewrite + - import_gnetlist in pcb-rnd-import-net (imports running gnetlist) + - import_net_action in pcb-rnd-import-net (imports by running an action script) + - import_net_cmd in pcb-rnd-import-net (imports by running an arbitrary command, e.g. make) + - import_sch2 in pcb-rnd-import-net (the rewrite of import_sch) + - new config file: $C/import_gnetlist.conf + +2. New plugins in existing packages + - drc_query in pcb-rnd-core; new conf files: $C/drc_query.conf and $C/drc_orig.conf + - tool_std in pcb-rnd-core + +B. changes that probably DO need action + +1. ./configure options changed (for the new plugins) + +2. Renamed librnd2-dev to librnd-dev in the doc (Debian recommendation) + Distributions are free to use either name; if there's no ditribution + dictated preference, please use librnd-dev. Please note: the binary + package, librnd2, still should have the '2' in its name. + +3. Missing data files from pcb-rnd-core + Previous versions missed a few data files, which are now all added in + package pcb-rnd-core. Pleasre revise the installed files for pcb-rnd-core + in your packaging. A short list of files affected: + - default boards (default*.lht) + - default font file (default_font) + - pcblib (the footprint library) + +4. Missing utilities from librnd-dev + Please revise the file listing, puplug and gen_conf got added + +5. The meta-package pcb-rnd should depend on import-net as it is + used in the most common workflow + + +Packaging changes between 2.1.4 and 2.2.0 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +1. new plugins in existing packages: + - millpath in package pcb-rnd-export + - exto_std in package pcb-rnd-core + - export_stl in package pcb-rnd-export-extra + +2. sorted out files and dependencies of the librnd packages; please make + sure librnd is packaged. + +3. pcb-rnd-core has all plugins built-in, so they are not dynamically loaded; + old versions of pacakges.html listed non-existing .so and .pup files for + these plugins, new version does not. + +B. changes that probably DO need action + +1. if you had a workaround for the --as-needed linker problem, please + disable it; the code should work fine with that flag since r28707. + +2. ./configure options changed (for the new plugins) + +3. please make sure pcb-rnd-cloud depends on wget + +4. fixed a dependency list bug in the script that generates packages.html; + this does not change dependencies, but it's best to double check these: + - the following packages should depend on pcb-rnd-lib-io: + pcb-rnd-import-net, pcb-rnd-auto, pcb-rnd-io-standard, pcb-rnd-io-alien, + - pcb-rnd-lib-gtk and pcb-rnd-hid-lesstif depend on pcb-rnd-lib-gui + - pcb-rnd-hid-gtk2-gdk and pcb-rnd-hid-gtk2-gl depend on pcb-rnd-lib-gtk + +5. pcb-rnd-import-net should contain gsch2pcb-rnd related files + (see packages.html) + +6. written/updated/refined package description for: + pcb-rnd-lib-gl, pcb-rnd-lib-io, pcb-rnd-lib-gui, pcb-rnd-lib-gtk + + +Packaging changes between 2.1.3 and 2.1.4 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A. changes that probably don't need action + +1. removed plugin lib_gtk_hid from pcb-rnd-hid-gtk + +2. removed some non-packaged code that depended on cairo; at the moment + pcb-rnd has no direct cairo dependency; if cairo creeped in as direct + explicit dependency on any package, please remove it. (gtk2 may bring + it in as indirect dependency) + +B. changes that probably DO need action + +1. copyright update: new minilib in src_3rd: libulzw (new author, BSD license) + (In case you need to maintain a copyright file) + +2. new plugins: import_pxm_gd import_pxm_pnm in package pcb-rnd-import-geo + Note: import_pxm_gd depends on libgd so pcb-rnd-import-geo + started to depend on libgd + +3. utility fp2anim got removed and replaced by the new utility fp2preview; + this affects the manual page file name too. + +Packaging changes between 2.1.2 and 2.1.3 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +1. removed old menu files pcb-menu-lesstif.lht and pcb-menu-gtk.lht from + the installation (used to install in $PREFIX/share/pcb-rnd) + +2. new plugin in package pcb-rnd-export: export_excellon (split + off from export_gerber) + +3. new plugin in package pcb-rnd-lib-gui: lib_hid_pcbui (for the hidlib split) + +4. new plugin in package pcb-rnd-core: act_read (new actions for accessing + board data) + +5. new plugin in package pcb-rnd-cloud: lib_wget (split off from fp_wget + to be reused in the board ordering plugins later) + + +B. changes that probably DO need action + +1. If you need to maintain a copyright file: there is a new piece of + minilib included in the source now in src_3rd/fast89_poly2tri; it's + distributed under a MIT license. + + +Packaging changes between 2.1.1 and 2.1.2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A. changes that probably don't need action + +1. Fixed typo in the packages.html: pcb-rnd-hid-gtk2-dl -> pcb-rnd-hid-gtk2-gl + +B. changes that probably DO need action + +1. Fixed wording in the description of package pcb-rnd-io-alien: + "PCB board" -> "PCB layout" (to avoid redundancy with the acrynom) + Please adjust the description of your package. + + +Packaging changes between 2.1.0 and 2.1.1 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A. changes that probably don't need action + +1. new plugins in already existing packages (new files in existing packages, ./configure line change): + - import_calay plugin in pcb-rnd-import-net + - drc_orig plugin in pcb-rnd-core (old DRC code moved from core code to plugin code) + - export_oldconn plugin in pcb-rnd-export-extra (old connection export moved out from core to plugin) + +2. plugins removed (but parent packages are kept, ./configure line change): + - boardflip plugin (was in pcb-rnd-core) + - lib_gtk_config (was in pcb-rnd-lib-gtk) - old gtk-only preferences dialog removed in favor of the new + +3. bugs that got fixed in packages.html + - cam.conf was not listed as installed file for pcb-rnd-export + +B. changes that probably DO need action + +1. minor changes in package deps: + - pcb-rnd-hid-gtk2-gl doesn't directly depend on pcb-rnd-lib-gui + - pcb-rnd-hid-gtk2-gdk doesn't directly depend on pcb-rnd-lib-gui + - pcb-rnd-io-standard started to depend on pcb-rnd-lib-io + +2. new files introduced by already existing plugins + - $C/dialogs.conf in pcb-rnd-lib-gui + +3. please update your ./configure line because it has changed for + plugin removals and new plugins. You can obtain a diff by looking + at the bottom of: svn diff -c 22941 packages.html + + + +Packaging changes between 2.0.1 and 2.1.0 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A. changes that probably don't need action + +1. FYI, the html now contains a more complete installed file listing: not +just the .so and .pup files but also the per plugin .conf files. +Installed files got a path prefix $P/ or $C/ depending on where they end +up (plugin dir or conf dir) after the installation. + +2. New plugin: ar_cpcb (in pcb-rnd-auto); this is our new interface for +external autorouter c-pcb. c-pcb doesn't seem to have standard installation +yet, so packaging it would be hard. If there's interest, in packaging +c-pcb, I can try to push for a make install. + +3. Scripting and fungw: by now fungw scripting is at least as capable +as gpmi scripting is. I will remove gpmi in December. However, for +packaged pcb-rnd scripting is not yet available because fungw is not +yet packaged. If you plan to make pcb-rnd scriptable in your distro, +you will need to package libmawk and fungw first - please contact me. +(Packaging those don't need to be in sync with pcb-rnd releases, can +happen any time). For more details see: +http://repo.hu/cgi-bin/pool.cgi?cmd=show&node=script_pkg + +4. New io plugin: io_dsn, in pcb-rnd-io-alien; it can load a full board +from dsn, which is a de-facto industrial standard for autorouting. + +5. New mini-plugin: act_draw in pcb-rnd-core; it implements actions to +low level drawing (exposes pcb-rnd's native drawing functions) + +6. New GUI plugin asm in pcb-rnd-auto; it's a feature that helps manually +building a board by preseting the BoM in a grouped, sorted list, keeping +track on what's put on the board already and highlighting what needs to be +put on next. It has a high eye-candy factor, may look good in the screenshots. + + +B. changes that probably DO need action + +7. We have removed our nelma support; please make sure you remove them +from any documentation/metadata/material. + +8. New, preliminary plugin in pcb-rnd-import-geo: ttf import; this makes +pcb-rnd-import-geo depend on libfreetype6 + +9. Package pcb-rnd-auto started to depend on package pcb-rnd-io +(because of external autorouters like ar_cpcb) Index: tags/2.3.0/doc/developer/packaging/desc =================================================================== --- tags/2.3.0/doc/developer/packaging/desc (nonexistent) +++ tags/2.3.0/doc/developer/packaging/desc (revision 33253) @@ -0,0 +1,127 @@ +@pcb-rnd + Standard installation of pcb-rnd + + Install pcb-rnd core and the most commonly used plugins. + +@pcb-rnd-doc + Documentation for pcb-rnd + + User manual (html) and manual pages. + +@pcb-rnd-core + pcb-rnd executable with the core functionality + + Includes the data model, the most common action commands, the native file + format and the CLI (batch HID). Does not contain GUI. Can be used in + headless mode or batch/scripted mode for automated processing. + +@pcb-rnd-auto + Autoroute and autoplace. + + Feature plugins for automated component placing and track routing. + +@pcb-rnd-cloud + Networking plugins. + + 'Cloud' footprint access plugin that integrates edakrill and gedasymbols.org. + +@pcb-rnd-debug + Debug and diagnostics. + + Extra action commands to help in debugging and diagnosing problems and bugs. + +@pcb-rnd-export-extra + Export formats: special/extra + + Less commonly used export formats: fidocadj, ipc-356-d, direct printing with lpr. + +@pcb-rnd-export-sim + Export plugins to simulators + + Export the board in formats that can be used for simulation: openems. + +@pcb-rnd-export + Common export plugins. + + Export the board in vector graphics (svg, ps, eps), raster graphics + (png, jpeg, etc.), gerber, 3d model in openscad, xy for pick and place, + BoM, etc. + +@pcb-rnd-extra + Extra action commands and optional functionality. + + Align objects in grid, optimize tracks, font editor, combine polygons, + renumber subcircuits, apply vendor drill mapping. + +@pcb-rnd-hid-gtk2-gdk + GUI: gtk2, software render + + Software rendering on gtk2, using the gdk API. + +@pcb-rnd-hid-gtk2-gl + GUI: gtk2, opengl + + Hardware accelerated (opengl) rendering on gtk2. + +@pcb-rnd-hid-lesstif + GUI: motif/lesstif, software render + + Lightweight GUI and software rendering using the motif (lesstif) toolkit. + +@pcb-rnd-import-geo + Geometry import plugins. + + Import geometry from HPGL plots. HPGL can be produced (plotted) with + most mechanical cads. + +@pcb-rnd-import-net + Netlist/schematics import plugins. + + Import netlist and footprint information from edif, ltspice, mentor graphics, + gschem and tinycad. + +@pcb-rnd-io-alien + File format compatibility with other PCB layout designers. + + Load and/or save boards in file formats supported by other + EDA tools, such as KiCAD, Eagle, protel/autotrax, etc. + +@pcb-rnd-io-standard + Commonly used non-native board and footprint file formats + + Plugins for tEDAx footprint format and the gEDA/PCB file formats + (footprint and board). + +@pcb-rnd-lib-gl + Support library for rendering with opengl. + + Provides plugins for driving an opengl output, rendering pcb-rnd + views on opengl. + +@pcb-rnd-lib-gtk + Support library for building the GUI with gtk. + + Provides the common gtk code (e.g. dialog box engine, input handling) + for any gtk based HID plugin. + +@pcb-rnd-lib-gui + Support library for building the GUI. + + Provides pcb-rnd specific dialog boxes (e.g. fontsel) and top + window GUI elements. + +@pcb-rnd-lib-io + Support library for alien file formats. + + Provides generic, low level parsers (such as s-expression + parser) for I/O plugins that need to deal with alien file formats. + +@librnd2 + pcb-rnd library, binaries. + + HID, polygons, infrastructure for 3rd party applications. + +@librnd-dev + pcb-rnd library, headers. + + HID, polygons, infrastructure for 3rd party applications. Index: tags/2.3.0/doc/developer/packaging/description.txt =================================================================== --- tags/2.3.0/doc/developer/packaging/description.txt (nonexistent) +++ tags/2.3.0/doc/developer/packaging/description.txt (revision 33253) @@ -0,0 +1,119 @@ +pcb-rnd is a highly modular PCB (Printed Circuit Board) layout tool +with a rich set of plugins for communicating with various external +design tools and other EDA/CAD packages. + +Feature highlights: + - subcircuits, pad stacks + - flexible footprint model; unrestricted pad shapes + - arbitrary copper, silk, paste and soldermask objects + - sophisticated, flexible layer model + - flexible/universal polygon model + - any object, even polygons, can have a clearance within a polygon + - advanced mil and mm grid, with support for mixed unit design + - strong CLI support + - static footprints and parametric (generated) footprints + - query language for advanced search & select + - powerful, user scriptable, modular Design Rule Checker (DRC) + - layout optimizers such as teardrops and a trace puller + - footprint library from local file systems, HTTP and board files + - netlist management: imported and as-built; back annotation + +File formats and compatibility: + - text based, tree structured native file format (lihata) + - import board: + * autotrax PCB board, version 4 + * autotrax PCB board, version 5 + * dsn board + * eagle xml board version 6, 7, 8 + * eagle binary board version 3, 4, 5 + * hyperlynx board, version 2 and above + * kicad board, version 3, 4 and 5 (s-expr) + * lihata pcb-rnd board (any version) + * gEDA/PCB .pcb board (any version up to 2017) + - export board: + * anonimized board statistics in lihata + * autotrax PCB board, version 4 + * dsn board + * hyperlynx board, version 2.0 + * kicad board, version 3 (s-expr) + * kicad pcbnew-board, version 1 (legacy plain text format) + * lihata pcb-rnd board (any version) + * gEDA/PCB .pcb board (various version up to 2017 ) + - import footprint: + * BXL footprints + * eagle xml footprint lib + * eagle binary footprint lib + * lihata pcb-rnd footprint (any version) + * Mentor Graphics cell footprints + * gEDA/PCB .fp footprints + * tEDAx footprint (any version) + - export footprint: + * kicad module (s-expr, according to version 3) + * kicad pcbnew-module (legacy plain text format) + * lihata pcb-rnd footprint (any version) + * gEDA/PCB .fp footprints + * tEDAx footprint (any version) + - import netlist: + * Accel ASCII netlists + footprint info + * calay (netlists + footprint info) + * flat netlist from EDIF + * freepcb netlist + footprint info + * gEDA/gschem (netlist + footpritn info, running gnetlist) + * import ltspice .net and .asc (netlist and footprint info) + * flat .edf (netlist+footprint, produced by Mentor Graphics Design Capture) + * pcb-rnd action script (netlist + footprint info) + * schematics import by running a commandline + * netlist import by running a commandline + * gEDA netlist (plain text, no footprint info) + * Orcad PCB II (netlist + footprint info) + * PADS ascii (.asc, netlists + footprint info) + * Protel netlists 2.0 + footprint info + * tinycad .net (netlists + footprint info) + * eeschema netlist and footprint info + * tEDAx netlist (any version) + - export netlist: + * tEDAx netlist (any version) + - import image: + * pixmap (e.g. png) + * pnm (pixmap) + - export image: + * render in .png + * render in .gif + * render in .jpeg + * render black&white postscript (single or multiple files) + * render black&white or color embedded postscript (single file) + * svg (Scalable Vector Graphics) + - import misc: + * specctra .dsn (wires and vias) + * HPGL plot (lines, arcs, polygons) + * MUCS unixplot .pl (lines and vias) + * ttf font + * eagle DRU (design rules) + * lihata pcb-rnd font (any version) + * gEDA/PCB font + * tEDAx drc + * tEDAx pcb-rnd drc script + - export misc: + * bom (Bill of Materials, text) + * specctra .dsn (padstacks and subcircuits, works with freerouting.net) + * .dxf (2D drawing for mech CADs) + * excellon drill/cnc (for PCB fabbing) + * fidocad .fcd (partial export) + * export gcode (for milling) + * gerber for PCB fabbing + * IPC-D-356 Netlist (for automated testing) + * printer (using ps) + * list of terminal connections (old, custom format) + * OpenEMS (simulation, matlab files) + * openscad script (colored 3D model) + * stl (3d triangulated surface model) + * geda/PCB xy + * gxyrs + * Macrofab's pick&place + * pick&place file for the TM220/TM240 device + * KiCad .pos file + * IPC-D-356 Netlist (from automated testing) + * lihata pcb-rnd font (any version) + * tEDAx etest + * tEDAx drc + * tEDAx pcb-rnd drc script Index: tags/2.3.0/doc/developer/packaging/extra.digest =================================================================== --- tags/2.3.0/doc/developer/packaging/extra.digest (nonexistent) +++ tags/2.3.0/doc/developer/packaging/extra.digest (revision 33253) @@ -0,0 +1,16 @@ +@files librnd-dev $PREFIX/include/librnd/* +@files librnd2 $PREFIX/lib/*.so.* +@appendfiles pcb-rnd-core $PREFIX/bin/pcb-rnd $PREFIX/share/man/man1/pcb-rnd.1 +@appendfiles pcb-rnd-core $C/pcb-conf.lht $C/pcb-menu-default.lht +@appendfiles pcb-rnd-core $PREFIX/share/pcb-rnd/default2.lht $PREFIX/share/pcb-rnd/default4.lht $PREFIX/share/pcb-rnd/default_font +@appendfiles pcb-rnd-core $PREFIX/bin/fp2preview $PREFIX/bin/fp2subc $PREFIX/bin/pcb-prj2lht $PREFIX/share/man/man1/fp2preview.1 $PREFIX/share/man/man1/fp2subc.1 $PREFIX/share/man/man1/pcb-prj2lht.1 +@appendfiles pcb-rnd-core $PREFIX/share/pcb-rnd/pcblib/* +@appendfiles pcb-rnd-io-alien $PREFIX/share/man/man1/txt2bxl.1 $PREFIX/share/man/man1/bxl2txt.1 +@appendfiles pcb-rnd-io-alien $PREFIX/bin/txt2bxl $PREFIX/bin/bxl2txt +@appendfiles pcb-rnd-export $PREFIX/bin/pcb-rnd-svg $PREFIX/share/man/man1/pcb-rnd-svg.1 +@appendfiles pcb-rnd-import-net $PREFIX/bin/gsch2pcb-rnd $PREFIX/lib/pcb-rnd/*.scm $PREFIX/share/man/man1/gsch2pcb-rnd.1 +@appendfiles librnd-dev $PREFIX/share/librnd/librnd.mak $PREFIX/lib/librnd +@appendfiles librnd-dev $PREFIX/lib/*.so +@appendfiles librnd-dev $PREFIX/lib/librnd/gen_conf $PREFIX/lib/librnd/puplug +@appenddeps librnd-dev librnd2 +@appenddeps pcb-rnd-cloud wget Index: tags/2.3.0/doc/developer/packaging/lib64.txt =================================================================== --- tags/2.3.0/doc/developer/packaging/lib64.txt (nonexistent) +++ tags/2.3.0/doc/developer/packaging/lib64.txt (revision 33253) @@ -0,0 +1,23 @@ +Why pcb-rnd plusings are in /usr/lib/ and not /usr/lib64/ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +On a 64 bit system where both 32 bit and 64 bit software needs to be run +a separate set of 32 and 64 bit libraries are kept for two reasons: + +1. You may want to install both the 32 and the 64 bit version of the +same lib (e.g. libc) without interference. + +2. You want the dynamic linker to find the right one for your app; so +when linking a 32 bit app, you want to look only for 32 bit libs and +when linking a 64 bit app, you want to look only for 64 bit libs. +Linking means the dynamic linker's automatic run when a dynamic linked +executable is started up. + +What we do in our plugin dir is neither of those. We never want to have +both 32 and 64 bit pcb-rnds live side by side on a 64 bit system. And +these .so files are never read by the dynamic linker on executable +startup. The only one way they are loaded is by explicit path, using +dlopen, from within pcb-rnd. Because they are plugins, not general +purpose shared libs. So it is safe to put them in a common lib/, we do +not need to install them in different libdirs per system. + Index: tags/2.3.0/doc/developer/packaging/packages.html =================================================================== --- tags/2.3.0/doc/developer/packaging/packages.html (nonexistent) +++ tags/2.3.0/doc/developer/packaging/packages.html (revision 33253) @@ -0,0 +1,179 @@ + + + + +

Package summary and dependencies

+ +
package depends on (packages) consists of (plugins) +
pcb-rnd-debug pcb-rnd-core diag +
pcb-rnd-export pcb-rnd-core cam export_bom export_dxf export_excellon export_gcode export_gerber export_openscad export_png export_ps export_stat export_svg export_xy millpath +
pcb-rnd-doc  +
pcb-rnd-export-sim pcb-rnd-core export_openems +
pcb-rnd-lib-gl pcb-rnd-core lib_hid_gl +
pcb-rnd-hid-gtk2-gl pcb-rnd-core pcb-rnd-lib-gtk pcb-rnd-lib-gl hid_gtk2_gl +
pcb-rnd-import-geo pcb-rnd-core import_hpgl import_pxm_gd import_pxm_pnm import_ttf +
pcb-rnd-import-net pcb-rnd-core pcb-rnd-lib-io import_accel_net import_calay import_edif import_fpcb_nl import_gnetlist import_ipcd356 import_ltspice import_mentor_sch import_net_action import_net_cmd import_netlist import_orcad_net import_pads_net import_protel_net import_sch2 import_tinycad +
pcb-rndpcb-rnd-core pcb-rnd-io-standard pcb-rnd-io-alien pcb-rnd-hid-gtk2-gl pcb-rnd-hid-gtk2-gdk pcb-rnd-export pcb-rnd-export-sim pcb-rnd-export-extra pcb-rnd-auto pcb-rnd-extra pcb-rnd-cloud pcb-rnd-doc pcb-rnd-import-net<metapackage> +
librnd-dev librnd2 pcb-rnd-coren/a +
pcb-rnd-auto pcb-rnd-core pcb-rnd-lib-io pcb-rnd-io-standard ar_cpcb ar_extern asm autoplace autoroute export_dsn import_dsn import_mucs smartdisperse +
pcb-rnd-lib-io pcb-rnd-core lib_netmap lib_gensexpr +
pcb-rnd-io-standard pcb-rnd-core pcb-rnd-lib-io io_pcb io_tedax +
pcb-rnd-lib-gui pcb-rnd-core dialogs draw_fontsel lib_hid_pcbui irc lib_hid_common +
pcb-rnd-core(builtin: act_draw act_read autocrop ch_editpoint ch_onpoint ddraft draw_csect draw_fab drc_query extedit exto_std fp_board fp_fs io_lihata lib_compat_help lib_formula lib_polyhelp mincut propedit query report rubberband_orig script shape tool_std hid_batch lib_portynet) +
pcb-rnd-lib-gtk pcb-rnd-core pcb-rnd-lib-gui lib_gtk_common +
pcb-rnd-hid-lesstif pcb-rnd-core pcb-rnd-lib-gui hid_lesstif +
librnd2 pcb-rnd-coren/a +
pcb-rnd-io-alien pcb-rnd-core pcb-rnd-lib-io io_autotrax io_bxl io_dsn io_eagle io_hyp io_kicad io_kicad_legacy +
pcb-rnd-cloud wget pcb-rnd-core fp_wget lib_wget +
pcb-rnd-export-extra pcb-rnd-core pcb-rnd-export export_fidocadj export_ipcd356 export_lpr export_oldconn export_stl +
pcb-rnd-hid-gtk2-gdk pcb-rnd-core pcb-rnd-lib-gtk hid_gtk2_gdk +
pcb-rnd-extra pcb-rnd-core distalign djopt fontmode jostle polycombine polystitch puller renumber shand_cmd teardrops vendordrill +
+

Package description and files

+ +
package files short long +
pcb-rnd-debug $P/diag.pup $P/diag.so Debug and diagnostics. Extra action commands to help in debugging and diagnosing problems and bugs. +
pcb-rnd-export $P/cam.pup $P/cam.so $P/export_bom.pup $P/export_bom.so $P/export_dxf.pup $P/export_dxf.so $P/export_excellon.pup $P/export_excellon.so $P/export_gcode.pup $P/export_gcode.so $P/export_gerber.pup $P/export_gerber.so $P/export_openscad.pup $P/export_openscad.so $P/export_png.pup $P/export_png.so $P/export_ps.pup $P/export_ps.so $P/export_stat.pup $P/export_stat.so $P/export_svg.pup $P/export_svg.so $P/export_xy.pup $P/export_xy.so $P/millpath.pup $P/millpath.so $PREFIX/bin/pcb-rnd-svg $PREFIX/share/man/man1/pcb-rnd-svg.1 $C/cam.conf $C/export_xy.conf Common export plugins. Export the board in vector graphics (svg, ps, eps), raster graphics (png, jpeg, etc.), gerber, 3d model in openscad, xy for pick and place, BoM, etc. +
pcb-rnd-doc/usr/share/doc/* Documentation for pcb-rnd User manual (html) and manual pages. +
pcb-rnd-export-sim $P/export_openems.pup $P/export_openems.so Export plugins to simulators Export the board in formats that can be used for simulation: openems. +
pcb-rnd-lib-gl $P/lib_hid_gl.pup $P/lib_hid_gl.so Support library for rendering with opengl. Provides plugins for driving an opengl output, rendering pcb-rnd views on opengl. +
pcb-rnd-hid-gtk2-gl $P/hid_gtk2_gl.pup $P/hid_gtk2_gl.so GUI: gtk2, opengl Hardware accelerated (opengl) rendering on gtk2. +
pcb-rnd-import-geo $P/import_hpgl.pup $P/import_hpgl.so $P/import_pxm_gd.pup $P/import_pxm_gd.so $P/import_pxm_pnm.pup $P/import_pxm_pnm.so $P/import_ttf.pup $P/import_ttf.so Geometry import plugins. Import geometry from HPGL plots. HPGL can be produced (plotted) with most mechanical cads. +
pcb-rnd-import-net $P/import_accel_net.pup $P/import_accel_net.so $P/import_calay.pup $P/import_calay.so $P/import_edif.pup $P/import_edif.so $P/import_fpcb_nl.pup $P/import_fpcb_nl.so $P/import_gnetlist.pup $P/import_gnetlist.so $P/import_ipcd356.pup $P/import_ipcd356.so $P/import_ltspice.pup $P/import_ltspice.so $P/import_mentor_sch.pup $P/import_mentor_sch.so $P/import_net_action.pup $P/import_net_action.so $P/import_net_cmd.pup $P/import_net_cmd.so $P/import_netlist.pup $P/import_netlist.so $P/import_orcad_net.pup $P/import_orcad_net.so $P/import_pads_net.pup $P/import_pads_net.so $P/import_protel_net.pup $P/import_protel_net.so $P/import_sch2.pup $P/import_sch2.so $P/import_tinycad.pup $P/import_tinycad.so $PREFIX/bin/gsch2pcb-rnd $PREFIX/lib/pcb-rnd/*.scm $PREFIX/share/man/man1/gsch2pcb-rnd.1 $C/import_gnetlist.conf Netlist/schematics import plugins. Import netlist and footprint information from edif, ltspice, mentor graphics, gschem and tinycad. +
pcb-rnd Standard installation of pcb-rnd Install pcb-rnd core and the most commonly used plugins. +
librnd-dev$PREFIX/include/librnd/* $PREFIX/share/librnd/librnd.mak $PREFIX/lib/librnd $PREFIX/lib/*.so $PREFIX/lib/librnd/gen_conf $PREFIX/lib/librnd/puplug pcb-rnd library, headers. HID, polygons, infrastructure for 3rd party applications. +
pcb-rnd-auto $P/ar_cpcb.pup $P/ar_cpcb.so $P/ar_extern.pup $P/ar_extern.so $P/asm.pup $P/asm.so $P/autoplace.pup $P/autoplace.so $P/autoroute.pup $P/autoroute.so $P/export_dsn.pup $P/export_dsn.so $P/import_dsn.pup $P/import_dsn.so $P/import_mucs.pup $P/import_mucs.so $P/smartdisperse.pup $P/smartdisperse.so $C/ar_extern.conf $C/asm.conf Autoroute and autoplace. Feature plugins for automated component placing and track routing. +
pcb-rnd-lib-io $P/lib_netmap.pup $P/lib_netmap.so $P/lib_gensexpr.pup $P/lib_gensexpr.so Support library for alien file formats. Provides generic, low level parsers (such as s-expression parser) for I/O plugins that need to deal with alien file formats. +
pcb-rnd-io-standard $P/io_pcb.pup $P/io_pcb.so $P/io_tedax.pup $P/io_tedax.so Commonly used non-native board and footprint file formats Plugins for tEDAx footprint format and the gEDA/PCB file formats (footprint and board). +
pcb-rnd-lib-gui $P/dialogs.pup $P/dialogs.so $P/draw_fontsel.pup $P/draw_fontsel.so $P/lib_hid_pcbui.pup $P/lib_hid_pcbui.so $P/irc.pup $P/irc.so $P/lib_hid_common.pup $P/lib_hid_common.so $C/dialogs.conf Support library for building the GUI. Provides pcb-rnd specific dialog boxes (e.g. fontsel) and top window GUI elements. +
pcb-rnd-core $PREFIX/bin/pcb-rnd $PREFIX/share/man/man1/pcb-rnd.1 $C/pcb-conf.lht $C/pcb-menu-default.lht $PREFIX/share/pcb-rnd/default2.lht $PREFIX/share/pcb-rnd/default4.lht $PREFIX/share/pcb-rnd/default_font $PREFIX/bin/fp2preview $PREFIX/bin/fp2subc $PREFIX/bin/pcb-prj2lht $PREFIX/share/man/man1/fp2preview.1 $PREFIX/share/man/man1/fp2subc.1 $PREFIX/share/man/man1/pcb-prj2lht.1 $PREFIX/share/pcb-rnd/pcblib/* $C/ch_editpoint.conf $C/drc_query.conf $C/fp_fs.conf pcb-rnd executable with the core functionality Includes the data model, the most common action commands, the native file format and the CLI (batch HID). Does not contain GUI. Can be used in headless mode or batch/scripted mode for automated processing. +
pcb-rnd-lib-gtk $P/lib_gtk_common.pup $P/lib_gtk_common.so Support library for building the GUI with gtk. Provides the common gtk code (e.g. dialog box engine, input handling) for any gtk based HID plugin. +
pcb-rnd-hid-lesstif $P/hid_lesstif.pup $P/hid_lesstif.so GUI: motif/lesstif, software render Lightweight GUI and software rendering using the motif (lesstif) toolkit. +
librnd2$PREFIX/lib/*.so.* pcb-rnd library, binaries. HID, polygons, infrastructure for 3rd party applications. +
pcb-rnd-io-alien $P/io_autotrax.pup $P/io_autotrax.so $P/io_bxl.pup $P/io_bxl.so $P/io_dsn.pup $P/io_dsn.so $P/io_eagle.pup $P/io_eagle.so $P/io_hyp.pup $P/io_hyp.so $P/io_kicad.pup $P/io_kicad.so $P/io_kicad_legacy.pup $P/io_kicad_legacy.so $PREFIX/share/man/man1/txt2bxl.1 $PREFIX/share/man/man1/bxl2txt.1 $PREFIX/bin/txt2bxl $PREFIX/bin/bxl2txt File format compatibility with other PCB layout designers. Load and/or save boards in file formats supported by other EDA tools, such as KiCAD, Eagle, protel/autotrax, etc. +
pcb-rnd-cloud $P/fp_wget.pup $P/fp_wget.so $P/lib_wget.pup $P/lib_wget.so $C/fp_wget.conf Networking plugins. 'Cloud' footprint access plugin that integrates edakrill and gedasymbols.org. +
pcb-rnd-export-extra $P/export_fidocadj.pup $P/export_fidocadj.so $P/export_ipcd356.pup $P/export_ipcd356.so $P/export_lpr.pup $P/export_lpr.so $P/export_oldconn.pup $P/export_oldconn.so $P/export_stl.pup $P/export_stl.so Export formats: special/extra Less commonly used export formats: fidocadj, ipc-356-d, direct printing with lpr. +
pcb-rnd-hid-gtk2-gdk $P/hid_gtk2_gdk.pup $P/hid_gtk2_gdk.so GUI: gtk2, software render Software rendering on gtk2, using the gdk API. +
pcb-rnd-extra $P/distalign.pup $P/distalign.so $P/djopt.pup $P/djopt.so $P/fontmode.pup $P/fontmode.so $P/jostle.pup $P/jostle.so $P/polycombine.pup $P/polycombine.so $P/polystitch.pup $P/polystitch.so $P/puller.pup $P/puller.so $P/renumber.pup $P/renumber.so $P/shand_cmd.pup $P/shand_cmd.so $P/teardrops.pup $P/teardrops.so $P/vendordrill.pup $P/vendordrill.so Extra action commands and optional functionality. Align objects in grid, optimize tracks, font editor, combine polygons, renumber subcircuits, apply vendor drill mapping. +
+

File prefixes:

    +
  • $P: plugin install dir (e.g. /usr/lib/pcb-rnd/) +
  • $C: conf dir (e.g. /usr/share/pcb-rnd/) +
  • $PREFIX: installation prefix (e.g. /usr) +
+

./configure arguments

+--all=disable +--buildin-script +--buildin-fp_fs +--buildin-draw_fab +--buildin-act_read +--buildin-drc_query +--buildin-mincut +--buildin-ch_onpoint +--buildin-report +--buildin-rubberband_orig +--buildin-exto_std +--buildin-fp_board +--buildin-propedit +--buildin-io_lihata +--buildin-autocrop +--buildin-lib_polyhelp +--buildin-draw_csect +--buildin-ddraft +--buildin-ch_editpoint +--buildin-hid_batch +--buildin-act_draw +--buildin-tool_std +--buildin-query +--buildin-lib_compat_help +--buildin-lib_portynet +--buildin-shape +--buildin-lib_formula +--buildin-extedit +--plugin-export_excellon +--plugin-export_fidocadj +--plugin-export_lpr +--plugin-export_oldconn +--plugin-irc +--plugin-import_pxm_gd +--plugin-export_stat +--plugin-io_kicad_legacy +--plugin-io_eagle +--plugin-io_tedax +--plugin-import_gnetlist +--plugin-import_pxm_pnm +--plugin-io_kicad +--plugin-import_mucs +--plugin-renumber +--plugin-import_calay +--plugin-smartdisperse +--plugin-draw_fontsel +--plugin-polycombine +--plugin-export_gcode +--plugin-export_bom +--plugin-ar_cpcb +--plugin-lib_hid_pcbui +--plugin-teardrops +--plugin-shand_cmd +--plugin-import_tinycad +--plugin-export_openems +--plugin-import_orcad_net +--plugin-import_ltspice +--plugin-export_dxf +--plugin-lib_gtk_common +--plugin-export_ipcd356 +--plugin-import_ttf +--plugin-import_mentor_sch +--plugin-import_dsn +--plugin-export_ps +--plugin-import_accel_net +--plugin-hid_gtk2_gdk +--plugin-millpath +--plugin-djopt +--plugin-hid_gtk2_gl +--plugin-import_edif +--plugin-hid_lesstif +--plugin-import_protel_net +--plugin-lib_gensexpr +--plugin-import_sch2 +--plugin-diag +--plugin-lib_wget +--plugin-lib_hid_gl +--plugin-export_stl +--plugin-autoplace +--plugin-export_svg +--plugin-import_net_cmd +--plugin-fp_wget +--plugin-fontmode +--plugin-import_netlist +--plugin-polystitch +--plugin-import_pads_net +--plugin-dialogs +--plugin-io_dsn +--plugin-export_xy +--plugin-export_png +--plugin-import_hpgl +--plugin-import_ipcd356 +--plugin-export_dsn +--plugin-lib_hid_common +--plugin-lib_netmap +--plugin-io_hyp +--plugin-cam +--plugin-puller +--plugin-import_fpcb_nl +--plugin-io_pcb +--plugin-distalign +--plugin-asm +--plugin-export_openscad +--plugin-jostle +--plugin-autoroute +--plugin-io_autotrax +--plugin-vendordrill +--plugin-export_gerber +--plugin-io_bxl +--plugin-ar_extern +--plugin-import_net_action + + + + Index: tags/2.3.0/doc/developer/packaging/packages.sh =================================================================== --- tags/2.3.0/doc/developer/packaging/packages.sh (nonexistent) +++ tags/2.3.0/doc/developer/packaging/packages.sh (revision 33253) @@ -0,0 +1,236 @@ +#!/bin/sh +ROOT=../../.. +proot=$ROOT/src_plugins +rnd_proot=$ROOT/src_3rd/librnd/plugins + +### generate description.txt (file formats) ### + +. $ROOT/util/devhelpers/awk_on_formats.sh + +awk_on_formats ' +{ print $0 } + +function out(dir, type ,n,v,A,tmp) +{ + v = split(FMTS[dir, type], A, " *
*") + if (v < 1) return + print " -", dir, type ":" + for(n = 1; n <= v; n++) { + tmp = A[n] + sub("^ *", "", tmp) + print " * " tmp + } +} + +/(lihata)/ { + t = split(types, T, " ") + for(n = 1; n <= t; n++) { + out("import", T[n]); + out("export", T[n]); + } + exit +} +' < description.txt > description2.txt && mv description2.txt description.txt + +### generate packages.html and auto/ ### + +meta_deps="core io-standard io-alien hid-gtk2-gl hid-gtk2-gdk export export-sim export-extra auto extra cloud doc import-net" + +(echo ' + + +' + +( +for n in $proot/*/*.pup $rnd_proot/*/*.pup +do + pkg=`basename $n` + sed "s/^/$pkg /" < $n +done + +for n in $proot/*/*.tmpasm $rnd_proot/*/*.tmpasm +do + sed "s@^@$n @" < $n +done +cat extra.digest +) | awk -v "meta_deps=$meta_deps" ' + BEGIN { + gsub(" ", " pcb-rnd-", meta_deps) + sub("^", "pcb-rnd-", meta_deps) + while((getline < "desc") == 1) { + if ($0 ~ "^@") { + pkg=$0 + sub("^@", "", pkg) + getline SHORT[pkg] < "desc" + continue + } + LONG[pkg] = LONG[pkg] $0 " " + } + } + + ($1 ~ "@files") { + pkg=$2 + files=$0 + sub("@files[ \t]*[^ \t]*[ \t]", "", files) + IFILES[pkg] = files + PKG[pkg] = "n/a" + } + + ($1 ~ "@appendfiles") { + pkg=$2 + files=$0 + sub("@appendfiles[ \t]*[^ \t]*[ \t]", "", files) + IFILES[pkg] = IFILES[pkg] " " files + } + + ($1 ~ "@appenddeps") { + pkg=$2 + deps=$0 + sub("@appenddeps[ \t]*[^ \t]*[ \t]", "", deps) + PKG_DEP[pkg] = PKG_DEP[pkg] " " deps + } + + ($1 ~ "[.]pup$") { + pkg = $1; + sub("[.]pup$", "", pkg) + if (pkg == "(core)") pkg="core" + } + + ($1 ~ "[.]tmpasm$") { + pkg = $1; + sub("/Plug.tmpasm$", "", pkg) + sub(".*/", "", pkg) + if (pkg == "(core)") pkg="core" + } + + ($1 ~ "[.]pup$") { + val=$3 + if (val == "(core)") val="core" + cfg = pkg + val = "pcb-rnd-" val + } + + { + pkg = "pcb-rnd-" pkg + } + + ($1 ~ "[.]pup$") && ($2 == "$package") { + PKG[val] = PKG[val] " " cfg; + PLUGIN[pkg] = val; + if (val == "pcb-rnd-core") { + CFG_BUILDIN[cfg]++ + } + else { + CFG_PLUGIN[cfg]++ + IFILES[val] = IFILES[val] " $P/" cfg ".pup $P/" cfg ".so" + } + } + + ($1 ~ "[.]pup$") && ($2 == "dep") { PLUGIN_DEP[pkg] = PLUGIN_DEP[pkg] " " val } + + ($1 ~ "[.]tmpasm$") && ($3 == "/local/pcb/mod/CONFFILE") { + fn=$4 + sub("[{][ \t]*", "", fn) + sub("[ \t]*[}]", "", fn) + if (CONFFILE[PLUGIN[pkg]] == "") + CONFFILE[PLUGIN[pkg]] = "$C/" fn + else + CONFFILE[PLUGIN[pkg]] = CONFFILE[PLUGIN[pkg]] " $C/" fn + } + + function add_dep(pkg, depson, ds) + { + if (pkg != depson) { + ds = pkg "::" depson + if (!(ds in DEP_SEEN)) { + DEP_SEEN[ds] = 1 + PKG_DEP[pkg] = PKG_DEP[pkg] " " depson + } + } + } + + function strip(s) { + sub("^[ \t]*", "", s) + sub("[ \t]*$", "", s) + return s + } + + END { + + # everything depends on core + for(pkg in PKG) + add_dep(pkg, "pcb-rnd-core") + + # calculate dependencies + for(plg in PLUGIN_DEP) { + v = split(PLUGIN_DEP[plg], A, " ") + pkg = PLUGIN[plg] + if (pkg == "") continue + for(n = 1; n <= v; n++) { + if (A[n] == "") continue + depson = PLUGIN[A[n]] + if (depson == "") + depson = A[n] + add_dep(pkg, depson) + } + } + + PKG_DEP["core"] = "" + PKG_DEP["doc"] = "" + PKG_DEP["pcb-rnd"] = meta_deps + PKG["pcb-rnd"] = "<metapackage>" + PKG["pcb-rnd-doc"] = " " + IFILES["pcb-rnd-doc"] = "/usr/share/doc/*" + + print "

Package summary and dependencies

" + print "" + print "
package depends on (packages) consists of (plugins)" + + for(pkg in PKG) { + if (pkg == "pcb-rnd-core") + print "
" pkg "" PKG_DEP[pkg] "(builtin: " PKG[pkg] ")" + else + print "
" pkg "" PKG_DEP[pkg] "" PKG[pkg] + print strip(PKG_DEP[pkg]) > "auto/" pkg ".deps" + print pkg > "auto/List" + } + print "
" + + print "

Package description and files

" + print "" + print "
package files short long" + for(pkg in PKG) { + if (SHORT[pkg] == "") SHORT[pkg] = " " + if (LONG[pkg] == "") LONG[pkg] = " " + print "
" pkg "" IFILES[pkg] " " CONFFILE[pkg] "" "" SHORT[pkg] "" LONG[pkg] + print strip(IFILES[pkg] " " CONFFILE[pkg]) > "auto/" pkg ".files" + print strip(SHORT[pkg]) > "auto/" pkg ".short" + print strip(LONG[pkg]) > "auto/" pkg ".long" + } + print "
" + print "

File prefixes:

    " + print "
  • $P: plugin install dir (e.g. /usr/lib/pcb-rnd/)" + print "
  • $C: conf dir (e.g. /usr/share/pcb-rnd/)" + print "
  • $PREFIX: installation prefix (e.g. /usr)" + print "
" + + print "

./configure arguments

" + print "--all=disable" + print "--all=disable" > "auto/Configure.args" + + for(p in CFG_BUILDIN) { + print "--buildin-" p + print "--buildin-" p > "auto/Configure.args" + } + for(p in CFG_PLUGIN) { + print "--plugin-" p + print "--plugin-" p > "auto/Configure.args" + } + } +' + +echo ' + + +') > packages.html + Property changes on: tags/2.3.0/doc/developer/packaging/packages.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/developer/packaging.txt =================================================================== --- tags/2.3.0/doc/developer/packaging.txt (nonexistent) +++ tags/2.3.0/doc/developer/packaging.txt (revision 33253) @@ -0,0 +1,95 @@ +Packaging pcb-rnd for a distribution +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +1. program, libs, desktop integration + +Pcb-rnd is an interactive printed circuit board editor program. A typical +user is an electric engineer. This sort of programs are often called EDA, +Electronics Design Automation. + +Pcb-rnd has different frontends: graphical and stdio/text based batch +processing. There are different graphical frontends - pcb-rnd does not +depend on gtk or motif, the specific frontend modules may depend on them. + +Pcb-rnd is scriptable if system installed libfungw is available. Since +libfungw is not a mainstream library, it is most probably not already +present in your distro and it should also be packaged too. + +Pcb-rnd is intended for UNIX-fans. It is heavily keyboard-oriented and it +doesn't assume its users don't want to understand or learn how it works. +Many typical user workflows include Makefiles and it's a common thing to +start pcb-rnd from a shell. Thus desktop integration is not in focus +at the moment. If you fixed things for this while packaging, please let +us know, we may merge your patches (see below). + +2. options, plugins, dependencies + +Pcb-rnd is a modular software with a lot of options. Majority of these options +are selected by the state of a module. A module has three states: + - disable: (not compiled at all) + - buildin: enabled and static linked + - plugin: enabled and dynamic loaded (from a .so) + +The configure script takes --disable-*, --building-* and --plugin-* +arguments with * substituted with the name of the module. The configure +script also determines the dependencies according to the selection. Special +arguments --all=plugin and --all=buildin are provided in configure to select +all working modules to be plugins or buildins. + +For binary distributions it's strongly recommended to have most of the +modules compiled as plugins and have them in separate packages. This +would let the user to install a core pcb-rnd package and then the GTK +or the lesstif plugin (or both) from separate packages. This also reduces +package dependencies. + +The preferred package splitup is documented in packaging/, +please follow that as closely as possible so different systems can +deliver similar pcb-rnd packages. + +This is less relevant for source distributions, if the user has full control +over the configuration. + +If non-critical dependencies are not met, modules are automatically disabled +by ./configure. + +3. typical ./configure options - scconfig vs. auto* + +./configure --prefix works as expected. DESTDIR works as expected. + +Typical commands for configuring pcb-rnd for packaging would be: + + ./configure --all=plugin --prefix=/usr + make all + DESTDIR=/tmp/pkg_tmp make install + +We are happy with scconfig. Please don't write about how much better +autoconf or cmake would be, we won't switch. + +4. release cycles, tarballs, svn trunk - what to package + +Development happens in svn trunk/, there are usually no branches. While +we try to keep trunk/ compilable any time, it's not guaranteed that it +would work out-of-the-box between releases. It is not recommended to +package trunk/ - please package stable releases instead. + +We follow the "release early, release often" rule. Source release tarballs +are always considered stable. Beside the project web page, releases are +also accessible as svn tags: svn://repo.hu/pcb-rnd/tags . + +Sometimes we have minor releases with 1..2 month period, sometimes a +longer period passes between releases. + +There's no automated release notification at the moment; if you want to +get notified about new releases, please contact me +(http://repo.hu/projects/pcb-rnd/contact.html) + +5. bug reporting and fixes for packaging + +There's no special method for reporting packaging related bugs and +feature requests, please follow the normal bug report instructions or just +drop me a mail. Please mention that the issue is related to packaging, this +usually gives it a higher priority. + +We are willing to make minor changes to make packaging easier - if you bump +into something you'd need to work around while packaging, please let us know, +we may just fix it "upstream". + Index: tags/2.3.0/doc/developer/plugin/actions.html =================================================================== --- tags/2.3.0/doc/developer/plugin/actions.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/actions.html (revision 33253) @@ -0,0 +1,96 @@ + + +

pcb-rnd - plugin development - creating actions

+

+Actions are fungw functions typically implemented in C or in a script language. +Actions are used by pcb-rnd to act upon any user request - there's always +an action behind any GUI, CLI or automated operation. pcb-rnd plugins are +written in C, thus they are registering actions written in C. + +

Includes and other requirements

+

+The plugin must #include "actions.h" to be able to register actions. +

+Registering actions require the standard plugin cookie. + +

action implementation

+

+The following example shows how an action is implemented: +

+static const char pcb_acts_ActionName[] = "ActionName(arg1, arg2, [arg3]...)";
+static const char pcb_acth_ActionName[] = "Help text: short description of what the action does.";
+static fgw_error_t pcb_act_ActionName(fgw_arg_t *res, int argc, fgw_arg_t *argv)
+{
+	/* process arguments */
+	/* implement the action */
+	/* return on no-error: */
+	PCB_ACT_IRES(0);
+	return 0;
+}
+
+

+More on how arguments are and return value are handled can be found in the +fungw action documentation. +

+Because of historical reasons action names are in CamelCase. This is the +only context where pcb-rnd tolerates CamelCase. +

+A plugin is free to register any amount of actions. Action names are globally +unique within pcb-rnd. For core plugins, the maintainer of the plugin is +responsible to avoid action name collision. For external plugins, the action +name must be prefixed with the plugin's name. + +

action table

+

+For convenience, actions are most often registered from data tables. The table +shall contain all actions provided by the plugin: +

+static const pcb_action_t pluginname_action_list[] = {
+	{"Action1", pcb_act_Action1, pcb_acth_Action1, pcb_acts_Action1},
+	{"Action2", pcb_act_Action2, pcb_acth_Action2, pcb_acts_Action2}
+};
+
+

+The action name in the first column must be unique. If an action has +alternative names (e.g. shorthands), multiple lines may contain the +same pcb_act* fields with only the name differing. If multiple actions +are implemented in the same function (that e.g. looks at argv[0] to +decide which one was invoked), multiple lines may contain the same +pcb_act_ function, with different name and help/syntax text. +In the very unlikely case multiple action functions have the same +syntax or help, the same pcb_acth_ and/or pcb_acts_ can be used in multiple +rows of the table. +

+The table should be placed after the last action to avoid action +function/help/syntax forward declarations. Most often the table is placed +right above the check_ver callback. + +

action registration on init

+

+Invoke macro +PCB_REGISTER_ACTIONS(pluginname_action_list, pluginname_cookie) +again, from the init callback. It requires the +standard plugin cookie. +

+In practice, the plugin init will look like this: +

+int pplg_init_expfeat(void)
+{
+	PCB_API_CHK_VER;
+	PCB_REGISTER_ACTIONS(pluginname_action_list, pluginname_cookie)
+	return 0;
+}
+
+ +

action removal on uninit

+

+When the plugin is uninitialized, all actions must be removed (to avoid +dangling function pointers after a dynamic plugin unload). This is normally +done by calling +

+	pcb_remove_actions_by_cookie(pluginname_cookie);
+
+from the plugin's uninit callback. + + + Index: tags/2.3.0/doc/developer/plugin/api.html =================================================================== --- tags/2.3.0/doc/developer/plugin/api.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/api.html (revision 33253) @@ -0,0 +1,101 @@ + + +

pcb-rnd - plugin development - API and initialization

+

+Since plugins are managed by puplug, the minimal API a plugin must +provide is as defined by the +puplug project. This +document describes that API with any pcb-rnd aspects included. +

+A minimalistic example of a plugin's main source file implementation +can be found in the plugin template. + +

copyright banner

+

+For core plugins the copyright banner is standard and shall not be +changed (except for the year and name in the copyright line). All +manually written .c files and any non-trivial .h file must have the +banner. License: core plugins must be GPL2+. +

+External plugins can choose a different license banner, but since +pcb-rnd is licensed under the GPL, they shall choose a license that is +compatible with the GPL for run-time dynamic linking. + +

headers and watchdogs

+

+If the plugin consists of multiple source files compiled as separate +compilation units (multiple .o files), there will be header (.h) files. +The header watchdog #defines shall be PCB_PLUGINNAME_H, unless +PLUGINNAME is short and generic and/or conflicts with already +existing core or core plugin watchdogs. In that case use +PCB_CPLUG_PLUGINNAME_H +

+For external plugins, always use PCB_EPLUG_PLUGINNAME_H. + +

#includes

+

+The first include in any .c file must be "config.h", to ensure +configuration time detected libc feature macros are. The .h files +shall not include "config.h". +

+The plugin shall #include pcb-rnd core's "plugins.h" for the mandatory +PCB_API_CHK_VER call. This also requires <stdio.h>. + +

int pplg_check_ver_pluginname(int ver_needed)

+

+This function is called by puplug before the plugin is initialized. The +code that triggered the load may have specified a required API version +number in ver_needed and the plugin needs to decide if it can serve +all functionality of that version - if so, it should return 0 and +initializing the plugin will proceed. How the version number is interpreted +is up to the plugin: can be a serially incremented number, a bitfield, a +date encoded. +

+Most pcb-rnd plugins will not need this and can safely return 0 without +even checking ver_needed. For pcb-rnd plugins the only situation when +using this API makes sense is for external (non-core) lib plugins that +other external plugins are likely to depend on. + + +

void pplg_uninit_pluginname(void)

+

+Called before unloading the plugin. This often happens before quitting pcb-rnd, +even for builtin (static linked) plugins, but for a dynamically loaded +plugin it can happen any time while pcb-rnd is running. +

+The plugin needs to free all memory allocated and unregister from all central +pcb-rnd infrastructure. The plugin must assume pcb-rnd will not exit +after plugin uninitialization. +

+The rule of thumb is: anything registered in the init() callback must have +an unregister call in this uninit() callback. + +

int pplg_init_pluginname(void)

+

+Called after the plugin is loaded and version is checked, +before any other plugin function or variable is accessed. +

+The plugin should set up its own infrastructure and register actions, callbacks, +hooks, tools, etc. in central infrastructure. +

+Each plugin is loaded and initialized only once at a time (there are no +multiple parallel instances of the same plugin), but it is possible to +load-unload the same plugin multiple times during a single pcb-rnd session. +

+Before the init does anything else, it must issue a PCB_API_CHK_VER. This macro +checks for ABI compatibility between the plugin and the core and returns +failure on incompatibility (useful in the dynamic plugin load setup). +

+The init call shall return 0 on success and anything else on failure. After +a failure, the plugin is unloaded - without a call to uninit. Thus on failure +the init function needs to clean up any effect of partial initialization +or registration before returning. + +

conventions

+

+These functions are implemented in the main c file of the plugin, which is +called pluginname.c. These functions are normally the last ones on +the bottom of the file. They are never exposed in header files. + + + Index: tags/2.3.0/doc/developer/plugin/conf.h =================================================================== --- tags/2.3.0/doc/developer/plugin/conf.h (nonexistent) +++ tags/2.3.0/doc/developer/plugin/conf.h (revision 33253) @@ -0,0 +1,17 @@ +!!! replace FOOBAR and foobar with your plugin name !!! + +#ifndef PCB_FOOBAR_CONF_H +#define PCB_FOOBAR_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN enable; /* Enable the plugin */ + RND_CFT_INTEGER snow; /* intensity of snowing, 0..100 */ + } foobar; + } plugins; +} conf_foobar_t; + +#endif Index: tags/2.3.0/doc/developer/plugin/conf.html =================================================================== --- tags/2.3.0/doc/developer/plugin/conf.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/conf.html (revision 33253) @@ -0,0 +1,84 @@ + + +

pcb-rnd - plugin development - per plugin config subtree

+

+Each plugin can maintain its own configuration subtree within the central +conf tree. For this, the plugin needs to create the subtree under its own +name under the plugins/. From then on, the config values are loaded and +handled by the central system and are accessible through a global +struct variable declared within the plugin. + +

the config header

+

+The source of all information on what nodes consists the plugin's own +subtree is the file pluginname_conf.h in the plugin dir. It can +be created by copying and renaming this template. +

+The structure must reproduce the plugin sub-struct and the pluginname +sub-struct nested in it, in order to keep the C struct field reference path +the same as the textual conf path. +

+Create an empty file called pluginname_conf_fields.h for placeholder. +Do not add it to the svn repo. + +

tmpasm

+

+The conf file must be registered in the tmpasm file. Add these lines in +Plug.tmpasm to set the file name: +

+put /local/pcb/mod/CONFFILE {pluginname.conf}
+put /local/pcb/mod/CONF {$(PLUGDIR)/pluginname/pluginname_conf.h}
+
+ +

Create the conf variable

+

+The conf access variable should be a global variable in the main plugin c file: +

+#include "pluginname_conf.h"
+
+const conf_pluginname_t conf_pluginname;
+
+

+From now on, the example fields can be accessed like: +

+conf_pluginname.plugins.pluginname.snow
+
+

+Note: these variables are strictly read-only. Use conf_set*() from src/conf.h +to change the value. + + +

plugin init

+

+Copy these lines in the plugin init callback: +

+#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \
+	conf_reg_field(conf_pluginname, field,isarray,type_name,cpath,cname,desc,flags);
+#include "pluginname_conf_fields.h"
+
+ +

plugin uninit

+

+On uninit all local config nodes need to be removed from the config system. +This is easy, since all our nodes are under a single subtree. Copy this line +in the plugin uninit callback: +

+	conf_unreg_fields("plugins/pluginname/");
+
+ +

make dep

+

+After committing all these, you will need to run make dep in src/. Before committing +that, double check svn diff: it must not have any unrelated change, only files +related to your plugin. +

+When done, the build system knows how to generate pluginname_conf_fields.h - +remove the dummy empty file and run make to get it generated. + +

default values

+

+For setting default values, a local +default config file needs to be set up. + + + Index: tags/2.3.0/doc/developer/plugin/conf_chg.html =================================================================== --- tags/2.3.0/doc/developer/plugin/conf_chg.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/conf_chg.html (revision 33253) @@ -0,0 +1,83 @@ + + +

pcb-rnd - plugin development - config change notification

+

+All settings are stored in one central conf tree. +Any part of the code can register function callbacks that are activated when +a specific (or any) conf node changes. +

+Multiple callback functions can be bound to the same config node and +the same callback function can be bound to multiple config nodes. It is +also possible to bind the callback function to global change, which +means it would be called on any config change. +

+Config change notification is also called 'watch'. + +

how to declare a callback function

+
+void bar_confchg(conf_native_t *cfg, int arr_idx)
+{
+}
+
+ +

local: how to bind the callback function to a node

+

+This typically happens in the plugin init callback: +

+	conf_native_t *cn;
+	conf_hid_id_t confid;
+	static const conf_hid_callbacks_t foo_cbs = { NULL, bar_confchg, NULL, NULL };
+
+	confid = conf_hid_reg(pluginname_cookie, NULL);
+
+	cn = conf_get_field("editor/all_direction_lines");
+	if (cn != NULL)
+		conf_hid_set_cb(cn, confid, &foo_cbs);
+	else
+		/* handle the error */
+
+

+The callbacks struct needs to be static because it is not copied, but the pointer +is stored after registration. The fields of this structure are callback function +pointers for different event types, e.g. "call before the change", "call after +the change" or "call when a new item is created in the conf database"; refer +to src/conf_hid.h for more info. +

+For registering config watches, a confid needs to be registered using conf_hid_reg(). +The registration is done by the plugins standard cookie. +The second argument to this call is for global conf change watches (see below). +

+The next step is to resolve the conf node's conf_native_t pointer, using +conf_get_field(), which takes the plain text config node path as argument. +

+If that worked, conf_hid_set_cb() binds the callback structure to the +config node. There can be only one such binding per conf node per confid, +but the plugin may request multiple confid's with different cookies. + +

global: how to bind the callback function to any change

+

+Sometimes a plugin needs to run on any conf change or needs to react on +new conf nodes being created. For these, use the global callback +argument of conf_hid_reg(): load it with a pointer to a static +conf_hid_callbacks_t struct. +

+Do not do this if you are watching a finite set of conf nodes with +known names - just do a per conf node local binding, even if it means +10 bindings. + +

how to unbind the callback function to a node

+

+When the watch is no longer needed, conf_hid_unreg(), +typically from the uninit callback of the plugin. This will unregister +all watches (local and global) and confid. If only one watch need to be +removed, conf_hid_set_cb() should be called with a callback struct that +has NULL for the given function pointer. (Note: this doesn't replace the +function pointer, but the callback struct pointer in the central registry). +

+For example, place this line in the plugin uninit callback: +

+	conf_hid_unreg(pluginname_cookie);
+
+ + + Index: tags/2.3.0/doc/developer/plugin/conf_file.conf =================================================================== --- tags/2.3.0/doc/developer/plugin/conf_file.conf (nonexistent) +++ tags/2.3.0/doc/developer/plugin/conf_file.conf (revision 33253) @@ -0,0 +1,10 @@ +li:pcb-rnd-conf-v1 { + ha:append { + ha:plugins { + ha:pluginname { + enabled=1 + snow=42 + } + } + } +} Index: tags/2.3.0/doc/developer/plugin/conf_file.html =================================================================== --- tags/2.3.0/doc/developer/plugin/conf_file.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/conf_file.html (revision 33253) @@ -0,0 +1,64 @@ + + +

pcb-rnd - plugin development - local default conf file

+

+Each plugin can have a config file, pluginname.conf, stored +locally and also installed. When this file is available, it specifies +the default value for the plugin-local config nodes. +It also allows users to create user config under ~/.pcb-rnd/ using the +same file name, modularizing the config. + +

create the config file

+

+Copy the template and rename it to +pluginname.conf, replace pluginname and the config nodes +to match the plugin's conf.h. +

+Create an empty file called conf_internal.c (but do not commit it). + +

include the internal version of the config file

+

+Insert the following lines in the main plugin c source: +

+#include "../src_plugins/pluginname/conf_internal.c"
+
+ +

Register the custom conf file

+

+Define the file name (will be used twice) somewhere around the top of +the main source file, then in plugin init callback issue a conf_reg_file(): +

+#define PLUGINNAME_CONF_FN "pluginname.conf"
+
+int pplg_init_pluginname(void)
+{
+	PCB_API_CHK_VER;
+	conf_reg_file(PLUGINNAME_CONF_FN, pluginname_conf_internal);
+	...
+
+

+The conf_reg_file() call should be before the conf fields initialization. + + + +

Unregister the custom conf file

+

+In the uninit callback of the plugin, insert the following line: +

+	conf_unreg_file(PLUGINNAME_CONF_FN, pluginname_conf_internal);
+
+ +

make dep

+

+After finishing all these, before the commit, you will need to run make +dep in src/. Before committing that, double check svn diff: it must not +have any unrelated change, only files related to your plugin. +

+When done, the build system knows how to generate conf_internal.c - +remove the dummy empty file and run make to get it generated. +

+The file will contain one large character array, holding the internal +version of pluginname.conf + + + Index: tags/2.3.0/doc/developer/plugin/cookie.html =================================================================== --- tags/2.3.0/doc/developer/plugin/cookie.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/cookie.html (revision 33253) @@ -0,0 +1,37 @@ + + +

pcb-rnd - plugin development - plugin cookie

+

+Many of the pcb-rnd infrastructure API requires a cookie for +registering new objects. This cookie is typically a const char *, which +is used only in pointer comparison. It is also useful for debugging: +when objects are not unregistered properly, the code can print the value +(string) of the cookie in the error message, which can be a hint on the +source of the registration. +

+The cookie should be a static const char string, normally on top +of the main c file of the plugin: +

+static const char *pluginname_cookie = "pluginname + a 2..3 word description";
+
+ +

multiple cookies

+

+The plugin may use multiple cookies, e.g. different cookie for registering +different set of objects, if that potentially helps debugging. This is especially +useful if the plugin is consists of largely independent subsystems - each +subsystem can have its own cookie. + +

multiple source files vs. cookies

+

+If the plugin contains multiple compilation units (object files), these files +may need to use the same cookie. In that case pluginname_cookie +should not be static and shall be exposed in a plugin header file using +extern. +

+Since cookies are used by pointer, it is important not to copy the +string into multiple objects - those copies will not match. This can happen +accidentally on some systems if the header is missing extern. + + + Index: tags/2.3.0/doc/developer/plugin/core_simple.html =================================================================== --- tags/2.3.0/doc/developer/plugin/core_simple.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/core_simple.html (revision 33253) @@ -0,0 +1,30 @@ + + +

pcb-rnd hacking - simple core plugins

+ +

Introduction

+ +

Setting up a new core plugin

+
    +
  • 1. make up a name for the plugin. There are a few conventions. This document will refer to the name as plg, always replace it with your chosen name. +
  • 2. cd src_plugins; svn mkdir plg +
  • 3. copy all files from the plugin template +
  • 4. edit Makefile: replace "foobar" to plg +
  • 5. edit plg.pup; there should be short summary about the purpose of the plugin then "#key: value" pairs for statistics. Please refer to the pup syntax +
  • 6. edit Plug.tmpasm: replace "foobar" with plg, list all local objects you plan to have +
  • 7. rename and edit foobar.c: replace "foobar" with plg +
  • 8. create your C sources and headers in src_plugins/plg/ +
  • 9. run "make map_plugins" in src/ to get your new plugin on the plugin list +
  • 10. run ./configure --buildin-plg +
  • 11. run make to see if it compiles and test +
  • (12. while developing, you can run make from src_plugins/plg - if + your plugin is a builtin, it will recompile pcb-rnd. For some of us it's convenient + to run make in the same directory where all the source files are.) +
+ +Congratulations, you now have a compilable core plugin that does not do +anything yet, with the basic API skeleton in place. + + + + Index: tags/2.3.0/doc/developer/plugin/events.html =================================================================== --- tags/2.3.0/doc/developer/plugin/events.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/events.html (revision 33253) @@ -0,0 +1,58 @@ + + +

pcb-rnd - plugin development - binding to events

+

+The pcb-rnd event system is a very simple callback system: a list +of function pointers registered by different parts of the code (e.g. plugins), +to be called back on certain events. Different events have different number +and type of arguments, which are passed as an argc/argv pair. An event may +be bound to any number of functions. +

+Upon the occurrence of the event, all event handler functions bound to it +are called, in no particular order. +

+An event handler function can be bound to one or more events, and it can +be bound and unbound runtime. +

+For more details, please read the API in src/event.h. + +

Creating the event handler

+

+Create an event handler function of type pcb_event_handler_t. +

+static void ev_my_event_handler_name(void *user_data, int argc, pcb_event_arg_t argv[])
+{
+
+}
+
+ +

Binding the event

+

+Call pcb_event_bind(), typically in the init callback of the plugin: +

+	pcb_event_bind(PCB_EVENT_BOARD_CHANGED, ev_my_event_handler_name, NULL, pluginname_cookie);
+
+

+The registration requires a standard plugin cookie. +

+The 3rd argument is an arbitrary user data pointer that will get passed to +each call of the event handler. It can be used to communicate between the +code that registers the event and the event handler code. The event system +only stores and passes it on, never dereferences, allocates or frees it. +Should be NULL if not used. + +

Unbinding events

+

+Events are normally unbound in the plugin's uninit callback, using +pcb_event_unbind_cookie(), which unregisters all events registered +with the same cookie. The typical call is: +

+	pcb_event_unbind_allcookie(pluginname_cookie);
+
+

+Events can be unbound one by one, on an event_id/callback_function basis, +using pcb_event_unbind(). This is useful if an event needs to be installed +and uninstalled temporarily. + + + Index: tags/2.3.0/doc/developer/plugin/ext_dont.html =================================================================== --- tags/2.3.0/doc/developer/plugin/ext_dont.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/ext_dont.html (revision 33253) @@ -0,0 +1,73 @@ + + +

pcb-rnd - plugin development - why not to create external plugins

+

+Short answer: join us and create a core plugin instead. Or write a script in +one of the many scripting languages pcb-rnd supports. +

+Pcb-rnd has a fast paced, centralized development strategy, heavily building +on coordinated team work. There is no "API stability": we do not promise +that core APIs wouldn't change. But we do guarantee that any change to the +core will be immediately tracked in all core plugins. +

+The core team, by definition, will not consider or upgrade any +external plugin while changing core APIs. Scripts are much less affected +as they are using actions only and we try not to break action backward +compatibility. +

+Because of the high amount of development time goes into pcb-rnd these days, +if you start maintaining your own external plugin, you will need to spend +a portion of the time we spend on pcb-rnd on just keeping your plugin +from bit-rotting. Example in geda/PCB, with much slower core development, showed +that it does not pay back long term. There are usually four outcomes: +

    +
  • You manage to keep up with core changes - but then you spend (waste) a + lot of time on just keeping your project up-to-date. You also have to + sync your release cycles to pcb-rnd's: users will have to pick the + corresponding plugin version for each pcb-rnd release else the plugin + won't work. That work could better be spent on developing the plugin + if it was a core plugin. +
  • You support only one specific pcb-rnd version; this will get your plugin + unaccessible for most users as they will go on upgrading pcb-rnd. + Rationale: we probably spend more accumulated time on developing + pcb-rnd than you spend on developing your plugin, which means more + features and more bugfixes. Most users will sooner or later will choose + more activity over less. Also, users using pcb-rnd from packages + will be "forced" to upgrade by their distribution. So effectively + this leads to the 3rd possibility: +
  • You maintain a plugin that practically will not be usable for + anybody else. Which sometimes leads to the 4th possibility: +
  • Sometimes we import external plugins and start to maintain them as + core plugins. We had such a mass-import back in 2016, for bit-rotten + pcb plugins floating on the web. However, this could happen only with + abandoned plugins, as we are not going to keep merging forth and back. + Also, this method proven to be extremely inefficient: we already had + to rewrite 1/3 of the imported plugins, had to remove a few and + scheduled a full rewrite on another 1/3. This taught us that it's + often cheaper to write something from scratch than insisting on reuse. + We will especially refuse importing plugins that were started as external + plugin in order to overcome pcb-rnd conventions (e.g. svn or C89). So + if you can't accept our ways and can't join to do a core plugin, it + is not worth starting an external plugin effort and hope it will get + merged because there's high chance it will just bit-rot instead. +
+

+That said, there are some legitimate cases when you could consider maintaining +an external plugin. For example if the goal of the plugin is so extremely +far away from pcb-rnd's that we do not accept the idea at all. But +if you start maintaining your plugin, and do not want to end up spending a lot +of time just to have something bit-rotting, you should really consider how much +time keeping things up to date will require, before you start. +

+Please also note that beause we really prefer our team work model, and we +most likely consider an external plugin effort just waste of time, we will +probably not endorse or promote your plugin in any way. +

+Please do not write an external plugin (or core plugin) off-svn and +then contact us to ask for inclusion as a core plugin. The only way a core +plugin can happen is that you contact the project lead, agree on some details, +get an svn write access and do it in pcb-rnd's repo. We will refuse to import +plugins developed differently. + + + Index: tags/2.3.0/doc/developer/plugin/ext_fungw.html =================================================================== --- tags/2.3.0/doc/developer/plugin/ext_fungw.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/ext_fungw.html (revision 33253) @@ -0,0 +1,41 @@ + + +

pcb-rnd - plugin development - external fungw plugin

+

+First of all: you should write a core plugin, not +an external plugin. +

+If you absolutely can't avoid writing an external plugin, you have two choices: +a native puplug plugin or a fungw engine plugin. This page is about the fungw plugin +method. Pros: simpler code, less boilerplate. Cons: loaded like a script, +shouldn't access pcb-rnd APIs other than actions, +requires system installed (full featured) fungw. +

+Note: this method is equivalent to using a script language and writing +an user script - except that it's written in C, needs to be compiled, and +if crashes, will bring down the whole process with it. +

+Please refer to the example/template plugin. +After make, the resulting .so can be loaded from pcb-rnd using the script() +action: +

+LoadScript(foo, ./ext_bar.so, c)
+
+

+The stderr message from init should appear. The ExtBar action should be +available. +

+To start your external plugin, copy it to new directory and rename +ext_bar both in file names and file content. Please preserve the ext_ prefix. + +

how to develop the plugin

+

+Some naming conventions differ from core plugin development. It is not +possible to register action help and syntax at the moment. + +

Other considerations

+

+As documented for puplug plugins. + + + Index: tags/2.3.0/doc/developer/plugin/ext_pup.html =================================================================== --- tags/2.3.0/doc/developer/plugin/ext_pup.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/ext_pup.html (revision 33253) @@ -0,0 +1,69 @@ + + +

pcb-rnd - plugin development - external pupplug plugin + FAQ

+

+First of all: you should write a core plugin, not +an external plugin. +

+If you absolutely can't avoid writing an external plugin, you have two choices: +a native puplug plugin or a fungw engine plugin. This page is about the puplug plugin +method. Pro: have full access to all APIs. Con: more boilerplate code. +

+Please refer to the example/template plugin. +After make and make install, starting pcb-rnd should auto-load the plugin. +The stderr message from init should appear. The ExtFoo action should +be available. +

+To start your external plugin, copy it to new directory and rename +ext_foo both in file names and file content. Make sure to fill in the +fields in the pup file. Please preserve the ext_ prefix. + +

how to develop the plugin

+

+Other than some naming conventions and the #includes, which are +either "src/*.h" or you need an extra -I for src/, everything is +as documented for core plugins. + +

how to access pcb-rnd's CC, CFLAGS, LDFLAGS, etc.

+

+For that you need to use scconfig +to configure your external plugin. Once you do that, you can use the +--import=$(TRUNK)/scconfig/config.cache argument, which will get scconfig +to read everything cached during pcb-rnd's configuration. This will save +running some detections that are already done for pcb-rnd and will also +import the exact results of CC, CFLAGS, LDFLAGS, etc. +

+After that, you should get your hooks.c to generate a conf file you can +include from your Makefile. +

+Note: we generally do not support having external plugins, so please do +not make requests for pcb-rnd's Makefile.conf to contain whatever nodes +your external plugin may need. + +

How to use autotools, cmake, qmake, ...

+

+No idea, at pcb-rnd we don't use those - we don't provide support for those +tools. + +

Suddenly pcb-rnd core API changed and my external plugin broke!

+

+We told you so. Please consider restarting +your plugin from scratch as a core plugin. If you can't, you will have to +live with frequent API changes. pcb-rnd is not a lib, but an application, +we do not promote developing external plugins, so we don't feel obliged +to keep internal API backward compatibility. + +

The API changes too often. Can you stop doing that please?

+

+No. + +

The API changes too often. Could you please maintain my external plugin?

+

+No. + +

The API changes too often. Could you please include my external plugin as core plugin?

+

+No. + + + Index: tags/2.3.0/doc/developer/plugin/index.html =================================================================== --- tags/2.3.0/doc/developer/plugin/index.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/index.html (revision 33253) @@ -0,0 +1,36 @@ + + +

pcb-rnd - plugin development

+ +

basics

+ + +

advanced topics

+ + +

external plugins

+ + + + Index: tags/2.3.0/doc/developer/plugin/io.html =================================================================== --- tags/2.3.0/doc/developer/plugin/io.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/io.html (revision 33253) @@ -0,0 +1,82 @@ + + +

pcb-rnd - plugin development - registering I/O

+

+A plugin can serve as an I/O interface. Note the difference between plain +import/export and a full I/O - do not implement an I/O for a simple +import or export task but do not implement a pair of import/export +plugins for an I/O task either. +

+A plugin can register multiple I/O interfaces. This is typical for +formats with multiple versions, or for format families with alternative +sub-formats for the same purpose. But the most common setup is that an +io plugin registers one I/O interface. +

+Each I/O interface has a name and priorities. The name is displayed to +the user and priorities determine in what order different options are +presented - this helps ordering common file formats first, exotic options +last. +

+Each I/O interface also has hooks for testing whether it will be able +to load an input file, before doing the real parse. When a file needs to +be loaded, the plugins that will attempt to load are not selected by the +file name, but by file content. +

+For more details on the I/O interface fields, callback functions and +mechanism, refer to src/plug_io.h. + +

Registering an I/O interface

+

+Declare a static variable of pcb_plug_io_t and fill it in from the plugin +init callback: +

+static pcb_plug_io_t io_pluginname;
+
+...
+
+int pplg_init_io_pluginname(void)
+{
+	PCB_API_CHK_VER;
+
+	memset(&io_pluginname, 0, sizeof(io_pluginname));
+
+	/* these are mandatory: */
+	io_pluginname.default_fmt = "shortname";
+	io_pluginname.description = "longname";
+	io_pluginname.save_preference_prio = 89;
+	io_pluginname.default_extension = ".foo";
+	io_pluginname.fp_extension = ".bar";
+	io_pluginname.mime_type = "application/x-pcb-layout";
+	io_pluginname.fmt_support_prio = io_pluginname_fmt;
+	io_pluginname.test_parse = io_pluginname_test_parse;
+
+	/* these are optional (leave NULL if not supported): */
+	io_pluginname.plugin_data = &ctx;
+	io_pluginname.parse_pcb = io_pluginname_parse_pcb;
+	io_pluginname.parse_footprint = io_pluginname_parse_footprint;
+	io_pluginname.parse_font = io_pluginname_parse_font;
+	io_pluginname.write_buffer = io_pluginname_write_buffer;
+	io_pluginname.write_footprint = io_pluginname_write_footprint;
+	io_pluginname.write_pcb = io_pluginname_write_pcb;
+
+	/* the actual registration */
+	PCB_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_pluginname);
+
+

+The memset is required in case the core struct is extended with new fields. +The convention is that NULL or 0 is the default/unused value. With the +memset extending the core struct won't force us to update all plugins. + + +

Unregistering an I/O interface

+

+On plugin uninit any I/O interface registered by the plugin must be +removed. This is done using the PCB_HOOK_UNREGISTER() macro: +

+	PCB_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_pluginname);
+
+ + + + Index: tags/2.3.0/doc/developer/plugin/menu.html =================================================================== --- tags/2.3.0/doc/developer/plugin/menu.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/menu.html (revision 33253) @@ -0,0 +1,64 @@ + + +

pcb-rnd - plugin development - per plugin menus

+

+Some plugins may need to create menu items. This should not be done in +the central menu file, because the plugin may be disabled leaving +defunct menu items in the menu system. Instead, each such plugin shall +inject a menu patch file on load and remove the menu patch on plugin unload. + +

the menu file

+

+The menu file is normally not a menu patch file but +a plain menu file since it only needs to extend the existing menu system and +this is the easiest way to do so. It's recommended to insert menus under +anchors because this method provides better stability over menu file changes. +

+The menu file is typically called: pluginname-menu.lht + +

tmpasm

+

+The menu file must be registered in the tmpasm file. Add these lines in +Plug.tmpasm to set the file name: +

+put /local/pcb/mod/MENUFILE {pluginname-menu.lht}
+put /local/pcb/mod/MENUVAR {pluginname_menu}
+
+ +

Create the menu variable

+

+Menu patch requires the following lines around the top of the plugin code: +

+#include <librnd/core/hid_menu.h>
+#include "menu_internal.c"
+
+

+The menu file is translated to a variable named in MENUVAR above, typically +pluginname_menu - this is the "internal" version embedded in the +executable, fallback in case the menu file is not found. + +

plugin init

+

+Copy these lines in the plugin init callback: +

+	rnd_hid_menu_load(rnd_gui, NULL, pluginname_cookie, 175, NULL, 0, pluginname_menu, "plugin: pluginname");
+
+

+Replace 175 with the patch priority - in the most common setup this controls +the order of newly created menu items under the same anchor. + +

plugin uninit

+

+On uninit the menu patch needs to be unloaded: +

+	rnd_hid_menu_unload(rnd_gui, pluginname_cookie);
+
+ +

make dep

+

+After committing all these, you will need to run make dep in src/. Before committing +that, double check svn diff: it must not have any unrelated change, only files +related to your plugin. + + + Index: tags/2.3.0/doc/developer/plugin/menu.lht =================================================================== --- tags/2.3.0/doc/developer/plugin/menu.lht (nonexistent) +++ tags/2.3.0/doc/developer/plugin/menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Load TinyCAD .net file = { action=LoadTinyCADFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/doc/developer/plugin/naming.html =================================================================== --- tags/2.3.0/doc/developer/plugin/naming.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/naming.html (revision 33253) @@ -0,0 +1,16 @@ + + +

pcb-rnd hacking - plugin naming conventions

+
    +
  • export_: export plugins start with export_; these render to a non-native format that can not be then loaded +
  • import_: import plugins start with import_; these perform partial data load from alien formats (typically: netlist/schematics) +
  • io_: full board save/load prefixed with io_; even if your plugin can now only load or save, if it's possible to do a load-save-load round-trip without data loss, it's an io_ +
  • hid_: interactive, often GUI, frontends are prefixed with hid_ +
  • fp_: footprint access plugins start with fp_ +
  • lib_ plugins are libraries used by other plugins; they are disabled by default and are enabled through the plugin dependency system +
  • act_ plugins are stateless wrappers to expose existing C functions (moslty core functionality) over the action API (for scripts and users) +
  • ar_ plugins are related to external autorouting: they are reponsible for calling the external process and coordinate the routing but sometimes also implement export/import pair for the format +
  • anything else is considered a feature plugin and has no specific prefix. +
+ + Index: tags/2.3.0/doc/developer/plugin/new_plugin.html =================================================================== --- tags/2.3.0/doc/developer/plugin/new_plugin.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/new_plugin.html (revision 33253) @@ -0,0 +1,38 @@ + + +

pcb-rnd - plugin development - when to create a new plugin

+

+The generic structure of the pcb-rnd source code is: +

    +
  • core (always linked into the pcb-rnd executable) +
  • core plugins (disabled, linked into the executable or installed as runtime dynamic loadable plugins) +
  • utilities (never linked to the pcb-rnd executable, as they are stand-alone programs) +
+

+Core is mainly providing startup and basic infrastructure, including basic +objects, basic operations on those objects, event and action systems, configuration +system, etc. Anything else, including any file format, GUI, and majority of the +user features are implemented in core plugins. Thus most of the code of +pcb-rnd are in the core plugins. +

+When a new feature is to be introduced, it should go into a plugin by +default. Adding it in core should be considered only if it's a basic, central +infrastructure multiple other plugins will depend on. +

+Whether the new feature should go in an existing core plugin or should get +a new core plugin depends on how far it is from existing plugin functionality. +We generally prefer to have more, smaller plugins instead of few large ones. +However we also prefer to avoid code duplications. +

+Before creating a new plugin or adding the feature in an existing plugin, +please consult the project leader. We are liberal and welcoming about new +plugins; however, any new plugin must meet a few requirements: +

    +
  • Programming language: C89. In a few special cases C99 (project leader permission required). Plugins can not be written in C11, C++, etc. +
  • External dependencies should be reasonable: reuse only when it pays off. Shall not depend on glib, apr and other large solves-everything megalib. +
  • Core plugins are in our central svn repository. It is not possible to maintain core plugins in git, hg, fossil, etc. Consult the project leader, you will get svn write access from day 0. +
  • If you start writing a plugin, we expect you to be able to allocate enough time to at least finish the initial version, but it's even better if you can maintain it afterward. If you implement the first 10% then lose interest and stop working on it, the code will eventually get removed from the project. +
+ + + Index: tags/2.3.0/doc/developer/plugin/pup.html =================================================================== --- tags/2.3.0/doc/developer/plugin/pup.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/pup.html (revision 33253) @@ -0,0 +1,38 @@ + + +

pcb-rnd hacking - plugin .pup fields

+

+The pup file holds all metadata for a plugin that is required for +./configure and for puplug to load the plugin run-time. Fields starting +with $ are pcb-rnd-specific fields, the rest are common puplug fields that +will behave the same in other puplug modularized projects as well. +

+Each field is a single-line and can not contain semicolon (';'). +

+The fields in use for pcb-rnd plugins: +

+

    +
  • $class the same as the plugin name prefix (see conventions. ) or (feature) for feature plugins; it's redundant but is kept for supporting external plugins - see mods3 for a short list of all classes +
  • $short short description - should be less than 32 characters; this shows up in the configure summary +
  • $long long description - used for documentation; no length limitation, but must be a single line +
  • $state works, WIP, abandoned or deprecated - see mods3 for explanation +
  • $lstate [optional] a chance to explain why the value of default is what it is; e.g. why a plugin is disabled +
  • $package when pcb-rnd is packaged for a distribution or OS, which package this plugin should end up in (see also: packaging howto) +
  • $fmt-native only for io_ plugins: whether this format is considered native (see also: io_lihata's pup) +
  • $fmt-feature-r only for io_ plugins: a read/load feature supported by the plugin (multiple entries of this should be added; see also: io_lihata's pup) +
  • $fmt-feature-w only for io_ plugins: a write/save feature supported by the plugin (multiple entries of this should be added; see also: io_lihata's pup) +
  • default disable-all or disable or buildin or plugin; see below +
  • dep [optional] a single plugin name on which plg depends; multiple dep lines can be added +
  • conflict [optional] a single plugin name on which plg conflicts with; multiple dep lines can be added +
  • autoload [optional] when 1, the plugin is automatically loaded and initialized (when not disabled); do not set this on libs and other code that are accessible only as a dependency of other plugins; set this 1 on HID, io, import, export, feature plugins +
+

Values of default: +

    +
  • buildin - unless the user requests otherwise, your plugin is linked into the executable +
  • plugin - unless the user requests otherwise, your plugin is dynamically linked; not recommended: the policy is to let users explicitly request dynamic linking +
  • disable - unless the user requests otherwise, your plugin is not compiled (recommended until the plugin gets some user testing) +
  • disable-all - the plugin stays disabled even with ./configure --all=* and the only way to enable it is to explicitly name it +
+ + + Index: tags/2.3.0/doc/developer/plugin/template/Makefile =================================================================== --- tags/2.3.0/doc/developer/plugin/template/Makefile (nonexistent) +++ tags/2.3.0/doc/developer/plugin/template/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_foobar + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/doc/developer/plugin/template/Plug.tmpasm =================================================================== --- tags/2.3.0/doc/developer/plugin/template/Plug.tmpasm (nonexistent) +++ tags/2.3.0/doc/developer/plugin/template/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {foobar} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/foobar/foobar.o +@] + +switch /local/pcb/foobar/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/doc/developer/plugin/template/foobar.c =================================================================== --- tags/2.3.0/doc/developer/plugin/template/foobar.c (nonexistent) +++ tags/2.3.0/doc/developer/plugin/template/foobar.c (revision 33253) @@ -0,0 +1,43 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include + +int pplg_check_ver_foobar(int ver_needed) { return 0; } + +void pplg_uninit_foobar(void) +{ +} + +int pplg_init_foobar(void) +{ + RND_API_CHK_VER; + return 0; +} Index: tags/2.3.0/doc/developer/plugin/template/foobar.pup =================================================================== --- tags/2.3.0/doc/developer/plugin/template/foobar.pup (nonexistent) +++ tags/2.3.0/doc/developer/plugin/template/foobar.pup (revision 33253) @@ -0,0 +1,6 @@ +$class ***FILL THIS IN*** +$short ***FILL THIS IN*** +$long ***FILL THIS IN*** +$state WIP +default disable +autoload 1 Index: tags/2.3.0/doc/developer/plugin/template_fungw/Makefile =================================================================== --- tags/2.3.0/doc/developer/plugin/template_fungw/Makefile (nonexistent) +++ tags/2.3.0/doc/developer/plugin/template_fungw/Makefile (revision 33253) @@ -0,0 +1,20 @@ +### config part ### + +# You may want to use some configuration system for these; below is +# a simple "edited by the user" concept to keep the example small and clear +CFLAGS = -Wall -g -fPIC +LDFLAGS = +SOFLAGS = -rdynamic -shared + + +### rules ### + +all: ext_bar.so + +ext_bar.so: ext_bar.o + $(CC) -o ext_bar.so $(LDFLAGS) $(SOFLAGS) ext_bar.o + +ext_bar.o: ext_bar.c + +clean: + rm -f ext_bar.o ext_bar.so Index: tags/2.3.0/doc/developer/plugin/template_fungw/ext_bar.c =================================================================== --- tags/2.3.0/doc/developer/plugin/template_fungw/ext_bar.c (nonexistent) +++ tags/2.3.0/doc/developer/plugin/template_fungw/ext_bar.c (revision 33253) @@ -0,0 +1,63 @@ +/* + * COPYRIGHT + * + * bar - an external fungw plugin for pcb-rnd (example/template plugin) + * Copyright (C) 2018 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: TODO: FILL THIS IN + */ + +#include +#include + +/* Action ExtBar() */ +static fgw_error_t extbar(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + fgw_ctx_t *ctx = argv[0].val.func->obj->parent; + fgw_arg_t call_res; + int retval; + + /* pcb-rnd API shall be accessed through fungw calls */ + retval = fgw_vcall(ctx, &call_res, "message", FGW_STR, "PLEASE CONSIDER DEVELOPING A CORE PLUGIN INSTEAD!\n", 0); + + /* need to check and free the return value - any action call may fail */ + if (retval != 0) + fprintf(stderr, "ERROR: failed to call message() (fungw level)\n"); + else if ((call_res.type != FGW_INT) || (call_res.val.nat_int != 0)) + fprintf(stderr, "ERROR: failed to call message() (action level)\n"); + fgw_arg_free(ctx, &call_res); + + /* Set the return value of this action */ + res->val.nat_int = 0; + res->type = FGW_INT; + return 0; +} + +/* Called once before the plugin is unloaded */ +void pcb_rnd_uninit(fgw_obj_t *obj) +{ + fprintf(stderr, "EXT BAR uninit\n"); +} + +/* Called once when the plugin is loaded; returns 0 on success */ +int pcb_rnd_init(fgw_obj_t *obj, const char *opts) +{ + fgw_func_reg(obj, "extbar", extbar); /* need to register with lowercase name */ + + fprintf(stderr, "EXT BAR init with '%s'\n", opts); + return 0; +} Index: tags/2.3.0/doc/developer/plugin/template_pup/Makefile =================================================================== --- tags/2.3.0/doc/developer/plugin/template_pup/Makefile (nonexistent) +++ tags/2.3.0/doc/developer/plugin/template_pup/Makefile (revision 33253) @@ -0,0 +1,36 @@ +### config part ### + +# edit this to point to pcb-rnd svn checkout's trunk/ (or the release +# tarball's root). Assumes the pcb-rnd source is configured. +TRUNK=../../../.. + +# You may want to use some configuration system for these; below is +# a simple "edited by the user" concept to keep the example small and clear +CFLAGS = -Wall -g -fPIC -I$(TRUNK) -I$(TRUNK)/src_3rd +LDFLAGS = +SOFLAGS = -rdynamic -shared +PLUGDIR = $(LIBDIR)/plugins + + +### rules ### + +all: ext_foo.so + +include $(TRUNK)/Makefile.conf + +ext_foo.so: ext_foo.o + $(CC) -o ext_foo.so $(LDFLAGS) $(SOFLAGS) ext_foo.o + +ext_foo.o: ext_foo.c + +clean: + rm -f ext_foo.o ext_foo.so + +install: + mkdir -p $(PLUGDIR) + cp ext_foo.so $(PLUGDIR)/ext_foo.so + cp ext_foo.pup $(PLUGDIR)/ext_foo.pup + +uninstall: + rm -f $(PLUGDIR)/ext_foo.so $(PLUGDIR)/ext_foo.pup + Index: tags/2.3.0/doc/developer/plugin/template_pup/ext_foo.c =================================================================== --- tags/2.3.0/doc/developer/plugin/template_pup/ext_foo.c (nonexistent) +++ tags/2.3.0/doc/developer/plugin/template_pup/ext_foo.c (revision 33253) @@ -0,0 +1,65 @@ +/* + * COPYRIGHT + * + * foo - an external plugin for pcb-rnd (example/template plugin) + * Copyright (C) 2018 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: TODO: FILL THIS IN + */ + +/* This is pcb-rnd's config.h from trunk: */ +#include "config.h" + +#include + +/* These are pcb-rnd's headers from trunk: */ +#include "src/actions.h" +#include "src/plugins.h" + +static const char *ext_foo_cookie = "ext foo (external plugin example/template)"; + +static const char pcb_acts_ExtFoo[] = "ExtFoo(arg1, arg2, [arg3]...)"; +static const char pcb_acth_ExtFoo[] = "Help text: short description of what the action does."; +static fgw_error_t pcb_act_ExtFoo(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "PLEASE CONSIDER DEVELOPING A CORE PLUGIN INSTEAD!\n"); + RND_ACT_IRES(0); + return 0; +} + +static const rnd_action_t ext_foo_action_list[] = { + {"ExtFoo", pcb_act_ExtFoo, pcb_acth_ExtFoo, pcb_acts_ExtFoo} +}; + +int pplg_check_ver_ext_foo(int ver_needed) { return 0; } + +void pplg_uninit_ext_foo(void) +{ + fprintf(stderr, "EXT FOO uninit\n"); + rnd_remove_actions_by_cookie(ext_foo_cookie); +} + + +int pplg_init_ext_foo(void) +{ + RND_API_CHK_VER; /* for external plugins this is CRITICAL */ + + RND_REGISTER_ACTIONS(ext_foo_action_list, ext_foo_cookie); + + fprintf(stderr, "EXT FOO init\n"); + return 0; +} Index: tags/2.3.0/doc/developer/plugin/template_pup/ext_foo.pup =================================================================== --- tags/2.3.0/doc/developer/plugin/template_pup/ext_foo.pup (nonexistent) +++ tags/2.3.0/doc/developer/plugin/template_pup/ext_foo.pup (revision 33253) @@ -0,0 +1,5 @@ +$class ***FILL THIS IN*** +$short ***FILL THIS IN*** +$long ***FILL THIS IN*** +$state WIP +autoload 1 Index: tags/2.3.0/doc/developer/plugin/terms.html =================================================================== --- tags/2.3.0/doc/developer/plugin/terms.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/terms.html (revision 33253) @@ -0,0 +1,23 @@ + + +

pcb-rnd - plugin development - terminology

+

+The core is pcb-rnd's core source code that lives in pcb-rnd svn, in +trunk/src. Maintained by the pcb-rnd team. +

+A plugin is a small portion of the code. +

+Core plugins are those plugins that are in pcb-rnd svn, +in trunk/src_plugins. Maintained by the pcb-rnd team. +

+External plugins are those plugins that are written, maintained +and hosted by developers not part of the pcb-rnd team. External plugins +are not hosted in the pcb-rnd svn and are not supported by the pcb-rnd team. +

+A core plugin can be disabled (not compiled at all), +static linked (builtin), or dynamically linked (plugin). This is +selected during pcb-rnd ./configure time. An external plugin is always dynamically +linked. + + + Index: tags/2.3.0/doc/developer/plugin/tmpasm_vars.html =================================================================== --- tags/2.3.0/doc/developer/plugin/tmpasm_vars.html (nonexistent) +++ tags/2.3.0/doc/developer/plugin/tmpasm_vars.html (revision 33253) @@ -0,0 +1,70 @@ + + +

pcb-rnd hacking - plugin Plug.tmpasm variables

+

+Plug.tmpasm is used for coordinating the build of the plugin. It is +written in tmpasm +and is processed by scconfig while generating the Makefile. For core (src/) +and core plugins (src_plugins/) there is a single central Makefile generated +in src/Makefile. The plugin's own Makefile is just a call to the central +Makefile for convenience. +

+Plug.tmpasm is a generic template, its output directly ends up in src/Makefile. +This provides the plugin developer some flexibility, but using this feature +needs deep understanding of the build system. +

+For the features that are most commonly needed, the system offers +prewritten, turn key solutions. It is strongly recommended to use these +features only. These features are accessible through setting /local/pcb/mod/* +tmpasm variables (typically with the put and append instructions). The +rest of this document lists and explains these variables. + + + + + + + + + + + + + +
variable description +
/local/pcb/mod + the name of the plugin +
/local/pcb/mod/OBJS + a whitespace separated list of local object files to compile, + e.g. foo.o +
/local/pcb/mod/OBJS_C99 + same as OBJS, but for sources that can be compiled only with a C99 + compiler; plugins must not use this variable unless the source + depends on 3rd party library which comes with a header that absolutely + can not compiled with C89 +
/local/pcb/mod/CFLAGS + +
/local/pcb/mod/LDFLAGS + +
/local/pcb/mod/CONF + optional: the name of the conf struct + header - if the plugin doesn't have runtime configuration + settings, remove this line +
/local/pcb/mod/CONFFILE + optional: conf file's internal version: the file name of the conf + file (without path) that should be encoded in conf_internal.c +
/local/pcb/mod/CONFVAR + optional: conf file's internal version: the variable name to use + in conf_internal.c +
/local/pcb/mod/YACC + optional: if you have files for yacc-processing, list them without + the .y suffix here (whitespace separated list) +
/local/pcb/mod/LEX + optional: if you have files for lex-processing, list them without + the .l suffix here (whitespace separated list) +
/local/pcb/mod/SPHASH + optional: if the plugin uses an sphash (compile time perfect hash), + the sphash source file name should be specified in this field + + + Index: tags/2.3.0/doc/developer/polygon.html =================================================================== --- tags/2.3.0/doc/developer/polygon.html (nonexistent) +++ tags/2.3.0/doc/developer/polygon.html (revision 33253) @@ -0,0 +1,160 @@ +

different faces of a polygon

+

+In pcb-rnd polygons have three possible appearance: +

    +
  • points: the as-drawn version +
  • clipped: the as-shown version, with holes +
  • no-holes: the as-shown version, without holes +
+ +

The as-drawn version

+

+The as-drawn version is a list of points (corners), as drawn +by the user. The points are stored in an array of x;y coordinates. +There is a single, continous, dynamically allocated array for all points, +including the outer contour and the holes. +

+The points are stored in the Points[] field. The HoleIndex[] +field lists the starting index of each hole. For example a +rectangular polygon with 2 triangle holes is stored as: +

+ +
index 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. +
Points[] value c1 c2 c3 c4 h1.1 h1.2 h1.3 h2.1 h2.2 h2.3 +
part of outer contour hole 1 hole 2 +
+

+The array length of Points[] is 10, the length of the correspoding HoleIndex[] is 2. +The values of HoleIndex[] is {4, 7}, indicating that the corners of first hole +starts at 4 while the corners of the second hole starts at 7. +

+If HoldeIndex[] is NULL, there are no holes and all points are part of the +outer contour. The Outer contour must contain at least 3 points. +

+The as-drawn version always contains the contour of a single island +and 0 or more holes - none of them can intersect or touch any contour or +hole of the same polygon. This also means a contour or hole can not be +self-intersecting. +

+The as-drawn version is stored to make editing possible. It is +not affected by other objects (e.g. clearances) or flags of the polygon. +The as-drawn points exist and are stored even if they are not visible +(clipped). The UI maniulates the as-drawn version. + + +

The clipped version

+

+The polygon is clipped by an object if both the polygon and the object have +the correspoding 'clear' flag set. A clipped polygon typically has a much +more complex shape than the as-drawn polygon, due to the clearance cutouts +(not to be confused with user drawn holes). The clipped polygon is the actual +"in-copper" shape of the polygon. +

+In some cases the clearance cutouts slice the polygon in multiple components +or in other word islands. If the polygon is full (set by +a polygon flag), all islands are kept, else only the largest island is kept. +(Note: the find code handles all islands of a full polygon as one polygon: it +indicates connection between them even if there is no connection, which makes +full polygons dangerous on copper layers.) +

+The clipped polygon is stored in the polyarea field Clipped. It is a doubly +linked circular list (link fields are .f for forward and .b for backward). Each +item on the list is an island of the polygon. If Clipped is NULL, the +polygon clipping is not yet compiled for the given polygon; call pcb_poly_init_clip(). +

+Each island is a polyarea, which consists of an outer contour and 0 or more +holes - all correspoding to the actual cutouts created by user-drawn polygon +holes and/or clearance cutouts. These contours are stored in a singly linked +list of plines. The first element of the list is the pline for the outer +contour and always exists. The next 0 or more plines, using the .next field +of the pline, are the contours of the cutouts (holes). +

+A pline consists of a circular, doubly linked list of points; traversing using +the .next field, the points are ordered in counter-clockwise. +

+The clipped polygon shall be updated by any code that changes: +

    +
  • the as-drawn points of the polygon +
  • geomerty of any object that may overlap with the polygon (so that clearance changes are applied) +
+

+When some code forgets to update clippig, the clipped polygon doesn't match +the clearances dictated by other objects; a reload of the board "fixes" the +problem by forcing the clip. (Native save files contain the as-drawn poly only, +not the (outdated) clipped poly). + +

The no-holes version

+

+Some export plugins (and/or export formats) don't support holes in polygons. +The no-hole version of the polygon is stored in the .NoHoles filed and is +a list of islands, each specified with an outer countour that are crafted +to include the holes. This is done by slicing an island at each hole. +TODO: check how it looks, include image + +

Further comments by Ben Jackson

+As extracted from the original code comments: +
+The first pcb_polyarea_t in pcb_polygon_t.Clipped is what is used for the vast
+majority of Polygon related tests.  The basic logic for an
+intersection is "is the target shape inside pcb_polyarea_t.contours and NOT
+fully enclosed in any of pcb_polyarea_t.contours.next... (the holes)".
+
+The polygon dicer (NoHolesPolygonDicer and r_NoHolesPolygonDicer)
+emits a series of "simple" pcb_pline_t shapes.  That is, the pcb_pline_t isn't
+linked to any other "holes" outlines).  That's the meaning of the first
+test in r_NoHolesPolygonDicer.  It is testing to see if the pcb_pline_t
+contour (the first, making it a solid outline) has a valid next
+pointer (which would point to one or more holes).  The dicer works by
+recursively chopping the polygon in half through the first hole it
+sees (which is guaranteed to eliminate at least that one hole).  The
+dicer output is used for HIDs which cannot render things with holes
+(which would require erasure).
+
+ +

How to code with polygons

+ +

Iterators: looping on clipped polygon geometry

+ +The following code prints all contours and holes of a polygon, using loops +iterators. The same iterator holds all states, so that it points to: +
    +
  • one polygon +
  • one of the islands of that polygon +
  • either the outer contour or one of the holes in that polygon (cntr) +
  • one of the points in cntr +
+ +
+void print_poly(pcb_polygon_t *polygon)
+{
+	pcb_poly_it_t it;
+	rnd_polyarea_t *pa;
+
+	/* first, iterate over all islands of a polygon */
+	for(pa = pcb_poly_island_first(polygon, &it); pa != NULL; pa = pcb_poly_island_next(&it)) {
+		rnd_coord_t x, y;
+		rnd_pline_t *pl;
+		int go;
+
+		printf(" island\n");
+		/* check if we have a contour for the given island */
+		pl = pcb_poly_contour(&it);
+		if (pl != NULL) {
+			printf("  contour:\n");
+			/* iterate over the vectors of the contour */
+			for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) {
+				pcb_printf("   %mm %mm\n", x, y);
+			}
+			
+			/* iterate over all holes within this island */
+			for(pl = pcb_poly_hole_first(&it); pl != NULL; pl = pcb_poly_hole_next(&it)) {
+				printf("  hole:\n");
+				/* iterate over the vectors of the given hole */
+				for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) {
+					rnd_printf("   %mm %mm\n", x, y);
+				}
+			}
+		}
+	}
+}
+
Index: tags/2.3.0/doc/developer/releasing.txt =================================================================== --- tags/2.3.0/doc/developer/releasing.txt (nonexistent) +++ tags/2.3.0/doc/developer/releasing.txt (revision 33253) @@ -0,0 +1,15 @@ +release check list + +(0. test compile and test run a clean checkout on a clean system + configure with --debug --all=buildin, then without + not required anymore: autotest does it now) +1. check next version number and previous revision in tags/ + temporary: also bump librnd's version +2. update the changelog +3. rewrite the release notes +4. modify version number in scconfig +5. commit trunk +6. svn tag using URLs +7. update the timeline, events and doc/news.html +8. update locally built binaries: windows + Index: tags/2.3.0/doc/developer/renames =================================================================== --- tags/2.3.0/doc/developer/renames (nonexistent) +++ tags/2.3.0/doc/developer/renames (revision 33253) @@ -0,0 +1,1784 @@ +Name differences between mainline -> pcb_rnd +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#types: + +PCBTypePtr -> pcb_board_t * +PCBType -> pcb_board_t +DataTypePtr -> pcb_data_t * +DataType -> pcb_data_t +LayerGroupTypePtr -> pcb_layer_group_t * +LayerGroupType -> pcb_layer_group_t +LayerTypePtr -> pcb_layer_t * +LayerType -> pcb_layer_t +BufferTypePtr -> pcb_buffer_t * +BufferType -> pcb_buffer_t +NetTypePtr -> pcb_net_t * +NetType -> pcb_net_t +ConnectionTypePtr -> pcb_connection_t * +ConnectionType -> pcb_connection_t +BoxTypePtr -> pcb_box_t * +BoxType -> pcb_box_t +BoxListTypePtr -> pcb_box_list_t * +BoxListType -> pcb_box_list_t +FontTypePtr -> pcb_font_t * +FontType -> pcb_font_t +LineTypePtr -> pcb_line_t * +LineType -> pcb_line_t +AttachedObjectTypePtr -> pcb_attached_obj_t * +AttachedObjectType -> pcb_attached_obj_t +AttachedLineTypePtr -> pcb_attached_line_t * +AttachedLineType -> pcb_attached_line_t +CrosshairTypePtr -> pcb_crosshair_t * +CrosshairType -> pcb_crosshair_t +MarkTypePtr -> pcb_mark_t * +MarkType -> pcb_mark_t +ArcTypePtr -> pcb_arc_t * +ArcType -> pcb_arc_t +PointTypePtr -> pcb_point_t * +PointType -> pcb_point_t +RatTypePtr -> pcb_rat_t * +RatType -> pcb_rat_t +PolygonTypePtr -> pcb_polygon_t * +PolygonType -> pcb_polygon_t +PadTypePtr -> pcb_pad_t * +PadType -> pcb_pad_t +PinTypeType -> pcb_pin_t * +PinType -> pcb_pin_t +ElementTypeHandle -> pcb_element_t ** +ElementTypePtr -> pcb_element_t * +ElementType -> pcb_element_t +TextTypePtr -> pcb_text_t * +TextType -> pcb_text_t +AttributeListTypePtr -> pcb_attribute_list_t * +AttributeListType -> pcb_attribute_list_t +AttributeTypePtr -> pcb_attribute_t * +AttributeType -> pcb_attribute_t +OutputTypePtr -> pcb_output_t * +OutputType -> pcb_output_t +DrcViolationTypePtr -> pcb_drc_violation_t * +DrcViolationType -> pcb_drc_violation_t +FlagBitsTypePtr -> pcb_flag_bits_t * +FlagBitsType -> pcb_flag_bits_t +FlagTypePtr -> pcb_flag_t * +FlagType -> pcb_flag_t +SymbolTypePtr -> pcb_symbol_t * +SymbolType -> pcb_symbol_t +FunctionID -> pcb_function_id_t +EndCapStyle -> pcb_cap_style_t +hidval -> pcb_hidval_t +HID_Action -> pcb_hid_action_t +PCBWatchFlags -> pcb_watch_flags_t +HID_DRC_GUI -> pcb_hid_drc_gui_t +HID -> pcb_hid_t +hid_gc_struct -> hid_gc_s +hidGC -> pcb_hid_gc_t +HID_Attr_Val -> pcb_hid_attr_val_t +HID_Attribute -> pcb_hid_attribute_t +HID_AttrNode -> pcb_hid_attr_node_t +LibraryEntryTypePtr -> pcb_lib_entry_t * +LibraryEntryType -> pcb_lib_entry_t +LibraryMenuTypePtr -> pcb_lib_menu_t * +LibraryMenuType -> pcb_lib_menu_t +LibraryTypePtr -> pcb_lib_t * +LibraryType -> pcb_lib_t +UnitList -> pcb_unit_list_t +unitflags -> pcb_unit_flags_e +UnitList -> pcb_unit_list_t +NetListTypePtr -> pcb_netlist_t * +NetListType -> pcb_netlist_t +NetListListTypePtr -> pcb_netlist_list_t * +NetListListType -> pcb_netlist_list_t +AnyObjectTypePtr -> pcb_any_obj_t * +AnyObjectType -> pcb_any_obj_t +AnyLineObjectTypePtr -> pcb_any_line_t * +AnyLineObjectType -> pcb_any_line_t +AttachedLineTypePtr -> pcb_attached_line_t +AttachedLineType -> pcb_attached_line_t * +Vector -> pcb_vector_t +vertex -> pcb_vertex_t +CVCList -> pcb_cvc_list_t +VNODE -> pcb_vnode_t +PLINE -> pcb_pline_t +POLYAREA -> pcb_polyarea_t +PolygonBooleanOperation -> pcb_poly_bool_op_e +RubberbandType -> pcb_rubberband_t +Unit -> pcb_unit_t +Increments -> pcb_increments_t +Angle -> pcb_angle_t +Coord -> pcb_coord_t +RouteStyleTypePtr -> pcb_route_style_t * +RouteStyleType -> pcb_route_style_t +heap_t -> pcb_heap_t +cost_t -> pcb_cost_t + +# functions: +EventMoveCrosshair -> pcb_event_move_crosshair +AdjustAttachedObjects -> pcb_adjust_attached_objects + +warpNoWhere -> pcb_warp_nowhere +get_style_size -> pcb_get_style_size +NotifyLine -> pcb_notify_line +NotifyBlock -> pcb_notify_block +NotifyMode -> pcb_notify_mode +ClearWarnings -> pcb_clear_warnings +ReleaseMode -> pcb_release_mode +AFAIL -> PCB_AFAIL +ACTION_ARG -> PCB_ACTION_ARG +AttributeGetFromList -> pcb_attribute_get +AttributePutToList -> pcb_attribute_put +AttributeRemoveFromList -> pcb_attribute_remove +FreeAttributeListMemory -> pcb_attribute_free +AttributeGet -> pcb_attrib_get +AttributePut -> pcb_attrib_put +AttributeRemove -> pcb_attrib_remove +FreePCBMemory -> pcb_board_free +CreateNewPCB_ -> pcb_board_new_ +CreateNewPCB -> pcb_board_new +CreateNewPCBPost -> pcb_board_new_postproc +CountHoles -> pcb_board_count_holes +SWAP_X -> PCB_SWAP_X +SWAP_Y -> PCB_SWAP_Y +ROTATEBOX_CW -> PCB_BOX_ROTATE_CW +ROTATEBOX_TO_NORTH -> PCB_BOX_ROTATE_TO_NORTH +ROTATEBOX_FROM_NORTH -> PCB_BOX_ROTATE_FROM_NORTH +CENTER_X -> PCB_BOX_CENTER_X +CENTER_Y -> PCB_BOX_CENTER_Y +MOVE_BOX_LOWLEVEL -> PCB_BOX_MOVE_LOWLEVEL +point_in_box -> pcb_point_in_box +point_in_closed_box -> pcb_point_in_closed_box +box_is_good -> pcb_box_is_good +box_intersect -> pcb_box_intersect +closest_pcb_point_in_box -> pcb_closest_pcb_point_in_box +box_in_box -> pcb_box_in_box +clip_box -> pcb_clip_box +shrink_box -> pcb_shrink_box +bloat_box -> pcb_bloat_box +box_center -> pcb_box_center +box_corner -> pcb_box_corner +point_box -> pcb_point_box +close_box -> pcb_close_box +dist2_to_box -> pcb_dist2_to_box +GetBoxMemory -> pcb_box_new +FreeBoxListMemory -> pcb_box_free +SetPointBoundingBox -> pcb_set_point_bounding_box +SwapBuffer -> pcb_swap_buffer +SetBufferBoundingBox -> pcb_set_buffer_bbox +ClearBuffer -> pcb_buffer_clear +pcb_swap_buffer -> pcb_buffer_swap +pcb_buffer_set_bbox -> +AddSelectedToBuffer -> pcb_buffer_add_selected +LoadLayoutToBuffer -> pcb_buffer_load_layout +RotateBuffer -> pcb_buffer_rotate +SelectPasteBuffer -> pcb_buffer_select_paste +MirrorBuffer -> pcb_buffer_mirror +InitBuffers -> pcb_init_buffers +UninitBuffers -> pcb_uninit_buffers +MoveObjectToBuffer -> pcb_move_obj_to_buffer +CopyObjectToBuffer -> pcb_copy_obj_to_buffer +LoadFootprint -> pcb_load_footprint +CreateNewBuffer -> pcb_buffer_new +PASTEBUFFER -> PCB_PASTEBUFFER +QuitApplication -> pcb_quit_app +GetInfoString -> pcb_get_infostr +ChangeLayoutName -> pcb_board_change_name +ChangeLayerName -> pcb_layer_change_name +ChangeSelectedSize -> pcb_chg_selected_size +ChangeSelectedClearSize -> pcb_chg_selected_clear_size +ChangeSelected2ndSize -> pcb_chg_selected_2nd_size +ChangeSelectedMaskSize -> pcb_chg_selected_mask_size +ChangeSelectedJoin -> pcb_chg_selected_join +SetSelectedJoin -> pcb_set_selected_join +ClrSelectedJoin -> pcb_clr_selected_join +ChangeSelectedNonetlist -> pcb_chg_selected_nonetlist +ChangeSelectedSquare -> pcb_chg_selected_square +SetSelectedSquare -> pcb_set_selected_square +ClrSelectedSquare -> pcb_clr_selected_square +ChangeSelectedThermals -> pcb_chg_selected_thermals +ChangeSelectedHole -> pcb_chg_selected_hole +ChangeSelectedPaste -> pcb_chg_selected_paste +ChangeSelectedOctagon -> pcb_chg_selected_octagon +SetSelectedOctagon -> pcb_set_selected_octagon +ClrSelectedOctagon -> pcb_clr_selected_octagon +ChangeObjectSize -> pcb_chg_obj_size +ChangeObject1stSize -> pcb_chg_obj_1st_size +ChangeObjectThermal -> pcb_chg_obj_thermal +ChangeObjectClearSize -> pcb_chg_obj_clear_size +ChangeObject2ndSize -> pcb_chg_obj_2nd_size +ChangeObjectMaskSize -> pcb_chg_obj_mask_size +ChangeObjectJoin -> pcb_chg_obj_join +SetObjectJoin -> pcb_set_obj_join +ClrObjectJoin -> pcb_clr_obj_join +ChangeObjectNonetlist -> pcb_chg_obj_nonetlist +ChangeObjectSquare -> pcb_chg_obj_square +SetObjectSquare -> pcb_set_obj_square +ClrObjectSquare -> pcb_clr_obj_square +ChangeObjectOctagon -> pcb_chg_obj_octagon +SetObjectOctagon -> pcb_set_obj_octagon +ClrObjectOctagon -> pcb_clr_obj_octagon +ChangeObjectName -> pcb_chg_obj_name +QueryInputAndChangeObjectName -> pcb_chg_obj_name_query +ChangeObjectPinnum -> pcb_chg_obj_pinnum +ChangeObjectRadius -> pcb_chg_obj_radius +ChangeObjectAngle -> pcb_chg_obj_angle +ChangeSelectedAngle -> pcb_chg_selected_angle +ChangeSelectedRadius -> pcb_chg_selected_radius +QueryInputAndpcb_chg_obj_name -> pcb_chg_obj_name_query +ChangePCBSize -> pcb_board_resize +ClipLine -> pcb_line_clip +GetWorkingDirectory -> pcb_get_wd +tempfile_name_new -> pcb_tempfile_name_new +tempfile_unlink -> pcb_tempfile_unlink +lrealpath -> pcb_lrealpath +get_user_name -> pcb_get_user_name +CopyPastebufferToLayout -> pcb_buffer_copy_to_layout +CopyObject -> pcb_copy_obj +GridFit -> pcb_grid_fit +notify_crosshair_change -> pcb_notify_crosshair_change +notify_mark_change -> pcb_notify_mark_change +HideCrosshair -> pcb_crosshair_hide +RestoreCrosshair -> pcb_crosshair_restore +DrawAttached -> pcb_draw_attached +DrawMark -> pcb_draw_mark +MoveCrosshairRelative -> pcb_crosshair_move_relative +MoveCrosshairAbsolute -> pcb_crosshair_move_absolute +SetCrosshairRange -> pcb_crosshair_set_range +InitCrosshair -> pcb_crosshair_init +DestroyCrosshair -> pcb_crosshair_uninit +FitCrosshairIntoGrid -> pcb_crosshair_grid_fit +CenterDisplay -> pcb_center_display +FreeDataMemory -> pcb_data_free +IsDataEmpty -> pcb_data_is_empty +GetDataBoundingBox -> pcb_data_bbox +Draw -> pcb_draw +Redraw -> pcb_redraw +DrawObject -> pcb_draw_obj +DrawLayer -> pcb_draw_layer +EraseObject -> pcb_erase_obj +LightenColor -> pcb_lighten_color +Message -> pcb_message +OpenErrorpcb_messag -> pcb_open_error_message +PopenErrorpcb_message -> pcb_popen_error_message +OpendirErrorpcb_message -> pcb_opendir_error_message +ChdirErrorpcb_message -> ocb_chdir_error_message +OpenErrorpcb_message -> pcb_open_error_message +CatchSignal -> pcb_catch_signal +events_init -> pcb_events_init +events_uninit -> pcb_events_uninit +event_bind -> pcb_event_bind +event_unbind -> pcb_event_unbind +event_unbind_cookie -> pcb_event_unbind_cookie +event_unbind_allcookie -> pcb_event_unbind_allcookie +event -> pcb_event +LineLineIntersect -> pcb_intersect_line_line +LineArcIntersect -> pcb_intersect_line_arc +PinLineIntersect -> pcb_intersect_line_pin +LinePadIntersect -> pcb_intersect_line_pad +ArcPadIntersect -> pcb_intersect_arc_pad +IsPolygonInPolygon -> pcb_is_poly_in_poly +LookupElementConnections -> pcb_lookup_element_conns +LookupConnectionsToAllElements -> pcb_lookup_conns_to_all_elements +LookupConnection -> pcb_lookup_conn +LookupConnectionByPin -> pcb_lookup_conn_by_pin +LookupUnusedPins -> pcb_lookup_unused_pins +ResetFoundLinesAndPolygons -> pcb_reset_found_lines_polys +ResetFoundPinsViasAndPads -> pcb_reset_found_pins_vias_pads +ResetConnections -> pcb_reset_conns +InitConnectionLookup -> pcb_conn_lookup_init +InitComponentLookup -> pcb_component_lookup_init +InitLayoutLookup -> pcb_layout_lookup_init +FreeConnectionLookupMemory -> pcb_conn_lookup_uninit +FreeComponentLookupMemory -> pcb_component_lookup_uninit +FreeLayoutLookupMemory -> pcb_layout_lookup_uninit +RatFindHook -> pcb_rat_find_hook +SaveFindFlag -> pcb_save_find_flag +RestoreFindFlag -> pcb_restore_find_flag +DRCAll -> pcb_drc_all +IsLineInPolygon -> pcb_is_line_in_poly +IsArcInPolygon -> pcb_is_arc_in_poly +IsPadInPolygon -> pcb_is_pad_in_poly +ClearFlagOnPinsViasAndPads -> pcb_clear_flag_on_pins_vias_pads +ClearFlagOnLinesAndPolygons -> pcb_clear_flag_on_lines_polys +ClearFlagOnAllObjects -> pcb_clear_flag_on_all_objs +MakeFlags -> pcb_flag_make +OldFlags -> pcb_flag_old +AddFlags -> pcb_flag_add +MaskFlags -> pcb_flag_mask +EraseFlags -> pcb_flag_erase +NoFlags -> pcb_no_flags +mem_any_set -> pcb_mem_any_set +SET_FLAG -> PCB_FLAG_SET +CLEAR_FLAG -> PCB_FLAG_CLEAR +TEST_FLAG -> PCB_FLAG_TEST +TOGGLE_FLAG -> PCB_FLAG_TOGGLE +ASSIGN_FLAG -> PCB_FLAG_ASSIGN +TEST_FLAGS -> PCB_FLAGS_TEST +CHANGE_FLAG -> PCB_FLAG_CHANGE +FLAGS_EQUAL -> PCB_FLAG_EQ +THERMFLAG -> PCB_FLAG_THERM +TEST_THERM -> PCB_FLAG_THERM_TEST +GET_THERM -> PCB_FLAG_THERM_GET +CLEAR_THERM -> PCB_FLAG_THERM_CLEAR +ASSIGN_THERM -> PCB_FLAG_THERM_ASSIGN +GET_SQUARE -> PCB_FLAG_SQUARE_GET +CLEAR_SQUARE -> PCB_FLAG_SQUARE_CLEAR +ASSIGN_SQUARE -> PCB_FLAG_SQUARE_ASSIGN +GET_INTCONN -> PCB_FLAG_INTCONN_GET +TEST_ANY_THERMS -> PCB_FLAG_THERM_TEST_ANY +common_string_to_flags -> pcb_strflg_common_s2f +common_flags_to_string -> pcb_strflg_common_f2s +uninit_strflags_buf -> pcb_strflg_uninit_buf +uninit_strflags_layerlist -> pcb_strflg_uninit_layerlist +pcbflags_to_string -> pcb_strflg_board_f2s +string_to_pcbflags -> pcb_strflg_board_s2f +string_to_flags -> pcb_strflg_s2f +flags_to_string -> pcb_strflg_f2s +CreateDefaultFont -> pcb_font_create_default +SetFontInfo -> pcb_font_set_info +CreateNewLineInSymbol -> pcb_font_new_line_in_sym +leaky_init -> pcb_leaky_init +leaky_uninit -> pcb_leaky_uninit +leaky_malloc -> pcb_leaky_malloc +leaky_calloc -> pcb_leaky_calloc +leaky_realloc -> pcb_leaky_realloc +leaky_strdup -> pcb_leaky_strdup +funchash_get -> pcb_funchash_get +funchash_set -> pcb_funchash_set +funchash_set_table -> pcb_funchash_set_table +funchash_remove_cookie -> pcb_funchash_remove_cookie +funchash_init -> pcb_funchash_init +funchash_uninit -> pcb_funchash_uninit +heap_create -> pcb_heap_create +heap_destroy -> pcb_heap_destroy +heap_free -> pcb_heap_free +heap_insert -> pcb_heap_insert +heap_remove_smallest -> pcb_heap_remove_smallest +heap_replace -> pcb_heap_replace +heap_is_empty -> pcb_heap_is_empty +heap_size -> pcb_heap_size +hid_register_action -> pcb_hid_register_action +hid_register_actions -> pcb_hid_register_actions +REGISTER_ACTIONS -> PCB_REGISTER_ACTIONS +HIDCONCAT -> PCB_HIDCONCAT +hid_expose_callback -> pcb_hid_expose_callback +hid_actions_init -> pcb_hid_actions_init +hid_actions_uninit -> pcb_hid_actions_uninit +REGISTER_ATTRIBUTES -> PCB_REGISTER_ATTRIBUTES +print_actions -> pcb_print_actions +dump_actions -> pcb_dump_actions +hid_find_action -> pcb_hid_find_action +hid_remove_actions -> pcb_hid_remove_actions +hid_remove_action -> pcb_hid_remove_action +hid_remove_actions_by_cookie -> pcb_hid_remove_actions_by_cookie +hid_action -> pcb_hid_action +hid_actionl -> pcb_hid_actionl +hid_actionv -> pcb_hid_actionv +hid_actionv_ -> pcb_hid_actionv_ +hid_parse_command -> pcb_hid_parse_command +hid_parse_actions -> pcb_hid_parse_actions +hid_register_attributes -> pcb_hid_register_attributes +hid_remove_attributes_by_cookie -> pcb_hid_remove_attributes_by_cookie +hid_attributes_uninit -> pcb_hid_attributes_uninit +hid_usage -> pcb_hid_usage +hid_usage_option -> pcb_hid_usage_option +hid_cfg_create_menu -> pcb_hid_cfg_create_menu +hid_cfg_remove_menu -> pcb_hid_cfg_remove_menu +hid_cfg_load -> pcb_hid_cfg_load +hid_cfg_load_lht -> pcb_hid_cfg_load_lht +hid_cfg_load_str -> pcb_hid_cfg_load_str +hid_cfg_get_menu -> pcb_hid_cfg_get_menu +hid_cfg_get_menu_at -> pcb_hid_cfg_get_menu_at +hid_cfg_menu_field_path -> pcb_hid_cfg_menu_field_path +hid_cfg_menu_field_str -> pcb_hid_cfg_menu_field_str +hid_cfg_menu_field -> pcb_hid_cfg_menu_field +hid_cfg_has_submenus -> pcb_hid_cfg_has_submenus +hid_cfg_create_hash_node -> pcb_hid_cfg_create_hash_node +hid_cfg_extend_hash_nodev -> pcb_hid_cfg_extend_hash_nodev +hid_cfg_extend_hash_node -> pcb_hid_cfg_extend_hash_node +hid_cfg_dfs -> pcb_hid_cfg_dfs +hid_cfg_error -> pcb_hid_cfg_error +hid_cfg_action -> pcb_hid_cfg_action +hid_cfg_keys_init -> pcb_hid_cfg_keys_init +hid_cfg_keys_uninit -> pcb_hid_cfg_keys_uninit +hid_cfg_keys_add_under -> pcb_hid_cfg_keys_add_under +hid_cfg_keys_add_by_desc -> pcb_hid_cfg_keys_add_by_desc +hid_cfg_keys_add_by_strdesc -> pcb_hid_cfg_keys_add_by_strdesc +hid_cfg_keys_gen_accel -> pcb_hid_cfg_keys_gen_accel +hid_cfg_keys_input -> pcb_hid_cfg_keys_input +hid_cfg_keys_action -> pcb_hid_cfg_keys_action +hid_cache_color -> pcb_hid_cache_color +common_fill_pcb_polygon -> pcb_dhlp_fill_pcb_polygon +common_thindraw_pcb_polygon -> pcb_dhlp_thindraw_pcb_polygon +common_fill_pcb_pad -> pcb_dhlp_fill_pcb_pad +common_thindraw_pcb_pad -> pcb_dhlp_thindraw_pcb_pad +common_fill_pcb_pv -> pcb_dhlp_fill_pcb_pv +common_thindraw_pcb_pv -> pcb_dhlp_thindraw_pcb_pv +common_draw_helpers_init -> pcb_dhlp_draw_helpers_init +hid_get_extents -> pcb_hid_get_extents +hid_save_and_show_layer_ons -> pcb_hid_save_and_show_layer_ons +hid_restore_layer_ons -> pcb_hid_restore_layer_ons +hid_get_flag -> pcb_hid_get_flag +derive_default_filename -> pcb_derive_default_filename +layer_type_to_file_name -> pcb_layer_type_to_file_name +hid_init -> pcb_hid_init +hid_uninit -> pcb_hid_uninit +hid_find_gui -> pcb_hid_find_gui +hid_find_printer -> pcb_hid_find_printer +hid_find_exporter -> pcb_hid_find_exporter +hid_enumerate -> pcb_hid_enumerate +hid_parse_command_line -> pcb_hid_parse_command_line +hid_register_hid -> pcb_hid_register_hid +hid_remove_hid -> pcb_hid_remove_hid +common_nogui_init -> pcb_hid_nogui_init +hid_nogui_get_hid -> pcb_hid_nogui_get_hid +InsertPointIntoObject -> pcb_insert_point_in_object +AdjustInsertPoint -> pcb_adjust_insert_point +ComputeIntersectionArea -> pcb_intersect_box_box +ComputeUnionArea -> pcb_union_box_box +GetLibraryMenuMemory -> pcb_lib_menu_new +GetLibraryEntryMemory -> pcb_lib_entry_new +FreeLibraryMemory -> pcb_lib_free +DeleteLibraryMenuMemory -> pcb_lib_menu_free +CreateNewNet -> pcb_lib_net_new +CreateNewConnection -> pcb_lib_conn_new +ENTRIES -> PCB_ENTRIES +UNKNOWN -> PCB_UNKNOWN +NSTRCMP -> PCB_NSTRCMP +EMPTY -> PCB_EMPTY +EMPTY_STRING_P -> PCB_EMPTY_STRING_P +XOR -> PCB_XOR +SQUARE -> PCB_SQUARE +OBJECT_ID -> PCB_OBJECT_ID +FRONT -> PCB_FRONT +ON_SIDE -> PCB_ON_SIDE +TO_RADIANS -> PCB_TO_RADIANS +MAKEMIN -> PCB_MAKE_MIN +MAKEMAX -> PCB_MAKE_MAX +SGNZ -> PCB_SGNZ +SWAP_SIGN_X -> PCB_SWAP_SIGN_X +SWAP_SIGN_Y -> PCB_SWAP_SIGN_Y +Distance2 -> pcb_distance2 +Distance -> pcb_distance +GetValue -> pcb_get_value +GetValueEx -> pcb_get_value_ex +GetNum -> pcb_get_num +Concat -> pcb_concat +StripWhiteSpaceAndDup -> pcb_strdup_strip_wspace +MoveLayer -> pcb_layer_move +MOVE -> PCB_MOVE +MoveObject -> pcb_move_obj +MoveObjectToLayer -> pcb_move_obj_to_layer +MoveObjectAndRubberband -> pcb_move_obj_and_rubberband +MoveSelectedObjectsToLayer -> pcb_move_selected_objs_to_layer +GetNetMemory -> pcb_net_new +GetNetListMemory -> pcb_netlist_new +FreeNetListListMemory -> pcb_netlist_list_free +FreeNetListMemory -> pcb_netlist_free +FreeNetMemory -> pcb_net_free +NETLIST_LOOP -> PCB_NETLIST_LOOP +NET_LOOP -> PCB_NET_LOOP +GetArcMemory -> pcb_arc_new +GetElementArcMemory -> pcb_element_arc_new +RemoveFreeArc -> pcb_arc_free +GetElementMemory -> pcb_element_new +RemoveFreeElement -> pcb_element_free +FreeElementMemory -> pcb_element_free_fields +GetElementLineMemory -> pcb_element_line_new +GetLineMemory -> pcb_line_new +RemoveFreeLine -> pcb_line_free +CreateNewLineOnLayer -> pcb_line_new_on_layer +CreateDrawnLineOnLayer -> pcb_line_new_on_layer_merge +GetPadMemory -> pcb_pad_new +RemoveFreePad -> pcb_pad_free +CreateNewPad -> pcb_pad_new_in_element +SetPadBoundingBox -> pcb_pad_bbox +GetViaMemory -> pcb_via_new +RemoveFreeVia -> pcb_via_free +GetPinMemory -> pcb_pin_new +RemoveFreePin -> pcb_pin_free +CreateNewVia -> pcb_via_new_on_board +CreateNewPin -> pcb_pin_new_in_element +SetPinBoundingBox -> pcb_pin_bbox +GetPolygonMemory -> pcb_poly_alloc +RemoveFreePolygon -> pcb_poly_free +GetPointMemoryInPolygon -> pcb_poly_point_alloc +GetHoleIndexMemoryInPolygon -> pcb_poly_holeidx_new +FreePolygonMemory -> pcb_poly_free_fields +SetPolygonBoundingBox -> pcb_poly_bbox +CreateNewPolygonFromRectangle -> pcb_poly_new_from_rectangle +CreateNewPolygon -> pcb_poly_new +CreateNewPointInPolygon -> pcb_poly_point_new +CreateNewHoleInPolygon -> pcb_poly_hole_new +RemovePolygon -> pcb_poly_remove +GetRatMemory -> pcb_rat_alloc +RemoveFreeRat -> pcb_rat_free +CreateNewRat -> pcb_rat_new +DeleteRats -> pcb_rats_delete +GetTextMemory -> pcb_text_alloc +RemoveFreeText -> pcb_text_free +CreateNewText -> pcb_text_new +pcb_arc_new -> pcb_arc_alloc +CreateNewArcOnLayer -> pcb_arc_new +RemoveArc -> pcb_arc_destroy +pcb_element_arc_new -> pcb_element_arc_alloc +pcb_element_new -> pcb_element_alloc +pcb_element_free_fields -> pcb_element_destroy +pcb_line_new -> pcb_line_alloc +pcb_line_new_on_layer_merge -> pcb_line_new_merge +pcb_line_new_on_layer -> pcb_line_new +RemoveLine -> pcb_line_destroy +pcb_pad_new -> pcb_pad_alloc +pcb_pad_new_in_element -> pcb_element_pad_new +pcb_via_new -> pcb_via_alloc +pcb_pin_new -> pcb_pin_alloc +pcb_via_new_on_board -> pcb_via_new +pcb_pin_new_in_element -> pcb_element_pin_new +pcb_rats_delete -> pcb_rats_destroy +RemoveText -> pcb_text_destroy +SetArcBoundingBox -> pcb_arc_bbox +SetElementBoundingBox -> pcb_element_bbox +SetLineBoundingBox -> pcb_line_bbox +SetTextBoundingBox -> pcb_text_bbox +RotateArcLowLevel -> pcb_arc_rotate90 +RotateElementLowLevel -> pcb_element_rotate90 +RotateLineLowLevel -> pcb_line_rotate90 +RotatePolygonLowLevel -> pcb_poly_rotate90 +RotateTextLowLevel -> pcb_text_rotate90 +Freepcb_element_rotate90 -> pcb_element_rotate +Freepcb_element_rotate90 -> pcb_element_rotate +Freepcb_buffer_rotate -> pcb_buffer_free_rotate +GetArcEnds -> pcb_arc_get_ends +ChangeArcAngles -> pcb_arc_set_angles +ChangeArcRadii -> pcb_arc_set_radii +ChangeElementSide -> pcb_element_change_side +ChangeSelectedElementSide -> pcb_selected_element_change_side +ElementOrientation -> pcb_element_get_orientation +ChangePaste -> pcb_pad_change_paste +ChangeHole -> pcb_pin_change_hole +CreateNewElement -> pcb_element_new +CreateNewArcInElement -> pcb_element_arc_new +CreateNewLineInElement -> pcb_element_line_new +RemoveElement -> pcb_element_remove +MoveElementLowLevel -> pcb_element_move +MirrorElementCoordinates -> pcb_element_mirror +MovePolygonLowLevel -> pcb_poly_move +CopyPolygonLowLevel -> pcb_poly_copy +MOVE_TEXT_LOWLEVEL -> pcb_text_move +TEXT_IS_VISIBLE -> pcb_text_is_visible +MOVE_ARC_LOWLEVEL -> pcb_arc_move +MOVE_LINE_LOWLEVEL -> pcb_line_move +MOVE_PAD_LOWLEVEL -> pcb_pad_move +MOVE_PIN_LOWLEVEL -> pcb_pin_move +MOVE_VIA_LOWLEVEL -> pcb_via_move +ALLARC_LOOP -> PCB_ARC_ALL_LOOP +COPPERARC_LOOP -> PCB_ARC_COPPER_LOOP +SILKARC_LOOP -> PCB_ARC_SILK_LOOP +VISIBLEARC_LOOP -> PCB_ARC_VISIBLE_LOOP +ARC_LOOP -> PCB_ARC_LOOP +ELEMENTTEXT_LOOP -> PCB_ELEMENT_TEXT_LOOP +ELEMENTNAME_LOOP -> PCB_ELEMENT_NAME_LOOP +ELEMENTLINE_LOOP -> PCB_ELEMENT_LINE_LOOP +ELEMENTPCB_ARC_LOOP -> PCB_ELEMENT_ARC_LOOP +ELEMENT_LOOP -> PCB_ELEMENT_LOOP +ALLLINE_LOOP -> PCB_LINE_ALL_LOOP +COPPERLINE_LOOP -> PCB_LINE_COPPER_LOOP +SILKLINE_LOOP -> PCB_LINE_SILK_LOOP +VISIBLELINE_LOOP -> PCB_LINE_VISIBLE_LOOP +LINE_LOOP -> PCB_LINE_LOOP +ALLPAD_LOOP -> PCB_PAD_ALL_LOOP +PAD_LOOP -> PCB_PAD_LOOP +ALLPIN_LOOP -> PCB_PIN_ALL_LOOP +VIA_LOOP -> PCB_VIA_LOOP +PIN_LOOP -> PCB_PIN_LOOP +POLYGONPOINT_LOOP -> PCB_POLY_POINT_LOOP +ALLPOLYGON_LOOP -> PCB_POLY_ALL_LOOP +COPPERPOLYGON_LOOP -> PCB_POLY_COPPER_LOOP +SILKPOLYGON_LOOP -> PCB_POLY_SILK_LOOP +VISIBLEPOLYGON_LOOP -> PCB_POLY_VISIBLE_LOOP +POLYGON_LOOP -> PCB_POLY_LOOP +ALLTEXT_LOOP -> PCB_TEXT_ALL_LOOP +VISIBLETEXT_LOOP -> PCB_TEXT_VISIBLE_LOOP +TEXT_LOOP -> PCB_TEXT_LOOP +LoadElementToBuffer -> pcb_element_load_to_buffer +LoadFootprintByName -> pcb_element_load_footprint_by_name +SmashBufferElement -> pcb_element_smash_buffer +ConvertBufferToElement -> pcb_element_convert_from_buffer +CopyElementLowLevel -> pcb_element_copy +UniqueElementName -> pcb_element_uniq_name +AddTextToElement -> pcb_element_text_set +ChangeElementText -> pcb_element_text_change +resolve_path -> pcb_path_resolve +resolve_path_inplace -> pcb_path_resolve_inplace +resolve_paths -> pcb_paths_resolve +resolve_all_paths -> pcb_paths_resolve_all +fp_fopen -> pcb_fp_fopen +fp_fclose -> pcb_fp_fclose +fp_dupname -> pcb_fp_dupname +fp_tagname -> pcb_fp_tagname +fp_uninit -> pcb_fp_uninit +fp_tag -> pcb_fp_tag +fp_init -> pcb_fp_init +get_library_memory -> pcb_get_library_memory +fp_free_children -> pcb_fp_free_children +fp_sort_children -> pcb_fp_sort_children +fp_rmdir -> pcb_fp_rmdir +fp_mkdir_p -> pcb_fp_mkdir_p +fp_mkdir_len -> pcb_fp_mkdir_len +fp_lib_search -> pcb_fp_lib_search +fp_append_entry -> pcb_fp_append_entry +fp_read_lib_all -> pcb_fp_read_lib_all +fp_default_search_path -> pcb_fp_default_search_path +fp_host_uninit -> pcb_fp_host_uninit +fp_rehash -> pcb_fp_rehash +ImportNetlist -> pcb_import_netlist +ParsePCB -> pcb_parse_pcb +ParseElement -> pcb_parse_element +ParseFont -> pcb_parse_font +WriteBuffer -> pcb_write_buffer +WriteElementData -> pcb_write_element_data +CheckAndOpenFile -> pcb_check_and_open_file +OpenConnectionDataFile -> pcb_open_connection_file +SavePCB -> pcb_save_pcb +LoadPCB -> pcb_load_pcb +EnableAutosave -> pcb_enable_autosave +Backup -> pcb_backup +SaveInTMP -> pcb_save_in_tmp +EmergencySave -> pcb_emergency_save +DisableEmergencySave -> pcb_disable_emergency_save +RevertPCB -> pcb_revert_pcb +SaveBufferElements -> pcb_save_buffer_elements +PrintQuotedString -> pcb_print_quoted_string +sort_library -> pcb_library_sort +set_some_route_style -> pcb_set_some_route_style +WritePCBFile -> pcb_write_pcb_file +WritePipe -> pcb_write_pipe +SaveTMPData -> pcb_tmp_data_save +RemoveTMPData -> pcb_tmp_data_remove +plugins_init -> pcb_plugins_init +plugins_uninit -> pcb_plugins_uninit +plugin_register -> pcb_plugin_register +HOOK_CALL_DO -> PCB_HOOK_CALL_DO +HOOK_CALL_ALL -> PCB_HOOK_CALL_ALL +HOOK_UNREGISTER -> PCB_HOOK_UNREGISTER +HOOK_CALL -> PCB_HOOK_CALL +HOOK_REGISTER -> PCB_HOOK_REGISTER +poly_NewContour -> pcb_poly_contour_new +poly_IniContour -> pcb_poly_contour_init +poly_ClrContour -> pcb_poly_contour_clear +poly_DelContour -> pcb_poly_contour_del +poly_CopyContour -> pcb_poly_contour_copy +poly_PreContour -> pcb_poly_contour_pre +poly_InvContour -> pcb_poly_contour_inv +poly_CreateNode -> pcb_poly_node_create +poly_InclVertex -> pcb_poly_vertex_include +poly_ExclVertex -> pcb_poly_vertex_exclude +poly_M_Copy0 -> pcb_poly_m_copy0 +poly_M_Incl -> pcb_poly_m_include +poly_Copy0 -> pcb_poly_copy0 +poly_Copy1 -> pcb_poly_copy1 +poly_InclContour -> pcb_poly_contour_include +poly_ExclContour -> pcb_poly_contour_exclide +poly_ChkContour -> pcb_poly_contour_check +poly_CheckInside -> pcb_poly_contour_inside +Touching -> pcb_poly_touching +pcb_poly_m_copy0 -> pcb_polyarea_m_copy0 +pcb_poly_m_include -> pcb_polyarea_m_include +pcb_poly_copy0 -> pcb_polyarea_copy0 +pcb_poly_copy1 -> pcb_polyarea_copy1 +pcb_poly_contour_include -> pcb_polyarea_contour_include +pcb_poly_contour_exclide -> pcb_polyarea_contour_exclide +pcb_poly_contour_check -> pcb_polyarea_contour_check +pcb_poly_contour_inside -> pcb_polyarea_contour_inside +pcb_poly_touching -> pcb_polyarea_touching +poly_InsideContour -> pcb_poly_contour_inside +poly_ContourInContour -> pcb_poly_contour_in_contour +poly_Create -> pcb_polyarea_create +poly_Free -> pcb_polyarea_free +poly_Init -> pcb_polyarea_init +poly_FreeContours -> pcb_poly_contours_free +poly_Valid -> pcb_poly_valid +vect_dist2 -> pcb_vect_dist2 +vect_det2 -> pcb_vect_det2 +vect_len2 -> pcb_vect_len2 +vect_inters2 -> pcb_vect_inters2 +poly_Boolean -> pcb_polyarea_boolean +poly_Boolean_free -> pcb_polyarea_boolean_free +poly_AndSubtract_free -> pcb_polyarea_and_subtract_free +poly_bbox -> pcb_polyarea_bbox +Savepcb_polyarea_t -> pcb_polyarea_save +polygon_init -> pcb_polygon_init +polygon_point_idx -> pcb_poly_point_idx +polygon_point_contour -> pcb_poly_contour_point +prev_contour_point -> pcb_poly_contour_prev_point +next_contour_point -> pcb_poly_contour_next_point +GetLowestDistancePolygonPoint -> pcb_poly_get_lowest_distance_point +RemoveExcessPolygonPoints -> pcb_poly_remove_excess_points +GoToPreviousPoint -> pcb_polygon_go_to_prev_point +ClosePolygon -> pcb_polygon_close_poly +CopyAttachedPolygonToLayer -> pcb_polygon_copy_attached_to_layer +PolygonHoles -> pcb_poly_holes +PlowsPolygon -> pcb_poly_plows +ComputeNoHoles -> pcb_poly_compute_no_holes +ContourToPoly -> pcb_poly_from_contour +PolygonToPoly -> pcb_poly_from_poly +RectPoly -> pcb_poly_from_rect +CirclePoly -> pcb_poly_from_circle +OctagonPoly -> pcb_poly_from_octagon +LinePoly -> pcb_poly_from_line +ArcPoly -> pcb_poly_from_arc +PinPoly -> pcb_poly_from_pin +BoxPolyBloated -> pcb_poly_from_box_bloated +ContourToPoly -> pcb_poly_from_contour +PolygonToPoly -> pcb_poly_from_poly +RectPoly -> pcb_poly_from_rect +CirclePoly -> pcb_poly_from_circle +OctagonPoly -> pcb_poly_from_octagon +LinePoly -> pcb_poly_from_line +ArcPoly -> pcb_poly_from_arc +PinPoly -> pcb_poly_from_pin +BoxPolyBloated -> pcb_poly_from_box_bloated +frac_circle -> pcb_poly_frac_circle +InitClip -> pcb_poly_init_clip +RestoreToPolygon -> pcb_poly_restore_to_poly +ClearFromPolygon -> pcb_poly_clear_from_poly +IsPointInPolygon -> pcb_poly_is_point_in_p +IsPointInPolygonIgnoreHoles -> pcb_poly_is_point_in_p_ignore_holes +IsRectangleInPolygon -> pcb_poly_is_rect_in_p +isects -> pcb_poly_isects_poly +MorphPolygon -> pcb_poly_morph +NoHolesPolygonDicer -> pcb_poly_no_holes_dicer +PolyToPolygonsOnLayer -> pcb_poly_to_polygons_on_layer +square_pin_factors -> pcb_poly_square_pin_factors +AddNet -> pcb_rat_add_net +ConnectionName -> pcb_connection_name +AddAllRats -> pcb_rat_add_all +SeekPad -> pcb_rat_seek_pad +ProcNetlist -> pcb_rat_proc_netlist +CollectSubnets -> pcb_rat_collect_subnets +GetConnectionMemory -> pcb_rat_connection_alloc +CONNECTION_LOOP -> PCB_CONNECTION_LOOP +RAT_LOOP -> PCB_RAT_LOOP +rats_patch_append -> pcb_ratspatch_append +rats_patch_destroy -> pcb_ratspatch_destroy +rats_patch_append_optimize -> pcb_ratspatch_append_optimize +rats_patch_make_edited -> pcb_ratspatch_make_edited +rats_patch_apply -> pcb_ratspatch_apply +rats_patch_fexport -> pcb_ratspatch_fexport +RemovePCB -> pcb_board_remove +RemoveSelected -> pcb_remove_selected +RemoveObject -> pcb_remove_object +DestroyObject -> pcb_destroy_object +ROTATE -> PCB_ROTATE90 +PIN_ROTATE -> PCB_PIN_ROTATE_SHAPE +ROTATE_VIA_LOWLEVEL -> PCB_VIA_ROTATE90 +ROTATE_PIN_LOWLEVEL -> PCB_PIN_ROTATE90 +ROTATE_PAD_LOWLEVEL -> PCB_PAD_ROTATE90 +RotateBoxLowLevel -> pcb_box_rotate90 +RotateObject -> pcb_obj_rotate90 +RotateScreenObject -> pcb_screen_obj_rotate90 +RotatePointLowLevel -> pcb_point_rotate90 +free_rotate -> pcb_rotate +PCB_ROTATE90 -> PCB_COORD_ROTATE90 +ParseRoutingString1 -> pcb_route_string_parse1 +ParseRouteString -> pcb_route_string_parse +make_route_string -> pcb_route_string_make +r_create_tree -> pcb_r_create_tree +r_destroy_tree -> pcb_r_destroy_tree +r_delete_entry -> pcb_r_delete_entry +r_insert_entry -> pcb_r_insert_entry +r_search -> pcb_r_search +r_region_is_empty -> pcb_r_region_is_empty +__r_dump_tree -> pcb_r_dump_tree +LookupRubberbandLines -> pcb_rubber_band_lookup_lines +LookupRatLines -> pcb_rubber_band_lookup_rat_lines +GetRubberbandMemory -> pcb_rubber_band_alloc +CreateNewRubberbandEntry -> pcb_rubber_band_create +IsPointOnLine -> pcb_is_point_on_line +IsPointOnPin -> pcb_is_point_in_pin +IsPointOnArc -> pcb_is_point_on_arc +IsPointOnLineEnd -> pcb_is_point_on_line_end +IsLineInRectangle -> pcb_is_line_in_rectangle +IsLineInQuadrangle -> pcb_is_line_in_quadrangle +IsArcInRectangle -> pcb_is_arc_in_rectangle +IsPointInPad -> pcb_is_point_in_pad +IsPointInBox -> pcb_is_point_in_box +lines_intersect -> pcb_lines_intersect +POINT_IN_BOX -> PCB_POINT_IN_BOX +VIA_OR_PIN_IN_BOX -> PCB_VIA_OR_PIN_IN_BOX +LINE_IN_BOX -> PCB_LINE_IN_BOX +PAD_IN_BOX -> PCB_PAD_IN_BOX +BOX_IN_BOX -> PCB_BOX_IN_BOX +TEXT_IN_BOX -> PCB_TEXT_IN_BOX +POLYGON_IN_BOX -> PCB_POLYGON_IN_BOX +ELEMENT_IN_BOX -> PCB_ELEMENT_IN_BOX +ARC_IN_BOX -> PCB_ARC_IN_BOX +POINT_IN_CIRCLE -> PCB_POINT_IN_CIRCLE +CIRCLE_TOUCHES_BOX -> PCB_CIRCLE_TOUCHES_BOX +VIA_OR_PIN_TOUCHES_BOX -> PCB_VIA_OR_PIN_TOUCHES_BOX +LINE_TOUCHES_BOX -> PCB_LINE_TOUCHES_BOX +PAD_TOUCHES_BOX -> PCB_PAD_TOUCHES_BOX +BOX_TOUCHES_BOX -> PCB_BOX_TOUCHES_BOX +TEXT_TOUCHES_BOX -> PCB_TEXT_TOUCHES_BOX +POLYGON_TOUCHES_BOX -> PCB_POLYGON_TOUCHES_BOX +ELEMENT_TOUCHES_BOX -> PCB_ELEMENT_TOUCHES_BOX +ARC_TOUCHES_BOX -> PCB_ARC_TOUCHES_BOX +IS_BOX_NEGATIVE -> PCB_IS_BOX_NEGATIVE +BOX_NEAR_BOX -> PCB_BOX_NEAR_BOX +VIA_OR_PIN_NEAR_BOX -> PCB_VIA_OR_PIN_NEAR_BOX +LINE_NEAR_BOX -> PCB_LINE_NEAR_BOX +PAD_NEAR_BOX -> PCB_PAD_NEAR_BOX +TEXT_NEAR_BOX -> PCB_TEXT_NEAR_BOX +POLYGON_NEAR_BOX -> PCB_POLYGON_NEAR_BOX +ELEMENT_NEAR_BOX -> PCB_ELEMENT_NEAR_BOX +ARC_NEAR_BOX -> PCB_ARC_NEAR_BOX +SearchObjectByLocation -> pcb_search_obj_by_location +SearchScreen -> pcb_search_screen +SearchScreenGridSlop -> pcb_search_grid_slop +SearchObjectByID -> pcb_search_obj_by_id +SearchElementByName -> pcb_search_elem_by_name +SelectObject -> pcb_select_object +SelectBlock -> pcb_select_block +ListBlock -> pcb_list_block +ObjectOperation -> pcb_object_operation +SelectedOperation -> pcb_selected_operation +SelectConnection -> pcb_select_connection +SelectObjectByName -> pcb_select_object_by_name +SetTextScale -> pcb_text_set_scale +SetGrid -> pcb_board_set_grid +SetLineSize -> pcb_line_set_size +SetViaSize -> pcb_via_set_size +SetViaDrillingHole -> pcb_via_set_drilling_hole +SetClearanceWidth -> pcb_conf_set_clearance_width +SetChangedFlag -> pcb_board_set_changed_flag +SetBufferNumber -> pcb_buffer_set_number +SetMode -> pcb_crosshair_set_mode +SetCrosshairRangeToBuffer -> pcb_crosshair_range_to_buffer +SetLocalRef -> pcb_crosshair_set_local_ref +SaveMode -> pcb_crosshair_save_mode +RestoreMode -> pcb_crosshair_restore_mode +pcb_text_set_scale -> pcb_board_set_text_scale +pcb_line_set_size -> pcb_board_set_line_width +pcb_via_set_size -> pcb_board_set_via_size +pcb_via_set_drilling_hole -> pcb_board_set_via_drilling_hole +pcb_conf_set_clearance_width -> pcb_board_set_clearance +stub_DrawFab_overhang -> pcb_stub_draw_fab_overhang +stub_DrawFab -> pcb_stub_draw_fab +stub_rat_found_short -> pcb_stub_rat_found_short +stub_rat_proc_shorts -> pcb_stub_rat_proc_shorts +Undo -> pcb_undo +Redo -> pcb_redo +IncrementUndoSerialNumber -> pcb_undo_inc_serial +SaveUndoSerialNumber -> pcb_undo_save_serial +RestoreUndoSerialNumber -> pcb_undo_restore_serial +ClearUndoList -> pcb_undo_clear_list +LockUndo -> pcb_undo_lock +UnlockUndo -> pcb_undo_unlock +Undoing -> pcb_undoing +MoveObjectToRemoveUndoList -> pcb_undo_move_obj_to_remove +AddObjectToRemovePointUndoList -> pcb_undo_add_obj_to_remove_point +AddObjectToInsertPointUndoList -> pcb_undo_add_obj_to_insert_point +AddObjectToRemoveContourUndoList -> pcb_undo_add_obj_to_remove_contour +AddObjectToInsertContourUndoList -> pcb_undo_add_obj_to_insert_contour +AddObjectToMoveUndoList -> pcb_undo_add_obj_to_move +AddObjectToChangeNameUndoList -> pcb_undo_add_obj_to_change_name +AddObjectToChangePinnumUndoList -> pcb_undo_add_obj_to_change_pinnum +AddObjectToRotateUndoList -> pcb_undo_add_obj_to_rotate +AddObjectToCreateUndoList -> pcb_undo_add_obj_to_create +AddObjectToMirrorUndoList -> pcb_undo_add_obj_to_mirror +AddObjectToMoveToLayerUndoList -> pcb_undo_add_obj_to_move_to_layer +AddObjectToFlagUndoList -> pcb_undo_add_obj_to_flag +AddObjectToSizeUndoList -> pcb_undo_add_obj_to_size +AddObjectTo2ndSizeUndoList -> pcb_undo_add_obj_to_2nd_size +AddObjectToClearSizeUndoList -> pcb_undo_add_obj_to_clear_size +AddObjectToMaskSizeUndoList -> pcb_undo_add_obj_to_mask_size +AddObjectToChangeAnglesUndoList -> pcb_undo_add_obj_to_change_angles +AddObjectToChangeRadiiUndoList -> pcb_undo_add_obj_to_change_radii +AddObjectToClearPolyUndoList -> pcb_undo_add_obj_to_clear_poly +AddLayerChangeToUndoList -> pcb_undo_add_layer_change +AddNetlistLibToUndoList -> pcb_undo_add_netlist_lib +get_n_units -> pcb_get_n_units +coord_to_unit -> pcb_coord_to_unit +unit_to_factor -> pcb_unit_to_factor +unit_to_coord -> pcb_unit_to_coord +get_increments_struct -> pcb_get_increments_struct +NormalizeAngle -> pcb_normalize_angle +initialize_units -> pcb_units_init +UNDO_CHANGENAME -> PCB_UNDO_CHANGENAME +UNDO_MOVE -> PCB_UNDO_MOVE +UNDO_REMOVE -> PCB_UNDO_REMOVE +UNDO_REMOVE_POINT -> PCB_UNDO_REMOVE_POINT +UNDO_INSERT_POINT -> PCB_UNDO_INSERT_POINT +UNDO_REMOVE_CONTOUR -> PCB_UNDO_REMOVE_CONTOUR +UNDO_INSERT_CONTOUR -> PCB_UNDO_INSERT_CONTOUR +UNDO_ROTATE -> PCB_UNDO_ROTATE +UNDO_CREATE -> PCB_UNDO_CREATE +UNDO_MOVETOLAYER -> PCB_UNDO_MOVETOLAYER +UNDO_FLAG -> PCB_UNDO_FLAG +UNDO_CHANGESIZE -> PCB_UNDO_CHANGESIZE +UNDO_CHANGE2NDSIZE -> PCB_UNDO_CHANGE2NDSIZE +UNDO_MIRROR -> PCB_UNDO_MIRROR +UNDO_CHANGECLEARSIZE -> PCB_UNDO_CHANGECLEARSIZE +UNDO_CHANGEMASKSIZE -> PCB_UNDO_CHANGEMASKSIZE +UNDO_CHANGEANGLES -> PCB_UNDO_CHANGEANGLES +UNDO_LAYERCHANGE -> PCB_UNDO_LAYERCHANGE +UNDO_CLEAR -> PCB_UNDO_CLEAR +UNDO_NETLISTCHANGE -> PCB_UNDO_NETLISTCHANGE +UNDO_CHANGEPINNUM -> PCB_UNDO_CHANGEPINNUM +UNDO_CHANGERADII -> PCB_UNDO_CHANGERADII +ROTATE_TYPES -> PCB_ROTATE_TYPES +CHANGENAME_TYPES -> PCB_CHANGENAME_TYPES +CHANGESIZE_TYPES -> PCB_CHANGESIZE_TYPES +CHANGE2NDSIZE_TYPES -> PCB_CHANGE2NDSIZE_TYPES +CHANGECLEARSIZE_TYPES -> PCB_CHANGECLEARSIZE_TYPES +CHANGENONETLIST_TYPES -> PCB_CHANGENONETLIST_TYPES +CHANGESQUARE_TYPES -> PCB_CHANGESQUARE_TYPES +CHANGEOCTAGON_TYPES -> PCB_CHANGEOCTAGON_TYPES +CHANGEJOIN_TYPES -> PCB_CHANGEJOIN_TYPES +CHANGETHERMAL_TYPES -> PCB_CHANGETHERMAL_TYPES +CHANGEMASKSIZE_TYPES -> PCB_CHANGEMASKSIZE_TYPES +SELECT_TYPES -> PCB_SELECT_TYPES +MOVE_TYPES -> PCB_MOVE_TYPES +MOVETOLAYER_TYPES -> PCB_MOVETOLAYER_TYPES +INSERT_TYPES -> PCB_INSERT_TYPES +COPY_TYPES -> PCB_COPY_TYPES +REMOVE_TYPES -> PCB_REMOVE_TYPES +NETLIST_INPUT -> PCB_NETLIST_INPUT +NETLIST_EDITED -> PCB_NETLIST_EDITED +NUM_NETLISTS -> PCB_NUM_NETLISTS +ATTRIBUTE_UNUSED -> PCB_ATTRIBUTE_UNUSED +UNLIKELY -> PCB_UNLIKELY +LIKELY -> PCB_LIKELY +STATE_FIRST -> PCB_CH_STATE_FIRST +STATE_SECOND -> PCB_CH_STATE_SECOND +STATE_THIRD -> PCB_CH_STATE_THIRD +Basic_Crosshair_Shape -> pcb_ch_shape_basic +Union_Jack_Crosshair_Shape -> pcb_ch_shape_union_jack +Dozen_Crosshair_Shape -> pcb_ch_shape_dozen +Crosshair_Shapes_Number -> pcb_ch_shape_NUM +Crosshair -> pcb_crosshair +Marked -> pcb_marked +max_group -> pcb_max_group +max_copper_layer -> pcb_max_copper_layer +solder_silk_layer -> pcb_solder_silk_layer +component_silk_layer -> pcb_component_silk_layer +Buffers -> pcb_buffers +addedLines -> pcb_added_lines +LayerStack -> pcb_layer_stack +Bumped -> pcb_bumped +STATUS_OK -> 0 +STATUS_ERROR -> -1 +EVENT_GUI_INIT -> PCB_EVENT_GUI_INIT +EVENT_CLI_ENTER -> PCB_EVENT_CLI_ENTER +EVENT_SAVE_PRE -> PCB_EVENT_SAVE_PRE +EVENT_SAVE_POST -> PCB_EVENT_SAVE_POST +EVENT_LOAD_PRE -> PCB_EVENT_LOAD_PRE +EVENT_LOAD_POST -> PCB_EVENT_LOAD_POST +EVENT_last -> PCB_EVENT_last +ARG_INT -> PCB_EVARG_INT +ARG_DOUBLE -> PCB_EVARG_DOUBLE +ARG_STR -> PCB_EVARG_STR +LOOKUP_FIRST -> PCB_LOOKUP_FIRST +LOOKUP_MORE -> PCB_LOOKUP_MORE +SILK_TYPE -> PCB_SILK_TYPE +FCT_COPPER -> PCB_FCT_COPPER +FCT_INTERNAL -> PCB_FCT_INTERNAL +FCT_RAT -> PCB_FCT_RAT +FCT_ELEMENT -> PCB_FCT_ELEMENT +FCT_START -> PCB_FCT_START +find_callback_t -> pcb_find_callback_t +find_callback -> pcb_find_callback +SHOWNUMBERFLAG -> PCB_SHOWNUMBERFLAG +LOCALREFFLAG -> PCB_LOCALREFFLAG +CHECKPLANESFLAG -> PCB_CHECKPLANESFLAG +SHOWPCB_FLAG_DRC -> PCB_SHOWPCB_FLAG_DRC +RUBBERBANDFLAG -> PCB_RUBBERBANDFLAG +DESCRIPTIONFLAG -> PCB_DESCRIPTIONFLAG +NAMEONPCBFLAG -> PCB_NAMEONPCBFLAG +AUTOPCB_FLAG_DRC -> PCB_AUTOPCB_FLAG_DRC +ALLDIRECTIONFLAG -> PCB_ALLDIRECTIONFLAG +SWAPSTARTDIRFLAG -> PCB_SWAPSTARTDIRFLAG +UNIQUENAMEFLAG -> PCB_UNIQUENAMEFLAG +CLEARNEWFLAG -> PCB_CLEARNEWFLAG +SNAPPCB_FLAG_PIN -> PCB_SNAPPCB_FLAG_PIN +SHOWMASKFLAG -> PCB_SHOWMASKFLAG +THINDRAWFLAG -> PCB_THINDRAWFLAG +ORTHOMOVEFLAG -> PCB_ORTHOMOVEFLAG +LIVEROUTEFLAG -> PCB_LIVEROUTEFLAG +THINDRAWPOLYFLAG -> PCB_THINDRAWPOLYFLAG +LOCKNAMESFLAG -> PCB_LOCKNAMESFLAG +ONLYNAMESFLAG -> PCB_ONLYNAMESFLAG +NEWPCB_FLAG_FULLPOLY -> PCB_NEWPCB_FLAG_FULLPOLY +HIDENAMESFLAG -> PCB_HIDENAMESFLAG +ENABLEPCB_FLAG_MINCUT -> PCB_ENABLEPCB_FLAG_MINCUT +GROUNDPLANEFRAME -> PCB_GROUNDPLANEFRAME +MASKFRAME -> PCB_MASKFRAME +LARGE_VALUE -> PCB_LARGE_VALUE +MAX_LAYER -> PCB_MAX_LAYER +MIN_LINESIZE -> PCB_MIN_LINESIZE +MAX_LINESIZE -> PCB_MAX_LINESIZE +MIN_ARCSIZE -> PCB_MIN_ARCSIZE +MAX_ARCSIZE -> PCB_MAX_ARCSIZE +MIN_TEXTSCALE -> PCB_MIN_TEXTSCALE +MAX_TEXTSCALE -> PCB_MAX_TEXTSCALE +MIN_PINORVIASIZE -> PCB_MIN_PINORVIASIZE +MIN_PINORVIAHOLE -> PCB_MIN_PINORVIAHOLE +MAX_PINORVIASIZE -> PCB_MAX_PINORVIASIZE +MIN_PINORVIACOPPER -> PCB_MIN_PINORVIACOPPER +MIN_PADSIZE -> PCB_MIN_PADSIZE +MAX_PADSIZE -> PCB_MAX_PADSIZE +MIN_DRC_VALUE -> PCB_MIN_DRC_VALUE +MAX_DRC_VALUE -> PCB_MAX_DRC_VALUE +MIN_DRC_SILK -> PCB_MIN_DRC_SILK +MAX_DRC_SILK -> PCB_MAX_DRC_SILK +MIN_DRC_DRILL -> PCB_MIN_DRC_DRILL +MAX_DRC_DRILL -> PCB_MAX_DRC_DRILL +MIN_DRC_RING -> PCB_MIN_DRC_RING +MAX_DRC_RING -> PCB_MAX_DRC_RING +MIN_GRID -> PCB_MIN_GRID +MAX_GRID -> PCB_MAX_GRID +MAX_FONTPOSITION -> PCB_MAX_FONTPOSITION +MAX_COORD -> PCB_MAX_COORD +MIN_SIZE -> PCB_MIN_SIZE +MAX_SIZE -> PCB_MAX_SIZE +MAX_BUFFER -> PCB_MAX_BUFFER +DEFAULT_DRILLINGHOLE -> PCB_DEFAULT_DRILLINGHOLE +MAXPATHLEN -> PCB_PATH_MAX +MAX_LINE_POINT_DISTANCE -> PCB_MAX_LINE_POINT_DISTANCE +MAX_POLYGON_POINT_DISTANCE -> PCB_MAX_POLYGON_POINT_DISTANCE +MAX_ELEMENTNAMES -> PCB_MAX_ELEMENTNAMES +MAX_NETLIST_LINE_LENGTH -> PCB_MAX_NETLIST_LINE_LENGTH +MAX_MODESTACK_DEPTH -> PCB_MAX_MODESTACK_DEPTH +MIN_GRID_DISTANCE -> PCB_MIN_GRID_DISTANCE +EMARK_SIZE -> PCB_EMARK_SIZE +FONT_CAPHEIGHT -> PCB_FONT_CAPHEIGHT +DEFAULT_CELLSIZE -> PCB_DEFAULT_CELLSIZE +next_gui -> pcb_next_gui +current_action -> pcb_current_action +pixel_slop -> pcb_pixel_slop +MF_ACCELERATOR -> PCB_MF_ACCELERATOR +MF_MNEMONIC -> PCB_MF_MNEMONIC +MF_SUBMENU -> PCB_MF_SUBMENU +MF_CHECKED -> PCB_MF_CHECKED +MF_UPDATE_ON -> PCB_MF_UPDATE_ON +MF_SENSITIVE -> PCB_MF_SENSITIVE +MF_TIP -> PCB_MF_TIP +MF_ACTIVE -> PCB_MF_ACTIVE +MF_ACTION -> PCB_MF_ACTION +MF_FOREGROUND -> PCB_MF_FOREGROUND +MF_BACKGROUND -> PCB_MF_BACKGROUND +MF_FONT -> PCB_MF_FONT +M_Shift -> PCB_M_Shift +M_Ctrl -> PCB_M_Ctrl +M_Alt -> PCB_M_Alt +M_Mod1 -> PCB_M_Mod1 +M_Release -> PCB_M_Release +MB_LEFT -> PCB_MB_LEFT +MB_MIDDLE -> PCB_MB_MIDDLE +MB_RIGHT -> PCB_MB_RIGHT +MB_SCROLL_UP -> PCB_MB_SCROLL_UP +MB_SCROLL_DOWN -> PCB_MB_SCROLL_DOWN +MB_SCROLL_LEFT -> PCB_MB_SCROLL_LEFT +MB_SCROLL_RIGHT -> PCB_MB_SCROLL_RIGHT +MB_ANY -> PCB_MB_ANY +M_ANY -> PCB_M_ANY +hid_list -> pcb_hid_list +hid_num_hids -> pcb_hid_num_hids +MENU_LOOP -> PCB_MENU_LOOP +ENTRY_LOOP -> PCB_ENTRY_LOOP +SWAP_IDENT -> PCB_SWAP_IDENT +END_LOOP -> PCB_END_LOOP +ENDALL_LOOP -> PCB_ENDALL_LOOP +pcb_create_be_lenient -> pcb_create_being_lenient +CreateBeLenient -> pcb_create_be_lenient +CreateIDBump -> pcb_create_ID_bump +CreateIDReset -> pcb_create_ID_reset +CreateIDGet -> pcb_create_ID_get +DESCRIPTION_INDEX -> PCB_ELEMNAME_IDX_DESCRIPTION +NAMEONPCB_INDEX -> PCB_ELEMNAME_IDX_REFDES +VALUE_INDEX -> PCB_ELEMNAME_IDX_VALUE +NAME_INDEX -> PCB_ELEMNAME_IDX_VISIBLE +ELEMENT_NAME -> PCB_ELEM_NAME_VISIBLE +DESCRIPTION_NAME -> PCB_ELEM_NAME_DESCRIPTION +NAMEONPCB_NAME -> PCB_ELEM_NAME_REFDES +VALUE_NAME -> PCB_ELEM_NAME_VALUE +ELEMENT_TEXT -> PCB_ELEM_TEXT_VISIBLE +DESCRIPTION_TEXT -> PCB_ELEM_TEXT_DESCRIPTION +NAMEONPCB_TEXT -> PCB_ELEM_TEXT_REFDES +VALUE_TEXT -> PCB_ELEM_TEXT_VALUE +AdjustAttachedLine -> pcb_line_adjust_attached +AdjustTwoLine -> pcb_line_adjust_attached_2lines +FortyFiveLine -> pcb_line_45 +EnforceLineDRC -> pcb_line_enforce_drc +library -> pcb_library +gui -> pcb_gui +exporter -> pcb_exporter +plug_fp_chain -> pcb_plug_fp_chain +plug_import_chain -> pcb_plug_import_chain +plug_io_chain -> pcb_plug_io_chain +PLF_DIR -> PCB_PLF_DIR +PLF_INV -> PCB_PLF_INV +PLF_MARK -> PCB_PLF_MARK +VertexEqu -> pcb_vertex_equ +VertexCpy -> pcb_vertex_cpy +err_no_memory -> pcb_err_no_memory +err_bad_parm -> pcb_err_bad_parm +err_ok -> pcb_err_ok +PBO_UNITE -> PCB_PBO_UNITE +PBO_ISECT -> PCB_PBO_ISECT +PBO_SUB -> PCB_PBO_SUB +PBO_XOR -> PCB_PBO_XOR +POLY_CIRC_SEGS -> PCB_POLY_CIRC_SEGS +POLY_CIRC_SEGS_F -> PCB_POLY_CIRC_SEGS_F +POLY_CIRC_RADIUS_ADJ -> PCB_POLY_CIRC_RADIUS_ADJ +POLY_ARC_MAX_DEVIATION -> PCB_POLY_ARC_MAX_DEVIATION +R_DIR_NOT_FOUND -> PCB_R_DIR_NOT_FOUND +R_DIR_FOUND_CONTINUE -> PCB_R_DIR_FOUND_CONTINUE +R_DIR_CANCEL -> PCB_R_DIR_CANCEL +SLOP -> PCB_SLOP +SM_REGEX -> PCB_SM_REGEX +SM_LIST -> PCB_SM_LIST +SWAP_ANGLE -> PCB_SWAP_ANGLE +SWAP_DELTA -> PCB_SWAP_DELTA +METRIC -> PCB_UNIT_METRIC +IMPERIAL -> PCB_UNIT_IMPERIAL +NO_SUFFIX -> PCB_UNIT_NO_SUFFIX +SUFFIX -> PCB_UNIT_SUFFIX +FILE_MODE -> PCB_UNIT_FILE_MODE +NO_PRINT -> PCB_UNIT_NO_PRINT +ALLOW_NM -> PCB_UNIT_ALLOW_NM +ALLOW_UM -> PCB_UNIT_ALLOW_UM +ALLOW_MM -> PCB_UNIT_ALLOW_MM +ALLOW_CM -> PCB_UNIT_ALLOW_CM +ALLOW_M -> PCB_UNIT_ALLOW_M +ALLOW_KM -> PCB_UNIT_ALLOW_KM +ALLOW_CMIL -> PCB_UNIT_ALLOW_CMIL +ALLOW_MIL -> PCB_UNIT_ALLOW_MIL +ALLOW_IN -> PCB_UNIT_ALLOW_IN +ALLOW_DMIL -> PCB_UNIT_ALLOW_DMIL +ALLOW_METRIC -> PCB_UNIT_ALLOW_METRIC +ALLOW_IMPERIAL -> PCB_UNIT_ALLOW_IMPERIAL +ALLOW_READABLE -> PCB_UNIT_ALLOW_READABLE +ALLOW_NATURAL -> PCB_UNIT_ALLOW_NATURAL +ALLOW_ALL -> PCB_UNIT_ALLOW_ALL +ActionExecuteFile -> pcb_act_ExecuteFile +executefile_help -> pcb_acth_ExecuteFile +executefile_syntax -> pcb_acts_ExecuteFile +ActionChangeAngle -> pcb_act_ChangeAngle +changeangle_help -> pcb_acth_ChangeAngle +changeangle_syntax -> pcb_acts_ChangeAngle +ActionChangeClearSize -> pcb_act_ChangeClearSize +changeclearsize_help -> pcb_acth_ChangeClearSize +changeclearsize_syntax -> pcb_acts_ChangeClearSize +ActionChange2ndSize -> pcb_act_Change2ndSize +change2ndsize_help -> pcb_acth_Change2ndSize +change2ndsize_syntax -> pcb_acts_Change2ndSize +ActionChangeHole -> pcb_act_ChangeHole +changehole_help -> pcb_acth_ChangeHole +changehole_syntax -> pcb_acts_ChangeHole +ActionChangeJoin -> pcb_act_ChangeJoin +changejoin_help -> pcb_acth_ChangeJoin +changejoin_syntax -> pcb_acts_ChangeJoin +ActionChangeName -> pcb_act_ChangeName +changename_help -> pcb_acth_ChangeName +changename_syntax -> pcb_acts_ChangeName +ActionChangePaste -> pcb_act_ChangePaste +changepaste_help -> pcb_acth_ChangePaste +changepaste_syntax -> pcb_acts_ChangePaste +ActionChangePinName -> pcb_act_ChangePinName +changepinname_help -> pcb_acth_ChangePinName +changepinname_syntax -> pcb_acts_ChangePinName +ActionChangeRadius -> pcb_act_ChangeRadius +changeradius_help -> pcb_acth_ChangeRadius +changeradius_syntax -> pcb_acts_ChangeRadius +ActionChangeSize -> pcb_act_ChangeSize +changesize_help -> pcb_acth_ChangeSize +changesize_syntax -> pcb_acts_ChangeSize +ActionChangeSizes -> pcb_act_ChangeSizes +changesizes_help -> pcb_acth_ChangeSizes +changesizes_syntax -> pcb_acts_ChangeSizes +ActionChangeNonetlist -> pcb_act_ChangeNonetlist +changenonetlist_help -> pcb_acth_ChangeNonetlist +changenonetlist_syntax -> pcb_acts_ChangeNonetlist +ActionChangeSquare -> pcb_act_ChangeSquare +changesquare_help -> pcb_acth_ChangeSquare +changesquare_syntax -> pcb_acts_ChangeSquare +ActionChangeOctagon -> pcb_act_ChangeOctagon +changeoctagon_help -> pcb_acth_ChangeOctagon +changeoctagon_syntax -> pcb_acts_ChangeOctagon +ActionChangeFlag -> pcb_act_ChangeFlag +changeflag_help -> pcb_acth_ChangeFlag +changeflag_syntax -> pcb_acts_ChangeFlag +ActionClearSquare -> pcb_act_ClearSquare +clearsquare_help -> pcb_acth_ClearSquare +clearsquare_syntax -> pcb_acts_ClearSquare +ActionClearOctagon -> pcb_act_ClearOctagon +clearoctagon_help -> pcb_acth_ClearOctagon +clearoctagon_syntax -> pcb_acts_ClearOctagon +ActionSetSquare -> pcb_act_SetSquare +setsquare_help -> pcb_acth_SetSquare +setsquare_syntax -> pcb_acts_SetSquare +ActionSetOctagon -> pcb_act_SetOctagon +setoctagon_help -> pcb_acth_SetOctagon +setoctagon_syntax -> pcb_acts_SetOctagon +ActionSetThermal -> pcb_act_SetThermal +setthermal_help -> pcb_acth_SetThermal +setthermal_syntax -> pcb_acts_SetThermal +ActionSetValue -> pcb_act_SetValue +setvalue_help -> pcb_acth_SetValue +setvalue_syntax -> pcb_acts_SetValue +ActionSetFlag -> pcb_act_SetFlag +setflag_help -> pcb_acth_SetFlag +setflag_syntax -> pcb_acts_SetFlag +ActionClrFlag -> pcb_act_ClrFlag +clrflag_help -> pcb_acth_ClrFlag +clrflag_syntax -> pcb_acts_ClrFlag +ActionExecCommand -> pcb_act_ExecCommand +execcommand_help -> pcb_acth_ExecCommand +execcommand_syntax -> pcb_acts_ExecCommand +ActionLoadFrom -> pcb_act_LoadFrom +loadfrom_help -> pcb_acth_LoadFrom +loadfrom_syntax -> pcb_acts_LoadFrom +ActionNew -> pcb_act_New +new_help -> pcb_acth_New +new_syntax -> pcb_acts_New +ActionSaveTo -> pcb_act_SaveTo +saveto_help -> pcb_acth_SaveTo +saveto_syntax -> pcb_acts_SaveTo +ActionQuit -> pcb_act_Quit +quit_help -> pcb_acth_Quit +quit_syntax -> pcb_acts_Quit +ActionDRCheck -> pcb_act_DRCheck +drcheck_help -> pcb_acth_DRCheck +drcheck_syntax -> pcb_acts_DRCheck +ActionDisplay -> pcb_act_Display +display_help -> pcb_acth_Display +display_syntax -> pcb_acts_Display +ActionCycleDrag -> pcb_act_CycleDrag +cycledrag_help -> pcb_acth_CycleDrag +cycledrag_syntax -> pcb_acts_CycleDrag +FullScreen -> pcb_act_FullScreen +fullscreen_help -> pcb_acth_FullScreen +fullscreen_syntax -> pcb_acts_FullScreen +ActionMarkCrosshair -> pcb_act_MarkCrosshair +markcrosshair_help -> pcb_acth_MarkCrosshair +markcrosshair_syntax -> pcb_acts_MarkCrosshair +ActionMessage -> pcb_act_Message +message_help -> pcb_acth_Message +message_syntax -> pcb_acts_Message +ActionMode -> pcb_act_Mode +mode_help -> pcb_acth_Mode +mode_syntax -> pcb_acts_Mode +ActionToggleHideName -> pcb_act_ToggleHideName +togglehidename_help -> pcb_acth_ToggleHideName +togglehidename_syntax -> pcb_acts_ToggleHideName +ActionSetSame -> pcb_act_SetSame +setsame_help -> pcb_acth_SetSame +setsame_syntax -> pcb_acts_SetSame +ActionRouteStyle -> pcb_act_RouteStyle +routestyle_help -> pcb_acth_RouteStyle +routestyle_syntax -> pcb_acts_RouteStyle +ActionCreateMenu -> pcb_act_CreateMenu +createmenu_help -> pcb_acth_CreateMenu +createmenu_syntax -> pcb_acts_CreateMenu +ActionRemoveMenu -> pcb_act_RemoveMenu +removemenu_help -> pcb_acth_RemoveMenu +removemenu_syntax -> pcb_acts_RemoveMenu +ActionSwitchHID -> pcb_act_SwitchHID +switchhid_help -> pcb_acth_SwitchHID +switchhid_syntax -> pcb_acts_SwitchHID +ActionPrintActions -> pcb_act_PrintActions +printactions_help -> pcb_acth_PrintActions +printactions_syntax -> pcb_acts_PrintActions +ActionDumpActions -> pcb_act_DumpActions +dumpactions_help -> pcb_acth_DumpActions +dumpactions_syntax -> pcb_acts_DumpActions +ActionPrintUsage -> pcb_act_PrintUsage +printusage_help -> pcb_acth_PrintUsage +printusage_syntax -> pcb_acts_PrintUsage +ActionPrintVersion -> pcb_act_PrintVersion +printversion_help -> pcb_acth_PrintVersion +printversion_syntax -> pcb_acts_PrintVersion +ActionPrintCopyright -> pcb_act_PrintCopyright +printcopyright_help -> pcb_acth_PrintCopyright +printcopyright_syntax -> pcb_acts_PrintCopyright +ActionPrintPaths -> pcb_act_PrintPaths +printpaths_help -> pcb_acth_PrintPaths +printpaths_syntax -> pcb_acts_PrintPaths +ActionNetlist -> pcb_act_Netlist +netlist_help -> pcb_acth_Netlist +netlist_syntax -> pcb_acts_Netlist +ActionNetlist -> pcb_act_Netlist +netlist_help -> pcb_acth_Netlist +netlist_syntax -> pcb_acts_Netlist +ActionAttributes -> pcb_act_Attributes +attributes_help -> pcb_acth_Attributes +attributes_syntax -> pcb_acts_Attributes +ActionDisperseElements -> pcb_act_DisperseElements +disperseelements_help -> pcb_acth_DisperseElements +disperseelements_syntax -> pcb_acts_DisperseElements +ActionFlip -> pcb_act_Flip +flip_help -> pcb_acth_Flip +flip_syntax -> pcb_acts_Flip +ActionListRotations -> pcb_act_ListRotations +listrotations_help -> pcb_acth_ListRotations +listrotations_syntax -> pcb_acts_ListRotations +ActionMoveObject -> pcb_act_MoveObject +moveobject_help -> pcb_acth_MoveObject +moveobject_syntax -> pcb_acts_MoveObject +ActionMoveToCurrentLayer -> pcb_act_MoveToCurrentLayer +movetocurrentlayer_help -> pcb_acth_MoveToCurrentLayer +movetocurrentlayer_syntax -> pcb_acts_MoveToCurrentLayer +ActionElementList -> pcb_act_ElementList +elementlist_help -> pcb_acth_ElementList +elementlist_syntax -> pcb_acts_ElementList +ActionElementSetAttr -> pcb_act_ElementSetAttr +elementsetattr_help -> pcb_acth_ElementSetAttr +elementsetattr_syntax -> pcb_acts_ElementSetAttr +ActionRipUp -> pcb_act_RipUp +ripup_help -> pcb_acth_RipUp +ripup_syntax -> pcb_acts_RipUp +ActionMinMaskGap -> pcb_act_MinMaskGap +minmaskgap_help -> pcb_acth_MinMaskGap +minmaskgap_syntax -> pcb_acts_MinMaskGap +ActionMinClearGap -> pcb_act_MinClearGap +mincleargap_help -> pcb_acth_MinClearGap +mincleargap_syntax -> pcb_acts_MinClearGap +MoveLayerAction -> pcb_act_MoveLayerAction +movelayeraction_help -> pcb_acth_MoveLayerAction +movelayeraction_syntax -> pcb_acts_MoveLayerAction +Action_fp_rehash -> pcb_act__fp_rehash +_fp_rehash_help -> pcb_acth__fp_rehash +_fp_rehash_syntax -> pcb_acts__fp_rehash +ActionMorphPolygon -> pcb_act_MorphPolygon +morphpolygon_help -> pcb_acth_MorphPolygon +morphpolygon_syntax -> pcb_acts_MorphPolygon +ActionPolygon -> pcb_act_Polygon +polygon_help -> pcb_acth_Polygon +polygon_syntax -> pcb_acts_Polygon +ActionAddRats -> pcb_act_AddRats +addrats_help -> pcb_acth_AddRats +addrats_syntax -> pcb_acts_AddRats +ActionConnection -> pcb_act_Connection +connection_help -> pcb_acth_Connection +connection_syntax -> pcb_acts_Connection +ActionDeleteRats -> pcb_act_DeleteRats +deleterats_help -> pcb_acth_DeleteRats +deleterats_syntax -> pcb_acts_DeleteRats +ActionDelete -> pcb_act_Delete +delete_help -> pcb_acth_Delete +delete_syntax -> pcb_acts_Delete +ActionRemoveSelected -> pcb_act_RemoveSelected +removeselected_help -> pcb_acth_RemoveSelected +removeselected_syntax -> pcb_acts_RemoveSelected +ActionSelect -> pcb_act_Select +select_help -> pcb_acth_Select +select_syntax -> pcb_acts_Select +ActionUnselect -> pcb_act_Unselect +unselect_help -> pcb_acth_Unselect +unselect_syntax -> pcb_acts_Unselect +ActionAtomic -> pcb_act_Atomic +atomic_help -> pcb_acth_Atomic +atomic_syntax -> pcb_acts_Atomic +ActionUndo -> pcb_act_Undo +undo_help -> pcb_acth_Undo +undo_syntax -> pcb_acts_Undo +ActionRedo -> pcb_act_Redo +redo_help -> pcb_acth_Redo +redo_syntax -> pcb_acts_Redo +ActionReplaceFootprint -> pcb_act_ReplaceFootprint +replacefootprint_help -> pcb_acth_ReplaceFootprint +replacefootprint_syntax -> pcb_acts_ReplaceFootprint +ActionSavePatch -> pcb_act_SavePatch +savepatch_help -> pcb_acth_SavePatch +savepatch_syntax -> pcb_acts_SavePatch +ActionManagePlugins -> pcb_act_ManagePlugins +manageplugins_help -> pcb_acth_ManagePlugins +manageplugins_syntax -> pcb_acts_ManagePlugins +ActionConf -> pcb_act_Conf +conf_help -> pcb_acth_Conf +conf_syntax -> pcb_acts_Conf +ActionGetStyle -> pcb_act_GetStyle +getstyle_help -> pcb_acth_GetStyle +getstyle_syntax -> pcb_acts_GetStyle +ActionChkMode -> pcb_act_ChkMode +chkmode_help -> pcb_acth_ChkMode +chkmode_syntax -> pcb_acts_ChkMode +ActionChkGridSize -> pcb_act_ChkGridSize +chkgridsize_help -> pcb_acth_ChkGridSize +chkgridsize_syntax -> pcb_acts_ChkGridSize +ActionChkElementName -> pcb_act_ChkElementName +chkelementname_help -> pcb_acth_ChkElementName +chkelementname_syntax -> pcb_acts_ChkElementName +ActionChkGridUnits -> pcb_act_ChkGridUnits +chkgridunits_help -> pcb_acth_ChkGridUnits +chkgridunits_syntax -> pcb_acts_ChkGridUnits +ActionChkBuffer -> pcb_act_ChkBuffer +chkbuffer_help -> pcb_acth_ChkBuffer +chkbuffer_syntax -> pcb_acts_ChkBuffer +ActionFreeRotateBuffer -> pcb_act_FreeRotateBuffer +freerotatebuffer_help -> pcb_acth_FreeRotateBuffer +freerotatebuffer_syntax -> pcb_acts_FreeRotateBuffer +ActionPasteBuffer -> pcb_act_PasteBuffer +pastebuffer_help -> pcb_acth_PasteBuffer +pastebuffer_syntax -> pcb_acts_PasteBuffer +ActionDumpLibrary -> pcb_act_DumpLibrary +dumplibrary_help -> pcb_acth_DumpLibrary +dumplibrary_syntax -> pcb_acts_DumpLibrary +ActionBell -> pcb_act_Bell +bell_help -> pcb_acth_Bell +bell_syntax -> pcb_acts_Bell +ActionToggleVendor -> pcb_act_ToggleVendor +togglevendor_help -> pcb_acth_ToggleVendor +togglevendor_syntax -> pcb_acts_ToggleVendor +ActionEnableVendor -> pcb_act_EnableVendor +enablevendor_help -> pcb_acth_EnableVendor +enablevendor_syntax -> pcb_acts_EnableVendor +ActionDisableVendor -> pcb_act_DisableVendor +disablevendor_help -> pcb_acth_DisableVendor +disablevendor_syntax -> pcb_acts_DisableVendor +ActionImport -> pcb_act_Import +import_help -> pcb_acth_Import +import_syntax -> pcb_acts_Import +ActionLoadhypFrom -> pcb_act_LoadhypFrom +loadhypfrom_help -> pcb_acth_LoadhypFrom +loadhypfrom_syntax -> pcb_acts_LoadhypFrom +ActionRenumber -> pcb_act_Renumber +renumber_help -> pcb_acth_Renumber +renumber_syntax -> pcb_acts_Renumber +ActionRenumberBlock -> pcb_act_RenumberBlock +renumberblock_help -> pcb_acth_RenumberBlock +renumberblock_syntax -> pcb_acts_RenumberBlock +ActionRenumberBuffer -> pcb_act_RenumberBuffer +renumberbuffer_help -> pcb_acth_RenumberBuffer +renumberbuffer_syntax -> pcb_acts_RenumberBuffer +ActionLoadDsnFrom -> pcb_act_LoadDsnFrom +loaddsnfrom_help -> pcb_acth_LoadDsnFrom +loaddsnfrom_syntax -> pcb_acts_LoadDsnFrom +ActionDumpConf -> pcb_act_DumpConf +dumpconf_help -> pcb_acth_DumpConf +dumpconf_syntax -> pcb_acts_DumpConf +ActionDumpLayers -> pcb_act_DumpLayers +dumplayers_help -> pcb_acth_DumpLayers +dumplayers_syntax -> pcb_acts_DumpLayers +ActionEvalConf -> pcb_act_EvalConf +evalconf_help -> pcb_acth_EvalConf +evalconf_syntax -> pcb_acts_EvalConf +ActionPSCalib -> pcb_act_PSCalib +pscalib_help -> pcb_acth_PSCalib +pscalib_syntax -> pcb_acts_PSCalib +ActionApplyVendor -> pcb_act_ApplyVendor +applyvendor_help -> pcb_acth_ApplyVendor +applyvendor_syntax -> pcb_acts_ApplyVendor +ActionUnloadVendor -> pcb_act_UnloadVendor +unloadvendor_help -> pcb_acth_UnloadVendor +unloadvendor_syntax -> pcb_acts_UnloadVendor +ActionLoadVendorFrom -> pcb_act_LoadVendorFrom +loadvendorfrom_help -> pcb_acth_LoadVendorFrom +loadvendorfrom_syntax -> pcb_acts_LoadVendorFrom +ActionAutoRoute -> pcb_act_AutoRoute +autoroute_help -> pcb_acth_AutoRoute +autoroute_syntax -> pcb_acts_AutoRoute +GlobalPuller -> pcb_act_GlobalPuller +globalpuller_help -> pcb_acth_GlobalPuller +globalpuller_syntax -> pcb_acts_GlobalPuller +Puller -> pcb_act_Puller +puller_help -> pcb_acth_Puller +puller_syntax -> pcb_acts_Puller +ActionAutoPlaceSelected -> pcb_act_AutoPlaceSelected +autoplaceselected_help -> pcb_acth_AutoPlaceSelected +autoplaceselected_syntax -> pcb_acts_AutoPlaceSelected +ActionDJopt -> pcb_act_DJopt +djopt_help -> pcb_acth_DJopt +djopt_syntax -> pcb_acts_DJopt +h_str -> pcb_hash_str +h_coordox -> pcb_hash_element_ox +h_coordoy -> pcb_hash_element_oy +h_coord -> pcb_hash_coord +pcb_buffer_swap -> pcb_buffer_flip_side +pcb_swap_buffers -> pcb_buffers_flip_side +LAYER_IS_PCB_EMPTY -> PCB_LAYER_IS_EMPTY +LAYER_IS_PCB_EMPTY -> PCB_LAYER_IS_EMPTY +IsLayerEmpty -> pcb_layer_is_empty_ +IsLayerNumEmpty -> pcb_layer_is_empty +IsLayerGroupEmpty -> pcb_is_layergrp_empty +ParseGroupString -> pcb_layer_parse_group_string +GetLayerNumber -> pcb_layer_id +GetGroupOfLayer -> pcb_layer_get_group +GetLayerGroupNumberByPointer -> pcb_layer_get_group_ +GetLayerGroupNumberByNumber -> pcb_layer_get_group +IsPasteEmpty -> pcb_layer_is_paste_empty +SOLDER_LAYER -> PCB_SOLDER_SIDE +COMPONENT_LAYER -> PCB_COMPONENT_SIDE +LayerStringToLayerStack -> pcb_layervis_parse_string +ChangeGroupVisibility -> pcb_layervis_change_group_vis +ResetStackAndVisibility -> pcb_layervis_reset_stack +SaveStackAndVisibility -> pcb_layervis_save_stack +RestoreStackAndVisibility -> pcb_layervis_restore_stack +AddArcToBuffer -> pcb_arcop_add_to_buffer +MoveArcToBuffer -> pcb_arcop_move_to_buffer +ChangeArcSize -> pcb_arcop_change_size +ChangeArcClearSize -> pcb_arcop_change_clear_size +ChangeArcRadius -> pcb_arcop_change_radius +ChangeArcAngle -> pcb_arcop_change_angle +ChangeArcJoin -> pcb_arcop_change_join +SetArcJoin -> pcb_arcop_set_join +ClrArcJoin -> pcb_arcop_clear_join +CopyArc -> pcb_arcop_copy +MoveArc -> pcb_arcop_move +MoveArcToLayerLowLevel -> pcb_arcop_move_to_layer_low +MoveArcToLayer -> pcb_arcop_move_to_layer +DestroyArc -> pcb_arcop_destroy +RemoveArc_op -> pcb_arcop_remove +RemoveArcPoint_op -> pcb_arcop_remove_point +Rotate90Arc -> pcb_arcop_rotate90 +ChgFlagArc -> pcb_arcop_change_flag +AddLineToBuffer -> pcb_lineop_add_to_buffer +ChangeLineSize -> pcb_lineop_change_size +ChangeLineClearSize -> pcb_lineop_change_clear_size +ChangeLineName -> pcb_lineop_change_name +ChangeLineJoin -> pcb_lineop_change_join +SetLineJoin -> pcb_lineop_set_join +ClrLineJoin -> pcb_lineop_clear_join +InsertPointIntoLine -> pcb_lineop_insert_point +MoveLineToBuffer -> pcb_lineop_move_to_buffer +CopyLine -> pcb_lineop_copy +MoveLine -> pcb_lineop_move +MoveLinePoint -> pcb_lineop_move_point +MoveLinePointWithRoute -> pcb_lineop_move_point_with_route +MoveLineToLayerLowLevel -> pcb_lineop_move_to_layer_low +MoveLineToLayer -> pcb_lineop_move_to_layer +DestroyLine -> pcb_lineop_destroy +RemoveLinePoint -> pcb_lineop_remove_point +RemoveLine_op -> pcb_lineop_remove +Rotate90LinePoint -> pcb_lineop_rotate90_point +Rotate90Line -> pcb_lineop_rotate90 +ChgFlagLine -> pcb_lineop_change_flag +AddArcToBuffer -> pcb_arcop_add_to_buffer +MoveArcToBuffer -> pcb_arcop_move_to_buffer +ChangeArcSize -> pcb_arcop_change_size +ChangeArcClearSize -> pcb_arcop_change_clear_size +ChangeArcRadius -> pcb_arcop_change_radius +ChangeArcAngle -> pcb_arcop_change_angle +ChangeArcJoin -> pcb_arcop_change_join +SetArcJoin -> pcb_arcop_set_join +ClrArcJoin -> pcb_arcop_clear_join +CopyArc -> pcb_arcop_copy +MoveArc -> pcb_arcop_move +MoveArcToLayerLowLevel -> pcb_arcop_move_to_layer_low +MoveArcToLayer -> pcb_arcop_move_to_layer +DestroyArc -> pcb_arcop_destroy +RemoveArc_op -> pcb_arcop_remove +RemoveArcPoint_op -> pcb_arcop_remove_point +Rotate90Arc -> pcb_arcop_rotate90 +ChgFlagArc -> pcb_arcop_change_flag +AddElementToBuffer -> pcb_elemop_add_to_buffer +MoveElementToBuffer -> pcb_elemop_move_to_buffer +ClrElementOctagon -> pcb_elemop_clear_octagon +SetElementOctagon -> pcb_elemop_set_octagon +ChangeElementOctagon -> pcb_elemop_change_octagon +ClrElementSquare -> pcb_elemop_clear_square +SetElementSquare -> pcb_elemop_set_square +ChangeElementSquare -> pcb_elemop_change_square +ChangeElementNonetlist -> pcb_elemop_change_nonetlist +ChangeElementName -> pcb_elemop_change_name +ChangeElementNameSize -> pcb_elemop_change_name_size +ChangeElementSize -> pcb_elemop_change_size +ChangeElementClearSize -> pcb_elemop_change_clear_size +ChangeElement1stSize -> pcb_elemop_change_1st_size +ChangeElement2ndSize -> pcb_elemop_change_2nd_size +CopyElement -> pcb_elemop_copy +MoveElementName -> pcb_elemop_move_name +MoveElement -> pcb_elemop_move +DestroyElement -> pcb_elemop_destroy +RemoveElement_op -> pcb_elemop_remove +Rotate90Element -> pcb_elemop_rotate90 +Rotate90ElementName -> pcb_elemop_rotate90_name +ChangePadSize -> pcb_padop_change_size +ChangePadClearSize -> pcb_padop_change_clear_size +ChangePadName -> pcb_padop_change_name +ChangePadNum -> pcb_padop_change_num +ChangePadSquare -> pcb_padop_change_square +SetPadSquare -> pcb_padop_set_square +ClrPadSquare -> pcb_padop_clear_square +ChangePadMaskSize -> pcb_padop_change_mask_size +AddViaToBuffer -> pcb_viaop_add_to_buffer +MoveViaToBuffer -> pcb_viaop_move_to_buffer +ChangeViaThermal -> pcb_viaop_change_thermal +ChangePinThermal -> pcb_pinop_change_thermal +ChangeViaSize -> pcb_viaop_change_size +ChangeVia2ndSize -> pcb_viaop_change_2nd_size +ChangePin2ndSize -> pcb_pinop_change_2nd_size +ChangeViaClearSize -> pcb_viaop_change_clear_size +ChangePinSize -> pcb_pinop_change_size +ChangePinClearSize -> pcb_pinop_change_clear_size +ChangeViaName -> pcb_viaop_change_name +ChangePinName -> pcb_pinop_change_name +ChangePinNum -> pcb_pinop_change_num +ChangeViaSquare -> pcb_viaop_change_square +ChangePinSquare -> pcb_pinop_change_square +SetPinSquare -> pcb_pinop_set_square +ClrPinSquare -> pcb_pinop_clear_square +ChangeViaOctagon -> pcb_viaop_change_octagon +SetViaOctagon -> pcb_viaop_set_octagon +ClrViaOctagon -> pcb_viaop_clear_octagon +ChangePinOctagon -> pcb_pinop_change_octagon +SetPinOctagon -> pcb_pinop_set_octagon +ClrPinOctagon -> pcb_pinop_clear_octagon +ChangePinMaskSize -> pcb_pinop_change_mask_size +ChangeViaMaskSize -> pcb_viaop_change_mask_size +CopyVia -> pcb_viaop_copy +MoveVia -> pcb_viaop_move +DestroyVia -> pcb_viaop_destroy +RemoveVia -> pcb_viaop_remove +AddPolygonToBuffer -> pcb_polyop_add_to_buffer +MovePolygonToBuffer -> pcb_polyop_move_to_buffer +ChangePolygonClearSize -> pcb_polyop_change_clear_size +ChangePolyClear -> pcb_polyop_change_clear +InsertPointIntoPolygon -> pcb_polyop_insert_point +MovePolygon -> pcb_polyop_move +MovePolygonPoint -> pcb_polyop_move_point +MovePolygonToLayerLowLevel -> pcb_polyop_move_to_layer_low +MovePolygonToLayer -> pcb_polyop_move_to_layer +DestroyPolygon -> pcb_polyop_destroy +DestroyPolygonPoint -> pcb_polyop_destroy_point +RemovePolygon_op -> pcb_polyop_remove +RemovePolygonContour -> pcb_polyop_remove_counter +RemovePolygonPoint -> pcb_polyop_remove_point +CopyPolygon -> pcb_polyop_copy +Rotate90Polygon -> pcb_polyop_rotate90 +ChgFlagPolygon -> pcb_polyop_change_flag +AddRatToBuffer -> pcb_ratop_add_to_buffer +MoveRatToBuffer -> pcb_ratop_move_to_buffer +InsertPointIntoRat -> pcb_ratop_insert_point +MoveRatToLayer -> pcb_ratop_move_to_layer +DestroyRat -> pcb_ratop_destroy +RemoveRat -> pcb_ratop_remove +CopySubc -> pcb_subcop_copy +MoveSubc -> pcb_subcop_move +Rotate90Subc -> pcb_subcop_rotate90 +MoveSubcToBuffer -> pcb_subcop_move_to_buffer +AddSubcToBuffer -> pcb_subcop_add_to_buffer +ChangeSubcSize -> pcb_subcop_change_size +ChangeSubcClearSize -> pcb_subcop_change_clear_size +ChangeSubc1stSize -> pcb_subcop_change_1st_size +ChangeSubc2ndSize -> pcb_subcop_change_2nd_size +ChangeSubcNonetlist -> pcb_subcop_change_nonetlist +ChangeSubcName -> pcb_subcop_change_name +DestroySubc -> pcb_subcop_destroy +RemoveSubc_op -> pcb_subcop_remove +ClrSubcOctagon -> pcb_subcop_clear_octagon +SetSubcOctagon -> pcb_subcop_set_octagon +ChangeSubcOctagon -> pcb_subcop_change_octagon +ClrSubcSquare -> pcb_subcop_clear_square +SetSubcSquare -> pcb_subcop_set_square +ChangeSubcSquare -> pcb_subcop_change_square +ChgFlagSubc -> pcb_subcop_change_flag +AddTextToBuffer -> pcb_textop_add_to_buffer +MoveTextToBuffer -> pcb_textop_move_to_buffer +ChangeTextSize -> pcb_textop_change_size +ChangeTextName -> pcb_textop_change_name +ChangeTextJoin -> pcb_textop_change_join +SetTextJoin -> pcb_textop_set_join +ClrTextJoin -> pcb_textop_clear_join +CopyText -> pcb_textop_copy +MoveText -> pcb_textop_move +MoveTextToLayerLowLevel -> pcb_textop_move_to_layer_low +MoveTextToLayer -> pcb_textop_move_to_layer +DestroyText -> pcb_textop_destroy +RemoveText_op -> pcb_textop_remove +Rotate90Text -> pcb_textop_rotate90 +ChgFlagText -> pcb_textop_change_flag +EraseArc -> pcb_arc_invalidate_erase +DrawArc -> pcb_arc_invalidate_draw +_draw_arc -> pcb_arc_draw_ +draw_arc -> pcb_arc_draw +draw_line_callback -> pcb_line_draw_callback +_draw_line -> pcb_line_draw_ +draw_line -> pcb_line_draw +EraseLine -> pcb_line_invalidate_erase +DrawLine -> pcb_line_invalidate_draw +draw_poly_callback -> pcb_poly_draw_callback +ErasePolygon -> pcb_poly_invalidate_erase +DrawPolygon -> pcb_poly_invalidate_draw +draw_rat_callback -> pcb_rat_draw_callback +EraseRat -> pcb_rat_invalidate_erase +DrawRat -> pcb_rat_invalidate_draw +draw_text_callback -> pcb_text_draw_callback +XORDrawText -> pcb_text_draw_xor +DrawTextLowLevel -> pcb_text_draw +EraseText -> pcb_text_invalidate_erase +DrawText -> pcb_text_invalidate_draw +draw_arc_callback -> pcb_arc_draw_callback +draw_pad_name_callback -> pcb_pad_name_draw_callback +pcb_draw_paste_auto -> pcb_pad_paste_draw +ErasePadName -> pcb_pad_name_invalidate_erase +DrawPadName -> pcb_pad_name_invalidate_draw +draw_pad_callback -> pcb_pad_draw_callback +clear_pad_callback -> pcb_pad_clear_callback +draw_pad -> pcb_pad_draw +ErasePad -> pcb_pad_invalidate_erase +DrawPad -> pcb_pad_invalidate_draw +draw_pin_name_callback -> pcb_pin_name_draw_callback +EraseViaName -> pcb_via_name_invalidate_erase +ErasePinName -> pcb_pin_name_invalidate_erase +DrawViaName -> pcb_via_name_invalidate_draw +DrawPinName -> pcb_pin_name_invalidate_draw +draw_pin_callback -> pcb_pin_draw_callback +clear_pin_callback -> pcb_pin_clear_callback +draw_via_callback -> pcb_via_draw_callback +draw_hole_callback -> pcb_hole_draw_callback +draw_pin -> pcb_pin_draw +EraseVia -> pcb_via_invalidate_erase +ErasePin -> pcb_pin_invalidate_erase +DrawVia -> pcb_via_invalidate_draw +DrawPin -> pcb_pin_invalidate_draw +draw_element_name_callback -> pcb_elem_name_draw_callback +draw_element_mark_callback -> pcb_elem_mark_draw_callback +draw_element_callback -> pcb_elem_draw_callback +draw_element_pins_and_pads -> pcb_elem_pp_draw +draw_element_package -> pcb_elem_package_draw +draw_element_name -> pcb_elem_name_draw +draw_element -> pcb_elem_draw +EraseElementPinsAndPads -> pcb_elem_pp_invalidate_erase +EraseElementName -> pcb_elem_name_invalidate_erase +EraseElement -> pcb_elem_invalidate_erase +DrawElementPinsAndPads -> pcb_elem_pp_invalidate_draw +DrawElementPackage -> pcb_elem_package_invalidate_draw +DrawElementName -> pcb_elem_name_invalidate_draw +DrawElement -> pcb_elem_invalidate_draw +pcb_polygon_t -> pcb_poly_t +pcb_polygon_s -> pcb_poly_s +pcb_add_polygon_on_layer -> pcb_add_poly_on_layer +GetObjectBoundingBox -> pcb_obj_get_bbox +PCB_TYPE_ -> PCB_OBJ_ +PCB_OBJ_NONE -> PCB_OBJ_VOID +pcb_obj_tpye_t -> pcb_objtype_t +PCB_TYPEMASK_ALL -> PCB_OBJ_ANY +PCB_OBJ_RATLINE -> PCB_OBJ_RAT +PCB_OBJ_SUBC_FLOATER -> PCB_OBJ_FLOATER +PCB_TYPEMASK_ -> PCB_OBJ_CLASS_ +XORDrawAttachedLine -> pcb_xordraw_attached_line +XORPolygon -> pcb_xordraw_poly +XORPolygon_subc -> pcb_xordraw_poly_subc +XORDrawAttachedArc -> pcb_xordraw_attached_arc +XORDrawBuffer -> pcb_xordraw_buffer +XORDrawMoveOrCopy -> pcb_xordraw_movecopy +XORDrawInsertPointObject -> pcb_xordraw_insert_pt_obj +XORDrawSubc -> pcb_xordraw_subc +pcb_hid_find_action -> pcb_find_action +pcb_hid_remove_actions -> pcb_remove_actions +pcb_hid_remove_action -> pcb_remove_action +pcb_hid_remove_actions_by_cookie -> pcb_remove_actions_by_cookie +pcb_hid_action -> pcb_action +pcb_hid_actionl -> pcb_actionl +pcb_hid_actionv -> pcb_actionv +pcb_hid_actionv_ -> pcb_actionv_ +pcb_hid_parse_command -> pcb_parse_command +pcb_hid_parse_actions -> pcb_parse_actions +pcb_hid_register_action -> pcb_register_action +pcb_hid_register_actions -> pcb_register_actions +pcb_hid_actions_uninit -> pcb_actions_uninit +pcb_hid_actions_init -> pcb_actions_init +pcb_poly_from_arc -> pcb_poly_from_pcb_arc +pcb_poly_from_line -> pcb_poly_from_pcb_line +pcb_notify_crosshair_change -> pcb_hid_notify_crosshair_change Index: tags/2.3.0/doc/developer/src/Makefile =================================================================== --- tags/2.3.0/doc/developer/src/Makefile (nonexistent) +++ tags/2.3.0/doc/developer/src/Makefile (revision 33253) @@ -0,0 +1,2 @@ +../data1.svg: data1.dot + dot -Tsvg $^ > $@ Index: tags/2.3.0/doc/developer/src/data1.dot =================================================================== --- tags/2.3.0/doc/developer/src/data1.dot (nonexistent) +++ tags/2.3.0/doc/developer/src/data1.dot (revision 33253) @@ -0,0 +1,88 @@ +digraph pcb_data { + ranksep=1.3 + PCBType_misc [label="misc fields:\nID\nName\nFileName\ncolors\ndrc settings\ncursor coords\ngrid\nlayergroups\nroute styles\npadstack protos\n..."] + PCBType_flags [label="flags:\nChanged\nViaOn (vias drawn?)\n..."] + pcb_board_t -> PCBType_misc + pcb_board_t -> PCBType_flags + pcb_board_t -> pcb_data_t + pcb_board_t [shape=box] + + pcb_data_t2 [label="another level of\npcb_data_t\n..." shape=none] + + pcb_subc_t [shape=box style=filled color="#aaffaa"] + pcb_rat_line_t [shape=box style=filled color="#aaffaa"] + pcb_pstk_t [shape=box style=filled color="#aaffaa"] + pcb_padstack_proto_t [shape=box] + pcb_arc_t [shape=box style=filled color="#aaffaa"] + pcb_gfx_t [shape=box style=filled color="#aaffaa"] + pcb_line_t [shape=box style=filled color="#aaffaa"] + pcb_text_t [shape=box style=filled color="#aaffaa"] + pcb_poly_t [shape=box style=filled color="#aaffaa"] + + PCB [label="extern pcb_board_t PCB\nglobal variable\nholding the current\nboard" shape=diamond] + PCB -> pcb_board_t + + Buffers [label="extern pcb_buffer_t Buffers[]\nglobal variable holding\nall paste buffers" shape=diamond] + Buffers -> pcb_buffer_t + + BufferType_misc [label="misc fields:\nbounding box\noffset"] + pcb_buffer_t -> BufferType_misc + pcb_buffer_t -> pcb_data_t + pcb_buffer_t [shape=box] + + DataType_listrt [label="layer-independent lists and rtrees"] + DataType_LayerN [label="LayerN: number of\nlayers in use"] + DataType_layers [label="an array of layers"] + DataType_misc [label="misc fields"] + + pcb_data_t -> DataType_misc [tailport=s] + pcb_data_t -> DataType_LayerN [tailport=s] + pcb_data_t -> DataType_layers [tailport=s] + pcb_data_t -> DataType_listrt [tailport=s] + pcb_data_t -> DataType_rtrees [tailport=s] + pcb_data_t [shape=box] + + DataType_layers -> pcb_layer_t + + DataType_listrt -> pcb_subc_t + DataType_listrt -> pcb_rat_line_t + DataType_listrt -> pcb_pstk_t + DataType_listrt -> pcb_padstack_proto_t + + pcb_subc_t -> pcb_data_t2 + pcb_pstk_t -> pcb_padstack_proto_t [constraint=no color=blue label="id\nref."] + + LayerType_lines [label="list and rtree of lines"] + LayerType_arcs [label="list and rtree of arcs"] + LayerType_gfxs [label="list and rtree of gfxs"] + LayerType_texts [label="list and rtree of text objects"] + LayerType_polygons [label="list and rtree of polygons"] + LayerType_misc [label="misc fields:\nflags\ncolors"] + + LayerType_lines -> pcb_line_t + LayerType_arcs -> pcb_arc_t + LayerType_gfxs -> pcb_gfx_t + LayerType_polygons -> pcb_poly_t + LayerType_texts -> pcb_text_t + + pcb_layer_t -> LayerType_misc + pcb_layer_t -> LayerType_lines + pcb_layer_t -> LayerType_arcs + pcb_layer_t -> LayerType_gfxs + pcb_layer_t -> LayerType_texts + pcb_layer_t -> LayerType_polygons + pcb_layer_t [shape=box] + + subgraph "cluster_1" { + label="LEGEND" + style=filled + bgcolor=grey + round [label="round:\nstruct field"] + struct [label="box:\nstruct" shape=box] + diamond [label="diamond:\nglobal variable" shape=diamond] + grn [label="green:\ndrawing primitive" shape=box style=filled color="#aaffaa"] + + } + + pcb_poly_t -> struct [style=invis] +} Index: tags/2.3.0/doc/doc.html =================================================================== --- tags/2.3.0/doc/doc.html (nonexistent) +++ tags/2.3.0/doc/doc.html (revision 33253) @@ -0,0 +1,38 @@ + + + + pcb-rnd - documentation + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +
+ +

pcb-rnd documentation

+ + + + + Index: tags/2.3.0/doc/faq.html =================================================================== --- tags/2.3.0/doc/faq.html (nonexistent) +++ tags/2.3.0/doc/faq.html (revision 33253) @@ -0,0 +1,115 @@ + + + + pcb-rnd - FAQ + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +
+ +

pcb-rnd FAQ

+ +

1. export

+ +

1.1. Gerber export not producing excellon drill files

+

+That is correct, by default direct gerber export shouldn't +produce excellon files as excellon is a different format. Direct +gerber export also won't produce ps or png files. +

+You have two ways getting excellon files: +

    +
  • If you need only excellon drill files, you can do a direct export using +the execllon export format; on GUI use the "File/Export layout" menu or +the {f e} key combination and select excellon; on CLI use -x excellon. +Unless you have an CNC router it's unlikely you want drill files only. + +
  • What you probably should do instead of direct exporting is CAM +exporting, using "File/Export with CAM job..." or {f c} on the GUI or "-x +cam jobname" on the CLI. The CAM exporter is designed to invoke multiple +export plugins (e.g. gerber and excellon). pcb-rnd is shipped with +preconfigured CAM jobs for the most popular fab houses so you get file +names you can directly upload to them. If you have a fab not yet +supported, please contact me. +
+ +

+ +Note: as of 2019, for the transition time, direct exporting to gerber using any of the old +naming styles (e.g. "fixed") will still cross-call the excellon export +plugin and produce the extra (non-gerber) drill files. It will also +generate a bunch of warnings telling you that this feature will be removed +soon. You shouldn't depend on this too much. + + +

2. padstacks

+ +

2.1. Intern copper layer shape not rendering

+

+Does the padstack has a hole? Does the hole drill through any internal +copper layer (in non-thru-hole case)? +

+Internal copper layers are special: there are multiple of them. The padstack +will place the intern shape on any internal copper layer that the padstack's +hole reaches. If the padstack has no hole, no internal layer shape is +rendered, even if it is specified. + + +

3. slots (oval holes)

+ +

3.1. My slot doesn't show up on screen or in exports

+

+Make sure you have the right layer groups and layers set up: +

    +
  • a mech layer group with purpose uroute and another with purpose proute for unplated and plated slots +
  • make sure there is a layer in each group that has auto in the comb flags - padstack side effects will land only on auto layers; auto layers are indicated with white hatching in the layer selector's layer color +
+ +

4. DSN format

+

4.1. There are no holes in padstacks on import

+

+The DSN format was originally designed for autorouting; an autorouter doesn't +need to know the geometry of a hole, assuming copper annulus is always around +the hole. Thus old versions of the file format simply does not have a way +to describe holes. +

+Some software extended the format and use a hole directive that pcb-rnd +picks up - but if the file does not contain holes, pcb-rnd can't improvise them. +

+You can use query() to find offending padstacks and use propset() or +the padstack editor to install the holes. + +

4.2. There are no silk graphics on subcircuits after import

+

+The DSN format does not specify silk. There are outline and keepout objects +in the format and pcb-rnd loads them on special purpose documentation layers. +The use of these objects vary from tool to tool - some tools will draw the +bounding box of the part using lines on the outline layer, but other tools +may just draw a large, rectangular filled polygon. +

+Use the per subcircuit layer bindings to map them on a board silk layer. + +

4.3. Missing solder mask cutouts and solder paste patterns after import

+

+The DSN format does not specify solder mask or paste. Please use the padstack +editor on the affected padstacks. + + + Index: tags/2.3.0/doc/help/err0001.html =================================================================== --- tags/2.3.0/doc/help/err0001.html (nonexistent) +++ tags/2.3.0/doc/help/err0001.html (revision 33253) @@ -0,0 +1,34 @@ + + + +

Had to convert import:: attributes to import_sch config

+ +

What it is

+

+The old schematics import code used board attributes to remember the name +of the schematics files and method of import. These attributes had names +starting with import::. +

+The new import code does not use those attributes to store its configuration +but uses the configuration subtree plugins/import_sch. The names +and meaning of the settings changed too. +

+This error message is generated once, when you first run import schematics +using the new code on a board file that still has the old, attribute based +configuration. By the time the error message is printed, the code has already +converted the old attributes to the new config. + +

What you need to do

+

+Normally: nothing. +

+There is only one special case: if you plan to use the same board file with +older versions of pcb-rnd in parallel to a new version of pcb-rnd and +you have to change the import configuration on any version, you will also need +to do the same changes on the other version. This is because the new code +will change only the import_sch config version, while the old code will change +only the attributes. + + + + Index: tags/2.3.0/doc/help/err0002.html =================================================================== --- tags/2.3.0/doc/help/err0002.html (nonexistent) +++ tags/2.3.0/doc/help/err0002.html (revision 33253) @@ -0,0 +1,13 @@ + + + +

Switching from Import() to ImportSch()

+

+For the full explanation, please read this +mail. +

+

Index: tags/2.3.0/doc/help.html =================================================================== --- tags/2.3.0/doc/help.html (nonexistent) +++ tags/2.3.0/doc/help.html (revision 33253) @@ -0,0 +1,69 @@ + + + + pcb-rnd - help wanted + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +

pcb-rnd - help wanted

+The project is looking for volunteers for the features listed below. If +you want to contribute, you will need to have an svn client and an email +client. Furthermore an IRC client is strongly recommended. +

+You will become part of the team and get svn commit right immediately +when you start working. +

+Don't have much free time? Don't worry: the tasks below are split up in +very small (1..2 hours) chunks. Coordination is granted, the administrative +overhead is almost zero - you can focus on the task, and finish it whenever +you have a free hour. +

+Worrying about your contribution to go in /dev/null? Don't: pcb-rnd +has very short loops; you start contributing and get immediate feedback. Your +work is part of the official thing immediately and revised and accepted (or +rarely refused) within hours or at most days. +There are no bitrotting branches. +

+You are not confident enough with your skills? pcb-rnd is an optimal +project for learning. If you start contributing, you get support. There +are small and simple entry level tasks. Most of the tasks don't require +any programming skills. +

+Sign up by contacting the lead developer +If you want to work on a feature not listed below, feel free to drop me +a mail. +

+ +
ID skill required description +
CUCP user or dev CUCP is a flexible system for small chunks of regular contribution - pick this if you have only 1..4 hours a week for contributing; anything else below takes more time. +
video user, video video editing - edit a tutorial video from an already recorded narration audio, a written script and an already recorded raw desktop capture video +
validation user reference output valudation (gerber and other formats) +
tutorial user user guide/tutorial projects in the pool +
doc user, html write sections of user documentation (generic) +
icons designer icons, other graphical elements for the GTK HID +
atest C/beginner program automated test cases +
rosetta scripting port example scripts to your favorite language (more details) +
fungw_pkg packaging packaging fungw for your favorite distro (more details) +
script_pkg packaging packaging libmawk, funlisp, estutter for your favorite distro (more details) +
actionw C action wrapper programming (more details) + +
+ + Index: tags/2.3.0/doc/help_details.html =================================================================== --- tags/2.3.0/doc/help_details.html (nonexistent) +++ tags/2.3.0/doc/help_details.html (revision 33253) @@ -0,0 +1,78 @@ + + + + pcb-rnd - help wanted + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +

pcb-rnd - help wanted - details

+ +

porting example scripts

+

+The rosetta scripts start with an awk script, because awk is my favorite +language. When the awk version is tested out and the documentation +finalized, the script needs to be ported to different languages. The +porting is line-by-line, becuase we want to have all scripts do the same +and look the same, that's how it's easy to compare them. +

+If you have a favorite language, you could join porting example scripts to +that language. +

+Requirements: knowing your scripting language, system-wide fungw +installation, pcb-rnd from svn. + +

packaging fungw for your favorite distro

+

+At the moment fungw has no packaging coverage. Because we use fungw as the +action infrastructure, we have a minimal (no-script) version embedded in +src_3rd/ and scconfig already has the logics for choosing a system +installed version over the local version when avaialble. +

+To make system installs more wide-spread, we need OS packages, preferrably +official packages in as many systems as possible. Fungw is small: the core +lib and all existing engines (~ script language bindings) take up 4k sloc +total). The only challange is that we need to have a modular packaging: a +core package and one package per script language binding, to avoid the +core package depending on 6..8 scripting engines. +

+Requirements: knowing your favorite distro's packaging model + + +

packaging libmawk, funlisp, estutter

+

+These three scripting language libs are relatively small (funlisp is even +tiny), and unlike many popular languages they come with a nice, generic +API. Unfortunately they are not widely known so we lack OS packages. They +are generally easy to package. +

+Requirements: knowing your favorite distro's packaging model + +

action wrapper programming

+

+Most of our API in pcb-rnd are good, old-fashioned, raw C APIs. Which +means they are currently unaccessible to scripts. To make them accessible, +we need to write action wrappers. Such an action wrapper is usually +simple, as 90% of the time we want to expose the very same API, +parameter-to-parameter, in a coordinated effort. +

+Requirements: intermediate C knowledge, willing to learn the fungw API, +willing to use svn and IRC + + Index: tags/2.3.0/doc/index.html =================================================================== --- tags/2.3.0/doc/index.html (nonexistent) +++ tags/2.3.0/doc/index.html (revision 33253) @@ -0,0 +1,133 @@ + + + + pcb-rnd - main + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +
+ + +
+

Summary

+ +
+
[pcb-rnd logo]pcb-rnd
+
+ is a free/open source, flexible, modular Printed Circuit Board editor +

for design of professional and hobby boards. +

is feature-rich and compatible +

has a long history, fast paced development, and big plans. +

is part of the coralEDA ecosystem. + + + +

Version Control svn://svn.repo.hu/pcb-rnd/trunk (mirrors) +
Download source releases | binary releases (windows) +
Comments, feedback, patches live chat with the developer
or contact the lead developer
Mailing list: pcb-rnd list.repo.hu (send a mail with subject: subscribe; may fail with gmail) (archives) (privacy policy) +
Contribution and support + How to join or contribute +
We are looking for help and sponsoration/donation. +
A major supporter is NLnet +
Do you have a feature request? + +
Key features + editor for multilayer Printed Circuit Boards +
scriptable in 10+ different scripting languages +
parametric footprint generation, web footprints +
modular code with a flexible plugin system +
fits well in a UNIXy workflow +
supports CLI and server applications +
active development, frequent releases +
friendly and efficient developer and user community +
powerful, user scriptable Design Rule Checker +
predictable development cycles +
compatible with KiCad and gEDA/PCB, understands Eagle and Protel/Autotrax file formats + +
Supported platforms + +
+ Linux desktop (various distributions, from source) +
official packages in Debian, Ubuntu, Fedora, Mageia, Kali, Parrot, PureOS, Raspbian (full list) +
Mac OS X +
Windows (7, 8, 10) +
IRIX 5.3 +
OpenBSD +
(Likely: any 90's UNIX system with motif) +
Screen resolution as small as 800x600 +
GUI options: motif/lesstif, gtk-gdk, gtk-gl +
+ + screenshot of pcb-rnd running on Debian GNU/Linux +
+
+ + +
+ + + +

What is -rnd?

+
+ + + +
RespoNsive Developers + Developers try to respond on user needs, adding features that are actually needed by current users. +
+ +

+ + +
+ Response Not Delayed + Bugreports, user requests and patches submitted are answered ASAP. There are no patches bitrotting for months. There are no forgotten bugreports. +
+ +

+ + + +
Research
&
Development
+
+
+ Rázós,
Nehéz
Döntések
(Brave, hard decisions) +
There is a constant experimentation with new features and directions. We are willing to try strange/unusual ideas without risking the stability of the daily workflow. +
+ +

+ + + +
Rants
Now
Dissipating
+
Instead of talking and ranting a lot about what could work better, we just sit down and make it work better. +
+ +

+ + + +
Rather
Nicely
Decentralized
+
Slim, generic core; most of the code organized in replacable plugins. Most plugins depend only on the core. +
+

+ + + Index: tags/2.3.0/doc/irc.html =================================================================== --- tags/2.3.0/doc/irc.html (nonexistent) +++ tags/2.3.0/doc/irc.html (revision 33253) @@ -0,0 +1,48 @@ + + + + pcb-rnd - IRC + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-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/2.3.0/doc/keys.html =================================================================== --- tags/2.3.0/doc/keys.html (nonexistent) +++ tags/2.3.0/doc/keys.html (revision 33253) @@ -0,0 +1,980 @@ + + + + + + Key to action bindings + + + + + +

Key to action bindings

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
key pcb-menu-default.lht +
+ + Zoom In 20%
Zoom(-1.2) +
, + Cycle object being dragged
CycleDrag() +
- + Zoom Out 20%
Zoom(+1.2) +
. + 'All-direction' lines
conf(toggle, editor/all_direction_lines, design) +
0 + Select Layer 10
SelectLayer(10) +
0-alt + Select Layer 20
SelectLayer(20) +
0-alt-ctrl + Toggle Layer 20
ToggleView(20) +
0-ctrl + Toggle Layer 10
ToggleView(10) +
1 + Select Layer 1
SelectLayer(1) +
1-alt + Select Layer 11
SelectLayer(11) +
1-alt-ctrl + Toggle Layer 11
ToggleView(11) +
1-ctrl + Toggle Layer 1
ToggleView(1) +
2 + Select Layer 2
SelectLayer(2) +
2-alt + Select Layer 12
SelectLayer(12) +
2-alt-ctrl + Toggle Layer 12
ToggleView(12) +
2-ctrl + Toggle Layer 2
ToggleView(2) +
3 + Select Layer 3
SelectLayer(3) +
3-alt + Select Layer 13
SelectLayer(13) +
3-alt-ctrl + Toggle Layer 13
ToggleView(13) +
3-ctrl + Toggle Layer 3
ToggleView(3) +
4 + Select Layer 4
SelectLayer(4) +
4-alt + Select Layer 14
SelectLayer(14) +
4-alt-ctrl + Toggle Layer 14
ToggleView(14) +
4-ctrl + Toggle Layer 4
ToggleView(4) +
5 + Select Layer 5
SelectLayer(5) +
5-alt + Select Layer 15
SelectLayer(15) +
5-alt-ctrl + Toggle Layer 15
ToggleView(15) +
5-ctrl + Toggle Layer 5
ToggleView(5) +
6 + Select Layer 6
SelectLayer(6) +
6-alt + Select Layer 16
SelectLayer(16) +
6-alt-ctrl + Toggle Layer 16
ToggleView(16) +
6-ctrl + Toggle Layer 6
ToggleView(6) +
7 + Select Layer 7
SelectLayer(7) +
7-alt + Select Layer 17
SelectLayer(17) +
7-alt-ctrl + Toggle Layer 17
ToggleView(17) +
7-ctrl + Toggle Layer 7
ToggleView(7) +
8 + Select Layer 8
SelectLayer(8) +
8-alt + Select Layer 18
SelectLayer(18) +
8-alt-ctrl + Toggle Layer 18
ToggleView(18) +
8-ctrl + Toggle Layer 8
ToggleView(8) +
9 + Select Layer 9
SelectLayer(9) +
9-alt + Select Layer 19
SelectLayer(19) +
9-alt-ctrl + Toggle Layer 19
ToggleView(19) +
9-ctrl + Toggle Layer 9
ToggleView(9) +
: + Command Entry
Command() +
[ + Previous grid
Grid(down) +
\ + Full screen
fullscreen(toggle) +
/ + Cycle line clip/refraction
Display(CycleClip) +
] + Next grid
Grid(up) +
a
 a +
Start routing an arc
Tool(Save); Tool(arc); Tool(Press) +
a
 b
  f
    +
Replace footprint
ReplaceFootprint() +
a
 b
  s
    +
Swap nets on two selected pins
net(swap) +
a
 b
  x +
netlist patch for back annotation
SavePatch() +
a
 d
  a
    +
Disperse all subcircuits
DisperseElements(All) +
a
 d
  s
    +
Disperse selected subcircuits
DisperseElements(Selected) +
a
 l +
Start routing a line
Tool(Save); Tool(line); Tool(Press) +
a
 m +
Place mark
MarkCrosshair() +
a
 o
  a
    +
Auto-Optimize
djopt(auto) +
a
 o
  d
    +
Debumpify
djopt(debumpify) +
a
 o
  m
    +
Miter
djopt(miter) +
a
 o
  n
    +
Vianudge
djopt(vianudge) +
a
 o
  o
    +
Ortho pull
djopt(orthopull) +
a
 o
  p
    +
Puller
Puller() +
a
 o
  s
    +
Simple optimization
djopt(simple) +
a
 o
  t
    +
Viatrim
djopt(viatrim) +
a
 o
  u
    +
Unjaggy
djopt(unjaggy) +
a
 p
  s
    +
Auto-place selected subcircuits
AutoPlaceSelected() +
a
 r
  a
    +
Auto-route all rats
AutoRoute(AllRats) +
a
 r
  r
    +
Rip up all auto-routed tracks
RipUp(All) +
a
 r
  s
    +
Auto-route selected rats
AutoRoute(SelectedRats) +
a
 r
  t
    +
Rip up selected auto-routed tracks
RipUp(Selected) +
a
 v +
Place via
Tool(Save); Tool(via); Tool(Press); Tool(Restore) +
a
 w +
Place mark
MarkCrosshair() +
a
 x
   +
Design Rule Checker
DRC() +
b
 1
   +
Select Buffer #1
PasteBuffer(1) +
b
 2
   +
Select Buffer #2
PasteBuffer(2) +
b
 3
   +
Select Buffer #3
PasteBuffer(3) +
b
 4
   +
Select Buffer #4
PasteBuffer(4) +
b
 5
   +
Select scratchpad
PasteBuffer(5) +
b
 b
   +
Layer bindings...
LayerBinding(buffer) +
b
 c
  c
    +
Clear buffer
PasteBuffer(Clear) +
b
 c
  e +
Convert buffer to extended object...
ExtobjConvFrom(buffer, @gui); Tool(buffer) +
b
 c
  p +
Convert buffer to padstack
PadstackConvert(buffer); Tool(buffer) +
b
 c
  s +
Convert buffer to subcircuit
PasteBuffer(ConvertSubc) +
b
 f
  l
    +
Load buffer content from file
PasteBuffer(LoadAll) +
b
 f
  s
    +
Save buffer content to file
PasteBuffer(SaveAll) +
b
 m
  l +
Mirror buffer (left/right)
Tool(buffer); PasteBuffer(Rotate,1); PasteBuffer(Mirror); PasteBuffer(Rotate,3) +
b
 m
  u +
Mirror buffer (up/down)
Tool(buffer); PasteBuffer(Mirror) +
b
 n +
Normalize
Tool(buffer); PasteBuffer(Rotate,1); PasteBuffer(Normalize) +
b
 r
  a +
Arbitrarily Rotate Buffer
Tool(buffer); FreeRotateBuffer() +
b
 r
  l +
Rotate buffer 90 deg CCW (left)
Tool(buffer); PasteBuffer(Rotate,1) +
b
 r
  r +
Rotate buffer 90 deg CW (right)
Tool(buffer); PasteBuffer(Rotate,3) +
b
 s
  b +
Break buffer subcircuits to pieces
PasteBuffer(Restore) +
b
 s
  l
   d +
in multiple footprint files
SaveLib(dir, buffer) +
b
 s
  l
   f +
in a single lib file
SaveLib(file, buffer) +
b
 s
  p +
Break buffer padstacks to pieces
PadstackBreakup(buffer) +
b
 s
  s +
Save buffer subcircuit to file
Save(PasteBuffer) +
c-ctrl
  +
Copy selection to buffer
GetXY(Click to set the snap point for this buffer); PasteBuffer(Clear); PasteBuffer(AddSelected); Unselect(All); Tool(buffer) +
c
 c
   +
Clear/reset lookup
Connection(Reset); Display(Redraw) +
c
 d
   +
Del/Remove Connected
Atomic(Save); Connection(Reset); Atomic(Restore); Unselect(All); Atomic(Restore); Connection(Find); Atomic(Restore); Select(Connection); Atomic(Restore); RemoveSelected(); Atomic(Restore); Connection(Reset); Atomic(Restore); Unselect(All); Atomic(Block) +
c
 e
   +
Erase rats nest
DeleteRats(AllRats) +
c
 f
   +
Find Connections
Connection(Reset); Connection(Find) +
c
 r-shift
   +
Optimize rats nest - autorouter
Atomic(Save); DeleteRats(AllRats); Atomic(Restore); AddRats(AllRats, manhattan); Atomic(Close) +
c
 r
   +
Optimize rats nest
Atomic(Save); DeleteRats(AllRats); Atomic(Restore); AddRats(AllRats); Atomic(Close) +
c
 s
   +
Select shortest rat
AddRats(Close) +
delete + Remove object
Tool(Save); Tool(remove); Tool(Press); Tool(Restore) +
down + Step Down
Cursor(Warp,0,1,grid) +
down-ctrl + Scroll Down
Scroll(down) +
down-shift + Step +Down
Cursor(Pan,0,50,view) +
e
 c +
Copy selection to buffer
GetXY(Click to set the snap point for this buffer); PasteBuffer(Clear); PasteBuffer(AddSelected); Unselect(All); Tool(buffer) +
e
 d +
Remove object
Tool(Save); Tool(remove); Tool(Press); Tool(Restore) +
e
 f +
Object flags...
FlagEdit() +
e
 g
  c +
Clearance +2 mil
ChangeClearSize(Object,+2,mil) +
e
 g
  c-shift +
Clearance -2 mil
ChangeClearSize(Object,-2,mil) +
e
 g
  d +
ChangeDrill +5 mil
ChangeDrillSize(Object,+5,mil) +
e
 g
  d-shift +
ChangeDrill -5 mil
ChangeDrillSize(Object,-5,mil) +
e
 g
  g +
Edit padstack geometry/prototype
padstackedit +
e
 g
  s +
ChangeSize +5 mil
ChangeSize(Object,+5,mil) +
e
 g
  s-shift +
ChangeSize -5 mil
ChangeSize(Object,-5,mil) +
e
 g
  y +
ChangeSizes to Route style
ChangeSizes(Object,style,mil) +
e
 i +
Flip Object
Flip(Object) +
e
 j +
ChangeJoin Object
ChangeJoin(Object) +
e
 l +
Move to current layer
MoveToCurrentLayer(Object) +
e
 o +
Change font...
FontSel(Object) +
e
 p +
Object Properties...
PropEdit(selection) +
e
 r +
Change refdes
ChangeName(Refdes) +
e
 s
  b +
Layer bindings...
LayerBinding() +
e
 s
  e +
External editor...
GetXY(Click on the subcircuit to edit); extedit(object) +
e
 s
  r +
Refdes
ChangeName(Subc) +
e
 s
  s +
Set Same Style
SetSame() +
e
 s
  x +
Convert to extended object...
ExtobjConvFrom(Object, @gui) +
e
 t +
Edit text...
ChangeName(Object) +
e
 v +
Paste buffer to layout
Tool(buffer) +
e
 x +
Cut selection to buffer
GetXY(Click to set the snap point for this buffer); PasteBuffer(Clear); PasteBuffer(MoveSelected); Tool(buffer) +
e
 y
   +
Cycle object being dragged
CycleDrag() +
enter + Click (left)
Tool(Press); Tool(Release) +
escape + Cancel
Tool(Escape) +
f1 + Via
Tool(via) +
f10 + Thermal
Tool(thermal) +
f11 + Arrow
Tool(arrow) +
f12 + Lock
Tool(lock) +
f2 + Line
Tool(line) +
f3 + Arc
Tool(arc) +
f4 + Text
Tool(text) +
f5 + Rectangle
Tool(rectangle) +
f6 + Polygon
Tool(poly) +
f7 + Buffer
Tool(buffer) +
f7-shift + Rotate buffer 90 deg CCW (left)
Tool(buffer); PasteBuffer(Rotate,1) +
f8 + Del/Remove
Tool(remove) +
f9 + Rotate
Tool(rotate) +
f
 a +
Save Layout As...
Save(LayoutAs) +
f
 c +
Export with CAM job...
cam() +
f
 e +
Export layout...
ExportGUI() +
f
 l +
Load layout...
Load(Layout) +
f
 n +
Start New Layout
New() +
f
 o +
Load layout...
Load(Layout) +
f
 p +
Print layout...
Print() +
f
 q +
Quit Program
Quit() +
f
 r +
Revert
Load(Revert,none) +
f
 s +
Save Layout
Save(Layout) +
f
 x
  p +
netlist patch for back annotation
SavePatch() +
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
Display(ToggleGrid) +
g
 v +
Enable visible grid
conf(toggle, editor/draw_grid, design) +
i
 a +
About...
About() +
i
 c
  c +
Calibrate Printer...
PrintCalibrate() +
i
 c
  i +
Data integrity check
Integrity() +
i
 c
  p +
Preferences...
preferences +
i
 c
  r +
Re-scan the footprint library
fp_rehash() +
i
 d +
Generate drill summary
Report(DrillReport) +
i
 f +
Report found padstacks
Report(FoundPins) +
i
 r +
Generate object report
ReportObject() +
insert + Insert Point
Tool(insert) +
j
 h +
Scroll Left
Scroll(left) +
j
 j +
Scroll Down
Scroll(down) +
j
 k +
Scroll Up
Scroll(up) +
j
 l +
Scroll Right
Scroll(right) +
k
 h +
Step Left
Cursor(Warp,-1,0,grid) +
k
 j +
Step Down
Cursor(Warp,0,1,grid) +
k
 k +
Step Up
Cursor(Warp,0,-1,grid) +
k
 l +
Step Right
Cursor(Warp,1,0,grid) +
k
 r +
Click (right)
Tool(Release); Popup(popup-obj, obj-type) +
k
 space +
Click (left)
Tool(Press); Tool(Release) +
l
 h
   +
all layers off
ToggleView(all, vis, clear) +
l
 k +
Select previous layer
LayerByStack(Select, Prev) +
l
 l +
Select next layer
LayerByStack(Select, Next) +
l
 v
   +
all layers on
ToggleView(all, vis, set) +
left + Step Left
Cursor(Warp,-1,0,grid) +
left-ctrl + Scroll Left
Scroll(left) +
left-shift + Step +Left
Cursor(Pan,-50,0,view) +
m
 c
  c +
Crosshair shows style clearance
conf(toggle, editor/show_drc, design) +
m
 c
  o +
Orthogonal moves
conf(toggle, editor/orthogonal_moves, design) +
m
 c
  p +
Crosshair snaps to padstacks
conf(toggle, editor/snap_pin, design) +
m
 c
  s +
Crosshair snaps to off-grid points on lines
conf(toggle, editor/snap_offgrid_line, design) +
m
 d
  a +
Show autorouter trials
conf(toggle, editor/live_routing, design) +
m
 d
  c +
Check polygons
conf(toggle, editor/check_planes, design) +
m
 d
  d +
poly as-drawn frame annotation
conf(toggle, editor/as_drawn_poly, design) +
m
 d
  h +
Highlighting on line, arc points
conf(toggle, editor/highlight_on_point, design) +
m
 d
  o +
Object list popup
conf(toggle, editor/click_objlist, design) +
m
 d
  p +
Thin draw poly
conf(toggle, editor/thin_draw_poly, design) +
m
 d
  r +
Reset
+
m
 d
  t +
Thin draw
conf(toggle, editor/thin_draw, design) +
m
 d
  w +
Wireframe draw
conf(toggle, editor/wireframe_draw, design) +
m
 f
  h +
Hide floaters
conf(toggle, editor/hide_names, design) +
m
 f
  l +
Lock floaters
conf(toggle, editor/lock_names, design) +
m
 f
  o +
Only floaters
conf(toggle, editor/only_names, design) +
m
 k
  s +
Loose subcircuits (no subc lock)
subc(loose, toggle) +
m
 l
  + +
Line Tool size +5 mil
SetValue(LineSize,+5,mil) +
m
 l
  - +
Line Tool size -5 mil
SetValue(LineSize,-5,mil) +
m
 l
  a +
'All-direction' lines
conf(toggle, editor/all_direction_lines, design) +
m
 l
  c +
New lines, arcs clear polygons
conf(toggle, editor/clear_line, design) +
m
 l
  d +
Auto enforce style clearance
conf(toggle, editor/auto_drc, design) +
m
 l
  f +
Cycle line clip/refraction
Display(CycleClip) +
m
 l
  m +
Automatic trace merging
conf(toggle, editor/trace_auto_merge, design) +
m
 o
  b +
black current group
conf(toggle, appearance/black_current_group, design) +
m
 o
  i +
Invisible-color on other groups
conf(toggle, appearance/invis_other_groups, design) +
m
 p
  c +
New polygons clear polygons
conf(toggle, editor/clear_polypoly, design) +
m
 p
  f +
New polygons are full ones
conf(toggle, editor/full_poly, design) +
m
 p
  i +
Polygon clip inhibit (toggle)
ClipInhibit(toggle) +
m
 r
  m +
Rubber band keeps middle line dir
conf(toggle, editor/rubber_band_keep_midlinedir, design) +
m
 r
  r +
Rubber band mode
conf(toggle, editor/rubber_band_mode, design) +
m
 t
  + +
Text Tool scale +10 mil
SetValue(TextScale,+10,mil) +
m
 t
  - +
Text Tool scale -10 mil
SetValue(TextScale,-10,mil) +
n-ctrl + Start New Layout
New() +
n
 c
  f
    +
claim net on found
ClaimNet(found) +
n
 c
  o
    +
claim net by object
ClaimNet(object) +
n
 c
  s
    +
claim net on selected
ClaimNet(selected) +
n
 l
  k
    +
Visual length, clear
NetLength(clear) +
n
 l
  l
    +
Netlist dialog, refresh lengths
NetlistDialog(); NetlistDialog(RefreshNetLens) +
n
 l
  o
    +
Visual length, from object
NetLength(object) +
p
 m
  p
    +
Manage plugins...
ManagePlugins() +
p
 m
  s
    +
Manage scripts...
BrowseScripts() +
p
 p
  c +
Polygon Close
Polygon(Close) +
p
 p
  p +
Polygon PreviousPoint
Polygon(PreviousPoint) +
q-ctrl + Quit Program
Quit() +
r
 r
  + +
Route radius +0.5
conf(delta, editor/route_radius, +0.5, design) +
r
 r
  - +
Route radius -0.5
conf(delta, editor/route_radius, -0.5, design) +
r
 r
  m +
Route radius -0.5
conf(delta, editor/route_radius, -0.5, design) +
r
 r
  p +
Route radius +0.5
conf(delta, editor/route_radius, +0.5, design) +
right + Step Right
Cursor(Warp,1,0,grid) +
right-ctrl + Scroll Right
Scroll(right) +
right-shift + Step +Right
Cursor(Pan,50,0,view) +
s-ctrl + Save Layout
Save(Layout) +
s-ctrl-shift + Save Layout As...
Save(LayoutAs) +
s
 a
  a
    +
Select all visible objects
Select(All) +
s
 a
  c
    +
Select all found objects
Select(Connection) +
s
 b
  p +
Break selection padstack to pieces
PadstackBreakup(selected) +
s
 b
  s +
Break selection subcircuits to pieces
PasteBuffer(Push); PasteBuffer(5); PasteBuffer(Clear); PasteBuffer(AddSelected); RemoveSelected(); PasteBuffer(Restore); PasteBuffer(ToLayout, crosshair); PasteBuffer(Clear); PasteBuffer(Pop) +
s
 c
  e
    +
Convert selection to extended object...
ExtobjConvFrom(Selected, @gui) +
s
 c
  p
    +
Convert selection to padstack
PadstackConvert(selected); Tool(buffer) +
s
 c
  s
    +
Convert selection to subcircuit
Select(ConvertSubc) +
s
 f
   +
Move selected subcircuits to other side
Flip(SelectedElements) +
s
 i
   +
Invert selection
Select(Invert) +
s
 l
   +
Move selected objects to current layer
MoveToCurrentLayer(Selected) +
s
 r
   +
Remove selected objects
RemoveSelected() +
s
 s
   +
Advanced search and select
SearchDialog() +
s
 u
  a
    +
Unselect all objects
Unselect(All) +
s
 u
  c
    +
Unselect all found objects
Unselect(Connection) +
space + Arrow
Tool(arrow) +
t
 a +
Arc
Tool(arc) +
t
 b +
Buffer
Tool(buffer) +
t
 c +
Copy
Tool(copy) +
t
 d +
Del/Remove
Tool(remove) +
t
 e +
Thermal
Tool(thermal) +
t
 h +
Polygon Hole
Tool(polyhole) +
t
 i +
Insert Point
Tool(insert) +
t
 k +
Lock
Tool(lock) +
t
 l +
Line
Tool(line) +
t
 m +
Move
Tool(move) +
t
 n +
Arrow
Tool(arrow) +
t
 o +
Rotate
Tool(rotate) +
t
 p +
Polygon
Tool(poly) +
t
 r +
Rectangle
Tool(rectangle) +
t
 t +
Text
Tool(text) +
t
 v +
Via
Tool(via) +
tab + Flip up/down
SwapSides(V) +
tab-ctrl + Spin 180 degrees
SwapSides(R) +
tab-ctrl-shift + Swap Sides
SwapSides() +
tab-shift + Flip left/right
SwapSides(H) +
u
 c +
Clear undo-buffer
Undo(ClearList) +
u
 d
   +
Undo dialog (for debugging)
UndoDialog() +
u
 r +
Redo last undone operation
Redo() +
u
 u +
Undo last operation
Undo() +
up + Step Up
Cursor(Warp,0,-1,grid) +
up-ctrl + Scroll Up
Scroll(up) +
up-shift + Step +Up
Cursor(Pan,0,-50,view) +
v
 c +
Center cursor
Center() +
v
 f +
Zoom Extents
Zoom() +
v
 n +
Show padstack numbers in a subc
Display(PinOrPadName) +
v
 r
  g +
Reset GUI
+
v
 r
  v +
Reset View
+
v
 s
  c +
user configured
Display(SubcID) +
v
 s
  f +
footprint
Display(SubcID,"%a.footprint%") +
v
 s
  r +
refdes
Display(SubcID, "%a.refdes%") +
v
 s
  s +
refdes+value
Display(SubcID,"%a.refdes%\\n%a.value%") +
v
 s
  v +
value
Display(SubcID,"%a.value%") +
v
 t
  c +
user configured
Display(TermID) +
v
 t
  n +
name
Display(TermID, "%a.name%") +
v
 t
  s +
term+name
Display(TermID, "%a.term%,%a.name%") +
v
 t
  t +
term
Display(TermID, "%a.term%") +
w
 a +
About...
About() +
w
 d +
DRC Check
DRC() +
w
 f +
Font selector
FontSel() +
w
 l +
Library
LibraryDialog() +
w
 m +
Message Log
LogDialog() +
w
 n +
Netlist
NetlistDialog() +
w
 p +
Pinout
Display(Pinout) +
y-ctrl + Redo last undone operation
Redo() +
z-ctrl + Undo last operation
Undo() +
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) +
| + Wireframe draw
conf(toggle, editor/wireframe_draw, design) +
+ + Index: tags/2.3.0/doc/license.html =================================================================== --- tags/2.3.0/doc/license.html (nonexistent) +++ tags/2.3.0/doc/license.html (revision 33253) @@ -0,0 +1,56 @@ + + + + pcb-rnd - license + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +

pcb-rnd - license

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

+Pcb-rnd started as a fork of gEDA/PCB thus inherited its GPL2+ license. +See file +trunk/COPYING for more details on the license terms. Pcb-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: pcb-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 not possible to +change pcb-rnd's license to anything else unless all past developers agree +(but there's not even a index of all the names!). It is possible to request +relicensing of the files that are brand new in pcb-rnd (they are all marked +in the copyright banner on the top of the file) - this requires the agreement +of all copyright holders listed in the file, and wouldn't affect other files. +Same rules apply for mini-libs. + + + + Index: tags/2.3.0/doc/mac.txt =================================================================== --- tags/2.3.0/doc/mac.txt (nonexistent) +++ tags/2.3.0/doc/mac.txt (revision 33253) @@ -0,0 +1,30 @@ +State on MacOSX +~~~~~~~~~~~~~~~ + +Source releases starting from 1.1.0 should compile and run out-of-the-box. + +Requirements for GUI: x11 and gtk+ + - X11 server and client libraries for OS X are available from the XQuartz + download and install + - gtk+ is available from brew + * brew install dependencies (gtk+ and libgd) with the following commands + brew install libgd + brew install gtk+ + brew install pkg-config + * if you want to use gEDA with PCB-RND you may want to install it as well + via brew + brew install homebrew/science/geda-gaf + +Known issues: + - application window opens behind other windows; it seems to be a gtk bug + that can not be worked around from the application + - slow rendering and error messages about invalid numerics on the console + +Considerations listed in ../INSTALL apply. + +pcb-rnd is reported to work at least on the following versions: + +macOS xquartz +---------------------------- +10.14.3 majove 2.7.11 + Index: tags/2.3.0/doc/man/Makefile =================================================================== --- tags/2.3.0/doc/man/Makefile (nonexistent) +++ tags/2.3.0/doc/man/Makefile (revision 33253) @@ -0,0 +1,65 @@ +# This Makefile is a plain old hand written one; all configuration settings +# are included from $(ROOT)/Makefile.conf which is scconfig generated +ROOT=../.. + +IN=pcb-rnd.1.mml pcb-prj2lht.1.mml fp2preview.1.mml fp2subc.1.mml bxl2txt.1.mml txt2bxl.1.mml pcb-rnd-svg.1.mml +OUT_HTML = pcb-rnd.1.html pcb-prj2lht.1.html fp2preview.1.html fp2subc.1.html bxl2txt.1.html txt2bxl.1.html pcb-rnd-svg.1.html +OUT_MAN1 = pcb-rnd.1 pcb-prj2lht.1 fp2preview.1 fp2subc.1 bxl2txt.1 txt2bxl.1 pcb-rnd-svg.1 +OUT_LINT = pcb-rnd.1.lint pcb-prj2lht.1.lint fp2preview.1.lint fp2subc.1.lint bxl2txt.1.lint txt2bxl.1.lint pcb-rnd-svg.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 - pcb-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_all: + $(SCCBOX) mkdir -p "$(MAN1DIR)" + $(SCCBOX) $(HOW) "pcb-rnd.1" "$(MAN1DIR)/pcb-rnd.1" + $(SCCBOX) $(HOW) "pcb-prj2lht.1" "$(MAN1DIR)/pcb-prj2lht.1" + $(SCCBOX) $(HOW) "gsch2pcb-rnd.1" "$(MAN1DIR)/gsch2pcb-rnd.1" + $(SCCBOX) $(HOW) "fp2preview.1" "$(MAN1DIR)/fp2preview.1" + $(SCCBOX) $(HOW) "fp2subc.1" "$(MAN1DIR)/fp2subc.1" + $(SCCBOX) $(HOW) "pcb-rnd-svg.1" "$(MAN1DIR)/pcb-rnd-svg.1" + $(SCCBOX) $(HOW) "bxl2txt.1" "$(MAN1DIR)/bxl2txt.1" + $(SCCBOX) $(HOW) "txt2bxl.1" "$(MAN1DIR)/txt2bxl.1" + +install: + $(MAKE) install_all HOW="install -f" + +linstall: + $(MAKE) install_all HOW="linstall -f" + +uninstall: + $(MAKE) install_all HOW="uninstall" + +include $(ROOT)/Makefile.conf + Index: tags/2.3.0/doc/man/README =================================================================== --- tags/2.3.0/doc/man/README (nonexistent) +++ tags/2.3.0/doc/man/README (revision 33253) @@ -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/2.3.0/doc/man/bxl2txt.1 =================================================================== --- tags/2.3.0/doc/man/bxl2txt.1 (nonexistent) +++ tags/2.3.0/doc/man/bxl2txt.1 (revision 33253) @@ -0,0 +1,30 @@ +.\" pcb-rnd - manual +.\" Copyright (C) 2016 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 bxl2txt 1 2020-04-07 "" "pcb-rnd manual" +.SH NAME +bxl2txt - decode a binary BXL file and dump the plain text content +.SH SYNPOSIS +.nf +.sp +\fBbxl2txt < \fIinfile.bxl\fB > \fIoutfile.txt\fB +.fi +.SH DECSRIPTION + +.BR bxl2txt +reads and decodes a binary bxl file in its standard input and prints the plain text content on its standard output. Index: tags/2.3.0/doc/man/bxl2txt.1.html =================================================================== --- tags/2.3.0/doc/man/bxl2txt.1.html (nonexistent) +++ tags/2.3.0/doc/man/bxl2txt.1.html (revision 33253) @@ -0,0 +1,62 @@ + + + +bxl2txt - pcb-rnd manual + + + + +
bxl2txt 1 + 2020-04-07 + pcb-rnd manual +
+ + + +

NAME

+
+bxl2txt - decode a binary BXL file and dump the plain text content +
+ +

SYNPOSIS

+
+

+bxl2txt < infile.bxl > outfile.txt + + + +

+ +

DESCRIPTION

+
+bxl2txt reads and decodes a binary bxl file in its standard input and prints the plain text content on its standard output. +
+

+ + +
bxl2txt 1 + 2020-04-07 + pcb-rnd manual +
+ + + Index: tags/2.3.0/doc/man/bxl2txt.1.mml =================================================================== --- tags/2.3.0/doc/man/bxl2txt.1.mml (nonexistent) +++ tags/2.3.0/doc/man/bxl2txt.1.mml (revision 33253) @@ -0,0 +1,10 @@ +bxl2txt +1 +2020-04-07 + + bxl2txt - decode a binary BXL file and dump the plain text content + bxl2txt < infile.bxl > outfile.txt + + +bxl2txt reads and decodes a binary bxl file in its standard +input and prints the plain text content on its standard output. Index: tags/2.3.0/doc/man/copyright.mml =================================================================== --- tags/2.3.0/doc/man/copyright.mml (nonexistent) +++ tags/2.3.0/doc/man/copyright.mml (revision 33253) @@ -0,0 +1,21 @@ + +pcb-rnd - manual\n +Copyright (C) 2016 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/2.3.0/doc/man/fp2preview.1 =================================================================== --- tags/2.3.0/doc/man/fp2preview.1 (nonexistent) +++ tags/2.3.0/doc/man/fp2preview.1 (revision 33253) @@ -0,0 +1,61 @@ +.\" pcb-rnd - manual +.\" Copyright (C) 2016 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 fp2preview 1 2019-10-01 "" "pcb-rnd manual" +.SH NAME +fp2preview - generate a preview for a library footprint +.SH SYNPOSIS +.nf +.sp +\fBfp2preview [\fIoptions\fB] [\fIinputfile\fB] +.fi +.SH DECSRIPTION + +.BR fp2preview +invokes pcb-rnd to generate a preview image of a library footprint. Its main use is to have a automated, light-weight footprint preview generator using a static linked pcb-rnd (e.g. on web servers). +.PP + +.SH OPTIONS + + +.TP + +.B --photo +draw the footprint in "photo realistic mode" +.TP + +.B -p +same as --photo +.TP + +.B --grid unit +set grid unit e.g. to mm or mil +.TP + +.B -g unit +same as --grid +.TP + +.B --mm +use an mm grid instead of a mil grid; shorthand for -g mm +.TP + +.B --annotation types +turn on annotation types; types is a string that may consist "pins" for pin/pad numbers, "dimname" and "dimvalue" for dimension names and values and "background" for drawing a background under annotation text +.PP + Index: tags/2.3.0/doc/man/fp2preview.1.html =================================================================== --- tags/2.3.0/doc/man/fp2preview.1.html (nonexistent) +++ tags/2.3.0/doc/man/fp2preview.1.html (revision 33253) @@ -0,0 +1,98 @@ + + + +fp2preview - pcb-rnd manual + + + + +
fp2preview 1 + 2019-10-01 + pcb-rnd manual +
+ + + +

NAME

+
+fp2preview - generate a preview for a library footprint +
+ +

SYNPOSIS

+
+

+fp2preview [options] [inputfile] + + + +

+ +

DESCRIPTION

+
+fp2preview invokes pcb-rnd to generate a preview image of a library footprint. Its main use is to have a automated, light-weight footprint preview generator using a static linked pcb-rnd (e.g. on web servers). +

+ + +

+ + +

OPTIONS

+
+ + + + + + + + + + + + + + + +
--photo + draw the footprint in "photo realistic mode" +
-p + same as --photo +
--grid unit + set grid unit e.g. to mm or mil +
-g unit + same as --grid +
--mm + use an mm grid instead of a mil grid; shorthand for -g mm +
--annotation types + turn on annotation types; types is a string that may consist "pins" for pin/pad numbers, "dimname" and "dimvalue" for dimension names and values and "background" for drawing a background under annotation text +
+
+

+ + +
fp2preview 1 + 2019-10-01 + pcb-rnd manual +
+ + + Index: tags/2.3.0/doc/man/fp2preview.1.mml =================================================================== --- tags/2.3.0/doc/man/fp2preview.1.mml (nonexistent) +++ tags/2.3.0/doc/man/fp2preview.1.mml (revision 33253) @@ -0,0 +1,50 @@ +fp2preview +1 +2019-10-01 + + fp2preview - generate a preview for a library footprint + fp2preview [options] [inputfile] + + +fp2preview invokes pcb-rnd to generate a preview image of a +library footprint. Its main use is to have a automated, light-weight footprint +preview generator using a static linked pcb-rnd (e.g. on web servers). +

+ + + + + + + --photo + draw the footprint in "photo realistic mode" + + + -p + same as --photo + + + + --grid unit + set grid unit e.g. to mm or mil + + + -g unit + same as --grid + + + + --mm + use an mm grid instead of a mil grid; shorthand for -g mm + + + + --annotation types + turn on annotation types; types is a string that may consist + "pins" for pin/pad numbers, "dimname" and "dimvalue" for dimension + names and values and "background" for drawing a background under + annotation text + + + + Index: tags/2.3.0/doc/man/fp2subc.1 =================================================================== --- tags/2.3.0/doc/man/fp2subc.1 (nonexistent) +++ tags/2.3.0/doc/man/fp2subc.1 (revision 33253) @@ -0,0 +1,65 @@ +.\" pcb-rnd - manual +.\" Copyright (C) 2016 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 fp2subc 1 2018-04-08 "" "pcb-rnd manual" +.SH NAME +fp2subc - convert any footprint into a pcb-rnd subcircuit +.SH SYNPOSIS +.nf +.sp +\fBfp2subc [\fIoptions\fB] \fIinfile\fB [\fIoutfile\fB] +.fi +.SH DECSRIPTION + +.BR fp2subc +executes pcb-rnd in batch mode to load a footprint (typically specified in an alien format) and save it as a native pcb-rnd subcircuit. The script is useful for mass-converting old footprint libraries. +.PP +If \fIoutfile\fR is not specified, its name is guessed from \fIinfile\fR +.SH OPTIONS + + +.TP + +.B --lib +\fIinfile\fR is not a path but a footprint name that should be searched in the library +.TP + +.B -l +same as --lib +.TP + +.B --pcb-rnd exepath +run exepath for invoking pcb-rnd (default is "pcb-rnd", which depends on $PATH) +.TP + +.B -p exepath +same as --pcb-rnd +.TP + +.B --debugger exepath +insert exepath before pcb-rnd on the command line; useful for running the process e.g. in valgrind +.TP + +.B -d exepath +same as --debugger +.TP + +.B -c key=val +pass on a -c key=val CLI config setting to pcb-rnd; useful for setting up library paths +.PP + Index: tags/2.3.0/doc/man/fp2subc.1.html =================================================================== --- tags/2.3.0/doc/man/fp2subc.1.html (nonexistent) +++ tags/2.3.0/doc/man/fp2subc.1.html (revision 33253) @@ -0,0 +1,102 @@ + + + +fp2subc - pcb-rnd manual + + + + +
fp2subc 1 + 2018-04-08 + pcb-rnd manual +
+ + + +

NAME

+
+fp2subc - convert any footprint into a pcb-rnd subcircuit +
+ +

SYNPOSIS

+
+

+fp2subc [options] infile [outfile] + + + +

+ +

DESCRIPTION

+
+fp2subc executes pcb-rnd in batch mode to load a footprint (typically specified in an alien format) and save it as a native pcb-rnd subcircuit. The script is useful for mass-converting old footprint libraries. +

+If outfile is not specified, its name is guessed from infile + +

+ + +

OPTIONS

+
+ + + + + + + + + + + + + + + + + +
--lib + infile is not a path but a footprint name that should be searched in the library +
-l + same as --lib +
--pcb-rnd exepath + run exepath for invoking pcb-rnd (default is "pcb-rnd", which depends on $PATH) +
-p exepath + same as --pcb-rnd +
--debugger exepath + insert exepath before pcb-rnd on the command line; useful for running the process e.g. in valgrind +
-d exepath + same as --debugger +
-c key=val + pass on a -c key=val CLI config setting to pcb-rnd; useful for setting up library paths +
+
+

+ + +
fp2subc 1 + 2018-04-08 + pcb-rnd manual +
+ + + Index: tags/2.3.0/doc/man/fp2subc.1.mml =================================================================== --- tags/2.3.0/doc/man/fp2subc.1.mml (nonexistent) +++ tags/2.3.0/doc/man/fp2subc.1.mml (revision 33253) @@ -0,0 +1,58 @@ +fp2subc +1 +2018-04-08 + + fp2subc - convert any footprint into a pcb-rnd subcircuit + fp2subc [options] infile [outfile] + + +fp2subc executes pcb-rnd in batch mode to load a footprint +(typically specified in an alien format) and save it as a native pcb-rnd +subcircuit. The script is useful for mass-converting old footprint +libraries. +

+If outfile is not specified, its name is guessed from +infile + + + + + + + --lib + infile is not a path but a footprint name that + should be searched in the library + + + -l + same as --lib + + + + --pcb-rnd exepath + run exepath for invoking pcb-rnd (default is "pcb-rnd", which + depends on $PATH) + + + -p exepath + same as --pcb-rnd + + + + --debugger exepath + insert exepath before pcb-rnd on the command line; useful + for running the process e.g. in valgrind + + + -d exepath + same as --debugger + + + + -c key=val + pass on a -c key=val CLI config setting to pcb-rnd; useful for + setting up library paths + + + + Index: tags/2.3.0/doc/man/gsch2pcb-rnd.1 =================================================================== --- tags/2.3.0/doc/man/gsch2pcb-rnd.1 (nonexistent) +++ tags/2.3.0/doc/man/gsch2pcb-rnd.1 (revision 33253) @@ -0,0 +1,134 @@ +.TH gsch2pcb-rnd 1 "September 25th, 2013" "gEDA Project" 1.8.2.20130925 +.SH NAME +gsch2pcb-rnd - Update pcb-rnd layouts from gEDA/gaf schematics +.SH SYNOPSIS +\fBgsch2pcb-rnd\fR [\fIOPTION\fR ...] {\fIPROJECT\fR | \fIFILE\fR ...} +.SH DESCRIPTION +.PP +\fBgsch2pcb-rnd\fR is a frontend to \fBgnetlist\fR(1) which aids in +creating and updating \fBpcb-rnd\fR(1) printed circuit board layouts based +on a set of electronic schematics created with \fBgschem\fR(1). + +.PP +Instead of specifying all options and input gEDA schematic \fIFILE\fRs +on the command line, \fBgsch2pcb-rnd\fR can use a \fIPROJECT\fR file +instead. + +.PP +\fBgsch2pcb-rnd\fR first runs \fBgnetlist\fR(1) with the `PCB' backend to +create a `.net' file containing a \fBpcb-rnd\fR(1) formatted netlist for +the design. + +.PP +The second step is to run \fBgnetlist\fR(1) again with the `gsch2pcb-rnd' +backend to find any \fBM4\fR(1) elements required by the schematics. +Any missing elements are found by searching a set of file element +directories. If no `.pcb' file exists for the design yet, it is +created with the required elements; otherwise, any new elements +are output to a `.new.pcb' file. + +.PP +If a `.pcb' file exists, it is searched for elements with a +non-empty element name with no matching schematic symbol. These +elements are removed from the `.pcb' file, with a backup in a +`.pcb.bak' file. + +.PP +Finally, \fBgnetlist\fR(1) is run a third time with the `pcbpins' +backend to create a `.cmd' file. This can be loaded into +\fBpcb-rnd\fR(1) to rename all pin names in the PCB layout to match the +schematic. + +.SH OPTIONS +.TP 8 +\fB-o\fR, \fB--output-name\fR=\fIBASENAME\fR +Use output filenames `\fIBASENAME\fR.net', `\fIBASENAME\fR.pcb', and +`\fIBASENAME\fR.new.pcb'. By default, the basename of the first +schematic file in the list of input files is used. +.TP 8 +\fB-d\fR, \fB--elements-dir\fR=\fIDIRECTORY\fR +Add \fIDIRECTORY\fR to the list of directories to search for PCB file +elements. +.TP 8 +\fB-r\fR, \fB--remove-unfound\fR +Don't include references to unfound elements in the generated `.pcb' +files. Use if you want \fBpcb-rnd\fR(1) to be able to load the +(incomplete) `.pcb' file. This is enabled by default. +.TP 8 +\fB-k\fR, \fB--keep-unfound\fR +Keep include references to unfound elements in the generated `.pcb' +files. Use if you want to hand edit or otherwise preprocess the +generated `.pcb' file before running \fBpcb\fR(1). +.TP 8 +\fB-p\fR, \fB--preserve\fR +Preserve elements in PCB files which are not found in the schematics. +Since elements with an empty element name (schematic "refdes") are +never deleted, this option is rarely useful. +.TP 8 +\fB--gnetlist\fR \fIBACKEND\fR +In addition to the default backends, run \fBgnetlist\fR(1) with `\-g +\fIBACKEND\fR', with output to `.\fIBACKEND\fR'. +.TP 8 +\fB--gnetlist-arg\fR \fIARG\fR +Pass \fIARG\fR as an additional argument to \fBgnetlist\fR(1). +.TP 8 +\fB--empty-footprint\fR \fINAME\fR +If \fINAME\fR is not `none', \fBgsch2pcb-rnd\fR will not add elements for +components with that name to the PCB file. Note that if the omitted +components have net connections, they will still appear in the netlist +and \fBpcb-rnd\fR(1) will warn that they are missing. +.TP 8 +\fB--fix-elements\fR +If a schematic component's `footprint' attribute is not equal to the +`Description' of the corresponding PCB element, update the +`Description' instead of replacing the element. +.TP 8 +\fB-q\fR, \fB--quiet\fR +Don't output information on steps to take after running \fBgsch2pcb-rnd\fR. +.TP 8 +\fB-v\fR, \fB--verbose\fR +Output extra debugging information. This option can be specified +twice (`\-v \-v') to obtain additional debugging for file elements. +.TP 8 +\fB-h\fR, \fB--help\fR +Print a help message. +.TP 8 +\fB-V\fR, \fB--version\fR +Print \fBgsch2pcb-rnd\fR version information. + +.SH PROJECT FILES +.PP +A \fBgsch2pcb-rnd\fR project file is a file (not ending in `.sch') +containing a list of schematics to process and some options. Any +long-form command line option can appear in the project file with the +leading `\-\-' removed, with the exception of `\-\-gnetlist-arg', +`\-\-fix-elements', `\-\-verbose', and `\-\-version'. Schematics should be +listed on a line beginning with `schematics'. +.PP +An example project file might look like: + +.nf + schematics partA.sch partB.sch + output-name design +.ad b + +.SH ENVIRONMENT +.TP 8 +.B GNETLIST +specifies the \fBgnetlist\fR(1) program to run. The default is +`gnetlist'. + +.SH AUTHORS +See the `AUTHORS' file included with this program. + +.SH COPYRIGHT +.nf +Copyright \(co 1999-2011 gEDA Contributors. License GPLv2+: GNU GPL +version 2 or later. Please see the `COPYING' file included with this +program for full details. +.PP +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +.SH SEE ALSO +\fBgschem\fR(1), \fBgnetlist\fR(1), \fBpcb-rnd\fR(1) Index: tags/2.3.0/doc/man/index.html =================================================================== --- tags/2.3.0/doc/man/index.html (nonexistent) +++ tags/2.3.0/doc/man/index.html (revision 33253) @@ -0,0 +1,10 @@ + +man page index - pcb-rnd

    +
  • pcb-rnd (1) -- pcb-rnd - Printed Circuit Board editor +
  • pcb-prj2lht (1) -- pcb-prj2lht - convert old gsch2pcb project file to pcb-rnd project +
  • fp2preview (1) -- fp2preview - generate a preview for a library footprint +
  • fp2subc (1) -- fp2subc - convert any footprint into a pcb-rnd subcircuit +
  • bxl2txt (1) -- bxl2txt - decode a binary BXL file and dump the plain text content +
  • txt2bxl (1) -- txt2bxl - encode a BXL file provided in plain text and save binary +
  • pcb-rnd-svg (1) -- pcb-rnd-svg - compare pcb-rnd svg renders +
Index: tags/2.3.0/doc/man/pcb-prj2lht.1 =================================================================== --- tags/2.3.0/doc/man/pcb-prj2lht.1 (nonexistent) +++ tags/2.3.0/doc/man/pcb-prj2lht.1 (revision 33253) @@ -0,0 +1,32 @@ +.\" pcb-rnd - manual +.\" Copyright (C) 2016 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 pcb-prj2lht 1 2016-12-27 "" "pcb-rnd manual" +.SH NAME +pcb-prj2lht - convert old gsch2pcb project file to pcb-rnd project +.SH SYNPOSIS +.nf +.sp +\fBpcb-prj2lht [\fIinputfile\fB] +.fi +.SH DECSRIPTION + +.BR pcb-prj2lht +converts the old gsch2pcb project file to the new, lihata project file format that is usable with pcb-rnd and gsch2pcb-rnd. If \fIinputfile\fR is specified, the file is modified in-place, else +.BR pcb-prj2lht +reads from STDIN and writes the result to STDOUT. Index: tags/2.3.0/doc/man/pcb-prj2lht.1.html =================================================================== --- tags/2.3.0/doc/man/pcb-prj2lht.1.html (nonexistent) +++ tags/2.3.0/doc/man/pcb-prj2lht.1.html (revision 33253) @@ -0,0 +1,62 @@ + + + +pcb-prj2lht - pcb-rnd manual + + + + +
pcb-prj2lht 1 + 2016-12-27 + pcb-rnd manual +
+ + + +

NAME

+
+pcb-prj2lht - convert old gsch2pcb project file to pcb-rnd project +
+ +

SYNPOSIS

+
+

+pcb-prj2lht [inputfile] + + + +

+ +

DESCRIPTION

+
+pcb-prj2lht converts the old gsch2pcb project file to the new, lihata project file format that is usable with pcb-rnd and gsch2pcb-rnd. If inputfile is specified, the file is modified in-place, else pcb-prj2lht reads from STDIN and writes the result to STDOUT. +
+

+ + +
pcb-prj2lht 1 + 2016-12-27 + pcb-rnd manual +
+ + + Index: tags/2.3.0/doc/man/pcb-prj2lht.1.mml =================================================================== --- tags/2.3.0/doc/man/pcb-prj2lht.1.mml (nonexistent) +++ tags/2.3.0/doc/man/pcb-prj2lht.1.mml (revision 33253) @@ -0,0 +1,14 @@ +pcb-prj2lht +1 +2016-12-27 + + pcb-prj2lht - convert old gsch2pcb project file to pcb-rnd project + pcb-prj2lht [inputfile] + + +pcb-prj2lht converts the old gsch2pcb project file to the +new, lihata project file format that is usable with pcb-rnd and +gsch2pcb-rnd. If inputfile is specified, the file is modified +in-place, else pcb-prj2lht reads from STDIN and writes the +result to STDOUT. + Index: tags/2.3.0/doc/man/pcb-rnd-svg.1 =================================================================== --- tags/2.3.0/doc/man/pcb-rnd-svg.1 (nonexistent) +++ tags/2.3.0/doc/man/pcb-rnd-svg.1 (revision 33253) @@ -0,0 +1,69 @@ +.\" pcb-rnd - manual +.\" Copyright (C) 2016 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 pcb-rnd-svg 1 2020-06-16 "" "pcb-rnd manual" +.SH NAME +pcb-rnd-svg - compare pcb-rnd svg renders +.SH SYNPOSIS +.nf +.sp +\fBpcb-rnd-svg command [\fIargs\fB] +.fi +.SH DECSRIPTION + +.BR pcb-rnd-svg +compares svg renders generated by pcb-rnd in a way that order of objects within the svg does not matter, only layering and geometry do. This is done by sorting group objects, assuming each object is a single line. +.PP +Note: stored reference files are of format boardname.ref or boardname.ref.gz if they are compressed. +.SH OPTIONS + + +.TP + +.B svg-sort +reads a pcb-rnd generated svg on stdin, prints sorted svg: objects within each group sorted alphabetically +.TP + +.B svg-diff s1 s2 +sort pcb-rnd generated svgs s1 and s2 and print diff s1 s2; result written to stdout in diff -u format +.TP + +.B diff b1 b2 +run pcb-rnd to generate svgs of b1 and b2 and print their diff; result written to stdout in diff -u format. Boards can be of any format pcb-rnd can load. +.TP + +.B svg-vis-comp s1 s2 +generate a visual comparison of s1 and s2, diffs highlighted: - lines of the diff with blue, + lines with red in a new group, over the faded version of s1. +.TP + +.B vis-comp b1 b2 +generate a svg visual comparison of board files b1 and b2, diffs highlighted: - lines of the diff with blue, + lines with red in a new group, over the faded svg render of b1. Boards can be of any format pcb-rnd can load. +.TP + +.B test brd +run pcb-rnd on brd and compare the resulting svg to a saved sorted svg reference file called brd.ref +.TP + +.B test-all dir1 [dir2 dirN...] +run test on all boards with a ref available under all directories listed, recursively. +.TP + +.B gen-ref brd1 [brd2 brdN...] +generate the initial svg reference file for all board files named +.PP + Index: tags/2.3.0/doc/man/pcb-rnd-svg.1.html =================================================================== --- tags/2.3.0/doc/man/pcb-rnd-svg.1.html (nonexistent) +++ tags/2.3.0/doc/man/pcb-rnd-svg.1.html (revision 33253) @@ -0,0 +1,106 @@ + + + +pcb-rnd-svg - pcb-rnd manual + + + + +
pcb-rnd-svg 1 + 2020-06-16 + pcb-rnd manual +
+ + + +

NAME

+
+pcb-rnd-svg - compare pcb-rnd svg renders +
+ +

SYNPOSIS

+
+

+pcb-rnd-svg command [args] + + + +

+ +

DESCRIPTION

+
+pcb-rnd-svg compares svg renders generated by pcb-rnd in a way that order of objects within the svg does not matter, only layering and geometry do. This is done by sorting group objects, assuming each object is a single line. +

+Note: stored reference files are of format boardname.ref or boardname.ref.gz if they are compressed. + +

+ + +

OPTIONS

+
+ + + + + + + + + + + + + + + + + + + +
svg-sort + reads a pcb-rnd generated svg on stdin, prints sorted svg: objects within each group sorted alphabetically +
svg-diff s1 s2 + sort pcb-rnd generated svgs s1 and s2 and print diff s1 s2; result written to stdout in diff -u format +
diff b1 b2 + run pcb-rnd to generate svgs of b1 and b2 and print their diff; result written to stdout in diff -u format. Boards can be of any format pcb-rnd can load. +
svg-vis-comp s1 s2 + generate a visual comparison of s1 and s2, diffs highlighted: - lines of the diff with blue, + lines with red in a new group, over the faded version of s1. +
vis-comp b1 b2 + generate a svg visual comparison of board files b1 and b2, diffs highlighted: - lines of the diff with blue, + lines with red in a new group, over the faded svg render of b1. Boards can be of any format pcb-rnd can load. +
test brd + run pcb-rnd on brd and compare the resulting svg to a saved sorted svg reference file called brd.ref +
test-all dir1 [dir2 dirN...] + run test on all boards with a ref available under all directories listed, recursively. +
gen-ref brd1 [brd2 brdN...] + generate the initial svg reference file for all board files named +
+
+

+ + +
pcb-rnd-svg 1 + 2020-06-16 + pcb-rnd manual +
+ + + Index: tags/2.3.0/doc/man/pcb-rnd-svg.1.mml =================================================================== --- tags/2.3.0/doc/man/pcb-rnd-svg.1.mml (nonexistent) +++ tags/2.3.0/doc/man/pcb-rnd-svg.1.mml (revision 33253) @@ -0,0 +1,72 @@ +pcb-rnd-svg +1 +2020-06-16 + + pcb-rnd-svg - compare pcb-rnd svg renders + pcb-rnd-svg command [args] + +pcb-rnd-svg compares svg renders generated by pcb-rnd in a way +that order of objects within the svg does not matter, only layering and +geometry do. This is done by sorting group objects, assuming each object +is a single line. +

+Note: stored reference files are of format boardname.ref or boardname.ref.gz +if they are compressed. + + + + + + svg-sort + reads a pcb-rnd generated svg on stdin, prints sorted svg: objects + within each group sorted alphabetically + + + + + svg-diff s1 s2 + sort pcb-rnd generated svgs s1 and s2 and print diff s1 s2; result + written to stdout in diff -u format + + + + diff b1 b2 + run pcb-rnd to generate svgs of b1 and b2 and print their diff; + result written to stdout in diff -u format. Boards can be of + any format pcb-rnd can load. + + + + svg-vis-comp s1 s2 + generate a visual comparison of s1 and s2, diffs highlighted: - lines of + the diff with blue, + lines with red in a new group, over the faded + version of s1. + + + + vis-comp b1 b2 + generate a svg visual comparison of board files b1 and b2, + diffs highlighted: - lines of + the diff with blue, + lines with red in a new group, over the faded + svg render of b1. Boards can be of any format pcb-rnd can load. + + + + test brd + run pcb-rnd on brd and compare the resulting svg to a saved + sorted svg reference file called brd.ref + + + + test-all dir1 [dir2 dirN...] + run test on all boards with a ref available under all directories + listed, recursively. + + + + gen-ref brd1 [brd2 brdN...] + generate the initial svg reference file for all board files named + + + + Index: tags/2.3.0/doc/man/pcb-rnd.1 =================================================================== --- tags/2.3.0/doc/man/pcb-rnd.1 (nonexistent) +++ tags/2.3.0/doc/man/pcb-rnd.1 (revision 33253) @@ -0,0 +1,51 @@ +.\" pcb-rnd - manual +.\" Copyright (C) 2016 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 pcb-rnd 1 2018-01-01 "" "pcb-rnd manual" +.SH NAME +pcb-rnd - Printed Circuit Board editor +.SH SYNPOSIS +.nf +.sp +\fBpcb-rnd [\fIoptions\fB] [\fIinputfile\fB] +.fi +.SH DECSRIPTION + +.BR pcb-rnd +is a modular PCB editor. The main use is interactive editing. If no \fI-x\fR is specified on the command line, the graphical editor mode is initiated. Automated, headless processing is also possible with \fI-x\fR or \fI--gui batch\fR. +.SH OPTIONS + + +.TP + +.B --help \fItopic\fR +Print help about \fItopic\fR and exit; if no topic is specified, print available topics. +.TP + +.B -x \fIexporter\fR [\fIexportflags] \fIinputfile\fR\fR +Instead of interactive editing, export the design (loaded from \fIinputfile\fR) to a file using the specified \fIexporter\fR plugin. A list of exporter-specific parameters may follow to control the details of the process. +.TP + +.B --gui \fIhid\fR +Use the \fIhid\fR plugin for the "gui" frontend. Common choices are "gtk" 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/2.3.0/doc/man/pcb-rnd.1.html =================================================================== --- tags/2.3.0/doc/man/pcb-rnd.1.html (nonexistent) +++ tags/2.3.0/doc/man/pcb-rnd.1.html (revision 33253) @@ -0,0 +1,87 @@ + + + +pcb-rnd - pcb-rnd manual + + + + +
pcb-rnd 1 + 2018-01-01 + pcb-rnd manual +
+ + + +

NAME

+
+pcb-rnd - Printed Circuit Board editor +
+ +

SYNPOSIS

+
+

+pcb-rnd [options] [inputfile] + + + +

+ +

DESCRIPTION

+
+pcb-rnd is a modular PCB editor. The main use is interactive editing. If no -x is specified on the command line, the graphical editor mode is initiated. Automated, headless processing is also possible with -x or --gui batch. +
+ + +

OPTIONS

+
+ + + + + + + + + + + +
--help topic + Print help about topic and exit; if no topic is specified, print available topics. +
-x exporter [exportflags] inputfile + Instead of interactive editing, export the design (loaded from inputfile) to a file using the specified exporter plugin. A list of exporter-specific parameters may follow to control the details of the process. +
--gui hid + Use the hid plugin for the "gui" frontend. Common choices are "gtk" 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). +
+
+

+ + +
pcb-rnd 1 + 2018-01-01 + pcb-rnd manual +
+ + + Index: tags/2.3.0/doc/man/pcb-rnd.1.mml =================================================================== --- tags/2.3.0/doc/man/pcb-rnd.1.mml (nonexistent) +++ tags/2.3.0/doc/man/pcb-rnd.1.mml (revision 33253) @@ -0,0 +1,43 @@ +pcb-rnd +1 +2018-01-01 + + pcb-rnd - Printed Circuit Board editor + pcb-rnd [options] [inputfile] + + +pcb-rnd is a modular PCB editor. The main use is interactive +editing. If no -x is specified on the command line, the +graphical editor mode is initiated. Automated, headless processing +is also possible with -x or --gui batch. + + + + + + --help topic + Print help about topic and exit; if no topic is + specified, print available topics. + + + -x exporter [exportflags] inputfile + Instead of interactive editing, export the design (loaded from + inputfile) to a file using the specified + exporter plugin. A list of exporter-specific parameters + may follow to control the details of the process. + + + --gui hid + Use the hid plugin for the "gui" frontend. Common + choices are "gtk" 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/2.3.0/doc/man/txt2bxl.1 =================================================================== --- tags/2.3.0/doc/man/txt2bxl.1 (nonexistent) +++ tags/2.3.0/doc/man/txt2bxl.1 (revision 33253) @@ -0,0 +1,30 @@ +.\" pcb-rnd - manual +.\" Copyright (C) 2016 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 txt2bxl 1 2020-04-18 "" "pcb-rnd manual" +.SH NAME +txt2bxl - encode a BXL file provided in plain text and save binary +.SH SYNPOSIS +.nf +.sp +\fBtxt2bxl \fIoutfile.bxl\fB < \fIinfile.txt\fB +.fi +.SH DECSRIPTION + +.BR txt2bxl +reads and encodes a text bxl file in its standard input and saves the resulting binary bxl file on the file name specified in the command line argument. Index: tags/2.3.0/doc/man/txt2bxl.1.html =================================================================== --- tags/2.3.0/doc/man/txt2bxl.1.html (nonexistent) +++ tags/2.3.0/doc/man/txt2bxl.1.html (revision 33253) @@ -0,0 +1,62 @@ + + + +txt2bxl - pcb-rnd manual + + + + +
txt2bxl 1 + 2020-04-18 + pcb-rnd manual +
+ + + +

NAME

+
+txt2bxl - encode a BXL file provided in plain text and save binary +
+ +

SYNPOSIS

+
+

+txt2bxl outfile.bxl < infile.txt + + + +

+ +

DESCRIPTION

+
+txt2bxl reads and encodes a text bxl file in its standard input and saves the resulting binary bxl file on the file name specified in the command line argument. +
+

+ + +
txt2bxl 1 + 2020-04-18 + pcb-rnd manual +
+ + + Index: tags/2.3.0/doc/man/txt2bxl.1.mml =================================================================== --- tags/2.3.0/doc/man/txt2bxl.1.mml (nonexistent) +++ tags/2.3.0/doc/man/txt2bxl.1.mml (revision 33253) @@ -0,0 +1,11 @@ +txt2bxl +1 +2020-04-18 + + txt2bxl - encode a BXL file provided in plain text and save binary + txt2bxl outfile.bxl < infile.txt + + +txt2bxl reads and encodes a text bxl file in its standard +input and saves the resulting binary bxl file on the file name specified in +the command line argument. Index: tags/2.3.0/doc/mirrors.html =================================================================== --- tags/2.3.0/doc/mirrors.html (nonexistent) +++ tags/2.3.0/doc/mirrors.html (revision 33253) @@ -0,0 +1,85 @@ + + + + pcb-rnd - main + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +
+ + +

Master read-write repository

+

+svn://repo.hu/pcb-rnd +

+Use only this one for commiting changes. + +

Real-time read-only svn mirrors

+

+These repositories are mirroring the master repo in real-time. That means +seconds after a commit to the master repository the synchronization takes +place and the mirror should be up to date. Use these mirrors if you +never commit and the master repository feels slow. +

+ +
url + location +
svn://us.repo.hu/pcb-rnd + U.S., west coast +
+ +

Periodic read-only svn mirrors

+

+These mirrors upgrade periodically, thus they are lagging behind the main +repositories above. Do not use them unless none of the above repositries +are accessible. +

+ +
url + update frequency location +
svn://timesausage.com/pcb-rnd + 10 minutes + U.S., west coast +
svn://svn.majenko.co.uk/pcb-rnd + 10 minutes + UK +
svn://turkos.aspodata.se/pcb-rnd + 60 minutes + SE, 10 Mbps +
svn://igor3.repo.hu/pcb-rnd + manual/random (every few days) + Budapest, Hungary +
+

+Note: svn mirrors are always read-only and lag behind the master +repository. The latest commits are often accessible only in the master +repo, until mirrors sync, which may take anything between minutes and +days. You should almost always use the master repository. +There are situations when using a mirror may help, tho: +

    +
  • if you need to do a lot of checkouts of past revisions, e.g. for + bisecting an old bug, you should pick the mirror that is fastest + for you +
  • the master repositry is not accessible for some reason and your + svn access can not wait until it is restored +
+ + + Index: tags/2.3.0/doc/motivation.html =================================================================== --- tags/2.3.0/doc/motivation.html (nonexistent) +++ tags/2.3.0/doc/motivation.html (revision 33253) @@ -0,0 +1,140 @@ + + + + pcb-rnd - motivation + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +

pcb-rnd motivation

+ +

Phase 6: the ringdove suite (2020)

+

+By 2020 pcb-rnd reached mature state with the new data model, CAM job based +exporting and even more modularity (e.g. tools in plugin). The next step +is to expand to a full EDA suite, with schematics editor included + +

Phase 5: new data model (2018)

+

+Mid 2018 the data model rewrite has mostly finished. The new model is +capable of handling complex layer stackups, subcircuits, padstacks, slots. We +are building a few long demanded features on top of the new infrastructure. + +

Phase 4: expansion, data model rewrite (2017)

+

+Late 2016 and during 2017 there was a major expansion in number of developers, +users and the amount of time spent on pcb-rnd. Our community is not tiny +any more, and is very active: there is a lot of on-topic discussion going +on on IRC every day, which result in bugs fixed and features implemented. +Newcomers are intergated fast. + +

+We started to rewrite the data model by slowly replacing elements with +more generic subcircuits. + + +

Phase 3: community requested features (2016)

+Overlapping phase 2 there was + feature poll . If there +are enough active users/testers for a feature, it gets implemented in +phase 3. +

+There is a small, active, constructive community forming around pcb-rnd. Future +directions will be mainly set by their need. + +

Phase 2: major cleanups (2015..2016)

+In the first phase I was mostly implementing a set of small features and fixes. +As I got more familiar with the code base, I decided to bite the bullet and +do some refactoring: +
    +
  • replaced the footprint mapping/loading code; instead of a hardwired m4 dependency, parametric (generated-on-the-fly) footprints can be written in any language +
  • replaced the default footprint library shipped with the software; the new library ships a small, well organized collection of essentials, omitting special/rarely used footprints +
  • got the code much more modular - a lot of core code got converted into plugins +
  • threw out the resource parser and file format (menu.res and friends) in favor of lihata; this removed a lot of code duplication and a strangely designed resource tree data structure I really hated; as a side effect the gtk hid has multi-stroke hotkeys +
  • replaced glib with a set of mini libs in core and most of the plugins; at the end only the gtk hid should depend on glib; this made the code easier to maintain and debug; a lot of checks are now compile-time (through the C type system) instead of runtime (glib lists) +
  • replaced the settings/rc/preferences system with a central, lihata based configuration system - long term hid attributes will be converted too +
+

+Plans for the future includes: +

    +
  • turning most of the core code into a library for external tools to reuse +
  • extending the core to provide an infrastructure for composite objects handled by plugins +
  • support for saving and loading pcb and footprint files in the lihata format +
  • plans for a set of smallish features that can be implemented in a weekend or two each. +
+ + +

Phase 1: At the beginning... (2013..2014)

+I use PCB a lot on various computers. I used to try to join the mainstream +development with small contribution (minor patches) and was active on +IRC and the mailing lists for a while. However, it didn't work out well, +and: +
    +
  • PCB already knew 95% of everything I'd ever need years ago +
  • the remaining 5% was not on the TODO list of developers and generally no one shown much interest in getting patches for those +
  • meanwhile a lot of new features have been added, from which most I find totally useless: +
      +
    • dbus +
    • gl - transparency makes even simple 2 sided boards unusable; slower than the classic version sw render on all my computers +
    • preparation for a C++ transition +
    • 3d support in core (I believe communication to 3d cad programs should be via exporter plugins) +
    +
  • the official Debian package enables (requires, depends on) both dbus and gl +
  • DVCS - it almost always results in chaos, and has no benefit for such a small group of developers; there are posts from time to time on the mailing list about how to handle the chaos; my choice is to stick with a simple, centralized version control system +
  • DVCS always results in increased administration, which I hate to spend my time on - I'd rather invest the time in bugfixing, documentation or implementing new features +
  • it's nearly impossible to get small patches applied^1: +
      +
    • often no one has the time to revise and commit them +
    • communication requires web2.0 (lp) +
    • there are too many cycles of "please fix this and change that first" +
    • with the chaos VCS, it's too likely that new feature patches would require ongoing maintenance while sitting in a "feature branch", to avoid that a large scale merge (or rebase, whatever) breaks it when it finally hits the official branch +
    • there are too much pondering and too less prototyping; there are features that are being considered for years (for example back annotation, internal connections) with multiple concurrent ideas, but no code. Instead, I'd like to implement some code from the early phase of the idea, test it, and deprecate it if it didn't work out well. +
    • I wouldn't even dream about getting larger patches in the official release +
    +
  • no stable release for years; maintaining a set of patches (like pcb-gpmi) and porting them to new releases is too much hassle +
+I was pondering a fork for years. The trigger was that one day I've upgraded +Debian on my lab computer and the new version of PCB came with gl enabled; this +made PCB absolutely unusable (had to wait like 10 seconds for a scroll) while +all the transparent polys over traces made the whole screen a mess. I should +have recompiled everything and built a new Debian package with gl disabled or +install from source (but I have too many computers for that). My decision +was to set up my own .deb but then build it from a fork (it's not much of +an extra effort), so I can add some of the features I miss in daily use. +My plans with this fork: +
    +
  • I stick with my fork and will use it on all my computers for all my designs +
  • Because of that, there's no emphasis on keeping the file formats compatible - breaking compatibility is not a goal either; as long as mainline doesn't change the format, pcb-rnd is about 98% compatible (the 2% is where pcb-rnd features are not supported by mainline) +
  • I won't actively seek ways to get my changes into the mainstream; I will keep on using my svn repo in a manner that (as a side effect) makes such merges easier, tho. If PCB developers decide to pick them up from svn and merge them in the official repo, it's fine (but I personally will keep using my fork anyway). +
  • Most probably I won't merge anything back from the mainstream to my fork - the past few years showed that it's unlikely there would be new features I'd need +
  • My plans for new features were: +
      +
    • pin shapes (a preliminary version was already implemented - as of 2017, it's obsolete because of padstacks) +
    • 1206 jumpers without having to add them on the schematics/netlist (done: [intconn] and [nonetlist] are the pcb-rnd-side features for this) +
    • merge pcb-gpmi; GPMI would be an optional addon, it'd probably stay a plugin, but there should not be a separate repo (done; meanwhile superseded by fungw scripting) +
    +
+

+Footnotes: +

    +
  • ^1: this may have changed lately and pcb developers are more open to newcomers; there seems to be a shortage of developers tho, which still makes it slow to get bigger patches through +
+ + + Index: tags/2.3.0/doc/myfeature.html =================================================================== --- tags/2.3.0/doc/myfeature.html (nonexistent) +++ tags/2.3.0/doc/myfeature.html (revision 33253) @@ -0,0 +1,55 @@ + + + + pcb-rnd - my feature + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +

pcb-rnd - how to get my favorite feature implemented

+ +The list below is sorted: top items have higher priority, but you +are free to choose any. + +

1. If you are a programmer with free time to spend

+Read the contribution howto and join the project. +You are welcome to work only on the feature you are interested in. You get +all the support (e.g. for understanding the API, to get a blank plugin +set up so you need to fill in only the feature-specific parts, etc.). Success +rate should be near to 100%. + +

2. If you are not a programmer and have free time

+You can join and work on things you don't need that much, but others do. +This will build your reputation in the community which in turns encourages +others to implement your favorite feature even if they wouldn't do it for +themselves. The success rate is somewhat more random, obviously. + +

3. If you don't have free time

+Consider donation: buy someone else's time, e.g. + sponsor the +project with small donations. +

+You can also directly buy the development time for the feature you need; +contact me (see the contribution +howto page). Since you don't need to cover all costs and the hourly +rates are much lower on a pet project, and your feature may be simpler +than it looks, and someone who already knows the code also saves the +learning curve, it may all be cheaper than you think. The success rate +should be close to 100%. + Index: tags/2.3.0/doc/news.html =================================================================== --- tags/2.3.0/doc/news.html (nonexistent) +++ tags/2.3.0/doc/news.html (revision 33253) @@ -0,0 +1,294 @@ + + + + pcb-rnd - news + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +
+ +

News

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 2020-09-09 +
+ release: 2.2.4 +
+ Release 2.2.4 available: feature release (menu patching, 4 new netlist formats and more) + +
+ 2020-07-09 +
+ release: 2.2.3 +
+ Release 2.2.3 available: critical bugfix of 2.2.2 (text object transformations) + +
+ 2020-07-01 +
+ release: 2.2.2 +
+ Release 2.2.2 available: BXL, net length UI + +
+ 2020-04-22 +
+ release: 2.2.1 +
+ Release 2.2.1 available: feature release with the new drc, new import_sch and the bus extended object + +
+ 2020-03-16 +
+ NLnet sponsoration +
+ pcb-rnd is getting NLnet + funding from the NGI0 PET fund. This allows us to have one full time + developer for more than a year. According to the task list there will + be major improvements on DRC, file format support and autorouting. + +
+ 2020-01-22 +
+ release: 2.2.0 +
+ Release 2.2.0 available: cleanup/bugfix release; plus extended objects, openEMS and STL export + +
+ 2019-10-30 +
+ release: 2.1.4 +
+ Release 2.1.4 available: cleanup/bugfix release; more scripting, better buffer content save + +
+ 2019-10-15 +
+ windows +
+ A windows version (from current svn head, pretty much what 2.1.4 is going to be) + is available +
+ 2019-07-17 +
+ release: 2.1.3 +
+ Release 2.1.3 available: cleanup/bugfix release; hidlib split, scripting + +
+ 2019-04-24 +
+ release: 2.1.2 +
+ Release 2.1.2 available: cleanup/bugfix release; netlist rewrite, CAM jobs, better KiCad4 support + +
+ 2019-02-13 +
+ release: 2.1.1 +
+ Release 2.1.1 available: cleanup/bugfix release; improved DRC GUI, find.c rewrite + +
+ 2018-11-25 +
+ release: 2.1.0 +
+ Release 2.1.0 available: doc/mech layers, slots, text rotation & thickness, asm plugin + +
+ 2018-09-19 +
+ CoralEDA +
+ pcb-rnd joins the CoralEDA ecosystem (umbrella project). + +
+ 2018-08-29 +
+ release: 2.0.1 +
+ Release 2.0.1 available: rendering speed optimization and various smallish features, including new scripting engine, CAM export, 2d drafting, new export dialog, easyEDA netlist import. + +
+ 2018-06-06 +
+ release: 2.0.0 +
+ Release 2.0.0 available: old data model fully removed; new default menu and key bindings. + +
+ 2018-03-21 +
+ release: 1.2.8 +
+ Release 1.2.8 available, with all parts of the code handling the new data model. + +
+ 2017-12-26 +
+ release: 1.2.7 +
+ Release 1.2.7 available, with padstacks. + +
+ 2017-10-11 +
+ release: 1.2.6 +
+ Release 1.2.6 available, with subcircuit terminals, dxf, hpgl, openscad and poly-clears-poly support. + +
+ 2017-09-15 +
+ release: 1.2.5b +
+ Release 1.2.5b is is an 1.2.5 with a security fix, please upgrade as soon as possible! + +
+ 2017-08-21 +
+ release: 1.2.5 +
+ Release 1.2.5 is available: it is an 1.2.4 with a few critical bugfixes + +
+ 2017-08-07 +
+ release: 1.2.4 +
+ Release 1.2.4 is available, with subcircuit, eagle binary and protel autotrax support. + +
+ 2017-05-30 +
+ release: 1.2.3 +
+ Release 1.2.3 is available, with a new plugin system and editable soldermask and paste layers. + +
+ 2017-04-10 +
+ release: 1.2.2 +
+ Release 1.2.2 is available. + +
+ 2017-03-12 +
+ opengl +
+ Opengl support available in svn HEAD. Thanks to Keith Packard. + +
+ 2017-02-17 +
+ EDA ecosystem, release: 1.2.1 +
+ Release 1.2.1 is available. +
+ We've strengthen our connections to other EDA tools, trying to + contribute more to the + EDA ecosystem, by implementing more import and export plugins. + +
+ 2016-12-28 +
+ release: 1.2.0 +
+ Release 1.2.0 is available. + +
+ 2016-12-20 +
+ Official Debian packaging +
+ Dima Kogan volunteered to do the packaging for Debian. We may get in + testing, or if we are lucky, in the next stable. To ease packaging + an unscheduled intermediate version 1.1.4 was released. Thank you Dima! + +
+ 2016-11-02 +
+ Release: 1.1.3 +
+ Available at the download page . +
+ Features kicad compatibility, advanced search and the + lihata board format. + +
+ 2016-09-04 +
+ Rebranding +
+ We have a new main page reflecting the transition how we regard pcb-rnd: + it is not much of just a fork of geda/pcb by now, but a separate PCB + editor with its own team and own course. File save/load compatibility is + maintained. + +
+ 2016-08-24 +
+ Release 1.1.1 +
+ Available at the download page . +
+ The next development cycle will focus on editable/searchable attributes + and a new native file format. + +
+
+ + + Index: tags/2.3.0/doc/plan.txt =================================================================== --- tags/2.3.0/doc/plan.txt (nonexistent) +++ tags/2.3.0/doc/plan.txt (revision 33253) @@ -0,0 +1,135 @@ +user manual + 1. intro: what is pcb-rnd; place in the generic workflow + 2. model of the world + intro + real boards (terminology) + pcb-rnd terminology + limitations + board, global properties + layer groups and layers + atomic objects + lines + arcs + vias + polygons + composite objects + elements + 3. where data is + board + paste buffers + footprint libraries + pcblib + static footprints + generated footprints + file formats + board + lihata + pcb + kicadl + kicad + footprint + import + export + 4. invocation + TODO + 5. user interface (hid plugins) + under the hood: actions + gtk + main window + menu + keys + misc dialogs + log window + cli + library dialog + propedit dialog + preferences dialog + batch + (lesstif: low prio) + (remote: not finished yet) + (sdl: not even started yet) + 6. feature plugins included,buildin name DocDraftComplete? + net auto-completion no [acompnet] y + crop board to fit objects yes, buildin [autocrop] y + auto place components yes, buildin [autoplace] + the original autorouter yes, buildin [autoroute] + flip board objects yes, buildin [boardflip] + diagnostic acts. for devs no [diag] + HID-independent GUI dialogs yes, buildin [dialogs] + distribute and align text yes, buildin [distaligntext] y + distribute and align objs yes, buildin [distalign] + djopt board optimization yes, buildin [djopt] y + draw cross-section (layers) yes, buildin [draw_csect] + fab layer in some exports yes, buildin [draw_fab] + font selection GUI yes, buildin [draw_fontsel] + font editor yes, buildin [fontmode] + push lines out of the way yes, buildin [jostle] + diagnostics: log HID calls no [loghid] + calculate toolpath for milling no [millpath] + minimal cut shorts yes, buildin [mincut] + old/obsolete actions no [oldactions] + combine selected polygons yes, buildin [polycombine] + stitch polygon at cursor no [polystitch] + object property editor yes, buildin [propedit] + puller yes, buildin [puller] + query language yes, buildin [query] y + renumber action yes, buildin [renumber] + report actions yes, buildin [report] + the original rubberband yes, buildin [rubberband_orig] + command shorthands yes, buildin [shand_cmd] + netlist based dispenser yes, buildin [smartdisperse] + libstroke gestures no [stroke] + draw teardrops on pins yes, buildin [teardrops] + vendor drill mapping yes, buildin [vendordrill] y + 7. io and import plugins + Comparison table (build from data like tests/RTT/RTT_kicad*) + intro: io_lihata extra attention to pcb-rnd's native format + IO & Import plugins sorted by capability: Boards, footprints, and netlists parens=(in development) + Boards: io plugins that deal with boards + lihata + pcb + kicadl + kicad + protel autotrax + (eagle) + Footprints: io plugins that deal with footprints + lihata + fp -- handled by pcb + kicadl + kicad + protel autotrax -- 'components' + (eagle) + (mentor-cell) + Netlists: there are import and io plugins dealing with netlists + lihata + specctra dsn + geda -- import_netlist plugin + tinycad + ltspice .net + .asc + kicadl + kicad + tinycad .net + protel autotrax + Mentor graphics schematic + Electronic Design Interchange Format (EDIF import plugin) + tEDAx + mucs routing + (eagle) + 8. utilities + 9. appendix + glossary + full index/catalog of actions (generated) + full index/catalog of all plugins + how to build + + +_styleguide notes:_ +urls all lowercased (eg. GTK becomes gtk) +pronouns: write to avoid pronouns, use user/developer, use she +organization: hierarchical with lots of links for people who have tunneled deep? +navigation: don't add navigation in page, rely on browser navs +html strict: use standard html 1.0 +css: use css for looks without content modification +assets: generate assets (use dot, etc), assume make and same system is able to build pcb-rnd +tables: use zebra styling for ease of reading +deps/requirements for pcb-rnd itself (we need an appendix table to live create the actions list) +naming sections: despite lowercasing urls, keep naming concise so links have names that lead to sections with same names Index: tags/2.3.0/doc/privacy.html =================================================================== --- tags/2.3.0/doc/privacy.html (nonexistent) +++ tags/2.3.0/doc/privacy.html (revision 33253) @@ -0,0 +1,129 @@ + + + + pcb-rnd - help wanted + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +

pcb-rnd - privacy policy

+

+By using any service provided at repo.hu, you agree to this privacy policy. + +

Mailing list

+

+You can subscribe to the mailing list by sending a mail to it with that +contains the word subscribe in the subject or in the message. +

+To unsubscribe: +

    +
  • send a mail that contains the word unsubscribe in the subject + or in the message to the list (note: this mail will be public to + inform other users that you are unsubscribing) +
  • or send a similar mail to the project admin + (in this case the mailing list won't be notified about the unsubscription) +
+

+Note: (un)subscriptions are handled manually and may take anything between +hours and days to get done. +

+The mailing list software running at list.repo.hu will store your email address +as long as you are subscribed. This address is used only for receiving +mails you send to the list and deliver mail from the list to you. Other +pcb-rnd users and developers subscribed to the mailing list may use +this email address to contact you privately about topics related to +pcb-rnd - these are private emails, outside of the scope of this privacy +policy. +

+The mailing list has a publicly accessible archive; anything you post +will be published there. In the published mailing list archives most of +the email headers in the mailing list are hidden or masked, but the body +(content) of the email is not necessarily masked. +

+If you do not want your content to be entered in the public mailing list +archive, do not post to the mailing list. +

+Using the mailing list or the list archives for harvesting email addresses +and/or sending advertisements to those addresses is strictly prohibited. + +

Bugreports in private mail

+

+Developers may accept pcb-rnd bugreports at their private email boxes. Since +these mail are private, person-to-person mail, this privacy policy does not +cover them, only common sense applies. Before sending anything confidential, +e.g. board files, agree with the developer how he may handle the data. + + +

IRC

+

+No registration is required for using the IRC network at repo.hu. Your +visible identification, as per the IRC protocol, will include: +

    +
  • your nickname (that you can choose) +
  • your 'ident' (which is either served to the IRC server by your ident server or is a string chosen by you) +
  • your IP address or host name, as seen by the IRC server (if you are using the kiwi-irc webchat service, your IP will be encoded in your 'ident') +
  • your 'real name' field, as specified by you (does not have to be your real name). +
+

+IRC channels on the repo.hu irc network are generally public. Any user +may log, quote or publish channel traffic. For some of the channels, +e.g. #pcb-rnd, the server publishes logs automatically. +The above data, with time stamps, is also visible in public irc logs. + +

Running pcb-rnd

+

+Running pcb-rnd does not require any registration. The software does +not try to handle personal data in any way (except when you enter +such data as arbitrary text strings, typically to be part of your +design data). Pcb-rnd does not send your design data over the network, unless +you explicitly command it to do so (e.g. saving to a network file system). +

+When configured so by the user, pcb-rnd may anonymously download files +from remote data repositories, such as edakrill or gedasymbols. These +sites may log your IP address and your request, according to their +privacy policy. + +

Writing source code, svn write access

+

+To gain write access to svn, you will need to choose a publicly visible +user name. It is not possible to change that user name later. Once you +commit, your user name, commit message, the diff you commited and the date +all become part of the repository history. It is not possible to remove this +data from the repository history later. +

+The lead developer grants svn write access. The lead developer may require that +you reveal your real name and electronic contact info to the lead developer +and/or to the audience. This is mainly required for copyright and communication +reasons. It is normally not possible to contribute code or svn diffs +anonymously and/or without letting pcb-rnd users and developers contact you. +

+If you make substantial change to files with copyright banner, coordinated +with the lead developer, you may choose to add your copyright to that banner. +If you do so, the copyright year and your real name will become part of that +source file, normally part of the source distribution and the repository +history and will be dupped into an uncontrollable amount of publicly accessible +copies (most often outside of repo.hu). +

+In other words, because of the nature of the technology being used +(version control, software distribution, packaging), if anything enters +the repository history, it is practically impossible to remove it from +publicly accessible material later. + + + Index: tags/2.3.0/doc/releases-bin/pcb-rnd-2.1.4-win32.errata.txt =================================================================== --- tags/2.3.0/doc/releases-bin/pcb-rnd-2.1.4-win32.errata.txt (nonexistent) +++ tags/2.3.0/doc/releases-bin/pcb-rnd-2.1.4-win32.errata.txt (revision 33253) @@ -0,0 +1,6 @@ +Known bugs: + - the parametric footprint dialog crashes with a GTK-Critical + mitigation: do not open the parametric footprint editor dialog + (do not double-click the parametric footprint name and do not use + the edit icon); entering the footprint in the filter still works, + e.g. entering so(8) or acy(300) should produce the right footprint. Index: tags/2.3.0/doc/releases-bin/pcb-rnd-2.2.0-win32.errata.txt =================================================================== --- tags/2.3.0/doc/releases-bin/pcb-rnd-2.2.0-win32.errata.txt (nonexistent) +++ tags/2.3.0/doc/releases-bin/pcb-rnd-2.2.0-win32.errata.txt (revision 33253) @@ -0,0 +1 @@ +Known bugs: there is no known windows-related bug. Index: tags/2.3.0/doc/resources/at.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/resources/at.png =================================================================== --- tags/2.3.0/doc/resources/at.png (nonexistent) +++ tags/2.3.0/doc/resources/at.png (revision 33253) Property changes on: tags/2.3.0/doc/resources/at.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/resources/header.lht =================================================================== --- tags/2.3.0/doc/resources/header.lht (nonexistent) +++ tags/2.3.0/doc/resources/header.lht (revision 33253) @@ -0,0 +1,1216 @@ +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 = 4.65in + y = 600.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.1 { + hdia=1.0mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.2mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.2mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.2mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.5 { + proto=0; x=100.0mil; y=250.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.6 { + proto=0; x=150.0mil; y=375.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.7 { + proto=0; x=200.0mil; y=500.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.17 { + proto=1; x=115.57mm; y=100.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.288 { + proto=1; x=4.4in; y=175.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.289 { + proto=1; x=115.57mm; y=250.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.305 { + proto=1; x=350.0mil; y=475.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.312 { + proto=1; x=4.4in; y=350.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:subc.48 { + ha:attributes { + footprint=1206 Standard SMT resistor, capacitor etc + refdes=R1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.726186mm + -1.02616mm + -0.726186mm + -1.02616mm + -0.726186mm + 1.02616mm + 0.726186mm + 1.02616mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.68 { + proto=0; x=1.26595in; y=175.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.69 { + proto=0; x=35.15487mm; y=175.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.49 { + x1=1.30138in; y1=3.49504mm; x2=34.254948mm; y2=3.49504mm; thickness=8.0mil; clearance=0.0; + } + ha:line.52 { + x1=1.30138in; y1=212.4mil; x2=34.254948mm; y2=212.4mil; thickness=8.0mil; clearance=0.0; + } + ha:text.55 { + string=%a.parent.refdes%; x=32.8549mm; y=143.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.56 { + x1=33.655mm; y1=175.0mil; x2=33.655mm; y2=175.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.59 { + x1=33.655mm; y1=175.0mil; x2=33.655mm; y2=175.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.62 { + x1=33.655mm; y1=175.0mil; x2=34.655mm; y2=175.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.65 { + x1=33.655mm; y1=175.0mil; x2=33.655mm; y2=5.445mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = pjaLj8tSfYLVqy1mjLYAAAAB + } + ha:subc.94 { + ha:attributes { + footprint=1206 Standard SMT resistor, capacitor etc + refdes=R2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.726186mm + -1.02616mm + -0.726186mm + -1.02616mm + -0.726186mm + 1.02616mm + 0.726186mm + 1.02616mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.114 { + proto=0; x=37.87013mm; y=275.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.115 { + proto=0; x=1.60905in; y=275.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.95 { + x1=1.52638in; y1=6.03504mm; x2=1.57362in; y2=6.03504mm; thickness=8.0mil; clearance=0.0; + } + ha:line.98 { + x1=1.52638in; y1=7.93496mm; x2=1.57362in; y2=7.93496mm; thickness=8.0mil; clearance=0.0; + } + ha:text.101 { + string=%a.parent.refdes%; x=38.5699mm; y=243.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.102 { + x1=1.55in; y1=275.0mil; x2=1.55in; y2=275.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.105 { + x1=1.55in; y1=275.0mil; x2=1.55in; y2=275.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.108 { + x1=1.55in; y1=275.0mil; x2=40.37mm; y2=275.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.111 { + x1=1.55in; y1=275.0mil; x2=1.55in; y2=7.985mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = pjaLj8tSfYLVqy1mjLYAAAAB + } + ha:subc.155 { + ha:attributes { + footprint=1206 Standard SMT resistor, capacitor etc + refdes=C1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.726186mm + -1.02616mm + -0.726186mm + -1.02616mm + -0.726186mm + 1.02616mm + 0.726186mm + 1.02616mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.175 { + proto=0; x=47.625mm; y=284.05mil; rot=90.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.176 { + proto=0; x=47.625mm; y=4.21513mm; rot=90.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.156 { + x1=46.67504mm; y1=248.62mil; x2=46.67504mm; y2=5.115052mm; thickness=8.0mil; clearance=0.0; + } + ha:line.159 { + x1=1.9124in; y1=248.62mil; x2=1.9124in; y2=5.115052mm; thickness=8.0mil; clearance=0.0; + } + ha:text.162 { + string=%a.parent.refdes%; x=1.8435in; y=256.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 90.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.163 { + x1=47.625mm; y1=225.0mil; x2=47.625mm; y2=225.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.166 { + x1=47.625mm; y1=225.0mil; x2=47.625mm; y2=225.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.169 { + x1=47.625mm; y1=225.0mil; x2=47.625mm; y2=4.715mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.172 { + x1=47.625mm; y1=225.0mil; x2=48.625mm; y2=225.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = pjaLj8tSfYLVqy1mjLYAAAAB + } + ha:subc.224 { + ha:attributes { + footprint=1206 Standard SMT resistor, capacitor etc + refdes=C2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.726186mm + -1.02616mm + -0.726186mm + -1.02616mm + -0.726186mm + 1.02616mm + 0.726186mm + 1.02616mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.244 { + proto=0; x=52.07mm; y=334.05mil; rot=90.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.245 { + proto=0; x=52.07mm; y=5.48513mm; rot=90.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.225 { + x1=51.12004mm; y1=298.62mil; x2=51.12004mm; y2=6.385052mm; thickness=8.0mil; clearance=0.0; + } + ha:line.228 { + x1=2.0874in; y1=298.62mil; x2=2.0874in; y2=6.385052mm; thickness=8.0mil; clearance=0.0; + } + ha:text.231 { + string=%a.parent.refdes%; x=51.2699mm; y=306.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 90.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.232 { + x1=52.07mm; y1=275.0mil; x2=52.07mm; y2=275.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.235 { + x1=52.07mm; y1=275.0mil; x2=52.07mm; y2=275.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.238 { + x1=52.07mm; y1=275.0mil; x2=52.07mm; y2=5.985mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.241 { + x1=52.07mm; y1=275.0mil; x2=53.07mm; y2=275.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = pjaLj8tSfYLVqy1mjLYAAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=1 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftt} + {pcb-rnd::key::select}={l; t} + } + + li:objects { + ha:line.8 { + x1=100.0mil; y1=250.0mil; x2=250.0mil; y2=100.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.11 { + x1=250.0mil; y1=100.0mil; x2=115.57mm; y2=100.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.116 { + x1=150.0mil; y1=375.0mil; x2=175.0mil; y2=375.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.119 { + x1=175.0mil; y1=375.0mil; x2=375.0mil; y2=175.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.122 { + x1=375.0mil; y1=175.0mil; x2=1.26595in; y2=175.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.125 { + x1=200.0mil; y1=500.0mil; x2=425.0mil; y2=275.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.128 { + x1=425.0mil; y1=275.0mil; x2=38.1mm; y2=275.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.246 { + x1=47.625mm; y1=4.21513mm; x2=1.70905in; y2=4.21513mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.249 { + x1=1.70905in; y1=4.21513mm; x2=1.7in; y2=175.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.252 { + x1=1.7in; y1=175.0mil; x2=35.15487mm; y2=175.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.255 { + x1=1.60905in; y1=275.0mil; x2=1.725in; y2=275.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.258 { + x1=1.725in; y1=275.0mil; x2=45.085mm; y2=225.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.261 { + x1=45.085mm; y1=225.0mil; x2=48.895mm; y2=225.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.270 { + x1=49.12487mm; y1=5.48513mm; x2=48.895mm; y2=225.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.273 { + x1=1.89095in; y1=4.21513mm; x2=49.12487mm; y2=4.21513mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.276 { + x1=49.12487mm; y1=4.21513mm; x2=49.53mm; y2=150.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.279 { + x1=49.53mm; y1=150.0mil; x2=53.975mm; y2=150.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.282 { + x1=53.975mm; y1=150.0mil; x2=54.61mm; y2=175.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.285 { + x1=54.61mm; y1=175.0mil; x2=4.4in; y2=175.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.302 { + x1=54.61mm; y1=250.0mil; x2=115.57mm; y2=250.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.334 { + x1=54.61mm; y1=250.0mil; x2=53.74513mm; y2=5.48513mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.337 { + x1=49.12487mm; y1=5.48513mm; x2=53.74513mm; y2=5.48513mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=5 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftb} + {pcb-rnd::key::select}={l; b} + } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=1 + ha:combining { } + + li:objects { + ha:line.313 { + x1=350.0mil; y1=475.0mil; x2=400.0mil; y2=425.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.319 { + x1=400.0mil; y1=425.0mil; x2=106.045mm; y2=425.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.322 { + x1=106.045mm; y1=425.0mil; x2=107.95mm; y2=350.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.325 { + x1=107.95mm; y1=350.0mil; x2=4.4in; y2=350.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.328 { + x1=47.625mm; y1=284.05mil; x2=47.625mm; y2=425.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.331 { + x1=52.07mm; y1=334.05mil; x2=52.07mm; y2=425.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#104e8b} + } + + ha:top-silk { + lid=3 + group=0 + ha:combining { auto=1; } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shifts} + {pcb-rnd::key::select}={l; s} + } + + li:objects { + } + color = {#000000} + } + + ha:slot-plated { + lid=4 + group=6 + ha:combining { auto=1; } + + li:objects { + } + color = {#8b7355} + } + + } + } + + ha:layer_stack { + li:groups { + ha:0 { + name = top_silk + ha:type { top=1; silk=1; } + li:layers { 3; } + } + ha:1 { + name = top_copper + ha:type { top=1; copper=1; } + li:layers { 0; 2; } + } + ha:2 { + name = grp_4 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:3 { + name = grp_6 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.125mm } + } + } + ha:4 { + name = grp_8 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:5 { + name = bottom_copper + ha:type { copper=1; bottom=1; } + li:layers { 1; } + } + ha:6 { + name = pmech + ha:type { mech=1; } + li:layers { 4;} + purpose = proute + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + text_scale = 100 + via_thickness = 2.2000 mm + via_drilling_hole = 1000.00 um + text_thickness = 0 + line_thickness = 20.00 mil + clearance = 20.00 mil + } + ha:editor { + lock_names = true + } + } + } +} Index: tags/2.3.0/doc/resources/header_300.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/resources/header_300.png =================================================================== --- tags/2.3.0/doc/resources/header_300.png (nonexistent) +++ tags/2.3.0/doc/resources/header_300.png (revision 33253) Property changes on: tags/2.3.0/doc/resources/header_300.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/resources/header_600.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/resources/header_600.png =================================================================== --- tags/2.3.0/doc/resources/header_600.png (nonexistent) +++ tags/2.3.0/doc/resources/header_600.png (revision 33253) Property changes on: tags/2.3.0/doc/resources/header_600.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/resources/logo.pcb =================================================================== --- tags/2.3.0/doc/resources/logo.pcb (nonexistent) +++ tags/2.3.0/doc/resources/logo.pcb (revision 33253) @@ -0,0 +1,91 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 15240000nm 15240000nm] + +Grid[635000nm 0 0 1] +Cursor[13335000nm 8890000nm 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,254000nm,1999996nm,800100nm,508000nm:Power,508000nm,2199894nm,999998nm,508000nm:Fat,2032000nm,3500120nm,1199896nm,635000nm:Sig-tight,254000nm,1625600nm,800100nm,304800nm"] + +Symbol['r' 304800nm] +( + SymbolLine[127000nm 889000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 889000nm 254000nm 762000nm 203200nm] + SymbolLine[254000nm 762000nm 508000nm 762000nm 203200nm] + SymbolLine[0 762000nm 127000nm 889000nm 203200nm] +) +Symbol['n' 304800nm] +( + SymbolLine[127000nm 889000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 889000nm 254000nm 762000nm 203200nm] + SymbolLine[254000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[508000nm 889000nm 508000nm 1270000nm 203200nm] + SymbolLine[0 762000nm 127000nm 889000nm 203200nm] +) +Symbol['d' 304800nm] +( + SymbolLine[508000nm 254000nm 508000nm 1270000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 889000nm 0 1143000nm 203200nm] + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] + SymbolLine[127000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] +) + + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/buffer_number" "0") +Attribute("PCB::conf::editor/draw_grid" "true") +Attribute("PCB::conf::editor/show_solder_side" "0") +Attribute("PCB::conf::editor/view/flip_x" "0") +Attribute("PCB::conf::editor/view/flip_y" "0") + +Element["" "dip(2)" "rnd" "2*300" 0 6985000nm 6350000nm 635000nm 0 115 ""] +( + Pin[7620000nm 0 2540000nm 1270000nm 2692400nm 999998nm "" "2" "thermal(0X,1X)"] + + ) +Layer(1 "component") +( + Polygon("clearpoly") + ( + [635000nm 635000nm] [14605000nm 635000nm] [14605000nm 14605000nm] [635000nm 14605000nm] + ) +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) Index: tags/2.3.0/doc/resources/logo.svg =================================================================== --- tags/2.3.0/doc/resources/logo.svg (nonexistent) +++ tags/2.3.0/doc/resources/logo.svg (revision 33253) @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/doc/resources/logo128.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/resources/logo128.png =================================================================== --- tags/2.3.0/doc/resources/logo128.png (nonexistent) +++ tags/2.3.0/doc/resources/logo128.png (revision 33253) Property changes on: tags/2.3.0/doc/resources/logo128.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/resources/logo16.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/resources/logo16.png =================================================================== --- tags/2.3.0/doc/resources/logo16.png (nonexistent) +++ tags/2.3.0/doc/resources/logo16.png (revision 33253) Property changes on: tags/2.3.0/doc/resources/logo16.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/resources/logo256.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/resources/logo256.png =================================================================== --- tags/2.3.0/doc/resources/logo256.png (nonexistent) +++ tags/2.3.0/doc/resources/logo256.png (revision 33253) Property changes on: tags/2.3.0/doc/resources/logo256.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/resources/logo32.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/resources/logo32.png =================================================================== --- tags/2.3.0/doc/resources/logo32.png (nonexistent) +++ tags/2.3.0/doc/resources/logo32.png (revision 33253) Property changes on: tags/2.3.0/doc/resources/logo32.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/resources/logo32.xpm =================================================================== --- tags/2.3.0/doc/resources/logo32.xpm (nonexistent) +++ tags/2.3.0/doc/resources/logo32.xpm (revision 33253) @@ -0,0 +1,295 @@ +/* XPM */ +static char *noname[] = { +/* width height ncolors chars_per_pixel */ +"32 32 256 2", +/* colors */ +" c #000000", +" . c #838D91", +" X c #365938", +" o c #5F6767", +" O c #E2E0E1", +" + c #799A7D", +" @ c #9FA9B3", +" # c #2F5331", +" $ c #B1C3B4", +" % c #2B552D", +" & c #2D512F", +" * c #6B6F76", +" = c #DBDADA", +" - c #2A532C", +" ; c #2B512D", +" : c #99A3AD", +" > c #AEBFB1", +" , c #2A4F2C", +" < c #729276", +" 1 c #294F2B", +" 2 c #859396", +" 3 c #284F2A", +" 4 c #709274", +" 5 c #6C9870", +" 6 c #274F29", +" 7 c #264F28", +" 8 c #254F27", +" 9 c #264D28", +" 0 c #254D27", +" q c #244D26", +" w c #234D25", +" e c #939DA7", +" r c #244B26", +" t c #6A8C6E", +" y c #8F99A3", +" u c #8F97A3", +" i c #6E737C", +" p c #8D97A1", +" a c #1B451D", +" s c #8B959F", +" d c #608C64", +" f c #9FAFA2", +" g c #89939D", +" h c #9DAFA0", +" j c #5D8861", +" k c #87919B", +" l c #708E77", +" z c #96AB99", +" x c #727B83", +" c c #113D13", +" v c #58785C", +" b c #547458", +" n c #537457", +" m c #57645B", +" M c #4B6C4F", +" N c #101112", +" B c #747C7E", +" V c #7D9D80", +" C c #73787D", +" Z c #7B9288", +" A c #B1C2B3", +" S c #879497", +" D c #55625C", +" F c #636A6D", +" G c #274828", +" H c #244C25", +" J c #9FB6A1", +" K c #A0B0A2", +" L c #9DAE9F", +" P c #709376", +" I c #87909A", +" U c #5B855E", +" Y c #858E98", +" T c #558558", +" R c #7E9987", +" E c #678B6D", +" W c #CAD3CB", +" Q c #4E7B51", +" ! c #49794C", +" ~ c #728D7B", +" ^ c #4C6D4F", +" / c #496F4C", +" ( c #B8C1B9", +" ) c #6E7577", +" _ c #465749", +" ` c #B3BBB4", +" ' c #37693A", +" ] c #3B5D3E", +" [ c #646D6D", +" { c #E7E6E7", +" } c #E2E4E2", +" | c #38513B", +". c #E1E2E1", +".. c #9099A2", +".X c #384D3B", +".o c #7D858C", +".O c #6C6F78", +".+ c #DBDCDB", +".@ c #729877", +".# c #2C512F", +".$ c #879399", +".% c #719476", +".& c #709475", +".* c #D8D8D8", +".= c #719276", +".- c #709275", +".; c #6F9274", +".: c #6E9073", +".> c #949FA9", +"., c #6D9072", +".< c #6D8E72", +".1 c #6A8E6F", +".2 c #6B8C70", +".3 c #67926C", +".4 c #303133", +".5 c #909BA5", +".6 c #678C6C", +".7 c #8E99A3", +".8 c #68886D", +".9 c #8D97A2", +".0 c #CDCECD", +".q c #517A53", +".w c #8EA18F", +".e c #9BB39F", +".r c #686F77", +".t c #517053", +".y c #2C2F32", +".u c #F3EDF2", +".i c #456047", +".p c #426444", +".a c #3C6A3E", +".s c #58645D", +".d c #161719", +".f c #39683B", +".g c #969EA7", +".h c #39543B", +".j c #7B9B7F", +".k c #2D562F", +".l c #B1C2B4", +".z c #2D522F", +".x c #6B7076", +".c c #677F68", +".v c #658166", +".b c #677B68", +".n c #89909A", +".m c #6F9773", +".M c #2E4830", +".N c #98A2AC", +".B c #565E5E", +".V c #265028", +".C c #274E29", +".Z c #6F9173", +".A c #264E28", +".S c #254E27", +".D c #6E8F72", +".F c #244E26", +".G c #254C27", +".H c #274829", +".J c #244C26", +".K c #234C25", +".L c #234A25", +".P c #214A23", +".I c #909AA4", +".U c #69896D", +".Y c #6F747D", +".T c #8E98A2", +".R c #577758", +".E c #68876C", +".W c #8C96A0", +".Q c #658769", +".! c #7B828C", +".~ c #5E8D62", +".^ c #9EB0A1", +"./ c #9DAEA0", +".( c #7F9789", +".) c #456746", +"._ c #C2CFC4", +".` c #859E88", +".' c #1D2022", +".] c #315732", +".[ c #426746", +".{ c #7C927F", +".} c #B1C1B3", +".| c #8B919B", +"X c #2E4D2F", +"X. c #2A512B", +"XX c #264F27", +"Xo c #224B23", +"XO c #7F878F", +"X+ c #8D97A0", +"X@ c #74947A", +"X# c #88919B", +"X$ c #6B9071", +"X% c #62696F", +"X& c #57845A", +"X* c #6B8C71", +"X= c #698E6F", +"X- c #678C6D", +"X; c #638A69", +"X: c #1A1B1B", +"X> c #697179", +"X, c #477A4A", +"X< c #5E7E64", +"X1 c #467649", +"X2 c #2F3336", +"X3 c #F6F1F6", +"X4 c #416A44", +"X5 c #6D7876", +"X6 c #436446", +"X7 c #8E949D", +"X8 c #060707", +"X9 c #415644", +"X0 c #385C3B", +"Xq c #3E5241", +"Xw c #355A38", +"Xe c #355838", +"Xr c #E2E3E2", +"Xt c #7B9B80", +"Xy c #7A997F", +"Xu c #8E9AA0", +"Xi c #E0DFE0", +"Xp c #DFDFDF", +"Xa c #315434", +"Xs c #DDDFDD", +"Xd c #739B78", +"Xf c #729577", +"Xg c #739378", +"Xh c #D9D9D9", +"Xj c #D8D9D8", +"Xk c #709375", +"Xl c #6F9374", +"Xz c #6F9174", +"Xx c #6E9173", +"Xc c #6B9570", +"Xv c #6D8F72", +"Xb c #919CA6", +"Xn c #698D6E", +"Xm c #909AA5", +"XM c #8F9AA4", +"XN c #69896E", +"XB c #8E98A3", +"XV c #8D96A2", +"XC c #8C96A1", +"XZ c #7C848E", +"XA c #8B96A0", +"XS c #65856A", +"XD c #CACDCA", +"XF c #5F7F64", +"XG c #879E88", +"XH c #899A8A", +"XJ c #889889", +"XK c #2B2E31", +"XL c #446546", +"XP c #EDE8EC", +"XI c #546359", +"XU c None", +/* pixels */ +"XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXxXxXxXxXxXxXkXf.<..n BX;XlXxXxXxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXv.8XvXx ~XC s s p s.W p pXA u.(.,.;XSXNXxXxXxXxXxXx", +"XxXxXxXxXx.2 #.KXw lXC p.W.W.W p.W.W p p pXV RX6 q 9.QXxXxXxXxXx", +"XxXxXxXx.; M 7 6Xo ..W.W p.W p y y p.W.W p.W IX. 6 6X4XzXxXxXxXx", +"XxXxXxXx PXa 6 6.M.g p.W.W.T xX2XKX> y p.W.WX#X9 7 6 7.@XxXxXxXx", +"XxXxXxXxX*.C 6 7.s y p.W p.r X%.W.W.WXM o.F 6 r.3XxXxXxXx", +"XxXxXxXx.E H 6XX ).W.W.W.5.d N e p p.T * - 6.G jXxXxXxXx", +"XxXxXxXxXF 0 6 8 C s p p pX8 @ p.W p.O.k 6 9X&.:XxXxXx", +"XxXxXxXxXN.K 6 7 [ p.W.W.I.y .4.I.W p p.x.V 6.G dXxXxXxXx", +"XxXxXxXxXv , 6 6 _Xm s.W p k.' X:...W.W p y D.S 6.L 5XxXxXxXx", +"XxXxXxXx.%Xe 6 6 G.| s.W.W.WXbXO.o.N.W p.W p Y.h 6 6 %XdXxXxXxXx", +"XxXxXxXxXx b.S 6.P Z p p.W.W p.W p.W.W p p.W S q 6.C !.:XxXxXxXx", +"XxXxXxXxXx.Z /.f T.,.$.W p.W.W p.W.W.W p.TX+.e.{.aX1.mXxXxXxXxXx", +"XxXxXxXxXxXxXz.-XxXx.: 2 sXB.W p.W.W.7 gXuX@.l h.-XzXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXxXxXxXzXL |.B i.!XZ.Y FX9X0.D $./XxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXxXt.6.`.R.] w.p.i.b ;.V q.) V._ hXxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXn.+ W.0 `.c.t.*XsXDXH.K.vXp (Xi.^XxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXx.j =X$.[.F.J.wXJ aX3 cXr.qXc.} hXxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXx.jXj.1.;Xl U JXG '.uX, }XyX- A LXxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXx +XhX=XxXxXx > f EXP.6 z O. { KXxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXx.,.-XxXxXxXx.,.-XxXzXx.,.=Xg < 4XxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx", +"XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx" +}; Index: tags/2.3.0/doc/resources/logo64.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/resources/logo64.png =================================================================== --- tags/2.3.0/doc/resources/logo64.png (nonexistent) +++ tags/2.3.0/doc/resources/logo64.png (revision 33253) Property changes on: tags/2.3.0/doc/resources/logo64.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/resources/logo64.xpm =================================================================== --- tags/2.3.0/doc/resources/logo64.xpm (nonexistent) +++ tags/2.3.0/doc/resources/logo64.xpm (revision 33253) @@ -0,0 +1,618 @@ +/* XPM */ +static char *noname[] = { +/* width height ncolors chars_per_pixel */ +"64 64 547 2", +/* colors */ +" c #000000", +" . c #829C86", +" X c #3F4941", +" o c #365738", +" O c #75A879", +" + c #365538", +" @ c #B4C7B7", +" # c #7A987E", +" $ c #E0DEDF", +" % c #79987D", +" & c #305532", +" * c #E0DCDF", +" = c #77987B", +" - c #DEDCDD", +" ; c #729C76", +" : c #344736", +" > c #749478", +" , c #2B512D", +" < c #709674", +" 1 c #28512A", +" 2 c #294F2B", +" 3 c #275129", +" 4 c #274F29", +" 5 c #6F9273", +" 6 c #264F28", +" 7 c #607C61", +" 8 c #264D28", +" 9 c #6E9072", +" 0 c #669C6A", +" q c #254D27", +" w c #244D26", +" e c #D5D2D4", +" r c #244B26", +" t c #234B25", +" y c #224B24", +" u c #6B8C6F", +" i c #919BA5", +" p c #224924", +" a c #6A8C6E", +" s c #204922", +" d c #619665", +" f c #1F4921", +" g c #8F99A3", +" h c #7B9682", +" j c #8E97A2", +" k c #1D471F", +" l c #8D97A1", +" z c #799480", +" x c #1C471E", +" c c #8C95A0", +" v c #91969B", +" b c #1B451D", +" n c #8B959F", +" m c #8A959E", +" M c #8A939E", +" N c #89939D", +" B c #638267", +" V c #174119", +" C c #87919B", +" Z c #8B9095", +" A c #607C64", +" S c #646B72", +" D c #54595F", +" F c #5F7C63", +" G c #5E7A62", +" H c #989EA5", +" J c #CDDACF", +" K c #75767C", +" L c #697A70", +" P c #547058", +" I c #537057", +" U c #4F7453", +" Y c #516C55", +" T c #575C5B", +" R c #888E95", +" E c #777C81", +" W c #4C6A50", +" Q c #4B6A4F", +" ! c #4B684F", +" ~ c #BACCBC", +" ^ c #374C38", +" / c #446248", +" ( c #9CA6AF", +" ) c #415E45", +" _ c #2B542C", +" ` c #69A16C", +" ' c #285229", +" ] c #68A16B", +" [ c #2A482B", +" { c #264E27", +" } c #254E26", +" | c #959EA8", +". c #949EA7", +".. c #254C26", +".X c #A9B8AB", +".o c #939CA6", +".O c #828A92", +".+ c #629B65", +".@ c #639966", +".# c #A7B6A9", +".$ c #909AA3", +".% c #808890", +".& c #7D868D", +".* c #5D9360", +".= c #5C935F", +".- c #879D90", +".; c #686E75", +".: c #719377", +".> c #8D9196", +"., c #588F5B", +".< c #9AAE9C", +".1 c #869099", +".2 c #858E98", +".3 c #6D9173", +".4 c #848E97", +".5 c #838C96", +".6 c #828C95", +".7 c #727A82", +".8 c #707880", +".9 c #92A894", +".0 c #69896F", +".q c #7D8690", +".w c #4D8350", +".e c #474C51", +".r c #97A9A6", +".t c #575F5A", +".y c #FAF8FA", +".u c #58575B", +".i c #A7B1B9", +".p c #F9F6F9", +".a c #A6AFB8", +".s c #74797D", +".d c #1E2022", +".f c #0E0E0F", +".g c #525555", +".h c #A3ABB5", +".j c #4C5D4F", +".k c #515354", +".l c #416544", +".z c #4E4F51", +".x c #8A9B99", +".c c #435F46", +".v c #B6BDB7", +".b c #B5BDB6", +".n c #EDECED", +".m c #B1BFB2", +".M c #ECEAEC", +".N c #3F5D42", +".B c #56635C", +".V c #38673B", +".C c #585B5E", +".Z c #365F39", +".A c #E6E6E6", +".S c #54575A", +".D c #37593A", +".F c #38573B", +".G c #E4E4E4", +".H c #E5E2E5", +".J c #37573A", +".K c #535359", +".L c #525358", +".P c #E2E2E2", +".I c #E1E0E1", +".U c #335536", +".Y c #E0E0E0", +".T c #E0DEE0", +".R c #315534", +".E c #2F5332", +".W c #77967C", +".Q c #DDDCDD", +".! c #DCDCDC", +".~ c #719C76", +".^ c #2B552E", +"./ c #749679", +".( c #DBDADB", +".) c #709A75", +"._ c #DADADA", +".` c #DBD8DB", +".' c #719676", +".] c #59905B", +".[ c #719476", +".{ c #709475", +".} c #709275", +".| c #5D845F", +"X c #859197", +"X. c #6F9274", +"XX c #6E9273", +"Xo c #656B71", +"XO c #6E9073", +"X+ c #6B9470", +"X@ c #848D96", +"X# c #6D9072", +"X$ c #6E8E73", +"X% c #97AB98", +"X& c #6C9071", +"X* c #D1D8D1", +"X= c #939DA8", +"X- c #6C8E71", +"X; c #95A996", +"X: c #D2D2D2", +"X> c #6B8C70", +"X, c #94A995", +"X< c #698E6E", +"X1 c #909BA5", +"X2 c #93A794", +"X3 c #698A6E", +"X4 c #678C6C", +"X5 c #94A395", +"X6 c #7E8790", +"X7 c #68886D", +"X8 c #67886C", +"X9 c #4E8450", +"X0 c #658A6A", +"Xq c #7C858E", +"Xw c #82848A", +"Xe c #8C95A1", +"Xr c #8B95A0", +"Xt c #CBCCCB", +"Xy c #65846A", +"Xu c #8A959F", +"Xi c #4B7E4D", +"Xp c #FEFBFD", +"Xa c #777F89", +"Xs c #899F8A", +"Xd c #767F88", +"Xf c #666D75", +"Xg c #7C7E84", +"Xh c #555B61", +"Xj c #607E65", +"Xk c #585C5A", +"Xl c #5F7C64", +"Xz c #636B72", +"Xx c #F9F7F8", +"Xc c #555C57", +"Xv c #A7B0B8", +"Xb c #67666C", +"Xn c #437445", +"Xm c #A5AEB6", +"XM c #4F555B", +"XN c #2E3134", +"XB c #A3ACB4", +"XV c #3D4146", +"XC c #4C5C4E", +"XZ c #476449", +"XA c #57745C", +"XS c #3D703F", +"XD c #436645", +"XF c #465C48", +"XG c #416443", +"XH c #050505", +"XJ c #3F5E41", +"XK c #38663A", +"XL c #3C5E3E", +"XP c #575A5C", +"XI c #111314", +"XU c #375E39", +"XY c #809F84", +"XT c #365E38", +"XR c #336035", +"XE c #809B84", +"XW c #3B523D", +"XQ c #326034", +"X! c #7F9B83", +"X~ c #76A97A", +"X^ c #38543A", +"X/ c #708571", +"X( c #525257", +"X) c #75A579", +"X_ c #335835", +"X` c #3D423F", +"X' c #7A977E", +"X] c #4F5054", +"X[ c #315433", +"X{ c #3C423E", +"X} c #79977D", +"X| c #39463B", +"o c #6B816C", +"o. c #38463A", +"oX c #70A374", +"oo c #39443B", +"oO c #6FA373", +"o+ c #2D562F", +"o@ c #729D76", +"o# c #6DA571", +"o$ c #364638", +"o% c #374439", +"o& c #697F6A", +"o* c #709F74", +"o= c #2E5230", +"o- c #778A85", +"o; c #2D522F", +"o: c #6DA171", +"o> c #2B542D", +"o, c #2B522D", +"o< c #DBD9DA", +"o1 c #719775", +"o2 c #709774", +"o3 c #2A502C", +"o4 c #DAD7D9", +"o5 c #28522A", +"o6 c #98A2AC", +"o7 c #29502B", +"o8 c #28502A", +"o9 c #294E2B", +"o0 c #2C482E", +"oq c #275029", +"ow c #265028", +"oe c #2A482C", +"or c #264E28", +"ot c #55585D", +"oy c #254E27", +"ou c #235025", +"oi c #254C27", +"op c #54565C", +"oa c #244C26", +"os c #264828", +"od c #234C25", +"of c #244A26", +"og c #929CA6", +"oh c #234A25", +"oj c #808C91", +"ok c #61666C", +"ol c #214A23", +"oz c #224824", +"ox c #204A22", +"oc c #214823", +"ov c #629566", +"ob c #688B6C", +"on c #658F69", +"om c #8F98A3", +"oM c #204622", +"oN c #3E4043", +"oB c #8E98A2", +"oV c #1D481F", +"oC c #6D747B", +"oZ c #8D96A1", +"oA c #618F65", +"oS c #8C96A0", +"oD c #8B969F", +"oF c #8B949F", +"oG c #909E90", +"oH c #8A949E", +"oJ c #788089", +"oK c #628166", +"oL c #869D90", +"oP c #728F79", +"oI c #7B7D82", +"oU c #607D64", +"oY c #96AE99", +"oT c #133C15", +"oR c #56875A", +"oE c #707881", +"oW c #6B8972", +"oQ c #58755C", +"o! c #557959", +"o~ c #7F8589", +"o^ c #8BA28E", +"o/ c #536F57", +"o( c #415D42", +"o) c #637D6A", +"o_ c #88A08B", +"o` c #4D6B51", +"o' c #57595B", +"o] c #212426", +"o[ c #859A88", +"o{ c #385B39", +"o} c #959DA5", +"o| c #728672", +"O c #49674D", +"O. c #0B0C0D", +"OX c #46634A", +"Oo c #3F4140", +"OO c #B2C5B4", +"O+ c #B4BDB6", +"O@ c #EBEEEC", +"O# c #9BA5AE", +"O$ c #9AA3AD", +"O% c #274F28", +"O& c #679C6A", +"O* c #959FA8", +"O= c #7F9C85", +"O- c #659A68", +"O; c #929BA5", +"O: c #525359", +"O> c #224923", +"O, c #254126", +"O< c #629665", +"O1 c #8D97A0", +"O2 c #DBE2DC", +"O3 c #8B959E", +"O4 c #5B5F65", +"O5 c #D9E0DA", +"O6 c #9DB59F", +"O7 c #5A5D64", +"O8 c #59905C", +"O9 c #88919B", +"O0 c #87919A", +"Oq c #676D74", +"Ow c #868F99", +"Oe c #848D97", +"Or c #838D96", +"Ot c #6B9071", +"Oy c #95AB97", +"Ou c #828B95", +"Oi c #717981", +"Op c #698E6F", +"Oa c #6B8871", +"Os c #6F777F", +"Od c #C9D2CA", +"Of c #517C54", +"Og c #7B858E", +"Oh c #81848A", +"Oj c #8B9E97", +"Ok c #C7D0C8", +"Ol c #FDFBFD", +"Oz c #FAF9FA", +"Ox c #69686F", +"Oc c #F9F7F9", +"Ov c #212325", +"Ob c #A7AEB9", +"On c #F8F5F8", +"Om c #6E8477", +"OM c #F5F5F5", +"ON c #427245", +"OB c #A3ACB5", +"OV c #829184", +"OC c #0B0B0C", +"OZ c #F2F1F2", +"OA c #71747A", +"OS c #436246", +"OD c #3C6C3F", +"OF c #8D949C", +"OG c #415E44", +"OH c #405E43", +"OJ c #4B4C4E", +"OK c #3B663E", +"OL c #E9E7E9", +"OP c #E7E7E7", +"OI c #E6E5E6", +"OU c #39583C", +"OY c #E5E5E5", +"OT c #E4E3E4", +"OR c #365839", +"OE c #365639", +"OW c #808C8F", +"OQ c #525258", +"O! c #335636", +"O~ c #515057", +"O^ c #E0DFE0", +"O/ c #325435", +"O( c #DFDFDF", +"O) c #485A4E", +"O_ c #2E5231", +"O` c #DCDBDC", +"O' c #75957A", +"O] c #729977", +"O[ c #749579", +"O{ c #D8DDD8", +"O} c #DAD9DA", +"O| c #709775", +"+ c #719576", +"+. c #DAD7DA", +"+X c #29502C", +"+o c #588F5A", +"+O c #6F9574", +"++ c #709375", +"+@ c #849D8C", +"+# c #6F9374", +"+$ c #6F9174", +"+% c #D2DDD2", +"+& c #849096", +"+* c #6E9173", +"+= c #6D9172", +"+- c #D5D5D5", +"+; c #6E8F73", +"+: c #D6D3D6", +"+> c #646A70", +"+, c #D5D3D5", +"+< c #838C95", +"+1 c #6C8F71", +"+2 c #D5D1D5", +"+3 c #6B8F70", +"+4 c #818A93", +"+5 c #698D6E", +"+6 c #D1D1D1", +"+7 c #6A8B6F", +"+8 c #5B755D", +"+9 c #8F9AA4", +"+0 c #CED1CE", +"+q c #8F98A4", +"+w c #68896D", +"+e c #1E4821", +"+r c #668B6B", +"+t c #8E98A3", +"+y c #84858C", +"+u c #1D4820", +"+i c #67876C", +"+p c #65896A", +"+a c #8D96A2", +"+s c #82858A", +"+d c #8C96A1", +"+f c #66856B", +"+g c #929E93", +"+h c #7B848D", +"+j c #65856A", +"+k c #818389", +"+l c #4C814E", +"+z c #4D7F4F", +"+x c #909E91", +"+c c #4C7F4E", +"+v c #8A949F", +"+b c #CACBCA", +"+n c #19441C", +"+m c #89949E", +"+M c #697078", +"+N c #88929D", +"+B c #628167", +"+V c #778089", +"+C c #8A9E8B", +"+Z c #9CA3AA", +"+A c #617F66", +"+S c #607D65", +"+D c #728B7A", +"+F c #89988A", +"+G c #5E7D63", +"+H c #A9B1BA", +"+J c #F9F6F8", +"+K c #5C7B61", +"+L c #829883", +"+P c #466948", +"+I c #8FAA93", +"+U c #4D5D4F", +"+Y c #4C5D4E", +"+T c #58755D", +"+R c #4A5D4C", +"+E c #1B1C1E", +"+W c #EDECEC", +"+Q c #445746", +"+! c #788E79", +"+~ c #141617", +"+^ c #3D5F3F", +"+/ c #38673A", +"+( c #595D5E", +"+) c #84A288", +"+_ c #83A287", +"+` c #3A5D3C", +"+' c None", +/* pixels */ +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+#.{+ +iX7X7X7X-.{++X.+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*.{Xy GO OE.FX[O_O_o= o.J.N I+AX-X.+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* 9Xl /.R wor 4 4 4 4 4 4 4 4 6oy+X.J PX8+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+* !o7or 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 }ORX.+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*X.XA 6 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4or U+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*++ /or 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4XRO]+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*.{OU 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4oMX~+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*X. Wor 4 4 4 4oqoyocoeo0o0o0or t 6 4 4 4 4 4.Vo@+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+Ao3 4 4oyosX|OoOxXgXw+sOhXb.k XX^ y 4 4oh.,+O+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*X.oK.ZO,X{ K v.iO$.$ n+moH | (OFOA.z ^ '.] <+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+7o-ObXmO*+d l noBoSoS loSoSoBXrO#.h.r./+=+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*X..0X XroB noS n l loSoSoS loS l l l loHoBom hX#+*+*+*+*+*X.X.+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*.{Xj+KoU+BX.+*+*Oa coDoB l loS noSoS noSoSoS loS l l l loSoBXeoLX&+*+*X- Fo/oQ+i+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+* Y ,oy wo; B+* a.1oSoS l noSoS n loS loB noS n loSoSoSoB l n n+qO=X# u.N 4oy w.DX>+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*XX+T 6 4 4 4 4 2obojoHoB l noS noS loSoSoS l loS loS loB n l l loS lom = )oy 4 4 4O%.lX.+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*X-.J 4 4 4 4 4oro) joSoSoS l loSoS n l l n noS l l g loS loS l l loHoSOWo, 4 4 4 4 4O>.)+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+* A+X 4 4 4 4 4of+k+voSoB n l l loS l loB+doB noBoH l n loSoSoSoSoS l lXao( 4 4 4 4 4 4OfXO+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+#O or 4 4 4 4oq : ZoHoBoH noSoS loS noBoH+h DXhoEOe l loS l loS loB n lXd.tod 4 4 4 4 4XQ.[+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*.J 4 4 4 4 4odOJ.aoSoSoB loS noSoS g.7XN o]Xf+toS loSoH l noS lO0O:+^ 4 4 4 4 4 po*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*X7o= 4 4 4 4 4 [ K.ooS loS n n loSoBOiO. Xz n l l l noS n n g+>+Roy 4 4 4 4oi dXO+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+Ao3 4 4 4 4oq :.>+N l n l loS l l+4XI oBoHoS loS l noBoBXdXc w 4 4 4 4 8oRXO+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*Xloy 4 4 4 4oqo% H loSoHoSoSoS lX1XM .eoSoH l l noB n lOg T 1 4 4 4 4 4.w+;+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*X.+Toy 4 4 4 4owX`OB loS l l l NoSO9Ov .fo6 l loSoS l l l.5O~XU 4 4 4 4 4ON+#+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*X. Qor 4 4 4 4owX`OB noS l loH loS.2+~ +HoS l l n n l nX@OQXT 4 4 4 4 4XK ;+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*X.o`or 4 4 4 4owX`XBoBoSoSoS loS l.4+E Xv loSoS n loS lOrOQXT 4 4 4 4 4OD.~+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+Soy 4 4 4 4oqooo} l noSoS loS l+9XV oN. oSoSoSoS loS lOuXPo+ 4 4 4 4 4X9X$+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*Xl w 4 4 4 4oqo$ R+doS noS loSoSoSX6XH +ZoSoS n l loSoS n+VXk w 4 4 4 4 4+l+;+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+f.E 4 4 4 4 4o0oI+m l n noS l l lO3 S .sO;oSoB noS l l noBoCXC q 4 4 4 4oa.@XO+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*X3.U 4 4 4 4 4ol.uX=oBoSoSoSoS l loS lOs.d OCo~ ioBoS n noSoS noS lO7XJ 4 4 4 4 4 r 0XO+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*.{.N 6 4 4 4 4oqo..O n noSoH goSoSoSoSoSog.%.S.C E+HO1oSoSoBoSoS loBoS l.q+( 3 4 4 4 4 4 4 O+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*X. I } 4 4 4 4 4os+yoHoS noSoS noBoBoSoSoSoSoHoHXuoS l n loS l n n loS noJXFor 4 4 4 4 4XnO|+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+j.R 4 4 4 4 4oq L n noBoS l loSoSoS loSoSoS l loSoS loH l noSoB noBoS.& _ 4 4 4 4 4oi.++;+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*.{OX { 4 4 4 4ozO- C loH l loSoS loSoS l loS loS l l l noSoSoSoSoSoB+a zO/ 4 4 4 4 4o>X)+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+wO!oa 4 8 pO8O|oWoS l loBoS l n loSoS l loSoS l noSoS loS l noSoZ.-+_o[o9.. 4 q.^ ]+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+$oA+c+oO&o2+*X.Om+qoS noS loS l loSoSoS loS n n n loS l l goF.xX4Oz+:+povXi.*oX+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+;+;XO+*+*+*+#+D M m l l n noHoSoS loSoS loSoS l l noSoZOj 5X0+J+,X #+*+*+* > #+*+*+*+*O[X!X!X!XEX} #+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*", +"+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*" +}; Index: tags/2.3.0/doc/resources/logo_made_with.lht =================================================================== --- tags/2.3.0/doc/resources/logo_made_with.lht (nonexistent) +++ tags/2.3.0/doc/resources/logo_made_with.lht (revision 33253) @@ -0,0 +1,555 @@ +li:pcb-rnd-subcircuit-v4 { + ha:subc.438 { + ha:attributes { + refdes = U0 + } + ha:data { + li:padstack_prototypes { + } + li:objects { + } + li:layers { + ha:silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.338 { + clearance = 20.0mil + y2 = 1.97in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.3in + x2 = 2.31in + ha:flags { + clearline = 1 + } + y1 = 1.96in + } + ha:line.341 { + clearance = 20.0mil + y2 = 1.93in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.3in + x2 = 2.31in + ha:flags { + clearline = 1 + } + y1 = 1.94in + } + ha:line.344 { + clearance = 20.0mil + y2 = 1.93in + thickness = 10.0mil + ha:attributes { + } + x1 = 59.436mm + x2 = 2.31in + ha:flags { + clearline = 1 + } + y1 = 1.93in + } + ha:line.347 { + clearance = 20.0mil + y2 = 1.88in + thickness = 10.0mil + ha:attributes { + } + x1 = 59.436mm + x2 = 59.436mm + ha:flags { + clearline = 1 + } + y1 = 1.97in + } + ha:line.350 { + clearance = 20.0mil + y2 = 1.97in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.31in + x2 = 59.436mm + ha:flags { + clearline = 1 + } + y1 = 1.97in + } + ha:line.353 { + clearance = 20.0mil + y2 = 1.96in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.3in + x2 = 2.3in + ha:flags { + clearline = 1 + } + y1 = 1.94in + } + ha:line.356 { + clearance = 20.0mil + y2 = 1.93in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.28in + x2 = 2.27in + ha:flags { + clearline = 1 + } + y1 = 1.94in + } + ha:line.359 { + clearance = 20.0mil + y2 = 1.97in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.28in + x2 = 2.28in + ha:flags { + clearline = 1 + } + y1 = 1.94in + } + ha:line.362 { + clearance = 20.0mil + y2 = 1.93in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.25in + x2 = 2.27in + ha:flags { + clearline = 1 + } + y1 = 1.93in + } + ha:line.365 { + clearance = 20.0mil + y2 = 1.93in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.24in + x2 = 2.25in + ha:flags { + clearline = 1 + } + y1 = 1.94in + } + ha:line.368 { + clearance = 20.0mil + y2 = 1.97in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.24in + x2 = 2.24in + ha:flags { + clearline = 1 + } + y1 = 1.93in + } + ha:line.371 { + clearance = 20.0mil + y2 = 1.96in + thickness = 10.0mil + ha:attributes { + } + x1 = 49.53mm + x2 = 1.96in + ha:flags { + clearline = 1 + } + y1 = 1.97in + } + ha:line.374 { + clearance = 20.0mil + y2 = 1.94in + thickness = 10.0mil + ha:attributes { + } + x1 = 49.53mm + x2 = 1.96in + ha:flags { + clearline = 1 + } + y1 = 1.93in + } + ha:line.377 { + clearance = 20.0mil + y2 = 1.97in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.08in + x2 = 52.578mm + ha:flags { + clearline = 1 + } + y1 = 1.96in + } + ha:line.380 { + clearance = 20.0mil + y2 = 1.94in + thickness = 10.0mil + ha:attributes { + } + x1 = 52.578mm + x2 = 2.08in + ha:flags { + clearline = 1 + } + y1 = 1.93in + } + ha:line.383 { + clearance = 20.0mil + y2 = 1.97in + thickness = 10.0mil + ha:attributes { + } + x1 = 1.98in + x2 = 1.99in + ha:flags { + clearline = 1 + } + y1 = 1.96in + } + ha:line.386 { + clearance = 20.0mil + y2 = 1.93in + thickness = 10.0mil + ha:attributes { + } + x1 = 1.98in + x2 = 1.99in + ha:flags { + clearline = 1 + } + y1 = 1.94in + } + ha:line.389 { + clearance = 20.0mil + y2 = 2.01in + thickness = 10.0mil + ha:attributes { + } + x1 = 1.92in + x2 = 1.92in + ha:flags { + clearline = 1 + } + y1 = 1.93in + } + ha:line.392 { + clearance = 20.0mil + y2 = 1.93in + thickness = 10.0mil + ha:attributes { + } + x1 = 52.578mm + x2 = 2.04in + ha:flags { + clearline = 1 + } + y1 = 1.93in + } + ha:line.395 { + clearance = 20.0mil + y2 = 1.94in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.08in + x2 = 2.08in + ha:flags { + clearline = 1 + } + y1 = 1.96in + } + ha:line.398 { + clearance = 20.0mil + y2 = 1.97in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.04in + x2 = 52.578mm + ha:flags { + clearline = 1 + } + y1 = 1.97in + } + ha:line.401 { + clearance = 20.0mil + y2 = 1.97in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.04in + x2 = 2.04in + ha:flags { + clearline = 1 + } + y1 = 1.88in + } + ha:line.404 { + clearance = 20.0mil + y2 = 1.97in + thickness = 10.0mil + ha:attributes { + } + x1 = 1.99in + x2 = 2.02in + ha:flags { + clearline = 1 + } + y1 = 1.97in + } + ha:line.407 { + clearance = 20.0mil + y2 = 1.96in + thickness = 10.0mil + ha:attributes { + } + x1 = 1.98in + x2 = 1.98in + ha:flags { + clearline = 1 + } + y1 = 1.94in + } + ha:line.410 { + clearance = 20.0mil + y2 = 1.93in + thickness = 10.0mil + ha:attributes { + } + x1 = 1.99in + x2 = 2.02in + ha:flags { + clearline = 1 + } + y1 = 1.93in + } + ha:line.413 { + clearance = 20.0mil + y2 = 1.96in + thickness = 10.0mil + ha:attributes { + } + x1 = 1.96in + x2 = 1.96in + ha:flags { + clearline = 1 + } + y1 = 1.94in + } + ha:line.416 { + clearance = 20.0mil + y2 = 1.97in + thickness = 10.0mil + ha:attributes { + } + x1 = 49.53mm + x2 = 1.92in + ha:flags { + clearline = 1 + } + y1 = 1.97in + } + ha:line.419 { + clearance = 20.0mil + y2 = 1.93in + thickness = 10.0mil + ha:attributes { + } + x1 = 1.92in + x2 = 49.53mm + ha:flags { + clearline = 1 + } + y1 = 1.93in + } + ha:line.422 { + clearance = 20.0mil + y2 = 1.93in + thickness = 10.0mil + ha:attributes { + } + x1 = 55.626mm + x2 = 2.22in + ha:flags { + clearline = 1 + } + y1 = 1.93in + } + ha:line.425 { + clearance = 20.0mil + y2 = 1.93in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.18in + x2 = 55.626mm + ha:flags { + clearline = 1 + } + y1 = 1.94in + } + ha:line.428 { + clearance = 20.0mil + y2 = 1.97in + thickness = 10.0mil + ha:attributes { + } + x1 = 2.18in + x2 = 2.18in + ha:flags { + clearline = 1 + } + y1 = 1.93in + } + ha:line.431 { + clearance = 20.0mil + y2 = 49.53mm + thickness = 10.0mil + ha:attributes { + } + x1 = 53.594mm + x2 = 54.61mm + ha:flags { + clearline = 1 + } + y1 = 49.53mm + } + ha:arc.434 { + astart = 0 + thickness = 10.0mil + width = 10.0mil + height = 10.0mil + ha:attributes { + } + x = 59.436mm + y = 1.87in + adelta = 360 + ha:flags { + clearline = 1 + } + clearance = 20.0mil + } + ha:arc.435 { + astart = 0 + thickness = 10.0mil + width = 10.0mil + height = 10.0mil + ha:attributes { + } + x = 2.04in + y = 1.87in + adelta = 360 + ha:flags { + clearline = 1 + } + clearance = 20.0mil + } + ha:arc.436 { + astart = 0 + thickness = 10.0mil + width = 10.0mil + height = 10.0mil + ha:attributes { + } + x = 1.92in + y = 2.02in + adelta = 360 + ha:flags { + clearline = 1 + } + clearance = 20.0mil + } + ha:text.437 { + scale = 100 + ha:attributes { + } + direction = 0 + x = 2.06in + y = 1.86in + string = made with + fid = 0 + ha:flags { + clearline = 1 + } + } + } + ha:combining { + auto = 1 + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.439 { + clearance = 0.0 + y2 = 1.93in + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.04in + x2 = 2.04in + ha:flags { + } + y1 = 1.93in + } + ha:line.442 { + clearance = 0.0 + y2 = 1.93in + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.04in + x2 = 52.816mm + ha:flags { + } + y1 = 1.93in + } + ha:line.445 { + clearance = 0.0 + y2 = 50.022mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.04in + x2 = 2.04in + ha:flags { + } + y1 = 1.93in + } + } + ha:combining { + } + } + } + } + uid = NhAIKQfa5EkLmJw7dscAAAAE + ha:flags { + } + } +} Index: tags/2.3.0/doc/resources/logo_made_with.pcb =================================================================== --- tags/2.3.0/doc/resources/logo_made_with.pcb (nonexistent) +++ tags/2.3.0/doc/resources/logo_made_with.pcb (revision 33253) @@ -0,0 +1,82 @@ +# release: pcb 20140316 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20091103] + +PCB["" 6000.00mil 5000.00mil] + +Grid[1000.000000 0.0000 0.0000 0] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[10.00mil 10.00mil 10.00mil 10.00mil 15.00mil 10.00mil] +Flags("nameonpcb,uniquename,clearnew,snappin") +Groups("1,c:2:3:4:5:6,s:7:8") +Styles["Signal,10.00mil,36.00mil,20.00mil,10.00mil:Power,25.00mil,60.00mil,35.00mil,10.00mil:Fat,40.00mil,60.00mil,35.00mil,10.00mil:Skinny,6.00mil,24.02mil,11.81mil,6.00mil"] + +Attribute("PCB::grid::unit" "mil") +Layer(1 "top") +( +) +Layer(2 "ground") +( +) +Layer(3 "signal2") +( +) +Layer(4 "signal3") +( +) +Layer(5 "power") +( +) +Layer(6 "bottom") +( +) +Layer(7 "outline") +( +) +Layer(8 "spare") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( + Line[2110.00mil 1950.00mil 2150.00mil 1950.00mil 10.00mil 20.00mil "clearline"] + Line[2180.00mil 1930.00mil 2180.00mil 1970.00mil 10.00mil 20.00mil "clearline"] + Line[2180.00mil 1940.00mil 2190.00mil 1930.00mil 10.00mil 20.00mil "clearline"] + Line[2190.00mil 1930.00mil 2220.00mil 1930.00mil 10.00mil 20.00mil "clearline"] + Line[1920.00mil 1930.00mil 1950.00mil 1930.00mil 10.00mil 20.00mil "clearline"] + Line[1950.00mil 1970.00mil 1920.00mil 1970.00mil 10.00mil 20.00mil "clearline"] + Line[1960.00mil 1940.00mil 1960.00mil 1960.00mil 10.00mil 20.00mil "clearline"] + Line[1990.00mil 1930.00mil 2020.00mil 1930.00mil 10.00mil 20.00mil "clearline"] + Line[1980.00mil 1940.00mil 1980.00mil 1960.00mil 10.00mil 20.00mil "clearline"] + Line[1990.00mil 1970.00mil 2020.00mil 1970.00mil 10.00mil 20.00mil "clearline"] + Line[2040.00mil 1880.00mil 2040.00mil 1970.00mil 10.00mil 20.00mil "clearline"] + Line[2040.00mil 1970.00mil 2070.00mil 1970.00mil 10.00mil 20.00mil "clearline"] + Line[2080.00mil 1960.00mil 2080.00mil 1940.00mil 10.00mil 20.00mil "clearline"] + Line[2070.00mil 1930.00mil 2040.00mil 1930.00mil 10.00mil 20.00mil "clearline"] + Line[1920.00mil 1930.00mil 1920.00mil 2010.00mil 10.00mil 20.00mil "clearline"] + Line[1980.00mil 1940.00mil 1990.00mil 1930.00mil 10.00mil 20.00mil "clearline"] + Line[1980.00mil 1960.00mil 1990.00mil 1970.00mil 10.00mil 20.00mil "clearline"] + Line[2070.00mil 1930.00mil 2080.00mil 1940.00mil 10.00mil 20.00mil "clearline"] + Line[2080.00mil 1960.00mil 2070.00mil 1970.00mil 10.00mil 20.00mil "clearline"] + Line[1950.00mil 1930.00mil 1960.00mil 1940.00mil 10.00mil 20.00mil "clearline"] + Line[1950.00mil 1970.00mil 1960.00mil 1960.00mil 10.00mil 20.00mil "clearline"] + Line[2240.00mil 1930.00mil 2240.00mil 1970.00mil 10.00mil 20.00mil "clearline"] + Line[2240.00mil 1940.00mil 2250.00mil 1930.00mil 10.00mil 20.00mil "clearline"] + Line[2250.00mil 1930.00mil 2270.00mil 1930.00mil 10.00mil 20.00mil "clearline"] + Line[2280.00mil 1940.00mil 2280.00mil 1970.00mil 10.00mil 20.00mil "clearline"] + Line[2280.00mil 1940.00mil 2270.00mil 1930.00mil 10.00mil 20.00mil "clearline"] + Line[2300.00mil 1940.00mil 2300.00mil 1960.00mil 10.00mil 20.00mil "clearline"] + Line[2310.00mil 1970.00mil 2340.00mil 1970.00mil 10.00mil 20.00mil "clearline"] + Line[2340.00mil 1970.00mil 2340.00mil 1880.00mil 10.00mil 20.00mil "clearline"] + Line[2340.00mil 1930.00mil 2310.00mil 1930.00mil 10.00mil 20.00mil "clearline"] + Line[2300.00mil 1940.00mil 2310.00mil 1930.00mil 10.00mil 20.00mil "clearline"] + Line[2300.00mil 1960.00mil 2310.00mil 1970.00mil 10.00mil 20.00mil "clearline"] + Arc[1920.00mil 2020.00mil 10.00mil 10.00mil 10.00mil 20.00mil 0 360 "clearline"] + Arc[2040.00mil 1870.00mil 10.00mil 10.00mil 10.00mil 20.00mil 0 360 "clearline"] + Arc[2340.00mil 1870.00mil 10.00mil 10.00mil 10.00mil 20.00mil 0 360 "clearline"] + Text[2060.00mil 1860.00mil 0 100 "made with" "clearline"] +) Index: tags/2.3.0/doc/resources/logo_svg.pcb =================================================================== --- tags/2.3.0/doc/resources/logo_svg.pcb (nonexistent) +++ tags/2.3.0/doc/resources/logo_svg.pcb (revision 33253) @@ -0,0 +1,105 @@ +# release: pcb-rnd 1.2.6 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 5080000nm 5080000nm] + +Grid[635000nm 0 0 1] +Cursor[4445000nm 3175000nm 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("9:11:1,3,4,c:7:8:2,5,6,s:12:10") +Styles["Signal,254000nm,1999996nm,800100nm,508000nm:Power,508000nm,2199894nm,999998nm,508000nm:Fat,2032000nm,3500120nm,1199896nm,635000nm:Sig-tight,254000nm,1625600nm,800100nm,304800nm"] + +Symbol['d' 304800nm] +( + SymbolLine[508000nm 0 508000nm 1016000nm 203200nm] + SymbolLine[381000nm 1016000nm 508000nm 889000nm 203200nm] + SymbolLine[127000nm 1016000nm 381000nm 1016000nm 203200nm] + SymbolLine[0 889000nm 127000nm 1016000nm 203200nm] + SymbolLine[0 635000nm 0 889000nm 203200nm] + SymbolLine[0 635000nm 127000nm 508000nm 203200nm] + SymbolLine[127000nm 508000nm 381000nm 508000nm 203200nm] + SymbolLine[381000nm 508000nm 508000nm 635000nm 203200nm] +) +Symbol['n' 304800nm] +( + SymbolLine[127000nm 635000nm 127000nm 1016000nm 203200nm] + SymbolLine[127000nm 635000nm 254000nm 508000nm 203200nm] + SymbolLine[254000nm 508000nm 381000nm 508000nm 203200nm] + SymbolLine[381000nm 508000nm 508000nm 635000nm 203200nm] + SymbolLine[508000nm 635000nm 508000nm 1016000nm 203200nm] + SymbolLine[0 508000nm 127000nm 635000nm 203200nm] +) +Symbol['r' 304800nm] +( + SymbolLine[127000nm 635000nm 127000nm 1016000nm 203200nm] + SymbolLine[127000nm 635000nm 254000nm 508000nm 203200nm] + SymbolLine[254000nm 508000nm 508000nm 508000nm 203200nm] + SymbolLine[0 508000nm 127000nm 635000nm 203200nm] +) +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/buffer_number" "0") +Attribute("PCB::conf::editor/draw_grid" "true") +Attribute("PCB::conf::editor/show_solder_side" "0") +Attribute("PCB::conf::editor/view/flip_x" "0") +Attribute("PCB::conf::editor/view/flip_y" "0") +Attribute("PCB::loader" "geda/pcb - nanometer") + +Element["" "dip(2)" "rnd" "2*300" -5000000nm 2500000nm 6350000nm 635000nm 0 115 ""] +( + Attribute("footprint" "dip(2)") + Attribute("refdes" "rnd") + Attribute("value" "2*300") + Pin[7620000nm 0 2540000nm 1270000nm 2692400nm 999998nm "" "2" "thermal(0X,1X)"] + +) +Layer(1 "component") +( + Polygon("clearpoly") + ( + [0 0] [5080000nm 0] [5080000nm 5080000nm] [0 5080000nm] + ) +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "top-paste") +( +) +Layer(10 "bottom-paste") +( +) +Layer(11 "top-mask") +( +) +Layer(12 "bottom-mask") +( +) +Layer(13 "silk") +( +) +Layer(14 "silk") +( +) Index: tags/2.3.0/doc/resources/screenshot.jpg =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/resources/screenshot.jpg =================================================================== --- tags/2.3.0/doc/resources/screenshot.jpg (nonexistent) +++ tags/2.3.0/doc/resources/screenshot.jpg (revision 33253) Property changes on: tags/2.3.0/doc/resources/screenshot.jpg ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/scripting.txt =================================================================== --- tags/2.3.0/doc/scripting.txt (nonexistent) +++ tags/2.3.0/doc/scripting.txt (revision 33253) @@ -0,0 +1,34 @@ +1. Action scripting +~~~~~~~~~~~~~~~~~~~ +Action scripting is the builtin, non-turing-complete way of giving pcb-rnd +commands. On the GUI it's usually the ':' key that pops up the command line. +Most HIDs support the --listen argument that makes pcb-rnd also read commands +on the stdin. + +The batch HID always reads commands on stdin (without --listen). Automated +pcb-rnd runs from shell is possible using a script like: + +echo ' + action1() + action2() + ... +' | pcb-rnd --gui batch + +From within pcb-rnd the ExecuteFile(filename) action can be used to +load and execute a pcb-rnd action script from a file. + +2. Embedded scripting +~~~~~~~~~~~~~~~~~~~~~ +pcb-rnd uses fungw for embedded scripting. This allows pcb-rnd to be +scripted in 10+ turing complete scripting languages, including awk, tcl, +python, perl, lua, some lisp dialects, etc. Embedded scripts run within +pcb-rnd (in the same process, same address space), having full access +to the action infrastructure: + - embedded scripts can declare new actions that are accessible from + menu, from the command line and from other embedded scripts + - embedded scripts can execute actions (defined by pcb-rnd or other + embedded scripts) + +For more info see user/06_feature/scripting/ + + Index: tags/2.3.0/doc/security/Makefile =================================================================== --- tags/2.3.0/doc/security/Makefile (nonexistent) +++ tags/2.3.0/doc/security/Makefile (revision 33253) @@ -0,0 +1,26 @@ +ROOT=../.. +SECDIR=$(DOCDIR)/security + + +all: + +install_all: + $(SCCBOX) mkdir -p $(SECDIR) + $(SCCBOX) $(HOW) *.html $(SECDIR)/ + $(SCCBOX) $(HOW) README $(SECDIR)/ + +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/2.3.0/doc/security/README =================================================================== --- tags/2.3.0/doc/security/README (nonexistent) +++ tags/2.3.0/doc/security/README (revision 33253) @@ -0,0 +1,2 @@ +This directory contains bugreports that are security sensitive. The +reports also describe mitigation and upgrade paths and safe versions. Index: tags/2.3.0/doc/security/bug1.html =================================================================== --- tags/2.3.0/doc/security/bug1.html (nonexistent) +++ tags/2.3.0/doc/security/bug1.html (revision 33253) @@ -0,0 +1,70 @@ + + + + pcb-rnd - news + + + + + +

pcb-rnd security related bug #1: execbug

+

+Users opening untrusted boards or projects may unintentionally execute +external programs. + +

1. Bug description

+

+pcb-rnd inherited 5 settings from gEDA/PCB that let pcb-rnd (and PCB) +execute external processes, wrapping certain file operations: +

    +
  • conf_core.rc.save_command +
  • conf_core.rc.rat_command +
  • conf_core.rc.library_shell +
  • conf_core.rc.file_command +
  • conf_core.rc.font_command +
+

+The old Settings system has been replaced in pcb-rnd; the new conf system +allows any configuration setting to be specified in a project file or a +board file. This includes the above 5 items as well. +

+Thus an attacker may produce a project or a single board file in .pcb or .lht format +that contains the above config settings, executing arbitrary shell command on the +user's computer when pcb-rnd opens or saves the file or loads fonts or +footprints or netlists. + +

2. How to prevent the attack

+ +

2.1. By using a version that is not affected

+

+

    +
  • from svn /trunk, any revision newer than r11597 +
  • any release starting from 1.2.6 +
  • old stable release 1.2.5, patched: 1.2.5b +
  • old stable release 1.1.4, patched: 1.1.4b +
+ +

2.2. By manually checking board and project files from untrusted source

+

+Before opening the file, grep for _command and _shell in it, remove +the offending lines. + + +

3. What did the patch/fix do

+

+The patch prevents these 5 settings to take effect when the source of +the setting is not from one of these: +

    +
  • internal (embedded in the executable, used as the ultimate fallback when no config is available) +
  • system installed config file (typically under /usr/) +
  • user config file (typically in ~/.pcb-rnd/) +
  • command line argument (-c) +
+

+This bans sources like the board file, the project file and environmental +variable. + + + + + Index: tags/2.3.0/doc/support.html =================================================================== --- tags/2.3.0/doc/support.html (nonexistent) +++ tags/2.3.0/doc/support.html (revision 33253) @@ -0,0 +1,69 @@ + + + + pcb-rnd - news + + + + + + + + + + +
Main + News + Doc & FAQ & pool + Support + People + Events & timeline + pcb-rnd [pcb-rnd logo] +
+ + +
+ +

pcb-rnd support

+ +

Get support

+ +Option 1: subscribe to the 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 pcb-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 repo.hu:6667 #pcb-rnd +
private email Igor2's email address +
private IRC Igor2 on repo.hu or on ircnet +
+

+(We used to provide support on the gEDA mailing lists but we no longer do that.) + + +

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; we are looking +for manpower with a lot of non-programming tasks as well! +

+Option 3: consider donating a small amount , +e.g. $5 or $10. Donations are transformed into developer hours put in the project. + + + + Index: tags/2.3.0/doc/tutorials/15_no_sch/Makefile.inst =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/Makefile.inst (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/Makefile.inst (revision 33253) @@ -0,0 +1,31 @@ +ROOT=../../.. +TUTDIR=$(DOCDIR)/tutorial/15_no_sch + +all: + +install_all: + $(SCCBOX) mkdir -p $(TUTDIR) + $(SCCBOX) $(HOW) step1a.png $(TUTDIR)/step1a.png + $(SCCBOX) $(HOW) step1b.png $(TUTDIR)/step1b.png + $(SCCBOX) $(HOW) step2.lht $(TUTDIR)/step2.lht + $(SCCBOX) $(HOW) step2.png $(TUTDIR)/step2.png + $(SCCBOX) $(HOW) step3.lht $(TUTDIR)/step3.lht + $(SCCBOX) $(HOW) step3a.png $(TUTDIR)/step3a.png + $(SCCBOX) $(HOW) step3b.png $(TUTDIR)/step3b.png + $(SCCBOX) $(HOW) step4.lht $(TUTDIR)/step4.lht + $(SCCBOX) $(HOW) step5.lht $(TUTDIR)/step5.lht + $(SCCBOX) $(HOW) step5.png $(TUTDIR)/step5.png + $(SCCBOX) $(HOW) step6.lht $(TUTDIR)/step6.lht + $(SCCBOX) $(HOW) step6.png $(TUTDIR)/step6.png + $(SCCBOX) $(HOW) index.html $(TUTDIR)/index.html + +install: + $(MAKE) -f Makefile.inst install_all HOW="install -f" + +linstall: + $(MAKE) -f Makefile.inst install_all HOW="install -f -l --absolute " + +uninstall: + $(MAKE) -f Makefile.inst install_all HOW="install -u" + +include $(ROOT)/Makefile.conf Index: tags/2.3.0/doc/tutorials/15_no_sch/index.html =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/index.html (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/index.html (revision 33253) @@ -0,0 +1,197 @@ +

step 1: place two capacitors

+

+Start pcb-rnd - it will start with an empty board (loaded from the +default board, as configured). +

+Pan: click with the scroll wheel of the mouse (or middle button) and move +the mouse; alternatively use the scroll bars at the bottom and right +of the editor area. Zoom: scroll wheel. +

+Press key w then key l (which will be written as {w l} in this tutorial). +This will open the library window ({w l} is for "window, library"). The +library window has a filter entry on the bottom left: enter +acy(200) there and the preview on the right side will show an +axial lead footprint with 200 mil pin distance. Although a typical +thru-hole ceramic capacitor is not axial lead, it will fit nicely in this +footprint: +

+step1: selecting acy(200) from the library window +

+The footprint is in the paste buffer and the buffer tool is selected +(which is visible on the overhead tool bar under the menu). Place +the buffer on the board by a left click. You can exit the buffer mode +by pressing the escape key or F11. +

+The placed footprint is called subcircuit or subc for short. The subc has +a refdes (the main ID of the subc) reading "R1". Grab this "R1" with a +left click and move it out from the middle of the subc and drop it near +the subc so it is readable. Rename the subc to "C1" by pressing {e r} +while hovering the mouse cursor over the subc body (not the refdes text); +{e r} is for "Edit Refdes". +

+Select the subcircuit by clicking it - any point where the subcircuit +has graphics would work, within the red dashed subc frame. The subc will +turn cyan. Note: the refdes text is selected separately from the subc. Make +sure to click on the silk screen graphics (black lines) or a pin to +make the whole subc cyan, not just the refdes text. +

+Once selected, press {e c} ("edit, copy") which will copy the modified subc +to the buffer and will select the buffer tool. Now place it next to the +original subc and modify its refdes to "C2". +

+step1: two capacitors + +

step 2: place the rest

+

+Place the rest of the subcircuits using the same method. It's best to keep +the library window open for all these placements: +

    +
  • a to220, rename it to U1 +
  • an rcy(200), rename it to C3 +
  • two connector(1,2), renamed to J1 and J2 +
+ +

+step2: all parts +

+ Board file for step 2 + + +

step 3: create the gnd net by drawing rat lines

+

+To ease laying out the board, we create a net list by drawing rats. +Rat lines are logical connections between terminals. A terminal is +a pin or pad of a component, addressed as refdes-termid, where +refdes is the host subcircuit's refdes and termid is the unique terminal +ID within the subc. The drawing already has unique refdes assigned to +each subc and the stock footprints we worked from already have unique +terminal IDs. +

+Note: terminal IDs can be shown or hidden by hovering over the subc or +the terminal and pressing {v n} (for "view name"). The ID shows up printed +over the terminal (pin in our case) with tiny red letters - zoom in to see them. +A tooltip also shows the terminal ID after hovering the mouse cursor over the +terminal for a few seconds1. +

+Select the Rats layer on the left - it is part of the "Virtual" layer +group on the bottom. Select the line tool on the overhead toolbar +(second icon from the left). +

+Start drawing a line from J1's terminal 2 (the round one) by left-clicking it. +Left click C1's terminal 2. This is a new logical connection, a new net, so +a popup dialog will ask for the net name. Enter gnd and press enter. +

+The rat line drawing is still active from the last terminal, so go on connecting +C2's terminal 2, J2's terminal 2, U1's middle terminal and C3's negative +terminal. Since these connections are all extending the gnd network, no net name +is asked. When finished, press esc or F11. Don't mind what your rat lines +cross: only the two endpoint of a rat line matter. +

+step3: the gnd network +

+Press {w n} to open the network window: +

+step3: the network window +

+Note: you can zoom/pan the preview on the top right the same way as the main +drawing. If the network selection on the left changes, the right side is +updated. The preview highlights affected terminals. +

+ Board file for step 3 + +

step 4: create the rest of the networks using the same method

+

+

    +
  • network called in: J1-1, C3-1, U1-1, C1-1 +
  • network called out: J2-1, U1-3, C2-1 +
+

+ Board file for step 4 +

+ +

step 5: draw the in and out nets

+

+Select the line tool (hotkey: F2). Select the 'Power' style from the +bottom left style selector - this will get the traces you'll be +drawing thicker. Select the bottom signal layer, called "bottom-sig" in +the layer selector on the left. This way the new traces will end up on +copper on the bottom side of the board. +

+Start drawing a line from J1-1 with left click. The line will bend in +45 degrees. You can press the shift key and move the mouse to invert +the refraction temporarily, or use the slash key to cycle through different +refraction (including the ortho mode, which allows 90 degree lines only). +With 2..3 clicks, connect J1-1 and C3's '+' pin. +

+Now that one of the logical connections is turned to copper, press {c r} +(for "connection, refresh rats") - this will recalculate all rats, considering +already established connections. +

+Draw the remaining segments of the in net, using {c r} to see the +progress. The number of remaining rat lines is also printed in the message +log, which can be opened using {w m}. +

+Do the same for the out network. At the end only the gnd network +should remain unrouted: +

+step4: in and out routed +

+ Board file for step 5. + +

step 6: draw the gnd poly

+

+We could route the gnd net the same way, using thick traces. +However, it's more common to have a solid ground plane/pour, which is +a polygon in pcb-rnd. +

+Select the bottom-gnd layer. This layer is in the same layer group, +bottom copper, as the other layer we used, so at the end it will go +on the same physical copper layer. However, it has a different color +configured on screen, which would make it easier to see what's connected +to gnd. +

+Select the rect tool from the toolbar. This will draw a rectangular polygon. +Do a single click on the top left corner of your circuit. After releasing +the mouse button, the rectangle tool draws an overlay indication on how big +the polygon would be. Move the mouse cursor to the bottom right corner until the +box encloses the whole circuit and some margin and do another single click. +

+This will finish the operation and a large red rectangular polygon will appear. +However, {c r} shows that no gnd rat line got routed: the terminals of +the subcircuits won't automatically touch the polygon. The easiest way to +get them connected is using the thermal tool (labelled THRM in the toolbar). +Select the thermal tool and click on the J1-2. An X shaped connection will +appear to the polygon. +

+Note: it's important to still have the bottom-gnd +layer selected: the thermal tool connects the terminal to the polygon on the +currently selected layer, so the currently selected layer should be the one +we drew the ground plane polygon on. +

+Another click on the terminal would remove the thermal - it's a toggle operation. +When the thermal is there, a shift+click with the thermal tool will change +the thermal style, cycling through different available styles. +

+Use the thermal tool to connect all gnd terminals and press {c r}. +

+step6: board finished +

+ Board file for step 6. + + +

Note on the view

+

+We've been drawing the board from looking at it from the top, with +'x-ray vision', seeing all copper on the bottom. Once the board is fabricated, +this is not how we'll see it. +

+It is possible to flip the board using the tab key, to get a bottom view. +There's also shift-tab an ctrl-tab to flip among different axes. Flipping +is a view-only feature, it does not modify any geometry or physical +property of the board. + +


+Footnotes: +
    +
  • 1: may not be available in the lesstif HID +
Index: tags/2.3.0/doc/tutorials/15_no_sch/step1a.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/tutorials/15_no_sch/step1a.png =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step1a.png (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step1a.png (revision 33253) Property changes on: tags/2.3.0/doc/tutorials/15_no_sch/step1a.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/tutorials/15_no_sch/step1b.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/tutorials/15_no_sch/step1b.png =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step1b.png (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step1b.png (revision 33253) Property changes on: tags/2.3.0/doc/tutorials/15_no_sch/step1b.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/tutorials/15_no_sch/step2.lht =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step2.lht (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step2.lht (revision 33253) @@ -0,0 +1,2107 @@ +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 = 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 = 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 { + ha:subc.1158 { + ha:attributes { + value=TO220 + footprint=Transistor + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.2 { + hdia=130.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1229 { + proto=0; x=44.45mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.1230 { + proto=1; x=46.99mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + ha:padstack_ref.1231 { + proto=1; x=49.53mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=3 + name=3 + } + } + ha:padstack_ref.1232 { + proto=2; x=46.99mm; y=1.13in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=4 + name=4 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1159 { + x1=44.45mm; y1=1.8in; x2=44.45mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1162 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1165 { + x1=49.53mm; y1=1.8in; x2=49.53mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1168 { + x1=1.65in; y1=1.62in; x2=52.07mm; y2=1.62in; thickness=20.0mil; clearance=0.0; + } + ha:line.1171 { + x1=52.07mm; y1=1.62in; x2=52.07mm; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1174 { + x1=52.07mm; y1=31.623mm; x2=1.65in; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1177 { + x1=1.65in; y1=31.623mm; x2=1.65in; y2=1.62in; thickness=20.0mil; clearance=0.0; + } + ha:line.1180 { + x1=1.65in; y1=31.623mm; x2=52.07mm; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1183 { + x1=52.07mm; y1=31.623mm; x2=52.07mm; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1186 { + x1=52.07mm; y1=1.12in; x2=51.689mm; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1189 { + x1=51.689mm; y1=1.12in; x2=51.689mm; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1192 { + x1=51.689mm; y1=26.67mm; x2=52.07mm; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1195 { + x1=52.07mm; y1=26.67mm; x2=52.07mm; y2=1.01in; thickness=20.0mil; clearance=0.0; + } + ha:line.1198 { + x1=52.07mm; y1=1.01in; x2=1.65in; y2=1.01in; thickness=20.0mil; clearance=0.0; + } + ha:line.1201 { + x1=1.65in; y1=1.01in; x2=1.65in; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1204 { + x1=1.65in; y1=26.67mm; x2=1.665in; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1207 { + x1=1.665in; y1=26.67mm; x2=1.665in; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1210 { + x1=1.665in; y1=1.12in; x2=1.65in; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1213 { + x1=1.65in; y1=1.12in; x2=1.65in; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:text.1216 { + string=%a.parent.refdes%; x=40.005mm; y=27.813mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 90.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1217 { + x1=46.99mm; y1=1.6325in; x2=46.99mm; y2=1.6325in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1220 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=1.8in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1223 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=46.72mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1226 { + x1=46.99mm; y1=1.8in; x2=47.99mm; y2=1.8in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAJ + } + ha:subc.1234 { + ha:attributes { + value=acy200 + footprint=rcy(200) + refdes=C3 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1258 { + proto=0; x=31.75mm; y=1.525in; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1259 { + proto=1; x=36.83mm; y=1.525in; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1235 { + x1=1.57in; y1=1.525in; x2=1.61in; y2=1.525in; thickness=10.0mil; clearance=0.0; + } + ha:line.1238 { + x1=1.09in; y1=1.525in; x2=1.13in; y2=1.525in; thickness=10.0mil; clearance=0.0; + } + ha:line.1241 { + x1=1.11in; y1=1.505in; x2=1.11in; y2=39.243mm; thickness=10.0mil; clearance=0.0; + } + ha:arc.1244 { + x=1.35in; y=1.525in; width=200.0mil; height=200.0mil; astart=0; adelta=360; thickness=10.0mil; clearance=0.0; + } + ha:text.1245 { + string=%a.parent.refdes%; x=1.31in; y=31.242mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1246 { + x1=1.35in; y1=1.525in; x2=1.35in; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1249 { + x1=31.75mm; y1=1.525in; x2=31.75mm; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1252 { + x1=31.75mm; y1=1.525in; x2=32.75mm; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1255 { + x1=31.75mm; y1=1.525in; x2=31.75mm; y2=39.735mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAL + } + ha:subc.1261 { + ha:attributes { + value=1*2 + footprint=connector(1,2) + refdes=J1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1293 { + proto=0; x=975.0mil; y=46.355mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1294 { + proto=1; x=975.0mil; y=48.895mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1262 { + x1=925.0mil; y1=45.085mm; x2=925.0mil; y2=1.975in; thickness=10.0mil; clearance=0.0; + } + ha:line.1265 { + x1=925.0mil; y1=45.085mm; x2=26.035mm; y2=45.085mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1268 { + x1=26.035mm; y1=1.975in; x2=925.0mil; y2=1.975in; thickness=10.0mil; clearance=0.0; + } + ha:line.1271 { + x1=26.035mm; y1=1.975in; x2=26.035mm; y2=45.085mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1274 { + x1=925.0mil; y1=47.625mm; x2=26.035mm; y2=47.625mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1277 { + x1=26.035mm; y1=45.085mm; x2=26.035mm; y2=47.625mm; thickness=10.0mil; clearance=0.0; + } + ha:text.1280 { + string=%a.parent.refdes%; x=950.0mil; y=42.545mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1281 { + x1=975.0mil; y1=47.625mm; x2=975.0mil; y2=47.625mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1284 { + x1=975.0mil; y1=46.355mm; x2=975.0mil; y2=46.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1287 { + x1=975.0mil; y1=46.355mm; x2=975.0mil; y2=45.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1290 { + x1=975.0mil; y1=46.355mm; x2=23.765mm; y2=46.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAN + } + ha:subc.1296 { + ha:attributes { + value=1*2 + footprint=connector(1,2) + refdes=J2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1328 { + proto=0; x=60.96mm; y=46.99mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1329 { + proto=1; x=60.96mm; y=49.53mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1297 { + x1=2.35in; y1=1.8in; x2=2.35in; y2=2.0in; thickness=10.0mil; clearance=0.0; + } + ha:line.1300 { + x1=2.35in; y1=1.8in; x2=2.45in; y2=1.8in; thickness=10.0mil; clearance=0.0; + } + ha:line.1303 { + x1=2.45in; y1=2.0in; x2=2.35in; y2=2.0in; thickness=10.0mil; clearance=0.0; + } + ha:line.1306 { + x1=2.45in; y1=2.0in; x2=2.45in; y2=1.8in; thickness=10.0mil; clearance=0.0; + } + ha:line.1309 { + x1=2.35in; y1=1.9in; x2=2.45in; y2=1.9in; thickness=10.0mil; clearance=0.0; + } + ha:line.1312 { + x1=2.45in; y1=1.8in; x2=2.45in; y2=1.9in; thickness=10.0mil; clearance=0.0; + } + ha:text.1315 { + string=%a.parent.refdes%; x=60.325mm; y=43.18mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1316 { + x1=60.96mm; y1=1.9in; x2=60.96mm; y2=1.9in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1319 { + x1=60.96mm; y1=46.99mm; x2=60.96mm; y2=46.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1322 { + x1=60.96mm; y1=46.99mm; x2=60.96mm; y2=45.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1325 { + x1=60.96mm; y1=46.99mm; x2=59.96mm; y2=46.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAN + } + ha:subc.1331 { + ha:attributes { + value=acy200 + footprint=acy(200) + refdes=C1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1363 { + proto=0; x=38.1mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1364 { + proto=1; x=43.18mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1332 { + x1=38.1mm; y1=53.975mm; x2=1.55in; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1335 { + x1=1.65in; y1=53.975mm; x2=43.18mm; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1338 { + x1=1.55in; y1=2.10834in; x2=1.55in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1341 { + x1=1.55in; y1=2.10834in; x2=1.65in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:line.1344 { + x1=1.65in; y1=54.398164mm; x2=1.55in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1347 { + x1=1.65in; y1=54.398164mm; x2=1.65in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:text.1350 { + string=%a.parent.refdes%; x=1.56in; y=50.927mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1351 { + x1=1.6in; y1=53.975mm; x2=1.6in; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1354 { + x1=38.1mm; y1=53.975mm; x2=38.1mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1357 { + x1=38.1mm; y1=53.975mm; x2=39.1mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1360 { + x1=38.1mm; y1=53.975mm; x2=38.1mm; y2=54.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAB + } + ha:subc.1366 { + ha:attributes { + value=acy200 + footprint=acy(200) + refdes=C2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1398 { + proto=0; x=48.895mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1399 { + proto=1; x=53.975mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1367 { + x1=48.895mm; y1=53.975mm; x2=1.975in; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1370 { + x1=2.075in; y1=53.975mm; x2=53.975mm; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1373 { + x1=1.975in; y1=2.10834in; x2=1.975in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1376 { + x1=1.975in; y1=2.10834in; x2=2.075in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:line.1379 { + x1=2.075in; y1=54.398164mm; x2=1.975in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1382 { + x1=2.075in; y1=54.398164mm; x2=2.075in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:text.1385 { + string=%a.parent.refdes%; x=1.985in; y=50.927mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1386 { + x1=51.435mm; y1=53.975mm; x2=51.435mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1389 { + x1=48.895mm; y1=53.975mm; x2=48.895mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.1392 { + x1=48.895mm; y1=53.975mm; x2=49.895mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.1395 { + x1=48.895mm; y1=53.975mm; x2=48.895mm; y2=54.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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 + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + text_thickness = 0 + line_thickness = 10.00 mil + poly_isle_area = 200000000.0 + clearance = 20.00 mil + } + ha:editor { + buffer_number = 0 + draw_grid = false + grids_idx = 4 + grid = 25.00 mil + } + } + } +} Index: tags/2.3.0/doc/tutorials/15_no_sch/step2.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/tutorials/15_no_sch/step2.png =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step2.png (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step2.png (revision 33253) Property changes on: tags/2.3.0/doc/tutorials/15_no_sch/step2.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/tutorials/15_no_sch/step3.lht =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step3.lht (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step3.lht (revision 33253) @@ -0,0 +1,2154 @@ +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 = 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 = 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 { + ha:subc.1158 { + ha:attributes { + value=TO220 + footprint=Transistor + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.2 { + hdia=130.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1229 { + proto=0; x=44.45mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.1230 { + proto=1; x=46.99mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + ha:padstack_ref.1231 { + proto=1; x=49.53mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=3 + name=3 + } + } + ha:padstack_ref.1232 { + proto=2; x=46.99mm; y=1.13in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=4 + name=4 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1159 { + x1=44.45mm; y1=1.8in; x2=44.45mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1162 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1165 { + x1=49.53mm; y1=1.8in; x2=49.53mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1168 { + x1=1.65in; y1=1.62in; x2=52.07mm; y2=1.62in; thickness=20.0mil; clearance=0.0; + } + ha:line.1171 { + x1=52.07mm; y1=1.62in; x2=52.07mm; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1174 { + x1=52.07mm; y1=31.623mm; x2=1.65in; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1177 { + x1=1.65in; y1=31.623mm; x2=1.65in; y2=1.62in; thickness=20.0mil; clearance=0.0; + } + ha:line.1180 { + x1=1.65in; y1=31.623mm; x2=52.07mm; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1183 { + x1=52.07mm; y1=31.623mm; x2=52.07mm; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1186 { + x1=52.07mm; y1=1.12in; x2=51.689mm; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1189 { + x1=51.689mm; y1=1.12in; x2=51.689mm; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1192 { + x1=51.689mm; y1=26.67mm; x2=52.07mm; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1195 { + x1=52.07mm; y1=26.67mm; x2=52.07mm; y2=1.01in; thickness=20.0mil; clearance=0.0; + } + ha:line.1198 { + x1=52.07mm; y1=1.01in; x2=1.65in; y2=1.01in; thickness=20.0mil; clearance=0.0; + } + ha:line.1201 { + x1=1.65in; y1=1.01in; x2=1.65in; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1204 { + x1=1.65in; y1=26.67mm; x2=1.665in; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1207 { + x1=1.665in; y1=26.67mm; x2=1.665in; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1210 { + x1=1.665in; y1=1.12in; x2=1.65in; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1213 { + x1=1.65in; y1=1.12in; x2=1.65in; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:text.1216 { + string=%a.parent.refdes%; x=40.005mm; y=27.813mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 90.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1217 { + x1=46.99mm; y1=1.6325in; x2=46.99mm; y2=1.6325in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1220 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=1.8in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1223 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=46.72mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1226 { + x1=46.99mm; y1=1.8in; x2=47.99mm; y2=1.8in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAJ + } + ha:subc.1234 { + ha:attributes { + value=acy200 + footprint=rcy(200) + refdes=C3 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1258 { + proto=0; x=31.75mm; y=1.525in; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1259 { + proto=1; x=36.83mm; y=1.525in; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1235 { + x1=1.57in; y1=1.525in; x2=1.61in; y2=1.525in; thickness=10.0mil; clearance=0.0; + } + ha:line.1238 { + x1=1.09in; y1=1.525in; x2=1.13in; y2=1.525in; thickness=10.0mil; clearance=0.0; + } + ha:line.1241 { + x1=1.11in; y1=1.505in; x2=1.11in; y2=39.243mm; thickness=10.0mil; clearance=0.0; + } + ha:arc.1244 { + x=1.35in; y=1.525in; width=200.0mil; height=200.0mil; astart=0; adelta=360; thickness=10.0mil; clearance=0.0; + } + ha:text.1245 { + string=%a.parent.refdes%; x=1.31in; y=31.242mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1246 { + x1=1.35in; y1=1.525in; x2=1.35in; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1249 { + x1=31.75mm; y1=1.525in; x2=31.75mm; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1252 { + x1=31.75mm; y1=1.525in; x2=32.75mm; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1255 { + x1=31.75mm; y1=1.525in; x2=31.75mm; y2=39.735mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAL + } + ha:subc.1261 { + ha:attributes { + value=1*2 + footprint=connector(1,2) + refdes=J1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1293 { + proto=0; x=975.0mil; y=46.355mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1294 { + proto=1; x=975.0mil; y=48.895mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1262 { + x1=925.0mil; y1=45.085mm; x2=925.0mil; y2=1.975in; thickness=10.0mil; clearance=0.0; + } + ha:line.1265 { + x1=925.0mil; y1=45.085mm; x2=26.035mm; y2=45.085mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1268 { + x1=26.035mm; y1=1.975in; x2=925.0mil; y2=1.975in; thickness=10.0mil; clearance=0.0; + } + ha:line.1271 { + x1=26.035mm; y1=1.975in; x2=26.035mm; y2=45.085mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1274 { + x1=925.0mil; y1=47.625mm; x2=26.035mm; y2=47.625mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1277 { + x1=26.035mm; y1=45.085mm; x2=26.035mm; y2=47.625mm; thickness=10.0mil; clearance=0.0; + } + ha:text.1280 { + string=%a.parent.refdes%; x=950.0mil; y=42.545mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1281 { + x1=975.0mil; y1=47.625mm; x2=975.0mil; y2=47.625mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1284 { + x1=975.0mil; y1=46.355mm; x2=975.0mil; y2=46.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1287 { + x1=975.0mil; y1=46.355mm; x2=975.0mil; y2=45.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1290 { + x1=975.0mil; y1=46.355mm; x2=23.765mm; y2=46.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAN + } + ha:subc.1296 { + ha:attributes { + value=1*2 + footprint=connector(1,2) + refdes=J2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1328 { + proto=0; x=60.96mm; y=46.99mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1329 { + proto=1; x=60.96mm; y=49.53mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1297 { + x1=2.35in; y1=1.8in; x2=2.35in; y2=2.0in; thickness=10.0mil; clearance=0.0; + } + ha:line.1300 { + x1=2.35in; y1=1.8in; x2=2.45in; y2=1.8in; thickness=10.0mil; clearance=0.0; + } + ha:line.1303 { + x1=2.45in; y1=2.0in; x2=2.35in; y2=2.0in; thickness=10.0mil; clearance=0.0; + } + ha:line.1306 { + x1=2.45in; y1=2.0in; x2=2.45in; y2=1.8in; thickness=10.0mil; clearance=0.0; + } + ha:line.1309 { + x1=2.35in; y1=1.9in; x2=2.45in; y2=1.9in; thickness=10.0mil; clearance=0.0; + } + ha:line.1312 { + x1=2.45in; y1=1.8in; x2=2.45in; y2=1.9in; thickness=10.0mil; clearance=0.0; + } + ha:text.1315 { + string=%a.parent.refdes%; x=60.325mm; y=43.18mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1316 { + x1=60.96mm; y1=1.9in; x2=60.96mm; y2=1.9in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1319 { + x1=60.96mm; y1=46.99mm; x2=60.96mm; y2=46.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1322 { + x1=60.96mm; y1=46.99mm; x2=60.96mm; y2=45.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1325 { + x1=60.96mm; y1=46.99mm; x2=59.96mm; y2=46.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAN + } + ha:subc.1331 { + ha:attributes { + value=acy200 + footprint=acy(200) + refdes=C1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1363 { + proto=0; x=38.1mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1364 { + proto=1; x=43.18mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1332 { + x1=38.1mm; y1=53.975mm; x2=1.55in; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1335 { + x1=1.65in; y1=53.975mm; x2=43.18mm; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1338 { + x1=1.55in; y1=2.10834in; x2=1.55in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1341 { + x1=1.55in; y1=2.10834in; x2=1.65in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:line.1344 { + x1=1.65in; y1=54.398164mm; x2=1.55in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1347 { + x1=1.65in; y1=54.398164mm; x2=1.65in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:text.1350 { + string=%a.parent.refdes%; x=1.56in; y=50.927mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1351 { + x1=1.6in; y1=53.975mm; x2=1.6in; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1354 { + x1=38.1mm; y1=53.975mm; x2=38.1mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1357 { + x1=38.1mm; y1=53.975mm; x2=39.1mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1360 { + x1=38.1mm; y1=53.975mm; x2=38.1mm; y2=54.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAB + } + ha:subc.1366 { + ha:attributes { + value=acy200 + footprint=acy(200) + refdes=C2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1398 { + proto=0; x=48.895mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1399 { + proto=1; x=53.975mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1367 { + x1=48.895mm; y1=53.975mm; x2=1.975in; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1370 { + x1=2.075in; y1=53.975mm; x2=53.975mm; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1373 { + x1=1.975in; y1=2.10834in; x2=1.975in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1376 { + x1=1.975in; y1=2.10834in; x2=2.075in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:line.1379 { + x1=2.075in; y1=54.398164mm; x2=1.975in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1382 { + x1=2.075in; y1=54.398164mm; x2=2.075in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:text.1385 { + string=%a.parent.refdes%; x=1.985in; y=50.927mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1386 { + x1=51.435mm; y1=53.975mm; x2=51.435mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1389 { + x1=48.895mm; y1=53.975mm; x2=48.895mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.1392 { + x1=48.895mm; y1=53.975mm; x2=49.895mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.1395 { + x1=48.895mm; y1=53.975mm; x2=48.895mm; y2=54.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAB + } + ha:rat.1400 { + x1=975.0mil; y1=48.895mm; lgrp1=3; x2=43.18mm; y2=53.975mm; lgrp2=3; + } + ha:rat.1403 { + x1=43.18mm; y1=53.975mm; lgrp1=3; x2=53.975mm; y2=53.975mm; lgrp2=3; + } + ha:rat.1406 { + x1=53.975mm; y1=53.975mm; lgrp1=3; x2=60.96mm; y2=49.53mm; lgrp2=3; + } + ha:rat.1409 { + x1=60.96mm; y1=49.53mm; lgrp1=3; x2=46.99mm; y2=1.8in; lgrp2=3; + } + ha:rat.1412 { + x1=46.99mm; y1=1.8in; lgrp1=3; x2=36.83mm; y2=1.525in; lgrp2=3; + } + ha:rat.1415 { + x1=975.0mil; y1=46.355mm; lgrp1=3; x2=31.75mm; y2=1.525in; lgrp2=3; + } + ha:rat.1418 { + x1=31.75mm; y1=1.525in; lgrp1=3; x2=44.45mm; y2=1.8in; lgrp2=3; + } + ha:rat.1421 { + x1=44.45mm; y1=1.8in; lgrp1=3; x2=38.1mm; y2=53.975mm; lgrp2=3; + } + ha:rat.1424 { + x1=60.96mm; y1=46.99mm; lgrp1=3; x2=49.53mm; y2=1.8in; lgrp2=3; + } + ha:rat.1427 { + x1=49.53mm; y1=1.8in; lgrp1=3; x2=48.895mm; y2=53.975mm; lgrp2=3; + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:netlist_patch { + ha:add_conn { net=gnd; term=J1-2; } + ha:add_conn { net=gnd; term=C1-2; } + ha:add_conn { net=gnd; term=C2-2; } + ha:add_conn { net=gnd; term=J2-2; } + ha:add_conn { net=gnd; term=U1-2; } + ha:add_conn { net=gnd; term=C3-2; } + ha:add_conn { net=in; term=J1-1; } + ha:add_conn { net=in; term=C3-1; } + ha:add_conn { net=in; term=U1-1; } + ha:add_conn { net=in; term=C1-1; } + ha:add_conn { net=out; term=J2-1; } + ha:add_conn { net=out; term=U1-3; } + ha:add_conn { net=out; term=C2-1; } + } + } + 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 + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + text_thickness = 0 + line_thickness = 10.00 mil + poly_isle_area = 200000000.0 + clearance = 20.00 mil + } + ha:editor { + buffer_number = 0 + draw_grid = false + grids_idx = 4 + grid = 25.00 mil + } + } + } +} Index: tags/2.3.0/doc/tutorials/15_no_sch/step3a.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/tutorials/15_no_sch/step3a.png =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step3a.png (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step3a.png (revision 33253) Property changes on: tags/2.3.0/doc/tutorials/15_no_sch/step3a.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/tutorials/15_no_sch/step3b.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/tutorials/15_no_sch/step3b.png =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step3b.png (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step3b.png (revision 33253) Property changes on: tags/2.3.0/doc/tutorials/15_no_sch/step3b.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/tutorials/15_no_sch/step4.lht =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step4.lht (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step4.lht (revision 33253) @@ -0,0 +1,2235 @@ +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 = 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 = 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 { + ha:subc.1158 { + ha:attributes { + value=TO220 + footprint=Transistor + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.2 { + hdia=130.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1229 { + proto=0; x=44.45mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.1230 { + proto=1; x=46.99mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + name=2 + } + } + ha:padstack_ref.1231 { + proto=1; x=49.53mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=3 + name=3 + } + } + ha:padstack_ref.1232 { + proto=2; x=46.99mm; y=1.13in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=4 + name=4 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1159 { + x1=44.45mm; y1=1.8in; x2=44.45mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1162 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1165 { + x1=49.53mm; y1=1.8in; x2=49.53mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1168 { + x1=1.65in; y1=1.62in; x2=52.07mm; y2=1.62in; thickness=20.0mil; clearance=0.0; + } + ha:line.1171 { + x1=52.07mm; y1=1.62in; x2=52.07mm; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1174 { + x1=52.07mm; y1=31.623mm; x2=1.65in; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1177 { + x1=1.65in; y1=31.623mm; x2=1.65in; y2=1.62in; thickness=20.0mil; clearance=0.0; + } + ha:line.1180 { + x1=1.65in; y1=31.623mm; x2=52.07mm; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1183 { + x1=52.07mm; y1=31.623mm; x2=52.07mm; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1186 { + x1=52.07mm; y1=1.12in; x2=51.689mm; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1189 { + x1=51.689mm; y1=1.12in; x2=51.689mm; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1192 { + x1=51.689mm; y1=26.67mm; x2=52.07mm; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1195 { + x1=52.07mm; y1=26.67mm; x2=52.07mm; y2=1.01in; thickness=20.0mil; clearance=0.0; + } + ha:line.1198 { + x1=52.07mm; y1=1.01in; x2=1.65in; y2=1.01in; thickness=20.0mil; clearance=0.0; + } + ha:line.1201 { + x1=1.65in; y1=1.01in; x2=1.65in; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1204 { + x1=1.65in; y1=26.67mm; x2=1.665in; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1207 { + x1=1.665in; y1=26.67mm; x2=1.665in; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1210 { + x1=1.665in; y1=1.12in; x2=1.65in; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1213 { + x1=1.65in; y1=1.12in; x2=1.65in; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:text.1216 { + string=%a.parent.refdes%; x=40.005mm; y=27.813mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 90.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1217 { + x1=46.99mm; y1=1.6325in; x2=46.99mm; y2=1.6325in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1220 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=1.8in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1223 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=46.72mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1226 { + x1=46.99mm; y1=1.8in; x2=47.99mm; y2=1.8in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAJ + } + ha:subc.1234 { + ha:attributes { + value=acy200 + footprint=rcy(200) + refdes=C3 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1258 { + proto=0; x=31.75mm; y=1.525in; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1259 { + proto=1; x=36.83mm; y=1.525in; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1235 { + x1=1.57in; y1=1.525in; x2=1.61in; y2=1.525in; thickness=10.0mil; clearance=0.0; + } + ha:line.1238 { + x1=1.09in; y1=1.525in; x2=1.13in; y2=1.525in; thickness=10.0mil; clearance=0.0; + } + ha:line.1241 { + x1=1.11in; y1=1.505in; x2=1.11in; y2=39.243mm; thickness=10.0mil; clearance=0.0; + } + ha:arc.1244 { + x=1.35in; y=1.525in; width=200.0mil; height=200.0mil; astart=0; adelta=360; thickness=10.0mil; clearance=0.0; + } + ha:text.1245 { + string=%a.parent.refdes%; x=1.31in; y=31.242mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1246 { + x1=1.35in; y1=1.525in; x2=1.35in; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1249 { + x1=31.75mm; y1=1.525in; x2=31.75mm; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1252 { + x1=31.75mm; y1=1.525in; x2=32.75mm; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1255 { + x1=31.75mm; y1=1.525in; x2=31.75mm; y2=39.735mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAL + } + ha:subc.1261 { + ha:attributes { + value=1*2 + footprint=connector(1,2) + refdes=J1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1293 { + proto=0; x=975.0mil; y=46.355mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1294 { + proto=1; x=975.0mil; y=48.895mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + round + noshape + } + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1262 { + x1=925.0mil; y1=45.085mm; x2=925.0mil; y2=1.975in; thickness=10.0mil; clearance=0.0; + } + ha:line.1265 { + x1=925.0mil; y1=45.085mm; x2=26.035mm; y2=45.085mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1268 { + x1=26.035mm; y1=1.975in; x2=925.0mil; y2=1.975in; thickness=10.0mil; clearance=0.0; + } + ha:line.1271 { + x1=26.035mm; y1=1.975in; x2=26.035mm; y2=45.085mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1274 { + x1=925.0mil; y1=47.625mm; x2=26.035mm; y2=47.625mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1277 { + x1=26.035mm; y1=45.085mm; x2=26.035mm; y2=47.625mm; thickness=10.0mil; clearance=0.0; + } + ha:text.1280 { + string=%a.parent.refdes%; x=950.0mil; y=42.545mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1281 { + x1=975.0mil; y1=47.625mm; x2=975.0mil; y2=47.625mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1284 { + x1=975.0mil; y1=46.355mm; x2=975.0mil; y2=46.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1287 { + x1=975.0mil; y1=46.355mm; x2=975.0mil; y2=45.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1290 { + x1=975.0mil; y1=46.355mm; x2=23.765mm; y2=46.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAN + } + ha:subc.1296 { + ha:attributes { + value=1*2 + footprint=connector(1,2) + refdes=J2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1328 { + proto=0; x=60.96mm; y=46.99mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1329 { + proto=1; x=60.96mm; y=49.53mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1297 { + x1=2.35in; y1=1.8in; x2=2.35in; y2=2.0in; thickness=10.0mil; clearance=0.0; + } + ha:line.1300 { + x1=2.35in; y1=1.8in; x2=2.45in; y2=1.8in; thickness=10.0mil; clearance=0.0; + } + ha:line.1303 { + x1=2.45in; y1=2.0in; x2=2.35in; y2=2.0in; thickness=10.0mil; clearance=0.0; + } + ha:line.1306 { + x1=2.45in; y1=2.0in; x2=2.45in; y2=1.8in; thickness=10.0mil; clearance=0.0; + } + ha:line.1309 { + x1=2.35in; y1=1.9in; x2=2.45in; y2=1.9in; thickness=10.0mil; clearance=0.0; + } + ha:line.1312 { + x1=2.45in; y1=1.8in; x2=2.45in; y2=1.9in; thickness=10.0mil; clearance=0.0; + } + ha:text.1315 { + string=%a.parent.refdes%; x=60.325mm; y=43.18mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1316 { + x1=60.96mm; y1=1.9in; x2=60.96mm; y2=1.9in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1319 { + x1=60.96mm; y1=46.99mm; x2=60.96mm; y2=46.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1322 { + x1=60.96mm; y1=46.99mm; x2=60.96mm; y2=45.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1325 { + x1=60.96mm; y1=46.99mm; x2=59.96mm; y2=46.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAN + } + ha:subc.1331 { + ha:attributes { + value=acy200 + footprint=acy(200) + refdes=C1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1363 { + proto=0; x=38.1mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1364 { + proto=1; x=43.18mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1332 { + x1=38.1mm; y1=53.975mm; x2=1.55in; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1335 { + x1=1.65in; y1=53.975mm; x2=43.18mm; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1338 { + x1=1.55in; y1=2.10834in; x2=1.55in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1341 { + x1=1.55in; y1=2.10834in; x2=1.65in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:line.1344 { + x1=1.65in; y1=54.398164mm; x2=1.55in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1347 { + x1=1.65in; y1=54.398164mm; x2=1.65in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:text.1350 { + string=%a.parent.refdes%; x=1.56in; y=50.927mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1351 { + x1=1.6in; y1=53.975mm; x2=1.6in; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1354 { + x1=38.1mm; y1=53.975mm; x2=38.1mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1357 { + x1=38.1mm; y1=53.975mm; x2=39.1mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1360 { + x1=38.1mm; y1=53.975mm; x2=38.1mm; y2=54.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAB + } + ha:subc.1366 { + ha:attributes { + value=acy200 + footprint=acy(200) + refdes=C2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1398 { + proto=0; x=48.895mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1399 { + proto=1; x=53.975mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1367 { + x1=48.895mm; y1=53.975mm; x2=1.975in; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1370 { + x1=2.075in; y1=53.975mm; x2=53.975mm; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1373 { + x1=1.975in; y1=2.10834in; x2=1.975in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1376 { + x1=1.975in; y1=2.10834in; x2=2.075in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:line.1379 { + x1=2.075in; y1=54.398164mm; x2=1.975in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1382 { + x1=2.075in; y1=54.398164mm; x2=2.075in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:text.1385 { + string=%a.parent.refdes%; x=1.985in; y=50.927mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1386 { + x1=51.435mm; y1=53.975mm; x2=51.435mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1389 { + x1=48.895mm; y1=53.975mm; x2=48.895mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.1392 { + x1=48.895mm; y1=53.975mm; x2=49.895mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.1395 { + x1=48.895mm; y1=53.975mm; x2=48.895mm; y2=54.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAB + } + ha:rat.1529 { + x1=53.975mm; y1=53.975mm; lgrp1=3; x2=60.96mm; y2=49.53mm; lgrp2=3; + } + ha:rat.1526 { + x1=43.18mm; y1=53.975mm; lgrp1=3; x2=53.975mm; y2=53.975mm; lgrp2=3; + } + ha:rat.1523 { + x1=43.18mm; y1=53.975mm; lgrp1=3; x2=46.99mm; y2=1.8in; lgrp2=3; + } + ha:rat.1520 { + x1=46.99mm; y1=1.8in; lgrp1=3; x2=36.83mm; y2=1.525in; lgrp2=3; + } + ha:rat.1517 { + x1=975.0mil; y1=48.895mm; lgrp1=3; x2=36.83mm; y2=1.525in; lgrp2=3; + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + ha:line.1433 { + x1=1.175in; y1=46.355mm; x2=31.75mm; y2=44.45mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1436 { + x1=31.75mm; y1=44.45mm; x2=31.75mm; y2=1.525in; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1472 { + x1=1.375in; y1=46.355mm; x2=38.1mm; y2=49.53mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1475 { + x1=38.1mm; y1=49.53mm; x2=38.1mm; y2=53.975mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1478 { + x1=975.0mil; y1=46.355mm; x2=1.725in; y2=46.355mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1481 { + x1=1.725in; y1=46.355mm; x2=44.45mm; y2=1.8in; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1505 { + x1=49.53mm; y1=1.8in; x2=2.35in; y2=1.8in; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1508 { + x1=2.35in; y1=1.8in; x2=60.96mm; y2=46.99mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1511 { + x1=49.53mm; y1=1.8in; x2=48.895mm; y2=46.355mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1514 { + x1=48.895mm; y1=46.355mm; x2=48.895mm; y2=53.975mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:netlist_patch { + ha:add_conn { net=gnd; term=J1-2; } + ha:add_conn { net=gnd; term=C1-2; } + ha:add_conn { net=gnd; term=C2-2; } + ha:add_conn { net=gnd; term=J2-2; } + ha:add_conn { net=gnd; term=U1-2; } + ha:add_conn { net=gnd; term=C3-2; } + ha:add_conn { net=in; term=J1-1; } + ha:add_conn { net=in; term=C3-1; } + ha:add_conn { net=in; term=U1-1; } + ha:add_conn { net=in; term=C1-1; } + ha:add_conn { net=out; term=J2-1; } + ha:add_conn { net=out; term=U1-3; } + ha:add_conn { net=out; term=C2-1; } + } + } + 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 + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + text_scale = 100 + via_thickness = 2.2000 mm + via_drilling_hole = 1000.00 um + text_thickness = 0 + line_thickness = 20.00 mil + poly_isle_area = 200000000.0 + clearance = 20.00 mil + } + ha:editor { + line_refraction = 1 + buffer_number = 0 + draw_grid = false + grids_idx = 4 + grid = 25.00 mil + } + } + } +} Index: tags/2.3.0/doc/tutorials/15_no_sch/step5.lht =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step5.lht (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step5.lht (revision 33253) @@ -0,0 +1,2201 @@ +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 = 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 = 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 { + ha:subc.1158 { + ha:attributes { + value=TO220 + footprint=Transistor + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.2 { + hdia=130.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1229 { + proto=0; x=44.45mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.1230 { + proto=1; x=46.99mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + ha:padstack_ref.1231 { + proto=1; x=49.53mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=3 + name=3 + } + } + ha:padstack_ref.1232 { + proto=2; x=46.99mm; y=1.13in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=4 + name=4 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1159 { + x1=44.45mm; y1=1.8in; x2=44.45mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1162 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1165 { + x1=49.53mm; y1=1.8in; x2=49.53mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1168 { + x1=1.65in; y1=1.62in; x2=52.07mm; y2=1.62in; thickness=20.0mil; clearance=0.0; + } + ha:line.1171 { + x1=52.07mm; y1=1.62in; x2=52.07mm; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1174 { + x1=52.07mm; y1=31.623mm; x2=1.65in; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1177 { + x1=1.65in; y1=31.623mm; x2=1.65in; y2=1.62in; thickness=20.0mil; clearance=0.0; + } + ha:line.1180 { + x1=1.65in; y1=31.623mm; x2=52.07mm; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1183 { + x1=52.07mm; y1=31.623mm; x2=52.07mm; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1186 { + x1=52.07mm; y1=1.12in; x2=51.689mm; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1189 { + x1=51.689mm; y1=1.12in; x2=51.689mm; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1192 { + x1=51.689mm; y1=26.67mm; x2=52.07mm; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1195 { + x1=52.07mm; y1=26.67mm; x2=52.07mm; y2=1.01in; thickness=20.0mil; clearance=0.0; + } + ha:line.1198 { + x1=52.07mm; y1=1.01in; x2=1.65in; y2=1.01in; thickness=20.0mil; clearance=0.0; + } + ha:line.1201 { + x1=1.65in; y1=1.01in; x2=1.65in; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1204 { + x1=1.65in; y1=26.67mm; x2=1.665in; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1207 { + x1=1.665in; y1=26.67mm; x2=1.665in; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1210 { + x1=1.665in; y1=1.12in; x2=1.65in; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1213 { + x1=1.65in; y1=1.12in; x2=1.65in; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:text.1216 { + string=%a.parent.refdes%; x=40.005mm; y=27.813mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 90.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1217 { + x1=46.99mm; y1=1.6325in; x2=46.99mm; y2=1.6325in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1220 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=1.8in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1223 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=46.72mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1226 { + x1=46.99mm; y1=1.8in; x2=47.99mm; y2=1.8in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAJ + } + ha:subc.1234 { + ha:attributes { + value=acy200 + footprint=rcy(200) + refdes=C3 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1258 { + proto=0; x=31.75mm; y=1.525in; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1259 { + proto=1; x=36.83mm; y=1.525in; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1235 { + x1=1.57in; y1=1.525in; x2=1.61in; y2=1.525in; thickness=10.0mil; clearance=0.0; + } + ha:line.1238 { + x1=1.09in; y1=1.525in; x2=1.13in; y2=1.525in; thickness=10.0mil; clearance=0.0; + } + ha:line.1241 { + x1=1.11in; y1=1.505in; x2=1.11in; y2=39.243mm; thickness=10.0mil; clearance=0.0; + } + ha:arc.1244 { + x=1.35in; y=1.525in; width=200.0mil; height=200.0mil; astart=0; adelta=360; thickness=10.0mil; clearance=0.0; + } + ha:text.1245 { + string=%a.parent.refdes%; x=1.31in; y=31.242mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1246 { + x1=1.35in; y1=1.525in; x2=1.35in; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1249 { + x1=31.75mm; y1=1.525in; x2=31.75mm; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1252 { + x1=31.75mm; y1=1.525in; x2=32.75mm; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1255 { + x1=31.75mm; y1=1.525in; x2=31.75mm; y2=39.735mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAL + } + ha:subc.1261 { + ha:attributes { + value=1*2 + footprint=connector(1,2) + refdes=J1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1293 { + proto=0; x=975.0mil; y=46.355mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1294 { + proto=1; x=975.0mil; y=48.895mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1262 { + x1=925.0mil; y1=45.085mm; x2=925.0mil; y2=1.975in; thickness=10.0mil; clearance=0.0; + } + ha:line.1265 { + x1=925.0mil; y1=45.085mm; x2=26.035mm; y2=45.085mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1268 { + x1=26.035mm; y1=1.975in; x2=925.0mil; y2=1.975in; thickness=10.0mil; clearance=0.0; + } + ha:line.1271 { + x1=26.035mm; y1=1.975in; x2=26.035mm; y2=45.085mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1274 { + x1=925.0mil; y1=47.625mm; x2=26.035mm; y2=47.625mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1277 { + x1=26.035mm; y1=45.085mm; x2=26.035mm; y2=47.625mm; thickness=10.0mil; clearance=0.0; + } + ha:text.1280 { + string=%a.parent.refdes%; x=950.0mil; y=42.545mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1281 { + x1=975.0mil; y1=47.625mm; x2=975.0mil; y2=47.625mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1284 { + x1=975.0mil; y1=46.355mm; x2=975.0mil; y2=46.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1287 { + x1=975.0mil; y1=46.355mm; x2=975.0mil; y2=45.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1290 { + x1=975.0mil; y1=46.355mm; x2=23.765mm; y2=46.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAN + } + ha:subc.1296 { + ha:attributes { + value=1*2 + footprint=connector(1,2) + refdes=J2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1328 { + proto=0; x=60.96mm; y=46.99mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1329 { + proto=1; x=60.96mm; y=49.53mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1297 { + x1=2.35in; y1=1.8in; x2=2.35in; y2=2.0in; thickness=10.0mil; clearance=0.0; + } + ha:line.1300 { + x1=2.35in; y1=1.8in; x2=2.45in; y2=1.8in; thickness=10.0mil; clearance=0.0; + } + ha:line.1303 { + x1=2.45in; y1=2.0in; x2=2.35in; y2=2.0in; thickness=10.0mil; clearance=0.0; + } + ha:line.1306 { + x1=2.45in; y1=2.0in; x2=2.45in; y2=1.8in; thickness=10.0mil; clearance=0.0; + } + ha:line.1309 { + x1=2.35in; y1=1.9in; x2=2.45in; y2=1.9in; thickness=10.0mil; clearance=0.0; + } + ha:line.1312 { + x1=2.45in; y1=1.8in; x2=2.45in; y2=1.9in; thickness=10.0mil; clearance=0.0; + } + ha:text.1315 { + string=%a.parent.refdes%; x=60.325mm; y=43.18mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1316 { + x1=60.96mm; y1=1.9in; x2=60.96mm; y2=1.9in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1319 { + x1=60.96mm; y1=46.99mm; x2=60.96mm; y2=46.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1322 { + x1=60.96mm; y1=46.99mm; x2=60.96mm; y2=45.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1325 { + x1=60.96mm; y1=46.99mm; x2=59.96mm; y2=46.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAN + } + ha:subc.1331 { + ha:attributes { + value=acy200 + footprint=acy(200) + refdes=C1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1363 { + proto=0; x=38.1mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1364 { + proto=1; x=43.18mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1332 { + x1=38.1mm; y1=53.975mm; x2=1.55in; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1335 { + x1=1.65in; y1=53.975mm; x2=43.18mm; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1338 { + x1=1.55in; y1=2.10834in; x2=1.55in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1341 { + x1=1.55in; y1=2.10834in; x2=1.65in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:line.1344 { + x1=1.65in; y1=54.398164mm; x2=1.55in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1347 { + x1=1.65in; y1=54.398164mm; x2=1.65in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:text.1350 { + string=%a.parent.refdes%; x=1.56in; y=50.927mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1351 { + x1=1.6in; y1=53.975mm; x2=1.6in; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1354 { + x1=38.1mm; y1=53.975mm; x2=38.1mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1357 { + x1=38.1mm; y1=53.975mm; x2=39.1mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1360 { + x1=38.1mm; y1=53.975mm; x2=38.1mm; y2=54.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAB + } + ha:subc.1366 { + ha:attributes { + value=acy200 + footprint=acy(200) + refdes=C2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1398 { + proto=0; x=48.895mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1399 { + proto=1; x=53.975mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1367 { + x1=48.895mm; y1=53.975mm; x2=1.975in; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1370 { + x1=2.075in; y1=53.975mm; x2=53.975mm; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1373 { + x1=1.975in; y1=2.10834in; x2=1.975in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1376 { + x1=1.975in; y1=2.10834in; x2=2.075in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:line.1379 { + x1=2.075in; y1=54.398164mm; x2=1.975in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1382 { + x1=2.075in; y1=54.398164mm; x2=2.075in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:text.1385 { + string=%a.parent.refdes%; x=1.985in; y=50.927mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1386 { + x1=51.435mm; y1=53.975mm; x2=51.435mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1389 { + x1=48.895mm; y1=53.975mm; x2=48.895mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.1392 { + x1=48.895mm; y1=53.975mm; x2=49.895mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.1395 { + x1=48.895mm; y1=53.975mm; x2=48.895mm; y2=54.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAB + } + ha:rat.1517 { + x1=975.0mil; y1=48.895mm; lgrp1=3; x2=36.83mm; y2=1.525in; lgrp2=3; + } + ha:rat.1520 { + x1=46.99mm; y1=1.8in; lgrp1=3; x2=36.83mm; y2=1.525in; lgrp2=3; + } + ha:rat.1523 { + x1=43.18mm; y1=53.975mm; lgrp1=3; x2=46.99mm; y2=1.8in; lgrp2=3; + } + ha:rat.1526 { + x1=43.18mm; y1=53.975mm; lgrp1=3; x2=53.975mm; y2=53.975mm; lgrp2=3; + } + ha:rat.1529 { + x1=53.975mm; y1=53.975mm; lgrp1=3; x2=60.96mm; y2=49.53mm; lgrp2=3; + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + ha:line.1433 { + x1=1.175in; y1=46.355mm; x2=31.75mm; y2=44.45mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1436 { + x1=31.75mm; y1=44.45mm; x2=31.75mm; y2=1.525in; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1472 { + x1=1.375in; y1=46.355mm; x2=38.1mm; y2=49.53mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1475 { + x1=38.1mm; y1=49.53mm; x2=38.1mm; y2=53.975mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1478 { + x1=975.0mil; y1=46.355mm; x2=1.725in; y2=46.355mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1481 { + x1=1.725in; y1=46.355mm; x2=44.45mm; y2=1.8in; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1505 { + x1=49.53mm; y1=1.8in; x2=2.35in; y2=1.8in; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1508 { + x1=2.35in; y1=1.8in; x2=60.96mm; y2=46.99mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1511 { + x1=49.53mm; y1=1.8in; x2=48.895mm; y2=46.355mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1514 { + x1=48.895mm; y1=46.355mm; x2=48.895mm; y2=53.975mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:netlist_patch { + ha:add_conn { net=gnd; term=J1-2; } + ha:add_conn { net=gnd; term=C1-2; } + ha:add_conn { net=gnd; term=C2-2; } + ha:add_conn { net=gnd; term=J2-2; } + ha:add_conn { net=gnd; term=U1-2; } + ha:add_conn { net=gnd; term=C3-2; } + ha:add_conn { net=in; term=J1-1; } + ha:add_conn { net=in; term=C3-1; } + ha:add_conn { net=in; term=U1-1; } + ha:add_conn { net=in; term=C1-1; } + ha:add_conn { net=out; term=J2-1; } + ha:add_conn { net=out; term=U1-3; } + ha:add_conn { net=out; term=C2-1; } + } + } + 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 + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + text_scale = 100 + via_thickness = 2.2000 mm + via_drilling_hole = 1000.00 um + text_thickness = 0 + line_thickness = 20.00 mil + poly_isle_area = 200000000.0 + clearance = 20.00 mil + } + ha:editor { + line_refraction = 1 + buffer_number = 0 + draw_grid = false + grids_idx = 4 + grid = 25.00 mil + } + } + } +} Index: tags/2.3.0/doc/tutorials/15_no_sch/step5.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/tutorials/15_no_sch/step5.png =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step5.png (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step5.png (revision 33253) Property changes on: tags/2.3.0/doc/tutorials/15_no_sch/step5.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/tutorials/15_no_sch/step6.lht =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step6.lht (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step6.lht (revision 33253) @@ -0,0 +1,2234 @@ +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 = 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 = 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 { + ha:subc.1158 { + ha:attributes { + value=TO220 + footprint=Transistor + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.2 { + hdia=130.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1229 { + proto=0; x=44.45mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.1230 { + proto=1; x=46.99mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + name=2 + } + } + ha:padstack_ref.1231 { + proto=1; x=49.53mm; y=1.8in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=3 + name=3 + } + } + ha:padstack_ref.1232 { + proto=2; x=46.99mm; y=1.13in; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=4 + name=4 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1159 { + x1=44.45mm; y1=1.8in; x2=44.45mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1162 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1165 { + x1=49.53mm; y1=1.8in; x2=49.53mm; y2=1.62in; thickness=30.0mil; clearance=0.0; + } + ha:line.1168 { + x1=1.65in; y1=1.62in; x2=52.07mm; y2=1.62in; thickness=20.0mil; clearance=0.0; + } + ha:line.1171 { + x1=52.07mm; y1=1.62in; x2=52.07mm; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1174 { + x1=52.07mm; y1=31.623mm; x2=1.65in; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1177 { + x1=1.65in; y1=31.623mm; x2=1.65in; y2=1.62in; thickness=20.0mil; clearance=0.0; + } + ha:line.1180 { + x1=1.65in; y1=31.623mm; x2=52.07mm; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1183 { + x1=52.07mm; y1=31.623mm; x2=52.07mm; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1186 { + x1=52.07mm; y1=1.12in; x2=51.689mm; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1189 { + x1=51.689mm; y1=1.12in; x2=51.689mm; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1192 { + x1=51.689mm; y1=26.67mm; x2=52.07mm; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1195 { + x1=52.07mm; y1=26.67mm; x2=52.07mm; y2=1.01in; thickness=20.0mil; clearance=0.0; + } + ha:line.1198 { + x1=52.07mm; y1=1.01in; x2=1.65in; y2=1.01in; thickness=20.0mil; clearance=0.0; + } + ha:line.1201 { + x1=1.65in; y1=1.01in; x2=1.65in; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1204 { + x1=1.65in; y1=26.67mm; x2=1.665in; y2=26.67mm; thickness=20.0mil; clearance=0.0; + } + ha:line.1207 { + x1=1.665in; y1=26.67mm; x2=1.665in; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1210 { + x1=1.665in; y1=1.12in; x2=1.65in; y2=1.12in; thickness=20.0mil; clearance=0.0; + } + ha:line.1213 { + x1=1.65in; y1=1.12in; x2=1.65in; y2=31.623mm; thickness=20.0mil; clearance=0.0; + } + ha:text.1216 { + string=%a.parent.refdes%; x=40.005mm; y=27.813mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 90.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1217 { + x1=46.99mm; y1=1.6325in; x2=46.99mm; y2=1.6325in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1220 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=1.8in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1223 { + x1=46.99mm; y1=1.8in; x2=46.99mm; y2=46.72mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1226 { + x1=46.99mm; y1=1.8in; x2=47.99mm; y2=1.8in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAJ + } + ha:subc.1234 { + ha:attributes { + value=acy200 + footprint=rcy(200) + refdes=C3 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1258 { + proto=0; x=31.75mm; y=1.525in; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1259 { + proto=1; x=36.83mm; y=1.525in; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1235 { + x1=1.57in; y1=1.525in; x2=1.61in; y2=1.525in; thickness=10.0mil; clearance=0.0; + } + ha:line.1238 { + x1=1.09in; y1=1.525in; x2=1.13in; y2=1.525in; thickness=10.0mil; clearance=0.0; + } + ha:line.1241 { + x1=1.11in; y1=1.505in; x2=1.11in; y2=39.243mm; thickness=10.0mil; clearance=0.0; + } + ha:arc.1244 { + x=1.35in; y=1.525in; width=200.0mil; height=200.0mil; astart=0; adelta=360; thickness=10.0mil; clearance=0.0; + } + ha:text.1245 { + string=%a.parent.refdes%; x=1.31in; y=31.242mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1246 { + x1=1.35in; y1=1.525in; x2=1.35in; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1249 { + x1=31.75mm; y1=1.525in; x2=31.75mm; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1252 { + x1=31.75mm; y1=1.525in; x2=32.75mm; y2=1.525in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1255 { + x1=31.75mm; y1=1.525in; x2=31.75mm; y2=39.735mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAL + } + ha:subc.1261 { + ha:attributes { + value=1*2 + footprint=connector(1,2) + refdes=J1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1293 { + proto=0; x=975.0mil; y=46.355mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1294 { + proto=1; x=975.0mil; y=48.895mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + round + noshape + } + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1262 { + x1=925.0mil; y1=45.085mm; x2=925.0mil; y2=1.975in; thickness=10.0mil; clearance=0.0; + } + ha:line.1265 { + x1=925.0mil; y1=45.085mm; x2=26.035mm; y2=45.085mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1268 { + x1=26.035mm; y1=1.975in; x2=925.0mil; y2=1.975in; thickness=10.0mil; clearance=0.0; + } + ha:line.1271 { + x1=26.035mm; y1=1.975in; x2=26.035mm; y2=45.085mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1274 { + x1=925.0mil; y1=47.625mm; x2=26.035mm; y2=47.625mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1277 { + x1=26.035mm; y1=45.085mm; x2=26.035mm; y2=47.625mm; thickness=10.0mil; clearance=0.0; + } + ha:text.1280 { + string=%a.parent.refdes%; x=950.0mil; y=42.545mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1281 { + x1=975.0mil; y1=47.625mm; x2=975.0mil; y2=47.625mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1284 { + x1=975.0mil; y1=46.355mm; x2=975.0mil; y2=46.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1287 { + x1=975.0mil; y1=46.355mm; x2=975.0mil; y2=45.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1290 { + x1=975.0mil; y1=46.355mm; x2=23.765mm; y2=46.355mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAN + } + ha:subc.1296 { + ha:attributes { + value=1*2 + footprint=connector(1,2) + refdes=J2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1328 { + proto=0; x=60.96mm; y=46.99mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1329 { + proto=1; x=60.96mm; y=49.53mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1297 { + x1=2.35in; y1=1.8in; x2=2.35in; y2=2.0in; thickness=10.0mil; clearance=0.0; + } + ha:line.1300 { + x1=2.35in; y1=1.8in; x2=2.45in; y2=1.8in; thickness=10.0mil; clearance=0.0; + } + ha:line.1303 { + x1=2.45in; y1=2.0in; x2=2.35in; y2=2.0in; thickness=10.0mil; clearance=0.0; + } + ha:line.1306 { + x1=2.45in; y1=2.0in; x2=2.45in; y2=1.8in; thickness=10.0mil; clearance=0.0; + } + ha:line.1309 { + x1=2.35in; y1=1.9in; x2=2.45in; y2=1.9in; thickness=10.0mil; clearance=0.0; + } + ha:line.1312 { + x1=2.45in; y1=1.8in; x2=2.45in; y2=1.9in; thickness=10.0mil; clearance=0.0; + } + ha:text.1315 { + string=%a.parent.refdes%; x=60.325mm; y=43.18mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1316 { + x1=60.96mm; y1=1.9in; x2=60.96mm; y2=1.9in; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1319 { + x1=60.96mm; y1=46.99mm; x2=60.96mm; y2=46.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1322 { + x1=60.96mm; y1=46.99mm; x2=60.96mm; y2=45.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1325 { + x1=60.96mm; y1=46.99mm; x2=59.96mm; y2=46.99mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAN + } + ha:subc.1331 { + ha:attributes { + value=acy200 + footprint=acy(200) + refdes=C1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1363 { + proto=0; x=38.1mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1364 { + proto=1; x=43.18mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1332 { + x1=38.1mm; y1=53.975mm; x2=1.55in; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1335 { + x1=1.65in; y1=53.975mm; x2=43.18mm; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1338 { + x1=1.55in; y1=2.10834in; x2=1.55in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1341 { + x1=1.55in; y1=2.10834in; x2=1.65in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:line.1344 { + x1=1.65in; y1=54.398164mm; x2=1.55in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1347 { + x1=1.65in; y1=54.398164mm; x2=1.65in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:text.1350 { + string=%a.parent.refdes%; x=1.56in; y=50.927mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1351 { + x1=1.6in; y1=53.975mm; x2=1.6in; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1354 { + x1=38.1mm; y1=53.975mm; x2=38.1mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.1357 { + x1=38.1mm; y1=53.975mm; x2=39.1mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.1360 { + x1=38.1mm; y1=53.975mm; x2=38.1mm; y2=54.975mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAB + } + ha:subc.1366 { + ha:attributes { + value=acy200 + footprint=acy(200) + refdes=C2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.1398 { + proto=0; x=48.895mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.1399 { + proto=1; x=53.975mm; y=53.975mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:3 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.1367 { + x1=48.895mm; y1=53.975mm; x2=1.975in; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1370 { + x1=2.075in; y1=53.975mm; x2=53.975mm; y2=53.975mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1373 { + x1=1.975in; y1=2.10834in; x2=1.975in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1376 { + x1=1.975in; y1=2.10834in; x2=2.075in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:line.1379 { + x1=2.075in; y1=54.398164mm; x2=1.975in; y2=54.398164mm; thickness=10.0mil; clearance=0.0; + } + ha:line.1382 { + x1=2.075in; y1=54.398164mm; x2=2.075in; y2=2.10834in; thickness=10.0mil; clearance=0.0; + } + ha:text.1385 { + string=%a.parent.refdes%; x=1.985in; y=50.927mm; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.1386 { + x1=51.435mm; y1=53.975mm; x2=51.435mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.1389 { + x1=48.895mm; y1=53.975mm; x2=48.895mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.1392 { + x1=48.895mm; y1=53.975mm; x2=49.895mm; y2=53.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.1395 { + x1=48.895mm; y1=53.975mm; x2=48.895mm; y2=54.975mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = 2YrIDHgdUiD93dfM91oAAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + ha:line.1433 { + x1=1.175in; y1=46.355mm; x2=31.75mm; y2=44.45mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1436 { + x1=31.75mm; y1=44.45mm; x2=31.75mm; y2=1.525in; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1472 { + x1=1.375in; y1=46.355mm; x2=38.1mm; y2=49.53mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1475 { + x1=38.1mm; y1=49.53mm; x2=38.1mm; y2=53.975mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1478 { + x1=975.0mil; y1=46.355mm; x2=1.725in; y2=46.355mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1481 { + x1=1.725in; y1=46.355mm; x2=44.45mm; y2=1.8in; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1505 { + x1=49.53mm; y1=1.8in; x2=2.35in; y2=1.8in; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1508 { + x1=2.35in; y1=1.8in; x2=60.96mm; y2=46.99mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1511 { + x1=49.53mm; y1=1.8in; x2=48.895mm; y2=46.355mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.1514 { + x1=48.895mm; y1=46.355mm; x2=48.895mm; y2=53.975mm; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + color = {#104e8b} + } + + ha:bottom-gnd { + lid=3 + group=10 + ha:combining { } + + li:objects { + ha:polygon.1537 { clearance=40.0mil; + li:geometry { + ta:contour { + { 850.0mil; 975.0mil } + { 64.135mm; 975.0mil } + { 64.135mm; 2.25in } + { 850.0mil; 2.25in } + } + } + + ha:flags { + clearpoly=1 + } + } + } + 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:netlists { + li:netlist_patch { + ha:add_conn { net=gnd; term=J1-2; } + ha:add_conn { net=gnd; term=C1-2; } + ha:add_conn { net=gnd; term=C2-2; } + ha:add_conn { net=gnd; term=J2-2; } + ha:add_conn { net=gnd; term=U1-2; } + ha:add_conn { net=gnd; term=C3-2; } + ha:add_conn { net=in; term=J1-1; } + ha:add_conn { net=in; term=C3-1; } + ha:add_conn { net=in; term=U1-1; } + ha:add_conn { net=in; term=C1-1; } + ha:add_conn { net=out; term=J2-1; } + ha:add_conn { net=out; term=U1-3; } + ha:add_conn { net=out; term=C2-1; } + } + } + 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 + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + text_scale = 100 + via_thickness = 2.2000 mm + via_drilling_hole = 1000.00 um + text_thickness = 0 + line_thickness = 20.00 mil + poly_isle_area = 200000000.0 + clearance = 20.00 mil + } + ha:editor { + line_refraction = 1 + buffer_number = 0 + draw_grid = false + grids_idx = 4 + grid = 25.00 mil + } + } + } +} Index: tags/2.3.0/doc/tutorials/15_no_sch/step6.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/tutorials/15_no_sch/step6.png =================================================================== --- tags/2.3.0/doc/tutorials/15_no_sch/step6.png (nonexistent) +++ tags/2.3.0/doc/tutorials/15_no_sch/step6.png (revision 33253) Property changes on: tags/2.3.0/doc/tutorials/15_no_sch/step6.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/tutorials/16_tdx_netlist/7805.tdx =================================================================== --- tags/2.3.0/doc/tutorials/16_tdx_netlist/7805.tdx (nonexistent) +++ tags/2.3.0/doc/tutorials/16_tdx_netlist/7805.tdx (revision 33253) @@ -0,0 +1,29 @@ +tEDAx v1 +begin netlist v1 linear_stab + conn gnd U1 2 + conn gnd J1 2 + conn gnd J2 2 + conn in U1 1 + conn in J1 1 + conn out U1 3 + conn out J2 1 + conn gnd C1 2 + conn in C1 1 + conn gnd C2 2 + conn out C2 1 + conn gnd C3 2 + conn out C3 1 + footprint J1 connector(1,2) + footprint J2 connector(1,2) + footprint U1 TO220 + footprint C1 acy(200) + footprint C2 acy(200) + footprint C3 rcy(200) + value C1 100 nf + value C2 100 nf + value C3 100 uf + device C1 ceramic\ capacitor + device C2 ceramic\ capacitor + device C3 electrolithic\ capacitor + device U1 7805 +end netlist Index: tags/2.3.0/doc/tutorials/16_tdx_netlist/Makefile.inst =================================================================== --- tags/2.3.0/doc/tutorials/16_tdx_netlist/Makefile.inst (nonexistent) +++ tags/2.3.0/doc/tutorials/16_tdx_netlist/Makefile.inst (revision 33253) @@ -0,0 +1,21 @@ +ROOT=../../.. +TUTDIR=$(DOCDIR)/tutorial/16_tdx_netlist + + +all: + +install_all: + $(SCCBOX) mkdir -p $(TUTDIR) + $(SCCBOX) $(HOW) 7805.tdx $(TUTDIR)/7805.tdx + $(SCCBOX) $(HOW) index.html $(TUTDIR)/index.html + +install: + $(MAKE) -f Makefile.inst install_all HOW="install -f" + +linstall: + $(MAKE) -f Makefile.inst install_all HOW="install -f -l --absolute " + +uninstall: + $(MAKE) -f Makefile.inst install_all HOW="install -u" + +include $(ROOT)/Makefile.conf Index: tags/2.3.0/doc/tutorials/16_tdx_netlist/index.html =================================================================== --- tags/2.3.0/doc/tutorials/16_tdx_netlist/index.html (nonexistent) +++ tags/2.3.0/doc/tutorials/16_tdx_netlist/index.html (revision 33253) @@ -0,0 +1,38 @@ +

Step 1: import the schematics

+

+Our schematics is coming from a tEDAx netlist, which is a bit more than +just a list of networks: it also contains information about footprints and +device attributes. +

+Start with an empty board and import the schematics information from +7805.tdx using the File menu, Import submenu, Import tEDAx schematics submenu. +

+All subcircuits and networks should be loaded. + +

Step 2: disperse

+

+However, the subcircuits are placed randomly. There are many different +strategies to resolve this: +

    +
  • manual placement: drag&drop move the subcircuits around; you may + want to temporarily enable the "floater lock" in the Mode menu, + Drawing submenu, "lock floaters" item (or using {m f l}). Since + refdes text is normally a floater, this will lock it down to + its parent subc so it will be easier to grab the subc to move, not + the refdes. +
  • disperse: Connects menu, Subcircuit placement submenu, disperse all + subcircuits. This will place the subcircuits in a grid in random order + so that there will be no overlap +
  • in the same submenu there is an auto-place selected subcircuits item; + select all subcircuits (drag-and-drop selection box enclosing them all) + then execute this menu. It's a smarter algorithm that is trying to + place subcircuits to minimize resulting rat line length. It will + try to use both sides of the board. +
+ +

Step 3 on: lay out the board

+

+Once subcircuits are placed, press {c r} and the nets are shown with rat lines. +From this point, please follow +the no-sch tutorial from step 5. + Index: tags/2.3.0/doc/tutorials/17_sch/7805_gschem.sch =================================================================== --- tags/2.3.0/doc/tutorials/17_sch/7805_gschem.sch (nonexistent) +++ tags/2.3.0/doc/tutorials/17_sch/7805_gschem.sch (revision 33253) @@ -0,0 +1,86 @@ +v 20130925 2 +C 23100 57800 1 0 0 lm7805-1.sym +{ +T 24700 59100 5 10 0 0 0 0 1 +device=7805 +T 24500 58800 5 10 1 1 0 6 1 +refdes=U1 +T 23400 58800 5 10 1 1 0 0 1 +footprint=TO220 +} +N 21100 58400 23100 58400 4 +N 21100 58000 21700 58000 4 +N 21700 58000 21700 56700 4 +C 21600 56400 1 0 0 gnd-1.sym +C 23800 56400 1 0 0 gnd-1.sym +N 23900 56700 23900 57800 4 +C 25900 57600 1 0 0 connector2-2.sym +{ +T 26600 58900 5 10 1 1 0 6 1 +refdes=J2 +T 26200 58850 5 10 0 0 0 0 1 +device=CONNECTOR_2 +T 26200 59050 5 10 0 0 0 0 1 +footprint=connector(1,2) +} +N 25900 58400 24700 58400 4 +N 25700 58000 25700 56700 4 +C 25600 56400 1 0 0 gnd-1.sym +N 25900 58000 25700 58000 4 +C 22000 58000 1 270 0 capacitor-2.sym +{ +T 22700 57800 5 10 0 0 270 0 1 +device=POLARIZED_CAPACITOR +T 22000 57400 5 10 1 1 270 0 1 +refdes=C3 +T 22900 57800 5 10 0 0 270 0 1 +symversion=0.1 +T 22000 58000 5 10 0 0 270 0 1 +footprint=rcy(200) +T 22000 58100 5 10 1 1 270 0 1 +value=100uF +} +C 22100 56400 1 0 0 gnd-1.sym +N 22200 57100 22200 56700 4 +N 22200 58000 22200 58400 4 +C 22700 58000 1 270 0 capacitor-1.sym +{ +T 23400 57800 5 10 0 0 270 0 1 +device=CAPACITOR +T 23200 57800 5 10 1 1 270 0 1 +refdes=C1 +T 23600 57800 5 10 0 0 270 0 1 +symversion=0.1 +T 22700 58200 5 10 1 1 270 0 1 +value=100nF +T 22700 58000 5 10 0 0 0 0 1 +footprint=acy(200) +} +N 22900 58000 22900 58400 4 +C 22800 56400 1 0 0 gnd-1.sym +N 22900 56700 22900 57100 4 +C 24800 58000 1 270 0 capacitor-1.sym +{ +T 25500 57800 5 10 0 0 270 0 1 +device=CAPACITOR +T 25300 57800 5 10 1 1 270 0 1 +refdes=C2 +T 25700 57800 5 10 0 0 270 0 1 +symversion=0.1 +T 24800 58200 5 10 1 1 270 0 1 +value=100nF +T 24800 58000 5 10 0 0 0 0 1 +footprint=acy(200) +} +N 25000 58000 25000 58400 4 +C 24900 56400 1 0 0 gnd-1.sym +N 25000 56700 25000 57100 4 +C 21100 57600 1 0 1 connector2-2.sym +{ +T 20400 58900 5 10 1 1 0 0 1 +refdes=J1 +T 20800 58850 5 10 0 0 0 6 1 +device=CONNECTOR_2 +T 20800 59050 5 10 0 0 0 6 1 +footprint=connector(1,2) +} Index: tags/2.3.0/doc/tutorials/17_sch/Makefile.inst =================================================================== --- tags/2.3.0/doc/tutorials/17_sch/Makefile.inst (nonexistent) +++ tags/2.3.0/doc/tutorials/17_sch/Makefile.inst (revision 33253) @@ -0,0 +1,22 @@ +ROOT=../../.. +TUTDIR=$(DOCDIR)/tutorial/17_sch + + +all: + +install_all: + $(SCCBOX) mkdir -p $(TUTDIR) + $(SCCBOX) $(HOW) 7805_gschem.sch $(TUTDIR)/7805_gschem.sch + $(SCCBOX) $(HOW) sch.png $(TUTDIR)/sch.png + $(SCCBOX) $(HOW) index.html $(TUTDIR)/index.html + +install: + $(MAKE) -f Makefile.inst install_all HOW="install -f" + +linstall: + $(MAKE) -f Makefile.inst install_all HOW="install -f -l --absolute " + +uninstall: + $(MAKE) -f Makefile.inst install_all HOW="install -u" + +include $(ROOT)/Makefile.conf Index: tags/2.3.0/doc/tutorials/17_sch/index.html =================================================================== --- tags/2.3.0/doc/tutorials/17_sch/index.html (nonexistent) +++ tags/2.3.0/doc/tutorials/17_sch/index.html (revision 33253) @@ -0,0 +1,45 @@ +

Step 1: schematics

+

+ The schematics is usually the single source of all logical information: + footprints, refdes and values and connections (networks or nets). + A project is just a directory that holds at least the schematics, but + usually also the pcb layout file and scripts. +

+ Start the new project by creating an empty directory. Draw + the schematics with any schematics editor supported by pcb-rnd and + save it in this new directory. On the schematics + place the following symbols and edit/add these attributes: +

    +
  • 7805, footprint=TO220, refdes=U1 +
  • 2 pin connector, footprint=connector(1,2), refdes=J1 +
  • 2 pin connector, footprint=connector(1,2), refdes=J2 +
  • polarized capacitor, fooptrint=rcy(200), value=100uF, refdes=C3 +
  • capacitor, fooptrint=acy(200), value=100nF, refdes=C1 +
  • capacitor, fooptrint=acy(200), value=100nF, refdes=C2 +
  • gnd +
+

+ Arrange and connect the pins as shown below. +

+ schematics +

+ +

Step 2: export the netlist as needed

+

+Depending on the schematics capture software you choose, you may need to +export a netlist that can be imported in pcb-rnd. +

+TODO: create a pool node on this + +

Step 3: lay out the board

+

+Please follow the tEDAx netlist +tutorial from step2 for laying out the board. + +

Step 4: updates: forward annotation

+

+If you need to change the schematics later, re-export it from the schematics +editor and re-import it from pcb-rnd. If the format included importing +footprints, all new footprints will be imported. The netlist will be updated. +press {c r} after the import and update the board to reflect schematics changes. + Index: tags/2.3.0/doc/tutorials/17_sch/sch.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/tutorials/17_sch/sch.png =================================================================== --- tags/2.3.0/doc/tutorials/17_sch/sch.png (nonexistent) +++ tags/2.3.0/doc/tutorials/17_sch/sch.png (revision 33253) Property changes on: tags/2.3.0/doc/tutorials/17_sch/sch.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/tutorials/20_dbl_sided/7805.lht =================================================================== --- tags/2.3.0/doc/tutorials/20_dbl_sided/7805.lht (nonexistent) +++ tags/2.3.0/doc/tutorials/20_dbl_sided/7805.lht (revision 33253) @@ -0,0 +1,2100 @@ +ha:pcb-rnd-board-v6 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + text_scale = 0 + text_thick = 0.0 + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + text_scale = 0 + text_thick = 0.0 + thickness = 20.0mil + hole = 0.999998mm + 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 = 30.48mm + y = 30.48mm + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + } + + li:objects { + ha:subc.5 { + ha:attributes { + footprint=0805 + refdes=C3 + manufacturer=unknown + vendor_part_number=unknown + manufacturer_part_number=unknown + value=100nF + vendor=unknown + device=CAPACITOR + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.749808mm + -0.649986mm + -0.749808mm + -0.649986mm + 0.749808mm + 0.649986mm + 0.749808mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.726186mm + -32.52mil + -0.726186mm + -32.52mil + -0.726186mm + 32.52mil + 0.726186mm + 32.52mil + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.749808mm + -0.649986mm + -0.749808mm + -0.649986mm + 0.749808mm + 0.649986mm + 0.749808mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.7 { + proto=0; x=1.03543in; y=800.0mil; rot=0.000000; xmirror=0; smirror=1; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.8 { + proto=0; x=964.57mil; y=800.0mil; rot=0.000000; xmirror=0; smirror=1; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.9 { + x1=996.07mil; y1=772.45mil; x2=25.499822mm; y2=772.45mil; thickness=8.0mil; clearance=0.0; + } + ha:line.12 { + x1=996.07mil; y1=21.01977mm; x2=25.499822mm; y2=21.01977mm; thickness=8.0mil; clearance=0.0; + } + ha:text.6 { + string=%a.parent.refdes%; x=24.864822mm; y=756.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + onsolder=1 + } + rot = 360.000000 + } + } + ha:type { + silk = 1 + bottom = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.15 { + x1=1000.0mil; y1=800.0mil; x2=1000.0mil; y2=800.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.18 { + x1=1000.0mil; y1=800.0mil; x2=1000.0mil; y2=800.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.21 { + x1=1000.0mil; y1=800.0mil; x2=26.4mm; y2=800.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.24 { + x1=1000.0mil; y1=800.0mil; x2=1000.0mil; y2=21.32mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + bottom = 1 + virtual = 1 + misc = 1 + } + } + } + } + uid = quxFXVYZGTxSjZpBCmYAAAAB + } + ha:subc.27 { + ha:attributes { + footprint=0805 + refdes=C2 + manufacturer=unknown + vendor_part_number=unknown + manufacturer_part_number=unknown + value=100nF + vendor=unknown + device=CAPACITOR + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.749808mm + -0.649986mm + -0.749808mm + -0.649986mm + 0.749808mm + 0.649986mm + 0.749808mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.726186mm + -32.52mil + -0.726186mm + -32.52mil + -0.726186mm + 32.52mil + 0.726186mm + 32.52mil + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.749808mm + -0.649986mm + -0.749808mm + -0.649986mm + 0.749808mm + 0.649986mm + 0.749808mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.29 { + proto=0; x=764.57mil; y=800.0mil; rot=0.000000; xmirror=0; smirror=1; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.30 { + proto=0; x=21.219922mm; y=800.0mil; rot=0.000000; xmirror=0; smirror=1; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.31 { + x1=796.07mil; y1=21.01977mm; x2=20.419822mm; y2=21.01977mm; thickness=8.0mil; clearance=0.0; + } + ha:line.34 { + x1=796.07mil; y1=772.45mil; x2=20.419822mm; y2=772.45mil; thickness=8.0mil; clearance=0.0; + } + ha:text.28 { + string=%a.parent.refdes%; x=783.07mil; y=756.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + onsolder=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + bottom = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.37 { + x1=800.0mil; y1=800.0mil; x2=800.0mil; y2=800.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.40 { + x1=800.0mil; y1=800.0mil; x2=800.0mil; y2=800.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.43 { + x1=800.0mil; y1=800.0mil; x2=19.32mm; y2=800.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.46 { + x1=800.0mil; y1=800.0mil; x2=800.0mil; y2=19.32mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + bottom = 1 + virtual = 1 + misc = 1 + } + } + } + } + uid = quxFXVYZGTxSjZpBCmYAAAAC + } + ha:subc.49 { + ha:attributes { + footprint=rcy(200) + refdes=C1 + manufacturer=unknown + vendor_part_number=unknown + manufacturer_part_number=unknown + value=47uF + vendor=unknown + device=POLARIZED_CAPACITOR + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.51 { + proto=0; x=500.0mil; y=400.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=+ + } + } + ha:padstack_ref.52 { + proto=1; x=300.0mil; y=400.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:4 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + name=- + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.53 { + x1=140.0mil; y1=400.0mil; x2=180.0mil; y2=400.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.56 { + x1=620.0mil; y1=400.0mil; x2=660.0mil; y2=400.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.59 { + x1=640.0mil; y1=380.0mil; x2=640.0mil; y2=420.0mil; thickness=10.0mil; clearance=0.0; + } + ha:arc.62 { + x=400.0mil; y=400.0mil; width=200.0mil; height=200.0mil; astart=180; adelta=360; thickness=10.0mil; clearance=0.0; + } + ha:text.50 { + string=%a.parent.refdes%; x=460.0mil; y=605.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.63 { + x1=400.0mil; y1=400.0mil; x2=400.0mil; y2=400.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.66 { + x1=500.0mil; y1=400.0mil; x2=500.0mil; y2=400.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.69 { + x1=500.0mil; y1=400.0mil; x2=11.7mm; y2=400.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.72 { + x1=500.0mil; y1=400.0mil; x2=500.0mil; y2=9.16mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = quxFXVYZGTxSjZpBCmYAAAAD + } + ha:subc.75 { + ha:attributes { + footprint=connector(2,1) + refdes=CONN2 + manufacturer=unknown + vendor_part_number=unknown + manufacturer_part_number=unknown + value=unknown + vendor=unknown + device=CONNECTOR_2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.77 { + proto=0; x=250.0mil; y=800.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.78 { + proto=1; x=250.0mil; y=700.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:4 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.79 { + x1=200.0mil; y1=850.0mil; x2=300.0mil; y2=850.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.82 { + x1=200.0mil; y1=650.0mil; x2=200.0mil; y2=850.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.85 { + x1=300.0mil; y1=650.0mil; x2=300.0mil; y2=850.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.88 { + x1=200.0mil; y1=650.0mil; x2=300.0mil; y2=650.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.91 { + x1=300.0mil; y1=750.0mil; x2=300.0mil; y2=850.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.94 { + x1=200.0mil; y1=750.0mil; x2=300.0mil; y2=750.0mil; thickness=10.0mil; clearance=0.0; + } + ha:text.76 { + string=%a.parent.refdes%; x=125.0mil; y=825.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 90.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.97 { + x1=250.0mil; y1=750.0mil; x2=250.0mil; y2=750.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.100 { + x1=250.0mil; y1=800.0mil; x2=250.0mil; y2=800.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.103 { + x1=250.0mil; y1=800.0mil; x2=250.0mil; y2=21.32mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.106 { + x1=250.0mil; y1=800.0mil; x2=7.35mm; y2=800.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = quxFXVYZGTxSjZpBCmYAAAAE + } + ha:subc.109 { + ha:attributes { + footprint=connector(3,1) + refdes=CONN1 + manufacturer=unknown + vendor_part_number=unknown + manufacturer_part_number=unknown + value=unknown + vendor=unknown + device=CONNECTOR_3 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.999998mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=80.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=86.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.111 { + proto=0; x=575.0mil; y=925.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.112 { + proto=1; x=475.0mil; y=925.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:4 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + name=2 + } + } + ha:padstack_ref.113 { + proto=1; x=375.0mil; y=925.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=3 + name=3 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.114 { + x1=625.0mil; y1=875.0mil; x2=625.0mil; y2=975.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.117 { + x1=325.0mil; y1=975.0mil; x2=625.0mil; y2=975.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.120 { + x1=325.0mil; y1=875.0mil; x2=625.0mil; y2=875.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.123 { + x1=325.0mil; y1=875.0mil; x2=325.0mil; y2=975.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.126 { + x1=525.0mil; y1=875.0mil; x2=625.0mil; y2=875.0mil; thickness=10.0mil; clearance=0.0; + } + ha:line.129 { + x1=525.0mil; y1=875.0mil; x2=525.0mil; y2=975.0mil; thickness=10.0mil; clearance=0.0; + } + ha:text.110 { + string=%a.parent.refdes%; x=425.0mil; y=975.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.132 { + x1=475.0mil; y1=925.0mil; x2=475.0mil; y2=925.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.135 { + x1=575.0mil; y1=925.0mil; x2=575.0mil; y2=925.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.138 { + x1=575.0mil; y1=925.0mil; x2=575.0mil; y2=22.495mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.141 { + x1=575.0mil; y1=925.0mil; x2=13.605mm; y2=925.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = quxFXVYZGTxSjZpBCmYAAAAF + } + ha:subc.144 { + ha:attributes { + footprint=TO220 + refdes=U1 + manufacturer=unknown + vendor_part_number=unknown + manufacturer_part_number=unknown + value=unknown + vendor=unknown + device=7805 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=60.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=90.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=96.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.2 { + hdia=130.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=150.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=156.0mil; } + ha:combining { sub=1; auto=1; } + ha:layer_mask { + bottom = 1 + mask = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.146 { + proto=0; x=800.0mil; y=925.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.147 { + proto=1; x=900.0mil; y=925.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:4 { + on + diag + round + noshape + } + } + + ha:attributes { + term=2 + name=2 + } + } + ha:padstack_ref.148 { + proto=1; x=1000.0mil; y=925.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=3 + name=3 + } + } + ha:padstack_ref.149 { + proto=2; x=900.0mil; y=255.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=15.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=4 + name=4 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.150 { + x1=800.0mil; y1=925.0mil; x2=800.0mil; y2=745.0mil; thickness=30.0mil; clearance=0.0; + } + ha:line.153 { + x1=900.0mil; y1=925.0mil; x2=900.0mil; y2=745.0mil; thickness=30.0mil; clearance=0.0; + } + ha:line.156 { + x1=1000.0mil; y1=925.0mil; x2=1000.0mil; y2=745.0mil; thickness=30.0mil; clearance=0.0; + } + ha:line.159 { + x1=700.0mil; y1=745.0mil; x2=1.1in; y2=745.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.162 { + x1=1.1in; y1=745.0mil; x2=1.1in; y2=370.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.165 { + x1=1.1in; y1=370.0mil; x2=700.0mil; y2=370.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.168 { + x1=700.0mil; y1=370.0mil; x2=700.0mil; y2=745.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.171 { + x1=700.0mil; y1=370.0mil; x2=1.1in; y2=370.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.174 { + x1=1.1in; y1=370.0mil; x2=1.1in; y2=245.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.177 { + x1=1.1in; y1=245.0mil; x2=27.559mm; y2=245.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.180 { + x1=27.559mm; y1=245.0mil; x2=27.559mm; y2=175.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.183 { + x1=27.559mm; y1=175.0mil; x2=1.1in; y2=175.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.186 { + x1=1.1in; y1=175.0mil; x2=1.1in; y2=135.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.189 { + x1=1.1in; y1=135.0mil; x2=700.0mil; y2=135.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.192 { + x1=700.0mil; y1=135.0mil; x2=700.0mil; y2=175.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.195 { + x1=700.0mil; y1=175.0mil; x2=715.0mil; y2=175.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.198 { + x1=715.0mil; y1=175.0mil; x2=715.0mil; y2=245.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.201 { + x1=715.0mil; y1=245.0mil; x2=700.0mil; y2=245.0mil; thickness=20.0mil; clearance=0.0; + } + ha:line.204 { + x1=700.0mil; y1=245.0mil; x2=700.0mil; y2=370.0mil; thickness=20.0mil; clearance=0.0; + } + ha:text.145 { + string=%a.parent.refdes%; x=625.0mil; y=170.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 90.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.207 { + x1=900.0mil; y1=757.5mil; x2=900.0mil; y2=757.5mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.210 { + x1=900.0mil; y1=925.0mil; x2=900.0mil; y2=925.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.213 { + x1=900.0mil; y1=925.0mil; x2=900.0mil; y2=24.495mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.216 { + x1=900.0mil; y1=925.0mil; x2=23.86mm; y2=925.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = quxFXVYZGTxSjZpBCmYAAAAG + } + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + + li:objects { + } + color = {#8b2323} + } + + ha:solder { + lid=1 + group=8 + ha:combining { } + + li:objects { + ha:line.219 { + x1=250.0mil; y1=800.0mil; x2=175.0mil; y2=800.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.222 { + x1=250.0mil; y1=800.0mil; x2=150.0mil; y2=800.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.225 { + x1=150.0mil; y1=800.0mil; x2=150.0mil; y2=150.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.228 { + x1=27.305mm; y1=150.0mil; x2=27.305mm; y2=925.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.231 { + x1=27.305mm; y1=925.0mil; x2=1000.0mil; y2=925.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.234 { + x1=150.0mil; y1=150.0mil; x2=800.0mil; y2=150.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.237 { + x1=27.305mm; y1=150.0mil; x2=1000.0mil; y2=150.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.240 { + x1=800.0mil; y1=150.0mil; x2=1000.0mil; y2=150.0mil; thickness=30.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.243 { + x1=800.0mil; y1=125.0mil; x2=26.035mm; y2=125.0mil; thickness=25.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.246 { + x1=500.0mil; y1=400.0mil; x2=600.0mil; y2=400.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.249 { + x1=600.0mil; y1=400.0mil; x2=675.0mil; y2=475.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.252 { + x1=675.0mil; y1=475.0mil; x2=675.0mil; y2=925.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.255 { + x1=800.0mil; y1=925.0mil; x2=575.0mil; y2=925.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.258 { + x1=764.57mil; y1=800.0mil; x2=675.0mil; y2=800.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#3a5fcd} + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + color = {#104e8b} + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + + li:objects { + } + color = {#cd3700} + } + + ha:sold-GND { + lid=4 + group=8 + ha:combining { } + + li:objects { + ha:line.261 { + x1=21.219922mm; y1=800.0mil; x2=964.57mil; y2=800.0mil; thickness=20.0mil; clearance=40.0mil; + } + ha:polygon.264 { + li:geometry { + ta:contour { + { 100.0mil; 26.035mm } + { 1.125in; 26.035mm } + { 1.125in; 100.0mil } + { 100.0mil; 100.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#548b54} + } + + ha:sold-power { + lid=5 + group=8 + ha:combining { } + + li:objects { + } + color = {#8b7355} + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + + li:objects { + } + color = {#00868b} + } + + ha:outline { + lid=7 + group=7 + ha:combining { auto=1; } + + li:objects { + ha:line.269 { + x1=100.0mil; y1=100.0mil; x2=100.0mil; y2=26.035mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.272 { + x1=100.0mil; y1=100.0mil; x2=1.125in; y2=100.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.275 { + x1=100.0mil; y1=26.035mm; x2=1.125in; y2=26.035mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.278 { + x1=1.125in; y1=26.035mm; x2=1.125in; y2=100.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#228b22} + } + + ha:silk { + lid=8 + group=10 + ha:combining { auto=1; } + + li:objects { + } + color = {#000000} + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + + li:objects { + ha:text.281 { + string=-; x=325.0mil; y=625.0mil; scale=195; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.282 { + string=+; x=325.0mil; y=725.0mil; scale=195; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.283 { + string=+; x=550.0mil; y=775.0mil; scale=195; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.284 { + string=-; x=450.0mil; y=775.0mil; scale=195; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.285 { + string=in; x=275.0mil; y=900.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.286 { + string={out: +5V}; x=115.0mil; y=585.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#000000} + } + + ha:top-mask { + lid=10 + group=2 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-mask { + lid=11 + group=9 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:top-paste { + lid=12 + group=0 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + ha:bottom-paste { + lid=13 + group=11 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + } + } + + + ha:netlists { + li:input { + ha:unnamed_net1 { + ha:attributes { + style=(unknown) + } + li:conn { C1-1; C2-1; CONN1-1; U1-1; } + style = (unknown) + } + ha:unnamed_net2 { + ha:attributes { + style=(unknown) + } + li:conn { C3-1; CONN2-1; U1-3; } + style = (unknown) + } + ha:GND { + ha:attributes { + style=(unknown) + } + li:conn { C1-2; C2-2; C3-2; CONN1-2; CONN2-2; U1-2; } + style = (unknown) + } + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { 12; } + } + ha:1 { + name = top_silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + 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; 3; } + } + ha:4 { + name = implicit_subst + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + name = implicit_subst + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:7 { + name = global_outline + ha:type { boundary=1; } + li:layers { 7; } + purpose = uroute + } + ha:8 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:9 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:10 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:11 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 13; } + } + } + } +} Index: tags/2.3.0/doc/tutorials/Makefile =================================================================== --- tags/2.3.0/doc/tutorials/Makefile (nonexistent) +++ tags/2.3.0/doc/tutorials/Makefile (revision 33253) @@ -0,0 +1,20 @@ +all: + $(MAKE) all_ CMD=all + +all_: + cd 15_no_sch && $(MAKE) -f Makefile.inst $(CMD) + cd 16_tdx_netlist && $(MAKE) -f Makefile.inst $(CMD) + cd 17_sch && $(MAKE) -f Makefile.inst $(CMD) + +install: + $(MAKE) all_ CMD=install + +linstall: + $(MAKE) all_ CMD=linstall + +uninstall: + $(MAKE) all_ CMD=uninstall + +clean: + +distclean: Index: tags/2.3.0/doc/tutorials/README =================================================================== --- tags/2.3.0/doc/tutorials/README (nonexistent) +++ tags/2.3.0/doc/tutorials/README (revision 33253) @@ -0,0 +1,6 @@ +Policy: + - a small, modular tutorial + - reference back wherever possible to save redundant board files and screenshots + - the goal is to provide the smallest starter kit here + - but the few tutorials we have here should describe full workflows + - any tutorial on detals shall go in the pool Index: tags/2.3.0/doc/tutorials/index.html =================================================================== --- tags/2.3.0/doc/tutorials/index.html (nonexistent) +++ tags/2.3.0/doc/tutorials/index.html (revision 33253) @@ -0,0 +1,20 @@ + + + + pcb-rnd tutorials + + + + +

pcb-rnd - tutorial index

+ +

+

+ +The number in the tutorial title indicates the difficulty level of the +tutorial. Index: tags/2.3.0/doc/tutorials/pnp-origin/index.html =================================================================== --- tags/2.3.0/doc/tutorials/pnp-origin/index.html (nonexistent) +++ tags/2.3.0/doc/tutorials/pnp-origin/index.html (revision 33253) @@ -0,0 +1,153 @@ + + + + pcb-rnd - license + + + +

pick and place - origin

+ +

A. simplest case: rectangular board, implicit outline, implicit P&P origin

+

+Assume a board of 775*725 mils needs to be +created. The P&P fab says coord 0;0 is the lower left corner. The board +fab says they need the centerline of tool-path on the outline layer for +milling. +

+By far the simplest way to handle this board is to rely on builtin defaults: +

    +
  • board size (width and height) specifies the outline of a rectangular board +
  • if the outline layer exists but is empty, an implicit rectangular outline is drawn, matching board sizes +
  • implicit P&P origin is the lower left corner +
+

+Setting it up: +

    +
  • 1. start pcb-rnd with no board - this gets the default board template +
  • 2. change board width & height (gtk: file/preferences/user PoV/sizes) +
  • 3. do the layout +
  • 4. when exporting Gerber, enable the 'all layers' option to get the implicit outline layer +
  • 5. export the xy +
+

+ + + +
ProsCons +
    +
  • easy to set up +
  • no need to draw the outline +
+
    +
  • limited drawing area - unsuitable for editing small boards +
  • supports rectangular shapes only +
+
+ +

B. rectangular board, explicit outline, explicit P&P origin

+

+Assume another board of 775*725 mils needs to +be created. The P&P fab says coord 0;0 is the lower left corner. The +board fab says they need the centerline of tool-path on the outline layer +for milling. +

+This time the virtual board (canvas, drawing area) will be larger and the +board outline of a 775*725 will be manually drawn. Since pcb-rnd won't make +a guess of where the lower-left corner is, an explicit origin mark +needs to be added for the pick&place process. +Setting it up, assuming the GTK HID: +

    +
  • 1. start pcb-rnd with no board - this gets the default board template +
  • 2. draw the 775*725 mils box on the outline layer anywhere in the drawing area +
  • 3. do the layout within this box +
  • 4. draw a short line on a random layer - this will be the P&P mark +
  • 5. drag&drop move the endpoint of the unselected mark line to its other endpoint - this will result in a 0 long line, which looks like a filled circle; with 's' increase the size so that it's easily visible +
  • 6. select the mark, drag&drop move it to the lower left corner of the outline box +
  • 7. the mark still selected, press ctrl+e and click on the "add attribute" button in the property editor +
  • 8. type in "pnp-origin" in the "Attribute key" and "yes" in the "Attribute value" field; click ok and close the property editor +
  • 9. export the Gerber and xy files +
+

+There is a video tutorial available on steps 4..8. +

+Note 1: the mark is not explicitly visible in the XY file. It is not explicitly +passed to the P&P fab. Instead, all subcircuit coordinates are calculated considering +the mark's center as 0;0. +

+Note 2: still, the mark is not hidden or suppressed by pcb-rnd from any +of the output. It must be a line, but it can be on any of the layers. +Thus the mark potentially would show up on the board. There are multiple +options to make the mark disappear: +

    +
  • make the mark diameter smaller that the router mill bit diameter and place + the mark on a copper layer; the board fab will have the copper dot, but it + will be milled away. +
  • same trick should work with silk as well +
  • or even on the solder mask layer where this object would be a small cutout over void +
  • make a new (copper) layer, place the mark there and don't send this layer's Gerber export + (later on pcb-rnd will support documentation layers which are more dedicated for this sort of use) +
+

+ + +
ProsCons +
    +
  • drawing area (canvas) is bigger than the board: easier to edit +
  • can handle slots, cut-outs on the outline layer +
  • if the pick and place fab requires a slight offset on the placement, it is easy to move the mark +
+
    +
  • requires more steps to set up +
+
+ +

C. round board, explicit outline, explicit P&P origin

+

+Assume a third board shaped as a 700 mil +diameter circle. The P&P fab says coord 0;0 is the lower left corner of +the bounding box of the circle. The board fab says they need the +centerline of tool-path on the outline layer for milling. +

+The process is the same as in example B. The only extra consideration +is how to find the coords of the P&P origin mark; for this the P&P fab +house needs to be consulted. +

+There is a video tutorial available on using temporary +lines to aid placing the mark for a round lower-left corner. + +

D. different P&P origin for different fabs

+

+If the same board is populated by two different fabs who want different +origins, as long as they are also using different file formats, it is possible +to use two marks. The mechanism for finding the relevant mark is this: +

    +
  • look for a line that has attribute pnp-origin-FORMAT where FORMAT is the name of the format, e.g. gxyrs or Macrofab +
  • if that's not found, look for a line that has attribute pnp-origin +
  • if that's not found, use the bottom-left corner of the drawing area +
+

+This means the origin can be a different mark per format and/or a fallback +mark can be also added. + +

E. mark shapes

+

+In the above examples we used a zero-length line for the mark, which looked +like a filled circle. The code will find the first line with the right attribute +and use the center point of that line. For a zero-length line the center point +is the same as the two endpoints or the center of the filled circle it produces +on the screen. +

+It is possible to use non-zero-length lines for the mark. For example two lines +arranged in a + or x shape, either or both lines having the pnp-origin +attribute. If the mark is symmetrical, the crossing point happens to be the +middle of the line, which is what the code is after. +

+Of course it's also possible to use a single, non-zer-length line as mark, +but then it's harder to see the middle point as an user. It may still work +in some simple cases, e.g. a 45 degree short line segment symmetrically placed +on the corner of a 90 degree outline corner. + + + + + Index: tags/2.3.0/doc/tutorials/pnp-origin/orig_impl.lht =================================================================== --- tags/2.3.0/doc/tutorials/pnp-origin/orig_impl.lht (nonexistent) +++ tags/2.3.0/doc/tutorials/pnp-origin/orig_impl.lht (revision 33253) @@ -0,0 +1,411 @@ +ha:pcb-rnd-board-v2 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 775.0mil + y = 725.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 25.0mil + y = 625.0mil + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + + li:objects { + ha:element.777 { + x=225.0mil; y=200.0mil; + li:objects { + ha:text.774 { + string=Standard SMT resistor, capacitor etc; x=193.5mil; y=93.5mil; scale=100; fid=0; direction=0; role=desc; + } + ha:text.775 { + string=R1; x=193.5mil; y=93.5mil; scale=100; fid=0; direction=0; role=name; + } + ha:text.776 { + string=1206; x=193.5mil; y=93.5mil; scale=100; fid=0; direction=0; role=value; + } + ha:line.778 { + x1=-599.948um; y1=-37.4mil; x2=23.62mil; y2=-37.4mil; thickness=8.0mil; clearance=0.0; + } + ha:line.779 { + x1=-599.948um; y1=0.94996mm; x2=23.62mil; y2=0.94996mm; thickness=8.0mil; clearance=0.0; + } + ha:pad.780 { + name=1; number=1; x1=-59.05mil; y1=-299.974um; x2=-59.05mil; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.781 { + name=2; number=2; x1=1.49987mm; y1=-299.974um; x2=1.49987mm; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + ha:element.785 { + x=550.0mil; y=200.0mil; + li:objects { + ha:text.782 { + string=Standard SMT resistor, capacitor etc; x=518.5mil; y=93.5mil; scale=100; fid=0; direction=0; role=desc; + } + ha:text.783 { + string=R2; x=518.5mil; y=93.5mil; scale=100; fid=0; direction=0; role=name; + } + ha:text.784 { + string=1206; x=518.5mil; y=93.5mil; scale=100; fid=0; direction=0; role=value; + } + ha:line.786 { + x1=-599.948um; y1=-37.4mil; x2=23.62mil; y2=-37.4mil; thickness=8.0mil; clearance=0.0; + } + ha:line.787 { + x1=-599.948um; y1=0.94996mm; x2=23.62mil; y2=0.94996mm; thickness=8.0mil; clearance=0.0; + } + ha:pad.788 { + name=1; number=1; x1=-59.05mil; y1=-299.974um; x2=-59.05mil; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.789 { + name=2; number=2; x1=1.49987mm; y1=-299.974um; x2=1.49987mm; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + ha:element.793 { + x=225.0mil; y=450.0mil; + li:objects { + ha:text.790 { + string=Standard SMT resistor, capacitor etc; x=193.5mil; y=343.5mil; scale=100; fid=0; direction=0; role=desc; + } + ha:text.791 { + string=R3; x=193.5mil; y=343.5mil; scale=100; fid=0; direction=0; role=name; + } + ha:text.792 { + string=1206; x=193.5mil; y=343.5mil; scale=100; fid=0; direction=0; role=value; + } + ha:line.794 { + x1=-599.948um; y1=-37.4mil; x2=23.62mil; y2=-37.4mil; thickness=8.0mil; clearance=0.0; + } + ha:line.795 { + x1=-599.948um; y1=0.94996mm; x2=23.62mil; y2=0.94996mm; thickness=8.0mil; clearance=0.0; + } + ha:pad.796 { + name=1; number=1; x1=-59.05mil; y1=-299.974um; x2=-59.05mil; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.797 { + name=2; number=2; x1=1.49987mm; y1=-299.974um; x2=1.49987mm; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + ha:element.801 { + x=550.0mil; y=450.0mil; + li:objects { + ha:text.798 { + string=Standard SMT resistor, capacitor etc; x=443.5mil; y=481.5mil; scale=100; fid=0; direction=1; role=desc; + } + ha:text.799 { + string=R4; x=443.5mil; y=481.5mil; scale=100; fid=0; direction=1; role=name; + } + ha:text.800 { + string=1206; x=443.5mil; y=481.5mil; scale=100; fid=0; direction=1; role=value; + } + ha:line.802 { + x1=-37.4mil; y1=-599.948um; x2=-37.4mil; y2=23.62mil; thickness=8.0mil; clearance=0.0; + } + ha:line.803 { + x1=0.94996mm; y1=-599.948um; x2=0.94996mm; y2=23.62mil; thickness=8.0mil; clearance=0.0; + } + ha:pad.804 { + name=1; number=1; x1=-299.974um; y1=1.49987mm; x2=11.81mil; y2=1.49987mm; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.805 { + name=2; number=2; x1=-299.974um; y1=-59.05mil; x2=11.81mil; y2=-59.05mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:line.750 { + x1=284.05mil; y1=200.0mil; x2=12.47013mm; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.753 { + x1=4.21513mm; y1=200.0mil; x2=4.21513mm; y2=450.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.756 { + x1=284.05mil; y1=450.0mil; x2=325.0mil; y2=450.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.759 { + x1=325.0mil; y1=450.0mil; x2=400.0mil; y2=525.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.762 { + x1=400.0mil; y1=525.0mil; x2=525.0mil; y2=525.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.765 { + x1=550.0mil; y1=9.93013mm; x2=550.0mil; y2=375.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.768 { + x1=550.0mil; y1=375.0mil; x2=625.0mil; y2=300.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.771 { + x1=625.0mil; y1=300.0mil; x2=625.0mil; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + } + + ha:solder { + lid=1 + group=8 + ha:combining { } + visible=1 + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + visible=1 + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + visible=1 + } + + ha:sold-GND { + lid=4 + group=8 + ha:combining { } + visible=1 + } + + ha:sold-power { + lid=5 + group=8 + ha:combining { } + visible=1 + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + visible=1 + + } + + ha:outline { + lid=7 + group=7 + ha:combining { } + visible=1 + + } + + ha:silk { + lid=8 + group=10 + ha:combining { auto=1; } + visible=1 + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + visible=1 + } + } + } + + ha:netlists { + li:input { + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + ha:2 { + name = top mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; 3; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_6 + } + ha:7 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 7; } + } + ha:8 { + name = bottom copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:9 { + name = bottom mask + ha:type { bottom=1; mask=1; } + li:layers { } + } + ha:10 { + name = bottom silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:11 { + name = bottom paste + ha:type { bottom=1; paste=1; } + li:layers { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.00 mil + clearance = 20.00 mil + via_thickness = 2000.00 um + via_drilling_hole = 31.50 mil + min_slk = 7.00 mil + max_height = 725.00 mil + line_thickness = 10.00 mil + shrink = 9.00 mil + poly_isle_area = 199999999.999200 + max_width = 775.00 mil + min_wid = 10.00 mil + bloat = 12.00 mil + min_drill = 15.00 mil + } + ha:editor { + buffer_number = 0 + grid_unit = mil + } + } + } +} Index: tags/2.3.0/doc/tutorials/pnp-origin/orig_round.lht =================================================================== --- tags/2.3.0/doc/tutorials/pnp-origin/orig_round.lht (nonexistent) +++ tags/2.3.0/doc/tutorials/pnp-origin/orig_round.lht (revision 33253) @@ -0,0 +1,449 @@ +ha:pcb-rnd-board-v2 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 1000.0mil + y = 1000.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 25.0mil + y = 625.0mil + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + + li:objects { + ha:element.45 { + x=375.0mil; y=350.0mil; + li:objects { + ha:text.42 { + string=Standard SMT resistor, capacitor etc; x=343.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=desc; + } + ha:text.43 { + string=R1; x=343.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=name; + } + ha:text.44 { + string=1206; x=343.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=value; + } + ha:line.46 { + x1=-599.948um; y1=-37.4mil; x2=23.62mil; y2=-37.4mil; thickness=8.0mil; clearance=0.0; + } + ha:line.47 { + x1=-599.948um; y1=0.94996mm; x2=23.62mil; y2=0.94996mm; thickness=8.0mil; clearance=0.0; + } + ha:pad.48 { + name=1; number=1; x1=-59.05mil; y1=-299.974um; x2=-59.05mil; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.49 { + name=2; number=2; x1=1.49987mm; y1=-299.974um; x2=1.49987mm; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + ha:element.73 { + x=700.0mil; y=350.0mil; + li:objects { + ha:text.70 { + string=Standard SMT resistor, capacitor etc; x=668.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=desc; + } + ha:text.71 { + string=R2; x=668.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=name; + } + ha:text.72 { + string=1206; x=668.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=value; + } + ha:line.74 { + x1=-599.948um; y1=-37.4mil; x2=23.62mil; y2=-37.4mil; thickness=8.0mil; clearance=0.0; + } + ha:line.75 { + x1=-599.948um; y1=0.94996mm; x2=23.62mil; y2=0.94996mm; thickness=8.0mil; clearance=0.0; + } + ha:pad.76 { + name=1; number=1; x1=-59.05mil; y1=-299.974um; x2=-59.05mil; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.77 { + name=2; number=2; x1=1.49987mm; y1=-299.974um; x2=1.49987mm; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + ha:element.81 { + x=375.0mil; y=600.0mil; + li:objects { + ha:text.78 { + string=Standard SMT resistor, capacitor etc; x=343.5mil; y=493.5mil; scale=100; fid=0; direction=0; role=desc; + } + ha:text.79 { + string=R3; x=343.5mil; y=493.5mil; scale=100; fid=0; direction=0; role=name; + } + ha:text.80 { + string=1206; x=343.5mil; y=493.5mil; scale=100; fid=0; direction=0; role=value; + } + ha:line.82 { + x1=-599.948um; y1=-37.4mil; x2=23.62mil; y2=-37.4mil; thickness=8.0mil; clearance=0.0; + } + ha:line.83 { + x1=-599.948um; y1=0.94996mm; x2=23.62mil; y2=0.94996mm; thickness=8.0mil; clearance=0.0; + } + ha:pad.84 { + name=1; number=1; x1=-59.05mil; y1=-299.974um; x2=-59.05mil; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.85 { + name=2; number=2; x1=1.49987mm; y1=-299.974um; x2=1.49987mm; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + ha:element.89 { + x=700.0mil; y=600.0mil; + li:objects { + ha:text.86 { + string=Standard SMT resistor, capacitor etc; x=593.5mil; y=631.5mil; scale=100; fid=0; direction=1; role=desc; + } + ha:text.87 { + string=R4; x=593.5mil; y=631.5mil; scale=100; fid=0; direction=1; role=name; + } + ha:text.88 { + string=1206; x=593.5mil; y=631.5mil; scale=100; fid=0; direction=1; role=value; + } + ha:line.90 { + x1=-37.4mil; y1=-599.948um; x2=-37.4mil; y2=23.62mil; thickness=8.0mil; clearance=0.0; + } + ha:line.91 { + x1=0.94996mm; y1=-599.948um; x2=0.94996mm; y2=23.62mil; thickness=8.0mil; clearance=0.0; + } + ha:pad.92 { + name=1; number=1; x1=-299.974um; y1=1.49987mm; x2=11.81mil; y2=1.49987mm; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.93 { + name=2; number=2; x1=-299.974um; y1=-59.05mil; x2=11.81mil; y2=-59.05mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:line.94 { + x1=434.05mil; y1=350.0mil; x2=640.95mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.97 { + x1=8.02513mm; y1=350.0mil; x2=8.02513mm; y2=600.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.100 { + x1=434.05mil; y1=600.0mil; x2=475.0mil; y2=600.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.103 { + x1=475.0mil; y1=600.0mil; x2=550.0mil; y2=675.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.112 { + x1=550.0mil; y1=675.0mil; x2=675.0mil; y2=675.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.115 { + x1=700.0mil; y1=540.95mil; x2=700.0mil; y2=525.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.118 { + x1=700.0mil; y1=525.0mil; x2=775.0mil; y2=450.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.127 { + x1=775.0mil; y1=450.0mil; x2=775.0mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + } + + ha:solder { + lid=1 + group=8 + ha:combining { } + visible=1 + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + visible=1 + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + visible=1 + } + + ha:sold-GND { + lid=4 + group=8 + ha:combining { } + visible=1 + } + + ha:sold-power { + lid=5 + group=8 + ha:combining { } + visible=1 + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + visible=1 + + li:objects { + ha:line.209 { + x1=150.0mil; y1=825.0mil; x2=150.0mil; y2=825.0mil; thickness=50.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + selected=1 + } + ha:attributes { + pnp-origin=yes + } + } + } + } + + ha:outline { + lid=7 + group=7 + ha:combining { } + visible=1 + + li:objects { + ha:arc.195 { + x=500.0mil; y=475.0mil; width=350.0mil; height=350.0mil; astart=0; adelta=-90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.197 { + x=500.0mil; y=475.0mil; width=350.0mil; height=350.0mil; astart=90; adelta=-90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.198 { + x=500.0mil; y=475.0mil; width=350.0mil; height=350.0mil; astart=180; adelta=-90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.199 { + x=500.0mil; y=475.0mil; width=350.0mil; height=350.0mil; astart=270; adelta=-90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + } + + ha:silk { + lid=8 + group=10 + ha:combining { auto=1; } + visible=1 + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + visible=1 + } + } + } + + ha:netlists { + li:input { + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + ha:2 { + name = top mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; 3; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_6 + } + ha:7 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 7; } + } + ha:8 { + name = bottom copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:9 { + name = bottom mask + ha:type { bottom=1; mask=1; } + li:layers { } + } + ha:10 { + name = bottom silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:11 { + name = bottom paste + ha:type { bottom=1; paste=1; } + li:layers { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.00 mil + clearance = 20.00 mil + via_thickness = 2000.00 um + via_drilling_hole = 31.50 mil + min_slk = 7.00 mil + max_height = 1000.00 mil + line_thickness = 10.00 mil + shrink = 9.00 mil + poly_isle_area = 199999999.999200 + max_width = 1000.00 mil + min_wid = 10.00 mil + bloat = 12.00 mil + min_drill = 15.00 mil + } + ha:editor { + buffer_number = 0 + grid_unit = mil + } + } + } +} Index: tags/2.3.0/doc/tutorials/pnp-origin/orig_sq.lht =================================================================== --- tags/2.3.0/doc/tutorials/pnp-origin/orig_sq.lht (nonexistent) +++ tags/2.3.0/doc/tutorials/pnp-origin/orig_sq.lht (revision 33253) @@ -0,0 +1,445 @@ +ha:pcb-rnd-board-v2 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 1000.0mil + y = 1000.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 25.0mil + y = 625.0mil + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + + li:objects { + ha:element.45 { + x=375.0mil; y=350.0mil; + li:objects { + ha:text.42 { + string=Standard SMT resistor, capacitor etc; x=343.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=desc; + } + ha:text.43 { + string=R1; x=343.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=name; + } + ha:text.44 { + string=1206; x=343.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=value; + } + ha:line.46 { + x1=-599.948um; y1=-37.4mil; x2=23.62mil; y2=-37.4mil; thickness=8.0mil; clearance=0.0; + } + ha:line.47 { + x1=-599.948um; y1=0.94996mm; x2=23.62mil; y2=0.94996mm; thickness=8.0mil; clearance=0.0; + } + ha:pad.48 { + name=1; number=1; x1=-59.05mil; y1=-299.974um; x2=-59.05mil; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.49 { + name=2; number=2; x1=1.49987mm; y1=-299.974um; x2=1.49987mm; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + ha:element.73 { + x=700.0mil; y=350.0mil; + li:objects { + ha:text.70 { + string=Standard SMT resistor, capacitor etc; x=668.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=desc; + } + ha:text.71 { + string=R2; x=668.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=name; + } + ha:text.72 { + string=1206; x=668.5mil; y=243.5mil; scale=100; fid=0; direction=0; role=value; + } + ha:line.74 { + x1=-599.948um; y1=-37.4mil; x2=23.62mil; y2=-37.4mil; thickness=8.0mil; clearance=0.0; + } + ha:line.75 { + x1=-599.948um; y1=0.94996mm; x2=23.62mil; y2=0.94996mm; thickness=8.0mil; clearance=0.0; + } + ha:pad.76 { + name=1; number=1; x1=-59.05mil; y1=-299.974um; x2=-59.05mil; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.77 { + name=2; number=2; x1=1.49987mm; y1=-299.974um; x2=1.49987mm; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + ha:element.81 { + x=375.0mil; y=600.0mil; + li:objects { + ha:text.78 { + string=Standard SMT resistor, capacitor etc; x=343.5mil; y=493.5mil; scale=100; fid=0; direction=0; role=desc; + } + ha:text.79 { + string=R3; x=343.5mil; y=493.5mil; scale=100; fid=0; direction=0; role=name; + } + ha:text.80 { + string=1206; x=343.5mil; y=493.5mil; scale=100; fid=0; direction=0; role=value; + } + ha:line.82 { + x1=-599.948um; y1=-37.4mil; x2=23.62mil; y2=-37.4mil; thickness=8.0mil; clearance=0.0; + } + ha:line.83 { + x1=-599.948um; y1=0.94996mm; x2=23.62mil; y2=0.94996mm; thickness=8.0mil; clearance=0.0; + } + ha:pad.84 { + name=1; number=1; x1=-59.05mil; y1=-299.974um; x2=-59.05mil; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.85 { + name=2; number=2; x1=1.49987mm; y1=-299.974um; x2=1.49987mm; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + ha:element.89 { + x=700.0mil; y=600.0mil; + li:objects { + ha:text.86 { + string=Standard SMT resistor, capacitor etc; x=593.5mil; y=631.5mil; scale=100; fid=0; direction=1; role=desc; + } + ha:text.87 { + string=R4; x=593.5mil; y=631.5mil; scale=100; fid=0; direction=1; role=name; + } + ha:text.88 { + string=1206; x=593.5mil; y=631.5mil; scale=100; fid=0; direction=1; role=value; + } + ha:line.90 { + x1=-37.4mil; y1=-599.948um; x2=-37.4mil; y2=23.62mil; thickness=8.0mil; clearance=0.0; + } + ha:line.91 { + x1=0.94996mm; y1=-599.948um; x2=0.94996mm; y2=23.62mil; thickness=8.0mil; clearance=0.0; + } + ha:pad.92 { + name=1; number=1; x1=-299.974um; y1=1.49987mm; x2=11.81mil; y2=1.49987mm; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.93 { + name=2; number=2; x1=-299.974um; y1=-59.05mil; x2=11.81mil; y2=-59.05mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:line.94 { + x1=434.05mil; y1=350.0mil; x2=640.95mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.97 { + x1=8.02513mm; y1=350.0mil; x2=8.02513mm; y2=600.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.100 { + x1=434.05mil; y1=600.0mil; x2=475.0mil; y2=600.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.103 { + x1=475.0mil; y1=600.0mil; x2=550.0mil; y2=675.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.112 { + x1=550.0mil; y1=675.0mil; x2=675.0mil; y2=675.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.115 { + x1=700.0mil; y1=540.95mil; x2=700.0mil; y2=525.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.118 { + x1=700.0mil; y1=525.0mil; x2=775.0mil; y2=450.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.127 { + x1=775.0mil; y1=450.0mil; x2=775.0mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + } + + ha:solder { + lid=1 + group=8 + ha:combining { } + visible=1 + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + visible=1 + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + visible=1 + } + + ha:sold-GND { + lid=4 + group=8 + ha:combining { } + visible=1 + } + + ha:sold-power { + lid=5 + group=8 + ha:combining { } + visible=1 + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + visible=1 + + li:objects { + ha:line.136 { + x1=150.0mil; y1=875.0mil; x2=150.0mil; y2=875.0mil; thickness=50.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + ha:attributes { + pnp-origin=yes + } + } + } + } + + ha:outline { + lid=7 + group=7 + ha:combining { } + visible=1 + + li:objects { + ha:line.50 { + x1=150.0mil; y1=150.0mil; x2=150.0mil; y2=875.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.53 { + x1=150.0mil; y1=875.0mil; x2=925.0mil; y2=875.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.56 { + x1=925.0mil; y1=875.0mil; x2=925.0mil; y2=150.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.59 { + x1=925.0mil; y1=150.0mil; x2=150.0mil; y2=150.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + } + + ha:silk { + lid=8 + group=10 + ha:combining { auto=1; } + visible=1 + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + visible=1 + } + } + } + + ha:netlists { + li:input { + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + ha:2 { + name = top mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; 3; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:7 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 7; } + } + ha:8 { + name = bottom copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:9 { + name = bottom mask + ha:type { bottom=1; mask=1; } + li:layers { } + } + ha:10 { + name = bottom silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:11 { + name = bottom paste + ha:type { bottom=1; paste=1; } + li:layers { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.00 mil + clearance = 20.00 mil + via_thickness = 2000.00 um + via_drilling_hole = 31.50 mil + min_slk = 7.00 mil + max_height = 1000.00 mil + line_thickness = 10.00 mil + shrink = 9.00 mil + poly_isle_area = 199999999.999200 + max_width = 1000.00 mil + min_wid = 10.00 mil + bloat = 12.00 mil + min_drill = 15.00 mil + } + ha:editor { + buffer_number = 0 + } + } + } +} Index: tags/2.3.0/doc/user/01_intro/Makefile =================================================================== --- tags/2.3.0/doc/user/01_intro/Makefile (nonexistent) +++ tags/2.3.0/doc/user/01_intro/Makefile (revision 33253) @@ -0,0 +1,2 @@ +flow.svg: src/flow.dot + dot -Tsvg src/flow.dot > flow.svg Index: tags/2.3.0/doc/user/01_intro/flow.svg =================================================================== --- tags/2.3.0/doc/user/01_intro/flow.svg (nonexistent) +++ tags/2.3.0/doc/user/01_intro/flow.svg (revision 33253) @@ -0,0 +1,135 @@ + + + + + + +flow + + +sch + +schematics editor +e.g. gschem + + +pcb + +pcb-rnd + + +sch->pcb + + +fwd annotation + + +pcb->sch + + +back annotation + + +fab + +fab house + + +pcb->fab + + +e.g. gerber, bom, xy + + +tt + +etching at home: +toner transfer + + +pcb->tt + + +e.g. ps or png + + +web + +web page + + +pcb->web + + +e.g. svg + + +doc + +printed +documentation + + +pcb->doc + + +e.g. ps, eps, png, jpg + + +kicad + +collaboration with +someone using kicad + + +pcb->kicad + + + +kicad's +native format + + +gpcb + +collaboration with +someone using gEDA/PCB + + +pcb->gpcb + + + +gEDA +native format + + +lib + +local footprint +library + + +lib->pcb + + + +.fp + + +wlib + +remote footprint +library (e.g. on the web) + + +wlib->pcb + + +import footprint + + + Index: tags/2.3.0/doc/user/01_intro/history.html =================================================================== --- tags/2.3.0/doc/user/01_intro/history.html (nonexistent) +++ tags/2.3.0/doc/user/01_intro/history.html (revision 33253) @@ -0,0 +1,49 @@ + + + + pcb-rnd user manual + + + + +

1.2. pcb-rnd History

+

pcb-rnd is a rapid moving independent project started in 2013, but roots +tracing back to the early 90s, to PCB. + +

+From the pcb.html documentation: +


+	Pcb was first written by Thomas Nau for an
+	Atari ST in 1990 and ported to UNIX and X11 in
+	1994.  It was not intended as a professional layout system, but as a tool
+	which supports people who do some home-developing of hardware.
+
+ +

In Fall 2013, Tibor 'Igor2' Palinkas started an +unofficial fork of PCB to make and +share random changes and improvements (hence the name "-rnd"). Over +the following years the fork was officially announced, adopted additional +users, and reached various milestones, including modularization of the code +base, a better configuration system. +

+In 2015, the project switched pace: lot of hours invested and many new developers +and contributors joined, pcb-rnd started to grow rapidly. Most of the code base +has been extended, cleaned up or rewritten. +

+In 2016 and 2017 pcb-rnd went on growig in number of developers, contributors +and users. The number of long standing bugs and misfeatures fixed and missing +features implemented grew a lot too. This affected major components +as the plugin system, the I/O (file format support) subsystem and even the +data model pcb-rnd operates on. +

+Between 2017 and 2019 pcb-rnd got a major data model redesign. The resulting +data model is generic and flexible, capable of representing most details +imported from alien file formats. +

+pcb-rnd is part of the ringdove EDA suite. +

+A more complete history can be found in the +pcb-history project. + + + Index: tags/2.3.0/doc/user/01_intro/index.html =================================================================== --- tags/2.3.0/doc/user/01_intro/index.html (nonexistent) +++ tags/2.3.0/doc/user/01_intro/index.html (revision 33253) @@ -0,0 +1,23 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+ +

1. About pcb-rnd

+

+pcb-rnd is an interactive (or scripted) graphical (or command line) +Printed Circuit Board editor. Besides editing it offers converting +between formats, running DRC checks, generating previews. +

+

+ + + Index: tags/2.3.0/doc/user/01_intro/intro.html =================================================================== --- tags/2.3.0/doc/user/01_intro/intro.html (nonexistent) +++ tags/2.3.0/doc/user/01_intro/intro.html (revision 33253) @@ -0,0 +1,70 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+ +

1.1. Introduction

+

+pcb-rnd is a highly modular, interactive Printed Circuit Board editor +with a very long history . + + +

1.1.1. Place in the workflow

+

+The main purpose of pcb-rnd is to edit the geometry of the board. This +includes board shape, copper shape, layer stackup, holes drilled, slots +routed. +

+The input of the layout process is usually a netlist derived from +schematics, and occasionally layouts drawn from scratch or created from +schematic without importable netlist. Pcb-rnd can read different netlist +formats and it can help the user to realize the given netlist in copper or to +change the netlist and back annotate the changes. Pcb-rnd, however, does not +display or edit schematics directly. +

+The output of pcb-rnd is most often a vector format (e.g. gerber +RS274D), that is sent to a pcb fab house for manufacturing or is utilized for +auto-fabrication. Pcb-rnd supports a variety of vector and raster output +formats making it easy to print boards, publish them on web pages, and include +them in documentation. +

+The typical workflows are: +

+[workflow diagram showing pcb-rnd interacting with schematics editor, fabrication, and others] +

+Black flows are the most commonly used; grey flows are possible, fully +supported but less often used in practice. + +

1.1.2. What pcb-rnd is and is not

+

+Pcb-rnd is a versatile tool for PCB layout design. It is geared to be +a tool for users with the UNIX mind set: +

    +
  • it is small, easy to compile and run, has low resource footprint +
  • it is modular - most features are in plugins, the user can chose which plugins to use +
  • it is portable - also runs on systems that are not hyped today +
  • it works well from both CLI (automation, e.g. called from a Makefile or even using with an interactive action command shell) and GUI +
  • it is designed to communicate with other software: +
      +
    • it is easy to remote control +
    • it speaks many file formats +
    +
  • it doesn't outsmart the user, it doesn't block the user from doing unusual things; it has support for checking the result and generate warnings +
+

+There are a few things that are out of scope for pcb-rnd: +

    +
  • 3d editing: pcb-rnd is 2.5d, that means it's basically 2d and understands the 3rd dimension partially; it does load, handle and export 3d data (e.g. subcircuit part models for an openscad export) but it does not edit 3d data +
  • embedded <whatever-non-pcb-editing>: as a UNIX tool, pcb-rnd focuses on one thing, pcb edition, and relies on (and maintains close cooperation with) other tools for: +
      +
    • circuit schematics edition +
    • 3d rendering +
    • simulation +
    +
  • autorouting - there's a basic built-in autorouter, but it's recommended to use external autorouters (various file formats are supported) +
Index: tags/2.3.0/doc/user/01_intro/src/flow.dot =================================================================== --- tags/2.3.0/doc/user/01_intro/src/flow.dot (nonexistent) +++ tags/2.3.0/doc/user/01_intro/src/flow.dot (revision 33253) @@ -0,0 +1,45 @@ +digraph flow { + rankdir=LR + + subgraph in { + rank=same + sch [label="schematics editor\ne.g. gschem"] + } + + subgraph edit { + rank=same + pcb [label="pcb-rnd" shape=octagon width=2 height=2] + lib [label="local footprint\nlibrary"] + wlib [label="remote footprint\nlibrary (e.g. on the web)" color=grey fontcolor=grey] + } + + + subgraph out { + rank=same + fab [label="fab house"] + tt [label="etching at home:\ntoner transfer"] + web [label="web page"] + doc [label="printed\ndocumentation"] + } + + subgraph edit { + rank=same + kicad [label="collaboration with\nsomeone using kicad" color=grey fontcolor=grey] + gpcb [label="collaboration with\nsomeone using gEDA/PCB" color=grey fontcolor=grey] + } + + + sch -> pcb [label="fwd annotation"] + pcb -> sch [label="back annotation" color=grey fontcolor=grey] + pcb -> fab [label="e.g. gerber, bom, xy"] + pcb -> tt [label="e.g. ps or png"] + pcb -> web [label="e.g. svg"] + pcb -> doc [label="e.g. ps, eps, png, jpg"] + + lib -> pcb [label=".fp" dir=both weight=1000] + + wlib -> pcb [label="import footprint" dir=back color=grey fontcolor=grey] + + pcb -> kicad [label="kicad's\nnative format" dir=both color=grey fontcolor=grey] + pcb -> gpcb [label="gEDA\nnative format" dir=both color=grey fontcolor=grey] +} Index: tags/2.3.0/doc/user/02_model/index.html =================================================================== --- tags/2.3.0/doc/user/02_model/index.html (nonexistent) +++ tags/2.3.0/doc/user/02_model/index.html (revision 33253) @@ -0,0 +1,714 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+ +

2. Model of the world

+

+Pcb-rnd is designed to handle the geometric data of a PCB. This section describes +how pcb-rnd represents reality (e.g. copper shapes) in memory. + +

2.1. Board

+

+Each design pcb-rnd handles is a board. The board has global properties and hosts +layers. Most drawing primitives (objects) are on layers. This section describes +the most important global properties. +

+Raw board size is given as a width and a height. This is the size +of the preferred drawing area on screen, but for rectangular boards this +can be the real board size. More often final board dimensions are +specified by drawing objects drawn on boundary layer groups within this +area. If the board is not rectangular, the contour must be specified on +boundary layers and the board size must be large enough that the outline +fits in it. +

+Netlist is the list of logical connections to be realized in copper. +A netlist is a list of named nets. Each net consists of a list of +terminals (pins or pads) to connect. A terminal is given as +refdes-pinname, e.g. U4-7 means "pin number 7 in subcircuit called U4". +

+Fonts are normally embedded in the design file in order to guarantee +that the file can be ported and will look the same on different hosts. +

+Configuration: misc editor settings, such as grid size and offset, plugin +settings. +

+Route styles. + +

2.2. Layers

+

+The main use of pcb-rnd is to aide the user in the process of producing real +pcbs composed of real physical layers. pcb-rnd also refers to layers to +conceptualize this process, but pcb-rnd layers are different than the +physical layers. +

+Unlike a physical layer, a pcb-rnd layer has no thickness. Any pcb-rnd +layer is always part of a layer group. It is a 2 dimensional logical +canvas, similar to layers in image manipulation software like GIMP. In pcb-rnd +there are explicit, virtual or implicit layers. An +explicit layer contains drawing primitives (objects) +placed by the user. The user has full control over an explicit layer: objects +can be added or removed or changed any time. A virtual or implicit layer has no +such flexibility: pcb-rnd computes its content from explicit layers and there's +no way for the user to change the result directly. +

+Pcb-rnd currently maintains some layers types as virtual layers for +compatibility with the PCB package. In a pcb-rnd board design started from +default configuration options, the mask, silk, and paste layers currently start +out as virtual layers. The content for these layers is computed by pcb-rnd as +for a virtual or explicit layer, until the user decides to use features that +require user control over one or more of the layers in the group. At that +point, the virtual layer is replaced with an explicit layer group. +

+For example, in pcb-rnd when using one of the gtk GUIs, if the user right +clicks on a solder mask ('mask') layer and choose an option to 'insert new +layer before this one', pcb-rnd replaces the virtual mask layer with an explicit +mask layer group. The mask layer group can contain one to many pcb-rnd layers +each with individual settings to control implicit generation, and additive or +subtractive behavior when adding objects to the layers. + +

2.3. Layer Groups

+

+One or more explicit layers form a layer group. All pcb-rnd layers +of a layer group will end up on the same physical layer. The visibility of +layers in a layer group are toggled together. Having more than one layer +in a group may be useful to: +

    +
  • exploit that layers have different + drawing color on screen: + e.g. there can be a signal and a gnd layers with different color in + the same layer group, on the same physical layer. +
  • on composite-groups (mask, paste, silk), layers are combined using + their properties: some layers may draw, others may clear; some layers + may contain auto-generated objects. The order of layers does matter + in draw-clear combinations. +
+

+Since layer groups donate the physical layers, a board stack-up +is built of layer groups. Substrates are layer groups without drawable +layers in them. The mask, paste, silk layer groups behave the same and +can host zero or more logical layers. +

+Each layer group has a main type. Main types are: +

    +
  • copper for signal layers +
  • silk for silkscreen layers +
  • mask for solder masks +
  • paste for solder paste + +
  • boundary for the contour of the board +
  • mech mechanical information (e.g. cutouts, slots, adhesive; sent to the board fab) +
  • doc documentation and metadata (not sent to the board fab) +
+

+Each layer group has a location. Locations are: +

    +
  • top (used to be the "component side" in the age of thru-hole components) +
  • bottom (used to be the "solder side" in the age of thru-hole components) +
  • intern (sandwiched between other layers) +
  • global (affects all physical layers, thus has no specific location) +
+

+Not all combination of type and location are supported: e.g. for a boundary +layer group the location is always global. The table below lists whether a +combination is supported or not. +

+ +
Layer Combination Support +
  top bottom intern global composite +
copper yes yes yes no no +
silk yes yes no no yes +
mask yes yes no no yes +
paste yes yes no no yes +
boundary no no no yes no +
mech yes yes yes yes maybe +
doc yes yes yes yes maybe +
+

+Note: for some layer types whether compositing is allowed depends on the +subtype (purpose). +

+Each layer group has a purpose field, which functions as a +subtype. The value is a free form text for user defined groups, but pcb-rnd +recognizes (and handles specially) the following combinations: +

+ +
Layer purpose combinations recongized +
main type purpose special meaning +
boundary uroute unplated, routed bounary: routed outline of the board +
boundary proute plated, routed bounary: routed outline of the board with copper plating +
mech uroute unplated, routed inner cutout: unplated slots and small inner cutouts, done with drilling or routing or punch-through +
mech proute plated, routed inner cutout: plated slots and small inner cutouts, done with drilling or routing or punch-through (typical for oval/rectanglar pins) +
+ +

+The following combinations are conventions many footprints and boards +would follow: +

+ +
Layer purpose combinations recommended +
main type purpose location special meaning +
boundary cut (global) unplated, straight line cuts at board outline +
boundary vcut (global) unplated, straight line v-cuts (or grooves) at board outline +
doc assy top or bottom assembly drawing (for populating the board) +
doc fab top fab instructions (for board fabrication: cuts and drills) +
doc ko.courtyard top or bottom keepout: component body above (or below) the board surface (polygons) +
doc ko@lt respectively keepout: nothing shall be drawn on layer type lt that intersects objects on this layer; lt is location-type, e.g. top-copper, bottom-silk, etc. +
doc placement any placement helpers, e.g. where board edge should be relative to a connector +
mech adhesive top or bottom adhesive (glue) pattern printed on the board to keep parts in place during reflow +
mech finish.gold top or bottom gold finish (typical for copper fingers intended for slots/connectors/contacts) +
mech finish.carbon top or bottom carbon finish (typical for under rubber push buttons) +
+ +

+Layer group attributes interpreted by pcb-rnd core: +

+ +
Layer group attributes +
layer group attribute name description +
thickness thickness of the physical layer, given with unit (e.g. 0.2mm or 200um or 50mil) +
plugin::thickness overrides the above thickness value for a specific plugin, if the plugin supports it; for example openems::thickness will use a different layer group thickness for the given layer group when exporting to openems +
dielectric Relative dielectric constant, typically for substrate layer groups, Er (unitless) +
+

+ +

2.4. Basic Drawing Objects

+

+Pcb-rnd supports a small number of basic drawing objects, from which complex +objects can be build. The following figure demonstrates all basic objects: +

+[Arc, Line, Polygon, Pin, Via] +

+Objects have flags that control their behavior. The following flags are common +to all objects: +

+ +
Object Flags +
name description +
selected selected by the user ("cyan") +
found found as a galvanic connection in the last connection lookup ("green") +
warn offending object e.g. in a short circuit ("orange") +
lock locked by the user: can't be selected, moved or changed using the basic mouse/keyboard actions (still can be copied, selected by query() and edited by propedit()) +
+ + +

2.4.1. Line Objects

+

+Lines are round ended straight line segments with a width and +a clearance. The above image shows 3 lines connected. Lines are mainly +used to construct traces. A line is always on a specific layer. The user +interface allows drawing lines aligned to 90 or 45 degree axes or +lines with random angle. +

+A line is specified by its two endpoints, width and clearance: +

+[Line interacting with a polygon] +

+A clearance is the gap between a line and the surrounding polygon +in the same layer group. The gap is made only if the surrounding polygon has +the "clearpoly" flag set and the line has the "clearline" flag set. If either +of these flags is not set, no gap is made - or in pcb-rnd terminology, +the line is joined to the polygon. +

+ +
Line Object Flags +
name description +
clearline clears polygons with the "clearpoly" flag in the same layer group +
+ +

2.4.2. Arc Objects

+

+Arcs are round ended circular arcs with trace width and clearance. They +behave like lines in all respects. +

+[Arc interacting with a polygon] +

+Although the arc is described with its center, radius, start and end +angles, the user interface may offer drawing arcs by endpoints. +

+ +
Arc Object Flags +
name description +
clearline clears polygons with the "clearpoly" flag in the same layer group +
+ +

2.4.3. Polygon Objects

+

+Polygons are solid, filled copper areas with optional holes in them. Polygon +contour consists of lines - when they look curvy, its really high resolution +line approximation. There are two type of holes in a polygon: explicit, +user drawn holes and clearance cutouts. User drawn holes are "negative" +polygons drawn manually. To keep polygons simple, if an user drawn hole +touches the contour of a polygon, the hole is removed and the contour is +modified; if two holes touch, they are merged into one hole. +

+If the polygon has the "clearpoly" flag set (default), clearance cutouts are +automatically inserted around objects on the same layer group: +

    +
  • lines and arcs, if they have the "clearline" flag set (default) +
  • padstacks, if they are not connected to the polygon by thermals +
+

+Overlapping or touching polygons are not automatically merged. An object +with the "clearline" flag set will clear all "clearpolys" it is over - +if there are multiple such polygons overlapping under the objects (on +the same layer group), all such polygons get the clearance cutout. +

+If a polygon has the "clearpolypoly" flag set, it clears any other polygon +that does not have the "clearpolypoly" flag set but has the +"clearpoly" set. In other words, a "clearpolypoly" polygon behaves the same +as a line/arc that has the "clearline" flag. +

+If a polygon is cut into multiple islands, the behavior depends on the +"fullpoly" flag of the polygon. If it is not set (default), only the largest +island is kept, else all islands are kept. In the "fullpoly" mode islands +will have no galvanic connection (unless the user adds vias and connect them +on another layer), still the program will handle all islands as a single +polygon. This is risky: the program will indicate connection between polygon +islands that are not really connected, only because they are part of the same +polygon! +

+Any polygon may have its enforce_clearance set to non-zero, in which +case any object that has a clearance within the given polygon by flags will +make a clearance at least as large as the polygon's enforce_clearance +(but larger, if the object requested larger clearance than +the polygon's enforce_clearance). Note: this applies only if +the object has the clearline flag and the polygon has the clearpoly flag. + +

+ +
Polygon Object Flags +
name description +
clearpoly should have clearance around objects, if the objects have the appropriate flags too +
fullpoly keep all islands, not only the largest +
+ +

2.4.4. Text Objects

+

+A text object is string and a series of symbols (pcb-rnd's terminology for +glyph). Symbols are built of lines and are stored in the font. Each board +can have its own font, but there can be only one font per board. When +the string of the text is edited, the object is rendered again so that the +new string appears. +

+Text objects can be placed on copper and silk layers. +Each text object has a scale_x, a scale_y and a scale parameter that +determine its size. If scale_x is non-zero, it is the width +multiplier on the neutral font width; if scale_y is non-zero, it +is the height multiplier on the normal font height. When any of the +two is zero, it is replaced by scale/100. +

+Thus scale_x=1 and scale_y=1 means symbols are rendered in 1:1 size. +Alternatively scale_x=0 and scale_y=0 and scale=100 means the same. +

+Text has a thickness field; if it is non-zero, +it specifies the stroke (line and arc) thickness of symbols (glyphs); if it +is zero, the thickness value is calculated from scale. +

+By default, the clearance around text is rendered as a round corner +rectangular cutout. If the tight_clearance attribute on the text object +is specified and the value is "yes" or "true" or "1", a more accurate +clearance is calculated that follows the true shape of the text object. +

+The Y coordinates of a text object are mirrored if the ONSOLDER flag is set +(which means the text is mirrored over the X axis). The X coordinates of a +text object are mirrored if the mirror_x attribute is true (which means the +text is mirrored over the Y axis). NOTE: the point of placement (which +corner is placed at the specified X;Y coordinate) depends on mirroring. +

+Bug: copper text can not participate in short circuits, the galvanic connection +checker code skips texts. + +

2.4.5. Subcircuits

+

+A subc (subcircuit) is a group of objects with its own, local layer +information. All layers of a subc are bound layers, that is, the user +is free to choose on which actual board layer it is placed on. +There is no limitation on what layers or objects a subc can contain. +

+The main uses of subc are: +

    +
  • footprint +
  • copy&paste anonymous repetitive section of a circuit +
+ +
2.4.5.1 Subcircuits as footprints
+ +

+A subcircuit may be an instance (copy) of a footprint. The subcircuit is +placed on the board or loaded into a paste buffer (the footprint lives in +the footprint library). + +

+In the footprint form the construct is small and flexible. It describes +all the physical parts, like pins, pads, silk lines. In the same time a +footprint leaves many details blank, e.g. it doesn't specify exact layers, +it doesn't have font and the refdes is random. + +

+When the footprint is loaded, it becomes a subcircuit. The subcircuit inherits all +the physical properties and the blank details are filled in with the data taken +from the current board: the layer binding is done, all parts of the subcircuit +lands on a specific board layer; the refdes is rendered using the font in +the current board. + +

+The footprint -> subcircuit instantiation is also a copy. Once the subcircuit +is created from a footprint, the subcircuit is a self-containing object and +does not have any direct reference to the footprint it was once derived from. +Changes to the original footprint will not affect the subcircuits. + +

+In other words, a footprint is an abstract recipe, part of a +library, while a subcircuit is a land pattern already embedded in a +specific design and describes actual copper and silk. + +

+Currently a subcircuit or footprint can contain any object on any layer +that a board can contain. +

+Commonly used subcircuit attributes: +

+ +
Subcircuit attributes +
subcircuit attribute name description +
refdes unique identifier, e.g. "C42" - pcb-rnd code will use this when present +
value informal value, e.g. "15 pF" +
footprint informal footprint description, e.g. "1206" +
+ +

+When a subcircuit is a footprint, it normally has the refdes attribute set. +Refdes is the name that identifies the part on the netlist. Some objects +of a footprint will have the term attribute to turn those object into +terminals (representing pins or pads). If multiple objects have the same +term attribute value, they are all contributing to the same terminal. +

+When the terminal object is a single padstack, it is called a +light terminal. When the terminal is built using multiple objects, +it is called a heavy terminal. +

+A connection on the netlist is identified as refdes-term, e.g. +U5-3 means "the object(s) whose term attribute is 3 within the subcircuit +whose refdes attribute is 'U5'". +

+If its nonetlist flag is set, the subcircuit is not intended to be +part of the netlist; that is, it will not cause shorts and will not be +removed on a forward annotation (schematics/netlist import). + +

2.4.5.2 Subcircuits as repetitive modules
+

+If the repetitive module is specified as a refdes-named device on +the schematics, it is really just a footprint. Else it is a non-footprint +subcircuit. +

+Compared to subcircuits as footprint, a non-footprint subcircuit will not have +a refdes attribute and will not have terminals. It will also have the +nonetlist flag set. + +

2.4.5.3 Subcircuit aux layer
+

+A subcircuit needs to have an aux layer. The name of this layer +is subc-aux, with type VIRTUAL and MISC, and is on top, bottom or intern. +It hosts three objects placed when the subc was first created: +

    +
  • a zero length line at the origin of the subc, with attribute subc-role=origin +
  • an 1mm long horizontal line in the positive x direction from the origin, with attribute subc-role=x +
  • an 1mm long vertical line in the positive y direction from the origin, with attribute subc-role=y +
+

+These objects specify the neutral state of the subcircuit. If the subcircuit +goes through any transformation (rotation, translation/move, mirroring, etc.), +these objects are also transformed (just like any other object in the subc). +Looking at the current state of these objects and the location flag of the +aux layer, the code can work out the net result of all transformations the +subc suffered since creation. + +

2.4.6. Pad stacks

+

+A pad stack is a generic pin/pad/via object that may contain any combination +of: +

    +
  • a hole (plated or unplated, thru-hole or blind/buried) +
  • a pad shape that can be different on each layer group type +
  • thermal relief info on a per layer basis +
+

+Pad stacks are flexible enough to cover the majority of the simple pin/pad/via +cases. In a subcircuit, marked as a terminal, a pad stack is called a +light terminal. This concept exist in parallel to the heavy terminal +concept: a heavy terminal consists of multiple objects (e.g. polygons, lines, +arcs, pad stacks), all tagged to the same terminal. When the pad stack model +is not capable to describe a complicated pin or pad, the user should chose the +heavy terminal model. A typical example is the center pad of a QFN footprint +with vias for heat transfer and a specific pattern of paste. The strength +of a pad stack is it's relative simplicity and that all objects on the vertical +stack are bundled together; the strength of the heavy model is its flexibility: +anything that can be drawn on board can be turned into a heavy terminal. +

+The optional hole of the pad stack is useful if the pad stack is to be used +as a mounting hole, via or pin. The span of the hole is described by two +integers: how far the hole starts and ends from the top or bottom copper +layer group, counted in copper layer groups. +

+A simple all-way-thru hole's span is 0;0, which means it starts at the +top copper group and ends on the bottom copper group. Or precisely, +"starts 0 groups down from top copper group and spans until 0 groups up +from the bottom group". That is, when hol span values are positive, +the top of the hole is counted from the top copper group down and the +bottom of the hole is counted from the bottom group up. If a span value +is negative, it is counted from the other side, e.g. a 0;-3 means: +"hole top is 0 groups down from top copper group, hole bottom is 3 groups +down from the top copper group". Or in other words, the topmost four copper +layer groups are connected by the via. +

+The plating of the hole is a boolean and is independent of any +other parameter. +

+For each layer group type, the user may specify zero or one pad shape. + +
Pad stack layer group types +
name remarks +
top silk   +
top paste   +
top mask the first negative layer is used +
top copper   +
intern copper the same pad will be used on all internal copper groups +
bottom copper   +
bottom mask the first negative layer is used +
bottom paste   +
bottom silk   +
+

+ +
Pad shapes +
name description +
fillcircle x;y offset of the center, diameter +
line round or square cap, from x1;y1 to x2;y2 with the specified thickness +
simple-polygon a simple polygon has a single outer contour and no holes +
hshadow n/a +
+

+Pad shape hshadow is a special construct: when drawing a clearance around +the shape, it pretends to be a copy of the hole or slot shape, but it never +has any visible (positive) effect on the target layer. Typical use is inner +layer clearance around a via that should not have a copper ring on that layer. +

+The pad stack has an origin, a 0;0 point where it is grabbed. If the pad stack +features a hole, the origin is the center point of the hole. Pad shapes are +all defined in a way that they do not have to be concentric with the hole or +the origin. This allows asymmetric pads. +

+In case of blind/buried vias, the internal copper layer pads are applied +only on layers with hole span. However, this does not apply to top/bottom +shapes, those are always explicit. This means it is possible to use a pad stack +as a pad-pair of an board edge connector, having a copper pad on the top +layer and one on the bottom layer, even without having a (plated) hole in between. +The code will assume connection between the pads only if the pad stack has a +plated hole. +

+If the global clearance is set, it overrides the per layer type +clearance and the padstack will have the same global clearance on all +layer groups on which it has copper objects. +

+ +
Typical pad stack examples +
name description +
rectangular smd pad no hole; square cap line or polygon on top copper, top mask and top paste +
simple pin or via plated hole and the same filled circle on all copper layers; if pin, a slightly bigger circle on the mask layers +
octagon pin or via plated hole and the same simple polygon (octagon shaped) on all copper layers; if pin, a slightly bigger polygon on the mask layers +
'oblong' pin plated hole, a short round cap line segment on the bottom copper and mask layers, filled circle on all other copper layers and on the top mask layer +
blind via plated hole and the same filled circle on internal and top copper layers - nothing on the bottom copper layer +
power jack with slot n/a - can not be done with pad stack as the plated slots for the pins can not be represented as plated round holes - use heavy terminals instead +
+

+Pad stack prototypes (templates) are stored only once per pcb_data_t (only once per +board for vias or per each subcircuit for terminals). The actual pad stacks +placed on the board (or in subcircuit) are called pad stack references. +A pad stack reference has its own x;y coordinate (within the board or +subcircuit), a rotation angle and a mirror flag. This means if a TQFP chip +has 48 pads along 4 sides, in the simplest setup there will be onlt one pad +stack prototype and 48 pad stack references using the same prototype with +different coordinates and rotations. +

+Each padstack reference has an optional global clearance; if it is +non-zero, this value is used as clearance on all layers for this instance. +When it is zero, the prototype's per shape clearance applies, which makes it +possible to have different clearance for internal layers, for example. +

+Each padstack reference has a per board layer list of thermal relief types. +

+A thermal relief property is added to the copper rings of a via when it is +connected to the surrounding polygon of any individual layer. Physical designs +may use thermal reliefs to enable easy hand soldering, or reduce occurrence of +tombstoning in automated production. +

+The following thermal relief options are available: + +
Pad/Pin/Via Thermal Relief +
Thermal Relief Appearance   Thermal Relief Appearance +
no connection unconnected via + solid solid thermal +
round x 90 Thermal relief arc style + round x 45 Thermal relief arc style, 45deg +
crossbar x 90 Thermal relief crossbar style, 90deg + crossbar x 45 Thermal relief crossbar style, 45deg +
+ + +

2.4.7. Rat line Objects

+

+A rat line represents a logical connection that is not yet realized in copper. +It requires a loaded netlist for generation, and relies on calculations for any +existing copper layers that connect terminals on the pcb-rnd board. Rat +connections are straight line connections between the terminals of any two +drawing primitives that aren't yet connected + +

2.4.8 Gfx objects

+

+A gfx object is a layer object that hosts a rectangular custom graphics - +typically pixel graphics. The raw graphics is rectangular ans has its own +size (width and height), which is scaled to the rectangular size of the gfx +object, the rotated and/or mirrored as requested by the gfx object. +

+Gfx objects are visible only on screen and will be ignored by most export +plugins. The main purpose of the gfx object is GUI enhancement - for example +breadboard support. +

+Gfx attributes intepreted by pcb-rnd: +

+ +
Gfx attributes +
gfx attribute name description +
render_level if value is "under", render the gfx object before (under) other objects on the same layer, else after (above) other objects on the same layer +
+

+ + +

2.4.9 Netlists

+

+A netlist is a list of named logical networks. Each network is a list of +netlist terminals that should be connected. A netlist terminal is a pair +of subcircuit-refdes and pin-number (or pad-number). Thus a typical netlist +looks like the following: +

    +
  • net: GND +
      +
    • U1-2 +
    • U2-7 +
    • U3-7 +
    • C1-1 +
    +
  • net: Vcc +
      +
    • U1-3 +
    • U2-14 +
    • U3-14 +
    • C1-2 +
    +
  • net: strobe +
      +
    • U2-2 +
    • U3-5 +
    +
+

+The netlist assumes subcircuit refdes are unique. If a subcircuit has multiple +instances of the same terminal number, the engine picks one randomly and +assumes there's an invisible, internal connection within the subcircuit. +

+Rat lines can be regenerated from the current netlist for missing connections. +Connections that are realized in copper but not present on the netlist, pcb-rnd +gives a "short circuit" warning. Both happens when the net is "optimized" +(upon user request). +

+The netlist is typically derived from a schematics by external tools +(such as gnetlist). The netlist can be imported (updated) any time. This +process is called "forward annotation". +

+It is also possible to make changes to the netlist from within pcb-rnd: +terminals can be swapped, subcircuit footprint replaced using back annotation +actions. Such actions will keep a list of intended netlist and subcircuit +changes, called the netlist patch. Pcb-rnd will keep these changes even +if a new version of the netlist is imported. It is possible to export the +netlist patch that can be imported in the schematics editor to change the +schematics - this process is called "back annotation". A new forward +annotation from the schematics editor to pcb-rnd will then cancel +the netlist/subcircuit changes as the new netlist import netlist matches +the intended (changed) netlist. + +

2.5. Non-objects

+

+The following objects are commonly used in the industry, but have no +special implementation in pcb-rnd but are created by using the above +objects. + +

Vias

+

+A via is an electrically connected hole that connects copper rings to multiple +layers. In pcb-rnd, a via is always implemented using a +padstack. + +

Holes

+

+A hole is a special case of a padstack: it has +an unplated hole and typically does not have copper pad shapes but should +have mask cutout shape. + +

Test points, test pads

+

+A test point or test pad is a padstack that has +copper shape only on one of the outer copper layer and a mask cutout shape +over that layer. + +

Fiducials

+

+A fiducial mark is a special case of a padstack +very similar to the test point/pad. + +

Targets/marks

+A mark or target (e.g. for layer alignment) is usually realized as a + subcircuit it has more complex graphics that +doesn't fit in a padstack. + +

Using subcircuit instead of raw padstack

+

+Holes, test points/pads and fiducials are often realized within a + subcircuit , especially if they have a refdes +and present on the schematics. However, the only way to implement a hole +is using a padstack, so the resulting subcircuit for holes and test pins +will always have at least one padstack. + +

2.6. Comparison of Physical world and pcb-rnd world terminology

+

+ +
Pcb-rnd Terminology +
Physical board pcb-rnd Description +
Layer Layer Group enables the user to design complex physical constructions +
Copper layer Layer group of type copper   +
Component/Top copper layer Layer group of type copper, location top   +
Solder/bottom copper layer Layer group of type copper, location bottom   +
Substrate, prepreg, core Layer group marked as substrate, hosting no logical layers pcb-rnd does not yet handle properties of physical substrate information +
Contour of the board Boundary layer designed using standard pcb-rnd objects +
Outline routing path Boundary layer designed using standard pcb-rnd objects +
Polygon pour Polygon an object available for design in any layer group +
Plane Polygon see above +
Mask (solder mask) Layer group with implicit and potential explicit content design layers available: automatic, additive, subtractive +
Silk Layer group with implicit and potential explicit content design layers available: automatic, additive, subtractive +
Paste (paste stencil) Layer group with implicit and potential explicit content design layers available: automatic, additive, subtractive +
  Rats assistive layer automatically generated with netlist and copper layer group connection data +
Via Padstack a vertical construction that features a plated hole and copper pads around the hole +
Pin Padstack a special via that is going to host a pin of a through-hole component soldered on the board +
Pad Padstack a copper feature that is going to host a lead of a surface mount component +
Hole, mounting hole Padstack special case of vias, with no plating or copper pads +
Fiducial mark, test pad Padstack special case of pad +
Element, module, part (on board) Subcircuit a placed instance of a library footprint +
Footprint, land pattern Footprint reusable patterns stored in the footprint library +
+ Index: tags/2.3.0/doc/user/02_model/obj_arc.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/02_model/obj_arc.png =================================================================== --- tags/2.3.0/doc/user/02_model/obj_arc.png (nonexistent) +++ tags/2.3.0/doc/user/02_model/obj_arc.png (revision 33253) Property changes on: tags/2.3.0/doc/user/02_model/obj_arc.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/02_model/obj_line.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/02_model/obj_line.png =================================================================== --- tags/2.3.0/doc/user/02_model/obj_line.png (nonexistent) +++ tags/2.3.0/doc/user/02_model/obj_line.png (revision 33253) Property changes on: tags/2.3.0/doc/user/02_model/obj_line.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/02_model/objects_basic.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/02_model/objects_basic.png =================================================================== --- tags/2.3.0/doc/user/02_model/objects_basic.png (nonexistent) +++ tags/2.3.0/doc/user/02_model/objects_basic.png (revision 33253) Property changes on: tags/2.3.0/doc/user/02_model/objects_basic.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/02_model/objects_complex.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/02_model/objects_complex.png =================================================================== --- tags/2.3.0/doc/user/02_model/objects_complex.png (nonexistent) +++ tags/2.3.0/doc/user/02_model/objects_complex.png (revision 33253) Property changes on: tags/2.3.0/doc/user/02_model/objects_complex.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/02_model/src/Makefile =================================================================== --- tags/2.3.0/doc/user/02_model/src/Makefile (nonexistent) +++ tags/2.3.0/doc/user/02_model/src/Makefile (revision 33253) @@ -0,0 +1,68 @@ +PCBRND=pcb-rnd +CLEANFILES= ../*.png + +all: ../objects_basic.png ../objects_complex.png ../obj_line.png \ + ../obj_arc.png ../via_therm_noconn.png ../via_therm_solid.png \ + ../via_therm_round_x90.png ../via_therm_round_x45.png \ + ../via_therm_sharp_x90.png ../via_therm_sharp_x45.png + +../objects_basic.png: objects_basic.lht + $(PCBRND) -x png --dpi 450 objects_basic.lht + mv objects_basic.png ../objects_basic.png + +../objects_complex.png: objects_complex.lht + $(PCBRND) -x png --dpi 450 objects_complex.lht + mv objects_complex.png ../objects_complex.png + +../obj_line.png: obj_line.lht + $(PCBRND) -x png --dpi 450 obj_line.lht + mv obj_line.png ../obj_line.png + +../obj_arc.png: obj_arc.lht + $(PCBRND) -x png --dpi 450 obj_arc.lht + mv obj_arc.png ../obj_arc.png + +../via_therm_noconn.png: via_therm_noconn.lht + $(PCBRND) -x png --dpi 450 via_therm_noconn.lht + mv via_therm_noconn.png ../ + +# make thermal style images +../via_therm_solid.png: via_therm_solid.lht + $(PCBRND) -x png --dpi 450 via_therm_solid.lht + mv via_therm_solid.png ../ + +../via_therm_round_x90.png: via_therm_round_x90.lht + $(PCBRND) -x png --dpi 450 via_therm_round_x90.lht + mv via_therm_round_x90.png ../ + +../via_therm_round_x45.png: via_therm_round_x45.lht + $(PCBRND) -x png --dpi 450 via_therm_round_x45.lht + mv via_therm_round_x45.png ../ + +../via_therm_sharp_x90.png: via_therm_sharp_x90.lht + $(PCBRND) -x png --dpi 450 via_therm_sharp_x90.lht + mv via_therm_sharp_x90.png ../ + +../via_therm_sharp_x45.png: via_therm_sharp_x45.lht + $(PCBRND) -x png --dpi 450 via_therm_sharp_x45.lht + mv via_therm_sharp_x45.png ../ + +#make shapes for shape table +via_ring_shape.png: via_ring_shape.lht + $(PCBRND) -x png --dpi 450 via_ring_shape.lht + mv via_ring_shape.png ../ + +via_square_shape.png: via_square_shape.lht + $(PCBRND) -x png --dpi 450 via_square_shape.lht + mv via_square_shape.png ../ + +via_octagon_shape.png: via_octagon_shape.lht + $(PCBRND) -x png --dpi 450 via_octagon_shape.lht + mv via_octagon_shape.png ../ + +via_asym_shape.png: via_asym_shape.lht + $(PCBRND) -x png --dpi 450 via_asym_shape.lht + mv via_asym_shape.png ../ + +clean: $(CLEANRULES) + -rm $(CLEANFILES) Index: tags/2.3.0/doc/user/02_model/src/obj_arc.lht =================================================================== --- tags/2.3.0/doc/user/02_model/src/obj_arc.lht (nonexistent) +++ tags/2.3.0/doc/user/02_model/src/obj_arc.lht (revision 33253) @@ -0,0 +1,384 @@ +ha:pcb-rnd-board-v1 { + + ha:attributes { + {PCB::loader}=geda/pcb - nanometer + {PCB::grid::unit}=mil + {PCB::conf::editor/grid}=25.00 mil + {PCB::conf::editor/draw_grid}=true + {PCB::conf::editor/buffer_number}=0 + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 1.4in + y = 31.75mm + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 0.0 + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:objects { + } + li:layers { + + ha:component { + visible=1 + group=0 + + li:objects { + ha:arc.3 { + x=26.67mm; y=27.305mm; width=400.0mil; height=400.0mil; astart=-90; adelta=90; thickness=75.0mil; clearance=48.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.4 { + li:geometry { + ta:contour { + { 725.0mil; 550.0mil } + { 31.75mm; 550.0mil } + { 31.75mm; 900.0mil } + { 725.0mil; 900.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + } + + ha:solder { + visible=1 + group=1 + } + + ha:comp-GND { + visible=1 + group=0 + } + + ha:comp-power { + visible=1 + group=0 + } + + ha:sold-GND { + visible=1 + group=1 + } + + ha:sold-power { + visible=1 + group=1 + } + + ha:signal3 { + visible=1 + group=2 + } + + ha:outline { + visible=1 + group=3 + } + + ha:silk { + visible=1 + group=1 + } + + ha:silk { + visible=1 + group=0 + + li:objects { + ha:line.9 { + x1=26.67mm; y1=26.67mm; x2=26.67mm; y2=1.1in; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.12 { + x1=26.035mm; y1=27.305mm; x2=27.305mm; y2=27.305mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.15 { + x1=29.21mm; y1=1.175in; x2=26.67mm; y2=27.305mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.18 { + x1=1.35in; y1=1.175in; x2=29.21mm; y2=1.175in; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.21 { + x1=26.67mm; y1=27.305mm; x2=675.0mil; y2=950.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.24 { + x1=625.0mil; y1=750.0mil; x2=800.0mil; y2=925.0mil; thickness=10.0mil; clearance=24.0mil; + ha:flags { + clearline=1 + } + } + ha:line.27 { + x1=625.0mil; y1=750.0mil; x2=350.0mil; y2=750.0mil; thickness=10.0mil; clearance=24.0mil; + ha:flags { + clearline=1 + } + } + ha:line.30 { + x1=875.0mil; y1=825.0mil; x2=650.0mil; y2=600.0mil; thickness=10.0mil; clearance=24.0mil; + ha:flags { + clearline=1 + } + } + ha:line.33 { + x1=650.0mil; y1=600.0mil; x2=325.0mil; y2=600.0mil; thickness=10.0mil; clearance=24.0mil; + ha:flags { + clearline=1 + } + } + ha:line.36 { + x1=675.0mil; y1=27.305mm; x2=0.0; y2=27.305mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.39 { + x1=26.67mm; y1=700.0mil; x2=26.67mm; y2=25.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.42 { + x1=150.0mil; y1=27.305mm; x2=150.0mil; y2=1.225in; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.45 { + x1=650.0mil; y1=26.67mm; x2=650.0mil; y2=1.1in; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.48 { + x1=26.035mm; y1=675.0mil; x2=27.305mm; y2=675.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.51 { + x=26.67mm; y=27.305mm; width=1000.0mil; height=1000.0mil; astart=-90; adelta=90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.58 { + li:geometry { + ta:contour { + { 17.594013mm; 20.769012mm } + { 657.3223622mil; 18.972961mm } + { 15.797962mm; 19.870987mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.62 { + li:geometry { + ta:contour { + { 18.600987mm; 21.775988mm } + { 19.499012mm; 23.572039mm } + { 20.397038mm; 22.674013mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.66 { + li:geometry { + ta:contour { + { 19.753013mm; 18.483012mm } + { 742.3223622mil; 16.686961mm } + { 17.956962mm; 17.584987mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.70 { + li:geometry { + ta:contour { + { 19.870987mm; 18.600988mm } + { 20.769012mm; 20.397039mm } + { 21.667038mm; 19.499013mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.74 { + li:geometry { + ta:contour { + { 690.0mil; 955.0mil } + { 19.109758mm; 25.491476mm } + { 19.533695mm; 24.29432mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.78 { + li:geometry { + ta:contour { + { 3.809999mm; 27.178001mm } + { 3.174999mm; 1.145in } + { 4.444999mm; 1.145in } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.82 { + li:geometry { + ta:contour { + { 26.796999mm; 1.904999mm } + { 980.0mil; 1.269999mm } + { 980.0mil; 2.539999mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.86 { + li:geometry { + ta:contour { + { 1.270001mm; 27.431999mm } + { 1.905001mm; 25.527mm } + { 0.635001mm; 25.527mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:text.52 { + string=center; x=1.175in; y=1.1in; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.53 { + string=width; x=375.0mil; y=675.0mil; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.54 { + string=R; x=850.0mil; y=950.0mil; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.55 { + string=clearance; x=350.0mil; y=525.0mil; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.56 { + string=delta angle; x=625.0mil; y=0.0; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.57 { + string=start angle; x=175.0mil; y=29.21mm; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + } + } + } + } + + +ha:netlists { + + li:input { + } +} +} Index: tags/2.3.0/doc/user/02_model/src/obj_line.lht =================================================================== --- tags/2.3.0/doc/user/02_model/src/obj_line.lht (nonexistent) +++ tags/2.3.0/doc/user/02_model/src/obj_line.lht (revision 33253) @@ -0,0 +1,302 @@ +ha:pcb-rnd-board-v1 { + + ha:attributes { + {PCB::loader}=geda/pcb - nanometer + {PCB::grid::unit}=mil + {PCB::conf::editor/grid}=25.00 mil + {PCB::conf::editor/draw_grid}=true + {PCB::conf::editor/buffer_number}=0 + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 30.48mm + y = 850.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 25.0mil + y = 275.0mil + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:objects { + } + li:layers { + + ha:component { + visible=1 + group=0 + + li:objects { + ha:line.5 { + x1=475.0mil; y1=675.0mil; x2=800.0mil; y2=350.0mil; thickness=110.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.8 { + li:geometry { + ta:contour { + { 600.0mil; 175.0mil } + { 1.125in; 175.0mil } + { 1.125in; 525.0mil } + { 600.0mil; 525.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + } + + ha:solder { + visible=1 + group=1 + } + + ha:comp-GND { + visible=1 + group=0 + } + + ha:comp-power { + visible=1 + group=0 + } + + ha:sold-GND { + visible=1 + group=1 + } + + ha:sold-power { + visible=1 + group=1 + } + + ha:signal3 { + visible=1 + group=2 + } + + ha:outline { + visible=1 + group=3 + } + + ha:silk { + visible=1 + group=1 + } + + ha:silk { + visible=1 + group=0 + + li:objects { + ha:line.13 { + x1=525.0mil; y1=425.0mil; x2=750.0mil; y2=650.0mil; thickness=10.0mil; clearance=24.0mil; + ha:flags { + clearline=1 + } + } + ha:line.16 { + x1=525.0mil; y1=425.0mil; x2=250.0mil; y2=425.0mil; thickness=10.0mil; clearance=24.0mil; + ha:flags { + clearline=1 + } + } + ha:line.19 { + x1=575.0mil; y1=225.0mil; x2=250.0mil; y2=225.0mil; thickness=10.0mil; clearance=24.0mil; + ha:flags { + clearline=1 + } + } + ha:line.22 { + x1=800.0mil; y1=450.0mil; x2=575.0mil; y2=225.0mil; thickness=10.0mil; clearance=24.0mil; + ha:flags { + clearline=1 + } + } + ha:line.25 { + x1=475.0mil; y1=650.0mil; x2=475.0mil; y2=700.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.28 { + x1=450.0mil; y1=675.0mil; x2=500.0mil; y2=675.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.31 { + x1=800.0mil; y1=325.0mil; x2=800.0mil; y2=375.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.34 { + x1=775.0mil; y1=350.0mil; x2=825.0mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.37 { + x1=475.0mil; y1=675.0mil; x2=375.0mil; y2=575.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.40 { + x1=375.0mil; y1=575.0mil; x2=25.0mil; y2=575.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.43 { + x1=800.0mil; y1=350.0mil; x2=550.0mil; y2=100.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.46 { + x1=550.0mil; y1=100.0mil; x2=200.0mil; y2=100.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.53 { + li:geometry { + ta:contour { + { 17.965987mm; 9.075988mm } + { 18.864012mm; 10.872039mm } + { 19.762038mm; 9.974013mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.57 { + li:geometry { + ta:contour { + { 16.695987mm; 14.155988mm } + { 17.594012mm; 15.952039mm } + { 18.492038mm; 15.054013mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.61 { + li:geometry { + ta:contour { + { 15.054013mm; 12.514012mm } + { 14.155988mm; 10.717961mm } + { 13.257962mm; 11.615987mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.65 { + li:geometry { + ta:contour { + { 17.848013mm; 8.958012mm } + { 16.949988mm; 281.9669685mil } + { 16.051962mm; 8.059987mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:text.49 { + string=width; x=275.0mil; y=350.0mil; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.50 { + string=clearance; x=275.0mil; y=150.0mil; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.51 { + string=1st endpoint; x=25.0mil; y=500.0mil; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.52 { + string=2nd endpoint; x=200.0mil; y=25.0mil; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + } + } + } + } + + +ha:netlists { + + li:input { + } +} +} Index: tags/2.3.0/doc/user/02_model/src/objects_basic.lht =================================================================== --- tags/2.3.0/doc/user/02_model/src/objects_basic.lht (nonexistent) +++ tags/2.3.0/doc/user/02_model/src/objects_basic.lht (revision 33253) @@ -0,0 +1,847 @@ +ha:pcb-rnd-board-v6 { + + ha:attributes { + {PCB::loader}=geda/pcb - nanometer + {PCB::grid::unit}=mil + {PCB::conf::editor/buffer_number}=0 + {PCB::conf::editor/draw_grid}=true + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + text_scale = 0 + text_thick = 0.0 + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + text_scale = 0 + text_thick = 0.0 + thickness = 20.0mil + hole = 0.999998mm + 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 = 2.075in + y = 500.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=47.24mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=137.8mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=137.8mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=137.8mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.1 { + hdia=47.24mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + -68.9mil + -68.9mil + 68.9mil + -68.9mil + 68.9mil + 68.9mil + -68.9mil + 68.9mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + -68.9mil + -68.9mil + 68.9mil + -68.9mil + 68.9mil + 68.9mil + -68.9mil + 68.9mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + -68.9mil + -68.9mil + 68.9mil + -68.9mil + 68.9mil + 68.9mil + -68.9mil + 68.9mil + } + } + } + } + + ha:ps_proto_v6.2 { + hdia=47.24mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 68.9mil + -0.724899mm + 0.724899mm + -68.9mil + -0.724899mm + -68.9mil + -68.9mil + -0.724899mm + -68.9mil + 0.724899mm + -0.724899mm + 68.9mil + 0.724899mm + 68.9mil + 68.9mil + 0.724899mm + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + 68.9mil + -0.724899mm + 0.724899mm + -68.9mil + -0.724899mm + -68.9mil + -68.9mil + -0.724899mm + -68.9mil + 0.724899mm + -0.724899mm + 68.9mil + 0.724899mm + 68.9mil + 68.9mil + 0.724899mm + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + 68.9mil + -0.724899mm + 0.724899mm + -68.9mil + -0.724899mm + -68.9mil + -68.9mil + -0.724899mm + -68.9mil + 0.724899mm + -0.724899mm + 68.9mil + 0.724899mm + 68.9mil + 68.9mil + 0.724899mm + } + } + } + } + + ha:ps_proto_v6.3 { + hdia=47.24mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 137.8mil + -0.724899mm + 1.449798mm + -68.9mil + -0.724899mm + -68.9mil + -68.9mil + -0.724899mm + -68.9mil + 0.724899mm + -0.724899mm + 68.9mil + 1.449798mm + 68.9mil + 137.8mil + 0.724899mm + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + 137.8mil + -0.724899mm + 1.449798mm + -68.9mil + -0.724899mm + -68.9mil + -68.9mil + -0.724899mm + -68.9mil + 0.724899mm + -0.724899mm + 68.9mil + 1.449798mm + 68.9mil + 137.8mil + 0.724899mm + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + 137.8mil + -0.724899mm + 1.449798mm + -68.9mil + -0.724899mm + -68.9mil + -68.9mil + -0.724899mm + -68.9mil + 0.724899mm + -0.724899mm + 68.9mil + 1.449798mm + 68.9mil + 137.8mil + 0.724899mm + } + } + } + } + + ha:ps_proto_v6.4 { + hdia=47.24mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 68.9mil + -1.449798mm + 0.724899mm + -137.8mil + -0.724899mm + -137.8mil + -68.9mil + -1.449798mm + -68.9mil + 0.724899mm + -0.724899mm + 68.9mil + 0.724899mm + 68.9mil + 68.9mil + 0.724899mm + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + li:ps_poly { + 68.9mil + -1.449798mm + 0.724899mm + -137.8mil + -0.724899mm + -137.8mil + -68.9mil + -1.449798mm + -68.9mil + 0.724899mm + -0.724899mm + 68.9mil + 0.724899mm + 68.9mil + 68.9mil + 0.724899mm + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + li:ps_poly { + 68.9mil + -1.449798mm + 0.724899mm + -137.8mil + -0.724899mm + -137.8mil + -68.9mil + -1.449798mm + -68.9mil + 0.724899mm + -0.724899mm + 68.9mil + 0.724899mm + 68.9mil + 68.9mil + 0.724899mm + } + } + } + } + + ha:ps_proto_v6.5 { + hdia=0.0; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + li:ps_poly { + 0.0 + -25.0mil + 25.0mil + -25.0mil + 25.0mil + 25.0mil + 0.0 + 25.0mil + } + } + } + } + + ha:ps_proto_v6.6 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + li:ps_poly { + -12.5mil + -25.0mil + 12.5mil + -25.0mil + 12.5mil + 25.0mil + -12.5mil + 25.0mil + } + } + } + } + + ha:ps_proto_v6.7 { + hdia=0.0; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=-25.0mil; y1=0.0; x2=50.0mil; y2=0.0; thickness=80.0mil; square=0; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=50.0mil + } + + ha:ps_shape_v4 { + ha:ps_line { x1=-25.0mil; y1=0.0; x2=50.0mil; y2=0.0; thickness=20.0mil; square=0; } + ha:combining { auto=1; } + ha:layer_mask { + mech = 1 + } + clearance=40.0mil + } + } + } + } + + li:objects { + ha:padstack_ref.48 { + proto=0; x=1.6in; y=125.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.49 { + proto=1; x=1.6in; y=350.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.50 { + proto=2; x=45.085mm; y=350.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.51 { + proto=3; x=45.085mm; y=125.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.88 { + proto=6; x=1.975in; y=200.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + ha:padstack_ref.107 { + proto=7; x=48.895mm; y=350.0mil; rot=90.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + } + } + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:line.16 { + x1=575.0mil; y1=75.0mil; x2=825.0mil; y2=75.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.19 { + x1=825.0mil; y1=75.0mil; x2=925.0mil; y2=175.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.22 { + x1=925.0mil; y1=175.0mil; x2=925.0mil; y2=400.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.25 { + x=425.0mil; y=425.0mil; width=350.0mil; height=350.0mil; astart=0.000000; adelta=-90.000000; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.42 { + li:geometry { + ta:contour { + { 26.67mm; 50.0mil } + { 31.75mm; 50.0mil } + { 1.375in; 175.0mil } + { 1.375in; 425.0mil } + { 26.67mm; 425.0mil } + } + ta:hole { + { 29.21mm; 225.0mil } + { 29.21mm; 300.0mil } + { 31.75mm; 300.0mil } + { 31.75mm; 175.0mil } + { 1.175in; 175.0mil } + { 29.21mm; 200.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#8b2323} + } + + ha:solder { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + color = {#104e8b} + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + + li:objects { + } + color = {#cd3700} + } + + ha:sold-GND { + lid=4 + group=10 + ha:combining { } + + li:objects { + } + color = {#548b54} + } + + ha:sold-power { + lid=5 + group=10 + ha:combining { } + + li:objects { + } + color = {#8b7355} + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + + li:objects { + } + color = {#00868b} + } + + ha:outline { + lid=7 + group=7 + ha:combining { auto=1; } + + li:objects { + } + color = {#228b22} + } + + ha:silk { + lid=8 + group=12 + ha:combining { auto=1; } + + li:objects { + } + color = {#000000} + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + + li:objects { + ha:text.44 { + string=Arc; x=275.0mil; y=425.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.45 { + string=Line; x=700.0mil; y=425.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.46 { + string=Polygon; x=1.125in; y=425.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.47 { + string=Padstack; x=1.65in; y=425.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#000000} + } + + ha:mech { + lid=10 + group=9 + ha:combining { auto=1; } + + li:objects { + } + color = {#104e8b} + } + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top_silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + ha:2 { + name = top_mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; 3; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:7 { + name = global_outline + ha:type { boundary=1; } + li:layers { 7; } + purpose = uroute + } + ha:8 { + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:9 { + name = global-mech + ha:type { mech=1; } + li:layers { 10; } + purpose = proute + } + ha:10 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:11 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { } + } + ha:12 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:13 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.0mil + min_drill = 15.0mil + text_font_id = 0 + text_scale = 100 + via_thickness = 86.61 mil + via_drilling_hole = 39.37 mil + min_slk = 7.0mil + text_thickness = 0 + line_thickness = 20.00 mil + shrink = 9.0mil + poly_isle_area = 199999999.999200 + min_wid = 10.0mil + bloat = 12.0mil + clearance = 20.00 mil + } + ha:editor { + grid_unit = mil + grids_idx = 4 + grid = 25.00 mil + } + } + } +} Index: tags/2.3.0/doc/user/02_model/src/objects_complex.lht =================================================================== --- tags/2.3.0/doc/user/02_model/src/objects_complex.lht (nonexistent) +++ tags/2.3.0/doc/user/02_model/src/objects_complex.lht (revision 33253) @@ -0,0 +1,182 @@ +ha:pcb-rnd-board-v1 { + + ha:attributes { + {PCB::loader}=geda/pcb - nanometer + {PCB::grid::unit}=mil + {PCB::conf::editor/buffer_number}=0 + {PCB::conf::editor/draw_grid}=true + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 850.0mil + y = 500.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 225.0mil + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:objects { + ha:element.81 { + x=600.0mil; y=250.0mil; + li:objects { + ha:text.78 { + string=Standard SMT resistor, capacitor etc; x=568.5mil; y=143.5mil; scale=100; direction=0; role=desc; + } + ha:text.79 { + string=R1; x=568.5mil; y=143.5mil; scale=100; direction=0; role=name; + } + ha:text.80 { + string=1206; x=568.5mil; y=143.5mil; scale=100; direction=0; role=value; + } + ha:line.82 { + x1=-599.948um; y1=-37.4mil; x2=23.62mil; y2=-37.4mil; thickness=8.0mil; clearance=0.0; + } + ha:line.83 { + x1=-599.948um; y1=0.94996mm; x2=23.62mil; y2=0.94996mm; thickness=8.0mil; clearance=0.0; + } + ha:pad.84 { + name=1; number=1; x1=-59.05mil; y1=-299.974um; x2=-59.05mil; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + ha:pad.85 { + name=2; number=2; x1=1.49987mm; y1=-299.974um; x2=1.49987mm; y2=11.81mil; mask=1.452372mm; thickness=1.299972mm; clearance=20.0mil; + ha:flags { + square=1 + } + } + } + } + } + li:layers { + + ha:component { + visible=1 + group=0 + + li:objects { + ha:text.75 { + string=Hello; x=25.0mil; y=150.0mil; scale=245; direction=0; + ha:flags { + clearline=1 + } + } + } + } + + ha:solder { + visible=1 + group=1 + } + + ha:comp-GND { + visible=1 + group=0 + } + + ha:comp-power { + visible=1 + group=0 + } + + ha:sold-GND { + visible=1 + group=1 + } + + ha:sold-power { + visible=1 + group=1 + } + + ha:signal3 { + visible=1 + group=2 + } + + ha:outline { + visible=1 + group=3 + } + + ha:silk { + visible=1 + group=1 + } + + ha:silk { + visible=1 + group=0 + + li:objects { + ha:text.76 { + string=Text; x=100.0mil; y=425.0mil; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.77 { + string=Element, Pad; x=425.0mil; y=425.0mil; scale=100; direction=0; + ha:flags { + clearline=1 + } + } + } + } + } + } + +ha:netlists { + + li:input { + } +} +} Index: tags/2.3.0/doc/user/02_model/src/via_therm_noconn.lht =================================================================== --- tags/2.3.0/doc/user/02_model/src/via_therm_noconn.lht (nonexistent) +++ tags/2.3.0/doc/user/02_model/src/via_therm_noconn.lht (revision 33253) @@ -0,0 +1,267 @@ +ha:pcb-rnd-board-v2 { + + ha:attributes { + {PCB::grid::unit}=mil + {PCB::conf::editor/draw_grid}=true + {PCB::conf::editor/grid}=181.00 um + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 300.0mil + y = 300.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 225.0mil + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 10.0mil + offs_x = 0.245mm + offs_y = 0.064mm + } + } + + ha:data { + + li:objects { + ha:via.107 { + x=150mil; y=150mil; hole=47.24mil; mask=0.0; thickness=3.11912mm; clearance=50.0mil; + ha:flags { + via=1 + } + } + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:polygon.110 { + li:geometry { + ta:contour { + { 25.0mil; 25.0mil } + { 275.0mil; 25.0mil } + { 275.0mil; 275.0mil } + { 25.0mil; 275.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + } + + ha:solder { + lid=1 + group=8 + ha:combining { } + visible=1 + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + visible=1 + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + visible=1 + } + + ha:sold-GND { + lid=4 + group=8 + ha:combining { } + visible=1 + } + + ha:sold-power { + lid=5 + group=8 + ha:combining { } + visible=1 + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + visible=1 + } + + ha:outline { + lid=7 + group=7 + ha:combining { } + visible=1 + } + + ha:silk { + lid=8 + group=10 + ha:combining { auto=1; } + visible=1 + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:text.114 { + string=no conn.; x=1.994mm; y=5.877mm; scale=70; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + } + } + } + + ha:netlists { + li:input { + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + ha:2 { + name = top mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; 3; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_6 + } + ha:7 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 7; } + } + ha:8 { + name = bottom copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:9 { + name = bottom mask + ha:type { bottom=1; mask=1; } + li:layers { } + } + ha:10 { + name = bottom silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:11 { + name = bottom paste + ha:type { bottom=1; paste=1; } + li:layers { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.00 mil + clearance = 20.00 mil + text_font_id = 1 + text_scale = 5744 + via_thickness = 2000.00 um + via_drilling_hole = 31.50 mil + min_slk = 7.00 mil + max_height = 300.00 mil + line_thickness = 10.00 mil + shrink = 9.00 mil + poly_isle_area = 199999999.999200 + max_width = 300.00 mil + min_wid = 10.00 mil + bloat = 12.00 mil + min_drill = 15.00 mil + } + ha:editor { + grid_unit = mil + buffer_number = 0 + grid = 10.00 mil + } + } + } +} Index: tags/2.3.0/doc/user/02_model/src/via_therm_round_x45.lht =================================================================== --- tags/2.3.0/doc/user/02_model/src/via_therm_round_x45.lht (nonexistent) +++ tags/2.3.0/doc/user/02_model/src/via_therm_round_x45.lht (revision 33253) @@ -0,0 +1,287 @@ +ha:pcb-rnd-board-v2 { + + ha:attributes { + {PCB::conf::editor/grid}=181.00 um + {PCB::conf::editor/draw_grid}=true + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 300.0mil + y = 300.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 225.0mil + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 0.181mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + + li:objects { + ha:via.118 { + x=150mil; y=150mil; hole=47.24mil; mask=0.0; thickness=3.11912mm; clearance=50.0mil; + ha:flags { + ha:thermal { silk=diagonal-round; component=diagonal-round; } + via=1 + } + } + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:polygon.110 { + li:geometry { + ta:contour { + { 25.0mil; 25.0mil } + { 275.0mil; 25.0mil } + { 275.0mil; 275.0mil } + { 25.0mil; 275.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + } + + ha:solder { + lid=1 + group=8 + ha:combining { } + visible=1 + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + visible=1 + + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + visible=1 + } + + ha:sold-GND { + lid=4 + group=8 + ha:combining { } + visible=1 + } + + ha:sold-power { + lid=5 + group=8 + ha:combining { } + visible=1 + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + visible=1 + } + + ha:outline { + lid=7 + group=7 + ha:combining { } + visible=1 + } + + ha:silk { + lid=8 + group=10 + ha:combining { auto=1; } + visible=1 + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:text.126 { + string=Arc Thermal; x=0.873886mm; y=5.34154mm; scale=70; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.131 { + string=45; x=2.896mm; y=7.24mm; scale=5744; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.137 { + string=45; x=3.258mm; y=6.335mm; scale=65; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + } + } + } + + + ha:netlists { + li:input { + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + ha:2 { + name = top mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; 3; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_6 + } + ha:7 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 7; } + } + ha:8 { + name = bottom copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:9 { + name = bottom mask + ha:type { bottom=1; mask=1; } + li:layers { } + } + ha:10 { + name = bottom silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:11 { + name = bottom paste + ha:type { bottom=1; paste=1; } + li:layers { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.00 mil + clearance = 20.00 mil + text_font_id = 0 + text_scale = 100 + via_thickness = 2000.00 um + via_drilling_hole = 31.50 mil + min_slk = 7.00 mil + max_height = 300.00 mil + line_thickness = 10.00 mil + shrink = 9.00 mil + poly_isle_area = 199999999.999200 + max_width = 300.00 mil + min_wid = 10.00 mil + bloat = 12.00 mil + min_drill = 15.00 mil + } + ha:editor { + ha:view { + flip_x = 0 + flip_y = 0 + } + grid_unit = mil + buffer_number = 0 + show_solder_side = 0 + grid = 181.00 um + } + } + } +} Index: tags/2.3.0/doc/user/02_model/src/via_therm_round_x90.lht =================================================================== --- tags/2.3.0/doc/user/02_model/src/via_therm_round_x90.lht (nonexistent) +++ tags/2.3.0/doc/user/02_model/src/via_therm_round_x90.lht (revision 33253) @@ -0,0 +1,275 @@ +ha:pcb-rnd-board-v2 { + + ha:attributes { + {PCB::conf::editor/grid}=181.00 um + {PCB::conf::editor/draw_grid}=true + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 300.0mil + y = 300.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 225.0mil + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 0.181mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + + li:objects { + ha:via.118 { + x=150mil; y=150mil; hole=47.24mil; mask=0.0; thickness=3.11912mm; clearance=50.0mil; + ha:flags { + ha:thermal { component=horver-round; silk=diagonal-round; } + via=1 + } + } + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:polygon.149 { + li:geometry { + ta:contour { + { 25.0mil; 25.0mil } + { 275.0mil; 25.0mil } + { 275.0mil; 275.0mil } + { 25.0mil; 275.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + } + + ha:solder { + lid=1 + group=8 + ha:combining { } + visible=1 + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + visible=1 + + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + visible=1 + } + + ha:sold-GND { + lid=4 + group=8 + ha:combining { } + visible=1 + } + + ha:sold-power { + lid=5 + group=8 + ha:combining { } + visible=1 + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + visible=1 + } + + ha:outline { + lid=7 + group=7 + ha:combining { } + visible=1 + } + + ha:silk { + lid=8 + group=10 + ha:combining { auto=1; } + visible=1 + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:text.144 { + string=Arc Thermal; x=0.692886mm; y=5.70354mm; scale=75; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + } + } + } + + + ha:netlists { + li:input { + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + ha:2 { + name = top mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; 3; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_6 + } + ha:7 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 7; } + } + ha:8 { + name = bottom copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:9 { + name = bottom mask + ha:type { bottom=1; mask=1; } + li:layers { } + } + ha:10 { + name = bottom silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:11 { + name = bottom paste + ha:type { bottom=1; paste=1; } + li:layers { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.00 mil + clearance = 20.00 mil + text_font_id = 1 + text_scale = 5744 + via_thickness = 2000.00 um + via_drilling_hole = 31.50 mil + min_slk = 7.00 mil + max_height = 300.00 mil + line_thickness = 10.00 mil + shrink = 9.00 mil + poly_isle_area = 199999999.999200 + max_width = 300.00 mil + min_wid = 10.00 mil + bloat = 12.00 mil + min_drill = 15.00 mil + } + ha:editor { + ha:view { + flip_x = 0 + flip_y = 0 + } + grid_unit = mil + buffer_number = 0 + show_solder_side = 0 + grid = 181.00 um + } + } + } +} Index: tags/2.3.0/doc/user/02_model/src/via_therm_sharp_x45.lht =================================================================== --- tags/2.3.0/doc/user/02_model/src/via_therm_sharp_x45.lht (nonexistent) +++ tags/2.3.0/doc/user/02_model/src/via_therm_sharp_x45.lht (revision 33253) @@ -0,0 +1,280 @@ +ha:pcb-rnd-board-v2 { + + ha:attributes { + {PCB::conf::editor/grid}=181.00 um + {PCB::conf::editor/draw_grid}=true + {PCB::grid::unit}=mil + {PCB::conf::editor/buffer_number}=0 + {PCB::conf::editor/show_solder_side}=0 + {PCB::loader}=geda/pcb - nanometer + {PCB::conf::editor/view/flip_x}=0 + {PCB::conf::editor/view/flip_y}=0 + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 300.0mil + y = 300.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 225.0mil + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 0.181mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + + li:objects { + ha:via.118 { + x=150mil; y=150mil; hole=47.24mil; mask=0.0; thickness=3.11912mm; clearance=50.0mil; + ha:flags { + ha:thermal { silk=diagonal-round; component=diagonal-sharp; } + via=1 + } + } + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:polygon.130 { + li:geometry { + ta:contour { + { 25.0mil; 25.0mil } + { 275.0mil; 25.0mil } + { 275.0mil; 275.0mil } + { 25.0mil; 275.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + } + + ha:solder { + lid=1 + group=8 + ha:combining { } + visible=1 + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + visible=1 + + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + visible=1 + } + + ha:sold-GND { + lid=4 + group=8 + ha:combining { } + visible=1 + } + + ha:sold-power { + lid=5 + group=8 + ha:combining { } + visible=1 + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + visible=1 + } + + ha:outline { + lid=7 + group=7 + ha:combining { } + visible=1 + } + + ha:silk { + lid=8 + group=10 + ha:combining { auto=1; } + visible=1 + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:text.131 { + string=Sharp, 45; x=1.054886mm; y=5.70354mm; scale=75; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + } + } + } + + + ha:netlists { + li:input { + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + ha:2 { + name = top mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; 3; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_6 + } + ha:7 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 7; } + } + ha:8 { + name = bottom copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:9 { + name = bottom mask + ha:type { bottom=1; mask=1; } + li:layers { } + } + ha:10 { + name = bottom silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:11 { + name = bottom paste + ha:type { bottom=1; paste=1; } + li:layers { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.00 mil + clearance = 20.00 mil + text_font_id = 0 + text_scale = 5744 + via_thickness = 2000.00 um + via_drilling_hole = 31.50 mil + min_slk = 7.00 mil + max_height = 300.00 mil + line_thickness = 10.00 mil + shrink = 9.00 mil + poly_isle_area = 199999999.999200 + max_width = 300.00 mil + min_wid = 10.00 mil + bloat = 12.00 mil + min_drill = 15.00 mil + } + ha:editor { + ha:view { + flip_x = 0 + flip_y = 0 + } + grid_unit = mil + buffer_number = 0 + show_solder_side = 0 + grid = 181.00 um + } + } + } +} Index: tags/2.3.0/doc/user/02_model/src/via_therm_sharp_x90.lht =================================================================== --- tags/2.3.0/doc/user/02_model/src/via_therm_sharp_x90.lht (nonexistent) +++ tags/2.3.0/doc/user/02_model/src/via_therm_sharp_x90.lht (revision 33253) @@ -0,0 +1,275 @@ +ha:pcb-rnd-board-v2 { + + ha:attributes { + {PCB::conf::editor/grid}=181.00 um + {PCB::conf::editor/draw_grid}=true + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 300.0mil + y = 300.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 225.0mil + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 0.181mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + + li:objects { + ha:via.118 { + x=150mil; y=150mil; hole=47.24mil; mask=0.0; thickness=3.11912mm; clearance=50.0mil; + ha:flags { + ha:thermal { silk=diagonal-round; component=horver-sharp; } + via=1 + } + } + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:polygon.136 { + li:geometry { + ta:contour { + { 25.0mil; 25.0mil } + { 275.0mil; 25.0mil } + { 275.0mil; 275.0mil } + { 25.0mil; 275.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + } + + ha:solder { + lid=1 + group=8 + ha:combining { } + visible=1 + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + visible=1 + + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + visible=1 + } + + ha:sold-GND { + lid=4 + group=8 + ha:combining { } + visible=1 + } + + ha:sold-power { + lid=5 + group=8 + ha:combining { } + visible=1 + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + visible=1 + } + + ha:outline { + lid=7 + group=7 + ha:combining { } + visible=1 + } + + ha:silk { + lid=8 + group=10 + ha:combining { auto=1; } + visible=1 + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:text.137 { + string=Sharp; x=2.140886mm; y=5.70354mm; scale=75; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + } + } + } + + + ha:netlists { + li:input { + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + ha:2 { + name = top mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; 3; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_6 + } + ha:7 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 7; } + } + ha:8 { + name = bottom copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:9 { + name = bottom mask + ha:type { bottom=1; mask=1; } + li:layers { } + } + ha:10 { + name = bottom silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:11 { + name = bottom paste + ha:type { bottom=1; paste=1; } + li:layers { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.00 mil + clearance = 20.00 mil + text_font_id = 0 + text_scale = 5744 + via_thickness = 2000.00 um + via_drilling_hole = 31.50 mil + min_slk = 7.00 mil + max_height = 300.00 mil + line_thickness = 10.00 mil + shrink = 9.00 mil + poly_isle_area = 199999999.999200 + max_width = 300.00 mil + min_wid = 10.00 mil + bloat = 12.00 mil + min_drill = 15.00 mil + } + ha:editor { + ha:view { + flip_x = 0 + flip_y = 0 + } + grid_unit = mil + buffer_number = 0 + show_solder_side = 0 + grid = 181.00 um + } + } + } +} Index: tags/2.3.0/doc/user/02_model/src/via_therm_solid.lht =================================================================== --- tags/2.3.0/doc/user/02_model/src/via_therm_solid.lht (nonexistent) +++ tags/2.3.0/doc/user/02_model/src/via_therm_solid.lht (revision 33253) @@ -0,0 +1,269 @@ +ha:pcb-rnd-board-v2 { + + ha:attributes { + {PCB::grid::unit}=mil + {PCB::conf::editor/draw_grid}=true + {PCB::conf::editor/grid}=181.00 um + } + + li:styles { + ha:Signal { + diameter = 1.999996mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999998mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 300.0mil + y = 300.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 225.0mil + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 0.181mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + + li:objects { + ha:via.107 { + x=150mil; y=150mil; hole=47.24mil; mask=0.0; thickness=3.11912mm; clearance=50.0mil; + ha:flags { + via=1 + ha:thermal { + component=solid; } + } + } + } + li:layers { + + ha:component { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:polygon.110 { + li:geometry { + ta:contour { + { 25.0mil; 25.0mil } + { 275.0mil; 25.0mil } + { 275.0mil; 275.0mil } + { 25.0mil; 275.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + } + + ha:solder { + lid=1 + group=8 + ha:combining { } + visible=1 + } + + ha:comp-GND { + lid=2 + group=3 + ha:combining { } + visible=1 + } + + ha:comp-power { + lid=3 + group=3 + ha:combining { } + visible=1 + } + + ha:sold-GND { + lid=4 + group=8 + ha:combining { } + visible=1 + } + + ha:sold-power { + lid=5 + group=8 + ha:combining { } + visible=1 + } + + ha:signal3 { + lid=6 + group=5 + ha:combining { } + visible=1 + } + + ha:outline { + lid=7 + group=7 + ha:combining { } + visible=1 + } + + ha:silk { + lid=8 + group=10 + ha:combining { auto=1; } + visible=1 + } + + ha:silk { + lid=9 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:text.113 { + string=Solid via; x=1.813mm; y=5.442mm; scale=70; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + } + } + } + + ha:netlists { + li:input { + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top silk + ha:type { silk=1; top=1; } + li:layers { 9; } + } + ha:2 { + name = top mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; 3; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 6; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_6 + } + ha:7 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 7; } + } + ha:8 { + name = bottom copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 4; 5; } + } + ha:9 { + name = bottom mask + ha:type { bottom=1; mask=1; } + li:layers { } + } + ha:10 { + name = bottom silk + ha:type { silk=1; bottom=1; } + li:layers { 8; } + } + ha:11 { + name = bottom paste + ha:type { bottom=1; paste=1; } + li:layers { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.00 mil + clearance = 20.00 mil + text_font_id = 0 + text_scale = 5744 + via_thickness = 2000.00 um + via_drilling_hole = 31.50 mil + min_slk = 7.00 mil + max_height = 300.00 mil + line_thickness = 10.00 mil + shrink = 9.00 mil + poly_isle_area = 199999999.999200 + max_width = 300.00 mil + min_wid = 10.00 mil + bloat = 12.00 mil + min_drill = 15.00 mil + } + ha:editor { + grid_unit = mil + buffer_number = 0 + grid = 181.00 um + } + } + } +} Index: tags/2.3.0/doc/user/02_model/via_therm_noconn.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/02_model/via_therm_noconn.png =================================================================== --- tags/2.3.0/doc/user/02_model/via_therm_noconn.png (nonexistent) +++ tags/2.3.0/doc/user/02_model/via_therm_noconn.png (revision 33253) Property changes on: tags/2.3.0/doc/user/02_model/via_therm_noconn.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/02_model/via_therm_round_x45.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/02_model/via_therm_round_x45.png =================================================================== --- tags/2.3.0/doc/user/02_model/via_therm_round_x45.png (nonexistent) +++ tags/2.3.0/doc/user/02_model/via_therm_round_x45.png (revision 33253) Property changes on: tags/2.3.0/doc/user/02_model/via_therm_round_x45.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/02_model/via_therm_round_x90.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/02_model/via_therm_round_x90.png =================================================================== --- tags/2.3.0/doc/user/02_model/via_therm_round_x90.png (nonexistent) +++ tags/2.3.0/doc/user/02_model/via_therm_round_x90.png (revision 33253) Property changes on: tags/2.3.0/doc/user/02_model/via_therm_round_x90.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/02_model/via_therm_sharp_x45.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/02_model/via_therm_sharp_x45.png =================================================================== --- tags/2.3.0/doc/user/02_model/via_therm_sharp_x45.png (nonexistent) +++ tags/2.3.0/doc/user/02_model/via_therm_sharp_x45.png (revision 33253) Property changes on: tags/2.3.0/doc/user/02_model/via_therm_sharp_x45.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/02_model/via_therm_sharp_x90.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/02_model/via_therm_sharp_x90.png =================================================================== --- tags/2.3.0/doc/user/02_model/via_therm_sharp_x90.png (nonexistent) +++ tags/2.3.0/doc/user/02_model/via_therm_sharp_x90.png (revision 33253) Property changes on: tags/2.3.0/doc/user/02_model/via_therm_sharp_x90.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/02_model/via_therm_solid.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/02_model/via_therm_solid.png =================================================================== --- tags/2.3.0/doc/user/02_model/via_therm_solid.png (nonexistent) +++ tags/2.3.0/doc/user/02_model/via_therm_solid.png (revision 33253) Property changes on: tags/2.3.0/doc/user/02_model/via_therm_solid.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/03_data/index.html =================================================================== --- tags/2.3.0/doc/user/03_data/index.html (nonexistent) +++ tags/2.3.0/doc/user/03_data/index.html (revision 33253) @@ -0,0 +1,179 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+ +

3. Where Data Is Stored

+

+Pcb-rnd enables the user to design complex original boards in a standard EDA +flow with netlists and other data inputs that aide in design. pcb-rnd also +acts as a multiuse layout design CAD, opening board designs saved in a variety +of legacy and contemporary software. +

+The user can import a variety of non-layout data sources commonly used in EDA +flow. Schematics from gschem or kicad, netlists, reference images, tinyCAD, +and more are available to the user. + +

3.1. Board

+

+pcb-rnd can edit a single board at a time. To edit multiple boards, open +multiple instances of pcb-rnd. + +

3.2. Paste Buffer

+There are multiple paste buffers available in pcb-rnd. The user can select +one of them to be active - most buffer operations will work with the active +buffer. +

+Buffers are board-independent: they have their own dynamic size and their +own virtual layer stack. These enable buffers to act as a proxy between +different boards with different properties. +

+The following operations can be done with buffers: +

    +
  • clear: the content of the buffer is discarded +
  • copy from layout: copy objects from the layout to the buffer +
  • paste to layout: copy objects from the buffer to the layout +
  • load: load buffer from file (including footprints/subcircuits from the library) +
  • save subcircuit: save elements/subcircuits from buffer to file +
  • build a subcircuit in a buffer, from the objects stored in the buffer +
  • build a padstack in a buffer, from the objects stored in the buffer +
  • break up a subcircuit in a buffer + +
  • rotate +
  • mirror +
+ +

3.3. Footprint Libraries

+

3.3.1. Library handling

+

+A footprint library is a collection of subcircuit files, optionally +equipped with metadata. A footprint library is stored and accessed by +footprint plugins (whose names are conventionally prefixed with fp_). +Where the actual data is stored, how and when it is retrieved depends +on the fp_ plugin. +

+There is a configuration node called rc/library_search_paths which +is a list of footprint library search paths. How each path is interpreted +also depends on the fp_ plugins. +

+Currently pcb-rnd offers the following fp_ plugins: + +
plugin description library_search_paths example +
fp_fs + list and load files from directories on the host file system + ~/my_lib
/usr/lib/company_lib
$(rc.path.share)/pcblib +
fp_board + extract all footprints from an existing board file (given in + any board format pcb-rnd can load) and use these footprints as + a library + board@/home/joe/ee/control/cpu.lht +
fp_wget + download a digested map of a footprint library from a web server, + using wget; make all footprints and metadata available in the + library but do not immediately download footprint files; keep + a local (host file system) cache of footprints accessed. Currently + supports edakrill + and gedasymbols. + wget@edakrill
wget@gedasymbols +
+ +

3.3.2. footprint types

+

+There are two types of footprints: +

    +
  • static (file) footprints; and +
  • parametric (generated) footprints. +
+

+A static footprint is a data file that is loaded and parsed by one of +the io_ plugins. pcb-rnd supports multiple file formats: the native lihata +subcircuit format, kicad, eagle, gEDA footprints. +

+A parametric footprint is an external program or script that is executed +by pcb-rnd. The external program shall write a valid footprint file to its +standard output, which is then parsed and used the same way as in case of +static footprints. The external program gets a list of parameters +extracted from the footprint name by pcb-rnd. +

+The basic syntax for a parametric footprint is name(arg1, arg2, ... +argN). Any footprint name that contains a '(' is treated as parametric. +The list of arguments is separated by commas. How arguments are interpreted, +e.g. whether the are positional or named or both, is up to the external +parametric footprint program. +

+The footprint programs are stored in the library tree, and are accessed +using the fp_ plugins. There is no limitation on how the program is implemented +other than the host operating system on which pcb-rnd runs has to be able to +execute it. + + +

3.4. file formats

+

+pcb-rnd operates on an in-memory data tree of the board while it is being edited. +The in-memory data tree can not be dumped in a file without conversion: loading +any file means converting the given file format to the in-memory representation +and saving from memory to any file format is just another conversion. + +

+Lossless save/load round trips for all pcb-rnd features are guaranteed +only when using the latest version of the native formats. The reason is +that the native formats are always upgraded to support all features of +the in-memory data model. It is possible (but not recommended) to use +older versions of the native formats to retrain compatibility with older +versions of pcb-rnd. + +

+The native file formats of pcb-rnd are: +

    +
  • lihata board for PCBs +
  • lihata subcircuit for footprints +
  • lihata based pcb-rnd-conf for configuration data +
+ +

+Non-native file formats are called alien formats. pcb-rnd supports +a large variety of alien formats, but lossless save/load round trips are +not guaranteed when alien formats are used. The code will always do its best +to get good results, but different alien formats have different features, +and most of them can not fully capture all features pcb-rnd offers. + +

+Some alien formats are implemented as io_ plugins and are accessible +as normal board (and footprint) file formats directly from the load/save +infrastructure and footprint library. These formats are trying to capture +all details of the board (or footprint) and are usually close to +producing lossless save/load round trips. + +

+Other alien formats are supported through import_ or export_ plugins. +These formats do not capture enough aspects of a board (or footprint) to +be used as a full load or save, round trip of any sort is impossible. + +

+Typical export example is render outputs: png, ps, gerber are all +export_ plugins: they export one aspect (geometry and sometimes layering) +of the board, but do not export other aspects such as connections, +subcircuits or padstack structure. Lacking that information, the exported +board can never be loaded as a board from png, ps or gerber. + +

+Typical import example is netlist (or schematics): it deals with one aspect +of the project, connection info, and lacks any physical information such +as geometry or layers. It is possible to import one aspect of the design from +a netlist (or schematics), but it is not possible to reconstruct a full board +using only the netlist information. + +

+a map of pcb-rnd format support + +

+For a detailed list of formats, please refer to + the list of supported file formats +in the appendix. + + Index: tags/2.3.0/doc/user/04_invoc/index.html =================================================================== --- tags/2.3.0/doc/user/04_invoc/index.html (nonexistent) +++ tags/2.3.0/doc/user/04_invoc/index.html (revision 33253) @@ -0,0 +1,70 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+ +

4. User Invocation (running pcb-rnd)

+

+pcb-rnd is typically run by invoking it from the shell after installation +

+ +pcb-rnd [options] + +or + +pcb-rnd [options] path + +

+When a path is provided, it is either a board file or a subcircuit which +will be automatically opened for editing. When invoked with a path referring +to a non-existing file, pcb-rnd assumes a new board is to be created and +saved using the file name provided as path. This makes it very easy to +make new boards from the command line. + +

+The list of available options can be acquired by running +

+ +pcb-rnd --help + +

+The most commonly used option is to export a file: + +pcb-rnd -x format [format_options] path + +

+For example a photo-realistic png export pwr.png from the board saved +in pwr.lht can be exported as: + +pcb-rnd --export png --dpi 600 --photo-mode pwr.lht + +

+Listing exporter-specific options is possible running pcb-rnd --help +exporter, e.g.: + +pcb-rnd --help png + +

+Another typical application of options is to select the user interface to +start pcb-rnd with (as pcb-rnd normally comes with multiple UIs compiled in): +

+
+pcb-rnd --gui batch
+pcb-rnd --gui gtk2_gdk
+pcb-rnd --gui gtk2_gl
+pcb-rnd --gui lesstif
+
+
+

+The most notable UI is the batch UI: it reads the standard input for +action commands, executes them and quits on EOF. This allows pcb-rnd to be +run as a UNIX filter (just like a sed, awk or perl), loading, manipulating +and saving boards, without starting a GUI. + + + Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_coordsreadout.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_coordsreadout.png =================================================================== --- tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_coordsreadout.png (nonexistent) +++ tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_coordsreadout.png (revision 33253) Property changes on: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_coordsreadout.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_layerops.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_layerops.png =================================================================== --- tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_layerops.png (nonexistent) +++ tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_layerops.png (revision 33253) Property changes on: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_layerops.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_main.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_main.png =================================================================== --- tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_main.png (nonexistent) +++ tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_main.png (revision 33253) Property changes on: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_main.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_menus.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_menus.png =================================================================== --- tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_menus.png (nonexistent) +++ tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_menus.png (revision 33253) Property changes on: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_menus.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_opsreadout.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_opsreadout.png =================================================================== --- tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_opsreadout.png (nonexistent) +++ tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_opsreadout.png (revision 33253) Property changes on: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_opsreadout.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_routestyle.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_routestyle.png =================================================================== --- tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_routestyle.png (nonexistent) +++ tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_routestyle.png (revision 33253) Property changes on: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_routestyle.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_workops.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_workops.png =================================================================== --- tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_workops.png (nonexistent) +++ tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_workops.png (revision 33253) Property changes on: tags/2.3.0/doc/user/05_ui/01_gtk/base_window_highlight_workops.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/05_ui/01_gtk/index.html =================================================================== --- tags/2.3.0/doc/user/05_ui/01_gtk/index.html (nonexistent) +++ tags/2.3.0/doc/user/05_ui/01_gtk/index.html (revision 33253) @@ -0,0 +1,74 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+ +

5.1 GTK+

+

+pcb-rnd comes with a default graphical hid using GTK+ + +

5.1.1 Using GTK+

+ +

Main Window

+
+Main layout window highlighted +

+The main window in pcb-rnd is a drawing area for your layout. +

Menus

+
+Menus highlighted +

+Menus perform standard file operations commands as well as pcb-rnd layout specific operations +menus: +

    +
  • File - Standard file operations -pcb-rnd import/export, and access to the pcb-rnd preferences +
  • Edit - Undos, buffer ops, selection, edit name and route styles +
  • View - Main view grid control and attribute visibility +
  • Settings - Direct control of main window settings that mostly affect drawing +
  • Select - Selection and edit selection control +
  • Buffer - edit, select, place, transform buffer contents +
  • Connects - connection operations and DRC +
  • Plugins - Manage plugins +
  • Info - Generate reports and get keybindings +
  • Window - open a auxiliary window (dialog) +
+

Operations Toolbar

+
+Operations toolbar highlighted +

+Add to and edit your layout +

Layer Controller

+
+Layer controls highlighted +

+Change layer visibility +

Coordinates Readout

+
+Coordinate readout highlighted +

+Readouts give live info for the user: +Obtain absolute and relative coordinate information +

Route Styles

+
+Route styles area highlighted +

+Access route style dialog and alter existing route style +

Ops Readout

+
+Operations readout highlighted +

+Readouts provide live info for the user +Obtain view grid line drawing style reporter, via size, clearance value, text +size, buffer number +

Key Commands

+pcb-rnd key command standard... +Quick Keys +

Gui Command Line Interface

+Enter the command line interface by typing : + + Index: tags/2.3.0/doc/user/05_ui/03_batch/index.html =================================================================== --- tags/2.3.0/doc/user/05_ui/03_batch/index.html (nonexistent) +++ tags/2.3.0/doc/user/05_ui/03_batch/index.html (revision 33253) @@ -0,0 +1,37 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+ +

5.3 Batch User Interface

+ +

+Pcb-rnd comes with a interpreter which is known as the batch UI. This batch UI +is a default buildin and can be summond at any time when running pcb-rnd (see +code below). Batch mode will compile and run as the default user interface when pcb-rnd is +compiled on systems without any GUI libs installed. + +

+The batch UI is useful for automation, test, and debugging: it is reading +action commands on the standard input and prints results on the standard +output. It does not run a GUI and does not require X. Typical invocation: +

+ +./pcb-rnd --gui batch [path] + + +

+Uses and examples for Batch mode (TODO): +

    +
  • automation +
  • export footprint (with additional plugins) +
  • possible hook processing (ensuring consistent layout state for a dvcs) +
+

+ + Index: tags/2.3.0/doc/user/05_ui/04_common/grid_menu.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/05_ui/04_common/grid_menu.png =================================================================== --- tags/2.3.0/doc/user/05_ui/04_common/grid_menu.png (nonexistent) +++ tags/2.3.0/doc/user/05_ui/04_common/grid_menu.png (revision 33253) Property changes on: tags/2.3.0/doc/user/05_ui/04_common/grid_menu.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/05_ui/04_common/index.html =================================================================== --- tags/2.3.0/doc/user/05_ui/04_common/index.html (nonexistent) +++ tags/2.3.0/doc/user/05_ui/04_common/index.html (revision 33253) @@ -0,0 +1,282 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+ +

5.4. pcb-rnd GUI (common)

+ +

5.4.1. keyboard bindings

+

+The same default menu file is used in all GUI HIDs. It comes with multi-stroke +key bindings, plus only a very few, alternative keys that use modifiers +(mostly ctrl). A multi-stroke key binding requires the user to type in a +sequence of keys, e.g. pressing 't' and 'l' (written as {t l} in this document) +will make pcb-rnd switch to the line tool. There are two major advantages of +using multi-stroke instead of modifiers: +

    +
  • It is often easier to remember them, e.g. the above {t l} can be + memorized as 'tool, line', and it is similar to {t a} for 'tool, arc' + and {t, p} for 'tool, polygon'. The old menu file had these as F2, F3 + and F6. They could be also ctrl+l, ctrl+a, ctrl+p, but then if another + group of functionality required similar letters, like l for list or + p for print, they would need to use a different modifier, e.g. alt+l + and alt+p. At the end there would be a random set of alt, ctrl, shift + combinations that are real hard to remember - this is exactly how + the old (pre-2.0.0) default menu file was. +
  • Since pcb-rnd is a graphical CAD, the mouse is an important user input + device. Most users will have one hand constantly on the mouse. It is much + faster to type a sequence of 2 or rarely 3 plain keys with one hand than + doing the acrobatics for something like ctrl+t or even alt+shif+u. +
+

+Most multi-stroke keys, especially the commonly used ones, use two strokes. +Some rarely used feature will require three. The system can be regarded +as a tree: e.g. in a 3-key sequence, starting from the root +(nothing is pressed) the first key select a chapter, the second +key narrows it down to a subchapter and the third key (leaf) selects the actual +action within the subchapter. The current key tree is +accessible in a large svg drawing or in a script-digestible +flat list. + +

5.4.2 Grid

+

+The grid is an imaginary set of points over the drawing. The crosshair +can snap to the grid, helping the user to keep coordinates of objects +distributed evenly. +

+The only grid geometry pcb-rnd supports is a regular, rectangular grid, that +is: grid points spaced evenly in x and y directions, aligned into horizontal +and vertical rows. The grid also has an optional offset in x and y directions +(which is usually set to 0;0). +

+The grid spacing (distance between grid points) is user configurable. There +are two methods managing the grid. + +

5.4.3. Preset grid

+ +

+The configuration system has a node called editor/grids, which is an ordered +list of preset grid settings. This list should contain the grid settings +preferred by the user, or preferred for the given design. Since this is a +configuration item, the usual conf rules apply (e.g. local grid config +can be saved in the project's config or even in the board file). +

+While drawing, the user can use the {g b} and {g f} hotkeys, or the shorter +[ and ] keys to step the current grid, selecting the previous or next item +from the list. The grid sizes menu will always have the currently selected +item checked. +

+ +

+If the user changes grid properties directly, the new grid setup will most +likely not match any of the presets and the check mark is gone from the menu. +However, pcb-rnd remember the last used preset menu and upon the next +stepping it will move from the last selected preset grid. + +

+The format for the grid configuration is a simple text that lists an +optional grid name, the mandatory grid size, the optional offset and +optionally instructs pcb-rnd to also switch units when the grid is activated. +The full syntax, optional parts written in [] is: +

+[name:]size[@offs][!unit]
+
+

+(The optional name has no functionality other than being displayed, helping +the user to remember the purpose of the grid.) + +

+Examples: +

+ +
grid spec description +
10 mil
anonymous 10 mil grid with no offset +
1.5 mm
anonymous 1.5 mm grid with no offset +
20 mil@1mil;-3mil
20 mil grid with a horizontal offset of +1 mil and vertical offset of -3 mil +
1.5 mm!mm
1.5 mm grid; when activated, switch untis to mm +
placing dips:100 mil
named grid +
leds:1mm@0.5mm;-0.1mm!mm
all the above features, combined +
+ +

5.4.4. Custom grid

+

+The current grid is stored as grid distance and x;y offset. Regardless of +the configured presets, these properties of the current grid can be changed +any time, using the SetValue() action or using the menu. + + +

+ +

5.4.5.1. Menu files, patches and sources

+

+The menu system is loaded and merged from multiple menu files and is dynamic +(can be changed while pcb-rnd is running). There is a base menu file +(file name is partially configured by conf node rc/menu_file), typically +/usr/share/pcb-menu-default.lht. This is file is loaded first, with priority 0. +Then pcb-rnd loads further menu files and menu file patches, for feature plugins, +scripts or user addons at higher priority. +

+All menu files and menu patches are kept in memory. Upon loading, +unloading or modifying any of these in-memory menu images, pcb-rnd will +merge them into the final menu tree, which is what the GUI menu layout is +modified to. +

+The following menu file/patch sources are supported: +

+ +
source usual prio description +
base 0 factory menu file, normally /usr/share/pcb-menu-default.lht +
plugins (static) 100..199 menu files embedded in feature plugins (e.g. to create import menus per format) +
user 300..400 menu files/patches loaded upon user request (conf node: rc/menu_patches) +
action (scripts) 500 using the CreateMenu() action +
plugins (dynamic) 500 e.g. route style or layer menus that are generated from board data +
+ +

+

+Menu files describe the + +menu tree, or a part of the menu tree, in its final +form. The base of the menu system, at priority 0, must be a menu file. When +a menu file is used to patch an existing in-memory menu image (at priority +higher than 0), it can overwrite existing parts of the image or it can +append to existing menus and submenus. But it can not remove submenus or +modify existing submenus without fully overwriting them. The root node +of a menu file is ha:rnd-menu-v1. +

+A +menu patch +file contains an ordered list of instructions on how to +make modifications to the current in-memory menu image. The menu patch +file is a lihata document as follows: +

+ha:rnd-menu-patch-v1 {
+	prio=456
+	li:patch {
+		...instructions (see below)...
+	}
+}
+
+

+The priority value is optional; when specified, it is used to position the +patch in the order of merging. Instructions are executed in the order they +are specified in the file. +

+An instruction can be one of these: +

+

    +
  • a. append_menu: +
    +ha:append_menu {
    + path = /main_menu/File/Reports
    + li:submenu {
    +  ha:foobar  = { a={<key>i;<key>5}; action=wow() }
    + }
    +}
    +
    +

    Appends (or overwrites) items under the menu path specified in path, with +the menu subtree taken from the submenu node. The structure of the submenu +node matches the structure of the plain menu file. The capabilities of this +instruction is similar to a plain menu file's; the reason for using this +variant is that it can be part of a menu patch instruction list. + +

  • b. remove_menu: +
    +ha:remove_menu {
    + path = /main_menu/File/Reports/Generate drill summary
    +}
    +
    +

    +Removes a menu or a whole menu subtree at the specified path, if it exists +(no error or warning is generated when it does not). + +

  • c. overwrite_menu_props: +
    +ha:overwrite_menu_props {
    + path = /main_menu/File/Reports/Report found padstacks
    + ha:props { a={<key>i;ctrl<key>1};}
    +}
    +
    +
    +

    +If the menu path specified in path exists and is a plain submenu item, +its properties specified in props are overwritten. If a property is +not present in the original menu node, it is added. The above example replaces +the hotkey of an existing menu item. If the menu node at the given path is not +found, the instruction is silently ignored. + + +

    5.4.5.3. The merge process

    +

    +Pcb-rnd maintains a list of menu files and menu patches ordered by priority. +Any change to this list triggers a menu merge. In the menu merge a new lihata +document is created in-memory (called the menu image). This document +is initially the copy of the base menu file (priority 0 on the list). Then +each menu file/patch is taken, in ascending order by priority and is applied +to the menu image. Plain menu files simply append/overwrite subtrees, menu +patch files are interpreted and executed instruction by instruction. Each menu +file/patch manipulates the menu image as-is at the moment the file/patch is +applied - that is, modified by previously applied files/patches. +

    +Once the merge process finished, the new menu image is ready. It is compared +with the last menu image and differences are used to update the GUI so that +the menu system will reflect the content of the new menu image by updating +from the previous image with the least number of steps. +Once the GUI menu update process finishes, the old menu image is discarded +as the new menu image is in effect. + +

    5.4.5.4. User interface

    +

    +Menu files and menu patches are created and edited using a text editor. +

    +The list of menu files loaded at the moment can be viewed on the menu +tab of the preferences window or can be printed using the following +action: +

    +MenuPatch(list)
    +
    +

    +Menu files/patches can be loaded and unloaded manually; even those can +be unloaded that are created by feature plugins. Such operation is possible +both from the preferences window and from the MenuPatch action. These modifications +however affect only the in-memory list of files/patches and are not permanent. +

    +To permanently add user supplied menu files/patches, typically to change +hotkeys or create new menu items, the following process should be followed: +

      +
    • 1. create the menu file/patch using a text editor +
    • 2. use the preferences window or a text editor to modify the config node rc/menu_patches +
    • 3. pcb-rnd will automatically update the in-memory menu file/patch list and will redo the menu merging once the config node is modified +
    + +

    5.4.5.5. Menu file layout

    +

    +A menu file has the following main trees: +

    +

      +
    • li:mouse defines the mouse bindings +
    • li:toolbar_static specifies the static part of the toolbar (the "left side"; plugins can still add anything not listed here and those will end up in the dynamic section on the right end in random order) +
    • li:main_menu the menu tree for the main menu of the top window +
    • li:popups named popup menu trees; each child is the root of an independent popup menu that is invoked by name +
    • li:scripts named action scripts that can be symlinked from any of the above trees so long scripts don't scatter single-line menu item descriptions +
    • li:anchored each item is a ha:@anchor { li:submenu { ... } }, where @anchor refers to anchor(s) placed in the tree, by name; the content of the submenu is copied after each instance of the anchor in the main_menu or plugins tree +
    + +

    5.4.5.6. Separators and anchors

    +

    +If a submenu item is a text node with a plain dash ("-") as value, it will +appear as a horizontal separator line in the menu. +

    +If a submenu item is a text node with a text starting with the character @, +it is a named anchor. An anchor is invisible placeholder. Plugins and scripts +and user menu files may refer to these anchors from their anchored +subtree to get submenus placed at specific (named) parts of the menu system +without having to hardwire a path to those parts. The same anchor name may +appear multiple times. Anchors are allowed only under the main_menu and popups +tree. + Index: tags/2.3.0/doc/user/05_ui/04_common/keytree.svg =================================================================== --- tags/2.3.0/doc/user/05_ui/04_common/keytree.svg (nonexistent) +++ tags/2.3.0/doc/user/05_ui/04_common/keytree.svg (revision 33253) @@ -0,0 +1,3516 @@ + + + + + + +keytree + + + +a + +{a} + auto or add + + + +a_b + +{a b} + back annotation + + + +a->a_b + + + + + +a_p + +{a p} + auto-place + + + +a->a_p + + + + + +a_d + +{a d} + auto-disperse + + + +a->a_d + + + + + +a_r + +{a r} + auto-route + + + +a->a_r + + + + + +a_o + +{a o} + optimize (djopt) + + + +a->a_o + + + + + +a_a + +{a a} +Start routing an arc + + + +a->a_a + + + + + +a_l + +{a l} +Start routing a line + + + +a->a_l + + + + + +a_m + +{a m} +Place mark + + + +a->a_m + + + + + +a_v + +{a v} +Place via + + + +a->a_v + + + + + +a_w + +{a w} +Place mark + + + +a->a_w + + + + + +a_x + +{a x} +Design Rule Checker + + + +a->a_x + + + + + +a_b_f + +{a b f} +Replace footprint + + + +a_b->a_b_f + + + + + +a_b_s + +{a b s} +Swap nets on two selected pins + + + +a_b->a_b_s + + + + + +a_b_x + +{a b x} +netlist patch for back annotation + + + +a_b->a_b_x + + + + + +a_p_s + +{a p s} +Auto-place selected subcircuits + + + +a_p->a_p_s + + + + + +a_d_a + +{a d a} +Disperse all subcircuits + + + +a_d->a_d_a + + + + + +a_d_s + +{a d s} +Disperse selected subcircuits + + + +a_d->a_d_s + + + + + +a_r_a + +{a r a} +Auto-route all rats + + + +a_r->a_r_a + + + + + +a_r_r + +{a r r} +Rip up all auto-routed tracks + + + +a_r->a_r_r + + + + + +a_r_s + +{a r s} +Auto-route selected rats + + + +a_r->a_r_s + + + + + +a_r_t + +{a r t} +Rip up selected auto-routed tracks + + + +a_r->a_r_t + + + + + +a_o_a + +{a o a} +Auto-Optimize + + + +a_o->a_o_a + + + + + +a_o_d + +{a o d} +Debumpify + + + +a_o->a_o_d + + + + + +a_o_m + +{a o m} +Miter + + + +a_o->a_o_m + + + + + +a_o_n + +{a o n} +Vianudge + + + +a_o->a_o_n + + + + + +a_o_o + +{a o o} +Ortho pull + + + +a_o->a_o_o + + + + + +a_o_p + +{a o p} +Puller + + + +a_o->a_o_p + + + + + +a_o_s + +{a o s} +Simple optimization + + + +a_o->a_o_s + + + + + +a_o_t + +{a o t} +Viatrim + + + +a_o->a_o_t + + + + + +a_o_u + +{a o u} +Unjaggy + + + +a_o->a_o_u + + + + + +b + +{b} + buffer + + + +b_c + +{b c} + convert & clear + + + +b->b_c + + + + + +b_m + +{b m} + mirror + + + +b->b_m + + + + + +b_r + +{b r} + rotate + + + +b->b_r + + + + + +b_s + +{b s} + subcircuit + + + +b->b_s + + + + + +b_b + +{b b} +Layer bindings... + + + +b->b_b + + + + + +b_f + +b_f + + + +b->b_f + + + + + +b_n + +{b n} +Normalize + + + +b->b_n + + + + + +b_c_c + +{b c c} +Clear buffer + + + +b_c->b_c_c + + + + + +b_c_e + +{b c e} +Convert buffer to extended object... + + + +b_c->b_c_e + + + + + +b_c_p + +{b c p} +Convert buffer to padstack + + + +b_c->b_c_p + + + + + +b_c_s + +{b c s} +Convert buffer to subcircuit + + + +b_c->b_c_s + + + + + +b_m_l + +{b m l} +Mirror buffer (left/right) + + + +b_m->b_m_l + + + + + +b_m_u + +{b m u} +Mirror buffer (up/down) + + + +b_m->b_m_u + + + + + +b_r_a + +{b r a} +Arbitrarily Rotate Buffer + + + +b_r->b_r_a + + + + + +b_r_l + +{b r l} +Rotate buffer 90 deg CCW (left) + + + +b_r->b_r_l + + + + + +b_r_r + +{b r r} +Rotate buffer 90 deg CW (right) + + + +b_r->b_r_r + + + + + +b_s_b + +{b s b} +Break buffer subcircuits to pieces + + + +b_s->b_s_b + + + + + +b_s_l + +b_s_l + + + +b_s->b_s_l + + + + + +b_s_p + +{b s p} +Break buffer padstacks to pieces + + + +b_s->b_s_p + + + + + +b_s_s + +{b s s} +Save buffer subcircuit to file + + + +b_s->b_s_s + + + + + +c + +{c} + connections & rats + + + +c_c + +{c c} +Clear/reset lookup + + + +c->c_c + + + + + +c_d + +{c d} +Del/Remove Connected + + + +c->c_d + + + + + +c_e + +{c e} +Erase rats nest + + + +c->c_e + + + + + +c_f + +{c f} +Find Connections + + + +c->c_f + + + + + +c_r + +{c r} +Optimize rats nest + + + +c->c_r + + + + + +c_s + +{c s} +Select shortest rat + + + +c->c_s + + + + + +e + +{e} + edit + + + +e_m + +{e m} + move + + + +e->e_m + + + + + +e_s + +{e s} + subcircuit or style + + + +e->e_s + + + + + +e_g + +{e g} + geometry + + + +e->e_g + + + + + +e_c + +{e c} +Copy selection to buffer + + + +e->e_c + + + + + +e_d + +{e d} +Remove object + + + +e->e_d + + + + + +e_f + +{e f} +Object flags... + + + +e->e_f + + + + + +e_i + +{e i} +Flip Object + + + +e->e_i + + + + + +e_j + +{e j} +ChangeJoin Object + + + +e->e_j + + + + + +e_l + +{e l} +Move to current layer + + + +e->e_l + + + + + +e_o + +{e o} +Change font... + + + +e->e_o + + + + + +e_p + +{e p} +Object Properties... + + + +e->e_p + + + + + +e_r + +{e r} +Change refdes + + + +e->e_r + + + + + +e_t + +{e t} +Edit text... + + + +e->e_t + + + + + +e_v + +{e v} +Paste buffer to layout + + + +e->e_v + + + + + +e_x + +{e x} +Cut selection to buffer + + + +e->e_x + + + + + +e_y + +{e y} +Cycle object being dragged + + + +e->e_y + + + + + +e_s_b + +{e s b} +Layer bindings... + + + +e_s->e_s_b + + + + + +e_s_e + +{e s e} +External editor... + + + +e_s->e_s_e + + + + + +e_s_r + +{e s r} +Refdes + + + +e_s->e_s_r + + + + + +e_s_s + +{e s s} +Set Same Style + + + +e_s->e_s_s + + + + + +e_s_x + +{e s x} +Convert to extended object... + + + +e_s->e_s_x + + + + + +e_g_c + +{e g c} +Clearance +2 mil + + + +e_g->e_g_c + + + + + +e_g_c-shift + +{e g c-shift} +Clearance -2 mil + + + +e_g->e_g_c-shift + + + + + +e_g_d + +{e g d} +ChangeDrill +5 mil + + + +e_g->e_g_d + + + + + +e_g_d-shift + +{e g d-shift} +ChangeDrill -5 mil + + + +e_g->e_g_d-shift + + + + + +e_g_g + +{e g g} +Edit padstack geometry/prototype + + + +e_g->e_g_g + + + + + +e_g_s + +{e g s} +ChangeSize +5 mil + + + +e_g->e_g_s + + + + + +e_g_s-shift + +{e g s-shift} +ChangeSize -5 mil + + + +e_g->e_g_s-shift + + + + + +e_g_y + +{e g y} +ChangeSizes to Route style + + + +e_g->e_g_y + + + + + +g + +{g} + grid + + + +g_b + +{g b} +Previous grid + + + +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 + + + + + +f + +{f} + file + + + +f_x + +{f x} + export to + + + +f->f_x + + + + + +f_c + +{f c} +Export with CAM job... + + + +f->f_c + + + + + +f_a + +{f a} +Save Layout As... + + + +f->f_a + + + + + +f_e + +{f e} +Export layout... + + + +f->f_e + + + + + +f_l + +{f l} +Load layout... + + + +f->f_l + + + + + +f_n + +{f n} +Start New Layout + + + +f->f_n + + + + + +f_o + +{f o} +Load layout... + + + +f->f_o + + + + + +f_p + +{f p} +Print layout... + + + +f->f_p + + + + + +f_q + +{f q} +Quit Program + + + +f->f_q + + + + + +f_r + +{f r} +Revert + + + +f->f_r + + + + + +f_s + +{f s} +Save Layout + + + +f->f_s + + + + + +f_x_p + +{f x p} +netlist patch for back annotation + + + +f_x->f_x_p + + + + + +i + +{i} + info + + + +i_c + +{i c} + configuration + + + +i->i_c + + + + + +i_a + +{i a} +About... + + + +i->i_a + + + + + +i_d + +{i d} +Generate drill summary + + + +i->i_d + + + + + +i_f + +{i f} +Report found padstacks + + + +i->i_f + + + + + +i_r + +{i r} +Generate object report + + + +i->i_r + + + + + +i_c_c + +{i c c} +Calibrate Printer... + + + +i_c->i_c_c + + + + + +i_c_i + +{i c i} +Data integrity check + + + +i_c->i_c_i + + + + + +i_c_p + +{i c p} +Preferences... + + + +i_c->i_c_p + + + + + +i_c_r + +{i c r} +Re-scan the footprint library + + + +i_c->i_c_r + + + + + +m + +{m} + mode + + + +m_c + +{m c} + cursor/crosshair mode + + + +m->m_c + + + + + +m_d + +{m d} + drawing (render) mode + + + +m->m_d + + + + + +m_f + +{m f} + floater mode + + + +m->m_f + + + + + +m_l + +{m l} + line drawing (routing) settings + + + +m->m_l + + + + + +m_t + +{m t} + text drawing (routing) settings + + + +m->m_t + + + + + +m_p + +{m p} + polygon drawing mode + + + +m->m_p + + + + + +m_r + +{m r} + rubber band mode + + + +m->m_r + + + + + +m_k + +m_k + + + +m->m_k + + + + + +m_o + +m_o + + + +m->m_o + + + + + +m_c_c + +{m c c} +Crosshair shows style clearance + + + +m_c->m_c_c + + + + + +m_c_o + +{m c o} +Orthogonal moves + + + +m_c->m_c_o + + + + + +m_c_p + +{m c p} +Crosshair snaps to padstacks + + + +m_c->m_c_p + + + + + +m_c_s + +{m c s} +Crosshair snaps to off-grid points on lines + + + +m_c->m_c_s + + + + + +m_d_a + +{m d a} +Show autorouter trials + + + +m_d->m_d_a + + + + + +m_d_c + +{m d c} +Check polygons + + + +m_d->m_d_c + + + + + +m_d_d + +{m d d} +poly as-drawn frame annotation + + + +m_d->m_d_d + + + + + +m_d_h + +{m d h} +Highlighting on line, arc points + + + +m_d->m_d_h + + + + + +m_d_o + +{m d o} +Object list popup + + + +m_d->m_d_o + + + + + +m_d_p + +{m d p} +Thin draw poly + + + +m_d->m_d_p + + + + + +m_d_r + +{m d r} +Reset + + + +m_d->m_d_r + + + + + +m_d_t + +{m d t} +Thin draw + + + +m_d->m_d_t + + + + + +m_d_w + +{m d w} +Wireframe draw + + + +m_d->m_d_w + + + + + +m_f_h + +{m f h} +Hide floaters + + + +m_f->m_f_h + + + + + +m_f_l + +{m f l} +Lock floaters + + + +m_f->m_f_l + + + + + +m_f_o + +{m f o} +Only floaters + + + +m_f->m_f_o + + + + + +m_l_+ + +{m l +} +Line Tool size +5 mil + + + +m_l->m_l_+ + + + + + +m_l_- + +{m l -} +Line Tool size -5 mil + + + +m_l->m_l_- + + + + + +m_l_a + +{m l a} +'All-direction' lines + + + +m_l->m_l_a + + + + + +m_l_c + +{m l c} +New lines, arcs clear polygons + + + +m_l->m_l_c + + + + + +m_l_d + +{m l d} +Auto enforce style clearance + + + +m_l->m_l_d + + + + + +m_l_f + +{m l f} +Cycle line clip/refraction + + + +m_l->m_l_f + + + + + +m_l_m + +{m l m} +Automatic trace merging + + + +m_l->m_l_m + + + + + +m_t_+ + +{m t +} +Text Tool scale +10 mil + + + +m_t->m_t_+ + + + + + +m_t_- + +{m t -} +Text Tool scale -10 mil + + + +m_t->m_t_- + + + + + +m_p_c + +{m p c} +New polygons clear polygons + + + +m_p->m_p_c + + + + + +m_p_f + +{m p f} +New polygons are full ones + + + +m_p->m_p_f + + + + + +m_p_i + +{m p i} +Polygon clip inhibit (toggle) + + + +m_p->m_p_i + + + + + +m_r_m + +{m r m} +Rubber band keeps middle line dir + + + +m_r->m_r_m + + + + + +m_r_r + +{m r r} +Rubber band mode + + + +m_r->m_r_r + + + + + +s + +{s} + select + + + +s_a + +{s a} + select all... + + + +s->s_a + + + + + +s_u + +{s u} + unselect all... + + + +s->s_u + + + + + +s_c + +{s c} + convert selected + + + +s->s_c + + + + + +s_b + +s_b + + + +s->s_b + + + + + +s_f + +{s f} +Move selected subcircuits to other side + + + +s->s_f + + + + + +s_i + +{s i} +Invert selection + + + +s->s_i + + + + + +s_l + +{s l} +Move selected objects to current layer + + + +s->s_l + + + + + +s_r + +{s r} +Remove selected objects + + + +s->s_r + + + + + +s_s + +{s s} +Advanced search and select + + + +s->s_s + + + + + +s_a_a + +{s a a} +Select all visible objects + + + +s_a->s_a_a + + + + + +s_a_c + +{s a c} +Select all found objects + + + +s_a->s_a_c + + + + + +s_u_a + +{s u a} +Unselect all objects + + + +s_u->s_u_a + + + + + +s_u_c + +{s u c} +Unselect all found objects + + + +s_u->s_u_c + + + + + +s_c_e + +{s c e} +Convert selection to extended object... + + + +s_c->s_c_e + + + + + +s_c_p + +{s c p} +Convert selection to padstack + + + +s_c->s_c_p + + + + + +s_c_s + +{s c s} +Convert selection to subcircuit + + + +s_c->s_c_s + + + + + +r + +{r} + routing helper + + + +r_r + +{r r} + routing radius + + + +r->r_r + + + + + +r_r_+ + +{r r +} +Route radius +0.5 + + + +r_r->r_r_+ + + + + + +r_r_- + +{r r -} +Route radius -0.5 + + + +r_r->r_r_- + + + + + +r_r_m + +{r r m} +Route radius -0.5 + + + +r_r->r_r_m + + + + + +r_r_p + +{r r p} +Route radius +0.5 + + + +r_r->r_r_p + + + + + +t + +{t} + tool + + + +t_a + +{t a} +Arc + + + +t->t_a + + + + + +t_b + +{t b} +Buffer + + + +t->t_b + + + + + +t_c + +{t c} +Copy + + + +t->t_c + + + + + +t_d + +{t d} +Del/Remove + + + +t->t_d + + + + + +t_e + +{t e} +Thermal + + + +t->t_e + + + + + +t_h + +{t h} +Polygon Hole + + + +t->t_h + + + + + +t_i + +{t i} +Insert Point + + + +t->t_i + + + + + +t_k + +{t k} +Lock + + + +t->t_k + + + + + +t_l + +{t l} +Line + + + +t->t_l + + + + + +t_m + +{t m} +Move + + + +t->t_m + + + + + +t_n + +{t n} +Arrow + + + +t->t_n + + + + + +t_o + +{t o} +Rotate + + + +t->t_o + + + + + +t_p + +{t p} +Polygon + + + +t->t_p + + + + + +t_r + +{t r} +Rectangle + + + +t->t_r + + + + + +t_t + +{t t} +Text + + + +t->t_t + + + + + +t_v + +{t v} +Via + + + +t->t_v + + + + + +u + +{u} + undo + + + +u_c + +{u c} +Clear undo-buffer + + + +u->u_c + + + + + +u_d + +{u d} +Undo dialog (for debugging) + + + +u->u_d + + + + + +u_r + +{u r} +Redo last undone operation + + + +u->u_r + + + + + +u_u + +{u u} +Undo last operation + + + +u->u_u + + + + + +v + +{v} + view + + + +v_s + +{v s} + set view + + + +v->v_s + + + + + +v_c + +{v c} +Center cursor + + + +v->v_c + + + + + +v_f + +{v f} +Zoom Extents + + + +v->v_f + + + + + +v_n + +{v n} +Show padstack numbers in a subc + + + +v->v_n + + + + + +v_r + +v_r + + + +v->v_r + + + + + +v_t + +v_t + + + +v->v_t + + + + + +v_s_c + +{v s c} +user configured + + + +v_s->v_s_c + + + + + +v_s_f + +{v s f} +footprint + + + +v_s->v_s_f + + + + + +v_s_r + +{v s r} +refdes + + + +v_s->v_s_r + + + + + +v_s_s + +{v s s} +refdes+value + + + +v_s->v_s_s + + + + + +v_s_v + +{v s v} +value + + + +v_s->v_s_v + + + + + +w + +{w} + window + + + +w_a + +{w a} +About... + + + +w->w_a + + + + + +w_d + +{w d} +DRC Check + + + +w->w_d + + + + + +w_f + +{w f} +Font selector + + + +w->w_f + + + + + +w_l + +{w l} +Library + + + +w->w_l + + + + + +w_m + +{w m} +Message Log + + + +w->w_m + + + + + +w_n + +{w n} +Netlist + + + +w->w_n + + + + + +w_p + +{w p} +Pinout + + + +w->w_p + + + + + +b_f_l + +{b f l} +Load buffer content from file + + + +b_f->b_f_l + + + + + +b_f_s + +{b f s} +Save buffer content to file + + + +b_f->b_f_s + + + + + +b_s_l_d + +{b s l d} +in multiple footprint files + + + +b_s_l->b_s_l_d + + + + + +b_s_l_f + +{b s l f} +in a single lib file + + + +b_s_l->b_s_l_f + + + + + +j_h + +{j h} +Scroll Left + + + +j + +j + + + +j->j_h + + + + + +j_j + +{j j} +Scroll Down + + + +j->j_j + + + + + +j_k + +{j k} +Scroll Up + + + +j->j_k + + + + + +j_l + +{j l} +Scroll Right + + + +j->j_l + + + + + +k_h + +{k h} +Step Left + + + +k + +k + + + +k->k_h + + + + + +k_j + +{k j} +Step Down + + + +k->k_j + + + + + +k_k + +{k k} +Step Up + + + +k->k_k + + + + + +k_l + +{k l} +Step Right + + + +k->k_l + + + + + +k_r + +{k r} +Click (right) + + + +k->k_r + + + + + +l_h + +{l h} +all layers off + + + +l + +l + + + +l->l_h + + + + + +l_k + +{l k} +Select previous layer + + + +l->l_k + + + + + +l_l + +{l l} +Select next layer + + + +l->l_l + + + + + +l_v + +{l v} +all layers on + + + +l->l_v + + + + + +m_k_s + +{m k s} +Loose subcircuits (no subc lock) + + + +m_k->m_k_s + + + + + +m_o_b + +{m o b} +black current group + + + +m_o->m_o_b + + + + + +m_o_i + +{m o i} +Invisible-color on other groups + + + +m_o->m_o_i + + + + + +n_c_f + +{n c f} +claim net on found + + + +n + +n + + + +n_c + +n_c + + + +n->n_c + + + + + +n_l + +n_l + + + +n->n_l + + + + + +n_c->n_c_f + + + + + +n_c_o + +{n c o} +claim net by object + + + +n_c->n_c_o + + + + + +n_c_s + +{n c s} +claim net on selected + + + +n_c->n_c_s + + + + + +n_l_k + +{n l k} +Visual length, clear + + + +n_l->n_l_k + + + + + +n_l_l + +{n l l} +Netlist dialog, refresh lengths + + + +n_l->n_l_l + + + + + +n_l_o + +{n l o} +Visual length, from object + + + +n_l->n_l_o + + + + + +p_m_p + +{p m p} +Manage plugins... + + + +p + +p + + + +p_m + +p_m + + + +p->p_m + + + + + +p_p + +p_p + + + +p->p_p + + + + + +p_m->p_m_p + + + + + +p_m_s + +{p m s} +Manage scripts... + + + +p_m->p_m_s + + + + + +p_p_c + +{p p c} +Polygon Close + + + +p_p->p_p_c + + + + + +p_p_p + +{p p p} +Polygon PreviousPoint + + + +p_p->p_p_p + + + + + +s_b_p + +{s b p} +Break selection padstack to pieces + + + +s_b->s_b_p + + + + + +s_b_s + +{s b s} +Break selection subcircuits to pieces + + + +s_b->s_b_s + + + + + +v_r_g + +{v r g} +Reset GUI + + + +v_r->v_r_g + + + + + +v_r_v + +{v r v} +Reset View + + + +v_r->v_r_v + + + + + +v_t_c + +{v t c} +user configured + + + +v_t->v_t_c + + + + + +v_t_n + +{v t n} +name + + + +v_t->v_t_n + + + + + +v_t_s + +{v t s} +term+name + + + +v_t->v_t_s + + + + + +v_t_t + +{v t t} +term + + + +v_t->v_t_t + + + + + +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/2.3.0/doc/user/05_ui/04_common/keytree.txt =================================================================== --- tags/2.3.0/doc/user/05_ui/04_common/keytree.txt (nonexistent) +++ tags/2.3.0/doc/user/05_ui/04_common/keytree.txt (revision 33253) @@ -0,0 +1,321 @@ ++ pcb-menu-default.lht Zoom(-1.2) Zoom In 20% +, pcb-menu-default.lht CycleDrag() Cycle object being dragged +- pcb-menu-default.lht Zoom(+1.2) Zoom Out 20% +. pcb-menu-default.lht conf(toggle, editor\057all_direction_lines, design) 'All-direction' lines +0 pcb-menu-default.lht SelectLayer(10) Select Layer 10 +0-alt pcb-menu-default.lht SelectLayer(20) Select Layer 20 +0-alt-ctrl pcb-menu-default.lht ToggleView(20) Toggle Layer 20 +0-ctrl pcb-menu-default.lht ToggleView(10) Toggle Layer 10 +1 pcb-menu-default.lht SelectLayer(1) Select Layer 1 +1-alt pcb-menu-default.lht SelectLayer(11) Select Layer 11 +1-alt-ctrl pcb-menu-default.lht ToggleView(11) Toggle Layer 11 +1-ctrl pcb-menu-default.lht ToggleView(1) Toggle Layer 1 +2 pcb-menu-default.lht SelectLayer(2) Select Layer 2 +2-alt pcb-menu-default.lht SelectLayer(12) Select Layer 12 +2-alt-ctrl pcb-menu-default.lht ToggleView(12) Toggle Layer 12 +2-ctrl pcb-menu-default.lht ToggleView(2) Toggle Layer 2 +3 pcb-menu-default.lht SelectLayer(3) Select Layer 3 +3-alt pcb-menu-default.lht SelectLayer(13) Select Layer 13 +3-alt-ctrl pcb-menu-default.lht ToggleView(13) Toggle Layer 13 +3-ctrl pcb-menu-default.lht ToggleView(3) Toggle Layer 3 +4 pcb-menu-default.lht SelectLayer(4) Select Layer 4 +4-alt pcb-menu-default.lht SelectLayer(14) Select Layer 14 +4-alt-ctrl pcb-menu-default.lht ToggleView(14) Toggle Layer 14 +4-ctrl pcb-menu-default.lht ToggleView(4) Toggle Layer 4 +5 pcb-menu-default.lht SelectLayer(5) Select Layer 5 +5-alt pcb-menu-default.lht SelectLayer(15) Select Layer 15 +5-alt-ctrl pcb-menu-default.lht ToggleView(15) Toggle Layer 15 +5-ctrl pcb-menu-default.lht ToggleView(5) Toggle Layer 5 +6 pcb-menu-default.lht SelectLayer(6) Select Layer 6 +6-alt pcb-menu-default.lht SelectLayer(16) Select Layer 16 +6-alt-ctrl pcb-menu-default.lht ToggleView(16) Toggle Layer 16 +6-ctrl pcb-menu-default.lht ToggleView(6) Toggle Layer 6 +7 pcb-menu-default.lht SelectLayer(7) Select Layer 7 +7-alt pcb-menu-default.lht SelectLayer(17) Select Layer 17 +7-alt-ctrl pcb-menu-default.lht ToggleView(17) Toggle Layer 17 +7-ctrl pcb-menu-default.lht ToggleView(7) Toggle Layer 7 +8 pcb-menu-default.lht SelectLayer(8) Select Layer 8 +8-alt pcb-menu-default.lht SelectLayer(18) Select Layer 18 +8-alt-ctrl pcb-menu-default.lht ToggleView(18) Toggle Layer 18 +8-ctrl pcb-menu-default.lht ToggleView(8) Toggle Layer 8 +9 pcb-menu-default.lht SelectLayer(9) Select Layer 9 +9-alt pcb-menu-default.lht SelectLayer(19) Select Layer 19 +9-alt-ctrl pcb-menu-default.lht ToggleView(19) Toggle Layer 19 +9-ctrl pcb-menu-default.lht ToggleView(9) Toggle Layer 9 +: pcb-menu-default.lht Command() Command Entry +[ pcb-menu-default.lht Grid(down) Previous grid +\ pcb-menu-default.lht fullscreen(toggle) Full screen +\057 pcb-menu-default.lht Display(CycleClip) Cycle line clip\057refraction +] pcb-menu-default.lht Grid(up) Next grid +a;a pcb-menu-default.lht Tool(Save);Tool(arc);Tool(Press) Start routing an arc +a;b;f; pcb-menu-default.lht ReplaceFootprint() Replace footprint +a;b;s; pcb-menu-default.lht net(swap) Swap nets on two selected pins +a;b;x pcb-menu-default.lht SavePatch() netlist patch for back annotation +a;d;a; pcb-menu-default.lht DisperseElements(All) Disperse all subcircuits +a;d;s; pcb-menu-default.lht DisperseElements(Selected) Disperse selected subcircuits +a;l pcb-menu-default.lht Tool(Save);Tool(line);Tool(Press) Start routing a line +a;m pcb-menu-default.lht MarkCrosshair() Place mark +a;o;a; pcb-menu-default.lht djopt(auto) Auto-Optimize +a;o;d; pcb-menu-default.lht djopt(debumpify) Debumpify +a;o;m; pcb-menu-default.lht djopt(miter) Miter +a;o;n; pcb-menu-default.lht djopt(vianudge) Vianudge +a;o;o; pcb-menu-default.lht djopt(orthopull) Ortho pull +a;o;p; pcb-menu-default.lht Puller() Puller +a;o;s; pcb-menu-default.lht djopt(simple) Simple optimization +a;o;t; pcb-menu-default.lht djopt(viatrim) Viatrim +a;o;u; pcb-menu-default.lht djopt(unjaggy) Unjaggy +a;p;s; pcb-menu-default.lht AutoPlaceSelected() Auto-place selected subcircuits +a;r;a; pcb-menu-default.lht AutoRoute(AllRats) Auto-route all rats +a;r;r; pcb-menu-default.lht RipUp(All) Rip up all auto-routed tracks +a;r;s; pcb-menu-default.lht AutoRoute(SelectedRats) Auto-route selected rats +a;r;t; pcb-menu-default.lht RipUp(Selected) Rip up selected auto-routed tracks +a;v pcb-menu-default.lht Tool(Save);Tool(via);Tool(Press);Tool(Restore) Place via +a;w pcb-menu-default.lht MarkCrosshair() Place mark +a;x; pcb-menu-default.lht DRC() Design Rule Checker +b;1; pcb-menu-default.lht PasteBuffer(1) Select Buffer #1 +b;2; pcb-menu-default.lht PasteBuffer(2) Select Buffer #2 +b;3; pcb-menu-default.lht PasteBuffer(3) Select Buffer #3 +b;4; pcb-menu-default.lht PasteBuffer(4) Select Buffer #4 +b;5; pcb-menu-default.lht PasteBuffer(5) Select scratchpad +b;b; pcb-menu-default.lht LayerBinding(buffer) Layer bindings... +b;c;c; pcb-menu-default.lht PasteBuffer(Clear) Clear buffer +b;c;e pcb-menu-default.lht ExtobjConvFrom(buffer, @gui);Tool(buffer) Convert buffer to extended object... +b;c;p pcb-menu-default.lht PadstackConvert(buffer);Tool(buffer) Convert buffer to padstack +b;c;s pcb-menu-default.lht PasteBuffer(ConvertSubc) Convert buffer to subcircuit +b;f;l; pcb-menu-default.lht PasteBuffer(LoadAll) Load buffer content from file +b;f;s; pcb-menu-default.lht PasteBuffer(SaveAll) Save buffer content to file +b;m;l pcb-menu-default.lht Tool(buffer);PasteBuffer(Rotate,1);PasteBuffer(Mirror);PasteBuffer(Rotate,3) Mirror buffer (left\057right) +b;m;u pcb-menu-default.lht Tool(buffer);PasteBuffer(Mirror) Mirror buffer (up\057down) +b;n pcb-menu-default.lht Tool(buffer);PasteBuffer(Rotate,1);PasteBuffer(Normalize) Normalize +b;r;a pcb-menu-default.lht Tool(buffer);FreeRotateBuffer() Arbitrarily Rotate Buffer +b;r;l pcb-menu-default.lht Tool(buffer);PasteBuffer(Rotate,1) Rotate buffer 90 deg CCW (left) +b;r;r pcb-menu-default.lht Tool(buffer);PasteBuffer(Rotate,3) Rotate buffer 90 deg CW (right) +b;s;b pcb-menu-default.lht PasteBuffer(Restore) Break buffer subcircuits to pieces +b;s;l;d pcb-menu-default.lht SaveLib(dir, buffer) in multiple footprint files +b;s;l;f pcb-menu-default.lht SaveLib(file, buffer) in a single lib file +b;s;p pcb-menu-default.lht PadstackBreakup(buffer) Break buffer padstacks to pieces +b;s;s pcb-menu-default.lht Save(PasteBuffer) Save buffer subcircuit to file +c-ctrl; pcb-menu-default.lht GetXY(Click to set the snap point for this buffer);PasteBuffer(Clear);PasteBuffer(AddSelected);Unselect(All);Tool(buffer) Copy selection to buffer +c;c; pcb-menu-default.lht Connection(Reset);Display(Redraw) Clear\057reset lookup +c;d; pcb-menu-default.lht Atomic(Save);Connection(Reset);Atomic(Restore);Unselect(All);Atomic(Restore);Connection(Find);Atomic(Restore);Select(Connection);Atomic(Restore);RemoveSelected();Atomic(Restore);Connection(Reset);Atomic(Restore);Unselect(All);Atomic(Block) Del\057Remove Connected +c;e; pcb-menu-default.lht DeleteRats(AllRats) Erase rats nest +c;f; pcb-menu-default.lht Connection(Reset);Connection(Find) Find Connections +c;r-shift; pcb-menu-default.lht Atomic(Save);DeleteRats(AllRats);Atomic(Restore);AddRats(AllRats, manhattan);Atomic(Close) Optimize rats nest - autorouter +c;r; pcb-menu-default.lht Atomic(Save);DeleteRats(AllRats);Atomic(Restore);AddRats(AllRats);Atomic(Close) Optimize rats nest +c;s; pcb-menu-default.lht AddRats(Close) Select shortest rat +delete pcb-menu-default.lht Tool(Save);Tool(remove);Tool(Press);Tool(Restore) Remove object +down pcb-menu-default.lht Cursor(Warp,0,1,grid) Step Down +down-ctrl pcb-menu-default.lht Scroll(down) Scroll Down +down-shift pcb-menu-default.lht Cursor(Pan,0,50,view) Step +Down +e;c pcb-menu-default.lht GetXY(Click to set the snap point for this buffer);PasteBuffer(Clear);PasteBuffer(AddSelected);Unselect(All);Tool(buffer) Copy selection to buffer +e;d pcb-menu-default.lht Tool(Save);Tool(remove);Tool(Press);Tool(Restore) Remove object +e;f pcb-menu-default.lht FlagEdit() Object flags... +e;g;c pcb-menu-default.lht ChangeClearSize(Object,+2,mil) Clearance +2 mil +e;g;c-shift pcb-menu-default.lht ChangeClearSize(Object,-2,mil) Clearance -2 mil +e;g;d pcb-menu-default.lht ChangeDrillSize(Object,+5,mil) ChangeDrill +5 mil +e;g;d-shift pcb-menu-default.lht ChangeDrillSize(Object,-5,mil) ChangeDrill -5 mil +e;g;g pcb-menu-default.lht padstackedit Edit padstack geometry\057prototype +e;g;s pcb-menu-default.lht ChangeSize(Object,+5,mil) ChangeSize +5 mil +e;g;s-shift pcb-menu-default.lht ChangeSize(Object,-5,mil) ChangeSize -5 mil +e;g;y pcb-menu-default.lht ChangeSizes(Object,style,mil) ChangeSizes to Route style +e;i pcb-menu-default.lht Flip(Object) Flip Object +e;j pcb-menu-default.lht ChangeJoin(Object) ChangeJoin Object +e;l pcb-menu-default.lht MoveToCurrentLayer(Object) Move to current layer +e;o pcb-menu-default.lht FontSel(Object) Change font... +e;p pcb-menu-default.lht PropEdit(selection) Object Properties... +e;r pcb-menu-default.lht ChangeName(Refdes) Change refdes +e;s;b pcb-menu-default.lht LayerBinding() Layer bindings... +e;s;e pcb-menu-default.lht GetXY(Click on the subcircuit to edit);extedit(object) External editor... +e;s;r pcb-menu-default.lht ChangeName(Subc) Refdes +e;s;s pcb-menu-default.lht SetSame() Set Same Style +e;s;x pcb-menu-default.lht ExtobjConvFrom(Object, @gui) Convert to extended object... +e;t pcb-menu-default.lht ChangeName(Object) Edit text... +e;v pcb-menu-default.lht Tool(buffer) Paste buffer to layout +e;x pcb-menu-default.lht GetXY(Click to set the snap point for this buffer);PasteBuffer(Clear);PasteBuffer(MoveSelected);Tool(buffer) Cut selection to buffer +e;y; pcb-menu-default.lht CycleDrag() Cycle object being dragged +enter pcb-menu-default.lht Tool(Press);Tool(Release) Click (left) +escape pcb-menu-default.lht Tool(Escape) Cancel +f1 pcb-menu-default.lht Tool(via) Via +f10 pcb-menu-default.lht Tool(thermal) Thermal +f11 pcb-menu-default.lht Tool(arrow) Arrow +f12 pcb-menu-default.lht Tool(lock) Lock +f2 pcb-menu-default.lht Tool(line) Line +f3 pcb-menu-default.lht Tool(arc) Arc +f4 pcb-menu-default.lht Tool(text) Text +f5 pcb-menu-default.lht Tool(rectangle) Rectangle +f6 pcb-menu-default.lht Tool(poly) Polygon +f7 pcb-menu-default.lht Tool(buffer) Buffer +f7-shift pcb-menu-default.lht Tool(buffer);PasteBuffer(Rotate,1) Rotate buffer 90 deg CCW (left) +f8 pcb-menu-default.lht Tool(remove) Del\057Remove +f9 pcb-menu-default.lht Tool(rotate) Rotate +f;a pcb-menu-default.lht Save(LayoutAs) Save Layout As... +f;c pcb-menu-default.lht cam() Export with CAM job... +f;e pcb-menu-default.lht ExportGUI() Export layout... +f;l pcb-menu-default.lht Load(Layout) Load layout... +f;n pcb-menu-default.lht New() Start New Layout +f;o pcb-menu-default.lht Load(Layout) Load layout... +f;p pcb-menu-default.lht Print() Print layout... +f;q pcb-menu-default.lht Quit() Quit Program +f;r pcb-menu-default.lht Load(Revert,none) Revert +f;s pcb-menu-default.lht Save(Layout) Save Layout +f;x;p pcb-menu-default.lht SavePatch() netlist patch for back annotation +g;b pcb-menu-default.lht Grid(down) Previous grid +g;d pcb-menu-default.lht SetGrid(*2) Grid *2 +g;f pcb-menu-default.lht Grid(up) Next grid +g;h pcb-menu-default.lht SetGrid(\0572) Grid \0572 +g;i pcb-menu-default.lht SetUnits(mil) mil +g;l pcb-menu-default.lht conf(toggle, plugins\057hid_gtk\057local_grid\057enable, design) Enable local grid +g;m pcb-menu-default.lht SetUnits(mm) mm +g;r pcb-menu-default.lht Display(ToggleGrid) Realign grid +g;v pcb-menu-default.lht conf(toggle, editor\057draw_grid, design) Enable visible grid +i;a pcb-menu-default.lht About() About... +i;c;c pcb-menu-default.lht PrintCalibrate() Calibrate Printer... +i;c;i pcb-menu-default.lht Integrity() Data integrity check +i;c;p pcb-menu-default.lht preferences Preferences... +i;c;r pcb-menu-default.lht fp_rehash() Re-scan the footprint library +i;d pcb-menu-default.lht Report(DrillReport) Generate drill summary +i;f pcb-menu-default.lht Report(FoundPins) Report found padstacks +i;r pcb-menu-default.lht ReportObject() Generate object report +insert pcb-menu-default.lht Tool(insert) Insert Point +j;h pcb-menu-default.lht Scroll(left) Scroll Left +j;j pcb-menu-default.lht Scroll(down) Scroll Down +j;k pcb-menu-default.lht Scroll(up) Scroll Up +j;l pcb-menu-default.lht Scroll(right) Scroll Right +k;h pcb-menu-default.lht Cursor(Warp,-1,0,grid) Step Left +k;j pcb-menu-default.lht Cursor(Warp,0,1,grid) Step Down +k;k pcb-menu-default.lht Cursor(Warp,0,-1,grid) Step Up +k;l pcb-menu-default.lht Cursor(Warp,1,0,grid) Step Right +k;r pcb-menu-default.lht Tool(Release);Popup(popup-obj, obj-type) Click (right) +k;space pcb-menu-default.lht Tool(Press);Tool(Release) Click (left) +l;h; pcb-menu-default.lht ToggleView(all, vis, clear) all layers off +l;k pcb-menu-default.lht LayerByStack(Select, Prev) Select previous layer +l;l pcb-menu-default.lht LayerByStack(Select, Next) Select next layer +l;v; pcb-menu-default.lht ToggleView(all, vis, set) all layers on +left pcb-menu-default.lht Cursor(Warp,-1,0,grid) Step Left +left-ctrl pcb-menu-default.lht Scroll(left) Scroll Left +left-shift pcb-menu-default.lht Cursor(Pan,-50,0,view) Step +Left +m;c;c pcb-menu-default.lht conf(toggle, editor\057show_drc, design) Crosshair shows style clearance +m;c;o pcb-menu-default.lht conf(toggle, editor\057orthogonal_moves, design) Orthogonal moves +m;c;p pcb-menu-default.lht conf(toggle, editor\057snap_pin, design) Crosshair snaps to padstacks +m;c;s pcb-menu-default.lht conf(toggle, editor\057snap_offgrid_line, design) Crosshair snaps to off-grid points on lines +m;d;a pcb-menu-default.lht conf(toggle, editor\057live_routing, design) Show autorouter trials +m;d;c pcb-menu-default.lht conf(toggle, editor\057check_planes, design) Check polygons +m;d;d pcb-menu-default.lht conf(toggle, editor\057as_drawn_poly, design) poly as-drawn frame annotation +m;d;h pcb-menu-default.lht conf(toggle, editor\057highlight_on_point, design) Highlighting on line, arc points +m;d;o pcb-menu-default.lht conf(toggle, editor\057click_objlist, design) Object list popup +m;d;p pcb-menu-default.lht conf(toggle, editor\057thin_draw_poly, design) Thin draw poly +m;d;r pcb-menu-default.lht Reset +m;d;t pcb-menu-default.lht conf(toggle, editor\057thin_draw, design) Thin draw +m;d;w pcb-menu-default.lht conf(toggle, editor\057wireframe_draw, design) Wireframe draw +m;f;h pcb-menu-default.lht conf(toggle, editor\057hide_names, design) Hide floaters +m;f;l pcb-menu-default.lht conf(toggle, editor\057lock_names, design) Lock floaters +m;f;o pcb-menu-default.lht conf(toggle, editor\057only_names, design) Only floaters +m;k;s pcb-menu-default.lht subc(loose, toggle) Loose subcircuits (no subc lock) +m;l;+ pcb-menu-default.lht SetValue(LineSize,+5,mil) Line Tool size +5 mil +m;l;- pcb-menu-default.lht SetValue(LineSize,-5,mil) Line Tool size -5 mil +m;l;a pcb-menu-default.lht conf(toggle, editor\057all_direction_lines, design) 'All-direction' lines +m;l;c pcb-menu-default.lht conf(toggle, editor\057clear_line, design) New lines, arcs clear polygons +m;l;d pcb-menu-default.lht conf(toggle, editor\057auto_drc, design) Auto enforce style clearance +m;l;f pcb-menu-default.lht Display(CycleClip) Cycle line clip\057refraction +m;l;m pcb-menu-default.lht conf(toggle, editor\057trace_auto_merge, design) Automatic trace merging +m;o;b pcb-menu-default.lht conf(toggle, appearance\057black_current_group, design) black current group +m;o;i pcb-menu-default.lht conf(toggle, appearance\057invis_other_groups, design) Invisible-color on other groups +m;p;c pcb-menu-default.lht conf(toggle, editor\057clear_polypoly, design) New polygons clear polygons +m;p;f pcb-menu-default.lht conf(toggle, editor\057full_poly, design) New polygons are full ones +m;p;i pcb-menu-default.lht ClipInhibit(toggle) Polygon clip inhibit (toggle) +m;r;m pcb-menu-default.lht conf(toggle, editor\057rubber_band_keep_midlinedir, design) Rubber band keeps middle line dir +m;r;r pcb-menu-default.lht conf(toggle, editor\057rubber_band_mode, design) Rubber band mode +m;t;+ pcb-menu-default.lht SetValue(TextScale,+10,mil) Text Tool scale +10 mil +m;t;- pcb-menu-default.lht SetValue(TextScale,-10,mil) Text Tool scale -10 mil +n-ctrl pcb-menu-default.lht New() Start New Layout +n;c;f; pcb-menu-default.lht ClaimNet(found) claim net on found +n;c;o; pcb-menu-default.lht ClaimNet(object) claim net by object +n;c;s; pcb-menu-default.lht ClaimNet(selected) claim net on selected +n;l;k; pcb-menu-default.lht NetLength(clear) Visual length, clear +n;l;l; pcb-menu-default.lht NetlistDialog();NetlistDialog(RefreshNetLens) Netlist dialog, refresh lengths +n;l;o; pcb-menu-default.lht NetLength(object) Visual length, from object +p;m;p; pcb-menu-default.lht ManagePlugins() Manage plugins... +p;m;s; pcb-menu-default.lht BrowseScripts() Manage scripts... +p;p;c pcb-menu-default.lht Polygon(Close) Polygon Close +p;p;p pcb-menu-default.lht Polygon(PreviousPoint) Polygon PreviousPoint +q-ctrl pcb-menu-default.lht Quit() Quit Program +r;r;+ pcb-menu-default.lht conf(delta, editor\057route_radius, +0.5, design) Route radius +0.5 +r;r;- pcb-menu-default.lht conf(delta, editor\057route_radius, -0.5, design) Route radius -0.5 +r;r;m pcb-menu-default.lht conf(delta, editor\057route_radius, -0.5, design) Route radius -0.5 +r;r;p pcb-menu-default.lht conf(delta, editor\057route_radius, +0.5, design) Route radius +0.5 +right pcb-menu-default.lht Cursor(Warp,1,0,grid) Step Right +right-ctrl pcb-menu-default.lht Scroll(right) Scroll Right +right-shift pcb-menu-default.lht Cursor(Pan,50,0,view) Step +Right +s-ctrl pcb-menu-default.lht Save(Layout) Save Layout +s-ctrl-shift pcb-menu-default.lht Save(LayoutAs) Save Layout As... +s;a;a; pcb-menu-default.lht Select(All) Select all visible objects +s;a;c; pcb-menu-default.lht Select(Connection) Select all found objects +s;b;p pcb-menu-default.lht PadstackBreakup(selected) Break selection padstack to pieces +s;b;s pcb-menu-default.lht PasteBuffer(Push);PasteBuffer(5);PasteBuffer(Clear);PasteBuffer(AddSelected);RemoveSelected();PasteBuffer(Restore);PasteBuffer(ToLayout, crosshair);PasteBuffer(Clear);PasteBuffer(Pop) Break selection subcircuits to pieces +s;c;e; pcb-menu-default.lht ExtobjConvFrom(Selected, @gui) Convert selection to extended object... +s;c;p; pcb-menu-default.lht PadstackConvert(selected);Tool(buffer) Convert selection to padstack +s;c;s; pcb-menu-default.lht Select(ConvertSubc) Convert selection to subcircuit +s;f; pcb-menu-default.lht Flip(SelectedElements) Move selected subcircuits to other side +s;i; pcb-menu-default.lht Select(Invert) Invert selection +s;l; pcb-menu-default.lht MoveToCurrentLayer(Selected) Move selected objects to current layer +s;r; pcb-menu-default.lht RemoveSelected() Remove selected objects +s;s; pcb-menu-default.lht SearchDialog() Advanced search and select +s;u;a; pcb-menu-default.lht Unselect(All) Unselect all objects +s;u;c; pcb-menu-default.lht Unselect(Connection) Unselect all found objects +space pcb-menu-default.lht Tool(arrow) Arrow +t;a pcb-menu-default.lht Tool(arc) Arc +t;b pcb-menu-default.lht Tool(buffer) Buffer +t;c pcb-menu-default.lht Tool(copy) Copy +t;d pcb-menu-default.lht Tool(remove) Del\057Remove +t;e pcb-menu-default.lht Tool(thermal) Thermal +t;h pcb-menu-default.lht Tool(polyhole) Polygon Hole +t;i pcb-menu-default.lht Tool(insert) Insert Point +t;k pcb-menu-default.lht Tool(lock) Lock +t;l pcb-menu-default.lht Tool(line) Line +t;m pcb-menu-default.lht Tool(move) Move +t;n pcb-menu-default.lht Tool(arrow) Arrow +t;o pcb-menu-default.lht Tool(rotate) Rotate +t;p pcb-menu-default.lht Tool(poly) Polygon +t;r pcb-menu-default.lht Tool(rectangle) Rectangle +t;t pcb-menu-default.lht Tool(text) Text +t;v pcb-menu-default.lht Tool(via) Via +tab pcb-menu-default.lht SwapSides(V) Flip up\057down +tab-ctrl pcb-menu-default.lht SwapSides(R) Spin 180 degrees +tab-ctrl-shift pcb-menu-default.lht SwapSides() Swap Sides +tab-shift pcb-menu-default.lht SwapSides(H) Flip left\057right +u;c pcb-menu-default.lht Undo(ClearList) Clear undo-buffer +u;d; pcb-menu-default.lht UndoDialog() Undo dialog (for debugging) +u;r pcb-menu-default.lht Redo() Redo last undone operation +u;u pcb-menu-default.lht Undo() Undo last operation +up pcb-menu-default.lht Cursor(Warp,0,-1,grid) Step Up +up-ctrl pcb-menu-default.lht Scroll(up) Scroll Up +up-shift pcb-menu-default.lht Cursor(Pan,0,-50,view) Step +Up +v;c pcb-menu-default.lht Center() Center cursor +v;f pcb-menu-default.lht Zoom() Zoom Extents +v;n pcb-menu-default.lht Display(PinOrPadName) Show padstack numbers in a subc +v;r;g pcb-menu-default.lht Reset GUI +v;r;v pcb-menu-default.lht Reset View +v;s;c pcb-menu-default.lht Display(SubcID) user configured +v;s;f pcb-menu-default.lht Display(SubcID,"%a.footprint%") footprint +v;s;r pcb-menu-default.lht Display(SubcID, "%a.refdes%") refdes +v;s;s pcb-menu-default.lht Display(SubcID,"%a.refdes%\\n%a.value%") refdes+value +v;s;v pcb-menu-default.lht Display(SubcID,"%a.value%") value +v;t;c pcb-menu-default.lht Display(TermID) user configured +v;t;n pcb-menu-default.lht Display(TermID, "%a.name%") name +v;t;s pcb-menu-default.lht Display(TermID, "%a.term%,%a.name%") term+name +v;t;t pcb-menu-default.lht Display(TermID, "%a.term%") term +w;a pcb-menu-default.lht About() About... +w;d pcb-menu-default.lht DRC() DRC Check +w;f pcb-menu-default.lht FontSel() Font selector +w;l pcb-menu-default.lht LibraryDialog() Library +w;m pcb-menu-default.lht LogDialog() Message Log +w;n pcb-menu-default.lht NetlistDialog() Netlist +w;p pcb-menu-default.lht Display(Pinout) Pinout +y-ctrl pcb-menu-default.lht Redo() Redo last undone operation +z-ctrl pcb-menu-default.lht Undo() Undo last operation +z;e; pcb-menu-default.lht Zoom() Zoom Extents +z;f; pcb-menu-default.lht ZoomTo(found) Zoom to found +z;s; pcb-menu-default.lht ZoomTo(selected) Zoom to selection +z;x; pcb-menu-default.lht Zoom(+1.2) Zoom Out 20% +z;z; pcb-menu-default.lht Zoom(-1.2) Zoom In 20% +| pcb-menu-default.lht conf(toggle, editor\057wireframe_draw, design) Wireframe draw Index: tags/2.3.0/doc/user/05_ui/04_common/src/node_names.txt =================================================================== --- tags/2.3.0/doc/user/05_ui/04_common/src/node_names.txt (nonexistent) +++ tags/2.3.0/doc/user/05_ui/04_common/src/node_names.txt (revision 33253) @@ -0,0 +1,41 @@ +/a auto or add +/a/b back annotation +/a/p auto-place +/a/d auto-disperse +/a/r auto-route +/a/o optimize (djopt) +/b buffer +/b/c convert & clear +/b/m mirror +/b/r rotate +/b/s subcircuit +/c connections & rats +/e edit +/e/m move +/e/s subcircuit or style +/e/g geometry +/g grid +/f file +/f/x export to +/f/c configuration +/i info +/i/c configuration +/m mode +/m/c cursor/crosshair mode +/m/d drawing (render) mode +/m/f floater mode +/m/l line drawing (routing) settings +/m/t text drawing (routing) settings +/m/p polygon drawing mode +/m/r rubber band mode +/s select +/s/a select all... +/s/u unselect all... +/s/c convert selected +/r routing helper +/r/r routing radius +/t tool +/u undo +/v view +/v/s set view +/w window Index: tags/2.3.0/doc/user/05_ui/05_cli/index.html =================================================================== --- tags/2.3.0/doc/user/05_ui/05_cli/index.html (nonexistent) +++ tags/2.3.0/doc/user/05_ui/05_cli/index.html (revision 33253) @@ -0,0 +1,35 @@ + + + + pcb-rnd user manual + + + + +

    pcb-rnd - user manual

    + +

    5.2 Actions and Command Line Interface

    +

    +Each user accessible operation and functionality is implemented in an action. +Menu items and hotkeys all invoke actions. An action is like a function call: +it has parameters and a return value. + +

    +pcb-rnd actions can be listed + +

    + +./pcb-rnd --show-actions + + +

    +A full list of actions can be found in the + appendix with +detailed desciption of parameters and operations they perform. +

    +Actions are entered on the GUI (typically using the ':' key for getting +a command line) and on the stdin using the batch GUI. User scripts call +actions with all-lowercase function names. + + + Index: tags/2.3.0/doc/user/05_ui/index.html =================================================================== --- tags/2.3.0/doc/user/05_ui/index.html (nonexistent) +++ tags/2.3.0/doc/user/05_ui/index.html (revision 33253) @@ -0,0 +1,28 @@ + + + + pcb-rnd user manual + + + + +

    pcb-rnd - user manual

    + +

    5. User Interface (UI)

    +

    +pcb-rnd offers various user interface plugins. The plugins connect different +input methods to the pcb-rnd core, offering functionality to match a variety of +user tools, experience, or desired workflows. +

    +The following sections describe all the existing pcb-rnd UI plugins. We start +with the section on GTK+ because it is the most commonly used HID +

    +

    + + Index: tags/2.3.0/doc/user/06_feature/asm/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/asm/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/asm/index.html (revision 33253) @@ -0,0 +1,89 @@ + + + + pcb-rnd user manual + + + + +

    asm - manual assembly helper

    +

    +The asm plugin provides an action called asm which pops up a dialog +box that assists manual assembly of the current board. The plugin is useful only +with a GUI HID. +

    +The plugin lists, groups and sorts all subcircuits (parts) that are placed +on the current board. The asm dialog presents all subcircuits in a tree of two +levels. the first level is all part groups. In each part group, the second level +is all parts that have the same grouping template. The list of groups is +sorted by group properties and the lists of parts within each groups are +sorted by the sorting template. While the assembly dialog is open, clicking a +part or a group of parts will highlight (select) the parts in the main window. + +

    Intended use: rapid full board building

    +

    +The intended use is configuring the plugin to group parts by assembly steps. +Each group should contain parts that are "coming from the same bin". Within +each group parts should be sorted by board side and location. +

    +The user should click the first part in the first group, check the highlight, +solder on the part and click the 'part done' button. This will skip to the +next part, while the focus stays on the same button. From now on, simply +pressing enter indicates the currently highlighted part is done, soldered +on the board. +

    +In this setup the grouping template should contain a height hint attribute +of the subcircuits so that taller parts are built last. + +

    Intended use: build by functionality

    +

    +It is also possible to configure the grouping/sorting templates to support +a per functionality build, which is more useful in building and testing the +first prototype. +

    +In this scenario subcircuits shall have a dedicated attribute defining +which functionality each part belongs to - preferably this attribute +should be coming from the schematics. The group template shall contain this +attribute as the first field, so groups are created and sorted by functionality. + +

    Templates

    +

    +There are two configured templates under /plugins/asm1: +

      +
    • group_template: for rendering the group string for each part +
    • sort_template: for rendering the sort string for each part +
    +

    +The group string is used for grouping parts and as the sorting function +for the groups. If two parts have the same group string, they will end up +in the same group. The sort string is used for sorting parts within +their group. +

    +A template is comma separated list of directives. A directive is one of +the following: +

    + +
    directive substituted with... +
    side either "0/top" or "1/bottom" depending on which side the subcircuit is placed on +
    x subcircuit origin X coordinate in mm, without unit +
    y subcircuit origin X coordinate in mm, without unit +
    a.keywith the value of the subcircuit's attribute with matching key +
    +

    +For example the group template +

    +a.footprint, a.value, a.asm::group
    +
    +

    +will be executed by pasting the footprint attribute, a comma, the value +attribute, a comma and the asm::group attribute. This will typically result +in something like "1206,100nF,". The resulting group string is then used for +grouping and sorting the groups alphabetically. + + + + + + + + Index: tags/2.3.0/doc/user/06_feature/autocrop/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/autocrop/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/autocrop/index.html (revision 33253) @@ -0,0 +1,32 @@ + + + + pcb-rnd user manual + + + + +

    Autocrop plugin

    +

    +Use the autocrop action to resize your pcb-board to extants +

    Description

    +

    +Autocrop finds the extents of your existing layout and resizes the board +dimensions to contain only your parts plus a margin along the edge. +

    +Syntax: +
    +autocrop(); +

    +Use: +
    +Bind autocrop to a key in the appropriate pcb-menu-*.lht for your preferred pcb-rnd gui. +

    +Issues: +
    Autocrop will move the objects to crop the layout, and as a consequence autocrop() plugin will take time to calculate for complex layouts. +
    Autocrop is not undoable. +
    Edge clearance is fixed at 5*line spacing + + + + Index: tags/2.3.0/doc/user/06_feature/autoplace/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/autoplace/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/autoplace/index.html (revision 33253) @@ -0,0 +1,22 @@ + + + + pcb-rnd user manual + + + + +

    Autoplace plugin

    +

    +The autoplace plugin looks at the netlist and tries to place subcircuits +in a way to get routing easier. The algorithms follow those described in +sections 4.1 of "Placement and Routing of Electronic Modules" edited by +Michael Pecht Marcel Dekker, Inc. 1993. ISBN: 0-8247-8916-4 TK7868.P7.P57 +1993. +

    +The plugin declares action AutoPlaceSelected which operates on +the selected subcircuits. A netlist shall be loaded and subcircuits +available on the board before the action is invoked. + + + Index: tags/2.3.0/doc/user/06_feature/autoroute/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/autoroute/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/autoroute/index.html (revision 33253) @@ -0,0 +1,46 @@ + + + + pcb-rnd user manual + + + + +

    Autoroute plugin

    +

    +Tha autoroute plugin attempts to route traces according to the netlist, +after subcircuit placement is done by the user. There are two modes of +operation: +

      +
    • route all rat lines +
    • route only the selected rat lines +
    +

    +Limiting the operation to selected rat lines only gives some control +to the user; typical use is to route critical nets first, while the board +is sparse and leave less important nets to the end (getting them longer and +have more vias). +

    +The autorouter uses only the currently visible copper layers and places +vias and jumps layers where necessary. +

    +Before the autorouter is ran, a netlist should be imported, subcircuits +should be loaded and placed. Other plugins, such as the + autoplace or smartdisperse can help with +the placement. After the autorouting, djopt +actions can be used to purify the routed tracks. +

    +The plugin implements a rectangle-expansion router, based on +"A Method for Gridless Routing of Printed Circuit Boards" by +A. C. Finch, K. J. Mackenzie, G. J. Balsdon, and G. Symonds in the +1985 Proceedings of the 22nd ACM/IEEE Design Automation Conference. +This reference is available from the ACM Digital Library at +http://www.acm.org/dl for those with institutional or personal +access to it. +

    +Note: the built-in autorouter is not very smart. There are 3rd party, external +autorouters that can do better job on some boards, and pcb-rnd supports +export/import to communicate with them. + + + Index: tags/2.3.0/doc/user/06_feature/cam/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/cam/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/cam/index.html (revision 33253) @@ -0,0 +1,230 @@ + + + + pcb-rnd user manual + + + + +

    CAM support

    +

    +The purpose of the CAM support is to provide a unified interface to export a +board in different file formats using different exporter plugins. The +interface consists of a CLI layer (each export plugin's "cam" option) and +an optional GUI (the CAM plugin). + +

    CAM export support in multi-layer plugins with '-x plugin --cam'

    +

    +This section is about the syntax used by the exporters that export +multiple layers (e.g. gerber, ps, png). +

    +Each CAM-plugin-compatible exporter plugin offers an option called "cam". +The syntax and capabilities are the same for all exporter's cam option. +

    +The syntax is: +

    +outfile=[global-opts] layergrp,layergrp,...
    +
    +

    +where: +

      +
    • outfile is the output file name template that substitutes %%: +
        +
      • %name% is substituted with the layer group name +
      • %base% is substituted with the base name of the output file path (the file name without directories) +
      • %top_offs% is substituted with the layer group offset from the top (top layer group being 0); only layer groups with the same material considered +
      • %bot_offs% is substituted with the layer group offset from the bottom (bottom layer group being 0); only layer groups with the same material considered +
      +
    • optionally [global-opts]: a comma separated list of group-global (but per-output-file) options in [] brackets. Options supported: +
        +
      • okempty-group: warning suppression: do not warn when none of the layer groups referenced for an outfile exists (outfile can not be created or will be empty) +
      • okempty-content: warning suppression: do not warn when all layer groups for an outfile were empty (outfile is normally created and valid, but is empty as no object got exported) +
      • okempty: shorthand that enables both okempty-group and okempty-content +
      +
    • layergrp: one or more layer group addresses separated by comma (syntax is documented in layer addressing appendix.) +
    +

    +Examples: + +
    directive + explanation +
    bot.gbr=@bottom_copper,@bottom_silk + export layer groups called bottom_copper and bottom_silk (by group name) +
    asm_top.ps=top-virtual(purpose=assy) + export the top assembly layer group (by type) +
    fabrication.ps=virtual(purpose=fab) + export the first virtual layer group with 'fab' purpose +
    gnd=copper:2 + export the second copper layer group from the top (the first internal copper layer group under the top copper layer group, if it is a multilayer board; for 2 layer boards this will be the bottom copper layer group) +
    gnd=intern-copper:1 + similar to the above, but addresses the first internal copper layer group explicitly so it can not end up being the bottom copper layer group +
    pwr=copper:-2 + export the second copper layer group from the bottom (the first internal copper layer group above the bottom copper layer group, if it is a multilayer board; for 2 layer boards this will be the top copper layer group) +
    gnd=intern-copper:-1 + similar to the above, but addresses the last internal copper layer group explicitly so it can not end up being the top copper layer group +
    pst.gbr=top-paste(bloat=0.1mm),bottom-paste(bloat=0.1mm) + export the top and bottom paste groups in the same file with all objects bloated up by 0.1mm +
    plated_drills.cnc=virtual(purpose=pdrill) + export plated drilled holes (padstack side effects, but no slots) +
    unplated_drills.cnc=virtual(purpose=udrill) + export unplated drilled holes (padstack side effects, but no slots) +
    unplated_drills.cnc=[okempty] virtual(purpose=udrill) + same as the previous, but do not print a warning if there was no unplated drill in the design +
    +

    +If multiple layer groups match a layergrp specification, all matching +layer groups are exported. If the file name is a static string, they are +all merged. If the file name is templated, it is possible to export the +layer groups in multiple files. For example: + +
    directive + explanation +
    copper.gbr=copper + export all copper layers to copper.gbr +
    copper-%top_offs%.gbr=copper + export all copper layers to numbered copper-N.gbr files where N is the offset from the top side, starting from 0 (for top copper) +
    copper-%name%.gbr=copper + export all copper layers to numbered copper-N.gbr files where N is the full name of the group being exported +
    + +

    CAM export support in no-layer plugins with '-x plugin --cam'

    +

    +This section is about the syntax used by the exporters export global digest +of the board and not layers (e.g. XY). +

    +For these exporters the above apply with no layergrp specified. In the simplest +for this means the '=' and the rest of the line is omitted. However, if +supplement needs to be passed, the syntax is filename=(supplement). +For example the XY exporter can be used with +

    +--cam foo.xy
    +
    +or a partial excellon export can be done using: +
    +--cam foo.exc=(partial)
    +
    +

    +The --cam option in these exporters are implemented for two reasons: +

      +
    • to provide an unified syntax for the output file name +
    • to allow a CAM job to use these exporters +
    + +

    partial export

    +

    +In partial exporting the rendering code in core will draw only those object +that have the EXPORTSEL flag set. The flag is normally set by a query() action +using an expression. +

    +A typical use of this feature is to export plugged/filled vias into a +separate file, assuming the padstacks have a specific attribute set. + +

    CAM plugin (CAM jobs) with '-x cam'

    +

    +The CAM plugin is a way to manage output "jobs": collections of cam export +settings for reproducing export packages in various formats. +

    +... +

    +A job is a script that contains zero or more export directives, separated +by semicolons or newlines. An export directive is one of these: +

    +desc text
    +plugin name [--option value] [--option value] ...
    +write outfile=layergrp[,layergrp,...]
    +
    +

    +desc is a free form one-liner that describes what the job is for. Multiple +desc directives may be present (to bypass the limitation that the text can +not contain newlines). +

    +The plugin directive selects a plugin and sets plugin specific options. +The plugin and options are active until the next plugin directive or the +end of the script. The first outfile directive must be preceeded by a +plugin directive. +

    +The write directive argument has the same syntax as the cam argument for each +cam-capable exporter, see above. Each write is a call +to an exporter the same way as if pcb-rnd was called with --cam and -x +with the exporter and options taken from the last plugin directive. +

    +For example, the following config tree defines a job called doc_png +that generates two 600 DPI images from the sides of the board, copper and +silk combined, all in the doc/ dir (that is created if necessary): +

    +li:pcb-rnd-conf-v1 {
    +	ha:overwrite {
    +		ha:plugins {
    +			ha:cam {
    +				li:jobs {
    +					doc_png {
    +						desc export top and bottom copper and silk in 600 DPI pngs
    +						plugin png --dpi 600
    +						write top.png=top-copper,top-silk
    +						write bottom.png=bottom-copper,bottom-silk
    +					}
    +				}
    +			}
    +		}
    +	}
    +}
    +
    +

    +Once the above subtree is loaded in the config, the following action triggers +the export: +

    +cam(call, doc_png)
    +
    +

    +If the command partial appears in the job, a query() is executed +with the expression specified in the command's argument, marking matching +objects with the EXPORTSEL flag. The full command is used to remove +the EXPORTSEL flag from all objects. Note: to export only marked objects, +the write command will typically need the partial supplement. +A typical use case is exporting filled vias in a separate file, using +a custom object attribute called "process": +

    +li:pcb-rnd-conf-v1 {
    +	ha:overwrite {
    +		ha:plugins {
    +			ha:cam {
    +				li:jobs {
    +					holes {
    +						desc export all holes in excellon files, sorted by whether they are filled
    +						plugin excellon
    +						partial @.a.process == "filled"
    +						write filled.exc=(partial)
    +						full
    +						partial @.a.process != "filled"
    +						write unfilled.exc=(partial)
    +						full
    +						write all.exc
    +					}
    +				}
    +			}
    +		}
    +	}
    +}
    +
    +Note: the first full command is used to cancel the effect of the first +partial command. Without full, at the second partial +all the "filled" vias would still be marked and unfilled.exc would contain +both filled and unfilled vias. + +

    Tips for using with various exporters

    +

    +When exporting to ps, consider using the --no-show-toc. It is +possible to combine multiple layers (e.g. top silk and top copper, which +may be useful for a single-layer board) using the --single-page option. +

    +The plugin field has the same values command line -x has. +The list of currently available exporter names can be acquired by running +

    +pcb-rnd -x
    +
    +Note: this list contains all exporter plugins currently available +(depends on your configure time options and plugin availability). Some export +plugins can not do per layer exporting and those will not support CAM exporting +either. + + Index: tags/2.3.0/doc/user/06_feature/ddraft/coord_seq.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/ddraft/coord_seq.png =================================================================== --- tags/2.3.0/doc/user/06_feature/ddraft/coord_seq.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/ddraft/coord_seq.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/ddraft/coord_seq.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/ddraft/coord_sys.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/ddraft/coord_sys.png =================================================================== --- tags/2.3.0/doc/user/06_feature/ddraft/coord_sys.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/ddraft/coord_sys.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/ddraft/coord_sys.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/ddraft/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/ddraft/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/ddraft/index.html (revision 33253) @@ -0,0 +1,194 @@ + + + + pcb-rnd user manual + + + + +

    ddraft - 2 dimensional drafting aid

    +

    +The purpose of ddraft is to provide actions and GUI tools to help users +drawing precise 2d drafts. Many of the features in ddraft are very similar +to those found in standard 2d CAD packages. +

    +Ddraft uses the following coordinate system (when looked from the top +of the board): +

    +ddraft coordinate system: upper left corner is 0;0, x+ is tot he right, y+ is down, 0 deg is at 3 o'clock and increases clockwise + +

    constraints

    +

    +Coordinate and/or angle constraints can be applied on line drawing (when +all-direction lines turned on) and move operation. Executing the +constraint() action without arguments opens a dialog box with the +settings. The same settings are accessible from the command line, using +the constraint() action with arguments: +

    + +
    Constraint arguments: explicitly set +
    action syntax description +
    constraint(line_angle, ang1, ang2, ...) permit drawing lines only at specific angles +
    constraint(line_angle_mod, ang) permit drawing lines only at angles which are integer multiplies of ang +
    constraint(line_length, len1, len2, ...) draw lines with length matching any length on the list +
    constraint(line_length_mod, len) draw lines with length matching any integer multiply of the len +
    constraint(move_angle, ang1, ang2, ...) permit moving objects only at specific angles +
    constraint(move_angle_mod, ang) permit moving objects only at angles which are integer multiplies of ang +
    constraint(move_length, len1, len2, ...) move objects at a distance matching any length on the list +
    constraint(move_length_mod, len) move objects at a distance matching an integer multiply of the len +
    constraint(reset) reset all constraints +
    +

    +Length can include unit (on the GUI: without space). Multiple constraints +can be set in the same time. Constraints are reset upon explicit user +request or pcb-rnd restart. +

    +For line drawing, it is possible to get the angle constraints calculated using +the line start point and an existing object: +

    + +
    Constraint arguments: calculated +
    action syntax description +
    perp() click on a line; set line_angle perpendicular to that line +
    paral() click on a line; set line_angle parallel to that line +
    tang() click on an arc; set line_angle tangential to the circle of the arc +
    + +

    Cutting edges

    +

    +For already existing, intersecting objects (lines and arcs), the user may +define cutting edges that can manipulate target objects they intersect. There +are two actions for cutting edges: trim() and split(). The first argument of +these actions is: +

      +
    • object (selecting a single cutting edge) +
    • selected (to use any selected object as cutting edge) +
    • found (to use any found (green highlight) object as cutting edge) +
    +

    +The objects participating may be on different layers. All calculation use +the centerline of the objects. +

    +In a trim operation the target objects are cut at the intersection point, +excess parts (at the click) removed. If there are multiple cutting edges, +the shortest possible section is removed. The below examples are generated +with trim(selected), clicking on the horizontal line at the small +triangle mark. +

    +[Effect of trim on a few examples] +

    +In a split operation target objects are split into multiple section wherever +they cross a cutting edge. A split means a single line object becomes multiple +line objects or a single arc object becomes multiple arc objects. + +

    Command line drafting

    +

    +The above features are pcb-rnd actions designed to fit in the action framework, +to work together with the original pcb-rnd drawing tools, like the line tool. +An alternative to that is using the new, ddraft command line interpreter, which +offers a different syntax, optimized for drafting. +

    +There are two ways to use the ddraft command line interpreter: +

      +
    • a command wrapped in the ddraft() action, e.g. ddraft(line from 1,3 to 4,2) +
    • switching the command entry to ddraft CLI mode, by issuing the ddraft() action; + to exit from the ddraft CLI mode, type /exit +
    +

    +When used as a CLI mode, mouse clicks on the drawing will also edit the +command line at the cursor. The generic rule is that a click will replace +an already entered numerical value or inserts a missing numerical value, but +all instruction keywords are typed on the keyboard. Instructions can +be abbreviated; the shortest form accepted is the shortest prefix that +is unique among the instruction keywords. For example "li" means "line" +and "rel" or even "re" works for "relative". +

    +The first instruction is the drawing command, which is one of the following. +

    + +
    ddraft drawing commands +
    command syntax summary purpose +
    line + line [from] coord to coord + draw line segments on the current layer, using the current routing style +
    +

    +Parts enclosed in [] are optional. A coord description is a sequence +of absolute and relative coordinates: +

    + +
    ddraft drawing commands +
    keyword next instruction (argument) example purpose +
    absolute + xcoord,ycoord + abs 1mm,15mm + an absolute coordinate; units are optional; must not contain space +
    * + *1mm,15mm +
      + 1mm,15mm + +
    relative + xcoord,ycoord + rel 1mm,15mm + a relative coordinate measured from the absolute coord specified so far; units are optional; must not contain space +
    @ + @1mm,15mm + +
    angle + degree + ang 15 + an absolute angle in degrees; always measured from the X axis; should be used together with length +
    < + <15 + +
    relative angle + degree + rel ang 15 + a relative angle in degrees; always measured from the X axis; should be used together with length +
    @< + @<15 + + + +
    length + coord + len 3.1mm + length or distance to move from the previous coordinate; always relative; used together with an angle +
    ~ + ~3.1mm + +
    +

    +For example the sequence +5mm,100mil relative 1mm,1mm relative angle 30 length 2mm +means: +

      +
    • step 1: start from absolute coords at 5mm, 100mil; after this the current coordinate is: 5.0000mm,2.5400mm +
    • step 2: move relative (to the right and down) 1 and 1 mm; after this the current coordinate is: 6.0000mm,3.5400mm +
    • step 3: the last move was a 45 degree move; relative to this 45 degrees, start moving at 30 degrees (that is, in absolute 75 degrees), and... +
    • step 4: ... move 2mm in that direction +
    • step 5: the sequence ends here, the coordinate it points to is: 6.5176mm,5.4719mm +
    +

    +Below the same steps are demonstrated; dark red lines demonstrate the moves, +thin black lines show how they are calculated. The result is a single coordinate +marked with a thin black cross at step 5. The sequence itself does not draw +anything, the drawing merely demonstrates how the steps are executed in +memory. +

    +the coord sequence annotated with auxiliary lines and step numbers +

    +Equivalent alternative forms for the same sequence: +

    +5mm,100mil rel 1mm,1mm rel ang 30 len 2mm
    +5mm,100mil @1mm,1mm @<30~2mm
    +5,100mil @1,1 @<30~2
    +
    +

    +The last one assumes unit is set to mm. + + + + + Index: tags/2.3.0/doc/user/06_feature/ddraft/src/Makefile =================================================================== --- tags/2.3.0/doc/user/06_feature/ddraft/src/Makefile (nonexistent) +++ tags/2.3.0/doc/user/06_feature/ddraft/src/Makefile (revision 33253) @@ -0,0 +1,19 @@ +PCBRND=pcb-rnd +CLEANFILES= ../*.png + +all: ../coord_sys.png ../coord_seq.png ../trim.png + +../coord_sys.png: coord_sys.lht + $(PCBRND) -x png --dpi 450 coord_sys.lht + mv coord_sys.png ../coord_sys.png + +../coord_seq.png: coord_seq.lht + $(PCBRND) -x png --dpi 450 coord_seq.lht + mv coord_seq.png ../coord_seq.png + +../trim.png: trim.lht + $(PCBRND) -x png --dpi 450 trim.lht + mv trim.png ../trim.png + +clean: $(CLEANRULES) + -rm $(CLEANFILES) Index: tags/2.3.0/doc/user/06_feature/ddraft/src/coord_seq.lht =================================================================== --- tags/2.3.0/doc/user/06_feature/ddraft/src/coord_seq.lht (nonexistent) +++ tags/2.3.0/doc/user/06_feature/ddraft/src/coord_seq.lht (revision 33253) @@ -0,0 +1,472 @@ +ha:pcb-rnd-board-v5 { + ha:netlists { + li:input { + } + } + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 390.0mil + y = 310.0mil + } + ha:grid { + spacing = 5.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + ha:layer_stack { + li:groups { + ha:0 { + ha:type { + top = 1 + paste = 1 + } + li:layers { + 8 + } + name = top_paste + } + ha:1 { + ha:type { + silk = 1 + top = 1 + } + li:layers { + 7 + } + name = top_silk + } + ha:2 { + ha:type { + top = 1 + mask = 1 + } + li:layers { + 9 + } + name = top_mask + } + ha:3 { + ha:type { + copper = 1 + top = 1 + } + li:layers { + 0 + 2 + } + name = top_copper + } + ha:4 { + ha:type { + substrate = 1 + intern = 1 + } + li:layers { + } + name = grp_4 + } + ha:5 { + ha:type { + copper = 1 + intern = 1 + } + li:layers { + 5 + } + name = Intern + } + ha:6 { + ha:type { + substrate = 1 + intern = 1 + } + li:layers { + } + name = grp_6 + } + ha:7 { + ha:type { + copper = 1 + intern = 1 + } + li:layers { + 4 + } + name = Intern + } + ha:8 { + ha:type { + substrate = 1 + intern = 1 + } + li:layers { + } + name = grp_8 + } + ha:9 { + ha:type { + outline = 1 + } + li:layers { + } + name = global_outline + } + ha:10 { + ha:type { + bottom = 1 + copper = 1 + } + li:layers { + 1 + 3 + } + name = bottom_copper + } + ha:11 { + ha:type { + bottom = 1 + mask = 1 + } + li:layers { + 10 + } + name = bottom_mask + } + ha:12 { + ha:type { + silk = 1 + bottom = 1 + } + li:layers { + 6 + } + name = bottom_silk + } + ha:13 { + ha:type { + bottom = 1 + paste = 1 + } + li:layers { + 11 + } + name = bottom_paste + } + } + } + + li:styles { + ha:Signal { + diameter = 2.0mm + thickness = 0.1mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1.0mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:data { + li:padstack_prototypes { + } + li:objects { + } + li:layers { + ha:top-sig { + visible = 1 + lid = 0 + li:objects { + ha:line.4 { + clearance = 40.0mil + y2 = 130.0mil + thickness = 10.0mil + x1 = 30.0mil + x2 = 226.8503937mil + ha:flags { + clearline = 1 + } + y1 = 30.0mil + } + ha:line.7 { + clearance = 40.0mil + y2 = 4.302mm + thickness = 10.0mil + x1 = 226.8503937mil + x2 = 6.762mm + ha:flags { + clearline = 1 + } + y1 = 130.0mil + } + ha:line.10 { + clearance = 40.0mil + y2 = 6.2339mm + thickness = 10.0mil + x1 = 6.762mm + x2 = 7.2796mm + ha:flags { + clearline = 1 + } + y1 = 4.302mm + } + } + color = {#8b2323} + group = 3 + ha:combining { + } + } + ha:bottom-sig { + visible = 1 + lid = 1 + li:objects { + } + color = {#3a5fcd} + group = 10 + ha:combining { + } + } + ha:top-gnd { + visible = 1 + lid = 2 + li:objects { + } + color = {#104e8b} + group = 3 + ha:combining { + } + } + ha:bottom-gnd { + visible = 1 + lid = 3 + li:objects { + } + color = {#cd3700} + group = 10 + ha:combining { + } + } + ha:int-sig2 { + visible = 1 + lid = 4 + li:objects { + } + color = {#548b54} + group = 7 + ha:combining { + } + } + ha:int-sig1 { + visible = 1 + lid = 5 + li:objects { + } + color = {#8b7355} + group = 5 + ha:combining { + } + } + ha:bottom-silk { + visible = 1 + lid = 6 + li:objects { + } + color = {#000000} + group = 12 + ha:combining { + auto = 1 + } + } + ha:top-silk { + visible = 1 + lid = 7 + li:objects { + ha:line.13 { + clearance = 40.0mil + y2 = 30.0mil + thickness = 0.1mil + x1 = 226.8503937mil + x2 = 226.8503937mil + ha:flags { + clearline = 1 + } + y1 = 130.0mil + } + ha:line.17 { + clearance = 40.0mil + y2 = 130.0mil + thickness = 0.1mil + x1 = 226.8503937mil + x2 = 6.762mm + ha:flags { + clearline = 1 + } + y1 = 130.0mil + } + ha:line.20 { + clearance = 40.0mil + y2 = 130.0mil + thickness = 0.1mil + x1 = 6.762mm + x2 = 6.762mm + ha:flags { + clearline = 1 + } + y1 = 4.302mm + } + ha:line.23 { + clearance = 40.0mil + y2 = 260.0mil + thickness = 0.1mil + x1 = 6.762mm + x2 = 9.064mm + ha:flags { + clearline = 1 + } + y1 = 4.302mm + } + ha:line.56 { + x1=7.2796mm; y1=6.2339mm; x2=4.834137mm; y2=6.889159mm; thickness=0.1mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.65 { + x1=6.762mm; y1=4.302mm; x2=4.316537mm; y2=4.957259mm; thickness=0.1mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.68 { + x1=180.0mil; y1=4.888807mm; x2=5.093772mm; y2=6.836086mm; thickness=0.1mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.104 { + x1=7.2796mm; y1=234.09972441mil; x2=7.2796mm; y2=255.0mil; thickness=0.1mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.113 { + x1=300.0mil; y1=6.2339mm; x2=275.0mil; y2=6.2339mm; thickness=0.1mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.38 { + x=260.0mil; y=190.0mil; width=50.0mil; height=50.0mil; astart=118; adelta=39; thickness=0.1mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:text.83 { + string=1; x=210.0mil; y=50.0mil; scale=50; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.85 { + string=2; x=270.0mil; y=100.0mil; scale=50; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.87 { + string=3; x=310.0mil; y=180.0mil; scale=50; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.89 { + string=4; x=170.0mil; y=220.0mil; scale=50; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.91 { + string=5; x=300.0mil; y=250.0mil; scale=50; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.117 { + string=0; x=10.0mil; y=0.0; scale=50; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + color = {#000000} + group = 1 + ha:combining { + auto = 1 + } + } + ha:top-paste { + visible = 0 + lid = 8 + li:objects { + } + color = {#cd00cd} + group = 0 + ha:combining { + auto = 1 + } + } + ha:top-mask { + visible = 0 + lid = 9 + li:objects { + } + color = {#ff0000} + group = 2 + ha:combining { + sub = 1 + auto = 1 + } + } + ha:bottom-mask { + visible = 0 + lid = 10 + li:objects { + } + color = {#ff0000} + group = 11 + ha:combining { + sub = 1 + auto = 1 + } + } + ha:bottom-paste { + visible = 0 + lid = 11 + li:objects { + } + color = {#cd00cd} + group = 13 + ha:combining { + auto = 1 + } + } + } + } +} Index: tags/2.3.0/doc/user/06_feature/ddraft/src/coord_sys.lht =================================================================== --- tags/2.3.0/doc/user/06_feature/ddraft/src/coord_sys.lht (nonexistent) +++ tags/2.3.0/doc/user/06_feature/ddraft/src/coord_sys.lht (revision 33253) @@ -0,0 +1,362 @@ +ha:pcb-rnd-board-v5 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 2.0mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1.0mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 950.0mil + y = 925.0mil + } + 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 { } + visible=1 + + li:objects { + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + visible=1 + + li:objects { + } + color = {#104e8b} + } + + ha:bottom-gnd { + lid=3 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + color = {#cd3700} + } + + ha:int-sig2 { + lid=4 + group=7 + ha:combining { } + visible=1 + + li:objects { + } + color = {#548b54} + } + + ha:int-sig1 { + lid=5 + group=5 + ha:combining { } + visible=1 + + li:objects { + } + color = {#8b7355} + } + + ha:outline { + lid=6 + group=9 + ha:combining { } + visible=1 + + li:objects { + } + color = {#00868b} + } + + ha:bottom-silk { + lid=7 + group=12 + ha:combining { auto=1; } + visible=1 + + li:objects { + } + color = {#000000} + } + + ha:top-silk { + lid=8 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:line.5 { + x1=75.0mil; y1=175.0mil; x2=850.0mil; y2=175.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.19 { + x1=200.0mil; y1=50.0mil; x2=200.0mil; y2=825.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.32 { + x=325.0mil; y=175.0mil; width=400.0mil; height=400.0mil; astart=142; adelta=38; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.11 { clearance=40.0mil; + li:geometry { + ta:contour { + { 900.0mil; 175.0mil } + { 775.0mil; 150.0mil } + { 775.0mil; 200.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.22 { clearance=40.0mil; + li:geometry { + ta:contour { + { 200.0mil; 875.0mil } + { 225.0mil; 750.0mil } + { 175.0mil; 750.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.45 { clearance=40.0mil; + li:geometry { + ta:contour { + { 14.851175mm; 12.720308mm } + { 17.192442mm; 10.483721mm } + { 16.15212mm; 9.755279mm } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:text.26 { + string=0; x=150.0mil; y=100.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.27 { + string=+x; x=825.0mil; y=100.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.28 { + string=+y; x=125.0mil; y=775.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.49 { + string=+angle; x=700.0mil; y=425.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.51 { + string=0 deg; x=625.0mil; y=100.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + color = {#000000} + } + + ha:top-paste { + lid=9 + group=0 + ha:combining { auto=1; } + visible=0 + + li:objects { + } + color = {#cd00cd} + } + + ha:top-mask { + lid=10 + group=2 + ha:combining { sub=1; auto=1; } + visible=0 + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-mask { + lid=11 + group=11 + ha:combining { sub=1; auto=1; } + visible=0 + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-paste { + lid=12 + group=13 + ha:combining { auto=1; } + visible=0 + + li:objects { + } + color = {#cd00cd} + } + } + } + + + 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 { outline=1; } + li:layers { 6; } + } + 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; } + } + } + } +} Index: tags/2.3.0/doc/user/06_feature/ddraft/src/trim.lht =================================================================== --- tags/2.3.0/doc/user/06_feature/ddraft/src/trim.lht (nonexistent) +++ tags/2.3.0/doc/user/06_feature/ddraft/src/trim.lht (revision 33253) @@ -0,0 +1,474 @@ +ha:pcb-rnd-board-v5 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 2.0mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1.0mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 800.0mil + y = 27.305mm + } + 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 { } + visible=1 + + li:objects { + ha:line.14 { + x1=75.0mil; y1=325.0mil; x2=275.0mil; y2=325.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.17 { + x1=150.0mil; y1=225.0mil; x2=150.0mil; y2=425.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + selected=1 + } + } + ha:line.63 { + x1=75.0mil; y1=600.0mil; x2=275.0mil; y2=600.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.66 { + x1=150.0mil; y1=500.0mil; x2=150.0mil; y2=700.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + selected=1 + } + } + ha:line.69 { + x1=75.0mil; y1=900.0mil; x2=275.0mil; y2=900.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.72 { + x1=150.0mil; y1=800.0mil; x2=150.0mil; y2=1000.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + selected=1 + } + } + ha:line.203 { + x1=475.0mil; y1=325.0mil; x2=550.0mil; y2=325.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.206 { + x1=550.0mil; y1=225.0mil; x2=550.0mil; y2=425.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + selected=1 + } + } + ha:line.209 { + x1=475.0mil; y1=600.0mil; x2=15.575194mm; y2=600.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.212 { + x1=550.0mil; y1=500.0mil; x2=550.0mil; y2=700.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + selected=1 + } + } + ha:line.215 { + x1=15.575194mm; y1=900.0mil; x2=675.0mil; y2=900.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.218 { + x1=550.0mil; y1=800.0mil; x2=550.0mil; y2=1000.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + selected=1 + } + } + ha:line.221 { + x1=475.0mil; y1=900.0mil; x2=550.0mil; y2=900.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.75 { + x=325.0mil; y=700.0mil; width=150.0mil; height=150.0mil; astart=-90; adelta=90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + selected=1 + } + } + ha:arc.76 { + x=325.0mil; y=1000.0mil; width=150.0mil; height=150.0mil; astart=-90; adelta=90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + selected=1 + } + } + ha:arc.224 { + x=725.0mil; y=700.0mil; width=150.0mil; height=150.0mil; astart=-90; adelta=90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + selected=1 + } + } + ha:arc.225 { + x=725.0mil; y=1000.0mil; width=150.0mil; height=150.0mil; astart=-90; adelta=90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + selected=1 + } + } + ha:polygon.89 { clearance=40.0mil; + li:geometry { + ta:contour { + { 260.0mil; 400.0mil } + { 250.0mil; 350.0mil } + { 240.0mil; 400.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.93 { clearance=40.0mil; + li:geometry { + ta:contour { + { 260.0mil; 675.0mil } + { 250.0mil; 625.0mil } + { 240.0mil; 675.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.97 { clearance=40.0mil; + li:geometry { + ta:contour { + { 165.0mil; 825.0mil } + { 175.0mil; 875.0mil } + { 185.0mil; 825.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + visible=1 + + li:objects { + } + color = {#104e8b} + } + + ha:bottom-gnd { + lid=3 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + color = {#cd3700} + } + + ha:int-sig2 { + lid=4 + group=7 + ha:combining { } + visible=1 + + li:objects { + } + color = {#548b54} + } + + ha:int-sig1 { + lid=5 + group=5 + ha:combining { } + visible=1 + + li:objects { + } + color = {#8b7355} + } + + ha:bottom-silk { + lid=6 + group=12 + ha:combining { auto=1; } + visible=1 + + li:objects { + } + color = {#000000} + } + + ha:top-silk { + lid=7 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:line.238 { + x1=400.0mil; y1=25.0mil; x2=400.0mil; y2=26.67mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.253 { + x1=25.0mil; y1=150.0mil; x2=775.0mil; y2=150.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.259 { + x1=25.0mil; y1=475.0mil; x2=775.0mil; y2=475.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.262 { + x1=25.0mil; y1=750.0mil; x2=775.0mil; y2=750.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.265 { + x1=25.0mil; y1=26.67mm; x2=775.0mil; y2=26.67mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.268 { + x1=25.0mil; y1=25.0mil; x2=775.0mil; y2=25.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.271 { + x1=25.0mil; y1=25.0mil; x2=25.0mil; y2=26.67mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.274 { + x1=775.0mil; y1=25.0mil; x2=775.0mil; y2=26.67mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:text.20 { + string=Before; x=100.0mil; y=50.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.21 { + string=After; x=525.0mil; y=50.0mil; scale=100; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + color = {#000000} + } + + ha:top-paste { + lid=8 + group=0 + ha:combining { auto=1; } + visible=0 + + li:objects { + } + color = {#cd00cd} + } + + ha:top-mask { + lid=9 + group=2 + ha:combining { sub=1; auto=1; } + visible=0 + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-mask { + lid=10 + group=11 + ha:combining { sub=1; auto=1; } + visible=0 + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-paste { + lid=11 + group=13 + ha:combining { auto=1; } + visible=0 + + li:objects { + } + color = {#cd00cd} + } + } + } + + + + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { 8; } + } + ha:1 { + name = top_silk + ha:type { silk=1; top=1; } + li:layers { 7; } + } + ha:2 { + name = top_mask + ha:type { top=1; mask=1; } + li:layers { 9; } + } + 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 { outline=1; } + li:layers { } + } + 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 { 10; } + } + ha:12 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 6; } + } + ha:13 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 11; } + } + } + } +} Index: tags/2.3.0/doc/user/06_feature/ddraft/trim.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/ddraft/trim.png =================================================================== --- tags/2.3.0/doc/user/06_feature/ddraft/trim.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/ddraft/trim.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/ddraft/trim.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/diag/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/diag/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/diag/index.html (revision 33253) @@ -0,0 +1,18 @@ + + + + pcb-rnd user manual + + + + +

    Diag plugin

    +

    +Diag is a config POV setting, you can enable or disable it any time, +from gui, from cli, from config files, from actions. It's called +plugins/diag/auto_integrity - by default it's 0 (off); it runs when it's set to +1. +

    +The diagnostic plugin provides a dumpconf action to pcb-rnd. + + Index: tags/2.3.0/doc/user/06_feature/distalign/align_mixed_parts_x.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/distalign/align_mixed_parts_x.png =================================================================== --- tags/2.3.0/doc/user/06_feature/distalign/align_mixed_parts_x.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/distalign/align_mixed_parts_x.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/distalign/align_mixed_parts_x.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/distalign/align_parts_y.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/distalign/align_parts_y.png =================================================================== --- tags/2.3.0/doc/user/06_feature/distalign/align_parts_y.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/distalign/align_parts_y.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/distalign/align_parts_y.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/distalign/distalign.txt =================================================================== --- tags/2.3.0/doc/user/06_feature/distalign/distalign.txt (nonexistent) +++ tags/2.3.0/doc/user/06_feature/distalign/distalign.txt (revision 33253) @@ -0,0 +1,79 @@ +From: Ben Jackson +To: geda-user@moria.seul.org +Date: Sat, 24 Feb 2007 22:13:51 -0800 +Subject: The amazing Align/Distribute plugin + +Ok, having "finished" the smartdisperse plugin, I moved on to phase 2 +of my "I'm sick of moving LEDs by hand" master plan. + +Introducing Align() and Distribute(), which work much like the +similarly named functions in Visio. +Given that PCB does not have the concept of "first selected object" +to draw on, the reference points can be selected by arguments. + +Both functions always work on all selected elements[*]. + +Some examples: + +:Align(X) + +Objects are moved left/right to align their Marks with the Mark of +the topmost selected object. All objects remain on or move to the +current grid. + +:Align(Y,Centers) + +Now objects are aligned up/down to their geometric centers rather +than their marks. The reference point is the center of the leftmost +object. + +:Align(Y,Tops,Average,Gridless) + +Feeling bold, you align the tops all selected objects to the average +of their top edges and let them wander off the grid to exactly the +average of their tops. + +:Align(X,Marks,pcb_crosshair) + +None of the objects are where you want them, so you move the +crosshair to a likely spot and cause them all to move their X +coordinates to your new X location. + +:Align(X,Marks,Last) + +As above, but instead of the crosshair you just override the default +"First" to "Last" so the reference object is bottommost instead of +topmost. + + +Now you have them in a neat line, but they're all clumped! + +:Distribute(Y) + +Objects are spread out evenly from the first (uppermost) to last +using their marks as the reference point. + +:Distribute(X,Lefts,pcb_crosshair,Last) + +You move your crosshair to the left edge of the target area, which +will be the leftmost edge of the leftmost object. The objects are +spread between your crosshair and the original location of the Last +(rightmost) object. + +:Distribute(Y,Gaps) + +You have chosen to select many oddly sized objects, and instead of +their centers being spread out evenly, you want the space (or "gaps") +to be even. + +You get tricky and bind `Align(X,Marks,pcb_crosshair)' to a key. +Now you can select an object and hit your key and the object will +warp to the same X coordinate as your cursor. + +[*] If it has any flaws, it is that you can't operate non-element +objects, though some melding of autocrop (which knows how to do such +things) and distalign could produce such a capability. + +Ben Jackson AD7GD + +http://www.ben.com/ Index: tags/2.3.0/doc/user/06_feature/distalign/distribute_parts_x.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/distalign/distribute_parts_x.png =================================================================== --- tags/2.3.0/doc/user/06_feature/distalign/distribute_parts_x.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/distalign/distribute_parts_x.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/distalign/distribute_parts_x.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/distalign/distribute_y_gaps.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/distalign/distribute_y_gaps.png =================================================================== --- tags/2.3.0/doc/user/06_feature/distalign/distribute_y_gaps.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/distalign/distribute_y_gaps.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/distalign/distribute_y_gaps.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/distalign/import_parts.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/distalign/import_parts.png =================================================================== --- tags/2.3.0/doc/user/06_feature/distalign/import_parts.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/distalign/import_parts.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/distalign/import_parts.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/distalign/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/distalign/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/distalign/index.html (revision 33253) @@ -0,0 +1,75 @@ + + + + pcb-rnd user manual + + + + +

    Distalign plugin

    +
    +Two actions for aligning and distributing any objects in pcb-rnd +

    Action Syntax

    +

    +

    +Align(X/Y, [Lefts/Rights/Tops/Bottoms/Centers/Marks, [First/Last/pcb_crosshair/Average[, Gridless]]]) +

    +

    +Distribute(Y, [Lefts/Rights/Tops/Bottoms/Centers/Marks/Gaps, [First/Last/pcb_crosshair, First/Last/pcb_crosshair[, Gridless]]]) +

    Description

    +

    +

    +Align() aligns selected objects along the X or Y axis relative to the user specified reference point, . +

    +

    +Distribute() distributes selected objects relative to the specified reference point, evenly between the first, last, or to the pcb crosshair +

    +Both actions can be used with gridless options to place parts in off grid location + +

    Examples

    +

    +

    Build a linear array of tactile switch parts

    +

    + +
    Command descriptionimage + +
    import +
    Import an array of 8 TACT_6x6_4p footprints needed for a 1x8 grid.
    Place the first part at the exact X,Y coord to start the array
    Place the last part at the X position where the array will end +
    + +
    align(y) +
    The user aligns the TACT_6x6_4p footprints along a Y axis
    The center of the first part is the default reference point +
    + +
    distribute(x,centers,first,last) +
    Note user places last part in position
    Parts are distributed between the first and last along the X axis +
    +
    + +

    Align & distribute a mix of parts

    + +
    Command descriptionimage + +
    import +
    A small set of nonhomogenous parts are imported +
    n/a + +
    align(x,centers,last) +
    The parts are aligned to each other along an x axis with resepect to their centers
    The chosen x axis is determined from the 'last' part location +
    + +
    distribute(y,gaps) +
    The parts are evenly distibuted by the gaps between them +
    + +
    copy, align(), distribute() +
    The parts in the first step are copied to create an array
    The align and distribute commands are used for each row of the array in turn +
    +
    + +

    +See also: the original email that describes the plugin, +the dist/align action argument gallery (illustration). + + + Index: tags/2.3.0/doc/user/06_feature/distalign/result.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/distalign/result.png =================================================================== --- tags/2.3.0/doc/user/06_feature/distalign/result.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/distalign/result.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/distalign/result.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/Makefile =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/Makefile (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/Makefile (revision 33253) @@ -0,0 +1,50 @@ +PCB=../../src/pcb-rnd +HTML=index.html +CASES = \ + debumpify.$(TARGET) \ + miter.$(TARGET) \ + orthopull.$(TARGET) \ + unjaggy.$(TARGET) \ + vianudge.$(TARGET) \ + viatrim.$(TARGET) + +all: + $(MAKE) conv TARGET=out.png + $(MAKE) conv TARGET=png + $(MAKE) index + +index: + $(MAKE) index.html TARGET=txt + +index.html: Pre.html Post.html $(CASES) Makefile + cat Pre.html > $(HTML) + $(MAKE) conv TARGET=tbl + cat Post.html >>$(HTML) + +conv: $(CASES) + +.SUFFIXES: .pcb .out.pcb .png .out.png .tbl +.PRECIOUS: %.pcb %.out.pcb %.png %.out.png + +.pcb.out.pcb: + echo "OptAutoOnly(); djopt($*); SaveTo(LayoutAs, $*.out.pcb.tmp);"| $(PCB) --gui batch $*.pcb + awk '/Symbol.. . 1800./,/^Attribute/ { next } { print $$0 }' < $*.out.pcb.tmp > $*.out.pcb + rm $*.out.pcb.tmp + +.pcb.tbl: + echo '

$*'>>$(HTML) + cat $*.txt >>$(HTML) + echo ' '>>$(HTML) + +.pcb.png: + $(PCB) -x png --dpi 300 $*.pcb + +out.pcb.out.png: + $(PCB) -x png --dpi 300 $*.out.pcb + +clean: + rm *.out.pcb *.png index.html 2>/dev/null; true + + + + Index: tags/2.3.0/doc/user/06_feature/djopt/Post.html =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/Post.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/Post.html (revision 33253) @@ -0,0 +1,4 @@ +
autorun all the above except miter; run them multiple times until there's no more change possible     +
+ + Index: tags/2.3.0/doc/user/06_feature/djopt/Pre.html =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/Pre.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/Pre.html (revision 33253) @@ -0,0 +1,14 @@ + + +

Action djopt()

+ +The different types of optimizations change your board in order to +reduce the total trace length and via count. Each optimization is accessible +using an argument, e.g. djopt(miter). The basic actions have to be run multiple +times as each iteration will change the design making new changes possible for +subsequent iterations with the same or other actions. +

+Click on the images to download the example .pcb design. + + +
argument name description example in example out after 1st iteration Index: tags/2.3.0/doc/user/06_feature/djopt/debumpify.out.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/debumpify.out.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/debumpify.out.pcb (revision 33253) @@ -0,0 +1,88 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[2500.0 0 0 1] +Cursor[0 5000 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 17500 32500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R102" "1206" 117500 32500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) +Layer(1 "component") +( + Line[23405 32500 30000 32500 1000 4000 "clearline"] + Line[92500 32500 111595 32500 1000 4000 "clearline"] + Line[30000 32500 30000 32500 1000 4000 "clearline"] + Line[30000 32500 37500 32500 1000 4000 "clearline"] + Line[37500 32500 37500 32500 1000 4000 "clearline"] + Line[37500 32500 47500 32500 1000 4000 "clearline"] + Line[47500 32500 57500 22500 1000 4000 "clearline"] + Line[57500 22500 67500 22500 1000 4000 "clearline"] + Line[67500 22500 77500 32500 1000 4000 "clearline"] + Line[77500 32500 82500 32500 1000 4000 "clearline"] + Line[82500 32500 85000 22500 1000 4000 "clearline"] + Line[90000 22500 92500 32500 1000 4000 "clearline"] + Line[85000 22500 90000 22500 1000 4000 "clearline"] +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( + Text[30000 5000 0 105 "90" "clearline"] + Text[60000 5000 0 105 "45" "clearline"] + Text[82500 5000 0 105 "rand" "clearline"] +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/debumpify.out.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/debumpify.out.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/debumpify.out.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/debumpify.out.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/debumpify.out.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/debumpify.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/debumpify.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/debumpify.pcb (revision 33253) @@ -0,0 +1,89 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[2500.0 0 0 1] +Cursor[0 5000 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Attribute("PCB::grid::unit" "mm") + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 17500 32500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R102" "1206" 117500 32500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) +Layer(1 "component") +( + Line[23405 32500 30000 32500 1000 4000 "clearline"] + Line[92500 32500 111595 32500 1000 4000 "clearline"] + Line[30000 32500 30000 22500 1000 4000 "clearline"] + Line[30000 22500 37500 22500 1000 4000 "clearline"] + Line[37500 22500 37500 32500 1000 4000 "clearline"] + Line[37500 32500 47500 32500 1000 4000 "clearline"] + Line[47500 32500 57500 22500 1000 4000 "clearline"] + Line[57500 22500 67500 22500 1000 4000 "clearline"] + Line[67500 22500 77500 32500 1000 4000 "clearline"] + Line[77500 32500 82500 32500 1000 4000 "clearline"] + Line[82500 32500 85000 22500 1000 4000 "clearline"] + Line[90000 22500 92500 32500 1000 4000 "clearline"] + Line[85000 22500 90000 22500 1000 4000 "clearline"] +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( + Text[30000 5000 0 105 "90" "clearline"] + Text[60000 5000 0 105 "45" "clearline"] + Text[82500 5000 0 105 "rand" "clearline"] +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/debumpify.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/debumpify.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/debumpify.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/debumpify.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/debumpify.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/debumpify.txt =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/debumpify.txt (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/debumpify.txt (revision 33253) @@ -0,0 +1,2 @@ +Looks for U-shaped traces (with 90 degree corners) that can be shortened +or eliminated. Index: tags/2.3.0/doc/user/06_feature/djopt/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/index.html (revision 33253) @@ -0,0 +1,45 @@ + + +

Action djopt()

+ +The different types of optimizations change your board in order to +reduce the total trace length and via count. Each optimization is accessible +using an argument, e.g. djopt(miter). The basic actions have to be run multiple +times as each iteration will change the design making new changes possible for +subsequent iterations with the same or other actions. +

+Click on the images to download the example .pcb design. + + +
argument name description example in example out after 1st iteration +
debumpify +Looks for U-shaped traces (with 90 degree corners) that can be shortened +or eliminated. + +
miter +Replaces 90 degree corners with a pair of 45 degree corners, to reduce +RF losses and trace length. + +
orthopull +Looks for chains of traces all going in one direction, with more +traces orthogonal on one side than on the other. Moves the chain in +that direction, causing a net reduction in trace length, possibly +eliminating traces and/or corners. + +
unjaggy +Looks for corners which could be flipped to eliminate one or more +corners (i.e. jaggy lines become simpler). + +
vianudge +Looks for vias where all traces leave in the same direction. Tries to +move via in that direction to eliminate one of the traces (and thus a +corner). + +
viatrim +Looks for traces that go from via to via, where moving that trace to a +different layer eliminates one or both vias. + +
autorun all the above except miter; run them multiple times until there's no more change possible     +
+ + Index: tags/2.3.0/doc/user/06_feature/djopt/miter.out.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/miter.out.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/miter.out.pcb (revision 33253) @@ -0,0 +1,75 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[500.0 0 0 1] +Cursor[500 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 45000 15000 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R102" "1206" 80000 47500 -4350 -5650 3 100 ""] +( + Pad[-1181 5905 1181 5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "2" "2" "square"] + ElementLine [-3740 -2362 -3740 2362 800] + ElementLine [3740 -2362 3740 2362 800] + + ) +Layer(1 "component") +( + Line[50905 15000 53405 15000 1000 4000 "clearline"] + Line[80000 41595 80000 41595 1000 4000 "clearline"] + Line[53405 15000 80000 41595 1000 4000 "clearline"] +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/miter.out.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/miter.out.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/miter.out.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/miter.out.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/miter.out.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/miter.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/miter.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/miter.pcb (revision 33253) @@ -0,0 +1,80 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[500.0 0 0 1] +Cursor[500 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + + +Attribute("PCB::grid::unit" "mil") + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 45000 15000 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R102" "1206" 80000 47500 -4350 -5650 3 100 ""] +( + Pad[-1181 5905 1181 5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "2" "2" "square"] + ElementLine [-3740 -2362 -3740 2362 800] + ElementLine [3740 -2362 3740 2362 800] + + ) +Layer(1 "component") +( + Line[50905 15000 80000 15000 1000 4000 "clearline"] + Line[80000 15000 80000 41595 1000 4000 "clearline"] + Line[81181 41595 80000 41595 1000 4000 "clearline"] + Line[80000 41595 78819 41595 1000 4000 "clearline"] + Line[50905 16181 50905 15000 1000 4000 "clearline"] + Line[50905 15000 50905 13819 1000 4000 "clearline"] +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/miter.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/miter.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/miter.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/miter.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/miter.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/miter.txt =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/miter.txt (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/miter.txt (revision 33253) @@ -0,0 +1,2 @@ +Replaces 90 degree corners with a pair of 45 degree corners, to reduce +RF losses and trace length. Index: tags/2.3.0/doc/user/06_feature/djopt/orthopull.out.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/orthopull.out.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/orthopull.out.pcb (revision 33253) @@ -0,0 +1,99 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[2500.0 0 0 1] +Cursor[47500 32500 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + + +Element["" "Standard SMT resistor, capacitor etc" "R102" "1206" 52500 10000 4350 5650 1 100 ""] +( + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 5905 1181 5905 5118 2000 5718 "2" "2" "square"] + ElementLine [3740 -2362 3740 2362 800] + ElementLine [-3740 -2362 -3740 2362 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R103" "1206" 72500 10000 4350 5650 1 100 ""] +( + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 5905 1181 5905 5118 2000 5718 "2" "2" "square"] + ElementLine [3740 -2362 3740 2362 800] + ElementLine [-3740 -2362 -3740 2362 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R104" "1206" 62500 52500 -4350 -5650 3 100 ""] +( + Pad[-1181 5905 1181 5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "2" "2" "square"] + ElementLine [-3740 -2362 -3740 2362 800] + ElementLine [3740 -2362 3740 2362 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 35000 10000 -4350 -5650 3 100 ""] +( + Pad[-1181 5905 1181 5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "2" "2" "square"] + ElementLine [-3740 -2362 -3740 2362 800] + ElementLine [3740 -2362 3740 2362 800] + + ) +Layer(1 "component") +( + Line[52500 15905 52500 22500 1000 4000 "clearline"] + Line[72500 15905 72500 22500 1000 4000 "clearline"] + Line[62500 46595 62500 22500 1000 4000 "clearline"] + Line[35000 22500 52500 22500 1000 4000 "clearline"] + Line[35000 22500 35000 15905 1000 4000 "clearline"] + Line[62500 22500 72500 22500 1000 4000 "clearline"] + Line[52500 22500 62500 22500 1000 4000 "clearline"] +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + Connect("R103-2") + Connect("R104-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/orthopull.out.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/orthopull.out.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/orthopull.out.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/orthopull.out.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/orthopull.out.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/orthopull.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/orthopull.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/orthopull.pcb (revision 33253) @@ -0,0 +1,98 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[2500.0 0 0 1] +Cursor[47500 32500 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Attribute("PCB::grid::unit" "mm") + +Element["" "Standard SMT resistor, capacitor etc" "R102" "1206" 52500 10000 4350 5650 1 100 ""] +( + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 5905 1181 5905 5118 2000 5718 "2" "2" "square"] + ElementLine [3740 -2362 3740 2362 800] + ElementLine [-3740 -2362 -3740 2362 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R103" "1206" 72500 10000 4350 5650 1 100 ""] +( + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 5905 1181 5905 5118 2000 5718 "2" "2" "square"] + ElementLine [3740 -2362 3740 2362 800] + ElementLine [-3740 -2362 -3740 2362 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R104" "1206" 62500 52500 -4350 -5650 3 100 ""] +( + Pad[-1181 5905 1181 5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "2" "2" "square"] + ElementLine [-3740 -2362 -3740 2362 800] + ElementLine [3740 -2362 3740 2362 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 35000 10000 -4350 -5650 3 100 ""] +( + Pad[-1181 5905 1181 5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "2" "2" "square"] + ElementLine [-3740 -2362 -3740 2362 800] + ElementLine [3740 -2362 3740 2362 800] + + ) +Layer(1 "component") +( + Line[52500 15905 52500 37500 1000 4000 "clearline"] + Line[72500 15905 72500 37500 1000 4000 "clearline"] + Line[62500 46595 62500 37500 1000 4000 "clearline"] + Line[35000 37500 72500 37500 1000 4000 "clearline"] + Line[35000 37500 35000 15905 1000 4000 "clearline"] +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + Connect("R103-2") + Connect("R104-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/orthopull.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/orthopull.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/orthopull.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/orthopull.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/orthopull.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/orthopull.txt =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/orthopull.txt (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/orthopull.txt (revision 33253) @@ -0,0 +1,4 @@ +Looks for chains of traces all going in one direction, with more +traces orthogonal on one side than on the other. Moves the chain in +that direction, causing a net reduction in trace length, possibly +eliminating traces and/or corners. Index: tags/2.3.0/doc/user/06_feature/djopt/unjaggy.out.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/unjaggy.out.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/unjaggy.out.pcb (revision 33253) @@ -0,0 +1,79 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[2500.0 0 0 1] +Cursor[12500 10000 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 17500 32500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R102" "1206" 65000 12500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) +Layer(1 "component") +( + Line[23405 32500 37500 32500 1000 4000 "clearline"] + Line[37500 32500 37500 15000 1000 4000 "clearline"] + Line[37500 15000 37500 15000 1000 4000 "clearline"] + Line[37500 32500 37500 32500 1000 4000 "clearline"] + Line[37500 15000 45000 15000 1000 4000 "clearline"] + Line[45000 15000 45000 10000 1000 4000 "clearline"] + Line[45000 10000 59095 10000 1000 4000 "clearline"] +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/unjaggy.out.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/unjaggy.out.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/unjaggy.out.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/unjaggy.out.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/unjaggy.out.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/unjaggy.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/unjaggy.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/unjaggy.pcb (revision 33253) @@ -0,0 +1,81 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[2500.0 0 0 1] +Cursor[12500 10000 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + + +Attribute("PCB::grid::unit" "mm") + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 17500 32500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R102" "1206" 65000 12500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) +Layer(1 "component") +( + Line[23405 32500 30000 32500 1000 4000 "clearline"] + Line[30000 22500 37500 22500 1000 4000 "clearline"] + Line[37500 22500 37500 15000 1000 4000 "clearline"] + Line[30000 32500 30000 22500 1000 4000 "clearline"] + Line[37500 15000 45000 15000 1000 4000 "clearline"] + Line[45000 15000 45000 10000 1000 4000 "clearline"] + Line[45000 10000 56595 10000 1000 4000 "clearline"] +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/unjaggy.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/unjaggy.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/unjaggy.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/unjaggy.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/unjaggy.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/unjaggy.txt =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/unjaggy.txt (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/unjaggy.txt (revision 33253) @@ -0,0 +1,2 @@ +Looks for corners which could be flipped to eliminate one or more +corners (i.e. jaggy lines become simpler). Index: tags/2.3.0/doc/user/06_feature/djopt/vianudge.out.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/vianudge.out.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/vianudge.out.pcb (revision 33253) @@ -0,0 +1,79 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[2500.0 0 0 1] +Cursor[17500 22500 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Via[85000 27500 8661 4000 0 3937 "" ""] + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 57500 10000 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) + +Element["onsolder" "Standard SMT resistor, capacitor etc" "R102" "1206" 10000 10000 5650 4350 2 100 "auto"] +( + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "1" "1" "onsolder,square"] + Pad[5905 -1181 5905 1181 5118 2000 5718 "2" "2" "onsolder,square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) +Layer(1 "component") +( + Line[63405 10000 85000 10000 1000 4000 "clearline"] + Line[85000 10000 85000 27500 1000 4000 "clearline"] +) +Layer(2 "solder") +( + Line[15905 10000 30000 10000 2000 4000 "clearline"] + Line[30000 10000 30000 27500 2000 4000 "clearline"] + Line[30000 27500 85000 27500 2000 4000 "clearline"] + Line[85000 27500 85000 27500 2000 4000 "clearline"] +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/vianudge.out.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/vianudge.out.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/vianudge.out.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/vianudge.out.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/vianudge.out.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/vianudge.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/vianudge.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/vianudge.pcb (revision 33253) @@ -0,0 +1,81 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[2500.0 0 0 1] +Cursor[17500 22500 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + + +Attribute("PCB::grid::unit" "mm") +Via[85000 50000 8661 4000 0 3937 "" ""] + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 57500 10000 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) + +Element["onsolder" "Standard SMT resistor, capacitor etc" "R102" "1206" 10000 10000 5650 4350 2 100 "auto"] +( + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "1" "1" "onsolder,square"] + Pad[5905 -1181 5905 1181 5118 2000 5718 "2" "2" "onsolder,square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) +Layer(1 "component") +( + Line[63405 10000 85000 10000 1000 4000 "clearline"] + Line[85000 10000 85000 50000 1000 4000 "clearline"] +) +Layer(2 "solder") +( + Line[15905 10000 30000 10000 2000 4000 "clearline"] + Line[30000 10000 30000 27500 2000 4000 "clearline"] + Line[30000 27500 85000 27500 2000 4000 "clearline"] + Line[85000 50000 85000 27500 2000 4000 "clearline"] +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/vianudge.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/vianudge.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/vianudge.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/vianudge.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/vianudge.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/vianudge.txt =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/vianudge.txt (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/vianudge.txt (revision 33253) @@ -0,0 +1,3 @@ +Looks for vias where all traces leave in the same direction. Tries to +move via in that direction to eliminate one of the traces (and thus a +corner). Index: tags/2.3.0/doc/user/06_feature/djopt/viatrim.out.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/viatrim.out.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/viatrim.out.pcb (revision 33253) @@ -0,0 +1,80 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[2500.0 0 0 1] +Cursor[37500 10000 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Via[60000 32500 7874 4000 0 3150 "" ""] +Via[92500 32500 7874 4000 0 3150 "" ""] +Via[75000 32500 7874 4000 0 3150 "" ""] + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 17500 32500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R102" "1206" 117500 32500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) +Layer(1 "component") +( + Line[23405 32500 60000 32500 1000 4000 "clearline"] + Line[92500 32500 111595 32500 1000 4000 "clearline"] + Line[60000 32500 60000 32500 1000 4000 "clearline"] + Line[60000 32500 75000 32500 1000 4000 "clearline"] +) +Layer(2 "solder") +( + Line[75000 32500 92500 32500 1000 4000 "clearline"] +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/viatrim.out.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/viatrim.out.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/viatrim.out.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/viatrim.out.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/viatrim.out.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/viatrim.pcb =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/viatrim.pcb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/viatrim.pcb (revision 33253) @@ -0,0 +1,87 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 140000 67500] + +Grid[2500.0 0 0 1] +Cursor[37500 10000 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + + +Attribute("PCB::grid::unit" "mm") +Via[60000 32500 7874 4000 0 3150 "" ""] +Via[92500 32500 7874 4000 0 3150 "" ""] +Via[75000 32500 7874 4000 0 3150 "" ""] +Via[40000 32500 7874 4000 0 3150 "" ""] + +Element["" "Standard SMT resistor, capacitor etc" "R101" "1206" 17500 32500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R102" "1206" 117500 32500 -5650 4350 0 100 ""] +( + Pad[5905 -1181 5905 1181 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -1181 -5905 1181 5118 2000 5718 "2" "2" "square"] + ElementLine [-2362 3740 2362 3740 800] + ElementLine [-2362 -3740 2362 -3740 800] + + ) +Layer(1 "component") +( + Line[23405 32500 40000 32500 1000 4000 "clearline"] + Line[92500 32500 111595 32500 1000 4000 "clearline"] + Line[111595 33681 111595 32500 1000 4000 "clearline"] + Line[111595 32500 111595 31319 1000 4000 "clearline"] + Line[23405 33681 23405 32500 1000 4000 "clearline"] + Line[23405 32500 23405 31319 1000 4000 "clearline"] + Line[40000 32500 60000 32500 1000 4000 "clearline"] +) +Layer(2 "solder") +( + Line[60000 32500 75000 32500 1000 4000 "clearline"] + Line[75000 32500 92500 32500 1000 4000 "clearline"] +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) +NetList() +( + Net("GND" "(unknown)") + ( + Connect("R101-1") + Connect("R102-2") + ) +) Index: tags/2.3.0/doc/user/06_feature/djopt/viatrim.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/djopt/viatrim.png =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/viatrim.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/viatrim.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/djopt/viatrim.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/djopt/viatrim.txt =================================================================== --- tags/2.3.0/doc/user/06_feature/djopt/viatrim.txt (nonexistent) +++ tags/2.3.0/doc/user/06_feature/djopt/viatrim.txt (revision 33253) @@ -0,0 +1,2 @@ +Looks for traces that go from via to via, where moving that trace to a +different layer eliminates one or both vias. Index: tags/2.3.0/doc/user/06_feature/drc_query/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/drc_query/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/drc_query/index.html (revision 33253) @@ -0,0 +1,255 @@ + + + + pcb-rnd user manual + + + + +

drc_query: query() based, scriptable Design Rule Checker

+

+The drc_query plugin is a glue layer between the +query plugin and the DRC infrastructure. It allows the +user (and sch import flows) to script DRC checks and use these script as part +of the normal DRC workflow. This chapter describes the +how to configure and use query() based DRC scripts +and offers a tutorial on developing DRC scripts. + +

Configuration

+

+DRC rules are specified as a list of hash nodes under the plugins/drc_query/rules +config path, from the config source of the user's choice. Commonly used config +sources: +

    +
  • internal or system config: generic DRC rules +
  • user config: generic, user maintained rules (extra default checks) +
  • board file: board-specific rules, e.g. imported from the schematics +
+

+Example 1: a full example of an user config, saved as ~/.pcb-rnd/drc_query.conf: +

+li:pcb-rnd-conf-v1 {
+  ha:overwrite {
+    ha:plugins {
+      ha:drc_query {
+        li:definitions {
+          ha:min_drill {
+            type = coord
+            desc = {minimum drill diameter}
+            default = 0
+          }
+        }
+        li:rules {
+          ha:hole_dia {
+            type = single hole
+            title = hole too small
+            desc = padstack hole diameter is too small
+            disable = 0
+            query = {(@.hole > 0) && (@.hole < $min_drill)}
+          }
+        }
+      }
+    }
+  }
+}
+
+

+There are two main subtrees below ha:drc_query: definitions and rules. +

Definitions

+

+Definitions create new config nodes under design/drc. These config nodes +can be used to configure parameters of the drc check. The order of +definitions does not matter but the name of each definition must be unique. +

+A definition is a named hash subtree with the following fields: + +
name mandatory meaning +
type yes data type of the configuration; one of: coord, boolean, integer, real, unit, color +
desc no human readable description +
default no low priority default value (format depends on type) for the case the configuration node is not set +
legacy no reserved for stock rules for compatibility with the old DRC, do not use in new rules +
+

+The definition in the above example creates config node design/drc/min_drill. +This new config node is accessible through the config system normally, through +the conf() action or the GUI (preferences dialog). From query(), it can +be referenced using the shorthand $min_dirll form. + + +

Rules

+

+Text fields type, tilte and desc are optional user readable strings +that will be presented in the DRC report. The type::title pair serves +as an unique identifier for the rule. If optional disable is 'yes' or +'true' or a non-zero integer value, the rule is temporarily disabled. +

+Note: since drc errors are presented on a per type basis, and drc rules +are executed each in its own, independent context, the order of the hash +nodes within the rules list (merged from different config sources) +determines the order in which tests are performed, but otherwise does not +matter (as tests are independent). +

+Rules optionally can have a source field, which is a one word free form text, +indicating where the rule is coming from. User specified/configured rules +should leave this field empty. Rules imported from the netlist (or schematics) +should set this field to netlist. When present, the GUI will display rules from +the same source groupped. But the real purpose of the source field is to make +re-import of rules possible: when a new import from the same source is performed, +the import code should remove all rules coming from the source and create +new rules with the same source. +

+Query text may consists of multiple lines. The format is as described +at the query plugin. There are two alternate forms: +

    +
  • a single expression (like in the example above); if the expression is + true, the last evaluated object (typically @) is marked as the DRC error +
  • one or more rule constructs, each containing let and assert + statements; when an assert is true, the object(s) in the return value or + if that is not available, the last evaluated object is marked as the + DRC error. +
+

+Example 2: a rule based query script example is finding overlapping drilled holes: +

+query = {
+  rule overlap
+  let A @.type==PSTK
+  let B A
+  assert (A.ID > B.ID) && (distance(A.x, A.y, B.x, B.y) < (A.hole + B.hole)/2) thus violation(DRCGRP1, A, DRCGRP2, B)
+}
+
+

+Note: since drc errors are presented on a per type basis, and drc rules +are executed each in its own, independent context, the order of rules does not +matter. + +

Tutorial

+ +

Single expression scripts

+

+In Example 1, a single query() expression is used: it iterates through all +objects available (@) and evaluates whether the object's hole property is +smaller than a predefined value. This expression can result in three +different outcome for any object: +

    +
  • invalid: e.g. when the object has no hole property because it is not + a padstack (this happens to all lines for example); in this case, no DRC + violation is reported +
  • valid, false: no DRC violation is reported +
  • valid, true: a DRC violation is reported +
+

+Such simple, single-expression DRC rules are common for checks that need +to decide whether every single object matching some criteria passes a test +on its properties. It works for Example 1 because each padstack object +can be checked separately from any other object and the outcome of +a check depends only on properties of the single padstack object and constants. +There is only one iterator used, @, which iterates on all objects of the board. +

+Note: the left-side check of && for hole diameter greater than zero +is needed because of the pcb-rnd data model: hole diameter zero means no hole +(e.g. smd pads) - no warning should be issued for that. + +

Rule scripts

+

+However, in some situations a DRC violation depends on two or more objects, +thus iterations need to be done on pairs (or tuplets) of objects. It is +done by: +

    +
  • announcing a multi-statement rule +
  • creating named lists of selected objects using the let statement +
  • writing one or more assert statements with expression using @ and/or the lists +
+

+Example 2 demonstrates a simple case of pair-wise iteration: first a list called +A is set up; it will contain all objects of the board whose type is PSTK. +Then list A is copied to B in the second let. +

+Note: the second argument of a let is always an expression. In +the first case it is more trivial: (@.type==PSTK). When this expression is +true, the last evaluated object (the current iteration with @) is appended +to the destination list (specified in the first argument). The second +let "copies" the list by expression (A). It really means: +having the iterator run on each item of A, evaluating each; they +will all be true (since they are existing objects); once an item is true, +the last evaluated object (the same that caused the expression to be true) +is appended to the left side-list B. The part that may be confusing +is this: on the left side, there's a list name, on the right side +there is an expression. Referencing a list within an expression +will always result in iteration and is always substituted by a single item +of the list. +

+Once the lists are set up, an assert is specified with an expression +that uses both A and B. This makes the query engine iterate +in nested loops for items of A and B, which means the expression +is evaluated to every possible pair of items in list A and list B. +

+Or in other words, any possible pair of padstacks on the board - including +the case of a virtual pair of the same padstack twice (since every padstack +is present on both lists). For example if the board has three padstacks +p1, p2 and p3, then A is [p1, p2, p3] and B is [p1, p2, p3] +too. The first iteration will take the first item of A and the +first item of B, so the pairing is p1 vs. p1. Avoiding such +false checks is easy by starting the assert expession by (A != B), +which will make the whole expression false for the virtual pair case. +

+Note: query has lazy evaluation so when the left side of an && if +false, the right side is not evaluated. This it makes execution more +efficient to add such simple checks that limit the number of objects or +combinations to deal with as early as possible in the expression. +

+With that, we would be checking the same pairs twice still: p1 vs. p2 +and then p2 vs. p1. The easiest way to avoid that is to consider +that each object has an unique integer ID that can be compared, which +allows us to write (A.ID > B.ID) instead od (A != B). This ensures +only 'ordered pairs' are considered, at about the same low cost of +check. +

+The left side of the && filters duplicates and self-overlaps. The +right side is the actual check: it calculates the distance of the hole +centers using the distance() builtin function and compares the result +to the expected minimum distance which is the sum of the radii of the two +holes. Since a hole is always at the origin of the padstack, the hole's +center coordinate matches the padstack's coordinate. When A.x is written +in the expression, that really means: "take the object from list A +for the current iteration and extract its x property", which for +a padstack means the x coordinate of the padstack placement. +

+When both the left side and the right side of the && evaluates to +true, that means the pair is valid and unique and the holes overlap. At +this point drc_query could already indicate the DRC violation, but it would +use the last evaulated object for indicating the location. Which means +the indication would mark only one of the two padstacks participating in the +overlap. +

+The thus keyword changes this: when the left side of thus +evaluates to true, instead of returning true, the right side is evaluated +and returned. The right side is a function call to the builtin function +violation, which will create a new list of instruction-objects pairs, +inserting the current iteration object from list A as group-1 object +and list B as group-2 object. In other words, it's +a list of the two padstack objects participating in the overlap, sorted into +two groups (red and blue on screen). +

+Call arguments for violation() are always pairs of a DRC* constant and an +object or numeric value. There can be 1 or more pairs. +The following DRC* constants can be used: + +
name meaning +
DRCGRP1 following object is in group-1 of offending objects +
DRCGRP2 following object is in group-2 of offending objects +
DRCEXPECT following numeric constant is DRC-expected value (e.g. minimum or maximum) +
DRCMEASURE following numeric constant is the measured value (that contradicts the expected value) +
DRCTEXT following string or value is appended to the violation description as plain text +
+

+Using any of the above instructions is optional, with the following considerations: +

    +
  • if a DRC rule is related to any drawing object, at least one + object should be listed as DRCGRP1 so that the user can identify + the location of the problem +
  • if DRCMEASURE is specified, DRCEXPECT must also be specified, else + DRCMEASURE is ignored +
  • order of instructions does not matter, except for: when multiple + DRCTEXT items are specified, their order is preserved +
Index: tags/2.3.0/doc/user/06_feature/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/index.html (revision 33253) @@ -0,0 +1,59 @@ + + + + pcb-rnd user manual + + + + + +

6. Feature Plugins

+These plugins have a wide variety of origins and offer a likewise wide variety +of actions to the pcb-rnd user. + + Index: tags/2.3.0/doc/user/06_feature/polystitch/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/polystitch/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/polystitch/index.html (revision 33253) @@ -0,0 +1,25 @@ + + + + pcb-rnd user manual + + + + +

Polystitch plugin

+

+This plugin is intended as a workaround for a bug in pstoedit. Pstodeit +generates polygons instead of polygon holes. This plugin creates a polystitch +action that can fix up that case. The polystitch action shall be ran while +the crosshair is over the inner polygon of two overlapping polygons. The action +takes the inner polygon and converts it into a hole within the outer polygon +then removes the inner polygon. +

+The plugin assumes that there are only two polygons under the crosshair and +the inner polygon is fully within the outer polygon. +

+The thindraw or wireframe view mode may be of help in searching such +overlapping polygons. + + + Index: tags/2.3.0/doc/user/06_feature/query/functions.html =================================================================== --- tags/2.3.0/doc/user/06_feature/query/functions.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/query/functions.html (revision 33253) @@ -0,0 +1,380 @@ + + + +

Query: advanced search, command line: function calls available

+

+Functions listed below can be called from a query expression. + +

List manipulation

+ +

llen(lst)

+

+ Determine length of a list. +

+ Arguments: +

    +
  • lst is the list (should be written as list(lst) to make sure no iteration is done) +
+

+ Return value: integer length of the list. + + +

mklist(args...)

+

+ Determine length of a list. +

+ Arguments: +

+ Variable number of objects. +

+ Return value: a list built of the objects passed. + +

layerlist()

+

+ Returns a list of all layers. + + +

Math & abstract geometry

+ +

distance(x1, y1, x2, y2)

+

+ Calculate the distance of two points. +

+ Arguments: +

    +
  • x1: first point, X coordinate +
  • y1: first point, Y coordinate +
  • x2: second point, X coordinate +
  • y2: second point, Y coordinate +
+

+ Return value: floating point distance value in nanometers. + + +

abs(number)

+

+ Returns the absolute value of a number + +

int(arg)

+

+ Returns the argument converted to an integer (truncating floating point numbers) + +

double(arg)

+

+ Returns the argument converted to a double precision number. + +

Object geometry

+ +

overlap(obj1, obj2, [bloat])

+

+ Returns 1 if obj1 and obj2 overlap (even if they are on different layers) +

+ Arguments: +

    +
  • obj1 and obj2 are objects; +
  • an optional bloat value, in coords: bloat up (or shrink, if negative) one of the objects by this value before the test. +
+

+ Return value: 1 for overlap, 0 for no overlap. + +

intersect(obj1, obj2, [bloat])

+

+ Returns 1 if obj1 and obj2 intersect (must share a layer) +

+ Arguments: +

    +
  • obj1 and obj2 are objects; +
  • an optional bloat value, in coords: bloat up (or shrink, if negative) one of the objects by this value before the test. +
+

+ Return value: 1 for intersection, 0 for no overlap. + +

pstkring(pstk, minimum_ring_thickness)

+

+ Return the number of layers on which the ring of a padstack is too thin. +

+ Arguments: +

    +
  • pstk is the padstack object +
  • minimum_ring_thickness is a coordinate value of the minimum ring thickness +
+

+ Return value: negative on wrong arguments, 0 if the padstack does not violate + the minimum_ring_thickness requirement, positive integer (number of violations) + otherwise. + + +

Networks

+ +

netlist()

+

+ Return the netlist. +

+ Arguments: None. +

+ Return value: an unordered list of all networks specified on the + edited netlist (which is the netlist the board is currently + using). Each item of the list is a net. + + +

netterms(net)

+

+ Return terminals of a network. +

+ Arguments: +

    +
  • net is a network of the netlist of the current board. +
+

+ Return value: an unordered list of objects (each terminal of the network + as described by the edited netlist). + + +

netobjs(net)

+

+ Return terminals and all copper objects galvanically connected to a network. +

+ Arguments: +

    +
  • net is a network of the netlist of the current board. +
+

+ Return value: an unordered list of copper objects connected to the network. + + +

netsegs(net)

+

+ Return a list of objects, one terminal object per disconnecte segment of + the network. +

+ Arguments: +

    +
  • net is a network of the netlist of the current board. +
+

+ Return value: an unordered list of terminal objects, one picked randomly + from each disconnected segment of the net. + + +

netbreak(obj, minimum_overlap)

+

+ Start a search on a galvanically connected network segment starting from + an object (typically returned by netsegs()) and generate a DRC violation + if there are copper objects with overlap smaller than the minimum_overlap. +

+ Arguments: +

    +
  • obj is the starting object of the search +
  • minimum_overlap is the coordinate value that represents the minimum required ovlerap between copper objects (e.g. 0.5mm) +
+

+ Return value: a list that represents a DRC violation (or empty list). + +

netshort(obj, minimum_distance)

+

+ Start a search on a galvanically connected network segment starting from + an object (typically returned by netsegs()) and generate a DRC violation + if there are disconnected copper objects with distance smaller than + the minimum_distance from the network. +

+ Arguments: +

    +
  • obj is the starting object of the search +
  • minimum_distance is the coordinate value that represents the minimum required distance from any non-connected copper objects (e.g. 0.5mm) +
+

+ Return value: a list that represents a DRC violation (or empty list). + +

netlen(net)

+

+ Return the length of a 2-terminal network. +

+ Arguments: net object or net name. +

+ Return value: network length. + + +

Object accessors

+ +

subcobjs(subc)

+

+ Return a list of objects that are within the subc. +

+ Arguments: +

    +
  • subc is an object of type subcircuit +
+

+ Return value: an unordered list of objects. + + +

poly_num_islands(poly)

+

+ Return the number of visible polygon islands. +

+ Arguments: +

    +
  • poly is the polygon object +
+

+ Return value: 0 if the polygon has been cleared out of existnece, 1 for normal + polygons and a positive integer higher than 1 if the polygon has the FULLPOLY + flag and is sliced into multiple parts not naturally connected by the polygon + itself. + +

thermal_on(tobj, lobj)

+

+ Return a string description of thermals of tobj on layer corrseponding to lobj. +

+ Arguments: +

    +
  • tobj is the object whose thermals are being queried +
  • lobj is either a layer or an object-on-a-layer, and it addresses the layer to query the thermals on +
+

+ Return value: a string that consists of: +

    +
  • empty if there's no thermal; or +
  • a single 'n' for no-shape; or +
  • a single '@' for solid connection; or +
  • 'o' for round, 'x' for sharp thermal +
  • in case of round or sharp thermal, a 'd' suffix if it is diagonal +
+ + +

Advanced layer access

+ +

layer_setup(obj, directive [, res])

+

+ Takes an object and executes a directive on the layer setup of the object. + If the directive matches, retruns either a measure (if result is specified) + or returns true. +

+ Directive is a comma separated list of requirements; the directive matches + only if all requirements matched. A requirement is specified in the form + of key:value. +

+ Key is a dash separated list of: +

    +
  • above - match a layer group that is above the object's layer (location modifier) +
  • below - match a layer group that is below the object's layer (location modifier) +
  • on - match the layer group of the object (location modifier) +
  • type - match a layer group type; value is a layer group type +
  • net - objects belonging to a specific net on an adjacent copper layer group that covers the current object; value is the name of a net +
  • netmargin - supplement for the net key: require the cover to extend the specified; value is a size (coord) +
+

+ Examples requirements: +

    +
  • above-type:copper - there is an adjacent copper layer group above the object's layer +
  • below-type:!copper - there is no adjacent copper layer group below the object's layer +
  • above-net:vcc - there are copper objects connected to the net called "vcc" on the adjacent copper layer group above the current object +
  • above-net:vcc,above-netmargin:1.3mm - there are copper objects connected to the net called "vcc" on the adjacent copper layer group above the current object; coverage calculated +1.3mm around the object; defaults to 0 if not specified +
+

+ "Above" and "below" are not in the board's coordinate system, but are + relative to the object. In other words, the function first assumes + above is upward and below is downward, then runs all requirements on the object. + If there is no match, above/below directions are reversed and the test is ran + again. +

+ Example directive: +

above-type:!copper,below-net:gnd,below-netmargin:125mil +

This directive requires: +

    +
  • there's no copper layer group above the object (so that the object is on the top or bottom copper layer group) +
  • the object is fully covered on the adjacent copper layer group "below" by copper objects belonging to the network named "gnd" +
  • plus this coverage extends beyond the object to 125mil in every direction +
+

+ Normally the return value is integer 0 (no match) or 1 (match). +

+ If the optional res parameter is specified, it must be a requirement + where key is result. Alternatively the result requirement can + be specified in the directive parameter. When a result is + specified, the return value of layer_setup() will not be a 0/1 boolean but + a readout specified by the result requirement (or the invalid value + is returned on no match). The value of a + result requirement is one of: +

    +
  • above - use a layer group that is above the object's layer (location modifier) +
  • below - use a layer group that is below the object's layer (location modifier) +
  • on - use the layer group of the object (location modifier) +
  • substrate - return the substrate layer group (using the location) +
  • uncovered - return the area (in square nanometers) that are not covered by the "net" directive; note: the total area is the area of the original object bloated by netmargin +
+

+ Complex query script example: +

layer_setup(OBJ, "above-type:!copper,below-net:gnd", "result:below-substrate").a."thickness" +

+ OBJ will match if it is on the top or bottom copper layer and is fully + covered by gnd copper on the adjacent copper layer group on the next internal + copper layer group. When matched, the return value of layer_setup is the + substrate layer group between the object's layer and that adjacent + internal layer group. The .a."thickness" part retrieves the value of + the thickness attribute of this substrate layer. On mismatch, the whole expression + evaluates to the invalid value. + +

Misc

+ +

action(args...)

+

+ Execute a pcb-rnd action. +

+ Arguments: variable nunmber of objects and constants. +

+ Return value: invalid on error, or the return value of the action. + +

coord(str)

+

+ Converts str to coordinates. Useful when using attribute values. +

+ Arguments: +

    +
  • str is a string (number with units) or a numeric value (taken as nanometers) +
+

+ Return value: integer length of the list. + +

isvoid(value)

+

+ Checks whether value is void (invalid). +

+ Arguments: +

    +
  • value is any value, typically a function call +
+

+ Return value: 1 if value is void (invalid), 0 otherwise. + +

getconf(path)

+

+ Fetch the value of a config node +

+ Arguments: +

    +
  • path is a conf node path, e.g. editor/grid +
+

+ Return value: invalid if the config node doesn't exist, else the value of + the config node (converted to the most appropriate data type). + +

violation(i1, v1, ..., iN, vN)

+

+ Build a DRC violation report (a list object). +

+ Arguments (a variable number of pairs of instruction and value): +

    +
  • i is an instruction, see below. +
  • v is a value (a constant or an object) +
+

+ Instruction is one of the following constants: +

    +
  • DRCGRP1 - the following v is an object, part of group 1 of offending objects +
  • DRCGRP2 - the following v is an object, part of group 2 of offending objects +
  • DRCEXPECT - the following v is a numeric value that represent the expected value +
  • DRCMEASURE - the following v is a numeric value that represent the measured value that mismatches the expected value +
+

+ Return value: a list suitable for the drc_query to process. Index: tags/2.3.0/doc/user/06_feature/query/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/query/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/query/index.html (revision 33253) @@ -0,0 +1,21 @@ + + + +

Query: data query language

+

+The query language is a powerful domain specific, declarative scripting +language that can: +

    +
  • list drawing objects, layers and networks +
  • iterate over them +
  • evaluate complex logical expressions using them +
  • selecting/unselecting/printing or drc-reporting objects depending on the result of the evaluation. +
+

+This chapter describes the query language and its use. The chapter is +split up to multiple sub-chapters: +

Index: tags/2.3.0/doc/user/06_feature/query/lang.html =================================================================== --- tags/2.3.0/doc/user/06_feature/query/lang.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/query/lang.html (revision 33253) @@ -0,0 +1,240 @@ + + + +

Query: the query language

+ +

Intro

+

+A DRC program is an unordered list of rules. Rules are evaluated and +violations reported. The advantage of a declarative language is that +intermediate results can be cached and reused. +

+The language is intended to be human readable and human writable, but +the main goal is to let programs and scripts (e.g. netlisters) to +generate it. +

+A rule consists of three parts: +

    +
  • the rule keyword; syntax: rule NAME, where NAME is an arbitrary string +
  • build variables (lists) using search statements, using the let keyword +
  • state assertions about those lists, using the assert keyword +
  • comments, empty lines +
+

+A simpler variant of a rule is a single expression, without any rule or +let or assert keywords in it. +

+Various parts of pcb-rnd, including the advanced search feature and +the query() action, runs a DRC rule (typically the simplified, +single-expression variant) to find/select/list drawing objects. + +

Variables (lists)

+

+Variables are named by the user and are local to the rule. A variable +always holds a list of objects. Lists are ordered. +A list is consists of zero or more objects. An object is on of the following: +

    +
  • the board +
  • a layer +
  • a drawing primitive (line, arc, polygon, padstack, text), whether it is part of a subcircuit or is directly on the board +
  • a subcircuit +
  • a net +
+ +

+Objects have named properties (or fields): +

    +
  • core attributes: for each object type a predefined set of key=value + pairs that always exist (e.g. thickness of a line, start angle of + an arc); these field names starts with "p." +
  • user attributes: free-form key=value pairs optionally assigned by + the user; these field names start with "a." +
  • a "parent" of the object, e.g. "FOO.net" is the network object FOO is + part of (assuming FOO is an object). +
+ +

+Note: the language is case sensitive with keywords and builtins using +lowercase only. For better readability, in syntax description in this +document uppercase words are user chosen identifiers or fields. (This +does not mean identifiers have to be uppercase in a program.) +

+Whitespace character sequences are usually treated as a single whitespace. +

+The syntax of a search statement that stores a result in a list is: +

+let LISTNAME EXPR
+
+ +

+It creates a list called LISTNAME and evaluates expression EXPR to all +available objects and adds the objects that match EXPR to the list. Each +matching object is added only once. +

+The particular order of objects on the list depends on how iterations are +taken in EXPR. For example if EXPR refers to only one list (e.g. @), the +ordering of that list is preserved in the result as well. +

+Object "matches EXPR" when the EXPR evaluated on the object yields true. + +

+A special list that always exist is called @, and contains all subcircuits +and drawing objects present on the board (including those that are part of +subcircuits), in random order. + +

Expressions and values

+

+An expression is evaluated to a value. A value can be: +

    +
  • an object +
  • a list +
  • scalar: a number or string (might be suffixed, like "42 mm") +
  • void (empty, nil, also known as false) +
+ +

+A value is considered true if: +

    +
  • it is an existing object; or +
  • it is a non-empty list; or +
  • it is a non-zero number or non-empty string +
+ +

+An expression is one of: + + +
syntax meaning +
(EXPR) change precedence +
EXPR || EXPR logical OR (result: number) +
EXPR && EXPR logical AND (result: number) +
EXPR1 thus EXPR2 evaluate to EXPR2 if EXPR1 is true, else to void +
EXPR + EXPR add (numbers only) +
EXPR - EXPR subtract (numbers only) +
EXPR * EXPR multiply (numbers only) +
EXPR / EXPR divide (numbers only) +
EXPR == EXPR the two values are equal (result: number) +
EXPR != EXPR the two values are not equal (result: number) +
EXPR ~ string extended regex match left EXPR using pattern right string (result: number) +
EXPR > EXPR left EXPR is greater than right EXPR (number only) +
EXPR >= EXPR left EXPR is greater than or equal to right EXPR (number only) +
EXPR < EXPR left EXPR is less than right EXPR (number only) +
EXPR <= EXPR left EXPR is less than or equal to right EXPR (number only) +
!EXPR logical NOT (result: number, 0 or 1) +
FUNC(EXPR, EXPR, ...) call a function with 0 or more arguments +
EXPR.field evaluated to the value of an object field (see P45, P46) +
+ +

+The syntax of an assertion is: +

+assert EXPR
+
+ +

+When running the DRC, if the EXPR in an assert evaluates to false, a +DRC violation is generated. The return value of such an expression should +normally be a list generated using the violation() function, so that it +can pass on all relevant details (such as expected value, affected objects) +to the DRC display. +

+When running a search, normally the result of an assert should be an object. + +

+If an EXPR references a variable (list), it is evaluated for all +valid members of the list, in order of the list. For example +if there is a variable called FOO, which is a list of objects +(built using a search statement), expression +

+FOO.p.thickness
+
+

+is evaluated as many times as many objects are on the list. +If there is another similar list called BAR, an expression: +

+(FOO.p.thickness < BAR.p.thickness)
+
+

+will compare each possible pair of FOO and BAR objects. That is, if +FOO has 4 objects and BAR has 15 objects, that is 4*15 = 60 comparisons. +

+However, each list is iterated only once, even if it is referenced multiple +times in the same expression. For example, with the above lists: +

+(FOO.p.clearance > 10 mil) && (FOO.p.thickness < BAR.p.thickness)
+
+the potential number of iterations is still 4*15, and not 4*4*15 (FOO is +not iterated twice). In practice the engine leverages lazy evaluation so +if FOO.p.clearance is smaller than 10 mil, the right side is not evaluated, +which saves a few comparisons. See also: fields. +

+If a function needs to be called with a whole list passed instead of +calling to function for each element of the list, the special list() +built-in function should be used. For example assume FOO is a list of 5 +objects: +

+llen(list(FOO))
+
+

+will pass FOO as a list to function llen(), which is called only once. Without +the list() wrapping, llen() would be called five times, once for each item +in the list. + +

Fields (properties and atributes)

+

+A field reference is valid if the field exists. For example a line object +has a thickness attribute, thus the .p.thickness is valid, but a polygon +object does not have a thickness and .p.thickness on a polygon is invalid. +An user attribute reference (e.g. field .a.baz) is valid if the attribute +key exists in the given object. +

+Invalid fields evaluate to value void (and is not considered an error). +Thus if variable BLOBB is a list +that consists of 3 line, 2 arc and a layer objects, the following expression +will be void (false) for at least the 3 line objects and can be true +for at most 2 cases (the arc objects): +

+(BLOBB.p.width >= 10 mm)
+
+(because only arc objects have valid .p.width field, which is the horizontal +radius of an arc). + +

+A void value is never equal to anything. A void value is not equal +even to another void value. + +

User functions

+

+User functions are defined with the function keyword, followed +by the function name and a comma separated list of argument names in +parenthesis. The argument list may be empty. Each argument passed must be +an object or a list (i.e. numbers can not be passed). +

+The body of the function may contain the same constructs as the body of a rule. +

+A function definition ends with a return keyword followed by an expression. +The experession is evaluated and the resulting value is returned. If the +expression iterates, the last evaluated value is returned. +

+Example (counts the number of non-terminal, holed padstacks on a net object +called LNET): +

+function count_vias(LNET)
+let OBJS netobjs(LNET)
+let VIAS (OBJS.type == PSTK) && (OBJS.hole > 0) && (OBJS.a."term" == "")
+return llen(list(VIAS))
+
+

+On the calling side user functions are the same as built-in functions, e.g. +the above functions can be called as: +

+let ALLNETS netlist()
+assert (count_vias(ALLNETS) != 4)
+
+ +

Misc

+

+Comments are lines starting with # + + + Index: tags/2.3.0/doc/user/06_feature/query/tutor_cli.html =================================================================== --- tags/2.3.0/doc/user/06_feature/query/tutor_cli.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/query/tutor_cli.html (revision 33253) @@ -0,0 +1,168 @@ + + + +

Query: advanced search, command line tutorial: query language

+ +

scope

+ +pcb-rnd from version 1.1.3 features a flexible advanced search that helps +the user selecting/unselecting objects that match a given logical expression. +The core of the feature is the pcb-rnd query language. The same language +is used in the programmable DRC (see also: +a more formal description of the language). +

+The current document is a walk through of the practical aspects of the +language. It starts with the simplest examples while working towards more +complex cases. +

+A limited version of the functionality is accessible through a GUI +wizard when using the GTK HID. A separate +tutorial is dealing with that feature. + +

Actions

+The query(act, expr) action creates the list called "@", which contains all +objects of the design. Then it iterates over this list (if needed) and +evaluates the query expression on each object. For each evaluation "act" +is performed; "act" is one of: +
    +
  • select - add the matching object to the selections if expr evaluated to true +
  • unselect - remove the matching object from the selections if expr evaluated to true +
  • eval - print the result of the expression to stdout +
  • dump - this inhibits evaluating; it compiles the expression and dumps the parse tree (useful for debugging) +
+

+The symbol @ in the query represents the iterator, or in other words, +the current object we are checking. The engine iterates over all +copper objects, silk objects, pins, holes, layers and nets. A simple query +that selects all objects looks like this: +

+query(select, '@')
+
+The actual query expression was a single @ in this case. This made +the iteration happen, got the expression evaluated one each object. The +result of each evaluation was the given object. Since these objects +were all existing, valid objects, they were taken as logical value TRUE, +thus for each the add-to-selection was performed. +

+Note: it's usually a good idea to write the expression in single quotes, because +it may contain commas, double quotes and parenthesis that pcb-rnd's action parser may +take as action syntax. +

+The same expression can ran with eval would print the result of each +evaluation: +

+query(eval, '@')
+
+This is visible on the terminal pcb-rnd was started from - on X, it's a good +idea to start a terminal and run pcb-rnd from that instead from a menu or +icon. The rest of this tutorial will use the eval query because it's easier +to include the result of an eval than of a selection. Most examples will +specify the query expression only, without quotes - the reader should +add the query(eval, ' ') part. + +

iteration vs. evaluate once

+If an expression does not reference the @ object, no iteration is performed +and the expression is ran only once: +
+query(eval, '1')
+
+This will calculate the value of 1 and prints it to the standard output. Since +there's no iteration, this can not result in changes in selection. However, +it makes it easy to demonstrate some basic concepts of the query language. +

+Note: if @ is present multiple times in the expression, it's still only +one loop over all objects. When evaluating the expression for a given object, +all instances of @ are substituted with the same object in that iteration. + + +

grammar: arithmetics and logics

+For example the integer and floating point numbers and the usual +arithmetic and logical operators work as expected: + + +
expression result explanation +
42 42 the integer value 42 +
3.14 3.14 the floating point value 3.14 +
10 mil 254000 a number with a unit suffix is converted to pcb-rnd's internal coordinate unit (nanometers) +
1+2 3 sum of 1 and 2 +
2*4 8 multiplication +
47/4 11 integer division (because both operands were integers) +
47/4.0 11.75 floating point division (because at least one of the operands was a float) +
(1+2)*5 15 parenthesis works as usual +
1 && 0 0 logical AND - the result is 1 if both operands were TRUE, 0 else +
1 || 0 1 logical OR - the result is 1 if either operand was TRUE, 0 else +
!2 0 logical NOT - 2 is non-zero, so it is TRUE, negate this to get the result (FALSE, which is 0) +
4 > 2 1 because four is greater than two; all the usual relational operators work: == is equal, != is not-equal, <, <=, > and >=. +
+ +

grammar: object properties

+Object have named properties, e.g. the thickness of a line (or arc, or +trace in general) is called ".thickness", so the thickness of +the current object is: +
+	@.thickness
+
+

+Next, we can already select all traces thicker than 10 mil: +

+	query(select, '@.thickness > 10 mil')
+
+

+Because logical expressions are available, it's easy to select all medium-thick +lines: +

+	(@.thickness >= 10 mil) && (@.thickness <= 30 mil)
+
+

+or any trace that's too thin or too thick: +

+	(@.thickness < 10 mil) || (@.thickness > 30 mil)
+
+

+or traces that don't match our preferred 8, 10 and 15 mil thickness values: +

+	(@.thickness != 8 mil) && (@.thickness != 10 mil) && (@.thickness != 15 mil)
+
+ +

grammar: invalid value

+But how comes an expression like '@.thickness > 10 mil' works while +@ iterates over non-trace objects, like layers, nets or subcircuits that +clearly have no thickness? +

+The answer is the invalid value, which is neither true nor false. If +a property does not exist in a given object, the result is the invalid value +or invalid for short. The invalid is treated specially: +

    +
  • in arithmetic operations it propagates: if either operand is invalid, the result is invalid, e.g. 1+invalid = invalid; this affects +, -, *, / and all the relational operators +
  • in binary logic operations (&& and ||), it is ignored: it is assumed to be true in a && and false in a || so the outcome depends on the other operand +
  • in logical NOT (!), TODO +
+When @ refers to a non-trace object, @.thickness is invalid and +'@.thickness > 10 mil' is evaluated t invalid. If the result is not TRUE, +the requested action is not performed. +

+The invalid value is generated only when the expression is valid but the +actual object doesn't have the feature needed. If the expression is wrong, +an error is generated and the expression stops evaluating immediately. + +

grammar: more properties

+Some properties are a single numeric value, like thickness, or the +.name of a layer (which is a string) but others are objects. For +example the .layer property of a line or arc refers to the layer +object the given line or arc is drawn on. These in turn can be combined, +and the "name of the layer the current object is on": +
+	@.layer.name
+
+

+Referencing non-existing properties yields an error, e.g. @.thickness.layer +is an error - in contrast with @.layer, which may evaluate to the +invalid value (e.g. for vias or nets, because they don't have layers). +The difference is that thickness can not have a layer ever (thus is an error) +while @.layer is either applicable or not, but potentially could work, this +when it doesn't, it's only an invalid value. +

+Further useful property combinations: +TODO +

+There is a full list of all properties. Index: tags/2.3.0/doc/user/06_feature/scripting/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/index.html (revision 33253) @@ -0,0 +1,23 @@ + + + + pcb-rnd user manual + + + +

pcb-rnd fungw scripting - TOC

+ +

Installation, configuration

+ + + +

High level docs

+ + + + Index: tags/2.3.0/doc/user/06_feature/scripting/install.txt =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/install.txt (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/install.txt (revision 33253) @@ -0,0 +1,27 @@ +Note: if you need only fawk, fbas and fpascal scripting, there is no + need to do the steps below, pcb-rnd source comes with those + embedded. The below steps are needed if you need more scripting + languages (e.g. python, lua, perl, tcl, mawk). + +Requirements: + 1. download and install genht - svn://repo.hu/genht/trunk + Some Linux distributions already have this packaged, please check your + repositories (and install the development version) + NOTE: version 1.0.1 is too old, please get a newer one (e.g. svn version) + NOTE: you need to install genht under /usr or /usr/local - non-standard + installation will NOT work for now. + 2. recommended, non-standard, optional dependency for running mawk scripts: + install libmawk - svn://repo.hu/libmawk/trunk + (Many of the example scripts are written in awk) + At least version 1.0.2 is required. + At the moment libmawk must be installed as root into /usr + e.g. './configure --prefix=/usr' + 3. download and install fungw - svn://repo.hu/fungw/trunk + 4. fungw should be installed as root, into /usr/local/ or /usr/ + during configuration, make sure all relevant scripting languages are found + 5. (re)configure and (re)compile pcb-rnd so that it uses the system-installed + version of fungw instead of the local, no-script version; make sure the + "script" plugin is compiled (as builtin or plugin) + 6. later on if a new scripting language is required, reconfigure, + recompile and reinstall fungw - no pcb-rnd recompilation is needed as + long as the system-installed fungw version is not upgraded Index: tags/2.3.0/doc/user/06_feature/scripting/intro.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/intro.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/intro.html (revision 33253) @@ -0,0 +1,196 @@ + + + + pcb-rnd user manual + + + + +

Scripting - User Intro

+This document is an introduction to fungw for pcb-rnd users. It focuses on +scripting pcb-rnd and doesn't discuss fungw deeper than the minimum necessary. +Fungw is more generic than shown here. + +

Stored scripts

+

+Stored scripts are typically larger piece of works that register actions, +may create menus, GUI dialog boxes. Their role is to introduce new +functionality to pcb-rnd - functionality written and shared by users, +using their favorite script language. +

+Loading a script using the CLI: run action +

+	LoadScript(id, filename, language)
+
+

+where id is an arbitrary text ID. The ID is used for referencing the script +once it is loaded. The filename should be a full path (CWD is pcb-rnd's +CWD). Language must be one of the languages configured in fungw. +

+Once the script is loaded, it is accessible by calling the actions it +registered using the standard fgw_func_reg() mechanism. +

+Scripts can be unloaded using the action +

+	UnloadScript(id)
+
+

+These operations can also be done using the script browser dialog box, which +is invoked from the menu system or by running action +

+	BrowseScripts()
+
+

+Stored scripts also can be made permanent, which means they are always loaded +automatically on startup. pcb-rnd loads scripts.lht from the user config +dir (typically ~/.pcb-rnd/) and from the system config dir (typically +/usr/share/pcb-rnd/). This file has the list of scripts to load under +its root li:pcb-rnd-perma-script-v1. Each script is a hash node, +node name is the ID of the script. +

+The has nodes have two text children: path and lang. Node path +sepcifies the path to the script file to load; if relative, it is +relative to scripts.lht. Node lang is optional and specifies +the scripting language engine to load for the script - when not specified, a +guess is made based on path. +

+For example the user may place foo.awk in ~/.pcb-rnd/scripts/foo.awk and +write the following ~/.pcb-rnd/scripts.lht: +

+li:pcb-rnd-perma-script-v1 {
+	ha:bar { path=scripts/foo.awk; lang=mawk; }
+}
+
+

+which will then load ~/.pcb-rnd/scripts/foo.awk using the mawk scripting +engine with the script id bar. + +

Oneliners

+

+Note: examples in this section assume pcb-rnd is configured and compiled +with system installed fungw, and libmawk is also installed +and the libmawk binding is compiled in fungw. +

+pcb-rnd also offers script one-liners. A one-liner is a short script +intended to do one thing at the moment of execution. It is typically not +saved in a file and is not recalled later. One-liners are invoked by +the Oneliner action: +

+	OneLiner(awk, 'message("hello")')
+
+

+Alternatively the language-specific shorthand action can be used; the +following example is equivalent to the above example: +

+	awk('message("hello")')
+
+

+A third approach, most convenient for experimenting, is switching the +command line interpreter to the given script lagnuage temporarily. For this +the shorthand action (e.g. "awk", "python", "perl") should be exected without +arguments. The promp of the cli changes to reflect the language that will +interpret all the following command lines entered. To leave the script mode, +type "/exit". +

+For example: +

    +
  • open the command line (pressing ':' with the default menu config) +
  • enter awk and press enter - this will switch to awk mode +
  • enter for(y=1; y < 10; y += 3) { createtext("#1", 0, "1 mm", y " mm", 0, 100, "foo:" y) } +
  • enter more awk one-liners +
  • enter /exit and press enter - this will switch back to the command line + +
+

+The one-liner mode can be used to get a better command interpreter. After +all, any pcb-rnd action is accessible from any scripting language. For +example the user may choose to switch to awk mode and issue normal +pcb-rnd actions using the awk syntax. The default mode can even be +configured through the conf system, by setting rc/cli_backend to the +language name. However, the CPU and memory footprint of executing a full +script interpreter for each command entered should be noted. +

+Limitations: each command line is a separate script context, there are no +script states (e.g. variables) preserved between lines entered. Actions +defined in one-liners are also discarded after the one-liner finished. For +such use cases, stored script shall be written. + +

Live Scripting

+

+Action LiveScript() pops up the Live Scripting window. The script +entered here can be executed, saved or loaded. +

+The main use case is experimenting with board edit (object generation) +sctipts: pcb-rnd keeps track of board edits execution may have done and +can undo them. The re-run button combines "undo the effects of the +previous run and run the new version of the script" into a single click. +

+Using the persistent mode allows developers to debug, fix and finalize +a script that is intended to be used as a stored script. This mode allows +the script to register actions. +

+A +Live Scripting Tutorial is available in the knowledge pool. + + +

Scripting - Developer Intro

+

+ +

The big picture

+

+The main interface between pcb-rnd internals and the outside world +(e.g. user interface, scripts) is called actions. An action is typically +a function with a few arguments that executes a smallish task. The +actions implemented by pcb-rnd are all functions written in C; some of +the actions are part of core pcb-rnd, others are implemented in plugins. +

+GUI operations, menu items, clicking on buttons all call these +actions. The advantage of this system is that the actions are accessible +in an user-interface-independent way: the same operations can be done +with and without GUI, initiated by an user with a mouse or by a script. +

+Thus the two main aspects of pcb-rnd scripting are: +

    +
  • defining new actions in script; actions that then can be called from + the user interface or from other scripts +
  • calling pcb-rnd actions from within the script to execute the actual + task +
+ +

Defining actions

+

+With fungw, every action is just a native function - the syntax varies +from scripting language to scripting language (see + the rosetta hello world example). The +arguments of the function are the arguments of the action. The return value +of the function is the return value of the action. +

+For the arguments, new actions should try to follow the conventions that +can be found in already existing + core actions +for similar purpose. +

+The return value depends on the purpose of the action. If the +action is used to calculate something, typically not changing any global +state (e.g. the board), it should return the value calculated, in whatever +scalar native data type the scripting language supports. If the action +is not called to get a value but to perform some changes, the return +value should be an integer: 0 means success, anything else means error. + +

Calling actions

+

+The script may call any action available at a given time, independently +of whether the action is defined in pcb-rnd core, in plugins or in other +scripts. In most scripting languages the action call looks like a simple +function call: function arguments are the action's arguments, the return +value of the function is the return value generated by the action. The calls +are all single threaded, blocking calls. The script may use any scalar native +data type for action arguments without conversion, fungw will take care of +the conversions automatically. + +

Action names

+

+All action names are registered in lowercase version. The script shall +register lower case function names and action (function) calls should be +spelled lowercase too. + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ID.desc =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ID.desc (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ID.desc (revision 33253) @@ -0,0 +1,2 @@ +Create a new action hello() that prints "Hello world!" in the message log. + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ID.name =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ID.name (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ID.name (revision 33253) @@ -0,0 +1 @@ +hello world (text, log) Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.awk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.awk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.awk (revision 33253) @@ -0,0 +1,12 @@ +# An action without arguments that prints hello world in the log window +# Returns 0 for success. +function hello() +{ + message("Hello world!\n"); + return 0 +} + +# Register the action - action name matches the function name +BEGIN { + fgw_func_reg("hello") +} Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.bas =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.bas (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.bas (revision 33253) @@ -0,0 +1,11 @@ +REM An action without arguments that prints hello world in the log window +REM Returns 0 for success. +function hello() + message("Hello world!\n") + hello = 0 +end function + +REM Register the action - action name matches the function name +fgw_func_reg(hello) + + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.fawk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.fawk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.fawk (revision 33253) @@ -0,0 +1,12 @@ +# An action without arguments that prints hello world in the log window +# Returns 0 for success. +function hello() +{ + message("Hello world!\n"); + return 0; +} + +# Register the action - action name matches the function name +function main(ARG) { + fgw_func_reg(hello); +} Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.fl =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.fl (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.fl (revision 33253) @@ -0,0 +1,15 @@ +;; An action without arguments that prints hello world in the log window +;; Returns 0 for success. +(define hello + (lambda () + (message "Hello world!\n") + 0 + ) +) + +;; Register the action - action name matches the function name +(define main + (lambda (args) + (fgw_func_reg "hello") + ) +) Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.html (revision 33253) @@ -0,0 +1,7 @@ +Create a function hello that will be registered as an action. +The name of the action and the function is always the same. Action names +shall be lowercase. +

+When the action is called, use message to append a log message. +

+In the "main" section of the script, register the action using fgw_func_reg(). Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.js =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.js (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.js (revision 33253) @@ -0,0 +1,10 @@ +// An action without arguments that prints hello world in the log window +// Returns 0 for success. +function hello() +{ + message("Hello world!\n"); + return 0 +} + +// Register the action - action name matches the function name +fgw_func_reg("hello") Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.lua =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.lua (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.lua (revision 33253) @@ -0,0 +1,9 @@ +-- An action without arguments that prints hello world in the log window +-- Returns 0 for success. +function hello() + message("Hello world!") + return 0 +end + +-- register hello() action +fgw_func_reg("hello") Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.pas =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.pas (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.pas (revision 33253) @@ -0,0 +1,14 @@ +{ An action without arguments that prints hello world in the log window + Returns 0 for success.} +function hello(); +begin + message('Hello world!\n'); + hello := 0; +end; + +{ Register the action - action name matches the function name } +function main(ARG); +begin + fgw_func_reg(hello); +end; + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.pl =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.pl (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.pl (revision 33253) @@ -0,0 +1,11 @@ +# An action without arguments that prints hello world in the log window +# Returns 0 for success. +sub hello { + message("Hello world!\n"); + return 0; +} + +# Register the action - action name matches the function name +fgw_func_reg("hello"); + + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.py =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.py (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.py (revision 33253) @@ -0,0 +1,8 @@ +# An action without arguments that prints hello world in the log window +# Returns 0 for success. +def hello(): + message("Hello world!"); + return 0 + +# register hello() action +fgw_func_reg("hello") Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.rb =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.rb (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.rb (revision 33253) @@ -0,0 +1,9 @@ +# An action without arguments that prints hello world in the log window +# Returns 0 for success. +def hello() + message("Hello world!\n") + return 0 +end + +# Register the action - action name matches the function name +fgw_func_reg("hello") Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.sh =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.sh (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.sh (revision 33253) @@ -0,0 +1,13 @@ +#!/bin/sh + +# An action without arguments that prints hello world in the log window +# Returns 0 for success. +hello() +{ + fgw message "Hello world!" + return 0 +} + +# Register the action - action name matches the function name +fgw_func_reg "hello" + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.stt =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.stt (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.stt (revision 33253) @@ -0,0 +1,10 @@ +;; An action without arguments that prints hello world in the log window +;; Returns 0 for success. +(defun hello () + (message "Hello world!\n") + 0 +) + +;; Register the action - action name matches the function name +(fgw_func_reg "hello") + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.tcl =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.tcl (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/ex.tcl (revision 33253) @@ -0,0 +1,9 @@ +# An action without arguments that prints hello world in the log window +# Returns 0 for success. +proc hello {} { + message "Hello world!" + return 0 +} + +# register hello() action +fgw_func_reg "hello" Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/10_hello/index.html (revision 33253) @@ -0,0 +1,47 @@ + + + + pcb-rnd rosetta hello world (text, log) + + + + + <-- back to the index of Rosetta examples +

hello world (text, log)

+Create a new action hello() that prints "Hello world!" in the message log. +
Example implementations
+awk + | +bas + | +fawk + | +fl + | +js + | +lua + | +pas + | +pl + | +py + | +rb + | +sh + | +stt + | +tcl +
Explanation, step by step
+Create a function +hello + that will be registered as an action. The name of the action and the function is always the same. Action names shall be lowercase. +

When the action is called, use +message + to append a log message. +

In the "main" section of the script, register the action using fgw_func_reg(). + + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ID.desc =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ID.desc (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ID.desc (revision 33253) @@ -0,0 +1,2 @@ +Create a new menu + action hello() that prints "Hello world!" in the message log. + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ID.name =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ID.name (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ID.name (revision 33253) @@ -0,0 +1 @@ +hello world (menu, log) Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.awk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.awk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.awk (revision 33253) @@ -0,0 +1,10 @@ +function hello() +{ + message("hello!\n") +} + +BEGIN { + fgw_func_reg("hello") + cookie = scriptcookie() + createmenu("/main_menu/Plugins/script/hello", "hello()", "Prints hello! in the log", cookie) +} Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.bas =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.bas (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.bas (revision 33253) @@ -0,0 +1,8 @@ +function hello() + message("hello!\n") +end function + +fgw_func_reg(hello) +cookie = scriptcookie() +createmenu("/main_menu/Plugins/script/hello", "hello()", "Prints hello! in the log", cookie) + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.fawk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.fawk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.fawk (revision 33253) @@ -0,0 +1,10 @@ +function hello() +{ + message("hello!\n"); +} + +function main(ARGV) { + fgw_func_reg(hello); + cookie = scriptcookie(); + createmenu("/main_menu/Plugins/script/hello", "hello()", "Prints hello! in the log", cookie); +} Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.html (revision 33253) @@ -0,0 +1,14 @@ +Create a function hello that will be registered as an action. +The name of the action and the function is always the same. Action names +shall be lowercase. +

+When the action is called, use message to append a log message. +

+In the "main" section of the script, register the action using fgw_func_reg(). +Then save the script cookie and register a new submenu using it. Registering +the submenu with this cookie makes pcb-rnd auto-remove the menu when the script +is unloaded. +

+The menu path starts with /main_menu, because it is also possible to +insert menu entries in popups. + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.lua =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.lua (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.lua (revision 33253) @@ -0,0 +1,8 @@ +function hello() + message("Hello world!") + return 0 +end + +fgw_func_reg("hello") +cookie = scriptcookie() +createmenu("/main_menu/Plugins/script/hello", "hello()", "Prints hello! in the log", cookie) Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.pas =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.pas (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.pas (revision 33253) @@ -0,0 +1,12 @@ +function hello(); +begin + message('hello!\n'); +end; + +function main(ARGV); +begin + fgw_func_reg(hello); + cookie := scriptcookie(); + createmenu('/main_menu/Plugins/script/hello', 'hello()', 'Prints hello! in the log', cookie); +end; + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.py =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.py (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.py (revision 33253) @@ -0,0 +1,7 @@ +def hello(): + message("Hello world!"); + return 0 + +fgw_func_reg("hello") +cookie = scriptcookie() +createmenu("/main_menu/Plugins/script/hello", "hello()", "Prints hello! in the log", cookie) Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.tcl =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.tcl (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/ex.tcl (revision 33253) @@ -0,0 +1,8 @@ +proc hello {} { + message "Hello world!" + return 0 +} + +fgw_func_reg "hello" +set cookie [scriptcookie] +createmenu "/main_menu/Plugins/script/hello" "hello()" "Prints hello! in the log" $cookie Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/11_hello_menu/index.html (revision 33253) @@ -0,0 +1,36 @@ + + + + pcb-rnd rosetta hello world (menu, log) + + + + + <-- back to the index of Rosetta examples +

hello world (menu, log)

+Create a new menu + action hello() that prints "Hello world!" in the message log. +
Example implementations
+awk + | +bas + | +fawk + | +lua + | +pas + | +py + | +tcl +
Explanation, step by step
+Create a function +hello + that will be registered as an action. The name of the action and the function is always the same. Action names shall be lowercase. +

When the action is called, use +message + to append a log message. +

In the "main" section of the script, register the action using fgw_func_reg(). Then save the script cookie and register a new submenu using it. Registering the submenu with this cookie makes pcb-rnd auto-remove the menu when the script is unloaded. +

The menu path starts with /main_menu, because it is also possible to insert menu entries in popups. + + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ID.desc =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ID.desc (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ID.desc (revision 33253) @@ -0,0 +1 @@ +Create a new action hello() that prints "Hello world!" in a modal dialog box using DAD. Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ID.name =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ID.name (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ID.name (revision 33253) @@ -0,0 +1 @@ +hello world (GUI) Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.awk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.awk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.awk (revision 33253) @@ -0,0 +1,12 @@ +function hello() +{ + dad("heldi", "new") + dad("heldi", "label", "Hello world!") + dad("heldi", "button_closes", "close", 0) + dad("heldi", "run_modal", "hello-world", "Hello world dialog") +} + +BEGIN { + fgw_func_reg("hello") +} + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.bas =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.bas (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.bas (revision 33253) @@ -0,0 +1,9 @@ +function hello() + dad("heldi", "new") + dad("heldi", "label", "Hello world!") + dad("heldi", "button_closes", "close", 0) + dad("heldi", "run_modal", "hello-world", "Hello world dialog") +end function + +fgw_func_reg(hello) + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.fawk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.fawk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.fawk (revision 33253) @@ -0,0 +1,12 @@ +function hello() +{ + dad("heldi", "new"); + dad("heldi", "label", "Hello world!"); + dad("heldi", "button_closes", "close", 0); + dad("heldi", "run_modal", "hello-world", "Hello world dialog"); +} + +function main(ARG) { + fgw_func_reg(hello); +} + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.html (revision 33253) @@ -0,0 +1,15 @@ +Create a function hello that will be registered as an action. +

+When the action is called, build a dad dialog called "heldi", with a single +label containing "Hello world!" and a close button that makes the dialog +return 0 when clicked. When the dialog is ran in modal mode, +it will be open and block other pcb-rnd windows until the user closes it. +

+Note: the window title (4th parameter of the 3rd dad() call) is displayed +because the root node of the DAD is not a box. For a more complex version, +see 13_hello_dad. +

+In the "main" section of the script, register the action using fgw_func_reg(). +

+More details on DAD: +DAD developer's doc Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.lua =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.lua (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.lua (revision 33253) @@ -0,0 +1,9 @@ +function hello() + dad("heldi", "new") + dad("heldi", "label", "Hello world!") + dad("heldi", "button_closes", "close", 0) + dad("heldi", "run_modal", "hello-world", "Hello world dialog") + return 0 +end + +fgw_func_reg("hello") Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.pas =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.pas (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.pas (revision 33253) @@ -0,0 +1,12 @@ +function hello(); +begin + dad('heldi', 'new'); + dad('heldi', 'label', 'Hello world!'); + dad('heldi', 'button_closes', 'close', 0); + dad('heldi', 'run_modal', 'hello-world', 'Hello world dialog'); +end; + +function main(ARG); +begin + fgw_func_reg(hello); +end; Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.pl =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.pl (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.pl (revision 33253) @@ -0,0 +1,9 @@ +sub hello +{ + dad('heldi', 'new'); + dad('heldi', 'label', 'Hello world!'); + dad('heldi', 'button_closes', "close", 0); + dad('heldi', 'run_modal', 'hello-world', 'Hello world dialog'); +} + +fgw_func_reg('hello'); Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.py =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.py (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.py (revision 33253) @@ -0,0 +1,8 @@ +def hello(): + dad("heldi", "new") + dad("heldi", "label", "Hello world!") + dad("heldi", "button_closes", "close", 0) + dad("heldi", "run_modal", "hello-world", "Hello world dialog") + return 0 + +fgw_func_reg("hello") Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.tcl =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.tcl (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/ex.tcl (revision 33253) @@ -0,0 +1,9 @@ +proc hello {} { + dad "heldi" "new" + dad "heldi" "label" "Hello world!" + dad "heldi" "button_closes" "close" 0 + dad "heldi" "run_modal" "hello-world" "Hello world dialog" + return 0 +} + +fgw_func_reg "hello" Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/12_hello_dad/index.html (revision 33253) @@ -0,0 +1,39 @@ + + + + pcb-rnd rosetta hello world (GUI) + + + + + <-- back to the index of Rosetta examples +

hello world (GUI)

+Create a new action hello() that prints "Hello world!" in a modal dialog box using DAD. +
Example implementations
+awk + | +bas + | +fawk + | +lua + | +pas + | +pl + | +py + | +tcl +
Explanation, step by step
+Create a function +hello + that will be registered as an action. +

When the action is called, build a dad dialog called "heldi", with a single label containing "Hello world!" and a close button that makes the dialog return 0 when clicked. When the dialog is ran in modal mode, it will be open and block other pcb-rnd windows until the user closes it. +

Note: the window title (4th parameter of the 3rd dad() call) is displayed because the root node of the DAD is not a box. For a more complex version, see 13_hello_dad. +

In the "main" section of the script, register the action using fgw_func_reg(). +

More details on DAD: +DAD developer's doc + + + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ID.desc =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ID.desc (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ID.desc (revision 33253) @@ -0,0 +1 @@ +Create a new action hello() that prints "Hello world!" in vertical layout in a dialog box. Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ID.name =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ID.name (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ID.name (revision 33253) @@ -0,0 +1 @@ +hello world (GUI, with vbox) Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.awk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.awk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.awk (revision 33253) @@ -0,0 +1,15 @@ +function hello() +{ + dad("heldi", "new") + dad("heldi", "begin_vbox") + dad("heldi", "label", "Hello") + dad("heldi", "label", "world!") + dad("heldi", "button_closes", "cancel", -1, "ok", 0) + dad("heldi", "end") + dad("heldi", "run_modal", "hello-world", "") +} + +BEGIN { + fgw_func_reg("hello") +} + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.bas =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.bas (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.bas (revision 33253) @@ -0,0 +1,13 @@ +function hello() + dad("heldi", "new") + dad("heldi", "begin_vbox") + dad("heldi", "label", "Hello") + dad("heldi", "label", "world!") + dad("heldi", "button_closes", "cancel", -1, "ok", 0) + dad("heldi", "end") + dad("heldi", "run_modal", "hello-world", "") +end function + +fgw_func_reg(hello) + + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.fawk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.fawk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.fawk (revision 33253) @@ -0,0 +1,14 @@ +function hello() +{ + dad("heldi", "new"); + dad("heldi", "begin_vbox"); + dad("heldi", "label", "Hello"); + dad("heldi", "label", "world!"); + dad("heldi", "button_closes", "cancel", -1, "ok", 0); + dad("heldi", "end"); + dad("heldi", "run_modal", "hello-world", ""); +} + +function main(ARGV) { + fgw_func_reg(hello); +} Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.html (revision 33253) @@ -0,0 +1,17 @@ +Create a function hello that will be registered as an action. +

+When the action is called, build a dad dialog called "heldi", with a +vertical box that contains two labels "Hello" and "world!" and standard +dialog box close buttons. When the cancel button is clicked, the dialog +box will return -1; clicking the ok button will return 0. The vbox is +closed by a "end" call to dad(). When the dialog is ran in modal mode, it +will be open and block other pcb-rnd windows until the user closes it. +

+Tip #1: change "begin_vbox" to "begin_hbox" to get a horizontal layout. +

+Tip #2: boxes can be nested (but each box must have a corresponding "end"). +

+In the "main" section of the script, register the action using fgw_func_reg(). +

+More details on DAD: +DAD developer's doc Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.lua =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.lua (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.lua (revision 33253) @@ -0,0 +1,12 @@ +function hello() + dad("heldi", "new") + dad("heldi", "begin_vbox") + dad("heldi", "label", "Hello") + dad("heldi", "label", "world!") + dad("heldi", "button_closes", "cancel", -1, "ok", 0) + dad("heldi", "end") + dad("heldi", "run_modal", "hello-world", "") + return 0 +end + +fgw_func_reg("hello") Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.pas =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.pas (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.pas (revision 33253) @@ -0,0 +1,16 @@ +function hello(); +begin + dad('heldi', 'new'); + dad('heldi', 'begin_vbox'); + dad('heldi', 'label', 'Hello'); + dad('heldi', 'label', 'world!'); + dad('heldi', 'button_closes', 'cancel', -1, 'ok', 0); + dad('heldi', 'end'); + dad('heldi', 'run_modal', 'hello-world', ''); +end; + +function main(ARGV); +begin + fgw_func_reg(hello); +end; + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.pl =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.pl (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.pl (revision 33253) @@ -0,0 +1,12 @@ +sub hello +{ + dad('heldi', 'new'); + dad('heldi', 'begin_vbox'); + dad('heldi', 'label', 'Hello'); + dad('heldi', 'label', 'world!'); + dad('heldi', 'button_closes', "cancel", -1, "ok", 0); + dad('heldi', 'end'); + dad('heldi', 'run_modal', 'hello-world', ''); +} + +fgw_func_reg('hello'); Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.py =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.py (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.py (revision 33253) @@ -0,0 +1,11 @@ +def hello(): + dad("heldi", "new") + dad("heldi", "begin_vbox") + dad("heldi", "label", "Hello") + dad("heldi", "label", "world!") + dad("heldi", "button_closes", "cancel", -1, "ok", 0) + dad("heldi", "end") + dad("heldi", "run_modal", "hello-world", "") + return 0 + +fgw_func_reg("hello") Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.tcl =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.tcl (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/ex.tcl (revision 33253) @@ -0,0 +1,12 @@ +proc hello {} { + dad "heldi" "new" + dad "heldi" "begin_vbox" + dad "heldi" "label" "Hello" + dad "heldi" "label" "world!" + dad "heldi" "button_closes" "cancel" -1 "ok" 0 + dad "heldi" "end" + dad "heldi" "run_modal" "hello-world" "" + return 0 +} + +fgw_func_reg "hello" Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/13_hello_dad/index.html (revision 33253) @@ -0,0 +1,42 @@ + + + + pcb-rnd rosetta hello world (GUI, with vbox) + + + + + <-- back to the index of Rosetta examples +

hello world (GUI, with vbox)

+Create a new action hello() that prints "Hello world!" in vertical layout in a dialog box. +
Example implementations
+awk + | +bas + | +fawk + | +lua + | +pas + | +pl + | +py + | +tcl +
Explanation, step by step
+Create a function +hello + that will be registered as an action. +

When the action is called, build a dad dialog called "heldi", with a vertical box that contains two labels "Hello" and "world!" and standard dialog box +close buttons +. When the cancel button is clicked, the dialog box will return -1; clicking the ok button will return 0. The vbox is closed by a "end" call to dad(). When the dialog is ran in modal mode, it will be open and block other pcb-rnd windows until the user closes it. +

Tip #1: change "begin_vbox" to "begin_hbox" to get a horizontal layout. +

Tip #2: boxes can be nested (but each box must have a corresponding "end"). +

In the "main" section of the script, register the action using fgw_func_reg(). +

More details on DAD: +DAD developer's doc + + + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ID.desc =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ID.desc (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ID.desc (revision 33253) @@ -0,0 +1 @@ +Create timers that are going to call back an action in the background. Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ID.name =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ID.name (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ID.name (revision 33253) @@ -0,0 +1 @@ +timers Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.awk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.awk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.awk (revision 33253) @@ -0,0 +1,15 @@ +function timer_cb(now, remain, ud) +{ + message("timer_cb: " now " " remain " " ud "\n") + return 0 +} + +BEGIN { + fgw_func_reg("timer_cb") + + addtimer("timer_cb", 0, 1, "single, async"); + addtimer("timer_cb", 1.2, 1, "single, delayed"); + addtimer("timer_cb", 0.5, 3, "multi"); + + message("Script init finished!\n"); +} Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.bas =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.bas (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.bas (revision 33253) @@ -0,0 +1,13 @@ +function timer_cb(now, remain, ud) + message("timer_cb: " @ now @ " " @ remain @ " " @ ud @ "\n") + timer_cb = 0 +end function + + +fgw_func_reg(timer_cb) + +addtimer("timer_cb", 0, 1, "single, async") +addtimer("timer_cb", 1.2, 1, "single, delayed") +addtimer("timer_cb", 0.5, 3, "multi") + +message("Script init finished!\n") Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.fawk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.fawk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.fawk (revision 33253) @@ -0,0 +1,15 @@ +function timer_cb(now, remain, ud) +{ + message("timer_cb: " @ now @ " " @ remain @ " " @ ud @ "\n"); + return 0; +} + +function main(ARGV) { + fgw_func_reg(timer_cb); + + addtimer("timer_cb", 0, 1, "single, async"); + addtimer("timer_cb", 1.2, 1, "single, delayed"); + addtimer("timer_cb", 0.5, 3, "multi"); + + message("Script init finished!\n"); +} Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.html (revision 33253) @@ -0,0 +1,16 @@ +Create a function timer_cb that will be registered as an action. +This is what the timer will execute. It only prints its arguments in +the message log so it is easy to trace how it is called. +

+Different combination of timer initialization arguments for period and count +(2nd and 3rd argument of addtimer()): +

+ +
period count effect +
0 1 call timer_cb once, but only after the script finished initialization (async); 0 means "0 seconds after the current script call returns" - but in practice this is a shortest non-zero time the timer system can do +
1.2 1 call timer_cb once, in 1.2 sec from now +
0.5 3 call timer_cb three times, with 0.5 sec in between +
+

+All timers start counting after a short period of time after the +script's initialization finished. The three timers are kept track on separately. Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.lua =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.lua (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.lua (revision 33253) @@ -0,0 +1,13 @@ +function timer_cb(now, remain, ud) + message("timer_cb: " .. now .. " " .. remain .. " " .. ud .. "\n") + return 0 +end + +fgw_func_reg("timer_cb") + +addtimer("timer_cb", 0, 1, "single, async") +addtimer("timer_cb", 1.2, 1, "single, delayed") +addtimer("timer_cb", 0.5, 3, "multi") + +message("Script init finished!\n") + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.pas =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.pas (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.pas (revision 33253) @@ -0,0 +1,17 @@ +function timer_cb(now; remain; ud); +begin + message('timer_cb: ' @ now @ ' ' @ remain @ ' ' @ ud @ '\n'); + timer_cb := 0; +end; + +function main(ARGV); +begin + fgw_func_reg(timer_cb); + + addtimer('timer_cb', 0, 1, 'single, async'); + addtimer('timer_cb', 1.2, 1, 'single, delayed'); + addtimer('timer_cb', 0.5, 3, 'multi'); + + message('Script init finished!\n'); +end; + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.pl =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.pl (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.pl (revision 33253) @@ -0,0 +1,13 @@ +sub timer_cb { + my ($now,$remain,$ud)=@_; + message("timer_cb: $now $remain $ud\n"); + return 0; +} + +fgw_func_reg('timer_cb'); + +addtimer('timer_cb', 0, 1, 'single, async'); +addtimer('timer_cb', 1.2, 1, 'single, delayed'); +addtimer('timer_cb', 0.5, 3, 'multi'); + +message("Script init finished!\n"); Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.py =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.py (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.py (revision 33253) @@ -0,0 +1,11 @@ +def timer_cb(now, remain, ud): + message("timer_cb: " + str(now) + " " + str(remain) + " " + str(ud) + "\n") + return 0 + +fgw_func_reg('timer_cb') + +addtimer('timer_cb', 0, 1, 'single, async') +addtimer('timer_cb', 1.2, 1, 'single, delayed') +addtimer('timer_cb', 0.5, 3, 'multi') + +message("Script init finished!\n") Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.tcl =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.tcl (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/ex.tcl (revision 33253) @@ -0,0 +1,12 @@ +proc timer_cb {now remain ud} { + message "timer_cb: $now $remain $ud\n" + return 0 +} + +fgw_func_reg "timer_cb" + +addtimer "timer_cb" 0 1 "single, async" +addtimer "timer_cb" 1.2 1 "single, delayed" +addtimer "timer_cb" 0.5 3 "multi" + +message "Script init finished!\n" Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/21_timer/index.html (revision 33253) @@ -0,0 +1,56 @@ + + + + pcb-rnd rosetta timers + + + + + <-- back to the index of Rosetta examples +

timers

+Create timers that are going to call back an action in the background. +
Example implementations
+awk + | +bas + | +fawk + | +lua + | +pas + | +pl + | +py + | +tcl +
Explanation, step by step
+Create a function +timer_cb + that will be registered as an action. This is what the timer will execute. It only prints its arguments in the message log so it is easy to trace how it is called. +

Different combination of timer initialization arguments for period and count (2nd and 3rd argument of addtimer()): +

+ + + + + +
period + count + effect +
0 + 1 + call timer_cb once, but only after the script finished initialization (async); 0 means "0 seconds after the current script call returns" - but in practice this is a shortest non-zero time the timer system can do +
1.2 + 1 + call timer_cb once, in 1.2 sec from now +
0.5 + 3 + call timer_cb three times, with 0.5 sec in between
+ +

All timers start counting after a short period of time +after + the script's initialization finished. The three timers are kept track on separately. + + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ID.desc =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ID.desc (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ID.desc (revision 33253) @@ -0,0 +1 @@ +Interactive unit converter in a dialog, created via dad(). Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ID.name =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ID.name (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ID.name (revision 33253) @@ -0,0 +1 @@ +unit converter (GUI, interactive) Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.awk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.awk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.awk (revision 33253) @@ -0,0 +1,34 @@ +function uconv() +{ + if (dad("uconv", "exists")) + return; + + dad("uconv", "new") + dad("uconv", "begin_vbox") + dad("uconv", "begin_hbox") + inp = dad("uconv", "coord", 0, "100m") + dad("uconv", "onchange", "uconv_update") + dad("uconv", "begin_vbox") + res1 = dad("uconv", "label", "-") + res2 = dad("uconv", "label", "-") + res3 = dad("uconv", "label", "-") + dad("uconv", "end") + dad("uconv", "end") + dad("uconv", "button_closes", "close", 0) + dad("uconv", "end") + + dad("uconv", "run", "Unit converter", "") +} + +function uconv_update() +{ + dad("uconv", "set", res1, dad("uconv", "get", inp, "mm") " mm") + dad("uconv", "set", res2, dad("uconv", "get", inp, "mil") " mil") + dad("uconv", "set", res3, dad("uconv", "get", inp, "inch") " inch") +} + +BEGIN { + fgw_func_reg("uconv") + fgw_func_reg("uconv_update") +} + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.fawk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.fawk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.fawk (revision 33253) @@ -0,0 +1,34 @@ +function uconv() +{ + if (dad("uconv", "exists")) + return; + + dad("uconv", "new"); + dad("uconv", "begin_vbox"); + dad("uconv", "begin_hbox"); + inp = dad("uconv", "coord", 0, "100m"); + dad("uconv", "onchange", "uconv_update"); + dad("uconv", "begin_vbox"); + res1 = dad("uconv", "label", "-"); + res2 = dad("uconv", "label", "-"); + res3 = dad("uconv", "label", "-"); + dad("uconv", "end"); + dad("uconv", "end"); + dad("uconv", "button_closes", "close", 0); + dad("uconv", "end"); + + dad("uconv", "run", "Unit converter", ""); +} + +function uconv_update() +{ + dad("uconv", "set", res1, dad("uconv", "get", inp, "mm") @ " mm"); + dad("uconv", "set", res2, dad("uconv", "get", inp, "mil") @ " mil"); + dad("uconv", "set", res3, dad("uconv", "get", inp, "inch") @ " inch"); +} + +function main(ARG) { + fgw_func_reg(uconv); + fgw_func_reg(uconv_update); +} + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.html (revision 33253) @@ -0,0 +1,23 @@ +Create a function uconv that will be registered as an action. +

+When the action is called, build a dad dialog called "uconv". Make sure +there's only one instance of the dialog is created by checking if a dialog +by this name already exists. +

+The dialog is built as a horizontal box to split it to left and right. On +the left side there is only a coordinate input box. On the right side there's +a vertical box hosting 3 labels where the results will be displayed. +

+uconv dialog box as rendered by gtk2 +

+The widget IDs of the input and the three result labels are saved in global +variables inp, res1, res2 and res3. +

+Any change on the input will call action "uconv_update", which is also +registered by the script. The update code reads the input field with +the unit set to "mm", then sets the value of the first label (res1) +to this text with a "mm" suffix appended. This is repeated two more times +for two other unit types. +

+More details on DAD: +DAD developer's doc Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.lua =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.lua (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.lua (revision 33253) @@ -0,0 +1,30 @@ +function uconv() + if dad("uconv", "exists") ~= 0 then + return + end + + dad("uconv", "new") + dad("uconv", "begin_vbox") + dad("uconv", "begin_hbox") + inp = dad("uconv", "coord", 0, "100m") + dad("uconv", "onchange", "uconv_update") + dad("uconv", "begin_vbox") + res1 = dad("uconv", "label", "-") + res2 = dad("uconv", "label", "-") + res3 = dad("uconv", "label", "-") + dad("uconv", "end") + dad("uconv", "end") + dad("uconv", "button_closes", "close", 0) + dad("uconv", "end") + dad("uconv", "run", "Unit converter", "") +end + +function uconv_update() + dad("uconv", "set", res1, dad("uconv", "get", inp, "mm") .. " mm") + dad("uconv", "set", res2, dad("uconv", "get", inp, "mil") .. " mil") + dad("uconv", "set", res3, dad("uconv", "get", inp, "inch") .. " inch") +end + +fgw_func_reg("uconv") +fgw_func_reg("uconv_update") + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.tcl =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.tcl (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/ex.tcl (revision 33253) @@ -0,0 +1,31 @@ +proc uconv {} { + global inp res1 res2 res3 + + if {[dad "uconv" "exists"] == 0} { + dad "uconv" "new" + dad "uconv" "begin_vbox" + dad "uconv" "begin_hbox" + set inp [dad "uconv" "coord" 0 "100m"] + dad "uconv" "onchange" "uconv_update" + dad "uconv" "begin_vbox" + set res1 [dad "uconv" "label" "-"] + set res2 [dad "uconv" "label" "-"] + set res3 [dad "uconv" "label" "-"] + dad "uconv" "end" + dad "uconv" "end" + dad "uconv" "button_closes" "close" 0 + dad "uconv" "end" + dad "uconv" "run" "Unit converter" "" + } +} + +proc uconv_update {} { + global inp res1 res2 res3 + + dad "uconv" "set" $res1 "[dad uconv get $inp mm] mm" + dad "uconv" "set" $res2 "[dad uconv get $inp mil] mil" + dad "uconv" "set" $res3 "[dad uconv get $inp inch] inch" +} + +fgw_func_reg "uconv" +fgw_func_reg "uconv_update" Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/index.html (revision 33253) @@ -0,0 +1,40 @@ + + + + pcb-rnd rosetta unit converter (GUI, interactive) + + + + + <-- back to the index of Rosetta examples +

unit converter (GUI, interactive)

+Interactive unit converter in a dialog, created via dad(). +
Example implementations
+awk + | +fawk + | +lua + | +tcl +
Explanation, step by step
+Create a function +uconv + that will be registered as an action. +

When the action is called, build a dad dialog called "uconv". Make sure there's only one instance of the dialog is created by checking if a dialog by this name already exists. +

The dialog is built as a horizontal box to split it to left and right. On the left side there is only a coordinate input box. On the right side there's a vertical box hosting 3 labels where the results will be displayed. +

+uconv dialog box as rendered by gtk2 +

The widget IDs of the input and the three result labels are saved in global variables +inp, res1, res2 + and +res3 +. +

Any change on the input will call action "uconv_update", which is also registered by the script. The update code reads the input field with the unit set to "mm", then sets the value of the first label ( +res1 +) to this text with a "mm" suffix appended. This is repeated two more times for two other unit types. +

More details on DAD: +DAD developer's doc + + + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/uconv.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/uconv.png =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/uconv.png (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/uconv.png (revision 33253) Property changes on: tags/2.3.0/doc/user/06_feature/scripting/rosetta/72_dad_unitconv/uconv.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ID.desc =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ID.desc (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ID.desc (revision 33253) @@ -0,0 +1,2 @@ +Counts how many times the script was loaded, in a persistent on-disk counter. + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ID.name =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ID.name (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ID.name (revision 33253) @@ -0,0 +1 @@ +script state persistency (load/unload/reload) Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ex.awk =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ex.awk (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ex.awk (revision 33253) @@ -0,0 +1,16 @@ +function preunload(why) +{ + message("preunload for " why "; counter will be " ctr "\n") + return ctr +} + +BEGIN { + ctr = scriptpersistency("read"); + if (ctr == -1) + ctr = 0; + ctr++ + message("pers reload: the script has been loaded " ctr " times so far.\n") +# scriptpersistency("remove") + + fgw_func_reg("preunload") +} Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ex.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ex.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ex.html (revision 33253) @@ -0,0 +1,34 @@ +Create a function preunload that will be registered as an action. +This function will be called automatically right before the script is unloaded. +The return value of this function, automatically converted to string, will +be saved on disk (by pcb-rnd). +

+On init, scriptpersistency("read") reads back the last saved string. If +it returns -1, that means there was no saved data, reset the counter to 0. +

+When scriptpersistency("remove") is called, it removes the file from disk. +This matters if pcb-rnd exits abruptly (e.g. crashes), not calling script +unload to overwrite it or if multiple pcb-rnd processes would be running in +parallel and only one should load the data into the script. Keeping it +on disk means the script would still load the last known-to-be-good data +after a pcb-rnd crash. +

+Note #1: the script can save and reload multiple items, as data is an opaque +string to pcb-rnd. However, serialization (packing and unpacking of the items +into a single string) needs to be done by the script. +

+Note #2: persistency data is stored by script ID. Script ID is assigned +run-time by the user. That means the ID can be reused by a different script +next time and persistency data saved by one script may need to be passed to +another. This simplified example does not deal with that. A real script should +either do sanity checks or even better store a signature in the data. +

+Note #3: however, this also means compatible scripts can share data written +in a common format. The example scripts in this directory can be all loaded +under the same ID and will continue the counting. In a case like this, a safer +approach is to store a format-specific signature. +

+Note #4: ReloadScript() really does an unload and a load, but the reason +passed to preunload() will be "reload". The script may decide to save +persistency differently knowing that the reload will be immediate. + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ex.lua =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ex.lua (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/ex.lua (revision 33253) @@ -0,0 +1,16 @@ +function preunload(why) + message("preunload for " .. why .. "; counter will be " .. ctr .. "\n") + return ctr +end + +ctr = scriptpersistency("read"); +if ctr == -1 then + ctr = 0; +end +ctr = ctr + 1 + +message("pers reload: the script has been loaded " .. ctr .. " times so far.\n") +-- scriptpersistency("remove") + +fgw_func_reg("preunload") + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/81_persistency/index.html (revision 33253) @@ -0,0 +1,27 @@ + + + + pcb-rnd rosetta script state persistency (load/unload/reload) + + + + + <-- back to the index of Rosetta examples +

script state persistency (load/unload/reload)

+Counts how many times the script was loaded, in a persistent on-disk counter. +
Example implementations
+awk + | +lua +
Explanation, step by step
+Create a function +preunload + that will be registered as an action. This function will be called automatically right before the script is unloaded. The return value of this function, automatically converted to string, will be saved on disk (by pcb-rnd). +

On init, scriptpersistency("read") reads back the last saved string. If it returns -1, that means there was no saved data, reset the counter to 0. +

When scriptpersistency("remove") is called, it removes the file from disk. This matters if pcb-rnd exits abruptly (e.g. crashes), not calling script unload to overwrite it or if multiple pcb-rnd processes would be running in parallel and only one should load the data into the script. Keeping it on disk means the script would still load the last known-to-be-good data after a pcb-rnd crash. +

Note #1: the script can save and reload multiple items, as data is an opaque string to pcb-rnd. However, serialization (packing and unpacking of the items into a single string) needs to be done by the script. +

Note #2: persistency data is stored by script ID. Script ID is assigned run-time by the user. That means the ID can be reused by a different script next time and persistency data saved by one script may need to be passed to another. This simplified example does not deal with that. A real script should either do sanity checks or even better store a signature in the data. +

Note #3: however, this also means compatible scripts can share data written in a common format. The example scripts in this directory can be all loaded under the same ID and will continue the counting. In a case like this, a safer approach is to store a format-specific signature. +

Note #4: ReloadScript() really does an unload and a load, but the reason passed to preunload() will be "reload". The script may decide to save persistency differently knowing that the reload will be immediate. + + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/Makefile =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/Makefile (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/Makefile (revision 33253) @@ -0,0 +1,4 @@ +all: FORCE + cd ../util && ./rosetta_genpages.sh + +FORCE: Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/index.html (revision 33253) @@ -0,0 +1,73 @@ + + + + pcb-rnd rosetta + + + + +

pcb-rnd scripting - Rosetta

+The Rosetta Stone +of pcb-rnd scripting is a collection of example scripts implemented in +various scripting languages. Rosetta has multiple purposes: +
    +
  • to provide examples of using the pcb-rnd API; +
  • to not scare away newcomers by showing the first examples in an unfamiliar language; +
  • to help the user to decide which language to use for a specific task; +
  • to provide examples on how to convert idioms of pcb-rnd scripts from one language to another. +
+

+Each example comes with an explanation, written in plain English about what the +scripts do, step by step. Instead of trying to exploit powerful features +of the language, example implementations try to be simple. +

+The list below is ordered from the least complex to the most complex examples. +Column lvl is the complexity score. The less the score is, the simpler +the example is. + + +

Index of examples

+ + + + + + + + + + +
lvlexample languages description +
10 + hello world (text, log) + awk bas fawk fl js lua pas perl python ruby sh stutter tcl + Create a new action hello() that prints "Hello world!" in the message log. +
11 + hello world (menu, log) + awk bas fawk lua pas python tcl + Create a new menu + action hello() that prints "Hello world!" in the message log. +
12 + hello world (GUI) + awk bas fawk lua pas perl python tcl + Create a new action hello() that prints "Hello world!" in a modal dialog box using DAD. +
13 + hello world (GUI, with vbox) + awk bas fawk lua pas perl python tcl + Create a new action hello() that prints "Hello world!" in vertical layout in a dialog box. +
21 + timers + awk bas fawk lua pas perl python tcl + Create timers that are going to call back an action in the background. +
72 + unit converter (GUI, interactive) + awk fawk lua tcl + Interactive unit converter in a dialog, created via dad(). +
81 + script state persistency (load/unload/reload) + awk lua + Counts how many times the script was loaded, in a persistent on-disk counter. +
+ + + + Index: tags/2.3.0/doc/user/06_feature/scripting/rosetta/index.templ.html =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/rosetta/index.templ.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/rosetta/index.templ.html (revision 33253) @@ -0,0 +1,34 @@ + + + + pcb-rnd rosetta + + + + +

pcb-rnd scripting - Rosetta

+The Rosetta Stone +of pcb-rnd scripting is a collection of example scripts implemented in +various scripting languages. Rosetta has multiple purposes: +
    +
  • to provide examples of using the pcb-rnd API; +
  • to not scare away newcomers by showing the first examples in an unfamiliar language; +
  • to help the user to decide which language to use for a specific task; +
  • to provide examples on how to convert idioms of pcb-rnd scripts from one language to another. +
+

+Each example comes with an explanation, written in plain English about what the +scripts do, step by step. Instead of trying to exploit powerful features +of the language, example implementations try to be simple. +

+The list below is ordered from the least complex to the most complex examples. +Column lvl is the complexity score. The less the score is, the simpler +the example is. + + +

Index of examples

+ + + + + Index: tags/2.3.0/doc/user/06_feature/scripting/util/Makefile =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/util/Makefile (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/util/Makefile (revision 33253) @@ -0,0 +1 @@ +all: Index: tags/2.3.0/doc/user/06_feature/scripting/util/rosetta_genpages.sh =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/util/rosetta_genpages.sh (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/util/rosetta_genpages.sh (revision 33253) @@ -0,0 +1,182 @@ +#!/bin/sh + +clean_id() +{ + tr "\r\n" "~" | sed ' +s/~*$//; +s/|/\&pipe;/g; +s/&/\&/g; +s//\>/g; +s/"/\"/g; +s/'\''/\'/g; +s/~\+/
/g; +' + echo "" +} + +genpage() +{ + local dir scripts name desc + + dir="$1" + scripts="$2" + + name=`cat $dir/ID.name` + desc=`cat $dir/ID.desc` + ./tags < "$dir/ex.html" | awk -v "fn_ref=../packages/XREF" -v "scripts=$scripts" -v "name=$name" -v "desc=$desc" ' + BEGIN { + while((getline < fn_ref) > 0) { + REF[$2] = $3 + } + print "" + print "" + print "" + print " pcb-rnd rosetta", name, "" + print " " + print "" + print "" + print "" + print " <-- back to the index of Rosetta examples" + print "

" name "

" + print desc + + print "
Example implementations
" + v = split(scripts, S, "[\r\n]+") + for(n = 1; n <= v; n++) { + lang=S[n] + sub("^ex[.]", "", lang) + if (n != 1) + print " | " + print "" lang "" + } + + print "
Explanation, step by step
" + } + /^/ { + gsub("", "", $0) + name=$0 + gsub("[ \t]*", "", name) + if (name in REF) { + link_begin="" + link_end = "" + } + else { + link_begin="" + link_end="" + } + print "" link_begin $0 link_end "" + next + } + + { print $0 } + + END { + print "" + print "" + } + + ' > "$dir/index.html" +} + +gen_index() +{ + + awk -v "template=$1" ' + BEGIN { + FS="[|]" + q = "\"" + LANGS["rb"] = "ruby" + LANGS["pl"] = "perl" + LANGS["py"] = "python" + LANGS["stt"] = "stutter" + LANGS["scm"] = "scheme" + } + + ($1 == "scripts") { + s = $3 + gsub("ex[.]", "", s) + v = split(s, S, " ") + s = "" + for(n = 1; n <= v; n++) { + if (S[n] in LANGS) + s = s " " LANGS[S[n]] + else + s = s " " S[n] + } + DATA[$2, $1] = s + next + } + + ($1 == "name") { + if (names == "") + names = $2 + else + names = names "|" $2 + } + + + { + # DATA[script, name] = "hello world" + DATA[$2, $1] = $3 + } + + function generate(cmd ,N,n,v,name,level) { + if (cmd == "index") { + print "" + print "" + print "
lvlexample languages description" + v = split(names, N, "[|]") + for(n = 1; n <= v; n++) { + name = N[n] + level = name + sub("_.*", "", level) + if (level ~ "[^0-9]") + level = "n/a" + print "
" level + print " " DATA[name, "name"] "" + print " " DATA[name, "scripts"] + print " " DATA[name, "desc"] + } + print "
" + } + else + print "Do not know how to generate " cmd > "/dev/stderr" + } + + END { + FS="" + while((getline < template) > 0) { + if (match($0, "]*>")) { + print substr($0, 1, RSTART-1) + cmd=substr($0, RSTART+8, RLENGTH-9) + sub("^[ \t]*", "", cmd) + generate(cmd) + print substr($0, RSTART+RLENGTH) + } + else + print $0 + } + } + ' + +} + + +for n in ../rosetta/* +do + if test -d "$n" + then + bn=`basename $n` + scripts=`cd $n && ls ex.* | grep -v ".pyc$\|.html$" ` + genpage "$n" "$scripts" + echo -n "desc|$bn|" + clean_id < $n/ID.desc + echo -n "name|$bn|" + clean_id < $n/ID.name + echo -n "scripts|$bn|" + echo $scripts + fi +done | gen_index ../rosetta/index.templ.html > ../rosetta/index.html + + Property changes on: tags/2.3.0/doc/user/06_feature/scripting/util/rosetta_genpages.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/scripting/util/tags =================================================================== --- tags/2.3.0/doc/user/06_feature/scripting/util/tags (nonexistent) +++ tags/2.3.0/doc/user/06_feature/scripting/util/tags (revision 33253) @@ -0,0 +1,4 @@ +#!/bin/sh + +tr "\n" " " | sed "s@\(<[^/]\)@\n\1@g;s@\(]*>\)@\1\n@g" + Property changes on: tags/2.3.0/doc/user/06_feature/scripting/util/tags ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/user/06_feature/smartdisperse/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/smartdisperse/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/smartdisperse/index.html (revision 33253) @@ -0,0 +1,23 @@ + + + + pcb-rnd user manual + + + + +

smartdisperse - smart netlist disperse

+

+The smartdisperse plugin provides an action called smartdisperse that +uses a loaded netlist to arrange the layout subcircuits in a linear order at +the top of the board, based on the netlist connections rather than arbitrary +subcircuit order. To use, run in the cli with :smartdisperse() or +:smartdisperse(all) to disperse all subcircuits, or :smartdisperse(selected) to +only disperse selected. +

+The plugin is intended for use with any GUI HID for board layout. The layout +must include a netlist for smartdisperse to work. The plugin uses the netlist +to prioritize the dispersal of all the subcircuits into clusters prioritized by +netlist connections. + + Index: tags/2.3.0/doc/user/06_feature/stroke/arrow.svg =================================================================== --- tags/2.3.0/doc/user/06_feature/stroke/arrow.svg (nonexistent) +++ tags/2.3.0/doc/user/06_feature/stroke/arrow.svg (revision 33253) @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Index: tags/2.3.0/doc/user/06_feature/stroke/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/stroke/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/stroke/index.html (revision 33253) @@ -0,0 +1,51 @@ + + + + pcb-rnd user manual + + + + +

Stroke plugin

+ +

Gestures

+

+The stroke plugin uses libstroke to recognize mouse gestures. By the +default menu config gestures are recognized while the right mouse button +is pressed and the mouse is moved. If no movement happened between press +and release or the gesture is not recognized, the context menu is open. +

+What gestures are recognized and what actions are executed for them are +all configured in stroke.conf. The default configuration coming with the +plugin defines the gestures listed in the table below. Please note: it is +important to start the gesture at the specific point relative to the +subsequent coordinates of the gesture; for example the rotation gestures +always need to start at the bottom. +

+ +
gesture drawing action taken +
switch to line drawing mode +
switch to arrow mode +
stop drawing a line, polygon contour or polygon hole +
switch to via placing mode +
rotate the object under the cursor 90 degrees clock-wise +
rotate the object under the cursor 90 degrees counter-clock-wise +
undo an operation +
redo an operation +
zoom to extent (all-board view) +
zoom in to the area between the endpoints of the gesture +
+ +

Configuration

+

+The stroke plugin is compiled only if (the development package of) +libstroke is installed. Any gesture recognition takes place only if +editor/enable_stroke is set to true (e.g. "1"). +

+The gestures are configured as an ordered list of +dial-pad-sequence={pcb-rnd-actions} under plugins/stroke/gestures. +Only the first match is executed; this allows the user to override default +gestures from user or project or design config. + + + Index: tags/2.3.0/doc/user/06_feature/stroke/line.svg =================================================================== --- tags/2.3.0/doc/user/06_feature/stroke/line.svg (nonexistent) +++ tags/2.3.0/doc/user/06_feature/stroke/line.svg (revision 33253) @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Index: tags/2.3.0/doc/user/06_feature/stroke/redo.svg =================================================================== --- tags/2.3.0/doc/user/06_feature/stroke/redo.svg (nonexistent) +++ tags/2.3.0/doc/user/06_feature/stroke/redo.svg (revision 33253) @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + Index: tags/2.3.0/doc/user/06_feature/stroke/rotccw.svg =================================================================== --- tags/2.3.0/doc/user/06_feature/stroke/rotccw.svg (nonexistent) +++ tags/2.3.0/doc/user/06_feature/stroke/rotccw.svg (revision 33253) @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Index: tags/2.3.0/doc/user/06_feature/stroke/rotcw.svg =================================================================== --- tags/2.3.0/doc/user/06_feature/stroke/rotcw.svg (nonexistent) +++ tags/2.3.0/doc/user/06_feature/stroke/rotcw.svg (revision 33253) @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Index: tags/2.3.0/doc/user/06_feature/stroke/stopline.svg =================================================================== --- tags/2.3.0/doc/user/06_feature/stroke/stopline.svg (nonexistent) +++ tags/2.3.0/doc/user/06_feature/stroke/stopline.svg (revision 33253) @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Index: tags/2.3.0/doc/user/06_feature/stroke/undo.svg =================================================================== --- tags/2.3.0/doc/user/06_feature/stroke/undo.svg (nonexistent) +++ tags/2.3.0/doc/user/06_feature/stroke/undo.svg (revision 33253) @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Index: tags/2.3.0/doc/user/06_feature/stroke/via.svg =================================================================== --- tags/2.3.0/doc/user/06_feature/stroke/via.svg (nonexistent) +++ tags/2.3.0/doc/user/06_feature/stroke/via.svg (revision 33253) @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + Index: tags/2.3.0/doc/user/06_feature/stroke/zoom_ext.svg =================================================================== --- tags/2.3.0/doc/user/06_feature/stroke/zoom_ext.svg (nonexistent) +++ tags/2.3.0/doc/user/06_feature/stroke/zoom_ext.svg (revision 33253) @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Index: tags/2.3.0/doc/user/06_feature/stroke/zoom_in.svg =================================================================== --- tags/2.3.0/doc/user/06_feature/stroke/zoom_in.svg (nonexistent) +++ tags/2.3.0/doc/user/06_feature/stroke/zoom_in.svg (revision 33253) @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Index: tags/2.3.0/doc/user/06_feature/vendordrill/index.html =================================================================== --- tags/2.3.0/doc/user/06_feature/vendordrill/index.html (nonexistent) +++ tags/2.3.0/doc/user/06_feature/vendordrill/index.html (revision 33253) @@ -0,0 +1,100 @@ + + + + pcb-rnd user manual + + + + +

The vendordrill plugin - Apply Vendor Drills and DRC

+

+Load and Apply vendor file to the current design. + +

Description

+

+Footprint holes are predefined within each footprint and layer +characteristics are predefined in the layout file. Consequentially, hole +sizes may vary among footprints or not match a vendor's available drill +availability unless manually adjusted. Likewise, predefined layout layer +characteristics may mismatch a vendor's specific requirements. For +example one type of Through-Hole resistor footprint may have 40mil holes +while another may have 43.5 mil holes. + +

+Some PCB fabricators have a finite set of drill sizes available. In this +case loading a vendor file will automatically adjust the layout's hole +sizes to agree with the vendor's drill availability. + +

+Many current PCB fabricators offer any drill size within a tolerance with +just a minimum and maximum. In this case the layout's holes do not need +to match specific drill sizes but it may be desirable to normalize the +hole sizes. While the user may want all holes consistent for aesthetic +reasons there may be a fabrication cost saving if hole sizes are +consistent. Likewise, design rules, such as trace width and minimum +separation, can impact fabrication cost. In this situation the drills +listed in the vendor files would not be specific drill availability but +rather normalization values. + +

+The LoadVendorFrom() Action enables a file of vendor specific fabrication +requirements to be loaded to the current design. When the vendor file is +applied, holes will be automatically adjusted to conform to the drill +sizes listed in the vendor file and layer characteristics will be used in +any subsequent Design Rule Checks (DRC). Some critical parts where you +may not want to change the drill size can be identified to be left alone +- "skipped". + +

Vendor File Requirements

+
    + +
  • The vendor file is a text file in lihata format. It expects a + drillmap section and supports two other sections - + drc and skips. Skips + defines subcircuits to be skipped , hence the name. Skips' + extended regex + patterns may only be defined for "refdes", "value" and + "descr" attributes. + +
  • The file name can be any existing, readable filename. The file name + may be entered in two ways - explicitly or using the standard file load + dialog box of the currently active HID. +
      +
    • LoadVendorFile(your_vendor_filename) +
    • LoadVendorFile() +
    + +
  • Defaults if no entry provided +
      +
    • vendor file = vendor.lht (allowed entries: + any readable filename in lihata vendor file format) +
    • units = mil (allowed entries: mil|mils|inch|inches|mm) +
    • round = up (allowed entries up|nearest) +
    +
+ +

Example Minimal Vendor File

+
    ha:vendor_drill_map {
+  vendor = oshpark  # Optional and can be omitted
+  units = mil      # mil|mils|inch|inches|mm - mil is default
+  round = nearest  # up is default
+  li:drillmap = {
+      20
+      25
+      30
+  }
+  li:skips = {
+      refdes = {^J3$}       # Skip J3.
+      refdes = {^U[1-3]$}   # Skip U1, U2, U3
+  }
+  ha:drc = {
+      copper_space = 7
+      copper_width = 7
+      copper_overlap = 4
+      min_ring = 6
+      silk_width = 10
+      min_drill = 20
+  }
+
+ + Index: tags/2.3.0/doc/user/07_io/1_1_io_hkp/index.html =================================================================== --- tags/2.3.0/doc/user/07_io/1_1_io_hkp/index.html (nonexistent) +++ tags/2.3.0/doc/user/07_io/1_1_io_hkp/index.html (revision 33253) @@ -0,0 +1,23 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+

7.1 IO plugins

+

7.1.1 io_hkp

+ +

7.1.1.1. What is the HKP format?

+

+HKP is Mentor Graphic's file format, Hierarchical Keyword Parser. A +set of HKP files can fully describe a board that can be exported from or +imported to Expedition PCB (old name: Veribest). In theory other +of their product would work with HKP files (such as PADS), but in practice +the actual import/export could be tricky. Also, discussions on +Mentor community forums show that the company started getting rid of the +ASCII HKP format around 2010 in favor of an encrypted and/or binary file format, +so an old version of the software or a special license with new versions might +be needed. Index: tags/2.3.0/doc/user/07_io/3_1_export_openscad/1206.scad =================================================================== --- tags/2.3.0/doc/user/07_io/3_1_export_openscad/1206.scad (nonexistent) +++ tags/2.3.0/doc/user/07_io/3_1_export_openscad/1206.scad (revision 33253) @@ -0,0 +1,15 @@ +module part_1206() +{ + translate([0,0,0.3]) { + // body + color([0.1,0.1,0.1]) + cube([3.2-2*0.2,1.6,0.6], center=true); + // terminals + color([0.8,0.8,0.8]) { + translate([+1.5, 0, 0]) + cube([0.2, 1.6, 0.6], center=true); + translate([-1.5, 0, 0]) + cube([0.2, 1.6, 0.6], center=true); + } + } +} Index: tags/2.3.0/doc/user/07_io/3_1_export_openscad/index.html =================================================================== --- tags/2.3.0/doc/user/07_io/3_1_export_openscad/index.html (nonexistent) +++ tags/2.3.0/doc/user/07_io/3_1_export_openscad/index.html (revision 33253) @@ -0,0 +1,63 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+

7.2 Export plugins

+

7.2.1 export_openscad

+

+The openscad exporter generates the 3D model of the board in form of +an openscad script. +

+The main entry point of the script is pcb_board(). All coordinates are in +mm. The in x and y directions the 0;0 point of the board is the 0;0 point on +screen in pcb-rnd, to make it easy to wrap the board in a translate() after +measuring the coords of a point in pcb-rnd. The vertical origin is the middle +of the board's FR4. +

+Supported features: +

    +
  • arbitrary shaped outline +
  • top/bottom copper (optional) +
  • top/bottom mask (optional) +
  • top/bottom silk (optional) +
  • holes (optional) +
  • subcircuit (3d) models (optional) +
+ +

+Subcircuit models are loaded from external files referenced from the subcircuit +in the pcb-rnd board file. Model files are searched recursively under the +footprint library search path. +

+The subcircuit (footprint instance) can have the following openscad related +attributes, all optional: +

+ +
attrib meaning +
openscad=filename file name of the .scad script (3d subcircuit model) +
openscad-transformation=script apply the specified transformation on the model instance +
openscad-param=p1,p2,p3... parameters to pass on to the model +
+

+If the openscad attribute is not present, no 3d model is inserted. +

+If openscad-transformation is specified, it is inserted before the model +call; it typically contains a transform() and/or a rotate() to modify the +placement of the model. The 0;0;0 point of the placement is the origin of +the subcircuit in pcb-rnd, on the surface of the board. (Note: it is used to +match the model to the footprint; subcircuit rotation and translation are +automatically inserted by pcb-rnd on top of this. This attribute is empty +or not present when the model lines up with the neutral state of the footprint.) +

+If openscad-param is specified, the module is called with this parameter +list, else the model is called with empty parameter list. +

+A model file shall contain a single module, with "module" and the arbitrary +module name in the same line, { in the following line. One instance of +each model is copied into the output file so that the resulting openscad +script has no external reference and is self-contained. Index: tags/2.3.0/doc/user/07_io/3_2_export_xy/index.html =================================================================== --- tags/2.3.0/doc/user/07_io/3_2_export_xy/index.html (nonexistent) +++ tags/2.3.0/doc/user/07_io/3_2_export_xy/index.html (revision 33253) @@ -0,0 +1,89 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+

7.3 Export plugins

+

7.3.2 export_xy

+

+Export_xy is a configurable template based export plugin that prints +text files. The output contains an optional header, then an optional block +for each subcircuit and after each such subcircuit block an optional block +for each terminal in that subcircuit. In pseudo-code: +

+print header_template
+foreach subc in subcircuits {
+	print subc_template
+	foreach term in s.terminals {
+		print term_template
+	}
+}
+
+

+Templates can reference to the current term, the current +subc and global properties (such as board properties). + +

7.3.2.1 Template configuration

+

+Each xy export format has an user assigned ID (which is the short name of the format). +There is a list of strings in the config tree under plugins/export_xy/templates; +each item is named as ID.something where something is: +

    +
  • ID.name: the long name of the format (as shown on the UI); mandatory +
  • ID.hdr: header template, printed once when the output file is opened; optional +
  • ID.subc: subcircuit template, printed once when a subcircuit is entered; optional +
  • ID.term: terminal template, printed once for each terminal within each subcircuit; optional +
+

+Templates are text strings; they are printed as is, keeping all newlines and +whitespace. Portions in between % signs are substituted, depending on the +context. + +

7.3.2.2. Substitution keywords

+

+ +
keyword description +
%UTC% current date and time in UTC +
%author% board author +
%title% board title +
%suffix% coordinate unit (mm or mil) +
%boardw% boward width (unit suffixed coord) +
%boardh% boward height (unit suffixed coord) +
%subc.a.KEY% paste the current subcircuit's attribute value of the attribute whose name matches KEY; print "n/a" for non-existing attributes +
%subc.a.KEY|unk% same as %subc.a.KEY% but print "unknown" instead of "n/a" +
%subc.a.KEY?yes% same as %subc.a.KEY% but print "yes" if attribute value represents true, "n/a" otherwise +
%subc.a.KEY?yes:nope% same as %subc.a.KEY% but print "yes" if attribute value represents true, "nope" otherwise +
%subc.refdes% print the refdes of the current subcircuit +
%subc.refdes_% print the cleaned refdes of the current subcircuit +
%subc.footprint% print the footprint name of the current subcircuit +
%subc.footprint_% print the cleaned footprint name of the current subcircuit +
%subc.value% print the value of the current subcircuit +
%subc.value_% print the cleaned value of the current subcircuit +
%subc.x% print the X coordinate of the origin of the subcircuit (coord with unit suffix) +
%subc.y% print the Y coordinate of the origin of the subcircuit (coord with unit suffix) +
%subc.padx% print the X coordinate calculated from padstacks of the subcircuit (coord with unit suffix) +
%subc.pady% print the Y coordinate calculated from padstacks of the subcircuit (coord with unit suffix) +
%subc.pad_width% print the total width calculated from padstacks of the subcircuit (coord with unit suffix) +
%subc.pad_height% print the total height calculated from padstacks of the subcircuit (coord with unit suffix) +
%subc.pad_width_prerot% print the total width calculated from padstacks of the subcircuit, before applying rotation (coord with unit suffix) +
%subc.pad_height_prerot% print the total height calculated from padstacks of the subcircuit, before applying rotation (coord with unit suffix) +
%subc.rot% print the subc rotation value in degrees +
%subc.siderot% print the subc rotation value in degrees, always looking from the top side, "x-ray mode" (relative to side) +
%subc.270-rot% print the subc rotation value in degrees, subtracted from 270 +
%subc.side270-rot% print the subc rotation value in degrees, always looking from the top side, "x-ray mode", subtracted from 270 (relative to side) +
%subc.side% "top" or "bottom" (determined by subc placement, the subc aux layer) +
%subc.num-side% "1" for top or "2" for bottom (determined by subc placement, the subc aux layer) +
%subc.count% integer value, incremented by one before processing each subcircuit +
%subc.smdvsthru% "SMD" if contains padstacks but no padstack with hole; "PTH" if contains padstack with hole; "0" if neither +
%subc.smdvsthrunum% "2" if contains padstacks but no padstack with hole; "1" if contains padstack with hole; "0" if neither +
%subc.pincout% "pin" or "pad" count. Do not use. +
%term.netname% name of the net the current terminal should be connected to according to the netlist; "NC" for no connection +
+ +

+Cleaned means any character that is non-alphanumeric, not "." and not "-" +and not "+" is replaced with "_". Index: tags/2.3.0/doc/user/07_io/index.html =================================================================== --- tags/2.3.0/doc/user/07_io/index.html (nonexistent) +++ tags/2.3.0/doc/user/07_io/index.html (revision 33253) @@ -0,0 +1,36 @@ + + + + pcb-rnd user manual + + + + + +

7. File format support

+Besides its native file format (lihata), pcb-rnd supports various +alien file formats. Support for each file format is implemented in +a separate plugin. +

+There are three types of file format plugins: +import plugins for partial load, export plugins for partial save and +io plugins for complete and/or bidirectional load/save. Partial in this +context means not the whole board, but only a few aspects of it are +handled. +

+ +

+ + + Index: tags/2.3.0/doc/user/08_util/01_gsch2pcb-rnd.html =================================================================== --- tags/2.3.0/doc/user/08_util/01_gsch2pcb-rnd.html (nonexistent) +++ tags/2.3.0/doc/user/08_util/01_gsch2pcb-rnd.html (revision 33253) @@ -0,0 +1,48 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+ +

8.1. gsch2pcb-rnd

+

+Gsch2pcb-rnd is a standalone utility that can extract netlists and +element data from a schematics produced by gschem. Thus it is a glue +between gschem and pcb-rnd, doing forward annotation. It is ideal +for automating the design process as it can be easily called from +Makefiles, shell scripts or other programs/scripts, whereas the +"import schematics" feautre (import_sch plugin) is more geared for the +GUI user. +

+Multiple methods of operation are offered - the user can select +one of these by name, using the -m command line argument (e.g. +gsch2pcb-rnd -m importsep foo.sch): + + + + + +
method name + description +
import + Runs the same gnetlist backend as the import_sch plugin. A single + action command file generated with .cmd suffix. When executed + (using action ExcuteFile(foo.cmd)), it syncs (replaces/creates) + every element and sets up all nets. Pro: single-command import. + Con: can't load netlist only or elements only. +
importsep + Similar to import, but produces two files: a .cmd file with element + updates only (can be appled the same way as import's) and a + separate .net netlist file that can be imported the same way as the + .net of the pcb method. Pro: the user can update elements-only or + nets-only. Con: requires two user actions to get a full impoty. +
pcb + The classic approach that tried to edit the .pcb file. + No longer supported. +
+ + Index: tags/2.3.0/doc/user/08_util/02_cgi.html =================================================================== --- tags/2.3.0/doc/user/08_util/02_cgi.html (nonexistent) +++ tags/2.3.0/doc/user/08_util/02_cgi.html (revision 33253) @@ -0,0 +1,53 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+ +

8.2. Installation of the footprint CGIs

+

8.2.1. system requirements, 3rd party software

+ The following software needs to be installed on the system + that will host the scripts: +
    +
  • /bin/bash (did not test with POSIX shell) +
  • awk (tested with gawk, may work with other modern implementation) +
  • common binutils, e.g. ls, find +
  • animator, the svn HEAD version; NOTE: it is possible to manually compile animator into a static executable (useful on dedicated web servers) +
  • a web server that can execute plain old CGI scripts +
  • a full checkout of pcb-rnd/trunk from svn://repo.hu/pcb-rnd/trunk +
+ +

8.2.2. Installation

+Since the CGIs are just demo scripts for repo.hu and are not really installed +anywhere else normally, there is no install script but a manual installation +process. For both the parametric and the static footprint CGI: +
    +
  1. check out pcb-rnd/trunk in a directory readable (but not writable) by www-data (or whatever user the CGI will run with) +
  2. copy the config file pcblib.cgi.conf from pcb-rnd/trunk/util to /etc +
  3. edit the config file; ignore setting sdir for now +
  4. hardlink, copy, or wrap the cgi files from under pcb-rnd/trunk/util into the web server's CGI directory +
+

+For the static footprint CGI (set up the map cache): +

    +
  1. cd to trunk/util/pcblib-map in the checkout and run make - NOTE: some awk scripts have hardwired CGI paths yet (TODO) +
  2. copy this directory to a web-accessible directory +
  3. set sdir to the absolute path of the web-accessible copy in /etc/pcblib.cgi.conf +
+ +

8.2.3. Tips and tricks

+

8.2.3.1. cgi wrapping

+Making the checkout directly into the cgi-bin dir is not a good idea. Using +a hard link on each CGI between the checkout and the cgi-bin dir is better, +but an svn up will silently break the link leaving the old version live. +The most stable solution is placing a wrapper script in the cgi-bin dir: +
+#!/bin/bash
+. /full/path/to/the/checkout/util/pcblib-param.cgi
+
+ + Index: tags/2.3.0/doc/user/08_util/index.html =================================================================== --- tags/2.3.0/doc/user/08_util/index.html (nonexistent) +++ tags/2.3.0/doc/user/08_util/index.html (revision 33253) @@ -0,0 +1,20 @@ + + + + pcb-rnd user manual + + + + + +

8. Utilities

+There are a few stand-alone utility programs shipped with pcb-rnd. These +are typically for building custom workflows or debugging. +

+

+ + + Index: tags/2.3.0/doc/user/09_appendix/action_details.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_details.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_details.html (revision 33253) @@ -0,0 +1,4269 @@ + + + + + pcb-rnd user manual - action details + + + + +

pcb-rnd actions (details)

+ + + +

AddRats

+
+

+ +
Syntax summary: +AddRats(AllRats|SelectedRats|Close, [manhattan]) +
Help text: +Add one or more rat lines to the board. +
Registered by:n/a +
+

+First argument: +

+ + + + + + + + + +
+ AllRats + + Create rat lines for all loaded nets that aren't already connected on with copper. +
+ SelectedRats + + Similarly, but only add rat lines for nets connected to selected pins and pads. +
+ Close + + Selects the shortest unselected rat on the board. +
+ +

+ The second argument is temporary and optional, for a workaround of a bug in the old (to be removed) autorouter. If the value of the second argument is "manhattan", non-axis-aligned lines are ignored when looking for rat anchor points. +

+ +

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. +

+ +

AdjustStyle

+
+

+ +
Syntax summary: +AdjustStyle([routestyle_idx]) +
Help text: +Open the dialog box for editing the route styles. +
Registered by: +lib_hid_pcbui/route_style +
+

+With no argument or negative argument, operate on the currently selected style (if there's any). Else operate on the style indexed. +

+ +

align

+
+

+ +
Syntax summary: +Align(X/Y, [Lefts/Rights/Tops/Bottoms/Centers/Marks, [First/Last/pcb_crosshair/Average[, Gridless]]]) +
Help text: +Align objects +
Registered by: +distalign plugin +
+

+ +Example: Align(X, [Lefts/Rights/Centers/Marks, [First/Last/pcb_crosshair/Average[, Gridless]]])
+ +

+ +Example: Align(Y, [Tops/Bottoms/Centers/Marks, [First/Last/pcb_crosshair/Average[, Gridless]]])
+ +

+ Arguments: +

+ + + + + + + + + + + +
+ X or Y + +Select which axis will move, other is untouched. +
+ Lefts, Rights, Tops, Bottoms, Centers, Marks + + Pick alignment point within each object +
+ First, Last, pcb_crosshair, Average + + Alignment reference, First=Topmost/Leftmost, Last=Bottommost/Rightmost, Average or pcb_crosshair point +
+ Gridless + + Do not force results to align to prevailing grid. +
+ +

+ Defaults are Marks, First. +

+ For non-subcircuit objects: using Marks is not recommended, using Gridless is recommended. +

+ +

ApplyVendor

+
+

+ +
Syntax summary: +ApplyVendor() +
Help text: +Applies the currently loaded vendor drill table to the current design. +
Registered by: +vendor drill mapping +
+

+This will modify all of your drill holes to match the list of allowed sizes for your vendor. +

+ +

Atomic

+
+

+ +
Syntax summary: +Atomic(Save|Restore|Close|Block) +
Help text: +Save or restore the undo serial number. +
Registered by:n/a +
+

+This action allows making multiple-action bindings into an atomic operation that will be undone by a single Undo command. For example, to optimize rat lines, you'd delete the rats and re-add them. To group these into a single undo, you'd want the deletions and the additions to have the same undo serial number. So, you +Save +, delete the rats, +Restore +, add the rats - using the same serial number as the deletes, then +Block +, which checks to see if the deletions or additions actually did anything. If not, the serial number is set to the saved number, as there's nothing to undo. If something did happen, the serial number is incremented so that these actions are counted as a single undo step. +

+ An alternative mechanism is freeze/unfreeze for the case restoring between every two actions is not possible or not practical. The sequence is +Save +, +Freeze +, call actions, +UnFreeze +, +Block +. +

+ Arguments: +

+ + + + + + + + + + + + + + + +
+ Save + + Saves the undo serial number. +
+ Restore + + Returns it to the last saved number. +
+ Close + + Sets it to 1 greater than the last save. +
+ Block + + Does a Restore if there was nothing to undo, else does a Close. +
+ Freeze + + Make sure no subsequent actions will bump the undo serial +
+ UnFreeze or Thaw + + Allow subsequent actions to bump the undo serial again +
+ +

+ +

Attributes

+
+

+ +
Syntax summary: +Attributes(Layout|Layer|Element|Subc) +Attributes(Layer,layername) +
Help text: +Let the user edit the attributes of the layout, current or given +layer, or selected subcircuit. +
Registered by: +oldactions plugin +
+

+Pops up a dialog letting the user edit the attributes of the pcb, a subcircuit, or a layer. +

+ +

AutoPlaceSelected

+
+

+ +
Syntax summary: +AutoPlaceSelected() +
Help text: +Auto-place selected components. +
Registered by: +autoplace plugin +
+

+Attempts to re-arrange the selected components such that the nets connecting them are minimized. Note that you cannot undo this. +

+ +

AutoRoute

+
+

+ +
Syntax summary: +AutoRoute(AllRats|SelectedRats) +
Help text: +Auto-route some or all rat lines. +
Registered by: +autoroute plugin +
+

+Before autorouting, it's important to set up a few things. First, make sure any layers you aren't using are disabled, else the autorouter may use them. Next, make sure the current routing styles are set accordingly. Last, make sure "new lines clear polygons" is set, in case you eventually want to add a copper pour. +

+ Autorouting takes a while. During this time, the program may not be responsive. +

+ Arguments: +

+ + + + + + + +
+ AllRats + + Attempt to autoroute all rats. +
+ SelectedRats + + Attempt to autoroute the selected rats. +
+ +

+ +

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. +

+ +

BoardFlip

+
+

+ +
Syntax summary: +BoardFlip([sides]) +
Help text: +Mirror the board over the x axis, optionally mirroring sides as well. +
Registered by:n/a +
+

+All objects on the board are up-down flipped (mirrored over the x axis). +

+ Command line board flipping: +

+ echo " BoardFlip() SaveTo(LayoutAs,$OUTFILE) Quit() " | pcb $INFILE 
+
+ +

+ To flip the board physically, use BoardFlip(sides) +

+ +

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. +

+ +

ChangeClearSize

+
+

+ +
Syntax summary: +ChangeClearSize(Object, delta|style) +ChangeClearSize(SelectedPins|SelectedPads|SelectedVias, delta|style) +ChangeClearSize(SelectedLines|SelectedArcs, delta|style) +ChangeClearSize(Selected|SelectedObjects, delta|style) +
Help text: +Changes the clearance size of objects. +
Registered by:n/a +
+

+If the solder mask is currently showing, this action changes the solder mask cutout size. If the mask is not showing, this action changes the polygon clearance. +

+ +

ChangeFlag

+
+

+ +
Syntax summary: +ChangeFlag(Object|Selected|SelectedObjects, flag, value) +ChangeFlag(SelectedLines|SelectedPins|SelectedVias, flag, value) +ChangeFlag(SelectedPads|SelectedTexts|SelectedNames, flag, value) +ChangeFlag(SelectedElements, flag, value) +flag = join +value = 0 | 1 +
Help text: +Sets or clears flags on objects. +
Registered by:n/a +
+

+Toggles the given flag on the indicated object(s). The flag may be one of the flags listed above (thermal, join). The value may be the number 0 or 1. If the value is 0, the flag is cleared. If the value is 1, the flag is set. +

+ +

ChangeJoin

+
+

+ +
Syntax summary: +ChangeJoin(ToggleObject|SelectedLines|SelectedArcs|Selected) +
Help text: +Changes the join (clearance through polygons) of objects. +
Registered by:n/a +
+

+The join flag determines whether a line or arc, drawn to intersect a polygon, electrically connects to the polygon or not. When joined, the line/arc is simply drawn over the polygon, making an electrical connection. When not joined, a gap is drawn between the line and the polygon, insulating them from each other. +

+ +

ChangeName

+
+

+ +
Syntax summary: +ChangeName(Object) +ChangeName(Refdes) +ChangeName(Layout|Layer) +
Help text: +Sets the name, text string, terminal ID or refdes of objects. +
Registered by:n/a +
+

+Arguments: +

+ + + + + + + + + + + +
+ Object + + Changes the "name" of the object under the cursor. For a text object this is the text string. For a terminal, this is the terminal ID. For a subcircuit this is the refdes. For a subc text object that has only the refdes template in it, it offers changing the text object (template) or the parent subcircuit's refdes attribute. +
+ Refdes + + Changes the refdes attribute of a subcircuit under the cursor. +
+ Layout + + Changes the name of the layout. This is printed on the fab drawings. +
+ Layer + + Changes the name of the currently active layer. +
+ +

+ +

ChangePinName

+
+

+ +
Syntax summary: +ChangePinName(Refdes,PinNumber,PinName) +
Help text: +Sets the name of a specific pin on a specific subcircuit. +
Registered by:n/a +
+

+This can be especially useful for annotating pin names from a schematic to the layout without requiring knowledge of the pcb file format. +

+ +Example: ChangePinName(U3, 7, VCC)
+ +

+ +

ChangeSize

+
+

+ +
Syntax summary: +ChangeSize(Object, delta|style) +ChangeSize(SelectedObjects|Selected, delta|style) +ChangeSize(SelectedLines|SelectedPins|SelectedVias, delta|style) +ChangeSize(SelectedPads|SelectedTexts|SelectedNames, delta|style) +ChangeSize(SelectedElements, delta|style) +
Help text: +Changes the size of objects. +
Registered by:n/a +
+

+For lines and arcs, this changes the width. For padstacks, this changes the shape size (but does not touch the hole diameter). For texts, this changes the scaling factor. For subcircuits, this changes the width of the lines and arcs and shape sizes of padstacks (thus mostly relative values make sense). +

+ +

ChangeSizes

+
+

+ +
Syntax summary: +ChangeSizes(Object, delta|style) +ChangeSizes(SelectedObjects|Selected, delta|style) +ChangeSizes(SelectedLines|SelectedPins|SelectedVias, delta|style) +ChangeSizes(SelectedPads|SelectedTexts|SelectedNames, delta|style) +ChangeSizes(SelectedElements, delta|style) +
Help text: +Changes all sizes of objects. +
Registered by:n/a +
+

+Call ChangeSize, ChangeDrillSize and ChangeClearSize with the same arguments. If any of them did not fail, return success. +

+ +

ChkLayer

+
+

+ +
Syntax summary: +ChkLayer(layerid) +
Help text: +Returns 1 if the specified layer is the active layer +
Registered by:n/a +
+

+Returns 1 if the specified layer is the active layer. +

+ +

ChkRst

+
+

+ +
Syntax summary: +ChkRst(route_style_id) +
Help text: +Return 1 if route_style_id matches pen. +
Registered by:n/a +
+

+Return 1 if route_style_id matches pen. +

+ +

ChkView

+
+

+ +
Syntax summary: +ChkView(layerid) +
Help text: +Return 1 if layerid is visible. +
Registered by:n/a +
+

+Return 1 if layerid is visible. Intended for menu item 'checked' fields. +

+ +

claimnet

+
+

+ +
Syntax summary: +ClaimNet(object|selected|found,[netname]) +
Help text: +Claim existing connections and create a new net +
Registered by:n/a +
+

+The ClaimNet() action can be used to construct network metadata (netlist entry) converting existing physical (galvanic, copper) connections or object lists. +

+ When galvanic connections are mapped, the first argument shall be +object +; in this case the object under the mouse cursor is the starting point and anything galvanically connected (at the moment) is considered part of the new network. This mode of operation is useful for capturing existing nets. +

+ When the first argument is +selected + or +found +, the list of (selected or found) terminals are converted to a new net, regardless of galvanic connections. This mode is useful for designing a PCB by a netlist but without a schematics - in this setup the netlist is "drawn" in pcb-rnd as well. +

+ If +netname + is specified, the user is prompted for a name. +

+ +

ClrFlag

+
+

+ +
Syntax summary: +ClrFlag(Object|Selected|SelectedObjects, flag) +ClrFlag(SelectedLines|SelectedPins|SelectedVias, flag) +ClrFlag(SelectedPads|SelectedTexts|SelectedNames, flag) +ClrFlag(SelectedElements, flag) +flag = thermal | join +
Help text: +Clears flags on objects. +
Registered by:n/a +
+

+Turns the given flag off, regardless of its previous setting. See +changeflag +. +

+ +Example: ClrFlag(SelectedLines,join)
+ +

+ +

Command

+
+

+ +
Syntax summary: +Command() +
Help text: +Displays the command line input in the status area. +
Registered by: +lib_hid_common plugin +
+

+The command entry allows the user to manually enter actions to be executed. This action opens the command entry. +

+ There are two ways to finish with the command window. If you press the + +Enter + + key, the command is invoked, the entry normally goes away, and the next time you bring up the command window it's empty. If you press the + +Esc + + key, the window goes away without invoking anything, and the next time you bring up the command window it's empty. +

+ Use the + +up + + and + +down + + arrow keys to access command history. +

+ +

Connection

+
+

+ +
Syntax summary: +Connection(Find|ResetLinesAndPolygons|ResetPinsAndVias|Reset) +
Help text: +Searches connections of the object at the cursor position. +
Registered by:n/a +
+

+Connections found with this action will be highlighted in the "connected-color" color and will have the "found" flag set. +

+ Arguments: +

+ + + + + + + + + + + + + + + +
+ Find + + The net under the cursor is "found". +
+ ResetLayerObjects + + Any "found" layer objects (lines, arcs, polygons and texts) are marked "not found". +
+ ResetPadstacks + + Any "found" padstack are marked "not found". WARNING: does not touch non-padstack heavy terminals! +
+ Reset + + All "found" objects are marked "not found". +
+ ResetLinesAndPolygons + + Obsolate, misleading name for ResetLayerObjects. Do not use. +
+ ResetPinsAndVias + + Obsolate, misleading name for ResetPadstacks. Do not use. +
+ +

+ +

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. +
+ +

+ +

CycleDrag

+
+

+ +
Syntax summary: +CycleDrag() +
Help text: +Cycle through which object is being dragged +
Registered by:n/a +
+

+When multiple overlapping objects are accessible by clicking on a pixel on the screen, drag&drop operations may become harder to do: pcb-rnd will often "pick the wrong object" on click. +

+ Cycledraw provides a way to get pcb-rnd to jump to selecting another object of the avaialble ones on the original site, while the user is still in drag mode. This obviously works only through the key binding, as selecting the menu would require the drag operation to finish first. +

+ +

DisperseElements

+
+

+ +
Syntax summary: +DisperseElements(All|Selected) +
Help text: +Disperses subcircuits. +
Registered by:n/a +
+

+Normally this is used when starting a board, by selecting all subcircuits and then dispersing them. This scatters the subcircuits around the board so that you can pick individual ones, rather than have all the subcircuits at the same 0,0 coordinate and thus impossible to choose from. +

+ +

Display

+
+

+ +
Syntax summary: +Display(SubcID, template) +Display(Grid|Redraw|Pinout|PinOrPadName) +Display(CycleClip|ToggleAllDirections|ToggleStartDirection) +Display(ToggleGrid|ToggleRubberBandMode|ToggleUniqueNames) +Display(ToggleName|ToggleClearLine|ToggleFullPoly|ToggleSnapPin) +Display(ToggleSnapOffGridLine|ToggleHighlightOnPoint|ToggleCheckPlanes) +Display(ToggleThindraw|ToggleThindrawPoly|ToggleOrthoMove|ToggleLocalRef) +Display(ToggleLiveRoute|ToggleShowDRC|ToggleAutoDRC|LockNames|OnlyNames) +
Help text: +Several display-related actions. +
Registered by:n/a +
+

+Changes random display related global states. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ SubcID +
+ Description +
+ Value +
+Specify the subcircuit ID template to be printed on the subcircuit layer +
+ Redraw + +Redraw the whole board. +
+ ToggleAllDirections + +When clear, lines can be drawn at any angle. When set, lines are restricted to multiples of 45 degrees and requested lines may be broken up according to the clip setting. +
+ CycleClip + +Changes the way lines are restricted to 45 degree increments. The various settings are: straight only, orthogonal then angled, and angled then orthogonal. If AllDirections is set, this action disables it. +
+ CycleCrosshair + +Changes crosshair drawing. Crosshair may accept form of 4-ray, 8-ray and 12-ray cross. +
+ ToggleRubberBandMode + +If set, moving an object moves all the lines attached to it too. +
+ ToggleStartDirection + +If set, each time you set a point in a line, the Clip toggles between orth-angle and angle-ortho. +
+ ToggleUniqueNames + +If set, you will not be permitted to change the name of an element to match that of another element. +
+ ToggleSnapPin + +If set, pin centers and pad end points are treated as additional grid points that the cursor can snap to. +
+ ToggleSnapOffGridLine + +If set, snap at some sensible point along a line. +
+ ToggleHighlightOnPoint + +If set, highlights lines and arcs when the crosshair is on one of their two (end) points. +
+ ToggleLocalRef + +If set, the mark is automatically set to the beginning of any move, so you can see the relative distance you've moved. +
+ ToggleThindraw + +If set, objects on the screen are drawn as outlines (lines are drawn as center-lines). This lets you see line endpoints hidden under pins, for example. +
+ ToggleThindrawPoly + +If set, polygons on the screen are drawn as outlines. +
+ ToggleShowDRC + +If set, pending objects (i.e. lines you're in the process of drawing) will be drawn with an outline showing how far away from other copper you need to be. +
+ ToggleLiveRoute + +If set, the progress of the autorouter will be visible on the screen. +
+ ToggleAutoDRC + +If set, you will not be permitted to make connections which violate the current DRC and netlist settings. +
+ ToggleCheckPlanes + +If set, lines and arcs aren't drawn, which usually leaves just the polygons. If you also disable all but the layer you're interested in, this allows you to check for isolated regions. +
+ ToggleOrthoMove + +If set, the crosshair is only allowed to move orthogonally from its previous position. I.e. you can move a subcircuit or line up, down, left, or right, but not up+left or down+right. +
+ ToggleName + +Selects whether the pinouts show the pin names or the pin numbers. +
+ ToggleLockNames + +If set, text will ignore left mouse clicks and actions that work on objects under the mouse. You can still select text with a lasso (left mouse drag) and perform actions on the selection. +
+ ToggleOnlyNames + +If set, only text will be sensitive for mouse clicks and actions that work on objects under the mouse. You can still select other objects with a lasso (left mouse drag) and perform actions on the selection. +
+ ToggleClearLine + +When set, the clear-line flag causes new lines and arcs to have their "clear polygons" flag set, so they won't be electrically connected to any polygons they overlap. +
+ ToggleFullPoly + +When set, the full-poly flag causes new polygons to have their "full polygon" flag set, so all parts of them will be displayed instead of only the biggest one. +
+ ToggleGrid + +Resets the origin of the current grid to be wherever the crosshair is. If you provide two numbers after this, the origin is set to that coordinate. +
+ Grid + +Toggles whether the grid is displayed or not. +
+ Pinout + +Causes the pinout of the subcircuit indicated by the cursor to be displayed, usually in a separate window. +
+ PinOrPadName + +Toggles whether the names of terminals will be displayed. If the cursor is over an subcircuit, all of its terminals are affected. +
+ +

+ +

distribute

+
+

+ +
Syntax summary: +Distribute(X/Y, [Lefts/Rights/Tops/Bottoms/Centers/Marks/Gaps, [First/Last/pcb_crosshair, First/Last/pcb_crosshair[, Gridless]]]) +
Help text: +Distribute objects +
Registered by: +distalign plugin +
+

+ +Example: Distribute(X, [Lefts/Rights/Centers/Marks/Gaps, [First/Last/pcb_crosshair, First/Last/pcb_crosshair[, Gridless]]])
+ +

+ +Example: Distribute(Y, [Tops/Bottoms/Centers/Marks/Gaps, [First/Last/pcb_crosshair, First/Last/pcb_crosshair[, Gridless]]])
+ +

+ As with +align +, plus: +

+ Arguments: +

+ + + + + + + +
+ Gaps + + Make gaps even rather than spreading points evenly. +
+ First, Last, pcb_crosshair + + Two arguments specifying both ends of the distribution, they can't both be the same. +
+ +

+ Defaults are Marks, First, Last +

+ Distributed objects always retain the same relative order they had before they were distributed. +

+ For non-subcircuit objects: using Marks is not recommended, using Gridless is recommended. +

+ +

djopt

+
+

+ +
Syntax summary: +djopt(debumpify|unjaggy|simple|vianudge|viatrim|orthopull) +djopt(auto) - all of the above +djopt(miter) +
Help text: +Perform various optimizations on the current board. +
Registered by: +djopt +
+

+The different types of optimizations change your board in order to reduce the total trace length and via count. +

+ Arguments: +

+ + + + + + + + + + + + + + + + + + + + + +
+ debumpify + + Looks for U-shaped traces that can be shortened or eliminated. +
+ unjaggy + + Looks for corners which could be flipped to eliminate one or more corners (i.e. jaggy lines become simpler). +
+ simple + + Removing uneeded vias, replacing two or more trace segments in a row with a single segment. This is usually performed automatically after other optimizations. +
+ vianudge + + Looks for vias where all traces leave in the same direction. Tries to move via in that direction to eliminate one of the traces (and thus a corner). +
+ viatrim + + Looks for traces that go from via to via, where moving that trace to a different layer eliminates one or both vias. +
+ orthopull + + Looks for chains of traces all going in one direction, with more traces orthogonal on one side than on the other. Moves the chain in that direction, causing a net reduction in trace length, possibly eliminating traces and/or corners. +
+ splitlines + + Looks for lines that pass through vias, pins, or pads, and splits them into separate lines so they can be managed separately. +
+ auto + + Performs the above options, repeating until no further optimizations can be made. +
+ miter + + Replaces 90 degree corners with a pair of 45 degree corners, to reduce RF losses and trace length. +
+ +

+ +

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. +
+ +

+ +

DRC

+
+

+ +
Syntax summary: +DRC([list|simple|print|log|dump]) +
Help text: +Invoke the DRC check. Results are presented as the argument requests. +
Registered by:n/a +
+

+Output styles available: + + + + + + + + + + + + + + +
+ name + + description +
+ list + + display a full list of all violations, with preview of the current item (large dialog) +
+ simple + + a small & simple dialog that navigates the user through the violations one by one, sequentially +
+ print + + print the list to stdout in human readable form +
+ log + + print the list as INFO lines in the log in human readable form +
+ dump + + print the list to stdout in script readable form +
+ +

+ Note that the design rule check uses the current board rule settings, not the current style settings. +

+ +

ElementList

+
+

+ +
Syntax summary: +ElementList(Start|Done|Need,,,) +
Help text: +Adds the given element if it doesn't already exist. +
Registered by:n/a +
+

+Arguments: +

+ + + + + + + + + +
+ Start + + Indicates the start of an subcircuit list; call this before any +Need + actions. +
+ Need + + Searches the board for an subcircuit with a matching refdes. +
+ If found, the value and footprint are updated. +
+ If not found, a new subcircuit is created with the given footprint and value. +
+ Done + + Compares the list of subcircuits needed since the most recent +Start + with the list of subcircuits actually on the board. Any subcircuits that weren't listed are selected, so that the user may delete them. +
+ +

+ Placement of new subcircuits depends on conf node import/footprint_placement/method, which is a string containing a one word instruction that is one of: +

+ + + + + + + +
+ disperse + + place all new subcircuits at randomized coordinates around + +location + +, within a distance configured in import/footprint_placement/disperse +
+ frame + + place all new subcircuits close outside of the drawing area, "framing" the design +
+ +

+ + +Location + + is a string instruction specified by import/footprint_placement/location, the value is one of: +

+ + + + + + + + + +
+ (empty, no value) + + place around the coordinates specified in coords import/footprint_placement/x and import/footprint_placement/y +
+ center + + place around the center of the drawing area +
+ mark + + place around the mark (or center of the drawing area if no mark present at the moment of import) +
+ +

+ Removal of excess subcircuits (the ones present on the board but not in the new netlist) depends on conf node import/footprint_removalt/method, which is a string containing a one word instruction that is one of: +

+ + + + + + + + + +
+ select (or empty) + + select excess subcircuits (an {s r} after the import removes them) +
+ remove + + automatically remove excess subcircuits +
+ list + + no change on excess subcircuit data on the board, but open a view list dialog enumerating them +
+ +

+ Note: subcircuits with the nonetlist flag set or empty/missing refdes will not be taken as excess even if they are not present on the netlist. +

+ +

ElementSetAttr

+
+

+ +
Syntax summary: +ElementSetAttr(refdes,name[,value]) +
Help text: +Sets or clears an element-specific attribute. +
Registered by:n/a +
+

+If a value is specified, the named attribute is added (if not already present) or changed (if it is) to the given value. If the value is not specified, the given attribute is removed if present. +

+ +

ExecuteFile

+
+

+ +
Syntax summary: +ExecuteFile(filename) +
Help text: +Run actions from the given file. +
Registered by:n/a +
+

+Lines starting with + +# + + are ignored. +

+ +

ExportOldConn

+
+

+ +
Syntax summary: +ExportOldConn(AllConnections|AllUnusedPins|ElementConnections,filename) +
Help text: +Export galvanic connection data in an old, custom file format. +
Registered by: +export_oldconn HID +
+

+Arguments: +

+ + + + + + + + + +
+ AllConnections + + Save all connections to a file. +
+ AllUnusedPins + + List all unconnected terminals to a file. +
+ ElementConnections + + Save connections to the subcircuit at the cursor to a file. +
+ +

+ +

Flip

+
+

+ +
Syntax summary: +Flip(Object|Selected) +
Help text: +Flip a subcircuit to the opposite side of the board. +
Registered by:n/a +
+

+Note that the location of the subcircuit will be symmetric about the cursor location; i.e. if the part you are pointing at will still be at the same spot once the subcircuit is on the other side. When flipping multiple subcircuits, this retains their positions relative to each other, not their absolute positions on the board. +

+ +

FreeRotateBuffer

+
+

+ +
Syntax summary: +FreeRotateBuffer([Angle]) +
Help text: +Rotates the current paste buffer contents by the specified angle. The +angle is given in degrees. If no angle is given, the user is prompted +for one. +
Registered by:n/a +
+

+Rotates the contents of the pastebuffer by an arbitrary angle. If no angle is given, the user is prompted for one. +

+ +

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. +

+ +

GfxMod

+
+

+ +
Syntax summary: +GfxMod(transparent, [idpath, [#rrggbb]]) +GfxMod(transparent, [idpath, [x, y]]) +GfxMod(resize, [idpath, [pdx, pdy1, len]]) +
Help text: +Modify a gfx object: set transparent pixel on the pixmap or resize by measurement +
Registered by:n/a +
+

+Commands: +

    + +
  • + transparent, no more args: interactive way for the user to specify the transparent color by a click +
  • + transparent, idpath, #rrggbb: specify transparent color +
  • + transparent, idpath, px, py: specify transparent color by pixel coordinates within the pixmap +
  • + resize, no more args: interactive resizer where the user clicks on two points of the pixmap on screen and specifies the real disatnce between them and the code resizes the pixmap to match that +
  • + resize, idpath, pdx, pdy, len: resize pixmap so that pixel distance pdx;pdy will match len coord units +
+ +
+ +

Import

+
+

+ +
Syntax summary: +Import() +Import([gnetlist|make[,source,source,...]]) +Import(setnewpoint[,(mark|center|X,Y)]) +Import(setdisperse,D,units) +
Help text: +Import schematics. +
Registered by: +oldactions plugin +
+

+Deprecated. Please use +importsch + instead. +

+ For help on switching over, please read this: + +err0002 + + +

+ +

ImportGUI

+
+

+ +
Syntax summary: +ImportGUI() +
Help text: +Asks user which schematics to import into PCB. +
Registered by: +oldactions plugin +
+

+Deprecated. Please use +importsch + instead. +

+ For help on switching over, please read this: + +err0002 + + +

+ +

ImportSch

+
+

+ +
Syntax summary: +ImportSch() +ImportSch(reimport) +ImportSch(setup, importer, [args...]) +
Help text: +Import schematics/netlist. +
Registered by: +import_sch2 plugin +
+

+Imports netlist (and optionally footprint references) from schematic(s) or netlist(s). Works from one or multiple input files. This action does not do file operations on its own, it is merely a dispatched to import plugins. +

+ The import configuration is normally stored in the config tree of the board file (on the + +design + + role of the conf system) and consists of: +

    + +
  • + the name of the importer that will load the input files +
  • + a list of arguments to the importer (strings, most often input file names) +
  • + misc settings, e.g. verbosity of the import +
+ +

+ When called without argument, or with the +reimport + the action will read the config and perform an import. +

+ When called with +setup +, the action will store the configuration read from the rest of the arguments: +

+  
+importsch
+(setup, 
+importer
+, 
+args...
+) 
+
+ +

+ There can be zero or more arguments following the importer. The syntax and meaning of those arguments are specific to the importer, but is most usually the file name(s) to import from, e.g. +

+ ImportSch(setup, tEDAx, foo.tdx) 
+
+ +
+ ImportSch(setup, gnetlist, sheet1.sch, sheet2.sch) 
+
+ +

+ When called with +dialog +, the action will present a non-modal GUI dialog that allows changing the setup and performing the import. +

+ +

l

+
+

+ +
Syntax summary: +l [name] [format] +
Help text: +Loads layout data. +
Registered by: +shand_cmd plugin +
+

+Loads a new datafile (layout) and, if confirmed, overwrites any existing unsaved data. If no filename is specified a file select box will popup. +

+ +

LayerByStack

+
+

+ +
Syntax summary: +LayerByStack(select, prev|next) +
Help text: +Layer operations based on physical layer stacking +
Registered by:n/a +
+

+First argument determines what to perform. When first argument is +select +, the second argument is either +prev + or +next + and the previous or next layer on the layer stack is selected. Note: layers are displayed in the layer stack order in the layer selector widget (normally on the left side of the main window) so prev/next is stepping up/down on that list. +

+ +

le

+
+

+ +
Syntax summary: +le [name] +
Help text: +Loads an element (subcircuit, footprint) into the current buffer. +
Registered by: +shand_cmd plugin +
+

+The +filename + is passed to the footprint loader. If no filename is specified a file select box will popup. +

+ +

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 + +. +
+ +

+ +

Load

+
+

+ +
Syntax summary: +Load() +Load(Layout|LayoutToBuffer|ElementToBuffer|Netlist|Revert) +
Help text: +Load layout data from a user-selected file. +
Registered by: +dialogs plugin +
+

+This action is a GUI front-end to the core's +loadfrom + action. If you happen to pass a filename, +loadfrom + is called directly. Else, the user is prompted for a filename to load, and then +loadfrom + is called with that filename. +

+ +

LoadFootprint

+
+

+ +
Syntax summary: +LoadFootprint(filename[,refdes,value]) +
Help text: +Loads a single footprint by name. +
Registered by:n/a +
+

+Loads a single footprint by name, rather than by reference or through the library. If a refdes and value are specified, those are inserted into the footprint as well. The footprint remains in the paste buffer. +

+ +

LoadFrom

+
+

+ +
Syntax summary: +LoadFrom(Layout|LayoutToBuffer|SubcToBuffer|Netlist|Revert,filename[,format]) +
Help text: +Load layout data from a file. +
Registered by:n/a +
+

+This action assumes you know what the filename is. The various GUIs should have a similar +load + action where the filename is optional, and will provide their own file selection mechanism to let you choose the file name. +

+ Arguments: +

+ + + + + + + + + + + + + +
+ Layout + + Loads an entire PCB layout, replacing the current one. +
+ LayoutToBuffer + + Loads an entire PCB layout to the paste buffer. +
+ ElementToBuffer + + Loads the given footprint file into the paste buffer. Footprint files contain only a single subcircuit definition in one of the various supported file formats. +
+ Netlist + + Loads a new netlist, replacing any current netlist. +
+ Revert + + Re-loads the current layout from its disk file, reverting any changes you may have made. +
+ +

+ +

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 pcb-rnd session per script and may contain alphanumeric characters and undescrore. +

+ +fn + is the file name of the script, which is a path. Pcb-rnd 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). +

+ +

LoadTtfGlyphs

+
+

+ +
Syntax summary: +LoadTtfGlyphs(filename, srcglyps, [dstchars], [outline|polygon], [scale], [offset]) +
Help text: +Loads glyphs from an outline ttf in the specified source range, optionally remapping them to dstchars range in the pcb-rnd font +
Registered by: +ttf importer +
+

+Import a range of glyphs from ttf outline font into the current font as symbols, starting from a specific character position. Note: pcb-rnd font symbols are not unicode code poitns, but consists of a single, 8 bit ASCII code page, thus values above 255 are invalid as destination symbol code. +

+ The +srcglyph + argumnet is a single + +character description + + or a pair of + +character descriptions + + separated with two dots (".."). In the former case the import is a single glyph, in the latter case the import is the whole range between the two characters, inclusive (one or more glyphs). +

+ The +dstchars + argumnet is always a single + +character description + +, addressing within the 0..255 range of the pcb-rnd font. This argment determines the first destination symbol that is going to be overwritten. If +srcglyph + specifies multiple characters, +dstchars + is internally stepped after each glyp import, up to 255, where the import stops. +

+ A + +character description + + addresses a code point on the input or a character code on the output, using one fo the following syntax variants: +

    + +
  • + 'A' is converted to 65 (as a single charatcer using the 8 bit ASCII table) +
  • + is converted as decimal number 10 +
  • +  is converted as hexadecimal number, to 16 +
  • + U+10 is converted as hexadecimal number, to 16 +
  • + anything else is taken as a single character and is converted as it was wrapped in '' +
+ +

+ The 4th argument is either polygon or line. When it is polygon, the glyph is imported as a polygon (with or without holes). When it is line, all contours of the glyph is imported as a series of lines. When not specified, it defaults to polygon. +

+ Finally, +scale + and +offset + specifies the transformation during the import. Each argument is either a single number or a pair of numbers separated with comma or semicolon or / or * or x, and specify the x and y components of the transformation. When only the x component is specified, y is assumed to be the same (this is useful for scale). +

+ +

LoadVendorFrom

+
+

+ +
Syntax summary: +LoadVendorFrom(filename) +
Help text: +Loads the specified vendor lihata file. +
Registered by: +vendor drill mapping +
+

+Arguments: +

+ + + + + +
+filename + + Name of the vendor lihata file. If not specified, the user will be prompted to enter one. +
+ +

+ +

m

+
+

+ +
Syntax summary: +m [name] +
Help text: +Loads a layout into the current buffer. +
Registered by: +shand_cmd plugin +
+

+If no filename is specified a file select box will popup. +

+ +

MarkCrosshair

+
+

+ +
Syntax summary: +MarkCrosshair() +MarkCrosshair(Center) +
Help text: +Set/Reset the pcb_crosshair mark. +
Registered by:n/a +
+

+The "mark" is a small X-shaped target on the display which is treated like a second origin (the normal origin is the upper let corner of the board). The GUI will display a second set of coordinates for this mark, which tells you how far you are from it. +

+ If no argument is given, the mark is toggled - disabled if it was enabled, or enabled at the current cursor position of disabled. If the +Center + argument is given, the mark is moved to the current cursor location. +

+ +

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 pcb-rnd. 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 +
+ +

+ +

Mode

+
+

+ +
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 +
+

+This command is a compatibility alias to +tool +. +

+ +

MorphPolygon

+
+

+ +
Syntax summary: +pcb_poly_morph(Object|Selected) +
Help text: +Converts dead polygon islands into separate polygons. +
Registered by:n/a +
+

+If a polygon is divided into unconnected "islands", you can use this command to convert the otherwise disappeared islands into separate polygons. Be sure the cursor is over a portion of the polygon that remains visible. Very small islands that may flake off are automatically deleted. +

+ +

MoveLayer

+
+

+ +
Syntax summary: +MoveLayer(old,new) +MoveLayer(lid,group,gid) +
Help text: +Moves/Creates/Deletes Layers. +
Registered by:n/a +
+

+Moves a layer, creates a new layer, or deletes a layer. +

+ Arguments: +

+ + + + + + + +
+ old + + The is the layer number to act upon. Allowed values are: +
    + +
  • + c = Currently selected layer. +
  • + -1 = Create a new layer. +
  • + + +number + + = An existing layer number. +
+ +
+ new + + Specifies where to move the layer to. Allowed values are: +
    + +
  • + -1 = Deletes the layer. +
  • + up = Moves the layer up (TODO: is this supported?) +
  • + down = Moves the layer down (TODO: is this supported?) +
  • + step+ = Moves the layer towards the end of its group's list. +
  • + step- = Moves the layer towards the beginning of its group's list. +
  • + c = Creates a new layer. +
  • + grp + +gid + + = move layer into group; target group ID is the 3rd argument +
+ +
+ +

+ +

MoveObject

+
+

+ +
Syntax summary: +pcb_move_obj(X,Y,[units]) +
Help text: +Moves the object under the crosshair. +
Registered by:n/a +
+

+The +code + and +Y + are treated like + +delta + + if they are prefixed by + or -, otherwise, they are absolute. Units can be + +mil + + or + +mm + + and is used when +X + and +Y + have no unit specified. If no unit unspecified in coords or units, nanometer is assumed. +

+ +

MoveToCurrentLayer

+
+

+ +
Syntax summary: +MoveToCurrentLayer(Object|SelectedObjects) +
Help text: +Moves objects to the current layer. +
Registered by:n/a +
+

+Note that moving an subcircuit from a component layer to a solder layer, or from solder to component, won't automatically flip it. Use the +flip + action to do that. +

+ +

netlist

+
+

+ +
Syntax summary: +Net(find|select|rats|norats||ripup|addrats|clear[,net[,pin]]) +Net(freeze|thaw|forcethaw) +Net(swap) +Net(add,net,pin)Net([rename|merge],srcnet,dstnet) +
Help text: +Perform various actions on netlists. +
Registered by:n/a +
+

+Each of these actions apply to a specified set of nets. +net + and +pin + are patterns which match one or more nets or pins; these patterns may be full names or regular expressions. If an exact match is found, it is the only match; if no exact match is found, + +then + + the pattern is tried as a regular expression. +

+ If neither +net + nor +pin + are specified, all nets apply. If +net + is specified but not +pin +, all nets matching +net + apply. If both are specified, nets which match +net + and contain a pin matching +pin + apply. +

+ +freeze +, +thaw + and +forcethaw + temporarily prevents changes to the netlist from being reflected in the GUI. For example, if you need to make multiple changes, you +freeze + the netlist, make the changes, then +thaw + it. Note that freeze/thaw requests may nest, with the netlist being fully thawed only when all pending freezes are thawed. You can bypass the nesting by using +forcethaw +, which resets the freeze count and immediately updates the GUI. +

+ Argument summary: +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ find + + Nets which apply are marked @emph{found} and are drawn in the + +connected-color + + color. +
+ select + + Nets which apply are selected (added to existing selections). +
+ unselect + + Nets which apply are unselected (removed from existing selections). +
+ rats + + Nets which apply are marked as available for the rats nest. +
+ norats + + Nets which apply are marked as not available for the rats nest. +
+ allrats + + Mark all nets available for the rats nest. +
+ allnorats + + Mark all nets not available for the rats nest. +
+ clear + + Clears the netlist. +
+ ripup + + Remove all non-subcircuit-part copper object that is connected to a net. +
+ add + + Add the given pin to the given netlist, creating either if needed. +
+ AddRats + + Calculate and add all rats required for finishing the named network. +
+ swap + + Swap the connections one end of two selected rats and pins. +
+ sort + + Called after a list of add's, this sorts the netlist. +
+ freeze +
+ thaw +
+ forcethaw +
+ Temporarily prevents changes to the netlist from being reflected in the GUI. +
+ rename + + Change the name of a network (with back annotation) +
+ merge + + Move all terminal connections from the source network (first arg) to the destination network (with back annotation) +
+ +

+ +

New

+
+

+ +
Syntax summary: +New([name]) +
Help text: +Starts a new layout. +
Registered by:n/a +
+

+If a name is not given, one is prompted for. +

+ +

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 + + +
+ +
+ +

OpenemsExcitation

+
+

+ +
Syntax summary: +OpenemsExcitation([interactive]) +OpenemsExcitation(select, excitationname) +OpenemsExcitation(set, [excitationnme], paramname, paramval) +OpenemsExcitation(get, [excitationnme], paramname) +
Help text: +Select which openEMS excitation method should be exported and manipulate the associated parameters. When invoked without arguments a dialog box with the same functionality is presented. +
Registered by: +openems HID +
+

+When invoked without argument or with +interactive + a dialog box is presented, allowing the user to do the same operations as with the action. +

+ If the first argument +select +, further OpenEMS exports will use the excitation named in the +excitationname + argument (in short: the excitation is selected). +

+ Arguments +set + and +get + is used to read or change an excitation parameter named in +paramname +. When +excitationname + is not set, they operate on the currently selected excitation. For +set + the +paramval + argument is mandatory. +

+ Note: the code remembers all settings for all excitements, not only the excitement that is currently selected. The selection and all parameters are saved as board attributes. +

+ +

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. +

+ +

PasteBuffer

+
+

+ +
Syntax summary: +PasteBuffer(AddSelected|MoveSelected|Clear|1..PCB_MAX_BUFFER) +PasteBuffer(Rotate, 1..3) +PasteBuffer(Convert|Restore|Mirror) +PasteBuffer(ToLayout, X, Y, units) +PasteBuffer(ToLayout, crosshair) +PasteBuffer(Save, Filename, [format], [force]) +PasteBuffer(SaveAll, Filename, [format]) +PasteBuffer(LoadAll, Filename) +PasteBuffer(Push) +PasteBuffer(Pop) +PasteBuffer(GetSource, [1..PCB_MAX_BUFFER]) +
Help text: +Various operations on the paste buffer. +
Registered by:n/a +
+

+There are a number of paste buffers; the actual limit is a compile-time constant + +PCB_MAX_BUFFER + +. It is normally + +5 + +. One of these is the "current" paste buffer, often referred to as "the" paste buffer. Arguments: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ AddSelected + + Copies the selected objects to the current paste buffer. +
+ Clear + + Remove all objects from the current paste buffer. +
+ Convert + + Convert the current paste buffer to an subcircuit. +
+ Restore + + Convert any subcircuit in the paste buffer back to plain objects. +
+ Mirror + + Flip all objects in the paste buffer vertically (up/down flip). To mirror horizontally, combine this with rotations. +
+ Rotate + + Rotates the current buffer. The number to pass is 1..3, where 1 means 90 degrees counter clockwise, 2 means 180 degrees, and 3 means 90 degrees clockwise (270 CCW). +
+ Normalize + + Set the buffer origin to the center of the paste buffer bounding box. This is useful especially if an import plugin loaded objects in the buffer with a large offset. +
+ Save + + Saves subcircuits in the current buffer to the indicated file. If format is specified, try to use that file format, else use the default. If force is specified, overwrite target, don't ask. +
+ SaveAll + + Saves all content of the current buffer to the indicated file. If format is specified, try to use that file format, else use the default. +
+ LoadAll + + Loads a previously saved paste buffer into the current buffer from the indicated file. +
+ ToLayout + + Pastes objects in the current buffer to the indicated X, Y coordinates in the layout. The +X + and +Y + are treated like +delta + is for many other objects. For each, if it's prefixed by + or -, then that amount is relative to the last location. Otherwise, it's absolute. If units is unspecified, units are PCB's internal units, currently nanometer. If "crosshair" is used instead of coordinates, the paste happens at the current crosshair coords. +
+ 1..PCB_MAX_BUFFER + + Selects the given buffer to be the current paste buffer. +
+ GetSource + + Returns the source file path the buffer is loaded from or nil if there is none. The return value is a string, usable from user scripts. +
+ +

+ +

PolyBool

+
+

+ +
Syntax summary: +PstkProto([noundo,] unite|isect|sub, [poly1, poly2, [poly...]]) +
Help text: +Perform polygon boolean operation on the clipped polygons referred. A poly is either and idpath, selected, found or object (for the object under the cursor). When not specified, two object polygons are used. +
Registered by: +act_draw +
+

+The boolean operation argument is one of these: +

    + +
  • + unite: calculate the union of the polygons +
  • + isect: calculate the intersection of all polygons; the result is the area where all argument polygons are present +
  • + sub: subtract subsequent polygons from the first polygon +
+ +

+ A polygon is a pcb layer object, that is: if it's fullpoly, it may have multiple islands. The code operates on the clipped shape of the input polygons, not on the 'as drawn shape'. The result is zero or more polygon layer objects, each with a single island, created on the current layer. +

+ The rest of the arguments will build a flat list of polygon objects to work on and need to address at least two polygons. Each argument may be one of: +

    + +
  • + object: the user needs to click an object using the GUI +
  • + selected: all selected polygons are appended to the list +
  • + found: all found (green highlight) polygons are appended to the list +
  • + + +ipdath + +: address a specific polygon +
+ +

+ Note: for the + +sub + + operation the first polygon is special, so order of attributes matter. When using + +selected + + or + +found + + to address polygons, if multiple polygons are selected or found at the time, the order they end up added to the operation object list is undefined. +

+ Input polygons are unchanged, new polygons are created on the current layer. +

+ Demo video: + + PolyBool(sub) mini-howto. + + +

+ +

PolyCombine

+
+

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

+The selected polygons are combined together according to the ordering of their points. +

+ +

Polygon

+
+

+ +
Syntax summary: +Polygon(Close|CloseHole|PreviousPoint) +
Help text: +Some polygon related stuff. +
Registered by:n/a +
+

+Argument: +

+ + + + + + + + + +
+ Close + + Creates the final segment of the polygon. This may fail if clipping to 45 degree lines is switched on, in which case a warning is issued. +
+ CloseHole + + Creates the final segment of the polygon hole. This may fail if clipping to 45 degree lines is switched on, in which case a warning is issued. +
+ PreviousPoint + + Resets the newly entered corner to the previous one. The Undo action will call Polygon(PreviousPoint) when appropriate to do so. +
+ +

+ +

PolyStitch

+
+

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

+The polygon under the cursor (based on closest-corner) is stitched together with the polygon surrounding it on the same layer. +

+ Use with pstoedit conversions where there's a "hole" in the shape - select the hole. +

+ + +
+

+ +
Syntax summary: +Popup(MenuName, [obj-type]) +
Help text: +Bring up the popup menu specified by MenuName, optionally modified with the object type under the cursor. +
Registered by: +lib_hid_pcbui/actions +
+

+Pops up the specified menu. The menu must have been defined in the popups subtree in the menu lht file. If the second argument is specified, the menu name is modified by runtime data: +

+ + + + + +
+ obj-type + + append a dash and the object type name (e.g. "-line") for the object currently under the cursor +
+ +

+ +

preunload

+
+

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

+ +preunload + is an optional action scripts may provide. When present, it is called by pcb-rnd as the last call to the script before the script is unloaded. It has two purposes: +

    + +
  • + give scripts a chance to clean up, uninit and unregister +
  • + give scripts a chance to perist their state +
+ +

+ State persisting is achieved through returning a string from this action. That string is then saved by pcb-rnd under the scripts' load ID (as specified by the user). In a later script load, the script with the same ID may read the persistent data frolm disk using the +scriptpersistency +(read) action and can remove the save using the +scriptpersistency +(remove) action. +

+ + +It should never be called by the user or other code or other actions. + + +

+ +

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. +

+ +

PrintCalibrate

+
+

+ +
Syntax summary: +PrintCalibrate() +
Help text: +Calibrate the printer. +
Registered by: +dialogs plugin +
+

+This will print a calibration page, which you would measure and type the measurements in, so that future printouts will be more precise. +

+ +

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. +

+ +

Puller

+
+

+ +
Syntax summary: +pcb_act_Puller() +
Help text: +Pull an arc-line junction tight. +
Registered by: +puller plugin +
+

+The +puller + action is a special-purpose optimization. When invoked while the crosshair is over the junction of an arc and a line, it will adjust the arc's angle and the connecting line's endpoint such that the line intersects the arc at a tangent. +

+ +

q

+
+

+ +
Syntax summary: +q +
Help text: +Quits the application after confirming. +
Registered by: +shand_cmd plugin +
+

+If you have unsaved changes, you will be prompted to confirm (or save) before quitting, unless the action name included a !. +

+ +

Quit

+
+

+ +
Syntax summary: +Quit() +
Help text: +Quits the application after confirming. +
Registered by:n/a +
+

+If you have unsaved changes, you will be prompted to confirm (or save) before quitting. +

+ +

Redo

+
+

+ +
Syntax summary: +redo() +
Help text: +Redo recent "undo" operations. +
Registered by:n/a +
+

+The +redo + action allows you to recover from the last undo command. You might want to do this if you thought that undo was going to revert something other than what it actually did (in case you are confused about which operations are un-doable), or if you have been backing up through a long undo list and over-shoot your stopping point. Any change that is made since the undo in question will trim the redo list. For example if you add ten lines, then undo three of them you could use redo to put them back, but if you move a line on the board before performing the redo, you will lose the ability to "redo" the three "undone" lines. +

+ +

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). +

+ +

RenumberBlock

+
+

+ +
Syntax summary: +RenumberBlock(old_base,new_base) +
Help text: +Renumber selected subcircuit refdes attributes by adding (new_base-old_base). +
Registered by: +renumber plugin +
+

+ +Example: RenumberBlock(oldnum,newnum)
+ +

+ All selected subcircuit refdes attributes are renumbered by adding (newnum-oldnum) to the existing number. +

+ +Example: RenumberBlock(100,200)
+ will change R213 to R313. +

+ +

RenumberBuffer

+
+

+ +
Syntax summary: +RenumberBuffer(old_base,new_base) +
Help text: +Renumber buffer subcircuit refdes attributes by adding (new_base-old_base). +
Registered by: +renumber plugin +
+

+ +Example: RenumberBuffer(oldnum,newnum)
+ +

+ Same as +renumberblock +, but the paste buffer is renumbered. +

+ +

ReplaceFootprint

+
+

+ +
Syntax summary: +ReplaceFootprint([Selected|Object], [footprint], [dumb]) +
Help text: +Replace the footprint of the selected components with the footprint specified. +
Registered by:n/a +
+

+Replace footprint(s) from the library or buffer, in-place (preserving the original subcircuit's location, rotation and metadata) and append the replacement to the back annotation changeset. +

+ If first argument is + +selected + +, replace all selected subcircuits with the new footprint; if it is + +object + +, replace only one subcircuit, under the cursor. +

+ If the second argument is a footprint name, load it from the library. If it is + +@buffer + +, use the subcircuit in the current buffer (there must be exactly 1 subcircuit in the buffer). If it is empty or not specified, the user is asked for a footprint. +

+ If the third argument is + +dumb + + the location and rotation of the original subcircuit is not preserved (but all metadata and board side are preserved). A dumb replacement also omits creating back annotation. +

+ +

Report

+
+

+ +
Syntax summary: +Report([DrillReport|FoundPins|NetLengthTo]) +Report(NetLength, [netname]) +Report(Object|Subc, [log]) +Report(AllNetLengths, [unit]) +
Help text: +Produce various report. +
Registered by: +report plugin +
+

+Arguments: +

+ + + + + + + + + + + + + +
+ Object + + The object under the crosshair will be reported, describing various aspects of the object. +
+ DrillReport + + A report summarizing the number of drill sizes used, and how many of each, will be produced. +
+ FoundPins + + A report listing all pins and pads which are marked as "found" will be produced. +
+ NetLength + + The name and length of the net under the crosshair will be reported to the message log. An optional parameter specifies the netname; when present the length of the named network is printed, else the net under the cursor is used. +
+ AllNetLengths + + The name and length of the net under the crosshair will be reported to the message log. An optional parameter specifies the unit name (e.g. mm) +
+ +

+ +

reportdialog

+
+

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

+This is a shortcut for +report +( +Object +). +

+ +

RipUp

+
+

+ +
Syntax summary: +RipUp(All|Selected|Element) +
Help text: +Ripup auto-routed tracks +
Registered by:n/a +
+

+Arguments: +

+ + + + + + + +
+ All + + Removes all lines and vias which were created by the autorouter. +
+ Selected + + Removes all selected lines and vias which were created by the autorouter. +
+ +

+ +

rn

+
+

+ +
Syntax summary: +rn [name] +
Help text: +Reads netlist. +
Registered by: +shand_cmd plugin +
+

+If no filename is given a file select box will pop up. +

+ +

Rotate90

+
+

+ +
Syntax summary: +pcb_move_obj(steps) +
Help text: +Rotates the object under the crosshair by 90 degree steps. +
Registered by:n/a +
+

+Rotates the object under the mouse pointer by 90 degree +steps +. +steps + must be an integer between -3 and +3. +

+ +

RouteStyle

+
+

+ +
Syntax summary: +RouteStyle(style_id|style_name|@current, [set|get|del], [trace-thickness|trace-clearance|text-thickness|text-scale|name], [value]]) +RouteStyle(new, [name]) +
Help text: +Without second argument: copies the indicated routing style into the current pen; with second argument sets or gets a field of the routing style. +
Registered by:n/a +
+

+Reads or writes route style properties. +

+ If the first argument is + +new + +, a new style is created, optionally using the name provided as the second argument; else the following happens. +

+ The first argument addresses the style and is one of: +

    + +
  • + an integer greater than zero: style ID (styles are counted from 1) +
  • + @current, which will pick the style currently selected +
  • + an arbitrary style name, which will pick the first style with matching name +
+ +

+ The second argument is one of: +

    + +
  • + + +set + +, which will modify the addressed style using the 4th argment +value + +
  • + + +get + +, where the 4th argument is omitted and the return value of the action holds the resulting value of the query +
  • + + +del + +, which will remove the style addressed. +
+ +

+ The 3rd argument addresses the property of the style. +

+ Note: all operations by this action are undoable. +

+ +

s

+
+

+ +
Syntax summary: +s [name] +w [name] +
Help text: +Saves layout data. +
Registered by: +shand_cmd plugin +
+

+If no filename is entered, either the last one is used again or, if it is not available, a file select box will pop up. +

+ +

Save

+
+

+ +
Syntax summary: +Save() +Save(Layout|LayoutAs) +Save(AllConnections|AllUnusedPins|ElementConnections) +Save(PasteBuffer) +Save(DialogByPattern, pcb|footprint|font|buffer, none|board|fp, prompt, [default_pattern]) +
Help text: +Save layout data to a user-selected file. +
Registered by: +dialogs plugin +
+

+This action is a GUI front-end to the core's +saveto + action. If you happen to pass a filename then +saveto + is called directly. Else, the user is prompted for a filename to save, and then +saveto + is called with that filename. +

+ The DialogByPattern mode is intended for scripts and core: it presents a dialog box with format selection and listing patterns, but does not perform any real file operation just returns a + +filename*format + + string. +

+ +

SaveLib

+
+

+ +
Syntax summary: +SaveLib(file|dir, board|buffer, [filename], [fmt]) +
Help text: +Saves all subcircuits to a library file or directory from a board or buffer. +
Registered by:n/a +
+

+Useful when multiple subcircuits should be saved to be reused as a library. When first argument is + +dir + +, each subcircuit is saved in a separate, numbered file. If the first argument is + +file + + and the target file format has library support, all subcircuits are saved in the same file, as a library. +

+ If a single subcircuit from buffer needs to be saved to be a footprint, use the +saveto + action with first argument set to PasteBuffer. +

+ +

SaveTo

+
+

+ +
Syntax summary: +SaveTo(Layout|LayoutAs,filename,[fmt]) +SaveTo(PasteBuffer,filename,[fmt]) +
Help text: +Saves data to a file. +
Registered by:n/a +
+

+Arguments: +

+ + + + + + + + + + + +
+ Layout + + Saves the current layout. +
+ LayoutAs + + Saves the current layout, and remembers the filename used. +
+ PasteBuffer + + Save the subcircuit from the active Buffer to a file. The buffer needs to contain exactly one subcircuit. This is the graphical way to create a footprint. If multiple subcircuits needs to be saved, use the +savelib + action. +
+ AllConnections, AllUnusedPins, ElementConnections + + obsolete arguments, kept for compatibility; please use +exportoldconn + instead. +
+ +

+ +

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 pcb-rnd infrastructure that requires cookie, such as +createmenu + +
  • + can depend on pcb-rnd 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. +
+ +

+ +

Select

+
+

+ +
Syntax summary: +Select(Object, [idpath]) +Select(ToggleObject) +Select(All|Block|Connection|Invert) +Select(Convert) +
Help text: +Toggles or sets the selection. +
Registered by:n/a +
+

+Arguments: +

+ + + + + + + + + + + + + + + +
+ Object +
+ ToggleObject +
+ If second argument is present, select the object addressed by that idpath, else selects the object under the cursor. +
+ Block + + Selects all objects in a rectangle indicated by the cursor. +
+ All + + Selects all objects on the board. +
+ Connection + + Selects all connections with the ``found'' flag set. +
+ Convert + + Converts the selected objects to a subcircuit. This uses the highest numbered paste buffer. +
+ Invert + + Invert selection: anything that was not selected becomes selected, everything that was selected becomes unselected. Locked objects are not affected. +
+ +

+ +

SelectLayer

+
+

+ +
Syntax summary: +SelectLayer(1..MAXLAYER|Silk|Rats) +
Help text: +Select which layer is the current layer. +
Registered by:n/a +
+

+The specified layer becomes the currently active layer. It is made visible if it is not already visible +

+ +

SetFlag

+
+

+ +
Syntax summary: +SetFlag(Object|Selected|SelectedObjects, flag) +SetFlag(SelectedLines|SelectedPins|SelectedVias, flag) +SetFlag(SelectedPads|SelectedTexts|SelectedNames, flag) +SetFlag(SelectedElements, flag) +flag = thermal | join +
Help text: +Sets flags on objects. +
Registered by:n/a +
+

+Turns the given flag on, regardless of its previous setting. See +changeflag +. +

+ +Example: SetFlag(SelectedPins,thermal)
+ +

+ +

SetSame

+
+

+ +
Syntax summary: +SetSame() +
Help text: +Sets current layer and sizes to match indicated item. +
Registered by:n/a +
+

+When invoked over any line, arc, polygon, or via, this changes the current layer to be the layer that item is on, and changes the current sizes (thickness, clearance, etc) according to that item. +

+ +

SetThermal

+
+

+ +
Syntax summary: +SetThermal(Object|SelectedPins|SelectedVias|Selected, Style) +
Help text: +Set the thermal (on the current layer) of padstacks to the given style. Style is one of: +0: means no thermal. +1: horizontal/vertical, round. +2: horizontal/vertical, sharp. +3: is a solid connection to the polygon. +4: (invalid). +5: diagonal, round. +6: diagonal, sharp. +noshape: no copper shape on layer +
Registered by:n/a +
+

+This changes how/whether padstacks connect to any rectangle or polygon on the current layer. The first argument can specify one object, or all selected padstacks. The second argument specifies the style of connection. +

+ Thermal styles: +

+ + + + + + + + + + + + + + + + + + + +
+0 + + no connection, +
+1 + + horizontal & vertical fingers with round edges, +
+2 + + horizontal & vertical fingers with sharp edges, +
+3 + + solid connection, +
+4 + + invalid, do not use +
+5 + + 45 degree fingers with rounded corners. +
+6 + + 45 degree fingers with sharp edges, +
+noshape + + remove copper shape on layer +
+ +

+ Padstacks may have thermals whether or not there is a polygon available to connect with. However, they will have no visible effect until a polygon is drawn around the padstack. +

+ +

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. +
+ +

+ +

SetValue

+
+

+ +
Syntax summary: +SetValue(Grid|Line|LineSize|Text|TextScale, delta) +
Help text: +Change various board-wide values and sizes. +
Registered by:n/a +
+

+Arguments: +

+ + + + + + + + + +
+ Grid + + Sets the grid spacing. +
+ Line +
+ LineSize +
+ Changes the thickness of new lines. +
+ Text +
+ TextScale +
+ Changes the size of new text. +
+ +

+ +

smartdisperse

+
+

+ +
Syntax summary: +SmartDisperse([All|Selected]) +
Help text: +Disperse subcircuits into clusters, by netlist connections +
Registered by: +smartdisperse plugin +
+

+Improve the initial dispersion of subcircuits by choosing an order based on the netlist, rather than the arbitrary subcircuit order. This isn't the same as a global autoplace, it's more of a linear autoplace. It might make some useful local groupings. For example, you should not have to chase all over the board to find the resistor that goes with a given LED. +

+ +

SwapSides

+
+

+ +
Syntax summary: +SwapSides(|v|h|r, [S]) +
Help text: +Swaps the side of the board you're looking at. +
Registered by: +lib_hid_pcbui/actions +
+

+This action changes the way you view the board (flipping the board). +

+ Arguments: +

+ + + + + + + + + +
+ v + + Flips the board over vertically (up/down); try to keep location on screen. +
+ h + + Flips the board over horizontally (left/right), like flipping pages in a book. +
+ r + + Rotates the board 180 degrees without changing sides. +
+ +

+ If no argument is given, the board isn't moved but the opposite side is shown. +

+ Normally, this action changes which pads and silk layer are drawn as pcb_true silk, and which are drawn as the "invisible" layer. It also determines which solder mask you see. +

+ If +S + is specified as a second argument, if the layer group for the side you're looking at is visible and currently active, and the layer group for the opposite is not visible (i.e. disabled), then this action will also swap which layer group is visible and active, effectively swapping the "working side" of the board. +

+ +

ToggleView

+
+

+ +
Syntax summary: +ToggleView(1..MAXLAYER) +ToggleView(layername) +ToggleView(Silk|Rats|Pins|Vias|BackSide) +ToggleView(All, Open|Vis, Set|Clear|Toggle) +
Help text: +Toggle the visibility of the specified layer or layer group. +
Registered by:n/a +
+

+If you pass an integer, that layer is specified by index (the first layer is + +1 + +, etc). If you pass a layer name, that layer is specified by name. When a layer is specified, the visibility of the layer group containing that layer is toggled. +

+ If you pass a special layer name, the visibility of those components (silk, rats, etc) is toggled. Note that if you have a layer named the same as a special layer, the layer is chosen over the special layer. +

+ +

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. +

+ + + + + + + + + + + + + + + + + + + +
+ Arc +
+ Arrow +
+ Copy +
+ InsertPoint +
+ Line +
+ Lock +
+ Move +
+ None +
+ PasteBuffer +
+ Poly +
+ PolyHole +
+ Rectangle +
+ Remove +
+ Rotate +
+ Text +
+ Thermal +
+ Via +
+ ... +
+ Select the indicated tool. +
+ 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 pcb-rnd 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. +
+ +

+ +

Undo

+
+

+ +
Syntax summary: +undo() +undo(ClearList|FreezeSerial|UnfreezeSerial|IncSerial) +
Help text: +Undo recent changes. +
Registered by:n/a +
+

+The unlimited undo feature of pcb-rnd allows you to recover from most operations that materially affect you work. Calling +pcb_undo + without any parameter recovers from the last (non-undo) operation. +ClearList + is used to release the allocated memory. +ClearList + is called whenever a new layout is started or loaded. See also +redo +. +

+ Note that undo groups operations by serial number; changes with the same serial number will be undone (or redone) as a group. See +atomic +. +

+ +

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). +

+ +

Unselect

+
+

+ +
Syntax summary: +Unselect(All|Block|Connection) +
Help text: +Unselects the object at the pointer location or the specified objects. +
Registered by:n/a +
+

+Arguments: +

+ + + + + + + + + +
+ All + + Unselect all objects. +
+ Block + + Unselect all objects in a rectangle given by the cursor. +
+ Connection + + Unselect all connections with the "found" flag set. +
+ +

+ +

w

+
+

+ +
Syntax summary: +s [name] +w [name] +
Help text: +Saves layout data. +
Registered by: +shand_cmd plugin +
+

+This commands has been added for the convenience of + +vi + + users and has the same functionality as +s +. +

+ +

wq

+
+

+ +
Syntax summary: +wq +
Help text: +Saves the layout data and quits. +
Registered by: +shand_cmd plugin +
+

+This command has been added for the convenience of + +vi + + users and has the same functionality as +s + combined with +q +. +

+ +

Zoom

+
+

+ +
Syntax summary: +Zoom() +Zoom([+|-|=]factor) +Zoom(x1, y1, x2, y2) +Zoom(?) +Zoom(get) +Zoom(found|selected) +
Help text: +GUI zoom +
Registered by: +lib_hid_pcbui/actions +
+

+Changes the zoom (magnification) of the view of the board. If no arguments are passed, the view is scaled such that the board just fits inside the visible window (i.e. "view all"). Otherwise, +factor + specifies a change in zoom factor. It may be prefixed by + ++ + +, + +- + +, + += + + to change how the zoom factor is modified (relative or absolute). The +factor + is a floating point number, such as + +1.5 + + or + +0.75 + +. +

+ Alternatively a box can be specified with 4 coordinates and +zoom + will set the zoom level (and modifies pan) so that the given box of the design is visible and as large as possible in the current window. +

+ Arguments: +

+ + + + + + + + + + + + + + + + + + + + + +
+ (no argument) + + Without argments: zoom to board extents. +
+ +factor + + Values greater than 1.0 cause the board to be drawn smaller; more of the board will be visible. Values between 0.0 and 1.0 cause the board to be drawn bigger; less of the board will be visible. +
+ -factor + + Values greater than 1.0 cause the board to be drawn bigger; less of the board will be visible. Values between 0.0 and 1.0 cause the board to be drawn smaller; more of the board will be visible. +
+ =factor + + The @var{factor} is an absolute zoom factor; the unit for this value is "PCB units per screen pixel". Since PCB units are nanometer, a +factor + of 1000 means 1 micrometer per pixel (TODO: test this). +
+ x1, y1, x2, y2 + + Zoom to the specified portion of the design, described as a rectangle (using board space coordinates) +
+ selected + + Zoom and pan so that all + +selected + + objects are on the screen. +
+ found + + Zoom and pan so that all + +found + + objects are on the screen. +
+ ? + + Print the current zoom level in the message log (as an info line). +
+ get + + Return the zoom level as an FGW_DOUBLE (useful for scripts). +
+ +

+ Note that zoom factors of zero are silently ignored. +

+ + + + Index: tags/2.3.0/doc/user/09_appendix/action_reference.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_reference.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_reference.html (revision 33253) @@ -0,0 +1,402 @@ + + + + pcb-rnd user manual + + + + +

+

pcb-rnd User Manual: Appendix

+

+

Action Reference

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +This is pcb-rnd 2.2.4 (svn r33161) an interactive printed circuit board editor , Revision: 33220 + +
Action Description Syntax Plugin +
AboutPresent the about boxAbout()dialogs plugin
acompnetAttempt to auto-complete the current networkacompnet()acompnet plugin
ActionStringExecute a pcb-rnd action parsing a string; syntac: "action(arg,arg,arg)"ActionString(action)script plugin
AddRatsAdd one or more rat lines to the board.AddRats(AllRats|SelectedRats|Close, [manhattan])
AddTimerAdd a new timerAddTimer(action, period, [repeat], [userdata])script plugin
AdjustStyleOpen the dialog box for editing the route styles.AdjustStyle([routestyle_idx])lib_hid_pcbui/route_style
alignAlign objectsAlign(X/Y, [Lefts/Rights/Tops/Bottoms/Centers/Marks, [First/Last/pcb_crosshair/Average[, Gridless]]])distalign plugin
aligntextAlign objectsAlign(X/Y, [Lefts/Rights/Tops/Bottoms/Centers/Marks, [First/Last/pcb_crosshair/Average[, Gridless]]])distalign plugin
ApplyVendorApplies the currently loaded vendor drill table to the current design.ApplyVendor()vendor drill mapping
ArcNewCreate a pcb arc segment on a layer. For now data must be "pcb". Returns the idpath of the new object or 0 on error.ArcNew([noundo,] data, layer, centx, centy, radiusx, radiusy, start_ang, delta_ang, thickness, clearance, flags)act_draw
asmInteractive assembly assistantasm()asm plugin
AtomicSave or restore the undo serial number.Atomic(Save|Restore|Close|Block)
AttributesLet the user edit the attributes of the layout, current or given
layer, or selected subcircuit.
Attributes(Layout|Layer|Element|Subc)
Attributes(Layer,layername)
oldactions plugin
autocropAutocrops the board dimensions to (extants + a margin of 1 grid), keeping the move and board size grid alignedautocrop()autocrop plugin
AutoPlaceSelectedAuto-place selected components.AutoPlaceSelected()autoplace plugin
AutoRouteAuto-route some or all rat lines.AutoRoute(AllRats|SelectedRats)autoroute plugin
BackupBackup the current layout - save using the same method that the timed backup function usesBackup()
basExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
BellAttempt to produce audible notification (e.g. beep the speaker).Bell()oldactions plugin
BenchmarkBenchmark the GUI speed.Benchmark()
BoardFlipMirror the board over the x axis, optionally mirroring sides as well.BoardFlip([sides])
BraveChanges brave settings.Brave()
Brave(setting, on|off)
BrowseScriptsPresent a dialog box for browsing scriptsBrowseScripts()script plugin
camExport jobs for feeding cam processescam(exec, script, [options])
cam(call, jobname, [options])
cam([gui])
cam exporter
CenterMoves the pointer to the center of the window.Center()lib_hid_common plugin
ChangeAngleChanges the start angle, delta angle or both angles of an arc.ChangeAngle(Object, start|delta|both, delta)
ChangeAngle(SelectedObjects|Selected, start|delta|both, delta)
ChangeAngle(SelectedArcs, start|delta|both, delta)
ChangeClearSizeChanges the clearance size of objects.ChangeClearSize(Object, delta|style)
ChangeClearSize(SelectedPins|SelectedPads|SelectedVias, delta|style)
ChangeClearSize(SelectedLines|SelectedArcs, delta|style)
ChangeClearSize(Selected|SelectedObjects, delta|style)
ChangeDrillSizeChanges the drilling hole size of objects.ChangeDrillSize(Object, delta|style)
ChangeDrillSize(SelectedPins|SelectedVias|Selected|SelectedObjects, delta|style)
ChangeFlagSets or clears flags on objects.ChangeFlag(Object|Selected|SelectedObjects, flag, value)
ChangeFlag(SelectedLines|SelectedPins|SelectedVias, flag, value)
ChangeFlag(SelectedPads|SelectedTexts|SelectedNames, flag, value)
ChangeFlag(SelectedElements, flag, value)
flag = join
value = 0 | 1
ChangeHoleoldactions plugin
ChangeJoinChanges the join (clearance through polygons) of objects.ChangeJoin(ToggleObject|SelectedLines|SelectedArcs|Selected)
ChangeNameSets the name, text string, terminal ID or refdes of objects.ChangeName(Object)
ChangeName(Refdes)
ChangeName(Layout|Layer)
ChangeNonetlistChanges the nonetlist flag of subcircuits.ChangeNonetlist(ToggleObject)
ChangeNonetlist(SelectedElements)
ChangeNonetlist(Selected|SelectedObjects)
ChangeOctagonoldactions plugin
ChangePasteoldactions plugin
ChangePinNameSets the name of a specific pin on a specific subcircuit.ChangePinName(Refdes,PinNumber,PinName)
ChangeRadiusChanges the width or height (radius) of an arc.ChangeRadius(Object, width|x|height|y|both, delta)
ChangeRadius(SelectedObjects|Selected, width|x|height|y|both, delta)
ChangeRadius(SelectedArcs, width|x|height|y|both, delta)
ChangeSizeChanges the size of objects.ChangeSize(Object, delta|style)
ChangeSize(SelectedObjects|Selected, delta|style)
ChangeSize(SelectedLines|SelectedPins|SelectedVias, delta|style)
ChangeSize(SelectedPads|SelectedTexts|SelectedNames, delta|style)
ChangeSize(SelectedElements, delta|style)
ChangeSizesChanges all sizes of objects.ChangeSizes(Object, delta|style)
ChangeSizes(SelectedObjects|Selected, delta|style)
ChangeSizes(SelectedLines|SelectedPins|SelectedVias, delta|style)
ChangeSizes(SelectedPads|SelectedTexts|SelectedNames, delta|style)
ChangeSizes(SelectedElements, delta|style)
ChangeSquareoldactions plugin
ChkBufferReturn 1 if currently selected buffer's index matches idxChkBuffer(idx)
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)
ChkLayerReturns 1 if the specified layer is the active layerChkLayer(layerid)
ChkModeReturn 1 if the currently selected mode is the expected_modeChkMode(expected_mode)
ChkRstReturn 1 if route_style_id matches pen.ChkRst(route_style_id)
ChkSubcIDReturn 1 if currently shown subc ID matches the requested patternChkSubcID(pattern)
ChkTermIDReturn 1 if currently shown term ID matches the requested patternChkTermID(pattern)
ChkViewReturn 1 if layerid is visible.ChkView(layerid)
circleGenerate a filled circle (zero length round cap line)circle([where,] diameter)shape plugin
claimnetClaim existing connections and create a new netClaimNet(object|selected|found,[netname])
ClearOctagonoldactions plugin
ClearSquareoldactions plugin
ClipInhibitClipInhibit Feature Template.ClipInhibit([on|off|check])
cli_MessageBoxIntenal: CLI frontend action. Do not use directly.
cli_PromptForIntenal: CLI frontend action. Do not use directly.
ClrFlagClears flags on objects.ClrFlag(Object|Selected|SelectedObjects, flag)
ClrFlag(SelectedLines|SelectedPins|SelectedVias, flag)
ClrFlag(SelectedPads|SelectedTexts|SelectedNames, flag)
ClrFlag(SelectedElements, flag)
flag = thermal | join
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)
ConnectionSearches connections of the object at the cursor position.Connection(Find|ResetLinesAndPolygons|ResetPinsAndVias|Reset)
constraintConfigure or remove a drawing constraintconstraint(type, off)
constraint(type, value, [value...])
ddraft plugin
cpcbExecuted external autorouter cpcb to route the board or parts of the boardcpcb(board|selected, [command])cpcb plugin
CreateMenuCreates a new menu, popup (only path specified) or submenu (at least path and action are specified)CreateMenu(path)
CreateMenu(path, action, tooltip, cookie)
CreateTextCreate a new text objectCreateText(layer, fontID, X, Y, direction, scale, text)
CursorMove the cursor.Cursor(Type,DeltaUp,DeltaRight,Units)
CycleDragCycle through which object is being draggedCycleDrag()
d1debug action for developmentd1()diag plugin
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
ddraftEnter 2d drafting CLI mode or execute commandddraft([command])ddraft plugin
DebugDebug action.Debug(...)oldactions plugin
DebugXYDebug action, with coordinatesDebugXY(...)oldactions plugin
DeleteDelete stuff.Delete(Object [,idpath])
Delete(Selected)
Delete(AllRats|SelectedRats)
DeleteRatsDelete rat lines.DeleteRats(AllRats|Selected|SelectedRats)
DelGroupRemove a layer group; if the first argument is not specified, the current group is removedDelGroup([@group])
DescribeLocationReturn a string constant (valud until the next call) containing a short description at x;y (object, net, etc.)DescribeLocation(x, y)lib_hid_pcbui/status
DisableVendorDisables automatic drill size mapping.DisableVendor()oldactions plugin
DisperseElementsDisperses subcircuits.DisperseElements(All|Selected)
DisplaySeveral display-related actions.Display(SubcID, template)
Display(Grid|Redraw|Pinout|PinOrPadName)
Display(CycleClip|ToggleAllDirections|ToggleStartDirection)
Display(ToggleGrid|ToggleRubberBandMode|ToggleUniqueNames)
Display(ToggleName|ToggleClearLine|ToggleFullPoly|ToggleSnapPin)
Display(ToggleSnapOffGridLine|ToggleHighlightOnPoint|ToggleCheckPlanes)
Display(ToggleThindraw|ToggleThindrawPoly|ToggleOrthoMove|ToggleLocalRef)
Display(ToggleLiveRoute|ToggleShowDRC|ToggleAutoDRC|LockNames|OnlyNames)
distributeDistribute objectsDistribute(X/Y, [Lefts/Rights/Tops/Bottoms/Centers/Marks/Gaps, [First/Last/pcb_crosshair, First/Last/pcb_crosshair[, Gridless]]])distalign plugin
distributetextDistribute objectsDistribute(X/Y, [Lefts/Rights/Tops/Bottoms/Centers/Marks/Gaps, [First/Last/pcb_crosshair, First/Last/pcb_crosshair[, Gridless]]])distalign plugin
djoptPerform various optimizations on the current board.djopt(debumpify|unjaggy|simple|vianudge|viatrim|orthopull)
djopt(auto) - all of the above
djopt(miter)
djopt
dlg_confval_editPresent a dialog box for editing the value of a conf node at path.dlg_confval_edit(path, idx, role, [modal])dialogs plugin
dlg_obj_listLet the user select an object from a list of objectsdlg_obj_list()dialogs plugin
dlg_testtest the attribute dialogdlg_test()dialogs plugin
DrawColorSet pen color in of a gc.DrawColor(gc, colorstr)act_draw
DrawLineLow level draw (render) a line using graphic context gc.DrawLine(gc, x1, y1, x2, y2, thickness)act_draw
DrawPolyLow level draw (render) a polygon using graphic context gc.DrawPoly(gc, x, y, x, y, x, y, [x, y...])act_draw
DrawTextLow level draw (render) a text object using graphic context gc.DrawText(gc, x, y, string, rot, scale_percent)act_draw
DRCInvoke the DRC check. Results are presented as the argument requests.DRC([list|simple|print|log|dump])
DrcDialogExecute drc checks and invoke a view list dialog box for presenting the resultsDrcDialog([list|simple]dialogs plugin
DrcQueryDefModAutomated DRC rule editing (for scripting and import)DrcQueryDefMod(clear, source)
DrcQueryDefMod(create, rule_name)
DrcQueryDefMod(get, rule_name, field_name)
DrcQueryDefMod(set, rule_name, field_name, value)
drc_query
DrcQueryEditRuleInteractive, GUI based DRC rule editorDrcQueryEditRule(role, path, rule)
DrcQueryEditRule(role, rule)
drc_query
DrcQueryExportExport a rule and related definitions to a file.DrcQueryExport(ruleID, [filename], [format])drc_query
DrcQueryImportImport a rule and related definitions from a file.DrcQueryImport([filename])drc_query
DrcQueryListRulesList all drc rules implemented in drc_queryDrcQueryListRules()drc_query
DrcQueryRuleModAutomated DRC rule editing (for scripting and import)DrcQueryRuleMod(clear, source)
DrcQueryRuleMod(create, rule_name)
DrcQueryRuleMod(get, rule_name, field_name)
DrcQueryRuleMod(set, rule_name, field_name, value)
drc_query
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 plugin
DumpCsectPrint the cross-section of the board (layer stack)DumpCsect()draw_csect
dumpdataDump an aspect of the datadumpdata()diag plugin
dumpflagsdump flags, optionally using the format string provided by the userdumpflags([fmt])diag plugin
dumpfontsPrint info about fontsdumpfonts()diag plugin
dumpidsDump the ID hashDumpIDs()diag plugin
dumplayersPrint info about each layerdumplayers([all])diag plugin
DumpLibFootprintprint footprint file and metadata to stdoutDumpLibFootprint(footprintname, [bbox|origin])diag plugin
DumpLibraryDisplay the entire contents of the libraries.DumpLibrary()oldactions plugin
DumpObjFlagsPrint a script processable digest of all flags, per object typeDumpObjFlags()
DumpPluginDirsPrint plugins directories in a format digestable by scripts.DumpPluginDirs()
DumpPluginsPrint plugins loaded in a format digestable by scripts.DumpPlugins()
dumpundoPrint info about fontsdumpfonts()diag plugin
DumpVersionDump version in script readable format.DumpVersion()
DupGroupDuplicate a layer group; if the first argument is not specified, the current group is duplicatedDupGroup([@group])
EditGroupChange a property or attribute of a layer group. If the first argument starts with @, it is taken as the group name to manipulate, else the action uses the current layer's group. Without arguments or if only a layer name is specified, interactive runs editing.Editgroup([@group], [name=text|type=+bit|type=-bit])]
Editlayer([@layer], attrib, key=value)
EditLayerChange a property or attribute of a layer. If the first argument starts with @, it is taken as the layer name to manipulate, else the action uses the current layer. Without arguments or if only a layer name is specified, interactive runs editing.Editlayer([@layer], [name=text|auto=[0|1]|sub=[0|1])]
Editlayer([@layer], attrib, key=value)
ElementListAdds the given element if it doesn't already exist.ElementList(Start|Done|Need,,,)
ElementSetAttrSets or clears an element-specific attribute.ElementSetAttr(refdes,name[,value])
EnableVendorEnables automatic drill size mapping.EnableVendor()oldactions 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 plugin
ExecCommandRun shell commandSystem(shell_cmd)
ExecuteFileRun actions from the given file.ExecuteFile(filename)
ExpFeatTmpExperimental Feature Template.ExpFeatTmp(...)experimental features plugin
ExportExport the current layout, e.g. Export(png, --dpi, 600)Export(exporter, [exporter-args])
ExportcpcbToDumps the current board in c-pcb format.ExportcpcbTo(filename)cpcb plugin
ExportGUIOpen the export dialog.ExportGUI()dialogs plugin
ExportOldConnExport galvanic connection data in an old, custom file format.ExportOldConn(AllConnections|AllUnusedPins|ElementConnections,filename)export_oldconn HID
ExportScadPolyexports all selected polygons to an openscad script; only the outmost contour of each poly is exportedScadExportPoly(filename)openscad HID
exteditextedit(object|selected|buffer, [interactive|method])Invoke an external program to edit a specific part of the current board.extedit plugin
ExtobjConvFromCreate a new extended object of extotype by converting existing objectsExtobjConvFrom(selected|buffer, extotype)
ExtobjConvFrom(object, extotype, [idpath])
ExtobjGUIPropEditInvoke the extobj-implementation-specific GUI property editor, if availableExtobjGUIPropEdit([object, [idpath]])
ExtobjToggleConvert an extobj into a plain subc or backExtobjToggle([object, [idpath]])
extrouteExecuted external autorouter to route the board or parts of the boardextroute(board|selected, router, [confkey=value, ...])extern autorouter 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
find2perfMeasure the peformance of find2.cfind2perf()diag plugin
FlagEditChange the layer binding.FlagEdit(object)dialogs plugin
FlipFlip a subcircuit to the opposite side of the board.Flip(Object|Selected)
FontEditConvert the current font to a PCB for editing.FontEdit()fontmode plugin
FontSaveConvert the current PCB back to a font.FontSave()fontmode plugin
FontselOpen the font selection dialogFontsel()dialogs plugin
forcecolorchange selected objects' color to #RRGGBB, reset if does not start with '#'forcecolor(#RRGGBB)diag plugin
formula_bisectFind the value for exactly one of the arguments that produces the expected result. One argument must be a string with type:min:max:precision, the rest of the arguments and res must be numeric.formula_bisect(action, res, args)lib_formula plugin
fpasExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
fp_rehashFlush the library index; rescan all library search paths and rebuild the library index. Useful if there are changes in the library during a pcb-rnd session.fp_rehash()
FreeRotateBufferRotates the current paste buffer contents by the specified angle. The
angle is given in degrees. If no angle is given, the user is prompted
for one.
FreeRotateBuffer([Angle])
FullScreenHide widgets to get edit area full screenFullScreen(on|off|toggle)
GetMarkReturn mark properties in numeric form.GetMark(active|user_placed|x|y)act_read
GetParentDataReturn the closest upstream pcb_data_t * parent of an objectGetParentData([root_data,] idpath)act_read
GetStyleReturn integer index (>=0) of the currently active style or -1 if no style is selected (== custom style)GetStyle()
GetValueConvert a coordinate value. Returns an unitless double or FGW_ERR_ARG_CONV. The 3rd parameter controls whether to require relative coordinates (+- prefix). Wraps rnd_get_value_ex().GetValue(input, units, relative, default_unit)act_read
GetXYGet a coordinate. If x or y specified, the return value of the action is the x or y coordinate.GetXY([message, [x|y]])
GfxModModify a gfx object: set transparent pixel on the pixmap or resize by measurementGfxMod(transparent, [idpath, [#rrggbb]])
GfxMod(transparent, [idpath, [x, y]])
GfxMod(resize, [idpath, [pdx, pdy1, len]])
GlobalPullerPull all traces tight. With no argument it runs on the current layer.pcb_act_GlobalPuller([Found|Selected])puller plugin
GridSet the grid.grid(set, [name:]size[@offs][!unit])
grid(+|up)
grid(-|down)
grid(#N)
grid(idx, N)
GroupPropGuiChange group flags and propertiesGroupPropGui(groupid)dialogs plugin
gui_FallbackColorPickIntenal: GUI frontend action. Do not use directly.lib_hid_common plugin
gui_fpmap_chooseInternal call action for a dialog to select a footprint from a map.gui_fpmap_choose(map)dialogs 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
hPrint a help message for commands.hshand_cmd plugin
HelpOn-line action helpHelp()
IDPBasic idpath manipulation.IDP([print|free|dup], idpath)act_read
IDPListBasic idpath list manipulation.IDPList(alloc)
IDPList(free|clear|print|dup|length, list)
IDPList(get|pop|remove, list, idx)
IDPList(prepend|append|push, list, idpath)
act_read
impedance_coplanar_waveguideCalculate the approximated impedance of a coplanar_waveguide transmission line, in ohmsimpedance_coplanar_waveguide(trace_width, trace_clearance, subst_height, dielectric)lib_formula plugin
impedance_microstripCalculate the approximated impedance of a microstrip transmission line, in ohmsimpedance_microstrip(trace_width, trace_height, subst_height, dielectric)lib_formula plugin
ImportImport schematics.Import()
Import([gnetlist|make[,source,source,...]])
Import(setnewpoint[,(mark|center|X,Y)])
Import(setdisperse,D,units)
oldactions plugin
ImportcpcbFromLoads the auto-routed tracks from the specified c-pcb output.ImportcpcbFrom(filename)cpcb plugin
ImportGUIAsks user which schematics to import into PCB.ImportGUI()oldactions plugin
ImportSchImport schematics/netlist.ImportSch()
ImportSch(reimport)
ImportSch(setup, importer, [args...])
import_sch2 plugin
Inforeport plugin
InfoBarFileChangedPresent the "file changed" warning info bar with buttons to reload or cancelInfoBarFileChanged(open|close)dialogs plugin
integrityperform integrirty check on the current board and generate errors if neededintegrity()diag plugin
IntersectObjObjReturns 1 if point x;y with radius r is on the arc addressed by idpath, 0 else.IntersectObjObj(idpath, idpath)act_read
IOIncompatListPresent the format incompatibilities of the last save to file operation.IOIncompatList([list|simple])
IOIncompatListDialogPresent the format incompatibilities of the last save to file operation in a GUI dialog.IOIncompatListDialog([list|simple])dialogs plugin
ircnon-modal, single-instance, single-server, single-channel irc window for online supportirc()irc plugin
IsPointOnArcReturns 1 if point x;y with radius r is on the arc addressed by idpath, 0 else.IsPointOnArc(x, y, r, idpath)act_read
IsPointOnLineReturns 1 if point x;y with radius r is on the line addressed by idpath, 0 else.IsPointOnLine(x, y, r, idpath)act_read
jostleMake room by moving wires away.Jostle(diameter)jostle plugin
lLoads layout data.l [name] [format]shand_cmd plugin
LayerBindingChange the layer binding.LayerBinding(object)
LayerBinding(buffer)
dialogs plugin
LayerByStackLayer operations based on physical layer stackingLayerByStack(select, prev|next)
LayerHotkeyChange the key binding for a layerLayerHotkey(layer, select|vis)lib_hid_pcbui/actions
LayerObjDupDuplicate srcobj on a layer. Srcobj is specified by an idpath. For now data must be "pcb". Returns the idpath of the new object or 0 on error.LayerObjDup([noundo,] data, layer, srcobj)act_draw
LayerPropGuiChange layer flags and propertiesLayerPropGui(layerid)dialogs plugin
LayerVisResetReset layer visibility to safe defaults.LayerVisReset()
leLoads an element (subcircuit, footprint) into the current buffer.le [name]shand_cmd plugin
LibraryChangedTells the GUI that the libraries have changed.LibraryChanged()oldactions plugin
LibraryDialogOpen the library dialog.libraryDialog()dialogs plugin
LineNewCreate a pcb line segment on a layer. For now data must be "pcb". Returns the idpath of the new object or 0 on error.LineNew([noundo,] data, layer, X1, Y1, X2, Y2, Thickness, Clearance, Flags)act_draw
ListRotationsoldactions plugin
ListScriptsList fungw scripts, optionally filtered wiht regex pat.ListScripts([pat])script plugin
LiveScriptManage a live scriptLiveScript([new], [name])
LiveScript(load|save, name, [filame])
LiveScript(run|stop|rerun|undo, name)
script plugin
LoadLoad layout data from a user-selected file.Load()
Load(Layout|LayoutToBuffer|ElementToBuffer|Netlist|Revert)
dialogs plugin
LoadAccelNetFromLoads the specified Accel EDA netlist file.LoadAccelNetFrom(filename)accel_net importer
LoadCalayFromLoads the specified calay netlist/component file pair.LoadCalayFrom(filename)calay importer
LoadDsnFromLoads the specified routed dsn file.LoadDsnFrom(filename)dsn importer
LoadEeschemaFromLoads the specified eeschema .net file - the netlist must be an s-expression.LoadEeschemaFrom(filename)kicad plugin
LoadFontFromLoad PCB font from a fileLoadFontFrom([file, id])
LoadFootprintLoads a single footprint by name.LoadFootprint(filename[,refdes,value])
LoadFpcbnlFromLoads the specified freepcb netlist.LoadFpcbnlFrom(filename)fpcb_nl importer
LoadFromLoad layout data from a file.LoadFrom(Layout|LayoutToBuffer|SubcToBuffer|Netlist|Revert,filename[,format])
LoadHpglFromLoads the specified hpgl plot file to the current bufferLoadHpglFrom(filename)hpgl importer
LoadhypFromLoads the specified Hyperlynx file.LoadhypFrom(filename[, "debug"]...)hyp importer
LoadIpc356FromLoads the specified IPC356-D netlistLoadIpc356From(filename, [nonet], [nopad], [nosubc])ipcd356 importer
LoadLtspiceFromLoads the specified ltspice .net and .asc file - the netlist must be mentor netlist.LoadLtspiceFrom(filename)ltspice importer
LoadMentorFromLoads the specified Mentor Graphics Design Capture schematics flat .edf file.LoadMentorFrom(filename)mentor_sch importer
LoadMucsFromLoads the specified mucs routing file.LoadMucsFrom(filename)mucs importer
LoadOrcadNetFromLoads the specified Orcad netlist file.LoadOrcadNetFrom(filename)orcad_net importer
LoadPadsNetFromLoads the specified pads ascii netlist .asc file.LoadPadsNetFrom(filename)pads_net importer
LoadPixmapLoads a pixmap image from disk and creates a gfx object in buffer.LoadPixmap([filename])
LoadProtelNetFromLoads the specified protel netlist 2.0 file.LoadProtelNetFrom(filename)protel_net importer
LoadScriptLoad a fungw scriptLoadScript(id, filename, [language])script plugin
LoadTedaxFromLoads the specified block from a tedax file.LoadTedaxFrom(netlist|board|footprint|stackup|layer|drc|drc_query|route_res, filename, [block_id, [silent, [src]]])tEDAx IO
LoadTinycadFromLoads the specified tinycad .net file - the netlist must be tinycad netlist output.LoadTinycadFrom(filename)tinycad importer
LoadTtfPresents a GUI dialog for interactively loading glyphs from from a ttf fileLoadTtf()ttf importer
LoadTtfGlyphsLoads glyphs from an outline ttf in the specified source range, optionally remapping them to dstchars range in the pcb-rnd fontLoadTtfGlyphs(filename, srcglyps, [dstchars], [outline|polygon], [scale], [offset])ttf importer
LoadVendorFromLoads the specified vendor lihata file.LoadVendorFrom(filename)vendor drill mapping
LogManages the central, in-memory log.Log(clear, [fromID, [toID])
Log(export, [filename, [text|lihata])
LogDialogOpen the log dialog.LogDialog()lib_hid_common plugin
mLoads a layout into the current buffer.m [name]shand_cmd plugin
ManagePluginsManage plugins dialog.ManagePlugins()dialogs plugin
MarkCrosshairSet/Reset the pcb_crosshair mark.MarkCrosshair()
MarkCrosshair(Center)
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)
meshgenerate a mesh for simulationmesh()openems HID
MessageWrites 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, ...)
millCalculate toolpath for milling away coppermill([script])millpath plugin
MinClearGapEnsures that polygons are a minimum distance from objects.MinClearGap(delta)
MinClearGap(Selected, delta)
oldactions plugin
MinMaskGapoldactions plugin
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)
MorphPolygonConverts dead polygon islands into separate polygons.pcb_poly_morph(Object|Selected)
MoveCursorToMove the cursor to absolute coords, pan the view as needed.MoveCursorTo(x,y)
MoveLayerMoves/Creates/Deletes Layers.MoveLayer(old,new)
MoveLayer(lid,group,gid)
MoveObjectMoves the object under the crosshair.pcb_move_obj(X,Y,[units])
MoveToCurrentLayerMoves objects to the current layer.MoveToCurrentLayer(Object|SelectedObjects)
netPerform various actions on netlists.Net(find|select|rats|norats||ripup|addrats|clear[,net[,pin]])
Net(freeze|thaw|forcethaw)
Net(swap)
Net(add,net,pin)Net([rename|merge],srcnet,dstnet)
NetLengthReport physical network lengthNetLength(clear)
NetLength(object)
report plugin
netlistPerform various actions on netlists.Net(find|select|rats|norats||ripup|addrats|clear[,net[,pin]])
Net(freeze|thaw|forcethaw)
Net(swap)
Net(add,net,pin)Net([rename|merge],srcnet,dstnet)
NetlistChangedTells the GUI that the netlist has changed.NetlistChanged()oldactions plugin
NetlistDialogOpen the netlist dialog or refresh network lengths in an already open dialog.NetlistDialog([RefreshNetLens])dialogs plugin
NewStarts a new layout.New([name])
NewGroupCreate a new layer group with a single, positive drawn layer in itNewGroup(type [,location [, purpose[, auto|sub [,name[,grp_attribs[,unique|first|last]]]]])
NormalizeMove all objects within the drawing area (or buffer 0;0), align the drawing to 0;0 (or set buffer grab point to 0;0)Normalize([board|buffer[n]])
ObjCenterReturns the x or y coordinate of the center of an objectObjCenter(idpath, x|y)act_read
OnelinerExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
OpenemsExcitationSelect which openEMS excitation method should be exported and manipulate the associated parameters. When invoked without arguments a dialog box with the same functionality is presented.OpenemsExcitation([interactive])
OpenemsExcitation(select, excitationname)
OpenemsExcitation(set, [excitationnme], paramname, paramval)
OpenemsExcitation(get, [excitationnme], paramname)
openems HID
OptAutoOnlyToggles the optimize-only-autorouted flag.OptAutoOnly()oldactions plugin
OrderPCBOrder the board from a faborderPCB([gui])order plugin
PadstackBreakupBreak up a padstack into one non-padstack object per layer type (the hole is ignored)PadstackBreakup(buffer|selected|objet)
PadstackConvertConvert selection or current buffer to padstackPadstackConvert(buffer|selected, [originx, originy])
PadstackEditinteractive pad stack editorPadstackEdit(object, [tab])dialogs plugin
PadstackPlacePlace a pad stack (either proto_id, or if not specified, the default for style)PadstackPlace([proto_id|default], [x, y])
PanStart or stop panning (Mode = 1 to start, 0 to stop)Pan(Mode)lib_hid_common plugin
paralDraw a line perpendicular to another lineperp()ddraft plugin
pasExecute a script one-liner using a specific languageOneliner(lang, script)script plugin
PasteBufferVarious operations on the paste buffer.PasteBuffer(AddSelected|MoveSelected|Clear|1..PCB_MAX_BUFFER)
PasteBuffer(Rotate, 1..3)
PasteBuffer(Convert|Restore|Mirror)
PasteBuffer(ToLayout, X, Y, units)
PasteBuffer(ToLayout, crosshair)
PasteBuffer(Save, Filename, [format], [force])
PasteBuffer(SaveAll, Filename, [format])
PasteBuffer(LoadAll, Filename)
PasteBuffer(Push)
PasteBuffer(Pop)
PasteBuffer(GetSource, [1..PCB_MAX_BUFFER])
PCBChangedTells the GUI that the whole PCB has changed. The optional "revert"parameter can be used as a hint to the GUI that the same design is beingreloaded, and that it might keep some viewport settingsPCBChanged([revert])oldactions plugin
PcbDeleteAlias to Delete()
pcbsplitSplit objects (idpath or idpath list) with cutting edges (idpath or idpath list), returning the idpath list of the newly created objectsPcbSplit(cutting_edges, objs)ddraft plugin
pcb_acosscript plugin
pcb_asinscript plugin
pcb_atan2script plugin
pcb_atanscript plugin
pcb_cosscript plugin
pcb_sinscript plugin
pcb_sqrtscript plugin
pcb_tanscript plugin
perpDraw a line perpendicular to another lineperp()ddraft plugin
PinoutPresent the subcircuit pinout boxPinout()dialogs plugin
PolyBoolPerform polygon boolean operation on the clipped polygons referred. A poly is either and idpath, selected, found or object (for the object under the cursor). When not specified, two object polygons are used.PstkProto([noundo,] unite|isect|sub, [poly1, poly2, [poly...]])act_draw
PolyCombinepolycombine plugin
PolygonSome polygon related stuff.Polygon(Close|CloseHole|PreviousPoint)
PolyHatchhatch the selected polygon(s) with lines of the current style; lines are drawn on the current layer; flags are h:horizontal, v:vertical, c:contour, p:polyPolyHatch([spacing], [hvcp])
PolyHatch(interactive)
lib_polyhelp
PolyNewCreate an empty polygon. For now data must be "pcb". Use PolyNewPoint to add points. Returns a polygon pointer valid until PolyNewEnd() is called.PolyNew([noundo,] data, layer, ptlist, clearance, flags)act_draw
PolyNewEndClose and place a polygon started by PolyNew. Returns the idpath of the new object or 0 on error.PolyNewEnd([noundo,] data, layer, poly)act_draw
PolyNewFromPointsCreate a polygon. For now data must be "pcb". ptlist is a comma separated list of coordinates (untiless coordinates are treated as mm). Returns the idpath of the new object or 0 on error.PolyNewFromRectangle([noundo,] data, layer, ptlist, clearance, flags)act_draw
PolyNewFromRectangleCreate a rectangular polygon. For now data must be "pcb". Returns the idpath of the new object or 0 on error.PolyNewFromRectangle([noundo,] data, layer, x1, y1, x2, y2, clearance, flags)act_draw
PolyNewPointsAdd a list of points to a polygon created by PolyNew. Returns 0 on success.PolyNewPoints([noundo,] poly, ptlist)act_draw
PolyOffsreplicate the outer contour of the selected polygon(s) with growing or shrinking them by offset; the new polygon is drawn on the current layerPolyOffs(offset)lib_polyhelp
PolyStitchpolystitch plugin
PopupBring up the popup menu specified by MenuName, optionally modified with the object type under the cursor.Popup(MenuName, [obj-type])lib_hid_pcbui/actions
PreferencesPresent the preferences dialog, optionally opening the tab requested.Preferences([tabname])dialogs plugin
PrintPresent the print export dialog for printing the layout from the GUI.Print()
PrintActionsPrint all actions available.PrintActions()
PrintCalibrateCalibrate the printer.PrintCalibrate()dialogs plugin
PrintCopyrightPrint copyright notice.PrintCopyright()
PrintFilesPrint files currently loaded.PrintFiles()
PrintGUIOpen the print dialog.PrintGUI()dialogs plugin
PrintPathsPrint full paths and search paths.PrintPaths()
PrintUsagePrint command line arguments of pcb-rnd or a plugin loaded.PrintUsage()
PrintUsage(plugin)
PrintVersionPrint version.PrintVersion()
PromptForPrompt for a string. Returns the string (or NULL on cancel)PromptFor([message[,default[,title]]])
propeditpropedit(object[:id]|layer[:id]|layergrp[:id]|pcb|subc|selection|selected)propedit
propgetReturn the named property of scope or all selected objects to/by value. Scope is documented at PropEdit().propget([scope], name, [stattype])propedit
propprintPrint a property map of objects matching the scope. Scope is documented at PropEdit().PropPrint([scope])propedit
propsetChange the named property of scope or all selected objects to/by value. Scope is documented at PropEdit().propset([scope], name, value)propedit
proptoggleToggle the named property of scope or all selected objects, assuming the property is boolean. Scope is documented at PropEdit(). If create is true, non-existing attributes are created as true.proptoggle([scope], name, [create])propedit
pscalibps HID
pstklibPresent the padstack library dialog on board padstacks or the padstacks of a subcircuitpstklib([board|subcid|object])dialogs plugin
PstkNewCreate a padstack. For now data must be "pcb". glob_clearance=0 turns off global clearance. Returns the idpath of the new object or 0 on error.PstkNew([noundo,] data, protoID, x, y, glob_clearance, flags)act_draw
PstkProtoEditEdit a padstack prototype specified by its pointer.PstkProto([noundo,] proto, remove, layer_type)
PstkProto([noundo,] proto, copy, dst_layer_type, src_layer_type)
PstkProto([noundo,] proto, hdia, dia)
PstkProto([noundo,] proto, shape:line, layer_type, x1, y1, x2, y2, th, [square])
act_draw
PstkProtoTmpAllocate, insert or free a temporary padstack prototypePstkProto([noundo,] new)
PstkProto([noundo,] dup, idpath)
PstkProto([noundo,] dup, data, src_proto_id)
PstkProto([noundo,] insert, idpath|data, proto)
PstkProto([noundo,] insert_dup, idpath|data, proto)
PstkProto([noundo,] free, proto)
act_draw
PullerPull an arc-line junction tight.pcb_act_Puller()puller plugin
q!Quits the application without confirming.q!shand_cmd plugin
qQuits the application after confirming.qshand_cmd plugin
queryPerform various queries on PCB data.query(dump, expr) - dry run: compile and dump an expression
query(eval|evalidp, expr) - compile and evaluate an expression and print a list of results on stdout
query(select|unselect|view, expr) - select or unselect or build a view of objects matching an expression
query(setflag:flag|unsetflag:flag, expr) - set or unset a named flag on objects matching an expression
query(append, idplist, expr) - compile and run expr and append the idpath of resulting objects on idplist
query plugin
QueryCalcNetLenCalculates the network length by netname; returns an error message string or a positive coord with the lengthQueryCalcNetLen(netname)query plugin
QueryCompileFieldWith "compile": precompiles textual field name to field ID; with "free": frees the memory allocated for a previously precompiled fieldID.QueryCompileField(compile, fieldname)
QueryCompileField(free, fieldID)
query plugin
QueryObjReturn the value of a field of an object, addressed by the object's idpath and the field's name or precompiled ID. Returns NIL on error.QueryObj(idpath, [.fieldname|fieldID])query plugin
QuitQuits the application after confirming.Quit()
ReadGroupLength returns the number of groups on the current PCB. Field returns one of the fields of the group named in groupid. Layerid returns the integer layer ID (as interpreted within data) for the idxth layer of the group.ReadGroup(length)
ReadGroup(field, group, [init_invis|ltype|ltypestr|ltypehas|name|open|purpose|vis|length])
ReadGroup(layerid, group, idx)
act_read
RedoRedo recent "undo" operations.redo()
RedrawRedraw the entire screenRedraw()
regpolyGenerate regular polygon. Where is x;y and radius is either r or rx;ry. Rotation is in degrees.regpoly([where,] corners, radius [,rotation])shape plugin
ReloadScriptReload a fungw scriptReloadScript(id)script plugin
RemoveMenuRecursively removes a new menu, popup (only path specified) or submenu. RemoveMenu(path, cookie)
RemoveSelectedRemoves any selected objects.pcb_remove_selected()
RenumberRenumber all subcircuits. The changes will be recorded to filename
for use in backannotating these changes to the schematic.
Renumber()
Renumber(filename)
renumber plugin
RenumberBlockRenumber selected subcircuit refdes attributes by adding (new_base-old_base).RenumberBlock(old_base,new_base)renumber plugin
RenumberBufferRenumber buffer subcircuit refdes attributes by adding (new_base-old_base).RenumberBuffer(old_base,new_base)renumber plugin
ReplaceFootprintReplace the footprint of the selected components with the footprint specified.ReplaceFootprint([Selected|Object], [footprint], [dumb])
ReportProduce various report.Report([DrillReport|FoundPins|NetLengthTo])
Report(NetLength, [netname])
Report(Object|Subc, [log])
Report(AllNetLengths, [unit])
report plugin
ReportObjectReport on the object under the crosshairReportObject()report plugin
RipUpRipup auto-routed tracksRipUp(All|Selected|Element)
rnReads netlist.rn [name]shand_cmd plugin
Rotate90Rotates the object under the crosshair by 90 degree steps.pcb_move_obj(steps)
roundrectGenerate a rectangle with round cornersroundrect([where,] width[;height] [,rx[;ry] [,rotation [,cornstyle [,roundness]]]])shape plugin
RouteStyleWithout second argument: copies the indicated routing style into the current pen; with second argument sets or gets a field of the routing style.RouteStyle(style_id|style_name|@current, [set|get|del], [trace-thickness|trace-clearance|text-thickness|text-scale|name], [value]])
RouteStyle(new, [name])
RouteStylesChangedTells the GUI that the routing styles have changed.RouteStylesChanged()oldactions plugin
sSaves layout data.s [name]
w [name]
shand_cmd plugin
SaveSave layout data to a user-selected file.Save()
Save(Layout|LayoutAs)
Save(AllConnections|AllUnusedPins|ElementConnections)
Save(PasteBuffer)
Save(DialogByPattern, pcb|footprint|font|buffer, none|board|fp, prompt, [default_pattern])
dialogs plugin
SaveFontToSave PCB font to a fileSaveFontTo([file, id])
SaveLibSaves all subcircuits to a library file or directory from a board or buffer.SaveLib(file|dir, board|buffer, [filename], [fmt])
SavePatchSave netlist patch for back annotation.SavePatch(filename)
SaveTedaxSaves the specific type of data in a tEDAx file.SaveTedax(netlist|board-footprints|stackup|layer|board|drc|etest, filename)
SaveTedax(drc_query, filename, [rule_name])SaveTedax(route_req, filename, [confkey=value, confkey=value, ...])
tEDAx IO
SaveToSaves data to a file.SaveTo(Layout|LayoutAs,filename,[fmt])
SaveTo(PasteBuffer,filename,[fmt])
ScaleBufferScales the buffer by multiplying all coordinates by a floating point number.
If only x is given, it is also used for y and thickness too. If subc is not
empty, subcircuits are also scaled
ScaleBuffer(x [,y [,thickness [,subc]]])
ScriptCookieReturn a cookie specific to the current script instance during script initializationScriptCookie()script plugin
ScriptPersistencyRead or remove script persistency data savd on preunloadScriptPersistency(read|remove)script plugin
ScrollScroll the viewport.Scroll(up|down|left|right, [pixels])lib_hid_common plugin
SearchDialogOpen the log dialog.SearchDialog()query plugin
SelectToggles or sets the selection.Select(Object, [idpath])
Select(ToggleObject)
Select(All|Block|Connection|Invert)
Select(Convert)
SelectLayerSelect which layer is the current layer.SelectLayer(1..MAXLAYER|Silk|Rats)
SetFlagSets flags on objects.SetFlag(Object|Selected|SelectedObjects, flag)
SetFlag(SelectedLines|SelectedPins|SelectedVias, flag)
SetFlag(SelectedPads|SelectedTexts|SelectedNames, flag)
SetFlag(SelectedElements, flag)
flag = thermal | join
SetGridChange various board-wide values and sizes.SetGrid(delta|*mult|/div, [unit])
SetOctagonoldactions plugin
SetSameSets current layer and sizes to match indicated item.SetSame()
SetSquareoldactions plugin
SetThermalSet the thermal (on the current layer) of padstacks to the given style. Style is one of:
0: means no thermal.
1: horizontal/vertical, round.
2: horizontal/vertical, sharp.
3: is a solid connection to the polygon.
4: (invalid).
5: diagonal, round.
6: diagonal, sharp.
noshape: no copper shape on layer
SetThermal(Object|SelectedPins|SelectedVias|Selected, Style)
SetUnitsSet the default measurement units.SetUnits(mm|mil)
SetValueChange various board-wide values and sizes.SetValue(Grid|Line|LineSize|Text|TextScale, delta)
shapeInteractive shape generator.shape()shape plugin
smartdisperseDisperse subcircuits into clusters, by netlist connectionsSmartDisperse([All|Selected])smartdisperse plugin
splitUse one or more objects as cutting edge and trim or split other objects. First argument is the cutting edgetrim([selected|found|object], [selected|found|object])
split([selected|found|object], [selected|found|object])
ddraft plugin
StatusSetTextReplace status printout with text temporarily; turn status printout back on if text is not provided.StatusSetText([text])lib_hid_pcbui/status
strokeVarious gesture recognition related functionsstroke(gesture, seq)stroke plugin
subcVarious operations on subcsubc(hash, [board|selected])
subc(loose, on|off|toggle|check)
SwapSidesSwaps the side of the board you're looking at.SwapSides(|v|h|r, [S])lib_hid_pcbui/actions
SystemRun shell commandSystem(shell_cmd)
tangDraw a line to be tangential to a circletang()ddraft plugin
Teardropsteardrops plugin
TedaxTestParseReturns 1 if the file looks like tEDAx (0 if not)TedaxTestParse(filename|FILE*)tEDAx IO
TextNewCreate a pcb text on a layer. For now data must be "pcb". Font id 0 is the default font. Thickness 0 means default, calculated thickness. Scale=100 is the original font size. Returns the idpath of the new object or 0 on error.TextNew([noundo,] data, layer, fontID, x, y, rot, scale, thickness, text_string, flags)act_draw
ToggleHideNameoldactions plugin
ToggleVendorToggles the state of automatic drill size mapping.ToggleVendor()oldactions plugin
ToggleViewToggle the visibility of the specified layer or layer group.ToggleView(1..MAXLAYER)
ToggleView(layername)
ToggleView(Silk|Rats|Pins|Vias|BackSide)
ToggleView(All, Open|Vis, Set|Clear|Toggle)
ToolChange 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)
ToPolyconvert a closed loop of lines and arcs into a polygonToPoly()
ToPoly(outline)
lib_polyhelp
trimUse one or more objects as cutting edge and trim or split other objects. First argument is the cutting edgetrim([selected|found|object], [selected|found|object])
split([selected|found|object], [selected|found|object])
ddraft plugin
UndoUndo recent changes.undo()
undo(ClearList|FreezeSerial|UnfreezeSerial|IncSerial)
UndoDialogOpen the undo dialog.UndoDialog()dialogs plugin
UnloadScriptUnload a fungw scriptUnloadScript(id)script plugin
UnloadVendorUnloads the current vendor drill mapping table.UnloadVendor()vendor drill mapping
UnselectUnselects the object at the pointer location or the specified objects.Unselect(All|Block|Connection)
ViewListPresent a new empty view listviewlist([name, [winid, [listptr]]])dialogs plugin
wSaves layout data.s [name]
w [name]
shand_cmd plugin
wqSaves the layout data and quits.wqshand_cmd plugin
ZoomGUI zoomZoom()
Zoom([+|-|=]factor)
Zoom(x1, y1, x2, y2)
Zoom(?)
Zoom(get)
Zoom(found|selected)
lib_hid_pcbui/actions
ZoomToGUI zoomZoom()
Zoom([+|-|=]factor)
Zoom(x1, y1, x2, y2)
Zoom(?)
Zoom(get)
Zoom(found|selected)
lib_hid_pcbui/actions
+ + Index: tags/2.3.0/doc/user/09_appendix/action_src/addrats.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/addrats.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/addrats.html (revision 33253) @@ -0,0 +1,20 @@ +First argument: +

+ +
AllRats + Create rat lines for all loaded nets that aren't already connected on + with copper. + +
SelectedRats + Similarly, but only add rat lines for nets connected to selected pins + and pads. + +
Close + Selects the shortest unselected rat on the board. +
+

+The second argument is temporary and optional, for a workaround of a bug in +the old (to be removed) autorouter. If the value of the second argument is +"manhattan", non-axis-aligned lines are ignored when looking for rat anchor +points. + Index: tags/2.3.0/doc/user/09_appendix/action_src/addtimer.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/addtimer.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/addtimer.html (revision 33253) @@ -0,0 +1,24 @@ +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. Index: tags/2.3.0/doc/user/09_appendix/action_src/adjuststyle.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/adjuststyle.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/adjuststyle.html (revision 33253) @@ -0,0 +1,2 @@ +With no argument or negative argument, operate on the currently selected +style (if there's any). Else operate on the style indexed. Index: tags/2.3.0/doc/user/09_appendix/action_src/align.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/align.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/align.html (revision 33253) @@ -0,0 +1,26 @@ +Align(X, [Lefts/Rights/Centers/Marks, [First/Last/pcb_crosshair/Average[, Gridless]]]) +

+Align(Y, [Tops/Bottoms/Centers/Marks, [First/Last/pcb_crosshair/Average[, Gridless]]]) +

+Arguments: +

+ +
X or Y + Select which axis will move, other is untouched. + +
Lefts, Rights, Tops, Bottoms, Centers, Marks + Pick alignment point within each object + +
First, Last, pcb_crosshair, Average + Alignment reference, First=Topmost/Leftmost, Last=Bottommost/Rightmost, Average or pcb_crosshair point + +
Gridless + Do not force results to align to prevailing grid. + +
+

+Defaults are Marks, First. +

+For non-subcircuit objects: using Marks is not recommended, using Gridless is +recommended. + Index: tags/2.3.0/doc/user/09_appendix/action_src/applyvendor.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/applyvendor.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/applyvendor.html (revision 33253) @@ -0,0 +1,2 @@ +This will modify all of your drill holes to match the list of allowed +sizes for your vendor. Index: tags/2.3.0/doc/user/09_appendix/action_src/atomic.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/atomic.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/atomic.html (revision 33253) @@ -0,0 +1,38 @@ +This action allows making multiple-action bindings into an atomic +operation that will be undone by a single Undo command. For example, +to optimize rat lines, you'd delete the rats and re-add them. To +group these into a single undo, you'd want the deletions and the +additions to have the same undo serial number. So, you Save, +delete the rats, Restore, add the rats - using the same serial +number as the deletes, then Block, which checks to see if the +deletions or additions actually did anything. If not, the serial +number is set to the saved number, as there's nothing to undo. If +something did happen, the serial number is incremented so that these +actions are counted as a single undo step. +

+An alternative mechanism is freeze/unfreeze for the case restoring between +every two actions is not possible or not practical. The sequence is +Save, Freeze, call actions, UnFreeze, +Block. +

+Arguments: +

+ +
Save + Saves the undo serial number. + +
Restore + Returns it to the last saved number. + +
Close + Sets it to 1 greater than the last save. + +
Block + Does a Restore if there was nothing to undo, else does a Close. + +
Freeze + Make sure no subsequent actions will bump the undo serial + +
UnFreeze or Thaw + Allow subsequent actions to bump the undo serial again +
Index: tags/2.3.0/doc/user/09_appendix/action_src/attributes.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/attributes.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/attributes.html (revision 33253) @@ -0,0 +1,3 @@ +Pops up a dialog letting the user edit the attributes of the +pcb, a subcircuit, or a layer. + Index: tags/2.3.0/doc/user/09_appendix/action_src/autoplaceselected.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/autoplaceselected.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/autoplaceselected.html (revision 33253) @@ -0,0 +1,2 @@ +Attempts to re-arrange the selected components such that the nets +connecting them are minimized. Note that you cannot undo this. Index: tags/2.3.0/doc/user/09_appendix/action_src/autoroute.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/autoroute.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/autoroute.html (revision 33253) @@ -0,0 +1,18 @@ +Before autorouting, it's important to set up a few things. First, +make sure any layers you aren't using are disabled, else the +autorouter may use them. Next, make sure the current routing +styles are set accordingly. Last, make sure "new lines clear +polygons" is set, in case you eventually want to add a copper pour. +

+Autorouting takes a while. During this time, the program may not be +responsive. +

+Arguments: +

+ +
AllRats + Attempt to autoroute all rats. + +
SelectedRats + Attempt to autoroute the selected rats. +
Index: tags/2.3.0/doc/user/09_appendix/action_src/benchmark.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/benchmark.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/benchmark.html (revision 33253) @@ -0,0 +1,3 @@ +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. Index: tags/2.3.0/doc/user/09_appendix/action_src/boardflip.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/boardflip.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/boardflip.html (revision 33253) @@ -0,0 +1,12 @@ +All objects on the board are up-down flipped (mirrored over the x axis). +

+Command line board flipping: +

+echo "
+BoardFlip()
+SaveTo(LayoutAs,$OUTFILE)
+Quit()
+" | pcb $INFILE
+
+

+To flip the board physically, use BoardFlip(sides) Index: tags/2.3.0/doc/user/09_appendix/action_src/center.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/center.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/center.html (revision 33253) @@ -0,0 +1,2 @@ +Move the pointer to the center of the window, but only if it's +currently within the window already. Index: tags/2.3.0/doc/user/09_appendix/action_src/changeclearsize.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/changeclearsize.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/changeclearsize.html (revision 33253) @@ -0,0 +1,3 @@ +If the solder mask is currently showing, this action changes the +solder mask cutout size. If the mask is not showing, this action +changes the polygon clearance. Index: tags/2.3.0/doc/user/09_appendix/action_src/changeflag.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/changeflag.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/changeflag.html (revision 33253) @@ -0,0 +1,4 @@ +Toggles the given flag on the indicated object(s). The flag may be +one of the flags listed above (thermal, join). The +value may be the number 0 or 1. If the value is 0, the flag is +cleared. If the value is 1, the flag is set. Index: tags/2.3.0/doc/user/09_appendix/action_src/changejoin.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/changejoin.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/changejoin.html (revision 33253) @@ -0,0 +1,5 @@ +The join flag determines whether a line or arc, drawn to intersect a +polygon, electrically connects to the polygon or not. When joined, +the line/arc is simply drawn over the polygon, making an electrical +connection. When not joined, a gap is drawn between the line and the +polygon, insulating them from each other. Index: tags/2.3.0/doc/user/09_appendix/action_src/changename.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/changename.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/changename.html (revision 33253) @@ -0,0 +1,22 @@ +Arguments: +

+ + +
Object + Changes the "name" of the object under the cursor. For a text object + this is the text string. For a terminal, this is the terminal ID. + For a subcircuit this is the refdes. For a subc text object that has + only the refdes template in it, it offers changing the text object + (template) or the parent subcircuit's refdes attribute. + +
Refdes + Changes the refdes attribute of a subcircuit under the cursor. + +
Layout + Changes the name of the layout. This is printed on the fab drawings. + +
Layer + Changes the name of the currently active layer. + +
+ Index: tags/2.3.0/doc/user/09_appendix/action_src/changepinname.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/changepinname.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/changepinname.html (revision 33253) @@ -0,0 +1,5 @@ +This can be especially useful for annotating pin names from a +schematic to the layout without requiring knowledge of the pcb file +format. +

+ChangePinName(U3, 7, VCC) Index: tags/2.3.0/doc/user/09_appendix/action_src/changesize.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/changesize.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/changesize.html (revision 33253) @@ -0,0 +1,5 @@ +For lines and arcs, this changes the width. For padstacks, this +changes the shape size (but does not touch the hole diameter). For +texts, this changes the scaling factor. +For subcircuits, this changes the width of the lines and arcs and +shape sizes of padstacks (thus mostly relative values make sense). Index: tags/2.3.0/doc/user/09_appendix/action_src/changesizes.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/changesizes.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/changesizes.html (revision 33253) @@ -0,0 +1,2 @@ +Call ChangeSize, ChangeDrillSize and ChangeClearSize +with the same arguments. If any of them did not fail, return success. Index: tags/2.3.0/doc/user/09_appendix/action_src/chklayer.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/chklayer.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/chklayer.html (revision 33253) @@ -0,0 +1 @@ +Returns 1 if the specified layer is the active layer. Index: tags/2.3.0/doc/user/09_appendix/action_src/chkrst.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/chkrst.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/chkrst.html (revision 33253) @@ -0,0 +1 @@ +Return 1 if route_style_id matches pen. Index: tags/2.3.0/doc/user/09_appendix/action_src/chkview.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/chkview.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/chkview.html (revision 33253) @@ -0,0 +1 @@ +Return 1 if layerid is visible. Intended for menu item 'checked' fields. Index: tags/2.3.0/doc/user/09_appendix/action_src/claimnet.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/claimnet.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/claimnet.html (revision 33253) @@ -0,0 +1,16 @@ +The ClaimNet() action can be used to construct network metadata +(netlist entry) converting existing physical (galvanic, copper) connections +or object lists. +

+When galvanic connections are mapped, the first argument shall be object; +in this case the object under the mouse cursor is the starting point and +anything galvanically connected (at the moment) is considered part of the new +network. This mode of operation is useful for capturing existing nets. +

+When the first argument is selected or found, the +list of (selected or found) terminals are converted to a new net, regardless +of galvanic connections. This mode is useful for designing a PCB by a netlist +but without a schematics - in this setup the netlist is "drawn" in pcb-rnd as +well. +

+If netname is specified, the user is prompted for a name. Index: tags/2.3.0/doc/user/09_appendix/action_src/clrflag.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/clrflag.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/clrflag.html (revision 33253) @@ -0,0 +1,4 @@ +Turns the given flag off, regardless of its previous setting. See +ChangeFlag. +

+ClrFlag(SelectedLines,join) Index: tags/2.3.0/doc/user/09_appendix/action_src/command.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/command.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/command.html (revision 33253) @@ -0,0 +1,12 @@ +The command entry allows the user to manually enter actions to be +executed. This action opens the command entry. +

+There are two ways to finish with the command window. If you press +the Enter key, the command is invoked, the entry normally goes away, +and the next time you bring up the command window it's empty. If you +press the Esc key, the window goes away without invoking +anything, and the next time you bring up the command window it's +empty. +

+Use the up and down arrow keys to access command history. + Index: tags/2.3.0/doc/user/09_appendix/action_src/connection.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/connection.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/connection.html (revision 33253) @@ -0,0 +1,28 @@ +Connections found with this action will be highlighted in the +"connected-color" color and will have the "found" flag set. +

+Arguments: +

+ +
Find + The net under the cursor is "found". + +
ResetLayerObjects + Any "found" layer objects (lines, arcs, polygons and texts) are + marked "not found". + +
ResetPadstacks + Any "found" padstack are marked "not found". WARNING: does not + touch non-padstack heavy terminals! + +
Reset + All "found" objects are marked "not found". + +
ResetLinesAndPolygons + Obsolate, misleading name for ResetLayerObjects. Do not use. + +
ResetPinsAndVias + Obsolate, misleading name for ResetPadstacks. Do not use. + +
+ Index: tags/2.3.0/doc/user/09_appendix/action_src/cursor.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/cursor.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/cursor.html (revision 33253) @@ -0,0 +1,29 @@ +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. + +
Index: tags/2.3.0/doc/user/09_appendix/action_src/cycledrag.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/cycledrag.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/cycledrag.html (revision 33253) @@ -0,0 +1,8 @@ +When multiple overlapping objects are accessible by clicking on a pixel +on the screen, drag&drop operations may become harder to do: pcb-rnd will +often "pick the wrong object" on click. +

+Cycledraw provides a way to get pcb-rnd to jump to selecting another object +of the avaialble ones on the original site, while the user is still in drag +mode. This obviously works only through the key binding, as selecting the +menu would require the drag operation to finish first. Index: tags/2.3.0/doc/user/09_appendix/action_src/disperseelements.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/disperseelements.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/disperseelements.html (revision 33253) @@ -0,0 +1,5 @@ +Normally this is used when starting a board, by selecting all subcircuits +and then dispersing them. This scatters the subcircuits around the board +so that you can pick individual ones, rather than have all the +subcircuits at the same 0,0 coordinate and thus impossible to choose +from. Index: tags/2.3.0/doc/user/09_appendix/action_src/display.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/display.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/display.html (revision 33253) @@ -0,0 +1,121 @@ +Changes random display related global states. +

+ +
SubcID
Description
Value +
Specify the subcircuit ID template to be printed on the subcircuit layer + +
Redraw + Redraw the whole board. + +
ToggleAllDirections + When clear, lines can be drawn at any angle. When set, lines are + restricted to multiples of 45 degrees and requested lines may be + broken up according to the clip setting. + +
CycleClip + Changes the way lines are restricted to 45 degree increments. The + various settings are: straight only, orthogonal then angled, and angled + then orthogonal. If AllDirections is set, this action disables it. + +
CycleCrosshair + Changes crosshair drawing. Crosshair may accept form of 4-ray, + 8-ray and 12-ray cross. + +
ToggleRubberBandMode + If set, moving an object moves all the lines attached to it too. + +
ToggleStartDirection + If set, each time you set a point in a line, the Clip toggles between + orth-angle and angle-ortho. + +
ToggleUniqueNames + If set, you will not be permitted to change the name of an element to + match that of another element. + +
ToggleSnapPin + If set, pin centers and pad end points are treated as additional grid + points that the cursor can snap to. + +
ToggleSnapOffGridLine + If set, snap at some sensible point along a line. + +
ToggleHighlightOnPoint + If set, highlights lines and arcs when the crosshair is on one of their + two (end) points. + +
ToggleLocalRef + If set, the mark is automatically set to the beginning of any move, so + you can see the relative distance you've moved. + +
ToggleThindraw + If set, objects on the screen are drawn as outlines (lines are drawn + as center-lines). This lets you see line endpoints hidden under pins, + for example. + +
ToggleThindrawPoly + If set, polygons on the screen are drawn as outlines. + +
ToggleShowDRC + If set, pending objects (i.e. lines you're in the process of drawing) + will be drawn with an outline showing how far away from other copper + you need to be. + +
ToggleLiveRoute + If set, the progress of the autorouter will be visible on the screen. + +
ToggleAutoDRC + If set, you will not be permitted to make connections which violate + the current DRC and netlist settings. + +
ToggleCheckPlanes + If set, lines and arcs aren't drawn, which usually leaves just the + polygons. If you also disable all but the layer you're interested in, + this allows you to check for isolated regions. + +
ToggleOrthoMove + If set, the crosshair is only allowed to move orthogonally from its + previous position. I.e. you can move a subcircuit or line up, down, + left, or right, but not up+left or down+right. + +
ToggleName + Selects whether the pinouts show the pin names or the pin numbers. + +
ToggleLockNames + If set, text will ignore left mouse clicks and actions that work on + objects under the mouse. You can still select text with a lasso (left + mouse drag) and perform actions on the selection. + +
ToggleOnlyNames + If set, only text will be sensitive for mouse clicks and actions that + work on objects under the mouse. You can still select other objects + with a lasso (left mouse drag) and perform actions on the selection. + +
ToggleClearLine + When set, the clear-line flag causes new lines and arcs to have their + "clear polygons" flag set, so they won't be electrically connected + to any polygons they overlap. + +
ToggleFullPoly + When set, the full-poly flag causes new polygons to have their + "full polygon" flag set, so all parts of them will be displayed + instead of only the biggest one. + +
ToggleGrid + Resets the origin of the current grid to be wherever the crosshair is. + If you provide two numbers after this, the origin is set to that + coordinate. + +
Grid + Toggles whether the grid is displayed or not. + +
Pinout + Causes the pinout of the subcircuit indicated by the cursor to be + displayed, usually in a separate window. + +
PinOrPadName + Toggles whether the names of terminals will be + displayed. If the cursor is over an subcircuit, all of its terminals + are affected. + +
+ Index: tags/2.3.0/doc/user/09_appendix/action_src/distribute.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/distribute.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/distribute.html (revision 33253) @@ -0,0 +1,23 @@ +Distribute(X, [Lefts/Rights/Centers/Marks/Gaps, [First/Last/pcb_crosshair, First/Last/pcb_crosshair[, Gridless]]]) +

+Distribute(Y, [Tops/Bottoms/Centers/Marks/Gaps, [First/Last/pcb_crosshair, First/Last/pcb_crosshair[, Gridless]]]) +

+As with align, plus: +

+Arguments: +

+ +
Gaps + Make gaps even rather than spreading points evenly. + +
First, Last, pcb_crosshair + Two arguments specifying both ends of the distribution, they can't both be the same. +
+

+Defaults are Marks, First, Last +

+Distributed objects always retain the same relative order they had +before they were distributed. +

+For non-subcircuit objects: using Marks is not recommended, using Gridless is +recommended. Index: tags/2.3.0/doc/user/09_appendix/action_src/djopt.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/djopt.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/djopt.html (revision 33253) @@ -0,0 +1,47 @@ +The different types of optimizations change your board in order to +reduce the total trace length and via count. +

+Arguments: +

+ + +
debumpify + Looks for U-shaped traces that can be shortened or eliminated. + +
unjaggy + Looks for corners which could be flipped to eliminate one or more + corners (i.e. jaggy lines become simpler). + +
simple + Removing uneeded vias, replacing two or more trace segments in a row + with a single segment. This is usually performed automatically after + other optimizations. + +
vianudge + Looks for vias where all traces leave in the same direction. Tries to + move via in that direction to eliminate one of the traces (and thus a + corner). + +
viatrim + Looks for traces that go from via to via, where moving that trace to a + different layer eliminates one or both vias. + +
orthopull + Looks for chains of traces all going in one direction, with more + traces orthogonal on one side than on the other. Moves the chain in + that direction, causing a net reduction in trace length, possibly + eliminating traces and/or corners. + +
splitlines + Looks for lines that pass through vias, pins, or pads, and splits them + into separate lines so they can be managed separately. + +
auto + Performs the above options, repeating until no further optimizations + can be made. + +
miter + Replaces 90 degree corners with a pair of 45 degree corners, to reduce + RF losses and trace length. + +
Index: tags/2.3.0/doc/user/09_appendix/action_src/dowindows.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/dowindows.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/dowindows.html (revision 33253) @@ -0,0 +1,27 @@ +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. + +
+ + Index: tags/2.3.0/doc/user/09_appendix/action_src/drc.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/drc.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/drc.html (revision 33253) @@ -0,0 +1,12 @@ +Output styles available: + +
name description +
list display a full list of all violations, with preview of the current item (large dialog) +
simple a small & simple dialog that navigates the user through the violations one by one, sequentially +
print print the list to stdout in human readable form +
log print the list as INFO lines in the log in human readable form +
dump print the list to stdout in script readable form +
+

+Note that the design rule check uses the current board rule settings, +not the current style settings. Index: tags/2.3.0/doc/user/09_appendix/action_src/elementlist.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/elementlist.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/elementlist.html (revision 33253) @@ -0,0 +1,80 @@ +Arguments: +

+ +
Start + Indicates the start of an subcircuit list; call this before any + Need actions. + +
Need + Searches the board for an subcircuit with a matching refdes.
+ If found, the value and footprint are updated.
+ If not found, a new subcircuit is created with the given + footprint and value. + +
Done + Compares the list of subcircuits needed since the most recent + Start with the list of subcircuits actually on the + board. Any subcircuits that weren't listed are selected, so + that the user may delete them. +
+

+Placement of new subcircuits depends on conf node +import/footprint_placement/method, which is a string containing +a one word instruction that is one of: +

+ + +
disperse + place all new subcircuits at randomized coordinates around + location, within a distance configured in + import/footprint_placement/disperse + +
frame + place all new subcircuits close outside of the drawing area, + "framing" the design + +
+ +

+Location is a string instruction specified by +import/footprint_placement/location, the value is one of: +

+ + +
(empty, no value) + place around the coordinates specified in coords + import/footprint_placement/x and import/footprint_placement/y + +
center + place around the center of the drawing area + +
mark + place around the mark (or center of the drawing area if no mark present + at the moment of import) + +
+ +

+Removal of excess subcircuits (the ones present on the board but not in +the new netlist) depends on conf node import/footprint_removalt/method, +which is a string containing a one word instruction that is one of: +

+ + +
select (or empty) + select excess subcircuits (an {s r} after the import removes them) + +
remove + automatically remove excess subcircuits + +
list + no change on excess subcircuit data on the board, but + open a view list dialog enumerating them + +
+ +

+Note: subcircuits with the nonetlist flag set or empty/missing refdes +will not be taken as excess even if they are not present on the netlist. + + Index: tags/2.3.0/doc/user/09_appendix/action_src/elementsetattr.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/elementsetattr.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/elementsetattr.html (revision 33253) @@ -0,0 +1,4 @@ +If a value is specified, the named attribute is added (if not already +present) or changed (if it is) to the given value. If the value is +not specified, the given attribute is removed if present. + Index: tags/2.3.0/doc/user/09_appendix/action_src/executefile.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/executefile.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/executefile.html (revision 33253) @@ -0,0 +1,2 @@ +Lines starting with # are ignored. + Index: tags/2.3.0/doc/user/09_appendix/action_src/exportoldconn.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/exportoldconn.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/exportoldconn.html (revision 33253) @@ -0,0 +1,14 @@ +Arguments: +

+ + +
AllConnections + Save all connections to a file. + +
AllUnusedPins + List all unconnected terminals to a file. + +
ElementConnections + Save connections to the subcircuit at the cursor to a file. + +
Index: tags/2.3.0/doc/user/09_appendix/action_src/flip.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/flip.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/flip.html (revision 33253) @@ -0,0 +1,6 @@ +Note that the location of the subcircuit will be symmetric about the +cursor location; i.e. if the part you are pointing at will still be at +the same spot once the subcircuit is on the other side. When flipping +multiple subcircuits, this retains their positions relative to each +other, not their absolute positions on the board. + Index: tags/2.3.0/doc/user/09_appendix/action_src/freerotatebuffer.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/freerotatebuffer.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/freerotatebuffer.html (revision 33253) @@ -0,0 +1,2 @@ +Rotates the contents of the pastebuffer by an arbitrary angle. If no +angle is given, the user is prompted for one. Index: tags/2.3.0/doc/user/09_appendix/action_src/getxy.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/getxy.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/getxy.html (revision 33253) @@ -0,0 +1 @@ +Prompts the user for a coordinate, if one is not already selected. Index: tags/2.3.0/doc/user/09_appendix/action_src/gfxmod.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/gfxmod.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/gfxmod.html (revision 33253) @@ -0,0 +1,8 @@ +Commands: +

    +
  • transparent, no more args: interactive way for the user to specify the transparent color by a click +
  • transparent, idpath, #rrggbb: specify transparent color +
  • transparent, idpath, px, py: specify transparent color by pixel coordinates within the pixmap +
  • resize, no more args: interactive resizer where the user clicks on two points of the pixmap on screen and specifies the real disatnce between them and the code resizes the pixmap to match that +
  • resize, idpath, pdx, pdy, len: resize pixmap so that pixel distance pdx;pdy will match len coord units +
Index: tags/2.3.0/doc/user/09_appendix/action_src/import.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/import.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/import.html (revision 33253) @@ -0,0 +1,5 @@ +Deprecated. Please use ImportSch instead. +

+For help on switching over, please read this: err0002 + + Index: tags/2.3.0/doc/user/09_appendix/action_src/importgui.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/importgui.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/importgui.html (revision 33253) @@ -0,0 +1,5 @@ +Deprecated. Please use ImportSch instead. +

+For help on switching over, please read this: err0002 + + Index: tags/2.3.0/doc/user/09_appendix/action_src/importsch.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/importsch.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/importsch.html (revision 33253) @@ -0,0 +1,33 @@ +Imports netlist (and optionally footprint references) from schematic(s) or +netlist(s). Works from one or multiple input files. This action does not +do file operations on its own, it is merely a dispatched to import plugins. +

+The import configuration is normally stored in the config tree of the board +file (on the design role of the conf system) and consists of: +

    +
  • the name of the importer that will load the input files +
  • a list of arguments to the importer (strings, most often input file names) +
  • misc settings, e.g. verbosity of the import +
+

+When called without argument, or with the reimport the action will +read the config and perform an import. +

+When called with setup, the action will store the configuration +read from the rest of the arguments: +

+	ImportSch(setup, importer, args...)
+
+

+There can be zero or more arguments following the importer. The syntax and +meaning of those arguments are specific to the importer, but is most usually +the file name(s) to import from, e.g. +

+ImportSch(setup, tEDAx, foo.tdx)
+
+
+ImportSch(setup, gnetlist, sheet1.sch, sheet2.sch)
+
+

+When called with dialog, the action will present a non-modal +GUI dialog that allows changing the setup and performing the import. Index: tags/2.3.0/doc/user/09_appendix/action_src/l.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/l.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/l.html (revision 33253) @@ -0,0 +1,4 @@ +Loads a new datafile (layout) and, if confirmed, overwrites any +existing unsaved data. If no filename is specified a file select box +will popup. + Index: tags/2.3.0/doc/user/09_appendix/action_src/layerbystack.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/layerbystack.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/layerbystack.html (revision 33253) @@ -0,0 +1,9 @@ +First argument determines what to perform. + +When first argument is select, the second argument is either +prev or next and the previous or next layer on the layer +stack is selected. Note: layers are displayed in the layer stack order in +the layer selector widget (normally on the left side of the main window) so +prev/next is stepping up/down on that list. + + Index: tags/2.3.0/doc/user/09_appendix/action_src/le.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/le.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/le.html (revision 33253) @@ -0,0 +1,2 @@ +The filename is passed to the +footprint loader. If no filename is specified a file select box will popup. Index: tags/2.3.0/doc/user/09_appendix/action_src/listscripts.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/listscripts.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/listscripts.html (revision 33253) @@ -0,0 +1,6 @@ +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). + Index: tags/2.3.0/doc/user/09_appendix/action_src/livescript.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/livescript.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/livescript.html (revision 33253) @@ -0,0 +1,40 @@ +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. + +
+ Index: tags/2.3.0/doc/user/09_appendix/action_src/load.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/load.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/load.html (revision 33253) @@ -0,0 +1,5 @@ +This action is a GUI front-end to the core's LoadFrom action. +If you happen to pass a filename, LoadFrom is called directly. +Else, the user is prompted for a filename to load, and then LoadFrom +is called with that filename. + Index: tags/2.3.0/doc/user/09_appendix/action_src/loadfootprint.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/loadfootprint.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/loadfootprint.html (revision 33253) @@ -0,0 +1,4 @@ +Loads a single footprint by name, rather than by reference or through +the library. If a refdes and value are specified, those are inserted +into the footprint as well. The footprint remains in the paste buffer. + Index: tags/2.3.0/doc/user/09_appendix/action_src/loadfrom.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/loadfrom.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/loadfrom.html (revision 33253) @@ -0,0 +1,28 @@ +This action assumes you know what the filename is. The various GUIs +should have a similar Load action where the filename is +optional, and will provide their own file selection mechanism to let +you choose the file name. +

+Arguments: +

+ +
Layout + Loads an entire PCB layout, replacing the current one. + +
LayoutToBuffer + Loads an entire PCB layout to the paste buffer. + +
ElementToBuffer + Loads the given footprint file into the paste buffer. Footprint files + contain only a single subcircuit definition in one of the various + supported file formats. + +
Netlist + Loads a new netlist, replacing any current netlist. + +
Revert + Re-loads the current layout from its disk file, reverting any changes + you may have made. + +
+ Index: tags/2.3.0/doc/user/09_appendix/action_src/loadscript.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/loadscript.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/loadscript.html (revision 33253) @@ -0,0 +1,10 @@ +id is an arbitrary string assigned by the user. id +must be unique per pcb-rnd session per script and may contain alphanumeric characters +and undescrore. +

+fn is the file name of the script, which is a path. Pcb-rnd 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). Index: tags/2.3.0/doc/user/09_appendix/action_src/loadttfglyphs.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/loadttfglyphs.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/loadttfglyphs.html (revision 33253) @@ -0,0 +1,37 @@ +Import a range of glyphs from ttf outline font into the current font as +symbols, starting from a specific character position. Note: pcb-rnd +font symbols are not unicode code poitns, but consists of a single, +8 bit ASCII code page, thus values above 255 are invalid as destination +symbol code. +

+The srcglyph argumnet is a single character description or +a pair of character descriptions separated with two dots (".."). In the +former case the import is a single glyph, in the latter case the import +is the whole range between the two characters, inclusive (one or more glyphs). +

+The dstchars argumnet is always a single character description, +addressing within the 0..255 range of the pcb-rnd font. This argment determines +the first destination symbol that is going to be overwritten. If srcglyph +specifies multiple characters, dstchars is internally stepped +after each glyp import, up to 255, where the import stops. +

+A character description addresses a code point on the input or +a character code on the output, using one fo the following syntax variants: +

    +
  • 'A' is converted to 65 (as a single charatcer using the 8 bit ASCII table) +
  • is converted as decimal number 10 +
  •  is converted as hexadecimal number, to 16 +
  • U+10 is converted as hexadecimal number, to 16 +
  • anything else is taken as a single character and is converted as it was wrapped in '' +
+

+The 4th argument is either polygon or line. When it is polygon, the glyph is +imported as a polygon (with or without holes). When it is line, all contours +of the glyph is imported as a series of lines. When not specified, it defaults +to polygon. +

+Finally, scale and offset specifies the transformation +during the import. Each argument is either a single number or a pair of numbers +separated with comma or semicolon or / or * or x, and specify the x and y +components of the transformation. When only the x component is specified, y +is assumed to be the same (this is useful for scale). Index: tags/2.3.0/doc/user/09_appendix/action_src/loadvendorfrom.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/loadvendorfrom.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/loadvendorfrom.html (revision 33253) @@ -0,0 +1,7 @@ +Arguments: +

+ +
filename + Name of the vendor lihata file. If not specified, the user will + be prompted to enter one. +
Index: tags/2.3.0/doc/user/09_appendix/action_src/m.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/m.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/m.html (revision 33253) @@ -0,0 +1 @@ +If no filename is specified a file select box will popup. Index: tags/2.3.0/doc/user/09_appendix/action_src/markcrosshair.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/markcrosshair.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/markcrosshair.html (revision 33253) @@ -0,0 +1,9 @@ +The "mark" is a small X-shaped target on the display which is +treated like a second origin (the normal origin is the upper let +corner of the board). The GUI will display a second set of +coordinates for this mark, which tells you how far you are from it. +

+If no argument is given, the mark is toggled - disabled if it was +enabled, or enabled at the current cursor position of disabled. If +the Center argument is given, the mark is moved to the current +cursor location. Index: tags/2.3.0/doc/user/09_appendix/action_src/message.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/message.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/message.html (revision 33253) @@ -0,0 +1,17 @@ +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 +pcb-rnd. 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 argumenterro level +
ERROR PCB_MSG_ERROR +
WARNING PCB_MSG_WARNING +
INFO PCB_MSG_INFO +
DEBUG PCB_MSG_DEBUG +
+ Index: tags/2.3.0/doc/user/09_appendix/action_src/mode.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/mode.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/mode.html (revision 33253) @@ -0,0 +1 @@ +This command is a compatibility alias to tool. Index: tags/2.3.0/doc/user/09_appendix/action_src/morphpolygon.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/morphpolygon.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/morphpolygon.html (revision 33253) @@ -0,0 +1,5 @@ +If a polygon is divided into unconnected "islands", you can use +this command to convert the otherwise disappeared islands into +separate polygons. Be sure the cursor is over a portion of the +polygon that remains visible. Very small islands that may flake +off are automatically deleted. Index: tags/2.3.0/doc/user/09_appendix/action_src/movelayer.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/movelayer.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/movelayer.html (revision 33253) @@ -0,0 +1,25 @@ +Moves a layer, creates a new layer, or deletes a layer. +

+Arguments: +

+ +
old + The is the layer number to act upon. Allowed values are: +
    +
  • c = Currently selected layer. +
  • -1 = Create a new layer. +
  • number = An existing layer number. +
+
new + Specifies where to move the layer to. Allowed values are: +
    +
  • -1 = Deletes the layer. +
  • up = Moves the layer up (TODO: is this supported?) +
  • down = Moves the layer down (TODO: is this supported?) +
  • step+ = Moves the layer towards the end of its group's list. +
  • step- = Moves the layer towards the beginning of its group's list. +
  • c = Creates a new layer. +
  • grp gid = move layer into group; target group ID is the 3rd argument +
+ +
Index: tags/2.3.0/doc/user/09_appendix/action_src/moveobject.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/moveobject.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/moveobject.html (revision 33253) @@ -0,0 +1,5 @@ +The code and Y are treated like delta +if they are prefixed by + or -, otherwise, they are absolute. Units can be +mil or mm and is used when X and Y +have no unit specified. If no unit unspecified in coords or units, +nanometer is assumed. Index: tags/2.3.0/doc/user/09_appendix/action_src/movetocurrentlayer.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/movetocurrentlayer.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/movetocurrentlayer.html (revision 33253) @@ -0,0 +1,4 @@ +Note that moving an subcircuit from a component layer to a solder layer, +or from solder to component, won't automatically flip it. Use the +Flip action to do that. + Index: tags/2.3.0/doc/user/09_appendix/action_src/netlist.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/netlist.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/netlist.html (revision 33253) @@ -0,0 +1,75 @@ +Each of these actions apply to a specified set of nets. net and +pin are patterns which match one or more nets or pins; these +patterns may be full names or regular expressions. If an exact match +is found, it is the only match; if no exact match is found, +then the pattern is tried as a regular expression. +

+If neither net nor pin are specified, all nets apply. +If net is specified but not pin, all nets matching +net apply. If both are specified, nets which match net +and contain a pin matching pin apply. +

+freeze, thaw and forcethaw +temporarily prevents changes to the netlist from being reflected in +the GUI. For example, if you need to make multiple changes, you +freeze the netlist, make the changes, then thaw it. +Note that freeze/thaw requests may nest, with the netlist being fully thawed +only when all pending freezes are thawed. You can bypass the nesting +by using forcethaw, which resets the freeze count and immediately +updates the GUI. +

+Argument summary: +

+

+ +
find + Nets which apply are marked @emph{found} and are drawn in the + connected-color color. + +
select + Nets which apply are selected (added to existing selections). + +
unselect + Nets which apply are unselected (removed from existing selections). + +
rats + Nets which apply are marked as available for the rats nest. + +
norats + Nets which apply are marked as not available for the rats nest. + +
allrats + Mark all nets available for the rats nest. + +
allnorats + Mark all nets not available for the rats nest. + +
clear + Clears the netlist. + +
ripup + Remove all non-subcircuit-part copper object that is connected to a net. + +
add + Add the given pin to the given netlist, creating either if needed. + +
AddRats + Calculate and add all rats required for finishing the named network. + +
swap + Swap the connections one end of two selected rats and pins. + +
sort + Called after a list of add's, this sorts the netlist. + +
freeze
thaw
forcethaw +
Temporarily prevents changes to the netlist from being reflected in the GUI. + +
rename + Change the name of a network (with back annotation) + +
merge + Move all terminal connections from the source network (first arg) + to the destination network (with back annotation) + +
Index: tags/2.3.0/doc/user/09_appendix/action_src/new.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/new.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/new.html (revision 33253) @@ -0,0 +1 @@ +If a name is not given, one is prompted for. Index: tags/2.3.0/doc/user/09_appendix/action_src/onliner.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/onliner.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/onliner.html (revision 33253) @@ -0,0 +1,19 @@ +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 +
Index: tags/2.3.0/doc/user/09_appendix/action_src/openemsexcitation.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/openemsexcitation.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/openemsexcitation.html (revision 33253) @@ -0,0 +1,16 @@ +When invoked without argument or with interactive a dialog box +is presented, allowing the user to do the same operations as with the +action. +

+If the first argument select, further OpenEMS exports will use +the excitation named in the excitationname argument (in short: +the excitation is selected). +

+Arguments set and get is used to read or change an +excitation parameter named in paramname. When excitationname +is not set, they operate on the currently selected excitation. For set +the paramval argument is mandatory. +

+Note: the code remembers all settings for all excitements, not only the +excitement that is currently selected. The selection and all parameters are +saved as board attributes. \ No newline at end of file Index: tags/2.3.0/doc/user/09_appendix/action_src/pan.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/pan.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/pan.html (revision 33253) @@ -0,0 +1,3 @@ +Start or stop panning. To start call with Mode = 1, to stop call with +Mode = 0. + Index: tags/2.3.0/doc/user/09_appendix/action_src/pastebuffer.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/pastebuffer.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/pastebuffer.html (revision 33253) @@ -0,0 +1,65 @@ +There are a number of paste buffers; the actual limit is a +compile-time constant PCB_MAX_BUFFER. It +is normally 5. One of these is the "current" paste buffer, +often referred to as "the" paste buffer. + +Arguments: +

+ + +
AddSelected + Copies the selected objects to the current paste buffer. + +
Clear + Remove all objects from the current paste buffer. + +
Convert + Convert the current paste buffer to an subcircuit. + +
Restore + Convert any subcircuit in the paste buffer back to plain objects. + +
Mirror + Flip all objects in the paste buffer vertically (up/down flip). To mirror + horizontally, combine this with rotations. + +
Rotate + Rotates the current buffer. The number to pass is 1..3, where 1 means + 90 degrees counter clockwise, 2 means 180 degrees, and 3 means 90 + degrees clockwise (270 CCW). + +
Normalize + Set the buffer origin to the center of the paste buffer bounding box. + This is useful especially if an import plugin loaded objects in the buffer + with a large offset. + +
Save + Saves subcircuits in the current buffer to the indicated file. If + format is specified, try to use that file format, else use the default. + If force is specified, overwrite target, don't ask. + +
SaveAll + Saves all content of the current buffer to the indicated file. If + format is specified, try to use that file format, else use the default. + +
LoadAll + Loads a previously saved paste buffer into the current buffer from the + indicated file. + +
ToLayout + Pastes objects in the current buffer to the indicated X, Y + coordinates in the layout. The X and Y are treated like + delta is for many other objects. For each, if it's prefixed by + + or -, then that amount is relative to the last + location. Otherwise, it's absolute. If units is unspecified, units are PCB's internal + units, currently nanometer. If "crosshair" is used instead of coordinates, + the paste happens at the current crosshair coords. + +
1..PCB_MAX_BUFFER + Selects the given buffer to be the current paste buffer. + +
GetSource + Returns the source file path the buffer is loaded from or nil if there + is none. The return value is a string, usable from user scripts. + +
Index: tags/2.3.0/doc/user/09_appendix/action_src/polybool.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/polybool.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/polybool.html (revision 33253) @@ -0,0 +1,31 @@ +The boolean operation argument is one of these: +

    +
  • unite: calculate the union of the polygons +
  • isect: calculate the intersection of all polygons; the result is the area where all argument polygons are present +
  • sub: subtract subsequent polygons from the first polygon +
+

+A polygon is a pcb layer object, that is: if it's fullpoly, it may have +multiple islands. The code operates on the clipped shape of the input polygons, +not on the 'as drawn shape'. The result is zero or more polygon layer objects, +each with a single island, created on the current layer. +

+The rest of the arguments will build a flat list of polygon objects to +work on and need to address at least two polygons. Each argument may be +one of: +

    +
  • object: the user needs to click an object using the GUI +
  • selected: all selected polygons are appended to the list +
  • found: all found (green highlight) polygons are appended to the list +
  • ipdath: address a specific polygon +
+

+Note: for the sub operation the first polygon is special, so order +of attributes matter. When using selected or found to address +polygons, if multiple polygons are selected or found at the time, the order +they end up added to the operation object list is undefined. +

+Input polygons are unchanged, new polygons are created on the current layer. +

+Demo video: PolyBool(sub) mini-howto. + Index: tags/2.3.0/doc/user/09_appendix/action_src/polycombine.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/polycombine.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/polycombine.html (revision 33253) @@ -0,0 +1,2 @@ +The selected polygons are combined together according to the ordering +of their points. Index: tags/2.3.0/doc/user/09_appendix/action_src/polygon.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/polygon.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/polygon.html (revision 33253) @@ -0,0 +1,17 @@ +Argument: +

+ +
Close + Creates the final segment of the polygon. This may fail if clipping + to 45 degree lines is switched on, in which case a warning is issued. + +
CloseHole + Creates the final segment of the polygon hole. This may fail if clipping + to 45 degree lines is switched on, in which case a warning is issued. + +
PreviousPoint + Resets the newly entered corner to the previous one. The Undo action + will call Polygon(PreviousPoint) when appropriate to do so. + +
+ Index: tags/2.3.0/doc/user/09_appendix/action_src/polystitch.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/polystitch.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/polystitch.html (revision 33253) @@ -0,0 +1,5 @@ +The polygon under the cursor (based on closest-corner) is stitched +together with the polygon surrounding it on the same layer. +

+Use with pstoedit conversions where there's a "hole" in the shape - +select the hole. Index: tags/2.3.0/doc/user/09_appendix/action_src/popup.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/popup.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/popup.html (revision 33253) @@ -0,0 +1,11 @@ +Pops up the specified menu. The menu must have been defined +in the popups subtree in the menu lht file. If the second argument +is specified, the menu name is modified by runtime data: +

+ + +
obj-type + append a dash and the object type name (e.g. "-line") for the object + currently under the cursor + +
Index: tags/2.3.0/doc/user/09_appendix/action_src/preunload.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/preunload.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/preunload.html (revision 33253) @@ -0,0 +1,15 @@ +preunload is an optional action scripts may provide. When present, +it is called by pcb-rnd as the last call to the script before the script is +unloaded. It has two purposes: +

    +
  • give scripts a chance to clean up, uninit and unregister +
  • give scripts a chance to perist their state +
+

+State persisting is achieved through returning a string from this action. That +string is then saved by pcb-rnd under the scripts' load ID (as specified by +the user). In a later script load, the script with the same ID may read the +persistent data frolm disk using the ScriptPersistency(read) action +and can remove the save using the ScriptPersistency(remove) action. +

+It should never be called by the user or other code or other actions. Index: tags/2.3.0/doc/user/09_appendix/action_src/print.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/print.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/print.html (revision 33253) @@ -0,0 +1,8 @@ +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. + + + Index: tags/2.3.0/doc/user/09_appendix/action_src/printcalibrate.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/printcalibrate.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/printcalibrate.html (revision 33253) @@ -0,0 +1,2 @@ +This will print a calibration page, which you would measure and type +the measurements in, so that future printouts will be more precise. Index: tags/2.3.0/doc/user/09_appendix/action_src/promptfor.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/promptfor.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/promptfor.html (revision 33253) @@ -0,0 +1,5 @@ +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. + + Index: tags/2.3.0/doc/user/09_appendix/action_src/puller.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/puller.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/puller.html (revision 33253) @@ -0,0 +1,4 @@ +The Puller action is a special-purpose optimization. When +invoked while the crosshair is over the junction of an arc and a line, +it will adjust the arc's angle and the connecting line's endpoint such +that the line intersects the arc at a tangent. Index: tags/2.3.0/doc/user/09_appendix/action_src/q.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/q.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/q.html (revision 33253) @@ -0,0 +1,2 @@ +If you have unsaved changes, you will be prompted to confirm (or +save) before quitting, unless the action name included a !. Index: tags/2.3.0/doc/user/09_appendix/action_src/quit.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/quit.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/quit.html (revision 33253) @@ -0,0 +1,2 @@ +If you have unsaved changes, you will be prompted to confirm (or save) +before quitting. Index: tags/2.3.0/doc/user/09_appendix/action_src/redo.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/redo.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/redo.html (revision 33253) @@ -0,0 +1,10 @@ +The Redo action allows you to recover from the last undo command. +You might want to do this if you thought that undo was going to revert +something other than what it actually did (in case you are confused +about which operations are un-doable), or if you have been backing up +through a long undo list and over-shoot your stopping point. Any +change that is made since the undo in question will trim the redo +list. For example if you add ten lines, then undo three of them you +could use redo to put them back, but if you move a line on the board +before performing the redo, you will lose the ability to "redo" the +three "undone" lines. Index: tags/2.3.0/doc/user/09_appendix/action_src/reloadscript.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/reloadscript.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/reloadscript.html (revision 33253) @@ -0,0 +1,4 @@ +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). + Index: tags/2.3.0/doc/user/09_appendix/action_src/renumberblock.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/renumberblock.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/renumberblock.html (revision 33253) @@ -0,0 +1,7 @@ +RenumberBlock(oldnum,newnum) +

+All selected subcircuit refdes attributes are renumbered by adding (newnum-oldnum) to +the existing number. +

+RenumberBlock(100,200) will change R213 +to R313. Index: tags/2.3.0/doc/user/09_appendix/action_src/renumberbuffer.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/renumberbuffer.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/renumberbuffer.html (revision 33253) @@ -0,0 +1,3 @@ +RenumberBuffer(oldnum,newnum) +

+Same as RenumberBlock, but the paste buffer is renumbered. Index: tags/2.3.0/doc/user/09_appendix/action_src/replacefootprint.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/replacefootprint.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/replacefootprint.html (revision 33253) @@ -0,0 +1,16 @@ +Replace footprint(s) from the library or buffer, in-place (preserving +the original subcircuit's location, rotation and metadata) and append +the replacement to the back annotation changeset. +

+If first argument is selected, replace all selected subcircuits +with the new footprint; if it is object, replace only one +subcircuit, under the cursor. +

+If the second argument is a footprint name, load it from the library. +If it is @buffer, use the subcircuit in the current buffer (there +must be exactly 1 subcircuit in the buffer). If it is empty or not specified, +the user is asked for a footprint. +

+If the third argument is dumb the location and rotation of the +original subcircuit is not preserved (but all metadata and board side are +preserved). A dumb replacement also omits creating back annotation. Index: tags/2.3.0/doc/user/09_appendix/action_src/report.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/report.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/report.html (revision 33253) @@ -0,0 +1,27 @@ +Arguments: +

+ +
Object + The object under the crosshair will be reported, describing various + aspects of the object. + +
DrillReport + A report summarizing the number of drill sizes used, and how many of + each, will be produced. + +
FoundPins + A report listing all pins and pads which are marked as "found" will + be produced. + +
NetLength + The name and length of the net under the crosshair will be reported to + the message log. An optional parameter specifies the netname; when present + the length of the named network is printed, else the net under the cursor + is used. + +
AllNetLengths + The name and length of the net under the crosshair will be reported to + the message log. An optional parameter specifies the unit name (e.g. mm) + +
+ Index: tags/2.3.0/doc/user/09_appendix/action_src/reportdialog.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/reportdialog.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/reportdialog.html (revision 33253) @@ -0,0 +1,2 @@ +This is a shortcut for Report(Object). + Index: tags/2.3.0/doc/user/09_appendix/action_src/ripup.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/ripup.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/ripup.html (revision 33253) @@ -0,0 +1,10 @@ +Arguments: +

+ +
All + Removes all lines and vias which were created by the autorouter. + +
Selected + Removes all selected lines and vias which were created by the + autorouter. +
Index: tags/2.3.0/doc/user/09_appendix/action_src/rn.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/rn.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/rn.html (revision 33253) @@ -0,0 +1 @@ +If no filename is given a file select box will pop up. Index: tags/2.3.0/doc/user/09_appendix/action_src/rotate90.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/rotate90.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/rotate90.html (revision 33253) @@ -0,0 +1,4 @@ +Rotates the object under the mouse pointer by 90 degree steps. +steps must be an integer between -3 and +3. + + Index: tags/2.3.0/doc/user/09_appendix/action_src/routestyle.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/routestyle.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/routestyle.html (revision 33253) @@ -0,0 +1,22 @@ +Reads or writes route style properties. +

+If the first argument is new, a new style is created, optionally using +the name provided as the second argument; else the following happens. +

+The first argument addresses the style and is one of: +

    +
  • an integer greater than zero: style ID (styles are counted from 1) +
  • @current, which will pick the style currently selected +
  • an arbitrary style name, which will pick the first style with matching name +
+

+The second argument is one of: +

    +
  • set, which will modify the addressed style using the 4th argment value +
  • get, where the 4th argument is omitted and the return value of the action holds the resulting value of the query +
  • del, which will remove the style addressed. +
+

+The 3rd argument addresses the property of the style. +

+Note: all operations by this action are undoable. Index: tags/2.3.0/doc/user/09_appendix/action_src/s.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/s.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/s.html (revision 33253) @@ -0,0 +1,2 @@ +If no filename is entered, either the last one is used +again or, if it is not available, a file select box will pop up. Index: tags/2.3.0/doc/user/09_appendix/action_src/save.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/save.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/save.html (revision 33253) @@ -0,0 +1,9 @@ +This action is a GUI front-end to the core's SaveTo action. +If you happen to pass a filename then SaveTo is called directly. +Else, the user is prompted for a filename to save, and then SaveTo +is called with that filename. +

+The DialogByPattern mode is intended for scripts and core: it presents a dialog +box with format selection and listing patterns, but does not perform any +real file operation just returns a filename*format string. + Index: tags/2.3.0/doc/user/09_appendix/action_src/savelib.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/savelib.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/savelib.html (revision 33253) @@ -0,0 +1,7 @@ +Useful when multiple subcircuits should be saved to be reused as a library. +When first argument is dir, each subcircuit is saved in a separate, numbered +file. If the first argument is file and the target file format has +library support, all subcircuits are saved in the same file, as a library. +

+If a single subcircuit from buffer needs to be saved to be a footprint, +use the SaveTo action with first argument set to PasteBuffer. Index: tags/2.3.0/doc/user/09_appendix/action_src/saveto.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/saveto.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/saveto.html (revision 33253) @@ -0,0 +1,19 @@ +Arguments: +

+ +
Layout + Saves the current layout. + +
LayoutAs + Saves the current layout, and remembers the filename used. + +
PasteBuffer + Save the subcircuit from the active Buffer to a file. The buffer + needs to contain exactly one subcircuit. This is + the graphical way to create a footprint. If multiple subcircuits + needs to be saved, use the SaveLib action. + +
AllConnections, AllUnusedPins, ElementConnections + obsolete arguments, kept for compatibility; please use + ExportOldConn instead. +
Index: tags/2.3.0/doc/user/09_appendix/action_src/scriptcookie.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/scriptcookie.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/scriptcookie.html (revision 33253) @@ -0,0 +1,9 @@ +The script: +

    +
  • may call ScriptCookie() during script initialization and save the resulting cookie string +
  • may use the cookie string to register to core pcb-rnd infrastructure that requires cookie, such as CreateMenu +
  • can depend on pcb-rnd 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. Index: tags/2.3.0/doc/user/09_appendix/action_src/scriptpersistency.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/scriptpersistency.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/scriptpersistency.html (revision 33253) @@ -0,0 +1,8 @@ +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. Index: tags/2.3.0/doc/user/09_appendix/action_src/scroll.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/scroll.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/scroll.html (revision 33253) @@ -0,0 +1,12 @@ +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. +
+ Index: tags/2.3.0/doc/user/09_appendix/action_src/select.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/select.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/select.html (revision 33253) @@ -0,0 +1,25 @@ +Arguments: +

+ +
Object
ToggleObject +
If second argument is present, select the object addressed by that + idpath, else selects the object under the cursor. + +
Block + Selects all objects in a rectangle indicated by the cursor. + +
All + Selects all objects on the board. + +
Connection + Selects all connections with the ``found'' flag set. + +
Convert + Converts the selected objects to a subcircuit. This uses the highest + numbered paste buffer. + +
Invert + Invert selection: anything that was not selected becomes selected, + everything that was selected becomes unselected. Locked objects + are not affected. +
Index: tags/2.3.0/doc/user/09_appendix/action_src/selectlayer.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/selectlayer.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/selectlayer.html (revision 33253) @@ -0,0 +1,2 @@ +The specified layer becomes the currently active layer. It is made +visible if it is not already visible Index: tags/2.3.0/doc/user/09_appendix/action_src/setflag.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/setflag.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/setflag.html (revision 33253) @@ -0,0 +1,7 @@ +Turns the given flag on, regardless of its previous setting. See +ChangeFlag. +

+SetFlag(SelectedPins,thermal) + + + Index: tags/2.3.0/doc/user/09_appendix/action_src/setsame.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/setsame.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/setsame.html (revision 33253) @@ -0,0 +1,3 @@ +When invoked over any line, arc, polygon, or via, this changes the +current layer to be the layer that item is on, and changes the current +sizes (thickness, clearance, etc) according to that item. Index: tags/2.3.0/doc/user/09_appendix/action_src/setthermal.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/setthermal.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/setthermal.html (revision 33253) @@ -0,0 +1,39 @@ +This changes how/whether padstacks connect to any rectangle or polygon +on the current layer. The first argument can specify one object, or all +selected padstacks. +The second argument specifies the style of connection. +

+Thermal styles: +

+ +
0 + no connection, + +
1 + horizontal & vertical fingers with round edges, + +
2 + horizontal & vertical fingers with sharp edges, + +
3 + solid connection, + +
4 + invalid, do not use + +
5 + 45 degree fingers with rounded corners. + +
6 + 45 degree fingers with sharp edges, + +
noshape + remove copper shape on layer + +
+ +

+Padstacks may have thermals whether or not there is a polygon available +to connect with. However, they will have no visible effect until a polygon +is drawn around the padstack. + Index: tags/2.3.0/doc/user/09_appendix/action_src/setunits.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/setunits.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/setunits.html (revision 33253) @@ -0,0 +1,7 @@ + +
mil + Sets the display units to mils (1/1000 inch). + +
mm + Sets the display units to millimeters. +
Index: tags/2.3.0/doc/user/09_appendix/action_src/setvalue.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/setvalue.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/setvalue.html (revision 33253) @@ -0,0 +1,14 @@ +Arguments: +

+ +
Grid + Sets the grid spacing. + +
Line
LineSize +
Changes the thickness of new lines. + +
Text
TextScale +
Changes the size of new text. + +
+ Index: tags/2.3.0/doc/user/09_appendix/action_src/smartdisperse.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/smartdisperse.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/smartdisperse.html (revision 33253) @@ -0,0 +1,6 @@ +Improve the initial dispersion of subcircuits by choosing an order based +on the netlist, rather than the arbitrary subcircuit order. This isn't +the same as a global autoplace, it's more of a linear autoplace. It +might make some useful local groupings. For example, you should not +have to chase all over the board to find the resistor that goes with +a given LED. Index: tags/2.3.0/doc/user/09_appendix/action_src/swapsides.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/swapsides.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/swapsides.html (revision 33253) @@ -0,0 +1,31 @@ +This action changes the way you view the board (flipping the board). +

+Arguments: +

+ + +
v + Flips the board over vertically (up/down); try to keep location on + screen. + +
h + Flips the board over horizontally (left/right), like flipping pages in + a book. + +
r + Rotates the board 180 degrees without changing sides. +
+

+If no argument is given, the board isn't moved but the opposite side +is shown. +

+Normally, this action changes which pads and silk layer are drawn as +pcb_true silk, and which are drawn as the "invisible" layer. It also +determines which solder mask you see. +

+If S is specified as a second argument, +if the layer group for the side you're looking at +is visible and currently active, and the layer group for the opposite +is not visible (i.e. disabled), then this action will also swap which +layer group is visible and active, effectively swapping the "working +side" of the board. Index: tags/2.3.0/doc/user/09_appendix/action_src/toggleview.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/toggleview.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/toggleview.html (revision 33253) @@ -0,0 +1,8 @@ +If you pass an integer, that layer is specified by index (the first +layer is 1, etc). If you pass a layer name, that layer is +specified by name. When a layer is specified, the visibility of the +layer group containing that layer is toggled. +

+If you pass a special layer name, the visibility of those components +(silk, rats, etc) is toggled. Note that if you have a layer named +the same as a special layer, the layer is chosen over the special layer. Index: tags/2.3.0/doc/user/09_appendix/action_src/tool.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/tool.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/tool.html (revision 33253) @@ -0,0 +1,35 @@ +Selects the tool or changes tool related global states. +

+ +
Arc
Arrow
Copy
InsertPoint
Line
Lock +
Move
None
PasteBuffer
Poly
PolyHole
Rectangle +
Remove
Rotate
Text
Thermal
Via
... +
Select the indicated tool. + +
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 pcb-rnd 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. + +
Index: tags/2.3.0/doc/user/09_appendix/action_src/undo.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/undo.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/undo.html (revision 33253) @@ -0,0 +1,11 @@ +The unlimited undo feature of pcb-rnd allows you to recover from +most operations that materially affect you work. Calling +pcb_undo without any parameter recovers from the last (non-undo) +operation. ClearList is used to release the allocated +memory. ClearList is called whenever a new layout is started or +loaded. See also Redo. +

+Note that undo groups operations by serial number; changes with the +same serial number will be undone (or redone) as a group. See +Atomic. + Index: tags/2.3.0/doc/user/09_appendix/action_src/unloadscript.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/unloadscript.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/unloadscript.html (revision 33253) @@ -0,0 +1,2 @@ +id is the same that was specified for LoadScript. +After the call id is released (can be reused for a new LoadScript). Index: tags/2.3.0/doc/user/09_appendix/action_src/unselect.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/unselect.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/unselect.html (revision 33253) @@ -0,0 +1,14 @@ +Arguments: +

+ +
All + Unselect all objects. + +
Block + Unselect all objects in a rectangle given by the cursor. + +
Connection + Unselect all connections with the "found" flag set. +
+ + Index: tags/2.3.0/doc/user/09_appendix/action_src/w.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/w.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/w.html (revision 33253) @@ -0,0 +1,2 @@ +This commands has been added for the convenience of vi users +and has the same functionality as s. Index: tags/2.3.0/doc/user/09_appendix/action_src/wq.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/wq.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/wq.html (revision 33253) @@ -0,0 +1,2 @@ +This command has been added for the convenience of vi users and +has the same functionality as s combined with q. Index: tags/2.3.0/doc/user/09_appendix/action_src/zoom.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/action_src/zoom.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/action_src/zoom.html (revision 33253) @@ -0,0 +1,54 @@ +Changes the zoom (magnification) of the view of the board. If no +arguments are passed, the view is scaled such that the board just fits +inside the visible window (i.e. "view all"). Otherwise, +factor specifies a change in zoom factor. +It may be prefixed by +, -, = to change how the zoom +factor is modified (relative or absolute). The factor is a +floating point number, such as 1.5 or 0.75. +

+Alternatively a box can be specified with 4 coordinates and zoom +will set the zoom level (and modifies pan) so that the given box of the +design is visible and as large as possible in the current window. +

+Arguments: +

+ + +
(no argument) + Without argments: zoom to board extents. + +
+factor + Values greater than 1.0 cause the board to be drawn smaller; more of + the board will be visible. Values between 0.0 and 1.0 cause the board + to be drawn bigger; less of the board will be visible. + +
-factor + Values greater than 1.0 cause the board to be drawn bigger; less of + the board will be visible. Values between 0.0 and 1.0 cause the board + to be drawn smaller; more of the board will be visible. + +
=factor + The @var{factor} is an absolute zoom factor; the unit for this value + is "PCB units per screen pixel". Since PCB units are nanometer, a + factor of 1000 means 1 micrometer per pixel (TODO: test this). + +
x1, y1, x2, y2 + Zoom to the specified portion of the design, described as a rectangle + (using board space coordinates) + +
selected + Zoom and pan so that all selected objects are on the screen. + +
found + Zoom and pan so that all found objects are on the screen. + +
? + Print the current zoom level in the message log (as an info line). + +
get + Return the zoom level as an FGW_DOUBLE (useful for scripts). + +
+

+Note that zoom factors of zero are silently ignored. + Index: tags/2.3.0/doc/user/09_appendix/attributes.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/attributes.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/attributes.html (revision 33253) @@ -0,0 +1,90 @@ + + + + pcb-rnd user manual - attributes recognized + + + + + +

attributes recognized

+

+Attributes are key-value pairs attached to objects. The format and content +of both keys and values are free form. Most of the time the meaning of +an attribute is defined by the user and the only code that process +the attribute are user scripts. +

+However, there are a few attributes recognized and parsed by pcb-rnd. This +document lists those attributes. + +

Object attribute summary

+ + +
attr key object + description +
term drawing primitives, subcircuit + terminal ID +
intconn terminals (drawing primitives, subcircuit with the term attribute set) + internal connection +
intnoconn copper objects (drawing primitives) + break internal connection +
noexport drawing primitives + do not export the object +
refdes subcircuit + reference designator; the unique name of the subcircuit instance (also used in the netlist) +
extobj subcircuit + names the extended object implementation that handles the subcircuit +
init-invis layer group + the layer group should be inivisible after loading the board +
+ + + +

Object attribute details

+ +

term

+

+Terminal ID is the unique identifier of a terminal (pin, pad, lead of a part). +Together with the subcircuit's refdes, the terminal ID is used to identify the +terminal on the netlist. Very often matches the datasheet's pin number. + +

intconn

+

+Value is a small positive integer. Terminals within the same subc sharing the +same intconn value are connected within the package, even if terminal IDs differ. +The connection is invisible/implied. Used to indicate in-package connections +(e.g. zero ohm resistor used for an extra layer). + + +

intnoconn

+

+Value is a small positive integer. Copper objects within the same subc sharing the +same intnoconn value are assumed to have no connection with each other even if +they overlap by geometry. Used to break unwanted connection in a subcircuit, +e.g. to avoid shorts in a 2 terminal antenna or coil footprint. + +

noexport

+

+A drawing primitive that has the noexport attribute (with any value) is marked +on the screen with an overlay X mark and is not exported to any of the +graphical exports. A noexport:exportername attribute will inhibit +the object only from the named exporter (e.g. noexport:png will make +the object disappear from the png export but not from any other exports). +Multiple noexport:exportername can be used. +

+Some side effects of the object will not disappear: +

    +
  • clearance in nearby polygons are preserved +
  • the object contributes in bounding box calculation +
+

+The noexport attribute on padstacks will inhibit all shapes (including the slot) +and the hole too. +

+Graphical exports are those that use the central draw mechanism for getting +the drawing primitives generated. Some exporters, typically the ones that +export data (and not drawing) will not call the draw API and thus will ignore +the noexport attribute. + + + Index: tags/2.3.0/doc/user/09_appendix/bridges.svg =================================================================== --- tags/2.3.0/doc/user/09_appendix/bridges.svg (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/bridges.svg (revision 33253) @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + pcb-rnd + + output-only + + input-output + + HID (GUI) + + input-only + + tEDAx(exchange file format) + + gtkgdk or gl render + + kicadpcbnew + + web client(javascript) + + batchCLI/automation + + lesstif(motif) + + remote(network) + + gEDApcb + + freerouting.netautorouter + + TinyCAD + + Calay + + mucs PCBautorouter + + XSCHEM + + (any)IPC-D-356 + + (any)EDIF + + LTSpice + + Lepton EDAgschem + + EasyEDA(web2.0) + + kicadeeschema + + (any)netlist + + dsn(autorouting) + + c-pcb(autorouting) + + HPGL(2D CAD) + + FreePCB(netlist) + + Accel EDA(netlist) + + hkp(mentor) + + Protel(netlist) + + Mentor grp.(netlist) + + Orcad(netlist) + + PADS ASCII(netlist) + + gEDAgschem + + Mentorhyperlynx + + Eagle(board) + + FidoCadJ(board) + + ProtelAutotrax + + gerber + + svg + + STL(3d) + + dxf(2D CAD) + + excellon(drill) + + XYtemplated + + openscad(3D CAD) + + OpenEMS(sim) + + lpr(print) + + ipcd356e-tester + + pngjpg, bmp + + pspostscript + + BOM + + g-code(mill) + + statstatistics + + importschematics + + + text + + + importnetlist + + importlines/arcs + + + .xy + + + importschematics + + importPCB + + + IPC356D + + + + .grb, .cnc + + + importschematics + + importschematics + + + + stl + + + + board + + + + importschematics + + importnetlist + + importschematics + + + footprint + + + + lihata + + + + + ps + + + + schematics + + + + + boards-expr + + + + postscript + + + + + board + + + + netlist + + + importschematics + + + + boardlegacy + + + importnetlist + + + svg + + + + DRCspec + + + + footprint + + + importschematics + + + footprints-expr + + + importschematics + + + board + + + netlistpads/subcs + + + board + + + + etest + + + importschematics + + + board + + + + board + + + importschematics + + + board + + + importnetlist + + + board + + + + + DRU + + + importschematics + + + + + TCP/IP + + + + Index: tags/2.3.0/doc/user/09_appendix/combined_glossary.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/combined_glossary.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/combined_glossary.html (revision 33253) @@ -0,0 +1,281 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd User Manual: Appendix

+ +

9.6 Glossary

+ +

Useful terminology for a common vernacular

+This glossary is under construction. It currently combines terms that focus +pertain to any of the following facet subjects. +
    +
  1. pcb-rnd specific terminology
  2. +
  3. pcb manufacturer terminology
  4. +
  5. pcb CAD layout and design terminology
  6. +
  7. CAD/graphics common design terminology
  8. +
+We will fill in definitions, continue to add terms, and determine an +appropriatly faceted method to index the terms. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Combined Glossary Table +
termdescriptionfacets +
5/5 5mil minimum traces & 5mil minimum spacing
6/5 6mil minimum traces & 5mil minimum spacing
AMC aluminum metal core
ACY
additive
Adhesive
Altium
Annular Ring
Annulus
AOI automatic optical inspection
Aperture
Arc
Array
assembly
AutoCAD
autorouter
Autotrax
Autotrax
AXI automated x-ray inspection
Axial
Bakelite
BGA
Blind Via
bloat
board house
Board Thickness
Breadboard
buffer
Buried Via
bus
C4 Controlled collapse chip connection
CAD
CAM files
CAM
Capture
Card Edge connector
Castellations
CEM-1
CEM-3
Centroid
centroid
Chip Scale Package
clad
Clearance
Coating (Spin, Roll, Film)
COB
Component Side
Component
Computer Aided Design
Computer Aided Machining
Conformal Coating
Conformal coating
connect
Copper Foil
Copper weight
Copper
copper
courtyard
cte coefficient of thermal expansion (see tce)
Curve, open
delamination
DFSM Dry film soldermask
Dialectric
Diameter
Dielectric
differential pair
DIP
Discrete Component
double-sided
DRC design rule check
Drill file
Eagle
EDF
EDI Electronic Data Interchange
Endpoint
ENIG Electroless Nickel Immersion Gold
epoxy resin
ESD Electrostatic Discharge
Etching
Excellon
explicit layer
fabrication fab
Feedthrough Via
fidocad
Fiducial
Finger
Finite Element Filter
Fixture
flags
Flex
Flip chip
flood fill
Flux
Flying probe
Foil
font
Footprint
FR-1
FR-2
FR-3
FR-4
Gcode
gEDA
Gerber
grid snap
grid-pitch
grid
Hard Gold pcb surface finish (slip rings, fingers, etc)
HASL Hot Air surface levelling
High Density Interconnect(HDI)
Hole
Immersion Silver
Immersion Tin
implicit layer
Integrated Circuit
IPC (circa 1957)
JIT
Kapton
KiCAD
Knife
Laminate
Land
Laser
Layer Group
Layer Sequence
Layers (Physical)
Layers (Virtual)
Library
Lihata
mask
Masonite
Mentor
Mil
Milling
milling
Mirroring
Mouse bites
Multilayer
neckdown
negative process
Negative transfer
NEMA
Net
Netlist
ODB++
OrCAD
OSP Organic Solderability preservative
outline
Package
Pad
padstack
Panel Service
panel
Panelization
paste stencil
paste
Path
pcb-rnd
PCB
PDIP
phenolic resin
Photoengraving
Photoresist
pick and place pnp
Pin
pinout
pitch
PLCC plastic lead chip carrier
plotter
Polygon hole
Polygon, complex
Polygon, concave
Polygon, convex
Polygon, irregular
Polygon, regular
Polygon, simple
Polygon
polygon
positive process
Positive transfer
Protel
PTH
Pyralux AP
Pyralux FR
Pyralux LF
QFP
Radial Lead
Raster
rat
Ratsnest
refdes Reference Designator, https://en.wikipedia.org/wiki/Reference_designator
reflow
Registration
resin
resist
RF
Rigid-Flex
Route and Retain
routing style
Routing
routing
RS-274D
RS-274X
Rubylithe
Scoring
Short
Silk Screen
Silk
silk
single-sided
SIP
slot
SMD
SMOBC soldermask over bare copper
prevent unintended flow of tin/lead during reflow
SMT
Snap
SOIC
Solder Side
Solder
STEP
Subcircuit
Substrate
Subtractive
Symbol
Tape out
TCE thermal coefficient of expansion
tEDAx
Tented(Via)
terminal
TG Glass transition temp
Thermal Via Thermal relief
Thou
Tin Whisker
Tin
TinyCAD
Tolerance
tombstone
tooling
toolpath generator
toolpath
toporouter
Trace
TT toner transfer
V-Cut
aka v-scoring
V-score
Vcc
Vdd
Vector
Via stitching
Via
Wave Solder
Wire bonding
XY
Index: tags/2.3.0/doc/user/09_appendix/dialogs.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/dialogs.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/dialogs.html (revision 33253) @@ -0,0 +1,27 @@ + + + + + pcb-rnd - list of file formats + + + + + +

pcb-rnd User Manual: Appendix

+

+

List of GUI dialog boxes

+ + +
ID + dialog box name + action + source + comments + +
view*view*n/asrc_plugins/dialogs/dlg_view.c  + +
+ + + Index: tags/2.3.0/doc/user/09_appendix/external_resources.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/external_resources.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/external_resources.html (revision 33253) @@ -0,0 +1,30 @@ + + + + pcb-rnd user manual + + + + +

+

pcb-rnd User Manual: Appendix

+ +

External Resources

+

9.2.1 pcb-rnd community Resources

+
    +
  1. repo.hu is the pcb-rnd +maintainer's SVN based project hosting site +
  2. Contributer erichVK5's blog, +(including many posts directly and indirectly relevant to pcb-rnd) +
  3. Contributer erichVK5's github repository +
+ +

9.2.2 resources on building and contributing to pcb-rnd

+
    +
  1. contribution guidelines for pcb-rnd +
  2. live chat with the pcb-rnd user community +
  3. StackOverflow discussion on using svn +
+ + + Index: tags/2.3.0/doc/user/09_appendix/formats.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/formats.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/formats.html (revision 33253) @@ -0,0 +1,454 @@ + + + + + pcb-rnd - list of file formats + + + + + +

pcb-rnd User Manual: Appendix

+

+

File format support

+ + + +
plugin native state reads formats writes formats + +
io_lihata +yes +works + + lihata pcb-rnd board (any version) +
+ lihata pcb-rnd footprint (any version) +
+ lihata pcb-rnd font (any version) +
+ lihata pcb-rnd board (any version) +
+ lihata pcb-rnd footprint (any version) +
+ lihata pcb-rnd font (any version) +
io_autotrax +no +works + + autotrax PCB board, version 4 +
+ autotrax PCB board, version 5 +
+ autotrax PCB board, version 4 +
io_bxl +no +WIP + + BXL footprints + +n/a +
io_dsn +no +works + + dsn board + + dsn board +
io_eagle +no +works + + eagle xml board version 6, 7, 8 +
+ eagle xml footprint lib +
+ eagle binary board version 3, 4, 5 +
+ eagle binary footprint lib +
+ eagle DRU (design rules) +
+n/a +
io_hyp +no +works + + hyperlynx board, version 2 and above + + hyperlynx board, version 2.0 +
io_kicad +no +works + + kicad board, version 3, 4 and 5 (s-expr) +
+ eeschema netlist and footprint info +
+ kicad board, version 3 (s-expr) +
+ kicad module (s-expr, according to version 3) +
io_kicad_legacy +no +works + +n/a + + kicad pcbnew-board, version 1 (legacy plain text format) +
+ kicad pcbnew-module (legacy plain text format) +
io_mentor_cell +no +WIP + + Mentor Graphics cell footprints + +n/a +
io_pcb +no +works + + gEDA/PCB .pcb board (any version up to 2017) +
+ gEDA/PCB .fp footprints +
+ gEDA/PCB font +
+ gEDA/PCB .pcb board (various version up to 2017 ) +
+ gEDA/PCB .fp footprints +
io_tedax +no +works + + tEDAx netlist (any version) +
+ tEDAx footprint (any version) +
+ tEDAx drc +
+ tEDAx pcb-rnd drc script +
+ tEDAx netlist (any version) +
+ tEDAx footprint (any version) +
+ tEDAx etest +
+ tEDAx drc +
+ tEDAx pcb-rnd drc script +
import_accel_net +no +works + + Accel ASCII netlists + footprint info + +n/a +
import_calay +no +works + + calay (netlists + footprint info) + +n/a +
import_dsn +no +works + + specctra .dsn (wires and vias) + +n/a +
import_edif +no +works + + flat netlist from EDIF + +n/a +
import_fpcb_nl +no +works + + freepcb netlist + footprint info + +n/a +
import_gnetlist +no +works + + gEDA/gschem (netlist + footpritn info, running gnetlist) + +n/a +
import_hpgl +no +works + + HPGL plot (lines, arcs, polygons) + +n/a +
import_ipcd356 +no +works + +n/a + + IPC-D-356 Netlist (from automated testing) +
import_ltspice +no +works + + import ltspice .net and .asc (netlist and footprint info) + +n/a +
import_mentor_sch +no +works + + flat .edf (netlist+footprint, produced by Mentor Graphics Design Capture) + +n/a +
import_mucs +no +works + + MUCS unixplot .pl (lines and vias) + +n/a +
import_net_action +no +works + + pcb-rnd action script (netlist + footprint info) + +n/a +
import_net_cmd +no +works + + schematics import by running a commandline +
+ netlist import by running a commandline +
+n/a +
import_netlist +no +works + + gEDA netlist (plain text, no footprint info) + +n/a +
import_orcad_net +no +works + + Orcad PCB II (netlist + footprint info) + +n/a +
import_pads_net +no +works + + PADS ascii (.asc, netlists + footprint info) + +n/a +
import_protel_net +no +works + + Protel netlists 2.0 + footprint info + +n/a +
import_pxm_gd +no +works + + pixmap (e.g. png) + +n/a +
import_pxm_pnm +no +works + + pnm (pixmap) + +n/a +
import_sch2 +no +WIP + +n/a + +n/a +
import_tinycad +no +works + + tinycad .net (netlists + footprint info) + +n/a +
import_ttf +no +WIP + + ttf font + +n/a +
export_bom +no +works + +n/a + + bom (Bill of Materials, text) +
export_dsn +no +works + +n/a + + specctra .dsn (padstacks and subcircuits, works with freerouting.net) +
export_dxf +no +works + +n/a + + .dxf (2D drawing for mech CADs) +
export_excellon +no +works + +n/a + + excellon drill/cnc (for PCB fabbing) +
export_fidocadj +no +WIP + +n/a + + fidocad .fcd (partial export) +
export_gcode +no +WIP + +n/a + + export gcode (for milling) +
export_gerber +no +works + +n/a + + gerber for PCB fabbing +
export_ipcd356 +no +works + +n/a + + IPC-D-356 Netlist (for automated testing) +
export_lpr +no +works + +n/a + + printer (using ps) +
export_oldconn +no +works + +n/a + + list of terminal connections (old, custom format) +
export_openems +no +WIP + +n/a + + OpenEMS (simulation, matlab files) +
export_openscad +no +WIP + +n/a + + openscad script (colored 3D model) +
export_png +no +works + +n/a + + render in .png +
+ render in .gif +
+ render in .jpeg +
export_ps +no +works + +n/a + + render black&white postscript (single or multiple files) +
+ render black&white or color embedded postscript (single file) +
export_stat +no +works + +n/a + + anonimized board statistics in lihata +
export_stl +no +WIP + +n/a + + stl (3d triangulated surface model) +
export_svg +no +works + +n/a + + svg (Scalable Vector Graphics) +
export_vfs_fuse + +WIP + +n/a + +n/a +
export_vfs_mc + +WIP + +n/a + +n/a +
export_xy +no +works + +n/a + + geda/PCB xy +
+ gxyrs +
+ Macrofab's pick&place +
+ pick&place file for the TM220/TM240 device +
+ KiCad .pos file + +
+ + + Index: tags/2.3.0/doc/user/09_appendix/index.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/index.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/index.html (revision 33253) @@ -0,0 +1,41 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd User Manual: Appendix

+

+

9.0 Action reference

+Condensed list of actions. Handy to use if you aren't sure what action you are +looking for. +

+Actions contain links to the action details page below: + pcb-rnd detailed list of action +

+

+Use this if you want all the info about a specific action. +

9.1 List of formats

+

+ File format support in pcb-rnd +

+ + +
Bridges
to other software through file formats + +

9.2 External resources

+Useful resources for designing with +pcb-rnd +

9.4 Layers

+Layer color mechanism +Layer addressing syntax +

9.5 Dialog boxes

+ List of GUI dialog boxes +

9.6 Attributes

+ List of attributes recognized +

9.7 Glossary of terminology

+ Useful terminology for a common vernacular + + Index: tags/2.3.0/doc/user/09_appendix/layer_addr.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/layer_addr.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/layer_addr.html (revision 33253) @@ -0,0 +1,179 @@ + + + + pcb-rnd user manual + + + + +

Layer addressing

+

+When an action or configuration file requires a layer or +layer group to be specified, it is usually done using the layer +address or layer group address sytax specified below. +

+However, some old actions still require the raw id or name of +a layer or layer group; in that case, the addressing syntax will not work +and the required data has to be specified as is, without any prefix. + +

Layer group address

+

+The layer group address is used to name one or more matching layer group(s). +If the code needs only one layer group and the address matches multiple, +always the first match is used (the layer group with the lowest ID). +

+A layer group address contains at most two parts: the base address +and optional supplements. The full version is base(supplements), +but supplements can be omitted so base alone is also valid. +

+The base part is one of the following syntaxes: +

+ +
syntax + description + example +
@groupname + find groups by their user assigned name (case sensitive string match) + @mysignal
matches groups whose name is "mysignal" + +
location-material + find groups by their location and material + bottom-copper
matches groups that are on the bottom side and are of copper + +
type[-type...] + same as location-material: types can really be used in any amount and any order, but matching groups have to match all types specified + mask
matches any group that is a solder mask + +
type:offs + offs is a positive integer; use the Nth group of that type from top + copper:2
matches the second copper layer group from the top; offs is counted from 1, +1 meaning top surface layer + +
type:-offs + -offs is a negative integer; use the Nth group of that type from bottom + copper:-3
matches the third copper layer group from the bottom; offs is counted from 1, -1 meaning bottom surface layer + +
#group_id + index by the ID of the group; useful for scripting + #4
picks group 4, counting from 0 + +
+

+When supplements are specified, it's a comma separated list of key=value pairs. +Available supplements are: +

    +
  • purpose: specify matching layer group purpose field +
  • bloat: bloat or shrink objects by the specified value (e.g. 1mm), when transformations are available +
  • partial: only export objects with the EXPORTSEL flag set, when doing an export +
  • wireframe: draw layer with wireframe objects instead of solid objects +
  • thin_draw: draw layer with thin centerline objects instead of solid objects (implies thin_draw_poly) +
  • thin_draw_poly: draw layer with thin contour polygons instead of solid polygons +
  • check_planes: draw only (clipped) polygons +
  • flag_color: if the exporter supports colors, highlight objects that are found, selected or warned with screen color +
  • hide_floaters: omit rendering subcircuit floaters; warning: floaters are not only silk refdes text +
  • (TODO: supplement for inversion) +
+

+Supplement examples: + +
top-doc(purpose=assy) + the explicit top assembly layer group (by type) +
top-virtual(purpose=assy) + the autogenerated top assembly layer group (by type); this works only if there is no explicit assy layer (legacy designs) +
top-paste(bloat=0.1mm) + when using the address in CAM, export the top paste group with all objects bloated up by 0.1mm +
virtual(purpose=pdrill) + for example in CAM: export plated drilled holes (padstack side effects, but no slots) +
virtual(purpose=pdrill,bloat=0.1mm) + the above two combined +
+ +

Layer address

+

+The layer address is used to name one or more matching layer(s). +If the code needs only one layer and the address matches multiple, +always the first match is used (the layer with the lowest ID). +Note: layers are not indexed in physical stack order. +

+There are two kind of layer addresses: direct and through-group. +

+The direct address has only two variants: + +
syntax + description + example + +
#idx + layer index (the internal, unique numbering, from 0) + #0
matches the first layer; useful only if the layer index was resolved earlier + +
@name + layer name - case sensitive match of user assigned layer name + @mysignal
matches layers with name "mysignal" + +
¤t + the currently selected layer + ¤t +
+

+The through grup address has a group address, a slash and a local +layer address. Counts are always from 1 (first layer within the +group is count 1). It is one of: + + +
syntax + description + example + +
group/#count + layer index within the group + top-copper/#2
matches the second layer in the top copper group + +
group/#-count + layer index within the group + top-copper/#-1
matches the last layer in the top copper group + +
group/#count+ + layer index within the group, considering only positive layers + top-silk/#2
matches the second positive layer in the top silk group + +
group/#-count+ + layer index within the group counted back from the last, considering only positive layers + top-silk/#-1+
matches the last positive layer in the top silk group + +
group/#count- + layer index within the group, considering only negative (sub) layers + top-silk/#2-
matches the second negative (sub) layer in the top silk group + +
group/#-count- + layer index within the group counted back from the last, considering only negative (sub) layers + top-silk/#-1-
matches the last negative (sub) layer in the top silk group + +
group/@name + user assigned layer name matches name (only the group's layers are considered) + top-copper/@gnd
matches the layer called "gnd" within the top copper group +
+

+Note: the full group addressing syntax can be used, so +

+top-doc(purpose=assy)/#-1
+
+

+works and means "fetch the first top documentation layer group whose purpose is +assy and pick the last layer in that group". + +

Best practices

+

+Avoid addressing by user assigned name (the @ syntax): that scheme is +fragile and unique names are not guaranteed. +

+When addressing a layer for the first time, it is best to use the +group-type/#count syntax (e.g. top-copper/1 fir the first layer of the +top copper group). +

+If a lot of accesses to the same layer is required (and the layer stack +is not changed during the operation) the best strategy is to resolve the +layer once , using e.g. the group-type/#count, then remember its layer id +and use the faster #id addressing for subsequent access. + + + Index: tags/2.3.0/doc/user/09_appendix/layer_colors.html =================================================================== --- tags/2.3.0/doc/user/09_appendix/layer_colors.html (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/layer_colors.html (revision 33253) @@ -0,0 +1,54 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd User Manual: Appendix

+

+

9.4 Layer colors

+

+Each layer has its own layer color. Starting with lihata board v5, the +layer color is saved to and loaded from board files. Layers retain their +color even when they are moved within or between layer groups. +

+In parallel to this mechanism, there is a set of default colors +defined in the conf subsystem: a set of default copper layer colors and +specific default colors for paste, mask and silk layers. +

+There are only two cases when the default colors from the config subsystem +are used: +

    +
  • +When a new layer is created or a layer without color specified is loaded +from a file or when a layer is loaded from a file format that does not +support per layer color, a default color is assigned from the config, +depending on the layer type. + +
  • +When an object needs to be displayed out of the board, e.g. in the footprint +preview window of the library dialog +
+

+Composite rendering: positive layers are always rendered using their own +layer color (e.g. it is possible to define two silk layers in the top silk +group with two different colors, and the silk drawing on screen will have +two colors). A negative layer's color is normally invisible, thus does not +matter, because objects of a negative layer are removing pixels, not drawing +them. +

+When a composite layer group is rendered with the first layer being negative +(typical for mask), the rendering code needs to apply a fill that covers +the whole board, so the negative layer objects can cut out from that fill. The +color of this fill is the color of the first layer. +

+Limitation: per board per layer custom color is supported by pcb-rnd but +is not supported by many of the other PCB editors and file formats. Thus +saving the board to an alien format (or to a lihata board version v4 or lower), +the layer color info is lost. There is no explicit warning is generated +about this. + + + Index: tags/2.3.0/doc/user/09_appendix/src/Makefile =================================================================== --- tags/2.3.0/doc/user/09_appendix/src/Makefile (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/src/Makefile (revision 33253) @@ -0,0 +1,24 @@ +# NOTE: aagraph is at svn://repo.hu/projects/aagraph/trunk + +PCBRND = ../../../../src/pcb-rnd +CLEANFILES=../action_details.html ../action_reference.html ../formats.html ../bridges.svg ../dialogs.html + +all: $(CLEANFILES) + +../action_details.html: ./action_compiler.sh ../action_src/*.html + ./action_compiler.sh ../action_src/*.html > ../action_details.html + +../action_reference.html : ./dump_actions_to_html.sh $(PCBRND) ../action_details.html + ./dump_actions_to_html.sh > ../action_reference.html + +../bridges.svg: bridges.txt + aagraph -Tsvg bridges.txt > ../bridges.svg + +../formats.html: gen_formats.sh ../../../../src_plugins/io_*/*.pup ../../../../src_plugins/import_*/*.pup ../../../../src_plugins/export_*/*.pup + ./gen_formats.sh > ../formats.html + +../dialogs.html: $(PCBRND) ./gen_dialogs.sh ./dialog_extra.awk + ./gen_dialogs.sh > ../dialogs.html + +clean: + rm $(CLEANFILES) Index: tags/2.3.0/doc/user/09_appendix/src/action_compiler.sh =================================================================== --- tags/2.3.0/doc/user/09_appendix/src/action_compiler.sh (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/src/action_compiler.sh (revision 33253) @@ -0,0 +1,162 @@ +#!/bin/sh + +SEP="<@@@@>" + +compile() +{ + awk -v "SEP=$SEP" ' + BEGIN { + q="\"" + SEP="^" SEP + } + + function strip(s) { + sub("^[ \t]*", "", s) + sub("[ \t]*$", "", s) + return s + } + + function read_tag(tag, tmp1,tmp2) { + getline tmp1 + getline tmp2 + if (tmp2 ~ " "/dev/stderr" + exit(1) + } + + function notav(s) { + if (s == "") return "n/a" + return s + } + + function end_act() + { + if (current != "") + print "" + currrent = "" + } + + ($0 ~ SEP) { + end_act() + action = "" + $1="" + current=tolower(strip($0)) + sub("^.*/", "", current) + sub(".html$", "", current) + + if (current in ANAME) + aname = ANAME[current] + else + aname = current + + print "" + print "

" aname "

" + print "
" + print "

" + print "" + print "
Syntax summary:" notav(SYNTAX[current]) + print "
Help text:" notav(HELP[current]) + print "
Registered by:" notav(COOKIE[current]) + print "
" + print "

" + next + } + + (current == "") && (/^A/) { + # reading the action list: new action + action=strip($0) + sub("^A", "", action) + aname= action + action = tolower(action) +# avoid saving duplicates at the main action node + if (action in SEEN) + action = action "_dup" + else + ANAME[action] = aname + SEEN[action] = 1 + next + } + + + (current == "") && (/^D/) { + # reading the action list: help line + tmp = $0 + sub("^D", "", tmp) + HELP[action]=HELP[action] "\n" tmp + next + } + + (current == "") && (/^S/) { + # reading the action list: syntax line + tmp = $0 + sub("^S", "", tmp) + SYNTAX[action]=SYNTAX[action] "\n" tmp + next + } + + (current == "") && (/^C/) { + # reading the action list: cookie line + tmp = $0 + sub("^C", "", tmp) + COOKIE[action]=COOKIE[action] "\n" tmp + next + } + + /^/ { + arg = read_tag("arg") + print "" arg "" + next + } + + /^/ { + ex = read_tag("example") + print "Example:", ex, "
" + next + } + + /^/ { + act = tolower(read_tag("act")) + print "" act "" + next + } + + { + print + } + + END { + end_act() + } + ' +} + +echo ' + + + + pcb-rnd user manual - action details + + + + +

pcb-rnd actions (details)

+' + +( + ( + cd ../../../../src + ./pcb-rnd --dump-actions 2>/dev/null + ) + for fn in "$@" + do + echo "" + echo "$SEP $fn" + tr "\n\r\t" " " < $fn | sed "s@<@\n<@g;s@>@>\n@g;" + done +) | compile + +echo ' + + +' Property changes on: tags/2.3.0/doc/user/09_appendix/src/action_compiler.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/user/09_appendix/src/bridges.txt =================================================================== --- tags/2.3.0/doc/user/09_appendix/src/bridges.txt (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/src/bridges.txt (revision 33253) @@ -0,0 +1,395 @@ + *io------------------------------------------------------------+ + |[kica ] [gpcb ] [hyp_] [gsch] [c_pcb] [dsn_ ] | + | [ tedax ] [ frt_ ] [fido] [prtl] [eagl] | + +--------------------------------------------------------------+ +*inp----+ *hid--------+ +|[eesc ]| *pcbrnd----------------------------------------------------------+ |[batch ] | +|[mucs ]| | | | | +|[lept ]| | | |[gtk ] | +|[ltsp ]| | | | | +|[tcad ]| | | |[lesstif] | +|[edif ]| | | | | +|[netl ]| | | |[remote] | +|[ipcd ]| | | | | +|[easy ]| | | | | +|[xsch ]| | | | | +|[caly ]| | | | | +|[hpgl ]| | | | | +|[hkp_ ]| | | | | +|[fpcb ]| | | | | +|[padsn]| | | | | +|[orcdn]| | | | | +|[accln]| | | | | +|[prtln]| | | | | +|[msch ]| +----------------------------------------------------------------+ +-----------+ ++-------+ + *out----------------------------------------------------------------+ + | [bom_] [xy__] [gerb] [opcd] [lpr_] [scad] [oems] | [web ] + | [stat] [ps__] [svg_] [png_] [stl_] [dxf_] [gcod] [exce] | + +-------------------------------------------------------------------+ +%% +OA +[] + shape box + + +[inp] + linecolor #cccccc + bgcolor #cccccc + textcolor #884433 + label input-only + valign top + +[io] + linecolor #cccccc + bgcolor #cccccc + textcolor #884433 + label input-output + valign top + +[out] + linecolor #cccccc + bgcolor #cccccc + textcolor #884433 + label output-only + valign bottom + +[hid] + linecolor #cccccc + bgcolor #cccccc + textcolor #884433 + label HID (GUI) + valign top + + +[pcbrnd] + label pcb-rnd + bgcolor #00ffff + + +[eesc] + label kicad\neeschema + +[mucs] + label mucs PCB\nautorouter + +[lept] + label Lepton EDA\ngschem + +[ltsp] + label LTSpice + +[tcad] + label TinyCAD + +[edif] + label (any)\nEDIF + +[netl] + label (any)\nnetlist + +[ipcd] + label (any)\nIPC-D-356 + +[hpgl] + label HPGL\n(2D CAD) + +[hkp_] + label hkp\n(mentor) + +[fpcb] + label FreePCB\n(netlist) + +[padsn] + label PADS ASCII\n(netlist) + +[orcdn] + label Orcad\n(netlist) + +[accln] + label Accel EDA\n(netlist) + +[prtln] + label Protel\n(netlist) + +[msch] + label Mentor grp.\n(netlist) + +[easy] + label EasyEDA\n(web2.0) + +[xsch] + label XSCHEM\n + +[caly] + label Calay\n + + +[hyp_] + label Mentor\nhyperlynx + +[gsch] + label gEDA\ngschem + +[kica] + label kicad\npcbnew + +[tedax] + label tEDAx\n(exchange file format) + +[gpcb] + label gEDA\npcb + +[frt_] + label freerouting.net\nautorouter + +[fido] + label FidoCadJ\n(board) + +[prtl] + label Protel\nAutotrax + +[eagl] + label Eagle\n(board) + +[c_pcb] + label c-pcb\n(autorouting) + +[dsn_] + label dsn\n(autorouting) + + + +[bom_] + label BOM + +[xy__] + label XY\ntemplated + +[gerb] + label gerber + +[opcd] + label ipcd356\ne-tester + +[stl_] + label STL\n(3d) + +[lpr_] + label lpr\n(print) + +[dxf_] + label dxf\n(2D CAD) + +[scad] + label openscad\n(3D CAD) + +[gcod] + label g-code\n(mill) + +[oems] + label OpenEMS\n(sim) + +[exce] + label excellon\n(drill) + +[stat] + label stat\nstatistics + +[ps__] + label ps\npostscript + +[svg_] + label svg + +[png_] + label png\njpg, bmp + + + + + +[batch] + label batch\nCLI/automation + +[gtk] + label gtk\ngdk or gl render + +[lesstif] + label lesstif\n(motif) + +[remote] + label remote\n(network) + +[web] + label web client\n(javascript) + linecolor #aaaaaa + textcolor #aaaaaa + + +-> pcbrnd bom_.n + label text + +-> pcbrnd xy__.n + label .xy + +-> pcbrnd gerb.n + label .grb, .cnc + +-> eesc.e pcbrnd + label import\nschematics + +-> pcbrnd opcd.n + label IPC356D + +-> pcbrnd stl_.n + label stl + +-> pcbrnd lpr_.n + label ps + +-> pcbrnd dxf_.n + +-> pcbrnd scad.n + +-> pcbrnd gcod.n + +-> pcbrnd oems.n + +-> pcbrnd exce.n + +-> pcbrnd stat.n + label lihata + +-> pcbrnd ps__.n + label postscript + +-> pcbrnd svg_.n + label svg + +-> pcbrnd png_.n + + + +-> mucs.e pcbrnd + label import\nnetlist + +-> lept.e pcbrnd + label import\nschematics + +-> ltsp.e pcbrnd + label import\nschematics + +-> tcad.e pcbrnd + label import\nschematics + +-> edif.e pcbrnd + label import\nschematics + +-> netl.e pcbrnd + label import\nnetlist + +-> ipcd.e pcbrnd + label netlist\npads/subcs + +-> easy.e pcbrnd + label import\nschematics + +-> xsch.e pcbrnd + label import\nschematics + +-> caly.e pcbrnd + label import\nschematics + +-> hpgl.e pcbrnd + label import\nlines/arcs + +-> hkp_.e pcbrnd + label import\nPCB + +-> fpcb.e pcbrnd + label import\nnetlist + +-> padsn.e pcbrnd + label import\nschematics + +-> orcdn.e pcbrnd + label import\nschematics + +-> accln.e pcbrnd + label import\nschematics + +-> prtln.e pcbrnd + label import\nschematics + +-> msch.e pcbrnd + label import\nnetlist + + + + +<-> hyp_.s pcbrnd + label board + +<-> gsch.s pcbrnd + label schematics + +<-> gpcb.s-0.2 pcbrnd + label board + +<-> gpcb.s+0.2 pcbrnd + label footprint + +<-> kica.s-0.3 pcbrnd + label board\ns-expr + +<- kica.s pcbrnd + label board\nlegacy + +<-> kica.s+0.3 pcbrnd + label footprint\ns-expr + +<-> tedax.s-0.35 pcbrnd + label netlist + +<-> tedax.s-0.1 pcbrnd + label footprint + +<-> tedax.s+0.1 pcbrnd + label etest + +<-> tedax.s+0.4 pcbrnd + label DRC\nspec + + +<-> frt_.s pcbrnd + label board + +<-> fido.s pcbrnd + label board + +<-> prtl.s pcbrnd + label board + +-> eagl.s-0.2 pcbrnd + label board + +-> eagl.s+0.2 pcbrnd + label DRU + +<-> c_pcb.s pcbrnd + label board + +<-> dsn_.s pcbrnd + label board + +<-> pcbrnd batch.w + +<-> pcbrnd gtk.w + +<-> pcbrnd lesstif.w + +<-> pcbrnd remote.w + +<-> remote.s web + label TCP/IP Index: tags/2.3.0/doc/user/09_appendix/src/dialog_extra.awk =================================================================== --- tags/2.3.0/doc/user/09_appendix/src/dialog_extra.awk (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/src/dialog_extra.awk (revision 33253) @@ -0,0 +1,35 @@ +# 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)" + ACTION["asm"] = "asm()" + ACTION["cam"] = "cam()"; COMMENT["cam"] = "does not yet work in lesstif" + ACTION["constraint"] = "constraint()" + ACTION["about"] = "about()"; COMMENT["about"] = "lesstif: needs to be resized to at least 600 pixels high" + ACTION["prompt_for"] = "n/a"; COMMENT["prompt_for"] = "not for use from actions (for internal HID use)" + ACTION["fallback_color_pick"] = "n/a"; COMMENT["fallback_color_pick"] = "not for use from actions (for internal HID use)" + ACTION["flags"] = "FlagEdit()" + ACTION["fontsel"] = "FontSel()" + ACTION["layer_binding"] = "LayerBinding()" + ACTION["pstk_lib"] = "PstkLib()"; COMMENT["pstk_lib"] = "does not yet work in lesstif" + ACTION["log"] = "log()" + ACTION["netlist"] = "NetlistDialog()"; COMMENT["NetlistDialog"] = "does not yet work in lesstif" + ACTION["padstack_shape"] = "n/a"; COMMENT["padstack_shape"] = "open from within the padstack dialog" + ACTION["padstack"] = "PadstackEdit()" + ACTION["pinout"] = "pinout()" + ACTION["plugins"] = "ManagePlugins()"; COMMENT["plugins"] = "read-only list at the moment" + ACTION["preferences"] = "preferences()"; COMMENT["preferences"] = "lesstif: some tabs are unusable" + ACTION["pref_lib_path"] = "n/a"; COMMENT["pref_lib_path"] = "open from within the preferences dialog" + ACTION["pref_lib_path_help"] = "n/a"; COMMENT["pref_lib_path_help"] = "open from within the preferences dialog" + ACTION["undo"] = "UndoDialog()" + ACTION["openems_excitation"] = "OpenEMSExcitation()" + ACTION["mesh"] = "mesh()" + ACTION["extedit"] = "extedit()" + ACTION["poly_hatch"] = "hatch(interactive)" + ACTION["propedit"] = "propedit()" + ACTION["report"] = "report()" + ACTION["live_script"] = "LiveScript()" + ACTION["scripts"] = "BrowseScript()" + ACTION["shape"] = "shape()" +} Index: tags/2.3.0/doc/user/09_appendix/src/dump_actions_to_html.sh =================================================================== --- tags/2.3.0/doc/user/09_appendix/src/dump_actions_to_html.sh (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/src/dump_actions_to_html.sh (revision 33253) @@ -0,0 +1,115 @@ +#!/bin/sh + +# collates the pcb-rnd action table into a html doc page + +asrc="../action_src" + +cd ../../../../src +pcb_rnd_ver=`./pcb-rnd --version` +pcb_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 + +echo " + + + pcb-rnd user manual + + + + +

+

pcb-rnd User Manual: Appendix

+

+

Action Reference

+" +echo "" a "" "" "" "" + } + + a="" + s="" + d="" + c="" +} + + +/^A/ { + flush_sd() + sub("^A", "", $0) + a = a "
" $0 + next +} + +/^D/ { + sub("^D", "", $0) + d = d "
" $0 + next +} + +/^S/ { + sub("^S", "", $0) + s = s "
" $0 + next +} + +/^C/ { + sub("^C", "", $0) + c = c "
" $0 + next +} + +' | sort -fu | awk -v "asrc=$asrc" ' +# insert links around actions where applicable + BEGIN { + q = "\"" + } + // { + pre = $0 + sub(".*", "", pre) + post = $0 + sub(".*", "", post) + act = $0 + sub(".*", "", act) + sub(".*", "", act) + loact = tolower(act) + fn = asrc "/" loact ".html" + if ((getline < fn) == 1) + print pre "" post + else + print pre "" post + close(fn) + next + } + + { print $0 } + + END { + print "
\n" "" +echo $pcb_rnd_ver ", " $pcb_rnd_rev +echo "" +echo "
Action Description Syntax Plugin" +( + cd ../../../../src + ./pcb-rnd --dump-actions 2>/dev/null +) | awk ' + +function flush_sd() +{ + if ( a != "" || s != "" || d != "" ) { + sub("^
", "", a) + sub("^
", "", d) + sub("^
", "", s) + sub("^
", "", c) + print "
" d "" s "" c "" act "" act "
" + print "" + print "" + } +' Property changes on: tags/2.3.0/doc/user/09_appendix/src/dump_actions_to_html.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/user/09_appendix/src/gen_dialogs.sh =================================================================== --- tags/2.3.0/doc/user/09_appendix/src/gen_dialogs.sh (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/src/gen_dialogs.sh (revision 33253) @@ -0,0 +1,95 @@ +#!/bin/sh + +trunk=../../../.. + +# 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"] = "" +} + +END { + out("view*", "view*", "src_plugins/dialogs/dlg_view.c") +} +' + +echo ' + + + + pcb-rnd - list of file formats + + + + + +

pcb-rnd User Manual: Appendix

+

+

List of GUI dialog boxes

+ + +
ID + dialog box name + action + source + comments +' + +$trunk/util/devhelpers/list_dialogs.sh | awk -F "[\t]" ' +function orna(s) +{ + if ((s == "") || (s == "")) return "n/a" + return s +} + +'"$dlgtbl"' +'"`cat dialog_extra.awk`"' + +function out(id, name, src, action, comment ,acturl1,acturl2,fn,tmp) { + if (action == "") { + if (id in ACTION) action = ACTION[id] + else if (src in ACTION) action = ACTION[src] + } + + if (action != "") { + acturl1 = action + sub("[(].*", "", acturl1) + fn = "../action_src/" acturl1 ".html" + if ((getline tmp < fn) == 1) { + acturl1 = "" + acturl2 = "" + } + else { + acturl1 = "" + acturl2 = "" + } + close(fn) + } + + if (comment == "") { + if (id in COMMENT) comment = COMMENT[id] + else if (src in COMMENT) comment = COMMENT[src] + else comment = " " + } + + print "
" orna(id) "" orna(name) "" acturl1 orna(action) acturl2 "" src "" comment +} + +{ + id=$1 + name=$2 + src=$3 + if ((src in IGNORE) && ((name ~ IGNORE[src]) || (id ~ IGNORE[src]))) + next + out(id, name, src) +} +' + +echo ' +
+ + +' Property changes on: tags/2.3.0/doc/user/09_appendix/src/gen_dialogs.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/user/09_appendix/src/gen_formats.sh =================================================================== --- tags/2.3.0/doc/user/09_appendix/src/gen_formats.sh (nonexistent) +++ tags/2.3.0/doc/user/09_appendix/src/gen_formats.sh (revision 33253) @@ -0,0 +1,104 @@ +#!/bin/sh + +PLUGINS=../../../../src_plugins + +echo ' + + + + pcb-rnd - list of file formats + + + + + +

pcb-rnd User Manual: Appendix

+

+

File format support

+ + + +
plugin native state reads formats writes formats +' + +files_io=`ls $PLUGINS/io_*/*.pup | sort` +files_e=`ls $PLUGINS/export_*/*.pup | sort` +files_i=`ls $PLUGINS/import_*/*.pup | sort` + +for n in $files_io $files_i $files_e +do + bn=`basename $n` + bn=${bn%%.pup} + sed ' + /^[$]fmt[-]/ { s@^@'$bn' @; p } + /^[$]state/ { s@^@'$bn' @; p } + { d } + ' $n +done | awk ' + BEGIN { + plgs = 0 + } + { + if ($1 != last) { + PLG[plgs] = $1 + last = $1 + plgs++ + } + p=$1 + f=$2 + text=$0 + sub("^[^ \t]+[ \t]+[^ \t]+[ \t]+", "", text) + DATA[p, f] = DATA[p, f] SUBSEP text + } + + function col(mask ,n,v,i,A) { + print " " + v = split(DATA[mask], A, "[" SUBSEP "]") + if (v == 0) { + print "n/a" + return + } + i = 0; + for(n = 1; n <= v; n++) { + if (A[n] == "") + continue; + if (i) + print "
" + print " " A[n] + i++ + } + } + + function strip(s) + { + gsub("[" SUBSEP "]", " ", s) + sub("^[ \t]*", "", s) + sub("[ \t]*$", "", s) + return s + } + + function row(plg) { + print "
" plg + print "" strip(DATA[plg, "$fmt-native"]) + print "" strip(DATA[plg, "$state"]) + col(plg SUBSEP "$fmt-feature-r") + col(plg SUBSEP "$fmt-feature-w") + } + + END { + for(p=0; p < plgs; p++) + if (DATA[PLG[p], "$fmt-native"] ~ "yes") + row(PLG[p]) + + for(p=0; p < plgs; p++) + if (!(DATA[PLG[p], "$fmt-native"] ~ "yes")) + row(PLG[p]) + } +' + + +echo ' +
+ + +' Property changes on: tags/2.3.0/doc/user/09_appendix/src/gen_formats.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/user/Makefile =================================================================== --- tags/2.3.0/doc/user/Makefile (nonexistent) +++ tags/2.3.0/doc/user/Makefile (revision 33253) @@ -0,0 +1,67 @@ +ROOT=../.. +BUILD=$(ROOT)/util/build_ps.sh +USERDIR=$(DOCDIR)/user + +INSTD = 02_model 03_data 04_invoc 05_ui 06_feature 07_io \ + 08_util 09_appendix + +all: pdf + +include $(ROOT)/Makefile.conf + +pdf: user1.pdf user2.pdf user3.pdf + +ps_logo.png: ../resources/logo32.png + cp ../resources/logo32.png ps_logo.png + +ps_header.png: ../resources/header_600.png + cp ../resources/header_600.png ps_header.png + +user1.ps: ps1.lst $(BUILD) default.css Makefile ps_logo.png ps_header.png + HTML2PS_OPTS="-f default.css --toc h" HTML2PS_SED="s^%%%volume%%%^Volume 1: Core functionality^;s^%%%ver%%%^Version $(PCB_RND_VER)^g" $(BUILD) `cat ps1.lst` > user1.ps + +user2.ps: ps2.lst $(BUILD) default.css Makefile ps_logo.png ps_header.png + HTML2PS_OPTS="-f default.css --toc h" HTML2PS_SED="s^%%%volume%%%^Volume 2: Plugins and utilities^;s^%%%ver%%%^Version $(PCB_RND_VER)^g" $(BUILD) `cat ps2.lst` > user2.ps + +user3.ps: ps3.lst $(BUILD) default.css Makefile ps_logo.png ps_header.png + HTML2PS_OPTS="-f default.css --toc h" HTML2PS_SED="s^%%%volume%%%^Volume 3: Appendix and misc^;s^%%%ver%%%^Version $(PCB_RND_VER)^g" $(BUILD) `cat ps3.lst` > user3.ps + +user1.pdf: user1.ps + ps2pdf user1.ps + +user2.pdf: user2.ps + ps2pdf user2.ps + +user3.pdf: user3.ps + ps2pdf user3.ps + +ps.lst.vols: */*.html */*.png ./listlnk Makefile + ./listlnk list -v | grep -v "^index.html \|[.]png \|[.]svg \|[.]pcb\| [.]lht\|keytree.txt" > ps.lst.vols + +ps1.lst: */*.html */*.png ps.lst.vols + echo "ps_title.html" > ps1.lst + awk -F " " '($$2 == 1) {print $$1}' < ps.lst.vols >> ps1.lst + +ps2.lst: */*.html */*.png ps.lst.vols + echo "ps_title.html" > ps2.lst + awk -F " " '($$2 == 2) {print $$1}' < ps.lst.vols >> ps2.lst + +ps3.lst: */*.html */*.png ps.lst.vols + echo "ps_title.html" > ps3.lst + awk -F " " '($$2 == 3) {print $$1}' < ps.lst.vols >> ps3.lst + +include Makefile.inst + +regen: instgen + ./instgen + +install: + $(MAKE) install_all HOW="install -f" + +linstall: + $(MAKE) install_all HOW="install -f -l --absolute " + +uninstall: + $(MAKE) install_all HOW="install -u" + +include $(ROOT)/Makefile.conf Index: tags/2.3.0/doc/user/Makefile.inst =================================================================== --- tags/2.3.0/doc/user/Makefile.inst (nonexistent) +++ tags/2.3.0/doc/user/Makefile.inst (revision 33253) @@ -0,0 +1,370 @@ +### autogenerated, DO NOT EDIT (but do commit); run make regen on *NIX ### +install_all: + $(SCCBOX) mkdir -p $(USERDIR)/01_intro + $(SCCBOX) $(HOW) 01_intro/Makefile $(USERDIR)/01_intro/Makefile + $(SCCBOX) $(HOW) 01_intro/flow.svg $(USERDIR)/01_intro/flow.svg + $(SCCBOX) $(HOW) 01_intro/history.html $(USERDIR)/01_intro/history.html + $(SCCBOX) $(HOW) 01_intro/index.html $(USERDIR)/01_intro/index.html + $(SCCBOX) $(HOW) 01_intro/intro.html $(USERDIR)/01_intro/intro.html + $(SCCBOX) mkdir -p $(USERDIR)/02_model + $(SCCBOX) $(HOW) 02_model/index.html $(USERDIR)/02_model/index.html + $(SCCBOX) $(HOW) 02_model/obj_arc.png $(USERDIR)/02_model/obj_arc.png + $(SCCBOX) $(HOW) 02_model/obj_line.png $(USERDIR)/02_model/obj_line.png + $(SCCBOX) $(HOW) 02_model/objects_basic.png $(USERDIR)/02_model/objects_basic.png + $(SCCBOX) $(HOW) 02_model/objects_complex.png $(USERDIR)/02_model/objects_complex.png + $(SCCBOX) $(HOW) 02_model/via_therm_noconn.png $(USERDIR)/02_model/via_therm_noconn.png + $(SCCBOX) $(HOW) 02_model/via_therm_round_x45.png $(USERDIR)/02_model/via_therm_round_x45.png + $(SCCBOX) $(HOW) 02_model/via_therm_round_x90.png $(USERDIR)/02_model/via_therm_round_x90.png + $(SCCBOX) $(HOW) 02_model/via_therm_sharp_x45.png $(USERDIR)/02_model/via_therm_sharp_x45.png + $(SCCBOX) $(HOW) 02_model/via_therm_sharp_x90.png $(USERDIR)/02_model/via_therm_sharp_x90.png + $(SCCBOX) $(HOW) 02_model/via_therm_solid.png $(USERDIR)/02_model/via_therm_solid.png + $(SCCBOX) mkdir -p $(USERDIR)/03_data + $(SCCBOX) $(HOW) 03_data/index.html $(USERDIR)/03_data/index.html + $(SCCBOX) mkdir -p $(USERDIR)/04_invoc + $(SCCBOX) $(HOW) 04_invoc/index.html $(USERDIR)/04_invoc/index.html + $(SCCBOX) mkdir -p $(USERDIR)/05_ui/01_gtk + $(SCCBOX) $(HOW) 05_ui/01_gtk/base_window_highlight_coordsreadout.png $(USERDIR)/05_ui/01_gtk/base_window_highlight_coordsreadout.png + $(SCCBOX) $(HOW) 05_ui/01_gtk/base_window_highlight_layerops.png $(USERDIR)/05_ui/01_gtk/base_window_highlight_layerops.png + $(SCCBOX) $(HOW) 05_ui/01_gtk/base_window_highlight_main.png $(USERDIR)/05_ui/01_gtk/base_window_highlight_main.png + $(SCCBOX) $(HOW) 05_ui/01_gtk/base_window_highlight_menus.png $(USERDIR)/05_ui/01_gtk/base_window_highlight_menus.png + $(SCCBOX) $(HOW) 05_ui/01_gtk/base_window_highlight_opsreadout.png $(USERDIR)/05_ui/01_gtk/base_window_highlight_opsreadout.png + $(SCCBOX) $(HOW) 05_ui/01_gtk/base_window_highlight_routestyle.png $(USERDIR)/05_ui/01_gtk/base_window_highlight_routestyle.png + $(SCCBOX) $(HOW) 05_ui/01_gtk/base_window_highlight_workops.png $(USERDIR)/05_ui/01_gtk/base_window_highlight_workops.png + $(SCCBOX) $(HOW) 05_ui/01_gtk/index.html $(USERDIR)/05_ui/01_gtk/index.html + $(SCCBOX) mkdir -p $(USERDIR)/05_ui/03_batch + $(SCCBOX) $(HOW) 05_ui/03_batch/index.html $(USERDIR)/05_ui/03_batch/index.html + $(SCCBOX) mkdir -p $(USERDIR)/05_ui/04_common + $(SCCBOX) $(HOW) 05_ui/04_common/grid_menu.png $(USERDIR)/05_ui/04_common/grid_menu.png + $(SCCBOX) $(HOW) 05_ui/04_common/index.html $(USERDIR)/05_ui/04_common/index.html + $(SCCBOX) $(HOW) 05_ui/04_common/keytree.svg $(USERDIR)/05_ui/04_common/keytree.svg + $(SCCBOX) $(HOW) 05_ui/04_common/keytree.txt $(USERDIR)/05_ui/04_common/keytree.txt + $(SCCBOX) mkdir -p $(USERDIR)/05_ui/05_cli + $(SCCBOX) $(HOW) 05_ui/05_cli/index.html $(USERDIR)/05_ui/05_cli/index.html + $(SCCBOX) mkdir -p $(USERDIR)/05_ui + $(SCCBOX) $(HOW) 05_ui/index.html $(USERDIR)/05_ui/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/asm + $(SCCBOX) $(HOW) 06_feature/asm/index.html $(USERDIR)/06_feature/asm/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/autocrop + $(SCCBOX) $(HOW) 06_feature/autocrop/index.html $(USERDIR)/06_feature/autocrop/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/autoplace + $(SCCBOX) $(HOW) 06_feature/autoplace/index.html $(USERDIR)/06_feature/autoplace/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/autoroute + $(SCCBOX) $(HOW) 06_feature/autoroute/index.html $(USERDIR)/06_feature/autoroute/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/cam + $(SCCBOX) $(HOW) 06_feature/cam/index.html $(USERDIR)/06_feature/cam/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/ddraft + $(SCCBOX) $(HOW) 06_feature/ddraft/coord_seq.png $(USERDIR)/06_feature/ddraft/coord_seq.png + $(SCCBOX) $(HOW) 06_feature/ddraft/coord_sys.png $(USERDIR)/06_feature/ddraft/coord_sys.png + $(SCCBOX) $(HOW) 06_feature/ddraft/index.html $(USERDIR)/06_feature/ddraft/index.html + $(SCCBOX) $(HOW) 06_feature/ddraft/trim.png $(USERDIR)/06_feature/ddraft/trim.png + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/diag + $(SCCBOX) $(HOW) 06_feature/diag/index.html $(USERDIR)/06_feature/diag/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/distalign + $(SCCBOX) $(HOW) 06_feature/distalign/align_mixed_parts_x.png $(USERDIR)/06_feature/distalign/align_mixed_parts_x.png + $(SCCBOX) $(HOW) 06_feature/distalign/align_parts_y.png $(USERDIR)/06_feature/distalign/align_parts_y.png + $(SCCBOX) $(HOW) 06_feature/distalign/distalign.txt $(USERDIR)/06_feature/distalign/distalign.txt + $(SCCBOX) $(HOW) 06_feature/distalign/distribute_parts_x.png $(USERDIR)/06_feature/distalign/distribute_parts_x.png + $(SCCBOX) $(HOW) 06_feature/distalign/distribute_y_gaps.png $(USERDIR)/06_feature/distalign/distribute_y_gaps.png + $(SCCBOX) $(HOW) 06_feature/distalign/import_parts.png $(USERDIR)/06_feature/distalign/import_parts.png + $(SCCBOX) $(HOW) 06_feature/distalign/index.html $(USERDIR)/06_feature/distalign/index.html + $(SCCBOX) $(HOW) 06_feature/distalign/result.png $(USERDIR)/06_feature/distalign/result.png + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/djopt + $(SCCBOX) $(HOW) 06_feature/djopt/Makefile $(USERDIR)/06_feature/djopt/Makefile + $(SCCBOX) $(HOW) 06_feature/djopt/Post.html $(USERDIR)/06_feature/djopt/Post.html + $(SCCBOX) $(HOW) 06_feature/djopt/Pre.html $(USERDIR)/06_feature/djopt/Pre.html + $(SCCBOX) $(HOW) 06_feature/djopt/debumpify.out.pcb $(USERDIR)/06_feature/djopt/debumpify.out.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/debumpify.out.png $(USERDIR)/06_feature/djopt/debumpify.out.png + $(SCCBOX) $(HOW) 06_feature/djopt/debumpify.pcb $(USERDIR)/06_feature/djopt/debumpify.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/debumpify.png $(USERDIR)/06_feature/djopt/debumpify.png + $(SCCBOX) $(HOW) 06_feature/djopt/debumpify.txt $(USERDIR)/06_feature/djopt/debumpify.txt + $(SCCBOX) $(HOW) 06_feature/djopt/index.html $(USERDIR)/06_feature/djopt/index.html + $(SCCBOX) $(HOW) 06_feature/djopt/miter.out.pcb $(USERDIR)/06_feature/djopt/miter.out.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/miter.out.png $(USERDIR)/06_feature/djopt/miter.out.png + $(SCCBOX) $(HOW) 06_feature/djopt/miter.pcb $(USERDIR)/06_feature/djopt/miter.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/miter.png $(USERDIR)/06_feature/djopt/miter.png + $(SCCBOX) $(HOW) 06_feature/djopt/miter.txt $(USERDIR)/06_feature/djopt/miter.txt + $(SCCBOX) $(HOW) 06_feature/djopt/orthopull.out.pcb $(USERDIR)/06_feature/djopt/orthopull.out.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/orthopull.out.png $(USERDIR)/06_feature/djopt/orthopull.out.png + $(SCCBOX) $(HOW) 06_feature/djopt/orthopull.pcb $(USERDIR)/06_feature/djopt/orthopull.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/orthopull.png $(USERDIR)/06_feature/djopt/orthopull.png + $(SCCBOX) $(HOW) 06_feature/djopt/orthopull.txt $(USERDIR)/06_feature/djopt/orthopull.txt + $(SCCBOX) $(HOW) 06_feature/djopt/unjaggy.out.pcb $(USERDIR)/06_feature/djopt/unjaggy.out.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/unjaggy.out.png $(USERDIR)/06_feature/djopt/unjaggy.out.png + $(SCCBOX) $(HOW) 06_feature/djopt/unjaggy.pcb $(USERDIR)/06_feature/djopt/unjaggy.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/unjaggy.png $(USERDIR)/06_feature/djopt/unjaggy.png + $(SCCBOX) $(HOW) 06_feature/djopt/unjaggy.txt $(USERDIR)/06_feature/djopt/unjaggy.txt + $(SCCBOX) $(HOW) 06_feature/djopt/vianudge.out.pcb $(USERDIR)/06_feature/djopt/vianudge.out.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/vianudge.out.png $(USERDIR)/06_feature/djopt/vianudge.out.png + $(SCCBOX) $(HOW) 06_feature/djopt/vianudge.pcb $(USERDIR)/06_feature/djopt/vianudge.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/vianudge.png $(USERDIR)/06_feature/djopt/vianudge.png + $(SCCBOX) $(HOW) 06_feature/djopt/vianudge.txt $(USERDIR)/06_feature/djopt/vianudge.txt + $(SCCBOX) $(HOW) 06_feature/djopt/viatrim.out.pcb $(USERDIR)/06_feature/djopt/viatrim.out.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/viatrim.out.png $(USERDIR)/06_feature/djopt/viatrim.out.png + $(SCCBOX) $(HOW) 06_feature/djopt/viatrim.pcb $(USERDIR)/06_feature/djopt/viatrim.pcb + $(SCCBOX) $(HOW) 06_feature/djopt/viatrim.png $(USERDIR)/06_feature/djopt/viatrim.png + $(SCCBOX) $(HOW) 06_feature/djopt/viatrim.txt $(USERDIR)/06_feature/djopt/viatrim.txt + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/drc_query + $(SCCBOX) $(HOW) 06_feature/drc_query/index.html $(USERDIR)/06_feature/drc_query/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature + $(SCCBOX) $(HOW) 06_feature/index.html $(USERDIR)/06_feature/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/polystitch + $(SCCBOX) $(HOW) 06_feature/polystitch/index.html $(USERDIR)/06_feature/polystitch/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/query + $(SCCBOX) $(HOW) 06_feature/query/functions.html $(USERDIR)/06_feature/query/functions.html + $(SCCBOX) $(HOW) 06_feature/query/index.html $(USERDIR)/06_feature/query/index.html + $(SCCBOX) $(HOW) 06_feature/query/tutor_cli.html $(USERDIR)/06_feature/query/tutor_cli.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/scripting + $(SCCBOX) $(HOW) 06_feature/scripting/index.html $(USERDIR)/06_feature/scripting/index.html + $(SCCBOX) $(HOW) 06_feature/scripting/install.txt $(USERDIR)/06_feature/scripting/install.txt + $(SCCBOX) $(HOW) 06_feature/scripting/intro.html $(USERDIR)/06_feature/scripting/intro.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/scripting/rosetta/10_hello + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ID.desc $(USERDIR)/06_feature/scripting/rosetta/10_hello/ID.desc + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ID.name $(USERDIR)/06_feature/scripting/rosetta/10_hello/ID.name + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.awk $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.awk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.bas $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.bas + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.fawk $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.fawk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.fl $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.fl + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.html $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.html + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.js $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.js + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.lua $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.lua + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.pas $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.pas + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.pl $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.pl + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.py $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.py + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.rb $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.rb + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.sh $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.sh + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.stt $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.stt + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/ex.tcl $(USERDIR)/06_feature/scripting/rosetta/10_hello/ex.tcl + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/10_hello/index.html $(USERDIR)/06_feature/scripting/rosetta/10_hello/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/11_hello_menu/ID.desc $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu/ID.desc + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/11_hello_menu/ID.name $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu/ID.name + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/11_hello_menu/ex.awk $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu/ex.awk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/11_hello_menu/ex.bas $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu/ex.bas + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/11_hello_menu/ex.fawk $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu/ex.fawk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/11_hello_menu/ex.html $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu/ex.html + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/11_hello_menu/ex.lua $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu/ex.lua + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/11_hello_menu/ex.pas $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu/ex.pas + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/11_hello_menu/ex.py $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu/ex.py + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/11_hello_menu/ex.tcl $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu/ex.tcl + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/11_hello_menu/index.html $(USERDIR)/06_feature/scripting/rosetta/11_hello_menu/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/ID.desc $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/ID.desc + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/ID.name $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/ID.name + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/ex.awk $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/ex.awk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/ex.bas $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/ex.bas + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/ex.fawk $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/ex.fawk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/ex.html $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/ex.html + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/ex.lua $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/ex.lua + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/ex.pas $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/ex.pas + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/ex.pl $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/ex.pl + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/ex.py $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/ex.py + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/ex.tcl $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/ex.tcl + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/12_hello_dad/index.html $(USERDIR)/06_feature/scripting/rosetta/12_hello_dad/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/ID.desc $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/ID.desc + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/ID.name $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/ID.name + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/ex.awk $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/ex.awk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/ex.bas $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/ex.bas + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/ex.fawk $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/ex.fawk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/ex.html $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/ex.html + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/ex.lua $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/ex.lua + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/ex.pas $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/ex.pas + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/ex.pl $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/ex.pl + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/ex.py $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/ex.py + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/ex.tcl $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/ex.tcl + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/13_hello_dad/index.html $(USERDIR)/06_feature/scripting/rosetta/13_hello_dad/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/scripting/rosetta/21_timer + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/ID.desc $(USERDIR)/06_feature/scripting/rosetta/21_timer/ID.desc + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/ID.name $(USERDIR)/06_feature/scripting/rosetta/21_timer/ID.name + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/ex.awk $(USERDIR)/06_feature/scripting/rosetta/21_timer/ex.awk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/ex.bas $(USERDIR)/06_feature/scripting/rosetta/21_timer/ex.bas + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/ex.fawk $(USERDIR)/06_feature/scripting/rosetta/21_timer/ex.fawk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/ex.html $(USERDIR)/06_feature/scripting/rosetta/21_timer/ex.html + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/ex.lua $(USERDIR)/06_feature/scripting/rosetta/21_timer/ex.lua + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/ex.pas $(USERDIR)/06_feature/scripting/rosetta/21_timer/ex.pas + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/ex.pl $(USERDIR)/06_feature/scripting/rosetta/21_timer/ex.pl + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/ex.py $(USERDIR)/06_feature/scripting/rosetta/21_timer/ex.py + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/ex.tcl $(USERDIR)/06_feature/scripting/rosetta/21_timer/ex.tcl + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/21_timer/index.html $(USERDIR)/06_feature/scripting/rosetta/21_timer/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/scripting/rosetta/72_dad_unitconv + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/72_dad_unitconv/ID.desc $(USERDIR)/06_feature/scripting/rosetta/72_dad_unitconv/ID.desc + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/72_dad_unitconv/ID.name $(USERDIR)/06_feature/scripting/rosetta/72_dad_unitconv/ID.name + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/72_dad_unitconv/ex.awk $(USERDIR)/06_feature/scripting/rosetta/72_dad_unitconv/ex.awk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/72_dad_unitconv/ex.fawk $(USERDIR)/06_feature/scripting/rosetta/72_dad_unitconv/ex.fawk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/72_dad_unitconv/ex.html $(USERDIR)/06_feature/scripting/rosetta/72_dad_unitconv/ex.html + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/72_dad_unitconv/ex.lua $(USERDIR)/06_feature/scripting/rosetta/72_dad_unitconv/ex.lua + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/72_dad_unitconv/ex.tcl $(USERDIR)/06_feature/scripting/rosetta/72_dad_unitconv/ex.tcl + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/72_dad_unitconv/index.html $(USERDIR)/06_feature/scripting/rosetta/72_dad_unitconv/index.html + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/72_dad_unitconv/uconv.png $(USERDIR)/06_feature/scripting/rosetta/72_dad_unitconv/uconv.png + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/scripting/rosetta/81_persistency + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/81_persistency/ID.desc $(USERDIR)/06_feature/scripting/rosetta/81_persistency/ID.desc + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/81_persistency/ID.name $(USERDIR)/06_feature/scripting/rosetta/81_persistency/ID.name + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/81_persistency/ex.awk $(USERDIR)/06_feature/scripting/rosetta/81_persistency/ex.awk + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/81_persistency/ex.html $(USERDIR)/06_feature/scripting/rosetta/81_persistency/ex.html + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/81_persistency/ex.lua $(USERDIR)/06_feature/scripting/rosetta/81_persistency/ex.lua + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/81_persistency/index.html $(USERDIR)/06_feature/scripting/rosetta/81_persistency/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/scripting/rosetta + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/Makefile $(USERDIR)/06_feature/scripting/rosetta/Makefile + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/index.html $(USERDIR)/06_feature/scripting/rosetta/index.html + $(SCCBOX) $(HOW) 06_feature/scripting/rosetta/index.templ.html $(USERDIR)/06_feature/scripting/rosetta/index.templ.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/scripting/util + $(SCCBOX) $(HOW) 06_feature/scripting/util/Makefile $(USERDIR)/06_feature/scripting/util/Makefile + $(SCCBOX) $(HOW) 06_feature/scripting/util/rosetta_genpages.sh $(USERDIR)/06_feature/scripting/util/rosetta_genpages.sh + $(SCCBOX) $(HOW) 06_feature/scripting/util/tags $(USERDIR)/06_feature/scripting/util/tags + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/smartdisperse + $(SCCBOX) $(HOW) 06_feature/smartdisperse/index.html $(USERDIR)/06_feature/smartdisperse/index.html + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/stroke + $(SCCBOX) $(HOW) 06_feature/stroke/arrow.svg $(USERDIR)/06_feature/stroke/arrow.svg + $(SCCBOX) $(HOW) 06_feature/stroke/index.html $(USERDIR)/06_feature/stroke/index.html + $(SCCBOX) $(HOW) 06_feature/stroke/line.svg $(USERDIR)/06_feature/stroke/line.svg + $(SCCBOX) $(HOW) 06_feature/stroke/redo.svg $(USERDIR)/06_feature/stroke/redo.svg + $(SCCBOX) $(HOW) 06_feature/stroke/rotccw.svg $(USERDIR)/06_feature/stroke/rotccw.svg + $(SCCBOX) $(HOW) 06_feature/stroke/rotcw.svg $(USERDIR)/06_feature/stroke/rotcw.svg + $(SCCBOX) $(HOW) 06_feature/stroke/stopline.svg $(USERDIR)/06_feature/stroke/stopline.svg + $(SCCBOX) $(HOW) 06_feature/stroke/undo.svg $(USERDIR)/06_feature/stroke/undo.svg + $(SCCBOX) $(HOW) 06_feature/stroke/via.svg $(USERDIR)/06_feature/stroke/via.svg + $(SCCBOX) $(HOW) 06_feature/stroke/zoom_ext.svg $(USERDIR)/06_feature/stroke/zoom_ext.svg + $(SCCBOX) $(HOW) 06_feature/stroke/zoom_in.svg $(USERDIR)/06_feature/stroke/zoom_in.svg + $(SCCBOX) mkdir -p $(USERDIR)/06_feature/vendordrill + $(SCCBOX) $(HOW) 06_feature/vendordrill/index.html $(USERDIR)/06_feature/vendordrill/index.html + $(SCCBOX) mkdir -p $(USERDIR)/07_io/1_1_io_hkp + $(SCCBOX) $(HOW) 07_io/1_1_io_hkp/index.html $(USERDIR)/07_io/1_1_io_hkp/index.html + $(SCCBOX) mkdir -p $(USERDIR)/07_io/3_1_export_openscad + $(SCCBOX) $(HOW) 07_io/3_1_export_openscad/1206.scad $(USERDIR)/07_io/3_1_export_openscad/1206.scad + $(SCCBOX) $(HOW) 07_io/3_1_export_openscad/index.html $(USERDIR)/07_io/3_1_export_openscad/index.html + $(SCCBOX) mkdir -p $(USERDIR)/07_io/3_2_export_xy + $(SCCBOX) $(HOW) 07_io/3_2_export_xy/index.html $(USERDIR)/07_io/3_2_export_xy/index.html + $(SCCBOX) mkdir -p $(USERDIR)/07_io + $(SCCBOX) $(HOW) 07_io/index.html $(USERDIR)/07_io/index.html + $(SCCBOX) mkdir -p $(USERDIR)/08_util + $(SCCBOX) $(HOW) 08_util/01_gsch2pcb-rnd.html $(USERDIR)/08_util/01_gsch2pcb-rnd.html + $(SCCBOX) $(HOW) 08_util/02_cgi.html $(USERDIR)/08_util/02_cgi.html + $(SCCBOX) $(HOW) 08_util/index.html $(USERDIR)/08_util/index.html + $(SCCBOX) mkdir -p $(USERDIR)/09_appendix + $(SCCBOX) $(HOW) 09_appendix/action_details.html $(USERDIR)/09_appendix/action_details.html + $(SCCBOX) $(HOW) 09_appendix/action_reference.html $(USERDIR)/09_appendix/action_reference.html + $(SCCBOX) mkdir -p $(USERDIR)/09_appendix/action_src + $(SCCBOX) $(HOW) 09_appendix/action_src/addrats.html $(USERDIR)/09_appendix/action_src/addrats.html + $(SCCBOX) $(HOW) 09_appendix/action_src/addtimer.html $(USERDIR)/09_appendix/action_src/addtimer.html + $(SCCBOX) $(HOW) 09_appendix/action_src/adjuststyle.html $(USERDIR)/09_appendix/action_src/adjuststyle.html + $(SCCBOX) $(HOW) 09_appendix/action_src/align.html $(USERDIR)/09_appendix/action_src/align.html + $(SCCBOX) $(HOW) 09_appendix/action_src/applyvendor.html $(USERDIR)/09_appendix/action_src/applyvendor.html + $(SCCBOX) $(HOW) 09_appendix/action_src/atomic.html $(USERDIR)/09_appendix/action_src/atomic.html + $(SCCBOX) $(HOW) 09_appendix/action_src/attributes.html $(USERDIR)/09_appendix/action_src/attributes.html + $(SCCBOX) $(HOW) 09_appendix/action_src/autoplaceselected.html $(USERDIR)/09_appendix/action_src/autoplaceselected.html + $(SCCBOX) $(HOW) 09_appendix/action_src/autoroute.html $(USERDIR)/09_appendix/action_src/autoroute.html + $(SCCBOX) $(HOW) 09_appendix/action_src/benchmark.html $(USERDIR)/09_appendix/action_src/benchmark.html + $(SCCBOX) $(HOW) 09_appendix/action_src/boardflip.html $(USERDIR)/09_appendix/action_src/boardflip.html + $(SCCBOX) $(HOW) 09_appendix/action_src/center.html $(USERDIR)/09_appendix/action_src/center.html + $(SCCBOX) $(HOW) 09_appendix/action_src/changeclearsize.html $(USERDIR)/09_appendix/action_src/changeclearsize.html + $(SCCBOX) $(HOW) 09_appendix/action_src/changeflag.html $(USERDIR)/09_appendix/action_src/changeflag.html + $(SCCBOX) $(HOW) 09_appendix/action_src/changejoin.html $(USERDIR)/09_appendix/action_src/changejoin.html + $(SCCBOX) $(HOW) 09_appendix/action_src/changename.html $(USERDIR)/09_appendix/action_src/changename.html + $(SCCBOX) $(HOW) 09_appendix/action_src/changepinname.html $(USERDIR)/09_appendix/action_src/changepinname.html + $(SCCBOX) $(HOW) 09_appendix/action_src/changesize.html $(USERDIR)/09_appendix/action_src/changesize.html + $(SCCBOX) $(HOW) 09_appendix/action_src/changesizes.html $(USERDIR)/09_appendix/action_src/changesizes.html + $(SCCBOX) $(HOW) 09_appendix/action_src/chklayer.html $(USERDIR)/09_appendix/action_src/chklayer.html + $(SCCBOX) $(HOW) 09_appendix/action_src/chkrst.html $(USERDIR)/09_appendix/action_src/chkrst.html + $(SCCBOX) $(HOW) 09_appendix/action_src/chkview.html $(USERDIR)/09_appendix/action_src/chkview.html + $(SCCBOX) $(HOW) 09_appendix/action_src/claimnet.html $(USERDIR)/09_appendix/action_src/claimnet.html + $(SCCBOX) $(HOW) 09_appendix/action_src/clrflag.html $(USERDIR)/09_appendix/action_src/clrflag.html + $(SCCBOX) $(HOW) 09_appendix/action_src/command.html $(USERDIR)/09_appendix/action_src/command.html + $(SCCBOX) $(HOW) 09_appendix/action_src/connection.html $(USERDIR)/09_appendix/action_src/connection.html + $(SCCBOX) $(HOW) 09_appendix/action_src/cursor.html $(USERDIR)/09_appendix/action_src/cursor.html + $(SCCBOX) $(HOW) 09_appendix/action_src/cycledrag.html $(USERDIR)/09_appendix/action_src/cycledrag.html + $(SCCBOX) $(HOW) 09_appendix/action_src/disperseelements.html $(USERDIR)/09_appendix/action_src/disperseelements.html + $(SCCBOX) $(HOW) 09_appendix/action_src/display.html $(USERDIR)/09_appendix/action_src/display.html + $(SCCBOX) $(HOW) 09_appendix/action_src/distribute.html $(USERDIR)/09_appendix/action_src/distribute.html + $(SCCBOX) $(HOW) 09_appendix/action_src/djopt.html $(USERDIR)/09_appendix/action_src/djopt.html + $(SCCBOX) $(HOW) 09_appendix/action_src/dowindows.html $(USERDIR)/09_appendix/action_src/dowindows.html + $(SCCBOX) $(HOW) 09_appendix/action_src/drc.html $(USERDIR)/09_appendix/action_src/drc.html + $(SCCBOX) $(HOW) 09_appendix/action_src/elementlist.html $(USERDIR)/09_appendix/action_src/elementlist.html + $(SCCBOX) $(HOW) 09_appendix/action_src/elementsetattr.html $(USERDIR)/09_appendix/action_src/elementsetattr.html + $(SCCBOX) $(HOW) 09_appendix/action_src/executefile.html $(USERDIR)/09_appendix/action_src/executefile.html + $(SCCBOX) $(HOW) 09_appendix/action_src/exportoldconn.html $(USERDIR)/09_appendix/action_src/exportoldconn.html + $(SCCBOX) $(HOW) 09_appendix/action_src/flip.html $(USERDIR)/09_appendix/action_src/flip.html + $(SCCBOX) $(HOW) 09_appendix/action_src/freerotatebuffer.html $(USERDIR)/09_appendix/action_src/freerotatebuffer.html + $(SCCBOX) $(HOW) 09_appendix/action_src/getxy.html $(USERDIR)/09_appendix/action_src/getxy.html + $(SCCBOX) $(HOW) 09_appendix/action_src/import.html $(USERDIR)/09_appendix/action_src/import.html + $(SCCBOX) $(HOW) 09_appendix/action_src/importgui.html $(USERDIR)/09_appendix/action_src/importgui.html + $(SCCBOX) $(HOW) 09_appendix/action_src/importsch.html $(USERDIR)/09_appendix/action_src/importsch.html + $(SCCBOX) $(HOW) 09_appendix/action_src/l.html $(USERDIR)/09_appendix/action_src/l.html + $(SCCBOX) $(HOW) 09_appendix/action_src/layerbystack.html $(USERDIR)/09_appendix/action_src/layerbystack.html + $(SCCBOX) $(HOW) 09_appendix/action_src/le.html $(USERDIR)/09_appendix/action_src/le.html + $(SCCBOX) $(HOW) 09_appendix/action_src/listscripts.html $(USERDIR)/09_appendix/action_src/listscripts.html + $(SCCBOX) $(HOW) 09_appendix/action_src/livescript.html $(USERDIR)/09_appendix/action_src/livescript.html + $(SCCBOX) $(HOW) 09_appendix/action_src/load.html $(USERDIR)/09_appendix/action_src/load.html + $(SCCBOX) $(HOW) 09_appendix/action_src/loadfootprint.html $(USERDIR)/09_appendix/action_src/loadfootprint.html + $(SCCBOX) $(HOW) 09_appendix/action_src/loadfrom.html $(USERDIR)/09_appendix/action_src/loadfrom.html + $(SCCBOX) $(HOW) 09_appendix/action_src/loadscript.html $(USERDIR)/09_appendix/action_src/loadscript.html + $(SCCBOX) $(HOW) 09_appendix/action_src/loadvendorfrom.html $(USERDIR)/09_appendix/action_src/loadvendorfrom.html + $(SCCBOX) $(HOW) 09_appendix/action_src/m.html $(USERDIR)/09_appendix/action_src/m.html + $(SCCBOX) $(HOW) 09_appendix/action_src/markcrosshair.html $(USERDIR)/09_appendix/action_src/markcrosshair.html + $(SCCBOX) $(HOW) 09_appendix/action_src/message.html $(USERDIR)/09_appendix/action_src/message.html + $(SCCBOX) $(HOW) 09_appendix/action_src/mode.html $(USERDIR)/09_appendix/action_src/mode.html + $(SCCBOX) $(HOW) 09_appendix/action_src/morphpolygon.html $(USERDIR)/09_appendix/action_src/morphpolygon.html + $(SCCBOX) $(HOW) 09_appendix/action_src/movelayer.html $(USERDIR)/09_appendix/action_src/movelayer.html + $(SCCBOX) $(HOW) 09_appendix/action_src/moveobject.html $(USERDIR)/09_appendix/action_src/moveobject.html + $(SCCBOX) $(HOW) 09_appendix/action_src/movetocurrentlayer.html $(USERDIR)/09_appendix/action_src/movetocurrentlayer.html + $(SCCBOX) $(HOW) 09_appendix/action_src/netlist.html $(USERDIR)/09_appendix/action_src/netlist.html + $(SCCBOX) $(HOW) 09_appendix/action_src/new.html $(USERDIR)/09_appendix/action_src/new.html + $(SCCBOX) $(HOW) 09_appendix/action_src/onliner.html $(USERDIR)/09_appendix/action_src/onliner.html + $(SCCBOX) $(HOW) 09_appendix/action_src/openemsexcitation.html $(USERDIR)/09_appendix/action_src/openemsexcitation.html + $(SCCBOX) $(HOW) 09_appendix/action_src/pan.html $(USERDIR)/09_appendix/action_src/pan.html + $(SCCBOX) $(HOW) 09_appendix/action_src/pastebuffer.html $(USERDIR)/09_appendix/action_src/pastebuffer.html + $(SCCBOX) $(HOW) 09_appendix/action_src/polycombine.html $(USERDIR)/09_appendix/action_src/polycombine.html + $(SCCBOX) $(HOW) 09_appendix/action_src/polygon.html $(USERDIR)/09_appendix/action_src/polygon.html + $(SCCBOX) $(HOW) 09_appendix/action_src/polystitch.html $(USERDIR)/09_appendix/action_src/polystitch.html + $(SCCBOX) $(HOW) 09_appendix/action_src/popup.html $(USERDIR)/09_appendix/action_src/popup.html + $(SCCBOX) $(HOW) 09_appendix/action_src/preunload.html $(USERDIR)/09_appendix/action_src/preunload.html + $(SCCBOX) $(HOW) 09_appendix/action_src/print.html $(USERDIR)/09_appendix/action_src/print.html + $(SCCBOX) $(HOW) 09_appendix/action_src/printcalibrate.html $(USERDIR)/09_appendix/action_src/printcalibrate.html + $(SCCBOX) $(HOW) 09_appendix/action_src/promptfor.html $(USERDIR)/09_appendix/action_src/promptfor.html + $(SCCBOX) $(HOW) 09_appendix/action_src/puller.html $(USERDIR)/09_appendix/action_src/puller.html + $(SCCBOX) $(HOW) 09_appendix/action_src/q.html $(USERDIR)/09_appendix/action_src/q.html + $(SCCBOX) $(HOW) 09_appendix/action_src/quit.html $(USERDIR)/09_appendix/action_src/quit.html + $(SCCBOX) $(HOW) 09_appendix/action_src/redo.html $(USERDIR)/09_appendix/action_src/redo.html + $(SCCBOX) $(HOW) 09_appendix/action_src/reloadscript.html $(USERDIR)/09_appendix/action_src/reloadscript.html + $(SCCBOX) $(HOW) 09_appendix/action_src/renumberblock.html $(USERDIR)/09_appendix/action_src/renumberblock.html + $(SCCBOX) $(HOW) 09_appendix/action_src/renumberbuffer.html $(USERDIR)/09_appendix/action_src/renumberbuffer.html + $(SCCBOX) $(HOW) 09_appendix/action_src/replacefootprint.html $(USERDIR)/09_appendix/action_src/replacefootprint.html + $(SCCBOX) $(HOW) 09_appendix/action_src/report.html $(USERDIR)/09_appendix/action_src/report.html + $(SCCBOX) $(HOW) 09_appendix/action_src/reportdialog.html $(USERDIR)/09_appendix/action_src/reportdialog.html + $(SCCBOX) $(HOW) 09_appendix/action_src/ripup.html $(USERDIR)/09_appendix/action_src/ripup.html + $(SCCBOX) $(HOW) 09_appendix/action_src/rn.html $(USERDIR)/09_appendix/action_src/rn.html + $(SCCBOX) $(HOW) 09_appendix/action_src/rotate90.html $(USERDIR)/09_appendix/action_src/rotate90.html + $(SCCBOX) $(HOW) 09_appendix/action_src/s.html $(USERDIR)/09_appendix/action_src/s.html + $(SCCBOX) $(HOW) 09_appendix/action_src/save.html $(USERDIR)/09_appendix/action_src/save.html + $(SCCBOX) $(HOW) 09_appendix/action_src/savelib.html $(USERDIR)/09_appendix/action_src/savelib.html + $(SCCBOX) $(HOW) 09_appendix/action_src/saveto.html $(USERDIR)/09_appendix/action_src/saveto.html + $(SCCBOX) $(HOW) 09_appendix/action_src/scriptcookie.html $(USERDIR)/09_appendix/action_src/scriptcookie.html + $(SCCBOX) $(HOW) 09_appendix/action_src/scriptpersistency.html $(USERDIR)/09_appendix/action_src/scriptpersistency.html + $(SCCBOX) $(HOW) 09_appendix/action_src/scroll.html $(USERDIR)/09_appendix/action_src/scroll.html + $(SCCBOX) $(HOW) 09_appendix/action_src/select.html $(USERDIR)/09_appendix/action_src/select.html + $(SCCBOX) $(HOW) 09_appendix/action_src/selectlayer.html $(USERDIR)/09_appendix/action_src/selectlayer.html + $(SCCBOX) $(HOW) 09_appendix/action_src/setflag.html $(USERDIR)/09_appendix/action_src/setflag.html + $(SCCBOX) $(HOW) 09_appendix/action_src/setsame.html $(USERDIR)/09_appendix/action_src/setsame.html + $(SCCBOX) $(HOW) 09_appendix/action_src/setthermal.html $(USERDIR)/09_appendix/action_src/setthermal.html + $(SCCBOX) $(HOW) 09_appendix/action_src/setunits.html $(USERDIR)/09_appendix/action_src/setunits.html + $(SCCBOX) $(HOW) 09_appendix/action_src/setvalue.html $(USERDIR)/09_appendix/action_src/setvalue.html + $(SCCBOX) $(HOW) 09_appendix/action_src/smartdisperse.html $(USERDIR)/09_appendix/action_src/smartdisperse.html + $(SCCBOX) $(HOW) 09_appendix/action_src/swapsides.html $(USERDIR)/09_appendix/action_src/swapsides.html + $(SCCBOX) $(HOW) 09_appendix/action_src/toggleview.html $(USERDIR)/09_appendix/action_src/toggleview.html + $(SCCBOX) $(HOW) 09_appendix/action_src/tool.html $(USERDIR)/09_appendix/action_src/tool.html + $(SCCBOX) $(HOW) 09_appendix/action_src/undo.html $(USERDIR)/09_appendix/action_src/undo.html + $(SCCBOX) $(HOW) 09_appendix/action_src/unloadscript.html $(USERDIR)/09_appendix/action_src/unloadscript.html + $(SCCBOX) $(HOW) 09_appendix/action_src/unselect.html $(USERDIR)/09_appendix/action_src/unselect.html + $(SCCBOX) $(HOW) 09_appendix/action_src/w.html $(USERDIR)/09_appendix/action_src/w.html + $(SCCBOX) $(HOW) 09_appendix/action_src/wq.html $(USERDIR)/09_appendix/action_src/wq.html + $(SCCBOX) $(HOW) 09_appendix/action_src/zoom.html $(USERDIR)/09_appendix/action_src/zoom.html + $(SCCBOX) $(HOW) 09_appendix/attributes.html $(USERDIR)/09_appendix/attributes.html + $(SCCBOX) $(HOW) 09_appendix/bridges.svg $(USERDIR)/09_appendix/bridges.svg + $(SCCBOX) $(HOW) 09_appendix/combined_glossary.html $(USERDIR)/09_appendix/combined_glossary.html + $(SCCBOX) $(HOW) 09_appendix/dialogs.html $(USERDIR)/09_appendix/dialogs.html + $(SCCBOX) $(HOW) 09_appendix/external_resources.html $(USERDIR)/09_appendix/external_resources.html + $(SCCBOX) $(HOW) 09_appendix/formats.html $(USERDIR)/09_appendix/formats.html + $(SCCBOX) $(HOW) 09_appendix/index.html $(USERDIR)/09_appendix/index.html + $(SCCBOX) $(HOW) 09_appendix/layer_addr.html $(USERDIR)/09_appendix/layer_addr.html + $(SCCBOX) $(HOW) 09_appendix/layer_colors.html $(USERDIR)/09_appendix/layer_colors.html + $(SCCBOX) $(HOW) default.css $(USERDIR)/default.css + $(SCCBOX) $(HOW) index.html $(USERDIR)/index.html Index: tags/2.3.0/doc/user/default.css =================================================================== --- tags/2.3.0/doc/user/default.css (nonexistent) +++ tags/2.3.0/doc/user/default.css (revision 33253) @@ -0,0 +1,65 @@ +H1 { + border-bottom-style: solid; + border-bottom-width: 3px; +} + +H2 { + border-bottom-style: solid; + border-bottom-width: 1px; +} + +P { + text-align: justify; + margin-left: 20px; +} + +PRE { + margin-left: 20px; +} + +table.actsum { + border: none; + margin-left: 20px; +} + +td.actsum { + background-color: #f0f0f0; + border: none; + padding: 15px; + align: left; +} + +th.actsum { + background-color: #f0f0f0; + border: none; + padding: 15px; + align: right; +} + +table { + border-collapse: collapse; + border: 2px solid #555555; + margin-left: 20px; +} + +td { + border: 1px solid #777777; + padding: 5px; +} + +th { + border: 1px solid #777777; + background-color: #e0e0e0; + padding: 5px; +} + + +ul.toc { + list-style-type: none; + padding: 20px; +} + +ul.toc li { + padding: 5px; + font-size: 120%; +} Index: tags/2.3.0/doc/user/index.html =================================================================== --- tags/2.3.0/doc/user/index.html (nonexistent) +++ tags/2.3.0/doc/user/index.html (revision 33253) @@ -0,0 +1,33 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual

+ +

Table of Contents

+

+

+ Index: tags/2.3.0/doc/user/index_pdf.html =================================================================== --- tags/2.3.0/doc/user/index_pdf.html (nonexistent) +++ tags/2.3.0/doc/user/index_pdf.html (revision 33253) @@ -0,0 +1,21 @@ + + + + pcb-rnd user manual + + + + +

pcb-rnd - user manual - pdf render

+

+The pdf version of the user documentation is converted from the + html version. +

+

+

+Note: each file cotnains a Table of Contents at the end of the +file. Index: tags/2.3.0/doc/user/instgen =================================================================== --- tags/2.3.0/doc/user/instgen (nonexistent) +++ tags/2.3.0/doc/user/instgen (revision 33253) @@ -0,0 +1,45 @@ +#!/bin/sh +export LANG=C +find 0*_* *.html *.css -type f -print | sort | awk ' +BEGIN { + print "### autogenerated, DO NOT EDIT (but do commit); run make regen on *NIX ###" + print "install_all:" +} +($0 ~ "[/][.]") { next } +($0 ~ "[/]src[/]") { next } +/[.]bak$/ { next } +/[.]backup$/ { next } +/^ps_title/ { next } +/^index_pdf.html/ { next } +/~$/ { next } + +function get_svn_st(path, st,cmd) +{ + cmd="svn stat " path + cmd | getline st + close(cmd) + return st; +} + +($0 ~ "/") { + path = $0 + + # don not list temp files + if (get_svn_st(path) ~ "[^?]") + next + + sub("/[^/]*$", "", path) + if (!(path in PATHS)) { + print " $(SCCBOX) mkdir -p $(USERDIR)/" path + PATHS[path]=1 + } +} + +{ + # don not list temp files + if (get_svn_st($0) ~ "[^?]") + next + + print " $(SCCBOX) $(HOW) " $0 " $(USERDIR)/" $0 +} +' > Makefile.inst Property changes on: tags/2.3.0/doc/user/instgen ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/user/listlnk =================================================================== --- tags/2.3.0/doc/user/listlnk (nonexistent) +++ tags/2.3.0/doc/user/listlnk (revision 33253) @@ -0,0 +1,199 @@ +#!/bin/sh + +volmap="vol.map" + +unlinked_ignores=' +# care only about subdirs +!($0 ~ "/") { next } + +# sources +/\/src\// { next } +/Makefile$/ { next } +/\/ID[.]desc$/ { next } +/\/ID[.]name$/ { next } +/[.]templ[.]html$/ { next } +/[.]dot$/ { next } +/09_appendix\/action_src/ { next } + +/06_feature\/djopt\/.*\.txt$/ { next } +/06_feature\/djopt\/Pre.html$/ { next } +/06_feature\/djopt\/Post.html$/ { next } +/06_feature\/scripting\/.*\/ex.html$/ { next } + +# tmp/backup leftover +/[.]svg[.]png$/ { next } +/[.]out[.]png$/ { next } +/06_feature\/stroke\/.*\.png$/ { next } +/PCB\.[^\/.]*\.save$/ { next } +/PCB\.[^\/.]*\.backup$/ { next } +/[.]pyc$/ { next } +' + +build_list() +{ + local vol=0 img=0 + + while test $# -gt 0 + do + case "$1" in + -v|--vol) vol=1;; + -i|--img) img=1;; + *) echo "unknown list parameter $1" >&2; exit 1;; + esac + shift 1 + done + +echo "index.html" | awk -v "vol=$vol" -v "volmap=$volmap" -v "img=$img" ' + BEGIN { + nopen=0 + dsq = "[\"'\'']" + if (vol) { + while((getline < volmap) == 1) + if (NF == 2) + VOL[$1] = $2 + } + } + + function append(path, vp) + { + if (path == "") + return 0 + if (path in SEEN) + return 0 + SEEN[path]= 1 + if (vol) { + vp = path + sub("/.*", "", vp) + print path "\t" int(VOL[vp]) + } + else + print path + return 1 + } + + function mkpath(cwd, path, P,v,n,m,found) + { + if (path ~ "://") + return "" + sub("#.*$", "", path) + if (path == "") + return "" + + path = cwd "/" path + gsub("//*", "/", path) + v = split(path, P, "/") + for(n = 2; n < v; n++) { + if (P[n] == "..") { + found=0 + for(m = n-1; m >= 0; m--) { + if (P[m] != "") { + P[m] = "" + P[n] = "" + found=1 + break; + } + } + # ponting to parent of root + if (!found) + return "" + } + } + path="" + for(n = 1; n < v; n++) + if (P[n] != "") + path = path P[n] "/" + path = path P[v] + + m = "^" cwd + if ((cwd != "") && !(path ~ m)) { + # pointing to parent from the current search + return "" + } + + return path + } + + function dump_links(cwd, fn , ors, line, path, found) + { + ors = RS + RS="[<]" + while((getline < fn) == 1) { + found = 0 + + if ((($1 == "a") || ($1 == "A")) && ($0 ~ "href=")) { + line=$0 + gsub("\n", " ", line) + sub(".*href=" dsq, "", line) + sub(dsq ".*", "", line) + found=1 + } + + if (img && (tolower($1) == "img") && ($0 ~ "src=")) { + line=$0 + gsub("\n", " ", line) + sub(".*src=" dsq, "", line) + sub(dsq ".*", "", line) + found=1 + } + + if (found) { + path = mkpath(cwd, line) + if (append(path)) + process(path) + } + } + RS=ors + } + + function process(fn) + { + if (fn == "") + return + cwd=fn + sub("[^/]*$", "", cwd) + dump_links(cwd, fn) + } + + { process(mkpath("", $0)); } + +' +} + +unlinked() +{ + local sep="@@@" + ( + build_list -i + echo "$sep" + find . -type f -print + ) | awk -v "sep=$sep" ' + + ($0 == sep) { after_sep=1; next; } + (!after_sep) { FOUND[$0]++ } + + { sub("^./", "", $0) } + + '"$unlinked_ignores"' + + (after_sep) { + if (!($0 in FOUND)) + print $0 + } + ' +} + +### main ### + +cmd="$1" +if test $# -gt 0 +then + shift 1 +fi + +case "$cmd" +in + unlinked) unlinked "$@" ;; + ""|list) build_list "$@" ;; + *) echo "unknown command $cmd" >&2; exit 1;; +esac + Property changes on: tags/2.3.0/doc/user/listlnk ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/doc/user/ps_title.html =================================================================== --- tags/2.3.0/doc/user/ps_title.html (nonexistent) +++ tags/2.3.0/doc/user/ps_title.html (revision 33253) @@ -0,0 +1,41 @@ + + + +


  +


  +


  +


  +


  +


  +

+ +
+ pcb-rnd +

%%%ver%%% +


  +


  + User manual +


  + %%%volume%%% +


  +

+ +

pcb-rnd - user manual

+

+pcb-rnd is an open source Printed Circuit Board editor. +

+This is the pdf version of the html based user manual shipped +with pcb-rnd. The up-to-date full version is available online at +http://repo.hu/projects/pcb-rnd/user +

+This file is one of the three volumes of the user documentation. +

+pcb-rnd downloads and contacts: +

    +
  • web page: http://www.repo.hu/projects/pcb-rnd +
  • source: svn://svn.repo.hu/pcb-rnd/trunk +
  • contact (email or chat): http://www.repo.hu/projects/pcb-rnd/contact.html +
+ + + Index: tags/2.3.0/doc/user/vol.map =================================================================== --- tags/2.3.0/doc/user/vol.map (nonexistent) +++ tags/2.3.0/doc/user/vol.map (revision 33253) @@ -0,0 +1,11 @@ +01_intro 1 +02_model 1 +03_data 1 +04_invoc 1 +05_ui 1 + +06_feature 2 +07_io 2 +08_util 2 + +09_appendix 3 Index: tags/2.3.0/doc/windows.html =================================================================== --- tags/2.3.0/doc/windows.html (nonexistent) +++ tags/2.3.0/doc/windows.html (revision 33253) @@ -0,0 +1,95 @@ + + + +

pcb-rnd on windows

+ +

We have a pack in beta testing. It should work on any windows version +from 7 up. (It does _not_ work on XP.) + +

IMPORTANT: if you use the windows version of pcb-rnd, please send me +an email to: pcb-rnd-win (at) igor2.repo.hu + +

I will use this for sampling user demand. If there are no emails, that +means there are no windows users which means it is not worth investing +time in compiling windows releases. + +

1. download the binary pack and install

+ +

Download a -win32.zip from the +binary releases page + + +

Unpack the zip anywhere, and run pcb-rnd from bin: +

    +
  • start a shell (cmd.exe), cd to where you unpacked it, cd bin, pcb-rnd +
  • create a shortcut icon (TODO: what's needed for the exe to find the dlls?) +
+ +

+IMPORTANT: Please make sure there's no space in the full path where you unpack. + + +

2. limitations

+ +

pcb-rnd is a package designed for UNIX. The windows port does not +change the UNIX aspect of pcb-rnd, thus a few things are different from +a normal windows application: +

    +
  • pcb-rnd works from config files, not from the registry +
  • pcb-rnd will figure the users home directory and will look for .pcb-rnd/ + in there for the user configs +
  • if anything breaks, try to run pcb-rnd from the command line: run a cmd.exe + and cd to the bin dir within the installation root and run pcb-rnd from + there watching what it prints to the console. +
+ +

The usual pcb-rnd policies apply: +

    +
  • pcb-rnd speaks English - there's no internalization, no unicode or utf +
  • some keyboard shortcuts may not work if your keyboard layout is not set + to English +
  • pcb-rnd uses the keyboard and the command line heavily +
+ +

There are a few limitations specific to the current windows pack: +

    +
  • there can not be space in the path where the pack is unzipped +
  • UNC paths (\\server\something) may fail randomly +
  • it does not support opengl, it is always doing software rendering +
  • some of the export formats (e.g. png) are not yet supported on windows +
  • there is no fp_wget support because there's no wget in the pack + (may work with busybox wget, busybox shipped in the pack, testing required) +
  • gsch2pcb-rnd is not supported +
  • import schematics with gnetlist has not been tested yet + (importing tEDAx netlist should work) +
  • the windows port may have some overhead; if you find pcb-rnd slow, + please try it on Linux. +
+ +

3. Cross compilation from Linux to win32

+ +(developers may need this, if you are an user, it is safe to skip.) + +

There is an svn repo that hosts all the sources for the dependencies. From +this, the binary DLLs can be compiled (this step may need some manual +intervention, autotools is not very nice for cross compilation). The result +is the "ultimate hidlib dependency pack" (uhdp), 90+ megabytes of dlls +with gtk, glib, gettext and whatnot. + +

The uhdp has two versions: the smaller one, with the dlls only, is part +of the pack downloaded by end users for installation. The bigger one, +called the developer pack, also contains the installed headers, .a and +.la files and can be used as "sysroot" for cross-compiling pcb-rnd +(or other software) against. + +

The uhdp can be donwloaded from http://repo.hu/projects/hidlib.w32 + +

The normal process is: +

+ Index: tags/2.3.0/doc/wishlist.txt =================================================================== --- tags/2.3.0/doc/wishlist.txt (nonexistent) +++ tags/2.3.0/doc/wishlist.txt (revision 33253) @@ -0,0 +1,14 @@ +Active user wishes: + W4: user doc [Miloh] + W9: push & shove [Erich, Evan] + +Being done: + W1: cschem [Chris] + +User wishes fulfilled: + W2: proper primitives - data model rewrite [Chris] + W3: more generic footprints [Chris, Evan] -> subcircuits + W5: 3d modeller export [Miloh, Evan] (bdale's sponsoration) + W6: GUI access to object attributes: gtk editor, find/select by attrib [James] + W7: programmable drc (star grounding is implemented with intconn) [James] + W8: gl support [Erich, Evan] Index: tags/2.3.0/font/HersheySans1.pcb_font =================================================================== --- tags/2.3.0/font/HersheySans1.pcb_font (nonexistent) +++ tags/2.3.0/font/HersheySans1.pcb_font (revision 33253) @@ -0,0 +1,1205 @@ +##name:Hershey Sans 1 Stroke Font v1.0 +##source:https://github.com/evil-mad/EggBot/blob/master/inkscape_driver/hersheydata.py +##ported_by:Erich S. Heinzle 2014 +##license:TODO +# +Symbol[' ' 1800] +( +) +Symbol['!' 1200] +( + SymbolLine[1191 1000 1191 3666 800] + SymbolLine[1191 4619 1000 4809 800] + SymbolLine[1000 4809 1191 4999 800] + SymbolLine[1191 4999 1381 4809 800] + SymbolLine[1381 4809 1191 4619 800] +) +Symbol['"' 1200] +( + SymbolLine[1000 1000 1000 2334 800] + SymbolLine[2523 1000 2523 2334 800] +) +Symbol['#' 1200] +( + SymbolLine[2573 1000 1239 5000 800] + SymbolLine[3916 1000 2582 5000 800] + SymbolLine[1339 2325 4207 2325 800] + SymbolLine[1000 3675 3866 3675 800] +) +Symbol['$' 1200] +( + SymbolLine[2333 300 2333 5824 800] + SymbolLine[3666 1633 3286 1252 800] + SymbolLine[3286 1252 2714 1062 800] + SymbolLine[2714 1062 1952 1062 800] + SymbolLine[1952 1062 1381 1252 800] + SymbolLine[1381 1252 1000 1633 800] + SymbolLine[1000 1633 1000 2015 800] + SymbolLine[1000 2015 1191 2395 800] + SymbolLine[1191 2395 1381 2586 800] + SymbolLine[1381 2586 1762 2776 800] + SymbolLine[1762 2776 2905 3157 800] + SymbolLine[2905 3157 3286 3347 800] + SymbolLine[3286 3347 3477 3538 800] + SymbolLine[3477 3538 3666 3919 800] + SymbolLine[3666 3919 3666 4490 800] + SymbolLine[3666 4490 3286 4872 800] + SymbolLine[3286 4872 2714 5062 800] + SymbolLine[2714 5062 1952 5062 800] + SymbolLine[1952 5062 1381 4872 800] + SymbolLine[1381 4872 1000 4490 800] + +) +Symbol['%' 1200] +( + SymbolLine[11285 1000 7857 4999 800] + SymbolLine[8809 1000 9191 1380 800] + SymbolLine[9191 1380 9191 1762 800] + SymbolLine[9191 1762 9000 2142 800] + SymbolLine[9000 2142 8619 2333 800] + SymbolLine[8619 2333 8238 2333 800] + SymbolLine[8238 2333 7857 1952 800] + SymbolLine[7857 1952 7857 1571 800] + SymbolLine[7857 1571 8048 1190 800] + SymbolLine[8048 1190 8428 1000 800] + SymbolLine[8428 1000 8809 1000 800] + SymbolLine[8809 1000 9191 1190 800] + SymbolLine[9191 1190 9762 1380 800] + SymbolLine[9762 1380 10332 1380 800] + SymbolLine[10332 1380 10905 1190 800] + SymbolLine[10905 1190 11285 1000 800] + SymbolLine[10523 3666 10143 3857 800] + SymbolLine[10143 3857 9952 4237 800] + SymbolLine[9952 4237 9952 4619 800] + SymbolLine[9952 4619 10332 4999 800] + SymbolLine[10332 4999 10714 4999 800] + SymbolLine[10714 4999 11095 4809 800] + SymbolLine[11095 4809 11285 4428 800] + SymbolLine[11285 4428 11285 4047 800] + SymbolLine[11285 4047 10905 3666 800] + SymbolLine[10905 3666 10523 3666 800] +) +Symbol['&' 1200] +( + SymbolLine[4809 2714 4809 2523 800] + SymbolLine[4809 2523 4618 2333 800] + SymbolLine[4618 2333 4428 2333 800] + SymbolLine[4428 2333 4237 2523 800] + SymbolLine[4237 2523 4046 2905 800] + SymbolLine[4046 2905 3666 3857 800] + SymbolLine[3666 3857 3285 4428 800] + SymbolLine[3285 4428 2905 4809 800] + SymbolLine[2905 4809 2523 4999 800] + SymbolLine[2523 4999 1762 4999 800] + SymbolLine[1762 4999 1380 4809 800] + SymbolLine[1380 4809 1189 4619 800] + SymbolLine[1189 4619 1000 4237 800] + SymbolLine[1000 4237 1000 3857 800] + SymbolLine[1000 3857 1189 3476 800] + SymbolLine[1189 3476 1380 3285 800] + SymbolLine[1380 3285 2714 2523 800] + SymbolLine[2714 2523 2905 2333 800] + SymbolLine[2905 2333 3094 1952 800] + SymbolLine[3094 1952 3094 1571 800] + SymbolLine[3094 1571 2905 1190 800] + SymbolLine[2905 1190 2523 1000 800] + SymbolLine[2523 1000 2142 1190 800] + SymbolLine[2142 1190 1952 1571 800] + SymbolLine[1952 1571 1952 1952 800] + SymbolLine[1952 1952 2142 2523 800] + SymbolLine[2142 2523 2523 3095 800] + SymbolLine[2523 3095 3475 4428 800] + SymbolLine[3475 4428 3857 4809 800] + SymbolLine[3857 4809 4237 4999 800] + SymbolLine[4237 4999 4618 4999 800] + SymbolLine[4618 4999 4809 4809 800] + SymbolLine[4809 4809 4809 4619 800] +) +Symbol[''' 1200] +( + SymbolLine[1191 1381 1000 1191 800] + SymbolLine[1000 1191 1191 1000 800] + SymbolLine[1191 1000 1381 1191 800] + SymbolLine[1381 1191 1381 1571 800] + SymbolLine[1381 1571 1191 1952 800] + SymbolLine[1191 1952 1000 2143 800] +) +Symbol['(' 1200] +( + SymbolLine[2333 0 1952 381 800] + SymbolLine[1952 381 1571 952 800] + SymbolLine[1571 952 1189 1715 800] + SymbolLine[1189 1715 1000 2667 800] + SymbolLine[1000 2667 1000 3429 800] + SymbolLine[1000 3429 1189 4381 800] + SymbolLine[1189 4381 1571 5143 800] + SymbolLine[1571 5143 1952 5714 800] + SymbolLine[1952 5714 2333 6095 800] +) +Symbol[')' 1200] +( + SymbolLine[1000 0 1380 381 800] + SymbolLine[1380 381 1762 952 800] + SymbolLine[1762 952 2143 1715 800] + SymbolLine[2143 1715 2332 2667 800] + SymbolLine[2332 2667 2332 3429 800] + SymbolLine[2332 3429 2143 4381 800] + SymbolLine[2143 4381 1762 5143 800] + SymbolLine[1762 5143 1380 5714 800] + SymbolLine[1380 5714 1000 6095 800] +) +Symbol['*' 1200] +( + SymbolLine[2667 1000 2667 5000 800] + SymbolLine[1000 2001 4333 4001 800] + SymbolLine[4333 2001 1000 4001 800] +) +Symbol['+' 1200] +( + SymbolLine[2714 1250 2714 4678 800] + SymbolLine[1000 2964 4428 2964 800] +) +Symbol[',' 1200] +( + SymbolLine[1381 4891 1191 5080 800] + SymbolLine[1191 5080 1000 4891 800] + SymbolLine[1000 4891 1191 4700 800] + SymbolLine[1191 4700 1381 4891 800] + SymbolLine[1381 4891 1381 5271 800] + SymbolLine[1381 5271 1000 5652 800] + +) +Symbol['-' 1200] +( + SymbolLine[0 3000 2500 3000 800] +) +Symbol['.' 1200] +( + SymbolLine[1190 4700 1000 4891 800] + SymbolLine[1000 4891 1190 5080 800] + SymbolLine[1190 5080 1380 4891 800] + SymbolLine[1380 4891 1190 4700 800] +) +Symbol['/' 1200] +( + SymbolLine[3251 1000 1000 5000 800] +) +Symbol['0' 1200] #numbers are new +( + SymbolLine[2143 1000 1572 1190 800] + SymbolLine[1572 1190 1190 1761 800] + SymbolLine[1190 1761 1000 2713 800] + SymbolLine[1000 2713 1000 3285 800] + SymbolLine[1000 3285 1190 4238 800] + SymbolLine[1190 4238 1572 4809 800] + SymbolLine[1572 4809 2143 5000 800] + SymbolLine[2143 5000 2524 5000 800] + SymbolLine[2524 5000 3095 4809 800] + SymbolLine[3095 4809 3476 4238 800] + SymbolLine[3476 4238 3667 3285 800] + SymbolLine[3667 3285 3667 2713 800] + SymbolLine[3667 2713 3476 1761 800] + SymbolLine[3476 1761 3095 1190 800] + SymbolLine[3095 1190 2524 1000 800] + SymbolLine[2524 1000 2143 1000 800] +) +Symbol['1' 1200] +( + SymbolLine[1000 1761 1380 1571 800] + SymbolLine[1380 1571 1952 1000 800] + SymbolLine[1952 1000 1952 5000 800] +) +Symbol['2' 1200] +( + SymbolLine[1190 1952 1190 1761 800] + SymbolLine[1190 1761 1381 1381 800] + SymbolLine[1381 1381 1570 1190 800] + SymbolLine[1570 1190 1952 1000 800] + SymbolLine[1952 1000 2713 1000 800] + SymbolLine[2713 1000 3095 1190 800] + SymbolLine[3095 1190 3285 1381 800] + SymbolLine[3285 1381 3475 1761 800] + SymbolLine[3475 1761 3475 2143 800] + SymbolLine[3475 2143 3285 2524 800] + SymbolLine[3285 2524 2904 3095 800] + SymbolLine[2904 3095 1000 5000 800] + SymbolLine[1000 5000 3666 5000 800] +) +Symbol['3' 1200] +( + SymbolLine[1380 1000 3475 1000 800] + SymbolLine[3475 1000 2332 2524 800] + SymbolLine[2332 2524 2904 2524 800] + SymbolLine[2904 2524 3284 2713 800] + SymbolLine[3284 2713 3475 2904 800] + SymbolLine[3475 2904 3666 3476 800] + SymbolLine[3666 3476 3666 3856 800] + SymbolLine[3666 3856 3475 4428 800] + SymbolLine[3475 4428 3095 4809 800] + SymbolLine[3095 4809 2523 5000 800] + SymbolLine[2523 5000 1952 5000 800] + SymbolLine[1952 5000 1380 4809 800] + SymbolLine[1380 4809 1190 4618 800] + SymbolLine[1190 4618 1000 4238 800] +) +Symbol['4' 1200] +( + SymbolLine[2904 1000 1000 3666 800] + SymbolLine[1000 3666 3856 3666 800] + SymbolLine[2904 1000 2904 5000 800] +) +Symbol['5' 1200] +( + SymbolLine[3286 1000 1381 1000 800] + SymbolLine[1381 1000 1190 2713 800] + SymbolLine[1190 2713 1381 2524 800] + SymbolLine[1381 2524 1952 2333 800] + SymbolLine[1952 2333 2524 2333 800] + SymbolLine[2524 2333 3095 2524 800] + SymbolLine[3095 2524 3476 2904 800] + SymbolLine[3476 2904 3667 3476 800] + SymbolLine[3667 3476 3667 3856 800] + SymbolLine[3667 3856 3476 4428 800] + SymbolLine[3476 4428 3095 4809 800] + SymbolLine[3095 4809 2524 5000 800] + SymbolLine[2524 5000 1952 5000 800] + SymbolLine[1952 5000 1381 4809 800] + SymbolLine[1381 4809 1190 4618 800] + SymbolLine[1190 4618 1000 4238 800] +) +Symbol['6' 1200] +( + SymbolLine[3285 1571 3095 1190 800] + SymbolLine[3095 1190 2523 1000 800] + SymbolLine[2523 1000 2143 1000 800] + SymbolLine[2143 1000 1570 1190 800] + SymbolLine[1570 1190 1190 1761 800] + SymbolLine[1190 1761 1000 2713 800] + SymbolLine[1000 2713 1000 3666 800] + SymbolLine[1000 3666 1190 4428 800] + SymbolLine[1190 4428 1570 4809 800] + SymbolLine[1570 4809 2143 5000 800] + SymbolLine[2143 5000 2333 5000 800] + SymbolLine[2333 5000 2904 4809 800] + SymbolLine[2904 4809 3285 4428 800] + SymbolLine[3285 4428 3475 3856 800] + SymbolLine[3475 3856 3475 3666 800] + SymbolLine[3475 3666 3285 3095 800] + SymbolLine[3285 3095 2904 2713 800] + SymbolLine[2904 2713 2333 2524 800] + SymbolLine[2333 2524 2143 2524 800] + SymbolLine[2143 2524 1570 2713 800] + SymbolLine[1570 2713 1190 3095 800] + SymbolLine[1190 3095 1000 3666 800] +) +Symbol['7' 1200] +( + SymbolLine[3666 1000 1761 5000 800] + SymbolLine[1000 1000 3666 1000 800] +) +Symbol['8' 1200] +( + SymbolLine[1952 1000 1380 1190 800] + SymbolLine[1380 1190 1190 1571 800] + SymbolLine[1190 1571 1190 1952 800] + SymbolLine[1190 1952 1380 2333 800] + SymbolLine[1380 2333 1761 2524 800] + SymbolLine[1761 2524 2523 2713 800] + SymbolLine[2523 2713 3095 2904 800] + SymbolLine[3095 2904 3475 3285 800] + SymbolLine[3475 3285 3666 3666 800] + SymbolLine[3666 3666 3666 4238 800] + SymbolLine[3666 4238 3475 4618 800] + SymbolLine[3475 4618 3284 4809 800] + SymbolLine[3284 4809 2713 5000 800] + SymbolLine[2713 5000 1952 5000 800] + SymbolLine[1952 5000 1380 4809 800] + SymbolLine[1380 4809 1190 4618 800] + SymbolLine[1190 4618 1000 4238 800] + SymbolLine[1000 4238 1000 3666 800] + SymbolLine[1000 3666 1190 3285 800] + SymbolLine[1190 3285 1570 2904 800] + SymbolLine[1570 2904 2142 2713 800] + SymbolLine[2142 2713 2904 2524 800] + SymbolLine[2904 2524 3284 2333 800] + SymbolLine[3284 2333 3475 1952 800] + SymbolLine[3475 1952 3475 1571 800] + SymbolLine[3475 1571 3284 1190 800] + SymbolLine[3284 1190 2713 1000 800] + SymbolLine[2713 1000 1952 1000 800] +) +Symbol['9' 1200] +( + SymbolLine[3475 2333 3285 2904 800] + SymbolLine[3285 2904 2904 3285 800] + SymbolLine[2904 3285 2332 3476 800] + SymbolLine[2332 3476 2142 3476 800] + SymbolLine[2142 3476 1571 3285 800] + SymbolLine[1571 3285 1189 2904 800] + SymbolLine[1189 2904 1000 2333 800] + SymbolLine[1000 2333 1000 2143 800] + SymbolLine[1000 2143 1189 1571 800] + SymbolLine[1189 1571 1571 1190 800] + SymbolLine[1571 1190 2142 1000 800] + SymbolLine[2142 1000 2332 1000 800] + SymbolLine[2332 1000 2904 1190 800] + SymbolLine[2904 1190 3285 1571 800] + SymbolLine[3285 1571 3475 2333 800] + SymbolLine[3475 2333 3475 3285 800] + SymbolLine[3475 3285 3285 4238 800] + SymbolLine[3285 4238 2904 4809 800] + SymbolLine[2904 4809 2332 5000 800] + SymbolLine[2332 5000 1952 5000 800] + SymbolLine[1952 5000 1380 4809 800] + SymbolLine[1380 4809 1189 4428 800] +) +Symbol[':' 1200] +( + SymbolLine[1190 3400 1000 3591 800] + SymbolLine[1000 3591 1190 3781 800] + SymbolLine[1190 3781 1380 3591 800] + SymbolLine[1380 3591 1190 3400 800] + SymbolLine[1190 4734 1000 4925 800] + SymbolLine[1000 4925 1190 5114 800] + SymbolLine[1190 5114 1380 4925 800] + SymbolLine[1380 4925 1190 4734 800] +) +Symbol[';' 1200] +( + SymbolLine[1191 3400 1000 3591 800] + SymbolLine[1000 3591 1191 3781 800] + SymbolLine[1191 3781 1380 3591 800] + SymbolLine[1380 3591 1191 3400 800] + SymbolLine[1380 4925 1191 5114 800] + SymbolLine[1191 5114 1000 4925 800] + SymbolLine[1000 4925 1191 4734 800] + SymbolLine[1191 4734 1380 4925 800] + SymbolLine[1380 4925 1380 5305 800] + SymbolLine[1380 5305 1000 5686 800] + +) +Symbol['<' 1200] +( + SymbolLine[3540 1000 1000 3001 800] + SymbolLine[1000 3001 3540 5000 800] +) +Symbol['=' 1200] +( + SymbolLine[0 2400 2500 2400 800] + SymbolLine[0 3600 2500 3600 800] +) +Symbol['>' 1200] +( + SymbolLine[1000 1000 3540 3001 800] + SymbolLine[3540 3001 1000 5000 800] +) +Symbol['?' 1200] +( + SymbolLine[1000 1952 1000 1762 800] + SymbolLine[1000 1762 1191 1381 800] + SymbolLine[1191 1381 1380 1191 800] + SymbolLine[1380 1191 1762 1000 800] + SymbolLine[1762 1000 2523 1000 800] + SymbolLine[2523 1000 2905 1191 800] + SymbolLine[2905 1191 3095 1381 800] + SymbolLine[3095 1381 3285 1762 800] + SymbolLine[3285 1762 3285 2143 800] + SymbolLine[3285 2143 3095 2523 800] + SymbolLine[3095 2523 2905 2714 800] + SymbolLine[2905 2714 2143 3095 800] + SymbolLine[2143 3095 2143 3666 800] + SymbolLine[2143 4618 1952 4809 800] + SymbolLine[1952 4809 2143 5000 800] + SymbolLine[2143 5000 2332 4809 800] + SymbolLine[2332 4809 2143 4618 800] + +) +Symbol['@' 1200] +( + SymbolLine[4751 3000 4500 2499 800] + SymbolLine[4500 2499 4001 2250 800] + SymbolLine[4001 2250 3250 2250 800] + SymbolLine[3250 2250 2751 2499 800] + SymbolLine[2751 2499 2500 2750 800] + SymbolLine[2500 2750 2250 3501 800] + SymbolLine[2250 3501 2250 4250 800] + SymbolLine[2250 4250 2500 4751 800] + SymbolLine[2500 4751 3001 5000 800] + SymbolLine[3001 5000 3751 5000 800] + SymbolLine[3751 5000 4251 4751 800] + SymbolLine[4251 4751 4500 4250 800] + SymbolLine[3250 2250 2751 2750 800] + SymbolLine[2751 2750 2500 3501 800] + SymbolLine[2500 3501 2500 4250 800] + SymbolLine[2500 4250 2751 4751 800] + SymbolLine[2751 4751 3001 5000 800] + SymbolLine[4751 2250 4500 4250 800] + SymbolLine[4500 4250 4500 4751 800] + SymbolLine[4500 4751 5001 5000 800] + SymbolLine[5001 5000 5502 5000 800] + SymbolLine[5502 5000 6001 4501 800] + SymbolLine[6001 4501 6251 3750 800] + SymbolLine[6251 3750 6251 3250 800] + SymbolLine[6251 3250 6001 2499 800] + SymbolLine[6001 2499 5751 2000 800] + SymbolLine[5751 2000 5251 1499 800] + SymbolLine[5251 1499 4751 1249 800] + SymbolLine[4751 1249 4001 1000 800] + SymbolLine[4001 1000 3250 1000 800] + SymbolLine[3250 1000 2500 1249 800] + SymbolLine[2500 1249 2000 1499 800] + SymbolLine[2000 1499 1501 2000 800] + SymbolLine[1501 2000 1250 2499 800] + SymbolLine[1250 2499 1000 3250 800] + SymbolLine[1000 3250 1000 4000 800] + SymbolLine[1000 4000 1250 4751 800] + SymbolLine[1250 4751 1501 5250 800] + SymbolLine[1501 5250 2000 5751 800] + SymbolLine[2000 5751 2500 6001 800] + SymbolLine[2500 6001 3250 6250 800] + SymbolLine[3250 6250 4001 6250 800] + SymbolLine[4001 6250 4751 6001 800] + SymbolLine[4751 6001 5251 5751 800] + SymbolLine[5251 5751 5502 5501 800] + SymbolLine[5001 2250 4751 4250 800] + SymbolLine[4751 4250 4751 4751 800] + SymbolLine[4751 4751 5001 5000 800] +) +Symbol['A' 1200] +( + SymbolLine[1524 1000 0 5000 800] + SymbolLine[1524 1000 3048 5000 800] + SymbolLine[572 3667 2477 3667 800] +) +Symbol['B' 1200] +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[1000 1000 2714 1000 800] + SymbolLine[2714 1000 3285 1191 800] + SymbolLine[3285 1191 3476 1381 800] + SymbolLine[3476 1381 3666 1763 800] + SymbolLine[3666 1763 3666 2143 800] + SymbolLine[3666 2143 3476 2524 800] + SymbolLine[3476 2524 3285 2715 800] + SymbolLine[3285 2715 2714 2905 800] + SymbolLine[1000 2905 2714 2905 800] + SymbolLine[2714 2905 3285 3095 800] + SymbolLine[3285 3095 3476 3286 800] + SymbolLine[3476 3286 3666 3667 800] + SymbolLine[3666 3667 3666 4238 800] + SymbolLine[3666 4238 3476 4620 800] + SymbolLine[3476 4620 3285 4809 800] + SymbolLine[3285 4809 2714 5000 800] + SymbolLine[2714 5000 1000 5000 800] +) +Symbol['C' 1200] +( + SymbolLine[3857 1952 3666 1572 800] + SymbolLine[3666 1572 3285 1191 800] + SymbolLine[3285 1191 2905 1000 800] + SymbolLine[2905 1000 2142 1000 800] + SymbolLine[2142 1000 1762 1191 800] + SymbolLine[1762 1191 1380 1572 800] + SymbolLine[1380 1572 1190 1952 800] + SymbolLine[1190 1952 1000 2524 800] + SymbolLine[1000 2524 1000 3477 800] + SymbolLine[1000 3477 1190 4048 800] + SymbolLine[1190 4048 1380 4429 800] + SymbolLine[1380 4429 1762 4809 800] + SymbolLine[1762 4809 2142 5000 800] + SymbolLine[2142 5000 2905 5000 800] + SymbolLine[2905 5000 3285 4809 800] + SymbolLine[3285 4809 3666 4429 800] + SymbolLine[3666 4429 3857 4048 800] +) +Symbol['D' 1200] +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[1000 1000 2334 1000 800] + SymbolLine[2334 1000 2905 1191 800] + SymbolLine[2905 1191 3286 1572 800] + SymbolLine[3286 1572 3476 1952 800] + SymbolLine[3476 1952 3666 2524 800] + SymbolLine[3666 2524 3666 3477 800] + SymbolLine[3666 3477 3476 4048 800] + SymbolLine[3476 4048 3286 4429 800] + SymbolLine[3286 4429 2905 4809 800] + SymbolLine[2905 4809 2334 5000 800] + SymbolLine[2334 5000 1000 5000 800] +) +Symbol['E' 1200] +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[1000 1000 3476 1000 800] + SymbolLine[1000 2905 2523 2905 800] + SymbolLine[1000 5000 3476 5000 800] +) +Symbol['F' 1200] +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[1000 1000 3475 1000 800] + SymbolLine[1000 2905 2523 2905 800] +) +Symbol['G' 1200] +( + SymbolLine[3857 1952 3666 1572 800] + SymbolLine[3666 1572 3286 1191 800] + SymbolLine[3286 1191 2905 1000 800] + SymbolLine[2905 1000 2143 1000 800] + SymbolLine[2143 1000 1762 1191 800] + SymbolLine[1762 1191 1381 1572 800] + SymbolLine[1381 1572 1191 1952 800] + SymbolLine[1191 1952 1000 2524 800] + SymbolLine[1000 2524 1000 3477 800] + SymbolLine[1000 3477 1191 4048 800] + SymbolLine[1191 4048 1381 4429 800] + SymbolLine[1381 4429 1762 4809 800] + SymbolLine[1762 4809 2143 5000 800] + SymbolLine[2143 5000 2905 5000 800] + SymbolLine[2905 5000 3286 4809 800] + SymbolLine[3286 4809 3666 4429 800] + SymbolLine[3666 4429 3857 4048 800] + SymbolLine[3857 4048 3857 3477 800] + SymbolLine[2905 3477 3857 3477 800] +) +Symbol['H' 1200] +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[3667 5000 3667 1000 800] + SymbolLine[1000 2905 3667 2905 800] +) +Symbol['I' 1200] +( + SymbolLine[0 1000 1000 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 1000 5000 800] +) +Symbol['J' 1200] +( + SymbolLine[2905 1000 2905 4048 800] + SymbolLine[2905 4048 2715 4620 800] + SymbolLine[2715 4620 2524 4809 800] + SymbolLine[2524 4809 2143 5000 800] + SymbolLine[2143 5000 1763 5000 800] + SymbolLine[1763 5000 1381 4809 800] + SymbolLine[1381 4809 1191 4620 800] + SymbolLine[1191 4620 1000 4048 800] + SymbolLine[1000 4048 1000 3667 800] +) +Symbol['K' 1200] +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[3666 1000 1000 3667 800] + SymbolLine[1952 2715 3666 5000 800] +) +Symbol['L' 1200] +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[1000 5000 3285 5000 800] +) +Symbol['M' 1200] +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[1000 1000 2523 5000 800] + SymbolLine[4048 1000 2523 5000 800] + SymbolLine[4048 1000 4048 5000 800] +) +Symbol['N' 1200] +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[1000 1000 3666 5000 800] + SymbolLine[3666 1000 3666 5000 800] +) +Symbol['O' 1200] +( + SymbolLine[2142 1000 1762 1191 800] + SymbolLine[1762 1191 1380 1572 800] + SymbolLine[1380 1572 1190 1952 800] + SymbolLine[1190 1952 1000 2524 800] + SymbolLine[1000 2524 1000 3476 800] + SymbolLine[1000 3476 1190 4049 800] + SymbolLine[1190 4048 1380 4429 800] + SymbolLine[1380 4429 1762 4809 800] + SymbolLine[1762 4809 2142 5000 800] + SymbolLine[2142 5000 2905 5000 800] + SymbolLine[2905 5000 3285 4809 800] + SymbolLine[3285 4809 3666 4429 800] + SymbolLine[3666 4429 3857 4048 800] + SymbolLine[3857 4048 4046 3476 800] + SymbolLine[4046 3476 4046 2524 800] + SymbolLine[4046 2524 3857 1952 800] + SymbolLine[3857 1952 3666 1572 800] + SymbolLine[3666 1572 3285 1191 800] + SymbolLine[3285 1191 2905 1000 800] + SymbolLine[2905 1000 2142 1000 800] +) +Symbol['P' 1200] +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[1000 1000 2714 1000 800] + SymbolLine[2714 1000 3285 1191 800] + SymbolLine[3285 1191 3476 1381 800] + SymbolLine[3476 1381 3666 1762 800] + SymbolLine[3666 1762 3666 2334 800] + SymbolLine[3666 2334 3476 2714 800] + SymbolLine[3476 2714 3285 2905 800] + SymbolLine[3285 2905 2714 3095 800] + SymbolLine[2714 3095 1000 3095 800] +) +Symbol['Q' 1200] +( + SymbolLine[2142 1000 1762 1191 800] + SymbolLine[1762 1191 1380 1572 800] + SymbolLine[1380 1572 1190 1952 800] + SymbolLine[1190 1952 1000 2524 800] + SymbolLine[1000 2524 1000 3476 800] + SymbolLine[1000 3476 1190 4048 800] + SymbolLine[1190 4048 1380 4429 800] + SymbolLine[1380 4429 1762 4809 800] + SymbolLine[1762 4809 2142 5000 800] + SymbolLine[2142 5000 2905 5000 800] + SymbolLine[2905 5000 3285 4809 800] + SymbolLine[3285 4809 3666 4429 800] + SymbolLine[3666 4429 3857 4048 800] + SymbolLine[3857 4048 4047 3476 800] + SymbolLine[4047 3476 4047 2524 800] + SymbolLine[4047 2524 3857 1952 800] + SymbolLine[3857 1952 3666 1572 800] + SymbolLine[3666 1572 3285 1191 800] + SymbolLine[3285 1191 2905 1000 800] + SymbolLine[2905 1000 2142 1000 800] + SymbolLine[2714 4238 3857 5381 800] +) +Symbol['R' 1200] +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[1000 1000 2714 1000 800] + SymbolLine[2714 1000 3285 1191 800] + SymbolLine[3285 1191 3476 1381 800] + SymbolLine[3476 1381 3666 1762 800] + SymbolLine[3666 1762 3666 2143 800] + SymbolLine[3666 2143 3476 2524 800] + SymbolLine[3476 2524 3285 2714 800] + SymbolLine[3285 2714 2714 2905 800] + SymbolLine[2714 2905 1000 2905 800] + SymbolLine[2333 2905 3666 5000 800] +) +Symbol['S' 1200] +( + SymbolLine[3666 1572 3285 1191 800] + SymbolLine[3285 1191 2714 1000 800] + SymbolLine[2714 1000 1952 1000 800] + SymbolLine[1952 1000 1380 1191 800] + SymbolLine[1380 1191 1000 1572 800] + SymbolLine[1000 1572 1000 1952 800] + SymbolLine[1000 1952 1189 2334 800] + SymbolLine[1189 2334 1380 2524 800] + SymbolLine[1380 2524 1762 2714 800] + SymbolLine[1762 2714 2905 3095 800] + SymbolLine[2905 3095 3285 3286 800] + SymbolLine[3285 3286 3475 3476 800] + SymbolLine[3475 3476 3666 3857 800] + SymbolLine[3666 3857 3666 4429 800] + SymbolLine[3666 4429 3285 4809 800] + SymbolLine[3285 4809 2714 5000 800] + SymbolLine[2714 5000 1952 5000 800] + SymbolLine[1952 5000 1380 4809 800] + SymbolLine[1380 4809 1000 4429 800] +) +Symbol['T' 1200] +( + SymbolLine[2333 1000 2333 5000 800] + SymbolLine[1000 1000 3666 1000 800] +) +Symbol['U' 1200] +( + SymbolLine[1000 1000 1000 3857 800] + SymbolLine[1000 3857 1191 4429 800] + SymbolLine[1191 4429 1571 4809 800] + SymbolLine[1571 4809 2143 5000 800] + SymbolLine[2143 5000 2523 5000 800] + SymbolLine[2523 5000 3095 4809 800] + SymbolLine[3095 4809 3476 4429 800] + SymbolLine[3476 4429 3666 3857 800] + SymbolLine[3666 3857 3666 1000 800] + +) +Symbol['V' 1200] +( + SymbolLine[1000 1000 2523 5000 800] + SymbolLine[4048 1000 2523 5000 800] +) +Symbol['W' 1200] +( + SymbolLine[1000 1000 1952 5000 800] + SymbolLine[2905 1000 1952 5000 800] + SymbolLine[2905 1000 3857 5000 800] + SymbolLine[4809 1000 3857 5000 800] +) +Symbol['X' 1200] +( + SymbolLine[1000 1000 3666 5000 800] + SymbolLine[3666 1000 1000 5000 800] +) +Symbol['Y' 1200] +( + SymbolLine[1000 1000 2523 2905 800] + SymbolLine[2523 2905 2523 5000 800] + SymbolLine[4048 1000 2523 2905 800] +) +Symbol['Z' 1200] +( + SymbolLine[3666 1000 1000 5000 800] + SymbolLine[1000 1000 3666 1000 800] + SymbolLine[1000 5000 3666 5000 800] +) +Symbol['[' 1200] +( + SymbolLine[1000 0 1000 6094 800] + SymbolLine[1191 0 1191 6094 800] + SymbolLine[1000 0 2334 0 800] + SymbolLine[1000 6094 2334 6094 800] +) +Symbol['\' 1200] +( + SymbolLine[1000 1000 3251 5000 800] + +) +Symbol[']' 1200] +( + SymbolLine[7666 0 7666 6094 800] + SymbolLine[7857 0 7857 6094 800] + SymbolLine[6524 0 7857 0 800] + SymbolLine[6524 6094 7857 6094 800] +) +Symbol['^' 1200] +( + SymbolLine[2523 1000 1000 3222 800] + SymbolLine[2523 1000 4046 3222 800] +) +Symbol['_' 1200] +( +SymbolLine[1000 5000 3500 5000 800] +) +Symbol['a' 1200] #new +( + SymbolLine[3286 2333 3286 4999 800] + SymbolLine[3286 2903 2904 2522 800] + SymbolLine[2904 2522 2524 2333 800] + SymbolLine[2524 2333 1952 2333 800] + SymbolLine[1952 2333 1572 2522 800] + SymbolLine[1572 2522 1190 2903 800] + SymbolLine[1190 2903 1000 3474 800] + SymbolLine[1000 3474 1000 3856 800] + SymbolLine[1000 3856 1190 4427 800] + SymbolLine[1190 4427 1572 4808 800] + SymbolLine[1572 4808 1952 4999 800] + SymbolLine[1952 4999 2524 4999 800] + SymbolLine[2524 4999 2904 4808 800] + SymbolLine[2904 4808 3286 4427 800] +) +Symbol['b' 1200] #new +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[1000 2904 1381 2523 800] + SymbolLine[1381 2523 1761 2333 800] + SymbolLine[1761 2333 2333 2333 800] + SymbolLine[2333 2333 2713 2523 800] + SymbolLine[2713 2523 3095 2904 800] + SymbolLine[3095 2904 3286 3475 800] + SymbolLine[3286 3475 3286 3856 800] + SymbolLine[3286 3856 3095 4427 800] + SymbolLine[3095 4427 2713 4809 800] + SymbolLine[2713 4809 2333 5000 800] + SymbolLine[2333 5000 1761 5000 800] + SymbolLine[1761 5000 1381 4809 800] + SymbolLine[1381 4809 1000 4427 800] +) + +Symbol['c' 1200] #new +( + SymbolLine[3286 2903 2904 2522 800] + SymbolLine[2904 2522 2524 2333 800] + SymbolLine[2524 2333 1952 2333 800] + SymbolLine[1952 2333 1572 2522 800] + SymbolLine[1572 2522 1190 2903 800] + SymbolLine[1190 2903 1000 3474 800] + SymbolLine[1000 3474 1000 3856 800] + SymbolLine[1000 3856 1190 4427 800] + SymbolLine[1190 4427 1572 4808 800] + SymbolLine[1572 4808 1952 4999 800] + SymbolLine[1952 4999 2524 4999 800] + SymbolLine[2524 4999 2904 4808 800] + SymbolLine[2904 4808 3286 4427 800] +) +Symbol['d' 1200] #new +( + SymbolLine[3284 1000 3284 5000 800] + SymbolLine[3284 2904 2904 2523 800] + SymbolLine[2904 2523 2523 2333 800] + SymbolLine[2523 2333 1952 2333 800] + SymbolLine[1952 2333 1570 2523 800] + SymbolLine[1570 2523 1189 2904 800] + SymbolLine[1189 2904 1000 3475 800] + SymbolLine[1000 3475 1000 3856 800] + SymbolLine[1000 3856 1189 4427 800] + SymbolLine[1189 4427 1570 4809 800] + SymbolLine[1570 4809 1952 5000 800] + SymbolLine[1952 5000 2523 5000 800] + SymbolLine[2523 5000 2904 4809 800] + SymbolLine[2904 4809 3284 4427 800] +) +Symbol['e' 1200] #NEW +( + SymbolLine[1000 3474 3284 3474 800] + SymbolLine[3284 3474 3284 3094 800] + SymbolLine[3284 3094 3094 2713 800] + SymbolLine[3094 2713 2904 2522 800] + SymbolLine[2904 2522 2523 2333 800] + SymbolLine[2523 2333 1952 2333 800] + SymbolLine[1952 2333 1570 2522 800] + SymbolLine[1570 2522 1189 2903 800] + SymbolLine[1189 2903 1000 3474 800] + SymbolLine[1000 3474 1000 3856 800] + SymbolLine[1000 3856 1189 4427 800] + SymbolLine[1189 4427 1570 4808 800] + SymbolLine[1570 4808 1952 4999 800] + SymbolLine[1952 4999 2523 4999 800] + SymbolLine[2523 4999 2904 4808 800] + SymbolLine[2904 4808 3284 4427 800] +) + +Symbol['f' 1200] #new +( + SymbolLine[2523 1000 2143 1000 800] + SymbolLine[2143 1000 1761 1190 800] + SymbolLine[1761 1190 1570 1761 800] + SymbolLine[1570 1761 1570 5000 800] + SymbolLine[1000 2333 2333 2333 800] +) + +Symbol['g' 1200] #NEW +( + SymbolLine[3286 2333 3286 5379 800] + SymbolLine[3286 5379 3095 5951 800] + SymbolLine[3095 5951 2904 6142 800] + SymbolLine[2904 6142 2524 6331 800] + SymbolLine[2524 6331 1952 6331 800] + SymbolLine[1952 6331 1572 6142 800] + SymbolLine[3286 2903 2904 2522 800] + SymbolLine[2904 2522 2524 2333 800] + SymbolLine[2524 2333 1952 2333 800] + SymbolLine[1952 2333 1572 2522 800] + SymbolLine[1572 2522 1190 2903 800] + SymbolLine[1190 2903 1000 3474 800] + SymbolLine[1000 3474 1000 3856 800] + SymbolLine[1000 3856 1190 4427 800] + SymbolLine[1190 4427 1572 4808 800] + SymbolLine[1572 4808 1952 4999 800] + SymbolLine[1952 4999 2524 4999 800] + SymbolLine[2524 4999 2904 4808 800] + SymbolLine[2904 4808 3286 4427 800] +) +Symbol['h' 1200] #new +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[1000 3095 1570 2523 800] + SymbolLine[1570 2523 1952 2333 800] + SymbolLine[1952 2333 2523 2333 800] + SymbolLine[2523 2333 2904 2523 800] + SymbolLine[2904 2523 3095 3095 800] + SymbolLine[3095 3095 3095 5000 800] +) + +Symbol['i' 1200] #new +( + SymbolLine[1190 2324 1190 4990 800] + SymbolLine[1000 990 1190 1181 800] + SymbolLine[1190 1181 1381 990 800] + SymbolLine[1381 990 1190 800 800] + SymbolLine[1190 800 1000 990 800] +) +Symbol['j' 1200] #new +( + SymbolLine[1952 2324 1952 5561 800] + SymbolLine[1952 5561 1761 6133 800] + SymbolLine[1761 6133 1380 6323 800] + SymbolLine[1380 6323 1000 6323 800] + SymbolLine[1761 990 1952 1181 800] + SymbolLine[1952 1181 2143 990 800] + SymbolLine[2143 990 1952 800 800] + SymbolLine[1952 800 1761 990 800] +) +Symbol['k' 1200] #new +( + SymbolLine[1000 1000 1000 5000 800] + SymbolLine[2904 2333 1000 4238 800] + SymbolLine[1761 3475 3095 5000 800] +) + +Symbol['l' 1200] #new +( + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['m' 1200] #new +( + SymbolLine[1000 2333 1000 4999 800] + SymbolLine[1000 3094 1570 2522 800] + SymbolLine[1570 2522 1952 2333 800] + SymbolLine[1952 2333 2523 2333 800] + SymbolLine[2523 2333 2904 2522 800] + SymbolLine[2904 2522 3094 3094 800] + SymbolLine[3094 3094 3094 4999 800] + SymbolLine[3094 3094 3666 2522 800] + SymbolLine[3666 2522 4046 2333 800] + SymbolLine[4046 2333 4618 2333 800] + SymbolLine[4618 2333 4998 2522 800] + SymbolLine[4998 2522 5189 3094 800] + SymbolLine[5189 3094 5189 4999 800] +) +Symbol['n' 1200] #new +( + SymbolLine[1000 2333 1000 4999 800] + SymbolLine[1000 3094 1572 2522 800] + SymbolLine[1572 2522 1952 2333 800] + SymbolLine[1952 2333 2524 2333 800] + SymbolLine[2524 2333 2904 2522 800] + SymbolLine[2904 2522 3095 3094 800] + SymbolLine[3095 3094 3095 4999 800] +) +Symbol['o' 1200] #new +( + SymbolLine[1952 2333 1570 2522 800] + SymbolLine[1570 2522 1189 2903 800] + SymbolLine[1189 2903 1000 3474 800] + SymbolLine[1000 3474 1000 3856 800] + SymbolLine[1000 3856 1189 4427 800] + SymbolLine[1189 4427 1570 4808 800] + SymbolLine[1570 4808 1952 4999 800] + SymbolLine[1952 4999 2523 4999 800] + SymbolLine[2523 4999 2904 4808 800] + SymbolLine[2904 4808 3284 4427 800] + SymbolLine[3284 4427 3475 3856 800] + SymbolLine[3475 3856 3475 3474 800] + SymbolLine[3475 3474 3284 2903 800] + SymbolLine[3284 2903 2904 2522 800] + SymbolLine[2904 2522 2523 2333 800] + SymbolLine[2523 2333 1952 2333 800] +) +Symbol['p' 1200] #new +( + SymbolLine[1000 2333 1000 6333 800] + SymbolLine[1000 2903 1381 2523 800] + SymbolLine[1381 2523 1761 2333 800] + SymbolLine[1761 2333 2333 2333 800] + SymbolLine[2333 2333 2714 2523 800] + SymbolLine[2714 2523 3095 2903 800] + SymbolLine[3095 2903 3286 3476 800] + SymbolLine[3286 3476 3286 3856 800] + SymbolLine[3286 3856 3095 4428 800] + SymbolLine[3095 4428 2714 4808 800] + SymbolLine[2714 4808 2333 4999 800] + SymbolLine[2333 4999 1761 4999 800] + SymbolLine[1761 4999 1381 4808 800] + SymbolLine[1381 4808 1000 4428 800] +) +Symbol['q' 1200] #new +( + SymbolLine[3285 2333 3285 6333 800] + SymbolLine[3285 2903 2904 2523 800] + SymbolLine[2904 2523 2524 2333 800] + SymbolLine[2524 2333 1952 2333 800] + SymbolLine[1952 2333 1571 2523 800] + SymbolLine[1571 2523 1190 2903 800] + SymbolLine[1190 2903 1000 3476 800] + SymbolLine[1000 3476 1000 3856 800] + SymbolLine[1000 3856 1190 4428 800] + SymbolLine[1190 4428 1571 4808 800] + SymbolLine[1571 4808 1952 4999 800] + SymbolLine[1952 4999 2524 4999 800] + SymbolLine[2524 4999 2904 4808 800] + SymbolLine[2904 4808 3285 4428 800] +) +Symbol['r' 1200] #new +( + SymbolLine[1000 2333 1000 4999 800] + SymbolLine[1000 3476 1190 2903 800] + SymbolLine[1190 2903 1572 2523 800] + SymbolLine[1572 2523 1952 2333 800] + SymbolLine[1952 2333 2524 2333 800] +) +Symbol['s' 1200] #new +( + SymbolLine[3094 2903 2904 2523 800] + SymbolLine[2904 2523 2332 2333 800] + SymbolLine[2332 2333 1761 2333 800] + SymbolLine[1761 2333 1189 2523 800] + SymbolLine[1189 2523 1000 2903 800] + SymbolLine[1000 2903 1189 3285 800] + SymbolLine[1189 3285 1570 3476 800] + SymbolLine[1570 3476 2523 3666 800] + SymbolLine[2523 3666 2904 3856 800] + SymbolLine[2904 3856 3094 4237 800] + SymbolLine[3094 4237 3094 4428 800] + SymbolLine[3094 4428 2904 4808 800] + SymbolLine[2904 4808 2332 4999 800] + SymbolLine[2332 4999 1761 4999 800] + SymbolLine[1761 4999 1189 4808 800] + SymbolLine[1189 4808 1000 4428 800] +) +Symbol['t' 1200] #new +( + SymbolLine[1572 1000 1572 4238 800] + SymbolLine[1572 4238 1761 4809 800] + SymbolLine[1761 4809 2143 5000 800] + SymbolLine[2143 5000 2524 5000 800] + SymbolLine[1000 2333 2333 2333 800] +) +Symbol['u' 1200] #new +( + SymbolLine[1000 2333 1000 4237 800] + SymbolLine[1000 4237 1190 4808 800] + SymbolLine[1190 4808 1572 4999 800] + SymbolLine[1572 4999 2143 4999 800] + SymbolLine[2143 4999 2524 4808 800] + SymbolLine[2524 4808 3095 4237 800] + SymbolLine[3095 2333 3095 4999 800] +) + +Symbol['v' 1200] #new +( + SymbolLine[1000 2333 2142 4999 800] + SymbolLine[3284 2333 2142 4999 800] +) + +Symbol['w' 1200] #new +( + SymbolLine[1000 2333 1761 4999 800] + SymbolLine[2523 2333 1761 4999 800] + SymbolLine[2523 2333 3286 4999 800] + SymbolLine[4047 2333 3286 4999 800] +) +Symbol['x' 1200] #new +( + SymbolLine[1000 2333 3095 4999 800] + SymbolLine[3095 2333 1000 4999 800] +) + + +Symbol['y' 1200] #new +( + SymbolLine[1190 2333 2333 4999 800] + SymbolLine[3476 2333 2333 4999 800] + SymbolLine[2333 4999 1952 5760 800] + SymbolLine[1952 5760 1572 6142 800] + SymbolLine[1572 6142 1190 6333 800] + SymbolLine[1190 6333 1000 6333 800] +) +Symbol['z' 1200] #new +( + SymbolLine[3095 2333 1000 4999 800] + SymbolLine[1000 2333 3095 2333 800] + SymbolLine[1000 4999 3095 4999 800] +) +Symbol['{' 1200] +( + SymbolLine[1952 0 1572 191 800] + SymbolLine[1572 191 1381 380 800] + SymbolLine[1381 380 1191 762 800] + SymbolLine[1191 762 1191 1143 800] + SymbolLine[1191 1143 1381 1523 800] + SymbolLine[1381 1523 1572 1714 800] + SymbolLine[1572 1714 1763 2095 800] + SymbolLine[1763 2095 1763 2475 800] + SymbolLine[1763 2475 1381 2857 800] + SymbolLine[1572 191 1381 571 800] + SymbolLine[1381 571 1381 952 800] + SymbolLine[1381 952 1572 1332 800] + SymbolLine[1572 1332 1763 1523 800] + SymbolLine[1763 1523 1952 1905 800] + SymbolLine[1952 1905 1952 2285 800] + SymbolLine[1952 2285 1763 2666 800] + SymbolLine[1763 2666 1000 3048 800] + SymbolLine[1000 3048 1763 3428 800] + SymbolLine[1763 3428 1952 3809 800] + SymbolLine[1952 3809 1952 4189 800] + SymbolLine[1952 4189 1763 4571 800] + SymbolLine[1763 4571 1572 4761 800] + SymbolLine[1572 4761 1381 5142 800] + SymbolLine[1381 5142 1381 5523 800] + SymbolLine[1381 5523 1572 5904 800] + SymbolLine[1381 3237 1763 3619 800] + SymbolLine[1763 3619 1763 4000 800] + SymbolLine[1763 4000 1572 4380 800] + SymbolLine[1572 4380 1381 4571 800] + SymbolLine[1381 4571 1191 4952 800] + SymbolLine[1191 4952 1191 5332 800] + SymbolLine[1191 5332 1381 5714 800] + SymbolLine[1381 5714 1572 5904 800] + SymbolLine[1572 5904 1952 6094 800] +) +Symbol['|' 1200] +( + SymbolLine[1000 250 1000 5750 800] +) +Symbol['}' 1200] +( + SymbolLine[1000 0 1381 191 800] + SymbolLine[1381 191 1572 380 800] + SymbolLine[1572 380 1762 762 800] + SymbolLine[1762 762 1762 1143 800] + SymbolLine[1762 1143 1572 1523 800] + SymbolLine[1572 1523 1381 1714 800] + SymbolLine[1381 1714 1191 2095 800] + SymbolLine[1191 2095 1191 2475 800] + SymbolLine[1191 2475 1572 2857 800] + SymbolLine[1381 191 1572 571 800] + SymbolLine[1572 571 1572 952 800] + SymbolLine[1572 952 1381 1332 800] + SymbolLine[1381 1332 1191 1523 800] + SymbolLine[1191 1523 1000 1905 800] + SymbolLine[1000 1905 1000 2285 800] + SymbolLine[1000 2285 1191 2666 800] + SymbolLine[1191 2666 1952 3048 800] + SymbolLine[1952 3048 1191 3428 800] + SymbolLine[1191 3428 1000 3809 800] + SymbolLine[1000 3809 1000 4189 800] + SymbolLine[1000 4189 1191 4571 800] + SymbolLine[1191 4571 1381 4761 800] + SymbolLine[1381 4761 1572 5142 800] + SymbolLine[1572 5142 1572 5523 800] + SymbolLine[1572 5523 1381 5904 800] + SymbolLine[1572 3237 1191 3619 800] + SymbolLine[1191 3619 1191 4000 800] + SymbolLine[1191 4000 1381 4380 800] + SymbolLine[1381 4380 1572 4571 800] + SymbolLine[1572 4571 1762 4952 800] + SymbolLine[1762 4952 1762 5332 800] + SymbolLine[1762 5332 1572 5714 800] + SymbolLine[1572 5714 1381 5904 800] + SymbolLine[1381 5904 1000 6094 800] +) +Symbol['~' 1200] +( + SymbolLine[1000 3643 1000 3262 800] + SymbolLine[1000 3262 1191 2691 800] + SymbolLine[1191 2691 1572 2500 800] + SymbolLine[1572 2500 1952 2500 800] + SymbolLine[1952 2500 2334 2691 800] + SymbolLine[2334 2691 3095 3262 800] + SymbolLine[3095 3262 3477 3452 800] + SymbolLine[3477 3452 3857 3452 800] + SymbolLine[3857 3452 4238 3262 800] + SymbolLine[4238 3262 4429 2881 800] + SymbolLine[1000 3262 1191 2881 800] + SymbolLine[1191 2881 1572 2691 800] + SymbolLine[1572 2691 1952 2691 800] + SymbolLine[1952 2691 2334 2881 800] + SymbolLine[2334 2881 3095 3452 800] + SymbolLine[3095 3452 3477 3643 800] + SymbolLine[3477 3643 3857 3643 800] + SymbolLine[3857 3643 4238 3452 800] + SymbolLine[4238 3452 4429 2881 800] + SymbolLine[4429 2881 4429 2500 800] +) + Index: tags/2.3.0/font/default_arc.lht =================================================================== --- tags/2.3.0/font/default_arc.lht (nonexistent) +++ tags/2.3.0/font/default_arc.lht (revision 33253) @@ -0,0 +1,2856 @@ +li:pcb-rnd-font-v1 { + ha:geda_pcb { + id = 0 + ha:symbols { + + ha:&20 { + width = 0.4mm + delta = 14.0mil + li:objects { + } + height = 1.373633mm + } + ha:] { + width = 0.127001mm + delta = 14.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 14.08mil + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + ha:&5c { + width = 0.762001mm + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 1.246632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 30.0mil + y1 = 0.484632mm + } + } + height = 1.246633mm + } + ha:b { + width = 0.713756mm + delta = 4.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.104909mm + x2 = 0.104909mm + y1 = 14.08mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -360.000000 + astart = 20.000000 + x = 0.356877mm + y = 44.0mil + r = 0.253245mm + } + } + height = 1.474479mm + } + ha:c { + width = 0.611633mm + delta = 0.203723mm + li:objects { + ha:line.0 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.357631mm + x2 = 0.611632mm + y1 = 34.0mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.357631mm + x2 = 0.611632mm + y1 = 54.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -180.000000 + astart = 90.000000 + x = 14.08mil + y = 44.0mil + r = 10.0mil + } + } + height = 1.475234mm + } + ha:d { + width = 0.713756mm + delta = 4.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.612909mm + x2 = 0.612909mm + y1 = 14.08mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -360.000000 + astart = 20.000000 + x = 0.356877mm + y = 44.0mil + r = 0.253245mm + } + } + height = 1.474479mm + } + ha:e { + width = 0.715266mm + delta = 0.152923mm + li:objects { + ha:line.0 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 4.08mil + x2 = 0.611632mm + y1 = 1.119632mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.357631mm + x2 = 0.611632mm + y1 = 1.373632mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 270.000000 + astart = 180.000000 + x = 14.08mil + y = 1.119632mm + r = 10.0mil + } + } + height = 1.477266mm + } + ha:f { + width = 0.484634mm + delta = 4.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 25.0mil + } + ha:line.1 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 0.865632mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 15.0mil + y = 0.611632mm + r = 10.0mil + } + } + height = 1.373633mm + } + ha:g { + width = 0.713756mm + delta = 0.128279mm + li:objects { + ha:line.0 { + y2 = 1.754632mm + thickness = 8.0mil + x1 = 0.104909mm + x2 = 0.231909mm + y1 = 1.627632mm + } + ha:line.1 { + y2 = 1.754632mm + thickness = 8.0mil + x1 = 0.231909mm + x2 = 0.485909mm + y1 = 1.754632mm + } + ha:line.2 { + y2 = 1.627632mm + thickness = 8.0mil + x1 = 0.485909mm + x2 = 0.612909mm + y1 = 1.754632mm + } + ha:line.3 { + y2 = 1.627632mm + thickness = 8.0mil + x1 = 0.612909mm + x2 = 0.612909mm + y1 = 0.865632mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -360.000000 + astart = 20.000000 + x = 0.356877mm + y = 44.0mil + r = 0.253245mm + } + } + height = 1.754633mm + } + ha:h { + width = 0.703348mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.095849mm + x2 = 0.095849mm + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.603849mm + x2 = 0.603849mm + y1 = 45.0mil + } + ha:line.2 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 0.600341mm + x2 = 0.603849mm + y1 = 1.017392mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -132.000000 + astart = 334.000000 + x = 0.347817mm + y = 44.0mil + r = 0.27168mm + } + } + height = 1.373633mm + } + ha:i { + width = 0.001um + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 0.637032mm + thickness = 10.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 0.611632mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 0.992632mm + } + } + height = 1.373633mm + } + ha:j { + width = 0.252632mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.637032mm + thickness = 10.0mil + x1 = 0.148998mm + x2 = 0.148998mm + y1 = 0.611632mm + } + ha:line.1 { + y2 = 1.576832mm + thickness = 8.0mil + x1 = 0.148998mm + x2 = 0.148998mm + y1 = 0.992632mm + } + ha:line.2 { + y2 = 1.754632mm + thickness = 8.0mil + x1 = 0.103944mm + x2 = 0.021998mm + y1 = 1.673856mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 50.000000 + astart = 130.000000 + x = 0.021998mm + y = 1.576832mm + r = 5.0mil + } + } + height = 1.777753mm + } + ha:k { + width = 0.381001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 0.992632mm + } + ha:line.2 { + y2 = 0.738632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 0.992632mm + } + } + height = 1.373633mm + } + ha:l { + width = 0.127001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 1.246632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 1.246632mm + } + } + height = 1.373633mm + } + ha:m { + width = 1.12574mm + delta = 0.148337mm + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 8.24mil + x2 = 8.24mil + y1 = 0.992632mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.615696mm + x2 = 0.615696mm + y1 = 0.992632mm + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 40.24mil + x2 = 40.24mil + y1 = 0.992632mm + } + ha:line.3 { + y2 = 0.967232mm + thickness = 8.0mil + x1 = 8.24mil + x2 = 8.16mil + y1 = 0.992632mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 4.08mil + y = 0.967232mm + r = 4.08mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -180.000000 + astart = 0.000000 + x = 32.32mil + y = 0.992632mm + r = 0.201178mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -180.000000 + astart = 0.000000 + x = 16.32mil + y = 0.992632mm + r = 0.201178mm + } + } + height = 1.373633mm + } + ha:n { + width = 0.71934mm + delta = 5.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 8.24mil + x2 = 8.24mil + y1 = 0.992632mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.615696mm + x2 = 0.615696mm + y1 = 0.992632mm + } + ha:line.2 { + y2 = 0.967232mm + thickness = 8.0mil + x1 = 8.24mil + x2 = 8.16mil + y1 = 0.992632mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 90.000000 + astart = 180.000000 + x = 4.08mil + y = 0.967232mm + r = 4.08mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -180.000000 + astart = 0.000000 + x = 16.32mil + y = 0.992632mm + r = 0.201178mm + } + } + height = 1.373633mm + } + ha:o { + width = 0.720439mm + delta = 0.132343mm + li:objects { + ha:simplearc.0 { + thickness = 8.0mil + adelta = -360.000000 + astart = 20.000000 + x = 13.92mil + y = 44.0mil + r = 0.263238mm + } + } + height = 1.269747mm + } + ha:p { + width = 0.735847mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.754632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 0.992632mm + } + ha:line.1 { + y2 = 0.992632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 0.865632mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -360.000000 + astart = 20.000000 + x = 14.92mil + y = 44.0mil + r = 0.253245mm + } + } + height = 1.754633mm + } + ha:q { + width = 0.713756mm + delta = 0.173737mm + li:objects { + ha:line.0 { + y2 = 1.754632mm + thickness = 8.0mil + x1 = 24.0mil + x2 = 0.612909mm + y1 = 34.0mil + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -360.000000 + astart = 20.000000 + x = 0.356877mm + y = 44.0mil + r = 0.253245mm + } + } + height = 1.754633mm + } + ha:r { + width = 0.534157mm + delta = 6.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 0.992632mm + } + ha:line.1 { + y2 = 0.992632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 0.865632mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -135.000000 + astart = 0.000000 + x = 12.0mil + y = 41.0mil + r = 7.0mil + } + } + height = 1.373633mm + } + ha:s { + width = 0.842266mm + delta = 6.0mil + li:objects { + ha:line.0 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 9.08mil + x2 = 0.611632mm + y1 = 1.119632mm + } + ha:line.1 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 9.08mil + x2 = 0.611632mm + y1 = 0.865632mm + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 9.08mil + x2 = 0.611632mm + y1 = 1.373632mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 180.000000 + astart = -90.000000 + x = 9.08mil + y = 0.992632mm + r = 5.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -52.403729 + astart = -90.000000 + x = 0.611632mm + y = 0.992632mm + r = 5.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 45.578726 + astart = 44.421274 + x = 9.08mil + y = 1.246632mm + r = 5.0mil + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -180.000000 + astart = -90.000000 + x = 0.611632mm + y = 1.246632mm + r = 5.0mil + } + } + height = 1.477266mm + } + ha:t { + width = 0.254001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 1.246632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 1.246632mm + } + ha:line.2 { + y2 = 0.738632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 0.738632mm + } + } + height = 1.373633mm + } + ha:u { + width = 0.711202mm + delta = 0.180588mm + li:objects { + ha:line.0 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 3.92mil + x2 = 3.92mil + y1 = 0.865632mm + } + ha:line.1 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 23.92mil + x2 = 23.92mil + y1 = 0.865632mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 180.000000 + astart = 0.000000 + x = 14.0mil + y = 45.0mil + r = 9.92mil + } + } + height = 1.498602mm + } + ha:v { + width = 0.508001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 0.865632mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 20.0mil + x2 = 10.0mil + y1 = 0.865632mm + } + } + height = 1.373633mm + } + ha:w { + width = 1.02639mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 1.170432mm + thickness = 8.0mil + x1 = 0.10414mm + x2 = 4.08mil + y1 = 0.86106mm + } + ha:line.1 { + y2 = 0.86106mm + thickness = 8.0mil + x1 = 0.514153mm + x2 = 0.514153mm + y1 = 1.15316mm + } + ha:line.2 { + y2 = 34.0mil + thickness = 8.0mil + x1 = 0.923093mm + x2 = 0.923093mm + y1 = 45.5mil + } + ha:line.3 { + y2 = 1.170432mm + thickness = 8.0mil + x1 = 0.514153mm + x2 = 0.513194mm + y1 = 1.15316mm + } + ha:line.4 { + y2 = 1.170432mm + thickness = 8.0mil + x1 = 0.923093mm + x2 = 0.922756mm + y1 = 45.5mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 180.000000 + astart = 0.000000 + x = 0.717975mm + y = 1.170432mm + r = 0.204781mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = 180.000000 + astart = 0.000000 + x = 0.308413mm + y = 1.170432mm + r = 0.204781mm + } + } + height = 1.478847mm + } + ha:x { + width = 0.508001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.865632mm + } + ha:line.1 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + ha:y { + width = 0.711202mm + delta = 6.0mil + li:objects { + ha:line.0 { + y2 = 45.0mil + thickness = 8.0mil + x1 = 3.92mil + x2 = 3.92mil + y1 = 0.865632mm + } + ha:line.1 { + y2 = 60.0mil + thickness = 8.0mil + x1 = 23.92mil + x2 = 23.92mil + y1 = 0.865632mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 156.225135 + astart = 23.774865 + x = 14.0mil + y = 60.0mil + r = 9.92mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 180.000000 + astart = 0.000000 + x = 14.0mil + y = 45.0mil + r = 9.92mil + } + } + height = 1.879602mm + } + ha:z { + width = 0.508001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.865632mm + } + ha:line.1 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 1.373632mm + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + ha:~ { + width = 0.829902mm + delta = 8.08mil + li:objects { + ha:simplearc.0 { + thickness = 8.0mil + adelta = -152.513380 + astart = 0.000000 + x = 10.08mil + y = 0.992632mm + r = 0.169501mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -152.513380 + astart = 180.000000 + x = 21.92mil + y = 32.92mil + r = 0.169501mm + } + } + height = 0.925323mm + } + ha:&7b { + width = 0.254001mm + delta = 14.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 0.484632mm + } + ha:line.1 { + y2 = 0.738632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 0.484632mm + } + ha:line.2 { + y2 = 0.738632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 0.865632mm + } + ha:line.3 { + y2 = 0.992632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 0.865632mm + } + ha:line.4 { + y2 = 1.246632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 0.992632mm + } + ha:line.5 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 1.246632mm + } + } + height = 1.373633mm + } + ha:&7d { + width = 0.254001mm + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 0.484632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 0.738632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 0.484632mm + } + ha:line.2 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 0.738632mm + } + ha:line.3 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 0.992632mm + } + ha:line.4 { + y2 = 1.246632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 0.992632mm + } + ha:line.5 { + y2 = 1.246632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + ha:| { + width = 0.001um + delta = 15.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + } + height = 1.373633mm + } + ha:&23 { + width = 0.508001mm + delta = 12.0mil + li:objects { + ha:line.0 { + y2 = 0.992632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.992632mm + } + ha:line.1 { + y2 = 0.738632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.738632mm + } + ha:line.2 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 15.0mil + x2 = 15.0mil + y1 = 0.611632mm + } + ha:line.3 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 0.611632mm + } + } + height = 1.119633mm + } + ha:&26 { + width = 0.765439mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 8.0mil + x2 = 0.765438mm + y1 = 32.0mil + } + ha:line.1 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 8.0mil + x2 = 6.0mil + y1 = 32.0mil + } + ha:line.2 { + y2 = 0.703086mm + thickness = 8.0mil + x1 = 0.159004mm + x2 = 0.477924mm + y1 = 0.993314mm + } + ha:line.3 { + y2 = 44.0mil + thickness = 8.0mil + x1 = 0.520801mm + x2 = 0.689238mm + y1 = 1.276688mm + } + ha:line.4 { + y2 = 28.0mil + thickness = 8.0mil + x1 = 0.134492mm + x2 = 6.0mil + y1 = 0.560832mm + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -185.000000 + astart = 144.000000 + x = 0.333638mm + y = 45.0mil + r = 0.230006mm + } + ha:simplearc.6 { + thickness = 8.0mil + adelta = -225.000000 + astart = 0.000000 + x = 0.33567mm + y = 0.560832mm + r = 0.201178mm + } + } + height = 1.47664mm + } + ha:! { + width = 0.001um + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 1.246632mm + } + ha:line.1 { + y2 = 0.992632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + } + height = 1.373633mm + } + ha:" { + width = 0.254001mm + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 0.611632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + ha:line.1 { + y2 = 0.611632mm + thickness = 8.0mil + x1 = 10.0mil + x2 = 10.0mil + y1 = 14.08mil + } + } + height = 0.611633mm + } + ha:$ { + width = 0.735821mm + delta = 8.0mil + li:objects { + ha:line.0 { + y2 = 65.0mil + thickness = 8.0mil + x1 = 0.381596mm + x2 = 0.381596mm + y1 = 10.0mil + } + ha:line.1 { + y2 = 0.954693mm + thickness = 8.0mil + x1 = 0.308266mm + x2 = 0.436371mm + y1 = 0.931603mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 227.000000 + astart = 25.000000 + x = 0.353178mm + y = 47.92mil + r = 0.275343mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 229.000000 + astart = 205.000000 + x = 0.382642mm + y = 0.666496mm + r = 0.275343mm + } + } + height = 1.651001mm + } + ha:% { + width = 1.274066mm + delta = 7.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 5.08mil + x2 = 1.145032mm + y1 = 1.373632mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = -353.000000 + astart = 0.000000 + x = 0.967232mm + y = 1.195832mm + r = 8.0mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -353.000000 + astart = 0.000000 + x = 12.08mil + y = 0.535432mm + r = 8.0mil + } + } + height = 1.502666mm + } + ha:' { + width = 0.254001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 0.611632mm + } + } + height = 0.611633mm + } + ha:( { + width = 0.299452mm + delta = 0.068708mm + li:objects { + ha:line.0 { + y2 = 46.0mil + thickness = 8.0mil + x1 = 0.104704mm + x2 = 0.104704mm + y1 = 22.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 0.194119mm + x2 = 8.0mil + y1 = 1.367332mm + } + ha:line.2 { + y2 = 14.0mil + thickness = 8.0mil + x1 = 0.195191mm + x2 = 8.0mil + y1 = 0.363931mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 50.000000 + astart = -50.000000 + x = 0.359776mm + y = 22.0mil + r = 0.255072mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -50.000000 + astart = 50.000000 + x = 0.358704mm + y = 1.172464mm + r = 0.255072mm + } + } + height = 1.471494mm + } + ha:) { + width = 0.299453mm + delta = 0.123115mm + li:objects { + ha:line.0 { + y2 = 46.0mil + thickness = 8.0mil + x1 = 0.194747mm + x2 = 0.194747mm + y1 = 22.0mil + } + ha:line.1 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 0.105332mm + x2 = 0.096251mm + y1 = 1.367332mm + } + ha:line.2 { + y2 = 14.0mil + thickness = 8.0mil + x1 = 0.10426mm + x2 = 0.096251mm + y1 = 0.363931mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -50.000000 + astart = 230.000000 + x = -60.325um + y = 22.0mil + r = 0.255072mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 50.000000 + astart = 130.000000 + x = -59.253um + y = 1.172464mm + r = 0.255072mm + } + } + height = 1.471494mm + } + ha:* { + width = 0.508001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.611632mm + } + ha:line.1 { + y2 = 0.611632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 1.119632mm + } + ha:line.2 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.865632mm + } + ha:line.3 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 10.0mil + x2 = 10.0mil + y1 = 0.611632mm + } + } + height = 1.119633mm + } + ha:+ { + width = 0.508001mm + delta = 12.0mil + li:objects { + ha:line.0 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.865632mm + } + ha:line.1 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 10.0mil + x2 = 10.0mil + y1 = 0.611632mm + } + } + height = 1.119633mm + } + ha:, { + width = 0.254001mm + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 1.627632mm + } + } + height = 1.627633mm + } + ha:- { + width = 0.508001mm + delta = 14.0mil + li:objects { + ha:line.0 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.865632mm + } + } + height = 0.865633mm + } + ha:. { + width = 0.127001mm + delta = 12.0mil + li:objects { + ha:line.0 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 54.0mil + } + } + height = 1.371601mm + } + ha:0 { + width = 0.715266mm + delta = 6.0mil + li:objects { + ha:line.0 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 4.08mil + x2 = 4.08mil + y1 = 0.611632mm + } + ha:line.1 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 0.611632mm + x2 = 0.611632mm + y1 = 0.611632mm + } + ha:line.2 { + y2 = 0.611632mm + thickness = 8.0mil + x1 = 4.08mil + x2 = 0.611632mm + y1 = 1.119632mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -180.000000 + astart = 180.000000 + x = 14.08mil + y = 1.119632mm + r = 10.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -180.000000 + astart = 0.000000 + x = 14.08mil + y = 0.611632mm + r = 10.0mil + } + } + height = 1.477266mm + } + ha:1 { + width = 0.381001mm + delta = 9.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 8.0mil + y1 = 0.560832mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 8.0mil + x2 = 8.0mil + y1 = 14.08mil + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + ha:2 { + width = 0.816866mm + delta = 6.0mil + li:objects { + ha:line.0 { + y2 = 0.80676mm + thickness = 8.0mil + x1 = 3.08mil + x2 = 0.642585mm + y1 = 1.373632mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 3.08mil + x2 = 0.713232mm + y1 = 1.373632mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -220.000000 + astart = 0.000000 + x = 0.408432mm + y = 0.611632mm + r = 12.0mil + } + } + height = 1.373633mm + } + ha:3 { + width = 0.744275mm + delta = 6.0mil + li:objects { + ha:line.0 { + y2 = 0.814832mm + thickness = 8.0mil + x1 = 12.4419685mil + x2 = 0.466389mm + y1 = 0.814832mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 221.000000 + astart = 27.000000 + x = 0.356661mm + y = 42.38mil + r = 0.28398mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -218.000000 + astart = 337.000000 + x = 0.341421mm + y = 0.593852mm + r = 10.0mil + } + } + height = 1.464066mm + } + ha:4 { + width = 0.635001mm + delta = 9.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.992632mm + } + ha:line.1 { + y2 = 0.992632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 25.0mil + y1 = 0.992632mm + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 20.0mil + x2 = 20.0mil + y1 = 14.08mil + } + } + height = 1.373633mm + } + ha:5 { + width = 0.762551mm + delta = 5.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.105039mm + x2 = 0.613039mm + y1 = 14.08mil + } + ha:line.1 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.105039mm + x2 = 0.105039mm + y1 = 14.08mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -261.000000 + astart = 315.000000 + x = 0.333639mm + y = 1.068832mm + r = 0.325278mm + } + } + height = 1.497744mm + } + ha:6 { + width = 0.725326mm + delta = 4.0mil + li:objects { + ha:line.0 { + y2 = 0.611632mm + thickness = 8.0mil + x1 = 0.10414mm + x2 = 0.10414mm + y1 = 1.094232mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 154.000000 + astart = 207.000000 + x = 0.362662mm + y = 0.611632mm + r = 0.25903mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 360.000000 + astart = 99.000000 + x = 0.362662mm + y = 1.094232mm + r = 0.25903mm + } + } + height = 1.456896mm + } + ha:7 { + width = 0.635001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 5.0mil + x2 = 25.0mil + y1 = 1.373632mm + } + ha:line.1 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 25.0mil + y1 = 14.08mil + } + } + height = 1.373633mm + } + ha:8 { + width = 0.718263mm + delta = 6.0mil + li:objects { + ha:simplearc.0 { + thickness = 8.0mil + adelta = 360.000000 + astart = 99.000000 + x = 14.0mil + y = 0.611632mm + r = 0.25903mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 360.000000 + astart = 99.000000 + x = 14.0mil + y = 1.119632mm + r = 0.25903mm + } + } + height = 1.270001mm + } + ha:9 { + width = 0.725326mm + delta = 6.0mil + li:objects { + ha:line.0 { + y2 = 1.094232mm + thickness = 8.0mil + x1 = 24.5mil + x2 = 24.5mil + y1 = 0.611632mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 153.000000 + astart = 27.000000 + x = 0.362662mm + y = 1.094232mm + r = 0.25903mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 360.000000 + astart = 279.000000 + x = 0.362662mm + y = 0.611632mm + r = 0.25903mm + } + } + height = 1.456896mm + } + ha:< { + width = 0.254001mm + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 0.611632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 0.865632mm + } + ha:line.1 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 0.865632mm + } + } + height = 1.119633mm + } + ha:> { + width = 0.254001mm + delta = 12.0mil + li:objects { + ha:line.0 { + y2 = 0.840232mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 0.586232mm + } + ha:line.1 { + y2 = 0.840232mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 1.094232mm + } + } + height = 1.094233mm + } + ha:? { + width = 0.664986mm + delta = 5.0mil + li:objects { + ha:line.0 { + y2 = 0.711422mm + thickness = 8.0mil + x1 = 0.388699mm + x2 = 0.504827mm + y1 = 0.825376mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.32543mm + x2 = 0.32543mm + y1 = 1.322832mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 46.000000 + astart = 320.000000 + x = 0.586492mm + y = 0.992632mm + r = 0.25903mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 227.000000 + astart = 139.000000 + x = 0.332492mm + y = 0.560832mm + r = 0.22886mm + } + } + height = 1.373633mm + } + ha:@ { + width = 1.477266mm + delta = 6.0mil + li:objects { + ha:line.0 { + y2 = 0.484632mm + thickness = 8.0mil + x1 = 0.992632mm + x2 = 0.992632mm + y1 = 0.865632mm + } + ha:line.1 { + y2 = 0.992632mm + thickness = 8.0mil + x1 = 1.119631mm + x2 = 1.310047mm + y1 = 0.992632mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 90.000000 + astart = 0.000000 + x = 1.119632mm + y = 0.865632mm + r = 5.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -307.000000 + astart = 153.000000 + x = 0.738632mm + y = 0.738632mm + r = 10.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -314.000000 + astart = 112.000000 + x = 0.738632mm + y = 0.738632mm + r = 25.0mil + } + } + height = 1.477266mm + } + ha:A { + width = 0.635001mm + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 0.611632mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 25.0mil + x2 = 25.0mil + y1 = 0.611632mm + } + ha:line.2 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 25.0mil + y1 = 0.865632mm + } + ha:line.3 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 7.0mil + x2 = 18.0mil + y1 = 14.08mil + } + ha:line.4 { + y2 = 0.611632mm + thickness = 8.0mil + x1 = 18.0mil + x2 = 25.0mil + y1 = 14.08mil + } + ha:line.5 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 7.0mil + y1 = 0.611632mm + } + } + height = 1.373633mm + } + ha:B { + width = 0.865633mm + delta = 6.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 14.08mil + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.482598mm + x2 = 0.0 + y1 = 1.373632mm + } + ha:line.3 { + y2 = 0.814832mm + thickness = 8.0mil + x1 = 0.482599mm + x2 = 5.0mil + y1 = 0.814832mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 180.000000 + astart = 90.000000 + x = 0.482599mm + y = 1.094232mm + r = 11.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = 180.000000 + astart = 90.000000 + x = 20.0mil + y = 0.586232mm + r = 9.0mil + } + } + height = 1.477266mm + } + ha:C { + width = 0.611633mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.484632mm + x2 = 0.611632mm + y1 = 1.373632mm + } + ha:line.1 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.484632mm + x2 = 0.611632mm + y1 = 14.08mil + } + ha:line.2 { + y2 = 0.992632mm + thickness = 8.0mil + x1 = 4.08mil + x2 = 4.08mil + y1 = 0.738632mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = 90.000000 + astart = -90.000000 + x = 0.484632mm + y = 0.738632mm + r = 15.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -90.000000 + astart = 90.000000 + x = 0.484632mm + y = 0.992632mm + r = 15.0mil + } + } + height = 1.477266mm + } + ha:D { + width = 0.738634mm + delta = 9.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 14.08mil + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 1.373632mm + } + ha:line.3 { + y2 = 0.992632mm + thickness = 8.0mil + x1 = 25.0mil + x2 = 25.0mil + y1 = 0.738632mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = 90.000000 + astart = 90.000000 + x = 10.0mil + y = 0.992632mm + r = 15.0mil + } + ha:simplearc.5 { + thickness = 8.0mil + adelta = -90.000000 + astart = 270.000000 + x = 10.0mil + y = 0.738632mm + r = 15.0mil + } + } + height = 1.477266mm + } + ha:E { + width = 0.508001mm + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 0.814832mm + thickness = 8.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 0.814832mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 1.373632mm + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + ha:line.3 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 14.08mil + } + } + height = 1.373633mm + } + ha:F { + width = 0.508001mm + delta = 8.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + ha:line.1 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 14.08mil + } + ha:line.2 { + y2 = 0.814832mm + thickness = 8.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 0.814832mm + } + } + height = 1.373633mm + } + ha:G { + width = 0.816866mm + delta = 8.0mil + li:objects { + ha:line.0 { + y2 = 1.043432mm + thickness = 8.0mil + x1 = 4.08mil + x2 = 4.08mil + y1 = 0.637032mm + } + ha:line.1 { + y2 = 0.881916mm + thickness = 8.0mil + x1 = 0.648647mm + x2 = 0.399316mm + y1 = 0.881916mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -149.000000 + astart = 0.000000 + x = 16.0mil + y = 0.637032mm + r = 11.92mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -218.000000 + astart = 218.000000 + x = 16.16mil + y = 1.068832mm + r = 11.92mil + } + } + height = 1.475234mm + } + ha:H { + width = 0.635001mm + delta = 12.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 25.0mil + x2 = 25.0mil + y1 = 14.08mil + } + ha:line.2 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 25.0mil + y1 = 0.865632mm + } + } + height = 1.373633mm + } + ha:I { + width = 0.254001mm + delta = 9.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 14.08mil + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + ha:J { + width = 0.613666mm + delta = 9.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 12.08mil + x2 = 0.510032mm + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 0.510032mm + x2 = 0.510032mm + y1 = 14.08mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -180.000000 + astart = 180.000000 + x = 12.08mil + y = 1.170432mm + r = 8.0mil + } + } + height = 1.477266mm + } + ha:K { + width = 0.508001mm + delta = 11.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + ha:line.1 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.865632mm + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.865632mm + } + } + height = 1.373633mm + } + ha:L { + width = 0.508001mm + delta = 12.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + ha:M { + width = 0.762001mm + delta = 12.0mil + li:objects { + ha:line.0 { + y2 = 1.399032mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 15.08mil + } + ha:line.1 { + y2 = 0.891032mm + thickness = 8.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 15.08mil + } + ha:line.2 { + y2 = 15.08mil + thickness = 8.0mil + x1 = 15.0mil + x2 = 30.0mil + y1 = 0.891032mm + } + ha:line.3 { + y2 = 1.399032mm + thickness = 8.0mil + x1 = 30.0mil + x2 = 30.0mil + y1 = 15.08mil + } + } + height = 1.399033mm + } + ha:&2f { + width = 0.762001mm + delta = 15.0mil + li:objects { + ha:line.0 { + y2 = 0.484632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 30.0mil + y1 = 1.246632mm + } + } + height = 1.246633mm + } + ha:&3a { + width = 0.127001mm + delta = 14.0mil + li:objects { + ha:line.0 { + y2 = 0.738632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 0.738632mm + } + ha:line.1 { + y2 = 0.992632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 0.992632mm + } + } + height = 0.992633mm + } + ha:&3b { + width = 0.254001mm + delta = 14.0mil + li:objects { + ha:line.0 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 10.0mil + x2 = 10.0mil + y1 = 0.738632mm + } + ha:line.1 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + ha:&3d { + width = 0.508001mm + delta = 12.0mil + li:objects { + ha:line.0 { + y2 = 0.738632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.738632mm + } + ha:line.1 { + y2 = 0.992632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 0.992632mm + } + } + height = 0.992633mm + } + ha:O { + width = 0.715266mm + delta = 0.230633mm + li:objects { + ha:line.0 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 4.08mil + x2 = 4.08mil + y1 = 0.611632mm + } + ha:line.1 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 0.611632mm + x2 = 0.611632mm + y1 = 0.611632mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -180.000000 + astart = 180.000000 + x = 14.08mil + y = 1.119632mm + r = 10.0mil + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -180.000000 + astart = 0.000000 + x = 14.08mil + y = 0.611632mm + r = 10.0mil + } + } + height = 1.477266mm + } + ha:P { + width = 0.738634mm + delta = 6.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 14.08mil + } + ha:line.2 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 15.0mil + y1 = 0.865632mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -180.000000 + astart = -90.000000 + x = 15.0mil + y = 0.611632mm + r = 10.0mil + } + } + height = 1.373633mm + } + ha:N { + width = 0.635001mm + delta = 10.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 25.0mil + y1 = 14.08mil + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 25.0mil + x2 = 25.0mil + y1 = 14.08mil + } + } + height = 1.373633mm + } + ha:R { + width = 0.738634mm + delta = 5.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 15.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 13.0mil + y1 = 0.865632mm + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 5.0mil + y1 = 14.08mil + } + ha:line.3 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 13.0mil + x2 = 25.0mil + y1 = 0.865632mm + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -180.000000 + astart = -90.000000 + x = 15.0mil + y = 0.611632mm + r = 10.0mil + } + } + height = 1.373633mm + } + ha:S { + width = 0.735821mm + delta = 0.204727mm + li:objects { + ha:line.0 { + y2 = 0.851061mm + thickness = 8.0mil + x1 = 0.308266mm + x2 = 0.436371mm + y1 = 0.827971mm + } + ha:simplearc.1 { + thickness = 8.0mil + adelta = 227.000000 + astart = 25.000000 + x = 0.353178mm + y = 43.84mil + r = 0.275343mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = 229.000000 + astart = 205.000000 + x = 0.382642mm + y = 22.16mil + r = 0.275343mm + } + } + height = 1.492513mm + } + ha:Q { + width = 0.715266mm + delta = 0.230633mm + li:objects { + ha:line.0 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 4.08mil + x2 = 4.08mil + y1 = 0.611632mm + } + ha:line.1 { + y2 = 54.0mil + thickness = 8.0mil + x1 = 15.0mil + x2 = 27.0mil + y1 = 45.0mil + } + ha:line.2 { + y2 = 1.119632mm + thickness = 8.0mil + x1 = 0.611632mm + x2 = 0.611632mm + y1 = 0.611632mm + } + ha:simplearc.3 { + thickness = 8.0mil + adelta = -180.000000 + astart = 180.000000 + x = 14.08mil + y = 1.119632mm + r = 10.0mil + } + ha:simplearc.4 { + thickness = 8.0mil + adelta = -180.000000 + astart = 0.000000 + x = 14.08mil + y = 0.611632mm + r = 10.0mil + } + } + height = 1.477266mm + } + ha:U { + width = 0.715266mm + delta = 0.228093mm + li:objects { + ha:line.0 { + y2 = 44.0mil + thickness = 8.0mil + x1 = 0.10414mm + x2 = 0.10414mm + y1 = 14.08mil + } + ha:line.1 { + y2 = 44.0mil + thickness = 8.0mil + x1 = 24.1mil + x2 = 24.1mil + y1 = 14.08mil + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -180.000000 + astart = 180.000000 + x = 14.08mil + y = 1.117092mm + r = 10.0mil + } + } + height = 1.474726mm + } + ha:V { + width = 0.508001mm + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 20.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + ha:T { + width = 0.508001mm + delta = 9.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 10.0mil + x2 = 10.0mil + y1 = 14.08mil + } + } + height = 1.373633mm + } + ha:X { + width = 0.635001mm + delta = 14.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 25.0mil + y1 = 1.373632mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 25.0mil + y1 = 14.08mil + } + } + height = 1.373633mm + } + ha:Y { + width = 0.508001mm + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 10.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 10.0mil + x2 = 20.0mil + y1 = 0.865632mm + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 10.0mil + x2 = 10.0mil + y1 = 0.865632mm + } + } + height = 1.373633mm + } + ha:W { + width = 0.762001mm + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 0.865632mm + } + ha:line.2 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 15.0mil + y1 = 1.373632mm + } + ha:line.3 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 15.0mil + x2 = 25.0mil + y1 = 0.865632mm + } + ha:line.4 { + y2 = 0.865632mm + thickness = 8.0mil + x1 = 25.0mil + x2 = 30.0mil + y1 = 1.373632mm + } + ha:line.5 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 30.0mil + x2 = 30.0mil + y1 = 0.865632mm + } + } + height = 1.373633mm + } + ha:[ { + width = 0.127001mm + delta = 12.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 0.0 + y1 = 14.08mil + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + ha:^ { + width = 0.254001mm + delta = 12.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 5.0mil + y1 = 0.484632mm + } + ha:line.1 { + y2 = 0.484632mm + thickness = 8.0mil + x1 = 5.0mil + x2 = 10.0mil + y1 = 14.08mil + } + } + height = 0.484633mm + } + ha:Z { + width = 0.635001mm + delta = 13.0mil + li:objects { + ha:line.0 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 25.0mil + y1 = 14.08mil + } + ha:line.1 { + y2 = 14.08mil + thickness = 8.0mil + x1 = 0.0 + x2 = 25.0mil + y1 = 1.373632mm + } + ha:line.2 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 25.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + ha:a { + width = 0.73991mm + delta = 8.0mil + li:objects { + ha:line.0 { + y2 = 1.246632mm + thickness = 8.0mil + x1 = 0.612909mm + x2 = 0.612909mm + y1 = 0.865632mm + } + ha:line.1 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.612909mm + x2 = 0.739909mm + y1 = 1.246632mm + } + ha:simplearc.2 { + thickness = 8.0mil + adelta = -360.000000 + astart = 20.000000 + x = 0.356877mm + y = 44.0mil + r = 0.253245mm + } + } + height = 1.474479mm + } + ha:_ { + width = 0.508001mm + delta = 12.0mil + li:objects { + ha:line.0 { + y2 = 1.373632mm + thickness = 8.0mil + x1 = 0.0 + x2 = 20.0mil + y1 = 1.373632mm + } + } + height = 1.373633mm + } + } + cell_width = 1.477266mm + cell_height = 1.879602mm + } +} Index: tags/2.3.0/font/osifontASCII.lht =================================================================== --- tags/2.3.0/font/osifontASCII.lht (nonexistent) +++ tags/2.3.0/font/osifontASCII.lht (revision 33253) @@ -0,0 +1,8566 @@ +li:pcb-rnd-font-v1 { + ha:geda_pcb { + id = 0 + ha:symbols { + ha:! { + width=4mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 79.78mil + 0.0mil; 79.69mil + 0.0mil; 79.42mil + 0.0mil; 78.96mil + 0.0mil; 78.32mil + 0.0mil; 77.5mil + 0.0mil; 76.44mil + 0.03mil; 75.43mil + 0.21mil; 74.61mil + 0.51mil; 73.94mil + 0.94mil; 73.49mil + 1.46mil; 73.18mil + 2.16mil; 73.06mil + 2.89mil; 73.18mil + 3.47mil; 73.46mil + 3.95mil; 73.94mil + 4.29mil; 74.61mil + 4.47mil; 75.46mil + 4.56mil; 76.56mil + 4.47mil; 77.56mil + 4.29mil; 78.35mil + 3.98mil; 78.99mil + 3.56mil; 79.42mil + 2.98mil; 79.69mil + } + li:simplepoly.1 { + 4.56mil; 65.91mil + 4.47mil; 65.91mil + 4.29mil; 65.91mil + 3.98mil; 65.91mil + 3.56mil; 65.91mil + 2.98mil; 65.91mil + 2.28mil; 65.91mil + 1.58mil; 65.85mil + 1.0mil; 65.61mil + 0.55mil; 65.21mil + 0.24mil; 64.66mil + 0.06mil; 63.93mil + 0.0mil; 63.02mil + 0.0mil; 36.59mil + 0.06mil; 35.77mil + 0.24mil; 35.07mil + 0.55mil; 34.52mil + 0.97mil; 34.12mil + 1.55mil; 33.88mil + 2.28mil; 33.79mil + 2.95mil; 33.88mil + 3.53mil; 34.12mil + 3.98mil; 34.49mil + 4.29mil; 35.04mil + 4.47mil; 35.74mil + 4.56mil; 36.62mil + 4.56mil; 63.02mil + 4.47mil; 63.9mil + 4.29mil; 64.63mil + 3.98mil; 65.18mil + 3.56mil; 65.61mil + 2.98mil; 65.85mil + } + } + height = 63.33mil + } + ha:" { + width=18mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 13.87mil; 27.07mil + 14.02mil; 26.49mil + 14.26mil; 26.0mil + 14.57mil; 25.64mil + 14.9mil; 25.36mil + 15.33mil; 25.18mil + 15.81mil; 25.12mil + 16.54mil; 25.18mil + 17.15mil; 25.33mil + 17.64mil; 25.61mil + 17.97mil; 25.97mil + 18.19mil; 26.43mil + 18.28mil; 27.01mil + 18.25mil; 27.25mil + 18.25mil; 27.52mil + 18.22mil; 27.8mil + 18.16mil; 28.1mil + 18.1mil; 28.44mil + 18.03mil; 28.77mil + 16.12mil; 36.68mil + 15.91mil; 37.32mil + 15.66mil; 37.84mil + 15.39mil; 38.23mil + 15.02mil; 38.54mil + 14.63mil; 38.72mil + 14.17mil; 38.75mil + 13.41mil; 38.72mil + 12.8mil; 38.54mil + 12.32mil; 38.26mil + 11.98mil; 37.87mil + 11.77mil; 37.35mil + 11.71mil; 36.71mil + 11.71mil; 36.53mil + 11.71mil; 36.35mil + 11.71mil; 36.16mil + 11.74mil; 36.01mil + 11.77mil; 35.83mil + 11.83mil; 35.68mil + } + li:simplepoly.1 { + 2.31mil; 27.07mil + 2.49mil; 26.49mil + 2.73mil; 26.03mil + 3.07mil; 25.64mil + 3.43mil; 25.39mil + 3.86mil; 25.21mil + 4.41mil; 25.15mil + 5.11mil; 25.21mil + 5.72mil; 25.39mil + 6.17mil; 25.7mil + 6.51mil; 26.09mil + 6.69mil; 26.61mil + 6.78mil; 27.25mil + 6.75mil; 27.37mil + 6.75mil; 27.52mil + 6.72mil; 27.68mil + 6.69mil; 27.86mil + 6.63mil; 28.07mil + 6.6mil; 28.28mil + 4.44mil; 36.8mil + 4.22mil; 37.41mil + 3.98mil; 37.9mil + 3.68mil; 38.26mil + 3.28mil; 38.54mil + 2.86mil; 38.72mil + 2.37mil; 38.75mil + 1.64mil; 38.72mil + 1.03mil; 38.54mil + 0.57mil; 38.26mil + 0.24mil; 37.9mil + 0.06mil; 37.41mil + 0.0mil; 36.77mil + 0.0mil; 36.62mil + 0.0mil; 36.44mil + 0.03mil; 36.28mil + 0.06mil; 36.1mil + 0.09mil; 35.89mil + 0.15mil; 35.68mil + } + } + height = 63.33mil + } + ha:\# { + width=32mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 6.84mil; 36.28mil + 6.9mil; 35.58mil + 7.08mil; 34.98mil + 7.39mil; 34.52mil + 7.81mil; 34.19mil + 8.36mil; 34.0mil + 9.06mil; 33.91mil + 9.73mil; 34.0mil + 10.28mil; 34.19mil + 10.7mil; 34.55mil + 11.01mil; 35.01mil + 11.19mil; 35.62mil + 11.28mil; 36.38mil + 11.28mil; 47.66mil + 20.77mil; 47.66mil + 20.77mil; 61.53mil + 20.77mil; 52.19mil + 11.31mil; 52.19mil + 11.31mil; 61.53mil + 20.77mil; 61.53mil + 20.77mil; 47.66mil + 20.77mil; 36.19mil + 20.83mil; 35.49mil + 21.02mil; 34.89mil + 21.35mil; 34.43mil + 21.81mil; 34.09mil + 22.38mil; 33.91mil + 23.14mil; 33.82mil + 23.78mil; 33.91mil + 24.3mil; 34.12mil + 24.73mil; 34.46mil + 25.03mil; 34.95mil + 25.18mil; 35.55mil + 25.27mil; 36.31mil + 25.27mil; 47.69mil + 29.87mil; 47.69mil + 30.54mil; 47.78mil + 31.08mil; 47.96mil + 31.54mil; 48.27mil + 31.84mil; 48.7mil + 32.03mil; 49.24mil + 32.12mil; 49.91mil + 32.03mil; 50.61mil + 31.84mil; 51.19mil + 31.54mil; 51.65mil + 31.11mil; 51.95mil + 30.54mil; 52.13mil + 29.84mil; 52.19mil + 25.27mil; 52.19mil + 25.27mil; 61.59mil + 29.75mil; 61.59mil + 30.45mil; 61.65mil + 31.02mil; 61.84mil + 31.48mil; 62.14mil + 31.81mil; 62.57mil + 32.0mil; 63.08mil + 32.09mil; 63.75mil + 32.0mil; 64.45mil + 31.81mil; 65.0mil + 31.51mil; 65.46mil + 31.08mil; 65.76mil + 30.54mil; 65.94mil + 29.84mil; 66.0mil + 25.21mil; 66.0mil + 25.21mil; 77.29mil + 25.12mil; 78.08mil + 24.94mil; 78.69mil + 24.6mil; 79.2mil + 24.15mil; 79.54mil + 23.57mil; 79.75mil + 22.84mil; 79.81mil + 22.2mil; 79.75mil + 21.68mil; 79.54mil + 21.29mil; 79.2mil + 20.99mil; 78.72mil + 20.8mil; 78.08mil + 20.77mil; 77.26mil + 20.77mil; 66.0mil + 11.34mil; 66.0mil + 11.34mil; 77.29mil + 11.25mil; 78.08mil + 11.07mil; 78.75mil + 10.76mil; 79.23mil + 10.34mil; 79.6mil + 9.76mil; 79.81mil + 9.06mil; 79.87mil + 8.36mil; 79.81mil + 7.81mil; 79.6mil + 7.39mil; 79.23mil + 7.08mil; 78.75mil + 6.9mil; 78.08mil + 6.84mil; 77.26mil + 6.84mil; 66.0mil + 2.46mil; 66.0mil + 1.7mil; 65.94mil + 1.09mil; 65.76mil + 0.64mil; 65.42mil + 0.3mil; 65.0mil + 0.09mil; 64.42mil + 0.03mil; 63.66mil + 0.09mil; 63.05mil + 0.27mil; 62.54mil + 0.64mil; 62.14mil + 1.09mil; 61.87mil + 1.7mil; 61.68mil + 2.49mil; 61.62mil + 6.84mil; 61.62mil + 6.84mil; 52.19mil + 2.55mil; 52.19mil + 1.76mil; 52.13mil + 1.12mil; 51.95mil + 0.64mil; 51.62mil + 0.27mil; 51.19mil + 0.06mil; 50.61mil + 0.0mil; 49.85mil + 0.06mil; 49.18mil + 0.27mil; 48.63mil + 0.64mil; 48.21mil + 1.12mil; 47.9mil + 1.76mil; 47.72mil + 2.58mil; 47.63mil + 6.84mil; 47.63mil + } + } + height = 63.33mil + } + ha:$ { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.2 { + 0.0mil; 47.66mil + 0.06mil; 46.5mil + 0.24mil; 45.38mil + 0.54mil; 44.35mil + 0.97mil; 43.4mil + 1.55mil; 42.52mil + 2.28mil; 41.67mil + 3.25mil; 40.79mil + 4.32mil; 40.06mil + 5.41mil; 39.48mil + 6.6mil; 39.08mil + 7.81mil; 38.81mil + 9.18mil; 38.72mil + 9.18mil; 36.47mil + 9.24mil; 35.77mil + 9.43mil; 35.19mil + 9.73mil; 34.76mil + 10.16mil; 34.43mil + 10.7mil; 34.25mil + 11.43mil; 34.16mil + 12.07mil; 34.25mil + 12.62mil; 34.46mil + 13.05mil; 34.82mil + 13.35mil; 35.31mil + 13.53mil; 35.98mil + 13.62mil; 36.77mil + 13.62mil; 38.96mil + 14.93mil; 39.17mil + 16.21mil; 39.42mil + 17.49mil; 39.72mil + 18.7mil; 40.09mil + 19.92mil; 40.48mil + 21.14mil; 40.94mil + 21.65mil; 41.21mil + 22.11mil; 41.52mil + 22.45mil; 41.88mil + 22.69mil; 42.28mil + 22.84mil; 42.7mil + 22.9mil; 43.19mil + 22.84mil; 43.77mil + 9.18mil; 53.11mil + 9.18mil; 52.86mil + 9.18mil; 52.04mil + 9.18mil; 50.67mil + 9.18mil; 48.79mil + 9.18mil; 46.32mil + 9.18mil; 43.22mil + 7.72mil; 43.37mil + 6.54mil; 43.77mil + 5.59mil; 44.41mil + 4.92mil; 45.32mil + 4.53mil; 46.47mil + 4.41mil; 47.93mil + 4.53mil; 48.91mil + 4.92mil; 49.82mil + 5.56mil; 50.7mil + 6.51mil; 51.55mil + 7.66mil; 52.35mil + 9.18mil; 53.11mil + 22.84mil; 43.77mil + 22.66mil; 44.22mil + 22.38mil; 44.62mil + 22.02mil; 44.95mil + 21.53mil; 45.2mil + 20.92mil; 45.38mil + 20.71mil; 45.41mil + 20.47mil; 45.41mil + 20.19mil; 45.38mil + 19.89mil; 45.29mil + 19.59mil; 45.2mil + 19.22mil; 45.04mil + 18.03mil; 44.62mil + 16.94mil; 44.22mil + 15.97mil; 43.95mil + 15.08mil; 43.74mil + 14.29mil; 43.62mil + 13.62mil; 43.55mil + 13.62mil; 55.72mil + 14.32mil; 56.06mil + 15.08mil; 56.45mil + 15.94mil; 56.91mil + 16.82mil; 57.42mil + 17.76mil; 58.0mil + 18.8mil; 58.64mil + 20.04mil; 59.62mil + 21.08mil; 60.68mil + 21.87mil; 61.87mil + 22.45mil; 63.2mil + 22.81mil; 64.63mil + 22.93mil; 66.25mil + 22.84mil; 67.43mil + 22.66mil; 68.56mil + 22.32mil; 69.59mil + 21.87mil; 70.6mil + 21.26mil; 71.51mil + 20.53mil; 72.39mil + 19.53mil; 73.33mil + 18.46mil; 74.06mil + 17.37mil; 74.64mil + 16.18mil; 75.07mil + 14.96mil; 75.34mil + 13.62mil; 75.4mil + 13.62mil; 77.53mil + 13.56mil; 78.29mil + 13.38mil; 78.9mil + 13.08mil; 79.39mil + 12.65mil; 79.72mil + 12.1mil; 79.93mil + 11.43mil; 80.0mil + 10.73mil; 79.93mil + 10.19mil; 79.75mil + 9.73mil; 79.42mil + 9.43mil; 78.93mil + 9.24mil; 78.35mil + 9.18mil; 77.56mil + 9.18mil; 75.07mil + 7.27mil; 74.79mil + 5.59mil; 74.46mil + 4.1mil; 74.12mil + 2.89mil; 73.76mil + 1.85mil; 73.36mil + 1.06mil; 72.91mil + 0.73mil; 72.69mil + 0.45mil; 72.42mil + 0.24mil; 72.09mil + 0.09mil; 71.75mil + 0.03mil; 71.39mil + 0.0mil; 70.93mil + 0.03mil; 70.29mil + 0.21mil; 69.74mil + 0.51mil; 69.32mil + 0.94mil; 69.04mil + 1.49mil; 68.86mil + 2.19mil; 68.77mil + 2.37mil; 68.8mil + 2.58mil; 68.83mil + 2.83mil; 68.86mil + 3.1mil; 68.92mil + 3.37mil; 69.01mil + 3.71mil; 69.11mil + 4.71mil; 69.47mil + 5.68mil; 69.77mil + 18.46mil; 65.94mil + 18.31mil; 65.0mil + 17.91mil; 64.06mil + 17.24mil; 63.2mil + 16.33mil; 62.38mil + 15.11mil; 61.62mil + 13.62mil; 60.89mil + 13.62mil; 70.96mil + 15.08mil; 70.84mil + 16.27mil; 70.41mil + 17.21mil; 69.74mil + 17.88mil; 68.77mil + 18.31mil; 67.52mil + 18.46mil; 65.94mil + 5.68mil; 69.77mil + 6.63mil; 70.05mil + 7.51mil; 70.29mil + 8.36mil; 70.47mil + 9.18mil; 70.6mil + 9.18mil; 58.25mil + 7.6mil; 57.55mil + 6.2mil; 56.82mil + 4.95mil; 56.09mil + 3.89mil; 55.36mil + 3.01mil; 54.6mil + 2.28mil; 53.84mil + 1.58mil; 52.95mil + 1.0mil; 52.01mil + 0.54mil; 51.01mil + 0.24mil; 49.94mil + 0.06mil; 48.85mil + } + } + height = 63.33mil + } + ha:% { + width=41mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 39.33mil; 64.82mil + 39.97mil; 65.67mil + 40.51mil; 66.61mil + 40.94mil; 67.61mil + 41.21mil; 68.71mil + 41.4mil; 69.9mil + 41.49mil; 71.2mil + 41.4mil; 72.36mil + 41.18mil; 73.46mil + 40.79mil; 74.49mil + 40.27mil; 75.46mil + 39.6mil; 76.41mil + 38.78mil; 77.32mil + 37.81mil; 78.14mil + 36.83mil; 78.81mil + 35.89mil; 67.77mil + 35.43mil; 67.28mil + 34.92mil; 66.88mil + 34.34mil; 66.55mil + 33.7mil; 66.34mil + 33.0mil; 66.19mil + 32.21mil; 66.12mil + 31.54mil; 66.19mil + 30.93mil; 66.34mil + 30.35mil; 66.58mil + 29.78mil; 66.92mil + 29.26mil; 67.34mil + 28.74mil; 67.89mil + 28.41mil; 68.31mil + 28.16mil; 68.77mil + 27.95mil; 69.26mil + 27.8mil; 69.81mil + 27.71mil; 70.35mil + 27.71mil; 70.96mil + 27.74mil; 71.6mil + 27.86mil; 72.21mil + 28.04mil; 72.76mil + 28.32mil; 73.27mil + 28.68mil; 73.73mil + 29.14mil; 74.15mil + 29.62mil; 74.55mil + 30.14mil; 74.88mil + 30.66mil; 75.13mil + 31.18mil; 75.31mil + 31.72mil; 75.4mil + 32.3mil; 75.43mil + 32.85mil; 75.4mil + 33.43mil; 75.28mil + 34.0mil; 75.04mil + 34.61mil; 74.73mil + 35.22mil; 74.34mil + 35.86mil; 73.82mil + 36.19mil; 73.46mil + 36.5mil; 73.06mil + 36.74mil; 72.57mil + 36.89mil; 72.06mil + 36.98mil; 71.48mil + 37.05mil; 70.81mil + 36.98mil; 70.32mil + 36.89mil; 69.81mil + 36.74mil; 69.32mil + 36.53mil; 68.8mil + 36.22mil; 68.31mil + 35.89mil; 67.77mil + 36.83mil; 78.81mil + 35.77mil; 79.33mil + 34.67mil; 79.72mil + 33.52mil; 79.93mil + 32.27mil; 80.0mil + 31.27mil; 79.96mil + 30.32mil; 79.78mil + 29.38mil; 79.51mil + 28.47mil; 79.14mil + 27.59mil; 78.66mil + 26.7mil; 78.02mil + 25.64mil; 77.11mil + 24.76mil; 76.1mil + 24.09mil; 75.01mil + 23.6mil; 73.82mil + 23.33mil; 72.54mil + 23.24mil; 71.14mil + 23.3mil; 69.68mil + 23.57mil; 68.31mil + 24.0mil; 67.07mil + 24.6mil; 65.91mil + 25.37mil; 64.85mil + 26.37mil; 63.84mil + 27.22mil; 63.2mil + 28.1mil; 62.66mil + 29.02mil; 62.23mil + 29.99mil; 61.93mil + 30.99mil; 61.74mil + 32.09mil; 61.65mil + 33.49mil; 61.74mil + 34.79mil; 62.02mil + 36.04mil; 62.44mil + 37.2mil; 63.05mil + 38.29mil; 63.84mil + } + li:simplepoly.2 { + 37.14mil; 35.07mil + 37.44mil; 34.76mil + 37.78mil; 34.52mil + 38.11mil; 34.34mil + 38.44mil; 34.19mil + 38.78mil; 34.09mil + 39.18mil; 34.06mil + 39.84mil; 34.16mil + 40.39mil; 34.34mil + 40.85mil; 34.67mil + 41.15mil; 35.13mil + 41.33mil; 35.71mil + 41.43mil; 36.44mil + 41.4mil; 36.68mil + 41.3mil; 36.89mil + 41.18mil; 37.17mil + 41.0mil; 37.44mil + 40.79mil; 37.74mil + 40.51mil; 38.08mil + 4.1mil; 79.05mil + 3.8mil; 79.36mil + 3.53mil; 79.6mil + 3.19mil; 79.78mil + 2.86mil; 79.9mil + 2.52mil; 80.0mil + 2.16mil; 80.0mil + 1.49mil; 79.93mil + 0.94mil; 79.75mil + 0.51mil; 79.45mil + 0.24mil; 79.02mil + 0.06mil; 78.44mil + 0.0mil; 77.71mil + 0.0mil; 77.44mil + 0.06mil; 77.17mil + 0.18mil; 76.86mil + 0.33mil; 76.59mil + 0.51mil; 76.28mil + 0.79mil; 75.98mil + } + li:simplepoly.4 { + 16.09mil; 37.23mil + 16.73mil; 38.08mil + 17.27mil; 39.02mil + 17.7mil; 40.03mil + 17.97mil; 41.12mil + 18.16mil; 42.31mil + 18.25mil; 43.62mil + 18.16mil; 44.77mil + 17.94mil; 45.87mil + 17.55mil; 46.93mil + 17.03mil; 47.9mil + 16.36mil; 48.85mil + 15.54mil; 49.73mil + 14.57mil; 50.55mil + 13.59mil; 51.19mil + 12.53mil; 51.71mil + 11.43mil; 52.07mil + 12.65mil; 40.18mil + 12.19mil; 39.69mil + 11.68mil; 39.3mil + 11.1mil; 38.96mil + 10.46mil; 38.75mil + 9.76mil; 38.6mil + 8.97mil; 38.54mil + 8.3mil; 38.6mil + 7.69mil; 38.75mil + 7.11mil; 38.99mil + 6.54mil; 39.33mil + 6.02mil; 39.75mil + 5.5mil; 40.3mil + 5.17mil; 40.73mil + 4.92mil; 41.18mil + 4.71mil; 41.67mil + 4.56mil; 42.22mil + 4.47mil; 42.76mil + 4.47mil; 43.37mil + 4.5mil; 44.01mil + 4.62mil; 44.62mil + 4.8mil; 45.17mil + 5.08mil; 45.68mil + 5.44mil; 46.14mil + 5.9mil; 46.57mil + 6.38mil; 46.96mil + 6.9mil; 47.3mil + 7.42mil; 47.54mil + 7.94mil; 47.72mil + 8.48mil; 47.81mil + 9.06mil; 47.84mil + 9.61mil; 47.81mil + 10.19mil; 47.69mil + 10.76mil; 47.45mil + 11.37mil; 47.14mil + 11.98mil; 46.75mil + 12.62mil; 46.23mil + 12.95mil; 45.87mil + 13.26mil; 45.47mil + 13.5mil; 44.98mil + 13.65mil; 44.47mil + 13.75mil; 43.89mil + 13.81mil; 43.22mil + 13.75mil; 42.73mil + 13.65mil; 42.22mil + 13.5mil; 41.73mil + 13.29mil; 41.21mil + 12.99mil; 40.73mil + 12.65mil; 40.18mil + 11.43mil; 52.07mil + 10.28mil; 52.28mil + 9.03mil; 52.35mil + 8.03mil; 52.31mil + 7.08mil; 52.16mil + 6.14mil; 51.89mil + 5.23mil; 51.52mil + 4.35mil; 51.04mil + 3.46mil; 50.43mil + 2.4mil; 49.55mil + 1.52mil; 48.54mil + 0.85mil; 47.45mil + 0.36mil; 46.26mil + 0.09mil; 44.98mil + 0.0mil; 43.55mil + 0.06mil; 42.09mil + 0.33mil; 40.73mil + 0.76mil; 39.48mil + 1.37mil; 38.32mil + 2.13mil; 37.26mil + 3.13mil; 36.25mil + 3.98mil; 35.62mil + 4.86mil; 35.07mil + 5.78mil; 34.64mil + 6.75mil; 34.34mil + 7.75mil; 34.16mil + 8.85mil; 34.06mil + 10.25mil; 34.16mil + 11.56mil; 34.43mil + 12.8mil; 34.85mil + 13.96mil; 35.46mil + 15.05mil; 36.25mil + } + } + height = 63.33mil + } + ha:&26 { + width=32mil; delta=12.0mil; + li:objects { + li:simplepoly.2 { + 11.4mil; 33.91mil + 12.68mil; 34.0mil + 13.93mil; 34.25mil + 15.11mil; 34.67mil + 16.24mil; 35.25mil + 17.33mil; 35.98mil + 18.4mil; 36.92mil + 19.1mil; 37.74mil + 19.71mil; 38.63mil + 20.16mil; 39.57mil + 20.5mil; 40.57mil + 20.68mil; 41.64mil + 20.77mil; 42.76mil + 20.71mil; 43.8mil + 20.62mil; 44.71mil + 20.47mil; 45.56mil + 20.26mil; 46.32mil + 19.95mil; 47.02mil + 19.62mil; 47.63mil + 14.02mil; 55.63mil + 21.47mil; 67.4mil + 17.91mil; 70.14mil + 16.51mil; 67.98mil + 15.24mil; 66.0mil + 14.08mil; 64.15mil + 13.02mil; 62.5mil + 12.07mil; 61.01mil + 11.22mil; 59.62mil + 5.78mil; 67.37mil + 5.41mil; 67.92mil + 5.14mil; 68.5mil + 4.92mil; 69.04mil + 4.77mil; 69.59mil + 4.68mil; 70.14mil + 4.65mil; 70.72mil + 4.77mil; 72.18mil + 5.17mil; 73.33mil + 5.87mil; 74.25mil + 6.81mil; 74.92mil + 8.03mil; 75.31mil + 9.58mil; 75.43mil + 10.03mil; 75.4mil + 10.52mil; 75.31mil + 11.01mil; 75.13mil + 11.53mil; 74.88mil + 12.07mil; 74.58mil + 12.65mil; 74.15mil + 17.91mil; 70.14mil + 21.47mil; 67.4mil + 28.5mil; 62.2mil + 28.74mil; 62.05mil + 28.99mil; 61.9mil + 29.26mil; 61.77mil + 29.5mil; 61.71mil + 29.75mil; 61.65mil + 29.99mil; 61.62mil + 30.63mil; 61.71mil + 31.18mil; 61.9mil + 31.6mil; 62.23mil + 31.91mil; 62.66mil + 32.09mil; 63.23mil + 32.18mil; 63.96mil + 32.12mil; 64.3mil + 32.03mil; 64.63mil + 31.84mil; 65.0mil + 31.57mil; 65.33mil + 31.24mil; 65.67mil + 30.84mil; 66.0mil + 23.94mil; 71.3mil + 27.19mil; 76.38mil + 27.28mil; 76.62mil + 27.4mil; 76.83mil + 27.46mil; 77.07mil + 27.52mil; 77.32mil + 27.56mil; 77.53mil + 27.59mil; 77.77mil + 27.49mil; 78.47mil + 27.31mil; 79.02mil + 27.01mil; 79.45mil + 26.58mil; 79.75mil + 26.03mil; 79.93mil + 25.37mil; 80.0mil + 25.0mil; 80.0mil + 24.67mil; 79.9mil + 24.36mil; 79.75mil + 24.09mil; 79.54mil + 23.81mil; 79.26mil + 23.6mil; 78.93mil + 20.38mil; 74.0mil + 14.41mil; 78.35mil + 13.65mil; 78.87mil + 12.86mil; 79.26mil + 12.01mil; 79.6mil + 11.13mil; 79.81mil + 10.19mil; 79.96mil + 9.15mil; 80.0mil + + 11.4mil; 51.58mil + 15.42mil; 45.87mil + 15.66mil; 45.44mil + 15.91mil; 45.01mil + 16.06mil; 44.53mil + 16.18mil; 44.04mil + 16.27mil; 43.49mil + 16.3mil; 42.92mil + 16.24mil; 42.4mil + 16.12mil; 41.88mil + 15.94mil; 41.36mil + 15.66mil; 40.85mil + 15.3mil; 40.36mil + 14.87mil; 39.84mil + 14.38mil; 39.45mil + 13.9mil; 39.08mil + 13.35mil; 38.81mil + 12.8mil; 38.63mil + 12.22mil; 38.51mil + 11.59mil; 38.44mil + 10.92mil; 38.51mil + 10.31mil; 38.63mil + 9.73mil; 38.81mil + 9.21mil; 39.08mil + 8.7mil; 39.42mil + 8.24mil; 39.84mil + 7.81mil; 40.36mil + 7.45mil; 40.85mil + 7.18mil; 41.36mil + 6.99mil; 41.88mil + 6.87mil; 42.43mil + 6.84mil; 42.98mil + 6.84mil; 43.46mil + 6.93mil; 43.98mil + 7.05mil; 44.47mil + 7.27mil; 44.95mil + 7.48mil; 45.47mil + 7.81mil; 45.99mil + + 11.4mil; 51.58mil + + 9.15mil; 80.0mil + + 7.97mil; 79.96mil + 6.9mil; 79.78mil + 5.9mil; 79.51mil + 4.99mil; 79.11mil + 4.16mil; 78.6mil + 3.43mil; 77.96mil + 2.37mil; 76.83mil + 1.52mil; 75.65mil + 0.85mil; 74.4mil + 0.36mil; 73.12mil + 0.09mil; 71.78mil + 0.0mil; 70.32mil + 0.03mil; 69.47mil + 0.21mil; 68.62mil + 0.48mil; 67.74mil + 0.88mil; 66.85mil + 1.4mil; 65.94mil + 2.07mil; 65.0mil + 8.67mil; 55.54mil + 3.31mil; 47.08mil + 3.04mil; 46.6mil + 2.8mil; 45.99mil + 2.64mil; 45.32mil + 2.52mil; 44.59mil + 2.43mil; 43.77mil + 2.43mil; 42.82mil + 2.52mil; 41.52mil + 2.8mil; 40.27mil + 3.28mil; 39.08mil + 3.95mil; 37.96mil + 4.8mil; 36.92mil + 5.93mil; 35.89mil + 6.75mil; 35.31mil + 7.6mil; 34.82mil + 8.48mil; 34.43mil + 9.4mil; 34.16mil + 10.37mil; 33.97mil + } + } + height = 63.33mil + } + ha:' { + width=6mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 2.19mil; 26.92mil + 2.37mil; 26.31mil + 2.64mil; 25.79mil + 2.95mil; 25.39mil + 3.34mil; 25.12mil + 3.77mil; 24.94mil + 4.32mil; 24.88mil + 4.99mil; 24.94mil + 5.56mil; 25.12mil + 6.02mil; 25.39mil + 6.32mil; 25.76mil + 6.51mil; 26.25mil + 6.6mil; 26.85mil + 6.57mil; 27.1mil + 6.57mil; 27.34mil + 6.54mil; 27.59mil + 6.51mil; 27.83mil + 6.45mil; 28.07mil + 6.41mil; 28.32mil + 4.44mil; 36.31mil + 4.19mil; 36.98mil + 3.92mil; 37.5mil + 3.59mil; 37.93mil + 3.19mil; 38.23mil + 2.73mil; 38.38mil + 2.19mil; 38.44mil + 1.52mil; 38.41mil + 0.97mil; 38.23mil + 0.54mil; 37.96mil + 0.24mil; 37.56mil + 0.06mil; 37.04mil + 0.0mil; 36.38mil + 0.0mil; 36.16mil + 0.03mil; 35.89mil + 0.06mil; 35.58mil + 0.12mil; 35.25mil + 0.18mil; 34.89mil + 0.3mil; 34.46mil + } + } + height = 63.33mil + } + ha:( { + width=8mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 4.62mil; 30.78mil + 4.84mil; 30.35mil + 5.11mil; 29.99mil + 5.44mil; 29.71mil + 5.87mil; 29.5mil + 6.33mil; 29.38mil + 6.87mil; 29.32mil + 7.45mil; 29.38mil + 7.94mil; 29.56mil + 8.33mil; 29.87mil + 8.61mil; 30.29mil + 8.79mil; 30.84mil + 8.85mil; 31.51mil + 8.82mil; 31.78mil + 8.79mil; 32.09mil + 8.73mil; 32.42mil + 8.61mil; 32.79mil + 8.52mil; 33.15mil + 8.36mil; 33.58mil + 7.09mil; 37.32mil + 6.05mil; 41.06mil + 5.23mil; 44.77mil + 4.65mil; 48.51mil + 4.32mil; 52.22mil + 4.2mil; 56.03mil + 4.29mil; 60.5mil + 4.62mil; 64.76mil + 5.2mil; 68.86mil + 5.99mil; 72.79mil + 7.03mil; 76.56mil + 8.33mil; 80.27mil + 8.49mil; 80.69mil + 8.61mil; 81.12mil + 8.73mil; 81.52mil + 8.79mil; 81.88mil + 8.85mil; 82.25mil + 8.88mil; 82.58mil + 8.79mil; 83.16mil + 8.61mil; 83.65mil + 8.27mil; 84.01mil + 7.79mil; 84.28mil + 7.21mil; 84.47mil + 6.45mil; 84.53mil + 6.02mil; 84.47mil + 5.66mil; 84.31mil + 5.32mil; 84.07mil + 5.02mil; 83.71mil + 4.74mil; 83.25mil + 4.5mil; 82.7mil + 3.13mil; 78.69mil + 2.01mil; 74.52mil + 1.12mil; 70.17mil + 0.49mil; 65.64mil + 0.12mil; 60.95mil + 0.0mil; 55.93mil + 0.12mil; 51.55mil + 0.49mil; 47.27mil + 1.12mil; 43.04mil + 2.01mil; 38.9mil + 3.16mil; 34.89mil + } + } + height = 63.33mil + } + ha:) { + width=8mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 4.26mil; 30.72mil + 5.65mil; 34.67mil + 6.81mil; 38.72mil + 7.69mil; 42.82mil + 8.33mil; 47.05mil + 8.73mil; 51.34mil + 8.88mil; 55.87mil + 8.73mil; 60.74mil + 8.36mil; 65.42mil + 7.75mil; 69.96mil + 6.87mil; 74.31mil + 5.78mil; 78.5mil + 4.38mil; 82.64mil + 4.1mil; 83.19mil + 3.83mil; 83.65mil + 3.53mil; 83.98mil + 3.19mil; 84.25mil + 2.83mil; 84.41mil + 2.43mil; 84.47mil + 1.67mil; 84.41mil + 1.06mil; 84.22mil + 0.61mil; 83.98mil + 0.27mil; 83.58mil + 0.06mil; 83.13mil + 0.0mil; 82.52mil + 0.0mil; 82.19mil + 0.03mil; 81.85mil + 0.12mil; 81.49mil + 0.21mil; 81.09mil + 0.36mil; 80.66mil + 0.54mil; 80.21mil + 1.79mil; 76.62mil + 2.83mil; 72.88mil + 3.62mil; 68.92mil + 4.19mil; 64.85mil + 4.56mil; 60.56mil + 4.68mil; 55.96mil + 4.56mil; 52.07mil + 4.19mil; 48.24mil + 3.65mil; 44.5mil + 2.83mil; 40.79mil + 1.79mil; 37.2mil + 0.51mil; 33.52mil + 0.33mil; 33.12mil + 0.21mil; 32.73mil + 0.12mil; 32.36mil + 0.03mil; 32.03mil + 0.0mil; 31.75mil + 0.0mil; 31.45mil + 0.03mil; 30.81mil + 0.21mil; 30.26mil + 0.48mil; 29.84mil + 0.88mil; 29.53mil + 1.37mil; 29.35mil + 2.0mil; 29.26mil + 2.52mil; 29.32mil + 2.98mil; 29.44mil + 3.37mil; 29.62mil + 3.74mil; 29.93mil + 4.01mil; 30.26mil + } + } + height = 63.33mil + } + ha:* { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 16.67mil; 59.89mil + 16.76mil; 59.89mil + 17.06mil; 59.89mil + 17.61mil; 59.89mil + 18.34mil; 59.89mil + 19.28mil; 59.89mil + 20.5mil; 59.89mil + 21.2mil; 59.95mil + 21.78mil; 60.13mil + 22.2mil; 60.41mil + 22.54mil; 60.8mil + 22.72mil; 61.32mil + 22.81mil; 61.96mil + 22.72mil; 62.63mil + 22.54mil; 63.17mil + 22.2mil; 63.6mil + 21.72mil; 63.9mil + 21.14mil; 64.09mil + 20.38mil; 64.15mil + 20.26mil; 64.15mil + 19.95mil; 64.15mil + 19.46mil; 64.15mil + 18.76mil; 64.15mil + 17.85mil; 64.15mil + 16.73mil; 64.15mil + 19.22mil; 66.67mil + 19.43mil; 66.95mil + 19.65mil; 67.19mil + 19.8mil; 67.46mil + 19.92mil; 67.71mil + 19.98mil; 67.95mil + 20.01mil; 68.16mil + 19.92mil; 68.83mil + 19.71mil; 69.35mil + 19.34mil; 69.77mil + 18.86mil; 70.08mil + 18.22mil; 70.23mil + 17.43mil; 70.29mil + 17.15mil; 70.29mil + 16.88mil; 70.2mil + 16.57mil; 70.08mil + 16.3mil; 69.9mil + 16.0mil; 69.65mil + 15.69mil; 69.35mil + 11.43mil; 65.12mil + 6.54mil; 70.02mil + 6.32mil; 70.2mil + 6.08mil; 70.35mil + 5.87mil; 70.47mil + 5.62mil; 70.54mil + 5.38mil; 70.6mil + 5.11mil; 70.6mil + 4.41mil; 70.54mil + 3.86mil; 70.35mil + 3.4mil; 70.05mil + 3.1mil; 69.62mil + 2.92mil; 69.07mil + 2.86mil; 68.38mil + 2.86mil; 68.1mil + 2.92mil; 67.86mil + 2.98mil; 67.58mil + 3.1mil; 67.34mil + 3.25mil; 67.1mil + 3.46mil; 66.85mil + 6.05mil; 64.15mil + 2.28mil; 64.15mil + 1.58mil; 64.09mil + 1.0mil; 63.9mil + 0.54mil; 63.6mil + 0.24mil; 63.17mil + 0.06mil; 62.63mil + 0.0mil; 61.93mil + 0.06mil; 61.29mil + 0.24mil; 60.77mil + 0.57mil; 60.35mil + 1.06mil; 60.04mil + 1.64mil; 59.89mil + 2.43mil; 59.8mil + 6.08mil; 59.8mil + 3.13mil; 56.82mil + 2.95mil; 56.66mil + 2.83mil; 56.45mil + 2.73mil; 56.24mil + 2.64mil; 56.03mil + 2.61mil; 55.75mil + 2.61mil; 55.48mil + 2.67mil; 54.75mil + 2.86mil; 54.14mil + 3.19mil; 53.68mil + 3.65mil; 53.35mil + 4.22mil; 53.14mil + 4.99mil; 53.04mil + 5.23mil; 53.08mil + 5.5mil; 53.14mil + 5.72mil; 53.2mil + 5.96mil; 53.32mil + 6.17mil; 53.47mil + 6.38mil; 53.65mil + 11.43mil; 58.85mil + 15.97mil; 54.32mil + 16.33mil; 53.99mil + 16.7mil; 53.68mil + 17.09mil; 53.47mil + 17.46mil; 53.32mil + 17.79mil; 53.23mil + 18.19mil; 53.17mil + 18.76mil; 53.26mil + 19.25mil; 53.44mil + 19.65mil; 53.77mil + 19.92mil; 54.23mil + 20.1mil; 54.81mil + 20.16mil; 55.54mil + 20.1mil; 55.84mil + 20.01mil; 56.15mil + 19.86mil; 56.48mil + 19.62mil; 56.85mil + 19.31mil; 57.21mil + 18.95mil; 57.61mil + } + } + height = 63.33mil + } + ha:+ { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 9.4mil; 52.92mil + 9.46mil; 52.19mil + 9.64mil; 51.58mil + 9.94mil; 51.13mil + 10.37mil; 50.79mil + 10.92mil; 50.58mil + 11.65mil; 50.49mil + 12.29mil; 50.58mil + 12.83mil; 50.79mil + 13.26mil; 51.16mil + 13.53mil; 51.65mil + 13.72mil; 52.31mil + 13.81mil; 53.11mil + 13.81mil; 59.71mil + 20.32mil; 59.71mil + 21.08mil; 59.8mil + 21.72mil; 59.98mil + 22.2mil; 60.28mil + 22.57mil; 60.71mil + 22.78mil; 61.26mil + 22.87mil; 61.93mil + 22.78mil; 62.57mil + 22.57mil; 63.11mil + 22.2mil; 63.51mil + 21.72mil; 63.81mil + 21.05mil; 63.96mil + 20.26mil; 64.03mil + 20.07mil; 64.03mil + 19.53mil; 64.03mil + 18.61mil; 64.03mil + 17.37mil; 64.03mil + 15.75mil; 64.03mil + 13.72mil; 64.03mil + 13.72mil; 70.69mil + 13.65mil; 71.48mil + 13.47mil; 72.09mil + 13.2mil; 72.6mil + 12.8mil; 72.94mil + 12.29mil; 73.15mil + 11.68mil; 73.21mil + 10.98mil; 73.15mil + 10.4mil; 72.97mil + 9.94mil; 72.6mil + 9.64mil; 72.15mil + 9.46mil; 71.54mil + 9.4mil; 70.75mil + 9.4mil; 64.03mil + 9.18mil; 64.03mil + 8.64mil; 64.03mil + 7.69mil; 64.03mil + 6.38mil; 64.03mil + 4.68mil; 64.03mil + 2.55mil; 64.03mil + 1.76mil; 63.96mil + 1.12mil; 63.78mil + 0.64mil; 63.48mil + 0.27mil; 63.05mil + 0.06mil; 62.5mil + 0.0mil; 61.77mil + 0.06mil; 61.17mil + 0.27mil; 60.62mil + 0.64mil; 60.22mil + 1.12mil; 59.92mil + 1.79mil; 59.77mil + 2.61mil; 59.68mil + 9.4mil; 59.68mil + } + } + height = 63.33mil + } + ha:, { + width=6mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 2.19mil; 79.17mil + 2.37mil; 78.57mil + 2.65mil; 78.05mil + 2.95mil; 77.65mil + 3.35mil; 77.38mil + 3.77mil; 77.2mil + 4.32mil; 77.14mil + 4.99mil; 77.2mil + 5.57mil; 77.38mil + 6.02mil; 77.65mil + 6.33mil; 78.02mil + 6.51mil; 78.5mil + 6.6mil; 79.11mil + 6.57mil; 79.36mil + 6.57mil; 79.6mil + 6.54mil; 79.84mil + 6.51mil; 80.06mil + 6.45mil; 80.3mil + 6.42mil; 80.57mil + 4.44mil; 88.57mil + 4.2mil; 89.21mil + 3.92mil; 89.73mil + 3.59mil; 90.15mil + 3.19mil; 90.46mil + 2.74mil; 90.61mil + 2.19mil; 90.7mil + 1.52mil; 90.64mil + 0.97mil; 90.46mil + 0.55mil; 90.18mil + 0.24mil; 89.79mil + 0.06mil; 89.27mil + 0.0mil; 88.63mil + 0.0mil; 88.39mil + 0.03mil; 88.12mil + 0.06mil; 87.81mil + 0.12mil; 87.48mil + 0.18mil; 87.11mil + 0.3mil; 86.72mil + } + } + height = 63.33mil + } + ha:- { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 2.34mil; 59.58mil + 2.83mil; 59.58mil + 4.35mil; 59.58mil + 6.87mil; 59.58mil + 10.4mil; 59.58mil + 14.93mil; 59.58mil + 20.68mil; 59.58mil + 21.32mil; 59.68mil + 21.87mil; 59.86mil + 22.29mil; 60.19mil + 22.6mil; 60.62mil + 22.78mil; 61.2mil + 22.87mil; 61.93mil + 22.78mil; 62.57mil + 22.6mil; 63.08mil + 22.26mil; 63.48mil + 21.84mil; 63.75mil + 21.26mil; 63.93mil + 20.53mil; 63.96mil + 2.25mil; 63.96mil + 1.55mil; 63.9mil + 1.0mil; 63.72mil + 0.54mil; 63.42mil + 0.24mil; 62.99mil + 0.06mil; 62.41mil + 0.0mil; 61.68mil + 0.06mil; 61.08mil + 0.24mil; 60.53mil + 0.57mil; 60.13mil + 1.0mil; 59.83mil + 1.58mil; 59.68mil + } + } + height = 63.33mil + } + ha:. { + width=4mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 80.0mil + 0.0mil; 79.93mil + 0.0mil; 79.66mil + 0.0mil; 79.2mil + 0.0mil; 78.57mil + 0.0mil; 77.77mil + 0.0mil; 76.74mil + 0.03mil; 75.77mil + 0.21mil; 74.95mil + 0.52mil; 74.34mil + 0.91mil; 73.88mil + 1.46mil; 73.61mil + 2.13mil; 73.49mil + 2.86mil; 73.61mil + 3.5mil; 73.88mil + 3.98mil; 74.37mil + 4.32mil; 75.04mil + 4.53mil; 75.89mil + 4.62mil; 76.95mil + 4.53mil; 77.9mil + 4.35mil; 78.66mil + 4.01mil; 79.23mil + 3.59mil; 79.66mil + 3.01mil; 79.93mil + 2.28mil; 80.0mil + 1.58mil; 79.93mil + 1.0mil; 79.66mil + 0.55mil; 79.2mil + 0.24mil; 78.57mil + 0.06mil; 77.77mil + } + } + height = 63.33mil + } + ha:/ { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 77.96mil + 0.0mil; 77.74mil + 0.03mil; 77.47mil + 0.12mil; 77.17mil + 0.21mil; 76.83mil + 0.36mil; 76.47mil + 0.55mil; 76.04mil + 18.25mil; 35.98mil + 18.52mil; 35.4mil + 18.86mil; 34.95mil + 19.22mil; 34.55mil + 19.62mil; 34.31mil + 20.01mil; 34.12mil + 20.5mil; 34.06mil + 21.14mil; 34.12mil + 21.69mil; 34.31mil + 22.11mil; 34.58mil + 22.42mil; 34.98mil + 22.6mil; 35.49mil + 22.69mil; 36.13mil + 22.66mil; 36.41mil + 22.63mil; 36.68mil + 22.6mil; 36.92mil + 22.54mil; 37.2mil + 22.48mil; 37.44mil + 22.39mil; 37.68mil + 4.53mil; 78.11mil + 4.23mil; 78.69mil + 3.92mil; 79.17mil + 3.56mil; 79.54mil + 3.19mil; 79.78mil + 2.8mil; 79.96mil + 2.37mil; 80.0mil + 1.64mil; 79.96mil + 1.03mil; 79.78mil + 0.58mil; 79.51mil + 0.24mil; 79.11mil + 0.06mil; 78.6mil + } + } + height = 63.33mil + } + ha:0 { + width=23mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 11.62mil; 34.06mil + 12.92mil; 34.16mil + 14.14mil; 34.43mil + 15.27mil; 34.89mil + 16.27mil; 35.49mil + 17.15mil; 36.28mil + 17.97mil; 37.29mil + + 11.46mil; 38.44mil + 10.8mil; 38.51mil + 10.22mil; 38.66mil + 9.67mil; 38.9mil + 9.21mil; 39.27mil + 8.82mil; 39.72mil + 8.48mil; 40.27mil + 7.72mil; 41.88mil + 7.02mil; 43.55mil + 6.41mil; 45.29mil + 5.9mil; 47.08mil + 5.41mil; 49.0mil + 5.02mil; 51.01mil + 4.83mil; 51.95mil + 4.71mil; 52.89mil + 4.62mil; 53.87mil + 4.53mil; 54.81mil + 4.5mil; 55.78mil + 4.5mil; 56.76mil + 4.5mil; 57.49mil + 4.5mil; 58.19mil + 4.56mil; 58.89mil + 4.59mil; 59.58mil + 4.68mil; 60.28mil + 4.77mil; 60.98mil + 5.08mil; 63.23mil + 5.47mil; 65.33mil + 5.93mil; 67.31mil + 6.48mil; 69.2mil + 7.08mil; 70.96mil + 7.78mil; 72.66mil + 8.21mil; 73.55mil + 8.73mil; 74.28mil + 9.3mil; 74.82mil + 9.94mil; 75.25mil + 10.64mil; 75.49mil + 11.43mil; 75.55mil + 12.16mil; 75.49mil + 12.83mil; 75.28mil + 13.47mil; 74.92mil + 14.05mil; 74.43mil + 14.57mil; 73.76mil + 15.08mil; 72.94mil + 15.69mil; 71.6mil + 16.3mil; 70.08mil + 16.82mil; 68.41mil + 17.3mil; 66.55mil + 17.7mil; 64.57mil + 18.1mil; 62.32mil + 18.22mil; 61.38mil + 18.31mil; 60.44mil + 18.4mil; 59.52mil + 18.46mil; 58.58mil + 18.49mil; 57.67mil + 18.52mil; 56.73mil + 18.49mil; 55.84mil + 18.46mil; 54.96mil + 18.4mil; 54.08mil + 18.31mil; 53.23mil + 18.22mil; 52.38mil + 18.1mil; 51.49mil + 17.67mil; 49.43mil + 17.21mil; 47.42mil + 16.64mil; 45.5mil + 16.03mil; 43.68mil + 15.3mil; 41.94mil + 14.51mil; 40.21mil + 14.14mil; 39.69mil + 13.75mil; 39.24mil + 13.29mil; 38.9mil + 12.74mil; 38.66mil + 12.13mil; 38.51mil + 11.46mil; 38.44mil + 17.97mil; 37.29mil + 19.01mil; 39.05mil + 19.98mil; 41.03mil + 20.8mil; 43.22mil + 21.53mil; 45.65mil + 22.14mil; 48.3mil + 22.66mil; 51.25mil + 22.75mil; 52.16mil + 22.87mil; 53.08mil + 22.93mil; 53.99mil + 22.99mil; 54.87mil + 23.02mil; 55.78mil + 23.05mil; 56.73mil + 23.02mil; 57.7mil + 22.99mil; 58.67mil + 22.93mil; 59.65mil + 22.84mil; 60.59mil + 22.75mil; 61.56mil + 22.63mil; 62.54mil + 22.14mil; 65.39mil + 21.53mil; 68.04mil + 20.83mil; 70.47mil + 20.04mil; 72.69mil + 19.13mil; 74.7mil + 18.1mil; 76.53mil + 17.27mil; 77.59mil + 16.36mil; 78.47mil + 15.36mil; 79.14mil + 14.2mil; 79.63mil + 12.92mil; 79.9mil + 11.53mil; 80.0mil + 10.16mil; 79.9mil + 8.88mil; 79.63mil + 7.75mil; 79.11mil + 6.72mil; 78.44mil + 5.78mil; 77.53mil + 4.95mil; 76.41mil + 4.04mil; 74.82mil + 3.22mil; 72.97mil + 2.43mil; 70.84mil + 1.73mil; 68.44mil + 1.06mil; 65.76mil + 0.48mil; 62.69mil + 0.33mil; 61.81mil + 0.21mil; 60.89mil + 0.12mil; 59.98mil + 0.03mil; 59.07mil + 0.0mil; 58.12mil + 0.0mil; 57.15mil + 0.0mil; 56.18mil + 0.03mil; 55.2mil + 0.12mil; 54.23mil + 0.21mil; 53.23mil + 0.33mil; 52.25mil + 0.51mil; 51.22mil + 1.06mil; 48.3mil + 1.67mil; 45.65mil + 2.34mil; 43.28mil + 3.07mil; 41.18mil + 3.83mil; 39.39mil + 4.71mil; 37.81mil + 5.53mil; 36.68mil + 6.48mil; 35.74mil + 7.57mil; 35.04mil + 8.76mil; 34.49mil + 10.1mil; 34.19mil + } + } + height = 63.33mil + } + ha:1 { + width=13mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 9.24mil; 35.04mil + 9.58mil; 34.76mil + 9.91mil; 34.52mil + 10.28mil; 34.34mil + 10.64mil; 34.19mil + 11.01mil; 34.09mil + 11.4mil; 34.06mil + 12.07mil; 34.16mil + 12.65mil; 34.37mil + 13.11mil; 34.7mil + 13.41mil; 35.19mil + 13.59mil; 35.83mil + 13.68mil; 36.59mil + 13.68mil; 77.26mil + 13.62mil; 78.05mil + 13.44mil; 78.72mil + 13.14mil; 79.2mil + 12.71mil; 79.57mil + 12.16mil; 79.78mil + 11.49mil; 79.84mil + 10.79mil; 79.78mil + 10.25mil; 79.57mil + 9.79mil; 79.2mil + 9.49mil; 78.72mil + 9.3mil; 78.05mil + 9.24mil; 77.23mil + 9.24mil; 76.25mil + 9.24mil; 73.3mil + 9.24mil; 68.38mil + 9.24mil; 61.47mil + 9.24mil; 52.62mil + 9.24mil; 41.36mil + 3.95mil; 46.66mil + 3.68mil; 46.93mil + 3.4mil; 47.11mil + 3.13mil; 47.3mil + 2.86mil; 47.39mil + 2.58mil; 47.48mil + 2.31mil; 47.48mil + 1.58mil; 47.45mil + 1.0mil; 47.27mil + 0.57mil; 46.99mil + 0.24mil; 46.6mil + 0.06mil; 46.08mil + 0.0mil; 45.44mil + 0.0mil; 45.11mil + 0.09mil; 44.8mil + 0.21mil; 44.47mil + 0.36mil; 44.16mil + 0.57mil; 43.86mil + 0.88mil; 43.52mil + } + } + height = 63.33mil + } + ha:2 { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 2.37mil; 45.35mil + 1.64mil; 45.32mil + 1.03mil; 45.14mil + 0.57mil; 44.83mil + 0.24mil; 44.44mil + 0.06mil; 43.89mil + 0.0mil; 43.22mil + 0.0mil; 43.01mil + 0.03mil; 42.73mil + 0.12mil; 42.46mil + 0.21mil; 42.16mil + 0.36mil; 41.82mil + 0.54mil; 41.46mil + 1.18mil; 40.27mil + 1.85mil; 39.2mil + 2.58mil; 38.26mil + 3.31mil; 37.41mil + 4.1mil; 36.71mil + 4.95mil; 36.07mil + 5.99mil; 35.46mil + 7.02mil; 34.98mil + 8.12mil; 34.58mil + 9.21mil; 34.31mil + 10.31mil; 34.12mil + 11.49mil; 34.06mil + 13.32mil; 34.19mil + 15.02mil; 34.55mil + 16.6mil; 35.16mil + 18.03mil; 36.01mil + 19.34mil; 37.11mil + 20.56mil; 38.47mil + 21.29mil; 39.57mil + 21.87mil; 40.7mil + 22.35mil; 41.82mil + 22.69mil; 42.98mil + 22.87mil; 44.16mil + 22.96mil; 45.41mil + 22.9mil; 46.5mil + 22.72mil; 47.57mil + 22.45mil; 48.66mil + 22.05mil; 49.73mil + 21.56mil; 50.82mil + 20.95mil; 51.92mil + 6.2mil; 75.74mil + 20.62mil; 75.74mil + 21.29mil; 75.83mil + 21.87mil; 76.01mil + 22.32mil; 76.31mil + 22.63mil; 76.74mil + 22.81mil; 77.32mil + 22.9mil; 78.02mil + 22.81mil; 78.63mil + 22.6mil; 79.11mil + 22.26mil; 79.51mil + 21.78mil; 79.78mil + 21.17mil; 79.96mil + 20.41mil; 80.0mil + 2.73mil; 80.0mil + 1.88mil; 79.96mil + 1.21mil; 79.78mil + 0.7mil; 79.54mil + 0.33mil; 79.14mil + 0.09mil; 78.69mil + 0.03mil; 78.05mil + 0.03mil; 77.77mil + 0.06mil; 77.53mil + 0.12mil; 77.26mil + 0.18mil; 77.01mil + 0.27mil; 76.8mil + 0.42mil; 76.56mil + 16.79mil; 50.19mil + 17.27mil; 49.33mil + 17.7mil; 48.48mil + 18.03mil; 47.66mil + 18.25mil; 46.9mil + 18.4mil; 46.14mil + 18.46mil; 45.41mil + 18.4mil; 44.59mil + 18.25mil; 43.77mil + 18.03mil; 42.98mil + 17.7mil; 42.25mil + 17.3mil; 41.55mil + 16.79mil; 40.85mil + 16.06mil; 40.15mil + 15.27mil; 39.54mil + 14.41mil; 39.08mil + 13.47mil; 38.75mil + 12.47mil; 38.57mil + 11.34mil; 38.47mil + 9.97mil; 38.63mil + 8.7mil; 39.05mil + 7.51mil; 39.72mil + 6.41mil; 40.7mil + 5.44mil; 41.91mil + 4.5mil; 43.46mil + 4.13mil; 44.04mil + 3.8mil; 44.53mil + 3.46mil; 44.89mil + 3.1mil; 45.14mil + 2.73mil; 45.32mil + } + } + height = 63.33mil + } + ha:3 { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 2.95mil; 33.91mil + 3.19mil; 33.91mil + 3.98mil; 33.91mil + 5.29mil; 33.91mil + 7.11mil; 33.91mil + 9.46mil; 33.91mil + 12.47mil; 33.91mil + 13.81mil; 34.03mil + 15.11mil; 34.31mil + 16.36mil; 34.79mil + 17.58mil; 35.49mil + 18.73mil; 36.38mil + 19.89mil; 37.47mil + 20.8mil; 38.6mil + 21.56mil; 39.78mil + 22.14mil; 41.03mil + 22.57mil; 42.34mil + 22.84mil; 43.71mil + 22.93mil; 45.17mil + 22.78mil; 46.96mil + 22.38mil; 48.66mil + 21.75mil; 50.28mil + 20.83mil; 51.83mil + 19.65mil; 53.26mil + 18.19mil; 54.63mil + 19.59mil; 55.78mil + 20.74mil; 57.03mil + 21.62mil; 58.37mil + 22.26mil; 59.77mil + 22.66mil; 61.26mil + 22.81mil; 62.87mil + 22.81mil; 63.08mil + 22.81mil; 63.63mil + 22.81mil; 64.54mil + 22.81mil; 65.82mil + 22.81mil; 67.49mil + 22.81mil; 69.56mil + 22.69mil; 70.87mil + 22.41mil; 72.12mil + 21.96mil; 73.33mil + 21.32mil; 74.55mil + 20.47mil; 75.71mil + 19.43mil; 76.86mil + 18.37mil; 77.77mil + 17.24mil; 78.53mil + 16.0mil; 79.11mil + 14.66mil; 79.51mil + 13.23mil; 79.78mil + 11.65mil; 79.84mil + 11.37mil; 79.84mil + 10.64mil; 79.84mil + 9.4mil; 79.84mil + 7.66mil; 79.84mil + 5.41mil; 79.84mil + 2.58mil; 79.84mil + 1.79mil; 79.78mil + 1.12mil; 79.6mil + 0.64mil; 79.3mil + 0.27mil; 78.87mil + 0.06mil; 78.32mil + 0.0mil; 77.59mil + 0.06mil; 76.98mil + 0.27mil; 76.47mil + 0.67mil; 76.07mil + 1.18mil; 75.8mil + 1.85mil; 75.61mil + 2.73mil; 75.55mil + 2.95mil; 75.55mil + 3.62mil; 75.55mil + 4.71mil; 75.55mil + 6.26mil; 75.55mil + 8.24mil; 75.55mil + 10.76mil; 75.55mil + 11.92mil; 75.52mil + 13.02mil; 75.34mil + 14.02mil; 75.04mil + 14.96mil; 74.61mil + 15.78mil; 74.06mil + 16.57mil; 73.36mil + 17.15mil; 72.66mil + 17.64mil; 71.9mil + 18.03mil; 71.05mil + 18.31mil; 70.14mil + 18.49mil; 69.14mil + 18.55mil; 68.04mil + 18.55mil; 64.09mil + 18.49mil; 63.11mil + 18.34mil; 62.17mil + 18.1mil; 61.32mil + 17.73mil; 60.5mil + 17.27mil; 59.77mil + 16.73mil; 59.07mil + 15.97mil; 58.37mil + 15.21mil; 57.79mil + 14.41mil; 57.33mil + 13.62mil; 57.0mil + 12.83mil; 56.82mil + 11.98mil; 56.73mil + 7.36mil; 56.73mil + 6.57mil; 56.66mil + 5.96mil; 56.48mil + 5.44mil; 56.18mil + 5.11mil; 55.75mil + 4.89mil; 55.17mil + 4.83mil; 54.44mil + 4.89mil; 53.84mil + 5.11mil; 53.35mil + 5.44mil; 52.95mil + 5.93mil; 52.68mil + 6.57mil; 52.5mil + 7.39mil; 52.44mil + 11.49mil; 52.44mil + 12.41mil; 52.41mil + 13.29mil; 52.22mil + 14.11mil; 51.95mil + 14.9mil; 51.55mil + 15.66mil; 51.04mil + 16.39mil; 50.37mil + 17.03mil; 49.64mil + 17.58mil; 48.88mil + 18.0mil; 48.06mil + 18.28mil; 47.2mil + 18.46mil; 46.32mil + 18.55mil; 45.38mil + 18.49mil; 44.47mil + 18.34mil; 43.62mil + 18.1mil; 42.82mil + 17.76mil; 42.09mil + 17.33mil; 41.39mil + 16.82mil; 40.76mil + 16.03mil; 40.03mil + 15.21mil; 39.45mil + 14.41mil; 38.96mil + 13.59mil; 38.63mil + 12.77mil; 38.44mil + 11.95mil; 38.35mil + 2.95mil; 38.35mil + 2.07mil; 38.29mil + 1.37mil; 38.11mil + 0.82mil; 37.81mil + 0.42mil; 37.38mil + 0.18mil; 36.8mil + 0.12mil; 36.07mil + 0.18mil; 35.43mil + 0.42mil; 34.89mil + 0.79mil; 34.46mil + 1.34mil; 34.19mil + 2.03mil; 34.0mil + } + } + height = 63.33mil + } + ha:4 { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 9.18mil; 35.62mil + 9.37mil; 35.1mil + 9.64mil; 34.7mil + 9.97mil; 34.37mil + 10.37mil; 34.12mil + 10.86mil; 33.97mil + 11.43mil; 33.91mil + 12.04mil; 33.97mil + 12.59mil; 34.16mil + 12.99mil; 34.46mil + 13.29mil; 34.85mil + 13.44mil; 35.37mil + 13.53mil; 36.01mil + 13.5mil; 36.19mil + 13.5mil; 36.38mil + 13.47mil; 36.59mil + 13.41mil; 36.8mil + 13.38mil; 37.01mil + 13.32mil; 37.23mil + 5.02mil; 66.19mil + 16.12mil; 66.19mil + 16.12mil; 59.55mil + 16.18mil; 58.79mil + 16.36mil; 58.15mil + 16.67mil; 57.67mil + 17.09mil; 57.3mil + 17.64mil; 57.09mil + 18.34mil; 57.0mil + 18.98mil; 57.09mil + 19.53mil; 57.3mil + 19.95mil; 57.7mil + 20.22mil; 58.22mil + 20.41mil; 58.89mil + 20.5mil; 59.74mil + 20.5mil; 66.22mil + 20.62mil; 66.22mil + 20.99mil; 66.22mil + 21.65mil; 66.22mil + 22.54mil; 66.22mil + 23.69mil; 66.22mil + 25.18mil; 66.22mil + 25.85mil; 66.31mil + 26.4mil; 66.49mil + 26.83mil; 66.82mil + 27.13mil; 67.28mil + 27.31mil; 67.89mil + 27.4mil; 68.62mil + 27.31mil; 69.23mil + 27.13mil; 69.71mil + 26.83mil; 70.08mil + 26.37mil; 70.35mil + 25.79mil; 70.54mil + 25.09mil; 70.57mil + 20.5mil; 70.57mil + 20.5mil; 77.44mil + 20.41mil; 78.2mil + 20.22mil; 78.81mil + 19.92mil; 79.3mil + 19.49mil; 79.63mil + 18.95mil; 79.84mil + 18.25mil; 79.9mil + 17.58mil; 79.84mil + 17.06mil; 79.66mil + 16.64mil; 79.33mil + 16.33mil; 78.87mil + 16.18mil; 78.29mil + 16.12mil; 77.53mil + 16.12mil; 70.66mil + 2.16mil; 70.66mil + 1.49mil; 70.63mil + 0.94mil; 70.44mil + 0.51mil; 70.17mil + 0.24mil; 69.77mil + 0.06mil; 69.26mil + 0.0mil; 68.62mil + 0.0mil; 68.38mil + 0.03mil; 68.1mil + 0.09mil; 67.77mil + 0.18mil; 67.37mil + 0.27mil; 66.95mil + 0.42mil; 66.43mil + 0.64mil; 65.61mil + 1.37mil; 63.05mil + 2.58mil; 58.82mil + 4.26mil; 52.89mil + 6.41mil; 45.29mil + } + } + height = 63.33mil + } + ha:5 { + width=23mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 36.38mil + 0.06mil; 35.68mil + 0.27mil; 35.1mil + 0.64mil; 34.67mil + 1.16mil; 34.34mil + 1.79mil; 34.16mil + 2.65mil; 34.06mil + 3.13mil; 34.06mil + 4.59mil; 34.06mil + 7.06mil; 34.06mil + 10.49mil; 34.06mil + 14.9mil; 34.06mil + 20.53mil; 34.06mil + 21.29mil; 34.12mil + 21.9mil; 34.31mil + 22.42mil; 34.61mil + 22.75mil; 35.04mil + 22.96mil; 35.58mil + 23.06mil; 36.25mil + 22.96mil; 36.92mil + 22.78mil; 37.47mil + 22.45mil; 37.9mil + 21.99mil; 38.2mil + 21.38mil; 38.38mil + 20.65mil; 38.44mil + 4.47mil; 38.44mil + 4.47mil; 52.53mil + 11.22mil; 52.53mil + 13.08mil; 52.65mil + 14.84mil; 53.01mil + 16.49mil; 53.62mil + 17.98mil; 54.47mil + 19.35mil; 55.54mil + 20.65mil; 56.91mil + 21.35mil; 57.91mil + 21.96mil; 58.98mil + 22.42mil; 60.1mil + 22.75mil; 61.29mil + 22.93mil; 62.57mil + 23.03mil; 63.9mil + 23.03mil; 68.8mil + 22.93mil; 70.38mil + 22.66mil; 71.84mil + 22.2mil; 73.21mil + 21.57mil; 74.49mil + 20.74mil; 75.65mil + 19.71mil; 76.74mil + 18.52mil; 77.74mil + 17.31mil; 78.57mil + 16.03mil; 79.17mil + 14.72mil; 79.63mil + 13.38mil; 79.9mil + 11.98mil; 80.0mil + 2.49mil; 80.0mil + 1.76mil; 79.96mil + 1.19mil; 79.78mil + 0.73mil; 79.48mil + 0.39mil; 79.08mil + 0.21mil; 78.53mil + 0.15mil; 77.87mil + 0.21mil; 77.23mil + 0.43mil; 76.68mil + 0.76mil; 76.25mil + 1.25mil; 75.98mil + 1.89mil; 75.8mil + 2.71mil; 75.71mil + 11.16mil; 75.71mil + 12.38mil; 75.65mil + 13.5mil; 75.43mil + 14.51mil; 75.07mil + 15.45mil; 74.58mil + 16.27mil; 73.91mil + 17.03mil; 73.09mil + 17.49mil; 72.45mil + 17.85mil; 71.75mil + 18.16mil; 70.99mil + 18.37mil; 70.23mil + 18.49mil; 69.41mil + 18.55mil; 68.5mil + 18.55mil; 63.9mil + 18.49mil; 63.02mil + 18.34mil; 62.17mil + 18.1mil; 61.38mil + 17.76mil; 60.62mil + 17.31mil; 59.89mil + 16.76mil; 59.16mil + 16.03mil; 58.49mil + 15.18mil; 57.94mil + 14.23mil; 57.49mil + 13.14mil; 57.18mil + 11.95mil; 57.0mil + 10.62mil; 56.91mil + 2.22mil; 56.91mil + 1.52mil; 56.85mil + 0.97mil; 56.63mil + 0.55mil; 56.27mil + 0.24mil; 55.78mil + 0.06mil; 55.14mil + 0.0mil; 54.32mil + } + } + height = 63.33mil + } + ha:6 { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 4.68mil; 52.56mil + 4.87mil; 52.56mil + 5.41mil; 52.56mil + 6.33mil; 52.56mil + 7.63mil; 52.56mil + 9.28mil; 52.56mil + 11.41mil; 52.56mil + 13.05mil; 52.68mil + 14.6mil; 52.98mil + 16.06mil; 53.5mil + 17.43mil; 54.23mil + 18.68mil; 55.17mil + 19.92mil; 56.36mil + 20.81mil; 57.49mil + 21.57mil; 58.61mil + 22.14mil; 59.77mil + 22.54mil; 60.95mil + 22.81mil; 62.17mil + 22.9mil; 63.42mil + 22.9mil; 63.6mil + 22.9mil; 64.12mil + 22.9mil; 64.94mil + 22.9mil; 66.12mil + 22.9mil; 67.65mil + 22.9mil; 69.56mil + 22.78mil; 70.87mil + 22.48mil; 72.15mil + 21.96mil; 73.42mil + 21.23mil; 74.67mil + 20.29mil; 75.92mil + 19.1mil; 77.17mil + 18.07mil; 78.05mil + 16.88mil; 78.75mil + 15.57mil; 79.3mil + 14.14mil; 79.69mil + 12.59mil; 79.93mil + 10.86mil; 80.0mil + 9.46mil; 79.93mil + 8.12mil; 79.66mil + 6.81mil; 79.2mil + 5.6mil; 78.6mil + 4.41mil; 77.8mil + 3.25mil; 76.77mil + 2.25mil; 75.71mil + 1.43mil; 74.58mil + 0.82mil; 73.42mil + 0.36mil; 72.21mil + 0.09mil; 70.93mil + 0.0mil; 69.56mil + 0.0mil; 53.68mil + 0.12mil; 51.43mil + 0.58mil; 49.18mil + 1.31mil; 46.96mil + 2.31mil; 44.8mil + 3.65mil; 42.67mil + + 4.35mil; 69.11mil + 4.41mil; 69.99mil + 4.62mil; 70.84mil + 4.96mil; 71.66mil + 5.44mil; 72.48mil + 6.08mil; 73.27mil + 6.9mil; 74.06mil + 7.51mil; 74.58mil + 8.18mil; 74.98mil + 8.91mil; 75.31mil + 9.7mil; 75.52mil + 10.55mil; 75.68mil + 11.5mil; 75.71mil + 12.2mil; 75.68mil + 12.99mil; 75.49mil + 13.78mil; 75.19mil + 14.63mil; 74.76mil + 15.51mil; 74.25mil + 16.49mil; 73.55mil + 17.09mil; 73.03mil + 17.58mil; 72.39mil + 17.98mil; 71.66mil + 18.25mil; 70.87mil + 18.43mil; 69.99mil + 18.49mil; 68.98mil + 18.49mil; 64.36mil + 18.43mil; 63.39mil + 18.25mil; 62.47mil + 17.98mil; 61.56mil + 17.58mil; 60.74mil + 17.06mil; 59.92mil + 16.42mil; 59.13mil + 15.73mil; 58.49mil + 15.0mil; 57.97mil + 14.2mil; 57.55mil + 13.35mil; 57.24mil + 12.44mil; 57.09mil + 11.47mil; 57.0mil + 4.35mil; 57.0mil + 4.35mil; 69.11mil + 3.65mil; 42.67mil + 5.32mil; 40.51mil + 6.45mil; 39.33mil + 7.7mil; 38.2mil + 9.06mil; 37.17mil + 10.55mil; 36.19mil + 12.17mil; 35.34mil + 13.96mil; 34.55mil + 14.33mil; 34.43mil + 14.72mil; 34.31mil + 15.06mil; 34.22mil + 15.39mil; 34.12mil + 15.73mil; 34.09mil + 16.03mil; 34.06mil + 16.67mil; 34.16mil + 17.22mil; 34.34mil + 17.64mil; 34.67mil + 17.95mil; 35.13mil + 18.13mil; 35.71mil + 18.22mil; 36.44mil + 18.16mil; 36.89mil + 18.01mil; 37.29mil + 17.73mil; 37.65mil + 17.37mil; 37.99mil + 16.88mil; 38.26mil + 16.3mil; 38.51mil + 14.9mil; 39.05mil + 13.66mil; 39.63mil + 12.47mil; 40.24mil + 11.41mil; 40.94mil + 10.43mil; 41.67mil + 9.55mil; 42.46mil + 8.24mil; 43.92mil + 7.15mil; 45.44mil + 6.23mil; 47.05mil + 5.54mil; 48.79mil + 4.99mil; 50.58mil + } + } + height = 63.33mil + } + ha:7 { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 20.22mil; 34.06mil + 20.99mil; 34.12mil + 21.62mil; 34.31mil + 22.11mil; 34.61mil + 22.48mil; 35.01mil + 22.69mil; 35.55mil + 22.78mil; 36.19mil + 22.75mil; 36.5mil + 22.69mil; 36.89mil + 22.6mil; 37.41mil + 22.48mil; 38.08mil + 22.32mil; 38.84mil + 22.14mil; 39.75mil + 21.9mil; 40.82mil + 21.2mil; 43.95mil + 20.04mil; 49.18mil + 18.43mil; 56.51mil + 16.33mil; 65.94mil + 13.72mil; 77.87mil + 13.5mil; 78.53mil + 13.26mil; 79.05mil + 12.95mil; 79.48mil + 12.56mil; 79.78mil + 12.13mil; 79.93mil + 11.62mil; 80.0mil + 10.89mil; 79.96mil + 10.31mil; 79.78mil + 9.85mil; 79.51mil + 9.52mil; 79.11mil + 9.34mil; 78.63mil + 9.27mil; 77.99mil + 9.27mil; 77.87mil + 9.27mil; 77.71mil + 9.27mil; 77.59mil + 9.3mil; 77.44mil + 9.34mil; 77.29mil + 9.37mil; 77.14mil + 17.94mil; 38.54mil + 4.32mil; 38.54mil + 4.32mil; 38.63mil + 4.32mil; 38.81mil + 4.32mil; 39.11mil + 4.32mil; 39.54mil + 4.32mil; 40.12mil + 4.32mil; 40.82mil + 4.22mil; 41.49mil + 4.04mil; 42.03mil + 3.74mil; 42.46mil + 3.31mil; 42.73mil + 2.76mil; 42.92mil + 2.1mil; 42.98mil + 1.46mil; 42.92mil + 0.91mil; 42.73mil + 0.51mil; 42.43mil + 0.21mil; 42.0mil + 0.06mil; 41.46mil + 0.0mil; 40.73mil + 0.0mil; 40.6mil + 0.0mil; 40.24mil + 0.0mil; 39.6mil + 0.0mil; 38.72mil + 0.0mil; 37.56mil + 0.0mil; 36.1mil + 0.06mil; 35.49mil + 0.24mil; 34.98mil + 0.57mil; 34.58mil + 1.06mil; 34.31mil + 1.64mil; 34.12mil + 2.43mil; 34.06mil + 2.92mil; 34.06mil + 4.38mil; 34.06mil + 6.81mil; 34.06mil + 10.25mil; 34.06mil + 14.63mil; 34.06mil + } + } + height = 63.33mil + } + ha:8 { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.2 { + 4.59mil; 54.6mil + 3.19mil; 53.35mil + 2.04mil; 51.95mil + 1.15mil; 50.4mil + 0.51mil; 48.66mil + 0.12mil; 46.81mil + 0.0mil; 44.71mil + 0.09mil; 43.1mil + 0.42mil; 41.58mil + 1.0mil; 40.18mil + 6.63mil; 40.24mil + 5.93mil; 41.03mil + 5.38mil; 41.82mil + 4.96mil; 42.61mil + 4.65mil; 43.43mil + 4.47mil; 44.28mil + 4.41mil; 45.14mil + 4.44mil; 45.96mil + 4.56mil; 46.75mil + 4.77mil; 47.54mil + 5.08mil; 48.3mil + 5.47mil; 49.06mil + 5.96mil; 49.82mil + 6.57mil; 50.61mil + 7.33mil; 51.25mil + 8.15mil; 51.74mil + 9.09mil; 52.1mil + 10.16mil; 52.31mil + 11.34mil; 52.38mil + 12.44mil; 52.35mil + 13.47mil; 52.16mil + 14.42mil; 51.86mil + 15.27mil; 51.46mil + 16.03mil; 50.92mil + 16.73mil; 50.25mil + 17.28mil; 49.52mil + 17.73mil; 48.76mil + 18.1mil; 47.96mil + 18.37mil; 47.14mil + 18.52mil; 46.26mil + 18.58mil; 45.35mil + 18.49mil; 44.47mil + 18.31mil; 43.58mil + 17.97mil; 42.73mil + 17.52mil; 41.91mil + 16.91mil; 41.15mil + 16.18mil; 40.36mil + 15.45mil; 39.78mil + 14.69mil; 39.33mil + 13.9mil; 38.93mil + 13.05mil; 38.69mil + 12.2mil; 38.51mil + 11.28mil; 38.44mil + 10.34mil; 38.51mil + 9.46mil; 38.66mil + 8.67mil; 38.9mil + 7.91mil; 39.24mil + 7.24mil; 39.69mil + 6.63mil; 40.24mil + 1.0mil; 40.18mil + 1.79mil; 38.9mil + 2.8mil; 37.68mil + 4.1mil; 36.56mil + 5.26mil; 35.77mil + 6.45mil; 35.1mil + 7.69mil; 34.58mil + 8.94mil; 34.22mil + 10.19mil; 34.0mil + 11.56mil; 33.91mil + 12.59mil; 33.97mil + 13.62mil; 34.09mil + 14.57mil; 34.28mil + 15.51mil; 34.58mil + 16.36mil; 34.92mil + 17.21mil; 35.37mil + 18.95mil; 36.65mil + 20.35mil; 38.05mil + 21.47mil; 39.63mil + 22.26mil; 41.36mil + 22.75mil; 43.25mil + 22.93mil; 45.35mil + 22.78mil; 47.3mil + 22.42mil; 49.06mil + 21.78mil; 50.67mil + 20.89mil; 52.16mil + 19.77mil; 53.5mil + 18.34mil; 54.69mil + 19.74mil; 55.96mil + 20.89mil; 57.33mil + 21.81mil; 58.79mil + 22.45mil; 60.35mil + 22.84mil; 61.99mil + 22.99mil; 63.78mil + 22.99mil; 68.98mil + 22.87mil; 70.44mil + 22.54mil; 71.84mil + 22.02mil; 73.21mil + 21.26mil; 74.52mil + 20.29mil; 75.8mil + 19.07mil; 77.07mil + 18.04mil; 77.93mil + 16.91mil; 78.63mil + 15.72mil; 79.17mil + 14.45mil; 79.57mil + 13.11mil; 79.81mil + 11.65mil; 79.87mil + 11.4mil; 56.88mil + 10.52mil; 56.94mil + 9.67mil; 57.12mil + 8.85mil; 57.36mil + 8.09mil; 57.76mil + 7.33mil; 58.22mil + 6.63mil; 58.82mil + 5.93mil; 59.55mil + 5.38mil; 60.31mil + 4.93mil; 61.11mil + 4.62mil; 61.93mil + 4.44mil; 62.78mil + 4.38mil; 63.69mil + 4.38mil; 69.23mil + 4.44mil; 69.99mil + 4.65mil; 70.75mil + 5.02mil; 71.54mil + 5.53mil; 72.33mil + 6.17mil; 73.15mil + 7.02mil; 73.97mil + 7.57mil; 74.43mil + 8.18mil; 74.82mil + 8.88mil; 75.1mil + 9.64mil; 75.31mil + 10.49mil; 75.43mil + 11.43mil; 75.46mil + 12.23mil; 75.43mil + 13.05mil; 75.25mil + 13.87mil; 74.98mil + 14.66mil; 74.61mil + 15.48mil; 74.12mil + 16.33mil; 73.49mil + 16.97mil; 72.88mil + 17.52mil; 72.18mil + 17.94mil; 71.39mil + 18.22mil; 70.5mil + 18.4mil; 69.56mil + 18.49mil; 68.5mil + 18.49mil; 63.96mil + 18.43mil; 63.11mil + 18.25mil; 62.26mil + 17.94mil; 61.44mil + 17.52mil; 60.59mil + 16.97mil; 59.77mil + 16.3mil; 58.89mil + 15.66mil; 58.28mil + 14.96mil; 57.79mil + 14.2mil; 57.39mil + 13.35mil; 57.12mil + 12.41mil; 56.94mil + 11.4mil; 56.88mil + 11.65mil; 79.87mil + 10.04mil; 79.81mil + 8.55mil; 79.6mil + 7.21mil; 79.23mil + 6.02mil; 78.75mil + 4.93mil; 78.11mil + 3.98mil; 77.29mil + 2.77mil; 75.98mil + 1.76mil; 74.67mil + 1.0mil; 73.33mil + 0.42mil; 71.96mil + 0.09mil; 70.63mil + 0.0mil; 69.17mil + 0.0mil; 63.54mil + 0.12mil; 61.93mil + 0.48mil; 60.38mil + 1.12mil; 58.85mil + 2.01mil; 57.39mil + 3.13mil; 56.0mil + } + } + height = 63.33mil + } + ha:9 { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 4.56mil; 77.74mil + 4.59mil; 77.26mil + 4.77mil; 76.83mil + 5.08mil; 76.44mil + 5.5mil; 76.07mil + 6.02mil; 75.77mil + 6.72mil; 75.49mil + 7.7mil; 75.16mil + 8.61mil; 74.76mil + 9.52mil; 74.34mil + 10.34mil; 73.85mil + 11.16mil; 73.3mil + 11.95mil; 72.69mil + 13.6mil; 71.17mil + 15.0mil; 69.5mil + 16.15mil; 67.74mil + 17.06mil; 65.82mil + 17.73mil; 63.78mil + 18.19mil; 61.56mil + 10.8mil; 61.56mil + 9.52mil; 61.5mil + 8.3mil; 61.29mil + 7.12mil; 60.89mil + 5.99mil; 60.38mil + 4.87mil; 59.71mil + 3.8mil; 58.85mil + 2.62mil; 57.73mil + 1.67mil; 56.54mil + 0.94mil; 55.27mil + 0.43mil; 53.96mil + 0.09mil; 52.59mil + 0.0mil; 51.1mil + 0.0mil; 50.95mil + 0.0mil; 50.4mil + 0.0mil; 49.52mil + 0.0mil; 48.3mil + 0.0mil; 46.72mil + 0.0mil; 44.68mil + 0.12mil; 43.04mil + 0.52mil; 41.49mil + 18.31mil; 45.81mil + 18.25mil; 44.83mil + 18.1mil; 43.89mil + 17.82mil; 43.04mil + 17.49mil; 42.22mil + 17.03mil; 41.49mil + 16.46mil; 40.76mil + 15.73mil; 40.09mil + 14.93mil; 39.54mil + 14.11mil; 39.11mil + 13.23mil; 38.81mil + 12.32mil; 38.63mil + 11.31mil; 38.54mil + 10.43mil; 38.6mil + 9.61mil; 38.75mil + 8.79mil; 39.02mil + 8.0mil; 39.36mil + 7.24mil; 39.81mil + 6.51mil; 40.39mil + 5.84mil; 41.06mil + 5.29mil; 41.79mil + 4.87mil; 42.61mil + 4.56mil; 43.46mil + 4.38mil; 44.41mil + 4.32mil; 45.44mil + 4.32mil; 50.37mil + 4.38mil; 51.37mil + 4.59mil; 52.31mil + 4.93mil; 53.2mil + 5.41mil; 54.02mil + 6.02mil; 54.78mil + 6.81mil; 55.51mil + 7.51mil; 56.03mil + 8.3mil; 56.42mil + 9.22mil; 56.76mil + 10.22mil; 56.97mil + 11.31mil; 57.12mil + 12.56mil; 57.15mil + 18.31mil; 57.15mil + 18.31mil; 56.85mil + 18.31mil; 55.93mil + 18.31mil; 54.35mil + 18.31mil; 52.19mil + 18.31mil; 49.36mil + 18.31mil; 45.81mil + 0.52mil; 41.49mil + 1.22mil; 40.0mil + 2.16mil; 38.6mil + 3.38mil; 37.29mil + 4.96mil; 35.98mil + 5.84mil; 35.4mil + 6.84mil; 34.95mil + 7.91mil; 34.55mil + 9.06mil; 34.31mil + 10.31mil; 34.12mil + 11.68mil; 34.06mil + 13.08mil; 34.19mil + 14.45mil; 34.46mil + 15.79mil; 34.95mil + 17.09mil; 35.62mil + 18.34mil; 36.47mil + 19.59mil; 37.53mil + 20.56mil; 38.63mil + 21.35mil; 39.81mil + 21.99mil; 41.09mil + 22.42mil; 42.46mil + 22.69mil; 43.92mil + 22.81mil; 45.53mil + 22.81mil; 45.93mil + 22.81mil; 47.08mil + 22.81mil; 49.0mil + 22.81mil; 51.71mil + 22.81mil; 55.14mil + 22.81mil; 59.52mil + 22.75mil; 61.01mil + 22.63mil; 62.41mil + 22.42mil; 63.78mil + 22.11mil; 65.06mil + 21.72mil; 66.31mil + 21.23mil; 67.52mil + 20.35mil; 69.32mil + 19.41mil; 70.96mil + 18.43mil; 72.42mil + 17.43mil; 73.73mil + 16.36mil; 74.85mil + 15.24mil; 75.83mil + 13.47mil; 77.11mil + 11.86mil; 78.14mil + 10.4mil; 78.96mil + 9.03mil; 79.54mil + 7.85mil; 79.87mil + 6.75mil; 80.0mil + 6.08mil; 79.93mil + 5.54mil; 79.75mil + 5.11mil; 79.45mil + 4.81mil; 79.02mil + 4.62mil; 78.47mil + } + } + height = 63.33mil + } + ha:\: { + width=4mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 71.63mil + 0.03mil; 70.63mil + 0.21mil; 69.81mil + 0.51mil; 69.14mil + 0.91mil; 68.68mil + 1.46mil; 68.41mil + 2.13mil; 68.28mil + 2.86mil; 68.41mil + 3.5mil; 68.68mil + 3.98mil; 69.14mil + 4.32mil; 69.81mil + 4.53mil; 70.63mil + 4.62mil; 71.69mil + 4.53mil; 72.69mil + 4.35mil; 73.49mil + 4.01mil; 74.12mil + 3.56mil; 74.55mil + 2.98mil; 74.82mil + 2.25mil; 74.92mil + 1.55mil; 74.85mil + 1.0mil; 74.58mil + 0.55mil; 74.12mil + 0.24mil; 73.49mil + 0.06mil; 72.66mil + } + li:simplepoly.1 { + 0.0mil; 53.26mil + 0.06mil; 52.25mil + 0.24mil; 51.43mil + 0.55mil; 50.76mil + 0.97mil; 50.31mil + 1.52mil; 50.03mil + 2.22mil; 49.91mil + 2.95mil; 50.03mil + 3.59mil; 50.31mil + 4.07mil; 50.76mil + 4.41mil; 51.43mil + 4.62mil; 52.25mil + 4.71mil; 53.32mil + 4.62mil; 54.29mil + 4.44mil; 55.11mil + 4.1mil; 55.72mil + 3.65mil; 56.18mil + 3.07mil; 56.42mil + 2.34mil; 56.51mil + 1.61mil; 56.45mil + 1.03mil; 56.18mil + 0.58mil; 55.72mil + 0.24mil; 55.08mil + 0.06mil; 54.29mil + } + } + height = 63.33mil + } + ha:; { + width=6mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 2.19mil; 72.0mil + 2.37mil; 71.39mil + 2.64mil; 70.87mil + 2.95mil; 70.47mil + 3.34mil; 70.2mil + 3.77mil; 70.02mil + 4.32mil; 69.96mil + 4.99mil; 70.02mil + 5.56mil; 70.2mil + 6.02mil; 70.47mil + 6.32mil; 70.84mil + 6.51mil; 71.33mil + 6.6mil; 71.93mil + 6.57mil; 72.18mil + 6.57mil; 72.42mil + 6.54mil; 72.66mil + 6.51mil; 72.91mil + 6.45mil; 73.15mil + 6.42mil; 73.39mil + 4.44mil; 81.39mil + 4.2mil; 82.03mil + 3.92mil; 82.55mil + 3.59mil; 82.98mil + 3.19mil; 83.28mil + 2.74mil; 83.43mil + 2.19mil; 83.52mil + 1.52mil; 83.46mil + 0.97mil; 83.28mil + 0.55mil; 83.01mil + 0.24mil; 82.61mil + 0.06mil; 82.09mil + 0.0mil; 81.46mil + 0.0mil; 81.21mil + 0.03mil; 80.94mil + 0.06mil; 80.63mil + 0.12mil; 80.3mil + 0.18mil; 79.96mil + 0.3mil; 79.54mil + } + li:simplepoly.1 { + 2.1mil; 54.84mil + 2.13mil; 53.84mil + 2.31mil; 53.01mil + 2.61mil; 52.35mil + 3.04mil; 51.89mil + 3.56mil; 51.62mil + 4.26mil; 51.49mil + 4.99mil; 51.62mil + 5.62mil; 51.89mil + 6.11mil; 52.35mil + 6.45mil; 53.01mil + 6.66mil; 53.84mil + 6.75mil; 54.9mil + 6.66mil; 55.9mil + 6.48mil; 56.69mil + 6.14mil; 57.33mil + 5.69mil; 57.76mil + 5.11mil; 58.03mil + 4.38mil; 58.12mil + 3.68mil; 58.06mil + 3.1mil; 57.79mil + 2.64mil; 57.33mil + 2.34mil; 56.69mil + 2.16mil; 55.87mil + } + } + height = 63.33mil + } + ha:< { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 21.05mil; 66.55mil + 21.59mil; 66.82mil + 22.05mil; 67.1mil + 22.38mil; 67.43mil + 22.66mil; 67.77mil + 22.81mil; 68.16mil + 22.87mil; 68.59mil + 22.81mil; 69.32mil + 22.63mil; 69.9mil + 22.35mil; 70.35mil + 21.99mil; 70.69mil + 21.5mil; 70.87mil + 20.89mil; 70.93mil + 20.65mil; 70.93mil + 20.41mil; 70.93mil + 20.19mil; 70.9mil + 19.98mil; 70.87mil + 19.77mil; 70.81mil + 19.59mil; 70.75mil + 2.1mil; 64.15mil + 1.46mil; 63.87mil + 0.91mil; 63.57mil + 0.51mil; 63.2mil + 0.21mil; 62.78mil + 0.06mil; 62.35mil + 0.0mil; 61.84mil + 0.06mil; 61.35mil + 0.24mil; 60.86mil + 0.57mil; 60.44mil + 1.0mil; 60.04mil + 1.58mil; 59.68mil + 2.34mil; 59.34mil + 19.37mil; 52.95mil + 19.59mil; 52.89mil + 19.83mil; 52.83mil + 20.07mil; 52.77mil + 20.32mil; 52.74mil + 20.56mil; 52.71mil + 20.8mil; 52.68mil + 21.41mil; 52.77mil + 21.9mil; 52.95mil + 22.29mil; 53.29mil + 22.57mil; 53.74mil + 22.75mil; 54.35mil + 22.81mil; 55.08mil + 22.75mil; 55.54mil + 22.57mil; 55.93mil + 22.29mil; 56.3mil + 21.9mil; 56.63mil + 21.38mil; 56.94mil + 20.74mil; 57.21mil + 8.57mil; 61.87mil + } + } + height = 63.33mil + } + ha:\= { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 20.47mil; 66.55mil + 21.14mil; 66.61mil + 21.72mil; 66.79mil + 22.17mil; 67.1mil + 22.48mil; 67.52mil + 22.66mil; 68.07mil + 22.75mil; 68.74mil + 22.69mil; 69.44mil + 22.51mil; 69.99mil + 22.2mil; 70.44mil + 21.81mil; 70.75mil + 21.26mil; 70.93mil + 20.62mil; 70.99mil + 20.1mil; 70.99mil + 18.58mil; 70.99mil + 16.03mil; 70.99mil + 12.5mil; 70.99mil + 7.94mil; 70.99mil + 2.16mil; 70.99mil + 1.49mil; 70.93mil + 0.94mil; 70.75mil + 0.51mil; 70.44mil + 0.24mil; 70.02mil + 0.06mil; 69.47mil + 0.0mil; 68.77mil + 0.03mil; 68.1mil + 0.21mil; 67.55mil + 0.51mil; 67.13mil + 0.94mil; 66.82mil + 1.49mil; 66.64mil + 2.19mil; 66.55mil + } + li:simplepoly.1 { + 20.53mil; 52.68mil + 21.2mil; 52.77mil + 21.78mil; 52.95mil + 22.23mil; 53.26mil + 22.54mil; 53.68mil + 22.72mil; 54.23mil + 22.81mil; 54.9mil + 22.75mil; 55.6mil + 22.57mil; 56.15mil + 22.26mil; 56.6mil + 21.87mil; 56.91mil + 21.32mil; 57.09mil + 20.68mil; 57.15mil + 2.22mil; 57.15mil + 1.55mil; 57.09mil + 1.0mil; 56.91mil + 0.57mil; 56.6mil + 0.27mil; 56.18mil + 0.09mil; 55.63mil + 0.03mil; 54.93mil + 0.09mil; 54.26mil + 0.27mil; 53.71mil + 0.57mil; 53.26mil + 1.0mil; 52.95mil + 1.55mil; 52.77mil + 2.25mil; 52.68mil + } + } + height = 63.33mil + } + ha:> { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 1.82mil; 66.58mil + 14.29mil; 61.9mil + 2.13mil; 57.24mil + 1.49mil; 57.0mil + 0.97mil; 56.69mil + 0.57mil; 56.36mil + 0.27mil; 56.0mil + 0.09mil; 55.57mil + 0.06mil; 55.11mil + 0.09mil; 54.38mil + 0.27mil; 53.81mil + 0.54mil; 53.32mil + 0.94mil; 52.98mil + 1.43mil; 52.8mil + 2.07mil; 52.71mil + 2.28mil; 52.74mil + 2.52mil; 52.74mil + 2.76mil; 52.8mil + 2.98mil; 52.83mil + 3.22mil; 52.92mil + 3.49mil; 52.98mil + 20.53mil; 59.37mil + 21.23mil; 59.71mil + 21.81mil; 60.04mil + 22.26mil; 60.44mil + 22.6mil; 60.89mil + 22.78mil; 61.35mil + 22.87mil; 61.87mil + 22.81mil; 62.35mil + 22.63mil; 62.81mil + 22.32mil; 63.2mil + 21.93mil; 63.57mil + 21.41mil; 63.9mil + 20.77mil; 64.18mil + 3.28mil; 70.78mil + 3.07mil; 70.84mil + 2.86mil; 70.9mil + 2.64mil; 70.93mil + 2.43mil; 70.96mil + 2.22mil; 70.96mil + 1.97mil; 70.96mil + 1.37mil; 70.9mil + 0.88mil; 70.72mil + 0.48mil; 70.38mil + 0.21mil; 69.96mil + 0.03mil; 69.38mil + 0.0mil; 68.62mil + 0.03mil; 68.19mil + 0.18mil; 67.83mil + 0.42mil; 67.46mil + 0.79mil; 67.13mil + 1.24mil; 66.85mil + } + } + height = 63.33mil + } + ha:? { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 1.09mil; 36.71mil + 2.98mil; 35.92mil + 4.95mil; 35.25mil + 6.99mil; 34.73mil + 9.12mil; 34.37mil + 11.31mil; 34.16mil + 13.68mil; 34.06mil + 15.02mil; 34.16mil + 16.3mil; 34.43mil + 17.49mil; 34.85mil + 18.58mil; 35.46mil + 19.62mil; 36.25mil + 20.59mil; 37.23mil + 21.26mil; 38.14mil + 21.81mil; 39.08mil + 22.26mil; 40.06mil + 22.57mil; 41.09mil + 22.75mil; 42.16mil + 22.84mil; 43.31mil + 22.75mil; 44.53mil + 22.54mil; 45.68mil + 22.17mil; 46.75mil + 21.68mil; 47.75mil + 21.02mil; 48.7mil + 20.22mil; 49.58mil + 14.72mil; 54.87mil + 14.32mil; 55.3mil + 14.02mil; 55.72mil + 13.81mil; 56.18mil + 13.62mil; 56.69mil + 13.53mil; 57.24mil + 13.5mil; 57.82mil + 13.5mil; 63.6mil + 13.44mil; 64.39mil + 13.26mil; 65.0mil + 12.95mil; 65.52mil + 12.53mil; 65.85mil + 11.98mil; 66.06mil + 11.31mil; 66.12mil + 10.64mil; 66.06mil + 10.1mil; 65.88mil + 9.67mil; 65.55mil + 9.37mil; 65.09mil + 9.18mil; 64.51mil + 9.12mil; 63.75mil + 9.12mil; 57.55mil + 9.15mil; 56.51mil + 9.34mil; 55.51mil + 9.64mil; 54.6mil + 10.07mil; 53.74mil + 10.58mil; 52.98mil + 11.28mil; 52.22mil + 17.33mil; 46.26mil + 17.61mil; 45.93mil + 17.85mil; 45.56mil + 18.03mil; 45.14mil + 18.19mil; 44.71mil + 18.28mil; 44.22mil + 18.31mil; 43.68mil + 18.16mil; 42.12mil + 17.7mil; 40.82mil + 16.94mil; 39.81mil + 15.87mil; 39.11mil + 14.51mil; 38.66mil + 12.77mil; 38.51mil + 11.53mil; 38.57mil + 10.19mil; 38.72mil + 8.73mil; 38.99mil + 7.21mil; 39.33mil + 5.56mil; 39.78mil + 3.77mil; 40.36mil + 3.43mil; 40.48mil + 3.1mil; 40.57mil + 2.83mil; 40.63mil + 2.58mil; 40.7mil + 2.34mil; 40.73mil + 2.13mil; 40.73mil + 2.1mil; 40.73mil + 2.1mil; 40.73mil + 2.1mil; 40.73mil + 2.1mil; 40.73mil + 2.07mil; 40.73mil + 2.07mil; 40.73mil + 1.43mil; 40.66mil + 0.91mil; 40.48mil + 0.51mil; 40.18mil + 0.21mil; 39.75mil + 0.03mil; 39.2mil + 0.0mil; 38.51mil + 0.0mil; 38.11mil + 0.09mil; 37.74mil + 0.24mil; 37.44mil + 0.45mil; 37.17mil + 0.73mil; 36.92mil + } + li:simplepoly.1 { + 9.12mil; 76.62mil + 9.15mil; 75.61mil + 9.34mil; 74.79mil + 9.61mil; 74.12mil + 10.0mil; 73.67mil + 10.49mil; 73.39mil + 11.13mil; 73.27mil + 11.83mil; 73.39mil + 12.41mil; 73.67mil + 12.83mil; 74.12mil + 13.17mil; 74.76mil + 13.35mil; 75.61mil + 13.44mil; 76.65mil + 13.38mil; 77.68mil + 13.2mil; 78.5mil + 12.89mil; 79.17mil + 12.5mil; 79.63mil + 11.95mil; 79.9mil + 11.31mil; 80.0mil + 10.64mil; 79.9mil + 10.1mil; 79.63mil + 9.67mil; 79.17mil + 9.37mil; 78.53mil + 9.18mil; 77.68mil + } + } + height = 63.33mil + } + ha:@ { + width=41mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 17.28mil; 86.69mil + 15.45mil; 86.57mil + 13.62mil; 86.23mil + 11.86mil; 85.65mil + 10.1mil; 84.86mil + 8.36mil; 83.86mil + 6.63mil; 82.58mil + 4.59mil; 80.66mil + 2.95mil; 78.47mil + 1.67mil; 75.98mil + 0.73mil; 73.21mil + 0.18mil; 70.11mil + 0.0mil; 66.61mil + 0.0mil; 66.12mil + 0.0mil; 64.6mil + 0.0mil; 62.08mil + 0.0mil; 58.55mil + 0.0mil; 54.02mil + 0.0mil; 48.24mil + 0.18mil; 44.86mil + 0.82mil; 41.73mil + 1.88mil; 38.84mil + 3.34mil; 36.22mil + 5.26mil; 33.82mil + 7.66mil; 31.6mil + 9.7mil; 30.14mil + 11.83mil; 28.95mil + 14.02mil; 28.01mil + 16.3mil; 27.34mil + 18.64mil; 26.95mil + 21.17mil; 26.79mil + 23.42mil; 26.95mil + 25.61mil; 27.34mil + 27.77mil; 28.04mil + 29.87mil; 28.98mil + 31.94mil; 30.2mil + 34.0mil; 31.72mil + 36.23mil; 33.88mil + 38.05mil; 36.28mil + 39.48mil; 38.9mil + 40.51mil; 41.79mil + 41.12mil; 44.92mil + 41.37mil; 48.39mil + 41.37mil; 48.82mil + 41.37mil; 50.09mil + 41.37mil; 52.16mil + 41.37mil; 55.11mil + 41.37mil; 58.89mil + 41.37mil; 63.63mil + 41.31mil; 65.03mil + 41.18mil; 66.28mil + 40.94mil; 67.4mil + 40.64mil; 68.38mil + 40.21mil; 69.2mil + 39.72mil; 69.9mil + 38.78mil; 70.84mil + 37.84mil; 71.6mil + 36.8mil; 72.18mil + 35.74mil; 72.6mil + 34.61mil; 72.88mil + 33.43mil; 72.94mil + 32.33mil; 72.88mil + 31.3mil; 72.63mil + 30.29mil; 72.24mil + 29.32mil; 71.66mil + 28.38mil; 70.96mil + 27.43mil; 70.02mil + 26.43mil; 70.93mil + 25.4mil; 71.66mil + 24.27mil; 72.21mil + 23.12mil; 72.63mil + 21.87mil; 72.88mil + 20.56mil; 72.94mil + 19.83mil; 72.91mil + 19.1mil; 72.82mil + 18.34mil; 72.63mil + 17.61mil; 72.39mil + 16.88mil; 72.09mil + 16.12mil; 71.66mil + 14.75mil; 70.75mil + 13.62mil; 69.62mil + 12.77mil; 68.34mil + 12.13mil; 66.88mil + 11.77mil; 65.24mil + 11.65mil; 63.36mil + 11.65mil; 50.34mil + 11.71mil; 48.94mil + 11.92mil; 47.63mil + 12.29mil; 46.41mil + 12.8mil; 45.29mil + 13.47mil; 44.28mil + 14.32mil; 43.31mil + 15.27mil; 42.52mil + 16.33mil; 41.88mil + 17.52mil; 41.36mil + 18.83mil; 41.0mil + 20.26mil; 40.79mil + 21.87mil; 40.7mil + 25.4mil; 45.17mil + 25.27mil; 45.17mil + 24.94mil; 45.17mil + 24.39mil; 45.17mil + 23.6mil; 45.17mil + 22.6mil; 45.17mil + 21.35mil; 45.17mil + 19.71mil; 45.35mil + 18.37mil; 45.81mil + 17.31mil; 46.63mil + 16.58mil; 47.72mil + 16.12mil; 49.18mil + 15.97mil; 50.98mil + 15.97mil; 51.31mil + 15.97mil; 52.22mil + 15.97mil; 53.74mil + 15.97mil; 55.87mil + 15.97mil; 58.64mil + 15.97mil; 62.11mil + 16.09mil; 64.06mil + 16.48mil; 65.64mil + 17.15mil; 66.85mil + 18.1mil; 67.74mil + 19.28mil; 68.25mil + 20.83mil; 68.44mil + 22.2mil; 68.28mil + 23.33mil; 67.77mil + 24.24mil; 66.95mil + 24.85mil; 65.76mil + 25.24mil; 64.24mil + 25.4mil; 62.29mil + 25.4mil; 61.84mil + 25.4mil; 60.44mil + 25.4mil; 58.06mil + 25.4mil; 54.78mil + 25.4mil; 50.55mil + 25.4mil; 45.17mil + 21.87mil; 40.7mil + 27.01mil; 40.7mil + 27.83mil; 40.79mil + 28.5mil; 41.0mil + 29.05mil; 41.36mil + 29.41mil; 41.85mil + 29.66mil; 42.52mil + 29.75mil; 43.31mil + 29.75mil; 62.69mil + 29.84mil; 64.45mil + 30.14mil; 65.88mil + 30.63mil; 67.01mil + 31.33mil; 67.8mil + 32.21mil; 68.28mil + 33.37mil; 68.44mil + 34.43mil; 68.34mil + 35.31mil; 67.98mil + 35.98mil; 67.37mil + 36.47mil; 66.55mil + 36.77mil; 65.49mil + 36.89mil; 64.12mil + 36.89mil; 47.42mil + 36.74mil; 45.14mil + 36.29mil; 42.95mil + 35.56mil; 40.91mil + 34.55mil; 38.99mil + 33.21mil; 37.2mil + 31.57mil; 35.46mil + 29.99mil; 34.22mil + 28.35mil; 33.15mil + 26.64mil; 32.33mil + 24.88mil; 31.75mil + 23.05mil; 31.42mil + 21.11mil; 31.27mil + 19.04mil; 31.39mil + 17.09mil; 31.72mil + 15.21mil; 32.3mil + 13.41mil; 33.09mil + 11.68mil; 34.12mil + 9.97mil; 35.4mil + 8.27mil; 37.04mil + 6.9mil; 38.84mil + 5.84mil; 40.82mil + 5.08mil; 42.92mil + 4.62mil; 45.2mil + 4.47mil; 47.72mil + 4.47mil; 67.04mil + 4.59mil; 69.32mil + 4.99mil; 71.48mil + 5.62mil; 73.52mil + 6.54mil; 75.43mil + 7.72mil; 77.23mil + 9.21mil; 78.93mil + 10.34mil; 79.93mil + 11.59mil; 80.73mil + 12.99mil; 81.36mil + 14.51mil; 81.82mil + 16.15mil; 82.09mil + 18.01mil; 82.22mil + 18.8mil; 82.28mil + 19.43mil; 82.46mil + 19.95mil; 82.79mil + 20.32mil; 83.25mil + 20.53mil; 83.86mil + 20.62mil; 84.62mil + 20.5mil; 85.23mil + 20.23mil; 85.74mil + 19.77mil; 86.14mil + 19.13mil; 86.44mil + 18.31mil; 86.63mil + } + } + height = 63.33mil + } + ha:A { + width=32mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 14.11mil; 35.74mil + 14.29mil; 35.25mil + 14.57mil; 34.82mil + 14.9mil; 34.49mil + 15.27mil; 34.28mil + 15.72mil; 34.12mil + 16.24mil; 34.06mil + 16.7mil; 34.12mil + 17.12mil; 34.28mil + 17.49mil; 34.49mil + 17.82mil; 34.82mil + 18.07mil; 35.22mil + 16.12mil; 43.31mil + 9.12mil; 64.09mil + 23.14mil; 64.09mil + 16.12mil; 43.31mil + 18.07mil; 35.22mil + 18.31mil; 35.74mil + 31.91mil; 76.62mil + 31.97mil; 76.89mil + 32.03mil; 77.14mil + 32.09mil; 77.38mil + 32.12mil; 77.59mil + 32.15mil; 77.77mil + 32.18mil; 77.96mil + 32.12mil; 78.53mil + 31.94mil; 78.99mil + 31.63mil; 79.39mil + 31.21mil; 79.66mil + 30.66mil; 79.87mil + 29.99mil; 80.0mil + 29.47mil; 79.96mil + 29.02mil; 79.78mil + 28.59mil; 79.51mil + 28.25mil; 79.11mil + 27.95mil; 78.63mil + 27.71mil; 77.99mil + 27.62mil; 77.74mil + 27.34mil; 76.95mil + 26.92mil; 75.61mil + 26.34mil; 73.79mil + 25.55mil; 71.39mil + 24.6mil; 68.38mil + 7.75mil; 68.38mil + 4.44mil; 78.23mil + 4.19mil; 78.81mil + 3.92mil; 79.26mil + 3.59mil; 79.63mil + 3.22mil; 79.9mil + 2.83mil; 80.03mil + 2.37mil; 80.09mil + 1.64mil; 80.0mil + 1.03mil; 79.84mil + 0.57mil; 79.54mil + 0.24mil; 79.11mil + 0.06mil; 78.57mil + 0.0mil; 77.87mil + 0.0mil; 77.74mil + 0.06mil; 77.5mil + 0.15mil; 77.17mil + 0.27mil; 76.74mil + 0.45mil; 76.22mil + 0.67mil; 75.58mil + } + } + height = 63.33mil + } + ha:B { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 27.74mil; 66.0mil + 27.62mil; 68.16mil + 27.25mil; 70.11mil + 26.67mil; 71.93mil + 25.85mil; 73.55mil + 24.82mil; 75.01mil + 23.51mil; 76.34mil + 22.11mil; 77.47mil + 20.74mil; 78.38mil + 19.4mil; 79.08mil + 18.07mil; 79.6mil + 16.79mil; 79.9mil + 15.48mil; 80.0mil + 4.68mil; 57.24mil + 4.68mil; 75.77mil + 14.17mil; 75.77mil + 15.48mil; 75.71mil + 16.73mil; 75.46mil + 17.85mil; 75.07mil + 18.92mil; 74.52mil + 19.89mil; 73.82mil + 20.8mil; 72.91mil + 21.53mil; 71.96mil + 22.17mil; 70.96mil + 22.66mil; 69.93mil + 22.99mil; 68.86mil + 23.21mil; 67.77mil + 23.3mil; 66.58mil + 23.21mil; 65.46mil + 23.02mil; 64.36mil + 22.69mil; 63.27mil + 22.26mil; 62.23mil + 21.69mil; 61.2mil + 20.96mil; 60.16mil + 20.1mil; 59.28mil + 19.19mil; 58.55mil + 18.13mil; 58.0mil + 16.97mil; 57.58mil + 15.69mil; 57.33mil + 14.26mil; 57.24mil + 4.68mil; 57.24mil + 15.48mil; 80.0mil + 2.13mil; 80.0mil + 1.46mil; 79.93mil + 0.94mil; 79.72mil + 0.51mil; 79.33mil + 0.21mil; 78.81mil + 0.06mil; 78.11mil + 0.0mil; 77.23mil + 0.0mil; 36.92mil + 0.06mil; 36.07mil + 0.3mil; 35.37mil + 0.67mil; 34.79mil + 1.21mil; 34.4mil + 1.91mil; 34.16mil + 2.83mil; 34.06mil + 4.68mil; 38.6mil + 4.68mil; 52.5mil + 13.96mil; 52.5mil + 15.05mil; 52.47mil + 16.06mil; 52.31mil + 17.0mil; 52.04mil + 17.79mil; 51.68mil + 18.52mil; 51.22mil + 19.19mil; 50.61mil + 19.71mil; 49.97mil + 20.13mil; 49.27mil + 20.47mil; 48.51mil + 20.71mil; 47.69mil + 20.89mil; 46.84mil + 20.96mil; 45.87mil + 20.89mil; 44.95mil + 20.74mil; 44.07mil + 20.47mil; 43.19mil + 20.13mil; 42.4mil + 19.68mil; 41.61mil + 19.1mil; 40.82mil + 18.43mil; 40.18mil + 17.67mil; 39.63mil + 16.85mil; 39.17mil + 15.94mil; 38.87mil + 14.93mil; 38.69mil + 13.84mil; 38.6mil + 4.68mil; 38.6mil + 2.83mil; 34.06mil + 12.32mil; 34.06mil + 14.14mil; 34.16mil + 15.78mil; 34.34mil + 17.28mil; 34.64mil + 18.58mil; 35.1mil + 19.74mil; 35.68mil + 20.74mil; 36.38mil + 22.14mil; 37.78mil + 23.3mil; 39.2mil + 24.18mil; 40.7mil + 24.82mil; 42.25mil + 25.21mil; 43.86mil + 25.37mil; 45.56mil + 25.24mil; 47.36mil + 24.88mil; 49.03mil + 24.3mil; 50.58mil + 23.48mil; 52.01mil + 22.42mil; 53.32mil + 21.11mil; 54.5mil + 21.99mil; 55.11mil + 22.87mil; 55.75mil + 23.66mil; 56.51mil + 24.42mil; 57.33mil + 25.12mil; 58.22mil + 25.82mil; 59.22mil + 26.37mil; 60.28mil + 26.86mil; 61.35mil + 27.22mil; 62.44mil + 27.5mil; 63.6mil + 27.65mil; 64.76mil + } + } + height = 63.33mil + } + ha:C { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 11.25mil; 33.91mil + 11.5mil; 33.91mil + 12.26mil; 33.91mil + 13.53mil; 33.91mil + 15.33mil; 33.91mil + 17.64mil; 33.91mil + 20.56mil; 33.91mil + 21.23mil; 34.0mil + 21.78mil; 34.19mil + 22.23mil; 34.49mil + 22.54mil; 34.92mil + 22.72mil; 35.49mil + 22.81mil; 36.19mil + 22.72mil; 36.92mil + 22.54mil; 37.5mil + 22.2mil; 37.93mil + 21.72mil; 38.26mil + 21.14mil; 38.44mil + 20.38mil; 38.51mil + 11.22mil; 38.51mil + 10.37mil; 38.6mil + 9.52mil; 38.78mil + 8.7mil; 39.08mil + 7.88mil; 39.51mil + 7.09mil; 40.06mil + 6.26mil; 40.73mil + 5.69mil; 41.33mil + 5.23mil; 42.0mil + 4.89mil; 42.73mil + 4.62mil; 43.49mil + 4.47mil; 44.35mil + 4.44mil; 45.29mil + 4.44mil; 68.53mil + 4.47mil; 69.47mil + 4.62mil; 70.35mil + 4.89mil; 71.2mil + 5.26mil; 72.0mil + 5.75mil; 72.73mil + 6.36mil; 73.46mil + 7.02mil; 74.12mil + 7.69mil; 74.64mil + 8.36mil; 75.07mil + 9.06mil; 75.37mil + 9.76mil; 75.52mil + 10.52mil; 75.58mil + 20.74mil; 75.58mil + 21.38mil; 75.68mil + 21.93mil; 75.86mil + 22.35mil; 76.16mil + 22.66mil; 76.59mil + 22.84mil; 77.14mil + 22.93mil; 77.8mil + 22.84mil; 78.44mil + 22.66mil; 78.99mil + 22.35mil; 79.39mil + 21.93mil; 79.69mil + 21.38mil; 79.84mil + 20.71mil; 79.9mil + 10.34mil; 79.9mil + 8.94mil; 79.81mil + 7.6mil; 79.48mil + 6.29mil; 78.93mil + 4.99mil; 78.14mil + 3.74mil; 77.14mil + 2.49mil; 75.86mil + 1.73mil; 74.92mil + 1.09mil; 73.88mil + 0.61mil; 72.73mil + 0.27mil; 71.51mil + 0.06mil; 70.23mil + 0.0mil; 68.77mil + 0.0mil; 44.95mil + 0.09mil; 43.49mil + 0.36mil; 42.06mil + 0.88mil; 40.73mil + 1.55mil; 39.45mil + 2.46mil; 38.23mil + 3.59mil; 37.01mil + 4.68mil; 36.07mil + 5.87mil; 35.31mil + 7.12mil; 34.7mil + 8.42mil; 34.28mil + 9.76mil; 34.0mil + } + } + height = 63.33mil + } + ha:D { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 0.0mil; 36.56mil + 0.06mil; 35.83mil + 0.27mil; 35.19mil + 0.61mil; 34.7mil + 1.09mil; 34.37mil + 1.73mil; 34.16mil + 2.52mil; 34.06mil + 16.79mil; 34.06mil + 18.13mil; 34.16mil + 19.47mil; 34.43mil + 20.71mil; 34.89mil + 21.93mil; 35.52mil + 23.08mil; 36.35mil + 24.24mil; 37.35mil + 25.21mil; 38.47mil + 23.08mil; 44.59mil + 22.9mil; 43.74mil + 22.63mil; 42.92mil + 22.26mil; 42.12mil + 21.78mil; 41.36mil + 21.17mil; 40.6mil + 20.47mil; 39.97mil + 19.71mil; 39.42mil + 18.86mil; 38.99mil + 17.97mil; 38.72mil + 17.0mil; 38.54mil + 15.94mil; 38.44mil + 4.47mil; 38.44mil + 4.47mil; 39.48mil + 4.47mil; 42.55mil + 4.47mil; 47.66mil + 4.47mil; 54.81mil + 4.47mil; 64.0mil + 4.47mil; 75.61mil + 4.74mil; 75.61mil + 5.62mil; 75.61mil + 7.05mil; 75.61mil + 9.09mil; 75.61mil + 11.71mil; 75.61mil + 15.02mil; 75.61mil + 16.3mil; 75.58mil + 17.49mil; 75.4mil + 18.55mil; 75.1mil + 19.5mil; 74.7mil + 20.35mil; 74.19mil + 21.11mil; 73.52mil + 21.72mil; 72.82mil + 22.2mil; 72.03mil + 22.6mil; 71.2mil + 22.87mil; 70.32mil + 23.05mil; 69.35mil + 23.15mil; 68.31mil + 23.15mil; 45.47mil + 23.08mil; 44.59mil + 25.21mil; 38.47mil + 26.04mil; 39.63mil + 26.67mil; 40.85mil + 27.13mil; 42.09mil + 27.4mil; 43.4mil + 27.53mil; 44.8mil + 27.53mil; 69.35mil + 27.43mil; 70.72mil + 27.16mil; 72.03mil + 26.7mil; 73.27mil + 26.07mil; 74.49mil + 25.24mil; 75.61mil + 24.24mil; 76.74mil + 23.12mil; 77.74mil + 21.99mil; 78.53mil + 20.83mil; 79.17mil + 19.68mil; 79.63mil + 18.46mil; 79.9mil + 17.21mil; 80.0mil + 2.04mil; 80.0mil + 1.4mil; 79.93mil + 0.88mil; 79.72mil + 0.48mil; 79.33mil + 0.21mil; 78.81mil + 0.03mil; 78.14mil + 0.0mil; 77.29mil + } + } + height = 63.33mil + } + ha:E { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 4.38mil; 75.46mil + 20.59mil; 75.46mil + 21.26mil; 75.52mil + 21.81mil; 75.71mil + 22.26mil; 76.01mil + 22.57mil; 76.44mil + 22.75mil; 76.98mil + 22.84mil; 77.65mil + 22.78mil; 78.32mil + 22.6mil; 78.87mil + 22.29mil; 79.3mil + 21.87mil; 79.6mil + 21.35mil; 79.78mil + 20.68mil; 79.84mil + 2.01mil; 79.84mil + 1.37mil; 79.78mil + 0.88mil; 79.6mil + 0.48mil; 79.3mil + 0.21mil; 78.87mil + 0.03mil; 78.29mil + 0.0mil; 77.56mil + 0.0mil; 36.28mil + 0.06mil; 35.58mil + 0.27mil; 34.98mil + 0.67mil; 34.52mil + 1.18mil; 34.19mil + 1.85mil; 34.0mil + 2.7mil; 33.91mil + 20.44mil; 33.91mil + 21.17mil; 34.0mil + 21.78mil; 34.19mil + 22.26mil; 34.49mil + 22.6mil; 34.92mil + 22.81mil; 35.46mil + 22.9mil; 36.13mil + 22.81mil; 36.8mil + 22.63mil; 37.35mil + 22.26mil; 37.78mil + 21.81mil; 38.08mil + 21.2mil; 38.26mil + 20.44mil; 38.32mil + 4.38mil; 38.32mil + 4.38mil; 52.5mil + 16.12mil; 52.5mil + 16.79mil; 52.56mil + 17.34mil; 52.74mil + 17.76mil; 53.04mil + 18.07mil; 53.47mil + 18.25mil; 54.02mil + 18.34mil; 54.69mil + 18.28mil; 55.33mil + 18.1mil; 55.84mil + 17.79mil; 56.24mil + 17.37mil; 56.54mil + 16.85mil; 56.73mil + 16.18mil; 56.76mil + 4.38mil; 56.76mil + } + } + height = 63.33mil + } + ha:F { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 4.5mil; 56.79mil + 4.5mil; 77.38mil + 4.41mil; 78.14mil + 4.23mil; 78.78mil + 3.92mil; 79.26mil + 3.5mil; 79.6mil + 2.92mil; 79.81mil + 2.22mil; 79.87mil + 1.52mil; 79.81mil + 0.97mil; 79.6mil + 0.55mil; 79.26mil + 0.24mil; 78.78mil + 0.06mil; 78.14mil + 0.0mil; 77.35mil + 0.0mil; 76.22mil + 0.0mil; 72.82mil + 0.0mil; 67.16mil + 0.0mil; 59.22mil + 0.0mil; 49.0mil + 0.0mil; 36.04mil + 0.06mil; 35.4mil + 0.24mil; 34.89mil + 0.58mil; 34.46mil + 1.03mil; 34.16mil + 1.61mil; 34.0mil + 2.37mil; 33.91mil + 2.86mil; 33.91mil + 4.35mil; 33.91mil + 6.84mil; 33.91mil + 10.31mil; 33.91mil + 14.81mil; 33.91mil + 20.5mil; 33.91mil + 21.23mil; 33.97mil + 21.81mil; 34.16mil + 22.29mil; 34.46mil + 22.63mil; 34.89mil + 22.81mil; 35.43mil + 22.9mil; 36.1mil + 22.81mil; 36.77mil + 22.63mil; 37.32mil + 22.29mil; 37.74mil + 21.84mil; 38.05mil + 21.26mil; 38.23mil + 20.53mil; 38.29mil + 4.53mil; 38.29mil + 4.53mil; 52.35mil + 20.53mil; 52.35mil + 21.23mil; 52.44mil + 21.84mil; 52.62mil + 22.29mil; 52.92mil + 22.63mil; 53.35mil + 22.81mil; 53.9mil + 22.9mil; 54.57mil + 22.81mil; 55.27mil + 22.63mil; 55.81mil + 22.29mil; 56.24mil + 21.84mil; 56.54mil + 21.23mil; 56.73mil + 20.5mil; 56.79mil + } + } + height = 63.33mil + } + ha:G { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 23.15mil; 75.46mil + 23.15mil; 56.79mil + 18.37mil; 56.79mil + 17.7mil; 56.76mil + 17.15mil; 56.57mil + 16.73mil; 56.27mil + 16.45mil; 55.84mil + 16.27mil; 55.33mil + 16.21mil; 54.63mil + 16.24mil; 53.99mil + 16.42mil; 53.44mil + 16.7mil; 53.01mil + 17.09mil; 52.71mil + 17.61mil; 52.53mil + 18.28mil; 52.44mil + 25.55mil; 52.44mil + 26.13mil; 52.53mil + 26.61mil; 52.77mil + 26.98mil; 53.17mil + 27.25mil; 53.71mil + 27.43mil; 54.44mil + 27.5mil; 55.33mil + 27.5mil; 77.2mil + 27.4mil; 78.02mil + 27.19mil; 78.69mil + 26.86mil; 79.2mil + 26.37mil; 79.57mil + 25.73mil; 79.78mil + 24.97mil; 79.84mil + 10.19mil; 79.84mil + 9.06mil; 79.78mil + 7.97mil; 79.54mil + 6.84mil; 79.11mil + 5.72mil; 78.53mil + 4.59mil; 77.8mil + 3.43mil; 76.86mil + 2.37mil; 75.8mil + 1.52mil; 74.52mil + 0.85mil; 73.03mil + 0.36mil; 71.36mil + 0.09mil; 69.5mil + 0.0mil; 67.34mil + 0.0mil; 44.68mil + 0.09mil; 43.31mil + 0.36mil; 41.97mil + 0.85mil; 40.7mil + 1.52mil; 39.48mil + 2.37mil; 38.32mil + 3.47mil; 37.17mil + 4.62mil; 36.19mil + 5.87mil; 35.4mil + 7.18mil; 34.76mil + 8.51mil; 34.31mil + 9.91mil; 34.03mil + 11.47mil; 33.91mil + 24.91mil; 33.91mil + 25.7mil; 33.97mil + 26.37mil; 34.16mil + 26.89mil; 34.46mil + 27.28mil; 34.89mil + 27.5mil; 35.43mil + 27.59mil; 36.1mil + 27.5mil; 36.77mil + 27.28mil; 37.32mil + 26.92mil; 37.74mil + 26.4mil; 38.05mil + 25.76mil; 38.23mil + 24.94mil; 38.29mil + 11.95mil; 38.29mil + 10.86mil; 38.35mil + 9.85mil; 38.54mil + 8.91mil; 38.84mil + 8.03mil; 39.27mil + 7.24mil; 39.81mil + 6.48mil; 40.48mil + 5.81mil; 41.24mil + 5.29mil; 42.06mil + 4.86mil; 42.92mil + 4.56mil; 43.83mil + 4.41mil; 44.77mil + 4.35mil; 45.81mil + 4.35mil; 67.83mil + 4.38mil; 68.92mil + 4.56mil; 69.96mil + 4.83mil; 70.9mil + 5.2mil; 71.78mil + 5.69mil; 72.57mil + 6.32mil; 73.33mil + 6.96mil; 74.0mil + 7.66mil; 74.52mil + 8.39mil; 74.95mil + 9.12mil; 75.25mil + 9.91mil; 75.4mil + 10.74mil; 75.46mil + } + } + height = 63.33mil + } + ha:H { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 23.36mil; 56.88mil + 4.47mil; 56.88mil + 4.47mil; 77.65mil + 4.38mil; 78.38mil + 4.2mil; 78.96mil + 3.89mil; 79.42mil + 3.47mil; 79.75mil + 2.92mil; 79.93mil + 2.25mil; 80.0mil + 1.55mil; 79.93mil + 1.0mil; 79.75mil + 0.58mil; 79.45mil + 0.24mil; 78.99mil + 0.06mil; 78.41mil + 0.0mil; 77.68mil + 0.0mil; 36.65mil + 0.06mil; 35.89mil + 0.24mil; 35.22mil + 0.55mil; 34.73mil + 0.97mil; 34.37mil + 1.52mil; 34.16mil + 2.22mil; 34.06mil + 2.89mil; 34.16mil + 3.43mil; 34.37mil + 3.86mil; 34.73mil + 4.2mil; 35.22mil + 4.38mil; 35.86mil + 4.47mil; 36.65mil + 4.47mil; 52.5mil + 23.36mil; 52.5mil + 23.36mil; 36.47mil + 23.39mil; 35.8mil + 23.57mil; 35.22mil + 23.88mil; 34.76mil + 24.3mil; 34.46mil + 24.82mil; 34.28mil + 25.52mil; 34.19mil + 26.16mil; 34.28mil + 26.7mil; 34.46mil + 27.13mil; 34.76mil + 27.4mil; 35.19mil + 27.59mil; 35.74mil + 27.68mil; 36.44mil + 27.68mil; 77.56mil + 27.62mil; 78.32mil + 27.43mil; 78.93mil + 27.13mil; 79.39mil + 26.7mil; 79.72mil + 26.19mil; 79.93mil + 25.52mil; 80.0mil + 24.85mil; 79.93mil + 24.3mil; 79.75mil + 23.88mil; 79.42mil + 23.6mil; 78.96mil + 23.42mil; 78.38mil + 23.36mil; 77.62mil + } + } + height = 63.33mil + } + ha:I { + width=4mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 4.62mil; 80.0mil + 4.53mil; 80.0mil + 4.35mil; 80.0mil + 4.04mil; 80.0mil + 3.59mil; 80.0mil + 3.01mil; 80.0mil + 2.31mil; 80.0mil + 1.58mil; 79.93mil + 1.0mil; 79.69mil + 0.58mil; 79.3mil + 0.24mil; 78.75mil + 0.06mil; 78.05mil + 0.0mil; 77.14mil + 0.0mil; 36.8mil + 0.06mil; 35.98mil + 0.24mil; 35.31mil + 0.55mil; 34.76mil + 1.0mil; 34.4mil + 1.58mil; 34.16mil + 2.31mil; 34.06mil + 3.01mil; 34.16mil + 3.59mil; 34.4mil + 4.01mil; 34.76mil + 4.35mil; 35.31mil + 4.53mil; 36.01mil + 4.62mil; 36.89mil + 4.62mil; 77.07mil + 4.53mil; 77.99mil + 4.35mil; 78.72mil + 4.04mil; 79.26mil + 3.59mil; 79.69mil + 3.01mil; 79.93mil + } + } + height = 63.33mil + } + ha:J { + width=18mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 13.81mil; 36.44mil + 13.84mil; 35.74mil + 14.02mil; 35.13mil + 14.32mil; 34.67mil + 14.75mil; 34.34mil + 15.3mil; 34.16mil + 16.0mil; 34.06mil + 16.64mil; 34.16mil + 17.18mil; 34.34mil + 17.61mil; 34.67mil + 17.88mil; 35.1mil + 18.07mil; 35.68mil + 18.16mil; 36.41mil + 18.16mil; 68.86mil + 18.07mil; 70.35mil + 17.79mil; 71.75mil + 17.33mil; 73.09mil + 16.7mil; 74.34mil + 15.91mil; 75.52mil + 14.9mil; 76.68mil + 13.78mil; 77.68mil + 12.56mil; 78.5mil + 11.28mil; 79.14mil + 9.94mil; 79.63mil + 8.48mil; 79.9mil + 6.93mil; 80.0mil + 2.25mil; 80.0mil + 1.55mil; 79.93mil + 1.0mil; 79.75mil + 0.54mil; 79.45mil + 0.24mil; 79.02mil + 0.06mil; 78.47mil + 0.0mil; 77.74mil + 0.06mil; 77.07mil + 0.27mil; 76.53mil + 0.64mil; 76.07mil + 1.15mil; 75.77mil + 1.79mil; 75.58mil + 2.64mil; 75.49mil + 7.14mil; 75.49mil + 8.06mil; 75.46mil + 8.91mil; 75.28mil + 9.73mil; 75.01mil + 10.49mil; 74.61mil + 11.19mil; 74.09mil + 11.89mil; 73.42mil + 12.44mil; 72.73mil + 12.92mil; 72.0mil + 13.29mil; 71.23mil + 13.56mil; 70.44mil + 13.72mil; 69.62mil + 13.81mil; 68.74mil + } + } + height = 63.33mil + } + ha:K { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 2.1mil; 79.9mil + 1.46mil; 79.84mil + 0.91mil; 79.6mil + 0.51mil; 79.23mil + 0.21mil; 78.69mil + 0.06mil; 77.99mil + 0.0mil; 77.07mil + 0.0mil; 36.07mil + 0.03mil; 35.46mil + 0.21mil; 34.98mil + 0.51mil; 34.58mil + 0.91mil; 34.31mil + 1.43mil; 34.12mil + 2.1mil; 34.06mil + 2.77mil; 34.16mil + 3.34mil; 34.34mil + 3.8mil; 34.64mil + 4.1mil; 35.07mil + 4.29mil; 35.65mil + 4.38mil; 36.35mil + 4.38mil; 55.75mil + 23.24mil; 35.07mil + 23.57mil; 34.73mil + 23.91mil; 34.43mil + 24.24mil; 34.22mil + 24.58mil; 34.06mil + 24.88mil; 33.97mil + 25.21mil; 33.91mil + 25.49mil; 33.94mil + 25.79mil; 34.0mil + 26.04mil; 34.12mil + 26.31mil; 34.25mil + 26.55mil; 34.46mil + 26.8mil; 34.67mil + 26.98mil; 34.95mil + 27.13mil; 35.19mil + 27.25mil; 35.43mil + 27.34mil; 35.71mil + 27.4mil; 35.98mil + 27.43mil; 36.25mil + 27.4mil; 36.56mil + 27.31mil; 36.83mil + 27.16mil; 37.17mil + 26.95mil; 37.5mil + 26.67mil; 37.87mil + 26.34mil; 38.26mil + 13.69mil; 52.28mil + 26.95mil; 76.22mil + 27.1mil; 76.56mil + 27.25mil; 76.86mil + 27.37mil; 77.14mil + 27.43mil; 77.38mil + 27.5mil; 77.56mil + 27.53mil; 77.74mil + 27.5mil; 78.08mil + 27.43mil; 78.35mil + 27.31mil; 78.63mil + 27.16mil; 78.9mil + 26.95mil; 79.14mil + 26.7mil; 79.39mil + 26.46mil; 79.6mil + 26.22mil; 79.75mil + 25.94mil; 79.84mil + 25.67mil; 79.93mil + 25.4mil; 80.0mil + 25.12mil; 80.0mil + 24.76mil; 79.96mil + 24.39mil; 79.87mil + 24.09mil; 79.66mil + 23.78mil; 79.42mil + 23.48mil; 79.08mil + 23.24mil; 78.63mil + 10.55mil; 55.72mil + 4.44mil; 62.41mil + 4.44mil; 76.98mil + 4.35mil; 77.9mil + 4.16mil; 78.63mil + 3.83mil; 79.17mil + 3.4mil; 79.6mil + 2.83mil; 79.84mil + } + } + height = 63.33mil + } + ha:L { + width=23mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 4.41mil; 36.41mil + 4.41mil; 75.58mil + 20.26mil; 75.58mil + 21.08mil; 75.65mil + 21.78mil; 75.83mil + 22.29mil; 76.13mil + 22.69mil; 76.56mil + 22.93mil; 77.11mil + 23.02mil; 77.77mil + 22.93mil; 78.44mil + 22.69mil; 78.99mil + 22.29mil; 79.45mil + 21.75mil; 79.75mil + 21.05mil; 79.93mil + 20.16mil; 80.0mil + 2.16mil; 80.0mil + 1.49mil; 79.93mil + 0.94mil; 79.72mil + 0.51mil; 79.33mil + 0.24mil; 78.81mil + 0.06mil; 78.14mil + 0.0mil; 77.29mil + 0.0mil; 36.41mil + 0.03mil; 35.71mil + 0.21mil; 35.13mil + 0.51mil; 34.67mil + 0.94mil; 34.34mil + 1.49mil; 34.16mil + 2.19mil; 34.06mil + 2.83mil; 34.16mil + 3.37mil; 34.34mil + 3.83mil; 34.67mil + 4.13mil; 35.1mil + 4.32mil; 35.68mil + } + } + height = 63.33mil + } + ha:M { + width=32mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 28.1mil; 35.22mil + 28.35mil; 34.89mil + 28.62mil; 34.58mil + 28.93mil; 34.37mil + 29.26mil; 34.22mil + 29.62mil; 34.12mil + 30.05mil; 34.06mil + 30.75mil; 34.16mil + 31.33mil; 34.34mil + 31.75mil; 34.67mil + 32.09mil; 35.16mil + 32.27mil; 35.74mil + 32.36mil; 36.5mil + 32.36mil; 76.98mil + 32.27mil; 77.93mil + 32.09mil; 78.66mil + 31.78mil; 79.23mil + 31.36mil; 79.66mil + 30.81mil; 79.93mil + 30.11mil; 80.0mil + 29.41mil; 79.93mil + 28.86mil; 79.69mil + 28.41mil; 79.26mil + 28.1mil; 78.69mil + 27.92mil; 77.96mil + 27.86mil; 76.98mil + 27.86mil; 44.35mil + 18.37mil; 59.8mil + 17.97mil; 60.41mil + 17.58mil; 60.86mil + 17.21mil; 61.26mil + 16.82mil; 61.5mil + 16.45mil; 61.68mil + 16.06mil; 61.71mil + 15.66mil; 61.68mil + 15.3mil; 61.53mil + 14.9mil; 61.26mil + 14.54mil; 60.92mil + 14.17mil; 60.47mil + 13.81mil; 59.86mil + 4.5mil; 44.41mil + 4.5mil; 77.14mil + 4.41mil; 78.02mil + 4.23mil; 78.72mil + 3.89mil; 79.3mil + 3.47mil; 79.69mil + 2.89mil; 79.93mil + 2.16mil; 80.0mil + 1.49mil; 79.93mil + 0.94mil; 79.69mil + 0.51mil; 79.33mil + 0.24mil; 78.78mil + 0.06mil; 78.08mil + 0.0mil; 77.2mil + 0.0mil; 36.47mil + 0.06mil; 35.74mil + 0.24mil; 35.16mil + 0.55mil; 34.67mil + 1.0mil; 34.34mil + 1.58mil; 34.16mil + 2.31mil; 34.06mil + 2.67mil; 34.09mil + 3.04mil; 34.19mil + 3.34mil; 34.34mil + 3.65mil; 34.55mil + 3.92mil; 34.82mil + 4.2mil; 35.13mil + 15.94mil; 54.93mil + } + } + height = 63.33mil + } + ha:N { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 23.24mil; 69.14mil + 23.24mil; 36.22mil + 23.27mil; 35.52mil + 23.45mil; 34.95mil + 23.75mil; 34.52mil + 24.15mil; 34.19mil + 24.67mil; 34.0mil + 25.34mil; 33.91mil + 25.94mil; 34.0mil + 26.49mil; 34.19mil + 26.89mil; 34.49mil + 27.19mil; 34.92mil + 27.34mil; 35.46mil + 27.43mil; 36.13mil + 27.43mil; 77.29mil + 27.37mil; 78.08mil + 27.19mil; 78.69mil + 26.92mil; 79.2mil + 26.52mil; 79.54mil + 26.04mil; 79.75mil + 25.43mil; 79.81mil + 24.97mil; 79.78mil + 24.54mil; 79.66mil + 24.15mil; 79.42mil + 23.78mil; 79.11mil + 23.42mil; 78.69mil + 23.12mil; 78.17mil + 4.38mil; 44.74mil + 4.38mil; 77.29mil + 4.29mil; 78.05mil + 4.1mil; 78.66mil + 3.8mil; 79.11mil + 3.34mil; 79.45mil + 2.77mil; 79.66mil + 2.07mil; 79.72mil + 1.43mil; 79.66mil + 0.91mil; 79.45mil + 0.51mil; 79.11mil + 0.21mil; 78.63mil + 0.03mil; 78.02mil + 0.0mil; 77.23mil + 0.0mil; 36.62mil + 0.03mil; 35.8mil + 0.21mil; 35.13mil + 0.51mil; 34.61mil + 0.94mil; 34.25mil + 1.49mil; 34.0mil + 2.19mil; 33.91mil + 2.64mil; 33.97mil + 3.04mil; 34.09mil + 3.43mil; 34.28mil + 3.8mil; 34.55mil + 4.1mil; 34.89mil + 4.41mil; 35.31mil + } + } + height = 63.33mil + } + ha:O { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 0.0mil; 46.9mil + 0.09mil; 45.26mil + 0.42mil; 43.68mil + 0.97mil; 42.16mil + 1.73mil; 40.7mil + 2.7mil; 39.3mil + 3.98mil; 37.9mil + 5.35mil; 36.71mil + 6.81mil; 35.71mil + 8.39mil; 34.95mil + 10.07mil; 34.37mil + 11.83mil; 34.03mil + 13.78mil; 33.91mil + 15.54mil; 34.03mil + 17.24mil; 34.37mil + 18.86mil; 34.92mil + 20.41mil; 35.68mil + 21.84mil; 36.65mil + 23.27mil; 37.87mil + 24.51mil; 39.3mil + 25.58mil; 40.79mil + 26.4mil; 42.37mil + 26.98mil; 43.98mil + 27.31mil; 45.71mil + 27.47mil; 47.54mil + 27.47mil; 66.12mil + 27.34mil; 68.07mil + 26.98mil; 69.9mil + 26.43mil; 71.6mil + 25.61mil; 73.21mil + 24.58mil; 74.7mil + 23.3mil; 76.13mil + 21.9mil; 77.32mil + 20.44mil; 78.29mil + 18.89mil; 79.02mil + 17.21mil; 79.57mil + 15.48mil; 79.9mil + 13.56mil; 80.0mil + 11.8mil; 79.9mil + 10.1mil; 79.6mil + 8.51mil; 79.05mil + 6.96mil; 78.32mil + 5.5mil; 77.35mil + 4.1mil; 76.13mil + 4.47mil; 67.13mil + 4.53mil; 68.22mil + 4.77mil; 69.26mil + 5.2mil; 70.26mil + 5.78mil; 71.27mil + 6.54mil; 72.21mil + 7.51mil; 73.15mil + 8.39mil; 73.88mil + 9.31mil; 74.46mil + 10.28mil; 74.92mil + 11.28mil; 75.25mil + 12.32mil; 75.43mil + 13.44mil; 75.49mil + 14.66mil; 75.46mil + 15.81mil; 75.28mil + 16.88mil; 74.98mil + 17.88mil; 74.55mil + 18.8mil; 74.03mil + 19.68mil; 73.33mil + 20.68mil; 72.3mil + 21.53mil; 71.23mil + 22.17mil; 70.08mil + 22.66mil; 68.86mil + 22.93mil; 67.61mil + 23.05mil; 66.25mil + 23.05mil; 47.75mil + 22.96mil; 46.35mil + 22.69mil; 45.01mil + 22.26mil; 43.8mil + 21.62mil; 42.7mil + 20.83mil; 41.67mil + 19.86mil; 40.73mil + 18.89mil; 40.03mil + 17.88mil; 39.45mil + 16.82mil; 39.02mil + 15.72mil; 38.69mil + 14.6mil; 38.51mil + 13.41mil; 38.41mil + 12.41mil; 38.51mil + 11.4mil; 38.69mil + 10.43mil; 39.02mil + 9.46mil; 39.45mil + 8.48mil; 40.03mil + 7.51mil; 40.76mil + 6.57mil; 41.64mil + 5.81mil; 42.61mil + 5.23mil; 43.71mil + 4.8mil; 44.89mil + 4.53mil; 46.2mil + 4.47mil; 47.63mil + 4.47mil; 67.13mil + 4.1mil; 76.13mil + 2.83mil; 74.79mil + 1.82mil; 73.39mil + 1.03mil; 71.9mil + 0.45mil; 70.35mil + 0.09mil; 68.74mil + 0.0mil; 66.98mil + } + } + height = 63.33mil + } + ha:P { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 4.5mil; 77.32mil + 4.41mil; 78.11mil + 4.23mil; 78.72mil + 3.92mil; 79.23mil + 3.5mil; 79.57mil + 2.95mil; 79.78mil + 2.25mil; 79.84mil + 1.55mil; 79.78mil + 1.0mil; 79.57mil + 0.55mil; 79.2mil + 0.24mil; 78.72mil + 0.06mil; 78.08mil + 0.0mil; 77.26mil + 0.0mil; 36.47mil + 0.06mil; 35.74mil + 0.27mil; 35.16mil + 0.61mil; 34.67mil + 1.09mil; 34.34mil + 1.7mil; 34.16mil + 2.49mil; 34.06mil + 4.5mil; 38.44mil + 4.5mil; 38.96mil + 4.5mil; 40.51mil + 4.5mil; 43.07mil + 4.5mil; 46.63mil + 4.5mil; 51.22mil + 4.5mil; 57.03mil + 14.6mil; 57.03mil + 15.6mil; 56.97mil + 16.58mil; 56.76mil + 17.55mil; 56.36mil + 18.49mil; 55.84mil + 19.43mil; 55.17mil + 20.38mil; 54.32mil + 21.17mil; 53.41mil + 21.84mil; 52.44mil + 22.35mil; 51.37mil + 22.75mil; 50.22mil + 22.96mil; 49.03mil + 23.05mil; 47.69mil + 22.96mil; 46.44mil + 22.75mil; 45.23mil + 22.39mil; 44.1mil + 21.87mil; 43.04mil + 21.2mil; 42.06mil + 20.38mil; 41.09mil + 19.43mil; 40.3mil + 18.4mil; 39.63mil + 17.28mil; 39.11mil + 16.06mil; 38.75mil + 14.75mil; 38.54mil + 13.32mil; 38.44mil + 4.5mil; 38.44mil + 2.49mil; 34.06mil + 14.26mil; 34.06mil + 16.09mil; 34.22mil + 17.85mil; 34.58mil + 19.5mil; 35.22mil + 21.08mil; 36.07mil + 22.57mil; 37.23mil + 24.03mil; 38.63mil + 25.06mil; 39.93mil + 25.88mil; 41.24mil + 26.55mil; 42.61mil + 27.04mil; 44.01mil + 27.31mil; 45.44mil + 27.43mil; 46.96mil + 27.34mil; 48.76mil + 27.16mil; 50.4mil + 26.83mil; 51.89mil + 26.37mil; 53.29mil + 25.79mil; 54.54mil + 25.06mil; 55.66mil + 23.54mil; 57.46mil + 21.93mil; 58.92mil + 20.26mil; 60.07mil + 18.46mil; 60.89mil + 16.61mil; 61.38mil + 14.6mil; 61.53mil + 4.5mil; 61.53mil + } + } + height = 63.33mil + } + ha:Q { + width=32mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 26.7mil; 71.11mil + 31.12mil; 75.61mil + 31.45mil; 76.01mil + 31.75mil; 76.41mil + 32.0mil; 76.77mil + 32.15mil; 77.11mil + 32.24mil; 77.44mil + 32.3mil; 77.74mil + 32.21mil; 78.44mil + 32.03mil; 78.99mil + 31.72mil; 79.45mil + 31.27mil; 79.75mil + 30.69mil; 79.93mil + 29.99mil; 80.0mil + 29.66mil; 79.96mil + 29.32mil; 79.87mil + 28.99mil; 79.72mil + 28.62mil; 79.48mil + 28.26mil; 79.17mil + 27.86mil; 78.78mil + 24.33mil; 75.16mil + 24.0mil; 75.61mil + 23.57mil; 76.1mil + 23.08mil; 76.56mil + 22.51mil; 77.01mil + 21.87mil; 77.5mil + 21.14mil; 77.99mil + 20.04mil; 78.63mil + 18.95mil; 79.11mil + 17.82mil; 79.51mil + 16.64mil; 79.78mil + 15.45mil; 79.96mil + 14.17mil; 80.0mil + 12.16mil; 79.9mil + 10.28mil; 79.54mil + 8.51mil; 78.96mil + 6.9mil; 78.14mil + 5.38mil; 77.07mil + 3.98mil; 75.71mil + 2.77mil; 74.25mil + 1.76mil; 72.73mil + 1.0mil; 71.14mil + 0.42mil; 69.5mil + 0.09mil; 67.8mil + 0.0mil; 65.97mil + 0.0mil; 47.69mil + 0.06mil; 46.26mil + 0.3mil; 44.86mil + 0.67mil; 43.49mil + 1.21mil; 42.12mil + 1.91mil; 40.82mil + 2.8mil; 39.48mil + 4.2mil; 37.84mil + 5.78mil; 36.5mil + 7.51mil; 35.43mil + 9.46mil; 34.7mil + 11.59mil; 34.25mil + 11.71mil; 38.69mil + 10.77mil; 38.96mil + 9.82mil; 39.36mil + 8.94mil; 39.84mil + 8.09mil; 40.45mil + 6.99mil; 41.46mil + 6.11mil; 42.58mil + 5.41mil; 43.8mil + 4.93mil; 45.14mil + 4.62mil; 46.6mil + 4.53mil; 48.18mil + 4.53mil; 66.37mil + 4.59mil; 67.55mil + 4.83mil; 68.68mil + 5.26mil; 69.77mil + 5.84mil; 70.84mil + 6.57mil; 71.87mil + 7.51mil; 72.88mil + 8.39mil; 73.67mil + 9.37mil; 74.34mil + 10.43mil; 74.82mil + 11.56mil; 75.19mil + 12.77mil; 75.4mil + 14.11mil; 75.46mil + 15.42mil; 75.37mil + 16.7mil; 75.1mil + 17.88mil; 74.61mil + 19.04mil; 73.94mil + 20.1mil; 73.09mil + 21.17mil; 71.96mil + 20.41mil; 71.33mil + 19.8mil; 70.75mil + 19.31mil; 70.17mil + 18.98mil; 69.65mil + 18.77mil; 69.2mil + 18.7mil; 68.74mil + 18.74mil; 68.01mil + 18.92mil; 67.4mil + 19.22mil; 66.95mil + 19.65mil; 66.61mil + 20.2mil; 66.4mil + 20.89mil; 66.31mil + 21.29mil; 66.37mil + 21.69mil; 66.49mil + 22.05mil; 66.7mil + 22.42mil; 66.98mil + 22.75mil; 67.34mil + 23.12mil; 67.8mil + 23.12mil; 67.25mil + 23.12mil; 65.58mil + 23.12mil; 62.78mil + 23.12mil; 58.85mil + 23.12mil; 53.81mil + 23.12mil; 47.42mil + 23.02mil; 46.2mil + 22.78mil; 45.04mil + 22.39mil; 43.95mil + 21.84mil; 42.89mil + 21.11mil; 41.91mil + 20.23mil; 40.94mil + 19.28mil; 40.21mil + 18.31mil; 39.57mil + 17.28mil; 39.08mil + 16.18mil; 38.75mil + 15.02mil; 38.54mil + 13.78mil; 38.44mil + 12.71mil; 38.51mil + 11.71mil; 38.69mil + 11.59mil; 34.25mil + 13.99mil; 34.06mil + 15.94mil; 34.19mil + 17.79mil; 34.55mil + 19.5mil; 35.13mil + 21.08mil; 35.92mil + 22.51mil; 36.95mil + 23.88mil; 38.26mil + 25.0mil; 39.69mil + 25.94mil; 41.09mil + 26.67mil; 42.49mil + 27.19mil; 43.89mil + 27.53mil; 45.26mil + 27.65mil; 46.69mil + 27.65mil; 65.79mil + 27.62mil; 66.88mil + 27.53mil; 67.89mil + 27.4mil; 68.83mil + 27.22mil; 69.65mil + 26.98mil; 70.41mil + } + } + height = 63.33mil + } + ha:R { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 2.37mil; 34.25mil + 14.39mil; 34.25mil + 16.18mil; 34.4mil + 17.94mil; 34.82mil + 19.65mil; 35.49mil + 21.32mil; 36.47mil + 22.9mil; 37.68mil + 24.51mil; 39.24mil + 25.43mil; 40.36mil + 26.16mil; 41.55mil + 26.73mil; 42.76mil + 27.16mil; 44.01mil + 27.43mil; 45.35mil + 27.53mil; 46.75mil + 27.47mil; 48.09mil + 27.34mil; 49.43mil + 27.13mil; 50.7mil + 26.86mil; 51.95mil + 26.46mil; 53.2mil + 26.0mil; 54.41mil + 25.34mil; 55.69mil + 24.48mil; 56.85mil + 23.45mil; 57.91mil + 22.2mil; 58.85mil + 20.77mil; 59.74mil + 19.1mil; 60.53mil + 27.04mil; 76.13mil + 27.16mil; 76.44mil + 27.28mil; 76.74mil + 27.37mil; 77.01mil + 27.43mil; 77.26mil + 22.57mil; 51.34mil + 22.9mil; 50.22mil + 23.12mil; 48.97mil + 23.21mil; 47.54mil + 23.12mil; 46.5mil + 22.9mil; 45.47mil + 22.54mil; 44.47mil + 22.02mil; 43.49mil + 21.35mil; 42.52mil + 20.53mil; 41.55mil + 19.56mil; 40.66mil + 18.58mil; 39.93mil + 17.58mil; 39.36mil + 16.55mil; 38.96mil + 15.48mil; 38.69mil + 14.39mil; 38.6mil + 4.47mil; 38.6mil + 4.47mil; 57.15mil + 4.71mil; 57.15mil + 5.53mil; 57.15mil + 6.9mil; 57.15mil + 8.82mil; 57.15mil + 11.28mil; 57.15mil + 14.42mil; 57.15mil + 15.45mil; 57.09mil + 16.48mil; 56.85mil + 17.55mil; 56.42mil + 18.58mil; 55.84mil + 19.65mil; 55.11mil + 20.74mil; 54.14mil + 21.47mil; 53.32mil + 22.08mil; 52.41mil + 22.57mil; 51.34mil + 27.43mil; 77.26mil + 27.47mil; 77.47mil + 27.5mil; 77.68mil + 27.4mil; 78.41mil + 27.22mil; 78.99mil + 26.92mil; 79.42mil + 26.49mil; 79.75mil + 25.94mil; 79.93mil + 25.24mil; 80.0mil + 24.85mil; 79.96mil + 24.48mil; 79.81mil + 24.12mil; 79.57mil + 23.81mil; 79.23mil + 23.48mil; 78.81mil + 23.21mil; 78.26mil + 14.69mil; 61.62mil + 4.38mil; 61.62mil + 4.38mil; 77.59mil + 4.29mil; 78.35mil + 4.1mil; 78.93mil + 3.8mil; 79.42mil + 3.37mil; 79.75mil + 2.83mil; 79.93mil + 2.16mil; 80.0mil + 1.49mil; 79.93mil + 0.94mil; 79.75mil + 0.51mil; 79.42mil + 0.24mil; 78.93mil + 0.06mil; 78.35mil + 0.0mil; 77.56mil + 0.0mil; 36.59mil + 0.06mil; 35.89mil + 0.24mil; 35.31mil + 0.58mil; 34.85mil + 1.03mil; 34.52mil + 1.61mil; 34.34mil + } + } + height = 63.33mil + } + ha:S { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 45.59mil + 0.06mil; 44.07mil + 0.33mil; 42.61mil + 0.79mil; 41.21mil + 1.43mil; 39.9mil + 2.25mil; 38.69mil + 3.28mil; 37.47mil + 4.41mil; 36.47mil + 5.59mil; 35.62mil + 6.87mil; 34.95mil + 8.21mil; 34.49mil + 9.64mil; 34.19mil + 11.22mil; 34.06mil + 13.32mil; 34.12mil + 15.36mil; 34.31mil + 17.33mil; 34.58mil + 19.22mil; 34.95mil + 21.08mil; 35.43mil + 22.93mil; 36.04mil + 23.57mil; 36.35mil + 24.12mil; 36.71mil + 24.54mil; 37.11mil + 24.85mil; 37.53mil + 25.03mil; 38.02mil + 25.12mil; 38.57mil + 25.06mil; 39.2mil + 24.88mil; 39.75mil + 24.57mil; 40.15mil + 24.18mil; 40.45mil + 23.66mil; 40.6mil + 23.02mil; 40.66mil + 22.69mil; 40.66mil + 22.32mil; 40.6mil + 21.9mil; 40.51mil + 21.41mil; 40.36mil + 20.86mil; 40.18mil + 20.26mil; 39.93mil + 18.92mil; 39.48mil + 17.58mil; 39.11mil + 16.21mil; 38.81mil + 14.81mil; 38.6mil + 13.38mil; 38.47mil + 11.89mil; 38.41mil + 10.58mil; 38.51mil + 9.43mil; 38.75mil + 8.36mil; 39.14mil + 7.39mil; 39.69mil + 6.54mil; 40.39mil + 5.78mil; 41.27mil + 5.38mil; 41.88mil + 5.05mil; 42.55mil + 4.8mil; 43.28mil + 4.62mil; 44.07mil + 4.53mil; 44.92mil + 4.5mil; 45.84mil + 4.62mil; 47.08mil + 5.02mil; 48.24mil + 5.65mil; 49.33mil + 6.57mil; 50.34mil + 7.72mil; 51.25mil + 9.21mil; 52.1mil + 20.32mil; 57.73mil + 22.51mil; 59.07mil + 24.3mil; 60.56mil + 25.7mil; 62.26mil + 26.7mil; 64.15mil + 27.31mil; 66.19mil + 27.52mil; 68.5mil + 27.4mil; 70.2mil + 27.1mil; 71.78mil + 26.58mil; 73.27mil + 25.85mil; 74.64mil + 24.91mil; 75.89mil + 23.75mil; 77.04mil + 22.57mil; 77.96mil + 21.32mil; 78.69mil + 20.01mil; 79.26mil + 18.61mil; 79.66mil + 17.15mil; 79.93mil + 15.57mil; 80.0mil + 13.17mil; 79.9mil + 10.83mil; 79.54mil + 8.51mil; 78.93mil + 6.23mil; 78.11mil + 3.98mil; 77.01mil + 1.7mil; 75.65mil + 1.15mil; 75.28mil + 0.76mil; 74.88mil + 0.42mil; 74.49mil + 0.18mil; 74.06mil + 0.03mil; 73.64mil + 0.0mil; 73.15mil + 0.06mil; 72.54mil + 0.24mil; 72.0mil + 0.54mil; 71.6mil + 0.97mil; 71.3mil + 1.52mil; 71.14mil + 2.25mil; 71.05mil + 2.52mil; 71.08mil + 2.83mil; 71.17mil + 3.19mil; 71.3mil + 3.56mil; 71.51mil + 3.98mil; 71.72mil + 4.44mil; 72.03mil + 6.08mil; 73.09mil + 7.81mil; 73.94mil + 9.67mil; 74.61mil + 11.65mil; 75.1mil + 13.72mil; 75.37mil + 15.97mil; 75.46mil + 16.6mil; 75.46mil + 17.21mil; 75.4mil + 17.82mil; 75.28mil + 18.4mil; 75.13mil + 18.95mil; 74.92mil + 19.53mil; 74.64mil + 20.56mil; 73.97mil + 21.44mil; 73.15mil + 22.11mil; 72.18mil + 22.6mil; 71.08mil + 22.9mil; 69.81mil + 23.02mil; 68.34mil + 22.87mil; 67.01mil + 22.51mil; 65.76mil + 21.87mil; 64.63mil + 20.99mil; 63.6mil + 19.86mil; 62.66mil + 18.43mil; 61.81mil + 6.48mil; 55.75mil + 4.5mil; 54.57mil + 2.89mil; 53.2mil + 1.61mil; 51.62mil + 0.73mil; 49.82mil + 0.18mil; 47.84mil + } + } + height = 63.33mil + } + ha:T { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 36.01mil + 0.06mil; 35.4mil + 0.27mil; 34.85mil + 0.64mil; 34.46mil + 1.15mil; 34.16mil + 1.82mil; 34.0mil + 2.67mil; 33.91mil + 25.21mil; 33.91mil + 25.85mil; 33.97mil + 26.4mil; 34.16mil + 26.83mil; 34.46mil + 27.13mil; 34.89mil + 27.31mil; 35.43mil + 27.4mil; 36.1mil + 27.34mil; 36.8mil + 27.16mil; 37.35mil + 26.86mil; 37.78mil + 26.46mil; 38.08mil + 25.91mil; 38.26mil + 25.27mil; 38.32mil + 15.94mil; 38.32mil + 15.94mil; 77.59mil + 15.84mil; 78.35mil + 15.66mil; 78.93mil + 15.36mil; 79.42mil + 14.93mil; 79.75mil + 14.38mil; 79.93mil + 13.72mil; 80.0mil + 13.02mil; 79.93mil + 12.47mil; 79.75mil + 12.04mil; 79.42mil + 11.74mil; 78.99mil + 11.56mil; 78.41mil + 11.49mil; 77.65mil + 11.49mil; 38.32mil + 2.61mil; 38.32mil + 1.79mil; 38.26mil + 1.15mil; 38.08mil + 0.64mil; 37.78mil + 0.27mil; 37.32mil + 0.06mil; 36.74mil + } + } + height = 63.33mil + } + ha:U { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 36.28mil + 0.03mil; 35.58mil + 0.21mil; 34.98mil + 0.51mil; 34.52mil + 0.91mil; 34.19mil + 1.46mil; 34.0mil + 2.13mil; 33.91mil + 2.83mil; 34.0mil + 3.4mil; 34.19mil + 3.83mil; 34.52mil + 4.16mil; 34.98mil + 4.35mil; 35.55mil + 4.44mil; 36.28mil + 4.44mil; 65.76mil + 4.5mil; 67.34mil + 4.77mil; 68.77mil + 5.23mil; 70.08mil + 5.87mil; 71.27mil + 6.69mil; 72.3mil + 7.72mil; 73.24mil + 8.67mil; 73.94mil + 9.64mil; 74.49mil + 10.61mil; 74.95mil + 11.62mil; 75.25mil + 12.62mil; 75.43mil + 13.69mil; 75.49mil + 14.9mil; 75.43mil + 16.12mil; 75.19mil + 17.28mil; 74.76mil + 18.4mil; 74.19mil + 19.47mil; 73.42mil + 20.56mil; 72.45mil + 21.29mil; 71.6mil + 21.93mil; 70.63mil + 22.42mil; 69.53mil + 22.75mil; 68.34mil + 22.96mil; 67.07mil + 23.05mil; 65.61mil + 23.05mil; 36.28mil + 23.12mil; 35.58mil + 23.3mil; 34.98mil + 23.6mil; 34.52mil + 24.03mil; 34.19mil + 24.61mil; 34.0mil + 25.34mil; 33.91mil + 26.0mil; 34.0mil + 26.55mil; 34.22mil + 26.98mil; 34.58mil + 27.28mil; 35.1mil + 27.47mil; 35.77mil + 27.56mil; 36.59mil + 27.56mil; 65.42mil + 27.43mil; 67.52mil + 27.1mil; 69.44mil + 26.55mil; 71.23mil + 25.79mil; 72.85mil + 24.82mil; 74.34mil + 23.57mil; 75.71mil + 22.08mil; 76.98mil + 20.56mil; 78.02mil + 18.95mil; 78.81mil + 17.24mil; 79.39mil + 15.51mil; 79.75mil + 13.62mil; 79.84mil + 11.98mil; 79.78mil + 10.4mil; 79.51mil + 8.88mil; 79.05mil + 7.45mil; 78.41mil + 6.05mil; 77.59mil + 4.68mil; 76.56mil + 3.25mil; 75.22mil + 2.07mil; 73.73mil + 1.15mil; 72.12mil + 0.51mil; 70.38mil + 0.12mil; 68.53mil + 0.0mil; 66.46mil + } + } + height = 63.33mil + } + ha:V { + width=32mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 16.06mil; 70.87mil + 27.77mil; 36.07mil + 28.01mil; 35.46mil + 28.29mil; 34.98mil + 28.62mil; 34.58mil + 29.02mil; 34.31mil + 29.44mil; 34.12mil + 29.96mil; 34.06mil + 30.63mil; 34.12mil + 31.18mil; 34.31mil + 31.63mil; 34.61mil + 31.94mil; 35.01mil + 32.12mil; 35.55mil + 32.21mil; 36.19mil + 32.18mil; 36.41mil + 32.18mil; 36.62mil + 32.12mil; 36.83mil + 32.09mil; 37.08mil + 32.0mil; 37.32mil + 31.94mil; 37.59mil + 18.52mil; 77.93mil + 18.25mil; 78.57mil + 17.94mil; 79.08mil + 17.58mil; 79.48mil + 17.15mil; 79.78mil + 16.67mil; 79.96mil + 16.12mil; 80.0mil + 15.63mil; 79.96mil + 15.21mil; 79.78mil + 14.84mil; 79.51mil + 14.51mil; 79.11mil + 14.2mil; 78.63mil + 13.96mil; 77.99mil + 0.18mil; 37.17mil + 0.12mil; 37.01mil + 0.06mil; 36.83mil + 0.03mil; 36.65mil + 0.0mil; 36.5mil + 0.0mil; 36.35mil + 0.0mil; 36.16mil + 0.06mil; 35.58mil + 0.24mil; 35.1mil + 0.57mil; 34.7mil + 1.03mil; 34.43mil + 1.64mil; 34.25mil + 2.4mil; 34.19mil + 2.83mil; 34.25mil + 3.22mil; 34.43mil + 3.62mil; 34.73mil + 3.92mil; 35.13mil + 4.22mil; 35.68mil + 4.5mil; 36.31mil + } + } + height = 63.33mil + } + ha:W { + width=41mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 37.02mil; 36.04mil + 37.2mil; 35.49mil + 37.44mil; 35.04mil + 37.75mil; 34.67mil + 38.14mil; 34.4mil + 38.6mil; 34.25mil + 39.14mil; 34.19mil + 39.78mil; 34.25mil + 40.33mil; 34.4mil + 40.76mil; 34.67mil + 41.06mil; 35.04mil + 41.24mil; 35.49mil + 41.33mil; 36.07mil + 41.3mil; 36.35mil + 41.3mil; 36.59mil + 41.27mil; 36.86mil + 41.24mil; 37.14mil + 41.18mil; 37.38mil + 41.15mil; 37.65mil + 32.15mil; 77.77mil + 31.94mil; 78.47mil + 31.69mil; 79.02mil + 31.39mil; 79.45mil + 30.99mil; 79.75mil + 30.54mil; 79.93mil + 30.02mil; 80.0mil + 29.44mil; 79.96mil + 28.95mil; 79.78mil + 28.53mil; 79.51mil + 28.13mil; 79.11mil + 27.83mil; 78.6mil + 27.59mil; 77.96mil + 20.62mil; 57.12mil + 13.68mil; 78.08mil + 13.44mil; 78.69mil + 13.14mil; 79.14mil + 12.8mil; 79.54mil + 12.41mil; 79.78mil + 11.98mil; 79.96mil + 11.49mil; 80.0mil + 10.92mil; 79.96mil + 10.4mil; 79.81mil + 9.97mil; 79.54mil + 9.64mil; 79.2mil + 9.4mil; 78.75mil + 9.21mil; 78.14mil + 0.09mil; 37.26mil + 0.06mil; 37.11mil + 0.03mil; 36.95mil + 0.0mil; 36.77mil + 0.0mil; 36.59mil + 0.0mil; 36.38mil + 0.0mil; 36.13mil + 0.06mil; 35.52mil + 0.24mil; 35.01mil + 0.57mil; 34.61mil + 1.0mil; 34.31mil + 1.58mil; 34.12mil + 2.34mil; 34.06mil + 2.83mil; 34.12mil + 3.28mil; 34.31mil + 3.65mil; 34.58mil + 3.98mil; 34.95mil + 4.22mil; 35.43mil + 4.41mil; 36.04mil + 11.8mil; 69.35mil + 18.37mil; 49.85mil + 18.61mil; 49.24mil + 18.92mil; 48.73mil + 19.31mil; 48.33mil + 19.74mil; 48.06mil + 20.22mil; 47.87mil + 20.8mil; 47.81mil + 21.26mil; 47.9mil + 21.68mil; 48.09mil + 22.05mil; 48.39mil + 22.41mil; 48.82mil + 22.72mil; 49.36mil + 22.99mil; 50.03mil + 29.5mil; 69.47mil + } + } + height = 63.33mil + } + ha:X { + width=32mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 13.5mil; 57.03mil + 13.14mil; 56.51mil + 12.07mil; 54.93mil + 10.28mil; 52.25mil + 7.81mil; 48.54mil + 4.62mil; 43.74mil + 0.57mil; 37.65mil + 0.42mil; 37.41mil + 0.3mil; 37.17mil + 0.21mil; 36.92mil + 0.12mil; 36.68mil + 0.09mil; 36.44mil + 0.09mil; 36.16mil + 0.15mil; 35.55mil + 0.33mil; 35.07mil + 0.64mil; 34.67mil + 1.06mil; 34.4mil + 1.61mil; 34.22mil + 2.34mil; 34.16mil + 2.7mil; 34.22mil + 3.04mil; 34.31mil + 3.4mil; 34.49mil + 3.71mil; 34.76mil + 4.04mil; 35.1mil + 4.38mil; 35.49mil + 16.15mil; 52.95mil + 28.1mil; 35.19mil + 28.38mil; 34.85mil + 28.65mil; 34.58mil + 28.99mil; 34.37mil + 29.32mil; 34.22mil + 29.68mil; 34.12mil + 30.11mil; 34.06mil + 30.75mil; 34.12mil + 31.3mil; 34.31mil + 31.72mil; 34.58mil + 32.03mil; 34.98mil + 32.21mil; 35.49mil + 32.3mil; 36.1mil + 32.27mil; 36.41mil + 32.21mil; 36.71mil + 32.09mil; 37.01mil + 31.94mil; 37.38mil + 31.75mil; 37.71mil + 31.51mil; 38.11mil + 18.83mil; 57.03mil + 31.72mil; 76.5mil + 31.84mil; 76.74mil + 31.97mil; 76.95mil + 32.06mil; 77.17mil + 32.15mil; 77.38mil + 32.18mil; 77.56mil + 32.21mil; 77.74mil + 32.12mil; 78.44mil + 31.94mil; 78.99mil + 31.63mil; 79.45mil + 31.21mil; 79.75mil + 30.66mil; 79.93mil + 29.99mil; 80.0mil + 29.56mil; 79.96mil + 29.17mil; 79.87mil + 28.8mil; 79.69mil + 28.47mil; 79.45mil + 28.16mil; 79.11mil + 27.86mil; 78.69mil + 16.15mil; 60.98mil + 4.29mil; 78.84mil + 4.01mil; 79.2mil + 3.71mil; 79.51mil + 3.43mil; 79.72mil + 3.13mil; 79.87mil + 2.8mil; 79.96mil + 2.46mil; 80.0mil + 1.7mil; 79.96mil + 1.09mil; 79.78mil + 0.61mil; 79.48mil + 0.27mil; 79.08mil + 0.06mil; 78.53mil + 0.0mil; 77.87mil + 0.0mil; 77.65mil + 0.06mil; 77.38mil + 0.15mil; 77.11mil + 0.27mil; 76.8mil + 0.45mil; 76.5mil + 0.67mil; 76.13mil + } + } + height = 63.33mil + } + ha:Y { + width=32mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 13.96mil; 56.85mil + 13.56mil; 56.33mil + 12.47mil; 54.75mil + 10.61mil; 52.1mil + 8.03mil; 48.42mil + 4.68mil; 43.68mil + 0.48mil; 37.65mil + 0.33mil; 37.44mil + 0.21mil; 37.2mil + 0.12mil; 36.98mil + 0.03mil; 36.74mil + 0.0mil; 36.5mil + 0.0mil; 36.25mil + 0.06mil; 35.62mil + 0.24mil; 35.07mil + 0.57mil; 34.64mil + 1.03mil; 34.34mil + 1.64mil; 34.16mil + 2.4mil; 34.06mil + 2.73mil; 34.12mil + 3.07mil; 34.22mil + 3.4mil; 34.4mil + 3.71mil; 34.67mil + 4.01mil; 35.01mil + 4.35mil; 35.4mil + 16.09mil; 52.44mil + 27.95mil; 35.13mil + 28.19mil; 34.82mil + 28.5mil; 34.55mil + 28.8mil; 34.34mil + 29.14mil; 34.19mil + 29.47mil; 34.12mil + 29.87mil; 34.06mil + 30.57mil; 34.12mil + 31.14mil; 34.31mil + 31.57mil; 34.58mil + 31.91mil; 34.98mil + 32.09mil; 35.49mil + 32.18mil; 36.13mil + 32.15mil; 36.41mil + 32.09mil; 36.68mil + 32.03mil; 36.92mil + 31.91mil; 37.2mil + 31.75mil; 37.5mil + 31.6mil; 37.78mil + 18.31mil; 56.97mil + 18.31mil; 77.41mil + 18.25mil; 78.2mil + 18.07mil; 78.87mil + 17.76mil; 79.36mil + 17.37mil; 79.72mil + 16.82mil; 79.93mil + 16.18mil; 80.0mil + 15.48mil; 79.93mil + 14.93mil; 79.72mil + 14.51mil; 79.36mil + 14.2mil; 78.84mil + 14.02mil; 78.2mil + 13.96mil; 77.35mil + } + } + height = 63.33mil + } + ha:Z { + width=27mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 5.87mil; 75.68mil + 25.18mil; 75.68mil + 25.88mil; 75.77mil + 26.49mil; 75.95mil + 26.95mil; 76.25mil + 27.28mil; 76.68mil + 27.46mil; 77.26mil + 27.56mil; 77.96mil + 27.46mil; 78.6mil + 27.28mil; 79.11mil + 26.95mil; 79.51mil + 26.49mil; 79.78mil + 25.88mil; 79.96mil + 25.15mil; 80.0mil + 2.31mil; 80.0mil + 1.58mil; 79.96mil + 1.0mil; 79.78mil + 0.57mil; 79.48mil + 0.24mil; 79.05mil + 0.06mil; 78.5mil + 0.0mil; 77.8mil + 0.0mil; 77.53mil + 0.06mil; 77.23mil + 0.15mil; 76.89mil + 0.3mil; 76.56mil + 0.45mil; 76.16mil + 0.7mil; 75.74mil + 21.56mil; 38.47mil + 2.61mil; 38.47mil + 1.82mil; 38.41mil + 1.18mil; 38.23mil + 0.7mil; 37.9mil + 0.33mil; 37.44mil + 0.12mil; 36.83mil + 0.06mil; 36.07mil + 0.12mil; 35.46mil + 0.33mil; 34.98mil + 0.7mil; 34.58mil + 1.21mil; 34.31mil + 1.85mil; 34.12mil + 2.7mil; 34.06mil + 24.6mil; 34.06mil + 25.46mil; 34.12mil + 26.16mil; 34.31mil + 26.73mil; 34.58mil + 27.13mil; 34.98mil + 27.37mil; 35.46mil + 27.46mil; 36.07mil + 27.43mil; 36.38mil + 27.4mil; 36.68mil + 27.34mil; 36.98mil + 27.22mil; 37.29mil + 27.13mil; 37.59mil + 26.98mil; 37.87mil + } + } + height = 63.33mil + } + ha:[ { + width=8mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 31.81mil + 0.06mil; 31.11mil + 0.24mil; 30.54mil + 0.55mil; 30.08mil + 0.97mil; 29.74mil + 1.52mil; 29.56mil + 2.25mil; 29.47mil + 2.34mil; 29.47mil + 2.7mil; 29.47mil + 3.31mil; 29.47mil + 4.13mil; 29.47mil + 5.23mil; 29.47mil + 6.6mil; 29.47mil + 7.3mil; 29.53mil + 7.88mil; 29.71mil + 8.33mil; 30.02mil + 8.67mil; 30.44mil + 8.85mil; 30.99mil + 8.94mil; 31.66mil + 8.85mil; 32.36mil + 8.67mil; 32.91mil + 8.36mil; 33.36mil + 7.94mil; 33.67mil + 7.36mil; 33.85mil + 6.66mil; 33.91mil + 4.44mil; 33.91mil + 4.44mil; 80.36mil + 6.63mil; 80.36mil + 7.33mil; 80.39mil + 7.91mil; 80.57mil + 8.33mil; 80.85mil + 8.67mil; 81.24mil + 8.85mil; 81.76mil + 8.94mil; 82.43mil + 8.85mil; 83.1mil + 8.67mil; 83.65mil + 8.3mil; 84.07mil + 7.85mil; 84.38mil + 7.24mil; 84.56mil + 6.48mil; 84.65mil + 2.13mil; 84.65mil + 1.46mil; 84.56mil + 0.94mil; 84.38mil + 0.51mil; 84.07mil + 0.21mil; 83.65mil + 0.06mil; 83.1mil + 0.0mil; 82.43mil + 0.0mil; 81.03mil + 0.0mil; 76.89mil + 0.0mil; 69.93mil + 0.0mil; 60.19mil + 0.0mil; 47.69mil + } + } + height = 63.33mil + } + ha:\\ { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 22.69mil; 77.96mil + 22.6mil; 78.6mil + 22.41mil; 79.11mil + 22.08mil; 79.51mil + 21.62mil; 79.78mil + 21.05mil; 79.96mil + 20.32mil; 80.0mil + 19.86mil; 79.96mil + 19.46mil; 79.81mil + 19.1mil; 79.54mil + 18.76mil; 79.17mil + 18.43mil; 78.72mil + 18.16mil; 78.11mil + 0.3mil; 37.68mil + 0.18mil; 37.44mil + 0.12mil; 37.2mil + 0.06mil; 36.92mil + 0.03mil; 36.68mil + 0.0mil; 36.41mil + 0.0mil; 36.13mil + 0.03mil; 35.52mil + 0.21mil; 35.01mil + 0.51mil; 34.61mil + 0.94mil; 34.31mil + 1.49mil; 34.12mil + 2.19mil; 34.06mil + 2.61mil; 34.12mil + 3.04mil; 34.28mil + 3.43mil; 34.55mil + 3.8mil; 34.92mil + 4.1mil; 35.4mil + 4.44mil; 35.98mil + 22.14mil; 76.04mil + 22.29mil; 76.47mil + 22.41mil; 76.83mil + 22.54mil; 77.17mil + 22.6mil; 77.47mil + 22.66mil; 77.71mil + } + } + height = 63.33mil + } + ha:] { + width=8mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 8.94mil; 31.81mil + 8.94mil; 33.21mil + 8.94mil; 37.38mil + 8.94mil; 44.35mil + 8.94mil; 54.08mil + 8.94mil; 66.58mil + 8.94mil; 82.43mil + 8.88mil; 83.1mil + 8.7mil; 83.65mil + 8.39mil; 84.07mil + 8.0mil; 84.38mil + 7.45mil; 84.56mil + 6.81mil; 84.65mil + 2.46mil; 84.65mil + 1.7mil; 84.56mil + 1.09mil; 84.38mil + 0.61mil; 84.07mil + 0.27mil; 83.65mil + 0.06mil; 83.1mil + 0.0mil; 82.43mil + 0.06mil; 81.79mil + 0.24mil; 81.27mil + 0.54mil; 80.88mil + 1.0mil; 80.57mil + 1.58mil; 80.39mil + 2.31mil; 80.36mil + 4.5mil; 80.36mil + 4.5mil; 33.91mil + 2.28mil; 33.91mil + 1.58mil; 33.85mil + 1.0mil; 33.67mil + 0.54mil; 33.36mil + 0.24mil; 32.94mil + 0.06mil; 32.39mil + 0.0mil; 31.66mil + 0.06mil; 31.02mil + 0.24mil; 30.47mil + 0.57mil; 30.05mil + 1.0mil; 29.74mil + 1.58mil; 29.56mil + 2.34mil; 29.47mil + 6.69mil; 29.47mil + 7.36mil; 29.56mil + 7.91mil; 29.74mil + 8.36mil; 30.08mil + 8.67mil; 30.51mil + 8.85mil; 31.08mil + } + } + height = 63.33mil + } + ha:^ { + width=18mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 13.9mil; 35.25mil + 13.75mil; 35.13mil + 13.35mil; 34.73mil + 12.71mil; 34.06mil + 11.8mil; 33.15mil + 10.64mil; 31.97mil + 9.18mil; 30.44mil + 4.38mil; 35.1mil + 3.95mil; 35.49mil + 3.56mil; 35.8mil + 3.19mil; 36.04mil + 2.86mil; 36.22mil + 2.52mil; 36.31mil + 2.22mil; 36.35mil + 1.52mil; 36.31mil + 0.97mil; 36.13mil + 0.54mil; 35.86mil + 0.24mil; 35.49mil + 0.06mil; 35.01mil + 0.0mil; 34.37mil + 0.0mil; 34.06mil + 0.09mil; 33.76mil + 0.24mil; 33.43mil + 0.42mil; 33.09mil + 0.7mil; 32.73mil + 1.03mil; 32.36mil + 7.05mil; 26.16mil + 7.39mil; 25.82mil + 7.75mil; 25.55mil + 8.12mil; 25.33mil + 8.45mil; 25.18mil + 8.82mil; 25.09mil + 9.18mil; 25.03mil + 9.46mil; 25.09mil + 9.76mil; 25.18mil + 10.1mil; 25.33mil + 10.43mil; 25.55mil + 10.76mil; 25.82mil + 11.16mil; 26.16mil + 17.09mil; 32.12mil + 17.4mil; 32.48mil + 17.67mil; 32.85mil + 17.88mil; 33.21mil + 18.03mil; 33.58mil + 18.13mil; 33.94mil + 18.19mil; 34.31mil + 18.1mil; 34.95mil + 17.91mil; 35.46mil + 17.61mil; 35.86mil + 17.15mil; 36.13mil + 16.57mil; 36.31mil + 15.87mil; 36.35mil + 15.54mil; 36.35mil + 15.24mil; 36.25mil + 14.9mil; 36.1mil + 14.57mil; 35.89mil + 14.23mil; 35.62mil + } + } + height = 63.33mil + } + ha:_ { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 2.19mil; 80.0mil + 2.67mil; 80.0mil + 4.19mil; 80.0mil + 6.75mil; 80.0mil + 10.31mil; 80.0mil + 14.87mil; 80.0mil + 20.68mil; 80.0mil + 21.32mil; 80.06mil + 21.87mil; 80.24mil + 22.29mil; 80.57mil + 22.6mil; 81.0mil + 22.78mil; 81.58mil + 22.87mil; 82.34mil + 22.78mil; 82.95mil + 22.6mil; 83.46mil + 22.29mil; 83.86mil + 21.87mil; 84.13mil + 21.29mil; 84.31mil + 20.59mil; 84.38mil + 2.25mil; 84.38mil + 1.55mil; 84.28mil + 1.0mil; 84.1mil + 0.54mil; 83.8mil + 0.24mil; 83.34mil + 0.06mil; 82.76mil + 0.0mil; 82.06mil + 0.03mil; 81.42mil + 0.21mil; 80.91mil + 0.51mil; 80.51mil + 0.94mil; 80.21mil + 1.49mil; 80.03mil + } + } + height = 63.33mil + } + ha:` { + width=13mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 3.92mil; 27.46mil + 4.13mil; 27.65mil + 4.83mil; 28.19mil + 6.02mil; 29.08mil + 7.66mil; 30.29mil + 9.76mil; 31.87mil + 12.47mil; 33.88mil + 12.77mil; 34.16mil + 13.05mil; 34.46mil + 13.26mil; 34.76mil + 13.41mil; 35.1mil + 13.5mil; 35.43mil + 13.56mil; 35.8mil + 13.5mil; 36.5mil + 13.32mil; 37.08mil + 13.05mil; 37.53mil + 12.65mil; 37.84mil + 12.13mil; 38.02mil + 11.49mil; 38.08mil + 11.22mil; 38.08mil + 10.95mil; 38.02mil + 10.67mil; 37.96mil + 10.4mil; 37.84mil + 10.1mil; 37.68mil + 9.82mil; 37.47mil + 9.58mil; 37.32mil + 8.85mil; 36.77mil + 7.66mil; 35.86mil + 5.99mil; 34.61mil + 3.86mil; 33.0mil + 1.15mil; 30.93mil + 0.79mil; 30.66mil + 0.48mil; 30.35mil + 0.27mil; 30.08mil + 0.12mil; 29.78mil + 0.03mil; 29.44mil + 0.0mil; 29.11mil + 0.06mil; 28.38mil + 0.24mil; 27.8mil + 0.54mil; 27.31mil + 1.0mil; 26.98mil + 1.58mil; 26.79mil + 2.31mil; 26.7mil + 2.52mil; 26.73mil + 2.76mil; 26.79mil + 3.01mil; 26.92mil + 3.28mil; 27.04mil + 3.59mil; 27.25mil + } + } + height = 63.33mil + } + ha:a { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 4.68mil; 52.16mil + 3.98mil; 52.1mil + 3.4mil; 51.92mil + 2.95mil; 51.62mil + 2.64mil; 51.19mil + 2.46mil; 50.64mil + 2.4mil; 49.91mil + 2.46mil; 49.27mil + 2.64mil; 48.73mil + 2.95mil; 48.3mil + 3.37mil; 48.0mil + 3.95mil; 47.81mil + 4.68mil; 47.72mil + 14.14mil; 47.72mil + 15.39mil; 47.81mil + 16.57mil; 48.06mil + 17.67mil; 48.45mil + 18.67mil; 49.03mil + 19.62mil; 49.73mil + 20.53mil; 50.64mil + 21.26mil; 51.65mil + 21.87mil; 52.62mil + 22.35mil; 53.62mil + 22.69mil; 54.63mil + 22.9mil; 55.63mil + 22.99mil; 56.69mil + 22.99mil; 77.14mil + 22.96mil; 77.56mil + 22.9mil; 77.96mil + 22.81mil; 78.32mil + 22.66mil; 78.66mil + 22.51mil; 78.93mil + 22.29mil; 79.2mil + 22.02mil; 79.45mil + 21.75mil; 79.63mil + 21.44mil; 79.78mil + 21.14mil; 79.9mil + 20.77mil; 79.96mil + 20.38mil; 80.0mil + 8.82mil; 80.0mil + 7.69mil; 79.93mil + 6.6mil; 79.69mil + 5.56mil; 79.33mil + 4.59mil; 78.78mil + 3.62mil; 78.08mil + 2.7mil; 77.2mil + 1.88mil; 76.25mil + 1.21mil; 75.28mil + 0.67mil; 74.25mil + 0.3mil; 73.18mil + 0.06mil; 72.09mil + 0.0mil; 70.87mil + 0.06mil; 69.62mil + 0.27mil; 68.41mil + 0.61mil; 67.28mil + 1.09mil; 66.22mil + 1.73mil; 65.24mil + 2.55mil; 64.27mil + 3.4mil; 63.48mil + 4.38mil; 62.81mil + 5.38mil; 62.26mil + 6.48mil; 61.9mil + 7.66mil; 61.65mil + 8.94mil; 61.56mil + 9.55mil; 65.97mil + 8.73mil; 66.03mil + 8.0mil; 66.15mil + 7.33mil; 66.37mil + 6.75mil; 66.64mil + 6.23mil; 67.01mil + 5.78mil; 67.46mil + 5.38mil; 67.98mil + 5.08mil; 68.5mil + 4.83mil; 69.04mil + 4.65mil; 69.62mil + 4.53mil; 70.2mil + 4.5mil; 70.81mil + 4.53mil; 71.48mil + 4.65mil; 72.09mil + 4.83mil; 72.63mil + 5.11mil; 73.15mil + 5.47mil; 73.64mil + 5.93mil; 74.09mil + 6.38mil; 74.49mil + 6.9mil; 74.82mil + 7.42mil; 75.07mil + 7.97mil; 75.25mil + 8.51mil; 75.37mil + 9.12mil; 75.4mil + 18.43mil; 75.4mil + 18.43mil; 65.97mil + 9.55mil; 65.97mil + 8.94mil; 61.56mil + 18.43mil; 61.56mil + 18.43mil; 55.96mil + 18.37mil; 55.6mil + 18.28mil; 55.2mil + 18.07mil; 54.78mil + 17.82mil; 54.38mil + 17.49mil; 53.96mil + 17.06mil; 53.5mil + 16.57mil; 53.11mil + 16.12mil; 52.8mil + 15.6mil; 52.53mil + 15.08mil; 52.35mil + 14.57mil; 52.22mil + 14.02mil; 52.16mil + } + } + height = 63.33mil + } + ha:b { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 2.74mil; 79.87mil + 1.88mil; 79.84mil + 1.21mil; 79.66mil + 0.67mil; 79.39mil + 0.3mil; 78.99mil + 0.06mil; 78.47mil + 0.0mil; 77.8mil + 0.0mil; 36.16mil + 0.03mil; 35.49mil + 0.21mil; 34.95mil + 0.51mil; 34.49mil + 0.91mil; 34.19mil + 1.43mil; 34.0mil + 2.1mil; 33.91mil + 2.77mil; 34.0mil + 3.31mil; 34.19mil + 3.77mil; 34.49mil + 4.07mil; 34.92mil + 4.26mil; 35.46mil + 4.35mil; 36.16mil + 4.35mil; 47.81mil + + 13.23mil; 75.49mil + 14.81mil; 75.37mil + 16.12mil; 74.95mil + 17.12mil; 74.22mil + 17.85mil; 73.24mil + 18.28mil; 71.96mil + 18.46mil; 70.32mil + 18.46mil; 69.99mil + 18.46mil; 68.89mil + 18.46mil; 67.1mil + 18.46mil; 64.6mil + 18.46mil; 61.38mil + 18.46mil; 57.27mil + 18.4mil; 56.54mil + 18.31mil; 55.84mil + 18.1mil; 55.2mil + 17.85mil; 54.6mil + 17.52mil; 54.08mil + 17.09mil; 53.56mil + 16.61mil; 53.17mil + 16.06mil; 52.83mil + 15.51mil; 52.56mil + 14.87mil; 52.35mil + 14.2mil; 52.22mil + 13.47mil; 52.16mil + 4.29mil; 52.16mil + 4.29mil; 75.49mil + 13.23mil; 75.49mil + + 4.35mil; 47.81mil + 14.39mil; 47.81mil + 15.63mil; 47.93mil + 16.82mil; 48.21mil + 17.94mil; 48.7mil + 19.04mil; 49.36mil + 20.07mil; 50.22mil + 21.08mil; 51.28mil + 21.59mil; 52.01mil + 22.02mil; 52.8mil + 22.35mil; 53.59mil + 22.6mil; 54.44mil + 22.75mil; 55.33mil + 22.81mil; 56.27mil + 22.81mil; 71.54mil + 22.72mil; 72.69mil + 22.51mil; 73.79mil + 22.14mil; 74.79mil + 21.66mil; 75.74mil + 20.99mil; 76.65mil + 20.2mil; 77.47mil + 19.28mil; 78.2mil + 18.31mil; 78.81mil + 17.24mil; 79.26mil + 16.15mil; 79.6mil + 14.93mil; 79.81mil + 13.66mil; 79.87mil + } + } + height = 63.33mil + } + ha:c { + width=18mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 15.91mil; 47.69mil + 16.61mil; 47.75mil + 17.19mil; 47.93mil + 17.61mil; 48.24mil + 17.95mil; 48.63mil + 18.13mil; 49.18mil + 18.22mil; 49.82mil + 18.13mil; 50.52mil + 17.95mil; 51.1mil + 17.64mil; 51.55mil + 17.19mil; 51.86mil + 16.61mil; 52.04mil + 15.91mil; 52.1mil + 15.73mil; 52.1mil + 15.24mil; 52.1mil + 14.39mil; 52.1mil + 13.23mil; 52.1mil + 11.74mil; 52.1mil + 9.85mil; 52.1mil + 8.18mil; 52.25mil + 6.84mil; 52.68mil + 5.78mil; 53.38mil + 5.05mil; 54.35mil + 4.59mil; 55.63mil + 4.44mil; 57.21mil + 4.44mil; 57.58mil + 4.44mil; 58.61mil + 4.44mil; 60.38mil + 4.44mil; 62.81mil + 4.44mil; 65.94mil + 4.44mil; 69.9mil + 4.56mil; 71.6mil + 4.99mil; 72.97mil + 5.69mil; 74.03mil + 6.66mil; 74.79mil + 7.94mil; 75.25mil + 9.55mil; 75.4mil + 15.76mil; 75.4mil + 16.49mil; 75.49mil + 17.09mil; 75.68mil + 17.58mil; 76.01mil + 17.92mil; 76.44mil + 18.13mil; 77.01mil + 18.22mil; 77.74mil + 18.13mil; 78.41mil + 17.95mil; 78.93mil + 17.61mil; 79.36mil + 17.19mil; 79.66mil + 16.61mil; 79.81mil + 15.88mil; 79.87mil + 15.66mil; 79.87mil + 15.09mil; 79.87mil + 14.11mil; 79.87mil + 12.74mil; 79.87mil + 10.98mil; 79.87mil + 8.79mil; 79.87mil + 7.6mil; 79.81mil + 6.48mil; 79.6mil + 5.38mil; 79.23mil + 4.38mil; 78.72mil + 3.41mil; 78.05mil + 2.49mil; 77.2mil + 1.73mil; 76.34mil + 1.09mil; 75.4mil + 0.61mil; 74.43mil + 0.27mil; 73.36mil + 0.06mil; 72.24mil + 0.0mil; 70.99mil + 0.0mil; 70.63mil + 0.0mil; 69.47mil + 0.0mil; 67.58mil + 0.0mil; 64.91mil + 0.0mil; 61.47mil + 0.0mil; 57.09mil + 0.06mil; 55.78mil + 0.24mil; 54.54mil + 0.58mil; 53.38mil + 1.06mil; 52.35mil + 1.64mil; 51.4mil + 2.43mil; 50.49mil + 3.38mil; 49.67mil + 4.44mil; 48.97mil + 5.54mil; 48.42mil + 6.75mil; 48.03mil + 8.03mil; 47.78mil + 9.43mil; 47.69mil + 9.58mil; 47.69mil + 10.13mil; 47.69mil + 11.01mil; 47.69mil + 12.26mil; 47.69mil + 13.87mil; 47.69mil + } + } + height = 63.33mil + } + ha:d { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 18.4mil; 36.25mil + 18.46mil; 35.55mil + 18.65mil; 34.98mil + 18.95mil; 34.52mil + 19.38mil; 34.19mil + 19.92mil; 34.0mil + 20.62mil; 33.91mil + 21.29mil; 34.0mil + 21.84mil; 34.22mil + 22.27mil; 34.55mil + 22.57mil; 35.04mil + 22.75mil; 35.65mil + 22.84mil; 36.41mil + 22.84mil; 77.14mil + 22.75mil; 78.02mil + 22.51mil; 78.72mil + 22.11mil; 79.3mil + 21.57mil; 79.69mil + 20.84mil; 79.93mil + 19.95mil; 80.0mil + 9.4mil; 80.0mil + 8.12mil; 79.93mil + 6.93mil; 79.75mil + 5.81mil; 79.39mil + 4.81mil; 78.93mil + 3.86mil; 78.32mil + 2.98mil; 77.53mil + 2.07mil; 76.53mil + 1.31mil; 75.49mil + 0.73mil; 74.43mil + 0.33mil; 73.33mil + 0.06mil; 72.18mil + 0.0mil; 70.96mil + 0.0mil; 56.45mil + 0.03mil; 55.51mil + 0.21mil; 54.57mil + 0.52mil; 53.62mil + 0.91mil; 52.74mil + 1.43mil; 51.86mil + 2.1mil; 50.95mil + 3.01mil; 49.97mil + 4.08mil; 49.18mil + 5.26mil; 48.54mil + 6.54mil; 48.12mil + 7.94mil; 47.84mil + 9.55mil; 47.72mil + 9.58mil; 52.13mil + 7.97mil; 52.31mil + 6.66mil; 52.8mil + 5.63mil; 53.59mil + 4.9mil; 54.72mil + 4.47mil; 56.15mil + 4.32mil; 57.97mil + 4.32mil; 58.31mil + 4.32mil; 59.31mil + 4.32mil; 60.95mil + 4.32mil; 63.27mil + 4.32mil; 66.22mil + 4.32mil; 69.96mil + 4.47mil; 71.63mil + 4.93mil; 73.0mil + 5.69mil; 74.03mil + 6.75mil; 74.79mil + 8.15mil; 75.25mil + 9.92mil; 75.4mil + 10.13mil; 75.4mil + 10.83mil; 75.4mil + 11.98mil; 75.4mil + 13.63mil; 75.4mil + 15.73mil; 75.4mil + 18.4mil; 75.4mil + 18.4mil; 74.76mil + 18.4mil; 72.85mil + 18.4mil; 69.65mil + 18.4mil; 65.18mil + 18.4mil; 59.43mil + 18.4mil; 52.13mil + 18.16mil; 52.13mil + 17.43mil; 52.13mil + 16.21mil; 52.13mil + 14.51mil; 52.13mil + 12.32mil; 52.13mil + 9.58mil; 52.13mil + 9.55mil; 47.72mil + 18.4mil; 47.72mil + } + } + height = 63.33mil + } + ha:e { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 0.0mil; 58.76mil + 0.09mil; 57.21mil + 0.43mil; 55.75mil + 0.97mil; 54.35mil + 1.73mil; 53.04mil + 2.71mil; 51.83mil + 3.98mil; 50.61mil + 5.14mil; 49.73mil + 6.36mil; 49.0mil + 7.6mil; 48.45mil + 8.88mil; 48.03mil + 10.19mil; 47.78mil + 11.62mil; 47.69mil + 13.2mil; 47.81mil + 14.72mil; 48.12mil + 16.15mil; 48.63mil + 17.52mil; 49.36mil + 18.8mil; 50.31mil + 20.04mil; 51.49mil + 20.9mil; 52.56mil + 21.6mil; 53.59mil + 22.14mil; 54.66mil + 22.54mil; 55.75mil + 22.78mil; 56.85mil + 22.87mil; 57.97mil + 22.87mil; 63.75mil + 22.81mil; 64.42mil + 22.63mil; 64.97mil + 22.36mil; 65.39mil + 21.96mil; 65.7mil + 21.44mil; 65.88mil + 20.84mil; 65.94mil + 4.5mil; 65.94mil + 4.5mil; 69.96mil + 4.62mil; 71.66mil + 5.02mil; 73.06mil + 4.56mil; 61.62mil + 18.52mil; 61.62mil + 18.46mil; 60.13mil + 18.34mil; 58.79mil + 18.13mil; 57.58mil + 17.85mil; 56.51mil + 17.46mil; 55.6mil + 17.0mil; 54.81mil + 16.3mil; 54.02mil + 15.54mil; 53.38mil + 14.72mil; 52.86mil + 13.81mil; 52.5mil + 12.81mil; 52.28mil + 11.71mil; 52.19mil + 10.65mil; 52.28mil + 9.64mil; 52.5mil + 8.7mil; 52.86mil + 7.79mil; 53.38mil + 6.9mil; 54.05mil + 6.08mil; 54.87mil + 5.6mil; 55.54mil + 5.23mil; 56.39mil + 4.93mil; 57.39mil + 4.71mil; 58.61mil + 4.59mil; 60.01mil + 4.56mil; 61.62mil + 5.02mil; 73.06mil + 5.66mil; 74.15mil + 6.57mil; 74.95mil + 7.76mil; 75.4mil + 9.25mil; 75.55mil + 20.29mil; 75.55mil + 21.08mil; 75.65mil + 21.75mil; 75.83mil + 22.27mil; 76.13mil + 22.66mil; 76.56mil + 22.87mil; 77.11mil + 22.96mil; 77.8mil + 22.87mil; 78.47mil + 22.66mil; 79.02mil + 22.3mil; 79.45mil + 21.78mil; 79.75mil + 21.14mil; 79.93mil + 20.32mil; 80.0mil + 9.12mil; 80.0mil + 7.91mil; 79.93mil + 6.75mil; 79.69mil + 5.66mil; 79.3mil + 4.62mil; 78.72mil + 3.62mil; 77.99mil + 2.65mil; 77.04mil + 1.82mil; 76.1mil + 1.16mil; 75.1mil + 0.64mil; 74.0mil + 0.27mil; 72.88mil + 0.06mil; 71.69mil + 0.0mil; 70.38mil + 0.0mil; 70.08mil + 0.0mil; 69.14mil + 0.0mil; 67.52mil + 0.0mil; 65.3mil + 0.0mil; 62.41mil + } + } + height = 63.33mil + } + ha:f { + width=18mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 15.88mil; 33.82mil + 16.58mil; 33.91mil + 17.15mil; 34.09mil + 17.58mil; 34.4mil + 17.91mil; 34.82mil + 18.1mil; 35.37mil + 18.19mil; 36.04mil + 18.1mil; 36.74mil + 17.88mil; 37.32mil + 17.55mil; 37.78mil + 17.06mil; 38.08mil + 16.45mil; 38.26mil + 15.69mil; 38.32mil + 14.35mil; 38.32mil + 13.66mil; 38.38mil + 13.02mil; 38.47mil + 12.41mil; 38.66mil + 11.83mil; 38.9mil + 11.25mil; 39.2mil + 10.74mil; 39.57mil + 10.19mil; 40.09mil + 9.76mil; 40.6mil + 9.43mil; 41.21mil + 9.18mil; 41.85mil + 9.03mil; 42.52mil + 9.0mil; 43.28mil + 9.0mil; 47.69mil + 15.66mil; 47.69mil + 16.42mil; 47.78mil + 17.06mil; 47.96mil + 17.55mil; 48.27mil + 17.91mil; 48.7mil + 18.13mil; 49.24mil + 18.22mil; 49.94mil + 18.13mil; 50.61mil + 17.91mil; 51.13mil + 17.55mil; 51.55mil + 17.06mil; 51.86mil + 16.42mil; 52.01mil + 15.63mil; 52.07mil + 8.97mil; 52.07mil + 8.97mil; 77.56mil + 8.88mil; 78.29mil + 8.7mil; 78.87mil + 8.36mil; 79.3mil + 7.94mil; 79.63mil + 7.36mil; 79.81mil + 6.63mil; 79.87mil + 5.99mil; 79.81mil + 5.47mil; 79.6mil + 5.08mil; 79.26mil + 4.77mil; 78.78mil + 4.59mil; 78.14mil + 4.56mil; 77.35mil + 4.56mil; 52.07mil + 2.1mil; 52.07mil + 1.46mil; 52.01mil + 0.91mil; 51.83mil + 0.51mil; 51.52mil + 0.21mil; 51.1mil + 0.06mil; 50.55mil + 0.0mil; 49.85mil + 0.06mil; 49.21mil + 0.24mil; 48.66mil + 0.55mil; 48.24mil + 0.97mil; 47.96mil + 1.52mil; 47.78mil + 2.22mil; 47.69mil + 4.56mil; 47.69mil + 4.56mil; 43.07mil + 4.62mil; 41.85mil + 4.83mil; 40.73mil + 5.17mil; 39.63mil + 5.66mil; 38.66mil + 6.29mil; 37.71mil + 7.09mil; 36.83mil + 8.12mil; 35.92mil + 9.18mil; 35.19mil + 10.25mil; 34.61mil + 11.34mil; 34.19mil + 12.47mil; 33.91mil + 13.66mil; 33.82mil + } + } + height = 63.33mil + } + ha:g { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 9.22mil; 47.84mil + 9.52mil; 47.84mil + 10.43mil; 47.84mil + 11.98mil; 47.84mil + 14.17mil; 47.84mil + 16.94mil; 47.84mil + 20.5mil; 47.84mil + 21.17mil; 47.93mil + 21.75mil; 48.15mil + 22.2mil; 48.48mil + 22.51mil; 48.97mil + 22.69mil; 49.58mil + 22.78mil; 50.34mil + 22.78mil; 51.31mil + 22.78mil; 54.23mil + 22.78mil; 59.04mil + 22.78mil; 65.82mil + 22.78mil; 74.49mil + 22.78mil; 85.5mil + 22.69mil; 86.6mil + 22.48mil; 87.66mil + 22.11mil; 88.69mil + 21.63mil; 89.64mil + 20.99mil; 90.55mil + 20.2mil; 91.43mil + 19.31mil; 92.16mil + 18.37mil; 92.77mil + 17.4mil; 93.23mil + 16.36mil; 93.56mil + 15.27mil; 93.77mil + 14.11mil; 93.87mil + 13.84mil; 93.87mil + 13.05mil; 93.87mil + 11.74mil; 93.87mil + 9.92mil; 93.87mil + 7.57mil; 93.87mil + 4.59mil; 93.87mil + 3.86mil; 93.8mil + 3.25mil; 93.62mil + 2.8mil; 93.32mil + 2.46mil; 92.89mil + 2.28mil; 92.38mil + 2.22mil; 91.71mil + 2.28mil; 91.01mil + 2.49mil; 90.46mil + 2.83mil; 90.0mil + 3.31mil; 89.7mil + 3.92mil; 89.52mil + 4.71mil; 89.45mil + 4.9mil; 89.45mil + 5.54mil; 89.45mil + 6.6mil; 89.45mil + 8.06mil; 89.45mil + 9.98mil; 89.45mil + + 9.58mil; 52.28mil + 8.88mil; 52.35mil + 8.21mil; 52.44mil + 7.6mil; 52.62mil + 7.0mil; 52.89mil + 6.45mil; 53.23mil + 5.9mil; 53.62mil + 5.41mil; 54.11mil + 5.02mil; 54.66mil + 4.71mil; 55.27mil + 4.47mil; 55.9mil + 4.35mil; 56.6mil + 4.32mil; 57.39mil + 4.32mil; 70.08mil + 4.35mil; 70.96mil + 4.44mil; 71.75mil + 4.62mil; 72.48mil + 4.9mil; 73.15mil + 5.23mil; 73.73mil + 5.66mil; 74.25mil + 6.08mil; 74.67mil + 6.6mil; 75.01mil + 7.18mil; 75.25mil + 7.82mil; 75.46mil + 8.55mil; 75.55mil + 9.37mil; 75.58mil + 18.37mil; 75.58mil + 18.37mil; 52.28mil + 9.58mil; 52.28mil + + 9.98mil; 89.45mil + 12.38mil; 89.45mil + 14.14mil; 89.33mil + 15.63mil; 88.97mil + 16.76mil; 88.36mil + 17.58mil; 87.54mil + 18.1mil; 86.47mil + 18.28mil; 85.14mil + 18.28mil; 80.0mil + 18.01mil; 80.0mil + 17.19mil; 80.0mil + 15.82mil; 80.0mil + 13.93mil; 80.0mil + 11.5mil; 80.0mil + 8.43mil; 80.0mil + 7.21mil; 79.93mil + 6.08mil; 79.72mil + 5.05mil; 79.33mil + 4.08mil; 78.81mil + 3.19mil; 78.11mil + 2.34mil; 77.23mil + 1.61mil; 76.31mil + 1.03mil; 75.31mil + 0.58mil; 74.25mil + 0.24mil; 73.15mil + 0.06mil; 71.96mil + 0.0mil; 70.69mil + 0.0mil; 70.32mil + 0.0mil; 69.17mil + 0.0mil; 67.25mil + 0.0mil; 64.57mil + 0.0mil; 61.14mil + 0.0mil; 56.76mil + 0.06mil; 55.57mil + 0.27mil; 54.41mil + 0.61mil; 53.35mil + 1.09mil; 52.35mil + 1.73mil; 51.43mil + 2.55mil; 50.52mil + 3.47mil; 49.73mil + 4.47mil; 49.06mil + 5.57mil; 48.54mil + 6.69mil; 48.15mil + 7.88mil; 47.93mil + } + } + height = 63.33mil + } + ha:h { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 36.62mil + 0.06mil; 35.8mil + 0.24mil; 35.13mil + 0.55mil; 34.61mil + 0.97mil; 34.25mil + 1.55mil; 34.0mil + 2.28mil; 33.91mil + 2.92mil; 34.0mil + 3.47mil; 34.22mil + 3.89mil; 34.58mil + 4.16mil; 35.07mil + 4.35mil; 35.71mil + 4.44mil; 36.5mil + 4.44mil; 47.75mil + 13.87mil; 47.75mil + 15.02mil; 47.84mil + 16.18mil; 48.09mil + 17.31mil; 48.45mil + 18.37mil; 49.0mil + 19.4mil; 49.7mil + 20.47mil; 50.58mil + 21.17mil; 51.4mil + 21.78mil; 52.28mil + 22.23mil; 53.26mil + 22.57mil; 54.35mil + 22.75mil; 55.54mil + 22.84mil; 56.85mil + 22.84mil; 77.44mil + 22.78mil; 78.17mil + 22.6mil; 78.78mil + 22.32mil; 79.23mil + 21.93mil; 79.57mil + 21.44mil; 79.75mil + 20.83mil; 79.81mil + 20.1mil; 79.75mil + 19.53mil; 79.57mil + 19.07mil; 79.23mil + 18.74mil; 78.75mil + 18.55mil; 78.17mil + 18.49mil; 77.38mil + 18.49mil; 57.36mil + 18.34mil; 55.78mil + 17.88mil; 54.47mil + 17.15mil; 53.47mil + 16.12mil; 52.74mil + 14.81mil; 52.31mil + 13.14mil; 52.13mil + 4.44mil; 52.13mil + 4.44mil; 77.35mil + 4.35mil; 78.11mil + 4.16mil; 78.72mil + 3.86mil; 79.2mil + 3.4mil; 79.54mil + 2.83mil; 79.75mil + 2.13mil; 79.81mil + 1.46mil; 79.75mil + 0.94mil; 79.54mil + 0.51mil; 79.17mil + 0.21mil; 78.69mil + 0.06mil; 78.02mil + 0.0mil; 77.2mil + } + } + height = 63.33mil + } + ha:i { + width=4mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 4.47mil; 50.19mil + 4.47mil; 77.32mil + 4.41mil; 78.11mil + 4.23mil; 78.72mil + 3.92mil; 79.23mil + 3.5mil; 79.57mil + 2.95mil; 79.78mil + 2.28mil; 79.84mil + 1.58mil; 79.78mil + 1.0mil; 79.6mil + 0.55mil; 79.23mil + 0.24mil; 78.78mil + 0.06mil; 78.17mil + 0.0mil; 77.38mil + 0.0mil; 50.22mil + 0.06mil; 49.49mil + 0.24mil; 48.85mil + 0.55mil; 48.36mil + 0.97mil; 48.03mil + 1.52mil; 47.81mil + 2.25mil; 47.72mil + 2.92mil; 47.81mil + 3.47mil; 48.0mil + 3.89mil; 48.36mil + 4.2mil; 48.82mil + 4.38mil; 49.43mil + } + li:simplepoly.1 { + 0.09mil; 36.04mil + 0.12mil; 35.4mil + 0.3mil; 34.89mil + 0.61mil; 34.46mil + 1.0mil; 34.16mil + 1.52mil; 34.0mil + 2.19mil; 33.91mil + 2.86mil; 34.0mil + 3.4mil; 34.19mil + 3.86mil; 34.49mil + 4.16mil; 34.92mil + 4.35mil; 35.49mil + 4.44mil; 36.19mil + 4.44mil; 38.17mil + 4.35mil; 38.9mil + 4.16mil; 39.51mil + 3.86mil; 39.97mil + 3.4mil; 40.3mil + 2.83mil; 40.48mil + 2.13mil; 40.54mil + 1.49mil; 40.48mil + 0.97mil; 40.3mil + 0.58mil; 40.0mil + 0.3mil; 39.57mil + 0.12mil; 39.02mil + 0.09mil; 38.32mil + } + } + height = 63.33mil + } + ha:j { + width=13mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 9.15mil; 50.22mil + 9.18mil; 49.55mil + 9.36mil; 48.97mil + 9.67mil; 48.51mil + 10.09mil; 48.21mil + 10.64mil; 48.03mil + 11.34mil; 47.93mil + 11.98mil; 48.03mil + 12.52mil; 48.21mil + 12.98mil; 48.51mil + 13.28mil; 48.94mil + 13.47mil; 49.49mil + 13.56mil; 50.19mil + 13.56mil; 85.2mil + 13.47mil; 86.26mil + 13.25mil; 87.3mil + 12.92mil; 88.27mil + 12.43mil; 89.24mil + 11.82mil; 90.12mil + 11.06mil; 91.04mil + 10.12mil; 91.89mil + 9.15mil; 92.59mil + 8.14mil; 93.14mil + 7.11mil; 93.53mil + 6.05mil; 93.77mil + 4.95mil; 93.87mil + 2.31mil; 93.87mil + 1.61mil; 93.77mil + 1.04mil; 93.59mil + 0.61mil; 93.29mil + 0.28mil; 92.86mil + 0.09mil; 92.31mil + 0.0mil; 91.61mil + 0.06mil; 90.95mil + 0.25mil; 90.4mil + 0.55mil; 89.97mil + 0.98mil; 89.7mil + 1.49mil; 89.52mil + 2.16mil; 89.45mil + 4.8mil; 89.45mil + 5.29mil; 89.39mil + 5.8mil; 89.27mil + 6.29mil; 89.06mil + 6.81mil; 88.76mil + 7.29mil; 88.36mil + 7.84mil; 87.87mil + 8.24mil; 87.39mil + 8.54mil; 86.93mil + 8.81mil; 86.44mil + 9.0mil; 85.93mil + 9.09mil; 85.41mil + 9.15mil; 84.86mil + } + li:simplepoly.1 { + 9.15mil; 36.38mil + 9.21mil; 35.65mil + 9.39mil; 35.04mil + 9.73mil; 34.55mil + 10.18mil; 34.22mil + 10.79mil; 34.0mil + 11.55mil; 33.91mil + 12.16mil; 34.0mil + 12.65mil; 34.22mil + 13.04mil; 34.58mil + 13.32mil; 35.07mil + 13.5mil; 35.74mil + 13.56mil; 36.53mil + 13.56mil; 38.41mil + 13.5mil; 39.08mil + 13.32mil; 39.63mil + 13.01mil; 40.06mil + 12.59mil; 40.36mil + 12.04mil; 40.54mil + 11.37mil; 40.6mil + 10.7mil; 40.57mil + 10.15mil; 40.39mil + 9.7mil; 40.12mil + 9.39mil; 39.72mil + 9.21mil; 39.2mil + 9.15mil; 38.57mil + } + } + height = 63.33mil + } + ha:k { + width=23mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 36.53mil + 0.03mil; 35.8mil + 0.21mil; 35.19mil + 0.51mil; 34.7mil + 0.94mil; 34.37mil + 1.46mil; 34.16mil + 2.16mil; 34.06mil + 2.83mil; 34.16mil + 3.37mil; 34.34mil + 3.8mil; 34.7mil + 4.1mil; 35.16mil + 4.29mil; 35.77mil + 4.38mil; 36.53mil + 4.38mil; 59.55mil + 18.98mil; 48.54mil + 19.28mil; 48.36mil + 19.59mil; 48.21mil + 19.92mil; 48.12mil + 20.23mil; 48.03mil + 20.53mil; 47.96mil + 20.86mil; 47.93mil + 21.5mil; 48.0mil + 22.05mil; 48.18mil + 22.48mil; 48.48mil + 22.75mil; 48.88mil + 22.93mil; 49.43mil + 23.02mil; 50.06mil + 22.99mil; 50.43mil + 22.9mil; 50.73mil + 22.75mil; 51.04mil + 22.57mil; 51.34mil + 22.29mil; 51.62mil + 21.99mil; 51.89mil + 13.17mil; 58.55mil + 22.6mil; 76.59mil + 22.69mil; 76.83mil + 22.78mil; 77.04mil + 22.84mil; 77.26mil + 22.9mil; 77.44mil + 22.93mil; 77.65mil + 22.96mil; 77.84mil + 22.87mil; 78.5mil + 22.69mil; 79.05mil + 22.35mil; 79.48mil + 21.9mil; 79.75mil + 21.32mil; 79.93mil + 20.59mil; 80.0mil + 20.2mil; 79.96mil + 19.86mil; 79.87mil + 19.56mil; 79.72mil + 19.28mil; 79.48mil + 19.01mil; 79.17mil + 18.8mil; 78.78mil + 9.61mil; 61.2mil + 4.53mil; 65.15mil + 4.53mil; 77.59mil + 4.44mil; 78.32mil + 4.26mil; 78.9mil + 3.95mil; 79.33mil + 3.53mil; 79.66mil + 2.98mil; 79.84mil + 2.28mil; 79.9mil + 1.58mil; 79.84mil + 1.0mil; 79.66mil + 0.55mil; 79.36mil + 0.24mil; 78.93mil + 0.06mil; 78.35mil + 0.0mil; 77.62mil + } + } + height = 63.33mil + } + ha:l { + width=9mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 36.44mil + 0.06mil; 35.71mil + 0.24mil; 35.13mil + 0.58mil; 34.64mil + 1.06mil; 34.31mil + 1.64mil; 34.12mil + 2.43mil; 34.03mil + 3.04mil; 34.12mil + 3.56mil; 34.34mil + 3.95mil; 34.67mil + 4.23mil; 35.16mil + 4.41mil; 35.77mil + 4.47mil; 36.53mil + 4.47mil; 37.53mil + 4.47mil; 40.45mil + 4.47mil; 45.35mil + 4.47mil; 52.19mil + 4.47mil; 60.98mil + 4.47mil; 72.12mil + 4.5mil; 73.15mil + 4.68mil; 74.0mil + 4.96mil; 74.64mil + 5.35mil; 75.13mil + 5.87mil; 75.4mil + 6.54mil; 75.49mil + 7.3mil; 75.58mil + 7.91mil; 75.77mil + 8.42mil; 76.07mil + 8.76mil; 76.5mil + 8.97mil; 77.07mil + 9.06mil; 77.77mil + 8.97mil; 78.47mil + 8.79mil; 79.02mil + 8.45mil; 79.45mil + 8.0mil; 79.75mil + 7.42mil; 79.93mil + 6.69mil; 80.0mil + 5.78mil; 79.96mil + 4.93mil; 79.78mil + 4.1mil; 79.48mil + 3.31mil; 79.05mil + 2.55mil; 78.53mil + 1.85mil; 77.84mil + 1.28mil; 77.17mil + 0.82mil; 76.44mil + 0.45mil; 75.65mil + 0.18mil; 74.79mil + 0.03mil; 73.88mil + 0.0mil; 72.85mil + 0.0mil; 71.87mil + 0.0mil; 68.86mil + 0.0mil; 63.87mil + 0.0mil; 56.85mil + 0.0mil; 47.84mil + } + } + height = 63.33mil + } + ha:m { + width=32mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 49.85mil + 0.0mil; 49.52mil + 0.06mil; 49.21mil + 0.18mil; 48.88mil + 0.33mil; 48.6mil + 0.52mil; 48.33mil + 0.79mil; 48.06mil + 0.94mil; 47.93mil + 1.19mil; 47.81mil + 1.46mil; 47.72mil + 1.76mil; 47.66mil + 2.1mil; 47.63mil + 2.52mil; 47.6mil + 3.07mil; 47.6mil + 4.71mil; 47.6mil + 7.45mil; 47.6mil + 11.28mil; 47.6mil + 16.21mil; 47.6mil + 22.48mil; 47.6mil + 23.73mil; 47.69mil + 24.94mil; 47.87mil + 26.07mil; 48.21mil + 27.1mil; 48.66mil + 28.08mil; 49.24mil + 29.02mil; 49.97mil + 29.93mil; 50.95mil + 30.69mil; 51.92mil + 31.3mil; 52.98mil + 31.73mil; 54.05mil + 32.0mil; 55.2mil + 32.09mil; 56.39mil + 32.09mil; 56.97mil + 32.09mil; 58.7mil + 32.09mil; 61.56mil + 32.09mil; 65.55mil + 32.09mil; 70.69mil + 32.09mil; 77.2mil + 32.03mil; 78.02mil + 31.85mil; 78.69mil + 31.54mil; 79.2mil + 31.15mil; 79.6mil + 30.6mil; 79.81mil + 29.96mil; 79.87mil + 29.23mil; 79.81mil + 28.65mil; 79.6mil + 28.2mil; 79.2mil + 27.86mil; 78.69mil + 27.68mil; 77.99mil + 27.62mil; 77.11mil + 27.62mil; 76.56mil + 27.62mil; 74.88mil + 27.62mil; 72.12mil + 27.62mil; 68.22mil + 27.62mil; 63.2mil + 27.62mil; 56.85mil + 27.56mil; 56.18mil + 27.47mil; 55.57mil + 27.28mil; 54.99mil + 27.04mil; 54.47mil + 26.74mil; 53.99mil + 26.34mil; 53.53mil + 25.82mil; 53.11mil + 25.25mil; 52.77mil + 24.67mil; 52.47mil + 24.03mil; 52.28mil + 23.36mil; 52.16mil + 22.63mil; 52.1mil + 18.31mil; 52.1mil + 18.31mil; 77.14mil + 18.25mil; 77.96mil + 18.07mil; 78.63mil + 17.76mil; 79.14mil + 17.34mil; 79.51mil + 16.82mil; 79.72mil + 16.15mil; 79.78mil + 15.39mil; 79.72mil + 14.78mil; 79.54mil + 14.33mil; 79.2mil + 13.99mil; 78.72mil + 13.78mil; 78.14mil + 13.72mil; 77.35mil + 13.72mil; 52.1mil + 4.38mil; 52.1mil + 4.38mil; 77.5mil + 4.32mil; 78.23mil + 4.14mil; 78.81mil + 3.83mil; 79.23mil + 3.41mil; 79.57mil + 2.86mil; 79.75mil + 2.19mil; 79.81mil + 1.52mil; 79.78mil + 0.97mil; 79.6mil + 0.55mil; 79.3mil + 0.24mil; 78.87mil + 0.06mil; 78.35mil + 0.0mil; 77.65mil + } + } + height = 63.33mil + } + ha:n { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 49.94mil + 0.06mil; 49.27mil + 0.24mil; 48.7mil + 0.55mil; 48.24mil + 0.97mil; 47.93mil + 1.52mil; 47.75mil + 2.22mil; 47.66mil + 2.52mil; 47.66mil + 3.5mil; 47.66mil + 5.11mil; 47.66mil + 7.36mil; 47.66mil + 10.25mil; 47.66mil + 13.93mil; 47.66mil + 15.12mil; 47.75mil + 16.27mil; 48.0mil + 17.4mil; 48.39mil + 18.49mil; 48.97mil + 19.53mil; 49.7mil + 20.59mil; 50.61mil + 21.26mil; 51.4mil + 21.81mil; 52.25mil + 22.27mil; 53.17mil + 22.57mil; 54.2mil + 22.75mil; 55.27mil + 22.84mil; 56.45mil + 22.84mil; 57.03mil + 22.84mil; 58.7mil + 22.84mil; 61.5mil + 22.84mil; 65.42mil + 22.84mil; 70.47mil + 22.84mil; 76.86mil + 22.78mil; 77.77mil + 22.6mil; 78.5mil + 22.3mil; 79.05mil + 21.9mil; 79.48mil + 21.35mil; 79.72mil + 20.71mil; 79.78mil + 19.98mil; 79.72mil + 19.41mil; 79.48mil + 18.98mil; 79.05mil + 18.65mil; 78.47mil + 18.46mil; 77.74mil + 18.4mil; 76.8mil + 18.4mil; 76.25mil + 18.4mil; 74.61mil + 18.4mil; 71.87mil + 18.4mil; 68.04mil + 18.4mil; 63.08mil + 18.4mil; 56.82mil + 18.34mil; 56.12mil + 18.25mil; 55.48mil + 18.1mil; 54.9mil + 17.85mil; 54.38mil + 17.58mil; 53.96mil + 17.22mil; 53.53mil + 16.73mil; 53.14mil + 16.21mil; 52.8mil + 15.73mil; 52.56mil + 15.18mil; 52.35mil + 14.63mil; 52.25mil + 14.08mil; 52.19mil + 13.81mil; 52.19mil + 12.99mil; 52.19mil + 11.65mil; 52.19mil + 9.76mil; 52.19mil + 7.33mil; 52.19mil + 4.29mil; 52.19mil + 4.29mil; 77.2mil + 4.23mil; 77.99mil + 4.04mil; 78.63mil + 3.74mil; 79.11mil + 3.35mil; 79.48mil + 2.8mil; 79.69mil + 2.16mil; 79.75mil + 1.49mil; 79.69mil + 0.94mil; 79.48mil + 0.52mil; 79.14mil + 0.24mil; 78.66mil + 0.06mil; 78.02mil + 0.0mil; 77.23mil + 0.0mil; 76.5mil + 0.0mil; 74.25mil + 0.0mil; 70.5mil + 0.0mil; 65.24mil + 0.0mil; 58.49mil + } + } + height = 63.33mil + } + ha:o { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 11.04mil; 47.66mil + 12.65mil; 47.75mil + 14.2mil; 48.03mil + 15.63mil; 48.45mil + 16.97mil; 49.09mil + 18.19mil; 49.88mil + 19.38mil; 50.85mil + 20.41mil; 52.01mil + 21.23mil; 53.17mil + 21.9mil; 54.32mil + 22.39mil; 55.54mil + 22.66mil; 56.76mil + 22.78mil; 58.03mil + 22.78mil; 68.62mil + 22.66mil; 70.26mil + 22.36mil; 71.81mil + 21.87mil; 73.24mil + 21.14mil; 74.58mil + 20.23mil; 75.8mil + 19.1mil; 76.95mil + 17.98mil; 77.8mil + 16.82mil; 78.5mil + 15.57mil; 79.05mil + 14.27mil; 79.45mil + 12.87mil; 79.69mil + 11.38mil; 79.75mil + 9.82mil; 79.69mil + 8.36mil; 79.45mil + 7.03mil; 79.05mil + 5.81mil; 78.47mil + 4.71mil; 77.77mil + 3.68mil; 76.83mil + 2.55mil; 75.58mil + 1.64mil; 74.28mil + 0.91mil; 72.91mil + 0.39mil; 71.51mil + 0.09mil; 70.05mil + 0.0mil; 68.47mil + 0.0mil; 58.52mil + 0.09mil; 56.94mil + 0.46mil; 55.45mil + 1.03mil; 54.02mil + 1.85mil; 52.68mil + 2.89mil; 51.43mil + 4.23mil; 50.19mil + 5.26mil; 49.43mil + 6.33mil; 48.82mil + 7.45mil; 48.3mil + 6.78mil; 53.77mil + 6.02mil; 54.44mil + 5.41mil; 55.2mil + 4.96mil; 56.06mil + 4.62mil; 57.03mil + 4.41mil; 58.12mil + 4.35mil; 59.34mil + 4.35mil; 59.62mil + 4.35mil; 60.38mil + 4.35mil; 61.65mil + 4.35mil; 63.45mil + 4.35mil; 65.76mil + 4.35mil; 68.68mil + 4.44mil; 69.81mil + 4.71mil; 70.84mil + 5.17mil; 71.78mil + 5.81mil; 72.66mil + 6.63mil; 73.49mil + 7.7mil; 74.22mil + 8.33mil; 74.61mil + 8.97mil; 74.92mil + 9.61mil; 75.13mil + 10.25mil; 75.31mil + 10.92mil; 75.4mil + 11.59mil; 75.43mil + 12.23mil; 75.4mil + 12.87mil; 75.31mil + 13.5mil; 75.13mil + 14.17mil; 74.85mil + 14.81mil; 74.52mil + 15.51mil; 74.09mil + 16.39mil; 73.39mil + 17.16mil; 72.51mil + 17.73mil; 71.54mil + 18.13mil; 70.41mil + 18.4mil; 69.17mil + 18.49mil; 67.74mil + 18.49mil; 59.98mil + 18.4mil; 58.76mil + 18.22mil; 57.64mil + 17.92mil; 56.6mil + 17.49mil; 55.66mil + 16.91mil; 54.84mil + 16.21mil; 54.05mil + 15.45mil; 53.44mil + 14.72mil; 52.95mil + 13.96mil; 52.56mil + 13.2mil; 52.28mil + 12.41mil; 52.1mil + 11.59mil; 52.04mil + 10.77mil; 52.1mil + 9.98mil; 52.25mil + 9.16mil; 52.5mil + 8.36mil; 52.83mil + 7.57mil; 53.26mil + 6.78mil; 53.77mil + 7.45mil; 48.3mil + 8.61mil; 47.96mil + 9.76mil; 47.75mil + } + } + height = 63.33mil + } + ha:p { + width=23mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 0.0mil; 50.52mil + 0.06mil; 49.76mil + 0.27mil; 49.09mil + 0.64mil; 48.6mil + 1.12mil; 48.24mil + 1.76mil; 48.03mil + 2.58mil; 47.93mil + 2.89mil; 47.93mil + 3.86mil; 47.93mil + 5.47mil; 47.93mil + 7.75mil; 47.93mil + 10.64mil; 47.93mil + 14.35mil; 47.93mil + 15.48mil; 48.03mil + 16.58mil; 48.27mil + 17.64mil; 48.7mil + 18.67mil; 49.27mil + 19.65mil; 50.0mil + 20.65mil; 50.95mil + 21.38mil; 51.86mil + 21.99mil; 52.8mil + 22.45mil; 53.81mil + 22.78mil; 54.87mil + 22.99mil; 56.0mil + 23.08mil; 57.21mil + 23.08mil; 57.58mil + 23.08mil; 58.64mil + 23.08mil; 60.41mil + 23.08mil; 62.87mil + 23.08mil; 66.03mil + 23.08mil; 70.05mil + 23.02mil; 71.45mil + 22.84mil; 72.73mil + 22.54mil; 73.91mil + 22.11mil; 74.98mil + 21.59mil; 75.98mil + 20.93mil; 76.86mil + 19.98mil; 77.84mil + 19.01mil; 78.6mil + 17.94mil; 79.2mil + 16.85mil; 79.66mil + 15.69mil; 79.9mil + 14.45mil; 80.0mil + 14.23mil; 75.61mil + 14.87mil; 75.58mil + 15.48mil; 75.43mil + 16.06mil; 75.16mil + 16.61mil; 74.82mil + 17.12mil; 74.37mil + 17.64mil; 73.76mil + 17.91mil; 73.36mil + 18.13mil; 72.91mil + 18.31mil; 72.42mil + 18.43mil; 71.87mil + 18.52mil; 71.33mil + 18.55mil; 70.69mil + 18.55mil; 57.36mil + 18.49mil; 56.66mil + 18.4mil; 56.03mil + 18.22mil; 55.42mil + 17.97mil; 54.84mil + 17.67mil; 54.32mil + 17.28mil; 53.81mil + 16.79mil; 53.38mil + 16.3mil; 53.04mil + 15.75mil; 52.74mil + 15.18mil; 52.56mil + 14.57mil; 52.44mil + 13.9mil; 52.38mil + 4.47mil; 52.38mil + 4.47mil; 75.61mil + 14.23mil; 75.61mil + 14.45mil; 80.0mil + 4.47mil; 80.0mil + 4.47mil; 91.1mil + 4.38mil; 91.92mil + 4.2mil; 92.62mil + 3.86mil; 93.14mil + 3.4mil; 93.53mil + 2.83mil; 93.77mil + 2.1mil; 93.87mil + 1.46mil; 93.77mil + 0.91mil; 93.53mil + 0.51mil; 93.14mil + 0.21mil; 92.59mil + 0.06mil; 91.86mil + 0.0mil; 90.98mil + 0.0mil; 89.85mil + 0.0mil; 86.5mil + 0.0mil; 80.97mil + 0.0mil; 73.21mil + 0.0mil; 63.2mil + } + } + height = 63.33mil + } + ha:q { + width=23mil; delta=12.0mil; + li:objects { + li:simplepoly.1 { + 23.09mil; 50.64mil + 23.09mil; 91.1mil + 23.03mil; 91.95mil + 22.84mil; 92.68mil + 22.54mil; 93.23mil + 22.14mil; 93.65mil + 21.63mil; 93.9mil + 20.99mil; 93.99mil + 20.26mil; 93.9mil + 19.65mil; 93.68mil + 19.19mil; 93.29mil + 18.86mil; 92.77mil + 18.68mil; 92.07mil + 18.62mil; 91.22mil + 18.62mil; 80.12mil + 8.64mil; 80.12mil + 8.85mil; 75.74mil + 9.09mil; 75.74mil + 9.92mil; 75.74mil + 11.25mil; 75.74mil + 13.14mil; 75.74mil + 15.54mil; 75.74mil + 18.62mil; 75.74mil + 18.62mil; 52.5mil + 9.19mil; 52.5mil + 8.52mil; 52.56mil + 7.91mil; 52.68mil + 7.33mil; 52.86mil + 6.78mil; 53.14mil + 6.27mil; 53.5mil + 5.81mil; 53.93mil + 5.41mil; 54.41mil + 5.08mil; 54.93mil + 4.84mil; 55.51mil + 4.65mil; 56.12mil + 4.56mil; 56.79mil + 4.53mil; 57.49mil + 4.53mil; 70.81mil + 4.53mil; 71.42mil + 4.62mil; 72.0mil + 4.74mil; 72.51mil + 4.93mil; 73.0mil + 5.14mil; 73.46mil + 5.44mil; 73.88mil + 5.9mil; 74.46mil + 6.42mil; 74.92mil + 6.97mil; 75.28mil + 7.54mil; 75.55mil + 8.15mil; 75.71mil + 8.85mil; 75.74mil + 8.64mil; 80.12mil + 7.39mil; 80.03mil + 6.23mil; 79.78mil + 5.14mil; 79.36mil + 4.08mil; 78.75mil + 3.1mil; 77.99mil + 2.16mil; 76.98mil + 1.49mil; 76.13mil + 0.94mil; 75.16mil + 0.52mil; 74.06mil + 0.24mil; 72.88mil + 0.06mil; 71.6mil + 0.0mil; 70.17mil + 0.0mil; 57.33mil + 0.06mil; 56.15mil + 0.24mil; 55.02mil + 0.58mil; 53.96mil + 1.06mil; 52.92mil + 1.64mil; 51.98mil + 2.43mil; 51.07mil + 3.38mil; 50.19mil + 4.35mil; 49.46mil + 5.38mil; 48.88mil + 6.45mil; 48.48mil + 7.54mil; 48.21mil + 8.73mil; 48.12mil + 20.5mil; 48.12mil + 21.26mil; 48.21mil + 21.93mil; 48.42mil + 22.42mil; 48.76mil + 22.78mil; 49.24mil + 23.0mil; 49.88mil + } + } + height = 63.33mil + } + ha:r { + width=18mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 50.22mil + 0.06mil; 49.49mil + 0.27mil; 48.85mil + 0.64mil; 48.36mil + 1.12mil; 48.03mil + 1.76mil; 47.81mil + 2.58mil; 47.72mil + 2.92mil; 47.72mil + 4.01mil; 47.72mil + 5.84mil; 47.72mil + 8.39mil; 47.72mil + 11.65mil; 47.72mil + 15.82mil; 47.72mil + 16.58mil; 47.78mil + 17.22mil; 47.96mil + 17.7mil; 48.27mil + 18.07mil; 48.66mil + 18.28mil; 49.18mil + 18.37mil; 49.82mil + 18.37mil; 49.97mil + 18.37mil; 50.34mil + 18.37mil; 50.95mil + 18.37mil; 51.8mil + 18.37mil; 52.89mil + 18.37mil; 54.29mil + 18.31mil; 55.08mil + 18.13mil; 55.69mil + 17.85mil; 56.21mil + 17.46mil; 56.54mil + 16.97mil; 56.76mil + 16.36mil; 56.82mil + 15.6mil; 56.76mil + 15.0mil; 56.57mil + 14.54mil; 56.24mil + 14.2mil; 55.78mil + 13.99mil; 55.2mil + 13.93mil; 54.44mil + 13.93mil; 54.38mil + 13.93mil; 54.2mil + 13.93mil; 53.9mil + 13.93mil; 53.47mil + 13.93mil; 52.92mil + 13.93mil; 52.19mil + 4.5mil; 52.19mil + 4.5mil; 77.5mil + 4.41mil; 78.26mil + 4.23mil; 78.84mil + 3.89mil; 79.33mil + 3.47mil; 79.66mil + 2.89mil; 79.84mil + 2.16mil; 79.9mil + 1.49mil; 79.84mil + 0.94mil; 79.63mil + 0.52mil; 79.3mil + 0.24mil; 78.81mil + 0.06mil; 78.2mil + 0.0mil; 77.41mil + 0.0mil; 76.68mil + 0.0mil; 74.43mil + 0.0mil; 70.69mil + 0.0mil; 65.49mil + 0.0mil; 58.76mil + } + } + height = 63.33mil + } + ha:s { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 19.1mil; 50.0mil + 19.53mil; 50.28mil + 19.89mil; 50.58mil + 20.16mil; 50.92mil + 20.38mil; 51.25mil + 20.5mil; 51.62mil + 20.56mil; 51.98mil + 20.5mil; 52.71mil + 20.32mil; 53.32mil + 20.01mil; 53.77mil + 19.62mil; 54.11mil + 19.1mil; 54.29mil + 18.46mil; 54.35mil + 18.25mil; 54.35mil + 18.0mil; 54.32mil + 17.73mil; 54.26mil + 17.43mil; 54.17mil + 17.09mil; 54.05mil + 16.73mil; 53.9mil + 15.21mil; 53.38mil + 13.78mil; 52.92mil + 12.41mil; 52.56mil + 11.13mil; 52.31mil + 9.91mil; 52.16mil + 8.73mil; 52.1mil + 7.42mil; 52.22mil + 6.35mil; 52.53mil + 5.5mil; 53.04mil + 4.92mil; 53.77mil + 4.56mil; 54.69mil + 4.44mil; 55.84mil + 4.5mil; 56.54mil + 4.68mil; 57.18mil + 4.99mil; 57.73mil + 5.41mil; 58.25mil + 5.99mil; 58.67mil + 6.72mil; 59.07mil + 17.94mil; 64.33mil + 19.43mil; 65.18mil + 20.68mil; 66.15mil + 21.65mil; 67.31mil + 22.35mil; 68.59mil + 22.78mil; 70.05mil + 22.93mil; 71.69mil + 22.81mil; 73.0mil + 22.51mil; 74.25mil + 22.02mil; 75.4mil + 21.32mil; 76.5mil + 20.44mil; 77.53mil + 19.31mil; 78.5mil + 18.67mil; 78.93mil + 18.0mil; 79.26mil + 17.27mil; 79.54mil + 16.48mil; 79.72mil + 15.66mil; 79.84mil + 14.75mil; 79.87mil + 12.83mil; 79.81mil + 10.83mil; 79.63mil + 8.76mil; 79.33mil + 6.6mil; 78.87mil + 4.38mil; 78.29mil + 1.97mil; 77.56mil + 1.37mil; 77.35mil + 0.88mil; 77.07mil + 0.48mil; 76.74mil + 0.21mil; 76.34mil + 0.03mil; 75.92mil + 0.0mil; 75.43mil + 0.03mil; 74.76mil + 0.21mil; 74.22mil + 0.48mil; 73.76mil + 0.88mil; 73.46mil + 1.37mil; 73.27mil + 2.0mil; 73.18mil + 2.37mil; 73.21mil + 2.8mil; 73.24mil + 3.19mil; 73.3mil + 3.59mil; 73.42mil + 4.01mil; 73.52mil + 4.44mil; 73.67mil + 5.96mil; 74.22mil + 7.51mil; 74.67mil + 9.09mil; 75.01mil + 10.7mil; 75.25mil + 12.35mil; 75.4mil + 14.11mil; 75.43mil + 14.66mil; 75.43mil + 15.21mil; 75.37mil + 15.66mil; 75.31mil + 16.09mil; 75.19mil + 16.48mil; 75.04mil + 16.85mil; 74.82mil + 17.33mil; 74.46mil + 17.73mil; 74.03mil + 18.03mil; 73.55mil + 18.25mil; 73.0mil + 18.4mil; 72.36mil + 18.46mil; 71.66mil + 18.37mil; 71.02mil + 18.13mil; 70.38mil + 17.76mil; 69.81mil + 17.21mil; 69.26mil + 16.51mil; 68.74mil + 15.63mil; 68.25mil + 4.86mil; 63.11mil + 3.37mil; 62.29mil + 2.16mil; 61.26mil + 1.21mil; 60.07mil + 0.54mil; 58.73mil + 0.12mil; 57.24mil + 0.0mil; 55.48mil + 0.03mil; 54.5mil + 0.21mil; 53.53mil + 0.51mil; 52.62mil + 0.94mil; 51.77mil + 1.46mil; 50.95mil + 2.16mil; 50.12mil + 2.95mil; 49.39mil + 3.83mil; 48.79mil + 4.77mil; 48.3mil + 5.81mil; 47.96mil + 6.9mil; 47.75mil + 8.12mil; 47.66mil + 10.22mil; 47.75mil + 12.22mil; 47.93mil + 14.11mil; 48.27mil + 15.87mil; 48.7mil + 17.52mil; 49.27mil + } + } + height = 63.33mil + } + ha:t { + width=18mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 4.56mil; 36.35mil + 4.62mil; 35.65mil + 4.81mil; 35.07mil + 5.11mil; 34.64mil + 5.54mil; 34.31mil + 6.11mil; 34.12mil + 6.84mil; 34.03mil + 7.45mil; 34.12mil + 8.0mil; 34.31mil + 8.4mil; 34.64mil + 8.7mil; 35.13mil + 8.85mil; 35.71mil + 8.94mil; 36.47mil + 8.94mil; 36.8mil + 8.94mil; 37.74mil + 8.94mil; 39.33mil + 8.94mil; 41.52mil + 8.94mil; 44.35mil + 8.94mil; 47.93mil + 9.13mil; 47.93mil + 9.7mil; 47.93mil + 10.65mil; 47.93mil + 11.98mil; 47.93mil + 13.72mil; 47.93mil + 15.91mil; 47.93mil + 16.61mil; 48.03mil + 17.22mil; 48.21mil + 17.67mil; 48.54mil + 18.01mil; 49.0mil + 18.19mil; 49.58mil + 18.28mil; 50.31mil + 18.19mil; 50.92mil + 18.01mil; 51.4mil + 17.67mil; 51.77mil + 17.19mil; 52.04mil + 16.61mil; 52.22mil + 15.85mil; 52.25mil + 8.94mil; 52.25mil + 8.94mil; 77.65mil + 8.88mil; 78.38mil + 8.7mil; 78.96mil + 8.4mil; 79.42mil + 7.97mil; 79.75mil + 7.42mil; 79.93mil + 6.75mil; 80.0mil + 6.08mil; 79.93mil + 5.54mil; 79.72mil + 5.11mil; 79.39mil + 4.81mil; 78.9mil + 4.62mil; 78.26mil + 4.56mil; 77.44mil + 4.56mil; 52.25mil + 2.25mil; 52.25mil + 1.55mil; 52.22mil + 1.0mil; 52.04mil + 0.55mil; 51.74mil + 0.24mil; 51.34mil + 0.06mil; 50.79mil + 0.0mil; 50.12mil + 0.06mil; 49.49mil + 0.24mil; 48.94mil + 0.55mil; 48.51mil + 0.97mil; 48.21mil + 1.52mil; 48.03mil + 2.22mil; 47.93mil + 4.56mil; 47.93mil + } + } + height = 63.33mil + } + ha:u { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 0.0mil; 50.46mil + 0.03mil; 49.67mil + 0.21mil; 49.0mil + 0.52mil; 48.48mil + 0.94mil; 48.12mil + 1.49mil; 47.9mil + 2.19mil; 47.81mil + 2.83mil; 47.9mil + 3.38mil; 48.12mil + 3.8mil; 48.51mil + 4.08mil; 49.03mil + 4.26mil; 49.7mil + 4.35mil; 50.52mil + 4.35mil; 51.1mil + 4.35mil; 52.74mil + 4.35mil; 55.54mil + 4.35mil; 59.4mil + 4.35mil; 64.42mil + 4.35mil; 70.72mil + 4.38mil; 71.42mil + 4.47mil; 72.03mil + 4.65mil; 72.63mil + 4.93mil; 73.18mil + 5.26mil; 73.67mil + 5.69mil; 74.12mil + 6.14mil; 74.55mil + 6.66mil; 74.92mil + 7.18mil; 75.19mil + 7.76mil; 75.37mil + 8.3mil; 75.49mil + 8.94mil; 75.52mil + 18.46mil; 75.52mil + 18.46mil; 50.34mil + 18.52mil; 49.61mil + 18.71mil; 49.03mil + 19.01mil; 48.54mil + 19.44mil; 48.21mil + 20.01mil; 48.03mil + 20.74mil; 47.93mil + 21.38mil; 48.03mil + 21.9mil; 48.21mil + 22.33mil; 48.57mil + 22.63mil; 49.03mil + 22.78mil; 49.64mil + 22.87mil; 50.4mil + 22.87mil; 77.5mil + 22.78mil; 78.26mil + 22.6mil; 78.9mil + 22.3mil; 79.39mil + 21.87mil; 79.72mil + 21.29mil; 79.93mil + 20.59mil; 80.0mil + 8.64mil; 80.0mil + 7.45mil; 79.93mil + 6.3mil; 79.69mil + 5.23mil; 79.3mil + 4.2mil; 78.75mil + 3.25mil; 78.05mil + 2.31mil; 77.14mil + 1.58mil; 76.28mil + 1.0mil; 75.37mil + 0.58mil; 74.37mil + 0.24mil; 73.27mil + 0.06mil; 72.12mil + 0.0mil; 70.81mil + 0.0mil; 70.26mil + 0.0mil; 68.59mil + 0.0mil; 65.79mil + 0.0mil; 61.87mil + 0.0mil; 56.85mil + } + } + height = 63.33mil + } + ha:v { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 18.52mil; 49.55mil + 18.7mil; 49.06mil + 18.98mil; 48.66mil + 19.31mil; 48.36mil + 19.74mil; 48.15mil + 20.19mil; 48.0mil + 20.77mil; 47.93mil + 21.41mil; 48.0mil + 21.96mil; 48.15mil + 22.38mil; 48.42mil + 22.66mil; 48.79mil + 22.84mil; 49.24mil + 22.93mil; 49.82mil + 22.9mil; 50.03mil + 22.9mil; 50.22mil + 22.87mil; 50.43mil + 22.81mil; 50.64mil + 22.78mil; 50.82mil + 22.72mil; 51.04mil + 22.45mil; 51.8mil + 21.72mil; 54.02mil + 20.47mil; 57.7mil + 18.73mil; 62.87mil + 16.51mil; 69.53mil + 13.72mil; 77.93mil + 13.44mil; 78.57mil + 13.17mil; 79.08mil + 12.8mil; 79.48mil + 12.44mil; 79.78mil + 11.98mil; 79.96mil + 11.49mil; 80.0mil + 10.98mil; 79.96mil + 10.52mil; 79.81mil + 10.13mil; 79.57mil + 9.76mil; 79.2mil + 9.49mil; 78.75mil + 9.24mil; 78.17mil + 8.97mil; 77.44mil + 8.24mil; 75.22mil + 7.02mil; 71.54mil + 5.29mil; 66.37mil + 3.07mil; 59.71mil + 0.27mil; 51.28mil + 0.18mil; 51.04mil + 0.12mil; 50.79mil + 0.06mil; 50.55mil + 0.03mil; 50.37mil + 0.0mil; 50.16mil + 0.0mil; 49.97mil + 0.06mil; 49.36mil + 0.27mil; 48.85mil + 0.64mil; 48.45mil + 1.15mil; 48.18mil + 1.79mil; 48.0mil + 2.64mil; 47.93mil + 3.01mil; 48.0mil + 3.37mil; 48.18mil + 3.71mil; 48.45mil + 3.98mil; 48.82mil + 4.26mil; 49.3mil + 4.5mil; 49.91mil + 4.68mil; 50.49mil + 5.26mil; 52.22mil + 6.2mil; 55.05mil + 7.54mil; 59.07mil + 9.27mil; 64.21mil + 11.46mil; 70.69mil + 11.65mil; 70.11mil + 12.22mil; 68.38mil + 13.2mil; 65.49mil + 14.54mil; 61.41mil + 16.3mil; 56.18mil + } + } + height = 63.33mil + } + ha:w { + width=32mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 27.74mil; 50.0mil + 27.95mil; 49.36mil + 28.22mil; 48.82mil + 28.56mil; 48.39mil + 28.95mil; 48.09mil + 29.38mil; 47.9mil + 29.93mil; 47.81mil + 30.54mil; 47.87mil + 31.08mil; 48.06mil + 31.48mil; 48.33mil + 31.78mil; 48.73mil + 31.94mil; 49.21mil + 32.03mil; 49.82mil + 32.0mil; 50.03mil + 32.0mil; 50.22mil + 31.97mil; 50.4mil + 31.94mil; 50.58mil + 31.91mil; 50.79mil + 31.87mil; 50.98mil + 31.69mil; 51.74mil + 31.14mil; 53.96mil + 30.23mil; 57.64mil + 28.99mil; 62.81mil + 27.37mil; 69.44mil + 25.33mil; 77.84mil + 25.12mil; 78.5mil + 24.85mil; 79.05mil + 24.51mil; 79.48mil + 24.09mil; 79.75mil + 23.63mil; 79.93mil + 23.08mil; 80.0mil + 22.54mil; 79.96mil + 22.05mil; 79.78mil + 21.59mil; 79.51mil + 21.23mil; 79.11mil + 20.89mil; 78.63mil + 20.62mil; 77.99mil + 20.47mil; 77.65mil + 20.1mil; 76.65mil + 19.46mil; 74.92mil + 18.58mil; 72.54mil + 17.43mil; 69.47mil + 16.0mil; 65.55mil + 11.4mil; 78.02mil + 11.13mil; 78.63mil + 10.83mil; 79.11mil + 10.49mil; 79.51mil + 10.13mil; 79.78mil + 9.7mil; 79.96mil + 9.21mil; 80.0mil + 8.64mil; 79.96mil + 8.15mil; 79.81mil + 7.72mil; 79.54mil + 7.39mil; 79.17mil + 7.11mil; 78.72mil + 6.93mil; 78.11mil + 6.72mil; 77.41mil + 6.17mil; 75.25mil + 5.26mil; 71.63mil + 3.98mil; 66.58mil + 2.34mil; 60.1mil + 0.27mil; 51.86mil + 0.18mil; 51.52mil + 0.12mil; 51.19mil + 0.06mil; 50.89mil + 0.03mil; 50.58mil + 0.0mil; 50.31mil + 0.0mil; 50.03mil + 0.06mil; 49.43mil + 0.24mil; 48.88mil + 0.57mil; 48.48mil + 1.06mil; 48.18mil + 1.64mil; 48.03mil + 2.43mil; 47.93mil + 2.86mil; 48.0mil + 3.28mil; 48.15mil + 3.62mil; 48.36mil + 3.89mil; 48.7mil + 4.13mil; 49.12mil + 4.32mil; 49.64mil + 4.44mil; 50.22mil + 4.86mil; 51.92mil + 5.59mil; 54.72mil + 6.6mil; 58.67mil + 7.91mil; 63.72mil + 9.55mil; 70.14mil + 9.64mil; 69.84mil + 10.0mil; 68.92mil + 10.61mil; 67.34mil + 11.46mil; 65.18mil + 12.53mil; 62.35mil + 13.93mil; 58.79mil + 14.14mil; 58.31mil + 14.41mil; 57.88mil + 14.75mil; 57.55mil + 15.14mil; 57.33mil + 15.57mil; 57.18mil + 16.06mil; 57.12mil + 16.54mil; 57.18mil + 17.0mil; 57.33mil + 17.43mil; 57.61mil + 17.79mil; 57.94mil + 18.1mil; 58.4mil + 18.37mil; 58.98mil + 18.46mil; 59.28mil + 18.8mil; 60.19mil + 19.37mil; 61.71mil + 20.16mil; 63.84mil + 21.17mil; 66.58mil + 22.48mil; 70.02mil + } + } + height = 63.33mil + } + ha:x { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 8.91mil; 63.96mil + 8.67mil; 63.63mil + 7.97mil; 62.6mil + 6.81mil; 60.86mil + 5.2mil; 58.46mil + 3.1mil; 55.36mil + 0.48mil; 51.4mil + 0.33mil; 51.19mil + 0.21mil; 50.95mil + 0.12mil; 50.7mil + 0.03mil; 50.49mil + 0.0mil; 50.28mil + 0.0mil; 50.03mil + 0.06mil; 49.39mil + 0.24mil; 48.85mil + 0.57mil; 48.42mil + 1.03mil; 48.12mil + 1.61mil; 47.93mil + 2.37mil; 47.84mil + 2.67mil; 47.87mil + 3.01mil; 47.96mil + 3.31mil; 48.12mil + 3.59mil; 48.33mil + 3.86mil; 48.6mil + 4.13mil; 48.94mil + 11.46mil; 59.95mil + 18.83mil; 48.94mil + 19.07mil; 48.63mil + 19.34mil; 48.39mil + 19.62mil; 48.21mil + 19.95mil; 48.06mil + 20.32mil; 47.96mil + 20.71mil; 47.93mil + 21.32mil; 48.0mil + 21.84mil; 48.15mil + 22.23mil; 48.42mil + 22.51mil; 48.79mil + 22.69mil; 49.27mil + 22.75mil; 49.85mil + 22.72mil; 50.22mil + 22.69mil; 50.55mil + 22.63mil; 50.85mil + 22.54mil; 51.16mil + 22.41mil; 51.43mil + 22.29mil; 51.68mil + 22.05mil; 52.04mil + 21.38mil; 53.04mil + 20.22mil; 54.72mil + 18.64mil; 57.09mil + 16.6mil; 60.1mil + 14.05mil; 63.93mil + 14.26mil; 64.27mil + 14.93mil; 65.27mil + 16.03mil; 66.92mil + 17.58mil; 69.23mil + 19.56mil; 72.18mil + 22.08mil; 75.92mil + 22.29mil; 76.31mil + 22.48mil; 76.68mil + 22.63mil; 76.98mil + 22.75mil; 77.29mil + 22.81mil; 77.56mil + 22.84mil; 77.8mil + 22.78mil; 78.47mil + 22.6mil; 79.02mil + 22.29mil; 79.45mil + 21.9mil; 79.75mil + 21.38mil; 79.93mil + 20.74mil; 80.0mil + 20.32mil; 80.0mil + 19.95mil; 79.9mil + 19.59mil; 79.75mil + 19.28mil; 79.54mil + 19.01mil; 79.26mil + 18.76mil; 78.93mil + 18.55mil; 78.66mil + 17.94mil; 77.74mil + 16.97mil; 76.22mil + 15.57mil; 74.09mil + 13.78mil; 71.36mil + 11.53mil; 67.86mil + 11.31mil; 68.16mil + 10.7mil; 69.07mil + 9.7mil; 70.6mil + 8.3mil; 72.69mil + 6.51mil; 75.4mil + 4.22mil; 78.81mil + 3.95mil; 79.17mil + 3.65mil; 79.48mil + 3.34mil; 79.72mil + 3.01mil; 79.87mil + 2.67mil; 79.96mil + 2.31mil; 80.0mil + 1.58mil; 79.96mil + 1.0mil; 79.78mil + 0.57mil; 79.51mil + 0.24mil; 79.11mil + 0.06mil; 78.6mil + 0.0mil; 77.93mil + 0.0mil; 77.68mil + 0.03mil; 77.38mil + 0.12mil; 77.11mil + 0.21mil; 76.83mil + 0.36mil; 76.56mil + 0.54mil; 76.25mil + 0.76mil; 75.92mil + 1.46mil; 74.92mil + 2.58mil; 73.24mil + 4.19mil; 70.87mil + 6.26mil; 67.83mil + } + } + height = 63.33mil + } + ha:y { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 22.35mil; 52.16mil + 9.09mil; 91.77mil + 8.82mil; 92.38mil + 8.48mil; 92.92mil + 8.06mil; 93.32mil + 7.57mil; 93.62mil + 7.02mil; 93.77mil + 6.38mil; 93.87mil + 6.26mil; 93.87mil + 5.93mil; 93.87mil + 5.41mil; 93.87mil + 4.65mil; 93.87mil + 3.68mil; 93.87mil + 2.46mil; 93.87mil + 1.7mil; 93.8mil + 1.09mil; 93.62mil + 0.61mil; 93.32mil + 0.27mil; 92.89mil + 0.06mil; 92.38mil + 0.0mil; 91.71mil + 0.06mil; 91.01mil + 0.27mil; 90.46mil + 0.61mil; 90.0mil + 1.09mil; 89.7mil + 1.73mil; 89.52mil + 2.55mil; 89.45mil + 5.14mil; 89.45mil + 5.23mil; 89.12mil + 5.53mil; 88.21mil + 6.05mil; 86.66mil + 6.78mil; 84.47mil + 7.69mil; 81.67mil + 8.88mil; 78.14mil + 0.39mil; 52.01mil + 0.27mil; 51.65mil + 0.15mil; 51.31mil + 0.09mil; 50.98mil + 0.03mil; 50.64mil + 0.0mil; 50.34mil + 0.0mil; 50.03mil + 0.06mil; 49.43mil + 0.24mil; 48.88mil + 0.54mil; 48.48mil + 0.97mil; 48.18mil + 1.52mil; 48.03mil + 2.22mil; 47.93mil + 2.7mil; 48.0mil + 3.16mil; 48.18mil + 3.56mil; 48.48mil + 3.89mil; 48.88mil + 4.19mil; 49.39mil + 4.47mil; 50.03mil + 11.28mil; 70.99mil + 18.49mil; 49.79mil + 18.7mil; 49.24mil + 18.98mil; 48.79mil + 19.31mil; 48.42mil + 19.68mil; 48.15mil + 20.1mil; 48.0mil + 20.59mil; 47.93mil + 21.26mil; 48.0mil + 21.81mil; 48.18mil + 22.26mil; 48.48mil + 22.57mil; 48.88mil + 22.75mil; 49.39mil + 22.84mil; 50.03mil + 22.81mil; 50.31mil + 22.78mil; 50.58mil + 22.72mil; 50.92mil + 22.6mil; 51.28mil + 22.51mil; 51.71mil + } + } + height = 63.33mil + } + ha:z { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 6.41mil; 75.31mil + 20.32mil; 75.31mil + 21.02mil; 75.4mil + 21.62mil; 75.61mil + 22.08mil; 75.98mil + 22.41mil; 76.47mil + 22.6mil; 77.11mil + 22.69mil; 77.9mil + 22.6mil; 78.53mil + 22.41mil; 79.08mil + 22.08mil; 79.48mil + 21.62mil; 79.78mil + 21.05mil; 79.93mil + 20.32mil; 80.0mil + 2.76mil; 80.0mil + 1.91mil; 79.93mil + 1.21mil; 79.75mil + 0.7mil; 79.42mil + 0.3mil; 78.93mil + 0.06mil; 78.35mil + 0.0mil; 77.56mil + 0.0mil; 77.29mil + 0.06mil; 76.98mil + 0.15mil; 76.71mil + 0.27mil; 76.41mil + 0.45mil; 76.07mil + 0.67mil; 75.74mil + 16.42mil; 52.13mil + 2.28mil; 52.13mil + 1.58mil; 52.1mil + 1.03mil; 51.92mil + 0.57mil; 51.62mil + 0.27mil; 51.19mil + 0.09mil; 50.67mil + 0.03mil; 49.97mil + 0.09mil; 49.27mil + 0.27mil; 48.7mil + 0.57mil; 48.24mil + 1.03mil; 47.9mil + 1.61mil; 47.72mil + 2.34mil; 47.63mil + 19.71mil; 47.63mil + 20.65mil; 47.72mil + 21.41mil; 47.9mil + 22.02mil; 48.21mil + 22.45mil; 48.63mil + 22.72mil; 49.18mil + 22.81mil; 49.88mil + 22.78mil; 50.16mil + 22.75mil; 50.4mil + 22.69mil; 50.64mil + 22.57mil; 50.89mil + 22.48mil; 51.13mil + 22.32mil; 51.37mil + } + } + height = 63.33mil + } + ha:\{ { + width=13mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 8.64mil; 29.05mil + 8.7mil; 29.05mil + 8.88mil; 29.05mil + 9.21mil; 29.05mil + 9.67mil; 29.05mil + 10.28mil; 29.05mil + 11.04mil; 29.05mil + 11.77mil; 29.11mil + 12.35mil; 29.29mil + 12.83mil; 29.59mil + 13.17mil; 29.99mil + 13.35mil; 30.51mil + 13.44mil; 31.14mil + 13.38mil; 31.78mil + 13.2mil; 32.33mil + 12.89mil; 32.79mil + 12.5mil; 33.12mil + 11.95mil; 33.36mil + 11.31mil; 33.49mil + 10.58mil; 33.67mil + 9.97mil; 33.94mil + 9.52mil; 34.31mil + 9.18mil; 34.76mil + 9.0mil; 35.34mil + 8.94mil; 36.04mil + 8.94mil; 52.19mil + 8.88mil; 52.92mil + 8.73mil; 53.68mil + 8.48mil; 54.41mil + 8.15mil; 55.14mil + 7.69mil; 55.9mil + 7.14mil; 56.66mil + 7.63mil; 57.21mil + 8.06mil; 57.85mil + 8.39mil; 58.52mil + 8.61mil; 59.25mil + 8.76mil; 60.07mil + 8.82mil; 60.95mil + 8.82mil; 61.41mil + 8.82mil; 62.75mil + 8.82mil; 64.94mil + 8.82mil; 68.04mil + 8.82mil; 72.0mil + 8.82mil; 77.01mil + 8.88mil; 77.8mil + 9.06mil; 78.47mil + 9.43mil; 79.02mil + 9.88mil; 79.42mil + 10.49mil; 79.72mil + 11.28mil; 79.87mil + 11.95mil; 80.0mil + 12.5mil; 80.24mil + 12.92mil; 80.57mil + 13.23mil; 80.97mil + 13.41mil; 81.52mil + 13.5mil; 82.15mil + 13.41mil; 82.76mil + 13.2mil; 83.28mil + 12.86mil; 83.68mil + 12.38mil; 83.95mil + 11.74mil; 84.13mil + 10.98mil; 84.19mil + 10.03mil; 84.13mil + 9.15mil; 83.95mil + 8.33mil; 83.65mil + 7.57mil; 83.25mil + 6.84mil; 82.7mil + 6.2mil; 82.06mil + 5.65mil; 81.36mil + 5.23mil; 80.6mil + 4.89mil; 79.81mil + 4.65mil; 78.96mil + 4.5mil; 78.02mil + 4.47mil; 76.95mil + 4.47mil; 76.53mil + 4.47mil; 75.22mil + 4.47mil; 73.06mil + 4.47mil; 70.02mil + 4.47mil; 66.12mil + 4.47mil; 61.17mil + 4.38mil; 60.56mil + 4.19mil; 60.04mil + 3.83mil; 59.62mil + 3.37mil; 59.28mil + 2.76mil; 59.04mil + 2.0mil; 58.85mil + 1.37mil; 58.73mil + 0.88mil; 58.49mil + 0.48mil; 58.19mil + 0.21mil; 57.76mil + 0.03mil; 57.27mil + 0.0mil; 56.63mil + 0.03mil; 56.0mil + 0.21mil; 55.45mil + 0.51mil; 55.02mil + 0.91mil; 54.72mil + 1.43mil; 54.54mil + 2.1mil; 54.44mil + 2.8mil; 54.41mil + 3.4mil; 54.23mil + 3.86mil; 53.93mil + 4.19mil; 53.5mil + 4.38mil; 52.95mil + 4.47mil; 52.25mil + 4.47mil; 35.31mil + 4.5mil; 34.52mil + 4.68mil; 33.76mil + 4.99mil; 33.0mil + 5.38mil; 32.3mil + 5.93mil; 31.6mil + 6.6mil; 30.9mil + 7.27mil; 30.35mil + 7.97mil; 29.9mil + 8.7mil; 29.53mil + 9.46mil; 29.26mil + 10.22mil; 29.11mil + } + } + height = 63.33mil + } + ha:| { + width=4mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 2.13mil; 86.93mil + 1.46mil; 86.84mil + 0.94mil; 86.6mil + 0.51mil; 86.17mil + 0.21mil; 85.59mil + 0.06mil; 84.86mil + 0.0mil; 83.95mil + 0.0mil; 29.68mil + 0.06mil; 28.86mil + 0.24mil; 28.16mil + 0.58mil; 27.62mil + 1.0mil; 27.22mil + 1.58mil; 26.98mil + 2.34mil; 26.89mil + 3.01mil; 26.98mil + 3.59mil; 27.22mil + 4.04mil; 27.59mil + 4.35mil; 28.13mil + 4.53mil; 28.83mil + 4.62mil; 29.71mil + 4.62mil; 84.04mil + 4.53mil; 84.89mil + 4.32mil; 85.62mil + 3.98mil; 86.17mil + 3.5mil; 86.6mil + 2.89mil; 86.84mil + } + } + height = 63.33mil + } + ha:&7D { + width=13mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 2.46mil; 29.05mil + 3.25mil; 29.11mil + 4.01mil; 29.26mil + 4.77mil; 29.53mil + 5.5mil; 29.87mil + 6.2mil; 30.32mil + 6.93mil; 30.9mil + 7.57mil; 31.57mil + 8.09mil; 32.27mil + 8.51mil; 32.97mil + 8.82mil; 33.73mil + 8.97mil; 34.49mil + 9.06mil; 35.31mil + 9.06mil; 52.25mil + 9.12mil; 52.92mil + 9.3mil; 53.47mil + 9.64mil; 53.9mil + 10.1mil; 54.2mil + 10.67mil; 54.38mil + 11.43mil; 54.44mil + 12.04mil; 54.5mil + 12.56mil; 54.69mil + 12.95mil; 54.99mil + 13.26mil; 55.42mil + 13.44mil; 55.96mil + 13.5mil; 56.63mil + 13.44mil; 57.24mil + 13.26mil; 57.76mil + 12.99mil; 58.19mil + 12.59mil; 58.49mil + 12.1mil; 58.73mil + 11.49mil; 58.85mil + 10.73mil; 59.04mil + 10.1mil; 59.28mil + 9.61mil; 59.62mil + 9.27mil; 60.04mil + 9.06mil; 60.56mil + 9.0mil; 61.17mil + 9.0mil; 76.95mil + 8.94mil; 77.99mil + 8.79mil; 78.93mil + 8.57mil; 79.81mil + 8.24mil; 80.57mil + 7.81mil; 81.33mil + 7.3mil; 82.06mil + 6.66mil; 82.7mil + 5.96mil; 83.22mil + 5.2mil; 83.65mil + 4.38mil; 83.95mil + 3.49mil; 84.1mil + 2.55mil; 84.19mil + 1.76mil; 84.13mil + 1.12mil; 83.95mil + 0.64mil; 83.68mil + 0.27mil; 83.28mil + 0.06mil; 82.76mil + 0.0mil; 82.15mil + 0.06mil; 81.52mil + 0.24mil; 81.0mil + 0.54mil; 80.57mil + 0.97mil; 80.24mil + 1.52mil; 80.0mil + 2.22mil; 79.87mil + 2.95mil; 79.72mil + 3.59mil; 79.45mil + 4.07mil; 79.02mil + 4.41mil; 78.5mil + 4.62mil; 77.84mil + 4.71mil; 77.01mil + 4.71mil; 60.95mil + 4.74mil; 60.1mil + 4.86mil; 59.28mil + 5.11mil; 58.55mil + 5.41mil; 57.85mil + 5.84mil; 57.24mil + 6.35mil; 56.66mil + 5.81mil; 55.93mil + 5.35mil; 55.17mil + 4.99mil; 54.44mil + 4.74mil; 53.68mil + 4.59mil; 52.95mil + 4.56mil; 52.19mil + 4.56mil; 36.04mil + 4.47mil; 35.37mil + 4.29mil; 34.76mil + 3.95mil; 34.31mil + 3.49mil; 33.94mil + 2.92mil; 33.67mil + 2.19mil; 33.49mil + 1.52mil; 33.36mil + 1.0mil; 33.12mil + 0.57mil; 32.79mil + 0.27mil; 32.36mil + 0.12mil; 31.81mil + 0.06mil; 31.14mil + 0.12mil; 30.54mil + 0.3mil; 29.99mil + 0.64mil; 29.59mil + 1.09mil; 29.29mil + 1.7mil; 29.14mil + } + } + height = 63.33mil + } + ha:&7E { + width=22mil; delta=12.0mil; + li:objects { + li:simplepoly.0 { + 18.31mil; 54.87mil + 18.64mil; 54.54mil + 19.04mil; 54.23mil + 19.43mil; 53.99mil + 19.86mil; 53.84mil + 20.32mil; 53.74mil + 20.83mil; 53.68mil + 21.44mil; 53.77mil + 21.99mil; 53.96mil + 22.38mil; 54.26mil + 22.69mil; 54.69mil + 22.84mil; 55.27mil + 22.93mil; 55.96mil + 22.87mil; 56.24mil + 22.78mil; 56.51mil + 22.63mil; 56.82mil + 22.41mil; 57.12mil + 22.14mil; 57.46mil + 21.81mil; 57.79mil + 20.92mil; 58.55mil + 20.01mil; 59.16mil + 19.07mil; 59.65mil + 18.07mil; 59.98mil + 17.06mil; 60.19mil + 15.97mil; 60.25mil + 15.05mil; 60.22mil + 14.17mil; 60.07mil + 13.38mil; 59.8mil + 12.59mil; 59.46mil + 11.89mil; 59.01mil + 11.19mil; 58.4mil + 10.25mil; 57.61mil + 9.43mil; 56.94mil + 8.64mil; 56.42mil + 7.94mil; 56.03mil + 7.33mil; 55.81mil + 6.75mil; 55.72mil + 6.41mil; 55.78mil + 6.05mil; 55.87mil + 5.68mil; 56.03mil + 5.29mil; 56.24mil + 4.89mil; 56.51mil + 4.44mil; 56.85mil + 3.98mil; 57.21mil + 3.56mil; 57.49mil + 3.16mil; 57.7mil + 2.8mil; 57.85mil + 2.46mil; 57.94mil + 2.16mil; 57.97mil + 1.49mil; 57.91mil + 0.94mil; 57.7mil + 0.51mil; 57.36mil + 0.24mil; 56.88mil + 0.06mil; 56.27mil + 0.0mil; 55.48mil + 0.0mil; 55.27mil + 0.09mil; 55.02mil + 0.24mil; 54.78mil + 0.42mil; 54.5mil + 0.7mil; 54.23mil + 1.03mil; 53.9mil + 1.97mil; 53.14mil + 2.92mil; 52.5mil + 3.86mil; 52.01mil + 4.83mil; 51.65mil + 5.81mil; 51.43mil + 6.81mil; 51.34mil + 7.78mil; 51.43mil + 8.79mil; 51.65mil + 9.76mil; 52.01mil + 10.73mil; 52.5mil + 11.74mil; 53.17mil + 12.74mil; 53.96mil + 13.41mil; 54.57mil + 14.02mil; 55.02mil + 14.6mil; 55.42mil + 15.08mil; 55.66mil + 15.54mil; 55.84mil + 15.97mil; 55.87mil + 16.42mil; 55.87mil + 16.85mil; 55.78mil + 17.27mil; 55.63mil + 17.64mil; 55.45mil + 17.97mil; 55.2mil + } + } + height = 63.33mil + } + + } + cell_width = 2.87641mm + cell_height = 1.879602mm + } +} Index: tags/2.3.0/pcblib/Makefile =================================================================== --- tags/2.3.0/pcblib/Makefile (nonexistent) +++ tags/2.3.0/pcblib/Makefile (revision 33253) @@ -0,0 +1,36 @@ +# This Makefile is a plain old hand written one; all configuration settings +# are included from ../Makefile.conf which is scconfig generated + +ROOT=.. + +all: + +# NOTE: this rule is _not_ called from linstall +install_: + $(MKDIR) "$(DATADIR)/pcblib" + $(MKDIR) "$(DATADIR)/pcblib/connector" + $(CPC) "`pwd`/connector"/* "$(DATADIR)/pcblib/connector" + $(MKDIR) "$(DATADIR)/pcblib/parametric" + $(CPC) "`pwd`/parametric"/* "$(DATADIR)/pcblib/parametric" + $(MKDIR) "$(DATADIR)/pcblib/smd" + $(CPC) "`pwd`/smd"/* "$(DATADIR)/pcblib/smd" + $(MKDIR) "$(DATADIR)/pcblib/tru-hole" + $(CPC) "`pwd`/tru-hole"/* "$(DATADIR)/pcblib/tru-hole" + +install: + $(MAKE) install_ CPC="$(CP)" + +# hack: pcb's chdir() based approach gets fooled on symlinks because of "cd .." +# returns to the wrong dir - rather symlink the whole dir +linstall: + $(MAKE) uninstall + $(MKDIR) "$(DATADIR)" + $(LN) "`pwd`" "$(DATADIR)/pcblib" + +uninstall: + $(RM) "$(DATADIR)/pcblib" + +clean: + +include $(ROOT)/Makefile.conf + Index: tags/2.3.0/pcblib/README =================================================================== --- tags/2.3.0/pcblib/README (nonexistent) +++ tags/2.3.0/pcblib/README (revision 33253) @@ -0,0 +1,8 @@ +This directory hosts the pcb-rnd's new footprint library. To avoid +confusuin with "newlib", which is in use in mainline, this one is called +pcblib. + +Some footprints are dynamically generated by scripts; they are +called parametric footprints and are in parametric/. Other footprints +are plain old data file footprints (static footpritns) in all the other +directories. Index: tags/2.3.0/pcblib/connector/BNC_LAY.fp =================================================================== --- tags/2.3.0/pcblib/connector/BNC_LAY.fp (nonexistent) +++ tags/2.3.0/pcblib/connector/BNC_LAY.fp (revision 33253) @@ -0,0 +1,498 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = right angle BNC + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 81.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 106.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 106.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.651392mm + rot = 0.000000 + y = 7.493392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 1.651392mm + rot = 0.000000 + y = 4.953392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = m1 + } + proto = 2 + xmirror = 0 + x = 6.731392mm + rot = 0.000000 + y = 2.413392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.22 { + smirror = 0 + ha:attributes { + term = 4 + name = m2 + } + proto = 2 + xmirror = 0 + x = 6.731392mm + rot = 0.000000 + y = 12.573392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.127392mm + x2 = 14.097392mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.10 { + clearance = 0.0 + y2 = 14.859392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 14.097392mm + x2 = 14.097392mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.13 { + clearance = 0.0 + y2 = 14.859392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 14.097392mm + x2 = 0.127392mm + ha:flags { + } + y1 = 14.859392mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.127392mm + x2 = 0.127392mm + ha:flags { + } + y1 = 14.859392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 6.731392mm + y = 7.493392mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.23 { + clearance = 0.0 + y2 = 6.858392mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 4.191392mm + x2 = 4.191392mm + ha:flags { + } + y1 = 6.858392mm + } + ha:line.26 { + clearance = 0.0 + y2 = 7.493392mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.651392mm + x2 = 1.651392mm + ha:flags { + } + y1 = 7.493392mm + } + ha:line.29 { + clearance = 0.0 + y2 = 8.493392mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.651392mm + x2 = 1.651392mm + ha:flags { + } + y1 = 7.493392mm + } + ha:line.32 { + clearance = 0.0 + y2 = 7.493392mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.651392mm + x2 = 2.651392mm + ha:flags { + } + y1 = 7.493392mm + } + } + ha:combining { + } + } + } + } + uid = +z9SkkMpL7AE/DrmKxoAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/connector/DB15F.fp =================================================================== --- tags/2.3.0/pcblib/connector/DB15F.fp (nonexistent) +++ tags/2.3.0/pcblib/connector/DB15F.fp (revision 33253) @@ -0,0 +1,1008 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = DSUB connector, female/male + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 125.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.43 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.026in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.47 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.918in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.51 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.81in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.55 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.702in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.59 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.594in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.63 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.486in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.67 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.378in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.71 { + smirror = 0 + ha:attributes { + term = 8 + name = 8 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.27in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.75 { + smirror = 0 + ha:attributes { + term = 9 + name = 9 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.972in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.79 { + smirror = 0 + ha:attributes { + term = 10 + name = 10 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.864in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.83 { + smirror = 0 + ha:attributes { + term = 11 + name = 11 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.756in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.87 { + smirror = 0 + ha:attributes { + term = 12 + name = 12 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.648in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.91 { + smirror = 0 + ha:attributes { + term = 13 + name = 13 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.54in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.95 { + smirror = 0 + ha:attributes { + term = 14 + name = 14 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 36.3728mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.99 { + smirror = 0 + ha:attributes { + term = 15 + name = 15 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.324in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.103 { + smirror = 0 + ha:attributes { + term = 16 + name = C1 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 1000.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.104 { + smirror = 0 + ha:attributes { + term = 17 + name = C2 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 2.296in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 61.3664mm + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 61.3664mm + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 61.3664mm + } + ha:line.16 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 61.3664mm + } + ha:line.19 { + clearance = 0.0 + y2 = 940.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 940.0mil + } + ha:line.22 { + clearance = 0.0 + y2 = 1.06in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.06in + } + ha:line.25 { + clearance = 0.0 + y2 = 59.8424mm + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 59.8424mm + } + ha:line.28 { + clearance = 0.0 + y2 = 2.236in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 2.236in + } + ha:line.31 { + clearance = 0.0 + y2 = 1.11in + thickness = 20.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.34 { + clearance = 0.0 + y2 = 55.5244mm + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.37 { + clearance = 0.0 + y2 = 55.5244mm + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 55.5244mm + } + ha:line.40 { + clearance = 0.0 + y2 = 1.11in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 55.5244mm + } + ha:line.44 { + clearance = 0.0 + y2 = 2.026in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.026in + } + ha:line.48 { + clearance = 0.0 + y2 = 1.918in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.918in + } + ha:line.52 { + clearance = 0.0 + y2 = 1.81in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.81in + } + ha:line.56 { + clearance = 0.0 + y2 = 1.702in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.702in + } + ha:line.60 { + clearance = 0.0 + y2 = 1.594in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.594in + } + ha:line.64 { + clearance = 0.0 + y2 = 1.486in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.486in + } + ha:line.68 { + clearance = 0.0 + y2 = 1.378in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.378in + } + ha:line.72 { + clearance = 0.0 + y2 = 1.27in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.27in + } + ha:line.76 { + clearance = 0.0 + y2 = 1.972in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.972in + } + ha:line.80 { + clearance = 0.0 + y2 = 1.864in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.864in + } + ha:line.84 { + clearance = 0.0 + y2 = 1.756in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.756in + } + ha:line.88 { + clearance = 0.0 + y2 = 1.648in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.648in + } + ha:line.92 { + clearance = 0.0 + y2 = 1.54in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.54in + } + ha:line.96 { + clearance = 0.0 + y2 = 36.3728mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 36.3728mm + } + ha:line.100 { + clearance = 0.0 + y2 = 1.324in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.324in + } + ha:text.6 { + scale = 150 + ha:attributes { + } + x = 1000.0mil + y = 2.026in + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.105 { + clearance = 0.0 + y2 = 1.648in + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 25.48367mm + x2 = 25.48367mm + ha:flags { + } + y1 = 1.648in + } + ha:line.108 { + clearance = 0.0 + y2 = 2.026in + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.056in + x2 = 1.056in + ha:flags { + } + y1 = 2.026in + } + ha:line.111 { + clearance = 0.0 + y2 = 2.026in + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.056in + x2 = 25.8224mm + ha:flags { + } + y1 = 2.026in + } + ha:line.114 { + clearance = 0.0 + y2 = 50.4604mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.056in + x2 = 1.056in + ha:flags { + } + y1 = 2.026in + } + } + ha:combining { + } + } + } + } + uid = mxLwtmLpMYT5EZjypDMAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/connector/DB15M.fp =================================================================== --- tags/2.3.0/pcblib/connector/DB15M.fp (nonexistent) +++ tags/2.3.0/pcblib/connector/DB15M.fp (revision 33253) @@ -0,0 +1,1008 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = DSUB connector, female/male + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 125.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.43 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.27in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.47 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.378in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.51 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.486in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.55 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.594in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.59 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.702in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.63 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.81in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.67 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.918in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.71 { + smirror = 0 + ha:attributes { + term = 8 + name = 8 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.026in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.75 { + smirror = 0 + ha:attributes { + term = 9 + name = 9 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.324in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.79 { + smirror = 0 + ha:attributes { + term = 10 + name = 10 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 36.3728mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.83 { + smirror = 0 + ha:attributes { + term = 11 + name = 11 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.54in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.87 { + smirror = 0 + ha:attributes { + term = 12 + name = 12 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.648in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.91 { + smirror = 0 + ha:attributes { + term = 13 + name = 13 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.756in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.95 { + smirror = 0 + ha:attributes { + term = 14 + name = 14 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.864in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.99 { + smirror = 0 + ha:attributes { + term = 15 + name = 15 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.972in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.103 { + smirror = 0 + ha:attributes { + term = 16 + name = C1 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 1000.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.104 { + smirror = 0 + ha:attributes { + term = 17 + name = C2 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 2.296in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 61.3664mm + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 61.3664mm + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 61.3664mm + } + ha:line.16 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 61.3664mm + } + ha:line.19 { + clearance = 0.0 + y2 = 940.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 940.0mil + } + ha:line.22 { + clearance = 0.0 + y2 = 1.06in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.06in + } + ha:line.25 { + clearance = 0.0 + y2 = 59.8424mm + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 59.8424mm + } + ha:line.28 { + clearance = 0.0 + y2 = 2.236in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 2.236in + } + ha:line.31 { + clearance = 0.0 + y2 = 1.11in + thickness = 20.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.34 { + clearance = 0.0 + y2 = 55.5244mm + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.37 { + clearance = 0.0 + y2 = 55.5244mm + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 55.5244mm + } + ha:line.40 { + clearance = 0.0 + y2 = 1.11in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 55.5244mm + } + ha:line.44 { + clearance = 0.0 + y2 = 1.27in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.27in + } + ha:line.48 { + clearance = 0.0 + y2 = 1.378in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.378in + } + ha:line.52 { + clearance = 0.0 + y2 = 1.486in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.486in + } + ha:line.56 { + clearance = 0.0 + y2 = 1.594in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.594in + } + ha:line.60 { + clearance = 0.0 + y2 = 1.702in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.702in + } + ha:line.64 { + clearance = 0.0 + y2 = 1.81in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.81in + } + ha:line.68 { + clearance = 0.0 + y2 = 1.918in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.918in + } + ha:line.72 { + clearance = 0.0 + y2 = 2.026in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.026in + } + ha:line.76 { + clearance = 0.0 + y2 = 1.324in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.324in + } + ha:line.80 { + clearance = 0.0 + y2 = 36.3728mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 36.3728mm + } + ha:line.84 { + clearance = 0.0 + y2 = 1.54in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.54in + } + ha:line.88 { + clearance = 0.0 + y2 = 1.648in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.648in + } + ha:line.92 { + clearance = 0.0 + y2 = 1.756in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.756in + } + ha:line.96 { + clearance = 0.0 + y2 = 1.864in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.864in + } + ha:line.100 { + clearance = 0.0 + y2 = 1.972in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.972in + } + ha:text.6 { + scale = 150 + ha:attributes { + } + x = 1000.0mil + y = 2.026in + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.105 { + clearance = 0.0 + y2 = 1.648in + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 25.48367mm + x2 = 25.48367mm + ha:flags { + } + y1 = 1.648in + } + ha:line.108 { + clearance = 0.0 + y2 = 1.27in + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 26.67mm + x2 = 26.67mm + ha:flags { + } + y1 = 1.27in + } + ha:line.111 { + clearance = 0.0 + y2 = 1.27in + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 26.67mm + x2 = 27.67mm + ha:flags { + } + y1 = 1.27in + } + ha:line.114 { + clearance = 0.0 + y2 = 33.258mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 26.67mm + x2 = 26.67mm + ha:flags { + } + y1 = 1.27in + } + } + ha:combining { + } + } + } + } + uid = OJxv7uCiNEnjpBVb3PgAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/connector/DB25F.fp =================================================================== --- tags/2.3.0/pcblib/connector/DB25F.fp (nonexistent) +++ tags/2.3.0/pcblib/connector/DB25F.fp (revision 33253) @@ -0,0 +1,1308 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = DSUB connector, female/male + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 125.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.43 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 65.1764mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.47 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.458in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.51 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.35in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.55 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.242in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.59 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 54.2036mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.63 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.026in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.67 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.918in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.71 { + smirror = 0 + ha:attributes { + term = 8 + name = 8 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.81in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.75 { + smirror = 0 + ha:attributes { + term = 9 + name = 9 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.702in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.79 { + smirror = 0 + ha:attributes { + term = 10 + name = 10 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.594in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.83 { + smirror = 0 + ha:attributes { + term = 11 + name = 11 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.486in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.87 { + smirror = 0 + ha:attributes { + term = 12 + name = 12 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.378in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.91 { + smirror = 0 + ha:attributes { + term = 13 + name = 13 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.27in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.95 { + smirror = 0 + ha:attributes { + term = 14 + name = 14 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.512in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.99 { + smirror = 0 + ha:attributes { + term = 15 + name = 15 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 61.0616mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.103 { + smirror = 0 + ha:attributes { + term = 16 + name = 16 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.296in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.107 { + smirror = 0 + ha:attributes { + term = 17 + name = 17 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.188in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.111 { + smirror = 0 + ha:attributes { + term = 18 + name = 18 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.08in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.115 { + smirror = 0 + ha:attributes { + term = 19 + name = 19 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.972in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.119 { + smirror = 0 + ha:attributes { + term = 20 + name = 20 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.864in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.123 { + smirror = 0 + ha:attributes { + term = 21 + name = 21 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.756in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.127 { + smirror = 0 + ha:attributes { + term = 22 + name = 22 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.648in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.131 { + smirror = 0 + ha:attributes { + term = 23 + name = 23 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.54in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.135 { + smirror = 0 + ha:attributes { + term = 24 + name = 24 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 36.3728mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.139 { + smirror = 0 + ha:attributes { + term = 25 + name = 25 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.324in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.143 { + smirror = 0 + ha:attributes { + term = 26 + name = C1 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 1000.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.144 { + smirror = 0 + ha:attributes { + term = 27 + name = C2 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 72.0344mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 2.956in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 2.956in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 2.956in + } + ha:line.16 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 2.956in + } + ha:line.19 { + clearance = 0.0 + y2 = 940.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 940.0mil + } + ha:line.22 { + clearance = 0.0 + y2 = 1.06in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.06in + } + ha:line.25 { + clearance = 0.0 + y2 = 73.5584mm + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 73.5584mm + } + ha:line.28 { + clearance = 0.0 + y2 = 2.776in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 2.776in + } + ha:line.31 { + clearance = 0.0 + y2 = 1.11in + thickness = 20.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.34 { + clearance = 0.0 + y2 = 2.726in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.37 { + clearance = 0.0 + y2 = 2.726in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 2.726in + } + ha:line.40 { + clearance = 0.0 + y2 = 1.11in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 2.726in + } + ha:line.44 { + clearance = 0.0 + y2 = 65.1764mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 65.1764mm + } + ha:line.48 { + clearance = 0.0 + y2 = 2.458in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.458in + } + ha:line.52 { + clearance = 0.0 + y2 = 2.35in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.35in + } + ha:line.56 { + clearance = 0.0 + y2 = 2.242in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.242in + } + ha:line.60 { + clearance = 0.0 + y2 = 54.2036mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 54.2036mm + } + ha:line.64 { + clearance = 0.0 + y2 = 2.026in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.026in + } + ha:line.68 { + clearance = 0.0 + y2 = 1.918in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.918in + } + ha:line.72 { + clearance = 0.0 + y2 = 1.81in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.81in + } + ha:line.76 { + clearance = 0.0 + y2 = 1.702in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.702in + } + ha:line.80 { + clearance = 0.0 + y2 = 1.594in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.594in + } + ha:line.84 { + clearance = 0.0 + y2 = 1.486in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.486in + } + ha:line.88 { + clearance = 0.0 + y2 = 1.378in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.378in + } + ha:line.92 { + clearance = 0.0 + y2 = 1.27in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.27in + } + ha:line.96 { + clearance = 0.0 + y2 = 2.512in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.512in + } + ha:line.100 { + clearance = 0.0 + y2 = 61.0616mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 61.0616mm + } + ha:line.104 { + clearance = 0.0 + y2 = 2.296in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.296in + } + ha:line.108 { + clearance = 0.0 + y2 = 2.188in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.188in + } + ha:line.112 { + clearance = 0.0 + y2 = 2.08in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.08in + } + ha:line.116 { + clearance = 0.0 + y2 = 1.972in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.972in + } + ha:line.120 { + clearance = 0.0 + y2 = 1.864in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.864in + } + ha:line.124 { + clearance = 0.0 + y2 = 1.756in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.756in + } + ha:line.128 { + clearance = 0.0 + y2 = 1.648in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.648in + } + ha:line.132 { + clearance = 0.0 + y2 = 1.54in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.54in + } + ha:line.136 { + clearance = 0.0 + y2 = 36.3728mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 36.3728mm + } + ha:line.140 { + clearance = 0.0 + y2 = 1.324in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.324in + } + ha:text.6 { + scale = 150 + ha:attributes { + } + x = 1000.0mil + y = 65.1764mm + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.145 { + clearance = 0.0 + y2 = 1.918in + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 25.452681mm + x2 = 25.452681mm + ha:flags { + } + y1 = 1.918in + } + ha:line.148 { + clearance = 0.0 + y2 = 65.1764mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.056in + x2 = 1.056in + ha:flags { + } + y1 = 65.1764mm + } + ha:line.151 { + clearance = 0.0 + y2 = 65.1764mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.056in + x2 = 25.8224mm + ha:flags { + } + y1 = 65.1764mm + } + ha:line.154 { + clearance = 0.0 + y2 = 64.1764mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.056in + x2 = 1.056in + ha:flags { + } + y1 = 65.1764mm + } + } + ha:combining { + } + } + } + } + uid = XgJ98fsHTDdEjKfSkLEAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/connector/DB25M.fp =================================================================== --- tags/2.3.0/pcblib/connector/DB25M.fp (nonexistent) +++ tags/2.3.0/pcblib/connector/DB25M.fp (revision 33253) @@ -0,0 +1,1308 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = DSUB connector, female/male + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 125.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.43 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.27in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.47 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.378in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.51 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.486in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.55 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.594in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.59 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.702in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.63 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.81in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.67 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.918in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.71 { + smirror = 0 + ha:attributes { + term = 8 + name = 8 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.026in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.75 { + smirror = 0 + ha:attributes { + term = 9 + name = 9 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 54.2036mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.79 { + smirror = 0 + ha:attributes { + term = 10 + name = 10 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.242in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.83 { + smirror = 0 + ha:attributes { + term = 11 + name = 11 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.35in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.87 { + smirror = 0 + ha:attributes { + term = 12 + name = 12 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.458in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.91 { + smirror = 0 + ha:attributes { + term = 13 + name = 13 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 65.1764mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.95 { + smirror = 0 + ha:attributes { + term = 14 + name = 14 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.324in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.99 { + smirror = 0 + ha:attributes { + term = 15 + name = 15 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 36.3728mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.103 { + smirror = 0 + ha:attributes { + term = 16 + name = 16 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.54in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.107 { + smirror = 0 + ha:attributes { + term = 17 + name = 17 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.648in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.111 { + smirror = 0 + ha:attributes { + term = 18 + name = 18 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.756in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.115 { + smirror = 0 + ha:attributes { + term = 19 + name = 19 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.864in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.119 { + smirror = 0 + ha:attributes { + term = 20 + name = 20 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.972in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.123 { + smirror = 0 + ha:attributes { + term = 21 + name = 21 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.08in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.127 { + smirror = 0 + ha:attributes { + term = 22 + name = 22 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.188in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.131 { + smirror = 0 + ha:attributes { + term = 23 + name = 23 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.296in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.135 { + smirror = 0 + ha:attributes { + term = 24 + name = 24 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 61.0616mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.139 { + smirror = 0 + ha:attributes { + term = 25 + name = 25 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.512in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.143 { + smirror = 0 + ha:attributes { + term = 26 + name = C1 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 1000.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.144 { + smirror = 0 + ha:attributes { + term = 27 + name = C2 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 72.0344mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 2.956in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 2.956in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 2.956in + } + ha:line.16 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 2.956in + } + ha:line.19 { + clearance = 0.0 + y2 = 940.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 940.0mil + } + ha:line.22 { + clearance = 0.0 + y2 = 1.06in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.06in + } + ha:line.25 { + clearance = 0.0 + y2 = 73.5584mm + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 73.5584mm + } + ha:line.28 { + clearance = 0.0 + y2 = 2.776in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 2.776in + } + ha:line.31 { + clearance = 0.0 + y2 = 1.11in + thickness = 20.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.34 { + clearance = 0.0 + y2 = 2.726in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.37 { + clearance = 0.0 + y2 = 2.726in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 2.726in + } + ha:line.40 { + clearance = 0.0 + y2 = 1.11in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 2.726in + } + ha:line.44 { + clearance = 0.0 + y2 = 1.27in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.27in + } + ha:line.48 { + clearance = 0.0 + y2 = 1.378in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.378in + } + ha:line.52 { + clearance = 0.0 + y2 = 1.486in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.486in + } + ha:line.56 { + clearance = 0.0 + y2 = 1.594in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.594in + } + ha:line.60 { + clearance = 0.0 + y2 = 1.702in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.702in + } + ha:line.64 { + clearance = 0.0 + y2 = 1.81in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.81in + } + ha:line.68 { + clearance = 0.0 + y2 = 1.918in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.918in + } + ha:line.72 { + clearance = 0.0 + y2 = 2.026in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.026in + } + ha:line.76 { + clearance = 0.0 + y2 = 54.2036mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 54.2036mm + } + ha:line.80 { + clearance = 0.0 + y2 = 2.242in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.242in + } + ha:line.84 { + clearance = 0.0 + y2 = 2.35in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.35in + } + ha:line.88 { + clearance = 0.0 + y2 = 2.458in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.458in + } + ha:line.92 { + clearance = 0.0 + y2 = 65.1764mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 65.1764mm + } + ha:line.96 { + clearance = 0.0 + y2 = 1.324in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.324in + } + ha:line.100 { + clearance = 0.0 + y2 = 36.3728mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 36.3728mm + } + ha:line.104 { + clearance = 0.0 + y2 = 1.54in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.54in + } + ha:line.108 { + clearance = 0.0 + y2 = 1.648in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.648in + } + ha:line.112 { + clearance = 0.0 + y2 = 1.756in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.756in + } + ha:line.116 { + clearance = 0.0 + y2 = 1.864in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.864in + } + ha:line.120 { + clearance = 0.0 + y2 = 1.972in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.972in + } + ha:line.124 { + clearance = 0.0 + y2 = 2.08in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.08in + } + ha:line.128 { + clearance = 0.0 + y2 = 2.188in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.188in + } + ha:line.132 { + clearance = 0.0 + y2 = 2.296in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.296in + } + ha:line.136 { + clearance = 0.0 + y2 = 61.0616mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 61.0616mm + } + ha:line.140 { + clearance = 0.0 + y2 = 2.512in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.512in + } + ha:text.6 { + scale = 150 + ha:attributes { + } + x = 1000.0mil + y = 65.1764mm + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.145 { + clearance = 0.0 + y2 = 1.918in + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 25.452681mm + x2 = 25.452681mm + ha:flags { + } + y1 = 1.918in + } + ha:line.148 { + clearance = 0.0 + y2 = 1.27in + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 26.67mm + x2 = 26.67mm + ha:flags { + } + y1 = 1.27in + } + ha:line.151 { + clearance = 0.0 + y2 = 1.27in + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 26.67mm + x2 = 27.67mm + ha:flags { + } + y1 = 1.27in + } + ha:line.154 { + clearance = 0.0 + y2 = 33.258mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 26.67mm + x2 = 26.67mm + ha:flags { + } + y1 = 1.27in + } + } + ha:combining { + } + } + } + } + uid = mwT/lhqrRxvsA+MkDMwAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/connector/DB37F.fp =================================================================== --- tags/2.3.0/pcblib/connector/DB37F.fp (nonexistent) +++ tags/2.3.0/pcblib/connector/DB37F.fp (revision 33253) @@ -0,0 +1,1668 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = DSUB connector, female/male + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 125.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.43 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 81.6356mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.47 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 78.8924mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.51 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.998in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.55 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.89in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.59 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.782in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.63 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.674in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.67 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 65.1764mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.71 { + smirror = 0 + ha:attributes { + term = 8 + name = 8 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.458in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.75 { + smirror = 0 + ha:attributes { + term = 9 + name = 9 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.35in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.79 { + smirror = 0 + ha:attributes { + term = 10 + name = 10 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.242in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.83 { + smirror = 0 + ha:attributes { + term = 11 + name = 11 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 54.2036mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.87 { + smirror = 0 + ha:attributes { + term = 12 + name = 12 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.026in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.91 { + smirror = 0 + ha:attributes { + term = 13 + name = 13 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.918in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.95 { + smirror = 0 + ha:attributes { + term = 14 + name = 14 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.81in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.99 { + smirror = 0 + ha:attributes { + term = 15 + name = 15 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.702in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.103 { + smirror = 0 + ha:attributes { + term = 16 + name = 16 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.594in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.107 { + smirror = 0 + ha:attributes { + term = 17 + name = 17 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.486in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.111 { + smirror = 0 + ha:attributes { + term = 18 + name = 18 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.378in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.115 { + smirror = 0 + ha:attributes { + term = 19 + name = 19 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.27in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.119 { + smirror = 0 + ha:attributes { + term = 20 + name = 20 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 3.16in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.123 { + smirror = 0 + ha:attributes { + term = 21 + name = 21 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 3.052in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.127 { + smirror = 0 + ha:attributes { + term = 22 + name = 22 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.944in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.131 { + smirror = 0 + ha:attributes { + term = 23 + name = 23 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 72.0344mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.135 { + smirror = 0 + ha:attributes { + term = 24 + name = 24 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.728in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.139 { + smirror = 0 + ha:attributes { + term = 25 + name = 25 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.62in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.143 { + smirror = 0 + ha:attributes { + term = 26 + name = 26 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.512in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.147 { + smirror = 0 + ha:attributes { + term = 27 + name = 27 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 61.0616mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.151 { + smirror = 0 + ha:attributes { + term = 28 + name = 28 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.296in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.155 { + smirror = 0 + ha:attributes { + term = 29 + name = 29 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.188in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.159 { + smirror = 0 + ha:attributes { + term = 30 + name = 30 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.08in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.163 { + smirror = 0 + ha:attributes { + term = 31 + name = 31 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.972in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.167 { + smirror = 0 + ha:attributes { + term = 32 + name = 32 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.864in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.171 { + smirror = 0 + ha:attributes { + term = 33 + name = 33 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.756in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.175 { + smirror = 0 + ha:attributes { + term = 34 + name = 34 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.648in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.179 { + smirror = 0 + ha:attributes { + term = 35 + name = 35 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.54in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.183 { + smirror = 0 + ha:attributes { + term = 36 + name = 36 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 36.3728mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.187 { + smirror = 0 + ha:attributes { + term = 37 + name = 37 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.324in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.191 { + smirror = 0 + ha:attributes { + term = 38 + name = C1 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 1000.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.192 { + smirror = 0 + ha:attributes { + term = 39 + name = C2 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 3.484in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 3.604in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 3.604in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 3.604in + } + ha:line.16 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 3.604in + } + ha:line.19 { + clearance = 0.0 + y2 = 940.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 940.0mil + } + ha:line.22 { + clearance = 0.0 + y2 = 1.06in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.06in + } + ha:line.25 { + clearance = 0.0 + y2 = 3.544in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 3.544in + } + ha:line.28 { + clearance = 0.0 + y2 = 86.9696mm + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 86.9696mm + } + ha:line.31 { + clearance = 0.0 + y2 = 1.11in + thickness = 20.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.34 { + clearance = 0.0 + y2 = 3.374in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.37 { + clearance = 0.0 + y2 = 3.374in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 3.374in + } + ha:line.40 { + clearance = 0.0 + y2 = 1.11in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 3.374in + } + ha:line.44 { + clearance = 0.0 + y2 = 81.6356mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 81.6356mm + } + ha:line.48 { + clearance = 0.0 + y2 = 78.8924mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 78.8924mm + } + ha:line.52 { + clearance = 0.0 + y2 = 2.998in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.998in + } + ha:line.56 { + clearance = 0.0 + y2 = 2.89in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.89in + } + ha:line.60 { + clearance = 0.0 + y2 = 2.782in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.782in + } + ha:line.64 { + clearance = 0.0 + y2 = 2.674in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.674in + } + ha:line.68 { + clearance = 0.0 + y2 = 65.1764mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 65.1764mm + } + ha:line.72 { + clearance = 0.0 + y2 = 2.458in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.458in + } + ha:line.76 { + clearance = 0.0 + y2 = 2.35in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.35in + } + ha:line.80 { + clearance = 0.0 + y2 = 2.242in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.242in + } + ha:line.84 { + clearance = 0.0 + y2 = 54.2036mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 54.2036mm + } + ha:line.88 { + clearance = 0.0 + y2 = 2.026in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.026in + } + ha:line.92 { + clearance = 0.0 + y2 = 1.918in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.918in + } + ha:line.96 { + clearance = 0.0 + y2 = 1.81in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.81in + } + ha:line.100 { + clearance = 0.0 + y2 = 1.702in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.702in + } + ha:line.104 { + clearance = 0.0 + y2 = 1.594in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.594in + } + ha:line.108 { + clearance = 0.0 + y2 = 1.486in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.486in + } + ha:line.112 { + clearance = 0.0 + y2 = 1.378in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.378in + } + ha:line.116 { + clearance = 0.0 + y2 = 1.27in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.27in + } + ha:line.120 { + clearance = 0.0 + y2 = 3.16in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 3.16in + } + ha:line.124 { + clearance = 0.0 + y2 = 3.052in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 3.052in + } + ha:line.128 { + clearance = 0.0 + y2 = 2.944in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.944in + } + ha:line.132 { + clearance = 0.0 + y2 = 72.0344mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 72.0344mm + } + ha:line.136 { + clearance = 0.0 + y2 = 2.728in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.728in + } + ha:line.140 { + clearance = 0.0 + y2 = 2.62in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.62in + } + ha:line.144 { + clearance = 0.0 + y2 = 2.512in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.512in + } + ha:line.148 { + clearance = 0.0 + y2 = 61.0616mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 61.0616mm + } + ha:line.152 { + clearance = 0.0 + y2 = 2.296in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.296in + } + ha:line.156 { + clearance = 0.0 + y2 = 2.188in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.188in + } + ha:line.160 { + clearance = 0.0 + y2 = 2.08in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.08in + } + ha:line.164 { + clearance = 0.0 + y2 = 1.972in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.972in + } + ha:line.168 { + clearance = 0.0 + y2 = 1.864in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.864in + } + ha:line.172 { + clearance = 0.0 + y2 = 1.756in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.756in + } + ha:line.176 { + clearance = 0.0 + y2 = 1.648in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.648in + } + ha:line.180 { + clearance = 0.0 + y2 = 1.54in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.54in + } + ha:line.184 { + clearance = 0.0 + y2 = 36.3728mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 36.3728mm + } + ha:line.188 { + clearance = 0.0 + y2 = 1.324in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.324in + } + ha:text.6 { + scale = 150 + ha:attributes { + } + x = 1000.0mil + y = 81.6356mm + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.193 { + clearance = 0.0 + y2 = 2.242in + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 25.436471mm + x2 = 25.436471mm + ha:flags { + } + y1 = 2.242in + } + ha:line.196 { + clearance = 0.0 + y2 = 81.6356mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.056in + x2 = 1.056in + ha:flags { + } + y1 = 81.6356mm + } + ha:line.199 { + clearance = 0.0 + y2 = 81.6356mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.056in + x2 = 25.8224mm + ha:flags { + } + y1 = 81.6356mm + } + ha:line.202 { + clearance = 0.0 + y2 = 80.6356mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.056in + x2 = 1.056in + ha:flags { + } + y1 = 81.6356mm + } + } + ha:combining { + } + } + } + } + uid = RfWOhvAGP43wbRWBULgAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/connector/DB37M.fp =================================================================== --- tags/2.3.0/pcblib/connector/DB37M.fp (nonexistent) +++ tags/2.3.0/pcblib/connector/DB37M.fp (revision 33253) @@ -0,0 +1,1668 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = DSUB connector, female/male + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 125.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.43 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.27in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.47 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.378in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.51 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.486in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.55 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.594in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.59 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.702in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.63 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.81in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.67 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.918in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.71 { + smirror = 0 + ha:attributes { + term = 8 + name = 8 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.026in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.75 { + smirror = 0 + ha:attributes { + term = 9 + name = 9 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 54.2036mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.79 { + smirror = 0 + ha:attributes { + term = 10 + name = 10 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.242in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.83 { + smirror = 0 + ha:attributes { + term = 11 + name = 11 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.35in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.87 { + smirror = 0 + ha:attributes { + term = 12 + name = 12 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.458in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.91 { + smirror = 0 + ha:attributes { + term = 13 + name = 13 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 65.1764mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.95 { + smirror = 0 + ha:attributes { + term = 14 + name = 14 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.674in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.99 { + smirror = 0 + ha:attributes { + term = 15 + name = 15 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.782in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.103 { + smirror = 0 + ha:attributes { + term = 16 + name = 16 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.89in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.107 { + smirror = 0 + ha:attributes { + term = 17 + name = 17 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 2.998in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.111 { + smirror = 0 + ha:attributes { + term = 18 + name = 18 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 78.8924mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.115 { + smirror = 0 + ha:attributes { + term = 19 + name = 19 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 81.6356mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.119 { + smirror = 0 + ha:attributes { + term = 20 + name = 20 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.324in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.123 { + smirror = 0 + ha:attributes { + term = 21 + name = 21 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 36.3728mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.127 { + smirror = 0 + ha:attributes { + term = 22 + name = 22 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.54in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.131 { + smirror = 0 + ha:attributes { + term = 23 + name = 23 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.648in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.135 { + smirror = 0 + ha:attributes { + term = 24 + name = 24 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.756in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.139 { + smirror = 0 + ha:attributes { + term = 25 + name = 25 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.864in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.143 { + smirror = 0 + ha:attributes { + term = 26 + name = 26 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.972in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.147 { + smirror = 0 + ha:attributes { + term = 27 + name = 27 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.08in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.151 { + smirror = 0 + ha:attributes { + term = 28 + name = 28 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.188in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.155 { + smirror = 0 + ha:attributes { + term = 29 + name = 29 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.296in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.159 { + smirror = 0 + ha:attributes { + term = 30 + name = 30 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 61.0616mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.163 { + smirror = 0 + ha:attributes { + term = 31 + name = 31 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.512in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.167 { + smirror = 0 + ha:attributes { + term = 32 + name = 32 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.62in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.171 { + smirror = 0 + ha:attributes { + term = 33 + name = 33 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.728in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.175 { + smirror = 0 + ha:attributes { + term = 34 + name = 34 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 72.0344mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.179 { + smirror = 0 + ha:attributes { + term = 35 + name = 35 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 2.944in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.183 { + smirror = 0 + ha:attributes { + term = 36 + name = 36 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 3.052in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.187 { + smirror = 0 + ha:attributes { + term = 37 + name = 37 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 3.16in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.191 { + smirror = 0 + ha:attributes { + term = 38 + name = C1 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 1000.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.192 { + smirror = 0 + ha:attributes { + term = 39 + name = C2 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 3.484in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 3.604in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 3.604in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 3.604in + } + ha:line.16 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 3.604in + } + ha:line.19 { + clearance = 0.0 + y2 = 940.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 940.0mil + } + ha:line.22 { + clearance = 0.0 + y2 = 1.06in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.06in + } + ha:line.25 { + clearance = 0.0 + y2 = 3.544in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 3.544in + } + ha:line.28 { + clearance = 0.0 + y2 = 86.9696mm + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 86.9696mm + } + ha:line.31 { + clearance = 0.0 + y2 = 1.11in + thickness = 20.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.34 { + clearance = 0.0 + y2 = 3.374in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.37 { + clearance = 0.0 + y2 = 3.374in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 3.374in + } + ha:line.40 { + clearance = 0.0 + y2 = 1.11in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 3.374in + } + ha:line.44 { + clearance = 0.0 + y2 = 1.27in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.27in + } + ha:line.48 { + clearance = 0.0 + y2 = 1.378in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.378in + } + ha:line.52 { + clearance = 0.0 + y2 = 1.486in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.486in + } + ha:line.56 { + clearance = 0.0 + y2 = 1.594in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.594in + } + ha:line.60 { + clearance = 0.0 + y2 = 1.702in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.702in + } + ha:line.64 { + clearance = 0.0 + y2 = 1.81in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.81in + } + ha:line.68 { + clearance = 0.0 + y2 = 1.918in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.918in + } + ha:line.72 { + clearance = 0.0 + y2 = 2.026in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.026in + } + ha:line.76 { + clearance = 0.0 + y2 = 54.2036mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 54.2036mm + } + ha:line.80 { + clearance = 0.0 + y2 = 2.242in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.242in + } + ha:line.84 { + clearance = 0.0 + y2 = 2.35in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.35in + } + ha:line.88 { + clearance = 0.0 + y2 = 2.458in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.458in + } + ha:line.92 { + clearance = 0.0 + y2 = 65.1764mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 65.1764mm + } + ha:line.96 { + clearance = 0.0 + y2 = 2.674in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.674in + } + ha:line.100 { + clearance = 0.0 + y2 = 2.782in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.782in + } + ha:line.104 { + clearance = 0.0 + y2 = 2.89in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.89in + } + ha:line.108 { + clearance = 0.0 + y2 = 2.998in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 2.998in + } + ha:line.112 { + clearance = 0.0 + y2 = 78.8924mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 78.8924mm + } + ha:line.116 { + clearance = 0.0 + y2 = 81.6356mm + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 81.6356mm + } + ha:line.120 { + clearance = 0.0 + y2 = 1.324in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.324in + } + ha:line.124 { + clearance = 0.0 + y2 = 36.3728mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 36.3728mm + } + ha:line.128 { + clearance = 0.0 + y2 = 1.54in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.54in + } + ha:line.132 { + clearance = 0.0 + y2 = 1.648in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.648in + } + ha:line.136 { + clearance = 0.0 + y2 = 1.756in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.756in + } + ha:line.140 { + clearance = 0.0 + y2 = 1.864in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.864in + } + ha:line.144 { + clearance = 0.0 + y2 = 1.972in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.972in + } + ha:line.148 { + clearance = 0.0 + y2 = 2.08in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.08in + } + ha:line.152 { + clearance = 0.0 + y2 = 2.188in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.188in + } + ha:line.156 { + clearance = 0.0 + y2 = 2.296in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.296in + } + ha:line.160 { + clearance = 0.0 + y2 = 61.0616mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 61.0616mm + } + ha:line.164 { + clearance = 0.0 + y2 = 2.512in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.512in + } + ha:line.168 { + clearance = 0.0 + y2 = 2.62in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.62in + } + ha:line.172 { + clearance = 0.0 + y2 = 2.728in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.728in + } + ha:line.176 { + clearance = 0.0 + y2 = 72.0344mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 72.0344mm + } + ha:line.180 { + clearance = 0.0 + y2 = 2.944in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 2.944in + } + ha:line.184 { + clearance = 0.0 + y2 = 3.052in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 3.052in + } + ha:line.188 { + clearance = 0.0 + y2 = 3.16in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 3.16in + } + ha:text.6 { + scale = 150 + ha:attributes { + } + x = 1000.0mil + y = 81.6356mm + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.193 { + clearance = 0.0 + y2 = 2.242in + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 25.436471mm + x2 = 25.436471mm + ha:flags { + } + y1 = 2.242in + } + ha:line.196 { + clearance = 0.0 + y2 = 1.27in + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 26.67mm + x2 = 26.67mm + ha:flags { + } + y1 = 1.27in + } + ha:line.199 { + clearance = 0.0 + y2 = 1.27in + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 26.67mm + x2 = 27.67mm + ha:flags { + } + y1 = 1.27in + } + ha:line.202 { + clearance = 0.0 + y2 = 33.258mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 26.67mm + x2 = 26.67mm + ha:flags { + } + y1 = 1.27in + } + } + ha:combining { + } + } + } + } + uid = 4q1Up8irTZeVRbtKn8sAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/connector/DB9F.fp =================================================================== --- tags/2.3.0/pcblib/connector/DB9F.fp (nonexistent) +++ tags/2.3.0/pcblib/connector/DB9F.fp (revision 33253) @@ -0,0 +1,828 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = DSUB connector, female/male + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 125.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.43 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.702in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.47 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.594in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.51 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.486in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.55 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.378in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.59 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.27in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.63 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.648in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.67 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.54in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.71 { + smirror = 0 + ha:attributes { + term = 8 + name = 8 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 36.3728mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.75 { + smirror = 0 + ha:attributes { + term = 9 + name = 9 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.324in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.79 { + smirror = 0 + ha:attributes { + term = 10 + name = C1 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 1000.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.80 { + smirror = 0 + ha:attributes { + term = 11 + name = C2 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 1.972in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 2.092in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 2.092in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 2.092in + } + ha:line.16 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 2.092in + } + ha:line.19 { + clearance = 0.0 + y2 = 940.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 940.0mil + } + ha:line.22 { + clearance = 0.0 + y2 = 1.06in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.06in + } + ha:line.25 { + clearance = 0.0 + y2 = 2.032in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 2.032in + } + ha:line.28 { + clearance = 0.0 + y2 = 1.912in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.912in + } + ha:line.31 { + clearance = 0.0 + y2 = 1.11in + thickness = 20.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.34 { + clearance = 0.0 + y2 = 1.862in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.37 { + clearance = 0.0 + y2 = 1.862in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.862in + } + ha:line.40 { + clearance = 0.0 + y2 = 1.11in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.862in + } + ha:line.44 { + clearance = 0.0 + y2 = 1.702in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.702in + } + ha:line.48 { + clearance = 0.0 + y2 = 1.594in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.594in + } + ha:line.52 { + clearance = 0.0 + y2 = 1.486in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.486in + } + ha:line.56 { + clearance = 0.0 + y2 = 1.378in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.378in + } + ha:line.60 { + clearance = 0.0 + y2 = 1.27in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.27in + } + ha:line.64 { + clearance = 0.0 + y2 = 1.648in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.648in + } + ha:line.68 { + clearance = 0.0 + y2 = 1.54in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.54in + } + ha:line.72 { + clearance = 0.0 + y2 = 36.3728mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 36.3728mm + } + ha:line.76 { + clearance = 0.0 + y2 = 1.324in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.324in + } + ha:text.6 { + scale = 150 + ha:attributes { + } + x = 1000.0mil + y = 1.702in + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.81 { + clearance = 0.0 + y2 = 1.486in + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 25.529309mm + x2 = 25.529309mm + ha:flags { + } + y1 = 1.486in + } + ha:line.84 { + clearance = 0.0 + y2 = 1.702in + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.056in + x2 = 1.056in + ha:flags { + } + y1 = 1.702in + } + ha:line.87 { + clearance = 0.0 + y2 = 1.702in + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.056in + x2 = 25.8224mm + ha:flags { + } + y1 = 1.702in + } + ha:line.90 { + clearance = 0.0 + y2 = 42.2308mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.056in + x2 = 1.056in + ha:flags { + } + y1 = 1.702in + } + } + ha:combining { + } + } + } + } + uid = bMtrWJ4J7RopF+TYtuYAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/connector/DB9M.fp =================================================================== --- tags/2.3.0/pcblib/connector/DB9M.fp (nonexistent) +++ tags/2.3.0/pcblib/connector/DB9M.fp (revision 33253) @@ -0,0 +1,828 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = DSUB connector, female/male + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 125.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 250.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 256.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.43 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.27in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.47 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.378in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.51 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.486in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.55 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.594in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.59 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 1.056in + rot = 0.000000 + y = 1.702in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.63 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.324in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.67 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 36.3728mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.71 { + smirror = 0 + ha:attributes { + term = 8 + name = 8 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.54in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.75 { + smirror = 0 + ha:attributes { + term = 9 + name = 9 + } + proto = 1 + xmirror = 0 + x = 944.0mil + rot = 0.000000 + y = 1.648in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.79 { + smirror = 0 + ha:attributes { + term = 10 + name = C1 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 1000.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.80 { + smirror = 0 + ha:attributes { + term = 11 + name = C2 + } + proto = 2 + xmirror = 0 + x = 1000.0mil + rot = 0.000000 + y = 1.972in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 2.092in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 880.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 2.092in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 2.092in + } + ha:line.16 { + clearance = 0.0 + y2 = 880.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 635.0mil + ha:flags { + } + y1 = 2.092in + } + ha:line.19 { + clearance = 0.0 + y2 = 940.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 940.0mil + } + ha:line.22 { + clearance = 0.0 + y2 = 1.06in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.06in + } + ha:line.25 { + clearance = 0.0 + y2 = 2.032in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 2.032in + } + ha:line.28 { + clearance = 0.0 + y2 = 1.912in + thickness = 10.0mil + ha:attributes { + } + x1 = 635.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.912in + } + ha:line.31 { + clearance = 0.0 + y2 = 1.11in + thickness = 20.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.34 { + clearance = 0.0 + y2 = 1.862in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.11in + } + ha:line.37 { + clearance = 0.0 + y2 = 1.862in + thickness = 20.0mil + ha:attributes { + } + x1 = 770.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.862in + } + ha:line.40 { + clearance = 0.0 + y2 = 1.11in + thickness = 10.0mil + ha:attributes { + } + x1 = 665.0mil + x2 = 665.0mil + ha:flags { + } + y1 = 1.862in + } + ha:line.44 { + clearance = 0.0 + y2 = 1.27in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.27in + } + ha:line.48 { + clearance = 0.0 + y2 = 1.378in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.378in + } + ha:line.52 { + clearance = 0.0 + y2 = 1.486in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.486in + } + ha:line.56 { + clearance = 0.0 + y2 = 1.594in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.594in + } + ha:line.60 { + clearance = 0.0 + y2 = 1.702in + thickness = 20.0mil + ha:attributes { + } + x1 = 1.016in + x2 = 770.0mil + ha:flags { + } + y1 = 1.702in + } + ha:line.64 { + clearance = 0.0 + y2 = 1.324in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.324in + } + ha:line.68 { + clearance = 0.0 + y2 = 36.3728mm + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 36.3728mm + } + ha:line.72 { + clearance = 0.0 + y2 = 1.54in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.54in + } + ha:line.76 { + clearance = 0.0 + y2 = 1.648in + thickness = 20.0mil + ha:attributes { + } + x1 = 904.0mil + x2 = 770.0mil + ha:flags { + } + y1 = 1.648in + } + ha:text.6 { + scale = 150 + ha:attributes { + } + x = 1000.0mil + y = 1.702in + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.81 { + clearance = 0.0 + y2 = 1.486in + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 25.529309mm + x2 = 25.529309mm + ha:flags { + } + y1 = 1.486in + } + ha:line.84 { + clearance = 0.0 + y2 = 1.27in + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 26.67mm + x2 = 26.67mm + ha:flags { + } + y1 = 1.27in + } + ha:line.87 { + clearance = 0.0 + y2 = 31.258mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 26.67mm + x2 = 26.67mm + ha:flags { + } + y1 = 1.27in + } + ha:line.90 { + clearance = 0.0 + y2 = 1.27in + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 26.67mm + x2 = 25.67mm + ha:flags { + } + y1 = 1.27in + } + } + ha:combining { + } + } + } + } + uid = KO9hCrE+Bz6rQzxqYx8AAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/connector/pwrjack.fp =================================================================== --- tags/2.3.0/pcblib/connector/pwrjack.fp (nonexistent) +++ tags/2.3.0/pcblib/connector/pwrjack.fp (revision 33253) @@ -0,0 +1,300 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = power jack + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 2.999994mm + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 4.99999mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 4.99999mm + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 4.99999mm + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 5.15239mm + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 5.15239mm + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 2 + } + proto = 0 + xmirror = 0 + x = 1.24016in + rot = 0.000000 + y = 35.999928mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 1 + } + proto = 0 + xmirror = 0 + x = 1.24016in + rot = 0.000000 + y = 1.14173in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + } + proto = 0 + xmirror = 0 + x = 1.06299in + rot = 0.000000 + y = 1.27953in + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 35.999928mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.06299in + x2 = 1.06299in + ha:flags { + } + y1 = 21.999956mm + } + ha:line.13 { + clearance = 0.0 + y2 = 35.999928mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.06299in + x2 = 35.999928mm + ha:flags { + } + y1 = 35.999928mm + } + ha:line.16 { + clearance = 0.0 + y2 = 21.999956mm + thickness = 10.0mil + ha:attributes { + } + x1 = 35.999928mm + x2 = 35.999928mm + ha:flags { + } + y1 = 35.999928mm + } + ha:line.19 { + clearance = 0.0 + y2 = 21.999956mm + thickness = 10.0mil + ha:attributes { + } + x1 = 35.999928mm + x2 = 1.06299in + ha:flags { + } + y1 = 21.999956mm + } + ha:line.22 { + clearance = 0.0 + y2 = 984.25mil + thickness = 10.0mil + ha:attributes { + } + x1 = 1.06299in + x2 = 35.999928mm + ha:flags { + } + y1 = 984.25mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 1.24016in + y = 35.999928mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.25 { + clearance = 0.0 + y2 = 32.499977mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 1.18110331in + x2 = 1.18110331in + ha:flags { + } + y1 = 32.499977mm + } + ha:line.28 { + clearance = 0.0 + y2 = 35.999928mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.24016in + x2 = 1.24016in + ha:flags { + } + y1 = 35.999928mm + } + ha:line.31 { + clearance = 0.0 + y2 = 34.999928mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.24016in + x2 = 1.24016in + ha:flags { + } + y1 = 35.999928mm + } + ha:line.34 { + clearance = 0.0 + y2 = 35.999928mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.24016in + x2 = 30.500064mm + ha:flags { + } + y1 = 35.999928mm + } + } + ha:combining { + } + } + } + } + uid = N9dhMGRbIqPCtXUXD0MAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/parametric/acy =================================================================== --- tags/2.3.0/pcblib/parametric/acy (nonexistent) +++ tags/2.3.0/pcblib/parametric/acy (revision 33253) @@ -0,0 +1,56 @@ +#!/bin/sh + +#@@example acy(300) + +#@@purpose Generate axial lead through-hole component + +#@@desc Generate axial lead through-hole component with 2 pins (typical use: resistor) +#@@params spacing,type,pol,dia + +#@@param:spacing spacing between the two pins +#@@dim:spacing + +#@@param:type silk symbol type +#@@enum:type:block eu-style block resistor symbol +#@@enum:type:endcap block resistor with caps on the ends +#@@enum:type:zigzag us-style zigzag resistor symbol +#@@enum:type:line a single line (e.g. for jumper wires) +#@@enum:type:standing vertically aligned, body standing on pin 1, pin 2 bent back +#@@enum:type:coil wavy coil symbol +#@@enum:type:core wavy coil symbol with a parallel line +#@@enum:type:core2 wavy coil symbol with two parallel lines +#@@optional:type +#@@default:type block +#@@preview_args:type 300 + +#@@param:pol how to mark polarity +#@@enum:pol:none no marking +#@@enum:pol:sign + and - signs; pin 1 is + +#@@enum:pol:bar bar next to pin 1 +#@@enum:pol:dot dot next to pin 1 +#@@optional:pol +#@@default:pol none +#@@preview_args:pol 300 + +#@@param:dia body diameter - affects silk size +#@@dim:dia +#@@optional:dia +#@@default:dia spacing/6 + + +#@@param:wiper silk symbol wiper type +#@@enum:wiper:none no wiper +#@@enum:wiper:parrow perpendicular arrow, pointing inwards +#@@enum:wiper:aarrow angled arrow, pointing outwards +#@@enum:wiper:looparrow arrow starting at pin 2 looping back to point inwards on the body +#@@enum:wiper:thermistor wiper of a thermistor symbol +#@@optional:wiper +#@@default:wiper none +#@@preview_args:wiper 400 + +#@@thumbsize 2 + +#@@include common_subc.awk + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/acy.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/acy ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/acy.awk =================================================================== --- tags/2.3.0/pcblib/parametric/acy.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/acy.awk (revision 33253) @@ -0,0 +1,158 @@ +function wave(type, repeat, step,x,y) +{ + step = len/repeat + for(x = sx1; x < sx2; x += step) { + if (type == 1) { + subc_arc("top-silk", x+step/2, 0, step/2, 0, -180) + } + else if (type == 2) { + y = dia + subc_line("top-silk", x, 0, x+step/4, -y) + subc_line("top-silk", x+step/4, -y, x+3*step/4, y) + subc_line("top-silk", x+3*step/4, y, x+step, 0) + + } + } +} + +BEGIN { + base_unit_mm = 0 + + help_auto() + set_arg(P, "?type", "block") + proc_args(P, "spacing,type,pol,dia", "spacing") + + spacing = parse_dim(P["spacing"]) + dia = either(parse_dim(P["dia"]), spacing/6) + +# oops, dia is a radius rather + dia=dia/2 + + offs_x = +spacing/2 + + subc_begin("acy" P["spacing"], "R1", -spacing/5, -mil(20), 0) + + proto_s = subc_proto_create_pin_square() + proto_r = subc_proto_create_pin_round() + + subc_pstk(proto_s, -spacing/2, 0, 0, 1) + subc_pstk(proto_r, +spacing/2, 0, 0, 2) + + dimension(-spacing/2, 0, +spacing/2, 0, dia*4, "spacing") + +# silk pins + if (P["type"] != "line") { + subc_line("top-silk", -spacing/2, 0, -spacing/4, 0) + subc_line("top-silk", +spacing/4, 0, +spacing/2, 0) + } + +# silk symbol + sx1 = -spacing/4 + sx2 = +spacing/4 + len = sx2-sx1 + if (P["type"] == "block") { + subc_rectangle("top-silk", sx1, -dia, sx2, +dia) + } + else if (P["type"] == "zigzag") { + wave(2, 3) + } + else if (P["type"] == "coil") { + wave(1, 4) + } + else if (P["type"] == "endcap") { + cl1 = len/9 + cl2 = len/8 + y1 = dia*1.2 + y2 = dia + rarc = dia/5 + subc_line("top-silk", sx1+cl2, y2, sx2-cl2, y2) + subc_line("top-silk", sx1+cl2, y2, sx1+cl1, y1) + subc_line("top-silk", sx2-cl2, y2, sx2-cl1, y1) + + subc_line("top-silk", sx1+cl2, -y2, sx2-cl2, -y2) + subc_line("top-silk", sx1+cl2, -y2, sx1+cl1, -y1) + subc_line("top-silk", sx2-cl2, -y2, sx2-cl1, -y1) + + subc_rectangle("top-silk", sx1, y1, sx1+cl1, -y1, "right,NE,SE", rarc) + subc_rectangle("top-silk", sx2-cl1, y1, sx2, -y1, "left,NW,SW", rarc) + } + else if (P["type"] ~ "^core") { + wave(1, 4) + nlines = P["type"] + sub("^core", "", nlines) + if (nlines == "") + nlines = 1 + + cdist = 3 * DEFAULT["line_thickness"] + y = -len/8 + for(nlines = int(nlines); nlines > 0; nlines--) { + y-=cdist + subc_line("top-silk", sx1, y, sx2, y) + } + } + else if (P["type"] == "line") { + subc_line("top-silk", -spacing/2, 0, +spacing/2, 0) + } + else if (P["type"] == "standing") { + r = dia*2 + if (r < DEFAULT["pin_ringdia"]/2*1.2) + r = DEFAULT["pin_ringdia"]/2*1.2 + subc_arc("top-silk", -spacing/2, 0, r, 0, 360) + subc_line("top-silk", -spacing/2, 0, +spacing/2, 0) + } + else { + error("Invalid type") + } + + dimension(sx2, -dia, sx2, dia, spacing/2, "dia") + +# silk wiper + if (P["wiper"] == "thermistor") { + x = len/3 + subc_line("top-silk", -4*x/4, dia*2, -2*x/4, dia*2) + subc_line("top-silk", -2*x/4, dia*2, +2*x/4, -dia*2) + } + else if (P["wiper"] == "aarrow") { + x = len/3 + subc_arrow("top-silk", -2*x/4, dia*2, +2*x/4, -dia*2-mil(30)) + } + else if (P["wiper"] == "parrow") { + subc_arrow("top-silk", 0, -dia*2-mil(30), 0, -dia) + } + else if (P["wiper"] == "looparrow") { + y = -dia*2-mil(30) + x = sx2+len/8 + subc_arrow("top-silk", 0, y, 0, -dia) + subc_line("top-silk", 0, y, x, y) + subc_line("top-silk", x, y, x, 0) + } + else if ((P["wiper"] != "none") && (P["wiper"] != "")) { + error("Invalid wiper") + } + +# silk sign + if (P["pol"] == "sign") { + size=mil(10) + + oy = size*2.2-offs_y + ox = DEFAULT["pin_ringdia"]/2+size*1.1-offs_x + subc_line("top-silk", ox-size, oy, ox+size, oy) + + ox = spacing - (DEFAULT["pin_ringdia"]/2+size*1.1)-offs_x + subc_line("top-silk", ox-size, oy, ox+size, oy) + subc_line("top-silk", ox, oy-size, ox, oy+size) + } + else if (P["pol"] == "bar") { + offs=DEFAULT["line_thickness"] + subc_rectangle("top-silk", -spacing/4-offs, -dia, -spacing/4+offs, +dia, DEFAULT["line_thickness"]*4) + } + else if (P["pol"] == "dot") { + r=2*DEFAULT["line_thickness"]/3 + subc_arc("top-silk", -spacing/4-r*3, -dia/2, r, 0, 360) + } + else if ((P["pol"] != "") && (P["pol"] != "none")) { + error("Invalid pol") + } + + subc_end() +} Index: tags/2.3.0/pcblib/parametric/alf =================================================================== --- tags/2.3.0/pcblib/parametric/alf (nonexistent) +++ tags/2.3.0/pcblib/parametric/alf (revision 33253) @@ -0,0 +1,37 @@ +#!/bin/sh + +#@@example alf(300, schottky) + +#@@purpose Generate ALF: axial lead through-hole component for diodes + +#@@desc Generate axial lead through-hole component with 2 pin diodes +#@@params spacing,type,dia +#@@thumbsize 2 + +#@@param:spacing spacing between the two pins +#@@dim:spacing + +#@@param:type symbol type +#@@enum:type:normal +#@@enum:type:schottky +#@@enum:type:zener +#@@enum:type:tunnel +#@@enum:type:varactor +#@@optional:type +#@@default:type normal +#@@preview_args:type 300 + +#@@param:dia body diameter - affects silk symbol size +#@@dim:dia +#@@optional:dia +#@@default:dia spacing/12 + +#@@param:aspect silk symbol aspect: total width expressed as a portion of spacing +#@@optional:aspect +#@@default:aspect spacing/6 + + +#@@include common_subc.awk + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/alf.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/alf ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/alf.awk =================================================================== --- tags/2.3.0/pcblib/parametric/alf.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/alf.awk (revision 33253) @@ -0,0 +1,71 @@ +BEGIN { + base_unit_mm = 0 + + help_auto() + set_arg(P, "?aspect", 6) + set_arg(P, "?type", "normal") + + proc_args(P, "spacing,type,dia,aspect", "spacing") + + spacing = parse_dim(P["spacing"]) + dia = either(parse_dim(P["dia"]), spacing/6) + aspect = P["aspect"] + + offs_x = +spacing/2 + + subc_begin("acy" P["spacing"], "D1", 2.2*spacing/3-offs_x,-mil(50)) + + proto_s = subc_proto_create_pin_square() + proto_r = subc_proto_create_pin_round() + + subc_pstk(proto_s, -spacing/2, 0, 0, 1) + subc_pstk(proto_r, +spacing/2, 0, 0, 2) + + dimension(-spacing/2, 0, +spacing/2, 0, dia*4, "spacing") + +# pins + subc_line("top-silk", -spacing/2, 0, -spacing/aspect, 0) + subc_line("top-silk", +spacing/aspect, 0, +spacing/2, 0) + +# triangle + subc_line("top-silk", +spacing/aspect, -dia, +spacing/aspect, +dia) + subc_line("top-silk", +spacing/aspect, -dia, -spacing/aspect, 0) + subc_line("top-silk", +spacing/aspect, +dia, -spacing/aspect, 0) + + dimension(+spacing/aspect, -dia, +spacing/aspect, dia, "@" spacing*1.2 ";0", "dia") + + +# front cross line with decoration + r = dia*0.3 + if (P["type"] == "normal") { + subc_line("top-silk", -spacing/aspect, -dia, -spacing/aspect, +dia) + } + else if (P["type"] == "zener") { + subc_line("top-silk", -spacing/aspect, -dia, -spacing/aspect, +dia) + subc_line("top-silk", -spacing/aspect, +dia, -spacing/aspect-r, +dia) + subc_line("top-silk", -spacing/aspect, -dia, -spacing/aspect+r, -dia) + } + else if (P["type"] == "tunnel") { + subc_line("top-silk", -spacing/aspect, -dia, -spacing/aspect, +dia) + subc_line("top-silk", -spacing/aspect, +dia, -spacing/aspect+r, +dia) + subc_line("top-silk", -spacing/aspect, -dia, -spacing/aspect+r, -dia) + } + else if (P["type"] == "varactor") { + subc_line("top-silk", -spacing/aspect, -dia, -spacing/aspect, +dia) + subc_line("top-silk", -spacing/aspect-r, -dia, -spacing/aspect-r, +dia) + } + else if (P["type"] == "schottky") { + cx = -spacing/aspect + r + cy = -(dia-r) + subc_line("top-silk", -spacing/aspect, -(dia-r), -spacing/aspect, +dia-r) + subc_arc("top-silk", cx, cy, r, 0, -180) + cx = -spacing/aspect - r + cy = +(dia-r) + subc_arc("top-silk", cx, cy, r, 0, +180) + } + else if ((P["type"] != "") && (P["type"] != "none")) { + error("Invalid type") + } + + subc_end() +} Index: tags/2.3.0/pcblib/parametric/bga =================================================================== --- tags/2.3.0/pcblib/parametric/bga (nonexistent) +++ tags/2.3.0/pcblib/parametric/bga (revision 33253) @@ -0,0 +1,74 @@ +#!/bin/sh + +# Reference: Microchip Packaging Specification DS00000049BX (en012702.pdf), SSOP + +#@@example bga(map=a1:a2:a3:#:b1:!:b3:#:c1:c2:!) + +#@@purpose Generate ball grid array + +#@@desc Generate a grid of circular pads for BGA chips + +#@@params nx,ny,spacing,balldia,silkmark,map,width,height,automap,automap2 + +#@@param:nx number of pins in the X direction +#@@optional:nx +#@@default:nx deduced from the map + +#@@param:ny number of pins in the Y direction +#@@optional:ny +#@@default:ny deduced from the map + +#@@param:spacing spacing between the pins +#@@dim:spacing +#@@default:spacing 0.5 mm + +#@@param:balldia diameter of a ball +#@@dim:balldia +#@@default:spacing 0.35 mm + +#@@include silkmark.help +#@@optional:silkmark +#@@default:silkmark square +#@@preview_args:silkmark 3,3 + +#@@param:map pin name map; a colon separated list of names, from left to right, rows first. If a name is empty or is a hash mark, a new row is started. If a name is a !, the given pin is missing and no pad is generated. +#@@optional:map + +#@@param:width width of the box (silk rectangle x size) +#@@dim:width +#@@optional:width +#@@default:width two columns wider than the array + +#@@param:height height of the box (silk rectangle y size) +#@@dim:height +#@@optional:height +#@@default:height two columns higher than the array + + +#@@param:automap assume a regular nx*ny array, automap (autonumber) the pins +#@@optional:automap +#@@enum:automap:none do not autonumber pins +#@@enum:automap:alnum number y rows from A..Z (then AA..AZ) from top to bottom, number x rows from 0..nx left to right +#@@default:none +#@@preview_args:automap 3,3 +#@@thumbsize:automap 3 +#@@thumbnum:automap 1 + +#@@param:automap2 change how automap behaves - multiple values separated by colon are accepted (e.g. automap2=pivot,reversex) +#@@enum:automap2:pivot swap x and y +#@@enum:automap2:reversex number x from right to left +#@@enum:automap2:reversey number y from bottom up +#@@preview_args:automap2 3,3,automap=alnum +#@@thumbsize:automap2 3 +#@@thumbnum:automap2 1 + +#@@param:alphabet the alphabet automap may use for rows; use A..Z if unspecified, else use the letters in this alphabet (in order). List letters without separator, e.g. ABCDEF +#@@preview_args:automap2 3,3,automap=alnum,alphabet=QDT +#@@thumbsize:automap2 3 +#@@thumbnum:automap2 1 + + +#@@include common_subc.awk + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/bga.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/bga ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/bga.awk =================================================================== --- tags/2.3.0/pcblib/parametric/bga.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/bga.awk (revision 33253) @@ -0,0 +1,125 @@ +function pinalpha(p, s) +{ + if (p >= alphabet_len) + s = pinalpha(int(p/alphabet_len)-1) + return s sprintf("%s", substr(alphabet, (p % alphabet_len)+1, 1)) +} + +function automap(algo, pivot, revx, revy ,xx,yy) +{ + if (algo == 1) { + for(y = 0; y < ny; y++) { + if (revy) + yy = ny - y - 1 + else + yy = y + for(x = 0; x < nx; x++) { + if (revx) + xx = nx - x - 1 + else + xx = x + if (pivot) + MAP[x,y] = pinalpha(xx) yy+1 + else + MAP[x,y] = pinalpha(yy) xx+1 + } + } + } +} + +BEGIN { + help_auto() + set_arg(P, "?spacing", "0.5mm") + set_arg(P, "?balldia", "0.35mm") + set_arg(P, "?silkmark", "arc") + + proc_args(P, "nx,ny,spacing,balldia,silkmark,map,width,height,automap,automap2,alphabet", "") + + step = parse_dim(P["spacing"]) + + half=step/2 + + nx = int(P["nx"]) + ny = int(P["ny"]) + + alphabet = P["alphabet"] + if (alphabet == "") + alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + alphabet_len = length(alphabet) + + if (P["map"] != "") { + v = split(P["map"], A, ":") + x = 0 + y = 0 + for(n = 1; n <= v; n++) { + if ((A[n] == "") || (A[n] == "#")) { + x = 0 + y++ + continue; + } + if (x > nx) + nx = x + if (y > ny) + ny = y + print x,y,A[n] > "/dev/stderr" + MAP[x, y] = A[n] + x++ + } + ny++; + nx++; + } + else { + if ((nx == "") || (ny == "")) + error("missing argument: need nx,ny or a map") + if (P["automap"] ~ "alnum") + automap(1, (P["automap2"] ~ "pivot"), (P["automap2"] ~ "reversex"), (P["automap2"] ~ "reversey")) + else if ((P["automap"] ~ "none") || (P["automap"] == "")) { + } + else + error("automap should be alnum or none") + } + + balldia = parse_dim(P["balldia"]) + bw = parse_dim(P["width"]) + bh = parse_dim(P["height"]) + + if (bw == "") + bw = (nx+1)*step + if (bh == "") + bh = (ny+1)*step + + xo = (nx-1)*step/2 + yo = (ny-1)*step/2 + + subc_begin(nx "*" ny, "U1", 0, -bh) + + proto = subc_proto_create_pad_circle(balldia) + + for(x = 0; x < nx; x++) { + for(y = 0; y < ny; y++) { + xx = x * step - xo + yy = y * step - yo + name = MAP[x,y] + if (name == "!") + continue + if (name == "") + name = "NC" + subc_pstk(proto, xx, yy, 0, name) + } + } + + dimension(-xo, -yo, -xo+step, -yo, bw/2, "spacing") + dimension(-xo-balldia/2, +yo, -xo+balldia/2, +yo, -bw*0.75, "balldia") + + + xx = -1 * (bw/2) + yy = -1 * (bh/2) + subc_rectangle("top-silk", xx, yy, bw/2, bh/2) + + dimension(xx, yy, bw/2, yy, bw/2, "width") + dimension(bw/2, yy, bw/2, bh/2, +bh/2, "height") + + silkmark(P["silkmark"], xx, yy, half*1.5) + + subc_end() +} Index: tags/2.3.0/pcblib/parametric/common.awk =================================================================== --- tags/2.3.0/pcblib/parametric/common.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/common.awk (revision 33253) @@ -0,0 +1,645 @@ +### DO NOT USE THIS FILE ### + +# This file is provided only for compatibility with old parametric footprints. +# New parametric footprints should use common_subc.awk because that uses lihata +# subcircuits instead of obsolete element format. + +#@@param:pin_ringdia pin's copper ring (annulus) outer diameter (in mil by default, mm suffix can be used) +#@@optional:pin_ringdia +#@@dim:pin_ringdia + +#@@param:pin_clearance pin's copper clearance diameter (in mil by default, mm suffix can be used) +#@@optional:pin_clearance +#@@dim:pin_clearance + +#@@param:pin_mask pin's solder mask diameter (in mil by default, mm suffix can be used) +#@@optional:pin_mask +#@@dim:pin_mask + +#@@param:pin_drill copper pin's drill diameter (in mil by default, mm suffix can be used) +#@@optional:pin_drill +#@@dim:pin_drill + +#@@param:pad_thickness width of pads (in mil by default, mm suffix can be used) +#@@optional:pad_thickness +#@@dim:pad_thickness + +#@@param:pad_clearance copper clearance around the pad (in mil by default, mm suffix can be used) +#@@optional:pad_clearance +#@@dim:pad_clearance + +#@@param:pad_mask pin's solder mask (in mil by default, mm suffix can be used) +#@@optional:pad_mask +#@@dim:pad_mask + +#@@param:line_thickness silk line thickness (in mil by default, mm suffix can be used) +#@@optional:line_thickness +#@@dim:line_thickness + +BEGIN { + q="\"" + + DEFAULT["pin_ringdia"] = 8000 + DEFAULT["pin_ringdia", "dim"] = 1 + + DEFAULT["pin_clearance"] = 5000 + DEFAULT["pin_clearance", "dim"] = 1 + + DEFAULT["pin_mask"] = 8600 + DEFAULT["pin_mask", "dim"] = 1 + + DEFAULT["pin_drill"] = 3937 + DEFAULT["pin_drill", "dim"] = 1 + + DEFAULT["line_thickness"] = 1000 + DEFAULT["line_thickness", "dim"] = 1 + + DEFAULT["pad_thickness"] = 2000 + DEFAULT["pad_thickness", "dim"] = 1 + DEFAULT["pad_clearance"] = 1000 + DEFAULT["pad_clearance", "dim"] = 1 + DEFAULT["pad_mask"] = 3000 + DEFAULT["pad_mask", "dim"] = 1 + + DEFAULT["pin_flags"] = "__auto" + + s_default=1 + s_weak=2 + s_explicit=3 + + offs_x = 0 + offs_y = 0 + + pi=3.141592654 +} + +# Throw an error and exit +function error(msg) +{ + print "Error: " msg > "/dev/stderr" + exit 1 +} + +# return a if it is not empty, else return b +function either(a, b) +{ + return a != "" ? a : b +} + +# strip leading/trailing whitespaces +function strip(s) +{ + sub("^[ \t\r\n]*", "", s) + sub("[ \t\r\n]*$", "", s) + return s +} + +# translate coordinates +function coord_x(x) { return int(x + offs_x) } +function coord_y(y) { return int(y + offs_y) } + +# generate an element header line; any argument may be empty +function element_begin(desc, name, value, cent_x, cent_y, text_x, text_y, text_dir, text_scale) +{ + if (desc == "") { + desc = gen "(" args ")" + gsub("[\r\n\t ]*[?][^,]*,[\r\n\t ]*", "", desc) + gsub("[\r\n\t]", " ", desc) + } + print "Element[" q q, q desc q, q name q, q value q, + int(either(cent_x, 0)), int(either(cent_y, 0)), + int(either(text_x, 0)), int(either(text_y, 0)), + int(either(text_dir, 0)), int(either(text_scale, 100)), q q "]" + print "(" +} + +# generate an element footer line +function element_end() +{ + print ")" +} + +# generate a pin; arguments from ringdia are optional (defaults are in global vars pin_*) +function element_pin(x, y, number, flags, ringdia, clearance, mask, drill, name) +{ + if (number == "") + number = ++pin_number + + flags = either(flags, DEFAULT["pin_flags"]) + + if (flags == "__auto") { + if (number == 1) + flags = "square" + else + flags = "" + } + + if (flags == "none") + flags = "" + + print " Pin[" coord_x(x), coord_y(y), + int(either(ringdia, DEFAULT["pin_ringdia"])), int(either(clearance, DEFAULT["pin_clearance"])), int(either(mask, DEFAULT["pin_mask"])), + int(either(drill, DEFAULT["pin_drill"])), q name q, q number q, q flags q "]" +} + +# draw element pad +function element_pad(x1, y1, x2, y2, thickness, number, flags, clearance, mask, name) +{ + print " Pad[", coord_x(x1), coord_y(y1), coord_x(x2), coord_y(y2), int(either(thickness, DEFAULT["pad_thickness"])), + int(either(clearance, DEFAULT["pad_clearance"])), int(either(mask, DEFAULT["pad_mask"])), + q name q, q number q, q flags q "]" +} + +# draw element pad - no thickness, but exact corner coordinates given +function element_pad_rectangle(x1, y1, x2, y2, number, flags, clearance, mask, name, th,dx,dy,cx,cy) +{ + if (x2 < x1) { + th = x2 + x2 = x1 + x1 = th + } + if (y2 < y1) { + th = y2 + y2 = y1 + y1 = th + } + + dx = x2-x1 + dy = y2-y1 + + if (dx >= dy) { + th = dy + cy = (y1+y2)/2 + + print " Pad[", coord_x(x1)+th/2, coord_y(cy), coord_x(x2)-th/2, coord_y(cy), th, + int(either(clearance, DEFAULT["pad_clearance"])), int(either(mask, DEFAULT["pad_mask"])), + q name q, q number q, q flags q "]" + } + else { + th = dx + cx = (x1+x2)/2 + + print " Pad[", coord_x(cx), coord_y(y1)+th/2, coord_x(cx), coord_y(y2)-th/2, th, + int(either(clearance, DEFAULT["pad_clearance"])), int(either(mask, DEFAULT["pad_mask"])), + q name q, q number q, q flags q "]" + } +} + +# draw a matrix of pads; top-left corner is x1;y1, there are nx*ny pads +# of w*h size. rows/cols of pads are drawn with ox and oy offset +function element_pad_matrix(x1, y1, nx, ny, w, h, ox, oy, number, flags, clearance, mask, name, ix,iy) +{ + for(iy = 0; iy < ny; iy++) + for(ix = 0; ix < nx; ix++) + element_pad_rectangle(x1+ix*ox, y1+iy*oy, x1+ix*ox+w, y1+iy*oy+h, number, flags, clearance, mask, name) +} + +# draw element pad circle +function element_pad_circle(x1, y1, radius, number, clearance, mask, name) +{ + print " Pad[", coord_x(x1), coord_y(y1), coord_x(x1), coord_y(y1), int(either(radius, DEFAULT["pad_thickness"])), + int(either(clearance, DEFAULT["pad_clearance"])), int(either(mask, DEFAULT["pad_mask"])), + q name q, q number q, q "" q "]" +} + +# draw a line on silk; thickness is optional (default: line_thickness) +function element_line(x1, y1, x2, y2, thickness) +{ + print " ElementLine[" coord_x(x1), coord_y(y1), coord_x(x2), coord_y(y2), int(either(thickness, DEFAULT["line_thickness"])) "]" +} + +function element_arrow(x1, y1, x2, y2, asize, thickness ,vx,vy,nx,ny,len,xb,yb) +{ + element_line(x1, y1, x2,y2, thickness) + + if (asize == 0) + asize = mil(20) + + vx = x2-x1 + vy = y2-y1 + len = sqrt(vx*vx+vy*vy) + if (len != 0) { + vx /= len + vy /= len + nx = vy + ny = -vx + xb = x2 - vx*asize + yb = y2 - vy*asize +# element_line(x2, y2, xb + 1000, yb + 1000) + element_line(x2, y2, xb + nx*asize/2, yb + ny*asize/2) + element_line(x2, y2, xb - nx*asize/2, yb - ny*asize/2) + element_line(xb - nx*asize/2, yb - ny*asize/2, xb + nx*asize/2, yb + ny*asize/2) + } +} + +# draw a rectangle of silk lines +# omit sides as requested in omit +# if r is non-zero, round corners - omit applies as NW, NW, SW, SE +# if omit includes "arc", corners are "rounded" with lines +function element_rectangle(x1, y1, x2, y2, omit, r, thickness ,tmp,r1,r2) +{ +# order coords for round corners + if (x1 > x2) { + tmp = x1 + x1 = x2 + x2 = tmp + } + if (y1 > y2) { + tmp = y1 + y1 = y2 + y2 = tmp + } + + if (!(omit ~ "left")) { + r1 = (omit ~ "NW") ? 0 : r + r2 = (omit ~ "SW") ? 0 : r + element_line(x1, y1+r1, x1, y2-r2, thickness) + } + if (!(omit ~ "top")) { + r1 = (omit ~ "NW") ? 0 : r + r2 = (omit ~ "NE") ? 0 : r + element_line(x1+r1, y1, x2-r2, y1, thickness) + } + if (!(omit ~ "bottom")) { + r1 = (omit ~ "SE") ? 0 : r + r2 = (omit ~ "SW") ? 0 : r + element_line(x2-r1, y2, x1+r2, y2, thickness) + } + if (!(omit ~ "right")) { + r1 = (omit ~ "SE") ? 0 : r + r2 = (omit ~ "NE") ? 0 : r + element_line(x2, y2-r1, x2, y1+r2, thickness) + } + + if (r > 0) { + if (omit ~ "arc") { + if (!(omit ~ "NW")) + element_line(x1, y1+r, x1+r, y1) + if (!(omit ~ "SW")) + element_line(x1, y2-r, x1+r, y2) + if (!(omit ~ "NE")) + element_line(x2, y1+r, x2-r, y1) + if (!(omit ~ "SE")) + element_line(x2, y2-r, x2-r, y2) + } + else { + if (!(omit ~ "NW")) + element_arc(x1+r, y1+r, r, r, 270, 90) + if (!(omit ~ "SW")) + element_arc(x1+r, y2-r, r, r, 0, 90) + if (!(omit ~ "NE")) + element_arc(x2-r, y1+r, r, r, 180, 90) + if (!(omit ~ "SE")) + element_arc(x2-r, y2-r, r, r, 90, 90) + } + } +} + +# draw a rectangle corners of silk lines, wx and wy long in x and y directions +# omit sides as requested in omit: NW, NW, SW, SE +# corners are always sharp +function element_rectangle_corners(x1, y1, x2, y2, wx, wy, omit, thickness ,tmp) +{ + if (!(omit ~ "NW")) { + element_line(x1, y1, x1+wx, y1, thickness) + element_line(x1, y1, x1, y1+wy, thickness) + } + if (!(omit ~ "NE")) { + element_line(x2-wx, y1, x2, y1, thickness) + element_line(x2, y1, x2, y1+wy, thickness) + } + if (!(omit ~ "SW")) { + element_line(x1, y2, x1+wx, y2, thickness) + element_line(x1, y2-wy, x1, y2, thickness) + } + if (!(omit ~ "SE")) { + element_line(x2-wx, y2, x2, y2, thickness) + element_line(x2, y2-wy, x2, y2, thickness) + } +} + +# draw a line on silk; thickness is optional (default: line_thickness) +function element_arc(cx, cy, rx, ry, a_start, a_delta, thickness) +{ + print " ElementArc[" coord_x(cx), coord_y(cy), int(rx), int(ry), int(a_start), int(a_delta), int(either(thickness, DEFAULT["line_thickness"])) "]" +} + + +# convert coord given in mils to footprint units +function mil(coord) +{ + return coord * 100 +} + +# reverse mil(): converts footprint units back to mil +function rev_mil(coord) +{ + return coord/100 +} + + +# convert coord given in mm to footprint units +function mm(coord) +{ + return coord*3937 +} + +# reverse mm(): converts footprint units back to mm +function rev_mm(coord) +{ + return coord/3937 +} + + +function set_arg_(OUT, key, value, strength) +{ + if (OUT[key, "strength"] > strength) + return + + OUT[key] = value + OUT[key, "strength"] = strength +} + +# set parameter key=value with optioal strength (s_* consts) in array OUT[] +# set only if current strength is stronger than the original value +# if key starts with a "?", use s_weak +# if key is in DEFAULT[], use DEFAULT[] instead of OUT[] +function set_arg(OUT, key, value ,strength) +{ + if (strength == "") + strength = s_explicit + if (key ~ "^[?]") { + sub("^[?]", "", key) + strength = s_weak + } + + if (key in DEFAULT) { + if (DEFAULT[key, "dim"]) + value = parse_dim_(value, 0) + set_arg_(DEFAULT, key, value, strength) + } + else + set_arg_(OUT, key, value, strength) +} + +# Process a generator argument list from arg_names. Save the result in +# array OUT. If mandatory is specified, check whether all mandatory +# parameters are specified +# Both arg_names and mandatory are comma separated list of argument names +function proc_args(OUT, arg_names, mandatory, N,A,M,v,n,key,val,pos) +{ + gsub(" ", "", arg_names) + gsub(" ", "", mandatory) + split(arg_names, N, ",") + v = split(args, A, ",") + +# fill in all named and positional arguments + pos = 1 + for(n = 1; n <= v; n++) { + A[n] = strip(A[n]) + if (A[n] == "") + continue + if (A[n] ~ "=") { +# named + key=A[n] + val=A[n] + sub("=.*", "", key) + sub("^[^=]*=", "", val) + set_arg(OUT, key, val, s_explicit) + } + else { +# positional + if (N[pos] == "") { + error("too many positional arguments at " A[n]) + } + while((N[pos] in OUT) && (N[pos, "strength"] == s_explicit)) pos++ + set_arg(OUT, N[pos], A[n], s_explicit) + pos++ + } + } + +# check whether all mandatory arguments are specified + v = split(mandatory, M, ",") + for(n = 1; n <= v; n++) { + if (!(M[n] in OUT)) { + error("missing argument " M[n] " (or positional " n ")") + exit 1 + } + } +} + +function parse_dim_(h, fallback_mil) +{ + if (h == "") + return "" + if (h ~ "mm$") { + sub("mm", "", h) + return mm(h) + } + if (h ~ "um$") { + sub("um", "", h) + return mm(h)/1000 + } + if (h ~ "nm$") { + sub("nm", "", h) + return mm(h)/1000000 + } + if (h ~ "cm$") { + sub("cm", "", h) + return mm(h)*10 + } + if (h ~ "m$") { + sub("m", "", h) + return mm(h)*1000 + } + if (h ~ "km$") { + sub("km", "", h) + return mm(h)*1000000 + } + + if (h ~ "in$") { + sub("in", "", h) + return mil(h)*1000 + } + if (h ~ "dmil$") { + sub("dmil", "", h) + return mil(h)/10 + } + if (h ~ "cmil$") { + sub("cmil", "", h) + return mil(h)/100 + } + if (h ~ "mil$") { + sub("mil", "", h) + return mil(h) + } + if (fallback_mil) + return mil(h) + else + return h +} + +# Assume h is a dimension and convert it +function parse_dim(h) +{ + return parse_dim_(h, 1) +} + +# Draw a DIP outline: useful for any rectangular package with a little +# half circle centered on the top line +# arcr: radius of the half circle +# xhalf: optional coordinate where the circle should be put +function dip_outline(x1, y1, x2, y2, arcr ,xhalf) +{ + if (xhalf == "") + xhalf=(x1+x2)/2 + + element_rectangle(x1, y1, x2, y2, "top") + element_line(x1, y1, xhalf-arcr, y1) + element_line(xhalf+arcr, y1, x2, y1) + + element_arc(xhalf, y1, arcr, arcr, 0, 180) +} + +# decide whether x is true or false +# returns 1 if true +# returns 0 if false +function tobool(x) +{ + if (x == int(x)) + return (int(x) != 0) + + x = tolower(x) + return (x == "true") || (x == "yes") || (x == "on") +} + +# default pin1 mark on a box +# style: mark style, ":" separated list +# x,y: the coordinates of the origin corner (top-left) +# half: half the stepping of the pin grid - the size of the mark +# step: optional size of the external arrow or square (defaults to 2*half) +function silkmark(style, x, y, half, step, S,n,v) +{ + if (step == "") + step = half*2 + + v = split(style, S, ":") + + for(n = 1; n <= v; n++) { + if (S[n] == "angled") { + element_line(x+half, y, x, y+half) + } + else if (S[n] == "square") { + element_line(x, y+step, x+2*half, y+step) + element_line(x+step, y, x+2*half, y+step) + } + else if ((S[n] == "external") || (S[n] == "externalx")) { + element_line(x, y+half, x-step+half, y+half/2) + element_line(x, y+half, x-step+half, y+half*1.5) + element_line(x-step+half, y+half/2, x-step+half, y+half*1.5) + } + else if (S[n] == "externaly") { + element_line(x+half, y, x-half/2+half, y-step+half) + element_line(x+half, y, x+half/2+half, y-step+half) + element_line(x-half/2+half, y-step+half, x+half/2+half, y-step+half) + } + else if (S[n] == "external45") { + element_line(x, y, x-half, y-half/3) + element_line(x, y, x-half/3, y-half) + element_line(x-half, y-half/3, x-half/3, y-half) + } + else if (S[n] == "arc") { + element_arc(x, y, step/2, step/2, 180, 270) + } + else if (S[n] == "circle") { + element_arc(x, y, step/2, step/2, 0, 360) + } + else if (S[n] == "dot") { + element_arc(x-step/2, y-step/2, step/4, step/4, 0, 360) + } + else if ((S[n] != "none") && (S[n] != "")) { + error("invalid silkmark parameter: " S[n]) + } + } +} + +# output a dimension specification between x1;y1 and x2;y2, text distance at dist +# for a name,value pair +# if name is empty, only value is printed +# if value is empty, it's calculated +# if only name should be printed, value should be "!" +# if dist starts with a "@", it's the absolute coordinate of the center of the dim line (text base), else it's relative distance from the measured line +function dimension(x1, y1, x2, y2, dist, name, value, vx,vy) +{ + print "#dimension", coord_x(x1), coord_y(y1), coord_x(x2), coord_y(y2), dist, name, value +} + +function help_extract(SEEN, fn, dirn, OVER, IGN, WANT,tmp,key,val,i,skip) +{ + if (fn in SEEN) + return + SEEN[fn]++ + print "#@@info-gen-extract " fn + close(fn) + while((getline line < fn) > 0) { + if (line ~ "^#@@include") { + sub("^#@@include[ \t]*", "", line) + tmp = dirn "/" line + WANT[tmp]++ + } + else if (line ~ "^#@@over@ignore") { + key = line + sub("^#@@over@ignore:", "", key) + sub(" .*", "", key) + IGN[key] = 1 + } + else if (line ~ "^#@@over@") { + key = line + sub("^#@@over@", "", key) + val = "#@@" key + sub(" .*", "", key) + OVER[key] = val + } + else if (line ~ "^#@@") { + key = line + sub("^#@@", "", key) + sub(" .*", "", key) + skip = 0 + for(i in IGN) { + if (key ~ i) + skip = 1 + } + if (skip) + continue + if (key in OVER) { + print OVER[key] + OVER[key "::PRINTED"] = 1 + } + else + print line + } + } + close(fn) + for(tmp in WANT) + help_extract(SEEN, tmp, dirn, OVER, IGN) +} + +function help_print( SEEN, OVER, dirn, k) +{ + print "#@@info-generator pcblib common.awk" + dirn = genfull + sub("/[^/]*$", "", dirn) + help_extract(SEEN, genfull, dirn, OVER) + for(k in OVER) { + if (!(k ~ "::PRINTED$") && !((k "::PRINTED") in OVER)) + print OVER[k] + } +} + +function help_auto() +{ + if ((args ~ "^--help") || (args ~ ",[ \t]*--help")) { + help_print() + exit(0) + } +} Index: tags/2.3.0/pcblib/parametric/common_subc.awk =================================================================== --- tags/2.3.0/pcblib/parametric/common_subc.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/common_subc.awk (revision 33253) @@ -0,0 +1,1205 @@ +#@@param:pin_ringdia pin's copper ring (annulus) outer diameter (in mil by default, mm suffix can be used) +#@@optional:pin_ringdia +#@@dim:pin_ringdia + +#@@param:pin_clearance pin's copper clearance diameter (in mil by default, mm suffix can be used) +#@@optional:pin_clearance +#@@dim:pin_clearance + +#@@param:pin_mask pin's solder mask diameter (in mil by default, mm suffix can be used) +#@@optional:pin_mask +#@@dim:pin_mask + +#@@param:pin_mask_offs how much bigger (+) or smaller (-) the mask opening should be compared to copper (in mil by default, mm suffix can be used) +#@@optional:pin_mask_offs +#@@dim:pin_mask_offs + +#@@param:pin_mask_ratio pin mask opening should be copper size * this ratio (numbers larger than 1 mean opening with a gap, 1.00 means exactly as big as the copper shape) +#@@optional:pin_mask_ratio +#@@dim:pin_mask_ratio + +#@@param:pin_drill copper pin's drill diameter (in mil by default, mm suffix can be used) +#@@optional:pin_drill +#@@dim:pin_drill + +#@@param:pad_thickness width of pads (in mil by default, mm suffix can be used) +#@@optional:pad_thickness +#@@dim:pad_thickness + +#@@param:pad_clearance copper clearance around the pad (in mil by default, mm suffix can be used) +#@@optional:pad_clearance +#@@dim:pad_clearance + +#@@param:pad_mask pin's solder mask (in mil by default, mm suffix can be used) +#@@optional:pad_mask +#@@dim:pad_mask + +#@@param:pad_mask_offs how much bigger (+) or smaller (-) the mask opening should be compared to copper (in mil by default, mm suffix can be used) +#@@optional:pad_mask_offs +#@@dim:pad_mask_offs + +#@@param:pad_mask_ratio pad mask opening should be copper size * this ratio (numbers larger than 1 mean opening with a gap, 1.00 means exactly as big as the copper shape) +#@@optional:pad_mask_ratio +#@@dim:pad_mask_ratio + +#@@param:pad_paste pad's paste line thickness (in mil by default, mm suffix can be used) +#@@optional:pad_paste +#@@dim:pad_paste + +#@@param:pad_paste_offs how much bigger (+) or smaller (-) the paste should be compared to copper (in mil by default, mm suffix can be used) +#@@optional:pad_paste_offs +#@@dim:pad_paste_offs + +#@@param:pad_paste_ratio pad paste should be copper size * this ratio (numbers smaller than 1 mean smaller paste, 1.00 means exactly as big as the copper shape) +#@@optional:pad_paste_ratio +#@@dim:pad_paste_ratio + +#@@param:line_thickness silk line thickness (in mil by default, mm suffix can be used) +#@@optional:line_thickness +#@@dim:line_thickness + +BEGIN { + q="\"" + + DEFAULT["pin_ringdia"] = mil(80) + DEFAULT["pin_ringdia", "dim"] = 1 + + DEFAULT["pin_clearance"] = mil(50) + DEFAULT["pin_clearance", "dim"] = 1 + + DEFAULT["pin_mask"] = mil(86) + DEFAULT["pin_mask", "dim"] = 1 + DEFAULT["pin_mask_offs"] = "" # use copper size + DEFAULT["pin_mask_offs", "dim"] = 1 + DEFAULT["pin_mask_ratio"] = "" # use copper size + + DEFAULT["pin_drill"] = mm(1) + DEFAULT["pin_drill", "dim"] = 1 + + DEFAULT["line_thickness"] = mil(10) + DEFAULT["line_thickness", "dim"] = 1 + + DEFAULT["pad_thickness"] = mil(20) + DEFAULT["pad_thickness", "dim"] = 1 + DEFAULT["pad_clearance"] = mil(10) + DEFAULT["pad_clearance", "dim"] = 1 + DEFAULT["pad_mask"] = mil(30) + DEFAULT["pad_mask", "dim"] = 1 + DEFAULT["pad_mask_offs"] = "" # use copper size + DEFAULT["pad_mask_offs", "dim"] = 1 + DEFAULT["pad_mask_ratio"] = "" # use copper size + DEFAULT["pad_paste"] = "" # use copper size + DEFAULT["pad_paste", "dim"] = 1 + DEFAULT["pad_paste_offs"] = "" # use copper size + DEFAULT["pad_paste_offs", "dim"] = 1 + DEFAULT["pad_paste_ratio"] = "" # use copper size + + DEFAULT["pin_flags"] = "__auto" + + s_default=1 + s_weak=2 + s_explicit=3 + + offs_x = 0 + offs_y = 0 + objid = 1 + proto_next_id = 0 + + pi=3.141592654 + + NL = "\n" + +# minuid + for(n = 32; n < 127; n++) + ORD[sprintf("%c", n)] = n + BASE64 = "ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz0123456789+/" +} + +function minuid_add(SUM, s ,n,v,c1,c2) +{ + v = length(s) + for(n = 1; n <= v; n++) + SUM[(n-1) % 20] += ORD[substr(s, n, 1)]-32 +} + +function minuid_str(SUM, s ,n) +{ + s = "Prm/" + for(n = 0; n < 20; n++) + s = s substr(BASE64, SUM[n] % 64, 1) + return s +} + +# Throw an error and exit +function error(msg) +{ + print "Error: " msg > "/dev/stderr" + exit 1 +} + +# return a if it is not empty, else return b +function either(a, b) +{ + return a != "" ? a : b +} + +# strip leading/trailing whitespaces +function strip(s) +{ + sub("^[ \t\r\n]*", "", s) + sub("[ \t\r\n]*$", "", s) + return s +} + +function lht_str(s) +{ + if (s ~ "[^A-Za-z0-9 _-]") { + gsub("}", "\\}", s) + return "{" s "}" + } + return s +} + +function unit(coord) +{ + if (coord == "") + coord = 0 + if (base_unit_mm) + return coord "mm" + return coord "mil" +} + +function subc_text(layer, x, y, str, scale, rot, flags, attributes ,s) +{ + + s = s " ha:text." (++objid) "{" NL + s = s " scale = " either(scale, 100) NL + if (attributes != "") + s = s " ha:attributes {" attributes "}" NL + s = s " x = " unit(x) NL + s = s " y = " unit(y) NL + s = s " rot = " either(rot, 0) NL + if (str == "") + str = "%a.parent.refdes%" + s = s " string = " str NL + s = s " fid = 0" NL + s = s " ha:flags {" flags "}" NL + s = s " }" NL + + LAYER[layer] = LAYER[layer] NL s +} + +function subc_line(layer, x1, y1, x2, y2, thick, clr, flags, attributes ,s) +{ + s = s " ha:line." (++objid) " {" NL + s = s " x1 = " unit(x1) NL + s = s " y1 = " unit(y1) NL + s = s " x2 = " unit(x2) NL + s = s " y2 = " unit(y2) NL + s = s " thickness = " unit(either(thick, DEFAULT["line_thickness"])) NL + s = s " clearance = " unit(either(clr, 0)) NL + if (attributes != "") + s = s " ha:attributes {" attributes "}" NL + s = s " ha:flags {" flags "}" NL + s = s " }" NL + + LAYER[layer] = LAYER[layer] NL s +} + +function subc_arc(layer, cx, cy, r, a_start, a_delta, thick, clr, flags, attributes ,s) +{ + s = s " ha:arc." (++objid) " {" NL + s = s " x = " unit(cx) NL + s = s " y = " unit(cy) NL + s = s " astart = " a_start NL + s = s " adelta = " a_delta NL + s = s " thickness = " unit(either(thick, DEFAULT["line_thickness"])) NL + s = s " clearance = " unit(either(clr, 0)) NL + s = s " width = " unit(r) NL + s = s " height = " unit(r) NL + if (attributes != "") + s = s " ha:attributes {" attributes "}" NL + s = s " ha:flags {" flags "}" NL + s = s " }" NL + + LAYER[layer] = LAYER[layer] NL s +} + +function subc_rect(layer, x1, y1, x2, y2, clearance, flags, attributes ,s) +{ + w = w/2 + h = h/2 + s = s " ha:polygon." (++objid) " {" NL + s = s " clearance=" unit(clearance) NL + s = s " li:geometry {" NL + s = s " ta:contour {" NL + s = s " { " unit(x1) "; " unit(y1) " }" NL + s = s " { " unit(x2) "; " unit(y1) " }" NL + s = s " { " unit(x2) "; " unit(y2) " }" NL + s = s " { " unit(x1) "; " unit(y2) " }" NL + s = s " }" NL + s = s " }" NL + s = s " ha:attributes {" attributes "}" NL + s = s " ha:flags {" flags "}" NL + s = s " }" NL + + LAYER[layer] = LAYER[layer] NL s +} + +# POLY[] is an array indexed between 0 to 2*N-1 for a polygon of N +# vertices, packed as x0;y0;x1;y1;x2;y2 ... xN;yN. The usual pcb-rnd +# polygon rules apply: at least 3 vertices, no self-intersection. This +# call does not make any attempt on cheking polygon validity. +function subc_poly(layer, POLY, clearance, flags, attributes ,s,n) +{ + w = w/2 + h = h/2 + s = s " ha:polygon." (++objid) " {" NL + s = s " clearance=" unit(clearance) NL + s = s " li:geometry {" NL + s = s " ta:contour {" NL + for(n = 0; (n in POLY); n += 2) + s = s " { " unit(POLY[n]) "; " unit(POLY[n+1]) " }" NL + s = s " }" NL + s = s " }" NL + s = s " ha:attributes {" attributes "}" NL + s = s " ha:flags {" flags "}" NL + s = s " }" NL + + LAYER[layer] = LAYER[layer] NL s +} + +# reset a polygon so it has no vertices +function poly_reset(POLY ,n) +{ + for(n = 0; (n in POLY); n += 2) + delete POLY[n] + POLY["len"] = 0 +} + +# append x;y to the end of a polygon's vertex list +function poly_append(POLY, x, y) +{ + POLY[POLY["len"]++] = x; + POLY[POLY["len"]++] = y; +} + +# start generating a subcircuit +function subc_begin(footprint, refdes, refdes_x, refdes_y, refdes_dir, ATTR ,a) +{ + print "li:pcb-rnd-subcircuit-v6 {" + print " ha:subc." (++objid) "{" + print " ha:attributes {" + print " footprint = " lht_str(footprint) + if (refdes != "") + print " refdes = " lht_str(refdes) + for(a in ATTR) + print " " a " = " lht_str(ATTR[a]); + print " }" + + + subc_text("top-silk", refdes_x, refdes_y, "%a.parent.refdes%", 100, text_dir, "dyntext = 1;floater=1;") + LAYER_TYPE["subc-aux"] = "top-misc-virtual" + subc_line("subc-aux", -offs_x, -offs_y, -offs_x + mm(1), -offs_y, mm(0.1), 0, "", "subc-role = x"); + subc_line("subc-aux", -offs_x, -offs_y, -offs_x, -offs_y + mm(1), mm(0.1), 0, "", "subc-role = y"); + subc_line("subc-aux", -offs_x, -offs_y, -offs_x, -offs_y, mm(0.1), 0, "", "subc-role = origin"); +} + +# generate subcircuit footers +function subc_end( layer,n,v,L,lt,UID) +{ + minuid_add(UID, tolower(gen)) + for(n in P) { + minuid_add(UID, tolower(n)) + minuid_add(UID, " " P[n]) + } + print " ha:data {" + print " li:padstack_prototypes {" + for(n = 0; n < proto_next_id; n++) { + if (PROTO_COMMENT[n] != "") + print PROTO_COMMENT[n] + print " ha:ps_proto_v6." n " {" + print PROTO[n] + print " }" + } + print " }" + +# global objects (padstack refs) + print " li:objects {" + print globals + print " }" + +# layers and layer objects + print " li:layers {" + for(layer in LAYER) { + lt = either(LAYER_TYPE[layer], layer) + v = split(lt, L, "-") + print " ha:" layer " {" + print " lid = 0" + print " ha:type {" + for(n = 1; n <= v; n++) + print " " L[n] " = 1" + print " }" + print " li:objects {" + print LAYER[layer] + print " }" + print " ha:combining {" + print " }" + print " }" + } + print " }" + print " }" + print " uid = " minuid_str(UID) + print " }" + print "}" +} + +function subc_proto_alloc() +{ + return proto_next_id++ +} + +function subc_pstk_add_hole(proto, dia, plated, htop, hbottom ,s) +{ + s = s " hdia = " unit(dia) NL + s = s " hplated = " int(plated) NL + s = s " htop = " int(htop) NL + s = s " hbottom = " int(hbottom) NL + PROTO[proto] = PROTO[proto] s + PROTO_HOLE[proto] = dia +} + +function subc_pstk_no_hole(proto ,s) +{ + s = s " hdia = 0; hplated = 0; htop = 0; hbottom = 0" NL + PROTO[proto] = PROTO[proto] s +} + +function subc_pstk_shape_layer(layer ,s,L,v,n) +{ + v = split(layer, L, "-") + s = s " ha:layer_mask {" NL + for(n = 1; n <= v; n++) + s = s " " L[n] " = 1" NL + s = s " }" NL + s = s " ha:combining {" NL + if (layer ~ "mask") + s = s " sub = 1" NL + if ((layer ~ "mask") || (layer ~ "paste")) + s = s " auto = 1" NL + s = s " }" NL + return s +} + +function subc_pstk_add_shape_circ(proto, layer, x, y, dia ,s) +{ + s = s " ha:ps_shape_v4 {" NL + s = s " clearance = 0" NL + s = s " ha:ps_circ {" NL + s = s " x = " unit(x) NL + s = s " y = " unit(y) NL + s = s " dia = " unit(dia) NL + s = s " }" NL + s = s subc_pstk_shape_layer(layer) + s = s " }" NL + PROTO[proto] = PROTO[proto] s +} + +function subc_pstk_add_shape_square(proto, layer, x, y, sx, sy ,s) +{ + sx = sx / 2 + sy = sy / 2 + s = s " ha:ps_shape_v4 {" NL + s = s " clearance = 0" NL + s = s " li:ps_poly {" NL + s = s " " unit(x - sx) ";" unit(y - sy) "; " unit(x + sx) ";" unit(y - sy) ";" NL + s = s " " unit(x + sx) ";" unit(y + sy) "; " unit(x - sx) ";" unit(y + sy) ";" NL + s = s " }" NL + s = s subc_pstk_shape_layer(layer) + s = s " }" NL + PROTO[proto] = PROTO[proto] s +} + +function subc_pstk_add_shape_square_corners(proto, layer, x1, y1, x2, y2 ,s) +{ + sx = sx / 2 + sy = sy / 2 + s = s " ha:ps_shape_v4 {" NL + s = s " clearance = 0" NL + s = s " li:ps_poly {" NL + s = s " " unit(x1) ";" unit(y1) "; " unit(x2) ";" unit(y1) ";" NL + s = s " " unit(x2) ";" unit(y2) "; " unit(x1) ";" unit(y2) ";" NL + s = s " }" NL + s = s subc_pstk_shape_layer(layer) + s = s " }" NL + PROTO[proto] = PROTO[proto] s +} + +function subc_pstk_add_shape_line(proto, layer, x1, y1, x2, y2, thick ,s) +{ + s = s " ha:ps_shape_v4 {" NL + s = s " clearance = 0" NL + s = s " ha:ps_line {" NL + s = s " x1=" unit(x1) "; y1=" unit(y1) "; x2=" unit(x2) "; y2=" unit(y2) ";" NL + s = s " thickness=" unit(thick) "; square=0" NL + s = s " }" NL + s = s subc_pstk_shape_layer(layer) + s = s " }" NL + PROTO[proto] = PROTO[proto] s +} + +# POLY[] is an array indexed between 0 to 2*N-1 for a polygon of N +# vertices, packed as x0;y0;x1;y1;x2;y2 ... xN;yN. The usual pcb-rnd +# polygon rules apply: at least 3 vertices, no self-intersection. This +# call does not make any attempt on cheking polygon validity. +function subc_pstk_add_shape_poly(proto, layer, POLY ,s,n) +{ + s = s " ha:ps_shape_v4 {" NL + s = s " clearance = 0" NL + s = s " li:ps_poly {" NL + for(n = 0; (n in POLY); n += 2) + s = s " { " unit(POLY[n]) "; " unit(POLY[n+1]) " }" NL + s = s " }" NL + s = s subc_pstk_shape_layer(layer) + s = s " }" NL + PROTO[proto] = PROTO[proto] s +} + +function subc_proto_create_pin_round(drill_dia, ring_dia, mask_dia ,proto) +{ + proto = subc_proto_alloc() + subc_pstk_add_hole(proto, either(drill_dia, DEFAULT["pin_drill"]), 1) + + PROTO_COMMENT[proto] = "# Round plated through hole " unit(ring_dia) "/" unit(drill_dia) + PROTO[proto] = PROTO[proto] " li:shape {" NL + + ring_dia = either(ring_dia, DEFAULT["pin_ringdia"]) + subc_pstk_add_shape_circ(proto, "top-copper", x, y, ring_dia) + subc_pstk_add_shape_circ(proto, "intern-copper", x, y, ring_dia) + subc_pstk_add_shape_circ(proto, "bottom-copper", x, y, ring_dia) + + mask_dia = pin_mask(ring_dia, mask_dia) + subc_pstk_add_shape_circ(proto, "top-mask", x, y, mask_dia) + subc_pstk_add_shape_circ(proto, "bottom-mask", x, y, mask_dia) + + PROTO[proto] = PROTO[proto] " }" NL + return proto +} + +function subc_proto_create_pin_square(drill_dia, ring_span, mask_span ,proto) +{ + proto = subc_proto_alloc() + subc_pstk_add_hole(proto, either(drill_dia, DEFAULT["pin_drill"]), 1) + + PROTO_COMMENT[proto] = "# Square plated through hole " unit(ring_dia) "/" unit(drill_dia) + PROTO[proto] = PROTO[proto] " li:shape {" NL + + ring_span = either(ring_span, DEFAULT["pin_ringdia"]) + subc_pstk_add_shape_square(proto, "top-copper", x, y, ring_span, ring_span) + subc_pstk_add_shape_square(proto, "intern-copper", x, y, ring_span, ring_span) + subc_pstk_add_shape_square(proto, "bottom-copper", x, y, ring_span, ring_span) + + mask_span = pin_mask(ring_span, mask_dia) + subc_pstk_add_shape_square(proto, "top-mask", x, y, mask_span, mask_span) + subc_pstk_add_shape_square(proto, "bottom-mask", x, y, mask_span, mask_span) + PROTO[proto] = PROTO[proto] " }" NL + + return proto +} + +function paste_or_mask_abs(copper, absval, offsval, ratio, prefix) +{ + if (absval != "") + return absval + if (offsval != 0) + return copper+offsval + if (ratio != 0) + return copper*ratio + if ((DEFAULT[prefix] != "") && (DEFAULT[prefix] != "-")) + return DEFAULT[prefix] + if (DEFAULT[prefix "_offs"] != "") + return copper+DEFAULT[prefix "_offs"]*2 + if (DEFAULT[prefix "_ratio"] != "") + return copper*DEFAULT[prefix "_ratio"] + return copper +} + +function pad_paste(copper, absval, offsval, ratio) +{ + return paste_or_mask_abs(copper, absval, offsval, ratio, "pad_paste") +} + +function pad_mask(copper, absval, offsval, ratio) +{ + return paste_or_mask_abs(copper, absval, offsval, ratio, "pad_mask") +} + +function pin_mask(copper, absval, offsval, ratio) +{ + return paste_or_mask_abs(copper, absval, offsval, ratio, "pin_mask") +} + +function pad_paste_offs(offsval ,copper) +{ + copper = DEFAULT["pad_thickness"] + return paste_or_mask_abs(copper, "", offsval, "", "pad_paste") - copper +} + +function pad_mask_offs(offsval ,copper) +{ + copper = DEFAULT["pad_thickness"] + return paste_or_mask_abs(copper, "", offsval, "", "pad_mask") - copper +} + + +function subc_proto_create_pad_sqline(x1, x2, thick, mask, paste ,proto,m,p) +{ + proto = subc_proto_alloc() + + thick = either(thick, DEFAULT["pad_thickness"]) + + subc_pstk_no_hole(proto) + + PROTO_COMMENT[proto] = "# Square smd pad " x2-x1 " * " thick + PROTO[proto] = PROTO[proto] " li:shape {" NL + + subc_pstk_add_shape_square_corners(proto, "top-copper", x1-thick/2, -thick/2, x2+thick/2, thick/2) + + m = (pad_mask(thick, mask)-thick)/2 + subc_pstk_add_shape_square_corners(proto, "top-mask", x1-thick/2-m, -thick/2-m, x2+thick/2+m, thick/2+m) + + p = (pad_paste(thick, paste)-thick)/2 + subc_pstk_add_shape_square_corners(proto, "top-paste", x1-thick/2-p, -thick/2-p, x2+thick/2+p, thick/2+p) + + PROTO[proto] = PROTO[proto] " }" NL + + return proto +} + +function subc_proto_create_pad_line(x1, x2, thick, mask, paste ,proto,m,p) +{ + proto = subc_proto_alloc() + + thick = either(thick, parse_dim(DEFAULT["pad_thickness"])) + + subc_pstk_no_hole(proto) + + PROTO_COMMENT[proto] = "# Square smd pad " x2-x1 " * " thick + PROTO[proto] = PROTO[proto] " li:shape {" NL + + subc_pstk_add_shape_line(proto, "top-copper", x1, 0, x2, 0, thick) + subc_pstk_add_shape_line(proto, "top-mask", x1, 0, x2, 0, pad_mask(thick, mask)) + subc_pstk_add_shape_line(proto, "top-paste", x1, 0, x2, 0, pad_paste(thick, paste)) + + PROTO[proto] = PROTO[proto] " }" NL + + return proto +} + +function subc_proto_create_pad_rect(w, h, mask_offs, paste_offs ,proto,m,p) +{ + proto = subc_proto_alloc() + + subc_pstk_no_hole(proto) + + PROTO_COMMENT[proto] = "# Square smd pad " w " * " h + PROTO[proto] = PROTO[proto] " li:shape {" NL + + w = w/2 + h = h/2 + + subc_pstk_add_shape_square_corners(proto, "top-copper", -w, -h, +w, +h) + + if (mask_offs != "none") { + m = pad_paste_offs(w, mask_offs) / 2 + subc_pstk_add_shape_square_corners(proto, "top-mask", -w-m, -h-m, +w+m, +h+m) + } + + if (paste_offs != "none") { + p = pad_paste_offs(w, paste_offs) / 2 + subc_pstk_add_shape_square_corners(proto, "top-paste", -w-p, -h-p, +w+p, +h+p) + } + + PROTO[proto] = PROTO[proto] " }" NL + + return proto +} + + +function subc_proto_create_pad_circle(dia, mask_dia, paste_dia ,proto) +{ + proto = subc_proto_alloc() + subc_pstk_no_hole(proto) + + dia = either(dia, DEFAULT["pad_dia"]) + + PROTO_COMMENT[proto] = "# Circular smd pad " unit(dia) + PROTO[proto] = PROTO[proto] " li:shape {" NL + + subc_pstk_add_shape_circ(proto, "top-copper", 0, 0, dia) + + mask_dia = either(mask_dia, DEFAULT["pad_mask_dia"]) + subc_pstk_add_shape_circ(proto, "top-mask", 0, 0, mask_dia) + + paste_dia = either(mask_dia, DEFAULT["pad_paste_dia"]) + subc_pstk_add_shape_circ(proto, "top-mask", 0, 0, paste_dia) + + PROTO[proto] = PROTO[proto] " }" NL + return proto +} + +# generate a padstack reference +function subc_pstk(proto, x, y, rot, termid, name, clearance, s) +{ + if (termid == "") + termid = ++pin_number + + s = s " ha:padstack_ref." (++objid) " {" NL + s = s " proto = " proto NL + s = s " x = " unit(x) NL + s = s " y = " unit(y) NL + s = s " rot = " rot+0 NL + s = s " smirror = 0; xmirror = 0" NL + s = s " clearance = " unit(either(clearance, (PROTO_HOLE[proto] > 0 ? DEFAULT["pin_clearance"] : DEFAULT["pad_clearance"]))/2) NL + s = s " ha:attributes {" NL + s = s " term = " termid NL + if (name != "") + s = s " name = 1" NL + s = s " }" NL + s = s " li:thermal { }" NL + s = s " ha:flags { clearline = 1; }" NL + s = s " }" NL + + globals = globals NL s +} + +# draw element pad +function subc_pad(x1, y1, x2, y2, thickness, number, flags, clearance, mask, name) +{ + print " Pad[", x1, y1, x2, y2, int(either(thickness, DEFAULT["pad_thickness"])), + int(either(clearance, DEFAULT["pad_clearance"])), int(either(mask, DEFAULT["pad_mask"])), + q name q, q number q, q flags q "]" +} + +# draw element pad - no thickness, but exact corner coordinates given +function subc_pad_rectangle(x1, y1, x2, y2, number, flags, clearance, mask, name, th,dx,dy,cx,cy) +{ + if (x2 < x1) { + th = x2 + x2 = x1 + x1 = th + } + if (y2 < y1) { + th = y2 + y2 = y1 + y1 = th + } + + dx = x2-x1 + dy = y2-y1 + + if (dx >= dy) { + th = dy + cy = (y1+y2)/2 + + print " Pad[", x1+th/2, cy, x2-th/2, cy, th, + int(either(clearance, DEFAULT["pad_clearance"])), int(either(mask, DEFAULT["pad_mask"])), + q name q, q number q, q flags q "]" + } + else { + th = dx + cx = (x1+x2)/2 + + print " Pad[", cx, y1+th/2, cx, y2-th/2, th, + int(either(clearance, DEFAULT["pad_clearance"])), int(either(mask, DEFAULT["pad_mask"])), + q name q, q number q, q flags q "]" + } +} + +# draw element pad circle +function subc_pad_circle(x1, y1, radius, number, clearance, mask, name) +{ + print " Pad[", x1, y1, x1, y1, int(either(radius, DEFAULT["pad_thickness"])), + int(either(clearance, DEFAULT["pad_clearance"])), int(either(mask, DEFAULT["pad_mask"])), + q name q, q number q, q "" q "]" +} + +function subc_arrow(layer, x1, y1, x2, y2, asize, thickness ,vx,vy,nx,ny,len,xb,yb) +{ + subc_line(layer, x1, y1, x2,y2, thickness) + + if (asize == 0) + asize = mil(20) + + vx = x2-x1 + vy = y2-y1 + len = sqrt(vx*vx+vy*vy) + if (len != 0) { + vx /= len + vy /= len + nx = vy + ny = -vx + xb = x2 - vx*asize + yb = y2 - vy*asize +# subc_line(layer, x2, y2, xb + 1000, yb + 1000) + subc_line(layer, x2, y2, xb + nx*asize/2, yb + ny*asize/2) + subc_line(layer, x2, y2, xb - nx*asize/2, yb - ny*asize/2) + subc_line(layer, xb - nx*asize/2, yb - ny*asize/2, xb + nx*asize/2, yb + ny*asize/2) + } +} + +# draw a rectangle of silk lines +# omit sides as requested in omit +# if r is non-zero, round corners - omit applies as NW, NW, SW, SE +# if omit includes "arc", corners are "rounded" with lines +function subc_rectangle(layer, x1, y1, x2, y2, omit, r, thickness ,tmp,r1,r2) +{ +# order coords for round corners + if (x1 > x2) { + tmp = x1 + x1 = x2 + x2 = tmp + } + if (y1 > y2) { + tmp = y1 + y1 = y2 + y2 = tmp + } + + if (!(omit ~ "left")) { + r1 = (omit ~ "NW") ? 0 : r + r2 = (omit ~ "SW") ? 0 : r + subc_line(layer, x1, y1+r1, x1, y2-r2, thickness) + } + if (!(omit ~ "top")) { + r1 = (omit ~ "NW") ? 0 : r + r2 = (omit ~ "NE") ? 0 : r + subc_line(layer, x1+r1, y1, x2-r2, y1, thickness) + } + if (!(omit ~ "bottom")) { + r1 = (omit ~ "SE") ? 0 : r + r2 = (omit ~ "SW") ? 0 : r + subc_line(layer, x2-r1, y2, x1+r2, y2, thickness) + } + if (!(omit ~ "right")) { + r1 = (omit ~ "SE") ? 0 : r + r2 = (omit ~ "NE") ? 0 : r + subc_line(layer, x2, y2-r1, x2, y1+r2, thickness) + } + + if (r > 0) { + if (omit ~ "arc") { + if (!(omit ~ "NW")) + subc_line(layer, x1, y1+r, x1+r, y1) + if (!(omit ~ "SW")) + subc_line(layer, x1, y2-r, x1+r, y2) + if (!(omit ~ "NE")) + subc_line(layer, x2, y1+r, x2-r, y1) + if (!(omit ~ "SE")) + subc_line(layer, x2, y2-r, x2-r, y2) + } + else { + if (!(omit ~ "NW")) + subc_arc(layer, x1+r, y1+r, r, 270, 90) + if (!(omit ~ "SW")) + subc_arc(layer, x1+r, y2-r, r, 0, 90) + if (!(omit ~ "NE")) + subc_arc(layer, x2-r, y1+r, r, 180, 90) + if (!(omit ~ "SE")) + subc_arc(layer, x2-r, y2-r, r, 90, 90) + } + } +} + +# draw a rectangle corners of silk lines, wx and wy long in x and y directions +# omit sides as requested in omit: NW, NW, SW, SE +# corners are always sharp +function subc_rectangle_corners(layer, x1, y1, x2, y2, wx, wy, omit, thickness ,tmp) +{ + if (!(omit ~ "NW")) { + subc_line(layer, x1, y1, x1+wx, y1, thickness) + subc_line(layer, x1, y1, x1, y1+wy, thickness) + } + if (!(omit ~ "NE")) { + subc_line(layer, x2-wx, y1, x2, y1, thickness) + subc_line(layer, x2, y1, x2, y1+wy, thickness) + } + if (!(omit ~ "SW")) { + subc_line(layer, x1, y2, x1+wx, y2, thickness) + subc_line(layer, x1, y2-wy, x1, y2, thickness) + } + if (!(omit ~ "SE")) { + subc_line(layer, x2-wx, y2, x2, y2, thickness) + subc_line(layer, x2, y2-wy, x2, y2, thickness) + } +} + +# convert coord given in mils to footprint units +function mil(coord) +{ + if (base_unit_mm) + return coord / 39.3701 + else + return coord +} + +# reverse mil(): converts footprint units back to mil +function rev_mil(coord) +{ + if (base_unit_mm) + return coord * 39.3701 + else + return coord +} + + +# convert coord given in mm to footprint units +function mm(coord) +{ + if (base_unit_mm) + return coord + else + return coord * 39.3701 +} + +# reverse mm(): converts footprint units back to mm +function rev_mm(coord) +{ + if (base_unit_mm) + return coord + else + return coord / 39.3701 +} + + +function set_arg_(OUT, key, value, strength) +{ + if (OUT[key, "strength"] > strength) + return + + OUT[key] = value + OUT[key, "strength"] = strength +} + +# set parameter key=value with optioal strength (s_* consts) in array OUT[] +# set only if current strength is stronger than the original value +# if key starts with a "?", use s_weak +# if key is in DEFAULT[], use DEFAULT[] instead of OUT[] +function set_arg(OUT, key, value ,strength) +{ + if (strength == "") + strength = s_explicit + if (key ~ "^[?]") { + sub("^[?]", "", key) + strength = s_weak + } + + if (key in DEFAULT) { + if (DEFAULT[key, "dim"]) + value = parse_dim_(value, 0) + set_arg_(DEFAULT, key, value, strength) + } + else + set_arg_(OUT, key, value, strength) +} + +# Process a generator argument list from arg_names. Save the result in +# array OUT. If mandatory is specified, check whether all mandatory +# parameters are specified +# Both arg_names and mandatory are comma separated list of argument names +function proc_args(OUT, arg_names, mandatory, N,A,M,v,n,key,val,pos) +{ + gsub(" ", "", arg_names) + gsub(" ", "", mandatory) + split(arg_names, N, ",") + v = split(args, A, ",") + +# fill in all named and positional arguments + pos = 1 + for(n = 1; n <= v; n++) { + A[n] = strip(A[n]) + if (A[n] == "") + continue + if (A[n] ~ "=") { +# named + key=A[n] + val=A[n] + sub("=.*", "", key) + sub("^[^=]*=", "", val) + set_arg(OUT, key, val, s_explicit) + } + else { +# positional + if (N[pos] == "") { + error("too many positional arguments at " A[n]) + } + while((N[pos] in OUT) && (N[pos, "strength"] == s_explicit)) pos++ + set_arg(OUT, N[pos], A[n], s_explicit) + pos++ + } + } + +# check whether all mandatory arguments are specified + v = split(mandatory, M, ",") + for(n = 1; n <= v; n++) { + if (!(M[n] in OUT)) { + error("missing argument " M[n] " (or positional " n ")") + exit 1 + } + } +} + +function parse_dim_(h, fallback_mil) +{ + if (h == "") + return "" + if (h ~ "mm$") { + sub("mm", "", h) + return mm(h) + } + if (h ~ "um$") { + sub("um", "", h) + return mm(h)/1000 + } + if (h ~ "nm$") { + sub("nm", "", h) + return mm(h)/1000000 + } + if (h ~ "cm$") { + sub("cm", "", h) + return mm(h)*10 + } + if (h ~ "m$") { + sub("m", "", h) + return mm(h)*1000 + } + if (h ~ "km$") { + sub("km", "", h) + return mm(h)*1000000 + } + + if (h ~ "in$") { + sub("in", "", h) + return mil(h)*1000 + } + if (h ~ "dmil$") { + sub("dmil", "", h) + return mil(h)/10 + } + if (h ~ "cmil$") { + sub("cmil", "", h) + return mil(h)/100 + } + if (h ~ "mil$") { + sub("mil", "", h) + return mil(h) + } + if (fallback_mil) + return mil(h) + else + return h +} + +# Assume h is a dimension and convert it +function parse_dim(h) +{ + return parse_dim_(h, 1) +} + +# Draw a DIP outline: useful for any rectangular package with a little +# half circle centered on the top line +# arcr: radius of the half circle +# xhalf: optional coordinate where the circle should be put +function dip_outline(layer, x1, y1, x2, y2, arcr ,xhalf) +{ + if (xhalf == "") + xhalf=(x1+x2)/2 + + subc_rectangle(layer, x1, y1, x2, y2, "top") + subc_line(layer, x1, y1, xhalf-arcr, y1) + subc_line(layer, xhalf+arcr, y1, x2, y1) + + subc_arc(layer, xhalf, y1, arcr, 0, 180) +} + +# decide whether x is true or false +# returns 1 if true +# returns 0 if false +function tobool(x) +{ + if (x == int(x)) + return (int(x) != 0) + + x = tolower(x) + return (x == "true") || (x == "yes") || (x == "on") +} + +# default pin1 mark on a box +# style: mark style, ":" separated list +# x,y: the coordinates of the origin corner (top-left) +# half: half the stepping of the pin grid - the size of the mark +# step: optional size of the external arrow or square (defaults to 2*half) +function silkmark(style, x, y, half, step, S,n,v,r) +{ + if (step == "") + step = half*2 + r = step + if (r < 5) r = 5; + + v = split(style, S, ":") + + for(n = 1; n <= v; n++) { + if (S[n] == "angled") { + subc_line("top-silk", x+half, y, x, y+half) + } + else if (S[n] == "square") { + subc_line("top-silk", x, y+step, x+2*half, y+step) + subc_line("top-silk", x+step, y, x+2*half, y+step) + } + else if ((S[n] == "external") || (S[n] == "externalx")) { + subc_line("top-silk", x, y+half, x-step+half, y+half/2) + subc_line("top-silk", x, y+half, x-step+half, y+half*1.5) + subc_line("top-silk", x-step+half, y+half/2, x-step+half, y+half*1.5) + } + else if (S[n] == "externaly") { + subc_line("top-silk", x+half, y, x-half/2+half, y-step+half) + subc_line("top-silk", x+half, y, x+half/2+half, y-step+half) + subc_line("top-silk", x-half/2+half, y-step+half, x+half/2+half, y-step+half) + } + else if (S[n] == "external45") { + subc_line("top-silk", x, y, x-half, y-half/3) + subc_line("top-silk", x, y, x-half/3, y-half) + subc_line("top-silk", x-half, y-half/3, x-half/3, y-half) + } + else if (S[n] == "arc") { + subc_arc("top-silk", x, y, r/2, 180, 270) + } + else if (S[n] == "circle") { + subc_arc("top-silk", x, y, r/2, 0, 360) + } + else if (S[n] == "dot") { + subc_arc("top-silk", x-step/2, y-step/2, r/4, 0, 360) + } + else if ((S[n] != "none") && (S[n] != "")) { + error("invalid silkmark parameter: " S[n]) + } + } +} + +function center_pad_init() +{ + cpm_width = parse_dim(P["cpm_width"]) + cpm_height = parse_dim(P["cpm_height"]) + cpm_nx = int(P["cpm_nx"]) + cpm_ny = int(P["cpm_ny"]) +} + +# draw a matrix of paste rectangles; top-left corner is x1;y1, there are nx*ny +# rectangles of w*h size. rows/cols of pads are drawn with ox and oy offset +function paste_matrix(x1, y1, nx, ny, w, h, ox, oy, flags, attrbiutes, clearance, ix,iy) +{ + for(iy = 0; iy < ny; iy++) + for(ix = 0; ix < nx; ix++) + subc_rect("top-paste", x1+ix*ox, y1+iy*oy, x1+ix*ox+w, y1+iy*oy+h, clearance, flags, attributes) +} + +function center_pad(cpadid, cpx, cpy) +{ + if ((cpad_width != "") && (cpad_height != "")) { +# center pad paste matrix + if ((cpm_nx > 0) && (cpm_ny > 0)) { + ox = (cpad_width - (cpm_nx*cpm_width)) / (cpm_nx - 1) + oy = (cpad_height - (cpm_ny*cpm_height)) / (cpm_ny - 1) + paste_matrix(cpx-cpad_width/2, xpy-cpad_height/2, cpm_nx,cpm_ny, cpm_width,cpm_height, + ox+cpm_width,oy+cpm_height, "", "termid=" cpadid ";", 0) + } + +# center pad + cpad_proto = subc_proto_create_pad_rect(cpad_width, cpad_height, cpad_mask == "" ? 0 : cpad_mask, "none") + subc_pstk(cpad_proto, cpx, cpy, 0, cpadid) + dimension(cpx-cpad_width/2, cpy-cpad_height/2, cpx+cpad_width/2, cpy-cpad_height/2, "@0;" (height * -0.6-ext_bloat), "cpad_width") + dimension(cpx+cpad_width/2, cpy-cpad_height/2, cpx+cpad_width/2, cpy+cpad_height/2, "@" (width * 0.8+ext_bloat) ";0", "cpad_height") + } + +} + +# output a dimension specification between x1;y1 and x2;y2, text distance at dist +# for a name,value pair +# if name is empty, only value is printed +# if value is empty, it's calculated +# if only name should be printed, value should be "!" +# if dist starts with a "@", it's the absolute coordinate of the center of the dim line (text base), else it's relative distance from the measured line +function dimension(x1, y1, x2, y2, dist, name, value, vx,vy) +{ + print "#dimension", x1, y1, x2, y2, dist, name, value +} + +function help_extract(SEEN, fn, dirn, OVER, IGN, WANT,tmp,key,val,i,skip) +{ + if (fn in SEEN) + return + SEEN[fn]++ + print "#@@info-gen-extract " fn + close(fn) + while((getline line < fn) > 0) { + if (line ~ "^#@@include") { + sub("^#@@include[ \t]*", "", line) + tmp = dirn "/" line + WANT[tmp]++ + } + else if (line ~ "^#@@over@ignore") { + key = line + sub("^#@@over@ignore:", "", key) + sub(" .*", "", key) + IGN[key] = 1 + } + else if (line ~ "^#@@over@") { + key = line + sub("^#@@over@", "", key) + val = "#@@" key + sub(" .*", "", key) + OVER[key] = val + } + else if (line ~ "^#@@") { + key = line + sub("^#@@", "", key) + sub(" .*", "", key) + skip = 0 + for(i in IGN) { + if (key ~ i) + skip = 1 + } + if (skip) + continue + if (key in OVER) { + print OVER[key] + OVER[key "::PRINTED"] = 1 + } + else + print line + } + } + close(fn) + for(tmp in WANT) + help_extract(SEEN, tmp, dirn, OVER, IGN) +} + +function help_print( SEEN, OVER, dirn, k) +{ + print "#@@info-generator pcblib common_subc.awk" + dirn = genfull + sub("/[^/]*$", "", dirn) + help_extract(SEEN, genfull, dirn, OVER) + for(k in OVER) { + if (!(k ~ "::PRINTED$") && !((k "::PRINTED") in OVER)) + print OVER[k] + } +} + +function help_auto() +{ + if ((args ~ "^--help") || (args ~ ",[ \t]*--help")) { + help_print() + exit(0) + } +} Index: tags/2.3.0/pcblib/parametric/connector =================================================================== --- tags/2.3.0/pcblib/parametric/connector (nonexistent) +++ tags/2.3.0/pcblib/parametric/connector (revision 33253) @@ -0,0 +1,53 @@ +#!/bin/sh + +#@@example connector(2, 3, silkmark=external, spacing=100) + +#@@purpose Generate pin-array connectors (e.g. headers). + +#@@desc Generate thru-hole connectors that consits of an array of +#@@desc evenly spaced pins, a plain frame and some optional pin marks +#@@desc on the silk layer. + +#@@params nx, ny, spacing, silkmark, eshift, etrunc + +#@@param:nx number of pins in the X direction +#@@param:ny number of pins in the Y direction +#@@param:spacing spacing between the pins +#@@dim:spacing +#@@default:spacing 100 mil + +#@@include silkmark.help +#@@optional:silkmark +#@@default:silkmark square +#@@preview_args:silkmark 2,3 + +#@@param:eshift shift even rows or columns by half spacing (optional; default: don't shift) +#@@enum:eshift:x shift columns +#@@enum:eshift:y shift rows +#@@enum:eshift:none do not shift anything +#@@default:eshift none +#@@optional:eshift +#@@preview_args:eshift 2,3 + +#@@param:etrunc truncate the last pin of a shifted row or column +#@@bool:etrunc +#@@default:etrunc false +#@@optional:etrunc +#@@preview_args:etrunc 2,3,eshift=x + +#@@param:sequence pin numbering sequence +#@@enum:sequence:normal increase by y first, then by x +#@@enum:sequence:pivot increase by x first, then by y +#@@enum:sequence:zigzag "dip-style" numbering in zig-zag: number odd x rows by y ascending, even x rows by y descending +#@@preview_args:sequence 2,4 +#@@thumbsize:sequence 3 +#@@thumbnum:sequence 1 +#@@default:sequence normal +#@@optional:sequence + + + +#@@include common_subc.awk + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/connector.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/connector ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/connector.awk =================================================================== --- tags/2.3.0/pcblib/parametric/connector.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/connector.awk (revision 33253) @@ -0,0 +1,93 @@ +BEGIN { + base_unit_mm = 0 + + help_auto() + set_arg(P, "?spacing", 100) + set_arg(P, "?silkmark", "square") + set_arg(P, "?sequence", "normal") + + proc_args(P, "nx,ny,spacing,silkmark,eshift,etrunc", "nx,ny") + + + step = parse_dim(P["spacing"]) + + if (pin_ringdia > step*0.9) + pin_ringdia = step*0.9 + + if (pin_drill > pin_ringdia*0.9) + pin_drill = pin_ringdia*0.9 + + half=step/2 + + P["nx"] = int(P["nx"]) + P["ny"] = int(P["ny"]) + + eshift=tolower(P["eshift"]) + etrunc=tobool(P["etrunc"]) + if ((eshift != "x") && (eshift != "y") && (eshift != "") && (eshift != "none")) + error("eshift must be x or y or none (got: " eshift ")"); + + subc_begin(P["nx"] "*" P["ny"], "CONN1", 0, -step) + + proto_s = subc_proto_create_pin_square() + proto_r = subc_proto_create_pin_round() + + for(x = 0; x < P["nx"]; x++) { + if ((eshift == "x") && ((x % 2) == 1)) + yo = step/2 + else + yo = 0 + for(y = 0; y < P["ny"]; y++) { + if ((eshift == "y") && ((y % 2) == 1)) { + xo = step/2 + if ((etrunc) && (x == P["nx"]-1)) + continue + } + else { + xo = 0 + if ((etrunc) && (y == P["ny"]-1) && (yo != 0)) + continue + } + if (P["sequence"] == "normal") { + pinno++ + } + else if (P["sequence"] == "pivot") { + pinno = y * P["nx"] + x + 1 + } + else if (P["sequence"] == "zigzag") { + if (x % 2) { + pinno = (x+1) * P["ny"] - y + if ((etrunc) && (eshift == "x")) + pinno -= int(x/2)+1 + else if ((etrunc) && (eshift == "y")) + pinno += int(x/2) + } + else { + pinno = x * P["ny"] + y + 1 + if ((etrunc) && (eshift == "x")) + pinno -= x/2 + else if ((etrunc) && (eshift == "y")) + pinno += x/2-1 + } + } + subc_pstk(pinno == 1 ? proto_s : proto_r, x * step + xo, y * step + yo, 0, pinno) + } + } + + xo = 0 + yo = 0 + if (!etrunc) { + if (eshift == "y") + xo = step/2 + if (eshift == "x") + yo = step/2 + } + + subc_rectangle("top-silk", -half, -half, P["nx"] * step - half + xo, P["ny"] * step - half + yo) + + silkmark(P["silkmark"], -half, -half, half) + + dimension(0, step, step, step, step*2, "spacing") + + subc_end() +} Index: tags/2.3.0/pcblib/parametric/dip =================================================================== --- tags/2.3.0/pcblib/parametric/dip (nonexistent) +++ tags/2.3.0/pcblib/parametric/dip (revision 33253) @@ -0,0 +1,21 @@ +#!/bin/sh + +#@@example dip(18) + +#@@purpose Generate classic DIP packages. + +#@@desc Generate thru-hole DIP packages with variable number of pins and +#@@desc row spacing +#@@params n, spacing + +#@@param:n number of pins + +#@@param:spacing spacing between the two rows of pins +#@@dim:spacing +#@@optional:spacing +#@@default:spacing 100 mil + +#@@include common_subc.awk + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/dip.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/dip ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/dip.awk =================================================================== --- tags/2.3.0/pcblib/parametric/dip.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/dip.awk (revision 33253) @@ -0,0 +1,32 @@ +BEGIN { + base_unit_mm = 0 + + help_auto() + set_arg(P, "?spacing", 300) + + proc_args(P, "n,spacing", "n") + + P["n"] = int(P["n"]) + if ((P["n"] < 2) || ((P["n"] % 2) != 0)) + error("Number of pins have to be an even positive number") + + spacing=parse_dim(P["spacing"]) + + subc_begin(P["n"] "*" P["spacing"], "U1", 0, mil(-100)) + + half = mil(50) + + pstk_s = subc_proto_create_pin_square() + pstk_r = subc_proto_create_pin_round() + + for(n = 1; n <= P["n"]/2; n++) { + subc_pstk((n == 1 ? pstk_s : pstk_r), 0, (n-1) * mil(100), 0, n) + subc_pstk(pstk_r, spacing, (n-1) * mil(100), 0, P["n"] - n + 1) + } + + dip_outline("top-silk", -half, -half, spacing + half , (n-2) * mil(100) + half, half) + + dimension(0, 0, spacing, 0, mil(100), "spacing") + + subc_end() +} Index: tags/2.3.0/pcblib/parametric/msop =================================================================== --- tags/2.3.0/pcblib/parametric/msop (nonexistent) +++ tags/2.3.0/pcblib/parametric/msop (revision 33253) @@ -0,0 +1,34 @@ +#!/bin/sh + +# Reference: Microchip Packaging Specification DS00000049BX (en012702.pdf), MSOP + +#@@example msop(8) + +#@@purpose Generate MSOP packages. + +#@@desc Generate MSOP packages with variable number of pins and +#@@desc row spacing + +#@@include so +#@@include common_subc.awk + +#@@over@default:pad_spacing 0.65 mm +#@@over@default:row_spacing 4.9 mm +#@@over@default:int_bloat 0.6 mm +#@@over@default:ext_bloat 0.6 mm +#@@over@default:pad_thickness 0.45 mm + + +defaults=' +?pad_spacing=0.65mm, +?row_spacing=4.9mm, +?int_bloat=0.6mm, +?ext_bloat=0.4mm, +?rarc=25, +?silk_ext_x=18, +?silk_ext_y=22, +?pad_thickness=0.45mm +' + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/so.awk -v "args=$defaults,$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/msop ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/plcc =================================================================== --- tags/2.3.0/pcblib/parametric/plcc (nonexistent) +++ tags/2.3.0/pcblib/parametric/plcc (revision 33253) @@ -0,0 +1,29 @@ +#!/bin/sh + +# Reference: Microchip Packaging Specification DS00000049BX (en012702.pdf), SSOP + +#@@example plcc(20) + +#@@purpose Generate PLCC packages +#@@desc Generate square PLCC packages - a simplified frontend to qf() - +#@@desc only the number of pins is really needed for a square PLCC footprint! +#@@desc NOTE: some of the qf() parameters can be also used; PLCC32 is non-square, and can not be properly generated using this generator. + +#@@params pins,size,pitch,cpad_size + +#@@param:pins total number of pins (leads); must be divisible by 4 + +#@@param:size a single integer N or NxN or NxNxH; outmost dimensions (width or height of the package, leads included) in mil +#@@optional:size +#@@default:size calculated from total number of pins and pitch + +#@@param:pitch lead pitch (distance between the centerline of two adjacent leads), in mil; must be 50 for now +#@@optional:pitch +#@@default:pitch 50mil + +#@@param:cpad_size width (and height) of the central pad, in mil +#@@optional:cpad_size +#@@default:cpad_size empty, there's no central pad + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/plcc.awk -f `dirname $0`/qf.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/plcc ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/plcc.awk =================================================================== --- tags/2.3.0/pcblib/parametric/plcc.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/plcc.awk (revision 33253) @@ -0,0 +1,60 @@ +function parri(A ,s,i) +{ + for(i in A) + s = s " " i + return s +} + +BEGIN { + base_unit_mm = 0 + + help_auto() + PT["50"] = "26mil" + set_arg(P, "?pitch", "50") + + proc_args(P, "pins,size,pitch,cpad_size,pad_thickness", "pins") + + pitch = P["pitch"] + sub("[.]0*$", "", pitch) + + if (!(args ~ "pad_thickness=")) { + if (!(pitch in PT)) + error("Unknown pitch (" pitch "), should be one of:" parri(PT)) + pt = PT[pitch] + } + else + pt = rev_mil(DEFAULT["pad_thickness"]) + + if (P["size"] == "") + P["size"] = int(P["pins"] * (pitch/4) + 140) + + split(P["size"], S, "x") + if (S[2] == "") + S[2] = S[1] + if (S[1] != S[2]) + error("need n*n size") + + pins = int(P["pins"]) + if (pins / 4 != int(pins / 4)) + error("number of pins must be divisible by 4") + + pins=pins/4 + + if ((pins % 2) != 1) + error("number of pins per side must be odd") + + S[1] -= 60 + S[2] -= 60 + args = args ",nx=" pins ",ny=" pins ",x_spacing=" S[1] "mil,y_spacing=" S[2] "mil,pad_spacing=" pitch "mil,pad_thickness=" pt + + args = args ",width=" S[1]-150 " mil,height=" S[2]-150 " mil" + + + if (P["cpad_size"] != "") + args = args ",cpad_width=" P["cpad_size"] "mil,cpad_height=" P["cpad_size"] "mil" + + args = args ",int_bloat=47mil,ext_bloat=47mil" + args = args ",?bodysilk=plcc,?silkmark=circle,pinoffs=" int(pins/2+0.5) + + +} Index: tags/2.3.0/pcblib/parametric/qf =================================================================== --- tags/2.3.0/pcblib/parametric/qf (nonexistent) +++ tags/2.3.0/pcblib/parametric/qf (revision 33253) @@ -0,0 +1,114 @@ +#!/bin/sh + +#@@example qf(nx=4,ny=4,cpad_auto=1) + +#@@purpose Generate generic *qf* (e.g. tqfp, qfn) packages + +#@@desc Generate *qf* (e.g. tqfp, qfn) packages: smd pads around a square; this is the generic implementation, end users may want to use the specific ones, e.g. tqfp(), qfn(), etc. +#@@params nx,ny,x_spacing,y_spacing,pad_spacing,ext_bloat,int_bloat,width,height,cpad_width,cpad_height,cpad_auto,bodysilk,pinoffs,silkmark + +#@@param:nx number of pins along the horizontal sides + +#@@param:ny number of pins along the vertical sides +#@@optional:ny +#@@default:ny assume ny=nx + +#@@param:x_spacing spacing between the two vertical rows of pins +#@@dim:x_spacing +#@@optional:x_spacing +#@@default:x_spacing calculated using nx and pad_spacing + +#@@param:y_spacing spacing between the two vertical rows of pins +#@@dim:y_spacing +#@@optional:y_spacing +#@@default:y_spacing calculated using ny and pad_spacing + +#@@param:pad_spacing spacing between the centerlines of two adjacent pads (aka pitch) +#@@dim:pad_spacing +#@@optional:pad_spacing + +#@@param:ext_bloat how much longer the pad should extend outwards from the end-point of the pin +#@@dim:ext_bloat +#@@optional:ext_bloat +#@@default:ext_bloat 0.37 mm + +#@@param:int_bloat how much longer the pad should extend inwards from the end-point of the pin +#@@dim:int_bloat +#@@optional:int_bloat +#@@default:int_bloat 0.37 mm + +#@@param:width width (horizontal, x axis size) of the box drawn on silk +#@@dim:width +#@@optional:width +#@@default:width calculated from the pad row geometry + +#@@param:height height (vertical, y axis size) of the box drawn on silk +#@@dim:height +#@@optional:height +#@@default:height calculated from the pad row geometry + +#@@param:cpad_width width (horizontal, x axis size) of the central pad +#@@dim:cpad_width +#@@optional:cpad_width +#@@default:cpad_width empty, no central pad + +#@@param:cpad_height height (vertical, y axis size) of the central pad +#@@dim:cpad_height +#@@optional:cpad_height +#@@default:cpad_height empty, no central pad + +#@@param:cpad_auto when true, calculate central pad sizes automatically from the pad row geometry +#@@bool:cpad_auto +#@@optional:cpad_height +#@@default:cpad_height false, no central pad + +#@@param:cpm_nx central pad paste matrix, number of paste pads in x direction +#@@optional:cpm_nx +#@@default:cpm_nx 2 + +#@@param:cpm_ny central pad paste matrix, number of paste pads in y direction +#@@optional:cpm_ny +#@@default:cpm_ny 2 + +#@@param:cpm_width central pad paste matrix, paste pad width (dimension of each paste rectangle) +#@@dim:cpm_width +#@@optional:cpm_width +#@@default:cpm_width 1mm + +#@@param:cpm_height central pad paste matrix, paste pad height (dimension of each paste rectangle) +#@@dim:cpm_height +#@@optional:cpm_height +#@@default:cpm_height 1mm + +#@@param:cpad_mask center pad mask; if not specified, use the same gap as for the rows (pad_mask) +#@@dim:cpad_mask +#@@optional:cpad_mask + +#@@param:rpad_round when true, row pads are round +#@@bool:rpad_round +#@@optional:rpad_round +#@@default:rpad_round false, row pads are square + +#@@param:bodysilk how to draw body on the silk layer +#@@enum:bodysilk:none no drawing +#@@enum:bodysilk:corners draw the corners, silkmark is outside of the top-left corner +#@@enum:bodysilk:full draw a full rectanlge, silkmark of the top-left corner +#@@enum:bodysilk:plcc angled top-left corner, horizontal line on the top +#@@optional:bodysilk +#@@default:bodysilk corners + +#@@param:pinoffs rotate pins by this amount, CW +#@@optional:pinoffs +#@@default:pinoffs 0 + +#@@include silkmark_qf.help +#@@optional:silkmark +#@@default:silkmark square +#@@preview_args:silkmark 4,4 + +#@@default:silkmark dot +#@@include common_subc.awk + + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/qf.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/qf ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/qf.awk =================================================================== --- tags/2.3.0/pcblib/parametric/qf.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/qf.awk (revision 33253) @@ -0,0 +1,163 @@ +function qf_globals(pre_args, post_args ,reqs) +{ + DEFAULT["cpad_mask", "dim"] = 1 + + if (hook_spc_conv == "") + hook_spc_conv = 1.8 + if (hook_cpad_mult == "") + hook_cpad_mult = 1 + + if (!qf_no_defaults) { + set_arg(P, "?pad_spacing", "0.5mm") + set_arg(P, "?ext_bloat", "0.37mm") + set_arg(P, "?int_bloat", "0.37mm") + set_arg(P, "?pad_thickness", "0.3mm") + set_arg(P, "?silkmark", "dot") + set_arg(P, "?line_thickness", "0.1mm") + set_arg(P, "?cpm_width", "1mm") + set_arg(P, "?cpm_height", "1mm") + set_arg(P, "?cpm_nx", "2") + set_arg(P, "?cpm_ny", "2") + } + + reqs = "nx,ny" + + if (pre_args != "") + reqs="" + + if ((post_args != "") && (!(post_args ~ "^,"))) + post_args = "," post_args + + if ((pre_args != "") && (!(pre_args ~ ",$"))) + pre_args = pre_args "," + + proc_args(P, pre_args "nx,ny,x_spacing,y_spacing,pad_spacing,ext_bloat,int_bloat,width,height,cpad_width,cpad_height,cpad_auto,cpm_nx,cpm_ny,cpm_width,cpm_height,cpad_mask,rpad_round,bodysilk,pinoffs,silkmark" post_args, reqs) + + nx = int(P["nx"]) + ny = int(P["ny"]) + + if (P["ny"] == "") + ny = nx + + if ((nx < 2) || (ny < 2)) + error("Number of pins have to be more than 2 in both directions") + + x_spacing=parse_dim(P["x_spacing"]) + y_spacing=parse_dim(P["y_spacing"]) + pad_spacing=parse_dim(P["pad_spacing"]) + pt = DEFAULT["pad_thickness"] + ext_bloat=parse_dim(P["ext_bloat"]) - pt/2 + int_bloat=parse_dim(P["int_bloat"]) - pt/2 + width=parse_dim(P["width"]) + height=parse_dim(P["height"]) + pinoffs = int(P["pinoffs"]) + + if (x_spacing == "") + x_spacing = (nx+hook_spc_conv) * pad_spacing + if (y_spacing == "") + y_spacing = (ny+hook_spc_conv) * pad_spacing + + cpad_width=parse_dim(P["cpad_width"]) + cpad_height=parse_dim(P["cpad_height"]) + + if (P["cpad_mask"] != "") + cpad_mask=parse_dim(P["cpad_mask"]) + + + if (tobool(P["cpad_auto"]) || hook_cpad_auto) { + if (cpad_width == "") + cpad_width = (x_spacing*0.85 - int_bloat*2 - pt) * hook_cpad_mult + if (cpad_height == "") + cpad_height = (y_spacing*0.85 - int_bloat*2 - pt) * hook_cpad_mult + } + + + if (width == "") + width = x_spacing + if (height == "") + height = y_spacing + + pinmax=(nx+ny)*2 + + if (!tobool(P["rpad_round"])) + rpad_round = "square" + else + rpad_round = "" + + center_pad_init() +} + +function pinnum(num) +{ + return ((num-1) + pinoffs) % (pinmax)+1 +} + +BEGIN { + base_unit_mm = 0 + + help_auto() + qf_globals() + + subc_begin("", "U1", -width/2 - mm(1), -height/2 - mm(2), 0) + + cx = (nx+1)/2 + cy = (ny+1)/2 + if (rpad_round == "square") + proto = subc_proto_create_pad_sqline(-ext_bloat, int_bloat, pad_width) + else + proto = subc_proto_create_pad_line(-ext_bloat, int_bloat, pad_width) + + for(n = 1; n <= ny; n++) { + y = (-cy + n) * pad_spacing + x1 = -x_spacing/2 + x2 = x_spacing/2 + subc_pstk(proto, x1, y, 0, pinnum(n)) + subc_pstk(proto, x2, y, 180, pinnum(nx+2*ny-n+1)) + if (n == 1) + y1 = y + if (n == 2) + dimension(x1, y1, x1, y, (ext_bloat * -3), "pad_spacing") + } + + dimension(x1, y-pt/2, x1, y+pt/2, (ext_bloat * -3), "pad_thickness") + + for(n = 1; n <= nx; n++) { + x = (-cx + n) * pad_spacing + y1 = -y_spacing/2 + y2 = y_spacing/2 + subc_pstk(proto, x, y1, 270, pinnum(nx*2+ny*2-n+1)) + subc_pstk(proto, x, y2, 90, pinnum(n+ny)) + } + + + center_pad(2*nx+2*ny+1, 0, 0) + + wx = (width - nx * pad_spacing) / 3.5 + wy = (height - ny * pad_spacing) / 3.5 + + bodysilk = P["bodysilk"] + if ((bodysilk == "corners") || (bodysilk == "")) { + subc_rectangle_corners("top-silk", -width/2, -height/2, width/2, height/2, wx, wy) + silkmark(P["silkmark"], -width/2, -height/2, (wx+wy)/3) + } + else if (bodysilk == "full") { + subc_rectangle("top-silk", -width/2, -height/2, width/2, height/2) + silkmark(P["silkmark"], -width/2, -height/2, (wx+wy)/2) + } + else if (bodysilk == "plcc") { + r = (width+height)/10 + subc_rectangle("top-silk", -width/2, -height/2, width/2, height/2, "arc,NE,SW,SE", r) + subc_line("top-silk", -width/2, -height/2+r, width/2, -height/2+r) + silkmark(P["silkmark"], 0, -height*0.2-r, height/40) + } + else if (bodysilk != "none") + error("invalid bodysilk parameter") + + dimension(-width/2, -height/2, +width/2, -height/2, "@0;" height*-0.8-ext_bloat, "width") + dimension(+width/2, -height/2, +width/2, +height/2, "@" (width * 1+ext_bloat) ";0", "height") + + dimension(-x_spacing/2, -height/2, +x_spacing/2, -height/2, "@0;" height*-1-ext_bloat, "x_spacing") + dimension(+width/2, -y_spacing/2, +width/2, +y_spacing/2, "@" (width * 1.2+ext_bloat) ";0", "y_spacing") + + subc_end() +} Index: tags/2.3.0/pcblib/parametric/qfn =================================================================== --- tags/2.3.0/pcblib/parametric/qfn (nonexistent) +++ tags/2.3.0/pcblib/parametric/qfn (revision 33253) @@ -0,0 +1,24 @@ +#!/bin/sh + +# Reference: Microchip Packaging Specification DS00000049BX (en012702.pdf), SSOP + +#@@example qfn(16,3x3,0.5) + +#@@purpose Generate QFN packages +#@@desc Generate QFN packages - a simplified frontend to qf() - +#@@desc look up 3..4 data in the datasheet and get a regular QFN footprint! +#@@desc Should work for QFN, TQFN, etc. +#@@desc NOTE: some of the qf() parameters can be also used. + +#@@params pins,size,pitch,cpad_size + +#@@param:pins total number of pins (leads); must be divisible by 4 +#@@param:size a single integer N or NxN or NxNxH; the pad spacing dimension (outer dimension, lead-to-lead) in mm +#@@param:pitch lead pitch (distance between the centerline of two adjacent leads), in mm; must be one of 0.4, 0.5, 0.65 + +#@@param:cpad_size width (and height) of the central pad, in mm +#@@optional:cpad_size +#@@default:cpad_size empty, there's no central pad + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/qfn.awk -f `dirname $0`/qf.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/qfn ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/qfn.awk =================================================================== --- tags/2.3.0/pcblib/parametric/qfn.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/qfn.awk (revision 33253) @@ -0,0 +1,47 @@ +function parri(A ,s,i) +{ + for(i in A) + s = s " " i + return s +} + +BEGIN { + help_auto() + PT["0.65"] = "0.35mm" + PT["0.5"] = "0.3mm" + PT["0.4"] = "0.2mm" + + proc_args(P, "pins,size,pitch,cpad_size,pad_thickness", "pins,size,pitch") + + pitch = P["pitch"] + sub("0*$", "", pitch) + + if (!(args ~ "pad_thickness=")) { + if (!(pitch in PT)) + error("Unknown pitch, should be one of:" parri(PT)) + pt = PT[pitch] + } + else + pt = rev_mm(DEFAULT["pad_thickness"]) "mm" + + split(P["size"], S, "x") + if (S[2] == "") + S[2] = S[1] + if (S[1] != S[2]) + error("need n*n size") + + pins = int(P["pins"]) + if (pins / 4 != int(pins / 4)) + error("number of pins must be divisible by 4") + + pins=pins/4 + + + args = args ",nx=" pins ",ny=" pins ",x_spacing=" S[1] "mm,y_spacing=" S[2] "mm,pad_spacing=" pitch "mm,pad_thickness=" pt + + if (P["cpad_size"] != "") + args = args ",cpad_width=" P["cpad_size"] "mm,cpad_height=" P["cpad_size"] "mm" + +# qf_globals("pins,size") + +} Index: tags/2.3.0/pcblib/parametric/qfp =================================================================== --- tags/2.3.0/pcblib/parametric/qfp (nonexistent) +++ tags/2.3.0/pcblib/parametric/qfp (revision 33253) @@ -0,0 +1,24 @@ +#!/bin/sh + +# Reference: Microchip Packaging Specification DS00000049BX (en012702.pdf), SSOP + +#@@example qfp(32,7x7,0.8) + +#@@purpose Generate QFP packages +#@@desc Generate QFP packages - a simplified frontend to qf() - +#@@desc look up 3..4 data in the datasheet and get a regular QFP footprint! +#@@desc NOTE: some of the qf() parameters can be also used. +#@@desc Should work for QFP, TQFP, LQFP, etc. + +#@@params pins,size,pitch,cpad_size + +#@@param:pins total number of pins (leads); must be divisible by 4 +#@@param:size a single integer N or NxN or NxNxH; body dimension (width or height of the plastic body) in mm +#@@param:pitch lead pitch (distance between the centerline of two adjacent leads), in mm; must be one of 0.4, 0.5, 0.65 + +#@@param:cpad_size width (and height) of the central pad, in mm +#@@optional:cpad_size +#@@default:cpad_size empty, there's no central pad + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/qfp.awk -f `dirname $0`/qf.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/qfp ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/qfp.awk =================================================================== --- tags/2.3.0/pcblib/parametric/qfp.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/qfp.awk (revision 33253) @@ -0,0 +1,52 @@ +function parri(A ,s,i) +{ + for(i in A) + s = s " " i + return s +} + +BEGIN { + help_auto() + PT["0.8"] = "0.55mm" + PT["0.65"] = "0.35mm" + PT["0.5"] = "0.3mm" + PT["0.4"] = "0.2mm" + + proc_args(P, "pins,size,pitch,cpad_size,pad_thickness", "pins,size,pitch") + + pitch = P["pitch"] + sub("0*$", "", pitch) + + if (!(args ~ "pad_thickness=")) { + if (!(pitch in PT)) + error("Unknown pitch, should be one of:" parri(PT)) + pt = PT[pitch] + } + else + pt = rev_mm(DEFAULT["pad_thickness"]) "mm" + + split(P["size"], S, "x") + if (S[2] == "") + S[2] = S[1] + if (S[1] != S[2]) + error("need n*n size") + + pins = int(P["pins"]) + if (pins / 4 != int(pins / 4)) + error("number of pins must be divisible by 4") + + pins=pins/4 + + args = args ",width=" S[1] " mm,height=" S[2] " mm" + + S[1] += 1.45 + S[2] += 1.45 + args = args ",nx=" pins ",ny=" pins ",x_spacing=" S[1] "mm,y_spacing=" S[2] "mm,pad_spacing=" pitch "mm,pad_thickness=" pt "mm" + + + if (P["cpad_size"] != "") + args = args ",cpad_width=" P["cpad_size"] "mm,cpad_height=" P["cpad_size"] "mm" + + args = args ",int_bloat=0.5mm,ext_bloat=1.1mm" + args = args ",?bodysilk=full,?silkmark=circle" +} Index: tags/2.3.0/pcblib/parametric/qsop =================================================================== --- tags/2.3.0/pcblib/parametric/qsop (nonexistent) +++ tags/2.3.0/pcblib/parametric/qsop (revision 33253) @@ -0,0 +1,34 @@ +#!/bin/sh + +# Reference: Microchip Packaging Specification DS00000049BX (en012702.pdf), QSOP + +#@@example qsop(14) + +#@@purpose Generate QSOP packages. + +#@@desc Generate QSOP packages with variable number of pins and +#@@desc row spacing + +#@@include so +#@@include common_subc.awk + +#@@over@default:pad_spacing 25 mil +#@@over@default:row_spacing 213 mil +#@@over@default:int_vloat 22 mil +#@@over@default:ext_bloat 23 mil +#@@over@default:pad_thickness 16 mil + + +defaults=' +?pad_spacing=25mil, +?row_spacing=213mil, +?int_bloat=22mil, +?ext_bloat=23mil, +?rarc=25, +?silk_ext_x=18, +?silk_ext_y=22, +?pad_thickness=16mil +' + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/so.awk -v "args=$defaults,$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/qsop ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/rcy =================================================================== --- tags/2.3.0/pcblib/parametric/rcy (nonexistent) +++ tags/2.3.0/pcblib/parametric/rcy (revision 33253) @@ -0,0 +1,32 @@ +#!/bin/sh + +#@@example rcy(300,bar+) + +#@@purpose Generate radial lead through-hole component + +#@@desc Generate radial lead through-hole component with 2 pins (typical use: electrolytic caps) +#@@params spacing,pol,dia + +#@@param:spacing spacing between the two pins +#@@dim:spacing + +#@@param:pol how to mark polarity: (optional; default: sign) +#@@enum:pol:none no marking +#@@enum:pol:sign print + next to pin 1 and - next to pin 2 +#@@enum:pol:bar+ draw a bar inside the circle, around pin 2 +#@@enum:pol:bar- draw a bar inside the circle, around pin 1 +#@@enum:pol:bar same as bar+ +#@@enum:pol:bar+sign bar+ and sign combined +#@@enum:pol:bar-sign bar- and sign combined +#@@optional:pol +#@@default:pol sign +#@@preview_args:pol 300 + +#@@param:dia body diameter - affects the silk circle +#@@optional:dia +#@@default:dia spacing*2 + +#@@include common_subc.awk + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/rcy.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/rcy ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/rcy.awk =================================================================== --- tags/2.3.0/pcblib/parametric/rcy.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/rcy.awk (revision 33253) @@ -0,0 +1,95 @@ +function pol_sign( ox) +{ + size=mil(20) + + ox = dia/2+size*2 + subc_line("top-silk", ox-size, 0, ox+size, 0) + + ox = -dia/2-size*2 + subc_line("top-silk", ox-size, 0, ox+size, 0) + subc_line("top-silk", ox, -size, ox, size) +} + +BEGIN { + base_unit_mm = 0 + + help_auto() + set_arg(P, "?pol", "sign") + proc_args(P, "spacing,pol,dia", "spacing") + + spacing = parse_dim(P["spacing"]) + dia = either(parse_dim(P["dia"]), spacing*2) + + offs_x = +spacing/2 + + subc_begin("rcy" P["spacing"], "C1", -spacing/5, -mil(20), 0) + + proto_s = subc_proto_create_pin_square() + proto_r = subc_proto_create_pin_round() + + subc_pstk(proto_s, -spacing/2, 0, 0, 1) + subc_pstk(proto_r, +spacing/2, 0, 0, 2) + + dimension(-spacing/2, 0, +spacing/2, 0, dia*0.8, "spacing") + + +# silk rectangle and pins + subc_arc("top-silk", 0, 0, dia/2, 0, 360) + dimension(-dia/2, 0, +dia/2, 0, dia*-0.8, "dia") + + + if (P["pol"] == "sign") { + pol_sign() + } + else if (P["pol"] ~ "^bar") { +# determine bar side (default to -) + side=P["pol"] + sub("^bar", "", side) + if (side ~ "sign") { + pol_sign() + sub("sign", "", side) + } + if (side == "") + side = "-" + side = int(side "1") * -1 + + th = mm(1) + ystep = th/2 + r = dia/2-th/2 + xs = dia/8 + ring = DEFAULT["pin_ringdia"] + for(y = 0; y < dia/2; y+=ystep) { + x = r*r-y*y + if (x < 0) + break + x = sqrt(x) + if (x <= xs) + break + if (y > ring/2+th/2) { + subc_line("top-silk", side*xs, y, side*x, y, th) + if (y != 0) + subc_line("top-silk", side*xs, -y, side*x, -y, th) + } + else { +# keep out a rectangle around the pin + end1=spacing/2-ring + end2=spacing/2+ring + if (end1 > xs) + subc_line("top-silk", side*xs, y, side*end1, y, th) + if (end2 < x) + subc_line("top-silk", side*end2, y, side*x, y, th) + if (y != 0) { + if (end1 > xs) + subc_line("top-silk", side*xs, -y, side*end1, -y, th) + if (end2 < x) + subc_line("top-silk", side*end2, -y, side*x, -y, th) + } + } + } + } + else if ((P["pol"] != "") && (P["pol"] != "none")) { + error("Invalid pol") + } + + subc_end() +} Index: tags/2.3.0/pcblib/parametric/screw =================================================================== --- tags/2.3.0/pcblib/parametric/screw (nonexistent) +++ tags/2.3.0/pcblib/parametric/screw (revision 33253) @@ -0,0 +1,35 @@ +#!/bin/sh + +#@@example screw(3.2mm, 6mm, circle:hex) + +#@@purpose Generic screw. + +#@@desc Generate a "single pin" screw with optional head shapes +#@@params hole,head,shape,ring + +#@@param:hole hole diameter or name of a standard screw (e.g. M3) +#@@dim:hole + + +#@@param:head head outmost diameter (or optional head name for a standard screw: pan, button, cheese, flat-washer, internal-lock-washer) +#@@dim:head + +#@@param:ring copper ring outer diameter +#@@dim:ring +#@@optional:ring +#@@default:ring 80% of head diameter + + +#@@param:shape shape of the head drawn on silkmark; multiple values can be listed separated with colons, e.g. "shape=circle:hex" +#@@enum:shape:circle circle +#@@enum:shape:hex hexagon with straight line edges, size is from corner to corner +#@@enum:shape:tx "torx": hexagon with arced edges +#@@enum:shape:xzn "triple square" +#@@enum:shape:ph philips slot (cross) - useful together with circle +#@@enum:shape:slot a single straight line slot - useful together with circle +#@@default:shape circle +#@@preview_args:shape 3mm,6mm + +#@@include common_subc.awk + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/screw.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" -v "genfull=$0" Property changes on: tags/2.3.0/pcblib/parametric/screw ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/screw.awk =================================================================== --- tags/2.3.0/pcblib/parametric/screw.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/screw.awk (revision 33253) @@ -0,0 +1,131 @@ +function shp(r, edges, tx ,a,x,y,xl,yl,step,x1,y1,x2,y2,tx1,tx2,txs) +{ + step = 2*3.141592654/edges + if (tx == 1) { + tx1 = 0.7 + tx2 = 0.6 + txs = 5 + } + else if (tx == 2) { + tx1 = 0.85 + tx2 = 0.8 + txs = 5 + } + else if (tx == 3) { + tx1 = 0.2 + tx2 = 0.2 + txs = 3 + } + for(n = 0; n <= edges; n++) { + a += step + x = cos(a)*r + y = sin(a)*r + if (xl != "") { + if (tx) { + x1 = cos(a-(txs-1)*step/txs)*r*tx1 + y1 = sin(a-(txs-1)*step/txs)*r*tx1 + x2 = cos(a-step/txs)*r*tx1 + y2 = sin(a-step/txs)*r*tx1 + x3 = cos(a-step/2)*r*tx2 + y3 = sin(a-step/2)*r*tx2 + subc_line("top-silk", xl, yl, x1, y1) + subc_line("top-silk", x, y, x2, y2) + subc_line("top-silk", x3, y3, x1, y1) + subc_line("top-silk", x3, y3, x2, y2) + } + else + subc_line("top-silk", xl, yl, x, y) + } + xl = x + yl = y + } +} + +function round_up(num, to) +{ + if ((num/to) == int(num/to)) + return num + return int(num/to+1)*to +} + +BEGIN { + help_auto() + set_arg(P, "?shape", "circle") + proc_args(P, "hole,head,shape,ring", "hole") + + subc_begin("screw:" P["hole"] "," P["head"]"," P["shape"], "S1", 0, -mil(100), 0) + + if (P["hole"] ~ "^M") { + hole = P["hole"] + sub("^M", "", hole) + h = parse_dim(int(hole) "mm") + if ((hole ~ "tight") || (hole ~ "close.fit")) + hole = h * 1.05 + else + hole = h * 1.1 + hd = parse_dim(P["head"]) + if ((hd == 0) || (hd == "")) { + hd = P["head"] + if (hd == "button") + head = 1.9*h + else if (hd == "button") + head = 1.9*h + else if (hd == "cheese") + head = round_up(1.7*h, mm(0.5)) + else if (hd ~ "flat.washer") + head = round_up(2.1*h, mm(1)) + else if ((hd == "") || (hd == "pan") || (hd ~ "int.*.lock.washer")) + head = 2*h + else + error("Unknown standard head: " hd) + } + else + head = hd +# print hole, head > "/dev/stderr" + } + else { + hole = parse_dim(P["hole"]) + head = parse_dim(P["head"]) + } + + if (head == "") + error("need a standard screw name, e.g. M3, or a head diameter") + + if (head < hole) + error("head diameter must be larger than hole diameter") + + ring = parse_dim(P["ring"]) + + if (ring == "") + ring = head*0.8 + + + proto = subc_proto_create_pin_round(hole, ring) + subc_pstk(proto, 0, 0, 0, 1) + + + shape = ":" P["shape"] ":" + + if (shape ~ ":circle:") + subc_arc("top-silk", 0, 0, head/2, 0, 360) + + if (shape ~ ":hex:") + shp(head/2, 6, 0) + + if (shape ~ ":tx:") + shp(head/2, 6, 1) + + if (shape ~ ":xzn:") + shp(head/2, 12, 2) + + if (shape ~ ":ph:") + shp(head*0.4, 4, 3) + + if (shape ~ ":slot:") + subc_line("top-silk", -head/2, 0, head/2, 0) + + dimension(-head/2, 0, head/2, 0, head*0.7, "head") + dimension(-hole/2, 0, hole/2, 0, head*0.6, "hole") + + subc_end() +} Index: tags/2.3.0/pcblib/parametric/silkmark.help =================================================================== --- tags/2.3.0/pcblib/parametric/silkmark.help (nonexistent) +++ tags/2.3.0/pcblib/parametric/silkmark.help (revision 33253) @@ -0,0 +1,11 @@ +#@@param:silkmark how to mark pin 1 on the silk layer; multiple values can be listed separated with colons, e.g. "silkmark=externalx:angled" +#@@enum:silkmark:square a rectangle around pin 1 +#@@enum:silkmark:externalx a little triangle placed outside of the box pointing in line with the first x row +#@@enum:silkmark:externaly a little triangle placed outside of the box pointing in line with the first y row +#@@enum:silkmark:external45 a little triangle placed outside of the box pointing at the corner in 45 degree +#@@enum:silkmark:external shorthand for externalx +#@@enum:silkmark:angled an angled line in the corner +#@@enum:silkmark:arc an external 270 degree arc +#@@enum:silkmark:circle a circle, 270 degrees external +#@@enum:silkmark:dot a small external dot +#@@enum:silkmark:none no mark Index: tags/2.3.0/pcblib/parametric/silkmark_qf.help =================================================================== --- tags/2.3.0/pcblib/parametric/silkmark_qf.help (nonexistent) +++ tags/2.3.0/pcblib/parametric/silkmark_qf.help (revision 33253) @@ -0,0 +1,11 @@ +#@@param:silkmark how to mark pin 1 on the silk layer; multiple values can be listed separated with colons, e.g. "silkmark=externalx:angled"; ***NOTE***: drawn only if bodysilk is also drawn! +#@@enum:silkmark:square a rectangle around pin 1 +#@@enum:silkmark:externalx a little triangle placed outside of the box pointing in line with the first x row +#@@enum:silkmark:externaly a little triangle placed outside of the box pointing in line with the first y row +#@@enum:silkmark:external45 a little triangle placed outside of the box pointing at the corner in 45 degree +#@@enum:silkmark:external shorthand for externalx +#@@enum:silkmark:angled an angled line in the corner +#@@enum:silkmark:arc an external 270 degree arc +#@@enum:silkmark:circle a circle, 270 degrees external +#@@enum:silkmark:dot a small external dot +#@@enum:silkmark:none no mark Index: tags/2.3.0/pcblib/parametric/so =================================================================== --- tags/2.3.0/pcblib/parametric/so (nonexistent) +++ tags/2.3.0/pcblib/parametric/so (revision 33253) @@ -0,0 +1,40 @@ +#!/bin/sh + +#@@example so(14) + +#@@purpose Generate SO and SO-like packages. + +#@@desc Generate SO packages with variable number of pins and +#@@desc row spacing +#@@params n, row_spacing, pad_spacing + +#@@param:n number of pins + +#@@param:row_spacing spacing between the two rows of pads: distance between the end of the first and last pins +#@@dim:row_spacing +#@@optional:row_spacing +#@@default:row_spacing 250 mil + + +#@@param:pad_spacing spacing between the centerline of two pads +#@@dim:pad_spacing +#@@optional:pad_spacing +#@@default:pad_spacing 50 mil + + +#@@param:ext_bloat how much longer the pad should extend outwards from the end-point of the pin +#@@dim:ext_bloat +#@@optional:ext_bloat +#@@default:ext_bloat 10 mil + +#@@param:int_bloat how much longer the pad should extend inwards from the end-point of the pin +#@@dim:int_bloat +#@@optional:int_bloat +#@@default:int_bloat 55 mil + +#@@include common_subc.awk + +#@@over@ignore::pin_ + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/so.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/so ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/so.awk =================================================================== --- tags/2.3.0/pcblib/parametric/so.awk (nonexistent) +++ tags/2.3.0/pcblib/parametric/so.awk (revision 33253) @@ -0,0 +1,55 @@ +BEGIN { + base_unit_mm = 0 + + help_auto() + set_arg(P, "?row_spacing", 250) + set_arg(P, "?pad_spacing", 50) + set_arg(P, "?ext_bloat", 10) + set_arg(P, "?int_bloat", 55) + + proc_args(P, "n,row_spacing,pad_spacing,ext_bloat,int_bloat", "n") + + P["n"] = int(P["n"]) + if ((P["n"] < 2) || ((P["n"] % 2) != 0)) + error("Number of pins have to be an even positive number") + + row_spacing=parse_dim(P["row_spacing"]) + pad_spacing=parse_dim(P["pad_spacing"]) + ext_bloat=parse_dim(P["ext_bloat"]) + int_bloat=parse_dim(P["int_bloat"]) + +# translate origin to the middle (int() and -0.5 rounds it for odd number of pins) + offs_x = -(row_spacing/2) + offs_y = -int((P["n"]/4-0.5) * pad_spacing) + + subc_begin(P["n"] "*" P["row_spacing"], "U1", -offs_x, mil(-100)-offs_y) + + proto = subc_proto_create_pad_sqline(-ext_bloat, int_bloat, pad_width) + + for(n = 1; n <= P["n"]/2; n++) { + y = (n-1) * pad_spacing + subc_pstk(proto, 0, y, 0, n) + subc_pstk(proto, row_spacing, y, 180, P["n"] - n + 1) + } + + silk_dist_x = either(parse_dim(P["silk_ext_x"]), pad_spacing/2) + silk_dist_y = either(parse_dim(P["silk_ext_y"]), pad_spacing/2) + rarc = either(parse_dim(P["rarc"]), pad_spacing/2) + + dip_outline("top-silk", -silk_dist_x-ext_bloat, -silk_dist_y, row_spacing + silk_dist_x+ext_bloat , (n-2) * pad_spacing + silk_dist_y, rarc) + + left_dim="@" -silk_dist_x-ext_bloat-pad_spacing ";0" + dimension(0, 0, 0, pad_spacing, left_dim, "pad_spacing") + dimension(0, 0, row_spacing, 0, (pad_spacing * 1.8), "row_spacing") + dimension(-ext_bloat, 0, 0, 0, (pad_spacing * 1.2), "ext_bloat") + dimension(row_spacing-int_bloat, 0, row_spacing, 0, (pad_spacing * 1.2), "int_bloat") + + th=DEFAULT["pad_thickness"] + y = (n-2) * pad_spacing + dimension(-ext_bloat-th/2, y, +int_bloat+th/2, y, (pad_spacing * -1.2), "") + dimension(0, y-th/2, 0, y+th/2, left_dim, "pad_thickness") + +# dimension(-silk_dist_x-ext_bloat, -silk_dist_y, row_spacing + silk_dist_x+ext_bloat, -silk_dist_y, pad_spacing*2.5, "") + + subc_end() +} Index: tags/2.3.0/pcblib/parametric/ssop =================================================================== --- tags/2.3.0/pcblib/parametric/ssop (nonexistent) +++ tags/2.3.0/pcblib/parametric/ssop (revision 33253) @@ -0,0 +1,33 @@ +#!/bin/sh + +# Reference: Microchip Packaging Specification DS00000049BX (en012702.pdf), SSOP + +#@@example ssop(14) + +#@@purpose Generate SSOP packages. + +#@@desc Generate SSOP packages with variable number of pins and +#@@desc row spacing + +#@@include so +#@@include common_subc.awk + +#@@over@default:pad_spacing 0.65 mm +#@@over@default:row_spacing 7.8 mm +#@@over@default:int_bloat 0.5 mm +#@@over@default:ext_bloat 0.13 mm +#@@over@default:pad_thickness 0.45 mm + +defaults=' +?pad_spacing=0.65mm, +?row_spacing=7.8mm, +?int_bloat=0.5mm, +?ext_bloat=0.13mm, +?rarc=25, +?silk_ext_x=18, +?silk_ext_y=22, +?pad_thickness=0.45mm +' + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/so.awk -v "args=$defaults,$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/ssop ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/parametric/tssop =================================================================== --- tags/2.3.0/pcblib/parametric/tssop (nonexistent) +++ tags/2.3.0/pcblib/parametric/tssop (revision 33253) @@ -0,0 +1,33 @@ +#!/bin/sh + +# Reference: Microchip Packaging Specification DS00000049BX (en012702.pdf), MSOP + +#@@example tssop(8) + +#@@purpose Generate TSSOP packages. + +#@@desc Generate TSSOP 4.4mm body packages with variable number of pins and +#@@desc row spacing + +#@@include so +#@@include common_subc.awk + +#@@over@default:pad_spacing 0.65 mm +#@@over@default:row_spacing 6.4 mm +#@@over@default:int_bloat 0.6 mm +#@@over@default:ext_bloat 0.4 mm +#@@over@default:pad_thickness 0.45 mm + +defaults=' +?pad_spacing=0.65mm, +?row_spacing=6.4mm, +?int_bloat=0.6mm, +?ext_bloat=0.4mm, +?rarc=25, +?silk_ext_x=18, +?silk_ext_y=22, +?pad_thickness=0.45mm +' + +awk -f `dirname $0`/common_subc.awk -f `dirname $0`/so.awk -v "args=$defaults,$*" -v gen=`basename $0` -v "genfull=$0" + Property changes on: tags/2.3.0/pcblib/parametric/tssop ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/pcblib/smd/01005.fp =================================================================== --- tags/2.3.0/pcblib/smd/01005.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/01005.fp (revision 33253) @@ -0,0 +1,212 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = 01005 Standard SMT resistor, capacitor etc + openscad = 01005.scad + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 4.92mil + -5.11mil + -4.92mil + -5.11mil + -4.92mil + 5.11mil + 4.92mil + 5.11mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 7.92mil + -0.205994mm + -7.92mil + -0.205994mm + -7.92mil + 0.205994mm + 7.92mil + 0.205994mm + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 4.92mil + -5.11mil + -4.92mil + -5.11mil + -4.92mil + 5.11mil + 4.92mil + 5.11mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 17.92mil + rot = 0.000000 + y = 0.459994mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 34.06mil + rot = 0.000000 + y = 0.459994mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:text.6 { + scale = 100 + ha:attributes { + } + x = -0.139954mm + y = -13.39mil + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 0.459994mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 0.660146mm + x2 = 0.660146mm + ha:flags { + } + y1 = 0.459994mm + } + ha:line.12 { + clearance = 0.0 + y2 = 0.459994mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 0.660146mm + x2 = 0.660146mm + ha:flags { + } + y1 = 0.459994mm + } + ha:line.15 { + clearance = 0.0 + y2 = 0.459994mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 0.660146mm + x2 = 1.660146mm + ha:flags { + } + y1 = 0.459994mm + } + ha:line.18 { + clearance = 0.0 + y2 = 1.459994mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 0.660146mm + x2 = 0.660146mm + ha:flags { + } + y1 = 0.459994mm + } + } + ha:combining { + } + } + } + } + uid = Q1c2peLxTgOy7O9YZ/8AAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/01005.scad =================================================================== --- tags/2.3.0/pcblib/smd/01005.scad (nonexistent) +++ tags/2.3.0/pcblib/smd/01005.scad (revision 33253) @@ -0,0 +1,19 @@ +module part_01005(len=0.4, width=0.2, height=0.13, pad_len=0.1) +{ + union() { + translate([0,0,height/2]) { + // body + color([0.1,0.1,0.1]) + cube([len-2*pad_len,width,height], center=true); + // terminals + color([0.8,0.8,0.8]) { + translate([+len/2-pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + color([0.8,0.8,0.8]) { + translate([-len/2+pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + } + } +} Index: tags/2.3.0/pcblib/smd/0201.fp =================================================================== --- tags/2.3.0/pcblib/smd/0201.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/0201.fp (revision 33253) @@ -0,0 +1,212 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = 0201 Standard SMT resistor, capacitor etc + openscad = 0201.scad + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -7.87mil + 7.87mil + 7.87mil + 7.87mil + 7.87mil + -7.87mil + -7.87mil + -7.87mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -0.276098mm + 0.276098mm + 0.276098mm + 0.276098mm + 0.276098mm + -0.276098mm + -0.276098mm + -0.276098mm + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -7.87mil + 7.87mil + 7.87mil + 7.87mil + 7.87mil + -7.87mil + -7.87mil + -7.87mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 20.87mil + rot = 0.000000 + y = 20.87mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 44.49mil + rot = 0.000000 + y = 20.87mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 0.029972mm + y = -10.63mil + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 20.87mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 0.830072mm + x2 = 0.830072mm + ha:flags { + } + y1 = 20.87mil + } + ha:line.12 { + clearance = 0.0 + y2 = 20.87mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 0.830072mm + x2 = 0.830072mm + ha:flags { + } + y1 = 20.87mil + } + ha:line.15 { + clearance = 0.0 + y2 = 20.87mil + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 0.830072mm + x2 = 1.830072mm + ha:flags { + } + y1 = 20.87mil + } + ha:line.18 { + clearance = 0.0 + y2 = 1.530098mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 0.830072mm + x2 = 0.830072mm + ha:flags { + } + y1 = 20.87mil + } + } + ha:combining { + } + } + } + } + uid = eStzy6mX6No40cDOtoEAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/0201.scad =================================================================== --- tags/2.3.0/pcblib/smd/0201.scad (nonexistent) +++ tags/2.3.0/pcblib/smd/0201.scad (revision 33253) @@ -0,0 +1,20 @@ +module part_0201(len=0.6, width=0.3, height=0.23, pad_len=0.15) +{ + union() { + translate([0,0,height/2]) { + // body + color([0.1,0.1,0.1]) + cube([len-2*pad_len,width,height], center=true); + // terminals + color([0.8,0.8,0.8]) { + translate([+len/2-pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + color([0.8,0.8,0.8]) { + translate([-len/2+pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + } + } +} + Index: tags/2.3.0/pcblib/smd/0402.fp =================================================================== --- tags/2.3.0/pcblib/smd/0402.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/0402.fp (revision 33253) @@ -0,0 +1,212 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = 0402 Standard SMT resistor, capacitor etc + openscad = 0402.scad + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.326136mm + -0.425958mm + -0.326136mm + -0.425958mm + -0.326136mm + 0.425958mm + 0.326136mm + 0.425958mm + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 0.580136mm + rot = 0.000000 + y = 0.679958mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 54.32mil + rot = 0.000000 + y = 0.679958mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 7.08mil + y = -4.73mil + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 0.679958mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 0.979932mm + x2 = 0.979932mm + ha:flags { + } + y1 = 0.679958mm + } + ha:line.12 { + clearance = 0.0 + y2 = 0.679958mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 0.979932mm + x2 = 0.979932mm + ha:flags { + } + y1 = 0.679958mm + } + ha:line.15 { + clearance = 0.0 + y2 = 0.679958mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 0.979932mm + x2 = 1.979932mm + ha:flags { + } + y1 = 0.679958mm + } + ha:line.18 { + clearance = 0.0 + y2 = 1.679958mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 0.979932mm + x2 = 0.979932mm + ha:flags { + } + y1 = 0.679958mm + } + } + ha:combining { + } + } + } + } + uid = xK4LY0258SGWTnYfnvwAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/0402.scad =================================================================== --- tags/2.3.0/pcblib/smd/0402.scad (nonexistent) +++ tags/2.3.0/pcblib/smd/0402.scad (revision 33253) @@ -0,0 +1,20 @@ +module part_0402(len=1.0, width=0.5, height=0.35, pad_len=0.25) +{ + union() { + translate([0,0,height/2]) { + // body + color([0.1,0.1,0.1]) + cube([len-2*pad_len,width,height], center=true); + // terminals + color([0.8,0.8,0.8]) { + translate([+len/2-pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + color([0.8,0.8,0.8]) { + translate([-len/2+pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + } + } +} + Index: tags/2.3.0/pcblib/smd/0603.fp =================================================================== --- tags/2.3.0/pcblib/smd/0603.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/0603.fp (revision 33253) @@ -0,0 +1,212 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = 0603 Standard SMT resistor, capacitor etc + openscad = 0603.scad + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.374904mm + -0.499872mm + -0.374904mm + -0.499872mm + -0.374904mm + 0.499872mm + 0.374904mm + 0.499872mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 17.76mil + -0.576072mm + -17.76mil + -0.576072mm + -17.76mil + 0.576072mm + 17.76mil + 0.576072mm + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.374904mm + -0.499872mm + -0.374904mm + -0.499872mm + -0.374904mm + 0.499872mm + 0.374904mm + 0.499872mm + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 27.76mil + rot = 0.000000 + y = 0.830072mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 2.005076mm + rot = 0.000000 + y = 0.830072mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 21.85mil + y = 0.029972mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 0.830072mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 53.35mil + x2 = 53.35mil + ha:flags { + } + y1 = 0.830072mm + } + ha:line.12 { + clearance = 0.0 + y2 = 0.830072mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 53.35mil + x2 = 53.35mil + ha:flags { + } + y1 = 0.830072mm + } + ha:line.15 { + clearance = 0.0 + y2 = 0.830072mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 53.35mil + x2 = 2.35509mm + ha:flags { + } + y1 = 0.830072mm + } + ha:line.18 { + clearance = 0.0 + y2 = 1.830072mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 53.35mil + x2 = 53.35mil + ha:flags { + } + y1 = 0.830072mm + } + } + ha:combining { + } + } + } + } + uid = XViXVIINgyaT6qmUrpMAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/0603.scad =================================================================== --- tags/2.3.0/pcblib/smd/0603.scad (nonexistent) +++ tags/2.3.0/pcblib/smd/0603.scad (revision 33253) @@ -0,0 +1,20 @@ +module part_0603(len=1.6, width=0.8, height=0.45, pad_len=0.3) +{ + union() { + translate([0,0,height/2]) { + // body + color([0.1,0.1,0.1]) + cube([len-2*pad_len,width,height], center=true); + // terminals + color([0.8,0.8,0.8]) { + translate([+len/2-pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + color([0.8,0.8,0.8]) { + translate([-len/2+pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + } + } +} + Index: tags/2.3.0/pcblib/smd/0805.fp =================================================================== --- tags/2.3.0/pcblib/smd/0805.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/0805.fp (revision 33253) @@ -0,0 +1,236 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = 0805 Standard SMT resistor, capacitor etc + openscad = 0805.scad + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.649986mm + -0.749808mm + -0.649986mm + -0.749808mm + -0.649986mm + 0.749808mm + 0.649986mm + 0.749808mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.726186mm + -32.52mil + -0.726186mm + -32.52mil + -0.726186mm + 32.52mil + 0.726186mm + 32.52mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.649986mm + -0.749808mm + -0.649986mm + -0.749808mm + -0.649986mm + 0.749808mm + 0.649986mm + 0.749808mm + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 38.59mil + rot = 0.000000 + y = 42.52mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 109.45mil + rot = 0.000000 + y = 42.52mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 14.97mil + thickness = 8.0mil + ha:attributes { + } + x1 = 70.09mil + x2 = 77.95mil + ha:flags { + } + y1 = 14.97mil + } + ha:line.12 { + clearance = 0.0 + y2 = 1.779778mm + thickness = 8.0mil + ha:attributes { + } + x1 = 70.09mil + x2 = 77.95mil + ha:flags { + } + y1 = 1.779778mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 42.52mil + y = 0.279908mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.15 { + clearance = 0.0 + y2 = 42.52mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 1.880108mm + x2 = 1.880108mm + ha:flags { + } + y1 = 42.52mil + } + ha:line.18 { + clearance = 0.0 + y2 = 42.52mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.880108mm + x2 = 1.880108mm + ha:flags { + } + y1 = 42.52mil + } + ha:line.21 { + clearance = 0.0 + y2 = 42.52mil + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.880108mm + x2 = 2.880108mm + ha:flags { + } + y1 = 42.52mil + } + ha:line.24 { + clearance = 0.0 + y2 = 2.080008mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.880108mm + x2 = 1.880108mm + ha:flags { + } + y1 = 42.52mil + } + } + ha:combining { + } + } + } + } + uid = Gb4CEJNqF8FflGx6irgAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/0805.scad =================================================================== --- tags/2.3.0/pcblib/smd/0805.scad (nonexistent) +++ tags/2.3.0/pcblib/smd/0805.scad (revision 33253) @@ -0,0 +1,19 @@ +module part_0805(len=2, width=1.2, height=0.5, pad_len=0.4) +{ + union() { + translate([0,0,height/2]) { + // body + color([0.1,0.1,0.1]) + cube([len-2*pad_len,width,height], center=true); + // terminals + color([0.8,0.8,0.8]) { + translate([+len/2-pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + color([0.8,0.8,0.8]) { + translate([-len/2+pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + } + } +} Index: tags/2.3.0/pcblib/smd/1008.fp =================================================================== --- tags/2.3.0/pcblib/smd/1008.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/1008.fp (revision 33253) @@ -0,0 +1,235 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = 1008 Standard SMT resistor, capacitor etc + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.54991mm + -45.27mil + -0.54991mm + -45.27mil + -0.54991mm + 45.27mil + 0.54991mm + 45.27mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.62611mm + -48.27mil + -0.62611mm + -48.27mil + -0.62611mm + 48.27mil + 0.62611mm + 48.27mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.54991mm + -45.27mil + -0.54991mm + -45.27mil + -0.54991mm + 45.27mil + 0.54991mm + 45.27mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 0.88011mm + rot = 0.000000 + y = 58.27mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 3.480054mm + rot = 0.000000 + y = 58.27mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 13.0mil + thickness = 8.0mil + ha:attributes { + } + x1 = 72.06mil + x2 = 2.52984mm + ha:flags { + } + y1 = 13.0mil + } + ha:line.12 { + clearance = 0.0 + y2 = 103.54mil + thickness = 8.0mil + ha:attributes { + } + x1 = 72.06mil + x2 = 2.52984mm + ha:flags { + } + y1 = 103.54mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 1.379982mm + y = 0.679958mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.15 { + clearance = 0.0 + y2 = 58.27mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 2.180082mm + x2 = 2.180082mm + ha:flags { + } + y1 = 58.27mil + } + ha:line.18 { + clearance = 0.0 + y2 = 58.27mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.180082mm + x2 = 2.180082mm + ha:flags { + } + y1 = 58.27mil + } + ha:line.21 { + clearance = 0.0 + y2 = 58.27mil + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.180082mm + x2 = 3.180082mm + ha:flags { + } + y1 = 58.27mil + } + ha:line.24 { + clearance = 0.0 + y2 = 2.480058mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.180082mm + x2 = 2.180082mm + ha:flags { + } + y1 = 58.27mil + } + } + ha:combining { + } + } + } + } + uid = bZx6+gfdERtBSuYKqRIAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/1206.fp =================================================================== --- tags/2.3.0/pcblib/smd/1206.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/1206.fp (revision 33253) @@ -0,0 +1,236 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = 1206 Standard SMT resistor, capacitor etc + openscad = 1206.scad + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.726186mm + -1.02616mm + -0.726186mm + -1.02616mm + -0.726186mm + 1.02616mm + 0.726186mm + 1.02616mm + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 38.59mil + rot = 0.000000 + y = 1.28016mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 3.979926mm + rot = 0.000000 + y = 1.28016mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 13.0mil + thickness = 8.0mil + ha:attributes { + } + x1 = 1.880108mm + x2 = 121.26mil + ha:flags { + } + y1 = 13.0mil + } + ha:line.12 { + clearance = 0.0 + y2 = 2.23012mm + thickness = 8.0mil + ha:attributes { + } + x1 = 1.880108mm + x2 = 121.26mil + ha:flags { + } + y1 = 2.23012mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 66.14mil + y = 0.48006mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.15 { + clearance = 0.0 + y2 = 1.28016mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 97.64mil + x2 = 97.64mil + ha:flags { + } + y1 = 1.28016mm + } + ha:line.18 { + clearance = 0.0 + y2 = 1.28016mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 97.64mil + x2 = 97.64mil + ha:flags { + } + y1 = 1.28016mm + } + ha:line.21 { + clearance = 0.0 + y2 = 1.28016mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 97.64mil + x2 = 3.480056mm + ha:flags { + } + y1 = 1.28016mm + } + ha:line.24 { + clearance = 0.0 + y2 = 2.28016mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 97.64mil + x2 = 97.64mil + ha:flags { + } + y1 = 1.28016mm + } + } + ha:combining { + } + } + } + } + uid = pjaLj8tSfYLVqy1mjLYAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/1206.scad =================================================================== --- tags/2.3.0/pcblib/smd/1206.scad (nonexistent) +++ tags/2.3.0/pcblib/smd/1206.scad (revision 33253) @@ -0,0 +1,20 @@ +module part_1206(len=3.2, width=1.6, height=0.6, pad_len=0.5) +{ + union() { + translate([0,0,height/2]) { + // body + color([0.1,0.1,0.1]) + cube([len-2*pad_len,width,height], center=true); + // terminals + color([0.8,0.8,0.8]) { + translate([+len/2-pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + color([0.8,0.8,0.8]) { + translate([-len/2+pad_len/2, 0, 0]) + cube([pad_len, width, height], center=true); + } + } + } +} + Index: tags/2.3.0/pcblib/smd/1210.fp =================================================================== --- tags/2.3.0/pcblib/smd/1210.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/1210.fp (revision 33253) @@ -0,0 +1,235 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = 1210 Standard SMT resistor, capacitor etc + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.649986mm + -53.14mil + -0.649986mm + -53.14mil + -0.649986mm + 53.14mil + 0.649986mm + 53.14mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.726186mm + -56.14mil + -0.726186mm + -56.14mil + -0.726186mm + 56.14mil + 0.726186mm + 56.14mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.649986mm + -53.14mil + -0.649986mm + -53.14mil + -0.649986mm + 53.14mil + 0.649986mm + 53.14mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 38.59mil + rot = 0.000000 + y = 66.14mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 3.979926mm + rot = 0.000000 + y = 66.14mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 13.0mil + thickness = 8.0mil + ha:attributes { + } + x1 = 1.980184mm + x2 = 2.979928mm + ha:flags { + } + y1 = 13.0mil + } + ha:line.12 { + clearance = 0.0 + y2 = 119.28mil + thickness = 8.0mil + ha:attributes { + } + x1 = 1.980184mm + x2 = 2.979928mm + ha:flags { + } + y1 = 119.28mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 66.14mil + y = 34.64mil + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.15 { + clearance = 0.0 + y2 = 66.14mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 97.64mil + x2 = 97.64mil + ha:flags { + } + y1 = 66.14mil + } + ha:line.18 { + clearance = 0.0 + y2 = 66.14mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 97.64mil + x2 = 97.64mil + ha:flags { + } + y1 = 66.14mil + } + ha:line.21 { + clearance = 0.0 + y2 = 66.14mil + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 97.64mil + x2 = 3.480056mm + ha:flags { + } + y1 = 66.14mil + } + ha:line.24 { + clearance = 0.0 + y2 = 2.679956mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 97.64mil + x2 = 97.64mil + ha:flags { + } + y1 = 66.14mil + } + } + ha:combining { + } + } + } + } + uid = OUdoBtbWh4DAdxBsTZ4AAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/1806.fp =================================================================== --- tags/2.3.0/pcblib/smd/1806.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/1806.fp (revision 33253) @@ -0,0 +1,235 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = 1806 Standard SMT resistor, capacitor etc + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 31.495mil + -1.699895mm + -31.495mil + -1.699895mm + -31.495mil + 1.699895mm + 31.495mil + 1.699895mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.876173mm + -1.776095mm + -0.876173mm + -1.776095mm + -0.876173mm + 1.776095mm + 0.876173mm + 1.776095mm + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 31.495mil + -1.699895mm + -31.495mil + -1.699895mm + -31.495mil + 1.699895mm + 31.495mil + 1.699895mm + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.130173mm + rot = 0.000000 + y = 2.030095mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 5.130165mm + rot = 0.000000 + y = 2.030095mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 13.005mil + thickness = 8.0mil + ha:attributes { + } + x1 = 91.745mil + x2 = 3.930015mm + ha:flags { + } + y1 = 13.005mil + } + ha:line.12 { + clearance = 0.0 + y2 = 3.729863mm + thickness = 8.0mil + ha:attributes { + } + x1 = 91.745mil + x2 = 3.930015mm + ha:flags { + } + y1 = 3.729863mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 2.330069mm + y = 1.229995mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.15 { + clearance = 0.0 + y2 = 2.030095mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 3.130169mm + x2 = 3.130169mm + ha:flags { + } + y1 = 2.030095mm + } + ha:line.18 { + clearance = 0.0 + y2 = 2.030095mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.130169mm + x2 = 3.130169mm + ha:flags { + } + y1 = 2.030095mm + } + ha:line.21 { + clearance = 0.0 + y2 = 2.030095mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.130169mm + x2 = 4.130169mm + ha:flags { + } + y1 = 2.030095mm + } + ha:line.24 { + clearance = 0.0 + y2 = 3.030095mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.130169mm + x2 = 3.130169mm + ha:flags { + } + y1 = 2.030095mm + } + } + ha:combining { + } + } + } + } + uid = oTnHpP1lGoaqmqIT+SoAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/1825.fp =================================================================== --- tags/2.3.0/pcblib/smd/1825.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/1825.fp (revision 33253) @@ -0,0 +1,235 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = 1825 Standard SMT resistor, capacitor etc + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 31.495mil + -3.399917mm + -31.495mil + -3.399917mm + -31.495mil + 3.399917mm + 31.495mil + 3.399917mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.876173mm + -3.476117mm + -0.876173mm + -3.476117mm + -0.876173mm + 3.476117mm + 0.876173mm + 3.476117mm + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 31.495mil + -3.399917mm + -31.495mil + -3.399917mm + -31.495mil + 3.399917mm + 31.495mil + 3.399917mm + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.130173mm + rot = 0.000000 + y = 3.730117mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 5.130165mm + rot = 0.000000 + y = 3.730117mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 13.005mil + thickness = 8.0mil + ha:attributes { + } + x1 = 91.745mil + x2 = 3.930015mm + ha:flags { + } + y1 = 13.005mil + } + ha:line.12 { + clearance = 0.0 + y2 = 7.129907mm + thickness = 8.0mil + ha:attributes { + } + x1 = 91.745mil + x2 = 3.930015mm + ha:flags { + } + y1 = 7.129907mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 2.330069mm + y = 115.355mil + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.15 { + clearance = 0.0 + y2 = 3.730117mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 3.130169mm + x2 = 3.130169mm + ha:flags { + } + y1 = 3.730117mm + } + ha:line.18 { + clearance = 0.0 + y2 = 3.730117mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.130169mm + x2 = 3.130169mm + ha:flags { + } + y1 = 3.730117mm + } + ha:line.21 { + clearance = 0.0 + y2 = 3.730117mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.130169mm + x2 = 4.130169mm + ha:flags { + } + y1 = 3.730117mm + } + ha:line.24 { + clearance = 0.0 + y2 = 4.730117mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.130169mm + x2 = 3.130169mm + ha:flags { + } + y1 = 3.730117mm + } + } + ha:combining { + } + } + } + } + uid = k6ig2fGd0J0pkK+aZVsAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/2706.fp =================================================================== --- tags/2.3.0/pcblib/smd/2706.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/2706.fp (revision 33253) @@ -0,0 +1,259 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = 2706 Standard SMT resistor, capacitor etc + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 39.0mil + -42.0mil + -39.0mil + -42.0mil + -39.0mil + 42.0mil + 39.0mil + 42.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 42.0mil + -45.0mil + -42.0mil + -45.0mil + -42.0mil + 45.0mil + 42.0mil + 45.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 39.0mil + -42.0mil + -39.0mil + -42.0mil + -39.0mil + 42.0mil + 39.0mil + 42.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.422792mm + rot = 0.000000 + y = 1.498992mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 6.909192mm + rot = 0.000000 + y = 1.498992mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 2.870592mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.127392mm + x2 = 0.127392mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.10 { + clearance = 0.0 + y2 = 2.870592mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.127392mm + x2 = 8.204592mm + ha:flags { + } + y1 = 2.870592mm + } + ha:line.13 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 8.204592mm + x2 = 8.204592mm + ha:flags { + } + y1 = 2.870592mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 8.204592mm + x2 = 0.127392mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 8.712592mm + y = 1.498992mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.21 { + clearance = 0.0 + y2 = 1.498992mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 4.165992mm + x2 = 4.165992mm + ha:flags { + } + y1 = 1.498992mm + } + ha:line.24 { + clearance = 0.0 + y2 = 1.498992mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 4.165992mm + x2 = 4.165992mm + ha:flags { + } + y1 = 1.498992mm + } + ha:line.27 { + clearance = 0.0 + y2 = 1.498992mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 4.165992mm + x2 = 5.165992mm + ha:flags { + } + y1 = 1.498992mm + } + ha:line.30 { + clearance = 0.0 + y2 = 2.498992mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 4.165992mm + x2 = 4.165992mm + ha:flags { + } + y1 = 1.498992mm + } + } + ha:combining { + } + } + } + } + uid = FePvr11aAXKyPT8fC0AAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/DO214.fp =================================================================== --- tags/2.3.0/pcblib/smd/DO214.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/DO214.fp (revision 33253) @@ -0,0 +1,283 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = DO214 SMT diode (pin 1 is cathode) + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 70.0mil + -89.0mil + -70.0mil + -89.0mil + -70.0mil + 89.0mil + 70.0mil + 89.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 73.0mil + -92.0mil + -73.0mil + -92.0mil + -73.0mil + 92.0mil + 73.0mil + 92.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 70.0mil + -89.0mil + -70.0mil + -89.0mil + -70.0mil + 89.0mil + 70.0mil + 89.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.921783mm + rot = 0.000000 + y = 3.022992mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 8.306583mm + rot = 0.000000 + y = 3.022992mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 5.283592mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.762392mm + } + ha:line.10 { + clearance = 0.0 + y2 = 5.918592mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 2.032783mm + ha:flags { + } + y1 = 5.283592mm + } + ha:line.13 { + clearance = 0.0 + y2 = 5.918592mm + thickness = 10.0mil + ha:attributes { + } + x1 = 2.032783mm + x2 = 10.719583mm + ha:flags { + } + y1 = 5.918592mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 10.719583mm + x2 = 10.719583mm + ha:flags { + } + y1 = 5.918592mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 10.719583mm + x2 = 2.032783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.762392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 2.032783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 11.227583mm + y = 3.022992mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 3.022992mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.614183mm + x2 = 5.614183mm + ha:flags { + } + y1 = 3.022992mm + } + ha:line.30 { + clearance = 0.0 + y2 = 3.022992mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 5.614183mm + x2 = 5.614183mm + ha:flags { + } + y1 = 3.022992mm + } + ha:line.33 { + clearance = 0.0 + y2 = 3.022992mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 5.614183mm + x2 = 6.614183mm + ha:flags { + } + y1 = 3.022992mm + } + ha:line.36 { + clearance = 0.0 + y2 = 4.022992mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 5.614183mm + x2 = 5.614183mm + ha:flags { + } + y1 = 3.022992mm + } + } + ha:combining { + } + } + } + } + uid = BVofxkidfNHI5Q7do+oAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/DO214.scad =================================================================== --- tags/2.3.0/pcblib/smd/DO214.scad (nonexistent) +++ tags/2.3.0/pcblib/smd/DO214.scad (revision 33253) @@ -0,0 +1,104 @@ +// Parametric model for DO214 AA/AB/AC packages +// +// Copyright (C) 2020 Alexey Kosilin +// +// File distribution license: +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// The above distribution license applies when the file is distributed as a +// stand alone model file or as part of a library, in both cases intended +// for reuse combined by the user with other openscad scripts. +// +// Use license: +// as a special exception, the content of the file may be +// embedded in an openscad script that represents a printed circuit board, +// for example when a board is exported by pcb-rnd. In such use case, +// the content of this file may be copied into the resulting board file +// with or without modifications, without affecting the board file's license +// in any way. +// + +module part_do214 (var) +{ + module impl (L, W, H, P, Tw, Th) + { + delta = 1e-3 ; + $fn = 30 ; + + module lead (P, Tw, Th) + color ([0.9, 0.9, 0.9]) + translate ([-delta, -Tw/2, -delta]) + { + translate ([0.3/2, 0, 0.3/2]) + rotate ([-90, 0, 0]) + cylinder (d = 0.3, h = Tw) ; + + translate ([0.3/2, 0, Th]) + rotate ([-90, 0, 0]) + cylinder (d = 0.3, h = Tw) ; + + translate ([0, 0, 0.3/2]) + cube ([0.3, Tw, Th - 0.3/2]) ; + + translate ([0.3/2, 0, 0]) + cube ([3*P - 0.3/2, Tw, 0.3]) ; + + translate ([0.3/2, 0, Th - 0.3/2]) + cube ([2*P - 0.3/2, Tw, 0.3]) ; + } + + module case() + hull() + { + translate ([0, 0, H/2]) + cube ([L*0.95, W*0.95, H], center = true) ; + + translate ([0, 0, Th]) + cube ([L, W, delta], center = true) ; + } + + color ([0.5, 0.5, 0.5]) + intersection() + { + translate ([-L/3, -5, -5]) + cube ([0.5, 10, 10]) ; + + scale (1.002) + case() ; + } + + color ([0.3, 0.3, 0.3]) + case() ; + + translate ([-L/2-P, 0, 0]) + lead (P, Tw, Th) ; + + translate ([L/2+P, 0, 0]) + mirror ([1, 0, 0]) + lead (P, Tw, Th) ; + } + + variants = [ "AA", "AB", "AC" ] ; + + L = [ 4.57, 7.11, 4.6 ] ; + W = [ 3.94, 6.22, 2.90 ] ; + H = [ 2.5, 2.62, 2.45 ] ; + Tw = [ 2.21, 3.2, 1.65 ] ; + Tl = [ 5.59, 8.13, 5.35 ] ; + + idx = search ([var], variants)[0] ; + + impl (L[idx], W[idx], H[idx], (Tl[idx]-L[idx]) / 2, Tw[idx], H[idx]/2) ; +} Index: tags/2.3.0/pcblib/smd/DO214AB.fp =================================================================== --- tags/2.3.0/pcblib/smd/DO214AB.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/DO214AB.fp (revision 33253) @@ -0,0 +1,285 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = DO214AB SMT diode (pin 1 is cathode) + openscad-param="AB" + openscad=DO214.scad + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 72.5mil + -92.5mil + -72.5mil + -92.5mil + -72.5mil + 92.5mil + 72.5mil + 92.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 75.5mil + -95.5mil + -75.5mil + -95.5mil + -75.5mil + 95.5mil + 75.5mil + 95.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 72.5mil + -92.5mil + -72.5mil + -92.5mil + -72.5mil + 92.5mil + 72.5mil + 92.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.997983mm + rot = 0.000000 + y = 3.124592mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 8.535183mm + rot = 0.000000 + y = 3.124592mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 5.461392mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.787792mm + } + ha:line.10 { + clearance = 0.0 + y2 = 6.121792mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 2.083583mm + ha:flags { + } + y1 = 5.461392mm + } + ha:line.13 { + clearance = 0.0 + y2 = 6.121792mm + thickness = 10.0mil + ha:attributes { + } + x1 = 2.083583mm + x2 = 11.024383mm + ha:flags { + } + y1 = 6.121792mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 11.024383mm + x2 = 11.024383mm + ha:flags { + } + y1 = 6.121792mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 11.024383mm + x2 = 2.083583mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.787792mm + thickness = 10.0mil + ha:attributes { + } + x1 = 2.083583mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 11.532383mm + y = 3.124592mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 3.124592mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.766583mm + x2 = 5.766583mm + ha:flags { + } + y1 = 3.124592mm + } + ha:line.30 { + clearance = 0.0 + y2 = 3.124592mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 5.766583mm + x2 = 5.766583mm + ha:flags { + } + y1 = 3.124592mm + } + ha:line.33 { + clearance = 0.0 + y2 = 3.124592mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 5.766583mm + x2 = 6.766583mm + ha:flags { + } + y1 = 3.124592mm + } + ha:line.36 { + clearance = 0.0 + y2 = 4.124592mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 5.766583mm + x2 = 5.766583mm + ha:flags { + } + y1 = 3.124592mm + } + } + ha:combining { + } + } + } + } + uid = LJaVZUMLh15GoNd+Ga8AAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/MPAK.fp =================================================================== --- tags/2.3.0/pcblib/smd/MPAK.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/MPAK.fp (revision 33253) @@ -0,0 +1,381 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = MPAK + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 15.5mil + -43.5mil + -15.5mil + -43.5mil + -15.5mil + 43.5mil + 15.5mil + 43.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 18.5mil + -46.5mil + -18.5mil + -46.5mil + -18.5mil + 46.5mil + 18.5mil + 46.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 15.5mil + -43.5mil + -15.5mil + -43.5mil + -15.5mil + 43.5mil + 15.5mil + 43.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 80.5mil + 43.5mil + 80.5mil + -43.5mil + -80.5mil + -43.5mil + -80.5mil + 43.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 83.5mil + 46.5mil + 83.5mil + -46.5mil + -83.5mil + -46.5mil + -83.5mil + 46.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 80.5mil + 43.5mil + 80.5mil + -43.5mil + -80.5mil + -43.5mil + -80.5mil + 43.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 0.940192mm + rot = 0.000000 + y = 12.751192mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 2.210192mm + rot = 0.000000 + y = 12.751192mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 3.480192mm + rot = 0.000000 + y = 12.751192mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.22 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 0 + xmirror = 0 + x = 4.750192mm + rot = 0.000000 + y = 12.751192mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.23 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 2.845192mm + rot = 0.000000 + y = 1.651392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 14.300592mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.127392mm + x2 = 0.127392mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.10 { + clearance = 0.0 + y2 = 14.300592mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.127392mm + x2 = 5.588392mm + ha:flags { + } + y1 = 14.300592mm + } + ha:line.13 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 5.588392mm + x2 = 5.588392mm + ha:flags { + } + y1 = 14.300592mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 5.588392mm + x2 = 0.127392mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 6.096392mm + y = 0.127392mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.24 { + clearance = 0.0 + y2 = 10.531232mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 2.845192mm + x2 = 2.845192mm + ha:flags { + } + y1 = 10.531232mm + } + ha:line.27 { + clearance = 0.0 + y2 = 12.751192mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 0.940192mm + x2 = 0.940192mm + ha:flags { + } + y1 = 12.751192mm + } + ha:line.30 { + clearance = 0.0 + y2 = 13.751192mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 0.940192mm + x2 = 0.940192mm + ha:flags { + } + y1 = 12.751192mm + } + ha:line.33 { + clearance = 0.0 + y2 = 12.751192mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 0.940192mm + x2 = 1.940192mm + ha:flags { + } + y1 = 12.751192mm + } + } + ha:combining { + } + } + } + } + uid = eZwOg7hh3XSQ6QI9EysAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SC70_3.fp =================================================================== --- tags/2.3.0/pcblib/smd/SC70_3.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SC70_3.fp (revision 33253) @@ -0,0 +1,277 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SC70_3 SMT transistor, 3 pins + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 14.5mil + -17.5mil + -14.5mil + -17.5mil + -14.5mil + 17.5mil + 14.5mil + 17.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 17.5mil + -20.5mil + -17.5mil + -20.5mil + -17.5mil + 20.5mil + 17.5mil + 20.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 14.5mil + -17.5mil + -14.5mil + -17.5mil + -14.5mil + 17.5mil + 14.5mil + 17.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 32.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 83.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 58.5mil + rot = 0.000000 + y = 35.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:line.10 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 105.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.13 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 105.5mil + x2 = 105.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.16 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 105.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 125.5mil + y = 11.5mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.22 { + clearance = 0.0 + y2 = 2.087033mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 1.477433mm + x2 = 1.477433mm + ha:flags { + } + y1 = 2.087033mm + } + ha:line.25 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 32.5mil + x2 = 32.5mil + ha:flags { + } + y1 = 105.5mil + } + ha:line.28 { + clearance = 0.0 + y2 = 3.6797mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 32.5mil + x2 = 32.5mil + ha:flags { + } + y1 = 105.5mil + } + ha:line.31 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 32.5mil + x2 = 1.8255mm + ha:flags { + } + y1 = 105.5mil + } + } + ha:combining { + } + } + } + } + uid = aeq5mTHtKdZxz1ABi/wAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SC70_4.fp =================================================================== --- tags/2.3.0/pcblib/smd/SC70_4.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SC70_4.fp (revision 33253) @@ -0,0 +1,363 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SC70_4 SMT transistor, 4 pins + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -16.0mil + -14.5mil + -16.0mil + 14.5mil + 16.0mil + 14.5mil + 16.0mil + -14.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -19.0mil + -17.5mil + -19.0mil + 17.5mil + 19.0mil + 17.5mil + 19.0mil + -17.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -16.0mil + -14.5mil + -16.0mil + 14.5mil + 16.0mil + 14.5mil + 16.0mil + -14.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 14.5mil + -17.5mil + -14.5mil + -17.5mil + -14.5mil + 17.5mil + 14.5mil + 17.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 17.5mil + -20.5mil + -17.5mil + -20.5mil + -17.5mil + 20.5mil + 17.5mil + 20.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 14.5mil + -17.5mil + -14.5mil + -17.5mil + -14.5mil + 17.5mil + 14.5mil + 17.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 37.0mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 83.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 83.5mil + rot = 0.000000 + y = 35.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.22 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 32.5mil + rot = 0.000000 + y = 35.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:line.10 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 105.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.13 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 105.5mil + x2 = 105.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.16 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 105.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 125.5mil + y = 11.5mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.23 { + clearance = 0.0 + y2 = 70.5mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 59.125mil + x2 = 59.125mil + ha:flags { + } + y1 = 70.5mil + } + ha:line.26 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 32.5mil + x2 = 32.5mil + ha:flags { + } + y1 = 105.5mil + } + ha:line.29 { + clearance = 0.0 + y2 = 3.6797mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 32.5mil + x2 = 32.5mil + ha:flags { + } + y1 = 105.5mil + } + ha:line.32 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 32.5mil + x2 = 1.8255mm + ha:flags { + } + y1 = 105.5mil + } + } + ha:combining { + } + } + } + } + uid = lUXAYtVgjXtuvW/Gy1MAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SC90.fp =================================================================== --- tags/2.3.0/pcblib/smd/SC90.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SC90.fp (revision 33253) @@ -0,0 +1,277 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SC90 SMT transistor, 3 pins + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 12.0mil + -14.0mil + -12.0mil + -14.0mil + -12.0mil + 14.0mil + 12.0mil + 14.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 15.0mil + -17.0mil + -15.0mil + -17.0mil + -15.0mil + 17.0mil + 15.0mil + 17.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 12.0mil + -14.0mil + -12.0mil + -14.0mil + -12.0mil + 14.0mil + 12.0mil + 14.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 30.0mil + rot = 0.000000 + y = 91.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 69.0mil + rot = 0.000000 + y = 91.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 49.0mil + rot = 0.000000 + y = 32.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 111.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 13.0mil + x2 = 13.0mil + ha:flags { + } + y1 = 13.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 111.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 13.0mil + x2 = 86.0mil + ha:flags { + } + y1 = 111.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 13.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 86.0mil + x2 = 86.0mil + ha:flags { + } + y1 = 111.0mil + } + ha:line.16 { + clearance = 0.0 + y2 = 13.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 86.0mil + x2 = 13.0mil + ha:flags { + } + y1 = 13.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 106.0mil + y = 13.0mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.22 { + clearance = 0.0 + y2 = 1.811866mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 1.253066mm + x2 = 1.253066mm + ha:flags { + } + y1 = 1.811866mm + } + ha:line.25 { + clearance = 0.0 + y2 = 91.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 30.0mil + x2 = 30.0mil + ha:flags { + } + y1 = 91.0mil + } + ha:line.28 { + clearance = 0.0 + y2 = 3.3114mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 30.0mil + x2 = 30.0mil + ha:flags { + } + y1 = 91.0mil + } + ha:line.31 { + clearance = 0.0 + y2 = 91.0mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 30.0mil + x2 = 1.762mm + ha:flags { + } + y1 = 91.0mil + } + } + ha:combining { + } + } + } + } + uid = Y7qfWU1Va5qxQ5ui32QAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOD106A.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOD106A.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOD106A.fp (revision 33253) @@ -0,0 +1,283 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOD106A SMT diode (pin 1 is cathode) + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 51.0mil + -68.0mil + -51.0mil + -68.0mil + -51.0mil + 68.0mil + 51.0mil + 68.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 54.0mil + -71.0mil + -54.0mil + -71.0mil + -54.0mil + 71.0mil + 54.0mil + 71.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 51.0mil + -68.0mil + -51.0mil + -68.0mil + -51.0mil + 68.0mil + 51.0mil + 68.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.286783mm + rot = 0.000000 + y = 2.337192mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 6.147583mm + rot = 0.000000 + y = 2.337192mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 4.064392mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.609992mm + } + ha:line.10 { + clearance = 0.0 + y2 = 4.546992mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 1.550183mm + ha:flags { + } + y1 = 4.064392mm + } + ha:line.13 { + clearance = 0.0 + y2 = 4.546992mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.550183mm + x2 = 7.925583mm + ha:flags { + } + y1 = 4.546992mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 7.925583mm + x2 = 7.925583mm + ha:flags { + } + y1 = 4.546992mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 7.925583mm + x2 = 1.550183mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.609992mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.550183mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 8.433583mm + y = 2.337192mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 2.337192mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 4.217183mm + x2 = 4.217183mm + ha:flags { + } + y1 = 2.337192mm + } + ha:line.30 { + clearance = 0.0 + y2 = 2.337192mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 4.217183mm + x2 = 4.217183mm + ha:flags { + } + y1 = 2.337192mm + } + ha:line.33 { + clearance = 0.0 + y2 = 2.337192mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 4.217183mm + x2 = 5.217183mm + ha:flags { + } + y1 = 2.337192mm + } + ha:line.36 { + clearance = 0.0 + y2 = 3.337192mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 4.217183mm + x2 = 4.217183mm + ha:flags { + } + y1 = 2.337192mm + } + } + ha:combining { + } + } + } + } + uid = nAb7/3R/VK5t4jRpvCYAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOD110.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOD110.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOD110.fp (revision 33253) @@ -0,0 +1,283 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOD110 SMT diode (pin 1 is cathode) + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 23.0mil + -38.0mil + -23.0mil + -38.0mil + -23.0mil + 38.0mil + 23.0mil + 38.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 26.0mil + -41.0mil + -26.0mil + -41.0mil + -26.0mil + 41.0mil + 26.0mil + 41.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 23.0mil + -38.0mil + -23.0mil + -38.0mil + -23.0mil + 38.0mil + 23.0mil + 38.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.372383mm + rot = 0.000000 + y = 1.371992mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 2.845583mm + rot = 0.000000 + y = 1.371992mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 2.337192mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.406792mm + } + ha:line.10 { + clearance = 0.0 + y2 = 2.616592mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.838983mm + ha:flags { + } + y1 = 2.337192mm + } + ha:line.13 { + clearance = 0.0 + y2 = 2.616592mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.838983mm + x2 = 3.709183mm + ha:flags { + } + y1 = 2.616592mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 3.709183mm + x2 = 3.709183mm + ha:flags { + } + y1 = 2.616592mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 3.709183mm + x2 = 0.838983mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.406792mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.838983mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 4.217183mm + y = 1.371992mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 1.371992mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 2.108983mm + x2 = 2.108983mm + ha:flags { + } + y1 = 1.371992mm + } + ha:line.30 { + clearance = 0.0 + y2 = 1.371992mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.108983mm + x2 = 2.108983mm + ha:flags { + } + y1 = 1.371992mm + } + ha:line.33 { + clearance = 0.0 + y2 = 1.371992mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.108983mm + x2 = 3.108983mm + ha:flags { + } + y1 = 1.371992mm + } + ha:line.36 { + clearance = 0.0 + y2 = 2.371992mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.108983mm + x2 = 2.108983mm + ha:flags { + } + y1 = 1.371992mm + } + } + ha:combining { + } + } + } + } + uid = GrzapLkK/Y8pdEkIr7EAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOD123.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOD123.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOD123.fp (revision 33253) @@ -0,0 +1,284 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOD123 SMT diode (pin 1 is cathode) + openscad=SOD123.scad + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 34.5mil + -40.5mil + -34.5mil + -40.5mil + -34.5mil + 40.5mil + 34.5mil + 40.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 37.5mil + -43.5mil + -37.5mil + -43.5mil + -37.5mil + 43.5mil + 37.5mil + 43.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 34.5mil + -40.5mil + -34.5mil + -40.5mil + -34.5mil + 40.5mil + 34.5mil + 40.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.651783mm + rot = 0.000000 + y = 1.422792mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 4.445783mm + rot = 0.000000 + y = 1.422792mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 2.438792mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.406792mm + } + ha:line.10 { + clearance = 0.0 + y2 = 2.718192mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 1.118383mm + ha:flags { + } + y1 = 2.438792mm + } + ha:line.13 { + clearance = 0.0 + y2 = 2.718192mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.118383mm + x2 = 5.588783mm + ha:flags { + } + y1 = 2.718192mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 5.588783mm + x2 = 5.588783mm + ha:flags { + } + y1 = 2.718192mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 5.588783mm + x2 = 1.118383mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.406792mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.118383mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 6.096783mm + y = 1.422792mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 1.422792mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 3.048783mm + x2 = 3.048783mm + ha:flags { + } + y1 = 1.422792mm + } + ha:line.30 { + clearance = 0.0 + y2 = 1.422792mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.048783mm + x2 = 3.048783mm + ha:flags { + } + y1 = 1.422792mm + } + ha:line.33 { + clearance = 0.0 + y2 = 1.422792mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.048783mm + x2 = 4.048783mm + ha:flags { + } + y1 = 1.422792mm + } + ha:line.36 { + clearance = 0.0 + y2 = 2.422792mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.048783mm + x2 = 3.048783mm + ha:flags { + } + y1 = 1.422792mm + } + } + ha:combining { + } + } + } + } + uid = bK7s+7eWCVc1F+i9KCMAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOD123.scad =================================================================== --- tags/2.3.0/pcblib/smd/SOD123.scad (nonexistent) +++ tags/2.3.0/pcblib/smd/SOD123.scad (revision 33253) @@ -0,0 +1,89 @@ +// Model for SOD123 package +// +// Copyright (C) 2020 Alexey Kosilin +// +// File distribution license: +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// The above distribution license applies when the file is distributed as a +// stand alone model file or as part of a library, in both cases intended +// for reuse combined by the user with other openscad scripts. +// +// Use license: +// as a special exception, the content of the file may be +// embedded in an openscad script that represents a printed circuit board, +// for example when a board is exported by pcb-rnd. In such use case, +// the content of this file may be copied into the resulting board file +// with or without modifications, without affecting the board file's license +// in any way. +// + +module part_sod123() +{ + $fn = 30 ; + + A = 1.35 ; + D = 1.8 ; + E = 2.84 ; + He = 3.86 ; + + c = 0.15 ; + L = 0.25 ; + b = 0.71 ; + l2 = 0.15 ; + + module lead() + color ([0.9, 0.9, 0.9]) + { + translate ([0, -b/2, L+c]) + rotate ([-90, 0, 0]) + rotate_extrude (angle = 90) + translate ([L, 0, 0]) + square ([c, b]) ; + + translate ([L, -b/2, L+c]) + cube ([c, b, A/2 - (L+c)]) ; + + translate ([c+l2+L, b/2, A/2]) + rotate ([90, -90, 0]) + rotate_extrude (angle = 90) + translate ([l2, 0, 0]) + square ([c, b]) ; + } + + module case() + translate ([He/2 - E/2 - He/2, -D/2, 0]) + cube ([E, D, A]) ; + + translate ([-He/2, 0, 0]) + lead() ; + + translate ([He/2, 0, 0]) + mirror ([1, 0, 0]) + lead() ; + + color ([0.5, 0.5, 0.5]) + intersection() + { + translate ([-He/4, -5, -5]) + cube ([0.3, 10, 10]) ; + + scale (1.002) + case() ; + } + + color ([0.3, 0.3, 0.3]) + case() ; +} Index: tags/2.3.0/pcblib/smd/SOD323.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOD323.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOD323.fp (revision 33253) @@ -0,0 +1,284 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOD323 SMT diode (pin 1 is cathode) + openscad=SOD323.scad + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 25.5mil + -35.5mil + -25.5mil + -35.5mil + -25.5mil + 35.5mil + 25.5mil + 35.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 28.5mil + -38.5mil + -28.5mil + -38.5mil + -28.5mil + 38.5mil + 28.5mil + 38.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 25.5mil + -35.5mil + -25.5mil + -35.5mil + -25.5mil + 35.5mil + 25.5mil + 35.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.423183mm + rot = 0.000000 + y = 1.270392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 3.302783mm + rot = 0.000000 + y = 1.270392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 2.159392mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.381392mm + } + ha:line.10 { + clearance = 0.0 + y2 = 2.413392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.889783mm + ha:flags { + } + y1 = 2.159392mm + } + ha:line.13 { + clearance = 0.0 + y2 = 2.413392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.889783mm + x2 = 4.217183mm + ha:flags { + } + y1 = 2.413392mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 4.217183mm + x2 = 4.217183mm + ha:flags { + } + y1 = 2.413392mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 4.217183mm + x2 = 0.889783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.381392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.889783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 4.725183mm + y = 1.270392mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 1.270392mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 2.362983mm + x2 = 2.362983mm + ha:flags { + } + y1 = 1.270392mm + } + ha:line.30 { + clearance = 0.0 + y2 = 1.270392mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.362983mm + x2 = 2.362983mm + ha:flags { + } + y1 = 1.270392mm + } + ha:line.33 { + clearance = 0.0 + y2 = 1.270392mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.362983mm + x2 = 3.362983mm + ha:flags { + } + y1 = 1.270392mm + } + ha:line.36 { + clearance = 0.0 + y2 = 2.270392mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.362983mm + x2 = 2.362983mm + ha:flags { + } + y1 = 1.270392mm + } + } + ha:combining { + } + } + } + } + uid = 2dW9Tvw7RTxCX0jj23YAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOD323.scad =================================================================== --- tags/2.3.0/pcblib/smd/SOD323.scad (nonexistent) +++ tags/2.3.0/pcblib/smd/SOD323.scad (revision 33253) @@ -0,0 +1,79 @@ +// Model for SOD323 package +// +// Copyright (C) 2020 Alexey Kosilin +// +// File distribution license: +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// The above distribution license applies when the file is distributed as a +// stand alone model file or as part of a library, in both cases intended +// for reuse combined by the user with other openscad scripts. +// +// Use license: +// as a special exception, the content of the file may be +// embedded in an openscad script that represents a printed circuit board, +// for example when a board is exported by pcb-rnd. In such use case, +// the content of this file may be copied into the resulting board file +// with or without modifications, without affecting the board file's license +// in any way. +// + +module part_sod323() +{ + $fn = 30 ; + + module lead() + color ([0.9, 0.9, 0.9]) + { + translate ([0, -0.35/2, 0.4]) + rotate ([-90, 0, 0]) + rotate_extrude (angle = 90) + translate ([0.25, 0, 0]) + square ([0.15, 0.35]) ; + + translate ([0.25, -0.35/2, 0.4]) + cube ([0.15, 0.35, 1.35/2 - 0.4]) ; + + translate ([0.5, 0.35/2, 1.35/2]) + rotate ([90, -90, 0]) + rotate_extrude (angle = 90) + translate ([0.1, 0, 0]) + square ([0.15, 0.35]) ; + } + + module case() + translate ([-0.9, -0.7, 0]) + cube ([1.8, 1.4, 1.35]) ; + + translate ([-0.5-0.9, 0, 0]) + lead() ; + + mirror ([1, 0, 0]) + translate ([-0.5-0.9, 0, 0]) + lead() ; + + color ([0.5, 0.5, 0.5]) + intersection() + { + translate ([-0.7, -5, -5]) + cube ([0.3, 10, 10]) ; + + scale (1.002) + case() ; + } + + color ([0.3, 0.3, 0.3]) + case() ; +} Index: tags/2.3.0/pcblib/smd/SOD80.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOD80.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOD80.fp (revision 33253) @@ -0,0 +1,283 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOD80 SMT diode (pin 1 is cathode) + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 26.5mil + -42.5mil + -26.5mil + -42.5mil + -26.5mil + 42.5mil + 26.5mil + 42.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 29.5mil + -45.5mil + -29.5mil + -45.5mil + -29.5mil + 45.5mil + 29.5mil + 45.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 26.5mil + -42.5mil + -26.5mil + -42.5mil + -26.5mil + 42.5mil + 26.5mil + 42.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.473983mm + rot = 0.000000 + y = 1.524392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 4.420383mm + rot = 0.000000 + y = 1.524392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 2.616592mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.432192mm + } + ha:line.10 { + clearance = 0.0 + y2 = 2.921392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.915183mm + ha:flags { + } + y1 = 2.616592mm + } + ha:line.13 { + clearance = 0.0 + y2 = 2.921392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.915183mm + x2 = 5.385583mm + ha:flags { + } + y1 = 2.921392mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 5.385583mm + x2 = 5.385583mm + ha:flags { + } + y1 = 2.921392mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 5.385583mm + x2 = 0.915183mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.432192mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.915183mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 5.893583mm + y = 1.524392mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 1.524392mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 2.947183mm + x2 = 2.947183mm + ha:flags { + } + y1 = 1.524392mm + } + ha:line.30 { + clearance = 0.0 + y2 = 1.524392mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.947183mm + x2 = 2.947183mm + ha:flags { + } + y1 = 1.524392mm + } + ha:line.33 { + clearance = 0.0 + y2 = 1.524392mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.947183mm + x2 = 3.947183mm + ha:flags { + } + y1 = 1.524392mm + } + ha:line.36 { + clearance = 0.0 + y2 = 2.524392mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.947183mm + x2 = 2.947183mm + ha:flags { + } + y1 = 1.524392mm + } + } + ha:combining { + } + } + } + } + uid = VTNdQbVwPxfgsvfI80oAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOD87.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOD87.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOD87.fp (revision 33253) @@ -0,0 +1,283 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOD87 SMT diode (pin 1 is cathode) + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 30.5mil + -56.5mil + -30.5mil + -56.5mil + -30.5mil + 56.5mil + 30.5mil + 56.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 33.5mil + -59.5mil + -33.5mil + -59.5mil + -33.5mil + 59.5mil + 33.5mil + 59.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 30.5mil + -56.5mil + -30.5mil + -56.5mil + -30.5mil + 56.5mil + 30.5mil + 56.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.677183mm + rot = 0.000000 + y = 1.981592mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 4.623583mm + rot = 0.000000 + y = 1.981592mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 3.429392mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.533792mm + } + ha:line.10 { + clearance = 0.0 + y2 = 3.835792mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 1.016783mm + ha:flags { + } + y1 = 3.429392mm + } + ha:line.13 { + clearance = 0.0 + y2 = 3.835792mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.016783mm + x2 = 5.791983mm + ha:flags { + } + y1 = 3.835792mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 5.791983mm + x2 = 5.791983mm + ha:flags { + } + y1 = 3.835792mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 5.791983mm + x2 = 1.016783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.533792mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.016783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 6.299983mm + y = 1.981592mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 1.981592mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 3.150383mm + x2 = 3.150383mm + ha:flags { + } + y1 = 1.981592mm + } + ha:line.30 { + clearance = 0.0 + y2 = 1.981592mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.150383mm + x2 = 3.150383mm + ha:flags { + } + y1 = 1.981592mm + } + ha:line.33 { + clearance = 0.0 + y2 = 1.981592mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.150383mm + x2 = 4.150383mm + ha:flags { + } + y1 = 1.981592mm + } + ha:line.36 { + clearance = 0.0 + y2 = 2.981592mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.150383mm + x2 = 3.150383mm + ha:flags { + } + y1 = 1.981592mm + } + } + ha:combining { + } + } + } + } + uid = Q1gCDJRE1xA3loRFXQsAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOT143.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOT143.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT143.fp (revision 33253) @@ -0,0 +1,363 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOT143 SMT transistor, 4 pins + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -18.5mil + -17.0mil + -18.5mil + 17.0mil + 18.5mil + 17.0mil + 18.5mil + -17.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -21.5mil + -20.0mil + -21.5mil + 20.0mil + 21.5mil + 20.0mil + 21.5mil + -20.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -18.5mil + -17.0mil + -18.5mil + 17.0mil + 18.5mil + 17.0mil + 18.5mil + -17.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 17.0mil + -20.0mil + -17.0mil + -20.0mil + -17.0mil + 20.0mil + 17.0mil + 20.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 20.0mil + -23.0mil + -20.0mil + -23.0mil + -20.0mil + 23.0mil + 20.0mil + 23.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 17.0mil + -20.0mil + -17.0mil + -20.0mil + -17.0mil + 20.0mil + 17.0mil + 20.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 39.5mil + rot = 0.000000 + y = 120.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 109.0mil + rot = 0.000000 + y = 120.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 109.0mil + rot = 0.000000 + y = 38.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.22 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 35.0mil + rot = 0.000000 + y = 38.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 149.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 10.0mil + x2 = 10.0mil + ha:flags { + } + y1 = 10.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 149.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 10.0mil + x2 = 134.0mil + ha:flags { + } + y1 = 149.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 10.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 134.0mil + x2 = 134.0mil + ha:flags { + } + y1 = 149.0mil + } + ha:line.16 { + clearance = 0.0 + y2 = 10.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 134.0mil + x2 = 10.0mil + ha:flags { + } + y1 = 10.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 154.0mil + y = 10.0mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.23 { + clearance = 0.0 + y2 = 79.0mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 73.125mil + x2 = 73.125mil + ha:flags { + } + y1 = 79.0mil + } + ha:line.26 { + clearance = 0.0 + y2 = 120.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 35.0mil + x2 = 35.0mil + ha:flags { + } + y1 = 120.0mil + } + ha:line.29 { + clearance = 0.0 + y2 = 4.048mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 35.0mil + x2 = 35.0mil + ha:flags { + } + y1 = 120.0mil + } + ha:line.32 { + clearance = 0.0 + y2 = 120.0mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 35.0mil + x2 = 1.889mm + ha:flags { + } + y1 = 120.0mil + } + } + ha:combining { + } + } + } + } + uid = 0oigisyzTIDYQhx/ge0AAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOT223.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOT223.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT223.fp (revision 33253) @@ -0,0 +1,363 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOT223 SMT transistor, 4 pins + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 28.0mil + -61.0mil + -28.0mil + -61.0mil + -28.0mil + 61.0mil + 28.0mil + 61.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 31.0mil + -64.0mil + -31.0mil + -64.0mil + -31.0mil + 64.0mil + 31.0mil + 64.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 28.0mil + -61.0mil + -28.0mil + -61.0mil + -28.0mil + 61.0mil + 28.0mil + 61.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 106.0mil + 61.0mil + 106.0mil + -61.0mil + -106.0mil + -61.0mil + -106.0mil + 61.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 109.0mil + 64.0mil + 109.0mil + -64.0mil + -109.0mil + -64.0mil + -109.0mil + 64.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 106.0mil + 61.0mil + 106.0mil + -61.0mil + -106.0mil + -61.0mil + -106.0mil + 61.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.448192mm + rot = 0.000000 + y = 8.483992mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 3.734192mm + rot = 0.000000 + y = 8.483992mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 6.045592mm + rot = 0.000000 + y = 8.483992mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.22 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 3.734192mm + rot = 0.000000 + y = 2.286392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 10.642992mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.127392mm + x2 = 0.127392mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.10 { + clearance = 0.0 + y2 = 10.642992mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.127392mm + x2 = 7.366392mm + ha:flags { + } + y1 = 10.642992mm + } + ha:line.13 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 7.366392mm + x2 = 7.366392mm + ha:flags { + } + y1 = 10.642992mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 7.366392mm + x2 = 0.127392mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 7.874392mm + y = 0.127392mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.23 { + clearance = 0.0 + y2 = 6.934592mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 3.740542mm + x2 = 3.740542mm + ha:flags { + } + y1 = 6.934592mm + } + ha:line.26 { + clearance = 0.0 + y2 = 8.483992mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.448192mm + x2 = 1.448192mm + ha:flags { + } + y1 = 8.483992mm + } + ha:line.29 { + clearance = 0.0 + y2 = 9.483992mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.448192mm + x2 = 1.448192mm + ha:flags { + } + y1 = 8.483992mm + } + ha:line.32 { + clearance = 0.0 + y2 = 8.483992mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.448192mm + x2 = 2.448192mm + ha:flags { + } + y1 = 8.483992mm + } + } + ha:combining { + } + } + } + } + uid = wL7+F9vz1VIcfqPPcnsAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOT23.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOT23.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT23.fp (revision 33253) @@ -0,0 +1,278 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOT23 SMT transistor, 3 pins + openscad=SOT23.scad + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 17.0mil + -20.0mil + -17.0mil + -20.0mil + -17.0mil + 20.0mil + 17.0mil + 20.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 20.0mil + -23.0mil + -20.0mil + -23.0mil + -20.0mil + 23.0mil + 20.0mil + 23.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 17.0mil + -20.0mil + -17.0mil + -20.0mil + -17.0mil + 20.0mil + 17.0mil + 20.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 35.0mil + rot = 0.000000 + y = 120.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 113.0mil + rot = 0.000000 + y = 120.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 74.0mil + rot = 0.000000 + y = 38.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 149.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 10.0mil + x2 = 10.0mil + ha:flags { + } + y1 = 10.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 149.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 10.0mil + x2 = 138.0mil + ha:flags { + } + y1 = 149.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 10.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 138.0mil + x2 = 138.0mil + ha:flags { + } + y1 = 149.0mil + } + ha:line.16 { + clearance = 0.0 + y2 = 10.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 138.0mil + x2 = 10.0mil + ha:flags { + } + y1 = 10.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 158.0mil + y = 10.0mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.22 { + clearance = 0.0 + y2 = 2.353733mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 74.0mil + x2 = 74.0mil + ha:flags { + } + y1 = 2.353733mm + } + ha:line.25 { + clearance = 0.0 + y2 = 120.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 35.0mil + x2 = 35.0mil + ha:flags { + } + y1 = 120.0mil + } + ha:line.28 { + clearance = 0.0 + y2 = 4.048mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 35.0mil + x2 = 35.0mil + ha:flags { + } + y1 = 120.0mil + } + ha:line.31 { + clearance = 0.0 + y2 = 120.0mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 35.0mil + x2 = 1.889mm + ha:flags { + } + y1 = 120.0mil + } + } + ha:combining { + } + } + } + } + uid = YmnO2BUK2cjwZjFkzKMAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOT23.scad =================================================================== --- tags/2.3.0/pcblib/smd/SOT23.scad (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT23.scad (revision 33253) @@ -0,0 +1,68 @@ +// Model for SOT23 package +// +// Copyright (C) 2017,2020 Tibor 'Igor2' Palinkas +// +// File distribution license: +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// The above distribution license applies when the file is distributed as a +// stand alone model file or as part of a library, in both cases intended +// for reuse combined by the user with other openscad scripts. +// +// Use license: +// as a special exception, the content of the file may be +// embedded in an openscad script that represents a printed circuit board, +// for example when a board is exported by pcb-rnd. In such use case, +// the content of this file may be copied into the resulting board file +// with or without modifications, without affecting the board file's license +// in any way. +// + +module sot23() +{ + module sot23_() + { + // pin prototype + module pin(length, height, thick) + { + linear_extrude(height=thick) + scale([length, -height, 1]) + polygon([[0.3400,0.0000],[0.3900,0.0100],[0.4300,0.0300],[0.4600,0.0600],[0.4789,0.0908],[0.6279,0.8307],[0.6500,0.8600],[0.6900,0.8900],[0.7300,0.9000],[1.0000,0.9000],[1.0000,1.0000],[0.6700,1.0012],[0.6100,0.9900],[0.5600,0.9600],[0.5300,0.9200],[0.5200,0.9000],[0.3721,0.1693],[0.3500,0.1400],[0.3100,0.1100],[0.2700,0.1000],[0.0000,0.1000],[0.0000,0.0000]]); + } + + rotate([90,0,-90]) scale([1.13,1.13,1.13]) translate([-0.9, 0.4, -2.1 - 0.43/2]) { + // body + color([0.1,0.1,0.1]) + linear_extrude(height=2.9) + polygon([[-0.55,0],[-0.45,0.53],[0.45,0.53],[0.55,0],[0.45,-0.35],[-0.45,-0.35]]); + + // 3 pins + color([0.9, 0.9, 0.9]) { + translate([0.5,0,0.5-0.43/2]) + pin(0.5, 0.4, 0.43); + + translate([0.5,0,2.3-0.43/2]) + pin(0.5, 0.4, 0.43); + + translate([-0.5,0,1.45-0.43/2]) + pin(-0.5, 0.4, 0.43); + } + } + } + + // match rotation with stock footprint's + rotate([0,0,90]) + sot23_(); +} Index: tags/2.3.0/pcblib/smd/SOT23D.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOT23D.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT23D.fp (revision 33253) @@ -0,0 +1,279 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOT23D SMT diode (pin 1 is cathode) + openscad=SOT23.scad + openscad-transformation={rotate([0,0,-90])} + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 17.0mil + -20.0mil + -17.0mil + -20.0mil + -17.0mil + 20.0mil + 17.0mil + 20.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 20.0mil + -23.0mil + -20.0mil + -23.0mil + -20.0mil + 23.0mil + 20.0mil + 23.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 17.0mil + -20.0mil + -17.0mil + -20.0mil + -17.0mil + 20.0mil + 17.0mil + 20.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 35.0mil + rot = 0.000000 + y = 120.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 113.0mil + rot = 0.000000 + y = 120.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 74.0mil + rot = 0.000000 + y = 38.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 149.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 10.0mil + x2 = 10.0mil + ha:flags { + } + y1 = 10.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 149.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 10.0mil + x2 = 138.0mil + ha:flags { + } + y1 = 149.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 10.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 138.0mil + x2 = 138.0mil + ha:flags { + } + y1 = 149.0mil + } + ha:line.16 { + clearance = 0.0 + y2 = 10.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 138.0mil + x2 = 10.0mil + ha:flags { + } + y1 = 10.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 158.0mil + y = 10.0mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.22 { + clearance = 0.0 + y2 = 2.353733mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 74.0mil + x2 = 74.0mil + ha:flags { + } + y1 = 2.353733mm + } + ha:line.25 { + clearance = 0.0 + y2 = 120.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 35.0mil + x2 = 35.0mil + ha:flags { + } + y1 = 120.0mil + } + ha:line.28 { + clearance = 0.0 + y2 = 120.0mil + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 35.0mil + x2 = 1.889mm + ha:flags { + } + y1 = 120.0mil + } + ha:line.31 { + clearance = 0.0 + y2 = 4.048mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 35.0mil + x2 = 35.0mil + ha:flags { + } + y1 = 120.0mil + } + } + ha:combining { + } + } + } + } + uid = hksuSYo1TTefRrW2D28AAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOT25.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOT25.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT25.fp (revision 33253) @@ -0,0 +1,313 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOT25 SMT transistor, 5 pins + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 12.0mil + -20.0mil + -12.0mil + -20.0mil + -12.0mil + 20.0mil + 12.0mil + 20.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 15.0mil + -23.0mil + -15.0mil + -23.0mil + -15.0mil + 23.0mil + 15.0mil + 23.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 12.0mil + -20.0mil + -12.0mil + -20.0mil + -12.0mil + 20.0mil + 12.0mil + 20.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 30.0mil + rot = 0.000000 + y = 120.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 108.0mil + rot = 0.000000 + y = 120.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 108.0mil + rot = 0.000000 + y = 38.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.22 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 0 + xmirror = 0 + x = 69.0mil + rot = 0.000000 + y = 38.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.23 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 0 + xmirror = 0 + x = 30.0mil + rot = 0.000000 + y = 38.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 149.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 10.0mil + x2 = 10.0mil + ha:flags { + } + y1 = 10.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 149.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 10.0mil + x2 = 128.0mil + ha:flags { + } + y1 = 149.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 10.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 128.0mil + x2 = 128.0mil + ha:flags { + } + y1 = 149.0mil + } + ha:line.16 { + clearance = 0.0 + y2 = 10.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 128.0mil + x2 = 10.0mil + ha:flags { + } + y1 = 10.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 148.0mil + y = 10.0mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.24 { + clearance = 0.0 + y2 = 1.79832mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 69.0mil + x2 = 69.0mil + ha:flags { + } + y1 = 1.79832mm + } + ha:line.27 { + clearance = 0.0 + y2 = 120.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 30.0mil + x2 = 30.0mil + ha:flags { + } + y1 = 120.0mil + } + ha:line.30 { + clearance = 0.0 + y2 = 4.048mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 30.0mil + x2 = 30.0mil + ha:flags { + } + y1 = 120.0mil + } + ha:line.33 { + clearance = 0.0 + y2 = 120.0mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 30.0mil + x2 = 1.762mm + ha:flags { + } + y1 = 120.0mil + } + } + ha:combining { + } + } + } + } + uid = FitPy/jBEPpaQxnl1vgAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOT26.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOT26.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT26.fp (revision 33253) @@ -0,0 +1,331 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOT26 SMT transistor, 6 pins + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 12.0mil + -20.0mil + -12.0mil + -20.0mil + -12.0mil + 20.0mil + 12.0mil + 20.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 15.0mil + -23.0mil + -15.0mil + -23.0mil + -15.0mil + 23.0mil + 15.0mil + 23.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 12.0mil + -20.0mil + -12.0mil + -20.0mil + -12.0mil + 20.0mil + 12.0mil + 20.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 30.0mil + rot = 0.000000 + y = 120.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 69.0mil + rot = 0.000000 + y = 120.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 108.0mil + rot = 0.000000 + y = 120.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.22 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 0 + xmirror = 0 + x = 108.0mil + rot = 0.000000 + y = 38.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.23 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 0 + xmirror = 0 + x = 69.0mil + rot = 0.000000 + y = 38.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.24 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 0 + xmirror = 0 + x = 30.0mil + rot = 0.000000 + y = 38.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 149.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 10.0mil + x2 = 10.0mil + ha:flags { + } + y1 = 10.0mil + } + ha:line.10 { + clearance = 0.0 + y2 = 149.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 10.0mil + x2 = 128.0mil + ha:flags { + } + y1 = 149.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 10.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 128.0mil + x2 = 128.0mil + ha:flags { + } + y1 = 149.0mil + } + ha:line.16 { + clearance = 0.0 + y2 = 10.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 128.0mil + x2 = 10.0mil + ha:flags { + } + y1 = 10.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 148.0mil + y = 10.0mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.25 { + clearance = 0.0 + y2 = 79.0mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 69.0mil + x2 = 69.0mil + ha:flags { + } + y1 = 79.0mil + } + ha:line.28 { + clearance = 0.0 + y2 = 120.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 30.0mil + x2 = 30.0mil + ha:flags { + } + y1 = 120.0mil + } + ha:line.31 { + clearance = 0.0 + y2 = 4.048mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 30.0mil + x2 = 30.0mil + ha:flags { + } + y1 = 120.0mil + } + ha:line.34 { + clearance = 0.0 + y2 = 120.0mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 30.0mil + x2 = 1.762mm + ha:flags { + } + y1 = 120.0mil + } + } + ha:combining { + } + } + } + } + uid = kS4vnWF4YqQfyJe4Fo8AAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOT323.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOT323.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT323.fp (revision 33253) @@ -0,0 +1,277 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOT323 SMT transistor, 3 pins + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 14.5mil + -17.5mil + -14.5mil + -17.5mil + -14.5mil + 17.5mil + 14.5mil + 17.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 17.5mil + -20.5mil + -17.5mil + -20.5mil + -17.5mil + 20.5mil + 17.5mil + 20.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 14.5mil + -17.5mil + -14.5mil + -17.5mil + -14.5mil + 17.5mil + 14.5mil + 17.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 32.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 83.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 58.5mil + rot = 0.000000 + y = 35.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:line.10 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 105.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.13 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 105.5mil + x2 = 105.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.16 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 105.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 125.5mil + y = 11.5mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.22 { + clearance = 0.0 + y2 = 2.087033mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 1.477433mm + x2 = 1.477433mm + ha:flags { + } + y1 = 2.087033mm + } + ha:line.25 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 32.5mil + x2 = 32.5mil + ha:flags { + } + y1 = 105.5mil + } + ha:line.28 { + clearance = 0.0 + y2 = 3.6797mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 32.5mil + x2 = 32.5mil + ha:flags { + } + y1 = 105.5mil + } + ha:line.31 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 32.5mil + x2 = 1.8255mm + ha:flags { + } + y1 = 105.5mil + } + } + ha:combining { + } + } + } + } + uid = cXXouN6IWQ/t3brFf7YAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOT323D.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOT323D.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT323D.fp (revision 33253) @@ -0,0 +1,277 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOT323D SMT diode (pin 1 is cathode) + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 14.5mil + -17.5mil + -14.5mil + -17.5mil + -14.5mil + 17.5mil + 14.5mil + 17.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 17.5mil + -20.5mil + -17.5mil + -20.5mil + -17.5mil + 20.5mil + 17.5mil + 20.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 14.5mil + -17.5mil + -14.5mil + -17.5mil + -14.5mil + 17.5mil + 14.5mil + 17.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 32.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 83.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 58.5mil + rot = 0.000000 + y = 35.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:line.10 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 105.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.13 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 105.5mil + x2 = 105.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.16 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 105.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 125.5mil + y = 11.5mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.22 { + clearance = 0.0 + y2 = 2.087033mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 1.477433mm + x2 = 1.477433mm + ha:flags { + } + y1 = 2.087033mm + } + ha:line.25 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 32.5mil + x2 = 32.5mil + ha:flags { + } + y1 = 105.5mil + } + ha:line.28 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 32.5mil + x2 = 1.8255mm + ha:flags { + } + y1 = 105.5mil + } + ha:line.31 { + clearance = 0.0 + y2 = 3.6797mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 32.5mil + x2 = 32.5mil + ha:flags { + } + y1 = 105.5mil + } + } + ha:combining { + } + } + } + } + uid = bi96z3ATUk0N6MnhWkkAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOT325.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOT325.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT325.fp (revision 33253) @@ -0,0 +1,313 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOT325 SMT transistor, 5 pins + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 7.5mil + -17.5mil + -7.5mil + -17.5mil + -7.5mil + 17.5mil + 7.5mil + 17.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 10.5mil + -20.5mil + -10.5mil + -20.5mil + -10.5mil + 20.5mil + 10.5mil + 20.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 7.5mil + -17.5mil + -7.5mil + -17.5mil + -7.5mil + 17.5mil + 7.5mil + 17.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 25.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 76.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 76.5mil + rot = 0.000000 + y = 35.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.22 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 0 + xmirror = 0 + x = 51.5mil + rot = 0.000000 + y = 35.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.23 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 0 + xmirror = 0 + x = 25.5mil + rot = 0.000000 + y = 35.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:line.10 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 91.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.13 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 91.5mil + x2 = 91.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.16 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 91.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 111.5mil + y = 11.5mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.24 { + clearance = 0.0 + y2 = 63.5mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 51.1mil + x2 = 51.1mil + ha:flags { + } + y1 = 63.5mil + } + ha:line.27 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 25.5mil + x2 = 25.5mil + ha:flags { + } + y1 = 105.5mil + } + ha:line.30 { + clearance = 0.0 + y2 = 3.6797mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 25.5mil + x2 = 25.5mil + ha:flags { + } + y1 = 105.5mil + } + ha:line.33 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 25.5mil + x2 = 1.6477mm + ha:flags { + } + y1 = 105.5mil + } + } + ha:combining { + } + } + } + } + uid = 8pGeYOC0HklbCnV30cwAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOT326.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOT326.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT326.fp (revision 33253) @@ -0,0 +1,331 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOT326 SMT transistor, 6 pins + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 7.5mil + -17.5mil + -7.5mil + -17.5mil + -7.5mil + 17.5mil + 7.5mil + 17.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 10.5mil + -20.5mil + -10.5mil + -20.5mil + -10.5mil + 20.5mil + 10.5mil + 20.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 7.5mil + -17.5mil + -7.5mil + -17.5mil + -7.5mil + 17.5mil + 7.5mil + 17.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 25.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 51.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 76.5mil + rot = 0.000000 + y = 105.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.22 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 0 + xmirror = 0 + x = 76.5mil + rot = 0.000000 + y = 35.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.23 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 0 + xmirror = 0 + x = 51.5mil + rot = 0.000000 + y = 35.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.24 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 0 + xmirror = 0 + x = 25.5mil + rot = 0.000000 + y = 35.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:line.10 { + clearance = 0.0 + y2 = 130.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 11.5mil + x2 = 91.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.13 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 91.5mil + x2 = 91.5mil + ha:flags { + } + y1 = 130.5mil + } + ha:line.16 { + clearance = 0.0 + y2 = 11.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 91.5mil + x2 = 11.5mil + ha:flags { + } + y1 = 11.5mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 111.5mil + y = 11.5mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.25 { + clearance = 0.0 + y2 = 70.5mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 1.299633mm + x2 = 1.299633mm + ha:flags { + } + y1 = 70.5mil + } + ha:line.28 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 25.5mil + x2 = 25.5mil + ha:flags { + } + y1 = 105.5mil + } + ha:line.31 { + clearance = 0.0 + y2 = 3.6797mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 25.5mil + x2 = 25.5mil + ha:flags { + } + y1 = 105.5mil + } + ha:line.34 { + clearance = 0.0 + y2 = 105.5mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 25.5mil + x2 = 1.6477mm + ha:flags { + } + y1 = 105.5mil + } + } + ha:combining { + } + } + } + } + uid = 6Bv/QN6fnFrzfC7tuHoAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/SOT89.fp =================================================================== --- tags/2.3.0/pcblib/smd/SOT89.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/SOT89.fp (revision 33253) @@ -0,0 +1,363 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = SOT89 SMT transistor, 4 pins + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 18.5mil + -30.5mil + -18.5mil + -30.5mil + -18.5mil + 30.5mil + 18.5mil + 30.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 21.5mil + -33.5mil + -21.5mil + -33.5mil + -21.5mil + 33.5mil + 21.5mil + 33.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 18.5mil + -30.5mil + -18.5mil + -30.5mil + -18.5mil + 30.5mil + 18.5mil + 30.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 60.5mil + 30.5mil + 60.5mil + -30.5mil + -60.5mil + -30.5mil + -60.5mil + 30.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 63.5mil + 33.5mil + 63.5mil + -33.5mil + -63.5mil + -33.5mil + -63.5mil + 33.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 60.5mil + 30.5mil + 60.5mil + -30.5mil + -60.5mil + -30.5mil + -60.5mil + 30.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 36.5mil + rot = 0.000000 + y = 170.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 97.5mil + rot = 0.000000 + y = 170.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 158.5mil + rot = 0.000000 + y = 170.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.22 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 97.5mil + rot = 0.000000 + y = 48.5mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 213.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 6.5mil + x2 = 6.5mil + ha:flags { + } + y1 = 6.5mil + } + ha:line.10 { + clearance = 0.0 + y2 = 213.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 6.5mil + x2 = 189.5mil + ha:flags { + } + y1 = 213.5mil + } + ha:line.13 { + clearance = 0.0 + y2 = 6.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 189.5mil + x2 = 189.5mil + ha:flags { + } + y1 = 213.5mil + } + ha:line.16 { + clearance = 0.0 + y2 = 6.5mil + thickness = 10.0mil + ha:attributes { + } + x1 = 189.5mil + x2 = 6.5mil + ha:flags { + } + y1 = 6.5mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 209.5mil + y = 6.5mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.23 { + clearance = 0.0 + y2 = 140.0mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 97.5mil + x2 = 97.5mil + ha:flags { + } + y1 = 140.0mil + } + ha:line.26 { + clearance = 0.0 + y2 = 170.5mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 36.5mil + x2 = 36.5mil + ha:flags { + } + y1 = 170.5mil + } + ha:line.29 { + clearance = 0.0 + y2 = 5.3307mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 36.5mil + x2 = 36.5mil + ha:flags { + } + y1 = 170.5mil + } + ha:line.32 { + clearance = 0.0 + y2 = 170.5mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 36.5mil + x2 = 1.9271mm + ha:flags { + } + y1 = 170.5mil + } + } + ha:combining { + } + } + } + } + uid = nhFNna5oWAROPukkSGYAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/TANT.scad =================================================================== --- tags/2.3.0/pcblib/smd/TANT.scad (nonexistent) +++ tags/2.3.0/pcblib/smd/TANT.scad (revision 33253) @@ -0,0 +1,95 @@ +// Various tantalum (from A to E) packages model +// +// Copyright (C) 2020 Alexey Kosilin +// +// File distribution license: +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// The above distribution license applies when the file is distributed as a +// stand alone model file or as part of a library, in both cases intended +// for reuse combined by the user with other openscad scripts. +// +// Use license: +// as a special exception, the content of the file may be +// embedded in an openscad script that represents a printed circuit board, +// for example when a board is exported by pcb-rnd. In such use case, +// the content of this file may be copied into the resulting board file +// with or without modifications, without affecting the board file's license +// in any way. +// + +module part_tantalum (sz) +{ + module impl (L, W, H, P, Tw, Th) + { + delta = 1e-3 ; + $fn = 30 ; + + module lead (P, Tw, Th) + color ([0.9, 0.9, 0.9]) + translate ([-delta, -Tw/2, -delta]) + { + translate ([0.3/2, 0, 0.3/2]) + rotate ([-90, 0, 0]) + cylinder (d = 0.3, h = Tw) ; + + translate ([0, 0, 0.3/2]) + cube ([0.3, Tw, Th - 0.3/2]) ; + + translate ([0.3/2, 0, 0]) + cube ([P - 0.3/2, Tw, 0.3]) ; + } + + module case() + hull() + { + translate ([0, 0, H/2]) + cube ([L - 0.3*2, W - 0.2, H], center = true) ; + + translate ([0, 0, Th]) + cube ([L, W, delta], center = true) ; + } + + color ([0.7, 0.55, 0]) + intersection() + { + translate ([-L/3, -5, -5]) + cube ([P/2, 10, 10]) ; + + scale (1.001) + case() ; + } + + color ([0.9, 0.8, 0.2]) + case() ; + + translate ([-L/2, 0, 0]) + lead (P, Tw, Th) ; + + translate ([L/2, 0, 0]) + mirror ([1, 0, 0]) + lead (P, Tw, Th) ; + } + + sizes = "ABCDE" ; + L = [ 3.2, 3.5, 6.0, 7.3, 7.3 ] ; + W = [ 1.6, 2.8, 3.2, 4.3, 4.3 ] ; + H = [ 1.6, 1.9, 2.5, 2.8, 4 ] ; + P = [ 0.8, 0.8, 1.3, 1.3, 1.3 ] ; + Tw = [ 1.2, 2.2, 2.2, 2.4, 2.4 ] ; + + idx = search (sz, sizes)[0] ; + impl (L[idx], W[idx], H[idx], P[idx], Tw[idx], H[idx]/2) ; +} Index: tags/2.3.0/pcblib/smd/TANT_A.fp =================================================================== --- tags/2.3.0/pcblib/smd/TANT_A.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/TANT_A.fp (revision 33253) @@ -0,0 +1,285 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TANT_A Tantalum SMT capacitor (pin 1 is +) + openscad = TANT.scad + openscad-param = {"A"} + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 24.5mil + -42.5mil + -24.5mil + -42.5mil + -24.5mil + 42.5mil + 24.5mil + 42.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 27.5mil + -45.5mil + -27.5mil + -45.5mil + -27.5mil + 45.5mil + 27.5mil + 45.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 24.5mil + -42.5mil + -24.5mil + -42.5mil + -24.5mil + 42.5mil + 24.5mil + 42.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.423183mm + rot = 0.000000 + y = 1.524392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 3.963183mm + rot = 0.000000 + y = 1.524392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 2.616592mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.432192mm + } + ha:line.10 { + clearance = 0.0 + y2 = 2.921392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.864383mm + ha:flags { + } + y1 = 2.616592mm + } + ha:line.13 { + clearance = 0.0 + y2 = 2.921392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.864383mm + x2 = 4.877583mm + ha:flags { + } + y1 = 2.921392mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 4.877583mm + x2 = 4.877583mm + ha:flags { + } + y1 = 2.921392mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 4.877583mm + x2 = 0.864383mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.432192mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.864383mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 5.385583mm + y = 1.524392mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 1.524392mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 2.693183mm + x2 = 2.693183mm + ha:flags { + } + y1 = 1.524392mm + } + ha:line.30 { + clearance = 0.0 + y2 = 1.524392mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.693183mm + x2 = 2.693183mm + ha:flags { + } + y1 = 1.524392mm + } + ha:line.33 { + clearance = 0.0 + y2 = 1.524392mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.693183mm + x2 = 3.693183mm + ha:flags { + } + y1 = 1.524392mm + } + ha:line.36 { + clearance = 0.0 + y2 = 2.524392mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.693183mm + x2 = 2.693183mm + ha:flags { + } + y1 = 1.524392mm + } + } + ha:combining { + } + } + } + } + uid = 26/rwM0jSKi02rxdXecAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/TANT_B.fp =================================================================== --- tags/2.3.0/pcblib/smd/TANT_B.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/TANT_B.fp (revision 33253) @@ -0,0 +1,285 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TANT_B Tantalum SMT capacitor (pin 1 is +) + openscad = TANT.scad + openscad-param = {"B"} + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 35.5mil + -76.5mil + -35.5mil + -76.5mil + -35.5mil + 76.5mil + 35.5mil + 76.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 38.5mil + -79.5mil + -38.5mil + -79.5mil + -38.5mil + 79.5mil + 38.5mil + 79.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 35.5mil + -76.5mil + -35.5mil + -76.5mil + -35.5mil + 76.5mil + 35.5mil + 76.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.956583mm + rot = 0.000000 + y = 2.641992mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 4.750583mm + rot = 0.000000 + y = 2.641992mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 4.597792mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.686192mm + } + ha:line.10 { + clearance = 0.0 + y2 = 5.156592mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 1.143783mm + ha:flags { + } + y1 = 4.597792mm + } + ha:line.13 { + clearance = 0.0 + y2 = 5.156592mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.143783mm + x2 = 6.198383mm + ha:flags { + } + y1 = 5.156592mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 6.198383mm + x2 = 6.198383mm + ha:flags { + } + y1 = 5.156592mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 6.198383mm + x2 = 1.143783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.686192mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.143783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 6.706383mm + y = 2.641992mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 2.641992mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 3.353583mm + x2 = 3.353583mm + ha:flags { + } + y1 = 2.641992mm + } + ha:line.30 { + clearance = 0.0 + y2 = 2.641992mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.353583mm + x2 = 3.353583mm + ha:flags { + } + y1 = 2.641992mm + } + ha:line.33 { + clearance = 0.0 + y2 = 2.641992mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.353583mm + x2 = 4.353583mm + ha:flags { + } + y1 = 2.641992mm + } + ha:line.36 { + clearance = 0.0 + y2 = 3.641992mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.353583mm + x2 = 3.353583mm + ha:flags { + } + y1 = 2.641992mm + } + } + ha:combining { + } + } + } + } + uid = z+x6iElAGsr55qcSOkgAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/TANT_C.fp =================================================================== --- tags/2.3.0/pcblib/smd/TANT_C.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/TANT_C.fp (revision 33253) @@ -0,0 +1,285 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TANT_C Tantalum SMT capacitor (pin 1 is +) + openscad = TANT.scad + openscad-param = {"C"} + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 48.5mil + -87.5mil + -48.5mil + -87.5mil + -48.5mil + 87.5mil + 48.5mil + 87.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 51.5mil + -90.5mil + -51.5mil + -90.5mil + -51.5mil + 90.5mil + 51.5mil + 90.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 48.5mil + -87.5mil + -48.5mil + -87.5mil + -48.5mil + 87.5mil + 48.5mil + 87.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.388383mm + rot = 0.000000 + y = 2.972192mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 7.163583mm + rot = 0.000000 + y = 2.972192mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 5.181992mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.762392mm + } + ha:line.10 { + clearance = 0.0 + y2 = 5.816992mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 1.473983mm + ha:flags { + } + y1 = 5.181992mm + } + ha:line.13 { + clearance = 0.0 + y2 = 5.816992mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.473983mm + x2 = 9.043183mm + ha:flags { + } + y1 = 5.816992mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 9.043183mm + x2 = 9.043183mm + ha:flags { + } + y1 = 5.816992mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 9.043183mm + x2 = 1.473983mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.762392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.473983mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 9.551183mm + y = 2.972192mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 2.972192mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 4.775983mm + x2 = 4.775983mm + ha:flags { + } + y1 = 2.972192mm + } + ha:line.30 { + clearance = 0.0 + y2 = 2.972192mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 4.775983mm + x2 = 4.775983mm + ha:flags { + } + y1 = 2.972192mm + } + ha:line.33 { + clearance = 0.0 + y2 = 2.972192mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 4.775983mm + x2 = 5.775983mm + ha:flags { + } + y1 = 2.972192mm + } + ha:line.36 { + clearance = 0.0 + y2 = 3.972192mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 4.775983mm + x2 = 4.775983mm + ha:flags { + } + y1 = 2.972192mm + } + } + ha:combining { + } + } + } + } + uid = JkGYP/uNTLhwqZKit+sAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/TANT_D.fp =================================================================== --- tags/2.3.0/pcblib/smd/TANT_D.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/TANT_D.fp (revision 33253) @@ -0,0 +1,285 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TANT_D Tantalum SMT capacitor (pin 1 is +) + openscad = TANT.scad + openscad-param = {"D"} + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 61.5mil + -117.5mil + -61.5mil + -117.5mil + -61.5mil + 117.5mil + 61.5mil + 117.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 1.638299mm + -3.060699mm + -1.638299mm + -3.060699mm + -1.638299mm + 3.060699mm + 1.638299mm + 3.060699mm + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 61.5mil + -117.5mil + -61.5mil + -117.5mil + -61.5mil + 117.5mil + 61.5mil + 117.5mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.25 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.896383mm + rot = 0.000000 + y = 3.937392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + ha:padstack_ref.26 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 8.738383mm + rot = 0.000000 + y = 3.937392mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 10.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.7 { + clearance = 0.0 + y2 = 6.909192mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.965592mm + } + ha:line.10 { + clearance = 0.0 + y2 = 7.747392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 1.804183mm + ha:flags { + } + y1 = 6.909192mm + } + ha:line.13 { + clearance = 0.0 + y2 = 7.747392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.804183mm + x2 = 11.125983mm + ha:flags { + } + y1 = 7.747392mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 11.125983mm + x2 = 11.125983mm + ha:flags { + } + y1 = 7.747392mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 11.125983mm + x2 = 1.804183mm + ha:flags { + } + y1 = 0.127392mm + } + ha:line.22 { + clearance = 0.0 + y2 = 0.965592mm + thickness = 10.0mil + ha:attributes { + } + x1 = 1.804183mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.127392mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 11.633983mm + y = 3.937392mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.27 { + clearance = 0.0 + y2 = 3.937392mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.817383mm + x2 = 5.817383mm + ha:flags { + } + y1 = 3.937392mm + } + ha:line.30 { + clearance = 0.0 + y2 = 3.937392mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 5.817383mm + x2 = 5.817383mm + ha:flags { + } + y1 = 3.937392mm + } + ha:line.33 { + clearance = 0.0 + y2 = 3.937392mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 5.817383mm + x2 = 6.817383mm + ha:flags { + } + y1 = 3.937392mm + } + ha:line.36 { + clearance = 0.0 + y2 = 4.937392mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 5.817383mm + x2 = 5.817383mm + ha:flags { + } + y1 = 3.937392mm + } + } + ha:combining { + } + } + } + } + uid = aZrmxsPqy0XUIP+9J8kAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/smd/minimelf.fp =================================================================== --- tags/2.3.0/pcblib/smd/minimelf.fp (nonexistent) +++ tags/2.3.0/pcblib/smd/minimelf.fp (revision 33253) @@ -0,0 +1,233 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = minimelf + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.649986mm + -0.899922mm + -0.649986mm + -0.899922mm + -0.649986mm + 0.899922mm + 0.649986mm + 0.899922mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 38.09mil + -1.217422mm + -38.09mil + -1.217422mm + -38.09mil + 1.217422mm + 38.09mil + 1.217422mm + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + 0.649986mm + -0.899922mm + -0.649986mm + -0.899922mm + -0.649986mm + 0.899922mm + 0.649986mm + 0.899922mm + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto = 1 + } + } + } + hbottom = 0 + hplated = 0 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + } + proto = 0 + xmirror = 0 + x = 1.52756in + rot = 0.000000 + y = 35.999928mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 25.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + } + proto = 0 + xmirror = 0 + x = 1.38582in + rot = 0.000000 + y = 35.999928mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 25.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 1.38582in + thickness = 7.87mil + ha:attributes { + } + x1 = 35.999928mm + x2 = 37.999924mm + ha:flags { + } + y1 = 1.38582in + } + ha:line.12 { + clearance = 0.0 + y2 = 1.44882in + thickness = 7.87mil + ha:attributes { + } + x1 = 35.999928mm + x2 = 37.999924mm + ha:flags { + } + y1 = 1.44882in + } + ha:text.6 { + scale = 70 + ha:attributes { + } + x = 1.41949in + y = 35.46983mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.15 { + clearance = 0.0 + y2 = 35.999928mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 1.45669in + x2 = 1.45669in + ha:flags { + } + y1 = 35.999928mm + } + ha:line.18 { + clearance = 0.0 + y2 = 35.999928mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.45669in + x2 = 1.45669in + ha:flags { + } + y1 = 35.999928mm + } + ha:line.21 { + clearance = 0.0 + y2 = 35.999928mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.45669in + x2 = 35.999926mm + ha:flags { + } + y1 = 35.999928mm + } + ha:line.24 { + clearance = 0.0 + y2 = 34.999928mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.45669in + x2 = 1.45669in + ha:flags { + } + y1 = 35.999928mm + } + } + ha:combining { + } + } + } + } + uid = kBcrKTtaM9kTfl/PmukAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/HC49.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/HC49.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/HC49.fp (revision 33253) @@ -0,0 +1,384 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = HC49 Crystals + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 28.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 28.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 60.2mil + rot = 0.000000 + y = 60.2mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 6.60908mm + rot = 0.000000 + y = 60.2mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 0.25908mm + thickness = 20.0mil + ha:attributes { + } + x1 = 60.2mil + x2 = 6.60908mm + ha:flags { + } + y1 = 0.25908mm + } + ha:line.13 { + clearance = 0.0 + y2 = 110.2mil + thickness = 20.0mil + ha:attributes { + } + x1 = 6.60908mm + x2 = 60.2mil + ha:flags { + } + y1 = 110.2mil + } + ha:arc.12 { + astart = 90 + thickness = 20.0mil + width = 50.0mil + height = 50.0mil + ha:attributes { + } + x = 6.60908mm + y = 60.2mil + adelta = 180 + ha:flags { + } + clearance = 0.0 + } + ha:arc.16 { + astart = 270 + thickness = 20.0mil + width = 50.0mil + height = 50.0mil + ha:attributes { + } + x = 60.2mil + y = 60.2mil + adelta = 180 + ha:flags { + } + clearance = 0.0 + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 0.25908mm + y = -1.26492mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.17 { + clearance = 0.0 + y2 = 60.2mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 4.06908mm + x2 = 4.06908mm + ha:flags { + } + y1 = 60.2mil + } + ha:line.20 { + clearance = 0.0 + y2 = 60.2mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 60.2mil + x2 = 60.2mil + ha:flags { + } + y1 = 60.2mil + } + ha:line.23 { + clearance = 0.0 + y2 = 60.2mil + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 60.2mil + x2 = 2.52908mm + ha:flags { + } + y1 = 60.2mil + } + ha:line.26 { + clearance = 0.0 + y2 = 2.52908mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 60.2mil + x2 = 60.2mil + ha:flags { + } + y1 = 60.2mil + } + } + ha:combining { + } + } + } + } + uid = K5zHll9kWHYvk+K8WxUAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/HC49U.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/HC49U.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/HC49U.fp (revision 33253) @@ -0,0 +1,384 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = HC49U Crystals + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 32.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 32.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 3.33248mm + rot = 0.000000 + y = 101.2mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 8.20928mm + rot = 0.000000 + y = 101.2mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 0.25908mm + thickness = 20.0mil + ha:attributes { + } + x1 = 101.2mil + x2 = 8.99668mm + ha:flags { + } + y1 = 0.25908mm + } + ha:line.13 { + clearance = 0.0 + y2 = 4.90728mm + thickness = 20.0mil + ha:attributes { + } + x1 = 8.99668mm + x2 = 101.2mil + ha:flags { + } + y1 = 4.90728mm + } + ha:arc.12 { + astart = 90 + thickness = 20.0mil + width = 91.0mil + height = 91.0mil + ha:attributes { + } + x = 8.99668mm + y = 101.2mil + adelta = 180 + ha:flags { + } + clearance = 0.0 + } + ha:arc.16 { + astart = 270 + thickness = 20.0mil + width = 91.0mil + height = 91.0mil + ha:attributes { + } + x = 101.2mil + y = 101.2mil + adelta = 180 + ha:flags { + } + clearance = 0.0 + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 0.25908mm + y = -1.26492mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.17 { + clearance = 0.0 + y2 = 101.2mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.77088mm + x2 = 5.77088mm + ha:flags { + } + y1 = 101.2mil + } + ha:line.20 { + clearance = 0.0 + y2 = 101.2mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.33248mm + x2 = 3.33248mm + ha:flags { + } + y1 = 101.2mil + } + ha:line.23 { + clearance = 0.0 + y2 = 101.2mil + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.33248mm + x2 = 4.33248mm + ha:flags { + } + y1 = 101.2mil + } + ha:line.26 { + clearance = 0.0 + y2 = 3.57048mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.33248mm + x2 = 3.33248mm + ha:flags { + } + y1 = 101.2mil + } + } + ha:combining { + } + } + } + } + uid = IU81ifHVXky8kV3JzMYAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/HC49UH.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/HC49UH.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/HC49UH.fp (revision 33253) @@ -0,0 +1,380 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = HC49UH Crystals + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 32.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 32.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 3.328183mm + rot = 0.000000 + y = 15.875783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 8.204983mm + rot = 0.000000 + y = 15.875783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 11.303783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.12 { + clearance = 0.0 + y2 = 13.335783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 11.303783mm + x2 = 11.303783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.15 { + clearance = 0.0 + y2 = 13.335783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 11.303783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 13.335783mm + } + ha:line.18 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 13.335783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 0.254783mm + y = -1.269217mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.21 { + clearance = 0.0 + y2 = 15.875783mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.766583mm + x2 = 5.766583mm + ha:flags { + } + y1 = 15.875783mm + } + ha:line.24 { + clearance = 0.0 + y2 = 15.875783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.328183mm + x2 = 3.328183mm + ha:flags { + } + y1 = 15.875783mm + } + ha:line.27 { + clearance = 0.0 + y2 = 15.875783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.328183mm + x2 = 4.328183mm + ha:flags { + } + y1 = 15.875783mm + } + ha:line.30 { + clearance = 0.0 + y2 = 16.875783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.328183mm + x2 = 3.328183mm + ha:flags { + } + y1 = 15.875783mm + } + } + ha:combining { + } + } + } + } + uid = d0kIIEVd9hKmfkrR2JwAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/HC49U_3.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/HC49U_3.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/HC49U_3.fp (revision 33253) @@ -0,0 +1,403 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + value = + footprint = HC49U_3 Crystals + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 32.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 32.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 3.33248mm + rot = 0.000000 + y = 101.2mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 5.77088mm + rot = 0.000000 + y = 101.2mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 8.20928mm + rot = 0.000000 + y = 101.2mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 0.25908mm + thickness = 20.0mil + ha:attributes { + } + x1 = 101.2mil + x2 = 8.99668mm + ha:flags { + } + y1 = 0.25908mm + } + ha:line.14 { + clearance = 0.0 + y2 = 4.90728mm + thickness = 20.0mil + ha:attributes { + } + x1 = 8.99668mm + x2 = 101.2mil + ha:flags { + } + y1 = 4.90728mm + } + ha:arc.13 { + astart = 90 + thickness = 20.0mil + width = 91.0mil + height = 91.0mil + ha:attributes { + } + x = 8.99668mm + y = 101.2mil + adelta = 180 + ha:flags { + } + clearance = 0.0 + } + ha:arc.17 { + astart = 270 + thickness = 20.0mil + width = 91.0mil + height = 91.0mil + ha:attributes { + } + x = 101.2mil + y = 101.2mil + adelta = 180 + ha:flags { + } + clearance = 0.0 + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 0.25908mm + y = -1.26492mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.18 { + clearance = 0.0 + y2 = 101.2mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.77088mm + x2 = 5.77088mm + ha:flags { + } + y1 = 101.2mil + } + ha:line.21 { + clearance = 0.0 + y2 = 101.2mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.33248mm + x2 = 3.33248mm + ha:flags { + } + y1 = 101.2mil + } + ha:line.24 { + clearance = 0.0 + y2 = 3.57048mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.33248mm + x2 = 3.33248mm + ha:flags { + } + y1 = 101.2mil + } + ha:line.27 { + clearance = 0.0 + y2 = 101.2mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.33248mm + x2 = 4.33248mm + ha:flags { + } + y1 = 101.2mil + } + } + ha:combining { + } + } + } + } + uid = yz1V4HtC1LifNPNIfzcAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/HC49U_3H.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/HC49U_3H.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/HC49U_3H.fp (revision 33253) @@ -0,0 +1,398 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = HC49U_3H Crystals + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 32.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.0mil + -30.0mil + 30.0mil + -30.0mil + 30.0mil + 30.0mil + -30.0mil + 30.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -33.0mil + -33.0mil + 33.0mil + -33.0mil + 33.0mil + 33.0mil + -33.0mil + 33.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 32.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 60.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 66.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 3.328183mm + rot = 0.000000 + y = 15.875783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 5.766583mm + rot = 0.000000 + y = 15.875783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 8.204983mm + rot = 0.000000 + y = 15.875783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 11.303783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.13 { + clearance = 0.0 + y2 = 13.335783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 11.303783mm + x2 = 11.303783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.16 { + clearance = 0.0 + y2 = 13.335783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 11.303783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 13.335783mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 13.335783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 0.254783mm + y = -1.269217mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.22 { + clearance = 0.0 + y2 = 15.875783mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.766583mm + x2 = 5.766583mm + ha:flags { + } + y1 = 15.875783mm + } + ha:line.25 { + clearance = 0.0 + y2 = 15.875783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.328183mm + x2 = 3.328183mm + ha:flags { + } + y1 = 15.875783mm + } + ha:line.28 { + clearance = 0.0 + y2 = 16.875783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.328183mm + x2 = 3.328183mm + ha:flags { + } + y1 = 15.875783mm + } + ha:line.31 { + clearance = 0.0 + y2 = 15.875783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.328183mm + x2 = 4.328183mm + ha:flags { + } + y1 = 15.875783mm + } + } + ha:combining { + } + } + } + } + uid = VTNBJgXKGQ7phRTbFDUAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/HC51U.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/HC51U.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/HC51U.fp (revision 33253) @@ -0,0 +1,384 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = HC51U Crystals + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 40.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 40.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 3.71348mm + rot = 0.000000 + y = 4.72948mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 631.2mil + rot = 0.000000 + y = 4.72948mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 0.25908mm + thickness = 20.0mil + ha:attributes { + } + x1 = 4.72948mm + x2 = 591.2mil + ha:flags { + } + y1 = 0.25908mm + } + ha:line.13 { + clearance = 0.0 + y2 = 9.19988mm + thickness = 20.0mil + ha:attributes { + } + x1 = 591.2mil + x2 = 4.72948mm + ha:flags { + } + y1 = 9.19988mm + } + ha:arc.12 { + astart = 90 + thickness = 20.0mil + width = 176.0mil + height = 176.0mil + ha:attributes { + } + x = 591.2mil + y = 4.72948mm + adelta = 180 + ha:flags { + } + clearance = 0.0 + } + ha:arc.16 { + astart = 270 + thickness = 20.0mil + width = 176.0mil + height = 176.0mil + ha:attributes { + } + x = 4.72948mm + y = 4.72948mm + adelta = 180 + ha:flags { + } + clearance = 0.0 + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 0.25908mm + y = -1.26492mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.17 { + clearance = 0.0 + y2 = 4.72948mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 9.87298mm + x2 = 9.87298mm + ha:flags { + } + y1 = 4.72948mm + } + ha:line.20 { + clearance = 0.0 + y2 = 4.72948mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.71348mm + x2 = 3.71348mm + ha:flags { + } + y1 = 4.72948mm + } + ha:line.23 { + clearance = 0.0 + y2 = 4.72948mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.71348mm + x2 = 4.71348mm + ha:flags { + } + y1 = 4.72948mm + } + ha:line.26 { + clearance = 0.0 + y2 = 5.72948mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.71348mm + x2 = 3.71348mm + ha:flags { + } + y1 = 4.72948mm + } + } + ha:combining { + } + } + } + } + uid = +FiihmhDvVGqTubuzyoAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/HC51UH.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/HC51UH.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/HC51UH.fp (revision 33253) @@ -0,0 +1,380 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = HC51UH Crystals + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 40.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 40.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 3.709183mm + rot = 0.000000 + y = 25.019783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 16.028183mm + rot = 0.000000 + y = 25.019783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 19.482583mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.12 { + clearance = 0.0 + y2 = 19.939783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 19.482583mm + x2 = 19.482583mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.15 { + clearance = 0.0 + y2 = 19.939783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 19.482583mm + x2 = 0.254783mm + ha:flags { + } + y1 = 19.939783mm + } + ha:line.18 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 19.939783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 0.254783mm + y = -1.269217mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.21 { + clearance = 0.0 + y2 = 25.019783mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 9.868683mm + x2 = 9.868683mm + ha:flags { + } + y1 = 25.019783mm + } + ha:line.24 { + clearance = 0.0 + y2 = 25.019783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.709183mm + x2 = 3.709183mm + ha:flags { + } + y1 = 25.019783mm + } + ha:line.27 { + clearance = 0.0 + y2 = 25.019783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.709183mm + x2 = 4.709183mm + ha:flags { + } + y1 = 25.019783mm + } + ha:line.30 { + clearance = 0.0 + y2 = 26.019783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.709183mm + x2 = 3.709183mm + ha:flags { + } + y1 = 25.019783mm + } + } + ha:combining { + } + } + } + } + uid = sAYDhniTNYN3q3leLhwAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/HEPTAWATT.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/HEPTAWATT.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/HEPTAWATT.fp (revision 33253) @@ -0,0 +1,506 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = HEPTAWATT Power IC, as in MULTIWATT15 + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.626383mm + rot = 0.000000 + y = 8.128783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 2.896383mm + rot = 0.000000 + y = 3.048783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 4.166383mm + rot = 0.000000 + y = 8.128783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.10 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 5.436383mm + rot = 0.000000 + y = 3.048783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.11 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 6.706383mm + rot = 0.000000 + y = 8.128783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.12 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 7.976383mm + rot = 0.000000 + y = 3.048783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.13 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 9.246383mm + rot = 0.000000 + y = 8.128783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.14 { + clearance = 0.0 + y2 = 5.055383mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.17 { + clearance = 0.0 + y2 = 5.055383mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.643383mm + ha:flags { + } + y1 = 5.055383mm + } + ha:line.20 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.643383mm + x2 = 10.643383mm + ha:flags { + } + y1 = 5.055383mm + } + ha:line.23 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.643383mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.26 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.643383mm + ha:flags { + } + y1 = 1.524783mm + } + ha:line.29 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 3.531383mm + x2 = 3.531383mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.32 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 7.341383mm + x2 = 7.341383mm + ha:flags { + } + y1 = 0.254783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 12.167383mm + y = 1.524783mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.35 { + clearance = 0.0 + y2 = 5.95164mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.436383mm + x2 = 5.436383mm + ha:flags { + } + y1 = 5.95164mm + } + ha:line.38 { + clearance = 0.0 + y2 = 6.579383mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.626383mm + x2 = 1.626383mm + ha:flags { + } + y1 = 6.579383mm + } + ha:line.41 { + clearance = 0.0 + y2 = 7.579383mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.626383mm + x2 = 1.626383mm + ha:flags { + } + y1 = 6.579383mm + } + ha:line.44 { + clearance = 0.0 + y2 = 6.579383mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.626383mm + x2 = 2.626383mm + ha:flags { + } + y1 = 6.579383mm + } + } + ha:combining { + } + } + } + } + uid = iVCWAJKpIXjZ4LV4utoAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/LED3.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/LED3.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/LED3.fp (revision 33253) @@ -0,0 +1,388 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = LED3, 3mm LED (pin 1 is +, 2 is -) + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 43.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -32.5mil + -32.5mil + 32.5mil + -32.5mil + 32.5mil + 32.5mil + -32.5mil + 32.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -32.5mil + -32.5mil + 32.5mil + -32.5mil + 32.5mil + 32.5mil + -32.5mil + 32.5mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -32.5mil + -32.5mil + 32.5mil + -32.5mil + 32.5mil + 32.5mil + -32.5mil + 32.5mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -35.5mil + -35.5mil + 35.5mil + -35.5mil + 35.5mil + 35.5mil + -35.5mil + 35.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -35.5mil + -35.5mil + 35.5mil + -35.5mil + 35.5mil + 35.5mil + -35.5mil + 35.5mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 43.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 65.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 65.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 65.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 71.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 71.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 50.5mil + rot = 0.000000 + y = 2.13614mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 150.5mil + rot = 0.000000 + y = 2.13614mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:arc.9 { + astart = 45 + thickness = 10.0mil + width = 59.0mil + height = 59.0mil + ha:attributes { + } + x = 100.5mil + y = 2.13614mm + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.10 { + astart = 225 + thickness = 10.0mil + width = 59.0mil + height = 59.0mil + ha:attributes { + } + x = 100.5mil + y = 2.13614mm + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.11 { + astart = 45 + thickness = 10.0mil + width = 79.0mil + height = 79.0mil + ha:attributes { + } + x = 100.5mil + y = 2.13614mm + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.12 { + astart = 225 + thickness = 10.0mil + width = 79.0mil + height = 79.0mil + ha:attributes { + } + x = 100.5mil + y = 2.13614mm + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 200.5mil + y = 3.91414mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.13 { + clearance = 0.0 + y2 = 2.13614mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 100.5mil + x2 = 100.5mil + ha:flags { + } + y1 = 2.13614mm + } + ha:line.16 { + clearance = 0.0 + y2 = 2.13614mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 100.5mil + x2 = 100.5mil + ha:flags { + } + y1 = 2.13614mm + } + ha:line.19 { + clearance = 0.0 + y2 = 2.13614mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 100.5mil + x2 = 3.5527mm + ha:flags { + } + y1 = 2.13614mm + } + ha:line.22 { + clearance = 0.0 + y2 = 3.13614mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 100.5mil + x2 = 100.5mil + ha:flags { + } + y1 = 2.13614mm + } + } + ha:combining { + } + } + } + } + uid = AXOBLf2n2pEOmUoe7pcAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/LED5.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/LED5.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/LED5.fp (revision 33253) @@ -0,0 +1,360 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = LED5, 5mm LED (pin 1 is +, 2 is -) + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 43.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -32.5mil + -32.5mil + 32.5mil + -32.5mil + 32.5mil + 32.5mil + -32.5mil + 32.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -32.5mil + -32.5mil + 32.5mil + -32.5mil + 32.5mil + 32.5mil + -32.5mil + 32.5mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -32.5mil + -32.5mil + 32.5mil + -32.5mil + 32.5mil + 32.5mil + -32.5mil + 32.5mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -35.5mil + -35.5mil + 35.5mil + -35.5mil + 35.5mil + 35.5mil + -35.5mil + 35.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -35.5mil + -35.5mil + 35.5mil + -35.5mil + 35.5mil + 35.5mil + -35.5mil + 35.5mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 43.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 65.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 65.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 65.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 71.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 71.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.36474mm + rot = 0.000000 + y = 3.63474mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 4.90474mm + rot = 0.000000 + y = 3.63474mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:arc.9 { + astart = 0 + thickness = 10.0mil + width = 118.0mil + height = 118.0mil + ha:attributes { + } + x = 3.63474mm + y = 3.63474mm + adelta = 360 + ha:flags { + } + clearance = 0.0 + } + ha:arc.10 { + astart = 0 + thickness = 10.0mil + width = 138.0mil + height = 138.0mil + ha:attributes { + } + x = 3.63474mm + y = 3.63474mm + adelta = 360 + ha:flags { + } + clearance = 0.0 + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 6.17474mm + y = 5.41274mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.11 { + clearance = 0.0 + y2 = 3.63474mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 3.63474mm + x2 = 3.63474mm + ha:flags { + } + y1 = 3.63474mm + } + ha:line.14 { + clearance = 0.0 + y2 = 3.63474mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 3.63474mm + x2 = 3.63474mm + ha:flags { + } + y1 = 3.63474mm + } + ha:line.17 { + clearance = 0.0 + y2 = 3.63474mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 3.63474mm + x2 = 4.63474mm + ha:flags { + } + y1 = 3.63474mm + } + ha:line.20 { + clearance = 0.0 + y2 = 4.63474mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 3.63474mm + x2 = 3.63474mm + ha:flags { + } + y1 = 3.63474mm + } + } + ha:combining { + } + } + } + } + uid = hFGipNdgRBmeMBGUNCcAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/MULTIWATT11.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/MULTIWATT11.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/MULTIWATT11.fp (revision 33253) @@ -0,0 +1,578 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = MULTIWATT11 Power IC + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 1.905783mm + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 3.607583mm + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 5.309383mm + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.10 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 7.011183mm + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.11 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 8.712983mm + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.12 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 10.414783mm + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.13 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 12.116583mm + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.14 { + smirror = 0 + ha:attributes { + term = 8 + name = 8 + } + proto = 1 + xmirror = 0 + x = 13.818383mm + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.15 { + smirror = 0 + ha:attributes { + term = 9 + name = 9 + } + proto = 1 + xmirror = 0 + x = 15.520183mm + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.16 { + smirror = 0 + ha:attributes { + term = 10 + name = 10 + } + proto = 1 + xmirror = 0 + x = 17.221983mm + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.17 { + smirror = 0 + ha:attributes { + term = 11 + name = 11 + } + proto = 1 + xmirror = 0 + x = 18.923783mm + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.18 { + clearance = 0.0 + y2 = 5.334783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.21 { + clearance = 0.0 + y2 = 5.334783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 20.574783mm + ha:flags { + } + y1 = 5.334783mm + } + ha:line.24 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 20.574783mm + x2 = 20.574783mm + ha:flags { + } + y1 = 5.334783mm + } + ha:line.27 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 20.574783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.30 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 20.574783mm + ha:flags { + } + y1 = 1.524783mm + } + ha:line.33 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 8.509783mm + x2 = 8.509783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.36 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 12.319783mm + x2 = 12.319783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 22.098783mm + y = 1.524783mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.39 { + clearance = 0.0 + y2 = 7.597692mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 7.597692mm + } + ha:line.42 { + clearance = 0.0 + y2 = 6.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.905783mm + x2 = 1.905783mm + ha:flags { + } + y1 = 6.858783mm + } + ha:line.45 { + clearance = 0.0 + y2 = 7.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.905783mm + x2 = 1.905783mm + ha:flags { + } + y1 = 6.858783mm + } + ha:line.48 { + clearance = 0.0 + y2 = 6.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.905783mm + x2 = 2.905783mm + ha:flags { + } + y1 = 6.858783mm + } + } + ha:combining { + } + } + } + } + uid = OJr8gHIpKF/u/Cj9DHsAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/MULTIWATT15.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/MULTIWATT15.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/MULTIWATT15.fp (revision 33253) @@ -0,0 +1,650 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = MULTIWATT15 Power IC + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 63.0mil + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 113.0mil + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 163.0mil + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.10 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 213.0mil + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.11 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 263.0mil + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.12 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 313.0mil + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.13 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 363.0mil + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.14 { + smirror = 0 + ha:attributes { + term = 8 + name = 8 + } + proto = 1 + xmirror = 0 + x = 413.0mil + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.15 { + smirror = 0 + ha:attributes { + term = 9 + name = 9 + } + proto = 1 + xmirror = 0 + x = 463.0mil + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.16 { + smirror = 0 + ha:attributes { + term = 10 + name = 10 + } + proto = 1 + xmirror = 0 + x = 513.0mil + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.17 { + smirror = 0 + ha:attributes { + term = 11 + name = 11 + } + proto = 1 + xmirror = 0 + x = 563.0mil + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.18 { + smirror = 0 + ha:attributes { + term = 12 + name = 12 + } + proto = 1 + xmirror = 0 + x = 613.0mil + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.19 { + smirror = 0 + ha:attributes { + term = 13 + name = 13 + } + proto = 1 + xmirror = 0 + x = 663.0mil + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.20 { + smirror = 0 + ha:attributes { + term = 14 + name = 14 + } + proto = 1 + xmirror = 0 + x = 713.0mil + rot = 0.000000 + y = 4.826783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.21 { + smirror = 0 + ha:attributes { + term = 15 + name = 15 + } + proto = 1 + xmirror = 0 + x = 763.0mil + rot = 0.000000 + y = 9.906783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.22 { + clearance = 0.0 + y2 = 5.334783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 13.0mil + x2 = 13.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:line.25 { + clearance = 0.0 + y2 = 5.334783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 13.0mil + x2 = 813.0mil + ha:flags { + } + y1 = 5.334783mm + } + ha:line.28 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 813.0mil + x2 = 813.0mil + ha:flags { + } + y1 = 5.334783mm + } + ha:line.31 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 813.0mil + x2 = 13.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:line.34 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 13.0mil + x2 = 813.0mil + ha:flags { + } + y1 = 1.524783mm + } + ha:line.37 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 338.0mil + x2 = 338.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:line.40 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 488.0mil + x2 = 488.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 873.0mil + y = 1.524783mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.43 { + clearance = 0.0 + y2 = 7.536116mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 413.0mil + x2 = 413.0mil + ha:flags { + } + y1 = 7.536116mm + } + ha:line.46 { + clearance = 0.0 + y2 = 6.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 63.0mil + x2 = 63.0mil + ha:flags { + } + y1 = 6.858783mm + } + ha:line.49 { + clearance = 0.0 + y2 = 7.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 63.0mil + x2 = 63.0mil + ha:flags { + } + y1 = 6.858783mm + } + ha:line.52 { + clearance = 0.0 + y2 = 6.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 63.0mil + x2 = 2.6002mm + ha:flags { + } + y1 = 6.858783mm + } + } + ha:combining { + } + } + } + } + uid = Pvw9fS9mULpdZ07inAAAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/MULTIWATT8.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/MULTIWATT8.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/MULTIWATT8.fp (revision 33253) @@ -0,0 +1,524 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = MULTIWATT8 Power IC + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 63.0mil + rot = 0.000000 + y = 3.175783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 163.0mil + rot = 0.000000 + y = 3.175783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 263.0mil + rot = 0.000000 + y = 3.175783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.10 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 363.0mil + rot = 0.000000 + y = 3.175783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.11 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 463.0mil + rot = 0.000000 + y = 3.175783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.12 { + smirror = 0 + ha:attributes { + term = 6 + name = 6 + } + proto = 1 + xmirror = 0 + x = 563.0mil + rot = 0.000000 + y = 3.175783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.13 { + smirror = 0 + ha:attributes { + term = 7 + name = 7 + } + proto = 1 + xmirror = 0 + x = 663.0mil + rot = 0.000000 + y = 3.175783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.14 { + smirror = 0 + ha:attributes { + term = 8 + name = 8 + } + proto = 1 + xmirror = 0 + x = 763.0mil + rot = 0.000000 + y = 3.175783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.15 { + clearance = 0.0 + y2 = 5.334783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 13.0mil + x2 = 13.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:line.18 { + clearance = 0.0 + y2 = 5.334783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 13.0mil + x2 = 813.0mil + ha:flags { + } + y1 = 5.334783mm + } + ha:line.21 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 813.0mil + x2 = 813.0mil + ha:flags { + } + y1 = 5.334783mm + } + ha:line.24 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 813.0mil + x2 = 13.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:line.27 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 13.0mil + x2 = 813.0mil + ha:flags { + } + y1 = 1.524783mm + } + ha:line.30 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 338.0mil + x2 = 338.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:line.33 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 488.0mil + x2 = 488.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 873.0mil + y = 1.524783mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.36 { + clearance = 0.0 + y2 = 3.175783mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 413.0mil + x2 = 413.0mil + ha:flags { + } + y1 = 3.175783mm + } + ha:line.39 { + clearance = 0.0 + y2 = 6.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 63.0mil + x2 = 63.0mil + ha:flags { + } + y1 = 6.858783mm + } + ha:line.42 { + clearance = 0.0 + y2 = 7.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 63.0mil + x2 = 63.0mil + ha:flags { + } + y1 = 6.858783mm + } + ha:line.45 { + clearance = 0.0 + y2 = 6.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 63.0mil + x2 = 2.6002mm + ha:flags { + } + y1 = 6.858783mm + } + } + ha:combining { + } + } + } + } + uid = IQhuhU7OlwL8WndT1toAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/OSC14.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/OSC14.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/OSC14.fp (revision 33253) @@ -0,0 +1,455 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = OSC14, Crystal oscillator + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 28.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 50.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 50.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 50.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 56.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 56.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = NC + } + proto = 0 + xmirror = 0 + x = 2.54254mm + rot = 0.000000 + y = 2.54254mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = GND + } + proto = 0 + xmirror = 0 + x = 2.54254mm + rot = 0.000000 + y = 700.1mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = CLK + } + proto = 0 + xmirror = 0 + x = 400.1mil + rot = 0.000000 + y = 700.1mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.10 { + smirror = 0 + ha:attributes { + term = 4 + name = VCC + } + proto = 0 + xmirror = 0 + x = 400.1mil + rot = 0.000000 + y = 2.54254mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.11 { + clearance = 0.0 + y2 = 0.12954mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.12954mm + x2 = 400.1mil + ha:flags { + } + y1 = 0.12954mm + } + ha:line.15 { + clearance = 0.0 + y2 = 700.1mil + thickness = 10.0mil + ha:attributes { + } + x1 = 495.1mil + x2 = 495.1mil + ha:flags { + } + y1 = 2.54254mm + } + ha:line.19 { + clearance = 0.0 + y2 = 795.1mil + thickness = 10.0mil + ha:attributes { + } + x1 = 400.1mil + x2 = 2.54254mm + ha:flags { + } + y1 = 795.1mil + } + ha:line.23 { + clearance = 0.0 + y2 = 0.12954mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.12954mm + x2 = 0.12954mm + ha:flags { + } + y1 = 700.1mil + } + ha:line.26 { + clearance = 0.0 + y2 = 60.1mil + thickness = 10.0mil + ha:attributes { + } + x1 = 2.54254mm + x2 = 400.1mil + ha:flags { + } + y1 = 60.1mil + } + ha:line.30 { + clearance = 0.0 + y2 = 700.1mil + thickness = 10.0mil + ha:attributes { + } + x1 = 440.1mil + x2 = 440.1mil + ha:flags { + } + y1 = 2.54254mm + } + ha:line.34 { + clearance = 0.0 + y2 = 740.1mil + thickness = 10.0mil + ha:attributes { + } + x1 = 400.1mil + x2 = 2.54254mm + ha:flags { + } + y1 = 740.1mil + } + ha:line.38 { + clearance = 0.0 + y2 = 2.54254mm + thickness = 10.0mil + ha:attributes { + } + x1 = 60.1mil + x2 = 60.1mil + ha:flags { + } + y1 = 700.1mil + } + ha:arc.14 { + astart = 180 + thickness = 10.0mil + width = 95.0mil + height = 95.0mil + ha:attributes { + } + x = 400.1mil + y = 2.54254mm + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.18 { + astart = 90 + thickness = 10.0mil + width = 95.0mil + height = 95.0mil + ha:attributes { + } + x = 400.1mil + y = 700.1mil + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.22 { + astart = 0 + thickness = 10.0mil + width = 95.0mil + height = 95.0mil + ha:attributes { + } + x = 2.54254mm + y = 700.1mil + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.29 { + astart = 180 + thickness = 10.0mil + width = 40.0mil + height = 40.0mil + ha:attributes { + } + x = 400.1mil + y = 2.54254mm + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.33 { + astart = 90 + thickness = 10.0mil + width = 40.0mil + height = 40.0mil + ha:attributes { + } + x = 400.1mil + y = 700.1mil + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.37 { + astart = 0 + thickness = 10.0mil + width = 40.0mil + height = 40.0mil + ha:attributes { + } + x = 2.54254mm + y = 700.1mil + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.41 { + astart = 270 + thickness = 10.0mil + width = 40.0mil + height = 40.0mil + ha:attributes { + } + x = 2.54254mm + y = 2.54254mm + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 270.1mil + y = 300.1mil + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.42 { + clearance = 0.0 + y2 = 400.1mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 6.35254mm + x2 = 6.35254mm + ha:flags { + } + y1 = 400.1mil + } + ha:line.45 { + clearance = 0.0 + y2 = 2.54254mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.54254mm + x2 = 2.54254mm + ha:flags { + } + y1 = 2.54254mm + } + ha:line.48 { + clearance = 0.0 + y2 = 2.54254mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.54254mm + x2 = 3.54254mm + ha:flags { + } + y1 = 2.54254mm + } + ha:line.51 { + clearance = 0.0 + y2 = 3.54254mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.54254mm + x2 = 2.54254mm + ha:flags { + } + y1 = 2.54254mm + } + } + ha:combining { + } + } + } + } + uid = xzk533cq9lHncC5p9N4AAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/PENTAWATT.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/PENTAWATT.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/PENTAWATT.fp (revision 33253) @@ -0,0 +1,470 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = PENTAWATT Power IC + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.032783mm + rot = 0.000000 + y = 8.738383mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 3.734583mm + rot = 0.000000 + y = 4.750583mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 5.436383mm + rot = 0.000000 + y = 8.738383mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.10 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 1 + xmirror = 0 + x = 7.138183mm + rot = 0.000000 + y = 4.750583mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.11 { + smirror = 0 + ha:attributes { + term = 5 + name = 5 + } + proto = 1 + xmirror = 0 + x = 8.839983mm + rot = 0.000000 + y = 8.738383mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.12 { + clearance = 0.0 + y2 = 5.055383mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.15 { + clearance = 0.0 + y2 = 5.055383mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.643383mm + ha:flags { + } + y1 = 5.055383mm + } + ha:line.18 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.643383mm + x2 = 10.643383mm + ha:flags { + } + y1 = 5.055383mm + } + ha:line.21 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.643383mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.24 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.643383mm + ha:flags { + } + y1 = 1.524783mm + } + ha:line.27 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 3.531383mm + x2 = 3.531383mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.30 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 7.341383mm + x2 = 7.341383mm + ha:flags { + } + y1 = 0.254783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 12.167383mm + y = 1.524783mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.33 { + clearance = 0.0 + y2 = 7.143263mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.436383mm + x2 = 5.436383mm + ha:flags { + } + y1 = 7.143263mm + } + ha:line.36 { + clearance = 0.0 + y2 = 6.579383mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.032783mm + x2 = 2.032783mm + ha:flags { + } + y1 = 6.579383mm + } + ha:line.39 { + clearance = 0.0 + y2 = 7.579383mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.032783mm + x2 = 2.032783mm + ha:flags { + } + y1 = 6.579383mm + } + ha:line.42 { + clearance = 0.0 + y2 = 6.579383mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.032783mm + x2 = 3.032783mm + ha:flags { + } + y1 = 6.579383mm + } + } + ha:combining { + } + } + } + } + uid = sniNjrnRQefHo+GXiZsAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TACT_6x6_4p =================================================================== --- tags/2.3.0/pcblib/tru-hole/TACT_6x6_4p (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TACT_6x6_4p (revision 33253) @@ -0,0 +1,589 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint=tactile button + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 0.999998mm + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 4 + intconn = 2 + } + proto = 0 + xmirror = 0 + x = 1.88591in + rot = 0.000000 + y = 31.623mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 25.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 3 + intconn = 2 + } + proto = 0 + xmirror = 0 + x = 1.63in + rot = 0.000000 + y = 31.623mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 25.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 2 + intconn = 1 + } + proto = 0 + xmirror = 0 + x = 1.88591in + rot = 0.000000 + y = 27.051mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 25.0mil + } + ha:padstack_ref.10 { + smirror = 0 + ha:attributes { + term = 1 + intconn = 1 + } + proto = 0 + xmirror = 0 + x = 1.63in + rot = 0.000000 + y = 27.051mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 25.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.11 { + clearance = 0.0 + y2 = 1.03614in + thickness = 7.87mil + ha:attributes { + } + x1 = 1.87681in + x2 = 1.87681in + ha:flags { + } + y1 = 32.317944mm + } + ha:line.14 { + clearance = 0.0 + y2 = 32.317944mm + thickness = 7.87mil + ha:attributes { + } + x1 = 1.64059in + x2 = 1.87681in + ha:flags { + } + y1 = 32.317944mm + } + ha:line.17 { + clearance = 0.0 + y2 = 32.317944mm + thickness = 7.87mil + ha:attributes { + } + x1 = 1.64059in + x2 = 1.64059in + ha:flags { + } + y1 = 1.03614in + } + ha:line.20 { + clearance = 0.0 + y2 = 1.03614in + thickness = 7.87mil + ha:attributes { + } + x1 = 1.64059in + x2 = 1.87681in + ha:flags { + } + y1 = 1.03614in + } + ha:arc.23 { + astart = 90 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 46.56201mm + y = 1.07469in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.24 { + astart = 0 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 46.56201mm + y = 1.07469in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.25 { + astart = 270 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 46.56201mm + y = 1.07469in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.26 { + astart = 180 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 46.56201mm + y = 1.07469in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.27 { + astart = 0 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 46.56201mm + y = 1.23217in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.28 { + astart = 270 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 46.56201mm + y = 1.23217in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.29 { + astart = 180 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 46.56201mm + y = 1.23217in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.30 { + astart = 90 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 46.56201mm + y = 1.23217in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.31 { + astart = 270 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 1.67567in + y = 1.23217in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.32 { + astart = 180 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 1.67567in + y = 1.23217in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.33 { + astart = 90 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 1.67567in + y = 1.23217in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.34 { + astart = 0 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 1.67567in + y = 1.23217in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.35 { + astart = 180 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 1.67567in + y = 1.07469in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.36 { + astart = 90 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 1.67567in + y = 1.07469in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.37 { + astart = 0 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 1.67567in + y = 1.07469in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.38 { + astart = 270 + thickness = 7.87mil + width = 0.700024mm + height = 0.700024mm + ha:attributes { + } + x = 1.67567in + y = 1.07469in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.39 { + astart = 270 + thickness = 7.87mil + width = 66.93mil + height = 66.93mil + ha:attributes { + } + x = 1.75441in + y = 1.15343in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.40 { + astart = 180 + thickness = 7.87mil + width = 66.93mil + height = 66.93mil + ha:attributes { + } + x = 1.75441in + y = 1.15343in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.41 { + astart = 90 + thickness = 7.87mil + width = 66.93mil + height = 66.93mil + ha:attributes { + } + x = 1.75441in + y = 1.15343in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:arc.42 { + astart = 0 + thickness = 7.87mil + width = 66.93mil + height = 66.93mil + ha:attributes { + } + x = 1.75441in + y = 1.15343in + adelta = 90 + ha:flags { + } + clearance = 0.0 + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 1.755in + y = 1.155in + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.43 { + clearance = 0.0 + y2 = 1.155in + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 1.757955in + x2 = 1.757955in + ha:flags { + } + y1 = 1.155in + } + ha:line.46 { + clearance = 0.0 + y2 = 1.155in + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 1.755in + x2 = 1.755in + ha:flags { + } + y1 = 1.155in + } + ha:line.49 { + clearance = 0.0 + y2 = 1.155in + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 1.755in + x2 = 45.577mm + ha:flags { + } + y1 = 1.155in + } + ha:line.52 { + clearance = 0.0 + y2 = 30.337mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 1.755in + x2 = 1.755in + ha:flags { + } + y1 = 1.155in + } + } + ha:combining { + } + } + } + } + uid = 2piHZ3u6tsVyFj4ZzGwAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO126.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO126.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO126.fp (revision 33253) @@ -0,0 +1,534 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO126 Transistor + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 52.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 52.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 110.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 130.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 130.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 130.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 136.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 136.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 110.0mil + rot = 0.000000 + y = 600.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 200.0mil + rot = 0.000000 + y = 600.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 290.0mil + rot = 0.000000 + y = 600.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.10 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 2 + xmirror = 0 + x = 200.0mil + rot = 0.000000 + y = 170.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.11 { + clearance = 0.0 + y2 = 500.0mil + thickness = 30.0mil + ha:attributes { + } + x1 = 100.0mil + x2 = 100.0mil + ha:flags { + } + y1 = 600.0mil + } + ha:line.14 { + clearance = 0.0 + y2 = 500.0mil + thickness = 30.0mil + ha:attributes { + } + x1 = 200.0mil + x2 = 200.0mil + ha:flags { + } + y1 = 600.0mil + } + ha:line.17 { + clearance = 0.0 + y2 = 500.0mil + thickness = 30.0mil + ha:attributes { + } + x1 = 300.0mil + x2 = 300.0mil + ha:flags { + } + y1 = 600.0mil + } + ha:line.20 { + clearance = 0.0 + y2 = 500.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 50.0mil + x2 = 350.0mil + ha:flags { + } + y1 = 500.0mil + } + ha:line.23 { + clearance = 0.0 + y2 = 70.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 350.0mil + x2 = 350.0mil + ha:flags { + } + y1 = 500.0mil + } + ha:line.26 { + clearance = 0.0 + y2 = 70.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 350.0mil + x2 = 50.0mil + ha:flags { + } + y1 = 70.0mil + } + ha:line.29 { + clearance = 0.0 + y2 = 500.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 50.0mil + x2 = 50.0mil + ha:flags { + } + y1 = 70.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 80.0mil + y = 480.0mil + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.32 { + clearance = 0.0 + y2 = 492.5mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 200.0mil + x2 = 200.0mil + ha:flags { + } + y1 = 492.5mil + } + ha:line.35 { + clearance = 0.0 + y2 = 600.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 100.0mil + x2 = 100.0mil + ha:flags { + } + y1 = 600.0mil + } + ha:line.38 { + clearance = 0.0 + y2 = 16.24mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 100.0mil + x2 = 100.0mil + ha:flags { + } + y1 = 600.0mil + } + ha:line.41 { + clearance = 0.0 + y2 = 600.0mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 100.0mil + x2 = 3.54mm + ha:flags { + } + y1 = 600.0mil + } + } + ha:combining { + } + } + } + } + uid = O0KUDhlczEfk/O0PriQAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO126S.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO126S.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO126S.fp (revision 33253) @@ -0,0 +1,534 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO126S Transistor + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 52.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 52.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 110.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 130.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 130.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 130.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 136.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 136.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 110.0mil + rot = 0.000000 + y = 600.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 200.0mil + rot = 0.000000 + y = 700.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 290.0mil + rot = 0.000000 + y = 600.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.10 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 2 + xmirror = 0 + x = 200.0mil + rot = 0.000000 + y = 170.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.11 { + clearance = 0.0 + y2 = 500.0mil + thickness = 30.0mil + ha:attributes { + } + x1 = 100.0mil + x2 = 100.0mil + ha:flags { + } + y1 = 600.0mil + } + ha:line.14 { + clearance = 0.0 + y2 = 500.0mil + thickness = 30.0mil + ha:attributes { + } + x1 = 200.0mil + x2 = 200.0mil + ha:flags { + } + y1 = 700.0mil + } + ha:line.17 { + clearance = 0.0 + y2 = 500.0mil + thickness = 30.0mil + ha:attributes { + } + x1 = 300.0mil + x2 = 300.0mil + ha:flags { + } + y1 = 600.0mil + } + ha:line.20 { + clearance = 0.0 + y2 = 500.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 50.0mil + x2 = 350.0mil + ha:flags { + } + y1 = 500.0mil + } + ha:line.23 { + clearance = 0.0 + y2 = 70.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 350.0mil + x2 = 350.0mil + ha:flags { + } + y1 = 500.0mil + } + ha:line.26 { + clearance = 0.0 + y2 = 70.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 350.0mil + x2 = 50.0mil + ha:flags { + } + y1 = 70.0mil + } + ha:line.29 { + clearance = 0.0 + y2 = 500.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 50.0mil + x2 = 50.0mil + ha:flags { + } + y1 = 70.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 80.0mil + y = 480.0mil + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.32 { + clearance = 0.0 + y2 = 517.5mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 200.0mil + x2 = 200.0mil + ha:flags { + } + y1 = 517.5mil + } + ha:line.35 { + clearance = 0.0 + y2 = 600.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 100.0mil + x2 = 100.0mil + ha:flags { + } + y1 = 600.0mil + } + ha:line.38 { + clearance = 0.0 + y2 = 16.24mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 100.0mil + x2 = 100.0mil + ha:flags { + } + y1 = 600.0mil + } + ha:line.41 { + clearance = 0.0 + y2 = 600.0mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 100.0mil + x2 = 3.54mm + ha:flags { + } + y1 = 600.0mil + } + } + ha:combining { + } + } + } + } + uid = Iqh6vyX2eHbtviil6fUAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO126SW.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO126SW.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO126SW.fp (revision 33253) @@ -0,0 +1,434 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO126SW Transistor + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 52.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 52.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 110.0mil + rot = 0.000000 + y = 100.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 200.0mil + rot = 0.000000 + y = 200.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 290.0mil + rot = 0.000000 + y = 100.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 150.0mil + thickness = 30.0mil + ha:attributes { + } + x1 = 200.0mil + x2 = 200.0mil + ha:flags { + } + y1 = 200.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 50.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 50.0mil + x2 = 350.0mil + ha:flags { + } + y1 = 50.0mil + } + ha:line.16 { + clearance = 0.0 + y2 = 150.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 350.0mil + x2 = 350.0mil + ha:flags { + } + y1 = 50.0mil + } + ha:line.19 { + clearance = 0.0 + y2 = 150.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 350.0mil + x2 = 50.0mil + ha:flags { + } + y1 = 150.0mil + } + ha:line.22 { + clearance = 0.0 + y2 = 50.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 50.0mil + x2 = 50.0mil + ha:flags { + } + y1 = 150.0mil + } + ha:line.25 { + clearance = 0.0 + y2 = 150.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 150.0mil + x2 = 150.0mil + ha:flags { + } + y1 = 50.0mil + } + ha:line.28 { + clearance = 0.0 + y2 = 150.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 250.0mil + x2 = 250.0mil + ha:flags { + } + y1 = 50.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 270.0mil + y = 170.0mil + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.31 { + clearance = 0.0 + y2 = 3.386666mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 200.0mil + x2 = 200.0mil + ha:flags { + } + y1 = 3.386666mm + } + ha:line.34 { + clearance = 0.0 + y2 = 100.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 100.0mil + x2 = 100.0mil + ha:flags { + } + y1 = 100.0mil + } + ha:line.37 { + clearance = 0.0 + y2 = 100.0mil + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 100.0mil + x2 = 3.54mm + ha:flags { + } + y1 = 100.0mil + } + ha:line.40 { + clearance = 0.0 + y2 = 3.54mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 100.0mil + x2 = 100.0mil + ha:flags { + } + y1 = 100.0mil + } + } + ha:combining { + } + } + } + } + uid = sxuYoda+IstkKcLGGkQAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO126W.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO126W.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO126W.fp (revision 33253) @@ -0,0 +1,398 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO126W Transistor + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 52.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 52.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 110.0mil + rot = 0.000000 + y = 100.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 200.0mil + rot = 0.000000 + y = 100.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 290.0mil + rot = 0.000000 + y = 100.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 50.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 50.0mil + x2 = 350.0mil + ha:flags { + } + y1 = 50.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 150.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 350.0mil + x2 = 350.0mil + ha:flags { + } + y1 = 50.0mil + } + ha:line.16 { + clearance = 0.0 + y2 = 150.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 350.0mil + x2 = 50.0mil + ha:flags { + } + y1 = 150.0mil + } + ha:line.19 { + clearance = 0.0 + y2 = 50.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 50.0mil + x2 = 50.0mil + ha:flags { + } + y1 = 150.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 60.0mil + y = 170.0mil + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.22 { + clearance = 0.0 + y2 = 100.0mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 200.0mil + x2 = 200.0mil + ha:flags { + } + y1 = 100.0mil + } + ha:line.25 { + clearance = 0.0 + y2 = 100.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 100.0mil + x2 = 100.0mil + ha:flags { + } + y1 = 100.0mil + } + ha:line.28 { + clearance = 0.0 + y2 = 3.54mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 100.0mil + x2 = 100.0mil + ha:flags { + } + y1 = 100.0mil + } + ha:line.31 { + clearance = 0.0 + y2 = 100.0mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 100.0mil + x2 = 3.54mm + ha:flags { + } + y1 = 100.0mil + } + } + ha:combining { + } + } + } + } + uid = M7n7GB058pNjVDcWttAAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO18.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO18.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO18.fp (revision 33253) @@ -0,0 +1,305 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO18 Transistor + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 55.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 55.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 55.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 61.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 61.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.61874mm + rot = 0.000000 + y = 1.549792mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 0 + xmirror = 0 + x = 53.1mil + rot = 0.000000 + y = 2.819792mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 0 + xmirror = 0 + x = 2.61874mm + rot = 0.000000 + y = 4.089792mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.11 { + clearance = 0.0 + y2 = 0.127392mm + thickness = 10.0mil + ha:attributes { + } + x1 = 4.32054mm + x2 = 5.00634mm + ha:flags { + } + y1 = 0.813192mm + } + ha:line.14 { + clearance = 0.0 + y2 = 0.279792mm + thickness = 10.0mil + ha:attributes { + } + x1 = 4.47294mm + x2 = 5.15874mm + ha:flags { + } + y1 = 0.965592mm + } + ha:line.17 { + clearance = 0.0 + y2 = 0.432192mm + thickness = 10.0mil + ha:attributes { + } + x1 = 4.62534mm + x2 = 5.31114mm + ha:flags { + } + y1 = 1.117992mm + } + ha:line.20 { + clearance = 0.0 + y2 = 0.432192mm + thickness = 10.0mil + ha:attributes { + } + x1 = 5.00634mm + x2 = 5.31114mm + ha:flags { + } + y1 = 0.127392mm + } + ha:arc.10 { + astart = 0 + thickness = 10.0mil + width = 98.0mil + height = 98.0mil + ha:attributes { + } + x = 2.61874mm + y = 2.819792mm + adelta = 360 + ha:flags { + } + clearance = 0.0 + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 4.14274mm + y = 4.597792mm + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.23 { + clearance = 0.0 + y2 = 2.819792mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 2.195406mm + x2 = 2.195406mm + ha:flags { + } + y1 = 2.819792mm + } + ha:line.26 { + clearance = 0.0 + y2 = 2.819792mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.61874mm + x2 = 2.61874mm + ha:flags { + } + y1 = 2.819792mm + } + ha:line.29 { + clearance = 0.0 + y2 = 1.819792mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.61874mm + x2 = 2.61874mm + ha:flags { + } + y1 = 2.819792mm + } + ha:line.32 { + clearance = 0.0 + y2 = 2.819792mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.61874mm + x2 = 1.61874mm + ha:flags { + } + y1 = 2.819792mm + } + } + ha:combining { + } + } + } + } + uid = OidYcSm6o+LolzS8Q8kAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO218.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO218.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO218.fp (revision 33253) @@ -0,0 +1,434 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO218 diode in TO220 + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -53.0mil + -53.0mil + 53.0mil + -53.0mil + 53.0mil + 53.0mil + -53.0mil + 53.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -53.0mil + -53.0mil + 53.0mil + -53.0mil + 53.0mil + 53.0mil + -53.0mil + 53.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 106.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 106.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.489983mm + rot = 0.000000 + y = 3.302783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 8.052583mm + rot = 0.000000 + y = 3.302783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 13.615183mm + rot = 0.000000 + y = 3.302783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 5.334783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.13 { + clearance = 0.0 + y2 = 5.334783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 15.875783mm + ha:flags { + } + y1 = 5.334783mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 15.875783mm + x2 = 15.875783mm + ha:flags { + } + y1 = 5.334783mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 15.875783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.22 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 15.875783mm + ha:flags { + } + y1 = 1.524783mm + } + ha:line.25 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 6.147583mm + x2 = 6.147583mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.28 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 9.957583mm + x2 = 9.957583mm + ha:flags { + } + y1 = 0.254783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 17.399783mm + y = 1.524783mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.31 { + clearance = 0.0 + y2 = 3.302783mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 8.052583mm + x2 = 8.052583mm + ha:flags { + } + y1 = 3.302783mm + } + ha:line.34 { + clearance = 0.0 + y2 = 6.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.489983mm + x2 = 2.489983mm + ha:flags { + } + y1 = 6.858783mm + } + ha:line.37 { + clearance = 0.0 + y2 = 7.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.489983mm + x2 = 2.489983mm + ha:flags { + } + y1 = 6.858783mm + } + ha:line.40 { + clearance = 0.0 + y2 = 6.858783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.489983mm + x2 = 3.489983mm + ha:flags { + } + y1 = 6.858783mm + } + } + ha:combining { + } + } + } + } + uid = es25ud3aaCFW34xH0swAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO220.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO220.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO220.fp (revision 33253) @@ -0,0 +1,678 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO220 Transistor + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 130.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 150.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 150.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 150.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 156.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 156.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.794783mm + rot = 0.000000 + y = 20.320783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 5.334783mm + rot = 0.000000 + y = 20.320783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 7.874783mm + rot = 0.000000 + y = 20.320783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.10 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 2 + xmirror = 0 + x = 5.334783mm + rot = 0.000000 + y = 3.302783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.11 { + clearance = 0.0 + y2 = 15.748783mm + thickness = 30.0mil + ha:attributes { + } + x1 = 2.794783mm + x2 = 2.794783mm + ha:flags { + } + y1 = 20.320783mm + } + ha:line.14 { + clearance = 0.0 + y2 = 15.748783mm + thickness = 30.0mil + ha:attributes { + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 20.320783mm + } + ha:line.17 { + clearance = 0.0 + y2 = 15.748783mm + thickness = 30.0mil + ha:attributes { + } + x1 = 7.874783mm + x2 = 7.874783mm + ha:flags { + } + y1 = 20.320783mm + } + ha:line.20 { + clearance = 0.0 + y2 = 15.748783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 15.748783mm + } + ha:line.23 { + clearance = 0.0 + y2 = 6.223783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 15.748783mm + } + ha:line.26 { + clearance = 0.0 + y2 = 6.223783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 6.223783mm + } + ha:line.29 { + clearance = 0.0 + y2 = 15.748783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 6.223783mm + } + ha:line.32 { + clearance = 0.0 + y2 = 6.223783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 6.223783mm + } + ha:line.35 { + clearance = 0.0 + y2 = 3.048783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 6.223783mm + } + ha:line.38 { + clearance = 0.0 + y2 = 3.048783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.033783mm + ha:flags { + } + y1 = 3.048783mm + } + ha:line.41 { + clearance = 0.0 + y2 = 1.270783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.033783mm + x2 = 10.033783mm + ha:flags { + } + y1 = 3.048783mm + } + ha:line.44 { + clearance = 0.0 + y2 = 1.270783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.033783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 1.270783mm + } + ha:line.47 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 1.270783mm + } + ha:line.50 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.53 { + clearance = 0.0 + y2 = 1.270783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.56 { + clearance = 0.0 + y2 = 1.270783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.635783mm + ha:flags { + } + y1 = 1.270783mm + } + ha:line.59 { + clearance = 0.0 + y2 = 3.048783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.635783mm + x2 = 0.635783mm + ha:flags { + } + y1 = 1.270783mm + } + ha:line.62 { + clearance = 0.0 + y2 = 3.048783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.635783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 3.048783mm + } + ha:line.65 { + clearance = 0.0 + y2 = 6.223783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 3.048783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 1.524783mm + y = 14.478783mm + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.68 { + clearance = 0.0 + y2 = 16.066283mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 16.066283mm + } + ha:line.71 { + clearance = 0.0 + y2 = 20.320783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 20.320783mm + } + ha:line.74 { + clearance = 0.0 + y2 = 21.320783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 20.320783mm + } + ha:line.77 { + clearance = 0.0 + y2 = 20.320783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 5.334783mm + x2 = 6.334783mm + ha:flags { + } + y1 = 20.320783mm + } + } + ha:combining { + } + } + } + } + uid = uOkA89keooMxmh5v+cMAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO220ACSTAND.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO220ACSTAND.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO220ACSTAND.fp (revision 33253) @@ -0,0 +1,416 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO220ACSTAND diode in TO220 + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 40.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -40.0mil + -40.0mil + 40.0mil + -40.0mil + 40.0mil + 40.0mil + -40.0mil + 40.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -43.0mil + -43.0mil + 43.0mil + -43.0mil + 43.0mil + 43.0mil + -43.0mil + 43.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 40.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 80.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 86.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.794783mm + rot = 0.000000 + y = 2.794783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 7.874783mm + rot = 0.000000 + y = 2.794783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 4.826783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.12 { + clearance = 0.0 + y2 = 4.826783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 4.826783mm + } + ha:line.15 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 4.826783mm + } + ha:line.18 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.21 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 1.524783mm + } + ha:line.24 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 3.429783mm + x2 = 3.429783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.27 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 7.239783mm + x2 = 7.239783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 11.938783mm + y = 1.524783mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.30 { + clearance = 0.0 + y2 = 2.794783mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 2.794783mm + } + ha:line.33 { + clearance = 0.0 + y2 = 5.842783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.794783mm + x2 = 2.794783mm + ha:flags { + } + y1 = 5.842783mm + } + ha:line.36 { + clearance = 0.0 + y2 = 5.842783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.794783mm + x2 = 3.794783mm + ha:flags { + } + y1 = 5.842783mm + } + ha:line.39 { + clearance = 0.0 + y2 = 6.842783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.794783mm + x2 = 2.794783mm + ha:flags { + } + y1 = 5.842783mm + } + } + ha:combining { + } + } + } + } + uid = giMFC8I9a3NsCRqIha4AAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO220S.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO220S.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO220S.fp (revision 33253) @@ -0,0 +1,678 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO220S Transistor + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.2 { + htop = 0 + hdia = 130.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 150.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 150.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 150.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 156.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 156.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.794783mm + rot = 0.000000 + y = 20.320783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 5.334783mm + rot = 0.000000 + y = 22.860783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 7.874783mm + rot = 0.000000 + y = 20.320783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.10 { + smirror = 0 + ha:attributes { + term = 4 + name = 4 + } + proto = 2 + xmirror = 0 + x = 5.334783mm + rot = 0.000000 + y = 3.302783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.11 { + clearance = 0.0 + y2 = 15.748783mm + thickness = 30.0mil + ha:attributes { + } + x1 = 2.794783mm + x2 = 2.794783mm + ha:flags { + } + y1 = 20.320783mm + } + ha:line.14 { + clearance = 0.0 + y2 = 15.748783mm + thickness = 30.0mil + ha:attributes { + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 22.860783mm + } + ha:line.17 { + clearance = 0.0 + y2 = 15.748783mm + thickness = 30.0mil + ha:attributes { + } + x1 = 7.874783mm + x2 = 7.874783mm + ha:flags { + } + y1 = 20.320783mm + } + ha:line.20 { + clearance = 0.0 + y2 = 15.748783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 15.748783mm + } + ha:line.23 { + clearance = 0.0 + y2 = 6.223783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 15.748783mm + } + ha:line.26 { + clearance = 0.0 + y2 = 6.223783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 6.223783mm + } + ha:line.29 { + clearance = 0.0 + y2 = 15.748783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 6.223783mm + } + ha:line.32 { + clearance = 0.0 + y2 = 6.223783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 6.223783mm + } + ha:line.35 { + clearance = 0.0 + y2 = 3.048783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 6.223783mm + } + ha:line.38 { + clearance = 0.0 + y2 = 3.048783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.033783mm + ha:flags { + } + y1 = 3.048783mm + } + ha:line.41 { + clearance = 0.0 + y2 = 1.270783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.033783mm + x2 = 10.033783mm + ha:flags { + } + y1 = 3.048783mm + } + ha:line.44 { + clearance = 0.0 + y2 = 1.270783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.033783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 1.270783mm + } + ha:line.47 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 1.270783mm + } + ha:line.50 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.53 { + clearance = 0.0 + y2 = 1.270783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.56 { + clearance = 0.0 + y2 = 1.270783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.635783mm + ha:flags { + } + y1 = 1.270783mm + } + ha:line.59 { + clearance = 0.0 + y2 = 3.048783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.635783mm + x2 = 0.635783mm + ha:flags { + } + y1 = 1.270783mm + } + ha:line.62 { + clearance = 0.0 + y2 = 3.048783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.635783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 3.048783mm + } + ha:line.65 { + clearance = 0.0 + y2 = 6.223783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 3.048783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 1.524783mm + y = 14.478783mm + rot = 90.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.68 { + clearance = 0.0 + y2 = 16.701283mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 16.701283mm + } + ha:line.71 { + clearance = 0.0 + y2 = 20.320783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 20.320783mm + } + ha:line.74 { + clearance = 0.0 + y2 = 21.320783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 20.320783mm + } + ha:line.77 { + clearance = 0.0 + y2 = 20.320783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 5.334783mm + x2 = 6.334783mm + ha:flags { + } + y1 = 20.320783mm + } + } + ha:combining { + } + } + } + } + uid = kX4D5wU+XHa4jjNd2YMAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO220SW.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO220SW.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO220SW.fp (revision 33253) @@ -0,0 +1,482 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO220SW Transistor + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.794783mm + rot = 0.000000 + y = 200.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 5.334783mm + rot = 0.000000 + y = 300.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 7.874783mm + rot = 0.000000 + y = 200.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 80.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 80.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 260.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 80.0mil + } + ha:line.16 { + clearance = 0.0 + y2 = 260.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 260.0mil + } + ha:line.19 { + clearance = 0.0 + y2 = 80.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 260.0mil + } + ha:line.22 { + clearance = 0.0 + y2 = 80.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 80.0mil + } + ha:line.25 { + clearance = 0.0 + y2 = 140.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 80.0mil + } + ha:line.28 { + clearance = 0.0 + y2 = 140.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 140.0mil + } + ha:line.31 { + clearance = 0.0 + y2 = 80.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 140.0mil + } + ha:line.34 { + clearance = 0.0 + y2 = 140.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 3.556783mm + x2 = 3.556783mm + ha:flags { + } + y1 = 80.0mil + } + ha:line.37 { + clearance = 0.0 + y2 = 140.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 7.112783mm + x2 = 7.112783mm + ha:flags { + } + y1 = 80.0mil + } + ha:line.40 { + clearance = 0.0 + y2 = 260.0mil + thickness = 30.0mil + ha:attributes { + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 300.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 0.254783mm + y = 10.0mil + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.43 { + clearance = 0.0 + y2 = 5.926666mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 5.926666mm + } + ha:line.46 { + clearance = 0.0 + y2 = 200.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.794783mm + x2 = 2.794783mm + ha:flags { + } + y1 = 200.0mil + } + ha:line.49 { + clearance = 0.0 + y2 = 200.0mil + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.794783mm + x2 = 3.794783mm + ha:flags { + } + y1 = 200.0mil + } + ha:line.52 { + clearance = 0.0 + y2 = 6.08mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.794783mm + x2 = 2.794783mm + ha:flags { + } + y1 = 200.0mil + } + } + ha:combining { + } + } + } + } + uid = wyLdsi+eW/3szft7c1QAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO220W.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO220W.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO220W.fp (revision 33253) @@ -0,0 +1,470 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO220W Transistor + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -45.0mil + -45.0mil + 45.0mil + -45.0mil + 45.0mil + 45.0mil + -45.0mil + 45.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -48.0mil + -48.0mil + 48.0mil + -48.0mil + 48.0mil + 48.0mil + -48.0mil + 48.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 90.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 96.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.794783mm + rot = 0.000000 + y = 200.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 5.334783mm + rot = 0.000000 + y = 200.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 7.874783mm + rot = 0.000000 + y = 200.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 80.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 80.0mil + } + ha:line.13 { + clearance = 0.0 + y2 = 260.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 80.0mil + } + ha:line.16 { + clearance = 0.0 + y2 = 260.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 260.0mil + } + ha:line.19 { + clearance = 0.0 + y2 = 80.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 260.0mil + } + ha:line.22 { + clearance = 0.0 + y2 = 80.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 80.0mil + } + ha:line.25 { + clearance = 0.0 + y2 = 140.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 80.0mil + } + ha:line.28 { + clearance = 0.0 + y2 = 140.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 10.414783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 140.0mil + } + ha:line.31 { + clearance = 0.0 + y2 = 80.0mil + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 140.0mil + } + ha:line.34 { + clearance = 0.0 + y2 = 140.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 3.556783mm + x2 = 3.556783mm + ha:flags { + } + y1 = 80.0mil + } + ha:line.37 { + clearance = 0.0 + y2 = 140.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 7.112783mm + x2 = 7.112783mm + ha:flags { + } + y1 = 80.0mil + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 0.254783mm + y = 10.0mil + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.40 { + clearance = 0.0 + y2 = 200.0mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 5.334783mm + x2 = 5.334783mm + ha:flags { + } + y1 = 200.0mil + } + ha:line.43 { + clearance = 0.0 + y2 = 200.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.794783mm + x2 = 2.794783mm + ha:flags { + } + y1 = 200.0mil + } + ha:line.46 { + clearance = 0.0 + y2 = 6.08mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.794783mm + x2 = 2.794783mm + ha:flags { + } + y1 = 200.0mil + } + ha:line.49 { + clearance = 0.0 + y2 = 200.0mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.794783mm + x2 = 3.794783mm + ha:flags { + } + y1 = 200.0mil + } + } + ha:combining { + } + } + } + } + uid = ayqDUR+Z6aT2RssOtxMAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO247.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO247.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO247.fp (revision 33253) @@ -0,0 +1,434 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO247 diode in TO220 + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -53.0mil + -53.0mil + 53.0mil + -53.0mil + 53.0mil + 53.0mil + -53.0mil + 53.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -53.0mil + -53.0mil + 53.0mil + -53.0mil + 53.0mil + 53.0mil + -53.0mil + 53.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 106.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 106.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.693183mm + rot = 0.000000 + y = 3.556783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 8.255783mm + rot = 0.000000 + y = 3.556783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 13.818383mm + rot = 0.000000 + y = 3.556783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 5.588783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.13 { + clearance = 0.0 + y2 = 5.588783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 16.256783mm + ha:flags { + } + y1 = 5.588783mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 16.256783mm + x2 = 16.256783mm + ha:flags { + } + y1 = 5.588783mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 16.256783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.22 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 16.256783mm + ha:flags { + } + y1 = 1.524783mm + } + ha:line.25 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 6.350783mm + x2 = 6.350783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.28 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 10.160783mm + x2 = 10.160783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 17.780783mm + y = 1.524783mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.31 { + clearance = 0.0 + y2 = 3.556783mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 8.255783mm + x2 = 8.255783mm + ha:flags { + } + y1 = 3.556783mm + } + ha:line.34 { + clearance = 0.0 + y2 = 7.112783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.693183mm + x2 = 2.693183mm + ha:flags { + } + y1 = 7.112783mm + } + ha:line.37 { + clearance = 0.0 + y2 = 8.112783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.693183mm + x2 = 2.693183mm + ha:flags { + } + y1 = 7.112783mm + } + ha:line.40 { + clearance = 0.0 + y2 = 7.112783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.693183mm + x2 = 3.693183mm + ha:flags { + } + y1 = 7.112783mm + } + } + ha:combining { + } + } + } + } + uid = iN8eCDY1d9cB+LCvYmsAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO247_2.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO247_2.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO247_2.fp (revision 33253) @@ -0,0 +1,416 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO247_2 diode in TO220 + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -53.0mil + -53.0mil + 53.0mil + -53.0mil + 53.0mil + 53.0mil + -53.0mil + 53.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -53.0mil + -53.0mil + 53.0mil + -53.0mil + 53.0mil + 53.0mil + -53.0mil + 53.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 106.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 106.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 2.693183mm + rot = 0.000000 + y = 3.556783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 13.818383mm + rot = 0.000000 + y = 3.556783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.9 { + clearance = 0.0 + y2 = 5.588783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.12 { + clearance = 0.0 + y2 = 5.588783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 16.256783mm + ha:flags { + } + y1 = 5.588783mm + } + ha:line.15 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 16.256783mm + x2 = 16.256783mm + ha:flags { + } + y1 = 5.588783mm + } + ha:line.18 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 16.256783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.21 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 16.256783mm + ha:flags { + } + y1 = 1.524783mm + } + ha:line.24 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 6.350783mm + x2 = 6.350783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.27 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 10.160783mm + x2 = 10.160783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 17.780783mm + y = 1.524783mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.30 { + clearance = 0.0 + y2 = 3.556783mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 8.255783mm + x2 = 8.255783mm + ha:flags { + } + y1 = 3.556783mm + } + ha:line.33 { + clearance = 0.0 + y2 = 7.112783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 2.693183mm + x2 = 2.693183mm + ha:flags { + } + y1 = 7.112783mm + } + ha:line.36 { + clearance = 0.0 + y2 = 7.112783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 2.693183mm + x2 = 3.693183mm + ha:flags { + } + y1 = 7.112783mm + } + ha:line.39 { + clearance = 0.0 + y2 = 8.112783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 2.693183mm + x2 = 2.693183mm + ha:flags { + } + y1 = 7.112783mm + } + } + ha:combining { + } + } + } + } + uid = WJYlfial3zliAL7vW/EAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO251.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO251.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO251.fp (revision 33253) @@ -0,0 +1,434 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO251 diode in TO220 + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 40.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -35.0mil + -35.0mil + 35.0mil + -35.0mil + 35.0mil + 35.0mil + -35.0mil + 35.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -35.0mil + -35.0mil + 35.0mil + -35.0mil + 35.0mil + 35.0mil + -35.0mil + 35.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -35.0mil + -35.0mil + 35.0mil + -35.0mil + 35.0mil + 35.0mil + -35.0mil + 35.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -38.0mil + -38.0mil + 38.0mil + -38.0mil + 38.0mil + 38.0mil + -38.0mil + 38.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -38.0mil + -38.0mil + 38.0mil + -38.0mil + 38.0mil + 38.0mil + -38.0mil + 38.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 40.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 70.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 70.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 70.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 76.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 76.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 53.0mil + rot = 0.000000 + y = 1.524783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 143.0mil + rot = 0.000000 + y = 1.524783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 233.0mil + rot = 0.000000 + y = 1.524783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 2.794783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 11.0mil + x2 = 11.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:line.13 { + clearance = 0.0 + y2 = 2.794783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 11.0mil + x2 = 276.0mil + ha:flags { + } + y1 = 2.794783mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 276.0mil + x2 = 276.0mil + ha:flags { + } + y1 = 2.794783mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 276.0mil + x2 = 11.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:line.22 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 11.0mil + x2 = 276.0mil + ha:flags { + } + y1 = 1.524783mm + } + ha:line.25 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 68.0mil + x2 = 68.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:line.28 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 218.0mil + x2 = 218.0mil + ha:flags { + } + y1 = 0.254783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 336.0mil + y = 1.524783mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.31 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 143.0mil + x2 = 143.0mil + ha:flags { + } + y1 = 1.524783mm + } + ha:line.34 { + clearance = 0.0 + y2 = 3.810783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 53.0mil + x2 = 53.0mil + ha:flags { + } + y1 = 3.810783mm + } + ha:line.37 { + clearance = 0.0 + y2 = 4.810783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 53.0mil + x2 = 53.0mil + ha:flags { + } + y1 = 3.810783mm + } + ha:line.40 { + clearance = 0.0 + y2 = 3.810783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 53.0mil + x2 = 2.3462mm + ha:flags { + } + y1 = 3.810783mm + } + } + ha:combining { + } + } + } + } + uid = v2nZCPR4jv3R3f/6N5sAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO264.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO264.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO264.fp (revision 33253) @@ -0,0 +1,434 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO264 diode in TO220 + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -50.0mil + -50.0mil + 50.0mil + -50.0mil + 50.0mil + 50.0mil + -50.0mil + 50.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -53.0mil + -53.0mil + 53.0mil + -53.0mil + 53.0mil + 53.0mil + -53.0mil + 53.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -53.0mil + -53.0mil + 53.0mil + -53.0mil + 53.0mil + 53.0mil + -53.0mil + 53.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 60.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 100.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 106.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 106.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 4.852183mm + rot = 0.000000 + y = 3.556783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 10.414783mm + rot = 0.000000 + y = 3.556783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 15.977383mm + rot = 0.000000 + y = 3.556783mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 5.588783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.13 { + clearance = 0.0 + y2 = 5.588783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 20.574783mm + ha:flags { + } + y1 = 5.588783mm + } + ha:line.16 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 20.574783mm + x2 = 20.574783mm + ha:flags { + } + y1 = 5.588783mm + } + ha:line.19 { + clearance = 0.0 + y2 = 0.254783mm + thickness = 20.0mil + ha:attributes { + } + x1 = 20.574783mm + x2 = 0.254783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.22 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 0.254783mm + x2 = 20.574783mm + ha:flags { + } + y1 = 1.524783mm + } + ha:line.25 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 8.509783mm + x2 = 8.509783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:line.28 { + clearance = 0.0 + y2 = 1.524783mm + thickness = 10.0mil + ha:attributes { + } + x1 = 12.319783mm + x2 = 12.319783mm + ha:flags { + } + y1 = 0.254783mm + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 22.098783mm + y = 1.524783mm + rot = 270.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.31 { + clearance = 0.0 + y2 = 3.556783mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 10.414783mm + x2 = 10.414783mm + ha:flags { + } + y1 = 3.556783mm + } + ha:line.34 { + clearance = 0.0 + y2 = 7.112783mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 4.852183mm + x2 = 4.852183mm + ha:flags { + } + y1 = 7.112783mm + } + ha:line.37 { + clearance = 0.0 + y2 = 8.112783mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 4.852183mm + x2 = 4.852183mm + ha:flags { + } + y1 = 7.112783mm + } + ha:line.40 { + clearance = 0.0 + y2 = 7.112783mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 4.852183mm + x2 = 5.852183mm + ha:flags { + } + y1 = 7.112783mm + } + } + ha:combining { + } + } + } + } + uid = 8OAC9HM9Aw1ZzceKxDMAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO39.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO39.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO39.fp (revision 33253) @@ -0,0 +1,412 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO39 Transistor + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -27.5mil + -27.5mil + 27.5mil + -27.5mil + 27.5mil + 27.5mil + -27.5mil + 27.5mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -27.5mil + -27.5mil + 27.5mil + -27.5mil + 27.5mil + 27.5mil + -27.5mil + 27.5mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -27.5mil + -27.5mil + 27.5mil + -27.5mil + 27.5mil + 27.5mil + -27.5mil + 27.5mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.5mil + -30.5mil + 30.5mil + -30.5mil + 30.5mil + 30.5mil + -30.5mil + 30.5mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -30.5mil + -30.5mil + 30.5mil + -30.5mil + 30.5mil + 30.5mil + -30.5mil + 30.5mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 35.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 55.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 55.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 55.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 61.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 61.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 4.77774mm + rot = 0.000000 + y = 2.23774mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 2.23774mm + rot = 0.000000 + y = 4.77774mm + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 4.77774mm + rot = 0.000000 + y = 288.1mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.10 { + clearance = 0.0 + y2 = 28.1mil + thickness = 10.0mil + ha:attributes { + } + x1 = 315.1mil + x2 = 336.1mil + ha:flags { + } + y1 = 49.1mil + } + ha:line.13 { + clearance = 0.0 + y2 = 34.1mil + thickness = 10.0mil + ha:attributes { + } + x1 = 321.1mil + x2 = 342.1mil + ha:flags { + } + y1 = 55.1mil + } + ha:line.16 { + clearance = 0.0 + y2 = 40.1mil + thickness = 10.0mil + ha:attributes { + } + x1 = 327.1mil + x2 = 348.1mil + ha:flags { + } + y1 = 61.1mil + } + ha:line.19 { + clearance = 0.0 + y2 = 28.1mil + thickness = 10.0mil + ha:attributes { + } + x1 = 348.1mil + x2 = 336.1mil + ha:flags { + } + y1 = 40.1mil + } + ha:arc.22 { + astart = 0 + thickness = 10.0mil + width = 183.0mil + height = 183.0mil + ha:attributes { + } + x = 4.77774mm + y = 4.77774mm + adelta = 360 + ha:flags { + } + clearance = 0.0 + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 6.30174mm + y = 258.1mil + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.23 { + clearance = 0.0 + y2 = 4.77774mm + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 3.931073mm + x2 = 3.931073mm + ha:flags { + } + y1 = 4.77774mm + } + ha:line.26 { + clearance = 0.0 + y2 = 4.77774mm + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 4.77774mm + x2 = 4.77774mm + ha:flags { + } + y1 = 4.77774mm + } + ha:line.29 { + clearance = 0.0 + y2 = 3.77774mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 4.77774mm + x2 = 4.77774mm + ha:flags { + } + y1 = 4.77774mm + } + ha:line.32 { + clearance = 0.0 + y2 = 4.77774mm + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 4.77774mm + x2 = 3.77774mm + ha:flags { + } + y1 = 4.77774mm + } + } + ha:combining { + } + } + } + } + uid = F67S28P4pxCGLl/9emkAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/pcblib/tru-hole/TO92.fp =================================================================== --- tags/2.3.0/pcblib/tru-hole/TO92.fp (nonexistent) +++ tags/2.3.0/pcblib/tru-hole/TO92.fp (revision 33253) @@ -0,0 +1,376 @@ +li:pcb-rnd-subcircuit-v6 { + ha:subc.5 { + ha:attributes { + footprint = TO92 Transistor + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 42.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -36.0mil + -36.0mil + 36.0mil + -36.0mil + 36.0mil + 36.0mil + -36.0mil + 36.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -36.0mil + -36.0mil + 36.0mil + -36.0mil + 36.0mil + 36.0mil + -36.0mil + 36.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -36.0mil + -36.0mil + 36.0mil + -36.0mil + 36.0mil + 36.0mil + -36.0mil + 36.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -39.0mil + -39.0mil + 39.0mil + -39.0mil + 39.0mil + 39.0mil + -39.0mil + 39.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + li:ps_poly { + -39.0mil + -39.0mil + 39.0mil + -39.0mil + 39.0mil + 39.0mil + -39.0mil + 39.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v6.1 { + htop = 0 + hdia = 42.0mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 72.0mil + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 72.0mil + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 72.0mil + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 78.0mil + } + ha:layer_mask { + top = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 78.0mil + } + ha:layer_mask { + bottom = 1 + mask = 1 + } + ha:combining { + sub = 1 + auto = 1 + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.7 { + smirror = 0 + ha:attributes { + term = 1 + name = 1 + } + proto = 0 + xmirror = 0 + x = 254.0mil + rot = 0.000000 + y = 200.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.8 { + smirror = 0 + ha:attributes { + term = 2 + name = 2 + } + proto = 1 + xmirror = 0 + x = 154.0mil + rot = 0.000000 + y = 200.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + ha:padstack_ref.9 { + smirror = 0 + ha:attributes { + term = 3 + name = 3 + } + proto = 1 + xmirror = 0 + x = 54.0mil + rot = 0.000000 + y = 200.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 15.0mil + } + } + li:layers { + ha:top-silk { + lid = 0 + ha:type { + silk = 1 + top = 1 + } + li:objects { + ha:line.11 { + clearance = 0.0 + y2 = 130.0mil + thickness = 10.0mil + ha:attributes { + } + x1 = 84.0mil + x2 = 224.0mil + ha:flags { + } + y1 = 130.0mil + } + ha:arc.10 { + astart = 315 + thickness = 10.0mil + width = 100.0mil + height = 100.0mil + ha:attributes { + } + x = 154.0mil + y = 200.0mil + adelta = 270 + ha:flags { + } + clearance = 0.0 + } + ha:text.6 { + scale = 100 + ha:attributes { + } + x = 64.0mil + y = 70.0mil + rot = 0.000000 + string = %a.parent.refdes% + fid = 0 + ha:flags { + dyntext = 1 + floater = 1 + } + } + } + ha:combining { + } + } + ha:subc-aux { + lid = 1 + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + li:objects { + ha:line.14 { + clearance = 0.0 + y2 = 200.0mil + thickness = 0.1mm + ha:attributes { + subc-role = pnp-origin + } + x1 = 154.0mil + x2 = 154.0mil + ha:flags { + } + y1 = 200.0mil + } + ha:line.17 { + clearance = 0.0 + y2 = 200.0mil + thickness = 0.1mm + ha:attributes { + subc-role = origin + } + x1 = 54.0mil + x2 = 54.0mil + ha:flags { + } + y1 = 200.0mil + } + ha:line.20 { + clearance = 0.0 + y2 = 4.08mm + thickness = 0.1mm + ha:attributes { + subc-role = x + } + x1 = 54.0mil + x2 = 54.0mil + ha:flags { + } + y1 = 200.0mil + } + ha:line.23 { + clearance = 0.0 + y2 = 200.0mil + thickness = 0.1mm + ha:attributes { + subc-role = y + } + x1 = 54.0mil + x2 = 0.3716mm + ha:flags { + } + y1 = 200.0mil + } + } + ha:combining { + } + } + } + } + uid = guzk2KSYW/BVDIzhJVkAAAAB + ha:flags { + } + } +} Index: tags/2.3.0/scconfig/Makefile =================================================================== --- tags/2.3.0/scconfig/Makefile (nonexistent) +++ tags/2.3.0/scconfig/Makefile (revision 33253) @@ -0,0 +1,108 @@ +# --- configuration part -- + +# - generic configuration - +SRC=src +BIN=src + +# what cflags to use to compile scconfig +USER_CFLAGS = -DGENCALL -Isrc -I../src_3rd +#USER_CFLAGS = -Wall -Wextra -g -DGENCALL -Isrc + +# what ldflags to use to link scconfig +USER_LDFLAGS = + +# in case hooks.c needs to link to something local +USER_OBJS = src/util/arg_auto_set.o + +# what to build - a ./configure +all: configure cquote + +# 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 software utility libs (glib) +include src/sul/Makefile.plugin + +# Uncomment this line if you need menus +include src/menulib/Makefile.plugin + +# Comment this line if you do not need generator (templating) +include src/generator/Makefile.plugin.legacy + +# Comment this line if you do not need tmpasm (templating) +include src/tmpasm/Makefile.plugin + +# --- you shouldn't edit the lines below --- +OBJS = $(USER_OBJS) hooks.o $(DEFAULT_NOMAIN_OBJS) $(SCRIPT_OBJS) $(PARSER_OBJS) $(GENERATOR_OBJS) $(TMPASM_OBJS) $(C99_OBJS) $(PARSGEN_OBJS) $(MATH_OBJS) $(SOCKET_OBJS) $(USERPASS_OBJS) $(GUI_OBJS) $(SUL_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) $(SUL_CFLAGS) $(MENULIB_CFLAGS) -Isrc/default -I. +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) $(SUL_LDFLAGS) $(MENULIB_LDFLAGS) + +all: configure revtest sccbox + +revtest: revtest.o + $(CC) -o revtest revtest.o + +revtest.o: revtest.c Rev.h + $(CC) -c $(CFLAGS) -o revtest.o revtest.c + +configure: $(OBJS) $(DEFAULT_MAIN_OBJS) + $(CC) -o configure $(OBJS) $(DEFAULT_MAIN_OBJS) + +menuconfig: menucfg + ./menucfg + +menucfg: $(OBJS) $(MENULIB_OBJS) src/default/main_lib.o src/default/main_custom_args.o menucfg.o src/util/arg_auto_menu.o src/util/arg_auto_set.o + $(CC) -o menucfg $(OBJS) $(MENULIB_OBJS) menucfg.o src/default/main_lib.o src/default/main_custom_args.o src/util/arg_auto_menu.o + +menucfg.o: menucfg.c + $(CC) -c $(CFLAGS) -o menucfg.o menucfg.c + +LIBRNDSCC=../src_3rd/librnd/scconfig +RNDHOOKS=$(LIBRNDSCC)/plugin_3state.h $(LIBRNDSCC)/hooks_common.h $(LIBRNDSCC)/hooks_gui.c $(LIBRNDSCC)/rnd_hook_detect.h +hooks.o: hooks.c $(RNDHOOKS) plugins.h Rev.h ../src_3rd/puplug/scconfig_hooks.h ../src_3rd/libfungw/scconfig_hooks.h ../src_3rd/libporty_net/hooks_net.c + +src/util/arg_auto_set.o: src/util/arg_auto_set.c src/util/arg_auto_set.h + $(CC) -c $(CFLAGS) -o src/util/arg_auto_set.o src/util/arg_auto_set.c + +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 + +cquote: src/util/cquote.c + $(CC) $(CFLAGS) $(LDFLAGS) -o cquote src/util/cquote.c + +clean: + -rm $(OBJS) $(DEFAULT_MAIN_OBJS) configure revtest revtest.o cquote core src/util/sccbox.o + +distclean: + -rm ../config.h ../Makefile.conf ../src/Makefile ../util/gsch2pcb-rnd/Makefile config.cache config.log Rev.stamp sccbox gmon.out ../src_3rd/puplug/Makefile ../src_3rd/puplug/config.h ../src_plugins/lib_hid_gl/opengl.h + -$(MAKE) clean Index: tags/2.3.0/scconfig/README =================================================================== --- tags/2.3.0/scconfig/README (nonexistent) +++ tags/2.3.0/scconfig/README (revision 33253) @@ -0,0 +1,3 @@ +The configuration system that runs ./configure. + +The engine is scconfig. Index: tags/2.3.0/scconfig/Rev.h =================================================================== --- tags/2.3.0/scconfig/Rev.h (nonexistent) +++ tags/2.3.0/scconfig/Rev.h (revision 33253) @@ -0,0 +1 @@ +static const int myrev = 33056; Index: tags/2.3.0/scconfig/Rev.tab =================================================================== --- tags/2.3.0/scconfig/Rev.tab (nonexistent) +++ tags/2.3.0/scconfig/Rev.tab (revision 33253) @@ -0,0 +1,303 @@ +33056 configure menu item for feature plugins: asm and shape +32952 configure new plugin: ch_editpoint draw edit points of objects +32934 configure moving onpoint from core to plugin +32857 configure menu item for import_ttf +32739 configure export_test plugin removed in favor of the loghid plugin +32715 configure fp_fs plugin conf subtree +32667 configure code removal: the onpoint feature doesn't need a special array type anymore +32636 configure librnd separation +32394 configure autoroute plugin: menu and conf +32327 configure new autoroute plugin for external autorouters +32326 configure new netlist import plugins: pads ascii netlist, orcad pcb II netlist, accel netliet, protel netlist 2.0 +32284 configure io_tedax: file format support for autorouters +32216 configure cleanup: eahc plugin shall register its own menus +32187 configure librnd: infra for menu patching +32169 configure hid_lesstif is part of the hidlib +32120 configure removing the old drc in favor of drc_query +32113 configure removing custom per hid attribute editor in favor of generic central propedit +32103 configure librnd DAD API transition (label cleanup) +32099 configure remove lesstif local dialog implementations: library, netlist +31776 configure new plugin: formula, for impedance calculations +31708 configure query plugin: move the advanced search dialog from dialogs plugin to query to better access of internals +31623 configure query plugin: net length calculations +31519 configure io_tedax drc block upgrade for drc_query +31420 configure online support plugin (irc) and lib for IPv4/tcp +31295 configure tEDAx drc_query block parse +31249 configure enabled io_bxl +31116 configure include libulzw in librnd 3rd +31041 configure pcb_ -> rnd_ renames in librnd +30779 configure remove distaligntext - all cases handled by distalign properly +30754 configure remove the old import_sch plugin (in favor of import_sch2) +30753 configure disable the old drc, enable the new drc +30497 configure new util: bxl2txt +30191 configure drc_orig: plugin configuration so the checks can be disabled +30181 configure query plugin: make bloat/shrink net drc loop reusable +30169 configure query plugin: function implementation/split +29927 configure generalizing zoom and pan actions for ringdove +29778 configure new object type: gfx +29655 configure librnd separation: scconfig hooks code +29647 configure generalize the toolbar code so it can be reused in camv-rnd and sch-rnd +29567 configure import_sch conf changes, new netlist import formats +29412 configure move generic actions from core to librnd +29385 configure remove build system special casing: generated lists for action registration +29375 configure librnd separation: stroke plugin API conversion from stub to event +29340 configure librnd separation: tool code +29309 distclean librnd separation +28871 configure compile standard extobjs by default +28855 configure extended object action infra +28805 configure generate new header for librnd header integrity test +28609 configure layer code split (layer_addr.[ch]) +28441 configure remove old gcode plugin +28114 distclean puplug bug blocked loading script pups +27952 configure removing dolists.h to simplify action declaration +27878 configure hidlib related bugfix in ./configure +27468 configure order pcbway now depends on libxml2 +27454 configure order plugin config file +27403 configure tEDAx: new source file for etest save +27401 configure remove cairo from optional dependencies +27296 configure gtk: detect GDK_KEY_ prefix for supporting ~10 years old systems +27155 configure hidlib: pixmap support framework: new .c file in the hidlib and pnm, png, jpeg, gif loader plugin +27100 configure hidlib: move base64 to core for reuse in hidlib (mainly for pixmaps) +27086 configure hidlib: tests and utils should use hidlib instead of manual object linking from the source tree +27069 configure retire the export_bboard plugin in favor of subc pixmaps that are going to be implemented soon +27041 configure hidlib: remove hid_color.[ch] in favor of color_cache +26986 configure hidlib: fallback scripting with libfawk +26982 configure hidlib: conf namespace cleanup +26976 configure rename netlist2.[ch] to netlist.[ch] +26946 configure hidlib: split DAD from hid_attrib +26906 configure hidlib: split hidlib into modular rndlib and install relevant headers +26716 configure gtk: merge lib_gtk_hid into lib_gtk_common +26299 configuew hidlib: include the batch HID in hidlib +26262 configure order: move wget to lib_wget for reuse, add order plugins +26253 configure hidlib: move hidlib-common dialogs from the dialogs plugin to lib_hid_common so other hidlib apps can benefit from them +26000 configure hildib: separate polygon generator funtions so they can be reused by hidlib apps +25853 configure new plugin for data access actions +25789 configure centralize the unit selector widget in a DAD compound +25783 congigure hidlib: remove unused parts of the gtk HID +25758 configure compound DAD widgets, for DAD based spinboxes: remove old, gtk-only coord entry +25701 configure hidlib: generate hidlib.h for external project use +25666 configure hidlib: make gtk2-gl part of the hidlib +25664 configure remove the gtk-only, old library window +25652 configure lib_hid_common: internal conf image for the file selection dialog upgrade +25634 configure infra for an stl export plugin +25603 configure infrastructure for extended objects +25463 configure new library window (DAD based) +25436 configure remove plugin lib_legacy_func +25418 configure remove obsolete menufiles from the install +25402 configure hidlib: rewrite the gtk-only layer selector using generic DAD +25350 configure hidlib: polygon vs. HID API cleanup +25331 configure new, DAD-based search dialog +25261 configure hidlib: various lesstif fixes +25255 configure split the tool API and default menus to hidlib doesn't depend on core +25228 configure rewrite PCB-file-changed-on-disk detection to common code, instead of gtk-specific +25226 configure hidlib: core-independent mouse cursor vs. tool handling +25187 configure hidlib: further split core code to hidlib and non-hidlib to reduce hidlib size +25154 configure hidlib: split lib_hid_common into a PCB-related and a PCB-unrelated plugin +25143 configure hidlib: indirect conf lookups to cut conf_core dependency +25036 configure hidlib: centralize GUI actions to remove code dup among gtk/lesstif and free up HIDs from PCB +25016 configure move the status bar and readouts out from gtk/lesstif to plugin lib_hid_pcbui +24987 configure move the toolbar out from gtk to plugin lib_hid_pcbui +24951 configure remove the lesstif implementation of route style +24944 configure reimplement the gtk-only route style selector and dialog using DAD +24910 configure hidlib: split lib_hid_common into a PCB-related and a PCB-unrelated plugin +24872 configure split excellon exporter from gerber to a separate plugin +24862 configure code simplification: merge hid_flags.[ch] into lib_hid_common +24824 configure move window placement from dialogs to lib_hid_commonfor hidlib cleanup +24816 configure safety wrapper around unlink, opendir, closedir and readdir +24736 configure make distclean fixes to really remove all generated files +24625 configure io_kicad common layer table code among read and write side +24585 configure io_kicad depends on the shape plugin for round-rect pads +24494 configure core shall not use glib for CFLAGS/LDFLAGS as core doesn't depend on glib +24429 configure move paper sizes out from ps to common code (io_kicad needs it too) +24389 configure live scripting: new source files for the new feature +24292 configure preparing for hidlib, splitting source files, scconfig hidlib deps +23902 configure cleanup: remove dead code from gtk +23857 configure new, centralized log dialog +23788 configure lesstif tabbed widget reimplementation for portability +23737 configure new fileselect dialog API and new, centralized load/save actions +23602 configure io_tedax namespace cleanup +23589 configure removing the old netlist dialog leftover from gtk +23585 configure removing the mincut stub (switched over to the event API) +23579 configure removing old netlist +23486 configure gerber/excellon splitup +23462 configure splitting up the dialog plugin code linking into multiple objects for compilation speed +23292 configure rewriting user lead, moving the code from gtk to common +23140 configure netlist rewrite +23099 configure merge copy.[ch] into move.[ch] for compactness +22617 distclean enable the socket plugin in scconfig for detecting select() as an alternative to usleep() +22462 configure lesstif tree table widget code, low level +22305 configure new source files for lesstif color button +22264 configure new source files for tEDAx layer, board and drc save +22167 configure removal of the old gtk-only preferences dialog code +22119 configure dialogs config for window placement +21977 configure new propedit +21972 configure boardflip plugin removed (core functionality took over) +21942 configure io_tedax for new blocks +21876 configure moving out the old drc to a plugin +21580 configure HID API cleanup, including dialogs rewritten with DAD and new DAD features +21289 configure new drc infra and GUI +21098 configure old pinout dialog removal +20317 configure new core color infra +20260 configure plugin frame for ttf import +20249 configure central gettimeofday() wrapper to fix a compilation bug on IRIX +20233 configure new plugin: act_draw +20188 configure dad() action +20152 configure remove notebook helper from gtk for the DAD transition +20061 configure made asm configurable +20030 configure new plugin: asm +19890 configure tree-table widget in DAD core +19656 configure new plugin for c-pcb +19626 configure retired the nelma exporter +19343 configure export_gerber: plugin configuration for G85 slots +19048 configure gtk: command line source cleanup/rename and centralize history handling +18668 configure ddraft: sphash for constraints +18603 configure ddraft: default buildin +18569 configure ddraft: new plugin +18446 configure fp_wget configuration +18380 configure siwtched over to the new about box and export dialog +18304 configure introducing the cam system: rename hid_helper to hid_cam + cam plugin +18166 configure swithc over to scconfig's cquote +17960 configure script plugin +17691 configure action code cleanup +17436 configure renamed hid_actions.[ch] +17426 configure introduce new 3rd party lib dep: fungw +17304 configure new plugin: expfeat for experimental features +17216 configure rendering optimizations: gl inlining +17200 configure moved clip.h out from core +16898 configure new stroke plugin +16616 configure fixes for large boards and 64 bit coords +16591 configure export_xy: tempalte config +16456 configure new plugin: import_ipcd356; rewrite export_ipcd356 +16265 configure introducing pcb api ver +16233 configure retire hid_srv_ws: we are not going to use websockets for the web variant +16155 configure rewrite route style anchored menu to be central +16109 configure split off grid code from crosshair code and move gui-specific part out from core +15944 configure new default menu file preparation: embed the new menu, do not embed the old menus +15910 configure old data model removal +15352 configure typo in LIBDIR_INSTALLED +15104 configure openems mesher code +14724 configure subc hash and compare +13953 configure rtree switchover +13726 configure opnegl code moved to a separate plugin for reuse +13584 configure opengl -lGLU bugfix +13386 configure proper detection of includes for fileno() and usleep() +13364 configure new plugin: extedit +13269 configure remove free_atexit +13171 configure io_eagle: new source file for parsing dru files +13037 configure code simplification: PCB_INLINE +12835 configure new plugin: shape +12748 configure libminuid cflags fix +12708 configure new source file for the 'brave' feature +12673 configure new lib plugin: compat helper (because of the data model rewrite) +12595 configure new source files for padstacks +12401 configure new source files for more generic thermal support +12108 configure tool code splitup +11724 configure new default pcb +11611 configure enforce safe_fs +11529 configure gsch2pcb-rnd uses safe_fs +11436 configure dialogs plugin for moving dialog boxes out from core +11396 configure hid_lesstif linking bug +11265 configure deprecate dbus +11247 configure HPGL importer +11189 configure replace the openscad exporter +11159 configure new source files in hid_gtk2_gl for new HID API +11156 configure new source files in core for safe FS access +11151 configure new source files in dxf_export +11051 make clean new HID API for composite layer drawing +10867 configure loghid resurrect +10799 configure attributes dialog split in gtk +10679 configure infra for new core feature: subcircuit terminal +10672 configure switching over to libuundo +10662 configure split undo code, preparing for a more modular undo +10356 configure move genht out of liblihata +10285 configure control variable name fix in 3 lib plugins +10042 configure generalize lib_netmap and lib_padstack_hash and add lib_polyhelp +9966 configure hyperlynx write +9919 configure rubberband_orig got its own config subtree +9840 configure compile and link libminuid +9600 configure eagle bin parser +9271 configure core cleanup (split select.c and operation.c) +9036 configure diag configuration for integrity checks +9025 configure new source files for eagle subformats +9019 configure new source file in diag for integrity checks +8990 configure new source files for subcircuits +8920 configure build changes in puplug +8912 configure fp_board enabled by default; new plugin for mentor cell footprints +8817 configure fp_board: new plugin +8774 configure layer: all-hid common library plugin for the layer menus +8748 configure core: new pcb_bool source file +8593 configure gtk: new layer selector +8331 configure cquote generates C98-safe long strings +8275 configure puplug +8153 configure enable io_hyp by default +8054 configure setenv() detection for parametric footprint env +7998 configure gtk GTK3 box compatibility +7968 configure clean up global namespace: rename VERSION, PACKAGE and REVISION +7967 configure rename import_hyp to io_hyp +7954 configure fp_wget configuration, edakrill integration +7720 configure new route feature +7594 configure gtk splitup and gl +7509 configure rubber band upgrade, new go code +7439 configure tEDAx chnaged from import to io +7432 configure mentor_sch plugin upgrades +7372 configure gtk splitup +7241 configure gtk parametric footprint handling +7217 configure gtk splitup +7136 configure mentor sch import plugin +7117 configure gtk splitup: DRC dialog +7105 configure font selector gui dependencies +7086 configure gtk splitup +7063 configure gtk dialog for font selection +7055 configure gtk splitup +7050 configure multifont support: merge all draw stubs for simplicity +7042 configure gtk splitup +7022 configure multifont support: new actions +6980 configure gtk splitup: preferences dialog +6924 configure new import plugins +6735 configure gtk splitup +6392 configure draw cross section plugin (gtk and lesstif depend on it) +6365 configure gtk splitup +6111 configure layer vs. layer group code split +6093 distclean,configure hid API extension for the common Cursor action +6087 configure start splitting up hid_gtk: new plugin that hid_gtk depends on: lib_gtk_common +6056 configure gschp2pcb-rnd build deps bug +6007 configure switch over Makefiles to use sccbox +6004 distclean,configure scconfig compiles sccbox thast will ease portable clean and installation rules +5982 make clean gsch2pcb-rnd build fix +5611 configure new feature: UI layer +5487 configure layer cleanup: layer visibility in a new source file +5472 configure draw_fab config subtree +5278 configure prepare for arc UI extension: blank arc_ui.[ch] to move arc UI logics into +5256 configure move rubberband code into a plugin +5199 configure new export plugin: export_stat +5108 configure cleanup: remove old pointer list and use genvt +5019 configure unravel - remove set.[ch] +4616 configure unravel - the big cleanup, moving code +4904 make clean,configure unravel2 - regenerate action registration because regiestrator function name changed +4882 configure unravel2 - the big cleanup, renaming types +4608 configure unravel - the big cleanup, moving code and files +4588 configure disable bison by default +4587 configure draw_fab moved to a plugin +4450 configure io_lihata plugin config and 3rd party lib dependency fix +4398 configure io_kicad plugin interdeps and enable io_kicad by default +4375 configure custom output style support in io_lihata +4321 configure imported lihata persistent save lib in src_3rd as svn extern +4160 configure lib_* plugins (renames, s-expression) +4063 configure netlist.c split and cleanup +4019 configure case sensitive string regex for query +4011 configure sphash available for all plugins (needed by query first) +4002 configure auto-enable the query plugin +3926 configure advanced search in gtk, imported 10 old plugins +3841 configure link string->int hash table (for the query language) +3822 configure new global struct: obj_any_t that will allow a query to list objects +3745 configure gsch2pcb-rnd footprint lib initialization bug fixed +3695 configure bind signals to emergency save so that a copy of the in-memory PCB is saved on most crashes +3513 configure rename detect gcc attribute "unused" and use it for static inline local functions +3510 configure rename the debug plugin to diag plugin to avoid confusion with --debug in ./configure +3509 configure solve non-c89-compliant function pointer <-> data pointer casts +3361 configure cleanup: layer.c is compiled into layer.o now +3339 configure C89: round() is detected by scconfig +3183 distclean,configure C89 switchover +3179 configure C89 correctness: do not depend on hardwired long long, detect it +2985 configure Revcheck installed in Makefiles. +2984 configure Introduction of the config-rev system. Index: tags/2.3.0/scconfig/gen_conf.sh =================================================================== --- tags/2.3.0/scconfig/gen_conf.sh (nonexistent) +++ tags/2.3.0/scconfig/gen_conf.sh (revision 33253) @@ -0,0 +1,206 @@ +#!/bin/sh + +# TODO: rewrite this in C for better portability + +if test -z "$AWK" +then + AWK="awk" +fi + +# Trickery: the name (for path) of the current struct is learned only at +# the end, when the struct is closed because struct type names would be +# global and pollute the namespace while variable names are local. So to +# pick up trailing variable names: +# - each struct gets an integer uid, 0 being the root; structs remember +# their ancestry using PARENT[uid]. +# - each entry is remembered in an SRC[uid, n], where n is between 0 +# and LEN[uid] +# - the output is build in END{} after loading everything into those arrays + + +$AWK -v "docdir=$1" ' + BEGIN { + level = -1 + q = "\"" + cm = "," + uids = 0 + stderr = "/dev/stderr" + } + + function doc_head(fn, path) + { + if (fn in DOCS) + return + DOCS[fn]++ + print "" > fn + print "

pcb-rnd conf tree

" > fn + print "

subtree: " path "

" > fn + print "" > fn + print "
node name type flags description" > fn + + } + + function doc_foot(fn) + { + print "
" > fn + } + + function gen(path, src_line,state_tags, id, name, type, array, desc, flags,path_tmp,type2,fn) + { + name=src_line + sub("^.*CFT_", "RND_CFN_", name) + sub(";.*", "", name) + type=name + sub("[ \t]*[^ \t]*$", "", type) + sub("[^ \t]*[ \t]*", "", name) + array = (name ~ "[[]") + if (array) + sub("[[].*$", "", name) + id = path + sub("^/", "", id) + gsub("/", ".", id) + id = id "." name + + desc = src_line + if (desc ~ "/[*]") { + sub("^.*/[*]", "", desc) + sub("[*]/.*$", "", desc) + sub("^[ \t]*", "", desc) + sub("[ \t]*$", "", desc) + } + else + desc = "" + if (desc == "") + desc = "<" name ">" + + flags = ""; + while(match(desc, "@[a-zA-Z_]+")) { + flag=substr(desc, RSTART, RLENGTH) + sub("[ \t]*" flag "[ \t]*", " ", desc) + sub("^@", "",flag) + flag="RND_CFF_" toupper(flag) + if (flags == "") + flags = flag + else + flags = flags " | " flag + } + if (flags == "") + flags = 0; + sub("^[ \t]*", "", desc) + sub("[ \t]*$", "", desc) + + path_tmp=path + sub("^/", "", path_tmp) + printf("conf_reg(%-36s %s %-16s %-25s %-25s %s, %s)\n", id cm, (array ? "array, " : "scalar,"), type cm, q path_tmp q cm, q name q cm, q desc q, flags) + if (docdir != "") { + path_tmp2 = path_tmp + gsub("/", "_", path_tmp2) + fn = docdir "/" path_tmp2 ".html" + doc_head(fn, path_tmp) + type2 = tolower(type) + sub("^cfn_", "", type2) + + print "
", name, "", type2, "", flags, "", state_tags desc > fn + } + } + + function push_uid() + { + level++ + UID_STACK[level] = uid + } + + function pop_uid() + { + level-- + uid = UID_STACK[level] + } + + function gen_path(uid ,path) { + path = "" + while(LEVEL[uid] > 0) { + path = NAME[uid] "/" path + uid = PARENT[uid] + } + sub("/$", "", path) + return path + } + + # structs on the first level must be const + /struct/ && (level == 0) { + if (!($0 ~ "struct *[a-z_]*temp_s")) { # special case for core/librnd temp storage + tmp=$0 + sub("struct.*$", "", tmp) + if (!(tmp ~ "const")) { + print "First level structs must be const in line", NR > stderr + exit 1 + } + } + } + + /[{]/ { + uid = uids++ + LEN[uid] = 0 + push_uid() + } + + /^[ \t]*[\/][\/]/ { next } + + /CFT_/ { + SRC[uid, LEN[uid]] = $0 + + state_tags = "" + for(st in STATE) + if (STATE[st]) state_tags=state_tags "," st + if (state_tags != "") { + sub("^,", "[", state_tags) + state_tags = state_tags "] " + } + SRC_STATE[uid, LEN[uid]] = state_tags + LEN[uid]++ + } + + /[}]/ { + name = $0 + sub(".*}[ \t]*", "", name) + sub("[ \t{].*", "", name) + sub(";.*", "", name); + + PARENT[uid] = UID_STACK[level-1] + NAME[uid] = name + LEVEL[uid] = level + + pop_uid() + } + + /@conf_gen.sh:/ { + sub(".*@conf_gen.sh: *", "", $0) + sub("[*]/", "", $0) + if ($1 == "begin") + STATE[$2] = 1 + else if ($1 == "end") + STATE[$2] = 0 + else + print "Unknown @conf_gen.sh directive:", $0 > stderr + } + + + END { + if (level != -1) + print "Error: unbalanced braces" > "/dev/stderr" + + if (LEN[0] != 0) { + for(n = 0; n < LEN[0]; n++) + print "gen_conf ERROR: ignoring line \"" SRC[0, n] "\" in root - needs to be within a struct" > stderr + } + + for(uid = 0; uid < uids; uid++) { + path = gen_path(uid) + for(n = 0; n < LEN[uid]; n++) + gen(path, SRC[uid, n], SRC_STATE[uid, n]) + } + + for(fn in DOCS) + doc_foot(fn) + } +' Property changes on: tags/2.3.0/scconfig/gen_conf.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/scconfig/hooks.c =================================================================== --- tags/2.3.0/scconfig/hooks.c (nonexistent) +++ tags/2.3.0/scconfig/hooks.c (revision 33253) @@ -0,0 +1,394 @@ +#include +#include +#include "arg.h" +#include "log.h" +#include "dep.h" +#include "libs.h" +#include "db.h" +#include "tmpasm.h" +#include "tmpasm_scconfig.h" +#include "generator.h" +#include "util/arg_auto_set.h" +#include "Rev.h" + +#define version "2.3.0" + +#define LIBRND_ROOT "../src_3rd/librnd" +#define LIBRND_PLUGIN_ROOT "../src_3rd/librnd/plugins" +#include "../src_3rd/puplug/scconfig_hooks.h" +#include "../src_3rd/libfungw/scconfig_hooks.h" +#include "../src_3rd/libporty_net/hooks_net.c" + +#include "librnd/scconfig/plugin_3state.h" +#include "librnd/scconfig/hooks_common.h" +#include "librnd/scconfig/hooks_gui.c" +#include "librnd/scconfig/rnd_hook_detect.h" + +const arg_auto_set_t disable_libs[] = { /* list of --disable-LIBs and the subtree they affect */ + {"disable-gd", "libs/gui/gd", arg_lib_nodes, "$do not use gd (many exporters need it)"}, + {"disable-gd-gif", "libs/gui/gd/gdImageGif", arg_lib_nodes, "$no gif support in the png rnd_exporter"}, + {"disable-gd-png", "libs/gui/gd/gdImagePng", arg_lib_nodes, "$no png support in the png rnd_exporter"}, + {"disable-gd-jpg", "libs/gui/gd/gdImageJpeg", arg_lib_nodes, "$no jpeg support in the png rnd_exporter"}, + {"enable-bison", "/local/pcb/want_bison", arg_true, "$enable generating language files using bison/flex"}, + {"disable-bison", "/local/pcb/want_bison", arg_false, "$disable generating language files using bison/flex"}, + {"enable-byaccic", "/local/pcb/want_byaccic", arg_true, "$enable generating language files using byaccic/ureglex"}, + {"disable-byaccic", "/local/pcb/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_, hidlib_) plugin3_args(name, desc) +#define plugin_header(sect) +#define plugin_dep(plg, on, hidlib) +#include "plugins.h" + + {NULL, NULL, NULL, NULL} +}; + +static void help1(void) +{ + rnd_help1("pcb-rnd"); + + printf(" --dot_pcb_rnd=path .pcb-rnd config path under $HOME/\n"); +} + +/* Runs when a custom command line argument is found + returns true if no further 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_pcb_rnd") == 0) { + put("/local/pcb/dot_pcb_rnd", value); + 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; +} + +/* Runs after initialization */ +int hook_postinit() +{ + db_mkdir("/local"); + db_mkdir("/local/pcb"); + + rnd_hook_postinit(); + + put("/local/pcb/want_bison", sfalse); + put("/local/pcb/want_byaccic", sfalse); + put("/local/pcb/dot_pcb_rnd", ".pcb-rnd"); + + return 0; +} + +/* Runs after all arguments are read and parsed */ +int hook_postarg() +{ + return rnd_hook_postarg(); +} + + + +/* Runs when things should be detected for the host system */ +int hook_detect_host() +{ + return rnd_hook_detect_host(); +} + + /* figure if we need the dialogs plugin */ +static void calc_dialog_deps(void) +{ + int buildin, plugin; + + rnd_calc_dialog_deps(); /* remove after librnd separation */ + + buildin = istrue(get("/target/librnd/dialogs/buildin")); + plugin = istrue(get("/target/librnd/dialogs/plugin")); + + if (buildin) { + hook_custom_arg("buildin-draw_csect", NULL); + hook_custom_arg("buildin-draw_fontsel", NULL); + hook_custom_arg("buildin-dialogs", NULL); + hook_custom_arg("buildin-lib_hid_pcbui", NULL); + } + else if (plugin) { + if (!plug_is_buildin("draw_csect")) + hook_custom_arg("plugin-draw_csect", NULL); + if (!plug_is_buildin("draw_fontsel")) + hook_custom_arg("plugin-draw_fontsel", NULL); + if (!plug_is_buildin("dialogs")) + hook_custom_arg("plugin-dialogs", NULL); + if (!plug_is_buildin("lib_hid_pcbui")) + hook_custom_arg("plugin-lib_hid_pcbui", NULL); + } +} + +/* Runs when things should be detected for the target system */ +int hook_detect_target() +{ + int want_gd, want_stroke, want_xml2, want_freetype2, want_fuse; + + want_gd = plug_is_enabled("export_png") || plug_is_enabled("import_pxm_gd"); + want_stroke = plug_is_enabled("stroke"); + want_xml2 = plug_is_enabled("io_eagle") || plug_is_enabled("order_pcbway"); + want_freetype2 = plug_is_enabled("import_ttf"); + want_fuse = plug_is_enabled("export_vfs_fuse"); + +/****** TODO #21: core depends on this plugin (yes, this is a bug) ******/ + hook_custom_arg("buildin-lib_compat_help", NULL); + + plugin_db_hidlib(); + + rnd_hook_detect_cc(); + if (rnd_hook_detect_sys() != 0) + return 1; + + if (want_fuse) { + require("libs/sul/fuse/*", 0, 0); + if (!istrue(get("libs/sul/fuse/presents"))) { + report_repeat("WARNING: Since there's no fuse found, disabling export_vfs_fuse plugin...\n"); + hook_custom_arg("disable-export_vfs_fuse", NULL); + } + } + + if (want_stroke) { + require("libs/gui/libstroke/presents", 0, 0); + if (!istrue(get("libs/gui/libstroke/presents"))) { + report_repeat("WARNING: Since there's no libstroke found, disabling the stroke plugin...\n"); + hook_custom_arg("disable-stroke", NULL); + } + } + + if (want_freetype2) { + require("libs/sul/freetype2/presents", 0, 0); + if (!istrue(get("libs/sul/freetype2/presents"))) { + report_repeat("WARNING: Since there's no libfreetype2 found, disabling the import_ttf plugin...\n"); + hook_custom_arg("disable-import_ttf", NULL); + } + } + + rnd_hook_detect_hid(plug_is_enabled("puller")); + + if (want_xml2) { + require("libs/sul/libxml2/presents", 0, 0); + if (!istrue(get("libs/sul/libxml2/presents"))) { + report("libxml2 is not available, disabling io_eagle...\n"); + report_repeat("WARNING: Since there's no libxml2 found, disabling the Eagle IO and pcbway order plugins...\n"); + hook_custom_arg("disable-io_eagle", NULL); + hook_custom_arg("disable-order_pcbway", NULL); + } + put("/local/pcb/want_libxml2", strue); + } + else + put("/local/pcb/want_libxml2", strue); + + calc_dialog_deps(); + + if (want_gd) { + require("libs/gui/gd/presents", 0, 0); + if (!istrue(get("libs/gui/gd/presents"))) { + report_repeat("WARNING: Since there's no libgd, disabling gd based exports and pixmap imports (png, gif, jpeg)...\n"); + hook_custom_arg("disable-gd-gif", NULL); + hook_custom_arg("disable-gd-png", NULL); + hook_custom_arg("disable-gd-jpg", NULL); + hook_custom_arg("disable-export_png", NULL); + hook_custom_arg("disable-import_pxm_gd", NULL); + want_gd = 0; + goto disable_gd_formats; + } + else { + require("libs/gui/gd/gdImagePng/presents", 0, 0); + require("libs/gui/gd/gdImageGif/presents", 0, 0); + require("libs/gui/gd/gdImageJpeg/presents", 0, 0); + require("libs/gui/gd/gdImageSetResolution/presents", 0, 0); + if (!istrue(get("libs/gui/gd/gdImagePng/presents"))) { + report_repeat("WARNING: libgd is installed, but its png code fails, some exporters will be compiled with reduced functionality\n"); + } + } + } + else { + put("libs/gui/gd/presents", sfalse); + disable_gd_formats:; + put("libs/gui/gd/gdImagePng/presents", sfalse); + put("libs/gui/gd/gdImageGif/presents", sfalse); + put("libs/gui/gd/gdImageJpeg/presents", sfalse); + } + + /* yacc/lex - are we able to regenerate languages? */ + if (istrue(get("/local/pcb/want_bison"))) { + require("parsgen/flex/*", 0, 0); + require("parsgen/bison/*", 0, 0); + if (!istrue(get("parsgen/flex/presents")) || !istrue(get("parsgen/bison/presents"))) + put("/local/pcb/want_parsgen", sfalse); + else + put("/local/pcb/want_parsgen", strue); + } + else { + report("Bison/flex are disabled, among with parser generation.\n"); + put("/local/pcb/want_parsgen", sfalse); + } + + /* byaccic - are we able to regenerate languages? */ + if (istrue(get("/local/pcb/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/pcb/want_parsgen_byaccic", sfalse); + else + put("/local/pcb/want_parsgen_byaccic", strue); + } + else { + report("byaccic/ureglex are disabled, among with parser generation.\n"); + put("/local/pcb/want_parsgen_byaccic", sfalse); + } + + libporty_net_detect_target(); + + /* plugin dependencies */ + plugin_deps(1); + + rnd_hook_detect_coord_bits(); /* remove this after the librnd split */ + + /* restore the original CFLAGS, without the effects of --debug, so Makefiles can decide when to use what cflag (c99 needs different ones) */ + /* this should be removed after the librnd split */ + put("/target/cc/cflags", get("/local/cc_flags_save")); + + return 0; +} + +#ifdef GENCALL +/* If enabled, generator implements ###call *### and generator_callback is + the callback function that will be executed upon ###call### */ +void generator_callback(char *cmd, char *args) +{ + printf("* generator_callback: '%s' '%s'\n", cmd, args); +} +#endif + +/* Runs after detection hooks, should generate the output (Makefiles, etc.) */ +int hook_generate() +{ + char *next, *rev = "non-svn", *curr, *tmp, *sep; + int generr = 0; + int res = 0; + char apiver[32], version_major[32]; + long r = 0; + int v1, v2, v3; + + tmp = svn_info(0, "../src", "Revision:"); + if (tmp != NULL) { + r = strtol(tmp, NULL, 10); + rev = str_concat("", "svn r", tmp, NULL); + free(tmp); + } + strcpy(apiver, version); + curr = apiver; next = strchr(curr, '.'); *next = '\n'; + v1 = atoi(curr); + curr = next+1; next = strchr(curr, '.'); *next = '\n'; + v2 = atoi(curr); + v3 = atoi(next+1); + sprintf(apiver, "%01d%01d%02d%05ld", v1, v2, v3, r); + + strcpy(version_major, version); + sep = strchr(version_major, '.'); + if (sep != NULL) + *sep = '\0'; + + logprintf(0, "scconfig generate version info: version='%s' rev='%s'\n", version, rev); + put("/local/revision", rev); + put("/local/version", version); + put("/local/version_major", version_major); + put("/local/apiver", apiver); + put("/local/pup/sccbox", "../../scconfig/sccbox"); + + printf("\n"); + + printf("Generating Makefile.conf (%d)\n", generr |= tmpasm("..", "Makefile.conf.in", "Makefile.conf")); + + printf("Generating src/Makefile (%d)\n", generr |= tmpasm("../src", "Makefile.in", "Makefile")); + + generr |= rnd_hook_generate(); + + printf("Generating util/gsch2pcb-rnd/Makefile (%d)\n", generr |= tmpasm("../util", "gsch2pcb-rnd/Makefile.in", "gsch2pcb-rnd/Makefile")); + printf("Generating util/bxl2txt/Makefile (%d)\n", generr |= tmpasm("../util", "bxl2txt/Makefile.in", "bxl2txt/Makefile")); + printf("Generating src_3rd/libporty_net/os_includes.h (%d)\n", generr |= generate("../src_3rd/libporty_net/os_includes.h.in", "../src_3rd/libporty_net/os_includes.h")); + printf("Generating src_3rd/libporty_net/pnet_config.h (%d)\n", generr |= generate("../src_3rd/libporty_net/pnet_config.h.in", "../src_3rd/libporty_net/pnet_config.h")); + printf("Generating src_3rd/libporty_net/phost_types.h (%d)\n", generr |= generate("../src_3rd/libporty_net/phost_types.h.in", "../src_3rd/libporty_net/phost_types.h")); + + printf("Generating pcb-rnd config.h (%d)\n", generr |= tmpasm("..", "config.h.in", "config.h")); + + if (plug_is_enabled("export_vfs_fuse")) + printf("Generating fuse_includes.h (%d)\n", generr |= tmpasm("../src_plugins/export_vfs_fuse", "fuse_includes.h.in", "fuse_includes.h")); + + generr |= pup_hook_generate("../src_3rd/puplug"); + + if (!istrue(get("libs/script/fungw/presents"))) + generr |= fungw_hook_generate("../src_3rd/libfungw"); + + + if (!generr) { + printf("\n\n"); + printf("=====================\n"); + printf("Configuration summary\n"); + printf("=====================\n"); + + print_sum_setting("/local/pcb/want_parsgen", "Regenerating languages with bison & flex"); + print_sum_setting("/local/pcb/debug", "Compilation for debugging"); + print_sum_setting_or("/local/pcb/symbols", "Include debug symbols", istrue(get("/local/pcb/debug"))); + print_sum_cfg_val("/local/pcb/coord_bits", "Coordinate type bits"); + print_sum_cfg_val("/local/pcb/dot_pcb_rnd", ".pcb_rnd config dir under $HOME"); + +#undef plugin_def +#undef plugin_header +#undef plugin_dep +#define plugin_def(name, desc, default_, all_, hidlib_) plugin3_stat(name, desc) +#define plugin_header(sect) printf(sect); +#define plugin_dep(plg, on, hidlib) +#include "plugins.h" + + if (repeat != NULL) { + printf("\n%s\n", repeat); + } + + if (all_plugin_check_explicit()) { + printf("\nNevertheless the configuration is complete, if you accept these differences\nyou can go on compiling.\n\n"); + res = 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, "Error generating some of the files\n"); + res = 1; + } + + return res; +} + +/* Runs before everything is uninitialized */ +void hook_preuninit() +{ +} + +/* Runs at the very end, when everything is already uninitialized */ +void hook_postuninit() +{ +} + Index: tags/2.3.0/scconfig/menucfg.c =================================================================== --- tags/2.3.0/scconfig/menucfg.c (nonexistent) +++ tags/2.3.0/scconfig/menucfg.c (revision 33253) @@ -0,0 +1,69 @@ +#include +#include +#include "default/hooks.h" +#include "default/libs.h" +#include "default/main_custom_args.h" +#include "default/main_lib.h" +#include "menulib/scmenu.h" +#include "util/arg_auto_set.h" +#include "util/arg_auto_menu.h" + + +void re_fail(char *s, char c) +{ + fprintf(stderr, "Regex error: %s [opcode %o]\n", s, c); + abort(); +} + +int cb_configure(scm_ctx_t *ctx, scm_menu_t *menu, scm_win_t *w, int selection) +{ + printf("configure!!\n"); + sleep(1); + return -1; +} + + + +scm_menu_entry_t me_hid_gtk[8] = {{SCM_TERMINATOR, NULL, NULL, NULL, NULL, NULL, 0}}; +scm_menu_entry_t me_hid_lesstif[8] = {{SCM_TERMINATOR, NULL, NULL, NULL, NULL, NULL, 0}}; +scm_menu_entry_t me_export[8] = {{SCM_TERMINATOR, NULL, NULL, NULL, NULL, NULL, 0}}; +scm_menu_entry_t me_autorouter[8] = {{SCM_TERMINATOR, NULL, NULL, NULL, NULL, NULL, 0}}; +scm_menu_entry_t me_all_settings[32] = {{SCM_TERMINATOR, NULL, NULL, NULL, NULL, NULL, 0}}; + +scm_menu_entry_t me_settings[] = { + {SCM_SUBMENU, NULL, "HID: gtk", "gtk settings -->", NULL, me_hid_gtk, SCM_AUTO_RUN}, + {SCM_SUBMENU, NULL, "HID: lesstif", "lesstif settings -->", NULL, me_hid_lesstif, SCM_AUTO_RUN}, + {SCM_SUBMENU, NULL, "HID: exporters", "export format settings -->", NULL, me_export, SCM_AUTO_RUN}, + {SCM_SUBMENU, NULL, "auto routers", "autorouter settings -->", NULL, me_autorouter, SCM_AUTO_RUN}, + {SCM_EMPTY, NULL, NULL, NULL, NULL, 0}, + {SCM_SUBMENU, NULL, "all", "all settings at once -->", NULL, me_all_settings, SCM_AUTO_RUN}, + {SCM_TERMINATOR, NULL, NULL, NULL, NULL, NULL, 0} +}; + +scm_menu_entry_t me_main[] = { + {SCM_SUBMENU, NULL, "Edit settings", "Edit user configurable settings -->", NULL, me_settings, SCM_AUTO_RUN}, + {SCM_SUBMENU, NULL, "Manual detection", "Run detection of individual libs -->", NULL, NULL, SCM_AUTO_RUN}, + {SCM_SUBMENU_CB, NULL, "Configure pcb-rnd", "Run the configuration process -->", NULL, cb_configure, SCM_AUTO_RUN}, + {SCM_EMPTY, NULL, NULL, NULL, NULL, 0}, + {SCM_KEY_VALUE, NULL, "Exit & save", "Exit with saving the settings", NULL, NULL, SCM_AUTO_RUN}, + {SCM_KEY_VALUE, NULL, "Exit", "Exit without saving the settings", NULL, NULL, SCM_AUTO_RUN}, + {SCM_TERMINATOR, NULL, NULL, NULL, NULL, NULL, 0} +}; + +extern const arg_auto_set_t disable_libs[] ; + +int main() +{ + scm_ctx_t ctx; + + main_init(); + + append_settings_auto_set(me_export, 32, disable_libs, "-gd", NULL, "^disable-", SCM_SUBMENU, 0); + + scm_init(&ctx); + scm_menu_autowin(&ctx, "main menu", me_main); + + main_uninit(); + + return 0; +} Index: tags/2.3.0/scconfig/plugins.h =================================================================== --- tags/2.3.0/scconfig/plugins.h (nonexistent) +++ tags/2.3.0/scconfig/plugins.h (revision 33253) @@ -0,0 +1,206 @@ +/****************************************************************************** + Auto-generated by trunk/src_plugins/map_plugins.sh - do NOT edit, + run make map_plugins in trunk/src/ - to change any of the data below, + edit trunk/src_plugins/PLUGIN/PLUGIN.pup +******************************************************************************/ + +plugin_header("\nLibrary plugins:\n") +plugin_def("lib_compat_help", "#compatibility helper functions", sbuildin, 1, 0) +plugin_def("lib_formula", "mathematical forumlas", sbuildin, 1, 0) +plugin_def("lib_gensexpr", "#s-expression library", sdisable, 0, 1) +plugin_def("lib_gtk_common", "all-hid_gtk common code", sdisable, 0, 1) +plugin_def("lib_hid_common", "all-gui-hid common code", sdisable, 0, 1) +plugin_def("lib_hid_gl", "openGL rendering", sdisable, 0, 1) +plugin_def("lib_hid_pcbui", "common PCB-related GUI elements", sdisable, 0, 0) +plugin_def("lib_netmap", "map nets and objects", sdisable, 0, 0) +plugin_def("lib_polyhelp", "polygon helpers", sbuildin, 1, 0) +plugin_def("lib_portynet", "#IPv4 tcp", sbuildin, 1, 1) +plugin_def("lib_vfs", "fetch data for VFS export", sdisable, 0, 0) +plugin_def("lib_wget", "wget(1) wrapper", sdisable, 0, 1) + +plugin_header("\nFeature plugins:\n") +plugin_def("acompnet", "net auto-completion", sdisable, 1, 0) +plugin_def("act_draw", "action wrappers for drawing", sbuildin, 1, 0) +plugin_def("act_read", "action wrappers for data access", sbuildin, 1, 0) +plugin_def("ar_cpcb", "autoroute with c-pcb", sbuildin, 1, 0) +plugin_def("ar_extern", "external autorouter", sbuildin, 1, 0) +plugin_def("asm", "assembly GUI", sbuildin, 1, 0) +plugin_def("autocrop", "crop board to fit objects", sbuildin, 1, 0) +plugin_def("autoplace", "auto place components", sbuildin, 1, 0) +plugin_def("autoroute", "the original autorouter", sbuildin, 1, 0) +plugin_def("ch_editpoint", "crosshair: on-point highlight", sbuildin, 1, 0) +plugin_def("ch_onpoint", "crosshair: on-point highlight", sbuildin, 1, 0) +plugin_def("diag", "diagnostic acts. for devs", sdisable, 1, 0) +plugin_def("dialogs", "HID-independent GUI dialogs", sdisable, 1, 0) +plugin_def("distalign", "distribute and align objs", sbuildin, 1, 0) +plugin_def("djopt", "djopt board optimization", sbuildin, 1, 0) +plugin_def("draw_csect", "draw cross-section (layers)", sdisable, 1, 0) +plugin_def("draw_fab", "fab layer in some exports", sbuildin, 1, 0) +plugin_def("draw_fontsel", "font selection GUI", sdisable, 1, 0) +plugin_def("drc_query", "query() based DRC", sbuildin, 1, 0) +plugin_def("expfeat", "experimental features", sdisable, 1, 0) +plugin_def("extedit", "edit with external program", sbuildin, 1, 0) +plugin_def("exto_std", "standard extended objects", sbuildin, 1, 0) +plugin_def("fontmode", "font editor", sbuildin, 1, 0) +plugin_def("irc", "on-line support (IRC)", sbuildin, 1, 1) +plugin_def("jostle", "push lines out of the way", sbuildin, 1, 0) +plugin_def("loghid", "diagnostics: log HID calls", sdisable, 1, 1) +plugin_def("millpath", "calculate toolpath for milling", sdisable, 1, 0) +plugin_def("mincut", "minimal cut shorts", sbuildin, 1, 0) +plugin_def("oldactions", "old/obsolete actions", sdisable, 1, 0) +plugin_def("order_pcbway", "board ordering from PCBWay", sdisable, 1, 0) +plugin_def("order", "online board ordering", sdisable, 1, 0) +plugin_def("polycombine", "combine selected polygons", sbuildin, 1, 0) +plugin_def("polystitch", "stitch polygon at cursor", sbuildin, 1, 0) +plugin_def("propedit", "object property editor", sbuildin, 1, 0) +plugin_def("puller", "puller", sbuildin, 1, 0) +plugin_def("query", "query language", sbuildin, 1, 0) +plugin_def("renumber", "renumber action", sbuildin, 1, 0) +plugin_def("report", "report actions", sbuildin, 1, 0) +plugin_def("rubberband_orig", "the original rubberband", sbuildin, 1, 0) +plugin_def("script", "fungw turing complete scripting", sbuildin, 1, 0) +plugin_def("serpentine", "Serpentine creation", sdisable, 0, 0) +plugin_def("shand_cmd", "command shorthands", sbuildin, 1, 0) +plugin_def("shape", "generate regular shapes", sbuildin, 1, 0) +plugin_def("sketch_route", "assisted semi-auto-routing", sdisable, 0, 0) +plugin_def("smartdisperse", "netlist based dispenser", sbuildin, 1, 0) +plugin_def("stroke", "mouse gestures", sbuildin, 1, 1) +plugin_def("teardrops", "draw teardrops on pins", sbuildin, 1, 0) +plugin_def("tool_std", "standard tools", sbuildin, 1, 0) +plugin_def("vendordrill", "vendor drill mapping", sbuildin, 1, 0) + +plugin_header("\nFootprint backends:\n") +plugin_def("fp_board", "footprint library from boards", sbuildin, 1, 0) +plugin_def("fp_fs", "filesystem footprints", sbuildin, 1, 0) +plugin_def("fp_wget", "web footprints", sbuildin, 1, 0) + +plugin_header("\nImport plugins:\n") +plugin_def("import_accel_net", "import Accel netlist", sbuildin, 1, 0) +plugin_def("import_calay", "import calay .net", sbuildin, 1, 0) +plugin_def("import_dsn", "specctra .dsn importer", sbuildin, 1, 0) +plugin_def("import_edif", "import edif", sbuildin, 1, 0) +plugin_def("import_fpcb_nl", "import freepcb netlist", sbuildin, 1, 0) +plugin_def("import_gnetlist", "sch import: run gnetlist", sbuildin, 1, 0) +plugin_def("import_hpgl", "import HP-GL plot files", sbuildin, 1, 0) +plugin_def("import_ipcd356", "import IPC-D-356 Netlist", sbuildin, 1, 0) +plugin_def("import_ltspice", "import ltspice .net+.asc", sbuildin, 1, 0) +plugin_def("import_mentor_sch","import mentor graphics sch", sbuildin, 1, 0) +plugin_def("import_mucs", "import mucs routing", sbuildin, 1, 0) +plugin_def("import_net_action","import net: action script", sbuildin, 1, 0) +plugin_def("import_net_cmd", "sch/net import: run custom cmd", sbuildin, 1, 0) +plugin_def("import_netlist", "import netlist", sbuildin, 1, 0) +plugin_def("import_orcad_net", "import Orcad netlist", sbuildin, 1, 0) +plugin_def("import_pads_net", "import PADS ascii netlist .asc", sbuildin, 1, 0) +plugin_def("import_protel_net","import Protel netlist 2.0", sbuildin, 1, 0) +plugin_def("import_pxm_gd", "import pixmaps from png/gif/jpg", sbuildin, 1, 0) +plugin_def("import_pxm_pnm", "import pixmaps from pnm ", sbuildin, 1, 0) +plugin_def("import_sch2", "import sch v2", sbuildin, 1, 0) +plugin_def("import_tinycad", "import tinycad .net", sbuildin, 1, 0) +plugin_def("import_ttf", "import ttf glyphs", sbuildin, 1, 0) + +plugin_header("\nExport plugins:\n") +plugin_def("cam", "cam/job based export", sbuildin, 1, 0) +plugin_def("ddraft", "2D drafting helper", sbuildin, 1, 0) +plugin_def("export_bom", "bom pcb_exporter", sbuildin, 1, 0) +plugin_def("export_dsn", "specctra .dsn pcb_exporter", sbuildin, 1, 0) +plugin_def("export_dxf", "DXF pcb_exporter", sbuildin, 1, 0) +plugin_def("export_excellon", "Excellon drill exporter", sbuildin, 1, 0) +plugin_def("export_fidocadj", "FidoCadJ .fcd pcb_exporter", sbuildin, 1, 0) +plugin_def("export_gcode", "gcode pcb_exporter", sbuildin, 1, 0) +plugin_def("export_gerber", "Gerber pcb_exporter", sbuildin, 1, 0) +plugin_def("export_ipcd356", "IPC-D-356 Netlist pcb_exporter", sbuildin, 1, 0) +plugin_def("export_lpr", "lpr pcb_exporter (printer)", sbuildin, 1, 0) +plugin_def("export_oldconn", "old connection data format", sbuildin, 1, 0) +plugin_def("export_openems", "openems exporter", sbuildin, 1, 0) +plugin_def("export_openscad", "openscad pcb_exporter", sbuildin, 1, 0) +plugin_def("export_png", "png/gif/jpg pcb_exporter", sbuildin, 1, 0) +plugin_def("export_ps", "postscript pcb_exporter", sbuildin, 1, 0) +plugin_def("export_stat", "export board statistics", sbuildin, 1, 0) +plugin_def("export_stl", "3d export: STL", sbuildin, 1, 0) +plugin_def("export_svg", "SVG pcb_exporter", sbuildin, 1, 0) +plugin_def("export_vfs_fuse", "FUSE VFS server", sdisable, 1, 0) +plugin_def("export_vfs_mc", "GNU mc VFS server", sdisable, 1, 0) +plugin_def("export_xy", "xy (centroid) pcb_exporter", sbuildin, 1, 0) + +plugin_header("\nIO plugins (file formats):\n") +plugin_def("io_autotrax", "autotrax (freeware PCB CAD)", sbuildin, 1, 0) +plugin_def("io_bxl", "BXL footprint", sbuildin, 1, 0) +plugin_def("io_dsn", "specctra .dsn", sdisable, 1, 0) +plugin_def("io_eagle", "Eagle's xml and binary formats", sbuildin, 1, 0) +plugin_def("io_hyp", "hyperlynx .hyp loader", sbuildin, 1, 0) +plugin_def("io_kicad_legacy", "Kicad's legacy format", sbuildin, 1, 0) +plugin_def("io_kicad", "Kicad's s-expr format", sbuildin, 1, 0) +plugin_def("io_lihata", "lihata board format", sbuildin, 1, 0) +plugin_def("io_mentor_cell", "Mentor Graphics cell footprints", sdisable, 1, 0) +plugin_def("io_pcb", "the original pcb format", sbuildin, 1, 0) +plugin_def("io_tedax", "tEDAx (Trivial EDA eXchange)", sbuildin, 1, 0) + +plugin_header("\nHID plugins:\n") +plugin_def("hid_batch", "batch process (no-gui HID)", sbuildin, 1, 1) +plugin_def("hid_gtk2_gdk", "GTK2 GUI, software render", sbuildin, 1, 1) +plugin_def("hid_gtk2_gl", "GTK2 GUI, opengl render", sbuildin, 1, 1) +plugin_def("hid_lesstif", "the lesstif gui", sbuildin, 1, 1) +plugin_def("hid_remote", "remote HID server", sdisable, 0, 1) + + +plugin_dep("ar_cpcb", "lib_compat_help", 0) +plugin_dep("ar_cpcb", "lib_gensexpr", 0) +plugin_dep("ar_cpcb", "lib_netmap", 0) +plugin_dep("ar_extern", "io_tedax", 0) +plugin_dep("autoroute", "lib_compat_help", 0) +plugin_dep("cam", "query", 0) +plugin_dep("dialogs", "draw_csect", 0) +plugin_dep("dialogs", "draw_fontsel", 0) +plugin_dep("dialogs", "lib_hid_common", 0) +plugin_dep("dialogs", "lib_hid_pcbui", 0) +plugin_dep("draw_fab", "report", 0) +plugin_dep("drc_query", "query", 0) +plugin_dep("export_fidocadj", "lib_compat_help", 0) +plugin_dep("export_gcode", "millpath", 0) +plugin_dep("export_gerber", "export_excellon", 0) +plugin_dep("export_ipcd356", "lib_compat_help", 0) +plugin_dep("export_lpr", "export_ps", 0) +plugin_dep("export_openems", "lib_polyhelp", 0) +plugin_dep("export_openscad", "lib_polyhelp", 0) +plugin_dep("export_ps", "lib_compat_help", 0) +plugin_dep("export_vfs_fuse", "lib_vfs", 0) +plugin_dep("export_vfs_mc", "lib_vfs", 0) +plugin_dep("export_xy", "export_bom", 0) +plugin_dep("extedit", "io_lihata", 0) +plugin_dep("exto_std", "lib_compat_help", 0) +plugin_dep("fp_wget", "fp_fs", 0) +plugin_dep("fp_wget", "lib_wget", 0) +plugin_dep("hid_gtk2_gdk", "lib_gtk_common", 01) +plugin_dep("hid_gtk2_gl", "lib_gtk_common", 01) +plugin_dep("hid_gtk2_gl", "lib_hid_gl", 01) +plugin_dep("hid_lesstif", "lib_hid_common", 01) +plugin_dep("import_accel_net", "lib_gensexpr", 0) +plugin_dep("import_dsn", "lib_compat_help", 0) +plugin_dep("import_dsn", "lib_gensexpr", 0) +plugin_dep("import_ipcd356", "lib_compat_help", 0) +plugin_dep("import_mentor_sch", "lib_gensexpr", 0) +plugin_dep("import_mucs", "lib_compat_help", 0) +plugin_dep("import_orcad_net", "lib_gensexpr", 0) +plugin_dep("io_autotrax", "lib_polyhelp", 0) +plugin_dep("io_dsn", "lib_gensexpr", 0) +plugin_dep("io_dsn", "lib_netmap", 0) +plugin_dep("io_eagle", "lib_compat_help", 0) +plugin_dep("io_eagle", "shape", 0) +plugin_dep("io_hyp", "lib_netmap", 0) +plugin_dep("io_kicad", "lib_compat_help", 0) +plugin_dep("io_kicad", "lib_gensexpr", 0) +plugin_dep("io_kicad", "shape", 0) +plugin_dep("io_kicad_legacy", "io_kicad", 0) +plugin_dep("io_lihata", "lib_compat_help", 0) +plugin_dep("io_pcb", "lib_compat_help", 0) +plugin_dep("io_tedax", "lib_compat_help", 0) +plugin_dep("io_tedax", "lib_netmap", 0) +plugin_dep("irc", "lib_portynet", 01) +plugin_dep("lib_gtk_common", "lib_hid_common", 01) +plugin_dep("lib_hid_pcbui", "lib_hid_common", 0) +plugin_dep("lib_vfs", "propedit", 0) +plugin_dep("millpath", "lib_polyhelp", 0) +plugin_dep("order_pcbway", "lib_wget", 0) +plugin_dep("order_pcbway", "order", 0) +plugin_dep("query", "lib_formula", 0) +plugin_dep("report", "query", 0) Index: tags/2.3.0/scconfig/revtest.c =================================================================== --- tags/2.3.0/scconfig/revtest.c (nonexistent) +++ tags/2.3.0/scconfig/revtest.c (revision 33253) @@ -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/2.3.0/scconfig =================================================================== --- tags/2.3.0/scconfig (nonexistent) +++ tags/2.3.0/scconfig (revision 33253) Property changes on: tags/2.3.0/scconfig ___________________________________________________________________ Added: svn:externals ## -0,0 +1 ## +svn://svn.repo.hu/scconfig/trunk/src@1671 src Index: tags/2.3.0/src/Makefile.dep =================================================================== --- tags/2.3.0/src/Makefile.dep (nonexistent) +++ tags/2.3.0/src/Makefile.dep (revision 33253) @@ -0,0 +1,12187 @@ +### Generated file, do not edit, run make dep ### + +../src_3rd/librnd/core/actions.o: ../src_3rd/librnd/core/actions.c \ + ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/libfungw/fungw_conv.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/funchash.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/safe_fs.h +../src_3rd/librnd/core/base64.o: ../src_3rd/librnd/core/base64.c \ + ../src_3rd/librnd/core/base64.h +../src_3rd/librnd/core/box.o: ../src_3rd/librnd/core/box.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/rotate.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h +../src_3rd/librnd/core/color.o: ../src_3rd/librnd/core/color.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +../src_3rd/librnd/core/compat_fs.o: ../src_3rd/librnd/core/compat_fs.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/compat_inc.h \ + ../src_3rd/librnd/core/compat_fs.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h +../src_3rd/librnd/core/compat_lrealpath.o: \ + ../src_3rd/librnd/core/compat_lrealpath.c ../src_3rd/librnd/core/compat_inc.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/compat_lrealpath.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_3rd/librnd/core/compat_misc.o: \ + ../src_3rd/librnd/core/compat_misc.c ../src_3rd/librnd/core/compat_inc.h \ + ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_3rd/librnd/core/conf.o: ../src_3rd/librnd/core/conf.c \ + ../src_3rd/genht/htsi.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/liblihata/tree.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/paths.h \ + ../src_3rd/librnd/core/compat_fs.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/file_loaded.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/fptr_cast.h \ + ../src_3rd/genvector/genvector_impl.c \ + ../src_3rd/librnd/core/conf_regfile.c +../src_3rd/librnd/core/conf_act.o: ../src_3rd/librnd/core/conf_act.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/funchash_core.h ../src_3rd/librnd/core/funchash.h \ + ../src_3rd/librnd/core/funchash_core_list.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/grid.h ../src_3rd/librnd/core/compat_misc.h +../src_3rd/librnd/core/conf_hid.o: ../src_3rd/librnd/core/conf_hid.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/genht/hash.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/color.h +../src_3rd/librnd/core/error.o: ../src_3rd/librnd/core/error.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hidlib_conf.h +../src_3rd/librnd/core/event.o: ../src_3rd/librnd/core/event.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/fptr_cast.h +../src_3rd/librnd/core/file_loaded.o: \ + ../src_3rd/librnd/core/file_loaded.c ../src_3rd/librnd/config.h \ + ../src_3rd/genht/hash.h ../src_3rd/librnd/core/file_loaded.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_3rd/librnd/core/fptr_cast.o: ../src_3rd/librnd/core/fptr_cast.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/fptr_cast.h +../src_3rd/librnd/core/funchash.o: ../src_3rd/librnd/core/funchash.c \ + ../src_3rd/genht/htpi.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/funchash.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/funchash_core.h \ + ../src_3rd/librnd/core/funchash_core_list.h +../src_3rd/librnd/core/grid.o: ../src_3rd/librnd/core/grid.c \ + ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/grid.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/misc_util.h +../src_3rd/librnd/core/gui_act.o: ../src_3rd/librnd/core/gui_act.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/librnd/core/grid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h +../src_3rd/librnd/core/heap.o: ../src_3rd/librnd/core/heap.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/heap.h +../src_3rd/librnd/core/hid.o: ../src_3rd/librnd/core/hid.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h +../src_3rd/librnd/core/hid_attrib.o: ../src_3rd/librnd/core/hid_attrib.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_3rd/librnd/core/hid_cfg.o: ../src_3rd/librnd/core/hid_cfg.c \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/tree.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hidlib.h +../src_3rd/librnd/core/hid_cfg_action.o: \ + ../src_3rd/librnd/core/hid_cfg_action.c ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/hid_cfg_action.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/liblihata/tree.h +../src_3rd/librnd/core/hid_cfg_input.o: \ + ../src_3rd/librnd/core/hid_cfg_input.c ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/tree.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/genht/ht_utils.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/hid_cfg_action.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h +../src_3rd/librnd/core/hid_dad.o: ../src_3rd/librnd/core/hid_dad.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h +../src_3rd/librnd/core/hid_dad_spin.o: \ + ../src_3rd/librnd/core/hid_dad_spin.c ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_unit.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h +../src_3rd/librnd/core/hid_dad_tree.o: \ + ../src_3rd/librnd/core/hid_dad_tree.c ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/hid_dad_tree.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/genht/hash.h +../src_3rd/librnd/core/hid_dad_unit.o: \ + ../src_3rd/librnd/core/hid_dad_unit.c ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_unit.h +../src_3rd/librnd/core/hid_dlg.o: ../src_3rd/librnd/core/hid_dlg.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/hid_nogui.h +../src_3rd/librnd/core/hid_init.o: ../src_3rd/librnd/core/hid_init.c \ + ../src_3rd/librnd/config.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/hid_dad_unit.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/compat_inc.h \ + ../src_3rd/librnd/core/compat_fs.h ../src_3rd/librnd/core/file_loaded.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/grid.h \ + ../src_3rd/librnd/core/funchash.h ../src_3rd/librnd/core/hid_menu.h +../src_3rd/librnd/core/hid_menu.o: ../src_3rd/librnd/core/hid_menu.c \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/tree.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/global_typedefs.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/file_loaded.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/paths.h \ + ../src_3rd/librnd/core/funchash_core.h ../src_3rd/librnd/core/funchash.h \ + ../src_3rd/librnd/core/funchash_core_list.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h +../src_3rd/librnd/core/hid_nogui.o: ../src_3rd/librnd/core/hid_nogui.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h +../src_3rd/librnd/core/hidlib.o: ../src_3rd/librnd/core/hidlib.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h +../src_3rd/librnd/core/hidlib_conf.o: \ + ../src_3rd/librnd/core/hidlib_conf.c ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/hidlib_conf_fields.h +../src_3rd/librnd/core/list_conf.o: ../src_3rd/librnd/core/list_conf.c \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.c +../src_3rd/librnd/core/main_act.o: ../src_3rd/librnd/core/main_act.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/file_loaded.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h +../src_3rd/librnd/core/misc_util.o: ../src_3rd/librnd/core/misc_util.c \ + ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h +../src_3rd/librnd/core/paths.o: ../src_3rd/librnd/core/paths.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/paths.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h +../src_3rd/librnd/core/pixmap.o: ../src_3rd/librnd/core/pixmap.c \ + ../src_3rd/librnd/config.h ../src_3rd/genht/hash.h ../src_3rd/librnd/core/pixmap.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h +../src_3rd/librnd/core/plugins.o: ../src_3rd/librnd/core/plugins.c \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h +../src_3rd/librnd/core/rnd_bool.o: ../src_3rd/librnd/core/rnd_bool.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/rnd_bool.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_3rd/librnd/core/rnd_printf.o: ../src_3rd/librnd/core/rnd_printf.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h +../src_3rd/librnd/core/safe_fs.o: ../src_3rd/librnd/core/safe_fs.c \ + ../src_3rd/librnd/core/compat_inc.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/compat_fs.h \ + ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/paths.h \ + ../src_3rd/librnd/core/hidlib.h +../src_3rd/librnd/core/tool.o: ../src_3rd/librnd/core/tool.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/tool.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/compat_misc.h +../src_3rd/librnd/core/unit.o: ../src_3rd/librnd/core/unit.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h +../src_3rd/librnd/core/vtc0.o: ../src_3rd/librnd/core/vtc0.c \ + ../src_3rd/librnd/core/vtc0.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +../src_3rd/librnd/poly/offset.o: ../src_3rd/librnd/poly/offset.c \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/polyarea.h ../src_3rd/librnd/poly/self_isc.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/poly/offset.h +../src_3rd/librnd/poly/polyarea.o: ../src_3rd/librnd/poly/polyarea.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/heap.h \ + ../src_3rd/librnd/core/compat_cc.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/poly/polyarea.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/poly/rtree2_compat.h +../src_3rd/librnd/poly/polygon1_gen.o: \ + ../src_3rd/librnd/poly/polygon1_gen.c ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/poly/polyarea.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/poly/polygon1_gen.h +../src_3rd/librnd/poly/rtree.o: ../src_3rd/librnd/poly/rtree.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ../src_3rd/genrtree/genrtree_impl.h \ + ../src_3rd/genrtree/genrtree_search.h \ + ../src_3rd/genrtree/genrtree_delete.h \ + ../src_3rd/genrtree/genrtree_debug.h \ + ../src_3rd/librnd/poly/rtree2_compat.h +../src_3rd/librnd/poly/self_isc.o: ../src_3rd/librnd/poly/self_isc.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/polyarea.h ../src_3rd/librnd/poly/self_isc.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h +../src_3rd/librnd/plugins/hid_batch/batch.o: \ + ../src_3rd/librnd/plugins/hid_batch/batch.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h +../src_3rd/librnd/plugins/hid_gtk2_gdk/gtkhid-gdk.o: \ + ../src_3rd/librnd/plugins/hid_gtk2_gdk/gtkhid-gdk.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/grid.h ../src_3rd/librnd/core/color_cache.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/hash.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/pixmap.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/coord_conv.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/lib_gtk_config.h \ + ../src_3rd/librnd/plugins/lib_hid_common/clip.h +../src_3rd/librnd/plugins/hid_gtk2_gdk/gtkhid-main.o: \ + ../src_3rd/librnd/plugins/hid_gtk2_gdk/gtkhid-main.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_hid.h +../src_3rd/librnd/plugins/hid_gtk2_gl/gtkhid-gl.o: \ + ../src_3rd/librnd/plugins/hid_gtk2_gl/gtkhid-gl.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/color_cache.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/pixmap.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/plugins/lib_hid_common/clip.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/lib_gtk_config.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/coord_conv.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h \ + ../src_3rd/librnd/plugins/lib_hid_gl/opengl.h \ + ../src_3rd/librnd/plugins/lib_hid_gl/draw_gl.h \ + ../src_3rd/librnd/plugins/lib_hid_gl/opengl.h \ + ../src_3rd/librnd/plugins/lib_hid_gl/hidgl.h \ + ../src_3rd/librnd/plugins/lib_hid_gl/stencil_gl.h +../src_3rd/librnd/plugins/hid_gtk2_gl/gtkhid-main.o: \ + ../src_3rd/librnd/plugins/hid_gtk2_gl/gtkhid-main.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/plugins/lib_hid_gl/draw_gl.h \ + ../src_3rd/librnd/plugins/lib_hid_gl/opengl.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_hid.h +../src_3rd/librnd/plugins/hid_lesstif/FillBox.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/FillBox.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/hid_lesstif/FillBoxP.h \ + ../src_3rd/librnd/plugins/hid_lesstif/FillBox.h \ + ../src_3rd/librnd/plugins/hid_lesstif/pxm_helper.h +../src_3rd/librnd/plugins/hid_lesstif/Pages.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/Pages.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/hid_lesstif/PagesP.h \ + ../src_3rd/librnd/plugins/hid_lesstif/Pages.h \ + ../src_3rd/librnd/plugins/hid_lesstif/pxm_helper.h +../src_3rd/librnd/plugins/hid_lesstif/dialogs.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/dialogs.c \ + ../src_3rd/librnd/plugins/hid_lesstif/xincludes.h ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/plugins/hid_lesstif/FillBox.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/plugins/hid_lesstif/lesstif.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h \ + ../src_3rd/librnd/plugins/hid_lesstif/ltf_stdarg.h \ + ../src_3rd/librnd/plugins/hid_lesstif/dlg_attr_misc.c \ + ../src_3rd/librnd/plugins/hid_lesstif/wt_xpm.h \ + ../src_3rd/librnd/plugins/hid_lesstif/wt_colorbtn.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dad_markup.h \ + ../src_3rd/librnd/plugins/hid_lesstif/wt_preview.h \ + ../src_3rd/librnd/plugins/hid_lesstif/dlg_attr_box.c \ + ../src_3rd/librnd/plugins/hid_lesstif/Pages.h \ + ../src_3rd/librnd/plugins/hid_lesstif/dlg_attr_tree.c \ + ../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_widget.h \ + ../src_3rd/librnd/core/hid_dad_tree.h ../src_3rd/genht/hash.h +../src_3rd/librnd/plugins/hid_lesstif/dlg_fileselect.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/dlg_fileselect.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/hid_lesstif/xincludes.h \ + ../src_3rd/librnd/plugins/hid_lesstif/lesstif.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/plugins/hid_lesstif/ltf_stdarg.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/hid_lesstif/dlg_fileselect.h +../src_3rd/librnd/plugins/hid_lesstif/ltf_stdarg.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/ltf_stdarg.c \ + ../src_3rd/librnd/plugins/hid_lesstif/ltf_stdarg.h \ + ../src_3rd/librnd/plugins/hid_lesstif/xincludes.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/rnd_bool.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h +../src_3rd/librnd/plugins/hid_lesstif/main.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/main.c \ + ../src_3rd/librnd/plugins/hid_lesstif/xincludes.h ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/pixmap.h \ + ../src_3rd/librnd/core/color_cache.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/hash.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/hid_lesstif/lesstif.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h \ + ../src_3rd/librnd/plugins/hid_lesstif/ltf_stdarg.h \ + ../src_3rd/librnd/core/grid.h ../src_3rd/librnd/core/tool.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/plugins/hid_lesstif/wt_preview.h \ + ../src_3rd/librnd/plugins/hid_lesstif/dlg_fileselect.h \ + ../src_3rd/librnd/plugins/hid_lesstif/FillBox.h \ + ../src_3rd/librnd/plugins/lib_hid_common/lib_hid_common.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dialogs_conf.h \ + ../src_3rd/librnd/plugins/lib_hid_common/clip.h \ + ../src_3rd/librnd/plugins/lib_hid_common/cli_history.h \ + ../src_3rd/librnd/plugins/hid_lesstif/mouse.c \ + ../src_3rd/genvector/genvector_impl.c \ + ../src_3rd/librnd/plugins/hid_lesstif/wt_preview.c +../src_3rd/librnd/plugins/hid_lesstif/menu.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/menu.c \ + ../src_3rd/librnd/plugins/hid_lesstif/xincludes.h ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/hid_cfg_action.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/hid_lesstif/lesstif.h \ + ../src_3rd/librnd/core/paths.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h \ + ../src_3rd/librnd/plugins/hid_lesstif/ltf_stdarg.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/genht/hash.h \ + ../src_3rd/librnd/plugins/lib_hid_common/menu_helper.h +../src_3rd/librnd/plugins/hid_lesstif/wt_colorbtn.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/wt_colorbtn.c \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h +../src_3rd/librnd/plugins/hid_lesstif/wt_xpm.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/wt_xpm.c \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/plugins/hid_lesstif/wt_xpm.h +../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_pixmaps.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_pixmaps.c \ + ../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_priv.h \ + ../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_widget.h \ + ../src_3rd/genlist/gendlist.h +../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_priv.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_priv.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_priv.h \ + ../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_widget.h \ + ../src_3rd/genlist/gendlist.h +../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_widget.o: \ + ../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_widget.c ../config.h \ + ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_priv.h \ + ../src_3rd/librnd/plugins/hid_lesstif/xm_tree_table_widget.h \ + ../src_3rd/genlist/gendlist.h +../src_3rd/librnd/plugins/hid_remote/proto.o: \ + ../src_3rd/librnd/plugins/hid_remote/proto.c \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/rnd_bool.h \ + ../src_3rd/librnd/plugins/hid_remote/proto_lowcommon.h \ + ../src_3rd/librnd/plugins/hid_remote/proto_lowsend.h \ + ../src_3rd/librnd/core/base64.h \ + ../src_3rd/librnd/plugins/hid_remote/proto_lowparse.h +../src_3rd/librnd/plugins/hid_remote/remote.o: \ + ../src_3rd/librnd/plugins/hid_remote/remote.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/hid_remote/proto.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/genvector/vtp0.h +../src_3rd/librnd/plugins/irc/irc.o: ../src_3rd/librnd/plugins/irc/irc.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/libuirc/libuirc.h ../src_3rd/libporty_net/libportytcp4.h \ + ../src_3rd/libporty_net/os_includes.h \ + ../src_3rd/libporty_net/pnet_config.h \ + ../src_3rd/libporty_net/phost_types.h +../src_3rd/librnd/plugins/lib_gensexpr/lib_gensexpr.o: \ + ../src_3rd/librnd/plugins/lib_gensexpr/lib_gensexpr.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h +../src_3rd/librnd/plugins/lib_gtk_common/bu_command.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/core/rnd_bool.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ + ../src_3rd/librnd/plugins/lib_hid_common/cli_history.h +../src_3rd/librnd/plugins/lib_gtk_common/bu_dwg_tooltip.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_dwg_tooltip.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_dwg_tooltip.h +../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/liblihata/tree.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg_action.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_keyboard.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_hid_common/menu_helper.h +../src_3rd/librnd/plugins/lib_gtk_common/dlg_attribute.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_attribute.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_attribute.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hid_dad_tree.h \ + ../src_3rd/genht/hash.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_attr_tree.c \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_attr_misc.c \ + ../src_3rd/librnd/plugins/lib_gtk_common/wt_preview.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dad_markup.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_attr_txt.c \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_attr_box.c +../src_3rd/librnd/plugins/lib_gtk_common/dlg_fileselect.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_fileselect.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_attribute.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h +../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/genht/hash.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_attribute.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/util_listener.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_keyboard.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/lib_gtk_config.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h +../src_3rd/librnd/plugins/lib_gtk_common/glue_common.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/pixmap.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_keyboard.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/wt_preview.h +../src_3rd/librnd/plugins/lib_gtk_common/glue_hid.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_hid.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/lib_gtk_common/glue_hid.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_3rd/librnd/core/pixmap.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/coord_conv.h \ + ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_keyboard.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_dwg_tooltip.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_crosshair.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_fileselect.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_attribute.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/util_listener.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/util_timer.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/util_watch.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/lib_gtk_config.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h \ + ../src_3rd/librnd/plugins/lib_hid_common/lib_hid_common.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dialogs_conf.h \ + ../src_3rd/librnd/plugins/lib_hid_common/menu_helper.h +../src_3rd/librnd/plugins/lib_gtk_common/in_keyboard.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_keyboard.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/lib_gtk_common/in_keyboard.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h +../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/tool.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/genvector/genvector_impl.c \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_keyboard.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h +../src_3rd/librnd/plugins/lib_gtk_common/lib_gtk_common.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/lib_gtk_common.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/lib_gtk_config.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h +../src_3rd/librnd/plugins/lib_gtk_common/lib_gtk_config.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/lib_gtk_config.c ../config.h \ + ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/lib_gtk_config.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/hid_gtk_conf.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/plugins/lib_hid_common/place.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/hid_gtk_conf_fields.h +../src_3rd/librnd/plugins/lib_gtk_common/ui_crosshair.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_crosshair.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/lib_gtk_common/ui_crosshair.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/core/rnd_bool.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/global_typedefs.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/hid_gtk_conf.h +../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/core/rnd_bool.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/global_typedefs.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h +../src_3rd/librnd/plugins/lib_gtk_common/util_listener.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/util_listener.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/util_listener.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h +../src_3rd/librnd/plugins/lib_gtk_common/util_timer.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/util_timer.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/lib_gtk_common/util_timer.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h +../src_3rd/librnd/plugins/lib_gtk_common/util_watch.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/util_watch.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/lib_gtk_common/util_watch.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/glue_common.h +../src_3rd/librnd/plugins/lib_gtk_common/wt_preview.o: \ + ../src_3rd/librnd/plugins/lib_gtk_common/wt_preview.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_mouse.h \ + ../src_3rd/librnd/core/hid_cfg_input.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/pcb_gtk.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/compat.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_menu.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/bu_command.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/dlg_topwin.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/in_keyboard.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/ui_zoompan.h \ + ../src_3rd/librnd/plugins/lib_gtk_common/wt_preview.h \ + ../src_3rd/librnd/core/globalconst.h +../src_3rd/librnd/plugins/lib_hid_common/act_dad.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/act_dad.c ../src_3rd/librnd/config.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_tree.h \ + ../src_3rd/librnd/plugins/lib_hid_common/act_dad.h +../src_3rd/librnd/plugins/lib_hid_common/cli_history.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/cli_history.c ../src_3rd/librnd/config.h \ + ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_hid_common/cli_history.h \ + ../src_3rd/librnd/plugins/lib_hid_common/lib_hid_common.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dialogs_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/paths.h +../src_3rd/librnd/plugins/lib_hid_common/dlg_comm_m.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/dlg_comm_m.c ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_hid_common/xpm.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dlg_comm_m.h \ + ../src_3rd/librnd/plugins/lib_hid_common/lib_hid_common.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dialogs_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h +../src_3rd/librnd/plugins/lib_hid_common/dlg_log.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/dlg_log.c ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dlg_log.h +../src_3rd/librnd/plugins/lib_hid_common/grid_menu.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/grid_menu.c ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/grid.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/plugins/lib_hid_common/grid_menu.h +../src_3rd/librnd/plugins/lib_hid_common/lead_user.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/lead_user.c ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h +../src_3rd/librnd/plugins/lib_hid_common/lib_hid_common.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/lib_hid_common.c \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/conf_hid.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/plugins/lib_hid_common/grid_menu.h \ + ../src_3rd/librnd/plugins/lib_hid_common/cli_history.h \ + ../src_3rd/librnd/plugins/lib_hid_common/lead_user.h \ + ../src_3rd/librnd/plugins/lib_hid_common/place.h \ + ../src_3rd/librnd/plugins/lib_hid_common/lib_hid_common.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dialogs_conf.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dlg_comm_m.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dlg_log.h \ + ../src_3rd/librnd/plugins/lib_hid_common/act_dad.h \ + ../src_3rd/librnd/plugins/lib_hid_common/zoompan.h \ + ../src_3rd/librnd/plugins/lib_hid_common/conf_internal.c \ + ../src_3rd/librnd/plugins/lib_hid_common/dialogs_conf_fields.h +../src_3rd/librnd/plugins/lib_hid_common/menu_helper.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/menu_helper.c ../src_3rd/librnd/config.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/tree.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/plugins/lib_hid_common/menu_helper.h +../src_3rd/librnd/plugins/lib_hid_common/place.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/place.c ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dialogs_conf.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/ht.c \ + ../src_3rd/genht/ht_inlines.h ../src_3rd/genht/hash.h +../src_3rd/librnd/plugins/lib_hid_common/toolbar.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/toolbar.c ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vti0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/tree.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/plugins/lib_hid_common/toolbar.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h +../src_3rd/librnd/plugins/lib_hid_common/xpm.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/xpm.c ../config.h \ + ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/plugins/lib_hid_common/xpm/question.xpm \ + ../src_3rd/librnd/plugins/lib_hid_common/xpm/warning.xpm +../src_3rd/librnd/plugins/lib_hid_common/zoompan.o: \ + ../src_3rd/librnd/plugins/lib_hid_common/zoompan.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_hid_common/zoompan.h +../src_3rd/librnd/plugins/lib_hid_gl/hidgl.o: \ + ../src_3rd/librnd/plugins/lib_hid_gl/hidgl.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/grid.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/plugins/lib_hid_gl/hidgl.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/plugins/lib_hid_gl/draw_gl.c \ + ../src_3rd/librnd/plugins/lib_hid_gl/stencil_gl.h \ + ../src_3rd/librnd/plugins/lib_hid_gl/opengl.h +../src_3rd/librnd/plugins/lib_hid_gl/lib_hid_gl.o: \ + ../src_3rd/librnd/plugins/lib_hid_gl/lib_hid_gl.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h +../src_3rd/librnd/plugins/lib_hid_gl/stencil_gl.o: \ + ../src_3rd/librnd/plugins/lib_hid_gl/stencil_gl.c \ + ../src_3rd/librnd/plugins/lib_hid_gl/stencil_gl.h \ + ../src_3rd/librnd/plugins/lib_hid_gl/opengl.h +../src_3rd/librnd/plugins/lib_portynet/lib_portynet.o: \ + ../src_3rd/librnd/plugins/lib_portynet/lib_portynet.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h +../src_3rd/librnd/plugins/lib_wget/lib_wget.o: \ + ../src_3rd/librnd/plugins/lib_wget/lib_wget.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/plugins/lib_wget/lib_wget.h +../src_3rd/librnd/plugins/loghid/hid-logger.o: \ + ../src_3rd/librnd/plugins/loghid/hid-logger.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/plugins/loghid/hid-logger.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/color.h +../src_3rd/librnd/plugins/loghid/loghid.o: \ + ../src_3rd/librnd/plugins/loghid/loghid.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/plugins/loghid/hid-logger.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hid_nogui.h +../src_3rd/librnd/plugins/stroke/stroke.o: \ + ../src_3rd/librnd/plugins/stroke/stroke.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/tool.h \ + ../src_3rd/librnd/plugins/stroke/conf_internal.c \ + ../src_3rd/librnd/plugins/stroke/stroke_conf.h \ + ../src_3rd/librnd/plugins/stroke/stroke_conf_fields.h +../src_plugins/acompnet/acompnet.o: ../src_plugins/acompnet/acompnet.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h layer.h layer_ui.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h search.h polygon.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + conf_core.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_plugins/acompnet/meshgraph.h +../src_plugins/acompnet/meshgraph.o: ../src_plugins/acompnet/meshgraph.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/hash.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + route.h buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/acompnet/meshgraph.h layer.h route.h +../src_plugins/act_draw/act_draw.o: ../src_plugins/act_draw/act_draw.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h board.h \ + vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/compat_misc.h flag_str.h obj_arc.h obj_line.h \ + obj_pstk.h obj_pstk_shape.h polygon.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h vtpadstack_t.h obj_text.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + obj_text_draw.h draw.h obj_line_draw.h \ + ../src_plugins/act_draw/keywords_sphash.h \ + ../src_plugins/act_draw/act_pstk_proto.c obj_pstk_inlines.h data.h \ + crosshair.h route.h buffer.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h ht_subc.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + vtpadstack.h thermal.h operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_plugins/act_draw/act_polybool.c search.h obj_poly.h data_list.h +../src_plugins/act_draw/keywords_sphash.o: \ + ../src_plugins/act_draw/keywords_sphash.c +../src_plugins/act_read/act_read.o: ../src_plugins/act_read/act_read.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data_parent.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h crosshair.h route.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h idpath.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_plugins/act_read/keywords_sphash.h \ + ../src_plugins/act_read/act_idpath.c ../src_plugins/act_read/act_geo.c \ + search.h find.h ../src_3rd/genvector/vtp0.h \ + ../src_plugins/act_read/act_layer.c data.h crosshair.h buffer.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h ht_subc.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h layer.h \ + actions_pcb.h +../src_plugins/act_read/keywords_sphash.o: \ + ../src_plugins/act_read/keywords_sphash.c +../src_plugins/ar_cpcb/ar_cpcb.o: ../src_plugins/ar_cpcb/ar_cpcb.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/gensexpr/gsxl.h \ + ../src_3rd/gensexpr/gensexpr_impl.h ../src_3rd/gensexpr/gsx_parse.h \ + ../src_3rd/genht/htpi.h ../src_3rd/genht/ht.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + conf_core.h obj_pstk_inlines.h data.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h \ + ../src_plugins/lib_netmap/netmap.h netlist.h +../src_plugins/ar_extern/ar_extern.o: \ + ../src_plugins/ar_extern/ar_extern.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h conf_core.h obj_pstk_inlines.h data.h \ + thermal.h operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h \ + ../src_plugins/lib_netmap/netmap.h netlist.h \ + ../src_plugins/ar_extern/ar_extern_conf.h \ + ../src_plugins/ar_extern/conf_internal.c \ + ../src_plugins/ar_extern/menu_internal.c \ + ../src_plugins/ar_extern/e_route-rnd.c \ + ../src_plugins/ar_extern/dlg_extroute.c ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_plugins/ar_extern/ar_extern_conf_fields.h +../src_plugins/asm/asm.o: ../src_plugins/asm/asm.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genlist/gendlist.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/compat_misc.h \ + obj_subc.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_tree.h ../src_3rd/librnd/core/hid_menu.h \ + search.h draw.h select.h operation.h ../src_plugins/asm/asm_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_plugins/asm/conf_internal.c \ + ../src_plugins/asm/menu_internal.c ../src_plugins/asm/asm_conf_fields.h +../src_plugins/autocrop/autocrop.o: ../src_plugins/autocrop/autocrop.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h +../src_plugins/autoplace/action.o: ../src_plugins/autoplace/action.c \ + ../config.h ../src_3rd/librnd/config.h ../src_plugins/autoplace/autoplace.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h board.h \ + vtroutestyle.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/event.h +../src_plugins/autoplace/autoplace.o: \ + ../src_plugins/autoplace/autoplace.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_plugins/autoplace/autoplace.h \ + ../src_3rd/librnd/core/compat_misc.h box_dir.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h layer.h intersect.h move.h netlist.h \ + remove.h operation.h rotate.h ../src_3rd/librnd/core/rotate.h obj_rat.h \ + obj_term.h obj_pstk_inlines.h data.h thermal.h \ + ../src_3rd/librnd/poly/polygon1_gen.h data_it.h +../src_plugins/autoroute/action.o: ../src_plugins/autoroute/action.c \ + ../config.h ../src_3rd/librnd/config.h ../src_plugins/autoroute/autoroute.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/event.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h +../src_plugins/autoroute/autoroute.o: \ + ../src_plugins/autoroute/autoroute.c ../config.h ../src_3rd/librnd/config.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + data.h layer.h attrib.h global_typedefs.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/autoroute/autoroute.h board.h vtroutestyle.h rats_patch.h \ + board.h draw.h box_dir.h find.h ../src_3rd/librnd/core/heap.h netlist.h \ + ../src_plugins/autoroute/mtspace.h ../src_plugins/autoroute/vector.h \ + polygon.h remove.h operation.h obj_pinvia_therm.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h layer.h obj_line_draw.h draw.h \ + obj_pstk_draw.h obj_pstk_inlines.h data.h thermal.h \ + ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h +../src_plugins/autoroute/mtspace.o: ../src_plugins/autoroute/mtspace.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/heap.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + box_dir.h ../src_plugins/autoroute/mtspace.h \ + ../src_plugins/autoroute/vector.h ../src_3rd/librnd/poly/rtree2_compat.h +../src_plugins/autoroute/vector.o: ../src_plugins/autoroute/vector.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/math_helper.h \ + ../src_plugins/autoroute/vector.h +../src_plugins/cam/cam.o: ../src_plugins/cam/cam.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h hid_cam.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_plugins/cam/cam_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_plugins/cam/conf_internal.c ../src_plugins/cam/cam_compile.c \ + data.h crosshair.h route.h buffer.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/cam/cam_compile.h layer_vis.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/genvector/genvector_impl.c \ + ../src_plugins/cam/cam_gui.c ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_tree.h \ + ../src_plugins/cam/cam_conf_fields.h +../src_plugins/ch_editpoint/ch_editpoint.o: \ + ../src_plugins/ch_editpoint/ch_editpoint.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h conf_core.h crosshair.h route.h data.h \ + crosshair.h buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h event.h \ + ../src_3rd/librnd/core/event.h obj_pstk.h polygon.h search.h \ + tool_logic.h ../src_plugins/ch_editpoint/ch_editpoint_conf.h \ + ../src_plugins/ch_editpoint/conf_internal.c \ + ../src_plugins/ch_editpoint/menu_internal.c \ + ../src_plugins/ch_editpoint/ch_editpoint_conf_fields.h +../src_plugins/ch_onpoint/ch_onpoint.o: \ + ../src_plugins/ch_onpoint/ch_onpoint.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + tool_logic.h board.h vtroutestyle.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h conf_core.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + data.h crosshair.h buffer.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h ht_subc.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h event.h \ + ../src_3rd/librnd/core/event.h obj_arc.h obj_arc_draw.h draw.h \ + obj_line_draw.h +../src_plugins/ddraft/centgeo.o: ../src_plugins/ddraft/centgeo.c \ + ../config.h ../src_3rd/librnd/config.h ../src_plugins/ddraft/centgeo.h obj_line.h \ + ../src_3rd/genlist/gendlist.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h obj_arc.h \ + ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/compat_misc.h search.h layer.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h +../src_plugins/ddraft/ddraft.o: ../src_plugins/ddraft/ddraft.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/error.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h search.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h attrib.h \ + global_typedefs.h obj_common.h flag.h data_parent.h obj_arc_list.h \ + obj_arc.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h \ + ../src_plugins/ddraft/centgeo.h obj_line.h board.h vtroutestyle.h \ + layer_grp.h rats_patch.h board.h data_it.h data.h crosshair.h route.h \ + buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_plugins/ddraft/fields_sphash.h draw_wireframe.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/conf_hid.h ../src_3rd/librnd/core/vtc0.h \ + ../src_plugins/ddraft/trim.c undo_old.h \ + ../src_plugins/ddraft/constraint.c crosshair.h \ + ../src_3rd/librnd/core/tool.h ../src_plugins/ddraft/constraint_gui.c \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_plugins/ddraft/cli.c \ + ../src_3rd/librnd/core/hid_inlines.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_plugins/ddraft/cli_line.c +../src_plugins/ddraft/fields_sphash.o: \ + ../src_plugins/ddraft/fields_sphash.c +../src_plugins/diag/diag.o: ../src_plugins/diag/diag.c ../config.h \ + ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h data_it.h data.h flag_str.h layer.h \ + ../src_plugins/diag/diag_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/event.h \ + ../src_plugins/diag/integrity.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h search.h plug_footprint.h \ + vtlibrary.h plug_io.h ../src_3rd/genvector/vts0.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h conf_core.h \ + find.h ../src_plugins/diag/diag_conf_fields.h +../src_plugins/diag/diag_conf.o: ../src_plugins/diag/diag_conf.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h +../src_plugins/diag/integrity.o: ../src_plugins/diag/integrity.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h +../src_plugins/dialogs/dialogs.o: ../src_plugins/dialogs/dialogs.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dialogs_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_plugins/dialogs/dlg_test.c board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h obj_text.h \ + ../src_3rd/librnd/core/hid_dad_tree.h ../src_3rd/genht/hash.h \ + ../src_plugins/dialogs/dlg_about.h ../src_plugins/dialogs/dlg_export.h \ + ../src_plugins/dialogs/dlg_flag_edit.h \ + ../src_plugins/dialogs/dlg_fontsel.h \ + ../src_plugins/dialogs/dlg_infobar.h \ + ../src_plugins/dialogs/dlg_layer_binding.h \ + ../src_plugins/dialogs/dlg_layer_flags.h \ + ../src_plugins/dialogs/dlg_lib_pstk.h \ + ../src_plugins/dialogs/dlg_library.h \ + ../src_plugins/dialogs/dlg_loadsave.h \ + ../src_plugins/dialogs/dlg_padstack.h obj_pstk.h obj_pstk_shape.h \ + polygon.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h vtpadstack_t.h \ + ../src_plugins/dialogs/dlg_pinout.c build_run.h obj_subc_parent.h data.h \ + crosshair.h route.h buffer.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h ht_subc.h \ + ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h vtpadstack.h draw.h \ + obj_term.h search.h search_r.h netlist.h \ + ../src_plugins/dialogs/dlg_undo.c ../src_3rd/libuundo/uundo.h event.h \ + ../src_3rd/librnd/core/event.h undo.h undo_old.h \ + ../src_plugins/dialogs/dlg_fpmap.c actions_pcb.h plug_footprint.h \ + vtlibrary.h plug_io.h ../src_3rd/genvector/vts0.h \ + ../src_plugins/dialogs/dlg_obj_list.c \ + ../src_plugins/dialogs/dlg_netlist.c \ + ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_plugins/dialogs/dlg_plugins.c \ + ../src_plugins/dialogs/dlg_printcalib.c \ + ../src_3rd/librnd/core/hid_init.h ../src_plugins/dialogs/dlg_view.h \ + ../src_plugins/dialogs/dlg_pref.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_plugins/dialogs/dlg_pref_sizes.h \ + ../src_plugins/dialogs/dlg_pref_board.h \ + ../src_plugins/dialogs/dlg_pref_general.h \ + ../src_plugins/dialogs/dlg_pref_lib.h \ + ../src_plugins/dialogs/dlg_pref_color.h \ + ../src_plugins/dialogs/dlg_pref_win.h \ + ../src_plugins/dialogs/dlg_pref_key.h \ + ../src_plugins/dialogs/dlg_pref_menu.h \ + ../src_plugins/dialogs/dlg_pref_conf.h +../src_plugins/dialogs/dlg_about.o: ../src_plugins/dialogs/dlg_about.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h build_run.h ../src_3rd/librnd/core/file_loaded.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_plugins/dialogs/dlg_about.h +../src_plugins/dialogs/dlg_export.o: ../src_plugins/dialogs/dlg_export.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h route.h buffer.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h layer_vis.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_unit.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_plugins/dialogs/dlg_export.h +../src_plugins/dialogs/dlg_flag_edit.o: \ + ../src_plugins/dialogs/dlg_flag_edit.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h flag_str.h flag.h change.h board.h \ + vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h ../src_3rd/librnd/core/hidlib.h \ + undo.h ../src_3rd/libuundo/uundo.h undo_old.h search.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_plugins/dialogs/dlg_flag_edit.h +../src_plugins/dialogs/dlg_fontsel.o: \ + ../src_plugins/dialogs/dlg_fontsel.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h change.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h stub_draw.h draw.h idpath.h \ + search.h ../src_plugins/dialogs/dlg_fontsel.h +../src_plugins/dialogs/dlg_infobar.o: \ + ../src_plugins/dialogs/dlg_infobar.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/plugins/lib_hid_common/xpm.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dlg_comm_m.h plug_io.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h +../src_plugins/dialogs/dlg_layer_binding.o: \ + ../src_plugins/dialogs/dlg_layer_binding.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h route.h buffer.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/event.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_dad_spin.h \ + funchash_core.h ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + obj_subc.h search.h ../src_plugins/dialogs/dlg_layer_binding.h +../src_plugins/dialogs/dlg_layer_flags.o: \ + ../src_plugins/dialogs/dlg_layer_flags.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_plugins/dialogs/dlg_layer_binding.h \ + ../src_plugins/dialogs/dlg_layer_flags.h +../src_plugins/dialogs/dlg_lib_pstk.o: \ + ../src_plugins/dialogs/dlg_lib_pstk.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h layer.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h crosshair.h ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h obj_subc.h vtpadstack.h \ + ../src_3rd/librnd/core/hid_inlines.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_tree.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h obj_pstk.h obj_pstk_inlines.h board.h \ + vtroutestyle.h rats_patch.h data.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h obj_text_draw.h draw.h \ + obj_pstk_draw.h undo_old.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h select.h search.h \ + ../src_plugins/dialogs/dlg_padstack.h \ + ../src_plugins/dialogs/dlg_lib_pstk.h +../src_plugins/dialogs/dlg_library.o: \ + ../src_plugins/dialogs/dlg_library.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htsi.h \ + ../src_3rd/genht/hash.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genregex/regex_sei.h \ + ../src_3rd/genregex/regex_templ.h ../src_3rd/genregex/regex.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h buffer.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h data.h \ + crosshair.h route.h buffer.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + obj_pstk_list.h obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h draw.h event.h ../src_3rd/librnd/core/event.h obj_subc.h \ + plug_footprint.h vtlibrary.h data.h ../src_3rd/librnd/core/tool.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_tree.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_plugins/dialogs/dlg_library.h \ + ../src_plugins/dialogs/dlg_library_param.c \ + ../src_3rd/librnd/core/safe_fs.h +../src_plugins/dialogs/dlg_loadsave.o: \ + ../src_plugins/dialogs/dlg_loadsave.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + route.h buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h \ + obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/compat_fs.h \ + conf_core.h ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/hidlib_conf.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dialogs_conf.h \ + ../src_plugins/dialogs/dlg_loadsave.h +../src_plugins/dialogs/dlg_padstack.o: \ + ../src_plugins/dialogs/dlg_padstack.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h obj_pstk.h \ + obj_common.h flag.h globalconst.h ../src_3rd/librnd/core/globalconst.h \ + attrib.h global_typedefs.h data_parent.h layer.h obj_arc_list.h \ + obj_arc.h obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h obj_pstk_shape.h \ + polygon.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h vtpadstack_t.h obj_pstk_op.h \ + operation.h obj_pstk_inlines.h board.h vtroutestyle.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h route.h \ + buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + thermal.h ../src_3rd/librnd/poly/polygon1_gen.h obj_subc_parent.h \ + search.h operation.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_plugins/dialogs/dlg_lib_pstk.h \ + ../src_plugins/dialogs/dlg_padstack.h +../src_plugins/dialogs/dlg_pref.o: ../src_plugins/dialogs/dlg_pref.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h build_run.h ../src_3rd/librnd/core/rnd_printf.h \ + event.h ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_tree.h ../src_3rd/genht/hash.h \ + ../src_plugins/dialogs/dlg_pref.h \ + ../src_plugins/dialogs/dlg_pref_sizes.h \ + ../src_plugins/dialogs/dlg_pref_board.h \ + ../src_plugins/dialogs/dlg_pref_general.h \ + ../src_plugins/dialogs/dlg_pref_lib.h \ + ../src_plugins/dialogs/dlg_pref_color.h \ + ../src_plugins/dialogs/dlg_pref_win.h \ + ../src_plugins/dialogs/dlg_pref_key.h \ + ../src_plugins/dialogs/dlg_pref_menu.h \ + ../src_plugins/dialogs/dlg_pref_conf.h \ + ../src_plugins/dialogs/dlg_pref_sizes.c board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h conf_core.h drc.h view.h idpath.h \ + ../src_plugins/dialogs/dlg_pref_board.c \ + ../src_plugins/dialogs/dlg_pref_general.c \ + ../src_plugins/dialogs/dlg_pref_lib.c ../src_3rd/liblihata/tree.h \ + ../src_3rd/librnd/core/paths.h ../src_plugins/dialogs/dlg_pref_layer.c \ + stub_draw.h draw.h ../src_plugins/dialogs/dlg_pref_color.c \ + ../src_plugins/dialogs/dlg_pref_win.c \ + ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/plugins/lib_hid_common/dialogs_conf.h \ + ../src_plugins/dialogs/dlg_pref_key.c \ + ../src_3rd/librnd/core/hid_cfg_input.h \ + ../src_plugins/dialogs/dlg_pref_menu.c ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_plugins/dialogs/dlg_pref_conf.c \ + ../src_plugins/dialogs/dlg_pref_confedit.c \ + ../src_3rd/librnd/core/hid_dad_unit.h +../src_plugins/dialogs/dlg_view.o: ../src_plugins/dialogs/dlg_view.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/hidlib_conf.h \ + view.h idpath.h draw.h drc.h view.h actions_pcb.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hid_inlines.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_tree.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h ../src_3rd/librnd/core/safe_fs.h +../src_plugins/distalign/distalign.o: \ + ../src_plugins/distalign/distalign.c board.h ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h data_it.h data.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h move.h draw.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_plugins/djopt/djopt.o: ../src_plugins/djopt/djopt.c ../config.h \ + ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + remove.h operation.h move.h draw.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h flag_str.h find.h layer.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_plugins/djopt/djopt_conf.h \ + obj_line.h ../src_3rd/librnd/core/event.h obj_pstk_inlines.h data.h \ + thermal.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_plugins/djopt/djopt_conf_fields.h +../src_plugins/draw_csect/draw_csect.o: \ + ../src_plugins/draw_csect/draw_csect.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h stub_draw.h draw.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h event.h \ + ../src_3rd/librnd/core/event.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h layer_vis.h conf_core.h obj_text_draw.h obj_line_draw.h +../src_plugins/draw_fab/draw_fab.o: ../src_plugins/draw_fab/draw_fab.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h build_run.h \ + ../src_3rd/librnd/core/compat_misc.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h \ + ../src_plugins/draw_fab/../report/drill.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h stub_draw.h draw.h \ + ../src_plugins/draw_fab/draw_fab_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h conf_core.h \ + ../src_3rd/librnd/core/hidlib_conf.h obj_pstk_inlines.h data.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_3rd/librnd/core/hid_inlines.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h obj_text_draw.h \ + ../src_plugins/draw_fab/draw_fab_conf_fields.h +../src_plugins/draw_fontsel/draw_fontsel.o: \ + ../src_plugins/draw_fontsel/draw_fontsel.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h build_run.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h font.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h stub_draw.h draw.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/librnd/core/compat_misc.h \ + conf_core.h ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h obj_text.h obj_text_draw.h \ + obj_line_draw.h +../src_plugins/drc_query/drc_query.o: \ + ../src_plugins/drc_query/drc_query.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genht/hash.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/liblihata/tree.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/safe_fs.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h drc.h view.h \ + idpath.h view.h conf_core.h find.h event.h \ + ../src_3rd/librnd/core/event.h ../src_plugins/drc_query/drc_query_conf.h \ + ../src_plugins/drc_query/conf_internal.c ../src_plugins/query/query.h \ + ../src_3rd/genvector/vti0.h ../src_3rd/genht/htsi.h \ + ../src_3rd/genregex/regex_se.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h ../src_plugins/query/fields_sphash.h \ + obj_common.h layer.h flag_str.h ../src_plugins/query/query_exec.h \ + ../src_plugins/query/query.h ../src_3rd/genht/htpi.h \ + ../src_plugins/drc_query/drc_query_stat.c \ + ../src_plugins/drc_query/drc_lht.c ../src_plugins/drc_query/dlg.c \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_tree.h actions_pcb.h \ + ../src_plugins/drc_query/drc_query_conf_fields.h +../src_plugins/expfeat/expfeat.o: ../src_plugins/expfeat/expfeat.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h layer.h \ + ../src_3rd/librnd/core/color.h attrib.h global_typedefs.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + change.h board.h vtroutestyle.h rats_patch.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h +../src_plugins/export_bom/bom.o: ../src_plugins/export_bom/bom.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/vts0.h build_run.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_3rd/librnd/core/hid_attrib.h hid_cam.h \ + ../src_3rd/librnd/core/hid_init.h +../src_plugins/export_dsn/dsn.o: ../src_plugins/export_dsn/dsn.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h buffer.h change.h draw.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_3rd/librnd/core/rnd_printf.h polygon.h \ + ../src_3rd/librnd/core/compat_misc.h layer.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + netlist.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/librnd/core/hid_attrib.h hid_cam.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/error.h obj_line.h \ + obj_pstk_inlines.h data.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h +../src_plugins/export_dxf/dxf.o: ../src_plugins/export_dxf/dxf.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/math_helper.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + layer.h layer_vis.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/compat_misc.h \ + ../src_plugins/export_dxf/lht_template.h \ + ../src_3rd/librnd/core/safe_fs.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/librnd/core/hid_attrib.h hid_cam.h \ + ../src_plugins/export_dxf/dxf_draw.c +../src_plugins/export_dxf/dxf_templ_lht.o: \ + ../src_plugins/export_dxf/dxf_templ_lht.c +../src_plugins/export_dxf/lht_template.o: \ + ../src_plugins/export_dxf/lht_template.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/liblihata/tree.h \ + ../src_plugins/export_dxf/lht_template.h +../src_plugins/export_excellon/aperture.o: \ + ../src_plugins/export_excellon/aperture.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h \ + ../src_plugins/export_excellon/aperture.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +../src_plugins/export_excellon/excellon.o: \ + ../src_plugins/export_excellon/excellon.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/error.h draw.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/compat_misc.h \ + layer.h layer_vis.h ../src_3rd/librnd/core/hid_attrib.h hid_cam.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/error.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h conf_core.h \ + ../src_3rd/librnd/core/event.h \ + ../src_plugins/export_excellon/excellon_conf.h \ + ../src_plugins/export_excellon/excellon.h \ + ../src_plugins/export_excellon/aperture.h \ + ../src_plugins/export_excellon/excellon_conf_fields.h +../src_plugins/export_fidocadj/fidocadj.o: \ + ../src_plugins/export_fidocadj/fidocadj.c ../config.h ../src_3rd/librnd/config.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genht/htsi.h ../src_3rd/librnd/core/math_helper.h board.h \ + vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + layer_vis.h ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/compat_misc.h plug_io.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/librnd/core/hid_attrib.h hid_cam.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h +../src_plugins/export_gcode/gcode.o: ../src_plugins/export_gcode/gcode.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h layer.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/librnd/core/hid_attrib.h hid_cam.h \ + ../src_plugins/millpath/toolpath.h layer_grp.h polygon.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h +../src_plugins/export_gerber/gerber.o: \ + ../src_plugins/export_gerber/gerber.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/math_helper.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h build_run.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h layer.h layer_vis.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h hid_cam.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + funchash_core.h ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_plugins/export_gerber/gerber_conf.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/librnd/core/hid_inlines.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_dad_spin.h \ + conf_core.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/actions.h \ + ../src_plugins/export_excellon/aperture.h \ + ../src_3rd/librnd/plugins/lib_hid_common/xpm.h \ + ../src_plugins/export_gerber/gerber_conf_fields.h +../src_plugins/export_ipcd356/ipcd356.o: \ + ../src_plugins/export_ipcd356/ipcd356.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + conf_core.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/compat_misc.h netlist.h layer.h obj_arc.h \ + obj_line.h obj_poly.h obj_subc.h obj_pstk.h obj_pstk_inlines.h data.h \ + thermal.h operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_3rd/librnd/core/hid_nogui.h hid_cam.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/error.h +../src_plugins/export_lpr/lpr.o: ../src_plugins/export_lpr/lpr.c \ + ../config.h ../src_3rd/librnd/config.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_plugins/export_lpr/../export_ps/ps.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/actions.h +../src_plugins/export_oldconn/oldconn.o: \ + ../src_plugins/export_oldconn/oldconn.c ../config.h ../src_3rd/librnd/config.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h board.h \ + vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/compat_fs.h data.h crosshair.h route.h buffer.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + data_it.h data.h draw.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/safe_fs.h find.h \ + obj_subc_parent.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + funchash_core.h ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + search.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/librnd/core/hid_attrib.h +../src_plugins/export_openems/export_openems.o: \ + ../src_plugins/export_openems/export_openems.c ../config.h \ + ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + data_it.h data.h draw.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/safe_fs.h layer_vis.h \ + obj_subc_parent.h obj_pstk_inlines.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid_nogui.h hid_cam.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/hid_init.h \ + ../src_plugins/lib_polyhelp/topoly.h obj_common.h \ + ../src_plugins/export_openems/mesh.h layer.h \ + ../src_3rd/librnd/core/vtc0.h vtr0.h \ + ../src_plugins/export_openems/excitation.c \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_dad_spin.h \ + event.h ../src_3rd/librnd/core/event.h \ + ../src_plugins/export_openems/openems_xml.c +../src_plugins/export_openems/mesh.o: \ + ../src_plugins/export_openems/mesh.c ../config.h ../src_3rd/librnd/config.h \ + ../src_plugins/export_openems/mesh.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h \ + ../src_3rd/librnd/core/vtc0.h vtr0.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/htpp.h layer_ui.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h board.h vtroutestyle.h layer.h \ + layer_grp.h rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h \ + crosshair.h route.h buffer.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/hid_dad_spin.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h +../src_plugins/export_openscad/export_openscad.o: \ + ../src_plugins/export_openscad/export_openscad.c ../config.h \ + ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/vti0.h ../src_3rd/librnd/core/compat_misc.h board.h \ + vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + layer.h layer_vis.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/safe_fs.h obj_pstk_inlines.h data.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid_attrib.h \ + hid_cam.h ../src_plugins/export_openscad/scad_draw.c \ + ../src_plugins/export_openscad/../lib_polyhelp/topoly.h obj_common.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_plugins/export_openscad/scad_models.c +../src_plugins/export_png/png.o: ../src_plugins/export_png/png.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/color_cache.h ../src_3rd/genht/hash.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + route.h buffer.h ../src_3rd/libfungw/fungw.h obj_rat_list.h obj_rat.h \ + idpath.h obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + obj_pstk_list.h obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h draw.h layer.h layer_vis.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/safe_fs.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_plugins/export_png/png.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/librnd/core/hid_attrib.h \ + hid_cam.h ../src_plugins/export_png/png_photo1.c \ + ../src_plugins/export_png/png_photo2.c +../src_plugins/export_ps/eps.o: ../src_plugins/export_ps/eps.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/math_helper.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + layer.h layer_vis.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_plugins/export_ps/ps.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/librnd/core/hid_attrib.h hid_cam.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h +../src_plugins/export_ps/ps.o: ../src_plugins/export_ps/ps.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/math_helper.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h layer.h draw.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h hid_cam.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h layer_vis.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_plugins/export_ps/ps.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/librnd/core/actions.h \ + conf_core.h ../src_3rd/librnd/core/compat_misc.h stub_draw.h draw.h \ + ../src_plugins/lib_compat_help/media.h +../src_plugins/export_stat/stat.o: ../src_plugins/export_stat/stat.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genht/htsi.h ../src_3rd/genht/hash.h \ + ../src_3rd/librnd/core/math_helper.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h data_it.h data.h netlist.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/compat_misc.h plug_io.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/safe_fs.h \ + obj_pstk_inlines.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/librnd/core/hid_attrib.h \ + hid_cam.h +../src_plugins/export_stl/export_stl.o: \ + ../src_plugins/export_stl/export_stl.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vtd0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h hid_cam.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h data.h crosshair.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h layer.h \ + obj_pstk_inlines.h board.h vtroutestyle.h rats_patch.h data.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h conf_core.h \ + ../src_plugins/export_stl/../lib_polyhelp/topoly.h board.h obj_common.h \ + ../src_plugins/export_stl/../lib_polyhelp/triangulate.h \ + ../src_3rd/fast89-poly2tri/fast89_poly2tri.h \ + ../src_plugins/export_stl/stl_models.c +../src_plugins/export_svg/svg.o: ../src_plugins/export_svg/svg.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/math_helper.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + layer.h layer_vis.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/safe_fs.h \ + funchash_core.h ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_3rd/librnd/core/hid_nogui.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/librnd/core/hid_attrib.h hid_cam.h +../src_plugins/export_vfs_fuse/export_vfs_fuse.o: \ + ../src_plugins/export_vfs_fuse/export_vfs_fuse.c \ + ../src_plugins/export_vfs_fuse/fuse_includes.h ../config.h \ + ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + build_run.h board.h vtroutestyle.h attrib.h global_typedefs.h layer.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/compat_fs.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_plugins/lib_vfs/lib_vfs.h +../src_plugins/export_vfs_mc/export_vfs_mc.o: \ + ../src_plugins/export_vfs_mc/export_vfs_mc.c ../config.h ../src_3rd/librnd/config.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + build_run.h board.h vtroutestyle.h attrib.h global_typedefs.h layer.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_plugins/lib_vfs/lib_vfs.h +../src_plugins/export_xy/xy.o: ../src_plugins/export_xy/xy.c ../config.h \ + ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/math_helper.h build_run.h board.h vtroutestyle.h \ + attrib.h global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + data_it.h data.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/compat_misc.h obj_pstk_inlines.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h obj_subc_op.h layer.h \ + netlist.h ../src_3rd/librnd/core/safe_fs.h operation.h \ + ../src_plugins/export_xy/xy_conf.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_3rd/librnd/core/hid_attrib.h hid_cam.h \ + ../src_3rd/librnd/core/hid_init.h \ + ../src_plugins/lib_compat_help/elem_rot.h \ + ../src_plugins/export_xy/conf_internal.c \ + ../src_plugins/export_xy/xy_conf_fields.h +../src_plugins/extedit/extedit.o: ../src_plugins/extedit/extedit.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/compat_fs.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h data.h crosshair.h route.h buffer.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + buffer.h ../src_3rd/librnd/core/paths.h remove.h operation.h \ + ../src_3rd/librnd/core/safe_fs.h search.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_plugins/io_lihata/io_lihata.h ../src_plugins/io_lihata/lht_conf.h \ + ../src_plugins/io_lihata/write.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_plugins/io_lihata/read.h \ + ../src_plugins/extedit/extedit_dad.c +../src_plugins/exto_std/exto_std.o: ../src_plugins/exto_std/exto_std.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h obj_subc.h \ + ../src_3rd/librnd/core/rnd_printf.h extobj.h data.h obj_subc_parent.h \ + draw.h extobj_helper.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/hid_inlines.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h change.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h conf_core.h \ + ../src_plugins/exto_std/line_of_vias.c \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h \ + ../src_plugins/exto_std/dimension.c search.h \ + ../src_plugins/exto_std/cord.c data_parent.h \ + ../src_plugins/exto_std/bus.c +../src_plugins/fontmode/fontmode.o: ../src_plugins/fontmode/fontmode.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + flag.h layer.h move.h remove.h operation.h flag_str.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/compat_misc.h \ + event.h ../src_3rd/librnd/core/event.h polygon.h obj_poly_draw.h draw.h +../src_plugins/fp_board/fp_board.o: ../src_plugins/fp_board/fp_board.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h plug_footprint.h \ + vtlibrary.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + attrib.h global_typedefs.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h board.h vtroutestyle.h rats_patch.h \ + board.h buffer.h data.h obj_subc.h obj_subc_list.h obj_subc_op.h \ + operation.h ../src_3rd/librnd/core/compat_misc.h operation.h plug_io.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/safe_fs.h +../src_plugins/fp_fs/fp_fs.o: ../src_plugins/fp_fs/fp_fs.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/compat_inc.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/paths.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/genregex/regex_sei.h \ + ../src_3rd/genregex/regex_templ.h ../src_3rd/genregex/regex.h \ + plug_footprint.h vtlibrary.h data.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h plug_io.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/compat_fs.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/conf_hid.h conf_core.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/safe_fs_dir.h ../src_plugins/fp_fs/fp_fs_conf.h \ + ../src_plugins/fp_fs/conf_internal.c \ + ../src_plugins/fp_fs/fp_fs_conf_fields.h +../src_plugins/fp_wget/edakrill.o: ../src_plugins/fp_wget/edakrill.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_plugins/fp_wget/wget_common.h \ + ../src_plugins/fp_wget/edakrill.h plug_footprint.h vtlibrary.h data.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h layer.h \ + ../src_3rd/librnd/core/color.h attrib.h global_typedefs.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_plugins/fp_wget/fp_wget_conf.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h globalconst.h +../src_plugins/fp_wget/fp_wget.o: ../src_plugins/fp_wget/fp_wget.c \ + ../config.h ../src_3rd/librnd/config.h ../src_plugins/fp_wget/gedasymbols.h \ + plug_footprint.h vtlibrary.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + attrib.h global_typedefs.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_plugins/fp_wget/fp_wget_conf.h \ + ../src_plugins/fp_wget/edakrill.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_plugins/fp_wget/conf_internal.c \ + ../src_plugins/fp_wget/fp_wget_conf_fields.h +../src_plugins/fp_wget/gedasymbols.o: \ + ../src_plugins/fp_wget/gedasymbols.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_plugins/fp_wget/wget_common.h \ + ../src_plugins/fp_wget/gedasymbols.h plug_footprint.h vtlibrary.h data.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h layer.h \ + ../src_3rd/librnd/core/color.h attrib.h global_typedefs.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_plugins/fp_wget/fp_wget_conf.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h globalconst.h +../src_plugins/fp_wget/wget_common.o: \ + ../src_plugins/fp_wget/wget_common.c ../config.h ../src_3rd/librnd/config.h \ + ../src_plugins/fp_wget/wget_common.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/plugins/lib_wget/lib_wget.h +../src_plugins/import_accel_net/accel_net.o: \ + ../src_plugins/import_accel_net/accel_net.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h plug_import.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/gensexpr/gsxl.h ../src_3rd/gensexpr/gensexpr_impl.h \ + ../src_3rd/gensexpr/gsx_parse.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h ../src_plugins/import_accel_net/menu_internal.c +../src_plugins/import_calay/calay.o: ../src_plugins/import_calay/calay.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + plug_import.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_plugins/import_calay/menu_internal.c +../src_plugins/import_dsn/dsn.o: ../src_plugins/import_dsn/dsn.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/gensexpr/gsxl.h \ + ../src_3rd/gensexpr/gensexpr_impl.h ../src_3rd/gensexpr/gsx_parse.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h polygon.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_plugins/lib_compat_help/pstk_compat.h \ + obj_pstk.h ../src_plugins/import_dsn/menu_internal.c +../src_plugins/import_edif/edif.o: ../src_plugins/import_edif/edif.c \ + ../src_3rd/librnd/core/math_helper.h board.h ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h netlist.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h +../src_plugins/import_edif/import_edif.o: \ + ../src_plugins/import_edif/import_edif.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h plug_import.h rats_patch.h plug_io.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h +../src_plugins/import_fpcb_nl/fpcb_nl.o: \ + ../src_plugins/import_fpcb_nl/fpcb_nl.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/qparse/qparse.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + plug_import.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_plugins/import_fpcb_nl/menu_internal.c +../src_plugins/import_gnetlist/import_gnetlist.o: \ + ../src_plugins/import_gnetlist/import_gnetlist.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/compat_fs.h \ + ../src_3rd/librnd/core/paths.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/hid_init.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h plug_import.h \ + ../src_plugins/import_gnetlist/import_gnetlist_conf.h \ + ../src_plugins/import_gnetlist/conf_internal.c \ + ../src_plugins/import_gnetlist/import_gnetlist_conf_fields.h +../src_plugins/import_hpgl/hpgl.o: ../src_plugins/import_hpgl/hpgl.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/libuhpgl/libuhpgl.h \ + ../src_3rd/libuhpgl/parse.h ../src_3rd/libuhpgl/libuhpgl.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + route.h buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + buffer.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_plugins/import_hpgl/menu_internal.c +../src_plugins/import_ipcd356/ipcd356.o: \ + ../src_plugins/import_ipcd356/ipcd356.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + board.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h conf_core.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_plugins/lib_compat_help/pstk_help.h obj_pstk.h plug_import.h \ + ../src_plugins/import_ipcd356/menu_internal.c +../src_plugins/import_ltspice/ltspice.o: \ + ../src_plugins/import_ltspice/ltspice.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/qparse/qparse.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + plug_import.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/compat_fs.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_plugins/import_ltspice/menu_internal.c +../src_plugins/import_mentor_sch/mentor_sch.o: \ + ../src_plugins/import_mentor_sch/mentor_sch.c ../config.h \ + ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + plug_import.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/gensexpr/gsxl.h ../src_3rd/gensexpr/gensexpr_impl.h \ + ../src_3rd/gensexpr/gsx_parse.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_plugins/import_mentor_sch/mentor_sch_conf.h \ + ../src_3rd/librnd/core/paths.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_plugins/import_mentor_sch/netlist_helper.h \ + ../src_3rd/genregex/regex_se.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h \ + ../src_plugins/import_mentor_sch/menu_internal.c \ + ../src_plugins/import_mentor_sch/mentor_sch_conf_fields.h +../src_plugins/import_mentor_sch/netlist_helper.o: \ + ../src_plugins/import_mentor_sch/netlist_helper.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/genht/hash.h \ + ../src_plugins/import_mentor_sch/netlist_helper.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genregex/regex_se.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h +../src_plugins/import_mucs/mucs.o: ../src_plugins/import_mucs/mucs.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h layer.h conf_core.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h \ + ../src_plugins/import_mucs/menu_internal.c +../src_plugins/import_net_action/import_net_action.o: \ + ../src_plugins/import_net_action/import_net_action.c ../config.h \ + ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h actions_pcb.h plug_import.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h +../src_plugins/import_net_cmd/import_net_cmd.o: \ + ../src_plugins/import_net_cmd/import_net_cmd.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/compat_fs.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h board.h \ + vtroutestyle.h attrib.h global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h plug_import.h +../src_plugins/import_netlist/import_netlist.o: \ + ../src_plugins/import_netlist/import_netlist.c ../config.h \ + ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h plug_import.h conf_core.h \ + ../src_3rd/librnd/core/error.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h rats_patch.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/paths.h \ + ../src_3rd/librnd/core/safe_fs.h netlist.h +../src_plugins/import_orcad_net/orcad_net.o: \ + ../src_plugins/import_orcad_net/orcad_net.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + plug_import.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/gensexpr/gsxl.h ../src_3rd/gensexpr/gensexpr_impl.h \ + ../src_3rd/gensexpr/gsx_parse.h \ + ../src_plugins/import_orcad_net/menu_internal.c +../src_plugins/import_pads_net/pads_net.o: \ + ../src_plugins/import_pads_net/pads_net.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + plug_import.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_plugins/import_pads_net/menu_internal.c +../src_plugins/import_protel_net/protel_net.o: \ + ../src_plugins/import_protel_net/protel_net.c ../config.h \ + ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + plug_import.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_plugins/import_protel_net/menu_internal.c +../src_plugins/import_pxm_gd/import_pxm_gd.o: \ + ../src_plugins/import_pxm_gd/import_pxm_gd.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/pixmap.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h +../src_plugins/import_pxm_pnm/import_pxm_pnm.o: \ + ../src_plugins/import_pxm_pnm/import_pxm_pnm.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/pixmap.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_plugins/import_sch2/import_sch.o: \ + ../src_plugins/import_sch2/import_sch.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/compat_fs.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h globalconst.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h plug_import.h ../src_plugins/import_sch2/import_sch_conf.h \ + ../src_plugins/import_sch2/import_sch_dlg.c \ + ../src_plugins/import_sch2/import_sch_conf_fields.h +../src_plugins/import_tinycad/tinycad.o: \ + ../src_plugins/import_tinycad/tinycad.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/qparse/qparse.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + plug_import.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_plugins/import_tinycad/menu_internal.c +../src_plugins/import_ttf/str_approx.o: \ + ../src_plugins/import_ttf/str_approx.c \ + ../src_plugins/import_ttf/ttf_load.h ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/polyarea.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/ht.h obj_poly.h ../src_3rd/genlist/gendlist.h \ + obj_common.h flag.h globalconst.h ../src_3rd/librnd/core/globalconst.h \ + attrib.h global_typedefs.h data_parent.h obj_poly_list.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_arc.h obj_arc_list.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_plugins/import_ttf/str_approx.h ../src_3rd/librnd/core/error.h +../src_plugins/import_ttf/ttf.o: ../src_plugins/import_ttf/ttf.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_plugins/import_ttf/ttf_load.h font.h \ + ../src_plugins/import_ttf/str_approx.h \ + ../src_3rd/librnd/poly/polygon1_gen.h ../src_3rd/librnd/poly/self_isc.h \ + ../src_plugins/import_ttf/menu_internal.c +../src_plugins/import_ttf/ttf_load.o: \ + ../src_plugins/import_ttf/ttf_load.c \ + ../src_plugins/import_ttf/ttf_load.h ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/polyarea.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/ht.h obj_poly.h ../src_3rd/genlist/gendlist.h \ + obj_common.h flag.h globalconst.h ../src_3rd/librnd/core/globalconst.h \ + attrib.h global_typedefs.h data_parent.h obj_poly_list.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_arc.h obj_arc_list.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h +../src_plugins/io_autotrax/io_autotrax.o: \ + ../src_plugins/io_autotrax/io_autotrax.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h plug_io.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtlibrary.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_plugins/io_autotrax/write.h data.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h layer.h \ + ../src_3rd/librnd/core/color.h attrib.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/io_autotrax/read.h ../src_3rd/librnd/core/actions.h \ + board.h vtroutestyle.h rats_patch.h board.h conf_core.h buffer.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_plugins/io_autotrax/read.o: ../src_plugins/io_autotrax/read.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/qparse/qparse.h \ + ../src_3rd/librnd/core/compat_misc.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h plug_io.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/error.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/io_autotrax/read.h layer.h polygon.h conf_core.h move.h \ + ../src_3rd/librnd/core/safe_fs.h rotate.h \ + ../src_3rd/librnd/core/rotate.h ../src_3rd/librnd/core/actions.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h \ + ../src_plugins/lib_compat_help/pstk_help.h \ + ../src_plugins/lib_compat_help/subc_help.h obj_subc.h +../src_plugins/io_autotrax/write.o: ../src_plugins/io_autotrax/write.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/compat_misc.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h plug_io.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/error.h \ + netlist.h data.h crosshair.h ../src_3rd/librnd/core/hid.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/io_autotrax/write.h layer.h \ + ../src_3rd/librnd/poly/offset.h \ + ../src_plugins/io_autotrax/../lib_polyhelp/polyhelp.h obj_poly.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h +../src_plugins/io_bxl/bxl_decode.o: ../src_plugins/io_bxl/bxl_decode.c \ + ../config.h ../src_3rd/librnd/config.h ../src_plugins/io_bxl/bxl_decode.h +../src_plugins/io_bxl/bxl_gram.o: ../src_plugins/io_bxl/bxl_gram.c \ + ../src_plugins/io_bxl/bxl_gram.h ../src_plugins/io_bxl/bxl.h data.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h ../config.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h layer.h obj_subc.h obj_poly.h obj_pstk.h \ + ../src_3rd/genht/htsi.h +../src_plugins/io_bxl/bxl_lex.o: ../src_plugins/io_bxl/bxl_lex.c \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/config.h \ + ../src_plugins/io_bxl/bxl_gram.h ../src_plugins/io_bxl/bxl.h data.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h ../config.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h layer.h obj_subc.h obj_poly.h obj_pstk.h \ + ../src_3rd/genht/htsi.h +../src_plugins/io_bxl/io_bxl.o: ../src_plugins/io_bxl/io_bxl.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/compat_misc.h plug_io.h \ + global_typedefs.h vtlibrary.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_plugins/io_bxl/read.h +../src_plugins/io_bxl/read.o: ../src_plugins/io_bxl/read.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/compat_misc.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h ../src_plugins/io_bxl/read.h plug_io.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h plug_footprint.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/io_bxl/bxl_decode.h ../src_plugins/io_bxl/bxl_lex.h \ + ../src_plugins/io_bxl/bxl_gram.h ../src_plugins/io_bxl/bxl.h data.h \ + layer.h obj_subc.h obj_poly.h obj_pstk.h ../src_3rd/genht/htsi.h +../src_plugins/io_dsn/io_dsn.o: ../src_plugins/io_dsn/io_dsn.c \ + ../config.h ../src_3rd/librnd/config.h ../src_plugins/io_dsn/read.h plug_io.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtlibrary.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_plugins/io_dsn/write.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h +../src_plugins/io_dsn/read.o: ../src_plugins/io_dsn/read.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/gensexpr/gsxl.h \ + ../src_3rd/gensexpr/gensexpr_impl.h ../src_3rd/gensexpr/gsx_parse.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h board.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/compat_misc.h layer_grp.h conf_core.h \ + ../src_3rd/librnd/core/actions.h netlist.h \ + ../src_3rd/librnd/poly/offset.h ../src_plugins/io_dsn/read.h +../src_plugins/io_dsn/write.o: ../src_plugins/io_dsn/write.c ../config.h \ + ../src_3rd/librnd/config.h plug_io.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtlibrary.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/error.h board.h \ + vtroutestyle.h attrib.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + layer.h layer_grp.h ../src_plugins/io_dsn/write.h \ + ../src_plugins/lib_netmap/netmap.h netlist.h +../src_plugins/io_eagle/eagle_bin.o: ../src_plugins/io_eagle/eagle_bin.c \ + ../config.h ../src_3rd/librnd/config.h ../src_plugins/io_eagle/eagle_bin.h \ + ../src_plugins/io_eagle/egb_tree.h ../src_3rd/genht/htss.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_plugins/io_eagle/egb_tree.o: ../src_plugins/io_eagle/egb_tree.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/hash.h \ + ../src_plugins/io_eagle/egb_tree.h ../src_3rd/genht/htss.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/compat_misc.h +../src_plugins/io_eagle/io_eagle.o: ../src_plugins/io_eagle/io_eagle.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h plug_io.h global_typedefs.h vtlibrary.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_plugins/io_eagle/read.h board.h \ + vtroutestyle.h attrib.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_plugins/io_eagle/read_dru.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h +../src_plugins/io_eagle/read.o: ../src_plugins/io_eagle/read.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_plugins/io_eagle/read.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h conf_core.h polygon.h \ + ../src_3rd/librnd/core/actions.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_plugins/io_eagle/trparse.h ../src_plugins/io_eagle/trparse_xml.h \ + ../src_plugins/io_eagle/trparse_bin.h obj_subc.h obj_poly_op.h \ + operation.h ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h \ + ../src_plugins/lib_compat_help/subc_help.h layer.h \ + ../src_plugins/lib_compat_help/pstk_help.h ../src_plugins/shape/shape.h +../src_plugins/io_eagle/read_dru.o: ../src_plugins/io_eagle/read_dru.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_plugins/io_eagle/read_dru.h plug_io.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h conf_core.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/safe_fs.h board.h vtroutestyle.h attrib.h layer.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h layer_grp.h \ + ../src_3rd/librnd/core/error.h +../src_plugins/io_eagle/trparse_bin.o: \ + ../src_plugins/io_eagle/trparse_bin.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_plugins/io_eagle/egb_tree.h \ + ../src_3rd/genht/htss.h ../src_plugins/io_eagle/eagle_bin.h \ + ../src_plugins/io_eagle/trparse.h ../src_plugins/io_eagle/trparse_bin.h +../src_plugins/io_eagle/trparse_xml.o: \ + ../src_plugins/io_eagle/trparse_xml.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_plugins/io_eagle/trparse.h \ + ../src_plugins/io_eagle/trparse_xml.h +../src_plugins/io_hyp/hyp_l.o: ../src_plugins/io_hyp/hyp_l.c \ + ../src_plugins/io_hyp/hyp_y.h ../src_plugins/io_hyp/parser.h \ + ../src_3rd/librnd/core/rnd_bool.h board.h ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h +../src_plugins/io_hyp/hyp_y.o: ../src_plugins/io_hyp/hyp_y.c \ + ../src_plugins/io_hyp/parser.h ../src_3rd/librnd/core/rnd_bool.h board.h \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + vtroutestyle.h ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_plugins/io_hyp/hyp_l.h +../src_plugins/io_hyp/io_hyp.o: ../src_plugins/io_hyp/io_hyp.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/error.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h plug_io.h \ + global_typedefs.h vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_plugins/io_hyp/parser.h board.h vtroutestyle.h attrib.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h ../src_plugins/io_hyp/write.h \ + obj_rat.h idpath.h ../src_plugins/io_hyp/menu_internal.c +../src_plugins/io_hyp/parser.o: ../src_plugins/io_hyp/parser.c \ + ../src_plugins/io_hyp/parser.h ../src_3rd/librnd/core/rnd_bool.h board.h \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + vtroutestyle.h ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_plugins/io_hyp/hyp_l.h ../src_plugins/io_hyp/hyp_y.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/rnd_printf.h \ + flag_str.h polygon.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h layer.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h search.h rotate.h ../src_3rd/librnd/core/rotate.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/actions.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_plugins/lib_compat_help/pstk_help.h obj_pstk.h \ + ../src_plugins/lib_compat_help/subc_help.h obj_subc.h +../src_plugins/io_hyp/write.o: ../src_plugins/io_hyp/write.c ../config.h \ + ../src_3rd/librnd/config.h ../src_plugins/io_hyp/write.h \ + ../src_3rd/librnd/core/rnd_bool.h plug_io.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h vtlibrary.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h board.h vtroutestyle.h attrib.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/compat_misc.h polygon.h obj_subc_parent.h data.h \ + obj_pstk_inlines.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h ../src_plugins/lib_netmap/netmap.h \ + netlist.h funchash_core.h ../src_3rd/librnd/core/funchash.h \ + funchash_core_list.h ../src_3rd/genht/htpi.h +../src_plugins/io_kicad/io_kicad.o: ../src_plugins/io_kicad/io_kicad.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h plug_io.h global_typedefs.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_plugins/io_kicad/write.h data.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h layer.h \ + ../src_3rd/librnd/core/color.h attrib.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/io_kicad/read.h ../src_plugins/io_kicad/read_net.h \ + ../src_3rd/librnd/core/actions.h ../src_plugins/io_kicad/menu_internal.c +../src_plugins/io_kicad/layertab.o: ../src_plugins/io_kicad/layertab.c \ + ../config.h ../src_3rd/librnd/config.h ../src_plugins/io_kicad/layertab.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h +../src_plugins/io_kicad/read.o: ../src_plugins/io_kicad/read.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/gensexpr/gsxl.h \ + ../src_3rd/gensexpr/gensexpr_impl.h ../src_3rd/gensexpr/gsx_parse.h \ + ../src_3rd/genht/htsi.h ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/librnd/core/compat_misc.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/error.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h ../src_plugins/io_kicad/read.h \ + layer.h polygon.h plug_footprint.h data.h conf_core.h move.h rotate.h \ + ../src_3rd/librnd/core/rotate.h ../src_3rd/librnd/core/safe_fs.h \ + attrib.h netlist.h obj_pstk_inlines.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h \ + ../src_plugins/lib_compat_help/pstk_help.h \ + ../src_plugins/lib_compat_help/subc_help.h obj_subc.h \ + ../src_plugins/lib_compat_help/media.h ../src_plugins/shape/shape.h \ + ../src_plugins/io_kicad/layertab.h +../src_plugins/io_kicad/read_net.o: ../src_plugins/io_kicad/read_net.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/gensexpr/gsxl.h \ + ../src_3rd/gensexpr/gensexpr_impl.h ../src_3rd/gensexpr/gsx_parse.h \ + ../src_plugins/io_kicad/read_net.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h obj_rat_list.h obj_rat.h \ + idpath.h obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h plug_import.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h +../src_plugins/io_kicad/uniq_name.o: ../src_plugins/io_kicad/uniq_name.c \ + ../src_3rd/genht/hash.h ../config.h ../src_3rd/librnd/config.h \ + ../src_plugins/io_kicad/uniq_name.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/compat_misc.h +../src_plugins/io_kicad/write.o: ../src_plugins/io_kicad/write.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/compat_misc.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h plug_io.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/error.h \ + ../src_plugins/io_kicad/uniq_name.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/io_kicad/write.h layer.h netlist.h obj_pstk_inlines.h \ + data.h thermal.h operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + funchash_core.h ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h +../src_plugins/io_kicad_legacy/io_kicad_legacy.o: \ + ../src_plugins/io_kicad_legacy/io_kicad_legacy.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h plug_io.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtlibrary.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_plugins/io_kicad_legacy/write.h \ + data.h globalconst.h ../src_3rd/librnd/core/globalconst.h layer.h \ + ../src_3rd/librnd/core/color.h attrib.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h +../src_plugins/io_kicad_legacy/write.o: \ + ../src_plugins/io_kicad_legacy/write.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/compat_misc.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h plug_io.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/error.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/io_kicad_legacy/write.h layer.h netlist.h \ + obj_pstk_inlines.h data.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_plugins/io_kicad_legacy/../io_kicad/uniq_name.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h +../src_plugins/io_lihata/common.o: ../src_plugins/io_lihata/common.c \ + ../config.h ../src_3rd/librnd/config.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_plugins/io_lihata/common.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h +../src_plugins/io_lihata/io_lihata.o: \ + ../src_plugins/io_lihata/io_lihata.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h plug_io.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtlibrary.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_plugins/io_lihata/read.h \ + ../src_plugins/io_lihata/write.h ../src_plugins/io_lihata/io_lihata.h \ + ../src_plugins/io_lihata/lht_conf.h \ + ../src_plugins/io_lihata/lht_conf_fields.h +../src_plugins/io_lihata/read.o: ../src_plugins/io_lihata/read.c \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/liblihata/tree.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/libminuid/libminuid.h ../config.h \ + ../src_3rd/librnd/config.h board.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h flag_str.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/base64.h \ + ../src_3rd/librnd/core/pixmap.h ../src_3rd/libulzw/libulzw.h layer.h \ + ../src_plugins/io_lihata/common.h polygon.h conf_core.h obj_subc.h \ + pcb_minuid.h thermal.h operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_plugins/io_lihata/io_lihata.h ../src_plugins/io_lihata/lht_conf.h \ + ../src_3rd/librnd/core/safe_fs.h plug_footprint.h data.h vtpadstack.h \ + obj_pstk_inlines.h thermal.h netlist.h \ + ../src_plugins/lib_compat_help/subc_help.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h \ + ../src_plugins/lib_compat_help/elem_rot.h +../src_plugins/io_lihata/write.o: ../src_plugins/io_lihata/write.c \ + ../src_3rd/liblihata/tree.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/htpi.h ../src_3rd/genht/hash.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/libulzw/libulzw.h \ + ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + obj_pstk_list.h obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h flag_str.h \ + ../src_3rd/librnd/core/compat_misc.h rats_patch.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/base64.h \ + ../src_3rd/librnd/core/pixmap.h layer.h \ + ../src_plugins/io_lihata/common.h ../src_plugins/io_lihata/write_style.h \ + ../src_3rd/liblhtpers/lhtpers.h ../src_plugins/io_lihata/io_lihata.h \ + ../src_plugins/io_lihata/lht_conf.h idpath.h \ + ../src_3rd/librnd/core/paths.h obj_subc_list.h pcb_minuid.h \ + ../src_3rd/librnd/core/safe_fs.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h netlist.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h +../src_plugins/io_lihata/write_style.o: \ + ../src_plugins/io_lihata/write_style.c ../config.h ../src_3rd/librnd/config.h \ + ../src_plugins/io_lihata/write_style.h ../src_3rd/liblhtpers/lhtpers.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h +../src_plugins/io_mentor_cell/io_mentor_cell.o: \ + ../src_plugins/io_mentor_cell/io_mentor_cell.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h plug_io.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtlibrary.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_plugins/io_mentor_cell/read.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h +../src_plugins/io_mentor_cell/read.o: \ + ../src_plugins/io_mentor_cell/read.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/qparse/qparse.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h board.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/rotate.h \ + netlist.h obj_subc.h ../src_plugins/lib_compat_help/pstk_help.h \ + obj_pstk.h ../src_plugins/io_mentor_cell/font.c \ + ../src_plugins/io_mentor_cell/font_geo.c \ + ../src_plugins/io_mentor_cell/read_net.c \ + ../src_plugins/io_mentor_cell/read_pstk.c +../src_plugins/io_pcb/attribs.o: ../src_plugins/io_pcb/attribs.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/compat_misc.h +../src_plugins/io_pcb/file.o: ../src_plugins/io_pcb/file.c ../config.h \ + ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h buffer.h obj_common.h flag.h \ + attrib.h global_typedefs.h data_parent.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h change.h board.h vtroutestyle.h layer.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + data.h crosshair.h buffer.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h ../src_plugins/io_pcb/file.h \ + board.h plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h layer.h \ + layer_grp.h move.h ../src_plugins/io_pcb/parse_common.h polygon.h \ + ../src_3rd/librnd/poly/polygon1_gen.h remove.h operation.h flag_str.h \ + ../src_3rd/librnd/core/compat_fs.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/paths.h rats_patch.h \ + ../src_3rd/librnd/core/actions.h ../src_plugins/io_pcb/attribs.h \ + route_style.h obj_poly.h thermal.h event.h \ + ../src_3rd/librnd/core/event.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h netlist.h \ + plug_footprint.h data.h ../src_plugins/lib_compat_help/layer_compat.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h \ + ../src_plugins/lib_compat_help/subc_help.h obj_subc.h \ + ../src_plugins/lib_compat_help/elem_rot.h +../src_plugins/io_pcb/io_pcb.o: ../src_plugins/io_pcb/io_pcb.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_plugins/io_pcb/parse_common.h plug_io.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtlibrary.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_plugins/io_pcb/file.h board.h \ + vtroutestyle.h attrib.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h +../src_plugins/io_pcb/parse_l.o: ../src_plugins/io_pcb/parse_l.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + flag_str.h flag.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/hidlib.h obj_line.h ../src_3rd/genlist/gendlist.h \ + obj_common.h attrib.h global_typedefs.h data_parent.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h route.h data.h layer.h obj_arc_list.h \ + obj_arc.h obj_line_list.h obj_poly_list.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h crosshair.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/io_pcb/file.h board.h vtroutestyle.h rats_patch.h board.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_plugins/io_pcb/parse_common.h ../src_plugins/io_pcb/parse_y.h \ + plug_footprint.h data.h ../src_plugins/io_pcb/attribs.h \ + ../src_3rd/librnd/core/compat_misc.h obj_common.h \ + ../src_3rd/librnd/core/paths.h ../src_3rd/librnd/core/safe_fs.h +../src_plugins/io_pcb/parse_y.o: ../src_plugins/io_pcb/parse_y.c \ + ../config.h ../src_3rd/librnd/config.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h layer.h \ + data.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_plugins/io_pcb/file.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_plugins/io_pcb/parse_l.h polygon.h \ + remove.h operation.h flag_str.h obj_pinvia_therm.h rats_patch.h \ + route_style.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h netlist.h \ + ../src_plugins/io_pcb/parse_y.h +../src_plugins/io_tedax/footprint.o: ../src_plugins/io_tedax/footprint.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h ../src_3rd/genht/hash.h \ + ../src_plugins/io_tedax/footprint.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_plugins/io_tedax/parse.h attrib.h board.h vtroutestyle.h \ + rats_patch.h board.h conf_core.h plug_footprint.h data.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/safe_fs.h \ + obj_line.h obj_arc.h obj_pstk.h obj_pstk_inlines.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_plugins/lib_compat_help/subc_help.h obj_subc.h layer.h \ + ../src_plugins/lib_compat_help/pstk_help.h +../src_plugins/io_tedax/io_tedax.o: ../src_plugins/io_tedax/io_tedax.c \ + ../config.h ../src_3rd/librnd/config.h ../src_plugins/io_tedax/footprint.h data.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h board.h vtroutestyle.h rats_patch.h \ + board.h conf_core.h buffer.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_plugins/io_tedax/stackup.h ../src_plugins/io_tedax/tlayer.h \ + layer.h ../src_plugins/lib_netmap/netmap.h netlist.h \ + ../src_plugins/io_tedax/tboard.h ../src_plugins/io_tedax/trouter.h \ + ../src_plugins/io_tedax/tdrc.h ../src_plugins/io_tedax/tdrc_query.h \ + ../src_plugins/io_tedax/tetest.h ../src_plugins/io_tedax/tnetlist.h \ + ../src_plugins/io_tedax/menu_internal.c +../src_plugins/io_tedax/parse.o: ../src_plugins/io_tedax/parse.c \ + ../config.h ../src_3rd/librnd/config.h ../src_plugins/io_tedax/parse.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/compat_misc.h +../src_plugins/io_tedax/stackup.o: ../src_plugins/io_tedax/stackup.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htip.h ../src_3rd/genht/hash.h \ + ../src_plugins/io_tedax/stackup.h board.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/genvector/vtp0.h \ + ../src_plugins/io_tedax/parse.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/error.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h +../src_plugins/io_tedax/tboard.o: ../src_plugins/io_tedax/tboard.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htsi.h ../src_3rd/genht/hash.h \ + ../src_plugins/lib_netmap/placement.h board.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h ht_subc.h ../src_plugins/io_tedax/tboard.h \ + ../src_plugins/io_tedax/parse.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_plugins/io_tedax/stackup.h ../src_plugins/io_tedax/footprint.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_plugins/io_tedax/tdrc.h ../src_plugins/io_tedax/tlayer.h layer.h \ + ../src_plugins/lib_netmap/netmap.h netlist.h obj_pstk.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_plugins/io_tedax/tnetlist.h +../src_plugins/io_tedax/tdrc.o: ../src_plugins/io_tedax/tdrc.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_plugins/io_tedax/parse.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_plugins/io_tedax/tdrc.h ../src_plugins/io_tedax/tdrc_query.h \ + ../src_plugins/io_tedax/tdrc_keys_sphash.h +../src_plugins/io_tedax/tdrc_keys_sphash.o: \ + ../src_plugins/io_tedax/tdrc_keys_sphash.c +../src_plugins/io_tedax/tdrc_query.o: \ + ../src_plugins/io_tedax/tdrc_query.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_plugins/io_tedax/parse.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_plugins/io_tedax/tdrc_query.h +../src_plugins/io_tedax/tetest.o: ../src_plugins/io_tedax/tetest.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_plugins/io_tedax/parse.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_plugins/io_tedax/tetest.h \ + obj_subc_parent.h data.h obj_pstk.h obj_pstk_inlines.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h netlist.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h hid_cam.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/hid_nogui.h \ + ../src_3rd/librnd/core/hid_init.h +../src_plugins/io_tedax/tlayer.o: ../src_plugins/io_tedax/tlayer.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h ../src_plugins/io_tedax/tlayer.h board.h vtroutestyle.h \ + rats_patch.h board.h layer.h ../src_plugins/lib_netmap/netmap.h \ + netlist.h ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_plugins/io_tedax/parse.h \ + ../src_3rd/librnd/core/compat_misc.h obj_line.h obj_arc.h obj_poly.h \ + ../src_3rd/librnd/core/vtc0.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h obj_pstk_inlines.h data.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_plugins/io_tedax/common_inlines.h +../src_plugins/io_tedax/tnetlist.o: ../src_plugins/io_tedax/tnetlist.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h board.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + plug_import.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/safe_fs.h obj_subc.h netlist.h \ + ../src_plugins/io_tedax/tnetlist.h ../src_plugins/io_tedax/tdrc_query.h \ + ../src_plugins/io_tedax/parse.h +../src_plugins/io_tedax/trouter.o: ../src_plugins/io_tedax/trouter.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htsi.h ../src_3rd/genht/hash.h \ + ../src_plugins/lib_netmap/placement.h board.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h ht_subc.h ../src_plugins/lib_compat_help/pstk_compat.h \ + obj_pstk.h ../src_plugins/io_tedax/tboard.h \ + ../src_plugins/io_tedax/parse.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + obj_pstk_inlines.h data.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h ../src_plugins/io_tedax/stackup.h \ + ../src_plugins/io_tedax/tlayer.h layer.h \ + ../src_plugins/lib_netmap/netmap.h netlist.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/actions.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h conf_core.h undo_old.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_plugins/io_tedax/common_inlines.h +../src_plugins/jostle/jostle.o: ../src_plugins/jostle/jostle.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + polygon.h ../src_3rd/librnd/poly/polygon1_gen.h remove.h operation.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h layer.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h obj_line.h \ + ../src_3rd/librnd/core/event.h +../src_plugins/lib_compat_help/lib_compat_help.o: \ + ../src_plugins/lib_compat_help/lib_compat_help.c \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_plugins/lib_compat_help/layer_compat.c \ + ../config.h ../src_3rd/librnd/config.h \ + ../src_plugins/lib_compat_help/layer_compat.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h layer.h obj_pstk_shape.h polygon.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h vtpadstack_t.h board.h \ + ../src_3rd/genht/htsp.h vtroutestyle.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + ../src_plugins/lib_compat_help/pstk_compat.c obj_pstk_inlines.h data.h \ + thermal.h operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_3rd/librnd/core/compat_misc.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h \ + ../src_plugins/lib_compat_help/pstk_help.c \ + ../src_plugins/lib_compat_help/pstk_help.h search.h remove.h find.h \ + ../src_plugins/lib_compat_help/subc_help.c \ + ../src_plugins/lib_compat_help/subc_help.h obj_subc.h \ + ../src_plugins/lib_compat_help/elem_rot.c \ + ../src_plugins/lib_compat_help/elem_rot.h conf_core.h data_it.h +../src_plugins/lib_compat_help/media.o: \ + ../src_plugins/lib_compat_help/media.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_plugins/lib_compat_help/media.h +../src_plugins/lib_formula/bisect.o: ../src_plugins/lib_formula/bisect.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_plugins/lib_formula/bisect.h +../src_plugins/lib_formula/impedance.o: \ + ../src_plugins/lib_formula/impedance.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_plugins/lib_formula/impedance.h +../src_plugins/lib_formula/lib_formula.o: \ + ../src_plugins/lib_formula/lib_formula.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_plugins/lib_formula/impedance.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_plugins/lib_formula/bisect.h +../src_plugins/lib_hid_pcbui/act.o: ../src_plugins/lib_hid_pcbui/act.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h conf_core.h \ + ../src_3rd/librnd/core/hidlib_conf.h draw.h layer.h layer_vis.h search.h \ + obj_subc_parent.h data.h crosshair.h route.h buffer.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/plugins/lib_hid_common/zoompan.h \ + ../src_plugins/lib_hid_pcbui/util.h data.h \ + ../src_plugins/lib_hid_pcbui/act.h +../src_plugins/lib_hid_pcbui/layer_menu.o: \ + ../src_plugins/lib_hid_pcbui/layer_menu.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/event.h layer.h layer_ui.h layer_grp.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_plugins/lib_hid_pcbui/layer_menu.h +../src_plugins/lib_hid_pcbui/layersel.o: \ + ../src_plugins/lib_hid_pcbui/layersel.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vti0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h board.h \ + vtroutestyle.h attrib.h global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + route.h buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h \ + obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h event.h \ + ../src_3rd/librnd/core/event.h layer.h layer_grp.h layer_ui.h \ + layer_vis.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h \ + ../src_plugins/lib_hid_pcbui/layersel.h +../src_plugins/lib_hid_pcbui/lib_hid_pcbui.o: \ + ../src_plugins/lib_hid_pcbui/lib_hid_pcbui.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/error.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_plugins/lib_hid_pcbui/layer_menu.h \ + ../src_plugins/lib_hid_pcbui/layersel.h \ + ../src_plugins/lib_hid_pcbui/routest.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/plugins/lib_hid_common/toolbar.h \ + ../src_plugins/lib_hid_pcbui/status.h ../src_plugins/lib_hid_pcbui/act.h \ + ../src_plugins/lib_hid_pcbui/util.c ../src_plugins/lib_hid_pcbui/util.h \ + data.h globalconst.h ../src_3rd/librnd/core/globalconst.h layer.h \ + ../src_3rd/librnd/core/color.h attrib.h global_typedefs.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h crosshair.h \ + route.h buffer.h obj_rat_list.h obj_rat.h layer_grp.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h data_it.h data.h flag.h \ + ../src_plugins/lib_hid_pcbui/rendering.c board.h vtroutestyle.h \ + rats_patch.h board.h conf_core.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h layer.h \ + ../src_plugins/lib_hid_pcbui/infobar.c ../src_3rd/librnd/core/safe_fs.h \ + ../src_plugins/lib_hid_pcbui/title.c +../src_plugins/lib_hid_pcbui/routest.o: \ + ../src_plugins/lib_hid_pcbui/routest.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + conf_core.h route_style.h event.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_plugins/lib_hid_pcbui/routest.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_plugins/lib_hid_pcbui/routest_dlg.c \ + ../src_3rd/librnd/core/hid_dad_tree.h ../src_3rd/genht/hash.h +../src_plugins/lib_hid_pcbui/status.o: \ + ../src_plugins/lib_hid_pcbui/status.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hid_cfg_input.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/hid_dad_spin.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/hidlib_conf.h \ + crosshair.h route.h layer.h search.h find.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + obj_subc_parent.h data.h crosshair.h buffer.h \ + ../src_3rd/libfungw/fungw.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h netlist.h \ + ../src_plugins/lib_hid_pcbui/status.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/actions.h +../src_plugins/lib_netmap/netmap.o: ../src_plugins/lib_netmap/netmap.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htpp.h \ + ../src_3rd/genht/ht.h ../src_plugins/lib_netmap/netmap.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h netlist.h \ + ../src_3rd/genvector/vtp0.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h find.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h +../src_plugins/lib_netmap/placement.o: \ + ../src_plugins/lib_netmap/placement.c ../config.h ../src_3rd/librnd/config.h \ + ../src_plugins/lib_netmap/placement.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ht_subc.h +../src_plugins/lib_polyhelp/polyhelp.o: \ + ../src_plugins/lib_polyhelp/polyhelp.c ../config.h ../src_3rd/librnd/config.h \ + ../src_plugins/lib_polyhelp/polyhelp.h obj_poly.h \ + ../src_3rd/genlist/gendlist.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h \ + ../src_3rd/librnd/poly/polyarea.h polygon.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + obj_line.h undo_old.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/poly/offset.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_plugins/lib_polyhelp/topoly.h board.h vtroutestyle.h layer.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h obj_text_list.h \ + obj_text.h font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h \ + layer_grp.h rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + obj_common.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h data.h \ + crosshair.h route.h buffer.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h ht_subc.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/actions.h +../src_plugins/lib_polyhelp/topoly.o: \ + ../src_plugins/lib_polyhelp/topoly.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vti0.h \ + ../src_plugins/lib_polyhelp/topoly.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h obj_common.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h route.h \ + buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + obj_arc.h obj_line.h obj_poly.h obj_poly_draw.h draw.h \ + obj_pstk_inlines.h data.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h find.h polygon.h search.h \ + ../src_3rd/librnd/core/actions.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h +../src_plugins/lib_polyhelp/triangulate.o: \ + ../src_plugins/lib_polyhelp/triangulate.c ../config.h ../src_3rd/librnd/config.h \ + ../src_plugins/lib_polyhelp/triangulate.h \ + ../src_3rd/fast89-poly2tri/fast89_poly2tri.h +../src_plugins/lib_vfs/lib_vfs.o: ../src_plugins/lib_vfs/lib_vfs.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_plugins/propedit/props.h \ + ../src_3rd/genvector/vtl0.h idpath.h ../src_plugins/propedit/propsel.h \ + ../src_plugins/lib_vfs/lib_vfs.h +../src_plugins/millpath/millpath.o: ../src_plugins/millpath/millpath.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_plugins/millpath/toolpath.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h layer.h polygon.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h board.h vtroutestyle.h \ + layer_grp.h rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h \ + crosshair.h route.h buffer.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h ht_subc.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h +../src_plugins/millpath/toolpath.o: ../src_plugins/millpath/toolpath.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/qparse/qparse.h \ + ../src_plugins/millpath/toolpath.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + layer.h polygon.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h board.h ../src_3rd/genht/htsp.h \ + vtroutestyle.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h flag.h layer_ui.h obj_line.h obj_line_op.h operation.h \ + obj_arc.h obj_poly.h obj_poly_op.h obj_text_draw.h draw.h \ + ../src_3rd/librnd/poly/polygon1_gen.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_plugins/lib_polyhelp/polyhelp.h ../src_plugins/ddraft/centgeo.h +../src_plugins/mincut/pcb-mincut/graph.o: \ + ../src_plugins/mincut/pcb-mincut/graph.c \ + ../src_plugins/mincut/pcb-mincut/graph.h \ + ../src_plugins/mincut/pcb-mincut/../../../config.h ../src_3rd/librnd/config.h +../src_plugins/mincut/pcb-mincut/solve.o: \ + ../src_plugins/mincut/pcb-mincut/solve.c \ + ../src_plugins/mincut/pcb-mincut/solve.h \ + ../src_plugins/mincut/pcb-mincut/graph.h \ + ../src_plugins/mincut/pcb-mincut/../../../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_plugins/mincut/rats_mincut.o: ../src_plugins/mincut/rats_mincut.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h event.h ../src_3rd/librnd/core/event.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h find.h \ + polygon.h search.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h netlist.h ../src_3rd/librnd/core/compat_misc.h \ + obj_common.h obj_subc_parent.h data.h \ + ../src_plugins/mincut/pcb-mincut/graph.h \ + ../src_plugins/mincut/pcb-mincut/../../../config.h \ + ../src_plugins/mincut/pcb-mincut/solve.h \ + ../src_plugins/mincut/pcb-mincut/graph.h \ + ../src_plugins/mincut/rats_mincut_conf.h \ + ../src_plugins/mincut/rats_mincut_conf_fields.h +../src_plugins/oldactions/oldactions.o: \ + ../src_plugins/oldactions/oldactions.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h layer.h \ + ../src_3rd/librnd/core/color.h attrib.h global_typedefs.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + event.h ../src_3rd/librnd/core/event.h change.h board.h vtroutestyle.h \ + rats_patch.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h \ + plug_footprint.h vtlibrary.h data.h obj_subc.h \ + ../src_3rd/librnd/core/compat_misc.h netlist.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h search.h +../src_plugins/order/order.o: ../src_plugins/order/order.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h route.h buffer.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/hid_menu.h \ + layer.h ../src_3rd/librnd/core/event.h ../src_plugins/order/order_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_plugins/order/conf_internal.c \ + ../src_plugins/order/order.h ../src_plugins/order/order_conf.h \ + ../src_plugins/order/menu_internal.c ../src_plugins/order/order_dlg.c \ + ../src_plugins/order/order_conf_fields.h +../src_plugins/order_pcbway/pcbway.o: \ + ../src_plugins/order_pcbway/pcbway.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vts0.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/paths.h ../src_3rd/librnd/core/compat_fs.h \ + ../src_3rd/librnd/plugins/lib_wget/lib_wget.h \ + ../src_plugins/order/order.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_plugins/order/order_conf.h \ + ../src_plugins/order_pcbway/order_pcbway_conf.h \ + ../src_plugins/order_pcbway/conf_internal.c \ + ../src_plugins/order_pcbway/order_pcbway_conf_fields.h +../src_plugins/polycombine/polycombine.o: \ + ../src_plugins/polycombine/polycombine.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h remove.h operation.h polygon.h flag_str.h \ + find.h draw.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h obj_poly.h +../src_plugins/polystitch/polystitch.o: \ + ../src_plugins/polystitch/polystitch.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h remove.h operation.h draw.h polygon.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h obj_poly.h \ + obj_poly_draw.h draw.h +../src_plugins/propedit/propdlg.o: ../src_plugins/propedit/propdlg.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/hash.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_tree.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h netlist.h \ + ../src_plugins/propedit/props.h ../src_3rd/genvector/vtl0.h idpath.h \ + ../src_3rd/genht/ht.h ../src_plugins/propedit/propsel.h +../src_plugins/propedit/propedit.o: ../src_plugins/propedit/propedit.c \ + board.h ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_plugins/propedit/props.h ../src_3rd/genvector/vtl0.h idpath.h \ + ../src_plugins/propedit/propsel.h ../src_plugins/propedit/propdlg.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/rnd_printf.h \ + layer.h layer_addr.h layer_grp.h search.h crosshair.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_plugins/propedit/props.o: ../src_plugins/propedit/props.c \ + ../config.h ../src_3rd/librnd/config.h ../src_plugins/propedit/props.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genvector/vtl0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h idpath.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + data_parent.h ../src_3rd/librnd/core/color.h ../src_3rd/genht/ht.h \ + ../src_plugins/propedit/propsel.h ../src_3rd/librnd/core/compat_misc.h \ + board.h vtroutestyle.h ../src_3rd/librnd/core/unit.h layer.h \ + obj_arc_list.h obj_arc.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/genht/hash.h \ + ../src_3rd/genht/ht.c ../src_3rd/genht/ht_inlines.h +../src_plugins/propedit/propsel.o: ../src_plugins/propedit/propsel.c \ + ../config.h ../src_3rd/librnd/config.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h data_it.h data.h \ + ../src_plugins/propedit/props.h ../src_3rd/genvector/vtl0.h idpath.h \ + ../src_plugins/propedit/propsel.h change.h board.h vtroutestyle.h \ + rats_patch.h draw.h flag_str.h ../src_3rd/librnd/core/compat_misc.h \ + undo.h ../src_3rd/libuundo/uundo.h undo_old.h rotate.h \ + ../src_3rd/librnd/core/rotate.h obj_pstk_inlines.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_3rd/librnd/core/rnd_printf.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/hidlib_conf.h \ + netlist.h obj_line_op.h obj_arc_op.h obj_text_op.h obj_pstk_op.h \ + obj_subc_op.h +../src_plugins/puller/puller.o: ../src_plugins/puller/puller.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + move.h remove.h operation.h flag_str.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h layer.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/compat_misc.h obj_pstk_inlines.h data.h thermal.h \ + ../src_3rd/librnd/poly/polygon1_gen.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h search.h find.h +../src_plugins/query/dlg_search.o: ../src_plugins/query/dlg_search.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/hidlib.h ../src_plugins/query/query.h \ + ../src_3rd/genvector/vti0.h ../src_3rd/genht/htsi.h \ + ../src_3rd/genregex/regex_se.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h ../src_plugins/query/fields_sphash.h \ + obj_common.h flag.h globalconst.h ../src_3rd/librnd/core/globalconst.h \ + attrib.h global_typedefs.h data_parent.h layer.h obj_common.h \ + obj_arc_list.h obj_arc.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h flag_str.h \ + board.h vtroutestyle.h layer.h layer_grp.h rats_patch.h board.h \ + ../src_plugins/query/dlg_search_tab.h \ + ../src_plugins/query/dlg_search_edit.c \ + ../src_3rd/librnd/core/hid_dad_tree.h ../src_3rd/genht/hash.h +../src_plugins/query/fields_sphash.o: \ + ../src_plugins/query/fields_sphash.c +../src_plugins/query/fnc.o: ../src_plugins/query/fnc.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/genht/hash.h ../src_3rd/genht/ht_utils.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/libfungw/fungw_conv.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + route.h buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h \ + obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + obj_pstk_list.h obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h find.h obj_term.h netlist.h \ + ../src_plugins/query/net_int.h obj_common.h \ + ../src_plugins/query/query_exec.h ../src_plugins/query/query.h \ + ../src_3rd/genvector/vti0.h ../src_3rd/genht/htsi.h \ + ../src_3rd/genregex/regex_se.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h ../src_plugins/query/fields_sphash.h layer.h \ + flag_str.h ../src_3rd/genht/htpi.h ../src_plugins/query/net_len.h \ + ../src_plugins/query/query_access.h ../src_plugins/query/fnc_glue.c \ + ../src_plugins/query/fnc_list.c ../src_plugins/query/fnc_geo.c \ + obj_poly.h data_it.h data.h ../src_plugins/query/fnc_obj.c thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_plugins/query/fnc_layer_setup.c ../src_3rd/genht/ht.c \ + ../src_3rd/genht/ht_inlines.h +../src_plugins/query/net_int.o: ../src_plugins/query/net_int.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htpp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h find.h \ + ../src_3rd/genvector/vtp0.h netlist.h ../src_plugins/query/net_int.h \ + obj_common.h ../src_plugins/query/query_exec.h \ + ../src_plugins/query/query.h ../src_3rd/genvector/vti0.h \ + ../src_3rd/genht/htsi.h ../src_3rd/genregex/regex_se.h \ + ../src_3rd/genregex/regex_templ.h ../src_3rd/genregex/regex.h \ + ../src_plugins/query/fields_sphash.h layer.h flag_str.h \ + ../src_3rd/genht/htpi.h +../src_plugins/query/net_len.o: ../src_plugins/query/net_len.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htpp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h find.h \ + ../src_3rd/genvector/vtp0.h netlist.h ../src_plugins/query/query_exec.h \ + ../src_plugins/query/query.h ../src_3rd/genvector/vti0.h \ + ../src_3rd/genht/htsi.h ../src_3rd/genregex/regex_se.h \ + ../src_3rd/genregex/regex_templ.h ../src_3rd/genregex/regex.h \ + ../src_plugins/query/fields_sphash.h obj_common.h layer.h flag_str.h \ + ../src_3rd/genht/htpi.h ../src_plugins/query/net_len.h obj_arc.h \ + obj_line.h obj_pstk.h obj_pstk_shape.h polygon.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h vtpadstack_t.h obj_term.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/libfungw/fungw.h +../src_plugins/query/query.o: ../src_plugins/query/query.c ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/genht/hash.h ../src_3rd/genht/htsi.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h data.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h layer.h \ + ../src_3rd/librnd/core/color.h attrib.h global_typedefs.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h change.h board.h \ + vtroutestyle.h rats_patch.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_plugins/query/query.h ../src_3rd/genvector/vti0.h \ + ../src_3rd/genregex/regex_se.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h ../src_plugins/query/fields_sphash.h \ + obj_common.h layer.h flag_str.h ../src_plugins/query/query_l.h \ + ../src_3rd/librnd/core/fptr_cast.h +../src_plugins/query/query_access.o: ../src_plugins/query/query_access.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/compat_misc.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_plugins/query/query_access.h \ + ../src_plugins/query/query.h ../src_3rd/genvector/vti0.h \ + ../src_3rd/genht/htsi.h ../src_3rd/genregex/regex_se.h \ + ../src_3rd/genregex/regex_templ.h ../src_3rd/genregex/regex.h \ + ../src_plugins/query/fields_sphash.h obj_common.h layer.h flag_str.h \ + ../src_plugins/query/query_exec.h ../src_3rd/genht/htpi.h netlist.h \ + obj_pstk_inlines.h data.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h obj_subc_parent.h \ + ../src_plugins/query/net_int.h find.h +../src_plugins/query/query_act.o: ../src_plugins/query/query_act.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_plugins/query/query.h ../src_3rd/genvector/vti0.h \ + ../src_3rd/genht/htsi.h ../src_3rd/genregex/regex_se.h \ + ../src_3rd/genregex/regex_templ.h ../src_3rd/genregex/regex.h \ + ../src_plugins/query/fields_sphash.h obj_common.h flag.h attrib.h \ + global_typedefs.h data_parent.h layer.h obj_common.h obj_arc_list.h \ + obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h obj_gfx_list.h \ + obj_gfx.h flag_str.h ../src_plugins/query/query_y.h \ + ../src_plugins/query/query_exec.h ../src_3rd/genht/htpi.h \ + ../src_plugins/query/query_access.h draw.h layer.h select.h operation.h \ + board.h vtroutestyle.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h idpath.h view.h idpath.h actions_pcb.h \ + ../src_plugins/query/net_len.h ../src_plugins/query/dlg_search.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_plugins/query/query_exec.o: ../src_plugins/query/query_exec.c \ + ../config.h ../src_3rd/librnd/config.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_plugins/query/query.h \ + ../src_3rd/genvector/vti0.h ../src_3rd/genht/htsi.h \ + ../src_3rd/genregex/regex_se.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h ../src_plugins/query/fields_sphash.h \ + obj_common.h layer.h flag_str.h ../src_plugins/query/query_exec.h \ + ../src_3rd/genht/htpi.h ../src_plugins/query/query_access.h \ + ../src_plugins/query/net_len.h ../src_3rd/librnd/core/rnd_printf.h +../src_plugins/query/query_l.o: ../src_plugins/query/query_l.c \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/rnd_bool.h \ + ../src_plugins/query/query.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vti0.h \ + ../src_3rd/genht/htsi.h ../src_3rd/genht/ht.h \ + ../src_3rd/genregex/regex_se.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h ../src_plugins/query/fields_sphash.h \ + obj_common.h flag.h globalconst.h ../src_3rd/librnd/core/globalconst.h \ + attrib.h global_typedefs.h data_parent.h layer.h \ + ../src_3rd/librnd/core/color.h obj_common.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h ../config.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h flag_str.h \ + ../src_plugins/query/query_y.h ../src_3rd/librnd/core/compat_misc.h \ + board.h ../src_3rd/genht/htsp.h vtroutestyle.h layer.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h +../src_plugins/query/query_y.o: ../src_plugins/query/query_y.c \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/rnd_bool.h \ + ../src_plugins/query/query.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/vti0.h \ + ../src_3rd/genht/htsi.h ../src_3rd/genregex/regex_se.h \ + ../src_3rd/genregex/regex_templ.h ../src_3rd/genregex/regex.h \ + ../src_plugins/query/fields_sphash.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + data_parent.h layer.h ../src_3rd/librnd/core/color.h obj_common.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../config.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h flag_str.h ../src_plugins/query/query_l.h \ + ../src_3rd/librnd/core/compat_misc.h +../src_plugins/renumber/renumber.o: ../src_plugins/renumber/renumber.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h change.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/compat_misc.h netlist.h \ + ../src_3rd/librnd/core/safe_fs.h +../src_plugins/renumber/renumberblock.o: \ + ../src_plugins/renumber/renumberblock.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h data.h crosshair.h \ + route.h buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h \ + obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h change.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h +../src_plugins/report/drill.o: ../src_plugins/report/drill.c ../config.h \ + ../src_3rd/librnd/config.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_plugins/report/drill.h \ + obj_pstk_inlines.h board.h vtroutestyle.h rats_patch.h data.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h +../src_plugins/report/report.o: ../src_plugins/report/report.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_plugins/query/net_len.h \ + ../src_plugins/query/query_exec.h ../src_plugins/query/query.h \ + ../src_3rd/genvector/vti0.h ../src_3rd/genht/htsi.h \ + ../src_3rd/genregex/regex_se.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h ../src_plugins/query/fields_sphash.h \ + obj_common.h flag.h attrib.h global_typedefs.h data_parent.h layer.h \ + obj_common.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h flag_str.h ../src_3rd/genht/htpp.h \ + ../src_3rd/genht/htpi.h ../src_plugins/report/report.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h board.h vtroutestyle.h layer.h \ + layer_grp.h rats_patch.h board.h data.h crosshair.h buffer.h \ + ../src_3rd/libfungw/fungw.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h data_it.h data.h \ + ../src_plugins/report/drill.h search.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h find.h draw.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h \ + ../src_plugins/report/report_conf.h ../src_3rd/librnd/core/compat_misc.h \ + layer_ui.h obj_term.h obj_pstk.h obj_pstk_inlines.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h obj_subc_parent.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h netlist.h \ + ../src_3rd/genregex/regex_sei.h \ + ../src_plugins/report/report_conf_fields.h +../src_plugins/rubberband_orig/fgeometry.o: \ + ../src_plugins/rubberband_orig/fgeometry.c \ + ../src_plugins/rubberband_orig/fgeometry.h obj_common.h flag.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/config.h \ + attrib.h global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h +../src_plugins/rubberband_orig/rubberband.o: \ + ../src_plugins/rubberband_orig/rubberband.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h data_it.h data.h data_list.h event.h \ + ../src_3rd/librnd/core/event.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h operation.h rotate.h ../src_3rd/librnd/core/rotate.h \ + ../src_3rd/librnd/core/compat_misc.h draw.h draw_wireframe.h crosshair.h \ + obj_rat_draw.h obj_line_op.h operation.h obj_line_draw.h draw.h \ + obj_pstk_inlines.h thermal.h ../src_3rd/librnd/poly/polygon1_gen.h \ + route_draw.h ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/hidlib_conf.h \ + layer_grp.h ../src_plugins/rubberband_orig/fgeometry.h obj_common.h \ + search.h polygon.h ../src_plugins/rubberband_orig/rubberband_conf.h \ + ../src_3rd/genvector/genvector_impl.c \ + ../src_plugins/rubberband_orig/rubberband_conf_fields.h +../src_plugins/script/live_script.o: ../src_plugins/script/live_script.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/safe_fs_dir.h \ + ../src_3rd/librnd/core/compat_inc.h ../src_3rd/librnd/core/compat_fs.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/hid_menu.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h global_typedefs.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_plugins/script/script.h \ + ../src_plugins/script/live_script.h \ + ../src_plugins/script/menu_internal.c +../src_plugins/script/script.o: ../src_plugins/script/script.c \ + ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/genregex/regex_se.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/compat_fs.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_plugins/script/script.h ../src_plugins/script/c_script.c \ + ../src_3rd/librnd/core/fptr_cast.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/color.h ../src_plugins/script/timer.c \ + ../src_plugins/script/perma.c ../src_3rd/librnd/core/hid_init.h \ + ../src_plugins/script/script_act.c ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid_dad_spin.h \ + ../src_3rd/librnd/core/hid_dad_tree.h \ + ../src_plugins/script/live_script.h +../src_plugins/serpentine/serpentine.o: \ + ../src_plugins/serpentine/serpentine.c ../config.h ../src_3rd/librnd/config.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/hidlib.h \ + obj_line.h ../src_3rd/genlist/gendlist.h obj_common.h flag.h attrib.h \ + global_typedefs.h data_parent.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h route.h board.h vtroutestyle.h layer.h \ + obj_arc_list.h obj_arc.h obj_line_list.h obj_poly_list.h obj_text_list.h \ + obj_text.h font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h \ + layer_grp.h rats_patch.h board.h data.h crosshair.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + data_it.h data.h search.h ../src_3rd/librnd/core/tool.h flag_str.h \ + undo.h ../src_3rd/libuundo/uundo.h undo_old.h find.h draw.h \ + draw_wireframe.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h \ + ../src_plugins/serpentine/serpentine_conf.h layer.h route.h \ + ../src_plugins/serpentine/serpentine_conf_fields.h +../src_plugins/shand_cmd/command.o: ../src_plugins/shand_cmd/command.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h build_run.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_plugins/shand_cmd/command.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/event.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/tool.h +../src_plugins/shape/shape.o: ../src_plugins/shape/shape.c ../config.h \ + ../src_3rd/librnd/config.h ../src_plugins/shape/shape.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h layer.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h buffer.h \ + ../src_3rd/librnd/core/compat_misc.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h event.h \ + ../src_3rd/librnd/core/event.h obj_poly.h obj_poly_draw.h draw.h \ + rotate.h ../src_3rd/librnd/core/rotate.h ../src_3rd/librnd/core/tool.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_plugins/shape/menu_internal.c \ + ../src_plugins/shape/shape_dialog.c ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_dad_spin.h +../src_plugins/sketch_route/ewire.o: ../src_plugins/sketch_route/ewire.c \ + ../src_plugins/sketch_route/ewire.h ../config.h ../src_3rd/librnd/config.h \ + ../src_plugins/sketch_route/sktypedefs.h \ + ../src_plugins/sketch_route/ewire_point.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +../src_plugins/sketch_route/ewire_point.o: \ + ../src_plugins/sketch_route/ewire_point.c \ + ../src_plugins/sketch_route/ewire_point.h \ + ../src_plugins/sketch_route/sktypedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +../src_plugins/sketch_route/pointdata.o: \ + ../src_plugins/sketch_route/pointdata.c \ + ../src_plugins/sketch_route/pointdata.h \ + ../src_plugins/sketch_route/sktypedefs.h \ + ../src_plugins/sketch_route/spoke.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/config.h attrib.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h \ + ../src_plugins/sketch_route/ewire.h ../config.h \ + ../src_plugins/sketch_route/ewire_point.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/libcdtr/point.h \ + ../src_3rd/libcdtr/typedefs.h ../src_3rd/libcdtr/list/list.h \ + ../src_3rd/genvector/vtp0.h ../src_plugins/sketch_route/wire.h \ + ../src_3rd/libcdtr/typedefs.h +../src_plugins/sketch_route/sketch_route.o: \ + ../src_plugins/sketch_route/sketch_route.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h data.h crosshair.h route.h buffer.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + event.h ../src_3rd/librnd/core/event.h list_common.h obj_line_list.h \ + obj_pstk.h obj_pstk_inlines.h data.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h obj_subc_parent.h search.h \ + ../src_3rd/librnd/core/tool.h layer_ui.h netlist.h \ + ../src_plugins/sketch_route/sktypedefs.h \ + ../src_plugins/sketch_route/wire.h ../src_3rd/libcdtr/typedefs.h \ + ../src_3rd/libcdtr/list/list.h ../src_plugins/sketch_route/ewire.h \ + ../src_plugins/sketch_route/ewire_point.h \ + ../src_plugins/sketch_route/pointdata.h \ + ../src_plugins/sketch_route/spoke.h obj_common.h \ + ../src_3rd/libcdtr/point.h ../src_3rd/libcdtr/typedefs.h \ + ../src_3rd/libcdtr/cdt.h ../src_3rd/libcdtr/point.h \ + ../src_3rd/libcdtr/edge.h ../src_3rd/libcdtr/triangle.h +../src_plugins/sketch_route/spoke.o: ../src_plugins/sketch_route/spoke.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_plugins/sketch_route/spoke.h \ + ../src_plugins/sketch_route/sktypedefs.h obj_common.h flag.h attrib.h \ + global_typedefs.h data_parent.h ../src_plugins/sketch_route/ewire.h \ + ../src_plugins/sketch_route/ewire_point.h ../src_3rd/libcdtr/point.h \ + ../src_3rd/libcdtr/typedefs.h ../src_3rd/libcdtr/list/list.h \ + ../src_plugins/sketch_route/pointdata.h \ + ../src_plugins/sketch_route/wire.h ../src_3rd/libcdtr/typedefs.h +../src_plugins/sketch_route/wire.o: ../src_plugins/sketch_route/wire.c \ + ../src_plugins/sketch_route/pointdata.h \ + ../src_plugins/sketch_route/sktypedefs.h \ + ../src_plugins/sketch_route/spoke.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/config.h attrib.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h \ + ../src_plugins/sketch_route/ewire.h ../config.h \ + ../src_plugins/sketch_route/ewire_point.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/libcdtr/point.h \ + ../src_3rd/libcdtr/typedefs.h ../src_3rd/libcdtr/list/list.h \ + ../src_3rd/genvector/vtp0.h ../src_plugins/sketch_route/wire.h \ + ../src_3rd/libcdtr/typedefs.h ../src_3rd/libcdtr/list/list.c \ + ../src_3rd/genvector/genvector_impl.c +../src_plugins/smartdisperse/smartdisperse.o: \ + ../src_plugins/smartdisperse/smartdisperse.c ../src_3rd/genht/htpi.h \ + ../src_3rd/genht/ht.h ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + netlist.h move.h draw.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h \ + ../src_3rd/librnd/core/actions.h obj_subc.h obj_subc_parent.h data.h \ + obj_term.h funchash_core.h ../src_3rd/librnd/core/funchash.h \ + funchash_core_list.h +../src_plugins/teardrops/teardrops.o: \ + ../src_plugins/teardrops/teardrops.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/math_helper.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h \ + obj_pstk_inlines.h data.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h +../src_plugins/tool_std/tool_arc.o: ../src_plugins/tool_std/tool_arc.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + data.h crosshair.h buffer.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h draw_wireframe.h \ + search.h ../src_3rd/librnd/core/tool.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h obj_arc_draw.h draw.h +../src_plugins/tool_std/tool_arrow.o: \ + ../src_plugins/tool_std/tool_arrow.c ../config.h ../src_3rd/librnd/config.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h buffer.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h route.h data.h crosshair.h buffer.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/actions.h remove.h operation.h move.h search.h \ + select.h ../src_3rd/librnd/core/tool.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h extobj.h data.h obj_subc_parent.h \ + draw.h tool_logic.h +../src_plugins/tool_std/tool_buffer.o: \ + ../src_plugins/tool_std/tool_buffer.c ../config.h ../src_3rd/librnd/config.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h buffer.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/compat_misc.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + route.h buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h \ + obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/actions.h search.h ../src_3rd/librnd/core/tool.h \ + undo.h ../src_3rd/libuundo/uundo.h undo_old.h +../src_plugins/tool_std/tool_copy.o: ../src_plugins/tool_std/tool_copy.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h move.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h search.h tool_logic.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/genvector/vtp0.h +../src_plugins/tool_std/tool_insert.o: \ + ../src_plugins/tool_std/tool_insert.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h insert.h polygon.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h search.h tool_logic.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/genvector/vtp0.h +../src_plugins/tool_std/tool_line.o: ../src_plugins/tool_std/tool_line.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + data.h crosshair.h buffer.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h draw_wireframe.h find.h \ + obj_line.h obj_subc.h search.h ../src_3rd/librnd/core/tool.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h netlist.h tool_logic.h \ + obj_line_draw.h draw.h obj_pstk_draw.h obj_rat_draw.h route_draw.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h +../src_plugins/tool_std/tool_lock.o: ../src_plugins/tool_std/tool_lock.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h change.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h ../src_3rd/librnd/core/actions.h \ + search.h ../src_3rd/librnd/core/tool.h tool_logic.h \ + ../src_plugins/tool_std/tool_lock.h +../src_plugins/tool_std/tool_move.o: ../src_plugins/tool_std/tool_move.c \ + ../config.h ../src_3rd/librnd/config.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h move.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h search.h tool_logic.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/genvector/vtp0.h extobj.h \ + data.h crosshair.h buffer.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h obj_subc_parent.h draw.h \ + obj_gfx.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h +../src_plugins/tool_std/tool_poly.o: ../src_plugins/tool_std/tool_poly.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h route.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h polygon.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/core/tool.h +../src_plugins/tool_std/tool_polyhole.o: \ + ../src_plugins/tool_std/tool_polyhole.c ../config.h ../src_3rd/librnd/config.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h route.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h polygon.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h search.h \ + ../src_3rd/librnd/core/tool.h +../src_plugins/tool_std/tool_rectangle.o: \ + ../src_plugins/tool_std/tool_rectangle.c ../config.h ../src_3rd/librnd/config.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h route.h data.h crosshair.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + tool_logic.h ../src_3rd/librnd/core/tool.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h obj_poly_draw.h draw.h +../src_plugins/tool_std/tool_remove.o: \ + ../src_plugins/tool_std/tool_remove.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + remove.h operation.h search.h obj_rat.h idpath.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/genvector/vtp0.h crosshair.h \ + route.h tool_logic.h +../src_plugins/tool_std/tool_rotate.o: \ + ../src_plugins/tool_std/tool_rotate.c ../config.h ../src_3rd/librnd/config.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h board.h \ + vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h rotate.h \ + ../src_3rd/librnd/core/rotate.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/tool.h crosshair.h route.h tool_logic.h +../src_plugins/tool_std/tool_std.o: ../src_plugins/tool_std/tool_std.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/tool.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/hidlib.h \ + obj_line.h ../src_3rd/genlist/gendlist.h obj_common.h flag.h attrib.h \ + global_typedefs.h data_parent.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h route.h \ + ../src_plugins/tool_std/tool_arc.h ../src_plugins/tool_std/tool_arrow.h \ + ../src_plugins/tool_std/tool_buffer.h \ + ../src_plugins/tool_std/tool_copy.h \ + ../src_plugins/tool_std/tool_insert.h \ + ../src_plugins/tool_std/tool_line.h ../src_plugins/tool_std/tool_lock.h \ + ../src_plugins/tool_std/tool_move.h ../src_plugins/tool_std/tool_poly.h \ + ../src_plugins/tool_std/tool_polyhole.h \ + ../src_plugins/tool_std/tool_rectangle.h \ + ../src_plugins/tool_std/tool_remove.h \ + ../src_plugins/tool_std/tool_rotate.h \ + ../src_plugins/tool_std/tool_text.h \ + ../src_plugins/tool_std/tool_thermal.h \ + ../src_plugins/tool_std/tool_via.h +../src_plugins/tool_std/tool_text.o: ../src_plugins/tool_std/tool_text.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h board.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/tool.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h obj_text_draw.h draw.h +../src_plugins/tool_std/tool_thermal.o: \ + ../src_plugins/tool_std/tool_thermal.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h change.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/actions.h obj_pstk.h \ + search.h thermal.h operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_3rd/librnd/core/tool.h +../src_plugins/tool_std/tool_via.o: ../src_plugins/tool_std/tool_via.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h board.h ../src_3rd/librnd/core/hidlib.h change.h \ + ../src_3rd/librnd/core/hid_inlines.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h data.h crosshair.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + ../src_3rd/librnd/core/tool.h ../src_plugins/tool_std/tool_thermal.h \ + undo.h ../src_3rd/libuundo/uundo.h undo_old.h obj_pstk_draw.h draw.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h +../src_plugins/vendordrill/vendor.o: ../src_plugins/vendordrill/vendor.c \ + ../config.h ../src_3rd/librnd/config.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genregex/regex_sei.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h change.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h board.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_menu.h \ + ../src_plugins/vendordrill/vendor_conf.h \ + ../src_3rd/librnd/core/compat_misc.h obj_pstk_inlines.h data.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/liblihata/tree.h \ + ../src_plugins/vendordrill/menu_internal.c \ + ../src_plugins/vendordrill/vendor_conf_fields.h +../src_3rd/gensexpr/gsx_parse.o: ../src_3rd/gensexpr/gsx_parse.c \ + ../src_3rd/gensexpr/gsx_parse.h +../src_3rd/gensexpr/gsxl.o: ../src_3rd/gensexpr/gsxl.c \ + ../src_3rd/gensexpr/gsxl.h ../src_3rd/gensexpr/gensexpr_impl.h \ + ../src_3rd/gensexpr/gsx_parse.h ../src_3rd/gensexpr/gensexpr_impl.c +../src_3rd/libcdtr/cdt.o: ../src_3rd/libcdtr/cdt.c \ + ../src_3rd/libcdtr/cdt.h ../src_3rd/libcdtr/typedefs.h \ + ../src_3rd/libcdtr/point.h ../src_3rd/libcdtr/list/list.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/libcdtr/edge.h \ + ../src_3rd/libcdtr/triangle.h +../src_3rd/libcdtr/edge.o: ../src_3rd/libcdtr/edge.c \ + ../src_3rd/libcdtr/edge.h ../src_3rd/libcdtr/typedefs.h \ + ../src_3rd/libcdtr/list/list.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/libcdtr/list/list.c \ + ../src_3rd/genvector/genvector_impl.c +../src_3rd/libcdtr/point.o: ../src_3rd/libcdtr/point.c \ + ../src_3rd/libcdtr/point.h ../src_3rd/libcdtr/typedefs.h \ + ../src_3rd/libcdtr/list/list.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/libcdtr/list/list.c \ + ../src_3rd/genvector/genvector_impl.c +../src_3rd/libcdtr/triangle.o: ../src_3rd/libcdtr/triangle.c \ + ../src_3rd/libcdtr/triangle.h ../src_3rd/libcdtr/typedefs.h \ + ../src_3rd/libcdtr/list/list.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/libcdtr/list/list.c \ + ../src_3rd/genvector/genvector_impl.c +../src_3rd/libfungwbind/fawk/fungw_fawk.o: \ + ../src_3rd/libfungwbind/fawk/fungw_fawk.c ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h \ + ../src_3rd/libfungw/fungw_conv.h \ + ../src_3rd/libfungwbind/fawk/libfawk_sc/libfawk_sc_all.c +../src_3rd/libporty_net/libportytcp4.o: \ + ../src_3rd/libporty_net/libportytcp4.c \ + ../src_3rd/libporty_net/libportytcp4.h \ + ../src_3rd/libporty_net/os_includes.h \ + ../src_3rd/libporty_net/pnet_config.h \ + ../src_3rd/libporty_net/phost_types.h +../src_3rd/libuhpgl/parse.o: ../src_3rd/libuhpgl/parse.c \ + ../src_3rd/libuhpgl/uhpgl_math.h ../src_3rd/libuhpgl/libuhpgl.h \ + ../src_3rd/libuhpgl/parse.h ../src_3rd/libuhpgl/arc_iterate.h +../src_3rd/libuirc/libuirc.o: ../src_3rd/libuirc/libuirc.c \ + ../src_3rd/libuirc/libuirc.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/libporty_net/libportytcp4.h \ + ../src_3rd/libporty_net/os_includes.h \ + ../src_3rd/libporty_net/pnet_config.h \ + ../src_3rd/libporty_net/phost_types.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/config.h +../src_3rd/genht/hash.o: ../src_3rd/genht/hash.c +../src_3rd/genht/htip.o: ../src_3rd/genht/htip.c ../src_3rd/genht/htip.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/ht.c \ + ../src_3rd/genht/ht_inlines.h +../src_3rd/genht/htpi.o: ../src_3rd/genht/htpi.c ../src_3rd/genht/htpi.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/ht.c \ + ../src_3rd/genht/ht_inlines.h +../src_3rd/genht/htpp.o: ../src_3rd/genht/htpp.c ../src_3rd/genht/htpp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/ht.c \ + ../src_3rd/genht/ht_inlines.h +../src_3rd/genht/htsi.o: ../src_3rd/genht/htsi.c ../src_3rd/genht/htsi.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/ht.c \ + ../src_3rd/genht/ht_inlines.h +../src_3rd/genht/htsp.o: ../src_3rd/genht/htsp.c ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/ht.c \ + ../src_3rd/genht/ht_inlines.h +../src_3rd/genht/htss.o: ../src_3rd/genht/htss.c ../src_3rd/genht/htss.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/ht.c \ + ../src_3rd/genht/ht_inlines.h +../src_3rd/genregex/regex.o: ../src_3rd/genregex/regex.c \ + ../src_3rd/genregex/regex.h +../src_3rd/genregex/regex_se.o: ../src_3rd/genregex/regex_se.c \ + ../src_3rd/genregex/regex_templ.c ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h +../src_3rd/genregex/regex_sei.o: ../src_3rd/genregex/regex_sei.c \ + ../src_3rd/genregex/regex_templ.c ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h +../src_3rd/genvector/gds_char.o: ../src_3rd/genvector/gds_char.c \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +../src_3rd/genvector/vtd0.o: ../src_3rd/genvector/vtd0.c \ + ../src_3rd/genvector/vtd0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +../src_3rd/genvector/vti0.o: ../src_3rd/genvector/vti0.c \ + ../src_3rd/genvector/vti0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +../src_3rd/genvector/vtl0.o: ../src_3rd/genvector/vtl0.c \ + ../src_3rd/genvector/vtl0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +../src_3rd/genvector/vtp0.o: ../src_3rd/genvector/vtp0.c \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +../src_3rd/genvector/vts0.o: ../src_3rd/genvector/vts0.c \ + ../src_3rd/genvector/vts0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +../src_3rd/libfungw/fungw.o: ../src_3rd/libfungw/fungw.c \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h ../src_3rd/genht/hash.h +../src_3rd/libfungw/fungw_call.o: ../src_3rd/libfungw/fungw_call.c \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h +../src_3rd/libfungw/fungw_conv.o: ../src_3rd/libfungw/fungw_conv.c \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h \ + ../src_3rd/libfungw/fungw_conv.h +../src_3rd/libfungw/fungw_debug.o: ../src_3rd/libfungw/fungw_debug.c \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h +../src_3rd/libfungw/fungw_ptr.o: ../src_3rd/libfungw/fungw_ptr.c \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h +../src_3rd/libfungwbind/c/fungw_c.o: ../src_3rd/libfungwbind/c/fungw_c.c \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h +../src_3rd/liblhtpers/lhtpers.o: ../src_3rd/liblhtpers/lhtpers.c \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/liblhtpers/lhtpers.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/liblhtpers/output.c ../src_3rd/liblhtpers/pers_list.c \ + ../src_3rd/liblhtpers/pers_hash.c ../src_3rd/liblhtpers/pers_text.c \ + ../src_3rd/liblhtpers/pers_table.c +../src_3rd/liblihata/dom.o: ../src_3rd/liblihata/dom.c \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/liblihata/dom_internal.h \ + ../src_3rd/liblihata/hash_str.h +../src_3rd/liblihata/dom_hash.o: ../src_3rd/liblihata/dom_hash.c \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/liblihata/dom_internal.h \ + ../src_3rd/liblihata/hash_str.h +../src_3rd/liblihata/dom_list.o: ../src_3rd/liblihata/dom_list.c \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/liblihata/dom_internal.h +../src_3rd/liblihata/dom_table.o: ../src_3rd/liblihata/dom_table.c \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/liblihata/dom_internal.h \ + ../src_3rd/liblihata/tree.h ../src_3rd/liblihata/dom.h +../src_3rd/liblihata/hash_str.o: ../src_3rd/liblihata/hash_str.c +../src_3rd/liblihata/lihata.o: ../src_3rd/liblihata/lihata.c \ + ../src_3rd/liblihata/lihata.h +../src_3rd/liblihata/parser.o: ../src_3rd/liblihata/parser.c \ + ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/lihata.h +../src_3rd/liblihata/tree.o: ../src_3rd/liblihata/tree.c \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/liblihata/tree.h \ + ../src_3rd/liblihata/dom_internal.h +../src_3rd/liblihata/tree_hash.o: ../src_3rd/liblihata/tree_hash.c \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/liblihata/dom_internal.h \ + ../src_3rd/liblihata/tree.h ../src_3rd/liblihata/dom.h +../src_3rd/liblihata/tree_list.o: ../src_3rd/liblihata/tree_list.c \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/liblihata/dom_internal.h \ + ../src_3rd/liblihata/tree.h ../src_3rd/liblihata/dom.h +../src_3rd/liblihata/tree_path.o: ../src_3rd/liblihata/tree_path.c \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/liblihata/tree.h +../src_3rd/liblihata/tree_symlink.o: ../src_3rd/liblihata/tree_symlink.c \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/liblihata/tree.h +../src_3rd/liblihata/tree_table.o: ../src_3rd/liblihata/tree_table.c \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/liblihata/dom_internal.h \ + ../src_3rd/liblihata/tree.h ../src_3rd/liblihata/dom.h +../src_3rd/libulzw/libulzw_comp.o: ../src_3rd/libulzw/libulzw_comp.c +../src_3rd/libulzw/libulzw_decomp.o: ../src_3rd/libulzw/libulzw_decomp.c +../src_3rd/libuundo/uundo.o: ../src_3rd/libuundo/uundo.c \ + ../src_3rd/libuundo/uundo.h +../src_3rd/libuundo/uundo_debug.o: ../src_3rd/libuundo/uundo_debug.c \ + ../src_3rd/libuundo/uundo.h ../src_3rd/libuundo/uundo_debug.h +../src_3rd/qparse/qparse.o: ../src_3rd/qparse/qparse.c \ + ../src_3rd/qparse/qparse.h +actions_pcb.o: actions_pcb.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/libfungw/fungw_conv.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h ../src_3rd/librnd/core/hidlib.h \ + data.h crosshair.h route.h buffer.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h ../src_3rd/librnd/core/compat_misc.h layer_addr.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h change.h \ + ../src_3rd/librnd/core/rnd_printf.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h +attrib.o: attrib.c ../src_3rd/librnd/config.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h +board.o: board.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/hidlib_conf.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/paths.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + undo.h ../src_3rd/libuundo/uundo.h undo_old.h draw.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/tool.h netlist.h defpcb_internal.c \ + obj_pstk_inlines.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h +brave.o: brave.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h brave.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_dad.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/hid_cfg.h \ + ../src_3rd/librnd/core/hid_menu.h ../src_3rd/librnd/core/hid_dad_spin.h +buffer.o: buffer.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + buffer.h obj_common.h flag.h attrib.h global_typedefs.h data_parent.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h board.h \ + vtroutestyle.h layer.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h move.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h rotate.h \ + ../src_3rd/librnd/core/rotate.h ../src_3rd/librnd/core/compat_misc.h \ + remove.h operation.h select.h draw.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h funchash_core.h ../src_3rd/librnd/core/funchash.h \ + funchash_core_list.h ../src_3rd/librnd/core/pixmap.h obj_arc_op.h \ + obj_line_op.h obj_text_op.h obj_subc_op.h obj_poly_op.h obj_pstk_op.h \ + obj_gfx_op.h obj_rat_op.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/tool.h extobj.h obj_subc_parent.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h +build_run.o: build_run.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h build_run.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h plug_io.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/compat_misc.h +buildin.o: buildin.c ../src_3rd/puplug/libs.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h +buildin.hidlib.o: buildin.hidlib.c ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h +change.o: change.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + change.h board.h vtroutestyle.h attrib.h global_typedefs.h layer.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/compat_misc.h \ + data.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + select.h operation.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + thermal.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_3rd/librnd/core/actions.h obj_pstk_op.h obj_subc_parent.h \ + obj_term.h obj_arc_op.h obj_line_op.h obj_poly_op.h obj_text_op.h \ + obj_subc_op.h obj_gfx_op.h extobj.h +change_act.o: change_act.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + data.h layer.h attrib.h global_typedefs.h obj_common.h flag.h \ + data_parent.h obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + funchash_core.h ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + board.h vtroutestyle.h rats_patch.h ../src_3rd/librnd/core/actions.h \ + change.h draw.h search.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + event.h ../src_3rd/librnd/core/event.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_3rd/librnd/core/compat_misc.h obj_rat_draw.h data_it.h \ + ../src_3rd/librnd/core/grid.h route_style.h \ + ../src_3rd/librnd/core/hidlib_conf.h obj_subc_parent.h +conf_act.o: conf_act.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/hidlib_conf.h \ + funchash_core.h ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + route_style.h ../src_3rd/librnd/core/tool.h +conf_core.o: conf_core.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h conf_core.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf_hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/genht/htpp.h \ + ../src_3rd/genht/hash.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h conf_core_fields.h +conf_internal.o: conf_internal.c +crosshair.o: crosshair.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + data.h buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + draw_wireframe.h search.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid_inlines.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/poly/offset.h \ + find.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h event.h \ + ../src_3rd/librnd/core/event.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h ../src_3rd/librnd/core/grid.h \ + obj_line_draw.h obj_arc_draw.h obj_text_draw.h obj_pstk_draw.h \ + obj_gfx_draw.h route_draw.h obj_arc_ui.h obj_subc_parent.h \ + ../src_3rd/librnd/core/tool.h +data.o: data.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h data_list.h data_it.h list_common.h \ + ../src_3rd/librnd/core/compat_misc.h layer_it.h operation.h undo_old.h \ + undo.h ../src_3rd/libuundo/uundo.h obj_pstk_draw.h draw.h \ + obj_text_draw.h obj_poly_draw.h obj_arc_draw.h obj_line_draw.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h +draw.o: draw.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/math_helper.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + ../src_3rd/librnd/core/event.h rotate.h ../src_3rd/librnd/core/rotate.h \ + ../src_3rd/librnd/core/compat_misc.h stub_draw.h layer_ui.h \ + ../src_3rd/librnd/core/hid_inlines.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h obj_pstk_draw.h \ + obj_line_draw.h obj_arc_draw.h obj_rat_draw.h obj_poly_draw.h \ + obj_text_draw.h obj_subc_parent.h obj_gfx_draw.h draw_label_smart.c \ + draw_composite.c draw_ly_spec.c +drc.o: drc.c ../config.h ../src_3rd/librnd/config.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h ../src_3rd/librnd/core/hidlib.h drc.h \ + view.h idpath.h ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h conf_core.h \ + ../src_3rd/librnd/core/compat_misc.h event.h \ + ../src_3rd/librnd/core/event.h +event.o: event.c ../config.h ../src_3rd/librnd/config.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/hidlib.h +extobj.o: extobj.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genht/htsi.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + attrib.h global_typedefs.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h data_it.h data_list.h remove.h \ + operation.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h extobj.h \ + board.h vtroutestyle.h rats_patch.h obj_subc_parent.h draw.h +extobj_act.o: extobj_act.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + funchash_core.h ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_3rd/librnd/core/hid_dad.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_dad_spin.h search.h layer.h attrib.h \ + global_typedefs.h obj_common.h flag.h data_parent.h obj_arc_list.h \ + obj_arc.h obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h \ + ../src_3rd/librnd/core/tool.h extobj.h board.h vtroutestyle.h \ + layer_grp.h rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h \ + crosshair.h route.h buffer.h obj_rat_list.h obj_rat.h idpath.h \ + obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h obj_subc_parent.h draw.h +file_act.o: file_act.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h build_run.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + funchash_core.h ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + data.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h plug_import.h remove.h \ + operation.h draw.h event.h ../src_3rd/librnd/core/event.h find.h \ + search.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h layer_vis.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/tool.h netlist.h +find.o: find.c ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/ht_utils.h \ + find.h ../src_3rd/genht/htpp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h obj_subc_parent.h data.h layer.h \ + ../src_3rd/librnd/core/color.h attrib.h obj_common.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h obj_rat_list.h obj_rat.h layer_grp.h \ + idpath.h obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h find_geo.c obj_arc_ui.h \ + obj_pstk_inlines.h board.h vtroutestyle.h rats_patch.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h search.h \ + find_any_isect.c +flag.o: flag.c ../config.h ../src_3rd/librnd/config.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h operation.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h +flag_str.o: flag_str.c ../config.h ../src_3rd/librnd/config.h flag_str.h flag.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h obj_common.h attrib.h \ + global_typedefs.h data_parent.h +font.o: font.c ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/hash.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h obj_poly.h \ + ../src_3rd/genlist/gendlist.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + data_parent.h ../src_3rd/librnd/poly/polyarea.h obj_poly_list.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_arc.h obj_arc_list.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h board.h \ + ../src_3rd/genht/htsp.h vtroutestyle.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h \ + ../src_3rd/librnd/core/color.h obj_line_list.h obj_line.h \ + obj_text_list.h obj_text.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/error.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/paths.h \ + ../src_3rd/librnd/core/compat_misc.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/file_loaded.h \ + font_internal.c +font_act.o: font_act.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h plug_io.h vtlibrary.h \ + ../src_3rd/genvector/vts0.h event.h ../src_3rd/librnd/core/event.h +gui_act.o: gui_act.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h build_run.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/hidlib_conf.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/librnd/core/grid.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h change.h draw.h \ + search.h find.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/librnd/core/compat_misc.h event.h \ + ../src_3rd/librnd/core/event.h layer_ui.h layer_vis.h \ + ../src_3rd/librnd/core/hid_attrib.h operation.h obj_subc_op.h \ + route_style.h tool_logic.h +hid_cam.o: hid_cam.c ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h board.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h hid_cam.h ../src_3rd/librnd/core/hid_attrib.h \ + ../src_3rd/librnd/core/compat_misc.h layer_addr.h layer_vis.h plug_io.h \ + vtlibrary.h ../src_3rd/genvector/vts0.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h +hidlib_pcb.o: hidlib_pcb.c board.h ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/genvector/vtp0.h +ht_subc.o: ht_subc.c ../config.h ../src_3rd/librnd/config.h obj_subc_list.h \ + obj_subc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h layer.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h ../src_3rd/genht/ht.c \ + ../src_3rd/genht/ht_inlines.h +idpath.o: idpath.c ../config.h ../src_3rd/librnd/config.h idpath.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h \ + ../src_3rd/genlist/gentdlist_impl.c board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h vtroutestyle.h ../src_3rd/librnd/core/unit.h \ + layer.h ../src_3rd/librnd/core/color.h obj_arc_list.h obj_arc.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h ../src_3rd/librnd/core/rnd_printf.h +insert.o: insert.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + select.h operation.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + obj_line_op.h obj_arc_op.h obj_rat_op.h obj_poly_op.h +intersect.o: intersect.c ../config.h ../src_3rd/librnd/config.h intersect.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h +layer.o: layer.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/compat_misc.h \ + undo.h ../src_3rd/libuundo/uundo.h undo_old.h event.h \ + ../src_3rd/librnd/core/event.h layer_ui.h layer_vis.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + obj_pstk_inlines.h thermal.h operation.h \ + ../src_3rd/librnd/poly/polygon1_gen.h list_common.h +layer_addr.o: layer_addr.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/compat_misc.h \ + layer_addr.h +layer_grp.o: layer_grp.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/rnd_printf.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/funchash.h \ + funchash_core.h funchash_core_list.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h +layer_ui.o: layer_ui.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/genvector/vtp0.h layer_ui.h +layer_vis.o: layer_vis.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h layer_ui.h layer_vis.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/conf_hid.h +main.o: main.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/libminuid/libminuid.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h brave.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/compat_lrealpath.h buildin.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h build_run.h \ + ../src_3rd/librnd/core/file_loaded.h flag_str.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/error.h \ + plug_footprint.h plug_import.h event.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/funchash.h conf_core.h \ + ../src_3rd/librnd/core/hidlib_conf.h layer_vis.h layer_ui.h pcb_minuid.h \ + ../src_3rd/librnd/core/tool.h netlist.h extobj.h obj_subc_parent.h \ + draw.h ../src_3rd/librnd/core/pixmap.h ../src_3rd/librnd/core/actions.h \ + actions_pcb.h ../src_3rd/librnd/core/hid_init.h \ + ../src_3rd/librnd/core/compat_misc.h tool_logic.h pixmap_pcb.h \ + funchash_core.h funchash_core_list.h +main_act.o: main_act.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h actions_pcb.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/actions.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h build_run.h \ + ../src_3rd/librnd/core/safe_fs.h flag_str.h \ + ../src_3rd/librnd/core/hid_init.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h +move.o: move.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + move.h select.h operation.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h event.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/compat_misc.h \ + obj_arc_op.h obj_line_op.h obj_text_op.h obj_subc_op.h obj_poly_op.h \ + obj_pstk_op.h obj_rat_op.h obj_gfx_op.h +netlist.o: netlist.c ../config.h ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/genregex/regex_sei.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h board.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ + vtpadstack_t.h data_it.h event.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/compat_misc.h find.h obj_term.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h obj_rat_draw.h obj_subc_parent.h \ + search.h remove.h operation.h draw.h netlist.h \ + ../src_3rd/genlist/gentdlist_impl.c netlist_geo.c obj_pstk_inlines.h \ + thermal.h ../src_3rd/librnd/poly/polygon1_gen.h +netlist_act.o: netlist_act.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genregex/regex_sei.h ../src_3rd/genregex/regex_templ.h \ + ../src_3rd/genregex/regex.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h data.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h data_it.h board.h vtroutestyle.h rats_patch.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/compat_misc.h \ + netlist.h find.h obj_term.h search.h obj_subc_parent.h +obj_arc.o: obj_arc.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + rotate.h ../src_3rd/librnd/core/rotate.h \ + ../src_3rd/librnd/core/compat_misc.h move.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + thermal.h operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + draw_wireframe.h ../src_3rd/librnd/core/hid_inlines.h obj_arc_op.h \ + obj_subc_parent.h obj_hash.h obj_arc_draw.h draw.h +obj_arc_list.o: obj_arc_list.c obj_arc_list.h obj_common.h flag.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/config.h \ + attrib.h global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.c +obj_arc_ui.o: obj_arc_ui.c ../config.h ../src_3rd/librnd/config.h obj_arc_ui.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/hidlib.h obj_line.h \ + ../src_3rd/genlist/gendlist.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + data_parent.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h route.h \ + obj_arc.h +obj_common.o: obj_common.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + flag_str.h flag.h ../src_3rd/librnd/core/error.h obj_common.h attrib.h \ + global_typedefs.h data_parent.h obj_arc_ui.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/hidlib.h obj_line.h ../src_3rd/genlist/gendlist.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h route.h obj_pstk.h layer.h \ + obj_arc_list.h obj_arc.h obj_line_list.h obj_poly_list.h obj_text_list.h \ + obj_text.h font.h ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h \ + obj_pstk_shape.h polygon.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h vtpadstack_t.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h obj_subc_parent.h data.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h ht_subc.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + vtpadstack.h obj_term.h extobj.h board.h vtroutestyle.h rats_patch.h \ + draw.h +obj_gfx.o: obj_gfx.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/hid_inlines.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h route.h \ + buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + rotate.h ../src_3rd/librnd/core/rotate.h move.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + draw_wireframe.h pixmap_pcb.h ../src_3rd/librnd/core/pixmap.h \ + obj_gfx_op.h operation.h obj_subc_parent.h obj_hash.h draw.h \ + obj_gfx_draw.h +obj_gfx_list.o: obj_gfx_list.c obj_gfx_list.h obj_common.h flag.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/config.h \ + attrib.h global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h obj_gfx.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.c +obj_line.o: obj_line.c ../config.h ../src_3rd/librnd/config.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h vtroutestyle.h ../src_3rd/librnd/core/unit.h \ + attrib.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h move.h search.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + thermal.h operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_3rd/librnd/core/compat_misc.h rotate.h \ + ../src_3rd/librnd/core/rotate.h ../src_3rd/librnd/core/hid_inlines.h \ + obj_line_op.h obj_subc_parent.h obj_hash.h draw_wireframe.h \ + obj_line_draw.h draw.h obj_rat_draw.h obj_pstk_draw.h \ + ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h +obj_line_drcenf.o: obj_line_drcenf.c ../config.h ../src_3rd/librnd/config.h \ + conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/math_helper.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h find.h +obj_line_list.o: obj_line_list.c obj_line_list.h obj_line.h \ + ../src_3rd/genlist/gendlist.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/config.h attrib.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.c +obj_pinvia_therm.o: obj_pinvia_therm.c ../config.h ../src_3rd/librnd/config.h \ + board.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h polygon.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/polygon1_gen.h obj_pinvia_therm.h +obj_poly.o: obj_poly.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + ../src_3rd/librnd/poly/polygon1_gen.h ../src_3rd/librnd/poly/offset.h \ + rotate.h ../src_3rd/librnd/core/rotate.h \ + ../src_3rd/librnd/core/compat_misc.h search.h thermal.h operation.h \ + ../src_3rd/librnd/core/hid_inlines.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + obj_poly_op.h obj_poly_draw.h draw.h obj_term.h obj_subc_parent.h \ + obj_hash.h obj_poly_draw_helper.c +obj_poly_list.o: obj_poly_list.c obj_poly_list.h obj_poly.h ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/genlist/gendlist.h obj_common.h flag.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h attrib.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h \ + ../src_3rd/librnd/poly/polyarea.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.c +obj_pstk.o: obj_pstk.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + route.h buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + data_list.h draw.h draw_wireframe.h obj_pstk_draw.h obj_pstk_inlines.h \ + thermal.h operation.h ../src_3rd/librnd/poly/polygon1_gen.h \ + obj_pstk_op.h obj_subc_parent.h obj_hash.h \ + ../src_3rd/librnd/core/compat_misc.h search.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hid_inlines.h \ + ../src_3rd/librnd/poly/offset.h obj_pstk_op.c rotate.h \ + ../src_3rd/librnd/core/rotate.h +obj_pstk_act.o: obj_pstk_act.c ../config.h ../src_3rd/librnd/config.h obj_pstk.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h layer.h \ + ../src_3rd/librnd/core/color.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h obj_pstk_shape.h polygon.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h vtpadstack_t.h obj_pstk_inlines.h \ + board.h ../src_3rd/genht/htsp.h vtroutestyle.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h vtpadstack.h thermal.h \ + operation.h ../src_3rd/librnd/poly/polygon1_gen.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/actions.h search.h data_list.h +obj_pstk_list.o: obj_pstk_list.c obj_pstk_list.h obj_pstk.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/config.h attrib.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.c +obj_pstk_proto.o: obj_pstk_proto.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/compat_misc.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h data.h \ + crosshair.h ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + route.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + data_list.h obj_pstk_op.h operation.h obj_pstk_inlines.h thermal.h \ + ../src_3rd/librnd/poly/polygon1_gen.h rotate.h \ + ../src_3rd/librnd/core/rotate.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h obj_hash.h funchash_core.h ../src_3rd/librnd/core/funchash.h \ + funchash_core_list.h ../src_3rd/librnd/poly/offset.h +obj_rat.o: obj_rat.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h data_it.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/hid_inlines.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h search.h obj_line_draw.h draw.h obj_rat_op.h operation.h \ + obj_rat_draw.h +obj_rat_list.o: obj_rat_list.c ../config.h ../src_3rd/librnd/config.h layer_grp.h \ + layer.h globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h obj_rat.h \ + idpath.h obj_rat_list.h ../src_3rd/genlist/gentdlist_impl.c +obj_subc.o: obj_subc.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/genht/ht_utils.h buffer.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h layer.h ../src_3rd/librnd/core/color.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h brave.h data.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h data_it.h obj_subc_op.h \ + operation.h obj_subc_parent.h obj_poly_op.h obj_pstk_inlines.h thermal.h \ + ../src_3rd/librnd/poly/polygon1_gen.h obj_pstk_draw.h draw.h \ + obj_line_op.h obj_term.h obj_text_draw.h draw_wireframe.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h move.h \ + ../src_3rd/librnd/core/compat_misc.h pcb_minuid.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/hid_inlines.h extobj.h +obj_subc_hash.o: obj_subc_hash.c ../config.h ../src_3rd/librnd/config.h data.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h +obj_subc_list.o: obj_subc_list.c ../config.h ../src_3rd/librnd/config.h obj_subc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h obj_common.h flag.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h attrib.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h layer.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h obj_subc_list.h ht_subc.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h \ + ../src_3rd/genlist/gentdlist_impl.c +obj_term.o: obj_term.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h change.h board.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h layer.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/color.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/compat_misc.h \ + obj_term.h obj_subc_parent.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/rnd_printf.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h +obj_text.o: obj_text.c ../config.h ../src_3rd/librnd/config.h rotate.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rotate.h \ + ../src_3rd/librnd/core/compat_misc.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h vtroutestyle.h ../src_3rd/librnd/core/unit.h \ + attrib.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/hid_inlines.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h ../src_3rd/librnd/poly/offset.h \ + event.h ../src_3rd/librnd/core/event.h obj_text_op.h operation.h \ + obj_poly_draw.h draw.h obj_arc_draw.h obj_subc_parent.h obj_hash.h \ + obj_line_draw.h obj_text_draw.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h +obj_text_list.o: obj_text_list.c obj_poly_list.h obj_poly.h ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/genlist/gendlist.h obj_common.h flag.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h attrib.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h \ + ../src_3rd/librnd/poly/polyarea.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_arc_list.h obj_arc.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genlist/gentdlist_impl.c +object_act.o: object_act.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h data.h layer.h attrib.h \ + global_typedefs.h obj_common.h flag.h data_parent.h obj_arc_list.h \ + obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + board.h vtroutestyle.h rats_patch.h ../src_3rd/librnd/core/tool.h \ + change.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h event.h \ + ../src_3rd/librnd/core/event.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_3rd/librnd/core/funchash_core.h \ + ../src_3rd/librnd/core/funchash_core_list.h search.h draw.h move.h \ + remove.h operation.h actions_pcb.h ../src_3rd/librnd/core/compat_misc.h \ + layer_vis.h rotate.h ../src_3rd/librnd/core/rotate.h \ + ../src_3rd/librnd/core/actions.h view.h +operation.o: operation.c ../config.h ../src_3rd/librnd/config.h operation.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h vtroutestyle.h ../src_3rd/librnd/core/unit.h \ + attrib.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h brave.h extobj.h obj_subc_parent.h draw.h +pcb_menu_default.o: pcb_menu_default.c +pcb_minuid.o: pcb_minuid.c ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/config.h pcb_minuid.h +pixmap_pcb.o: pixmap_pcb.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/pixmap.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/error.h \ + pixmap_pcb.h ../src_3rd/genht/htpp.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + data_parent.h +plug_footprint.o: plug_footprint.c ../config.h ../src_3rd/librnd/config.h \ + plug_footprint.h vtlibrary.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h data.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + attrib.h global_typedefs.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/librnd/core/plugins.h \ + ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h conf_core.h \ + actions_pcb.h plug_io.h ../src_3rd/genvector/vts0.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/compat_misc.h \ + event.h ../src_3rd/librnd/core/event.h +plug_footprint_act.o: plug_footprint_act.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h ../src_3rd/librnd/core/hidlib.h \ + plug_footprint.h vtlibrary.h data.h crosshair.h route.h buffer.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h +plug_import.o: plug_import.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h plug_import.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/safe_fs.h ../src_3rd/librnd/core/compat_fs.h +plug_io.o: plug_io.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h change.h board.h vtroutestyle.h \ + attrib.h global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + plug_io.h vtlibrary.h ../src_3rd/genvector/vts0.h remove.h operation.h \ + ../src_3rd/librnd/core/paths.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/plugins.h ../src_3rd/puplug/puplug.h \ + ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ + ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ + ../src_3rd/puplug/error.h ../src_3rd/librnd/core/hid_menu.h \ + ../src_3rd/librnd/core/hid_cfg.h ../src_3rd/librnd/core/hid_menu.h \ + event.h ../src_3rd/librnd/core/event.h \ + ../src_3rd/librnd/core/compat_misc.h route_style.h \ + ../src_3rd/librnd/core/compat_fs.h \ + ../src_3rd/librnd/core/compat_lrealpath.h layer_vis.h \ + ../src_3rd/librnd/core/safe_fs.h plug_footprint.h \ + ../src_3rd/librnd/core/file_loaded.h ../src_3rd/librnd/core/tool.h \ + view.h +polygon.o: polygon.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ + remove.h operation.h search.h thermal.h \ + ../src_3rd/librnd/poly/polygon1_gen.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h obj_poly_draw.h obj_text_draw.h \ + ../src_3rd/librnd/poly/self_isc.h event.h ../src_3rd/librnd/core/event.h +polygon_act.o: polygon_act.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h board.h \ + vtroutestyle.h attrib.h global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h draw.h search.h \ + ../src_3rd/librnd/core/tool.h ../src_3rd/librnd/core/actions.h +rats_act.o: rats_act.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h find.h remove.h operation.h \ + funchash_core.h ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/funchash_core.h \ + ../src_3rd/librnd/core/funchash_core_list.h netlist.h draw.h \ + obj_rat_draw.h +rats_patch.o: rats_patch.c rats_patch.h board.h ../config.h \ + ../src_3rd/librnd/config.h ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/genht/hash.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h data.h crosshair.h \ + route.h buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h \ + obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + obj_pstk_list.h obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h move.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/safe_fs.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + funchash_core.h ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + search.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h conf_core.h \ + netlist.h +remove.o: remove.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h draw.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h extobj.h data.h crosshair.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + obj_subc_parent.h remove.h operation.h select.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h obj_arc_op.h obj_line_op.h \ + obj_poly_op.h obj_text_op.h obj_rat_op.h obj_subc_op.h obj_pstk_op.h \ + obj_gfx_op.h +remove_act.o: remove_act.c ../config.h ../src_3rd/librnd/config.h data.h \ + globalconst.h ../src_3rd/librnd/core/globalconst.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h layer.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/hidlib.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/tool.h remove.h operation.h board.h \ + vtroutestyle.h rats_patch.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h +rotate.o: rotate.c ../config.h ../src_3rd/librnd/config.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h rotate.h ../src_3rd/librnd/core/rotate.h \ + ../src_3rd/librnd/core/compat_misc.h search.h select.h operation.h \ + undo.h ../src_3rd/libuundo/uundo.h undo_old.h event.h \ + ../src_3rd/librnd/core/event.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h obj_arc_op.h obj_line_op.h \ + obj_poly_op.h obj_text_op.h obj_subc_op.h obj_pstk_op.h obj_gfx_op.h \ + obj_line_draw.h obj_rat_draw.h +route.o: route.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/compat_misc.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h \ + ../src_3rd/librnd/core/math_helper.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + extobj.h obj_subc_parent.h draw.h find.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h obj_line_draw.h obj_arc_draw.h \ + route_draw.h obj_line_op.h operation.h draw_wireframe.h +route_style.o: route_style.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h route_style.h vtroutestyle.h attrib.h \ + global_typedefs.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genvector/vtp0.h \ + ../src_3rd/librnd/core/list_conf.h ../src_3rd/genlist/gentdlist_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/librnd/core/misc_util.h board.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h obj_gfx_list.h obj_gfx.h \ + layer_grp.h rats_patch.h ../src_3rd/librnd/core/hidlib.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h conf_core.h \ + event.h ../src_3rd/librnd/core/event.h +search.o: search.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + actions_pcb.h board.h vtroutestyle.h attrib.h global_typedefs.h layer.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/actions.h find.h search.h select.h operation.h \ + obj_subc_parent.h obj_pstk_inlines.h thermal.h \ + ../src_3rd/librnd/poly/polygon1_gen.h +select.o: select.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/librnd/core/hidlib_conf.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h \ + data_it.h draw.h search.h select.h operation.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h find.h extobj.h obj_subc_parent.h \ + ../src_3rd/librnd/core/compat_misc.h obj_arc_draw.h obj_line_draw.h \ + obj_poly_draw.h obj_text_draw.h obj_rat_draw.h obj_pstk_draw.h \ + obj_gfx_draw.h ../src_3rd/genregex/regex_sei.h \ + ../src_3rd/genregex/regex_templ.h ../src_3rd/genregex/regex.h +select_act.o: select_act.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h \ + ../src_3rd/librnd/core/tool.h select.h operation.h draw.h remove.h \ + move.h tool_logic.h ../src_3rd/librnd/core/grid.h \ + ../src_3rd/librnd/core/hid_attrib.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/actions.h +stub_draw.o: stub_draw.c ../config.h ../src_3rd/librnd/config.h stub_draw.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h draw.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h attrib.h global_typedefs.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genvector/gds_char.h obj_gfx_list.h \ + obj_gfx.h obj_text_draw.h +thermal.o: thermal.c ../config.h ../src_3rd/librnd/config.h thermal.h obj_common.h \ + flag.h globalconst.h ../src_3rd/librnd/core/globalconst.h attrib.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h operation.h layer.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h \ + ../src_3rd/librnd/poly/polygon1_gen.h \ + ../src_3rd/librnd/core/compat_misc.h ../src_3rd/librnd/core/rnd_printf.h \ + data.h crosshair.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/hidlib.h route.h \ + buffer.h ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h \ + obj_rat_list.h obj_rat.h layer_grp.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h undo.h ../src_3rd/libuundo/uundo.h \ + undo_old.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + obj_pstk_inlines.h board.h vtroutestyle.h rats_patch.h \ + obj_pinvia_therm.h funchash_core.h ../src_3rd/librnd/core/funchash.h \ + funchash_core_list.h +tool_logic.o: tool_logic.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/librnd/core/hidlib_conf.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/librnd/core/color.h event.h \ + ../src_3rd/librnd/core/event.h ../src_3rd/librnd/core/hidlib.h \ + ../src_3rd/librnd/core/grid.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/core/misc_util.h ../src_3rd/libfungw/fungw.h \ + ../src_3rd/genht/htpp.h ../src_3rd/librnd/core/tool.h \ + ../src_3rd/librnd/core/conf_hid.h board.h vtroutestyle.h attrib.h \ + global_typedefs.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h obj_common.h flag.h data_parent.h \ + obj_arc_list.h obj_arc.h ../src_3rd/genlist/gendlist.h obj_line_list.h \ + obj_line.h obj_poly_list.h obj_poly.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h obj_gfx_list.h \ + obj_gfx.h layer_grp.h rats_patch.h conf_core.h crosshair.h route.h \ + data.h buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h \ + obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h tool_logic.h +undo.o: undo.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/libuundo/uundo_debug.h ../src_3rd/libuundo/uundo.h board.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h change.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h event.h ../src_3rd/librnd/core/event.h \ + insert.h remove.h operation.h rotate.h ../src_3rd/librnd/core/rotate.h \ + ../src_3rd/librnd/core/compat_misc.h search.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h flag_str.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/librnd/core/list_conf.h \ + obj_poly_draw.h +undo_act.o: undo_act.c ../config.h ../src_3rd/librnd/config.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h ../src_3rd/librnd/core/rnd_printf.h \ + ../src_3rd/genvector/gds_char.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/librnd/core/unit.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/genht/htsp.h ../src_3rd/genht/ht.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + board.h vtroutestyle.h attrib.h global_typedefs.h layer.h obj_common.h \ + flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h obj_line_list.h obj_line.h obj_poly_list.h \ + obj_poly.h ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h \ + font.h ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + ../src_3rd/librnd/core/hidlib.h ../src_3rd/librnd/core/actions.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/librnd/core/error.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h data.h crosshair.h \ + route.h buffer.h obj_rat_list.h obj_rat.h idpath.h obj_subc_list.h \ + obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ../src_3rd/librnd/poly/rtree2_compat.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ht_subc.h ../src_3rd/genht/ht.h \ + ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ + obj_pstk_shape.h polygon.h vtpadstack_t.h \ + ../src_3rd/librnd/core/compat_misc.h funchash_core.h \ + ../src_3rd/librnd/core/funchash.h funchash_core_list.h undo.h \ + ../src_3rd/libuundo/uundo.h undo_old.h undo_act.h search.h \ + obj_line_draw.h draw.h ../src_3rd/librnd/core/tool.h +undo_old.o: undo_old.c ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/libuundo/uundo.h board.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h attrib.h global_typedefs.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h layer.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/core/color.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ + ../src_3rd/librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ + ../src_3rd/genht/htip.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genvector/gds_char.h obj_gfx_list.h obj_gfx.h layer_grp.h \ + rats_patch.h ../src_3rd/librnd/core/hidlib.h change.h data.h crosshair.h \ + ../src_3rd/librnd/core/hid.h ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/error.h route.h buffer.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htpp.h obj_rat_list.h \ + obj_rat.h idpath.h obj_subc_list.h obj_subc.h \ + ../src_3rd/libminuid/libminuid.h ../src_3rd/librnd/poly/rtree2_compat.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ht_subc.h ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h \ + obj_pstk.h ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h draw.h move.h extobj.h obj_subc_parent.h \ + insert.h remove.h operation.h rotate.h ../src_3rd/librnd/core/rotate.h \ + ../src_3rd/librnd/core/compat_misc.h search.h undo.h undo_old.h \ + flag_str.h conf_core.h ../src_3rd/librnd/core/conf.h \ + ../src_3rd/librnd/core/rnd_printf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/librnd/core/list_conf.h netlist.h obj_poly_draw.h obj_term.h \ + brave.h +view.o: view.c ../config.h ../src_3rd/librnd/config.h idpath.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h attrib.h global_typedefs.h \ + ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h view.h \ + ../src_3rd/libfungw/fungw.h ../src_3rd/genht/htsp.h \ + ../src_3rd/genht/ht.h ../src_3rd/genht/htpp.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/genlist/gentdlist_impl.c ../src_3rd/liblihata/dom.h \ + ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ + ../src_3rd/librnd/core/actions.h ../src_3rd/librnd/core/hid.h \ + ../src_3rd/librnd/core/error.h ../src_3rd/librnd/core/compat_misc.h \ + ../src_3rd/librnd/core/rnd_printf.h conf_core.h \ + ../src_3rd/librnd/core/conf.h ../src_3rd/liblihata/lihata.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/librnd/core/list_conf.h \ + ../src_3rd/librnd/core/color.h +vtlibrary.o: vtlibrary.c vtlibrary.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +vtpadstack.o: vtpadstack.c obj_pstk.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genvector/vtp0.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h obj_common.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/config.h attrib.h \ + global_typedefs.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/core/rnd_bool.h data_parent.h layer.h \ + ../src_3rd/librnd/core/color.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gendlist.h \ + ../src_3rd/genlist/gentdlist_undef.h obj_line_list.h obj_line.h \ + obj_poly_list.h obj_poly.h ../config.h ../src_3rd/librnd/poly/polyarea.h \ + obj_text_list.h obj_text.h font.h ../src_3rd/genht/htip.h \ + ../src_3rd/genht/ht.h ../src_3rd/librnd/core/box.h \ + ../src_3rd/librnd/core/math_helper.h ../src_3rd/librnd/core/misc_util.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/genvector/gds_char.h \ + obj_gfx_list.h obj_gfx.h obj_pstk_shape.h polygon.h \ + ../src_3rd/librnd/poly/rtree.h ../src_3rd/genrtree/genrtree_api.h \ + ../src_3rd/librnd/poly/rtree2_compat.h vtpadstack_t.h vtpadstack.h \ + ../src_3rd/genvector/genvector_impl.c +vtpadstack_t.o: vtpadstack_t.c ../src_3rd/genvector/vtp0.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h ../src_3rd/genvector/gds_char.h \ + ../src_3rd/librnd/core/color.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/rnd_bool.h vtpadstack_t.h \ + obj_pstk_shape.h ../src_3rd/librnd/core/unit.h polygon.h ../config.h \ + global_typedefs.h flag.h globalconst.h \ + ../src_3rd/librnd/core/globalconst.h ../src_3rd/librnd/poly/rtree.h \ + ../src_3rd/genrtree/genrtree_api.h ../src_3rd/librnd/core/math_helper.h \ + ../src_3rd/librnd/poly/polyarea.h ../src_3rd/librnd/poly/rtree2_compat.h \ + layer.h attrib.h obj_common.h data_parent.h obj_arc_list.h obj_arc.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_impl.h \ + ../src_3rd/genlist/gendlist.h ../src_3rd/genlist/gentdlist_undef.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h obj_text_list.h \ + obj_text.h font.h ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h \ + ../src_3rd/librnd/core/box.h ../src_3rd/librnd/core/misc_util.h \ + obj_gfx_list.h obj_gfx.h ../src_3rd/genvector/genvector_impl.c +vtr0.o: vtr0.c vtr0.h ../config.h ../src_3rd/librnd/config.h \ + ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c +vtroutestyle.o: vtroutestyle.c vtroutestyle.h \ + ../src_3rd/librnd/core/unit.h ../src_3rd/librnd/core/global_typedefs.h \ + ../src_3rd/librnd/config.h ../src_3rd/librnd/core/rnd_bool.h attrib.h \ + global_typedefs.h ../src_3rd/genvector/genvector_impl.h \ + ../src_3rd/genvector/genvector_undef.h \ + ../src_3rd/genvector/genvector_impl.c Index: tags/2.3.0/src/Makefile.in =================================================================== --- tags/2.3.0/src/Makefile.in (nonexistent) +++ tags/2.3.0/src/Makefile.in (revision 33253) @@ -0,0 +1,715 @@ +append /local/pcb/CFLAGS {-I. -I.. -I../src_3rd -I../src -I../src_3rd/liblihata } +append /local/pcb/LDFLAGS cc/ldflags +append /local/pcb/LDFLAGS cc/rdynamic +append /local/pcb/LDFLAGS ?/local/pcb/cflags_profile +put /local/pcb/DEPCFLAGS {} +put /local/pcb/OBJS_3RDLIB {} +put /local/pcb/OBJS_HIDLIB {} +put /local/pcb/OBJS_HIDLIB_ONLY {} +put /local/pcb/OBJS_C99_HIDLIB_PLG {} +put /local/pcb/OBJS_HIDLIB_PLG {} + +if ?libs/script/fungw/presents +then + append /local/pcb/CFLAGS libs/script/fungw/cflags + append /local/pcb/LDFLAGS libs/script/fungw/ldflags + append /local/pcb/LIBRND_3RD_LDFLAGS libs/script/fungw/ldflags +else +# no system installed fungw means we need to use local genht + append /local/pcb/OBJS_3RDLIB [@ + ../src_3rd/genht/hash.o + ../src_3rd/genht/htsp.o + ../src_3rd/genht/htss.o + ../src_3rd/genht/htsi.o + ../src_3rd/genht/htpi.o + ../src_3rd/genht/htip.o + ../src_3rd/genht/htpp.o + @] +# local compilation of fungw objects + append /local/pcb/OBJS_3RDLIB [@ + ../src_3rd/libfungw/fungw.o + ../src_3rd/libfungw/fungw_conv.o + ../src_3rd/libfungw/fungw_ptr.o + ../src_3rd/libfungw/fungw_debug.o + ../src_3rd/libfungw/fungw_call.o + ../src_3rd/libfungwbind/c/fungw_c.o + @] + put /local/pcb/LIBRND_3RD_LDFLAGS {} +end + +# These files are to be generated before make dep is run +put /local/pcb/DEPDEPS { $(LIBRND)/core/hidlib_conf_fields.h conf_core_fields.h conf_internal.c defpcb_internal.c buildin.c buildin.hidlib.c pcb_menu_default.c } + +include {../src_3rd/librnd/scconfig/template/debug.tmpasm} + +# main: objects +# hidlib will be a library that provides: +# - the plugin system +# - the conf system +# - some basic/generic types like pcb_coord_t +# - the HID infra, including DAD +# but nothing else; in short the HID part of pcb-rnd for developing a +# GUI program based on pcb-rnd HIDs. + +# These have constructs that are not c89 strictly speaking but are +# effectively c89; typical example is casting a function pointer to a +# data pointer for dlsym(). +put /local/pcb/OBJS_C99_HIDLIB [@ + $(LIBRND)/core/fptr_cast.o +@] + +append /local/pcb/OBJS_HIDLIB [@ + $(LIBRND)/core/actions.o + $(LIBRND)/core/base64.o + $(LIBRND)/core/box.o + $(LIBRND)/core/color.o + $(LIBRND)/core/conf.o + $(LIBRND)/core/conf_act.o + $(LIBRND)/core/conf_hid.o + $(LIBRND)/core/compat_fs.o + $(LIBRND)/core/compat_lrealpath.o + $(LIBRND)/core/compat_misc.o + $(LIBRND)/core/error.o + $(LIBRND)/core/event.o + $(LIBRND)/core/file_loaded.o + $(LIBRND)/core/funchash.o + $(LIBRND)/core/grid.o + $(LIBRND)/core/gui_act.o + $(LIBRND)/core/heap.o + $(LIBRND)/core/hid.o + $(LIBRND)/core/hid_attrib.o + $(LIBRND)/core/hid_cfg.o + $(LIBRND)/core/hid_cfg_action.o + $(LIBRND)/core/hid_cfg_input.o + $(LIBRND)/core/hid_dlg.o + $(LIBRND)/core/hid_dad.o + $(LIBRND)/core/hid_dad_tree.o + $(LIBRND)/core/hid_dad_spin.o + $(LIBRND)/core/hid_dad_unit.o + $(LIBRND)/core/hid_init.o + $(LIBRND)/core/hid_menu.o + $(LIBRND)/core/hid_nogui.o + $(LIBRND)/core/hidlib.o + $(LIBRND)/core/hidlib_conf.o + $(LIBRND)/core/list_conf.o + $(LIBRND)/core/main_act.o + $(LIBRND)/core/misc_util.o + $(LIBRND)/core/paths.o + $(LIBRND)/core/rnd_bool.o + $(LIBRND)/core/rnd_printf.o + $(LIBRND)/core/plugins.o + $(LIBRND)/core/pixmap.o + $(LIBRND)/core/safe_fs.o + $(LIBRND)/core/tool.o + $(LIBRND)/core/unit.o + $(LIBRND)/core/vtc0.o +@] + +put /local/pcb/OBJS_POLYLIB [@ + $(LIBRND)/poly/polyarea.o + $(LIBRND)/poly/polygon1_gen.o + $(LIBRND)/poly/offset.o + $(LIBRND)/poly/self_isc.o + $(LIBRND)/poly/rtree.o +@] + +append /local/pcb/OBJS_3RDLIB [@ + ../src_3rd/liblihata/parser.o + ../src_3rd/liblihata/dom.o + ../src_3rd/liblihata/dom_list.o + ../src_3rd/liblihata/dom_hash.o + ../src_3rd/liblihata/dom_table.o + ../src_3rd/liblihata/lihata.o + ../src_3rd/liblihata/hash_str.o + ../src_3rd/liblihata/tree.o + ../src_3rd/liblihata/tree_list.o + ../src_3rd/liblihata/tree_hash.o + ../src_3rd/liblihata/tree_table.o + ../src_3rd/liblihata/tree_symlink.o + ../src_3rd/liblihata/tree_path.o + ../src_3rd/liblhtpers/lhtpers.o + ../src_3rd/genvector/gds_char.o + ../src_3rd/genvector/vtp0.o + ../src_3rd/genvector/vtd0.o + ../src_3rd/genvector/vts0.o + ../src_3rd/genvector/vti0.o + ../src_3rd/genvector/vtl0.o + ../src_3rd/genregex/regex_sei.o + ../src_3rd/genregex/regex_se.o + ../src_3rd/genregex/regex.o + ../src_3rd/libulzw/libulzw_comp.o + ../src_3rd/libulzw/libulzw_decomp.o +@] + +# these will be linked only to the hidlib, not to pcb-rnd +append /local/pcb/OBJS_HIDLIB_ONLY [@ + buildin.hidlib.o +@] + +put /local/pcb/OBJS_C99 /local/pcb/OBJS_C99_HIDLIB +put /local/pcb/OBJS /local/pcb/OBJS_HIDLIB +append /local/pcb/OBJS /local/pcb/OBJS_3RDLIB +append /local/pcb/OBJS /local/pcb/OBJS_POLYLIB +append /local/pcb/OBJS [@ + actions_pcb.o + attrib.o + board.o + brave.o + buffer.o + build_run.o + change.o + change_act.o + conf_act.o + conf_core.o + conf_internal.o + crosshair.o + data.o + draw.o + drc.o + event.o + extobj.o + extobj_act.o + font.o + font_act.o + file_act.o + find.o + flag.o + flag_str.o + gui_act.o + hid_cam.o + hidlib_pcb.o + ht_subc.o + idpath.o + insert.o + intersect.o + layer.o + layer_addr.o + layer_grp.o + layer_ui.o + layer_vis.o + main.o + main_act.o + move.o + netlist.o + netlist_act.o + object_act.o + obj_common.o + obj_arc.o + obj_arc_list.o + obj_arc_ui.o + obj_gfx.o + obj_gfx_list.o + obj_line.o + obj_line_drcenf.o + obj_line_list.o + obj_pstk.o + obj_pstk_act.o + obj_pstk_list.o + obj_pstk_proto.o + obj_pinvia_therm.o + obj_poly.o + obj_poly_list.o + obj_rat.o + obj_rat_list.o + obj_subc.o + obj_subc_hash.o + obj_subc_list.o + obj_term.o + obj_text.o + obj_text_list.o + operation.o + pcb_menu_default.o + pcb_minuid.o + pixmap_pcb.o + plug_import.o + plug_io.o + plug_footprint.o + plug_footprint_act.o + polygon.o + polygon_act.o + rats_act.o + rats_patch.o + remove.o + remove_act.o + rotate.o + route.o + route_style.o + search.o + select.o + select_act.o + stub_draw.o + thermal.o + tool_logic.o + undo.o + undo_act.o + undo_old.o + view.o + vtlibrary.o + vtpadstack.o + vtpadstack_t.o + vtr0.o + vtroutestyle.o + buildin.o + ../src_3rd/qparse/qparse.o + ../src_3rd/libuundo/uundo.o + ../src_3rd/libuundo/uundo_debug.o +@] + +put /local/pcb/LIBS_3RD [@ + ../src_3rd/puplug/libpuplug.a + ../src_3rd/libminuid/libminuid.a +@] + +put /local/pcb/LIBS /local/pcb/LIBS_3RD + +# We do not compile these in the executable but we need rules for these for utils +# e.g. ../src_3rd/genht/htsp.o +put /local/pcb/OBJS_UTIL [@ +@] + +#---- modules ----# +# extra rules for modules +put /local/pcb/RULES {} +put /local/pcb/CLEANFILES {} +put /local/pcb/CLEANRULES {} +put /local/pcb/EXEDEPS {} +put /local/pcb/all {} +put /local/pcb/buildin_init {} +put /local/pcb/rules/install_ {} +put /local/pcb/rules/install {} +put /local/pcb/rules/linstall {} +put /local/pcb/rules/uninstall {} +put /local/pcb/mod/OBJS {} +put /local/pcb/mod/OBJS_C99 {} +put /local/pcb/mod/CONF {} +put /local/pcb/mod/LDFLAGS {} +put /local/pcb/mod/CFLAGS {} +put /local/pcb/mod/YACC {} +put /local/pcb/mod/LEX {} +put /local/pcb/mod/BYACCIC {} +put /local/pcb/mod/UREGLEX {} + +put /local/pcb/tmpasm/buildin {../src_plugins/Buildin.tmpasm} +put /local/pcb/tmpasm/plugin {../src_plugins/Plugin.tmpasm} +put /local/pcb/tmpasm/plugin_local {../src_plugins/Plugin_local.tmpasm} +put /local/pcb/tmpasm/plugin_librnd {../src_plugins/Plugin_librnd.tmpasm} +put /local/pcb/tmpasm/disable {../src_plugins/Disable.tmpasm} +put /local/pcb/tmpasm/common_enabled {../src_plugins/Common_enabled.tmpasm} +put /local/pcb/tmpasm/plugin_sphash {../src_3rd/librnd/scconfig/template/plugin_sphash.tmpasm} +put /local/pcb/tmpasm/plugin_conf {../src_3rd/librnd/scconfig/template/plugin_conf.tmpasm} +put /local/pcb/tmpasm/plugin_intconf {../src_3rd/librnd/scconfig/template/plugin_intconf.tmpasm} +put /local/pcb/tmpasm/plugin_intmenu {../src_3rd/librnd/scconfig/template/plugin_intmenu.tmpasm} + +include {../src_plugins/plugins_ALL.tmpasm} + +# Lesstif requires that -lXm is before -lXt or else there is a runtime BadWindow error +order /local/pcb/LDFLAGS {-lXm} {before} {-lXt} + +# ---- logic ---- + + +# Clean up variables +uniq /local/pcb/OBJS +uniq /local/pcb/OBJS_C99 +uniq /local/pcb/OBJS_3RDLIB +uniq /local/pcb/OBJS_POLYLIB +uniq /local/pcb/OBJS_HIDLIB +uniq /local/pcb/OBJS_HIDLIB_ONLY +uniq /local/pcb/OBJS_C99_HIDLIB +uniq /local/pcb/OBJS_HIDLIB_PLG +uniq /local/pcb/OBJS_C99_HIDLIB_PLG +uniq /local/pcb/OBJS_UTIL +uniq /local/pcb/CFLAGS +uniq /local/pcb/CFLAGS_GENERIC +uniq /local/pcb/LDFLAGS +uniq /local/pcb/LIBS +uniq /local/pcb/LIBS_PRE +uniq /local/pcb/LIBS_3RD +uniq /local/pcb/EXEDEPS +uniq /local/pcb/CLEANFILES +uniq /local/pcb/DISTCLEANFILES +uniq /local/pcb/CLEANRULES +uniq /local/pcb/all +put /local/pcb/SRCS /local/pcb/OBJS +append /local/pcb/SRCS ?/local/pcb/OBJS_C99 +append /local/pcb/SRCS ?/local/pcb/OBJS_3RDLIB +append /local/pcb/SRCS ?/local/pcb/OBJS_POLYLIB +append /local/pcb/SRCS ?/local/pcb/OBJS_HIDLIB +append /local/pcb/SRCS ?/local/pcb/OBJS_HIDLIB_ONLY +gsub /local/pcb/SRCS {.o } {.c } + +# Makefile, static +print [@ +# *** DO NOT EDIT THIS FILE *** +# This file has been generated from Makefile.in by configure +# *** DO NOT EDIT THIS FILE *** + +ROOT=.. + +# plugin source +PLUGDIR=$(ROOT)/src_plugins +LIBRND_PLUGDIR=$(ROOT)/src_3rd/librnd/plugins + +# plugin source install - so that pcb-rnd runs from source properly +PLUGIDIR=plugins + +# src_3rd dir for the lib_ wrapper plugins +SRC_3RD_DIR=$(ROOT)/src_3rd + +@?/local/pcb/TOPVARS@ +OBJS=@/local/pcb/OBJS@ +OBJS_C99=@/local/pcb/OBJS_C99@ +OBJS_POLYLIB=@/local/pcb/OBJS_POLYLIB@ +OBJS_3RDLIB=@/local/pcb/OBJS_3RDLIB@ ../src_3rd/libminuid/*.o ../src_3rd/puplug/*.o +OBJS_HIDLIB=@/local/pcb/OBJS_HIDLIB@ +OBJS_HIDLIB_ONLY=@/local/pcb/OBJS_HIDLIB_ONLY@ +OBJS_C99_HIDLIB=@/local/pcb/OBJS_C99_HIDLIB@ +OBJS_HIDLIB_PLG=@/local/pcb/OBJS_HIDLIB_PLG@ +OBJS_C99_HIDLIB_PLG=@/local/pcb/OBJS_C99_HIDLIB_PLG@ +OBJS_UTIL=@/local/pcb/OBJS_UTIL@ +SRCS=@/local/pcb/SRCS@ +CFLAGS=@?cc/argstd/std_c99@ @/local/pcb/CFLAGS@ +C89FLAGS=@/local/pcb/c89flags@ @/local/pcb/CFLAGS@ +LDFLAGS=@/local/pcb/LDFLAGS@ +LIBS_PRE=@/local/pcb/LIBS_PRE@ +LIBS=@/local/pcb/LIBS@ @libs/socket/socket/ldflags@ -lm @?/target/libs/ldl@ +LIBS_3RD=@/local/pcb/LIBS_3RD@ +EXEDEPS=@/local/pcb/EXEDEPS@ +CLEANFILES=@/local/pcb/CLEANFILES@ +CLEANRULES=@/local/pcb/CLEANRULES@ +CC=@/target/cc/cc@ +AR=@/target/fstools/ar@ +HOSTCC=@/host/cc/cc@ +CQUOTE=$(ROOT)/scconfig/cquote +SPHASH_PATH=$(ROOT)/src_3rd/sphash +SPHASH=$(SPHASH_PATH)/sphash +PUPLUG=$(ROOT)/src_3rd/puplug/util/puplug +LIBMINUID_CFLAGS=@/local/pcb/CFLAGS_GENERIC@ +LIBMINUID_LDFLAGS=@cc/ldflags@ +GENLIST_CFLAGS=@/local/pcb/CFLAGS_GENERIC@ +GENLIST_LDFLAGS=@cc/ldflags@ +LIBRND=../src_3rd/librnd + +all: + $(MAKE) revcheck + $(MAKE) all_exe + $(MAKE) librnd + +include $(ROOT)/Makefile.conf + +revcheck: + cd $(ROOT)/scconfig && ./revtest Rev.stamp < Rev.tab + +all_exe: pcb-rnd$(EXE) @/local/pcb/all@ + +pcb-rnd$(EXE): $(OBJS) $(OBJS_C99) $(EXEDEPS) $(LIBS_3RD) + $(CC) $(OBJS) $(OBJS_C99) -o pcb-rnd$(EXE) $(LIBS_PRE) $(LDFLAGS) $(LIBS) + +### librnd, hidlib #### + +OBJS_HIDLIB_ALL = $(OBJS_HIDLIB_PLG) $(OBJS_C99_HIDLIB_PLG) $(OBJS_HIDLIB) $(OBJS_HIDLIB_ONLY) $(OBJS_C99_HIDLIB) +DEPS_HIDLIB_ALL = $(OBJS_HIDLIB_ALL) $(EXEDEPS) $(LIBS_3RD) $(LIBRND)/core/buildin.hidlib.h +@] + +switch cc/soname + case {^$} print [@ +SONAME_HID= +SONAME_3RD= +SONAME_POLY= +@] + end; + default print [@ +SONAME_HID=@cc/soname@librnd-hid.so.$(PCB_RND_VER_MAJOR) +SONAME_3RD=@cc/soname@librnd-3rd.so.$(PCB_RND_VER_MAJOR) +SONAME_POLY=@cc/soname@librnd-poly.so.$(PCB_RND_VER_MAJOR) +@] + end; +end + +print [@ + +librnd-hid.a: $(DEPS_HIDLIB_ALL) + $(AR) rvu librnd-hid.a $(OBJS_HIDLIB_ALL) + +librnd-3rd.a: $(OBJS_3RDLIB) + $(AR) rvu librnd-3rd.a $(OBJS_3RDLIB) + +librnd-poly.a: $(OBJS_POLYLIB) + $(AR) rvu librnd-poly.a $(OBJS_POLYLIB) + +librnd-hid.so.$(PCB_RND_VER): $(DEPS_HIDLIB_ALL) + $(CC) $(LDFLAGS) @?cc/ldflags_dynlib@ @?cc/so_undefined@ $(SONAME_HID) -o librnd-hid.so.$(PCB_RND_VER) $(OBJS_HIDLIB_ALL) + +librnd-3rd.so.$(PCB_RND_VER): $(OBJS_3RDLIB) + $(CC) @cc/ldflags@ @?cc/ldflags_dynlib@ @?cc/so_undefined@ $(SONAME_3RD) -o librnd-3rd.so.$(PCB_RND_VER) $(OBJS_3RDLIB) @/local/pcb/LIBRND_3RD_LDFLAGS@ @?/target/libs/ldl@ -lm + +librnd-poly.so.$(PCB_RND_VER): $(OBJS_POLYLIB) + $(CC) @cc/ldflags@ @?cc/ldflags_dynlib@ @?cc/so_undefined@ $(SONAME_POLY) -o librnd-poly.so.$(PCB_RND_VER) $(OBJS_POLYLIB) -lm + +HIDLIB_CLEAN_FILES=\ + librnd-hid.so.$(PCB_RND_VER) librnd-hid.a \ + librnd-3rd.so.$(PCB_RND_VER) librnd-3rd.a \ + librnd-poly.so.$(PCB_RND_VER) librnd-poly.a + +librnd: $(HIDLIB_CLEAN_FILES) + +### pcb-rnd infra ### + +$(SPHASH): $(SPHASH_PATH)/sphash.c + $(HOSTCC) $(SPHASH_PATH)/sphash.c -o $(SPHASH) + +# needed by gsch2pcb-rnd +../src_3rd/genlist/genadlist.o ../src_3rd/genlist/genlistalloc.o: + cd ../src_3rd/genlist && $(MAKE) GENLIST_CFLAGS="$(GENLIST_CFLAGS)" GENLIST_LDFLAGS="$(GENLIST_LDFLAGS)" CC=$(CC) + +buildin.c: $(PLUGDIR)/.builtin.pups $(PUPLUG) + cd $(PLUGDIR) && $(PUPLUG) buildin.c "-" < $(PLUGDIR)/.builtin.pups > $(ROOT)/src/buildin.c + +buildin.h: $(PLUGDIR)/.builtin.pups $(PUPLUG) + $(PUPLUG) buildin.h > buildin.h + +buildin.hidlib.c: $(PLUGDIR)/.builtin.hidlib.pups $(PUPLUG) + cd $(LIBRND_PLUGDIR) && ../../$(PUPLUG) buildin.c "-" < ../../$(PLUGDIR)/.builtin.hidlib.pups > ../../$(ROOT)/src/buildin.hidlib.c + +$(LIBRND)/core/buildin.hidlib.h: $(PLUGDIR)/.builtin.hidlib.pups $(PUPLUG) + $(PUPLUG) buildin.h > $(LIBRND)/core/buildin.hidlib.h + +../src_3rd/libminuid/libminuid.a: ../src_3rd/libminuid/libminuid.c ../src_3rd/libminuid/libminuid.h + cd ../src_3rd/libminuid && $(MAKE) libminuid.a LIBMINUID_CFLAGS="$(LIBMINUID_CFLAGS)" LIBMINUID_LDFLAGS="$(LIBMINUID_LDFLAGS)" CC=$(CC) +@] + +if sys/cross +then +print [@ +../src_3rd/puplug/libpuplug.a $(PUPLUG): + cd ../src_3rd/puplug && make clean + cd ../src_3rd/puplug && make util/puplug CC=$(HOSTCC) + cd ../src_3rd/puplug && rm *.o + cd ../src_3rd/puplug && make libpuplug.a CC=$(CC) +@] +else +print [@ +../src_3rd/puplug/libpuplug.a $(PUPLUG): + cd ../src_3rd/puplug && make libpuplug.a util/puplug +@] +end + +print [@ +##### module rules begin ##### + +@/local/pcb/RULES@ + +##### module rules end ##### + +### default menu embed +pcb_menu_default.c: pcb-menu-default.lht $(CQUOTE) + $(CQUOTE) -n rnd_hidlib_default_embedded_menu pcb_menu_default.c + +pcblib_DATA= \ + default_font \ + default2.lht \ + default4.lht \ + pcb-menu-default.lht + +EXTRA_DIST= \ + default_font \ + default2.lht \ + default4.lht \ + pcbtest.sh.in + +all-local: pcbtest.sh + +conf_core_fields.h: conf_core.h $(ROOT)/doc/conf/tree/rc.html + AWK=@/host/fstools/awk@ $(ROOT)/scconfig/gen_conf.sh < conf_core.h > conf_core_fields.h + +$(LIBRND)/core/hidlib_conf_fields.h: $(LIBRND)/core/hidlib_conf.h $(ROOT)/doc/conf/tree/rc.html + AWK=@/host/fstools/awk@ $(ROOT)/scconfig/gen_conf.sh < $(LIBRND)/core/hidlib_conf.h > $(LIBRND)/core/hidlib_conf_fields.h + +$(ROOT)/doc/conf/tree/rc.html: $(LIBRND)/core/hidlib_conf.h conf_core.h + cat conf_core.h $(LIBRND)/core/hidlib_conf.h | AWK=@/host/fstools/awk@ $(ROOT)/scconfig/gen_conf.sh $(ROOT)/doc/conf/tree > /dev/null + +conf_internal.c: pcb-conf.lht $(CQUOTE) + $(CQUOTE) -n pcb_conf_internal < pcb-conf.lht > conf_internal.c + +defpcb_internal.c: default4.lht + $(CQUOTE) -n default_pcb_internal < default4.lht > defpcb_internal.c + +# do not make this automatic, most users won't need to regenerate font_internal.c +gen_font: + $(ROOT)/util/devhelpers/font2c.sh < default_font > font_internal.c + +util_deps: $(OBJS) $(OBJS_UTIL) ../src_3rd/genlist/genadlist.o ../src_3rd/genlist/genlistalloc.o + +FORCE: + + +DISTCLEANFILES = Makefile.depgen core_lists.h buildin.c buildin.h buildin.hidlib.c $(LIBRND)/core/buildin.hidlib.h $(LIBRND)/core/compat_inc.h $(LIBRND)/core/hidlib_conf_fields.h conf_core_fields.h conf_internal.c defpcb_internal.c pcb_menu_default.c ../src_plugins/.builtin.pups ../src_plugins/.builtin.hidlib.pups $(LIBRND)/core/librnd.mak @/local/pcb/DISTCLEANFILES@ + +clean: $(CLEANRULES) + $(SCCBOX) rm -f -q pcb-rnd $(HIDLIB_CLEAN_FILES) $(OBJS) $(OBJS_C99) $(OBJS_HIDLIB_ONLY) $(CLEANFILES) + +distclean: FORCE + $(SCCBOX) rm -f -q $(DISTCLEANFILES) + +install_pcbrnd: + $(SCCBOX) mkdir -p "$(BINDIR)" "$(DATADIR)" "$(LIBDIR)" "$(LIBDIR)/plugins" "$(CONFDIR)" + $(SCCBOX) $(HOW) "pcb-rnd$(EXE)" "$(BINDIR)/pcb-rnd$(EXE)" + $(SCCBOX) $(HOW) "pcb-conf.lht" "$(CONFDIR)/pcb-conf.lht" + $(SCCBOX) $(HOW) "pcb-menu-default.lht" "$(CONFDIR)/pcb-menu-default.lht" + $(SCCBOX) $(HOW) "default2.lht" "$(DATADIR)/default2.lht" + $(SCCBOX) $(HOW) "default4.lht" "$(DATADIR)/default4.lht" + $(SCCBOX) $(HOW) "default_font" "$(DATADIR)/default_font"@/local/pcb/rules/install_@ + +install_librnd: librnd + $(MAKE) install_librnd_ + +install_librnd_: + $(SCCBOX) mkdir -p "$(HL_LIBDIR)/librnd" "$(HL_INCDIR)/core" "$(HL_INCDIR)/poly" "$(HL_INCDIR)/scconfig" "$(HL_INCDIR)/src_3rd/liblihata" "$(HL_INCDIR)/src_3rd/liblhtpers" "$(HL_INCDIR)/src_3rd/puplug" "$(HL_INCDIR)/src_3rd/libfungw" "$(HL_INCDIR)/src_3rd/genvector" "$(HL_INCDIR)/src_3rd/genregex" "$(HL_INCDIR)/src_3rd/genrtree" "$(HL_INCDIR)/src_3rd/genlist" "$(HL_INCDIR)/src_3rd/libulzw" "$(HL_INCDIR)/src_3rd/genht" "$(HL_INCDIR)/src_3rd/libfungwbind/c" "$(HL_SHAREDIR)" + $(SCCBOX) $(HOW) "librnd-hid.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER)" + $(SCCBOX) $(HOW) "librnd-hid.a" "$(HL_LIBDIR)/librnd-hid.a" + $(SCCBOX) $(HOW) "librnd-3rd.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-3rd.so.$(PCB_RND_VER)" + $(SCCBOX) $(HOW) "librnd-3rd.a" "$(HL_LIBDIR)/librnd-3rd.a" + $(SCCBOX) $(HOW) "librnd-poly.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-poly.so.$(PCB_RND_VER)" + $(SCCBOX) $(HOW) "librnd-poly.a" "$(HL_LIBDIR)/librnd-poly.a" + $(SCCBOX) $(HOW) "$(LIBRND)/core/librnd.mak" "$(HL_SHAREDIR)/librnd.mak" + $(SCCBOX) $(HOW) "../config.h" "$(HL_INCDIR)/core/config.h" + $(SCCBOX) $(HOW) "../src_3rd/puplug/util/puplug" "$(HL_LIBDIR)/librnd/puplug" + $(SCCBOX) $(HOW) "../scconfig/gen_conf.sh" "$(HL_LIBDIR)/librnd/gen_conf" + $(SCCBOX) $(HOW) "$(LIBRND)/scconfig/hooks_common.h" "$(HL_INCDIR)/scconfig/hooks_common.h" + $(SCCBOX) $(HOW) "$(LIBRND)/scconfig/plugin_3state.h" "$(HL_INCDIR)/scconfig/plugin_3state.h" + cd ../src_3rd/puplug && $(MAKE) install_hdr_ MKDR="../$(SCCBOX) mkdir -p" INST="../$(SCCBOX) $(HOW)" INCDIR="$(HL_INCDIR)/src_3rd/puplug" +@] + +# rndlib: build a list of header files to be installed with the hidlib +put /local/pcb/HDRS_3RDLIB /local/pcb/OBJS_3RDLIB +put /local/pcb/HDRS_HIDLIB /local/pcb/OBJS_HIDLIB +append /local/pcb/HDRS_HIDLIB /local/pcb/OBJS_POLYLIB +uniq /local/pcb/HDRS_3RDLIB +uniq /local/pcb/HDRS_HIDLIB +gsub /local/pcb/HDRS_HIDLIB {.o } {.h } +gsub /local/pcb/HDRS_3RDLIB {.o } {.h } + +# rndlib: corner case: some headers are not derived from the objects +sub /local/pcb/HDRS_HIDLIB {$(LIBRND)/core/hid_dlg.h } {} +sub /local/pcb/HDRS_HIDLIB {$(LIBRND)/core/conf_act.h } {} +sub /local/pcb/HDRS_HIDLIB {$(LIBRND)/core/gui_act.h } {} +sub /local/pcb/HDRS_HIDLIB {$(LIBRND)/core/main_act.h } {} +append /local/pcb/HDRS_HIDLIB {$(LIBRND)/config.h $(LIBRND)/core/global_typedefs.h $(LIBRND)/core/globalconst.h $(LIBRND)/core/math_helper.h $(LIBRND)/core/buildin.hidlib.h $(LIBRND)/core/hid_inlines.h $(LIBRND)/core/rotate.h $(LIBRND)/core/fptr_cast.h $(LIBRND)/core/safe_fs_dir.h $(LIBRND)/core/compat_inc.h $(LIBRND)/poly/rtree2_compat.h $(LIBRND)/core/color_cache.h } +# compatibility layer: remove this when librnd goes separate: +append /local/pcb/HDRS_HIDLIB { $(LIBRND)/pcb_compat.h $(LIBRND)/core/pcb-printf.h } + +gsub /local/pcb/HDRS_3RDLIB {../src_3rd/liblihata/dom_[^ ]*.h } {} +gsub /local/pcb/HDRS_3RDLIB {../src_3rd/liblihata/tree_[^ ]*.h } {} +gsub /local/pcb/HDRS_3RDLIB {../src_3rd/libulzw/libulzw_[^ ]*.h } {} +gsub /local/pcb/HDRS_3RDLIB {../src_3rd/libfungw/fungw_ptr.h ../src_3rd/libfungw/fungw_debug.h ../src_3rd/libfungw/fungw_call.h } {} +append /local/pcb/HDRS_3RDLIB {../src_3rd/genvector/genvector_impl.h ../src_3rd/genvector/genvector_impl.c ../src_3rd/genvector/genvector_undef.h } +append /local/pcb/HDRS_3RDLIB {../src_3rd/genrtree/genrtree_api.h ../src_3rd/genrtree/genrtree_impl.h ../src_3rd/genrtree/genrtree_search.h ../src_3rd/genrtree/genrtree_delete.h ../src_3rd/genrtree/genrtree_debug.h } +append /local/pcb/HDRS_3RDLIB {../src_3rd/genlist/gentdlist_impl.h ../src_3rd/genlist/gentdlist_undef.h ../src_3rd/genlist/gendlist.h } +append /local/pcb/HDRS_3RDLIB {../src_3rd/libulzw/libulzw.h } + +if ?libs/script/fungw/presents +then +else +# when there is no fungw installed, we go with local genht and that needs a few extras too +append /local/pcb/HDRS_3RDLIB {../src_3rd/genht/ht.h } +end + +# dynamic part of install_pcbrnd: hidlib headers +foreach /local/h in /local/pcb/HDRS_HIDLIB + put /local/hd /local/h + switch /local/h + case {^$(LIBRND)/} + sub /local/hd {$(LIBRND)/} {} + end + case {^../} + sub /local/hd {^[.][.]/} {} + end + default + sub /local/hd {^} {core/} + end + end + print [@ $(SCCBOX) $(HOW) "@/local/h@" "$(HL_INCDIR)/@/local/hd@"@] {\n} +end + +# dynamic part of install_pcbrnd: 3rdlib headers +foreach /local/h in /local/pcb/HDRS_3RDLIB + put /local/hd /local/h + switch /local/h + case {^../} + sub /local/hd {^[.][.]/} {} + end + default + sub /local/hd {^} {src_3rd/} + end + end + print [@ $(SCCBOX) $(HOW) "@/local/h@" "$(HL_INCDIR)/@/local/hd@"@] {\n} +end + +print [@ + +install_librnd_sy: + $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER_MAJOR)" + $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-hid.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-hid.so" + $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-3rd.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-3rd.so.$(PCB_RND_VER_MAJOR)" + $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-3rd.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-3rd.so" + $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-poly.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-poly.so.$(PCB_RND_VER_MAJOR)" + $(SCCBOX) $(HOW) "$(HL_LIBDIR)/librnd-poly.so.$(PCB_RND_VER)" "$(HL_LIBDIR)/librnd-poly.so" + +install: + $(MAKE) install_pcbrnd HOW="install -f" + $(MAKE) install_librnd HOW="install -f" + $(MAKE) install_librnd_sy HOW="ln -f --relative" + +linstall: + $(MAKE) install_pcbrnd HOW="linstall -f" + $(MAKE) install_librnd HOW="linstall -f" + $(MAKE) install_librnd_sy HOW="ln -f --relative" + +uninstall: + $(MAKE) install_pcbrnd HOW="uninstall" + $(MAKE) install_librnd_sy HOW="uninstall" + $(MAKE) install_librnd_ HOW="uninstall" + +map_plugins: + cd ../src_plugins && PUPLUG=../src_3rd/puplug/util/puplug ../src_3rd/librnd/plugins/map_plugins.sh ../src_plugins ../src_3rd/librnd/plugins + +@] + +# generate explicit rules for .c -> .o +put /local/comp/OBJS /local/pcb/OBJS +put /local/comp/OBJS_C99 ?/local/pcb/OBJS_C99 +include {../src_3rd/librnd/scconfig/template/compile.tmpasm} + +print [@ +# for extern utils:@] + +put /local/comp/OBJS /local/pcb/OBJS_UTIL +include {../src_3rd/librnd/scconfig/template/compile.tmpasm} + +# generate deps +put /local/dep/CFLAGS /local/pcb/CFLAGS +put /local/dep/SRCS /local/pcb/SRCS + +gsub /local/pcb/DEPSRCS {.o } {.c } +append /local/dep/SRCS /local/pcb/DEPSRCS +include {../src_3rd/librnd/scconfig/template/cdep.tmpasm} + +# librnd separation, temporary workaround: +# since pcb-rnd is trying to build everything without using librnd's build system +# our local builtins must contain librnd plugins too; but those plugins are +# in a different subdir. The workaround is extending the file names with local, +# relative path to that dir. +put /local/pcb/buildin_hidlib_pups_fullpath ?/local/pcb/buildin_hidlib_pups +gsub /local/pcb/buildin_hidlib_pups_fullpath {=} {=../src_3rd/librnd/plugins/} + +redir {../src_plugins/.builtin.pups} +print [@# Autogenerated by ./configure - do NOT edit - contains the list of buildins +@?/local/pcb/buildin_pups@ +@?/local/pcb/buildin_hidlib_pups_fullpath@ +@] + +redir {../src_plugins/.builtin.hidlib.pups} +print [@# Autogenerated by ./configure - do NOT edit - contains the list of buildins for the hidlib +@?/local/pcb/buildin_hidlib_pups@ +@] + Index: tags/2.3.0/src/actions_pcb.c =================================================================== --- tags/2.3.0/src/actions_pcb.c (nonexistent) +++ tags/2.3.0/src/actions_pcb.c (revision 33253) @@ -0,0 +1,355 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* fungw type extensions for pcb-rnd-only actions (not part of the hidlib) */ + +#include "config.h" + +#include + +#include + +#include +#include "board.h" +#include "data.h" +#include +#include "layer.h" +#include "layer_addr.h" +#include "undo.h" +#include "change.h" +#include +#include "conf_core.h" + +const char *PCB_PTR_DOMAIN_LAYER = "pcb_fgw_ptr_domain_layer"; +const char *PCB_PTR_DOMAIN_LAYERGRP = "pcb_fgw_ptr_domain_layergrp"; +const char *PCB_PTR_DOMAIN_VIEWLIST = "pcb_fgw_ptr_domain_viewlist"; + + +#define conv_str2layerid(dst, src) \ +do { \ + rnd_layer_id_t lid = pcb_layer_str2id(PCB->Data, src); \ + if (lid < 0) \ + return -1; \ + dst = lid; \ +} while(0) + +static int layerid_arg_conv(fgw_ctx_t *ctx, fgw_arg_t *arg, fgw_type_t target) +{ + if (target == FGW_LAYERID) { /* convert to layer id */ + rnd_layer_id_t tmp; + switch(FGW_BASE_TYPE(arg->type)) { + ARG_CONV_CASE_LONG(tmp, conv_assign) + ARG_CONV_CASE_LLONG(tmp, conv_assign) + ARG_CONV_CASE_DOUBLE(tmp, conv_assign) + ARG_CONV_CASE_LDOUBLE(tmp, conv_assign) + ARG_CONV_CASE_STR(tmp, conv_str2layerid) + ARG_CONV_CASE_PTR(tmp, conv_err) + ARG_CONV_CASE_CLASS(tmp, conv_err) + ARG_CONV_CASE_INVALID(tmp, conv_err) + } + arg->type = FGW_LAYERID; + fgw_layerid(arg) = tmp; + return 0; + } + if (arg->type == FGW_LAYERID) { /* convert from layer id */ + rnd_layer_id_t tmp = fgw_layerid(arg); + switch(target) { + ARG_CONV_CASE_LONG(tmp, conv_rev_assign) + ARG_CONV_CASE_LLONG(tmp, conv_rev_assign) + ARG_CONV_CASE_DOUBLE(tmp, conv_rev_assign) + ARG_CONV_CASE_LDOUBLE(tmp, conv_rev_assign) + ARG_CONV_CASE_PTR(tmp, conv_err) + ARG_CONV_CASE_CLASS(tmp, conv_err) + ARG_CONV_CASE_INVALID(tmp, conv_err) + case FGW_AUTO: + case FGW_STR: + arg->val.str = (char *)rnd_strdup_printf("#%ld", (long)tmp); + arg->type = FGW_STR | FGW_DYN; + return 0; + } + arg->type = target; + return 0; + } + fprintf(stderr, "Neither side of the conversion is layer id\n"); + abort(); +} + +static int layer_arg_conv(fgw_ctx_t *ctx, fgw_arg_t *arg, fgw_type_t target) +{ + if (target == FGW_LAYER) { /* convert to layer */ + rnd_layer_id_t lid; + if (layerid_arg_conv(ctx, arg, FGW_LAYERID) != 0) + return -1; + lid = fgw_layerid(arg); + arg->val.ptr_void = pcb_get_layer(PCB->Data, lid); + if (arg->val.ptr_void == NULL) { + arg->type = FGW_INVALID; + return -1; + } + arg->type = FGW_LAYER; + return 0; + } + if (arg->type == FGW_LAYER) { /* convert from layer */ + rnd_layer_id_t lid; + pcb_layer_t *ly = arg->val.ptr_void; + pcb_data_t *data; + if (ly == NULL) + return -1; + data = ly->parent.data; + lid = ly - data->Layer; + if ((lid >= 0) && (lid < data->LayerN)) { + arg->type = FGW_LAYERID; + arg->val.nat_long = lid; + if (layerid_arg_conv(ctx, arg, target) != 0) + return -1; + return 0; + } + return -1; + } + fprintf(stderr, "Neither side of the conversion is layer\n"); + abort(); +} + +#define conv_str2layergrpid(dst, src) \ +do { \ + rnd_layergrp_id_t gid = pcb_layergrp_str2id(PCB, src); \ + if (gid < 0) \ + return -1; \ + dst = gid; \ +} while(0) + +static int layergrpid_arg_conv(fgw_ctx_t *ctx, fgw_arg_t *arg, fgw_type_t target) +{ + if (target == FGW_LAYERGRPID) { /* convert to layergrp id */ + rnd_layergrp_id_t tmp; + switch(FGW_BASE_TYPE(arg->type)) { + ARG_CONV_CASE_LONG(tmp, conv_assign) + ARG_CONV_CASE_LLONG(tmp, conv_assign) + ARG_CONV_CASE_DOUBLE(tmp, conv_assign) + ARG_CONV_CASE_LDOUBLE(tmp, conv_assign) + ARG_CONV_CASE_STR(tmp, conv_str2layergrpid) + ARG_CONV_CASE_PTR(tmp, conv_err) + ARG_CONV_CASE_CLASS(tmp, conv_err) + ARG_CONV_CASE_INVALID(tmp, conv_err) + } + arg->type = FGW_LAYERGRPID; + fgw_layergrpid(arg) = tmp; + return 0; + } + if (arg->type == FGW_LAYERGRPID) { /* convert from layergrp id */ + rnd_layergrp_id_t tmp = fgw_layergrpid(arg); + switch(target) { + ARG_CONV_CASE_LONG(tmp, conv_rev_assign) + ARG_CONV_CASE_LLONG(tmp, conv_rev_assign) + ARG_CONV_CASE_DOUBLE(tmp, conv_rev_assign) + ARG_CONV_CASE_LDOUBLE(tmp, conv_rev_assign) + ARG_CONV_CASE_PTR(tmp, conv_err) + ARG_CONV_CASE_CLASS(tmp, conv_err) + ARG_CONV_CASE_INVALID(tmp, conv_err) + case FGW_AUTO: + case FGW_STR: + arg->val.str = (char *)rnd_strdup_printf("#%ld", (long)tmp); + arg->type = FGW_STR | FGW_DYN; + return 0; + } + arg->type = target; + return 0; + } + fprintf(stderr, "Neither side of the conversion is layer group id\n"); + abort(); +} + +static int layergrp_arg_conv(fgw_ctx_t *ctx, fgw_arg_t *arg, fgw_type_t target) +{ + if (target == FGW_LAYERGRP) { /* convert to layer group */ + rnd_layergrp_id_t gid; + if (layergrpid_arg_conv(ctx, arg, FGW_LAYERGRPID) != 0) + return -1; + gid = fgw_layergrpid(arg); + arg->val.ptr_void = pcb_get_layergrp(PCB, gid); + if (arg->val.ptr_void == NULL) { + arg->type = FGW_INVALID; + return -1; + } + arg->type = FGW_LAYERGRP; + return 0; + } + if (arg->type == FGW_LAYERGRP) { /* convert from layer group */ + rnd_layer_id_t gid; + pcb_layergrp_t *grp = arg->val.ptr_void; + pcb_board_t *pcb; + if (grp == NULL) + return -1; + pcb = grp->parent.board; + gid = grp - pcb->LayerGroups.grp; + if ((gid >= 0) && (gid < pcb->LayerGroups.len)) { + arg->type = FGW_LAYERGRPID; + arg->val.nat_long = gid; + if (layergrpid_arg_conv(ctx, arg, target) != 0) + return -1; + return 0; + } + return -1; + } + fprintf(stderr, "Neither side of the conversion is layer group\n"); + abort(); +} + +static int data_arg_conv(fgw_ctx_t *ctx, fgw_arg_t *arg, fgw_type_t target) +{ + if (target == FGW_DATA) { /* convert to data */ + if (FGW_BASE_TYPE(arg->type) == FGW_STR) { + const char *str = arg->val.str; + pcb_data_t *data = pcb_data_by_name(PCB, &str); + if (data != NULL) { + arg->val.ptr_void = data; + arg->type = FGW_DATA; + return 0; + } + } + if (FGW_BASE_TYPE(arg->type) == (FGW_PTR | FGW_STRUCT)) { +TODO("Dangerous: rather support subc's data with IDPATH"); + arg->val.ptr_void = arg->val.ptr_void; + arg->type = FGW_DATA; + return 0; + } + arg->type = FGW_INVALID; + return -1; + } + if (arg->type == FGW_DATA) { /* convert from data */ + char buf[32]; + const char *name = pcb_data_to_name(PCB, arg->val.ptr_void, buf, sizeof(buf)); + + if (name != NULL) { + if (name == buf) { + arg->val.str = rnd_strdup(name); + arg->type = FGW_STR | FGW_DYN; + } + else { /* static string */ + arg->val.cstr = name; + arg->type = FGW_STR; + } + return 0; + } + +TODO("Dangerous: rather support subc's data with IDPATH"); + arg->type = FGW_PTR | FGW_DYN; + return 0; + } + fprintf(stderr, "Neither side of the conversion is data\n"); + abort(); +} + +#define conv_struct_from_str(str, DOMAIN, TYPE) \ + if ((str[0] == '0') && (str[1] == 'x')) { \ + fgw_arg_conv(&rnd_fgw, arg, FGW_PTR); \ + if (fgw_ptr_in_domain(&rnd_fgw, arg, DOMAIN)) { \ + arg->type = TYPE | FGW_PTR; \ + return 0; \ + } \ + arg->type = FGW_INVALID; \ + return -1; \ + } + +static int idpath_arg_conv(fgw_ctx_t *ctx, fgw_arg_t *arg, fgw_type_t target) +{ + if (target == FGW_IDPATH) { /* convert to idpath */ + if (FGW_BASE_TYPE(arg->type) == FGW_STR) { + const char *str = arg->val.str; + pcb_idpath_t *idp; + + conv_struct_from_str(str, RND_PTR_DOMAIN_IDPATH, FGW_IDPATH); + idp = pcb_str2idpath(PCB, str); + if (idp != NULL) { + fgw_ptr_reg(&rnd_fgw, arg, RND_PTR_DOMAIN_IDPATH, FGW_IDPATH, idp); + return 0; + } + } + if (FGW_BASE_TYPE(arg->type) == (FGW_PTR | FGW_STRUCT) && fgw_ptr_in_domain(&rnd_fgw, arg, RND_PTR_DOMAIN_IDPATH)) + return 0; + arg->type = FGW_INVALID; + return -1; + } + if (arg->type == FGW_IDPATH) { /* convert from idpath */ + if (fgw_ptr_in_domain(&rnd_fgw, arg, RND_PTR_DOMAIN_IDPATH)) { + char *name = pcb_idpath2str(arg->val.ptr_void, 0); + if (name != NULL) { + arg->val.str = name; + arg->type = FGW_STR | FGW_DYN; + } + return 0; + } + return -1; + } + fprintf(stderr, "Neither side of the conversion is idpath\n"); + abort(); +} + +void pcb_actions_init_pcb_only(void) +{ + if (fgw_reg_custom_type(&rnd_fgw, FGW_LAYERID, "layerid", layerid_arg_conv, NULL) != FGW_LAYERID) { + fprintf(stderr, "pcb_actions_init: failed to register FGW_LAYERID\n"); + abort(); + } + if (fgw_reg_custom_type(&rnd_fgw, FGW_LAYER, "layer", layer_arg_conv, NULL) != FGW_LAYER) { + fprintf(stderr, "pcb_actions_init: failed to register FGW_LAYER\n"); + abort(); + } + if (fgw_reg_custom_type(&rnd_fgw, FGW_LAYERGRPID, "layergrpid", layergrpid_arg_conv, NULL) != FGW_LAYERGRPID) { + fprintf(stderr, "pcb_actions_init: failed to register FGW_LAYERGRPID\n"); + abort(); + } + if (fgw_reg_custom_type(&rnd_fgw, FGW_LAYERGRP, "layergrp", layergrp_arg_conv, NULL) != FGW_LAYERGRP) { + fprintf(stderr, "pcb_actions_init: failed to register FGW_LAYERGRP\n"); + abort(); + } + if (fgw_reg_custom_type(&rnd_fgw, FGW_DATA, "data", data_arg_conv, NULL) != FGW_DATA) { + fprintf(stderr, "pcb_actions_init: failed to register FGW_DATA\n"); + abort(); + } + if (fgw_reg_custom_type(&rnd_fgw, FGW_IDPATH, "idpath", idpath_arg_conv, NULL) != FGW_IDPATH) { + fprintf(stderr, "pcb_actions_init: failed to register FGW_IDPATH\n"); + abort(); + } +} + +int pcb_act_execute_file(rnd_hidlib_t *hidlib, const char *fn) +{ + int res; + + defer_updates = 1; + defer_needs_update = 0; + + res = rnd_act_execute_file(hidlib, fn); + + defer_updates = 0; + if (defer_needs_update) { + pcb_undo_inc_serial(); + rnd_gui->invalidate_all(rnd_gui); + } + + return res; +} Index: tags/2.3.0/src/actions_pcb.h =================================================================== --- tags/2.3.0/src/actions_pcb.h (nonexistent) +++ tags/2.3.0/src/actions_pcb.h (revision 33253) @@ -0,0 +1,12 @@ +extern const char *PCB_PTR_DOMAIN_LAYER; +extern const char *PCB_PTR_DOMAIN_LAYERGRP; +extern const char *PCB_PTR_DOMAIN_VIEWLIST; +extern const char *PCB_PTR_DOMAIN_FPMAP; + + +void pcb_actions_init_pcb_only(void); + +/* Read and execute an action script from a file, batching redraws; + return 0 if all actions returned 0 */ +int pcb_act_execute_file(rnd_hidlib_t *hidlib, const char *fn); + Index: tags/2.3.0/src/attrib.c =================================================================== --- tags/2.3.0/src/attrib.c (nonexistent) +++ tags/2.3.0/src/attrib.c (revision 33253) @@ -0,0 +1,321 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2004,2006 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* attribute lists */ +#include +#include +#include +#include +#include +#include +#include +#include "attrib.h" +#include "undo.h" + +static const char core_attribute_cookie[] = "core-attribute"; + +#define NOTIFY(list, name, value) \ +do { \ + if (list->post_change != NULL) \ + list->post_change(list, name, value); \ +} while(0) + +char *pcb_attribute_get(const pcb_attribute_list_t *list, const char *name) +{ + int i; + for (i = 0; i < list->Number; i++) + if (strcmp(name, list->List[i].name) == 0) + return list->List[i].value; + return NULL; +} + +char **pcb_attribute_get_ptr(const pcb_attribute_list_t *list, const char *name) +{ + int i; + for (i = 0; i < list->Number; i++) + if (strcmp(name, list->List[i].name) == 0) + return &list->List[i].value; + return NULL; +} + +int pcb_attribute_get_idx(const pcb_attribute_list_t *list, const char *name) +{ + int i; + for(i = 0; i < list->Number; i++) + if (strcmp(name, list->List[i].name) == 0) + return i; + return -1; +} + +char **pcb_attribute_get_namespace_ptr(const pcb_attribute_list_t *list, const char *plugin, const char *key) +{ + int i, glb = -1, plugin_len = strlen(plugin); + + for (i = 0; i < list->Number; i++) { + if (strcmp(list->List[i].name, key) == 0) + glb = i; + if ((strncmp(list->List[i].name, plugin, plugin_len) == 0) && (list->List[i].name[plugin_len] == ':') && (list->List[i].name[plugin_len+1] == ':')) { + if (strcmp(list->List[i].name+plugin_len+2, key) == 0) + return &list->List[i].value; /* found the plugin-specific value, that wins */ + } + } + if (glb >= 0) + return &list->List[glb].value; /* fall back to global if present */ + return NULL; /* nothing */ +} + +char *pcb_attribute_get_namespace(const pcb_attribute_list_t *list, const char *plugin, const char *key) +{ + char **res = pcb_attribute_get_namespace_ptr(list, plugin, key); + if (res == NULL) + return NULL; + return *res; +} + +/* assumes name and value strdup'd by the caller! */ +RND_INLINE int pcb_attribute_put_append(pcb_attribute_list_t *list, char *name, char *value) +{ + int i; + + if (list->Number >= list->Max) { + list->Max += 10; + list->List = (pcb_attribute_t *) realloc(list->List, list->Max * sizeof(pcb_attribute_t)); + } + + /* Now add the new attribute. */ + i = list->Number; + list->List[i].name = name; + list->List[i].value = value; + list->List[i].cpb_written = 1; + NOTIFY(list, list->List[i].name, list->List[i].value); + list->Number++; + return 0; +} + +int pcb_attribute_put(pcb_attribute_list_t * list, const char *name, const char *value) +{ + int i; + + if ((name == NULL) || (*name == '\0')) + return -1; + + /* Replace an existing attribute if there is a name match. */ + for (i = 0; i < list->Number; i++) { + if (strcmp(name, list->List[i].name) == 0) { + char *old_value = list->List[i].value; + list->List[i].value = rnd_strdup_null(value); + NOTIFY(list, list->List[i].name, list->List[i].value); + free(old_value); + return 1; + } + } + + /* At this point, we're going to need to add a new attribute to the + list. See if there's room. */ + return pcb_attribute_put_append(list, rnd_strdup_null(name), rnd_strdup_null(value)); +} + +int pcb_attribute_remove_idx(pcb_attribute_list_t * list, int idx) +{ + int j; + char *old_name = list->List[idx].name, *old_value = list->List[idx].value; + + for (j = idx; j < list->Number-1; j++) + list->List[j] = list->List[j + 1]; + list->Number--; + + NOTIFY(list, old_name, NULL); + free(old_name); + free(old_value); + return 0; +} + +int pcb_attribute_remove(pcb_attribute_list_t * list, const char *name) +{ + int i, found = 0; + for (i = 0; i < list->Number; i++) + if (strcmp(name, list->List[i].name) == 0) { + found++; + pcb_attribute_remove_idx(list, i); + } + return found; +} + +void pcb_attribute_free(pcb_attribute_list_t *list) +{ + int i; + + /* first notify for all removals while the values are still available */ + for (i = 0; i < list->Number; i++) + NOTIFY(list, list->List[i].name, NULL); + + for (i = 0; i < list->Number; i++) { + free(list->List[i].name); + free(list->List[i].value); + } + free(list->List); + list->List = NULL; + list->Max = 0; +} + +void pcb_attribute_copy_all(pcb_attribute_list_t *dest, const pcb_attribute_list_t *src) +{ + int i; + + for (i = 0; i < src->Number; i++) + pcb_attribute_put(dest, src->List[i].name, src->List[i].value); +} + + +void pcb_attribute_copyback_begin(pcb_attribute_list_t *dst) +{ + int i; + + for (i = 0; i < dst->Number; i++) + dst->List[i].cpb_written = 0; +} + +void pcb_attribute_copyback(pcb_attribute_list_t *dst, const char *name, const char *value) +{ + int i; + for (i = 0; i < dst->Number; i++) { + if (strcmp(name, dst->List[i].name) == 0) { + dst->List[i].cpb_written = 1; + if (strcmp(value, dst->List[i].value) != 0) { + char *old_value = dst->List[i].value; + dst->List[i].value = rnd_strdup(value); + NOTIFY(dst, dst->List[i].name, dst->List[i].value); + free(old_value); + } + return; + } + } + pcb_attribute_put(dst, name, value); +} + +void pcb_attribute_copyback_end(pcb_attribute_list_t *dst) +{ + int i; + for (i = 0; i < dst->Number; i++) + if (!dst->List[i].cpb_written) + pcb_attribute_remove_idx(dst, i); +} + + +void pcb_attrib_compat_set_intconn(pcb_attribute_list_t *dst, int intconn) +{ + char buff[32]; + + if (intconn <= 0) + return; + + sprintf(buff, "%d", intconn & 0xFF); + pcb_attribute_put(dst, "intconn", buff); +} + + + +/*** undoable attribute set/del */ +typedef struct { + pcb_attribute_list_t *list; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + char *name; + char *value; +} undo_attribute_set_t; + +static int undo_attribute_set_swap(void *udata) +{ + undo_attribute_set_t *g = udata; + int idx = pcb_attribute_get_idx(g->list, g->name); + char **slot = NULL; + + if (idx >= 0) + slot = &g->list->List[idx].value; + + /* want to delete */ + if (g->value == NULL) { + if (slot == NULL) /* but it does not exist */ + return 0; + + /* save old value and remove */ + g->value = *slot; + *slot = NULL; + pcb_attribute_remove_idx(g->list, idx); + return 0; + } + + /* old value doesn't exist: need to create it */ + if (slot == NULL) { + pcb_attribute_put_append(g->list, rnd_strdup(g->name), g->value); + g->value = NULL; + return 0; + } + + /* replace the existing value */ + rnd_swap(char *, *slot, g->value); + NOTIFY(g->list, g->name, *slot); + return 0; +} + +static void undo_attribute_set_print(void *udata, char *dst, size_t dst_len) +{ + undo_attribute_set_t *g = udata; + rnd_snprintf(dst, dst_len, "attribute set %s to %s", g->name, g->value == NULL ? "" : g->value); +} + +static void undo_attribute_set_free(void *udata) +{ + undo_attribute_set_t *g = udata; + free(g->name); + free(g->value); +} + +static const uundo_oper_t undo_attribute_set = { + core_attribute_cookie, + undo_attribute_set_free, + undo_attribute_set_swap, + undo_attribute_set_swap, + undo_attribute_set_print +}; + + + +void pcb_attribute_set(pcb_board_t *pcb, pcb_attribute_list_t *list, const char *name, const char *value, rnd_bool undoable) +{ + undo_attribute_set_t gtmp, *g = >mp; + + if (undoable) g = pcb_undo_alloc(pcb, &undo_attribute_set, sizeof(undo_attribute_set_t)); + + g->list = list; + g->name = rnd_strdup_null(name); + g->value = rnd_strdup_null(value); + + undo_attribute_set_swap(g); + if (undoable) pcb_undo_inc_serial(); +} + Index: tags/2.3.0/src/attrib.h =================================================================== --- tags/2.3.0/src/attrib.h (nonexistent) +++ tags/2.3.0/src/attrib.h (revision 33253) @@ -0,0 +1,94 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* attribute lists */ + +#ifndef PCB_ATTRIB_H +#define PCB_ATTRIB_H + +#include "global_typedefs.h" + +typedef struct pcb_attribute_list_s pcb_attribute_list_t; + +typedef struct pcb_attribute_s { + char *name; + char *value; + unsigned cpb_written:1; /* copyback: written */ +} pcb_attribute_t; + +struct pcb_attribute_list_s { + int Number, Max; + pcb_attribute_t *List; + void (*post_change)(pcb_attribute_list_t *list, const char *name, const char *value); /* called any time an attribute changes (including removes); value is NULL if removed; old value is free'd only after the call so cached old values are valid */ +}; + +/* Returns NULL if the name isn't found, else the value for that named + attribute. The ptr version returns the address of the value str in the slot */ +char *pcb_attribute_get(const pcb_attribute_list_t *list, const char *name); +char **pcb_attribute_get_ptr(const pcb_attribute_list_t *list, const char *name); + +/* Same as pcb_attribute_get, but also look for plugin::key which overrides + plain key hits */ +char *pcb_attribute_get_namespace(const pcb_attribute_list_t *list, const char *plugin, const char *key); +char **pcb_attribute_get_namespace_ptr(const pcb_attribute_list_t *list, const char *plugin, const char *key); + + +/* Adds an attribute to the list. If the attribute already exists, the value + is replaced. Returns non-zero if an existing attribute was replaced. */ +int pcb_attribute_put(pcb_attribute_list_t * list, const char *name, const char *value); +/* Simplistic version: Takes a pointer to an object, looks up attributes in it. */ +#define pcb_attrib_get(OBJ,name) pcb_attribute_get(&(OBJ->Attributes), name) +/* Simplistic version: Takes a pointer to an object, sets attributes in it. */ +#define pcb_attrib_put(OBJ,name,value) pcb_attribute_put(&(OBJ->Attributes), name, value) +/* Remove an attribute by name; returns number of items removed */ +int pcb_attribute_remove(pcb_attribute_list_t * list, const char *name); +/* Simplistic version of Remove. */ +#define pcb_attrib_remove(OBJ, name) pcb_attribute_remove(&(OBJ->Attributes), name) + +/* Universal, optionally undoable set/del: value==NULL means remove */ +void pcb_attribute_set(pcb_board_t *pcb, pcb_attribute_list_t *list, const char *name, const char *value, rnd_bool undoable); + + +/* remove item by index - WARNING: no checks are made, idx has to be valid! */ +int pcb_attribute_remove_idx(pcb_attribute_list_t * list, int idx); + +/* Frees memory used by an attribute list */ +void pcb_attribute_free(pcb_attribute_list_t *list); + +/* Copy each attribute from src to dest */ +void pcb_attribute_copy_all(pcb_attribute_list_t *dest, const pcb_attribute_list_t *src); + +/* Copy back a mirrored attribute list, minimizing the changes */ +void pcb_attribute_copyback_begin(pcb_attribute_list_t *dst); +void pcb_attribute_copyback(pcb_attribute_list_t *dst, const char *name, const char *value); +void pcb_attribute_copyback_end(pcb_attribute_list_t *dst); + +/* Set the intconn attribute - hack for compatibility parsing */ +void pcb_attrib_compat_set_intconn(pcb_attribute_list_t *dst, int intconn); + +#endif Index: tags/2.3.0/src/board.c =================================================================== --- tags/2.3.0/src/board.c (nonexistent) +++ tags/2.3.0/src/board.c (revision 33253) @@ -0,0 +1,467 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include "config.h" +#include "board.h" +#include "data.h" +#include "conf_core.h" +#include +#include "plug_io.h" +#include +#include +#include +#include +#include +#include "undo.h" +#include "draw.h" +#include "event.h" +#include +#include +#include "layer.h" +#include "netlist.h" + +pcb_board_t *PCB; + +static const char core_board_cookie[] = "core/board"; + +void pcb_board_free(pcb_board_t * pcb) +{ + int i; + + if (pcb == NULL) + return; + + free(pcb->line_mod_merge); + free(pcb->hidlib.name); + free(pcb->hidlib.filename); + free(pcb->PrintFilename); + pcb_ratspatch_destroy(pcb); + pcb_data_free(pcb->Data); + + /* release font symbols */ + pcb_fontkit_free(&pcb->fontkit); + for (i = 0; i < PCB_NUM_NETLISTS; i++) + pcb_netlist_uninit(&(pcb->netlist[i])); + vtroutestyle_uninit(&pcb->RouteStyle); + pcb_attribute_free(&pcb->Attributes); + + pcb_layergroup_free_stack(&pcb->LayerGroups); + + /* clear struct */ + memset(pcb, 0, sizeof(pcb_board_t)); +} + +/* creates a new PCB */ +pcb_board_t *pcb_board_new_(rnd_bool SetDefaultNames) +{ + pcb_board_t *ptr; + int i; + + /* allocate memory, switch all layers on and copy resources */ + ptr = calloc(1, sizeof(pcb_board_t)); + ptr->Data = pcb_buffer_new(ptr); + + for(i = 0; i < PCB_NUM_NETLISTS; i++) + pcb_netlist_init(&(ptr->netlist[i])); + + rnd_conf_set(RND_CFR_INTERNAL, "design/poly_isle_area", -1, "200000000", RND_POL_OVERWRITE); + + ptr->RatDraw = rnd_false; + + /* NOTE: we used to set all the pcb flags on ptr here, but we don't need to do that anymore due to the new conf system */ + ptr->hidlib.grid = rnd_conf.editor.grid; + + ptr->hidlib.size_y = ptr->hidlib.size_x = RND_MM_TO_COORD(20); /* should be overriden by the default design */ + ptr->ID = pcb_create_ID_get(); + ptr->ThermScale = 0.5; + + pcb_font_create_default(ptr); + + return ptr; +} + +#include "defpcb_internal.c" + +pcb_board_t *pcb_board_new(int inhibit_events) +{ + pcb_board_t *old, *nw = NULL; + int dpcb; + unsigned int inh = inhibit_events ? PCB_INHIBIT_BOARD_CHANGED : 0; + + old = PCB; + PCB = NULL; + + dpcb = -1; + pcb_io_err_inhibit_inc(); + rnd_hid_menu_merge_inhibit_inc(); + rnd_conf_list_foreach_path_first(NULL, dpcb, &conf_core.rc.default_pcb_file, pcb_load_pcb(__path__, NULL, rnd_false, 1 | 0x10 | inh)); + rnd_hid_menu_merge_inhibit_dec(); + pcb_io_err_inhibit_dec(); + + if (dpcb != 0) { /* no default PCB in file, use embedded version */ + FILE *f; + char *efn; + const char *tmp_fn = ".pcb-rnd.default.pcb"; + + /* We can parse from file only, make a temp file */ + f = rnd_fopen_fn(NULL, tmp_fn, "wb", &efn); + if (f != NULL) { + fwrite(default_pcb_internal, strlen(default_pcb_internal), 1, f); + fclose(f); + dpcb = pcb_load_pcb(efn, NULL, rnd_false, 1 | 0x10); + if (dpcb == 0) + rnd_message(RND_MSG_WARNING, "Couldn't find default.pcb - using the embedded fallback\n"); + else + rnd_message(RND_MSG_ERROR, "Couldn't find default.pcb and failed to load the embedded fallback\n"); + rnd_remove(NULL, efn); + free(efn); + } + } + + if (dpcb == 0) { + nw = PCB; + if (nw->hidlib.filename != NULL) { + /* make sure the new PCB doesn't inherit the name and loader of the default pcb */ + free(nw->hidlib.filename); + nw->hidlib.filename = NULL; + nw->Data->loader = NULL; + } + } + + PCB = old; + return nw; +} + +int pcb_board_new_postproc(pcb_board_t *pcb, int use_defaults) +{ + int n; + + /* copy default settings */ + pcb_layer_colors_from_conf(pcb, 0); + + for(n = 0; n < PCB_MAX_BUFFER; n++) { + if (pcb_buffers[n].Data != NULL) { + pcb_data_unbind_layers(pcb_buffers[n].Data); + pcb_data_binding_update(pcb, pcb_buffers[n].Data); + } + } + + if (pcb == PCB) + rnd_event(&PCB->hidlib, PCB_EVENT_ROUTE_STYLES_CHANGED, NULL); + + return 0; +} + +void pcb_layer_colors_from_conf(pcb_board_t *ptr, int force) +{ + int i; + + /* copy default settings */ + for (i = 0; i < PCB_MAX_LAYER; i++) + if (force || (ptr->Data->Layer[i].meta.real.color.str[0] == '\0')) + memcpy(&ptr->Data->Layer[i].meta.real.color, pcb_layer_default_color(i, pcb_layer_flags(ptr, i)), sizeof(rnd_color_t)); +} + +typedef struct { + int nplated; + int nunplated; +} hole_count_t; + +#include "obj_pstk_inlines.h" +static rnd_r_dir_t hole_counting_callback(const rnd_box_t * b, void *cl) +{ + pcb_pstk_t *ps = (pcb_pstk_t *)b; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + hole_count_t *hcs = (hole_count_t *)cl; + + if ((proto != NULL) && (proto->hdia > 0)) { + if (proto->hplated) + hcs->nplated++; + else + hcs->nunplated++; + } + return RND_R_DIR_FOUND_CONTINUE; +} + +static rnd_r_dir_t slot_counting_callback(const rnd_box_t *b, void *cl) +{ + pcb_pstk_t *ps = (pcb_pstk_t *)b; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + hole_count_t *hcs = (hole_count_t *)cl; + + if ((proto != NULL) && (proto->mech_idx >= 0)) { + if (proto->hplated) + hcs->nplated++; + else + hcs->nunplated++; + } + return RND_R_DIR_FOUND_CONTINUE; +} + +void pcb_board_count_holes(pcb_board_t *pcb, int *plated, int *unplated, const rnd_box_t *within_area) +{ + hole_count_t hcs = { 0, 0 }; + + rnd_r_search(pcb->Data->padstack_tree, within_area, NULL, hole_counting_callback, &hcs, NULL); + + if (plated != NULL) + *plated = hcs.nplated; + if (unplated != NULL) + *unplated = hcs.nunplated; +} + +void pcb_board_count_slots(pcb_board_t *pcb, int *plated, int *unplated, const rnd_box_t *within_area) +{ + hole_count_t hcs = { 0, 0 }; + + rnd_r_search(pcb->Data->padstack_tree, within_area, NULL, slot_counting_callback, &hcs, NULL); + + if (plated != NULL) + *plated = hcs.nplated; + if (unplated != NULL) + *unplated = hcs.nunplated; +} + +const char *pcb_board_get_filename(void) +{ + return PCB->hidlib.filename; +} + +const char *pcb_board_get_name(void) +{ + return PCB->hidlib.name; +} + +rnd_bool pcb_board_change_name(char *Name) +{ + free(PCB->hidlib.name); + PCB->hidlib.name = Name; + pcb_board_changed(0); + return rnd_true; +} + +static void pcb_board_resize_(pcb_board_t *pcb, rnd_coord_t Width, rnd_coord_t Height) +{ + pcb->hidlib.size_x = Width; + pcb->hidlib.size_y = Height; + + if (pcb == PCB) + pcb_board_changed(0); +} + +/*** undoable board resize ***/ + +typedef struct { + pcb_board_t *pcb; + rnd_coord_t w, h; +} undo_board_size_t; + +static int undo_board_size_swap(void *udata) +{ + undo_board_size_t *s = udata; + rnd_coord_t oldw = s->pcb->hidlib.size_x, oldh = s->pcb->hidlib.size_y; + pcb_board_resize_(s->pcb, s->w, s->h); + s->w = oldw; + s->h = oldh; + return 0; +} + +static void undo_board_size_print(void *udata, char *dst, size_t dst_len) +{ + undo_board_size_t *s = udata; + rnd_snprintf(dst, dst_len, "board_size: %mmx%mm", s->w, s->h); +} + +static const uundo_oper_t undo_board_size = { + core_board_cookie, + NULL, /* free */ + undo_board_size_swap, + undo_board_size_swap, + undo_board_size_print +}; + +void pcb_board_resize(rnd_coord_t width, rnd_coord_t height, int undoable) +{ + undo_board_size_t *s; + + if (!undoable) { + pcb_board_resize_(PCB, width, height); + return; + } + + s = pcb_undo_alloc(PCB, &undo_board_size, sizeof(undo_board_size_t)); + s->pcb = PCB; + s->w = width; + s->h = height; + undo_board_size_swap(s); +} + + +void pcb_board_remove(pcb_board_t *Ptr) +{ + pcb_undo_clear_list(rnd_true); + pcb_board_free(Ptr); + free(Ptr); +} + +/* sets a new line thickness */ +void pcb_board_set_line_width(rnd_coord_t Size) +{ + if (Size >= PCB_MIN_THICKNESS && Size <= PCB_MAX_THICKNESS) { + rnd_conf_set_design("design/line_thickness", "%$mS", Size); + if (conf_core.editor.auto_drc) + pcb_crosshair_grid_fit(PCB, pcb_crosshair.X, pcb_crosshair.Y); + } +} + +/* sets a new via thickness */ +void pcb_board_set_via_size(rnd_coord_t Size, rnd_bool Force) +{ + if (Force || (Size <= PCB_MAX_PINORVIASIZE && Size >= PCB_MIN_PINORVIASIZE && Size >= conf_core.design.via_drilling_hole + PCB_MIN_PINORVIACOPPER)) { + rnd_conf_set_design("design/via_thickness", "%$mS", Size); + } +} + +/* sets a new via drilling hole */ +void pcb_board_set_via_drilling_hole(rnd_coord_t Size, rnd_bool Force) +{ + if (Force || (Size <= PCB_MAX_PINORVIASIZE && Size >= PCB_MIN_PINORVIAHOLE && Size <= conf_core.design.via_thickness - PCB_MIN_PINORVIACOPPER)) { + rnd_conf_set_design("design/via_drilling_hole", "%$mS", Size); + } +} + +/* sets a clearance width */ +void pcb_board_set_clearance(rnd_coord_t Width) +{ + if (Width <= PCB_MAX_THICKNESS) { + rnd_conf_set_design("design/clearance", "%$mS", Width); + } +} + +/* sets a text scaling */ +void pcb_board_set_text_scale(int Scale) +{ + if (Scale <= PCB_MAX_TEXTSCALE && Scale >= PCB_MIN_TEXTSCALE) { + rnd_conf_set_design("design/text_scale", "%d", Scale); + } +} + +/* sets or resets changed flag and redraws status */ +void pcb_board_set_changed_flag(pcb_board_t *pcb, rnd_bool New) +{ + rnd_bool old = pcb->Changed; + + pcb->Changed = New; + + if (old != New) + rnd_event(&pcb->hidlib, RND_EVENT_BOARD_META_CHANGED, NULL); +} + + +void pcb_board_changed(int reverted) +{ + if ((rnd_gui != NULL) && (rnd_gui->set_hidlib != NULL)) + rnd_gui->set_hidlib(rnd_gui, &PCB->hidlib); + rnd_event(&PCB->hidlib, RND_EVENT_BOARD_CHANGED, "i", reverted); +} + +int pcb_board_normalize(pcb_board_t *pcb) +{ + rnd_box_t b; + int chg = 0; + + if (pcb_data_bbox(&b, pcb->Data, rnd_false) == NULL) + return -1; + + if ((b.X2 - b.X1) > pcb->hidlib.size_x) { + pcb->hidlib.size_x = b.X2 - b.X1; + chg++; + } + + if ((b.Y2 - b.Y1) > pcb->hidlib.size_y) { + pcb->hidlib.size_y = b.Y2 - b.Y1; + chg++; + } + + chg += pcb_data_normalize_(pcb->Data, &b); + + return chg; +} + +rnd_coord_t pcb_stack_thickness(pcb_board_t *pcb, const char *namespace, pcb_board_thickness_flags_t flags, rnd_layergrp_id_t from, rnd_bool include_from, rnd_layergrp_id_t to, rnd_bool include_to, pcb_layer_type_t accept) +{ + rnd_layergrp_id_t gid; + pcb_layergrp_t *grp; + rnd_coord_t curr, total = 0; + + if (from > to) { + rnd_swap(rnd_layergrp_id_t, from, to); + rnd_swap(int, include_from, include_to); + } + + if (!include_from) + from++; + + if (!include_to) + to--; + + if (to < from) + return -1; + + for(gid = from, grp = pcb->LayerGroups.grp+from; gid <= to; gid++,grp++) { + const char *s; + + if (!(grp->ltype & accept)) + continue; + + curr = 0; + s = pcb_layergrp_thickness_attr(grp, namespace); + if (s != NULL) + curr = rnd_get_value(s, NULL, NULL, NULL); + if (curr <= 0) { + if (grp->ltype & PCB_LYT_SUBSTRATE) { + if (flags & PCB_BRDTHICK_PRINT_ERROR) { + if (namespace != NULL) + rnd_message(RND_MSG_ERROR, "%s: ", namespace); + rnd_message(RND_MSG_ERROR, "can not determine substrate thickness on layer group %ld - total board thickness is probably wrong\n", (long)gid); + } + if (flags & PCB_BRDTHICK_TOLERANT) + continue; + return -1; + } + else + continue; + } + total += curr; + } + return total; +} + +rnd_coord_t pcb_board_thickness(pcb_board_t *pcb, const char *namespace, pcb_board_thickness_flags_t flags) +{ + return pcb_stack_thickness(pcb, namespace, flags, 0, rnd_true, pcb->LayerGroups.len-1, rnd_true, PCB_LYT_COPPER | PCB_LYT_SUBSTRATE); +} Index: tags/2.3.0/src/board.h =================================================================== --- tags/2.3.0/src/board.h (nonexistent) +++ tags/2.3.0/src/board.h (revision 33253) @@ -0,0 +1,203 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2004 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* definition of types */ +#ifndef PCB_BOARD_H +#define PCB_BOARD_H + +#include "config.h" + +enum { + PCB_NETLIST_INPUT = 0, /* index of the original netlist as imported */ + PCB_NETLIST_EDITED = 1, /* index of the netlist produced by applying netlist patches on [PCB_NETLIST_INPUT] */ + PCB_NUM_NETLISTS /* so that we know how many netlists we are dealing with */ +}; + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "vtroutestyle.h" +#include "layer.h" +#include "layer_grp.h" +#include "attrib.h" +#include "rats_patch.h" +#include "font.h" +#include + +typedef htsp_t pcb_netlist_t; + +/* The pcb_board_t struct holds information about board layout most of which is + saved with the layout. */ +struct pcb_board_s { + rnd_hidlib_t hidlib; + + long ID; + char *PrintFilename; /* from print dialog */ + char *Netlistname; /* name of netlist file */ + + rnd_bool Changed; /* layout has been changed */ + + rnd_bool pstk_on, RatOn, InvisibleObjectsOn, + SubcOn, SubcPartsOn, + padstack_mark_on, hole_on; /* visibility flags */ + rnd_bool RatDraw; /* we're drawing rats */ + + rnd_bool loose_subc; /* when set, subc parts are not locked into the subc */ + + double ThermScale; /* scale factor used with thermals */ + + pcb_fontkit_t fontkit; + pcb_layer_stack_t LayerGroups; + vtroutestyle_t RouteStyle; + pcb_netlist_t netlist[PCB_NUM_NETLISTS]; + /* htsp_t netlist_subc[PCB_NUM_NETLISTS]; hierarchic netlists */ + pcb_ratspatch_line_t *NetlistPatches, *NetlistPatchLast; + pcb_attribute_list_t Attributes; + + pcb_data_t *Data; /* entire database */ + rnd_bool is_footprint; /* If set, the user has loaded a footprint, not a pcb. */ + + const pcb_attribute_list_t *pen_attr; + +/* netlist states */ + int netlist_frozen; /* counter */ + unsigned netlist_needs_update:1; + + /* delayed trace optimization */ + int line_mod_merge_inhibit; + struct vtp0_s *line_mod_merge; + + /* random */ + unsigned suppress_warn_missing_font:1; /* do not warn for missing font; useful for alien formats not having embedded font */ +}; + +extern pcb_board_t *PCB; /* the board being edited */ + +/* free memory used by a board */ +void pcb_board_free(pcb_board_t *pcb); + +/* creates a new PCB - low level */ +pcb_board_t *pcb_board_new_(rnd_bool SetDefaultNames); + +/* creates a new PCB - high level (uses a template board); does not generate + new board event if inhibit_events is set */ +pcb_board_t *pcb_board_new(int inhibit_events); + +/* Called after PCB->Data->LayerN is set. Returns non-zero on error */ +int pcb_board_new_postproc(pcb_board_t *pcb, int use_defaults); + +/* Set the color field of each layer that does not yet have an explicit + color, from the config, using default colors per layer type. If + force is non-zero, overwrite even existing colors. */ +void pcb_layer_colors_from_conf(pcb_board_t *pcb, int force); + +/* counts the number of plated and unplated holes or slots in the design within + a given area of the board. To count for the whole board, pass NULL within_area. */ +void pcb_board_count_holes(pcb_board_t *pcb, int *plated, int *unplated, const rnd_box_t *within_area); +void pcb_board_count_slots(pcb_board_t *pcb, int *plated, int *unplated, const rnd_box_t *within_area); + +#define PCB_SWAP_X(x) (RND_SWAP_SIGN_X(x)) +#define PCB_SWAP_Y(y) (PCB->hidlib.size_y +RND_SWAP_SIGN_Y(y)) + +#define PCB_CSWAP_X(x, w, cond) ((cond) ? (RND_SWAP_SIGN_X(x)) : (x)) +#define PCB_CSWAP_Y(y, h, cond) ((cond) ? (h+RND_SWAP_SIGN_Y(y)) : (y)) + +/* Conditionally allow subc parts to be reached directly in search masks */ +#define PCB_LOOSE_SUBC(pcb) ((pcb)->loose_subc ? PCB_OBJ_SUBC_PART : 0) + + +/* changes the name of a layout; Name is allocated by the caller (no strdup() is made) */ +rnd_bool pcb_board_change_name(char *Name); + +/* changes the maximum size of a layout, notifies the GUI + * and adjusts the cursor confinement box */ +void pcb_board_resize(rnd_coord_t Width, rnd_coord_t Height, int undoable); + + +/* free the board and remove its undo list */ +void pcb_board_remove(pcb_board_t *Ptr); + +/* sets a new line thickness */ +void pcb_board_set_line_width(rnd_coord_t Size); + +/* sets a new via thickness */ +void pcb_board_set_via_size(rnd_coord_t Size, rnd_bool Force); + +/* sets a new via drilling hole */ +void pcb_board_set_via_drilling_hole(rnd_coord_t Size, rnd_bool Force); + +/* sets a clearance width */ +void pcb_board_set_clearance(rnd_coord_t Width); + +/* sets a text scaling */ +void pcb_board_set_text_scale(int Scale); + +/* make sure the data of the board fits the PCB (move it out from negative, + make the board large enough); returns -1 on error, the number of changes on success */ +int pcb_board_normalize(pcb_board_t *pcb); + +/* sets or resets changed flag and redraws status */ +void pcb_board_set_changed_flag(pcb_board_t *pcb, rnd_bool New); + +/* Shorthand for emitting a board changed event (RND_EVENT_BOARD_CHANGED) */ +void pcb_board_changed(int reverted); + + +/* pcb_board_t field accessors - do not use; required for path.[ch] to not depend on board.h */ +const char *pcb_board_get_filename(void); +const char *pcb_board_get_name(void); + +/* Update the bounding box of the subc being edited as board; if the + board is not a subc, this call is a NOP; implemented in obj_subc.c */ +void pcb_subc_as_board_update(pcb_board_t *pcb); + +/*** thickness ***/ +typedef enum pcb_board_thickness_flags_e { /* bitfield */ + PCB_BRDTHICK_TOLERANT = 1, /* do not return -1 if any substrate layer lacks thickness */ + PCB_BRDTHICK_PRINT_ERROR = 2 /* print an error message for missing thickness attributes */ +} pcb_board_thickness_flags_t; + +/* Return the total thickness of the stack between groups 'from' and 'to'; + whether the own thickness of 'from' and 'to' are included in the + calculation depends on the corresponding include_ argument. Only groups + with type matching 'accept' will be considered. Return -1 on error. */ +rnd_coord_t pcb_stack_thickness(pcb_board_t *pcb, const char *namespace, pcb_board_thickness_flags_t flags, rnd_layergrp_id_t from, rnd_bool include_from, rnd_layergrp_id_t to, rnd_bool include_to, pcb_layer_type_t accept); + +/* Return the board thickness or -1 on error */ +rnd_coord_t pcb_board_thickness(pcb_board_t *pcb, const char *namespace, pcb_board_thickness_flags_t flags); + + +#define PCB_ACT_BOARD ((pcb_board_t *)argv[0].val.argv0.user_call_ctx) + +#endif Index: tags/2.3.0/src/box_dir.h =================================================================== --- tags/2.3.0/src/box_dir.h (nonexistent) +++ tags/2.3.0/src/box_dir.h (revision 33253) @@ -0,0 +1,84 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1998,1999,2000,2001 harry eaton + * + * this file, box.h, was written and is + * Copyright (c) 2001 C. Scott Ananian. + * + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA + * haceaton@aplcomm.jhuapl.edu + * + */ + + +#ifndef RND_BOX_DIR_H +#define RND_BOX_DIR_H + + +typedef enum { + RND_NORTH = 0, RND_EAST = 1, RND_SOUTH = 2, RND_WEST = 3, + RND_NE = 4, RND_SE = 5, RND_SW = 6, RND_NW = 7, RND_ANY_DIR = 8 +} rnd_direction_t; + +#define RND_BOX_ROTATE_TO_NORTH(box, dir) \ +do { rnd_coord_t t;\ + switch(dir) {\ + case RND_EAST: \ + t = (box).X1; (box).X1 = (box).Y1; (box).Y1 = -(box).X2;\ + (box).X2 = (box).Y2; (box).Y2 = -t; break;\ + case RND_SOUTH: \ + t = (box).X1; (box).X1 = -(box).X2; (box).X2 = -t;\ + t = (box).Y1; (box).Y1 = -(box).Y2; (box).Y2 = -t; break;\ + case RND_WEST: \ + t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\ + (box).X2 = -(box).Y1; (box).Y1 = t; break;\ + case RND_NORTH: break;\ + default: assert(0);\ + }\ +} while (0) + +#define RND_BOX_ROTATE_FROM_NORTH(box, dir) \ +do { rnd_coord_t t;\ + switch(dir) {\ + case RND_WEST: \ + t = (box).X1; (box).X1 = (box).Y1; (box).Y1 = -(box).X2;\ + (box).X2 = (box).Y2; (box).Y2 = -t; break;\ + case RND_SOUTH: \ + t = (box).X1; (box).X1 = -(box).X2; (box).X2 = -t;\ + t = (box).Y1; (box).Y1 = -(box).Y2; (box).Y2 = -t; break;\ + case RND_EAST: \ + t = (box).X1; (box).X1 = -(box).Y2; (box).Y2 = (box).X2;\ + (box).X2 = -(box).Y1; (box).Y1 = t; break;\ + case RND_NORTH: break;\ + default: assert(0);\ + }\ +} while (0) + +#endif Index: tags/2.3.0/src/brave.c =================================================================== --- tags/2.3.0/src/brave.c (nonexistent) +++ tags/2.3.0/src/brave.c (revision 33253) @@ -0,0 +1,302 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017 Tibor 'Igor2' Palinkas + * + * This module, diag, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include "board.h" +#include "brave.h" +#include +#include "conf_core.h" +#include +#include +#include +#include + +pcb_brave_t pcb_brave = 0; +static const char brave_cookie[] = "brave"; +static rnd_conf_hid_id_t brave_conf_id; + +typedef struct { + pcb_brave_t bit; + const char *name, *shrt, *lng; + int widget; +} desc_t; + +static desc_t desc[] = { + {PCB_BRAVE_NOXOR, "noxor", "avoid xor drawing", "use alternative rendering instead of xor draw", 0}, + {PCB_BRAVE_NOCLIPBATCH, "noclipbatch", "do not batch poly clipping", "skip optimization of batching polygon clipping in some expensive user operations", 0}, + {0, NULL, NULL, NULL} +}; + +static desc_t *find_by_name(const char *name) +{ + desc_t *d; + for(d = desc; d->name != NULL; d++) + if (rnd_strcasecmp(name, d->name) == 0) + return d; + return NULL; +} + +/* convert the brave bits into a config string, save in CLI */ +static void set_conf(pcb_brave_t br) +{ + gds_t tmp; + desc_t *d; + + gds_init(&tmp); + + for(d = desc; d->name != NULL; d++) { + if (br & d->bit) { + gds_append_str(&tmp, d->name); + gds_append(&tmp, ','); + } + } + + /* truncate last comma */ + gds_truncate(&tmp, gds_len(&tmp)-1); + + rnd_conf_set(RND_CFR_CLI, "rc/brave", 0, tmp.array, RND_POL_OVERWRITE); + + gds_uninit(&tmp); +} + +/* Upon a change in the config, parse the new config string and set the brave bits */ +static void brave_conf_chg(rnd_conf_native_t *cfg, int arr_idx) +{ + char *curr, *next, old; + desc_t *d; + + pcb_brave = 0; + if ((conf_core.rc.brave == NULL) || (*conf_core.rc.brave == '\0')) + return; + for(curr = (char *)conf_core.rc.brave; *curr != '\0'; curr = next) { + next = strpbrk(curr, ", "); + if (next == NULL) + next = curr + strlen(curr); + old = *next; + *next = '\0'; + d = find_by_name(curr); + + if (d != NULL) + pcb_brave |= d->bit; + *next = old; + if (*next != '\0') + next++; + while((*next == ',') || (*next == ' ')) next++; + } +} + +/* Set one bit; if changed, update the config */ +static void brave_set(pcb_brave_t bit, int on) +{ + int state = pcb_brave & bit; + pcb_brave_t nb; + + if (state == on) + return; + + if (on) + nb = pcb_brave | bit; + else + nb = pcb_brave & ~bit; + + set_conf(nb); +} + +/*** interactive mode (DAD dialog) ***/ + +/* Convert the current brave bits into dialog box widget states, update the dialog */ +static void brave2dlg(void *hid_ctx) +{ + desc_t *d; + int len; + + for(d = desc, len=0; d->name != NULL; d++,len++) { + if (pcb_brave & d->bit) + RND_DAD_SET_VALUE(hid_ctx, d->widget, lng, 1); + else + RND_DAD_SET_VALUE(hid_ctx, d->widget, lng, 0); + } +} + +/* Convert the current state of dialog box widget into brave bits, update the conf */ +static void dlg2brave(rnd_hid_attribute_t *attrs) +{ + desc_t *d; + for(d = desc; d->name != NULL; d++) + brave_set(d->bit, attrs[d->widget].val.lng); +} + +/* If a checkbox changes, do the conversion forth and back to ensure sync */ +static void brave_dialog_chg(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + dlg2brave(caller_data); + brave2dlg(hid_ctx); +} + +/* Tick in all - button callback */ +static void brave_dialog_allon(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + desc_t *d; + for(d = desc; d->name != NULL; d++) + brave_set(d->bit, 1); + brave2dlg(hid_ctx); +} + +/* Tick off all - button callback */ +static void brave_dialog_alloff(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + desc_t *d; + for(d = desc; d->name != NULL; d++) + brave_set(d->bit, 0); + brave2dlg(hid_ctx); +} + +/* Copy the config from CLI to USER and flush the file */ +static void brave_dialog_save(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_conf_set(RND_CFR_USER, "rc/brave", 0, conf_core.rc.brave, RND_POL_OVERWRITE); + if (rnd_conf_isdirty(RND_CFR_USER)) + rnd_conf_save_file(&PCB->hidlib, NULL, NULL, RND_CFR_USER, NULL); +} + +static int brave_interact(void) +{ + desc_t *d; + int len; + rnd_hid_dad_buttons_t btn[] = {{"Close", 0}, {NULL, 0}}; + RND_DAD_DECL(dlg); + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(dlg, "Experimental features for the brave"); + + RND_DAD_BEGIN_TABLE(dlg, 3); + for(d = desc, len=0; d->name != NULL; d++,len++) { + RND_DAD_LABEL(dlg, d->name); + RND_DAD_HELP(dlg, d->lng); + RND_DAD_BOOL(dlg); + d->widget = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, brave_dialog_chg); + RND_DAD_HELP(dlg, d->lng); + RND_DAD_LABEL(dlg, d->shrt); + RND_DAD_HELP(dlg, d->lng); + } + RND_DAD_END(dlg); + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_END(dlg); + RND_DAD_BEGIN_HBOX(dlg); + if (len != 0) { + RND_DAD_BUTTON(dlg, "all ON"); + RND_DAD_HELP(dlg, "Tick in all boxes\nenabling all experimental features\n(Super Brave Mode)"); + RND_DAD_CHANGE_CB(dlg, brave_dialog_allon); + RND_DAD_BUTTON(dlg, "all OFF"); + RND_DAD_HELP(dlg, "Tick off all boxes\ndisabling all experimental features\n(Safe Mode)"); + RND_DAD_CHANGE_CB(dlg, brave_dialog_alloff); + RND_DAD_BUTTON(dlg, "save in user cfg"); + RND_DAD_HELP(dlg, "Save current brave state in the \nuser configuration file"); + RND_DAD_CHANGE_CB(dlg, brave_dialog_save); + } + RND_DAD_END(dlg); + + if (len == 0) + RND_DAD_LABEL(dlg, "(There are no brave features at the moment)"); + + RND_DAD_BUTTON_CLOSES(dlg, btn); + RND_DAD_END(dlg); + + + RND_DAD_NEW("brave", dlg, "Brave features", dlg, rnd_true, NULL); + brave2dlg(dlg_hid_ctx); + RND_DAD_RUN(dlg); + RND_DAD_FREE(dlg); + return 0; +} + +/*** action ***/ + +static const char pcb_acts_Brave[] = + "Brave()\n" + "Brave(setting, on|off)\n"; +static const char pcb_acth_Brave[] = "Changes brave settings."; +static fgw_error_t pcb_act_Brave(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + desc_t *d; + const char *name, *op; + if (argc <= 1) { + RND_ACT_IRES(brave_interact()); + return 0; + } + + /* look up */ + RND_ACT_CONVARG(1, FGW_STR, Brave, name = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, Brave, op = argv[2].val.str); + d = find_by_name(name); + if (d == NULL) { + rnd_message(RND_MSG_ERROR, "Unknown brave setting: %s\n", name); + RND_ACT_IRES(-1); + return 0; + } + brave_set(d->bit, (rnd_strcasecmp(op, "on") == 0)); + + rnd_message(RND_MSG_INFO, "Brave setting: %s in %s\n", name, (pcb_brave & d->bit) ? "on" : "off"); + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t brave_action_list[] = { + {"Brave", pcb_act_Brave, pcb_acth_Brave, pcb_acts_Brave} +}; + +void pcb_brave_init2(void) +{ + RND_REGISTER_ACTIONS(brave_action_list, NULL); +} + +void pcb_brave_init(void) +{ + rnd_conf_native_t *n = rnd_conf_get_field("rc/brave"); + brave_conf_id = rnd_conf_hid_reg(brave_cookie, NULL); + + if (n != NULL) { + static rnd_conf_hid_callbacks_t cbs; + memset(&cbs, 0, sizeof(rnd_conf_hid_callbacks_t)); + cbs.val_change_post = brave_conf_chg; + rnd_conf_hid_set_cb(n, brave_conf_id, &cbs); + } +} + +void pcb_brave_uninit(void) +{ + rnd_conf_hid_unreg(brave_cookie); +} Index: tags/2.3.0/src/brave.h =================================================================== --- tags/2.3.0/src/brave.h (nonexistent) +++ tags/2.3.0/src/brave.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_BRAVE_H +#define PCB_BRAVE_H +typedef enum { /* bitfield */ + PCB_BRAVE_OFF = 0, + PCB_BRAVE_NOXOR = 1, + PCB_BRAVE_NOCLIPBATCH = 2, + PCB_BRAVE_max +} pcb_brave_t; + +extern pcb_brave_t pcb_brave; /* cache generated from the config */ + +void pcb_brave_init(void); +void pcb_brave_uninit(void); +#endif Index: tags/2.3.0/src/buffer.c =================================================================== --- tags/2.3.0/src/buffer.c (nonexistent) +++ tags/2.3.0/src/buffer.c (revision 33253) @@ -0,0 +1,1244 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2005 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* functions used by paste- and move/copy buffer + */ +#include "config.h" +#include "conf_core.h" + +#include "buffer.h" +#include "board.h" +#include "move.h" +#include "data.h" +#include "plug_io.h" +#include "polygon.h" +#include "rotate.h" +#include "remove.h" +#include "select.h" +#include "draw.h" +#include "undo.h" +#include "funchash_core.h" +#include +#include +#include "obj_arc_op.h" +#include "obj_line_op.h" +#include "obj_text_op.h" +#include "obj_subc_op.h" +#include "obj_poly_op.h" +#include "obj_pstk_op.h" +#include "obj_gfx_op.h" +#include "obj_rat_op.h" +#include "obj_pstk.h" +#include "layer_grp.h" +#include +#include +#include +#include +#include "extobj.h" +#include + +static int move_buffer_pre(pcb_opctx_t *ctx, pcb_any_obj_t *ptr2, void *ptr3); +static void move_buffer_post(pcb_opctx_t *ctx, pcb_any_obj_t *ptr2, void *ptr3); +static int add_buffer_pre(pcb_opctx_t *ctx, pcb_any_obj_t *ptr2, void *ptr3); + +static pcb_opfunc_t AddBufferFunctions = { + add_buffer_pre, + NULL, /* common_post */ + pcb_lineop_add_to_buffer, + pcb_textop_add_to_buffer, + pcb_polyop_add_to_buffer, + NULL, + NULL, + pcb_arcop_add_to_buffer, + pcb_gfxop_add_to_buffer, + pcb_ratop_add_to_buffer, + NULL, + pcb_subcop_add_to_buffer, + pcb_pstkop_add_to_buffer, + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t MoveBufferFunctions = { + move_buffer_pre, + move_buffer_post, + pcb_lineop_move_buffer, + pcb_textop_move_buffer, + pcb_polyop_move_buffer, + NULL, + NULL, + pcb_arcop_move_buffer, + pcb_gfxop_move_buffer, + pcb_ratop_move_buffer, + NULL, + pcb_subcop_move_buffer, + pcb_pstkop_move_buffer, + 0 /* extobj_inhibit_regen */ +}; + +static int move_buffer_pre(pcb_opctx_t *ctx, pcb_any_obj_t *obj, void *ptr3) +{ + ctx->buffer.post_subc = pcb_extobj_get_floater_subc(obj); + + if (ctx->buffer.removing) + return 0; /* don't do anything extobj-special for removing, it's already been done */ + + /* when an edit-object is moved to buffer, the corresponding subc obj needs to be moved too */ + if (ctx->buffer.post_subc != NULL) { + pcb_subcop_move_buffer(ctx, ctx->buffer.post_subc); + return 1; + } + return 0; +} + +static void move_buffer_post(pcb_opctx_t *ctx, pcb_any_obj_t *obj, void *ptr3) +{ + if ((!ctx->buffer.removing) || (ctx->buffer.post_subc == NULL)) + return; + + /* when an edit-object is moved to buffer, the corresponding subc obj needs to be moved too */ + if (ctx->buffer.post_subc != NULL) { + pcb_extobj_subc_geo(ctx->buffer.post_subc); + ctx->buffer.post_subc = NULL; + } +} + +static int add_buffer_pre(pcb_opctx_t *ctx, pcb_any_obj_t *obj, void *ptr3) +{ + pcb_subc_t *subc = pcb_extobj_get_floater_subc(obj); + + /* when an edit-object is moved to buffer, the corresponding subc obj needs to be moved too */ + if (subc != NULL) { + /* make sure the same subc is not copied twice by detecting a copy already done from the same subc to the same buffer */ + pcb_subc_t *bsc; + gdl_iterator_t it; + subclist_foreach(&ctx->buffer.dst->subc, &it, bsc) { + if (bsc->copied_from_ID == subc->ID) + return 1; + } + pcb_subcop_add_to_buffer(ctx, subc); + return 1; + } + return 0; + +} + +int pcb_set_buffer_bbox(pcb_buffer_t *Buffer) +{ + rnd_box_t tmp, *box; + int res = 0; + + box = pcb_data_bbox(&tmp, Buffer->Data, rnd_false); + if (box) + Buffer->BoundingBox = *box; + else + res = -1; + + box = pcb_data_bbox_naked(&tmp, Buffer->Data, rnd_false); + if (box) + Buffer->bbox_naked = *box; + else + res = -1; + + return res; +} + +static void pcb_buffer_clear_(pcb_board_t *pcb, pcb_buffer_t *Buffer, rnd_bool bind) +{ + if (Buffer && Buffer->Data) { + void *old_parent = Buffer->Data->parent.any; + pcb_parenttype_t old_pt = Buffer->Data->parent_type; + + pcb_data_uninit(Buffer->Data); + pcb_data_init(Buffer->Data); + + Buffer->Data->parent.any = old_parent; + Buffer->Data->parent_type = old_pt; + if ((pcb != NULL) && (bind)) + pcb_data_bind_board_layers(pcb, Buffer->Data, 0); + } + Buffer->from_outside = 0; + free(Buffer->source_path); Buffer->source_path = NULL; + Buffer->X = Buffer->Y = 0; +} + +void pcb_buffer_clear(pcb_board_t *pcb, pcb_buffer_t *Buffer) +{ + pcb_buffer_clear_(pcb, Buffer, rnd_true); +} + +/* add (or move) selected */ +static void pcb_buffer_toss_selected(pcb_opfunc_t *fnc, pcb_board_t *pcb, pcb_buffer_t *Buffer, rnd_coord_t X, rnd_coord_t Y, rnd_bool LeaveSelected, rnd_bool on_locked_too, rnd_bool keep_id) +{ + rnd_hidlib_t *hidlib = (rnd_hidlib_t *)pcb; + pcb_opctx_t ctx; + + ctx.buffer.pcb = pcb; + ctx.buffer.keep_id = keep_id; + ctx.buffer.removing = 0; + + /* switch crosshair off because adding objects to the pastebuffer + * may change the 'valid' area for the cursor + */ + if (!LeaveSelected) + ctx.buffer.extraflg = PCB_FLAG_SELECTED; + else + ctx.buffer.extraflg = 0; + + rnd_hid_notify_crosshair_change(hidlib, rnd_false); + ctx.buffer.src = pcb->Data; + ctx.buffer.dst = Buffer->Data; + pcb_selected_operation(pcb, pcb->Data, fnc, &ctx, rnd_false, PCB_OBJ_ANY & (~PCB_OBJ_SUBC_PART), (on_locked_too ? PCB_OP_ON_LOCKED : 0) | PCB_OP_NO_SUBC_PART); + + /* set origin to passed or current position */ + if (X || Y) { + Buffer->X = X; + Buffer->Y = Y; + } + else { + Buffer->X = pcb_crosshair.X; + Buffer->Y = pcb_crosshair.Y; + } + Buffer->from_outside = 0; + free(Buffer->source_path); Buffer->source_path = NULL; + rnd_hid_notify_crosshair_change(hidlib, rnd_true); +} + +void pcb_buffer_add_selected(pcb_board_t *pcb, pcb_buffer_t *Buffer, rnd_coord_t X, rnd_coord_t Y, rnd_bool LeaveSelected, rnd_bool keep_id) +{ + pcb_buffer_toss_selected(&AddBufferFunctions, pcb, Buffer, X, Y, LeaveSelected, rnd_false, keep_id); +} + +extern pcb_opfunc_t pcb_RemoveFunctions; +void pcb_buffer_move_selected(pcb_board_t *pcb, pcb_buffer_t *Buffer, rnd_coord_t X, rnd_coord_t Y, rnd_bool LeaveSelected, rnd_bool keep_id) +{ + pcb_buffer_toss_selected(&AddBufferFunctions, pcb, Buffer, X, Y, LeaveSelected, rnd_false, keep_id); + pcb_buffer_toss_selected(&pcb_RemoveFunctions, pcb, Buffer, X, Y, LeaveSelected, rnd_false, keep_id); + pcb_undo_inc_serial(); +} + +static const char pcb_acts_LoadFootprint[] = "LoadFootprint(filename[,refdes,value])"; +static const char pcb_acth_LoadFootprint[] = "Loads a single footprint by name."; +/* DOC: loadfootprint.html */ +fgw_error_t pcb_act_LoadFootprint(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *name, *refdes = NULL, *value = NULL; + pcb_subc_t *s; + rnd_cardinal_t len; + + + RND_ACT_CONVARG(1, FGW_STR, LoadFootprint, name = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, LoadFootprint, refdes = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, LoadFootprint, value = argv[3].val.str); + + if (!pcb_buffer_load_footprint(PCB_PASTEBUFFER, name, NULL)) { + RND_ACT_IRES(1); + return 0; + } + + len = pcb_subclist_length(&PCB_PASTEBUFFER->Data->subc); + + if (len == 0) { + rnd_message(RND_MSG_ERROR, "Footprint %s contains no subcircuits", name); + RND_ACT_IRES(1); + return 0; + } + if (len > 1) { + rnd_message(RND_MSG_ERROR, "Footprint %s contains multiple subcircuits", name); + RND_ACT_IRES(1); + return 0; + } + + s = pcb_subclist_first(&PCB_PASTEBUFFER->Data->subc); + pcb_attribute_put(&s->Attributes, "refdes", refdes); + pcb_attribute_put(&s->Attributes, "footprint", name); + pcb_attribute_put(&s->Attributes, "value", value); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_LoadPixmap[] = "LoadPixmap([filename])"; +static const char pcb_acth_LoadPixmap[] = "Loads a pixmap image from disk and creates a gfx object in buffer."; +fgw_error_t pcb_act_LoadPixmap(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fn = NULL; + double dpi = 600.0; + rnd_pixmap_t *pxm; + pcb_gfx_t *g; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadPixmap, fn = argv[1].val.str); + + if (fn == NULL) { + static char *default_file = NULL; + char *nfn; + nfn = rnd_gui->fileselect(rnd_gui, "Load pixmap into buffer gfx...", + "Choose a file to load the pixmap\nfor the gfx object to be created\nin the buffer.\n", + default_file, ".*", NULL, "gfx", RND_HID_FSD_READ | RND_HID_FSD_MAY_NOT_EXIST, NULL); + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + if (nfn == NULL) { /* cancel */ + RND_ACT_IRES(-1); + return 0; + } + fn = default_file = nfn; + } + + pxm = rnd_pixmap_load(RND_ACT_HIDLIB, fn); + if (pxm == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to load pixmap from '%s' - is that file a pixmap in any of the supported formats?\n", fn); + RND_ACT_IRES(-1); + return 0; + } + + g = pcb_gfx_new(&PCB_PASTEBUFFER->Data->Layer[PCB_CURRLID(pcb)], 0, 0, + RND_MIL_TO_COORD((double)pxm->sx / dpi * 1000.0), RND_MIL_TO_COORD((double)pxm->sy / dpi * 1000.0), + 0, pcb_flag_make(0)); + + pcb_gfx_set_pixmap_free(g, pxm, 0); + + RND_ACT_IRES(0); + return 0; +} + +rnd_bool pcb_buffer_load_layout(pcb_board_t *pcb, pcb_buffer_t *Buffer, const char *Filename, const char *fmt) +{ + pcb_board_t *orig, *newPCB = pcb_board_new_(rnd_false); + + orig = PCB; + PCB = newPCB; + pcb_layergrp_inhibit_inc(); + + /* new data isn't added to the undo list */ + if (!pcb_parse_pcb(newPCB, Filename, fmt, RND_CFR_invalid, 0)) { + pcb_data_t *tmpdata; + + /* clear data area and replace pointer */ + pcb_buffer_clear(pcb, Buffer); + tmpdata = Buffer->Data; + Buffer->Data = newPCB->Data; + newPCB->Data = tmpdata; + Buffer->X = 0; + Buffer->Y = 0; + PCB_CLEAR_PARENT(Buffer->Data); + pcb_data_make_layers_bound(newPCB, Buffer->Data); + pcb_data_binding_update(pcb, Buffer->Data); + pcb_board_free(newPCB); + free(newPCB); + Buffer->from_outside = 0; /* always place matching top-to-top, don't swap sides only because the user is viewing the board from the bottom */ + free(Buffer->source_path); Buffer->source_path = rnd_strdup(Filename); + PCB = orig; + pcb_layergrp_inhibit_dec(); + return rnd_true; + } + + /* release unused memory */ + pcb_board_free(newPCB); + free(newPCB); + if (Buffer->Data != NULL) + PCB_CLEAR_PARENT(Buffer->Data); + PCB = orig; + pcb_layergrp_inhibit_dec(); + Buffer->from_outside = 0; + free(Buffer->source_path); Buffer->source_path = NULL; + return rnd_false; +} + +void pcb_buffer_rotate90(pcb_buffer_t *Buffer, unsigned int Number) +{ + pcb_undo_freeze_serial(); + pcb_undo_freeze_add(); + + PCB_PADSTACK_LOOP(Buffer->Data); + { + pcb_pstk_rotate90(padstack, Buffer->X, Buffer->Y, Number); + } + PCB_END_LOOP; + + PCB_SUBC_LOOP(Buffer->Data); + { + pcb_obj_rotate90(PCB, (pcb_any_obj_t *)subc, Buffer->X, Buffer->Y, Number); + } + PCB_END_LOOP; + + /* all layer related objects */ + PCB_LINE_ALL_LOOP(Buffer->Data); + { + if (layer->line_tree != NULL) + rnd_r_delete_entry(layer->line_tree, (rnd_box_t *) line); + pcb_line_rotate90(line, Buffer->X, Buffer->Y, Number); + if (layer->line_tree != NULL) + rnd_r_insert_entry(layer->line_tree, (rnd_box_t *) line); + } + PCB_ENDALL_LOOP; + PCB_ARC_ALL_LOOP(Buffer->Data); + { + if (layer->arc_tree != NULL) + rnd_r_delete_entry(layer->arc_tree, (rnd_box_t *) arc); + pcb_arc_rotate90(arc, Buffer->X, Buffer->Y, Number); + if (layer->arc_tree != NULL) + rnd_r_insert_entry(layer->arc_tree, (rnd_box_t *) arc); + } + PCB_ENDALL_LOOP; + PCB_TEXT_ALL_LOOP(Buffer->Data); + { + if (layer->text_tree != NULL) + rnd_r_delete_entry(layer->text_tree, (rnd_box_t *) text); + pcb_text_rotate90(text, Buffer->X, Buffer->Y, Number); + if (layer->text_tree != NULL) + rnd_r_insert_entry(layer->text_tree, (rnd_box_t *) text); + } + PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(Buffer->Data); + { + if (layer->polygon_tree != NULL) + rnd_r_delete_entry(layer->polygon_tree, (rnd_box_t *) polygon); + pcb_poly_rotate90(polygon, Buffer->X, Buffer->Y, Number); + if (layer->polygon_tree != NULL) + rnd_r_insert_entry(layer->polygon_tree, (rnd_box_t *) polygon); + } + PCB_ENDALL_LOOP; + + /* finally the origin and the bounding box */ + RND_COORD_ROTATE90(Buffer->X, Buffer->Y, Buffer->X, Buffer->Y, Number); + rnd_box_rotate90(&Buffer->BoundingBox, Buffer->X, Buffer->Y, Number); + + pcb_undo_unfreeze_add(); + pcb_undo_unfreeze_serial(); +} + +void pcb_buffer_rotate(pcb_buffer_t *Buffer, rnd_angle_t angle) +{ + double cosa, sina; + + pcb_undo_freeze_serial(); + pcb_undo_freeze_add(); + + cosa = cos(angle * M_PI / 180.0); + sina = sin(angle * M_PI / 180.0); + + PCB_PADSTACK_LOOP(Buffer->Data); + { + pcb_pstk_rotate(padstack, Buffer->X, Buffer->Y, cosa, sina, angle); + } + PCB_END_LOOP; + + PCB_SUBC_LOOP(Buffer->Data); + { + pcb_subc_rotate(subc, Buffer->X, Buffer->Y, cosa, sina, angle); + } + PCB_END_LOOP; + + /* all layer related objects */ + PCB_LINE_ALL_LOOP(Buffer->Data); + { + pcb_line_rotate(layer, line, Buffer->X, Buffer->Y, cosa, sina); + } + PCB_ENDALL_LOOP; + PCB_ARC_ALL_LOOP(Buffer->Data); + { + pcb_arc_rotate(layer, arc, Buffer->X, Buffer->Y, cosa, sina, angle); + } + PCB_ENDALL_LOOP; + PCB_TEXT_ALL_LOOP(Buffer->Data); + { + pcb_text_rotate(text, Buffer->X, Buffer->Y, cosa, sina, angle); + } + PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(Buffer->Data); + { + pcb_poly_rotate(layer, polygon, Buffer->X, Buffer->Y, cosa, sina); + } + PCB_ENDALL_LOOP; + + pcb_set_buffer_bbox(Buffer); + pcb_undo_unfreeze_add(); + pcb_undo_unfreeze_serial(); +} + +pcb_data_t *pcb_buffer_new(pcb_board_t *pcb) +{ + return pcb_data_new(pcb); +} + + +static const char pcb_acts_FreeRotateBuffer[] = "FreeRotateBuffer([Angle])"; +static const char pcb_acth_FreeRotateBuffer[] = + "Rotates the current paste buffer contents by the specified angle. The\n" + "angle is given in degrees. If no angle is given, the user is prompted\n" "for one.\n"; +/* DOC: freerotatebuffer */ +fgw_error_t pcb_act_FreeRotateBuffer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char *angle_s = NULL; + double ang; + + RND_ACT_MAY_CONVARG(1, FGW_STR, FreeRotateBuffer, angle_s = rnd_strdup(argv[1].val.str)); + RND_ACT_IRES(0); + + if (angle_s == NULL) + angle_s = rnd_hid_prompt_for(RND_ACT_HIDLIB, "Enter Rotation (degrees, CCW):", "0", "Rotation angle"); + + if ((angle_s == NULL) || (*angle_s == '\0')) { + free(angle_s); + RND_ACT_IRES(-1); + return 0; + } + + RND_ACT_IRES(0); + ang = strtod(angle_s, 0); + free(angle_s); + if (ang == 0) { + RND_ACT_IRES(-1); + return 0; + } + + if ((ang < -360000) || (ang > +360000)) { + rnd_message(RND_MSG_ERROR, "Angle too large\n"); + RND_ACT_IRES(-1); + return 0; + } + + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + pcb_buffer_rotate(PCB_PASTEBUFFER, ang); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + return 0; +} + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int wx, wy, wlock, wth, wrecurse; +} scale_t; + +/* make sure x;y values are synced when lock is active */ +static void scale_chg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + scale_t *ctx = caller_data; + int wid = attr - ctx->dlg, locked = ctx->dlg[ctx->wlock].val.lng; + rnd_hid_attr_val_t hv; + + if (!locked) + return; + + if (wid == ctx->wy) { /* copy y into x */ + hv.dbl = ctx->dlg[ctx->wy].val.dbl; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wx, &hv); + } + else { /* copy x into y */ + hv.dbl = ctx->dlg[ctx->wx].val.dbl; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wy, &hv); + } +} + +/* returns 0 on OK */ +static int pcb_actgui_ScaleBuffer(rnd_hidlib_t *hidlib, double *x, double *y, double *th, int *recurse) +{ + scale_t ctx; + int res; + + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"Apply", 0}, {NULL, 0}}; + + memset(&ctx, 0, sizeof(ctx)); + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABLE(ctx.dlg, 2); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + + RND_DAD_LABEL(ctx.dlg, "scale X"); + RND_DAD_REAL(ctx.dlg); + ctx.wx = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_DEFAULT_NUM(ctx.dlg, 1); + RND_DAD_CHANGE_CB(ctx.dlg, scale_chg_cb); + + RND_DAD_LABEL(ctx.dlg, "same"); + RND_DAD_BOOL(ctx.dlg); + ctx.wlock = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_DEFAULT_NUM(ctx.dlg, 1); + RND_DAD_CHANGE_CB(ctx.dlg, scale_chg_cb); + + RND_DAD_LABEL(ctx.dlg, "scale Y"); + RND_DAD_REAL(ctx.dlg); + ctx.wy = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_DEFAULT_NUM(ctx.dlg, 1); + RND_DAD_CHANGE_CB(ctx.dlg, scale_chg_cb); + + RND_DAD_LABEL(ctx.dlg, "scale thickness"); + RND_DAD_REAL(ctx.dlg); + ctx.wth = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_DEFAULT_NUM(ctx.dlg, 1); + + RND_DAD_LABEL(ctx.dlg, "subcircuits"); + RND_DAD_BOOL(ctx.dlg); + ctx.wrecurse = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_DEFAULT_NUM(ctx.dlg, 0); + + RND_DAD_BUTTON_CLOSES(ctx.dlg, clbtn); + RND_DAD_END(ctx.dlg); + + RND_DAD_NEW("buffer_scale", ctx.dlg, "Buffer scale factors", &ctx, rnd_true, NULL); + res = RND_DAD_RUN(ctx.dlg); + *x = ctx.dlg[ctx.wx].val.dbl; + *y = ctx.dlg[ctx.wy].val.dbl; + *th = ctx.dlg[ctx.wth].val.dbl; + *recurse = ctx.dlg[ctx.wrecurse].val.lng; + RND_DAD_FREE(ctx.dlg); + return res; +} + +static const char pcb_acts_ScaleBuffer[] = "ScaleBuffer(x [,y [,thickness [,subc]]])"; +static const char pcb_acth_ScaleBuffer[] = + "Scales the buffer by multiplying all coordinates by a floating point number.\n" + "If only x is given, it is also used for y and thickness too. If subc is not\n" + "empty, subcircuits are also scaled\n"; +fgw_error_t pcb_act_ScaleBuffer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *sx = NULL; + double x, y, th; + int recurse = 0; + char *end; + + RND_ACT_MAY_CONVARG(1, FGW_STR, ScaleBuffer, sx = argv[1].val.str); + + if (sx != NULL) { + x = strtod(sx, &end); + if (*end != '\0') { + RND_ACT_IRES(-1); + return 0; + } + y = th = x; + } + else { + if (pcb_actgui_ScaleBuffer(RND_ACT_HIDLIB, &x, &y, &th, &recurse) != 0) { + RND_ACT_IRES(-1); + return 0; + } + } + + RND_ACT_MAY_CONVARG(2, FGW_DOUBLE, ScaleBuffer, y = argv[2].val.nat_double); + RND_ACT_MAY_CONVARG(3, FGW_DOUBLE, ScaleBuffer, th = argv[3].val.nat_double); + RND_ACT_MAY_CONVARG(4, FGW_STR, ScaleBuffer, recurse = (argv[4].val.str != NULL)); + + if ((x <= 0) || (y <= 0)) { + RND_ACT_IRES(-1); + return 0; + } + + RND_ACT_IRES(0); + + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + pcb_buffer_scale(PCB_PASTEBUFFER, x, y, th, recurse); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + return 0; +} + + +void pcb_init_buffers(pcb_board_t *pcb) +{ + int i; + + for (i = 0; i < PCB_MAX_BUFFER; i++) + pcb_buffers[i].Data = pcb_buffer_new(NULL); +} + +void pcb_uninit_buffers(pcb_board_t *pcb) +{ + int i; + + for (i = 0; i < PCB_MAX_BUFFER; i++) { + pcb_buffer_clear_(pcb, pcb_buffers+i, rnd_false); + pcb_data_uninit(pcb_buffers[i].Data); + free(pcb_buffers[i].Data); + } +} + +void pcb_buffer_mirror(pcb_board_t *pcb, pcb_buffer_t *Buffer) +{ + int i, num_layers; + + num_layers = PCB_PASTEBUFFER->Data->LayerN; + if (num_layers == 0) /* some buffers don't have layers, just simple objects */ + num_layers = pcb->Data->LayerN; + + for (i = 0; i < num_layers; i++) { + pcb_layer_t *layer = Buffer->Data->Layer + i; + if (textlist_length(&layer->Text)) { + rnd_message(RND_MSG_ERROR, "You can't mirror a buffer that has text!\n"); + return; + } + } + /* set buffer offset to 'mark' position */ + Buffer->X = PCB_SWAP_X(Buffer->X); + Buffer->Y = PCB_SWAP_Y(Buffer->Y); + pcb_undo_freeze_add(); + pcb_data_mirror(Buffer->Data, 0, PCB_TXM_COORD, rnd_false, 0); + pcb_undo_unfreeze_add(); + pcb_set_buffer_bbox(Buffer); +} + +void pcb_buffer_scale(pcb_buffer_t *Buffer, double sx, double sy, double sth, int recurse) +{ + pcb_data_scale(Buffer->Data, sx, sy, sth, recurse); + Buffer->X = rnd_round((double)Buffer->X * sx); + Buffer->Y = rnd_round((double)Buffer->Y * sy); + pcb_set_buffer_bbox(Buffer); +} + +void pcb_buffer_flip_side(pcb_board_t *pcb, pcb_buffer_t *Buffer) +{ +#if 0 +/* this results in saving flipped (bottom-side) footprints whenlooking at the board from the bottom */ + PCB_SUBC_LOOP(Buffer->Data); + { + pcb_subc_change_side(subc, /*2 * pcb_crosshair.Y - pcb->hidlib.size_y*/0); + } + PCB_END_LOOP; +#endif + + /* set buffer offset to 'mark' position */ + Buffer->X = PCB_SWAP_X(Buffer->X); + Buffer->Y = PCB_SWAP_Y(Buffer->Y); + + PCB_PADSTACK_LOOP(Buffer->Data); + { + pcb_pstk_mirror(padstack, PCB_PSTK_DONT_MIRROR_COORDS, 1, 0, 0); + } + PCB_END_LOOP; + PCB_LINE_ALL_LOOP(Buffer->Data); + { + pcb_line_flip_side(layer, line); + } + PCB_ENDALL_LOOP; + PCB_ARC_ALL_LOOP(Buffer->Data); + { + pcb_arc_flip_side(layer, arc); + } + PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(Buffer->Data); + { + pcb_poly_flip_side(layer, polygon); + } + PCB_ENDALL_LOOP; + PCB_TEXT_ALL_LOOP(Buffer->Data); + { + pcb_text_flip_side(layer, text, 0, 0); + } + PCB_ENDALL_LOOP; + + pcb_set_buffer_bbox(Buffer); +} + +void pcb_buffers_flip_side(pcb_board_t *pcb) +{ + int i; + + for (i = 0; i < PCB_MAX_BUFFER; i++) + pcb_buffer_flip_side(pcb, &pcb_buffers[i]); +} + +void *pcb_move_obj_to_buffer(pcb_board_t *pcb, pcb_data_t *Destination, pcb_data_t *Src, int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + pcb_opctx_t ctx; + + /* setup local identifiers used by move operations */ + ctx.buffer.pcb = pcb; + ctx.buffer.dst = Destination; + ctx.buffer.src = Src; + ctx.buffer.removing = (Destination == pcb_removelist); + return (pcb_object_operation(&MoveBufferFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3)); +} + +void *pcb_copy_obj_to_buffer(pcb_board_t *pcb, pcb_data_t *Destination, pcb_data_t *Src, int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + pcb_opctx_t ctx; + + ctx.buffer.pcb = pcb; + ctx.buffer.dst = Destination; + ctx.buffer.src = Src; + ctx.buffer.removing = 0; + return (pcb_object_operation(&AddBufferFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3)); +} + +rnd_bool pcb_buffer_copy_to_layout(pcb_board_t *pcb, rnd_coord_t X, rnd_coord_t Y, rnd_bool keep_id) +{ + rnd_cardinal_t i; + rnd_bool changed = rnd_false; + pcb_opctx_t ctx; + int num_layers; + +#ifdef DEBUG + printf("Entering CopyPastebufferToLayout.....\n"); +#endif + + pcb_data_clip_inhibit_inc(pcb->Data); + + /* set movement vector */ + ctx.copy.pcb = pcb; + ctx.copy.DeltaX = X - PCB_PASTEBUFFER->X; + ctx.copy.DeltaY = Y - PCB_PASTEBUFFER->Y; + ctx.copy.from_outside = PCB_PASTEBUFFER->from_outside; + ctx.copy.keep_id = keep_id; + + /* paste all layers */ + num_layers = PCB_PASTEBUFFER->Data->LayerN; + if (num_layers != 0) /* some buffers don't have layers, just global objects */ + for (i = 0; i < num_layers; i++) { + pcb_layer_t *sourcelayer = &PCB_PASTEBUFFER->Data->Layer[i]; + pcb_layer_t *destlayer = pcb_layer_resolve_binding(pcb, sourcelayer); + + if (destlayer == NULL) { + if ((!(sourcelayer->meta.bound.type & PCB_LYT_VIRTUAL)) && (!pcb_layer_is_pure_empty(sourcelayer))) { + const char *src_name = sourcelayer->name; + if ((src_name == NULL) || (*src_name == '\0')) + src_name = ""; + rnd_message(RND_MSG_WARNING, "Couldn't resolve buffer layer #%d (%s) on the current board\n", i, src_name); + } + continue; + } + + destlayer = pcb_loose_subc_layer(PCB, destlayer, rnd_true); + + if (destlayer->meta.real.vis) { + PCB_LINE_LOOP(sourcelayer); + { + pcb_line_t *nline = pcb_lineop_copy(&ctx, destlayer, line); + if (nline != NULL) { + if (keep_id) + pcb_extobj_float_geo((pcb_any_obj_t *)nline); + changed = 1; + } + } + PCB_END_LOOP; + PCB_ARC_LOOP(sourcelayer); + { + pcb_arc_t *narc = pcb_arcop_copy(&ctx, destlayer, arc); + if (narc != NULL) { + if (keep_id) + pcb_extobj_float_geo((pcb_any_obj_t *)narc); + changed = 1; + } + } + PCB_END_LOOP; + PCB_TEXT_LOOP(sourcelayer); + { + pcb_text_t *ntext = pcb_textop_copy(&ctx, destlayer, text); + if (ntext != NULL) { + if (keep_id) + pcb_extobj_float_geo((pcb_any_obj_t *)ntext); + changed = 1; + } + } + PCB_END_LOOP; + PCB_POLY_LOOP(sourcelayer); + { + pcb_poly_t *npoly = pcb_polyop_copy(&ctx, destlayer, polygon); + if (npoly != NULL) { + if (keep_id) + pcb_extobj_float_geo((pcb_any_obj_t *)npoly); + changed = 1; + } + } + PCB_END_LOOP; + PCB_GFX_LOOP(sourcelayer); + { + pcb_gfx_t *ngfx = pcb_gfxop_copy(&ctx, destlayer, gfx); + if (ngfx != NULL) { + if (keep_id) + pcb_extobj_float_geo((pcb_any_obj_t *)ngfx); + changed = 1; + } + } + PCB_END_LOOP; + } + } + + /* paste subcircuits */ + PCB_SUBC_LOOP(PCB_PASTEBUFFER->Data); + { + pcb_subc_t *nsubc; + if (pcb->is_footprint) { + rnd_message(RND_MSG_WARNING, "Can not paste subcircuit in the footprint edit mode\n"); + break; + } + nsubc = pcb_subcop_copy(&ctx, subc); + if (nsubc != NULL) { + if (keep_id) + pcb_extobj_float_geo((pcb_any_obj_t *)nsubc); + changed = 1; + } + } + PCB_END_LOOP; + + /* finally: padstacks */ + if (pcb->pstk_on) { + pcb_board_t dummy; + changed |= (padstacklist_length(&(PCB_PASTEBUFFER->Data->padstack)) != 0); + + /* set up a dummy board to work around that pcb_pstkop_copy() requires a + pcb_board_t instead of a pcb_data_t */ + if (pcb->is_footprint) { + pcb_subc_t *sc = pcb_subclist_first(&pcb->Data->subc); + if (sc != NULL) { + ctx.copy.pcb = &dummy; + memset(&dummy, 0, sizeof(dummy)); + dummy.Data = sc->data; + } + } + + PCB_PADSTACK_LOOP(PCB_PASTEBUFFER->Data); + { + pcb_pstk_t *nps; + nps = pcb_pstkop_copy(&ctx, padstack); + if (nps != NULL) { + if (keep_id) + pcb_extobj_float_geo((pcb_any_obj_t *)nps); + changed = 1; + } + } + PCB_END_LOOP; + } + + if (changed) { + pcb_subc_as_board_update(PCB); + pcb_draw(); + pcb_undo_inc_serial(); + } + +#ifdef DEBUG + printf(" .... Leaving CopyPastebufferToLayout.\n"); +#endif + + pcb_data_clip_inhibit_dec(pcb->Data, rnd_true); + + return changed; +} + +void pcb_buffer_set_number(int Number) +{ + if (Number >= 0 && Number < PCB_MAX_BUFFER) + rnd_conf_set_design("editor/buffer_number", "%d", Number); +} + +/* loads footprint data from file/library into buffer (as subcircuit) + * returns rnd_false on error + * if successful, update some other stuff and reposition the pastebuffer */ +rnd_bool pcb_buffer_load_footprint(pcb_buffer_t *Buffer, const char *Name, const char *fmt) +{ + pcb_buffer_clear(PCB, Buffer); + if (!pcb_parse_footprint(Buffer->Data, Name, fmt)) { + if (conf_core.editor.show_solder_side) + pcb_buffer_flip_side(PCB, Buffer); + pcb_set_buffer_bbox(Buffer); + + Buffer->X = 0; + Buffer->Y = 0; + Buffer->from_outside = 1; + free(Buffer->source_path); Buffer->source_path = rnd_strdup(Name); + + if (pcb_subclist_length(&Buffer->Data->subc)) { + pcb_subc_t *subc = pcb_subclist_first(&Buffer->Data->subc); + pcb_subc_get_origin(subc, &Buffer->X, &Buffer->Y); + } + + /* the loader may have created new layers */ + pcb_data_binding_update(PCB, Buffer->Data); + + return rnd_true; + } + + /* release memory which might have been acquired */ + pcb_buffer_clear(PCB, Buffer); + return rnd_false; +} + + +static const char pcb_acts_PasteBuffer[] = + "PasteBuffer(AddSelected|MoveSelected|Clear|1..PCB_MAX_BUFFER)\n" + "PasteBuffer(Rotate, 1..3)\n" + "PasteBuffer(Convert|Restore|Mirror)\n" + "PasteBuffer(ToLayout, X, Y, units)\n" + "PasteBuffer(ToLayout, crosshair)\n" + "PasteBuffer(Save, Filename, [format], [force])\n" + "PasteBuffer(SaveAll, Filename, [format])\n" + "PasteBuffer(LoadAll, Filename)\n" + "PasteBuffer(Push)\n" + "PasteBuffer(Pop)\n" + "PasteBuffer(GetSource, [1..PCB_MAX_BUFFER])\n" + ; +static const char pcb_acth_PasteBuffer[] = "Various operations on the paste buffer."; +/* DOC: pastebuffer.html */ +static fgw_error_t pcb_act_PasteBuffer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op, force; + const char *sbufnum = "", *fmt = NULL, *forces = NULL, *name, *tmp; + static char *default_file = NULL; + rnd_bool free_name = rnd_false; + static int stack[32]; + static int sp = 0; + int number, rv; + + RND_ACT_CONVARG(1, FGW_STR, PasteBuffer, tmp = argv[1].val.str); + number = atoi(tmp); + RND_ACT_CONVARG(1, FGW_KEYWORD, PasteBuffer, op = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, PasteBuffer, sbufnum = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, PasteBuffer, fmt = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, PasteBuffer, forces = argv[4].val.str); + + force = (forces != NULL) && ((*forces == '1') || (*forces == 'y') || (*forces == 'Y')); + + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + switch (op) { + /* clear contents of paste buffer */ + case F_Clear: + pcb_buffer_clear(PCB, PCB_PASTEBUFFER); + break; + + case F_Push: + if (sp < sizeof(stack) / sizeof(stack[0])) + stack[sp++] = conf_core.editor.buffer_number; + else + rnd_message(RND_MSG_ERROR, "Paste buffer stack overflow on push.\n"); + break; + + case F_Pop: + if (sp > 0) + pcb_buffer_set_number(stack[--sp]); + else + rnd_message(RND_MSG_ERROR, "Paste buffer stack underflow on pop.\n"); + break; + + /* copies objects to paste buffer */ + case F_AddSelected: + pcb_buffer_add_selected(PCB, PCB_PASTEBUFFER, 0, 0, rnd_false, rnd_false); + if (pcb_data_is_empty(PCB_PASTEBUFFER->Data)) { + rnd_message(RND_MSG_WARNING, "Nothing buffer-movable is selected, nothing copied to the paste buffer\n"); + goto error; + } + break; + + /* cuts objects to paste buffer; it's different from AddSelected+RemoveSelected in extobj side effects */ + case F_MoveSelected: + pcb_buffer_move_selected(PCB, PCB_PASTEBUFFER, 0, 0, rnd_false, rnd_false); + if (pcb_data_is_empty(PCB_PASTEBUFFER->Data)) { + rnd_message(RND_MSG_WARNING, "Nothing buffer-movable is selected, nothing moved to the paste buffer\n"); + goto error; + } + break; + + /* converts buffer contents into a subcircuit */ + case F_Convert: + case F_ConvertSubc: + pcb_subc_convert_from_buffer(PCB_PASTEBUFFER); + break; + + /* break up subcircuit for editing */ + case F_Restore: + if (!pcb_subc_smash_buffer(PCB_PASTEBUFFER)) + rnd_message(RND_MSG_ERROR, "Error breaking up subcircuits - only one can be broken up at a time\n"); + break; + + /* Mirror buffer */ + case F_Mirror: + pcb_buffer_mirror(PCB, PCB_PASTEBUFFER); + break; + + case F_Rotate: + if (sbufnum) { + int numtmp = atoi(sbufnum); + if (numtmp < 0) + numtmp = 4-numtmp; + pcb_buffer_rotate90(PCB_PASTEBUFFER, (unsigned int)numtmp); + } + break; + + case F_SaveAll: + free_name = rnd_false; + if (argc <= 2) { + name = rnd_gui->fileselect(rnd_gui, "Save Paste Buffer As ...", + "Choose a file to save the contents of the\npaste buffer to.\n", + default_file, ".lht", NULL, "buffer", 0, NULL); + + if (default_file) { + free(default_file); + default_file = NULL; + } + if (name && *name) + default_file = rnd_strdup(name); + free_name = rnd_true; + } + else + name = sbufnum; + + { + FILE *exist; + + if ((!force) && ((exist = rnd_fopen(RND_ACT_HIDLIB, name, "r")))) { + fclose(exist); + if (rnd_hid_message_box(RND_ACT_HIDLIB, "warning", "Buffer: overwrite file", "File exists! Ok to overwrite?", "cancel", 0, "yes", 1, NULL) == 1) + pcb_save_buffer(name, fmt); + } + else + pcb_save_buffer(name, fmt); + + if (free_name && name) + free((char*)name); + } + break; + + case F_LoadAll: + free_name = rnd_false; + if (argc <= 2) { + name = rnd_gui->fileselect(rnd_gui, "Load Paste Buffer ...", + "Choose a file to load the contents of the\npaste buffer from.\n", + default_file, ".lht", NULL, "buffer", RND_HID_FSD_READ | RND_HID_FSD_MAY_NOT_EXIST, NULL); + + if (default_file) { + free(default_file); + default_file = NULL; + } + if (name && *name) + default_file = rnd_strdup(name); + free_name = rnd_true; + } + else + name = sbufnum; + + if (pcb_load_buffer(RND_ACT_HIDLIB, PCB_PASTEBUFFER, name, NULL) != 0) { + rnd_message(RND_MSG_ERROR, "Failed to load buffer from %s\n", name); + RND_ACT_IRES(-1); + } + else + rnd_tool_select_by_name(RND_ACT_HIDLIB, "buffer"); + break; + + case F_Save: + name = sbufnum; + rv = rnd_actionva(RND_ACT_HIDLIB, "SaveTo", "PasteBuffer", name, fmt, NULL); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + return rv; + + case F_ToLayout: + { + static rnd_coord_t oldx = 0, oldy = 0; + rnd_coord_t x, y; + rnd_bool absolute; + if (argc == 2) { + x = y = 0; + } + else if (strcmp(sbufnum, "crosshair") == 0) { + x = pcb_crosshair.X; + y = pcb_crosshair.Y; + } + else if (argc == 4 || argc == 5) { + x = rnd_get_value(sbufnum, forces, &absolute, NULL); + if (!absolute) + x += oldx; + y = rnd_get_value(fmt, forces, &absolute, NULL); + if (!absolute) + y += oldy; + } + + else { + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + RND_ACT_FAIL(PasteBuffer); + } + + oldx = x; + oldy = y; + if (pcb_buffer_copy_to_layout(PCB, x, y, rnd_false)) + pcb_board_set_changed_flag(PCB, rnd_true); + } + break; + + case F_Normalize: + pcb_set_buffer_bbox(PCB_PASTEBUFFER); + PCB_PASTEBUFFER->X = rnd_round(((double)PCB_PASTEBUFFER->BoundingBox.X1 + (double)PCB_PASTEBUFFER->BoundingBox.X2) / 2.0); + PCB_PASTEBUFFER->Y = rnd_round(((double)PCB_PASTEBUFFER->BoundingBox.Y1 + (double)PCB_PASTEBUFFER->BoundingBox.Y2) / 2.0); + break; + + case F_GetSource: + if ((sbufnum != NULL) && (*sbufnum != '\0')) { + char *end; + number = strtol(sbufnum, &end, 10); + if (*end != 0) { + rnd_message(RND_MSG_ERROR, "invalid buffer number '%s': should be an integer\n", sbufnum); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + return FGW_ERR_ARG_CONV; + } + number--; + if ((number < 0) || (number >= PCB_MAX_BUFFER)) { + rnd_message(RND_MSG_ERROR, "invalid buffer number '%d': out of range 1..%d\n", number+1, PCB_MAX_BUFFER); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + return FGW_ERR_ARG_CONV; + } + } + else + number = conf_core.editor.buffer_number; + res->type = FGW_STR; + res->val.str = pcb_buffers[number].source_path; + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + return 0; + + /* set number */ + default: + { + + + /* correct number */ + if (number) + pcb_buffer_set_number(number - 1); + } + } + + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + RND_ACT_IRES(0); + return 0; + + error:; + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + RND_ACT_IRES(-1); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static rnd_action_t buffer_action_list[] = { + {"FreeRotateBuffer", pcb_act_FreeRotateBuffer, pcb_acth_FreeRotateBuffer, pcb_acts_FreeRotateBuffer}, + {"ScaleBuffer", pcb_act_ScaleBuffer, pcb_acth_ScaleBuffer, pcb_acts_ScaleBuffer}, + {"LoadFootprint", pcb_act_LoadFootprint, pcb_acth_LoadFootprint, pcb_acts_LoadFootprint}, + {"LoadPixmap", pcb_act_LoadPixmap, pcb_acth_LoadPixmap, pcb_acts_LoadPixmap}, + {"PasteBuffer", pcb_act_PasteBuffer, pcb_acth_PasteBuffer, pcb_acts_PasteBuffer} +}; + +void pcb_buffer_init2(void) +{ + RND_REGISTER_ACTIONS(buffer_action_list, NULL); +} + + + Index: tags/2.3.0/src/buffer.h =================================================================== --- tags/2.3.0/src/buffer.h (nonexistent) +++ tags/2.3.0/src/buffer.h (revision 33253) @@ -0,0 +1,111 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Board independent paste buffers */ + +#ifndef PCB_BUFFER_H +#define PCB_BUFFER_H + +#include "obj_common.h" +#include + +struct pcb_buffer_s { /* information about the paste buffer */ + rnd_coord_t X, Y; /* offset */ + rnd_box_t BoundingBox; + rnd_box_t bbox_naked; + pcb_data_t *Data; /* data; not all members of pcb_board_t */ + int from_outside; /* data is coming from outside of the current board (lib, loaded board) */ + char *source_path; /* when from the outside, this field may remember the full path of the original source file */ +}; + +/* Recalculates the bounding box of the buffer; returns 0 on success */ +int pcb_set_buffer_bbox(pcb_buffer_t *); + +/* clears the contents of the paste buffer: free's data, but preserves parent */ +void pcb_buffer_clear(pcb_board_t *pcb, pcb_buffer_t *Buffer); + +/* adds (copies) all selected and visible objects to the paste buffer */ +void pcb_buffer_add_selected(pcb_board_t *pcb, pcb_buffer_t *Buffer, rnd_coord_t X, rnd_coord_t Y, rnd_bool LeaveSelected, rnd_bool keep_id); + +/* load a board into buffer parse the file with enabled 'PCB mode' */ +rnd_bool pcb_buffer_load_layout(pcb_board_t *pcb, pcb_buffer_t *Buffer, const char *Filename, const char *fmt); + +/* rotates the contents of the pastebuffer by Number * 90 degrees or free angle*/ +void pcb_buffer_rotate90(pcb_buffer_t *Buffer, unsigned int Number); +void pcb_buffer_rotate(pcb_buffer_t *Buffer, rnd_angle_t angle); + +/* flip elements/subcircuits/tracks from one side to the other; also swap + the layer stackup of padstacks */ +void pcb_buffers_flip_side(pcb_board_t *pcb); + +/* graphically mirror the buffer on the current side */ +void pcb_buffer_mirror(pcb_board_t *pcb, pcb_buffer_t *Buffer); + +/* Scale all coords and sizes by sx;sy and thicknesses by sth; + if recurse is non-zero, also scale subcircuits */ +void pcb_buffer_scale(pcb_buffer_t *Buffer, double sx, double sy, double sth, int recurse); + +/* Init/uninit all buffers (stored in board-independent global variables) */ +void pcb_init_buffers(pcb_board_t *pcb); +void pcb_uninit_buffers(pcb_board_t *pcb); + +/* Creates a new empty paste buffer */ +pcb_data_t *pcb_buffer_new(pcb_board_t *pcb); + +/* Moves the passed object to the passed buffer's data and removes it from its + original data; returns the new object pointer on success or NULL on fail */ +void *pcb_move_obj_to_buffer(pcb_board_t *pcb, pcb_data_t *Destination, pcb_data_t *Src, int Type, void *Ptr1, void *Ptr2, void *Ptr3); + +/* Adds/copies the passed object to the passed buffer's data; + returns the new object pointer on success or NULL on fail */ +void *pcb_copy_obj_to_buffer(pcb_board_t *pcb, pcb_data_t *Destination, pcb_data_t *Src, int Type, void *Ptr1, void *Ptr2, void *Ptr3); + + +/* This action is called from ActionElementAddIf() */ +fgw_error_t pcb_act_LoadFootprint(fgw_arg_t *res, int oargc, fgw_arg_t *oargv); + +/* pastes the contents of the buffer to the layout. Only visible objects + are handled by the routine. + If keep_id is true, do not change object IDs - this should be used only + in one specific case, when selected objects are moved using the buffer + (which means exactly 1 copy is made and the original version is removed). */ +rnd_bool pcb_buffer_copy_to_layout(pcb_board_t *pcb, rnd_coord_t X, rnd_coord_t Y, rnd_bool keep_id); + +/* change the side of all objects in the buffer */ +void pcb_buffer_flip_side(pcb_board_t *pcb, pcb_buffer_t *Buffer); + +/* Load a footprint by name into a buffer; fmt is optional (may be NULL). */ +rnd_bool pcb_buffer_load_footprint(pcb_buffer_t *Buffer, const char *Name, const char *fmt); + +/* sets currently active buffer */ +void pcb_buffer_set_number(int Number); + +/* Address of the currently active paste buffer */ +#define PCB_PASTEBUFFER (&pcb_buffers[conf_core.editor.buffer_number]) + +#endif Index: tags/2.3.0/src/build_run.c =================================================================== --- tags/2.3.0/src/build_run.c (nonexistent) +++ tags/2.3.0/src/build_run.c (revision 33253) @@ -0,0 +1,257 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (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 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include +#include +#include "conf_core.h" +#include "board.h" +#include "build_run.h" +#include +#include "plug_io.h" +#include + +extern void pcb_main_uninit(void); + +void pcb_quit_app(void) +{ + /* save data if necessary. It not needed, then don't trigger EmergencySave + * via our atexit() registering of pcb_emergency_save(). We presumably wanted to + * exit here and thus it is not an emergency. */ + if (PCB->Changed && conf_core.editor.save_in_tmp) + pcb_emergency_save(); + else + pcb_disable_emergency_save(); + + if (rnd_gui->do_exit == NULL) { + pcb_main_uninit(); + exit(0); + } + else + rnd_gui->do_exit(rnd_gui); +} + +char *pcb_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 pcb-rnd " PCB_VERSION " (" PCB_REVISION ")" "\n an interactive "); + gds_append_str(&info, "printed circuit board editor\n"); + } + return info.array; +} + +char *pcb_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, "Recent pcb-rnd copyright:\n"); + gds_append_str(&info, "Copyright (C) Tibor Palinkas 2013..2020 (pcb-rnd)\n"); + gds_append_str(&info, "For a more complete list of pcb-rnd authors and\ncontributors, see http://repo.hu/cgi-bin/pcb-rnd-people.cgi\n\n"); + + gds_append_str(&info, "Historical copyright:\n"); + gds_append_str(&info, "pcb-rnd was originally forked from gEDA/PCB:\n"); + gds_append_str(&info, "Copyright (C) Thomas Nau 1994..1997\n"); + gds_append_str(&info, "Copyright (C) harry eaton 1998..2007\n"); + gds_append_str(&info, "Copyright (C) C. Scott Ananian 2001\n"); + gds_append_str(&info, "Copyright (C) DJ Delorie 2003..2008\n"); + gds_append_str(&info, "Copyright (C) Dan McMahill 2003..2008\n\n"); + } + return info.array; +} + +char *pcb_get_info_websites(const char **url_out) +{ + static gds_t info; + static int first_time = 1; + static const char *URL = "http://pcb-rnd.repo.hu\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 *pcb_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 = pcb_get_info_program(); + gds_append_str(&info, tmp); + tmp = pcb_get_info_websites(NULL); + gds_append_str(&info, tmp); + } + return info.array; +} + + +char *pcb_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, "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 *pcb_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, "pcb-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; +} + +const char *pcb_author(void) +{ + if (conf_core.design.fab_author && conf_core.design.fab_author[0]) + return conf_core.design.fab_author; + else + return rnd_get_user_name(); +} + +/* Catches signals which abort the program. */ +void pcb_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/2.3.0/src/build_run.h =================================================================== --- tags/2.3.0/src/build_run.h (nonexistent) +++ tags/2.3.0/src/build_run.h (revision 33253) @@ -0,0 +1,58 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_BUILD_RUN_H +#define PCB_BUILD_RUN_H + +void pcb_quit_app(void); + +/* Returns a string that has a bunch of information about this program. */ +char *pcb_get_info_program(void); + +/* Returns a string that has a bunch of information about the copyrights. */ +char *pcb_get_info_copyright(void); + +/* Returns a string about how the program is licensed. */ +char *pcb_get_info_license(void); + +/* Returns a string that has a bunch of information about the websites. */ +char *pcb_get_info_websites(const char **url_out); + +/* Returns a string as the concatenation of pcb_get_info_program() and pcb_get_info_websites() */ +char *pcb_get_info_comments(void); + +/* Returns a string that has a bunch of information about the options selected at compile time. */ +char *pcb_get_info_compile_options(void); + +/* Author's name: either from the config system (typically from the design) or + as a last resort from the OS */ +const char *pcb_author(void); + +void pcb_catch_signal(int Signal); + +#endif Index: tags/2.3.0/src/buildin.h =================================================================== --- tags/2.3.0/src/buildin.h (nonexistent) +++ tags/2.3.0/src/buildin.h (revision 33253) @@ -0,0 +1,4 @@ +/* This file is generated by the puplug utility. Please DO NOT edit this file. */ + +#include +extern const pup_buildin_t pup_buildins[]; Index: tags/2.3.0/src/change.c =================================================================== --- tags/2.3.0/src/change.c (nonexistent) +++ tags/2.3.0/src/change.c (revision 33253) @@ -0,0 +1,1029 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2005 Thomas Nau + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include "conf_core.h" + +#include "change.h" +#include +#include "board.h" +#include "data.h" +#include "draw.h" +#include "select.h" +#include "undo.h" +#include "thermal.h" +#include +#include "obj_pstk_op.h" +#include "obj_subc_parent.h" +#include "obj_term.h" +#include "obj_arc_op.h" +#include "obj_line_op.h" +#include "obj_poly_op.h" +#include "obj_text_op.h" +#include "obj_subc_op.h" +#include "obj_gfx_op.h" +#include "extobj.h" + +static const char core_chg_cookie[] = "core: change.c"; + +int defer_updates = 0; +int defer_needs_update = 0; + +pcb_opfunc_t ChangeSizeFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_change_size, + pcb_textop_change_size, + pcb_polyop_change_clear, + NULL, + NULL, + pcb_arcop_change_size, + NULL, /* gfx */ + NULL, + NULL, + pcb_subcop_change_size, + pcb_pstkop_change_size, + 0 /* extobj_inhibit_regen */ +}; + +pcb_opfunc_t Change1stSizeFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_change_size, + pcb_textop_change_size, + pcb_polyop_change_clear, + NULL, + NULL, + pcb_arcop_change_size, + NULL, /* gfx */ + NULL, + NULL, + pcb_subcop_change_1st_size, + NULL, /* padstack */ + 0 /* extobj_inhibit_regen */ +}; + +pcb_opfunc_t Change2ndSizeFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + NULL, + pcb_textop_change_2nd_size, + NULL, + NULL, + NULL, + NULL, + NULL, /* gfx */ + NULL, + NULL, + pcb_subcop_change_2nd_size, + pcb_pstkop_change_2nd_size, + 0 /* extobj_inhibit_regen */ +}; + +pcb_opfunc_t ChangeRotFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + NULL, + pcb_textop_change_rot, + NULL, + NULL, + NULL, + NULL, + NULL, /* gfx */ + NULL, + NULL, + NULL, + pcb_pstkop_rotate, + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t ChangeThermalFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_change_thermal, + NULL, + pcb_polyop_change_thermal, + NULL, + NULL, + NULL, /* arc */ + NULL, /* gfx */ + NULL, + NULL, + NULL, /* subc */ + pcb_pstkop_change_thermal, + 0 /* extobj_inhibit_regen */ +}; + +pcb_opfunc_t ChangeClearSizeFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_change_clear_size, + NULL, + pcb_polyop_change_clear_size, + NULL, + NULL, + pcb_arcop_change_clear_size, + NULL, /* gfx */ + NULL, + NULL, + pcb_subcop_change_clear_size, + pcb_pstkop_change_clear_size, + 0 /* extobj_inhibit_regen */ +}; + +pcb_opfunc_t ChangeEnforceClearSizeFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + NULL, + NULL, + pcb_polyop_change_enforce_clear_size, + NULL, + NULL, + NULL, + NULL, /* gfx */ + NULL, + NULL, + NULL, + NULL, + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t ChangeNameFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + NULL, + pcb_textop_change_name, + NULL, + NULL, + NULL, + NULL, + NULL, /* gfx */ + NULL, + NULL, + pcb_subcop_change_name, + NULL, /* padstack */ + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t ChangeNonetlistFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* gfx */ + NULL, + NULL, + pcb_subcop_change_nonetlist, + NULL, /* padstack */ + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t ChangeJoinFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_change_join, + pcb_textop_change_join, + pcb_polyop_change_join, + NULL, + NULL, + pcb_arcop_change_join, + NULL, /* gfx */ + NULL, + NULL, + NULL, /* subc */ + NULL, /* padstack */ + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t SetJoinFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_set_join, + pcb_textop_set_join, + NULL, + NULL, + NULL, + pcb_arcop_set_join, + NULL, /* gfx */ + NULL, + NULL, + NULL, /* subc */ + NULL, /* padstack */ + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t ClrJoinFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_clear_join, + pcb_textop_clear_join, + NULL, + NULL, + NULL, + pcb_arcop_clear_join, + NULL, /* gfx */ + NULL, + NULL, + NULL, /* subc */ + NULL, /* padstack */ + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t ChangeRadiusFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + NULL, + NULL, + NULL, + NULL, + NULL, + pcb_arcop_change_radius, + NULL, /* gfx */ + NULL, + NULL, + NULL, /* subc */ + NULL, /* padstack */ + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t ChangeAngleFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + NULL, + NULL, + NULL, + NULL, + NULL, + pcb_arcop_change_angle, + NULL, /* gfx */ + NULL, + NULL, + NULL, /* subc */ + NULL, /* padstack */ + 0 /* extobj_inhibit_regen */ +}; + +pcb_opfunc_t ChgFlagFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_change_flag, + pcb_textop_change_flag, + pcb_polyop_change_flag, + NULL, + NULL, + pcb_arcop_change_flag, + pcb_gfxop_change_flag, + NULL, + NULL, + pcb_subcop_change_flag, + pcb_pstkop_change_flag, + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t InvalLabelFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_invalidate_label, + pcb_textop_invalidate_label, + pcb_polyop_invalidate_label, + NULL, + NULL, + pcb_arcop_invalidate_label, + pcb_gfxop_invalidate_label, + NULL, + NULL, + /*pcb_subcop_invalidate_flag*/ NULL, + NULL, /* padstack */ + 0 /* extobj_inhibit_regen */ +}; + + +/* ---------------------------------------------------------------------- + * changes the thermals on all selected and visible padstacks. + * Returns rnd_true if anything has changed + */ +rnd_bool pcb_chg_selected_thermals(int types, int therm_style, unsigned long lid) +{ + rnd_bool change = rnd_false; + pcb_opctx_t ctx; + + ctx.chgtherm.pcb = PCB; + ctx.chgtherm.style = therm_style; + ctx.chgtherm.lid = lid; + + change = pcb_selected_operation(PCB, PCB->Data, &ChangeThermalFunctions, &ctx, rnd_false, types, 0); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* ---------------------------------------------------------------------- + * changes the size of all selected and visible object types + * returns rnd_true if anything has changed + */ +rnd_bool pcb_chg_selected_size(int types, rnd_coord_t Difference, rnd_bool fixIt) +{ + rnd_bool change = rnd_false; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = pcb_selected_operation(PCB, PCB->Data, &ChangeSizeFunctions, &ctx, rnd_false, types, 0); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* ---------------------------------------------------------------------- + * changes the clearance size of all selected and visible objects + * returns rnd_true if anything has changed + */ +rnd_bool pcb_chg_selected_clear_size(int types, rnd_coord_t Difference, rnd_bool fixIt) +{ + rnd_bool change = rnd_false; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = pcb_selected_operation(PCB, PCB->Data, &ChangeClearSizeFunctions, &ctx, rnd_false, types, 0); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* -------------------------------------------------------------------------- + * changes the 2nd size (drilling hole) of all selected and visible objects + * returns rnd_true if anything has changed + */ +rnd_bool pcb_chg_selected_2nd_size(int types, rnd_coord_t Difference, rnd_bool fixIt) +{ + rnd_bool change = rnd_false; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = pcb_selected_operation(PCB, PCB->Data, &Change2ndSizeFunctions, &ctx, rnd_false, types, 0); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* -------------------------------------------------------------------------- + * changes the internal/self rotation all selected and visible objects + * returns rnd_true if anything has changed + */ +rnd_bool pcb_chg_selected_rot(int types, double Difference, rnd_bool fixIt) +{ + rnd_bool change = rnd_false; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = pcb_selected_operation(PCB, PCB->Data, &ChangeRotFunctions, &ctx, rnd_false, types, 0); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* ---------------------------------------------------------------------- + * changes the clearance flag (join) of all selected and visible lines + * and/or arcs. Returns rnd_true if anything has changed + */ +rnd_bool pcb_chg_selected_join(int types) +{ + rnd_bool change = rnd_false; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + + change = pcb_selected_operation(PCB, PCB->Data, &ChangeJoinFunctions, &ctx, rnd_false, types, 0); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* ---------------------------------------------------------------------- + * changes the clearance flag (join) of all selected and visible lines + * and/or arcs. Returns rnd_true if anything has changed + */ +rnd_bool pcb_set_selected_join(int types) +{ + rnd_bool change = rnd_false; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + + change = pcb_selected_operation(PCB, PCB->Data, &SetJoinFunctions, &ctx, rnd_false, types, 0); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* ---------------------------------------------------------------------- + * changes the clearance flag (join) of all selected and visible lines + * and/or arcs. Returns rnd_true if anything has changed + */ +rnd_bool pcb_clr_selected_join(int types) +{ + rnd_bool change = rnd_false; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + + change = pcb_selected_operation(PCB, PCB->Data, &ClrJoinFunctions, &ctx, rnd_false, types, 0); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* ---------------------------------------------------------------------- + * changes the nonetlist-flag of all selected and visible subcircuits + * returns rnd_true if anything has changed + */ +rnd_bool pcb_chg_selected_nonetlist(int types) +{ + rnd_bool change = rnd_false; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + + change = pcb_selected_operation(PCB, PCB->Data, &ChangeNonetlistFunctions, &ctx, rnd_false, types, 0); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* ---------------------------------------------------------------------- + * changes the angle of all selected and visible object types + * returns rnd_true if anything has changed + */ +rnd_bool pcb_chg_selected_angle(int types, int is_start, rnd_angle_t Difference, rnd_bool fixIt) +{ + rnd_bool change = rnd_false; + pcb_opctx_t ctx; + + ctx.chgangle.pcb = PCB; + ctx.chgangle.is_primary = is_start; + ctx.chgangle.is_absolute = fixIt; + ctx.chgangle.value = Difference; + + change = pcb_selected_operation(PCB, PCB->Data, &ChangeAngleFunctions, &ctx, rnd_false, types, 0); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* ---------------------------------------------------------------------- + * changes the radius of all selected and visible object types + * returns rnd_true if anything has changed + */ +rnd_bool pcb_chg_selected_radius(int types, int is_start, rnd_angle_t Difference, rnd_bool fixIt) +{ + rnd_bool change = rnd_false; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = is_start; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = pcb_selected_operation(PCB, PCB->Data, &ChangeRadiusFunctions, &ctx, rnd_false, types, 0); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* --------------------------------------------------------------------------- + * Changes the size of the passed object; + * subc size is line, arc and padstack sizes. + * Returns rnd_true if anything is changed + */ +rnd_bool pcb_chg_obj_size(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t Difference, rnd_bool fixIt) +{ + rnd_bool change; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = (pcb_object_operation(&ChangeSizeFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* --------------------------------------------------------------------------- + * changes the size of the passed object; subcircuits pass this on to their parts + * Returns rnd_true if anything is changed + */ +rnd_bool pcb_chg_obj_1st_size(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t Difference, rnd_bool fixIt) +{ + rnd_bool change; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = (pcb_object_operation(&Change1stSizeFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* --------------------------------------------------------------------------- + * changes the radius of the passed object (e.g. arc width/height) + * Returns rnd_true if anything is changed + */ +rnd_bool pcb_chg_obj_radius(int Type, void *Ptr1, void *Ptr2, void *Ptr3, int is_x, rnd_coord_t r, rnd_bool fixIt) +{ + rnd_bool change; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = is_x; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = r; + + change = (pcb_object_operation(&ChangeRadiusFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* --------------------------------------------------------------------------- + * changes the angles of the passed object (e.g. arc start/ctx->chgsize.value) + * Returns rnd_true if anything is changed + */ +rnd_bool pcb_chg_obj_angle(int Type, void *Ptr1, void *Ptr2, void *Ptr3, int is_start, rnd_angle_t a, rnd_bool fixIt) +{ + rnd_bool change; + pcb_opctx_t ctx; + + ctx.chgangle.pcb = PCB; + ctx.chgangle.is_primary = is_start; + ctx.chgangle.is_absolute = fixIt; + ctx.chgangle.value = a; + + change = (pcb_object_operation(&ChangeAngleFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + + +/* --------------------------------------------------------------------------- + * changes the clearance size of the passed object + * Returns rnd_true if anything is changed + */ +rnd_bool pcb_chg_obj_clear_size(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t Difference, rnd_bool fixIt) +{ + rnd_bool change; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = (pcb_object_operation(&ChangeClearSizeFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +rnd_bool pcb_chg_obj_enforce_clear_size(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t Difference, rnd_bool fixIt) +{ + rnd_bool change; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = (pcb_object_operation(&ChangeEnforceClearSizeFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + + +/* --------------------------------------------------------------------------- + * changes the thermal of the passed object + * Returns rnd_true if anything is changed + * + */ +rnd_bool pcb_chg_obj_thermal(int Type, void *Ptr1, void *Ptr2, void *Ptr3, int therm_type, unsigned long lid) +{ + rnd_bool change; + pcb_opctx_t ctx; + + ctx.chgtherm.pcb = PCB; + ctx.chgtherm.style = therm_type; + ctx.chgtherm.lid = lid; + + change = (pcb_object_operation(&ChangeThermalFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL); + if (change) { + pcb_draw(); + pcb_undo_inc_serial(); + } + return change; +} + +/* --------------------------------------------------------------------------- + * changes the 2nd size of the passed object + * Returns rnd_true if anything is changed + */ +rnd_bool pcb_chg_obj_2nd_size(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t Difference, rnd_bool fixIt, rnd_bool incundo) +{ + rnd_bool change; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = (pcb_object_operation(&Change2ndSizeFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL); + if (change) { + pcb_draw(); + if (incundo) + pcb_undo_inc_serial(); + } + return change; +} + +/* --------------------------------------------------------------------------- + * changes the internal/self rotation of the passed object + * Returns rnd_true if anything is changed + */ +rnd_bool pcb_chg_obj_rot(int Type, void *Ptr1, void *Ptr2, void *Ptr3, double Difference, rnd_bool fixIt, rnd_bool incundo) +{ + rnd_bool change; + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + ctx.chgsize.is_primary = 1; + ctx.chgsize.is_absolute = fixIt; + ctx.chgsize.value = Difference; + + change = (pcb_object_operation(&ChangeRotFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL); + if (change) { + pcb_draw(); + if (incundo) + pcb_undo_inc_serial(); + } + return change; +} + +/* --------------------------------------------------------------------------- + * changes the name of the passed object + * returns the old name + * + * The allocated memory isn't freed because the old string is used + * by the undo module. + */ +void *pcb_chg_obj_name(int Type, void *Ptr1, void *Ptr2, void *Ptr3, char *Name) +{ + void *result; + pcb_opctx_t ctx; + + ctx.chgname.pcb = PCB; + ctx.chgname.new_name = Name; + + result = pcb_object_operation(&ChangeNameFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); + pcb_draw(); + return result; +} + +/* --------------------------------------------------------------------------- + * changes the clearance-flag of the passed object + * Returns rnd_true if anything is changed + */ +rnd_bool pcb_chg_obj_join(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + + if (pcb_object_operation(&ChangeJoinFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL) { + pcb_draw(); + pcb_undo_inc_serial(); + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * sets the clearance-flag of the passed object + * Returns rnd_true if anything is changed + */ +rnd_bool pcb_set_obj_join(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + + if (pcb_object_operation(&SetJoinFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL) { + pcb_draw(); + pcb_undo_inc_serial(); + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * clears the clearance-flag of the passed object + * Returns rnd_true if anything is changed + */ +rnd_bool pcb_clr_obj_join(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + + if (pcb_object_operation(&ClrJoinFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL) { + pcb_draw(); + pcb_undo_inc_serial(); + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * changes the square-flag of the passed object + * Returns rnd_true if anything is changed + */ +rnd_bool pcb_chg_obj_nonetlist(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + pcb_opctx_t ctx; + + ctx.chgsize.pcb = PCB; + + if (pcb_object_operation(&ChangeNonetlistFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3) != NULL) { + pcb_draw(); + pcb_undo_inc_serial(); + return rnd_true; + } + return rnd_false; +} + +void *pcb_chg_obj_name_query(pcb_any_obj_t *obj) +{ + char *name = NULL; + pcb_subc_t *parent_subc; + + parent_subc = pcb_obj_parent_subc(obj); + + switch(obj->type) { + case PCB_OBJ_TEXT: + if ((parent_subc != NULL) && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, obj) && !PCB_FLAG_TEST(PCB_FLAG_DYNTEXT, obj)) + goto term_name; /* special case: dyntext floaters are rarely temrinals */ + if ((parent_subc != NULL) && PCB_FLAG_TEST(PCB_FLAG_DYNTEXT, obj) && (strstr(((pcb_text_t *)obj)->TextString, "%a.parent.refdes%"))) { + if (rnd_hid_message_box(&PCB->hidlib, "question", "Text edit: refdes or template?", "Text object seems to be a refdes text", "edit the text (template)", 0, "edit subcircuit refdes", 1, NULL) == 1) { + obj = (pcb_any_obj_t *)parent_subc; + goto subc_name; + } + } + name = rnd_hid_prompt_for(&PCB->hidlib, "Enter text:", RND_EMPTY(((pcb_text_t *)obj)->TextString), "Change text"); + break; + + case PCB_OBJ_SUBC: + subc_name:; + name = rnd_hid_prompt_for(&PCB->hidlib, "Subcircuit refdes:", RND_EMPTY(((pcb_subc_t *)obj)->refdes), "Change refdes"); + break; + + default: + term_name:; + { + name = rnd_hid_prompt_for(&PCB->hidlib, "Enter terminal ID:", RND_EMPTY(obj->term), "Change terminal ID"); + if (name != NULL) { + pcb_term_undoable_rename(PCB, obj, name); + pcb_draw(); + } + free(name); + return obj; + } + break; + } + + if (name) { + /* ChangeObjectName takes ownership of the passed memory; do not free old name, it's kept for undo */ + char *old; + old = (char *)pcb_chg_obj_name(obj->type, obj->parent.any, obj, obj, name); + + if (old != (char *)-1) { + pcb_undo_add_obj_to_change_name(obj->type, obj->parent.any, obj, obj, old); + pcb_undo_inc_serial(); + } + pcb_draw(); + return obj; + } + return NULL; +} + +void pcb_flag_change(pcb_board_t *pcb, pcb_change_flag_t how, pcb_flag_values_t flag, int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + pcb_opctx_t ctx; + + ctx.chgflag.pcb = pcb; + ctx.chgflag.how = how; + ctx.chgflag.flag = flag; + + pcb_object_operation(&ChgFlagFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); +} + +void *pcb_obj_invalidate_label(pcb_objtype_t Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + pcb_opctx_t ctx; + ctx.noarg.pcb = PCB; + return pcb_object_operation(&InvalLabelFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); +} + + +/*** undoable attribute change */ +typedef struct { + pcb_any_obj_t *obj; + char *value; + int delete; + char key[1]; /* must be the last item, spans longer than 1 */ +} chg_attr_t; + +static int undo_chg_attr_swap(void *udata) +{ + chg_attr_t *ca = udata; + int curr_delete = 0; + char *curr_value = NULL, **slot; + const char *new_val; + + slot = pcb_attribute_get_ptr(&ca->obj->Attributes, ca->key); + + /* temp save current state */ + if (slot == NULL) + curr_delete = 1; + else + curr_value = *slot; + + /* install ca in the slot */ + if (!ca->delete) { + if (curr_delete) { + pcb_attribute_put(&ca->obj->Attributes, ca->key, NULL); + slot = pcb_attribute_get_ptr(&ca->obj->Attributes, ca->key); + } + *slot = ca->value; + new_val = ca->value; + if (ca->obj->Attributes.post_change != NULL) + ca->obj->Attributes.post_change(&ca->obj->Attributes, ca->key, ca->value); + } + else { + *slot = NULL; + new_val = NULL; + pcb_attribute_remove(&ca->obj->Attributes, ca->key); + } + + + /* save current state in ca */ + ca->delete = curr_delete; + ca->value = curr_value; + + + /* side effects */ + pcb_extobj_chg_attr(ca->obj, ca->key, new_val); + return 0; +} + +static void undo_chg_attr_print(void *udata, char *dst, size_t dst_len) +{ + chg_attr_t *ca = udata; + rnd_snprintf(dst, dst_len, "chg_attr: #%ld/%s to '%s'\n", + ca->obj->ID, ca->key, ca->delete ? "" : ca->value); +} + +static void undo_chg_attr_free(void *udata) +{ + chg_attr_t *ca = udata; + free(ca->value); +} + +static const uundo_oper_t undo_chg_attr = { + core_chg_cookie, + undo_chg_attr_free, + undo_chg_attr_swap, + undo_chg_attr_swap, + undo_chg_attr_print +}; + +int pcb_uchg_attr(pcb_board_t *pcb, pcb_any_obj_t *obj, const char *key, const char *new_value) +{ + int len; + chg_attr_t *ca; + const char *curr; + + if (key == NULL) + return -1; + + curr = pcb_attribute_get(&obj->Attributes, key); + if ((curr == NULL) && (new_value == NULL)) + return 0; /* nothing to do: both delete */ + if ((curr != NULL) && (new_value != NULL) && (strcmp(curr, new_value) == 0)) + return 0; /* nothing to do: value match */ + + len = strlen(key); /* +1 for the terminator is implied by sizeof(->str) */ + + ca = pcb_undo_alloc(pcb, &undo_chg_attr, sizeof(chg_attr_t) + len); + ca->obj = obj; + memcpy(ca->key, key, len+1); + if (new_value == NULL) { + ca->value = NULL; + ca->delete = 1; + } + else { + ca->value = rnd_strdup(new_value); + ca->delete = 0; + } + undo_chg_attr_swap(ca); + + pcb_undo_inc_serial(); + return 0; +} Index: tags/2.3.0/src/change.h =================================================================== --- tags/2.3.0/src/change.h (nonexistent) +++ tags/2.3.0/src/change.h (revision 33253) @@ -0,0 +1,116 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Generic, object-type independent change calls */ + +#ifndef PCB_CHANGE_H +#define PCB_CHANGE_H + +#include "config.h" +#include "board.h" +#include "flag.h" +#include +#include + +extern int defer_updates, defer_needs_update; + +#define PCB_CHANGENAME_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_TEXT | PCB_OBJ_SUBC | PCB_OBJ_LINE | \ + PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_SUBC_PART | PCB_OBJ_SUBC) + +#define PCB_CHANGESIZE_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_POLY | PCB_OBJ_LINE | PCB_OBJ_ARC | \ + PCB_OBJ_TEXT | PCB_OBJ_SUBC | PCB_OBJ_SUBC_PART) + +#define PCB_CHANGE2NDSIZE_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_SUBC | PCB_OBJ_SUBC_PART) + +#define PCB_CHANGEROT_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_TEXT | PCB_OBJ_GFX) + +/* We include polygons here only to inform the user not to do it that way. */ +#define PCB_CHANGECLEARSIZE_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_SUBC | \ + PCB_OBJ_SUBC_PART) + +#define PCB_CHANGENONETLIST_TYPES \ + (PCB_OBJ_SUBC) + +#define PCB_CHANGESQUARE_TYPES \ + (PCB_OBJ_SUBC | PCB_OBJ_SUBC_PART) + +#define PCB_CHANGEOCTAGON_TYPES \ + (PCB_OBJ_SUBC | PCB_OBJ_SUBC_PART) + +#define PCB_CHANGEJOIN_TYPES \ + (PCB_OBJ_ARC | PCB_OBJ_LINE | PCB_OBJ_TEXT | PCB_OBJ_POLY) + +#define PCB_CHANGETHERMAL_TYPES \ + (PCB_OBJ_SUBC_PART) + +rnd_bool pcb_chg_selected_size(int, rnd_coord_t, rnd_bool); +rnd_bool pcb_chg_selected_clear_size(int, rnd_coord_t, rnd_bool); +rnd_bool pcb_chg_selected_2nd_size(int, rnd_coord_t, rnd_bool); +rnd_bool pcb_chg_selected_rot(int, double, rnd_bool); +rnd_bool pcb_chg_selected_join(int); +rnd_bool pcb_set_selected_join(int); +rnd_bool pcb_clr_selected_join(int); +rnd_bool pcb_chg_selected_nonetlist(int); +rnd_bool pcb_chg_selected_thermals(int types, int therm_style, unsigned long lid); +rnd_bool pcb_chg_obj_size(int, void *, void *, void *, rnd_coord_t, rnd_bool); +rnd_bool pcb_chg_obj_1st_size(int, void *, void *, void *, rnd_coord_t, rnd_bool); +rnd_bool pcb_chg_obj_thermal(int Type, void *Ptr1, void *Ptr2, void *Ptr3, int therm_type, unsigned long lid); +rnd_bool pcb_chg_obj_clear_size(int, void *, void *, void *, rnd_coord_t, rnd_bool); +rnd_bool pcb_chg_obj_enforce_clear_size(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t Difference, rnd_bool fixIt); +rnd_bool pcb_chg_obj_2nd_size(int, void *, void *, void *, rnd_coord_t, rnd_bool, rnd_bool); +rnd_bool pcb_chg_obj_rot(int, void *, void *, void *, double, rnd_bool, rnd_bool); +rnd_bool pcb_chg_obj_join(int, void *, void *, void *); +rnd_bool pcb_set_obj_join(int, void *, void *, void *); +rnd_bool pcb_clr_obj_join(int, void *, void *, void *); +rnd_bool pcb_chg_obj_nonetlist(int Type, void *Ptr1, void *Ptr2, void *Ptr3); +void *pcb_chg_obj_name(int, void *, void *, void *, char *); + +/* queries the user for a new object name and changes it */ +void *pcb_chg_obj_name_query(pcb_any_obj_t *obj); + +rnd_bool pcb_chg_obj_radius(int Type, void *Ptr1, void *Ptr2, void *Ptr3, int is_x, rnd_coord_t r, rnd_bool absolute); +rnd_bool pcb_chg_obj_angle(int Type, void *Ptr1, void *Ptr2, void *Ptr3, int is_start, rnd_angle_t a, rnd_bool absolute); +rnd_bool pcb_chg_selected_angle(int types, int is_start, rnd_angle_t Difference, rnd_bool fixIt); +rnd_bool pcb_chg_selected_radius(int types, int is_start, rnd_angle_t Difference, rnd_bool fixIt); + +/* Change flag flg of an object in a way dictated by 'how' */ +void pcb_flag_change(pcb_board_t *pcb, pcb_change_flag_t how, pcb_flag_values_t flg, int Type, void *Ptr1, void *Ptr2, void *Ptr3); + +/* Invalidate the term label of an object */ +void *pcb_obj_invalidate_label(pcb_objtype_t Type, void *Ptr1, void *Ptr2, void *Ptr3); + +/* Undoable obj attribute change; if new_value is NULL, delete the attribute */ +int pcb_uchg_attr(pcb_board_t *pcb, pcb_any_obj_t *obj, const char *key, const char *new_value); + + +#endif Index: tags/2.3.0/src/change_act.c =================================================================== --- tags/2.3.0/src/change_act.c (nonexistent) +++ tags/2.3.0/src/change_act.c (revision 33253) @@ -0,0 +1,990 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2018,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" +#include "conf_core.h" + +#include "data.h" +#include "funchash_core.h" + +#include "board.h" +#include +#include "change.h" +#include "draw.h" +#include "search.h" +#include "undo.h" +#include "event.h" +#include "thermal.h" +#include +#include "obj_rat_draw.h" +#include "data_it.h" +#include +#include "route_style.h" +#include +#include "obj_subc_parent.h" + +#define PCB (do not use PCB directly) + +static void ChangeFlag(pcb_board_t *, const char *, const char *, int, const char *); +static fgw_error_t pcb_act_ChangeSize(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv); +static fgw_error_t pcb_act_Change2ndSize(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv); + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_ChangeClearSize[] = + "ChangeClearSize(Object, delta|style)\n" + "ChangeClearSize(SelectedPins|SelectedPads|SelectedVias, delta|style)\n" + "ChangeClearSize(SelectedLines|SelectedArcs, delta|style)\n" + "ChangeClearSize(Selected|SelectedObjects, delta|style)"; +static const char pcb_acth_ChangeClearSize[] = "Changes the clearance size of objects."; +/* DOC: changeclearsize.html */ +static fgw_error_t pcb_act_ChangeClearSize(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *function; + const char *delta = NULL; + const char *units = NULL; + rnd_bool absolute; + rnd_coord_t value; + int type = PCB_OBJ_VOID; + void *ptr1, *ptr2, *ptr3; + rnd_coord_t x, y; + int got_coords = 0; + + RND_ACT_CONVARG(1, FGW_STR, ChangeClearSize, function = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, ChangeClearSize, delta = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, ChangeClearSize, units = argv[3].val.str); + + if (function && delta) { + int funcid = rnd_funchash_get(function, NULL); + + if (funcid == F_Object) { + rnd_hid_get_coords("Select an Object", &x, &y, 0); + got_coords = 1; + type = pcb_search_screen(x, y, PCB_CHANGECLEARSIZE_TYPES, &ptr1, &ptr2, &ptr3); + } + + if (strcmp(delta, "style") == 0) { + if (!got_coords) { + rnd_hid_get_coords("Select an Object", &x, &y, 0); + got_coords = 1; + } + + if ((type == PCB_OBJ_VOID) || (type == PCB_OBJ_POLY)) /* workaround: pcb_search_screen(PCB_CHANGECLEARSIZE_TYPES) wouldn't return elements */ + type = pcb_search_screen(x, y, PCB_CHANGE2NDSIZE_TYPES, &ptr1, &ptr2, &ptr3); + if (pcb_get_style_size(funcid, &value, type, 2) != 0) { + RND_ACT_IRES(-1); + return 0; + } + absolute = 1; + value *= 2; + } + else + value = 2 * rnd_get_value(delta, units, &absolute, NULL); + switch (rnd_funchash_get(function, NULL)) { + case F_Object: + { + if (type != PCB_OBJ_VOID) + if (pcb_chg_obj_clear_size(type, ptr1, ptr2, ptr3, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + case F_SelectedVias: + case F_SelectedPads: + case F_SelectedPins: + if (pcb_chg_selected_clear_size(PCB_OBJ_PSTK, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + case F_SelectedLines: + if (pcb_chg_selected_clear_size(PCB_OBJ_LINE, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + case F_SelectedArcs: + if (pcb_chg_selected_clear_size(PCB_OBJ_ARC, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + case F_Selected: + case F_SelectedObjects: + if (pcb_chg_selected_clear_size(PCB_CHANGECLEARSIZE_TYPES, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + } + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_ChangeFlag[] = + "ChangeFlag(Object|Selected|SelectedObjects, flag, value)\n" + "ChangeFlag(SelectedLines|SelectedPins|SelectedVias, flag, value)\n" + "ChangeFlag(SelectedPads|SelectedTexts|SelectedNames, flag, value)\n" + "ChangeFlag(SelectedElements, flag, value)\n" "flag = join\n" "value = 0 | 1"; +static const char pcb_acth_ChangeFlag[] = "Sets or clears flags on objects."; +/* DOC: changeflag.html */ +static fgw_error_t pcb_act_ChangeFlag(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *function; + const char *flag; + int value; + + RND_ACT_CONVARG(1, FGW_STR, ChangeFlag, function = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, ChangeFlag, flag = argv[2].val.str); + RND_ACT_CONVARG(2, FGW_INT, ChangeFlag, value = argv[3].val.nat_int); + + if (value != 0 && value != 1) + RND_ACT_FAIL(ChangeFlag); + + ChangeFlag(PCB_ACT_BOARD, function, flag, value, "ChangeFlag"); + RND_ACT_IRES(0); + return 0; +} + + +static void ChangeFlag(pcb_board_t *pcb, const char *what, const char *flag_name, int value, + const char *cmd_name) +{ + rnd_bool(*set_object) (int, void *, void *, void *); + rnd_bool(*set_selected) (int); + + if (RND_NSTRCMP(flag_name, "join") == 0) { + /* Note: these are backwards, because the flag is "clear" but + the command is "join". */ + set_object = value ? pcb_clr_obj_join : pcb_set_obj_join; + set_selected = value ? pcb_clr_selected_join : pcb_set_selected_join; + } + else { + rnd_message(RND_MSG_ERROR, "%s(): Flag \"%s\" is not valid\n", cmd_name, flag_name); + return; + } + + switch (rnd_funchash_get(what, NULL)) { + case F_Object: + { + int type; + void *ptr1, *ptr2, *ptr3; + rnd_coord_t x, y; + + rnd_hid_get_coords("Click on object to change", &x, &y, 0); + + if ((type = pcb_search_screen(x, y, PCB_CHANGESIZE_TYPES, &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) { + pcb_any_obj_t *obj = (pcb_any_obj_t *)ptr2; + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, obj)) + rnd_message(RND_MSG_WARNING, "Sorry, %s object is locked\n", pcb_obj_type_name(obj->type)); + } + if (set_object(type, ptr1, ptr2, ptr3)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + + case F_SelectedVias: + case F_SelectedPins: + case F_SelectedPads: + if (set_selected(PCB_OBJ_PSTK)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_SelectedLines: + if (set_selected(PCB_OBJ_LINE)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_SelectedTexts: + if (set_selected(PCB_OBJ_TEXT)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_SelectedNames: + case F_SelectedElements: + rnd_message(RND_MSG_ERROR, "Feature not supported\n"); + break; + + case F_Selected: + case F_SelectedObjects: + if (set_selected(PCB_CHANGESIZE_TYPES)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_ChangeSizes[] = + "ChangeSizes(Object, delta|style)\n" + "ChangeSizes(SelectedObjects|Selected, delta|style)\n" + "ChangeSizes(SelectedLines|SelectedPins|SelectedVias, delta|style)\n" + "ChangeSizes(SelectedPads|SelectedTexts|SelectedNames, delta|style)\n" "ChangeSizes(SelectedElements, delta|style)"; +static const char pcb_acth_ChangeSizes[] = "Changes all sizes of objects."; +/* DOC: changesizes.html */ +static fgw_error_t pcb_act_ChangeSizes(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + fgw_error_t a, b, c; + pcb_undo_save_serial(); + a = pcb_act_ChangeSize(res, argc, argv); + pcb_undo_restore_serial(); + b = pcb_act_Change2ndSize(res, argc, argv); + pcb_undo_restore_serial(); + c = pcb_act_ChangeClearSize(res, argc, argv); + pcb_undo_restore_serial(); + pcb_undo_inc_serial(); + RND_ACT_IRES(!(!a || !b || !c)); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_ChangeSize[] = + "ChangeSize(Object, delta|style)\n" + "ChangeSize(SelectedObjects|Selected, delta|style)\n" + "ChangeSize(SelectedLines|SelectedPins|SelectedVias, delta|style)\n" + "ChangeSize(SelectedPads|SelectedTexts|SelectedNames, delta|style)\n" "ChangeSize(SelectedElements, delta|style)"; +static const char pcb_acth_ChangeSize[] = "Changes the size of objects."; +/* DOC: changesize.html */ +static fgw_error_t pcb_act_ChangeSize(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *function; + const char *delta; + const char *units = NULL; + rnd_bool absolute; /* indicates if absolute size is given */ + rnd_coord_t value; + int type = PCB_OBJ_VOID, tostyle = 0; + void *ptr1, *ptr2, *ptr3; + + RND_ACT_CONVARG(1, FGW_STR, ChangeSize, function = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, ChangeSize, delta = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, ChangeSize, units = argv[3].val.str); + + + if (function && delta) { + int funcid = rnd_funchash_get(function, NULL); + + if (funcid == F_Object) { + rnd_coord_t x, y; + rnd_hid_get_coords("Click on object to change size of", &x, &y, 0); + type = pcb_search_screen(x, y, PCB_CHANGESIZE_TYPES, &ptr1, &ptr2, &ptr3); + } + + if (strcmp(delta, "style") == 0) { + if (pcb_get_style_size(funcid, &value, type, 0) != 0) + return 1; + absolute = 1; + tostyle = 1; + } + else + value = rnd_get_value(delta, units, &absolute, NULL); + switch (funcid) { + case F_Object: + { + if (type != PCB_OBJ_VOID) { + pcb_any_obj_t *obj = (pcb_any_obj_t *)ptr2; + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, obj)) + rnd_message(RND_MSG_WARNING, "Sorry, %s object is locked\n", pcb_obj_type_name(obj->type)); + } + if (tostyle) { + if (pcb_chg_obj_1st_size(type, ptr1, ptr2, ptr3, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + } + else { + if (pcb_chg_obj_size(type, ptr1, ptr2, ptr3, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + } + break; + } + case F_SelectedVias: + case F_SelectedPins: + case F_SelectedPads: + if (pcb_chg_selected_size(PCB_OBJ_PSTK, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_SelectedArcs: + if (pcb_chg_selected_size(PCB_OBJ_ARC, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_SelectedLines: + if (pcb_chg_selected_size(PCB_OBJ_LINE, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_SelectedTexts: + if (pcb_chg_selected_size(PCB_OBJ_TEXT, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_SelectedNames: + case F_SelectedElements: + rnd_message(RND_MSG_ERROR, "Feature not supported.\n"); + break; + + case F_Selected: + case F_SelectedObjects: + if (pcb_chg_selected_size(PCB_CHANGESIZE_TYPES, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + } + + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_Change2ndSize[] = + "ChangeDrillSize(Object, delta|style)\n" "ChangeDrillSize(SelectedPins|SelectedVias|Selected|SelectedObjects, delta|style)"; + +static const char pcb_acth_Change2ndSize[] = "Changes the drilling hole size of objects."; + +static fgw_error_t pcb_act_Change2ndSize(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *function; + const char *delta; + const char *units = NULL; + int type = PCB_OBJ_VOID; + void *ptr1, *ptr2, *ptr3; + rnd_bool absolute; + rnd_coord_t value; + + RND_ACT_CONVARG(1, FGW_STR, Change2ndSize, function = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, Change2ndSize, delta = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, Change2ndSize, units = argv[3].val.str); + + if (function && delta) { + int funcid = rnd_funchash_get(function, NULL); + + if (funcid == F_Object) { + rnd_coord_t x, y; + rnd_hid_get_coords("Select an Object", &x, &y, 0); + type = pcb_search_screen(x, y, PCB_CHANGE2NDSIZE_TYPES, &ptr1, &ptr2, &ptr3); + } + + if (strcmp(delta, "style") == 0) { + if (pcb_get_style_size(funcid, &value, type, 1) != 0) + return 1; + absolute = 1; + } + else + value = rnd_get_value(delta, units, &absolute, NULL); + + switch (rnd_funchash_get(function, NULL)) { + case F_Object: + { + + if (type != PCB_OBJ_VOID) + if (pcb_chg_obj_2nd_size(type, ptr1, ptr2, ptr3, value, absolute, rnd_true)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + + case F_SelectedPadstacks: + case F_SelectedVias: + case F_SelectedPins: + if (pcb_chg_selected_2nd_size(PCB_OBJ_PSTK, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_Selected: + case F_SelectedObjects: + if (pcb_chg_selected_2nd_size(PCB_OBJ_CLASS_PIN, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + } + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_ChangePinName[] = "ChangePinName(Refdes,PinNumber,PinName)"; +static const char pcb_acth_ChangePinName[] = "Sets the name of a specific pin on a specific subcircuit."; +/* DOC: changepinname.html */ +static fgw_error_t pcb_act_ChangePinName(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + rnd_cardinal_t changed = 0; + const char *refdes, *pinnum, *pinname; + + RND_ACT_CONVARG(1, FGW_STR, ChangePinName, refdes = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, ChangePinName, pinnum = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, ChangePinName, pinname = argv[3].val.str); + + PCB_SUBC_LOOP(PCB_ACT_BOARD->Data); + { + if ((subc->refdes != NULL) && (RND_NSTRCMP(refdes, subc->refdes) == 0)) { + pcb_any_obj_t *o; + pcb_data_it_t it; + + for(o = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + if ((o->term != NULL) && (RND_NSTRCMP(pinnum, o->term) == 0)) { + pcb_attribute_set(PCB_ACT_BOARD, &o->Attributes, "name", pinname, 1); + pcb_board_set_changed_flag(pcb, rnd_true); + changed++; + } + } + } + } + PCB_END_LOOP; + + /* + * done with our action so increment the undo # if we actually + * changed anything + */ + if (changed) { + if (defer_updates) + defer_needs_update = 1; + else { + /* pcb_undo_inc_serial(); */ + rnd_gui->invalidate_all(rnd_gui); + } + } + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_ChangeName[] = "ChangeName(Object)\n" "ChangeName(Refdes)\n" "ChangeName(Layout|Layer)"; +static const char pcb_acth_ChangeName[] = "Sets the name, text string, terminal ID or refdes of objects."; +/* DOC: changename.html */ +static fgw_error_t pcb_act_ChangeName(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int op; + char *name; + pcb_objtype_t type; + + RND_ACT_CONVARG(1, FGW_KEYWORD, ChangeName, op = fgw_keyword(&argv[1])); + + switch(op) { + /* change the refdes of a subcircuit */ + case F_Subc: + { + rnd_coord_t x, y; + rnd_hid_get_coords("Select a subcircuit", &x, &y, 0); + type = op = PCB_OBJ_SUBC; + goto do_chg_name; + } + /* change the name of an object */ + case F_Object: + case F_Refdes: + { + rnd_coord_t x, y; + void *ptr1, *ptr2, *ptr3; + rnd_hid_get_coords("Select an Object", &x, &y, 0); + type = op == F_Refdes ? PCB_OBJ_SUBC : PCB_CHANGENAME_TYPES; + do_chg_name:; + type = pcb_search_screen(x, y, type, &ptr1, &ptr2, &ptr3); + if (type != PCB_OBJ_VOID) { + pcb_undo_save_serial(); + if (pcb_chg_obj_name_query(ptr2)) { + rnd_hid_redraw(PCB); + pcb_board_set_changed_flag(pcb, rnd_true); + rnd_actionva(RND_ACT_HIDLIB, "DeleteRats", "AllRats", NULL); + } + if (op == F_Object) { + pcb_subc_t *subc = pcb_obj_parent_subc(ptr2); + if ((subc != NULL) && subc->auto_termname_display) { + pcb_undo_add_obj_to_flag(ptr2); + PCB_FLAG_SET(PCB_FLAG_TERMNAME, (pcb_any_obj_t *)ptr2); + pcb_board_set_changed_flag(pcb, rnd_true); + pcb_undo_inc_serial(); + pcb_draw(); + } + } + } + break; + } + + /* change the layout's name */ + case F_Layout: + name = rnd_hid_prompt_for(RND_ACT_HIDLIB, "Enter the layout name:", RND_EMPTY(RND_ACT_HIDLIB->name), "Layout name"); + /* NB: ChangeLayoutName takes ownership of the passed memory */ + if (name && pcb_board_change_name(name)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + /* change the name of the active layer */ + case F_Layer: + name = rnd_hid_prompt_for(RND_ACT_HIDLIB, "Enter the layer name:", RND_EMPTY(PCB_CURRLAYER(PCB_ACT_BOARD)->name), "Layer name"); + /* NB: pcb_layer_rename_ takes ownership of the passed memory */ + if (name && (pcb_layer_rename_(PCB_CURRLAYER(PCB_ACT_BOARD), name, 1) == 0)) + pcb_board_set_changed_flag(pcb, rnd_true); + else + free(name); + break; + + default: + return FGW_ERR_ARG_CONV; + } + + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_ChangeJoin[] = "ChangeJoin(ToggleObject|SelectedLines|SelectedArcs|Selected)"; + +static const char pcb_acth_ChangeJoin[] = "Changes the join (clearance through polygons) of objects."; + +/* DOC: changejoin.html */ + +static fgw_error_t pcb_act_ChangeJoin(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int op; + + RND_ACT_CONVARG(1, FGW_KEYWORD, ChangeJoin, op = fgw_keyword(&argv[1])); + + switch(op) { + case F_ToggleObject: + case F_Object: + { + rnd_coord_t x, y; + int type; + void *ptr1, *ptr2, *ptr3; + + rnd_hid_get_coords("Select an Object", &x, &y, 0); + if ((type = pcb_search_screen(x, y, PCB_CHANGEJOIN_TYPES, &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) + if (pcb_chg_obj_join(type, ptr1, ptr2, ptr3)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + + case F_SelectedLines: + if (pcb_chg_selected_join(PCB_OBJ_LINE)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_SelectedArcs: + if (pcb_chg_selected_join(PCB_OBJ_ARC)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_Selected: + case F_SelectedObjects: + if (pcb_chg_selected_join(PCB_CHANGEJOIN_TYPES)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + default: + return FGW_ERR_ARG_CONV; + } + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_ChangeNonetlist[] = + "ChangeNonetlist(ToggleObject)\n" "ChangeNonetlist(SelectedElements)\n" "ChangeNonetlist(Selected|SelectedObjects)"; +static const char pcb_acth_ChangeNonetlist[] = "Changes the nonetlist flag of subcircuits."; +static fgw_error_t pcb_act_ChangeNonetlist(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int op; + + RND_ACT_CONVARG(1, FGW_KEYWORD, ChangeJoin, op = fgw_keyword(&argv[1])); + + switch(op) { + case F_ToggleObject: + case F_Object: + case F_Element: + { + rnd_coord_t x, y; + int type; + void *ptr1, *ptr2, *ptr3; + rnd_hid_get_coords("Select an Element", &x, &y, 0); + + ptr3 = NULL; + type = pcb_search_screen(x, y, PCB_CHANGENONETLIST_TYPES, &ptr1, &ptr2, &ptr3); + if (pcb_chg_obj_nonetlist(type, ptr1, ptr2, ptr3)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + case F_SelectedElements: + case F_Selected: + case F_SelectedObjects: + if (pcb_chg_selected_nonetlist(PCB_OBJ_SUBC)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + default: + return FGW_ERR_ARG_CONV; + } + + RND_ACT_IRES(0); + return 0; +} + + +static const char pcb_acts_SetThermal[] = "SetThermal(Object|SelectedPins|SelectedVias|Selected, Style)"; +static const char pcb_acth_SetThermal[] = + "Set the thermal (on the current layer) of padstacks to the given style. Style is one of:\n" + "0: means no thermal.\n" + "1: horizontal/vertical, round.\n" + "2: horizontal/vertical, sharp.\n" + "3: is a solid connection to the polygon.\n" + "4: (invalid).\n" + "5: diagonal, round.\n" + "6: diagonal, sharp.\n" + "noshape: no copper shape on layer\n"; +/* DOC: setthermal.html */ +static fgw_error_t pcb_act_SetThermal(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *function; + const char *style; + void *ptr1, *ptr2, *ptr3; + int type, kind = 0; + int err = 0; + rnd_coord_t gx, gy; + + RND_ACT_CONVARG(1, FGW_STR, SetThermal, function = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, SetThermal, style = argv[2].val.str); + + if (function && *function && style && *style) { + rnd_bool absolute; + + if (rnd_strcasecmp(style, "noshape") == 0) + kind = PCB_THERMAL_NOSHAPE | PCB_THERMAL_ON; + else + kind = rnd_get_value_ex(style, NULL, &absolute, NULL, NULL, NULL); + if ((absolute && (kind <= 6)) || (kind & PCB_THERMAL_ON)) { + if (kind != 0) + kind |= PCB_THERMAL_ON; + switch (rnd_funchash_get(function, NULL)) { + case F_Object: + rnd_hid_get_coords("Click on object for SetThermal", &gx, &gy, 0); + if ((type = pcb_search_screen(gx, gy, PCB_CHANGETHERMAL_TYPES, &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) { + pcb_chg_obj_thermal(type, ptr1, ptr2, ptr3, kind, PCB_CURRLID(PCB_ACT_BOARD)); + pcb_undo_inc_serial(); + pcb_draw(); + } + break; + case F_SelectedPins: + case F_SelectedVias: + pcb_chg_selected_thermals(PCB_OBJ_PSTK, kind, PCB_CURRLID(PCB_ACT_BOARD)); + break; + case F_Selected: + case F_SelectedElements: + pcb_chg_selected_thermals(PCB_CHANGETHERMAL_TYPES, kind, PCB_CURRLID(PCB_ACT_BOARD)); + break; + default: + err = 1; + break; + } + } + else + err = 1; + if (!err) { + RND_ACT_IRES(0); + return 0; + } + } + + RND_ACT_FAIL(SetThermal); +} + + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_SetFlag[] = + "SetFlag(Object|Selected|SelectedObjects, flag)\n" + "SetFlag(SelectedLines|SelectedPins|SelectedVias, flag)\n" + "SetFlag(SelectedPads|SelectedTexts|SelectedNames, flag)\n" + "SetFlag(SelectedElements, flag)\n" "flag = thermal | join"; +static const char pcb_acth_SetFlag[] = "Sets flags on objects."; +/* DOC: setflag.html */ +static fgw_error_t pcb_act_SetFlag(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *function; + const char *flag; + + RND_ACT_CONVARG(1, FGW_STR, SetFlag, function = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, SetFlag, flag = argv[2].val.str); + + ChangeFlag(PCB_ACT_BOARD, function, flag, 1, "SetFlag"); + + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_ClrFlag[] = + "ClrFlag(Object|Selected|SelectedObjects, flag)\n" + "ClrFlag(SelectedLines|SelectedPins|SelectedVias, flag)\n" + "ClrFlag(SelectedPads|SelectedTexts|SelectedNames, flag)\n" + "ClrFlag(SelectedElements, flag)\n" "flag = thermal | join"; +static const char pcb_acth_ClrFlag[] = "Clears flags on objects."; +/* DOC: clrflag.html */ +static fgw_error_t pcb_act_ClrFlag(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *function; + const char *flag; + + RND_ACT_CONVARG(1, FGW_STR, SetFlag, function = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, SetFlag, flag = argv[2].val.str); + + ChangeFlag(PCB_ACT_BOARD, function, flag, 0, "ClrFlag"); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_SetValue[] = "SetValue(Grid|Line|LineSize|Text|TextScale, delta)"; +static const char pcb_acth_SetValue[] = "Change various board-wide values and sizes."; +/* DOC: setvalue.html */ +static fgw_error_t pcb_act_SetValue(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int fnc_id; + const char *val, *units = NULL; + rnd_bool absolute; /* flag for 'absolute' value */ + double value; + int err = 0; + + RND_ACT_CONVARG(1, FGW_KEYWORD, SetValue, fnc_id = fgw_keyword(&argv[1])); + + if (fnc_id == F_Grid) + return rnd_actionv_bin(RND_ACT_HIDLIB, "setgrid", res, argc-1, argv+1); + + RND_ACT_CONVARG(2, FGW_STR, SetValue, val = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, SetValue, units = argv[3].val.str); + + value = rnd_get_value(val, units, &absolute, NULL); + + switch(fnc_id) { + case F_LineSize: + case F_Line: + pcb_board_set_line_width(absolute ? value : value + conf_core.design.line_thickness); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_ROUTE_STYLES_CHANGED, NULL); + break; + + case F_Text: + case F_TextScale: + value = rnd_round(value / (double)PCB_FONT_CAPHEIGHT * 100.0); + pcb_board_set_text_scale(absolute ? value : (value + conf_core.design.text_scale)); + break; + default: + err = 1; + break; + } + if (!err) { + RND_ACT_IRES(0); + return 0; + } + + RND_ACT_FAIL(SetValue); +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_ChangeAngle[] = + "ChangeAngle(Object, start|delta|both, delta)\n" + "ChangeAngle(SelectedObjects|Selected, start|delta|both, delta)\n" + "ChangeAngle(SelectedArcs, start|delta|both, delta)\n"; +static const char pcb_acth_ChangeAngle[] = "Changes the start angle, delta angle or both angles of an arc."; +static fgw_error_t pcb_act_ChangeAngle(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *prim; + const char *delta; + rnd_bool absolute; /* indicates if absolute size is given */ + double value; + int funcid, type = PCB_OBJ_VOID, which; + void *ptr1, *ptr2, *ptr3; + + RND_ACT_CONVARG(1, FGW_KEYWORD, ChangeAngle, funcid = fgw_keyword(&argv[1])); + RND_ACT_CONVARG(2, FGW_STR, ChangeAngle, prim = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, ChangeAngle, delta = argv[3].val.str); + + + if (rnd_strcasecmp(prim, "start") == 0) which = 0; + else if (rnd_strcasecmp(prim, "delta") == 0) which = 1; + else if (rnd_strcasecmp(prim, "both") == 0) which = 2; + else { + rnd_message(RND_MSG_ERROR, "Second argument of ChangeAngle must be start, delta or both\n"); + return -1; + } + + if (funcid == F_Object) { + rnd_coord_t x, y; + rnd_hid_get_coords("Click on object to change angle of", &x, &y, 0); + type = pcb_search_screen(x, y, PCB_CHANGESIZE_TYPES, &ptr1, &ptr2, &ptr3); + } + + { /* convert angle from string */ + char *end; + while(isspace(*delta)) delta++; + value = strtod(delta, &end); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Invalid numeric (in angle)\n"); + return -1; + } + absolute = ((*delta != '-') && (*delta != '+')); + } + + switch(funcid) { + case F_Object: + { + if (type != PCB_OBJ_VOID) { + pcb_any_obj_t *obj = (pcb_any_obj_t *)ptr2; + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, obj)) + rnd_message(RND_MSG_WARNING, "Sorry, %s object is locked\n", pcb_obj_type_name(obj->type)); + else { + if (pcb_chg_obj_angle(type, ptr1, ptr2, ptr3, which, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + } + } + break; + } + + case F_SelectedArcs: + if (pcb_chg_selected_angle(PCB_OBJ_ARC, which, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_Selected: + case F_SelectedObjects: + if (pcb_chg_selected_angle(PCB_CHANGESIZE_TYPES, which, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_ChangeRadius[] = + "ChangeRadius(Object, width|x|height|y|both, delta)\n" + "ChangeRadius(SelectedObjects|Selected, width|x|height|y|both, delta)\n" + "ChangeRadius(SelectedArcs, width|x|height|y|both, delta)\n"; +static const char pcb_acth_ChangeRadius[] = "Changes the width or height (radius) of an arc."; +static fgw_error_t pcb_act_ChangeRadius(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *prim; + const char *delta; + const char *units; + rnd_bool absolute; /* indicates if absolute size is given */ + double value; + int funcid, type = PCB_OBJ_VOID, which; + void *ptr1, *ptr2, *ptr3; + + RND_ACT_CONVARG(1, FGW_KEYWORD, ChangeRadius, funcid = fgw_keyword(&argv[1])); + RND_ACT_CONVARG(2, FGW_STR, ChangeRadius, prim = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, ChangeRadius, delta = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, ChangeRadius, units = argv[4].val.str); + + if ((rnd_strcasecmp(prim, "width") == 0) || (rnd_strcasecmp(prim, "x") == 0)) which = 0; + else if ((rnd_strcasecmp(prim, "height") == 0) || (rnd_strcasecmp(prim, "y") == 0)) which = 1; + else if (rnd_strcasecmp(prim, "both") == 0) which = 2; + else { + rnd_message(RND_MSG_ERROR, "Second argument of ChangeRadius must be width, x, height, y or both\n"); + return -1; + } + + if (funcid == F_Object) { + rnd_coord_t x, y; + rnd_hid_get_coords("Click on object to change radius of", &x, &y, 0); + type = pcb_search_screen(x, y, PCB_CHANGESIZE_TYPES, &ptr1, &ptr2, &ptr3); + } + + value = rnd_get_value(delta, units, &absolute, NULL); + + switch(funcid) { + case F_Object: + { + if (type != PCB_OBJ_VOID) { + pcb_any_obj_t *obj = (pcb_any_obj_t *)ptr2; + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, obj)) + rnd_message(RND_MSG_WARNING, "Sorry, %s object is locked\n", pcb_obj_type_name(obj->type)); + else { + if (pcb_chg_obj_radius(type, ptr1, ptr2, ptr3, which, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + } + } + break; + } + + case F_SelectedArcs: + if (pcb_chg_selected_radius(PCB_OBJ_ARC, which, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + + case F_Selected: + case F_SelectedObjects: + if (pcb_chg_selected_radius(PCB_CHANGESIZE_TYPES, which, value, absolute)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + + RND_ACT_IRES(0); + return 0; +} + + +/* --------------------------------------------------------------------------- */ + +static rnd_action_t change_action_list[] = { + {"ChangeAngle", pcb_act_ChangeAngle, pcb_acth_ChangeAngle, pcb_acts_ChangeAngle}, + {"ChangeClearSize", pcb_act_ChangeClearSize, pcb_acth_ChangeClearSize, pcb_acts_ChangeClearSize}, + {"ChangeDrillSize", pcb_act_Change2ndSize, pcb_acth_Change2ndSize, pcb_acts_Change2ndSize}, + {"ChangeJoin", pcb_act_ChangeJoin, pcb_acth_ChangeJoin, pcb_acts_ChangeJoin}, + {"ChangeName", pcb_act_ChangeName, pcb_acth_ChangeName, pcb_acts_ChangeName}, + {"ChangePinName", pcb_act_ChangePinName, pcb_acth_ChangePinName, pcb_acts_ChangePinName}, + {"ChangeRadius", pcb_act_ChangeRadius, pcb_acth_ChangeRadius, pcb_acts_ChangeRadius}, + {"ChangeSize", pcb_act_ChangeSize, pcb_acth_ChangeSize, pcb_acts_ChangeSize}, + {"ChangeSizes", pcb_act_ChangeSizes, pcb_acth_ChangeSizes, pcb_acts_ChangeSizes}, + {"ChangeNonetlist", pcb_act_ChangeNonetlist, pcb_acth_ChangeNonetlist, pcb_acts_ChangeNonetlist}, + {"ChangeFlag", pcb_act_ChangeFlag, pcb_acth_ChangeFlag, pcb_acts_ChangeFlag}, + {"SetThermal", pcb_act_SetThermal, pcb_acth_SetThermal, pcb_acts_SetThermal}, + {"SetValue", pcb_act_SetValue, pcb_acth_SetValue, pcb_acts_SetValue}, + {"SetFlag", pcb_act_SetFlag, pcb_acth_SetFlag, pcb_acts_SetFlag}, + {"ClrFlag", pcb_act_ClrFlag, pcb_acth_ClrFlag, pcb_acts_ClrFlag} +}; + +void pcb_change_act_init2(void) +{ + RND_REGISTER_ACTIONS(change_action_list, NULL); +} + + + + Index: tags/2.3.0/src/conf_act.c =================================================================== --- tags/2.3.0/src/conf_act.c (nonexistent) +++ tags/2.3.0/src/conf_act.c (revision 33253) @@ -0,0 +1,100 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "board.h" +#include +#include "conf_core.h" +#include +#include "funchash_core.h" +#include "route_style.h" +#include +#include + +#define PCB do_not_use_PCB + +/*------------ get/chk (check flag actions for menus) ------------------*/ +static const char pcb_acts_GetStyle[] = "GetStyle()" ; +static const char pcb_acth_GetStyle[] = "Return integer index (>=0) of the currently active style or -1 if no style is selected (== custom style)"; +fgw_error_t pcb_act_GetStyle(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + RND_ACT_IRES(pcb_route_style_lookup(&pcb->RouteStyle, conf_core.design.line_thickness, conf_core.design.via_thickness, conf_core.design.via_drilling_hole, conf_core.design.clearance, NULL)); + return 0; +} + +static const char pcb_acts_ChkSubcID[] = "ChkSubcID(pattern)\n"; +static const char pcb_acth_ChkSubcID[] = "Return 1 if currently shown subc ID matches the requested pattern"; +static fgw_error_t pcb_act_ChkSubcID(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *have = conf_core.editor.subc_id, *expected = ""; + + if (have == NULL) have = ""; + + RND_ACT_MAY_CONVARG(1, FGW_STR, ChkSubcID, expected = argv[1].val.str); + + RND_ACT_IRES(strcmp(expected, have) == 0); + return 0; +} + +static const char pcb_acts_ChkTermID[] = "ChkTermID(pattern)\n"; +static const char pcb_acth_ChkTermID[] = "Return 1 if currently shown term ID matches the requested pattern"; +static fgw_error_t pcb_act_ChkTermID(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *have = conf_core.editor.term_id, *expected = ""; + + if (have == NULL) have = ""; + + RND_ACT_MAY_CONVARG(1, FGW_STR, ChkTermID, expected = argv[1].val.str); + + RND_ACT_IRES(strcmp(expected, have) == 0); + return 0; +} + +static const char pcb_acts_ChkBuffer[] = "ChkBuffer(idx)"; +static const char pcb_acth_ChkBuffer[] = "Return 1 if currently selected buffer's index matches idx"; +static fgw_error_t pcb_act_ChkBuffer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int expected; + RND_ACT_CONVARG(1, FGW_INT, ChkBuffer, expected = argv[1].val.nat_int); + RND_ACT_IRES((conf_core.editor.buffer_number + 1) == expected); + return 0; +} + +static rnd_action_t conf_action_list[] = { + {"GetStyle", pcb_act_GetStyle, pcb_acth_GetStyle, pcb_acts_GetStyle}, + {"ChkSubcID", pcb_act_ChkSubcID, pcb_acth_ChkSubcID, pcb_acts_ChkSubcID}, + {"ChkTermID", pcb_act_ChkTermID, pcb_acth_ChkTermID, pcb_acts_ChkTermID}, + {"ChkBuffer", pcb_act_ChkBuffer, pcb_acth_ChkBuffer, pcb_acts_ChkBuffer} +}; + +void pcb_conf_act_init2(void) +{ + RND_REGISTER_ACTIONS(conf_action_list, NULL); +} + + + Index: tags/2.3.0/src/conf_core.c =================================================================== --- tags/2.3.0/src/conf_core.c (nonexistent) +++ tags/2.3.0/src/conf_core.c (revision 33253) @@ -0,0 +1,133 @@ +#include "config.h" +#include +#include "conf_core.h" +#include +#include +#include +#include +#include + +TODO("win32: remove this once the w32_ dir workaround is removed") +#include + +conf_core_t conf_core; + +static const char conf_core_cookie[] = "conf_core"; +static htpp_t legacy_new2old, legacy_old2new; + +#define conf_clamp_to(type, var, min, max, safe_val) \ +do { \ + if ((var < min) || (var > max)) \ + *((type *)(&var)) = safe_val; \ +} while(0) + +#define conf_clamp(type, var, min, max) \ +do { \ + if (var < min) \ + *((type *)(&var)) = min; \ + else if (var > max) \ + *((type *)(&var)) = max; \ +} while(0) + +static void pcb_conf_legacy_(rnd_conf_native_t *ndst, rnd_conf_native_t *nlegacy) +{ + gds_t tmp; + const char *dst_path = ndst->hash_path; + + gds_init(&tmp); + rnd_conf_print_native_field((rnd_conf_pfn)rnd_append_printf, &tmp, 0, &nlegacy->val, nlegacy->type, nlegacy->prop, 0); + if (tmp.used > 0) + rnd_conf_set(RND_CFR_INTERNAL, dst_path, -1, tmp.array, RND_POL_OVERWRITE); + gds_uninit(&tmp); +} + +void pcb_conf_legacy(const char *dst_path, const char *legacy_path) +{ + rnd_conf_native_t *nlegacy = rnd_conf_get_field(legacy_path); + rnd_conf_native_t *ndst = rnd_conf_get_field(dst_path); + if (nlegacy == NULL) { + rnd_message(RND_MSG_ERROR, "pcb_conf_legacy: invalid legacy path '%s' for %s\n", legacy_path, dst_path); + return; + } + if (ndst == NULL) { + rnd_message(RND_MSG_ERROR, "pcb_conf_legacy: invalid new path %s\n", dst_path); + return; + } + pcb_conf_legacy_(ndst, nlegacy); + htpp_set(&legacy_new2old, ndst, nlegacy); + htpp_set(&legacy_old2new, nlegacy, ndst); +} + + +static void conf_core_postproc(void) +{ + htpp_entry_t *e; + + conf_clamp_to(RND_CFT_COORD, conf_core.design.line_thickness, PCB_MIN_THICKNESS, PCB_MAX_THICKNESS, RND_MIL_TO_COORD(10)); + rnd_conf_force_set_bool(conf_core.rc.have_regex, 1); + rnd_conf_ro("rc/have_regex"); + + rnd_conf_force_set_str(conf_core.rc.path.prefix, PCB_PREFIX); rnd_conf_ro("rc/path/prefix"); + rnd_conf_force_set_str(conf_core.rc.path.lib, PCBLIBDIR); rnd_conf_ro("rc/path/lib"); + rnd_conf_force_set_str(conf_core.rc.path.bin, BINDIR); rnd_conf_ro("rc/path/bin"); + rnd_conf_force_set_str(conf_core.rc.path.share, PCBSHAREDIR); rnd_conf_ro("rc/path/share"); + + for(e = htpp_first(&legacy_new2old); e != NULL; e = htpp_next(&legacy_new2old, e)) { + rnd_conf_native_t *nlegacy = e->value, *ndst = e->key; + if (nlegacy->rnd_conf_rev > ndst->rnd_conf_rev) + pcb_conf_legacy_(ndst, nlegacy); + } +} + +static void conf_legacy_chg(rnd_conf_native_t *ndst, int arr_idx) +{ + /* check if a legacy nde changes so we need to update a new node */ + rnd_conf_native_t *nlegacy; + static int lock = 0; + + if (lock) + return; + + nlegacy = htpp_get(&legacy_old2new, ndst); + if (nlegacy == NULL) + return; + + lock++; + pcb_conf_legacy_(ndst, nlegacy); /* overwrite content on role INTERNAL */ + lock--; +} + +static rnd_conf_hid_callbacks_t cbs; + + +void conf_core_uninit_pre(void) +{ + rnd_conf_hid_unreg(conf_core_cookie); +} + +void conf_core_uninit(void) +{ + htpp_uninit(&legacy_new2old); + htpp_uninit(&legacy_old2new); +} + +void conf_core_init(void) +{ + htpp_init(&legacy_new2old, ptrhash, ptrkeyeq); + htpp_init(&legacy_old2new, ptrhash, ptrkeyeq); + +#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" + rnd_conf_core_postproc = conf_core_postproc; + conf_core_postproc(); + + cbs.val_change_post = conf_legacy_chg; + rnd_conf_hid_reg(conf_core_cookie, &cbs); + + /* these old drc settings from editor/ are copied over to editor/drc + because various core and tool code depend on the values being at the + new place. */ + pcb_conf_legacy("design/drc/min_copper_clearance", "design/bloat"); + pcb_conf_legacy("design/drc/min_copper_overlap", "design/shrink"); +} Index: tags/2.3.0/src/conf_core.h =================================================================== --- tags/2.3.0/src/conf_core.h (nonexistent) +++ tags/2.3.0/src/conf_core.h (revision 33253) @@ -0,0 +1,244 @@ +#ifndef PCB_CONF_CORE_H +#define PCB_CONF_CORE_H + +#include +#include "globalconst.h" +#include + +/* NOTE: this struct has a strict format because a code generator needs to + read it. Please always keep the format (preferably even whitespace style). + Use only the CFT_* prefixed types declared in conf.h. + */ + +typedef struct { + + struct pcb_rnd_core_temp_s { + RND_CFT_BOOLEAN rat_warn; /* rats nest has set warnings */ + RND_CFT_BOOLEAN clip_inhibit_chg; /* dummy node to inform the menu about clip inhibit change */ + } temp; + + const struct { /* editor */ + RND_CFT_REAL zoom; /* default zoom */ + RND_CFT_INTEGER buffer_number; /* number of the current buffer */ + RND_CFT_BOOLEAN clear_line; /* new lines/arc clear polygons. */ + RND_CFT_BOOLEAN clear_polypoly; /* new polygons clear polygons. */ + RND_CFT_BOOLEAN full_poly; /* new polygons are full polygons. */ + RND_CFT_BOOLEAN unique_names; /* OBSOLETE: force unique names */ + RND_CFT_BOOLEAN snap_pin; /* snap to pins and pads */ + RND_CFT_BOOLEAN snap_offgrid_line; /* Snap to certain off-grid points along a line. */ + RND_CFT_BOOLEAN marker_snaps; /* marker snaps to grid or snap points, as any other click */ + RND_CFT_BOOLEAN highlight_on_point; /* Highlight if crosshair is on endpoints. */ + RND_CFT_BOOLEAN show_solder_side; /* mirror output */ + RND_CFT_BOOLEAN save_last_command; /* OBSOLETE: use the session-persistent command line history instead (press the up arrow) */ + RND_CFT_INTEGER line_refraction; /* value for line lookahead setting */ + RND_CFT_BOOLEAN save_in_tmp; /* emergency save unsaved PCB data (despite the user clicks don't save) when: user starts a new PCB; user quits pcb-rnd. Does not affect the on-crash emergency save. */ + RND_CFT_BOOLEAN all_direction_lines; /* enable lines to all directions */ + RND_CFT_BOOLEAN rubber_band_mode; /* move, rotate use rubberband connections */ + RND_CFT_BOOLEAN rubber_band_keep_midlinedir; /* keep line direction when a middle line is moved */ + RND_CFT_BOOLEAN swap_start_direction; /* change starting direction after each click */ + RND_CFT_BOOLEAN show_drc; /* (misnomer) show style clearance on crosshair */ + RND_CFT_BOOLEAN auto_drc; /* (misnomer) block drawing traces that get too close (according to style clearance) to other nets */ + RND_CFT_BOOLEAN conn_find_rat; /* connection find includes rats; when off, only existing galvanic connections are mapped */ + RND_CFT_BOOLEAN show_number; /* OBSOLETE: pinout shows number */ + RND_CFT_BOOLEAN orthogonal_moves; /* move items orthogonally. */ + RND_CFT_BOOLEAN reset_after_element; /* OBSOLETE: reset connections after each element while saving all connections */ + RND_CFT_BOOLEAN lock_names; /* lock down text so they can not be moved or selected */ + RND_CFT_BOOLEAN only_names; /* lock down everything else but text so only text objects can be moved or selected */ + RND_CFT_BOOLEAN thin_draw; /* if set, objects on the screen are drawn as outlines (lines are drawn as center-lines). This lets you see line endpoints hidden under pins, for example. */ + RND_CFT_BOOLEAN thin_draw_poly; /* if set, polygons on the screen are drawn as outlines. */ + RND_CFT_BOOLEAN as_drawn_poly; /* if set, also draw the as-drawn outline of polygons */ + RND_CFT_BOOLEAN wireframe_draw; /* if set, lines and arcs on the screen are drawn as outlines. */ + RND_CFT_BOOLEAN local_ref; /* use local reference for moves, by setting the mark at the beginning of each move. */ + RND_CFT_BOOLEAN check_planes; /* when set, only polygons and their clearances are drawn, to see if polygons have isolated regions. */ + RND_CFT_BOOLEAN hide_names; /* when set, subc floater text objects (typical use case: refdes text) are not drawn. */ + RND_CFT_BOOLEAN description; /* obsolete - DO NOT USE - kept for compatibility */ + RND_CFT_BOOLEAN name_on_pcb; /* obsolete - DO NOT USE - kept for compatibility */ + RND_CFT_BOOLEAN trace_auto_merge; /* automatically merge trace overlapping trace lines while drawing or moving traces */ + RND_CFT_STRING subc_id; /* subcircuit ID template for diplaying the subcircuit label on the subcircuit layer; default to displaying the refes, if empty; syntax if the same as for DYNTEXT */ + RND_CFT_STRING term_id; /* terminal ID template for diplaying the subcircuit label on the subcircuit layer; default to displaying termid[intconn], if empty; syntax if the same as for DYNTEXT */ + RND_CFT_BOOLEAN move_linepoint_uses_route; /* Moving a line point calculates a new line route. This allows 45/90 line modes when editing lines. */ + RND_CFT_BOOLEAN auto_via; /* when drawing traces and switching layers or when moving an object from one layer to another, try to keep connections by automatically inserting vias. */ + RND_CFT_REAL route_radius; /* temporary: route draw helper's arc radius at corners (factor of the trace thickness) */ + RND_CFT_BOOLEAN drc_inclusive_bbox; /* when enabled, the drc view will always include all red and blue objects (turns off optimization that focuses on red objects) */ + + + RND_CFT_BOOLEAN io_incomp_popup; /* wether to enable popping up the io incompatibility list dialog on save incompatibility errors */ + RND_CFT_STRING io_incomp_style; /* view listing style (list or simple), when io_incomp_popup is true */ + + RND_CFT_INTEGER click_time; /* default time for click expiration, in ms */ + RND_CFT_BOOLEAN click_objlist; /* if there are multiple objects available upon a click, present a modal dialog box to select from them */ + + struct { + RND_CFT_BOOLEAN disable_negative; /* selection box behaviour: disable the negative-direction selection - any selection box will select only what's fully within the box */ + RND_CFT_BOOLEAN symmetric_negative; /* selection box behaviour: when set, the selection direction is considered negative only if the box has negative size in the X direction */ + } selection; + + + /* this would need to be moved in the router plugin.... There are two + reasons to keep it here: + - the original pcb and pcb-rnd file formats already have named/numbered flags for it, so io_pcb needs it + - more than one router plugins may share it */ + RND_CFT_BOOLEAN live_routing; /* autorouter shows tracks in progress */ + + /* Keep it here instead of the router plugin: more than one router plugin may share these */ + RND_CFT_BOOLEAN beep_when_finished; /* flag if a signal should be produced when searching of connections is done */ + + RND_CFT_INTEGER undo_warning_size; /* warn the user when undo list exceeds this amount of kilobytes in memory */ + + RND_CFT_STRING subc_conv_refdes; /* automatic refdes value assigned to new subcircuits on conversion from objects - if empty, no refdes text or attribute is added; if the value is , the refdes text object is added but no refdes attribute is created */ + } editor; + + const struct { + struct { + RND_CFT_STRING method; /* method/strategy of placement; one of: disperse, frame, fit */ + RND_CFT_STRING location; /* placement coordinate for methods that require it; if empty, use fixed coordinates at x,y; if non-empty, it may be: mark, center */ + RND_CFT_COORD x; /* for some methods if location is empty, X coordinate of placement */ + RND_CFT_COORD y; /* for some methods if location is empty, Y coordinate of placement */ + RND_CFT_COORD disperse; /* dispersion distance for the disperse method */ + } footprint_placement; + + struct { + RND_CFT_STRING method; /* method/strategy of removal; one of: select, remove, list */ + } footprint_removal; + } import; + + const struct { /* rc */ + RND_CFT_REAL file_changed_interval; /* how often to check if the file has changed on the disk (in seconds); 0 or negative means no check at all */ + RND_CFT_INTEGER backup_interval; /* time between two backups in seconds; 0 means disabled (no backups) */ + RND_CFT_STRING brave; /* brave mode flags: when non-empty, enable various experimental (unstable) features - useful for testers */ + RND_CFT_STRING font_command; /* file name template; if not empty, run this command and read its output for loading the font; %f is the file name */ + RND_CFT_STRING file_command; /* file name template; if not empty, run this command and read its output for loading a pcb file; %f is the file name, %p is the conf setting rc.file_path */ + RND_CFT_STRING file_path; + RND_CFT_STRING library_shell; + RND_CFT_LIST library_search_paths; + + RND_CFT_STRING emergency_name; /* file name template for emergency save anonymous .pcb files (when pcb-rnd crashes); optional field: %ld --> pid; must be shorter than 240 characters. Don't do emergency save if this item is empty. */ + RND_CFT_STRING emergency_format; /* if set, use this format for the backups; if unset, use the default format */ + RND_CFT_STRING backup_name; /* file name template for periodic backup of board files; optional fields (the usual % substitutions work) */ + RND_CFT_STRING backup_format; /* if set, use this format for the backups; if unset or set to 'original', use the original format */ + + RND_CFT_STRING save_command; /* command to pipe the pcb, footprint or buffer file into, when saving (makes lihata persist impossible) */ + RND_CFT_BOOLEAN keep_save_backups; /* a copy is made before a save operation overwrites an existing file; if this setting is true, keep the copy even after a successful save */ + RND_CFT_LIST default_font_file; /* name of default font file (list of names to search) */ + RND_CFT_LIST default_pcb_file; + + RND_CFT_BOOLEAN silently_create_on_load; /* do not generate an error message if the board does not exist on load from command line argument, silently create it in memory */ + + RND_CFT_STRING script_filename; /* PCB Actions script to execute on startup */ + RND_CFT_STRING action_string; /* PCB Actions string to execute on startup */ + RND_CFT_STRING rat_path; + RND_CFT_STRING rat_command; /* file name template; if not empty, run this command and read its output for loading a rats; %f is the file name, %p is the rc.rat_path conf setting */ + + RND_CFT_STRING save_final_fallback_fmt;/* when a new file is created (by running pcb-rnd with the file name) there won't be a known format; pcb-rnd will guess from the file name (extension) but eventhat may fail. This format is the final fallback that'll be used if no other guessing mechanism worked. The user can override this by save as. */ + RND_CFT_STRING save_fp_fmt; /* when saving a buffer element/subcircuit, prefer this format by default */ + + /***** automatically set (in postproc) *****/ + RND_CFT_BOOLEAN have_regex; /* whether we have regex compiled in */ + struct { + RND_CFT_STRING prefix; /* e.g. /usr/local */ + RND_CFT_STRING lib; /* e.g. /usr/lib/pcb-rnd */ + RND_CFT_STRING bin; /* e.g. /usr/bin */ + RND_CFT_STRING share; /* e.g. /usr/share/pcb-rnd */ + + RND_CFT_STRING design; /* directory path of the current design, or if the current design doesn't have a file name yet */ + } path; + } rc; + + const struct { /* design: defaults of a new layout */ + RND_CFT_COORD via_thickness; + RND_CFT_COORD via_drilling_hole; + RND_CFT_COORD line_thickness; + RND_CFT_COORD clearance; + + /* limiting sizes (old DRC) settings */ + RND_CFT_COORD bloat; /* core: size of box-style clearance around text objects; old plugins: gap between copper features on different nets */ + RND_CFT_COORD shrink; /* [OBSOLETE] minimum overlap between connected copper features */ + RND_CFT_COORD min_wid; /* core: minimum copper thickness in stroked text, core+plugins: implicit outline rectangle thickness */ + RND_CFT_COORD min_slk; /* core: minimum silk thickness in stroked text, core+plugins: implicit outline rectangle thickness on silk layers */ + RND_CFT_COORD min_drill; /* [OBSOLETE] minimum drill diameter */ + RND_CFT_COORD min_ring; /* [OBSOLETE] minimum annular ring */ + + struct { /* drc: new, flexible drc settings */ + RND_CFT_COORD min_copper_clearance; /* minimum space between copper features on different networks (default when the net attributes or other settings don't specify a different value) */ + RND_CFT_COORD min_copper_overlap; /* minimum overlap between connected copper features (default when the net attributes or other settings don't specify a different value)*/ + } drc; + + struct { /* disable drc checks on a per rule basis */ + RND_CFT_BOOLEAN dummy; /* placeholder, not used */ + } drc_disable; + + RND_CFT_INTEGER text_scale; /* text scaling in % */ + RND_CFT_COORD text_thickness; /* override stroke font text thickness */ + RND_CFT_INTEGER text_font_id; + RND_CFT_REAL poly_isle_area; /* polygon min area */ + RND_CFT_STRING fab_author; /* Full name of author for FAB drawings */ + RND_CFT_STRING initial_layer_stack; /* deprecated. */ + + struct { + RND_CFT_REAL poly_scale; /* scale thermal bridges around polygons; 1.000 is the original size - DO NOT USE YET */ + } thermal; + + RND_CFT_COORD paste_adjust; /* Adjust paste thickness */ + } design; + +/* @path appearance/color */ + const struct { /* appearance */ + RND_CFT_BOOLEAN compact; /* when set: optimize GUI widget arrangement for small screen; may be wasting some screen space on large screen */ + RND_CFT_COORD rat_thickness; + RND_CFT_COORD mark_size; /* relative marker size */ + RND_CFT_BOOLEAN text_host_bbox; /* when moving a text object, the outline thin-draw should also include the bounding box */ + RND_CFT_REAL term_label_size; /* size of terminal labels, in pcb font scale (100 is for the normal size) */ + RND_CFT_BOOLEAN subc_layer_per_side; /* hide top or bottom placed subcircuit annotations if the view is showing the other side */ + RND_CFT_BOOLEAN invis_other_groups; /* render non-current group layers with the inivisble color */ + RND_CFT_BOOLEAN black_current_group; /* render all layers of the current group black, for maximum contrast */ + RND_CFT_BOOLEAN smart_labels; /* attempt to place terminal labels in a way they don't overlap (costs extra CPU cycles, may slow down on-screen rendering) */ + RND_CFT_COORD label_thickness; /* font thickness for labels (e.g. terminal labels); thinnest possible is 1nm */ + + struct { /* color */ + RND_CFT_COLOR crosshair; /* obsolete - DO NOT USE - kept for compatibility (use appearance/color/cross instead) */ + RND_CFT_COLOR attached; /* color of the non-layer corsshair-attached objects drawn in XOR (e.g. when padstack or buffer outline before placed; layer-objects like lines and arcs typically onherit the layer color) */ + RND_CFT_COLOR drc; /* color of the on-screen drc clearance indication while routing */ + RND_CFT_COLOR mark; /* color of the on-screen marks (user placed mark and automatic 'grabbed' mark) */ + RND_CFT_COLOR selected; /* generic object selection color */ + RND_CFT_COLOR via; /* non-terminal padstack shape on current layer */ + RND_CFT_COLOR via_far; /* non-terminal padstack shape on non-current ('far side') layer */ + RND_CFT_COLOR pin; /* terminal padstack shape on current layer */ + RND_CFT_COLOR pin_far; /* terminal padstack shape on non-current ('far side') layer */ + RND_CFT_COLOR pin_name; /* on-screen terminal number/name labels */ + RND_CFT_COLOR subc; /* on-screen subcircuit marks */ + RND_CFT_COLOR subc_nonetlist; /* on-screen subcircuit marks for subcircuits with the nonetlist flag */ + RND_CFT_COLOR extobj; /* on-screen marks of extended objects */ + RND_CFT_COLOR padstackmark; /* on-screen center mark cross for padstacks */ + RND_CFT_COLOR rat; /* on-screen rat lines */ + RND_CFT_COLOR invisible_objects; /* other-side objects and padstack shapes on non-current layer */ + RND_CFT_COLOR connected; /* 'connected' highlight (galvanic connections found) */ + RND_CFT_COLOR warn; /* warning highlight (e.g. object found to cause a short) */ + RND_CFT_COLOR layer[PCB_MAX_LAYER]; /* default layer colors; when a new layer is created, a color from this list is assigned initially */ + RND_CFT_COLOR mask; /* default mask layer color (when a new mask layer is created) */ + RND_CFT_COLOR paste; /* default paste layer color (when a new paste layer is created) */ + RND_CFT_COLOR element; /* default silk layer color (when a new silk layer is created) */ + } color; + struct { + RND_CFT_INTEGER cross_thick; /* cross thickness in pixels - 0 means disable crosses */ + RND_CFT_COORD cross_size; /* cross size in word coords - size of one arm of the cross (minus the hole radius) */ + } padstack; + struct { + RND_CFT_INTEGER dash_freq; /* how dense the dashed outline should be; -1 means do not display the dashed outline; 0 means solid outline; 1..32 means dashed outline */ + } subc; + struct { + RND_CFT_INTEGER char_per_line; /* width of an output line in characters (used by separator drawing in find.c) */ + } messages; + struct { + RND_CFT_INTEGER volume; /* the speakers volume -100..100 */ + } misc; + } appearance; + +} conf_core_t; + +extern conf_core_t conf_core; +void conf_core_init(void); +void conf_core_uninit(void); +void conf_core_uninit_pre(void); +void pcb_conf_legacy(const char *dst_path, const char *legacy_path); + +#endif Index: tags/2.3.0/src/crosshair.c =================================================================== --- tags/2.3.0/src/crosshair.c (nonexistent) +++ tags/2.3.0/src/crosshair.c (revision 33253) @@ -0,0 +1,1221 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include "conf_core.h" +#include + +#include "board.h" +#include "crosshair.h" +#include "data.h" +#include "draw.h" +#include "draw_wireframe.h" +#include "search.h" +#include "polygon.h" +#include +#include +#include +#include +#include "find.h" +#include "undo.h" +#include "event.h" +#include "thermal.h" +#include + +#include "obj_line_draw.h" +#include "obj_arc_draw.h" +#include "obj_text_draw.h" +#include "obj_pstk_draw.h" +#include "obj_gfx_draw.h" +#include "route_draw.h" +#include "obj_arc_ui.h" +#include "obj_subc_parent.h" + +#include + +typedef struct { + int x, y; +} point; + +static char crosshair_cookie[] = "crosshair"; + +pcb_crosshair_t pcb_crosshair; /* information about cursor settings */ +rnd_mark_t pcb_marked; +pcb_crosshair_note_t pcb_crosshair_note; + + +static void thindraw_moved_ps(pcb_pstk_t *ps, rnd_coord_t x, rnd_coord_t y) +{ + /* Make a copy of the pin structure, moved to the correct position */ + pcb_pstk_t moved_ps = *ps; + moved_ps.x += x; + moved_ps.y += y; + + pcb_pstk_thindraw(NULL, pcb_crosshair.GC, &moved_ps); +} + +/* --------------------------------------------------------------------------- + * creates a tmp polygon with coordinates converted to screen system + */ +void pcb_xordraw_poly(pcb_poly_t *polygon, rnd_coord_t dx, rnd_coord_t dy, int dash_last) +{ + rnd_cardinal_t i; + for (i = 0; i < polygon->PointN; i++) { + rnd_cardinal_t next = pcb_poly_contour_next_point(polygon, i); + + if (next == 0) { /* last line: sometimes the implicit closing line */ + if (i == 1) /* corner case: don't draw two lines on top of each other - with XOR it looks bad */ + continue; + + if (dash_last) { + pcb_draw_dashed_line(NULL, pcb_crosshair.GC, + polygon->Points[i].X + dx, + polygon->Points[i].Y + dy, polygon->Points[next].X + dx, polygon->Points[next].Y + dy, 5, rnd_false); + break; /* skip normal line draw below */ + } + } + + /* normal contour line */ + rnd_render->draw_line(pcb_crosshair.GC, + polygon->Points[i].X + dx, + polygon->Points[i].Y + dy, polygon->Points[next].X + dx, polygon->Points[next].Y + dy); + } +} + +void pcb_xordraw_pline(rnd_pline_t *pline, rnd_coord_t dx, rnd_coord_t dy) +{ + rnd_vnode_t *n = pline->head; + do { + rnd_render->draw_line(pcb_crosshair.GC, + n->point[0] + dx, n->point[1] + dy, + n->next->point[0] + dx, n->next->point[1] + dy); + n = n->next; + } while(n != pline->head); +} + +void pcb_xordraw_polyarea(rnd_polyarea_t *parea, rnd_coord_t dx, rnd_coord_t dy) +{ + rnd_polyarea_t *pa = parea; + rnd_pline_t *pl; + do { + for(pl = pa->contours; pl != NULL; pl = pl->next) + pcb_xordraw_pline(pl, dx, dy); + pa = pa->f; + } while(pa != parea); +} + +/* --------------------------------------------------------------------------- + * creates a tmp polygon with coordinates converted to screen system, designed + * for subc paste xor-draw + */ +void pcb_xordraw_poly_subc(pcb_poly_t *polygon, rnd_coord_t dx, rnd_coord_t dy, rnd_coord_t w, rnd_coord_t h, int mirr) +{ + rnd_cardinal_t i; + for (i = 0; i < polygon->PointN; i++) { + rnd_cardinal_t next = pcb_poly_contour_next_point(polygon, i); + + if (next == 0) { /* last line: sometimes the implicit closing line */ + if (i == 1) /* corner case: don't draw two lines on top of each other - with XOR it looks bad */ + continue; + } + + /* normal contour line */ + rnd_render->draw_line(pcb_crosshair.GC, + PCB_CSWAP_X(polygon->Points[i].X, w, mirr) + dx, + PCB_CSWAP_Y(polygon->Points[i].Y, h, mirr) + dy, + PCB_CSWAP_X(polygon->Points[next].X, w, mirr) + dx, + PCB_CSWAP_Y(polygon->Points[next].Y, h, mirr) + dy); + } +} + +void pcb_xordraw_attached_arc(rnd_coord_t thick) +{ + pcb_arc_t arc; + rnd_coord_t wx, wy; + rnd_angle_t sa, dir; + + wx = pcb_crosshair.X - pcb_crosshair.AttachedBox.Point1.X; + wy = pcb_crosshair.Y - pcb_crosshair.AttachedBox.Point1.Y; + if (wx == 0 && wy == 0) + return; + arc.X = pcb_crosshair.AttachedBox.Point1.X; + arc.Y = pcb_crosshair.AttachedBox.Point1.Y; + if (RND_XOR(pcb_crosshair.AttachedBox.otherway, coord_abs(wy) > coord_abs(wx))) { + arc.X = pcb_crosshair.AttachedBox.Point1.X + coord_abs(wy) * RND_SGNZ(wx); + sa = (wx >= 0) ? 0 : 180; + dir = (RND_SGNZ(wx) == RND_SGNZ(wy)) ? 90 : -90; + } + else { + arc.Y = pcb_crosshair.AttachedBox.Point1.Y + coord_abs(wx) * RND_SGNZ(wy); + sa = (wy >= 0) ? -90 : 90; + dir = (RND_SGNZ(wx) == RND_SGNZ(wy)) ? -90 : 90; + wy = wx; + } + wy = coord_abs(wy); + arc.StartAngle = sa; + arc.Delta = dir; + arc.Width = arc.Height = wy; + arc.Thickness = thick; + + pcb_draw_wireframe_arc(pcb_crosshair.GC, &arc, thick); +} + +/* --------------------------------------------------------------------------- + * draws all visible and attached objects of the pastebuffer + */ +void pcb_xordraw_buffer(pcb_buffer_t *Buffer) +{ + rnd_cardinal_t i; + rnd_coord_t x, y; + + /* set offset */ + x = pcb_crosshair.AttachedObject.tx - Buffer->X; + y = pcb_crosshair.AttachedObject.ty - Buffer->Y; + + /* draw all visible layers */ + for (i = 0; i < pcb_max_layer(PCB); i++) + if (PCB->Data->Layer[i].meta.real.vis) { + pcb_layer_t *layer = &Buffer->Data->Layer[i]; + + PCB_LINE_LOOP(layer); + { + pcb_draw_wireframe_line( pcb_crosshair.GC, + x + line->Point1.X, y + line->Point1.Y, + x + line->Point2.X, y + line->Point2.Y, + line->Thickness,0 ); + } + PCB_END_LOOP; + PCB_ARC_LOOP(layer); + { + pcb_arc_t translated_arc = *arc; + translated_arc.X += x; + translated_arc.Y += y; + pcb_draw_wireframe_arc(pcb_crosshair.GC, &translated_arc, arc->Thickness); + } + PCB_END_LOOP; + PCB_TEXT_LOOP(layer); + { + pcb_text_draw_xor(text, x, y, 1); + } + PCB_END_LOOP; + /* the tmp polygon has n+1 points because the first + * and the last one are set to the same coordinates + */ + PCB_POLY_LOOP(layer); + { + pcb_xordraw_poly(polygon, x, y, 0); + } + PCB_END_LOOP; + PCB_GFX_LOOP(layer); + { + pcb_gfx_draw_xor(gfx, x, y); + } + PCB_END_LOOP; + } + + /* draw subcircuit */ + PCB_SUBC_LOOP(Buffer->Data); + { + pcb_xordraw_subc(subc, x, y, Buffer->from_outside); + } + PCB_END_LOOP; + + /* and the padstacks */ + if (PCB->pstk_on) + PCB_PADSTACK_LOOP(Buffer->Data); + { + thindraw_moved_ps(padstack, x, y); + } + PCB_END_LOOP; +} + +/* --------------------------------------------------------------------------- + * draws the rubberband to insert points into polygons/lines/... + */ +void pcb_xordraw_insert_pt_obj(void) +{ + pcb_line_t *line = (pcb_line_t *) pcb_crosshair.AttachedObject.Ptr2; + rnd_point_t *point = (rnd_point_t *) pcb_crosshair.AttachedObject.Ptr3; + + if (pcb_crosshair.AttachedObject.Type != PCB_OBJ_VOID) { + rnd_render->draw_line(pcb_crosshair.GC, point->X, point->Y, line->Point1.X, line->Point1.Y); + rnd_render->draw_line(pcb_crosshair.GC, point->X, point->Y, line->Point2.X, line->Point2.Y); + } +} + +/* project dx;fy onto an orthogonal to vx;vy and return the offset */ +static void proj_extend(double *ox, double *oy, double vx, double vy, double dx, double dy) +{ + double nx, ny, l, offs; + + if ((vx == 0) && (vy == 0)) { + *ox = *oy = 0; + return; + } + + nx = -vy; ny = vx; /* normal vector */ + + l = nx*nx+ny*ny; + + /* normalize n */ + l = sqrt(l); + nx /= l; ny /= l; + + /* dot product: projected length */ + offs = (dx * nx + dy * ny); + + /* offsets: normal's direction * projected len */ + *ox =nx * offs; *oy = ny * offs; +} + + +/* extend the pine between px;py and (already moved) x;y knowing the previous + point beyond px;py (which is ppx;ppy) */ +static void perp_extend(rnd_coord_t ppx, rnd_coord_t ppy, rnd_coord_t *px, rnd_coord_t *py, rnd_coord_t x, rnd_coord_t y, rnd_coord_t dx, rnd_coord_t dy) +{ + rnd_coord_t ix, iy; + + pcb_lines_intersect_at(ppx, ppy, *px, *py, (*px) + dx, (*py) + dy, x, y, &ix, &iy); + + *px = ix; + *py = iy; +} + + +/*** draw the attached object while in tool mode move or copy ***/ + +/* Some complex objects (padstacks, text, polygons) need to cache their + clearance outline because it's too expensive to calculate on every + screen update */ +typedef struct { + rnd_pline_t *pline; + rnd_polyarea_t *pa; +} xordraw_cache_t; + +static xordraw_cache_t xordraw_cache; + +RND_INLINE void xordraw_movecopy_pstk(rnd_bool modifier, int *event_sent, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_pstk_t *ps = (pcb_pstk_t *)pcb_crosshair.AttachedObject.Ptr2; + thindraw_moved_ps(ps, dx, dy); + + if (conf_core.editor.show_drc) { + if (xordraw_cache.pa == NULL) { + static pcb_poly_t in_poly = {0}; + rnd_layergrp_id_t gid; + + /* build an union of all-layer clearances since a padstack affects multiple layers */ + for(gid = 0; gid < PCB->LayerGroups.len; gid++) { + pcb_layergrp_t *g = &PCB->LayerGroups.grp[gid]; + rnd_polyarea_t *cla, *tmp; + if (!(g->ltype & PCB_LYT_COPPER) || (g->len < 1)) continue; + cla = pcb_thermal_area_pstk(PCB, ps, g->lid[0], &in_poly); + if (xordraw_cache.pa != NULL) { + rnd_polyarea_boolean_free(xordraw_cache.pa, cla, &tmp, RND_PBO_UNITE); + xordraw_cache.pa = tmp; + } + else + xordraw_cache.pa = cla; + } + } + if (xordraw_cache.pa != NULL) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + pcb_xordraw_polyarea(xordraw_cache.pa, dx, dy); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } + } +} + +RND_INLINE void xordraw_movecopy_line(rnd_bool modifier, int *event_sent, rnd_coord_t dx, rnd_coord_t dy) +{ + /* We move a local copy of the line - the real line hasn't moved, only the preview. */ + int constrained = 0; + pcb_line_t line; + rnd_coord_t dx1 = dx, dx2 = dx; + rnd_coord_t dy1 = dy, dy2 = dy; + + memcpy(&line, (pcb_line_t *)pcb_crosshair.AttachedObject.Ptr2, sizeof(line)); + + if(conf_core.editor.rubber_band_keep_midlinedir) + rnd_event(&PCB->hidlib, PCB_EVENT_RUBBER_CONSTRAIN_MAIN_LINE, "pppppp", &line, &constrained, &dx1, &dy1, &dx2, &dy2); + rnd_event(&PCB->hidlib, PCB_EVENT_RUBBER_MOVE_DRAW, "icccc", constrained, dx1, dy1, dx2, dy2); + + *event_sent = 1; + + line.Point1.X += dx1; + line.Point1.Y += dy1; + line.Point2.X += dx2; + line.Point2.Y += dy2; + + pcb_draw_wireframe_line(pcb_crosshair.GC, + line.Point1.X, line.Point1.Y, line.Point2.X, line.Point2.Y, + line.Thickness, 0); + + /* Draw the DRC outline if it is enabled */ + if (conf_core.editor.show_drc) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + pcb_draw_wireframe_line(pcb_crosshair.GC, + line.Point1.X, line.Point1.Y, line.Point2.X, line.Point2.Y, + line.Thickness + 2 * (conf_core.design.clearance + 1), 0); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } +} + +RND_INLINE void xordraw_movecopy_arc(rnd_bool modifier, int *event_sent, rnd_coord_t dx, rnd_coord_t dy) +{ + /* Make a temporary arc and move it by dx,dy */ + pcb_arc_t arc = *((pcb_arc_t *)pcb_crosshair.AttachedObject.Ptr2); + rnd_event(&PCB->hidlib, PCB_EVENT_RUBBER_MOVE_DRAW, "icccc", 0, dx, dy, dx, dy); + *event_sent = 1; + + arc.X += dx; + arc.Y += dy; + + pcb_draw_wireframe_arc(pcb_crosshair.GC, &arc, arc.Thickness); + + /* Draw the DRC outline if it is enabled */ + if (conf_core.editor.show_drc) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + arc.Thickness += 2 * (conf_core.design.clearance + 1); + pcb_draw_wireframe_arc(pcb_crosshair.GC, &arc, arc.Thickness); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } +} + + +RND_INLINE void xordraw_movecopy_poly(rnd_bool modifier, int *event_sent, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_poly_t *polygon = (pcb_poly_t *)pcb_crosshair.AttachedObject.Ptr2; + + /* the tmp polygon has n+1 points because the first and the last one are set to the same coordinates */ + pcb_xordraw_poly(polygon, dx, dy, 0); + + /* if show_drc is enabled and polygon is trying to clear other polygons, + calculate the offset poly and cache */ + if ((conf_core.editor.show_drc) && (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, polygon))) { + if (xordraw_cache.pline == NULL) { + long n; + rnd_vector_t v; + rnd_pline_t *pl; + + for(n = 0; n < polygon->PointN; n++) { + v[0] = polygon->Points[n].X; v[1] = polygon->Points[n].Y; + if (n == 0) + pl = rnd_poly_contour_new(v); + else + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + } + rnd_poly_contour_pre(pl, 1); + if (pl->Flags.orient) + rnd_poly_contour_inv(pl); + + xordraw_cache.pline = rnd_pline_dup_offset(pl, -conf_core.design.clearance); + rnd_poly_contour_del(&pl); + } + + /* draw the clearance offset poly */ + if (xordraw_cache.pline != NULL) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + pcb_xordraw_pline(xordraw_cache.pline, dx, dy); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } + } +} + +RND_INLINE void xordraw_movecopy_text(rnd_bool modifier, int *event_sent, rnd_coord_t dx, rnd_coord_t dy) +{ + int want_box = 1; + pcb_text_t *text = (pcb_text_t *)pcb_crosshair.AttachedObject.Ptr2; + if (conf_core.editor.show_drc) { + if (xordraw_cache.pa == NULL) + xordraw_cache.pa = pcb_poly_construct_text_clearance(text); + if (xordraw_cache.pa != NULL) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + pcb_xordraw_polyarea(xordraw_cache.pa, dx, dy); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + want_box = 0; + } + } + pcb_text_draw_xor(text, dx, dy, want_box); +} + +RND_INLINE void xordraw_movecopy_gfx(rnd_bool modifier, int *event_sent, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_gfx_t *gfx = (pcb_gfx_t *)pcb_crosshair.AttachedObject.Ptr2; + pcb_gfx_draw_xor(gfx, dx, dy); +} + +RND_INLINE void xordraw_movecopy_line_point(rnd_bool modifier, int *event_sent, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_line_t *line; + rnd_point_t *point, *point1, point2; + + line = (pcb_line_t *)pcb_crosshair.AttachedObject.Ptr2; + point = (rnd_point_t *)pcb_crosshair.AttachedObject.Ptr3; + point1 = (point == &line->Point1 ? &line->Point2 : &line->Point1); + point2 = *point; + point2.X += dx; + point2.Y += dy; + + if(conf_core.editor.move_linepoint_uses_route == 0) { /* config setting for selecting new 45/90 method */ + pcb_draw_wireframe_line(pcb_crosshair.GC,point1->X, point1->Y, point2.X, point2.Y, line->Thickness, 0); + + /* Draw the DRC outline if it is enabled */ + if (conf_core.editor.show_drc) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + pcb_draw_wireframe_line(pcb_crosshair.GC,point1->X, point1->Y, point2.X, point2.Y,line->Thickness + 2 * (conf_core.design.clearance + 1), 0); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } + } + else { + pcb_route_t route; + pcb_route_init(&route); + pcb_route_calculate(PCB, + &route, point1, &point2, pcb_layer_id(PCB->Data,(pcb_layer_t *)pcb_crosshair.AttachedObject.Ptr1), + line->Thickness, line->Clearance, line->Flags, + rnd_gui->shift_is_pressed(rnd_gui), rnd_gui->control_is_pressed(rnd_gui)); + pcb_route_draw(&route,pcb_crosshair.GC); + if (conf_core.editor.show_drc) + pcb_route_draw_drc(&route,pcb_crosshair.GC); + pcb_route_destroy(&route); + } +} + +RND_INLINE void xordraw_movecopy_arc_point(rnd_bool modifier, int *event_sent, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_arc_t arc = *((pcb_arc_t *)pcb_crosshair.AttachedObject.Ptr2); + rnd_coord_t ox1, ox2, oy1, oy2; + rnd_coord_t nx1, nx2, ny1, ny2; + + /* Get the initial position of the arc point */ + pcb_arc_get_end(&arc,0, &ox1, &oy1); + pcb_arc_get_end(&arc,1, &ox2, &oy2); + + /* Update the attached arc point */ + pcb_arc_ui_move_or_copy(&pcb_crosshair); + + /* Update our local arc copy from the attached object */ + if(pcb_crosshair.AttachedObject.radius != 0) { + arc.Width = pcb_crosshair.AttachedObject.radius; + arc.Height = pcb_crosshair.AttachedObject.radius; + } + else { + arc.StartAngle = pcb_crosshair.AttachedObject.start_angle; + arc.Delta = pcb_crosshair.AttachedObject.delta_angle; + } + + pcb_draw_wireframe_arc(pcb_crosshair.GC, &arc, arc.Thickness); + + /* Draw the DRC outline if it is enabled */ + if (conf_core.editor.show_drc) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + arc.Thickness += 2 * (conf_core.design.clearance + 1); + pcb_draw_wireframe_arc(pcb_crosshair.GC, &arc, arc.Thickness); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } + + /* Get the new arc point positions, calculate the movement deltas and send them + in a rubber_move_draw event */ + pcb_arc_get_end(&arc,0, &nx1, &ny1); + pcb_arc_get_end(&arc,1, &nx2, &ny2); + + rnd_event(&PCB->hidlib, PCB_EVENT_RUBBER_MOVE_DRAW, "icccc", 0, nx1-ox1, ny1-oy1, nx2-ox2, ny2-oy2); + *event_sent = 1; +} + +RND_INLINE void xordraw_movecopy_poly_point(rnd_bool modifier, int *event_sent, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_poly_t *polygon; + rnd_point_t *point; + rnd_cardinal_t point_idx, prev, next, prev2, next2; + rnd_coord_t px, py, x, y, nx, ny; + + polygon = (pcb_poly_t *) pcb_crosshair.AttachedObject.Ptr2; + point = (rnd_point_t *) pcb_crosshair.AttachedObject.Ptr3; + point_idx = pcb_poly_point_idx(polygon, point); + + /* get previous and following point */ + prev = pcb_poly_contour_prev_point(polygon, point_idx); + next = pcb_poly_contour_next_point(polygon, point_idx); + + px = polygon->Points[prev].X; py = polygon->Points[prev].Y; + x = point->X + dx; y = point->Y + dy; + nx = polygon->Points[next].X; ny = polygon->Points[next].Y; + + /* modified version: angle keeper; run only on every even call to not mess up the xor */ + if (modifier && pcb_crosshair.edit_poly_point_extra.last_active) { + rnd_coord_t ppx, ppy, nnx, nny; + + pcb_crosshair.edit_poly_point_extra.active = 1; + pcb_crosshair.edit_poly_point_extra.point[0] = &polygon->Points[prev]; + pcb_crosshair.edit_poly_point_extra.point[1] = &polygon->Points[next]; + + prev2 = pcb_poly_contour_prev_point(polygon, prev); + next2 = pcb_poly_contour_next_point(polygon, next); + ppx = polygon->Points[prev2].X; ppy = polygon->Points[prev2].Y; + nnx = polygon->Points[next2].X; nny = polygon->Points[next2].Y; + + perp_extend(ppx, ppy, &px, &py, x, y, dx, dy); + perp_extend(nnx, nny, &nx, &ny, x, y, dx, dy); + + /* draw the extra two segments on prev-prev and next-next */ + rnd_render->draw_line(pcb_crosshair.GC, ppx, ppy, px, py); + rnd_render->draw_line(pcb_crosshair.GC, nnx, nny, nx, ny); + + pcb_crosshair.edit_poly_point_extra.dx[0] = px - polygon->Points[prev].X; + pcb_crosshair.edit_poly_point_extra.dy[0] = py - polygon->Points[prev].Y; + pcb_crosshair.edit_poly_point_extra.dx[1] = nx - polygon->Points[next].X; + pcb_crosshair.edit_poly_point_extra.dy[1] = ny - polygon->Points[next].Y; + } + else + pcb_crosshair.edit_poly_point_extra.active = 0; + + pcb_crosshair.edit_poly_point_extra.last_active = modifier; + + /* draw the two segments */ + rnd_render->draw_line(pcb_crosshair.GC, px, py, x, y); + rnd_render->draw_line(pcb_crosshair.GC, x, y, nx, ny); +} + +RND_INLINE void xordraw_movecopy_gfx_point(rnd_bool modifier, int *event_sent, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_gfx_t *gfx; + rnd_point_t *point, *prev, *next, *opp; + int point_idx, i; + double px, py, nx, ny, cx, cy; + + gfx = (pcb_gfx_t *)pcb_crosshair.AttachedObject.Ptr2; + point = (rnd_point_t *)pcb_crosshair.AttachedObject.Ptr3; + point_idx = point - gfx->corner; + if ((point_idx < 0) || (point_idx > 3)) + return; + + cx = pcb_crosshair.X; + cy = pcb_crosshair.Y; + + i = point_idx - 1; + if (i < 0) i = 3; + prev = gfx->corner + i; + + i = (point_idx + 1) % 4; + next = gfx->corner + i; + + i = (point_idx + 2) % 4; + opp = gfx->corner + i; + + proj_extend(&px, &py, point->X - prev->X, point->Y - prev->Y, dx, dy); + proj_extend(&nx, &ny, point->X - next->X, point->Y - next->Y, dx, dy); + + rnd_render->draw_line(pcb_crosshair.GC, opp->X, opp->Y, prev->X+px, prev->Y+py); + rnd_render->draw_line(pcb_crosshair.GC, opp->X, opp->Y, next->X+nx, next->Y+ny); + rnd_render->draw_line(pcb_crosshair.GC, cx, cy, prev->X+px, prev->Y+py); + rnd_render->draw_line(pcb_crosshair.GC, cx, cy, next->X+nx, next->Y+ny); +} + +void pcb_xordraw_movecopy(rnd_bool modifier) +{ + rnd_coord_t dx = pcb_crosshair.AttachedObject.tx - pcb_crosshair.AttachedObject.X; + rnd_coord_t dy = pcb_crosshair.AttachedObject.ty - pcb_crosshair.AttachedObject.Y; + int event_sent = 0; + + switch (pcb_crosshair.AttachedObject.Type) { + case PCB_OBJ_PSTK: xordraw_movecopy_pstk(modifier, &event_sent, dx, dy); break; + case PCB_OBJ_LINE: xordraw_movecopy_line(modifier, &event_sent, dx, dy); break; + case PCB_OBJ_ARC: xordraw_movecopy_arc(modifier, &event_sent, dx, dy); break; + case PCB_OBJ_POLY: xordraw_movecopy_poly(modifier, &event_sent, dx, dy); break; + case PCB_OBJ_TEXT: xordraw_movecopy_text(modifier, &event_sent, dx, dy); break; + case PCB_OBJ_GFX: xordraw_movecopy_gfx(modifier, &event_sent, dx, dy); break; + case PCB_OBJ_LINE_POINT: xordraw_movecopy_line_point(modifier, &event_sent, dx, dy); break; + case PCB_OBJ_ARC_POINT: xordraw_movecopy_arc_point(modifier, &event_sent, dx, dy); break; + case PCB_OBJ_POLY_POINT: xordraw_movecopy_poly_point(modifier, &event_sent, dx, dy); break; + case PCB_OBJ_GFX_POINT: xordraw_movecopy_gfx_point(modifier, &event_sent, dx, dy); break; + case PCB_OBJ_SUBC: pcb_xordraw_subc((pcb_subc_t *) pcb_crosshair.AttachedObject.Ptr2, dx, dy, 0); break; + } + + /* floaters have a link back to their parent subc */ + if ((pcb_crosshair.AttachedObject.Ptr2 != NULL) && PCB_FLAG_TEST(PCB_FLAG_FLOATER, (pcb_any_obj_t *)pcb_crosshair.AttachedObject.Ptr2)) { + pcb_any_obj_t *obj = pcb_crosshair.AttachedObject.Ptr2; + if (obj->parent_type == PCB_PARENT_LAYER) { + pcb_data_t *data = obj->parent.layer->parent.data; + if ((data != NULL) && (data->parent_type == PCB_PARENT_SUBC)) { + pcb_subc_t *sc = data->parent.subc; + rnd_coord_t ox, oy; + if (pcb_subc_get_origin(sc, &ox, &oy) == 0) + rnd_render->draw_line(pcb_crosshair.GC, ox, oy, pcb_crosshair.X, pcb_crosshair.Y); + } + } + } + + if(!event_sent) + rnd_event(&PCB->hidlib, PCB_EVENT_RUBBER_MOVE_DRAW, "icc", 0, dx, dy); +} + +void pcb_crosshair_attached_clean(rnd_hidlib_t *hidlib) +{ + if (xordraw_cache.pline != NULL) + rnd_poly_contour_del(&xordraw_cache.pline); + + if (xordraw_cache.pa != NULL) + rnd_polyarea_free(&xordraw_cache.pa); +} + +void rnd_draw_attached(rnd_hidlib_t *hidlib, rnd_bool inhibit_drawing_mode) +{ + if (!inhibit_drawing_mode) { + rnd_render->set_drawing_mode(rnd_gui, RND_HID_COMP_RESET, 1, NULL); + rnd_render->set_drawing_mode(rnd_gui, RND_HID_COMP_POSITIVE_XOR, 1, NULL); + } + + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + rnd_tool_draw_attached(hidlib); + + /* an attached box does not depend on a special mode */ + if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_SECOND || pcb_crosshair.AttachedBox.State == PCB_CH_STATE_THIRD) { + rnd_coord_t x1, y1, x2, y2; + + x1 = pcb_crosshair.AttachedBox.Point1.X; + y1 = pcb_crosshair.AttachedBox.Point1.Y; + x2 = pcb_crosshair.AttachedBox.Point2.X; + y2 = pcb_crosshair.AttachedBox.Point2.Y; + rnd_render->draw_rect(pcb_crosshair.GC, x1, y1, x2, y2); + } + + if (!inhibit_drawing_mode) + rnd_render->set_drawing_mode(rnd_gui, RND_HID_COMP_FLUSH, 1, NULL); +} + +void rnd_draw_marks(rnd_hidlib_t *hidlib, rnd_bool inhibit_drawing_mode) +{ + rnd_coord_t ms = conf_core.appearance.mark_size, ms2 = ms / 2; + + if ((pcb_marked.status) || (hidlib->tool_grabbed.status)) { + if (!inhibit_drawing_mode) { + rnd_render->set_drawing_mode(rnd_gui, RND_HID_COMP_RESET, 1, NULL); + rnd_render->set_drawing_mode(rnd_gui, RND_HID_COMP_POSITIVE, 1, NULL); + } + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.mark); + } + + if (pcb_marked.status) { + rnd_render->draw_line(pcb_crosshair.GC, pcb_marked.X - ms, pcb_marked.Y - ms, pcb_marked.X + ms, pcb_marked.Y + ms); + rnd_render->draw_line(pcb_crosshair.GC, pcb_marked.X + ms, pcb_marked.Y - ms, pcb_marked.X - ms, pcb_marked.Y + ms); + } + + if (hidlib->tool_grabbed.status) { + rnd_render->draw_line(pcb_crosshair.GC, hidlib->tool_grabbed.X - ms, hidlib->tool_grabbed.Y - ms2, hidlib->tool_grabbed.X + ms, hidlib->tool_grabbed.Y + ms2); + rnd_render->draw_line(pcb_crosshair.GC, hidlib->tool_grabbed.X + ms2, hidlib->tool_grabbed.Y - ms, hidlib->tool_grabbed.X - ms2, hidlib->tool_grabbed.Y + ms); + } + + if ((pcb_marked.status) || (hidlib->tool_grabbed.status)) + if (!inhibit_drawing_mode) + rnd_render->set_drawing_mode(rnd_gui, RND_HID_COMP_FLUSH, 1, NULL); +} + + +/* --------------------------------------------------------------------------- + * notify the GUI that data relating to the mark is being changed. + * + * The argument passed is rnd_false to notify "changes are about to happen", + * and rnd_true to notify "changes have finished". + * + * Each call with a 'rnd_false' parameter must be matched with a following one + * with a 'rnd_true' parameter. Unmatched 'rnd_true' calls are currently not permitted, + * but might be allowed in the future. + * + * GUIs should not complain if they receive extra calls with 'rnd_true' as parameter. + * They should initiate a redraw of the mark - which may (if necessary) mean + * repainting the whole screen if the GUI hasn't tracked the mark's location. + */ +void pcb_notify_mark_change(rnd_bool changes_complete) +{ + if (rnd_gui->notify_mark_change) + rnd_gui->notify_mark_change(rnd_gui, changes_complete); +} + +static double square(double x) +{ + return x * x; +} + +static double crosshair_sq_dist(pcb_crosshair_t * crosshair, rnd_coord_t x, rnd_coord_t y) +{ + return square(x - crosshair->X) + square(y - crosshair->Y); +} + +struct snap_data { + pcb_crosshair_t *crosshair; + double nearest_sq_dist, max_sq_dist; + rnd_bool nearest_is_grid; + rnd_coord_t x, y; +}; + +/* Snap to a given location if it is the closest thing we found so far. + * If "prefer_to_grid" is set, the passed location will take preference + * over a closer grid points we already snapped to UNLESS the user is + * pressing the SHIFT key. If the SHIFT key is pressed, the closest object + * (including grid points), is always preferred. + */ +static void check_snap_object(struct snap_data *snap_data, rnd_coord_t x, rnd_coord_t y, rnd_bool prefer_to_grid, pcb_any_obj_t *snapo) +{ + double sq_dist; + + /* avoid snapping to an object if it is in the same subc */ + if ((snapo != NULL) && (rnd_conf.editor.mode == pcb_crosshair.tool_move) && (pcb_crosshair.AttachedObject.Type == PCB_OBJ_SUBC)) { + pcb_any_obj_t *parent = (pcb_any_obj_t *)pcb_obj_parent_subc(snapo); + int n; + rnd_cardinal_t parent_id = snapo->ID; + if (parent != NULL) + parent_id = parent->ID; + for(n = 0; n < pcb_crosshair.drags_len; n++) { + if ((snapo->ID == pcb_crosshair.drags[n]) || (parent_id == pcb_crosshair.drags[n])) + return; + } + } + + sq_dist = crosshair_sq_dist(snap_data->crosshair, x, y); + if (sq_dist > snap_data->max_sq_dist) + return; + + if (sq_dist < snap_data->nearest_sq_dist || (prefer_to_grid && snap_data->nearest_is_grid && !rnd_gui->shift_is_pressed(rnd_gui))) { + snap_data->x = x; + snap_data->y = y; + snap_data->nearest_sq_dist = sq_dist; + snap_data->nearest_is_grid = rnd_false; + } +} + +static rnd_bool should_snap_offgrid_line(pcb_board_t *pcb, pcb_layer_t *layer, pcb_line_t *line) +{ + /* Allow snapping to off-grid lines when drawing new lines (on + * the same layer), and when moving a line end-point + * (but don't snap to the same line) + */ + if ((rnd_conf.editor.mode == pcb_crosshair.tool_line && PCB_CURRLAYER(pcb) == layer) || + (rnd_conf.editor.mode == pcb_crosshair.tool_move + && pcb_crosshair.AttachedObject.Type == PCB_OBJ_LINE_POINT + && pcb_crosshair.AttachedObject.Ptr1 == layer + && pcb_crosshair.AttachedObject.Ptr2 != line)) + return rnd_true; + else + return rnd_false; +} + +static void check_snap_offgrid_line(pcb_board_t *pcb, struct snap_data *snap_data, rnd_coord_t nearest_grid_x, rnd_coord_t nearest_grid_y) +{ + void *ptr1, *ptr2, *ptr3; + int ans; + pcb_line_t *line; + rnd_coord_t try_x, try_y; + double dx, dy; + double dist; + + if (!conf_core.editor.snap_pin) + return; + + /* Code to snap at some sensible point along a line */ + /* Pick the nearest grid-point in the x or y direction + * to align with, then adjust until we hit the line + */ + ans = pcb_search_grid_slop(pcb_crosshair.X, pcb_crosshair.Y, PCB_OBJ_LINE, &ptr1, &ptr2, &ptr3); + + if (ans == PCB_OBJ_VOID) + return; + + line = (pcb_line_t *) ptr2; + + if (!should_snap_offgrid_line(pcb, ptr1, line)) + return; + + dx = line->Point2.X - line->Point1.X; + dy = line->Point2.Y - line->Point1.Y; + + /* Try snapping along the X axis */ + if (dy != 0.) { + /* Move in the X direction until we hit the line */ + try_x = (nearest_grid_y - line->Point1.Y) / dy * dx + line->Point1.X; + try_y = nearest_grid_y; + check_snap_object(snap_data, try_x, try_y, rnd_true, (pcb_any_obj_t *)line); + } + + /* Try snapping along the Y axis */ + if (dx != 0.) { + try_x = nearest_grid_x; + try_y = (nearest_grid_x - line->Point1.X) / dx * dy + line->Point1.Y; + check_snap_object(snap_data, try_x, try_y, rnd_true, (pcb_any_obj_t *)line); + } + + if (dx != dy) { /* If line not parallel with dX = dY direction.. */ + /* Try snapping diagonally towards the line in the dX = dY direction */ + + if (dy == 0) + dist = line->Point1.Y - nearest_grid_y; + else + dist = ((line->Point1.X - nearest_grid_x) - (line->Point1.Y - nearest_grid_y) * dx / dy) / (1 - dx / dy); + + try_x = nearest_grid_x + dist; + try_y = nearest_grid_y + dist; + + check_snap_object(snap_data, try_x, try_y, rnd_true, (pcb_any_obj_t *)line); + } + + if (dx != -dy) { /* If line not parallel with dX = -dY direction.. */ + /* Try snapping diagonally towards the line in the dX = -dY direction */ + + if (dy == 0) + dist = nearest_grid_y - line->Point1.Y; + else + dist = ((line->Point1.X - nearest_grid_x) - (line->Point1.Y - nearest_grid_y) * dx / dy) / (1 + dx / dy); + + try_x = nearest_grid_x + dist; + try_y = nearest_grid_y - dist; + + check_snap_object(snap_data, try_x, try_y, rnd_true, (pcb_any_obj_t *)line); + } +} + +/* --------------------------------------------------------------------------- + * recalculates the passed coordinates to fit the current grid setting + */ +void pcb_crosshair_grid_fit(pcb_board_t *pcb, rnd_coord_t X, rnd_coord_t Y) +{ + rnd_hidlib_t *hidlib = &pcb->hidlib; + rnd_coord_t nearest_grid_x, nearest_grid_y, oldx, oldy; + void *ptr1, *ptr2, *ptr3; + struct snap_data snap_data; + int ans, newpos; + + oldx = pcb_crosshair.X; + oldy = pcb_crosshair.Y; + pcb->hidlib.ch_x = pcb_crosshair.X = RND_CLAMP(X, -pcb->hidlib.size_x/2, pcb->hidlib.size_x*3/2); + pcb->hidlib.ch_y = pcb_crosshair.Y = RND_CLAMP(Y, -pcb->hidlib.size_y/2, pcb->hidlib.size_y*3/2); + + nearest_grid_x = rnd_grid_fit(pcb_crosshair.X, pcb->hidlib.grid, pcb->hidlib.grid_ox); + nearest_grid_y = rnd_grid_fit(pcb_crosshair.Y, pcb->hidlib.grid, pcb->hidlib.grid_oy); + + + if (pcb_marked.status && conf_core.editor.orthogonal_moves) { + rnd_coord_t dx = pcb_crosshair.X - hidlib->tool_grabbed.X; + rnd_coord_t dy = pcb_crosshair.Y - hidlib->tool_grabbed.Y; + if (RND_ABS(dx) > RND_ABS(dy)) + nearest_grid_y = hidlib->tool_grabbed.Y; + else + nearest_grid_x = hidlib->tool_grabbed.X; + } + + snap_data.crosshair = &pcb_crosshair; + snap_data.nearest_sq_dist = crosshair_sq_dist(&pcb_crosshair, nearest_grid_x, nearest_grid_y); + snap_data.nearest_is_grid = rnd_true; + snap_data.x = nearest_grid_x; + snap_data.y = nearest_grid_y; + snap_data.max_sq_dist = RND_MAX(rnd_conf.editor.grid * 1.5, rnd_pixel_slop*25); + snap_data.max_sq_dist = snap_data.max_sq_dist * snap_data.max_sq_dist; + + ans = PCB_OBJ_VOID; + if (!pcb->RatDraw) + ans = pcb_search_grid_slop(X, Y, PCB_OBJ_SUBC, &ptr1, &ptr2, &ptr3); + + hidlib->tool_snapped_obj_bbox = NULL; + + if (ans & PCB_OBJ_SUBC) { + pcb_subc_t *sc = (pcb_subc_t *) ptr1; + rnd_coord_t ox, oy; + if (pcb_subc_get_origin(sc, &ox, &oy) == 0) { + check_snap_object(&snap_data, ox, oy, rnd_true, (pcb_any_obj_t *)sc); + hidlib->tool_snapped_obj_bbox = &sc->BoundingBox; + } + } + + /*** padstack center ***/ + ans = PCB_OBJ_VOID; + if (conf_core.editor.snap_pin) + ans = pcb_search_grid_slop(X, Y, PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART, &ptr1, &ptr2, &ptr3); + + /* Avoid snapping padstack to any other padstack */ + if (rnd_conf.editor.mode == pcb_crosshair.tool_move && pcb_crosshair.AttachedObject.Type == PCB_OBJ_PSTK && (ans & PCB_OBJ_PSTK)) + ans = PCB_OBJ_VOID; + + if (ans != PCB_OBJ_VOID) { + pcb_pstk_t *ps = (pcb_pstk_t *) ptr2; + check_snap_object(&snap_data, ps->x, ps->y, rnd_true, (pcb_any_obj_t *)ps); + hidlib->tool_snapped_obj_bbox = &ps->BoundingBox; + } + + /*** arc ***/ + ans = PCB_OBJ_VOID; + if (conf_core.editor.snap_pin) + ans = pcb_search_grid_slop(X, Y, PCB_OBJ_LINE_POINT | PCB_OBJ_ARC_POINT | PCB_OBJ_SUBC_PART, &ptr1, &ptr2, &ptr3); + + if (ans == PCB_OBJ_ARC_POINT) { + /* Arc point needs special handling as it's not a real point but has to be calculated */ + rnd_coord_t ex, ey; + pcb_arc_get_end((pcb_arc_t *)ptr2, (ptr3 != pcb_arc_start_ptr), &ex, &ey); + check_snap_object(&snap_data, ex, ey, rnd_true, (pcb_any_obj_t *)ptr2); + } + else if (ans != PCB_OBJ_VOID) { + rnd_point_t *pnt = (rnd_point_t *) ptr3; + check_snap_object(&snap_data, pnt->X, pnt->Y, rnd_true, (pcb_any_obj_t *)ptr2); + } + + /*** polygon terminal: center ***/ + ans = PCB_OBJ_VOID; + if (conf_core.editor.snap_pin) + ans = pcb_search_grid_slop(X, Y, PCB_OBJ_POLY | PCB_OBJ_SUBC_PART, &ptr1, &ptr2, &ptr3); + + if (ans == PCB_OBJ_POLY) { + pcb_poly_t *p = ptr2; + if (p->term != NULL) { + rnd_coord_t cx, cy; + cx = (p->BoundingBox.X1 + p->BoundingBox.X2)/2; + cy = (p->BoundingBox.Y1 + p->BoundingBox.Y2)/2; + if (pcb_poly_is_point_in_p(cx, cy, 1, p)) + check_snap_object(&snap_data, cx, cy, rnd_true, (pcb_any_obj_t *)p); + } + } + + /*** gfx ***/ + ans = PCB_OBJ_VOID; + ans = pcb_search_grid_slop(X, Y, PCB_OBJ_GFX | PCB_OBJ_SUBC_PART, &ptr1, &ptr2, &ptr3); + if (ans == PCB_OBJ_VOID) { + ans = pcb_search_grid_slop(X, Y, PCB_OBJ_GFX_POINT | PCB_OBJ_SUBC_PART, &ptr1, &ptr2, &ptr3); + if (ans != PCB_OBJ_VOID) { + rnd_point_t *pt = ptr3; + check_snap_object(&snap_data, pt->X, pt->Y, rnd_true, (pcb_any_obj_t *)NULL); + } + } + + /* Snap to offgrid points on lines. */ + if (conf_core.editor.snap_offgrid_line) + check_snap_offgrid_line(pcb, &snap_data, nearest_grid_x, nearest_grid_y); + + ans = PCB_OBJ_VOID; + if (conf_core.editor.snap_pin) + ans = pcb_search_grid_slop(X, Y, PCB_OBJ_POLY_POINT, &ptr1, &ptr2, &ptr3); + + if (ans != PCB_OBJ_VOID) { + rnd_point_t *pnt = (rnd_point_t *) ptr3; + check_snap_object(&snap_data, pnt->X, pnt->Y, rnd_true, NULL); + } + + newpos = (snap_data.x != oldx) || (snap_data.y != oldy); + + pcb->hidlib.ch_x = pcb_crosshair.X = snap_data.x; + pcb->hidlib.ch_y = pcb_crosshair.Y = snap_data.y; + + if (newpos) + rnd_event(hidlib, PCB_EVENT_CROSSHAIR_NEW_POS, "pcc", &pcb_crosshair, oldx, oldy); + + if (rnd_conf.editor.mode == pcb_crosshair.tool_arrow) { + ans = pcb_search_grid_slop(X, Y, PCB_OBJ_LINE_POINT, &ptr1, &ptr2, &ptr3); + if (ans == PCB_OBJ_VOID) { + if ((rnd_gui != NULL) && (rnd_gui->point_cursor != NULL)) + rnd_gui->point_cursor(rnd_gui, rnd_false); + } + else if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, (pcb_line_t *) ptr2)) { + if ((rnd_gui != NULL) && (rnd_gui->point_cursor != NULL)) + rnd_gui->point_cursor(rnd_gui, rnd_true); + } + } + + if (rnd_conf.editor.mode == pcb_crosshair.tool_line && pcb_crosshair.AttachedLine.State != PCB_CH_STATE_FIRST && conf_core.editor.auto_drc) + pcb_line_enforce_drc(pcb); + + rnd_gui->set_crosshair(rnd_gui, pcb_crosshair.X, pcb_crosshair.Y, HID_SC_DO_NOTHING); +} + +/* --------------------------------------------------------------------------- + * move crosshair relative (has to be switched off) + */ +void pcb_crosshair_move_relative(rnd_coord_t DeltaX, rnd_coord_t DeltaY) +{ + pcb_crosshair_grid_fit(PCB, pcb_crosshair.X + DeltaX, pcb_crosshair.Y + DeltaY); +} + +/* --------------------------------------------------------------------------- + * move crosshair absolute + * return rnd_true if the crosshair was moved from its existing position + */ +rnd_bool pcb_crosshair_move_absolute(pcb_board_t *pcb, rnd_coord_t X, rnd_coord_t Y) +{ + rnd_coord_t x, y, z; + pcb_crosshair.ptr_x = X; + pcb_crosshair.ptr_y = Y; + x = pcb_crosshair.X; + y = pcb_crosshair.Y; + pcb_crosshair_grid_fit(pcb, X, Y); + if (pcb_crosshair.X != x || pcb_crosshair.Y != y) { + /* back up to old position to notify the GUI + * (which might want to erase the old crosshair) */ + z = pcb_crosshair.X; + pcb->hidlib.ch_x = pcb_crosshair.X = x; + x = z; + z = pcb_crosshair.Y; + pcb->hidlib.ch_y = pcb_crosshair.Y = y; + rnd_hid_notify_crosshair_change(&pcb->hidlib, rnd_false); /* Our caller notifies when it has done */ + /* now move forward again */ + pcb->hidlib.ch_x = pcb_crosshair.X = x; + pcb->hidlib.ch_y = pcb_crosshair.Y = z; + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * centers the displayed PCB around the specified point (X,Y) + */ +void pcb_center_display(pcb_board_t *pcb, rnd_coord_t X, rnd_coord_t Y) +{ + rnd_coord_t save_grid = pcb->hidlib.grid; + pcb->hidlib.grid = 1; + if (pcb_crosshair_move_absolute(pcb, X, Y)) + rnd_hid_notify_crosshair_change(&pcb->hidlib, rnd_true); + rnd_gui->set_crosshair(rnd_gui, pcb_crosshair.X, pcb_crosshair.Y, HID_SC_WARP_POINTER); + pcb->hidlib.grid = save_grid; +} + +/* allocate GC only when the GUI is already up and running */ +static void pcb_crosshair_gui_init(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pcb_crosshair.GC = rnd_hid_make_gc(); + + rnd_render->set_color(pcb_crosshair.GC, &rnd_conf.appearance.color.cross); + rnd_hid_set_draw_xor(pcb_crosshair.GC, 1); + rnd_hid_set_line_cap(pcb_crosshair.GC, rnd_cap_round); + rnd_hid_set_line_width(pcb_crosshair.GC, 1); +} + +/* --------------------------------------------------------------------------- + * initializes crosshair stuff + * clears the struct + */ +void pcb_crosshair_init(void) +{ + /* clear the mark */ + pcb_marked.status = rnd_false; + + /* Initialise Line Route */ + pcb_route_init(&pcb_crosshair.Route); + + + rnd_event_bind(RND_EVENT_GUI_INIT, pcb_crosshair_gui_init, NULL, crosshair_cookie); +} + +void pcb_crosshair_pre_init(void) +{ + pcb_crosshair.tool_arrow = pcb_crosshair.tool_move = pcb_crosshair.tool_line = -1; + pcb_crosshair.tool_arc = pcb_crosshair.tool_poly = pcb_crosshair.tool_poly_hole = -1; +} + +void pcb_crosshair_uninit(void) +{ + pcb_poly_free_fields(&pcb_crosshair.AttachedPolygon); + pcb_route_destroy(&pcb_crosshair.Route); + if (rnd_render != NULL) + rnd_hid_destroy_gc(pcb_crosshair.GC); + rnd_event_unbind_allcookie(crosshair_cookie); +} + +void pcb_crosshair_set_local_ref(rnd_coord_t X, rnd_coord_t Y, rnd_bool Showing) +{ + static rnd_mark_t old; + static int count = 0; + + if (Showing) { + pcb_notify_mark_change(rnd_false); + if (count == 0) + old = pcb_marked; + pcb_marked.X = X; + pcb_marked.Y = Y; + pcb_marked.status = rnd_true; + count++; + pcb_notify_mark_change(rnd_true); + } + else if (count > 0) { + pcb_notify_mark_change(rnd_false); + count = 0; + pcb_marked = old; + pcb_notify_mark_change(rnd_true); + } +} + +static void pcb_event_move_crosshair(rnd_coord_t ev_x, rnd_coord_t ev_y) +{ + if (pcb_crosshair_move_absolute(PCB, ev_x, ev_y)) { + /* update object position and cursor location */ + rnd_tool_adjust_attached(&PCB->hidlib); + rnd_event(&PCB->hidlib, PCB_EVENT_DRAW_CROSSHAIR_CHATT, NULL); + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); + } +} + + +typedef struct { + int obj, line, box; +} old_crosshair_t; + +void *rnd_hidlib_crosshair_suspend(rnd_hidlib_t *hl) +{ + old_crosshair_t *buf = malloc(sizeof(old_crosshair_t)); + + buf->obj = pcb_crosshair.AttachedObject.State; + buf->line = pcb_crosshair.AttachedLine.State; + buf->box = pcb_crosshair.AttachedBox.State; + rnd_hid_notify_crosshair_change(hl, rnd_false); + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_FIRST; + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; + rnd_hid_notify_crosshair_change(hl, rnd_true); + return buf; +} + +void rnd_hidlib_crosshair_restore(rnd_hidlib_t *hl, void *susp_data) +{ + old_crosshair_t *buf = susp_data; + + rnd_hid_notify_crosshair_change(hl, rnd_false); + pcb_crosshair.AttachedObject.State = buf->obj; + pcb_crosshair.AttachedLine.State = buf->line; + pcb_crosshair.AttachedBox.State = buf->box; + rnd_hid_notify_crosshair_change(hl, rnd_true); + + free(buf); +} + + +void rnd_hidlib_crosshair_move_to(rnd_hidlib_t *hl, rnd_coord_t abs_x, rnd_coord_t abs_y, int mouse_mot) +{ + if (!mouse_mot) { + rnd_hid_notify_crosshair_change(hl, rnd_false); + if (pcb_crosshair_move_absolute((pcb_board_t *)hl, abs_x, abs_y)) + rnd_hid_notify_crosshair_change(hl, rnd_true); + rnd_hid_notify_crosshair_change(hl, rnd_true); + } + else + pcb_event_move_crosshair(abs_x, abs_y); +} Index: tags/2.3.0/src/crosshair.h =================================================================== --- tags/2.3.0/src/crosshair.h (nonexistent) +++ tags/2.3.0/src/crosshair.h (revision 33253) @@ -0,0 +1,126 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_CROSSHAIR_H +#define PCB_CROSSHAIR_H + +#include "config.h" +#include +#include +#include "obj_line.h" +#include "obj_poly.h" +#include "route.h" + +typedef struct { /* currently marked block */ + rnd_point_t Point1, Point2; /* start- and end-position */ + long int State; + rnd_bool otherway; +} pcb_attached_box_t; + +typedef struct { /* currently attached object */ + rnd_coord_t X, Y; /* saved position when tool is move */ + rnd_coord_t tx, ty; /* target position when tool is move */ + rnd_box_t BoundingBox; + long int Type; /* object type */ + long int State; + void *Ptr1, *Ptr2, *Ptr3; /* three pointers to data, see search.c */ + rnd_angle_t start_angle, delta_angle; + rnd_coord_t radius; +} pcb_attached_object_t; + +typedef struct { /* holds crosshair, cursor and crosshair-attachment information */ + rnd_hid_gc_t GC; /* GC for cursor drawing */ + rnd_hid_gc_t AttachGC; /* and for displaying buffer contents */ + rnd_coord_t ptr_x, ptr_y; /* last seen raw mouse pointer x;y coords */ + rnd_coord_t X, Y; /* (snapped) crosshair position */ + pcb_attached_line_t AttachedLine; /* data of new lines... */ + pcb_attached_box_t AttachedBox; + pcb_poly_t AttachedPolygon; + int AttachedPolygon_pts; /* number of valid points ever seen for this poly */ + pcb_attached_object_t AttachedObject; /* data of attached objects */ + pcb_route_t Route; /* Calculated line route in LINE or MOVE(LINE) mode */ + pcb_any_obj_t *extobj_edit; /* refers to the editobject (of an extobj) being edited */ + + /* list of object IDs that could have been dragged so that they can be cycled */ + long int *drags; + int drags_len, drags_current; + rnd_coord_t dragx, dragy; /* the point where drag started */ + + /* tool-specific temporary storage */ + struct { + int active, last_active; + rnd_point_t *point[2]; + rnd_coord_t dx[2], dy[2]; + } edit_poly_point_extra; + + /* cached tool IDs */ + int tool_arrow, tool_line, tool_move, tool_arc, tool_poly, tool_poly_hole; +} pcb_crosshair_t; + +typedef struct { + rnd_cardinal_t Buffer; /* buffer number */ + rnd_bool Moving; /* true if clicked on an object of PCB_SELECT_TYPES */ + void *ptr1, *ptr2, *ptr3; +} pcb_crosshair_note_t; + +extern pcb_crosshair_note_t pcb_crosshair_note; + + +/*** all possible states of an attached object ***/ +#define PCB_CH_STATE_FIRST 0 /* initial state */ +#define PCB_CH_STATE_SECOND 1 +#define PCB_CH_STATE_THIRD 2 + +extern pcb_crosshair_t pcb_crosshair; +extern rnd_mark_t pcb_marked; /* the point the user explicitly marked, or in some operations where the operation originally started */ + +void pcb_notify_mark_change(rnd_bool changes_complete); +void pcb_crosshair_move_relative(rnd_coord_t, rnd_coord_t); +rnd_bool pcb_crosshair_move_absolute(pcb_board_t *pcb, rnd_coord_t, rnd_coord_t); +void pcb_crosshair_init(void); +void pcb_crosshair_pre_init(void); +void pcb_crosshair_uninit(void); +void pcb_crosshair_grid_fit(pcb_board_t *pcb, rnd_coord_t, rnd_coord_t); +void pcb_center_display(pcb_board_t *pcb, rnd_coord_t X, rnd_coord_t Y); + +void pcb_crosshair_set_local_ref(rnd_coord_t X, rnd_coord_t Y, rnd_bool Showing); + +/*** utility for plugins ***/ +void pcb_xordraw_attached_line(rnd_coord_t, rnd_coord_t, rnd_coord_t, rnd_coord_t, rnd_coord_t); +void pcb_xordraw_poly(pcb_poly_t *polygon, rnd_coord_t dx, rnd_coord_t dy, int dash_last); +void pcb_xordraw_poly_subc(pcb_poly_t *polygon, rnd_coord_t dx, rnd_coord_t dy, rnd_coord_t w, rnd_coord_t h, int mirr); +void pcb_xordraw_attached_arc(rnd_coord_t thick); +void pcb_xordraw_buffer(pcb_buffer_t *Buffer); +void pcb_xordraw_movecopy(rnd_bool modifier); +void pcb_xordraw_insert_pt_obj(void); + +/* Always call this before changing the attached object of the crosshair */ +void pcb_crosshair_attached_clean(rnd_hidlib_t *hidlib); + +#endif Index: tags/2.3.0/src/data.c =================================================================== --- tags/2.3.0/src/data.c (nonexistent) +++ tags/2.3.0/src/data.c (revision 33253) @@ -0,0 +1,1036 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include + +#include "board.h" +#include "data.h" +#include "data_list.h" +#include "data_it.h" +#include +#include "list_common.h" +#include +#include "layer_it.h" +#include "operation.h" +#include "flag.h" +#include "undo_old.h" +#include "undo.h" +#include "obj_arc.h" +#include "obj_line.h" +#include "obj_poly.h" +#include "obj_text.h" +#include "obj_pstk.h" +#include "obj_subc.h" + +int pcb_layer_stack[PCB_MAX_LAYER]; /* determines the layer draw order */ + +pcb_buffer_t pcb_buffers[PCB_MAX_BUFFER]; /* my buffers */ +rnd_bool pcb_bumped; /* if the undo serial number has changed */ + +int pcb_added_lines; + +static void pcb_loop_layer(pcb_board_t *pcb, pcb_layer_t *layer, void *ctx, pcb_layer_cb_t lacb, pcb_line_cb_t lcb, pcb_arc_cb_t acb, pcb_text_cb_t tcb, pcb_poly_cb_t pocb, pcb_gfx_cb_t gcb) +{ + if (lacb != NULL) + if (lacb(ctx, pcb, layer, 1)) + return; + + if (lcb != NULL) { + PCB_LINE_LOOP(layer); + { + lcb(ctx, pcb, layer, line); + } + PCB_END_LOOP; + } + + if (acb != NULL) { + PCB_ARC_LOOP(layer); + { + acb(ctx, pcb, layer, arc); + } + PCB_END_LOOP; + } + + if (tcb != NULL) { + PCB_TEXT_LOOP(layer); + { + tcb(ctx, pcb, layer, text); + } + PCB_END_LOOP; + } + + if (pocb != NULL) { + PCB_POLY_LOOP(layer); + { + pocb(ctx, pcb, layer, polygon); + } + PCB_END_LOOP; + } + + if (gcb != NULL) { + PCB_GFX_LOOP(layer); + { + gcb(ctx, pcb, layer, gfx); + } + PCB_END_LOOP; + } + + if (lacb != NULL) + lacb(ctx, pcb, layer, 0); +} + +/* callback based loops */ +void pcb_loop_layers(pcb_board_t *pcb, void *ctx, pcb_layer_cb_t lacb, pcb_line_cb_t lcb, pcb_arc_cb_t acb, pcb_text_cb_t tcb, pcb_poly_cb_t pocb, pcb_gfx_cb_t gcb) +{ + if ((lacb != NULL) || (lcb != NULL) || (acb != NULL) || (tcb != NULL) || (pocb != NULL) || (gcb != NULL)) { + if (pcb->is_footprint) { + int n; + pcb_data_t *data = PCB_REAL_DATA(pcb); + for(n = 0; n < data->LayerN; n++) + pcb_loop_layer(pcb, &data->Layer[n], ctx, lacb, lcb, acb, tcb, pocb, gcb); + } + else { + pcb_layer_it_t it; + rnd_layer_id_t lid; + for(lid = pcb_layer_first_all(&pcb->LayerGroups, &it); lid != -1; lid = pcb_layer_next(&it)) { + pcb_layer_t *layer = pcb->Data->Layer + lid; + pcb_loop_layer(pcb, layer, ctx, lacb, lcb, acb, tcb, pocb, gcb); + } + } + } +} + +void pcb_loop_subc(pcb_board_t *pcb, void *ctx, pcb_subc_cb_t scb) +{ + if (scb != NULL) { + PCB_SUBC_LOOP(PCB_REAL_DATA(pcb)); + { + scb(ctx, pcb, subc, 1); + } + PCB_END_LOOP; + } +} + +void pcb_loop_pstk(pcb_board_t *pcb, void *ctx, pcb_pstk_cb_t pscb) +{ + if (pscb != NULL) { + PCB_PADSTACK_LOOP(PCB_REAL_DATA(pcb)); + { + pscb(ctx, pcb, padstack); + } + PCB_END_LOOP; + } +} + +void pcb_loop_all(pcb_board_t *pcb, void *ctx, + pcb_layer_cb_t lacb, pcb_line_cb_t lcb, pcb_arc_cb_t acb, pcb_text_cb_t tcb, pcb_poly_cb_t pocb, pcb_gfx_cb_t gcb, + pcb_subc_cb_t scb, + pcb_pstk_cb_t pscb + ) +{ + pcb_loop_layers(pcb, ctx, lacb, lcb, acb, tcb, pocb, gcb); + pcb_loop_subc(pcb, ctx, scb); + pcb_loop_pstk(pcb, ctx, pscb); +} + +void pcb_data_uninit(pcb_data_t *data) +{ + pcb_layer_t *layer; + int i, is_subc; + long l; + + is_subc = (data->parent_type == PCB_PARENT_SUBC); + + PCB_SUBC_LOOP(data); + { + pcb_subc_free(subc); + } + PCB_END_LOOP; + + PCB_PADSTACK_LOOP(data); + { + pcb_pstk_free(padstack); + } + PCB_END_LOOP; + + list_map0(&data->Rat, pcb_rat_t, pcb_rat_free); + + for (layer = data->Layer, i = 0; i < data->LayerN; layer++, i++) + pcb_layer_free_fields(layer, 0); + + if (!is_subc) { + if (data->subc_tree) + rnd_r_destroy_tree(&data->subc_tree); + if (data->padstack_tree) + rnd_r_destroy_tree(&data->padstack_tree); + if (data->rat_tree) + rnd_r_destroy_tree(&data->rat_tree); + } + + for (layer = data->Layer, i = 0; i < PCB_MAX_LAYER; layer++, i++) + free((char *)layer->name); + + htip_uninit(&data->id2obj); + + for(l = 0; l < data->ps_protos.used; l++) + pcb_pstk_proto_free_fields(&data->ps_protos.array[l]); + pcb_vtpadstack_proto_uninit(&data->ps_protos); + + memset(data, 0, sizeof(pcb_data_t)); +} + +void pcb_data_free(pcb_data_t *data) +{ + if (data == NULL) + return; + + pcb_data_uninit(data); + free(data); +} + +rnd_bool pcb_data_is_empty(pcb_data_t *Data) +{ + rnd_cardinal_t i; + + if (padstacklist_length(&Data->padstack) != 0) return rnd_false; + if (pcb_subclist_length(&Data->subc) != 0) return rnd_false; + for (i = 0; i < Data->LayerN; i++) + if (!pcb_layer_is_pure_empty(&(Data->Layer[i]))) + return rnd_false; + + return rnd_true; +} + +rnd_box_t *pcb_data_bbox(rnd_box_t *out, pcb_data_t *Data, rnd_bool ignore_floaters) +{ + /* preset identifiers with highest and lowest possible values */ + out->X1 = out->Y1 = RND_MAX_COORD; + out->X2 = out->Y2 = -RND_MAX_COORD; + + /* now scan for the lowest/highest X and Y coordinate */ + PCB_PADSTACK_LOOP(Data); + { + pcb_pstk_bbox(padstack); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, padstack)) + rnd_box_bump_box(out, &padstack->BoundingBox); + } + PCB_END_LOOP; + PCB_SUBC_LOOP(Data); + { + pcb_subc_bbox(subc); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, subc)) + rnd_box_bump_box(out, &subc->BoundingBox); + } + PCB_END_LOOP; + PCB_LINE_ALL_LOOP(Data); + { + pcb_line_bbox(line); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, line)) + rnd_box_bump_box(out, &line->BoundingBox); + } + PCB_ENDALL_LOOP; + PCB_ARC_ALL_LOOP(Data); + { + pcb_arc_bbox(arc); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, arc)) + rnd_box_bump_box(out, &arc->BoundingBox); + } + PCB_ENDALL_LOOP; + PCB_TEXT_ALL_LOOP(Data); + { + pcb_text_bbox(pcb_font(PCB, text->fid, 1), text); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, text)) + rnd_box_bump_box(out, &text->BoundingBox); + } + PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(Data); + { + pcb_poly_bbox(polygon); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, polygon)) + rnd_box_bump_box(out, &polygon->BoundingBox); + } + PCB_ENDALL_LOOP; + return (pcb_data_is_empty(Data) ? NULL : out); +} + +rnd_box_t *pcb_data_bbox_naked(rnd_box_t *out, pcb_data_t *Data, rnd_bool ignore_floaters) +{ + /* preset identifiers with highest and lowest possible values */ + out->X1 = out->Y1 = RND_MAX_COORD; + out->X2 = out->Y2 = -RND_MAX_COORD; + + /* now scan for the lowest/highest X and Y coordinate */ + PCB_PADSTACK_LOOP(Data); + { + pcb_pstk_bbox(padstack); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, padstack)) + rnd_box_bump_box(out, &padstack->bbox_naked); + } + PCB_END_LOOP; + PCB_SUBC_LOOP(Data); + { + pcb_subc_bbox(subc); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, subc)) + rnd_box_bump_box(out, &subc->bbox_naked); + } + PCB_END_LOOP; + PCB_LINE_ALL_LOOP(Data); + { + pcb_line_bbox(line); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, line)) + rnd_box_bump_box(out, &line->bbox_naked); + } + PCB_ENDALL_LOOP; + PCB_ARC_ALL_LOOP(Data); + { + pcb_arc_bbox(arc); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, arc)) + rnd_box_bump_box(out, &arc->bbox_naked); + } + PCB_ENDALL_LOOP; + PCB_TEXT_ALL_LOOP(Data); + { + pcb_text_bbox(pcb_font(PCB, text->fid, 1), text); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, text)) + rnd_box_bump_box(out, &text->bbox_naked); + } + PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(Data); + { + pcb_poly_bbox(polygon); + if (!ignore_floaters || !PCB_FLAG_TEST(PCB_FLAG_FLOATER, polygon)) + rnd_box_bump_box(out, &polygon->bbox_naked); + } + PCB_ENDALL_LOOP; + return (pcb_data_is_empty(Data) ? NULL : out); +} + +void pcb_data_set_layer_parents(pcb_data_t *data) +{ + rnd_layer_id_t n; + for(n = 0; n < PCB_MAX_LAYER; n++) + pcb_layer_setup(&data->Layer[n], data); +} + +void pcb_data_bind_board_layers(pcb_board_t *pcb, pcb_data_t *data, int share_rtrees) +{ + rnd_layer_id_t n; + for(n = 0; n < pcb->Data->LayerN; n++) { + pcb_layer_real2bound(&data->Layer[n], &pcb->Data->Layer[n], share_rtrees); + data->Layer[n].parent.data = data; + data->Layer[n].parent_type = PCB_PARENT_DATA; + data->Layer[n].type = PCB_OBJ_LAYER; + } + data->LayerN = pcb->Data->LayerN; +} + +void pcb_data_make_layers_bound(pcb_board_t *pcb4layer_groups, pcb_data_t *data) +{ + rnd_layer_id_t n; + for(n = 0; n < data->LayerN; n++) { + pcb_layer_type_t lyt = pcb_layergrp_flags(pcb4layer_groups, data->Layer[n].meta.real.grp); + memset(&data->Layer[n].meta.bound, 0, sizeof(data->Layer[n].meta.bound)); + pcb_layer_real2bound_offs(&data->Layer[n], pcb4layer_groups, &data->Layer[n]); + data->Layer[n].parent.data = data; + data->Layer[n].parent_type = PCB_PARENT_DATA; + data->Layer[n].type = PCB_OBJ_LAYER; + data->Layer[n].meta.bound.type = lyt; + } +} + +void pcb_data_unbind_layers(pcb_data_t *data) +{ + rnd_layer_id_t n; + for(n = 0; n < data->LayerN; n++) + data->Layer[n].meta.bound.real = NULL; +} + +void pcb_data_binding_update(pcb_board_t *pcb, pcb_data_t *data) +{ + int i; + for(i = 0; i < data->LayerN; i++) { + pcb_layer_t *sourcelayer = &data->Layer[i]; + pcb_layer_t *destlayer = pcb_layer_resolve_binding(pcb, sourcelayer); + sourcelayer->meta.bound.real = destlayer; + } +} + +void pcb_data_init(pcb_data_t *data) +{ + memset(data, 0, sizeof(pcb_data_t)); + htip_init(&data->id2obj, longhash, longkeyeq); +} + +pcb_data_t *pcb_data_new(pcb_board_t *parent) +{ + pcb_data_t *data; + data = malloc(sizeof(pcb_data_t)); + pcb_data_init(data); + if (parent != NULL) + PCB_SET_PARENT(data, board, parent); + pcb_data_set_layer_parents(data); + return data; +} + +pcb_board_t *pcb_data_get_top(pcb_data_t *data) +{ + while((data != NULL) && (data->parent_type == PCB_PARENT_SUBC)) + data = data->parent.subc->parent.data; + + if (data == NULL) + return NULL; + + if (data->parent_type == PCB_PARENT_BOARD) + return data->parent.board; + + return NULL; +} + +void pcb_data_mirror(pcb_data_t *data, rnd_coord_t y_offs, pcb_data_mirror_text_t mtxt, rnd_bool pstk_smirror, rnd_bool undoable) +{ + pcb_undo_freeze_serial(); + pcb_data_clip_inhibit_inc(data); + PCB_PADSTACK_LOOP(data); + { + pcb_pstk_mirror(padstack, y_offs, pstk_smirror, 0, undoable); + } + PCB_END_LOOP; + PCB_SUBC_LOOP(data); + { + pcb_subc_mirror(data, subc, y_offs, pstk_smirror, undoable); + } + PCB_END_LOOP; + PCB_LINE_ALL_LOOP(data); + { + pcb_line_mirror(line, y_offs, undoable); + } + PCB_ENDALL_LOOP; + PCB_ARC_ALL_LOOP(data); + { + pcb_arc_mirror(arc, y_offs, undoable); + } + PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(data); + { + pcb_poly_mirror(polygon, y_offs, undoable); + } + PCB_ENDALL_LOOP; + + switch(mtxt & PCB_TXM_MASK_OP) { + case PCB_TXM_NONE: + break; + case PCB_TXM_SIDE: + PCB_TEXT_ALL_LOOP(data); + { + pcb_text_flip_side(layer, text, y_offs, undoable); + } + PCB_ENDALL_LOOP; + break; + case PCB_TXM_COORD: + PCB_TEXT_ALL_LOOP(data); + { + pcb_text_mirror_coords(text, y_offs, undoable); + } + PCB_ENDALL_LOOP; + break; + } + + if(mtxt & PCB_TXM_ROT) { + PCB_TEXT_ALL_LOOP(data); + { + if (text->rot != 0) { + text->rot = -text->rot; + } + } + PCB_ENDALL_LOOP; + } + + pcb_data_clip_inhibit_dec(data, 0); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); +} + +void pcb_data_scale(pcb_data_t *data, double sx, double sy, double sth, int recurse) +{ + int undoable = 0; + + if ((sx == 1.0) && (sy == 1.0) && (sth == 1.0)) + return; + + PCB_PADSTACK_LOOP(data); + { + pcb_pstk_scale(padstack, sx, sy, undoable); + } + PCB_END_LOOP; + if (recurse) { + PCB_SUBC_LOOP(data); + { + pcb_subc_scale(data, subc, sx, sy, sth, 1); + } + PCB_END_LOOP; + } + else { + /* when not scaled recursively, position still needs to be scaled */ + PCB_SUBC_LOOP(data); + { + rnd_coord_t ox, oy, nx, ny; + if (pcb_subc_get_origin(subc, &ox, &oy) == 0) { + nx = rnd_round((double)ox * sx); + ny = rnd_round((double)oy * sy); + pcb_subc_move(subc, nx - ox, ny - oy, rnd_true); + } + } + PCB_END_LOOP; + } + PCB_LINE_ALL_LOOP(data); + { + pcb_line_scale(line, sx, sy, sth); + } + PCB_ENDALL_LOOP; + PCB_ARC_ALL_LOOP(data); + { + pcb_arc_scale(arc, sx, sy, sth); + } + PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(data); + { + pcb_poly_scale(polygon, sx, sy); + } + PCB_ENDALL_LOOP; + PCB_TEXT_ALL_LOOP(data); + { + pcb_text_scale(text, sx, sy, sth); + } + PCB_ENDALL_LOOP; +} + + +int pcb_data_normalize_(pcb_data_t *data, rnd_box_t *data_bbox) +{ + rnd_box_t tmp; + rnd_coord_t dx = 0, dy = 0; + + if (data_bbox == NULL) { + data_bbox = &tmp; + if (pcb_data_bbox(data_bbox, data, rnd_false) == NULL) + return -1; + } + + if (data_bbox->X1 < 0) + dx = -data_bbox->X1; + if (data_bbox->Y1 < 0) + dy = -data_bbox->Y1; + + if ((dx > 0) || (dy > 0)) { + pcb_data_move(data, dx, dy, 0); + return 1; + } + + return 0; +} + +int pcb_data_normalize(pcb_data_t *data) +{ + return pcb_data_normalize_(data, NULL); +} + +void pcb_data_set_parent_globals(pcb_data_t *data, pcb_data_t *new_parent) +{ + pcb_pstk_t *ps; + pcb_subc_t *sc; + gdl_iterator_t it; + + padstacklist_foreach(&data->padstack, &it, ps) { + ps->parent_type = PCB_PARENT_DATA; + ps->parent.data = new_parent; + } + subclist_foreach(&data->subc, &it, sc) { + sc->parent_type = PCB_PARENT_DATA; + sc->parent.data = new_parent; + } +} + + +extern pcb_opfunc_t MoveFunctions; +void pcb_data_move(pcb_data_t *data, rnd_coord_t dx, rnd_coord_t dy, int undoable) +{ + pcb_opctx_t ctx; + + ctx.move.pcb = pcb_data_get_top(data); + ctx.move.dx = dx; + ctx.move.dy = dy; + + PCB_PADSTACK_LOOP(data); + { + if (undoable) pcb_undo_add_obj_to_move(PCB_OBJ_PSTK, data, padstack, padstack, dx, dy); + pcb_object_operation(&MoveFunctions, &ctx, PCB_OBJ_PSTK, padstack, padstack, padstack); + } + PCB_END_LOOP; + PCB_SUBC_LOOP(data); + { + if (undoable) pcb_undo_add_obj_to_move(PCB_OBJ_SUBC, data, subc, subc, dx, dy); + pcb_object_operation(&MoveFunctions, &ctx, PCB_OBJ_SUBC, subc, subc, subc); + } + PCB_END_LOOP; + PCB_LINE_ALL_LOOP(data); + { + if (undoable) pcb_undo_add_obj_to_move(PCB_OBJ_LINE, layer, line, line, dx, dy); + pcb_object_operation(&MoveFunctions, &ctx, PCB_OBJ_LINE, layer, line, line); + } + PCB_ENDALL_LOOP; + PCB_ARC_ALL_LOOP(data); + { + if (undoable) pcb_undo_add_obj_to_move(PCB_OBJ_ARC, layer, arc, arc, dx, dy); + pcb_object_operation(&MoveFunctions, &ctx, PCB_OBJ_ARC, layer, arc, arc); + } + PCB_ENDALL_LOOP; + PCB_TEXT_ALL_LOOP(data); + { + if (undoable) pcb_undo_add_obj_to_move(PCB_OBJ_TEXT, layer, text, text, dx, dy); + pcb_object_operation(&MoveFunctions, &ctx, PCB_OBJ_TEXT, layer, text, text); + } + PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(data); + { + if (undoable) pcb_undo_add_obj_to_move(PCB_OBJ_POLY, layer, polygon, polygon, dx, dy); + pcb_object_operation(&MoveFunctions, &ctx, PCB_OBJ_POLY, layer, polygon, polygon); + } + PCB_ENDALL_LOOP; + PCB_GFX_ALL_LOOP(data); + { + if (undoable) pcb_undo_add_obj_to_move(PCB_OBJ_GFX, layer, gfx, gfx, dx, dy); + pcb_object_operation(&MoveFunctions, &ctx, PCB_OBJ_GFX, layer, gfx, gfx); + } + PCB_ENDALL_LOOP; +} + +void pcb_data_list_by_flag(pcb_data_t *data, vtp0_t *dst, pcb_objtype_t type, unsigned long mask) +{ + if (type & PCB_OBJ_PSTK) PCB_PADSTACK_LOOP(data); { + if ((mask == 0) || (PCB_FLAG_TEST(mask, padstack))) vtp0_append(dst, padstack); + } PCB_END_LOOP; + if (type & PCB_OBJ_SUBC) PCB_SUBC_LOOP(data); { + if ((mask == 0) || (PCB_FLAG_TEST(mask, subc))) vtp0_append(dst, subc); + } PCB_END_LOOP; + if (type & PCB_OBJ_LINE) PCB_LINE_ALL_LOOP(data); { + if ((mask == 0) || (PCB_FLAG_TEST(mask, line))) vtp0_append(dst, line); + } PCB_ENDALL_LOOP; + if (type & PCB_OBJ_ARC) PCB_ARC_ALL_LOOP(data); { + if ((mask == 0) || (PCB_FLAG_TEST(mask, arc))) vtp0_append(dst, arc); + } PCB_ENDALL_LOOP; + if (type & PCB_OBJ_TEXT) PCB_TEXT_ALL_LOOP(data); { + if ((mask == 0) || (PCB_FLAG_TEST(mask, text))) vtp0_append(dst, text); + } PCB_ENDALL_LOOP; + if (type & PCB_OBJ_POLY) PCB_POLY_ALL_LOOP(data); { + if ((mask == 0) || (PCB_FLAG_TEST(mask, polygon))) vtp0_append(dst, polygon); + } PCB_ENDALL_LOOP; + if (type & PCB_OBJ_GFX) PCB_GFX_ALL_LOOP(data); { + if ((mask == 0) || (PCB_FLAG_TEST(mask, gfx))) vtp0_append(dst, gfx); + } PCB_ENDALL_LOOP; +} + +void pcb_data_list_terms(pcb_data_t *data, vtp0_t *dst, pcb_objtype_t type) +{ +TODO("subc TODO: subc-in-subc") +/* if (type & PCB_OBJ_SUBC) PCB_SUBC_LOOP(data); { + if (subc->term != NULL) vtp0_append(dst, subc); + } PCB_END_LOOP;*/ + if (type & PCB_OBJ_LINE) PCB_LINE_ALL_LOOP(data); { + if ((line->term != NULL)) vtp0_append(dst, line); + } PCB_ENDALL_LOOP; + if (type & PCB_OBJ_ARC) PCB_ARC_ALL_LOOP(data); { + if (arc->term != NULL) vtp0_append(dst, arc); + } PCB_ENDALL_LOOP; + if (type & PCB_OBJ_TEXT) PCB_TEXT_ALL_LOOP(data); { + if (text->term != NULL) vtp0_append(dst, text); + } PCB_ENDALL_LOOP; + if (type & PCB_OBJ_POLY) PCB_POLY_ALL_LOOP(data); { + if (polygon->term != NULL) vtp0_append(dst, polygon); + } PCB_ENDALL_LOOP; +} + +void pcb_data_clip_polys(pcb_data_t *data) +{ + PCB_POLY_ALL_LOOP(data); + { + pcb_poly_init_clip(data, layer, polygon); + } + PCB_ENDALL_LOOP; +} + +#define rsearch(tree) \ + do { \ + rnd_r_dir_t tmp = rnd_r_search(tree, starting_region, region_in_search, rectangle_in_region, closure, num_found); \ + if (tmp == RND_R_DIR_CANCEL) return tmp; \ + res |= tmp; \ + } while(0); + +rnd_r_dir_t pcb_data_r_search(pcb_data_t *data, pcb_objtype_t types, const rnd_box_t *starting_region, + rnd_r_dir_t (*region_in_search) (const rnd_box_t *region, void *cl), + rnd_r_dir_t (*rectangle_in_region) (const rnd_box_t *box, void *cl), + void *closure, int *num_found, rnd_bool vis_only) +{ + rnd_layer_id_t lid; + rnd_r_dir_t res = 0; + + if (!vis_only || PCB->RatOn) + if (types & PCB_OBJ_RAT) rsearch(data->rat_tree); + + if (!vis_only || PCB->pstk_on || PCB->hole_on) + if (types & PCB_OBJ_PSTK) rsearch(data->padstack_tree); + + if (!vis_only || PCB->SubcOn) + if (types & PCB_OBJ_SUBC) rsearch(data->subc_tree); + + for(lid = 0; lid < data->LayerN; lid++) { + pcb_layer_t *ly = data->Layer + lid; + + if (vis_only && (!ly->meta.real.vis)) + continue; + + if (types & PCB_OBJ_LINE) rsearch(ly->line_tree); + if (types & PCB_OBJ_TEXT) rsearch(ly->text_tree); + if (types & PCB_OBJ_POLY) rsearch(ly->polygon_tree); + if (types & PCB_OBJ_ARC) rsearch(ly->arc_tree); + if (types & PCB_OBJ_GFX) rsearch(ly->gfx_tree); + } + + return res; +} + +/*** poly clip inhibit mechanism ***/ +void pcb_data_clip_inhibit_inc(pcb_data_t *data) +{ + int old = data->clip_inhibit; + data->clip_inhibit++; + + if (old > data->clip_inhibit) { + rnd_message(RND_MSG_ERROR, "Internal error: overflow on poly clip inhibit\n"); + abort(); + } +} + +void pcb_data_clip_inhibit_dec(pcb_data_t *data, rnd_bool enable_progbar) +{ + if (data->clip_inhibit == 0) { + rnd_message(RND_MSG_ERROR, "Internal error: overflow on poly clip inhibit\n"); + assert(!"clip_inhibit underflow"); + return; + } + data->clip_inhibit--; + + if (data->clip_inhibit == 0) + pcb_data_clip_dirty(data, enable_progbar); +} + +typedef struct { + pcb_data_t *data; + time_t nextt; + int inited, force_all; + rnd_cardinal_t at, total; +} data_clip_all_t; + +static void data_clip_all_cb(void *ctx_) +{ + data_clip_all_t *ctx = ctx_; + + ctx->at++; + if ((ctx->at % 8) == 0) { + time_t now = time(NULL); + if (now >= ctx->nextt) { + ctx->nextt = now+1; + if (!ctx->inited) { + ctx->total = 0; + PCB_POLY_ALL_LOOP(ctx->data); { + if (ctx->force_all || polygon->clip_dirty) + ctx->total += pcb_poly_num_clears(ctx->data, layer, polygon); + } PCB_ENDALL_LOOP; + ctx->inited = 1; + } + if (rnd_hid_progress(ctx->at, ctx->total, "Clipping polygons...") != 0) { + int rv = rnd_hid_message_box(&PCB->hidlib, "warning", "Stop poly clipping", "The only way to cancel poly clipping is to quit pcb-rnd.\nAre you sure you want to quit?", "yes, quit pcb-rnd", 1, "no, continue clipping", 2, NULL); + if (rv == 1) { + exit(1); + } + else { + /* Have to recreate the dialog next time, that's the only way to get it out from the cancel state */ + rnd_hid_progress(0, 0, NULL); + } + } + } + } +} + +void pcb_data_clip_all_poly(pcb_data_t *data, rnd_bool enable_progbar, rnd_bool force_all) +{ + data_clip_all_t ctx; + + if (data->clip_inhibit != 0) + return; + + PCB_SUBC_LOOP(data); { + pcb_data_clip_dirty(subc->data, enable_progbar); + } PCB_END_LOOP; + + ctx.data = data; + ctx.force_all = force_all; + ctx.nextt = time(NULL) + 2; + ctx.total = ctx.at = 0; + ctx.inited = 0; + + /* have to go in two passes, to make sure that clearing polygons are done + before the polygons that are potentially being cleared - this way we + guarantee that by the time the poly-vs-poly clearance needs to be + calculated, the clearing poly has a contour */ + PCB_POLY_ALL_LOOP(data); { + if ((force_all || polygon->clip_dirty) && (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, polygon))) + pcb_poly_init_clip_prog(data, layer, polygon, (enable_progbar ? data_clip_all_cb : NULL), &ctx, 0); + } PCB_ENDALL_LOOP; + + PCB_POLY_ALL_LOOP(data); { + if ((force_all || polygon->clip_dirty) && (!PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, polygon))) + pcb_poly_init_clip_prog(data, layer, polygon, (enable_progbar ? data_clip_all_cb : NULL), &ctx, 0); + } PCB_ENDALL_LOOP; + + if (enable_progbar) + rnd_hid_progress(0, 0, NULL); +} + +void pcb_data_clip_dirty(pcb_data_t *data, rnd_bool enable_progbar) +{ + pcb_data_clip_all_poly(data, enable_progbar, rnd_false); +} + +void pcb_data_clip_all(pcb_data_t *data, rnd_bool enable_progbar) +{ + pcb_data_clip_all_poly(data, enable_progbar, rnd_true); +} + + +void pcb_data_flag_change(pcb_data_t *data, pcb_objtype_t mask, int how, unsigned long flags) +{ + pcb_any_obj_t *o; + pcb_data_it_t it; + + for(o = pcb_data_first(&it, data, mask); o != NULL; o = pcb_data_next(&it)) { + PCB_FLAG_CHANGE(how, flags, o); + if (o->type == PCB_OBJ_SUBC) + pcb_data_flag_change(((pcb_subc_t *)o)->data, mask, how, flags); + } +} + +#include "obj_pstk_draw.h" +#include "obj_text_draw.h" +#include "obj_poly_draw.h" +#include "obj_arc_draw.h" +#include "obj_line_draw.h" +#include "conf_core.h" +#include "undo.h" + +/* Check if object n has flag set and if so, clear it and do all administration */ +#define CHK_CLEAR(n) \ +do { \ + if (PCB_FLAG_TEST(flag, (pcb_any_obj_t *)n)) { \ + if (undoable) \ + pcb_undo_add_obj_to_flag((pcb_any_obj_t *)n); \ + PCB_FLAG_CLEAR(flag, (pcb_any_obj_t *)n); \ + if (redraw) \ + pcb_pstk_invalidate_draw((pcb_pstk_t *)n); \ + cnt++; \ + } \ +} while(0) + +unsigned long pcb_data_clear_obj_flag(pcb_data_t *data, pcb_objtype_t tmask, unsigned long flag, int redraw, int undoable) +{ + rnd_rtree_it_t it; + rnd_box_t *n; + int li; + pcb_layer_t *l; + unsigned long cnt = 0; + + if (flag & PCB_FLAG_WARN) + conf_core.temp.rat_warn = rnd_false; + + if (tmask & PCB_OBJ_PSTK) + for(n = rnd_r_first(data->padstack_tree, &it); n != NULL; n = rnd_r_next(&it)) + CHK_CLEAR(n); + + if (tmask & PCB_OBJ_RAT) + for(n = rnd_r_first(data->rat_tree, &it); n != NULL; n = rnd_r_next(&it)) + CHK_CLEAR(n); + + if (tmask & PCB_OBJ_SUBC) + for(n = rnd_r_first(data->subc_tree, &it); n != NULL; n = rnd_r_next(&it)) + CHK_CLEAR(n); + + if ((tmask & (PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_TEXT | PCB_OBJ_GFX)) == 0) + return cnt; /* do not run the layer loop if no layer object is requested */ + + for(li = 0, l = data->Layer; li < data->LayerN; li++,l++) { + if (tmask & PCB_OBJ_LINE) + for(n = rnd_r_first(l->line_tree, &it); n != NULL; n = rnd_r_next(&it)) + CHK_CLEAR(n); + + if (tmask & PCB_OBJ_ARC) + for(n = rnd_r_first(l->arc_tree, &it); n != NULL; n = rnd_r_next(&it)) + CHK_CLEAR(n); + + if (tmask & PCB_OBJ_POLY) + for(n = rnd_r_first(l->polygon_tree, &it); n != NULL; n = rnd_r_next(&it)) + CHK_CLEAR(n); + + if (tmask & PCB_OBJ_TEXT) + for(n = rnd_r_first(l->text_tree, &it); n != NULL; n = rnd_r_next(&it)) + CHK_CLEAR(n); + + if (tmask & PCB_OBJ_GFX) + for(n = rnd_r_first(l->gfx_tree, &it); n != NULL; n = rnd_r_next(&it)) + CHK_CLEAR(n); + } + return cnt; +} +#undef CHK_CLEAR + +unsigned long pcb_data_clear_flag(pcb_data_t *data, unsigned long flag, int redraw, int undoable) +{ + return pcb_data_clear_obj_flag(data, PCB_OBJ_CLASS_REAL, flag, redraw, undoable); +} + + +void pcb_data_dynflag_clear(pcb_data_t *data, pcb_dynf_t dynf) +{ + rnd_rtree_it_t it; + rnd_box_t *n; + int li; + pcb_layer_t *l; + + for(n = rnd_r_first(data->padstack_tree, &it); n != NULL; n = rnd_r_next(&it)) + PCB_DFLAG_CLR(&((pcb_any_obj_t *)n)->Flags, dynf); + + for(n = rnd_r_first(data->subc_tree, &it); n != NULL; n = rnd_r_next(&it)) + PCB_DFLAG_CLR(&((pcb_any_obj_t *)n)->Flags, dynf); + + for(n = rnd_r_first(data->rat_tree, &it); n != NULL; n = rnd_r_next(&it)) + PCB_DFLAG_CLR(&((pcb_any_obj_t *)n)->Flags, dynf); + + for(li = 0, l = data->Layer; li < data->LayerN; li++,l++) { + for(n = rnd_r_first(l->line_tree, &it); n != NULL; n = rnd_r_next(&it)) + PCB_DFLAG_CLR(&((pcb_any_obj_t *)n)->Flags, dynf); + + for(n = rnd_r_first(l->arc_tree, &it); n != NULL; n = rnd_r_next(&it)) + PCB_DFLAG_CLR(&((pcb_any_obj_t *)n)->Flags, dynf); + + for(n = rnd_r_first(l->polygon_tree, &it); n != NULL; n = rnd_r_next(&it)) + PCB_DFLAG_CLR(&((pcb_any_obj_t *)n)->Flags, dynf); + + for(n = rnd_r_first(l->text_tree, &it); n != NULL; n = rnd_r_next(&it)) + PCB_DFLAG_CLR(&((pcb_any_obj_t *)n)->Flags, dynf); + + for(n = rnd_r_first(l->gfx_tree, &it); n != NULL; n = rnd_r_next(&it)) + PCB_DFLAG_CLR(&((pcb_any_obj_t *)n)->Flags, dynf); + } +} + +static pcb_data_t *pcb_data_by_name_(pcb_board_t *pcb, const char **name, int *addr) +{ + if (name == NULL) + return NULL; + + if (rnd_strncasecmp(*name, "pcb", 3) == 0) { + (*name) += 3; + if (**name == '/') + (*name)++; + *addr = 1; + return pcb->Data; + } + else if (rnd_strncasecmp(*name, "buffer#", 7) == 0) { + char *end; + long idx = strtol((*name)+7, &end, 10); + if ((*end == '\0') && (idx >= 0) && (idx < PCB_MAX_BUFFER)) { + *name = end; + if (**name == '/') + (*name)++; + *addr = idx+2; + return pcb_buffers[idx].Data; + } + } + else if (rnd_strncasecmp(*name, "buffer", 6) == 0) { + (*name) += 6; + if (**name == '/') + (*name)++; + *addr = conf_core.editor.buffer_number+2; + return PCB_PASTEBUFFER->Data; + } + *addr = 0; + return NULL; +} + +char *pcb_data_name_by_addr(int addr, char *buf) +{ + if (addr == 0) *buf = '\0'; + else if (addr == 1) strcpy(buf, "pcb"); + else rnd_snprintf(buf, 16, "buffer#%d", addr-2); + return buf; +} + +pcb_data_t *pcb_data_by_name(pcb_board_t *pcb, const char **name) +{ + int dummy; + return pcb_data_by_name_(pcb, name, &dummy); +} + +int pcb_data_addr_by_name(pcb_board_t *pcb, const char **name) +{ + int dummy; + pcb_data_by_name_(pcb, name, &dummy); + return dummy; +} + +const char *pcb_data_to_name(pcb_board_t *pcb, pcb_data_t *data, char *buf, int buf_len) +{ + int n; + + assert(buf_len > 15); + if (buf_len < 16) + return NULL; + + if (data == pcb->Data) + return "pcb"; + + for(n = 0; n < PCB_MAX_BUFFER; n++) { + if (data == pcb_buffers[n].Data) { + rnd_sprintf(buf, "buffer#%d", n); + return buf; + } + } + + return NULL; +} Index: tags/2.3.0/src/data.h =================================================================== --- tags/2.3.0/src/data.h (nonexistent) +++ tags/2.3.0/src/data.h (revision 33253) @@ -0,0 +1,257 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* common identifiers */ + +#ifndef PCB_DATA_H +#define PCB_DATA_H + +#include "globalconst.h" +#include +#include "layer.h" +#include "crosshair.h" +#include "buffer.h" +#include "data_parent.h" +#include "obj_rat_list.h" +#include "obj_subc_list.h" +#include "obj_pstk_list.h" +#include +#include "vtpadstack.h" +#include + +/* Generic container object that can hold subcircuits with layer-global + objects (e.g. vias and rats) and layer-locals (lines, arcs) */ +struct pcb_data_s { + htip_t id2obj; /* long object ID -> (pcb_any_obj_t *) */ + int LayerN; /* number of layers in this board */ + + pcb_vtpadstack_proto_t ps_protos; + + padstacklist_t padstack; + pcb_subclist_t subc; +/**/ + rnd_rtree_t *padstack_tree, *subc_tree, *rat_tree; + pcb_layer_t Layer[PCB_MAX_LAYER]; /* layer TODO: make this dynamic */ + pcb_plug_io_t *loader; + ratlist_t Rat; + +/**/ + pcb_parenttype_t parent_type; + pcb_parent_t parent; + +/* poly clip inhibit */ + int clip_inhibit; /* counter: >0 means we are in inhibit mode */ +}; + +#define pcb_max_group(pcb) ((pcb)->LayerGroups.len) +#define pcb_max_layer(pcb) ((pcb)->Data->LayerN) + + + +extern pcb_buffer_t pcb_buffers[PCB_MAX_BUFFER]; +extern int pcb_added_lines; +extern int pcb_layer_stack[PCB_MAX_LAYER]; + +extern rnd_bool pcb_bumped; + +/****** callback based loops *****/ + +/* The functions returning int are called once when processing of a new layer + or element starts, with enter=1. If they return non-zero, the current layer + or element is skipped. If it is not skipped, the function is called once + at the end of processing the given layer or element, with enter=0 (and + return value ignored). + + Any of the callbacks for any loop function can be NULL. + */ + +/* layer object callbacks */ +typedef int (*pcb_layer_cb_t)(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, int enter); +typedef void (*pcb_line_cb_t)(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_line_t *line); +typedef void (*pcb_arc_cb_t)(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_arc_t *arc); +typedef void (*pcb_text_cb_t)(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_text_t *text); +typedef void (*pcb_poly_cb_t)(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_poly_t *poly); +typedef void (*pcb_gfx_cb_t)(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_gfx_t *gfx); + +/* subc callbacks */ +typedef int (*pcb_subc_cb_t)(void *ctx, pcb_board_t *pcb, pcb_subc_t *subc, int enter); + +/* via and padstack callbacks */ +typedef void (*pcb_pstk_cb_t)(void *ctx, pcb_board_t *pcb, pcb_pstk_t *ps); + +/* Loop over all layer objects on each layer. Layer is the outer loop. */ +void pcb_loop_layers(pcb_board_t *pcb, void *ctx, pcb_layer_cb_t lacb, pcb_line_cb_t lcb, pcb_arc_cb_t acb, pcb_text_cb_t tcb, pcb_poly_cb_t pocb, pcb_gfx_cb_t gcb); + +/* Loop over all subcircuits. */ +void pcb_loop_subc(pcb_board_t *pcb, void *ctx, pcb_subc_cb_t scb); + +/* Loop over all design objects. (So all the above three in one call.) */ +void pcb_loop_all(pcb_board_t *pcb, void *ctx, + pcb_layer_cb_t lacb, pcb_line_cb_t lcb, pcb_arc_cb_t acb, pcb_text_cb_t tcb, pcb_poly_cb_t pocb, pcb_gfx_cb_t gcb, + pcb_subc_cb_t scb, + pcb_pstk_cb_t pscb +); + +/* Initialize the fields of data */ +void pcb_data_init(pcb_data_t *data); + +/* Allocate new data and initialize all fields */ +pcb_data_t *pcb_data_new(pcb_board_t *parent); + +/* Uninitialize and free the fields of data (doesn't free data) */ +void pcb_data_uninit(pcb_data_t *data); + +/* Calls pcb_data_uninit() and free data */ +void pcb_data_free(pcb_data_t *data); + +rnd_bool pcb_data_is_empty(pcb_data_t *); + +/* gets minimum and maximum coordinates + * returns NULL if layout is empty */ +rnd_box_t *pcb_data_bbox(rnd_box_t *out, pcb_data_t *Data, rnd_bool ignore_floaters); +rnd_box_t *pcb_data_bbox_naked(rnd_box_t *out, pcb_data_t *Data, rnd_bool ignore_floaters); + +/* Make sure all layers of data has their .parent field pointing to the data */ +void pcb_data_set_layer_parents(pcb_data_t *data); + +/* Set up all data layers as bound layers to pcb's Data */ +void pcb_data_bind_board_layers(pcb_board_t *pcb, pcb_data_t *data, int share_rtrees); + +/* redo all layers of data to be bound layers (layer recipes) using the stackup + from pcb4layer_groups. The new bound layers are not bound to any real layer. */ +void pcb_data_make_layers_bound(pcb_board_t *pcb4layer_groups, pcb_data_t *data); + +/* Recalculate data's layer bindings in meta.bound.real to point to board layers */ +void pcb_data_binding_update(pcb_board_t *pcb, pcb_data_t *data); + +/* Break the binding in data bound layers (set htem all to NULL) */ +void pcb_data_unbind_layers(pcb_data_t *data); + +/* Make sure there are no negative coords in data, knowing the bbox of the data */ +int pcb_data_normalize_(pcb_data_t *data, rnd_box_t *data_bbox); + +/* Make sure there are no negative coords in data (calculates the bbox of the data) */ +int pcb_data_normalize(pcb_data_t *data); + +/* Returns the top level pcb related to a data, or NULL if the data is floating + (e.g. is a global buffer) */ +pcb_board_t *pcb_data_get_top(pcb_data_t *data); + +/* Force-set the parent.data field of each global object in data (but not + the layers!) */ +void pcb_data_set_parent_globals(pcb_data_t *data, pcb_data_t *new_parent); + +typedef enum pcb_data_mirror_text_e { + /* main operation - choose one: */ + PCB_TXM_NONE = 0, /* do not mirror text */ + PCB_TXM_SIDE, /* mirror text, changing side */ + PCB_TXM_COORD, /* mirror text base coords only */ + + /* modifier bits, can be OR'd: */ + PCB_TXM_ROT = 32, /* mirror text rotation angle */ + + /* msic */ + PCB_TXM_MASK_OP = PCB_TXM_ROT-1 +} pcb_data_mirror_text_t; + + + + +void pcb_data_mirror(pcb_data_t *data, rnd_coord_t y_offs, pcb_data_mirror_text_t mtxt, rnd_bool pstk_smirror, rnd_bool undoable); + +void pcb_data_move(pcb_data_t *data, rnd_coord_t dx, rnd_coord_t dy, int undoable); + +/* Multiply x and y coords by sx and sy and thickness by sth (where applicable). + If recurse is non-zero, also modify subcircuits */ +void pcb_data_scale(pcb_data_t *data, double sx, double sy, double sth, int recurse); + +/* run pcb_poly_init_clip() on all polygons in data */ +void pcb_data_clip_polys(pcb_data_t *data); + + +/* rsearch on all trees matching types of data */ +rnd_r_dir_t pcb_data_r_search(pcb_data_t *data, pcb_objtype_t types, const rnd_box_t *starting_region, + rnd_r_dir_t (*region_in_search) (const rnd_box_t *region, void *cl), + rnd_r_dir_t (*rectangle_in_region) (const rnd_box_t *box, void *cl), + void *closure, int *num_found, rnd_bool vis_only); + +/* Either pcb->data or the subcircuit's data if PCB is a subc (footprint edit mode) */ +#define PCB_REAL_DATA(pcb) \ + ((pcb)->is_footprint ? (pcb_subclist_first(&(pcb)->Data->subc)->data) : ((pcb)->Data)) + + +/*** Polygon clipping inhibit ***/ + +/* increase the inhibit counter (stop clipping polygons) */ +void pcb_data_clip_inhibit_inc(pcb_data_t *data); + +/* decrease the inhibit counter - if it's zero, reclip all dirty polygons; + enable_progbar controls whether a progress bar is drawn for reclips + that take longer than a few seconds. */ +void pcb_data_clip_inhibit_dec(pcb_data_t *data, rnd_bool enable_progbar); + +/* attempt to reclip all dirty polygons; normally called by + pcb_data_clip_inhibit_dec(). */ +void pcb_data_clip_dirty(pcb_data_t *data, rnd_bool enable_progbar); + +/* Force reclip all polygons; useful after a move-everything kind + of operation (e.g. autocrop()) */ +void pcb_data_clip_all(pcb_data_t *data, rnd_bool enable_progbar); + + +/* Recursively change flags of data; how is one of pcb_change_flag_t */ +void pcb_data_flag_change(pcb_data_t *data, pcb_objtype_t mask, int how, unsigned long flags); + +/* Clear specific static flag from all objects, optionally with matching + object types only. If redraw is not 0, issue an object redraw on change. + If undoable is not 0, add flag changes to the undo list. Returns number + of object changed. */ +unsigned long pcb_data_clear_obj_flag(pcb_data_t *data, pcb_objtype_t tmask, unsigned long flag, int redraw, int undoable); +unsigned long pcb_data_clear_flag(pcb_data_t *data, unsigned long flag, int redraw, int undoable); + +/* Clear the given dyflag bit from all objects under data */ +void pcb_data_dynflag_clear(pcb_data_t *data, pcb_dynf_t dynf); + +/* Convert name to data, return NULL if not found */ +pcb_data_t *pcb_data_by_name(pcb_board_t *pcb, const char **name); + + +/* Convert name to data address, return 0 if not found; 1 is pcb's data, + 2+ are buffer+2 */ +int pcb_data_addr_by_name(pcb_board_t *pcb, const char **name); + +/* Render data name in buf, which must be at least 16 bytes long. Returns buf. */ +char *pcb_data_name_by_addr(int addr, char *buf); + + +/* Convert data to name; either returns a static srting or fills in + buf with dynamic data and returns buf. Buf needs to be at least 16 + bytes long. Returns NULL if data is not the pcb or a buffer. */ +const char *pcb_data_to_name(pcb_board_t *pcb, pcb_data_t *data, char *buf, int buf_len); + +#endif Index: tags/2.3.0/src/data_it.h =================================================================== --- tags/2.3.0/src/data_it.h (nonexistent) +++ tags/2.3.0/src/data_it.h (revision 33253) @@ -0,0 +1,145 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Flat, non-recursive iterator on pcb_data_t children objects */ + +#ifndef PCB_DATA_IT_H +#define PCB_DATA_IT_H + +#include "obj_common.h" +#include "data.h" + +typedef struct pcb_data_it_s { + /* config */ + pcb_data_t *data; + pcb_objtype_t mask; /* caller wants to see these types */ + + /* current state */ + pcb_objtype_t remaining; + pcb_objtype_t type; + rnd_cardinal_t ln; + pcb_any_obj_t *last; +} pcb_data_it_t; + +#define PCB_DATA_IT_TYPES \ + (PCB_OBJ_LINE | PCB_OBJ_TEXT | PCB_OBJ_POLY | PCB_OBJ_ARC | PCB_OBJ_GFX | \ + PCB_OBJ_PSTK | PCB_OBJ_SUBC | PCB_OBJ_RAT) + +/* Start an iteration on data, looking for any object type listed in mask; + returns NULL if nothing is found. The iteration is non-recursive to subcircuits */ +RND_INLINE pcb_any_obj_t *pcb_data_first(pcb_data_it_t *it, pcb_data_t *data, pcb_objtype_t mask); + +/* Return the next object or NULL on end of iteration */ +RND_INLINE pcb_any_obj_t *pcb_data_next(pcb_data_it_t *it); + +/**** implementation (inlines) ****/ + +/* Skip to the next type; returns 0 on success, non-0 at the end of types */ +RND_INLINE int pcb_data_it_next_type(pcb_data_it_t *it) +{ + if (it->remaining == 0) + return 1; + + if (it->type == 0) + it->type = 1; + else + it->type <<= 1; + + /* find and remove the next bit */ + while((it->remaining & it->type) == 0) it->type <<= 1; + it->remaining &= ~it->type; + + return 0; +} + +/* Take the next layer object, skip layer if there's no more */ +#define PCB_DATA_IT_LOBJ(it, otype, ltype, list) \ + do { \ + if (it->last == NULL) \ + it->last = (pcb_any_obj_t *)ltype ## _first(&(it->data->Layer[it->ln].list)); \ + else \ + it->last = (pcb_any_obj_t *)ltype ## _next((otype *)it->last); \ + if (it->last == NULL) \ + goto next_layer; \ + } while(0) + +/* Take the next global object, skip type if there's no more */ +#define PCB_DATA_IT_GOBJ(it, otype, ltype, list) \ + do { \ + if (it->last == NULL) \ + it->last = (pcb_any_obj_t *)ltype ## _first(&(it->data->list)); \ + else \ + it->last = (pcb_any_obj_t *)ltype ## _next((otype *)it->last); \ + if (it->last == NULL) \ + goto next_type; \ + } while(0) + + +RND_INLINE pcb_any_obj_t *pcb_data_next(pcb_data_it_t *it) +{ + retry:; + + switch(it->type) { + case PCB_OBJ_LINE: PCB_DATA_IT_LOBJ(it, pcb_line_t, linelist, Line); break; + case PCB_OBJ_TEXT: PCB_DATA_IT_LOBJ(it, pcb_text_t, textlist, Text); break; + case PCB_OBJ_POLY: PCB_DATA_IT_LOBJ(it, pcb_poly_t, polylist, Polygon); break; + case PCB_OBJ_ARC: PCB_DATA_IT_LOBJ(it, pcb_arc_t, arclist, Arc); break; + case PCB_OBJ_PSTK: PCB_DATA_IT_GOBJ(it, pcb_pstk_t, padstacklist, padstack); break; + case PCB_OBJ_SUBC: PCB_DATA_IT_GOBJ(it, pcb_subc_t, pcb_subclist, subc); break; + case PCB_OBJ_RAT: PCB_DATA_IT_GOBJ(it, pcb_rat_t, ratlist, Rat); break; + case PCB_OBJ_GFX: PCB_DATA_IT_LOBJ(it, pcb_gfx_t, gfxlist, Gfx); break; + default: + assert(!"iterating on invalid type"); + return NULL; + } + return it->last; + + /* skip to the next layer and retry unless ran out of types */ + next_layer:; + it->ln++; + if (it->ln >= it->data->LayerN) { /* checked all layers for this type, skip to next type */ + it->ln = 0; + next_type:; + if (pcb_data_it_next_type(it)) + return NULL; + } + + goto retry; /* ... on the new layer */ +} + +RND_INLINE pcb_any_obj_t *pcb_data_first(pcb_data_it_t *it, pcb_data_t *data, pcb_objtype_t mask) +{ + it->data = data; + it->mask = it->remaining = mask & PCB_DATA_IT_TYPES; + it->type = 0; + it->ln = 0; + it->last = NULL; + if (pcb_data_it_next_type(it)) + return NULL; + return pcb_data_next(it); +} + +#endif Index: tags/2.3.0/src/data_list.h =================================================================== --- tags/2.3.0/src/data_list.h (nonexistent) +++ tags/2.3.0/src/data_list.h (revision 33253) @@ -0,0 +1,41 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_DATA_LIST_H +#define PCB_DATA_LIST_H + +#include +#include "data.h" + +/* append objects of type, with flags matching mask to dst; pointer are + valid only until the first change to data; if flags is 0, everything matches. */ +void pcb_data_list_by_flag(pcb_data_t *data, vtp0_t *dst, pcb_objtype_t type, unsigned long mask); + +/* append objects of type that are terminals; pointer are + valid only until the first change to data */ +void pcb_data_list_terms(pcb_data_t *data, vtp0_t *dst, pcb_objtype_t type); + +#endif Index: tags/2.3.0/src/data_parent.h =================================================================== --- tags/2.3.0/src/data_parent.h (nonexistent) +++ tags/2.3.0/src/data_parent.h (revision 33253) @@ -0,0 +1,72 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016..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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_DATA_PARENT_H +#define PCB_DATA_PARENT_H + +#include + +/* which elem of the parent union is active */ +typedef enum pcb_parenttype_e { + PCB_PARENT_INVALID = 0, /* invalid or unknown */ + PCB_PARENT_LAYER, /* object is on a layer */ + PCB_PARENT_SUBC, /* object is part of a subcircuit */ + PCB_PARENT_DATA, /* global objects like via */ + PCB_PARENT_BOARD, /* directly under a board (typical for pcb_data_t of a board) */ + PCB_PARENT_NET, /* pcb_net_term_t's parent is a pcb_net_t */ + PCB_PARENT_UI /* parent of UI layers */ +} pcb_parenttype_t; + +/* class is e.g. PCB_OBJ_CLASS_OBJ */ +#define PCB_OBJ_IS_CLASS(type, class) (((type) & PCB_OBJ_CLASS_MASK) == (class)) + +union pcb_parent_s { + void *any; + pcb_layer_t *layer; + pcb_data_t *data; + pcb_subc_t *subc; + pcb_board_t *board; + pcb_net_t *net; +}; + +#define PCB_PARENT_TYPENAME_layer PCB_PARENT_LAYER +#define PCB_PARENT_TYPENAME_data PCB_PARENT_DATA +#define PCB_PARENT_TYPENAME_subc PCB_PARENT_SUBC +#define PCB_PARENT_TYPENAME_board PCB_PARENT_BOARD + +#define PCB_SET_PARENT(obj, ptype, parent_ptr) \ + do { \ + (obj)->parent_type = PCB_PARENT_TYPENAME_ ## ptype; \ + (obj)->parent.ptype = parent_ptr; \ + } while(0) + +#define PCB_CLEAR_PARENT(obj) \ + do { \ + (obj)->parent_type = PCB_PARENT_INVALID; \ + (obj)->parent.any = NULL; \ + } while(0) + +#endif Index: tags/2.3.0/src/default2.lht =================================================================== --- tags/2.3.0/src/default2.lht (nonexistent) +++ tags/2.3.0/src/default2.lht (revision 33253) @@ -0,0 +1,156 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v7 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 127.0mm; y = 127.0mm + isle_area_nm2 = 200000000.0 + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; ha:attributes { {pcb-rnd::key::select}={l; t}; {pcb-rnd::key::vis}={l; Shiftt} }} + ha:bottom-sig { lid=1; group=6; ha:attributes { {pcb-rnd::key::select}={l; b}; {pcb-rnd::key::vis}={l; Shiftb} }} + ha:top-gnd { lid=2; group=3; } + ha:bottom-gnd { lid=3; group=6; } + ha:top-vcc { lid=4; group=3; } + ha:bottom-vcc { lid=5; group=6; } + ha:outline { lid=6; group=5; } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; }; ha:attributes { {pcb-rnd::key::select}={l; x}; {pcb-rnd::key::vis}={l; Shiftx} } } + ha:top-silk { lid=8; group=1; ha:combining { auto=1; }; ha:attributes { {pcb-rnd::key::select}={l; s}; {pcb-rnd::key::vis}={l; Shifts} } } + ha:top-paste { lid=9; group=0; ha:combining { auto=1; } } + ha:top-mask { lid=10; group=2; ha:combining { sub=1; auto=1; } } + ha:bottom-mask { lid=11; group=7; ha:combining { sub=1; auto=1; } } + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } } + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } } + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } } + ha:top-assy { lid=15; group=12; color={#444444}; } + ha:bot-assy { lid=16; group=13; color={#444444}; } + ha:fab { lid=17; group=14; ha:combining { auto=1; }; color={#222222}; } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + ha:attributes { thickness=1.6mm } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + ha:12 { + name = top_assy + ha:type { top=1; doc=1; } + purpose = assy + ha:attributes { init-invis=1; } + li:layers { 15; } + } + ha:13 { + name = bot_assy + ha:type { bottom=1; doc=1; } + purpose = assy + ha:attributes { init-invis=1; } + li:layers { 16; } + } + ha:14 { + name = fab + ha:type { top=1; doc=1; } + purpose = fab + ha:attributes { init-invis=1; } + li:layers { 17; } + } + } + } +} Index: tags/2.3.0/src/default4.lht =================================================================== --- tags/2.3.0/src/default4.lht (nonexistent) +++ tags/2.3.0/src/default4.lht (revision 33253) @@ -0,0 +1,178 @@ +# pcb-rnd official 4-layer default board + +ha:pcb-rnd-board-v7 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 127.0mm; y = 127.0mm + isle_area_nm2 = 200000000.0 + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; ha:attributes { {pcb-rnd::key::select}={l; t}; {pcb-rnd::key::vis}={l; Shiftt} }} + ha:bottom-sig { lid=1; group=10; ha:attributes { {pcb-rnd::key::select}={l; b}; {pcb-rnd::key::vis}={l; Shiftb} }} + ha:top-gnd { lid=2; group=3; } + ha:bottom-gnd { lid=3; group=10; } + ha:int-sig2 { lid=4; group=7; ha:attributes { {pcb-rnd::key::select}={l; i}; {pcb-rnd::key::vis}={l; Shifti} }} + ha:int-sig1 { lid=5; group=5; ha:attributes { {pcb-rnd::key::select}={l; o}; {pcb-rnd::key::vis}={l; Shifto} }} + ha:outline { lid=6; group=9; } + ha:bottom-silk { lid=7; group=12; ha:combining { auto=1; }; ha:attributes { {pcb-rnd::key::select}={l; x}; {pcb-rnd::key::vis}={l; Shiftx} } } + ha:top-silk { lid=8; group=1; ha:combining { auto=1; }; ha:attributes { {pcb-rnd::key::select}={l; s}; {pcb-rnd::key::vis}={l; Shifts} } } + ha:top-paste { lid=9; group=0; ha:combining { auto=1; } } + ha:top-mask { lid=10; group=2; ha:combining { sub=1; auto=1; } } + ha:bottom-mask { lid=11; group=11; ha:combining { sub=1; auto=1; } } + ha:bottom-paste { lid=12; group=13; ha:combining { auto=1; } } + ha:slot-plated { lid=13; group=14; ha:combining { auto=1; } } + ha:slot-unplated { lid=14; group=15; ha:combining { auto=1; } } + ha:top-assy { lid=15; group=16; color={#444444}; } + ha:bot-assy { lid=16; group=17; color={#444444}; } + ha:fab { lid=17; group=18; ha:combining { auto=1; }; color={#222222}; } + } + } + + 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 { + ha:type { substrate=1; intern=1; } + ha:attributes { thickness=0.7375mm } + li:layers { } + name = grp_4 + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 5; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + ha:attributes { thickness=0.125mm } + li:layers { } + name = grp_6 + } + ha:7 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 4; } + } + ha:8 { + ha:type { substrate=1; intern=1; } + ha:attributes { thickness=0.7375mm } + li:layers { } + name = grp_8 + } + ha:9 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + 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; } + purpose = proute + li:layers { 13; } + } + ha:15 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + ha:16 { + name = top_assy + ha:type { top=1; doc=1; } + purpose = assy + ha:attributes { init-invis=1; } + li:layers { 15; } + } + ha:17 { + name = bot_assy + ha:type { bottom=1; doc=1; } + purpose = assy + ha:attributes { init-invis=1; } + li:layers { 16; } + } + ha:18 { + name = fab + ha:type { top=1; doc=1; } + purpose = fab + ha:attributes { init-invis=1; } + li:layers { 17; } + } + } + } +} Index: tags/2.3.0/src/default_font =================================================================== --- tags/2.3.0/src/default_font (nonexistent) +++ tags/2.3.0/src/default_font (revision 33253) @@ -0,0 +1,773 @@ +Symbol(' ' 18) +( +) +Symbol('!' 12) +( + SymbolLine(0 35 0 40 8) + SymbolLine(0 0 0 25 8) +) +Symbol('"' 12) +( + SymbolLine(0 0 0 10 8) + SymbolLine(10 0 10 10 8) +) +Symbol('#' 12) +( + SymbolLine(0 25 20 25 8) + SymbolLine(0 15 20 15 8) + SymbolLine(15 10 15 30 8) + SymbolLine(5 10 5 30 8) +) +Symbol('$' 12) +( + SymbolLine(15 5 20 10 8) + SymbolLine(5 5 15 5 8) + SymbolLine(0 10 5 5 8) + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 5 20 8) + SymbolLine(5 20 15 20 8) + SymbolLine(15 20 20 25 8) + SymbolLine(20 25 20 30 8) + SymbolLine(15 35 20 30 8) + SymbolLine(5 35 15 35 8) + SymbolLine(0 30 5 35 8) + SymbolLine(10 0 10 40 8) +) +Symbol('%' 12) +( + SymbolLine(0 5 0 10 8) + SymbolLine(0 5 5 0 8) + SymbolLine(5 0 10 0 8) + SymbolLine(10 0 15 5 8) + SymbolLine(15 5 15 10 8) + SymbolLine(10 15 15 10 8) + SymbolLine(5 15 10 15 8) + SymbolLine(0 10 5 15 8) + SymbolLine(0 40 40 0 8) + SymbolLine(35 40 40 35 8) + SymbolLine(40 30 40 35 8) + SymbolLine(35 25 40 30 8) + SymbolLine(30 25 35 25 8) + SymbolLine(25 30 30 25 8) + SymbolLine(25 30 25 35 8) + SymbolLine(25 35 30 40 8) + SymbolLine(30 40 35 40 8) +) +Symbol('&' 12) +( + SymbolLine(0 35 5 40 8) + SymbolLine(0 5 0 15 8) + SymbolLine(0 5 5 0 8) + SymbolLine(0 25 15 10 8) + SymbolLine(5 40 10 40 8) + SymbolLine(10 40 20 30 8) + SymbolLine(0 15 25 40 8) + SymbolLine(5 0 10 0 8) + SymbolLine(10 0 15 5 8) + SymbolLine(15 5 15 10 8) + SymbolLine(0 25 0 35 8) +) +Symbol(''' 12) +( + SymbolLine(0 10 10 0 8) +) +Symbol('(' 12) +( + SymbolLine(0 35 5 40 8) + SymbolLine(0 5 5 0 8) + SymbolLine(0 5 0 35 8) +) +Symbol(')' 12) +( + SymbolLine(0 0 5 5 8) + SymbolLine(5 5 5 35 8) + SymbolLine(0 40 5 35 8) +) +Symbol('*' 12) +( + SymbolLine(0 10 20 30 8) + SymbolLine(0 30 20 10 8) + SymbolLine(0 20 20 20 8) + SymbolLine(10 10 10 30 8) +) +Symbol('+' 12) +( + SymbolLine(0 20 20 20 8) + SymbolLine(10 10 10 30 8) +) +Symbol(',' 12) +( + SymbolLine(0 50 10 40 8) +) +Symbol('-' 12) +( + SymbolLine(0 20 20 20 8) +) +Symbol('.' 12) +( + SymbolLine(0 40 5 40 8) +) +Symbol('/' 12) +( + SymbolLine(0 35 30 5 8) +) +Symbol('0' 12) +( + SymbolLine(0 35 5 40 8) + SymbolLine(0 5 0 35 8) + SymbolLine(0 5 5 0 8) + SymbolLine(5 0 15 0 8) + SymbolLine(15 0 20 5 8) + SymbolLine(20 5 20 35 8) + SymbolLine(15 40 20 35 8) + SymbolLine(5 40 15 40 8) + SymbolLine(0 30 20 10 8) +) +Symbol('1' 12) +( + SymbolLine( 0 8 8 0 8) + SymbolLine( 8 0 8 40 8) + SymbolLine( 0 40 15 40 8) +) +Symbol('2' 12) +( + SymbolLine(0 5 5 0 8) + SymbolLine(5 0 20 0 8) + SymbolLine(20 0 25 5 8) + SymbolLine(25 5 25 15 8) + SymbolLine(0 40 25 15 8) + SymbolLine(0 40 25 40 8) +) +Symbol('3' 12) +( + SymbolLine( 0 5 5 0 8) + SymbolLine( 5 0 15 0 8) + SymbolLine(15 0 20 5 8) + SymbolLine(15 40 20 35 8) + SymbolLine( 5 40 15 40 8) + SymbolLine( 0 35 5 40 8) + + SymbolLine( 5 18 15 18 8) + SymbolLine(20 5 20 13 8) + SymbolLine(20 23 20 35 8) + SymbolLine(20 23 15 18 8) + SymbolLine(20 13 15 18 8) +) +Symbol('4' 12) +( + SymbolLine(0 25 20 0 8) + SymbolLine(0 25 25 25 8) + SymbolLine(20 0 20 40 8) +) +Symbol('5' 12) +( + SymbolLine(0 0 20 0 8) + SymbolLine(0 0 0 20 8) + SymbolLine(0 20 5 15 8) + SymbolLine(5 15 15 15 8) + SymbolLine(15 15 20 20 8) + SymbolLine(20 20 20 35 8) + SymbolLine(15 40 20 35 8) + SymbolLine(5 40 15 40 8) + SymbolLine(0 35 5 40 8) +) +Symbol('6' 12) +( + SymbolLine(15 0 20 5 8) + SymbolLine( 5 0 15 0 8) + SymbolLine( 0 5 5 0 8) + SymbolLine( 0 5 0 35 8) + SymbolLine( 0 35 5 40 8) + SymbolLine(15 18 20 23 8) + SymbolLine( 0 18 15 18 8) + SymbolLine( 5 40 15 40 8) + SymbolLine(15 40 20 35 8) + SymbolLine(20 23 20 35 8) +) +Symbol('7' 12) +( + SymbolLine( 5 40 25 0 8) + SymbolLine( 0 0 25 0 8) +) +Symbol('8' 12) +( + SymbolLine( 0 35 5 40 8) + SymbolLine( 0 27 0 35 8) + SymbolLine( 0 27 7 20 8) + SymbolLine( 7 20 13 20 8) + SymbolLine(13 20 20 27 8) + SymbolLine(20 27 20 35 8) + SymbolLine(15 40 20 35 8) + SymbolLine( 5 40 15 40 8) + SymbolLine( 0 13 7 20 8) + SymbolLine( 0 5 0 13 8) + SymbolLine( 0 5 5 0 8) + SymbolLine( 5 0 15 0 8) + SymbolLine(15 0 20 5 8) + SymbolLine(20 5 20 13 8) + SymbolLine(13 20 20 13 8) +) +Symbol('9' 12) +( + SymbolLine(5 40 20 20 8) + SymbolLine(20 5 20 20 8) + SymbolLine(15 0 20 5 8) + SymbolLine(5 0 15 0 8) + SymbolLine(0 5 5 0 8) + SymbolLine(0 5 0 15 8) + SymbolLine(0 15 5 20 8) + SymbolLine(5 20 20 20 8) +) +Symbol(':' 12) +( + SymbolLine(0 15 5 15 8) + SymbolLine(0 25 5 25 8) +) +Symbol(';' 12) +( + SymbolLine(0 40 10 30 8) + SymbolLine(10 15 10 20 8) +) +Symbol('<' 12) +( + SymbolLine(0 20 10 10 8) + SymbolLine(0 20 10 30 8) +) +Symbol('=' 12) +( + SymbolLine(0 15 20 15 8) + SymbolLine(0 25 20 25 8) +) +Symbol('>' 12) +( + SymbolLine(0 10 10 20 8) + SymbolLine(0 30 10 20 8) +) +Symbol('?' 12) +( + SymbolLine(10 20 10 25 8) + SymbolLine(10 35 10 40 8) + SymbolLine(0 5 0 10 8) + SymbolLine(0 5 5 0 8) + SymbolLine(5 0 15 0 8) + SymbolLine(15 0 20 5 8) + SymbolLine(20 5 20 10 8) + SymbolLine(10 20 20 10 8) +) +Symbol('A' 12) +( + SymbolLine( 0 10 0 40 8) + SymbolLine( 0 10 7 0 8) + SymbolLine( 7 0 18 0 8) + SymbolLine(18 0 25 10 8) + SymbolLine(25 10 25 40 8) + SymbolLine( 0 20 25 20 8) +) +Symbol('B' 12) +( + SymbolLine( 0 40 20 40 8) + SymbolLine(20 40 25 35 8) + SymbolLine(25 23 25 35 8) + SymbolLine(20 18 25 23 8) + SymbolLine( 5 18 20 18 8) + SymbolLine( 5 0 5 40 8) + SymbolLine( 0 0 20 0 8) + SymbolLine(20 0 25 5 8) + SymbolLine(25 5 25 13 8) + SymbolLine(20 18 25 13 8) +) +Symbol('C' 12) +( + SymbolLine(7 40 20 40 8) + SymbolLine(0 33 7 40 8) + SymbolLine(0 7 0 33 8) + SymbolLine(0 7 7 0 8) + SymbolLine(7 0 20 0 8) +) +Symbol('D' 12) +( + SymbolLine( 5 0 5 40 8) + SymbolLine(18 0 25 7 8) + SymbolLine(25 7 25 33 8) + SymbolLine(18 40 25 33 8) + SymbolLine( 0 40 18 40 8) + SymbolLine( 0 0 18 0 8) +) +Symbol('E' 12) +( + SymbolLine(0 18 15 18 8) + SymbolLine(0 40 20 40 8) + SymbolLine(0 0 0 40 8) + SymbolLine(0 0 20 0 8) +) +Symbol('F' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 0 20 0 8) + SymbolLine(0 18 15 18 8) +) +Symbol('G' 12) +( + SymbolLine(20 0 25 5 8) + SymbolLine(5 0 20 0 8) + SymbolLine(0 5 5 0 8) + SymbolLine(0 5 0 35 8) + SymbolLine(0 35 5 40 8) + SymbolLine(5 40 20 40 8) + SymbolLine(20 40 25 35 8) + SymbolLine(25 25 25 35 8) + SymbolLine(20 20 25 25 8) + SymbolLine(10 20 20 20 8) +) +Symbol('H' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(25 0 25 40 8) + SymbolLine(0 20 25 20 8) +) +Symbol('I' 12) +( + SymbolLine(0 0 10 0 8) + SymbolLine(5 0 5 40 8) + SymbolLine(0 40 10 40 8) +) +Symbol('J' 12) +( + SymbolLine( 7 0 15 0 8) + SymbolLine(15 0 15 35 8) + SymbolLine(10 40 15 35 8) + SymbolLine( 5 40 10 40 8) + SymbolLine( 0 35 5 40 8) + SymbolLine( 0 35 0 30 8) +) +Symbol('K' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 20 20 0 8) + SymbolLine(0 20 20 40 8) +) +Symbol('L' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 40 20 40 8) +) +Symbol('M' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 0 15 20 8) + SymbolLine(15 20 30 0 8) + SymbolLine(30 0 30 40 8) +) +Symbol('N' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 0 25 40 8) + SymbolLine(25 0 25 40 8) +) +Symbol('O' 12) +( + SymbolLine(0 5 0 35 8) + SymbolLine(0 5 5 0 8) + SymbolLine(5 0 15 0 8) + SymbolLine(15 0 20 5 8) + SymbolLine(20 5 20 35 8) + SymbolLine(15 40 20 35 8) + SymbolLine(5 40 15 40 8) + SymbolLine(0 35 5 40 8) +) +Symbol('P' 12) +( + SymbolLine(5 0 5 40 8) + SymbolLine(0 0 20 0 8) + SymbolLine(20 0 25 5 8) + SymbolLine(25 5 25 15 8) + SymbolLine(20 20 25 15 8) + SymbolLine(5 20 20 20 8) +) +Symbol('Q' 12) +( + SymbolLine( 0 5 0 35 8) + SymbolLine( 0 5 5 0 8) + SymbolLine( 5 0 15 0 8) + SymbolLine(15 0 20 5 8) + SymbolLine(20 5 20 30 8) + SymbolLine(10 40 20 30 8) + SymbolLine( 5 40 10 40 8) + SymbolLine( 0 35 5 40 8) + SymbolLine(10 25 20 40 8) +) +Symbol('R' 12) +( + SymbolLine( 0 0 20 0 8) + SymbolLine(20 0 25 5 8) + SymbolLine(25 5 25 15 8) + SymbolLine(20 20 25 15 8) + SymbolLine( 5 20 20 20 8) + SymbolLine( 5 0 5 40 8) + SymbolLine(13 20 25 40 8) +) +Symbol('S' 12) +( + SymbolLine(20 0 25 5 8) + SymbolLine(5 0 20 0 8) + SymbolLine(0 5 5 0 8) + SymbolLine(0 5 0 15 8) + SymbolLine(0 15 5 20 8) + SymbolLine(5 20 20 20 8) + SymbolLine(20 20 25 25 8) + SymbolLine(25 25 25 35 8) + SymbolLine(20 40 25 35 8) + SymbolLine(5 40 20 40 8) + SymbolLine(0 35 5 40 8) +) +Symbol('T' 12) +( + SymbolLine(0 0 20 0 8) + SymbolLine(10 0 10 40 8) +) +Symbol('U' 12) +( + SymbolLine(0 0 0 35 8) + SymbolLine(0 35 5 40 8) + SymbolLine(5 40 15 40 8) + SymbolLine(15 40 20 35 8) + SymbolLine(20 0 20 35 8) +) +Symbol('V' 12) +( + SymbolLine( 0 0 10 40 8) + SymbolLine(10 40 20 0 8) +) +Symbol('W' 12) +( + SymbolLine( 0 0 0 20 8) + SymbolLine( 0 20 5 40 8) + SymbolLine( 5 40 15 20 8) + SymbolLine(15 20 25 40 8) + SymbolLine(25 40 30 20 8) + SymbolLine(30 20 30 0 8) +) +Symbol('X' 12) +( + SymbolLine( 0 40 25 0 8) + SymbolLine( 0 0 25 40 8) +) +Symbol('Y' 12) +( + SymbolLine( 0 0 10 20 8) + SymbolLine(10 20 20 0 8) + SymbolLine(10 20 10 40 8) +) +Symbol('Z' 12) +( + SymbolLine( 0 0 25 0 8) + SymbolLine( 0 40 25 0 8) + SymbolLine( 0 40 25 40 8) +) +Symbol('[' 12) +( + SymbolLine(0 0 5 0 8) + SymbolLine(0 0 0 40 8) + SymbolLine(0 40 5 40 8) +) +Symbol('\' 12) +( + SymbolLine(0 5 30 35 8) +) +Symbol(']' 12) +( + SymbolLine(0 0 5 0 8) + SymbolLine(5 0 5 40 8) + SymbolLine(0 40 5 40 8) +) +Symbol('^' 12) +( + SymbolLine(0 5 5 0 8) + SymbolLine(5 0 10 5 8) +) +Symbol('_' 12) +( + SymbolLine(0 40 20 40 8) +) +Symbol('a' 12) +( + SymbolLine(15 20 20 25 8) + SymbolLine(5 20 15 20 8) + SymbolLine(0 25 5 20 8) + SymbolLine(0 25 0 35 8) + SymbolLine(0 35 5 40 8) + SymbolLine(20 20 20 35 8) + SymbolLine(20 35 25 40 8) + SymbolLine(5 40 15 40 8) + SymbolLine(15 40 20 35 8) +) +Symbol('b' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 35 5 40 8) + SymbolLine(5 40 15 40 8) + SymbolLine(15 40 20 35 8) + SymbolLine(20 25 20 35 8) + SymbolLine(15 20 20 25 8) + SymbolLine(5 20 15 20 8) + SymbolLine(0 25 5 20 8) +) +Symbol('c' 12) +( + SymbolLine(5 20 20 20 8) + SymbolLine(0 25 5 20 8) + SymbolLine(0 25 0 35 8) + SymbolLine(0 35 5 40 8) + SymbolLine(5 40 20 40 8) +) +Symbol('d' 12) +( + SymbolLine(20 0 20 40 8) + SymbolLine(15 40 20 35 8) + SymbolLine(5 40 15 40 8) + SymbolLine(0 35 5 40 8) + SymbolLine(0 25 0 35 8) + SymbolLine(0 25 5 20 8) + SymbolLine(5 20 15 20 8) + SymbolLine(15 20 20 25 8) +) +Symbol('e' 12) +( + SymbolLine(5 40 20 40 8) + SymbolLine(0 35 5 40 8) + SymbolLine(0 25 0 35 8) + SymbolLine(0 25 5 20 8) + SymbolLine(5 20 15 20 8) + SymbolLine(15 20 20 25 8) + SymbolLine(0 30 20 30 8) + SymbolLine(20 30 20 25 8) +) +Symbol('f' 10) +( + SymbolLine(5 5 5 40 8) + SymbolLine(5 5 10 0 8) + SymbolLine(10 0 15 0 8) + SymbolLine(0 20 10 20 8) +) +Symbol('g' 12) +( + SymbolLine(15 20 20 25 8) + SymbolLine(5 20 15 20 8) + SymbolLine(0 25 5 20 8) + SymbolLine(0 25 0 35 8) + SymbolLine(0 35 5 40 8) + SymbolLine(5 40 15 40 8) + SymbolLine(15 40 20 35 8) + SymbolLine(0 50 5 55 8) + SymbolLine(5 55 15 55 8) + SymbolLine(15 55 20 50 8) + SymbolLine(20 20 20 50 8) +) +Symbol('h' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 25 5 20 8) + SymbolLine(5 20 15 20 8) + SymbolLine(15 20 20 25 8) + SymbolLine(20 25 20 40 8) +) +Symbol('i' 10) +( + SymbolLine(0 10 0 11 10) + SymbolLine(0 25 0 40 8) +) +Symbol('j' 10) +( + SymbolLine(5 10 5 11 10) + SymbolLine(5 25 5 50 8) + SymbolLine(0 55 5 50 8) +) +Symbol('k' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 25 15 40 8) + SymbolLine(0 25 10 15 8) +) +Symbol('l' 10) +( + SymbolLine(0 0 0 35 8) + SymbolLine(0 35 5 40 8) +) +Symbol('m' 12) +( + SymbolLine(5 25 5 40 8) + SymbolLine(5 25 10 20 8) + SymbolLine(10 20 15 20 8) + SymbolLine(15 20 20 25 8) + SymbolLine(20 25 20 40 8) + SymbolLine(20 25 25 20 8) + SymbolLine(25 20 30 20 8) + SymbolLine(30 20 35 25 8) + SymbolLine(35 25 35 40 8) + SymbolLine(0 20 5 25 8) +) +Symbol('n' 12) +( + SymbolLine(5 25 5 40 8) + SymbolLine(5 25 10 20 8) + SymbolLine(10 20 15 20 8) + SymbolLine(15 20 20 25 8) + SymbolLine(20 25 20 40 8) + SymbolLine(0 20 5 25 8) +) +Symbol('o' 12) +( + SymbolLine(0 25 0 35 8) + SymbolLine(0 25 5 20 8) + SymbolLine(5 20 15 20 8) + SymbolLine(15 20 20 25 8) + SymbolLine(20 25 20 35 8) + SymbolLine(15 40 20 35 8) + SymbolLine(5 40 15 40 8) + SymbolLine(0 35 5 40 8) +) +Symbol('p' 12) +( + SymbolLine(5 25 5 55 8) + SymbolLine(0 20 5 25 8) + SymbolLine(5 25 10 20 8) + SymbolLine(10 20 20 20 8) + SymbolLine(20 20 25 25 8) + SymbolLine(25 25 25 35 8) + SymbolLine(20 40 25 35 8) + SymbolLine(10 40 20 40 8) + SymbolLine(5 35 10 40 8) +) +Symbol('q' 12) +( + SymbolLine(20 25 20 55 8) + SymbolLine(15 20 20 25 8) + SymbolLine(5 20 15 20 8) + SymbolLine(0 25 5 20 8) + SymbolLine(0 25 0 35 8) + SymbolLine(0 35 5 40 8) + SymbolLine(5 40 15 40 8) + SymbolLine(15 40 20 35 8) +) +Symbol('r' 12) +( + SymbolLine(5 25 5 40 8) + SymbolLine(5 25 10 20 8) + SymbolLine(10 20 20 20 8) + SymbolLine(0 20 5 25 8) +) +Symbol('s' 12) +( + SymbolLine(5 40 20 40 8) + SymbolLine(20 40 25 35 8) + SymbolLine(20 30 25 35 8) + SymbolLine(5 30 20 30 8) + SymbolLine(0 25 5 30 8) + SymbolLine(0 25 5 20 8) + SymbolLine(5 20 20 20 8) + SymbolLine(20 20 25 25 8) + SymbolLine(0 35 5 40 8) +) +Symbol('t' 10) +( + SymbolLine(5 0 5 35 8) + SymbolLine(5 35 10 40 8) + SymbolLine(0 15 10 15 8) +) +Symbol('u' 12) +( + SymbolLine(0 20 0 35 8) + SymbolLine(0 35 5 40 8) + SymbolLine(5 40 15 40 8) + SymbolLine(15 40 20 35 8) + SymbolLine(20 20 20 35 8) +) +Symbol('v' 12) +( + SymbolLine( 0 20 10 40 8) + SymbolLine(20 20 10 40 8) +) +Symbol('w' 12) +( + SymbolLine(0 20 0 35 8) + SymbolLine(0 35 5 40 8) + SymbolLine(5 40 10 40 8) + SymbolLine(10 40 15 35 8) + SymbolLine(15 20 15 35 8) + SymbolLine(15 35 20 40 8) + SymbolLine(20 40 25 40 8) + SymbolLine(25 40 30 35 8) + SymbolLine(30 20 30 35 8) +) +Symbol('x' 12) +( + SymbolLine(0 20 20 40 8) + SymbolLine(0 40 20 20 8) +) +Symbol('y' 12) +( + SymbolLine(0 20 0 35 8) + SymbolLine(0 35 5 40 8) + SymbolLine(20 20 20 50 8) + SymbolLine(15 55 20 50 8) + SymbolLine(5 55 15 55 8) + SymbolLine(0 50 5 55 8) + SymbolLine(5 40 15 40 8) + SymbolLine(15 40 20 35 8) +) +Symbol('z' 12) +( + SymbolLine(0 20 20 20 8) + SymbolLine(0 40 20 20 8) + SymbolLine(0 40 20 40 8) +) +Symbol('{' 12) +( + SymbolLine(5 5 10 0 8) + SymbolLine(5 5 5 15 8) + SymbolLine(0 20 5 15 8) + SymbolLine(0 20 5 25 8) + SymbolLine(5 25 5 35 8) + SymbolLine(5 35 10 40 8) +) +Symbol('|' 12) +( + SymbolLine(0 0 0 40 8) +) +Symbol('}' 12) +( + SymbolLine(0 0 5 5 8) + SymbolLine(5 5 5 15 8) + SymbolLine(5 15 10 20 8) + SymbolLine(5 25 10 20 8) + SymbolLine(5 25 5 35 8) + SymbolLine(0 40 5 35 8) +) +Symbol('~' 12) +( + SymbolLine(0 25 5 20 8) + SymbolLine(5 20 10 20 8) + SymbolLine(10 20 15 25 8) + SymbolLine(15 25 20 25 8) + SymbolLine(20 25 25 20 8) +) +Symbol('@' 12) +( + SymbolLine(0 0 0 30 8) + SymbolLine(0 30 10 40 8) + SymbolLine(10 40 40 40 8) + SymbolLine(50 25 50 0 8) + SymbolLine(50 0 40 -10 8) + SymbolLine(40 -10 10 -10 8) + SymbolLine(10 -10 0 0 8) + SymbolLine(15 10 15 20 8) + SymbolLine(15 20 20 25 8) + SymbolLine(20 25 30 25 8) + SymbolLine(30 25 35 20 8) + SymbolLine(35 20 40 25 8) + SymbolLine(35 20 35 5 8) + SymbolLine(35 10 30 5 8) + SymbolLine(20 5 30 5 8) + SymbolLine(20 5 15 10 8) + SymbolLine(40 25 50 25 8) +) Index: tags/2.3.0/src/draw.c =================================================================== --- tags/2.3.0/src/draw.c (nonexistent) +++ tags/2.3.0/src/draw.c (revision 33253) @@ -0,0 +1,1352 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2003, 2004 Thomas Nau + * Copyright (C) 2017,2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include "conf_core.h" +#include +#include +#include "board.h" +#include "data.h" +#include "draw.h" +#include +#include "rotate.h" +#include +#include "stub_draw.h" +#include "layer_ui.h" +#include +#include "funchash_core.h" + +#include "obj_pstk_draw.h" +#include "obj_line_draw.h" +#include "obj_arc_draw.h" +#include "obj_rat_draw.h" +#include "obj_poly_draw.h" +#include "obj_text_draw.h" +#include "obj_subc_parent.h" +#include "obj_gfx_draw.h" + +#undef NDEBUG +#include + +pcb_output_t pcb_draw_out; /* global context used for drawing */ + +rnd_box_t pcb_draw_invalidated = { RND_COORD_MAX, RND_COORD_MAX, -RND_COORD_MAX, -RND_COORD_MAX }; + +int pcb_draw_force_termlab = 0; +rnd_bool pcb_draw_doing_assy = rnd_false; +static vtp0_t delayed_labels, delayed_objs, annot_objs; +rnd_bool delayed_labels_enabled = rnd_false; +rnd_bool delayed_terms_enabled = rnd_false; + +static void draw_everything(pcb_draw_info_t *info); +static void pcb_draw_layer_grp(pcb_draw_info_t *info, int, int); +static void pcb_draw_obj_label(pcb_draw_info_t *info, rnd_layergrp_id_t gid, pcb_any_obj_t *obj); +static void pcb_draw_pstk_marks(pcb_draw_info_t *info); +static void pcb_draw_pstk_labels(pcb_draw_info_t *info); +static void pcb_draw_pstk_holes(pcb_draw_info_t *info, rnd_layergrp_id_t group, pcb_pstk_draw_hole_t holetype); +static void pcb_draw_ppv(pcb_draw_info_t *info, rnd_layergrp_id_t group); +static void xform_setup(pcb_draw_info_t *info, rnd_xform_t *dst, const pcb_layer_t *Layer); + +/* In draw_ly_spec.c: */ +static void pcb_draw_paste(pcb_draw_info_t *info, int side); +static void pcb_draw_mask(pcb_draw_info_t *info, int side); +static void pcb_draw_silk_doc(pcb_draw_info_t *info, pcb_layer_type_t lyt_side, pcb_layer_type_t lyt_type, int setgrp, int invis); +static void pcb_draw_boundary_mech(pcb_draw_info_t *info); +static void pcb_draw_rats(pcb_draw_info_t *info, const rnd_box_t *); +static void pcb_draw_assembly(pcb_draw_info_t *info, pcb_layer_type_t lyt_side); + + +void pcb_draw_delay_label_add(pcb_any_obj_t *obj) +{ + if (delayed_labels_enabled) + vtp0_append(&delayed_labels, obj); +} + +void pcb_draw_delay_obj_add(pcb_any_obj_t *obj) +{ + vtp0_append(&delayed_objs, obj); +} + +void pcb_draw_annotation_add(pcb_any_obj_t *obj) +{ + vtp0_append(&annot_objs, obj); +} + + +TODO("cleanup: this should be cached") +void pcb_lighten_color(const rnd_color_t *orig, rnd_color_t *dst, double factor) +{ + rnd_color_load_int(dst, MIN(255, orig->r * factor), MIN(255, orig->g * factor), MIN(255, orig->b * factor), 255); +} + +void pcb_draw_dashed_line(pcb_draw_info_t *info, rnd_hid_gc_t GC, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, unsigned int segs, rnd_bool_t cheap) +{ +/* TODO: we need a real geo lib... using double here is plain wrong */ + double dx = x2-x1, dy = y2-y1; + double len_mnt = RND_ABS(dx) + RND_ABS(dy); + int n; + rnd_coord_t minlen = rnd_render->coord_per_pix * 8; + + /* Ignore info->xform->bloat because a dashed line is always thin */ + + if (len_mnt < minlen*2) { + /* line too short, just draw it */ + rnd_render->draw_line(GC, x1, y1, x2, y2); + return; + } + + segs = (segs << 1) + 1; /* must be odd */ + + if (cheap) { + if ((segs > 3) && (len_mnt < minlen * segs)) + segs = 3; + else if ((segs > 5) && (len_mnt < minlen * 2 * segs)) + segs = 5; + } + + /* first seg is drawn from x1, y1 with no rounding error due to n-1 == 0 */ + for(n = 1; n < segs; n+=2) + rnd_render->draw_line(GC, + x1 + (dx * (double)(n-1) / (double)segs), y1 + (dy * (double)(n-1) / (double)segs), + x1 + (dx * (double)n / (double)segs), y1 + (dy * (double)n / (double)segs)); + + + /* make sure the last segment is drawn properly to x2 and y2, don't leave + room for rounding errors */ + rnd_render->draw_line(GC, + x2 - (dx / (double)segs), y2 - (dy / (double)segs), + x2, y2); +} + + +/* + * initiate the actual redrawing of the updated area + */ +rnd_cardinal_t pcb_draw_inhibit = 0; +void pcb_draw(void) +{ + if (pcb_draw_inhibit) + return; + if (pcb_draw_invalidated.X1 <= pcb_draw_invalidated.X2 && pcb_draw_invalidated.Y1 <= pcb_draw_invalidated.Y2) + rnd_render->invalidate_lr(rnd_render, pcb_draw_invalidated.X1, pcb_draw_invalidated.X2, pcb_draw_invalidated.Y1, pcb_draw_invalidated.Y2); + + /* shrink the update block */ + pcb_draw_invalidated.X1 = pcb_draw_invalidated.Y1 = RND_COORD_MAX; + pcb_draw_invalidated.X2 = pcb_draw_invalidated.Y2 = -RND_COORD_MAX; +} + +static void draw_everything_holes(pcb_draw_info_t *info, rnd_layergrp_id_t gid) +{ + int plated, unplated; + pcb_board_count_holes(PCB, &plated, &unplated, info->drawn_area); + + if (plated && pcb_layer_gui_set_vlayer(PCB, PCB_VLY_PLATED_DRILL, 0, &info->xform_exporter)) { + pcb_draw_pstk_holes(info, gid, PCB_PHOLE_PLATED); + rnd_render->end_layer(rnd_render); + } + + if (unplated && pcb_layer_gui_set_vlayer(PCB, PCB_VLY_UNPLATED_DRILL, 0, &info->xform_exporter)) { + pcb_draw_pstk_holes(info, gid, PCB_PHOLE_UNPLATED); + rnd_render->end_layer(rnd_render); + } +} + +typedef struct { + rnd_layergrp_id_t top_fab, top_assy, bot_assy; + int top_fab_enable, top_assy_enable, bot_assy_enable; +} legacy_vlayer_t; + +static int set_vlayer(pcb_draw_info_t *info, rnd_layergrp_id_t gid, int enable, pcb_virtual_layer_t vly_type) +{ + if (gid >= 0) { /* has a doc layer */ + if (!enable) + return 0; + return pcb_layer_gui_set_glayer(PCB, gid, 0, &info->xform_exporter); + } + + /* fall back to the legacy implicit virtual layer mode */ + return pcb_layer_gui_set_vlayer(PCB, vly_type, 0, &info->xform_exporter); +} + + +static void draw_virtual_layers(pcb_draw_info_t *info, const legacy_vlayer_t *lvly_drawn) +{ + rnd_hid_expose_ctx_t hid_exp; + rnd_xform_t tmp; + + hid_exp.view = *info->drawn_area; + + if (set_vlayer(info, lvly_drawn->top_assy, lvly_drawn->top_assy_enable, PCB_VLY_TOP_ASSY)) { + xform_setup(info, &tmp, NULL); + pcb_draw_assembly(info, PCB_LYT_TOP); + rnd_render->end_layer(rnd_render); + info->xform = NULL; info->layer = NULL; + } + + if (set_vlayer(info, lvly_drawn->bot_assy, lvly_drawn->bot_assy_enable, PCB_VLY_BOTTOM_ASSY)) { + xform_setup(info, &tmp, NULL); + pcb_draw_assembly(info, PCB_LYT_BOTTOM); + rnd_render->end_layer(rnd_render); + info->xform = NULL; info->layer = NULL; + } + + if (set_vlayer(info, lvly_drawn->top_fab, lvly_drawn->top_fab_enable, PCB_VLY_FAB)) { + xform_setup(info, &tmp, NULL); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + pcb_stub_draw_fab(info, pcb_draw_out.fgGC, &hid_exp); + rnd_render->end_layer(rnd_render); + info->xform = NULL; info->layer = NULL; + } + + if (pcb_layer_gui_set_vlayer(PCB, PCB_VLY_CSECT, 0, &info->xform_exporter)) { + xform_setup(info, &tmp, NULL); + pcb_stub_draw_csect(pcb_draw_out.fgGC, &hid_exp); + rnd_render->end_layer(rnd_render); + info->xform = NULL; info->layer = NULL; + } +} + +static void draw_ui_layers(pcb_draw_info_t *info) +{ + int i; + pcb_layer_t *first, *ly; + + /* find the first ui layer in use */ + first = NULL; + for(i = 0; i < vtp0_len(&pcb_uilayers); i++) { + if (pcb_uilayers.array[i] != NULL) { + first = pcb_uilayers.array[i]; + break; + } + } + + /* if there's any UI layer, try to draw them */ + if ((first != NULL) && pcb_layer_gui_set_g_ui(first, 0, &info->xform_exporter)) { + int have_canvas = 0; + for(i = 0; i < vtp0_len(&pcb_uilayers); i++) { + ly = pcb_uilayers.array[i]; + if ((ly != NULL) && (ly->meta.real.vis)) { + if (!have_canvas) { + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + have_canvas = 1; + } + pcb_draw_layer(info, ly); + } + } + if (have_canvas) + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); + rnd_render->end_layer(rnd_render); + } +} + +/* Draw subc and padstack marks in xor mode */ +static void draw_xor_marks(pcb_draw_info_t *info) +{ + int per_side = conf_core.appearance.subc_layer_per_side; + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE_XOR, pcb_draw_out.direct, info->drawn_area); + + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); + rnd_hid_set_draw_xor(pcb_draw_out.fgGC, 1); + + if (PCB->SubcOn) { + info->objcb.subc.per_side = per_side; + rnd_r_search(PCB->Data->subc_tree, info->drawn_area, NULL, draw_subc_mark_callback, info, NULL); + } + + rnd_hid_set_line_width(pcb_draw_out.fgGC, 0); + + if ((PCB->padstack_mark_on) && (conf_core.appearance.padstack.cross_thick > 0)) { + rnd_hid_set_line_width(pcb_draw_out.fgGC, -conf_core.appearance.padstack.cross_thick); + pcb_draw_pstk_marks(info); + } + + rnd_event(&PCB->hidlib, RND_EVENT_GUI_DRAW_OVERLAY_XOR, "p", &pcb_draw_out.fgGC, NULL); + + rnd_hid_set_draw_xor(pcb_draw_out.fgGC, 0); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); +} + +static void draw_rats(pcb_draw_info_t *info, const rnd_box_t *drawn_area) +{ + if (pcb_layer_gui_set_vlayer(PCB, PCB_VLY_RATS, 0, NULL)) { + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, drawn_area); + pcb_draw_rats(info, drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, drawn_area); + rnd_render->end_layer(rnd_render); + } +} + +static void draw_pins_and_pads(pcb_draw_info_t *info, rnd_layergrp_id_t component, rnd_layergrp_id_t solder) +{ + int per_side = conf_core.appearance.subc_layer_per_side; + + /* Draw pins' and pads' names */ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); + rnd_hid_set_line_width(pcb_draw_out.fgGC, 0); + if (PCB->SubcOn) { + info->objcb.subc.per_side = per_side; + rnd_r_search(PCB->Data->subc_tree, info->drawn_area, NULL, draw_subc_label_callback, info, NULL); + } + if (PCB->padstack_mark_on) { + rnd_hid_set_line_width(pcb_draw_out.fgGC, -conf_core.appearance.padstack.cross_thick); + pcb_draw_pstk_labels(info); + } + pcb_draw_pstk_names(info, info->xform->show_solder_side ? solder : component, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); +} + +static int has_auto(pcb_layergrp_t *grp) +{ + int n; + for(n = 0; n < grp->len; n++) { + pcb_layer_t *ly = pcb_get_layer(PCB->Data, grp->lid[n]); + if (ly->comb & PCB_LYC_AUTO) + return 1; + } + return 0; +} + +static void draw_everything(pcb_draw_info_t *info) +{ + rnd_layergrp_id_t backsilk_gid; + pcb_layergrp_t *backsilk_grp; + rnd_color_t old_silk_color[PCB_MAX_LAYERGRP]; + int i, ngroups; + rnd_layergrp_id_t component, solder, gid, side_copper_grp; + /* This is the list of layer groups we will draw. */ + char do_group[PCB_MAX_LAYERGRP]; + /* This is the reverse of the order in which we draw them. */ + rnd_layergrp_id_t drawn_groups[PCB_MAX_LAYERGRP]; + rnd_bool paste_empty; + legacy_vlayer_t lvly; + rnd_xform_t tmp; + + xform_setup(info, &tmp, NULL); + backsilk_gid = ((!info->xform->show_solder_side) ? pcb_layergrp_get_bottom_silk() : pcb_layergrp_get_top_silk()); + backsilk_grp = pcb_get_layergrp(PCB, backsilk_gid); + if (backsilk_grp != NULL) { + rnd_cardinal_t n; + for(n = 0; n < backsilk_grp->len; n++) { + pcb_layer_t *ly = pcb_get_layer(PCB->Data, backsilk_grp->lid[n]); + if (ly != NULL) { + old_silk_color[n] = ly->meta.real.color; + ly->meta.real.color = conf_core.appearance.color.invisible_objects; + } + } + } + + rnd_render->render_burst(rnd_render, RND_HID_BURST_START, info->drawn_area); + + memset(do_group, 0, sizeof(do_group)); + lvly.top_fab = -1; + lvly.top_assy = lvly.bot_assy = -1; + for (ngroups = 0, i = 0; i < pcb_max_layer(PCB); i++) { + pcb_layer_t *l = PCB_STACKLAYER(PCB, i); + rnd_layergrp_id_t group = pcb_layer_get_group(PCB, pcb_layer_stack[i]); + pcb_layergrp_t *grp = pcb_get_layergrp(PCB, group); + unsigned int gflg = 0; + + if (grp != NULL) + gflg = grp->ltype; + + if ((gflg & PCB_LYT_DOC) && (grp->purpi == F_fab)) { + lvly.top_fab = group; + lvly.top_fab_enable = has_auto(grp); + } + + if ((gflg & PCB_LYT_DOC) && (grp->purpi == F_assy)) { + if (gflg & PCB_LYT_TOP) { + lvly.top_assy = group; + lvly.top_assy_enable = has_auto(grp); + } + else if (gflg & PCB_LYT_BOTTOM) { + lvly.bot_assy = group; + lvly.bot_assy_enable = has_auto(grp); + } + } + + if ((gflg & PCB_LYT_SILK) || (gflg & PCB_LYT_DOC) || (gflg & PCB_LYT_MASK) || (gflg & PCB_LYT_PASTE) || (gflg & PCB_LYT_BOUNDARY) || (gflg & PCB_LYT_MECH)) /* do not draw silk, mask, paste and boundary here, they'll be drawn separately */ + continue; + + if (l->meta.real.vis && !do_group[group]) { + do_group[group] = 1; + drawn_groups[ngroups++] = group; + } + } + + solder = component = -1; + pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_COPPER, &solder, 1); + pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_COPPER, &component, 1); + side_copper_grp = info->xform->show_solder_side ? solder : component; + + + /* + * first draw all 'invisible' stuff + */ + if ((info->xform_exporter != NULL) && !info->xform_exporter->check_planes && pcb_layer_gui_set_vlayer(PCB, PCB_VLY_INVISIBLE, 0, &info->xform_exporter)) { + pcb_layer_type_t side = PCB_LYT_INVISIBLE_SIDE(); + + pcb_draw_silk_doc(info, side, PCB_LYT_DOC, 0, 1); + pcb_draw_silk_doc(info, side, PCB_LYT_SILK, 0, 1); + + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); + rnd_render->end_layer(rnd_render); + } + + /* Draw far side doc and silks */ + { + pcb_layer_type_t ivside = PCB_LYT_INVISIBLE_SIDE(); + + pcb_draw_silk_doc(info, ivside, PCB_LYT_SILK, 1, 0); + pcb_draw_silk_doc(info, ivside, PCB_LYT_DOC, 1, 0); + } + + /* draw all layers in layerstack order */ + for (i = ngroups - 1; i >= 0; i--) { + rnd_layergrp_id_t group = drawn_groups[i]; + + if (pcb_layer_gui_set_glayer(PCB, group, 0, &info->xform_exporter)) { + int is_current = 0; + rnd_layergrp_id_t cgrp = PCB_CURRLAYER(PCB)->meta.real.grp; + + if ((cgrp == solder) || (cgrp == component)) { + /* current group is top or bottom: visibility depends on side we are looking at */ + if (group == side_copper_grp) + is_current = 1; + } + else { + /* internal layer displayed on top: current group is solid, others are "invisible" */ + if (group == cgrp) + is_current = 1; + } + + pcb_draw_layer_grp(info, group, is_current); + rnd_render->end_layer(rnd_render); + } + } + + if (conf_core.editor.check_planes && rnd_render->gui) + goto finish; + + /* Draw padstacks below silk */ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + if (rnd_render->gui) { + rnd_xform_t tmp; + xform_setup(info, &tmp, NULL); + pcb_draw_ppv(info, info->xform->show_solder_side ? solder : component); + info->xform = NULL; info->layer = NULL; + } + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); + + /* Draw the solder mask if turned on */ + gid = pcb_layergrp_get_top_mask(); + if ((gid >= 0) && (pcb_layer_gui_set_glayer(PCB, gid, 0, &info->xform_exporter))) { + pcb_draw_mask(info, PCB_COMPONENT_SIDE); + rnd_render->end_layer(rnd_render); + } + + gid = pcb_layergrp_get_bottom_mask(); + if ((gid >= 0) && (pcb_layer_gui_set_glayer(PCB, gid, 0, &info->xform_exporter))) { + pcb_draw_mask(info, PCB_SOLDER_SIDE); + rnd_render->end_layer(rnd_render); + } + + /* Draw doc and silks */ + { + pcb_layer_type_t vside = PCB_LYT_VISIBLE_SIDE(); + + pcb_draw_silk_doc(info, PCB_LYT_INTERN, PCB_LYT_SILK, 1, 0); + pcb_draw_silk_doc(info, PCB_LYT_INTERN, PCB_LYT_DOC, 1, 0); + pcb_draw_silk_doc(info, 0, PCB_LYT_DOC, 1, 0); + pcb_draw_silk_doc(info, vside, PCB_LYT_SILK, 1, 0); + pcb_draw_silk_doc(info, vside, PCB_LYT_DOC, 1, 0); + } + + { /* holes_after: draw holes after copper, silk and mask, to make sure it punches through everything. */ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + draw_everything_holes(info, side_copper_grp); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); + } + + gid = pcb_layergrp_get_top_paste(); + if (gid >= 0) + paste_empty = pcb_layergrp_is_empty(PCB, gid); + if ((gid >= 0) && (pcb_layer_gui_set_glayer(PCB, gid, paste_empty, &info->xform_exporter))) { + pcb_draw_paste(info, PCB_COMPONENT_SIDE); + rnd_render->end_layer(rnd_render); + } + + gid = pcb_layergrp_get_bottom_paste(); + if (gid >= 0) + paste_empty = pcb_layergrp_is_empty(PCB, gid); + if ((gid >= 0) && (pcb_layer_gui_set_glayer(PCB, gid, paste_empty, &info->xform_exporter))) { + pcb_draw_paste(info, PCB_SOLDER_SIDE); + rnd_render->end_layer(rnd_render); + } + + pcb_draw_boundary_mech(info); + + draw_virtual_layers(info, &lvly); + if ((rnd_render->gui) || (!info->xform_caller->omit_overlay)) { + rnd_xform_t tmp; + xform_setup(info, &tmp, NULL); + draw_rats(info, info->drawn_area); + draw_pins_and_pads(info, component, solder); + } + draw_ui_layers(info); + + if (rnd_render->gui) { + rnd_xform_t tmp; + xform_setup(info, &tmp, NULL); + draw_xor_marks(info); + } + + finish:; + if (backsilk_grp != NULL) { + rnd_cardinal_t n; + for(n = 0; n < backsilk_grp->len; n++) { + pcb_layer_t *ly = pcb_get_layer(PCB->Data, backsilk_grp->lid[n]); + if (ly != NULL) + ly->meta.real.color = old_silk_color[n]; + } + } +} + +static void pcb_draw_pstks(pcb_draw_info_t *info, rnd_layergrp_id_t group, int is_current, pcb_layer_combining_t comb) +{ + pcb_layergrp_t *g = PCB->LayerGroups.grp + group; + rnd_xform_t tmp; + + xform_setup(info, &tmp, NULL); + + info->objcb.pstk.gid = group; + info->objcb.pstk.is_current = is_current; + info->objcb.pstk.comb = comb; + if (g->len > 0) + info->objcb.pstk.layer1 = pcb_get_layer(info->pcb->Data, g->lid[0]); + else + info->objcb.pstk.layer1 = NULL; + + if (!info->xform->check_planes) + rnd_r_search(info->pcb->Data->padstack_tree, info->drawn_area, NULL, pcb_pstk_draw_callback, info, NULL); + + info->xform = NULL; info->layer = NULL; +} + +static void pcb_draw_pstk_marks(pcb_draw_info_t *info) +{ + rnd_r_search(PCB->Data->padstack_tree, info->drawn_area, NULL, pcb_pstk_draw_mark_callback, info, NULL); +} + +static void pcb_draw_pstk_labels(pcb_draw_info_t *info) +{ + rnd_r_search(PCB->Data->padstack_tree, info->drawn_area, NULL, pcb_pstk_draw_label_callback, info, NULL); +} + +static void pcb_draw_pstk_holes(pcb_draw_info_t *info, rnd_layergrp_id_t group, pcb_pstk_draw_hole_t holetype) +{ + rnd_xform_t tmp; + + + if (!PCB->hole_on) + return; + + xform_setup(info, &tmp, NULL); + info->objcb.pstk.gid = group; + info->objcb.pstk.holetype = holetype; + rnd_r_search(PCB->Data->padstack_tree, info->drawn_area, NULL, pcb_pstk_draw_hole_callback, info, NULL); + info->xform = NULL; info->layer = NULL; +} + +static void pcb_draw_pstk_slots(pcb_draw_info_t *info, rnd_layergrp_id_t group, pcb_pstk_draw_hole_t holetype) +{ + rnd_xform_t tmp; + + if (!PCB->hole_on) + return; + + xform_setup(info, &tmp, NULL); + info->objcb.pstk.gid = group; + info->objcb.pstk.holetype = holetype; + rnd_r_search(PCB->Data->padstack_tree, info->drawn_area, NULL, pcb_pstk_draw_slot_callback, info, NULL); + info->xform = NULL; info->layer = NULL; +} + +/* --------------------------------------------------------------------------- + * Draws padstacks - Always draws for non-gui HIDs, + * otherwise drawing depends on PCB->pstk_on + */ +static void pcb_draw_ppv(pcb_draw_info_t *info, rnd_layergrp_id_t group) +{ + /* draw padstack holes - copper is drawn with each group */ + if (PCB->pstk_on || !rnd_render->gui) { + pcb_draw_pstk_holes(info, group, PCB_PHOLE_PLATED | PCB_PHOLE_UNPLATED | PCB_PHOLE_BB); + if ( + !rnd_render->gui /* on the gui padstacks can be turned off separately so we shouldn't enforce drawing the slot in it; on export, copper is copper, no matter if it is coming from a padstack: slot always needs to be drawn */ + && !info->xform_caller->no_slot_in_nonmech /* keep the output cleaner in some exporters, like gerber, where solid copper is drawn anyway */ + ) + pcb_draw_pstk_slots(info, group, PCB_PHOLE_PLATED | PCB_PHOLE_UNPLATED | PCB_PHOLE_BB); + } +} + +#include "draw_label_smart.c" + +/* --------------------------------------------------------------------------- + * Draws padstacks' names - Always draws for non-gui HIDs, + * otherwise drawing depends on PCB->pstk_on + */ +void pcb_draw_pstk_names(pcb_draw_info_t *info, rnd_layergrp_id_t group, const rnd_box_t *drawn_area) +{ + if (PCB->pstk_on || !rnd_render->gui) { + size_t n; + for(n = 0; n < delayed_labels.used; n++) + pcb_draw_obj_label(info, group, delayed_labels.array[n]); + } + pcb_label_smart_flush(info); + delayed_labels.used = 0; +} + +static void pcb_draw_delayed_objs(pcb_draw_info_t *info) +{ + size_t n; + + for(n = 0; n < delayed_objs.used; n++) { + pcb_any_obj_t *o = delayed_objs.array[n]; + rnd_box_t *b = (rnd_box_t *)o; + switch(o->type) { + case PCB_OBJ_ARC: pcb_arc_draw_term_callback(b, info); break; + case PCB_OBJ_LINE: pcb_line_draw_term_callback(b, info); break; + case PCB_OBJ_TEXT: pcb_text_draw_term_callback(b, info); break; + case PCB_OBJ_POLY: pcb_poly_draw_term_callback(b, info); break; + default: + assert(!"Don't know how to draw delayed object"); + } + } + vtp0_truncate(&delayed_objs, 0); +} + +static void pcb_draw_annotations(pcb_draw_info_t *info) +{ + size_t n; + + if ((rnd_render != NULL) && (rnd_render->gui)) { + for(n = 0; n < annot_objs.used; n++) { + pcb_any_obj_t *o = annot_objs.array[n]; + switch(o->type) { + case PCB_OBJ_POLY: pcb_poly_draw_annotation(info, (pcb_poly_t *)o); break; + default: + assert(!"Don't know how to draw annotation for object"); + } + } + } + vtp0_truncate(&annot_objs, 0); +} + +#include "draw_composite.c" +#include "draw_ly_spec.c" + +static void xform_setup(pcb_draw_info_t *info, rnd_xform_t *dst, const pcb_layer_t *Layer) +{ + info->layer = Layer; + if ((Layer != NULL) && (!pcb_xform_is_nop(&Layer->meta.real.xform))) { + pcb_xform_copy(dst, &Layer->meta.real.xform); + info->xform = dst; + } + if (info->xform_caller != NULL) { + if (info->xform == NULL) { + info->xform = dst; + pcb_xform_copy(dst, info->xform_caller); + } + else + pcb_xform_add(dst, info->xform_caller); + } + if (info->xform_exporter != NULL) { + if (info->xform == NULL) { + info->xform = dst; + pcb_xform_copy(dst, info->xform_exporter); + } + else + pcb_xform_add(dst, info->xform_exporter); + } +} + +void pcb_draw_layer(pcb_draw_info_t *info, const pcb_layer_t *Layer_) +{ + unsigned int lflg = 0; + int may_have_delayed = 0, restore_color = 0, current_grp; + rnd_xform_t xform; + rnd_color_t orig_color; + pcb_layer_t *Layer = (pcb_layer_t *)Layer_; /* ugly hack until layer color is moved into info */ + + xform_setup(info, &xform, Layer); + + current_grp = (Layer_->meta.real.grp == PCB_CURRLAYER(PCB)->meta.real.grp); + + if ((info->xform != NULL) && (info->xform->layer_faded)) { + orig_color = Layer->meta.real.color; + pcb_lighten_color(&orig_color, &Layer->meta.real.color, 0.5); + restore_color = 1; + } + else if (info->xform->invis_other_groups && !current_grp) { + orig_color = Layer->meta.real.color; + Layer->meta.real.color = conf_core.appearance.color.invisible_objects; + restore_color = 1; + } + + if (info->xform->black_current_group && current_grp) { + if (!restore_color) { + orig_color = Layer->meta.real.color; + restore_color = 1; + Layer->meta.real.color = *rnd_color_black; + } + } + + lflg = pcb_layer_flags_(Layer); + if (PCB_LAYERFLG_ON_VISIBLE_SIDE(lflg)) + pcb_draw_out.active_padGC = pcb_draw_out.padGC; + else + pcb_draw_out.active_padGC = pcb_draw_out.backpadGC; + + /* first draw all gfx that's under other layer objects */ + if (lflg & PCB_LYT_COPPER) { + delayed_terms_enabled = rnd_true; + rnd_r_search(Layer->gfx_tree, info->drawn_area, NULL, pcb_gfx_draw_under_callback, info, NULL); + delayed_terms_enabled = rnd_false; + may_have_delayed = 1; + } + else + rnd_r_search(Layer->gfx_tree, info->drawn_area, NULL, pcb_gfx_draw_under_callback, info, NULL); + + /* print the non-clearing polys */ + if (lflg & PCB_LYT_COPPER) { + delayed_terms_enabled = rnd_true; + rnd_hid_set_line_width(pcb_draw_out.fgGC, 1); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_square); + rnd_r_search(Layer->polygon_tree, info->drawn_area, NULL, pcb_poly_draw_term_callback, info, NULL); + delayed_terms_enabled = rnd_false; + may_have_delayed = 1; + } + else { + rnd_r_search(Layer->polygon_tree, info->drawn_area, NULL, pcb_poly_draw_callback, info, NULL); + } + + if (info->xform->check_planes) + goto out; + + /* draw all visible layer objects (with terminal gfx on copper) */ + if (lflg & PCB_LYT_COPPER) { + delayed_terms_enabled = rnd_true; + rnd_r_search(Layer->line_tree, info->drawn_area, NULL, pcb_line_draw_term_callback, info, NULL); + rnd_r_search(Layer->arc_tree, info->drawn_area, NULL, pcb_arc_draw_term_callback, info, NULL); + rnd_r_search(Layer->text_tree, info->drawn_area, NULL, pcb_text_draw_term_callback, info, NULL); + rnd_r_search(Layer->gfx_tree, info->drawn_area, NULL, pcb_gfx_draw_above_callback, info, NULL); + delayed_terms_enabled = rnd_false; + may_have_delayed = 1; + } + else { + rnd_r_search(Layer->line_tree, info->drawn_area, NULL, pcb_line_draw_callback, info, NULL); + rnd_r_search(Layer->arc_tree, info->drawn_area, NULL, pcb_arc_draw_callback, info, NULL); + rnd_r_search(Layer->text_tree, info->drawn_area, NULL, pcb_text_draw_callback, info, NULL); + rnd_r_search(Layer->gfx_tree, info->drawn_area, NULL, pcb_gfx_draw_above_callback, info, NULL); + } + + if (may_have_delayed) + pcb_draw_delayed_objs(info); + pcb_draw_annotations(info); + + out:; + pcb_draw_out.active_padGC = NULL; + + if (restore_color) + Layer->meta.real.color = orig_color; + + info->xform = NULL; info->layer = NULL; +} + +static void pcb_draw_info_setup(pcb_draw_info_t *info, pcb_board_t *pcb) +{ + info->pcb = pcb; + info->exporting = (rnd_render->exporter || rnd_render->printer); + info->export_name = rnd_render->name; + if (info->exporting) { + strcpy(info->noexport_name, "noexport:"); + strncpy(info->noexport_name+9, info->export_name, sizeof(info->noexport_name)-10); + info->noexport_name[sizeof(info->noexport_name)-1] = '\0'; + } + else + *info->noexport_name = '\0'; +} + +void pcb_draw_layer_noxform(pcb_board_t *pcb, const pcb_layer_t *Layer, const rnd_box_t *screen) +{ + pcb_draw_info_t info; + rnd_box_t scr2; + + pcb_draw_info_setup(&info, pcb); + info.drawn_area = screen; + info.xform_exporter = info.xform = NULL; + + /* fix screen coord order */ + if ((screen->X2 <= screen->X1) || (screen->Y2 <= screen->Y1)) { + scr2 = *screen; + info.drawn_area = &scr2; + if (scr2.X2 <= scr2.X1) + scr2.X2 = scr2.X1+1; + if (scr2.Y2 <= scr2.Y1) + scr2.Y2 = scr2.Y1+1; + } + + pcb_draw_layer(&info, Layer); +} + + +/* This version is about 1% slower and used rarely, thus it's all dupped + from pcb_draw_layer() to keep the original speed there */ +void pcb_draw_layer_under(pcb_board_t *pcb, const pcb_layer_t *Layer, const rnd_box_t *screen, pcb_data_t *data, rnd_xform_t *xf) +{ + pcb_draw_info_t info; + rnd_box_t scr2; + unsigned int lflg = 0; + rnd_rtree_it_t it; + pcb_any_obj_t *o; + rnd_xform_t tmp; + + if ((screen->X2 <= screen->X1) || (screen->Y2 <= screen->Y1)) { + scr2 = *screen; + screen = &scr2; + if (scr2.X2 <= scr2.X1) + scr2.X2 = scr2.X1+1; + if (scr2.Y2 <= scr2.Y1) + scr2.Y2 = scr2.Y1+1; + } + + pcb_draw_info_setup(&info, pcb); + info.drawn_area = screen; + info.xform_exporter = info.xform_caller = info.xform = xf; + + xform_setup(&info, &tmp, Layer); + + lflg = pcb_layer_flags_(Layer); + if (PCB_LAYERFLG_ON_VISIBLE_SIDE(lflg)) + pcb_draw_out.active_padGC = pcb_draw_out.padGC; + else + pcb_draw_out.active_padGC = pcb_draw_out.backpadGC; + + /* first draw gfx that are under other layer objects */ + if (lflg & PCB_LYT_COPPER) { + if (Layer->gfx_tree != NULL) + for(o = rnd_rtree_first(&it, Layer->gfx_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if ((pcb_obj_is_under(o, data)) && (((pcb_gfx_t *)o)->render_under)) + pcb_gfx_draw(&info, (pcb_gfx_t *)o, 0); + } + else { + if (Layer->gfx_tree != NULL) + for(o = rnd_rtree_first(&it, Layer->gfx_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if (pcb_obj_is_under(o, data)) + pcb_gfx_draw_under_callback((rnd_box_t *)o, &info); + } + + /* print the non-clearing polys */ + if (Layer->polygon_tree != NULL) { + if (lflg & PCB_LYT_COPPER) { + for(o = rnd_rtree_first(&it, Layer->polygon_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if (pcb_obj_is_under(o, data)) + pcb_poly_draw_term_callback((rnd_box_t *)o, &info); + } + else { + for(o = rnd_rtree_first(&it, Layer->polygon_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if (pcb_obj_is_under(o, data)) + pcb_poly_draw_callback((rnd_box_t *)o, &info); + } + } + + if (info.xform->check_planes) + goto out; + + /* draw all visible layer objects (with terminal gfx on copper) */ + if (lflg & PCB_LYT_COPPER) { + if (Layer->line_tree != NULL) + for(o = rnd_rtree_first(&it, Layer->line_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if (pcb_obj_is_under(o, data)) + pcb_line_draw_term_callback((rnd_box_t *)o, &info); + if (Layer->arc_tree != NULL) + for(o = rnd_rtree_first(&it, Layer->arc_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if (pcb_obj_is_under(o, data)) + pcb_arc_draw_term_callback((rnd_box_t *)o, &info); + if (Layer->text_tree != NULL) + for(o = rnd_rtree_first(&it, Layer->text_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if (pcb_obj_is_under(o, data)) + pcb_text_draw_term_callback((rnd_box_t *)o, &info); + if (Layer->gfx_tree != NULL) + for(o = rnd_rtree_first(&it, Layer->gfx_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if ((pcb_obj_is_under(o, data)) && !(((pcb_gfx_t *)o)->render_under)) + pcb_gfx_draw(&info, (pcb_gfx_t *)o, 0); + } + else { + if (Layer->line_tree != NULL) + for(o = rnd_rtree_first(&it, Layer->line_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if (pcb_obj_is_under(o, data)) + pcb_line_draw_callback((rnd_box_t *)o, &info); + if (Layer->arc_tree != NULL) + for(o = rnd_rtree_first(&it, Layer->arc_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if (pcb_obj_is_under(o, data)) + pcb_arc_draw_callback((rnd_box_t *)o, &info); + if (Layer->text_tree != NULL) + for(o = rnd_rtree_first(&it, Layer->text_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if (pcb_obj_is_under(o, data)) + pcb_text_draw_callback((rnd_box_t *)o, &info); + if (Layer->gfx_tree != NULL) + for(o = rnd_rtree_first(&it, Layer->gfx_tree, (rnd_rtree_box_t *)screen); o != NULL; o = rnd_rtree_next(&it)) + if (pcb_obj_is_under(o, data)) + pcb_gfx_draw_above_callback((rnd_box_t *)o, &info); + } + + out:; + pcb_draw_out.active_padGC = NULL; + + info.layer = NULL; info.xform = NULL; +} + +/* --------------------------------------------------------------------------- + * draws one layer group. If the exporter is not a GUI, + * also draws the padstacks in this layer group. + */ +static void pcb_draw_layer_grp(pcb_draw_info_t *info, int group, int is_current) +{ + int i; + rnd_layer_id_t layernum; + pcb_layer_t *Layer; + rnd_cardinal_t n_entries = PCB->LayerGroups.grp[group].len; + rnd_layer_id_t *layers = PCB->LayerGroups.grp[group].lid; + pcb_layergrp_t *grp = pcb_get_layergrp(PCB, group); + unsigned int gflg = grp->ltype; + + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + + for (i = n_entries - 1; i >= 0; i--) { + layernum = layers[i]; + Layer = info->pcb->Data->Layer + layernum; + if (!(gflg & PCB_LYT_SILK) && Layer->meta.real.vis) + pcb_draw_layer(info, Layer); + } + + if ((gflg & PCB_LYT_COPPER) && (PCB->pstk_on)) { + rnd_xform_t tmp; + const pcb_layer_t *ly1 = NULL; + + /* figure first layer to get the transformations from */ + if (n_entries > 0) + ly1 = info->pcb->Data->Layer + layers[0]; + + xform_setup(info, &tmp, ly1); + pcb_draw_pstks(info, group, (PCB_CURRLAYER(PCB)->meta.real.grp == group), 0); + info->xform = NULL; info->layer = NULL; + } + + /* this draws the holes - must be the last, so holes are drawn over everything else */ + if (!rnd_render->gui) + pcb_draw_ppv(info, group); + + + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); +} + +void pcb_erase_obj(int type, void *lptr, void *ptr) +{ + if (pcb_hidden_floater_gui((pcb_any_obj_t *)ptr)) + return; + + switch (type) { + case PCB_OBJ_PSTK: + pcb_pstk_invalidate_erase((pcb_pstk_t *) ptr); + break; + + case PCB_OBJ_TEXT: + pcb_text_invalidate_erase((pcb_layer_t *) lptr, (pcb_text_t *) ptr); + break; + case PCB_OBJ_POLY: + pcb_poly_invalidate_erase((pcb_poly_t *) ptr); + break; + case PCB_OBJ_SUBC: + EraseSubc((pcb_subc_t *)ptr); + break; + case PCB_OBJ_LINE: + case PCB_OBJ_RAT: + pcb_line_invalidate_erase((pcb_line_t *) ptr); + break; + case PCB_OBJ_ARC: + pcb_arc_invalidate_erase((pcb_arc_t *) ptr); + break; + case PCB_OBJ_GFX: + pcb_gfx_invalidate_erase((pcb_gfx_t *)ptr); + break; + default: + rnd_message(RND_MSG_ERROR, "hace: Internal ERROR, trying to erase an unknown type\n"); + } +} + + +void pcb_draw_obj(pcb_any_obj_t *obj) +{ + if (pcb_hidden_floater_gui(obj)) + return; + + switch (obj->type) { + case PCB_OBJ_PSTK: + if (PCB->pstk_on) + pcb_pstk_invalidate_draw((pcb_pstk_t *)obj); + break; + case PCB_OBJ_LINE: + if (obj->parent.layer->meta.real.vis) + pcb_line_invalidate_draw(obj->parent.layer, (pcb_line_t *)obj); + break; + case PCB_OBJ_ARC: + if (obj->parent.layer->meta.real.vis) + pcb_arc_invalidate_draw(obj->parent.layer, (pcb_arc_t *)obj); + break; + case PCB_OBJ_GFX: + if (obj->parent.layer->meta.real.vis) + pcb_gfx_invalidate_draw(obj->parent.layer, (pcb_gfx_t *)obj); + break; + case PCB_OBJ_TEXT: + if (obj->parent.layer->meta.real.vis) + pcb_text_invalidate_draw(obj->parent.layer, (pcb_text_t *)obj); + break; + case PCB_OBJ_POLY: + if (obj->parent.layer->meta.real.vis) + pcb_poly_invalidate_draw(obj->parent.layer, (pcb_poly_t *)obj); + break; + case PCB_OBJ_RAT: + if (PCB->RatOn) + pcb_rat_invalidate_draw((pcb_rat_t *)obj); + break; + case PCB_OBJ_SUBC: + case PCB_OBJ_NET: + case PCB_OBJ_LAYER: + case PCB_OBJ_LAYERGRP: + case PCB_OBJ_VOID: + case PCB_OBJ_NET_TERM: + break; + } +} + +static void pcb_draw_obj_label(pcb_draw_info_t *info, rnd_layergrp_id_t gid, pcb_any_obj_t *obj) +{ + rnd_bool vis_side = 1; + + if (pcb_hidden_floater(obj, info)) + return; + + /* do not show layer-object labels of the other side on non-pinout views */ + if ((!pcb_draw_force_termlab) && (obj->parent_type == PCB_PARENT_LAYER)) { + pcb_layer_t *ly = pcb_layer_get_real(obj->parent.layer); + if ((ly != NULL) && (ly->meta.real.grp != gid)) + vis_side = 0; + } + + switch(obj->type) { + case PCB_OBJ_LINE: pcb_line_draw_label(info, (pcb_line_t *)obj, vis_side); return; + case PCB_OBJ_ARC: pcb_arc_draw_label(info, (pcb_arc_t *)obj, vis_side); return; + case PCB_OBJ_GFX: pcb_gfx_draw_label(info, (pcb_gfx_t *)obj, vis_side); return; + case PCB_OBJ_POLY: pcb_poly_draw_label(info, (pcb_poly_t *)obj, vis_side); return; + case PCB_OBJ_TEXT: pcb_text_draw_label(info, (pcb_text_t *)obj, vis_side); return; + case PCB_OBJ_PSTK: pcb_pstk_draw_label(info, (pcb_pstk_t *)obj, vis_side); return; + default: break; + } +} + +/* --------------------------------------------------------------------------- + * HID drawing callback. + */ + +static void expose_begin(pcb_output_t *save, rnd_hid_t *hid) +{ + memcpy(save, &pcb_draw_out, sizeof(pcb_output_t)); + save->hid = rnd_render; + + delayed_labels_enabled = rnd_true; + vtp0_truncate(&delayed_labels, 0); + vtp0_truncate(&delayed_objs, 0); + + if ((rnd_render != NULL) && (!rnd_render->override_render)) + rnd_render = hid; + pcb_draw_out.hid = rnd_render; + + pcb_draw_out.fgGC = rnd_hid_make_gc(); + pcb_draw_out.padGC = rnd_hid_make_gc(); + pcb_draw_out.backpadGC = rnd_hid_make_gc(); + pcb_draw_out.padselGC = rnd_hid_make_gc(); + pcb_draw_out.drillGC = rnd_hid_make_gc(); + pcb_draw_out.pmGC = rnd_hid_make_gc(); + + if (hid->force_compositing) + pcb_draw_out.direct = 0; + else + pcb_draw_out.direct = 1; + + hid->set_color(pcb_draw_out.pmGC, rnd_color_cyan); + hid->set_color(pcb_draw_out.drillGC, rnd_color_drill); + hid->set_color(pcb_draw_out.padGC, &conf_core.appearance.color.pin); + hid->set_color(pcb_draw_out.backpadGC, &conf_core.appearance.color.invisible_objects); + hid->set_color(pcb_draw_out.padselGC, &conf_core.appearance.color.selected); + rnd_hid_set_line_width(pcb_draw_out.backpadGC, -1); + rnd_hid_set_line_cap(pcb_draw_out.backpadGC, rnd_cap_square); + rnd_hid_set_line_width(pcb_draw_out.padselGC, -1); + rnd_hid_set_line_cap(pcb_draw_out.padselGC, rnd_cap_square); + rnd_hid_set_line_width(pcb_draw_out.padGC, -1); + rnd_hid_set_line_cap(pcb_draw_out.padGC, rnd_cap_square); +} + +static void expose_end(pcb_output_t *save) +{ + rnd_hid_destroy_gc(pcb_draw_out.fgGC); + rnd_hid_destroy_gc(pcb_draw_out.padGC); + rnd_hid_destroy_gc(pcb_draw_out.backpadGC); + rnd_hid_destroy_gc(pcb_draw_out.padselGC); + rnd_hid_destroy_gc(pcb_draw_out.drillGC); + rnd_hid_destroy_gc(pcb_draw_out.pmGC); + + pcb_draw_out.fgGC = NULL; + + delayed_labels_enabled = rnd_false; + vtp0_truncate(&delayed_labels, 0); + vtp0_truncate(&delayed_objs, 0); + + memcpy(&pcb_draw_out, save, sizeof(pcb_output_t)); + rnd_render = pcb_draw_out.hid; +} + +void pcb_draw_setup_default_gui_xform(rnd_xform_t *dst) +{ + dst->wireframe = conf_core.editor.wireframe_draw; + dst->thin_draw = conf_core.editor.thin_draw; + dst->thin_draw_poly = conf_core.editor.thin_draw_poly; + dst->check_planes = conf_core.editor.check_planes; + dst->hide_floaters = conf_core.editor.hide_names; + dst->show_solder_side = conf_core.editor.show_solder_side; + dst->invis_other_groups = conf_core.appearance.invis_other_groups; + dst->black_current_group = conf_core.appearance.black_current_group; + dst->flag_color = 1; +} + +void pcb_draw_setup_default_xform_info(rnd_hid_t *hid, pcb_draw_info_t *info) +{ + static rnd_xform_t xf_def = {0}; + static rnd_xform_t xform_main_exp; + + if (info->xform_caller == NULL) { + if (hid->exporter) { + /* exporters without xform should automatically inherit the default xform for exporting, which differs from what GUI does */ + memset(&xform_main_exp, 0, sizeof(xform_main_exp)); + info->xform = info->xform_exporter = &xform_main_exp; + + xform_main_exp.omit_overlay = 1; /* normally exporters shouldn't draw overlays */ + info->xform_caller = &xform_main_exp; + } + else if (hid->gui) { + /* no xform means we should use the default logic designed for the GUI */ + info->xform = info->xform_exporter = info->xform_caller = &xf_def; + pcb_draw_setup_default_gui_xform(&xf_def); + } + } +} + +void rnd_expose_main(rnd_hid_t * hid, const rnd_hid_expose_ctx_t *ctx, rnd_xform_t *xform_caller) +{ + if (!pcb_draw_inhibit) { + pcb_output_t save; + pcb_draw_info_t info; + + expose_begin(&save, hid); + pcb_draw_info_setup(&info, PCB); + info.drawn_area = &ctx->view; + info.xform_caller = xform_caller; + info.xform = info.xform_exporter = NULL; + info.layer = NULL; + + pcb_draw_setup_default_xform_info(hid, &info); + + draw_everything(&info); + expose_end(&save); + } +} + +void rnd_expose_preview(rnd_hid_t *hid, const rnd_hid_expose_ctx_t *e) +{ + pcb_output_t save; + expose_begin(&save, hid); + + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, 1, &e->view); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, 1, &e->view); + e->expose_cb(pcb_draw_out.fgGC, e); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, 1, &e->view); + rnd_render->end_layer(rnd_render); + + expose_end(&save); +} + +static const char *lab_with_intconn(const pcb_any_obj_t *term, int intconn, const char *lab, char *buff, int bufflen) +{ + if ((conf_core.editor.term_id != NULL) && (*conf_core.editor.term_id != '\0')) { + gds_t tmp; + if (pcb_append_dyntext(&tmp, term, conf_core.editor.term_id) == 0) { + int len = tmp.used < (bufflen-1) ? tmp.used : (bufflen-1); + memcpy(buff, tmp.array, len); + buff[len] = '\0'; + gds_uninit(&tmp); + return buff; + } + } + + /* fallback when template is not available or failed */ + if (intconn <= 0) + return lab; + rnd_snprintf(buff, bufflen, "%s[%d]", lab, intconn); + + return buff; +} + +/* vert flip magic: make sure the offset is in-line with the flip and our sick y coords for vertical */ +#define PCB_TERM_LABEL_SETUP(label) \ + rnd_bool flip_x = rnd_conf.editor.view.flip_x; \ + rnd_bool flip_y = rnd_conf.editor.view.flip_y; \ + pcb_font_t *font = pcb_font(PCB, 0, 0); \ + rnd_coord_t w, h, dx, dy; \ + double scl = scale/100.0; \ + if (vert) { \ + h = pcb_text_width(font, scl, label); \ + w = pcb_text_height(font, scl, label); \ + } \ + else { \ + w = pcb_text_width(font, scl, label); \ + h = pcb_text_height(font, scl, label); \ + } \ + dx = w / 2; \ + dy = h / 2; \ + if (flip_x ^ flip_y) { \ + if (vert) \ + dx = -dx; \ + else \ + dy = -dy; \ + } \ + if (vert) \ + dy = -dy; \ + if (centered) { \ + x -= dx; \ + y -= dy; \ + } + + +void pcb_label_draw(pcb_draw_info_t *info, rnd_coord_t x, rnd_coord_t y, double scale, rnd_bool vert, rnd_bool centered, const char *label, int prio) +{ + int mirror, direction; + + PCB_TERM_LABEL_SETUP((const unsigned char *)label); + + mirror = (flip_x ? PCB_TXT_MIRROR_X : 0) | (flip_y ? PCB_TXT_MIRROR_Y : 0); + direction = (vert ? 1 : 0); + + if (!conf_core.appearance.smart_labels) { + + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.pin_name); + + if (rnd_render->gui) + pcb_draw_force_termlab++; + pcb_text_draw_string(info, font, (unsigned const char *)label, x, y, scale/100, scale/100, direction*90.0, mirror, conf_core.appearance.label_thickness, 0, 0, 0, 0, PCB_TXT_TINY_HIDE); + if (rnd_render->gui) + pcb_draw_force_termlab--; + } + else + pcb_label_smart_add(info, x, y, scale/100.0, direction*90.0, mirror, w, h, label, prio); +} + + +void pcb_label_invalidate(rnd_coord_t x, rnd_coord_t y, double scale, rnd_bool vert, rnd_bool centered, const char *label) +{ + rnd_coord_t ox = x, oy = y, margin = 0; + rnd_box_t b; + PCB_TERM_LABEL_SETUP((const unsigned char *)label); + + dx = RND_ABS(dx); + dy = RND_ABS(dy); + b.X1 = ox - dx - margin; + b.X2 = ox + dx + margin; + b.Y1 = oy - dy - margin; + b.Y2 = oy + dy + margin; + + pcb_draw_invalidate(&b); +} + +void pcb_term_label_draw(pcb_draw_info_t *info, rnd_coord_t x, rnd_coord_t y, double scale, rnd_bool vert, rnd_bool centered, const pcb_any_obj_t *obj) +{ + char buff[128]; + int prio = 1; /* slightly lower prio than subc */ + int on_bottom, flips; + const char *label = lab_with_intconn(obj, obj->intconn, obj->term, buff, sizeof(buff)); + + flips = !!(rnd_conf.editor.view.flip_x ^ rnd_conf.editor.view.flip_y); + + switch(obj->type) { + case PCB_OBJ_PSTK: /* top prio */ + break; + case PCB_OBJ_LINE: + case PCB_OBJ_ARC: + case PCB_OBJ_TEXT: + case PCB_OBJ_POLY: + case PCB_OBJ_GFX: + on_bottom = !!(pcb_layer_flags_(obj->parent.layer) & PCB_LYT_BOTTOM); + if (on_bottom == flips) + prio += 1; + else + prio += 2; /* other-side object penalty */ + break; + default: + prio += 10; + } + pcb_label_draw(info, x, y, scale, vert, centered, label, prio); +} + +void pcb_term_label_invalidate(rnd_coord_t x, rnd_coord_t y, double scale, rnd_bool vert, rnd_bool centered, const pcb_any_obj_t *obj) +{ + char buff[128]; + const char *label = lab_with_intconn(obj, obj->intconn, obj->term, buff, sizeof(buff)); + pcb_label_invalidate(x, y, scale, vert, centered, label); +} + Index: tags/2.3.0/src/draw.h =================================================================== --- tags/2.3.0/src/draw.h (nonexistent) +++ tags/2.3.0/src/draw.h (revision 33253) @@ -0,0 +1,189 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2004 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_DRAW_H +#define PCB_DRAW_H + +#include "config.h" +#include +#include "layer.h" + +/* holds information about output window */ +typedef struct { + rnd_hid_t *hid; + rnd_hid_gc_t drillGC, fgGC, pmGC; /* changed from some routines */ + rnd_hid_gc_t active_padGC, backpadGC, padGC, padselGC; /* pads are drawn with this gc */ + unsigned direct:1; /* starts as 1 and becomes 0 before the first compositing layer group is reset */ +} pcb_output_t; + +extern pcb_output_t pcb_draw_out; + +typedef enum { + PCB_PHOLE_PLATED = 1, + PCB_PHOLE_UNPLATED = 2, + PCB_PHOLE_BB = 4 +} pcb_pstk_draw_hole_t; + +/* Some low level draw callback depend on this in their void *cl */ +typedef struct pcb_draw_info_s { + pcb_board_t *pcb; + int exporting; /* 1 if doing an export, 0 if working to screen */ + const char *export_name; /* name of the export plugin */ + char noexport_name[64]; /* "noexport:" attribute name rendered for the current exporter */ + const rnd_box_t *drawn_area; + rnd_xform_t *xform_caller; /* the extra transformation the caller requested (the one who has initiated the rendering, e.g. throuh pcb_draw_everything()) */ + rnd_xform_t *xform_exporter; /* the extra transformation the exporter requested (e.g. because of cam) */ + rnd_xform_t *xform; /* the final transformation applied on objects */ + + const pcb_layer_t *layer; + + union { /* fields used for specific object callbacks */ + struct { + rnd_layergrp_id_t gid; + int is_current; + pcb_pstk_draw_hole_t holetype; + pcb_layer_combining_t comb; + const pcb_layer_t *layer1; /* first (real) layer in the target group */ + + pcb_layer_type_t shape_mask; /* when gid is invalid, use this for the shapes */ + } pstk; + struct { + int per_side; + } subc; + } objcb; +} pcb_draw_info_t; + +/* Temporarily inhibid drawing if this is non-zero. A function that calls a + lot of other functions that would call pcb_draw() a lot in turn may increase + this value before the calls, then decrease it at the end and call pcb_draw(). + This makes sure the whole block is redrawn only once at the end. */ +extern rnd_cardinal_t pcb_draw_inhibit; + +#define pcb_draw_inhibit_inc() pcb_draw_inhibit++ +#define pcb_draw_inhibit_dec() \ +do { \ + if (pcb_draw_inhibit > 0) \ + pcb_draw_inhibit--; \ +} while(0) \ + +/* When true, do not draw terminals but put them on the obj delay list + using pcb_draw_delay_obj_add() - used to delay heavy terminal drawing + to get proper overlaps */ +extern rnd_bool delayed_terms_enabled; +void pcb_draw_delay_obj_add(pcb_any_obj_t *obj); + +/* Append an object to the annotatation list; annotations are drawn at the + end, after labels */ +void pcb_draw_annotation_add(pcb_any_obj_t *obj); + +/* the minimum box that needs to be redrawn */ +extern rnd_box_t pcb_draw_invalidated; + +/* Adds the update rect to the invalidated region. This schedules the object + for redraw (by pcb_draw()). obj is anything that can be casted to rnd_box_t */ +#define pcb_draw_invalidate(obj) \ +do { \ + rnd_box_t *box = (rnd_box_t *)obj; \ + pcb_draw_invalidated.X1 = MIN(pcb_draw_invalidated.X1, box->X1); \ + pcb_draw_invalidated.X2 = MAX(pcb_draw_invalidated.X2, box->X2); \ + pcb_draw_invalidated.Y1 = MIN(pcb_draw_invalidated.Y1, box->Y1); \ + pcb_draw_invalidated.Y2 = MAX(pcb_draw_invalidated.Y2, box->Y2); \ +} while(0) + +extern int pcb_draw_force_termlab; /* force drawing terminal lables - useful for pinout previews */ +extern rnd_bool pcb_draw_doing_assy; + +void pcb_lighten_color(const rnd_color_t *orig, rnd_color_t *dst, double factor); + +/* Draw a series of short line segments emulating a dashed line. segs is + the number of on/off segment pairs. It is guaranteed that the line starts + and ends with an "on" line segment. If cheap is true, allow drawing less + segments if the line is short */ +void pcb_draw_dashed_line(pcb_draw_info_t *info, rnd_hid_gc_t GC, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, unsigned int segs, rnd_bool_t cheap); + + +void pcb_draw(void); +void pcb_draw_obj(pcb_any_obj_t *obj); +void pcb_draw_layer(pcb_draw_info_t *info, const pcb_layer_t *ly); +void pcb_draw_layer_noxform(pcb_board_t *pcb, const pcb_layer_t *ly, const rnd_box_t *screen); + +/* Same as pcb_draw_layer(), but never draws an implicit outline and ignores + objects that are not in the subtree of data - useful for drawing a subtree, + e.g. a subc only */ +void pcb_draw_layer_under(pcb_board_t *pcb, const pcb_layer_t *Layer, const rnd_box_t *screen, pcb_data_t *data, rnd_xform_t *xform); + +/* Composite draw all layer groups matching lyt/purpi/purpose */ +void pcb_draw_groups(rnd_hid_t *hid, pcb_board_t *pcb, pcb_layer_type_t lyt, int purpi, char *purpose, const rnd_box_t *screen, const rnd_color_t *default_color, pcb_layer_type_t pstk_lyt_match, int thin_draw, int invert); + + +void pcb_erase_obj(int, void *, void *); +void pcb_draw_pstk_names(pcb_draw_info_t *info, rnd_layergrp_id_t group, const rnd_box_t *drawn_area); + +/*#define PCB_BBOX_DEBUG*/ + +#ifdef PCB_BBOX_DEBUG +#define PCB_DRAW_BBOX(obj) \ + do { \ + rnd_hid_set_line_width(pcb_draw_out.fgGC, 0); \ + rnd_render->draw_rect(pcb_draw_out.fgGC, obj->BoundingBox.X1, obj->BoundingBox.Y1, obj->BoundingBox.X2, obj->BoundingBox.Y2); \ + } while(0) +#else +#define PCB_DRAW_BBOX(obj) +#endif + + +/* Returns whether lay_id is part of a group that is composite-drawn */ +int pcb_draw_layer_is_comp(rnd_layer_id_t lay_id); + +/* Returns whether a group is composite-drawn */ +int pcb_draw_layergrp_is_comp(const pcb_layergrp_t *g); + +/* Draw (render) or invalidate a terminal label */ +void pcb_term_label_draw(pcb_draw_info_t *info, rnd_coord_t x, rnd_coord_t y, double scale, rnd_bool vert, rnd_bool centered, const pcb_any_obj_t *obj); +void pcb_term_label_invalidate(rnd_coord_t x, rnd_coord_t y, double scale, rnd_bool vert, rnd_bool centered, const pcb_any_obj_t *obj); +void pcb_label_draw(pcb_draw_info_t *info, rnd_coord_t x, rnd_coord_t y, double scale, rnd_bool vert, rnd_bool centered, const char *label, int prio); +void pcb_label_invalidate(rnd_coord_t x, rnd_coord_t y, double scale, rnd_bool vert, rnd_bool centered, const char *label); + + +void pcb_draw_setup_default_xform_info(rnd_hid_t *hid, pcb_draw_info_t *info); +void pcb_draw_setup_default_gui_xform(rnd_xform_t *dst); + + +/* Schedule an object to be called again at the end for drawing its labels + on top of everything. */ +void pcb_draw_delay_label_add(pcb_any_obj_t *obj); + +/* Return non-zero if extra terminal graphics should be drawn */ +#define pcb_draw_term_need_gfx(obj) \ + (((obj)->term != NULL) && !PCB_FLAG_TEST(PCB_FLAG_FOUND, (obj)) && !PCB_FLAG_TEST(PCB_FLAG_WARN, (obj)) && !PCB_FLAG_TEST(PCB_FLAG_SELECTED, (obj))) + +#define pcb_draw_term_hid_permission() (rnd_gui->heavy_term_layer_ind) + +#define PCB_DRAW_TERM_GFX_WIDTH (-3) + +#endif Index: tags/2.3.0/src/draw_composite.c =================================================================== --- tags/2.3.0/src/draw_composite.c (nonexistent) +++ tags/2.3.0/src/draw_composite.c (revision 33253) @@ -0,0 +1,226 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2003, 2004 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Local functions to draw a layer group as a composite of logical layers + using positive and negative draw operations. Included from draw.c. */ + +typedef struct comp_ctx_s { + pcb_draw_info_t *info; + const pcb_layergrp_t *grp; + rnd_layergrp_id_t gid; + const rnd_color_t *color; + + unsigned thin:1; + unsigned invert:1; +} comp_ctx_t; + +static void comp_fill_board(comp_ctx_t *ctx) +{ + rnd_render->set_color(pcb_draw_out.fgGC, ctx->color); + if (ctx->info->drawn_area == NULL) + rnd_render->fill_rect(pcb_draw_out.fgGC, 0, 0, ctx->info->pcb->hidlib.size_x, ctx->info->pcb->hidlib.size_y); + else + rnd_render->fill_rect(pcb_draw_out.fgGC, ctx->info->drawn_area->X1, ctx->info->drawn_area->Y1, ctx->info->drawn_area->X2, ctx->info->drawn_area->Y2); +} + +static void comp_start_sub_(comp_ctx_t *ctx) +{ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_NEGATIVE, pcb_draw_out.direct, ctx->info->drawn_area); +} + +static void comp_start_add_(comp_ctx_t *ctx) +{ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, ctx->info->drawn_area); +} + +static void comp_start_sub(comp_ctx_t *ctx) +{ + if (ctx->thin) { + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, ctx->info->drawn_area); + rnd_render->set_color(pcb_draw_out.pmGC, ctx->color); + return; + } + + if (ctx->invert) + comp_start_add_(ctx); + else + comp_start_sub_(ctx); +} + +static void comp_start_add(comp_ctx_t *ctx) +{ + if (ctx->thin) { + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, ctx->info->drawn_area); + return; + } + + if (ctx->invert) + comp_start_sub_(ctx); + else + comp_start_add_(ctx); +} + +static void comp_finish(comp_ctx_t *ctx) +{ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, ctx->info->drawn_area); +} + +static void comp_init(comp_ctx_t *ctx, int negative) +{ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, ctx->info->drawn_area); + + if (ctx->thin) + return; + + if (ctx->invert) + negative = !negative; + + if ((!ctx->thin) && (negative)) { + /* drawing the big poly for the negative */ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, ctx->info->drawn_area); + comp_fill_board(ctx); + } +} + +/* Real composite draw: if any layer is negative, we have to use the HID API's + composite layer draw mechanism */ +static void comp_draw_layer_real(comp_ctx_t *ctx, void (*draw_auto)(comp_ctx_t *ctx, void *data), void *auto_data) +{ /* generic multi-layer rendering */ + int n, adding = -1; + pcb_layer_t *l = pcb_get_layer(PCB->Data, ctx->grp->lid[0]); + comp_init(ctx, (l->comb & PCB_LYC_SUB)); + + for(n = 0; n < ctx->grp->len; n++) { + int want_add; + l = pcb_get_layer(PCB->Data, ctx->grp->lid[n]); + + want_add = ctx->thin || !(l->comb & PCB_LYC_SUB); + if (want_add != adding) { + if (want_add) + comp_start_add(ctx); + else + comp_start_sub(ctx); + adding = want_add; + } + + { + rnd_hid_gc_t old_fg = pcb_draw_out.fgGC; + pcb_draw_out.fgGC = pcb_draw_out.pmGC; + if ((l->comb & PCB_LYC_AUTO) && (draw_auto != NULL)) + draw_auto(ctx, auto_data); + pcb_draw_layer(ctx->info, l); + pcb_draw_out.fgGC = old_fg; + } + } + if (!adding) + comp_start_add(ctx); +} + +int pcb_draw_layergrp_is_comp(const pcb_layergrp_t *g) +{ + int n; + + /* as long as we are doing only positive compositing, we can go without compositing */ + for(n = 0; n < g->len; n++) + if (PCB->Data->Layer[g->lid[n]].comb & (PCB_LYC_SUB)) + return 1; + + return 0; +} + +int pcb_draw_layer_is_comp(rnd_layer_id_t id) +{ + pcb_layergrp_t *g = pcb_get_layergrp(PCB, PCB->Data->Layer[id].meta.real.grp); + if (g == NULL) return 0; + return pcb_draw_layergrp_is_comp(g); +} + +/* Draw a layer group with fake or real compositing */ +static void comp_draw_layer(comp_ctx_t *ctx, void (*draw_auto)(comp_ctx_t *ctx, void *data), void *auto_data) +{ + int is_comp = pcb_draw_layergrp_is_comp(ctx->grp); + + if (is_comp) + pcb_draw_out.direct = 0; + + comp_draw_layer_real(ctx, draw_auto, auto_data); +} + +/******** generic group draws ********/ + +static void pcb_draw_groups_auto(comp_ctx_t *ctx, void *lym) +{ + pcb_layer_type_t *pstk_lyt_match = (pcb_layer_type_t *)lym; + if ((ctx->info->pcb->pstk_on) && (*pstk_lyt_match != 0)) + pcb_draw_pstks(ctx->info, ctx->gid, 0, *pstk_lyt_match); +} + +void pcb_draw_groups(rnd_hid_t *hid, pcb_board_t *pcb, pcb_layer_type_t lyt, int purpi, char *purpose, const rnd_box_t *screen, const rnd_color_t *default_color, pcb_layer_type_t pstk_lyt_match, int thin_draw, int invert) +{ + pcb_draw_info_t info; + rnd_layergrp_id_t gid; + pcb_layergrp_t *g; + comp_ctx_t cctx; + rnd_xform_t tmp; + + memset(&info, 0, sizeof(info)); + info.pcb = pcb; + info.drawn_area = screen; + + pcb_draw_setup_default_xform_info(hid, &info); + xform_setup(&info, &tmp, NULL); + + for(gid = 0, g = pcb->LayerGroups.grp; gid < pcb->LayerGroups.len; gid++,g++) { + pcb_layer_t *ly = NULL; + + if ((g->ltype & lyt) != lyt) + continue; + + if ((purpi != -1) && (g->purpi != purpi)) + continue; + + if ((purpose != NULL) && (strcmp(g->purpose, purpose) != 0)) + continue; + + if (g->len > 0) + ly = pcb_get_layer(PCB->Data, g->lid[0]); + info.layer = ly; + cctx.grp = g; + cctx.info = &info; + cctx.gid = gid; + cctx.color = ly != NULL ? &ly->meta.real.color : default_color; + cctx.thin = thin_draw; + cctx.invert = invert; + + if (!cctx.invert) + pcb_draw_out.direct = 0; + + comp_draw_layer(&cctx, pcb_draw_groups_auto, &pstk_lyt_match); + comp_finish(&cctx); + } +} Index: tags/2.3.0/src/draw_label_smart.c =================================================================== --- tags/2.3.0/src/draw_label_smart.c (nonexistent) +++ tags/2.3.0/src/draw_label_smart.c (revision 33253) @@ -0,0 +1,176 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +typedef struct pcb_smart_label_s pcb_smart_label_t; + +struct pcb_smart_label_s { + rnd_box_t bbox; + rnd_coord_t x; + rnd_coord_t y; + double scale; + double rot; + int prio; + rnd_bool mirror; + rnd_coord_t w; + rnd_coord_t h; + pcb_smart_label_t *next; + char label[1]; /* dynamic length array */ +}; + +static pcb_smart_label_t *smart_labels = NULL; + +RND_INLINE void pcb_label_smart_add(pcb_draw_info_t *info, rnd_coord_t x, rnd_coord_t y, double scale, double rot, rnd_bool mirror, rnd_coord_t w, rnd_coord_t h, const char *label, int prio) +{ + int len = strlen(label); + pcb_smart_label_t *l = malloc(sizeof(pcb_smart_label_t) + len + 1); + + l->x = x; l->y = y; + l->scale = scale; + l->rot = rot; + l->mirror = mirror; + l->w = w; l->h = h; + l->prio = prio; + memcpy(l->label, label, len+1); + + l->next = smart_labels; + smart_labels = l; +} + +/* returns 1 if x;y was suitable and the label could be placed */ +RND_INLINE int lsm_shuffle_try(rnd_rtree_t *rt, pcb_smart_label_t *l, rnd_coord_t x, rnd_coord_t y) +{ + rnd_box_t b; + rnd_rtree_it_t it; + + b.X1 = x; b.Y1 = y; + b.X2 = x + l->w; b.Y2 = y + l->h; + + if (rnd_rtree_first(&it, rt, (rnd_rtree_box_t *)&b) != NULL) + return 0; + + l->bbox = b; + rnd_rtree_insert(rt, (void *)l, (rnd_rtree_box_t *)l); + return 1; +} + +RND_INLINE void lsm_shuffle(rnd_rtree_t *rt, pcb_smart_label_t *l) +{ + int nx, ny; + rnd_coord_t dx, dy, step = RND_MM_TO_COORD(0.25); + + rnd_rtree_delete(rt, (void *)l, (rnd_rtree_box_t *)l); + + /* try 0;0, maybe other objects got moved out of the way */ + if (lsm_shuffle_try(rt, l, l->x, l->y)) + return; + + /* try a few locations as close as possible */ + for(ny = 1; ny < 16*2; ny++) { + dy = step * ny / 2; + if (ny % 2) dy = -dy; + for(nx = 1; nx < 16*2; nx++) { + dx = step * nx / 2; + if (nx % 2) dx = -dx; + if (lsm_shuffle_try(rt, l, l->x + dx, l->y + dy)) + return; + } + } + + /* all failed, place it back on the wrong place */ + rnd_rtree_insert(rt, (void *)l, (rnd_rtree_box_t *)l); +} + + +RND_INLINE void lsm_place(rnd_rtree_t *rt, pcb_smart_label_t *l) +{ + rnd_rtree_it_t it; + pcb_smart_label_t *c; + int n, tries = 0; + + /* check if there's any collision with a higher prio label; if so, this label has to be moved */ + for(c = rnd_rtree_first(&it, rt, (rnd_rtree_box_t *)l); c != NULL; c = rnd_rtree_next(&it)) { + if (c->prio < l->prio) { + lsm_shuffle(rt, l); + return; + } + tries += 2; + } + + if (tries == 0) { + /* no collision, just place */ + rnd_rtree_insert(rt, (void *)l, (rnd_rtree_box_t *)l); + return; + } + + /* this seems to be the highest prio label around, shuffle the rest */ + rnd_rtree_insert(rt, (void *)l, (rnd_rtree_box_t *)l); + for(n = 0; n < tries; n++) { + for(c = rnd_rtree_first(&it, rt, (rnd_rtree_box_t *)l); c != NULL; c = rnd_rtree_next(&it)) { + lsm_shuffle(rt, c); + break; + } + } +} + + +RND_INLINE void pcb_label_smart_flush(pcb_draw_info_t *info) +{ + pcb_smart_label_t *l, *next; + pcb_font_t *font; + rnd_rtree_t rt; + + if (smart_labels == NULL) return; + + rnd_rtree_init(&rt); + font = pcb_font(PCB, 0, 0); + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.pin_name); + if (rnd_render->gui) + pcb_draw_force_termlab++; + + for(l = smart_labels; l != NULL; l = l->next) { + l->bbox.X1 = l->x; l->bbox.Y1 = l->y; + l->bbox.X2 = l->x + l->w; l->bbox.Y2 = l->y + l->h; + lsm_place(&rt, l); + } + + + for(l = smart_labels; l != NULL; l = next) { + next = l->next; + pcb_text_draw_string(info, font, (unsigned const char *)l->label, l->bbox.X1, l->bbox.Y1, l->scale, l->scale, l->rot, l->mirror, conf_core.appearance.label_thickness, 0, 0, 0, 0, PCB_TXT_TINY_HIDE); + if ((l->bbox.X1 != l->x) || (l->bbox.Y1 != l->y)) { + rnd_coord_t dx = l->w/2, dy = l->h/2; + rnd_render->draw_line(pcb_draw_out.fgGC, l->bbox.X1+dx, l->bbox.Y1+dy, l->x+dx, l->y+dy); + } + free(l); + } + smart_labels = NULL; + rnd_rtree_uninit(&rt); + + if (rnd_render->gui) + pcb_draw_force_termlab--; +} Index: tags/2.3.0/src/draw_ly_spec.c =================================================================== --- tags/2.3.0/src/draw_ly_spec.c (nonexistent) +++ tags/2.3.0/src/draw_ly_spec.c (revision 33253) @@ -0,0 +1,354 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2003, 2004 Thomas Nau + * Copyright (C) 2017,2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Local functions for special layer draw logics. This code is not generic; + instead it collects all the hardwired heuristics for the special layers. + Included from draw.c. */ + +/******** paste ********/ + +static void pcb_draw_paste_auto_(comp_ctx_t *ctx, void *side) +{ + if (PCB->pstk_on) + pcb_draw_pstks(ctx->info, ctx->gid, 0, PCB_LYC_AUTO); +} + +static void pcb_draw_paste(pcb_draw_info_t *info, int side) +{ + unsigned long side_lyt = side ? PCB_LYT_TOP : PCB_LYT_BOTTOM; + rnd_layergrp_id_t gid = -1; + comp_ctx_t cctx; + pcb_layer_t *ly = NULL; + rnd_xform_t tmp; + + xform_setup(info, &tmp, NULL); + + pcb_layergrp_list(info->pcb, PCB_LYT_PASTE | side_lyt, &gid, 1); + + cctx.grp = pcb_get_layergrp((pcb_board_t *)info->pcb, gid); + + if (cctx.grp->len > 0) + ly = pcb_get_layer(info->pcb->Data, cctx.grp->lid[0]); + + cctx.info = info; + cctx.gid = gid; + cctx.color = ly != NULL ? &ly->meta.real.color : &conf_core.appearance.color.paste; + cctx.thin = (info->xform != NULL) && (info->xform->thin_draw || info->xform->thin_draw_poly || info->xform->wireframe); + cctx.invert = 0; + + if ((cctx.grp == NULL) || (cctx.grp->len == 0)) { /* fallback: no layers -> original code: draw a single auto-add */ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); + } + else { + comp_draw_layer(&cctx, pcb_draw_paste_auto_, &side); + comp_finish(&cctx); + } + info->xform = NULL; info->layer = NULL; +} + +/******** mask ********/ +static void pcb_draw_mask_auto(comp_ctx_t *ctx, void *side) +{ + if (PCB->pstk_on) + pcb_draw_pstks(ctx->info, ctx->gid, 0, PCB_LYC_SUB | PCB_LYC_AUTO); +} + +static void pcb_draw_mask(pcb_draw_info_t *info, int side) +{ + unsigned long side_lyt = side ? PCB_LYT_TOP : PCB_LYT_BOTTOM; + rnd_layergrp_id_t gid = -1; + comp_ctx_t cctx; + pcb_layer_t *ly = NULL; + rnd_xform_t tmp; + + xform_setup(info, &tmp, NULL); + + pcb_layergrp_list(PCB, PCB_LYT_MASK | side_lyt, &gid, 1); + + cctx.grp = pcb_get_layergrp(PCB, gid); + + if (cctx.grp->len > 0) + ly = pcb_get_layer(PCB->Data, cctx.grp->lid[0]); + + cctx.info = info; + cctx.gid = gid; + cctx.color = ly != NULL ? &ly->meta.real.color : &conf_core.appearance.color.mask; + cctx.thin = (info->xform != NULL) && (info->xform->thin_draw || info->xform->thin_draw_poly || info->xform->wireframe); + cctx.invert = rnd_render->mask_invert; + + if (!cctx.invert) + pcb_draw_out.direct = 0; + + if ((cctx.grp == NULL) || (cctx.grp->len == 0)) { /* fallback: no layers -> original code: draw a single auto-sub */ + comp_init(&cctx, 1); + comp_start_sub(&cctx); + pcb_draw_mask_auto(&cctx, &side); + comp_start_add(&cctx); + } + else + comp_draw_layer(&cctx, pcb_draw_mask_auto, &side); + comp_finish(&cctx); + info->xform = NULL; info->layer = NULL; +} + +/******** silk ********/ + +static void pcb_draw_silk_auto(comp_ctx_t *ctx, void *lyt_side) +{ + if (PCB->pstk_on) + pcb_draw_pstks(ctx->info, ctx->gid, 0, PCB_LYC_AUTO); +} + +static int pcb_is_silk_old_style(comp_ctx_t *cctx, rnd_layer_id_t lid) +{ + if (cctx->grp == NULL) + return 1; /* no group means no silk -> fall back to implicit */ + + if ((cctx->grp->len == 1) && ((PCB->Data->Layer[lid].comb & (PCB_LYC_AUTO | PCB_LYC_SUB)) == PCB_LYC_AUTO)) + return 1; /* A single auto-positive layer -> original code: draw auto+manual */ + + return 0; +} + +static void pcb_draw_silk_doc(pcb_draw_info_t *info, pcb_layer_type_t lyt_side, pcb_layer_type_t lyt_type, int setgrp, int invis) +{ + rnd_layer_id_t lid; + rnd_layergrp_id_t gid[PCB_MAX_LAYERGRP]; + comp_ctx_t cctx; + int len, n; + + len = pcb_layergrp_list(info->pcb, lyt_type | lyt_side, gid, PCB_MAX_LAYERGRP); + if (len < 1) + return; + + for(n = 0; n < len; n++) { + pcb_layergrp_t *grp = &info->pcb->LayerGroups.grp[gid[n]]; + pcb_layer_t *ly = NULL; + + /* Special case: 'global' location is not a specific location bit but + lack of location bits; for that case listing will return every group + and we need to filter by hand */ + if ((lyt_side == 0) && ((grp->ltype & PCB_LYT_ANYWHERE) != 0)) + continue; + + /* workaround: in direct export group visibility is not really set + but layer visibility is set; if they are contradicting, it's enough + if either is set. Assume all layers are visible or invisible within + a group, so depend only on the first layer */ + if (grp->len > 0) + ly = pcb_get_layer(info->pcb->Data, grp->lid[0]); + if ((!grp->vis) && ((ly == NULL) || (!ly->meta.real.vis))) + continue; + + if (setgrp) + if (!pcb_layer_gui_set_glayer(info->pcb, gid[n], 0, &info->xform_exporter)) + continue; + + cctx.info = info; + cctx.gid = gid[n]; + cctx.grp = pcb_get_layergrp((pcb_board_t *)info->pcb, gid[n]); + if ((lyt_side == 0) && (cctx.grp->ltype & PCB_LYT_ANYWHERE) != 0) /* special case for global */ + continue; + if (cctx.grp->len == 0) + continue; + lid = cctx.grp->lid[0]; + cctx.color = invis ? &conf_core.appearance.color.invisible_objects : &info->pcb->Data->Layer[lid].meta.real.color; + cctx.thin = (info->xform != NULL) && (info->xform->thin_draw || info->xform->thin_draw_poly || info->xform->wireframe); + cctx.invert = 0; + + if ((lyt_type & PCB_LYT_SILK) && (pcb_is_silk_old_style(&cctx, lid))) { + /* fallback: implicit layer -> original code: draw auto+manual */ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + pcb_draw_layer(info, pcb_get_layer(info->pcb->Data, lid)); + pcb_draw_silk_auto(&cctx, &lyt_side); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); + } + else { + comp_draw_layer(&cctx, pcb_draw_silk_auto, &lyt_side); + comp_finish(&cctx); + } + if (setgrp) + rnd_render->end_layer(rnd_render); + } +} + +static void remember_slot(pcb_layer_t **uslot, pcb_layer_t **pslot, int *uscore, int *pscore, const pcb_layergrp_t *g, pcb_layer_t *ly) +{ + int score; + pcb_layer_t **dslot; + int *dscore; + + if (!(ly->comb & PCB_LYC_AUTO)) + return; + + if (g->purpi == F_uroute) { + dslot = uslot; + dscore = uscore; + } + else if (g->purpi == F_proute) { + dslot = pslot; + dscore = pscore; + } + else + return; + + if (g->ltype & PCB_LYT_BOUNDARY) score = 1; + if (g->ltype & PCB_LYT_MECH) score = 2; + + if (score > *dscore) { + *dscore = score; + *dslot = ly; + } +} + +static void pcb_draw_boundary_mech(pcb_draw_info_t *info) +{ + int count = 0; + rnd_layergrp_id_t gid, goutid; + const pcb_layergrp_t *g, *goutl = NULL; + pcb_layer_t *uslot = NULL, *pslot = NULL; + int uscore = 0, pscore = 0; + int plated, unplated; + + for(gid = 0, g = info->pcb->LayerGroups.grp; gid < info->pcb->LayerGroups.len; gid++,g++) { + int n, numobj; + + if ((g->ltype & PCB_LYT_BOUNDARY) && (g->purpi == F_uroute)) { + goutl = g; + goutid = gid; + } + + if (!(g->ltype & (PCB_LYT_BOUNDARY | PCB_LYT_MECH)) || (g->len < 1)) + continue; + + /* Count whether there are objects on any boundary layer: + don't count the objects drawn, but the objects the layer has; + zooming in the middle doesn't mean we need to have the implicit + outline */ + numobj = 0; + for(n = 0; n < g->len; n++) { + pcb_layer_t *ly = pcb_get_layer(info->pcb->Data, g->lid[n]); + if (ly->line_tree != NULL) + numobj += ly->line_tree->size; + if (ly->arc_tree != NULL) + numobj += ly->arc_tree->size; + if (ly->text_tree != NULL) + numobj += ly->text_tree->size; + if (ly->polygon_tree != NULL) + numobj += ly->polygon_tree->size; + remember_slot(&uslot, &pslot, &uscore, &pscore, g, ly); + } + count += numobj; + + if (pcb_layer_gui_set_layer(gid, g, (numobj == 0), &info->xform_exporter)) { + /* boundary does NOT support compisiting, everything is drawn in positive */ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + for(n = 0; n < g->len; n++) { + pcb_layer_t *ly = pcb_get_layer(info->pcb->Data, g->lid[n]); + pcb_draw_layer(info, ly); + } + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); + rnd_render->end_layer(rnd_render); + } + } + + if ((count == 0) && (goutl != NULL) && (pcb_layer_gui_set_layer(goutid, goutl, 0, &info->xform))) { + /* The implicit outline rectangle (or automatic outline rectanlge). + We should check for rnd_render->gui here, but it's kinda cool seeing the + auto-outline magically disappear when you first add something to + the outline layer. */ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + + rnd_render->set_color(pcb_draw_out.fgGC, &PCB->Data->Layer[goutl->lid[0]].meta.real.color); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); + rnd_hid_set_line_width(pcb_draw_out.fgGC, conf_core.design.min_wid); + rnd_render->draw_rect(pcb_draw_out.fgGC, 0, 0, PCB->hidlib.size_x, PCB->hidlib.size_y); + + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); + rnd_render->end_layer(rnd_render); + } + + /* draw slots */ + if (((uslot == NULL) || (!uslot->meta.real.vis)) && ((pslot == NULL) || (!pslot->meta.real.vis))) + return; + + pcb_board_count_slots(PCB, &plated, &unplated, info->drawn_area); + + if ((uslot != NULL) && (uslot->meta.real.vis)) { + if (pcb_layer_gui_set_glayer(PCB, uslot->meta.real.grp, unplated <= 0, &info->xform)) { + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + pcb_draw_pstk_slots(info, uslot->meta.real.grp, PCB_PHOLE_UNPLATED | PCB_PHOLE_BB); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); + rnd_render->end_layer(rnd_render); + } + } + if ((pslot != NULL) && (pslot->meta.real.vis)) { + if (pcb_layer_gui_set_glayer(PCB, pslot->meta.real.grp, plated <= 0, &info->xform)) { + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, info->drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, info->drawn_area); + pcb_draw_pstk_slots(info, pslot->meta.real.grp, PCB_PHOLE_PLATED | PCB_PHOLE_BB); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, info->drawn_area); + rnd_render->end_layer(rnd_render); + } + } +} + + +/******** misc ********/ + +static void pcb_draw_rats(pcb_draw_info_t *info, const rnd_box_t *drawn_area) +{ + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_RESET, pcb_draw_out.direct, drawn_area); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_POSITIVE, pcb_draw_out.direct, drawn_area); + rnd_r_search(PCB->Data->rat_tree, drawn_area, NULL, pcb_rat_draw_callback, info, NULL); + rnd_render->set_drawing_mode(rnd_render, RND_HID_COMP_FLUSH, pcb_draw_out.direct, drawn_area); +} + +static void pcb_draw_assembly(pcb_draw_info_t *info, pcb_layer_type_t lyt_side) +{ + rnd_layergrp_id_t side_group; + + if (pcb_layergrp_list(PCB, PCB_LYT_COPPER | lyt_side, &side_group, 1) != 1) + return; + + pcb_draw_doing_assy = rnd_true; + rnd_hid_set_draw_faded(pcb_draw_out.fgGC, 1); + pcb_draw_layer_grp(info, side_group, 0); + rnd_hid_set_draw_faded(pcb_draw_out.fgGC, 0); + + /* draw package */ + pcb_draw_silk_doc(info, lyt_side, PCB_LYT_SILK, 0, 0); + pcb_draw_doing_assy = rnd_false; +} Index: tags/2.3.0/src/draw_wireframe.h =================================================================== --- tags/2.3.0/src/draw_wireframe.h (nonexistent) +++ tags/2.3.0/src/draw_wireframe.h (revision 33253) @@ -0,0 +1,111 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#ifndef PCB_DRAW_WIREFRAME_H +#define PCB_DRAW_WIREFRAME_H + +#include "config.h" +#include + +/*----------------------------------------------------------- + * Draws the outline of an arc + */ +RND_INLINE void pcb_draw_wireframe_arc(rnd_hid_gc_t gc, pcb_arc_t *arc, rnd_coord_t thick) +{ + rnd_coord_t wid = thick / 2; + rnd_coord_t x1, y1, x2, y2; + + if ((arc->Width == 0) && (arc->Height == 0)) { + rnd_render->draw_arc(gc, arc->X, arc->Y, wid, wid, 0, 360); + return; + } + + pcb_arc_get_end(arc, 0, &x1, &y1); + pcb_arc_get_end(arc, 1, &x2, &y2); + + rnd_render->draw_arc(gc, arc->X, arc->Y, arc->Width + wid, arc->Height + wid, arc->StartAngle, arc->Delta); + if (wid > rnd_pixel_slop) { + rnd_coord_t w = (wid < arc->Width) ? (arc->Width - wid) : 0; + rnd_coord_t h = (wid < arc->Height) ? (arc->Height - wid) : 0; + rnd_render->draw_arc(gc, arc->X, arc->Y, w, h, arc->StartAngle, arc->Delta); + rnd_render->draw_arc(gc, x1, y1, wid, wid, arc->StartAngle, -180 * SGN(arc->Delta)); + rnd_render->draw_arc(gc, x2, y2, wid, wid, arc->StartAngle + arc->Delta, 180 * SGN(arc->Delta)); + } +} + +/*----------------------------------------------------------- + * Draws the outline of a line + */ +RND_INLINE void pcb_draw_wireframe_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t thick, int square) +{ + if((x1 != x2) || (y1 != y2)) { + double dx = x2 - x1; + double dy = y2 - y1; + double h = 0.5 * thick / sqrt(RND_SQUARE(dx) + RND_SQUARE(dy)); + rnd_coord_t ox = dy * h + 0.5 * SGN(dy); + rnd_coord_t oy = -(dx * h + 0.5 * SGN(dx)); + if (square) { + /* make the line longer by cap */ + x1 -= dx * h; + x2 += dx * h; + y1 -= dy * h; + y2 += dy * h; + } + if ((coord_abs(ox) >= rnd_pixel_slop) || (coord_abs(oy) >= rnd_pixel_slop)) { + rnd_render->draw_line(gc, x1 + ox, y1 + oy, x2 + ox, y2 + oy); + rnd_render->draw_line(gc, x1 - ox, y1 - oy, x2 - ox, y2 - oy); + + /* draw caps */ + if (!square) { + rnd_angle_t angle = atan2(dx, dy) * 57.295779; + rnd_render->draw_arc(gc, x1, y1, thick / 2, thick / 2, angle - 180, 180); + rnd_render->draw_arc(gc, x2, y2, thick / 2, thick / 2, angle, 180); + } + else { + rnd_render->draw_line(gc, x1 + ox, y1 + oy, x1 - ox, y1 - oy); + rnd_render->draw_line(gc, x2 + ox, y2 + oy, x2 - ox, y2 - oy); + } + } + else + rnd_render->draw_line(gc, x1, y1, x2, y2); + } + else { + if (square) { + /* square cap 0 long line does not have an angle -> always draw it axis aligned */ + rnd_coord_t cx1 = x1 - thick/2, cx2 = x1 + thick/2, cy1 = y1 - thick/2, cy2 = y1 + thick/2; + rnd_render->draw_line(gc, cx1, cy1, cx2, cy1); + rnd_render->draw_line(gc, cx2, cy1, cx2, cy2); + rnd_render->draw_line(gc, cx2, cy2, cx1, cy2); + rnd_render->draw_line(gc, cx1, cy2, cx1, cy1); + } + else + rnd_render->draw_arc(gc, x1, y1, thick/2, thick/2, 0, 360); + } +} + +#endif /* ! defined PCB_DRAW_WIREFRAME_H */ + Index: tags/2.3.0/src/drc.c =================================================================== --- tags/2.3.0/src/drc.c (nonexistent) +++ tags/2.3.0/src/drc.c (revision 33253) @@ -0,0 +1,203 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include "config.h" + +#include +#include "board.h" +#include "drc.h" +#include +#include "conf_core.h" +#include +#include "event.h" + + +pcb_view_list_t pcb_drc_lst; +extern pcb_view_list_t pcb_io_incompat_lst; +gdl_list_t pcb_drc_impls; + +void pcb_drc_impl_reg(pcb_drc_impl_t *impl) +{ + gdl_insert(&pcb_drc_impls, impl, link); +} + +void pcb_drc_impl_unreg(pcb_drc_impl_t *impl) +{ + gdl_remove(&pcb_drc_impls, impl, link); +} + + + +void pcb_drc_set_data(pcb_view_t *violation, const fgw_arg_t *measured_value, fgw_arg_t required_value) +{ + violation->data_type = PCB_VIEW_DRC; + violation->data.drc.required_value = required_value; + if (measured_value != NULL) { + violation->data.drc.have_measured = 1; + violation->data.drc.measured_value = *measured_value; + } + else + violation->data.drc.have_measured = 0; +} + + +static fgw_error_t view_dlg(fgw_arg_t *res, int argc, fgw_arg_t *argv, const char *dlg_type, const char *dlgact, pcb_view_list_t *lst, void (*refresh)()) +{ + fgw_arg_t args[2]; + + args[1].type = FGW_STR; + + if (rnd_strcasecmp(dlg_type, "list") == 0) { + if (RND_HAVE_GUI_ATTR_DLG) { + args[1].val.str = "list"; + return rnd_actionv_bin(RND_ACT_HIDLIB, dlgact, res, 2, args); + } + dlg_type = "print"; + } + + if (rnd_strcasecmp(dlg_type, "simple") == 0) { + if (RND_HAVE_GUI_ATTR_DLG) { + args[1].val.str = "simple"; + return rnd_actionv_bin(RND_ACT_HIDLIB, dlgact, res, 2, args); + } + dlg_type = "print"; + } + + + RND_ACT_IRES(-1); + if (refresh != NULL) + refresh(); + + if (rnd_strcasecmp(dlg_type, "print") == 0) { + pcb_view_t *v; + for(v = pcb_view_list_first(lst); v != NULL; v = pcb_view_list_next(v)) { + printf("%ld: %s: %s\n", v->uid, v->type, v->title); + if (v->have_bbox) + rnd_printf("%m+within %$m4\n", rnd_conf.editor.grid_unit->allow, v->bbox.X1, v->bbox.Y1, v->bbox.X2, v->bbox.Y2); + if (v->have_xy) + rnd_printf("%m+at %$m2\n", rnd_conf.editor.grid_unit->allow, v->x, v->y); + if (v->data.drc.required_value.type != FGW_INVALID) + rnd_printf("%m+required value %mw\n", rnd_conf.editor.grid_unit->allow, v->data.drc.required_value); + if ((v->data.drc.have_measured) && (v->data.drc.measured_value.type != FGW_INVALID)) + rnd_printf("%m+measured value %mw\n", rnd_conf.editor.grid_unit->allow, v->data.drc.measured_value); + printf("%s\n\n", v->description); + } + } + else if (rnd_strcasecmp(dlg_type, "log") == 0) { + pcb_view_t *v; + for(v = pcb_view_list_first(lst); v != NULL; v = pcb_view_list_next(v)) { + rnd_message(RND_MSG_INFO, "%ld: %s: %s\n", v->uid, v->type, v->title); + if (v->have_bbox) + rnd_message(RND_MSG_INFO, "%m+within %$m4\n", rnd_conf.editor.grid_unit->allow, v->bbox.X1, v->bbox.Y1, v->bbox.X2, v->bbox.Y2); + if (v->have_xy) + rnd_message(RND_MSG_INFO, "%m+at %$m2\n", rnd_conf.editor.grid_unit->allow, v->x, v->y); + if (v->data.drc.required_value.type != FGW_INVALID) + rnd_printf("%m+required value %mw\n", rnd_conf.editor.grid_unit->allow, v->data.drc.required_value); + if ((v->data.drc.have_measured) && (v->data.drc.measured_value.type != FGW_INVALID)) + rnd_message(RND_MSG_INFO, "%m+measured value %mw\n", rnd_conf.editor.grid_unit->allow, v->data.drc.measured_value); + rnd_message(RND_MSG_INFO, "%s\n\n", v->description); + } + } + if (rnd_strcasecmp(dlg_type, "dump") == 0) { + pcb_view_t *v; + char *s; + for(v = pcb_view_list_first(lst); v != NULL; v = pcb_view_list_next(v)) { + printf("V%ld\n", v->uid); + printf("T%s\n", v->type); + printf("t%s\n", v->title); + if (v->have_bbox) + rnd_printf("B%mm %mm %mm %mm mm\n", v->bbox.X1, v->bbox.Y1, v->bbox.X2, v->bbox.Y2); + if (v->have_xy) + rnd_printf("A%mm %mm mm\n", v->x, v->y); + rnd_printf("R%$mw\n", v->data.drc.required_value); + if (v->data.drc.have_measured) + rnd_printf("M%$mw\n", v->data.drc.measured_value); + for(s = v->description; *s != '\0'; s++) + if (*s == '\n') + *s = ' '; + printf("E%s\n\n", v->description); + } + } + else if (rnd_strcasecmp(dlg_type, "count") == 0) + RND_ACT_IRES(pcb_view_list_length(lst)); + + + if (refresh != NULL) + pcb_view_list_free_fields(lst); + + return 0; +} + +void pcb_drc_all(void) +{ + int ran = 0; + pcb_view_list_free_fields(&pcb_drc_lst); + rnd_event(&PCB->hidlib, PCB_EVENT_DRC_RUN, "p", &ran); + if (ran == 0) + rnd_message(RND_MSG_ERROR, "No DRC tests ran. Is any DRC plugin compiled? Are they disabled? Are all rules disabled?\n"); +} + +static const char pcb_acts_DRC[] = "DRC([list|simple|print|log|dump])"; +static const char pcb_acth_DRC[] = "Invoke the DRC check. Results are presented as the argument requests."; +/* DOC: drc.html */ +static fgw_error_t pcb_act_DRC(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *dlg_type = "list"; + RND_ACT_MAY_CONVARG(1, FGW_STR, DRC, dlg_type = argv[1].val.str); + return view_dlg(res, argc, argv, dlg_type, "drcdialog", &pcb_drc_lst, pcb_drc_all); +} + +const char pcb_acts_IOIncompatList[] = "IOIncompatList([list|simple])\n"; +const char pcb_acth_IOIncompatList[] = "Present the format incompatibilities of the last save to file operation."; +fgw_error_t pcb_act_IOIncompatList(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *dlg_type = "list"; + const char *aauto = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, IOIncompatList, dlg_type = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, IOIncompatList, aauto = argv[2].val.str); + + if ((aauto != NULL) && (strcmp(aauto, "auto") == 0)) { + if (rnd_conf.rc.quiet && !RND_HAVE_GUI_ATTR_DLG) { + /* if not explicitly asked for a listing style and we are on CLI and quiet is set, don't print anything */ + RND_ACT_IRES(0); + return 0; + } + } + + return view_dlg(res, argc, argv, dlg_type, "ioincompatlistdialog", &pcb_io_incompat_lst, NULL); +} + +static rnd_action_t drc_action_list[] = { + {"DRC", pcb_act_DRC, pcb_acth_DRC, pcb_acts_DRC}, + {"IOIncompatList", pcb_act_IOIncompatList, pcb_acth_IOIncompatList, pcb_acts_IOIncompatList}, +}; + +void pcb_drc_act_init2(void) +{ + RND_REGISTER_ACTIONS(drc_action_list, NULL); +} Index: tags/2.3.0/src/drc.h =================================================================== --- tags/2.3.0/src/drc.h (nonexistent) +++ tags/2.3.0/src/drc.h (revision 33253) @@ -0,0 +1,62 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_DRC_H +#define PCB_DRC_H + +/* Generic DRC infra: helper functions for keeping track of a list of views + for drc violations (without any actual checking logics) */ + +#include "view.h" + +#include + +typedef struct pcb_drc_impl_s { + const char *name; + const char *desc; + const char *list_rules_action; + gdl_elem_t link; +} pcb_drc_impl_t; + +/* Load drc-specific fields of a view; if measured_value is NULL, it + is not available. Values should be long, double or coord */ +void pcb_drc_set_data(pcb_view_t *violation, const fgw_arg_t *measured_value, fgw_arg_t required_value); + +extern pcb_view_list_t pcb_drc_lst; + +/* run all configured DRCs */ +void pcb_drc_all(void); + +/* DRC implementation plugins can register/unregister a helper */ +void pcb_drc_impl_reg(pcb_drc_impl_t *impl); +void pcb_drc_impl_unreg(pcb_drc_impl_t *impl); +extern gdl_list_t pcb_drc_impls; /* the full list of currently registered implementations */ + + +#endif + Index: tags/2.3.0/src/event.c =================================================================== --- tags/2.3.0/src/event.c (nonexistent) +++ tags/2.3.0/src/event.c (revision 33253) @@ -0,0 +1,58 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "event.h" + +static const char *pcb_evnames[] = { + "pcbev_new_pstk", + "pcbev_route_styles_changed", + "pcbev_netlist_changed", + "pcbev_layers_changed", + "pcbev_layer_changed_grp", + "pcbev_layervis_changed", + "pcbev_library_changed", + "pcbev_font_changed", + "pcbev_undo_post", + "pcbev_rubber_reset", + "pcbev_rubber_move", + "pcbev_rubber_move_draw", + "pcbev_rubber_rotate90", + "pcbev_rubber_rotate", + "pcbev_rubber_lookup_lines", + "pcbev_rubber_lookup_rats", + "pcbev_rubber_constrain_main_line", + "pcbev_draw_crosshair_chatt", + "pcbev_drc_run", + "pcbev_net_indicate_short", + "pcbev_layer_key_change", + "pcbev_crosshair_new_pos" +}; + +void pcb_event_init_app(void) +{ + rnd_event_app_reg(PCB_EVENT_last, pcb_evnames, sizeof(pcb_evnames)); +} Index: tags/2.3.0/src/event.h =================================================================== --- tags/2.3.0/src/event.h (nonexistent) +++ tags/2.3.0/src/event.h (revision 33253) @@ -0,0 +1,69 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_EVENT_H +#define PCB_EVENT_H + +#include + +enum { + PCB_EVENT_NEW_PSTK = RND_EVENT_app, /* called when a new padstack is created */ + + PCB_EVENT_ROUTE_STYLES_CHANGED, /* called after any route style change (used to be the RouteStylesChanged action) */ + PCB_EVENT_NETLIST_CHANGED, /* called after any netlist change (used to be the NetlistChanged action) */ + PCB_EVENT_LAYERS_CHANGED, /* called after layers or layer groups change (used to be the LayersChanged action) */ + PCB_EVENT_LAYER_CHANGED_GRP, /* called after a layer changed its group; argument: layer pointer */ + PCB_EVENT_LAYERVIS_CHANGED, /* called after the visibility of layers has changed */ + PCB_EVENT_LIBRARY_CHANGED, /* called after a change in the footprint lib (used to be the LibraryChanged action) */ + PCB_EVENT_FONT_CHANGED, /* called when a font has changed; argument is the font ID */ + + PCB_EVENT_UNDO_POST, /* called after an undo/redo operation; argument is an integer pcb_undo_ev_t */ + + PCB_EVENT_RUBBER_RESET, /* rubber band: reset attached */ + PCB_EVENT_RUBBER_MOVE, /* rubber band: object moved */ + PCB_EVENT_RUBBER_MOVE_DRAW, /* rubber band: draw crosshair-attached rubber band objects after a move or copy */ + PCB_EVENT_RUBBER_ROTATE90, /* rubber band: crosshair object rotated by 90 degrees */ + PCB_EVENT_RUBBER_ROTATE, /* rubber band: crosshair object rotated by arbitrary angle */ + PCB_EVENT_RUBBER_LOOKUP_LINES, /* rubber band: attach rubber banded line objects to crosshair */ + PCB_EVENT_RUBBER_LOOKUP_RATS, /* rubber band: attach rubber banded rat lines objects to crosshair */ + PCB_EVENT_RUBBER_CONSTRAIN_MAIN_LINE, /* rubber band: adapt main line to keep rubberband lines direction */ + + PCB_EVENT_DRAW_CROSSHAIR_CHATT, /* called from crosshair code upon attached object recalculation; event handlers can use this hook to enforce various geometric restrictions */ + + PCB_EVENT_DRC_RUN, /* called from core to run all configured DRCs (implemented in plugins). Args: (int *) that each DRC plugin shall increase if it did any check */ + + PCB_EVENT_NET_INDICATE_SHORT, /* called by core to get a shortcircuit indicated (e.g. by mincut). Args: (pcb_net_t *net, pcb_any_obj_t *offending_term, pcb_net_t *offending_net, int *handled, int *cancel) - if *handled is non-zero, the short is already indicated; if *cancel is non-zero the whole process is cancelled, no more advanced short checking should take place in this session */ + + PCB_EVENT_LAYER_KEY_CHANGE, /* called by core if a pcb-rnd::key::* attribute on a layer changes */ + + PCB_EVENT_CROSSHAIR_NEW_POS, /* called when the crosshair is moved to a new position; screen indications may need to be updated; args: (pcb_crosshair_t *), pcb_coord_t oldx, pcb_coord_t oldy */ + + PCB_EVENT_last /* not a real event */ +}; + +void pcb_event_init_app(void); + +#endif Index: tags/2.3.0/src/extobj.c =================================================================== --- tags/2.3.0/src/extobj.c (nonexistent) +++ tags/2.3.0/src/extobj.c (revision 33253) @@ -0,0 +1,237 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "data.h" +#include "data_it.h" +#include "data_list.h" +#include "remove.h" +#include "undo.h" + +#include "extobj.h" + + +static htsi_t pcb_extobj_n2i; /* extobj name -> index */ +vtp0_t pcb_extobj_i2o; /* extobj_idx -> (pcb_ext_obj_t *) */ +int pcb_extobj_invalid; /* this changes upon each new extobj reg, forcing the caches to be invalidated eventually */ + +void pcb_extobj_unreg(pcb_extobj_t *o) +{ + if (!o->registered) + return; + htsi_pop(&pcb_extobj_n2i, o->name); + vtp0_set(&pcb_extobj_i2o, o->idx, NULL); + o->registered = 0; + o->idx = 0; +} + +void pcb_extobj_reg(pcb_extobj_t *o) +{ + o->idx = pcb_extobj_i2o.used; + vtp0_append(&pcb_extobj_i2o, o); + o->registered = 0; + htsi_set(&pcb_extobj_n2i, (char *)o->name, o->idx); + pcb_extobj_invalid = -o->idx; +} + +pcb_extobj_t *pcb_extobj_lookup(const char *name) +{ + int idx = htsi_get(&pcb_extobj_n2i, name); + if ((idx <= 0) || (idx >= pcb_extobj_i2o.used)) + return NULL; + return pcb_extobj_i2o.array[idx]; +} + +int pcb_extobj_lookup_idx(const char *name) +{ + return htsi_get(&pcb_extobj_n2i, (char *)name); +} + +void pcb_extobj_init(void) +{ + vtp0_init(&pcb_extobj_i2o); + htsi_init(&pcb_extobj_n2i, strhash, strkeyeq); + + vtp0_append(&pcb_extobj_i2o, NULL); /* idx=0 is reserved for no extended obj */ +} + + +void pcb_extobj_uninit(void) +{ + size_t n; + + for(n = 0; n < pcb_extobj_i2o.used; n++) { + pcb_extobj_t *o = pcb_extobj_i2o.array[n]; + if (o != NULL) + pcb_extobj_unreg(o); + } + htsi_uninit(&pcb_extobj_n2i); + vtp0_uninit(&pcb_extobj_i2o); +} + +RND_INLINE pcb_data_t *pcb_extobj_parent_data(pcb_any_obj_t *obj) +{ + if (obj->parent_type == PCB_PARENT_DATA) + return obj->parent.data; + if (obj->parent_type == PCB_PARENT_LAYER) + return obj->parent.layer->parent.data; + return NULL; +} + +void pcb_extobj_float_new_spawn(pcb_extobj_t *eo, pcb_subc_t *subc_copy_from, pcb_any_obj_t *edit_obj) +{ + pcb_data_t *data = pcb_extobj_parent_data(edit_obj); + pcb_board_t *pcb; + const char *save; + + pcb = pcb_data_get_top(data); + if (pcb == NULL) + return; + + save = subc_copy_from->extobj; + subc_copy_from->extobj = NULL; + PCB_FLAG_CLEAR(PCB_FLAG_FLOATER, edit_obj); + pcb_extobj_conv_obj_using(pcb, eo, pcb->Data, edit_obj, 1, subc_copy_from); + subc_copy_from->extobj = save; +} + + +void pcb_extobj_del_pre(pcb_subc_t *sc) +{ + pcb_extobj_t *eo = pcb_extobj_get(sc); + + if ((eo != NULL) && (eo->del_pre != NULL)) + eo->del_pre(sc); +} + +static pcb_subc_t *pcb_extobj_conv_list(pcb_board_t *pcb, const pcb_extobj_t *eo, pcb_data_t *dst, vtp0_t *list, rnd_bool remove, pcb_subc_t *copy_from) +{ + pcb_subc_t *res; + + if ((eo->conv_objs == NULL) || (list->used == 0)) + return NULL; + + res = eo->conv_objs(dst, list, copy_from); + + if ((res != NULL) && remove) { + long n; + for(n = 0; n < list->used; n++) { + pcb_any_obj_t *o = list->array[n]; + pcb_remove_object(o->type, o->parent.any, o, o); + } + } + + return res; +} + +static pcb_subc_t *pcb_extobj_conv_flag_objs_using(pcb_board_t *pcb, const pcb_extobj_t *eo, pcb_data_t *dst, pcb_data_t *src, rnd_bool remove, pcb_flag_values_t flg, pcb_subc_t *copy_from) +{ + vtp0_t list; + pcb_subc_t *res; + + vtp0_init(&list); + pcb_data_list_by_flag(src, &list, PCB_OBJ_ANY, flg); + res = pcb_extobj_conv_list(pcb, eo, dst, &list, remove, copy_from); + vtp0_uninit(&list); + + return res; +} + +pcb_subc_t *pcb_extobj_conv_selected_objs(pcb_board_t *pcb, const pcb_extobj_t *eo, pcb_data_t *dst, pcb_data_t *src, rnd_bool remove) +{ + return pcb_extobj_conv_flag_objs_using(pcb, eo, dst, src, remove, PCB_FLAG_SELECTED, NULL); +} + +pcb_subc_t *pcb_extobj_conv_all_objs(pcb_board_t *pcb, const pcb_extobj_t *eo, pcb_data_t *dst, pcb_data_t *src, rnd_bool remove) +{ + return pcb_extobj_conv_flag_objs_using(pcb, eo, dst, src, remove, 0, NULL); +} + + +pcb_subc_t *pcb_extobj_conv_obj_using(pcb_board_t *pcb, const pcb_extobj_t *eo, pcb_data_t *dst, pcb_any_obj_t *src, rnd_bool remove, pcb_subc_t *copy_from) +{ + vtp0_t list; + pcb_subc_t *res; + + vtp0_init(&list); + vtp0_append(&list, src); + res = pcb_extobj_conv_list(pcb, eo, dst, &list, remove, copy_from); + vtp0_uninit(&list); + + return res; +} + + +pcb_subc_t *pcb_extobj_conv_obj(pcb_board_t *pcb, const pcb_extobj_t *eo, pcb_data_t *dst, pcb_any_obj_t *src, rnd_bool remove) +{ + return pcb_extobj_conv_obj_using(pcb, eo, dst, src, remove, NULL); +} + +rnd_cardinal_t pcb_extobj_sync_floater_flags(pcb_board_t *pcb, const pcb_any_obj_t *flt, int undoable, int draw) +{ + pcb_subc_t *subc; + pcb_extobj_t *eo; + pcb_data_it_t it; + pcb_any_obj_t *o; + int sel; + rnd_cardinal_t cnt = 0; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, flt)) + return 0; + + subc = pcb_obj_parent_subc(flt); + if (subc == NULL) + return 0; + + eo = pcb_extobj_get(subc); + if (eo == NULL) + return 0; + + sel = PCB_FLAG_TEST(PCB_FLAG_SELECTED, flt); + + for(o = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + /* sync selection */ + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, o)) + continue; + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, o) != sel) { + if (undoable) + pcb_undo_add_obj_to_flag(o); + PCB_FLAG_ASSIGN(PCB_FLAG_SELECTED, sel, o); + if (draw) + pcb_draw_obj(o); + cnt++; + } + } + + PCB_FLAG_ASSIGN(PCB_FLAG_SELECTED, sel, subc); + + return cnt; +} Index: tags/2.3.0/src/extobj.h =================================================================== --- tags/2.3.0/src/extobj.h (nonexistent) +++ tags/2.3.0/src/extobj.h (revision 33253) @@ -0,0 +1,270 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_EXT_OBJ_H +#define PCB_EXT_OBJ_H + +#include + +#include "board.h" +#include "data.h" +#include "obj_common.h" +#include "obj_subc.h" +#include "obj_subc_parent.h" +#include "draw.h" + + +typedef struct pcb_extobj_s pcb_extobj_t; + +typedef enum pcb_extobj_del_e { + PCB_EXTODEL_NOOP, /* do not do anything (floater is not removed either) */ + PCB_EXTODEL_FLOATER, /* remove the floater only */ + PCB_EXTODEL_SUBC /* remove the whole subcircuit */ +} pcb_extobj_del_t; + +typedef enum pcb_extobj_new_e { + PCB_EXTONEW_FLOATER, /* new floater created normally */ + PCB_EXTONEW_SPAWN /* spawn a new subc the new floater will be in */ +} pcb_extobj_new_t; + +struct pcb_extobj_s { + /* static data - filled in by the extobj code */ + const char *name; + void (*draw_mark)(pcb_draw_info_t *info, pcb_subc_t *obj); /* called when drawing the subc marks (instead of drawing the dashed outline and diamond origin) */ + void (*float_pre)(pcb_subc_t *subc, pcb_any_obj_t *floater); /* called before an extobj floater is edited in any way - must not free() the floater */ + void (*float_geo)(pcb_subc_t *subc, pcb_any_obj_t *floater); /* called after the geometry of an extobj floater is changed - must not free() the floater; floater may be NULL (post-floater-deletion update on the parent subc) */ + pcb_extobj_new_t (*float_new)(pcb_subc_t *subc, pcb_any_obj_t *floater); /* called when a floater object is split so a new floater is created; defaults to PCB_EXTONEW_SPAWN if NULL */ + pcb_extobj_del_t (*float_del)(pcb_subc_t *subc, pcb_any_obj_t *floater); /* called when a floater object is to be removed; returns what the core should do; if not specified: remove the subc */ + void (*chg_attr)(pcb_subc_t *subc, const char *key, const char *value); /* called after an attribute changed; value == NULL means attribute is deleted */ + void (*del_pre)(pcb_subc_t *subc); /* called before the extobj subcircuit is deleted - should free any internal cache, but shouldn't delete the subcircuit */ + pcb_subc_t *(*conv_objs)(pcb_data_t *dst, vtp0_t *objs, pcb_subc_t *copy_from); /* called to convert objects into an extobj subc; returns NULL on error; objects should not be changed; if copy_from is not NULL, the new extobj is being created by copying copy_from (the implementation should pick up info from there, not from PCB) */ + void (*gui_propedit)(pcb_subc_t *subc); /* invoke implementation-defined GUI for editing extended object properties */ + + /* dynamic data - filled in by core */ + int idx; + unsigned registered:1; +}; + +void pcb_extobj_init(void); +void pcb_extobj_uninit(void); + +void pcb_extobj_unreg(pcb_extobj_t *o); +void pcb_extobj_reg(pcb_extobj_t *o); + +pcb_extobj_t *pcb_extobj_lookup(const char *name); + +/* Called to remove the subc of an edit object floater; returns 0 on no + action, 1 if it removed an extobj subc */ +RND_INLINE int pcb_extobj_del_floater(pcb_any_obj_t *edit_obj); + + +/* called (by the subc code) before an edit-obj is removed */ +void pcb_extobj_del_pre(pcb_subc_t *edit_obj); + +/* Creates and returns a new extended object on dst, using (selected|all) + object(s) of src. If the operation was successful and remove is true, + remove selected objects. The "using" variant carries an existing extobj + of the same type that is used as a source of metadata */ +pcb_subc_t *pcb_extobj_conv_selected_objs(pcb_board_t *pcb, const pcb_extobj_t *eo, pcb_data_t *dst, pcb_data_t *src, rnd_bool remove); +pcb_subc_t *pcb_extobj_conv_all_objs(pcb_board_t *pcb, const pcb_extobj_t *eo, pcb_data_t *dst, pcb_data_t *src, rnd_bool remove); +pcb_subc_t *pcb_extobj_conv_obj(pcb_board_t *pcb, const pcb_extobj_t *eo, pcb_data_t *dst, pcb_any_obj_t *src, rnd_bool remove); +pcb_subc_t *pcb_extobj_conv_obj_using(pcb_board_t *pcb, const pcb_extobj_t *eo, pcb_data_t *dst, pcb_any_obj_t *src, rnd_bool remove, pcb_subc_t *copy_from); + +/* for internal use: when an extobj needs to be cloned becase a new floater + is added */ +void pcb_extobj_float_new_spawn(pcb_extobj_t *eo, pcb_subc_t *subc, pcb_any_obj_t *flt); + + +/* Call this after selection changes on a floater - this makes sure all floaters + are selected or unselected at once; returns the number of objects changed */ +rnd_cardinal_t pcb_extobj_sync_floater_flags(pcb_board_t *pcb, const pcb_any_obj_t *flt, int undoable, int draw); + + +int pcb_extobj_lookup_idx(const char *name); + +extern int pcb_extobj_invalid; /* this changes upon each new extobj reg, forcing the caches to be invalidated eventually */ +extern vtp0_t pcb_extobj_i2o; /* extobj_idx -> (pcb_ext_obj_t *) */ + +RND_INLINE pcb_extobj_t *pcb_extobj_get(pcb_subc_t *obj) +{ + pcb_extobj_t **eo; + + if ((obj == NULL) || (obj->extobj == NULL) || (obj->extobj_idx == pcb_extobj_invalid)) + return NULL; /* known negative */ + + if (obj->extobj_idx <= 0) { /* invalid idx cache - look up by name */ + obj->extobj_idx = pcb_extobj_lookup_idx(obj->extobj); + if (obj->extobj_idx == 0) { /* no such name */ + obj->extobj_idx = pcb_extobj_invalid; /* make the next lookup cheaper */ + return NULL; + } + } + + eo = (pcb_extobj_t **)vtp0_get(&pcb_extobj_i2o, obj->extobj_idx, 0); + if ((eo == NULL) || (*eo == NULL)) /* extobj backend got deregistered meanwhile */ + obj->extobj_idx = pcb_extobj_invalid; /* make the next lookup cheaper */ + return *eo; +} + +RND_INLINE void pcb_extobj_chg_attr(pcb_any_obj_t *obj, const char *key, const char *value) +{ + pcb_subc_t *subc = (pcb_subc_t *)obj; + pcb_extobj_t *eo; + + if ((obj->type != PCB_OBJ_SUBC) || (PCB_FLAG_TEST(PCB_FLAG_FLOATER, obj))) + return; + + eo = pcb_extobj_get(subc); + if ((eo != NULL) && (eo->chg_attr != NULL)) + eo->chg_attr(subc, key, value); +} + +RND_INLINE pcb_subc_t *pcb_extobj_get_floater_subc(pcb_any_obj_t *flt) +{ + pcb_subc_t *subc; + pcb_extobj_t *eo; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, flt)) + return NULL; + + subc = pcb_obj_parent_subc(flt); + if (subc == NULL) + return NULL; + + eo = pcb_extobj_get(subc); + if (eo == NULL) + return NULL; + + return subc; +} + +RND_INLINE int pcb_extobj_del_floater(pcb_any_obj_t *flt) +{ + pcb_subc_t *subc; + pcb_extobj_t *eo; + pcb_extobj_del_t act = PCB_EXTODEL_SUBC; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, flt)) + return 0; + + subc = pcb_obj_parent_subc(flt); + if (subc == NULL) + return 0; + + eo = pcb_extobj_get(subc); + if (eo == NULL) + return 0; /* do not delete non-extobjs */ + + if (eo->float_del != NULL) + act = eo->float_del(subc, flt); + + switch(act) { + case PCB_EXTODEL_NOOP: + return 1; + case PCB_EXTODEL_FLOATER: + return 0; + case PCB_EXTODEL_SUBC: + pcb_subc_remove(subc); + return 1; + } + return 0; +} + +RND_INLINE void pcb_extobj_float_new(pcb_any_obj_t *flt) +{ + pcb_subc_t *subc = pcb_obj_parent_subc(flt); + pcb_extobj_t *eo; + pcb_extobj_new_t act = PCB_EXTONEW_SPAWN; + + if (subc == NULL) + return; + + eo = pcb_extobj_get(subc); + + if ((eo != NULL) && (eo->float_new != NULL)) + act = eo->float_new(subc, flt); + + switch(act) { + case PCB_EXTONEW_FLOATER: + /* no action required, the new floater got created already and got registered in the hook above */ + break; + case PCB_EXTONEW_SPAWN: + pcb_extobj_float_new_spawn(eo, subc, flt); + break; + } +} + +RND_INLINE pcb_any_obj_t *pcb_extobj_float_pre(pcb_any_obj_t *flt) +{ + pcb_subc_t *subc; + pcb_extobj_t *eo; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, flt)) + return NULL; + + subc = pcb_obj_parent_subc(flt); + if (subc == NULL) + return NULL; + + eo = pcb_extobj_get(subc); + + if ((eo != NULL) && (eo->float_pre != NULL)) { + eo->float_pre(subc, flt); + return flt; + } + + return NULL; +} + +RND_INLINE void pcb_extobj_float_geo(pcb_any_obj_t *flt) +{ + pcb_subc_t *subc; + pcb_extobj_t *eo; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, flt)) + return; + + subc = pcb_obj_parent_subc(flt); + if (subc == NULL) + return; + + eo = pcb_extobj_get(subc); + + if ((eo != NULL) && (eo->float_geo != NULL)) + eo->float_geo(subc, flt); +} + +RND_INLINE void pcb_extobj_subc_geo(pcb_subc_t *subc) +{ + pcb_extobj_t *eo; + + eo = pcb_extobj_get(subc); + + if ((eo != NULL) && (eo->float_geo != NULL)) + eo->float_geo(subc, NULL); +} + +#endif Index: tags/2.3.0/src/extobj_act.c =================================================================== --- tags/2.3.0/src/extobj_act.c (nonexistent) +++ tags/2.3.0/src/extobj_act.c (revision 33253) @@ -0,0 +1,287 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include "conf_core.h" +#include "funchash_core.h" +#include +#include "search.h" +#include + +#include "extobj.h" + +static int extobj_pick_gui(void) +{ + int n, res; + static int last = 0; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {NULL, 0}}; + RND_DAD_DECL(dlg); + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(dlg, "Choose extended object:"); + if ((last > 0) && (last < pcb_extobj_i2o.used)) { + pcb_extobj_t *eo = pcb_extobj_i2o.array[last]; + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_LABEL(dlg, "Last used:"); + RND_DAD_BUTTON_CLOSE(dlg, eo->name, last); + RND_DAD_END(dlg); + } + RND_DAD_BEGIN_TABLE(dlg, 3); + for(n = 1; n < pcb_extobj_i2o.used; n++) { + pcb_extobj_t *eo = pcb_extobj_i2o.array[n]; + RND_DAD_BUTTON_CLOSE(dlg, eo->name, n); + } + RND_DAD_END(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + RND_DAD_NEW("extobj_select", dlg, "Select extended object", NULL, rnd_true, NULL); + res = RND_DAD_RUN(dlg); + RND_DAD_FREE(dlg); + if (res > 0) + last = res; + return res; +} + +static const char pcb_acts_ExtobjConvFrom[] = "ExtobjConvFrom(selected|buffer, extotype)\nExtobjConvFrom(object, extotype, [idpath])"; +static const char pcb_acth_ExtobjConvFrom[] = "Create a new extended object of extotype by converting existing objects"; +fgw_error_t pcb_act_ExtobjConvFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + pcb_extobj_t *eo; + const char *eoname = NULL; + int op; + pcb_subc_t *sc; + pcb_any_obj_t *obj; + + RND_ACT_CONVARG(1, FGW_KEYWORD, ExtobjConvFrom, op = fgw_keyword(&argv[1])); + RND_ACT_CONVARG(2, FGW_STR, ExtobjConvFrom, eoname = argv[2].val.str); + + if (strcmp(eoname, "@gui") != 0) { + eo = pcb_extobj_lookup(eoname); + if (eo == NULL) { + rnd_message(RND_MSG_ERROR, "ExtobjConvFrom: extended object '%s' is not available\n", eoname); + RND_ACT_IRES(-1); + return 0; + } + } + else { + int idx = extobj_pick_gui(); + if (idx <= 0) { + RND_ACT_IRES(-1); + return 0; + } + eo = pcb_extobj_i2o.array[idx]; + } + + switch(op) { + case F_Object: + if (argc > 3) { /* convert by idpath */ + pcb_idpath_t *idp; + RND_ACT_CONVARG(3, FGW_IDPATH, ExtobjConvFrom, idp = fgw_idpath(&argv[2])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[3], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + obj = pcb_idpath2obj(PCB, idp); + } + else { /* interactive convert */ + void *p1, *p3; + rnd_coord_t x, y; + rnd_hid_get_coords("Click on object to convert", &x, &y, 0); + obj = NULL; + if (pcb_search_screen(x, y, PCB_OBJ_CLASS_REAL, &p1, (void **)&obj, &p3) == 0) { + rnd_message(RND_MSG_ERROR, "ExtobjConvFrom: object not found (no object under the cursor)\n"); + RND_ACT_IRES(-1); + return 0; + } + } + if ((obj == NULL) || ((obj->type & PCB_OBJ_CLASS_REAL) == 0)) { + rnd_message(RND_MSG_ERROR, "ExtobjConvFrom: object not found\n"); + RND_ACT_IRES(-1); + return 0; + } + sc = pcb_extobj_conv_obj(pcb, eo, pcb->Data, obj, 1); + break; + + case F_Selected: + sc = pcb_extobj_conv_selected_objs(pcb, eo, pcb->Data, pcb->Data, 1); + break; + + case F_Buffer: + sc = pcb_extobj_conv_all_objs(pcb, eo, PCB_PASTEBUFFER->Data, PCB_PASTEBUFFER->Data, 1); + break; + + default: + RND_ACT_FAIL(ExtobjConvFrom); + } + + if (sc == NULL) { + rnd_message(RND_MSG_ERROR, "ExtobjConvFrom: failed to create the extended object\n"); + RND_ACT_IRES(-1); + return 0; + } + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_ExtobjGUIPropEdit[] = "ExtobjGUIPropEdit([object, [idpath]])"; +static const char pcb_acth_ExtobjGUIPropEdit[] = "Invoke the extobj-implementation-specific GUI property editor, if available"; + +static int exto_get_obj(fgw_arg_t *res, int argc, fgw_arg_t *argv, pcb_subc_t **dst_obj, pcb_extobj_t **dst_eo, rnd_bool require_extobj) +{ + int op = F_Object; + pcb_extobj_t *eo; + pcb_subc_t *obj; + + *dst_obj = NULL; + *dst_eo = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, ExtobjGUIPropEdit, op = fgw_keyword(&argv[1])); + + switch(op) { + case F_Object: + if (argc > 2) { /* convert by idpath */ + pcb_idpath_t *idp; + RND_ACT_CONVARG(2, FGW_IDPATH, ExtobjGUIPropEdit, idp = fgw_idpath(&argv[2])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + obj = (pcb_subc_t *)pcb_idpath2obj(PCB, idp); + } + else { /* interactive convert */ + void *p1, *p3; + rnd_coord_t x, y; + rnd_hid_get_coords("Click on extended object to edit", &x, &y, 0); + obj = NULL; + if (pcb_search_screen(x, y, PCB_OBJ_SUBC, &p1, (void **)&obj, &p3) == 0) { + rnd_message(RND_MSG_ERROR, "ExtobjConvFrom: object not found (no object under the cursor)\n"); + RND_ACT_IRES(-1); + return 0; + } + } + if ((obj == NULL) || ((obj->type & PCB_OBJ_CLASS_REAL) == 0)) { + rnd_message(RND_MSG_ERROR, "ExtobjConvFrom: object not found\n"); + RND_ACT_IRES(-1); + return 0; + } + break; + + default: + RND_ACT_FAIL(ExtobjConvFrom); + } + + if ((obj == NULL) || (obj->type != PCB_OBJ_SUBC)) { + rnd_message(RND_MSG_ERROR, "Object is not an extended object (not even a subcircuit)\n"); + RND_ACT_IRES(-1); + return 0; + } + + if (require_extobj && (obj->extobj == NULL)) { + rnd_message(RND_MSG_ERROR, "Subcircuit is not an extended object\n"); + RND_ACT_IRES(-1); + return 0; + } + + eo = pcb_extobj_get(obj); + if (require_extobj && (eo == NULL)) { + rnd_message(RND_MSG_ERROR, "Extended object '%s' is not available\n", obj->extobj); + RND_ACT_IRES(1); + return 0; + } + + + *dst_obj = obj; + *dst_eo = eo; + return 0; +} + +fgw_error_t pcb_act_ExtobjGUIPropEdit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_extobj_t *eo; + pcb_subc_t *obj; + int rv = exto_get_obj(res, argc, argv, &obj, &eo, 1); + + if (obj == NULL) { + RND_ACT_IRES(1); + return rv; + } + + if (eo->gui_propedit != NULL) + eo->gui_propedit(obj); + else + rnd_message(RND_MSG_ERROR, "Extended object '%s' does not implement GUI property editor", obj->extobj); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_ExtobjToggle[] = "ExtobjToggle([object, [idpath]])"; +static const char pcb_acth_ExtobjToggle[] = "Convert an extobj into a plain subc or back"; +fgw_error_t pcb_act_ExtobjToggle(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_extobj_t *eo; + pcb_subc_t *obj; + int rv = exto_get_obj(res, argc, argv, &obj, &eo, 0); + + if (obj == NULL) { + RND_ACT_IRES(1); + return rv; + } + + if (eo != NULL) { + pcb_attribute_put(&obj->Attributes, "disabled_extobj", obj->extobj); + pcb_attribute_remove(&obj->Attributes, "extobj"); + PCB_FLAG_CLEAR(PCB_FLAG_LOCK, obj); + } + else { + const char *type = pcb_attribute_get(&obj->Attributes, "disabled_extobj"); + if (type == NULL) { + rnd_message(RND_MSG_ERROR, "Subcircuit was not an extended object\n"); + RND_ACT_IRES(1); + return 0; + } + pcb_attribute_put(&obj->Attributes, "extobj", type); + pcb_attribute_remove(&obj->Attributes, "disabled_extobj"); + PCB_FLAG_SET(PCB_FLAG_LOCK, obj); + } + + RND_ACT_IRES(0); + return 0; +} + + +static rnd_action_t pcb_extobj_action_list[] = { + {"ExtobjConvFrom", pcb_act_ExtobjConvFrom, pcb_acth_ExtobjConvFrom, pcb_acts_ExtobjConvFrom}, + {"ExtobjGUIPropEdit", pcb_act_ExtobjGUIPropEdit, pcb_acth_ExtobjGUIPropEdit, pcb_acts_ExtobjGUIPropEdit}, + {"ExtobjToggle", pcb_act_ExtobjToggle, pcb_acth_ExtobjToggle, pcb_acts_ExtobjToggle} +}; + +void pcb_extobj_act_init2(void) +{ + RND_REGISTER_ACTIONS(pcb_extobj_action_list, NULL); +} Index: tags/2.3.0/src/extobj_helper.h =================================================================== --- tags/2.3.0/src/extobj_helper.h (nonexistent) +++ tags/2.3.0/src/extobj_helper.h (revision 33253) @@ -0,0 +1,249 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "obj_subc.h" +#include "conf_core.h" +#include +#include +#include "change.h" +#include "undo.h" + +/*** API ***/ + +/* Convert an attribute to coord, return 0 on success */ +RND_INLINE int pcb_extobj_unpack_coord(const pcb_subc_t *obj, rnd_coord_t *res, const char *name); +RND_INLINE int pcb_extobj_unpack_int(const pcb_subc_t *obj, int *res, const char *name); + +/* Wrap the update/re-generation of an extobject-subc in this begin/end to + make sure bbox and undo are updated properly. The end() call always returns + 0. */ +RND_INLINE void pcb_exto_regen_begin(pcb_subc_t *subc); +RND_INLINE int pcb_exto_regen_end(pcb_subc_t *subc); + +/*** implementation ***/ +RND_INLINE int pcb_extobj_unpack_coord(const pcb_subc_t *obj, rnd_coord_t *res, const char *name) +{ + double v; + rnd_bool succ; + const char *s = pcb_attribute_get(&obj->Attributes, name); + if (s != NULL) { + v = rnd_get_value(s, NULL, NULL, &succ); + if (succ) { + *res = v; + return 0; + } + } + return -1; +} + +RND_INLINE int pcb_extobj_unpack_int(const pcb_subc_t *obj, int *res, const char *name) +{ + long l; + char *end; + const char *s = pcb_attribute_get(&obj->Attributes, name); + if (s != NULL) { + l = strtol(s, &end, 10); + if (*end == '\0') { + *res = l; + return 0; + } + } + return -1; +} + +RND_INLINE void pcb_exto_regen_begin(pcb_subc_t *subc) +{ + pcb_data_t *data = subc->parent.data; + if (data->subc_tree != NULL) + rnd_r_delete_entry(data->subc_tree, (rnd_box_t *)subc); + pcb_undo_freeze_add(); +} + +RND_INLINE int pcb_exto_regen_end(pcb_subc_t *subc) +{ + pcb_data_t *data = subc->parent.data; + + pcb_undo_unfreeze_add(); + pcb_subc_bbox(subc); + if ((data != NULL) && (data->subc_tree != NULL)) + rnd_r_insert_entry(data->subc_tree, (rnd_box_t *)subc); + + return 0; +} + +RND_INLINE pcb_subc_t *pcb_exto_create(pcb_data_t *dst, const char *eoname, const pcb_dflgmap_t *layers, rnd_coord_t ox, rnd_coord_t oy, rnd_bool on_bottom, pcb_subc_t *copy_from) +{ + pcb_subc_t *subc = pcb_subc_alloc(); + pcb_board_t *pcb = NULL; + + if (copy_from != NULL) + pcb_subc_copy_meta(subc, copy_from); + pcb_attribute_put(&subc->Attributes, "extobj", eoname); + + for(; layers->name != NULL; layers++) + pcb_subc_layer_create(subc, layers->name, layers->lyt, layers->comb, 0, layers->purpose); + + pcb_subc_create_aux(subc, ox, oy, 0, on_bottom); + + PCB_FLAG_SET(PCB_FLAG_LOCK, subc); + pcb_subc_bbox(subc); + pcb_subc_reg(dst, subc); + + if (dst->parent_type == PCB_PARENT_BOARD) + pcb = dst->parent.board; + + if (pcb != NULL) { + pcb_subc_rebind(pcb, subc); + pcb_subc_bind_globals(pcb, subc); + if (!dst->subc_tree) + dst->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(dst->subc_tree, (rnd_box_t *)subc); + } + + pcb_undo_add_obj_to_create(PCB_OBJ_SUBC, subc, subc, subc); + + return subc; +} + +RND_INLINE void pcb_exto_draw_mark(pcb_draw_info_t *info, pcb_subc_t *subc) +{ + rnd_coord_t x, y, unit = PCB_SUBC_AUX_UNIT; + + if (pcb_subc_get_origin(subc, &x, &y) != 0) + return; + + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.extobj); + rnd_hid_set_line_width(pcb_draw_out.fgGC, -2); + rnd_render->draw_line(pcb_draw_out.fgGC, x, y, x, y + unit); + rnd_render->draw_line(pcb_draw_out.fgGC, x, y, x + unit/2, y); + rnd_render->draw_line(pcb_draw_out.fgGC, x, y + unit, x + unit/2, y + unit); + rnd_render->draw_line(pcb_draw_out.fgGC, x, y + unit/2, x + unit/3, y + unit/2); +} + +/*** dialog box build ***/ + +RND_INLINE void pcb_exto_dlg_gui_chg_attr(pcb_subc_t *subc, rnd_hid_attribute_t *attr, const char *newval) /* for internal use */ +{ + pcb_board_t *pcb; + pcb_data_t *data; + + if (subc->parent_type != PCB_PARENT_DATA) + return; + data = subc->parent.data; + if (data->parent_type != PCB_PARENT_BOARD) + return; + pcb = data->parent.board; + + pcb_uchg_attr(pcb, (pcb_any_obj_t *)subc, (char *)attr->user_data, newval); + rnd_trace("chg: %s\n", (char *)attr->user_data); + rnd_gui->invalidate_all(rnd_gui); +} + +RND_INLINE void pcb_exto_dlg_coord_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_subc_t *subc = caller_data; + char tmp[128]; + + rnd_snprintf(tmp, sizeof(tmp), "%$mm", attr->val.crd); + pcb_exto_dlg_gui_chg_attr(subc, attr, tmp); +} + +#define pcb_exto_dlg_coord(dlg, subc, vis_name, attr_name, help) \ +do { \ + rnd_hid_dad_spin_t *spin; \ + double d; \ + rnd_coord_t currval = 0; \ + const rnd_unit_t *unit_out = NULL; \ + int wid; \ + char *sval = pcb_attribute_get(&subc->Attributes, attr_name); \ + if (sval != NULL) \ + rnd_get_value_unit(sval, NULL, 0, &d, &unit_out); \ + currval = d; \ + RND_DAD_LABEL(dlg, vis_name); \ + if (help != NULL) RND_DAD_HELP(dlg, help); \ + RND_DAD_COORD(dlg); \ + if (help != NULL) RND_DAD_HELP(dlg, help); \ + RND_DAD_CHANGE_CB(dlg, pcb_exto_dlg_coord_cb); \ + wid = RND_DAD_CURRENT(dlg); \ + dlg[wid].user_data = (void *)attr_name; \ + RND_DAD_DEFAULT_NUM(dlg, currval); \ + spin = dlg[wid].wdata; \ + spin->unit = unit_out; \ + spin->no_unit_chg = 1; \ + rnd_dad_spin_update_internal(spin); \ +} while(0) + +/* hv.crd = currval; \*/ +/* rnd_dad_spin_set_value(spin->cmp.wend, NULL, wid, &hv); \*/ + + +RND_INLINE void pcb_exto_dlg_str_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_subc_t *subc = caller_data; + pcb_exto_dlg_gui_chg_attr(subc, attr, attr->val.str); +} + +#define pcb_exto_dlg_str(dlg, subc, vis_name, attr_name, help) \ +do { \ + int wid; \ + const char *currval = pcb_attribute_get(&subc->Attributes, attr_name); \ + if (currval == NULL) currval = ""; \ + currval = rnd_strdup(currval); \ + RND_DAD_LABEL(dlg, vis_name); \ + if (help != NULL) RND_DAD_HELP(dlg, help); \ + RND_DAD_STRING(dlg); \ + if (help != NULL) RND_DAD_HELP(dlg, help); \ + RND_DAD_CHANGE_CB(dlg, pcb_exto_dlg_str_cb); \ + wid = RND_DAD_CURRENT(dlg); \ + dlg[wid].user_data = (void *)attr_name; \ + RND_DAD_DEFAULT_PTR(dlg, currval); \ +} while(0) + +RND_INLINE void pcb_exto_dlg_int_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_subc_t *subc = caller_data; + char tmp[128]; + + rnd_snprintf(tmp, sizeof(tmp), "%d", attr->val.lng); + pcb_exto_dlg_gui_chg_attr(subc, attr, tmp); +} + +#define pcb_exto_dlg_int(dlg, subc, vis_name, attr_name, help) \ +do { \ + rnd_coord_t currval = 0; \ + int wid; \ + char *sval = pcb_attribute_get(&subc->Attributes, attr_name); \ + if (sval != NULL) \ + currval = strtol(sval, NULL, 10); \ + RND_DAD_LABEL(dlg, vis_name); \ + if (help != NULL) RND_DAD_HELP(dlg, help); \ + RND_DAD_INTEGER(dlg); \ + if (help != NULL) RND_DAD_HELP(dlg, help); \ + RND_DAD_CHANGE_CB(dlg, pcb_exto_dlg_int_cb); \ + wid = RND_DAD_CURRENT(dlg); \ + dlg[wid].user_data = (void *)attr_name; \ + RND_DAD_DEFAULT_NUM(dlg, currval); \ +} while(0) Index: tags/2.3.0/src/file_act.c =================================================================== --- tags/2.3.0/src/file_act.c (nonexistent) +++ tags/2.3.0/src/file_act.c (revision 33253) @@ -0,0 +1,559 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" +#include "board.h" +#include "build_run.h" +#include "conf_core.h" +#include "funchash_core.h" +#include "data.h" +#include "buffer.h" + +#include "plug_io.h" +#include "plug_import.h" +#include "remove.h" +#include "draw.h" +#include "event.h" +#include "find.h" +#include "search.h" +#include +#include +#include +#include "layer_vis.h" +#include +#include +#include "netlist.h" +#include "plug_io.h" + +#define PCB (do_not_use_PCB) + +static const char pcb_acts_LoadFrom[] = "LoadFrom(Layout|LayoutToBuffer|SubcToBuffer|Netlist|Revert,filename[,format])"; +static const char pcb_acth_LoadFrom[] = "Load layout data from a file."; +/* DOC: loadfrom.html */ +fgw_error_t pcb_act_LoadFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *name, *format = NULL; + int op; + + RND_ACT_CONVARG(1, FGW_KEYWORD, LoadFrom, op = fgw_keyword(&argv[1])); + 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); + + switch(op) { + case F_ElementToBuffer: + case F_FootprintToBuffer: + case F_Element: + case F_SubcToBuffer: + case F_Subcircuit: + case F_Footprint: + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + if (pcb_buffer_load_footprint(PCB_PASTEBUFFER, name, format)) + rnd_tool_select_by_name(RND_ACT_HIDLIB, "buffer"); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + break; + + case F_LayoutToBuffer: + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + if (pcb_buffer_load_layout(pcb, PCB_PASTEBUFFER, name, format)) + rnd_tool_select_by_name(RND_ACT_HIDLIB, "buffer"); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + break; + + case F_Layout: + if (!pcb->Changed || rnd_hid_message_box(RND_ACT_HIDLIB, "warning", "File overwrite", "OK to override layout data?", "cancel", 0, "ok", 1, NULL)) + pcb_load_pcb(name, format, rnd_true, 0); + break; + + case F_Netlist: + if (pcb->Netlistname) + free(pcb->Netlistname); + pcb->Netlistname = rnd_strdup_strip_wspace(name); + { + int i; + for (i = 0; i < PCB_NUM_NETLISTS; i++) { + pcb_netlist_uninit(&(pcb->netlist[i])); + pcb_netlist_init(&(pcb->netlist[i])); + } + } + if (!pcb_import_netlist(RND_ACT_HIDLIB, pcb->Netlistname)) + pcb_netlist_changed(1); + else + rnd_message(RND_MSG_ERROR, "None of the netlist import plugins could handle that file (unknown or broken file format?)\n"); + break; + + case F_Revert: + if (RND_ACT_HIDLIB->filename && (!pcb->Changed || (rnd_hid_message_box(RND_ACT_HIDLIB, "warning", "Revert: lose data", "Really revert all modifications?", "no", 0, "yes", 1, NULL) == 1))) + pcb_revert_pcb(); + break; + + default: + rnd_message(RND_MSG_ERROR, "LoadFrom(): invalid command (first arg)\n"); + RND_ACT_IRES(1); + return 0; + } + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_New[] = "New([name])"; +static const char pcb_acth_New[] = "Starts a new layout."; +/* DOC: new.html */ +static fgw_error_t pcb_act_New(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *argument_name = NULL; + char *name = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, New, argument_name = argv[1].val.str); + + if (!pcb->Changed || (rnd_hid_message_box(RND_ACT_HIDLIB, "warning", "New pcb", "OK to clear layout data?", "cancel", 0, "yes", 1, NULL) == 1)) { + if (argument_name) + name = rnd_strdup(argument_name); + else + name = rnd_hid_prompt_for(RND_ACT_HIDLIB, "Enter the layout name:", "", "Layout name"); + + if (!name) + return 1; + +/* pcb usage: at the moment, while having only one global pcb, this function + legitimately uses that */ + + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + /* do emergency saving + * clear the old struct and allocate memory for the new one + */ + if (pcb->Changed && conf_core.editor.save_in_tmp) + pcb_save_in_tmp(); + + pcb_crosshair_move_absolute(pcb, RND_COORD_MAX, RND_COORD_MAX); /* make sure the crosshair is not above any object so ch* plugins release their highlights */ + if (rnd_gui->set_hidlib != NULL) + rnd_gui->set_hidlib(rnd_gui, NULL); + + pcb_draw_inhibit_inc(); + pcb_board_remove(pcb); +#undef PCB + PCB = pcb = pcb_board_new(1); +#define PCB do_not_use + pcb_board_new_postproc(pcb, 1); + if (rnd_gui->set_hidlib != NULL) + rnd_gui->set_hidlib(rnd_gui, &pcb->hidlib); + pcb_draw_inhibit_dec(); + + pcb_set_design_dir(NULL); + rnd_conf_set(RND_CFR_DESIGN, "design/text_font_id", 0, "0", RND_POL_OVERWRITE); /* we have only one font now, make sure it is selected */ + + /* setup the new name and reset some values to default */ + free(pcb->hidlib.name); + pcb->hidlib.name = name; + + pcb_layervis_reset_stack(&pcb->hidlib); + pcb_center_display(pcb, pcb->hidlib.size_x / 2, pcb->hidlib.size_y / 2); + pcb_board_changed(0); + rnd_hid_redraw(pcb); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + RND_ACT_IRES(0); + return 0; + } + RND_ACT_IRES(-1); + return 0; +} + +/* --------------------------------------------------------------------------- */ +static const char pcb_acts_normalize[] = "Normalize([board|buffer[n]])"; +static const char pcb_acth_normalize[] = "Move all objects within the drawing area (or buffer 0;0), align the drawing to 0;0 (or set buffer grab point to 0;0)"; +static fgw_error_t pcb_act_normalize(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *target = "board"; + + RND_ACT_MAY_CONVARG(1, FGW_STR, normalize, target = argv[1].val.str); + + if (strcmp(target, "board") == 0) + RND_ACT_IRES(pcb_board_normalize(pcb)); + else if (strncmp(target, "buffer", 6) == 0) { + int bn; + char *end; + + target += 6; + if (*target != '\0') { + bn = strtol(target, &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Expected buffer number, got '%s'\n", target); + RND_ACT_IRES(-1); + } + bn--; + if ((bn < 0) || (bn >= PCB_MAX_BUFFER)) { + rnd_message(RND_MSG_ERROR, "Buffer number out of range\n"); + RND_ACT_IRES(-1); + } + } + else + bn = conf_core.editor.buffer_number; + + if ((pcb_buffers[bn].bbox_naked.X1 != 0) || (pcb_buffers[bn].bbox_naked.Y1 != 0)) { + pcb_data_move(pcb_buffers[bn].Data, -pcb_buffers[bn].bbox_naked.X1, -pcb_buffers[bn].bbox_naked.Y1, 0); + pcb_set_buffer_bbox(&pcb_buffers[bn]); + } + + pcb_buffers[bn].X = pcb_buffers[bn].Y = 0; + RND_ACT_IRES(0); + } + else + RND_ACT_FAIL(normalize); + return 0; +} + + +static const char pcb_acts_SaveTo[] = + "SaveTo(Layout|LayoutAs,filename,[fmt])\n" + "SaveTo(PasteBuffer,filename,[fmt])"; +static const char pcb_acth_SaveTo[] = "Saves data to a file."; +/* DOC: saveto.html */ +fgw_error_t pcb_act_SaveTo(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + const char *name = NULL; + const char *fmt = NULL; + + RND_ACT_CONVARG(1, FGW_KEYWORD, SaveTo, op = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, SaveTo, name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, SaveTo, fmt = argv[3].val.str); + RND_ACT_IRES(0); + + if ((op != F_Layout) && (name == NULL)) + RND_ACT_FAIL(SaveTo); + + switch(op) { + case F_Layout: + if (argc != 2) { + rnd_message(RND_MSG_ERROR, "SaveTo(Layout) doesn't take file name or format - did you mean SaveTo(LayoutAs)?\n"); + return FGW_ERR_ARGC; + } + if (pcb_save_pcb(RND_ACT_HIDLIB->filename, NULL) == 0) + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_false); + rnd_event(RND_ACT_HIDLIB, RND_EVENT_BOARD_FN_CHANGED, NULL); + return 0; + + case F_LayoutAs: + if (pcb_save_pcb(name, fmt) == 0) { + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_false); + free(RND_ACT_HIDLIB->filename); + RND_ACT_HIDLIB->filename = rnd_strdup(name); + rnd_event(RND_ACT_HIDLIB, RND_EVENT_BOARD_FN_CHANGED, NULL); + } + return 0; + + + case F_PasteBuffer: + if (pcb_subclist_length(&PCB_PASTEBUFFER->Data->subc) == 0) { + rnd_message(RND_MSG_ERROR, "Can not save subcircuit: there is no subcircuit in the paste buffer.\n"); + RND_ACT_IRES(-1); + } + else if (pcb_subclist_length(&PCB_PASTEBUFFER->Data->subc) > 1) { + rnd_message(RND_MSG_ERROR, "Can not save subcircuit: there are more than one subcircuits in the paste buffer.\nDid you mean saving a library instead?\n"); + RND_ACT_IRES(-1); + } + else + RND_ACT_IRES(pcb_save_buffer_subcs(name, fmt, 0)); + return 0; + + /* shorthand kept only for compatibility reasons - do not use */ + case F_AllConnections: + rnd_message(RND_MSG_WARNING, "Please use action ExportOldConn() instead of SaveTo() for connections.\n"); + return rnd_actionva(RND_ACT_HIDLIB, "ExportOldConn", "AllConnections", name, NULL); + case F_AllUnusedPins: + rnd_message(RND_MSG_WARNING, "Please use action ExportOldConn() instead of SaveTo() for connections.\n"); + return rnd_actionva(RND_ACT_HIDLIB, "ExportOldConn", "AllUnusedPins", name, NULL); + case F_ElementConnections: + case F_SubcConnections: + rnd_message(RND_MSG_WARNING, "Please use action ExportOldConn() instead of SaveTo() for connections.\n"); + return rnd_actionva(RND_ACT_HIDLIB, "ExportOldConn", "SubcConnections", name, NULL); + } + + RND_ACT_FAIL(SaveTo); +} + +/* Run the save dialog, either the full version from the dialogs plugin +(if available) or a simplified version. Return 0 on success and fill in +name_out and fmt_out. */ +static int save_fmt_dialog(const char *title, const char *descr, char **default_file, const char *history_tag, rnd_hid_fsd_flags_t flags, char **name_out, const char **fmt_out) +{ + const fgw_func_t *f = rnd_act_lookup("save"); + + *name_out = NULL; + *fmt_out = NULL; + + if (f != NULL) { /* has dialogs plugin */ + fgw_error_t err; + fgw_arg_t res, argv[6]; + char *sep; + + argv[1].type = FGW_STR; argv[1].val.str = "DialogByPattern"; + argv[2].type = FGW_STR; argv[2].val.str = "footprint"; + argv[3].type = FGW_STR; argv[3].val.str = "fp"; + argv[4].type = FGW_STR; argv[4].val.cstr = descr; + argv[5].type = FGW_STR; argv[5].val.cstr = conf_core.rc.save_fp_fmt; + err = rnd_actionv_(f, &res, 5, argv); + if ((err != 0) || (res.val.str == NULL)) /* cancel */ + return -1; + if ((res.type & (FGW_STR | FGW_DYN)) != (FGW_STR | FGW_DYN)) { + rnd_message(RND_MSG_ERROR, "Internal error: Save(DialogByPattern) did not return a dynamic string\n"); + return -1; + } + *name_out = res.val.str; /* will be free'd by the caller */ + sep = strchr(res.val.str, '*'); + if (sep != NULL) { + *sep = '\0'; + *fmt_out = sep+1; + } + printf("RES2: '%s' '%s'\n", *name_out, *fmt_out); + } + else { /* fallback to simpler fileselect */ + char *name = rnd_gui->fileselect(rnd_gui, title, descr, *default_file, "", NULL, history_tag, flags, NULL); + + *name_out = name; + if (name == NULL) + return -1; + + if (*default_file != NULL) + free(*default_file); + *default_file = rnd_strdup(name); + } + return 0; +} + +static const char pcb_acts_SaveLib[] = + "SaveLib(file|dir, board|buffer, [filename], [fmt])\n"; +static const char pcb_acth_SaveLib[] = "Saves all subcircuits to a library file or directory from a board or buffer."; +/* DOC: savelib.html */ +fgw_error_t pcb_act_SaveLib(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *method, *source, *fn = NULL, *fmt = NULL; + pcb_data_t *src; + + RND_ACT_CONVARG(1, FGW_STR, SaveLib, method = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, SaveLib, source = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, SaveLib, fn = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, SaveLib, fmt = argv[4].val.str); + + if (rnd_strcasecmp(source, "board") == 0) src = pcb->Data; + else if (rnd_strcasecmp(source, "buffer") == 0) src = PCB_PASTEBUFFER->Data; + else + RND_ACT_FAIL(SaveLib); + + if (rnd_strcasecmp(method, "file") == 0) { + char *name; + FILE *f; + static char *default_file; + + if (fn == NULL) { + int sr = save_fmt_dialog("Save footprint lib to file ...", "Choose a file to save all subcircuits to.\n", + &default_file, "save_lib_file", RND_HID_FSD_MAY_NOT_EXIST, &name, &fmt); + if (sr != 0) { + RND_ACT_IRES(-1); + return 0; + } + } + else + name = rnd_strdup(fn); + + f = rnd_fopen(RND_ACT_HIDLIB, name, "w"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to open %s for write\n", name); + free(name); + RND_ACT_IRES(-1); + return 0; + } + free(name); + RND_ACT_IRES(pcb_write_footprint_data(f, src, fmt, -1)); + } + else if (rnd_strcasecmp(method, "dir") == 0) { + unsigned int ares = 0; + void *udata; + gdl_iterator_t sit; + char *name, *sep; + const char *ending; + static char *default_file; + pcb_subc_t *subc; + pcb_plug_io_t *p; + + + if (fn == NULL) { + int sr = save_fmt_dialog("Save footprint lib to directory ...", "Choose a file name pattern to save all subcircuits to.\n", + &default_file, "save_lib_dir", RND_HID_FSD_IS_TEMPLATE, &name, &fmt); + if (sr != 0) { + RND_ACT_IRES(-1); + return 0; + } + } + else + name = rnd_strdup(fn); + + p = pcb_io_find_writer(PCB_IOT_FOOTPRINT, fmt); + if (p == NULL) { + if (fmt == NULL) + rnd_message(RND_MSG_ERROR, "Failed to find a plugin that can write subcircuits", fmt); + else + rnd_message(RND_MSG_ERROR, "Failed to find a plugin for format %s", fmt); + RND_ACT_IRES(-1); + return 0; + } + + sep = strrchr(name, '.'); + if ((sep != NULL) && (strchr(sep, RND_DIR_SEPARATOR_C) == NULL)) { + *sep = '\0'; + ending = sep+1; + sep = "."; + } + else { + ending = p->fp_extension; + sep = ""; + } + + subclist_foreach(&src->subc, &sit, subc) { + FILE *f; + char *fullname = rnd_strdup_printf("%s.%ld%s%s", name, (long)sit.count, sep, ending); + + f = rnd_fopen(RND_ACT_HIDLIB, fullname, "w"); + free(fullname); + if (f != NULL) { + if (p->write_subcs_head(p, &udata, f, 0, 1) == 0) { + ares |= p->write_subcs_subc(p, &udata, f, subc); + ares |= p->write_subcs_tail(p, &udata, f); + } + else ares |= 1; + } + else ares |= 1; + } + + if (ares != 0) + rnd_message(RND_MSG_ERROR, "Some of the subcircuits failed to export\n"); + RND_ACT_IRES(ares); + free(name); + } + else + RND_ACT_FAIL(SaveLib); + + return 0; +} + +static const char pcb_acts_Quit[] = "Quit()"; +static const char pcb_acth_Quit[] = "Quits the application after confirming."; +/* DOC: quit.html */ +static fgw_error_t pcb_act_Quit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *force = NULL; + RND_ACT_MAY_CONVARG(1, FGW_STR, Quit, force = argv[1].val.str); + + if ((force != NULL) && (rnd_strcasecmp(force, "force") == 0)) + exit(0); + if (!pcb->Changed || (rnd_hid_message_box(RND_ACT_HIDLIB, "warning", "Close: lose data", "OK to lose data?", "cancel", 0, "ok", 1, NULL) == 1)) + pcb_quit_app(); + RND_ACT_IRES(-1); + return 0; +} + + +static const char pcb_acts_Export[] = "Export(exporter, [exporter-args])"; +static const char pcb_acth_Export[] = "Export the current layout, e.g. Export(png, --dpi, 600)"; +static fgw_error_t pcb_act_Export(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char *args[128]; + char **a; + int n; + + if (argc < 1) { + rnd_message(RND_MSG_ERROR, "Export() needs at least one argument, the name of the export plugin\n"); + return 1; + } + + if (argc > sizeof(args)/sizeof(args[0])) { + rnd_message(RND_MSG_ERROR, "Export(): too many arguments\n"); + return 1; + } + + args[0] = NULL; + for(n = 1; n < argc; n++) + RND_ACT_CONVARG(n, FGW_STR, Export, args[n-1] = argv[n].val.str); + + rnd_exporter = rnd_hid_find_exporter(args[0]); + if (rnd_exporter == NULL) { + rnd_message(RND_MSG_ERROR, "Export plugin %s not found. Was it enabled in ./configure?\n", args[0]); + return 1; + } + + /* remove the name of the exporter */ + argc-=2; + + /* call the exporter */ + rnd_event(RND_ACT_HIDLIB, RND_EVENT_EXPORT_SESSION_BEGIN, NULL); + a = args; + a++; + rnd_exporter->parse_arguments(rnd_exporter, &argc, &a); + rnd_exporter->do_export(rnd_exporter, NULL); + rnd_event(RND_ACT_HIDLIB, RND_EVENT_EXPORT_SESSION_END, NULL); + + rnd_exporter = NULL; + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_Backup[] = "Backup()"; +static const char pcb_acth_Backup[] = "Backup the current layout - save using the same method that the timed backup function uses"; +static fgw_error_t pcb_act_Backup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_backup(); + RND_ACT_IRES(0); + return 0; +} + +rnd_action_t file_action_list[] = { + {"Backup", pcb_act_Backup, pcb_acth_Backup, pcb_acts_Backup}, + {"Export", pcb_act_Export, pcb_acth_Export, pcb_acts_Export}, + {"LoadFrom", pcb_act_LoadFrom, pcb_acth_LoadFrom, pcb_acts_LoadFrom}, + {"New", pcb_act_New, pcb_acth_New, pcb_acts_New}, + {"Normalize", pcb_act_normalize, pcb_acth_normalize, pcb_acts_normalize}, + {"SaveTo", pcb_act_SaveTo, pcb_acth_SaveTo, pcb_acts_SaveTo}, + {"SaveLib", pcb_act_SaveLib, pcb_acth_SaveLib, pcb_acts_SaveLib}, + {"Quit", pcb_act_Quit, pcb_acth_Quit, pcb_acts_Quit} +}; + +void pcb_file_act_init2(void) +{ + RND_REGISTER_ACTIONS(file_action_list, NULL); +} Index: tags/2.3.0/src/find.c =================================================================== --- tags/2.3.0/src/find.c (nonexistent) +++ tags/2.3.0/src/find.c (revision 33253) @@ -0,0 +1,607 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Follow galvanic connections through overlapping objects */ + +#include "config.h" +#include +#include "find.h" +#include "undo.h" +#include "obj_subc_parent.h" + +const pcb_find_t pcb_find0_, *pcb_find0 = &pcb_find0_; + +#include "find_geo.c" +#include "find_any_isect.c" + +/* Multimark flags for a given object. This struct is used to store + partial marks for objects that have multiple independently connected + components: when such an object has the mark set that only means at + least one component is found. But then which components are found needs + to be looked up in an object-type-specific way from this struct. Multiple + component objects: + - padstacks: each (copper) layer may have a shape that is connected or not + (through a hole/slot) to others shapes; there can be only one + group of connections realized by the hole/slot and zero or + more independent shapes + - text: each drawing primitive should be a separate component (not yet implemented) + - poly: if fullpoly is on, each island is a separate component (not yet implemented) +*/ +typedef union pcb_find_mm_s { + unsigned char layers[(PCB_MAX_LAYER / 8)+1]; /* for pstk */ +} pcb_find_mm_t; + +/* Retrieve (or allocate) the multimark structure for a given object, storing + it in a cache in ctx. Also init the cache as needed */ +RND_INLINE pcb_find_mm_t *pcb_find_get_mm(pcb_find_t *ctx, pcb_any_obj_t *obj) +{ + pcb_find_mm_t *mm; + + if (!ctx->multimark_inited) { + htpp_init(&ctx->multimark, ptrhash, ptrkeyeq); + ctx->multimark_inited = 1; + mm = NULL; + } + else + mm = htpp_get(&ctx->multimark, obj); + + if (mm != NULL) + return mm; + + mm = calloc(sizeof(pcb_find_mm_t), 1); + htpp_set(&ctx->multimark, obj, mm); + return mm; +} + +/* Padstack: take all layers that are connected by a hole/slot and mark all + them. Useful when any of them gets marked, this is how the mark propagates + through the plated hole/slot */ +RND_INLINE void mark_all_hole_connections(pcb_find_t *ctx, pcb_pstk_t *ps, pcb_find_mm_t *mm) +{ + rnd_layer_id_t lid; + + for(lid = 0; lid < ctx->pcb->Data->LayerN; lid++) { + pcb_layer_t *ly = &ctx->pcb->Data->Layer[lid]; + pcb_pstk_shape_t *shp = pcb_pstk_shape_at(ctx->pcb, ps, ly); + if ((shp != NULL) && shp->hconn) + mm->layers[lid / 8] |= (1 << (lid % 8)); + } +} + +/* Set mark on components of a padstak: on the component that's on the same + layer as arrived_from, and any hole/slot connected other shapes */ +RND_INLINE void pcb_find_mark_set_pstk(pcb_find_t *ctx, pcb_any_obj_t *obj, pcb_any_obj_t *arrived_from) +{ + pcb_find_mm_t *mm; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto((pcb_pstk_t *)obj); + pcb_layer_t *ly; + pcb_data_t *data; + rnd_layer_id_t lid; + pcb_pstk_shape_t *shp; + + /* do anything only if there are disjoint copper shapes */ + if ((proto == NULL) || (proto->all_copper_connd && proto->hplated) || ((pcb_pstk_t *)obj)->term) + return; + + mm = pcb_find_get_mm(ctx, obj); + if (arrived_from != NULL) { + switch(arrived_from->type) { + case PCB_OBJ_LINE: + case PCB_OBJ_ARC: + case PCB_OBJ_TEXT: + case PCB_OBJ_POLY: + case PCB_OBJ_GFX: + /* single layer */ + ly = arrived_from->parent.layer; + assert(arrived_from->parent_type == PCB_PARENT_LAYER); + data = ly->parent.data; + lid = ly - data->Layer; + if ((lid < 0) || (lid >= PCB_MAX_LAYER)) { + assert(!"pcb_find_mark_set: invalid layer to arrive from"); + goto fallback1; + } + mm->layers[lid / 8] |= (1 << (lid % 8)); + + /* propagate the mark if the shape is connected to the hole/slot + (hconn) and the hole/slot is + plated */ + if ((ctx->pcb != NULL) && (proto->hplated)) { + shp = pcb_pstk_shape_at(ctx->pcb, (pcb_pstk_t *)obj, ly); + if (shp->hconn) + mark_all_hole_connections(ctx, (pcb_pstk_t *)obj, mm); + } + break; + case PCB_OBJ_PSTK: + if (arrived_from != obj) + rnd_message(RND_MSG_ERROR, "BUG: disjoint padstack overlap with disjoint padstack - not handled correctly\nPlease report htis bug with your board file!\n"); + goto fallback1; + default: + assert(!"pcb_find_mark_set: invalid arrived_from object type"); + goto fallback1; + } + } + else { + /* coming from NULL means starting object - mark all layers found */ + fallback1:; + memset(&mm->layers, 0xff, sizeof(mm->layers)); + } +} + + +/* Set found mark on an object. If arrived_from is NULL, obj is a starting + point for the search */ +RND_INLINE void pcb_find_mark_set(pcb_find_t *ctx, pcb_any_obj_t *obj, pcb_any_obj_t *arrived_from) +{ + PCB_DFLAG_SET(&obj->Flags, ctx->mark); + switch(obj->type) { + case PCB_OBJ_PSTK: pcb_find_mark_set_pstk(ctx, obj, arrived_from); break; + default: break; + } +} + +/* Return whether pstk is marked on the layer(s) specified by arrived_from. + If arrived_from is NULL, obj is a starting object and is always found. */ +RND_INLINE int pcb_find_mark_get_pstk(pcb_find_t *ctx, pcb_any_obj_t *obj, pcb_any_obj_t *arrived_from) +{ + pcb_find_mm_t *mm; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto((pcb_pstk_t *)obj); + pcb_layer_t *ly; + pcb_data_t *data; + rnd_layer_id_t lid; + + /* do anything only if there are disjoint copper shapes */ + if ((proto == NULL) || (proto->all_copper_connd && proto->hplated) || ((pcb_pstk_t *)obj)->term) + return 1; + + mm = pcb_find_get_mm(ctx, obj); + if (arrived_from != NULL) { + switch(arrived_from->type) { + case PCB_OBJ_LINE: + case PCB_OBJ_ARC: + case PCB_OBJ_TEXT: + case PCB_OBJ_POLY: + case PCB_OBJ_GFX: + /* single layer */ + ly = arrived_from->parent.layer; + assert(arrived_from->parent_type == PCB_PARENT_LAYER); + data = ly->parent.data; + lid = ly - data->Layer; + if ((lid < 0) || (lid >= PCB_MAX_LAYER)) { + assert(!"pcb_find_mark_get: invalid layer to arrive from"); + return 1; + } + return !!(mm->layers[lid / 8] & (1 << (lid % 8))); + case PCB_OBJ_PSTK: + if (arrived_from != obj) + rnd_message(RND_MSG_ERROR, "BUG: disjoint padstack overlap with disjoint padstack - not handled correctly\nPlease report htis bug with your board file!\n"); + return 1; + default: + assert(!"pcb_find_mark_get: invalid arrived_from object type"); + return 1; + } + } + /* coming from NULL means starting object - assume all layers affected */ + return 1; +} + +/* a variant of pcb_find_mark_get_pstk() where the target layer is explicitly + named instead of using an arrived_from object. ly can not be NULL */ +RND_INLINE int pcb_find_mark_get_pstk_on_layer(pcb_find_t *ctx, pcb_any_obj_t *obj, pcb_layer_t *ly) +{ + pcb_find_mm_t *mm; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto((pcb_pstk_t *)obj); + pcb_data_t *data; + rnd_layer_id_t lid; + + /* do anything only if there are disjoint copper shapes */ + if ((proto == NULL) || (proto->all_copper_connd && proto->hplated) || ((pcb_pstk_t *)obj)->term) + return 1; + + mm = pcb_find_get_mm(ctx, obj); + + data = ly->parent.data; + lid = ly - data->Layer; + if ((lid < 0) || (lid >= PCB_MAX_LAYER)) { + assert(!"pcb_find_mark_get: invalid layer to arrive from"); + return 1; + } + return !!(mm->layers[lid / 8] & (1 << (lid % 8))); +} + +/* Return whether object is marked on any component related to arrived_from. + If arrived_from is NULL, obj is a starting object and is always found. */ +RND_INLINE int pcb_find_mark_get(pcb_find_t *ctx, pcb_any_obj_t *obj, pcb_any_obj_t *arrived_from) +{ + if (PCB_DFLAG_TEST(&obj->Flags, ctx->mark) == 0) + return 0; + + switch(obj->type) { + case PCB_OBJ_PSTK: return pcb_find_mark_get_pstk(ctx, obj, arrived_from); + default: break; + } + + return 1; +} + +/* trickery: keeping vtp0 is reentrant and is cheaper than keeping lists, + at least for appending. But as long as only the last item is removed, + it's also cheap on remove! */ + +/* Do everything that needs to be done for an object found */ +static int pcb_find_found(pcb_find_t *ctx, pcb_any_obj_t *obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + int fr; + + if (ctx->list_found) + vtp0_append(&ctx->found, obj); + + if ((ctx->flag_set != 0) || (ctx->flag_clr != 0)) { + if (ctx->flag_chg_undoable) + pcb_undo_add_obj_to_flag(obj); + if (ctx->flag_set != 0) + PCB_FLAG_SET(ctx->flag_set, obj); + if (ctx->flag_clr != 0) + PCB_FLAG_CLEAR(ctx->flag_clr, obj); + } + + ctx->nfound++; + + if ((ctx->found_cb != NULL) && ((fr = ctx->found_cb(ctx, obj, arrived_from, ctype)) != 0)) { + if (fr == PCB_FIND_DROP_THREAD) + return 0; + ctx->aborted = 1; + return 1; + } + + return 0; +} + +static int pcb_find_addobj(pcb_find_t *ctx, pcb_any_obj_t *obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype, int jump) +{ + pcb_find_mark_set(ctx, obj, arrived_from); + + if (jump) + vtp0_append(&ctx->open, obj); + + if (pcb_find_found(ctx, obj, arrived_from, ctype) != 0) { + ctx->aborted = 1; + return 1; + } + return 0; +} + +static void find_int_conn(pcb_find_t *ctx, pcb_any_obj_t *from_) +{ + void *from = from_; /* for warningless comparison */ + pcb_subc_t *s; + int ic; + + s = pcb_obj_parent_subc(from_); + if (s == NULL) + return; + + ic = from_->intconn; + + /* it is okay to test for mark directly here: internal connection + assumes all-layer affection as it is a special case mostly used for SMD pads + and thru-hole pins; the flag means "found in any way" */ + + PCB_PADSTACK_LOOP(s->data); + { + if ((padstack != from) && (padstack->term != NULL) && (padstack->intconn == ic) && (!(PCB_DFLAG_TEST(&(padstack->Flags), ctx->mark)))) + if (pcb_find_addobj(ctx, (pcb_any_obj_t *)padstack, from_, PCB_FCT_INTCONN, 1) != 0) + return; + } + PCB_END_LOOP; + + PCB_LINE_COPPER_LOOP(s->data); + { + if ((line != from) && (line->term != NULL) && (line->intconn == ic) && (!(PCB_DFLAG_TEST(&(line->Flags), ctx->mark)))) + if (pcb_find_addobj(ctx, (pcb_any_obj_t *)line, from_, PCB_FCT_INTCONN, 1) != 0) + return; + } + PCB_ENDALL_LOOP; + + PCB_ARC_COPPER_LOOP(s->data); + { + if ((arc != from) && (arc->term != NULL) && (arc->intconn == ic) && (!(PCB_DFLAG_TEST(&(arc->Flags), ctx->mark)))) + if (pcb_find_addobj(ctx, (pcb_any_obj_t *)arc, from_, PCB_FCT_INTCONN, 1) != 0) + return; + } + PCB_ENDALL_LOOP; + + PCB_POLY_COPPER_LOOP(s->data); + { + if ((polygon != from) && (polygon->term != NULL) && (polygon->intconn == ic) && (!(PCB_DFLAG_TEST(&(polygon->Flags), ctx->mark)))) + if (pcb_find_addobj(ctx, (pcb_any_obj_t *)polygon, from_, PCB_FCT_INTCONN, 1) != 0) + return; + } + PCB_ENDALL_LOOP; + +TODO("find: no find through text yet") +#if 0 + PCB_TEXT_COPPER_LOOP(s->data); + { + if ((text != from) && (text->term != NULL) && (text->intconn == ic) && (!(PCB_DFLAG_TEST(&(text->Flags), ctx->mark)))) + if (pcb_find_addobj(ctx, (pcb_any_obj_t *)text, from_, PCB_FCT_INTCONN, 1) != 0) + return; + } + PCB_ENDALL_LOOP; +#endif +} + +/* return whether a and b are in the same internal-no-connection group */ +static rnd_bool int_noconn(pcb_any_obj_t *a, pcb_any_obj_t *b) +{ + pcb_subc_t *pa, *pb; + + /* cheap test: they need to have valid and matching intnoconn */ + if ((a->intnoconn == 0) || (a->intnoconn != b->intnoconn)) + return rnd_false; + + /* expensive tests: they need to be in the same subc */ + pa = pcb_obj_parent_subc(a); + if (pa == NULL) + return rnd_false; + + pb = pcb_obj_parent_subc(b); + + return (pa == pb); +} + +#define INOCONN(a,b) int_noconn((pcb_any_obj_t *)a, (pcb_any_obj_t *)b) + +#define PCB_FIND_CHECK(ctx, curr, obj, ctype, retstmt) \ + do { \ + pcb_any_obj_t *__obj__ = (pcb_any_obj_t *)obj; \ + if (!pcb_find_mark_get(ctx, __obj__, (curr))) { \ + if (!INOCONN(curr, obj) && (pcb_intersect_obj_obj(ctx, curr, __obj__))) {\ + if (pcb_find_addobj(ctx, __obj__, curr, ctype, 1) != 0) { retstmt; } \ + if ((__obj__->term != NULL) && (!ctx->ignore_intconn) && (__obj__->intconn > 0)) \ + find_int_conn(ctx, __obj__); \ + } \ + } \ + } while(0) + +#define PCB_FIND_CHECK_RAT(ctx, curr, obj, ctype, retstmt) \ + do { \ + pcb_any_obj_t *__obj__ = (pcb_any_obj_t *)obj; \ + if (!pcb_find_mark_get(ctx, __obj__, (curr))) { \ + if (!INOCONN(curr, obj) && (pcb_intersect_obj_obj(ctx, curr, __obj__))) {\ + if (pcb_find_addobj(ctx, __obj__, curr, ctype, ctx->consider_rats) != 0) { retstmt; } \ + if ((__obj__->term != NULL) && (!ctx->ignore_intconn) && (__obj__->intconn > 0)) \ + find_int_conn(ctx, __obj__); \ + } \ + } \ + } while(0) + +void pcb_find_on_layer(pcb_find_t *ctx, pcb_layer_t *l, pcb_any_obj_t *curr, rnd_rtree_box_t *sb, pcb_found_conn_type_t ctype) +{ + rnd_rtree_it_t it; + rnd_box_t *n; + + if (l->line_tree != NULL) + for(n = rnd_rtree_first(&it, l->line_tree, sb); n != NULL; n = rnd_rtree_next(&it)) + PCB_FIND_CHECK(ctx, curr, n, ctype, return); + + if (l->arc_tree != NULL) + for(n = rnd_rtree_first(&it, l->arc_tree, sb); n != NULL; n = rnd_rtree_next(&it)) + PCB_FIND_CHECK(ctx, curr, n, ctype, return); + + if (l->polygon_tree != NULL) + for(n = rnd_rtree_first(&it, l->polygon_tree, sb); n != NULL; n = rnd_rtree_next(&it)) + PCB_FIND_CHECK(ctx, curr, n, ctype, return); + + if (l->text_tree != NULL) + for(n = rnd_rtree_first(&it, l->text_tree, sb); n != NULL; n = rnd_rtree_next(&it)) + PCB_FIND_CHECK(ctx, curr, n, ctype, return); +} + +void pcb_find_on_layergrp(pcb_find_t *ctx, pcb_layergrp_t *g, pcb_any_obj_t *curr, rnd_rtree_box_t *sb, pcb_found_conn_type_t ctype) +{ + int n; + if (g == NULL) + return; + for(n = 0; n < g->len; n++) + pcb_find_on_layer(ctx, &ctx->data->Layer[g->lid[n]], curr, sb, ctype); +} + +static void pcb_find_rat(pcb_find_t *ctx, pcb_rat_t *rat) +{ + rnd_rtree_box_t sb; + + sb.x1 = rat->Point1.X; sb.x2 = rat->Point1.X+1; + sb.y1 = rat->Point1.Y; sb.y2 = rat->Point1.Y+1; + pcb_find_on_layergrp(ctx, pcb_get_layergrp(ctx->pcb, rat->group1), (pcb_any_obj_t *)rat, &sb, PCB_FCT_RAT); + + sb.x1 = rat->Point2.X; sb.x2 = rat->Point2.X+1; + sb.y1 = rat->Point2.Y; sb.y2 = rat->Point2.Y+1; + pcb_find_on_layergrp(ctx, pcb_get_layergrp(ctx->pcb, rat->group2), (pcb_any_obj_t *)rat, &sb, PCB_FCT_RAT); +} + +static unsigned long pcb_find_exec(pcb_find_t *ctx) +{ + pcb_any_obj_t *curr; + pcb_found_conn_type_t ctype; + + if ((ctx->start_layergrp == NULL) && (ctx->open.used > 0) && (ctx->pcb != NULL)) { + curr = ctx->open.array[0]; + if ((curr != NULL) && (curr->parent_type == PCB_PARENT_LAYER)) { + rnd_layergrp_id_t gid = pcb_layer_get_group_(curr->parent.layer); + ctx->start_layergrp = pcb_get_layergrp(ctx->pcb, gid); + if (!ctx->allow_noncopper) { + TODO("find.c: implement this; special case: starting layer object on non-copper can still jump on padstack!"); + } + } + } + + while((ctx->open.used > 0) && (!ctx->aborted)) { + /* pop the last object, without reallocating to smaller, mark it found */ + ctx->open.used--; + curr = ctx->open.array[ctx->open.used]; + ctype = curr->type == PCB_OBJ_RAT ? PCB_FCT_RAT : PCB_FCT_COPPER; + + { /* search unmkared connections: iterative approach */ + rnd_rtree_it_t it; + rnd_box_t *n; + rnd_rtree_box_t *sb = (rnd_rtree_box_t *)&curr->bbox_naked; + + if (PCB->Data->padstack_tree != NULL) + for(n = rnd_rtree_first(&it, PCB->Data->padstack_tree, sb); n != NULL; n = rnd_rtree_next(&it)) + PCB_FIND_CHECK(ctx, curr, n, ctype, return ctx->nfound); + + if ((ctx->consider_rats || ctx->only_mark_rats) && (PCB->Data->rat_tree != NULL)) + if (PCB->Data->padstack_tree != NULL) + for(n = rnd_rtree_first(&it, PCB->Data->rat_tree, sb); n != NULL; n = rnd_rtree_next(&it)) + PCB_FIND_CHECK_RAT(ctx, curr, n, PCB_FCT_RAT, return ctx->nfound); + + if (curr->type == PCB_OBJ_PSTK) { + int li; + pcb_layer_t *l; + if ((!ctx->stay_layergrp) || (ctx->start_layergrp == NULL)) { + pcb_pstk_proto_t *proto = pcb_pstk_get_proto((const pcb_pstk_t *)curr); + for(li = 0, l = ctx->data->Layer; li < ctx->data->LayerN; li++,l++) { + if (!ctx->allow_noncopper) { + /* skip anything that's not on a copper layer */ + pcb_layer_type_t lyt = pcb_layer_flags_(l); + if (!(lyt & PCB_LYT_COPPER)) + continue; + } + if (!pcb_find_mark_get_pstk_on_layer(ctx, curr, l)) + continue; /* padstack is not really found on this specific layer (it is marked found on other layers) */ + if (pcb_pstk_shape_at_(ctx->pcb, (pcb_pstk_t *)curr, l, 0)) + pcb_find_on_layer(ctx, l, curr, sb, ctype); + else if (proto->hplated) { /* consider plated slots */ + pcb_layer_t *rl = pcb_layer_get_real(l); + if (pcb_pstk_bb_drills(ctx->pcb, (const pcb_pstk_t *)curr, rl->meta.real.grp, NULL)) + pcb_find_on_layer(ctx, l, curr, sb, ctype); + } + } + } + else { + for(li = 0; li < ctx->start_layergrp->len; li++) { + l = pcb_get_layer(ctx->data, ctx->start_layergrp->lid[li]); + if (l != NULL) + pcb_find_on_layer(ctx, l, curr, sb, ctype); + } + } + } + else if (curr->type == PCB_OBJ_RAT) { + pcb_find_rat(ctx, (pcb_rat_t *)curr); + } + else { + pcb_layergrp_t *g; + /* layer objects need to be checked against objects in the same layer group only */ + assert(curr->parent_type == PCB_PARENT_LAYER); + g = pcb_get_layergrp(PCB, pcb_layer_get_group_(curr->parent.layer)); + if (g != NULL) /* g==NULL for inbound subc layers */ + pcb_find_on_layergrp(ctx, g, curr, sb, ctype); + } + } + } + + if (ctx->flag_chg_undoable) + pcb_undo_inc_serial(); + + return ctx->nfound; +} + +static int pcb_find_init_(pcb_find_t *ctx, pcb_data_t *data) +{ + if (ctx->in_use) + return -1; + ctx->in_use = 1; + ctx->aborted = 0; + ctx->mark = pcb_dynflag_alloc("pcb_find_from_obj"); + ctx->data = data; + ctx->nfound = 0; + ctx->start_layergrp = NULL; + ctx->pcb = pcb_data_get_top(data); + + if (ctx->list_found) + vtp0_init(&ctx->found); + vtp0_init(&ctx->open); + return 0; +} + +unsigned long pcb_find_from_obj(pcb_find_t *ctx, pcb_data_t *data, pcb_any_obj_t *from) +{ + if (pcb_find_init_(ctx, data) < 0) + return -1; + + pcb_data_dynflag_clear(data, ctx->mark); + if (from != NULL) { + pcb_find_addobj(ctx, from, NULL, PCB_FCT_START, 1); /* add the starting object with no 'arrived_from' */ + return pcb_find_exec(ctx); + } + return 0; +} + +unsigned long pcb_find_from_obj_next(pcb_find_t *ctx, pcb_data_t *data, pcb_any_obj_t *from) +{ + pcb_find_addobj(ctx, from, NULL, PCB_FCT_START, 1); /* add the starting object with no 'arrived_from' */ + return pcb_find_exec(ctx); +} + + +unsigned long pcb_find_from_xy(pcb_find_t *ctx, pcb_data_t *data, rnd_coord_t x, rnd_coord_t y) +{ + void *ptr1, *ptr2, *ptr3; + pcb_any_obj_t *obj; + int type; + + type = pcb_search_obj_by_location(PCB_LOOKUP_FIRST, &ptr1, &ptr2, &ptr3, x, y, PCB_SLOP * rnd_pixel_slop); + if (type == PCB_OBJ_VOID) + type = pcb_search_obj_by_location(PCB_LOOKUP_MORE, &ptr1, &ptr2, &ptr3, x, y, PCB_SLOP * rnd_pixel_slop); + + if (type == PCB_OBJ_VOID) + return -1; + + obj = ptr2; + if ((obj->parent_type == PCB_PARENT_LAYER) && ((pcb_layer_flags_(obj->parent.layer) & PCB_LYT_COPPER) == 0)) + return -1; /* non-conductive object */ + + return pcb_find_from_obj(ctx, data, obj); +} + + +void pcb_find_free(pcb_find_t *ctx) +{ + if (!ctx->in_use) + return; + if (ctx->multimark_inited) { + genht_uninit_deep(htpp, &ctx->multimark, { + free(htent->value); + }); \ + ctx->multimark_inited = 0; + } + if (ctx->list_found) + vtp0_uninit(&ctx->found); + vtp0_uninit(&ctx->open); + pcb_dynflag_free(ctx->mark); + ctx->in_use = 0; +} + Index: tags/2.3.0/src/find.h =================================================================== --- tags/2.3.0/src/find.h (nonexistent) +++ tags/2.3.0/src/find.h (revision 33253) @@ -0,0 +1,137 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Follow galvanic connections through overlapping objects */ + +#ifndef PCB_FIND2_H +#define PCB_FIND2_H + +#include +#include +#include "global_typedefs.h" +#include "flag.h" + +typedef enum { + PCB_FCT_COPPER = 1, /* copper connection */ + PCB_FCT_INTCONN = 2, /* subc internal connection, using the intconn attrib */ + PCB_FCT_RAT = 4, /* connected between a rat line and anything else */ + PCB_FCT_START = 8 /* starting object of a query */ +} pcb_found_conn_type_t; + +#define PCB_FIND_DROP_THREAD 4242 + +typedef struct pcb_find_s pcb_find_t; +struct pcb_find_s { + /* public config - all-zero uses the original method, except for flag set */ + /* low level (will work with isc calls): */ + rnd_coord_t bloat; /* perform intersection tests with one object bloated up by this amount (can be negative for shrinking) */ + unsigned ignore_clearance:1; /* a flag dictated clearance is no excuse for intersection - useful for overlap calculation between objects on different layers */ + unsigned allow_noncopper_pstk:1;/* when 1, even non-copper shapes of padstacks will "conduct" in a pstk-pstk check (useful for the drc) */ + unsigned pstk_anylayer:1; /* when 1, check every shape of the padstack for intersection, don't require it to be on the same layer */ + + /* high level (ignored by isc calls): */ + unsigned stay_layergrp:1; /* do not leave the layer (no padstack hop) */ + unsigned allow_noncopper:1; /* also run on non-copper objects */ + unsigned list_found:1; /* allow adding objects in the ->found vector */ + unsigned ignore_intconn:1; /* do not jump terminals on subc intconn */ + unsigned consider_rats:1; /* don't ignore rat lines, don't consider physical objects only */ + unsigned only_mark_rats:1; /* don't ignore rat lines, find them, but do not jump over them */ + unsigned flag_chg_undoable:1; /* when set, and flag_set or flag_clr is non-zero, put all found objects on the flag-undo before the flag change */ + unsigned long flag_set; /* when non-zero, set the static flag bits on objects found */ + unsigned long flag_clr; /* when non-zero, remove the static flag bits on objects found */ + + /* if non-NULL, call after an object is found; if returns non-zero, + set ->aborted and stop the search. When search started from an object, + it is called for the starting object as well. All object data and ctx + fields are updated for new_obj before the call. arrived_from is + the previous object (that already triggered a callback) from which + new_obj was first found; can be NULL for the starting object. ctype + describes the relation between arrived_from and new_obj. + If return PCB_FIND_DROP_THREAD, stop searching this thread of objects + and continue elsewhere. + */ + int (*found_cb)(pcb_find_t *ctx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype); + + /* public state/result */ + vtp0_t found; /* objects found, when list_found is 1 - of (pcb_any_obj_t *) */ + void *user_data; /* filled in by caller, not read or modified by find code */ + + /* private */ + vtp0_t open; /* objects already found but need checking for conns of (pcb_any_obj_t *) */ + pcb_data_t *data; + pcb_board_t *pcb; + pcb_layergrp_t *start_layergrp; + + /* marks if the object is ever found; in some cases this can be partial: + e.g. in some padstacks not all copper shapes are connected and there's + an extra bitfield for per-layer found bool; the extra per-component + found flags are stored in multimark */ + pcb_dynf_t mark; + htpp_t multimark; /* key=(pcb_any_obj_t *), value=(pcb_find_mm_t *), private to find.c */ + + unsigned long nfound; + unsigned in_use:1; + unsigned aborted:1; + unsigned multimark_inited:1; +}; + +extern const pcb_find_t *pcb_find0; /* nop-configuration for calling isc functions */ + +unsigned long pcb_find_from_xy(pcb_find_t *ctx, pcb_data_t *data, rnd_coord_t x, rnd_coord_t y); + +/* Find connections starting from an object. The obj() variant initializes the + search; if from is NULL, don't do the initial search. The obj_next() variant + assumes ctx is already initialized (by an obj()) and continues from that state */ +unsigned long pcb_find_from_obj(pcb_find_t *ctx, pcb_data_t *data, pcb_any_obj_t *from); +unsigned long pcb_find_from_obj_next(pcb_find_t *ctx, pcb_data_t *data, pcb_any_obj_t *from); + +void pcb_find_free(pcb_find_t *ctx); + +/* High level intersection function: returns if a and b intersect (overlap) */ +rnd_bool pcb_intersect_obj_obj(const pcb_find_t *ctx, pcb_any_obj_t *a, pcb_any_obj_t *b); + +/* Low level intersection functions: */ +rnd_bool pcb_isc_line_line(const pcb_find_t *ctx, pcb_line_t *Line1, pcb_line_t *Line2); +rnd_bool pcb_isc_line_arc(const pcb_find_t *ctx, pcb_line_t *Line, pcb_arc_t *Arc); +rnd_bool pcb_isc_arc_poly(const pcb_find_t *ctx, pcb_arc_t *Arc, pcb_poly_t *Polygon); +rnd_bool pcb_isc_arc_polyarea(const pcb_find_t *ctx, pcb_arc_t *Arc, rnd_polyarea_t *pa); +rnd_bool pcb_isc_line_poly(const pcb_find_t *ctx, pcb_line_t *Line, pcb_poly_t *Polygon); +rnd_bool pcb_isc_poly_poly(const pcb_find_t *ctx, pcb_poly_t *P1, pcb_poly_t *P2); +rnd_bool_t pcb_isc_pstk_line(const pcb_find_t *ctx, pcb_pstk_t *ps, pcb_line_t *line, rnd_bool anylayer); +#ifdef PCB_OBJ_PSTK_STRUCT_DECLARED +rnd_bool_t pcb_isc_pstk_line_shp(const pcb_find_t *ctx, pcb_pstk_t *ps, pcb_line_t *line, pcb_pstk_shape_t *shape); +rnd_polyarea_t *pcb_pstk_shape2polyarea(pcb_pstk_t *ps, pcb_pstk_shape_t *shape); +#endif + +/* Return whether obj is marked as already visited by the current search context */ +#define PCB_FIND_IS_MARKED(ctx, obj) PCB_DFLAG_TEST(&((obj)->Flags), (ctx)->mark) + +#define PCB_LOOKUP_FIRST \ + (PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART) +#define PCB_LOOKUP_MORE \ + (PCB_OBJ_LINE | PCB_OBJ_RAT | PCB_OBJ_POLY | PCB_OBJ_ARC | PCB_OBJ_GFX | PCB_OBJ_SUBC_PART) + +#endif Index: tags/2.3.0/src/find_any_isect.c =================================================================== --- tags/2.3.0/src/find_any_isect.c (nonexistent) +++ tags/2.3.0/src/find_any_isect.c (revision 33253) @@ -0,0 +1,149 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,2020 Tibor 'Igor2' Palinkas + * + * This module, diag, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + + +TODO("implement text intersections; same problem as with padstacks: can't mark a whole test as found") +rnd_bool pcb_isc_text_line(const pcb_find_t *ctx, pcb_text_t *a, pcb_line_t *b) { return rnd_false; } +rnd_bool pcb_isc_text_text(const pcb_find_t *ctx, pcb_text_t *a, pcb_text_t *b) { return rnd_false; } +rnd_bool pcb_isc_text_poly(const pcb_find_t *ctx, pcb_text_t *a, pcb_poly_t *b) { return rnd_false; } +rnd_bool pcb_isc_text_arc(const pcb_find_t *ctx, pcb_text_t *a, pcb_arc_t *b) { return rnd_false; } +rnd_bool pcb_isc_text_pstk(const pcb_find_t *ctx, pcb_text_t *a, pcb_pstk_t *b, rnd_bool anylayer) { return rnd_false; } + +rnd_bool pcb_intersect_obj_obj(const pcb_find_t *ctx, pcb_any_obj_t *a, pcb_any_obj_t *b) +{ + /* produce the clopped version for polygons to compare */ + if ((a->type == PCB_OBJ_POLY) && (((pcb_poly_t *)a)->Clipped == NULL)) + pcb_poly_init_clip(a->parent.layer->parent.data, a->parent.layer, (pcb_poly_t *)a); + if ((b->type == PCB_OBJ_POLY) && (((pcb_poly_t *)b)->Clipped == NULL)) + pcb_poly_init_clip(b->parent.layer->parent.data, b->parent.layer, (pcb_poly_t *)b); + + /* NOTE: for the time being GFX is not intersecting with anything because + graphics can't contribute to galvanic connections */ + + switch(a->type) { + case PCB_OBJ_VOID: return rnd_false; + case PCB_OBJ_LINE: + switch(b->type) { + case PCB_OBJ_VOID: return rnd_false; + case PCB_OBJ_LINE: return pcb_isc_line_line(ctx, (pcb_line_t *)a, (pcb_line_t *)b); + case PCB_OBJ_TEXT: return pcb_isc_text_line(ctx, (pcb_text_t *)b, (pcb_line_t *)a); + case PCB_OBJ_POLY: return pcb_isc_line_poly(ctx, (pcb_line_t *)a, (pcb_poly_t *)b); + case PCB_OBJ_ARC: return pcb_isc_line_arc(ctx, (pcb_line_t *)a, (pcb_arc_t *)b); +/* case PCB_OBJ_GFX: return pcb_isc_line_gfx(ctx, (pcb_line_t *)a, (pcb_gfx_t *)b);*/ + case PCB_OBJ_PSTK: return pcb_isc_pstk_line(ctx, (pcb_pstk_t *)b, (pcb_line_t *)a, ctx->pstk_anylayer); + case PCB_OBJ_RAT: return pcb_isc_rat_line(ctx, (pcb_rat_t *)b, (pcb_line_t *)a); + default:; + } + break; + case PCB_OBJ_TEXT: + switch(b->type) { + case PCB_OBJ_VOID: return rnd_false; + case PCB_OBJ_LINE: return pcb_isc_text_line(ctx, (pcb_text_t *)a, (pcb_line_t *)b); + case PCB_OBJ_TEXT: return pcb_isc_text_text(ctx, (pcb_text_t *)a, (pcb_text_t *)b); + case PCB_OBJ_POLY: return pcb_isc_text_poly(ctx, (pcb_text_t *)a, (pcb_poly_t *)b); + case PCB_OBJ_ARC: return pcb_isc_text_arc(ctx, (pcb_text_t *)a, (pcb_arc_t *)b); +/* case PCB_OBJ_GFX: return pcb_isc_text_gfx(ctx, (pcb_text_t *)a, (pcb_gfx_t *)b);*/ + case PCB_OBJ_PSTK: return pcb_isc_text_pstk(ctx, (pcb_text_t *)a, (pcb_pstk_t *)b, ctx->pstk_anylayer); + case PCB_OBJ_RAT: return rnd_false; /* text is invisible to find for now */ + default:; + } + break; + + case PCB_OBJ_POLY: + switch(b->type) { + case PCB_OBJ_VOID: return rnd_false; + case PCB_OBJ_LINE: return pcb_isc_line_poly(ctx, (pcb_line_t *)b, (pcb_poly_t *)a); + case PCB_OBJ_TEXT: return pcb_isc_text_poly(ctx, (pcb_text_t *)b, (pcb_poly_t *)a); + case PCB_OBJ_POLY: return pcb_isc_poly_poly(ctx, (pcb_poly_t *)a, (pcb_poly_t *)b); + case PCB_OBJ_ARC: return pcb_isc_arc_poly(ctx, (pcb_arc_t *)b, (pcb_poly_t *)a); +/* case PCB_OBJ_GFX: return pcb_isc_gfx_poly(ctx, (pcb_gfx_t *)b, (pcb_poly_t *)a);*/ + case PCB_OBJ_PSTK: return pcb_isc_pstk_poly(ctx, (pcb_pstk_t *)b, (pcb_poly_t *)a, ctx->pstk_anylayer); + case PCB_OBJ_RAT: return pcb_isc_rat_poly(ctx, (pcb_rat_t *)b, (pcb_poly_t *)a); + default:; + } + break; + case PCB_OBJ_ARC: + switch(b->type) { + case PCB_OBJ_VOID: return rnd_false; + case PCB_OBJ_LINE: return pcb_isc_line_arc(ctx, (pcb_line_t *)b, (pcb_arc_t *)a); + case PCB_OBJ_TEXT: return pcb_isc_text_arc(ctx, (pcb_text_t *)b, (pcb_arc_t *)a); + case PCB_OBJ_POLY: return pcb_isc_arc_poly(ctx, (pcb_arc_t *)a, (pcb_poly_t *)b); + case PCB_OBJ_ARC: return pcb_isc_arc_arc(ctx, (pcb_arc_t *)a, (pcb_arc_t *)b); +/* case PCB_OBJ_GFX: return pcb_isc_gfx_arc(ctx, (pcb_gfx_t *)a, (pcb_arc_t *)b);*/ + case PCB_OBJ_PSTK: return pcb_isc_pstk_arc(ctx, (pcb_pstk_t *)b, (pcb_arc_t *)a, ctx->pstk_anylayer); + case PCB_OBJ_RAT: return pcb_isc_rat_arc(ctx, (pcb_rat_t *)b, (pcb_arc_t *)a); + default:; + } + break; +/* case PCB_OBJ_GFX: + switch(b->type) { + case PCB_OBJ_VOID: return rnd_false; + case PCB_OBJ_LINE: return pcb_isc_line_gfx(ctx, (pcb_line_t *)b, (pcb_gfx_t *)a); + case PCB_OBJ_TEXT: return pcb_isc_text_gfx(ctx, (pcb_text_t *)b, (pcb_gfx_t *)a); + case PCB_OBJ_POLY: return pcb_isc_gfx_poly(ctx, (pcb_gfx_t *)a, (pcb_poly_t *)b); + case PCB_OBJ_ARC: return pcb_isc_arc_arc(ctx, (pcb_arc_t *)a, (pcb_arc_t *)b); + case PCB_OBJ_GFX: return pcb_isc_gfx_gfx(ctx, (pcb_gfx_t *)a, (pcb_gfx_t *)b); + case PCB_OBJ_PSTK: return pcb_isc_pstk_arc(ctx, (pcb_pstk_t *)b, (pcb_arc_t *)a); + case PCB_OBJ_RAT: return pcb_isc_rat_arc(ctx, (pcb_rat_t *)b, (pcb_arc_t *)a); + default:; + } + break;*/ + case PCB_OBJ_PSTK: + switch(b->type) { + case PCB_OBJ_VOID: return rnd_false; + case PCB_OBJ_LINE: return pcb_isc_pstk_line(ctx, (pcb_pstk_t *)a, (pcb_line_t *)b, ctx->pstk_anylayer); + case PCB_OBJ_TEXT: return pcb_isc_text_pstk(ctx, (pcb_text_t *)b, (pcb_pstk_t *)a, ctx->pstk_anylayer); + case PCB_OBJ_POLY: return pcb_isc_pstk_poly(ctx, (pcb_pstk_t *)a, (pcb_poly_t *)b, ctx->pstk_anylayer); + case PCB_OBJ_ARC: return pcb_isc_pstk_arc(ctx, (pcb_pstk_t *)a, (pcb_arc_t *)b, ctx->pstk_anylayer); +/* case PCB_OBJ_GFX: return pcb_isc_pstk_gfx(ctx, (pcb_pstk_t *)a, (pcb_gfx_t *)b, ctx->pstk_anylayer);*/ + case PCB_OBJ_PSTK: return pcb_isc_pstk_pstk(ctx, (pcb_pstk_t *)a, (pcb_pstk_t *)b, ctx->pstk_anylayer); + case PCB_OBJ_RAT: return pcb_isc_pstk_rat(ctx, (pcb_pstk_t *)a, (pcb_rat_t *)b); + default:; + } + break; + case PCB_OBJ_RAT: + switch(b->type) { + case PCB_OBJ_VOID: return rnd_false; + case PCB_OBJ_LINE: return pcb_isc_rat_line(ctx, (pcb_rat_t *)a, (pcb_line_t *)b); + case PCB_OBJ_TEXT: return rnd_false; /* text is invisible to find for now */ + case PCB_OBJ_POLY: return pcb_isc_rat_poly(ctx, (pcb_rat_t *)a, (pcb_poly_t *)b); + case PCB_OBJ_ARC: return pcb_isc_rat_arc(ctx, (pcb_rat_t *)a, (pcb_arc_t *)b); +/* case PCB_OBJ_GFX: return pcb_isc_rat_gfx(ctx, (pcb_rat_t *)a, (pcb_gfx_t *)b);*/ + case PCB_OBJ_PSTK: return pcb_isc_pstk_rat(ctx, (pcb_pstk_t *)b, (pcb_rat_t *)a); + case PCB_OBJ_RAT: return pcb_isc_rat_rat(ctx, (pcb_rat_t *)a, (pcb_rat_t *)b); + default:; + } + break; + default:; + } + assert(!"Don't know how to check intersection of these objet types"); + return rnd_false; +} + + Index: tags/2.3.0/src/find_geo.c =================================================================== --- tags/2.3.0/src/find_geo.c (nonexistent) +++ tags/2.3.0/src/find_geo.c (revision 33253) @@ -0,0 +1,1334 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2005 Thomas Nau + * pcb-rnd 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Generic geometric functions used by find.c lookup */ + +/* + * Intersection of line <--> circle: + * - calculate the signed distance from the line to the center, + * return false if abs(distance) > R + * - get the distance from the line <--> distancevector intersection to + * (X1,Y1) in range [0,1], return rnd_true if 0 <= distance <= 1 + * - depending on (r > 1.0 or r < 0.0) check the distance of X2,Y2 or X1,Y1 + * to X,Y + * + * Intersection of line <--> line: + * - see the description of 'pcb_isc_line_line()' + */ + +#include "obj_arc_ui.h" +#include "obj_pstk_inlines.h" +#include "obj_poly.h" +#include "search.h" + +#define Bloat ctx->bloat + +/* This is required for fullpoly: whether an object bbox intersects a poly + bbox can't be determined by a single contour check because there might be + multiple contours. Returns 1 if obj bbox intersects any island's bbox */ +RND_INLINE int box_isc_poly_any_island_bbox(const pcb_find_t *ctx, const rnd_box_t *box, const pcb_poly_t *poly, int first_only) +{ + pcb_poly_it_t it; + rnd_polyarea_t *pa; + + /* first, iterate over all islands of a polygon */ + for(pa = pcb_poly_island_first(poly, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_pline_t *c = pcb_poly_contour(&it); + if ((box->X1 <= c->xmax + Bloat) && (box->X2 >= c->xmin - Bloat) && + (box->Y1 <= c->ymax + Bloat) && (box->Y2 >= c->ymin - Bloat)) { return 1; } + if (first_only) + break; + } + + return 0; +} + + +/* This is required for fullpoly: whether an object intersects a poly + can't be determined by a single contour check because there might be + multiple contours. Returns 1 if obj's poly intersects any island's. + Frees objpoly at the end. */ +RND_INLINE int box_isc_poly_any_island_free(rnd_polyarea_t *objpoly, const pcb_poly_t *poly, int first_only) +{ + pcb_poly_it_t it; + rnd_polyarea_t *pa; + int ans; + + /* first, iterate over all islands of a polygon */ + for(pa = pcb_poly_island_first(poly, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + ans = rnd_polyarea_touching(objpoly, pa); + if (ans) + break; + if (first_only) + break; + } + rnd_polyarea_free(&objpoly); + return ans; +} + +/* reduce arc start angle and delta to 0..360 */ +static void normalize_angles(rnd_angle_t * sa, rnd_angle_t * d) +{ + if (*d < 0) { + *sa += *d; + *d = -*d; + } + if (*d > 360) /* full circle */ + *d = 360; + *sa = rnd_normalize_angle(*sa); +} + +static int radius_crosses_arc(double x, double y, pcb_arc_t *arc) +{ + double alpha = atan2(y - arc->Y, -x + arc->X) * RND_RAD_TO_DEG; + rnd_angle_t sa = arc->StartAngle, d = arc->Delta; + + normalize_angles(&sa, &d); + if (alpha < 0) + alpha += 360; + if (sa <= alpha) + return (sa + d) >= alpha; + return (sa + d - 360) >= alpha; +} + +static void get_arc_ends(rnd_coord_t * box, pcb_arc_t *arc) +{ + box[0] = arc->X - arc->Width * cos(RND_M180 * arc->StartAngle); + box[1] = arc->Y + arc->Height * sin(RND_M180 * arc->StartAngle); + box[2] = arc->X - arc->Width * cos(RND_M180 * (arc->StartAngle + arc->Delta)); + box[3] = arc->Y + arc->Height * sin(RND_M180 * (arc->StartAngle + arc->Delta)); +} + +/* --------------------------------------------------------------------------- + * check if two arcs intersect + * first we check for circle intersections, + * then find the actual points of intersection + * and test them to see if they are on arcs + * + * consider a, the distance from the center of arc 1 + * to the point perpendicular to the intersecting points. + * + * a = (r1^2 - r2^2 + l^2)/(2l) + * + * the perpendicular distance to the point of intersection + * is then + * + * d = sqrt(r1^2 - a^2) + * + * the points of intersection would then be + * + * x = X1 + a/l dx +- d/l dy + * y = Y1 + a/l dy -+ d/l dx + * + * where dx = X2 - X1 and dy = Y2 - Y1 + * + * + */ +static rnd_bool pcb_isc_arc_arc(const pcb_find_t *ctx, pcb_arc_t *Arc1, pcb_arc_t *Arc2) +{ + double x, y, dx, dy, r1, r2, a, d, l, t, t1, t2, dl; + rnd_coord_t pdx, pdy; + rnd_coord_t box[8]; + + t = 0.5 * Arc1->Thickness + Bloat; + t2 = 0.5 * Arc2->Thickness; + t1 = t2 + Bloat; + + /* too thin arc */ + if (t < 0 || t1 < 0) + return rnd_false; + + /* try the end points first */ + get_arc_ends(&box[0], Arc1); + get_arc_ends(&box[4], Arc2); + if (pcb_is_point_on_arc(box[0], box[1], t, Arc2) + || pcb_is_point_on_arc(box[2], box[3], t, Arc2) + || pcb_is_point_on_arc(box[4], box[5], t, Arc1) + || pcb_is_point_on_arc(box[6], box[7], t, Arc1)) + return rnd_true; + + pdx = Arc2->X - Arc1->X; + pdy = Arc2->Y - Arc1->Y; + dl = rnd_distance(Arc1->X, Arc1->Y, Arc2->X, Arc2->Y); + /* concentric arcs, simpler intersection conditions */ + if (dl < 0.5) { + if ((Arc1->Width - t >= Arc2->Width - t2 && Arc1->Width - t <= Arc2->Width + t2) + || (Arc1->Width + t >= Arc2->Width - t2 && Arc1->Width + t <= Arc2->Width + t2)) { + rnd_angle_t sa1 = Arc1->StartAngle, d1 = Arc1->Delta; + rnd_angle_t sa2 = Arc2->StartAngle, d2 = Arc2->Delta; + /* NB the endpoints have already been checked, + so we just compare the angles */ + + normalize_angles(&sa1, &d1); + normalize_angles(&sa2, &d2); + /* sa1 == sa2 was caught when checking endpoints */ + if (sa1 > sa2) + if (sa1 < sa2 + d2 || sa1 + d1 - 360 > sa2) + return rnd_true; + if (sa2 > sa1) + if (sa2 < sa1 + d1 || sa2 + d2 - 360 > sa1) + return rnd_true; + } + return rnd_false; + } + r1 = Arc1->Width; + r2 = Arc2->Width; + /* arcs centerlines are too far or too near */ + if (dl > r1 + r2 || dl + r1 < r2 || dl + r2 < r1) { + /* check the nearest to the other arc's center point */ + dx = pdx * r1 / dl; + dy = pdy * r1 / dl; + if (dl + r1 < r2) { /* Arc1 inside Arc2 */ + dx = -dx; + dy = -dy; + } + + if (radius_crosses_arc(Arc1->X + dx, Arc1->Y + dy, Arc1) + && pcb_is_point_on_arc(Arc1->X + dx, Arc1->Y + dy, t, Arc2)) + return rnd_true; + + dx = -pdx * r2 / dl; + dy = -pdy * r2 / dl; + if (dl + r2 < r1) { /* Arc2 inside Arc1 */ + dx = -dx; + dy = -dy; + } + + if (radius_crosses_arc(Arc2->X + dx, Arc2->Y + dy, Arc2) + && pcb_is_point_on_arc(Arc2->X + dx, Arc2->Y + dy, t1, Arc1)) + return rnd_true; + return rnd_false; + } + + l = dl * dl; + r1 *= r1; + r2 *= r2; + a = 0.5 * (r1 - r2 + l) / l; + r1 = r1 / l; + d = r1 - a * a; + /* the circles are too far apart to touch or probably just touch: + check the nearest point */ + if (d < 0) + d = 0; + else + d = sqrt(d); + x = Arc1->X + a * pdx; + y = Arc1->Y + a * pdy; + dx = d * pdx; + dy = d * pdy; + if (radius_crosses_arc(x + dy, y - dx, Arc1) + && pcb_is_point_on_arc(x + dy, y - dx, t, Arc2)) + return rnd_true; + if (radius_crosses_arc(x + dy, y - dx, Arc2) + && pcb_is_point_on_arc(x + dy, y - dx, t1, Arc1)) + return rnd_true; + + if (radius_crosses_arc(x - dy, y + dx, Arc1) + && pcb_is_point_on_arc(x - dy, y + dx, t, Arc2)) + return rnd_true; + if (radius_crosses_arc(x - dy, y + dx, Arc2) + && pcb_is_point_on_arc(x - dy, y + dx, t1, Arc1)) + return rnd_true; + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * Tests if point is same as line end point or center point + */ +static rnd_bool pcb_isc_ratp_line(const pcb_find_t *ctx, rnd_point_t *Point, pcb_line_t *Line) +{ + rnd_coord_t cx, cy; + + /* either end */ + if ((Point->X == Line->Point1.X && Point->Y == Line->Point1.Y) + || (Point->X == Line->Point2.X && Point->Y == Line->Point2.Y)) + return rnd_true; + + /* middle point */ + pcb_obj_center((pcb_any_obj_t *)Line, &cx, &cy); + if ((Point->X == cx) && (Point->Y == cy)) + return rnd_true; + + return rnd_false; +} + +/* Tests any end of a rat line is on the line */ +static rnd_bool pcb_isc_rat_line(const pcb_find_t *ctx, pcb_rat_t *rat, pcb_line_t *line) +{ + rnd_layergrp_id_t gid = pcb_layer_get_group_(line->parent.layer); + + if ((rat->group1 == gid) && pcb_isc_ratp_line(ctx, &rat->Point1, line)) + return rnd_true; + if ((rat->group2 == gid) && pcb_isc_ratp_line(ctx, &rat->Point2, line)) + return rnd_true; + + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * Tests if point is same as arc end point or center point + */ +static rnd_bool pcb_isc_ratp_arc(const pcb_find_t *ctx, rnd_point_t *Point, pcb_arc_t *arc) +{ + rnd_coord_t cx, cy; + + /* either end */ + pcb_arc_get_end(arc, 0, &cx, &cy); + if ((Point->X == cx) && (Point->Y == cy)) + return rnd_true; + + pcb_arc_get_end(arc, 1, &cx, &cy); + if ((Point->X == cx) && (Point->Y == cy)) + return rnd_true; + + /* middle point */ + pcb_arc_middle(arc, &cx, &cy); + if ((Point->X == cx) && (Point->Y == cy)) + return rnd_true; + + return rnd_false; +} + +/* Tests any end of a rat line is on the arc */ +static rnd_bool pcb_isc_rat_arc(const pcb_find_t *ctx, pcb_rat_t *rat, pcb_arc_t *arc) +{ + rnd_layergrp_id_t gid = pcb_layer_get_group_(arc->parent.layer); + + if ((rat->group1 == gid) && pcb_isc_ratp_arc(ctx, &rat->Point1, arc)) + return rnd_true; + if ((rat->group2 == gid) && pcb_isc_ratp_arc(ctx, &rat->Point2, arc)) + return rnd_true; + + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * Tests if rat line point is connected to a polygon + */ +static rnd_bool pcb_isc_ratp_poly(const pcb_find_t *ctx, rnd_point_t *Point, pcb_poly_t *polygon, int donut) +{ + rnd_coord_t cx, cy; + pcb_poly_it_t it; + rnd_polyarea_t *pa; + + /* clipped out of existence... */ + if (polygon->Clipped == NULL) + return rnd_false; + + /* special case: zero length connection */ + if (donut) + return pcb_poly_is_point_in_p_ignore_holes(Point->X, Point->Y, polygon); + + /* canonical point */ + cx = polygon->Clipped->contours->head->point[0]; + cy = polygon->Clipped->contours->head->point[1]; + if ((Point->X == cx) && (Point->Y == cy)) + return rnd_true; + + /* middle point */ + pcb_obj_center((pcb_any_obj_t *)polygon, &cx, &cy); + if ((Point->X == cx) && (Point->Y == cy)) + return rnd_true; + + /* expensive test: the rat can end on any contour point */ + for(pa = pcb_poly_island_first(polygon, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_coord_t x, y; + rnd_pline_t *pl; + int go; + + pl = pcb_poly_contour(&it); + if (pl != NULL) { + /* contour of the island */ + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) + if ((Point->X == x) && (Point->Y == y)) + return rnd_true; + + /* iterate over all holes within this island */ + for(pl = pcb_poly_hole_first(&it); pl != NULL; pl = pcb_poly_hole_next(&it)) + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) + if ((Point->X == x) && (Point->Y == y)) + return rnd_true; + } + if (!PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, polygon)) + break; + } + + return rnd_false; +} + +/* Tests any end of a rat line is on the poly */ +static rnd_bool pcb_isc_rat_poly(const pcb_find_t *ctx, pcb_rat_t *rat, pcb_poly_t *poly) +{ + rnd_layergrp_id_t gid = pcb_layer_get_group_(poly->parent.layer); + int donut = PCB_FLAG_TEST(PCB_FLAG_VIA, rat); + + if ((rat->group1 == gid) && pcb_isc_ratp_poly(ctx, &rat->Point1, poly, donut)) + return rnd_true; + if ((rat->group2 == gid) && pcb_isc_ratp_poly(ctx, &rat->Point2, poly, donut)) + return rnd_true; + + return rnd_false; +} + +/* Tests any end of a rat line is on the other rat */ +static rnd_bool pcb_isc_rat_rat(const pcb_find_t *ctx, pcb_rat_t *r1, pcb_rat_t *r2) +{ + if ((r1->group1 == r2->group1) && (r1->Point1.X == r2->Point1.X) && (r1->Point1.Y == r2->Point1.Y)) + return rnd_true; + if ((r1->group2 == r2->group2) && (r1->Point2.X == r2->Point2.X) && (r1->Point2.Y == r2->Point2.Y)) + return rnd_true; + if ((r1->group1 == r2->group2) && (r1->Point1.X == r2->Point2.X) && (r1->Point1.Y == r2->Point2.Y)) + return rnd_true; + if ((r1->group2 == r2->group1) && (r1->Point2.X == r2->Point1.X) && (r1->Point2.Y == r2->Point1.Y)) + return rnd_true; + return rnd_false; +} + +static void form_slanted_rectangle(rnd_point_t p[4], pcb_line_t *l) +/* writes vertices of a squared line */ +{ + double dwx = 0, dwy = 0; + if (l->Point1.Y == l->Point2.Y) + dwx = l->Thickness / 2.0; + else if (l->Point1.X == l->Point2.X) + dwy = l->Thickness / 2.0; + else { + rnd_coord_t dX = l->Point2.X - l->Point1.X; + rnd_coord_t dY = l->Point2.Y - l->Point1.Y; + double r = rnd_distance(l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y); + dwx = l->Thickness / 2.0 / r * dX; + dwy = l->Thickness / 2.0 / r * dY; + } + p[0].X = l->Point1.X - dwx + dwy; + p[0].Y = l->Point1.Y - dwy - dwx; + p[1].X = l->Point1.X - dwx - dwy; + p[1].Y = l->Point1.Y - dwy + dwx; + p[2].X = l->Point2.X + dwx - dwy; + p[2].Y = l->Point2.Y + dwy + dwx; + p[3].X = l->Point2.X + dwx + dwy; + p[3].Y = l->Point2.Y + dwy - dwx; +} + +/* --------------------------------------------------------------------------- + * checks if two lines intersect + * from news FAQ: + * + * Let A,B,C,D be 2-space position vectors. Then the directed line + * segments AB & CD are given by: + * + * AB=A+r(B-A), r in [0,1] + * CD=C+s(D-C), s in [0,1] + * + * If AB & CD intersect, then + * + * A+r(B-A)=C+s(D-C), or + * + * XA+r(XB-XA)=XC+s(XD-XC) + * YA+r(YB-YA)=YC+s(YD-YC) for some r,s in [0,1] + * + * Solving the above for r and s yields + * + * (YA-YC)(XD-XC)-(XA-XC)(YD-YC) + * r = ----------------------------- (eqn 1) + * (XB-XA)(YD-YC)-(YB-YA)(XD-XC) + * + * (YA-YC)(XB-XA)-(XA-XC)(YB-YA) + * s = ----------------------------- (eqn 2) + * (XB-XA)(YD-YC)-(YB-YA)(XD-XC) + * + * Let I be the position vector of the intersection point, then + * + * I=A+r(B-A) or + * + * XI=XA+r(XB-XA) + * YI=YA+r(YB-YA) + * + * By examining the values of r & s, you can also determine some + * other limiting conditions: + * + * If 0<=r<=1 & 0<=s<=1, intersection exists + * r<0 or r>1 or s<0 or s>1 line segments do not intersect + * + * If the denominator in eqn 1 is zero, AB & CD are parallel + * If the numerator in eqn 1 is also zero, AB & CD are coincident + * + * If the intersection point of the 2 lines are needed (lines in this + * context mean infinite lines) regardless whether the two line + * segments intersect, then + * + * If r>1, I is located on extension of AB + * If r<0, I is located on extension of BA + * If s>1, I is located on extension of CD + * If s<0, I is located on extension of DC + * + * Also note that the denominators of eqn 1 & 2 are identical. + * + */ +rnd_bool pcb_isc_line_line(const pcb_find_t *ctx, pcb_line_t *Line1, pcb_line_t *Line2) +{ + double s, r; + double line1_dx, line1_dy, line2_dx, line2_dy, point1_dx, point1_dy; + if (PCB_FLAG_TEST(PCB_FLAG_SQUARE, Line1)) { /* pretty reckless recursion */ + rnd_point_t p[4]; + form_slanted_rectangle(p, Line1); + return pcb_is_line_in_quadrangle(p, Line2); + } + /* here come only round Line1 because pcb_is_line_in_quadrangle() + calls pcb_isc_line_line() with first argument rounded */ + if (PCB_FLAG_TEST(PCB_FLAG_SQUARE, Line2)) { + rnd_point_t p[4]; + form_slanted_rectangle(p, Line2); + return pcb_is_line_in_quadrangle(p, Line1); + } + /* now all lines are round */ + + /* Check endpoints: this provides a quick exit, catches + * cases where the "real" lines don't intersect but the + * thick lines touch, and ensures that the dx/dy business + * below does not cause a divide-by-zero. */ + if (pcb_is_point_in_line(Line2->Point1.X, Line2->Point1.Y, MAX(Line2->Thickness / 2 + Bloat, 0), (pcb_any_line_t *) Line1) + || pcb_is_point_in_line(Line2->Point2.X, Line2->Point2.Y, MAX(Line2->Thickness / 2 + Bloat, 0), (pcb_any_line_t *) Line1) + || pcb_is_point_in_line(Line1->Point1.X, Line1->Point1.Y, MAX(Line1->Thickness / 2 + Bloat, 0), (pcb_any_line_t *) Line2) + || pcb_is_point_in_line(Line1->Point2.X, Line1->Point2.Y, MAX(Line1->Thickness / 2 + Bloat, 0), (pcb_any_line_t *) Line2)) + return rnd_true; + + /* setup some constants */ + line1_dx = Line1->Point2.X - Line1->Point1.X; + line1_dy = Line1->Point2.Y - Line1->Point1.Y; + line2_dx = Line2->Point2.X - Line2->Point1.X; + line2_dy = Line2->Point2.Y - Line2->Point1.Y; + point1_dx = Line1->Point1.X - Line2->Point1.X; + point1_dy = Line1->Point1.Y - Line2->Point1.Y; + + /* If either line is a point, we have failed already, since the + * endpoint check above will have caught an "intersection". */ + if ((line1_dx == 0 && line1_dy == 0) + || (line2_dx == 0 && line2_dy == 0)) + return rnd_false; + + /* set s to cross product of Line1 and the line + * Line1.Point1--Line2.Point1 (as vectors) */ + s = point1_dy * line1_dx - point1_dx * line1_dy; + + /* set r to cross product of both lines (as vectors) */ + r = line1_dx * line2_dy - line1_dy * line2_dx; + + /* No cross product means parallel lines, or maybe Line2 is + * zero-length. In either case, since we did a bounding-box + * check before getting here, the above pcb_is_point_in_line() checks + * will have caught any intersections. */ + if (r == 0.0) + return rnd_false; + + s /= r; + r = (point1_dy * line2_dx - point1_dx * line2_dy) / r; + + /* intersection is at least on AB */ + if (r >= 0.0 && r <= 1.0) + return (s >= 0.0 && s <= 1.0); + + /* intersection is at least on CD */ + /* [removed this case since it always returns rnd_false --asp] */ + return rnd_false; +} + +/*--------------------------------------------------- + * + * Check for line intersection with an arc + * + * Mostly this is like the circle/line intersection + * found in pcb_is_point_on_line(search.c) see the detailed + * discussion for the basics there. + * + * Since this is only an arc, not a full circle we need + * to find the actual points of intersection with the + * circle, and see if they are on the arc. + * + * To do this, we translate along the line from the point Q + * plus or minus a distance delta = sqrt(Radius^2 - d^2) + * but it's handy to normalize with respect to l, the line + * length so a single projection is done (e.g. we don't first + * find the point Q + * + * The projection is now of the form + * + * Px = X1 + (r +- r2)(X2 - X1) + * Py = Y1 + (r +- r2)(Y2 - Y1) + * + * Where r2 sqrt(Radius^2 l^2 - d^2)/l^2 + * note that this is the variable d, not the symbol d described in IsPointOnLine + * (variable d = symbol d * l) + * + * The end points are hell so they are checked individually + */ +rnd_bool pcb_isc_line_arc(const pcb_find_t *ctx, pcb_line_t *Line, pcb_arc_t *Arc) +{ + double dx, dy, dx1, dy1, l, d, r, r2, Radius; + rnd_coord_t ex, ey; + + dx = Line->Point2.X - Line->Point1.X; + dy = Line->Point2.Y - Line->Point1.Y; + dx1 = Line->Point1.X - Arc->X; + dy1 = Line->Point1.Y - Arc->Y; + l = dx * dx + dy * dy; + d = dx * dy1 - dy * dx1; + d *= d; + + /* use the larger diameter circle first */ + Radius = Arc->Width + MAX(0.5 * (Arc->Thickness + Line->Thickness) + Bloat, 0.0); + Radius *= Radius; + r2 = Radius * l - d; + /* projection doesn't even intersect circle when r2 < 0 */ + if (r2 < 0) + return rnd_false; + /* check the ends of the line in case the projected point */ + /* of intersection is beyond the line end */ + if (pcb_is_point_on_arc(Line->Point1.X, Line->Point1.Y, MAX(0.5 * Line->Thickness + Bloat, 0.0), Arc)) + return rnd_true; + if (pcb_is_point_on_arc(Line->Point2.X, Line->Point2.Y, MAX(0.5 * Line->Thickness + Bloat, 0.0), Arc)) + return rnd_true; + if (l == 0.0) + return rnd_false; + r2 = sqrt(r2); + Radius = -(dx * dx1 + dy * dy1); + r = (Radius + r2) / l; + if (r >= 0 && r <= 1 + && pcb_is_point_on_arc(Line->Point1.X + r * dx, Line->Point1.Y + r * dy, MAX(0.5 * Line->Thickness + Bloat, 0.0) + 1, Arc)) + return rnd_true; + r = (Radius - r2) / l; + if (r >= 0 && r <= 1 + && pcb_is_point_on_arc(Line->Point1.X + r * dx, Line->Point1.Y + r * dy, MAX(0.5 * Line->Thickness + Bloat, 0.0) + 1, Arc)) + return rnd_true; + + /* check arc end points */ + pcb_arc_get_end(Arc, 0, &ex, &ey); + if (pcb_is_point_in_line(ex, ey, Arc->Thickness * 0.5 + Bloat, (pcb_any_line_t *) Line)) + return rnd_true; + + pcb_arc_get_end(Arc, 1, &ex, &ey); + if (pcb_is_point_in_line(ex, ey, Arc->Thickness * 0.5 + Bloat, (pcb_any_line_t *) Line)) + return rnd_true; + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * checks if an arc has a connection to a polygon + * + * - first check if the arc can intersect with the polygon by + * evaluating the bounding boxes + * - check the two end points of the arc. If none of them matches + * - check all segments of the polygon against the arc. + */ +rnd_bool pcb_isc_arc_poly(const pcb_find_t *ctx, pcb_arc_t *Arc, pcb_poly_t *Polygon) +{ + rnd_box_t *Box = (rnd_box_t *) Arc; + + /* arcs with clearance never touch polys */ + if ((Bloat == 0) && !ctx->ignore_clearance && PCB_FLAG_TEST(PCB_FLAG_CLEARPOLY, Polygon) && PCB_OBJ_HAS_CLEARANCE(Arc)) + return rnd_false; + if (!Polygon->Clipped) + return rnd_false; + if (box_isc_poly_any_island_bbox(ctx, Box, Polygon, !PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, Polygon))) { + rnd_polyarea_t *ap; + + if (!(ap = pcb_poly_from_pcb_arc(Arc, Arc->Thickness + Bloat))) + return rnd_false; /* error */ + return box_isc_poly_any_island_free(ap, Polygon, !PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, Polygon)); + } + return rnd_false; +} + +rnd_bool pcb_isc_arc_polyarea(const pcb_find_t *ctx, pcb_arc_t *Arc, rnd_polyarea_t *pa) +{ + rnd_box_t *Box = (rnd_box_t *) Arc; + rnd_bool res = rnd_false; + + /* arcs with clearance never touch polys */ + if ((Box->X1 <= pa->contours->xmax + Bloat) && (Box->X2 >= pa->contours->xmin - Bloat) + && (Box->Y1 <= pa->contours->ymax + Bloat) && (Box->Y2 >= pa->contours->ymin - Bloat)) { + rnd_polyarea_t *arcp; + + if (!(arcp = pcb_poly_from_pcb_arc(Arc, Arc->Thickness + Bloat))) + return rnd_false; /* error */ + res = rnd_polyarea_touching(arcp, pa); + rnd_polyarea_free(&arcp); + } + return res; +} + + +/* --------------------------------------------------------------------------- + * checks if a line has a connection to a polygon + * + * - first check if the line can intersect with the polygon by + * evaluating the bounding boxes + * - check the two end points of the line. If none of them matches + * - check all segments of the polygon against the line. + */ +rnd_bool pcb_isc_line_poly(const pcb_find_t *ctx, pcb_line_t *Line, pcb_poly_t *Polygon) +{ + rnd_box_t *Box = (rnd_box_t *) Line; + rnd_polyarea_t *lp; + + /* lines with clearance never touch polygons */ + if ((Bloat == 0) && !ctx->ignore_clearance && PCB_FLAG_TEST(PCB_FLAG_CLEARPOLY, Polygon) && PCB_OBJ_HAS_CLEARANCE(Line)) + return rnd_false; + if (!Polygon->Clipped) + return rnd_false; + if (PCB_FLAG_TEST(PCB_FLAG_SQUARE, Line) && (Line->Point1.X == Line->Point2.X || Line->Point1.Y == Line->Point2.Y)) { + rnd_coord_t wid = (Line->Thickness + Bloat + 1) / 2; + rnd_coord_t x1, x2, y1, y2; + + x1 = MIN(Line->Point1.X, Line->Point2.X) - wid; + y1 = MIN(Line->Point1.Y, Line->Point2.Y) - wid; + x2 = MAX(Line->Point1.X, Line->Point2.X) + wid; + y2 = MAX(Line->Point1.Y, Line->Point2.Y) + wid; + return pcb_poly_is_rect_in_p(x1, y1, x2, y2, Polygon); + } + if (box_isc_poly_any_island_bbox(ctx, Box, Polygon, !PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, Polygon))) { + if (!(lp = pcb_poly_from_pcb_line(Line, Line->Thickness + Bloat))) + return rnd_false; /* error */ + return box_isc_poly_any_island_free(lp, Polygon, !PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, Polygon)); + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * checks if a polygon has a connection to a second one + * + * First check all points out of P1 against P2 and vice versa. + * If both fail check all lines of P1 against the ones of P2 + */ +rnd_bool pcb_isc_poly_poly(const pcb_find_t *ctx, pcb_poly_t *P1, pcb_poly_t *P2) +{ + int pcp_cnt = 0; + rnd_coord_t pcp_gap; + pcb_poly_it_t it1, it2; + rnd_polyarea_t *pa1, *pa2; + + if (!P1->Clipped || !P2->Clipped) + return rnd_false; + assert(P1->Clipped->contours); + assert(P2->Clipped->contours); + + /* first, iterate over all island pairs of the polygons to find if any of them has overlapping bbox */ + for(pa1 = pcb_poly_island_first(P1, &it1); pa1 != NULL; pa1 = pcb_poly_island_next(&it1)) { + rnd_pline_t *c1 = pcb_poly_contour(&it1); + for(pa2 = pcb_poly_island_first(P2, &it2); pa2 != NULL; pa2 = pcb_poly_island_next(&it2)) { + rnd_pline_t *c2 = pcb_poly_contour(&it2); + if ((c1->xmin - Bloat <= c2->xmax) && (c2->xmin <= c1->xmax + Bloat) && + (c1->ymin - Bloat <= c2->ymax) && (c2->ymin <= c1->ymax + Bloat)) { goto do_check; } + if (!PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, P2)) + break; + } + if (!PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, P1)) + break; + } + return rnd_false; + + do_check:; + + /* cheat: poly-clear-poly means we did generate the clearance; this + shall happen only if there's exactly one poly that is clearing the other */ + if ((Bloat == 0) && !ctx->ignore_clearance && PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, P1)) { + pcp_cnt++; + pcp_gap = pcb_obj_clearance_p2(P1, P2) / 2.0; + } + if (!ctx->ignore_clearance && PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, P2)) { + pcp_cnt++; + pcp_gap = pcb_obj_clearance_p2(P2, P1) / 2.0; + } + if (pcp_cnt == 1) { + if (pcp_gap >= Bloat) + return rnd_false; + return rnd_true; + } + + /* first check un-bloated case (most common) */ + if (Bloat == 0) { + for(pa1 = pcb_poly_island_first(P1, &it1); pa1 != NULL; pa1 = pcb_poly_island_next(&it1)) { + for(pa2 = pcb_poly_island_first(P2, &it2); pa2 != NULL; pa2 = pcb_poly_island_next(&it2)) { + if (rnd_polyarea_touching(pa1, pa2)) + return rnd_true; + if (!PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, P2)) + break; + } + if (!PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, P1)) + break; + } + } + + /* now the difficult case of bloated for each island vs. island */ + if (Bloat > 0) { + for(pa1 = pcb_poly_island_first(P1, &it1); pa1 != NULL; pa1 = pcb_poly_island_next(&it1)) { + rnd_pline_t *c1 = pcb_poly_contour(&it1); + for(pa2 = pcb_poly_island_first(P2, &it2); pa2 != NULL; pa2 = pcb_poly_island_next(&it2)) { + rnd_pline_t *c, *c2 = pcb_poly_contour(&it2); + + if (!((c1->xmin - Bloat <= c2->xmax) && (c2->xmin <= c1->xmax + Bloat) && + (c1->ymin - Bloat <= c2->ymax) && (c2->ymin <= c1->ymax + Bloat))) continue; + for (c = c1; c; c = c->next) { + pcb_line_t line; + rnd_vnode_t *v = c->head; + if (c->xmin - Bloat <= c2->xmax && c->xmax + Bloat >= c2->xmin && + c->ymin - Bloat <= c2->ymax && c->ymax + Bloat >= c2->ymin) { + + line.Point1.X = v->point[0]; + line.Point1.Y = v->point[1]; + line.Thickness = 2 * Bloat; + line.Clearance = 0; + line.Flags = pcb_no_flags(); + for (v = v->next; v != c->head; v = v->next) { + line.Point2.X = v->point[0]; + line.Point2.Y = v->point[1]; + pcb_line_bbox(&line); + if (pcb_isc_line_poly(ctx, &line, P2)) + return rnd_true; + line.Point1.X = line.Point2.X; + line.Point1.Y = line.Point2.Y; + } + } + } + if (!PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, P2)) + break; + } + if (!PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, P1)) + break; + } + } + + return rnd_false; +} + +/* returns whether a round-cap pcb line touches a polygon; assumes bounding + boxes do touch */ +RND_INLINE rnd_bool_t pcb_isc_line_polyline(const pcb_find_t *ctx, rnd_pline_t *pl, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t thick) +{ + rnd_coord_t ox, oy, vx, vy; + double dx, dy, h, l; + + thick += Bloat*2; + if (thick < 0) thick = 0; + + /* single-point line - check only one circle*/ + if ((x1 == x2) && (y1 == y2)) + return pcb_pline_overlaps_circ(pl, x1, y1, thick/2); + + /* long line - check ends */ + if (pcb_pline_overlaps_circ(pl, x1, y1, thick/2)) return rnd_true; + if (pcb_pline_overlaps_circ(pl, x2, y2, thick/2)) return rnd_true; + + dx = x2 - x1; + dy = y2 - y1; + l = sqrt(RND_SQUARE(dx) + RND_SQUARE(dy)); + h = 0.5 * thick / l; + ox = dy * h + 0.5 * SGN(dy); + oy = -(dx * h + 0.5 * SGN(dx)); + vx = (double)dx / -l * ((double)Bloat/2.0); + vy = (double)dy / -l * ((double)Bloat/2.0); + + /* long line - consider edge intersection */ + if (pcb_pline_isect_line(pl, x1 + ox + vx, y1 + oy + vy, x2 + ox - vx, y2 + oy - vy, NULL, NULL)) return rnd_true; + if (pcb_pline_isect_line(pl, x1 - ox + vx, y1 - oy + vy, x2 - ox - vx, y2 - oy - vy, NULL, NULL)) return rnd_true; + + /* A corner case is when the polyline is fully within the line. By now we + are sure there's no contour intersection, so if any of the polyline points + is in, the whole polyline is in. */ + { + rnd_vector_t q[4]; + + q[0][0] = x1 + ox; q[0][1] = y1 + oy; + q[1][0] = x2 + ox; q[1][1] = y2 + oy; + q[2][0] = x1 - ox; q[2][1] = y1 - oy; + q[3][0] = x2 - ox; q[3][1] = y2 - oy; + + return pcb_is_point_in_convex_quad(pl->head->point, q); + } +} + +#define shape_line_to_pcb_line(ps, shape_line, pcb_line) \ + do { \ + pcb_line.Point1.X = shape_line.x1 + ps->x; \ + pcb_line.Point1.Y = shape_line.y1 + ps->y; \ + pcb_line.Point2.X = shape_line.x2 + ps->x; \ + pcb_line.Point2.Y = shape_line.y2 + ps->y; \ + pcb_line.Clearance = 0; \ + pcb_line.Thickness = shape_line.thickness; \ + pcb_line.Flags = shape_line.square ? pcb_flag_make(PCB_FLAG_SQUARE) : pcb_no_flags(); \ + } while(0) + +rnd_bool_t pcb_isc_pstk_line_shp(const pcb_find_t *ctx, pcb_pstk_t *ps, pcb_line_t *line, pcb_pstk_shape_t *shape) +{ + if (shape == NULL) goto noshape; + + switch(shape->shape) { + case PCB_PSSH_POLY: + if (shape->data.poly.pa == NULL) + pcb_pstk_shape_update_pa(&shape->data.poly); + return pcb_isc_line_polyline(ctx, shape->data.poly.pa->contours, line->Point1.X - ps->x, line->Point1.Y - ps->y, line->Point2.X - ps->x, line->Point2.Y - ps->y, line->Thickness); + case PCB_PSSH_LINE: + { + pcb_line_t tmp; + shape_line_to_pcb_line(ps, shape->data.line, tmp); + return pcb_isc_line_line(ctx, line, &tmp); + } + case PCB_PSSH_CIRC: + { + pcb_any_line_t tmp; + tmp.Point1.X = line->Point1.X; + tmp.Point1.Y = line->Point1.Y; + tmp.Point2.X = line->Point2.X; + tmp.Point2.Y = line->Point2.Y; + tmp.Thickness = line->Thickness; + tmp.Flags = pcb_no_flags(); + return pcb_is_point_in_line(shape->data.circ.x + ps->x, shape->data.circ.y + ps->y, shape->data.circ.dia/2 + Bloat, &tmp); + } + case PCB_PSSH_HSHADOW: + /* if the line reaches the plated hole or slot, there's connection */ + noshape:; + { + pcb_pstk_shape_t *slshape, sltmp; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + if (!proto->hplated) + return 0; + + slshape = pcb_pstk_shape_mech_or_hole_at(PCB, ps, line->parent.layer, &sltmp); + if (slshape == NULL) + return rnd_false; + return pcb_isc_pstk_line_shp(ctx, ps, line, slshape); + } + } + return rnd_false; +} + +#define PCB_ISC_PSTK_ANYLAYER(ps, call) \ +do { \ + int n; \ + pcb_pstk_tshape_t *tshp = pcb_pstk_get_tshape(ps); \ + for(n = 0; n < tshp->len; n++) \ + if (call) \ + return rnd_true; \ + return rnd_false; \ +} while(0) + +rnd_bool_t pcb_isc_pstk_line(const pcb_find_t *ctx, pcb_pstk_t *ps, pcb_line_t *line, rnd_bool anylayer) +{ + pcb_pstk_shape_t *shape; + pcb_pstk_proto_t *proto; + + if (anylayer) + PCB_ISC_PSTK_ANYLAYER(ps, pcb_isc_pstk_line_shp(ctx, ps, line, &tshp->shape[n])); + + shape = pcb_pstk_shape_at(PCB, ps, line->parent.layer); + if (pcb_isc_pstk_line_shp(ctx, ps, line, shape)) + return rnd_true; + + proto = pcb_pstk_get_proto(ps); + if (proto->hplated) { + shape = pcb_pstk_shape_mech_at(PCB, ps, line->parent.layer); + if (pcb_isc_pstk_line_shp(ctx, ps, line, shape)) + return rnd_true; + } + + return rnd_false; +} + + +RND_INLINE rnd_bool_t pcb_isc_pstk_arc_shp(const pcb_find_t *ctx, pcb_pstk_t *ps, pcb_arc_t *arc, pcb_pstk_shape_t *shape) +{ + if (shape == NULL) goto noshape; + + switch(shape->shape) { + case PCB_PSSH_POLY: + { + pcb_arc_t tmp; + + /* transform the arc back to 0;0 of the padstack */ + tmp = *arc; + tmp.X -= ps->x; + tmp.Y -= ps->y; + tmp.BoundingBox.X1 -= ps->x; + tmp.BoundingBox.Y1 -= ps->y; + tmp.BoundingBox.X2 -= ps->x; + tmp.BoundingBox.Y2 -= ps->y; + + if (shape->data.poly.pa == NULL) + pcb_pstk_shape_update_pa(&shape->data.poly); + + return pcb_isc_arc_polyarea(ctx, &tmp, shape->data.poly.pa); + } + + case PCB_PSSH_LINE: + { + pcb_line_t tmp; + shape_line_to_pcb_line(ps, shape->data.line, tmp); + return pcb_isc_line_arc(ctx, &tmp, arc); + } + case PCB_PSSH_CIRC: + return pcb_is_point_on_arc(shape->data.circ.x + ps->x, shape->data.circ.y + ps->y, shape->data.circ.dia/2, arc); + case PCB_PSSH_HSHADOW: + /* if the arc reaches the plated hole or slot, there's connection */ + noshape:; + { + pcb_pstk_shape_t *slshape, sltmp; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + if (!proto->hplated) + return 0; + + slshape = pcb_pstk_shape_mech_or_hole_at(PCB, ps, arc->parent.layer, &sltmp); + if (slshape == NULL) + return rnd_false; + return pcb_isc_pstk_arc_shp(ctx, ps, arc, slshape); + } + } + return rnd_false; +} + +RND_INLINE rnd_bool_t pcb_isc_pstk_arc(const pcb_find_t *ctx, pcb_pstk_t *ps, pcb_arc_t *arc, rnd_bool anylayer) +{ + pcb_pstk_shape_t *shape; + pcb_pstk_proto_t *proto; + + if (anylayer) + PCB_ISC_PSTK_ANYLAYER(ps, pcb_isc_pstk_arc_shp(ctx, ps, arc, &tshp->shape[n])); + + shape = pcb_pstk_shape_at(PCB, ps, arc->parent.layer); + if (pcb_isc_pstk_arc_shp(ctx, ps, arc, shape)) + return rnd_true; + + proto = pcb_pstk_get_proto(ps); + if (proto->hplated) { + shape = pcb_pstk_shape_mech_at(PCB, ps, arc->parent.layer); + if (pcb_isc_pstk_arc_shp(ctx, ps, arc, shape)) + return rnd_true; + } + + return rnd_false; +} + + +RND_INLINE rnd_polyarea_t *pcb_pstk_shp_poly2area(pcb_pstk_t *ps, pcb_pstk_shape_t *shape) +{ + int n; + rnd_pline_t *pl; + rnd_vector_t v; + rnd_polyarea_t *shp = rnd_polyarea_create(); + + v[0] = shape->data.poly.x[0] + ps->x; v[1] = shape->data.poly.y[0] + ps->y; + pl = rnd_poly_contour_new(v); + for(n = 1; n < shape->data.poly.len; n++) { + v[0] = shape->data.poly.x[n] + ps->x; v[1] = shape->data.poly.y[n] + ps->y; + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + } + rnd_poly_contour_pre(pl, 1); + rnd_polyarea_contour_include(shp, pl); + + if (!rnd_poly_valid(shp)) { +/* rnd_polyarea_free(&shp); shp = rnd_polyarea_create();*/ + rnd_poly_contour_inv(pl); + rnd_polyarea_contour_include(shp, pl); + } + + return shp; +} + +RND_INLINE rnd_bool_t pcb_isc_pstk_poly_shp(const pcb_find_t *ctx, pcb_pstk_t *ps, pcb_poly_t *poly, pcb_pstk_shape_t *shape) +{ + if (shape == NULL) goto noshape; + + switch(shape->shape) { + case PCB_PSSH_POLY: + { + /* convert the shape poly to a new poly so that it can be intersected */ + rnd_bool res; + rnd_polyarea_t *shp = pcb_pstk_shp_poly2area(ps, shape); + res = rnd_polyarea_touching(shp, poly->Clipped); + rnd_polyarea_free(&shp); + return res; + } + case PCB_PSSH_LINE: + { + pcb_line_t tmp; + shape_line_to_pcb_line(ps, shape->data.line, tmp); + pcb_line_bbox(&tmp); + return pcb_isc_line_poly(ctx, &tmp, poly); + } + case PCB_PSSH_CIRC: + { + pcb_line_t tmp; + tmp.type = PCB_OBJ_LINE; + tmp.Point1.X = tmp.Point2.X = shape->data.circ.x + ps->x; + tmp.Point1.Y = tmp.Point2.Y = shape->data.circ.y + ps->y; + tmp.Clearance = 0; + tmp.Thickness = shape->data.circ.dia; + tmp.Flags = pcb_no_flags(); + pcb_line_bbox(&tmp); + return pcb_isc_line_poly(ctx, &tmp, poly); + } + case PCB_PSSH_HSHADOW: + /* if the poly reaches the plated hole or slot, there's connection */ + noshape:; + { + pcb_pstk_shape_t *slshape, sltmp; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + if (!proto->hplated) + return 0; + + slshape = pcb_pstk_shape_mech_or_hole_at(PCB, ps, poly->parent.layer, &sltmp); + if (slshape == NULL) + return rnd_false; + return pcb_isc_pstk_poly_shp(ctx, ps, poly, slshape); + } + + } + return rnd_false; +} + +rnd_polyarea_t *pcb_pstk_shape2polyarea(pcb_pstk_t *ps, pcb_pstk_shape_t *shape) +{ + pcb_line_t tmp; + pcb_pstk_proto_t *proto; + pcb_pstk_shape_t sltmp; + int tries = 0; + + if (shape == NULL) return NULL; + + retry:; + if (tries++ > 16) { + rnd_message(RND_MSG_ERROR, "pcb_pstk_shape2polyarea(): PCB_PSSH_HSHADOW recursion too deep\nPlease report this bug!\n"); + return NULL; + } + switch(shape->shape) { + case PCB_PSSH_POLY: + return pcb_pstk_shp_poly2area(ps, shape); + case PCB_PSSH_LINE: + shape_line_to_pcb_line(ps, shape->data.line, tmp); + goto retline; + case PCB_PSSH_CIRC: + tmp.type = PCB_OBJ_LINE; + tmp.Point1.X = tmp.Point2.X = shape->data.circ.x + ps->x; + tmp.Point1.Y = tmp.Point2.Y = shape->data.circ.y + ps->y; + tmp.Clearance = 0; + tmp.Thickness = shape->data.circ.dia; + tmp.Flags = pcb_no_flags(); + retline:; + return pcb_poly_from_pcb_line(&tmp, tmp.Thickness); + case PCB_PSSH_HSHADOW: + proto = pcb_pstk_get_proto(ps); + shape = pcb_pstk_shape_mech_or_hole_(ps, proto, &sltmp); + goto retry; + } + return NULL; +} + +RND_INLINE rnd_bool_t pcb_isc_pstk_poly(const pcb_find_t *ctx, pcb_pstk_t *ps, pcb_poly_t *poly, rnd_bool anylayer) +{ + pcb_pstk_shape_t *shape; + pcb_pstk_proto_t *proto; + + if (anylayer) + PCB_ISC_PSTK_ANYLAYER(ps, pcb_isc_pstk_poly_shp(ctx, ps, poly, &tshp->shape[n])); + + shape = pcb_pstk_shape_at(PCB, ps, poly->parent.layer); + if (pcb_isc_pstk_poly_shp(ctx, ps, poly, shape)) + return rnd_true; + + proto = pcb_pstk_get_proto(ps); + if (proto->hplated) { + shape = pcb_pstk_shape_mech_at(PCB, ps, poly->parent.layer); + if (pcb_isc_pstk_poly_shp(ctx, ps, poly, shape)) + return rnd_true; + } + + return rnd_false; +} + + +RND_INLINE rnd_bool_t pstk_shape_isc_circ_poly(const pcb_find_t *ctx, pcb_pstk_t *p, pcb_pstk_shape_t *sp, pcb_pstk_t *c, pcb_pstk_shape_t *sc) +{ + rnd_coord_t px = sc->data.circ.x + c->x - p->x; + rnd_coord_t py = sc->data.circ.y + c->y - p->y; + return pcb_isc_line_polyline(ctx, sp->data.poly.pa->contours, px, py, px, py, sc->data.circ.dia); +} + +RND_INLINE rnd_bool_t pstk_shape_isc_circ_line(const pcb_find_t *ctx, pcb_pstk_t *l, pcb_pstk_shape_t *sl, pcb_pstk_t *c, pcb_pstk_shape_t *sc) +{ + pcb_any_line_t tmp; + tmp.Point1.X = sl->data.line.x1 + l->x; + tmp.Point1.Y = sl->data.line.y1 + l->y; + tmp.Point2.X = sl->data.line.x2 + l->x; + tmp.Point2.Y = sl->data.line.y2 + l->y; + tmp.Thickness = sl->data.line.thickness; + tmp.Flags = pcb_no_flags(); + return pcb_is_point_in_line(sc->data.circ.x + c->x, sc->data.circ.y + c->y, sc->data.circ.dia/2, &tmp); +} + +RND_INLINE rnd_bool_t pcb_pstk_shape_intersect_(const pcb_find_t *ctx, pcb_pstk_t *ps1, pcb_pstk_shape_t *shape1, pcb_pstk_t *ps2, pcb_pstk_shape_t *shape2) +{ + if ((shape1->shape == PCB_PSSH_POLY) && (shape1->data.poly.pa == NULL)) + pcb_pstk_shape_update_pa(&shape1->data.poly); + if ((shape2->shape == PCB_PSSH_POLY) && (shape2->data.poly.pa == NULL)) + pcb_pstk_shape_update_pa(&shape2->data.poly); + + switch(shape1->shape) { + case PCB_PSSH_POLY: + switch(shape2->shape) { + case PCB_PSSH_POLY: + { + rnd_bool res; + rnd_polyarea_t *shp1 = pcb_pstk_shp_poly2area(ps1, shape1); + rnd_polyarea_t *shp2 = pcb_pstk_shp_poly2area(ps2, shape2); + res = rnd_polyarea_touching(shp1, shp2); + rnd_polyarea_free(&shp1); + rnd_polyarea_free(&shp2); + return res; + } + case PCB_PSSH_LINE: + return pcb_isc_line_polyline(ctx, shape1->data.poly.pa->contours, shape2->data.line.x1 + ps2->x - ps1->x, shape2->data.line.y1 + ps2->y - ps1->y, shape2->data.line.x2 + ps2->x - ps1->x, shape2->data.line.y2 + ps2->y - ps1->y, shape2->data.line.thickness); + case PCB_PSSH_CIRC: + return pstk_shape_isc_circ_poly(ctx, ps1, shape1, ps2, shape2); + case PCB_PSSH_HSHADOW: + return 0; /* non-object won't intersect */ + } + break; + + case PCB_PSSH_LINE: + switch(shape2->shape) { + case PCB_PSSH_POLY: + return pcb_isc_line_polyline(ctx, shape2->data.poly.pa->contours, shape1->data.line.x1 + ps1->x - ps2->x, shape1->data.line.y1 + ps1->y - ps2->y, shape1->data.line.x2 + ps1->x - ps2->x, shape1->data.line.y2 + ps1->y - ps2->y, shape1->data.line.thickness); + case PCB_PSSH_LINE: + { + pcb_line_t tmp1, tmp2; + shape_line_to_pcb_line(ps1, shape1->data.line, tmp1); + shape_line_to_pcb_line(ps2, shape2->data.line, tmp2); + return pcb_isc_line_line(ctx, &tmp1, &tmp2); + } + case PCB_PSSH_CIRC: + return pstk_shape_isc_circ_line(ctx, ps1, shape1, ps2, shape2); + case PCB_PSSH_HSHADOW: + return 0; /* non-object won't intersect */ + } + break; + + case PCB_PSSH_CIRC: + switch(shape2->shape) { + case PCB_PSSH_POLY: + return pstk_shape_isc_circ_poly(ctx, ps2, shape2, ps1, shape1); + case PCB_PSSH_LINE: + return pstk_shape_isc_circ_line(ctx, ps2, shape2, ps1, shape1); + case PCB_PSSH_CIRC: + { + double cdist2 = rnd_distance2(ps1->x + shape1->data.circ.x, ps1->y + shape1->data.circ.y, ps2->x + shape2->data.circ.x, ps2->y + shape2->data.circ.y); + double dia = ((double)shape1->data.circ.dia + (double)shape2->data.circ.dia)/2.0; + return cdist2 <= dia*dia; + } + case PCB_PSSH_HSHADOW: + return 0; /* non-object won't intersect */ + } + break; + + case PCB_PSSH_HSHADOW: + return 0; /* non-object won't intersect */ + } + return rnd_false; +} + +rnd_bool_t pcb_pstk_shape_intersect(pcb_pstk_t *ps1, pcb_pstk_shape_t *shape1, pcb_pstk_t *ps2, pcb_pstk_shape_t *shape2) +{ + static const pcb_find_t ctx = {0}; + return pcb_pstk_shape_intersect_(&ctx, ps1, shape1, ps2, shape2); +} + + +RND_INLINE rnd_bool_t pcb_isc_pstk_pstk(const pcb_find_t *ctx, pcb_pstk_t *ps1, pcb_pstk_t *ps2, rnd_bool anylayer) +{ + pcb_layer_t *ly; + pcb_pstk_proto_t *proto1, *proto2; + int n; + + if (anylayer) { + int n1, n2; + pcb_pstk_tshape_t *tshp1 = pcb_pstk_get_tshape(ps1), *tshp2 = pcb_pstk_get_tshape(ps2); + for(n1 = 0; n1 < tshp1->len; n1++) { + for(n2 = 0; n2 < tshp2->len; n2++) { + if (pcb_pstk_shape_intersect_(ctx, ps1, &tshp1->shape[n1], ps2, &tshp2->shape[n2])) + return rnd_true; + } + } + return rnd_false; + } + + proto1 = pcb_pstk_get_proto(ps1); + proto2 = pcb_pstk_get_proto(ps2); + + for(n = 0, ly = PCB->Data->Layer; n < PCB->Data->LayerN; n++,ly++) { + pcb_pstk_shape_t *shape1, *slshape1 = NULL, sltmp1; + pcb_pstk_shape_t *shape2, *slshape2 = NULL, sltmp2; + pcb_layer_type_t lyt = pcb_layer_flags_(ly); + + if (!ctx->allow_noncopper_pstk && !(lyt & PCB_LYT_COPPER)) /* consider only copper for connections */ + continue; + + shape1 = pcb_pstk_shape_at(PCB, ps1, ly); + shape2 = pcb_pstk_shape_at(PCB, ps2, ly); + + if ((shape1 != NULL) && (shape2 != NULL) && pcb_pstk_shape_intersect_(ctx, ps1, shape1, ps2, shape2)) return rnd_true; + + if (proto1->hplated) + slshape1 = pcb_pstk_shape_mech_or_hole_at(PCB, ps1, ly, &sltmp1); + if (proto2->hplated) + slshape2 = pcb_pstk_shape_mech_or_hole_at(PCB, ps2, ly, &sltmp2); + + if ((slshape1 != NULL) && (shape2 != NULL) && pcb_pstk_shape_intersect_(ctx, ps1, slshape1, ps2, shape2)) return rnd_true; + if ((slshape2 != NULL) && (shape1 != NULL) && pcb_pstk_shape_intersect_(ctx, ps2, slshape2, ps1, shape1)) return rnd_true; + if ((slshape1 != NULL) && (slshape2 != NULL) && pcb_pstk_shape_intersect_(ctx, ps1, slshape1, ps2, slshape2)) return rnd_true; + } + return rnd_false; +} + + +RND_INLINE rnd_bool_t pcb_isc_pstk_rat(const pcb_find_t *ctx, pcb_pstk_t *ps, pcb_rat_t *rat) +{ + pcb_board_t *pcb = PCB; + + if ((rat->Point1.X == ps->x) && (rat->Point1.Y == ps->y)) { + pcb_layer_t *layer = pcb_get_layer(pcb->Data, pcb->LayerGroups.grp[rat->group1].lid[0]); + if ((layer != NULL) && (pcb_pstk_shape_at(pcb, ps, layer) != NULL)) + return rnd_true; + } + + if ((rat->Point2.X == ps->x) && (rat->Point2.Y == ps->y)) { + pcb_layer_t *layer = pcb_get_layer(pcb->Data, pcb->LayerGroups.grp[rat->group2].lid[0]); + if ((layer != NULL) && (pcb_pstk_shape_at(pcb, ps, layer) != NULL)) + return rnd_true; + } + + return rnd_false; +} Index: tags/2.3.0/src/flag.c =================================================================== --- tags/2.3.0/src/flag.c (nonexistent) +++ tags/2.3.0/src/flag.c (revision 33253) @@ -0,0 +1,117 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2004,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include +#include +#include +#include "config.h" +#include "flag.h" +#include "operation.h" + +/* This just fills in a pcb_flag_t with current flags. */ +pcb_flag_t pcb_flag_make(unsigned int flags) +{ + pcb_flag_t rv; + memset(&rv, 0, sizeof(rv)); + rv.f = flags; + return rv; +} + +pcb_flag_t pcb_flag_add(pcb_flag_t flag, unsigned int flags) +{ + flag.f |= flags; + return flag; +} + +pcb_flag_t pcb_flag_mask(pcb_flag_t flag, unsigned int flags) +{ + flag.f &= ~flags; + return flag; +} + +int rnd_mem_any_set(unsigned char *ptr, int bytes) +{ + while (bytes--) + if (*ptr++) + return 1; + return 0; +} + +void pcb_flag_erase(pcb_flag_t * f) +{ + pcb_unknown_flag_t *u, *next; + for (u = f->unknowns; u != NULL; u = next) { + free(u->str); + next = u->next; + free(u); + } + f->unknowns = NULL; +} + +int pcb_flag_eq(pcb_flag_t *f1, pcb_flag_t *f2) +{ + if (f1->f != f2->f) + return 0; + + if (f1->q != f2->q) + return 0; + + /* WARNING: ignore unknowns for now: the only place where we use this function, + undo.c, won't care */ + + return (memcmp(f1->t, &f2->t, sizeof(f1->t)) == 0); +} + +const char *pcb_dynflag_cookie[RND_DYNFLAG_BLEN]; + +pcb_dynf_t pcb_dynflag_alloc(const char *cookie) +{ + pcb_dynf_t n; + for(n = 0; n < RND_DYNFLAG_BLEN; n++) { + if (pcb_dynflag_cookie[n] == NULL) { + pcb_dynflag_cookie[n] = cookie; + return n; + } + } + return PCB_DYNF_INVALID; +} + +void pcb_dynflag_free(pcb_dynf_t dynf) +{ + if ((dynf >= 0) && (dynf < RND_DYNFLAG_BLEN)) + pcb_dynflag_cookie[dynf] = NULL; +} + + +void pcb_dynflag_uninit(void) +{ + pcb_dynf_t n; + for(n = 0; n < RND_DYNFLAG_BLEN; n++) + if (pcb_dynflag_cookie[n] != NULL) + fprintf(stderr, "pcb-rnd: Internal error: dynamic flag %d (%s) not unregistered\n", n, pcb_dynflag_cookie[n]); +} Index: tags/2.3.0/src/flag.h =================================================================== --- tags/2.3.0/src/flag.h (nonexistent) +++ tags/2.3.0/src/flag.h (revision 33253) @@ -0,0 +1,200 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_FLAG_H +#define PCB_FLAG_H + +#include "globalconst.h" + +/* Nobody should know about the internals of this except the macros in + macros.h that access it. This structure must be simple-assignable + for now. */ +typedef struct pcb_unknown_flag_s pcb_unknown_flag_t; +struct pcb_unknown_flag_s { + char *str; + pcb_unknown_flag_t *next; +}; + +#define PCB_DYNFLAG_WORD unsigned long +#define PCB_DYNFLAG_WLEN ((RND_DYNFLAG_BLEN-1) / sizeof(PCB_DYNFLAG_WORD)+1) +typedef PCB_DYNFLAG_WORD pcb_dynflag_t[PCB_DYNFLAG_WLEN]; + +typedef struct { + unsigned long f; /* generic statically assigned flag bits */ + pcb_dynflag_t df; /* dynamically allocated flag bits */ + unsigned char t[(PCB_MAX_LAYER + 1) / 2]; /* thermals */ + unsigned char q; /* square geometry flag - need to keep only for .pcb compatibility */ + pcb_unknown_flag_t *unknowns; +} pcb_flag_t; + +extern pcb_flag_t no_flags; + +/*** object flags ***/ +typedef enum { + PCB_FLAG_NO = 0x00000, + PCB_FLAG_PIN = 0x00001, /* unused */ + PCB_FLAG_VIA = 0x00002, /* when a rat line has this flag, it's displayed as a circle ("via needs to connect to sorrunding poly") */ + PCB_FLAG_FOUND = 0x00004, /* the "green highlight" find.c does for the user */ + PCB_FLAG_HOLE = 0x00008, /* legacy io_pcb only (broken?) */ + PCB_FLAG_NOPASTE = 0x00008, /* legacy io_pcb only (broken?) */ + PCB_FLAG_RAT = 0x00010, /* rat line objects are marked with this flag */ + PCB_FLAG_PININPOLY = 0x00010, /* unused */ + PCB_FLAG_CLEARPOLY = 0x00010, /* polygon objects that are willing to be cleared */ + PCB_FLAG_HIDENAME = 0x00010, /* legacy io_pcb only */ + PCB_FLAG_DISPLAYNAME = 0x00020, /* unused */ + PCB_FLAG_CLEARLINE = 0x00020, /* non-polygon objects clear polygons */ + PCB_FLAG_FULLPOLY = 0x00020, /* DANGEROUS: keep all islands of a poly */ + PCB_FLAG_SELECTED = 0x00040, /* user selection ("cyan") */ + PCB_FLAG_ONSOLDER = 0x00080, /* mirror text because it is on the solder side */ + PCB_FLAG_AUTO = 0x00080, /* object placed by autorouter */ + PCB_FLAG_SQUARE = 0x00100, /* line cap: square instead of the default round */ + PCB_FLAG_RUBBEREND = 0x00200, /* unused */ + PCB_FLAG_WARN = 0x00200, /* "orange" warning e.g. for shorts */ + PCB_FLAG_USETHERMAL = 0x00400, /* legacy io_pcb only */ + PCB_FLAG_ONSILK = 0x00400, /* Obsolete, old files used this to indicate lines drawn on silk. (Used by io_pcb for compatibility.) */ + PCB_FLAG_OCTAGON = 0x00800, /* legacy io_pcb only */ + PCB_FLAG_DRC = 0x01000, /* temporary, invisible */ + PCB_FLAG_EXPORTSEL = 0x01000, /* temporary, invisible: export selection (limit objects while CAM exporting) */ + PCB_FLAG_LOCK = 0x02000, /* user lock (no move, no edit) */ + PCB_FLAG_EDGE2 = 0x04000, /* unused */ + PCB_FLAG_VISIT = 0x08000, /* marker to avoid re-visiting an object */ + PCB_FLAG_NONETLIST = 0x10000, /* object is not part of the netlist, don't warn for netlist issues */ + PCB_FLAG_MINCUT = 0x20000, /* used by the mincut short find code */ +/* unused = 0x40000, */ + PCB_FLAG_TERMNAME = 0x80000, /* show terminal name of the object */ + PCB_FLAG_DRC_INTCONN = 0x100000,/* Set for objects are put on the DRC mark because of an intconn */ + PCB_FLAG_CLEARPOLYPOLY= 0x200000,/* polygon clearning other polygons */ + PCB_FLAG_DYNTEXT = 0x400000,/* templated text */ + PCB_FLAG_FLOATER = 0x800000 /* object ignores subc lock */ +/* PCB_FLAG_NOCOPY = (PCB_FLAG_FOUND | CONNECTEDFLAG)*/ +} pcb_flag_values_t; + +#define PCB_FLAGS 0x01ffffff /* all used flags */ + +#define PCB_SHOWNUMBERFLAG 0x00000001 +#define PCB_LOCALREFFLAG 0x00000002 +#define PCB_CHECKPLANESFLAG 0x00000004 +#define PCB_SHOWPCB_FLAG_DRC 0x00000008 +#define PCB_RUBBERBANDFLAG 0x00000010 +#define PCB_DESCRIPTIONFLAG 0x00000020 +#define PCB_NAMEONPCBFLAG 0x00000040 +#define PCB_AUTOPCB_FLAG_DRC 0x00000080 +#define PCB_ALLDIRECTIONFLAG 0x00000100 +#define PCB_SWAPSTARTDIRFLAG 0x00000200 +#define PCB_UNIQUENAMEFLAG 0x00000400 +#define PCB_CLEARNEWFLAG 0x00000800 +#define PCB_SNAPPCB_FLAG_PIN 0x00001000 +#define PCB_SHOWMASKFLAG 0x00002000 +#define PCB_THINDRAWFLAG 0x00004000 +#define PCB_ORTHOMOVEFLAG 0x00008000 +#define PCB_LIVEROUTEFLAG 0x00010000 +#define PCB_THINDRAWPOLYFLAG 0x00020000 +#define PCB_LOCKNAMESFLAG 0x00040000 +#define PCB_ONLYNAMESFLAG 0x00080000 +#define PCB_NEWPCB_FLAG_FULLPOLY 0x00100000 +#define PCB_HIDENAMESFLAG 0x00200000 +#define PCB_ENABLEPCB_FLAG_MINCUT 0x00400000 + + + +/* Convert flags to flags, set everything else to 0 */ +pcb_flag_t pcb_flag_make(unsigned int src); + +/* set bits of src in dst */ +pcb_flag_t pcb_flag_add(pcb_flag_t dst, unsigned int src); + +/* clear (unset) bits of src in dst */ +pcb_flag_t pcb_flag_mask(pcb_flag_t dst, unsigned int src); + +/* destroy flags: clear all bits and free fields */ +void pcb_flag_erase(pcb_flag_t *f); + +#define pcb_no_flags() pcb_flag_make(0) + +/* --------------------------------------------------------------------------- + * some routines for flag setting, clearing, changing and testing + */ +#define PCB_FLAG_SET(F,P) ((P)->Flags.f |= (F)) +#define PCB_FLAG_CLEAR(F,P) ((P)->Flags.f &= (~(F))) +#define PCB_FLAG_TEST(F,P) ((P)->Flags.f & (F) ? 1 : 0) +#define PCB_FLAG_TOGGLE(F,P) ((P)->Flags.f ^= (F)) +#define PCB_FLAG_ASSIGN(F,V,P) ((P)->Flags.f = ((P)->Flags.f & (~(F))) | ((V) ? (F) : 0)) +#define PCB_FLAGS_TEST(F,P) (((P)->Flags.f & (F)) == (F) ? 1 : 0) + +typedef enum { + PCB_CHGFLG_CLEAR, + PCB_CHGFLG_SET, + PCB_CHGFLG_TOGGLE +} pcb_change_flag_t; + +#define PCB_FLAG_CHANGE(how, F, P) \ +do { \ + switch(how) { \ + case PCB_CHGFLG_CLEAR: PCB_FLAG_CLEAR(F, P); break; \ + case PCB_CHGFLG_SET: PCB_FLAG_SET(F, P); break; \ + case PCB_CHGFLG_TOGGLE: PCB_FLAG_TOGGLE(F, P); break; \ + } \ +} while(0) + +/* Ignores dynamic flags and thermals */ +int pcb_flag_eq(pcb_flag_t *f1, pcb_flag_t *f2); +#define PCB_FLAG_EQ(F1,F2) pcb_flag_eq(&(F1), &(F2)) + +#define PCB_FLAG_THERM(L) (0xf << (4 *((L) % 2))) + +#define PCB_FLAG_THERM_TEST(L,P) ((P)->Flags.t[(L)/2] & PCB_FLAG_THERM(L) ? 1 : 0) +#define PCB_FLAG_THERM_GET(L,P) (((P)->Flags.t[(L)/2] >> (4 * ((L) % 2))) & 0xf) +#define PCB_FLAG_THERM_CLEAR(L,P) (P)->Flags.t[(L)/2] &= ~PCB_FLAG_THERM(L) +#define PCB_FLAG_THERM_ASSIGN(L,V,P) (P)->Flags.t[(L)/2] = ((P)->Flags.t[(L)/2] & ~PCB_FLAG_THERM(L)) | ((V) << (4 * ((L) % 2))) +#define PCB_FLAG_THERM_ASSIGN_(L,V,F) (F).t[(L)/2] = (((F).t[(L)/2] & ~PCB_FLAG_THERM(L)) | ((V) << (4 * ((L) % 2)))) + + +#define PCB_FLAG_SQUARE_GET(P) ((P)->Flags.q) +#define PCB_FLAG_SQUARE_CLEAR(P) (P)->Flags.q = 0 +#define PCB_FLAG_SQUARE_ASSIGN(V,P) (P)->Flags.q = V + +/* Returns 1 if any of the bytes in arr is non-zero */ +int rnd_mem_any_set(unsigned char *arr, int arr_len); +#define PCB_FLAG_THERM_TEST_ANY(P) rnd_mem_any_set((P)->Flags.t, sizeof((P)->Flags.t)) + +/*** Dynamic flags ***/ +#define PCB_DFLAG_SET(flg, dynf) (flg)->df[(dynf) / sizeof(PCB_DYNFLAG_WORD)] |= (1 << (dynf) % sizeof(PCB_DYNFLAG_WORD)) +#define PCB_DFLAG_CLR(flg, dynf) (flg)->df[(dynf) / sizeof(PCB_DYNFLAG_WORD)] &= ~(1 << (dynf) % sizeof(PCB_DYNFLAG_WORD)) +#define PCB_DFLAG_TEST(flg, dynf) (!!((flg)->df[(dynf) / sizeof(PCB_DYNFLAG_WORD)] & (1 << (dynf) % sizeof(PCB_DYNFLAG_WORD)))) +#define PCB_DFLAG_PUT(flg, dynf, val) ((val) ? PCB_DFLAG_SET((flg), (dynf)) : PCB_DFLAG_CLR((flg), (dynf))) + +extern const char *pcb_dynflag_cookie[RND_DYNFLAG_BLEN]; + +typedef int pcb_dynf_t; +#define PCB_DYNF_INVALID (-1) +pcb_dynf_t pcb_dynflag_alloc(const char *cookie); +void pcb_dynflag_free(pcb_dynf_t dynf); + +void pcb_dynflag_uninit(void); + +#endif Index: tags/2.3.0/src/flag_str.c =================================================================== --- tags/2.3.0/src/flag_str.c (nonexistent) +++ tags/2.3.0/src/flag_str.c (revision 33253) @@ -0,0 +1,616 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2005 DJ Delorie + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA + * dj@delorie.com + * + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "flag_str.h" +#include +#include +#include "obj_common.h" + +/* Because the common flag access macros expect an object struct to work on. */ +typedef struct { + pcb_flag_t Flags; +} FlagHolder; + +/* Be careful to list more specific flags first, followed by general + flags, when two flags use the same bit. For example, "onsolder" is + for elements only, while "auto" is for everything else. They use + the same bit, but onsolder is listed first so that elements will + use it and not auto. + + Thermals are handled separately, as they're layer-selective. */ + +#define N(x) x, sizeof(x)-1 +#define FN(x) x, #x +pcb_flag_bits_t pcb_object_flagbits[] = { + {FN(PCB_FLAG_PIN), N("pin"), PCB_OBJ_ANY, "If set, this object is a pin. This flag is for internal use only.", 0, 1}, + {FN(PCB_FLAG_VIA), N("via"), PCB_OBJ_ANY, "If set, this object is a via. This flag is for internal use only.", 0, 1}, + {FN(PCB_FLAG_FOUND), N("found"), PCB_OBJ_ANY, "If set, this object has been found by FindConnection()", 0, 0}, + {FN(PCB_FLAG_HOLE), N("hole"), PCB_OBJ_CLASS_PIN, "For pins and vias, this flag means that the pin or via is a hole without a copper annulus.", 0, 0}, + {FN(PCB_FLAG_RAT), N("rat"), PCB_OBJ_RAT, "If set for a line, indicates that this line is a rat line instead of a copper trace.", 0, 0}, + {FN(PCB_FLAG_PININPOLY), N("pininpoly"), 0, "For pins and pads, this flag is used internally to indicate that the pin or pad overlaps a polygon on some layer.", 0, 0}, + {FN(PCB_FLAG_CLEARPOLY), N("clearpoly"), PCB_OBJ_POLY, "For polygons, this flag means that pins and vias will normally clear these polygons (thus, thermals are required for electrical connection). When clear, polygons will solidly connect to pins and vias. ", 0, 0}, + {FN(PCB_FLAG_HIDENAME), N("hidename"), 0, "For elements, when set the name of the element is hidden.", PCB_OBJ_SUBC, 0}, + {FN(PCB_FLAG_DISPLAYNAME), N("showname"), 0, "OBSOLETE: For elements, when set the names of pins are shown.", 0, 0}, + {FN(PCB_FLAG_CLEARLINE), N("clearline"), PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_TEXT | PCB_OBJ_PSTK, "For lines and arcs, the line/arc will clear polygons instead of connecting to them.", 0, 0 }, + {FN(PCB_FLAG_SELECTED), N("selected"), PCB_OBJ_ANY, "Set when the object is selected.", 0, 0}, + {FN(PCB_FLAG_ONSOLDER), N("onsolder"), PCB_OBJ_TEXT, "For text, indicates that it is on the solder side.", PCB_OBJ_SUBC | PCB_OBJ_PSTK, 0}, + {FN(PCB_FLAG_AUTO), N("auto"), PCB_OBJ_LINE|PCB_OBJ_ARC|PCB_OBJ_PSTK, "For lines and vias, indicates that these were created by the autorouter.", 0, 0}, + {FN(PCB_FLAG_SQUARE), N("square"), 0, "For pins and pads, indicates a square (vs round) pin/pad.", PCB_OBJ_PSTK, 0}, + {FN(PCB_FLAG_RUBBEREND), N("rubberend"), PCB_OBJ_LINE | PCB_OBJ_ARC, "For lines, used internally for rubber band moves: indicates one end already rubber banding.", 0, 0}, + {FN(PCB_FLAG_WARN), N("warn"), PCB_OBJ_CLASS_PIN, "For pins, vias, and pads, set to indicate a warning.", 0, 0}, + {FN(PCB_FLAG_USETHERMAL), N("usetherm"), PCB_OBJ_CLASS_PIN | PCB_OBJ_LINE | PCB_OBJ_ARC, "Obsolete, indicates that pins/vias should be drawn with thermal fingers.", 0, 1}, + {FN(PCB_FLAG_OCTAGON), N("octagon"), 0, "Draw pins and vias as octagons.", PCB_OBJ_PSTK, 0}, + {FN(PCB_FLAG_DRC), N("drc"), PCB_OBJ_ANY, "Set for objects that fail DRC: flag like FOUND flag for DRC checking.", 0}, + {FN(PCB_FLAG_EXPORTSEL), N("exportsel"), PCB_OBJ_ANY, "Set for objects that should be exported in a partial export.", 1}, + {FN(PCB_FLAG_LOCK), N("lock"), PCB_OBJ_ANY, "Set for locked objects.", 0, 0}, + {FN(PCB_FLAG_EDGE2), N("edge2"), PCB_OBJ_ANY, "For pads, indicates that the second point is closer to the edge. For pins, indicates that the pin is closer to a horizontal edge and thus pinout text should be vertical. (Padr.Point2 is closer to outside edge also pinout text for pins is vertical)", 0, 1}, + {FN(PCB_FLAG_FULLPOLY), N("fullpoly"), PCB_OBJ_POLY, "For polygons, the full polygon is drawn (i.e. all parts instead of only the biggest one).", 0, 0}, + {FN(PCB_FLAG_NOPASTE), N("nopaste"), 0, "Pad should not receive solderpaste. This is to support fiducials", 0, 0}, + {FN(PCB_FLAG_NONETLIST), N("nonetlist"), PCB_OBJ_SUBC, "subcircuit is not on the netlist and should not interfere with the netlist ", 0, 0}, + {FN(PCB_FLAG_TERMNAME), N("termname"), PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_TEXT | PCB_OBJ_PSTK | PCB_OBJ_SUBC, "when set the names of pins are shown.", 0, 0}, + {FN(PCB_FLAG_CLEARPOLYPOLY), N("clearpolypoly"), PCB_OBJ_POLY, "For polygons, apply clearance to nearby polygons", 0, 0}, + {FN(PCB_FLAG_DYNTEXT), N("dyntext"), PCB_OBJ_TEXT, "For text: dynamic string (substitute %patterns%)", 0, 0}, + {FN(PCB_FLAG_FLOATER), N("floater"), PCB_OBJ_ANY, "subc part can be moved after subc placing", 0, 0} +}; +#undef N +#undef FN + +const int pcb_object_flagbits_len = RND_ENTRIES(pcb_object_flagbits); + +/* List of old/obsolete flags to silently ignore on load */ +static const char *old_flag_ignore[] = { "connected", NULL }; + +/* This helper function maintains a small list of buffers which are + used by pcb_strflg_f2s(). Each buffer is allocated from the heap, + but the caller must not free them (they get realloced when they're + reused, but never completely freed). */ + +static struct { + char *ptr; + int len; +} buffers[10]; +static int bufptr = 0; +static char *alloc_buf(int len) +{ +#define B buffers[bufptr] + len++; + bufptr = (bufptr + 1) % 10; + if (B.len < len) { + if (B.ptr) + B.ptr = (char *) realloc(B.ptr, len); + else + B.ptr = (char *) malloc(len); + B.len = len; + } + return B.ptr; +#undef B +} + +void pcb_strflg_uninit_buf(void) +{ + int n; + for(n = 0; n < 10; n++) { + if (buffers[n].ptr != NULL) { + free(buffers[n].ptr); + buffers[n].ptr = NULL; + } + } +} + +/* This set of routines manages a list of layer-specific flags. + Callers should call grow_layer_list(0) to reset the list, and + set_layer_list(layer,1) to set bits in the layer list. The results + are stored in layers[], which has num_layers valid entries. */ + +static char *layers = 0; +static int max_layers = 0, num_layers = 0; + +static void grow_layer_list(int num) +{ + if (layers == 0) { + layers = (char *) calloc(num > 0 ? num : 1, 1); + max_layers = num; + } + else if (num > max_layers) { + max_layers = num; + layers = (char *) realloc(layers, max_layers); + } + if (num > num_layers) + memset(layers + num_layers, 0, num - num_layers - 1); + num_layers = num; + return; +} + +void pcb_strflg_uninit_layerlist(void) +{ + if (layers != NULL) { + free(layers); + layers = NULL; + num_layers = max_layers = 0; + } +} + +static inline void set_layer_list(int layer, int v) +{ + if (layer >= num_layers) + grow_layer_list(layer + 1); + layers[layer] = v; +} + +/* These next two convert between layer lists and strings. + parse_layer_list() is passed a pointer to a string, and parses a + list of integer which reflect layers to be flagged. It returns a + pointer to the first character following the list. The syntax of + the list is a paren-surrounded, comma-separated list of integers + and/or pairs of integers separated by a dash (like "(1,2,3-7)"). + Spaces and other punctuation are not allowed. The results are + stored in layers[] defined above. + + print_layer_list() does the opposite - it uses the flags set in + layers[] to build a string that represents them, using the syntax + above. */ + +/* Returns a pointer to the first character past the list. */ +static const char *parse_layer_list(const char *bp, int (*error) (const char *)) +{ + const char *orig_bp = bp; + int l = 0, range = -1; + int value = 1; + + grow_layer_list(0); + while (*bp) { + if (*bp == '+') + value = 2; + else if (*bp == 'S') + value = 3; + else if (*bp == 'X') + value = 4; + else if (*bp == 't') + value = 5; + else if (*bp == ')' || *bp == ',' || *bp == '-') { + if (range == -1) + range = l; + while (range <= l) + set_layer_list(range++, value); + if (*bp == '-') + range = l; + else + range = -1; + value = 1; + l = 0; + } + + else if (isdigit((int) *bp)) + l = l * 10 + (*bp - '0'); + + else if (error) { + const char *fmt = "Syntax error parsing layer list \"%.*s\" at %c"; + char *msg = alloc_buf(strlen(fmt) + strlen(orig_bp)); + sprintf(msg, fmt, bp - orig_bp + 5, orig_bp, *bp); + error(msg); + error = NULL; + } + + if (*bp == ')') + return bp + 1; + + bp++; + } + return bp; +} + +/* Number of character the value "i" requires when printed. */ +static int printed_int_length(int i, int j) +{ + int rv; + + if (i < 10) + return 1 + (j ? 1 : 0); + if (i < 100) + return 2 + (j ? 1 : 0); + + for (rv = 1; i >= 10; rv++) + i /= 10; + return rv + (j ? 1 : 0); +} + +/* Returns a pointer to an internal buffer which is overwritten with + each new call. */ +static char *print_layer_list() +{ + static char *buf = 0; + static int buflen = 0; + int len, i, j; + char *bp; + + len = 2; + for (i = 0; i < num_layers; i++) + if (layers[i]) + len += 1 + printed_int_length(i, layers[i]); + if (buflen < len) { + if (buf) + buf = (char *) realloc(buf, len); + else + buf = (char *) malloc(len); + buflen = len; + } + + bp = buf; + *bp++ = '('; + + for (i = 0; i < num_layers; i++) + if (layers[i]) { + /* 0 0 1 1 1 0 0 */ + /* i j */ + for (j = i + 1; j < num_layers && layers[j] == 1; j++); + if (j > i + 2) { + sprintf(bp, "%d-%d,", i, j - 1); + i = j - 1; + } + else + switch (layers[i]) { + case 1: + sprintf(bp, "%d,", i); + break; + case 2: + sprintf(bp, "%d+,", i); + break; + case 3: + sprintf(bp, "%dS,", i); + break; + case 4: + sprintf(bp, "%dX,", i); + break; + case 5: + default: + sprintf(bp, "%dt,", i); + break; + } + bp += strlen(bp); + } + bp[-1] = ')'; + *bp = 0; + return buf; +} + +static int error_ignore(const char *msg) +{ + return 0; +} + +static pcb_flag_t empty_flags; + +pcb_flag_t pcb_strflg_common_s2f(const char *flagstring, int (*error) (const char *msg), pcb_flag_bits_t *flagbits, int n_flagbits, unsigned char *intconn, int compat) +{ + const char *fp, *ep; + int flen; + FlagHolder rv; + int i; + + if (intconn != NULL) + *intconn = 0; + rv.Flags = empty_flags; + + if (error == 0) + error = error_ignore; + + if (flagstring == NULL) + return empty_flags; + + fp = ep = flagstring; + + if (*fp == '"') + ep = ++fp; + + while (*ep && *ep != '"') { + int found = 0; + + while (*fp == ',') + fp++; + + for (ep = fp; *ep && *ep != ',' && *ep != '"' && *ep != '('; ep++); + flen = ep - fp; + if (*ep == '(') + ep = parse_layer_list(ep + 1, error); + + if (flen == 7 && memcmp(fp, "thermal", 7) == 0) { + for (i = 0; i < PCB_MAX_LAYER && i < num_layers; i++) + if (layers[i]) + PCB_FLAG_THERM_ASSIGN(i, layers[i], &rv); + } + else if (flen == 5 && memcmp(fp, "shape", 5) == 0) { + rv.Flags.q = atoi(fp + 6); + } + else if (intconn != NULL && flen == 7 && memcmp(fp, "intconn", 7) == 0) { + *intconn = atoi(fp + 8); + } + else { + for (i = 0; i < n_flagbits; i++) + if (flagbits[i].nlen == flen && memcmp(flagbits[i].name, fp, flen) == 0) { + found = 1; + PCB_FLAG_SET(flagbits[i].mask, &rv); + break; + } + if (!found) { + const char **ign; + for(ign = old_flag_ignore; *ign != NULL; ign++) { + if (memcmp(*ign, fp, flen) == 0) { + found = 1; + break; + } + } + } + if (!found) { + const char *fmt = "Unknown flag: \"%.*s\" ignored"; + pcb_unknown_flag_t *u; + char *msg; + const char *s; + + /* include () */ + s = fp + flen; + if (*s == '(') { + while (*s != ')') { + flen++; + s++; + } + } + if (*s == ')') + flen++; + + msg = alloc_buf(strlen(fmt) + flen); + sprintf(msg, fmt, flen, fp); + error(msg); + + u = malloc(sizeof(pcb_unknown_flag_t)); + u->str = rnd_strndup(fp, flen); + u->next = NULL; + /* need to append, to keep order of flags */ + if (rv.Flags.unknowns != NULL) { + pcb_unknown_flag_t *n; + for (n = rv.Flags.unknowns; n->next != NULL; n = n->next); + n->next = u; + } + else + rv.Flags.unknowns = u; + } + } + fp = ep + 1; + } + return rv.Flags; +} + +pcb_flag_t pcb_strflg_s2f(const char *flagstring, int (*error) (const char *msg), unsigned char *intconn, int compat) +{ + return pcb_strflg_common_s2f(flagstring, error, pcb_object_flagbits, RND_ENTRIES(pcb_object_flagbits), intconn, compat); +} + +char *pcb_strflg_common_f2s(pcb_flag_t flags, int object_type, pcb_flag_bits_t *flagbits, int n_flagbits, unsigned char *intconn, int compat) +{ + int len; + int i; + FlagHolder fh, savef; + char *buf, *bp; + pcb_unknown_flag_t *u; + + fh.Flags = flags; + +#ifndef FLAG_TEST + switch (object_type) { + case PCB_OBJ_RAT: + PCB_FLAG_CLEAR(PCB_FLAG_RAT, &fh); + break; + } +#endif + + savef = fh; + + len = 3; /* for "()\0" */ + + for (i = 0; i < n_flagbits; i++) { + long my_obj_typs = flagbits[i].object_types | (compat ? flagbits[i].compat_types : 0); + if ((my_obj_typs & object_type) && (PCB_FLAG_TEST(flagbits[i].mask, &fh))) { + len += flagbits[i].nlen + 1; + PCB_FLAG_CLEAR(flagbits[i].mask, &fh); + } + } + + if (PCB_FLAG_THERM_TEST_ANY(&fh)) { + len += sizeof("thermal()"); + for (i = 0; i < PCB_MAX_LAYER; i++) + if (PCB_FLAG_THERM_TEST(i, &fh)) + len += printed_int_length(i, PCB_FLAG_THERM_GET(i, &fh)) + 1; + } + + if (flags.q > 0) { + len += sizeof("shape(.)"); + if (flags.q > 9) + len += 2; + } + + if ((intconn != NULL) && (*intconn > 0)) { + len += sizeof("intconn(.)"); + if (*intconn > 9) + len++; + if (*intconn > 99) + len++; + } + + for (u = flags.unknowns; u != NULL; u = u->next) + len += strlen(u->str) + 1; + + bp = buf = alloc_buf(len + 2); + + *bp++ = '"'; + + fh = savef; + for (i = 0; i < n_flagbits; i++) { + long my_obj_typs = flagbits[i].object_types | (compat ? flagbits[i].compat_types : 0); + if ((my_obj_typs & object_type) && (PCB_FLAG_TEST(flagbits[i].mask, &fh))) { + if (bp != buf + 1) + *bp++ = ','; + strcpy(bp, flagbits[i].name); + bp += flagbits[i].nlen; + PCB_FLAG_CLEAR(flagbits[i].mask, &fh); + } + } + + if (PCB_FLAG_THERM_TEST_ANY(&fh)) { + if (bp != buf + 1) + *bp++ = ','; + strcpy(bp, "thermal"); + bp += strlen("thermal"); + grow_layer_list(0); + for (i = 0; i < PCB_MAX_LAYER; i++) + if (PCB_FLAG_THERM_TEST(i, &fh)) + set_layer_list(i, PCB_FLAG_THERM_GET(i, &fh)); + strcpy(bp, print_layer_list()); + bp += strlen(bp); + } + + if (flags.q > 0) { + if (bp != buf + 1) + *bp++ = ','; + bp += sprintf(bp, "shape(%d)", flags.q); + } + + if ((intconn != NULL) && (*intconn > 0)) { + if (bp != buf + 1) + *bp++ = ','; + bp += sprintf(bp, "intconn(%d)", *intconn); + } + + for (u = flags.unknowns; u != NULL; u = u->next) { + int len; + len = strlen(u->str); + if (bp != buf + 1) + *bp++ = ','; + memcpy(bp, u->str, len); + bp += len; + } + + *bp++ = '"'; + *bp = 0; + return buf; +} + +char *pcb_strflg_f2s(pcb_flag_t flags, int object_type, unsigned char *intconn, int compat) +{ + return pcb_strflg_common_f2s(flags, object_type, pcb_object_flagbits, RND_ENTRIES(pcb_object_flagbits), intconn, compat); +} + +const pcb_flag_bits_t *pcb_strflg_1bit(unsigned long bit, int object_type) +{ + int i, n_flagbits = RND_ENTRIES(pcb_object_flagbits);; + for (i = 0; i < n_flagbits; i++) { + unsigned long my_obj_typs = pcb_object_flagbits[i].object_types; + if ((my_obj_typs & object_type) && (!pcb_object_flagbits[i].omit_list) && (pcb_object_flagbits[i].mask & bit)) + return &pcb_object_flagbits[i]; + } + return NULL; +} + +const pcb_flag_bits_t *pcb_strflg_name(const char *name, int object_type) +{ + int i, n_flagbits = RND_ENTRIES(pcb_object_flagbits);; + for (i = 0; i < n_flagbits; i++) { + unsigned long my_obj_typs = pcb_object_flagbits[i].object_types; + if ((my_obj_typs & object_type) && (!pcb_object_flagbits[i].omit_list) && (strcmp(pcb_object_flagbits[i].name, name) == 0)) + return &pcb_object_flagbits[i]; + } + return NULL; +} + +void pcb_strflg_map(unsigned long fbits, int object_type, void *ctx, void (*cb)(void *ctx, unsigned long flg, const pcb_flag_bits_t *fb)) +{ + int n, i, n_flagbits = RND_ENTRIES(pcb_object_flagbits); + for(n = 0; n < 32; n++) { + unsigned long bit = 1 << n; + if (!(fbits & bit)) + continue; + + for (i = 0; i < n_flagbits; i++) { + unsigned long my_obj_typs = pcb_object_flagbits[i].object_types /*| pcb_object_flagbits[i].compat_types*/; + if ((my_obj_typs & object_type) && (!pcb_object_flagbits[i].omit_list) && (pcb_object_flagbits[i].mask & bit)) { + cb(ctx, bit, &pcb_object_flagbits[i]); + } + } + } +} + + +#define N(x) x, sizeof(x)-1 +#define FN(x) x, #x +static pcb_flag_bits_t pcb_flagbits[] = { + {FN(PCB_SHOWNUMBERFLAG), N("shownumber"), 1, "Pinout displays pin numbers instead of pin names." }, + {FN(PCB_LOCALREFFLAG), N("localref"), 1, "Use local reference for moves, by setting the mark at the beginning of each move." }, + {FN(PCB_CHECKPLANESFLAG), N("checkplanes"), 1, "When set, only polygons and their clearances are drawn, to see if polygons have isolated regions." }, + {FN(PCB_SHOWPCB_FLAG_DRC), N("showdrc"), 1, "Display DRC region on crosshair." }, + {FN(PCB_RUBBERBANDFLAG), N("rubberband"), 1, "Do all move, mirror, rotate with rubberband connections." }, + {FN(PCB_DESCRIPTIONFLAG), N("description"), 1, "Display descriptions of elements, instead of refdes." }, + {FN(PCB_NAMEONPCBFLAG), N("nameonpcb"), 1, "Display names of elements, instead of refdes." }, + {FN(PCB_AUTOPCB_FLAG_DRC), N("autodrc"), 1, "Auto-DRC flag. When set, PCB doesn't let you place copper that violates DRC." }, + {FN(PCB_ALLDIRECTIONFLAG), N("alldirection"), 1, "Enable 'all-direction' lines." }, + {FN(PCB_SWAPSTARTDIRFLAG), N("swapstartdir"), 1, "Switch starting angle after each click." }, + {FN(PCB_UNIQUENAMEFLAG), N("uniquename"), 1, "Force unique names on board." }, + {FN(PCB_CLEARNEWFLAG), N("clearnew"), 1, "New lines/arc clear polygons." }, + {FN(PCB_SNAPPCB_FLAG_PIN), N("snappin"), 1, "pcb_crosshair snaps to pins and pads." }, + {FN(PCB_SHOWMASKFLAG), N("showmask"), 1, "Show the solder mask layer." }, + {FN(PCB_THINDRAWFLAG), N("thindraw"), 1, "Draw with thin lines." }, + {FN(PCB_ORTHOMOVEFLAG), N("orthomove"), 1, "Move items orthogonally." }, + {FN(PCB_LIVEROUTEFLAG), N("liveroute"), 1, "Draw autoroute paths real-time." }, + {FN(PCB_NEWPCB_FLAG_FULLPOLY), N("newfullpoly"), 1, "New polygons are full ones." }, + {FN(PCB_THINDRAWPOLYFLAG), N("thindrawpoly"), 1, "Thin draw polygon contours instead of filling polygons." }, + {FN(PCB_LOCKNAMESFLAG), N("locknames"), 1, "Names are locked, the mouse cannot select them." }, + {FN(PCB_ONLYNAMESFLAG), N("onlynames"), 1, "Everything but names are locked, the mouse cannot select anything else." }, + {FN(PCB_HIDENAMESFLAG), N("hidenames"), 1, "When set, element names are not drawn." }, + {FN(PCB_ENABLEPCB_FLAG_MINCUT), N("enablemincut"), 1, "Use the mincut algorithm for finding shorts." }, +}; +#undef N +#undef FN + +char *pcb_strflg_board_f2s(pcb_flag_t flags) +{ + return pcb_strflg_common_f2s(flags, PCB_OBJ_ANY, pcb_flagbits, RND_ENTRIES(pcb_flagbits), NULL, 0); +} + +pcb_flag_t pcb_strflg_board_s2f(const char *flagstring, int (*error)(const char *msg)) +{ + return pcb_strflg_common_s2f(flagstring, error, pcb_flagbits, RND_ENTRIES(pcb_flagbits), NULL, 0); +} Index: tags/2.3.0/src/flag_str.h =================================================================== --- tags/2.3.0/src/flag_str.h (nonexistent) +++ tags/2.3.0/src/flag_str.h (revision 33253) @@ -0,0 +1,104 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2005 DJ Delorie + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA + * dj@delorie.com + * + */ + +#ifndef PCB_STRFLAGS_H +#define PCB_STRFLAGS_H + +#include "flag.h" + +typedef struct { + + /* This is the bit that we're setting. */ + pcb_flag_values_t mask; + const char *mask_name; + + /* The name used in the output file. */ + const char *name; + int nlen; + + /* The entry won't be output unless the object type is one of these. */ + int object_types; + + char *help; + + /* in compatibility mode also accept these object types to have the flag */ + int compat_types; + + /* when non-zero, omit from all-flag listings */ + int omit_list; +} pcb_flag_bits_t; + +/* All flags natively known by the core */ +extern pcb_flag_bits_t pcb_object_flagbits[]; +extern const int pcb_object_flagbits_len; + +/* The purpose of this interface is to make the file format able to + handle more than 32 flags, and to hide the internal details of + flags from the file format. In compat mode, compat_types are + also considered (so an old PCB PAD (padstack now) can have + a square flag). */ + +/* When passed a string, parse it and return an appropriate set of + flags. Errors cause error() to be called with a suitable message; + if error is NULL, errors are ignored. */ +pcb_flag_t pcb_strflg_s2f(const char *flagstring, int (*error) (const char *msg), unsigned char *intconn, int compat); + +/* Given a set of flags for a given object type, return a string which + can be output to a file. The returned pointer must not be + freed. If compat is set, allow some old flags set on new object types + which normally won't handle them - this is only for io_pcb, for the + transitional period */ +char *pcb_strflg_f2s(pcb_flag_t flags, int object_type, unsigned char *intconn, int compat); + + +/* Call cb for each flag bit for a given object type */ +void pcb_strflg_map(unsigned long fbits, int object_type, void *ctx, void (*cb)(void *ctx, unsigned long flg, const pcb_flag_bits_t *fb)); + +/* Return flag bit info for a single bit for an object type, or NULL is not available - slow linear search */ +const pcb_flag_bits_t *pcb_strflg_1bit(unsigned long bit, int object_type); + +/* Return flag bit info by flag name for an object type, or NULL is not available - slow linear search */ +const pcb_flag_bits_t *pcb_strflg_name(const char *name, int object_type); + +/* same as above, for pcb level flags */ +char *pcb_strflg_board_f2s(pcb_flag_t flags); +pcb_flag_t pcb_strflg_board_s2f(const char *flagstring, int (*error) (const char *msg)); + +void pcb_strflg_uninit_buf(void); +void pcb_strflg_uninit_layerlist(void); + +/* low level */ +pcb_flag_t pcb_strflg_common_s2f(const char *flagstring, int (*error) (const char *msg), pcb_flag_bits_t * flagbits, int n_flagbits, unsigned char *intconn, int compat); +char *pcb_strflg_common_f2s(pcb_flag_t flags, int object_type, pcb_flag_bits_t * flagbits, int n_flagbits, unsigned char *intconn, int compat); + +#endif Index: tags/2.3.0/src/font.c =================================================================== --- tags/2.3.0/src/font.c (nonexistent) +++ tags/2.3.0/src/font.c (revision 33253) @@ -0,0 +1,489 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2005 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* font support. Note: glyphs are called symbols here */ + +#include "config.h" + +#include +#include + +#include "font.h" +#include "board.h" +#include "conf_core.h" +#include +#include "plug_io.h" +#include +#include +#include "event.h" +#include + +#define STEP_SYMBOLLINE 10 + +typedef struct embf_line_s { + int x1, y1, x2, y2, th; +} embf_line_t; + +typedef struct embf_font_s { + int delta; + embf_line_t *lines; + int num_lines; +} embf_font_t; + +#include "font_internal.c" + +static void pcb_font_load_internal(pcb_font_t *font) +{ + int n, l; + memset(font, 0, sizeof(pcb_font_t)); + font->MaxWidth = embf_maxx - embf_minx; + font->MaxHeight = embf_maxy - embf_miny; + for(n = 0; n < sizeof(embf_font) / sizeof(embf_font[0]); n++) { + if (embf_font[n].delta != 0) { + pcb_symbol_t *s = font->Symbol + n; + embf_line_t *lines = embf_font[n].lines; + + for(l = 0; l < embf_font[n].num_lines; l++) { + rnd_coord_t x1 = RND_MIL_TO_COORD(lines[l].x1); + rnd_coord_t y1 = RND_MIL_TO_COORD(lines[l].y1); + rnd_coord_t x2 = RND_MIL_TO_COORD(lines[l].x2); + rnd_coord_t y2 = RND_MIL_TO_COORD(lines[l].y2); + rnd_coord_t th = RND_MIL_TO_COORD(lines[l].th); + pcb_font_new_line_in_sym(s, x1, y1, x2, y2, th); + } + + s->Valid = 1; + s->Delta = RND_MIL_TO_COORD(embf_font[n].delta); + } + } + pcb_font_set_info(font); +} + +static int pcb_parse_font_default(pcb_font_t *ptr, const char *filename) +{ + int res = pcb_parse_font(ptr, filename); + if (res == 0) + rnd_file_loaded_set_at("font", "default", filename, "original default font"); + return res; +} + +/* parses a file with font information and installs it into the provided PCB + checks directories given as colon separated list by resource fontPath + if the fonts filename doesn't contain a directory component */ +void pcb_font_create_default(pcb_board_t *pcb) +{ + int res = -1; + pcb_io_err_inhibit_inc(); + rnd_conf_list_foreach_path_first(&pcb->hidlib, res, &conf_core.rc.default_font_file, pcb_parse_font_default(&pcb->fontkit.dflt, __path__)); + pcb_io_err_inhibit_dec(); + + if (res != 0) { + const char *s; + gds_t buff; + s = rnd_conf_concat_strlist(&conf_core.rc.default_font_file, &buff, NULL, ':'); + rnd_message(RND_MSG_WARNING, "Can't find font-symbol-file. Searched: '%s'; falling back to the embedded default font\n", s); + pcb_font_load_internal(&pcb->fontkit.dflt); + rnd_file_loaded_set_at("font", "default", "", "original default font"); + gds_uninit(&buff); + } +} + +/* transforms symbol coordinates so that the left edge of each symbol + is at the zero position. The y coordinates are moved so that min(y) = 0 */ +void pcb_font_set_info(pcb_font_t *Ptr) +{ + rnd_cardinal_t i, j; + pcb_symbol_t *symbol; + pcb_line_t *line; + pcb_arc_t *arc; + pcb_poly_t *poly; + rnd_coord_t totalminy = RND_MAX_COORD; + + /* calculate cell with and height (is at least PCB_DEFAULT_CELLSIZE) + maximum cell width and height + minimum x and y position of all lines */ + Ptr->MaxWidth = PCB_DEFAULT_CELLSIZE; + Ptr->MaxHeight = PCB_DEFAULT_CELLSIZE; + for (i = 0, symbol = Ptr->Symbol; i <= PCB_MAX_FONTPOSITION; i++, symbol++) { + rnd_coord_t minx, miny, maxx, maxy; + + /* next one if the index isn't used or symbol is empty (SPACE) */ + if (!symbol->Valid || !symbol->LineN) + continue; + + minx = miny = RND_MAX_COORD; + maxx = maxy = 0; + for (line = symbol->Line, j = symbol->LineN; j; j--, line++) { + minx = MIN(minx, line->Point1.X); + miny = MIN(miny, line->Point1.Y); + minx = MIN(minx, line->Point2.X); + miny = MIN(miny, line->Point2.Y); + maxx = MAX(maxx, line->Point1.X); + maxy = MAX(maxy, line->Point1.Y); + maxx = MAX(maxx, line->Point2.X); + maxy = MAX(maxy, line->Point2.Y); + } + + for(arc = arclist_first(&symbol->arcs); arc != NULL; arc = arclist_next(arc)) { + pcb_arc_bbox(arc); + minx = MIN(minx, arc->BoundingBox.X1); + miny = MIN(miny, arc->BoundingBox.Y1); + maxx = MAX(maxx, arc->BoundingBox.X2); + maxy = MAX(maxy, arc->BoundingBox.Y2); + } + + for(poly = polylist_first(&symbol->polys); poly != NULL; poly = polylist_next(poly)) { + pcb_poly_bbox(poly); + minx = MIN(minx, poly->BoundingBox.X1); + miny = MIN(miny, poly->BoundingBox.Y1); + maxx = MAX(maxx, poly->BoundingBox.X2); + maxy = MAX(maxy, poly->BoundingBox.Y2); + } + + + /* move symbol to left edge */ + for (line = symbol->Line, j = symbol->LineN; j; j--, line++) + pcb_line_move(line, -minx, 0); + + for(arc = arclist_first(&symbol->arcs); arc != NULL; arc = arclist_next(arc)) + pcb_arc_move(arc, -minx, 0); + + for(poly = polylist_first(&symbol->polys); poly != NULL; poly = polylist_next(poly)) + pcb_poly_move(poly, -minx, 0); + + /* set symbol bounding box with a minimum cell size of (1,1) */ + symbol->Width = maxx - minx + 1; + symbol->Height = maxy + 1; + + /* check total min/max */ + Ptr->MaxWidth = MAX(Ptr->MaxWidth, symbol->Width); + Ptr->MaxHeight = MAX(Ptr->MaxHeight, symbol->Height); + totalminy = MIN(totalminy, miny); + } + + /* move coordinate system to the upper edge (lowest y on screen) */ + for (i = 0, symbol = Ptr->Symbol; i <= PCB_MAX_FONTPOSITION; i++, symbol++) { + if (symbol->Valid) { + symbol->Height -= totalminy; + for (line = symbol->Line, j = symbol->LineN; j; j--, line++) + pcb_line_move(line, 0, -totalminy); + + for(arc = arclist_first(&symbol->arcs); arc != NULL; arc = arclist_next(arc)) + pcb_arc_move(arc, 0, -totalminy); + + for(poly = polylist_first(&symbol->polys); poly != NULL; poly = polylist_next(poly)) + pcb_poly_move(poly, 0, -totalminy); + } + } + + /* setup the box for the default symbol */ + Ptr->DefaultSymbol.X1 = Ptr->DefaultSymbol.Y1 = 0; + Ptr->DefaultSymbol.X2 = Ptr->DefaultSymbol.X1 + Ptr->MaxWidth; + Ptr->DefaultSymbol.Y2 = Ptr->DefaultSymbol.Y1 + Ptr->MaxHeight; +} + +/* creates a new line in a symbol */ +pcb_line_t *pcb_font_new_line_in_sym(pcb_symbol_t *Symbol, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Thickness) +{ + pcb_line_t *line = Symbol->Line; + + /* realloc new memory if necessary and clear it */ + if (Symbol->LineN >= Symbol->LineMax) { + Symbol->LineMax += STEP_SYMBOLLINE; + line = (pcb_line_t *) realloc(line, Symbol->LineMax * sizeof(pcb_line_t)); + Symbol->Line = line; + memset(line + Symbol->LineN, 0, STEP_SYMBOLLINE * sizeof(pcb_line_t)); + } + + /* copy values */ + line = line + Symbol->LineN++; + line->Point1.X = X1; + line->Point1.Y = Y1; + line->Point2.X = X2; + line->Point2.Y = Y2; + line->Thickness = Thickness; + return line; +} + +pcb_poly_t *pcb_font_new_poly_in_sym(pcb_symbol_t *Symbol, int num_points) +{ + pcb_poly_t *p = calloc(sizeof(pcb_poly_t), 1); + if (num_points > 0) { + p->PointN = p->PointMax = num_points; + p->Points = malloc(sizeof(rnd_point_t) * num_points); + } + polylist_insert(&Symbol->polys, p); + return p; +} + +pcb_arc_t *pcb_font_new_arc_in_sym(pcb_symbol_t *Symbol, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t r, rnd_angle_t start, rnd_angle_t delta, rnd_coord_t thickness) +{ + pcb_arc_t *a = calloc(sizeof(pcb_arc_t), 1); + a->X = cx; + a->Y = cy; + a->Height = a->Width = r; + a->StartAngle = start; + a->Delta = delta; + a->Thickness = thickness; + arclist_insert(&Symbol->arcs, a); + return a; +} + + +static pcb_font_t *pcb_font_(pcb_board_t *pcb, pcb_font_id_t id, int fallback, int unlink) +{ + if (id <= 0) { + do_default:; + if (unlink) { + int s; + pcb_font_t *f = malloc(sizeof(pcb_font_t)); + memcpy(f, &pcb->fontkit.dflt, sizeof(pcb_font_t)); + /* change the parent of linked lists to f */ + for(s = 0; s < PCB_MAX_FONTPOSITION; s++) { + pcb_symbol_t *symbol = &f->Symbol[s]; + pcb_poly_t *poly; + pcb_arc_t *arc; + for(poly = polylist_first(&symbol->polys); poly != NULL; poly = polylist_next(poly)) + poly->link.parent = (gdl_list_t *)&symbol->polys; + for(arc = arclist_first(&symbol->arcs); arc != NULL; arc = arclist_next(arc)) + arc->link.parent = (gdl_list_t *)&symbol->arcs; + } + memset(&pcb->fontkit.dflt, 0, sizeof(pcb_font_t)); + return f; + } + else + return &pcb->fontkit.dflt; + } + + if (pcb->fontkit.hash_inited) { + pcb_font_t *f = htip_get(&pcb->fontkit.fonts, id); + if (f != NULL) { + if (unlink) + htip_popentry(&pcb->fontkit.fonts, id); + return f; + } + } + + if (fallback) + goto do_default; + + return NULL; +} + +pcb_font_t *pcb_font(pcb_board_t *pcb, pcb_font_id_t id, int fallback) +{ + return pcb_font_(pcb, id, fallback, 0); +} + +pcb_font_t *pcb_font_unlink(pcb_board_t *pcb, pcb_font_id_t id) +{ + return pcb_font_(pcb, id, 0, 1); +} + + +static void hash_setup(pcb_fontkit_t *fk) +{ + if (fk->hash_inited) + return; + + htip_init(&fk->fonts, longhash, longkeyeq); + fk->hash_inited = 1; +} + +pcb_font_t *pcb_new_font(pcb_fontkit_t *fk, pcb_font_id_t id, const char *name) +{ + pcb_font_t *f; + + if (id == 0) + return NULL; + + if (id < 0) + id = fk->last_id + 1; + + hash_setup(fk); + + /* do not attempt to overwrite/reuse existing font of the same ID, rather report error */ + f = htip_get(&fk->fonts, id); + if (f != NULL) + return NULL; + + f = calloc(sizeof(pcb_font_t), 1); + htip_set(&fk->fonts, id, f); + if (name != NULL) + f->name = rnd_strdup(name); + f->id = id; + + if (f->id > fk->last_id) + fk->last_id = f->id; + + return f; +} + +void pcb_font_free_symbol(pcb_symbol_t *s) +{ + pcb_poly_t *p; + pcb_arc_t *a; + + free(s->Line); + + for(p = polylist_first(&s->polys); p != NULL; p = polylist_first(&s->polys)) { + polylist_remove(p); + pcb_poly_free_fields(p); + free(p); + } + + for(a = arclist_first(&s->arcs); a != NULL; a = arclist_first(&s->arcs)) { + arclist_remove(a); + free(a); + } + + memset (s, 0, sizeof(pcb_symbol_t)); +} + +void pcb_font_free(pcb_font_t *f) +{ + int i; + for (i = 0; i <= PCB_MAX_FONTPOSITION; i++) + pcb_font_free_symbol(&f->Symbol[i]); + + free(f->name); + f->name = NULL; + f->id = -1; +} + +void pcb_fontkit_free(pcb_fontkit_t *fk) +{ + pcb_font_free(&fk->dflt); + if (fk->hash_inited) { + htip_entry_t *e; + for (e = htip_first(&fk->fonts); e; e = htip_next(&fk->fonts, e)) + pcb_font_free(e->value); + htip_uninit(&fk->fonts); + fk->hash_inited = 0; + } + fk->last_id = 0; +} + +void pcb_fontkit_reset(pcb_fontkit_t *fk) +{ + if (fk->hash_inited) { + htip_entry_t *e; + for (e = htip_first(&fk->fonts); e; e = htip_first(&fk->fonts)) { + pcb_font_free(e->value); + htip_delentry(&fk->fonts, e); + } + } + fk->last_id = 0; +} + +static void update_last_id(pcb_fontkit_t *fk) +{ + pcb_font_id_t id; + for (id = fk->last_id; id > 0; id--) { + if (htip_has(&fk->fonts, id)) + break; + } + fk->last_id = id; +} + +int pcb_del_font(pcb_fontkit_t *fk, pcb_font_id_t id) +{ + htip_entry_t *e; + + if ((id == 0) || (!fk->hash_inited) || (htip_get(&fk->fonts, id) == NULL)) + return -1; + + e = htip_popentry(&fk->fonts, id); + pcb_font_free(e->value); + rnd_event(&PCB->hidlib, PCB_EVENT_FONT_CHANGED, "i", id); + if (id == fk->last_id) + update_last_id(fk); + return 0; +} + +static void copy_font(pcb_font_t *dst, pcb_font_t *src) +{ + int i; + + memcpy(dst, src, sizeof(pcb_font_t)); + for (i = 0; i <= PCB_MAX_FONTPOSITION; i++) { + pcb_poly_t *p_src; + pcb_arc_t *a_src; + + if (src->Symbol[i].Line) { + dst->Symbol[i].Line = malloc(sizeof(pcb_line_t) * src->Symbol[i].LineMax); + memcpy(dst->Symbol[i].Line, src->Symbol[i].Line, sizeof(pcb_line_t) * src->Symbol[i].LineN); + } + + memset(&dst->Symbol[i].polys, 0, sizeof(polylist_t)); + for(p_src = polylist_first(&src->Symbol[i].polys); p_src != NULL; p_src = polylist_next(p_src)) { + pcb_poly_t *p_dst = pcb_font_new_poly_in_sym(&dst->Symbol[i], p_src->PointN); + memcpy(p_dst->Points, p_src->Points, p_src->PointN * sizeof(rnd_point_t)); + } + + memset(&dst->Symbol[i].arcs, 0, sizeof(arclist_t)); + for(a_src = arclist_first(&src->Symbol[i].arcs); a_src != NULL; a_src = arclist_next(a_src)) { + pcb_font_new_arc_in_sym(&dst->Symbol[i], a_src->X, a_src->Y, a_src->Width, + a_src->StartAngle, a_src->Delta, a_src->Thickness); + } + } + if (src->name != NULL) + dst->name = rnd_strdup(src->name); +} + +int pcb_move_font(pcb_fontkit_t *fk, pcb_font_id_t src, pcb_font_id_t dst) +{ + htip_entry_t *e; + pcb_font_t *src_font; + + if ((!fk->hash_inited) || (htip_get(&fk->fonts, src) == NULL)) + return -1; + + pcb_del_font(fk, dst); + + e = htip_popentry(&fk->fonts, src); + src_font = e->value; + if (dst == 0) { + pcb_font_free (&fk->dflt); + copy_font (&fk->dflt, src_font); + pcb_font_free (src_font); + fk->dflt.id = 0; + } else { + htip_set(&fk->fonts, dst, src_font); + src_font->id = dst; + } + if (src == fk->last_id) + update_last_id (fk); + fk->last_id = MAX(fk->last_id, dst); + rnd_event(&PCB->hidlib, PCB_EVENT_FONT_CHANGED, "i", src); + rnd_event(&PCB->hidlib, PCB_EVENT_FONT_CHANGED, "i", dst); + + return 0; +} + Index: tags/2.3.0/src/font.h =================================================================== --- tags/2.3.0/src/font.h (nonexistent) +++ tags/2.3.0/src/font.h (revision 33253) @@ -0,0 +1,101 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_FONT_H +#define PCB_FONT_H + +#include +#include +#include "obj_poly.h" +#include "obj_poly_list.h" +#include "obj_arc.h" +#include "obj_arc_list.h" +#include + +/* --------------------------------------------------------------------------- + * symbol and font related stuff + */ +typedef struct symbol_s { /* a single symbol */ + pcb_line_t *Line; + rnd_bool Valid; + rnd_cardinal_t LineN; /* number of lines */ + rnd_cardinal_t LineMax; /* lines allocated */ + rnd_coord_t Width, Height, Delta; /* size of cell, distance to next symbol */ + polylist_t polys; /* simple (non-clipped) polygons */ + arclist_t arcs; +} pcb_symbol_t; + +typedef long int pcb_font_id_t; /* a font is referenced by a pcb_board_t:pcb_font_id_t pair */ + +struct pcb_font_s { /* complete set of symbols */ + rnd_coord_t MaxHeight, MaxWidth; /* maximum cell width and height */ + rnd_box_t DefaultSymbol; /* the default symbol is a filled box */ + pcb_symbol_t Symbol[PCB_MAX_FONTPOSITION + 1]; + char *name; + pcb_font_id_t id; +}; + +struct pcb_fontkit_s { /* a set of unrelated fonts */ + pcb_font_t dflt; /* default, fallback font, also the sysfont */ + htip_t fonts; + rnd_bool valid, hash_inited; + pcb_font_id_t last_id; /* highest font id ever seen in this kit */ +}; + +/* Look up font. If not found: return NULL (fallback=0), or return the + default font (fallback=1) */ +pcb_font_t *pcb_font(pcb_board_t *pcb, pcb_font_id_t id, int fallback); + +void pcb_font_create_default(pcb_board_t *pcb); +void pcb_font_set_info(pcb_font_t *Ptr); + +pcb_line_t *pcb_font_new_line_in_sym(pcb_symbol_t *Symbol, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Thickness); +pcb_arc_t *pcb_font_new_arc_in_sym(pcb_symbol_t *Symbol, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t r, rnd_angle_t start, rnd_angle_t delta, rnd_coord_t thickness); +pcb_poly_t *pcb_font_new_poly_in_sym(pcb_symbol_t *Symbol, int num_points); + +void pcb_font_free(pcb_font_t *f); + +/* Free all drawing primitives of a symbol, leaving it empty */ +void pcb_font_free_symbol(pcb_symbol_t *s); + +/*** font kit handling ***/ +void pcb_fontkit_free(pcb_fontkit_t *fk); +pcb_font_t *pcb_new_font(pcb_fontkit_t *fk, pcb_font_id_t id, const char *name); +int pcb_del_font(pcb_fontkit_t *fk, pcb_font_id_t id); +int pcb_move_font(pcb_fontkit_t *fk, pcb_font_id_t src, pcb_font_id_t dst); + +/* Reset the fontkit so that only the default font is kept and all extra fonts are purged */ +void pcb_fontkit_reset(pcb_fontkit_t *fk); + +/* Unlink the font from pcb, but do not free anything but return the font */ +pcb_font_t *pcb_font_unlink(pcb_board_t *pcb, pcb_font_id_t id); + + +#endif + Index: tags/2.3.0/src/font_act.c =================================================================== --- tags/2.3.0/src/font_act.c (nonexistent) +++ tags/2.3.0/src/font_act.c (revision 33253) @@ -0,0 +1,181 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ +#include "config.h" +#include +#include "board.h" +#include +#include +#include "font.h" +#include "conf_core.h" +#include "plug_io.h" +#include "event.h" + +#define PCB (do not use PCB directly) + +static const char pcb_acts_load_font_from[] = "LoadFontFrom([file, id])"; +static const char pcb_acth_load_font_from[] = "Load PCB font from a file"; + +fgw_error_t pcb_act_load_font_from(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL, *sid = NULL; + static char *default_file = NULL; + pcb_font_id_t fid, dst_fid = -1; + pcb_font_t *fnt; + int r; + + RND_ACT_MAY_CONVARG(1, FGW_STR, load_font_from, fname = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, load_font_from, sid = argv[2].val.str); + + if (sid != NULL) { + char *end; + fid = strtol(sid, &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "LoadFontFrom(): when second argument is present, it must be an integer\n"); + return 1; + } + if (pcb_font(PCB_ACT_BOARD, fid, 0) != NULL) { /* font already exists */ + dst_fid = fid; + fid = -1; /* allocate a new id, which will be later moved to dst_fid */ + } + } + else + fid = -1; /* auto-allocate a new ID */ + + if (!fname || !*fname) { + static const char *flt_lht[] = {"*.lht", NULL}; + static const char *flt_pcb[] = {"*.font", "*.pcb_font", NULL}; + static const char *flt_fonts[] = {"*.lht", "*.font", "*.pcb_font", NULL}; + static const char *flt_any[] = {"*", "*.*", NULL}; + const rnd_hid_fsd_filter_t flt[] = { + {"any font", NULL, flt_fonts}, + {"lihata pcb-rnd font", NULL, flt_lht}, + {"gEDA pcb font", NULL, flt_pcb}, + {"all", NULL, flt_any}, + {NULL, NULL,NULL} + }; + fname = rnd_gui->fileselect(rnd_gui, + "Load PCB font file...", "Picks a PCB font file to load.\n", + default_file, ".font", flt, "pcbfont", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 0; /* cancel */ + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + fnt = pcb_new_font(&PCB_ACT_BOARD->fontkit, fid, NULL); + if (fnt == NULL) { + rnd_message(RND_MSG_ERROR, "LoadFontFrom(): unable to allocate font\n"); + return 1; + } + + r = pcb_parse_font(fnt, fname); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_FONT_CHANGED, "i", fnt->id); + if (r != 0) { + rnd_message(RND_MSG_ERROR, "LoadFontFrom(): failed to load font from %s\n", fname); + pcb_del_font(&PCB_ACT_BOARD->fontkit, fnt->id); + return 1; + } + + if (dst_fid != -1) { + pcb_move_font(&PCB_ACT_BOARD->fontkit, fnt->id, dst_fid); + } + + fid = dst_fid == 0 ? 0 : fnt->id; + rnd_message(RND_MSG_INFO, "LoadFontFrom(): new font (ID %d) successfully loaded from file %s\n", fid, fname); + RND_ACT_IRES(0); + return 0; +} + + +static const char pcb_acts_save_font_to[] = "SaveFontTo([file, id])"; +static const char pcb_acth_save_font_to[] = "Save PCB font to a file"; + +fgw_error_t pcb_act_save_font_to(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL, *sid = NULL; + static char *default_file = NULL; + pcb_font_id_t fid; + pcb_font_t *fnt; + int r; + + RND_ACT_MAY_CONVARG(1, FGW_STR, load_font_from, fname = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, load_font_from, sid = argv[1].val.str); + + if (sid != NULL) { + char *end; + fid = strtol(sid, &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "SaveFontTo(): when second argument is present, it must be an integer\n"); + return 1; + } + if (pcb_font(PCB_ACT_BOARD, fid, 0) == NULL) { + rnd_message(RND_MSG_ERROR, "SaveFontTo(): can not fetch font ID %d\n", fid); + return 1; + } + } + else + fid = conf_core.design.text_font_id; + + fnt = pcb_font(PCB_ACT_BOARD, fid, 0); + if (fnt == NULL) { + rnd_message(RND_MSG_ERROR, "SaveFontTo(): failed to fetch font %d\n", fid); + return 1; + } + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Save PCB font file...", + "Picks a PCB font file to save.\n", + default_file, ".font", NULL, "pcbfont", RND_HID_FSD_MAY_NOT_EXIST, NULL); + if (fname == NULL) + RND_ACT_FAIL(save_font_to); + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + r = pcb_write_font(fnt, fname, "lihata"); + if (r != 0) { + rnd_message(RND_MSG_ERROR, "SaveFontTo(): failed to save font to %s\n", fname); + return 1; + } + + RND_ACT_IRES(0); + return 0; +} + + +static rnd_action_t font_action_list[] = { + {"LoadFontFrom", pcb_act_load_font_from, pcb_acth_load_font_from, pcb_acts_load_font_from}, + {"SaveFontTo", pcb_act_save_font_to, pcb_acth_save_font_to, pcb_acts_save_font_to} +}; + +void pcb_font_act_init2(void) +{ + RND_REGISTER_ACTIONS(font_action_list, NULL); +} Index: tags/2.3.0/src/font_internal.c =================================================================== --- tags/2.3.0/src/font_internal.c (nonexistent) +++ tags/2.3.0/src/font_internal.c (revision 33253) @@ -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/2.3.0/src/funchash_core.h =================================================================== --- tags/2.3.0/src/funchash_core.h (nonexistent) +++ tags/2.3.0/src/funchash_core.h (revision 33253) @@ -0,0 +1,10 @@ +/* central, auto-generated enum of core function IDs */ + +#include + +#define action_entry(x) F_ ## x, +typedef enum { +#include "funchash_core_list.h" +F_END +} pcb_function_id_t; +#undef action_entry Index: tags/2.3.0/src/funchash_core_list.h =================================================================== --- tags/2.3.0/src/funchash_core_list.h (nonexistent) +++ tags/2.3.0/src/funchash_core_list.h (revision 33253) @@ -0,0 +1,179 @@ +/* + Central list of function IDs + The core and core plugins use these from a single, central hash + This list is used to cpp-generate the F_* constants in enum pcb_function_id_t +*/ + +/* layer purpose */ +action_entry(user) +action_entry(fab) +action_entry(assy) +action_entry(csect) +action_entry(pdrill) +action_entry(udrill) +action_entry(proute) +action_entry(uroute) +action_entry(ucut) +action_entry(uvcut) + +/* Keywords for actions */ +action_entry(Add) +action_entry(AddSelected) +action_entry(AddRats) +action_entry(All) +action_entry(AllConnections) +action_entry(AllRats) +action_entry(AllUnusedPins) +action_entry(AutoLen) +action_entry(Block) +action_entry(Buffer) +action_entry(Cancel) +action_entry(Center) +action_entry(Check) +action_entry(Clear) +action_entry(ClearAndRedraw) +action_entry(ClearList) +action_entry(Close) +action_entry(CloseHole) +action_entry(Connection) +action_entry(Convert) +action_entry(ConvertSubc) +action_entry(CycleClip) +action_entry(CycleCrosshair) +action_entry(DeleteRats) +action_entry(Done) +action_entry(Drag) +action_entry(DrillReport) +action_entry(Element) +action_entry(ElementConnections) +action_entry(ElementToBuffer) +action_entry(Escape) +action_entry(Eq) +action_entry(Export) +action_entry(Find) +action_entry(FlipElement) +action_entry(Found) +action_entry(FoundPins) +action_entry(Footprint) +action_entry(FootprintToBuffer) +action_entry(ForceThaw) +action_entry(Freeze) +action_entry(GetSource) +action_entry(Grid) +action_entry(Hash) +action_entry(Invert) +action_entry(Layer) +action_entry(Layout) +action_entry(LayoutAs) +action_entry(LayoutToBuffer) +action_entry(Lihata) +action_entry(Line) +action_entry(LineSize) +action_entry(LoadAll) +action_entry(Loose) +action_entry(Merge) +action_entry(Mirror) +action_entry(MoveSelected) +action_entry(Native) +action_entry(Netlist) +action_entry(Need) +action_entry(Next) +action_entry(NoAutoLen) +action_entry(Normalize) +action_entry(Notify) +action_entry(NoAllRats) +action_entry(NoRats) +action_entry(Object) +action_entry(Off) +action_entry(On) +action_entry(Pan) +action_entry(PasteBuffer) +action_entry(PinOrPadName) +action_entry(Pinout) +action_entry(Pop) +action_entry(Press) +action_entry(PreviousPoint) +action_entry(Prev) +action_entry(Push) +action_entry(Rats) +action_entry(RatsNest) +action_entry(Redraw) +action_entry(Refdes) +action_entry(Release) +action_entry(Revert) +action_entry(RemoveSelected) +action_entry(Rename) +action_entry(Report) +action_entry(ResetLayerObjects) +action_entry(ResetLinesAndPolygons) +action_entry(ResetPadstacks) +action_entry(ResetPinsViasAndPads) +action_entry(Resize) +action_entry(Restore) +action_entry(Ripup) +action_entry(Rotate) +action_entry(Save) +action_entry(SaveAll) +action_entry(Select) +action_entry(Selected) +action_entry(SelectedArcs) +action_entry(SelectedElements) +action_entry(SelectedLines) +action_entry(SelectedNames) +action_entry(SelectedObjects) +action_entry(SelectedPads) +action_entry(SelectedPins) +action_entry(SelectedPadstacks) +action_entry(SelectedTexts) +action_entry(SelectedVias) +action_entry(SelectedRats) +action_entry(Sides) +action_entry(Sort) +action_entry(Start) +action_entry(Stroke) +action_entry(Style) +action_entry(Subc) +action_entry(Subcircuit) +action_entry(SubcConnections) +action_entry(SubcToBuffer) +action_entry(SubcID) +action_entry(Swap) +action_entry(TermID) +action_entry(Text) +action_entry(TextScale) +action_entry(Thaw) +action_entry(ToLayout) +action_entry(ToggleAllDirections) +action_entry(ToggleAutoDRC) +action_entry(ToggleClearLine) +action_entry(ToggleFullPoly) +action_entry(ToggleGrid) +action_entry(ToggleHideNames) +action_entry(ToggleMinCut) +action_entry(ToggleMask) +action_entry(TogglePaste) +action_entry(ToggleName) +action_entry(ToggleObject) +action_entry(ToggleShowDRC) +action_entry(ToggleLiveRoute) +action_entry(ToggleRubberBandMode) +action_entry(ToggleStartDirection) +action_entry(ToggleSnapPin) +action_entry(ToggleSnapOffGridLine) +action_entry(ToggleHighlightOnPoint) +action_entry(ToggleThindraw) +action_entry(ToggleLockNames) +action_entry(ToggleOnlyNames) +action_entry(ToggleThindrawPoly) +action_entry(ToggleOrthoMove) +action_entry(ToggleLocalRef) +action_entry(ToggleCheckPlanes) +action_entry(ToggleUniqueNames) +action_entry(ToggleStroke) +action_entry(Transparent) +action_entry(Unselect) +action_entry(UnFreeze) +action_entry(Via) +action_entry(Warp) +action_entry(Zoom) + Index: tags/2.3.0/src/global_typedefs.h =================================================================== --- tags/2.3.0/src/global_typedefs.h (nonexistent) +++ tags/2.3.0/src/global_typedefs.h (revision 33253) @@ -0,0 +1,67 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2016..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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef GLOBAL_TYPEDEFS_H +#define GLOBAL_TYPEDEFS_H + +#include + +typedef struct pcb_board_s pcb_board_t; +typedef struct pcb_data_s pcb_data_t; +typedef struct pcb_layer_stack_s pcb_layer_stack_t; +typedef struct pcb_layer_s pcb_layer_t; +typedef struct pcb_layergrp_s pcb_layergrp_t; +typedef struct pcb_buffer_s pcb_buffer_t; +typedef struct pcb_net_s pcb_net_t; +typedef struct pcb_net_term_s pcb_net_term_t; +typedef struct pcb_oldnet_s pcb_oldnet_t; +typedef struct pcb_connection_s pcb_connection_t; +typedef struct pcb_font_s pcb_font_t; +typedef struct pcb_fontkit_s pcb_fontkit_t; +typedef struct pcb_line_s pcb_line_t; +typedef struct pcb_arc_s pcb_arc_t; +typedef struct pcb_gfx_s pcb_gfx_t; +typedef struct pcb_rat_line_s pcb_rat_t; + +typedef struct pcb_poly_s pcb_poly_t; +typedef struct pcb_pstk_s pcb_pstk_t; +typedef struct pcb_pstk_proto_s pcb_pstk_proto_t; + +typedef struct pcb_ratspatch_line_s pcb_ratspatch_line_t; +typedef struct pcb_subc_s pcb_subc_t; +typedef struct pcb_text_s pcb_text_t; + +typedef struct pcb_any_obj_s pcb_any_obj_t; +typedef struct pcb_any_line_s pcb_any_line_t; + +typedef union pcb_parent_s pcb_parent_t; + +typedef struct pcb_plug_io_s pcb_plug_io_t; +typedef struct pcb_plug_fp_map_s pcb_plug_fp_map_t; + +typedef struct pcb_view_s pcb_view_t; +#endif Index: tags/2.3.0/src/globalconst.h =================================================================== --- tags/2.3.0/src/globalconst.h (nonexistent) +++ tags/2.3.0/src/globalconst.h (revision 33253) @@ -0,0 +1,62 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_GLOBALCONST_H +#define PCB_GLOBALCONST_H + +#include + +#define PCB_MAX_LAYER 38 /* max number of layer, check source code for more changes, a *lot* more changes */ +/* new array size that allows substrate layers */ +#define PCB_MAX_LAYERGRP ((PCB_MAX_LAYER+8)*2) /* max number of layer groups, a.k.a. physical layers: a few extra outer layers per side, pluse one substrate per real layer */ +#define PCB_MIN_THICKNESS RND_MIN_SIZE +#define PCB_MAX_THICKNESS RND_MAX_COORD +#define PCB_MIN_ARCRADIUS RND_MIN_SIZE +#define PCB_MAX_ARCRADIUS RND_MAX_COORD +#define PCB_MIN_TEXTSCALE 1 /* scaling of text objects in percent (must be an integer greater than 0) */ +#define PCB_MAX_TEXTSCALE 10000 +#define PCB_MIN_PINORVIASIZE RND_MIL_TO_COORD(20) /* size of a pin or via */ +#define PCB_MIN_PINORVIAHOLE RND_MIL_TO_COORD(4) /* size of a pins or vias drilling hole */ +#define PCB_MAX_PINORVIASIZE ((rnd_coord_t)RND_LARGE_VALUE) +#define PCB_MIN_PINORVIACOPPER RND_MIL_TO_COORD(4) /* min difference outer-inner diameter */ +#define PCB_MIN_GRID 1 +#define PCB_MAX_FONTPOSITION 255 /* upper limit of characters in my font */ + +#define PCB_MAX_BUFFER 5 /* number of pastebuffers additional changes in menu.c are also required to select more buffers */ + +#define PCB_EMARK_SIZE RND_MIL_TO_COORD(10) /* size of diamond element mark */ +#define PCB_SUBC_AUX_UNIT RND_MM_TO_COORD(1) /* size of the unit vector for the subc-aux layer */ + +/**** Font ***/ +/* These are used in debug draw font rendering (e.g. pin names) and reverse + scale calculations (e.g. when report is trying to figure how the font + is scaled. Changing these values is not really supported. */ +#define PCB_FONT_CAPHEIGHT RND_MIL_TO_COORD (45) /* (Approximate) capheight size of the default PCB font */ +#define PCB_DEFAULT_CELLSIZE 50 /* default cell size for symbols */ + +#endif Index: tags/2.3.0/src/gui_act.c =================================================================== --- tags/2.3.0/src/gui_act.c (nonexistent) +++ tags/2.3.0/src/gui_act.c (revision 33253) @@ -0,0 +1,1604 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" +#include "board.h" +#include "build_run.h" +#include "conf_core.h" +#include +#include "data.h" +#include +#include +#include +#include "undo.h" +#include "funchash_core.h" +#include "change.h" + +#include "draw.h" +#include "search.h" +#include "find.h" +#include +#include +#include +#include "event.h" +#include "layer.h" +#include "layer_ui.h" +#include "layer_grp.h" +#include "layer_vis.h" +#include "attrib.h" +#include +#include "operation.h" +#include "obj_subc_op.h" +#include +#include "route_style.h" +#include "tool_logic.h" + +#define CLONE_TYPES PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY + +/* --------------------------------------------------------------------------- */ +/* Toggle actions are kept for compatibility; new code should use the conf system instead */ +static const char pcb_acts_Display[] = + "Display(SubcID, template)\n" + "Display(Grid|Redraw|Pinout|PinOrPadName)\n" + "Display(CycleClip|ToggleAllDirections|ToggleStartDirection)\n" + "Display(ToggleGrid|ToggleRubberBandMode|ToggleUniqueNames)\n" + "Display(ToggleName|ToggleClearLine|ToggleFullPoly|ToggleSnapPin)\n" + "Display(ToggleSnapOffGridLine|ToggleHighlightOnPoint|ToggleCheckPlanes)\n" + "Display(ToggleThindraw|ToggleThindrawPoly|ToggleOrthoMove|ToggleLocalRef)\n" + "Display(ToggleLiveRoute|ToggleShowDRC|ToggleAutoDRC|LockNames|OnlyNames)"; + +static const char pcb_acth_Display[] = "Several display-related actions."; +/* DOC: display.html */ +extern pcb_opfunc_t ChgFlagFunctions; +static fgw_error_t pcb_act_Display(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *str_dir = NULL; + int id; + int err = 0; + + RND_ACT_IRES(0); + RND_ACT_CONVARG(1, FGW_KEYWORD, Display, id = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, Display, str_dir = argv[2].val.str); + + if (id == F_SubcID) { /* change the displayed name of subcircuits */ + if (argc > 1) + rnd_conf_set(RND_CFR_DESIGN, "editor/subc_id", -1, str_dir, RND_POL_OVERWRITE); + else + rnd_conf_set(RND_CFR_DESIGN, "editor/subc_id", -1, "", RND_POL_OVERWRITE); + + rnd_gui->invalidate_all(rnd_gui); /* doesn't change too often, isn't worth anything more complicated */ + pcb_draw(); + return 0; + } + + if (id == F_TermID) { /* change the displayed name of terminals */ + if (argc > 1) + rnd_conf_set(RND_CFR_DESIGN, "editor/term_id", -1, str_dir, RND_POL_OVERWRITE); + else + rnd_conf_set(RND_CFR_DESIGN, "editor/term_id", -1, "", RND_POL_OVERWRITE); + + rnd_gui->invalidate_all(rnd_gui); /* doesn't change too often, isn't worth anything more complicated */ + pcb_draw(); + return 0; + } + + if (!str_dir || !*str_dir) { + switch (id) { + + /* redraw layout */ + case F_ClearAndRedraw: + case F_Redraw: + rnd_hid_redraw(PCB); + break; + + /* toggle line-adjust flag */ + case F_ToggleAllDirections: + rnd_conf_toggle_editor(all_direction_lines); + rnd_tool_adjust_attached(RND_ACT_HIDLIB); + break; + + case F_CycleClip: + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + if (conf_core.editor.all_direction_lines) { + rnd_conf_toggle_editor(all_direction_lines); + rnd_conf_setf(RND_CFR_DESIGN,"editor/line_refraction",-1,"%d",0); + } + else { + rnd_conf_setf(RND_CFR_DESIGN,"editor/line_refraction",-1,"%d",(conf_core.editor.line_refraction +1) % 3); + } + rnd_tool_adjust_attached(RND_ACT_HIDLIB); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + break; + + case F_CycleCrosshair: + rnd_message(RND_MSG_ERROR, "CycleCrosshair: not supported any more\n"); + break; + + case F_ToggleRubberBandMode: + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + rnd_conf_toggle_editor(rubber_band_mode); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + break; + + case F_ToggleStartDirection: + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + rnd_conf_toggle_editor(swap_start_direction); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + break; + + case F_ToggleUniqueNames: + rnd_message(RND_MSG_ERROR, "Unique names/refdes is not supported any more - please use the renumber plugin\n"); + break; + + case F_ToggleSnapPin: + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + rnd_conf_toggle_editor(snap_pin); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + break; + + case F_ToggleSnapOffGridLine: + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + rnd_conf_toggle_editor(snap_offgrid_line); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + break; + + case F_ToggleHighlightOnPoint: + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + rnd_conf_toggle_editor(highlight_on_point); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + break; + + case F_ToggleLocalRef: + rnd_conf_toggle_editor(local_ref); + break; + + case F_ToggleThindraw: + rnd_conf_toggle_editor(thin_draw); + rnd_hid_redraw(PCB); + break; + + case F_ToggleThindrawPoly: + rnd_conf_toggle_editor(thin_draw_poly); + rnd_hid_redraw(PCB); + break; + + case F_ToggleLockNames: + rnd_conf_toggle_editor(lock_names); + rnd_conf_set_editor(only_names, 0); + break; + + case F_ToggleOnlyNames: + rnd_conf_toggle_editor(only_names); + rnd_conf_set_editor(lock_names, 0); + break; + + case F_ToggleHideNames: + rnd_conf_toggle_editor(hide_names); + rnd_hid_redraw(PCB); + break; + + case F_ToggleStroke: + rnd_conf_toggle_heditor(enable_stroke); + break; + + case F_ToggleShowDRC: + rnd_conf_toggle_editor(show_drc); + break; + + case F_ToggleLiveRoute: + rnd_conf_toggle_editor(live_routing); + break; + + case F_ToggleAutoDRC: + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + rnd_conf_toggle_editor(auto_drc); + if (conf_core.editor.auto_drc && rnd_conf.editor.mode == pcb_crosshair.tool_line) { + if (pcb_data_clear_flag(PCB->Data, PCB_FLAG_FOUND, 1, 1) > 0) { + pcb_undo_inc_serial(); + pcb_draw(); + } + if (pcb_crosshair.AttachedLine.State != PCB_CH_STATE_FIRST) { + pcb_find_t fctx; + memset(&fctx, 0, sizeof(fctx)); + fctx.flag_set = PCB_FLAG_FOUND; + fctx.flag_chg_undoable = 1; + pcb_find_from_xy(&fctx, PCB->Data, pcb_crosshair.X, pcb_crosshair.Y); + pcb_find_free(&fctx); + } + } + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + break; + + case F_ToggleCheckPlanes: + rnd_conf_toggle_editor(check_planes); + rnd_hid_redraw(PCB); + break; + + case F_ToggleOrthoMove: + rnd_conf_toggle_editor(orthogonal_moves); + break; + + case F_ToggleName: + rnd_conf_toggle_editor(show_number); + rnd_hid_redraw(PCB); + break; + + case F_ToggleClearLine: + rnd_conf_toggle_editor(clear_line); + break; + + case F_ToggleFullPoly: + rnd_conf_toggle_editor(full_poly); + break; + + /* shift grid alignment */ + case F_ToggleGrid: + { + rnd_coord_t old_grid = rnd_conf.editor.grid, x, y; + + rnd_hidlib_set_grid(RND_ACT_HIDLIB, 1, rnd_false, 0, 0); + /* ask for coordinates, but then use the crosshair: with grid 0;0, this + means the user can go anywhere, but snapping will apply; if the + crosshair is snapped, we are aligning to an object(point), else + we are aligning to whatever fine point the user clicked */ + rnd_hid_get_coords("Click to set the grid origin", &x, &y, 1); + if (pcb_crosshair_move_absolute(PCB_ACT_BOARD, pcb_crosshair.X, pcb_crosshair.Y)) + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); /* first notify was in MoveCrosshairAbs */ + rnd_hidlib_set_grid(RND_ACT_HIDLIB, old_grid, rnd_true, pcb_crosshair.X, pcb_crosshair.Y); + + rnd_grid_inval(); + } + break; + + /* toggle displaying of the grid */ + case F_Grid: + rnd_conf_toggle_heditor(draw_grid); + rnd_hid_redraw(PCB); + break; + + /* display the pinout of a subcircuit */ + case F_Pinout: + return rnd_actionva(RND_ACT_HIDLIB, "pinout", NULL); + + /* toggle displaying of terminal names */ + case F_PinOrPadName: + { + int type; + void *ptr1, *ptr2, *ptr3; + rnd_coord_t x, y; + rnd_hid_get_coords("Click on a subcircuit", &x, &y, 0); + + /* toggle terminal ID print for subcircuit parts */ + type = pcb_search_screen(x, y, PCB_OBJ_SUBC | PCB_OBJ_SUBC_PART | PCB_OBJ_PSTK | PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_TEXT, (void **)&ptr1, (void **)&ptr2, (void **)&ptr3); + if (type) { + pcb_any_obj_t *obj = ptr2; + pcb_opctx_t opctx; + + switch(type) { + case PCB_OBJ_SUBC: + opctx.chgflag.pcb = PCB; + opctx.chgflag.how = PCB_CHGFLG_TOGGLE; + opctx.chgflag.flag = PCB_FLAG_TERMNAME; + pcb_subc_op(PCB->Data, (pcb_subc_t *)obj, &ChgFlagFunctions, &opctx, 0); + ((pcb_subc_t *)obj)->auto_termname_display = !((pcb_subc_t *)obj)->auto_termname_display; + pcb_undo_inc_serial(); + return 0; + break; + case PCB_OBJ_LINE: + case PCB_OBJ_ARC: + case PCB_OBJ_POLY: + case PCB_OBJ_TEXT: + case PCB_OBJ_PSTK: + pcb_obj_invalidate_label(type, ptr1, ptr2, ptr3); + break; + default: + return 0; /* nothing else can have a displayed name */ + } + + pcb_undo_add_obj_to_flag(ptr2); + PCB_FLAG_TOGGLE(PCB_FLAG_TERMNAME, obj); + pcb_board_set_changed_flag(pcb, rnd_true); + pcb_undo_inc_serial(); + pcb_draw(); + } + break; + } + default: + err = 1; + } + } + else if (str_dir) { + switch(id) { + case F_ToggleGrid: + if (argc > 3) { + if (fgw_arg_conv(&rnd_fgw, &argv[3], FGW_KEYWORD) != 0) { + RND_ACT_FAIL(Display); + return FGW_ERR_ARG_CONV; + } + RND_ACT_HIDLIB->grid_ox = rnd_get_value(argv[2].val.str, NULL, NULL, NULL); + RND_ACT_HIDLIB->grid_oy = rnd_get_value(argv[3].val.str, NULL, NULL, NULL); + if (rnd_conf.editor.draw_grid) + rnd_hid_redraw(PCB); + } + break; + + default: + err = 1; + break; + } + } + + if (!err) + return 0; + + RND_ACT_FAIL(Display); +} + +/* ---------------------------------------------------------------- */ +static const char pcb_acts_CycleDrag[] = "CycleDrag()\n"; +static const char pcb_acth_CycleDrag[] = "Cycle through which object is being dragged"; +/* DOC: cycledrag.html */ +#define close_enough(a, b) ((((a)-(b)) > 0) ? ((a)-(b) < (PCB_SLOP * rnd_pixel_slop)) : ((a)-(b) > -(PCB_SLOP * rnd_pixel_slop))) +static fgw_error_t pcb_act_CycleDrag(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_hidlib_t *hidlib = RND_ACT_HIDLIB; + void *ptr1, *ptr2, *ptr3; + int over = 0; + + RND_ACT_IRES(0); + if (pcb_crosshair.drags == NULL) + return 0; + + do { + pcb_crosshair.drags_current++; + if (pcb_crosshair.drags_current >= pcb_crosshair.drags_len) { + pcb_crosshair.drags_current = 0; + over++; + } + + if (pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, pcb_crosshair.drags[pcb_crosshair.drags_current], PCB_OBJ_LINE) != PCB_OBJ_VOID) { + /* line has two endpoints, check which one is close to the original x;y */ + pcb_line_t *l = ptr2; + if (close_enough(hidlib->tool_x, l->Point1.X) && close_enough(hidlib->tool_y, l->Point1.Y)) { + pcb_crosshair_attached_clean(hidlib); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_LINE_POINT; + pcb_crosshair.AttachedObject.Ptr1 = ptr1; + pcb_crosshair.AttachedObject.Ptr2 = ptr2; + pcb_crosshair.AttachedObject.Ptr3 = &l->Point1; + goto switched; + } + if (close_enough(hidlib->tool_x, l->Point2.X) && close_enough(hidlib->tool_y, l->Point2.Y)) { + pcb_crosshair_attached_clean(hidlib); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_LINE_POINT; + pcb_crosshair.AttachedObject.Ptr1 = ptr1; + pcb_crosshair.AttachedObject.Ptr2 = ptr2; + pcb_crosshair.AttachedObject.Ptr3 = &l->Point2; + goto switched; + } + } + else if (pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, pcb_crosshair.drags[pcb_crosshair.drags_current], PCB_OBJ_ARC_POINT) != PCB_OBJ_VOID) { + rnd_coord_t ex, ey; + pcb_arc_get_end((pcb_arc_t *)ptr2, 0, &ex, &ey); + if (close_enough(hidlib->tool_x, ex) && close_enough(hidlib->tool_y, ey)) { + pcb_crosshair_attached_clean(hidlib); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_ARC_POINT; + pcb_crosshair.AttachedObject.Ptr1 = ptr1; + pcb_crosshair.AttachedObject.Ptr2 = ptr2; + pcb_crosshair.AttachedObject.Ptr3 = pcb_arc_start_ptr; + goto switched; + } + pcb_arc_get_end((pcb_arc_t *)ptr2, 1, &ex, &ey); + if (close_enough(hidlib->tool_x, ex) && close_enough(hidlib->tool_y, ey)) { + pcb_crosshair_attached_clean(hidlib); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_ARC_POINT; + pcb_crosshair.AttachedObject.Ptr1 = ptr1; + pcb_crosshair.AttachedObject.Ptr2 = ptr2; + pcb_crosshair.AttachedObject.Ptr3 = pcb_arc_end_ptr; + goto switched; + } + } + else if (pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, pcb_crosshair.drags[pcb_crosshair.drags_current], PCB_OBJ_ARC) != PCB_OBJ_VOID) { + pcb_crosshair_attached_clean(hidlib); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_ARC; + pcb_crosshair.AttachedObject.Ptr1 = ptr1; + pcb_crosshair.AttachedObject.Ptr2 = ptr2; + pcb_crosshair.AttachedObject.Ptr3 = ptr3; + goto switched; + } + + } while (over <= 1); + + RND_ACT_IRES(-1); + return 0; + switched:; + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_RUBBER_RESET, NULL); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_RUBBER_LOOKUP_LINES, "ippp", pcb_crosshair.AttachedObject.Type, pcb_crosshair.AttachedObject.Ptr1, pcb_crosshair.AttachedObject.Ptr2, pcb_crosshair.AttachedObject.Ptr3); + return 0; +} + +#undef close_enough + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_MarkCrosshair[] = "MarkCrosshair()\n" "MarkCrosshair(Center)"; +static const char pcb_acth_MarkCrosshair[] = "Set/Reset the pcb_crosshair mark."; +/* DOC: markcrosshair.html */ +static fgw_error_t pcb_act_MarkCrosshair(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int id = -2; + + RND_ACT_IRES(0); + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, Display, id = fgw_keyword(&argv[1])); + + if (id == -1) { /* invalid */ + RND_ACT_FAIL(MarkCrosshair); + return FGW_ERR_ARGV_TYPE; + } + else if (id == -2) { /* empty */ + if (pcb_marked.status) { + pcb_notify_mark_change(rnd_false); + pcb_marked.status = rnd_false; + pcb_marked.user_placed = 0; + pcb_notify_mark_change(rnd_true); + } + else { + pcb_notify_mark_change(rnd_false); + pcb_marked.status = rnd_true; + pcb_marked.user_placed = 1; + if (conf_core.editor.marker_snaps) { + pcb_marked.X = pcb_crosshair.X; + pcb_marked.Y = pcb_crosshair.Y; + } + else + rnd_hid_get_coords("Click on new mark", &pcb_marked.X, &pcb_marked.Y, 0); + pcb_notify_mark_change(rnd_true); + } + } + else if (id == F_Center) { + pcb_notify_mark_change(rnd_false); + pcb_marked.status = rnd_true; + if (conf_core.editor.marker_snaps) { + pcb_marked.X = pcb_crosshair.X; + pcb_marked.Y = pcb_crosshair.Y; + } + else + rnd_hid_get_coords("Click on new mark", &pcb_marked.X, &pcb_marked.Y, 0); + pcb_notify_mark_change(rnd_true); + pcb_marked.user_placed = 1; + } + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_RouteStyle[] = + "RouteStyle(style_id|style_name|@current, [set|get|del], [trace-thickness|trace-clearance|text-thickness|text-scale|name], [value]])\n" + "RouteStyle(new, [name])"; +static const char pcb_acth_RouteStyle[] = "Without second argument: copies the indicated routing style into the current pen; with second argument sets or gets a field of the routing style."; +/* DOC: routestyle.html */ +static fgw_error_t pcb_act_RouteStyle(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char *end; + const char *str = NULL, *cmd = "", *sfield = NULL; + pcb_route_style_t *rts; + rnd_coord_t c; + int number, is_curr; + + RND_ACT_IRES(0); + RND_ACT_CONVARG(1, FGW_STR, RouteStyle, str = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, RouteStyle, cmd = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, RouteStyle, sfield = argv[3].val.str); + + if (strcmp(str, "new") == 0) { + str = "new style"; + RND_ACT_MAY_CONVARG(2, FGW_STR, RouteStyle, str = argv[2].val.str); + res->type = FGW_INT; + res->val.nat_int = pcb_route_style_new(PCB, str, 1); + return 0; + } + + is_curr = (strcmp(str, "@current") == 0); + if (!is_curr) { + number = strtol(str, &end, 10); + + if (*end != '\0') { /* if not an integer, find by name */ + int n; + number = -1; + for(n = 0; n < vtroutestyle_len(&PCB->RouteStyle); n++) { + rts = &PCB->RouteStyle.array[n]; + if (rnd_strcasecmp(rts->name, str) == 0) { + number = n + 1; + break; + } + } + } + } + else + number = pcb_route_style_lookup(&PCB->RouteStyle, conf_core.design.line_thickness, conf_core.design.via_thickness, conf_core.design.via_drilling_hole, conf_core.design.clearance, NULL)+1; + + if ((number <= 0) || (number > vtroutestyle_len(&PCB->RouteStyle))) { + rnd_message(RND_MSG_ERROR, "RouteStyle: invalid route style name or index\n"); + RND_ACT_IRES(-1); + return 0; + } + + rts = &PCB->RouteStyle.array[number - 1]; + + switch(*cmd) { + case '\0': + do_select:; + pcb_board_set_line_width(rts->Thick); + pcb_board_set_via_size(rts->Diameter, rnd_true); + pcb_board_set_via_drilling_hole(rts->Hole, rnd_true); + pcb_board_set_clearance(rts->Clearance); + break; + case 'd': /* del */ + res->type = FGW_INT; + res->val.nat_int = pcb_route_style_del(PCB, number-1, 1); + return 0; + case 's': /* set */ + if (sfield == NULL) goto err_missing_field; + + if (strcmp(sfield, "trace-thickness") == 0) { + RND_ACT_CONVARG(4, FGW_COORD, RouteStyle, c = fgw_coord(&argv[4])); + pcb_route_style_change(PCB, number-1, &c, NULL, NULL, NULL, NULL, 1); + } + else if (strcmp(sfield, "text-thickness") == 0) { + RND_ACT_CONVARG(4, FGW_COORD, RouteStyle, c = fgw_coord(&argv[4])); + pcb_route_style_change(PCB, number-1, NULL, &c, NULL, NULL, NULL, 1); + } + else if (strcmp(sfield, "text-scale") == 0) { + int sc; + RND_ACT_CONVARG(4, FGW_COORD, RouteStyle, sc = argv[4].val.nat_int); + pcb_route_style_change(PCB, number-1, NULL, NULL, &sc, NULL, NULL, 1); + } + else if (strcmp(sfield, "trace-clearance") == 0) { + RND_ACT_CONVARG(4, FGW_COORD, RouteStyle, c = fgw_coord(&argv[4])); + pcb_route_style_change(PCB, number-1, NULL, NULL, NULL, &c, NULL, 1); + } + else if (strcmp(sfield, "name") == 0) { + const char *new_name; + RND_ACT_CONVARG(4, FGW_STR, RouteStyle, new_name = argv[4].val.cstr); + pcb_route_style_change_name(PCB, number-1, new_name, 1); + } + else goto err_bad_field; + rnd_event(&PCB->hidlib, PCB_EVENT_ROUTE_STYLES_CHANGED, NULL); + if (is_curr) + goto do_select; + break; + case 'g': /* get */ + if (sfield == NULL) goto err_missing_field; + if (strcmp(sfield, "trace-thickness") == 0) { + res->type = FGW_COORD; + fgw_coord(res) = rts->Thick; + } + else if (strcmp(sfield, "text-thickness") == 0) { + res->type = FGW_COORD; + fgw_coord(res) = rts->textt; + } + else if (strcmp(sfield, "text-scale") == 0) { + res->type = FGW_INT; + res->val.nat_int = rts->texts; + } + else if (strcmp(sfield, "trace-clearance") == 0) { + res->type = FGW_COORD; + fgw_coord(res) = rts->Clearance; + } + else if (strcmp(sfield, "name") == 0) { + res->type = FGW_STR; + res->val.cstr = rts->name; + } + else goto err_bad_field; + break; + default: + RND_ACT_FAIL(RouteStyle); + } + + return 0; + + err_missing_field:; + rnd_message(RND_MSG_ERROR, "RouteStyle: missing field name\n"); + RND_ACT_IRES(-1); + return 0; + + err_bad_field:; + rnd_message(RND_MSG_ERROR, "RouteStyle: invalid field name '%s'\n", sfield); + RND_ACT_IRES(-1); + return 0; + +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_SetSame[] = "SetSame()"; +static const char pcb_acth_SetSame[] = "Sets current layer and sizes to match indicated item."; +/* DOC: setsame.html */ +static void set_same_(rnd_coord_t Thick, rnd_coord_t Diameter, rnd_coord_t Hole, rnd_coord_t Clearance, char *Name) +{ + int known; + known = pcb_route_style_lookup(&PCB->RouteStyle, Thick, Diameter, Hole, Clearance, Name); + if (known < 0) { + /* unknown style, set properties */ + if (Thick != -1) { pcb_custom_route_style.Thick = Thick; rnd_conf_set_design("design/line_thickness", "%$mS", Thick); } + if (Clearance != -1) { pcb_custom_route_style.Clearance = Clearance; rnd_conf_set_design("design/clearance", "%$mS", Clearance); } + if (Diameter != -1) { pcb_custom_route_style.Diameter = Diameter; rnd_conf_set_design("design/via_thickness", "%$mS", Diameter); } + if (Hole != -1) { pcb_custom_route_style.Hole = Hole; rnd_conf_set_design("design/via_drilling_hole", "%$mS", Hole); } + PCB->pen_attr = NULL; + } + else + pcb_use_route_style_idx(&PCB->RouteStyle, known); +} + +static fgw_error_t pcb_act_SetSame(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_coord_t x, y; + void *ptr1, *ptr2, *ptr3; + int type; + pcb_layer_t *layer = PCB_CURRLAYER(PCB_ACT_BOARD); + + rnd_hid_get_coords("Select item to use properties from", &x, &y, 0); + + type = pcb_search_screen(x, y, CLONE_TYPES, &ptr1, &ptr2, &ptr3); +/* set layer current and size from line or arc */ + switch (type) { + case PCB_OBJ_LINE: + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + set_same_(((pcb_line_t *) ptr2)->Thickness, -1, -1, ((pcb_line_t *) ptr2)->Clearance / 2, NULL); + layer = (pcb_layer_t *) ptr1; + if (rnd_conf.editor.mode != pcb_crosshair.tool_line) + rnd_tool_select_by_name(RND_ACT_HIDLIB, "line"); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_ROUTE_STYLES_CHANGED, NULL); + break; + + case PCB_OBJ_ARC: + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + set_same_(((pcb_arc_t *) ptr2)->Thickness, -1, -1, ((pcb_arc_t *) ptr2)->Clearance / 2, NULL); + layer = (pcb_layer_t *) ptr1; + if (rnd_conf.editor.mode != pcb_crosshair.tool_arc) + rnd_tool_select_by_name(RND_ACT_HIDLIB, "arc"); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_ROUTE_STYLES_CHANGED, NULL); + break; + + case PCB_OBJ_POLY: + layer = (pcb_layer_t *) ptr1; + break; + + default: + RND_ACT_IRES(-1); + return 0; + } + if (layer != PCB_CURRLAYER(PCB_ACT_BOARD)) { + pcb_layervis_change_group_vis(RND_ACT_HIDLIB, pcb_layer_id(PCB_ACT_BOARD->Data, layer), rnd_true, rnd_true); + rnd_hid_redraw(PCB); + } + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_EditLayer[] = "Editlayer([@layer], [name=text|auto=[0|1]|sub=[0|1])]\nEditlayer([@layer], attrib, key=value)"; +static const char pcb_acth_EditLayer[] = "Change a property or attribute of a layer. If the first argument starts with @, it is taken as the layer name to manipulate, else the action uses the current layer. Without arguments or if only a layer name is specified, interactive runs editing."; +static fgw_error_t pcb_act_EditLayer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int ret = 0, n, interactive = 1, explicit = 0; + pcb_layer_t *ly = PCB_CURRLAYER(PCB_ACT_BOARD); + + for(n = 1; n < argc; n++) { + const char *arg; + RND_ACT_CONVARG(n, FGW_STR, EditLayer, arg = argv[n].val.str); + if (!explicit && (*arg == '@')) { + rnd_layer_id_t lid = pcb_layer_by_name(PCB->Data, arg+1); + if (lid < 0) { + rnd_message(RND_MSG_ERROR, "Can't find layer named %s\n", arg+1); + return 1; + } + ly = pcb_get_layer(PCB->Data, lid); + explicit = 1; + } + else if (strncmp(arg, "name=", 5) == 0) { + interactive = 0; + ret |= pcb_layer_rename_(ly, rnd_strdup(arg+5), 1); + pcb_board_set_changed_flag(pcb, rnd_true); + } + else if (strncmp(arg, "auto=", 5) == 0) { + interactive = 0; + if (rnd_istrue(arg+5)) + ly->comb |= PCB_LYC_AUTO; + else + ly->comb &= ~PCB_LYC_AUTO; + pcb_board_set_changed_flag(pcb, rnd_true); + } + else if (strncmp(arg, "sub=", 4) == 0) { + interactive = 0; + if (rnd_istrue(arg+4)) + ly->comb |= PCB_LYC_SUB; + else + ly->comb &= ~PCB_LYC_SUB; + pcb_board_set_changed_flag(pcb, rnd_true); + } + else if (strncmp(arg, "attrib", 6) == 0) { + char *key, *val; + interactive = 0; + n++; + if (n >= argc) { + rnd_message(RND_MSG_ERROR, "Need an attribute name=value\n", arg+1); + return 1; + } + key = rnd_strdup(arg); + val = strchr(key, '='); + if (val != NULL) { + *val = '\0'; + val++; + if (*val == '\0') + val = NULL; + } + if (val == NULL) + ret |= pcb_attribute_remove(&ly->Attributes, key); + else + ret |= pcb_attribute_put(&ly->Attributes, key, val); + free(key); + pcb_board_set_changed_flag(pcb, rnd_true); + } + else { + rnd_message(RND_MSG_ERROR, "Invalid EditLayer() command: %s\n", arg); + RND_ACT_FAIL(EditLayer); + } + } + + if (interactive) { + char fn[RND_ACTION_NAME_MAX]; + fgw_arg_t args[2]; + args[0].type = FGW_FUNC; + args[0].val.argv0.func = fgw_func_lookup(&rnd_fgw, rnd_aname(fn, "LayerPropGui")); + args[0].val.argv0.user_call_ctx = RND_ACT_HIDLIB; + if (args[0].val.func != NULL) { + args[1].type = FGW_LONG; + args[1].val.nat_long = pcb_layer_id(PCB->Data, ly); + ret = rnd_actionv_(args[0].val.func, res, 2, args); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERS_CHANGED, NULL); + } + else + return FGW_ERR_NOT_FOUND; + return ret; + } + + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERS_CHANGED, NULL); + RND_ACT_IRES(0); + return ret; +} + +rnd_layergrp_id_t pcb_actd_EditGroup_gid = -1; +static const char pcb_acts_EditGroup[] = "Editgroup([@group], [name=text|type=+bit|type=-bit])]\nEditlayer([@layer], attrib, key=value)"; +static const char pcb_acth_EditGroup[] = "Change a property or attribute of a layer group. If the first argument starts with @, it is taken as the group name to manipulate, else the action uses the current layer's group. Without arguments or if only a layer name is specified, interactive runs editing."; +static fgw_error_t pcb_act_EditGroup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int ret = 0, n, interactive = 1, explicit = 0; + pcb_layergrp_t *g = NULL; + + if (PCB_CURRLAYER(PCB_ACT_BOARD)->is_bound) { + rnd_message(RND_MSG_ERROR, "Can't edit bound layers yet\n"); + RND_ACT_IRES(1); + return 0; + } + + if (PCB_CURRLAYER(PCB_ACT_BOARD) != NULL) + g = pcb_get_layergrp(PCB, PCB_CURRLAYER(PCB_ACT_BOARD)->meta.real.grp); + + for(n = 1; n < argc; n++) { + const char *arg; + RND_ACT_CONVARG(n, FGW_STR, EditLayer, arg = argv[n].val.str); + if (!explicit && (*arg == '@')) { + rnd_layergrp_id_t gid; + if (arg[1] == '\0') + gid = pcb_actd_EditGroup_gid; + else + gid = pcb_layergrp_by_name(PCB, arg+1); + if (gid < 0) { + rnd_message(RND_MSG_ERROR, "Can't find layer group named %s\n", arg+1); + RND_ACT_IRES(1); + return 0; + } + g = pcb_get_layergrp(PCB, gid); + explicit = 1; + } + else if (strncmp(arg, "name=", 5) == 0) { + interactive = 0; + ret |= pcb_layergrp_rename_(g, rnd_strdup(arg+5), 1); + pcb_board_set_changed_flag(pcb, rnd_true); + } + else if (strncmp(arg, "type=", 5) == 0) { + const char *sbit = arg+5; + pcb_layer_type_t bit = pcb_layer_type_str2bit(sbit+1); + if (bit == 0) { + if (strcmp(sbit+1, "anything") == 0) bit = PCB_LYT_ANYTHING; + else if (strcmp(sbit+1, "anywhere") == 0) bit = PCB_LYT_ANYWHERE; + } + if (bit == 0) { + rnd_message(RND_MSG_ERROR, "Unknown type bit %s\n", sbit+1); + RND_ACT_IRES(1); + return 0; + } + switch(*sbit) { + case '+': g->ltype |= bit; break; + case '-': g->ltype &= ~bit; break; + } + interactive = 0; + pcb_board_set_changed_flag(pcb, rnd_true); + } + else if (strncmp(arg, "attrib", 6) == 0) { + char *key, *val; + interactive = 0; + n++; + if (n >= argc) { + rnd_message(RND_MSG_ERROR, "Need an attribute name=value\n", arg+1); + RND_ACT_IRES(1); + return 0; + } + key = rnd_strdup(arg); + val = strchr(key, '='); + if (val != NULL) { + *val = '\0'; + val++; + if (*val == '\0') + val = NULL; + } + if (val == NULL) + ret |= pcb_attribute_remove(&g->Attributes, key); + else + ret |= pcb_attribute_put(&g->Attributes, key, val); + free(key); + } + else { + rnd_message(RND_MSG_ERROR, "Invalid EditGroup() command: %s\n", arg); + RND_ACT_FAIL(EditLayer); + } + } + + if (interactive) { + char fn[RND_ACTION_NAME_MAX]; + fgw_arg_t args[2]; + args[0].type = FGW_FUNC; + args[0].val.argv0.func = fgw_func_lookup(&rnd_fgw, rnd_aname(fn, "GroupPropGui")); + args[0].val.argv0.user_call_ctx = RND_ACT_HIDLIB; + if (args[0].val.func != NULL) { + args[1].type = FGW_LONG; + args[1].val.nat_long = pcb_layergrp_id(PCB, g); + ret = rnd_actionv_(args[0].val.func, res, 2, args); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERS_CHANGED, NULL); + } + else + return FGW_ERR_NOT_FOUND; + return ret; + + } + + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERS_CHANGED, NULL); + RND_ACT_IRES(0); + return ret; +} + +static const char pcb_acts_DelGroup[] = "DelGroup([@group])"; +static const char pcb_acth_DelGroup[] = "Remove a layer group; if the first argument is not specified, the current group is removed"; +static fgw_error_t pcb_act_DelGroup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *name = NULL; + pcb_layergrp_t *g = NULL; + rnd_layergrp_id_t gid; + + if (PCB_CURRLAYER(PCB_ACT_BOARD) != NULL) + g = pcb_get_layergrp(PCB, PCB_CURRLAYER(PCB_ACT_BOARD)->meta.real.grp); + + RND_ACT_MAY_CONVARG(1, FGW_STR, DelGroup, name = argv[1].val.str); + if (*name == '@') { + gid = pcb_actd_EditGroup_gid; + if (name[1] != '\0') + gid = pcb_layergrp_by_name(PCB, name+1); + if (gid < 0) { + rnd_message(RND_MSG_ERROR, "Can't find layer group named %s\n", name+1); + RND_ACT_IRES(1); + return 0; + } + } + else { + if (g == NULL) { + rnd_message(RND_MSG_ERROR, "Can't find layer group\n"); + RND_ACT_IRES(1); + return 0; + } + gid = pcb_layergrp_id(PCB, g); + } + + RND_ACT_IRES(pcb_layergrp_del(PCB, gid, 1, 1)); + return 0; +} + +static const char pcb_acts_NewGroup[] = "NewGroup(type [,location [, purpose[, auto|sub [,name[,grp_attribs[,unique|first|last]]]]])"; +static const char pcb_acth_NewGroup[] = "Create a new layer group with a single, positive drawn layer in it"; +static fgw_error_t pcb_act_NewGroup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *stype = NULL, *sloc = NULL, *spurp = NULL, *scomb = NULL, *name = NULL, *attr = NULL, *show = NULL; + pcb_layergrp_t *g = NULL; + pcb_layer_type_t ltype = 0, lloc = 0; + int unique = 0, first = 0, last = 0; + + RND_ACT_CONVARG(1, FGW_STR, NewGroup, stype = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, NewGroup, sloc = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, NewGroup, spurp = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, NewGroup, scomb = argv[4].val.str); + RND_ACT_MAY_CONVARG(5, FGW_STR, NewGroup, name = argv[5].val.str); + RND_ACT_MAY_CONVARG(6, FGW_STR, NewGroup, attr = argv[6].val.str); + RND_ACT_MAY_CONVARG(7, FGW_STR, NewGroup, show = argv[7].val.str); + + if (show != NULL) { + if (strstr(show, "unique") != NULL) unique = 1; + if (strstr(show, "first") != NULL) first = 1; + if (strstr(show, "last") != NULL) last = 1; + } + + ltype = pcb_layer_type_str2bit(stype) & PCB_LYT_ANYTHING; + if (ltype == 0) { + rnd_message(RND_MSG_ERROR, "Invalid type: '%s'\n", sloc); + RND_ACT_IRES(-1); + return 0; + } + + if ((ltype == PCB_LYT_COPPER) || (ltype == PCB_LYT_SUBSTRATE)) { + rnd_message(RND_MSG_ERROR, "Can not create this type of layer group: '%s'\n", sloc); + RND_ACT_IRES(-1); + return 0; + } + + if (sloc != NULL) { + if (strcmp(sloc, "global") != 0) { + lloc = pcb_layer_type_str2bit(sloc) & PCB_LYT_ANYWHERE; + if (lloc == 0) { + rnd_message(RND_MSG_ERROR, "Invalid location: '%s'\n", sloc); + RND_ACT_IRES(-1); + return 0; + } + } + } + + /* empty purpose string is the same as unspecified */ + if ((spurp != NULL) && (spurp[0] == '\0')) + spurp = NULL; + + if (unique) { + int found; + rnd_layergrp_id_t gid; + if (spurp != NULL) + found = pcb_layergrp_listp(pcb, ltype|lloc, &gid, 1, -1, spurp); + else + found = pcb_layergrp_list(pcb, ltype|lloc, &gid, 1); + + if (found) { /* do not create existing */ + RND_ACT_IRES(-1); + return 0; + } + } + + pcb_layergrp_inhibit_inc(); + + if (first) + g = pcb_get_grp_new_raw(pcb, 1); + else if (last) + g = pcb_get_grp_new_raw(pcb, 0); + else + g = pcb_get_grp_new_misc(pcb); + + if (g != NULL) { + rnd_layer_id_t lid; + + if (spurp != NULL) + pcb_layergrp_set_purpose__(g, rnd_strdup(spurp), 1); + + free(g->name); + if (name != NULL) + g->name = rnd_strdup(name); + else + g->name = rnd_strdup_printf("%s%s%s", sloc == NULL ? "" : sloc, sloc == NULL ? "" : "-", stype); + g->ltype = ltype | lloc; + g->vis = 1; + g->open = 1; + + pcb_undo_freeze_serial(); + pcb_layergrp_undoable_created(g); + + if (attr != NULL) { + char *attrs = rnd_strdup(attr), *curr, *next, *val; + for(curr = attrs; curr != NULL; curr = next) { + next = strchr(curr, ';'); + if (next != NULL) { + *next = '\0'; + next++; + } + while(isspace(*curr)) curr++; + val = strchr(curr, '='); + if (val != NULL) { + *val = '\0'; + val++; + } + else + val = ""; + pcb_attribute_put(&g->Attributes, curr, val); + } + free(attrs); + } + + lid = pcb_layer_create(PCB, g - PCB->LayerGroups.grp, stype, 1); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + if (lid >= 0) { + pcb_layer_t *ly; + RND_ACT_IRES(0); + ly = &PCB->Data->Layer[lid]; + ly->meta.real.vis = 1; + if (scomb != NULL) { + if (strstr(scomb, "auto") != NULL) ly->comb |= PCB_LYC_AUTO; + if (strstr(scomb, "sub") != NULL) ly->comb |= PCB_LYC_SUB; + } + if (name != NULL) { + free((char *)ly->name); + ly->name = rnd_strdup(name); + } + } + else + RND_ACT_IRES(-1); + + } + else + RND_ACT_IRES(-1); + pcb_layergrp_inhibit_dec(); + + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERS_CHANGED, NULL); + if ((rnd_gui != NULL) && (rnd_exporter == NULL)) + rnd_gui->invalidate_all(rnd_gui); + + return 0; +} + +static const char pcb_acts_DupGroup[] = "DupGroup([@group])"; +static const char pcb_acth_DupGroup[] = "Duplicate a layer group; if the first argument is not specified, the current group is duplicated"; +static fgw_error_t pcb_act_DupGroup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *name = NULL; + pcb_layergrp_t *g = NULL; + rnd_layergrp_id_t gid, ng; + + if (PCB_CURRLAYER(PCB_ACT_BOARD) != NULL) + g = pcb_get_layergrp(PCB, PCB_CURRLAYER(PCB_ACT_BOARD)->meta.real.grp); + + RND_ACT_MAY_CONVARG(1, FGW_STR, DupGroup, name = argv[1].val.str); + if (*name == '@') { + gid = pcb_actd_EditGroup_gid; + if (name[1] != '\0') + gid = pcb_layergrp_by_name(PCB, name+1); + if (gid < 0) { + rnd_message(RND_MSG_ERROR, "Can't find layer group named %s\n", name+1); + RND_ACT_IRES(1); + return 0; + } + } + else { + if (g == NULL) { + rnd_message(RND_MSG_ERROR, "Can't find layer group\n"); + RND_ACT_IRES(1); + return 0; + } + gid = pcb_layergrp_id(PCB, g); + } + + pcb_layergrp_inhibit_inc(); + pcb_undo_freeze_serial(); + ng = pcb_layergrp_dup(PCB, gid, 1, 1); + if (ng >= 0) { + rnd_layer_id_t lid = pcb_layer_create(PCB, ng, g->name, 1); + if (lid >= 0) { + RND_ACT_IRES(0); + PCB->Data->Layer[lid].meta.real.vis = 1; + } + else + RND_ACT_IRES(-1); + } + else + RND_ACT_IRES(-1); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + pcb_layergrp_inhibit_dec(); + + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERS_CHANGED, NULL); + if ((rnd_gui != NULL) && (rnd_exporter == NULL)) + rnd_gui->invalidate_all(rnd_gui); + return 0; +} + +const char pcb_acts_selectlayer[] = "SelectLayer(1..MAXLAYER|Silk|Rats)"; +const char pcb_acth_selectlayer[] = "Select which layer is the current layer."; +/* DOC: selectlayer.html */ +static fgw_error_t pcb_act_SelectLayer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_layer_id_t lid; + const pcb_menu_layers_t *ml; + char *name; + + RND_ACT_IRES(0); + RND_ACT_CONVARG(1, FGW_STR, selectlayer, name = argv[1].val.str); + + if (rnd_strcasecmp(name, "silk") == 0) { + PCB->RatDraw = 0; + if (pcb_layer_list(PCB, PCB_LYT_VISIBLE_SIDE() | PCB_LYT_SILK, &lid, 1) > 0) { + pcb_layervis_change_group_vis(RND_ACT_HIDLIB, lid, 1, 1); + } + else { + rnd_message(RND_MSG_ERROR, "Can't find this-side silk layer\n"); + RND_ACT_IRES(-1); + } + return 0; + } + + ml = pcb_menu_layer_find(name); + if (ml != NULL) { + rnd_bool *v = (rnd_bool *)((char *)PCB + ml->vis_offs); + rnd_bool *s = (rnd_bool *)((char *)PCB + ml->sel_offs); + if (ml->sel_offs == 0) { + rnd_message(RND_MSG_ERROR, "Virtual layer '%s' (%s) can not be selected\n", ml->name, ml->abbrev); + RND_ACT_IRES(-1); + return 0; + } + *s = *v = 1; + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERVIS_CHANGED, NULL); + return 0; + } + + PCB->RatDraw = 0; + pcb_layervis_change_group_vis(RND_ACT_HIDLIB, atoi(name)-1, 1, 1); + rnd_gui->invalidate_all(rnd_gui); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERVIS_CHANGED, NULL); + return 0; +} + +const char pcb_acts_chklayer[] = "ChkLayer(layerid)"; +const char pcb_acth_chklayer[] = "Returns 1 if the specified layer is the active layer"; +/* DOC: chklayer.html */ +static fgw_error_t pcb_act_ChkLayer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + rnd_layer_id_t lid; + pcb_layer_t *ly; + char *end; + const char *name; + const pcb_menu_layers_t *ml; + + RND_ACT_CONVARG(1, FGW_STR, chklayer, name = argv[1].val.str); + + lid = strtol(name, &end, 10); + if (*end != '\0') { + ml = pcb_menu_layer_find(name); + if (ml != NULL) { + if (ml->sel_offs != 0) { + rnd_bool *s = (rnd_bool *)((char *)pcb + ml->sel_offs); + RND_ACT_IRES(*s); + } + else + RND_ACT_IRES(-1); + return 0; + } + rnd_message(RND_MSG_ERROR, "pcb_act_ChkLayer: '%s' is not a valid layer ID - check your menu file!\n", argv[0]); + RND_ACT_IRES(-1); + return 0; + } + + /* if any virtual is selected, do not accept PCB_CURRLAYER(PCB_ACT_BOARD) as selected */ + for(ml = pcb_menu_layers; ml->name != NULL; ml++) { + rnd_bool *s = (rnd_bool *)((char *)pcb + ml->sel_offs); + if ((ml->sel_offs != 0) && (*s)) { + RND_ACT_IRES(0); + return 0; + } + } + + lid--; + ly = pcb_get_layer(pcb->Data, lid); + if (ly == NULL) + RND_ACT_IRES(-1); + else + RND_ACT_IRES(ly == PCB_CURRLAYER(PCB_ACT_BOARD)); + return 0; +} + + +const char pcb_acts_toggleview[] = "ToggleView(1..MAXLAYER)\n" "ToggleView(layername)\n" "ToggleView(Silk|Rats|Pins|Vias|BackSide)\n" "ToggleView(All, Open|Vis, Set|Clear|Toggle)"; +const char pcb_acth_toggleview[] = "Toggle the visibility of the specified layer or layer group."; +/* DOC: toggleview.html */ +static fgw_error_t pcb_act_ToggleView(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_layer_id_t lid; + const char *name; + + RND_ACT_CONVARG(1, FGW_STR, toggleview, name = argv[1].val.str); + RND_ACT_IRES(0); + + if (rnd_strcasecmp(name, "all") == 0) { + rnd_bool_op_t open = RND_BOOL_PRESERVE, vis = RND_BOOL_PRESERVE, user = RND_BOOL_PRESERVE; + const char *cmd, *suser; + RND_ACT_CONVARG(2, FGW_STR, toggleview, cmd = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, toggleview, suser = argv[3].val.str); + + user = rnd_str2boolop(suser); + if (user == RND_BOOL_INVALID) + RND_ACT_FAIL(toggleview); + if (rnd_strcasecmp(cmd, "open") == 0) + open = user; + else if (rnd_strcasecmp(cmd, "vis") == 0) + vis = user; + else + RND_ACT_FAIL(toggleview); + pcb_layer_vis_change_all(PCB, open, vis); + rnd_gui->invalidate_all(rnd_gui); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERVIS_CHANGED, NULL); + return 0; + } + else if (rnd_strcasecmp(name, "silk") == 0) { + if (pcb_layer_list(PCB, PCB_LYT_VISIBLE_SIDE() | PCB_LYT_SILK, &lid, 1) > 0) + pcb_layervis_change_group_vis(RND_ACT_HIDLIB, lid, -1, 0); + else + rnd_message(RND_MSG_ERROR, "Can't find this-side silk layer\n"); + } + else if ((rnd_strcasecmp(name, "padstacks") == 0) || (rnd_strcasecmp(name, "vias") == 0) || (rnd_strcasecmp(name, "pins") == 0) || (rnd_strcasecmp(name, "pads") == 0)) { + PCB->pstk_on = !PCB->pstk_on; + rnd_gui->invalidate_all(rnd_gui); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERVIS_CHANGED, NULL); + } + else if (rnd_strcasecmp(name, "BackSide") == 0) { + PCB->InvisibleObjectsOn = !PCB->InvisibleObjectsOn; + rnd_gui->invalidate_all(rnd_gui); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERVIS_CHANGED, NULL); + } + else if (strncmp(name, "ui:", 3) == 0) { + pcb_layer_t *ly = pcb_uilayer_get(atoi(name+3)); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid ui layer id: '%s'\n", name); + RND_ACT_IRES(-1); + return 0; + } + ly->meta.real.vis = !ly->meta.real.vis; + rnd_gui->invalidate_all(rnd_gui); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERVIS_CHANGED, NULL); + } + else { + char *end; + int id = strtol(name, &end, 10) - 1; + if (*end == '\0') { /* integer layer */ + pcb_layervis_change_group_vis(RND_ACT_HIDLIB, id, -1, 0); + rnd_gui->invalidate_all(rnd_gui); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERVIS_CHANGED, NULL); + return 0; + } + else { /* virtual menu layer */ + const pcb_menu_layers_t *ml = pcb_menu_layer_find(name); + if (ml != NULL) { + rnd_bool *v = (rnd_bool *)((char *)PCB + ml->vis_offs); + *v = !(*v); + rnd_gui->invalidate_all(rnd_gui); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERVIS_CHANGED, NULL); + return 0; + } + rnd_message(RND_MSG_ERROR, "Invalid layer id: '%s'\n", name); + } + } + + RND_ACT_IRES(1); + return 0; +} + +const char pcb_acts_chkview[] = "ChkView(layerid)\n"; +const char pcb_acth_chkview[] = "Return 1 if layerid is visible."; +/* DOC: chkview.html */ +static fgw_error_t pcb_act_ChkView(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + rnd_layer_id_t lid; + pcb_layer_t *ly; + char *end; + const char *name; + + RND_ACT_CONVARG(1, FGW_STR, chkview, name = argv[1].val.str); + + if (strncmp(name, "ui:", 3) == 0) { + pcb_layer_t *ly = pcb_uilayer_get(atoi(name+3)); + if (ly == NULL) { + RND_ACT_IRES(-1); + return 0; + } + RND_ACT_IRES(ly->meta.real.vis); + return 0; + } + + lid = strtol(name, &end, 10); + + if (*end != '\0') { + const pcb_menu_layers_t *ml = pcb_menu_layer_find(name); + + if (ml != NULL) { + rnd_bool *v = (rnd_bool *)((char *)pcb + ml->vis_offs); + RND_ACT_IRES(*v); + return 0; + } + + rnd_message(RND_MSG_ERROR, "pcb_act_ChkView: '%s' is not a valid layer ID - check your menu file!\n", name); + return FGW_ERR_ARGV_TYPE; + } + + lid--; + ly = pcb_get_layer(pcb->Data, lid); + if (ly == NULL) { + RND_ACT_IRES(-1); + return 0; + } + + RND_ACT_IRES(ly->meta.real.vis); + return 0; +} + + +static int layer_get_curr_pos(pcb_board_t *pcb, rnd_layer_id_t *lidout, rnd_layergrp_id_t *gid, pcb_layergrp_t **grp, int *glidx) +{ + pcb_layergrp_t *g; + rnd_layer_id_t lid; + int n; + + lid = PCB_CURRLID(pcb); + if (lid == -1) + return -1; + + *gid = pcb_layer_get_group(pcb, lid); + g = pcb_get_layergrp(pcb, *gid); + if (g == NULL) + return -1; + + for(n = 0; n < g->len; n++) { + if (g->lid[n] == lid) { + *lidout = lid; + *glidx = n; + *grp = g; + return 0; + } + } + + return -1; +} + +static int layer_select_delta(pcb_board_t *pcb, int d) +{ + pcb_layergrp_t *g; + rnd_layer_id_t lid; + rnd_layergrp_id_t gid; + int glidx; + + if (layer_get_curr_pos(pcb, &lid, &gid, &g, &glidx) < 0) + return -1; + + if (d > 0) { + while(d > 0) { + glidx++; + while(glidx >= g->len) { + gid++; + g = pcb_get_layergrp(pcb, gid); + if (g == NULL) + return -1; + glidx = 0; + } + lid = g->lid[glidx]; + d--; + } + } + else if (d < 0) { + while(d < 0) { + glidx--; + while(glidx < 0) { + gid--; + g = pcb_get_layergrp(pcb, gid); + if (g == NULL) + return -1; + glidx = g->len-1; + } + lid = g->lid[glidx]; + d++; + } + } + else + return 0; /* 0 means: stay where we are */ + + pcb->RatDraw = 0; + pcb_layervis_change_group_vis(&pcb->hidlib, lid, 1, 1); + rnd_gui->invalidate_all(rnd_gui); + rnd_event(&pcb->hidlib, PCB_EVENT_LAYERVIS_CHANGED, NULL); + + return 0; +} + +static const char pcb_acts_LayerByStack[] = "LayerByStack(select, prev|next)"; +static const char pcb_acth_LayerByStack[] = "Layer operations based on physical layer stacking"; +/* DOC: layerbystack.html */ +static fgw_error_t pcb_act_LayerByStack(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op1, op2; + + RND_ACT_CONVARG(1, FGW_KEYWORD, LayerByStack, op1 = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_KEYWORD, LayerByStack, op2 = fgw_keyword(&argv[2])); + RND_ACT_IRES(0); + + switch(op1) { + case F_Select: + switch(op2) { + case F_Prev: RND_ACT_IRES(layer_select_delta(PCB_ACT_BOARD, -1)); return 0; + case F_Next: RND_ACT_IRES(layer_select_delta(PCB_ACT_BOARD, +1)); return 0; + } + } + + RND_ACT_FAIL(LayerByStack); + RND_ACT_IRES(1); + return 0; +} + + + +const char pcb_acts_chkrst[] = "ChkRst(route_style_id)\n"; +const char pcb_acth_chkrst[] = "Return 1 if route_style_id matches pen."; +/* DOC: chkrst.html */ +static fgw_error_t pcb_act_ChkRst(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int rid; + pcb_route_style_t *rst; + + RND_ACT_CONVARG(1, FGW_INT, chkrst, rid = argv[1].val.nat_int); + + rst = vtroutestyle_get(&PCB->RouteStyle, rid, 0); + if (rst == NULL) + RND_ACT_IRES(-1); + else + RND_ACT_IRES(pcb_route_style_match(rst, conf_core.design.line_thickness, conf_core.design.via_thickness, conf_core.design.via_drilling_hole, conf_core.design.clearance, NULL)); + return 0; +} + +static const char pcb_acts_boardflip[] = "BoardFlip([sides])"; +static const char pcb_acth_boardflip[] = "Mirror the board over the x axis, optionally mirroring sides as well."; +/* DOC: boardflip.html */ +static fgw_error_t pcb_act_boardflip(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op = -2; + rnd_bool smirror; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, boardflip, op = fgw_keyword(&argv[1])); + + smirror = (op == F_Sides); + pcb_data_mirror(PCB->Data, 0, smirror ? PCB_TXM_SIDE : PCB_TXM_COORD, smirror, 1); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_ClipInhibit[] = "ClipInhibit([on|off|check])"; +static const char pcb_acth_ClipInhibit[] = "ClipInhibit Feature Template."; +static fgw_error_t pcb_act_ClipInhibit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + static int is_on = 0; + int target; + const char *op; + char tmp[2]; + + RND_ACT_CONVARG(1, FGW_STR, ClipInhibit, op = argv[1].val.str); + + if (strcmp(op, "check") == 0) { + RND_ACT_IRES(is_on); + return 0; + } + + + if (strcmp(op, "toggle") == 0) { + target = !is_on; + } + else { + if (op[0] != 'o') + RND_ACT_FAIL(ClipInhibit); + + switch(op[1]) { + case 'n': target = 1; break; + case 'f': target = 0; break; + default: RND_ACT_FAIL(ClipInhibit); + } + } + + if (is_on == target) { + RND_ACT_IRES(0); + return 0; + } + + is_on = target; + if (is_on) + pcb_data_clip_inhibit_inc(PCB->Data); + else + pcb_data_clip_inhibit_dec(PCB->Data, 1); + + tmp[0] = '0' + !conf_core.temp.clip_inhibit_chg; + tmp[1] = '\0'; + rnd_conf_set(RND_CFR_CLI, "temp/clip_inhibit_chg", 0, tmp, RND_POL_OVERWRITE); + + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_LayerVisReset[] = "LayerVisReset()"; +static const char pcb_acth_LayerVisReset[] = "Reset layer visibility to safe defaults."; +static fgw_error_t pcb_act_LayerVisReset(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_layervis_reset_stack(RND_ACT_HIDLIB); + pcb_layer_vis_historical_hides(PCB_ACT_BOARD); + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_LAYERVIS_CHANGED, NULL); + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t gui_action_list[] = { + {"Display", pcb_act_Display, pcb_acth_Display, pcb_acts_Display}, + {"CycleDrag", pcb_act_CycleDrag, pcb_acth_CycleDrag, pcb_acts_CycleDrag}, + {"MarkCrosshair", pcb_act_MarkCrosshair, pcb_acth_MarkCrosshair, pcb_acts_MarkCrosshair}, + {"SetSame", pcb_act_SetSame, pcb_acth_SetSame, pcb_acts_SetSame}, + {"RouteStyle", pcb_act_RouteStyle, pcb_acth_RouteStyle, pcb_acts_RouteStyle}, + {"SelectLayer", pcb_act_SelectLayer, pcb_acth_selectlayer, pcb_acts_selectlayer}, + {"ChkLayer", pcb_act_ChkLayer, pcb_acth_chklayer, pcb_acts_chklayer}, + {"ToggleView", pcb_act_ToggleView, pcb_acth_toggleview, pcb_acts_toggleview}, + {"ChkView", pcb_act_ChkView, pcb_acth_chkview, pcb_acts_chkview}, + {"LayerByStack", pcb_act_LayerByStack, pcb_acth_LayerByStack, pcb_acts_LayerByStack}, + {"EditLayer", pcb_act_EditLayer, pcb_acth_EditLayer, pcb_acts_EditLayer}, + {"EditGroup", pcb_act_EditGroup, pcb_acth_EditGroup, pcb_acts_EditGroup}, + {"DelGroup", pcb_act_DelGroup, pcb_acth_DelGroup, pcb_acts_DelGroup}, + {"DupGroup", pcb_act_DupGroup, pcb_acth_DupGroup, pcb_acts_DupGroup}, + {"NewGroup", pcb_act_NewGroup, pcb_acth_NewGroup, pcb_acts_NewGroup}, + {"ChkRst", pcb_act_ChkRst, pcb_acth_chkrst, pcb_acts_chkrst}, + {"BoardFlip", pcb_act_boardflip, pcb_acth_boardflip, pcb_acts_boardflip}, + {"ClipInhibit", pcb_act_ClipInhibit, pcb_acth_ClipInhibit, pcb_acts_ClipInhibit}, + {"LayerVisReset", pcb_act_LayerVisReset, pcb_acth_LayerVisReset, pcb_acts_LayerVisReset} +}; + +void pcb_gui_act_init2(void) +{ + RND_REGISTER_ACTIONS(gui_action_list, NULL); +} Index: tags/2.3.0/src/hid_cam.c =================================================================== --- tags/2.3.0/src/hid_cam.c (nonexistent) +++ tags/2.3.0/src/hid_cam.c (revision 33253) @@ -0,0 +1,577 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2004 harry eaton + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include +#include + +#include "board.h" +#include "data.h" +#include "hid_cam.h" +#include +#include +#include "layer_addr.h" +#include "layer_vis.h" +#include "plug_io.h" +#include + +htsp_t *pcb_cam_vars = NULL; /* substitute %% variables from this hash */ + +typedef struct { + pcb_cam_t *cam; + const pcb_layergrp_t *grp; + const pcb_virt_layer_t *vl; + htsp_t *vars; +} cam_name_ctx_t; +static int cam_update_name_cb(void *ctx_, gds_t *s, const char **input); + +static void cam_gen_fn(pcb_cam_t *dst) +{ + cam_name_ctx_t ctx; + + memset(&ctx, 0, sizeof(ctx)); + ctx.cam = dst; + ctx.vars = pcb_cam_vars; + free(dst->fn); + dst->fn = rnd_strdup_subst(dst->fn_template, cam_update_name_cb, &ctx, RND_SUBST_HOME | RND_SUBST_PERCENT | RND_SUBST_CONF); +} + + +char *pcb_layer_to_file_name_append(gds_t *dest, rnd_layer_id_t lid, unsigned int flags, const char *purpose, int purpi, pcb_file_name_style_t style) +{ + const pcb_virt_layer_t *v; + rnd_layergrp_id_t group; + const char *res = NULL; + static char buf[PCB_DERIVE_FN_SUFF_LEN]; + + if (flags == 0) + flags = pcb_layer_flags(PCB, lid); + + + if (style == PCB_FNS_pcb_rnd) { + const char *sloc, *styp; + group = pcb_layer_get_group(PCB, lid); + sloc = pcb_layer_type_bit2str(flags & PCB_LYT_ANYWHERE); + styp = pcb_layer_type_bit2str(flags & (PCB_LYT_ANYTHING | PCB_LYT_VIRTUAL)); + if (sloc == NULL) sloc = "global"; + if (styp == NULL) styp = "none"; + if (purpose == NULL) purpose = "none"; + if (group < 0) { + rnd_append_printf(dest, "%s.%s.%s.none", sloc, styp, purpose); + } + else + rnd_append_printf(dest, "%s.%s.%s.%ld", sloc, styp, purpose, group); + return dest->array; + } + + if (flags & PCB_LYT_BOUNDARY) { + gds_append_str(dest, "outline"); + return dest->array; + } + + /* NOTE: long term only PCB_FNS_pcb_rnd will be supported and the rest, + below, will be removed */ + v = pcb_vlayer_get_first(flags, purpose, purpi); + if (v != NULL) { + gds_append_str(dest, v->name); + return dest->array; + } + + group = pcb_layer_get_group(PCB, lid); + + if (flags & PCB_LYT_TOP) { + if (flags & PCB_LYT_SILK) + res = "topsilk"; + else if (flags & PCB_LYT_MASK) + res = "topmask"; + else if (flags & PCB_LYT_PASTE) + res = "toppaste"; + else if (purpose != NULL) { + rnd_snprintf(buf, sizeof(buf), "top-%s", purpose); + res = buf; + } + else + res = "top"; + } + else if (flags & PCB_LYT_BOTTOM) { + if (flags & PCB_LYT_SILK) + res = "bottomsilk"; + else if (flags & PCB_LYT_MASK) + res = "bottommask"; + else if (flags & PCB_LYT_PASTE) + res = "bottompaste"; + else if (purpose != NULL) { + rnd_snprintf(buf, sizeof(buf), "bottom-%s", purpose); + res = buf; + } + else + res = "bottom"; + } + else { + static char buf[PCB_DERIVE_FN_SUFF_LEN]; + sprintf(buf, "group%ld", group); + res = buf; + } + + assert(res != NULL); + gds_append_str(dest, res); + return dest->array; +} + +char *pcb_layer_to_file_name(gds_t *dest, rnd_layer_id_t lid, unsigned int flags, const char *purpose, int purpi, pcb_file_name_style_t style) +{ + dest->used = 0; + return pcb_layer_to_file_name_append(dest, lid, flags, purpose, purpi, style); +} + + +char *pcb_derive_default_filename_(const char *pcbfile, const char *suffix) +{ + char *buf; + const char *pf; + + if (pcbfile == NULL) + pf = "unknown.pcb"; + else + pf = pcbfile; + + buf = (char *) malloc(strlen(pf) + strlen(suffix) + 1); + if (buf) { + size_t bl; + pcb_plug_io_t *i; + strcpy(buf, pf); + bl = strlen(buf); + for(i = pcb_plug_io_chain; i != NULL; i = i->next) { + if (i->default_extension != NULL) { + int slen = strlen(i->default_extension); + if (bl > slen && strcmp(buf + bl - slen, i->default_extension) == 0) { + buf[bl - slen] = 0; + break; + } + } + } + strcat(buf, suffix); + } + + return buf; +} + +void pcb_derive_default_filename(const char *pcbfile, rnd_export_opt_t *filename_attrib, const char *suffix) +{ + if (filename_attrib->default_val.str) + free((char *)filename_attrib->default_val.str); + filename_attrib->default_val.str = pcb_derive_default_filename_(pcbfile, suffix); +} + +static void layervis_save_and_reset(pcb_cam_t *cam) +{ + rnd_layer_id_t n; + for(n = 0; n < cam->pcb->Data->LayerN; n++) { + cam->orig_vis[n] = cam->pcb->Data->Layer[n].meta.real.vis; + cam->pcb->Data->Layer[n].meta.real.vis = 0; + } +} + +static void layervis_restore(pcb_cam_t *cam) +{ + rnd_layer_id_t n; + for(n = 0; n < cam->pcb->Data->LayerN; n++) + cam->pcb->Data->Layer[n].meta.real.vis = cam->orig_vis[n]; +} + +static void cam_xform_init(rnd_xform_t *dst_xform) +{ + memset(dst_xform, 0, sizeof(rnd_xform_t)); + dst_xform->omit_overlay = 1; /* normally exporters shouldn't draw overlays */ +} + + +static void read_out_params(pcb_cam_t *dst, char **str) +{ + char *curr, *next; + + if (*str == NULL) + return; + if (**str == '=') { + **str = '\0'; + (*str)++; + } + if (**str != '[') + return; + + for(curr = (*str)+1; curr != NULL; curr = next) { + next = strpbrk(curr, ",]"); + if (next != NULL) { + if (*next == ']') { + *next = '\0'; + next++; + while(isspace(*next)) next++; + *str = next; + next = NULL; + } + else { + *next = '\0'; + next++; + } + if (strcmp(curr, "okempty") == 0) { + dst->okempty_group = 1; + dst->okempty_content = 1; + } + else if (strcmp(curr, "okempty-group") == 0) + dst->okempty_group = 1; + else if (strcmp(curr, "okempty-content") == 0) + dst->okempty_content = 1; + else + rnd_message(RND_MSG_ERROR, "CAM: ignoring unknown global parameter [%s]\n", curr); + } + else + *str = NULL; + } +} + +int pcb_cam_begin(pcb_board_t *pcb, pcb_cam_t *dst, rnd_xform_t *dst_xform, const char *src, const rnd_export_opt_t *attr_tbl, int numa, rnd_hid_attr_val_t *options) +{ + char *curr, *next; + + memset(dst, 0, sizeof(pcb_cam_t)); + + if (dst_xform != NULL) + cam_xform_init(dst_xform); + + if ((src == NULL) || (*src == '\0')) + return 0; + + dst->pcb = pcb; + dst->inst = rnd_strdup(src); + layervis_save_and_reset(dst); + + + /* Syntax: fn=[out_params]layergrp,layergrp(opt=val,opt=val),layergrp */ + /* parse: get file name name */ + next = strchr(dst->inst, '='); + if (next == NULL) { + rnd_message(RND_MSG_ERROR, "CAM rule missing '='\n"); + goto err; + } + read_out_params(dst, &next); + dst->fn = rnd_str_strip(dst->inst); + + if (strchr(dst->fn, '%') != NULL) { + dst->fn_template = dst->fn; + dst->fn = NULL; + cam_gen_fn(dst); + } + + while(isspace(*next)) + next++; + + /* parse layers */ + for(curr = next; curr != NULL; curr = next) { + rnd_layergrp_id_t gids[PCB_MAX_LAYERGRP]; + rnd_xform_t *xf = NULL, xf_; + int numg, vid; + char *spk[64], *spv[64]; + int spc = sizeof(spk) / sizeof(spk[0]); + + next = pcb_parse_layergrp_address(curr, spk, spv, &spc); + if (next == pcb_parse_layergrp_err) { + rnd_message(RND_MSG_ERROR, "CAM rule: invalid layer transformation\n"); + goto err; + } + + curr = rnd_str_strip(curr); + numg = pcb_layergrp_list_by_addr(pcb, curr, gids, spk, spv, spc, &vid, &xf, &xf_, "CAM rule: "); + if (numg < 0) + goto err; + else if (numg >= 1) { + int n; + for(n = 0; n < numg; n++) { + rnd_layergrp_id_t gid = gids[n]; + pcb_layervis_change_group_vis(&pcb->hidlib, pcb->LayerGroups.grp[gid].lid[0], 1, 0); + dst->grp_vis[gid] = 1; + if (xf != NULL) { + dst->xform[gid] = &dst->xform_[gid]; + memcpy(&dst->xform_[gid], &xf_, sizeof(rnd_xform_t)); + } + } + } + else if (vid >= 0) { + dst->vgrp_vis[vid] = 1; + if (xf != NULL) { + dst->vxform[vid] = &dst->vxform_[vid]; + memcpy(&dst->vxform_[vid], &xf_, sizeof(rnd_xform_t)); + } + } + } + + dst->active = 1; + return 0; + err:; + layervis_restore(dst); + free(dst->inst); + dst->inst = NULL; + return -1; +} + +int pcb_cam_end(pcb_cam_t *dst) +{ + free(dst->inst); + if (dst->fn_template != NULL) { + free(dst->fn); + free(dst->fn_last); + } + dst->inst = NULL; + if (!dst->active) + return -1; + layervis_restore(dst); + dst->active = 0; + return dst->exported_grps; +} + + +void pcb_cam_begin_nolayer(pcb_board_t *pcb, pcb_cam_t *dst, rnd_xform_t *dst_xform, const char *src, const char **fn_out) +{ + char *eq; + + memset(dst, 0, sizeof(pcb_cam_t)); + dst->pcb = pcb; + + if (dst_xform != NULL) + cam_xform_init(dst_xform); + + if (src != NULL) { + eq = strchr(src, '='); + if (eq != NULL) { + char *start; + read_out_params(dst, &eq); + start = strchr(src, '('); + if ((start != eq) || (start == NULL)) { + rnd_message(RND_MSG_ERROR, "global exporter --cam doesn't take layers, only a file name and optionally global supplements\n"); + } + if (start != NULL) { /* parse supplements for global xform */ + char *tmp; + char *spk[64], *spv[64], *end, *purpose = NULL; + int spc = sizeof(spk) / sizeof(spk[0]); + rnd_xform_t *dummy; + + tmp = rnd_strdup(start); + end = pcb_parse_layergrp_address(start, spk, spv, &spc); + if ((end != NULL) && (*end != '\0')) + rnd_message(RND_MSG_ERROR, "global exporter --cam takes only one set of global supplements\n"); + pcb_parse_layer_supplements(spk, spv, spc, &purpose, &dummy, dst_xform); + if (purpose != NULL) + rnd_message(RND_MSG_ERROR, "global exporter --cam ignores layer purpose\n"); + free(tmp); + } + } + + + dst->fn_template = rnd_strdup(src); + eq = strchr(dst->fn_template, '='); + if (eq != NULL) + *eq = '\0'; + + cam_gen_fn(dst); + *fn_out = dst->fn; + /* note: dst->active is not set so that layer selection is not altered */ + } +} + + + +/* convert string to integer, step input beyond the terminating % */ +static int get_tune(const char **input) +{ + char *end; + int res; + + if (**input == '%') { + (*input)++; + return 0; + } + res = atoi(*input); + end = strchr(*input, '%'); + *input = end+1; + return res; +} + +static int cam_update_name_cb(void *ctx_, gds_t *s, const char **input) +{ + cam_name_ctx_t *ctx = ctx_; + if (strncmp(*input, "name%", 5) == 0) { + (*input) += 5; + if (ctx->grp != NULL) { + if (ctx->grp->name != NULL) + gds_append_str(s, ctx->grp->name); + } + else if (ctx->vl != NULL) + gds_append_str(s, ctx->vl->name); + } + else if (strncmp(*input, "top_offs", 8) == 0) { + int tune, from_top = -1; + pcb_layergrp_t *tcop = pcb_get_grp(&PCB->LayerGroups, PCB_LYT_TOP, PCB_LYT_COPPER); + rnd_layergrp_id_t tcop_id = pcb_layergrp_id(PCB, tcop); + + (*input) += 8; + tune = get_tune(input); + + pcb_layergrp_dist(PCB, pcb_layergrp_id(PCB, ctx->grp), tcop_id, PCB_LYT_COPPER, &from_top); + rnd_append_printf(s, "%d", from_top+tune); + } + else if (strncmp(*input, "bot_offs", 8) == 0) { + int tune, from_bot = -1; + pcb_layergrp_t *bcop = pcb_get_grp(&PCB->LayerGroups, PCB_LYT_BOTTOM, PCB_LYT_COPPER); + rnd_layergrp_id_t bcop_id = pcb_layergrp_id(PCB, bcop); + + (*input) += 8; + tune = get_tune(input); + + pcb_layergrp_dist(PCB, pcb_layergrp_id(PCB, ctx->grp), bcop_id, PCB_LYT_COPPER, &from_bot); + rnd_append_printf(s, "%d", from_bot+tune); + } + else { + char *end = strchr(*input, '%'); + char varname[128]; + int len; + + if (end == NULL) { + gds_append_str(s, *input); + return 0; + } + + if (ctx->vars != NULL) { + len = end - *input; + if (len < sizeof(varname)-1) { + const char *val; + strncpy(varname, *input, len); + varname[len] = 0; + val = htsp_get(ctx->vars, varname); + if (val != NULL) + gds_append_str(s, val); + } + else + rnd_message(RND_MSG_ERROR, "cam job error: %%%% variable name too long at: '%%%s' - did not substitute\n", *input); + } + + *input = end+1; + } + + return 0; +} + +static int cam_update_name(pcb_cam_t *cam, rnd_layergrp_id_t gid, const pcb_virt_layer_t *vl) +{ + cam_name_ctx_t ctx; + if (cam->fn_template == NULL) + return 0; /* not templated */ + + free(cam->fn); + ctx.cam = cam; + ctx.grp = pcb_get_layergrp(cam->pcb, gid); + ctx.vl = vl; + ctx.vars = pcb_cam_vars; + cam->fn = rnd_strdup_subst(cam->fn_template, cam_update_name_cb, &ctx, RND_SUBST_HOME | RND_SUBST_PERCENT | RND_SUBST_CONF); + if ((cam->fn_last == NULL) || (strcmp(cam->fn, cam->fn_last) != 0)) { + cam->fn_changed = 1; + free(cam->fn_last); + cam->fn_last = rnd_strdup(cam->fn); + } + else + cam->fn_changed = 0; + return 0; +} + +int pcb_cam_set_layer_group_(pcb_cam_t *cam, rnd_layergrp_id_t group, const char *purpose, int purpi, unsigned int flags, rnd_xform_t **xform) +{ + const pcb_virt_layer_t *vl; + + if (!cam->active) + return 0; + + vl = pcb_vlayer_get_first(flags, purpose, purpi); + if (vl == NULL) { + if (group == -1) + return 1; + + if (!cam->grp_vis[group]) + return 1; + + if (cam->xform[group] != NULL) + *xform = cam->xform[group]; + } + else { + int vid = vl->new_id - PCB_LYT_VIRTUAL - 1; + if (!cam->vgrp_vis[vid]) + return 1; + + if (cam->vxform[vid] != NULL) + *xform = cam->vxform[vid]; + } + + cam->exported_grps++; + return cam_update_name(cam, group, NULL);; +} + + +void *pcb_cam_vars_alloc(void) +{ + return htsp_alloc(strhash, strkeyeq); +} + +void pcb_cam_vars_free(void *ctx) +{ + htsp_t *vars = ctx; + htsp_entry_t *e; + + for(e = htsp_first(vars); e != NULL; e = htsp_next(vars, e)) { + free(e->key); + free(e->value); + } + htsp_free(vars); +} + +void *pcb_cam_vars_use(void *new_vars) +{ + void *old = pcb_cam_vars; + pcb_cam_vars = new_vars; + return old; +} + +void pcb_cam_set_var(void *ctx, char *key, char *val) +{ + htsp_t *vars = ctx; + htsp_entry_t *e = htsp_popentry(vars, key); + if (e != NULL) { + free(e->key); + free(e->value); + } + htsp_set(vars, key, val); +} Index: tags/2.3.0/src/hid_cam.h =================================================================== --- tags/2.3.0/src/hid_cam.h (nonexistent) +++ tags/2.3.0/src/hid_cam.h (revision 33253) @@ -0,0 +1,98 @@ +#ifndef PCB_HID_HELPER_H +#define PCB_HID_HELPER_H + +#include "layer.h" +#include +#include + +/*** CAM plugin side API ***/ +typedef struct pcb_cam_s { + /* public */ + char *fn; + rnd_bool fn_changed; /* true if last call changed the ->fn field */ + rnd_bool active; + int grp_vis[PCB_MAX_LAYERGRP]; /* whether a real layer group should be rendered */ + int vgrp_vis[PCB_VLY_end]; /* whether a virtual layer group should be rendered */ + + rnd_xform_t *xform[PCB_MAX_LAYERGRP]; + rnd_xform_t xform_[PCB_MAX_LAYERGRP]; + rnd_xform_t *vxform[PCB_VLY_end]; + rnd_xform_t vxform_[PCB_VLY_end]; + + unsigned int okempty_content:1; /* do not warn if no objects exported (but group exists) */ + unsigned int okempty_group:1; /* do not warn if no group exported */ + + /* private/internal/cache */ + const char *fn_template; + char *fn_last; + char *inst; + pcb_board_t *pcb; + int orig_vis[PCB_MAX_LAYER]; /* backup of the original layer visibility */ + int exported_grps; +} pcb_cam_t; + +int pcb_cam_begin(pcb_board_t *pcb, pcb_cam_t *dst, rnd_xform_t *dst_xform, const char *src, const rnd_export_opt_t *attr_tbl, int numa, rnd_hid_attr_val_t *options); + +/* Finish cam export, free all memory, mark cam export inactive and report + the number of layer groups exported */ +int pcb_cam_end(pcb_cam_t *dst); + +/* load *fn_out with the cam-requested output file name in cam mode; useful + for non layer based exporters */ +void pcb_cam_begin_nolayer(pcb_board_t *pcb, pcb_cam_t *dst, rnd_xform_t *dst_xform, const char *src, const char **fn_out); + + +/* Shall be the first rule in a cam capable exporter's set_layer_group() + callback: decides not to draw a layer group in cam mode if the + group is not scheduled for export */ +#define pcb_cam_set_layer_group(cam, group, purpose, purpi, flags, xform) \ +do { \ + if (pcb_cam_set_layer_group_(cam, group, purpose, purpi, flags, xform)) \ + return 0; \ +} while(0) + +/* the logics behind pcb_cam_set_layer_group(); returns non-zero if the macro + should return (and skip the current group) */ +int pcb_cam_set_layer_group_(pcb_cam_t *cam, rnd_layergrp_id_t group, const char *purpose, int purpi, unsigned int flags, rnd_xform_t **xform); + +/*** CAM caller side API for global export ***/ + +/* Allocate or free a var context, in which pcb_cam_set_var() operates and + which then can be 'used' for exporting. */ +void *pcb_cam_vars_alloc(void); +void pcb_cam_vars_free(void *ctx); + +/* Use new_vars for the next export; returns the old var context that the + caller needs to restore (with another call to this function) after the export. */ +void *pcb_cam_vars_use(void *new_vars); + +/* Overwrite a CAM variable in the currently active context; both key + and val must be strdup'd on caller side (they are free'd by the CAM code) */ +void pcb_cam_set_var(void *ctx, char *key, char *val); + + +/*** Obsolete file suffix API - new plugins should not use this ***/ +/* maximum size of a derived suffix */ +#define PCB_DERIVE_FN_SUFF_LEN 20 + +typedef enum pcb_file_name_style_e { + /* The only style that will be available long term: native */ + PCB_FNS_pcb_rnd, + /* Files for copper layers are named top, groupN, bottom, used by some exporters like ps and gcode */ + PCB_FNS_fixed +} pcb_file_name_style_t; + +/* Returns a filename base that can be used to output the layer. The file + name is built in dest, the returned pointer is pointing to the array of dest. */ +char *pcb_layer_to_file_name(gds_t *dest, rnd_layer_id_t lid, unsigned int flags, const char *purpose, int purpi, pcb_file_name_style_t style); +char *pcb_layer_to_file_name_append(gds_t *dest, rnd_layer_id_t lid, unsigned int flags, const char *purpose, int purpi, pcb_file_name_style_t style); + +/* Returns a filename base that can be used to output the layer; if flags is 0, + look it up. Copies result in dest (which should be at least PCB_DERIVE_FN_SUFF_LEN bytes wide). */ +void pcb_derive_default_filename(const char *pcbfile, rnd_export_opt_t *filename_attrib, const char *suffix); + +/* Same as pcb_derive_default_filename() but returns an allocated string + directly, instead of manipulating an attribute */ +char *pcb_derive_default_filename_(const char *pcbfile, const char *suffix); + +#endif Index: tags/2.3.0/src/hidlib_pcb.c =================================================================== --- tags/2.3.0/src/hidlib_pcb.c (nonexistent) +++ tags/2.3.0/src/hidlib_pcb.c (revision 33253) @@ -0,0 +1,33 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "board.h" +#include + +void rnd_hidlib_adjust_attached_objects(rnd_hidlib_t *hl) +{ + rnd_tool_adjust_attached(hl); +} Index: tags/2.3.0/src/ht_subc.c =================================================================== --- tags/2.3.0/src/ht_subc.c (nonexistent) +++ tags/2.3.0/src/ht_subc.c (revision 33253) @@ -0,0 +1,9 @@ +#include +#include "config.h" +#include "obj_subc_list.h" + +#define HT(x) htscp_ ## x +#include +#undef HT + + Index: tags/2.3.0/src/ht_subc.h =================================================================== --- tags/2.3.0/src/ht_subc.h (nonexistent) +++ tags/2.3.0/src/ht_subc.h (revision 33253) @@ -0,0 +1,13 @@ +#ifndef PCB_HT_SUBC_H +#define PCB_HT_SUBC_H + +/* Hash: subcircuit -> pointer */ + +/* hash instance */ +typedef pcb_subc_t *htscp_key_t; +typedef void * htscp_value_t; +#define HT(x) htscp_ ## x +#include +#undef HT + +#endif Index: tags/2.3.0/src/idpath.c =================================================================== --- tags/2.3.0/src/idpath.c (nonexistent) +++ tags/2.3.0/src/idpath.c (revision 33253) @@ -0,0 +1,259 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#define TDL_DONT_UNDEF +#include "idpath.h" +#include +#undef TDL_DONT_UNDEF +#include + +#include + +#include "board.h" +#include "data.h" +#include "layer.h" +#include + +static int idpath_map(pcb_idpath_t *idp, pcb_any_obj_t *obj, int level, int *numlevels) +{ + pcb_data_t *data; + int n; + + if (numlevels != 0) + (*numlevels)++; + + if (idp != NULL) { + if (level < 0) + return -1; + idp->id[level] = obj->ID; + } + + switch(obj->parent_type) { + case PCB_PARENT_INVALID: + case PCB_PARENT_UI: + case PCB_PARENT_SUBC: + case PCB_PARENT_BOARD: + case PCB_PARENT_NET: + return -1; + case PCB_PARENT_LAYER: + assert(obj->parent.layer->parent_type = PCB_PARENT_DATA); + data = obj->parent.layer->parent.data; + goto recurse; + + case PCB_PARENT_DATA: + data = obj->parent.data; + recurse:; + switch(data->parent_type) { + case PCB_PARENT_UI: + case PCB_PARENT_LAYER: + case PCB_PARENT_DATA: + case PCB_PARENT_NET: + return -1; + case PCB_PARENT_BOARD: + if (idp == NULL) + return 0; + if (data == PCB->Data) { + idp->data_addr = 1; + return 0; + } + case PCB_PARENT_INVALID: + if (idp == NULL) + return 0; + for(n = 0; n < PCB_MAX_BUFFER; n++) { + if (data == pcb_buffers[n].Data) { + idp->data_addr = n+2; + return 0; + } + } + /* not the board, not any buffer -> unknown */ + return 0; + case PCB_PARENT_SUBC: /* recurse */ + return idpath_map(idp, (pcb_any_obj_t *)data->parent.subc, level-1, numlevels); + } + break; + } + return -1; +} + +pcb_idpath_t *pcb_idpath_alloc(int len) +{ + pcb_idpath_t *idp; + idp = calloc(1, sizeof(pcb_idpath_t) + (sizeof(long int) * (len-1))); + idp->len = len; + return idp; +} + +pcb_idpath_t *pcb_obj2idpath(pcb_any_obj_t *obj) +{ + pcb_idpath_t *idp; + int len = 0; + + /* determine the length first */ + if (idpath_map(NULL, obj, 0, &len) != 0) + return NULL; + + idp = pcb_idpath_alloc(len); + if (idpath_map(idp, obj, len-1, NULL) != 0) { + free(idp); + return NULL; + } + + return idp; +} + +pcb_idpath_t *pcb_str2idpath(pcb_board_t *pcb, const char *str) +{ + const char *s, *ps; + char *next; + int data_addr, n, len = 1; + pcb_idpath_t *idp; + + for(ps = str; *ps == '/'; ps++) ; + + data_addr = pcb_data_addr_by_name(pcb, &ps); + + for(s = ps; *s != '\0'; s++) { + if ((s[0] == '/') && (s[1] != '/') && (s[1] != '\0')) + len++; + else if ((!isdigit(*s)) && (*s != '/')) { + rnd_trace("bad idpath: '%s' in '%s'\n", s, ps); + return NULL; + } + } + + idp = pcb_idpath_alloc(len); + idp->data_addr = data_addr; + + for(s = ps, n = 0; *s != '\0'; s++,n++) { + while(*s == '/') s++; + if (*s == '\0') + break; + idp->id[n] = strtol(s, &next, 10); + s = (const char *)next; + if (*s == '\0') + break; + } + return idp; +} + + +void pcb_append_idpath(gds_t *dst, const pcb_idpath_t *idp, rnd_bool relative) +{ + int n; + + if (!relative) { + size_t end = dst->used; + gds_enlarge(dst, dst->used + 32); + dst->used = end; + pcb_data_name_by_addr(idp->data_addr, dst->array+end); + dst->used += strlen(dst->array+end); + } + + for(n = 0; n < idp->len; n++) + rnd_append_printf(dst, "/%ld", idp->id[n]); +} + +char *pcb_idpath2str(const pcb_idpath_t *idp, rnd_bool relative) +{ + gds_t tmp; + + gds_init(&tmp); + gds_enlarge(&tmp, 32); + tmp.used = 0; + pcb_append_idpath(&tmp, idp, relative); + return tmp.array; +} + + +static pcb_any_obj_t *idpath2obj(pcb_data_t *data, const pcb_idpath_t *path, int level) +{ + + for(;;) { + pcb_any_obj_t *obj = htip_get(&data->id2obj, path->id[level]); + pcb_subc_t *sc = (pcb_subc_t *)obj; + + if (obj == NULL) + return NULL; + + level++; + if (level == path->len) + return obj; + + if (obj->type != PCB_OBJ_SUBC) /* can descend only in subcircuits */ + return NULL; + + data = sc->data; + } +} + +pcb_any_obj_t *pcb_idpath2obj_in(pcb_data_t *data, const pcb_idpath_t *path) +{ + return idpath2obj(data, path, 0); +} + +pcb_any_obj_t *pcb_idpath2obj(pcb_board_t *pcb, const pcb_idpath_t *path) +{ + pcb_data_t *data; + if (path->data_addr == 1) { + if (pcb == NULL) + return NULL; + data = pcb->Data; + } + else if ((path->data_addr >= 2) && (path->data_addr < PCB_MAX_BUFFER+2)) + data = pcb_buffers[path->data_addr - 2].Data; + else + return NULL; + + return idpath2obj(data, path, 0); +} + +void pcb_idpath_destroy(pcb_idpath_t *path) +{ + pcb_idpath_list_remove(path); + free(path); +} + +void pcb_idpath_list_clear(pcb_idpath_list_t *lst) +{ + pcb_idpath_t *i, *next; + for(i = pcb_idpath_list_first(lst); i != NULL; i = next) { + next = pcb_idpath_list_next(i); + pcb_idpath_destroy(i); + } +} + +pcb_idpath_t *pcb_idpath_dup(const pcb_idpath_t *path) +{ + pcb_idpath_t *res = pcb_idpath_alloc(path->len); + memcpy(res->id, path->id, (sizeof(long int) * path->len)); + return res; +} + + Index: tags/2.3.0/src/idpath.h =================================================================== --- tags/2.3.0/src/idpath.h (nonexistent) +++ tags/2.3.0/src/idpath.h (revision 33253) @@ -0,0 +1,75 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_IDPATH_H +#define PCB_IDPATH_H + +#include +#include + +typedef struct pcb_idpath_s { + int len; + gdl_elem_t link; /* may be part of an idpath list */ + int data_addr; /* 0 means unknown, 1 means PCB, 2+ means buffer idx (-2) */ + long int id[1]; /* the struct is allocated to be sizeof(long int) * len */ +} pcb_idpath_t; + +/* List of id paths */ +#define TDL(x) pcb_idpath_list_ ## x +#define TDL_LIST_T pcb_idpath_list_t +#define TDL_ITEM_T pcb_idpath_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define pcb_idpath_list_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + +#include +#include + +#include "obj_common.h" + +/* Allocate an idpath of a given length with all id's set to 0 */ +pcb_idpath_t *pcb_idpath_alloc(int len); + +pcb_idpath_t *pcb_obj2idpath(pcb_any_obj_t *obj); +pcb_idpath_t *pcb_str2idpath(pcb_board_t *pcb, const char *str); /* slash separated list of ids */ +char *pcb_idpath2str(const pcb_idpath_t *idp, rnd_bool relative); +void pcb_append_idpath(gds_t *dst, const pcb_idpath_t *idp, rnd_bool relative); +pcb_any_obj_t *pcb_idpath2obj_in(pcb_data_t *data, const pcb_idpath_t *path); +pcb_idpath_t *pcb_idpath_dup(const pcb_idpath_t *path); +void pcb_idpath_destroy(pcb_idpath_t *path); + +/* Look up self contained path; Refuse unknown root, if pcb is NULL, refuse +pcb root. Always has access to the buffers. Returns NULL on error. */ +pcb_any_obj_t *pcb_idpath2obj(pcb_board_t *pcb, const pcb_idpath_t *path); + +void pcb_idpath_list_clear(pcb_idpath_list_t *lst); + +#endif Index: tags/2.3.0/src/insert.c =================================================================== --- tags/2.3.0/src/insert.c (nonexistent) +++ tags/2.3.0/src/insert.c (revision 33253) @@ -0,0 +1,89 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + + +/* functions used to insert points into objects */ + +#include "config.h" +#include "conf_core.h" + +#include "board.h" +#include "data.h" +#include "select.h" +#include "undo.h" + +#include "obj_line_op.h" +#include "obj_arc_op.h" +#include "obj_rat_op.h" +#include "obj_poly_op.h" + +static pcb_opfunc_t InsertFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_insert_point, + NULL, + pcb_polyop_insert_point, + NULL, + NULL, + pcb_arc_insert_point, + NULL, /* gfx */ + pcb_ratop_insert_point, + NULL, + NULL, /* subc */ + NULL, /* padstack */ + 0 /* extobj_inhibit_regen */ +}; + +void *pcb_insert_point_in_object(int Type, void *Ptr1, void *Ptr2, rnd_cardinal_t *Ptr3, rnd_coord_t DX, rnd_coord_t DY, rnd_bool Force, rnd_bool insert_last) +{ + void *ptr; + pcb_opctx_t ctx; + + ctx.insert.pcb = PCB; + ctx.insert.x = DX; + ctx.insert.y = DY; + ctx.insert.idx = *Ptr3; + ctx.insert.last = insert_last; + ctx.insert.forcible = Force; + + /* the operation insert the points to the undo-list */ + ptr = pcb_object_operation(&InsertFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); + if (ptr != NULL) + pcb_undo_inc_serial(); + return ptr; +} + +rnd_point_t *pcb_adjust_insert_point(void) +{ + static rnd_point_t InsertedPoint; + + InsertedPoint.X = pcb_crosshair.X; + InsertedPoint.Y = pcb_crosshair.Y; + return &InsertedPoint; +} Index: tags/2.3.0/src/insert.h =================================================================== --- tags/2.3.0/src/insert.h (nonexistent) +++ tags/2.3.0/src/insert.h (revision 33253) @@ -0,0 +1,43 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Inserting points into objects */ + +#ifndef PCB_INSERT_H +#define PCB_INSERT_H + +#include "config.h" + +#define PCB_INSERT_TYPES (PCB_OBJ_POLY | PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_RAT) + +void *pcb_insert_point_in_object(int Type, void *Ptr1, void *Ptr2, rnd_cardinal_t * Ptr3, rnd_coord_t DX, rnd_coord_t DY, rnd_bool Force, rnd_bool insert_last); + +/* adjusts the insert point to make 45 degree lines as necessary */ +rnd_point_t *pcb_adjust_insert_point(void); + +#endif Index: tags/2.3.0/src/intersect.c =================================================================== --- tags/2.3.0/src/intersect.c (nonexistent) +++ tags/2.3.0/src/intersect.c (revision 33253) @@ -0,0 +1,270 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1998,1999,2000,2001 harry eaton + * + * this file, intersect.c, was written and is + * Copyright (c) 2001 C. Scott Ananian + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +/* rectangle intersection/union routines. */ + +#include "config.h" + +#include +#include + +#include "intersect.h" +#include + +static int compareleft(const void *ptr1, const void *ptr2); +static int compareright(const void *ptr1, const void *ptr2); +static int comparepos(const void *ptr1, const void *ptr2); +static int nextpwrof2(int i); + +typedef struct { + rnd_coord_t left, right; + int covered; + rnd_coord_t area; +} SegmentTreeNode; + +typedef struct { + SegmentTreeNode *nodes; + int size; +} SegmentTree; + +typedef struct { + rnd_coord_t *p; + int size; +} LocationList; + +/* --------------------------------------------------------------------------- + * Create a sorted list of unique y coords from a BoxList. + */ +static LocationList createSortedYList(rnd_box_list_t *boxlist) +{ + LocationList yCoords; + rnd_coord_t last; + int i, n; + /* create sorted list of Y coordinates */ + yCoords.size = 2 * boxlist->BoxN; + yCoords.p = (rnd_coord_t *) calloc(yCoords.size, sizeof(*yCoords.p)); + for (i = 0; i < boxlist->BoxN; i++) { + yCoords.p[2 * i] = boxlist->Box[i].Y1; + yCoords.p[2 * i + 1] = boxlist->Box[i].Y2; + } + qsort(yCoords.p, yCoords.size, sizeof(*yCoords.p), comparepos); + /* count uniq y coords */ + last = 0; + for (n = 0, i = 0; i < yCoords.size; i++) + if (i == 0 || yCoords.p[i] != last) + yCoords.p[n++] = last = yCoords.p[i]; + yCoords.size = n; + return yCoords; +} + +/* --------------------------------------------------------------------------- + * Create an empty segment tree from the given sorted list of uniq y coords. + */ +static SegmentTree createSegmentTree(rnd_coord_t * yCoords, int N) +{ + SegmentTree st; + int i; + /* size is twice the nearest larger power of 2 */ + st.size = 2 * nextpwrof2(N); + st.nodes = (SegmentTreeNode *) calloc(st.size, sizeof(*st.nodes)); + /* initialize the rightmost leaf node */ + st.nodes[st.size - 1].left = (N > 0) ? yCoords[--N] : 10; + st.nodes[st.size - 1].right = st.nodes[st.size - 1].left + 1; + /* initialize the rest of the leaf nodes */ + for (i = st.size - 2; i >= st.size / 2; i--) { + st.nodes[i].right = st.nodes[i + 1].left; + st.nodes[i].left = (N > 0) ? yCoords[--N] : st.nodes[i].right - 1; + } + /* initialize the internal nodes */ + for (; i > 0; i--) { /* node 0 is not used */ + st.nodes[i].right = st.nodes[2 * i + 1].right; + st.nodes[i].left = st.nodes[2 * i].left; + } + /* done! */ + return st; +} + +void insertSegment(SegmentTree * st, int n, rnd_coord_t Y1, rnd_coord_t Y2) +{ + rnd_coord_t discriminant; + if (st->nodes[n].left >= Y1 && st->nodes[n].right <= Y2) { + st->nodes[n].covered++; + } + else { + assert(n < st->size / 2); + discriminant = st->nodes[n * 2 + 1 /*right */ ].left; + if (Y1 < discriminant) + insertSegment(st, n * 2, Y1, Y2); + if (discriminant < Y2) + insertSegment(st, n * 2 + 1, Y1, Y2); + } + /* fixup area */ + st->nodes[n].area = (st->nodes[n].covered > 0) ? + (st->nodes[n].right - st->nodes[n].left) : (n >= st->size / 2) ? 0 : st->nodes[n * 2].area + st->nodes[n * 2 + 1].area; +} + +void deleteSegment(SegmentTree * st, int n, rnd_coord_t Y1, rnd_coord_t Y2) +{ + rnd_coord_t discriminant; + if (st->nodes[n].left >= Y1 && st->nodes[n].right <= Y2) { + assert(st->nodes[n].covered); + --st->nodes[n].covered; + } + else { + assert(n < st->size / 2); + discriminant = st->nodes[n * 2 + 1 /*right */ ].left; + if (Y1 < discriminant) + deleteSegment(st, n * 2, Y1, Y2); + if (discriminant < Y2) + deleteSegment(st, n * 2 + 1, Y1, Y2); + } + /* fixup area */ + st->nodes[n].area = (st->nodes[n].covered > 0) ? + (st->nodes[n].right - st->nodes[n].left) : (n >= st->size / 2) ? 0 : st->nodes[n * 2].area + st->nodes[n * 2 + 1].area; +} + +/* --------------------------------------------------------------------------- + * Compute the area of the intersection of the given rectangles; that is, + * the area covered by more than one rectangle (counted twice if the area is + * covered by three rectangles, three times if covered by four rectangles, + * etc.). + * Runs in O(N ln N) time. + */ +double pcb_intersect_box_box(rnd_box_list_t *boxlist) +{ + rnd_cardinal_t i; + double area = 0.0; + /* first get the aggregate area. */ + for (i = 0; i < boxlist->BoxN; i++) + area += (double) (boxlist->Box[i].X2 - boxlist->Box[i].X1) * (double) (boxlist->Box[i].Y2 - boxlist->Box[i].Y1); + /* intersection area is aggregate - union. */ + return area * 0.0001 - pcb_union_box_box(boxlist); +} + +/* --------------------------------------------------------------------------- + * Compute the area of the union of the given rectangles. + * O(N ln N) time. + */ +double pcb_union_box_box(rnd_box_list_t *boxlist) +{ + rnd_box_t **rectLeft, **rectRight; + rnd_cardinal_t i, j; + LocationList yCoords; + SegmentTree segtree; + rnd_coord_t lastX; + double area = 0.0; + + if (boxlist->BoxN == 0) + return 0.0; + /* create sorted list of Y coordinates */ + yCoords = createSortedYList(boxlist); + /* now create empty segment tree */ + segtree = createSegmentTree(yCoords.p, yCoords.size); + free(yCoords.p); + /* create sorted list of left and right X coordinates of rectangles */ + rectLeft = (rnd_box_t **) calloc(boxlist->BoxN, sizeof(*rectLeft)); + rectRight = (rnd_box_t **) calloc(boxlist->BoxN, sizeof(*rectRight)); + for (i = 0; i < boxlist->BoxN; i++) { + assert(boxlist->Box[i].X1 <= boxlist->Box[i].X2); + assert(boxlist->Box[i].Y1 <= boxlist->Box[i].Y2); + rectLeft[i] = rectRight[i] = &boxlist->Box[i]; + } + qsort(rectLeft, boxlist->BoxN, sizeof(*rectLeft), compareleft); + qsort(rectRight, boxlist->BoxN, sizeof(*rectRight), compareright); + /* sweep through x segments from left to right */ + i = j = 0; + lastX = rectLeft[0]->X1; + while (j < boxlist->BoxN) { + assert(i <= boxlist->BoxN); + /* i will step through rectLeft, j will through rectRight */ + if (i == boxlist->BoxN || rectRight[j]->X2 < rectLeft[i]->X1) { + /* right edge of rectangle */ + rnd_box_t *b = rectRight[j++]; + /* check lastX */ + if (b->X2 != lastX) { + assert(lastX < b->X2); + area += (double) (b->X2 - lastX) * segtree.nodes[1].area; + lastX = b->X2; + } + /* remove a segment from the segment tree. */ + deleteSegment(&segtree, 1, b->Y1, b->Y2); + } + else { + /* left edge of rectangle */ + rnd_box_t *b = rectLeft[i++]; + /* check lastX */ + if (b->X1 != lastX) { + assert(lastX < b->X1); + area += (double) (b->X1 - lastX) * segtree.nodes[1].area; + lastX = b->X1; + } + /* add a segment from the segment tree. */ + insertSegment(&segtree, 1, b->Y1, b->Y2); + } + } + free(rectLeft); + free(rectRight); + free(segtree.nodes); + return area * 0.0001; +} + +static int compareleft(const void *ptr1, const void *ptr2) +{ + rnd_box_t **b1 = (rnd_box_t **) ptr1, **b2 = (rnd_box_t **) ptr2; + return (*b1)->X1 - (*b2)->X1; +} + +static int compareright(const void *ptr1, const void *ptr2) +{ + rnd_box_t **b1 = (rnd_box_t **) ptr1, **b2 = (rnd_box_t **) ptr2; + return (*b1)->X2 - (*b2)->X2; +} + +static int comparepos(const void *ptr1, const void *ptr2) +{ + return *((rnd_coord_t *) ptr1) - *((rnd_coord_t *) ptr2); +} + +static int nextpwrof2(int n) +{ + int r = 1; + while (n != 0) { + n /= 2; + r *= 2; + } + return r; +} Index: tags/2.3.0/src/intersect.h =================================================================== --- tags/2.3.0/src/intersect.h (nonexistent) +++ tags/2.3.0/src/intersect.h (revision 33253) @@ -0,0 +1,49 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1998,1999,2000,2001 harry eaton + * + * this file, intersect.h, was written and is + * Copyright (c) 2001 C. Scott Ananian. + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA + * haceaton@aplcomm.jhuapl.edu + * + */ + + +/* Box (rectangle) intersection/union routines. */ + +#ifndef PCB_INTERSECT_H +#define PCB_INTERSECT_H + +#include + +double pcb_intersect_box_box(rnd_box_list_t *boxlist); /* will sort boxlist */ +double pcb_union_box_box(rnd_box_list_t *boxlist); + +#endif Index: tags/2.3.0/src/layer.c =================================================================== --- tags/2.3.0/src/layer.c (nonexistent) +++ tags/2.3.0/src/layer.c (revision 33253) @@ -0,0 +1,1577 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2004,2006 Thomas Nau + * Copyright (C) 2016, 2017, 2020 Tibor 'Igor2' Palinkas (pcb-rnd extensions) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include "board.h" +#include "data.h" +#include "conf_core.h" +#include "layer.h" +#include +#include "undo.h" +#include "event.h" +#include "layer_ui.h" +#include "layer_vis.h" +#include "funchash_core.h" +#include +#include "obj_pstk_inlines.h" +#include "list_common.h" + +static const char core_layer_cookie[] = "core-layer"; + +pcb_virt_layer_t pcb_virt_layers[] = { + {"invisible", PCB_LYT_VIRTUAL + 1, PCB_LYT_VIRTUAL | PCB_LYT_INVIS, NULL, -1 }, + {"rats", PCB_LYT_VIRTUAL + 2, PCB_LYT_VIRTUAL | PCB_LYT_RAT, NULL, -1 }, + {"topassembly", PCB_LYT_VIRTUAL + 3, PCB_LYT_VIRTUAL | PCB_LYT_TOP, "assy", F_assy }, + {"bottomassembly", PCB_LYT_VIRTUAL + 4, PCB_LYT_VIRTUAL | PCB_LYT_BOTTOM, "assy", F_assy }, + {"fab", PCB_LYT_VIRTUAL + 5, PCB_LYT_VIRTUAL | PCB_LYT_LOGICAL, "fab", F_fab }, + {"plated-drill", PCB_LYT_VIRTUAL + 6, PCB_LYT_VIRTUAL, "pdrill", F_pdrill }, + {"unplated-drill", PCB_LYT_VIRTUAL + 7, PCB_LYT_VIRTUAL, "udrill", F_udrill }, + {"csect", PCB_LYT_VIRTUAL + 8, PCB_LYT_VIRTUAL | PCB_LYT_LOGICAL, "csect", F_csect }, + {"dialog", PCB_LYT_VIRTUAL + 9, PCB_LYT_VIRTUAL | PCB_LYT_DIALOG | PCB_LYT_LOGICAL | PCB_LYT_NOEXPORT, NULL, -1 }, + { NULL, 0 }, +}; + +const pcb_menu_layers_t pcb_menu_layers[] = { + { "Subcircuits", "subc", &conf_core.appearance.color.subc, NULL, offsetof(pcb_board_t, SubcOn), 0 }, + { "Subc. parts", "subcpart", &conf_core.appearance.color.subc, NULL, offsetof(pcb_board_t, SubcPartsOn), 0 }, + { "Padstacks", "padstacks",&conf_core.appearance.color.pin, NULL, offsetof(pcb_board_t, pstk_on), 0 }, + { "Holes", "holes", &conf_core.appearance.color.pin, NULL, offsetof(pcb_board_t, hole_on), 0 }, + { "Pstk. marks", "pstkmark", &conf_core.appearance.color.padstackmark, NULL, offsetof(pcb_board_t, padstack_mark_on), 0 }, + { "Far side", "farside", &conf_core.appearance.color.invisible_objects, NULL, offsetof(pcb_board_t, InvisibleObjectsOn), 0 }, + { "Rats", "rats", &conf_core.appearance.color.rat, "rats", offsetof(pcb_board_t, RatOn), offsetof(pcb_board_t, RatDraw) }, + { NULL, NULL, NULL, NULL, 0} +}; + + +typedef struct { + pcb_layer_type_t type; + int class; + const char *name; +} pcb_layer_type_name_t; + +/* update docs: lihata format tree */ +static const pcb_layer_type_name_t pcb_layer_type_names[] = { + { PCB_LYT_TOP, 1, "top" }, + { PCB_LYT_BOTTOM, 1, "bottom" }, + { PCB_LYT_INTERN, 1, "intern" }, + { PCB_LYT_LOGICAL, 1, "logical" }, + { PCB_LYT_COPPER, 2, "copper" }, + { PCB_LYT_SILK, 2, "silk" }, + { PCB_LYT_MASK, 2, "mask" }, + { PCB_LYT_PASTE, 2, "paste" }, + { PCB_LYT_BOUNDARY,2, "boundary" }, + { PCB_LYT_RAT, 2, "rat" }, + { PCB_LYT_INVIS, 2, "invis" }, + { PCB_LYT_SUBSTRATE,2,"substrate" }, + { PCB_LYT_MISC, 2, "misc" }, + { PCB_LYT_DOC, 2, "doc" }, + { PCB_LYT_MECH, 2, "mech" }, + { PCB_LYT_UI, 2, "userinterface" }, + { PCB_LYT_VIRTUAL, 3, "virtual" }, + { 0, 0, NULL } +}; + +static const char *pcb_layer_type_class_names[] = { + "INVALID", "location", "purpose", "property" +}; + +static const pcb_layer_type_name_t pcb_layer_comb_names[] = { + { PCB_LYC_SUB, 0, "sub"}, + { PCB_LYC_AUTO, 0, "auto"}, + { 0, 0, NULL } +}; + + +#define PCB_LAYER_VIRT_MIN (PCB_LYT_VIRTUAL + PCB_VLY_first + 1) +#define PCB_LAYER_VIRT_MAX (PCB_LYT_VIRTUAL + PCB_VLY_end) + +#define layer_if_too_many(pcb, fail_cmd) \ +do { \ + if (pcb->Data->LayerN >= PCB_MAX_LAYER) { \ + rnd_message(RND_MSG_ERROR, "Too many layers - can't have more than %d\n", PCB_MAX_LAYER); \ + fail_cmd; \ + } \ +} while(0) + +#define PURP_MATCH(ps, pi) (((purpi == -1) || (purpi == pi)) && ((purpose == NULL) || ((ps != NULL) && (strcmp(purpose, ps) == 0)))) + +static void obj_free_undoable(pcb_any_obj_t *obj) +{ + pcb_undo_move_obj_to_remove(obj->type, obj->parent.any, obj, obj); +} + + +static void layer_post_change(pcb_attribute_list_t *list, const char *name, const char *value) +{ + if (strncmp(name, "pcb-rnd::key::", 14) == 0) + rnd_event(&PCB->hidlib, PCB_EVENT_LAYER_KEY_CHANGE, NULL); +} + + +#define UFC(f) ((void (*)(void *))(f)) +void pcb_layer_free_fields(pcb_layer_t *layer, rnd_bool undoable) +{ + if (!layer->is_bound) + pcb_attribute_free(&layer->Attributes); + + list_map0(&layer->Line, pcb_line_t, undoable ? UFC(obj_free_undoable) : UFC(pcb_line_free)); + list_map0(&layer->Arc, pcb_arc_t, undoable ? UFC(obj_free_undoable) : UFC(pcb_arc_free)); + list_map0(&layer->Text, pcb_text_t, undoable ? UFC(obj_free_undoable) : UFC(pcb_text_free)); + if (!undoable) { + PCB_POLY_LOOP(layer); + { + pcb_poly_free_fields(polygon); + } + PCB_END_LOOP; + } + list_map0(&layer->Polygon, pcb_poly_t, undoable ? UFC(obj_free_undoable) : UFC(pcb_poly_free)); + if (!layer->is_bound) { + if (layer->line_tree) + rnd_r_destroy_tree(&layer->line_tree); + if (layer->arc_tree) + rnd_r_destroy_tree(&layer->arc_tree); + if (layer->text_tree) + rnd_r_destroy_tree(&layer->text_tree); + if (layer->polygon_tree) + rnd_r_destroy_tree(&layer->polygon_tree); + if (layer->gfx_tree) + rnd_r_destroy_tree(&layer->gfx_tree); + } + free((char *)layer->name); + memset(layer, 0, sizeof(pcb_layer_t)); + layer->Attributes.post_change = layer_post_change; +} + +rnd_bool pcb_layer_is_pure_empty(pcb_layer_t *layer) +{ + /* if any local list is non-empty, the layer is non-empty */ + if (layer->Line.lst.length > 0) return rnd_false; + if (layer->Arc.lst.length > 0) return rnd_false; + if (layer->Polygon.lst.length > 0) return rnd_false; + if (layer->Text.lst.length > 0) return rnd_false; + + /* if the layer is locally empty, it might be a board layer that has + objects from subcircuits so also check the rtrees */ + return + RND_RTREE_EMPTY(layer->line_tree) && + RND_RTREE_EMPTY(layer->arc_tree) && + RND_RTREE_EMPTY(layer->gfx_tree) && + RND_RTREE_EMPTY(layer->polygon_tree) && + RND_RTREE_EMPTY(layer->text_tree); +} + +static rnd_bool pcb_layer_is_empty_glob(pcb_board_t *pcb, pcb_data_t *data, pcb_layer_t *layer) +{ + /* if any padstack has a shape on this layer, it is not empty */ + PCB_PADSTACK_LOOP(data); + { + if (pcb_pstk_shape_at(pcb, padstack, layer) != NULL) + return 0; + } + PCB_END_LOOP; + + /* need to recurse to subc */ + PCB_SUBC_LOOP(data); + { + rnd_layer_id_t n; + pcb_layer_t *sl; + + for(sl = subc->data->Layer, n = 0; n < subc->data->LayerN; sl++,n++) { + if (sl->meta.bound.real == layer) { + if (!pcb_layer_is_empty_(pcb, sl)) + return 0; + /* can't break here: multiple bound layers may point to the same real layer! */ + } + } + + if (!pcb_layer_is_empty_glob(pcb, subc->data, layer)) + return 0; + } + PCB_END_LOOP; + + return 1; +} + +rnd_bool pcb_layer_is_empty_(pcb_board_t *pcb, pcb_layer_t *layer) +{ + pcb_layer_type_t flags = pcb_layer_flags_(layer); + if (flags == 0) + return 1; + + /* fast check: direct object */ + if (!pcb_layer_is_pure_empty(layer)) + return 0; + + if (!pcb_layer_is_empty_glob(pcb, pcb->Data, layer)) + return 0; + + /* found nothing: layer is empty */ + return 1; +} + +rnd_bool pcb_layer_is_empty(pcb_board_t *pcb, rnd_layer_id_t num) +{ + if ((num >= 0) && (num < pcb->Data->LayerN)) + return pcb_layer_is_empty_(pcb, pcb->Data->Layer + num); + return rnd_false; +} + +rnd_layer_id_t pcb_layer_id(const pcb_data_t *Data, const pcb_layer_t *Layer) +{ + if (Layer->parent_type == PCB_PARENT_UI) + return pcb_uilayer_get_id(Layer); + + if (Layer->parent.data != Data) { + /* the only case this makes sense is when we are resolving a bound layer */ + if ((Layer->is_bound) && (Layer->meta.bound.real != NULL)) + return pcb_layer_id(Data, Layer->meta.bound.real); + /* failed binding, ignore the layer */ + return -1; + } + if ((Layer >= Data->Layer) && (Layer < (Data->Layer + PCB_MAX_LAYER))) + return Layer - Data->Layer; + + return -1; +} + +unsigned int pcb_layer_flags(const pcb_board_t *pcb, rnd_layer_id_t layer_idx) +{ + pcb_layer_t *l; + + if (layer_idx & PCB_LYT_UI) + return PCB_LYT_UI | PCB_LYT_VIRTUAL; + + if ((layer_idx >= PCB_LAYER_VIRT_MIN) && (layer_idx <= PCB_LAYER_VIRT_MAX)) + return pcb_virt_layers[layer_idx - PCB_LAYER_VIRT_MIN].type; + + if ((layer_idx < 0) || (layer_idx >= pcb->Data->LayerN)) + return 0; + + l = &pcb->Data->Layer[layer_idx]; + return pcb_layergrp_flags(pcb, l->meta.real.grp); +} + +unsigned int pcb_layer_flags_(const pcb_layer_t *layer) +{ + + /* real layer: have to do a layer stack based lookup; but at least we have a real layer ID */ + if (!layer->is_bound) { + pcb_data_t *data = layer->parent.data; + rnd_layer_id_t lid; + + if (data == NULL) + return 0; + + lid = pcb_layer_id(data, layer);; + if (lid < 0) + return 0; + + assert(data->parent_type == PCB_PARENT_BOARD); + return pcb_layer_flags(data->parent.board, lid); + } + + /* bound layer: if it is already bound to a real layer, use that, whatever it is (manual binding may override our local type match pattern) */ + if (layer->meta.bound.real != NULL) { + layer = pcb_layer_get_real(layer); + if (layer == NULL) + return 0; + return pcb_layer_flags_(layer); /* tail recursion */ + } + + /* bound layer without a real layer binding: use the type match */ + return layer->meta.bound.type; +} + +int pcb_layer_purpose(const pcb_board_t *pcb, rnd_layer_id_t layer_idx, const char **out) +{ + pcb_layergrp_t *grp; + + if (layer_idx & PCB_LYT_UI) + return PCB_LYT_UI | PCB_LYT_VIRTUAL; + + if ((layer_idx >= PCB_LAYER_VIRT_MIN) && (layer_idx <= PCB_LAYER_VIRT_MAX)) { + if (out != NULL) + *out = pcb_virt_layers[layer_idx - PCB_LAYER_VIRT_MIN].purpose; + return pcb_virt_layers[layer_idx - PCB_LAYER_VIRT_MIN].purpi; + } + + if ((layer_idx < 0) || (layer_idx >= pcb->Data->LayerN)) { + if (out != NULL) + *out = NULL; + return -1; + } + + grp = pcb_get_layergrp((pcb_board_t *)pcb, pcb->Data->Layer[layer_idx].meta.real.grp); + + if (out != NULL) { + if (grp == NULL) { + *out = NULL; + return -1; + } + *out = grp->purpose; + return grp->purpi; + } + + if (grp == NULL) + return -1; + + return grp->purpi; +} + +int pcb_layer_purpose_(const pcb_layer_t *layer, const char **out) +{ + /* real layer: have to do a layer stack based lookup; but at least we have a real layer ID */ + if (!layer->is_bound) { + pcb_data_t *data = layer->parent.data; + rnd_layer_id_t lid; + + if (data == NULL) + return 0; + + lid = pcb_layer_id(data, layer);; + if (lid < 0) + return 0; + + assert(data->parent_type == PCB_PARENT_BOARD); + return pcb_layer_purpose(data->parent.board, lid, out); + } + + /* bound layer: if it is already bound to a real layer, use that, whatever it is (manual binding may override our local type match pattern) */ + if (layer->meta.bound.real != NULL) { + layer = pcb_layer_get_real(layer); + if (layer == NULL) + return 0; + return pcb_layer_purpose_(layer, out); /* tail recursion */ + } + + /* bound layer without a real layer binding: use the type match */ + if (out != NULL) + *out = layer->meta.bound.purpose; + return rnd_funchash_get(layer->meta.bound.purpose, NULL); +} + +#define APPEND(n) \ + do { \ + if (res != NULL) { \ + if (used < res_len) { \ + res[used] = n; \ + used++; \ + } \ + } \ + else \ + used++; \ + } while(0) + +#define APPEND_VIRT(v) \ +do { \ + APPEND(v->new_id); \ +} while(0) + +const pcb_virt_layer_t *pcb_vlayer_get_first(pcb_layer_type_t mask, const char *purpose, int purpi) +{ + const pcb_virt_layer_t *v; + mask &= (~PCB_LYT_VIRTUAL); + for(v = pcb_virt_layers; v->name != NULL; v++) + if ((((v->type & (~PCB_LYT_VIRTUAL)) & mask) == mask) && PURP_MATCH(v->purpose, v->purpi)) + return v; + return NULL; +} + + + +int pcb_layer_list(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layer_id_t *res, int res_len) +{ + int n, used = 0; + pcb_virt_layer_t *v; + + for(v = pcb_virt_layers; v->name != NULL; v++) + if ((v->type & mask) == mask) + APPEND_VIRT(v); + + for (n = 0; n < PCB_MAX_LAYER; n++) + if ((pcb_layer_flags(pcb, n) & mask) == mask) + APPEND(n); + + if (mask == PCB_LYT_UI) + for (n = 0; n < vtp0_len(&pcb_uilayers); n++) + if (pcb_uilayers.array[n] != NULL) + APPEND(n | PCB_LYT_UI | PCB_LYT_VIRTUAL); + + return used; +} + +/* optimization: code dup for speed */ +int pcb_layer_listp(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layer_id_t *res, int res_len, int purpi, const char *purpose) +{ + int n, used = 0; + pcb_virt_layer_t *v; + + + for(v = pcb_virt_layers; v->name != NULL; v++) + if (((v->type & mask) == mask) && (PURP_MATCH(v->purpose, v->purpi))) + APPEND_VIRT(v); + + for (n = 0; n < PCB_MAX_LAYER; n++) { + if ((pcb_layer_flags(pcb, n) & mask) == mask) { + const char *lpurp; + int lpurpi = pcb_layer_purpose(pcb, n, &lpurp); + if (PURP_MATCH(lpurp, lpurpi)) + APPEND(n); + } + } + + if (mask == PCB_LYT_UI) + for (n = 0; n < vtp0_len(&pcb_uilayers); n++) + if ((pcb_uilayers.array[n] != NULL)) + APPEND(n | PCB_LYT_UI | PCB_LYT_VIRTUAL); + + return used; +} + + +int pcb_layer_list_any(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layer_id_t *res, int res_len) +{ + int n, used = 0; + pcb_virt_layer_t *v; + + for(v = pcb_virt_layers; v->name != NULL; v++) + if ((v->type & mask)) + APPEND_VIRT(v); + + for (n = 0; n < PCB_MAX_LAYER; n++) + if ((pcb_layer_flags(pcb, n) & mask)) + APPEND(n); + + if (mask & PCB_LYT_UI) + for (n = 0; n < vtp0_len(&pcb_uilayers); n++) + if (pcb_uilayers.array[n] != NULL) + APPEND(n | PCB_LYT_UI | PCB_LYT_VIRTUAL); + + return used; +} + +rnd_layer_id_t pcb_layer_by_name(pcb_data_t *data, const char *name) +{ + rnd_layer_id_t n; + for (n = 0; n < data->LayerN; n++) + if (strcmp(data->Layer[n].name, name) == 0) + return n; + return -1; +} + +void pcb_layers_reset(pcb_board_t *pcb) +{ + rnd_layer_id_t n; + + /* reset everything to empty, even if that's invalid (no top/bottom copper) + for the rest of the code: the (embedded) default design will overwrite this. */ + /* reset layers */ + for(n = 0; n < PCB_MAX_LAYER; n++) { + if (pcb->Data->Layer[n].name != NULL) + free((char *)pcb->Data->Layer[n].name); + pcb->Data->Layer[n].name = rnd_strdup(""); + pcb->Data->Layer[n].meta.real.grp = -1; + pcb->Data->Layer[n].Attributes.post_change = layer_post_change; + } + + /* reset layer groups */ + for(n = 0; n < PCB_MAX_LAYERGRP; n++) { + pcb->LayerGroups.grp[n].len = 0; + pcb->LayerGroups.grp[n].ltype = 0; + pcb->LayerGroups.grp[n].valid = 0; + } + pcb->LayerGroups.len = 0; + pcb->Data->LayerN = 0; +} + +/* empty and detach a layer - must be initialized or another layer moved over it later */ +static void layer_clear(pcb_layer_t *dst) +{ + memset(dst, 0, sizeof(pcb_layer_t)); + dst->meta.real.grp = -1; + dst->Attributes.post_change = layer_post_change; +} + +static void pcb_layer_undoable_created(pcb_board_t *pcb, pcb_layer_t *l); +rnd_layer_id_t pcb_layer_create(pcb_board_t *pcb, rnd_layergrp_id_t grp, const char *lname, rnd_bool undoable) +{ + rnd_layer_id_t id; + + layer_if_too_many(pcb, return -1); + + id = pcb->Data->LayerN++; + + if (lname != NULL) { + if (pcb->Data->Layer[id].name != NULL) + free((char *)pcb->Data->Layer[id].name); + } + + layer_clear(&pcb->Data->Layer[id]); + pcb->Data->Layer[id].name = rnd_strdup(lname); + + /* add layer to group */ + if (grp >= 0) { + pcb->LayerGroups.grp[grp].lid[pcb->LayerGroups.grp[grp].len] = id; + pcb->LayerGroups.grp[grp].len++; + pcb->Data->Layer[id].meta.real.vis = pcb->Data->Layer[pcb->LayerGroups.grp[grp].lid[0]].meta.real.vis; + } + pcb->Data->Layer[id].meta.real.grp = grp; + pcb->Data->Layer[id].meta.real.color = *pcb_layer_default_color(id, (grp < 0) ? 0 : pcb->LayerGroups.grp[grp].ltype); + + pcb->Data->Layer[id].parent_type = PCB_PARENT_DATA; + pcb->Data->Layer[id].parent.data = pcb->Data; + pcb->Data->Layer[id].type = PCB_OBJ_LAYER; + pcb->Data->Layer[id].Attributes.post_change = layer_post_change; + + if (pcb == PCB) + pcb_board_set_changed_flag(pcb, 1); + + if (undoable) + pcb_layer_undoable_created(pcb, &pcb->Data->Layer[id]); + + return id; +} + +/*** undoable layer rename ***/ +typedef struct { + pcb_layer_t *layer; + char *name; +} undo_layer_rename_t; + +static int undo_layer_rename_swap(void *udata) +{ + char *old; + undo_layer_rename_t *r = udata; + + old = (char *)r->layer->name; + r->layer->name = r->name; + r->name = old; + if (!r->layer->is_bound) { + assert((r->layer->parent_type == PCB_PARENT_DATA) && (r->layer->parent.data->parent_type == PCB_PARENT_BOARD)); + pcb_layergrp_notify_chg(r->layer->parent.data->parent.board); + } + return 0; +} + +static void undo_layer_rename_print(void *udata, char *dst, size_t dst_len) +{ + undo_layer_rename_t *r = udata; + rnd_snprintf(dst, dst_len, "rename layer: '%s' -> '%s'", r->layer->name, r->name); +} + +static void undo_layer_rename_free(void *udata) +{ + undo_layer_rename_t *r = udata; + free(r->name); +} + + +static const uundo_oper_t undo_layer_rename = { + core_layer_cookie, + undo_layer_rename_free, + undo_layer_rename_swap, + undo_layer_rename_swap, + undo_layer_rename_print +}; + + + +int pcb_layer_rename_(pcb_layer_t *Layer, char *Name, rnd_bool undoable) +{ + undo_layer_rename_t rtmp, *r = &rtmp; + + if (undoable) { + pcb_board_t *pcb = pcb_data_get_top(Layer->parent.data); + if (pcb != NULL) + r = pcb_undo_alloc(pcb, &undo_layer_rename, sizeof(undo_layer_rename_t)); + } + + r->layer = Layer; + r->name = Name; + + undo_layer_rename_swap(r); + if (undoable) + pcb_undo_inc_serial(); + else + undo_layer_rename_free(r); + + return 0; +} + +int pcb_layer_rename(pcb_data_t *data, rnd_layer_id_t layer, const char *lname, rnd_bool undoable) +{ + return pcb_layer_rename_(&data->Layer[layer], rnd_strdup(lname), undoable); +} + +/*** undoable layer recolor ***/ +typedef struct { + pcb_layer_t *layer; + rnd_color_t color; +} undo_layer_recolor_t; + + +static int undo_layer_recolor_swap(void *udata) +{ + rnd_color_t old; + undo_layer_recolor_t *r = udata; + + old = r->layer->meta.real.color; + r->layer->meta.real.color = r->color; + r->color = old; + if (!r->layer->is_bound) { + assert((r->layer->parent_type == PCB_PARENT_DATA) && (r->layer->parent.data->parent_type == PCB_PARENT_BOARD)); + pcb_layergrp_notify_chg(r->layer->parent.data->parent.board); + } + return 0; +} + +static void undo_layer_recolor_print(void *udata, char *dst, size_t dst_len) +{ + undo_layer_recolor_t *r = udata; + rnd_snprintf(dst, dst_len, "recolor layer: '%s' -> '%s'", r->layer->meta.real.color.str, r->color.str); +} + +static const uundo_oper_t undo_layer_recolor = { + core_layer_cookie, + NULL, + undo_layer_recolor_swap, + undo_layer_recolor_swap, + undo_layer_recolor_print +}; + + +int pcb_layer_recolor_(pcb_layer_t *Layer, const rnd_color_t *color, rnd_bool undoable) +{ + undo_layer_recolor_t rtmp, *r = &rtmp; + + if (Layer->is_bound) + return -1; + + if (undoable) { + pcb_board_t *pcb = pcb_data_get_top(Layer->parent.data); + if (pcb != NULL) + r = pcb_undo_alloc(pcb, &undo_layer_recolor, sizeof(undo_layer_recolor_t)); + } + + r->layer = Layer; + r->color = *color; + + undo_layer_recolor_swap(r); + if (undoable) + pcb_undo_inc_serial(); + + return 0; +} + +int pcb_layer_recolor(pcb_data_t *data, rnd_layer_id_t layer, const char *color, rnd_bool undoable) +{ + rnd_color_t clr; + rnd_color_load_str(&clr, color); + return pcb_layer_recolor_(&data->Layer[layer], &clr, undoable); +} + +/*** undoable layer comb changes ***/ +typedef struct { + pcb_layer_t *layer; + pcb_layer_combining_t comb; +} undo_layer_recomb_t; + + +static int undo_layer_recomb_swap(void *udata) +{ + pcb_layer_combining_t old; + undo_layer_recomb_t *r = udata; + + old = r->layer->comb; + r->layer->comb = r->comb; + r->comb = old; + if (!r->layer->is_bound) { + assert((r->layer->parent_type == PCB_PARENT_DATA) && (r->layer->parent.data->parent_type == PCB_PARENT_BOARD)); + pcb_layergrp_notify_chg(r->layer->parent.data->parent.board); + } + return 0; +} + +static void undo_layer_recomb_print(void *udata, char *dst, size_t dst_len) +{ + undo_layer_recomb_t *r = udata; + rnd_snprintf(dst, dst_len, "recomb layer: '%x' -> '%x'", r->layer->comb, r->comb); +} + +static const uundo_oper_t undo_layer_recomb = { + core_layer_cookie, + NULL, + undo_layer_recomb_swap, + undo_layer_recomb_swap, + undo_layer_recomb_print +}; + + +int pcb_layer_recomb(pcb_layer_t *Layer, pcb_layer_combining_t comb, rnd_bool undoable) +{ + undo_layer_recomb_t rtmp, *r = &rtmp; + + if (Layer->is_bound) + return -1; + + if (Layer->comb == comb) + return 0; + + if (undoable) { + pcb_board_t *pcb = pcb_data_get_top(Layer->parent.data); + if (pcb != NULL) + r = pcb_undo_alloc(pcb, &undo_layer_recomb, sizeof(undo_layer_recomb_t)); + } + + r->layer = Layer; + r->comb = comb; + + undo_layer_recomb_swap(r); + if (undoable) + pcb_undo_inc_serial(); + + return 0; +} + +#undef APPEND + +static int is_last_top_copper_layer(pcb_board_t *pcb, int layer) +{ + rnd_layergrp_id_t cgroup = pcb_layer_get_group(pcb, pcb->LayerGroups.len + PCB_COMPONENT_SIDE); + rnd_layergrp_id_t lgroup = pcb_layer_get_group(pcb, layer); + if (cgroup == lgroup && pcb->LayerGroups.grp[lgroup].len == 1) + return 1; + return 0; +} + +static int is_last_bottom_copper_layer(pcb_board_t *pcb, int layer) +{ + int sgroup = pcb_layer_get_group(pcb, pcb->LayerGroups.len + PCB_SOLDER_SIDE); + int lgroup = pcb_layer_get_group(pcb, layer); + if (sgroup == lgroup && pcb->LayerGroups.grp[lgroup].len == 1) + return 1; + return 0; +} + +/* Safe move of a layer within a layer array, updating all fields (list->parents) */ +void pcb_layer_move_(pcb_layer_t *dst, pcb_layer_t *src) +{ + pcb_line_t *li; + pcb_text_t *te; + pcb_poly_t *po; + pcb_arc_t *ar; + + memcpy(dst, src, sizeof(pcb_layer_t)); + + /* reparent all the lists: each list item has a ->parent pointer that needs to point to the new place */ + for(li = linelist_first(&dst->Line); li != NULL; li = linelist_next(li)) { + li->parent.layer = dst; + li->link.parent = &dst->Line.lst; + } + for(te = textlist_first(&dst->Text); te != NULL; te = textlist_next(te)) { + te->parent.layer = dst; + te->link.parent = &dst->Text.lst; + } + for(po = polylist_first(&dst->Polygon); po != NULL; po = polylist_next(po)) { + po->parent.layer = dst; + po->link.parent = &dst->Polygon.lst; + } + for(ar = arclist_first(&dst->Arc); ar != NULL; ar = arclist_next(ar)) { + ar->parent.layer = dst; + ar->link.parent = &dst->Arc.lst; + } +} + +const rnd_color_t *pcb_layer_default_color(int idx, pcb_layer_type_t lyt) +{ + const int clrs = sizeof(conf_core.appearance.color.layer) / sizeof(conf_core.appearance.color.layer[0]); + + if (lyt & PCB_LYT_MASK) + return &conf_core.appearance.color.mask; + if (lyt & PCB_LYT_PASTE) + return &conf_core.appearance.color.paste; + if (lyt & PCB_LYT_SILK) + return &conf_core.appearance.color.element; + + return &conf_core.appearance.color.layer[idx % clrs]; +} + +void pcb_layer_setup(pcb_layer_t *ly, pcb_data_t *parent_data) +{ + ly->Attributes.post_change = layer_post_change; + ly->parent.data = parent_data; + ly->parent_type = PCB_PARENT_DATA; + ly->type = PCB_OBJ_LAYER; +} + +/* Initialize a new layer with safe initial values */ +static void layer_init(pcb_board_t *pcb, pcb_layer_t *lp, rnd_layer_id_t idx, rnd_layergrp_id_t gid, pcb_data_t *parent) +{ + memset(lp, 0, sizeof(pcb_layer_t)); + lp->meta.real.grp = gid; + lp->meta.real.vis = 1; + lp->name = rnd_strdup("New Layer"); + lp->meta.real.color = *pcb_layer_default_color(idx, (gid >= 0) ? pcb->LayerGroups.grp[gid].ltype : 0); + if ((gid >= 0) && (pcb->LayerGroups.grp[gid].len == 0)) { /*When adding the first layer in a group, set up comb flags automatically */ + switch((pcb->LayerGroups.grp[gid].ltype) & PCB_LYT_ANYTHING) { + case PCB_LYT_MASK: lp->comb = PCB_LYC_AUTO | PCB_LYC_SUB; break; + case PCB_LYT_SILK: lp->comb = PCB_LYC_AUTO; + case PCB_LYT_PASTE: lp->comb = PCB_LYC_AUTO; + default: break; + } + } + pcb_layer_setup(lp, parent); +} + +static pcb_layer_t *pcb_layer_move_append_(pcb_board_t *pcb, rnd_layer_id_t new_index, rnd_layergrp_id_t new_in_grp) +{ + pcb_layergrp_t *g; + pcb_layer_t *lp; + rnd_layer_id_t new_lid = pcb->Data->LayerN++; + int grp_idx; + + lp = &pcb->Data->Layer[new_lid]; + if (new_in_grp >= 0) + layer_init(pcb, lp, new_lid, new_in_grp, pcb->Data); + else + layer_init(pcb, lp, new_lid, pcb->Data->Layer[new_index].meta.real.grp, pcb->Data); + + g = pcb_get_layergrp(pcb, lp->meta.real.grp); + + if (new_in_grp >= 0) { + if (new_index == 0) + grp_idx = 0; + else + grp_idx = g->len; + } + else + grp_idx = pcb_layergrp_index_in_grp(g, new_index); + + /* shift group members up and insert the new layer in group */ + if ((g->len > grp_idx) && (grp_idx >= 0)) + memmove(g->lid+grp_idx+1, g->lid+grp_idx, (g->len - grp_idx) * sizeof(rnd_layer_id_t)); + if (grp_idx < 0) + grp_idx = 0; + g->lid[grp_idx] = new_lid; + g->len++; + pcb_layergrp_notify_chg(pcb); + pcb_layervis_change_group_vis(&pcb->hidlib, new_lid, 1, 1); + rnd_event(&pcb->hidlib, PCB_EVENT_LAYERVIS_CHANGED, NULL); + + return lp; +} + +static pcb_layer_t *pcb_layer_move_insert_(pcb_board_t *pcb, rnd_layer_id_t new_lid, rnd_layergrp_id_t new_in_grp, int grp_idx) +{ + pcb_layergrp_t *g; + pcb_layer_t *lp; + rnd_layergrp_id_t gid; + rnd_layer_id_t lid; + + + /* update lids in all groups (shifting down idx) */ + for(gid = 0; gid < pcb_max_group(pcb); gid++) { + int n; + g = &pcb->LayerGroups.grp[gid]; + for(n = 0; n < g->len; n++) + if (g->lid[n] >= new_lid) + g->lid[n]++; + } + + /* shift the layer array to make room */ + for(lid = pcb->Data->LayerN-1; lid >= new_lid ; lid--) { + layer_clear(&pcb->Data->Layer[lid+1]); + pcb_layer_move_(&pcb->Data->Layer[lid+1], &pcb->Data->Layer[lid]); + } + + /* do not update the stack - rendering order is not that important */ + + /* remove layer from the logical layer array */ + pcb_max_layer(PCB)++; + + /* shift target group members up and insert the new layer in group */ + g = pcb_get_layergrp(pcb, new_in_grp); + if ((g->len > grp_idx) && (grp_idx >= 0)) + memmove(g->lid+grp_idx+1, g->lid+grp_idx, (g->len - grp_idx) * sizeof(rnd_layer_id_t)); + g->lid[grp_idx] = new_lid; + g->len++; + + lp = &pcb->Data->Layer[new_lid]; + layer_clear(lp); + layer_init(pcb, lp, new_lid, new_in_grp, pcb->Data); + + return lp; +} + +static int pcb_layer_move_delete_(pcb_board_t *pcb, rnd_layer_id_t old_index, rnd_bool undoable) +{ + rnd_layer_id_t l; + rnd_layergrp_id_t gid; + pcb_layergrp_t *g; + int grp_idx, remaining; + + /* make sure subcircuits don't reference this layer any more */ + pcb_subc_unbind_all(pcb, &pcb->Data->Layer[old_index], undoable); + + /* remove the current lid from its group */ + g = pcb_get_layergrp(pcb, pcb->Data->Layer[old_index].meta.real.grp); + grp_idx = pcb_layergrp_index_in_grp(g, old_index); + if (grp_idx < 0) { + rnd_message(RND_MSG_ERROR, "Internal error; layer not in group\n"); + return -1; + } + + pcb_layer_free_fields(&pcb->Data->Layer[old_index], undoable); + + remaining = (g->len - grp_idx - 1); + if (remaining > 0) + memmove(g->lid+grp_idx, g->lid+grp_idx+1, remaining * sizeof(rnd_layer_id_t)); + g->len--; + + /* update lids in all groups (shifting down idx) */ + for(gid = 0; gid < pcb_max_group(pcb); gid++) { + int n; + g = &pcb->LayerGroups.grp[gid]; + for(n = 0; n < g->len; n++) + if (g->lid[n] > old_index) + g->lid[n]--; + } + + /* update visibility */ + for(l = old_index; l < pcb->Data->LayerN-1; l++) { + pcb_layer_move_(&pcb->Data->Layer[l], &pcb->Data->Layer[l+1]); + layer_clear(&pcb->Data->Layer[l+1]); + } + + for (l = 0; l < pcb->Data->LayerN; l++) + if (pcb_layer_stack[l] == old_index) + memmove(pcb_layer_stack + l, pcb_layer_stack + l + 1, (pcb->Data->LayerN - l - 1) * sizeof(pcb_layer_stack[0])); + + /* remove layer from the logical layer array */ + pcb_max_layer(PCB)--; + for (l = 0; l < pcb->Data->LayerN; l++) + if (pcb_layer_stack[l] > old_index) + pcb_layer_stack[l]--; + + pcb_layergrp_notify_chg(pcb); + return 0; +} + +typedef struct { + pcb_board_t *pcb; + unsigned append:1; + rnd_layer_id_t lid; + long in_grp_idx; + + /* fields */ + char *name; + pcb_layer_combining_t comb; + rnd_layergrp_id_t grp; + rnd_color_t color; +} undo_layer_move_t; + +static int undo_layer_move_swap(void *udata) +{ + undo_layer_move_t *m = udata; + pcb_board_t *pcb = m->pcb; + + if (m->append) { /* undo an append by deleting */ + pcb_layer_t *l = &pcb->Data->Layer[m->lid]; + m->name = (char *)l->name; + l->name = NULL; + pcb_layer_move_delete_(pcb, m->lid, 0); + } + else { /* undo a delete by inserting it back in its place */ + pcb_layer_t *l = pcb_layer_move_insert_(pcb, m->lid, m->grp, m->in_grp_idx); + l->name = m->name; + m->name = NULL; + l->meta.real.color = m->color; + pcb_layergrp_notify_chg(pcb); + pcb_layervis_change_group_vis(&pcb->hidlib, m->lid, 1, 1); + rnd_event(&pcb->hidlib, PCB_EVENT_LAYERVIS_CHANGED, NULL); + } + + m->append = !m->append; + return 0; +} + +static void undo_layer_move_print(void *udata, char *dst, size_t dst_len) +{ + undo_layer_move_t *m = udata; + rnd_snprintf(dst, dst_len, "layer_move: %s %s lid=%ld grp=%ld", m->append ? "append" : "delete", m->name, m->lid, m->grp); +} + +static void undo_layer_move_free(void *udata) +{ + undo_layer_move_t *m = udata; + free(m->name); +} + + +static const uundo_oper_t undo_layer_move = { + core_layer_cookie, + undo_layer_move_free, + undo_layer_move_swap, + undo_layer_move_swap, + undo_layer_move_print +}; + +static long layer_idx_in_grp(pcb_board_t *pcb, pcb_layer_t *l) +{ + rnd_layer_id_t lid = l - pcb->Data->Layer; + pcb_layergrp_t *g; + + if ((lid < 0) || (lid >= pcb->Data->LayerN)) + return 0; + + g = pcb_get_layergrp(pcb, l->meta.real.grp); + if (g != NULL) { + long n; + for(n = 0; n < g->len; n++) + if (g->lid[n] == lid) + return n; + } + return 0; +} + +/* Call this after creating grp to add the creation to the undo list */ +static void pcb_layer_undoable_created(pcb_board_t *pcb, pcb_layer_t *l) +{ + undo_layer_move_t *m = pcb_undo_alloc(pcb, &undo_layer_move, sizeof(undo_layer_move_t)); + memset(m, 0, sizeof(undo_layer_move_t)); + m->pcb = pcb; + m->lid = l - pcb->Data->Layer; + m->grp = l->meta.real.grp; + m->color = l->meta.real.color; + m->in_grp_idx = layer_idx_in_grp(pcb, l); + m->append = 1; + pcb_undo_inc_serial(); +} + + +static int pcb_layer_move_append(pcb_board_t *pcb, rnd_layer_id_t new_index, rnd_layergrp_id_t new_in_grp, int undoable) +{ + pcb_layer_t *l; + + l = pcb_layer_move_append_(pcb, new_index, new_in_grp); + if (l == NULL) + return 1; + + if (undoable) + pcb_layer_undoable_created(pcb, l); + return 0; +} + +static int pcb_layer_move_delete(pcb_board_t *pcb, rnd_layer_id_t old_index, int undoable) +{ + undo_layer_move_t *m, mtmp; + pcb_layer_t *l; + int res; + + if (!undoable) + return pcb_layer_move_delete_(pcb, old_index, undoable); + + pcb_undo_freeze_serial(); + + l = &pcb->Data->Layer[old_index]; + memset(&mtmp, 0, sizeof(undo_layer_move_t)); + mtmp.pcb = pcb; + mtmp.lid = old_index; + mtmp.name = (char *)l->name; + l->name = NULL; + mtmp.grp = l->meta.real.grp; + mtmp.color = l->meta.real.color; + mtmp.in_grp_idx = layer_idx_in_grp(pcb, l); + mtmp.append = 0; + res = pcb_layer_move_delete_(pcb, old_index, undoable); + + m = pcb_undo_alloc(pcb, &undo_layer_move, sizeof(undo_layer_move_t)); + memcpy(m, &mtmp, sizeof(undo_layer_move_t)); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + return res; +} + + +int pcb_layer_move(pcb_board_t *pcb, rnd_layer_id_t old_index, rnd_layer_id_t new_index, rnd_layergrp_id_t new_in_grp, rnd_bool undoable) +{ + /* sanity checks */ + if (old_index < -1 || old_index >= pcb->Data->LayerN) { + rnd_message(RND_MSG_ERROR, "Invalid old layer %d for move: must be -1..%d\n", old_index, pcb->Data->LayerN - 1); + return 1; + } + + if (new_index < -1 || new_index > pcb->Data->LayerN || new_index >= PCB_MAX_LAYER) { + rnd_message(RND_MSG_ERROR, "Invalid new layer %d for move: must be -1..%d\n", new_index, pcb->Data->LayerN); + return 1; + } + + if (new_index == -1 && is_last_top_copper_layer(pcb, old_index)) { + rnd_hid_message_box(&pcb->hidlib, "warning", "Layer delete", "You can't delete the last top-side layer\n", "cancel", 0, NULL); + return 1; + } + + if (new_index == -1 && is_last_bottom_copper_layer(pcb, old_index)) { + rnd_hid_message_box(&pcb->hidlib, "warning", "Layer delete", "You can't delete the last bottom-side layer\n", "cancel", 0, NULL); + return 1; + } + + + if (old_index == -1) /* append new layer at the end of the logical layer list, put it in the current group */ + return pcb_layer_move_append(pcb, new_index, new_in_grp, undoable); + if (new_index == -1) /* Delete the layer at old_index */ + return pcb_layer_move_delete(pcb, old_index, undoable); + + + rnd_message(RND_MSG_ERROR, "Logical layer move is not supported any more. This function should have not been called. Please report this error.\n"); + /* Removed r8686: + The new layer design presents the layers by groups to preserve physical + order. In this system the index of the logical layer on the logical + layer list is insignificant, thus we shouldn't try to change it. */ + return 1; +} + +const char *pcb_layer_name(pcb_data_t *data, rnd_layer_id_t id) +{ + if (id < 0) + return NULL; + if (id < data->LayerN) + return data->Layer[id].name; + if ((id >= PCB_LAYER_VIRT_MIN) && (id <= PCB_LAYER_VIRT_MAX)) + return pcb_virt_layers[id-PCB_LAYER_VIRT_MIN].name; + return NULL; +} + +pcb_layer_t *pcb_get_layer(pcb_data_t *data, rnd_layer_id_t id) +{ + if ((id >= 0) && (id < data->LayerN)) + return &data->Layer[id]; + if (id & PCB_LYT_UI) + return pcb_uilayer_get(id); + return NULL; +} + +rnd_layer_id_t pcb_layer2id(pcb_data_t *data, pcb_layer_t *ly) +{ + long lid; + + if (ly == NULL) return -1; + + lid = ly - data->Layer; + if ((lid < 0) || (lid >= data->LayerN)) + return -1; + + return lid; +} + +void pcb_layer_link_trees(pcb_layer_t *dst, pcb_layer_t *src) +{ + /* we can't link non-existing trees - make sure src does have the trees initialized */ + if (src->line_tree == NULL) src->line_tree = rnd_r_create_tree(); + if (src->arc_tree == NULL) src->arc_tree = rnd_r_create_tree(); + if (src->text_tree == NULL) src->text_tree = rnd_r_create_tree(); + if (src->polygon_tree == NULL) src->polygon_tree = rnd_r_create_tree(); + if (src->gfx_tree == NULL) src->gfx_tree = rnd_r_create_tree(); + + dst->line_tree = src->line_tree; + dst->arc_tree = src->arc_tree; + dst->text_tree = src->text_tree; + dst->polygon_tree = src->polygon_tree; + dst->gfx_tree = src->gfx_tree; +} + + +void pcb_layer_real2bound_offs(pcb_layer_t *dst, pcb_board_t *src_pcb, pcb_layer_t *src) +{ + dst->meta.bound.real = NULL; + dst->is_bound = 1; + if ((dst->meta.bound.type & PCB_LYT_INTERN) && (dst->meta.bound.type & PCB_LYT_COPPER)) { + int from_top, from_bottom, res; + pcb_layergrp_t *tcop = pcb_get_grp(&src_pcb->LayerGroups, PCB_LYT_TOP, PCB_LYT_COPPER); + pcb_layergrp_t *bcop = pcb_get_grp(&src_pcb->LayerGroups, PCB_LYT_BOTTOM, PCB_LYT_COPPER); + rnd_layergrp_id_t tcop_id = pcb_layergrp_id(src_pcb, tcop); + rnd_layergrp_id_t bcop_id = pcb_layergrp_id(src_pcb, bcop); + + res = pcb_layergrp_dist(src_pcb, src->meta.real.grp, tcop_id, PCB_LYT_COPPER, &from_top); + res |= pcb_layergrp_dist(src_pcb, src->meta.real.grp, bcop_id, PCB_LYT_COPPER, &from_bottom); + if (res == 0) { + if (from_top <= from_bottom) + dst->meta.bound.stack_offs = from_top; + else + dst->meta.bound.stack_offs = -from_bottom; + } + else + rnd_message(RND_MSG_ERROR, "Internal error: can't figure the inter copper\nlayer offset for %s\n", src->name); + } + else + dst->meta.bound.stack_offs = 0; +} + +void pcb_layer_real2bound(pcb_layer_t *dst, pcb_layer_t *src, int share_rtrees) +{ + pcb_board_t *pcb; + pcb_layergrp_t *grp; + + assert(!src->is_bound); + + pcb = pcb_layer_get_top(src); + grp = pcb_get_layergrp(pcb, src->meta.real.grp); + dst->comb = src->comb; + + dst->meta.bound.type = pcb_layergrp_flags(pcb, src->meta.real.grp); + if (src->name != NULL) + dst->name = rnd_strdup(src->name); + else + dst->name = NULL; + + if ((grp != NULL) && (grp->purpose != NULL)) + dst->meta.bound.purpose = rnd_strdup(grp->purpose); + else + dst->meta.bound.purpose = NULL; + + pcb_layer_real2bound_offs(dst, pcb, src); + + if (!src->is_bound) { + dst->meta.bound.real = src; + if (share_rtrees) + pcb_layer_link_trees(dst, src); + } +} + +static int strcmp_score(const char *s1, const char *s2) +{ + int score = 0; + + if (s1 == s2) /* mainly for NULL = NULL */ + score += 4; + + if ((s1 != NULL) && (s2 != NULL)) { + if (strcmp(s1, s2) == 0) + score += 4; + else if (rnd_strcasecmp(s1, s2) == 0) + score += 2; + } + + return score; +} + +void pcb_layer_resolve_best(pcb_board_t *pcb, pcb_layergrp_t *grp, pcb_layer_t *src, int *best_score, pcb_layer_t **best) +{ + int l, score; + + for(l = 0; l < grp->len; l++) { + pcb_layer_t *ly = pcb_get_layer(pcb->Data, grp->lid[l]); + if ((ly->comb & PCB_LYC_SUB) == (src->comb & PCB_LYC_SUB)) { + score = 1; + if (ly->comb == src->comb) + score++; + + score += strcmp_score(ly->name, src->name); + score += strcmp_score(grp->purpose, src->meta.bound.purpose); + + if (score > *best_score) { + *best = ly; + *best_score = score; + } + } + } +} + +pcb_layer_t *pcb_layer_resolve_binding(pcb_board_t *pcb, pcb_layer_t *src) +{ + rnd_layergrp_id_t gid; + pcb_layergrp_t *grp; + int best_score = 0; + pcb_layer_t *best = NULL; + + + assert(src->is_bound); + + /* look up the layer group; for internal copper this means counting the offset */ + if ((src->meta.bound.type & PCB_LYT_INTERN) && (src->meta.bound.type & PCB_LYT_COPPER) && (src->meta.bound.stack_offs != 0)) { + if (src->meta.bound.stack_offs < 0) + gid = pcb_layergrp_get_bottom_copper(); + else + gid = pcb_layergrp_get_top_copper(); + gid = pcb_layergrp_step(pcb, gid, src->meta.bound.stack_offs, PCB_LYT_COPPER | PCB_LYT_INTERN); + /* target group identified; pick the closest match layer within that group */ + grp = pcb->LayerGroups.grp+gid; + pcb_layer_resolve_best(pcb, grp, src, &best_score, &best); + } + else { + pcb_layer_type_t lyt = src->meta.bound.type; + if ((lyt & PCB_LYT_BOUNDARY) && (lyt & PCB_LYT_ANYWHERE)) { + lyt = PCB_LYT_BOUNDARY; + rnd_message(RND_MSG_WARNING, "Ignoring invalid layer flag combination for %s: boundary layer must be global\n(fixed up by removing location specifier bits)\n", src->name); + } + for(gid = 0, grp = pcb->LayerGroups.grp; gid < pcb->LayerGroups.len; gid++,grp++) + if ((grp->ltype & lyt) == lyt) + pcb_layer_resolve_best(pcb, grp, src, &best_score, &best); + } + + return best; +} + +pcb_layer_t *pcb_layer_new_bound(pcb_data_t *data, pcb_layer_type_t type, const char *name, const char *purpose) +{ + pcb_layer_t *lay = &data->Layer[data->LayerN++]; + + memset(lay, 0, sizeof(pcb_layer_t)); + lay->is_bound = 1; + lay->name = rnd_strdup(name); + lay->meta.bound.type = type; + if (purpose == NULL) + lay->meta.bound.purpose = NULL; + else + lay->meta.bound.purpose = rnd_strdup(purpose); + lay->parent.data = data; + lay->parent_type = PCB_PARENT_DATA; + lay->type = PCB_OBJ_LAYER; + return lay; +} + +unsigned int pcb_layer_hash_bound(pcb_layer_t *ly, rnd_bool smirror) +{ + unsigned int hash; + pcb_layer_type_t lyt; + int offs; + + assert(ly->is_bound); + + lyt = ly->meta.bound.type; + offs = ly->meta.bound.stack_offs; + + if (smirror) { + lyt = pcb_layer_mirror_type(lyt); + offs = -offs; + } + + hash = (unsigned long)arclist_length(&ly->Arc); + hash ^= (unsigned long)linelist_length(&ly->Line); + hash ^= (unsigned long)textlist_length(&ly->Text); + hash ^= (unsigned long)polylist_length(&ly->Polygon); + hash ^= (unsigned long)ly->comb ^ (unsigned long)lyt; + + if (ly->meta.bound.type & PCB_LYT_INTERN) + hash ^= (unsigned int)offs; + + return hash; +} + +pcb_layer_type_t pcb_layer_mirror_type(pcb_layer_type_t lyt) +{ + if (lyt & PCB_LYT_TOP) + return (lyt & ~PCB_LYT_TOP) | PCB_LYT_BOTTOM; + else if (lyt & PCB_LYT_BOTTOM) + return (lyt & ~PCB_LYT_BOTTOM) | PCB_LYT_TOP; + return lyt; +} + +int pcb_layer_type_map(pcb_layer_type_t type, void *ctx, void (*cb)(void *ctx, pcb_layer_type_t bit, const char *name, int class, const char *class_name)) +{ + const pcb_layer_type_name_t *n; + int found = 0; + for(n = pcb_layer_type_names; n->name != NULL; n++) { + if (type & n->type) { + cb(ctx, n->type, n->name, n->class, pcb_layer_type_class_names[n->class]); + found++; + } + } + return found; +} + +int pcb_layer_comb_map(pcb_layer_combining_t type, void *ctx, void (*cb)(void *ctx, pcb_layer_combining_t bit, const char *name)) +{ + const pcb_layer_type_name_t *n; + int found = 0; + for(n = pcb_layer_comb_names; n->name != NULL; n++) { + if (type & n->type) { + cb(ctx, n->type, n->name); + found++; + } + } + return found; +} + + +pcb_layer_type_t pcb_layer_type_str2bit(const char *name) +{ + const pcb_layer_type_name_t *n; + for(n = pcb_layer_type_names; n->name != NULL; n++) + if (strcmp(n->name, name) == 0) + return n->type; + return 0; +} + +pcb_layer_type_t pcb_layer_type_strn2bit(const char *name, size_t len) +{ + const pcb_layer_type_name_t *n; + for(n = pcb_layer_type_names; n->name != NULL; n++) + if ((strncmp(n->name, name, len) == 0) && (n->name[len] == '\0')) + return n->type; + return 0; +} + +const char *pcb_layer_type_bit2str(pcb_layer_type_t type) +{ + const pcb_layer_type_name_t *n; + for(n = pcb_layer_type_names; n->name != NULL; n++) + if (type & n->type) + return n->name; + return 0; +} + +pcb_layer_combining_t pcb_layer_comb_str2bit(const char *name) +{ + const pcb_layer_type_name_t *n; + for(n = pcb_layer_comb_names; n->name != NULL; n++) + if (strcmp(n->name, name) == 0) + return n->type; + return 0; +} + + +int pcb_layer_typecomb_str2bits(const char *str, pcb_layer_type_t *lyt, pcb_layer_combining_t *lyc, rnd_bool allow_implicit_lyc) +{ + const char *curr, *next; + int res = 0, got_lyc = 0; + + *lyt = 0; + *lyc = 0; + for(curr = str; curr != NULL; curr = next) { + const pcb_layer_type_name_t *nc; + const pcb_layer_type_name_t *nt; + + size_t len; + while((*curr != '\0') && !isalnum(*curr)) curr++; + if (*curr == '\0') + break; + for(next = curr; isalpha(*next); next++) ; + len = next - curr; + + + for(nt = pcb_layer_type_names; nt->name != NULL; nt++) { + if (rnd_strncasecmp(nt->name, curr, len) == 0) { + *lyt |= nt->type; + goto done; + } + } + + for(nc = pcb_layer_comb_names; nc->name != NULL; nc++) { + if (rnd_strncasecmp(nc->name, curr, len) == 0) { + got_lyc = 1; + *lyc |= nc->type; + goto done; + } + } + + if ((rnd_strncasecmp("pos", curr, len) == 0) || (rnd_strncasecmp("add", curr, len) == 0)) { + got_lyc = 1; + *lyc &= ~PCB_LYC_SUB; + goto done; + } + + res = -1; /* not found in either */ + + done:; + } + + if (allow_implicit_lyc && !got_lyc) { + if (*lyt & PCB_LYT_MASK) *lyc = PCB_LYC_SUB | PCB_LYC_AUTO; + if (*lyt & PCB_LYT_PASTE) *lyc = PCB_LYC_AUTO; + } + + return res; +} + +void pcb_layer_auto_fixup(pcb_board_t *pcb) +{ + rnd_layer_id_t n; + + /* old silk layers are always auto */ + for(n = 0; n < pcb->Data->LayerN; n++) + if (pcb_layer_flags(pcb, n) & PCB_LYT_SILK) + pcb->Data->Layer[n].comb |= PCB_LYC_AUTO; +} + +int pcb_layer_gui_set_vlayer(pcb_board_t *pcb, pcb_virtual_layer_t vid, int is_empty, rnd_xform_t **xform) +{ + pcb_virt_layer_t *v = &pcb_virt_layers[vid]; + assert((vid >= 0) && (vid < PCB_VLY_end)); + + /* if there's no renderer, that means no draw should be done */ + if (rnd_render == NULL) + return 0; + + if (xform != NULL) + *xform = NULL; + +TODO("layer: need to pass the flags of the group, not the flags of the layer once we have a group for each layer") + if (rnd_render->set_layer_group != NULL) { + rnd_layergrp_id_t grp; + rnd_layer_id_t lid = v->new_id; + grp = pcb_layer_get_group(pcb, lid); + return rnd_render->set_layer_group(rnd_render, grp, v->purpose, v->purpi, lid, v->type, is_empty, xform); + } + + /* if the GUI doesn't have a set_layer, assume it wants to draw all layers */ + return 1; +} + +int pcb_layer_gui_set_g_ui(pcb_layer_t *first, int is_empty, rnd_xform_t **xform) +{ + /* if there's no renderer, that means no draw should be done */ + if (rnd_render == NULL) + return 0; + + if (xform != NULL) + *xform = NULL; + + if (rnd_render->set_layer_group != NULL) + return rnd_render->set_layer_group(rnd_render, -1, NULL, -1, pcb_layer_id(first->parent.data, first), PCB_LYT_VIRTUAL | PCB_LYT_UI, is_empty, xform); + + /* if the GUI doesn't have a set_layer, assume it wants to draw all layers */ + return 1; +} + +const pcb_menu_layers_t *pcb_menu_layer_find(const char *name_or_abbrev) +{ + const pcb_menu_layers_t *ml; + + for(ml = pcb_menu_layers; ml->name != NULL; ml++) + if (rnd_strcasecmp(name_or_abbrev, ml->abbrev) == 0) + return ml; + + for(ml = pcb_menu_layers; ml->name != NULL; ml++) + if (rnd_strcasecmp(name_or_abbrev, ml->name) == 0) + return ml; + + return NULL; +} Index: tags/2.3.0/src/layer.h =================================================================== --- tags/2.3.0/src/layer.h (nonexistent) +++ tags/2.3.0/src/layer.h (revision 33253) @@ -0,0 +1,384 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2006 Thomas Nau + * Copyright (C) 2016,2019 Tibor 'Igor2' Palinkas (pcb-rnd extensions) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_LAYER_H +#define PCB_LAYER_H + +/* Layer type bitfield */ +typedef enum { + /* Stack-up (vertical position): */ + PCB_LYT_TOP = 0x00000001, /* layer is on the top side of the board */ + PCB_LYT_BOTTOM = 0x00000002, /* layer is on the bottom side of the board */ + PCB_LYT_INTERN = 0x00000004, /* layer is internal */ + PCB_LYT_LOGICAL = 0x00000008, /* does not depend on the layer stackup (typically aux drawing layer) */ + PCB_LYT_ANYWHERE = 0x000000FF, /* MASK: layer is anywhere on the stack */ + + /* What the layer consists of (main type) */ + PCB_LYT_COPPER = 0x00000100, /* copper objects */ + PCB_LYT_SILK = 0x00000200, /* silk objects */ + PCB_LYT_MASK = 0x00000400, /* solder mask */ + PCB_LYT_PASTE = 0x00000800, /* paste */ + PCB_LYT_RAT = 0x00002000, /* (virtual) rats nest (one, not in the stackup) */ + PCB_LYT_INVIS = 0x00004000, /* (virtual) layer is invisible (one, not in the stackup) */ + PCB_LYT_BOUNDARY = 0x00008000, /* physical boundaries of the board (inner and outer): route, cuts, slots, drills */ + PCB_LYT_UI = 0x00080000, /* (virtual) user interface drawings (feature plugins use this for displaying states or debug info) */ + PCB_LYT_SUBSTRATE= 0x00200000, /* substrate / insulator */ + PCB_LYT_MISC = 0x00400000, /* misc (for internal use) */ + PCB_LYT_DIALOG = 0x00800000, /* (virtual) dialog box drawings (e.g. font selector) - not to be interpreted in the board space */ + PCB_LYT_DOC = 0x01000000, /* misc documentation layers - user allocated, largely ignored by the code */ + PCB_LYT_MECH = 0x02000000, /* misc mechanical/physical layers (e.g. adhesive, keepouts) */ + PCB_LYT_ANYTHING = 0x0FFFFF00, /* MASK: layers consist anything */ + + /* misc properties */ + PCB_LYT_VIRTUAL = 0x10000000, /* the layer is not in the layer array (generated layer) */ + PCB_LYT_NOEXPORT = 0x20000000, /* should not show up in any of the exports */ + PCB_LYT_ANYPROP = 0x70000000 /* MASK: misc layer properties */ +} pcb_layer_type_t; + + +typedef enum { + PCB_VLY_INVISIBLE, + PCB_VLY_RATS, + PCB_VLY_TOP_ASSY, + PCB_VLY_BOTTOM_ASSY, + PCB_VLY_FAB, + PCB_VLY_PLATED_DRILL, + PCB_VLY_UNPLATED_DRILL, + PCB_VLY_CSECT, + + /* for determining the range, do not use */ + PCB_VLY_end, + PCB_VLY_first = PCB_VLY_INVISIBLE +} pcb_virtual_layer_t; + +typedef enum { /* bitfield */ + PCB_LYC_SUB = 1, /* bit 0 is 0 for add or 1 for sub */ + PCB_LYC_AUTO = 2 /* bit 1 is 0 for manual drawn layer or 1 for side-effect objects from padstacks; this is how the user controls on which composite mask/paste layer padstack side effects should appear */ +} pcb_layer_combining_t; + +#define PCB_LAYER_IN_STACK(lyt) (((lyt) & PCB_LYT_COPPER) || ((lyt) & PCB_LYT_SILK) || ((lyt) & PCB_LYT_MASK) || ((lyt) & PCB_LYT_PASTE) || ((lyt) & PCB_LYT_SUBSTRATE)) +#define PCB_LAYER_SIDED(lyt) (((lyt) & PCB_LYT_COPPER) || ((lyt) & PCB_LYT_SILK) || ((lyt) & PCB_LYT_MASK) || ((lyt) & PCB_LYT_PASTE) || ((lyt) & PCB_LYT_DOC)) + +#define PCB_LAYER_IS_VASSY(lyt, purpi) (((lyt) & PCB_LYT_VIRTUAL) && ((purpi) == F_assy)) +#define PCB_LAYER_IS_RASSY(lyt, purpi) (((lyt) & PCB_LYT_DOC) && ((purpi) == F_assy)) +#define PCB_LAYER_IS_ASSY(lyt, purpi) (PCB_LAYER_IS_VASSY(lyt, purpi)||PCB_LAYER_IS_RASSY(lyt, purpi)) +#define PCB_LAYER_IS_VFAB(lyt, purpi) (((lyt) & PCB_LYT_VIRTUAL) && ((purpi) == F_fab)) +#define PCB_LAYER_IS_RFAB(lyt, purpi) (((lyt) & PCB_LYT_DOC) && ((purpi) == F_fab)) +#define PCB_LAYER_IS_FAB(lyt, purpi) (PCB_LAYER_IS_VFAB(lyt, purpi) || PCB_LAYER_IS_RFAB(lyt, purpi)) +#define PCB_LAYER_IS_CSECT(lyt, purpi) (((lyt) & PCB_LYT_VIRTUAL) && ((purpi) == F_csect)) +#define PCB_LAYER_IS_PDRILL(lyt, purpi) (((lyt) & PCB_LYT_VIRTUAL) && ((purpi) == F_pdrill)) +#define PCB_LAYER_IS_UDRILL(lyt, purpi) (((lyt) & PCB_LYT_VIRTUAL) && ((purpi) == F_udrill)) +#define PCB_LAYER_IS_DRILL(lyt, purpi) (((lyt) & PCB_LYT_VIRTUAL) && (((purpi) == F_pdrill) || ((purpi) == F_udrill))) + +/* Route must be on a mech or boundary layer */ +#define PCB_LAYER_IS_UROUTE(lyt, purpi) (((lyt) & (PCB_LYT_BOUNDARY | PCB_LYT_MECH)) && ((((purpi) == F_uroute)))) +#define PCB_LAYER_IS_PROUTE(lyt, purpi) (((lyt) & (PCB_LYT_BOUNDARY | PCB_LYT_MECH)) && (((purpi) == F_proute))) +#define PCB_LAYER_IS_ROUTE(lyt, purpi) (((lyt) & (PCB_LYT_BOUNDARY | PCB_LYT_MECH)) && (((purpi) == F_proute) || ((purpi) == F_uroute))) + +/* Outline is a route in a boundary group; outline in this sense + means the "perimeter of the board", but could include largish internal + cutout - the user needs to be explicit about this. Mech layers are NOT + included, that's the difference compared to routed layers */ +#define PCB_LAYER_IS_OUTLINE(lyt, purpi) (((lyt) & PCB_LYT_BOUNDARY) && (((purpi) == F_proute) || ((purpi) == F_uroute) || ((purpi) == F_ucut) || ((purpi) == F_uvcut))) + +#include "globalconst.h" +#include +#include +#include "attrib.h" +#include "obj_common.h" +#include "obj_arc_list.h" +#include "obj_line_list.h" +#include "obj_poly_list.h" +#include "obj_text_list.h" +#include "obj_gfx_list.h" + +struct pcb_layer_s { /* holds information about one layer */ + PCB_ANY_OBJ_FIELDS; + + linelist_t Line; + textlist_t Text; + polylist_t Polygon; + arclist_t Arc; + gfxlist_t Gfx; + + const char *name; /* layer name */ + + pcb_layer_combining_t comb; /* how to combine this layer with other layers in the group */ + + /* for bound layers these point to the board layer's*/ + rnd_rtree_t *line_tree, *text_tree, *polygon_tree, *arc_tree, *gfx_tree; + + union { + struct { /* A real board layer */ + rnd_layergrp_id_t grp; /* the group this layer is in (cross-reference) */ + rnd_bool vis; /* visible flag */ + rnd_color_t color; /* copied */ + int no_drc; /* whether to ignore the layer when checking the design rules */ + const char *cookie; /* for UI layers: registration cookie; NULL for unused UI layers */ + rnd_xform_t xform; /* layer specified rendering transformation */ + } real; + struct { /* A subcircuit layer binding; list data are local but everything else is coming from board layers */ + pcb_layer_t *real; /* NULL if unbound */ + + /* matching rules */ + pcb_layer_type_t type; + /* for comb, use the ->comb from the common part */ + int stack_offs; /* offset in the stack for PCB_LYT_INNER: positive is counted from primary side, negative from the opposite side */ + char *purpose; /* what the target doc/mech layer is used for */ + + unsigned user_specified:1; /* 1 if the user forced the binding */ + rnd_layer_id_t user_lid; + } bound; + } meta; + + unsigned is_bound:1; +}; + +/* returns the layer number for the passed copper or silk layer pointer */ +rnd_layer_id_t pcb_layer_id(const pcb_data_t *Data, const pcb_layer_t *Layer); + + +/* the offsets of the two additional special layers (e.g. silk) for 'component' + and 'solder'. The offset of PCB_MAX_LAYER is not added here. Also can be + used to address side of the board without referencing to groups or layers. */ +typedef enum { + PCB_SOLDER_SIDE = 0, + PCB_COMPONENT_SIDE = 1 +} pcb_side_t; + +/* Return the board the layer is under */ +#define pcb_layer_get_top(layer) pcb_data_get_top((layer)->parent.data) + +typedef struct { + const char *name, *abbrev; + rnd_color_t const *force_color; + const char *select_name; + int vis_offs, sel_offs; +} pcb_menu_layers_t; + +extern const pcb_menu_layers_t pcb_menu_layers[]; + +const pcb_menu_layers_t *pcb_menu_layer_find(const char *name_or_abbrev); + +/************ OLD API - new code should not use these **************/ + +#define LAYER_LOOP(data, ml) \ + do { \ + rnd_cardinal_t n; \ + for (n = 0; n < ml; n++) { \ + pcb_layer_t *layer = (&data->Layer[(n)]); + +/************ NEW API - new code should use these **************/ + +#define PCB_STACKLAYER(pcb, n) (&((pcb)->Data->Layer[pcb_layer_stack[(n)]])) +#define PCB_CURRLAYER(pcb) (PCB_STACKLAYER((pcb), 0)) +#define PCB_CURRLID(pcb) (pcb_layer_stack[0]) + +/* Free all metadata and objects of a layer; does not free(layer) */ +void pcb_layer_free_fields(pcb_layer_t *layer, rnd_bool undoable); + +/* Return the layer pointer (or NULL on invalid or virtual layers) for an id */ +pcb_layer_t *pcb_get_layer(pcb_data_t *data, rnd_layer_id_t id); + +/* Return the layer ID within data, or -1 if ly is not in data */ +rnd_layer_id_t pcb_layer2id(pcb_data_t *data, pcb_layer_t *ly); + +/* Return the name of a layer (real or virtual) or NULL on error + NOTE: layer names may not be unique; returns the first case sensitive hit; + slow linear search */ +rnd_layer_id_t pcb_layer_by_name(pcb_data_t *data, const char *name); + +/* Returns rnd_true if the given layer is empty (there are no objects on the layer) */ +rnd_bool pcb_layer_is_empty_(pcb_board_t *pcb, pcb_layer_t *ly); +rnd_bool pcb_layer_is_empty(pcb_board_t *pcb, rnd_layer_id_t ly); + +/* Returns rnd_true if the given layer is empty - non-recursive variant (doesn't deal with side effects) */ +rnd_bool pcb_layer_is_pure_empty(pcb_layer_t *layer); + + +/* call the gui to set a virtual layer or the UI layer group */ +int pcb_layer_gui_set_vlayer(pcb_board_t *pcb, pcb_virtual_layer_t vid, int is_empty, rnd_xform_t **xform); +int pcb_layer_gui_set_g_ui(pcb_layer_t *first, int is_empty, rnd_xform_t **xform); + + +/* returns a bitfield of pcb_layer_type_t; returns 0 if layer_idx or layer is invalid. */ +unsigned int pcb_layer_flags(const pcb_board_t *pcb, rnd_layer_id_t layer_idx); +unsigned int pcb_layer_flags_(const pcb_layer_t *layer); + +/* Return the purpi of the group of a layer; if out is not NULL, also copy + a pointer to the purpose string there (valid until a layer change) */ +int pcb_layer_purpose(const pcb_board_t *pcb, rnd_layer_id_t layer_idx, const char **out); +int pcb_layer_purpose_(const pcb_layer_t *layer, const char **out); + + +/* map bits of a layer type (call cb for each bit set); return number of bits + found. */ +int pcb_layer_type_map(pcb_layer_type_t type, void *ctx, void (*cb)(void *ctx, pcb_layer_type_t bit, const char *name, int class, const char *class_name)); +int pcb_layer_comb_map(pcb_layer_combining_t type, void *ctx, void (*cb)(void *ctx, pcb_layer_combining_t bit, const char *name)); + +/* return 0 or the flag value correspoding to name (linear search) */ +pcb_layer_type_t pcb_layer_type_str2bit(const char *name); +pcb_layer_type_t pcb_layer_type_strn2bit(const char *name, size_t len); +pcb_layer_combining_t pcb_layer_comb_str2bit(const char *name); + +/* Convert a list of types/combs from string to bits. Returns 0 on success. + The string is separated by any non-alpha character and is case insensitive. + If allow_implicit_lyc is true, improvise the value of *lyc using *lyt if + no comb flag was explicitly specified in the string. */ +int pcb_layer_typecomb_str2bits(const char *str, pcb_layer_type_t *lyt, pcb_layer_combining_t *lyc, rnd_bool allow_implicit_lyc); + +/* return the name of a type bit; type should have only one bit set */ +const char *pcb_layer_type_bit2str(pcb_layer_type_t type); + +/* Various fixes for old/plain/flat layer stack imports vs. composite layers */ +void pcb_layer_auto_fixup(pcb_board_t *pcb); + +/* List layer IDs that matches mask - write the first res_len items in res, + if res is not NULL. Returns: + - the total number of layers matching the query, if res is NULL + - the number of layers copied into res if res is not NULL + The plain version require exact match (look for a specific layer), + the _any version allows partial match so work with PCB_LYT_ANY*. + The version that ends in 'p' also matches purpose if purpi is not -1 + and/or purpose is not NULL. +*/ +int pcb_layer_list(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layer_id_t *res, int res_len); +int pcb_layer_list_any(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layer_id_t *res, int res_len); +int pcb_layer_listp(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layer_id_t *res, int res_len, int purpi, const char *purpose); + + +/**** layer creation (for load/import code) ****/ + +/* Set parent and attribute change callback */ +void pcb_layer_setup(pcb_layer_t *ly, pcb_data_t *parent_data); + +/* Reset layers and layer groups to empty */ +void pcb_layers_reset(pcb_board_t *pcb); + +/* Create a new layer and put it in an existing group (if grp is not -1). */ +rnd_layer_id_t pcb_layer_create(pcb_board_t *pcb, rnd_layergrp_id_t grp, const char *lname, rnd_bool undoable); + +/* Return the name of a layer (resolving the true name of virtual layers too) */ +const char *pcb_layer_name(pcb_data_t *data, rnd_layer_id_t id); + +/* Return the default color for a new layer from the config */ +const rnd_color_t *pcb_layer_default_color(int idx, pcb_layer_type_t lyt); + +/* Rename/recolor an existing layer by idx */ +int pcb_layer_rename(pcb_data_t *data, rnd_layer_id_t layer, const char *lname, rnd_bool undoable); +int pcb_layer_recolor(pcb_data_t *data, rnd_layer_id_t layer, const char *lcolor, rnd_bool undoable); + +/* Change the combination flags of a layer */ +int pcb_layer_recomb(pcb_layer_t *Layer, pcb_layer_combining_t comb, rnd_bool undoable); + + +/* changes the color of a layer; string has to be allocated by the caller (pcb_strdup) */ +int pcb_layer_rename_(pcb_layer_t *Layer, char *Name, rnd_bool undoable); + +/* Low level layer color change, parsed color must be available */ +int pcb_layer_recolor_(pcb_layer_t *Layer, const rnd_color_t *color, rnd_bool undoable); + +/* index is 0..PCB_MAX_LAYER-1. If old_index is -1, a new layer is + inserted at that index. If new_index is -1, the specified layer is + deleted. Returns non-zero on error, zero if OK. */ +int pcb_layer_move(pcb_board_t *pcb, rnd_layer_id_t old_index, rnd_layer_id_t new_index, rnd_layergrp_id_t new_in_grp, rnd_bool undoable); + + +/* set up dst to be a bound layer with the right offset in the stack; src_pcb + is used for the layer stack of src. Assumes other fields of dst, e.g. name, + are all set up. */ +void pcb_layer_real2bound_offs(pcb_layer_t *dst, pcb_board_t *src_pcb, pcb_layer_t *src); + +/* Set up dst so that it's a non-real layer bound to src */ +void pcb_layer_real2bound(pcb_layer_t *dst, pcb_layer_t *src, int share_rtrees); + +/* Assume src is a bound layer; find the closest match in pcb's layer stack */ +pcb_layer_t *pcb_layer_resolve_binding(pcb_board_t *pcb, pcb_layer_t *src); + +/* Allocate a new bound layer within data, set it up, but do not do the binding */ +pcb_layer_t *pcb_layer_new_bound(pcb_data_t *data, pcb_layer_type_t type, const char *name, const char *purpose); + +/* Calculate a hash of a bound layer (ingoring its name) */ +unsigned int pcb_layer_hash_bound(pcb_layer_t *ly, rnd_bool smirror); + +/* Calculate mirrored version of some (bound) layer properties */ +pcb_layer_type_t pcb_layer_mirror_type(pcb_layer_type_t lyt); + + +/* Modify tree pointers in dst to point to src's; allocates trees for src if they are not yet allocated */ +void pcb_layer_link_trees(pcb_layer_t *dst, pcb_layer_t *src); + +/* How deep subcs can be nested */ +#define PCB_MAX_BOUND_LAYER_RECURSION 128 + +/* Return the real layer, resolving layer bindings. Returns NULL on + error (e.g. binding loop) */ +RND_INLINE pcb_layer_t *pcb_layer_get_real(const pcb_layer_t *layer) +{ + int rec = 0; + + while(layer->is_bound) { + layer = layer->meta.bound.real; + rec++; + if ((rec > PCB_MAX_BOUND_LAYER_RECURSION) || (layer == NULL)) + return NULL; + } + return (pcb_layer_t *)layer; +} + +/* list of virtual layers: these are generated by the draw code but do not + have a real layer in the array */ +typedef struct pcb_virt_layer_s { + char *name; + rnd_layer_id_t new_id; + pcb_layer_type_t type; + const char *purpose; + int purpi; +} pcb_virt_layer_t; + +extern pcb_virt_layer_t pcb_virt_layers[]; + +/* Return the first virtual layer that fully matches mask */ +const pcb_virt_layer_t *pcb_vlayer_get_first(pcb_layer_type_t mask, const char *purpose, int purpi); + +/* Returns whether the given unsigned int layer flags corresponds to a layer + that's on the visible side of the board at the moment. */ +#define PCB_LAYERFLG_ON_VISIBLE_SIDE(uint_flags) \ + (!!(conf_core.editor.show_solder_side ? ((uint_flags) & PCB_LYT_BOTTOM) : ((uint_flags) & PCB_LYT_TOP))) + +#define PCB_LYT_VISIBLE_SIDE() \ + ((conf_core.editor.show_solder_side ? PCB_LYT_BOTTOM : PCB_LYT_TOP)) + +#define PCB_LYT_INVISIBLE_SIDE() \ + ((conf_core.editor.show_solder_side ? PCB_LYT_TOP : PCB_LYT_BOTTOM)) + +/*** For internal use ***/ +void pcb_layer_move_(pcb_layer_t *dst, pcb_layer_t *src); + +#endif Index: tags/2.3.0/src/layer_addr.c =================================================================== --- tags/2.3.0/src/layer_addr.c (nonexistent) +++ tags/2.3.0/src/layer_addr.c (revision 33253) @@ -0,0 +1,541 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include "board.h" +#include "data.h" +#include +#include +#include + +#include "layer_addr.h" + +char *pcb_parse_layergrp_err = ""; +char *pcb_parse_layergrp_address(char *curr, char **spk, char **spv, int *spc) +{ + char *s, *lasta, *eq; + int level = 0, trmax = *spc; + *spc = 0; + + for(s = curr; *s != '\0'; s++) { + switch(*s) { + case '(': + if (level == 0) { + *s = '\0'; + lasta = s+1; + } + level++; + break; + case ')': + if (level > 0) + level--; + if (level == 0) + goto append; + break; + case ',': + if (level == 0) + goto out; + append:; + *s = '\0'; + if (*spc >= trmax) + return pcb_parse_layergrp_err; + lasta = rnd_str_strip(lasta); + spk[*spc] = lasta; + eq = strchr(lasta, '='); + if (eq != NULL) { + *eq = '\0'; + eq++; + } + spv[*spc] = eq; + (*spc)++; + *s = '\0'; + lasta = s+1; + } + } + + if (level > 0) + return pcb_parse_layergrp_err; + + out:; + + if (*s != '\0') { + *s = '\0'; + s++; + return s; + } + + return NULL; /* no more layers */ +} + +static int parse_layer_type(const char *type, pcb_layer_type_t *lyt, int *offs, int *has_offs) +{ + const char *soffs, *nxt, *cur; + char *end; + pcb_layer_type_t l; + + *lyt = 0; + *offs = *has_offs = 0; + + soffs = strchr(type, ':'); + if (soffs != NULL) { + *offs = strtol(soffs+1, &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "CAM rule: invalid offset '%s'\n", soffs); + return 1; + } + *has_offs = 1; + } + + for(cur = type; cur != NULL; cur = nxt) { + nxt = strpbrk(cur, "-:(/"); + if (nxt != NULL) + l = pcb_layer_type_strn2bit(cur, nxt - cur); + else + l = pcb_layer_type_str2bit(cur); + if (nxt != NULL) { + if (*nxt != '-') + nxt = NULL; + else + nxt++; + } + if (l == 0) { + rnd_message(RND_MSG_ERROR, "CAM rule: invalid layer type '%s'\n", cur); + return 1; + } + (*lyt) |= l; + } + return 0; +} + +void pcb_parse_layer_supplements(char **spk, char **spv, int spc, char **purpose, rnd_xform_t **xf, rnd_xform_t *xf_) +{ + int n; + + *purpose = NULL; + if (xf_ != NULL) + memset(xf_, 0, sizeof(rnd_xform_t)); + + for(n = 0; n < spc; n++) { + char *key = spk[n], *val = spv[n]; + + if (strcmp(key, "purpose") == 0) + *purpose = val; + else if (strcmp(key, "bloat") == 0) { + rnd_bool succ; + double v = rnd_get_value(val, NULL, NULL, &succ); + if (succ) { + if (xf_ != NULL) + xf_->bloat = v; + if (xf != NULL) + *xf = xf_; + } + else + rnd_message(RND_MSG_ERROR, "CAM: ignoring invalid layer supplement value '%s' for bloat\n", val); + } + else if (strcmp(key, "faded") == 0) { + if (xf_ != NULL) xf_->layer_faded = 1; + if (xf != NULL) *xf = xf_; + } + else if (strcmp(key, "partial") == 0) { + if (xf_ != NULL) xf_->partial_export = 1; + if (xf != NULL) *xf = xf_; + } + else if (strcmp(key, "wireframe") == 0) { + if (xf_ != NULL) xf_->wireframe = 1; + if (xf != NULL) *xf = xf_; + } + else if (strcmp(key, "thin_draw") == 0) { + if (xf_ != NULL) xf_->thin_draw = 1; + if (xf != NULL) *xf = xf_; + } + else if (strcmp(key, "thin_draw_poly") == 0) { + if (xf_ != NULL) xf_->thin_draw_poly = 1; + if (xf != NULL) *xf = xf_; + } + else if (strcmp(key, "check_planes") == 0) { + if (xf_ != NULL) xf_->check_planes = 1; + if (xf != NULL) *xf = xf_; + } + else if (strcmp(key, "flag_color") == 0) { + if (xf_ != NULL) xf_->flag_color = 1; + if (xf != NULL) *xf = xf_; + } + else if (strcmp(key, "hide_floaters") == 0) { + if (xf_ != NULL) xf_->hide_floaters = 1; + if (xf != NULL) *xf = xf_; + } + else + rnd_message(RND_MSG_ERROR, "CAM: ignoring unknown layer supplement key '%s'\n", key); + } +} + + +int pcb_layergrp_list_by_addr(pcb_board_t *pcb, const char *curr, rnd_layergrp_id_t gids[PCB_MAX_LAYERGRP], char **spk, char **spv, int spc, int *vid, rnd_xform_t **xf, rnd_xform_t *xf_in, const char *err_prefix) +{ + rnd_layergrp_id_t gid, lgids[PCB_MAX_LAYERGRP]; + int gids_max = PCB_MAX_LAYERGRP; + char *purpose; + + if (vid != NULL) + *vid = -1; + + if (*curr == '#') { + char *end; + gid = strtol(curr+1, &end, 10); + if ((*end == '\0') && (gid >= 0) && (gid < pcb->LayerGroups.len)) { + gids[0] = gid; + return 1; + } + if (err_prefix != NULL) + rnd_message(RND_MSG_ERROR, "%sinvalid layer group number\n", err_prefix); + return -1; + } + + if (*curr == '@') { + /* named layer group */ + curr++; + gid = pcb_layergrp_by_name(pcb, curr); + if (gid < 0) { + if (vid != NULL) { + const pcb_virt_layer_t *v; + int n; + pcb_parse_layer_supplements(spk, spv, spc, &purpose, xf, xf_in); + for(n = 0, v = pcb_virt_layers; v->name != NULL; n++,v++) { + if (strcmp(v->name, curr) == 0) { + *vid = n; + return 0; + } + } + } + return 0; + } + if (gid < 0) { + if (err_prefix != NULL) + rnd_message(RND_MSG_ERROR, "%sno such layer group '%s'\n", curr, err_prefix); + return -1; + } + if (pcb->LayerGroups.grp[gid].len <= 0) + return 0; + pcb_parse_layer_supplements(spk, spv, spc, &purpose, xf, xf_in); + gids[0] = gid; + return 1; + } + else { + /* by layer type */ + int offs, has_offs; + pcb_layer_type_t lyt; + const pcb_virt_layer_t *vl; + + if (parse_layer_type(curr, &lyt, &offs, &has_offs) != 0) + return -1; + + pcb_parse_layer_supplements(spk, spv, spc, &purpose, xf, xf_in); + + vl = pcb_vlayer_get_first(lyt, purpose, -1); + if ((lyt & PCB_LYT_VIRTUAL) && (vl == NULL)) { + if (err_prefix != NULL) + rnd_message(RND_MSG_ERROR, "%sno virtual layer with purpose '%s'\n", err_prefix, purpose); + return -1; + } + if (vl == NULL) { + if (has_offs) { + int len = pcb_layergrp_listp(pcb, lyt, lgids, sizeof(lgids)/sizeof(lgids[0]), -1, purpose); + if (offs < 0) + offs = len + offs; + else + offs--; + if ((offs >= 0) && (offs < len)) { + gids[0] = lgids[offs]; + return 1; + } + } + else { + return pcb_layergrp_listp(pcb, lyt, gids, gids_max, -1, purpose); + } + } + else { + if (vid != NULL) + *vid = vl->new_id - PCB_LYT_VIRTUAL - 1; + } + } + return 0; +} + +static rnd_layer_id_t layer_str2id_data(pcb_board_t *pcb, pcb_data_t *data, const char *str) +{ + char *end; + rnd_layer_id_t id; + + if (*str == '#') { + id = strtol(str+1, &end, 10); + if ((*end == '\0') && (id >= 0) && (id < data->LayerN)) + return id; + } + if (*str == '@') { + for(id = 0; id < data->LayerN; id++) { + pcb_layer_t *ly = pcb_get_layer(data, id); + if (ly == NULL) continue; + if (strcmp(ly->name, str+1) == 0) + return id; + } + } + if (*str == '&') { + str++; + if (rnd_strcasecmp(str, "current") == 0) + return PCB_CURRLID(pcb); + } + return -1; +} + +static rnd_layer_id_t layer_str2id_grp(pcb_board_t *pcb, pcb_layergrp_t *grp, const char *str) +{ + char *end; + long id, n; + + if (*str == '#') { + str++; + id = strtol(str, &end, 10); + if ((*end == '+') || (*end == '-')) { /* search the nth positive or negative layer, count from 1 */ + int pos = (id > 0); + if (!pos) id = -id; + n = pos ? 0 : grp->len-1; + for(; (pos ? (n < grp->len) : (n >= 0));) { + pcb_layer_t *ly = pcb_get_layer(pcb->Data, grp->lid[n]); + if (ly == NULL) continue; + if ((*end == '-') && (ly->comb & PCB_LYC_SUB)) id--; + else if ((*end == '+') && !(ly->comb & PCB_LYC_SUB)) id--; + if (id == 0) + return grp->lid[n]; + if (pos) n++; + else n--; + } + return -1; /* not enough layers */ + } + /* simply the nth layer ID, counting from 1 */ + if ((*end == '\0') && (id > 0) && (id <= grp->len)) + return grp->lid[id - 1]; + if ((*end == '\0') && (id < 0) && (id >= -((long)grp->len))) + return grp->lid[id + grp->len]; + return -1; + } + if (*str == '@') { + for(n = 0; n < grp->len; n++) { + pcb_layer_t *ly = pcb_get_layer(pcb->Data, grp->lid[n]); + if (ly == NULL) continue; + if (strcmp(ly->name, str+1) == 0) + return grp->lid[n]; + } + } + return -1; +} + +rnd_layer_id_t pcb_layer_str2id(pcb_data_t *data, const char *str) +{ + char *sep; + pcb_board_t *pcb = NULL; + + if (data->parent_type == PCB_PARENT_BOARD) + pcb = data->parent.board; + + sep = strchr(str, '/'); + if (sep != NULL) { + rnd_layergrp_id_t gid; + pcb_layergrp_t *grp; + if (pcb == NULL) + return -1; /* group addressing works only on a board */ + gid = pcb_layergrp_str2id(pcb, str); + grp = pcb_get_layergrp(pcb, gid); + if (grp == NULL) + return -1; /* invalid group */ + return layer_str2id_grp(pcb, grp, sep+1); + } + + return layer_str2id_data(pcb, data, str); +} + +rnd_layergrp_id_t pcb_layergrp_str2id(pcb_board_t *pcb, const char *str) +{ + char *end, *tmp = NULL; + const char *curr; + rnd_layer_id_t gid = -1; + char *spk[64], *spv[64]; + int spc = 0, numg; + rnd_layergrp_id_t gids[PCB_MAX_LAYERGRP]; + + if (*str == '#') { + gid = strtol(str+1, &end, 10); + if ((*end != '\0') || (gid < 0) || (gid >= pcb->LayerGroups.len)) + return -1; + return gid; + } + + if (strchr(str, '(') != NULL) { + curr = tmp = rnd_strdup(str); + spc = sizeof(spk) / sizeof(spk[0]); + end = pcb_parse_layergrp_address(tmp, spk, spv, &spc); + if (end != NULL) { + free(tmp); + return -1; + } + } + else + curr = str; + + numg = pcb_layergrp_list_by_addr(pcb, curr, gids, spk, spv, spc, NULL, NULL, NULL, NULL); + if (numg > 0) + gid = gids[0]; + + free(tmp); + return gid; +} + +/*** layer/group to addr ***/ + +static void addr_append_loc_type(gds_t *res, pcb_layer_type_t mask) +{ + const char *tmp; + tmp = pcb_layer_type_bit2str(mask & PCB_LYT_ANYWHERE); + if (tmp != NULL) { + gds_append_str(res, tmp); + gds_append(res, '-'); + } + tmp = pcb_layer_type_bit2str(mask & PCB_LYT_ANYTHING); + if (tmp != NULL) + gds_append_str(res, tmp); +} + +/* append loc-type:offs */ +static int pcb_layergrp_append_to_addr_offs(pcb_board_t *pcb, pcb_layergrp_t *grp, gds_t *dst) +{ + char buf[64]; + long n, np = 0, nt = 0, offs, found = 0; + pcb_layer_type_t mask = grp->ltype & (PCB_LYT_ANYWHERE | PCB_LYT_ANYTHING); + + addr_append_loc_type(dst, grp->ltype); + + for(n = 0; n < pcb->LayerGroups.len; n++) { + pcb_layergrp_t *ng = &pcb->LayerGroups.grp[n]; + if (ng == grp) + found = 1; + if ((ng->ltype & (PCB_LYT_ANYWHERE | PCB_LYT_ANYTHING)) == mask) { + if (!found) + np++; + nt++; + } + } + /* np is the number of matching layer groups before grp, nt is the number + of matching groups total */ + if (mask & PCB_LYT_BOTTOM) + offs = -(nt-np); /* bottom groups are counted from the bottom */ + else if (mask & PCB_LYT_TOP) + offs = np+1; /* top groups are counted from top */ + else if (mask & PCB_LYT_INTERN) { /* intern groups are counted from the closer side */ + if (np < nt/2) + offs = np+1; + else + offs = -(nt-np); + } + else { /* global: count from "top" */ + offs = np+1; + } + sprintf(buf, ":%ld", offs); + gds_append_str(dst, buf); + return 0; +} + +/* append loc-type(purpose=...) */ +static int pcb_layergrp_append_to_addr_purp(pcb_board_t *pcb, pcb_layergrp_t *grp, gds_t *dst) +{ + addr_append_loc_type(dst, grp->ltype); + if (grp->purpose != NULL) { + gds_append_str(dst, "(purpose="); + gds_append_str(dst, grp->purpose); + gds_append(dst, ')'); + } + return 0; +} + +int pcb_layergrp_append_to_addr(pcb_board_t *pcb, pcb_layergrp_t *grp, gds_t *dst) +{ + if (PCB_LAYER_IN_STACK(grp->ltype)) + return pcb_layergrp_append_to_addr_offs(pcb, grp, dst); + return pcb_layergrp_append_to_addr_purp(pcb, grp, dst); +} + +int pcb_layer_append_to_addr(pcb_board_t *pcb, pcb_layer_t *ly, gds_t *dst) +{ + rnd_layer_id_t lid; + pcb_layergrp_t *grp; + long n; + char buf[64]; + + if (ly->is_bound) + return -1; + + grp = pcb_get_layergrp(pcb, ly->meta.real.grp); + if (grp == NULL) + return -1; + + lid = ly - pcb->Data->Layer; + + for(n = 0; n < grp->len; n++) { + if (grp->lid[n] == lid) { + pcb_layergrp_append_to_addr(pcb, grp, dst); + sprintf(buf, "/#%ld", n); + gds_append_str(dst, buf); + return 0; + } + } + + return -1; +} + +char *pcb_layergrp_to_addr(pcb_board_t *pcb, pcb_layergrp_t *grp) +{ + gds_t res; + gds_init(&res); + + if (pcb_layergrp_append_to_addr(pcb, grp, &res) == 0) + return res.array; + + gds_uninit(&res); + return NULL; +} + +char *pcb_layer_to_addr(pcb_board_t *pcb, pcb_layer_t *ly) +{ + gds_t res; + gds_init(&res); + + if (pcb_layer_append_to_addr(pcb, ly, &res) == 0) + return res.array; + + gds_uninit(&res); + return NULL; +} Index: tags/2.3.0/src/layer_addr.h =================================================================== --- tags/2.3.0/src/layer_addr.h (nonexistent) +++ tags/2.3.0/src/layer_addr.h (revision 33253) @@ -0,0 +1,52 @@ +#ifndef PCB_LAYER_ADDR_H +#define PCB_LAYER_ADDR_H + +#include "layer.h" +#include "layer_grp.h" + +/*** main API ***/ + +/* Convert a textual layer(grp) reference into a layer ID. The text is either + #id or a layer name. */ +rnd_layer_id_t pcb_layer_str2id(pcb_data_t *data, const char *str); +rnd_layergrp_id_t pcb_layergrp_str2id(pcb_board_t *pcb, const char *str); + +/* Convert a layer(grp) into a reusable address; returns NULL on error; + caller needs to free() the returned string */ +char *pcb_layer_to_addr(pcb_board_t *pcb, pcb_layer_t *ly); +char *pcb_layergrp_to_addr(pcb_board_t *pcb, pcb_layergrp_t *grp); + +/* Same, but append to dst instead of allocating new string; return 0 on + success */ +int pcb_layer_append_to_addr(pcb_board_t *pcb, pcb_layer_t *ly, gds_t *dst); +int pcb_layergrp_append_to_addr(pcb_board_t *pcb, pcb_layergrp_t *grp, gds_t *dst); + +/*** for internal use ***/ + +/* Parse a layer group address: split at comma, addr will end up holding the + layer name. If there were transformations in (), they are split and + listed in tr up to at most *spc entries. Returns NULL on error or + pointer to the next layer directive. */ +char *pcb_parse_layergrp_address(char *curr, char **spk, char **spv, int *spc); +extern char *pcb_parse_layergrp_err; + +void pcb_parse_layer_supplements(char **spk, char **spv, int spc, char **purpose, rnd_xform_t **xf, rnd_xform_t *xf_); + +/* parse addr into: + - a list of layer group IDs + - in case of a virtual group is addressed, return 0 and load vid if *vid is non-NULL + - load xf_in fields if there are transformations requested (if xf_in is not NULL) + - load *xf with xf_in if there are transformations requested (if xf is not NULL) + - if err_prefix is not NULL, use rnd_message() with this prefix to priont detailed error + Input: + - the address, without supplements or other suffixes, in addr + - parsed supplement key/value pairs are expected in spk/spv (at most spc items) + Returns: + - 0 for valid syntax if no matching group is found + - 0 for valid syntax if a virtual group is found (*vid is loaded if vid != NULL) + - a positive integer if 1 or more real matching groups are found + - -1 on error (typically syntax error) +*/ +int pcb_layergrp_list_by_addr(pcb_board_t *pcb, const char *addr, rnd_layergrp_id_t gids[PCB_MAX_LAYERGRP], char **spk, char **spv, int spc, int *vid, rnd_xform_t **xf, rnd_xform_t *xf_in, const char *err_prefix); + +#endif Index: tags/2.3.0/src/layer_grp.c =================================================================== --- tags/2.3.0/src/layer_grp.c (nonexistent) +++ tags/2.3.0/src/layer_grp.c (revision 33253) @@ -0,0 +1,1596 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2004,2006 Thomas Nau + * Copyright (C) 2016,2019,2020 Tibor 'Igor2' Palinkas (pcb-rnd extensions) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include "board.h" +#include "data.h" +#include "layer_grp.h" +#include +#include +#include "event.h" +#include +#include "funchash_core.h" +#include "undo.h" + +static const char core_layergrp_cookie[] = "core-layergrp"; + +/* notify the rest of the code after layer group changes so that the GUI + and other parts sync up */ +static int inhibit_notify = 0; +#define NOTIFY(pcb) \ +do { \ + pcb->LayerGroups.cache.copper_valid = 0; \ + if (!inhibit_notify) { \ + rnd_event(&pcb->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); \ + if ((rnd_gui != NULL) && (rnd_exporter == NULL)) \ + rnd_gui->invalidate_all(rnd_gui); \ + pcb_board_set_changed_flag(pcb, rnd_true); \ + } \ +} while(0) + +void pcb_layergrp_notify_chg(pcb_board_t *pcb) +{ + NOTIFY(pcb); +} + +void pcb_layergrp_inhibit_inc(void) +{ + inhibit_notify++; +} + +void pcb_layergrp_inhibit_dec(void) +{ + inhibit_notify--; +} + +void pcb_layergrp_notify(pcb_board_t *pcb) +{ + NOTIFY(pcb); +} + +rnd_layergrp_id_t pcb_layergrp_id(const pcb_board_t *pcb, const pcb_layergrp_t *grp) +{ + if ((grp >= &pcb->LayerGroups.grp[0]) && (grp < &pcb->LayerGroups.grp[pcb->LayerGroups.len])) + return grp - &pcb->LayerGroups.grp[0]; + return -1; +} + +rnd_layergrp_id_t pcb_layer_get_group_(pcb_layer_t *Layer) +{ + if (!Layer->is_bound) + return Layer->meta.real.grp; + + if (Layer->meta.bound.real == NULL) /* bound layer without a binding */ + return -1; + + return Layer->meta.bound.real->meta.real.grp; +} + +pcb_layergrp_t *pcb_get_layergrp(pcb_board_t *pcb, rnd_layergrp_id_t gid) +{ + if ((gid < 0) || (gid >= pcb->LayerGroups.len)) + return NULL; + return pcb->LayerGroups.grp + gid; +} + + +rnd_layergrp_id_t pcb_layer_get_group(pcb_board_t *pcb, rnd_layer_id_t lid) +{ + if ((lid < 0) || (lid >= pcb->Data->LayerN)) + return -1; + + return pcb_layer_get_group_(&pcb->Data->Layer[lid]); +} + +int pcb_layergrp_del_layer(pcb_board_t *pcb, rnd_layergrp_id_t gid, rnd_layer_id_t lid) +{ + int n; + pcb_layergrp_t *grp; + pcb_layer_t *layer; + + if ((lid < 0) || (lid >= pcb->Data->LayerN)) + return -1; + + layer = pcb->Data->Layer + lid; + if (gid < 0) { + gid = layer->meta.real.grp; + if (gid == -1) + return 0; /* already deleted from groups */ + } + if (gid >= pcb->LayerGroups.len) + return -1; + + grp = &pcb->LayerGroups.grp[gid]; + + if (layer->meta.real.grp != gid) + return -1; + + for(n = 0; n < grp->len; n++) { + if (grp->lid[n] == lid) { + int remain = grp->len - n - 1; + if (remain > 0) + memmove(&grp->lid[n], &grp->lid[n+1], remain * sizeof(rnd_layer_id_t)); + grp->len--; + layer->meta.real.grp = -1; + NOTIFY(pcb); + return 0; + } + } + + + /* also: broken layer group list */ + return -1; +} + +static void make_substrate(pcb_board_t *pcb, pcb_layergrp_t *g) +{ + g->ltype = PCB_LYT_INTERN | PCB_LYT_SUBSTRATE; + pcb_layergrp_setup(g, pcb); +} + +rnd_layergrp_id_t pcb_layergrp_dup(pcb_board_t *pcb, rnd_layergrp_id_t gid, int auto_substrate, rnd_bool undoable) +{ + pcb_layergrp_t *ng, *og = pcb_get_layergrp(pcb, gid); + rnd_layergrp_id_t after; + + if (og == NULL) + return -1; + + inhibit_notify++; + if (auto_substrate && (og->ltype & PCB_LYT_COPPER) && !(og->ltype & PCB_LYT_BOTTOM)) { + ng = pcb_layergrp_insert_after(pcb, gid); + make_substrate(pcb, ng); + after = ng - pcb->LayerGroups.grp; + if (undoable) pcb_layergrp_undoable_created(ng); + } + else + after = gid; + + ng = pcb_layergrp_insert_after(pcb, after); + if (og->name != NULL) + ng->name = rnd_strdup(og->name); + ng->ltype = og->ltype; + if (og->purpose != NULL) + ng->purpose = rnd_strdup(og->purpose); + ng->purpi = og->purpi; + ng->valid = ng->open = ng->vis = 1; + pcb_layergrp_setup(ng, pcb); + if (undoable) pcb_layergrp_undoable_created(ng); + + inhibit_notify--; + NOTIFY(pcb); + return ng - pcb->LayerGroups.grp; +} + + +rnd_layergrp_id_t pcb_layer_move_to_group(pcb_board_t *pcb, rnd_layer_id_t lid, rnd_layergrp_id_t gid) +{ + if (pcb_layergrp_del_layer(pcb, -1, lid) != 0) + return -1; + pcb_layer_add_in_group(pcb, lid, gid); + rnd_event(&pcb->hidlib, PCB_EVENT_LAYER_CHANGED_GRP, "p", &pcb->Data->Layer[lid]); + NOTIFY(pcb); + return gid; +} + +unsigned int pcb_layergrp_flags(const pcb_board_t *pcb, rnd_layergrp_id_t gid) +{ + + if ((gid < 0) || (gid >= pcb->LayerGroups.len)) + return 0; + + return pcb->LayerGroups.grp[gid].ltype; +} + +const char *pcb_layergrp_name(pcb_board_t *pcb, rnd_layergrp_id_t gid) +{ + + if ((gid < 0) || (gid >= pcb->LayerGroups.len)) + return 0; + + return pcb->LayerGroups.grp[gid].name; +} + +rnd_bool pcb_layergrp_is_empty(pcb_board_t *pcb, rnd_layergrp_id_t num) +{ + int i; + pcb_layergrp_t *g = &pcb->LayerGroups.grp[num]; + + /* some layers are never empty */ + if (g->ltype & PCB_LYT_MASK) + return rnd_false; + + if (!pcb_pstk_is_group_empty(pcb, num)) + return rnd_false; + + for (i = 0; i < g->len; i++) + if (!pcb_layer_is_empty(pcb, g->lid[i])) + return rnd_false; + return rnd_true; +} + +rnd_bool pcb_layergrp_is_pure_empty(pcb_board_t *pcb, rnd_layergrp_id_t num) +{ + int i; + pcb_layergrp_t *g = &pcb->LayerGroups.grp[num]; + + for (i = 0; i < g->len; i++) + if (!pcb_layer_is_pure_empty(pcb_get_layer(pcb->Data, g->lid[i]))) + return rnd_false; + return rnd_true; +} + +static void pcb_layergrp_free_fields(pcb_layergrp_t *g) +{ + free(g->name); + free(g->purpose); + g->name = g->purpose = NULL; + g->purpi = -1; +} + + +int pcb_layergrp_free(pcb_board_t *pcb, rnd_layergrp_id_t id) +{ + pcb_layer_stack_t *stack = &pcb->LayerGroups; + if ((id >= 0) && (id < stack->len)) { + int n; + pcb_layergrp_t *g = stack->grp + id; + for(n = 0; n < g->len; n++) { + pcb_layer_t *layer = pcb->Data->Layer + g->lid[n]; + layer->meta.real.grp = -1; + } + pcb_layergrp_free_fields(g); + memset(g, 0, sizeof(pcb_layergrp_t)); + return 0; + } + return -1; +} + +int pcb_layergrp_move_onto(pcb_board_t *pcb, rnd_layergrp_id_t dst, rnd_layergrp_id_t src) +{ + pcb_layer_stack_t *stack = &pcb->LayerGroups; + pcb_layergrp_t *d, *s; + int n; + + if ((src < 0) || (src >= stack->len)) + return -1; + if ((dst < stack->len) && (pcb_layergrp_free(pcb, dst) != 0)) + return -1; + d = stack->grp + dst; + s = stack->grp + src; + memcpy(d, s, sizeof(pcb_layergrp_t)); + + /* update layer's group refs to the new grp */ + for(n = 0; n < d->len; n++) { + pcb_layer_t *layer = pcb->Data->Layer + d->lid[n]; + layer->meta.real.grp = dst; + } + + memset(s, 0, sizeof(pcb_layergrp_t)); + NOTIFY(pcb); + return 0; +} + +pcb_layergrp_t *pcb_get_grp(pcb_layer_stack_t *stack, pcb_layer_type_t loc, pcb_layer_type_t typ) +{ + int n; + for(n = 0; n < stack->len; n++) + if ((stack->grp[n].ltype & loc) && (stack->grp[n].ltype & typ)) + return &(stack->grp[n]); + return NULL; +} + +pcb_layergrp_t *pcb_layergrp_insert_after(pcb_board_t *pcb, rnd_layergrp_id_t where) +{ + pcb_layer_stack_t *stack = &pcb->LayerGroups; + pcb_layergrp_t *g; + int n; + if ((where <= 0) || (where >= stack->len)) + return NULL; + + for(n = stack->len-1; n > where; n--) + pcb_layergrp_move_onto(pcb, n+1, n); + + stack->len++; + g = stack->grp+where+1; + PCB_SET_PARENT(g, board, pcb); + NOTIFY(pcb); + return g; +} + +static void layergrp_post_change(pcb_attribute_list_t *list, const char *name, const char *value) +{ + pcb_layergrp_t *g = (pcb_layergrp_t *)(((char *)list) - offsetof(pcb_layergrp_t, Attributes)); + + if (strcmp(name, "init-invis") == 0) { + int newv; + if ((value == NULL) || (*value == '\0')) + return; + if ((rnd_strcasecmp(value, "true") == 0) || (rnd_strcasecmp(value, "yes") == 0) || (rnd_strcasecmp(value, "on") == 0) || (strcmp(value, "1") == 0)) newv = 1; + else if ((rnd_strcasecmp(value, "false") == 0) || (rnd_strcasecmp(value, "no") == 0) || (rnd_strcasecmp(value, "off") == 0) || (strcmp(value, "0") == 0)) newv = 0; + else { + rnd_message(RND_MSG_ERROR, "unrecognized value '%s' of layer group %s's init-invis attribute", value, g->name == NULL ? "" : g->name); + return; + } + g->init_invis = newv; + } + +} + +void pcb_layergrp_setup(pcb_layergrp_t *g, pcb_board_t *parent) +{ + g->valid = 1; + g->parent_type = PCB_PARENT_BOARD; + g->parent.board = parent; + g->type = PCB_OBJ_LAYERGRP; + g->Attributes.post_change = layergrp_post_change; +} + +static pcb_layergrp_t *pcb_get_grp_new_intern_insert(pcb_board_t *pcb, int room, int bl, int omit_substrate) +{ + int n; + pcb_layer_stack_t *stack = &pcb->LayerGroups; + + if (bl < stack->len-1) + for(n = stack->len-1; n >= bl; n--) + pcb_layergrp_move_onto(pcb, n+room, n); + + stack->len += room; + + stack->grp[bl].name = rnd_strdup("Intern"); + stack->grp[bl].ltype = PCB_LYT_INTERN | PCB_LYT_COPPER; + stack->grp[bl].len = 0; + pcb_layergrp_setup(&stack->grp[bl], pcb); + bl++; + if (!omit_substrate) + make_substrate(pcb, &stack->grp[bl]); + return &stack->grp[bl-1]; +} + +static pcb_layergrp_t *pcb_get_grp_new_intern_(pcb_board_t *pcb, int omit_substrate, int force_end) +{ + pcb_layer_stack_t *stack = &pcb->LayerGroups; + int bl; + int room = omit_substrate ? 1 : 2; + + if ((stack->len + room) >= PCB_MAX_LAYERGRP) + return NULL; + + /* seek the bottom copper layer */ + if (!force_end) + for(bl = stack->len; bl >= 0; bl--) { + if ((stack->grp[bl].ltype & PCB_LYT_BOTTOM) && (stack->grp[bl].ltype & PCB_LYT_COPPER)) { + pcb_get_grp_new_intern_insert(pcb, room, bl, omit_substrate); + return &stack->grp[bl]; + } + } + + /* bottom copper did not exist - insert at the end */ + bl = stack->len; + pcb_get_grp_new_intern_insert(pcb, room, bl, omit_substrate); + return &stack->grp[bl]; +} + +pcb_layergrp_t *pcb_get_grp_new_intern(pcb_board_t *pcb, int intern_id) +{ + pcb_layer_stack_t *stack = &pcb->LayerGroups; + pcb_layergrp_t *g; + + if (intern_id > 0) { /* look for existing intern layer first */ + int n; + for(n = 0; n < stack->len; n++) + if (stack->grp[n].intern_id == intern_id) + return &stack->grp[n]; + } + + inhibit_notify++; + g = pcb_get_grp_new_intern_(pcb, 0, 0); + inhibit_notify--; + if (g != NULL) { + g->intern_id = intern_id; + NOTIFY(pcb); + } + return g; +} + +pcb_layergrp_t *pcb_get_grp_new_misc(pcb_board_t *pcb) +{ + pcb_layergrp_t *g; + inhibit_notify++; + g = pcb_get_grp_new_intern_(pcb, 1, 0); + inhibit_notify--; + NOTIFY(pcb); + return g; +} + +pcb_layergrp_t *pcb_get_grp_new_raw(pcb_board_t *pcb, int prepend) +{ + pcb_layergrp_t *g; + inhibit_notify++; + g = pcb_get_grp_new_intern_insert(pcb, 1, prepend ? 0 : pcb->LayerGroups.len, 1); + inhibit_notify--; + NOTIFY(pcb); + return g; +} + + +/* Move an inclusive block of groups [from..to] by delta on the stack, assuming + target is already cleared and the new hole will be cleared by the caller */ +static void move_grps(pcb_board_t *pcb, pcb_layer_stack_t *stk, rnd_layergrp_id_t from, rnd_layergrp_id_t to, int delta) +{ + int g, remaining, n; + + for(g = from; g <= to; g++) { + for(n = 0; n < stk->grp[g].len; n++) { + rnd_layer_id_t lid =stk->grp[g].lid[n]; + if ((lid >= 0) && (lid < pcb->Data->LayerN)) { + pcb_layer_t *l = &pcb->Data->Layer[lid]; + if (l->meta.real.grp > 0) + l->meta.real.grp += delta; + } + } + } + + remaining = to - from+1; + if (remaining > 0) + memmove(&stk->grp[from + delta], &stk->grp[from], sizeof(pcb_layergrp_t) * remaining); +} + +int pcb_layergrp_index_in_grp(pcb_layergrp_t *grp, rnd_layer_id_t lid) +{ + int idx; + for(idx = 0; idx < grp->len; idx++) + if (grp->lid[idx] == lid) + return idx; + return -1; +} + +/*** undoable step within the group ***/ + +static int pcb_layergrp_step_layer_(pcb_board_t *pcb, pcb_layergrp_t *grp, rnd_layer_id_t lid, int delta) +{ + int idx, idx2; + rnd_layer_id_t tmp; + + for(idx = 0; idx < grp->len; idx++) { + if (grp->lid[idx] == lid) { + if (delta > 0) { + if (idx == grp->len - 1) /* already the last */ + return 0; + idx2 = idx+1; + goto swap; + } + else if (delta < 0) { + if (idx == 0) /* already the last */ + return 0; + idx2 = idx-1; + goto swap; + } + else + return -1; + } + } + return -1; + + swap:; + tmp = grp->lid[idx]; + grp->lid[idx] =grp->lid[idx2]; + grp->lid[idx2] = tmp; + NOTIFY(pcb); + return 0; +} + +typedef struct { + pcb_board_t *pcb; + rnd_layergrp_id_t gid; + rnd_layer_id_t lid; + int delta; +} undo_layergrp_steply_t; + +static int undo_layergrp_steply_swap(void *udata) +{ + undo_layergrp_steply_t *s = udata; + int res; + pcb_layergrp_t *grp = pcb_get_layergrp(s->pcb, s->gid); + if (grp == NULL) return -1; + res = pcb_layergrp_step_layer_(s->pcb, grp, s->lid, s->delta); + if (res == 0) + s->delta = -s->delta; + return res; +} + +static void undo_layergrp_steply_print(void *udata, char *dst, size_t dst_len) +{ + undo_layergrp_steply_t *s = udata; + rnd_snprintf(dst, dst_len, "step layer in grp: #%ld/#%ld: %+d", s->gid, s->lid, s->delta); +} + +static const uundo_oper_t undo_layergrp_steply = { + core_layergrp_cookie, + NULL, + undo_layergrp_steply_swap, + undo_layergrp_steply_swap, + undo_layergrp_steply_print +}; + +int pcb_layergrp_step_layer(pcb_board_t *pcb, pcb_layergrp_t *grp, rnd_layer_id_t lid, int delta) +{ + undo_layergrp_steply_t *s = pcb_undo_alloc(pcb, &undo_layergrp_steply, sizeof(undo_layergrp_steply_t)); + int res; + + s->pcb = pcb; + s->gid = grp - pcb->LayerGroups.grp; + s->lid = lid; + s->delta = delta; + res = undo_layergrp_steply_swap(s); + pcb_undo_inc_serial(); + return res; +} + + +static void grp_move_struct(pcb_layergrp_t *dst, pcb_layergrp_t *src) +{ + *dst = *src; + memset(src, 0, sizeof(pcb_layergrp_t)); +} + +static void pcb_layergrp_del_1(pcb_board_t *pcb, rnd_layergrp_id_t gid, int del_layers, rnd_bool undoable) +{ + int n; + pcb_layer_stack_t *stk = &pcb->LayerGroups; + + for(n = 0; n < stk->grp[gid].len; n++) { + pcb_layer_t *l = pcb_get_layer(pcb->Data, stk->grp[gid].lid[n]); + if (l != NULL) { + if (del_layers) { + pcb_layer_move(pcb, stk->grp[gid].lid[n], -1, -1, undoable); + n = -1; /* restart counting because the layer remove code may have changed the order */ + } + else { + /* detach only */ + l->meta.real.grp = -1; + } + } + } +} + +static void pcb_layergrp_del_2(pcb_board_t *pcb, rnd_layergrp_id_t gid) +{ + pcb_layer_stack_t *stk = &pcb->LayerGroups; + + pcb_layergrp_free(pcb, gid); + move_grps(pcb, stk, gid+1, stk->len-1, -1); + stk->len--; + NOTIFY(pcb); +} + +static void pcb_layergrp_ins(pcb_board_t *pcb, rnd_layergrp_id_t gid, pcb_layergrp_t *src) +{ + pcb_layer_stack_t *stk = &pcb->LayerGroups; + move_grps(pcb, stk, gid, stk->len-1, +1); + stk->len++; + grp_move_struct(&stk->grp[gid], src); + NOTIFY(pcb); +} + + +typedef struct { + pcb_board_t *pcb; + rnd_layergrp_id_t gid; + unsigned int del:1; + pcb_layergrp_t save; +} undo_layergrp_del_t; + +static int undo_layergrp_del_swap(void *udata) +{ + undo_layergrp_del_t *r = udata; + pcb_layer_stack_t *stk = &r->pcb->LayerGroups; + + if (r->del) { /* undo a delete by inserting the group back at its place */ + pcb_layergrp_ins(r->pcb, r->gid, &r->save); + } + else { /* redo delete */ + pcb_layergrp_del_1(r->pcb, r->gid, 1, 0); + grp_move_struct(&r->save, &stk->grp[r->gid]); + pcb_layergrp_del_2(r->pcb, r->gid); + } + + r->del = !r->del; + return 0; +} + +static void undo_layergrp_del_free(void *udata) +{ + undo_layergrp_del_t *r = udata; + pcb_layergrp_free_fields(&r->save); +} + + +static void undo_layergrp_del_print(void *udata, char *dst, size_t dst_len) +{ + undo_layergrp_del_t *r = udata; + rnd_snprintf(dst, dst_len, "layergrp %s: '%s'", r->del ? "delete" : "insert", r->del ? r->save.name : pcb_layergrp_name(r->pcb, r->gid)); +} + +static const uundo_oper_t undo_layergrp_del = { + core_layergrp_cookie, + undo_layergrp_del_free, + undo_layergrp_del_swap, + undo_layergrp_del_swap, + undo_layergrp_del_print +}; + + +int pcb_layergrp_del(pcb_board_t *pcb, rnd_layergrp_id_t gid, int del_layers, rnd_bool undoable) +{ + undo_layergrp_del_t *r; + pcb_layer_stack_t *stk = &pcb->LayerGroups; + + if ((gid < 0) || (gid >= stk->len)) + return -1; + + if (!undoable || !del_layers) { + pcb_layergrp_del_1(pcb, gid, del_layers, undoable); + pcb_layergrp_del_2(pcb, gid); + return 0; + } + + /* undoable */ + pcb_undo_freeze_serial(); + pcb_layergrp_del_1(pcb, gid, 1, 1); + r = pcb_undo_alloc(pcb, &undo_layergrp_del, sizeof(undo_layergrp_del_t)); + r->pcb = pcb; + r->gid = gid; + r->del = 1; + grp_move_struct(&r->save, &stk->grp[gid]); + pcb_layergrp_del_2(pcb, gid); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + return 0; +} + +void pcb_layergrp_undoable_created(pcb_layergrp_t *grp) +{ + pcb_board_t *pcb = grp->parent.board; + undo_layergrp_del_t *r; + + assert(grp->parent_type == PCB_PARENT_BOARD); + r = pcb_undo_alloc(pcb, &undo_layergrp_del, sizeof(undo_layergrp_del_t)); + memset(r, 0, sizeof(undo_layergrp_del_t)); + r->pcb = pcb; + r->gid = grp - pcb->LayerGroups.grp; + r->del = 0; + pcb_undo_inc_serial(); +} + +int pcb_layergrp_move(pcb_board_t *pcb, rnd_layergrp_id_t from, rnd_layergrp_id_t to_before) +{ + pcb_layer_stack_t *stk = &pcb->LayerGroups; + pcb_layergrp_t tmp; + int n; + + if ((from < 0) || (from >= stk->len)) + return -1; + + if ((to_before < 0) || (to_before >= stk->len)) + return -1; + + if ((to_before == from + 1) || (to_before == from)) + return 0; + + memcpy(&tmp, &stk->grp[from], sizeof(pcb_layergrp_t)); + memset(&stk->grp[from], 0, sizeof(pcb_layergrp_t)); + if (to_before < from + 1) { + move_grps(pcb, stk, to_before, from-1, +1); + memcpy(&stk->grp[to_before], &tmp, sizeof(pcb_layergrp_t)); + } + else { + move_grps(pcb, stk, from+1, to_before-1, -1); + memcpy(&stk->grp[to_before-1], &tmp, sizeof(pcb_layergrp_t)); + } + + /* fix up the group id for the layers of the group moved */ + for(n = 0; n < stk->grp[to_before].len; n++) { + pcb_layer_t *l = pcb_get_layer(pcb->Data, stk->grp[to_before].lid[n]); + if ((l != NULL) && (l->meta.real.grp > 0)) + l->meta.real.grp = to_before; + } + + NOTIFY(pcb); + return 0; +} + + + /* ugly hack: remove the extra substrate we added after the outline layer */ +void pcb_layergrp_fix_old_outline(pcb_board_t *pcb) +{ + pcb_layer_stack_t *LayerGroup = &pcb->LayerGroups; + pcb_layergrp_t *g = pcb_get_grp(LayerGroup, PCB_LYT_ANYWHERE, PCB_LYT_BOUNDARY); + if ((g != NULL) && (g[1].ltype & PCB_LYT_SUBSTRATE)) { + rnd_layergrp_id_t gid = g - LayerGroup->grp + 1; + pcb_layergrp_del(pcb, gid, 0, 0); + } +} + +void pcb_layergrp_fix_turn_to_outline(pcb_layergrp_t *g) +{ + g->ltype |= PCB_LYT_BOUNDARY; + g->ltype &= ~PCB_LYT_COPPER; + g->ltype &= ~(PCB_LYT_ANYWHERE); + free(g->name); + g->name = rnd_strdup("global_outline"); + pcb_layergrp_set_purpose__(g, rnd_strdup("uroute"), 0); +} + + +/* old outline rules from geda/pcb */ +#define LAYER_IS_OUTLINE(idx) ((pcb->Data->Layer[idx].name != NULL) && ((strcmp(pcb->Data->Layer[idx].name, "route") == 0 || rnd_strcasecmp(pcb->Data->Layer[(idx)].name, "outline") == 0))) + +void pcb_layergrp_fix_old_outline_detect(pcb_board_t *pcb, pcb_layergrp_t *g) +{ + int n, converted = 0; + + for(n = 0; n < g->len; n++) { + if (g->lid[n] < 0) + continue; + if (LAYER_IS_OUTLINE(g->lid[n])) { + if (!converted) { + pcb_layergrp_fix_turn_to_outline(g); + converted = 1; + break; + } + } + } + + if (converted) { + for(n = 0; n < g->len; n++) + pcb->Data->Layer[g->lid[n]].comb = PCB_LYC_AUTO; + } +} + +int pcb_layer_gui_set_layer(rnd_layergrp_id_t gid, const pcb_layergrp_t *grp, int is_empty, rnd_xform_t **xform) +{ + /* if there's no GUI, that means no draw should be done */ + if (rnd_gui == NULL) + return 0; + + if (xform != NULL) + *xform = NULL; + + if (rnd_render->set_layer_group != NULL) + return rnd_render->set_layer_group(rnd_gui, gid, grp->purpose, grp->purpi, grp->lid[0], grp->ltype, is_empty, xform); + + /* if the GUI doesn't have a set_layer, assume it wants to draw all layers */ + return 1; +} + +int pcb_layer_gui_set_glayer(pcb_board_t *pcb, rnd_layergrp_id_t grp, int is_empty, rnd_xform_t **xform) +{ + return pcb_layer_gui_set_layer(grp, &pcb->LayerGroups.grp[grp], is_empty, xform); +} + +#define APPEND(n) \ + do { \ + if (res != NULL) { \ + if (used < res_len) { \ + res[used] = n; \ + used++; \ + } \ + } \ + else \ + used++; \ + } while(0) + +int pcb_layergrp_list(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layergrp_id_t *res, int res_len) +{ + int group, used = 0; + for (group = 0; group < pcb->LayerGroups.len; group++) { + if ((pcb_layergrp_flags(pcb, group) & mask) == mask) + APPEND(group); + } + return used; +} + +int pcb_layergrp_listp(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layergrp_id_t *res, int res_len, int purpi, const char *purpose) +{ + int group, used = 0; + const pcb_layergrp_t *g; + for (group = 0, g = pcb->LayerGroups.grp; group < pcb->LayerGroups.len; group++,g++) { + if ((pcb_layergrp_flags(pcb, group) & mask) == mask) { + if (((purpose == NULL) || ((g->purpose != NULL) && (strcmp(purpose, g->purpose) == 0))) && ((purpi == -1) || (purpi == g->purpi))) { + APPEND(group); + } + } + } + return used; +} + +int pcb_layergrp_list_any(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layergrp_id_t *res, int res_len) +{ + int group, used = 0; + for (group = 0; group < pcb->LayerGroups.len; group++) { + if ((pcb_layergrp_flags(pcb, group) & mask)) + APPEND(group); + } + return used; +} + +int pcb_layer_add_in_group_(pcb_board_t *pcb, pcb_layergrp_t *grp, rnd_layergrp_id_t group_id, rnd_layer_id_t layer_id) +{ + if ((layer_id < 0) || (layer_id >= pcb->Data->LayerN)) + return -1; + + grp->lid[grp->len] = layer_id; + grp->len++; + pcb->Data->Layer[layer_id].meta.real.grp = group_id; + + return 0; +} + +int pcb_layer_add_in_group(pcb_board_t *pcb, rnd_layer_id_t layer_id, rnd_layergrp_id_t group_id) +{ + if ((group_id < 0) || (group_id >= pcb->LayerGroups.len)) + return -1; + + return pcb_layer_add_in_group_(pcb, &pcb->LayerGroups.grp[group_id], group_id, layer_id); +} + +#define NEWG(g, flags, gname, pcb) \ +do { \ + g = &(newg->grp[newg->len]); \ + pcb_layergrp_setup(g, pcb); \ + if (gname != NULL) \ + g->name = rnd_strdup(gname); \ + else \ + g->name = NULL; \ + g->ltype = flags; \ + newg->len++; \ +} while(0) + +void pcb_layer_group_setup_default(pcb_board_t *pcb) +{ + pcb_layer_stack_t *newg = &pcb->LayerGroups; + pcb_layergrp_t *g; + + memset(newg, 0, sizeof(pcb_layer_stack_t)); + + NEWG(g, PCB_LYT_TOP | PCB_LYT_PASTE, "top_paste", pcb); + NEWG(g, PCB_LYT_TOP | PCB_LYT_SILK, "top_silk", pcb); + NEWG(g, PCB_LYT_TOP | PCB_LYT_MASK, "top_mask", pcb); + NEWG(g, PCB_LYT_TOP | PCB_LYT_COPPER, "top_copper", pcb); + NEWG(g, PCB_LYT_INTERN | PCB_LYT_SUBSTRATE, NULL, pcb); + + NEWG(g, PCB_LYT_BOTTOM | PCB_LYT_COPPER, "bottom_copper", pcb); + NEWG(g, PCB_LYT_BOTTOM | PCB_LYT_MASK, "bottom_mask", pcb); + NEWG(g, PCB_LYT_BOTTOM | PCB_LYT_SILK, "bottom_silk", pcb); + NEWG(g, PCB_LYT_BOTTOM | PCB_LYT_PASTE, "bottom_paste", pcb); + +/* NEWG(g, PCB_LYT_INTERN | PCB_LYT_BOUNDARY, "outline");*/ +} + +void pcb_layer_group_setup_silks(pcb_board_t *pcb) +{ + rnd_layergrp_id_t gid; + for(gid = 0; gid < pcb->LayerGroups.len; gid++) + if ((pcb->LayerGroups.grp[gid].ltype & PCB_LYT_SILK) && (pcb->LayerGroups.grp[gid].len == 0)) + pcb_layer_create(pcb, gid, "silk", 0); +} + +/*** undoable rename ***/ + +typedef struct { + pcb_layergrp_t *grp; + char *name; +} undo_layergrp_rename_t; + +static int undo_layergrp_rename_swap(void *udata) +{ + char *old; + undo_layergrp_rename_t *r = udata; + + old = (char *)r->grp->name; + r->grp->name = r->name; + r->name = old; + + rnd_event(&r->grp->parent.board->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + return 0; +} + +static void undo_layergrp_rename_print(void *udata, char *dst, size_t dst_len) +{ + undo_layergrp_rename_t *r = udata; + rnd_snprintf(dst, dst_len, "rename layergrp: '%s' -> '%s'", r->grp->name, r->name); +} + +static void undo_layergrp_rename_free(void *udata) +{ + undo_layergrp_rename_t *r = udata; + free(r->name); +} + + +static const uundo_oper_t undo_layergrp_rename = { + core_layergrp_cookie, + undo_layergrp_rename_free, + undo_layergrp_rename_swap, + undo_layergrp_rename_swap, + undo_layergrp_rename_print +}; + + +int pcb_layergrp_rename_(pcb_layergrp_t *grp, char *name, rnd_bool undoable) +{ + undo_layergrp_rename_t rtmp, *r = &rtmp; + + assert(grp->parent_type == PCB_PARENT_BOARD); + + if (undoable) + r = pcb_undo_alloc(grp->parent.board, &undo_layergrp_rename, sizeof(undo_layergrp_rename_t)); + + r->grp = grp; + r->name = name; + + undo_layergrp_rename_swap(r); + if (undoable) + pcb_undo_inc_serial(); + else + undo_layergrp_rename_free(r); + + return 0; +} + +int pcb_layergrp_rename(pcb_board_t *pcb, rnd_layergrp_id_t gid, const char *name, rnd_bool undoable) +{ + pcb_layergrp_t *grp = pcb_get_layergrp(pcb, gid); + if (grp == NULL) return -1; + return pcb_layergrp_rename_(grp, rnd_strdup(name), undoable); +} + +/*** undoable set-purpose ***/ + +typedef struct { + pcb_layergrp_t *grp; + char *purps; + int purpi; +} undo_layergrp_repurp_t; + +static int undo_layergrp_repurp_swap(void *udata) +{ + char *olds; + int oldi; + undo_layergrp_repurp_t *r = udata; + + olds = (char *)r->grp->purpose; + oldi = r->grp->purpi; + r->grp->purpose = r->purps; + r->grp->purpi = r->purpi; + r->purps = olds; + r->purpi = oldi; + + return 0; +} + +static void undo_layergrp_repurp_print(void *udata, char *dst, size_t dst_len) +{ + undo_layergrp_repurp_t *r = udata; + rnd_snprintf(dst, dst_len, "repurpose layergrp: '%s' -> '%s'", r->grp->purpose, r->purps); +} + +static void undo_layergrp_repurp_free(void *udata) +{ + undo_layergrp_repurp_t *r = udata; + free(r->purps); +} + + +static const uundo_oper_t undo_layergrp_repurp = { + core_layergrp_cookie, + undo_layergrp_repurp_free, + undo_layergrp_repurp_swap, + undo_layergrp_repurp_swap, + undo_layergrp_repurp_print +}; + + +int pcb_layergrp_set_purpose__(pcb_layergrp_t *grp, char *purpose, rnd_bool undoable) +{ + undo_layergrp_repurp_t rtmp, *r = &rtmp; + + if (undoable) + r = pcb_undo_alloc(grp->parent.board, &undo_layergrp_repurp, sizeof(undo_layergrp_repurp_t)); + + r->grp = grp; + if (purpose == NULL) { + r->purps = NULL; + r->purpi = F_user; + } + else { + r->purps = purpose; + r->purpi = rnd_funchash_get(purpose, NULL); + if (r->purpi < 0) + r->purpi = F_user; + } + + undo_layergrp_repurp_swap(r); + if (undoable) + pcb_undo_inc_serial(); + else + undo_layergrp_repurp_free(r); + + return 0; +} + +int pcb_layergrp_set_purpose_(pcb_layergrp_t *lg, char *purpose, rnd_bool undoable) +{ + int ret = pcb_layergrp_set_purpose__(lg, purpose, undoable); + assert(lg->parent_type == PCB_PARENT_BOARD); + rnd_event(&lg->parent.board->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + return ret; +} + +int pcb_layergrp_set_purpose(pcb_layergrp_t *lg, const char *purpose, rnd_bool undoable) +{ + return pcb_layergrp_set_purpose_(lg, rnd_strdup(purpose), undoable); +} + +/*** undoable flags/type set ***/ + +typedef struct { + pcb_layergrp_t *grp; + pcb_layer_type_t ltype; +} undo_layergrp_ltype_t; + +static int undo_layergrp_ltype_swap(void *udata) +{ + pcb_layer_type_t old; + undo_layergrp_ltype_t *r = udata; + + old = r->grp->ltype; + r->grp->ltype = r->ltype; + r->ltype = old; + + return 0; +} + +static void undo_layergrp_ltype_print(void *udata, char *dst, size_t dst_len) +{ + undo_layergrp_ltype_t *r = udata; + rnd_snprintf(dst, dst_len, "layergrp type: '%lx' -> '%lx'", r->grp->ltype, r->ltype); +} + +static const uundo_oper_t undo_layergrp_ltype = { + core_layergrp_cookie, + NULL, + undo_layergrp_ltype_swap, + undo_layergrp_ltype_swap, + undo_layergrp_ltype_print +}; + + + +int pcb_layergrp_set_ltype(pcb_layergrp_t *grp, pcb_layer_type_t lyt, rnd_bool undoable) +{ + undo_layergrp_ltype_t rtmp, *r = &rtmp; + + if (undoable) + r = pcb_undo_alloc(grp->parent.board, &undo_layergrp_ltype, sizeof(undo_layergrp_ltype_t)); + + r->grp = grp; + r->ltype = lyt; + + undo_layergrp_ltype_swap(r); + if (undoable) + pcb_undo_inc_serial(); + + return 0; + +} + +rnd_layergrp_id_t pcb_layergrp_by_name(pcb_board_t *pcb, const char *name) +{ + rnd_layergrp_id_t n; + for (n = 0; n < pcb->LayerGroups.len; n++) + if ((pcb->LayerGroups.grp[n].name != NULL) && (strcmp(pcb->LayerGroups.grp[n].name, name) == 0)) + return n; + return -1; +} + +int pcb_layergrp_dist(pcb_board_t *pcb, rnd_layergrp_id_t gid1, rnd_layergrp_id_t gid2, pcb_layer_type_t mask, int *diff) +{ + int gid, d, cnt; + + if ((gid1 < 0) || (gid2 < 0)) + return -1; + if (gid1 == gid2) { + *diff = 0; + return 0; + } + + d = (gid1 < gid2) ? +1 : -1; + cnt = 0; + for(gid = gid1; gid != gid2; gid += d) { + if ((gid < 0) || (gid >= pcb->LayerGroups.len)) + return -1; + if ((pcb->LayerGroups.grp[gid].ltype & mask) == mask) + cnt++; + } + *diff = cnt; + return 0; +} + +rnd_layergrp_id_t pcb_layergrp_step(pcb_board_t *pcb, rnd_layergrp_id_t gid, int steps, pcb_layer_type_t mask) +{ + int d; + + if (gid < 0) + return -1; + + if (steps == 0) + return gid; + + if (steps < 0) { + d = -1; + steps = -steps; + } + else + d = 1; + + for(gid += d;; gid += d) { + if ((gid < 0) || (gid >= pcb->LayerGroups.len)) + return -1; + if ((pcb->LayerGroups.grp[gid].ltype & mask) == mask) { + steps--; + if (steps == 0) + return gid; + } + } + return -1; +} + +void pcb_layergrp_create_missing_substrate(pcb_board_t *pcb) +{ + rnd_layergrp_id_t g; + for(g = 0; g < ((rnd_layergrp_id_t)pcb->LayerGroups.len)-2; g++) { + pcb_layergrp_t *g0 = &pcb->LayerGroups.grp[g], *g1 = &pcb->LayerGroups.grp[g+1]; + if ((g < ((rnd_layergrp_id_t)pcb->LayerGroups.len)-3) && (g1->ltype & PCB_LYT_BOUNDARY)) g1++; + if ((g0->ltype & PCB_LYT_COPPER) && (g1->ltype & PCB_LYT_COPPER)) { + pcb_layergrp_t *ng = pcb_layergrp_insert_after(pcb, g); + ng->ltype = PCB_LYT_INTERN | PCB_LYT_SUBSTRATE; + ng->name = rnd_strdup("implicit_subst"); + pcb_layergrp_setup(ng, pcb); + } + } +} + +int pcb_layer_create_all_for_recipe(pcb_board_t *pcb, pcb_layer_t *layer, int num_layer) +{ + int n, existing_intern = 0, want_intern = 0; + static char *anon = "anon"; + + for(n = 0; n < pcb->LayerGroups.len; n++) + if ((pcb->LayerGroups.grp[n].ltype & PCB_LYT_COPPER) && (pcb->LayerGroups.grp[n].ltype & PCB_LYT_INTERN)) + existing_intern++; + + for(n = 0; n < num_layer; n++) { + pcb_layer_t *ly = layer + n; + pcb_layer_t *dst = pcb_layer_resolve_binding(pcb, ly); + pcb_layergrp_t *grp; + + if ((ly->meta.bound.type & PCB_LYT_COPPER) && (ly->meta.bound.type & PCB_LYT_INTERN)) { + want_intern++; + continue; + } + + if (dst != NULL) + continue; + + if (ly->meta.bound.type & PCB_LYT_VIRTUAL) { + /* no chance to have this yet */ + continue; + } + + if (ly->meta.bound.type & PCB_LYT_BOUNDARY) { + pcb_layergrp_t *grp = pcb_get_grp_new_misc(pcb); + rnd_layer_id_t nlid; + pcb_layer_t *nly; + grp->ltype = PCB_LYT_BOUNDARY; + grp->name = rnd_strdup("outline"); + if (ly->meta.bound.purpose != NULL) + pcb_layergrp_set_purpose__(grp, rnd_strdup(ly->meta.bound.purpose), 0); + nlid = pcb_layer_create(pcb, pcb_layergrp_id(pcb, grp), ly->name, 0); + nly = pcb_get_layer(pcb->Data, nlid); + if (nly != NULL) + nly->comb = ly->comb; + continue; + } + + + if (ly->meta.bound.type & PCB_LYT_COPPER) { /* top or bottom copper */ + grp = pcb_get_grp(&pcb->LayerGroups, ly->meta.bound.type & PCB_LYT_ANYWHERE, PCB_LYT_COPPER); + if (grp != NULL) { + pcb_layer_create(pcb, pcb_layergrp_id(pcb, grp), ly->name, 0); + continue; + } + } + + grp = pcb_get_grp(&pcb->LayerGroups, ly->meta.bound.type & PCB_LYT_ANYWHERE, ly->meta.bound.type & PCB_LYT_ANYTHING); + if (grp != NULL) { + rnd_layer_id_t lid = pcb_layer_create(pcb, pcb_layergrp_id(pcb, grp), ly->name, 0); + pcb_layer_t *nly = pcb_get_layer(pcb->Data, lid); + nly->comb = ly->comb; + continue; + } + + if (!((ly->meta.bound.type & PCB_LYT_DOC) || (ly->meta.bound.type & PCB_LYT_MECH))) /* doc layers are created later */ + rnd_message(RND_MSG_ERROR, "Failed to create layer from recipe %s\n", ly->name); + } + + if (want_intern > existing_intern) { + int int_ofs = 0; +/*rnd_trace("want: %d have: %d\n", want_intern, existing_intern);*/ + /* create enough dummy internal layers, mark them by name anon */ + while(want_intern > existing_intern) { + pcb_layergrp_t *grp = pcb_get_grp_new_intern(pcb, -1); + grp->name = anon; + existing_intern++; + } + /* rename new interns from the recipe layer names */ + for(n = 0; n < pcb->LayerGroups.len; n++) { + if (pcb->LayerGroups.grp[n].name == anon) { + int m; + int_ofs++; + for(m = 0; m < num_layer; m++) { + pcb_layer_t *ly = layer + m; + if ((ly->meta.bound.type & PCB_LYT_COPPER) && (ly->meta.bound.type & PCB_LYT_INTERN)) { + int offs = ly->meta.bound.stack_offs; +/*rnd_trace("offs: %d (%d) == %d\n", offs, existing_intern + offs + 1, int_ofs);*/ + if (offs < 0) + offs = existing_intern + offs + 1; + if ((offs == int_ofs) && (ly->name != NULL)) { + pcb->LayerGroups.grp[n].name = rnd_strdup("internal"); + pcb_layer_create(pcb, n, ly->name, 0); + goto found; + } + } + } + pcb->LayerGroups.grp[n].name = rnd_strdup("anon-recipe"); + found:; + } + } + } + + + /* create doc and mech layers */ + for(n = 0; n < num_layer; n++) { + pcb_layer_t *ly = layer + n; + if ((ly->meta.bound.type & PCB_LYT_DOC) || (ly->meta.bound.type & PCB_LYT_MECH)) { + pcb_layergrp_t *grp = pcb_get_grp_new_misc(pcb); + if (grp != NULL) { + grp->ltype = ly->meta.bound.type; + grp->name = rnd_strdup(ly->name); + pcb_layer_create(pcb, pcb_layergrp_id(pcb, grp), ly->name, 0); + pcb_layer_resolve_binding(pcb, ly); + } + } + } + return 0; +} + +void pcb_layergroup_free_stack(pcb_layer_stack_t *st) +{ + int n; + + for(n = 0; n < st->len; n++) + pcb_layergrp_free_fields(st->grp + n); + + free(st->cache.copper); + st->cache.copper = NULL; + st->cache.copper_len = st->cache.copper_alloced = 0; +} + +const pcb_dflgmap_t pcb_dflg_top_noncop[] = { + {"top_paste", PCB_LYT_TOP | PCB_LYT_PASTE, NULL, PCB_LYC_AUTO, 0}, + {"top_silk", PCB_LYT_TOP | PCB_LYT_SILK, NULL, PCB_LYC_AUTO, 0}, + {"top_mask", PCB_LYT_TOP | PCB_LYT_MASK, NULL, PCB_LYC_SUB | PCB_LYC_AUTO, 0}, + {NULL, 0} +}; + +const pcb_dflgmap_t pcb_dflg_bot_noncop[] = { + {"bottom_mask", PCB_LYT_BOTTOM | PCB_LYT_MASK, NULL, PCB_LYC_SUB | PCB_LYC_AUTO, PCB_DFLGMAP_FORCE_END}, + {"bottom_silk", PCB_LYT_BOTTOM | PCB_LYT_SILK, NULL, PCB_LYC_AUTO, PCB_DFLGMAP_FORCE_END}, + {"bottom_paste", PCB_LYT_BOTTOM | PCB_LYT_PASTE, NULL, PCB_LYC_AUTO, PCB_DFLGMAP_FORCE_END}, + {NULL, 0} +}; + +const pcb_dflgmap_t pcb_dflg_glob_noncop[] = { + {"outline", PCB_LYT_BOUNDARY, "uroute", 0, 0}, + {"pmech", PCB_LYT_MECH, "proute", PCB_LYC_AUTO, 0}, + {"umech", PCB_LYT_MECH, "uroute", PCB_LYC_AUTO, 0}, + {NULL, 0} +}; + +const pcb_dflgmap_t pcb_dflgmap[] = { + {"top_paste", PCB_LYT_TOP | PCB_LYT_PASTE, NULL, PCB_LYC_AUTO, 0}, + {"top_silk", PCB_LYT_TOP | PCB_LYT_SILK, NULL, PCB_LYC_AUTO, 0}, + {"top_mask", PCB_LYT_TOP | PCB_LYT_MASK, NULL, PCB_LYC_SUB | PCB_LYC_AUTO, 0}, + {"top_copper", PCB_LYT_TOP | PCB_LYT_COPPER, NULL, 0, 0}, + {"any_internal_copper", PCB_LYT_INTERN | PCB_LYT_COPPER, NULL, 0, 0}, + {"bottom_copper", PCB_LYT_BOTTOM | PCB_LYT_COPPER, NULL, 0, 0}, + {"bottom_mask", PCB_LYT_BOTTOM | PCB_LYT_MASK, NULL, PCB_LYC_SUB | PCB_LYC_AUTO, PCB_DFLGMAP_FORCE_END}, + {"bottom_silk", PCB_LYT_BOTTOM | PCB_LYT_SILK, NULL, PCB_LYC_AUTO, PCB_DFLGMAP_FORCE_END}, + {"bottom_paste", PCB_LYT_BOTTOM | PCB_LYT_PASTE, NULL, PCB_LYC_AUTO, PCB_DFLGMAP_FORCE_END}, + + {"outline", PCB_LYT_BOUNDARY, "uroute", 0, 0}, + {"pmech", PCB_LYT_MECH, "proute", PCB_LYC_AUTO, 0}, + {"umech", PCB_LYT_MECH, "uroute", PCB_LYC_AUTO, 0}, + + {NULL, 0} +}; + +const pcb_dflgmap_t *pcb_dflgmap_last_top_noncopper = pcb_dflgmap+2; +const pcb_dflgmap_t *pcb_dflgmap_first_bottom_noncopper = pcb_dflgmap+6; +const pcb_dflgmap_t pcb_dflg_top_copper = { + "top_copper", PCB_LYT_TOP | PCB_LYT_COPPER, NULL, 0, 0 +}; +const pcb_dflgmap_t pcb_dflg_int_copper = { + "int_copper", PCB_LYT_INTERN | PCB_LYT_COPPER, NULL, 0, 0 +}; +const pcb_dflgmap_t pcb_dflg_substrate = { + "substrate", PCB_LYT_INTERN | PCB_LYT_SUBSTRATE, NULL, 0, 0 +}; +const pcb_dflgmap_t pcb_dflg_bot_copper = { + "bot_copper", PCB_LYT_BOTTOM | PCB_LYT_COPPER, NULL, 0, 0 +}; + +const pcb_dflgmap_t pcb_dflg_outline = { + "outline", PCB_LYT_BOUNDARY, "uroute", 0, 0 +}; + +const pcb_dflgmap_t pcb_dflgmap_doc[] = { + {"top_assy", PCB_LYT_TOP | PCB_LYT_DOC, "assy", 0, PCB_DFLGMAP_INIT_INVIS}, + {"bottom_assy", PCB_LYT_BOTTOM | PCB_LYT_DOC, "assy", 0, PCB_DFLGMAP_INIT_INVIS}, + {"fab", PCB_LYT_TOP | PCB_LYT_DOC, "fab", PCB_LYC_AUTO, PCB_DFLGMAP_INIT_INVIS}, + {NULL, 0} +}; + +void pcb_layergrp_set_dflgly(pcb_board_t *pcb, pcb_layergrp_t *grp, const pcb_dflgmap_t *src, const char *grname, const char *lyname) +{ + rnd_layergrp_id_t gid = grp - pcb->LayerGroups.grp; + + if (grname == NULL) + grname = src->name; + if (lyname == NULL) + lyname = src->name; + + grp->name = rnd_strdup(grname); + grp->ltype = src->lyt; + + free(grp->purpose); + grp->purpose = NULL; + if (src->purpose != NULL) + pcb_layergrp_set_purpose__(grp, rnd_strdup(src->purpose), 1); + + if (grp->len == 0) { + rnd_layer_id_t lid = pcb_layer_create(pcb, gid, lyname, 0); + if (lid >= 0) { + pcb->Data->Layer[lid].comb = src->comb; + } + } + grp->valid = 1; +} + +static void pcb_layergrp_upgrade_by_map_(pcb_board_t *pcb, const pcb_dflgmap_t *map, int force) +{ + const pcb_dflgmap_t *m; + pcb_layergrp_t *grp; + rnd_layergrp_id_t gid; + + inhibit_notify++; + for(m = map; m->name != NULL; m++) { + int found = 0; + + if (!force) { + if (m->purpose == NULL) + found = pcb_layergrp_list(pcb, m->lyt, &gid, 1); + else + found = pcb_layergrp_listp(pcb, m->lyt, &gid, 1, 0, m->purpose); + } + + if (found == 1) { + grp = &pcb->LayerGroups.grp[gid]; + free(grp->name); + } + else + grp = pcb_get_grp_new_intern_(pcb, 1, (m->flags & PCB_DFLGMAP_FORCE_END)); + if (m->flags & PCB_DFLGMAP_INIT_INVIS) + pcb_attribute_put(&grp->Attributes, "init-invis", "1"); + pcb_layergrp_set_dflgly(pcb, grp, m, NULL, NULL); + } + inhibit_notify--; + NOTIFY(pcb); +} + +void pcb_layergrp_upgrade_by_map(pcb_board_t *pcb, const pcb_dflgmap_t *map) +{ + pcb_layergrp_upgrade_by_map_(pcb, map, 0); +} + +void pcb_layergrp_create_by_map(pcb_board_t *pcb, const pcb_dflgmap_t *map) +{ + pcb_layergrp_upgrade_by_map_(pcb, map, 1); +} + + +void pcb_layergrp_upgrade_to_pstk(pcb_board_t *pcb) +{ + pcb_layergrp_upgrade_by_map(pcb, pcb_dflgmap); +} + +static rnd_layergrp_id_t pcb_layergrp_get_cached(pcb_board_t *pcb, rnd_layer_id_t *cache, unsigned int loc, unsigned int typ) +{ + pcb_layergrp_t *g; + + /* check if the last known value is still accurate */ + if ((*cache >= 0) && (*cache < pcb->LayerGroups.len)) { + g = &(pcb->LayerGroups.grp[*cache]); + if ((g->ltype & loc) && (g->ltype & typ)) + return *cache; + } + + /* nope: need to resolve it again */ + g = pcb_get_grp(&pcb->LayerGroups, loc, typ); + if (g == NULL) + *cache = -1; + else + *cache = (g - pcb->LayerGroups.grp); + return *cache; +} + +rnd_layergrp_id_t pcb_layergrp_get_bottom_mask() +{ + static rnd_layer_id_t cache = -1; + return pcb_layergrp_get_cached(PCB, &cache, PCB_LYT_BOTTOM, PCB_LYT_MASK); +} + +rnd_layergrp_id_t pcb_layergrp_get_top_mask() +{ + static rnd_layer_id_t cache = -1; + return pcb_layergrp_get_cached(PCB, &cache, PCB_LYT_TOP, PCB_LYT_MASK); +} + +rnd_layergrp_id_t pcb_layergrp_get_bottom_paste() +{ + static rnd_layer_id_t cache = -1; + return pcb_layergrp_get_cached(PCB, &cache, PCB_LYT_BOTTOM, PCB_LYT_PASTE); +} + +rnd_layergrp_id_t pcb_layergrp_get_top_paste() +{ + static rnd_layer_id_t cache = -1; + return pcb_layergrp_get_cached(PCB, &cache, PCB_LYT_TOP, PCB_LYT_PASTE); +} + +rnd_layergrp_id_t pcb_layergrp_get_bottom_silk() +{ + static rnd_layer_id_t cache = -1; + return pcb_layergrp_get_cached(PCB, &cache, PCB_LYT_BOTTOM, PCB_LYT_SILK); +} + +rnd_layergrp_id_t pcb_layergrp_get_top_silk() +{ + static rnd_layer_id_t cache = -1; + return pcb_layergrp_get_cached(PCB, &cache, PCB_LYT_TOP, PCB_LYT_SILK); +} + +rnd_layergrp_id_t pcb_layergrp_get_bottom_copper() +{ + static rnd_layer_id_t cache = -1; + return pcb_layergrp_get_cached(PCB, &cache, PCB_LYT_BOTTOM, PCB_LYT_COPPER); +} + +rnd_layergrp_id_t pcb_layergrp_get_top_copper() +{ + static rnd_layer_id_t cache = -1; + return pcb_layergrp_get_cached(PCB, &cache, PCB_LYT_TOP, PCB_LYT_COPPER); +} + +/* Note: these function is in this file mainly to access the static inlines */ +int pcb_silk_on(pcb_board_t *pcb) +{ + static rnd_layer_id_t ts = -1, bs = -1; + pcb_layergrp_get_cached(pcb, &ts, PCB_LYT_TOP, PCB_LYT_SILK); + if ((ts >= 0) && (pcb->LayerGroups.grp[ts].vis)) + return 1; + pcb_layergrp_get_cached(pcb, &bs, PCB_LYT_BOTTOM, PCB_LYT_SILK); + if ((bs >= 0) && (pcb->LayerGroups.grp[bs].vis)) + return 1; + return 0; +} + +int pcb_mask_on(pcb_board_t *pcb) +{ + static rnd_layer_id_t tm = -1, bm = -1; + pcb_layergrp_get_cached(pcb, &tm, PCB_LYT_TOP, PCB_LYT_MASK); + if ((tm >= 0) && (pcb->LayerGroups.grp[tm].vis)) + return 1; + pcb_layergrp_get_cached(pcb, &bm, PCB_LYT_BOTTOM, PCB_LYT_MASK); + if ((bm >= 0) && (pcb->LayerGroups.grp[bm].vis)) + return 1; + return 0; +} + + +int pcb_paste_on(pcb_board_t *pcb) +{ + static rnd_layer_id_t tp = -1, bp = -1; + pcb_layergrp_get_cached(pcb, &tp, PCB_LYT_TOP, PCB_LYT_PASTE); + if ((tp >= 0) && (pcb->LayerGroups.grp[tp].vis)) + return 1; + pcb_layergrp_get_cached(pcb, &bp, PCB_LYT_BOTTOM, PCB_LYT_PASTE); + if ((bp >= 0) && (pcb->LayerGroups.grp[bp].vis)) + return 1; + return 0; +} + + +void pcb_layergrp_copper_cache_update(pcb_layer_stack_t *st) +{ + rnd_layergrp_id_t n; + if (st->len > st->cache.copper_alloced) { + st->cache.copper_alloced = st->len + 64; + st->cache.copper = realloc(st->cache.copper, sizeof(st->cache.copper[0]) * st->cache.copper_alloced); + } + + st->cache.copper_len = 0; + for(n = 0; n < st->len; n++) + if (st->grp[n].ltype & PCB_LYT_COPPER) + st->cache.copper[st->cache.copper_len++] = n; + + st->cache.copper_valid = 1; +} + +rnd_bool pcb_has_explicit_outline(pcb_board_t *pcb) +{ + int i; + pcb_layergrp_t *g; + for(i = 0, g = pcb->LayerGroups.grp; i < pcb->LayerGroups.len; i++,g++) + if (PCB_LAYER_IS_OUTLINE(g->ltype, g->purpi) && !pcb_layergrp_is_pure_empty(pcb, i)) + return 1; + return 0; +} + +const char *pcb_layergrp_thickness_attr(pcb_layergrp_t *grp, const char *namespace) +{ + const char *s = NULL; + if (namespace != NULL) + s = pcb_attribute_get_namespace(&grp->Attributes, namespace, "thickness"); + if (s == NULL) + s = pcb_attribute_get(&grp->Attributes, "thickness"); + return s; +} Index: tags/2.3.0/src/layer_grp.h =================================================================== --- tags/2.3.0/src/layer_grp.h (nonexistent) +++ tags/2.3.0/src/layer_grp.h (revision 33253) @@ -0,0 +1,308 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2006 Thomas Nau + * Copyright (C) 2016, 2017 Tibor 'Igor2' Palinkas (pcb-rnd extensions) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_LAYER_GRP_H +#define PCB_LAYER_GRP_H + +#include "layer.h" + +/* ---------------------------------------------------------------------- + * layer group. A layer group identifies layers which are always switched + * on/off together. + */ + +struct pcb_layergrp_s { + PCB_ANY_OBJ_FIELDS; + rnd_cardinal_t len; /* number of layer IDs in use */ + rnd_layer_id_t lid[PCB_MAX_LAYER]; /* lid=layer ID */ + char *name; /* name of the physical layer (independent of the name of the layer groups) */ + + pcb_layer_type_t ltype; + char *purpose; /* what a doc/mech layer is used for */ + int purpi; /* integer version of purpose from the funtion hash (cache) */ + + unsigned valid:1; /* 1 if it's a new-style, valid layer group; 0 after loading old files with no layer stackup info */ + unsigned vis:1; /* 1 if layer group is visible on the GUI */ + unsigned open:1; /* 1 if the group is open (expanded) on the GUI */ + + /* internal: temporary states */ + int intern_id; /* for the old layer import mechanism */ + + /* internal: attribute cache */ + unsigned init_invis:1; /* layer group should be inivisible by default (e.g. after load) */ +}; + + +/* layer stack: an ordered list of layer groups (physical layers). */ +struct pcb_layer_stack_s { + rnd_cardinal_t len; + pcb_layergrp_t grp[PCB_MAX_LAYERGRP]; + struct { /* cache copper groups from top to bottom for fast padstack ("bbvia") lookup */ + int copper_len, copper_alloced; + rnd_layergrp_id_t *copper; + unsigned copper_valid:1; /* whether the cache is valid */ + } cache; +}; + +/* Free all fields of a layer stack */ +void pcb_layergroup_free_stack(pcb_layer_stack_t *st); + +/* Return the layer group for an id, or NULL on error (range check) */ +pcb_layergrp_t *pcb_get_layergrp(pcb_board_t *pcb, rnd_layergrp_id_t gid); + +/* Return the gid if grp is in the stackup of pcb (else return -1) */ +rnd_layergrp_id_t pcb_layergrp_id(const pcb_board_t *pcb, const pcb_layergrp_t *grp); + +/* Free a layer group (don't free the layers but detach them) */ +int pcb_layergrp_free(pcb_board_t *pcb, rnd_layergrp_id_t id); + +/* lookup the group to which a layer belongs to returns -1 if no group is found */ +rnd_layergrp_id_t pcb_layer_get_group(pcb_board_t *pcb, rnd_layer_id_t Layer); +rnd_layergrp_id_t pcb_layer_get_group_(pcb_layer_t *Layer); + +/* Returns group actually moved to (i.e. either group or previous) */ +rnd_layergrp_id_t pcb_layer_move_to_group(pcb_board_t *pcb, rnd_layer_id_t layer, rnd_layergrp_id_t group); + +/* Returns rnd_true if all layers in a group are empty */ +rnd_bool pcb_layergrp_is_empty(pcb_board_t *pcb, rnd_layergrp_id_t lgrp); +rnd_bool pcb_layergrp_is_pure_empty(pcb_board_t *pcb, rnd_layergrp_id_t num); + +/* call the gui to set a layer group */ +int pcb_layer_gui_set_layer(rnd_layergrp_id_t gid, const pcb_layergrp_t *grp, int is_empty, rnd_xform_t **xform); +int pcb_layer_gui_set_glayer(pcb_board_t *pcb, rnd_layergrp_id_t grp, int is_empty, rnd_xform_t **xform); + +/* returns a bitfield of pcb_layer_type_t; returns 0 if layer_idx is invalid. */ +unsigned int pcb_layergrp_flags(const pcb_board_t *pcb, rnd_layergrp_id_t group_idx); +const char *pcb_layergrp_name(pcb_board_t *pcb, rnd_layergrp_id_t gid); + +/* Same as pcb_layer_list but lists layer groups. A group is matching + if any layer in that group matches mask. */ +int pcb_layergrp_list(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layergrp_id_t *res, int res_len); +int pcb_layergrp_listp(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layergrp_id_t *res, int res_len, int purpi, const char *purpose); +int pcb_layergrp_list_any(const pcb_board_t *pcb, pcb_layer_type_t mask, rnd_layergrp_id_t *res, int res_len); + +/* Put a layer in a group (the layer should not be in any other group); + returns 0 on success */ +int pcb_layer_add_in_group(pcb_board_t *pcb, rnd_layer_id_t layer_id, rnd_layergrp_id_t group_id); +int pcb_layer_add_in_group_(pcb_board_t *pcb, pcb_layergrp_t *grp, rnd_layergrp_id_t group_id, rnd_layer_id_t layer_id); + +/* Remove a layer group; if del_layers is zero, layers are kept but detached + (.grp = -1), else layers are deleted too */ +int pcb_layergrp_del(pcb_board_t *pcb, rnd_layergrp_id_t gid, int del_layers, rnd_bool undoable); + +/* Remove a layer from a group */ +int pcb_layergrp_del_layer(pcb_board_t *pcb, rnd_layergrp_id_t gid, rnd_layer_id_t lid); + +/* Duplicate a layer group (with no layers); if auto_substrate is set, insert + a substrate layer automatically if needed */ +rnd_layergrp_id_t pcb_layergrp_dup(pcb_board_t *pcb, rnd_layergrp_id_t gid, int auto_substrate, rnd_bool undoable); + +/* Move gfrom to to_before and shift the stack as necessary. Return -1 on range error */ +int pcb_layergrp_move(pcb_board_t *pcb, rnd_layergrp_id_t gfrom, rnd_layergrp_id_t to_before); + +/* Move src onto dst, not shifting the stack, free()'ing and overwriting dst, leaving a gap (0'd slot) at src */ +int pcb_layergrp_move_onto(pcb_board_t *pcb, rnd_layergrp_id_t dst, rnd_layergrp_id_t src); + +/* Set up the administrative fields (type, parent) of a group */ +void pcb_layergrp_setup(pcb_layergrp_t *g, pcb_board_t *parent); + + +/* Insert a new layer group in the layer stack after the specified group */ +pcb_layergrp_t *pcb_layergrp_insert_after(pcb_board_t *pcb, rnd_layergrp_id_t where); + +/* Move lid 1 step towards the front (delta=-1) or end (delta=+1) of the + layer list of the group. Return 0 on success (even when already reached + the end of the list) or -1 on error. + This operation is always undoable. */ +int pcb_layergrp_step_layer(pcb_board_t *pcb, pcb_layergrp_t *grp, rnd_layer_id_t lid, int delta); + +/* Return the array index of lid within the grp's lid list or -1 if not on the list */ +int pcb_layergrp_index_in_grp(pcb_layergrp_t *grp, rnd_layer_id_t lid); + +/* Calculate the distance between gid1 and gid2 in the stack, in number of + layer groups matching mask. The result is placed in *diff. Returns 0 on success. + Typical use case: gid1 is an internal copper layer, gid2 is the top copper layer, + mask is PCB_LYT_COPPER -> *diff is the copper index of the internal layer from top */ +int pcb_layergrp_dist(pcb_board_t *pcb, rnd_layergrp_id_t gid1, rnd_layergrp_id_t gid2, pcb_layer_type_t mask, int *diff); + +/* walk the given amount steps on the stack among layer groups matching mask. + A negative step goes upward. + Typical use: "return the 2nd copper layer below this one" */ +rnd_layergrp_id_t pcb_layergrp_step(pcb_board_t *pcb, rnd_layergrp_id_t gid, int steps, pcb_layer_type_t mask); + + +/* Enable/disable inhibition of layer changed events during layer group updates */ +void pcb_layergrp_inhibit_inc(void); +void pcb_layergrp_inhibit_dec(void); + +/* send out a layers changed notification, respecting the inhibit flag */ +void pcb_layergrp_notify_chg(pcb_board_t *pcb); + + +/* Send out a layer changed event if not inhibited */ +void pcb_layergrp_notify(pcb_board_t *pcb); + +/* Rename an existing layer by idx */ +int pcb_layergrp_rename(pcb_board_t *pcb, rnd_layergrp_id_t gid, const char *lname, rnd_bool undoable); + +/* changes the name of a layer; memory has to be already allocated */ +int pcb_layergrp_rename_(pcb_layergrp_t *grp, char *name, rnd_bool undoable); + +/* Change the purpose field and recalc purpi (not undoable) */ +int pcb_layergrp_set_purpose__(pcb_layergrp_t *lg, char *purpose, rnd_bool undoable); /* no strdup, no event */ +int pcb_layergrp_set_purpose_(pcb_layergrp_t *lg, char *purpose, rnd_bool undoable); /* no strdup, send layer change event */ +int pcb_layergrp_set_purpose(pcb_layergrp_t *lg, const char *purpose, rnd_bool undoable); /* strdup, send event */ + +/* Change layer group flags (layer-type) */ +int pcb_layergrp_set_ltype(pcb_layergrp_t *g, pcb_layer_type_t lyt, rnd_bool undoable); + +/* Slow linear search for a layer group by name */ +rnd_layergrp_id_t pcb_layergrp_by_name(pcb_board_t *pcb, const char *name); + +/* Create a layer for each unbindable layers from the layer array */ +int pcb_layer_create_all_for_recipe(pcb_board_t *pcb, pcb_layer_t *layer, int num_layer); + +/* Upgrade the current layer stack to incldue all layers for + fully representaing standard padstacks. This includes reusing or + creating layer groups and layers, altering layer group names (but + not removing layers or groups) */ +void pcb_layergrp_upgrade_to_pstk(pcb_board_t *pcb); + +/* Compatibility helper: insert a substrate group in between any two adjacent + copper groups. */ +void pcb_layergrp_create_missing_substrate(pcb_board_t *pcb); + +/* Call this after creating grp to add the creation to the undo list */ +void pcb_layergrp_undoable_created(pcb_layergrp_t *grp); + +#define PCB_COPPER_GROUP_LOOP(data, group) do { \ + rnd_cardinal_t entry; \ + pcb_board_t *cgl__pcb = pcb_data_get_top(data); \ + if (cgl__pcb == NULL) \ + cgl__pcb = PCB; \ + for (entry = 0; entry < ((pcb_board_t *)(cgl__pcb))->LayerGroups.grp[(group)].len; entry++) \ + { \ + pcb_layer_t *layer; \ + rnd_layer_id_t number; \ + number = ((pcb_board_t *)(cgl__pcb))->LayerGroups.grp[(group)].lid[entry]; \ + if (!(pcb_layer_flags(PCB, number) & PCB_LYT_COPPER)) \ + continue; \ + layer = &data->Layer[number]; + +/* for parsing old files with old layer descriptions, with no layer groups */ +void pcb_layer_group_setup_default(pcb_board_t *pcb); /* default layer groups, no layers */ +void pcb_layer_group_setup_silks(pcb_board_t *pcb); /* make sure we have two silk layers, add them if needed */ +pcb_layergrp_t *pcb_get_grp(pcb_layer_stack_t *stack, pcb_layer_type_t loc, pcb_layer_type_t typ); +pcb_layergrp_t *pcb_get_grp_new_intern(pcb_board_t *pcb, int intern_id); +pcb_layergrp_t *pcb_get_grp_new_misc(pcb_board_t *pcb); + +/* prepend or append a layer group without any smart side effects - used + from io loaders */ +pcb_layergrp_t *pcb_get_grp_new_raw(pcb_board_t *pcb, rnd_bool prepend); + +/* ugly hack: remove the extra substrate we added after the outline layer */ +void pcb_layergrp_fix_old_outline(pcb_board_t *pcb); + +/* ugly hack: turn an old intern layer group into an outline group after realizing it is really an outline (reading the old layers) */ +void pcb_layergrp_fix_turn_to_outline(pcb_layergrp_t *g); + +/* ugly hack: look at layers and convert g into an outline group if needed */ +void pcb_layergrp_fix_old_outline_detect(pcb_board_t *pcb, pcb_layergrp_t *g); + + +/* Cached layer group lookups foir a few common cases */ +rnd_layergrp_id_t pcb_layergrp_get_bottom_mask(); +rnd_layergrp_id_t pcb_layergrp_get_top_mask(); +rnd_layergrp_id_t pcb_layergrp_get_bottom_paste(); +rnd_layergrp_id_t pcb_layergrp_get_top_paste(); +rnd_layergrp_id_t pcb_layergrp_get_bottom_silk(); +rnd_layergrp_id_t pcb_layergrp_get_top_silk(); +rnd_layergrp_id_t pcb_layergrp_get_bottom_copper(); +rnd_layergrp_id_t pcb_layergrp_get_top_copper(); + + +/* return whether any silk or mask or paste layer group is visible */ +int pcb_silk_on(pcb_board_t *pcb); +int pcb_mask_on(pcb_board_t *pcb); +int pcb_paste_on(pcb_board_t *pcb); + +/* recalculate the copper cache */ +void pcb_layergrp_copper_cache_update(pcb_layer_stack_t *st); + +/* default layer group map */ +typedef struct pcb_dflgmap_s { + const char *name; + pcb_layer_type_t lyt; + const char *purpose; + pcb_layer_combining_t comb; + enum { /* bitfield */ + PCB_DFLGMAP_FORCE_END = 1, + PCB_DFLGMAP_INIT_INVIS = 2 + } flags; +} pcb_dflgmap_t; + +extern const pcb_dflgmap_t pcb_dflgmap[]; /* the whole map, without doc layers */ + +/* non-coper parts of the map, without doc layers, without doc layers */ +extern const pcb_dflgmap_t pcb_dflg_top_noncop[]; +extern const pcb_dflgmap_t pcb_dflg_bot_noncop[]; +extern const pcb_dflgmap_t pcb_dflg_glob_noncop[]; + +/* pointers into the array marking boundaries */ +extern const pcb_dflgmap_t *pcb_dflgmap_last_top_noncopper; +extern const pcb_dflgmap_t *pcb_dflgmap_first_bottom_noncopper; + +extern const pcb_dflgmap_t pcb_dflgmap_doc[]; /* map for the doc layers, e.g. assy and fab layers */ + +/* predefined common default map entries for building a stack */ +extern const pcb_dflgmap_t pcb_dflg_top_copper; +extern const pcb_dflgmap_t pcb_dflg_int_copper; +extern const pcb_dflgmap_t pcb_dflg_substrate; +extern const pcb_dflgmap_t pcb_dflg_bot_copper; +extern const pcb_dflgmap_t pcb_dflg_outline; + +/* Overwrite or create all groups from a map */ +void pcb_layergrp_upgrade_by_map(pcb_board_t *pcb, const pcb_dflgmap_t *map); + +/* Create all groups from a map (even if duplicate to existing) */ +void pcb_layergrp_create_by_map(pcb_board_t *pcb, const pcb_dflgmap_t *map); + +/* Overwrite an existing group from a default layer group map entry and create + a layer in the group */ +void pcb_layergrp_set_dflgly(pcb_board_t *pcb, pcb_layergrp_t *grp, const pcb_dflgmap_t *src, const char *grname, const char *lyname); + +/* Return true if the board has an outline layer with at least one object on it */ +rnd_bool pcb_has_explicit_outline(pcb_board_t *pcb); + +/* Return the thickness attribute of a layer group, optionally considering + the namespace based override attribute, when present; returns NULL if + attribute is not found. */ +const char *pcb_layergrp_thickness_attr(pcb_layergrp_t *grp, const char *namespace); + +#endif Index: tags/2.3.0/src/layer_it.h =================================================================== --- tags/2.3.0/src/layer_it.h (nonexistent) +++ tags/2.3.0/src/layer_it.h (revision 33253) @@ -0,0 +1,121 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Layer and layer group iterators (static inline functions) */ + +#ifndef PCB_LAYER_IT_H +#define PCB_LAYER_IT_H + +#include "layer_grp.h" + +typedef struct pcb_layer_it_s pcb_layer_it_t; + +/* Start an iteration matching exact flags or any of the flags; returns -1 if over */ +RND_INLINE rnd_layer_id_t pcb_layer_first(pcb_layer_stack_t *stack, pcb_layer_it_t *it, unsigned int exact_mask); +RND_INLINE rnd_layer_id_t pcb_layer_first_any(pcb_layer_stack_t *stack, pcb_layer_it_t *it, unsigned int any_mask); + +/* next iteration; returns -1 if over */ +RND_INLINE rnd_layer_id_t pcb_layer_next(pcb_layer_it_t *it); + + +/*************** inline implementation *************************/ +struct pcb_layer_it_s { + pcb_layer_stack_t *stack; + rnd_layergrp_id_t gid; + rnd_cardinal_t lidx; + unsigned int mask; + unsigned int exact:1; + unsigned int global:1; +}; + +RND_INLINE rnd_layer_id_t pcb_layer_next(pcb_layer_it_t *it) +{ + if (it->global) { + /* over all layers, random order, without any checks - go the cheap way, bypassing groups */ + if (it->lidx < pcb_max_layer(PCB)) + return it->lidx++; + return -1; + } + else for(;;) { + pcb_layergrp_t *g = &(it->stack->grp[it->gid]); + rnd_layer_id_t lid; + unsigned int hit; + if (it->lidx >= g->len) { /* layer list over in this group */ + it->gid++; + if (it->gid >= PCB_MAX_LAYERGRP) /* last group */ + return -1; + it->lidx = 0; + continue; /* skip to next group */ + } + + lid = g->lid[it->lidx]; + it->lidx++; + hit = g->ltype & it->mask; + if (it->exact) { + if (hit == it->mask) + return lid; + } + else { + if (hit) + return lid; + } + /* skip to next group */ + } +} + +RND_INLINE rnd_layer_id_t pcb_layer_first(pcb_layer_stack_t *stack, pcb_layer_it_t *it, unsigned int exact_mask) +{ + it->stack = stack; + it->mask = exact_mask; + it->gid = 0; + it->lidx = 0; + it->exact = 1; + it->global = 0; + return pcb_layer_next(it); +} + +RND_INLINE rnd_layer_id_t pcb_layer_first_any(pcb_layer_stack_t *stack, pcb_layer_it_t *it, unsigned int any_mask) +{ + it->stack = stack; + it->mask = any_mask; + it->gid = 0; + it->lidx = 0; + it->exact = 0; + it->global = 0; + return pcb_layer_next(it); +} + +RND_INLINE rnd_layer_id_t pcb_layer_first_all(pcb_layer_stack_t *stack, pcb_layer_it_t *it) +{ + it->stack = stack; + it->lidx = 0; + it->global = 1; + return pcb_layer_next(it); +} + + +#endif Index: tags/2.3.0/src/layer_ui.c =================================================================== --- tags/2.3.0/src/layer_ui.c (nonexistent) +++ tags/2.3.0/src/layer_ui.c (revision 33253) @@ -0,0 +1,126 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This module, layer_ui.c, was written and is Copyright (C) 2016 by + * Tibor 'Igor2' Palinkas. + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Virtual layers for UI and debug */ +#include "config.h" +#include "board.h" +#include "layer.h" +#include "event.h" +#include +#include "genvector/vtp0.h" +#include "layer_ui.h" + +vtp0_t pcb_uilayers; + + +pcb_layer_t *pcb_uilayer_alloc(const char *cookie, const char *name, const rnd_color_t *color) +{ + int n; + pcb_layer_t *l; + void **p; + + if (cookie == NULL) + return NULL; + + for(n = 0; n < vtp0_len(&pcb_uilayers); n++) { + l = pcb_uilayers.array[n]; + if (l == NULL) { + l = calloc(sizeof(pcb_layer_t), 1); + pcb_uilayers.array[n] = l; + goto found; + } + } + + l = calloc(sizeof(pcb_layer_t), 1); + p = vtp0_alloc_append(&pcb_uilayers, 1); + *p = l; +found:; + l->meta.real.cookie = cookie; + l->meta.real.color = *color; + l->name = rnd_strdup(name); + l->meta.real.vis = 1; + l->parent_type = PCB_PARENT_UI; + l->parent.any = NULL; + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + return l; +} + +static void pcb_uilayer_free_(pcb_layer_t *l, long idx) +{ + pcb_layer_free_fields(l, 0); + free(l); + pcb_uilayers.array[idx] = NULL; +} + +void pcb_uilayer_free(pcb_layer_t *ly) +{ + int n; + for(n = 0; n < vtp0_len(&pcb_uilayers); n++) { + pcb_layer_t *l = pcb_uilayers.array[n]; + if (l == ly) { + pcb_uilayer_free_(l, n); + break; + } + } + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); +} + +void pcb_uilayer_free_all_cookie(const char *cookie) +{ + int n; + for(n = 0; n < vtp0_len(&pcb_uilayers); n++) { + pcb_layer_t *l = pcb_uilayers.array[n]; + if ((l != NULL) && (l->meta.real.cookie == cookie)) + pcb_uilayer_free_(l, n); + } + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); +} + +void pcb_uilayer_uninit(void) +{ + vtp0_uninit(&pcb_uilayers); +} + +pcb_layer_t *pcb_uilayer_get(long ui_ly_id) +{ + void **p = vtp0_get(&pcb_uilayers, (ui_ly_id & (PCB_LYT_UI-1)), 0); + if (p == NULL) + return NULL; + return (pcb_layer_t *)(*p); +} + +long pcb_uilayer_get_id(const pcb_layer_t *ly) +{ + int n; + for(n = 0; n < vtp0_len(&pcb_uilayers); n++) + if (pcb_uilayers.array[n] == ly) + return (long)n | PCB_LYT_UI; + return -1; +} Index: tags/2.3.0/src/layer_ui.h =================================================================== --- tags/2.3.0/src/layer_ui.h (nonexistent) +++ tags/2.3.0/src/layer_ui.h (revision 33253) @@ -0,0 +1,50 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This module, layer_ui.c, was written and is Copyright (C) 2016 by + * Tibor 'Igor2' Palinkas. + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_LAYER_UI_H +#define PCB_LAYER_UI_H + +/* Virtual layers for UI and debug */ +#include + +#include "genvector/vtp0.h" + +/* list of all UI layers - each item is a persistent pointer to a layer struct */ +extern vtp0_t pcb_uilayers; + +pcb_layer_t *pcb_uilayer_alloc(const char *cookie, const char *name, const rnd_color_t *color); +void pcb_uilayer_free(pcb_layer_t *l); +void pcb_uilayer_free_all_cookie(const char *cookie); +void pcb_uilayer_uninit(void); + +pcb_layer_t *pcb_uilayer_get(long ui_ly_id); +long pcb_uilayer_get_id(const pcb_layer_t *ly); + +#endif Index: tags/2.3.0/src/layer_vis.c =================================================================== --- tags/2.3.0/src/layer_vis.c (nonexistent) +++ tags/2.3.0/src/layer_vis.c (revision 33253) @@ -0,0 +1,374 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2004,2006 Thomas Nau + * Copyright (C) 2016 Tibor 'Igor2' Palinkas (pcb-rnd extensions) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Layer visibility logics (affects the GUI and some exporters) */ + +#include "config.h" +#include "board.h" +#include "data.h" +#include "conf_core.h" +#include "layer.h" +#include "layer_ui.h" +#include "layer_vis.h" +#include "event.h" +#include +#include + +/* + * Used by pcb_layervis_save_stack() and + * pcb_layervis_restore_stack() + */ +static struct { + rnd_bool ElementOn, InvisibleObjectsOn, pstk_on, RatOn; + int pcb_layer_stack[PCB_MAX_LAYER]; + rnd_bool LayerOn[PCB_MAX_LAYER]; + int cnt; +} SavedStack; + + +/* --------------------------------------------------------------------------- + * move layer (number is passed in) to top of layerstack + */ +static void PushOnTopOfLayerStack(pcb_board_t *pcb, int NewTop) +{ + int i; + + /* ignore silk layers */ + if (NewTop < pcb_max_layer(pcb)) { + /* first find position of passed one */ + for (i = 0; i < pcb_max_layer(pcb); i++) + if (pcb_layer_stack[i] == NewTop) + break; + + /* bring this element to the top of the stack */ + for (; i; i--) + pcb_layer_stack[i] = pcb_layer_stack[i - 1]; + pcb_layer_stack[0] = NewTop; + } +} + +int pcb_layervis_change_group_vis(rnd_hidlib_t *hl, rnd_layer_id_t Layer, int On, rnd_bool ChangeStackOrder) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + rnd_layergrp_id_t group; + int i, changed = 1; /* at least the current layer changes */ + + + if (Layer & PCB_LYT_UI) { + pcb_layer_t *ly = pcb_uilayer_get(Layer); + if (ly == NULL) + return 0; + if (On < 0) + On = !ly->meta.real.vis; + ly->meta.real.vis = On; + changed = 1; + goto done; + } + + if (On < 0) + On = !pcb->Data->Layer[Layer].meta.real.vis; + + /* decrement 'i' to keep stack in order of layergroup */ + if ((group = pcb_layer_get_group(pcb, Layer)) >= 0) { + for (i = pcb->LayerGroups.grp[group].len; i;) { + rnd_layer_id_t layer = pcb->LayerGroups.grp[group].lid[--i]; + + /* don't count the passed member of the group */ + if (layer != Layer && layer < pcb_max_layer(pcb)) { + pcb->Data->Layer[layer].meta.real.vis = On; + + /* push layer on top of stack if switched on */ + if (On && ChangeStackOrder) + PushOnTopOfLayerStack(pcb, layer); + changed++; + } + } + pcb->LayerGroups.grp[group].vis = On; + } + + /* change at least the passed layer */ + pcb->Data->Layer[Layer].meta.real.vis = On; + if (On && ChangeStackOrder) + PushOnTopOfLayerStack(pcb, Layer); + + done:; + /* update control panel and exit */ + if (ChangeStackOrder) + pcb->RatDraw = 0; /* any layer selection here means we can not be in rat mode */ + rnd_event(hl, PCB_EVENT_LAYERVIS_CHANGED, NULL); + return changed; +} + +void pcb_layervis_reset_stack(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + rnd_layer_id_t comp; + rnd_cardinal_t i; + + assert(pcb->Data->LayerN <= PCB_MAX_LAYER); + for (i = 0; i < pcb_max_layer(pcb); i++) { + pcb_layergrp_t *grp = pcb_get_layergrp(pcb, pcb->Data->Layer[i].meta.real.grp); + + if (!(pcb_layer_flags(pcb, i) & PCB_LYT_SILK)) + pcb_layer_stack[i] = i; + if (grp != NULL) + pcb->Data->Layer[i].meta.real.vis = !grp->init_invis; + else + pcb->Data->Layer[i].meta.real.vis = rnd_true; + } + pcb->InvisibleObjectsOn = rnd_true; + pcb->pstk_on = rnd_true; + pcb->SubcOn = rnd_true; + pcb->SubcPartsOn = rnd_true; + pcb->RatOn = rnd_true; + pcb->padstack_mark_on = rnd_true; + pcb->hole_on = rnd_true; + + /* Bring the top copper group to the front and make it active. */ + if (pcb_layer_list(pcb, PCB_LYT_TOP | PCB_LYT_COPPER, &comp, 1) > 0) + pcb_layervis_change_group_vis(hl, comp, 1, 1); +} + +/* --------------------------------------------------------------------------- + * saves the layerstack setting + */ +void pcb_layervis_save_stack(void) +{ + rnd_cardinal_t i; + static rnd_bool run = rnd_false; + + if (run == rnd_false) { + SavedStack.cnt = 0; + run = rnd_true; + } + + if (SavedStack.cnt != 0) + rnd_message(RND_MSG_ERROR, "pcb_layervis_save_stack() layerstack was already saved and not yet restored. cnt = %d\n", SavedStack.cnt); + + for (i = 0; i < pcb_max_layer(PCB); i++) { + if (!(pcb_layer_flags(PCB, i) & PCB_LYT_SILK)) + SavedStack.pcb_layer_stack[i] = pcb_layer_stack[i]; + SavedStack.LayerOn[i] = PCB->Data->Layer[i].meta.real.vis; + } + SavedStack.ElementOn = pcb_silk_on(PCB); + SavedStack.InvisibleObjectsOn = PCB->InvisibleObjectsOn; + SavedStack.pstk_on = PCB->pstk_on; + SavedStack.RatOn = PCB->RatOn; + SavedStack.cnt++; +} + +/* --------------------------------------------------------------------------- + * restores the layerstack setting + */ +void pcb_layervis_restore_stack(void) +{ + rnd_cardinal_t i; + + if (SavedStack.cnt == 0) { + rnd_message(RND_MSG_ERROR, "pcb_layervis_restore_stack() layerstack has not" " been saved. cnt = %d\n", SavedStack.cnt); + return; + } + else if (SavedStack.cnt != 1) { + rnd_message(RND_MSG_ERROR, "pcb_layervis_restore_stack() layerstack save count is" " wrong. cnt = %d\n", SavedStack.cnt); + } + + for (i = 0; i < pcb_max_layer(PCB); i++) { + if (!(pcb_layer_flags(PCB, i) & PCB_LYT_SILK)) + pcb_layer_stack[i] = SavedStack.pcb_layer_stack[i]; + PCB->Data->Layer[i].meta.real.vis = SavedStack.LayerOn[i]; + } + PCB->InvisibleObjectsOn = SavedStack.InvisibleObjectsOn; + PCB->pstk_on = SavedStack.pstk_on; + PCB->RatOn = SavedStack.RatOn; + + SavedStack.cnt--; +} + +static rnd_conf_hid_id_t layer_vis_conf_id; + +void layer_vis_chg_mask(rnd_conf_native_t *cfg, int arr_idx) +{ + rnd_layer_id_t n; + int chg = 0; + static int in = 0; /* don't run when called from the PCB_EVENT_LAYERS_CHANGED triggered from this function */ + + if ((PCB == NULL) || (in)) + return; + + in = 1; + for(n = 0; n < pcb_max_layer(PCB); n++) { + if (pcb_layer_flags(PCB, n) & PCB_LYT_MASK) { + if (PCB->Data->Layer[n].meta.real.vis != *cfg->val.boolean) { + chg = 1; + PCB->Data->Layer[n].meta.real.vis = *cfg->val.boolean; + } + } + } + if (chg) + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERVIS_CHANGED, NULL); + in = 0; +} + +void pcb_layer_vis_change_all(pcb_board_t *pcb, rnd_bool_op_t open, rnd_bool_op_t vis) +{ + rnd_layergrp_id_t gid; + int n; + + for(gid = 0; gid < pcb_max_group(pcb); gid++) { + pcb_layergrp_t *g = &pcb->LayerGroups.grp[gid]; + + rnd_bool_op(g->open, open); + + if (vis == RND_BOOL_PRESERVE) { + /* the group is visible exactly if if any layer is visible */ + g->vis = 0; + for(n = 0; n < g->len; n++) { + pcb_layer_t *l = pcb_get_layer(pcb->Data, g->lid[n]); + if ((l != NULL) && (l->meta.real.vis)) { + g->vis = 1; + break; + } + } + } + else { + rnd_bool_op(g->vis, vis); + for(n = 0; n < g->len; n++) { + pcb_layer_t *l = pcb_get_layer(pcb->Data, g->lid[n]); + rnd_bool_op(l->meta.real.vis, vis); + } + } + } + /* do NOT generate an event: some callers want to handle that */ +} + +void pcb_layer_vis_historical_hides(pcb_board_t *pcb) +{ + rnd_layergrp_id_t gid; + + /* do not show paste and mask by default - they are distractive */ + for(gid = 0; gid < pcb_max_group(pcb); gid++) { + pcb_layergrp_t *g = &PCB->LayerGroups.grp[gid]; + if ((g->ltype & PCB_LYT_MASK) || (g->ltype & PCB_LYT_PASTE)) { + int n; + g->vis = rnd_false; + for(n = 0; n < g->len; n++) { + pcb_layer_t *l = pcb_get_layer(PCB->Data, g->lid[n]); + if (l == NULL) + rnd_message(RND_MSG_ERROR, "broken layer groups; layer group references to non-existing layer\n"); + else + l->meta.real.vis = 0; + } + } + } +} + +static void layer_vis_grp_defaults(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pcb_board_t *pcb = (pcb_board_t *)hidlib; + pcb_layer_vis_change_all(pcb, RND_BOOL_SET, RND_BOOL_PRESERVE); + pcb_layer_vis_historical_hides(pcb); + + rnd_event(hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); /* Can't send LAYERVIS_CHANGED here: it's a race condition, the layer selector could still have the old widgets */ +} + +rnd_layer_id_t pcb_layer_vis_last_lyt(pcb_layer_type_t target) +{ + int n; + /* find the last used match on stack first */ + for(n = 0; n < PCB_MAX_LAYER; n++) { + rnd_layer_id_t lid = pcb_layer_stack[n]; + pcb_layer_type_t lyt = pcb_layer_flags(PCB, lid); + if ((lyt & target) == target) + return lid; + } + + /* if no match, find any matching layer */ + for(n = 0; n < PCB_MAX_LAYER; n++) { + pcb_layer_type_t lyt = pcb_layer_flags(PCB, n); + if ((lyt & target) == target) + return n; + } + + return -1; +} + +void pcb_hid_save_and_show_layer_ons(int *save_array) +{ + rnd_layer_id_t i; + for (i = 0; i < pcb_max_layer(PCB); i++) { + save_array[i] = PCB->Data->Layer[i].meta.real.vis; + PCB->Data->Layer[i].meta.real.vis = 1; + } +} + +void pcb_hid_save_and_show_layergrp_ons(int *save_array) +{ + rnd_layergrp_id_t i; + for (i = 0; i < PCB->LayerGroups.len; i++) + save_array[i] = PCB->LayerGroups.grp[i].vis; +} + +void pcb_hid_restore_layer_ons(int *save_array) +{ + rnd_layer_id_t i; + for (i = 0; i < pcb_max_layer(PCB); i++) + PCB->Data->Layer[i].meta.real.vis = save_array[i]; +} + +void pcb_hid_restore_layergrp_ons(int *save_array) +{ + rnd_layergrp_id_t i; + for (i = 0; i < PCB->LayerGroups.len; i++) + PCB->LayerGroups.grp[i].vis = save_array[i]; +} + +static const char *layer_vis_cookie = "core_layer_vis"; + +void pcb_layer_vis_init(void) +{ + rnd_conf_native_t *n_mask = rnd_conf_get_field("editor/show_mask"); + static rnd_conf_hid_callbacks_t cbs_mask; + + layer_vis_conf_id = rnd_conf_hid_reg(layer_vis_cookie, NULL); + + if (n_mask != NULL) { + memset(&cbs_mask, 0, sizeof(rnd_conf_hid_callbacks_t)); + cbs_mask.val_change_post = layer_vis_chg_mask; + rnd_conf_hid_set_cb(n_mask, layer_vis_conf_id, &cbs_mask); + } + + rnd_event_bind(RND_EVENT_BOARD_CHANGED, layer_vis_grp_defaults, NULL, layer_vis_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, layer_vis_grp_defaults, NULL, layer_vis_cookie); +} + +void pcb_layer_vis_uninit(void) +{ + rnd_event_unbind_allcookie(layer_vis_cookie); + rnd_conf_hid_unreg(layer_vis_cookie); +} Index: tags/2.3.0/src/layer_vis.h =================================================================== --- tags/2.3.0/src/layer_vis.h (nonexistent) +++ tags/2.3.0/src/layer_vis.h (revision 33253) @@ -0,0 +1,75 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2004,2006 Thomas Nau + * Copyright (C) 2016 Tibor 'Igor2' Palinkas (pcb-rnd extensions) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Layer visibility logics (affects the GUI and some exporters) */ + +#ifndef PCB_LAYER_VIS_H +#define PCB_LAYER_VIS_H + +#include "layer.h" + +/* changes the visibility of all layers in a group; returns the number of + changed layers; on should be 0 or 1 for setting the state or -1 for toggling it */ +int pcb_layervis_change_group_vis(rnd_hidlib_t *hl, rnd_layer_id_t Layer, int On, rnd_bool ChangeStackOrder); + +/* resets the layer visibility stack setting */ +void pcb_layervis_reset_stack(rnd_hidlib_t *hl); + +/* for historical reasons mask and paste are hidden by default (and this + is hardwired in code); this function hides them */ +void pcb_layer_vis_historical_hides(pcb_board_t *pcb); + +/* saves the layerstack setting */ +void pcb_layervis_save_stack(void); + +/* restores the layerstack setting */ +void pcb_layervis_restore_stack(void); + +/* Return the last used layer (or if none, any layer) that matches target type */ +rnd_layer_id_t pcb_layer_vis_last_lyt(pcb_layer_type_t target); + +/* Use this to temporarily make all layers visible, so that they can be + exported even if they're not currently visible. save_array must be + PCB_MAX_LAYER (or PCB_MAX_LAYERGRP) big. Groups are only saved, not + set visible */ +void pcb_hid_save_and_show_layer_ons(int *save_array); +void pcb_hid_save_and_show_layergrp_ons(int *save_array); + +/* Use this to restore them. */ +void pcb_hid_restore_layer_ons(int *save_array); +void pcb_hid_restore_layergrp_ons(int *save_array); + +/* (un)init config watches and events to keep layers in sync */ +void pcb_layer_vis_init(void); +void pcb_layer_vis_uninit(void); + +/* Open/close, on/off all layers and groups; does NOT generate an event */ +void pcb_layer_vis_change_all(pcb_board_t *pcb, rnd_bool_op_t open, rnd_bool_op_t vis); + +#endif Index: tags/2.3.0/src/list_common.h =================================================================== --- tags/2.3.0/src/list_common.h (nonexistent) +++ tags/2.3.0/src/list_common.h (revision 33253) @@ -0,0 +1,40 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef LIST_COMMON_H +#define LIST_COMMON_H + +/* iterate over all items of list and call func(item) */ +#define list_map0(list, itemtype, func) \ + do { \ + void (*__f__)(void *) = (void (*)(void *))(func); \ + itemtype *__item__; \ + gdl_iterator_t it; \ + linelist_foreach((list), &it, __item__) \ + __f__(__item__); \ + } while(0) + +#endif Index: tags/2.3.0/src/main.c =================================================================== --- tags/2.3.0/src/main.c (nonexistent) +++ tags/2.3.0/src/main.c (revision 33253) @@ -0,0 +1,575 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2004 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include + +static const char *EXPERIMENTAL = NULL; + +#include +#include +#include +#include /* Seed for srand() */ +#include + +#include "board.h" +#include "brave.h" +#include "data.h" +#include +#include "plug_io.h" +#include "buffer.h" +#include "crosshair.h" +#include +#include "polygon.h" +#include "buildin.h" +#include "build_run.h" +#include +#include "flag.h" +#include "flag_str.h" +#include +#include "plug_footprint.h" +#include "plug_import.h" +#include "event.h" +#include +#include +#include "conf_core.h" +#include +#include +#include "layer_vis.h" +#include "layer_ui.h" +#include "obj_text.h" +#include "pcb_minuid.h" +#include +#include +#include "netlist.h" +#include "extobj.h" +#include + +#include +#include "actions_pcb.h" +#include +#include +#include "tool_logic.h" +#include "pixmap_pcb.h" + +const char *rnd_menu_file_paths[4]; +const char *rnd_menu_name_fmt = "pcb-menu-%s.lht"; + +#define CONF_USER_DIR "~/" DOT_PCB_RND +const char *rnd_conf_userdir_path, *rnd_pcphl_conf_user_path; +const char *rnd_conf_sysdir_path, *rnd_conf_sys_path; +const char *rnd_app_package = PCB_PACKAGE; +const char *rnd_app_version = PCB_VERSION; +const char *rnd_app_url = "http://repo.hu/projects/pcb-rnd"; + +/* Figure out the canonical name of the executed program + and fix up the defaults for various paths; returns exec prefix that + should be saved in the config */ +static char *main_path_init(char *argv0) +{ + size_t l; + int haspath; + char *t1, *t2; + int found_bindir = 0, se = 0; + char *exec_prefix = NULL; + char *bindir = NULL, *tmp; + + + /* see if argv0 has enough of a path to let lrealpath give the + real path. This should be the case if you invoke pcb with + something like /usr/local/bin/pcb or ./pcb or ./foo/pcb + but if you just use pcb and it exists in your path, you'll + just get back pcb again. */ + haspath = (strchr(argv0, RND_DIR_SEPARATOR_C) != NULL); + +#ifdef DEBUG + printf("main_path_init (%s): haspath = %d\n", argv0, haspath); +#endif + + if (haspath) { + bindir = rnd_lrealpath(argv0); + found_bindir = 1; + } + else { + char *path, *p, *tmps; + struct stat sb; + int r; + + tmps = getenv("PATH"); + + if (tmps != NULL) { + path = rnd_strdup(tmps); + + /* search through the font path for a font file */ + for (p = strtok(path, RND_PATH_DELIMETER); p && *p; p = strtok(NULL, RND_PATH_DELIMETER)) { +#ifdef DEBUG + printf("Looking for %s in %s\n", argv0, p); +#endif + if ((tmps = (char *) malloc((strlen(argv0) + strlen(p) + 2) * sizeof(char))) == NULL) { + fprintf(stderr, "main_path_init(): malloc failed\n"); + exit(1); + } + sprintf(tmps, "%s%s%s", p, RND_DIR_SEPARATOR_S, argv0); + r = stat(tmps, &sb); + if (r == 0) { +#ifdef DEBUG + printf("Found it: \"%s\"\n", tmps); +#endif + bindir = rnd_lrealpath(tmps); + found_bindir = 1; + free(tmps); + break; + } + free(tmps); + } + free(path); + } + } + + if (found_bindir) { + /* strip off the executable name leaving only the path */ + t2 = NULL; + t1 = strchr(bindir, RND_DIR_SEPARATOR_C); + while (t1 != NULL && *t1 != '\0') { + t2 = t1; + t1 = strchr(t2 + 1, RND_DIR_SEPARATOR_C); + } + if (t2 != NULL) + *t2 = '\0'; + } + else { + /* we have failed to find out anything from argv[0] so fall back to the original install prefix */ + bindir = rnd_strdup(BINDIR); + } + + /* now find the path to exec_prefix */ + l = strlen(bindir) + 1 + strlen(BINDIR_TO_EXECPREFIX) + 1; + if ((exec_prefix = (char *) malloc(l * sizeof(char))) == NULL) { + fprintf(stderr, "main_path_init(): malloc failed\n"); + exit(1); + } + sprintf(exec_prefix, "%s%s%s", bindir, RND_DIR_SEPARATOR_S, BINDIR_TO_EXECPREFIX); + + /* export the most important paths and data for child processes (e.g. parametric footprints) */ + tmp = rnd_concat(PCBSHAREDIR, "/pcblib", NULL); + se |= rnd_setenv("PCB_RND_VERSION", PCB_VERSION, 1); + se |= rnd_setenv("PCB_RND_REVISION", PCB_REVISION, 1); + se |= rnd_setenv("PCB_RND_PCBLIB", tmp, 1); + se |= rnd_setenv("PCB_RND_SHARE", PCBSHAREDIR, 1); + se |= rnd_setenv("PCB_RND_LIB", PCBLIBDIR, 1); + se |= rnd_setenv("PCB_RND_EXEC_PREFIX", exec_prefix, 1); + free(tmp); + + if (se != 0) + fprintf(stderr, "WARNING: setenv() failed - external commands such as parametric footprints may not have a proper environment\n"); + + rnd_menu_file_paths[0] = "./"; + rnd_menu_file_paths[1] = "~/.pcb-rnd/"; + rnd_menu_file_paths[2] = rnd_concat(PCBCONFDIR, "/", NULL); + rnd_menu_file_paths[3] = NULL; + + rnd_conf_userdir_path = CONF_USER_DIR; + rnd_pcphl_conf_user_path = rnd_concat(CONF_USER_DIR, "/pcb-conf.lht", NULL); + rnd_conf_sysdir_path = PCBCONFDIR; + rnd_conf_sys_path = rnd_concat(PCBCONFDIR, "/pcb-conf.lht", NULL); + + free(bindir); + return exec_prefix; +} + +static void main_path_uninit(void) +{ + /* const for all other parts of the code, but we had to concat (alloc) it above */ + free((char *)rnd_menu_file_paths[2]); + free((char *)rnd_pcphl_conf_user_path); + free((char *)rnd_conf_sys_path); +} + + +/* initialize signal and error handlers */ +static void main_sighand_init(void) +{ +#ifdef RND_HAVE_SIGHUP + signal(SIGHUP, pcb_catch_signal); +#endif +#ifdef RND_HAVE_SIGQUIT + signal(SIGQUIT, pcb_catch_signal); +#endif +#ifdef RND_HAVE_SIGTERM + signal(SIGTERM, pcb_catch_signal); +#endif +#ifdef RND_HAVE_SIGINT + signal(SIGINT, pcb_catch_signal); +#endif + +#ifdef NDEBUG +/* so that we get a core dump on segfault in debug mode */ +# ifdef RND_HAVE_SIGABRT + signal(SIGABRT, pcb_catch_signal); +# endif +# ifdef RND_HAVE_SIGSEGV + signal(SIGSEGV, pcb_catch_signal); +# endif +#endif + +/* calling external program by popen() may cause a PIPE signal, so we ignore it */ +#ifdef RND_HAVE_SIGPIPE + signal(SIGPIPE, SIG_IGN); +#endif +} + +/* ---------------------------------------------------------------------- + * main program + */ +static void gui_support_plugins(int load) +{ + static int loaded = 0; + static pup_plugin_t *puphand; + + if (load && !loaded) { + static const char *plugin_name = "dialogs"; + 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; + } +} + +extern void pcb_buffer_init2(void); +extern void pcb_brave_init2(void); +extern void pcb_change_act_init2(void); +extern void pcb_conf_act_init2(void); +extern void pcb_drc_act_init2(void); +extern void pcb_extobj_act_init2(void); +extern void pcb_file_act_init2(void); +extern void pcb_font_act_init2(void); +extern void pcb_gui_act_init2(void); +extern void pcb_main_act_init2(void); +extern void pcb_netlist_act_init2(void); +extern void pcb_object_act_init2(void); +extern void pcb_poly_act_init2(void); +extern void pcb_plug_footprint_act_init2(void); +extern void pcb_pstk_act_init2(void); +extern void pcb_rats_act_init2(void); +extern void pcb_rats_patch_init2(void); +extern void pcb_remove_act_init2(void); +extern void pcb_select_act_init2(void); +extern void pcb_undo_act_init2(void); + +void pcb_main_init_actions(void) +{ + pcb_buffer_init2(); + pcb_brave_init2(); + pcb_change_act_init2(); + pcb_conf_act_init2(); + pcb_drc_act_init2(); + pcb_extobj_act_init2(); + pcb_file_act_init2(); + pcb_font_act_init2(); + pcb_gui_act_init2(); + pcb_main_act_init2(); + pcb_netlist_act_init2(); + pcb_object_act_init2(); + pcb_poly_act_init2(); + pcb_plug_footprint_act_init2(); + pcb_pstk_act_init2(); + pcb_rats_act_init2(); + pcb_rats_patch_init2(); + pcb_remove_act_init2(); + pcb_select_act_init2(); + pcb_undo_act_init2(); +} + +extern void pcb_poly_uninit(void); + +void pcb_main_uninit(void) +{ + if (rnd_log_last != NULL) + rnd_log_last->seen = 1; /* ignore anything unseen before the uninit */ + + conf_core_uninit_pre(); + pcb_brave_uninit(); + pcb_polygon_uninit(); + + pcb_text_uninit(); + pcb_layer_vis_uninit(); + + pcb_strflg_uninit_buf(); + pcb_strflg_uninit_layerlist(); + + gui_support_plugins(0); + rnd_render = rnd_gui = NULL; + pcb_crosshair_uninit(); + pcb_tool_logic_uninit(); + + if (PCB != NULL) { + pcb_uninit_buffers(PCB); + + /* Free up memory allocated to the PCB. Why bother when we're about to exit ? + Because it removes some false positives from heap bug detectors such as + valgrind. */ + pcb_board_free(PCB); + free(PCB); + } + PCB = NULL; + + pcb_extobj_uninit(); + + rnd_hidlib_uninit(); /* plugin unload */ + + rnd_funchash_uninit(); + rnd_file_loaded_uninit(); + pcb_uilayer_uninit(); + rnd_cli_uninit(); + pcb_dynflag_uninit(); + + pcb_import_uninit(); + pcb_pixmap_uninit(); + pcb_io_uninit(); + pcb_fp_uninit(); + pcb_fp_host_uninit(); + rnd_tool_uninit(); + pcb_poly_uninit(); + + rnd_log_print_uninit_errs("Log produced during uninitialization"); + rnd_log_uninit(); + main_path_uninit(); + conf_core_uninit(); +} + +/* action table number of columns for a single action */ +const char *pcb_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, "-dump-oflags", "DumpObjFlags()", "Print object flags and exit", NULL, + NULL, "-show-paths", "PrintPaths()", "Print all configured paths and exit", NULL, + NULL, "-dump-config", "dumpconf(native,1)", "Print the config tree and exit", "Config dump not available - make sure you have configured pcb-rnd with --buildin-diag", + "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 print_pup_err(pup_err_stack_t *entry, char *string) +{ + rnd_message(RND_MSG_ERROR, "puplug: %s\n", string); +} + +#include "funchash_core.h" +#define action_entry(x) { #x, F_ ## x}, +static rnd_funchash_table_t Functions[] = { +#include "funchash_core_list.h" + {"F_END", F_END} +}; + +int main(int argc, char *argv[]) +{ + int n; + char **sp, *exec_prefix, *command_line_pcb = NULL; + + rnd_main_args_t ga; + + rnd_conf_dot_dir = DOT_PCB_RND; + rnd_conf_lib_dir = PCBLIBDIR; + + rnd_fix_locale_and_env(); + exec_prefix = main_path_init(argv[0]); + + pcb_crosshair_pre_init(); + + rnd_main_args_init(&ga, argc, pcb_action_args); + + /* init application: + - make program name available for error handlers + - initialize infrastructure (e.g. the conf system) + - evaluate options + - create an empty PCB with default symbols + - register 'call on exit()' function */ + + /* Minimal conf setup before we do anything else */ + pcb_netlist_geo_init(); + pcb_minuid_init(); + pcb_extobj_init(); + + rnd_hidlib_init1(conf_core_init); + pcb_event_init_app(); + rnd_conf_set(RND_CFR_INTERNAL, "rc/path/exec_prefix", -1, exec_prefix, RND_POL_OVERWRITE); + free(exec_prefix); + + pcb_layer_vis_init(); + pcb_brave_init(); + pcb_pixmap_init(); + + /* process arguments */ + for(n = 1; n < argc; n++) { + /* optionally: handle extra arguments, not processed by the hidlib, here */ + n += rnd_main_args_add(&ga, argv[n], argv[n+1]); + } + rnd_tool_init(); + pcb_tool_logic_init(); + + rnd_hidlib_init2(pup_buildins, NULL); + pcb_actions_init_pcb_only(); + + setbuf(stdout, 0); + + pcb_fp_init(); + + srand(time(NULL)); /* Set seed for rand() */ + + rnd_funchash_set_table(Functions, RND_ENTRIES(Functions), NULL); + pcb_polygon_init(); + + /* Register a function to be called when the program terminates. This makes + sure that data is saved even if LEX/YACC routines abort the program. + If the OS doesn't have at least one of them, the critical sections will + be handled by parse_l.l */ + atexit(pcb_emergency_save); + + pcb_text_init(); + + if (rnd_pup.err_stack != NULL) { + rnd_message(RND_MSG_ERROR, "Some of the static linked buildins could not be loaded:\n"); + pup_err_stack_process_str(&rnd_pup, print_pup_err); + } + + for(sp = rnd_pup_paths; *sp != NULL; sp++) { + rnd_message(RND_MSG_DEBUG, "Loading plugins from '%s'\n", *sp); + pup_autoload_dir(&rnd_pup, *sp, (const char **)rnd_pup_paths); + } + if (rnd_pup.err_stack != NULL) { + rnd_message(RND_MSG_ERROR, "Some of the dynamic linked plugins could not be loaded:\n"); + pup_err_stack_process_str(&rnd_pup, print_pup_err); + } + + if (rnd_main_args_setup1(&ga) != 0) { + pcb_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). */ + pcb_main_init_actions(); + + if (rnd_main_args_setup2(&ga, &n) != 0) { + pcb_main_uninit(); + rnd_main_args_uninit(&ga); + exit(n); + } + + if (RND_HAVE_GUI_ATTR_DLG) + gui_support_plugins(1); + + /* Create a new PCB object in memory */ + PCB = pcb_board_new(0); + + if (PCB == NULL) { + rnd_message(RND_MSG_ERROR, "Can't create an empty layout, exiting\n"); + rnd_log_print_uninit_errs("Initialization"); + exit(1); + } + + /* Update board layer colors and buffer bindings */ + pcb_board_new_postproc(PCB, 1); + + pcb_layervis_reset_stack(&PCB->hidlib); + + if (rnd_gui->gui) + pcb_crosshair_init(); + main_sighand_init(); + pcb_init_buffers(PCB); + + if (ga.hid_argc > 0) + command_line_pcb = ga.hid_argv[0]; + if (command_line_pcb) { + int how = conf_core.rc.silently_create_on_load ? 0x10 : 0; + if (pcb_load_pcb(command_line_pcb, NULL, rnd_true, how) != 0) { + if (rnd_main_exporting) { + rnd_message(RND_MSG_ERROR, "Can not load file '%s' (specified on command line) for exporting or printing\n", command_line_pcb); + rnd_log_print_uninit_errs("Export load error"); + exit(1); + } + /* keep filename if load failed: file might not exist, save it by that name */ + PCB->hidlib.filename = rnd_strdup(command_line_pcb); + } + } + + if (conf_core.design.initial_layer_stack && conf_core.design.initial_layer_stack[0]) + rnd_message(RND_MSG_ERROR, "Config setting desgin/initial_layer_stack is set but is deprecated and ignored. Please edit your config files to remove it.\n"); + + /* read the library file and display it if it's not empty */ + if (!pcb_fp_read_lib_all() && pcb_library.data.dir.children.used) + rnd_event(&PCB->hidlib, PCB_EVENT_LIBRARY_CHANGED, NULL); + + if (conf_core.rc.script_filename) { + rnd_message(RND_MSG_INFO, "Executing startup script file %s\n", conf_core.rc.script_filename); + rnd_actionva(&PCB->hidlib, "ExecuteFile", conf_core.rc.script_filename, NULL); + } + if (conf_core.rc.action_string) { + rnd_message(RND_MSG_INFO, "Executing startup action %s\n", conf_core.rc.action_string); + rnd_parse_actions(&PCB->hidlib, conf_core.rc.action_string); + } + + if (rnd_main_exported(&ga, &PCB->hidlib, pcb_data_is_empty(PCB->Data))) { + pcb_main_uninit(); + rnd_main_args_uninit(&ga); + exit(0); + } + + pcb_enable_autosave(); + + /* 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 pcb-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_tool_select_by_name(&PCB->hidlib, "arrow"); + rnd_event(&PCB->hidlib, PCB_EVENT_LIBRARY_CHANGED, NULL); + rnd_mainloop_interactive(&ga, &PCB->hidlib); + + pcb_main_uninit(); + rnd_main_args_uninit(&ga); + return 0; +} Index: tags/2.3.0/src/main_act.c =================================================================== --- tags/2.3.0/src/main_act.c (nonexistent) +++ tags/2.3.0/src/main_act.c (revision 33253) @@ -0,0 +1,317 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#define Progname "pcb-rnd" + +#include "config.h" + +#include +#include "config.h" + +#include "board.h" +#include "data.h" +#include "crosshair.h" +#include "actions_pcb.h" +#include +#include "layer.h" +#include +#include "conf_core.h" +#include "build_run.h" +#include +#include "flag_str.h" +#include "obj_common.h" +#include + +#define PCB do_not_use_PCB + +/* print usage lines */ +static 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 pcb_acts_PrintUsage[] = + "PrintUsage()\n" + "PrintUsage(plugin)"; + +static const char pcb_acth_PrintUsage[] = "Print command line arguments of pcb-rnd or a plugin loaded."; + +static int help0(void) +{ + rnd_hid_t **hl = rnd_hid_enumerate(); + int i; + + u("pcb-rnd Printed Circuit Board editing program, http://repo.hu/projects/pcb-rnd"); + u("For more information, please read the topic help pages:"); + u(" %s --help topic", Progname); + u("Topics are:"); + u(" invocation how to run pcb-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 *pcb_action_args[]; +extern const int PCB_ACTION_ARGS_WIDTH; +static int help_main(void) { + const char **cs; + for(cs = pcb_action_args; cs[2] != NULL; cs += RND_ACTION_ARGS_WIDTH) { + fprintf(stderr, "%s [", Progname); + 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_gui = 0, n_exporter = 0; + + u("pcb-rnd invocation:"); + u(""); + u("%s [main options] See --help main", Progname); + u(""); + u("%s [generics] [--gui GUI] [gui options] interactive GUI", Progname); + + u("Available GUI hid%s:", n_gui == 1 ? "" : "s"); + for (i = 0; hl[i]; i++) + if (hl[i]->gui) + fprintf(stderr, "\t%-8s %s\n", hl[i]->name, hl[i]->description); + + u("\n%s [generics] -p [printing options] \tto print", Progname); + 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("\n%s [generics] -x hid [export options] \tto export", Progname); + 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 pcb_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 pcb_acts_PrintVersion[] = "PrintVersion()"; +static const char pcb_acth_PrintVersion[] = "Print version."; +fgw_error_t pcb_act_PrintVersion(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + printf("%s\n", pcb_get_info_program()); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_DumpVersion[] = "DumpVersion()"; +static const char pcb_acth_DumpVersion[] = "Dump version in script readable format."; +fgw_error_t pcb_act_DumpVersion(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + printf("%s\n", PCB_VERSION); + printf("%s\n", PCB_REVISION); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_PrintCopyright[] = "PrintCopyright()"; +static const char pcb_acth_PrintCopyright[] = "Print copyright notice."; +fgw_error_t pcb_act_PrintCopyright(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + printf("%s\n", pcb_get_info_copyright()); + printf("%s\n", pcb_get_info_license()); + + 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 pcb_acts_PrintPaths[] = "PrintPaths()"; +static const char pcb_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 pcb_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]); + } + printf("rc/default_font_file ="); print_list(&conf_core.rc.default_font_file); + printf("rc/library_search_paths ="); print_list(&conf_core.rc.library_search_paths); + printf("rc/library_shell = \"%s\"\n", conf_core.rc.library_shell); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_DumpObjFlags[] = "DumpObjFlags()"; +static const char pcb_acth_DumpObjFlags[] = "Print a script processable digest of all flags, per object type"; +static void dumpoflg(void *ctx, unsigned long flg, const pcb_flag_bits_t *fb) +{ + printf(" %lx %s %s\n", flg, fb->name, fb->help); +} +fgw_error_t pcb_act_DumpObjFlags(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + unsigned long ot, max = PCB_OBJ_CLASS_REAL + 1; + + for(ot = 1; ot < max; ot <<= 1) { + const char *name = pcb_obj_type_name(ot); + + if (*name == '<') + continue; + printf("%s\n", name); + pcb_strflg_map(0x7fffffff, ot, NULL, dumpoflg); + } + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_System[] = "System(shell_cmd)"; +static const char pcb_acth_System[] = "Run shell command"; +fgw_error_t pcb_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("PCB_RND_BOARD_FILE_NAME", RND_ACT_HIDLIB->filename == NULL ? "" : RND_ACT_HIDLIB->filename, 1); + rnd_snprintf(tmp, sizeof(tmp), "%mm", pcb_crosshair.X); + rnd_setenv("PCB_RND_CROSSHAIR_X_MM", tmp, 1); + rnd_snprintf(tmp, sizeof(tmp), "%mm", pcb_crosshair.Y); + rnd_setenv("PCB_RND_CROSSHAIR_Y_MM", tmp, 1); + rnd_setenv("PCB_RND_CURRENT_LAYER_NAME", PCB_CURRLAYER(PCB_ACT_BOARD)->name, 1); + RND_ACT_IRES(rnd_system(RND_ACT_HIDLIB, cmd)); + return 0; +} + +static const char pcb_acts_ExecuteFile[] = "ExecuteFile(filename)"; +static const char pcb_acth_ExecuteFile[] = "Run actions from the given file."; +/* DOC: executefile.html */ +fgw_error_t pcb_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(pcb_act_execute_file(RND_ACT_HIDLIB, fname)); + return 0; +} + +static rnd_action_t main_action_list[] = { + {"PrintUsage", pcb_act_PrintUsage, pcb_acth_PrintUsage, pcb_acts_PrintUsage}, + {"PrintVersion", pcb_act_PrintVersion, pcb_acth_PrintVersion, pcb_acts_PrintVersion}, + {"DumpVersion", pcb_act_DumpVersion, pcb_acth_DumpVersion, pcb_acts_DumpVersion}, + {"PrintCopyright", pcb_act_PrintCopyright, pcb_acth_PrintCopyright, pcb_acts_PrintCopyright}, + {"PrintPaths", pcb_act_PrintPaths, pcb_acth_PrintPaths, pcb_acts_PrintPaths}, + {"DumpObjFlags", pcb_act_DumpObjFlags, pcb_acth_DumpObjFlags, pcb_acts_DumpObjFlags}, + {"System", pcb_act_System, pcb_acth_System, pcb_acts_System}, + {"ExecCommand", pcb_act_System, pcb_acth_System, pcb_acts_System}, + {"ExecuteFile", pcb_act_ExecuteFile, pcb_acth_ExecuteFile, pcb_acts_ExecuteFile} +}; + +void pcb_main_act_init2(void) +{ + RND_REGISTER_ACTIONS(main_action_list, NULL); +} Index: tags/2.3.0/src/move.c =================================================================== --- tags/2.3.0/src/move.c (nonexistent) +++ tags/2.3.0/src/move.c (revision 33253) @@ -0,0 +1,311 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include "conf_core.h" + +#include + +#include "board.h" +#include "data.h" +#include "draw.h" +#include +#include "move.h" +#include "select.h" +#include "undo.h" +#include "event.h" +#include +#include +#include "obj_arc_op.h" +#include "obj_line_op.h" +#include "obj_text_op.h" +#include "obj_subc_op.h" +#include "obj_poly_op.h" +#include "obj_pstk_op.h" +#include "obj_rat_op.h" +#include "obj_gfx_op.h" + +pcb_opfunc_t MoveFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_move, + pcb_textop_move, + pcb_polyop_move, + pcb_lineop_move_point, + pcb_polyop_move_point, + pcb_arcop_move, + pcb_gfxop_move, + NULL, + NULL, + pcb_subcop_move, + pcb_pstkop_move, + 0 /* extobj_inhibit_regen */ +}; + +pcb_opfunc_t MoveFunctions_noclip = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_move_noclip, + pcb_textop_move_noclip, + pcb_polyop_move_noclip, + NULL, + NULL, + pcb_arcop_move_noclip, + pcb_gfxop_move_noclip, + NULL, + NULL, + NULL, /* subc */ + pcb_pstkop_move_noclip, + 0 /* extobj_inhibit_regen */ +}; + +pcb_opfunc_t ClipFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_clip, + pcb_textop_clip, + pcb_polyop_clip, + NULL, + NULL, + pcb_arcop_clip, + NULL, /* gfx */ + NULL, + NULL, + NULL, /* subc */ + pcb_pstkop_clip, + 1 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t MoveToLayerFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_move_to_layer, + pcb_textop_move_to_layer, + pcb_polyop_move_to_layer, + NULL, + NULL, + pcb_arcop_move_to_layer, + pcb_gfxop_move_to_layer, + pcb_ratop_move_to_layer, + NULL, + NULL, /* subc */ + NULL, /* padstack */ + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t CopyFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_copy, + pcb_textop_copy, + pcb_polyop_copy, + NULL, + NULL, + pcb_arcop_copy, + pcb_gfxop_copy, + NULL, + NULL, + pcb_subcop_copy, + pcb_pstkop_copy, + 0 /* extobj_inhibit_regen */ +}; + + +void *pcb_move_obj(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t DX, rnd_coord_t DY) +{ + void *result; + pcb_opctx_t ctx; + + ctx.move.pcb = PCB; + ctx.move.dx = DX; + ctx.move.dy = DY; + pcb_undo_add_obj_to_move(Type, Ptr1, Ptr2, Ptr3, DX, DY); + result = pcb_object_operation(&MoveFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); + return result; +} + +void *pcb_move_obj_and_rubberband(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t DX, rnd_coord_t DY) +{ + pcb_opctx_t ctx; + void *ptr2; + + if ((DX == 0) && (DY == 0) && (conf_core.editor.move_linepoint_uses_route == 0)) + return NULL; + + ctx.move.pcb = PCB; + ctx.move.dx = DX; + ctx.move.dy = DY; + + pcb_data_clip_inhibit_inc(PCB->Data); + pcb_draw_inhibit_inc(); + + switch(Type) { + case PCB_OBJ_ARC_POINT: + { + /* Get the initial arc point positions */ + pcb_arc_t * p_arc = ((pcb_arc_t *)pcb_crosshair.AttachedObject.Ptr2); + rnd_coord_t ox1,ox2,oy1,oy2; + rnd_coord_t nx1,nx2,ny1,ny2; + + pcb_arc_get_end(p_arc,0, &ox1, &oy1); + pcb_arc_get_end(p_arc,1, &ox2, &oy2); + + /* moving the endpoint of an arc is not really a move, but a change of arc properties */ + if (pcb_crosshair.AttachedObject.radius == 0) + pcb_arc_set_angles((pcb_layer_t *)Ptr1, (pcb_arc_t *)Ptr2, + pcb_crosshair.AttachedObject.start_angle, + pcb_crosshair.AttachedObject.delta_angle); + else + pcb_arc_set_radii((pcb_layer_t *)Ptr1, (pcb_arc_t *)Ptr2, + pcb_crosshair.AttachedObject.radius, + pcb_crosshair.AttachedObject.radius); + pcb_crosshair.AttachedObject.radius = 0; + + /* Get the new arc point positions so that we can calculate the position deltas */ + pcb_arc_get_end(p_arc,0, &nx1, &ny1); + pcb_arc_get_end(p_arc,1, &nx2, &ny2); + rnd_event(&PCB->hidlib, PCB_EVENT_RUBBER_MOVE, "icccc", 0, nx1-ox1, ny1-oy1, nx2-ox2, ny2-oy2); + ptr2 = p_arc; + } + break; + + case PCB_OBJ_ARC: + rnd_event(&PCB->hidlib, PCB_EVENT_RUBBER_MOVE, "icccc", 0, DX, DY, DX, DY); + pcb_undo_add_obj_to_move(Type, Ptr1, Ptr2, Ptr3, DX, DY); + ptr2 = pcb_object_operation(&MoveFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); + break; + + case PCB_OBJ_LINE_POINT : + rnd_event(&PCB->hidlib, PCB_EVENT_RUBBER_MOVE, "icc", 0, DX, DY); + ptr2 = pcb_lineop_move_point_with_route(&ctx, Ptr1, Ptr2, Ptr3); + break; + + case PCB_OBJ_LINE: + { + rnd_coord_t dx1 = DX; + rnd_coord_t dy1 = DY; + rnd_coord_t dx2 = DX; + rnd_coord_t dy2 = DY; + pcb_line_t *line = (pcb_line_t*) Ptr2; + int constrained = 0; + + if(conf_core.editor.rubber_band_keep_midlinedir) + rnd_event(&PCB->hidlib, PCB_EVENT_RUBBER_CONSTRAIN_MAIN_LINE, "pppppp", line, &constrained, &dx1, &dy1, &dx2, &dy2); + rnd_event(&PCB->hidlib, PCB_EVENT_RUBBER_MOVE, "icccc", constrained, dx1, dy1, dx2, dy2); + + ctx.move.dx = dx1; + ctx.move.dy = dy1; + + /* If the line ends have moved indpendently then move the individual points */ + if((dx1 != dx2) || (dy1 != dy2)) { + /* Move point1 form line */ + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, + Ptr1, line, &line->Point1, + dx1, dy1); + pcb_lineop_move_point(&ctx, Ptr1, line, &line->Point1); + + /* Move point2 form line */ + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, + Ptr1, line, &line->Point2, + dx2, dy2); + ctx.move.dx = dx2; + ctx.move.dy = dy2; + ptr2 = pcb_lineop_move_point(&ctx, Ptr1, line, &line->Point2); + pcb_line_mod_merge(line, 1); + } + /* Otherwise make a normal move */ + else { + pcb_undo_add_obj_to_move(Type, Ptr1, Ptr2, Ptr3, dx1, dy1); + ptr2 = pcb_object_operation(&MoveFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); + pcb_line_mod_merge(ptr2, 1); + } + } + break; + + default: + rnd_event(&PCB->hidlib, PCB_EVENT_RUBBER_MOVE, "icc", 0, DX, DY); + pcb_undo_add_obj_to_move(Type, Ptr1, Ptr2, Ptr3, DX, DY); + ptr2 = pcb_object_operation(&MoveFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); + if (((pcb_any_obj_t *)ptr2)->type == PCB_OBJ_LINE) + pcb_line_mod_merge(ptr2, 1); + break; + } + + pcb_undo_inc_serial(); + + pcb_draw_inhibit_dec(); + pcb_data_clip_inhibit_dec(PCB->Data, 0); + pcb_draw(); + + return ptr2; +} + +void *pcb_move_obj_to_layer(int Type, void *Ptr1, void *Ptr2, void *Ptr3, pcb_layer_t *Target, rnd_bool enmasse) +{ + void *result; + pcb_opctx_t ctx; + + ctx.move.pcb = PCB; + ctx.move.dst_layer = Target; + ctx.move.more_to_come = enmasse; + + result = pcb_object_operation(&MoveToLayerFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); + pcb_undo_inc_serial(); + return result; +} + +rnd_bool pcb_move_selected_objs_to_layer(pcb_layer_t *Target) +{ + rnd_bool changed; + pcb_opctx_t ctx; + + ctx.move.pcb = PCB; + ctx.move.dst_layer = Target; + ctx.move.more_to_come = rnd_true; + + changed = pcb_selected_operation(PCB, PCB->Data, &MoveToLayerFunctions, &ctx, rnd_true, PCB_OBJ_ANY, 0); + /* passing rnd_true to above operation causes Undoserial to auto-increment */ + return changed; +} + +void *pcb_copy_obj(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t DX, rnd_coord_t DY) +{ + void *ptr; + pcb_opctx_t ctx; + + ctx.copy.pcb = PCB; + ctx.copy.DeltaX = DX; + ctx.copy.DeltaY = DY; + ctx.copy.from_outside = 0; + ctx.copy.keep_id = 0; + + /* the subroutines add the objects to the undo-list */ + ptr = pcb_object_operation(&CopyFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); + pcb_undo_inc_serial(); + return ptr; +} Index: tags/2.3.0/src/move.h =================================================================== --- tags/2.3.0/src/move.h (nonexistent) +++ tags/2.3.0/src/move.h (revision 33253) @@ -0,0 +1,63 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_MOVE_H +#define PCB_MOVE_H + +#include "config.h" + +/*** move ***/ +#define PCB_MOVE_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_LINE | PCB_OBJ_TEXT | PCB_OBJ_GFX | PCB_OBJ_GFX_POINT | PCB_OBJ_SUBC | \ + PCB_OBJ_POLY | PCB_OBJ_POLY_POINT | PCB_OBJ_LINE_POINT | PCB_OBJ_ARC | PCB_OBJ_ARC_POINT) +#define PCB_MOVETOLAYER_TYPES \ + (PCB_OBJ_LINE | PCB_OBJ_TEXT | PCB_OBJ_POLY | PCB_OBJ_RAT | PCB_OBJ_ARC | PCB_OBJ_GFX) + + +/* undoably moves an object by relative DX and DY. Doesn't bump + the undo serial. Operation wrapper. The rubberband version also moves + or modifies connected objects. */ +void *pcb_move_obj(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t DX, rnd_coord_t DY); +void *pcb_move_obj_and_rubberband(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t DX, rnd_coord_t DY); + +/* undoably moves objects to a different layer. Doesn't bump + the undo serial. Operation wrapper. */ +void *pcb_move_obj_to_layer(int Type, void *Ptr1, void *Ptr2, void *Ptr3, pcb_layer_t *Target, rnd_bool enmasse); +rnd_bool pcb_move_selected_objs_to_layer(pcb_layer_t *Target); + + +/*** copy ***/ +#define PCB_COPY_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_LINE | PCB_OBJ_TEXT | \ + PCB_OBJ_SUBC | PCB_OBJ_POLY | PCB_OBJ_ARC | PCB_OBJ_GFX) + +/* Undoably copies (duplicates) an object; the new objects is moved by DX,DY + (operation wrapper) */ +void *pcb_copy_obj(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t DX, rnd_coord_t DY); + +#endif Index: tags/2.3.0/src/netlist.c =================================================================== --- tags/2.3.0/src/netlist.c (nonexistent) +++ tags/2.3.0/src/netlist.c (revision 33253) @@ -0,0 +1,1136 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "data_it.h" +#include "event.h" +#include +#include "layer_grp.h" +#include "find.h" +#include "obj_term.h" +#include "conf_core.h" +#include "undo.h" +#include "obj_rat_draw.h" +#include "obj_subc_parent.h" +#include "search.h" +#include "remove.h" +#include "draw.h" + +#define TDL_DONT_UNDEF +#include "netlist.h" +#include + +#include + +static const char core_net_cookie[] = "core-net"; + +void pcb_net_term_free_fields(pcb_net_term_t *term) +{ + pcb_attribute_free(&term->Attributes); + free(term->refdes); + free(term->term); +} + +void pcb_net_term_free(pcb_net_term_t *term) +{ + pcb_net_term_free_fields(term); + free(term); +} + +static pcb_net_term_t *pcb_net_term_alloc(pcb_net_t *net, const char *refdes, const char *term) +{ + pcb_net_term_t *t; + + t = calloc(sizeof(pcb_net_term_t), 1); + t->type = PCB_OBJ_NET_TERM; + t->parent_type = PCB_PARENT_NET; + t->parent.net = net; + t->refdes = rnd_strdup(refdes); + t->term = rnd_strdup(term); + pcb_termlist_append(&net->conns, t); + return t; +} + +/*** undoable term alloc ***/ +typedef struct { + pcb_board_t *pcb; + int nl_idx; + char *netname; /* have to save net by name because pcb_net_t * is not persistent for removal */ + char *refdes; + char *term; +} undo_term_alloc_t; + +static int undo_term_alloc_redo(void *udata) +{ + undo_term_alloc_t *a = udata; + pcb_net_t *net = pcb_net_get(a->pcb, &a->pcb->netlist[a->nl_idx], a->netname, PCB_NETA_NOALLOC); + if (pcb_net_term_alloc(net, a->refdes, a->term) == NULL) + return -1; + pcb_netlist_changed(0); + return 0; +} + +static int undo_term_alloc_undo(void *udata) +{ + undo_term_alloc_t *a = udata; + pcb_net_t *net = pcb_net_get(a->pcb, &a->pcb->netlist[a->nl_idx], a->netname, PCB_NETA_NOALLOC); + pcb_net_term_t *term; + int res; + + if (net == NULL) { + rnd_message(RND_MSG_ERROR, "undo_term_alloc_undo failed: net is NULL\n"); + return -1; + } + + term = pcb_net_term_get(net, a->refdes, a->term, PCB_NETA_NOALLOC); + if (term == NULL) { + rnd_message(RND_MSG_ERROR, "undo_term_alloc_undo failed: term is NULL\n"); + return -1; + } + + res = pcb_net_term_del(net, term); + if (res == 0) + pcb_netlist_changed(0); + return res; +} + +static void undo_term_alloc_print(void *udata, char *dst, size_t dst_len) +{ + undo_term_alloc_t *a = udata; + rnd_snprintf(dst, dst_len, "net_term_alloc: %s/%d %s-%s", a->netname, a->nl_idx, a->refdes, a->term); +} + +static void undo_term_alloc_free(void *udata) +{ + undo_term_alloc_t *a = udata; + free(a->netname); + free(a->refdes); + free(a->term); +} + + +static const uundo_oper_t undo_term_alloc = { + core_net_cookie, + undo_term_alloc_free, + undo_term_alloc_undo, + undo_term_alloc_redo, + undo_term_alloc_print +}; + +pcb_net_term_t *pcb_net_term_get(pcb_net_t *net, const char *refdes, const char *term, pcb_net_alloc_t alloc) +{ + undo_term_alloc_t *a; + pcb_net_term_t *t; + + /* for allocation this is slow, O(N^2) algorithm, but other than a few + biggish networks like GND, there won't be too many connections anyway) */ + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) { + if ((strcmp(t->refdes, refdes) == 0) && (strcmp(t->term, term) == 0)) + return t; + } + + switch(alloc) { + case PCB_NETA_NOALLOC: + return NULL; + case PCB_NETA_ALLOC_UNDOABLE: + if (net->parent_nl_idx >= 0) { + assert(net->parent_type == PCB_PARENT_BOARD); + a = pcb_undo_alloc(net->parent.board, &undo_term_alloc, sizeof(undo_term_alloc_t)); + a->pcb = net->parent.board; + a->nl_idx = net->parent_nl_idx; + a->netname = rnd_strdup(net->name); + a->refdes = rnd_strdup(refdes); + a->term = rnd_strdup(term); + return pcb_net_term_alloc(net, a->refdes, a->term); + } + else + rnd_message(RND_MSG_ERROR, "Internal error: failed to add terminal in an undoable way\nUndo will not affect this temrinal. Please report this bug."); + /* intentional fall-through */ + case PCB_NETA_ALLOC: + return pcb_net_term_alloc(net, refdes, term); + } + return NULL; +} + +pcb_net_term_t *pcb_net_term_get_by_obj(pcb_net_t *net, const pcb_any_obj_t *obj) +{ + pcb_data_t *data; + pcb_subc_t *sc; + + if (obj->term == NULL) + return NULL; + + if (obj->parent_type == PCB_PARENT_LAYER) + data = obj->parent.layer->parent.data; + else if (obj->parent_type == PCB_PARENT_DATA) + data = obj->parent.data; + else + return NULL; + + if (data->parent_type != PCB_PARENT_SUBC) + return NULL; + + sc = data->parent.subc; + if (sc->refdes == NULL) + return NULL; + + return pcb_net_term_get(net, sc->refdes, obj->term, PCB_NETA_NOALLOC); +} + +pcb_net_term_t *pcb_net_term_get_by_pinname(pcb_net_t *net, const char *pinname, pcb_net_alloc_t alloc) +{ + char tmp[256]; + char *pn, *refdes, *term; + int len = strlen(pinname)+1; + pcb_net_term_t *t = NULL; + + if (len <= sizeof(tmp)) { + pn = tmp; + memcpy(pn, pinname, len); + } + else + pn = rnd_strdup(pinname); + + + refdes = pn; + term = strchr(refdes, '-'); + if (term != NULL) { + *term = '\0'; + term++; + t = pcb_net_term_get(net, refdes, term, alloc); + } + + if (pn != tmp) + free(pn); + return t; + +} + + +int pcb_net_term_del(pcb_net_t *net, pcb_net_term_t *term) +{ + pcb_termlist_remove(term); + pcb_net_term_free(term); + return 0; +} + + +int pcb_net_term_del_by_name(pcb_net_t *net, const char *refdes, const char *term) +{ + pcb_net_term_t *t; + + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) + if ((strcmp(t->refdes, refdes) == 0) && (strcmp(t->term, term) == 0)) + return pcb_net_term_del(net, t); + + return -1; +} + +rnd_bool pcb_net_name_valid(const char *netname) +{ + for(;*netname != '\0'; netname++) { + if (isalnum(*netname)) continue; + switch(*netname) { + case '_': + break; + return rnd_false; + } + } + return rnd_true; +} + +static pcb_net_t *pcb_net_alloc_(pcb_board_t *pcb, pcb_netlist_t *nl, const char *netname) +{ + pcb_net_t *net; + int n; + + net = calloc(sizeof(pcb_net_t), 1); + net->type = PCB_OBJ_NET; + net->parent_type = PCB_PARENT_BOARD; + net->parent.board = pcb; + net->parent_nl_idx = -1; + for(n = 0; n < PCB_NUM_NETLISTS; n++) + if (nl == &pcb->netlist[n]) + net->parent_nl_idx = n; + net->name = rnd_strdup(netname); + htsp_set(nl, net->name, net); + return net; +} + +/*** undoable net alloc ***/ +typedef struct { + pcb_board_t *pcb; + int nl_idx; + char netname[1]; /* must be the last item, spans longer than 1 */ +} undo_net_alloc_t; + +static int undo_net_alloc_redo(void *udata) +{ + undo_net_alloc_t *a = udata; + if (pcb_net_alloc_(a->pcb, &a->pcb->netlist[a->nl_idx], a->netname) == NULL) + return -1; + pcb_netlist_changed(0); + return 0; +} + +static int undo_net_alloc_undo(void *udata) +{ + undo_net_alloc_t *a = udata; + int res = pcb_net_del(&a->pcb->netlist[a->nl_idx], a->netname); + if (res == 0) + pcb_netlist_changed(0); + return res; +} + +static void undo_net_alloc_print(void *udata, char *dst, size_t dst_len) +{ + undo_net_alloc_t *a = udata; + rnd_snprintf(dst, dst_len, "net_alloc: %d %s", a->nl_idx, a->netname); +} + +static const uundo_oper_t undo_net_alloc = { + core_net_cookie, + NULL, /* free */ + undo_net_alloc_undo, + undo_net_alloc_redo, + undo_net_alloc_print +}; + + +static pcb_net_t *pcb_net_alloc(pcb_board_t *pcb, pcb_netlist_t *nl, const char *netname, pcb_net_alloc_t alloc) +{ + int nl_idx = -1; + undo_net_alloc_t *a; + + assert(alloc != 0); + + if (alloc == PCB_NETA_ALLOC) + return pcb_net_alloc_(pcb, nl, netname); + + if (nl == &pcb->netlist[PCB_NETLIST_INPUT]) nl_idx = PCB_NETLIST_INPUT; + else if (nl == &pcb->netlist[PCB_NETLIST_EDITED]) nl_idx = PCB_NETLIST_EDITED; + else { + assert(!"netlist alloc is undoable only on board nets"); + return NULL; + } + + + a = pcb_undo_alloc(pcb, &undo_net_alloc, sizeof(undo_net_alloc_t) + strlen(netname)); + a->pcb = pcb; + a->nl_idx = nl_idx; + strcpy(a->netname, netname); + + return pcb_net_alloc_(pcb, nl, netname); +} + +pcb_net_t *pcb_net_get(pcb_board_t *pcb, pcb_netlist_t *nl, const char *netname, pcb_net_alloc_t alloc) +{ + pcb_net_t *net; + + if (nl == NULL) + return NULL; + + if (!pcb_net_name_valid(netname)) + return NULL; + + net = htsp_get(nl, netname); + if (net != NULL) + return net; + + if (alloc) + return pcb_net_alloc(pcb, nl, netname, alloc); + + return NULL; +} + +pcb_net_t *pcb_net_get_icase(pcb_board_t *pcb, pcb_netlist_t *nl, const char *name) +{ + htsp_entry_t *e; + + for(e = htsp_first(nl); e != NULL; e = htsp_next(nl, e)) { + pcb_net_t *net = e->value; + if (rnd_strcasecmp(name, net->name) == 0) + break; + } + + if (e == NULL) + return NULL; + return e->value; +} + +pcb_net_t *pcb_net_get_regex(pcb_board_t *pcb, pcb_netlist_t *nl, const char *rx) +{ + htsp_entry_t *e; + re_sei_t *regex; + + regex = re_sei_comp(rx); + if (re_sei_errno(regex) != 0) + return NULL; + + for(e = htsp_first(nl); e != NULL; e = htsp_next(nl, e)) { + pcb_net_t *net = e->value; + if (re_sei_exec(regex, net->name)) + break; + } + re_sei_free(regex); + + if (e == NULL) + return NULL; + return e->value; +} + +pcb_net_t *pcb_net_get_user(pcb_board_t *pcb, pcb_netlist_t *nl, const char *name_or_rx) +{ + pcb_net_t *net = pcb_net_get(pcb, nl, name_or_rx, 0); + if (net == NULL) + net = pcb_net_get_icase(pcb, nl, name_or_rx); + if (net == NULL) + net = pcb_net_get_regex(pcb, nl, name_or_rx); + return net; +} + +void pcb_net_free_fields(pcb_net_t *net) +{ + pcb_attribute_free(&net->Attributes); + free(net->name); + for(;;) { + pcb_net_term_t *term = pcb_termlist_first(&net->conns); + if (term == NULL) + break; + pcb_termlist_remove(term); + pcb_net_term_free(term); + } +} + +void pcb_net_free(pcb_net_t *net) +{ + pcb_net_free_fields(net); + free(net); +} + +int pcb_net_del(pcb_netlist_t *nl, const char *netname) +{ + htsp_entry_t *e; + + if (nl == NULL) + return -1; + + e = htsp_getentry(nl, netname); + if (e == NULL) + return -1; + + pcb_net_free(e->value); + + htsp_delentry(nl, e); + return 0; +} + +/* crawl from a single terminal; "first" sould be a pointer to an int + initialized to 0. Returns number of objects found. */ +static rnd_cardinal_t pcb_net_term_crawl(const pcb_board_t *pcb, pcb_net_term_t *term, pcb_find_t *fctx, int *first, rnd_cardinal_t *missing) +{ + pcb_any_obj_t *o; + +/* there can be multiple terminals with the same ID, but it is enough to run find from the first: find.c will consider them all */ + o = pcb_term_find_name(pcb, pcb->Data, PCB_LYT_COPPER, term->refdes, term->term, NULL, NULL); + if (o == NULL) { + if (missing != NULL) { + rnd_message(RND_MSG_WARNING, "Netlist problem: terminal %s-%s is missing from the board but referenced from the netlist\n", term->refdes, term->term); + (*missing)++; + } + return 0; + } + + if ((*first) == 0) { + *first = 1; + return pcb_find_from_obj(fctx, PCB->Data, o); + } + + if (PCB_FIND_IS_MARKED(fctx, o)) + return 0; /* already visited, no need to run 'find' again */ + + return pcb_find_from_obj_next(fctx, PCB->Data, o); +} + +void pcb_net_short_ctx_init(pcb_short_ctx_t *sctx, const pcb_board_t *pcb, pcb_net_t *net) +{ + sctx->pcb = pcb; + sctx->current_net = net; + sctx->changed = 0; + sctx->missing = 0; + sctx->num_shorts = 0; + sctx->cancel_advanced = 0; + htsp_init(&sctx->found, strhash, strkeyeq); +} + +void pcb_net_short_ctx_uninit(pcb_short_ctx_t *sctx) +{ + htsp_entry_t *e; + for(e = htsp_first(&sctx->found); e != NULL; e = htsp_next(&sctx->found, e)) + free(e->key); + htsp_uninit(&sctx->found); + if (sctx->changed) { + rnd_gui->invalidate_all(rnd_gui); + conf_core.temp.rat_warn = rnd_true; + } +} + +/* Return 1 if net1-net2 (or net2-net1) is already seen as a short, return 0 + else. Save net1-net2 as seen. */ +static int short_ctx_is_dup(pcb_short_ctx_t *sctx, pcb_net_t *net1, pcb_net_t *net2) +{ + char *key; + int order; + + order = strcmp(net1->name, net2->name); + + if (order == 0) { + rnd_message(RND_MSG_ERROR, "netlist internal error: short_ctx_is_dup() net %s shorted with itself?!\n", net1->name); + return 1; + } + if (order > 0) + key = rnd_concat(net1->name, "-", net2->name, NULL); + else + key = rnd_concat(net2->name, "-", net1->name, NULL); + + if (htsp_has(&sctx->found, key)) { + free(key); + return 1; + } + + htsp_set(&sctx->found, key, net1); + return 0; +} + +/* Short circuit found between net and an offender object that should not + be part of the net but is connected to the net */ +static void net_found_short(pcb_short_ctx_t *sctx, pcb_any_obj_t *offender) +{ + pcb_subc_t *sc = pcb_obj_parent_subc(offender); + int handled = 0; + + pcb_net_term_t *offt = pcb_net_find_by_refdes_term(&sctx->pcb->netlist[PCB_NETLIST_EDITED], sc->refdes, offender->term); + pcb_net_t *offn = NULL; + const char *offnn = ""; + + if (offt != NULL) { + offn = offt->parent.net; + offnn = offn->name; + if (short_ctx_is_dup(sctx, sctx->current_net, offn)) + return; + } + + if (offnn != NULL) + rnd_message(RND_MSG_WARNING, "SHORT: net \"%s\" is shorted to \"%s\" at terminal %s-%s\n", sctx->current_net->name, offnn, sc->refdes, offender->term); + else + rnd_message(RND_MSG_WARNING, "SHORT: net \"%s\" is shorted to terminal %s-%s\n", sctx->current_net->name, sc->refdes, offender->term); + + rnd_event(&PCB->hidlib, PCB_EVENT_NET_INDICATE_SHORT, "ppppp", sctx->current_net, offender, offn, &handled, &sctx->cancel_advanced); + if (!handled) { + pcb_net_term_t *orig_t = pcb_termlist_first(&sctx->current_net->conns); + pcb_any_obj_t *orig_o = pcb_term_find_name(sctx->pcb, sctx->pcb->Data, PCB_LYT_COPPER, orig_t->refdes, orig_t->term, NULL, NULL); + + /* dummy fallback: warning-highlight the two terminals */ + PCB_FLAG_SET(PCB_FLAG_WARN, offender); + if (orig_o != NULL) + PCB_FLAG_SET(PCB_FLAG_WARN, orig_o); + } + sctx->changed++; + sctx->num_shorts++; +} + +static int net_short_check(pcb_find_t *fctx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + if (new_obj->term != NULL) { + pcb_net_term_t *t; + pcb_short_ctx_t *sctx = fctx->user_data; + pcb_subc_t *sc = pcb_obj_parent_subc(new_obj); + + if ((sc == NULL) || (sc->refdes == NULL) || PCB_FLAG_TEST(PCB_FLAG_NONETLIST, sc)) + return 0; + + /* if new_obj is a terminal on our net, return */ + for(t = pcb_termlist_first(&sctx->current_net->conns); t != NULL; t = pcb_termlist_next(t)) + if ((strcmp(t->refdes, sc->refdes) == 0) && (strcmp(t->term, new_obj->term) == 0)) + return 0; + + /* new_obj is not on our net but has a refdes-term -> must be a short */ + net_found_short(fctx->user_data, new_obj); + } + + return 0; +} + +rnd_cardinal_t pcb_net_crawl_flag(pcb_board_t *pcb, pcb_net_t *net, unsigned long setf, unsigned long clrf) +{ + pcb_find_t fctx; + pcb_net_term_t *t; + rnd_cardinal_t res = 0, n; + pcb_short_ctx_t sctx; + int first = 0; + + pcb_net_short_ctx_init(&sctx, pcb, net); + + memset(&fctx, 0, sizeof(fctx)); + fctx.flag_set = setf; + fctx.flag_clr = clrf; + fctx.flag_chg_undoable = 1; + fctx.only_mark_rats = 1; /* do not trust rats, but do mark them */ + fctx.user_data = &sctx; + fctx.found_cb = net_short_check; + + for(t = pcb_termlist_first(&net->conns), n = 0; t != NULL; t = pcb_termlist_next(t), n++) { + res += pcb_net_term_crawl(pcb, t, &fctx, &first, NULL); + } + + pcb_find_free(&fctx); + pcb_net_short_ctx_uninit(&sctx); + return res; +} + +pcb_net_term_t *pcb_net_find_by_refdes_term(const pcb_netlist_t *nl, const char *refdes, const char *term) +{ + htsp_entry_t *e; + + for(e = htsp_first(nl); e != NULL; e = htsp_next(nl, e)) { + pcb_net_t *net = (pcb_net_t *)e->value; + pcb_net_term_t *t; + + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) + if ((strcmp(t->refdes, refdes) == 0) && (strcmp(t->term, term) == 0)) + return t; + } + + return NULL; +} + +pcb_net_term_t *pcb_net_find_by_pinname(const pcb_netlist_t *nl, const char *pinname) +{ + char tmp[256]; + char *pn, *refdes, *term; + int len = strlen(pinname)+1; + pcb_net_term_t *t = NULL; + + if (len <= sizeof(tmp)) { + pn = tmp; + memcpy(pn, pinname, len); + } + else + pn = rnd_strdup(pinname); + + refdes = pn; + term = strchr(refdes, '-'); + if (term != NULL) { + *term = '\0'; + term++; + t = pcb_net_find_by_refdes_term(nl, refdes, term); + } + + if (pn != tmp) + free(pn); + return t; +} + +pcb_net_term_t *pcb_net_find_by_obj(const pcb_netlist_t *nl, const pcb_any_obj_t *obj) +{ + const pcb_subc_t *sc; + + if (obj->term == NULL) + return NULL; + + sc = pcb_obj_parent_subc(obj); + if ((sc == NULL) || (sc->refdes == NULL)) + return NULL; + + return pcb_net_find_by_refdes_term(nl, sc->refdes, obj->term); +} + + + +static int netname_sort(const void *va, const void *vb) +{ + const pcb_net_t **a = (const pcb_net_t **)va; + const pcb_net_t **b = (const pcb_net_t **)vb; + return strcmp((*a)->name, (*b)->name); +} + +pcb_net_t **pcb_netlist_sort(pcb_netlist_t *nl) +{ + pcb_net_t **arr; + htsp_entry_t *e; + long n; + + if (nl->used == 0) + return NULL; + arr = malloc((nl->used+1) * sizeof(pcb_net_t)); + + for(e = htsp_first(nl), n = 0; e != NULL; e = htsp_next(nl, e), n++) + arr[n] = e->value; + qsort(arr, nl->used, sizeof(pcb_net_t *), netname_sort); + arr[nl->used] = NULL; + return arr; +} + +#include "netlist_geo.c" + +rnd_cardinal_t pcb_net_map_subnets(pcb_short_ctx_t *sctx, pcb_rat_accuracy_t acc, vtp0_t *subnets) +{ + pcb_find_t fctx; + pcb_net_term_t *t; + rnd_cardinal_t drawn = 0, r, n, s1, s2, su, sd; + pcb_subnet_dist_t *connmx; + char *done; + int left, first = 0; + pcb_rat_t *line; + + + memset(&fctx, 0, sizeof(fctx)); + fctx.consider_rats = 1; /* keep existing rats and their connections */ + fctx.list_found = 1; + fctx.user_data = sctx; + fctx.found_cb = net_short_check; + + /* each component of a desired network is called a subnet; already connected + objects of each subnet is collected on a vtp0_t; object-lists per subnet + is saved in variable "subnets" */ + for(t = pcb_termlist_first(&sctx->current_net->conns), n = 0; t != NULL; t = pcb_termlist_next(t), n++) { + r = pcb_net_term_crawl(sctx->pcb, t, &fctx, &first, &sctx->missing); + if (r > 0) { + vtp0_t *objs = malloc(sizeof(vtp0_t)); + memcpy(objs, &fctx.found, sizeof(vtp0_t)); + vtp0_append(subnets, objs); + memset(&fctx.found, 0, sizeof(vtp0_t)); + } + } + + /* find the shortest connection between any two subnets and save the info + in connmx */ + connmx = calloc(sizeof(pcb_subnet_dist_t), vtp0_len(subnets) * vtp0_len(subnets)); + for(s1 = 0; s1 < vtp0_len(subnets); s1++) { + for(s2 = s1+1; s2 < vtp0_len(subnets); s2++) { + connmx[s2 * vtp0_len(subnets) + s1] = connmx[s1 * vtp0_len(subnets) + s2] = pcb_subnet_dist(sctx->pcb, subnets->array[s1], subnets->array[s2], acc); + } + } + + /* Start collecting subnets into one big snowball of newly connected + subnets. done[subnet] is 1 if a subnet is already in the snowball. + Use a greedy algorithm: mark the first subnet as dine, then always + add the shortest from any 'undone' subnet to any 'done' */ + done = calloc(vtp0_len(subnets), 1); + done[0] = 1; + for(left = vtp0_len(subnets)-1; left > 0; left--) { + double best_dist = HUGE_VAL; + int bestu; + pcb_subnet_dist_t *best = NULL, *curr; + + for(su = 1; su < vtp0_len(subnets); su++) { + if (done[su]) continue; + for(sd = 0; sd < vtp0_len(subnets); sd++) { + curr = &connmx[su * vtp0_len(subnets) + sd]; + if ((done[sd]) && (curr->dist2 < best_dist)) { + bestu = su; + best_dist = curr->dist2; + best = curr; + } + } + } + + if (best == NULL) { + /* Unlikely: if there are enough restrictions on the search, e.g. + PCB_RATACC_ONLY_MANHATTAN for the old autorouter is on and some + subnets have only heavy terminals made of non-manhattan-lines, + we will not find a connection. When best is NULL, that means + no connection found between any undone subnet to any done subnet + found, so some subnets will remain disconnected (there is no point + in looping more, this won't improve) */ + sctx->missing++; + rnd_message(RND_MSG_WARNING, "Netlist problem: could not find the best rat line, rat missing (#1)\n"); + break; + } + + /* best connection is 'best' between from 'undone' network bestu; draw the rat */ + line = pcb_rat_new(sctx->pcb->Data, -1, + best->o1x, best->o1y, best->o2x, best->o2y, best->o1g, best->o2g, + conf_core.appearance.rat_thickness, pcb_no_flags(), + best->o1, best->o2); + if (line != NULL) { + pcb_undo_add_obj_to_create(PCB_OBJ_RAT, line, line, line); + pcb_rat_invalidate_draw(line); + drawn++; + } + else { + sctx->missing++; + rnd_message(RND_MSG_WARNING, "Netlist problem: could not find the best rat line, rat missing (#2)\n"); + } + done[bestu] = 1; + } + + /* cleanup */ + free(connmx); + free(done); + pcb_find_free(&fctx); + return drawn; +} + +void pcb_net_reset_subnets(vtp0_t *subnets) +{ + rnd_cardinal_t n; + for(n = 0; n < vtp0_len(subnets); n++) + vtp0_uninit(subnets->array[n]); + subnets->used = 0; +} + +void pcb_net_free_subnets(vtp0_t *subnets) +{ + pcb_net_reset_subnets(subnets); + vtp0_uninit(subnets); +} + + +rnd_cardinal_t pcb_net_add_rats(const pcb_board_t *pcb, pcb_net_t *net, pcb_rat_accuracy_t acc) +{ + rnd_cardinal_t res; + pcb_short_ctx_t sctx; + vtp0_t subnets; + + vtp0_init(&subnets); + pcb_net_short_ctx_init(&sctx, pcb, net); + res = pcb_net_map_subnets(&sctx, acc, &subnets); + pcb_net_short_ctx_uninit(&sctx); + pcb_net_free_subnets(&subnets); + return res; +} + + +rnd_cardinal_t pcb_net_add_all_rats(const pcb_board_t *pcb, pcb_rat_accuracy_t acc) +{ + htsp_entry_t *e; + rnd_cardinal_t drawn = 0; + pcb_short_ctx_t sctx; + vtp0_t subnets; + + vtp0_init(&subnets); + + if (acc & PCB_RATACC_INFO) + rnd_message(RND_MSG_INFO, "\n--- netlist check ---\n"); + + + pcb_net_short_ctx_init(&sctx, pcb, NULL); + + for(e = htsp_first(&pcb->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&pcb->netlist[PCB_NETLIST_EDITED], e)) { + pcb_net_t *net = e->value; + if (acc & PCB_RATACC_ONLY_SELECTED) { + pcb_net_term_t *t; + int has_selection = 0; + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) { + pcb_any_obj_t *o = pcb_term_find_name(pcb, pcb->Data, PCB_LYT_COPPER, t->refdes, t->term, NULL, NULL); + if ((o != NULL) && (PCB_FLAG_TEST(PCB_FLAG_SELECTED, o))) { + has_selection = 1; + break; + } + } + if (!has_selection) + continue; + } + + sctx.current_net = net; + if (sctx.current_net->inhibit_rats) + continue; + drawn += pcb_net_map_subnets(&sctx, acc, &subnets); + pcb_net_reset_subnets(&subnets); + } + + if (acc & PCB_RATACC_INFO) { + long rem = ratlist_length(&pcb->Data->Rat); + if (rem > 0) + rnd_message(RND_MSG_INFO, "%d rat line%s remaining\n", rem, rem > 1 ? "s" : ""); + else if (acc & PCB_RATACC_ONLY_SELECTED) + rnd_message(RND_MSG_WARNING, "No rat for any network that has selected terminal\n"); + else if (sctx.missing > 0) + rnd_message(RND_MSG_WARNING, "Nothing more to add, but there are\neither rat-lines in the layout, disabled nets\nin the net-list, or missing components\n"); + else if (sctx.num_shorts == 0) + rnd_message(RND_MSG_INFO, "Congratulations!!\n" "The layout is complete and has no shorted nets.\n"); + } + + vtp0_uninit(&subnets); + pcb_net_short_ctx_uninit(&sctx); + return drawn; +} + +void pcb_netlist_changed(int force_unfreeze) +{ + if (force_unfreeze) + PCB->netlist_frozen = 0; + if (PCB->netlist_frozen) + PCB->netlist_needs_update = 1; + else { + PCB->netlist_needs_update = 0; + rnd_event(&PCB->hidlib, PCB_EVENT_NETLIST_CHANGED, NULL); + } +} + +void pcb_netlist_init(pcb_netlist_t *nl) +{ + htsp_init(nl, strhash, strkeyeq); +} + + +void pcb_netlist_uninit(pcb_netlist_t *nl) +{ + htsp_entry_t *e; + + for(e = htsp_first(nl); e != NULL; e = htsp_next(nl, e)) + pcb_net_free(e->value); + + htsp_uninit(nl); +} + +void pcb_netlist_copy(pcb_board_t *pcb, pcb_netlist_t *dst, pcb_netlist_t *src) +{ + htsp_entry_t *e; + + assert(dst->used == 0); + for(e = htsp_first(src); e != NULL; e = htsp_next(src, e)) { + pcb_net_t *src_net, *dst_net; + pcb_net_term_t *src_term, *dst_term; + + src_net = e->value; + dst_net = pcb_net_alloc(pcb, dst, src_net->name, PCB_NETA_ALLOC); + dst_net->export_tmp = src_net->export_tmp; + dst_net->inhibit_rats = src_net->inhibit_rats; + pcb_attribute_copy_all(&dst_net->Attributes, &src_net->Attributes); + + for(src_term = pcb_termlist_first(&src_net->conns); src_term != NULL; src_term = pcb_termlist_next(src_term)) { + dst_term = pcb_net_term_alloc(dst_net, src_term->refdes, src_term->term); + pcb_attribute_copy_all(&dst_term->Attributes, &src_term->Attributes); + } + } +} + +/* Return the (most natural) copper group the obj is in */ +static rnd_layergrp_id_t get_side_group(pcb_board_t *pcb, pcb_any_obj_t *obj) +{ + switch(obj->type) { + case PCB_OBJ_ARC: + case PCB_OBJ_LINE: + case PCB_OBJ_POLY: + case PCB_OBJ_TEXT: + case PCB_OBJ_GFX: + return pcb_layer_get_group_(obj->parent.layer); + case PCB_OBJ_PSTK: + if (pcb_pstk_shape((pcb_pstk_t *)obj, PCB_LYT_COPPER | PCB_LYT_TOP, 0) != NULL) + return pcb_layergrp_get_top_copper(); + if (pcb_pstk_shape((pcb_pstk_t *)obj, PCB_LYT_COPPER | PCB_LYT_BOTTOM, 0) != NULL) + return pcb_layergrp_get_bottom_copper(); + default: return -1; + } +} + +static pcb_rat_t *pcb_net_create_by_rat_(pcb_board_t *pcb, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, pcb_any_obj_t *o1, pcb_any_obj_t *o2, rnd_bool interactive) +{ + pcb_subc_t *sc1, *sc2, *sctmp; + pcb_net_t *net1 = NULL, *net2 = NULL, *ntmp, *target_net = NULL; + rnd_layergrp_id_t group1, group2; + pcb_rat_t *res; + static long netname_cnt = 0; + char ratname_[32], *ratname, *id; + long old_len, new_len; + + if ((o1 == o2) || (o1 == NULL) || (o2 == NULL)) { + rnd_message(RND_MSG_ERROR, "Missing start or end terminal\n"); + return NULL; + } + + { /* make sure at least one of the terminals is not on a net */ + pcb_net_term_t *term1, *term2; + + sc1 = pcb_obj_parent_subc(o1); + sc2 = pcb_obj_parent_subc(o2); + if ((sc1 == NULL) || (sc2 == NULL) || (sc1->refdes == NULL) || (sc2->refdes == NULL)) { + rnd_message(RND_MSG_ERROR, "Both start or end terminal must be in a subcircuit with refdes\n"); + return NULL; + } + + term1 = pcb_net_find_by_refdes_term(&pcb->netlist[PCB_NETLIST_EDITED], sc1->refdes, o1->term); + term2 = pcb_net_find_by_refdes_term(&pcb->netlist[PCB_NETLIST_EDITED], sc2->refdes, o2->term); + if (term1 != NULL) net1 = term1->parent.net; + if (term2 != NULL) net1 = term2->parent.net; + + if ((net1 == net2) && (net1 != NULL)) { + rnd_message(RND_MSG_ERROR, "Those terminals are already on the same net (%s)\n", net1->name); + return NULL; + } + if ((net1 != NULL) && (net2 != NULL)) { + rnd_message(RND_MSG_ERROR, "Can not connect two existing nets with a rat (%s and %s)\n", net1->name, net2->name); + return NULL; + } + } + + /* swap vars so it's always o1 is off-net (and o2 may be in a net) */ + if (net1 != NULL) { + pcb_any_obj_t *otmp; + otmp = o1; o1 = o2; o2 = otmp; + sctmp = sc1; sc1 = sc2; sc2 = sctmp; + ntmp = net1; net1 = net2; net2 = ntmp; + } + + group1 = get_side_group(pcb, o1); + group2 = get_side_group(pcb, o2); + if ((group1 == -1) && (group2 == -1)) { + rnd_message(RND_MSG_ERROR, "Can not determine copper layer group of that terminal\n"); + return NULL; + } + + /* passed all sanity checks, o1 is off-net; figure the target_net (create it if needed) */ + if ((net1 == NULL) && (net2 == NULL)) { + do { + sprintf(ratname_, "pcbrnd%ld", ++netname_cnt); + } while(htsp_has(&pcb->netlist[PCB_NETLIST_EDITED], ratname_)); + if (interactive) { + ratname = rnd_hid_prompt_for(&pcb->hidlib, "Name of the new net", ratname_, "rat net name"); + if (ratname == NULL) /* cancel */ + return NULL; + } + else + ratname = ratname_; + target_net = pcb_net_get(pcb, &pcb->netlist[PCB_NETLIST_EDITED], ratname, PCB_NETA_ALLOC_UNDOABLE); + + assert(target_net != NULL); + if (ratname != ratname_) + free(ratname); + } + else + target_net = net2; + + /* create the rat and add terminals in the target_net */ + res = pcb_rat_new(pcb->Data, -1, x1, y1, x2, y2, group1, group2, conf_core.appearance.rat_thickness, pcb_no_flags(), o1, o2); + + old_len = pcb_termlist_length(&target_net->conns); + pcb_net_term_get(target_net, sc1->refdes, o1->term, PCB_NETA_ALLOC_UNDOABLE); + new_len = pcb_termlist_length(&target_net->conns); + if (new_len != old_len) { + id = rnd_concat(sc1->refdes, "-", o1->term, NULL); + pcb_ratspatch_append(pcb, RATP_ADD_CONN, id, target_net->name, NULL, 1); + free(id); + } + + old_len = new_len; + pcb_net_term_get(target_net, sc2->refdes, o2->term, PCB_NETA_ALLOC_UNDOABLE); + new_len = pcb_termlist_length(&target_net->conns); + if (new_len != old_len) { + id = rnd_concat(sc2->refdes, "-", o2->term, NULL); + pcb_ratspatch_append(pcb, RATP_ADD_CONN, id, target_net->name, NULL, 1); + free(id); + } + + pcb_netlist_changed(0); + return res; +} + +static pcb_any_obj_t *find_rat_end(pcb_board_t *pcb, rnd_coord_t x, rnd_coord_t y, const char *loc) +{ + void *ptr1, *ptr2, *ptr3; + pcb_any_obj_t *o; + pcb_objtype_t type = pcb_search_obj_by_location(PCB_OBJ_CLASS_TERM | PCB_OBJ_SUBC_PART, &ptr1, &ptr2, &ptr3, x, y, 5); + pcb_subc_t *sc; + + o = ptr2; + if ((type == PCB_OBJ_VOID) || (o->term == NULL)) { + rnd_message(RND_MSG_ERROR, "Can't find a terminal at %s\n", loc); + return NULL; + } + + sc = pcb_obj_parent_subc(o); + if ((sc == NULL) || (sc->refdes == NULL)) { + rnd_message(RND_MSG_ERROR, "The terminal terminal found at %s is not part of a subc with refdes\n", loc); + return NULL; + } + + return o; +} + +pcb_rat_t *pcb_net_create_by_rat_coords(pcb_board_t *pcb, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_bool interactive) +{ + pcb_any_obj_t *os, *oe; + if ((x1 == x2) && (y1 == y2)) + return NULL; + + os = find_rat_end(pcb, x1, y1, "rat line start"); + oe = find_rat_end(pcb, x2, y2, "rat line end"); + + return pcb_net_create_by_rat_(pcb, x1, y1, x2, y2, os, oe, interactive); +} + + +rnd_cardinal_t pcb_net_ripup(pcb_board_t *pcb, pcb_net_t *net) +{ + pcb_find_t fctx; + pcb_net_term_t *t; + rnd_cardinal_t res, n; + pcb_any_obj_t *o, *lasto; + pcb_data_it_t it; + int first = 0; + + memset(&fctx, 0, sizeof(fctx)); + fctx.only_mark_rats = 1; /* do not trust rats, but do mark them */ + + for(t = pcb_termlist_first(&net->conns), n = 0; t != NULL; t = pcb_termlist_next(t), n++) + pcb_net_term_crawl(pcb, t, &fctx, &first, NULL); + + pcb_undo_save_serial(); + pcb_draw_inhibit_inc(); + + /* always remove the (n-1)th object; removing the current iterator object + confuses the iteration */ + res = 0; + lasto = NULL; + o = pcb_data_first(&it, pcb->Data, PCB_OBJ_CLASS_REAL & (~PCB_OBJ_SUBC)); + for(;;) { + if ((lasto != NULL) && (PCB_FIND_IS_MARKED(&fctx, lasto))) { + pcb_remove_object(lasto->type, lasto->parent.any, lasto, lasto); + res++; + } + lasto = o; + if (lasto == NULL) + break; + o = pcb_data_next(&it); + } + + pcb_undo_restore_serial(); + if (res > 0) + pcb_undo_inc_serial(); + + pcb_draw_inhibit_dec(); + pcb_find_free(&fctx); + return res; +} Index: tags/2.3.0/src/netlist.h =================================================================== --- tags/2.3.0/src/netlist.h (nonexistent) +++ tags/2.3.0/src/netlist.h (revision 33253) @@ -0,0 +1,201 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_NETLIST2_H +#define PCB_NETLIST2_H + +#include +#include +#include +#include "board.h" +#include "obj_common.h" + +/* some calls may create new nets as side effect; they are normally controlled by this enum */ +typedef enum { + PCB_NETA_NOALLOC=0, + PCB_NETA_ALLOC=1, + PCB_NETA_ALLOC_UNDOABLE=2 +} pcb_net_alloc_t; + +struct pcb_net_term_s { + PCB_ANY_OBJ_FIELDS; + char *refdes; + char *term; + gdl_elem_t link; /* a net is mainly an ordered list of terminals */ +}; + +typedef enum { /* bitfield */ + PCB_RATACC_PRECISE = 1, /* find the shortest rats, precisely (expensive); if unset, use a simplified algo e.g. considering only endpoints of lines */ + PCB_RATACC_ONLY_MANHATTAN = 2, /* the old autorouter doesn't like non-manhattan lines and arcs */ + PCB_RATACC_ONLY_SELECTED = 4, + PCB_RATACC_INFO = 8 /* print INFO messages in the log about how many rats are to go */ +} pcb_rat_accuracy_t; + +/* List of refdes-terminals */ +#define TDL(x) pcb_termlist_ ## x +#define TDL_LIST_T pcb_termlist_t +#define TDL_ITEM_T pcb_net_term_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define pcb_termlist_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + + +#include +#include + + +struct pcb_net_s { + PCB_ANY_OBJ_FIELDS; + int parent_nl_idx; /* netlist index within the parent board */ + char *name; + rnd_cardinal_t export_tmp; /* filled in and used by export code; valid only until the end of exporting */ + unsigned inhibit_rats:1; + unsigned auto_len:1; + pcb_termlist_t conns; +}; + + +/* Initialize an empty netlist */ +void pcb_netlist_init(pcb_netlist_t *nl); + +/* Free all memory (including nets and terminals) of a netlist */ +void pcb_netlist_uninit(pcb_netlist_t *nl); + +/* Copy all fields from src to dst, assuming dst is empty */ +void pcb_netlist_copy(pcb_board_t *pcb, pcb_netlist_t *dst, pcb_netlist_t *src); + +/* Look up (or allocate) a net by name within a netlist. Returns NULL on error */ +pcb_net_t *pcb_net_get(pcb_board_t *pcb, pcb_netlist_t *nl, const char *netname, pcb_net_alloc_t alloc); +pcb_net_t *pcb_net_get_icase(pcb_board_t *pcb, pcb_netlist_t *nl, const char *name); /* read-only, case-insnensitive */ +pcb_net_t *pcb_net_get_regex(pcb_board_t *pcb, pcb_netlist_t *nl, const char *regex); +pcb_net_t *pcb_net_get_user(pcb_board_t *pcb, pcb_netlist_t *nl, const char *name_or_rx); /* run all three above in order, until one succeeds */ + + +/* Remove a net from a netlist by namel returns 0 on removal, -1 on error */ +int pcb_net_del(pcb_netlist_t *nl, const char *netname); + +/* Look up (or allocate) a terminal within a net. Pinname is "refdes-termid". + Returns NULL on error */ +pcb_net_term_t *pcb_net_term_get(pcb_net_t *net, const char *refdes, const char *term, pcb_net_alloc_t alloc); +pcb_net_term_t *pcb_net_term_get_by_obj(pcb_net_t *net, const pcb_any_obj_t *obj); +pcb_net_term_t *pcb_net_term_get_by_pinname(pcb_net_t *net, const char *pinname, pcb_net_alloc_t alloc); + +/* Remove term from its net and free all fields and term itself */ +int pcb_net_term_del(pcb_net_t *net, pcb_net_term_t *term); +int pcb_net_term_del_by_name(pcb_net_t *net, const char *refdes, const char *term); + + +/* Crawl a net and clear&set flags on each object belonging to the net + and. Return the number of objects found */ +rnd_cardinal_t pcb_net_crawl_flag(pcb_board_t *pcb, pcb_net_t *net, unsigned long setf, unsigned long clrf); + + +/* Slow, linear search for a terminal, by pinname ("refdes-pinnumber") or + separate refdes and terminal ID. */ +pcb_net_term_t *pcb_net_find_by_pinname(const pcb_netlist_t *nl, const char *pinname); +pcb_net_term_t *pcb_net_find_by_refdes_term(const pcb_netlist_t *nl, const char *refdes, const char *term); +pcb_net_term_t *pcb_net_find_by_obj(const pcb_netlist_t *nl, const pcb_any_obj_t *obj); + +/* Create an alphabetic sorted, NULL terminated array from the nets; + the return value is valid until any change to nl and should be free'd + by the caller. Pointers in the array are the same as in the has table, + should not be free'd. */ +pcb_net_t **pcb_netlist_sort(pcb_netlist_t *nl); + +/* Create missing rat lines */ +rnd_cardinal_t pcb_net_add_rats(const pcb_board_t *pcb, pcb_net_t *net, pcb_rat_accuracy_t acc); +rnd_cardinal_t pcb_net_add_all_rats(const pcb_board_t *pcb, pcb_rat_accuracy_t acc); + +/* Create a new network or a new net connection by drawing a rat line between two terminals */ +pcb_rat_t *pcb_net_create_by_rat_coords(pcb_board_t *pcb, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_bool interactive); + +/* Undoably remove all non-subc-part copper objects that are connected to net. + Return the number of removals. */ +rnd_cardinal_t pcb_net_ripup(pcb_board_t *pcb, pcb_net_t *net); + +void pcb_netlist_changed(int force_unfreeze); + +rnd_bool pcb_net_name_valid(const char *netname); + +/*** subnet mapping ***/ + +typedef struct { + const pcb_board_t *pcb; + pcb_net_t *current_net; + htsp_t found; + rnd_cardinal_t changed, missing, num_shorts; + int cancel_advanced; /* do not do any time consuming advanced operations (such as mincut) in the event handler because the user already clicked cancel */ +} pcb_short_ctx_t; + +void pcb_net_short_ctx_init(pcb_short_ctx_t *sctx, const pcb_board_t *pcb, pcb_net_t *net); +void pcb_net_short_ctx_uninit(pcb_short_ctx_t *sctx); + +/* Search and collect all subnets of a net, adding rat lines in between them. + Caller provided subnets is a vector of vtp0_t items that each contain + (pcb_any_obj_t *) pointers to subnet objects */ +rnd_cardinal_t pcb_net_map_subnets(pcb_short_ctx_t *sctx, pcb_rat_accuracy_t acc, vtp0_t *subnets); + +void pcb_net_reset_subnets(vtp0_t *subnets); /* clear the subnet list to zero items, but don't free the array ("malloc cache") */ +void pcb_net_free_subnets(vtp0_t *subnets); /* same as reset but also free the array */ + + + +/*** looping ***/ + +typedef struct pcb_net_it_s { + pcb_netlist_t *nl; + htsp_entry_t *next; +} pcb_net_it_t; + +RND_INLINE pcb_net_t *pcb_net_next(pcb_net_it_t *it) +{ + pcb_net_t *res; + if (it->next == NULL) + return NULL; + res = it->next->value; + it->next = htsp_next(it->nl, it->next); + return res; +} + +RND_INLINE pcb_net_t *pcb_net_first(pcb_net_it_t *it, pcb_netlist_t *nl) +{ + it->nl = nl; + it->next = htsp_first(nl); + return pcb_net_next(it); +} + +/*** Internal ***/ +void pcb_net_free_fields(pcb_net_t *net); +void pcb_net_free(pcb_net_t *net); +void pcb_net_term_free_fields(pcb_net_term_t *term); +void pcb_net_term_free(pcb_net_term_t *term); + +void pcb_netlist_geo_init(void); + +#endif Index: tags/2.3.0/src/netlist_act.c =================================================================== --- tags/2.3.0/src/netlist_act.c (nonexistent) +++ tags/2.3.0/src/netlist_act.c (revision 33253) @@ -0,0 +1,676 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2005 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* generic netlist operations + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "funchash_core.h" +#include "data.h" +#include "data_it.h" +#include "board.h" +#include +#include "plug_io.h" +#include +#include +#include "netlist.h" +#include "data_it.h" +#include "find.h" +#include "obj_term.h" +#include "search.h" +#include "obj_subc_parent.h" + +static int pcb_netlist_swap() +{ + char *pins[3] = { NULL, NULL, NULL }; + int next = 0, n; + int ret = -1; + pcb_net_term_t *t1, *t2; + pcb_net_t *n1, *n2; + + PCB_SUBC_LOOP(PCB->Data); + { + pcb_any_obj_t *o; + pcb_data_it_t it; + + for(o = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, o) && (o->term != NULL)) { + int le, lp; + + if (next > 2) { + rnd_message(RND_MSG_ERROR, "Exactly two terminals should be selected for swap (more than 2 selected at the moment)\n"); + goto quit; + } + + le = strlen(subc->refdes); + lp = strlen(o->term); + pins[next] = malloc(le + lp + 2); + sprintf(pins[next], "%s-%s", subc->refdes, o->term); + next++; + } + } + } + PCB_END_LOOP; + + if (next < 2) { + rnd_message(RND_MSG_ERROR, "Exactly two terminals should be selected for swap (less than 2 selected at the moment)\n"); + goto quit; + } + + + t1 = pcb_net_find_by_pinname(&PCB->netlist[PCB_NETLIST_EDITED], pins[0]); + t2 = pcb_net_find_by_pinname(&PCB->netlist[PCB_NETLIST_EDITED], pins[1]); + if ((t1 == NULL) || (t2 == NULL)) { + rnd_message(RND_MSG_ERROR, "That terminal is not on a net.\n"); + goto quit; + } + + n1 = t1->parent.net; + n2 = t2->parent.net; + if (n1 == n2) { + rnd_message(RND_MSG_ERROR, "Those two terminals are on the same net, can't swap them.\n"); + goto quit; + } + + + pcb_ratspatch_append_optimize(PCB, RATP_DEL_CONN, pins[0], n1->name, NULL); + pcb_ratspatch_append_optimize(PCB, RATP_DEL_CONN, pins[1], n2->name, NULL); + pcb_ratspatch_append_optimize(PCB, RATP_ADD_CONN, pins[0], n2->name, NULL); + pcb_ratspatch_append_optimize(PCB, RATP_ADD_CONN, pins[1], n1->name, NULL); + + /* TODO: not very efficient to regenerate the whole list... */ + pcb_ratspatch_make_edited(PCB); + ret = 0; + +quit:; + for (n = 0; n < 3; n++) + if (pins[n] != NULL) + free(pins[n]); + return ret; +} + +/* The primary purpose of this action is to rebuild a netlist from a + script, in conjunction with the clear action above. */ +static int pcb_netlist_add(int patch, const char *netname, const char *pinname) +{ + pcb_net_t *n; + pcb_net_term_t *t; + + if ((netname == NULL) || (pinname == NULL)) + return -1; + + if ((*netname == '\0') || (*pinname == '\0')) + return -1; + + n = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_INPUT+(!!patch)], netname, PCB_NETA_ALLOC); + t = pcb_net_term_get_by_pinname(n, pinname, PCB_NETA_NOALLOC); + if (t == NULL) { + if (!patch) { + t = pcb_net_term_get_by_pinname(n, pinname, PCB_NETA_ALLOC); + PCB->netlist_needs_update=1; + } + else { + t = pcb_net_term_get_by_pinname(n, pinname, PCB_NETA_ALLOC); + pcb_ratspatch_append_optimize(PCB, RATP_ADD_CONN, pinname, netname, NULL); + } + } + + pcb_netlist_changed(0); + return 0; +} + +static void pcb_netlist_find(pcb_net_t *new_net, pcb_net_term_t *term) +{ + pcb_net_crawl_flag(PCB, pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], new_net->name, 0), PCB_FLAG_FOUND, 0); +} + +static void pcb_netlist_select(pcb_net_t *new_net, pcb_net_term_t *term) +{ + pcb_net_crawl_flag(PCB, pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], new_net->name, 0), PCB_FLAG_SELECTED, 0); +} + +static void pcb_netlist_unselect(pcb_net_t *new_net, pcb_net_term_t *term) +{ + pcb_net_crawl_flag(PCB, pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], new_net->name, 0), 0, PCB_FLAG_SELECTED); +} + +static void pcb_netlist_autolen(pcb_net_t *new_net, pcb_net_term_t *term) +{ + pcb_net_t *n = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], new_net->name, 0); + if (n != NULL) + n->auto_len = 1; + pcb_netlist_changed(0); +} + +static void pcb_netlist_noautolen(pcb_net_t *new_net, pcb_net_term_t *term) +{ + pcb_net_t *n = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], new_net->name, 0); + if (n != NULL) + n->auto_len = 0; + pcb_netlist_changed(0); +} + +static void pcb_netlist_rats(pcb_net_t *new_net, pcb_net_term_t *term) +{ + pcb_net_t *n = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], new_net->name, 0); + if (n != NULL) + n->inhibit_rats = 0; + pcb_netlist_changed(0); +} + +static void pcb_netlist_norats(pcb_net_t *new_net, pcb_net_term_t *term) +{ + pcb_net_t *n = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], new_net->name, 0); + if (n != NULL) + n->inhibit_rats = 1; + pcb_netlist_changed(0); +} + +static void allrats(int val) +{ + htsp_entry_t *e; + int chg = 0; + for(e = htsp_first(&PCB->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&PCB->netlist[PCB_NETLIST_EDITED], e)) { + pcb_net_t *n = e->value; + if ((n != NULL) && (n->inhibit_rats != val)) { + n->inhibit_rats = val; + chg = 1; + } + } + if (chg) + pcb_netlist_changed(0); +} + +static int pcb_netlist_allrats() +{ + allrats(0); + return 0; +} + +static int pcb_netlist_noallrats() +{ + allrats(1); + return 0; +} + +/* The primary purpose of this action is to remove the netlist + completely so that a new one can be loaded, usually via a gsch2pcb + style script. */ +static void pcb_netlist_clear(pcb_net_t *net, pcb_net_term_t *term) +{ + int ni; + + if (net == 0) { + /* Clear the entire netlist. */ + for (ni = 0; ni < PCB_NUM_NETLISTS; ni++) { + pcb_netlist_uninit(&PCB->netlist[ni]); + pcb_netlist_init(&PCB->netlist[ni]); + } + } + else if (term == NULL) { + /* Remove a net from the netlist. */ + pcb_net_del(&PCB->netlist[PCB_NETLIST_EDITED], net->name); + } + else { + /* Remove a pin from the given net. Note that this may leave an + empty net, which is different than removing the net + (above). */ + pcb_net_term_del(net, term); + } + pcb_netlist_changed(0); +} + +static void pcb_netlist_style(pcb_net_t *new_net, const char *style) +{ + pcb_attribute_put(&new_net->Attributes, "style", style); +} + +static void pcb_netlist_ripup(pcb_net_t *new_net, pcb_net_term_t *term) +{ + pcb_net_ripup(PCB, new_net); +} + +static void pcb_netlist_addrats(pcb_net_t *new_net, pcb_net_term_t *term) +{ + pcb_net_add_rats(PCB, new_net, PCB_RATACC_PRECISE); +} + + +static const char pcb_acts_Netlist[] = + "Net(find|select|rats|norats||ripup|addrats|clear[,net[,pin]])\n" + "Net(freeze|thaw|forcethaw)\n" + "Net(swap)\n" + "Net(add,net,pin)" + "Net([rename|merge],srcnet,dstnet)" + ; +static const char pcb_acth_Netlist[] = "Perform various actions on netlists."; + +/* DOC: netlist.html */ +static fgw_error_t pcb_act_Netlist(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +typedef void (*NFunc)(pcb_net_t *net, pcb_net_term_t *term); + +static unsigned netlist_act_do(pcb_net_t *net, int argc, const char *a1, const char *a2, NFunc func) +{ + pcb_net_term_t *term = NULL; + int pin_found = 0; + + if (func == (NFunc)pcb_netlist_style) { + pcb_netlist_style(net, a2); + return 1; + } + + if (argc > 3) { + { + char *refdes, *termid; + refdes = rnd_strdup(a2); + termid = strchr(refdes, '-'); + if (termid != NULL) { + *termid = '\0'; + termid++; + } + else + termid = ""; + for(term = pcb_termlist_first(&net->conns); term != NULL; term = pcb_termlist_next(term)) { + if ((rnd_strcasecmp(refdes, term->refdes) == 0) && (rnd_strcasecmp(termid, term->term) == 0)) { + pin_found = 1; + func(net, term); + } + } + + free(refdes); + } + if (rnd_gui != NULL) + rnd_gui->invalidate_all(rnd_gui); + } + else if (argc > 2) { + pin_found = 1; + { + for(term = pcb_termlist_first(&net->conns); term != NULL; term = pcb_termlist_next(term)) + func(net, term); + } + if (rnd_gui != NULL) + rnd_gui->invalidate_all(rnd_gui); + } + else { + func(net, NULL); + if (rnd_gui != NULL) + rnd_gui->invalidate_all(rnd_gui); + } + + return pin_found; +} + +static void netlist_freeze(pcb_board_t *pcb) +{ + pcb->netlist_frozen++; +} + +static void netlist_unfreeze(pcb_board_t *pcb) +{ + if (pcb->netlist_frozen > 0) { + pcb->netlist_frozen--; + if (pcb->netlist_needs_update) + pcb_netlist_changed(0); + } +} + +/* Rename or merge networks: move all conns from 'from' to 'to'. If merge, + 'to' shall be an existing network, else it shall be a non-existing network. */ +static int netlist_merge(pcb_board_t *pcb, const char *from, const char *to, int merge) +{ + pcb_net_t *nfrom, *nto; + pcb_net_term_t *t, *tnext; + + nfrom = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], from, 0); + if (nfrom == NULL) { + rnd_message(RND_MSG_ERROR, "No such net: '%s'\n", from); + return 1; + } + + nto = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], to, 0); + if (merge) { + if (nto == NULL) { + rnd_message(RND_MSG_ERROR, "No such net: '%s'\n", to); + return 1; + } + } + else { + if (nto != NULL) { + rnd_message(RND_MSG_ERROR, "Net name '%s' already in use\n", to); + return 1; + } + nto = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], to, PCB_NETA_ALLOC); + } + + /* move over all terminals from nfrom to nto */ + for(t = pcb_termlist_first(&nfrom->conns); t != NULL; t = tnext) { + char *pinname = rnd_strdup_printf("%s-%s", t->refdes, t->term); + + tnext = pcb_termlist_next(t); + pcb_net_term_del(nfrom, t); + pcb_ratspatch_append_optimize(PCB, RATP_DEL_CONN, pinname, nfrom->name, NULL); + + pcb_net_term_get_by_pinname(nto, pinname, PCB_NETA_ALLOC); + pcb_ratspatch_append_optimize(PCB, RATP_ADD_CONN, pinname, nto->name, NULL); + + free(pinname); + } + pcb_net_del(&PCB->netlist[PCB_NETLIST_EDITED], from); + pcb_netlist_changed(0); + return 0; +} + +static fgw_error_t pcb_act_Netlist(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + NFunc func; + const char *a1 = NULL, *a2 = NULL; + char *a2free = NULL; + int op; + pcb_net_t *net = NULL; + unsigned net_found = 0; + unsigned pin_found = 0; + + RND_ACT_CONVARG(1, FGW_KEYWORD, Netlist, op = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, Netlist, a1 = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, Netlist, a2 = argv[3].val.str); + RND_ACT_IRES(0); + + if (!PCB) + return 1; + + switch(op) { + case F_Rename: + if (a1 == NULL) + RND_ACT_FAIL(Netlist); + if (a2 == NULL) { + a2 = a2free = rnd_hid_prompt_for(RND_ACT_HIDLIB, "New name of the network", NULL, "net rename"); + if (a2 == NULL) { + RND_ACT_IRES(1); + return 0; + } + } + RND_ACT_IRES(netlist_merge(PCB, a1, a2, 0)); + free(a2free); + return 0; + case F_Merge: + if (a1 == NULL) + RND_ACT_FAIL(Netlist); + if (a2 == NULL) { + a2 = a2free = rnd_hid_prompt_for(RND_ACT_HIDLIB, "Network name to merge into", NULL, "net merge"); + if (a2 == NULL) { + RND_ACT_IRES(1); + return 0; + } + } + RND_ACT_IRES(netlist_merge(PCB, a1, a2, 1)); + free(a2free); + return 0; + case F_Find: func = pcb_netlist_find; break; + case F_Select: func = pcb_netlist_select; break; + case F_Unselect: func = pcb_netlist_unselect; break; + case F_AutoLen: func = pcb_netlist_autolen; break; + case F_NoAutoLen: func = pcb_netlist_noautolen; break; + case F_Rats: func = pcb_netlist_rats; break; + case F_NoRats: func = pcb_netlist_norats; break; + case F_AllRats: return pcb_netlist_allrats(); + case F_NoAllRats: return pcb_netlist_noallrats(); + case F_AddRats: func = pcb_netlist_addrats; break; + case F_Style: func = (NFunc) pcb_netlist_style; break; + case F_Ripup: func = pcb_netlist_ripup; break; + case F_Swap: return pcb_netlist_swap(); break; + case F_Clear: + func = pcb_netlist_clear; + if (argc == 2) { + pcb_netlist_clear(NULL, NULL); + return 0; + } + break; + case F_Add: + /* Add is different, because the net/pin won't already exist. */ + return pcb_netlist_add(0, a1, a2); + case F_Sort: + pcb_ratspatch_make_edited(PCB); + return 0; + case F_Freeze: + netlist_freeze(PCB); + return 0; + case F_Thaw: + netlist_unfreeze(PCB); + return 0; + case F_ForceThaw: + PCB->netlist_frozen = 0; + if (PCB->netlist_needs_update) + pcb_netlist_changed(0); + return 0; + default: + RND_ACT_FAIL(Netlist); + } + + netlist_freeze(PCB); + { + pcb_netlist_t *nl = &PCB->netlist[PCB_NETLIST_EDITED]; + net = pcb_net_get(PCB, nl, a1, 0); + if (net == NULL) + net = pcb_net_get_icase(PCB, nl, a1); + if (net == NULL) { /* no direct match - have to go for the multi-net regex approach */ + re_sei_t *regex = re_sei_comp(a1); + if (re_sei_errno(regex) == 0) { + htsp_entry_t *e; + for(e = htsp_first(nl); e != NULL; e = htsp_next(nl, e)) { + pcb_net_t *net = e->value; + if (re_sei_exec(regex, net->name)) { + net_found = 1; + pin_found |= netlist_act_do(net, argc, a1, a2, func); + } + } + } + re_sei_free(regex); + } + else { + net_found = 1; + pin_found |= netlist_act_do(net, argc, a1, a2, func); + } + } + netlist_unfreeze(PCB); + + if (argc > 3 && !pin_found) { + rnd_message(RND_MSG_ERROR, "Net %s has no pin %s\n", a1, a2); + return 1; + } + else if (!net_found) { + rnd_message(RND_MSG_ERROR, "No net named %s\n", a1); + } + + + return 0; +} + +static void claim_import_by_flag(pcb_data_t *data, vtp0_t *termlist, unsigned long flg) +{ + pcb_any_obj_t *o; + pcb_data_it_t it; + + for(o = pcb_data_first(&it, data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + pcb_subc_t *subc; + + if (o->type == PCB_OBJ_SUBC) + claim_import_by_flag(((pcb_subc_t *)o)->data, termlist, flg); + + if ((o->term == NULL) || (!PCB_FLAG_TEST(flg, o))) + continue; + + subc = pcb_obj_parent_subc(o); + if ((subc == NULL) || (subc->refdes == NULL)) + continue; + + vtp0_append(termlist, o); + } +} + +static int claim_net_cb(pcb_find_t *ctx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + pcb_subc_t *subc; + vtp0_t *termlist = ctx->user_data; + + if (new_obj->term == NULL) + return 0; + + subc = pcb_obj_parent_subc(new_obj); + if ((subc == NULL) || (subc->refdes == NULL)) + return 0; + + vtp0_append(termlist, new_obj); + return 0; +} + +static void pcb_net_claim_from_list(pcb_board_t *pcb, pcb_net_t *net, vtp0_t *termlist) +{ + size_t n; + + for(n = 0; n < vtp0_len(termlist); n++) { + pcb_any_obj_t *obj = termlist->array[n]; + pcb_subc_t *subc = pcb_obj_parent_subc(obj); + pcb_net_term_t *t = pcb_net_find_by_obj(&pcb->netlist[PCB_NETLIST_EDITED], obj); + char *pinname; + + if (t != NULL) { + /* remove term from its original net */ + pinname = rnd_strdup_printf("%s-%s", t->refdes, t->term); + pcb_ratspatch_append_optimize(PCB, RATP_DEL_CONN, pinname, net->name, NULL); + free(pinname); + } + + t = pcb_net_term_get(net, subc->refdes, obj->term, PCB_NETA_ALLOC); + pinname = rnd_strdup_printf("%s-%s", t->refdes, t->term); + pcb_ratspatch_append_optimize(PCB, RATP_ADD_CONN, pinname, net->name, NULL); + free(pinname); + } +} + +static const char pcb_acts_ClaimNet[] = "ClaimNet(object|selected|found,[netname])\n"; +static const char pcb_acth_ClaimNet[] = "Claim existing connections and create a new net"; +/* DOC: claimnet.html */ +static fgw_error_t pcb_act_ClaimNet(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_find_t fctx; + int op; + vtp0_t termlist; + pcb_net_t *net; + char *netname = NULL, *free_netname = NULL; + + RND_ACT_CONVARG(1, FGW_KEYWORD, Netlist, op = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, Netlist, netname = argv[2].val.str); + RND_ACT_IRES(0); + + vtp0_init(&termlist); + switch(op) { + case F_Object: + { + rnd_coord_t x, y; + void *r1, *r2, *r3; + + rnd_hid_get_coords("Select a an object to claim network from", &x, &y, 0); + if (pcb_search_screen(x, y, PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_PSTK, &r1, &r2, &r3) <= 0) + return 0; + + memset(&fctx, 0, sizeof(fctx)); + fctx.consider_rats = 1; + fctx.found_cb = claim_net_cb; + fctx.user_data = &termlist; + pcb_find_from_obj(&fctx, PCB->Data, (pcb_any_obj_t *)r2); + } + break; + case F_Found: + claim_import_by_flag(PCB->Data, &termlist, PCB_FLAG_FOUND); + break; + case F_Selected: + claim_import_by_flag(PCB->Data, &termlist, PCB_FLAG_SELECTED); + break; + default: + vtp0_uninit(&termlist); + RND_ACT_FAIL(ClaimNet); + } + + if (termlist.used < 1) { + vtp0_uninit(&termlist); + rnd_message(RND_MSG_ERROR, "Can not claim network: no terminal found.\nPlease pick objects that have terminals with refdes-termID.\n"); + RND_ACT_IRES(1); + return 0; + } + + if (netname == NULL) { + free_netname = netname = rnd_hid_prompt_for(RND_ACT_HIDLIB, "Name of the new network", NULL, "net name"); + if (netname == NULL) { + vtp0_uninit(&termlist); + RND_ACT_IRES(1); + return 0; + } + } + + if (pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], netname, 0) != NULL) { + free(free_netname); + vtp0_uninit(&termlist); + rnd_message(RND_MSG_ERROR, "Can not claim network: '%s' is an existing network\n", netname); + RND_ACT_IRES(1); + return 0; + } + + net = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], netname, PCB_NETA_ALLOC); + free(free_netname); + + if (net == NULL) { + vtp0_uninit(&termlist); + rnd_message(RND_MSG_ERROR, "Can not claim network: failed to create net '%s'\n", netname); + RND_ACT_IRES(1); + return 0; + } + + pcb_net_claim_from_list(PCB, net, &termlist); + pcb_netlist_changed(0); + vtp0_uninit(&termlist); + return 0; +} + + +static rnd_action_t netlist_action_list[] = { + {"net", pcb_act_Netlist, pcb_acth_Netlist, pcb_acts_Netlist}, + {"netlist", pcb_act_Netlist, pcb_acth_Netlist, pcb_acts_Netlist}, + {"claimnet", pcb_act_ClaimNet, pcb_acth_ClaimNet, pcb_acts_ClaimNet} +}; + +void pcb_netlist_act_init2(void) +{ + RND_REGISTER_ACTIONS(netlist_action_list, NULL); +} Index: tags/2.3.0/src/netlist_geo.c =================================================================== --- tags/2.3.0/src/netlist_geo.c (nonexistent) +++ tags/2.3.0/src/netlist_geo.c (revision 33253) @@ -0,0 +1,433 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include "obj_pstk_inlines.h" + +typedef struct { + pcb_any_obj_t *o1, *o2; + rnd_coord_t o1x, o1y, o2x, o2y; + rnd_layergrp_id_t o1g, o2g; + double dist2; +} pcb_subnet_dist_t; + +static pcb_subnet_dist_t sdist_invalid = { NULL, NULL, 0, 0, 0, 0, -1, -1, 0 }; + +#define is_line_manhattan(l) (((l)->Point1.X == (l)->Point2.X) || ((l)->Point1.Y == (l)->Point2.Y)) + +#define dist_(o1_, o1x_, o1y_, o2_, o2x_, o2y_) \ +do { \ + double __dx__, __dy__; \ + curr.o1 = (pcb_any_obj_t *)o1_; \ + curr.o1x= o1x_; \ + curr.o1y= o1y_; \ + curr.o2 = (pcb_any_obj_t *)o2_; \ + curr.o2x= o2x_; \ + curr.o2y= o2y_; \ + __dx__ = o1x_ - o2x_; \ + __dy__ = o1y_ - o2y_; \ + curr.dist2 = __dx__ * __dx__ + __dy__ * __dy__; \ +} while(0) + + +#define dist2(o1, o1x, o1y, o2, o2x, o2y) \ +do { \ + dist_(o1, o1x, o1y, o2, o2x, o2y); \ + if (curr.dist2 < best.dist2) \ + best = curr; \ +} while(0) + +#define dist1(o1, o1x, o1y, o2, o2x, o2y) \ +do { \ + dist_(o1, o1x, o1y, o2, o2x, o2y); \ + best = curr; \ +} while(0) + +static pcb_subnet_dist_t pcb_dist_arc_arc(pcb_arc_t *o1, pcb_arc_t *o2, pcb_rat_accuracy_t acc) +{ + pcb_subnet_dist_t best, curr; + rnd_coord_t o1x1, o1y1, o1x2, o1y2, o2x1, o2y1, o2x2, o2y2; + + if (acc & PCB_RATACC_ONLY_MANHATTAN) + return sdist_invalid; + + pcb_arc_get_end(o1, 0, &o1x1, &o1y1); + pcb_arc_get_end(o1, 1, &o1x2, &o1y2); + pcb_arc_get_end(o2, 0, &o2x1, &o2y1); + pcb_arc_get_end(o2, 1, &o2x2, &o2y2); + + dist1(o1, o1x1, o1y1, o2, o2x1, o2y1); + dist2(o1, o1x1, o1y1, o2, o2x2, o2y2); + dist2(o1, o1x2, o1y2, o2, o2x1, o2y1); + dist2(o1, o1x2, o1y2, o2, o2x2, o2y2); + + return best; +} + +static pcb_subnet_dist_t pcb_dist_line_line(pcb_line_t *o1, pcb_line_t *o2, pcb_rat_accuracy_t acc) +{ + pcb_subnet_dist_t best, curr; + + if ((acc & PCB_RATACC_ONLY_MANHATTAN) && ((!is_line_manhattan(o1) || !is_line_manhattan(o2)))) + return sdist_invalid; + + dist1(o1, o1->Point1.X, o1->Point1.Y, o2, o2->Point1.X, o2->Point1.Y); + dist2(o1, o1->Point1.X, o1->Point1.Y, o2, o2->Point2.X, o2->Point2.Y); + dist2(o1, o1->Point2.X, o1->Point2.Y, o2, o2->Point1.X, o2->Point1.Y); + dist2(o1, o1->Point2.X, o1->Point2.Y, o2, o2->Point2.X, o2->Point2.Y); + + return best; +} + +static pcb_subnet_dist_t pcb_dist_line_arc(pcb_line_t *o1, pcb_arc_t *o2, pcb_rat_accuracy_t acc) +{ + pcb_subnet_dist_t best, curr; + rnd_coord_t o2x1, o2y1, o2x2, o2y2; + + if (acc & PCB_RATACC_ONLY_MANHATTAN) + return sdist_invalid; + if ((acc & PCB_RATACC_ONLY_MANHATTAN) && (!is_line_manhattan(o1))) + return sdist_invalid; + + pcb_arc_get_end(o2, 0, &o2x1, &o2y1); + pcb_arc_get_end(o2, 1, &o2x2, &o2y2); + + dist1(o1, o1->Point1.X, o1->Point1.Y, o2, o2x1, o2y1); + dist2(o1, o1->Point1.X, o1->Point1.Y, o2, o2x2, o2y2); + dist2(o1, o1->Point2.X, o1->Point2.Y, o2, o2x1, o2y1); + dist2(o1, o1->Point2.X, o1->Point2.Y, o2, o2x2, o2y2); + + return best; +} + +#define poly_dist_chk(x, y) \ +do { \ + double dx = o2x - x, dy = o2y - y, dist2 = dx*dx + dy*dy; \ + if (dist2 < best.dist2) { \ + best.dist2 = dist2; \ + best.o1x = x; \ + best.o1y = y; \ + } \ +} while(0) + +static pcb_subnet_dist_t dist_poly(pcb_poly_t *o1, pcb_any_obj_t *o2, rnd_coord_t o2x, rnd_coord_t o2y, rnd_coord_t radius) +{ + pcb_subnet_dist_t best; + pcb_poly_it_t it; + rnd_polyarea_t *pa; + + best.dist2 = HUGE_VAL; + best.o1 = (pcb_any_obj_t *)o1; + best.o2 = o2; + best.o2x = o2x; + best.o2y = o2y; + + for(pa = pcb_poly_island_first(o1, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_coord_t x, y; + rnd_pline_t *pl; + int go; + + pl = pcb_poly_contour(&it); + if (pl != NULL) { + /* contour of the island */ + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) + poly_dist_chk(x, y); + + /* iterate over all holes within this island */ + for(pl = pcb_poly_hole_first(&it); pl != NULL; pl = pcb_poly_hole_next(&it)) + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) + poly_dist_chk(x, y); + } + + if (!PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, o1)) + break; /* further islands are removed */ + } + return best; +} + +static pcb_subnet_dist_t pcb_dist_poly_arc(pcb_poly_t *o1, pcb_arc_t *o2, pcb_rat_accuracy_t acc) +{ + pcb_subnet_dist_t best, curr; + rnd_coord_t o2x1, o2y1, o2x2, o2y2, radius; + + if (acc & PCB_RATACC_ONLY_MANHATTAN) + return sdist_invalid; + + pcb_arc_get_end(o2, 0, &o2x1, &o2y1); + pcb_arc_get_end(o2, 1, &o2x2, &o2y2); + + radius = (o2->Thickness + pcb_obj_clearance_p2(o2, o1))/2+4; + best = dist_poly(o1, (pcb_any_obj_t *)o2, o2x1, o2y1, radius); + curr = dist_poly(o1, (pcb_any_obj_t *)o2, o2x2, o2y2, radius); + if (curr.dist2 < best.dist2) + return curr; + + return best; +} + +static pcb_subnet_dist_t pcb_dist_poly_line(pcb_poly_t *o1, pcb_line_t *o2, pcb_rat_accuracy_t acc) +{ + pcb_subnet_dist_t best, curr; + rnd_coord_t radius; + + if (acc & PCB_RATACC_ONLY_MANHATTAN) + return sdist_invalid; + + radius = (o2->Thickness + pcb_obj_clearance_p2(o2, o1))/2+4; + best = dist_poly(o1, (pcb_any_obj_t *)o2, o2->Point1.X, o2->Point1.Y, radius); + curr = dist_poly(o1, (pcb_any_obj_t *)o2, o2->Point2.X, o2->Point2.Y, radius); + if (curr.dist2 < best.dist2) + return curr; + + return best; +} + +#define poly_pt_chk(x, y) \ +do { \ + pcb_subnet_dist_t curr = dist_poly(o1, (pcb_any_obj_t *)o2, x, y, 0); \ + if (curr.dist2 < best.dist2) \ + best = curr; \ +} while(0) + +static pcb_subnet_dist_t pcb_dist_poly_poly(pcb_poly_t *o1, pcb_poly_t *o2, pcb_rat_accuracy_t acc) +{ + pcb_subnet_dist_t best; + pcb_poly_it_t it; + rnd_polyarea_t *pa; + + if (acc & PCB_RATACC_ONLY_MANHATTAN) + return sdist_invalid; + + if (!(acc & PCB_RATACC_PRECISE)) /* this is a slow, O(n^2) algo */ + return sdist_invalid; + + best.dist2 = HUGE_VAL; + + for(pa = pcb_poly_island_first(o2, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_coord_t x, y; + rnd_pline_t *pl; + int go; + + pl = pcb_poly_contour(&it); + if (pl != NULL) { + /* contour of the island */ + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) + poly_pt_chk(x, y); + + /* iterate over all holes within this island */ + for(pl = pcb_poly_hole_first(&it); pl != NULL; pl = pcb_poly_hole_next(&it)) + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) + poly_pt_chk(x, y); + } + } + return best; +} + + +static pcb_subnet_dist_t pcb_dist_pstk_arc(pcb_pstk_t *o1, pcb_arc_t *o2, pcb_rat_accuracy_t acc) +{ + pcb_subnet_dist_t best, curr; + rnd_coord_t o2x1, o2y1, o2x2, o2y2; + + if (acc & PCB_RATACC_ONLY_MANHATTAN) + return sdist_invalid; + + pcb_arc_get_end(o2, 0, &o2x1, &o2y1); + pcb_arc_get_end(o2, 1, &o2x2, &o2y2); + + dist1(o1, o1->x, o1->y, o2, o2x1, o2y1); + dist2(o1, o1->x, o1->y, o2, o2x2, o2y2); + + return best; +} + +static pcb_subnet_dist_t pcb_dist_pstk_line(pcb_pstk_t *o1, pcb_line_t *o2, pcb_rat_accuracy_t acc) +{ + pcb_subnet_dist_t best, curr; + + if ((acc & PCB_RATACC_ONLY_MANHATTAN) &&(!is_line_manhattan(o2))) + return sdist_invalid; + + dist1(o1, o1->x, o1->y, o2, o2->Point1.X, o2->Point1.Y); + dist2(o1, o1->x, o1->y, o2, o2->Point2.X, o2->Point2.Y); + + return best; +} + +static pcb_subnet_dist_t pcb_dist_pstk_poly(pcb_pstk_t *o1, pcb_poly_t *o2, pcb_rat_accuracy_t acc) +{ + if (acc & PCB_RATACC_ONLY_MANHATTAN) + return sdist_invalid; + + return dist_poly(o2, (pcb_any_obj_t *)o1, o1->x, o1->y, 1); +} + +static pcb_subnet_dist_t pcb_dist_pstk_pstk(pcb_pstk_t *o1, pcb_pstk_t *o2, pcb_rat_accuracy_t acc) +{ + pcb_subnet_dist_t curr; + dist_(o1, o1->x, o1->y, o2, o2->x, o2->y); + return curr; +} + + +static pcb_subnet_dist_t pcb_obj_obj_distance(pcb_any_obj_t *o1, pcb_any_obj_t *o2, pcb_rat_accuracy_t acc) +{ + switch(o1->type) { + case PCB_OBJ_ARC: + switch(o2->type) { + case PCB_OBJ_ARC: return pcb_dist_arc_arc((pcb_arc_t *)o2, (pcb_arc_t *)o1, acc); + case PCB_OBJ_LINE: return pcb_dist_line_arc((pcb_line_t *)o2, (pcb_arc_t *)o1, acc); + case PCB_OBJ_POLY: return pcb_dist_poly_arc((pcb_poly_t *)o2, (pcb_arc_t *)o1, acc); + case PCB_OBJ_PSTK: return pcb_dist_pstk_arc((pcb_pstk_t *)o2, (pcb_arc_t *)o1, acc); + + case PCB_OBJ_RAT: case PCB_OBJ_TEXT: case PCB_OBJ_SUBC: case PCB_OBJ_GFX: + case PCB_OBJ_VOID: case PCB_OBJ_NET: case PCB_OBJ_NET_TERM: case PCB_OBJ_LAYER: case PCB_OBJ_LAYERGRP: goto wrongtype; + } + break; + case PCB_OBJ_LINE: + switch(o2->type) { + case PCB_OBJ_ARC: return pcb_dist_line_arc((pcb_line_t *)o1, (pcb_arc_t *)o2, acc); + case PCB_OBJ_LINE: return pcb_dist_line_line((pcb_line_t *)o1, (pcb_line_t *)o2, acc); + case PCB_OBJ_POLY: return pcb_dist_poly_line((pcb_poly_t *)o2, (pcb_line_t *)o1, acc); + case PCB_OBJ_PSTK: return pcb_dist_pstk_line((pcb_pstk_t *)o2, (pcb_line_t *)o1, acc); + + case PCB_OBJ_RAT: case PCB_OBJ_TEXT: case PCB_OBJ_SUBC: case PCB_OBJ_GFX: + case PCB_OBJ_VOID: case PCB_OBJ_NET: case PCB_OBJ_NET_TERM: case PCB_OBJ_LAYER: case PCB_OBJ_LAYERGRP: goto wrongtype; + } + break; + case PCB_OBJ_POLY: + switch(o2->type) { + case PCB_OBJ_ARC: return pcb_dist_poly_arc((pcb_poly_t *)o1, (pcb_arc_t *)o2, acc); + case PCB_OBJ_LINE: return pcb_dist_poly_line((pcb_poly_t *)o1, (pcb_line_t *)o2, acc); + case PCB_OBJ_POLY: return pcb_dist_poly_poly((pcb_poly_t *)o1, (pcb_poly_t *)o2, acc); + case PCB_OBJ_PSTK: return pcb_dist_pstk_poly((pcb_pstk_t *)o2, (pcb_poly_t *)o1, acc); + + case PCB_OBJ_RAT: case PCB_OBJ_TEXT: case PCB_OBJ_SUBC: case PCB_OBJ_GFX: + case PCB_OBJ_VOID: case PCB_OBJ_NET: case PCB_OBJ_NET_TERM: case PCB_OBJ_LAYER: case PCB_OBJ_LAYERGRP: goto wrongtype; + } + break; + + case PCB_OBJ_PSTK: + switch(o2->type) { + case PCB_OBJ_ARC: return pcb_dist_pstk_arc((pcb_pstk_t *)o1, (pcb_arc_t *)o2, acc); + case PCB_OBJ_LINE: return pcb_dist_pstk_line((pcb_pstk_t *)o1, (pcb_line_t *)o2, acc); + case PCB_OBJ_POLY: return pcb_dist_pstk_poly((pcb_pstk_t *)o1, (pcb_poly_t *)o2, acc); + case PCB_OBJ_PSTK: return pcb_dist_pstk_pstk((pcb_pstk_t *)o1, (pcb_pstk_t *)o2, acc); + + case PCB_OBJ_RAT: case PCB_OBJ_TEXT: case PCB_OBJ_SUBC: case PCB_OBJ_GFX: + case PCB_OBJ_VOID: case PCB_OBJ_NET: case PCB_OBJ_NET_TERM: case PCB_OBJ_LAYER: case PCB_OBJ_LAYERGRP: goto wrongtype; + } + break; + + case PCB_OBJ_RAT: case PCB_OBJ_TEXT: case PCB_OBJ_SUBC: case PCB_OBJ_GFX: + case PCB_OBJ_VOID: case PCB_OBJ_NET: case PCB_OBJ_NET_TERM: case PCB_OBJ_LAYER: case PCB_OBJ_LAYERGRP: goto wrongtype; + } + + wrongtype:; + return sdist_invalid; +} + +static rnd_layergrp_id_t get_obj_grp(const pcb_board_t *pcb, pcb_any_obj_t *obj) +{ + switch(obj->type) { + case PCB_OBJ_ARC: + case PCB_OBJ_LINE: + case PCB_OBJ_POLY: + return pcb_layer_get_group_(obj->parent.layer); + + case PCB_OBJ_PSTK: /* return the first copper layer's group */ + { + int n; + rnd_layergrp_id_t res; + pcb_pstk_tshape_t *ts = pcb_pstk_get_tshape((pcb_pstk_t *)obj); + for(n = 0; n < ts->len; n++) + if (ts->shape[n].layer_mask & PCB_LYT_COPPER) + if (pcb_layergrp_list(pcb, ts->shape[n].layer_mask, &res, 1) == 1) + return res; + } + return -1; + + case PCB_OBJ_RAT: case PCB_OBJ_TEXT: case PCB_OBJ_SUBC: case PCB_OBJ_GFX: + case PCB_OBJ_VOID: case PCB_OBJ_NET: case PCB_OBJ_NET_TERM: case PCB_OBJ_LAYER: case PCB_OBJ_LAYERGRP: + break; + } + return -1; +} + +static pcb_subnet_dist_t pcb_subnet_dist(const pcb_board_t *pcb, vtp0_t *objs1, vtp0_t *objs2, pcb_rat_accuracy_t acc) +{ + int i1, i2; + pcb_subnet_dist_t best, curr; + + memset(&best, 0, sizeof(best)); + best.dist2 = HUGE_VAL; + + for(i1 = 0; i1 < vtp0_len(objs1); i1++) { + for(i2 = 0; i2 < vtp0_len(objs2); i2++) { + pcb_any_obj_t *o1 = objs1->array[i1], *o2 = objs2->array[i2]; + + curr = pcb_obj_obj_distance(o1, o2, acc); + +#if 0 +/* remains of the donut rat */ + if (curr.dist2 < HUGE_VAL) { + pcb_any_obj_t *o_in_poly = NULL, *poly; + rnd_coord_t x, y, farx, fary; + + /* if object needs to connect to sorrunding polygon, use a special rat + to indicate "in-place" connection */ + if ((curr.o1->type == PCB_OBJ_POLY) && (curr.o2->type != PCB_OBJ_POLY)) { + o_in_poly = curr.o2; + poly = curr.o1; + x = curr.o2x; + y = curr.o2y; + farx = curr.o1x; + fary = curr.o1y; + } + else if ((curr.o2->type == PCB_OBJ_POLY) && (curr.o1->type != PCB_OBJ_POLY)) { + o_in_poly = curr.o1; + poly = curr.o2; + x = curr.o1x; + y = curr.o1y; + farx = curr.o2x; + fary = curr.o2y; + } + } +#endif + if (curr.dist2 < best.dist2) + best = curr; + } + } + + best.o1g = get_obj_grp(pcb, best.o1); + best.o2g = get_obj_grp(pcb, best.o2); + return best; +} + +void pcb_netlist_geo_init(void) +{ + sdist_invalid.dist2 = HUGE_VAL; /* on some systems this is not constant and can be used as an initializer */ +} Index: tags/2.3.0/src/obj_arc.c =================================================================== --- tags/2.3.0/src/obj_arc.c (nonexistent) +++ tags/2.3.0/src/obj_arc.c (revision 33253) @@ -0,0 +1,1217 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Drawing primitive: (elliptical) arc */ + + +#include "config.h" +#include "board.h" +#include "data.h" +#include "polygon.h" +#include "undo.h" +#include "rotate.h" +#include "move.h" +#include "conf_core.h" +#include "thermal.h" +#include +#include "draw_wireframe.h" +#include + +#include "obj_arc.h" +#include "obj_arc_op.h" + +#include "obj_subc_parent.h" +#include "obj_hash.h" + +#include "obj_arc_draw.h" + + +static int pcb_arc_end_addr = 1; +int *pcb_arc_start_ptr = NULL, *pcb_arc_end_ptr = &pcb_arc_end_addr; + +void pcb_arc_reg(pcb_layer_t *layer, pcb_arc_t *arc) +{ + arclist_append(&layer->Arc, arc); + PCB_SET_PARENT(arc, layer, layer); + + if (layer->parent_type == PCB_PARENT_UI) + return; + + if (layer->parent_type == PCB_PARENT_DATA) + pcb_obj_id_reg(layer->parent.data, arc); +} + +void pcb_arc_unreg(pcb_arc_t *arc) +{ + pcb_layer_t *layer = arc->parent.layer; + assert(arc->parent_type == PCB_PARENT_LAYER); + arclist_remove(arc); + if (layer->parent_type != PCB_PARENT_UI) { + assert(layer->parent_type == PCB_PARENT_DATA); + pcb_obj_id_del(layer->parent.data, arc); + } + PCB_CLEAR_PARENT(arc); +} + +pcb_arc_t *pcb_arc_alloc_id(pcb_layer_t *layer, long int id) +{ + pcb_arc_t *new_obj; + + new_obj = calloc(sizeof(pcb_arc_t), 1); + new_obj->ID = id; + new_obj->type = PCB_OBJ_ARC; + new_obj->Attributes.post_change = pcb_obj_attrib_post_change; + + pcb_arc_reg(layer, new_obj); + + return new_obj; +} + +pcb_arc_t *pcb_arc_alloc(pcb_layer_t *layer) +{ + return pcb_arc_alloc_id(layer, pcb_create_ID_get()); +} + +/* computes the bounding box of an arc */ +static rnd_box_t pcb_arc_bbox_(const pcb_arc_t *Arc, int mini) +{ + double ca1, ca2, sa1, sa2; + double minx, maxx, miny, maxy, delta; + rnd_angle_t ang1, ang2; + rnd_coord_t width; + rnd_box_t res; + + /* first put angles into standard form: + * ang1 < ang2, both angles between 0 and 720 */ + delta = RND_CLAMP(Arc->Delta, -360, 360); + + if (delta > 0) { + ang1 = rnd_normalize_angle(Arc->StartAngle); + ang2 = rnd_normalize_angle(Arc->StartAngle + delta); + } + else { + ang1 = rnd_normalize_angle(Arc->StartAngle + delta); + ang2 = rnd_normalize_angle(Arc->StartAngle); + } + if (ang1 > ang2) + ang2 += 360; + /* Make sure full circles aren't treated as zero-length arcs */ + if (delta == 360 || delta == -360) + ang2 = ang1 + 360; + + /* calculate sines, cosines */ + sa1 = sin(RND_M180 * ang1); + ca1 = cos(RND_M180 * ang1); + sa2 = sin(RND_M180 * ang2); + ca2 = cos(RND_M180 * ang2); + + minx = MIN(ca1, ca2); + maxx = MAX(ca1, ca2); + miny = MIN(sa1, sa2); + maxy = MAX(sa1, sa2); + + /* Check for extreme angles */ + if ((ang1 <= 0 && ang2 >= 0) || (ang1 <= 360 && ang2 >= 360)) + maxx = 1; + if ((ang1 <= 90 && ang2 >= 90) || (ang1 <= 450 && ang2 >= 450)) + maxy = 1; + if ((ang1 <= 180 && ang2 >= 180) || (ang1 <= 540 && ang2 >= 540)) + minx = -1; + if ((ang1 <= 270 && ang2 >= 270) || (ang1 <= 630 && ang2 >= 630)) + miny = -1; + + /* Finally, calculate bounds, converting sane geometry into pcb geometry */ + res.X1 = Arc->X - Arc->Width * maxx; + res.X2 = Arc->X - Arc->Width * minx; + res.Y1 = Arc->Y + Arc->Height * miny; + res.Y2 = Arc->Y + Arc->Height * maxy; + + if (!mini) { + width = (Arc->Thickness + Arc->Clearance) / 2; + /* Adjust for our discrete polygon approximation */ + width = (double) width *MAX(RND_POLY_CIRC_RADIUS_ADJ, (1.0 + RND_POLY_ARC_MAX_DEVIATION)) + 0.5; + } + else + width = Arc->Thickness / 2; + + res.X1 -= width; + res.X2 += width; + res.Y1 -= width; + res.Y2 += width; + rnd_close_box(&res); + return res; +} + + +void pcb_arc_bbox(pcb_arc_t *Arc) +{ + Arc->BoundingBox = pcb_arc_bbox_(Arc, 0); + Arc->bbox_naked = pcb_arc_bbox_(Arc, 1); +} + +void pcb_arc_get_end(pcb_arc_t *arc, int which, rnd_coord_t *x, rnd_coord_t *y) +{ + rnd_arc_get_endpt(arc->X, arc->Y, arc->Width, arc->Height, arc->StartAngle, arc->Delta, which, x, y); +} + + +void pcb_arc_set_angles(pcb_layer_t *Layer, pcb_arc_t *a, rnd_angle_t new_sa, rnd_angle_t new_da) +{ + if (new_da >= 360) { + new_da = 360; + new_sa = 0; + } + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, a); + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) a); + pcb_undo_add_obj_to_change_angles(PCB_OBJ_ARC, a, a, a); + a->StartAngle = new_sa; + a->Delta = new_da; + pcb_arc_bbox(a); + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) a); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, Layer, a); +} + + +void pcb_arc_set_radii(pcb_layer_t *Layer, pcb_arc_t *a, rnd_coord_t new_width, rnd_coord_t new_height) +{ + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, a); + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) a); + pcb_undo_add_obj_to_change_radii(PCB_OBJ_ARC, a, a, a); + a->Width = new_width; + a->Height = new_height; + pcb_arc_bbox(a); + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) a); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, Layer, a); +} + + +/* creates a new arc on a layer */ +pcb_arc_t *pcb_arc_new(pcb_layer_t *Layer, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t width, rnd_coord_t height, rnd_angle_t sa, rnd_angle_t dir, rnd_coord_t Thickness, rnd_coord_t Clearance, pcb_flag_t Flags, rnd_bool prevent_dups) +{ + pcb_arc_t *Arc; + + if ((prevent_dups) && (Layer->arc_tree != NULL)) { + rnd_rtree_it_t it; + pcb_any_obj_t *o; + rnd_box_t b; + + b.X1 = X1 - width; + b.Y1 = Y1 - height; + b.X2 = X1 + width; + b.Y2 = Y1 + height; + + for(o = rnd_rtree_first(&it, Layer->arc_tree, (rnd_rtree_box_t *)&b); o != NULL; o = rnd_rtree_next(&it)) { + pcb_arc_t *arc = (pcb_arc_t *)o; + if ((arc->X == X1) && (arc->Y == Y1) && (arc->Width == width)) { + double s1, s2, d1 = arc->Delta, d2 = dir; + + /* there are two ways normalized arcs can be the same: with + and with - delta */ + if (d1 < 0) { + s1 = rnd_normalize_angle(arc->StartAngle + d1); + d1 = -d1; + } + else + s1 = rnd_normalize_angle(arc->StartAngle); + + if (d2 < 0) { + s2 = rnd_normalize_angle(sa + d2); + d2 = -d2; + } + else + s2 = rnd_normalize_angle(sa); + + if ((s1 == s2) && (d1 == d2)) + return NULL; /* prevent stacked arcs */ + } + } + } + + Arc = pcb_arc_alloc(Layer); + if (!Arc) + return Arc; + + Arc->Flags = Flags; + Arc->Thickness = Thickness; + Arc->Clearance = Clearance; + Arc->X = X1; + Arc->Y = Y1; + Arc->Width = width; + Arc->Height = height; + Arc->StartAngle = sa; + Arc->Delta = dir; + pcb_add_arc_on_layer(Layer, Arc); + return Arc; +} + +static pcb_arc_t *pcb_arc_copy_meta(pcb_arc_t *dst, pcb_arc_t *src) +{ + if (dst == NULL) + return NULL; + pcb_attribute_copy_all(&dst->Attributes, &src->Attributes); + return dst; +} + + +pcb_arc_t *pcb_arc_dup(pcb_layer_t *dst, pcb_arc_t *src) +{ + pcb_arc_t *a = pcb_arc_new(dst, src->X, src->Y, src->Width, src->Height, src->StartAngle, src->Delta, src->Thickness, src->Clearance, src->Flags, rnd_false); + pcb_arc_copy_meta(a, src); + return a; +} + +pcb_arc_t *pcb_arc_dup_at(pcb_layer_t *dst, pcb_arc_t *src, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_arc_t *a = pcb_arc_new(dst, src->X+dx, src->Y+dy, src->Width, src->Height, src->StartAngle, src->Delta, src->Thickness, src->Clearance, src->Flags, rnd_false); + pcb_arc_copy_meta(a, src); + return a; +} + + +void pcb_add_arc_on_layer(pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + pcb_arc_bbox(Arc); + if (!Layer->arc_tree) + Layer->arc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) Arc); + Arc->type = PCB_OBJ_ARC; + PCB_SET_PARENT(Arc, layer, Layer); +} + + + +void pcb_arc_free(pcb_arc_t *arc) +{ + if ((arc->parent.layer != NULL) && (arc->parent.layer->arc_tree != NULL)) + rnd_r_delete_entry(arc->parent.layer->arc_tree, (rnd_box_t *)arc); + pcb_attribute_free(&arc->Attributes); + pcb_arc_unreg(arc); + pcb_obj_common_free((pcb_any_obj_t *)arc); + free(arc); +} + + +int pcb_arc_eq(const pcb_host_trans_t *tr1, const pcb_arc_t *a1, const pcb_host_trans_t *tr2, const pcb_arc_t *a2) +{ + double sgn1 = tr1->on_bottom ? -1 : +1; + double sgn2 = tr2->on_bottom ? -1 : +1; + + if (pcb_field_neq(a1, a2, Thickness) || pcb_field_neq(a1, a2, Clearance)) return 0; + if (pcb_field_neq(a1, a2, Width) || pcb_field_neq(a1, a2, Height)) return 0; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, a1) && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, a2)) { + if (pcb_neq_tr_coords(tr1, a1->X, a1->Y, tr2, a2->X, a2->Y)) return 0; + if (rnd_normalize_angle(rnd_round(a1->StartAngle * sgn1 + tr1->rot * sgn1)) != rnd_normalize_angle(rnd_round(a2->StartAngle * sgn2 + tr2->rot * sgn2))) return 0; + if (rnd_round(a1->Delta * sgn1) != rnd_round(a2->Delta * sgn2)) return 0; + } + + return 1; +} + +unsigned int pcb_arc_hash(const pcb_host_trans_t *tr, const pcb_arc_t *a) +{ + unsigned int crd = 0; + double sgn = tr->on_bottom ? -1 : +1; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, a)) { + rnd_coord_t x, y; + pcb_hash_tr_coords(tr, &x, &y, a->X, a->Y); + crd = pcb_hash_coord(x) ^ pcb_hash_coord(y) ^ + pcb_hash_coord(rnd_normalize_angle(rnd_round(a->StartAngle*sgn + tr->rot*sgn))) ^ pcb_hash_coord(rnd_round(a->Delta * sgn)); + } + + return + pcb_hash_coord(a->Thickness) ^ pcb_hash_coord(a->Clearance) ^ + pcb_hash_coord(a->Width) ^ pcb_hash_coord(a->Height) ^ crd; +} + +rnd_coord_t pcb_arc_length(const pcb_arc_t *arc) +{ + double da = arc->Delta; + double r = ((double)arc->Width + (double)arc->Height) / 2.0; /* TODO: lame approximation */ + if (da < 0) + da = -da; + while(da > 360.0) + da = 360.0; + return rnd_round(2.0*r*M_PI*da/360.0); +} + +double pcb_arc_area(const pcb_arc_t *arc) +{ + return + (pcb_arc_length(arc) * (double)arc->Thickness /* body */ + + (double)arc->Thickness * (double)arc->Thickness * (double)M_PI); /* cap circles */ +} + +rnd_box_t pcb_arc_mini_bbox(const pcb_arc_t *arc) +{ + return pcb_arc_bbox_(arc, 1); +} + +void pcb_arc_pre(pcb_arc_t *arc) +{ + pcb_layer_t *ly = pcb_layer_get_real(arc->parent.layer); + if (ly == NULL) + return; + if (ly->arc_tree != NULL) + rnd_r_delete_entry(ly->arc_tree, (rnd_box_t *)arc); + pcb_poly_restore_to_poly(ly->parent.data, PCB_OBJ_ARC, ly, arc); +} + +void pcb_arc_post(pcb_arc_t *arc) +{ + pcb_layer_t *ly = pcb_layer_get_real(arc->parent.layer); + if (ly == NULL) + return; + if (ly->arc_tree != NULL) + rnd_r_insert_entry(ly->arc_tree, (rnd_box_t *)arc); + pcb_poly_clear_from_poly(ly->parent.data, PCB_OBJ_ARC, ly, arc); +} + + +/***** operations *****/ + +static const char core_arc_cookie[] = "core-arc"; + +typedef struct { + pcb_arc_t *arc; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + rnd_coord_t Thickness, Clearance; + rnd_coord_t Width, Height; + rnd_coord_t X, Y; + rnd_angle_t StartAngle, Delta; + +} undo_arc_geo_t; + +static int undo_arc_geo_swap(void *udata) +{ + undo_arc_geo_t *g = udata; + pcb_layer_t *layer = g->arc->parent.layer; + + if (layer->arc_tree != NULL) + rnd_r_delete_entry(layer->arc_tree, (rnd_box_t *)g->arc); + pcb_poly_restore_to_poly(layer->parent.data, PCB_OBJ_ARC, layer, g->arc); + + rnd_swap(rnd_coord_t, g->Thickness, g->arc->Thickness); + rnd_swap(rnd_coord_t, g->Clearance, g->arc->Clearance); + rnd_swap(rnd_coord_t, g->Width, g->arc->Width); + rnd_swap(rnd_coord_t, g->Height, g->arc->Height); + rnd_swap(rnd_coord_t, g->X, g->arc->X); + rnd_swap(rnd_coord_t, g->Y, g->arc->Y); + rnd_swap(rnd_angle_t, g->StartAngle, g->arc->StartAngle); + rnd_swap(rnd_angle_t, g->Delta, g->arc->Delta); + + pcb_arc_bbox(g->arc); + if (layer->arc_tree != NULL) + rnd_r_insert_entry(layer->arc_tree, (rnd_box_t *)g->arc); + pcb_poly_clear_from_poly(layer->parent.data, PCB_OBJ_ARC, layer, g->arc); + + return 0; +} + +static void undo_arc_geo_print(void *udata, char *dst, size_t dst_len) +{ + rnd_snprintf(dst, dst_len, "arc geo"); +} + +static const uundo_oper_t undo_arc_geo = { + core_arc_cookie, + NULL, + undo_arc_geo_swap, + undo_arc_geo_swap, + undo_arc_geo_print +}; + +/* copies an arc to buffer */ +void *pcb_arcop_add_to_buffer(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + pcb_arc_t *a; + rnd_layer_id_t lid = pcb_layer_id(ctx->buffer.src, Layer); + pcb_layer_t *layer; + + /* the buffer may not have the specified layer, e.g. on loose subc subc-aux layer */ + if (lid == -1) + return NULL; + + layer = &ctx->buffer.dst->Layer[lid]; + a = pcb_arc_new(layer, Arc->X, Arc->Y, + Arc->Width, Arc->Height, Arc->StartAngle, Arc->Delta, + Arc->Thickness, Arc->Clearance, pcb_flag_mask(Arc->Flags, PCB_FLAG_FOUND | ctx->buffer.extraflg), rnd_false); + + pcb_arc_copy_meta(a, Arc); + if (ctx->buffer.keep_id) pcb_obj_change_id((pcb_any_obj_t *)a, Arc->ID); + return a; +} + +/* moves an arc between board and buffer */ +void *pcb_arcop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t *dstly, pcb_arc_t *arc) +{ + pcb_layer_t *srcly = arc->parent.layer; + + assert(arc->parent_type == PCB_PARENT_LAYER); + if ((dstly == NULL) || (dstly == srcly)) { /* auto layer in dst */ + rnd_layer_id_t lid = pcb_layer_id(ctx->buffer.src, srcly); + if (lid < 0) { + rnd_message(RND_MSG_ERROR, "Internal error: can't resolve source layer ID in pcb_arcop_move_buffer\n"); + return NULL; + } + dstly = &ctx->buffer.dst->Layer[lid]; + } + + pcb_poly_restore_to_poly(ctx->buffer.src, PCB_OBJ_ARC, srcly, arc); + rnd_r_delete_entry(srcly->arc_tree, (rnd_box_t *) arc); + + pcb_arc_unreg(arc); + pcb_arc_reg(dstly, arc); + + PCB_FLAG_CLEAR(PCB_FLAG_FOUND, arc); + + if (!dstly->arc_tree) + dstly->arc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(dstly->arc_tree, (rnd_box_t *) arc); + pcb_poly_clear_from_poly(ctx->buffer.dst, PCB_OBJ_ARC, dstly, arc); + + return arc; +} + +void *pcb_arcop_change_thermal(pcb_opctx_t *ctx, pcb_layer_t *ly, pcb_arc_t *arc) +{ + return pcb_anyop_change_thermal(ctx, (pcb_any_obj_t *)arc); +} + +/* changes the size of an arc */ +void *pcb_arcop_change_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + rnd_coord_t value = (ctx->chgsize.is_absolute) ? ctx->chgsize.value : Arc->Thickness + ctx->chgsize.value; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Arc)) + return NULL; + if (value <= PCB_MAX_THICKNESS && value >= PCB_MIN_THICKNESS && value != Arc->Thickness) { + pcb_undo_add_obj_to_size(PCB_OBJ_ARC, Layer, Arc, Arc); + pcb_arc_invalidate_erase(Arc); + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + Arc->Thickness = value; + pcb_arc_bbox(Arc); + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + pcb_arc_invalidate_draw(Layer, Arc); + return Arc; + } + return NULL; +} + +/* changes the clearance size of an arc */ +void *pcb_arcop_change_clear_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + rnd_coord_t value = (ctx->chgsize.is_absolute) ? ctx->chgsize.value : Arc->Clearance + ctx->chgsize.value; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Arc) || !PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Arc)) + return NULL; + if (value < 0) + value = 0; + value = MIN(PCB_MAX_THICKNESS, value); + if (!ctx->chgsize.is_absolute && ctx->chgsize.value < 0) + value = 0; + if (value != Arc->Clearance) { + pcb_undo_add_obj_to_clear_size(PCB_OBJ_ARC, Layer, Arc, Arc); + pcb_arc_invalidate_erase(Arc); + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + Arc->Clearance = value; + pcb_arc_bbox(Arc); + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + pcb_arc_invalidate_draw(Layer, Arc); + return Arc; + } + return NULL; +} + +/* changes the radius of an arc (is_primary 0=width or 1=height or 2=both) */ +void *pcb_arcop_change_radius(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + rnd_coord_t value, *dst; + void *a0, *a1; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Arc)) + return NULL; + + switch(ctx->chgsize.is_primary) { + case 0: dst = &Arc->Width; break; + case 1: dst = &Arc->Height; break; + case 2: + ctx->chgsize.is_primary = 0; a0 = pcb_arcop_change_radius(ctx, Layer, Arc); + ctx->chgsize.is_primary = 1; a1 = pcb_arcop_change_radius(ctx, Layer, Arc); + if ((a0 != NULL) || (a1 != NULL)) + return Arc; + return NULL; + } + + value = (ctx->chgsize.is_absolute) ? ctx->chgsize.value : (*dst) + ctx->chgsize.value; + value = MIN(PCB_MAX_ARCRADIUS, MAX(value, PCB_MIN_ARCRADIUS)); + if (value != *dst) { + pcb_undo_add_obj_to_change_radii(PCB_OBJ_ARC, Layer, Arc, Arc); + pcb_arc_invalidate_erase(Arc); + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + *dst = value; + pcb_arc_bbox(Arc); + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + pcb_arc_invalidate_draw(Layer, Arc); + return Arc; + } + return NULL; +} + +/* changes the angle of an arc (is_primary 0=start or 1=end) */ +void *pcb_arcop_change_angle(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + rnd_angle_t value, *dst; + void *a0, *a1; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Arc)) + return NULL; + + switch(ctx->chgangle.is_primary) { + case 0: dst = &Arc->StartAngle; break; + case 1: dst = &Arc->Delta; break; + case 2: + ctx->chgangle.is_primary = 0; a0 = pcb_arcop_change_angle(ctx, Layer, Arc); + ctx->chgangle.is_primary = 1; a1 = pcb_arcop_change_angle(ctx, Layer, Arc); + if ((a0 != NULL) || (a1 != NULL)) + return Arc; + return NULL; + } + + value = (ctx->chgangle.is_absolute) ? ctx->chgangle.value : (*dst) + ctx->chgangle.value; + if ((value > 360.0) || (value < -360.0)) + value = fmod(value, 360.0); + + if (value != *dst) { + pcb_undo_add_obj_to_change_angles(PCB_OBJ_ARC, Layer, Arc, Arc); + pcb_arc_invalidate_erase(Arc); + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + *dst = value; + pcb_arc_bbox(Arc); + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + pcb_arc_invalidate_draw(Layer, Arc); + return Arc; + } + return NULL; +} + +/* changes the clearance flag of an arc */ +void *pcb_arcop_change_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Arc)) + return NULL; + pcb_arc_invalidate_erase(Arc); + if (PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Arc)) { + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + pcb_undo_add_obj_to_clear_poly(PCB_OBJ_ARC, Layer, Arc, Arc, rnd_false); + } + pcb_undo_add_obj_to_flag(Arc); + PCB_FLAG_TOGGLE(PCB_FLAG_CLEARLINE, Arc); + if (PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Arc)) { + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + pcb_undo_add_obj_to_clear_poly(PCB_OBJ_ARC, Layer, Arc, Arc, rnd_true); + } + pcb_arc_invalidate_draw(Layer, Arc); + return Arc; +} + +/* sets the clearance flag of an arc */ +void *pcb_arcop_set_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Arc) || PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Arc)) + return NULL; + return pcb_arcop_change_join(ctx, Layer, Arc); +} + +/* clears the clearance flag of an arc */ +void *pcb_arcop_clear_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Arc) || !PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Arc)) + return NULL; + return pcb_arcop_change_join(ctx, Layer, Arc); +} + +/* copies an arc */ +void *pcb_arcop_copy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + pcb_arc_t *arc; + + arc = pcb_arc_new(Layer, Arc->X + ctx->copy.DeltaX, Arc->Y + ctx->copy.DeltaY, + Arc->Width, Arc->Height, Arc->StartAngle, Arc->Delta, + Arc->Thickness, Arc->Clearance, + pcb_flag_mask(Arc->Flags, PCB_FLAG_FOUND), rnd_true); + if (!arc) + return arc; + if (ctx->copy.keep_id) + arc->ID = Arc->ID; + pcb_arc_copy_meta(arc, Arc); + pcb_arc_invalidate_draw(Layer, arc); + pcb_undo_add_obj_to_create(PCB_OBJ_ARC, Layer, arc, arc); + return arc; +} + +/* moves an arc */ +void *pcb_arcop_move_noclip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + if (Layer->meta.real.vis) { + pcb_arc_invalidate_erase(Arc); + pcb_arc_move(Arc, ctx->move.dx, ctx->move.dy); + pcb_arc_invalidate_draw(Layer, Arc); + } + else { + pcb_arc_move(Arc, ctx->move.dx, ctx->move.dy); + } + return Arc; +} + +void *pcb_arcop_move(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + pcb_arcop_move_noclip(ctx, Layer, Arc); + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + return Arc; +} + +void *pcb_arcop_clip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + if (ctx->clip.restore) { + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + } + if (ctx->clip.clear) { + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + } + return Arc; +} + +/* moves an arc between layers; lowlevel routines */ +void *pcb_arcop_move_to_layer_low(pcb_opctx_t *ctx, pcb_layer_t * Source, pcb_arc_t * arc, pcb_layer_t * Destination) +{ + rnd_r_delete_entry(Source->arc_tree, (rnd_box_t *) arc); + + pcb_arc_unreg(arc); + pcb_arc_reg(Destination, arc); + + if (!Destination->arc_tree) + Destination->arc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Destination->arc_tree, (rnd_box_t *) arc); + + return arc; +} + + +/* moves an arc between layers */ +void *pcb_arcop_move_to_layer(pcb_opctx_t *ctx, pcb_layer_t * Layer, pcb_arc_t * Arc) +{ + pcb_arc_t *newone; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Arc)) { + rnd_message(RND_MSG_WARNING, "Sorry, arc object is locked\n"); + return NULL; + } + if (ctx->move.dst_layer == Layer && Layer->meta.real.vis) + pcb_arc_invalidate_draw(Layer, Arc); + if (ctx->move.dst_layer == Layer) + return Arc; + pcb_undo_add_obj_to_move_to_layer(PCB_OBJ_ARC, Layer, Arc, Arc); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + if (Layer->meta.real.vis) + pcb_arc_invalidate_erase(Arc); + newone = (pcb_arc_t *) pcb_arcop_move_to_layer_low(ctx, Layer, Arc, ctx->move.dst_layer); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, ctx->move.dst_layer, Arc); + if (ctx->move.dst_layer->meta.real.vis) + pcb_arc_invalidate_draw(ctx->move.dst_layer, newone); + return newone; +} + +/* destroys an arc from a layer */ +void *pcb_arcop_destroy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) Arc); + + pcb_arc_free(Arc); + return NULL; +} + +/* removes an arc from a layer */ +void *pcb_arcop_remove(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + /* erase from screen */ + if (Layer->meta.real.vis) + pcb_arc_invalidate_erase(Arc); + pcb_undo_move_obj_to_remove(PCB_OBJ_ARC, Layer, Arc, Arc); + return NULL; +} + +void *pcb_arcop_remove_point(pcb_opctx_t *ctx, pcb_layer_t *l, pcb_arc_t *a, int *end_id) +{ + return pcb_arcop_remove(ctx, l, a); +} + +void *pcb_arc_destroy(pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + void *res; + pcb_opctx_t ctx; + + ctx.remove.pcb = PCB; + ctx.remove.destroy_target = NULL; + + res = pcb_arcop_remove(&ctx, Layer, Arc); + pcb_draw(); + return res; +} + +/* rotates an arc */ +void pcb_arc_rotate90(pcb_arc_t *Arc, rnd_coord_t X, rnd_coord_t Y, unsigned Number) +{ + rnd_coord_t save; + + /* add Number*90 degrees (i.e., Number quarter-turns) */ + Arc->StartAngle = rnd_normalize_angle(Arc->StartAngle + Number * 90); + RND_COORD_ROTATE90(Arc->X, Arc->Y, X, Y, Number); + + /* now change width and height */ + if (Number == 1 || Number == 3) { + save = Arc->Width; + Arc->Width = Arc->Height; + Arc->Height = save; + } + + /* can't optimize with box rotation due to closed boxes */ + pcb_arc_bbox(Arc); +} + +void pcb_arc_rotate(pcb_layer_t *layer, pcb_arc_t *arc, rnd_coord_t X, rnd_coord_t Y, double cosa, double sina, rnd_angle_t angle) +{ + if (layer->arc_tree != NULL) + rnd_r_delete_entry(layer->arc_tree, (rnd_box_t *) arc); + rnd_rotate(&arc->X, &arc->Y, X, Y, cosa, sina); + arc->StartAngle = rnd_normalize_angle(arc->StartAngle + angle); + if (layer->arc_tree != NULL) + rnd_r_insert_entry(layer->arc_tree, (rnd_box_t *) arc); +} + +void pcb_arc_mirror(pcb_arc_t *arc, rnd_coord_t y_offs, rnd_bool undoable) +{ + undo_arc_geo_t gtmp, *g = >mp; + + if (undoable) g = pcb_undo_alloc(pcb_data_get_top(arc->parent.layer->parent.data), &undo_arc_geo, sizeof(undo_arc_geo_t)); + + g->arc = arc; + g->Thickness = arc->Thickness; + g->Clearance = arc->Clearance; + g->Width = arc->Width; + g->Height = arc->Height; + g->X = PCB_SWAP_X(arc->X); + g->Y = PCB_SWAP_Y(arc->Y) + y_offs; + g->StartAngle = RND_SWAP_ANGLE(arc->StartAngle); + g->Delta = RND_SWAP_DELTA(arc->Delta); + + undo_arc_geo_swap(g); + if (undoable) pcb_undo_inc_serial(); +} + +void pcb_arc_flip_side(pcb_layer_t *layer, pcb_arc_t *arc) +{ + rnd_r_delete_entry(layer->arc_tree, (rnd_box_t *) arc); + arc->X = PCB_SWAP_X(arc->X); + arc->Y = PCB_SWAP_Y(arc->Y); + arc->StartAngle = RND_SWAP_ANGLE(arc->StartAngle); + arc->Delta = RND_SWAP_DELTA(arc->Delta); + pcb_arc_bbox(arc); + rnd_r_insert_entry(layer->arc_tree, (rnd_box_t *) arc); +} + +void pcb_arc_scale(pcb_arc_t *arc, double sx, double sy, double sth) +{ + int onbrd = (arc->parent.layer != NULL) && (!arc->parent.layer->is_bound); + + if (onbrd) + pcb_arc_pre(arc); + + if (sx != 1.0) { + arc->X = rnd_round((double)arc->X * sx); + arc->Width = rnd_round((double)arc->Width * sx); + } + + if (sy != 1.0) { + arc->Y = rnd_round((double)arc->Y * sy); + arc->Height = rnd_round((double)arc->Height * sy); + } + + if (sth != 1.0) + arc->Thickness = rnd_round((double)arc->Thickness * sth); + + pcb_arc_bbox(arc); + if (onbrd) + pcb_arc_post(arc); +} + +/* rotates an arc */ +void *pcb_arcop_rotate90(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + pcb_arc_invalidate_erase(Arc); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + if (Layer->arc_tree != NULL) + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_arc_rotate90(Arc, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.number); + if (Layer->arc_tree != NULL) + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) Arc); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + pcb_arc_invalidate_draw(Layer, Arc); + return Arc; +} + +void *pcb_arcop_rotate(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + pcb_arc_invalidate_erase(Arc); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + pcb_arc_rotate(Layer, Arc, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.cosa, ctx->rotate.sina, ctx->rotate.angle); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, Layer, Arc); + pcb_arc_invalidate_draw(Layer, Arc); + return Arc; +} + +void *pcb_arc_insert_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *arc) +{ + rnd_angle_t end_ang = arc->StartAngle + arc->Delta; + rnd_coord_t x = pcb_crosshair.X, y = pcb_crosshair.Y; + rnd_angle_t angle = atan2(-(y - arc->Y), (x - arc->X)) * 180.0 / M_PI + 180.0; + pcb_arc_t *new_arc; + + if (end_ang > 360.0) + end_ang -= 360.0; + if (end_ang < -360.0) + end_ang += 360.0; + + if ((arc->Delta < 0) || (arc->Delta > 180)) + new_arc = pcb_arc_new(Layer, arc->X, arc->Y, arc->Width, arc->Height, angle, end_ang - angle + 360.0, arc->Thickness, arc->Clearance, arc->Flags, rnd_true); + else + new_arc = pcb_arc_new(Layer, arc->X, arc->Y, arc->Width, arc->Height, angle, end_ang - angle, arc->Thickness, arc->Clearance, arc->Flags, rnd_true); + + if (new_arc != NULL) { + pcb_arc_copy_meta(new_arc, arc); + PCB_FLAG_CHANGE(PCB_CHGFLG_SET, PCB_FLAG_FOUND, new_arc); + if (arc->Delta < 0) + pcb_arc_set_angles(Layer, arc, arc->StartAngle, angle - arc->StartAngle - 360.0); + else + pcb_arc_set_angles(Layer, arc, arc->StartAngle, angle - arc->StartAngle); + pcb_undo_add_obj_to_create(PCB_OBJ_ARC, Layer, new_arc, new_arc); + } + return new_arc; +} + +void *pcb_arcop_change_flag(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + static pcb_flag_values_t pcb_arc_flags = 0; + if (pcb_arc_flags == 0) + pcb_arc_flags = pcb_obj_valid_flags(PCB_OBJ_ARC); + + if ((ctx->chgflag.flag & pcb_arc_flags) != ctx->chgflag.flag) + return NULL; + if ((ctx->chgflag.flag & PCB_FLAG_TERMNAME) && (Arc->term == NULL)) + return NULL; + pcb_undo_add_obj_to_flag(Arc); + + if (ctx->chgflag.flag & PCB_FLAG_CLEARLINE) + pcb_poly_restore_to_poly(ctx->chgflag.pcb->Data, PCB_OBJ_ARC, Arc->parent.layer, Arc); + + PCB_FLAG_CHANGE(ctx->chgflag.how, ctx->chgflag.flag, Arc); + + if (ctx->chgflag.flag & PCB_FLAG_CLEARLINE) + pcb_poly_clear_from_poly(ctx->chgflag.pcb->Data, PCB_OBJ_ARC, Arc->parent.layer, Arc); + + return Arc; +} + +void *pcb_arcop_invalidate_label(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_arc_t *arc) +{ + pcb_arc_name_invalidate_draw(arc); + return arc; +} + + +/*** draw ***/ + +static void arc_label_pos(const pcb_arc_t *arc, rnd_coord_t *x0, rnd_coord_t *y0, rnd_bool_t *vert) +{ + double da, ea, la; + + da = RND_CLAMP(arc->Delta, -360, 360); + ea = arc->StartAngle + da; + while(ea < -360) ea += 360; + while(ea > +360) ea -= 360; + + la = (arc->StartAngle+ea)/2.0; + + *x0 = rnd_round((double)arc->X - (double)arc->Width * cos(la * RND_M180)); + *y0 = rnd_round((double)arc->Y + (double)arc->Height * sin(la * RND_M180)); + *vert = (((la < 45) && (la > -45)) || ((la > 135) && (la < 225))); +} + +void pcb_arc_middle(const pcb_arc_t *arc, rnd_coord_t *x, rnd_coord_t *y) +{ + rnd_bool_t waste; + arc_label_pos(arc, x, y, &waste); +} + +void pcb_arc_approx(const pcb_arc_t *arc, double res, int reverse, void *uctx, int (*cb)(void *uctx, rnd_coord_t x, rnd_coord_t y)) +{ + double a, da = arc->Delta, sa, ea, ea2, step; + + while(da < -360.0) da = -360.0; + while(da > +360.0) da = +360.0; + + if (!reverse) { + sa = arc->StartAngle; + ea = sa + da; + } + else { + sa = arc->StartAngle + da; + ea = arc->StartAngle; + da = -da; + } + + if (res == 0) + res = RND_MM_TO_COORD(-1); + + if (res < 0) { + double arclen, delta; + delta = arc->Delta; + if (delta < 0) delta = -delta; + arclen = M_PI * ((double)arc->Width + (double)arc->Height) / 360.0 * delta; + step = delta / (arclen / -res); + } + else + step = res; + + if (ea > sa) { + if (step < 0) step = -step; + ea2 = ea - step/3; + for(a = sa; a < ea2; a += step) + if (cb(uctx, rnd_round((double)arc->X - (double)arc->Width * cos(a * RND_M180)), rnd_round((double)arc->Y + (double)arc->Height * sin(a * RND_M180))) != 0) + return; + } + else { + if (step > 0) step = +step; + ea2 = ea + step/3; + for(a = sa; a > ea2; a -= step) + if (cb(uctx, rnd_round((double)arc->X - (double)arc->Width * cos(a * RND_M180)), rnd_round((double)arc->Y + (double)arc->Height * sin(a * RND_M180))) != 0) + return; + } + + cb(uctx, rnd_round((double)arc->X - (double)arc->Width * cos(ea * RND_M180)), rnd_round((double)arc->Y + (double)arc->Height * sin(ea * RND_M180))); +} + +void pcb_arc_name_invalidate_draw(pcb_arc_t *arc) +{ + if (arc->term != NULL) { + rnd_coord_t x0, y0; + rnd_bool_t vert; + + arc_label_pos(arc, &x0, &y0, &vert); + pcb_term_label_invalidate(x0, y0, 100.0, vert, rnd_true, (pcb_any_obj_t *)arc); + } +} + +void pcb_arc_draw_label(pcb_draw_info_t *info, pcb_arc_t *arc, rnd_bool vis_side) +{ + if ((arc->term != NULL) && vis_side) { + rnd_coord_t x0, y0; + rnd_bool_t vert; + + arc_label_pos(arc, &x0, &y0, &vert); + pcb_term_label_draw(info, x0, y0, conf_core.appearance.term_label_size, vert, rnd_true, (pcb_any_obj_t *)arc); + } + if (arc->noexport && vis_side) { + rnd_coord_t cx, cy; + pcb_arc_middle(arc, &cx, &cy); + pcb_obj_noexport_mark(arc, cx, cy); + } + + if (arc->ind_editpoint) { + rnd_coord_t x1, y1, x2, y2; + pcb_obj_editpont_setup(); + + pcb_arc_get_end(arc, 0, &x1, &y1); + pcb_arc_get_end(arc, 1, &x2, &y2); + + pcb_obj_editpont_cross(arc->X, arc->Y); + if ((arc->X != x1) || (arc->Y != y1)) + pcb_obj_editpont_cross(x1, y1); + if ((x2 != x1) || (y2 != y1)) + pcb_obj_editpont_cross(x2, y2); + } +} + +void pcb_arc_draw_(pcb_draw_info_t *info, pcb_arc_t *arc, int allow_term_gfx) +{ + rnd_coord_t thickness = arc->Thickness; + int draw_lab; + + if (arc->Thickness < 0) + return; + + if (delayed_terms_enabled && (arc->term != NULL)) { + pcb_draw_delay_obj_add((pcb_any_obj_t *)arc); + return; + } + + if ((info != NULL) && (info->xform != NULL) && (info->xform->bloat != 0)) { + thickness += info->xform->bloat; + if (thickness < 1) + thickness = 1; + } + + PCB_DRAW_BBOX(arc); + + if (!info->xform->thin_draw && !info->xform->wireframe) + { + if ((allow_term_gfx) && pcb_draw_term_need_gfx(arc) && pcb_draw_term_hid_permission()) { + rnd_hid_set_line_cap(pcb_draw_out.active_padGC, rnd_cap_round); + rnd_hid_set_line_width(pcb_draw_out.active_padGC, thickness); + rnd_render->draw_arc(pcb_draw_out.active_padGC, arc->X, arc->Y, arc->Width, arc->Height, arc->StartAngle, arc->Delta); + rnd_hid_set_line_width(pcb_draw_out.fgGC, PCB_DRAW_TERM_GFX_WIDTH); + } + else + rnd_hid_set_line_width(pcb_draw_out.fgGC, thickness); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); + rnd_render->draw_arc(pcb_draw_out.fgGC, arc->X, arc->Y, arc->Width, arc->Height, arc->StartAngle, arc->Delta); + } + else + { + rnd_hid_set_line_width(pcb_draw_out.fgGC, 0); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); + + if(info->xform->thin_draw) + rnd_render->draw_arc(pcb_draw_out.fgGC, arc->X, arc->Y, arc->Width, arc->Height, arc->StartAngle, arc->Delta); + + if(info->xform->wireframe) + pcb_draw_wireframe_arc(pcb_draw_out.fgGC, arc, thickness); + } + + draw_lab = (arc->term != NULL) && ((pcb_draw_force_termlab) || PCB_FLAG_TEST(PCB_FLAG_TERMNAME, arc)); + draw_lab |= arc->ind_editpoint; + + if (draw_lab) + pcb_draw_delay_label_add((pcb_any_obj_t *)arc); +} + +static void pcb_arc_draw(pcb_draw_info_t *info, pcb_arc_t *arc, int allow_term_gfx) +{ + const rnd_color_t *color; + rnd_color_t buf; + const pcb_layer_t *layer = info->layer != NULL ? info->layer : pcb_layer_get_real(arc->parent.layer); + + pcb_obj_noexport(info, arc, return); + + if (layer == NULL) /* if the layer is inbound, e.g. in preview, fall back using the layer recipe */ + layer = arc->parent.layer; + + if (info->xform->flag_color && PCB_FLAG_TEST(PCB_FLAG_WARN, arc)) + color = &conf_core.appearance.color.warn; + else if (info->xform->flag_color && PCB_FLAG_TEST(PCB_FLAG_SELECTED | PCB_FLAG_FOUND, arc)) { + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, arc)) { + if (layer->is_bound) + PCB_OBJ_COLOR_ON_BOUND_LAYER(color, layer, 1); + else + color = &conf_core.appearance.color.selected; + } + else + color = &conf_core.appearance.color.connected; + } + else if (PCB_HAS_COLOROVERRIDE(arc)) { + color = arc->override_color; + } + else if (layer->is_bound) + PCB_OBJ_COLOR_ON_BOUND_LAYER(color, layer, 0); + else + color = &layer->meta.real.color; + + if (info->xform->flag_color && arc->ind_onpoint) { + pcb_lighten_color(color, &buf, 1.75); + color = &buf; + } + rnd_render->set_color(pcb_draw_out.fgGC, color); + pcb_arc_draw_(info, arc, allow_term_gfx); +} + +rnd_r_dir_t pcb_arc_draw_callback(const rnd_box_t * b, void *cl) +{ + pcb_arc_t *arc = (pcb_arc_t *)b; + pcb_draw_info_t *info = cl; + + if (pcb_hidden_floater((pcb_any_obj_t*)b, info) || pcb_partial_export((pcb_any_obj_t*)b, info)) + return RND_R_DIR_FOUND_CONTINUE; + + if (!PCB->SubcPartsOn && pcb_lobj_parent_subc(arc->parent_type, &arc->parent)) + return RND_R_DIR_NOT_FOUND; + + pcb_arc_draw(info, arc, 0); + return RND_R_DIR_FOUND_CONTINUE; +} + +rnd_r_dir_t pcb_arc_draw_term_callback(const rnd_box_t * b, void *cl) +{ + pcb_arc_t *arc = (pcb_arc_t *)b; + pcb_draw_info_t *info = cl; + + if (pcb_hidden_floater((pcb_any_obj_t*)b, info) || pcb_partial_export((pcb_any_obj_t*)b, info)) + return RND_R_DIR_FOUND_CONTINUE; + + if (!PCB->SubcPartsOn && pcb_lobj_parent_subc(arc->parent_type, &arc->parent)) + return RND_R_DIR_NOT_FOUND; + + pcb_arc_draw(info, arc, 1); + return RND_R_DIR_FOUND_CONTINUE; +} + +/* erases an arc on a layer */ +void pcb_arc_invalidate_erase(pcb_arc_t *Arc) +{ + if (!Arc->Thickness) + return; + pcb_draw_invalidate(Arc); + pcb_flag_erase(&Arc->Flags); +} + +void pcb_arc_invalidate_draw(pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + pcb_draw_invalidate(Arc); +} Index: tags/2.3.0/src/obj_arc.h =================================================================== --- tags/2.3.0/src/obj_arc.h (nonexistent) +++ tags/2.3.0/src/obj_arc.h (revision 33253) @@ -0,0 +1,152 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Drawing primitive: (elliptical) arc */ + +#ifndef PCB_OBJ_ARC_H +#define PCB_OBJ_ARC_H + +#include +#include "obj_common.h" + +struct pcb_arc_s { /* holds information about arcs */ + PCB_ANY_PRIMITIVE_FIELDS; + rnd_coord_t Thickness, Clearance; + rnd_coord_t Width, Height; /* length of axis */ + rnd_coord_t X, Y; /* center coordinates */ + rnd_angle_t StartAngle, Delta; /* the two limiting angles in degrees */ + gdl_elem_t link; /* an arc is in a list: either on a layer or in an element or in a font */ +}; + +/*** Memory ***/ +pcb_arc_t *pcb_arc_alloc(pcb_layer_t *); +pcb_arc_t *pcb_arc_alloc_id(pcb_layer_t *layer, long int id); +void pcb_arc_free(pcb_arc_t *data); + +pcb_arc_t *pcb_arc_new(pcb_layer_t *Layer, rnd_coord_t center_x, rnd_coord_t center_y, rnd_coord_t width_r, rnd_coord_t height_r, rnd_angle_t start_angle, rnd_angle_t delta_angle, rnd_coord_t Thickness, rnd_coord_t Clearance, pcb_flag_t Flags, rnd_bool prevent_dups); +pcb_arc_t *pcb_arc_dup(pcb_layer_t *dst, pcb_arc_t *src); +pcb_arc_t *pcb_arc_dup_at(pcb_layer_t *dst, pcb_arc_t *src, rnd_coord_t dx, rnd_coord_t dy); +void *pcb_arc_destroy(pcb_layer_t *Layer, pcb_arc_t *Arc); + +void pcb_arc_reg(pcb_layer_t *layer, pcb_arc_t *arc); +void pcb_arc_unreg(pcb_arc_t *arc); + +/* Add objects without creating them or making any "sanity modifications" to them */ +void pcb_add_arc_on_layer(pcb_layer_t *Layer, pcb_arc_t *Arc); + + +/*** Utility ***/ +void pcb_arc_bbox(pcb_arc_t *Arc); +void pcb_arc_rotate90(pcb_arc_t *Arc, rnd_coord_t X, rnd_coord_t Y, unsigned Number); +void pcb_arc_rotate(pcb_layer_t *layer, pcb_arc_t *arc, rnd_coord_t X, rnd_coord_t Y, double cosa, double sina, rnd_angle_t angle); +void pcb_arc_mirror(pcb_arc_t *arc, rnd_coord_t y_offs, rnd_bool undoable); +void pcb_arc_flip_side(pcb_layer_t *layer, pcb_arc_t *arc); +void pcb_arc_scale(pcb_arc_t *arc, double sx, double sy, double sth); +rnd_box_t pcb_arc_mini_bbox(const pcb_arc_t *arc); + + +/*** hash and eq ***/ +int pcb_arc_eq(const pcb_host_trans_t *tr1, const pcb_arc_t *a1, const pcb_host_trans_t *tr2, const pcb_arc_t *a2); +unsigned int pcb_arc_hash(const pcb_host_trans_t *tr, const pcb_arc_t *a); + + +/* Return the x;y coordinate of the endpoint of an arc; if which is 0, return + the endpoint that corresponds to StartAngle, else return the end angle's. */ +void pcb_arc_get_end(pcb_arc_t *Arc, int which, rnd_coord_t *x, rnd_coord_t *y); +void pcb_arc_middle(const pcb_arc_t *arc, rnd_coord_t *x, rnd_coord_t *y); + +/* Call cb() with coords of approximation for an arc from start to end, or + end to start (if reverse is true). Resolution is set by res: if it is positive, + it is an angle in degrees; if negative, it's an edge length in rnd_coord_t; if + zero, the default 1 mm resolution is used. If cb returns non-zero, the loop + quits immediately. Even stepping is not guaranteed, but visiting the exact + arc start and end point is. */ +void pcb_arc_approx(const pcb_arc_t *arc, double res, int reverse, void *uctx, int (*cb)(void *uctx, rnd_coord_t x, rnd_coord_t y)); + + +void pcb_arc_set_angles(pcb_layer_t *Layer, pcb_arc_t *a, rnd_angle_t new_sa, rnd_angle_t new_da); +void pcb_arc_set_radii(pcb_layer_t *Layer, pcb_arc_t *a, rnd_coord_t new_width, rnd_coord_t new_height); + +rnd_coord_t pcb_arc_length(const pcb_arc_t *arc); +double pcb_arc_area(const pcb_arc_t *arc); + +/* ptr3 values for start and end point */ +extern int *pcb_arc_start_ptr, *pcb_arc_end_ptr; + +/* un-administrate a arc; call before changing geometry */ +void pcb_arc_pre(pcb_arc_t *arc); + +/* re-administrate a arc; call after changing geometry */ +void pcb_arc_post(pcb_arc_t *arc); + +#define pcb_arc_move(a,dx,dy) \ + do { \ + rnd_coord_t __dx__ = (dx), __dy__ = (dy); \ + pcb_arc_t *__a__ = (a); \ + RND_MOVE_POINT((__a__)->X,(__a__)->Y,__dx__,__dy__); \ + RND_BOX_MOVE_LOWLEVEL(&((__a__)->BoundingBox),__dx__,__dy__); \ + RND_BOX_MOVE_LOWLEVEL(&((__a__)->bbox_naked),__dx__,__dy__); \ + } while(0) + +#define PCB_ARC_LOOP(element) do { \ + pcb_arc_t *arc; \ + gdl_iterator_t __it__; \ + linelist_foreach(&(element)->Arc, &__it__, arc) { + +#define PCB_ARC_ALL_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l =0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + PCB_ARC_LOOP(layer) + +#define PCB_ARC_COPPER_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l =0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (!(pcb_layer_flags(PCB, l) & PCB_LYT_COPPER)) continue; \ + PCB_ARC_LOOP(layer) + +#define PCB_ARC_SILK_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (!(pcb_layer_flags(PCB, l) & PCB_LYT_SILK)) continue; \ + PCB_ARC_LOOP(layer) + +#define PCB_ARC_VISIBLE_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (layer->meta.real.vis) \ + PCB_ARC_LOOP(layer) + +#endif Index: tags/2.3.0/src/obj_arc_draw.h =================================================================== --- tags/2.3.0/src/obj_arc_draw.h (nonexistent) +++ tags/2.3.0/src/obj_arc_draw.h (revision 33253) @@ -0,0 +1,44 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard draw of arcs ***/ + +#include "draw.h" + +/* Include rtree.h for this */ +#ifdef RND_RTREE_H +rnd_r_dir_t pcb_arc_draw_callback(const rnd_box_t * b, void *cl); +rnd_r_dir_t pcb_arc_draw_term_callback(const rnd_box_t * b, void *cl); +#endif + +void pcb_arc_draw_(pcb_draw_info_t *info, pcb_arc_t *arc, int allow_term_gfx); +void pcb_arc_invalidate_erase(pcb_arc_t *Arc); +void pcb_arc_invalidate_draw(pcb_layer_t *Layer, pcb_arc_t *Arc); +void pcb_arc_name_invalidate_draw(pcb_arc_t *arc); +void pcb_arc_draw_label(pcb_draw_info_t *info, pcb_arc_t *arc, rnd_bool vis_side); + Index: tags/2.3.0/src/obj_arc_list.c =================================================================== --- tags/2.3.0/src/obj_arc_list.c (nonexistent) +++ tags/2.3.0/src/obj_arc_list.c (revision 33253) @@ -0,0 +1,29 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#define TDL_DONT_UNDEF +#include "obj_arc_list.h" +#include Index: tags/2.3.0/src/obj_arc_list.h =================================================================== --- tags/2.3.0/src/obj_arc_list.h (nonexistent) +++ tags/2.3.0/src/obj_arc_list.h (revision 33253) @@ -0,0 +1,48 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_ARC_LIST_H +#define PCB_OBJ_ARC_LIST_H + +#include "obj_common.h" +#include "obj_arc.h" + +/* List of Arcs */ +#define TDL(x) arclist_ ## x +#define TDL_LIST_T arclist_t +#define TDL_ITEM_T pcb_arc_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define arclist_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + + +#include +#include + +#endif Index: tags/2.3.0/src/obj_arc_op.h =================================================================== --- tags/2.3.0/src/obj_arc_op.h (nonexistent) +++ tags/2.3.0/src/obj_arc_op.h (revision 33253) @@ -0,0 +1,60 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard operations on arc ***/ + +#include "operation.h" + +void *pcb_arcop_add_to_buffer(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_arc_t *arc); +void *pcb_arcop_change_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_change_clear_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_change_radius(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_change_angle(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_change_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_set_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_clear_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_copy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_move(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_move_noclip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_clip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_move_to_layer_low(pcb_opctx_t *ctx, pcb_layer_t * Source, pcb_arc_t * arc, pcb_layer_t * Destination); +void *pcb_arcop_move_to_layer(pcb_opctx_t *ctx, pcb_layer_t * Layer, pcb_arc_t * Arc); +void *pcb_arcop_destroy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_remove(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_remove_point(pcb_opctx_t *ctx, pcb_layer_t *l, pcb_arc_t *a, int *end_id); +void *pcb_arcop_rotate90(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_rotate(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_change_flag(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *Arc); +void *pcb_arcop_invalidate_label(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_arc_t *arc); +void *pcb_arcop_change_thermal(pcb_opctx_t *ctx, pcb_layer_t *ly, pcb_arc_t *arc); + + +void *pcb_arc_insert_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_arc_t *arc); + + Index: tags/2.3.0/src/obj_arc_ui.c =================================================================== --- tags/2.3.0/src/obj_arc_ui.c (nonexistent) +++ tags/2.3.0/src/obj_arc_ui.c (revision 33253) @@ -0,0 +1,145 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Arc UI logics */ + +#include "config.h" +#include +#include "obj_arc_ui.h" +#include "obj_arc.h" +#include + + +#include + +static void draw_mark(rnd_hid_gc_t gc, const pcb_arc_t *arc) +{ + const rnd_coord_t mark = RND_MM_TO_COORD(0.2); + rnd_render->draw_line(gc, arc->X-mark, arc->Y, arc->X+mark, arc->Y); + rnd_render->draw_line(gc, arc->X, arc->Y-mark, arc->X, arc->Y+mark); +} + +static void pcb_arc_ui_move_or_copy_angle(pcb_crosshair_t *ch) +{ + int *end_pt = ch->AttachedObject.Ptr3; + pcb_arc_t *arc = (pcb_arc_t *) pcb_crosshair.AttachedObject.Ptr2; + rnd_angle_t start = arc->StartAngle, delta = arc->Delta; + + if (end_pt == pcb_arc_start_ptr) { + double end2, new_delta, new_start = atan2(-(ch->Y - arc->Y), (ch->X - arc->X)) * 180.0 / M_PI + 180.0; + + end2 = start + delta; + new_delta = end2 - new_start; + if (new_delta > 360.0) + new_delta -= 360.0; + if (new_delta < -360.0) + new_delta += 360.0; + +/* fprintf(stderr, "start: %f new_start: %f delta=%f new delta=%f\n", start, new_start, delta, new_delta);*/ + + if (delta > 0) { + if (new_delta < 0) + new_delta += 360.0; + } + else { + if (new_delta > 0) + new_delta -= 360.0; + } + + start = new_start; + delta = new_delta; + } + else { + double new_delta, new_end = atan2(-(ch->Y - arc->Y), (ch->X - arc->X)) * 180.0 / M_PI + 180.0; + if (delta < 0) + new_end -= 360.0; +/* fprintf(stderr, "delta: %f abs-end: %f new-abs: %f new-delta: %f\n", delta, start+delta, new_end, new_end-start);*/ + new_delta = new_end-start; + if (delta > 0) { + if (new_delta < 0) + new_delta += 360.0; + } + else { + if (new_delta > 0) + new_delta -= 360.0; + } + delta = new_delta; + } + + if (delta > 360.0) + delta -= 360.0; + if (delta < -360.0) + delta += 360.0; + + /* remember the result of the calculation so the actual move code can reuse them */ + ch->AttachedObject.start_angle = start; + ch->AttachedObject.delta_angle = delta; + ch->AttachedObject.radius = 0; + + rnd_render->draw_arc(ch->GC, arc->X, arc->Y, arc->Width, arc->Height, start, delta); + draw_mark(ch->GC, arc); +} + +void pcb_arc_ui_move_or_copy_endp(pcb_crosshair_t *ch) +{ + int *end_pt = ch->AttachedObject.Ptr3; + pcb_arc_t arc2, *arc = (pcb_arc_t *) pcb_crosshair.AttachedObject.Ptr2; + rnd_coord_t ex, ey; + double dx, dy, d; + + pcb_arc_get_end(arc, (end_pt != NULL), &ex, &ey); + + dx = (arc->X - ch->X); + dy = (arc->Y - ch->Y); + d = sqrt(dx*dx+dy*dy); + + ch->AttachedObject.radius = d; + + rnd_render->draw_arc(ch->GC, arc->X, arc->Y, ch->AttachedObject.radius, ch->AttachedObject.radius, arc->StartAngle, arc->Delta); + + draw_mark(ch->GC, &arc2); +} + + +void pcb_arc_ui_move_or_copy(pcb_crosshair_t *ch) +{ + if (rnd_gui->shift_is_pressed(rnd_gui) || (ch->AttachedObject.radius != 0)) + pcb_arc_ui_move_or_copy_endp(ch); + else + pcb_arc_ui_move_or_copy_angle(ch); +} + + +int pcb_obj_ui_arc_point_bbox(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_box_t *res) +{ + pcb_arc_t *arc = Ptr2; + int *end_pt = Ptr3; + rnd_coord_t ex, ey; + pcb_arc_get_end(arc, (end_pt != pcb_arc_start_ptr), &ex, &ey); + *res = rnd_point_box(ex, ey); + return 0; +} + Index: tags/2.3.0/src/obj_arc_ui.h =================================================================== --- tags/2.3.0/src/obj_arc_ui.h (nonexistent) +++ tags/2.3.0/src/obj_arc_ui.h (revision 33253) @@ -0,0 +1,33 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ +/* Arc UI logics */ + +#include "crosshair.h" + +void pcb_arc_ui_move_or_copy(pcb_crosshair_t *ch); +int pcb_obj_ui_arc_point_bbox(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_box_t *res); +void pcb_arc_middle(const pcb_arc_t *arc, rnd_coord_t *x, rnd_coord_t *y); + Index: tags/2.3.0/src/obj_common.c =================================================================== --- tags/2.3.0/src/obj_common.c (nonexistent) +++ tags/2.3.0/src/obj_common.c (revision 33253) @@ -0,0 +1,485 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2005 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include "config.h" + +#include +#include +#include "conf_core.h" +#include "flag_str.h" +#include +#include +#include "obj_common.h" +#include "obj_arc_ui.h" +#include "obj_pstk.h" +#include "obj_subc.h" +#include "obj_subc_parent.h" +#include "obj_term.h" +#include "extobj.h" + +const char *pcb_obj_type_name(pcb_objtype_t type) +{ + switch(type) { + case PCB_OBJ_VOID: return "void"; + case PCB_OBJ_LINE: return "line"; + case PCB_OBJ_TEXT: return "text"; + case PCB_OBJ_POLY: return "polygon"; + case PCB_OBJ_ARC: return "arc"; + case PCB_OBJ_RAT: return "ratline"; + case PCB_OBJ_GFX: return "gfx"; + case PCB_OBJ_PSTK: return "padstack"; + case PCB_OBJ_SUBC: return "subcircuit"; + case PCB_OBJ_NET: return "net"; + case PCB_OBJ_NET_TERM: return "net_term"; + case PCB_OBJ_LAYER: return "layer"; + case PCB_OBJ_LAYERGRP: return "layer_group"; + } + switch((pcb_vobjtype_t)type) { + case PCB_OBJ_LINE_POINT: return "line_point"; + case PCB_OBJ_POLY_POINT: return "poly_point"; + case PCB_OBJ_ARC_POINT: return "arc_point"; + case PCB_OBJ_SUBC_PART: return "subc_part"; + case PCB_OBJ_LOCKED: return "locked"; + case PCB_OBJ_FLOATER: return "floater"; + case PCB_OBJ_GFX_POINT: return "gfx_point"; + + } + return ""; +} + +/* returns a pointer to an objects bounding box; + * data is valid until the routine is called again + */ +int pcb_obj_get_bbox_naked(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_box_t *res) +{ + switch (Type) { + case PCB_OBJ_LINE: + case PCB_OBJ_ARC: + case PCB_OBJ_TEXT: + case PCB_OBJ_POLY: + case PCB_OBJ_PSTK: + case PCB_OBJ_GFX: + *res = ((pcb_any_obj_t *)Ptr2)->bbox_naked; + return 0; + case PCB_OBJ_SUBC: + *res = ((pcb_any_obj_t *)Ptr1)->bbox_naked; + return 0; + case PCB_OBJ_POLY_POINT: + case PCB_OBJ_LINE_POINT: + case PCB_OBJ_GFX_POINT: + *res = *(rnd_box_t *)Ptr3; + return 0; + case PCB_OBJ_ARC_POINT: + return pcb_obj_ui_arc_point_bbox(Type, Ptr1, Ptr2, Ptr3, res); + default: + rnd_message(RND_MSG_ERROR, "Request for bounding box of unsupported type %d\n", Type); + *res = *(rnd_box_t *)Ptr2; + return -1; + } +} + + + +/* current object ID; incremented after each creation of an object */ +long int ID = 1; + +rnd_bool pcb_create_being_lenient = rnd_false; + +void pcb_create_be_lenient(rnd_bool v) +{ + pcb_create_being_lenient = v; +} + +void pcb_create_ID_bump(int min_id) +{ + if (ID < min_id) + ID = min_id; +} + +void pcb_create_ID_reset(void) +{ + ID = 1; +} + +long int pcb_create_ID_get(void) +{ + return ID++; +} + +static void pcb_attribute_copy_all_smart(pcb_attribute_list_t *dest, const pcb_attribute_list_t *src, pcb_any_obj_t *dstobj, pcb_any_obj_t *copy_from_any) +{ + int i; + for (i = 0; i < src->Number; i++) + pcb_attribute_put(dest, src->List[i].name, src->List[i].value); +} + + +void pcb_obj_add_attribs(pcb_any_obj_t *o, const pcb_attribute_list_t *src, pcb_any_obj_t *copy_from) +{ + if (src == NULL) + return; + if (copy_from) + pcb_attribute_copy_all_smart(&o->Attributes, src, o, copy_from); + else + pcb_attribute_copy_all(&o->Attributes, src); +} + +void pcb_obj_center(const pcb_any_obj_t *obj, rnd_coord_t *x, rnd_coord_t *y) +{ + switch (obj->type) { + case PCB_OBJ_PSTK: + *x = ((const pcb_pstk_t *)(obj))->x; + *y = ((const pcb_pstk_t *)(obj))->y; + break; + case PCB_OBJ_ARC: + pcb_arc_middle((const pcb_arc_t *)obj, x, y); + break; + default: + *x = (obj->BoundingBox.X1 + obj->BoundingBox.X2) / 2; + *y = (obj->BoundingBox.Y1 + obj->BoundingBox.Y2) / 2; + } +} + +void pcb_obj_attrib_post_change(pcb_attribute_list_t *list, const char *name, const char *value) +{ + pcb_any_obj_t *obj = (pcb_any_obj_t *)(((char *)list) - offsetof(pcb_any_obj_t, Attributes)); + if (strcmp(name, "term") == 0) { + const char *inv; + pcb_subc_t *subc = pcb_obj_parent_subc(obj); + + if ((subc != NULL) && (obj->term != NULL)) /* remove the old term */ + pcb_term_del(&subc->terminals, obj->term, obj); + obj->term = value; + if ((subc != NULL) && (obj->term != NULL)) /* add the new term */ + pcb_term_add(&subc->terminals, obj); + inv = pcb_obj_id_invalid(obj->term); + if (inv != NULL) + rnd_message(RND_MSG_ERROR, "Invalid character '%c' in terminal name (term attribute) '%s'\n", *inv, obj->term); + } + else if (strcmp(name, "intconn") == 0) { + long cid = 0; + if (value != NULL) { + char *end; + cid = strtol(value, &end, 10); + if (*end != '\0') + cid = 0; + } + obj->intconn = cid; + } + else if (strcmp(name, "intnoconn") == 0) { + long cid = 0; + if (value != NULL) { + char *end; + cid = strtol(value, &end, 10); + if (*end != '\0') + cid = 0; + } + obj->intnoconn = cid; + } + else if (strncmp(name, "noexport", 8) == 0) { + obj->noexport = 1; + obj->noexport_named = (name[8] == ':'); + } + else if (strncmp(name, "extobj::", 8) == 0) { + const char *arg = name+8; + if (strcmp(arg, "role") == 0) + obj->extobj_role = value; + } + else if ((obj->type == PCB_OBJ_TEXT) && (strcmp(name, "tight_clearance") == 0)) { + pcb_text_t *t = (pcb_text_t *)obj; + t->tight_clearance = rnd_istrue(value); + } + else if ((obj->type == PCB_OBJ_TEXT) && (strcmp(name, "mirror_x") == 0)) { + pcb_text_t *t = (pcb_text_t *)obj; + t->mirror_x = rnd_istrue(value); + } + else if ((obj->type == PCB_OBJ_GFX) && (strcmp(name, "render_level") == 0)) { + pcb_gfx_t *g = (pcb_gfx_t *)obj; + if ((value != NULL) && ((*value == 'u') || (*value == 'U'))) g->render_under = 1; + else g->render_under = 0; + } +} + +const char *pcb_obj_id_invalid(const char *id) +{ + const char *s; + if (id != NULL) + for(s = id; *s != '\0'; s++) { + if (isalnum(*s)) + continue; + switch(*s) { + case '_': case '.': case '$': case '*': case ':': continue; + } + return s; + } + return NULL; +} + +char *pcb_obj_id_fix(char *id) +{ + char *s; + if (id == NULL) + return NULL; + + for(s = id; *s != '\0'; s++) { + if (isalnum(*s)) + continue; + switch(*s) { + case '_': case '.': case '$': case '*': case ':': continue; + default: *s = '_'; + } + } + + return id; +} + + +pcb_flag_values_t pcb_obj_valid_flags(unsigned long int objtype) +{ + pcb_flag_values_t res = 0; + int n; + + for(n = 0; n < pcb_object_flagbits_len; n++) + if (pcb_object_flagbits[n].object_types & objtype) + res |= pcb_object_flagbits[n].mask; + + return res; +} + +rnd_coord_t pcb_obj_clearance_at(pcb_board_t *pcb, const pcb_any_obj_t *o, pcb_layer_t *at) +{ + switch(o->type) { + case PCB_OBJ_POLY: + if (!(PCB_POLY_HAS_CLEARANCE((pcb_poly_t *)o))) + return 0; + return ((pcb_poly_t *)o)->Clearance; + case PCB_OBJ_LINE: + if (!(PCB_NONPOLY_HAS_CLEARANCE((pcb_line_t *)o))) + return 0; + return ((pcb_line_t *)o)->Clearance; + case PCB_OBJ_TEXT: + return 0; + case PCB_OBJ_ARC: + if (!(PCB_NONPOLY_HAS_CLEARANCE((pcb_arc_t *)o))) + return 0; + return ((pcb_arc_t *)o)->Clearance; + case PCB_OBJ_PSTK: + return obj_pstk_get_clearance(pcb, (pcb_pstk_t *)o, at); + default: + return 0; + } +} + +static void mmult(pcb_xform_mx_t dst, const pcb_xform_mx_t src) +{ + pcb_xform_mx_t tmp; + + tmp[0] = dst[0] * src[0] + dst[1] * src[3] + dst[2] * src[6]; + tmp[1] = dst[0] * src[1] + dst[1] * src[4] + dst[2] * src[7]; + tmp[2] = dst[0] * src[2] + dst[1] * src[5] + dst[2] * src[8]; + + tmp[3] = dst[3] * src[0] + dst[4] * src[3] + dst[5] * src[6]; + tmp[4] = dst[3] * src[1] + dst[4] * src[4] + dst[5] * src[7]; + tmp[5] = dst[3] * src[2] + dst[4] * src[5] + dst[5] * src[8]; + + tmp[6] = dst[6] * src[0] + dst[7] * src[3] + dst[8] * src[6]; + tmp[7] = dst[6] * src[1] + dst[7] * src[4] + dst[8] * src[7]; + tmp[8] = dst[6] * src[2] + dst[7] * src[5] + dst[8] * src[8]; + + memcpy(dst, tmp, sizeof(tmp)); +} + +void pcb_xform_mx_rotate(pcb_xform_mx_t mx, double deg) +{ + pcb_xform_mx_t tr; + + deg /= RND_RAD_TO_DEG; + + tr[0] = cos(deg); + tr[1] = sin(deg); + tr[2] = 0; + + tr[3] = -sin(deg); + tr[4] = cos(deg); + tr[5] = 0; + + tr[6] = 0; + tr[7] = 0; + tr[8] = 1; + + mmult(mx, tr); +} + +void pcb_xform_mx_translate(pcb_xform_mx_t mx, double xt, double yt) +{ + pcb_xform_mx_t tr; + + tr[0] = 1; + tr[1] = 0; + tr[2] = xt; + + tr[3] = 0; + tr[4] = 1; + tr[5] = yt; + + tr[6] = 0; + tr[7] = 0; + tr[8] = 1; + + mmult(mx, tr); +} + +void pcb_xform_mx_scale(pcb_xform_mx_t mx, double sx, double sy) +{ + pcb_xform_mx_t tr; + + tr[0] = sx; + tr[1] = 0; + tr[2] = 0; + + tr[3] = 0; + tr[4] = sy; + tr[5] = 0; + + tr[6] = 0; + tr[7] = 0; + tr[8] = 1; + + mmult(mx, tr); +} + +void pcb_xform_mx_shear(pcb_xform_mx_t mx, double sx, double sy) +{ + pcb_xform_mx_t tr; + + tr[0] = 1; + tr[1] = sx; + tr[2] = 0; + + tr[3] = sy; + tr[4] = 1; + tr[5] = 0; + + tr[6] = 0; + tr[7] = 0; + tr[8] = 1; + + mmult(mx, tr); +} + +void pcb_xform_mx_mirrorx(pcb_xform_mx_t mx) +{ + pcb_xform_mx_scale(mx, 0, -1); +} + +void pcb_obj_pre(pcb_any_obj_t *o) +{ + switch(o->type) { + case PCB_OBJ_LINE: pcb_line_pre((pcb_line_t *)o); break; + case PCB_OBJ_TEXT: pcb_text_pre((pcb_text_t *)o); break; + case PCB_OBJ_POLY: pcb_poly_pre((pcb_poly_t *)o); break; + case PCB_OBJ_ARC: pcb_arc_pre((pcb_arc_t *)o); break; + case PCB_OBJ_GFX: pcb_gfx_pre((pcb_gfx_t *)o); break; + case PCB_OBJ_PSTK: pcb_pstk_pre((pcb_pstk_t *)o); break; + default: break; + } +} + +void pcb_obj_post(pcb_any_obj_t *o) +{ + switch(o->type) { + case PCB_OBJ_LINE: pcb_line_post((pcb_line_t *)o); break; + case PCB_OBJ_TEXT: pcb_text_post((pcb_text_t *)o); break; + case PCB_OBJ_POLY: pcb_poly_post((pcb_poly_t *)o); break; + case PCB_OBJ_ARC: pcb_arc_post((pcb_arc_t *)o); break; + case PCB_OBJ_GFX: pcb_gfx_post((pcb_gfx_t *)o); break; + case PCB_OBJ_PSTK: pcb_pstk_post((pcb_pstk_t *)o); break; + default: break; + } +} + +void pcb_obj_change_id(pcb_any_obj_t *obj, long int new_id) +{ + pcb_data_t *data; + + if (obj->parent_type == PCB_PARENT_DATA) + data = obj->parent.data; + else if (obj->parent_type == PCB_PARENT_LAYER) + data = obj->parent.layer->parent.data; + else + return; + + pcb_obj_id_del(data, obj); + obj->ID = new_id; + pcb_obj_id_reg(data, obj); +} + + +void pcb_set_point_bounding_box(rnd_point_t *Pnt) +{ + Pnt->X2 = Pnt->X + 1; + Pnt->Y2 = Pnt->Y + 1; +} + +void pcb_obj_common_free(pcb_any_obj_t *o) +{ + if (o->override_color != NULL) { + free(o->override_color); + o->override_color = NULL; + } +} + +unsigned char *pcb_obj_common_get_thermal(pcb_any_obj_t *obj, unsigned long lid, rnd_bool_t alloc) +{ + if (obj->type == PCB_OBJ_PSTK) + return pcb_pstk_get_thermal((pcb_pstk_t *)obj, lid, alloc); + + return &obj->thermal; +} + + +void pcb_obj_update_bbox(pcb_board_t *pcb, pcb_any_obj_t *obj) +{ + switch(obj->type) { + case PCB_OBJ_ARC: pcb_arc_bbox((pcb_arc_t *)obj); break; + case PCB_OBJ_LINE: pcb_line_bbox((pcb_line_t *)obj); break; + case PCB_OBJ_POLY: pcb_poly_bbox((pcb_poly_t *)obj); break; + case PCB_OBJ_TEXT: pcb_text_bbox(pcb_font(pcb, ((pcb_text_t *)obj)->fid, 1), (pcb_text_t *)obj); break; + case PCB_OBJ_SUBC: pcb_subc_bbox((pcb_subc_t *)obj); break; + case PCB_OBJ_PSTK: pcb_pstk_bbox((pcb_pstk_t *)obj); break; + case PCB_OBJ_GFX: pcb_gfx_bbox((pcb_gfx_t *)obj); break; + + case PCB_OBJ_RAT: + case PCB_OBJ_VOID: + case PCB_OBJ_NET: + case PCB_OBJ_NET_TERM: + case PCB_OBJ_LAYER: + case PCB_OBJ_LAYERGRP: + /* these don't have bbox */ + break; + } +} Index: tags/2.3.0/src/obj_common.h =================================================================== --- tags/2.3.0/src/obj_common.h (nonexistent) +++ tags/2.3.0/src/obj_common.h (revision 33253) @@ -0,0 +1,453 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_OBJ_COMMON_H +#define PCB_OBJ_COMMON_H + +#include +#include +#include "flag.h" +#include "attrib.h" +#include "global_typedefs.h" +#include "data_parent.h" + +/* Real objects that have actual struct; can be used as a bitfield */ +typedef enum pcb_objtype_e { + PCB_OBJ_VOID = 0x0000000, + + PCB_OBJ_ARC = 0x0000001, + PCB_OBJ_LINE = 0x0000002, + PCB_OBJ_POLY = 0x0000004, + PCB_OBJ_TEXT = 0x0000008, + PCB_OBJ_SUBC = 0x0000010, + PCB_OBJ_PSTK = 0x0000020, + PCB_OBJ_RAT = 0x0000040, + PCB_OBJ_GFX = 0x0000080, + + /* more abstract objects */ + PCB_OBJ_NET = 0x0001000, + PCB_OBJ_NET_TERM = 0x0002000, + PCB_OBJ_LAYER = 0x0004000, + PCB_OBJ_LAYERGRP = 0x0008000 +} pcb_objtype_t; + +/* Virtual objects for configuring searches; can be used as a bitfield with the above */ +typedef enum pcb_vobjtype_e { + PCB_OBJ_ARC_POINT = 0x0100000, + PCB_OBJ_LINE_POINT = 0x0200000, + PCB_OBJ_POLY_POINT = 0x0400000, + PCB_OBJ_SUBC_PART = 0x0800000, + PCB_OBJ_LOCKED = 0x1000000, + PCB_OBJ_FLOATER = 0x2000000, + PCB_OBJ_GFX_POINT = 0x4000000 +} pcb_vobjtype_t; + + +/* combinations, groups, masks of pcb_objtype_t */ +typedef enum pcb_objmask_e { + /* lists */ + PCB_OBJ_CLASS_PIN = (PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART), + PCB_OBJ_CLASS_TERM = (PCB_OBJ_CLASS_PIN | PCB_OBJ_SUBC_PART | PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_TEXT), + PCB_OBJ_CLASS_LAYER = (PCB_OBJ_ARC | PCB_OBJ_LINE | PCB_OBJ_POLY | PCB_OBJ_TEXT | PCB_OBJ_GFX), + PCB_OBJ_CLASS_GLOBAL = (PCB_OBJ_SUBC | PCB_OBJ_PSTK), + + /* masks */ + PCB_OBJ_CLASS_REAL = 0x0000FFF, /* global and on-layer objects (but not abstract things like layers) */ + PCB_OBJ_CLASS_HOST = 0x00FF000, /* host types: layers, boards, nets */ + PCB_OBJ_CLASS_MASK = 0xFF00000, /* for virtual searches */ + PCB_OBJ_CLASS_OBJ = 0x0000000, /* anything with common object fields (pcb_any_obj_t) */ + PCB_OBJ_ANY = 0xFFFFFFF +} pcb_objmask_t; + + +/* point and box type - they are so common everything depends on them */ +struct rnd_point_s { /* a line/polygon point */ + rnd_coord_t X, Y, X2, Y2; /* so Point type can be cast as rnd_box_t */ + long int ID; +}; + +typedef double pcb_xform_mx_t[9]; +#define PCB_XFORM_MX_IDENT {1,0,0, 0,1,0, 0,0,1} + +struct rnd_xform_s { /* generic object transformation; all-zero means no transformation */ + rnd_coord_t bloat; /* if non-zero, bloat (positive) or shrink (negative) by this value */ + + unsigned layer_faded:1; /* draw layer colors faded */ + unsigned omit_overlay:1; /* do not draw overlays (which are useful on screen but normally omitted on exports, except if --as-shown is specified */ + unsigned partial_export:1; /* 1 if only objects with the EXPORTSEL flag should be drawn */ + unsigned no_slot_in_nonmech:1; /* if 1, do not draw slots on non-mechanical layers (e.g. "no slot in copper") */ + unsigned wireframe:1; /* when 1, draw wireframe contours instead of solid objects */ + unsigned thin_draw:1; /* when 1, draw thin centerline instead of solid objects (implies thin_draw_poly) */ + unsigned thin_draw_poly:1; /* when 1, draw thin countour instead of solid polygons */ + unsigned check_planes:1; /* when 1, draw polygons only */ + unsigned flag_color:1; /* when zero, ignore colors that would be derived from object flags (i.e. selection, warn, found) */ + unsigned hide_floaters:1; /* when 1 omit drawing floaters (typically refdes text on silk) */ + unsigned show_solder_side:1; /* GUI */ + unsigned invis_other_groups:1; /* GUI */ + unsigned black_current_group:1; /* GUI */ + /* WARNING: After adding new fields, make sure to update pcb_xform_add() and pcb_xform_is_nop() below */ +}; + +#define pcb_xform_clear(dst) memset(dst, 0, sizeof(rnd_xform_t)) +#define pcb_xform_copy(dst, src) memcpy(dst, src, sizeof(rnd_xform_t)) +#define pcb_xform_add(dst, src) \ + do { \ + rnd_xform_t *__dst__ = dst; \ + const rnd_xform_t *__src__ = src; \ + __dst__->bloat += __src__->bloat; \ + __dst__->layer_faded |= __src__->layer_faded; \ + __dst__->omit_overlay |= __src__->omit_overlay; \ + __dst__->partial_export |= __src__->partial_export; \ + __dst__->no_slot_in_nonmech |= __src__->no_slot_in_nonmech; \ + __dst__->wireframe |= __src__->wireframe; \ + __dst__->thin_draw |= __src__->thin_draw; \ + __dst__->thin_draw_poly |= __src__->thin_draw_poly; \ + __dst__->check_planes |= __src__->check_planes; \ + __dst__->flag_color |= __src__->flag_color; \ + __dst__->hide_floaters |= __src__->hide_floaters; \ + __dst__->show_solder_side |= __src__->show_solder_side; \ + __dst__->invis_other_groups |= __src__->invis_other_groups; \ + __dst__->black_current_group |= __src__->black_current_group; \ + } while(0) +#define pcb_xform_is_nop(src) (\ + ((src)->bloat == 0) && \ + ((src)->layer_faded == 0) && \ + ((src)->omit_overlay == 0) && ((src)->partial_export == 0) && \ + ((src)->no_slot_in_nonmech == 0) && \ + ((src)->wireframe == 0) && \ + ((src)->thin_draw == 0) && \ + ((src)->thin_draw_poly == 0) && \ + ((src)->check_planes == 0) && \ + ((src)->flag_color == 0) && \ + ((src)->hide_floaters == 0) && \ + ((src)->show_solder_side == 0) && \ + ((src)->invis_other_groups == 0) && \ + ((src)->black_current_group == 0) \ + ) + +/* Returns true if overlay drawing should be omitted */ +#define pcb_xform_omit_overlay(info) \ + ((info != NULL) && (info->xform != NULL) && (info->xform->omit_overlay != 0)) + +/* Standard 2d matrix transformation using mx as pcb_xform_mx_t */ +#define pcb_xform_x(mx, x_in, y_in) ((double)(x_in) * mx[0] + (double)(y_in) * mx[1] + mx[2]) +#define pcb_xform_y(mx, x_in, y_in) ((double)(x_in) * mx[3] + (double)(y_in) * mx[4] + mx[5]) + +void pcb_xform_mx_rotate(pcb_xform_mx_t mx, double deg); +void pcb_xform_mx_translate(pcb_xform_mx_t mx, double xt, double yt); +void pcb_xform_mx_scale(pcb_xform_mx_t mx, double st, double sy); +void pcb_xform_mx_shear(pcb_xform_mx_t mx, double sx, double sy); +void pcb_xform_mx_mirrorx(pcb_xform_mx_t mx); /* mirror over the x axis (flip y coords) */ + +/* Return the user readable name of an object type in a string; never NULL */ +const char *pcb_obj_type_name(pcb_objtype_t type); + +/* returns a flag mask of all valid flags for an (old) object type */ +pcb_flag_values_t pcb_obj_valid_flags(unsigned long int objtype); + + +int pcb_obj_get_bbox_naked(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_box_t *res); + +/* Host transformations: typically the transformations an object of a subc + inherits from the subc */ +typedef struct pcb_host_trans_s { + rnd_coord_t ox, oy; + int on_bottom; + double rot; + double cosa, sina; /* rot angle cache */ +} pcb_host_trans_t; + +/* memset object to 0, but keep the link field */ +#define reset_obj_mem(type, obj) \ +do { \ + gdl_elem_t __lnk__ = obj->link; \ + memset(obj, 0, sizeof(type)); \ + obj->link = __lnk__; \ +} while(0) \ + + +/* rnd_true during file loads, for example to allow overlapping vias. + rnd_false otherwise, to stop the user from doing normally dangerous + things. */ +void pcb_create_be_lenient(rnd_bool); +extern rnd_bool pcb_create_being_lenient; + +void pcb_create_ID_bump(int min_id); +void pcb_create_ID_reset(void); +long int pcb_create_ID_get(void); + +/* Copy src attributes into obj's attributes, overwriting anything. If src_obj + is not NULL, it is the source object - be smart about extobj and other + attribute side effects (some of those will not be copied or will be + changed); src_obj should be the objec src attributes are coming from */ +void pcb_obj_add_attribs(pcb_any_obj_t *obj, const pcb_attribute_list_t *src, pcb_any_obj_t *src_obj); + +/* --------------------------------------------------------------------------- + * Do not change the following definitions even if they're not very + * nice. It allows us to have functions act on these "base types" and + * not need to know what kind of actual object they're working on. + */ + +/* Any object that ends up in common use as pcb_any_obj_t, MUST be defined + using this as the first fieldsusing the following macros. */ +#define PCB_ANY_OBJ_FIELDS \ + rnd_box_t BoundingBox; \ + long int ID; \ + pcb_flag_t Flags; \ + pcb_objtype_t type; \ + pcb_parenttype_t parent_type; \ + pcb_parent_t parent; \ + rnd_box_t bbox_naked; \ + unsigned ind_onpoint:1; \ + unsigned ind_editpoint:1; \ + pcb_attribute_list_t Attributes \ + +#define PCB_ANY_PRIMITIVE_FIELDS \ + PCB_ANY_OBJ_FIELDS; \ + const char *term, *extobj_role; \ + void *ratconn; \ + unsigned char thermal; \ + unsigned char intconn, intnoconn; \ + unsigned int noexport:1; \ + unsigned int noexport_named:1; \ + unsigned int extobj_editing:1; \ + rnd_color_t *override_color + +/* Lines, pads, and rats all use this so they can be cross-cast. */ +#define PCB_ANYLINEFIELDS \ + PCB_ANY_PRIMITIVE_FIELDS; \ + rnd_coord_t Thickness, Clearance; \ + rnd_point_t Point1, Point2 + +/* All on-pcb objects (elements, lines, pads, vias, rats, etc) are + based on this. */ +struct pcb_any_obj_s { + PCB_ANY_PRIMITIVE_FIELDS; +}; + +/* Lines, rats, pads, etc. */ +struct pcb_any_line_s { + PCB_ANYLINEFIELDS; +}; + +/* Return the geometric center of an object, as shown (center of bbox usually, + but not for an arc) */ +void pcb_obj_center(const pcb_any_obj_t *obj, rnd_coord_t *x, rnd_coord_t *y); + +/* Return the clearance value of object on the specified layer (in + case of padstack - in case of other objects layer is ignored) */ +rnd_coord_t pcb_obj_clearance_at(pcb_board_t *pcb, const pcb_any_obj_t *o, pcb_layer_t *at); + +unsigned char *pcb_obj_common_get_thermal(pcb_any_obj_t *obj, unsigned long lid, rnd_bool_t alloc); + +/* Update cached attributes (->term) */ +void pcb_obj_attrib_post_change(pcb_attribute_list_t *list, const char *name, const char *value); + +/* Returns the first invalid character of an ID (terminal, refdes) or NULL */ +const char *pcb_obj_id_invalid(const char *id); + +/* Fix an ID in place (replace anything invalid with '_'); returns id */ +char *pcb_obj_id_fix(char *id); + +/* switch() on o->type and call the right implementation */ +void pcb_obj_pre(pcb_any_obj_t *o); +void pcb_obj_post(pcb_any_obj_t *o); + +/* change the ID of an object already registered in the ID hash */ +void pcb_obj_change_id(pcb_any_obj_t *o, long int new_id); + +/* sets the bounding box of a point */ +void pcb_set_point_bounding_box(rnd_point_t *Pnt); + +void pcb_obj_common_free(pcb_any_obj_t *o); + +/* Determine the size class of a sub-kilobyte object: the largest 2^n that + is smaller than the size; size must be at least 16. */ +#define pcb_size_class(a) ((a) < 32 ? 16 : ((a) < 64 ? 32 : ((a) < 128 ? 64 : ((a) < 256 ? 128 : ((a) < 512 ? 256 : ((a) < 1024 ? 512 : 1024 )))))) + +/* Return an object-instance-unique integer value */ +RND_INLINE size_t pcb_obj_iid(pcb_any_obj_t *obj) +{ + return (size_t)obj / pcb_size_class(sizeof(pcb_any_obj_t)); +} + +/* Recalculate the bounding box of the object */ +void pcb_obj_update_bbox(pcb_board_t *pcb, pcb_any_obj_t *obj); + + +/* Assuming clearance is happening (flags), clearance of an object + in a polygon is the bigger of the obj's ->clearance and the polygon's + ->enforce_clearance */ +#define pcb_obj_clearance(obj, in_poly) \ + (RND_MAX((obj)->Clearance, (in_poly)->enforce_clearance)) + +#define pcb_obj_clearance_p2(obj, in_poly) \ + (RND_MAX((obj)->Clearance, ((in_poly)->enforce_clearance)*2)) + +#define pcb_obj_clearance_o05(obj, in_poly) \ + (RND_MAX((obj)->Clearance/2, ((in_poly)->enforce_clearance))) + +#define pcb_obj_id_reg(data, obj) \ + do { \ + pcb_any_obj_t *__obj__ = (pcb_any_obj_t *)(obj); \ + htip_set(&(data)->id2obj, __obj__->ID, __obj__); \ + } while(0) + +#define pcb_obj_id_del(data, obj) \ + htip_pop(&(data)->id2obj, (obj)->ID) + +/* Figure object's noexport attribute vs. the current exporter and run + inhibit if object should not be exported. On GUI, draw the no-export mark + at x;y */ +#define pcb_obj_noexport(info, obj, inhibit) \ +do { \ + if (obj->noexport) { \ + if (info->exporting) { \ + if (!obj->noexport_named || (pcb_attribute_get(&obj->Attributes, info->noexport_name) != NULL)) { \ + inhibit; \ + } \ + } \ + else \ + pcb_draw_delay_label_add((pcb_any_obj_t *)obj); \ + } \ +} while(0) + +#define pcb_obj_noexport_mark(obj, cx, cy) \ +do { \ + rnd_coord_t radius = RND_MM_TO_COORD(0.2); \ + int selected = PCB_FLAG_TEST(PCB_FLAG_SELECTED, obj); \ + rnd_render->set_color(pcb_draw_out.fgGC, selected ? &conf_core.appearance.color.selected : &conf_core.appearance.color.subc); \ + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); \ + rnd_hid_set_line_width(pcb_draw_out.fgGC, -2); \ + rnd_render->draw_line(pcb_draw_out.fgGC, cx-radius, cy-radius, cx+radius, cy+radius); \ + rnd_render->draw_line(pcb_draw_out.fgGC, cx+radius, cy-radius, cx-radius, cy+radius); \ +} while(0) + +#define pcb_obj_editpont_setup() \ +do { \ + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.subc); \ + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); \ + rnd_hid_set_line_width(pcb_draw_out.fgGC, -2); \ +} while(0) + +#define pcb_obj_editpont_cross(x, y) \ +do { \ + static const rnd_coord_t radius = RND_MM_TO_COORD(0.2); \ + rnd_render->draw_line(pcb_draw_out.fgGC, (x)-radius, (y), (x)+radius, (y)); \ + rnd_render->draw_line(pcb_draw_out.fgGC, (x), (y)-radius, (x), (y)+radius); \ +} while(0) + + +#define pcb_hidden_floater(obj,info) ((info)->xform->hide_floaters && PCB_FLAG_TEST(PCB_FLAG_FLOATER, (obj))) +#define pcb_hidden_floater_gui(obj) (conf_core.editor.hide_names && PCB_FLAG_TEST(PCB_FLAG_FLOATER, (obj))) +#define pcb_partial_export(obj,info) (((info)->xform != NULL) && (info)->xform->partial_export && (!PCB_FLAG_TEST(PCB_FLAG_EXPORTSEL, (obj)))) + +/* Returns whether a subc part object is editable (not under the subc lock) */ +#define pcb_subc_part_editable(pcb, obj) \ + (((pcb)->loose_subc) || ((obj)->term != NULL) || PCB_FLAG_TEST(PCB_FLAG_FLOATER, (obj))) + +/* set const char *dst to a color, depending on the bound layer type: + top silk and copper get the color of the first crresponding layer + from current PCB, the rest get the far-side color; + set the selected color if sel is true. + NOTE: caller needs to make sure sel is 0 in case of xform->flag_colors == 0 */ +#define PCB_OBJ_COLOR_ON_BOUND_LAYER(dst, layer, sel) \ +do { \ + if (layer->meta.bound.type & PCB_LYT_TOP) { \ + rnd_layer_id_t lid = -1; \ + pcb_layergrp_t *g; \ + rnd_layergrp_id_t grp = -1; \ + if (layer->meta.bound.type & PCB_LYT_SILK) { \ + if (sel) {\ + dst = &conf_core.appearance.color.selected; \ + } \ + else {\ + if (layer != NULL) { \ + pcb_layer_t *ly = pcb_layer_get_real(layer); \ + if (ly != NULL) \ + dst = &ly->meta.real.color; \ + else \ + dst = &conf_core.appearance.color.element; \ + } \ + else \ + dst = &conf_core.appearance.color.element; \ + } \ + break; \ + } \ + else if (layer->meta.bound.type & PCB_LYT_COPPER) \ + grp = pcb_layergrp_get_top_copper(); \ + g = pcb_get_layergrp(PCB, grp); \ + if ((g != NULL) && (g->len > 0)) \ + lid = g->lid[0]; \ + if ((lid >= 0) && (lid <= PCB_MAX_LAYER)) { \ + if (sel) \ + dst = &conf_core.appearance.color.selected; \ + else {\ + if (layer != NULL) { \ + pcb_layer_t *ly = pcb_layer_get_real(layer); \ + if (ly != NULL) \ + dst = &ly->meta.real.color; \ + else \ + dst = &conf_core.appearance.color.layer[lid]; \ + } \ + else \ + dst = &conf_core.appearance.color.layer[lid]; \ + } \ + break; \ + } \ + } \ + if (sel) \ + dst = &conf_core.appearance.color.selected; \ + else \ + dst = &conf_core.appearance.color.invisible_objects; \ +} while(0) + +/* check if an object has clearance to polygon */ +#define PCB_POLY_HAS_CLEARANCE(ply) \ + (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, (ply)) && ((ply)->Clearance != 0)) + +#define PCB_NONPOLY_HAS_CLEARANCE(obj) \ + (PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, (obj)) && ((obj)->Clearance != 0)) + +#define PCB_OBJ_HAS_CLEARANCE(obj) \ + ( \ + ((obj)->type == PCB_OBJ_POLY) ? \ + PCB_POLY_HAS_CLEARANCE(obj) : PCB_NONPOLY_HAS_CLEARANCE(obj) \ + ) + +#define PCB_HAS_COLOROVERRIDE(obj) ((obj)->override_color != NULL) + +/* a pointer is created from index addressing because the base pointer + * may change when new memory is allocated; + * + * all data is relative to an objects name 'top' which can be either + * PCB or PasteBuffer */ +#define PCB_END_LOOP }} while (0) +#define PCB_ENDALL_LOOP }} while (0); }} while(0) + +#endif Index: tags/2.3.0/src/obj_gfx.c =================================================================== --- tags/2.3.0/src/obj_gfx.c (nonexistent) +++ tags/2.3.0/src/obj_gfx.c (revision 33253) @@ -0,0 +1,975 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Drawing primitive: custom graphics (e.g. pixmap) */ + + +#include "config.h" + +#include +#include +#include + + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "rotate.h" +#include "move.h" +#include "conf_core.h" +#include "draw_wireframe.h" +#include "pixmap_pcb.h" + +#include "obj_gfx.h" +#include "obj_gfx_op.h" + +#include "obj_subc_parent.h" +#include "obj_hash.h" + +/* TODO: could be removed if draw.c could be split up */ +#include "draw.h" +#include "obj_gfx_draw.h" + + +void pcb_gfx_reg(pcb_layer_t *layer, pcb_gfx_t *gfx) +{ + gfxlist_append(&layer->Gfx, gfx); + PCB_SET_PARENT(gfx, layer, layer); + + if (layer->parent_type == PCB_PARENT_UI) + return; + + if (layer->parent_type == PCB_PARENT_DATA) + pcb_obj_id_reg(layer->parent.data, gfx); +} + +void pcb_gfx_unreg(pcb_gfx_t *gfx) +{ + pcb_layer_t *layer = gfx->parent.layer; + assert(gfx->parent_type == PCB_PARENT_LAYER); + gfxlist_remove(gfx); + if (layer->parent_type != PCB_PARENT_UI) { + assert(layer->parent_type == PCB_PARENT_DATA); + pcb_obj_id_del(layer->parent.data, gfx); + } + PCB_CLEAR_PARENT(gfx); +} + +pcb_gfx_t *pcb_gfx_alloc_id(pcb_layer_t *layer, long int id) +{ + pcb_gfx_t *new_obj; + + new_obj = calloc(sizeof(pcb_gfx_t), 1); + new_obj->ID = id; + new_obj->type = PCB_OBJ_GFX; + new_obj->Attributes.post_change = pcb_obj_attrib_post_change; + + pcb_gfx_reg(layer, new_obj); + + return new_obj; +} + +pcb_gfx_t *pcb_gfx_alloc(pcb_layer_t *layer) +{ + return pcb_gfx_alloc_id(layer, pcb_create_ID_get()); +} + +/* computes the bounding box of a gfx */ +static rnd_box_t pcb_gfx_bbox_(const pcb_gfx_t *gfx) +{ + rnd_box_t res = {+RND_COORD_MAX, +RND_COORD_MAX, -RND_COORD_MAX, -RND_COORD_MAX}; + int n; + for(n = 0; n < 4; n++) + rnd_box_bump_point(&res, gfx->corner[n].X, gfx->corner[n].Y); + return res; +} + + +void pcb_gfx_bbox(pcb_gfx_t *gfx) +{ + gfx->bbox_naked = gfx->BoundingBox = pcb_gfx_bbox_(gfx); +} + +void pcb_gfx_update(pcb_gfx_t *gfx) +{ + int n; + double a, rx, ry, cosa, sina; + + rx = (double)gfx->sx / 2.0; + ry = (double)gfx->sy / 2.0; + + gfx->corner[0].X = rnd_round((double)gfx->cx + rx); gfx->corner[0].Y = rnd_round((double)gfx->cy + ry); + gfx->corner[1].X = rnd_round((double)gfx->cx - rx); gfx->corner[1].Y = rnd_round((double)gfx->cy + ry); + gfx->corner[2].X = rnd_round((double)gfx->cx - rx); gfx->corner[2].Y = rnd_round((double)gfx->cy - ry); + gfx->corner[3].X = rnd_round((double)gfx->cx + rx); gfx->corner[3].Y = rnd_round((double)gfx->cy - ry); + if (gfx->rot != 0.0) { + a = gfx->rot / RND_RAD_TO_DEG; + cosa = cos(a); + sina = sin(a); + for(n = 0; n < 4; n++) + rnd_rotate(&gfx->corner[n].X, &gfx->corner[n].Y, gfx->cx, gfx->cy, cosa, sina); + } + pcb_gfx_bbox(gfx); +} + +/* creates a new gfx on a layer */ +pcb_gfx_t *pcb_gfx_new(pcb_layer_t *layer, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t sx, rnd_coord_t sy, rnd_angle_t rot, pcb_flag_t Flags) +{ + pcb_gfx_t *gfx; + + gfx = pcb_gfx_alloc(layer); + if (!gfx) + return gfx; + + gfx->Flags = Flags; + gfx->cx = cx; + gfx->cy = cy; + gfx->sx = sx; + gfx->sy = sy; + gfx->rot = rot; + pcb_gfx_update(gfx); + pcb_add_gfx_on_layer(layer, gfx); + return gfx; +} + +static pcb_gfx_t *pcb_gfx_copy_meta(pcb_gfx_t *dst, pcb_gfx_t *src) +{ + if (dst == NULL) + return NULL; + pcb_attribute_copy_all(&dst->Attributes, &src->Attributes); + return dst; +} + +static void pcb_gfx_copy_data(pcb_gfx_t *dst, pcb_gfx_t *src) +{ + dst->rot = src->rot; + dst->xmirror = src->xmirror; + dst->ymirror = src->ymirror; + dst->pxm_id = src->pxm_id; + dst->pxm_neutral = src->pxm_neutral; + src->pxm_neutral->refco++; + dst->pxm_xformed = src->pxm_xformed; + src->pxm_xformed->refco++; + pcb_gfx_update(dst); +} + +pcb_gfx_t *pcb_gfx_dup_at(pcb_layer_t *dst, pcb_gfx_t *src, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_gfx_t *a = pcb_gfx_new(dst, src->cx+dx, src->cy+dy, src->sx, src->sy, src->rot, src->Flags); + pcb_gfx_copy_meta(a, src); + pcb_gfx_copy_data(a, src); + return a; +} + +pcb_gfx_t *pcb_gfx_dup(pcb_layer_t *dst, pcb_gfx_t *src) +{ + return pcb_gfx_dup_at(dst, src, 0, 0); +} + + +void pcb_add_gfx_on_layer(pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + pcb_gfx_bbox(gfx); + if (!Layer->gfx_tree) + Layer->gfx_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Layer->gfx_tree, (rnd_box_t *)gfx); + gfx->type = PCB_OBJ_GFX; + PCB_SET_PARENT(gfx, layer, Layer); +} + + + +void pcb_gfx_free(pcb_gfx_t *gfx) +{ + if ((gfx->parent.layer != NULL) && (gfx->parent.layer->gfx_tree != NULL)) + rnd_r_delete_entry(gfx->parent.layer->gfx_tree, (rnd_box_t *)gfx); + pcb_attribute_free(&gfx->Attributes); + pcb_gfx_unreg(gfx); + pcb_obj_common_free((pcb_any_obj_t *)gfx); + free(gfx); +} + + +int pcb_gfx_eq(const pcb_host_trans_t *tr1, const pcb_gfx_t *a1, const pcb_host_trans_t *tr2, const pcb_gfx_t *a2) +{ + double sgn1 = tr1->on_bottom ? -1 : +1; + double sgn2 = tr2->on_bottom ? -1 : +1; + + if (a1->sx != a2->sx) return 0; + if (a1->sy != a2->sy) return 0; + if (pcb_neq_tr_coords(tr1, a1->cx, a1->cy, tr2, a2->cx, a2->cy)) return 0; + if (rnd_normalize_angle(rnd_round(a1->rot * sgn1)) != rnd_normalize_angle(rnd_round(a2->rot * sgn2))) return 0; +TODO("compare pixmaps"); + return 1; +} + +unsigned int pcb_gfx_hash(const pcb_host_trans_t *tr, const pcb_gfx_t *a) +{ + unsigned int content = 0, crd = 0; + double sgn = tr->on_bottom ? -1 : +1; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, a)) { + rnd_coord_t x, y; + pcb_hash_tr_coords(tr, &x, &y, a->cx, a->cy); + crd = pcb_hash_coord(x) ^ pcb_hash_coord(y) ^ pcb_hash_coord(a->sx) ^ pcb_hash_coord(a->sy) ^ + pcb_hash_coord(rnd_normalize_angle(rnd_round(a->rot*sgn + tr->rot*sgn))); + } + +TODO("hash pixmaps"); + + return crd ^ content; +} + +void pcb_gfx_pre(pcb_gfx_t *gfx) +{ + pcb_layer_t *ly = pcb_layer_get_real(gfx->parent.layer); + if (ly == NULL) + return; + if (ly->gfx_tree != NULL) + rnd_r_delete_entry(ly->gfx_tree, (rnd_box_t *)gfx); +} + +void pcb_gfx_post(pcb_gfx_t *gfx) +{ + pcb_layer_t *ly = pcb_layer_get_real(gfx->parent.layer); + pcb_gfx_update(gfx); + if (ly == NULL) + return; + if (ly->gfx_tree != NULL) + rnd_r_insert_entry(ly->gfx_tree, (rnd_box_t *)gfx); +} + +/***** operations *****/ + +static const char core_gfx_cookie[] = "core-gfx"; + +typedef struct { + pcb_gfx_t *gfx; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + rnd_coord_t cx, cy, sx, sy; + rnd_angle_t rot; +} undo_gfx_geo_t; + +static int undo_gfx_geo_swap(void *udata) +{ + undo_gfx_geo_t *g = udata; + pcb_layer_t *layer = g->gfx->parent.layer; + + if (layer->gfx_tree != NULL) + rnd_r_delete_entry(layer->gfx_tree, (rnd_box_t *)g->gfx); + + rnd_swap(rnd_coord_t, g->cx, g->gfx->cx); + rnd_swap(rnd_coord_t, g->cy, g->gfx->cy); + rnd_swap(rnd_coord_t, g->sx, g->gfx->sx); + rnd_swap(rnd_coord_t, g->sy, g->gfx->sy); + rnd_swap(rnd_angle_t, g->rot, g->gfx->rot); + + if (g->rot != g->gfx->rot) + g->gfx->pxm_xformed = pcb_pixmap_alloc_insert_transformed(&pcb_pixmaps, g->gfx->pxm_neutral, g->gfx->rot, g->gfx->xmirror, g->gfx->ymirror); + + pcb_gfx_update(g->gfx); + pcb_gfx_bbox(g->gfx); + if (layer->gfx_tree != NULL) + rnd_r_insert_entry(layer->gfx_tree, (rnd_box_t *)g->gfx); + + return 0; +} + +static void undo_gfx_geo_print(void *udata, char *dst, size_t dst_len) +{ + rnd_snprintf(dst, dst_len, "gfx geo"); +} + +static const uundo_oper_t undo_gfx_geo = { + core_gfx_cookie, + NULL, + undo_gfx_geo_swap, + undo_gfx_geo_swap, + undo_gfx_geo_print +}; + +/* copies a gfx to buffer */ +void *pcb_gfxop_add_to_buffer(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + pcb_gfx_t *a; + rnd_layer_id_t lid = pcb_layer_id(ctx->buffer.src, Layer); + pcb_layer_t *layer; + + /* the buffer may not have the specified layer, e.g. on loose subc subc-aux layer */ + if (lid == -1) + return NULL; + + layer = &ctx->buffer.dst->Layer[lid]; + a = pcb_gfx_new(layer, gfx->cx, gfx->cy, gfx->sx, gfx->sy, gfx->rot, + pcb_flag_mask(gfx->Flags, PCB_FLAG_FOUND | ctx->buffer.extraflg)); + + pcb_gfx_copy_meta(a, gfx); + pcb_gfx_copy_data(a, gfx); + if (ctx->buffer.keep_id) pcb_obj_change_id((pcb_any_obj_t *)a, gfx->ID); + return a; +} + +/* moves a gfx between board and buffer */ +void *pcb_gfxop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t *dstly, pcb_gfx_t *gfx) +{ + pcb_layer_t *srcly = gfx->parent.layer; + + assert(gfx->parent_type == PCB_PARENT_LAYER); + if ((dstly == NULL) || (dstly == srcly)) { /* auto layer in dst */ + rnd_layer_id_t lid = pcb_layer_id(ctx->buffer.src, srcly); + if (lid < 0) { + rnd_message(RND_MSG_ERROR, "Internal error: can't resolve source layer ID in pcb_gfxop_move_buffer\n"); + return NULL; + } + dstly = &ctx->buffer.dst->Layer[lid]; + } + + rnd_r_delete_entry(srcly->gfx_tree, (rnd_box_t *) gfx); + + pcb_gfx_unreg(gfx); + pcb_gfx_reg(dstly, gfx); + + PCB_FLAG_CLEAR(PCB_FLAG_FOUND, gfx); + + if (!dstly->gfx_tree) + dstly->gfx_tree = rnd_r_create_tree(); + rnd_r_insert_entry(dstly->gfx_tree, (rnd_box_t *) gfx); + + return gfx; +} + +/* copies a gfx */ +void *pcb_gfxop_copy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + pcb_gfx_t *ngfx; + + ngfx = pcb_gfx_new(Layer, gfx->cx + ctx->copy.DeltaX, gfx->cy + ctx->copy.DeltaY, + gfx->sx, gfx->sy, gfx->rot, pcb_flag_mask(gfx->Flags, PCB_FLAG_FOUND)); + if (ngfx == NULL) + return NULL; + if (ctx->copy.keep_id) + ngfx->ID = gfx->ID; + pcb_gfx_copy_meta(ngfx, gfx); + pcb_gfx_copy_data(ngfx, gfx); + pcb_gfx_invalidate_draw(Layer, ngfx); + pcb_undo_add_obj_to_create(PCB_OBJ_GFX, Layer, ngfx, ngfx); + return ngfx; +} + + +#define pcb_gfx_move(g,dx,dy) \ + do { \ + rnd_coord_t __dx__ = (dx), __dy__ = (dy); \ + pcb_gfx_t *__g__ = (g); \ + RND_MOVE_POINT((__g__)->cx, (__g__)->cy,__dx__,__dy__); \ + RND_BOX_MOVE_LOWLEVEL(&((__g__)->BoundingBox),__dx__,__dy__); \ + RND_BOX_MOVE_LOWLEVEL(&((__g__)->bbox_naked),__dx__,__dy__); \ + pcb_gfx_update(__g__); \ + } while(0) + +void *pcb_gfxop_move_noclip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + if (Layer->meta.real.vis) { + pcb_gfx_invalidate_erase(gfx); + pcb_gfx_move(gfx, ctx->move.dx, ctx->move.dy); + pcb_gfx_invalidate_draw(Layer, gfx); + } + else { + pcb_gfx_move(gfx, ctx->move.dx, ctx->move.dy); + } + return gfx; +} + +void *pcb_gfxop_move(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + rnd_r_delete_entry(Layer->gfx_tree, (rnd_box_t *)gfx); + pcb_gfxop_move_noclip(ctx, Layer, gfx); + rnd_r_insert_entry(Layer->gfx_tree, (rnd_box_t *)gfx); + return gfx; +} + +/* moves a gfx between layers; lowlevel routines */ +void *pcb_gfxop_move_to_layer_low(pcb_opctx_t *ctx, pcb_layer_t * Source, pcb_gfx_t * gfx, pcb_layer_t * Destination) +{ + rnd_r_delete_entry(Source->gfx_tree, (rnd_box_t *)gfx); + + pcb_gfx_unreg(gfx); + pcb_gfx_reg(Destination, gfx); + + if (!Destination->gfx_tree) + Destination->gfx_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Destination->gfx_tree, (rnd_box_t *)gfx); + + return gfx; +} + + +/* moves a gfx between layers */ +void *pcb_gfxop_move_to_layer(pcb_opctx_t *ctx, pcb_layer_t * Layer, pcb_gfx_t * gfx) +{ + pcb_gfx_t *newone; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, gfx)) { + rnd_message(RND_MSG_WARNING, "Sorry, gfx object is locked\n"); + return NULL; + } + if (ctx->move.dst_layer == Layer && Layer->meta.real.vis) + pcb_gfx_invalidate_draw(Layer, gfx); + if (ctx->move.dst_layer == Layer) + return gfx; + pcb_undo_add_obj_to_move_to_layer(PCB_OBJ_GFX, Layer, gfx, gfx); + if (Layer->meta.real.vis) + pcb_gfx_invalidate_erase(gfx); + newone = (pcb_gfx_t *) pcb_gfxop_move_to_layer_low(ctx, Layer, gfx, ctx->move.dst_layer); + if (ctx->move.dst_layer->meta.real.vis) + pcb_gfx_invalidate_draw(ctx->move.dst_layer, newone); + return newone; +} + +/* destroys a gfx from a layer */ +void *pcb_gfxop_destroy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + rnd_r_delete_entry(Layer->gfx_tree, (rnd_box_t *) gfx); + + pcb_gfx_free(gfx); + return NULL; +} + +/* removes a gfx from a layer */ +void *pcb_gfxop_remove(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + /* erase from screen */ + if (Layer->meta.real.vis) + pcb_gfx_invalidate_erase(gfx); + pcb_undo_move_obj_to_remove(PCB_OBJ_GFX, Layer, gfx, gfx); + return NULL; +} + +void *pcb_gfx_destroy(pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + void *res; + pcb_opctx_t ctx; + + ctx.remove.pcb = PCB; + ctx.remove.destroy_target = NULL; + + res = pcb_gfxop_remove(&ctx, Layer, gfx); + pcb_draw(); + return res; +} + +/* rotates a gfx */ +void pcb_gfx_rotate90(pcb_gfx_t *gfx, rnd_coord_t X, rnd_coord_t Y, unsigned Number) +{ + gfx->rot = rnd_normalize_angle(gfx->rot + Number * 90); + TODO("rotate content") + pcb_gfx_update(gfx); + pcb_gfx_bbox(gfx); +} + +void pcb_gfx_rotate(pcb_layer_t *layer, pcb_gfx_t *gfx, rnd_coord_t X, rnd_coord_t Y, double cosa, double sina, rnd_angle_t angle) +{ + if (layer->gfx_tree != NULL) + rnd_r_delete_entry(layer->gfx_tree, (rnd_box_t *) gfx); + + gfx->rot = rnd_normalize_angle(gfx->rot + angle); + TODO("rotate content") + pcb_gfx_update(gfx); + pcb_gfx_bbox(gfx); + + if (layer->gfx_tree != NULL) + rnd_r_insert_entry(layer->gfx_tree, (rnd_box_t *) gfx); +} + +void pcb_gfx_mirror(pcb_gfx_t *gfx, rnd_coord_t y_offs, rnd_bool undoable) +{ + undo_gfx_geo_t gtmp, *g = >mp; + + if (undoable) g = pcb_undo_alloc(pcb_data_get_top(gfx->parent.layer->parent.data), &undo_gfx_geo, sizeof(undo_gfx_geo_t)); + + g->gfx = gfx; + g->cx = gfx->cx; + g->cy = gfx->cy; + g->sx = gfx->sx; + g->sy = gfx->sy; + g->rot = gfx->rot; +TODO("implement a mirror bit") + + undo_gfx_geo_swap(g); + if (undoable) pcb_undo_inc_serial(); +} + +void pcb_gfx_flip_side(pcb_layer_t *layer, pcb_gfx_t *gfx) +{ + rnd_r_delete_entry(layer->gfx_tree, (rnd_box_t *)gfx); + gfx->cx = PCB_SWAP_X(gfx->cx); + gfx->cy = PCB_SWAP_Y(gfx->cy); + gfx->rot = RND_SWAP_ANGLE(gfx->rot); + pcb_gfx_update(gfx); + pcb_gfx_bbox(gfx); + rnd_r_insert_entry(layer->gfx_tree, (rnd_box_t *)gfx); +} + +void pcb_gfx_chg_geo(pcb_gfx_t *gfx, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t sx, rnd_coord_t sy, rnd_angle_t rot, rnd_bool undoable) +{ + undo_gfx_geo_t gtmp, *g = >mp; + + if (undoable) g = pcb_undo_alloc(pcb_data_get_top(gfx->parent.layer->parent.data), &undo_gfx_geo, sizeof(undo_gfx_geo_t)); + + g->gfx = gfx; + g->cx = cx; + g->cy = cy; + g->sx = sx; + g->sy = sy; + g->rot = rot; + + undo_gfx_geo_swap(g); + if (undoable) pcb_undo_inc_serial(); +} + +void pcb_gfx_scale(pcb_gfx_t *gfx, double sx, double sy, double sth) +{ + int onbrd = (gfx->parent.layer != NULL) && (!gfx->parent.layer->is_bound); + + if (onbrd) + pcb_gfx_pre(gfx); + + if (sx != 1.0) gfx->sx = rnd_round((double)gfx->sx * sx); + if (sy != 1.0) gfx->sy = rnd_round((double)gfx->sy * sy); + + pcb_gfx_bbox(gfx); + if (onbrd) + pcb_gfx_post(gfx); + else + pcb_gfx_update(gfx); +} + +/* rotates a gfx */ +void *pcb_gfxop_rotate90(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + pcb_gfx_invalidate_erase(gfx); + if (Layer->gfx_tree != NULL) + rnd_r_delete_entry(Layer->gfx_tree, (rnd_box_t *) gfx); + pcb_gfx_rotate90(gfx, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.number); + if (Layer->gfx_tree != NULL) + rnd_r_insert_entry(Layer->gfx_tree, (rnd_box_t *) gfx); + pcb_gfx_invalidate_draw(Layer, gfx); + return gfx; +} + +void *pcb_gfxop_rotate(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + pcb_gfx_invalidate_erase(gfx); + pcb_gfx_rotate(Layer, gfx, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.cosa, ctx->rotate.sina, ctx->rotate.angle); + pcb_gfx_invalidate_draw(Layer, gfx); + return gfx; +} + +void *pcb_gfxop_change_flag(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + static pcb_flag_values_t pcb_gfx_flags = 0; + if (pcb_gfx_flags == 0) + pcb_gfx_flags = pcb_obj_valid_flags(PCB_OBJ_GFX); + + if ((ctx->chgflag.flag & pcb_gfx_flags) != ctx->chgflag.flag) + return NULL; + if ((ctx->chgflag.flag & PCB_FLAG_TERMNAME) && (gfx->term == NULL)) + return NULL; + pcb_undo_add_obj_to_flag(gfx); + + PCB_FLAG_CHANGE(ctx->chgflag.how, ctx->chgflag.flag, gfx); + + pcb_gfx_update(gfx); + return gfx; +} + +void *pcb_gfxop_invalidate_label(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_gfx_t *gfx) +{ + pcb_gfx_name_invalidate_draw(gfx); + return gfx; +} + +void pcb_gfx_set_pixmap_free(pcb_gfx_t *gfx, rnd_pixmap_t *pxm, rnd_bool undoable) +{ + TODO("gfx: undoable pixmap assign"); + gfx->pxm_neutral = pcb_pixmap_insert_neutral_or_free(&pcb_pixmaps, pxm); + gfx->pxm_xformed = pcb_pixmap_alloc_insert_transformed(&pcb_pixmaps, gfx->pxm_neutral, gfx->rot, gfx->xmirror, gfx->ymirror); + gfx->pxm_id = 0; /* no preference on the ID now */ +} + +void pcb_gfx_set_pixmap_dup(pcb_gfx_t *gfx, const rnd_pixmap_t *pxm, rnd_bool undoable) +{ + TODO("gfx: undoable pixmap assign"); + gfx->pxm_neutral = pcb_pixmap_insert_neutral_dup(&PCB->hidlib, &pcb_pixmaps, pxm); + gfx->pxm_xformed = pcb_pixmap_alloc_insert_transformed(&pcb_pixmaps, gfx->pxm_neutral, gfx->rot, gfx->xmirror, gfx->ymirror); + gfx->pxm_id = 0; /* no preference on the ID now */ +} + +void pcb_gfx_resize_move_corner(pcb_gfx_t *gfx, int corn_idx, rnd_coord_t dx, rnd_coord_t dy, int undoable) +{ + rnd_point_t *corn; + double sgnx, sgny; + undo_gfx_geo_t gtmp, *g = >mp; + rnd_coord_t nsx, nsy; + + if ((corn_idx < 0) || (corn_idx > 3)) + return; + corn = &gfx->corner[corn_idx]; + + sgnx = corn->X > gfx->cx ? 1 : -1; + sgny = corn->Y > gfx->cy ? 1 : -1; + + nsx = gfx->sx + dx * sgnx; + nsy = gfx->sy + dy * sgny; + + if ((nsx < 128) || (nsy < 128)) { + rnd_message(RND_MSG_ERROR, "Invalid gfx size\n"); + return; + } + + if (undoable) g = pcb_undo_alloc(pcb_data_get_top(gfx->parent.layer->parent.data), &undo_gfx_geo, sizeof(undo_gfx_geo_t)); + + g->gfx = gfx; + g->cx = gfx->cx + rnd_round((double)dx / 2.0);; + g->cy = gfx->cy + rnd_round((double)dy / 2.0);; + g->sx = nsx; + g->sy = nsy; + g->rot = gfx->rot; + + undo_gfx_geo_swap(g); + if (undoable) pcb_undo_inc_serial(); + +/* rnd_trace("pcb_gfx_resize_move_corner pt %d %mm;%mm %.0f;%.0f!\n", corn_idx, dx, dy, sgnx, sgny); */ +} + +int gfx_screen2pixmap_coord(pcb_gfx_t *gfx, rnd_coord_t x, rnd_coord_t y, long *px, long *py) +{ + rnd_coord_t dx = x - gfx->cx, dy = y - gfx->cy; + + if (gfx->pxm_neutral == NULL) + return -1; + + rnd_rotate(&dx, &dy, 0, 0, cos(-gfx->rot / RND_RAD_TO_DEG), sin(-gfx->rot / RND_RAD_TO_DEG)); + *px = floor((double)dx / (double)gfx->sx * (double)gfx->pxm_neutral->sx + (double)gfx->pxm_neutral->sx/2.0); + *py = floor((double)dy / (double)gfx->sy * (double)gfx->pxm_neutral->sy + (double)gfx->pxm_neutral->sy/2.0); + + if ((*px < 0) || (*px >= gfx->pxm_neutral->sx) || (*py < 0) || (*py >= gfx->pxm_neutral->sy)) + return -1; + + return 0; +} + +int gfx_set_resize_by_pixel_dist(pcb_gfx_t *gfx, long pdx, long pdy, rnd_coord_t len, rnd_bool allow_x, rnd_bool allow_y, rnd_bool undoable) +{ + rnd_coord_t nsx = 0, nsy = 0; + + if (pdx < 10) allow_x = 0; + if (pdy < 10) allow_y = 0; + + if ((allow_x == 0) && (allow_y == 0)) + return -1; + + if (gfx->pxm_neutral == NULL) + return -1; + +/*rnd_trace("resize1: %mm %mm (%d %d)\n", gfx->sx, gfx->sy, pdx, pdy);*/ + if (allow_x) { + double lenx = cos(-gfx->rot / RND_RAD_TO_DEG) * (double)len; + double sc = lenx / (double)pdx; + nsx = gfx->pxm_neutral->sx * sc; + } + + if (allow_y) { + double leny = sin((90-gfx->rot) / RND_RAD_TO_DEG) * (double)len; + double sc = leny / (double)pdy; + nsy = gfx->pxm_neutral->sy * sc; + } + + if ((nsx > 0) || (nsy > 0)) { + if (nsx <= 0) nsx = gfx->sx; + if (nsy <= 0) nsy = gfx->sy; + pcb_gfx_chg_geo(gfx, gfx->cx, gfx->cy, nsx, nsy, gfx->rot, undoable); + } + +/*rnd_trace("resize2: %mm %mm\n", gfx->sx, gfx->sy);*/ + return 0; +} + +void gfx_set_resize_gui(rnd_hidlib_t *hl, pcb_gfx_t *gfx, rnd_bool allow_x, rnd_bool allow_y) +{ + char *lens; + rnd_coord_t x1, y1, x2, y2; + long px1, py1, px2, py2; + double len; + int dirs; + rnd_bool succ; + static const char *msg[4] = { + NULL, + "horizontal distance of these two points", + "vertical distance of these two points", + "distance distance of these two points", + }; + + dirs = ((int)allow_y) << 1 | (int)allow_x; + if (dirs == 0) { + rnd_message(RND_MSG_ERROR, "Invalid direction restriction: either allow_x or allow_y should be 1\n"); + return; + } + + if (gfx->pxm_neutral == NULL) { + rnd_message(RND_MSG_ERROR, "Missing pixmap\n"); + return; + } + + rnd_hid_get_coords("Click the first point", &x1, &y1, 1); + rnd_hid_get_coords("Click the second point", &x2, &y2, 1); + if ((gfx_screen2pixmap_coord(gfx, x1, y1, &px1, &py1) != 0) || (gfx_screen2pixmap_coord(gfx, x2, y2, &px2, &py2) != 0)) { + rnd_message(RND_MSG_ERROR, "No pixmap available for this gfx objet or clicked outside of the pixmap\n"); + return; + } + + lens = rnd_hid_prompt_for(hl, msg[dirs], "0", "distance"); + if (lens == NULL) + return; + + len = rnd_get_value(lens, NULL, NULL, &succ); + if (succ) + gfx_set_resize_by_pixel_dist(gfx, px2-px1, py2-py1, len, allow_x, allow_y, 1); + free(lens); +} + + +/*** undoable transparent color set ***/ +typedef struct { + pcb_gfx_t *gfx; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + unsigned char tr, tg, tb; + unsigned char has_transp, transp_valid; +} undo_gfx_transp_t; + +static int undo_gfx_transp_swap(void *udata) +{ + undo_gfx_transp_t *g = udata; + pcb_gfx_t *gfx = g->gfx; + + if (gfx->pxm_neutral == NULL) + return -1; + + rnd_swap(unsigned char, gfx->pxm_xformed->tr, g->tr); + rnd_swap(unsigned char, gfx->pxm_xformed->tg, g->tg); + rnd_swap(unsigned char, gfx->pxm_xformed->tb, g->tb); + rnd_swap(unsigned char, gfx->pxm_xformed->has_transp, g->has_transp); + rnd_swap(unsigned char, gfx->pxm_xformed->transp_valid, g->transp_valid); + + gfx->pxm_neutral->tr = gfx->pxm_xformed->tr; + gfx->pxm_neutral->tg = gfx->pxm_xformed->tg; + gfx->pxm_neutral->tb = gfx->pxm_xformed->tb; + gfx->pxm_neutral->has_transp = gfx->pxm_xformed->has_transp; + gfx->pxm_neutral->transp_valid = gfx->pxm_xformed->transp_valid; + rnd_pixmap_free_hid_data(gfx->pxm_xformed); + + pcb_gfx_invalidate_draw(gfx->parent.layer, gfx); + pcb_draw(); + + return 0; +} + +static void undo_gfx_transp_print(void *udata, char *dst, size_t dst_len) +{ + undo_gfx_transp_t *g = udata; + rnd_snprintf(dst, dst_len, "gfx transp: %d %d #%02x%02x%02x", g->has_transp, g->transp_valid, g->tr, g->tg, g->tb); +} + +static const uundo_oper_t undo_gfx_transp = { + core_gfx_cookie, + NULL, + undo_gfx_transp_swap, + undo_gfx_transp_swap, + undo_gfx_transp_print +}; + +int gfx_set_transparent(pcb_gfx_t *gfx, unsigned char tr, unsigned char tg, unsigned char tb, int undoable) +{ + undo_gfx_transp_t gtmp, *g = >mp; + + if (gfx->pxm_neutral == NULL) + return -1; + + if (undoable) g = pcb_undo_alloc(pcb_data_get_top(gfx->parent.layer->parent.data), &undo_gfx_transp, sizeof(undo_gfx_transp_t)); + + g->gfx = gfx; + g->tr = tr; + g->tg = tg; + g->tb = tb; + g->has_transp = g->transp_valid = 1; + + undo_gfx_transp_swap(g); + if (undoable) pcb_undo_inc_serial(); + + return 0; +} + +int gfx_set_transparent_by_coord(pcb_gfx_t *gfx, long px, long py) +{ + unsigned char *t; + + if (gfx->pxm_neutral == NULL) + return -1; + + if ((px < 0) || (py < 0) || (px >= gfx->pxm_neutral->sx) || (py >= gfx->pxm_neutral->sy)) + return -1; + + t = gfx->pxm_neutral->p + (px + py * gfx->pxm_neutral->sx) * 3; + return gfx_set_transparent(gfx, t[0], t[1], t[2], 1); +} + +void gfx_set_transparent_gui(pcb_gfx_t *gfx) +{ + rnd_coord_t x, y; + long px, py; + unsigned char *t; + + rnd_hid_get_coords("Click on the pixel that should be transparent", &x, &y, 1); + + if (gfx_screen2pixmap_coord(gfx, x, y, &px, &py) != 0) { + rnd_message(RND_MSG_ERROR, "No pixmap available for this gfx objet or clicked outside of the pixmap\n"); + return; + } + + t = gfx->pxm_neutral->p + (px + py * gfx->pxm_neutral->sx) * 3; + + gfx_set_transparent(gfx, t[0], t[1], t[2], 1); +} + +/*** draw ***/ + +void pcb_gfx_name_invalidate_draw(pcb_gfx_t *gfx) +{ + /* ->term: can't be a terminal, no label to draw */ +} + +void pcb_gfx_draw_label(pcb_draw_info_t *info, pcb_gfx_t *gfx, rnd_bool vis_side) +{ + /* ->term: can't be a terminal, no label to draw */ + if (gfx->noexport && vis_side) + pcb_obj_noexport_mark(gfx, gfx->cx, gfx->cy); +} + +void pcb_gfx_draw_(pcb_draw_info_t *info, pcb_gfx_t *gfx, int allow_term_gfx) +{ + const pcb_layer_t *layer = info->layer != NULL ? info->layer : pcb_layer_get_real(gfx->parent.layer); + + PCB_DRAW_BBOX(gfx); + + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, gfx)) { + const rnd_color_t *color; + if (layer->is_bound) + PCB_OBJ_COLOR_ON_BOUND_LAYER(color, layer, 1); + else + color = &conf_core.appearance.color.selected; + + rnd_render->set_color(pcb_draw_out.fgGC, color); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); + rnd_hid_set_line_width(pcb_draw_out.fgGC, -2); + rnd_render->draw_line(pcb_draw_out.fgGC, gfx->corner[0].X, gfx->corner[0].Y, gfx->corner[1].X, gfx->corner[1].Y); + rnd_render->draw_line(pcb_draw_out.fgGC, gfx->corner[1].X, gfx->corner[1].Y, gfx->corner[2].X, gfx->corner[2].Y); + rnd_render->draw_line(pcb_draw_out.fgGC, gfx->corner[2].X, gfx->corner[2].Y, gfx->corner[3].X, gfx->corner[3].Y); + rnd_render->draw_line(pcb_draw_out.fgGC, gfx->corner[3].X, gfx->corner[3].Y, gfx->corner[0].X, gfx->corner[0].Y); + } + + + if ((gfx->pxm_neutral == NULL) || (rnd_render->draw_pixmap == NULL)) { + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.warn); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); + rnd_hid_set_line_width(pcb_draw_out.fgGC, RND_MM_TO_COORD(0.1)); + rnd_render->draw_line(pcb_draw_out.fgGC, gfx->corner[0].X, gfx->corner[0].Y, gfx->corner[2].X, gfx->corner[2].Y); + rnd_render->draw_line(pcb_draw_out.fgGC, gfx->corner[1].X, gfx->corner[1].Y, gfx->corner[3].X, gfx->corner[3].Y); + } + else { + rnd_render->draw_pixmap(rnd_render, gfx->cx, gfx->cy, gfx->sx, gfx->sy, gfx->pxm_xformed); + } +} + +void pcb_gfx_draw(pcb_draw_info_t *info, pcb_gfx_t *gfx, int allow_term_gfx) +{ + const pcb_layer_t *layer = info->layer != NULL ? info->layer : pcb_layer_get_real(gfx->parent.layer); + + pcb_obj_noexport(info, gfx, return); + + if (layer == NULL) /* if the layer is inbound, e.g. in preview, fall back using the layer recipe */ + layer = gfx->parent.layer; + + pcb_gfx_draw_(info, gfx, allow_term_gfx); +} + +RND_INLINE rnd_r_dir_t pcb_gfx_draw_callback_(pcb_gfx_t *gfx, void *cl) +{ + pcb_draw_info_t *info = cl; + + if (pcb_hidden_floater((pcb_any_obj_t*)gfx, info) || pcb_partial_export((pcb_any_obj_t*)gfx, info)) + return RND_R_DIR_FOUND_CONTINUE; + + if (!PCB->SubcPartsOn && pcb_lobj_parent_subc(gfx->parent_type, &gfx->parent)) + return RND_R_DIR_NOT_FOUND; + + pcb_gfx_draw(info, gfx, 0); + return RND_R_DIR_FOUND_CONTINUE; +} + +rnd_r_dir_t pcb_gfx_draw_under_callback(const rnd_box_t *b, void *cl) +{ + pcb_gfx_t *gfx = (pcb_gfx_t *)b; + if (!gfx->render_under) + return RND_R_DIR_FOUND_CONTINUE; + return pcb_gfx_draw_callback_(gfx, cl); +} + +rnd_r_dir_t pcb_gfx_draw_above_callback(const rnd_box_t *b, void *cl) +{ + pcb_gfx_t *gfx = (pcb_gfx_t *)b; + if (gfx->render_under) + return RND_R_DIR_FOUND_CONTINUE; + return pcb_gfx_draw_callback_(gfx, cl); +} + +/* erases a gfx on a layer */ +void pcb_gfx_invalidate_erase(pcb_gfx_t *gfx) +{ + pcb_draw_invalidate(gfx); + pcb_flag_erase(&gfx->Flags); +} + +void pcb_gfx_invalidate_draw(pcb_layer_t *Layer, pcb_gfx_t *gfx) +{ + pcb_draw_invalidate(gfx); +} + +void pcb_gfx_draw_xor(pcb_gfx_t *gfx, rnd_coord_t dx, rnd_coord_t dy) +{ + rnd_render->draw_line(pcb_crosshair.GC, gfx->corner[0].X+dx, gfx->corner[0].Y+dy, gfx->corner[1].X+dx, gfx->corner[1].Y+dy); + rnd_render->draw_line(pcb_crosshair.GC, gfx->corner[1].X+dx, gfx->corner[1].Y+dy, gfx->corner[2].X+dx, gfx->corner[2].Y+dy); + rnd_render->draw_line(pcb_crosshair.GC, gfx->corner[2].X+dx, gfx->corner[2].Y+dy, gfx->corner[3].X+dx, gfx->corner[3].Y+dy); + rnd_render->draw_line(pcb_crosshair.GC, gfx->corner[3].X+dx, gfx->corner[3].Y+dy, gfx->corner[0].X+dx, gfx->corner[0].Y+dy); +} Index: tags/2.3.0/src/obj_gfx.h =================================================================== --- tags/2.3.0/src/obj_gfx.h (nonexistent) +++ tags/2.3.0/src/obj_gfx.h (revision 33253) @@ -0,0 +1,149 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Drawing primitive: custom graphics (e.g. pixmap) */ + +#ifndef PCB_OBJ_GFX_H +#define PCB_OBJ_GFX_H + +#include +#include +#include "obj_common.h" + +struct pcb_gfx_s { /* holds information about gfxs */ + PCB_ANY_PRIMITIVE_FIELDS; + rnd_coord_t cx, cy; /* center coordinates */ + rnd_coord_t sx, sy; /* size x and y on board (net box size before rotation) */ + rnd_angle_t rot; + unsigned int xmirror:1, ymirror:1; + + long int pxm_id; /* preferred id for the pixmap (to preserve it on save/load) */ + + rnd_pixmap_t *pxm_neutral; /* graphics is a pixmap, if not NULL - in neutral scale/rot */ + rnd_pixmap_t *pxm_xformed; /* transformed version from the cache */ + + /* calculated/cached fields */ + unsigned int render_under:1; /* render under layer objects (default is 0=above) */ + rnd_point_t corner[4]; /* the 4 corners - has to be point so search.c can return it for the crosshair to edit */ + gdl_elem_t link; /* an gfx is in a list on a layer */ +}; + +/*** Memory ***/ +pcb_gfx_t *pcb_gfx_alloc(pcb_layer_t *); +pcb_gfx_t *pcb_gfx_alloc_id(pcb_layer_t *layer, long int id); +void pcb_gfx_free(pcb_gfx_t *data); + +pcb_gfx_t *pcb_gfx_new(pcb_layer_t *layer, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t sx, rnd_coord_t sy, rnd_angle_t rot, pcb_flag_t Flags); +pcb_gfx_t *pcb_gfx_dup(pcb_layer_t *dst, pcb_gfx_t *src); +pcb_gfx_t *pcb_gfx_dup_at(pcb_layer_t *dst, pcb_gfx_t *src, rnd_coord_t dx, rnd_coord_t dy); +void *pcb_gfx_destroy(pcb_layer_t *Layer, pcb_gfx_t *gfx); + +void pcb_gfx_reg(pcb_layer_t *layer, pcb_gfx_t *gfx); +void pcb_gfx_unreg(pcb_gfx_t *gfx); + +/* Add objects without creating them or making any "sanity modifications" to them */ +void pcb_add_gfx_on_layer(pcb_layer_t *layer, pcb_gfx_t *gfx); + + +/*** Utility ***/ +void pcb_gfx_update(pcb_gfx_t *gfx); /* update corner cache: call this after any geometry change */ +void pcb_gfx_bbox(pcb_gfx_t *gfx); +void pcb_gfx_rotate90(pcb_gfx_t *gfx, rnd_coord_t X, rnd_coord_t Y, unsigned Number); +void pcb_gfx_rotate(pcb_layer_t *layer, pcb_gfx_t *gfx, rnd_coord_t X, rnd_coord_t Y, double cosa, double sina, rnd_angle_t angle); +void pcb_gfx_mirror(pcb_gfx_t *gfx, rnd_coord_t y_offs, rnd_bool undoable); +void pcb_gfx_flip_side(pcb_layer_t *layer, pcb_gfx_t *gfx); +void pcb_gfx_scale(pcb_gfx_t *gfx, double sx, double sy, double sth); +void pcb_gfx_chg_geo(pcb_gfx_t *gfx, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t sx, rnd_coord_t sy, rnd_angle_t rot, rnd_bool undoable); + +/* assings pxm to gfx and free pxm (if needed) */ +void pcb_gfx_set_pixmap_free(pcb_gfx_t *gfx, rnd_pixmap_t *pxm, rnd_bool undoable); + +/* same but dups pxm so it is never free'd */ +void pcb_gfx_set_pixmap_dup(pcb_gfx_t *gfx, const rnd_pixmap_t *pxm, rnd_bool undoable); + +/* Request a resize by moving one of the corners relative, by dx;dy */ +void pcb_gfx_resize_move_corner(pcb_gfx_t *gfx, int corn_idx, rnd_coord_t dx, rnd_coord_t dy, int undoable); + +/* Change the transparent pixel value on the underlying pixmap */ +int gfx_set_transparent(pcb_gfx_t *gfx, unsigned char tr, unsigned char tg, unsigned char tb, int undoable); +int gfx_set_transparent_by_coord(pcb_gfx_t *gfx, long px, long py); +void gfx_set_transparent_gui(pcb_gfx_t *gfx); + +/* Resize the image by a pair of screen coords and an expected size; if allow_x + or allow_y is zero, ignore the component in that direction (intrepreted on + the rotated image) */ +int gfx_set_resize_by_pixel_dist(pcb_gfx_t *gfx, long pdx, long pdy, rnd_coord_t len, rnd_bool allow_x, rnd_bool allow_y, rnd_bool undoable); +void gfx_set_resize_gui(rnd_hidlib_t *hl, pcb_gfx_t *gfx, rnd_bool allow_x, rnd_bool allow_y); + + +/*** hash and eq ***/ +int pcb_gfx_eq(const pcb_host_trans_t *tr1, const pcb_gfx_t *g1, const pcb_host_trans_t *tr2, const pcb_gfx_t *g2); +unsigned int pcb_gfx_hash(const pcb_host_trans_t *tr, const pcb_gfx_t *g); + +/* un-administrate a gfx; call before changing geometry */ +void pcb_gfx_pre(pcb_gfx_t *gfx); + +/* re-administrate a gfx; call after changing geometry */ +void pcb_gfx_post(pcb_gfx_t *gfx); + +#define PCB_GFX_LOOP(element) do { \ + pcb_gfx_t *gfx; \ + gdl_iterator_t __it__; \ + linelist_foreach(&(element)->Gfx, &__it__, gfx) { + +#define PCB_GFX_ALL_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l =0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + PCB_GFX_LOOP(layer) + +#define PCB_GFX_COPPER_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l =0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (!(pcb_layer_flags(PCB, l) & PCB_LYT_COPPER)) continue; \ + PCB_GFX_LOOP(layer) + +#define PCB_GFX_SILK_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (!(pcb_layer_flags(PCB, l) & PCB_LYT_SILK)) continue; \ + PCB_GFX_LOOP(layer) + +#define PCB_GFX_VISIBLE_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (layer->meta.real.vis) \ + PCB_GFX_LOOP(layer) + +#endif Index: tags/2.3.0/src/obj_gfx_draw.h =================================================================== --- tags/2.3.0/src/obj_gfx_draw.h (nonexistent) +++ tags/2.3.0/src/obj_gfx_draw.h (revision 33253) @@ -0,0 +1,45 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard draw of gfxs ***/ + +#include "draw.h" + +/* Include rtree.h for this */ +#ifdef RND_RTREE_H +rnd_r_dir_t pcb_gfx_draw_under_callback(const rnd_box_t * b, void *cl); +rnd_r_dir_t pcb_gfx_draw_above_callback(const rnd_box_t * b, void *cl); +#endif + +void pcb_gfx_draw_(pcb_draw_info_t *info, pcb_gfx_t *gfx, int allow_term_gfx); +void pcb_gfx_draw(pcb_draw_info_t *info, pcb_gfx_t *gfx, int allow_term_gfx); +void pcb_gfx_invalidate_erase(pcb_gfx_t *gfx); +void pcb_gfx_invalidate_draw(pcb_layer_t *Layer, pcb_gfx_t *gfx); +void pcb_gfx_name_invalidate_draw(pcb_gfx_t *gfx); +void pcb_gfx_draw_label(pcb_draw_info_t *info, pcb_gfx_t *gfx, rnd_bool vis_side); + +void pcb_gfx_draw_xor(pcb_gfx_t *gfx, rnd_coord_t x, rnd_coord_t y); Index: tags/2.3.0/src/obj_gfx_list.c =================================================================== --- tags/2.3.0/src/obj_gfx_list.c (nonexistent) +++ tags/2.3.0/src/obj_gfx_list.c (revision 33253) @@ -0,0 +1,29 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#define TDL_DONT_UNDEF +#include "obj_gfx_list.h" +#include Index: tags/2.3.0/src/obj_gfx_list.h =================================================================== --- tags/2.3.0/src/obj_gfx_list.h (nonexistent) +++ tags/2.3.0/src/obj_gfx_list.h (revision 33253) @@ -0,0 +1,48 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_GFX_LIST_H +#define PCB_OBJ_GFX_LIST_H + +#include "obj_common.h" +#include "obj_gfx.h" + +/* List of gfxs */ +#define TDL(x) gfxlist_ ## x +#define TDL_LIST_T gfxlist_t +#define TDL_ITEM_T pcb_gfx_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define gfxlist_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + + +#include +#include + +#endif Index: tags/2.3.0/src/obj_gfx_op.h =================================================================== --- tags/2.3.0/src/obj_gfx_op.h (nonexistent) +++ tags/2.3.0/src/obj_gfx_op.h (revision 33253) @@ -0,0 +1,47 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard operations on gfx ***/ + +#include "operation.h" + +void *pcb_gfxop_add_to_buffer(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx); +void *pcb_gfxop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_gfx_t *gfx); +void *pcb_gfxop_copy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx); +void *pcb_gfxop_move(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx); +void *pcb_gfxop_move_noclip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx); +void *pcb_gfxop_move_to_layer_low(pcb_opctx_t *ctx, pcb_layer_t * Source, pcb_gfx_t * gfx, pcb_layer_t * Destination); +void *pcb_gfxop_move_to_layer(pcb_opctx_t *ctx, pcb_layer_t * Layer, pcb_gfx_t * gfx); +void *pcb_gfxop_destroy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx); +void *pcb_gfxop_remove(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx); +void *pcb_gfxop_rotate90(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx); +void *pcb_gfxop_rotate(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx); +void *pcb_gfxop_change_flag(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_gfx_t *gfx); +void *pcb_gfxop_invalidate_label(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_gfx_t *gfx); + + + Index: tags/2.3.0/src/obj_hash.h =================================================================== --- tags/2.3.0/src/obj_hash.h (nonexistent) +++ tags/2.3.0/src/obj_hash.h (revision 33253) @@ -0,0 +1,105 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017, 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include + +/* compare two strings and return 0 if they are equal. NULL == NULL means equal. */ +RND_INLINE int pcb_neqs(const char *s1, const char *s2) +{ + if ((s1 == NULL) && (s2 == NULL)) return 0; + if ((s1 == NULL) || (s2 == NULL)) return 1; + return strcmp(s1, s2) != 0; +} + +RND_INLINE unsigned pcb_hash_coord(rnd_coord_t c) +{ + return murmurhash(&(c), sizeof(rnd_coord_t)); +} + +/* cheat: round with a tolerance of a few nanometers to overcome the usual + +-1 nanometer rounding error */ +RND_INLINE rnd_coord_t pcb_round_tol(double v, int tol) +{ + return rnd_round(v/(double)tol)*tol; +} + +RND_INLINE void pcb_hash_tr_coords(const pcb_host_trans_t *tr, rnd_coord_t *dstx, rnd_coord_t *dsty, rnd_coord_t srcx, rnd_coord_t srcy) +{ + rnd_coord_t px, py; + + px = srcx + tr->ox; + py = srcy + tr->oy; + + if ((tr->rot == 0.0) && (!tr->on_bottom)) { + *dstx = px; + *dsty = py; + } + else { + double x, y; + x = (double)px * tr->cosa + (double)py * tr->sina; + y = (double)py * tr->cosa - (double)px * tr->sina; + if (tr->on_bottom) y = -(y); + + *dstx = pcb_round_tol(x, 4); + *dsty = pcb_round_tol(y, 4); + } +} + + +RND_INLINE unsigned pcb_hash_angle(const pcb_host_trans_t *tr, rnd_angle_t ang) +{ + long l; + ang = fmod(ang + tr->rot, 360.0); + ang *= 10000; + l = floor(ang); + return murmurhash(&l, sizeof(l)); +} + +RND_INLINE unsigned pcb_hash_scale(rnd_angle_t ang) +{ + long l; + ang *= 100000.0; + l = floor(ang); + return murmurhash(&l, sizeof(l)); +} + +#define pcb_hash_str(s) ((s) == NULL ? 0 : strhash(s)) + +/* compare two fields and return 0 if they are equal */ +#define pcb_field_neq(s1, s2, f) ((s1)->f != (s2)->f) + +/* retruns if two sets of tr;x;y mismatches */ +RND_INLINE rnd_bool pcb_neq_tr_coords(const pcb_host_trans_t *tr1, rnd_coord_t x1, rnd_coord_t y1, const pcb_host_trans_t *tr2, rnd_coord_t x2, rnd_coord_t y2) +{ + pcb_hash_tr_coords(tr1, &x1, &y1, x1, y1); + pcb_hash_tr_coords(tr2, &x2, &y2, x2, y2); + if (x1 != x2) return rnd_true; + if (y1 != y2) return rnd_true; + return rnd_false; +} + Index: tags/2.3.0/src/obj_line.c =================================================================== --- tags/2.3.0/src/obj_line.c (nonexistent) +++ tags/2.3.0/src/obj_line.c (revision 33253) @@ -0,0 +1,1510 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Drawing primitive: line segment */ + +#include "config.h" +#include + +#include "undo.h" +#include "board.h" +#include "data.h" +#include "move.h" +#include "search.h" +#include "polygon.h" +#include "conf_core.h" +#include "thermal.h" +#include +#include "rotate.h" +#include +#include + +#include "obj_line.h" +#include "obj_line_op.h" + +#include "obj_subc_parent.h" +#include "obj_hash.h" + +#include "draw_wireframe.h" +#include "obj_line_draw.h" +#include "obj_rat_draw.h" +#include "obj_pstk_draw.h" + +TODO("padstack: remove this when via is removed and the padstack is created from style directly") +#include "src_plugins/lib_compat_help/pstk_compat.h" + + +/**** allocation ****/ + +void pcb_line_reg(pcb_layer_t *layer, pcb_line_t *line) +{ + linelist_append(&layer->Line, line); + PCB_SET_PARENT(line, layer, layer); + + if (layer->parent_type == PCB_PARENT_UI) + return; + + if (layer->parent_type == PCB_PARENT_DATA) { + pcb_obj_id_reg(layer->parent.data, line); + pcb_obj_id_reg(layer->parent.data, &line->Point1); + pcb_obj_id_reg(layer->parent.data, &line->Point2); + } +} + +void pcb_line_unreg(pcb_line_t *line) +{ + pcb_layer_t *layer = line->parent.layer; + assert(line->parent_type == PCB_PARENT_LAYER); + linelist_remove(line); + if (layer->parent_type != PCB_PARENT_UI) { + assert(layer->parent_type == PCB_PARENT_DATA); + pcb_obj_id_del(layer->parent.data, line); + pcb_obj_id_del(layer->parent.data, &line->Point1); + pcb_obj_id_del(layer->parent.data, &line->Point2); + } + PCB_CLEAR_PARENT(line); +} + +pcb_line_t *pcb_line_alloc_id(pcb_layer_t *layer, long int id) +{ + pcb_line_t *new_obj; + + new_obj = calloc(sizeof(pcb_line_t), 1); + new_obj->ID = id; + new_obj->type = PCB_OBJ_LINE; + new_obj->Attributes.post_change = pcb_obj_attrib_post_change; + + pcb_line_reg(layer, new_obj); + + return new_obj; +} + +pcb_line_t *pcb_line_alloc(pcb_layer_t *layer) +{ + return pcb_line_alloc_id(layer, pcb_create_ID_get()); +} + +void pcb_line_free(pcb_line_t *line) +{ + if ((line->parent.layer != NULL) && (line->parent.layer->line_tree != NULL)) + rnd_r_delete_entry(line->parent.layer->line_tree, (rnd_box_t *)line); + pcb_attribute_free(&line->Attributes); + pcb_line_unreg(line); + pcb_obj_common_free((pcb_any_obj_t *)line); + free(line); +} + + +/**** utility ****/ + +static const char core_line_cookie[] = "core-line"; + +typedef struct { + pcb_line_t *line; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + rnd_coord_t Thickness, Clearance; + rnd_point_t Point1, Point2; +} undo_line_geo_t; + +static int undo_line_geo_swap(void *udata) +{ + undo_line_geo_t *g = udata; + pcb_layer_t *layer = g->line->parent.layer; + + if (layer->line_tree != NULL) + rnd_r_delete_entry(layer->line_tree, (rnd_box_t *)g->line); + pcb_poly_restore_to_poly(layer->parent.data, PCB_OBJ_LINE, layer, g->line); + + rnd_swap(rnd_point_t, g->Point1, g->line->Point1); + rnd_swap(rnd_point_t, g->Point2, g->line->Point2); + rnd_swap(rnd_coord_t, g->Thickness, g->line->Thickness); + rnd_swap(rnd_coord_t, g->Clearance, g->line->Clearance); + + pcb_line_bbox(g->line); + if (layer->line_tree != NULL) + rnd_r_insert_entry(layer->line_tree, (rnd_box_t *)g->line); + pcb_poly_clear_from_poly(layer->parent.data, PCB_OBJ_LINE, layer, g->line); + + return 0; +} + +static void undo_line_geo_print(void *udata, char *dst, size_t dst_len) +{ + rnd_snprintf(dst, dst_len, "line geo"); +} + +static const uundo_oper_t undo_line_geo = { + core_line_cookie, + NULL, + undo_line_geo_swap, + undo_line_geo_swap, + undo_line_geo_print +}; + + + +struct line_info { + pcb_line_t lin; + pcb_line_t modpts, *remove_line; /* if remove line is not NULL, remove that line and modify new line coords to modpts */ + unsigned skip_new:1; + jmp_buf env; +}; + +RND_INLINE pcb_line_merge_t can_merge_lines(const pcb_line_t *old_line, const pcb_line_t *new_line, pcb_line_t *out) +{ + int ov_n1o, ov_n2o, ov_o1n, ov_o2n; + pcb_line_t tmp; + + if (!conf_core.editor.trace_auto_merge) + return PCB_LINMER_NONE; + + /* do not merge to subc parts or terminals */ + if ((pcb_obj_parent_subc((pcb_any_obj_t *)old_line) != NULL) || (old_line->term != NULL)) + return PCB_LINMER_NONE; + + /* 100% match on endpoints */ + if (new_line->Point1.X == old_line->Point1.X && new_line->Point2.X == old_line->Point2.X && new_line->Point1.Y == old_line->Point1.Y && new_line->Point2.Y == old_line->Point2.Y) + return PCB_LINMER_SKIP; + + /* 100% match on endpoints - check the other point order */ + if (new_line->Point2.X == old_line->Point1.X && new_line->Point1.X == old_line->Point2.X && new_line->Point2.Y == old_line->Point1.Y && new_line->Point1.Y == old_line->Point2.Y) + return PCB_LINMER_SKIP; + + /* don't merge lines if the clear flags or clearance or thickness differ */ + if (old_line->Thickness != new_line->Thickness) + return PCB_LINMER_NONE; + + if (old_line->Clearance != new_line->Clearance) + return PCB_LINMER_NONE; + + if (PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, old_line) != PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, new_line)) + return PCB_LINMER_NONE; + + /*** matching endpoint ***/ + out->Thickness = 4; /* theoretical line for the on-point check should have small thicnkess - but leave some room for rouding errors */ + + /* remove unnecessary line points */ + if (old_line->Point1.X == new_line->Point1.X && old_line->Point1.Y == new_line->Point1.Y) { + out->Point1.X = old_line->Point2.X; + out->Point1.Y = old_line->Point2.Y; + out->Point2.X = new_line->Point2.X; + out->Point2.Y = new_line->Point2.Y; + if (pcb_is_point_on_line(new_line->Point1.X, new_line->Point1.Y, 1, out)) + return PCB_LINMER_REMPT; + return PCB_LINMER_NONE; + } + else if (old_line->Point2.X == new_line->Point1.X && old_line->Point2.Y == new_line->Point1.Y) { + out->Point1.X = old_line->Point1.X; + out->Point1.Y = old_line->Point1.Y; + out->Point2.X = new_line->Point2.X; + out->Point2.Y = new_line->Point2.Y; + if (pcb_is_point_on_line(new_line->Point1.X, new_line->Point1.Y, 1, out)) + return PCB_LINMER_REMPT; + return PCB_LINMER_NONE; + } + else if (old_line->Point1.X == new_line->Point2.X && old_line->Point1.Y == new_line->Point2.Y) { + out->Point1.X = old_line->Point2.X; + out->Point1.Y = old_line->Point2.Y; + out->Point2.X = new_line->Point1.X; + out->Point2.Y = new_line->Point1.Y; + if (pcb_is_point_on_line(new_line->Point2.X, new_line->Point2.Y, 1, out)) + return PCB_LINMER_REMPT; + return PCB_LINMER_NONE; + } + else if (old_line->Point2.X == new_line->Point2.X && old_line->Point2.Y == new_line->Point2.Y) { + out->Point1.X = old_line->Point1.X; + out->Point1.Y = old_line->Point1.Y; + out->Point2.X = new_line->Point1.X; + out->Point2.Y = new_line->Point1.Y; + if (pcb_is_point_on_line(new_line->Point2.X, new_line->Point2.Y, 1, out)) + return PCB_LINMER_REMPT; + return PCB_LINMER_NONE; + } + + /*** Partial overlap ***/ + + tmp = *old_line; + tmp.Thickness = 4; + ov_n1o = pcb_is_point_on_line(new_line->Point1.X, new_line->Point1.Y, 1, &tmp); + ov_n2o = pcb_is_point_on_line(new_line->Point2.X, new_line->Point2.Y, 1, &tmp); + + /* new line fully within old line */ + if (ov_n1o && ov_n2o) + return PCB_LINMER_SKIP; + + tmp = *new_line; + tmp.Thickness = 4; + ov_o1n = pcb_is_point_on_line(old_line->Point1.X, old_line->Point1.Y, 1, &tmp); + ov_o2n = pcb_is_point_on_line(old_line->Point2.X, old_line->Point2.Y, 1, &tmp); + + /* old line fully covered by the new line */ + if (ov_o1n && ov_o2n) { + *out = *new_line; + return PCB_LINMER_REMPT; + } + + /* common overlapping segment */ + if (ov_o1n && ov_n2o) { + out->Point1.X = old_line->Point2.X; + out->Point1.Y = old_line->Point2.Y; + out->Point2.X = new_line->Point1.X; + out->Point2.Y = new_line->Point1.Y; + return PCB_LINMER_REMPT; + } + + if (ov_o1n && ov_n1o) { + out->Point1.X = old_line->Point2.X; + out->Point1.Y = old_line->Point2.Y; + out->Point2.X = new_line->Point2.X; + out->Point2.Y = new_line->Point2.Y; + return PCB_LINMER_REMPT; + } + + if (ov_o2n && ov_n2o) { + out->Point1.X = old_line->Point1.X; + out->Point1.Y = old_line->Point1.Y; + out->Point2.X = new_line->Point1.X; + out->Point2.Y = new_line->Point1.Y; + return PCB_LINMER_REMPT; + } + + if (ov_o2n && ov_n1o) { + out->Point1.X = old_line->Point1.X; + out->Point1.Y = old_line->Point1.Y; + out->Point2.X = new_line->Point2.X; + out->Point2.Y = new_line->Point2.Y; + return PCB_LINMER_REMPT; + } + + + return PCB_LINMER_NONE; +} + +pcb_line_merge_t pcb_line_can_merge_lines(const pcb_line_t *old_line, const pcb_line_t *new_line, pcb_line_t *out) +{ + return can_merge_lines(old_line, new_line, out); +} + +static void maybe_move_line_pt(pcb_layer_t *layer, pcb_line_t *line, rnd_point_t *pt, rnd_point_t *new_loc) +{ + rnd_coord_t dx = new_loc->X - pt->X, dy = new_loc->Y - pt->Y; + if ((dx == 0) && (dy == 0)) + return; + pcb_move_obj(PCB_OBJ_LINE_POINT, layer, line, pt, dx, dy); +} + + +void pcb_line_mod_merge_inhibit_inc(pcb_board_t *pcb) +{ + if (pcb->line_mod_merge_inhibit > 8192) { + rnd_message(RND_MSG_ERROR, "internal error: pcb_line_mod_merge_inhibit_dec overflow\n"); + return; + } + pcb->line_mod_merge_inhibit++; +} + +void pcb_line_mod_merge_inhibit_dec(pcb_board_t *pcb) +{ + if (pcb->line_mod_merge_inhibit == 0) { + rnd_message(RND_MSG_ERROR, "internal error: pcb_line_mod_merge_inhibit_dec underflow\n"); + return; + } + pcb->line_mod_merge_inhibit--; + if (pcb->line_mod_merge_inhibit == 0) { + long n; + if (pcb->line_mod_merge == NULL) + return; + for(n = 0; n < pcb->line_mod_merge->used; n++) + if (pcb->line_mod_merge->array[n] != NULL) + pcb_line_mod_merge(pcb->line_mod_merge->array[n], 1); + pcb->line_mod_merge->used = 0; + } +} + +static void line_mod_merge_removed(pcb_board_t *pcb, pcb_line_t *line) +{ + long n; + if (pcb->line_mod_merge == NULL) + return; + for(n = 0; n < pcb->line_mod_merge->used; n++) { + if (pcb->line_mod_merge->array[n] == line) { + pcb->line_mod_merge->array[n] = NULL; + return; + } + } +} + +void pcb_line_mod_merge(pcb_line_t *line, rnd_bool undoable) +{ + pcb_layer_t *layer = line->parent.layer; + rnd_rtree_it_t it; + pcb_line_t *l2, *old_line, *new_line, out; + rnd_box_t search; + int retries = 16; + pcb_board_t *pcb; + + if (!conf_core.editor.trace_auto_merge) + return; + + pcb = pcb_data_get_top(line->parent.layer->parent.data); + if (pcb == NULL) + return; + + if (pcb->line_mod_merge_inhibit) { /* delay removal */ + long n; + if (pcb->line_mod_merge == NULL) + pcb->line_mod_merge = calloc(sizeof(vtp0_t), 1); + for(n = 0; n < pcb->line_mod_merge->used; n++) + if (pcb->line_mod_merge->array[n] == line) + return; + vtp0_append(pcb->line_mod_merge, line); + return; + } + + assert(undoable); /* non-undoable is not yet supported */ + + retry:; + if (retries-- == 0) + return; /* fallback: avoid infinite loop in any case */ + + search.X1 = MIN(line->Point1.X, line->Point2.X); + search.X2 = MAX(line->Point1.X, line->Point2.X); + search.Y1 = MIN(line->Point1.Y, line->Point2.Y); + search.Y2 = MAX(line->Point1.Y, line->Point2.Y); + if (search.Y2 == search.Y1) + search.Y2++; + if (search.X2 == search.X1) + search.X2++; + + for(l2 = rnd_rtree_first(&it, layer->line_tree, (rnd_rtree_box_t *)&search); l2 != NULL; l2 = rnd_rtree_next(&it)) { + pcb_line_merge_t res; + + if (line == l2) + continue; + + if (line->ID < l2->ID) { + old_line = line; + new_line = l2; + } + else { + old_line = l2; + new_line = line; + } + + res = can_merge_lines(old_line, new_line, &out); + switch(res) { + case PCB_LINMER_NONE: break; + case PCB_LINMER_REMPT: + pcb_undo_move_obj_to_remove(PCB_OBJ_LINE, layer, new_line, new_line); + line_mod_merge_removed(pcb, new_line); + maybe_move_line_pt(layer, old_line, &old_line->Point1, &out.Point1); + maybe_move_line_pt(layer, old_line, &old_line->Point2, &out.Point2); + line = old_line; + goto retry; + + case PCB_LINMER_SKIP: + pcb_undo_move_obj_to_remove(PCB_OBJ_LINE, layer, new_line, new_line); + line_mod_merge_removed(pcb, new_line); + break; + } + } +} + + +static rnd_r_dir_t line_callback(const rnd_box_t * b, void *cl) +{ + int res; + pcb_line_t *line = (pcb_line_t *) b; + struct line_info *i = (struct line_info *) cl; + + res = can_merge_lines(line, &i->lin, &i->modpts); + switch(res) { + case PCB_LINMER_NONE: return RND_R_DIR_NOT_FOUND; + case PCB_LINMER_REMPT: i->remove_line = line; longjmp(i->env, 1); break; + case PCB_LINMER_SKIP: i->skip_new = 1; longjmp(i->env, 1); break; + } + + return RND_R_DIR_NOT_FOUND; /* should't ever get here */ +} + + +/* creates a new line on a layer and checks for overlap and extension */ +pcb_line_t *pcb_line_new_merge(pcb_layer_t *Layer, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Thickness, rnd_coord_t Clearance, pcb_flag_t Flags) +{ + struct line_info info = {0}; + rnd_box_t search; + + if (!conf_core.editor.trace_auto_merge) + return pcb_line_new(Layer, X1, Y1, X2, Y2, Thickness, Clearance, Flags); + + search.X1 = MIN(X1, X2); + search.X2 = MAX(X1, X2); + search.Y1 = MIN(Y1, Y2); + search.Y2 = MAX(Y1, Y2); + if (search.Y2 == search.Y1) + search.Y2++; + if (search.X2 == search.X1) + search.X2++; + + info.lin.Point1.X = X1; + info.lin.Point2.X = X2; + info.lin.Point1.Y = Y1; + info.lin.Point2.Y = Y2; + info.lin.Thickness = Thickness; + info.lin.Clearance = Clearance; + info.lin.Flags = Flags; + + /* prevent stacking of duplicate lines + * and remove needless intermediate points + * verify that the layer is on the board first! + */ + if (setjmp(info.env) == 0) { + rnd_r_search(Layer->line_tree, &search, NULL, line_callback, &info, NULL); + return pcb_line_new(Layer, X1, Y1, X2, Y2, Thickness, Clearance, Flags); + } + + if (info.skip_new) + return NULL; /* skip creating the new line (e.g. stacked line) */ + + /* remove unnecessary points */ + if (info.remove_line) { + /* must do this BEFORE getting new line memory */ + pcb_undo_move_obj_to_remove(PCB_OBJ_LINE, Layer, info.remove_line, info.remove_line); + X1 = info.modpts.Point1.X; + X2 = info.modpts.Point2.X; + Y1 = info.modpts.Point1.Y; + Y2 = info.modpts.Point2.Y; + } + return pcb_line_new(Layer, X1, Y1, X2, Y2, Thickness, Clearance, Flags); +} + +pcb_line_t *pcb_line_new(pcb_layer_t *Layer, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Thickness, rnd_coord_t Clearance, pcb_flag_t Flags) +{ + pcb_line_t *Line; + + Line = pcb_line_alloc(Layer); + if (!Line) + return Line; + Line->Flags = Flags; + PCB_FLAG_CLEAR(PCB_FLAG_RAT, Line); + Line->Thickness = Thickness; + Line->Clearance = Clearance; + Line->Point1.X = X1; + Line->Point1.Y = Y1; + Line->Point1.ID = pcb_create_ID_get(); + Line->Point2.X = X2; + Line->Point2.Y = Y2; + Line->Point2.ID = pcb_create_ID_get(); + pcb_add_line_on_layer(Layer, Line); + return Line; +} + +static pcb_line_t *pcb_line_copy_meta(pcb_line_t *dst, pcb_line_t *src) +{ + if (dst == NULL) + return NULL; + pcb_attribute_copy_all(&dst->Attributes, &src->Attributes); + return dst; +} + +pcb_line_t *pcb_line_dup(pcb_layer_t *dst, pcb_line_t *src) +{ + pcb_line_t *l = pcb_line_new(dst, src->Point1.X, src->Point1.Y, src->Point2.X, src->Point2.Y, src->Thickness, src->Clearance, src->Flags); + return pcb_line_copy_meta(l, src); +} + +pcb_line_t *pcb_line_dup_at(pcb_layer_t *dst, pcb_line_t *src, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_line_t *l = pcb_line_new(dst, src->Point1.X + dx, src->Point1.Y + dy, src->Point2.X + dx, src->Point2.Y + dy, src->Thickness, src->Clearance, src->Flags); + return pcb_line_copy_meta(l, src); +} + +void pcb_add_line_on_layer(pcb_layer_t *Layer, pcb_line_t *Line) +{ + pcb_line_bbox(Line); + if (!Layer->line_tree) + Layer->line_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Layer->line_tree, (rnd_box_t *) Line); + Line->parent.layer = Layer; + Line->parent_type = PCB_PARENT_LAYER; +} + +static void pcb_line_bbox_(const pcb_line_t *Line, rnd_box_t *dst, int mini) +{ + rnd_coord_t width = mini ? (Line->Thickness + 1) / 2 : (Line->Thickness + Line->Clearance + 1) / 2; + + /* Adjust for our discrete polygon approximation */ + width = (double) width *RND_POLY_CIRC_RADIUS_ADJ + 0.5; + + dst->X1 = MIN(Line->Point1.X, Line->Point2.X) - width; + dst->X2 = MAX(Line->Point1.X, Line->Point2.X) + width; + dst->Y1 = MIN(Line->Point1.Y, Line->Point2.Y) - width; + dst->Y2 = MAX(Line->Point1.Y, Line->Point2.Y) + width; + rnd_close_box(dst); +} + +/* sets the bounding box of a line */ +void pcb_line_bbox(pcb_line_t *Line) +{ + pcb_line_bbox_(Line, &Line->BoundingBox, 0); + pcb_line_bbox_(Line, &Line->bbox_naked, 1); + pcb_set_point_bounding_box(&Line->Point1); + pcb_set_point_bounding_box(&Line->Point2); +} + +int pcb_line_eq(const pcb_host_trans_t *tr1, const pcb_line_t *l1, const pcb_host_trans_t *tr2, const pcb_line_t *l2) +{ + if (pcb_field_neq(l1, l2, Thickness) || pcb_field_neq(l1, l2, Clearance)) return 0; + if (pcb_neqs(l1->term, l2->term)) return 0; + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, l1) && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, l2)) { + if (pcb_neq_tr_coords(tr1, l1->Point1.X, l1->Point1.Y, tr2, l2->Point1.X, l2->Point1.Y)) goto swap; + if (pcb_neq_tr_coords(tr1, l1->Point2.X, l1->Point2.Y, tr2, l2->Point2.X, l2->Point2.Y)) return 0; + } + return 1; + + swap:; /* check the line with swapped endpoints */ + if (pcb_neq_tr_coords(tr1, l1->Point2.X, l1->Point2.Y, tr2, l2->Point1.X, l2->Point1.Y)) return 0; + if (pcb_neq_tr_coords(tr1, l1->Point1.X, l1->Point1.Y, tr2, l2->Point2.X, l2->Point2.Y)) return 0; + return 1; +} + + +unsigned int pcb_line_hash(const pcb_host_trans_t *tr, const pcb_line_t *l) +{ + unsigned int crd = 0; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, l)) { + rnd_coord_t x1, y1, x2, y2; + pcb_hash_tr_coords(tr, &x1, &y1, l->Point1.X, l->Point1.Y); + pcb_hash_tr_coords(tr, &x2, &y2, l->Point2.X, l->Point2.Y); + crd = pcb_hash_coord(x1) ^ pcb_hash_coord(y1) ^ pcb_hash_coord(x2) ^ pcb_hash_coord(y2); + } + + return pcb_hash_coord(l->Thickness) ^ pcb_hash_coord(l->Clearance) ^ + pcb_hash_str(l->term) ^ crd; +} + + +rnd_coord_t pcb_line_length(const pcb_line_t *line) +{ + return rnd_round(rnd_distance((double)line->Point1.X, (double)line->Point1.Y, (double)line->Point2.X, (double)line->Point2.Y)); +} + +double pcb_line_area(const pcb_line_t *line) +{ + return + pcb_line_length(line) * (double)line->Thickness /* body */ + + (double)line->Thickness * (double)line->Thickness * M_PI; /* cap circles */ +} + +void pcb_sqline_to_rect(const pcb_line_t *line, rnd_coord_t *x, rnd_coord_t *y) +{ + double l, vx, vy, nx, ny, width, x1, y1, x2, y2, dx, dy; + + x1 = line->Point1.X; + y1 = line->Point1.Y; + x2 = line->Point2.X; + y2 = line->Point2.Y; + + width = (double)((line->Thickness + 1) / 2); + dx = x2-x1; + dy = y2-y1; + + if ((dx == 0) && (dy == 0)) + dx = 1; + + l = sqrt((double)dx*(double)dx + (double)dy*(double)dy); + + vx = dx / l; + vy = dy / l; + nx = -vy; + ny = vx; + + x[0] = (rnd_coord_t)rnd_round(x1 - vx * width + nx * width); + y[0] = (rnd_coord_t)rnd_round(y1 - vy * width + ny * width); + x[1] = (rnd_coord_t)rnd_round(x1 - vx * width - nx * width); + y[1] = (rnd_coord_t)rnd_round(y1 - vy * width - ny * width); + x[2] = (rnd_coord_t)rnd_round(x2 + vx * width - nx * width); + y[2] = (rnd_coord_t)rnd_round(y2 + vy * width - ny * width); + x[3] = (rnd_coord_t)rnd_round(x2 + vx * width + nx * width); + y[3] = (rnd_coord_t)rnd_round(y2 + vy * width + ny * width); +} + +void pcb_line_pre(pcb_line_t *line) +{ + pcb_layer_t *ly = pcb_layer_get_real(line->parent.layer); + if (ly == NULL) + return; + if (ly->line_tree != NULL) + rnd_r_delete_entry(ly->line_tree, (rnd_box_t *)line); + pcb_poly_restore_to_poly(ly->parent.data, PCB_OBJ_LINE, ly, line); +} + +void pcb_line_post(pcb_line_t *line) +{ + pcb_layer_t *ly = pcb_layer_get_real(line->parent.layer); + if (ly == NULL) + return; + if (ly->line_tree != NULL) + rnd_r_insert_entry(ly->line_tree, (rnd_box_t *)line); + pcb_poly_clear_from_poly(ly->parent.data, PCB_OBJ_LINE, ly, line); +} + +/*** ops ***/ +/* copies a line to buffer */ +void *pcb_lineop_add_to_buffer(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + pcb_line_t *line; + rnd_layer_id_t lid = pcb_layer_id(ctx->buffer.src, Layer); + pcb_layer_t *layer; + + /* the buffer may not have the specified layer, e.g. on loose subc subc-aux layer */ + if (lid == -1) + return NULL; + + layer = &ctx->buffer.dst->Layer[lid]; + line = pcb_line_new(layer, Line->Point1.X, Line->Point1.Y, + Line->Point2.X, Line->Point2.Y, + Line->Thickness, Line->Clearance, pcb_flag_mask(Line->Flags, PCB_FLAG_FOUND | ctx->buffer.extraflg)); + pcb_line_copy_meta(line, Line); + if (ctx->buffer.keep_id) pcb_obj_change_id((pcb_any_obj_t *)line, Line->ID); + return line; +} + +/* moves a line between board and buffer */ +void *pcb_lineop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t *dstly, pcb_line_t *line) +{ + pcb_layer_t *srcly = line->parent.layer; + + assert(line->parent_type == PCB_PARENT_LAYER); + if ((dstly == NULL) || (dstly == srcly)) { /* auto layer in dst */ + rnd_layer_id_t lid = pcb_layer_id(ctx->buffer.src, srcly); + if (lid < 0) { + rnd_message(RND_MSG_ERROR, "Internal error: can't resolve source layer ID in pcb_lineop_move_buffer\n"); + return NULL; + } + dstly = &ctx->buffer.dst->Layer[lid]; + } + + pcb_poly_restore_to_poly(ctx->buffer.src, PCB_OBJ_LINE, srcly, line); + rnd_r_delete_entry(srcly->line_tree, (rnd_box_t *)line); + + pcb_line_unreg(line); + pcb_line_reg(dstly, line); + + PCB_FLAG_CLEAR(PCB_FLAG_FOUND, line); + + if (!dstly->line_tree) + dstly->line_tree = rnd_r_create_tree(); + rnd_r_insert_entry(dstly->line_tree, (rnd_box_t *)line); + pcb_poly_clear_from_poly(ctx->buffer.dst, PCB_OBJ_LINE, dstly, line); + + return line; +} + +/* changes the size of a line */ +void *pcb_lineop_change_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + rnd_coord_t value = (ctx->chgsize.is_absolute) ? ctx->chgsize.value : Line->Thickness + ctx->chgsize.value; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Line)) + return NULL; + if (value <= PCB_MAX_THICKNESS && value >= PCB_MIN_THICKNESS && value != Line->Thickness) { + pcb_undo_add_obj_to_size(PCB_OBJ_LINE, Layer, Line, Line); + pcb_line_invalidate_erase(Line); + rnd_r_delete_entry(Layer->line_tree, (rnd_box_t *) Line); + pcb_poly_restore_to_poly(ctx->chgsize.pcb->Data, PCB_OBJ_LINE, Layer, Line); + Line->Thickness = value; + pcb_line_bbox(Line); + rnd_r_insert_entry(Layer->line_tree, (rnd_box_t *) Line); + pcb_poly_clear_from_poly(ctx->chgsize.pcb->Data, PCB_OBJ_LINE, Layer, Line); + pcb_line_invalidate_draw(Layer, Line); + return Line; + } + return NULL; +} + +/*changes the clearance size of a line */ +void *pcb_lineop_change_clear_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + rnd_coord_t value = (ctx->chgsize.is_absolute) ? ctx->chgsize.value : Line->Clearance + ctx->chgsize.value; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Line) || !PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Line)) + return NULL; + if (value < 0) + value = 0; + value = MIN(PCB_MAX_THICKNESS, value); + if (!ctx->chgsize.is_absolute && ctx->chgsize.value < 0) + value = 0; + if (value != Line->Clearance) { + pcb_undo_add_obj_to_clear_size(PCB_OBJ_LINE, Layer, Line, Line); + pcb_poly_restore_to_poly(ctx->chgsize.pcb->Data, PCB_OBJ_LINE, Layer, Line); + pcb_line_invalidate_erase(Line); + rnd_r_delete_entry(Layer->line_tree, (rnd_box_t *) Line); + Line->Clearance = value; + pcb_line_bbox(Line); + rnd_r_insert_entry(Layer->line_tree, (rnd_box_t *) Line); + pcb_poly_clear_from_poly(ctx->chgsize.pcb->Data, PCB_OBJ_LINE, Layer, Line); + pcb_line_invalidate_draw(Layer, Line); + return Line; + } + return NULL; +} + +/* changes the clearance flag of a line */ +void *pcb_lineop_change_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Line)) + return NULL; + pcb_line_invalidate_erase(Line); + if (PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Line)) { + pcb_undo_add_obj_to_clear_poly(PCB_OBJ_LINE, Layer, Line, Line, rnd_false); + pcb_poly_restore_to_poly(ctx->chgsize.pcb->Data, PCB_OBJ_LINE, Layer, Line); + } + pcb_undo_add_obj_to_flag(Line); + PCB_FLAG_TOGGLE(PCB_FLAG_CLEARLINE, Line); + if (PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Line)) { + pcb_undo_add_obj_to_clear_poly(PCB_OBJ_LINE, Layer, Line, Line, rnd_true); + pcb_poly_clear_from_poly(ctx->chgsize.pcb->Data, PCB_OBJ_LINE, Layer, Line); + } + pcb_line_invalidate_draw(Layer, Line); + return Line; +} + +/* sets the clearance flag of a line */ +void *pcb_lineop_set_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Line) || PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Line)) + return NULL; + return pcb_lineop_change_join(ctx, Layer, Line); +} + +/* clears the clearance flag of a line */ +void *pcb_lineop_clear_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Line) || !PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Line)) + return NULL; + return pcb_lineop_change_join(ctx, Layer, Line); +} + +/* copies a line */ +void *pcb_lineop_copy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + pcb_line_t *line; + + line = pcb_line_new_merge(Layer, Line->Point1.X + ctx->copy.DeltaX, + Line->Point1.Y + ctx->copy.DeltaY, + Line->Point2.X + ctx->copy.DeltaX, + Line->Point2.Y + ctx->copy.DeltaY, Line->Thickness, Line->Clearance, pcb_flag_mask(Line->Flags, PCB_FLAG_FOUND)); + if (!line) + return line; + if (ctx->copy.keep_id) + line->ID = Line->ID; + pcb_line_copy_meta(line, Line); + pcb_line_invalidate_draw(Layer, line); + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, Layer, line, line); + return line; +} + +/* moves a line */ +void *pcb_lineop_move_noclip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + if (Layer->meta.real.vis) + pcb_line_invalidate_erase(Line); + pcb_line_move(Line, ctx->move.dx, ctx->move.dy); + if (Layer->meta.real.vis) + pcb_line_invalidate_draw(Layer, Line); + return Line; +} + +void *pcb_lineop_move(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + if (Layer->line_tree != NULL) + rnd_r_delete_entry(Layer->line_tree, (rnd_box_t *) Line); + if (ctx->move.pcb != NULL) + pcb_poly_restore_to_poly(ctx->move.pcb->Data, PCB_OBJ_LINE, Layer, Line); + pcb_lineop_move_noclip(ctx, Layer, Line); + if (Layer->line_tree != NULL) + rnd_r_insert_entry(Layer->line_tree, (rnd_box_t *) Line); + if (ctx->move.pcb != NULL) + pcb_poly_clear_from_poly(ctx->move.pcb->Data, PCB_OBJ_LINE, Layer, Line); + return Line; +} + +void *pcb_lineop_clip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + if (ctx->clip.restore) { + rnd_r_delete_entry(Layer->line_tree, (rnd_box_t *) Line); + if (ctx->clip.pcb != NULL) + pcb_poly_restore_to_poly(ctx->clip.pcb->Data, PCB_OBJ_LINE, Layer, Line); + } + if (ctx->clip.clear) { + rnd_r_insert_entry(Layer->line_tree, (rnd_box_t *) Line); + if (ctx->clip.pcb != NULL) + pcb_poly_clear_from_poly(ctx->clip.pcb->Data, PCB_OBJ_LINE, Layer, Line); + } + return Line; +} + +/* moves one end of a line */ +void *pcb_lineop_move_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line, rnd_point_t *Point) +{ + if (Layer) { + if (Layer->meta.real.vis) + pcb_line_invalidate_erase(Line); + pcb_poly_restore_to_poly(ctx->move.pcb->Data, PCB_OBJ_LINE, Layer, Line); + rnd_r_delete_entry(Layer->line_tree, &Line->BoundingBox); + RND_MOVE_POINT(Point->X, Point->Y, ctx->move.dx, ctx->move.dy); + pcb_line_bbox(Line); + rnd_r_insert_entry(Layer->line_tree, &Line->BoundingBox); + pcb_poly_clear_from_poly(ctx->move.pcb->Data, PCB_OBJ_LINE, Layer, Line); + if (Layer->meta.real.vis) + pcb_line_invalidate_draw(Layer, Line); + return Line; + } + else { /* must be a rat */ + + if (ctx->move.pcb->RatOn) + pcb_rat_invalidate_erase((pcb_rat_t *) Line); + rnd_r_delete_entry(ctx->move.pcb->Data->rat_tree, &Line->BoundingBox); + RND_MOVE_POINT(Point->X, Point->Y, ctx->move.dx, ctx->move.dy); + pcb_line_bbox(Line); + rnd_r_insert_entry(ctx->move.pcb->Data->rat_tree, &Line->BoundingBox); + if (ctx->move.pcb->RatOn) + pcb_rat_invalidate_draw((pcb_rat_t *) Line); + return Line; + } +} + +/* moves one end of a line */ +void *pcb_lineop_move_point_with_route(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line, rnd_point_t *Point) +{ + if ((conf_core.editor.move_linepoint_uses_route == 0) || !Layer) { + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, Layer, Line, Point, ctx->move.dx, ctx->move.dy); + return pcb_lineop_move_point(ctx, Layer, Line, Point); + } + else { + /* Move with Route Code */ + pcb_route_t route; + int mod1, is_first = (&Line->Point1 == Point); + rnd_point_t point1 = Line->Point1; + rnd_point_t point2 = Line->Point2; + + if (is_first) { + point1.X += ctx->move.dx; + point1.Y += ctx->move.dy; + } + else { + point2.X += ctx->move.dx; + point2.Y += ctx->move.dy; + } + + mod1 = rnd_gui->shift_is_pressed(rnd_gui); + if (is_first) + mod1 = !mod1; + + /* Calculate the new line route and add apply it */ + pcb_route_init(&route); + pcb_route_calculate(PCB, + &route, + &point1, + &point2, + pcb_layer_id(ctx->move.pcb->Data,Layer), + Line->Thickness, + Line->Clearance, + Line->Flags, + mod1, + rnd_gui->control_is_pressed(rnd_gui) ); + pcb_route_apply_to_line(&route,Layer,Line); + pcb_route_destroy(&route); + return Line; /* first line is preserved */ + } +} + +/* moves a line between layers; lowlevel routines */ +void *pcb_lineop_move_to_layer_low(pcb_opctx_t *ctx, pcb_layer_t * Source, pcb_line_t * line, pcb_layer_t * Destination) +{ + rnd_r_delete_entry(Source->line_tree, (rnd_box_t *) line); + + pcb_line_unreg(line); + pcb_line_reg(Destination, line); + + if (!Destination->line_tree) + Destination->line_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Destination->line_tree, (rnd_box_t *) line); + + return line; +} + +/* --------------------------------------------------------------------------- + * moves a line between layers + */ +struct via_info { + rnd_coord_t X, Y; + jmp_buf env; +}; + +static rnd_r_dir_t moveline_callback(const rnd_box_t * b, void *cl) +{ + struct via_info *i = (struct via_info *) cl; + pcb_pstk_t *ps; + +TODO("pstk TODO #21: do not work in comp mode, use a pstk proto - scconfig also has TODO #21, fix it there too") + if ((ps = pcb_pstk_new_compat_via(PCB->Data, -1, i->X, i->Y, conf_core.design.via_drilling_hole, conf_core.design.via_thickness, conf_core.design.clearance, 0, PCB_PSTK_COMPAT_ROUND, rnd_true)) != NULL) { + pcb_undo_add_obj_to_create(PCB_OBJ_PSTK, ps, ps, ps); + pcb_pstk_invalidate_draw(ps); + } + longjmp(i->env, 1); +} + +void *pcb_lineop_move_to_layer(pcb_opctx_t *ctx, pcb_layer_t * Layer, pcb_line_t * Line) +{ + struct via_info info; + rnd_box_t sb; + pcb_line_t *newone; + void *ptr1, *ptr2, *ptr3; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Line)) { + rnd_message(RND_MSG_WARNING, "Sorry, line object is locked\n"); + return NULL; + } + if (ctx->move.dst_layer == Layer && Layer->meta.real.vis) + pcb_line_invalidate_draw(Layer, Line); + if (ctx->move.dst_layer == Layer) + return Line; + + pcb_undo_add_obj_to_move_to_layer(PCB_OBJ_LINE, Layer, Line, Line); + if (Layer->meta.real.vis) + pcb_line_invalidate_erase(Line); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_LINE, Layer, Line); + newone = (pcb_line_t *) pcb_lineop_move_to_layer_low(ctx, Layer, Line, ctx->move.dst_layer); + Line = NULL; + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_LINE, ctx->move.dst_layer, newone); + if (ctx->move.dst_layer->meta.real.vis) + pcb_line_invalidate_draw(ctx->move.dst_layer, newone); + if (!conf_core.editor.auto_via || !PCB->pstk_on || ctx->move.more_to_come || + pcb_layer_get_group_(Layer) == + pcb_layer_get_group_(ctx->move.dst_layer) || !(pcb_layer_flags(PCB, pcb_layer_id(PCB->Data, Layer)) & PCB_LYT_COPPER) || !(pcb_layer_flags_(ctx->move.dst_layer) & PCB_LYT_COPPER)) + return newone; + /* consider via at Point1 */ + sb.X1 = newone->Point1.X - newone->Thickness / 2; + sb.X2 = newone->Point1.X + newone->Thickness / 2; + sb.Y1 = newone->Point1.Y - newone->Thickness / 2; + sb.Y2 = newone->Point1.Y + newone->Thickness / 2; + if ((pcb_search_obj_by_location(PCB_OBJ_CLASS_PIN, &ptr1, &ptr2, &ptr3, + newone->Point1.X, newone->Point1.Y, conf_core.design.via_thickness / 2) == PCB_OBJ_VOID)) { + info.X = newone->Point1.X; + info.Y = newone->Point1.Y; + if (setjmp(info.env) == 0) + rnd_r_search(Layer->line_tree, &sb, NULL, moveline_callback, &info, NULL); + } + /* consider via at Point2 */ + sb.X1 = newone->Point2.X - newone->Thickness / 2; + sb.X2 = newone->Point2.X + newone->Thickness / 2; + sb.Y1 = newone->Point2.Y - newone->Thickness / 2; + sb.Y2 = newone->Point2.Y + newone->Thickness / 2; + if ((pcb_search_obj_by_location(PCB_OBJ_CLASS_PIN, &ptr1, &ptr2, &ptr3, + newone->Point2.X, newone->Point2.Y, conf_core.design.via_thickness / 2) == PCB_OBJ_VOID)) { + info.X = newone->Point2.X; + info.Y = newone->Point2.Y; + if (setjmp(info.env) == 0) + rnd_r_search(Layer->line_tree, &sb, NULL, moveline_callback, &info, NULL); + } + return newone; +} + +void *pcb_lineop_change_thermal(pcb_opctx_t *ctx, pcb_layer_t *ly, pcb_line_t *line) +{ + return pcb_anyop_change_thermal(ctx, (pcb_any_obj_t *)line); +} + +/* destroys a line from a layer */ +void *pcb_lineop_destroy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + rnd_r_delete_entry(Layer->line_tree, (rnd_box_t *) Line); + + pcb_line_free(Line); + return NULL; +} + +/* remove point... */ +struct rlp_info { + jmp_buf env; + pcb_line_t *line; + rnd_point_t *point; +}; +static rnd_r_dir_t remove_point(const rnd_box_t * b, void *cl) +{ + pcb_line_t *line = (pcb_line_t *) b; + struct rlp_info *info = (struct rlp_info *) cl; + if (line == info->line) + return RND_R_DIR_NOT_FOUND; + if ((line->Point1.X == info->point->X) + && (line->Point1.Y == info->point->Y)) { + info->line = line; + info->point = &line->Point1; + longjmp(info->env, 1); + } + else if ((line->Point2.X == info->point->X) + && (line->Point2.Y == info->point->Y)) { + info->line = line; + info->point = &line->Point2; + longjmp(info->env, 1); + } + return RND_R_DIR_NOT_FOUND; +} + +/* removes a line point, or a line if the selected point is the end */ +void *pcb_lineop_remove_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line, rnd_point_t *Point) +{ + rnd_point_t other; + struct rlp_info info; + if (&Line->Point1 == Point) + other = Line->Point2; + else + other = Line->Point1; + info.line = Line; + info.point = Point; + if (setjmp(info.env) == 0) { + rnd_r_search(Layer->line_tree, (const rnd_box_t *) Point, NULL, remove_point, &info, NULL); + return pcb_lineop_remove(ctx, Layer, Line); + } + pcb_move_obj(PCB_OBJ_LINE_POINT, Layer, info.line, info.point, other.X - Point->X, other.Y - Point->Y); + return (pcb_lineop_remove(ctx, Layer, Line)); +} + +/* removes a line from a layer */ +void *pcb_lineop_remove(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + /* erase from screen */ + if (Layer->meta.real.vis) + pcb_line_invalidate_erase(Line); + pcb_undo_move_obj_to_remove(PCB_OBJ_LINE, Layer, Line, Line); + return NULL; +} + +void *pcb_line_destroy(pcb_layer_t *Layer, pcb_line_t *Line) +{ + void *res; + pcb_opctx_t ctx; + + ctx.remove.pcb = PCB; + ctx.remove.destroy_target = NULL; + + res = pcb_lineop_remove(&ctx, Layer, Line); + pcb_draw(); + return res; +} + +/* rotates a line in 90 degree steps */ +void pcb_line_rotate90(pcb_line_t *Line, rnd_coord_t X, rnd_coord_t Y, unsigned Number) +{ + RND_COORD_ROTATE90(Line->Point1.X, Line->Point1.Y, X, Y, Number); + RND_COORD_ROTATE90(Line->Point2.X, Line->Point2.Y, X, Y, Number); + /* keep horizontal, vertical Point2 > Point1 */ + if (Line->Point1.X == Line->Point2.X) { + if (Line->Point1.Y > Line->Point2.Y) { + rnd_coord_t t; + t = Line->Point1.Y; + Line->Point1.Y = Line->Point2.Y; + Line->Point2.Y = t; + } + } + else if (Line->Point1.Y == Line->Point2.Y) { + if (Line->Point1.X > Line->Point2.X) { + rnd_coord_t t; + t = Line->Point1.X; + Line->Point1.X = Line->Point2.X; + Line->Point2.X = t; + } + } + /* instead of rotating the bounding box, the call updates both end points too */ + pcb_line_bbox(Line); +} + +void pcb_line_rotate(pcb_layer_t *layer, pcb_line_t *line, rnd_coord_t X, rnd_coord_t Y, double cosa, double sina) +{ + if (layer->line_tree != NULL) + rnd_r_delete_entry(layer->line_tree, (rnd_box_t *) line); + rnd_rotate(&line->Point1.X, &line->Point1.Y, X, Y, cosa, sina); + rnd_rotate(&line->Point2.X, &line->Point2.Y, X, Y, cosa, sina); + pcb_line_bbox(line); + if (layer->line_tree != NULL) + rnd_r_insert_entry(layer->line_tree, (rnd_box_t *) line); +} + +void pcb_line_mirror(pcb_line_t *line, rnd_coord_t y_offs, rnd_bool undoable) +{ + undo_line_geo_t gtmp, *g = >mp; + + if (undoable) g = pcb_undo_alloc(pcb_data_get_top(line->parent.layer->parent.data), &undo_line_geo, sizeof(undo_line_geo_t)); + + g->line = line; + g->Point1.X = PCB_SWAP_X(line->Point1.X); + g->Point1.Y = PCB_SWAP_Y(line->Point1.Y) + y_offs; + g->Point2.X = PCB_SWAP_X(line->Point2.X); + g->Point2.Y = PCB_SWAP_Y(line->Point2.Y) + y_offs; + g->Thickness = line->Thickness; + g->Clearance = line->Clearance; + + undo_line_geo_swap(g); + if (undoable) pcb_undo_inc_serial(); +} + +void pcb_line_scale(pcb_line_t *line, double sx, double sy, double sth) +{ + int onbrd = (line->parent.layer != NULL) && (!line->parent.layer->is_bound); + + if (onbrd) + pcb_line_pre(line); + + if (sx != 1.0) { + line->Point1.X = rnd_round((double)line->Point1.X * sx); + line->Point2.X = rnd_round((double)line->Point2.X * sx); + } + + if (sy != 1.0) { + line->Point1.Y = rnd_round((double)line->Point1.Y * sy); + line->Point2.Y = rnd_round((double)line->Point2.Y * sy); + } + + if (sth != 1.0) + line->Thickness = rnd_round((double)line->Thickness * sth); + + pcb_line_bbox(line); + + if (onbrd) + pcb_line_post(line); +} + +void pcb_line_flip_side(pcb_layer_t *layer, pcb_line_t *line) +{ + rnd_r_delete_entry(layer->line_tree, (rnd_box_t *) line); + line->Point1.X = PCB_SWAP_X(line->Point1.X); + line->Point1.Y = PCB_SWAP_Y(line->Point1.Y); + line->Point2.X = PCB_SWAP_X(line->Point2.X); + line->Point2.Y = PCB_SWAP_Y(line->Point2.Y); + pcb_line_bbox(line); + rnd_r_insert_entry(layer->line_tree, (rnd_box_t *) line); +} + +static void rotate_line1(pcb_layer_t *Layer, pcb_line_t *Line) +{ + pcb_line_invalidate_erase(Line); + if (Layer) { + if (!Layer->is_bound) + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_LINE, Layer, Line); + if (Layer->line_tree != NULL) + rnd_r_delete_entry(Layer->line_tree, (rnd_box_t *) Line); + } + else + rnd_r_delete_entry(PCB->Data->rat_tree, (rnd_box_t *) Line); +} + +static void rotate_line2(pcb_layer_t *Layer, pcb_line_t *Line) +{ + pcb_line_bbox(Line); + if (Layer) { + if (Layer->line_tree != NULL) + rnd_r_insert_entry(Layer->line_tree, (rnd_box_t *) Line); + if (!Layer->is_bound) + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_LINE, Layer, Line); + pcb_line_invalidate_draw(Layer, Line); + } + else { + rnd_r_insert_entry(PCB->Data->rat_tree, (rnd_box_t *) Line); + pcb_rat_invalidate_draw((pcb_rat_t *) Line); + } +} + +/* rotates a line's point */ +void *pcb_lineop_rotate90_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line, rnd_point_t *Point) +{ + rotate_line1(Layer, Line); + + pcb_point_rotate90(Point, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.number); + + rotate_line2(Layer, Line); + return Line; +} + +/* rotates a line */ +void *pcb_lineop_rotate90(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + rotate_line1(Layer, Line); + pcb_point_rotate90(&Line->Point1, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.number); + pcb_point_rotate90(&Line->Point2, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.number); + rotate_line2(Layer, Line); + return Line; +} + +void *pcb_lineop_rotate(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + pcb_line_rotate(Layer, Line, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.cosa, ctx->rotate.sina); + return Line; +} + +/* inserts a point into a line */ +void *pcb_lineop_insert_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + pcb_line_t *line; + rnd_coord_t X, Y; + + if (((Line->Point1.X == ctx->insert.x) && (Line->Point1.Y == ctx->insert.y)) || + ((Line->Point2.X == ctx->insert.x) && (Line->Point2.Y == ctx->insert.y))) + return NULL; + X = Line->Point2.X; + Y = Line->Point2.Y; + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, Layer, Line, &Line->Point2, ctx->insert.x - X, ctx->insert.y - Y); + pcb_line_invalidate_erase(Line); + rnd_r_delete_entry(Layer->line_tree, (rnd_box_t *) Line); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_LINE, Layer, Line); + Line->Point2.X = ctx->insert.x; + Line->Point2.Y = ctx->insert.y; + pcb_line_bbox(Line); + rnd_r_insert_entry(Layer->line_tree, (rnd_box_t *) Line); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_LINE, Layer, Line); + pcb_line_invalidate_draw(Layer, Line); + /* we must create after playing with Line since creation may + * invalidate the line pointer + */ + + line = pcb_line_new(Layer, ctx->insert.x, ctx->insert.y, X, Y, Line->Thickness, Line->Clearance, Line->Flags); + + if (line) { + pcb_line_copy_meta(line, Line); + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, Layer, line, line); + pcb_line_invalidate_draw(Layer, line); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_LINE, Layer, line); + /* creation call adds it to the rtree */ + } + return line; +} + +void *pcb_lineop_change_flag(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line) +{ + static pcb_flag_values_t pcb_line_flags = 0; + if (pcb_line_flags == 0) + pcb_line_flags = pcb_obj_valid_flags(PCB_OBJ_LINE); + + if ((ctx->chgflag.flag & pcb_line_flags) != ctx->chgflag.flag) + return NULL; + if ((ctx->chgflag.flag & PCB_FLAG_TERMNAME) && (Line->term == NULL)) + return NULL; + pcb_undo_add_obj_to_flag(Line); + + if (ctx->chgflag.flag & PCB_FLAG_CLEARLINE) + pcb_poly_restore_to_poly(ctx->chgflag.pcb->Data, PCB_OBJ_LINE, Line->parent.layer, Line); + + PCB_FLAG_CHANGE(ctx->chgflag.how, ctx->chgflag.flag, Line); + + if (ctx->chgflag.flag & PCB_FLAG_CLEARLINE) + pcb_poly_clear_from_poly(ctx->chgflag.pcb->Data, PCB_OBJ_LINE, Line->parent.layer, Line); + + return Line; +} + +void *pcb_lineop_invalidate_label(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_line_t *line) +{ + pcb_line_name_invalidate_draw(line); + return line; +} + + +/*** draw ***/ + +static rnd_bool is_line_term_vert(const pcb_line_t *line) +{ + rnd_coord_t dx, dy; + + dx = line->Point1.X - line->Point2.X; + if (dx < 0) + dx = -dx; + + dy = line->Point1.Y - line->Point2.Y; + if (dy < 0) + dy = -dy; + + return dx < dy; +} + +void pcb_line_name_invalidate_draw(pcb_line_t *line) +{ + if (line->term != NULL) { + pcb_term_label_invalidate((line->Point1.X + line->Point2.X)/2, (line->Point1.Y + line->Point2.Y)/2, + 100.0, is_line_term_vert(line), rnd_true, (pcb_any_obj_t *)line); + } +} + +void pcb_line_draw_label(pcb_draw_info_t *info, pcb_line_t *line, rnd_bool vis_side) +{ + if ((line->term != NULL) && vis_side) + pcb_term_label_draw(info, (line->Point1.X + line->Point2.X)/2, (line->Point1.Y + line->Point2.Y)/2, + conf_core.appearance.term_label_size, is_line_term_vert(line), rnd_true, (pcb_any_obj_t *)line); + if (line->noexport && vis_side) + pcb_obj_noexport_mark(line, (line->Point1.X+line->Point2.X)/2, (line->Point1.Y+line->Point2.Y)/2); + + if (line->ind_editpoint) { + pcb_obj_editpont_setup(); + pcb_obj_editpont_cross(line->Point1.X, line->Point1.Y); + if ((line->Point1.X != line->Point2.X) || (line->Point1.Y != line->Point2.Y)) + pcb_obj_editpont_cross(line->Point2.X, line->Point2.Y); + } +} + + +void pcb_line_draw_(pcb_draw_info_t *info, pcb_line_t *line, int allow_term_gfx) +{ + rnd_coord_t thickness = line->Thickness; + int draw_lab; + + if (delayed_terms_enabled && (line->term != NULL)) { + pcb_draw_delay_obj_add((pcb_any_obj_t *)line); + return; + } + + if ((info != NULL) && (info->xform != NULL) && (info->xform->bloat != 0)) { + thickness += info->xform->bloat; + if (thickness < 1) + thickness = 1; + } + + PCB_DRAW_BBOX(line); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); + if (!info->xform->thin_draw && !info->xform->wireframe) { + if ((allow_term_gfx) && pcb_draw_term_need_gfx(line) && pcb_draw_term_hid_permission()) { + rnd_hid_set_line_cap(pcb_draw_out.active_padGC, rnd_cap_round); + rnd_hid_set_line_width(pcb_draw_out.active_padGC, thickness); + rnd_render->draw_line(pcb_draw_out.active_padGC, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); + rnd_hid_set_line_width(pcb_draw_out.fgGC, PCB_DRAW_TERM_GFX_WIDTH); + } + else + rnd_hid_set_line_width(pcb_draw_out.fgGC, thickness); + rnd_render->draw_line(pcb_draw_out.fgGC, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); + } + else { + if(info->xform->thin_draw) { + rnd_hid_set_line_width(pcb_draw_out.fgGC, 0); + rnd_render->draw_line(pcb_draw_out.fgGC, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); + } + + if (info->xform->wireframe) { + rnd_hid_set_line_width(pcb_draw_out.fgGC, 0); + pcb_draw_wireframe_line(pcb_draw_out.fgGC, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, thickness, 0); + } + } + + draw_lab = (line->term != NULL) && ((pcb_draw_force_termlab) || PCB_FLAG_TEST(PCB_FLAG_TERMNAME, line)); + draw_lab |= line->ind_editpoint; + + if (draw_lab) + pcb_draw_delay_label_add((pcb_any_obj_t *)line); +} + +static void pcb_line_draw(pcb_draw_info_t *info, pcb_line_t *line, int allow_term_gfx) +{ + const rnd_color_t *color; + rnd_color_t buf; + const pcb_layer_t *layer = info->layer != NULL ? info->layer : pcb_layer_get_real(line->parent.layer); + + pcb_obj_noexport(info, line, return); + + if (layer == NULL) /* if the layer is inbound, e.g. in preview, fall back using the layer recipe */ + layer = line->parent.layer; + + if (info->xform->flag_color && PCB_FLAG_TEST(PCB_FLAG_WARN, line)) + color = &conf_core.appearance.color.warn; + else if (info->xform->flag_color && PCB_FLAG_TEST(PCB_FLAG_SELECTED | PCB_FLAG_FOUND, line)) { + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, line)) { + if (layer->is_bound) + PCB_OBJ_COLOR_ON_BOUND_LAYER(color, layer, 1); + else + color = &conf_core.appearance.color.selected; + } + else + color = &conf_core.appearance.color.connected; + } + else if (PCB_HAS_COLOROVERRIDE(line)) { + color = line->override_color; + } + else if (layer->is_bound) + PCB_OBJ_COLOR_ON_BOUND_LAYER(color, layer, 0); + else + color = &layer->meta.real.color; + + if (info->xform->flag_color && line->ind_onpoint) { + pcb_lighten_color(color, &buf, 1.75); + color = &buf; + } + + rnd_render->set_color(pcb_draw_out.fgGC, color); + pcb_line_draw_(info, line, allow_term_gfx); +} + +rnd_r_dir_t pcb_line_draw_callback(const rnd_box_t * b, void *cl) +{ + pcb_line_t *line = (pcb_line_t *)b; + pcb_draw_info_t *info = cl; + + if (pcb_hidden_floater((pcb_any_obj_t*)b, info) || pcb_partial_export((pcb_any_obj_t*)b, info)) + return RND_R_DIR_FOUND_CONTINUE; + + if (!PCB->SubcPartsOn && pcb_lobj_parent_subc(line->parent_type, &line->parent)) + return RND_R_DIR_NOT_FOUND; + + pcb_line_draw(info, line, 0); + return RND_R_DIR_FOUND_CONTINUE; +} + +rnd_r_dir_t pcb_line_draw_term_callback(const rnd_box_t * b, void *cl) +{ + pcb_line_t *line = (pcb_line_t *)b; + pcb_draw_info_t *info = cl; + + if (pcb_hidden_floater((pcb_any_obj_t*)b, info) || pcb_partial_export((pcb_any_obj_t*)b, info)) + return RND_R_DIR_FOUND_CONTINUE; + + if (!PCB->SubcPartsOn && pcb_lobj_parent_subc(line->parent_type, &line->parent)) + return RND_R_DIR_NOT_FOUND; + + pcb_line_draw(info, line, 1); + return RND_R_DIR_FOUND_CONTINUE; +} + +/* erases a line on a layer */ +void pcb_line_invalidate_erase(pcb_line_t *Line) +{ + pcb_draw_invalidate(Line); + pcb_flag_erase(&Line->Flags); +} + +void pcb_line_invalidate_draw(pcb_layer_t *Layer, pcb_line_t *Line) +{ + pcb_draw_invalidate(Line); +} + Index: tags/2.3.0/src/obj_line.h =================================================================== --- tags/2.3.0/src/obj_line.h (nonexistent) +++ tags/2.3.0/src/obj_line.h (revision 33253) @@ -0,0 +1,186 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Drawing primitive: line segment */ + +#ifndef PCB_OBJ_LINE_H +#define PCB_OBJ_LINE_H + +#include +#include "obj_common.h" + +struct pcb_line_s { /* holds information about one line */ + PCB_ANYLINEFIELDS; + gdl_elem_t link; /* a line is in a list: either on a layer */ +}; + +/* crosshair: */ +typedef struct { /* current marked line */ + rnd_point_t Point1, Point2; /* start- and end-position */ + long int State; + rnd_bool draw; +} pcb_attached_line_t; + + +pcb_line_t *pcb_line_alloc(pcb_layer_t * layer); +pcb_line_t *pcb_line_alloc_id(pcb_layer_t *layer, long int id); +void pcb_line_free(pcb_line_t * data); + +pcb_line_t *pcb_line_new_merge(pcb_layer_t *Layer, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Thickness, rnd_coord_t Clearance, pcb_flag_t Flags); +pcb_line_t *pcb_line_new(pcb_layer_t *Layer, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Thickness, rnd_coord_t Clearance, pcb_flag_t Flags); +pcb_line_t *pcb_line_dup(pcb_layer_t *Layer, pcb_line_t *src); +pcb_line_t *pcb_line_dup_at(pcb_layer_t *dst, pcb_line_t *src, rnd_coord_t dx, rnd_coord_t dy); +void *pcb_line_destroy(pcb_layer_t *dst, pcb_line_t *src); + +void pcb_line_reg(pcb_layer_t *layer, pcb_line_t *line); +void pcb_line_unreg(pcb_line_t *line); + +/* Add objects without creating them or making any "sanity modifications" to them */ +void pcb_add_line_on_layer(pcb_layer_t *Layer, pcb_line_t *Line); + +void pcb_line_bbox(pcb_line_t *Line); +void pcb_line_rotate90(pcb_line_t *Line, rnd_coord_t X, rnd_coord_t Y, unsigned Number); +void pcb_line_rotate(pcb_layer_t *layer, pcb_line_t *line, rnd_coord_t X, rnd_coord_t Y, double cosa, double sina); +void pcb_line_mirror(pcb_line_t *line, rnd_coord_t y_offs, rnd_bool undoable); +void pcb_line_flip_side(pcb_layer_t *layer, pcb_line_t *line); +void pcb_line_scale(pcb_line_t *line, double sx, double sy, double sth); + +rnd_coord_t pcb_line_length(const pcb_line_t *line); +double pcb_line_area(const pcb_line_t *line); + +/* Convert a square cap line (e.g. a gEDA/pcb pad) to 4 corner points of a rectangle */ +void pcb_sqline_to_rect(const pcb_line_t *line, rnd_coord_t *x, rnd_coord_t *y); + +/* hash and eq */ +int pcb_line_eq(const pcb_host_trans_t *tr1, const pcb_line_t *l1, const pcb_host_trans_t *tr2, const pcb_line_t *l2); +unsigned int pcb_line_hash(const pcb_host_trans_t *tr, const pcb_line_t *l); + +/* un-administrate a line; call before changing geometry */ +void pcb_line_pre(pcb_line_t *line); + +/* re-administrate a line; call after changing geometry */ +void pcb_line_post(pcb_line_t *line); + +/*** DRC enforcement (obj_line_drcenf.c) ***/ + +/* Adjust the attached line to 45 degrees if necessary */ +void pcb_line_adjust_attached(void); + +/* adjusts the insert lines to make them 45 degrees as necessary */ +void pcb_line_adjust_attached_2lines(rnd_bool); + +/* makes the attached line fit into a 45 degree direction */ +void pcb_line_45(pcb_attached_line_t *); + +void pcb_line_enforce_drc(pcb_board_t *pcb); + +/* Calculate a pair of refractioned (ortho-45) lines between 'start' and 'end'. + If 'mid_out' is not NULL, load it with the coords of the middle point. + If way is false it checks an ortho start line with one 45 refraction to + reach the endpoint, otherwise it checks a 45 start, with a ortho refraction + to reach endpoint. + + Checks for intersectors against two lines. + + If optimize is false, return straight-line distance between start and end + on success or -1 if the pair-of-lines has hit a blocker object. + + If optimize is true, keep on looking for a mid-way solution, adjusting + the fields of 'end' needed to find the closest point to the original target + that still won't hit any object. Returns the straigh-line distance between + start and the new end. */ +double pcb_drc_lines(pcb_board_t *pcb, const rnd_point_t *start, rnd_point_t *end, rnd_point_t *mid_out, rnd_bool way, rnd_bool optimize); + +/*** decide if two liens are overlapping in a way they can be simplified ***/ +typedef enum { + PCB_LINMER_NONE = 0, /* no merge is possible */ + PCB_LINMER_REMPT = 1, /* remove both endpoints passed back in out */ + PCB_LINMER_SKIP = 2 /* do not create the new line at all */ +} pcb_line_merge_t; + +pcb_line_merge_t pcb_line_can_merge_lines(const pcb_line_t *old_line, const pcb_line_t *new_line, pcb_line_t *out); + + +/* Check if line can be merged with any other line and do the merge if so + (typically called after line has been modified) */ +void pcb_line_mod_merge(pcb_line_t *line, rnd_bool undoable); + +/* Batch line merge optimization */ +void pcb_line_mod_merge_inhibit_inc(pcb_board_t *pcb); +void pcb_line_mod_merge_inhibit_dec(pcb_board_t *pcb); + + +/* Rather than mode the line bounding box, we set it so the point bounding + * boxes are updated too. + */ +#define pcb_line_move(l,dx,dy) \ + do { \ + rnd_coord_t __dx__ = (dx), __dy__ = (dy); \ + pcb_line_t *__l__ = (l); \ + RND_MOVE_POINT((__l__)->Point1.X,(__l__)->Point1.Y,(__dx__),(__dy__)); \ + RND_MOVE_POINT((__l__)->Point2.X,(__l__)->Point2.Y,(__dx__),(__dy__)); \ + pcb_line_bbox(__l__); \ + } while(0) + +#define PCB_LINE_LOOP(layer) do { \ + pcb_line_t *line; \ + gdl_iterator_t __it__; \ + linelist_foreach(&(layer)->Line, &__it__, line) { + +#define PCB_LINE_ALL_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + PCB_LINE_LOOP(layer) + +#define PCB_LINE_COPPER_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (!(pcb_layer_flags(PCB, l) & PCB_LYT_COPPER)) continue; \ + PCB_LINE_LOOP(layer) + +#define PCB_LINE_SILK_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (!(pcb_layer_flags(PCB, l) & PCB_LYT_SILK)) continue; \ + PCB_LINE_LOOP(layer) + +#define PCB_LINE_VISIBLE_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (layer->meta.real.vis) \ + PCB_LINE_LOOP(layer) + +#endif Index: tags/2.3.0/src/obj_line_draw.h =================================================================== --- tags/2.3.0/src/obj_line_draw.h (nonexistent) +++ tags/2.3.0/src/obj_line_draw.h (revision 33253) @@ -0,0 +1,44 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard draw of lines ***/ + +#include "draw.h" + +/* Include rtree.h for this */ +#ifdef RND_RTREE_H +rnd_r_dir_t pcb_line_draw_callback(const rnd_box_t * b, void *cl); +rnd_r_dir_t pcb_line_draw_term_callback(const rnd_box_t * b, void *cl); +#endif + +void pcb_line_draw_(pcb_draw_info_t *info, pcb_line_t *line, int allow_term_gfx); +void pcb_line_invalidate_erase(pcb_line_t *Line); +void pcb_line_invalidate_draw(pcb_layer_t *Layer, pcb_line_t *Line); +void pcb_line_draw_label(pcb_draw_info_t *info, pcb_line_t *line, rnd_bool vis_side); +void pcb_line_name_invalidate_draw(pcb_line_t *line); + Index: tags/2.3.0/src/obj_line_drcenf.c =================================================================== --- tags/2.3.0/src/obj_line_drcenf.c (nonexistent) +++ tags/2.3.0/src/obj_line_drcenf.c (revision 33253) @@ -0,0 +1,525 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2004 harry eaton + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include "conf_core.h" +#include + +#include +#include + +#include "board.h" +#include "data.h" +#include "find.h" +#include + +void pcb_line_adjust_attached(void) +{ + pcb_attached_line_t *line = &pcb_crosshair.AttachedLine; + int flags = conf_core.editor.clear_line ? PCB_FLAG_CLEARLINE : 0; + + if (conf_core.editor.auto_drc && (pcb_layer_flags_(PCB_CURRLAYER(PCB)) & PCB_LYT_COPPER)) + flags |= PCB_FLAG_FOUND; + + /* I need at least one point */ + if (line->State == PCB_CH_STATE_FIRST) + return; + + line->Point2.X = pcb_crosshair.X; + line->Point2.Y = pcb_crosshair.Y; + + pcb_route_calculate(PCB, + &pcb_crosshair.Route, &line->Point1, &line->Point2, + pcb_layer_id(PCB->Data, PCB_CURRLAYER(PCB)), + conf_core.design.line_thickness, conf_core.design.clearance * 2, + pcb_flag_make(flags), rnd_gui->shift_is_pressed(rnd_gui), + rnd_gui->control_is_pressed(rnd_gui)); +} + +/* directions: + * + * 0 + * 7 1 + * 6 2 + * 5 3 + * 4 + */ +void pcb_line_45(pcb_attached_line_t *Line) +{ + rnd_coord_t dx, dy, min; + unsigned direction = 0; + double m; + + /* first calculate direction of line */ + dx = pcb_crosshair.X - Line->Point1.X; + dy = pcb_crosshair.Y - Line->Point1.Y; + + if (!dx) { + if (!dy) + /* zero length line, don't draw anything */ + return; + else + direction = dy > 0 ? 0 : 4; + } + else { + m = (double) dy / dx; + direction = 2; + if (m > RND_TAN_30_DEGREE) + direction = m > RND_TAN_60_DEGREE ? 0 : 1; + else if (m < -RND_TAN_30_DEGREE) + direction = m < -RND_TAN_60_DEGREE ? 0 : 3; + } + if (dx < 0) + direction += 4; + + dx = coord_abs(dx); + dy = coord_abs(dy); + min = MIN(dx, dy); + + /* now set up the second pair of coordinates */ + switch (direction) { + case 0: + case 4: + Line->Point2.X = Line->Point1.X; + Line->Point2.Y = pcb_crosshair.Y; + break; + + case 2: + case 6: + Line->Point2.X = pcb_crosshair.X; + Line->Point2.Y = Line->Point1.Y; + break; + + case 1: + Line->Point2.X = Line->Point1.X + min; + Line->Point2.Y = Line->Point1.Y + min; + break; + + case 3: + Line->Point2.X = Line->Point1.X + min; + Line->Point2.Y = Line->Point1.Y - min; + break; + + case 5: + Line->Point2.X = Line->Point1.X - min; + Line->Point2.Y = Line->Point1.Y - min; + break; + + case 7: + Line->Point2.X = Line->Point1.X - min; + Line->Point2.Y = Line->Point1.Y + min; + break; + } +} + +void pcb_line_adjust_attached_2lines(rnd_bool way) +{ + rnd_coord_t dx, dy; + pcb_attached_line_t *line = &pcb_crosshair.AttachedLine; + + if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_FIRST) + return; + + /* don't draw outline when ctrl key is pressed */ + if (rnd_gui->control_is_pressed(rnd_gui)) { + line->draw = rnd_false; + return; + } + else + line->draw = rnd_true; + + if (conf_core.editor.all_direction_lines) { + line->Point2.X = pcb_crosshair.X; + line->Point2.Y = pcb_crosshair.Y; + return; + } + + /* swap the modes if shift is held down */ + if (rnd_gui->shift_is_pressed(rnd_gui)) + way = !way; + + dx = pcb_crosshair.X - line->Point1.X; + dy = pcb_crosshair.Y - line->Point1.Y; + + if (!way) { + if (coord_abs(dx) > coord_abs(dy)) { + line->Point2.X = pcb_crosshair.X - SGN(dx) * coord_abs(dy); + line->Point2.Y = line->Point1.Y; + } + else { + line->Point2.X = line->Point1.X; + line->Point2.Y = pcb_crosshair.Y - SGN(dy) * coord_abs(dx); + } + } + else { + if (coord_abs(dx) > coord_abs(dy)) { + line->Point2.X = line->Point1.X + SGN(dx) * coord_abs(dy); + line->Point2.Y = pcb_crosshair.Y; + } + else { + line->Point2.X = pcb_crosshair.X; + line->Point2.Y = line->Point1.Y + SGN(dy) * coord_abs(dx); + } + } +} + +struct drc_info { + pcb_line_t *line; + rnd_bool solder; + jmp_buf env; +}; + +static rnd_r_dir_t drcPstk_callback(const rnd_box_t *b, void *cl) +{ + pcb_pstk_t *ps = (pcb_pstk_t *)b; + struct drc_info *i = (struct drc_info *)cl; + + if (!PCB_FLAG_TEST(PCB_FLAG_FOUND, ps) && pcb_isc_pstk_line(pcb_find0, ps, i->line, rnd_false)) + longjmp(i->env, 1); + return RND_R_DIR_FOUND_CONTINUE; +} + +static rnd_r_dir_t drcLine_callback(const rnd_box_t * b, void *cl) +{ + pcb_line_t *line = (pcb_line_t *) b; + struct drc_info *i = (struct drc_info *) cl; + + if (!PCB_FLAG_TEST(PCB_FLAG_FOUND, line) && pcb_isc_line_line(pcb_find0, line, i->line)) + longjmp(i->env, 1); + return RND_R_DIR_FOUND_CONTINUE; +} + +static rnd_r_dir_t drcArc_callback(const rnd_box_t * b, void *cl) +{ + pcb_arc_t *arc = (pcb_arc_t *) b; + struct drc_info *i = (struct drc_info *) cl; + + if (!PCB_FLAG_TEST(PCB_FLAG_FOUND, arc) && pcb_isc_line_arc(pcb_find0, i->line, arc)) + longjmp(i->env, 1); + return RND_R_DIR_FOUND_CONTINUE; +} + +double pcb_drc_lines(pcb_board_t *pcb, const rnd_point_t *start, rnd_point_t *end, rnd_point_t *mid_out, rnd_bool way, rnd_bool optimize) +{ + double f, s, f2, s2, len, best; + rnd_coord_t dx, dy, temp, last, length; + rnd_coord_t temp2, last2, length2; + pcb_line_t line1, line2; + rnd_layergrp_id_t group, comp; + struct drc_info info; + rnd_bool two_lines, x_is_long, blocker; + rnd_point_t ans; + + f = 1.0; + s = 0.5; + last = -1; + line1.type = line2.type = PCB_OBJ_LINE; + line1.Flags = line2.Flags = pcb_no_flags(); + line1.parent_type = line2.parent_type = PCB_PARENT_LAYER; + line1.parent.layer = line2.parent.layer = PCB_CURRLAYER(PCB); + line1.Thickness = conf_core.design.line_thickness + 2 * (conf_core.design.clearance + 1); + line2.Thickness = line1.Thickness; + line1.Clearance = line2.Clearance = 0; + line1.Point1.X = start->X; + line1.Point1.Y = start->Y; + dy = end->Y - line1.Point1.Y; + dx = end->X - line1.Point1.X; + + if (coord_abs(dx) > coord_abs(dy)) { + x_is_long = rnd_true; + length = coord_abs(dx); + } + else { + x_is_long = rnd_false; + length = coord_abs(dy); + } + + group = pcb_layer_get_group(PCB, PCB_CURRLID(pcb)); + comp = PCB->LayerGroups.len + 10; /* this out-of-range group might save a call */ + + if (pcb_layergrp_flags(PCB, group) & PCB_LYT_BOTTOM) + info.solder = rnd_true; + else { + info.solder = rnd_false; + pcb_layer_list(PCB, PCB_LYT_TOP | PCB_LYT_SILK, &comp, 1); + } + temp = length; + + /* assume the worst */ + best = 0.0; + ans.X = line1.Point1.X; + ans.Y = line1.Point1.Y; + while (length != last) { + last = length; + if (x_is_long) { + dx = SGN(dx) * length; + dy = end->Y - line1.Point1.Y; + length2 = coord_abs(dy); + } + else { + dy = SGN(dy) * length; + dx = end->X - line1.Point1.X; + length2 = coord_abs(dx); + } + temp2 = length2; + f2 = 1.0; + s2 = 0.5; + last2 = -1; + blocker = rnd_true; + while (length2 != last2) { + if (x_is_long) + dy = SGN(dy) * length2; + else + dx = SGN(dx) * length2; + two_lines = rnd_true; + if (coord_abs(dx) > coord_abs(dy) && x_is_long) { + line1.Point2.X = line1.Point1.X + (way ? SGN(dx) * coord_abs(dy) : dx - SGN(dx) * coord_abs(dy)); + line1.Point2.Y = line1.Point1.Y + (way ? dy : 0); + } + else if (coord_abs(dy) >= coord_abs(dx) && !x_is_long) { + line1.Point2.X = line1.Point1.X + (way ? dx : 0); + line1.Point2.Y = line1.Point1.Y + (way ? SGN(dy) * coord_abs(dx) : dy - SGN(dy) * coord_abs(dx)); + } + else if (x_is_long) { + /* we've changed which axis is long, so only do one line */ + line1.Point2.X = line1.Point1.X + dx; + line1.Point2.Y = line1.Point1.Y + (way ? SGN(dy) * coord_abs(dx) : 0); + two_lines = rnd_false; + } + else { + /* we've changed which axis is long, so only do one line */ + line1.Point2.Y = line1.Point1.Y + dy; + line1.Point2.X = line1.Point1.X + (way ? SGN(dx) * coord_abs(dy) : 0); + two_lines = rnd_false; + } + line2.Point1.X = line1.Point2.X; + line2.Point1.Y = line1.Point2.Y; + if (!two_lines) { + line2.Point2.Y = line1.Point2.Y; + line2.Point2.X = line1.Point2.X; + } + else { + line2.Point2.X = line1.Point1.X + dx; + line2.Point2.Y = line1.Point1.Y + dy; + } + pcb_line_bbox(&line1); + pcb_line_bbox(&line2); + last2 = length2; + if (setjmp(info.env) == 0) { + info.line = &line1; + rnd_r_search(PCB->Data->padstack_tree, &line1.BoundingBox, NULL, drcPstk_callback, &info, NULL); + if (two_lines) { + info.line = &line2; + rnd_r_search(PCB->Data->padstack_tree, &line2.BoundingBox, NULL, drcPstk_callback, &info, NULL); + } + PCB_COPPER_GROUP_LOOP(PCB->Data, group); + { + info.line = &line1; + rnd_r_search(layer->line_tree, &line1.BoundingBox, NULL, drcLine_callback, &info, NULL); + rnd_r_search(layer->arc_tree, &line1.BoundingBox, NULL, drcArc_callback, &info, NULL); + if (two_lines) { + info.line = &line2; + rnd_r_search(layer->line_tree, &line2.BoundingBox, NULL, drcLine_callback, &info, NULL); + rnd_r_search(layer->arc_tree, &line2.BoundingBox, NULL, drcArc_callback, &info, NULL); + } + } + PCB_END_LOOP; + /* no intersector! */ + blocker = rnd_false; + f2 += s2; + len = (line2.Point2.X - line1.Point1.X); + len *= len; + len += (double) (line2.Point2.Y - line1.Point1.Y) * (line2.Point2.Y - line1.Point1.Y); + if (len > best) { + best = len; + ans.X = line2.Point2.X; + ans.Y = line2.Point2.Y; + } +#if 0 + if (f2 > 1.0) + f2 = 0.5; +#endif + } + else { + /* bumped into something, back off */ + f2 -= s2; + } + s2 *= 0.5; + length2 = MIN(f2 * temp2, temp2); + } + if (!blocker && ((x_is_long && line2.Point2.X - line1.Point1.X == dx) + || (!x_is_long && line2.Point2.Y - line1.Point1.Y == dy))) + f += s; + else + f -= s; + s *= 0.5; + length = MIN(f * temp, temp); + if (!optimize) { + if (blocker) + best = -1; + else + best = length; + break; + } + } + + end->X = ans.X; + end->Y = ans.Y; + if (mid_out != NULL) { + mid_out->X = line1.Point2.X; + mid_out->Y = line1.Point2.Y; + } + return best; +} + +static void drc_line(rnd_point_t *end) +{ + struct drc_info info; + rnd_layergrp_id_t group, comp; + pcb_line_t line; + pcb_attached_line_t aline; + static rnd_point_t last_good; /* internal state of last good endpoint - we can do this cheat, because... */ + + /* ... we hardwire the assumption on how a line is drawn: it starts out as a 0 long segment, which is valid: */ + if ((pcb_crosshair.AttachedLine.Point1.X == pcb_crosshair.X) && (pcb_crosshair.AttachedLine.Point1.Y == pcb_crosshair.Y)) { + line.Point1 = line.Point2 = pcb_crosshair.AttachedLine.Point1; + goto auto_good; + } + + memset(&line, 0, sizeof(line)); + + /* check where the line wants to end */ + aline.Point1.X = pcb_crosshair.AttachedLine.Point1.X; + aline.Point1.Y = pcb_crosshair.AttachedLine.Point1.Y; + pcb_line_45(&aline); + line.parent_type = PCB_PARENT_LAYER; + line.parent.layer = PCB_CURRLAYER(PCB); + line.type = PCB_OBJ_LINE; + line.Point1 = aline.Point1; + line.Point2 = aline.Point2; + + /* prepare for the intersection search */ + group = pcb_layer_get_group(PCB, PCB_CURRLID(pcb)); + comp = PCB->LayerGroups.len + 10; /* this out-of-range group might save a call */ + if (pcb_layergrp_flags(PCB, group) & PCB_LYT_BOTTOM) + info.solder = rnd_true; + else { + info.solder = rnd_false; + pcb_layer_list(PCB, PCB_LYT_TOP | PCB_LYT_SILK, &comp, 1); + } + + /* search for intersection */ + pcb_line_bbox(&line); + if (setjmp(info.env) == 0) { + info.line = &line; + rnd_r_search(PCB->Data->padstack_tree, &line.BoundingBox, NULL, drcPstk_callback, &info, NULL); + PCB_COPPER_GROUP_LOOP(PCB->Data, group); + { + info.line = &line; + rnd_r_search(layer->line_tree, &line.BoundingBox, NULL, drcLine_callback, &info, NULL); + rnd_r_search(layer->arc_tree, &line.BoundingBox, NULL, drcArc_callback, &info, NULL); + } + PCB_END_LOOP; + /* no intersector! */ + auto_good:; + last_good.X = end->X = line.Point2.X; + last_good.Y = end->Y = line.Point2.Y; + return; + } + + /* bumped into ans */ + end->X = last_good.X; + end->Y = last_good.Y; +} + +void pcb_line_enforce_drc(pcb_board_t *pcb) +{ + rnd_point_t r45, rs, start; + rnd_bool shift; + double r1, r2; + + /* Silence a bogus compiler warning by storing this in a variable */ + rnd_layer_id_t layer_idx = PCB_CURRLID(pcb); + + if (rnd_gui->mod1_is_pressed(rnd_gui) || rnd_gui->control_is_pressed(rnd_gui) || PCB->RatDraw) + return; + + if (!(pcb_layer_flags(PCB, layer_idx) & PCB_LYT_COPPER)) + return; + + start.X = pcb_crosshair.AttachedLine.Point1.X; + start.Y = pcb_crosshair.AttachedLine.Point1.Y; + rs.X = r45.X = pcb_crosshair.X; + rs.Y = r45.Y = pcb_crosshair.Y; + + if (conf_core.editor.line_refraction != 0) { + /* first try starting straight */ + r1 = pcb_drc_lines(pcb, &start, &rs, NULL, rnd_false, rnd_true); + /* then try starting at 45 */ + r2 = pcb_drc_lines(pcb, &start, &r45, NULL, rnd_true, rnd_true); + } + else { + drc_line(&rs); + r45 = rs; +#define sqr(a) ((a) * (a)) + r1 = r2 = sqrt(sqr(rs.X - pcb_crosshair.AttachedLine.Point1.X) + sqr(rs.Y - pcb_crosshair.AttachedLine.Point1.Y)); +#undef sqr + } + /* shift forces the line lookahead path to refract the alternate way */ + shift = rnd_gui->shift_is_pressed(rnd_gui); + + if (RND_XOR(r1 > r2, shift)) { + if (conf_core.editor.line_refraction != 0) { + if (shift) { + if (conf_core.editor.line_refraction !=2) + rnd_conf_setf(RND_CFR_DESIGN, "editor/line_refraction", -1, "%d", 2); + } + else{ + if (conf_core.editor.line_refraction != 1) + rnd_conf_setf(RND_CFR_DESIGN, "editor/line_refraction", -1, "%d", 1); + } + } + pcb->hidlib.ch_x = pcb_crosshair.X = rs.X; + pcb->hidlib.ch_y = pcb_crosshair.Y = rs.Y; + } + else { + if (conf_core.editor.line_refraction !=0) { + if (shift) { + if (conf_core.editor.line_refraction != 1) + rnd_conf_setf(RND_CFR_DESIGN, "editor/line_refraction", -1, "%d", 1); + } + else { + if (conf_core.editor.line_refraction != 2) + rnd_conf_setf(RND_CFR_DESIGN, "editor/line_refraction", -1, "%d", 2); + } + } + pcb->hidlib.ch_x = pcb_crosshair.X = r45.X; + pcb->hidlib.ch_y = pcb_crosshair.Y = r45.Y; + } +} Index: tags/2.3.0/src/obj_line_list.c =================================================================== --- tags/2.3.0/src/obj_line_list.c (nonexistent) +++ tags/2.3.0/src/obj_line_list.c (revision 33253) @@ -0,0 +1,29 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#define TDL_DONT_UNDEF +#include "obj_line_list.h" +#include Index: tags/2.3.0/src/obj_line_list.h =================================================================== --- tags/2.3.0/src/obj_line_list.h (nonexistent) +++ tags/2.3.0/src/obj_line_list.h (revision 33253) @@ -0,0 +1,47 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_LINE_LIST_H +#define PCB_OBJ_LINE_LIST_H + +#include "obj_line.h" + +/* List of Lines */ +#define TDL(x) linelist_ ## x +#define TDL_LIST_T linelist_t +#define TDL_ITEM_T pcb_line_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define linelist_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + + +#include +#include + +#endif Index: tags/2.3.0/src/obj_line_op.h =================================================================== --- tags/2.3.0/src/obj_line_op.h (nonexistent) +++ tags/2.3.0/src/obj_line_op.h (revision 33253) @@ -0,0 +1,61 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard operations on line segments ***/ + +#include "operation.h" + +void *pcb_lineop_add_to_buffer(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_change_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_change_clear_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_change_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_set_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_clear_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_insert_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t * layer, pcb_line_t * line); +void *pcb_lineop_copy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_move(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_move_noclip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_clip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_move_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line, rnd_point_t *Point); +void *pcb_lineop_move_point_with_route(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line, rnd_point_t *Point); +void *pcb_lineop_move_to_layer_low(pcb_opctx_t *ctx, pcb_layer_t * Source, pcb_line_t * line, pcb_layer_t * Destination); +void *pcb_lineop_move_to_layer(pcb_opctx_t *ctx, pcb_layer_t * Layer, pcb_line_t * Line); +void *pcb_lineop_destroy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_remove_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line, rnd_point_t *Point); +void *pcb_lineop_remove(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_rotate90_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line, rnd_point_t *Point); +void *pcb_lineop_rotate90(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_rotate(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_change_flag(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_line_t *Line); +void *pcb_lineop_invalidate_label(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_line_t *line); +void *pcb_lineop_change_thermal(pcb_opctx_t *ctx, pcb_layer_t *ly, pcb_line_t *line); + + + + Index: tags/2.3.0/src/obj_pinvia_therm.c =================================================================== --- tags/2.3.0/src/obj_pinvia_therm.c (nonexistent) +++ tags/2.3.0/src/obj_pinvia_therm.c (revision 33253) @@ -0,0 +1,157 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2004,2006 Thomas Nau + * + * this file, thermal.c was written by and is + * (C) Copyright 2006, harry eaton + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* negative thermal finger polygons */ + +#include "config.h" + +#include +#include + +#include "board.h" +#include "polygon.h" +#include +#include "obj_pinvia_therm.h" + +static rnd_polyarea_t *pcb_pa_diag_line(rnd_coord_t X, rnd_coord_t Y, rnd_coord_t l, rnd_coord_t w, rnd_bool rt) +{ + rnd_pline_t *c; + rnd_vector_t v; + rnd_coord_t x1, x2, y1, y2; + + if (rt) { + x1 = (l - w) * M_SQRT1_2; + x2 = (l + w) * M_SQRT1_2; + y1 = x1; + y2 = x2; + } + else { + x2 = -(l - w) * M_SQRT1_2; + x1 = -(l + w) * M_SQRT1_2; + y1 = -x1; + y2 = -x2; + } + + v[0] = X + x1; + v[1] = Y + y2; + if ((c = rnd_poly_contour_new(v)) == NULL) + return NULL; + v[0] = X - x2; + v[1] = Y - y1; + rnd_poly_vertex_include(c->head->prev, rnd_poly_node_create(v)); + v[0] = X - x1; + v[1] = Y - y2; + rnd_poly_vertex_include(c->head->prev, rnd_poly_node_create(v)); + v[0] = X + x2; + v[1] = Y + y1; + rnd_poly_vertex_include(c->head->prev, rnd_poly_node_create(v)); + return rnd_poly_from_contour(c); +} + +/* ThermPoly returns a rnd_polyarea_t having all of the clearance that when + * subtracted from the plane create the desired thermal fingers. + * Usually this is 4 disjoint regions. + * + */ +rnd_polyarea_t *ThermPoly_(pcb_board_t *pcb, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t thickness, rnd_coord_t clearance, rnd_cardinal_t style) +{ + pcb_arc_t a; + rnd_polyarea_t *pa, *arc; + + /* must be circular */ + switch (style) { + case 1: + case 2: + { + rnd_polyarea_t *m; + rnd_coord_t t = (thickness + clearance) / 2; + rnd_coord_t w = 0.5 * pcb->ThermScale * clearance; + pa = rnd_poly_from_circle(cx, cy, t); + arc = rnd_poly_from_circle(cx, cy, thickness / 2); + /* create a thin ring */ + rnd_polyarea_boolean_free(pa, arc, &m, RND_PBO_SUB); + /* fix me needs error checking */ + if (style == 2) { + /* t is the theoretically required length, but we use twice that + * to avoid discretisation errors in our circle approximation. + */ + pa = rnd_poly_from_rect(cx - t * 2, cx + t * 2, cy - w, cy + w); + rnd_polyarea_boolean_free(m, pa, &arc, RND_PBO_SUB); + pa = rnd_poly_from_rect(cx - w, cx + w, cy - t * 2, cy + t * 2); + } + else { + /* t is the theoretically required length, but we use twice that + * to avoid discretisation errors in our circle approximation. + */ + pa = pcb_pa_diag_line(cx, cy, t * 2, w, rnd_true); + rnd_polyarea_boolean_free(m, pa, &arc, RND_PBO_SUB); + pa = pcb_pa_diag_line(cx, cy, t * 2, w, rnd_false); + } + rnd_polyarea_boolean_free(arc, pa, &m, RND_PBO_SUB); + return m; + } + + default: + a.X = cx; + a.Y = cy; + a.Height = a.Width = thickness / 2 + clearance / 4; + a.Thickness = 1; + a.Clearance = clearance / 2; + a.Flags = pcb_no_flags(); + a.Delta = 90 - (a.Clearance * (1. + 2. * pcb->ThermScale) * 180) / (M_PI * a.Width); + a.StartAngle = 90 - a.Delta / 2 + (style == 4 ? 0 : 45); + pa = pcb_poly_from_pcb_arc(&a, a.Clearance); + if (!pa) + return NULL; + a.StartAngle += 90; + arc = pcb_poly_from_pcb_arc(&a, a.Clearance); + if (!arc) + return NULL; + pa->f = arc; + arc->b = pa; + a.StartAngle += 90; + arc = pcb_poly_from_pcb_arc(&a, a.Clearance); + if (!arc) + return NULL; + pa->f->f = arc; + arc->b = pa->f; + a.StartAngle += 90; + arc = pcb_poly_from_pcb_arc(&a, a.Clearance); + if (!arc) + return NULL; + pa->b = arc; + pa->f->f->f = arc; + arc->b = pa->f->f; + arc->f = pa; + pa->b = arc; + return pa; + } +} Index: tags/2.3.0/src/obj_pinvia_therm.h =================================================================== --- tags/2.3.0/src/obj_pinvia_therm.h (nonexistent) +++ tags/2.3.0/src/obj_pinvia_therm.h (revision 33253) @@ -0,0 +1,39 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Thermal on padstacks are modified forms of the clearance cutout so that + the padstack has galvanic connection to the sorrunding polygon. */ +#ifndef PCB_PINVIA_THERMAL_H +#define PCB_PINVIA_THERMAL_H + +#include +#include "config.h" + +rnd_polyarea_t *ThermPoly_(pcb_board_t *p, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t thickness, rnd_coord_t clearance, rnd_cardinal_t style); + +#endif Index: tags/2.3.0/src/obj_poly.c =================================================================== --- tags/2.3.0/src/obj_poly.c (nonexistent) +++ tags/2.3.0/src/obj_poly.c (revision 33253) @@ -0,0 +1,1569 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Drawing primitive: polygons */ + + +#include "config.h" + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "polygon.h" +#include +#include +#include "rotate.h" +#include "search.h" +#include "thermal.h" +#include + +#include "conf_core.h" + +#include "obj_poly.h" +#include "obj_poly_op.h" +#include "obj_poly_list.h" +#include "obj_poly_draw.h" +#include "obj_term.h" + +#include "obj_subc_parent.h" +#include "obj_hash.h" + +#define STEP_POLYGONPOINT 10 +#define STEP_POLYGONHOLEINDEX 10 + +#include "obj_poly_draw_helper.c" + +/*** allocation ***/ + +void pcb_poly_reg(pcb_layer_t *layer, pcb_poly_t *poly) +{ + polylist_append(&layer->Polygon, poly); + PCB_SET_PARENT(poly, layer, layer); + + if (layer->parent_type == PCB_PARENT_UI) + return; + + if (layer->parent_type == PCB_PARENT_DATA) + pcb_obj_id_reg(layer->parent.data, poly); +} + +void pcb_poly_unreg(pcb_poly_t *poly) +{ + pcb_layer_t *layer = poly->parent.layer; + + pcb_term_del_auto((pcb_any_obj_t *)poly); + assert(poly->parent_type == PCB_PARENT_LAYER); + polylist_remove(poly); + if (layer->parent_type != PCB_PARENT_UI) { + assert(layer->parent_type == PCB_PARENT_DATA); + pcb_obj_id_del(layer->parent.data, poly); + } + PCB_SET_PARENT(poly, layer, NULL); +} + +pcb_poly_t *pcb_poly_alloc_id(pcb_layer_t *layer, long int id) +{ + pcb_poly_t *new_obj; + + new_obj = calloc(sizeof(pcb_poly_t), 1); + new_obj->ID = id; + new_obj->type = PCB_OBJ_POLY; + new_obj->Attributes.post_change = pcb_obj_attrib_post_change; + + pcb_poly_reg(layer, new_obj); + + return new_obj; +} + +pcb_poly_t *pcb_poly_alloc(pcb_layer_t *layer) +{ + return pcb_poly_alloc_id(layer, pcb_create_ID_get()); +} + + +void pcb_poly_free(pcb_poly_t *poly) +{ + if ((poly->parent.layer != NULL) && (poly->parent.layer->polygon_tree != NULL)) + rnd_r_delete_entry(poly->parent.layer->polygon_tree, (rnd_box_t *)poly); + pcb_attribute_free(&poly->Attributes); + pcb_poly_unreg(poly); + pcb_obj_common_free((pcb_any_obj_t *)poly); + free(poly); +} + +/* gets the next slot for a point in a polygon struct, allocates memory if necessary */ +rnd_point_t *pcb_poly_point_alloc(pcb_poly_t *Polygon) +{ + rnd_point_t *points = Polygon->Points; + + /* realloc new memory if necessary and clear it */ + if (Polygon->PointN >= Polygon->PointMax) { + Polygon->PointMax += STEP_POLYGONPOINT; + points = (rnd_point_t *) realloc(points, Polygon->PointMax * sizeof(rnd_point_t)); + Polygon->Points = points; + memset(points + Polygon->PointN, 0, STEP_POLYGONPOINT * sizeof(rnd_point_t)); + } + return (points + Polygon->PointN++); +} + +/* gets the next slot for a point in a polygon struct, allocates memory if necessary */ +rnd_cardinal_t *pcb_poly_holeidx_new(pcb_poly_t *Polygon) +{ + rnd_cardinal_t *holeindex = Polygon->HoleIndex; + + /* realloc new memory if necessary and clear it */ + if (Polygon->HoleIndexN >= Polygon->HoleIndexMax) { + Polygon->HoleIndexMax += STEP_POLYGONHOLEINDEX; + holeindex = (rnd_cardinal_t *) realloc(holeindex, Polygon->HoleIndexMax * sizeof(int)); + Polygon->HoleIndex = holeindex; + memset(holeindex + Polygon->HoleIndexN, 0, STEP_POLYGONHOLEINDEX * sizeof(int)); + } + return (holeindex + Polygon->HoleIndexN++); +} + +/* frees memory used by a polygon */ +void pcb_poly_free_fields(pcb_poly_t * polygon) +{ + pcb_parent_t parent; + pcb_parenttype_t parent_type; + + if (polygon == NULL) + return; + + free(polygon->Points); + free(polygon->HoleIndex); + + if (polygon->Clipped) + rnd_polyarea_free(&polygon->Clipped); + rnd_poly_contours_free(&polygon->NoHoles); + + /* have to preserve parent info for unreg */ + parent = polygon->parent; + parent_type = polygon->parent_type; + reset_obj_mem(pcb_poly_t, polygon); + polygon->parent = parent; + polygon->parent_type = parent_type; +} + +/*** utility ***/ + +/* rotates a polygon in 90 degree steps */ +void pcb_poly_rotate90(pcb_poly_t *Polygon, rnd_coord_t X, rnd_coord_t Y, unsigned Number) +{ + pcb_layer_t *layer = Polygon->parent.layer; + assert(Polygon->parent_type = PCB_PARENT_LAYER); + PCB_POLY_POINT_LOOP(Polygon); + { + RND_COORD_ROTATE90(point->X, point->Y, X, Y, Number); + } + PCB_END_LOOP; + + if (layer->parent_type == PCB_PARENT_DATA) + pcb_poly_init_clip(layer->parent.data, layer, Polygon); + /* simply rotating the bounding box here won't work, because the box is 'closed' (increased by 1) */ + pcb_poly_bbox(Polygon); +} + +void pcb_poly_rotate(pcb_layer_t *layer, pcb_poly_t *polygon, rnd_coord_t X, rnd_coord_t Y, double cosa, double sina) +{ + if (layer->polygon_tree != NULL) + rnd_r_delete_entry(layer->polygon_tree, (rnd_box_t *) polygon); + PCB_POLY_POINT_LOOP(polygon); + { + rnd_rotate(&point->X, &point->Y, X, Y, cosa, sina); + } + PCB_END_LOOP; + if (layer->parent_type == PCB_PARENT_DATA) + pcb_poly_init_clip(layer->parent.data, layer, polygon); + pcb_poly_bbox(polygon); + if (layer->polygon_tree != NULL) + rnd_r_insert_entry(layer->polygon_tree, (rnd_box_t *) polygon); +} + +int pcb_poly_is_valid(pcb_poly_t *p) +{ + rnd_pline_t *contour = NULL; + rnd_polyarea_t *np1 = NULL, *np = NULL; + rnd_cardinal_t n; + rnd_vector_t v; + int res = 1; + + np1 = np = rnd_polyarea_create(); + if (np == NULL) + return 0; + + /* first make initial polygon contour */ + for (n = 0; n < p->PointN; n++) { + /* No current contour? Make a new one starting at point */ + /* (or) Add point to existing contour */ + + v[0] = p->Points[n].X; + v[1] = p->Points[n].Y; + if (contour == NULL) { + if ((contour = rnd_poly_contour_new(v)) == NULL) + goto err; + } + else { + rnd_poly_vertex_include(contour->head->prev, rnd_poly_node_create(v)); + } + + /* Is current point last in contour? If so process it. */ + if (n == p->PointN - 1) { + rnd_poly_contour_pre(contour, rnd_true); + + if (contour->Count == 0) { + rnd_poly_contours_free(&contour); + goto err; + } + + { /* count number of not-on-the-same-line vertices to make sure there's more than 2*/ + rnd_vnode_t *cur; + int r = 0; + + cur = contour->head; + do { + r++; + } while ((cur = cur->next) != contour->head); + if (r < 3) { + rnd_poly_contours_free(&contour); + goto err; + } + } + + /* make sure it is a positive contour (outer) or negative (hole) */ + if (contour->Flags.orient != RND_PLF_DIR) { + rnd_poly_contour_inv(contour); + } + + rnd_polyarea_contour_include(np, contour); + if (contour->Count == 0) + goto err; + contour = NULL; + + if (!rnd_poly_valid(np)) + res = 0; + } + } + rnd_polyarea_free(&np1); + return res; + + err:; + rnd_polyarea_free(&np1); + return 0; +} + +/*** undoable mirror ***/ + +static const char core_poly_cookie[] = "core-poly"; + +typedef struct { + pcb_poly_t *poly; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + rnd_coord_t y_offs; +} undo_poly_mirror_t; + +static int undo_poly_mirror_swap(void *udata) +{ + undo_poly_mirror_t *g = udata; + pcb_layer_t *layer = g->poly->parent.layer; + + if (layer->polygon_tree != NULL) + rnd_r_delete_entry(layer->polygon_tree, (rnd_box_t *)g->poly); + PCB_POLY_POINT_LOOP(g->poly); + { + point->X = PCB_SWAP_X(point->X); + point->Y = PCB_SWAP_Y(point->Y) + g->y_offs; + } + PCB_END_LOOP; + if (layer->parent_type == PCB_PARENT_DATA) + pcb_poly_init_clip(layer->parent.data, layer, g->poly); + pcb_poly_bbox(g->poly); + if (layer->polygon_tree != NULL) + rnd_r_insert_entry(layer->polygon_tree, (rnd_box_t *)g->poly); + + return 0; +} + +static void undo_poly_mirror_print(void *udata, char *dst, size_t dst_len) +{ + undo_poly_mirror_t *g = udata; + rnd_snprintf(dst, dst_len, "poly mirror y=%$mm", g->y_offs); +} + +static const uundo_oper_t undo_poly_mirror = { + core_poly_cookie, + NULL, + undo_poly_mirror_swap, + undo_poly_mirror_swap, + undo_poly_mirror_print +}; + + +void pcb_poly_mirror(pcb_poly_t *poly, rnd_coord_t y_offs, rnd_bool undoable) +{ + undo_poly_mirror_t gtmp, *g = >mp; + + if (undoable) g = pcb_undo_alloc(pcb_data_get_top(poly->parent.layer->parent.data), &undo_poly_mirror, sizeof(undo_poly_mirror_t)); + + g->poly = poly; + g->y_offs = y_offs; + + undo_poly_mirror_swap(g); + if (undoable) pcb_undo_inc_serial(); +} + +void pcb_poly_flip_side(pcb_layer_t *layer, pcb_poly_t *polygon) +{ + rnd_r_delete_entry(layer->polygon_tree, (rnd_box_t *) polygon); + PCB_POLY_POINT_LOOP(polygon); + { + point->X = PCB_SWAP_X(point->X); + point->Y = PCB_SWAP_Y(point->Y); + } + PCB_END_LOOP; + if (layer->parent_type == PCB_PARENT_DATA) + pcb_poly_init_clip(layer->parent.data, layer, polygon); + pcb_poly_bbox(polygon); + rnd_r_insert_entry(layer->polygon_tree, (rnd_box_t *) polygon); + /* hmmm, how to handle clip */ +} + +void pcb_poly_scale(pcb_poly_t *poly, double sx, double sy) +{ + int onbrd = (poly->parent.layer != NULL) && (!poly->parent.layer->is_bound); + + if (onbrd) + pcb_poly_pre(poly); + PCB_POLY_POINT_LOOP(poly); + { + point->X = rnd_round((double)point->X * sx); + point->Y = rnd_round((double)point->Y * sy); + } + PCB_END_LOOP; + pcb_poly_bbox(poly); + if (onbrd) + pcb_poly_post(poly); +} + + +/* sets the bounding box of a polygons */ +void pcb_poly_bbox(pcb_poly_t *Polygon) +{ + Polygon->bbox_naked.X1 = Polygon->bbox_naked.Y1 = RND_MAX_COORD; + Polygon->bbox_naked.X2 = Polygon->bbox_naked.Y2 = -RND_MAX_COORD; + + PCB_POLY_POINT_LOOP(Polygon); + { + RND_MAKE_MIN(Polygon->bbox_naked.X1, point->X); + RND_MAKE_MIN(Polygon->bbox_naked.Y1, point->Y); + RND_MAKE_MAX(Polygon->bbox_naked.X2, point->X); + RND_MAKE_MAX(Polygon->bbox_naked.Y2, point->Y); + } + PCB_END_LOOP; + + /* clearance is generally considered to be part of the bbox for all objects */ + { + rnd_coord_t clr = PCB_POLY_HAS_CLEARANCE(Polygon) ? Polygon->Clearance/2 : 0; + Polygon->BoundingBox.X1 = Polygon->bbox_naked.X1 - clr; + Polygon->BoundingBox.Y1 = Polygon->bbox_naked.Y1 - clr; + Polygon->BoundingBox.X2 = Polygon->bbox_naked.X2 + clr; + Polygon->BoundingBox.Y2 = Polygon->bbox_naked.Y2 + clr; + } + + /* boxes don't include the lower right corner */ + rnd_close_box(&Polygon->bbox_naked); + rnd_close_box(&Polygon->BoundingBox); +} + +int pcb_poly_eq(const pcb_host_trans_t *tr1, const pcb_poly_t *p1, const pcb_host_trans_t *tr2, const pcb_poly_t *p2) +{ + if (p1->PointN != p2->PointN) return 0; + if (pcb_field_neq(p1, p2, Clearance)) return 0; + if (pcb_neqs(p1->term, p2->term)) return 0; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, p1) && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, p2)) { + rnd_cardinal_t n; + for(n = 0; n < p1->PointN; n++) { + rnd_coord_t x1, y1, x2, y2; + pcb_hash_tr_coords(tr1, &x1, &y1, p1->Points[n].X, p1->Points[n].Y); + pcb_hash_tr_coords(tr2, &x2, &y2, p2->Points[n].X, p2->Points[n].Y); + if ((x1 != x2) || (y1 != y2)) return 0; + } + } + return 1; +} + +unsigned int pcb_poly_hash(const pcb_host_trans_t *tr, const pcb_poly_t *p) +{ + unsigned int crd = 0; + rnd_cardinal_t n; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, p)) + for(n = 0; n < p->PointN; n++) { + rnd_coord_t x, y; + + pcb_hash_tr_coords(tr, &x, &y, p->Points[n].X, p->Points[n].Y); + crd ^= pcb_hash_coord(x) ^ pcb_hash_coord(y); + } + + return pcb_hash_coord(p->Clearance) ^ pcb_hash_str(p->term) ^ crd; +} + + +/* creates a new polygon from the old formats rectangle data */ +pcb_poly_t *pcb_poly_new_from_rectangle(pcb_layer_t *Layer, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Clearance, pcb_flag_t Flags) +{ + pcb_poly_t *polygon = pcb_poly_new(Layer, Clearance, Flags); + if (!polygon) + return polygon; + + pcb_poly_point_new(polygon, X1, Y1); + pcb_poly_point_new(polygon, X2, Y1); + pcb_poly_point_new(polygon, X2, Y2); + pcb_poly_point_new(polygon, X1, Y2); + + pcb_add_poly_on_layer(Layer, polygon); + return polygon; +} + +pcb_poly_t *pcb_poly_new_from_poly(pcb_layer_t *Layer, pcb_poly_t *src, rnd_coord_t offs, rnd_coord_t Clearance, pcb_flag_t Flags) +{ + rnd_coord_t x, y; + pcb_poly_it_t it; + rnd_pline_t *pl; + int go; + pcb_poly_t *polygon = pcb_poly_new(Layer, Clearance, Flags); + + if (!polygon) + return polygon; + + it.pa = src->Clipped; + pcb_poly_island_first(src, &it); + pl = pcb_poly_contour(&it); + it.cntr = rnd_pline_dup_offset(pl, offs); + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) + pcb_poly_point_new(polygon, x, y); + + rnd_poly_contours_free(&it.cntr); + + pcb_add_poly_on_layer(Layer, polygon); + return polygon; +} + + + +void pcb_add_poly_on_layer(pcb_layer_t *Layer, pcb_poly_t *polygon) +{ + pcb_poly_bbox(polygon); + if (!Layer->polygon_tree) + Layer->polygon_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) polygon); + PCB_SET_PARENT(polygon, layer, Layer); + pcb_poly_clear_from_poly(Layer->parent.data, PCB_OBJ_POLY, Layer, polygon); +} + +/* creates a new polygon on a layer */ +pcb_poly_t *pcb_poly_new(pcb_layer_t *Layer, rnd_coord_t Clearance, pcb_flag_t Flags) +{ + pcb_poly_t *polygon = pcb_poly_alloc(Layer); + + /* copy values */ + polygon->Flags = Flags; + + polygon->Clearance = Clearance; + polygon->Clipped = NULL; + polygon->NoHoles = NULL; + polygon->NoHolesValid = 0; + return polygon; +} + +static pcb_poly_t *pcb_poly_copy_meta(pcb_poly_t *dst, pcb_poly_t *src) +{ + if (dst == NULL) + return NULL; + pcb_attribute_copy_all(&dst->Attributes, &src->Attributes); + return dst; +} + +pcb_poly_t *pcb_poly_dup(pcb_layer_t *dst, pcb_poly_t *src) +{ + pcb_board_t *pcb; + pcb_poly_t *p = pcb_poly_new(dst, src->Clearance, src->Flags); + pcb_poly_copy(p, src, 0, 0); + pcb_add_poly_on_layer(dst, p); + pcb_poly_copy_meta(p, src); + + pcb = pcb_data_get_top(dst->parent.data); + if (pcb != NULL) + pcb_poly_init_clip(pcb->Data, dst, p); + return p; +} + +pcb_poly_t *pcb_poly_dup_at(pcb_layer_t *dst, pcb_poly_t *src, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_board_t *pcb; + pcb_poly_t *p = pcb_poly_new(dst, src->Clearance, src->Flags); + pcb_poly_copy(p, src, dx, dy); + pcb_add_poly_on_layer(dst, p); + pcb_poly_copy_meta(p, src); + + pcb = pcb_data_get_top(dst->parent.data); + if (pcb != NULL) + pcb_poly_init_clip(pcb->Data, dst, p); + return p; +} + +/* creates a new point in a polygon */ +rnd_point_t *pcb_poly_point_new(pcb_poly_t *Polygon, rnd_coord_t X, rnd_coord_t Y) +{ + rnd_point_t *point = pcb_poly_point_alloc(Polygon); + + /* copy values */ + point->X = X; + point->Y = Y; +TODO("ID: register points too") + point->ID = pcb_create_ID_get(); + return point; +} + +/* creates a new hole in a polygon */ +pcb_poly_t *pcb_poly_hole_new(pcb_poly_t * Polygon) +{ + rnd_cardinal_t *holeindex = pcb_poly_holeidx_new(Polygon); + *holeindex = Polygon->PointN; + return Polygon; +} + +/* copies data from one polygon to another; 'Dest' has to exist */ +pcb_poly_t *pcb_poly_copy(pcb_poly_t *Dest, pcb_poly_t *Src, rnd_coord_t dx, rnd_coord_t dy) +{ + rnd_cardinal_t hole = 0; + rnd_cardinal_t n; + + for (n = 0; n < Src->PointN; n++) { + if (hole < Src->HoleIndexN && n == Src->HoleIndex[hole]) { + pcb_poly_hole_new(Dest); + hole++; + } + pcb_poly_point_new(Dest, Src->Points[n].X+dx, Src->Points[n].Y+dy); + } + pcb_poly_bbox(Dest); + Dest->Flags = Src->Flags; + PCB_FLAG_CLEAR(PCB_FLAG_FOUND, Dest); + return Dest; +} + +static double poly_area(rnd_point_t *points, rnd_cardinal_t n_points) +{ + double area = 0; + int n; + + for(n = 1; n < n_points; n++) + area += (double)(points[n-1].X - points[n].X) * (double)(points[n-1].Y + points[n].Y); + area +=(double)(points[n_points-1].X - points[0].X) * (double)(points[n_points-1].Y + points[0].Y); + + if (area > 0) + area /= 2.0; + else + area /= -2.0; + + return area; +} + +double pcb_poly_area(const pcb_poly_t *poly) +{ + double area; + + if (poly->HoleIndexN > 0) { + int h; + area = poly_area(poly->Points, poly->HoleIndex[0]); + for(h = 0; h < poly->HoleIndexN - 1; h++) + area -= poly_area(poly->Points + poly->HoleIndex[h], poly->HoleIndex[h+1] - poly->HoleIndex[h]); + area -= poly_area(poly->Points + poly->HoleIndex[h], poly->PointN - poly->HoleIndex[h]); + } + else + area = poly_area(poly->Points, poly->PointN); + + return area; +} + + + +/*** ops ***/ + +/* copies a polygon to buffer */ +void *pcb_polyop_add_to_buffer(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + pcb_poly_t *polygon; + rnd_layer_id_t lid = pcb_layer_id(ctx->buffer.src, Layer); + pcb_layer_t *layer; + + /* the buffer may not have the specified layer, e.g. on loose subc subc-aux layer */ + if (lid == -1) + return NULL; + + layer = &ctx->buffer.dst->Layer[lid]; + + polygon = pcb_poly_new(layer, Polygon->Clearance, Polygon->Flags); + pcb_poly_copy(polygon, Polygon, 0, 0); + pcb_poly_copy_meta(polygon, Polygon); + if (ctx->buffer.keep_id) pcb_obj_change_id((pcb_any_obj_t *)polygon, Polygon->ID); + + /* Update the polygon r-tree. Unlike similarly named functions for + * other objects, CreateNewPolygon does not do this as it creates a + * skeleton polygon object, which won't have correct bounds. + */ + if (!layer->polygon_tree) + layer->polygon_tree = rnd_r_create_tree(); + rnd_r_insert_entry(layer->polygon_tree, (rnd_box_t *) polygon); + + PCB_FLAG_CLEAR(PCB_FLAG_FOUND | ctx->buffer.extraflg, polygon); + return polygon; +} + + +/* moves a polygon between board and buffer. Doesn't allocate memory for the points */ +void *pcb_polyop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t *dstly, pcb_poly_t *polygon) +{ + pcb_layer_t *srcly = polygon->parent.layer; + + assert(polygon->parent_type == PCB_PARENT_LAYER); + if ((dstly == NULL) || (dstly == srcly)) { /* auto layer in dst */ + rnd_layer_id_t lid = pcb_layer_id(ctx->buffer.src, srcly); + if (lid < 0) { + rnd_message(RND_MSG_ERROR, "Internal error: can't resolve source layer ID in pcb_polyop_move_buffer\n"); + return NULL; + } + dstly = &ctx->buffer.dst->Layer[lid]; + } + + pcb_poly_pprestore(polygon); + + rnd_r_delete_entry(srcly->polygon_tree, (rnd_box_t *)polygon); + + pcb_poly_unreg(polygon); + pcb_poly_reg(dstly, polygon); + + PCB_FLAG_CLEAR(PCB_FLAG_FOUND, polygon); + + if (!dstly->polygon_tree) + dstly->polygon_tree = rnd_r_create_tree(); + rnd_r_insert_entry(dstly->polygon_tree, (rnd_box_t *)polygon); + + pcb_poly_ppclear(polygon); + return polygon; +} + +void *pcb_polyop_change_thermal(pcb_opctx_t *ctx, pcb_layer_t *ly, pcb_poly_t *poly) +{ + return pcb_anyop_change_thermal(ctx, (pcb_any_obj_t *)poly); +} + +/* Handle attempts to change the clearance of a polygon. */ +void *pcb_polyop_change_clear_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *poly) +{ + if (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, poly)) { + rnd_coord_t value = (ctx->chgsize.is_absolute) ? ctx->chgsize.value : poly->Clearance + ctx->chgsize.value; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, poly)) + return NULL; + + value = MIN(PCB_MAX_THICKNESS, value); + if (!ctx->chgsize.is_absolute && ctx->chgsize.value < 0) + value = 0; + if (value != poly->Clearance) { + pcb_undo_add_obj_to_clear_size(PCB_OBJ_POLY, Layer, poly, poly); + pcb_poly_restore_to_poly(ctx->chgsize.pcb->Data, PCB_OBJ_POLY, Layer, poly); + pcb_poly_invalidate_erase(poly); + rnd_r_delete_entry(Layer->polygon_tree, (rnd_box_t *)poly); + poly->Clearance = value; + pcb_poly_bbox(poly); + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *)poly); + pcb_poly_clear_from_poly(ctx->chgsize.pcb->Data, PCB_OBJ_POLY, Layer, poly); + pcb_poly_invalidate_draw(Layer, poly); + return poly; + } + + return poly; + } + + /* poly does not clear other polys */ + rnd_message(RND_MSG_WARNING, + "To change the clearance of objects in a polygon, change \nthe objects, not the polygon.\n" + "Alternatively, set the clearpolypoly flag on the polygon to \nallow it to clear other polygons.\n" + "Hint: To set a minimum clearance for a group of objects, \nselect them all then :MinClearGap(Selected,=10,mil)\n", + "Ok", NULL); + + return NULL; +} + +/*** undoable enforce_clearance change ***/ +typedef struct { + pcb_data_t *data; + pcb_poly_t *poly; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + rnd_coord_t enfc; +} undo_poly_enfc_t; + +static int undo_poly_enfc_swap(void *udata) +{ + undo_poly_enfc_t *g = udata; + pcb_layer_t *layer = g->poly->parent.layer; + rnd_coord_t tmp; + + pcb_poly_restore_to_poly(g->data, PCB_OBJ_POLY, layer, g->poly); + pcb_poly_invalidate_erase(g->poly); + if (layer->polygon_tree != NULL) + rnd_r_delete_entry(layer->polygon_tree, (rnd_box_t *)g->poly); + tmp = g->poly->enforce_clearance; + g->poly->enforce_clearance = g->enfc; + g->enfc = tmp; + pcb_poly_bbox(g->poly); + if (layer->polygon_tree != NULL) + rnd_r_insert_entry(layer->polygon_tree, (rnd_box_t *)g->poly); + pcb_poly_clear_from_poly(g->data, PCB_OBJ_POLY, layer, g->poly); + if (layer->polygon_tree != NULL) + pcb_poly_invalidate_draw(layer, g->poly); + + return 0; +} + +static void undo_poly_enfc_print(void *udata, char *dst, size_t dst_len) +{ + undo_poly_enfc_t *g = udata; + rnd_snprintf(dst, dst_len, "poly enforce_clearance=%$mm", g->enfc); +} + +static const uundo_oper_t undo_poly_enfc = { + core_poly_cookie, + NULL, + undo_poly_enfc_swap, + undo_poly_enfc_swap, + undo_poly_enfc_print +}; + + + +/* Handle attempts to change the enforce_clearance of a polygon. */ +void *pcb_polyop_change_enforce_clear_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *poly) +{ + rnd_coord_t value = (ctx->chgsize.is_absolute) ? ctx->chgsize.value : poly->Clearance + ctx->chgsize.value; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, poly)) + return NULL; + + if (!ctx->chgsize.is_absolute && ctx->chgsize.value < 0) + value = 0; + if (value != poly->enforce_clearance) { + undo_poly_enfc_t *g = pcb_undo_alloc(pcb_data_get_top(poly->parent.layer->parent.data), &undo_poly_enfc, sizeof(undo_poly_enfc_t)); + + g->data = ctx->chgsize.pcb->Data; + g->poly = poly; + g->enfc = value; + + undo_poly_enfc_swap(g); + pcb_undo_inc_serial(); + + return poly; + } + + return poly; +} + +/* changes the CLEARPOLY flag of a polygon */ +void *pcb_polyop_change_clear(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Polygon)) + return NULL; + pcb_undo_add_obj_to_clear_poly(PCB_OBJ_POLY, Layer, Polygon, Polygon, rnd_true); + pcb_undo_add_obj_to_flag(Polygon); + PCB_FLAG_TOGGLE(PCB_FLAG_CLEARPOLY, Polygon); + pcb_poly_init_clip(PCB->Data, Layer, Polygon); + pcb_poly_invalidate_draw(Layer, Polygon); + return Polygon; +} + +/* inserts a point into a polygon */ +void *pcb_polyop_insert_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + rnd_point_t save; + rnd_cardinal_t n; + pcb_line_t line; + + pcb_poly_pprestore(Polygon); + + if (!ctx->insert.forcible) { + /* + * first make sure adding the point is sensible + */ + line.Thickness = 0; + line.Point1 = Polygon->Points[pcb_poly_contour_prev_point(Polygon, ctx->insert.idx)]; + line.Point2 = Polygon->Points[ctx->insert.idx]; + if (pcb_is_point_on_line((float) ctx->insert.x, (float) ctx->insert.y, 0.0, &line)) + return NULL; + } + /* + * second, shift the points up to make room for the new point + */ + pcb_poly_invalidate_erase(Polygon); + rnd_r_delete_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + save = *pcb_poly_point_new(Polygon, ctx->insert.x, ctx->insert.y); + for (n = Polygon->PointN - 1; n > ctx->insert.idx; n--) + Polygon->Points[n] = Polygon->Points[n - 1]; + + /* Shift up indices of any holes */ + for (n = 0; n < Polygon->HoleIndexN; n++) + if (Polygon->HoleIndex[n] > ctx->insert.idx || (ctx->insert.last && Polygon->HoleIndex[n] == ctx->insert.idx)) + Polygon->HoleIndex[n]++; + + Polygon->Points[ctx->insert.idx] = save; + pcb_board_set_changed_flag(PCB, rnd_true); + pcb_undo_add_obj_to_insert_point(PCB_OBJ_POLY_POINT, Layer, Polygon, &Polygon->Points[ctx->insert.idx]); + + pcb_poly_bbox(Polygon); + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + pcb_poly_init_clip(PCB->Data, Layer, Polygon); + if (ctx->insert.forcible || !pcb_poly_remove_excess_points(Layer, Polygon)) + pcb_poly_invalidate_draw(Layer, Polygon); + + pcb_poly_ppclear(Polygon); + + return (&Polygon->Points[ctx->insert.idx]); +} + +/* changes the clearance flag of a polygon */ +void *pcb_polyop_change_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *poly) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, poly)) + return NULL; + pcb_poly_invalidate_erase(poly); + if (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, poly)) { + pcb_undo_add_obj_to_clear_poly(PCB_OBJ_POLY, Layer, poly, poly, rnd_false); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_POLY, Layer, poly); + } + pcb_undo_add_obj_to_flag(poly); + PCB_FLAG_TOGGLE(PCB_FLAG_CLEARPOLYPOLY, poly); + if (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, poly)) { + pcb_undo_add_obj_to_clear_poly(PCB_OBJ_POLY, Layer, poly, poly, rnd_true); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_POLY, Layer, poly); + } + pcb_poly_invalidate_draw(Layer, poly); + return poly; +} + +/* low level routine to move a polygon */ +void pcb_poly_move(pcb_poly_t *Polygon, rnd_coord_t DX, rnd_coord_t DY) +{ + PCB_POLY_POINT_LOOP(Polygon); + { + RND_MOVE_POINT(point->X, point->Y, DX, DY); + } + PCB_END_LOOP; + RND_BOX_MOVE_LOWLEVEL(&Polygon->BoundingBox, DX, DY); + RND_BOX_MOVE_LOWLEVEL(&Polygon->bbox_naked, DX, DY); +} + +/* moves a polygon */ +void *pcb_polyop_move_noclip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + if (Layer->meta.real.vis) { + pcb_poly_invalidate_erase(Polygon); + } + pcb_poly_move(Polygon, ctx->move.dx, ctx->move.dy); + pcb_poly_init_clip(PCB->Data, Layer, Polygon); + if (Layer->meta.real.vis) + pcb_poly_invalidate_draw(Layer, Polygon); + return Polygon; +} + +void *pcb_polyop_move(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + rnd_r_delete_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + pcb_poly_pprestore(Polygon); + pcb_polyop_move_noclip(ctx, Layer, Polygon); + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + pcb_poly_ppclear(Polygon); + return Polygon; +} + +void *pcb_polyop_clip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + if (ctx->clip.restore) { + rnd_r_delete_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + pcb_poly_pprestore(Polygon); + } + if (ctx->clip.clear) { + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + pcb_poly_ppclear(Polygon); + } + return Polygon; +} +/* moves a polygon-point */ +void *pcb_polyop_move_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon, rnd_point_t *Point) +{ + pcb_poly_pprestore(Polygon); + if (Layer->meta.real.vis) { + pcb_poly_invalidate_erase(Polygon); + } + rnd_r_delete_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + RND_MOVE_POINT(Point->X, Point->Y, ctx->move.dx, ctx->move.dy); + pcb_poly_bbox(Polygon); + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + pcb_poly_remove_excess_points(Layer, Polygon); + pcb_poly_init_clip(PCB->Data, Layer, Polygon); + if (Layer->meta.real.vis) + pcb_poly_invalidate_draw(Layer, Polygon); + pcb_poly_ppclear(Polygon); + return Point; +} + +/* moves a polygon between layers; lowlevel routines */ +void *pcb_polyop_move_to_layer_low(pcb_opctx_t *ctx, pcb_layer_t * Source, pcb_poly_t * polygon, pcb_layer_t * Destination) +{ + rnd_r_delete_entry(Source->polygon_tree, (rnd_box_t *) polygon); + + pcb_poly_pprestore(polygon); + pcb_poly_unreg(polygon); + pcb_poly_reg(Destination, polygon); + + if (!Destination->polygon_tree) + Destination->polygon_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Destination->polygon_tree, (rnd_box_t *) polygon); + + pcb_poly_ppclear(polygon); + return polygon; +} + +/* moves a polygon between layers */ +void *pcb_polyop_move_to_layer(pcb_opctx_t *ctx, pcb_layer_t * Layer, pcb_poly_t * Polygon) +{ + pcb_poly_t *newone; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Polygon)) { + rnd_message(RND_MSG_WARNING, "Sorry, polygon object is locked\n"); + return NULL; + } + if (Layer == ctx->move.dst_layer) + return Polygon; + pcb_undo_add_obj_to_move_to_layer(PCB_OBJ_POLY, Layer, Polygon, Polygon); + if (Layer->meta.real.vis) + pcb_poly_invalidate_erase(Polygon); + + newone = (struct pcb_poly_s *) pcb_polyop_move_to_layer_low(ctx, Layer, Polygon, ctx->move.dst_layer); + pcb_poly_init_clip(PCB->Data, ctx->move.dst_layer, newone); + if (ctx->move.dst_layer->meta.real.vis) + pcb_poly_invalidate_draw(ctx->move.dst_layer, newone); + return newone; +} + + +/* destroys a polygon from a layer */ +void *pcb_polyop_destroy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + pcb_term_del_auto((pcb_any_obj_t *)Polygon); + rnd_r_delete_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + pcb_poly_free_fields(Polygon); + + pcb_poly_free(Polygon); + + return NULL; +} + +/* removes a polygon-point from a polygon and destroys the data */ +void *pcb_polyop_destroy_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon, rnd_point_t *Point) +{ + rnd_cardinal_t point_idx; + rnd_cardinal_t i; + rnd_cardinal_t contour; + rnd_cardinal_t contour_start, contour_end, contour_points; + + pcb_poly_pprestore(Polygon); + point_idx = pcb_poly_point_idx(Polygon, Point); + contour = pcb_poly_contour_point(Polygon, point_idx); + contour_start = (contour == 0) ? 0 : Polygon->HoleIndex[contour - 1]; + contour_end = (contour == Polygon->HoleIndexN) ? Polygon->PointN : Polygon->HoleIndex[contour]; + contour_points = contour_end - contour_start; + + if (contour_points <= 3) + return pcb_polyop_remove_counter(ctx, Layer, Polygon, contour); + + rnd_r_delete_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + + /* remove point from list, keep point order */ + for (i = point_idx; i < Polygon->PointN - 1; i++) + Polygon->Points[i] = Polygon->Points[i + 1]; + Polygon->PointN--; + + /* Shift down indices of any holes */ + for (i = 0; i < Polygon->HoleIndexN; i++) + if (Polygon->HoleIndex[i] > point_idx) + Polygon->HoleIndex[i]--; + + pcb_poly_bbox(Polygon); + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + pcb_poly_init_clip(PCB->Data, Layer, Polygon); + pcb_poly_ppclear(Polygon); + return Polygon; +} + +/* removes a polygon from a layer */ +void *pcb_polyop_remove(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + /* erase from screen */ + pcb_poly_pprestore(Polygon); + if (Layer->meta.real.vis) + pcb_poly_invalidate_erase(Polygon); + pcb_undo_move_obj_to_remove(PCB_OBJ_POLY, Layer, Polygon, Polygon); + return NULL; +} + +void *pcb_poly_remove(pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + void *res; + pcb_opctx_t ctx; + + ctx.remove.pcb = PCB; + ctx.remove.destroy_target = NULL; + + res = pcb_polyop_remove(&ctx, Layer, Polygon); + pcb_draw(); + return res; +} + +/* Removes a contour from a polygon. + If removing the outer contour, it removes the whole polygon. */ +void *pcb_polyop_remove_counter(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon, rnd_cardinal_t contour) +{ + rnd_cardinal_t contour_start, contour_end, contour_points; + rnd_cardinal_t i; + + if (contour == 0) + return pcb_poly_remove(Layer, Polygon); + + pcb_poly_pprestore(Polygon); + + if (Layer->meta.real.vis) + pcb_poly_invalidate_erase(Polygon); + + /* Copy the polygon to the undo list */ + pcb_undo_add_obj_to_remove_contour(PCB_OBJ_POLY, Layer, Polygon); + + contour_start = (contour == 0) ? 0 : Polygon->HoleIndex[contour - 1]; + contour_end = (contour == Polygon->HoleIndexN) ? Polygon->PointN : Polygon->HoleIndex[contour]; + contour_points = contour_end - contour_start; + + /* remove points from list, keep point order */ + for (i = contour_start; i < Polygon->PointN - contour_points; i++) + Polygon->Points[i] = Polygon->Points[i + contour_points]; + Polygon->PointN -= contour_points; + + /* remove hole from list and shift down remaining indices */ + for (i = contour; i < Polygon->HoleIndexN; i++) + Polygon->HoleIndex[i - 1] = Polygon->HoleIndex[i] - contour_points; + Polygon->HoleIndexN--; + + pcb_poly_init_clip(PCB->Data, Layer, Polygon); + + pcb_poly_ppclear(Polygon); + + /* redraw polygon if necessary */ + if (Layer->meta.real.vis) + pcb_poly_invalidate_draw(Layer, Polygon); + return NULL; +} + +/* removes a polygon-point from a polygon */ +void *pcb_polyop_remove_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon, rnd_point_t *Point) +{ + rnd_cardinal_t point_idx; + rnd_cardinal_t i; + rnd_cardinal_t contour; + rnd_cardinal_t contour_start, contour_end, contour_points; + + pcb_poly_pprestore(Polygon); + + point_idx = pcb_poly_point_idx(Polygon, Point); + contour = pcb_poly_contour_point(Polygon, point_idx); + contour_start = (contour == 0) ? 0 : Polygon->HoleIndex[contour - 1]; + contour_end = (contour == Polygon->HoleIndexN) ? Polygon->PointN : Polygon->HoleIndex[contour]; + contour_points = contour_end - contour_start; + + if (contour_points <= 3) + return pcb_polyop_remove_counter(ctx, Layer, Polygon, contour); + + if (Layer->meta.real.vis) + pcb_poly_invalidate_erase(Polygon); + + /* insert the polygon-point into the undo list */ + pcb_undo_add_obj_to_remove_point(PCB_OBJ_POLY_POINT, Layer, Polygon, point_idx); + rnd_r_delete_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + + /* remove point from list, keep point order */ + for (i = point_idx; i < Polygon->PointN - 1; i++) + Polygon->Points[i] = Polygon->Points[i + 1]; + Polygon->PointN--; + + /* Shift down indices of any holes */ + for (i = 0; i < Polygon->HoleIndexN; i++) + if (Polygon->HoleIndex[i] > point_idx) + Polygon->HoleIndex[i]--; + + pcb_poly_bbox(Polygon); + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + pcb_poly_remove_excess_points(Layer, Polygon); + pcb_poly_init_clip(PCB->Data, Layer, Polygon); + + /* redraw polygon if necessary */ + if (Layer->meta.real.vis) + pcb_poly_invalidate_draw(Layer, Polygon); + + pcb_poly_ppclear(Polygon); + return NULL; +} + +/* copies a polygon */ +void *pcb_polyop_copy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + pcb_poly_t *polygon; + + polygon = pcb_poly_new(Layer, Polygon->Clearance, pcb_no_flags()); + if (ctx->copy.keep_id) + polygon->ID = Polygon->ID; + pcb_poly_copy(polygon, Polygon, ctx->copy.DeltaX, ctx->copy.DeltaY); + pcb_poly_copy_meta(polygon, Polygon); + if (!Layer->polygon_tree) + Layer->polygon_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) polygon); + pcb_poly_init_clip(PCB->Data, Layer, polygon); + pcb_poly_invalidate_draw(Layer, polygon); + pcb_undo_add_obj_to_create(PCB_OBJ_POLY, Layer, polygon, polygon); + pcb_poly_ppclear(polygon); + return polygon; +} + +void *pcb_polyop_rotate90(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + pcb_poly_pprestore(Polygon); + if (Layer->meta.real.vis) + pcb_poly_invalidate_erase(Polygon); + if (Layer->polygon_tree != NULL) + rnd_r_delete_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + pcb_poly_rotate90(Polygon, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.number); + if (Layer->polygon_tree != NULL) + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + pcb_poly_init_clip(PCB->Data, Layer, Polygon); + if (Layer->meta.real.vis) + pcb_poly_invalidate_draw(Layer, Polygon); + pcb_poly_ppclear(Polygon); + return Polygon; +} + +void *pcb_polyop_rotate(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + pcb_poly_pprestore(Polygon); + if (Layer->meta.real.vis) + pcb_poly_invalidate_erase(Polygon); + pcb_poly_rotate(Layer, Polygon, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.cosa, ctx->rotate.sina); + pcb_poly_init_clip(PCB->Data, Layer, Polygon); + if (Layer->meta.real.vis) + pcb_poly_invalidate_draw(Layer, Polygon); + pcb_poly_ppclear(Polygon); + return Polygon; +} + +void *pcb_polyop_change_flag(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + static pcb_flag_values_t pcb_poly_flags = 0; + if (pcb_poly_flags == 0) + pcb_poly_flags = pcb_obj_valid_flags(PCB_OBJ_POLY); + + if ((ctx->chgflag.flag & pcb_poly_flags) != ctx->chgflag.flag) + return NULL; + if ((ctx->chgflag.flag & PCB_FLAG_TERMNAME) && (Polygon->term == NULL)) + return NULL; + pcb_undo_add_obj_to_flag(Polygon); + + + if (ctx->chgflag.flag & (PCB_FLAG_CLEARPOLY | PCB_FLAG_CLEARPOLYPOLY)) + pcb_poly_restore_to_poly(ctx->chgflag.pcb->Data, PCB_OBJ_POLY, Polygon->parent.layer, Polygon); + + PCB_FLAG_CHANGE(ctx->chgflag.how, ctx->chgflag.flag, Polygon); + + if (ctx->chgflag.flag & PCB_FLAG_FULLPOLY) + pcb_poly_init_clip(ctx->chgflag.pcb->Data, Polygon->parent.layer, Polygon); + + if (ctx->chgflag.flag & (PCB_FLAG_CLEARPOLY | PCB_FLAG_CLEARPOLYPOLY)) + pcb_poly_clear_from_poly(ctx->chgflag.pcb->Data, PCB_OBJ_POLY, Polygon->parent.layer, Polygon); + + return Polygon; +} + +void pcb_poly_pre(pcb_poly_t *poly) +{ + pcb_layer_t *ly = pcb_layer_get_real(poly->parent.layer); + if (ly == NULL) + return; + + pcb_poly_pprestore(poly); + if (ly->polygon_tree != NULL) + rnd_r_delete_entry(ly->polygon_tree, (rnd_box_t *)poly); +} + +void pcb_poly_post(pcb_poly_t *poly) +{ + pcb_layer_t *ly = pcb_layer_get_real(poly->parent.layer); + if (ly == NULL) + return; + + if (ly->polygon_tree != NULL) + rnd_r_insert_entry(ly->polygon_tree, (rnd_box_t *)poly); + pcb_poly_ppclear(poly); +} + + +/*** iteration helpers ***/ +void pcb_poly_map_contours(pcb_poly_t *p, void *ctx, pcb_poly_map_cb_t *cb) +{ + rnd_polyarea_t *pa; + rnd_pline_t *pl; + + pa = p->Clipped; + do { + int cidx; + for(cidx = 0, pl = pa->contours; pl != NULL; cidx++, pl = pl->next) { + rnd_vnode_t *v; + cb(p, ctx, (cidx == 0 ? PCB_POLYEV_ISLAND_START : PCB_POLYEV_HOLE_START), 0, 0); + v = pl->head->next; + do { + cb(p, ctx, (cidx == 0 ? PCB_POLYEV_ISLAND_POINT : PCB_POLYEV_HOLE_POINT), v->point[0], v->point[1]); + } while ((v = v->next) != pl->head->next); + + cb(p, ctx, (cidx == 0 ? PCB_POLYEV_ISLAND_END : PCB_POLYEV_HOLE_END), 0, 0); + } + pa = pa->f; + } while(pa != p->Clipped); +} + +void *pcb_polyop_invalidate_label(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_poly_t *poly) +{ + pcb_poly_name_invalidate_draw(poly); + return poly; +} + +/*** draw ***/ + +static rnd_bool is_poly_term_vert(const pcb_poly_t *poly) +{ + rnd_coord_t dx, dy; + + dx = poly->BoundingBox.X2 - poly->BoundingBox.X1; + if (dx < 0) + dx = -dx; + + dy = poly->BoundingBox.Y2 - poly->BoundingBox.Y1; + if (dy < 0) + dy = -dy; + + return dx < dy; +} + + +void pcb_poly_name_invalidate_draw(pcb_poly_t *poly) +{ + if (poly->term != NULL) { + pcb_term_label_invalidate((poly->BoundingBox.X1 + poly->BoundingBox.X2)/2, (poly->BoundingBox.Y1 + poly->BoundingBox.Y2)/2, + 100.0, is_poly_term_vert(poly), rnd_true, (pcb_any_obj_t *)poly); + } +} + +void pcb_poly_draw_label(pcb_draw_info_t *info, pcb_poly_t *poly, rnd_bool vis_side) +{ + if ((poly->term != NULL) && (vis_side)) + pcb_term_label_draw(info, (poly->BoundingBox.X1 + poly->BoundingBox.X2)/2, (poly->BoundingBox.Y1 + poly->BoundingBox.Y2)/2, + conf_core.appearance.term_label_size, is_poly_term_vert(poly), rnd_true, (pcb_any_obj_t *)poly); + + if (poly->noexport && vis_side) + pcb_obj_noexport_mark(poly, (poly->BoundingBox.X1 + poly->BoundingBox.X2)/2, (poly->BoundingBox.Y1 + poly->BoundingBox.Y2)/2); + + if (poly->ind_editpoint) { + long n; + pcb_obj_editpont_setup(); + for(n = 0; n < poly->PointN; n++) + pcb_obj_editpont_cross(poly->Points[n].X, poly->Points[n].Y); + } +} + +void pcb_poly_draw_annotation(pcb_draw_info_t *info, pcb_poly_t *poly) +{ + rnd_cardinal_t n, np; + + if (!conf_core.editor.as_drawn_poly) + return; + + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, poly)) + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.selected); + else + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.pin_name); + + rnd_hid_set_line_width(pcb_draw_out.fgGC, -1); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); + + if (poly->HoleIndexN > 0) + np = poly->HoleIndex[0]; + else + np = poly->PointN; + + for(n = 1; n < np; n++) + rnd_render->draw_line(pcb_draw_out.fgGC, poly->Points[n-1].X, poly->Points[n-1].Y, poly->Points[n].X, poly->Points[n].Y); + rnd_render->draw_line(pcb_draw_out.fgGC, poly->Points[n-1].X, poly->Points[n-1].Y, poly->Points[0].X, poly->Points[0].Y); +} + +static void pcb_poly_draw_tr_offs(pcb_poly_it_t *it, rnd_coord_t offs) +{ + int go; + long len, n; + rnd_coord_t x, y; + rnd_polo_t *p, p_st[256]; + + /* calculate length of the polyline */ + for(go = pcb_poly_vect_first(it, &x, &y), len = 0; go; go = pcb_poly_vect_next(it, &x, &y)) + len++; + + if (len >= sizeof(p_st) / sizeof(p_st[0])) + p = malloc(sizeof(rnd_polo_t) * len); + else + p = p_st; + + for(go = pcb_poly_vect_first(it, &x, &y), n = 0; go; go = pcb_poly_vect_next(it, &x, &y), n++) { + p[n].x = x; + p[n].y = y; + } + + rnd_polo_norms(p, len); + rnd_polo_offs(offs, p, len); + + + for(go = pcb_poly_vect_first(it, &x, &y), n = 0; go; go = pcb_poly_vect_next(it, &x, &y), n++) { + it->v->point[0] = rnd_round(p[n].x); + it->v->point[1] = rnd_round(p[n].y); + } + + if (p != p_st) + free(p); +} + +static pcb_poly_t *pcb_poly_draw_tr(pcb_draw_info_t *info, pcb_poly_t *polygon) +{ + pcb_poly_t *np = pcb_poly_alloc(polygon->parent.layer); + pcb_poly_it_t it; + rnd_polyarea_t *pa; + rnd_coord_t offs = info->xform->bloat / 2; + + pcb_poly_copy(np, polygon, 0, 0); + rnd_polyarea_copy0(&np->Clipped, polygon->Clipped); + + /* iterate over all islands of a polygon */ + for(pa = pcb_poly_island_first(np, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_pline_t *pl; + + /* check if we have a contour for the given island */ + pl = pcb_poly_contour(&it); + if (pl == NULL) + continue; + + /* iterate over the vectors of the contour */ + pcb_poly_draw_tr_offs(&it, offs); + + /* iterate over all holes within this island */ + for(pl = pcb_poly_hole_first(&it); pl != NULL; pl = pcb_poly_hole_next(&it)) + pcb_poly_draw_tr_offs(&it, offs); + } + + return np; +} + +void pcb_poly_draw_(pcb_draw_info_t *info, pcb_poly_t *polygon, int allow_term_gfx) +{ + pcb_poly_t *trpoly = NULL; + int draw_lab; + + if (delayed_terms_enabled && (polygon->term != NULL)) { + pcb_draw_delay_obj_add((pcb_any_obj_t *)polygon); + return; + } + + if (conf_core.editor.as_drawn_poly) + pcb_draw_annotation_add((pcb_any_obj_t *)polygon); + + if ((info != NULL) && (info->xform != NULL) && (info->xform->bloat != 0)) { + /* Slow dupping and recalculation every time; if we ever need this on-screen, we should cache */ + trpoly = pcb_poly_draw_tr(info, polygon); + polygon = trpoly; + } + + if ((info->xform->thin_draw || info->xform->thin_draw_poly || info->xform->wireframe)) + { + pcb_dhlp_thindraw_pcb_polygon(pcb_draw_out.fgGC, polygon, info->drawn_area); + } + else { + if ((allow_term_gfx) && pcb_draw_term_need_gfx(polygon) && pcb_draw_term_hid_permission()) { + rnd_vnode_t *n, *head; + int i; + pcb_dhlp_fill_pcb_polygon(pcb_draw_out.active_padGC, polygon, info->drawn_area); + head = polygon->Clipped->contours->head; + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_square); + for(n = head, i = 0; (n != head) || (i == 0); n = n->next, i++) { + rnd_coord_t x, y, r; + x = (n->prev->point[0] + n->point[0] + n->next->point[0]) / 3; + y = (n->prev->point[1] + n->point[1] + n->next->point[1]) / 3; + +TODO("subc: check if x;y is within the poly, but use a cheaper method than the official") + r = PCB_DRAW_TERM_GFX_WIDTH; + rnd_hid_set_line_width(pcb_draw_out.fgGC, r); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_square); + rnd_render->draw_line(pcb_draw_out.fgGC, x, y, x, y); + } + } + else + pcb_dhlp_fill_pcb_polygon(pcb_draw_out.fgGC, polygon, info->drawn_area); + } + + /* If checking planes, thin-draw any pieces which have been clipped away */ + if (info->xform->check_planes && !PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, polygon)) { + pcb_poly_t poly = *polygon; + + for (poly.Clipped = polygon->Clipped->f; poly.Clipped != polygon->Clipped; poly.Clipped = poly.Clipped->f) + pcb_dhlp_thindraw_pcb_polygon(pcb_draw_out.fgGC, &poly, info->drawn_area); + } + + draw_lab = (polygon->term != NULL) && ((pcb_draw_force_termlab) || PCB_FLAG_TEST(PCB_FLAG_TERMNAME, polygon)); + draw_lab |= polygon->ind_editpoint; + + if (draw_lab) + pcb_draw_delay_label_add((pcb_any_obj_t *)polygon); + + if (trpoly != NULL) + pcb_poly_free(trpoly); +} + +static void pcb_poly_draw(pcb_draw_info_t *info, pcb_poly_t *polygon, int allow_term_gfx) +{ + static const rnd_color_t *color; + rnd_color_t buf; + const pcb_layer_t *layer = info->layer != NULL ? info->layer : pcb_layer_get_real(polygon->parent.layer); + + pcb_obj_noexport(info, polygon, return); + + if (layer == NULL) /* if the layer is inbound, e.g. in preview, fall back using the layer recipe */ + layer = polygon->parent.layer; + + if (info->xform->flag_color && PCB_FLAG_TEST(PCB_FLAG_WARN, polygon)) + color = &conf_core.appearance.color.warn; + else if (info->xform->flag_color && PCB_FLAG_TEST(PCB_FLAG_SELECTED, polygon)) { + if (layer->is_bound) + PCB_OBJ_COLOR_ON_BOUND_LAYER(color, layer, 1); + else + color = &conf_core.appearance.color.selected; + } + else if (info->xform->flag_color && PCB_FLAG_TEST(PCB_FLAG_FOUND, polygon)) + color = &conf_core.appearance.color.connected; + else if (info->xform->flag_color && polygon->ind_onpoint) { + pcb_lighten_color(color, &buf, 1.75); + color = &buf; + } + else if (PCB_HAS_COLOROVERRIDE(polygon)) { + color = polygon->override_color; + } + else if (layer->is_bound) + PCB_OBJ_COLOR_ON_BOUND_LAYER(color, layer, 0); + else + color = &layer->meta.real.color; + rnd_render->set_color(pcb_draw_out.fgGC, color); + + pcb_poly_draw_(info, polygon, allow_term_gfx); +} + +rnd_r_dir_t pcb_poly_draw_callback(const rnd_box_t * b, void *cl) +{ + pcb_draw_info_t *i = cl; + pcb_poly_t *polygon = (pcb_poly_t *) b; + + if (pcb_hidden_floater((pcb_any_obj_t*)b, i) || pcb_partial_export((pcb_any_obj_t*)b, i)) + return RND_R_DIR_FOUND_CONTINUE; + + if (!polygon->Clipped) + return RND_R_DIR_NOT_FOUND; + + if (!PCB->SubcPartsOn && pcb_lobj_parent_subc(polygon->parent_type, &polygon->parent)) + return RND_R_DIR_NOT_FOUND; + + pcb_poly_draw(i, polygon, 0); + + return RND_R_DIR_FOUND_CONTINUE; +} + +rnd_r_dir_t pcb_poly_draw_term_callback(const rnd_box_t * b, void *cl) +{ + pcb_draw_info_t *i = cl; + pcb_poly_t *polygon = (pcb_poly_t *) b; + + if (pcb_hidden_floater((pcb_any_obj_t*)b, i) || pcb_partial_export((pcb_any_obj_t*)b, i)) + return RND_R_DIR_FOUND_CONTINUE; + + if (polygon->Clipped == NULL) { + /* if poly is cleared out of existence, it may still have some annotations + visible. Do it the cheap way: if it has term, it's not cleared, so the + only thing affected is the as-drawn contour */ + if (conf_core.editor.as_drawn_poly) + pcb_draw_annotation_add((pcb_any_obj_t *)polygon); + return RND_R_DIR_NOT_FOUND; + } + + if (!PCB->SubcPartsOn && pcb_lobj_parent_subc(polygon->parent_type, &polygon->parent)) + return RND_R_DIR_NOT_FOUND; + + pcb_poly_draw(i, polygon, 1); + + return RND_R_DIR_FOUND_CONTINUE; +} + +/* erases a polygon on a layer */ +void pcb_poly_invalidate_erase(pcb_poly_t *Polygon) +{ + pcb_draw_invalidate(Polygon); + pcb_flag_erase(&Polygon->Flags); +} + +void pcb_poly_invalidate_draw(pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + pcb_draw_invalidate(Polygon); +} + +void pcb_poly_uninit(void) +{ + pcb_dhlp_uninit(); +} Index: tags/2.3.0/src/obj_poly.h =================================================================== --- tags/2.3.0/src/obj_poly.h (nonexistent) +++ tags/2.3.0/src/obj_poly.h (revision 33253) @@ -0,0 +1,310 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Drawing primitive: polygons */ + +#ifndef PCB_OBJ_POLY_H +#define PCB_OBJ_POLY_H + +#include "config.h" +#include +#include "obj_common.h" +#include + +struct pcb_poly_s { /* holds information about a polygon */ + PCB_ANY_PRIMITIVE_FIELDS; + rnd_coord_t Clearance; + rnd_coord_t enforce_clearance; /* all objects within this polygon needs to have at least this much clearance; WARNING: true gap value, not *2 as with the Clearance fields */ + rnd_cardinal_t PointN; /* number of points in polygon */ + rnd_cardinal_t PointMax; /* max number from malloc() */ + rnd_polyarea_t *Clipped; /* the clipped region of this polygon */ + rnd_pline_t *NoHoles; /* the polygon broken into hole-less regions */ + int NoHolesValid; /* Is the NoHoles polygon up to date? */ + rnd_point_t *Points; /* data */ + rnd_cardinal_t *HoleIndex; /* Index of hole data within the Points array */ + rnd_cardinal_t HoleIndexN; /* number of holes in polygon */ + rnd_cardinal_t HoleIndexMax; /* max number from malloc() */ + unsigned clip_dirty:1; /* 1 if polygon should be reclipped after clipping inhibit is over */ + gdl_elem_t link; /* a poly is in a list of a layer */ +}; + + + +pcb_poly_t *pcb_poly_alloc(pcb_layer_t * layer); +pcb_poly_t *pcb_poly_alloc_id(pcb_layer_t *layer, long int id); +void pcb_poly_free(pcb_poly_t * data); +rnd_point_t *pcb_poly_point_alloc(pcb_poly_t *Polygon); +rnd_cardinal_t *pcb_poly_holeidx_new(pcb_poly_t *Polygon); +void pcb_poly_free_fields(pcb_poly_t * polygon); + +void pcb_poly_reg(pcb_layer_t *layer, pcb_poly_t *poly); +void pcb_poly_unreg(pcb_poly_t *poly); + +void pcb_poly_bbox(pcb_poly_t *Polygon); +pcb_poly_t *pcb_poly_new_from_rectangle(pcb_layer_t *Layer, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Clearance, pcb_flag_t Flags); +pcb_poly_t *pcb_poly_new_from_poly(pcb_layer_t *Layer, pcb_poly_t *src, rnd_coord_t offs, rnd_coord_t Clearance, pcb_flag_t Flags); +pcb_poly_t *pcb_poly_new(pcb_layer_t *Layer, rnd_coord_t Clearance, pcb_flag_t Flags); +pcb_poly_t *pcb_poly_dup(pcb_layer_t *dst, pcb_poly_t *src); +pcb_poly_t *pcb_poly_dup_at(pcb_layer_t *dst, pcb_poly_t *src, rnd_coord_t dx, rnd_coord_t dy); +rnd_point_t *pcb_poly_point_new(pcb_poly_t *Polygon, rnd_coord_t X, rnd_coord_t Y); +pcb_poly_t *pcb_poly_hole_new(pcb_poly_t * Polygon); +void *pcb_poly_remove(pcb_layer_t *Layer, pcb_poly_t *Polygon); + +void pcb_poly_rotate90(pcb_poly_t *Polygon, rnd_coord_t X, rnd_coord_t Y, unsigned Number); +void pcb_poly_rotate(pcb_layer_t *layer, pcb_poly_t *poly, rnd_coord_t X, rnd_coord_t Y, double cosa, double sina); +void pcb_poly_mirror(pcb_poly_t *polygon, rnd_coord_t y_offs, rnd_bool undoable); +void pcb_poly_flip_side(pcb_layer_t *layer, pcb_poly_t *polygon); +void pcb_poly_scale(pcb_poly_t *poly, double sx, double sy); + +void pcb_poly_move(pcb_poly_t *Polygon, rnd_coord_t DX, rnd_coord_t DY); +pcb_poly_t *pcb_poly_copy(pcb_poly_t *Dest, pcb_poly_t *Src, rnd_coord_t dx, rnd_coord_t dy); + +void pcb_poly_pre(pcb_poly_t *poly); +void pcb_poly_post(pcb_poly_t *poly); + +/* hash and eq */ +int pcb_poly_eq(const pcb_host_trans_t *tr1, const pcb_poly_t *p1, const pcb_host_trans_t *tr2, const pcb_poly_t *p2); +unsigned int pcb_poly_hash(const pcb_host_trans_t *tr, const pcb_poly_t *p); + +/* Add objects without creating them or making any "sanity modifications" to them */ +void pcb_add_poly_on_layer(pcb_layer_t *Layer, pcb_poly_t *polygon); + +double pcb_poly_area(const pcb_poly_t *poly); + +/* Returns whether p is valid, without ever asserting */ +int pcb_poly_is_valid(pcb_poly_t *p); + + +/* called from main.c to free some caches */ +void pcb_poly_uninit(void); + + +/*** helpers for iterating over countours */ + +/*** Polygon helpers on the clopped polygon ***/ +typedef enum { + PCB_POLYEV_ISLAND_START, + PCB_POLYEV_ISLAND_POINT, + PCB_POLYEV_ISLAND_END, + PCB_POLYEV_HOLE_START, + PCB_POLYEV_HOLE_POINT, + PCB_POLYEV_HOLE_END +} pcb_poly_event_t; + +/* return non-zero to quit mapping immediatley */ +typedef int pcb_poly_map_cb_t(pcb_poly_t *p, void *ctx, pcb_poly_event_t ev, rnd_coord_t x, rnd_coord_t y); + +/* call cb for each point of each island and cutout */ +void pcb_poly_map_contours(pcb_poly_t *p, void *ctx, pcb_poly_map_cb_t *cb); + +typedef struct pcb_poly_it_s { + const pcb_poly_t *p; + rnd_polyarea_t *pa; + rnd_pline_t *cntr; + rnd_vnode_t *v; +} pcb_poly_it_t; + +/* WARNING: if the poly is not a FULLPOLY, quit after the first island else + invisible islands are returned */ + +/* Set the iterator to the first island of the polygon; returns NULL if no contour available */ +RND_INLINE rnd_polyarea_t *pcb_poly_island_first(const pcb_poly_t *p, pcb_poly_it_t *it) +{ + it->p = p; + it->pa = p->Clipped; + it->cntr = NULL; + it->v = NULL; + return it->pa; +} + +/* Set the iterator to the next island of the polygon; returns NULL if no more */ +RND_INLINE rnd_polyarea_t *pcb_poly_island_next(pcb_poly_it_t *it) +{ + if (it->pa->f == it->p->Clipped) + return NULL; + it->pa = it->pa->f; + it->cntr = NULL; + it->v = NULL; + return it->pa; +} + +/* Set the iterator to trace the outer contour of the current island */ +RND_INLINE rnd_pline_t *pcb_poly_contour(pcb_poly_it_t *it) +{ + it->v = NULL; + return it->cntr = it->pa->contours; +} + +/* Set the iterator to trace the first hole of the current island; returns NULL if there are no holes */ +RND_INLINE rnd_pline_t *pcb_poly_hole_first(pcb_poly_it_t *it) +{ + it->v = NULL; + return it->cntr = it->pa->contours->next; +} + +/* Set the iterator to trace the next hole of the current island; returns NULL if there are were more holes */ +RND_INLINE rnd_pline_t *pcb_poly_hole_next(pcb_poly_it_t *it) +{ + it->v = NULL; + return it->cntr = it->cntr->next; +} + +/* Set the iterator to the first point of the last selected contour or hole; + read the coords into x,y; returns 1 on success, 0 if there are no points */ +RND_INLINE int pcb_poly_vect_first(pcb_poly_it_t *it, rnd_coord_t *x, rnd_coord_t *y) +{ + it->v = it->cntr->head->next; + if (it->v == NULL) + return 0; + *x = it->v->point[0]; + *y = it->v->point[1]; + return 1; +} + + +/* Set the iterator to the next point of the last selected contour or hole; + read the coords into x,y; returns 1 on success, 0 if there are were more points */ +RND_INLINE int pcb_poly_vect_next(pcb_poly_it_t *it, rnd_coord_t *x, rnd_coord_t *y) +{ + it->v = it->v->next; + if (it->v == it->cntr->head->next) + return 0; + *x = it->v->point[0]; + *y = it->v->point[1]; + return 1; +} + +/* read the previous contour/hole coords into x,y, without bumping the iterator */ +RND_INLINE void pcb_poly_vect_peek_prev(pcb_poly_it_t *it, rnd_coord_t *x, rnd_coord_t *y) +{ + *x = it->v->prev->point[0]; + *y = it->v->prev->point[1]; +} + +/* read the next contour/hole coords into x,y, without bumping the iterator */ +RND_INLINE void pcb_poly_vect_peek_next(pcb_poly_it_t *it, rnd_coord_t *x, rnd_coord_t *y) +{ + *x = it->v->next->point[0]; + *y = it->v->next->point[1]; +} + +/* Set the iterator to a polyarea*/ +RND_INLINE rnd_polyarea_t *pcb_poly_iterate_polyarea(rnd_polyarea_t *pa, pcb_poly_it_t *it) +{ + it->p = NULL; + it->pa = pa; + it->cntr = NULL; + it->v = NULL; + return it->pa; +} + +/* construct the full poly clearance cutout for the pa in the iterator and add + it to dst - implemented in polygon.c */ +void pcb_poly_pa_clearance_construct(rnd_polyarea_t **dst, pcb_poly_it_t *it, rnd_coord_t clearance); + + +#define pcb_poly_ppclear_at(poly, layer) \ +do { \ + if (layer->is_bound) layer = layer->meta.bound.real; \ + if (PCB_POLY_HAS_CLEARANCE(poly) && (layer != NULL)) \ + pcb_poly_clear_from_poly(layer->parent.data, PCB_OBJ_POLY, layer, poly); \ +} while(0) + +/* Let the poly clear sorrunding polys in its layer */ +#define pcb_poly_ppclear(poly) \ +do { \ + if (poly->parent.layer != NULL) { \ + pcb_layer_t *layer = pcb_layer_get_real(poly->parent.layer); \ + if ((layer != NULL) && (layer->parent.data->parent_type == PCB_PARENT_BOARD)) { \ + pcb_poly_ppclear_at(poly, layer); \ + } \ + } \ +} while(0) + +/* Let the poly restore sorrunding polys in its layer */ +#define pcb_poly_pprestore(poly) \ +do { \ + if (poly->parent.layer != NULL) { \ + pcb_layer_t *layer = pcb_layer_get_real(poly->parent.layer); \ + if ((layer != NULL) && (layer->parent.data->parent_type == PCB_PARENT_BOARD)) { \ + if (layer->is_bound) layer = layer->meta.bound.real; \ + if (PCB_POLY_HAS_CLEARANCE(poly) && (layer != NULL)) \ + pcb_poly_restore_to_poly(layer->parent.data, PCB_OBJ_POLY, layer, poly); \ + } \ + } \ +} while(0) + + + +/*** loops ***/ + +#define PCB_POLY_LOOP(layer) do { \ + pcb_poly_t *polygon; \ + gdl_iterator_t __it__; \ + linelist_foreach(&(layer)->Polygon, &__it__, polygon) { + +#define PCB_POLY_POINT_LOOP(polygon) do { \ + rnd_cardinal_t n; \ + rnd_point_t *point; \ + for (n = (polygon)->PointN-1; n != -1; n--) \ + { \ + point = &(polygon)->Points[n] + +#define PCB_POLY_ALL_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN) ; l++, layer++) \ + { \ + PCB_POLY_LOOP(layer) + +#define PCB_POLY_COPPER_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (!(pcb_layer_flags(PCB, l) & PCB_LYT_COPPER)) continue; \ + PCB_POLY_LOOP(layer) + +#define PCB_POLY_SILK_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (!(pcb_layer_flags(PCB, l) & PCB_LYT_SILK)) continue; \ + PCB_POLY_LOOP(layer) + +#define PCB_POLY_VISIBLE_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (layer->meta.real.vis) \ + PCB_POLY_LOOP(layer) + + +#endif Index: tags/2.3.0/src/obj_poly_draw.h =================================================================== --- tags/2.3.0/src/obj_poly_draw.h (nonexistent) +++ tags/2.3.0/src/obj_poly_draw.h (revision 33253) @@ -0,0 +1,45 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard draw of polygons ***/ + +#include "draw.h" + +/* Include rtree.h for these */ +#ifdef RND_RTREE_H +rnd_r_dir_t pcb_poly_draw_callback(const rnd_box_t * b, void *cl); +rnd_r_dir_t pcb_poly_draw_term_callback(const rnd_box_t * b, void *cl); +#endif + +void pcb_poly_invalidate_erase(pcb_poly_t *Polygon); +void pcb_poly_invalidate_draw(pcb_layer_t *Layer, pcb_poly_t *Polygon); +void pcb_poly_name_invalidate_draw(pcb_poly_t *poly); +void pcb_poly_draw_label(pcb_draw_info_t *info, pcb_poly_t *poly, rnd_bool vis_side); +void pcb_poly_draw_annotation(pcb_draw_info_t *info, pcb_poly_t *poly); + + Index: tags/2.3.0/src/obj_poly_draw_helper.c =================================================================== --- tags/2.3.0/src/obj_poly_draw_helper.c (nonexistent) +++ tags/2.3.0/src/obj_poly_draw_helper.c (revision 33253) @@ -0,0 +1,269 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2004 harry eaton + * Copyright (C) 2016..2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include +#include "polygon.h" +#include "obj_poly.h" +#include + +static rnd_coord_t *fc_x = NULL, *fc_y = NULL; +static size_t fc_alloced = 0; + + +/* call this before the loop */ +#define vert_opt_begin() \ + { \ + rnd_coord_t last_x, last_y, this_x, this_y, next_x, next_y, mindist; \ + last_x = pl->head->point[0]; \ + last_y = pl->head->point[1]; \ + v = pl->head->next; \ + mindist = rnd_render->coord_per_pix * 2; \ + +/* call this before drawing the next vertex */ +#define vert_opt_loop1(v, force, skip_stmt) \ + this_x = v->point[0]; \ + this_y = v->point[1]; \ + if ((!force) && (RND_ABS(this_x - last_x) < mindist) && (RND_ABS(this_y - last_y) < mindist)) { \ + next_x = v->next->point[0]; \ + next_y = v->next->point[1]; \ + if ((RND_ABS(this_x - next_x) < mindist) && (RND_ABS(this_y - next_y) < mindist)) \ + { skip_stmt; } \ + } \ + +/* call this after drawing the next vertex */ +#define vert_opt_loop2() \ + last_x = this_x; \ + last_y = this_y; \ + + +/* call this after the loop */ +#define vert_opt_end() \ + } + + +static void fill_contour(rnd_hid_gc_t gc, rnd_pline_t * pl) +{ + size_t n, i = 0; + rnd_vnode_t *v; + int first = 1; + + n = pl->Count; + + if (n > fc_alloced) { + free(fc_x); + free(fc_y); + fc_x = (rnd_coord_t *) malloc(n * sizeof(rnd_coord_t)); + fc_y = (rnd_coord_t *) malloc(n * sizeof(rnd_coord_t)); + fc_alloced = n; + } + + vert_opt_begin(); + do { + vert_opt_loop1(v, first, continue); + if (rnd_render->gui) + first = 0; /* if gui, turn on optimization and start to omit vertices */ + fc_x[i] = this_x; + fc_y[i++] = this_y; + vert_opt_loop2(); + } + while ((v = v->next) != pl->head->next); + + if (i < 3) { + rnd_hid_set_line_width(gc, RND_MM_TO_COORD(0.01)); + rnd_hid_set_line_cap(gc, rnd_cap_round); + rnd_render->draw_line(gc, last_x, last_y, this_x, this_y); + } + else + rnd_render->fill_polygon(gc, i, fc_x, fc_y); + + vert_opt_end(); +} + + +static void thindraw_contour(rnd_hid_gc_t gc, rnd_pline_t * pl) +{ + rnd_vnode_t *v; + + + rnd_hid_set_line_width(gc, 0); + rnd_hid_set_line_cap(gc, rnd_cap_round); + + /* If the contour is round, use an arc drawing routine. */ + if (pl->is_round) { + rnd_render->draw_arc(gc, pl->cx, pl->cy, pl->radius, pl->radius, 0, 360); + return; + } + + /* Need at least two points in the contour */ + if (pl->head->next == NULL) + return; + + vert_opt_begin(); + do { + vert_opt_loop1(v, 0, continue); + rnd_render->draw_line(gc, last_x, last_y, this_x, this_y); + vert_opt_loop2(); + } + while ((v = v->next) != pl->head->next); + vert_opt_end(); +} + +static void fill_contour_cb(rnd_pline_t * pl, void *user_data) +{ + rnd_hid_gc_t gc = (rnd_hid_gc_t) user_data; + rnd_pline_t *local_pl = pl; + + fill_contour(gc, pl); + rnd_poly_contours_free(&local_pl); +} + +static void fill_clipped_contour(rnd_hid_gc_t gc, rnd_pline_t * pl, const rnd_box_t * clip_box) +{ + rnd_pline_t *pl_copy; + rnd_polyarea_t *clip_poly; + rnd_polyarea_t *piece_poly; + rnd_polyarea_t *clipped_pieces; + rnd_polyarea_t *draw_piece; + int x; + + /* Optimization: the polygon has no holes; if it is smaller the clip_box, + it is safe to draw directly */ + if ((clip_box->X1 <= pl->xmin) && (clip_box->X2 >= pl->xmax) && (clip_box->Y1 <= pl->ymin) && (clip_box->Y2 >= pl->ymax)) { + fill_contour(gc, pl); + return; + } + + clip_poly = rnd_poly_from_rect(clip_box->X1, clip_box->X2, clip_box->Y1, clip_box->Y2); + rnd_poly_contour_copy(&pl_copy, pl); + piece_poly = rnd_polyarea_create(); + rnd_polyarea_contour_include(piece_poly, pl_copy); + x = rnd_polyarea_boolean_free(piece_poly, clip_poly, &clipped_pieces, RND_PBO_ISECT); + if (x != rnd_err_ok || clipped_pieces == NULL) + return; + + draw_piece = clipped_pieces; + do { + /* NB: The polygon won't have any holes in it */ + fill_contour(gc, draw_piece->contours); + } + while ((draw_piece = draw_piece->f) != clipped_pieces); + rnd_polyarea_free(&clipped_pieces); +} + +/* If at least 50% of the bounding box of the polygon is on the screen, + * lets compute the complete no-holes polygon. + */ +#define BOUNDS_INSIDE_CLIP_THRESHOLD 0.5 +static int should_compute_no_holes(pcb_poly_t * poly, const rnd_box_t * clip_box) +{ + rnd_coord_t x1, x2, y1, y2; + double poly_bounding_area; + double clipped_poly_area; + + /* If there is no passed clip box, compute the whole thing */ + if (clip_box == NULL) + return 1; + + x1 = MAX(poly->BoundingBox.X1, clip_box->X1); + x2 = MIN(poly->BoundingBox.X2, clip_box->X2); + y1 = MAX(poly->BoundingBox.Y1, clip_box->Y1); + y2 = MIN(poly->BoundingBox.Y2, clip_box->Y2); + + /* Check if the polygon is outside the clip box */ + if ((x2 <= x1) || (y2 <= y1)) + return 0; + + poly_bounding_area = (double) (poly->BoundingBox.X2 - poly->BoundingBox.X1) * + (double) (poly->BoundingBox.Y2 - poly->BoundingBox.Y1); + + clipped_poly_area = (double) (x2 - x1) * (double) (y2 - y1); + + if (clipped_poly_area / poly_bounding_area >= BOUNDS_INSIDE_CLIP_THRESHOLD) + return 1; + + return 0; +} + +#undef BOUNDS_INSIDE_CLIP_THRESHOLD + +static void pcb_dhlp_fill_pcb_polygon(rnd_hid_gc_t gc, pcb_poly_t * poly, const rnd_box_t * clip_box) +{ + if (!poly->NoHolesValid) { + /* If enough of the polygon is on-screen, compute the entire + * NoHoles version and cache it for later rendering, otherwise + * just compute what we need to render now. + */ + if (should_compute_no_holes(poly, clip_box)) + pcb_poly_compute_no_holes(poly); + else + pcb_poly_no_holes_dicer(poly, clip_box, fill_contour_cb, gc); + } + if (poly->NoHolesValid && poly->NoHoles) { + rnd_pline_t *pl; + + for (pl = poly->NoHoles; pl != NULL; pl = pl->next) { + if (clip_box == NULL) + fill_contour(gc, pl); + else + fill_clipped_contour(gc, pl, clip_box); + } + } + + /* Draw other parts of the polygon if fullpoly flag is set */ + /* NB: No "NoHoles" cache for these */ + if (PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, poly)) { + pcb_poly_t p = *poly; + + for (p.Clipped = poly->Clipped->f; p.Clipped != poly->Clipped; p.Clipped = p.Clipped->f) + pcb_poly_no_holes_dicer(&p, clip_box, fill_contour_cb, gc); + } +} + +static int thindraw_hole_cb(rnd_pline_t * pl, void *user_data) +{ + rnd_hid_gc_t gc = (rnd_hid_gc_t) user_data; + thindraw_contour(gc, pl); + return 0; +} + +static void pcb_dhlp_thindraw_pcb_polygon(rnd_hid_gc_t gc, pcb_poly_t * poly, const rnd_box_t * clip_box) +{ + thindraw_contour(gc, poly->Clipped->contours); + pcb_poly_holes(poly, clip_box, thindraw_hole_cb, gc); +} + +static void pcb_dhlp_uninit(void) +{ + free(fc_x); + free(fc_y); + fc_x = fc_y = NULL; + fc_alloced= 0; +} Index: tags/2.3.0/src/obj_poly_list.c =================================================================== --- tags/2.3.0/src/obj_poly_list.c (nonexistent) +++ tags/2.3.0/src/obj_poly_list.c (revision 33253) @@ -0,0 +1,29 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#define TDL_DONT_UNDEF +#include "obj_poly_list.h" +#include Index: tags/2.3.0/src/obj_poly_list.h =================================================================== --- tags/2.3.0/src/obj_poly_list.h (nonexistent) +++ tags/2.3.0/src/obj_poly_list.h (revision 33253) @@ -0,0 +1,47 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef LIST_POLY_H +#define LIST_POLY_H + +#include "obj_poly.h" + +/* List of Lines */ +#define TDL(x) polylist_ ## x +#define TDL_LIST_T polylist_t +#define TDL_ITEM_T pcb_poly_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define polylist_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + + +#include +#include + +#endif Index: tags/2.3.0/src/obj_poly_op.h =================================================================== --- tags/2.3.0/src/obj_poly_op.h (nonexistent) +++ tags/2.3.0/src/obj_poly_op.h (revision 33253) @@ -0,0 +1,56 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard operations on polygons ***/ + +#include "operation.h" + +void *pcb_polyop_add_to_buffer(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t * layer, pcb_poly_t * polygon); +void *pcb_polyop_change_clear_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *poly); +void *pcb_polyop_change_enforce_clear_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *poly); +void *pcb_polyop_change_clear(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_insert_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_move(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_move_noclip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_clip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_move_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon, rnd_point_t *Point); +void *pcb_polyop_move_to_layer_low(pcb_opctx_t *ctx, pcb_layer_t * Source, pcb_poly_t * polygon, pcb_layer_t * Destination); +void *pcb_polyop_move_to_layer(pcb_opctx_t *ctx, pcb_layer_t * Layer, pcb_poly_t * Polygon); +void *pcb_polyop_destroy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_destroy_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon, rnd_point_t *Point); +void *pcb_polyop_remove(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_remove_counter(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon, rnd_cardinal_t contour); +void *pcb_polyop_remove_point(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon, rnd_point_t *Point); +void *pcb_polyop_copy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_rotate90(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_rotate(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_change_flag(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *Polygon); +void *pcb_polyop_invalidate_label(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_poly_t *poly); +void *pcb_polyop_change_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_poly_t *poly); +void *pcb_polyop_change_thermal(pcb_opctx_t *ctx, pcb_layer_t *ly, pcb_poly_t *poly); Index: tags/2.3.0/src/obj_pstk.c =================================================================== --- tags/2.3.0/src/obj_pstk.c (nonexistent) +++ tags/2.3.0/src/obj_pstk.c (revision 33253) @@ -0,0 +1,1579 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include "board.h" +#include "conf_core.h" +#include "data.h" +#include "data_list.h" +#include "draw.h" +#include "draw_wireframe.h" +#include "flag.h" +#include "obj_pstk.h" +#include "obj_pstk_draw.h" +#include "obj_pstk_list.h" +#include "obj_pstk_inlines.h" +#include "obj_pstk_op.h" +#include "obj_subc_parent.h" +#include "obj_hash.h" +#include "operation.h" +#include "search.h" +#include "undo.h" +#include "vtpadstack.h" +#include "event.h" +#include +#include + +#define SQR(o) ((o)*(o)) + +static const char core_pstk_cookie[] = "padstack"; + +const pcb_proto_layer_t pcb_proto_layers[pcb_proto_num_layers] = { + {"top paste", PCB_LYT_TOP | PCB_LYT_PASTE, PCB_LYC_AUTO, {2,-1}, 0}, + {"top mask", PCB_LYT_TOP | PCB_LYT_MASK, PCB_LYC_SUB|PCB_LYC_AUTO, {2,-1}, PCB_PROTO_MASK_BLOAT}, + {"top copper", PCB_LYT_TOP | PCB_LYT_COPPER, 0, {4,3}, 0}, + {"any internal copper", PCB_LYT_INTERN | PCB_LYT_COPPER, 0, {2,4}, 0}, + {"bottom copper", PCB_LYT_BOTTOM | PCB_LYT_COPPER, 0, {2,3}, 0}, + {"bottom mask", PCB_LYT_BOTTOM | PCB_LYT_MASK, PCB_LYC_SUB|PCB_LYC_AUTO, {4,-1}, PCB_PROTO_MASK_BLOAT}, + {"bottom paste", PCB_LYT_BOTTOM | PCB_LYT_PASTE, PCB_LYC_AUTO, {4,-1}, 0}, + {"slot", PCB_LYT_MECH, PCB_LYC_AUTO, {-1,-1},0} +}; + + +void pcb_pstk_reg(pcb_data_t *data, pcb_pstk_t *pstk) +{ + padstacklist_append(&data->padstack, pstk); + pcb_obj_id_reg(data, pstk); + PCB_SET_PARENT(pstk, data, data); +} + +void pcb_pstk_unreg(pcb_pstk_t *pstk) +{ + pcb_data_t *data = pstk->parent.data; + assert(pstk->parent_type == PCB_PARENT_DATA); + padstacklist_remove(pstk); + pcb_obj_id_del(data, pstk); + PCB_CLEAR_PARENT(pstk); +} + +pcb_pstk_t *pcb_pstk_alloc_id(pcb_data_t *data, long int id) +{ + pcb_pstk_t *ps; + + ps = calloc(sizeof(pcb_pstk_t), 1); + ps->ID = id; + ps->protoi = -1; + ps->type = PCB_OBJ_PSTK; + ps->Attributes.post_change = pcb_obj_attrib_post_change; + + pcb_pstk_reg(data, ps); + + return ps; +} + +pcb_pstk_t *pcb_pstk_alloc(pcb_data_t *data) +{ + return pcb_pstk_alloc_id(data, pcb_create_ID_get()); +} + + +void pcb_pstk_free(pcb_pstk_t *ps) +{ + if ((ps->parent.data != NULL) && (ps->parent.data->padstack_tree != NULL)) + rnd_r_delete_entry(ps->parent.data->padstack_tree, (rnd_box_t *)ps); + pcb_attribute_free(&ps->Attributes); + pcb_pstk_unreg(ps); + free(ps->thermals.shape); + pcb_obj_common_free((pcb_any_obj_t *)ps); + free(ps); +} + +pcb_pstk_t *pcb_pstk_new_tr(pcb_data_t *data, long int id, rnd_cardinal_t proto, rnd_coord_t x, rnd_coord_t y, rnd_coord_t clearance, pcb_flag_t Flags, double rot, int xmirror, int smirror) +{ + pcb_pstk_t *ps; + + if (proto >= pcb_vtpadstack_proto_len(&data->ps_protos)) + return NULL; + + if (id <= 0) + id = pcb_create_ID_get(); + + ps = pcb_pstk_alloc_id(data, id); + + /* copy values */ + ps->proto = proto; + ps->x = x; + ps->y = y; + ps->Clearance = clearance; + ps->Flags = Flags; + ps->rot = rot; + ps->xmirror = xmirror; + ps->smirror = smirror; + pcb_pstk_add(data, ps); + rnd_event(&PCB->hidlib, PCB_EVENT_NEW_PSTK, "p", ps); + pcb_poly_clear_from_poly(data, PCB_OBJ_PSTK, NULL, ps); + return ps; +} + +pcb_pstk_t *pcb_pstk_new(pcb_data_t *data, long int id, rnd_cardinal_t proto, rnd_coord_t x, rnd_coord_t y, rnd_coord_t clearance, pcb_flag_t Flags) +{ + return pcb_pstk_new_tr(data, id, proto, x, y, clearance, Flags, 0, 0, 0); +} + + +void pcb_pstk_add(pcb_data_t *data, pcb_pstk_t *ps) +{ + pcb_pstk_bbox(ps); + if (!data->padstack_tree) + data->padstack_tree = rnd_r_create_tree(); + rnd_r_insert_entry(data->padstack_tree, (rnd_box_t *)ps); + PCB_SET_PARENT(ps, data, data); +} + +static void pcb_pstk_bbox_(rnd_box_t *dst, pcb_pstk_t *ps, rnd_bool copper_only) +{ + int n, sn; + pcb_line_t line; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + pcb_pstk_tshape_t *ts = pcb_pstk_get_tshape(ps); + assert(proto != NULL); + + dst->X1 = dst->X2 = ps->x; + dst->Y1 = dst->Y2 = ps->y; + + if (ts != NULL) + for(sn = 0; sn < ts->len; sn++) { + pcb_pstk_shape_t *shape = ts->shape + sn; + switch(shape->shape) { + case PCB_PSSH_POLY: + for(n = 0; n < shape->data.poly.len; n++) + rnd_box_bump_point(dst, shape->data.poly.x[n] + ps->x, shape->data.poly.y[n] + ps->y); + break; + case PCB_PSSH_LINE: + line.Point1.X = shape->data.line.x1 + ps->x; + line.Point1.Y = shape->data.line.y1 + ps->y; + line.Point2.X = shape->data.line.x2 + ps->x; + line.Point2.Y = shape->data.line.y2 + ps->y; + line.Thickness = shape->data.line.thickness; + line.Clearance = 0; + line.Flags = pcb_flag_make(shape->data.line.square ? PCB_FLAG_SQUARE : 0); + pcb_line_bbox(&line); + rnd_box_bump_box(dst, &line.BoundingBox); + break; + case PCB_PSSH_CIRC: + rnd_box_bump_point(dst, ps->x - shape->data.circ.dia/2, ps->y - shape->data.circ.dia/2); + rnd_box_bump_point(dst, ps->x + shape->data.circ.dia/2, ps->y + shape->data.circ.dia/2); + break; + case PCB_PSSH_HSHADOW: + break; + } + } + + if (!copper_only && PCB_NONPOLY_HAS_CLEARANCE(ps)) { + dst->X1 -= ps->Clearance; + dst->Y1 -= ps->Clearance; + dst->X2 += ps->Clearance; + dst->Y2 += ps->Clearance; + } + + if (proto->hdia != 0) { + /* corner case: no copper around the hole all 360 deg - let the hole stick out */ + rnd_box_bump_point(dst, ps->x - proto->hdia/2, ps->y - proto->hdia/2); + rnd_box_bump_point(dst, ps->x + proto->hdia/2, ps->y + proto->hdia/2); + } + + rnd_close_box(dst); +} + +void pcb_pstk_bbox(pcb_pstk_t *ps) +{ + pcb_pstk_bbox_(&ps->BoundingBox, ps, rnd_false); + pcb_pstk_bbox_(&ps->bbox_naked, ps, rnd_true); +} + +void pcb_pstk_copper_bbox(rnd_box_t *dst, pcb_pstk_t *ps) +{ + pcb_pstk_bbox_(dst, ps, rnd_true); +} + +/* hash */ +int pcb_pstk_eq(const pcb_host_trans_t *tr1, const pcb_pstk_t *p1, const pcb_host_trans_t *tr2, const pcb_pstk_t *p2) +{ + double rotdir1 = tr1->on_bottom ? -1.0 : 1.0, rotdir2 = tr2->on_bottom ? -1.0 : 1.0; + +TODO("padstack: should compare shape by shape: a 180 deg rotated or mirrored rectangle is still just the same rectangle!") + + if ((p1->smirror ^ tr1->on_bottom) != (p2->smirror ^ tr2->on_bottom)) return 0; + if ((p1->xmirror ^ tr1->on_bottom) != (p2->xmirror ^ tr2->on_bottom)) return 0; + if (floor(fmod((p1->rot * rotdir1) + tr1->rot, 360.0)*10000) != floor(fmod((p2->rot * rotdir2) + tr2->rot, 360.0)*10000)) return 0; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, p1) && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, p2)) { + rnd_coord_t x1, y1, x2, y2; + + pcb_hash_tr_coords(tr1, &x1, &y1, p1->x, p1->y); + pcb_hash_tr_coords(tr2, &x2, &y2, p2->x, p2->y); + if ((x1 != x2) || (y1 != y2)) return 0; + } + + if (pcb_neqs(p1->term, p2->term)) return 0; + return 1; +} + +unsigned int pcb_pstk_hash(const pcb_host_trans_t *tr, const pcb_pstk_t *p) +{ + unsigned int crd = 0; + double rotdir = tr->on_bottom ? -1.0 : 1.0; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, p)) { + rnd_coord_t x, y; + + pcb_hash_tr_coords(tr, &x, &y, p->x, p->y); + crd = pcb_hash_coord(x) ^ pcb_hash_coord(y); + } + + return pcb_hash_angle(tr, p->rot * rotdir) ^ pcb_hash_coord(p->Clearance) ^ + pcb_hash_str(p->term) ^ crd ^ + murmurhash(&p->smirror, sizeof(p->smirror)) ^ + murmurhash(&p->xmirror, sizeof(p->xmirror)); +} + +/*** utils ***/ + +pcb_pstk_t *pcb_pstk_copy_meta(pcb_pstk_t *dst, pcb_pstk_t *src) +{ + if (dst == NULL) + return NULL; + pcb_attribute_copy_all(&dst->Attributes, &src->Attributes); + dst->thermals.used = src->thermals.used; + if (dst->thermals.used > 0) { + dst->thermals.shape = malloc(dst->thermals.used * sizeof(dst->thermals.shape[0])); + memcpy(dst->thermals.shape, src->thermals.shape, src->thermals.used * sizeof(src->thermals.shape[0])); + } + else + dst->thermals.shape = 0; + memcpy(&dst->Flags, &src->Flags, sizeof(dst->Flags)); + return dst; +} + +pcb_pstk_t *pcb_pstk_copy_orient(pcb_pstk_t *dst, pcb_pstk_t *src) +{ + if (dst == NULL) + return NULL; + dst->rot = src->rot; + dst->xmirror = src->xmirror; + dst->smirror = src->smirror; + dst->protoi = -1; /* invalidate the transformed index to get it recalculated */ + return dst; +} + +void pcb_pstk_move_(pcb_pstk_t *ps, rnd_coord_t dx, rnd_coord_t dy) +{ + ps->x += dx; + ps->y += dy; + ps->BoundingBox.X1 += dx; + ps->BoundingBox.Y1 += dy; + ps->BoundingBox.X2 += dx; + ps->BoundingBox.Y2 += dy; + ps->bbox_naked.X1 += dx; + ps->bbox_naked.Y1 += dy; + ps->bbox_naked.X2 += dx; + ps->bbox_naked.Y2 += dy; +} + +void pcb_pstk_move(pcb_pstk_t *ps, rnd_coord_t dx, rnd_coord_t dy, rnd_bool more_to_come) +{ + pcb_opctx_t ctx; + ctx.move.pcb = NULL; + ctx.move.dx = dx; + ctx.move.dy = dy; + ctx.move.more_to_come = more_to_come; + pcb_pstkop_move(&ctx, ps); +} + +pcb_pstk_t *pcb_pstk_by_id(pcb_data_t *base, long int ID) +{ + /* We can not have an rtree based search here: we are often called + in the middle of an operation, after the pstk got already removed + from the rtree. It happens in e.g. undoable padstack operations + where the padstack tries to look up its parent subc by ID, while + the subc is being sent to the other side. + + The solution will be the ID hash. */ + PCB_PADSTACK_LOOP(base); + { + if (padstack->ID == ID) + return padstack; + } + PCB_END_LOOP; + + return NULL; +} + +/*** draw ***/ + +static void set_ps_color(pcb_pstk_t *ps, int is_current, pcb_layer_type_t lyt, const pcb_layer_t *ly1, rnd_xform_t *xform) +{ + const rnd_color_t *color, *layer_color = NULL; + rnd_color_t buf; + + if ((lyt & PCB_LYT_PASTE) || (lyt & PCB_LYT_MASK) || (lyt & PCB_LYT_SILK)) { + if (ly1 == NULL) + layer_color = pcb_layer_default_color(0, lyt); + else + layer_color = &ly1->meta.real.color; + } + + if (xform->invis_other_groups && !is_current) { + color = &conf_core.appearance.color.invisible_objects; + } + else if (xform->black_current_group && is_current) { + color = rnd_color_black; + } + else if (ps->term == NULL) { + /* normal via, not a terminal */ + if (xform->flag_color && !pcb_draw_force_termlab && PCB_FLAG_TEST(PCB_FLAG_WARN | PCB_FLAG_SELECTED | PCB_FLAG_FOUND, ps)) { + if (PCB_FLAG_TEST(PCB_FLAG_WARN, ps)) + color = &conf_core.appearance.color.warn; + else if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, ps)) + color = &conf_core.appearance.color.selected; + else + color = &conf_core.appearance.color.connected; + + if (ps->ind_onpoint) { + pcb_lighten_color(color, &buf, 1.75); + color = &buf; + } + } + else { + if (layer_color != NULL) + color = layer_color; + else if (PCB_HAS_COLOROVERRIDE(ps)) + color = ps->override_color; + else if (is_current) + color = &conf_core.appearance.color.via; + else + color = &conf_core.appearance.color.via_far; + } + } + else { + /* terminal */ + if (xform->flag_color && !pcb_draw_force_termlab && PCB_FLAG_TEST(PCB_FLAG_WARN | PCB_FLAG_SELECTED | PCB_FLAG_FOUND, ps)) { + if (PCB_FLAG_TEST(PCB_FLAG_WARN, ps)) + color = &conf_core.appearance.color.warn; + else if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, ps)) + color = &conf_core.appearance.color.selected; + else + color = &conf_core.appearance.color.connected; + + if (ps->ind_onpoint) { + pcb_lighten_color(color, &buf, 1.75); + color = &buf; + } + } + else + if (layer_color != NULL) + color = layer_color; + else if (PCB_HAS_COLOROVERRIDE(ps)) + color = ps->override_color; + else if (is_current) + color = &conf_core.appearance.color.pin; + else + color = &conf_core.appearance.color.pin_far; + + } + + rnd_render->set_color(pcb_draw_out.fgGC, color); +} + +static void set_ps_annot_color(rnd_hid_gc_t gc, pcb_pstk_t *ps) +{ + rnd_render->set_color(pcb_draw_out.fgGC, PCB_FLAG_TEST(PCB_FLAG_SELECTED, ps) ? + &conf_core.appearance.color.selected : &conf_core.appearance.color.padstackmark); +} + +static void pcb_pstk_draw_poly(pcb_draw_info_t *info, rnd_hid_gc_t gc, pcb_pstk_t *ps, pcb_pstk_shape_t *shape, int fill, rnd_coord_t dthick) +{ + long n; + + if (shape->data.poly.pa == NULL) + pcb_pstk_shape_update_pa(&shape->data.poly); + rnd_hid_set_line_cap(gc, rnd_cap_round); + if (dthick != 0) { + /* slow - but would be used on export mostly, not on-screen drawing */ + rnd_polo_t *p, p_st[32]; + rnd_coord_t *x, *y, xy_st[64]; + double vl = rnd_round(-dthick/2); + long n; + + if (shape->data.poly.inverted) + dthick = -dthick; + vl = rnd_round(dthick/2); + + if (shape->data.poly.len >= sizeof(p_st) / sizeof(p_st[0])) { + p = malloc(sizeof(rnd_polo_t) * shape->data.poly.len); + x = malloc(sizeof(rnd_coord_t) * shape->data.poly.len); + } + else { + p = p_st; + x = xy_st; + } + y = x + sizeof(p_st) / sizeof(p_st[0]); + + /* relative: move each point radially */ + for(n = 0; n < shape->data.poly.len; n++) { + p[n].x = shape->data.poly.x[n]; + p[n].y = shape->data.poly.y[n]; + } + rnd_polo_norms(p, shape->data.poly.len); + rnd_polo_offs(vl, p, shape->data.poly.len); + for(n = 0; n < shape->data.poly.len; n++) { + x[n] = rnd_round(p[n].x); + y[n] = rnd_round(p[n].y); + } + + if (!fill) { + for(n = 1; n < shape->data.poly.len; n++) + rnd_render->draw_line(gc, ps->x + x[n-1], ps->y + y[n-1], ps->x + x[n], ps->y + y[n]); + rnd_render->draw_line(gc, ps->x + x[n-1], ps->y + y[n-1], ps->x + x[0], ps->y + y[0]); + } + else + rnd_render->fill_polygon_offs(gc, shape->data.poly.len, x, y, ps->x, ps->y); + if (p != p_st) { + free(p); + free(x); + } + } + else { + if (!fill) { + for(n = 1; n < shape->data.poly.len; n++) + rnd_render->draw_line(gc, ps->x + shape->data.poly.x[n-1], ps->y + shape->data.poly.y[n-1], ps->x + shape->data.poly.x[n], ps->y + shape->data.poly.y[n]); + rnd_render->draw_line(gc, ps->x + shape->data.poly.x[n-1], ps->y + shape->data.poly.y[n-1], ps->x + shape->data.poly.x[0], ps->y + shape->data.poly.y[0]); + } + else + rnd_render->fill_polygon_offs(gc, shape->data.poly.len, shape->data.poly.x, shape->data.poly.y, ps->x, ps->y); + } +} + +static void pcb_pstk_draw_shape_solid(pcb_draw_info_t *info, rnd_hid_gc_t gc, pcb_pstk_t *ps, pcb_pstk_shape_t *shape) +{ + rnd_coord_t r, dthick = 0; + if ((info != NULL) && (info->xform != NULL) && (info->xform->bloat != 0)) + dthick = info->xform->bloat; + + switch(shape->shape) { + case PCB_PSSH_POLY: + pcb_pstk_draw_poly(info, gc, ps, shape, 1, dthick); + break; + case PCB_PSSH_LINE: + rnd_hid_set_line_cap(gc, shape->data.line.square ? rnd_cap_square : rnd_cap_round); + rnd_hid_set_line_width(gc, MAX(shape->data.line.thickness + dthick, 1)); + rnd_render->draw_line(gc, ps->x + shape->data.line.x1, ps->y + shape->data.line.y1, ps->x + shape->data.line.x2, ps->y + shape->data.line.y2); + break; + case PCB_PSSH_CIRC: + r = MAX(shape->data.circ.dia/2 + dthick/2, 1); + rnd_hid_set_line_cap(gc, rnd_cap_round); + rnd_render->fill_circle(gc, ps->x + shape->data.circ.x, ps->y + shape->data.circ.y, r); + break; + case PCB_PSSH_HSHADOW: + break; + } +} + +static void pcb_pstk_draw_shape_thin(pcb_draw_info_t *info, rnd_hid_gc_t gc, pcb_pstk_t *ps, pcb_pstk_shape_t *shape) +{ + rnd_coord_t r, dthick = 0; + rnd_hid_set_line_cap(gc, rnd_cap_round); + + if ((info != NULL) && (info->xform != NULL) && (info->xform->bloat != 0)) + dthick = info->xform->bloat; + + switch(shape->shape) { + case PCB_PSSH_POLY: + pcb_pstk_draw_poly(info, gc, ps, shape, 0, dthick); + break; + case PCB_PSSH_LINE: + pcb_draw_wireframe_line(gc, ps->x + shape->data.line.x1, ps->y + shape->data.line.y1, ps->x + shape->data.line.x2, ps->y + shape->data.line.y2, MAX(shape->data.line.thickness + dthick, 1), shape->data.line.square); + break; + case PCB_PSSH_CIRC: + r = MAX(shape->data.circ.dia/2 + dthick/2, 1); + rnd_render->draw_arc(gc, ps->x + shape->data.circ.x, ps->y + shape->data.circ.y, r, r, 0, 360); + break; + case PCB_PSSH_HSHADOW: + break; + } +} + +rnd_r_dir_t pcb_pstk_draw_callback(const rnd_box_t *b, void *cl) +{ + pcb_draw_info_t *info = cl; + pcb_pstk_t *ps = (pcb_pstk_t *)b; + pcb_pstk_shape_t *shape; + pcb_layergrp_t *grp = NULL; + + pcb_obj_noexport(info, ps, return RND_R_DIR_NOT_FOUND); + + if (pcb_hidden_floater((pcb_any_obj_t*)b, info) || pcb_partial_export((pcb_any_obj_t*)b, info)) + return RND_R_DIR_FOUND_CONTINUE; + + if (!PCB->SubcPartsOn && pcb_gobj_parent_subc(ps->parent_type, &ps->parent)) + return RND_R_DIR_NOT_FOUND; + + if (info->objcb.pstk.gid < 0) { + if (info->objcb.pstk.shape_mask != 0) + shape = pcb_pstk_shape(ps, info->objcb.pstk.shape_mask, info->objcb.pstk.comb); + else + return RND_R_DIR_NOT_FOUND; + } + else { + int n; + rnd_layer_id_t *lid; + shape = pcb_pstk_shape_gid(info->pcb, ps, info->objcb.pstk.gid, info->objcb.pstk.comb, &grp); + for(n = 0, lid = grp->lid; n < grp->len; n++,lid++) { + if (*lid < ps->thermals.used) { + if ((ps->thermals.shape[*lid] & PCB_THERMAL_ON) && ((ps->thermals.shape[*lid] & 3) == PCB_THERMAL_NOSHAPE)) + return RND_R_DIR_NOT_FOUND; + } + } + } + + if (shape != NULL) { + if (grp == NULL) + set_ps_color(ps, info->objcb.pstk.is_current, info->objcb.pstk.shape_mask, info->objcb.pstk.layer1, info->xform); + else + set_ps_color(ps, info->objcb.pstk.is_current, grp->ltype, info->objcb.pstk.layer1, info->xform); + if (info->xform->thin_draw || info->xform->wireframe) { + rnd_hid_set_line_width(pcb_draw_out.fgGC, 0); + pcb_pstk_draw_shape_thin(info, pcb_draw_out.fgGC, ps, shape); + } + else + pcb_pstk_draw_shape_solid(info, pcb_draw_out.fgGC, ps, shape); + } + + if (ps->ind_editpoint) + pcb_draw_delay_label_add((pcb_any_obj_t *)ps); + + return RND_R_DIR_FOUND_CONTINUE; +} + +rnd_r_dir_t pcb_pstk_draw_mark_callback(const rnd_box_t *b, void *cl) +{ + pcb_pstk_t *ps = (pcb_pstk_t *)b; + pcb_pstk_proto_t *proto; + rnd_coord_t mark, mark2; + + /* mark is a cross in the middle, right on the hole; + cross size should extend beyond the hole */ + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_round); + mark = conf_core.appearance.padstack.cross_size; + proto = pcb_pstk_get_proto(ps); + if (proto != NULL) + mark += proto->hdia/2; + + mark2 = mark*2; + if (mark2 < rnd_render->coord_per_pix) + return RND_R_DIR_FOUND_CONTINUE; + + /* draw the cross using xor */ + set_ps_annot_color(pcb_draw_out.fgGC, ps); + rnd_hid_set_line_width(pcb_draw_out.fgGC, 0); + if (mark2 > rnd_render->coord_per_pix*3) { + rnd_render->draw_line(pcb_draw_out.fgGC, ps->x-mark, ps->y, ps->x+mark, ps->y); + rnd_render->draw_line(pcb_draw_out.fgGC, ps->x, ps->y-mark, ps->x, ps->y+mark); + } + else + rnd_render->draw_line(pcb_draw_out.fgGC, ps->x-rnd_render->coord_per_pix, ps->y, ps->x+rnd_render->coord_per_pix, ps->y); + + return RND_R_DIR_FOUND_CONTINUE; +} + +rnd_r_dir_t pcb_pstk_draw_label_callback(const rnd_box_t *b, void *cl) +{ + pcb_draw_info_t *info = cl; + pcb_pstk_t *ps = (pcb_pstk_t *)b; + + /* draw the label if enabled, after everything else is drawn */ + if (ps->term != NULL) { + if ((pcb_draw_force_termlab) || PCB_FLAG_TEST(PCB_FLAG_TERMNAME, ps)) + pcb_pstk_draw_label(info, ps, 1); + } + + if (ps->noexport) + pcb_obj_noexport_mark(ps, ps->x, ps->y); + + return RND_R_DIR_FOUND_CONTINUE; +} + +rnd_r_dir_t pcb_pstk_draw_hole_callback(const rnd_box_t *b, void *cl) +{ + pcb_draw_info_t *info = cl; + pcb_pstk_t *ps = (pcb_pstk_t *)b; + pcb_pstk_proto_t *proto; + + pcb_obj_noexport(info, ps, return RND_R_DIR_NOT_FOUND); + + if (pcb_hidden_floater(ps, info) || pcb_partial_export(ps, info)) + return RND_R_DIR_FOUND_CONTINUE; + + /* hide subc parts if requested */ + if (!info->pcb->SubcPartsOn && pcb_gobj_parent_subc(ps->parent_type, &ps->parent)) + return RND_R_DIR_NOT_FOUND; + + /* no hole in this layer group */ + if (info->objcb.pstk.gid >= 0) { + if (!pcb_pstk_bb_drills(info->pcb, ps, info->objcb.pstk.gid, &proto)) + return RND_R_DIR_FOUND_CONTINUE; + } + else + proto = pcb_pstk_get_proto(ps); + + /* No hole at all */ + if ((proto == NULL) || (proto->hdia <= 0)) + return RND_R_DIR_NOT_FOUND; + + /* hole is plated, but the caller doesn't want plated holes */ + if (proto->hplated && (!(info->objcb.pstk.holetype & PCB_PHOLE_PLATED))) + return RND_R_DIR_NOT_FOUND; + + /* hole is unplated, but the caller doesn't want unplated holes */ + if (!proto->hplated && (!(info->objcb.pstk.holetype & PCB_PHOLE_UNPLATED))) + return RND_R_DIR_NOT_FOUND; + + /* BBvia, but the caller doesn't want BBvias */ + if (((proto->htop != 0) || (proto->hbottom != 0)) && (!(info->objcb.pstk.holetype & PCB_PHOLE_BB))) + return RND_R_DIR_NOT_FOUND; + + /* actual hole */ + rnd_hid_set_line_width(pcb_draw_out.drillGC, 0); + rnd_hid_set_line_cap(pcb_draw_out.drillGC, rnd_cap_round); + rnd_render->fill_circle(pcb_draw_out.drillGC, ps->x, ps->y, proto->hdia / 2); + + /* indicate unplated holes with an arc; unplated holes are more rare + than plated holes, thus unplated holes are indicated */ + if (!proto->hplated && !pcb_xform_omit_overlay(info)) { + rnd_coord_t r = proto->hdia / 2; + r -= r/8; /* +12.5% */ + rnd_render->set_color(pcb_draw_out.fgGC, PCB_FLAG_TEST(PCB_FLAG_SELECTED, ps) ? &conf_core.appearance.color.selected : &conf_core.appearance.color.subc); + rnd_hid_set_line_width(pcb_draw_out.fgGC, 0); + rnd_render->draw_arc(pcb_draw_out.fgGC, ps->x, ps->y, r, r, 20, 290); + } + + return RND_R_DIR_FOUND_CONTINUE; +} + +rnd_r_dir_t pcb_pstk_draw_slot_callback(const rnd_box_t *b, void *cl) +{ + pcb_draw_info_t *info = cl; + pcb_pstk_t *ps = (pcb_pstk_t *)b; + pcb_pstk_proto_t *proto; + pcb_pstk_shape_t *shape; + + pcb_obj_noexport(info, ps, return RND_R_DIR_NOT_FOUND); + + if (pcb_hidden_floater(ps, info) || pcb_partial_export(ps, info)) + return RND_R_DIR_FOUND_CONTINUE; + + /* hide subc parts if requested */ + if (!info->pcb->SubcPartsOn && pcb_gobj_parent_subc(ps->parent_type, &ps->parent)) + return RND_R_DIR_NOT_FOUND; + + /* no slot in this layer group */ + if (info->objcb.pstk.gid >= 0) { + if (!pcb_pstk_bb_drills(info->pcb, ps, info->objcb.pstk.gid, &proto)) + return RND_R_DIR_FOUND_CONTINUE; + } + else + proto = pcb_pstk_get_proto(ps); + + /* No slot at all */ + if (proto->mech_idx < 0) + return RND_R_DIR_NOT_FOUND; + + /* hole is plated, but the caller doesn't want plated holes */ + if (proto->hplated && (!(info->objcb.pstk.holetype & PCB_PHOLE_PLATED))) + return RND_R_DIR_NOT_FOUND; + + /* hole is unplated, but the caller doesn't want unplated holes */ + if (!proto->hplated && (!(info->objcb.pstk.holetype & PCB_PHOLE_UNPLATED))) + return RND_R_DIR_NOT_FOUND; + + /* BBslot, but the caller doesn't want BBslot */ + if (((proto->htop != 0) || (proto->hbottom != 0)) && (!(info->objcb.pstk.holetype & PCB_PHOLE_BB))) + return RND_R_DIR_NOT_FOUND; + + /* actual slot */ + shape = pcb_pstk_shape(ps, PCB_LYT_MECH, PCB_LYC_AUTO); + if (shape != NULL) { + if (info->xform->thin_draw || info->xform->wireframe) { + rnd_hid_set_line_width(pcb_draw_out.drillGC, 0); + pcb_pstk_draw_shape_thin(info, pcb_draw_out.drillGC, ps, shape); + } + else + pcb_pstk_draw_shape_solid(info, pcb_draw_out.drillGC, ps, shape); + } + + return RND_R_DIR_FOUND_CONTINUE; +} + +void pcb_pstk_thindraw(pcb_draw_info_t *info, rnd_hid_gc_t gc, pcb_pstk_t *ps) +{ + pcb_pstk_shape_t *shape = NULL; + pcb_board_t *pcb; + rnd_layergrp_id_t gid = PCB_CURRLAYER(PCB)->meta.real.grp; + + pcb = pcb_data_get_top(ps->parent.data); + if (pcb != NULL) { + shape = pcb_pstk_shape_gid(pcb, ps, gid, 0, NULL); + if (shape == NULL) + shape = pcb_pstk_shape_gid(pcb, ps, gid, PCB_LYC_SUB, NULL); + } + else { /* no pcb means buffer - take the first shape, whichever layer it is for */ + pcb_pstk_tshape_t *ts = pcb_pstk_get_tshape(ps); + if ((ts != NULL) && (ts->len > 0)) + shape = ts->shape; + } + + if (shape != NULL) + pcb_pstk_draw_shape_thin(info, gc, ps, shape); +} + +void pcb_pstk_draw_label(pcb_draw_info_t *info, pcb_pstk_t *ps, rnd_bool vis_side) +{ + rnd_bool vert; + rnd_coord_t dx, dy; + + if (ps->term == NULL) + return; + + dx = ps->BoundingBox.X2 - ps->BoundingBox.X1; + dy = ps->BoundingBox.Y2 - ps->BoundingBox.Y1; + if ((dx == 0) && (dy == 0)) { + pcb_pstk_bbox(ps); + dx = ps->BoundingBox.X2 - ps->BoundingBox.X1; + dy = ps->BoundingBox.Y2 - ps->BoundingBox.Y1; + } + + vert = dx < dy; +#ifdef PCB_PSTK_LABEL_OFFCENTER + rnd_coord_t offs = 0; + pcb_pstk_proto_t *proto; + proto = pcb_pstk_get_proto(ps); + if ((proto != NULL) && (proto->hdia > 0)) + offs = proto->hdia/2; + pcb_term_label_draw(info, ps->x + offs, ps->y, conf_core.appearance.term_label_size, vert, rnd_false, (pcb_any_obj_t *)ps); +#endif + pcb_term_label_draw(info, ps->x, ps->y, conf_core.appearance.term_label_size, vert, rnd_true, (pcb_any_obj_t *)ps); +} + +static rnd_xform_t dummy_xform; +void pcb_pstk_draw_preview(pcb_board_t *pcb, const pcb_pstk_t *ps, char *layers, rnd_bool mark, rnd_bool label, const rnd_box_t *drawn_area) +{ + pcb_draw_info_t info; + int n, draw_hole = 0; + rnd_layer_id_t lid; + + info.pcb = pcb; + info.drawn_area = drawn_area; + info.xform_caller = info.xform_exporter = info.xform = &dummy_xform; + info.layer = NULL; + info.objcb.pstk.gid = -1; + info.objcb.pstk.holetype = PCB_PHOLE_UNPLATED | PCB_PHOLE_PLATED; + + /* draw non-currents */ + info.objcb.pstk.is_current = 0; + for(n = pcb_proto_num_layers-1; n >= 0; n--) { + if ((layers == NULL) || (layers[n] == 1)) { + info.objcb.pstk.shape_mask = pcb_proto_layers[n].mask; + info.objcb.pstk.comb = pcb_proto_layers[n].comb; + info.objcb.pstk.layer1 = info.layer = NULL; + if (!(info.objcb.pstk.shape_mask & PCB_LYT_COPPER)) { + if (pcb_layer_list(pcb, info.objcb.pstk.shape_mask, &lid, 1) == 1) + info.objcb.pstk.layer1 = info.layer = pcb_get_layer(pcb->Data, lid); + } + if (info.objcb.pstk.shape_mask == PCB_LYT_MECH) + draw_hole = 1; + else + pcb_pstk_draw_callback((rnd_box_t *)ps, &info); + } + } + + /* draw current with strong */ + info.objcb.pstk.is_current = 1; + for(n = pcb_proto_num_layers-1; n >= 0; n--) { + if ((layers == NULL) || (layers[n] > 1)) { + info.objcb.pstk.shape_mask = pcb_proto_layers[n].mask; + info.objcb.pstk.comb = pcb_proto_layers[n].comb; + info.objcb.pstk.layer1 = info.layer = NULL; + if (!(info.objcb.pstk.shape_mask & PCB_LYT_COPPER)) { + if (pcb_layer_list(pcb, info.objcb.pstk.shape_mask, &lid, 1) == 1) + info.objcb.pstk.layer1 = info.layer = pcb_get_layer(pcb->Data, lid); + } + if (info.objcb.pstk.shape_mask == PCB_LYT_MECH) + draw_hole = 2; + else + pcb_pstk_draw_callback((rnd_box_t *)ps, &info); + } + } + + if (draw_hole) { + info.objcb.pstk.shape_mask = PCB_LYT_MECH; + info.objcb.pstk.is_current = (draw_hole > 1); + pcb_pstk_draw_hole_callback((rnd_box_t *)ps, &info); + } + + if (mark) + pcb_pstk_draw_mark_callback((rnd_box_t *)ps, &info); + + if (label) + pcb_pstk_draw_label_callback((rnd_box_t *)ps, &info); +} + + + +void pcb_pstk_invalidate_erase(pcb_pstk_t *ps) +{ + pcb_draw_invalidate(ps); +} + +void pcb_pstk_invalidate_draw(pcb_pstk_t *ps) +{ + pcb_draw_invalidate(ps); +} + + +static int pcb_pstk_near_box_(pcb_pstk_t *ps, rnd_box_t *box, pcb_pstk_shape_t *shape) +{ + pcb_any_line_t pad; + rnd_vector_t v; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + int isneg = PCB_IS_BOX_NEGATIVE(box), is_in, n; + + /* cheap check: hole */ + if (proto->hdia > 0) { + /* in negative case, touching the hole means hit */ + if (isneg) + if (PCB_CIRCLE_TOUCHES_BOX(ps->x, ps->y, proto->hdia/2, box)) + return 1; + + /* in positive case, not including the hole means bad */ + if (!isneg) + if (!PCB_POINT_IN_BOX(ps->x-proto->hdia/2,ps->y-proto->hdia/2, box) || + !PCB_POINT_IN_BOX(ps->x+proto->hdia/2,ps->y+proto->hdia/2, box)) + return 0; + } + + switch(shape->shape) { + case PCB_PSSH_CIRC: + if (isneg) + return PCB_CIRCLE_TOUCHES_BOX(ps->x + shape->data.circ.x, ps->y + shape->data.circ.y, shape->data.circ.dia/2, box); + return + PCB_POINT_IN_BOX(ps->x+shape->data.circ.x-proto->hdia/2,ps->y+shape->data.circ.y-shape->data.circ.dia/2, box) && + PCB_POINT_IN_BOX(ps->x+shape->data.circ.x+proto->hdia/2,ps->y+shape->data.circ.y+shape->data.circ.dia/2, box); + case PCB_PSSH_LINE: + pad.Point1.X = shape->data.line.x1 + ps->x; + pad.Point1.Y = shape->data.line.y1 + ps->y; + pad.Point2.X = shape->data.line.x2 + ps->x; + pad.Point2.Y = shape->data.line.y2 + ps->y; + pad.Thickness = shape->data.line.thickness; + pad.Clearance = 0; + pad.Flags = pcb_flag_make(shape->data.line.square ? PCB_FLAG_SQUARE : 0); + return isneg ? PCB_PAD_TOUCHES_BOX(&pad, box) : PCB_PAD_IN_BOX(&pad, box); + + case PCB_PSSH_HSHADOW: + if (proto->hdia > 0) { + /* If there is a hole, we have already checked that the hole is near. + Since hshadow is the hole. The negative case was already handled + above at the hole, need to handle the positive for hit. Note: for + slots there is a separate shape that will match */ + + if (!isneg && PCB_POINT_IN_BOX(ps->x-proto->hdia/2,ps->y-proto->hdia/2, box) && + PCB_POINT_IN_BOX(ps->x+proto->hdia/2,ps->y+proto->hdia/2, box)) + return 1; + } + return 0; + + case PCB_PSSH_POLY: + if (shape->data.poly.pa == NULL) + pcb_pstk_shape_update_pa(&shape->data.poly); + + if (isneg) { + /* shortcut: if any point is in our box in negative, we are done */ + for(n = 0; n < shape->data.poly.len; n++) { + int pib = PCB_POINT_IN_BOX(ps->x + shape->data.poly.x[n], ps->y + shape->data.poly.y[n], box); + if (pib) + return 1; + } + } + + /* fully within */ + is_in = 1; + for(n = 0; n < shape->data.poly.len; n++) { + int pib = PCB_POINT_IN_BOX(ps->x + shape->data.poly.x[n], ps->y + shape->data.poly.y[n], box); + if (!pib) { + is_in = 0; + break; + } + } + + if (!isneg) /* normal box - accept only if we are in */ + return is_in; + + /* negative box, not fully within, no poly point in the box, check whether + the box is fully within the poly - if any of it's corners is in */ + v[0] = box->X1 - ps->x; + v[1] = box->Y1 - ps->y; + if (rnd_polyarea_contour_inside(shape->data.poly.pa, v)) + return 1; + + + /* negative box, not fully within, no poly point in the box, check whether + box lines intersect poly lines + We expect shapes to be simple so linear search is faster than + being clever */ + for(n = 1; n < shape->data.poly.len; n++) { + if (PCB_XYLINE_ISECTS_BOX(ps->x+shape->data.poly.x[n-1],ps->y+shape->data.poly.y[n-1],ps->x+shape->data.poly.x[n],ps->y+shape->data.poly.y[n], box)) + return 1; + } + + n = shape->data.poly.len-1; + if (PCB_XYLINE_ISECTS_BOX(ps->x+shape->data.poly.x[n-1],ps->y+shape->data.poly.y[n-1],ps->x+shape->data.poly.x[0],ps->y+shape->data.poly.y[0], box)) + return 1; + } + + return 0; +} + +#define HOLE_IN_BOX(ps, dia, b) \ + ( \ + PCB_POINT_IN_BOX((ps)->x - dia/2, (ps)->y - dia/2, (b)) && \ + PCB_POINT_IN_BOX((ps)->x + dia/2, (ps)->y + dia/2, (b)) \ + ) + +#define HOLE_TOUCHES_BOX(ps, dia, b) \ + PCB_CIRCLE_TOUCHES_BOX((ps)->x, (ps)->y, dia/2, (b)) + +int pcb_pstk_near_box(pcb_pstk_t *ps, rnd_box_t *box, pcb_layer_t *layer) +{ + pcb_pstk_shape_t *shp; + pcb_pstk_tshape_t *tshp = pcb_pstk_get_tshape(ps); + + /* special case: no-shape padstack is used for hole */ + if ((tshp == NULL) || (tshp->len == 0)) { + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + if (proto->hdia <= 0) + return 0; + return (PCB_IS_BOX_NEGATIVE(box) ? HOLE_TOUCHES_BOX(ps, proto->hdia, box) : HOLE_IN_BOX(ps, proto->hdia, box)); + } + + /* no layer means: "is any shape near?" */ + if (layer == NULL) { + int n; + + if (tshp == NULL) + return 0; + + for(n = 0; n < tshp->len; n++) + if (pcb_pstk_near_box_(ps, box, &tshp->shape[n]) != 0) + return 1; + return 0; + } + + /* else check only on the specific layer */ + shp = pcb_pstk_shape(ps, pcb_layer_flags_(layer), layer->comb); + if (shp == NULL) + return 0; + return pcb_pstk_near_box_(ps, box, shp); +} + +static int pcb_is_point_in_pstk_(pcb_pstk_t *ps, rnd_coord_t x, rnd_coord_t y, rnd_coord_t radius, pcb_pstk_shape_t *shape) +{ + pcb_any_line_t pad; + rnd_vector_t v; + + switch(shape->shape) { + case PCB_PSSH_HSHADOW: + return 0; + case PCB_PSSH_CIRC: + return PCB_POINT_IN_CIRCLE(x, y, ps->x + shape->data.circ.x, ps->y + shape->data.circ.y, shape->data.circ.dia/2 + radius); + case PCB_PSSH_LINE: + pad.Point1.X = shape->data.line.x1 + ps->x; + pad.Point1.Y = shape->data.line.y1 + ps->y; + pad.Point2.X = shape->data.line.x2 + ps->x; + pad.Point2.Y = shape->data.line.y2 + ps->y; + pad.Thickness = shape->data.line.thickness; + pad.Clearance = 0; + pad.Flags = pcb_flag_make(shape->data.line.square ? PCB_FLAG_SQUARE : 0); + return pcb_is_point_in_line(x, y, radius, &pad); + case PCB_PSSH_POLY: + if (shape->data.poly.pa == NULL) + pcb_pstk_shape_update_pa(&shape->data.poly); + v[0] = x - ps->x; + v[1] = y - ps->y; + return rnd_polyarea_contour_inside(shape->data.poly.pa, v); + } + + return 0; +} + +int pcb_is_point_in_pstk(rnd_coord_t x, rnd_coord_t y, rnd_coord_t radius, pcb_pstk_t *ps, pcb_layer_t *layer) +{ + pcb_pstk_shape_t *shp; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + + /* cheap check: hole clicked (also necessary for a mounting hole too) */ + if (proto->hdia > 0) { + double dist2 = SQR((double)x - (double)ps->x) + SQR((double)y - (double)ps->y); + if (dist2 <= SQR((double)radius + (double)proto->hdia/2.0)) + return 1; + } + + /* no layer means: "is point in any shape?" */ + if (layer == NULL) { + int n; + pcb_pstk_tshape_t *tshp = pcb_pstk_get_tshape(ps); + + if (tshp == NULL) + return 0; + + for(n = 0; n < tshp->len; n++) + if (pcb_is_point_in_pstk_(ps, x, y, radius, &tshp->shape[n]) != 0) + return 1; + return 0; + } + + /* else check only on the specific layer */ + shp = pcb_pstk_shape(ps, pcb_layer_flags_(layer), layer->comb); + if (shp == NULL) + return 0; + return pcb_is_point_in_pstk_(ps, x, y, radius, shp); +} + +/* Check the minimum distance between a hole's edge and a shape's edge and + indicate error if it's smaller than min */ +static rnd_bool pcb_pstk_shape_hole_break(pcb_pstk_shape_t *shp, rnd_coord_t hdia, rnd_coord_t min) +{ + double dist, neck, mindist2, dist2; + pcb_line_t line; + int n; + + switch(shp->shape) { + case PCB_PSSH_HSHADOW: + break; + case PCB_PSSH_CIRC: + dist = sqrt((double)shp->data.circ.x*(double)shp->data.circ.x + (double)shp->data.circ.y*(double)shp->data.circ.y); + neck = (double)(shp->data.circ.dia - hdia) / 2.0 - dist; + break; + case PCB_PSSH_LINE: + line.Point1.X = shp->data.line.x1; + line.Point1.Y = shp->data.line.y1; + line.Point2.X = shp->data.line.x2; + line.Point2.Y = shp->data.line.y2; + line.Thickness = shp->data.line.thickness; + dist = sqrt(pcb_point_line_dist2(0, 0, &line)); + neck = (double)(shp->data.line.thickness - hdia) / 2.0 - dist; + break; + case PCB_PSSH_POLY: + /* square of the minimal distance required for a neck */ + mindist2 = hdia/2 + min; + mindist2 *= mindist2; + + /* cheapest test: if any corner is closer to the hole than min, we are doomed */ + for(n = 0; n < shp->data.poly.len; n++) { + dist2 = (double)shp->data.poly.x[n] * (double)shp->data.poly.x[n] + (double)shp->data.poly.y[n] * (double)shp->data.poly.y[n]; + if (dist2 < mindist2) + return 1; + } + + /* more expensive: check each edge */ + line.Point1.X = shp->data.poly.x[shp->data.poly.len - 1]; + line.Point1.Y = shp->data.poly.y[shp->data.poly.len - 1]; + line.Thickness = 1; + + for(n = 0; n < shp->data.poly.len; n++) { + line.Point2.X = shp->data.poly.x[n]; + line.Point2.Y = shp->data.poly.y[n]; + + dist2 = pcb_point_line_dist2(0, 0, &line); + if (dist2 < mindist2) + return 1; + + /* shift coords for the next iteration */ + line.Point1.X = line.Point2.X; + line.Point1.Y = line.Point2.Y; + } + return 0; /* survived all tests: we are fine! */ + } + + return neck < min; +} + +void pcb_pstk_drc_check_and_warn(pcb_pstk_t *ps, rnd_coord_t *err_minring, rnd_coord_t *err_minhole, rnd_coord_t minring, rnd_coord_t mindrill) +{ + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + + if (proto->hdia > 0) { + int n; + pcb_pstk_tshape_t *ts = pcb_pstk_get_tshape_(ps->parent.data, ps->proto, 0); + + for(n = 0; n < ts->len; n++) { + if (!(ts->shape[n].layer_mask & PCB_LYT_COPPER)) + continue; /* only copper shapes can break */ + if (pcb_pstk_shape_hole_break(&ts->shape[n], proto->hdia, minring)) { + (*err_minring)++; + break; + } + } + } + +TODO("slot: check if slot breaks other shapes") + + if ((mindrill > 0) && (proto->hdia > 0) && (proto->hdia < mindrill)) + *err_minhole = proto->hdia; +} + +/*** undoable mirror ***/ + +typedef struct { + pcb_pstk_t *pstk; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + rnd_coord_t y_offs; + int swap_side; + int disable_xmirror; +} undo_pstk_mirror_t; + +static int undo_pstk_mirror_swap(void *udata) +{ + undo_pstk_mirror_t *g = udata; + pcb_pstk_t *ps = g->pstk; + int xmirror = !ps->xmirror, smirror = (g->swap_side ? (!ps->smirror) : ps->smirror); + + /* change the mirror flag - this will automatically cause mirroring in + every aspect */ + if (g->disable_xmirror) + pcb_pstk_change_instance(ps, NULL, NULL, NULL, NULL, &smirror); + else + pcb_pstk_change_instance(ps, NULL, NULL, NULL, &xmirror, &smirror); + + /* if mirror center is not 0, also move, to emulate that the mirror took + place around that point */ + if (((g->y_offs != 0) || (ps->y != 0)) && (g->y_offs != PCB_PSTK_DONT_MIRROR_COORDS)) { + pcb_poly_restore_to_poly(ps->parent.data, PCB_OBJ_PSTK, NULL, ps); + pcb_pstk_invalidate_erase(ps); + if (ps->parent.data->padstack_tree != NULL) + rnd_r_delete_entry(ps->parent.data->padstack_tree, (rnd_box_t *)ps); + + ps->y = PCB_SWAP_Y(ps->y) + g->y_offs; + pcb_pstk_bbox(ps); + + if (ps->parent.data->padstack_tree != NULL) + rnd_r_insert_entry(ps->parent.data->padstack_tree, (rnd_box_t *)ps); + pcb_poly_clear_from_poly(ps->parent.data, PCB_OBJ_PSTK, NULL, ps); + pcb_pstk_invalidate_draw(ps); + } + + + return 0; +} + +static void undo_pstk_mirror_print(void *udata, char *dst, size_t dst_len) +{ + undo_pstk_mirror_t *g = udata; + rnd_snprintf(dst, dst_len, "pstk mirror y_offs=%$mm swap_side=%d disable_xmirror=%d", g->y_offs, g->swap_side, g->disable_xmirror); +} + +static const uundo_oper_t undo_pstk_mirror = { + core_pstk_cookie, + NULL, + undo_pstk_mirror_swap, + undo_pstk_mirror_swap, + undo_pstk_mirror_print +}; + + + +void pcb_pstk_mirror(pcb_pstk_t *ps, rnd_coord_t y_offs, int swap_side, int disable_xmirror, rnd_bool undoable) +{ + undo_pstk_mirror_t gtmp, *g = >mp; + + if (undoable) g = pcb_undo_alloc(pcb_data_get_top(ps->parent.data), &undo_pstk_mirror, sizeof(undo_pstk_mirror_t)); + + g->pstk = ps; + g->y_offs = y_offs; + g->swap_side = swap_side; + g->disable_xmirror = disable_xmirror; + + undo_pstk_mirror_swap(g); + if (undoable) pcb_undo_inc_serial(); +} + +void pcb_pstk_scale(pcb_pstk_t *ps, double sx, double sy, int undoable) +{ + pcb_pstk_proto_t *prt; + int n; + + if ((sx == 1.0) && (sy == 1.0)) + return; + + pcb_pstk_pre(ps); + + prt = malloc(sizeof(pcb_pstk_proto_t)); + pcb_pstk_proto_copy(prt, pcb_pstk_get_proto(ps)); + + /* after the copy we have the canonical transformed shape only; scale each shape in it */ + for(n = 0; n < prt->tr.array[0].len; n++) + pcb_pstk_shape_scale(prt, 0, n, sx, sy, undoable); + + if (prt->hdia > 0.0) + prt->hdia = rnd_round((double)prt->hdia * ((sx+sy)/2.0)); + + pcb_pstk_proto_update(prt); + ps->proto = pcb_pstk_proto_insert_or_free(ps->parent.data, prt, 1, undoable); + + if (sx != 1.0) + ps->x = rnd_round((double)ps->x * sx); + + if (sy != 1.0) + ps->y = rnd_round((double)ps->y * sy); + + pcb_pstk_post(ps); +} + +unsigned char *pcb_pstk_get_thermal(pcb_pstk_t *ps, unsigned long lid, rnd_bool_t alloc) +{ + if (ps->thermals.used <= lid) { + unsigned long oldu = ps->thermals.used; + if (!alloc) + return NULL; + ps->thermals.used = lid+1; + ps->thermals.shape = realloc(ps->thermals.shape, ps->thermals.used); + memset(ps->thermals.shape + oldu, 0, ps->thermals.used - oldu); + } + return ps->thermals.shape + lid; +} + +/*** undoable thermal change ***/ +typedef struct { + pcb_pstk_t *ps; + rnd_layer_id_t lid; + unsigned char shape; +} undo_pstk_thermal_t; + +static int undo_pstk_thermal_swap(void *udata) +{ + undo_pstk_thermal_t *t = udata; + unsigned char old, *th = pcb_pstk_get_thermal(t->ps, t->lid, 1); + + if (th != NULL) { + pcb_board_t *pcb = pcb_data_get_top(t->ps->parent.data); + pcb_layer_t *layer = pcb_get_layer(pcb->Data, t->lid); + + pcb_poly_restore_to_poly(pcb->Data, PCB_OBJ_PSTK, layer, t->ps); + + old = *th; + *th = t->shape; + t->shape = old; + + pcb_poly_clear_from_poly(pcb->Data, PCB_OBJ_PSTK, layer, t->ps); + pcb_pstk_invalidate_draw(t->ps); + } + return 0; +} + +static void undo_pstk_thermal_print(void *udata, char *dst, size_t dst_len) +{ + undo_pstk_thermal_t *t = udata; + rnd_snprintf(dst, dst_len, "pstk_thermal: #%ld %ld %d", t->ps->ID, t->lid, t->shape); +} + +static const uundo_oper_t undo_pstk_thermal = { + core_pstk_cookie, + NULL, /* free */ + undo_pstk_thermal_swap, + undo_pstk_thermal_swap, + undo_pstk_thermal_print +}; + + +void pcb_pstk_set_thermal(pcb_pstk_t *ps, unsigned long lid, unsigned char shape, int undoable) +{ + undo_pstk_thermal_t *t; + pcb_board_t *pcb = NULL; + + if (undoable) { + assert(ps->parent_type == PCB_PARENT_DATA); + pcb = pcb_data_get_top(ps->parent.data); + } + + + if (!undoable || (pcb == NULL)) { + unsigned char *th = pcb_pstk_get_thermal(ps, lid, 1); + if (th != NULL) + *th = shape; + return; + } + + t = pcb_undo_alloc(pcb, &undo_pstk_thermal, sizeof(undo_pstk_thermal_t)); + t->ps = ps; + t->lid = lid; + t->shape = shape; + undo_pstk_thermal_swap(t); +} + +/*** Undoable instance parameter change ***/ + +typedef struct { + long int parent_ID; /* -1 for pcb, positive for a subc */ + long int ID; /* ID of the padstack */ + + rnd_cardinal_t proto; + rnd_coord_t clearance; + double rot; + int xmirror, smirror; +} padstack_change_instance_t; + +#define swap(a,b,type) \ + do { \ + type tmp = a; \ + a = b; \ + b = tmp; \ + } while(0) + +pcb_data_t *pcb_pstk_data_hack = NULL; + +static int undo_change_instance_swap(void *udata) +{ + padstack_change_instance_t *u = udata; + pcb_data_t *data; + pcb_pstk_t *ps; + + /* data is either parent subc's data or board's data */ + if (u->parent_ID != -1) { + pcb_subc_t *subc; + int n; + + /* Look up the parent subc by ID; on the board, in the hack-data and in all buffers */ + subc = pcb_subc_by_id(PCB->Data, u->parent_ID); + if ((subc == NULL) && (pcb_pstk_data_hack != NULL)) + subc = pcb_subc_by_id(pcb_pstk_data_hack, u->parent_ID); + for(n = 0; (subc == NULL) && (n < PCB_MAX_BUFFER); n++) + subc = pcb_subc_by_id(pcb_buffers[n].Data, u->parent_ID); + if (subc == NULL) { + rnd_message(RND_MSG_ERROR, "Can't undo padstack change: parent subc #%ld is not found\n", u->parent_ID); + return -1; + } + data = subc->data; + } + else + data = PCB->Data; + + ps = pcb_pstk_by_id(data, u->ID); + if (ps == NULL) { + rnd_message(RND_MSG_ERROR, "Can't undo padstack change: padstack ID #%ld is not available\n", u->ID); + return -1; + } + + pcb_poly_restore_to_poly(ps->parent.data, PCB_OBJ_PSTK, NULL, ps); + pcb_pstk_invalidate_erase(ps); + if (ps->parent.data->padstack_tree != NULL) + rnd_r_delete_entry(ps->parent.data->padstack_tree, (rnd_box_t *)ps); + + swap(ps->proto, u->proto, rnd_cardinal_t); + swap(ps->Clearance, u->clearance, rnd_coord_t); + swap(ps->rot, u->rot, double); + swap(ps->xmirror, u->xmirror, int); + swap(ps->smirror, u->smirror, int); + + /* force re-render the prototype */ + ps->protoi = -1; + pcb_pstk_get_tshape(ps); + + pcb_pstk_bbox(ps); + if (ps->parent.data->padstack_tree != NULL) + rnd_r_insert_entry(ps->parent.data->padstack_tree, (rnd_box_t *)ps); + pcb_poly_clear_from_poly(ps->parent.data, PCB_OBJ_PSTK, NULL, ps); + pcb_pstk_invalidate_draw(ps); + + return 0; +} + +static void undo_change_instance_print(void *udata, char *dst, size_t dst_len) +{ + padstack_change_instance_t *u = udata; + rnd_snprintf(dst, dst_len, "padstack change: clearance=%$mm rot=%.2f xmirror=%d smirror=%d\n", u->clearance, u->rot, u->xmirror, u->smirror); +} + +static const uundo_oper_t undo_pstk_change_instance = { + core_pstk_cookie, + NULL, /* free */ + undo_change_instance_swap, + undo_change_instance_swap, + undo_change_instance_print +}; + +int pcb_pstk_change_instance(pcb_pstk_t *ps, rnd_cardinal_t *proto, const rnd_coord_t *clearance, double *rot, int *xmirror, int *smirror) +{ + padstack_change_instance_t *u; + long int parent_ID; + pcb_opctx_t ctx; + + if ((proto != NULL) && ((*proto < 0) || (*proto >= ps->parent.data->ps_protos.used))) + return -1; + + + if (ps->ID <= 0) { /* off-board padstack: undo and clipping disabled */ + if (proto != NULL) ps->proto = *proto; + if (clearance != NULL) ps->Clearance = *clearance; + if (rot != NULL) ps->rot = *rot; + if (xmirror != NULL) ps->xmirror = *xmirror; + if (smirror != NULL) ps->xmirror = *smirror; + pcb_pstk_bbox(ps); + return 0; + } + + switch(ps->parent.data->parent_type) { + case PCB_PARENT_INVALID: + /* happens if parent is a buffer: do not undo operations done on the buffer */ + ps->proto = proto ? *proto : ps->proto; + ps->Clearance = clearance ? *clearance : ps->Clearance; + ps->rot = rot ? *rot : ps->rot; + ps->xmirror = xmirror ? *xmirror : ps->xmirror; + ps->smirror = smirror ? *smirror : ps->smirror; + + /* re-render the prototype so the new shape is generated and cached */ + ps->protoi = -1; + pcb_pstk_get_tshape(ps); + return 0; + case PCB_PARENT_BOARD: parent_ID = -1; break; + case PCB_PARENT_SUBC: parent_ID = ps->parent.data->parent.subc->ID; break; + default: return -1; + } + + ctx.clip.clear = 0; + ctx.clip.restore = 1; + pcb_pstkop_clip(&ctx, ps); + + u = pcb_undo_alloc(PCB, &undo_pstk_change_instance, sizeof(padstack_change_instance_t)); + u->parent_ID = parent_ID; + u->ID = ps->ID; + u->proto = proto ? *proto : ps->proto; + u->clearance = clearance ? *clearance : ps->Clearance; + u->rot = rot ? *rot : ps->rot; + u->xmirror = xmirror ? *xmirror : ps->xmirror; + u->smirror = smirror ? *smirror : ps->smirror; + + pcb_pstk_bbox(ps); + ctx.clip.clear = 1; + ctx.clip.restore = 0; + pcb_pstkop_clip(&ctx, ps); + + + undo_change_instance_swap(u); + + pcb_undo_inc_serial(); + return 0; +} + +rnd_bool pcb_pstk_is_group_empty(pcb_board_t *pcb, rnd_layergrp_id_t gid) +{ + pcb_layergrp_t *g = &pcb->LayerGroups.grp[gid]; + + PCB_PADSTACK_LOOP(pcb->Data); { + rnd_cardinal_t n; + for(n = 0; n < g->len; n++) + if (pcb_pstk_shape_at(pcb, padstack, &pcb->Data->Layer[g->lid[n]])) + return rnd_false; + } + PCB_END_LOOP; + return rnd_true; +} + + +#include "obj_pstk_op.c" + +void pcb_pstk_rotate90(pcb_pstk_t *pstk, rnd_coord_t cx, rnd_coord_t cy, int steps) +{ + pcb_opctx_t ctx; + + ctx.rotate.center_x = cx; + ctx.rotate.center_y = cy; + ctx.rotate.number = steps; + pcb_pstkop_rotate90(&ctx, pstk); +} + +void pcb_pstk_rotate(pcb_pstk_t *pstk, rnd_coord_t cx, rnd_coord_t cy, double cosa, double sina, double angle) +{ + pcb_opctx_t ctx; + + ctx.rotate.center_x = cx; + ctx.rotate.center_y = cy; + ctx.rotate.angle = angle; + ctx.rotate.cosa = cosa; + ctx.rotate.sina = sina; + pcb_pstkop_rotate(&ctx, pstk); +} + +rnd_coord_t obj_pstk_get_clearance(pcb_board_t *pcb, pcb_pstk_t *ps, pcb_layer_t *layer) +{ + pcb_pstk_shape_t *shp; + + if (!PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, ps)) + return 0; + + if (ps->Clearance > 0) /* global clarance overrides */ + return ps->Clearance; + + shp = pcb_pstk_shape_at(pcb, ps, layer); + return shp->clearance; +} + +void pcb_pstk_pre(pcb_pstk_t *pstk) +{ + pcb_data_t *data = pstk->parent.data; + if (data->padstack_tree != NULL) + rnd_r_delete_entry(data->padstack_tree, (rnd_box_t *)pstk); + pcb_poly_restore_to_poly(data, PCB_OBJ_PSTK, NULL, pstk); +} + +void pcb_pstk_post(pcb_pstk_t *pstk) +{ + pcb_data_t *data = pstk->parent.data; + if (data->padstack_tree != NULL) + rnd_r_insert_entry(data->padstack_tree, (rnd_box_t *)pstk); + pcb_poly_clear_from_poly(data, PCB_OBJ_PSTK, NULL, pstk); +} + +rnd_layer_id_t pcb_proto_board_layer_for(const pcb_data_t *data, pcb_layer_type_t mask, pcb_layer_combining_t comb) +{ + rnd_layer_id_t lid; + const pcb_layer_t *ly; + for(lid = 0, ly = data->Layer; lid < data->LayerN; lid++,ly++) { + pcb_layer_type_t typ = pcb_layer_flags_(ly); + if ((typ == mask) && (ly->comb == comb)) + return lid; + } + return -1; +} Index: tags/2.3.0/src/obj_pstk.h =================================================================== --- tags/2.3.0/src/obj_pstk.h (nonexistent) +++ tags/2.3.0/src/obj_pstk.h (revision 33253) @@ -0,0 +1,307 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_PSTK_STRUCT_DECLARED +#define PCB_OBJ_PSTK_STRUCT_DECLARED + +#include +#include +#include "obj_common.h" + +/* The actual padstack is just a reference to a padstack proto within the same data */ +struct pcb_pstk_s { +#define thermal thermal_dont_use + PCB_ANY_PRIMITIVE_FIELDS; +#undef thermal + rnd_cardinal_t proto; /* reference to a pcb_pstk_proto_t within pcb_data_t */ + int protoi; /* index of the transformed proto; -1 means invalid; local cache, not saved */ + rnd_coord_t x, y; + rnd_coord_t Clearance; + double rot; /* rotation angle */ + char xmirror, smirror; + struct { + unsigned long used; + unsigned char *shape; /* indexed by layer ID */ + } thermals; + gdl_elem_t link; /* a padstack is in a list in pcb_data_t as a global object */ +}; +#endif + +#ifndef PCB_PADSTACK_STRUCT_ONLY +#ifndef PCB_OBJ_PSTK_H +#define PCB_OBJ_PSTK_H + +#define PCB_PADSTACK_MAX_SHAPES 31 + +#define PCB_PADSTACK_INVALID ((rnd_cardinal_t)(-1)) + +#include "layer.h" +#include "obj_common.h" +#include "obj_pstk_shape.h" +#include "vtpadstack_t.h" + +struct pcb_pstk_proto_s { + unsigned in_use:1; /* 1 if the slot is in use */ + + unsigned hplated:1; /* if > 0, whether the hole is plated */ + char *name; /* optional user assigned name (or NULL) */ + rnd_coord_t hdia; /* if > 0, diameter of the hole (else there's no hole) */ + int htop, hbottom; /* if hdia > 0, determine the hole's span, counted in copper layer groups from the top or bottom copper layer group */ + + pcb_vtpadstack_tshape_t tr; /* [0] is the canonical prototype with rot=0, xmirror=0 and smirror=0; the rest is an unordered list of transformed entries */ + + /* local cache - not saved */ + unsigned long hash; /* optimization: linear search compare speeded up: go into detailed match only if hash matches */ + pcb_data_t *parent; + int mech_idx; /* -1 or index to the first shape[] that is of PCB_LYT_MECH */ + unsigned all_copper_connd:1; /* 1 if all copper shapes are connected by the hole/slot (regardless of plating!) */ +}; + +/* Whether a proto cuts through board layers (has a hole or slot) */ +#define PCB_PSTK_PROTO_CUTS(proto) (((proto)->hdia > 0) || ((proto)->mech_idx >= 0)) + +/* Whether a proto cuts through board layers (has a hole or slot) and connects + layers with conductive material */ +#define PCB_PSTK_PROTO_PLATES(proto) (((proto)->hplated) && (((proto)->hdia > 0) || ((proto)->mech_idx >= 0))) + + +pcb_pstk_t *pcb_pstk_alloc(pcb_data_t *data); +pcb_pstk_t *pcb_pstk_alloc_id(pcb_data_t *data, long int id); +void pcb_pstk_free(pcb_pstk_t *ps); +pcb_pstk_t *pcb_pstk_new(pcb_data_t *data, long int id, rnd_cardinal_t proto, rnd_coord_t x, rnd_coord_t y, rnd_coord_t clearance, pcb_flag_t Flags); +pcb_pstk_t *pcb_pstk_new_tr(pcb_data_t *data, long int id, rnd_cardinal_t proto, rnd_coord_t x, rnd_coord_t y, rnd_coord_t clearance, pcb_flag_t Flags, double rot, int xmirror, int smirror); +void pcb_pstk_add(pcb_data_t *data, pcb_pstk_t *ps); +void pcb_pstk_bbox(pcb_pstk_t *ps); +void pcb_pstk_copper_bbox(rnd_box_t *dst, pcb_pstk_t *ps); + +void pcb_pstk_reg(pcb_data_t *data, pcb_pstk_t *pstk); +void pcb_pstk_unreg(pcb_pstk_t *pstk); + + +void pcb_pstk_pre(pcb_pstk_t *pstk); +void pcb_pstk_post(pcb_pstk_t *pstk); + +/* hash and eq */ +int pcb_pstk_eq(const pcb_host_trans_t *tr1, const pcb_pstk_t *p1, const pcb_host_trans_t *tr2, const pcb_pstk_t *p2); +unsigned int pcb_pstk_hash(const pcb_host_trans_t *tr, const pcb_pstk_t *p); + + +void pcb_pstk_set_thermal(pcb_pstk_t *ps, unsigned long lid, unsigned char shape, int undoable); +unsigned char *pcb_pstk_get_thermal(pcb_pstk_t *ps, unsigned long lid, rnd_bool_t alloc); + +pcb_pstk_t *pcb_pstk_by_id(pcb_data_t *base, long int ID); + +/* Undoably change the instance parameters of a padstack ref */ +int pcb_pstk_change_instance(pcb_pstk_t *ps, rnd_cardinal_t *proto, const rnd_coord_t *clearance, double *rot, int *xmirror, int *smirror); + +/* Return whether a group is empty (free of padstack shapes) */ +rnd_bool pcb_pstk_is_group_empty(pcb_board_t *pcb, rnd_layergrp_id_t gid); + +/* Copy all metadata (attributes, thermals, etc.) */ +pcb_pstk_t *pcb_pstk_copy_meta(pcb_pstk_t *dst, pcb_pstk_t *src); + +/* Copy orientation information (rotatioin and mirror) of an instance */ +pcb_pstk_t *pcb_pstk_copy_orient(pcb_pstk_t *dst, pcb_pstk_t *src); + +/* Clearance of the padstack on a given layer */ +rnd_coord_t obj_pstk_get_clearance(pcb_board_t *pcb, pcb_pstk_t *ps, pcb_layer_t *layer); + +/*** proto ***/ + +/* Convert selection or current buffer to padstack; returns PCB_PADSTACK_INVALID + on error; looks for existing matching protos to avoid adding redundant + entries */ +rnd_cardinal_t pcb_pstk_conv_selection(pcb_board_t *pcb, int quiet, rnd_coord_t ox, rnd_coord_t oy); +rnd_cardinal_t pcb_pstk_conv_buffer(int quiet); + +/* Low level converter: take an array of (pcb_any_obj_t *) objs and convert + them into shapes of the dst proto. Does not remove input objects. */ +int pcb_pstk_proto_conv(pcb_data_t *data, pcb_pstk_proto_t *dst, int quiet, vtp0_t *objs, rnd_coord_t ox, rnd_coord_t oy); + +/* Break up src into discrete non-pstk objects placed in dst, one object + per layer type. The hole is ignored. If remove_src is true, also remove + src padstack. */ +int pcb_pstk_proto_breakup(pcb_data_t *dst, pcb_pstk_t *src, rnd_bool remove_src); + +/* free fields of a proto (not freeing the proto itself, not removing it from lists */ +void pcb_pstk_proto_free_fields(pcb_pstk_proto_t *dst); + +/* low level: allocate a new, uninitialized shape at the end of a transformed shape + WARNING: this should be done on all transformed shapes in parallel! */ +pcb_pstk_shape_t *pcb_pstk_alloc_append_shape(pcb_pstk_tshape_t *ts); + +/* allocate/free the point array of a poly shape (single allocation for x and y) */ +void pcb_pstk_shape_alloc_poly(pcb_pstk_poly_t *poly, int len); +void pcb_pstk_shape_free_poly(pcb_pstk_poly_t *poly); + +/* geometry for select.c and search.c; if layer is NULL, consider all shapes */ +int pcb_pstk_near_box(pcb_pstk_t *ps, rnd_box_t *box, pcb_layer_t *layer); +int pcb_is_point_in_pstk(rnd_coord_t x, rnd_coord_t y, rnd_coord_t radius, pcb_pstk_t *ps, pcb_layer_t *layer); + +/* Check all possible local drc errors regarding to pad stacks - errors that + depend only on the padstack, not on other objects. load err_minring and + err_minhole with the relevant data for the report when ring or hole rules + are violated */ +void pcb_pstk_drc_check_and_warn(pcb_pstk_t *ps, rnd_coord_t *err_minring, rnd_coord_t *err_minhole, rnd_coord_t minring, rnd_coord_t mindrill); + +/* Generate poly->pa (which should be NULL at the time of call) */ +void pcb_pstk_shape_update_pa(pcb_pstk_poly_t *poly); + +/* Insert proto into the cache of data; if it's already in, return the existing + ID, else dup it and insert it. The forcedup variant always dups. + WARNING: make sure pcb_pstk_proto_update() was called on proto some point + in time before this call, esle the hash is invalid. */ +rnd_cardinal_t pcb_pstk_proto_insert_dup(pcb_data_t *data, const pcb_pstk_proto_t *proto, int quiet, int undoable); +rnd_cardinal_t pcb_pstk_proto_insert_forcedup(pcb_data_t *data, const pcb_pstk_proto_t *proto, int quiet, int undoable); + +/* Change the non-NULL hole properties of a padstack proto; undoable. + Returns 0 on success. */ +int pcb_pstk_proto_change_hole(pcb_pstk_proto_t *proto, const int *hplated, const rnd_coord_t *hdia, const int *htop, const int *hbottom); + +/* Change the name of a padstack proto; not yet undoable. + Returns 0 on success. */ +int pcb_pstk_proto_change_name(pcb_pstk_proto_t *proto, const char *new_name, int undoable); + +/* Find or create a new transformed version of an existing proto */ +pcb_pstk_tshape_t *pcb_pstk_make_tshape(pcb_data_t *data, pcb_pstk_proto_t *proto, double rot, int xmirror, int smirror, int *out_protoi); + +/* Deep copy a prototype or shape */ +void pcb_pstk_proto_copy(pcb_pstk_proto_t *dst, const pcb_pstk_proto_t *src); +void pcb_pstk_shape_copy(pcb_pstk_shape_t *dst, pcb_pstk_shape_t *src); + +/* free all fields of a shape */ +void pcb_pstk_shape_free(pcb_pstk_shape_t *s); + +/* grow (or shrink) a prototype to or by val - change the proto in place */ +void pcb_pstk_proto_grow(pcb_pstk_proto_t *proto, rnd_bool is_absolute, rnd_coord_t val); +void pcb_pstk_shape_grow_(pcb_pstk_shape_t *shp, rnd_bool is_absolute, rnd_coord_t val); +void pcb_pstk_shape_grow(pcb_pstk_proto_t *proto, int tridx, int shpidx, rnd_bool is_absolute, rnd_coord_t val, int undoable); +void pcb_pstk_shape_clr_grow_(pcb_pstk_shape_t *shp, rnd_bool is_absolute, rnd_coord_t val); +void pcb_pstk_shape_clr_grow(pcb_pstk_proto_t *proto, int tridx, int shpidx, rnd_bool is_absolute, rnd_coord_t val, int undoable); +void pcb_pstk_shape_scale(pcb_pstk_proto_t *proto, int tridx, int shpidx, double sx, double sy, int undoable); + +/* Derive (copy and bloat) the shape at dst_idx from src_idx; set the mask and comb + for the new shape. If dst_idx is -1, allocate the new shape */ +void pcb_pstk_shape_derive(pcb_pstk_proto_t *proto, int dst_idx, int src_idx, rnd_coord_t bloat, pcb_layer_type_t mask, pcb_layer_combining_t comb); + +/* Swap the layer definition of two shapes within a prototype; returns 0 on success */ +int pcb_pstk_shape_swap_layer(pcb_pstk_proto_t *proto, int idx1, int idx2); + +/* Create a new hshadow shape (in all transformed shape as well) */ +void pcb_pstk_shape_add_hshadow(pcb_pstk_proto_t *proto, pcb_layer_type_t mask, pcb_layer_combining_t comb); + + +/* Look up the shape index corresponding to a lty/comb; returns -1 if not found/empty */ +int pcb_pstk_get_shape_idx(pcb_pstk_tshape_t *ts, pcb_layer_type_t lyt, pcb_layer_combining_t comb); + +/* Remove a shape from the proto (either by layer or by idx) */ +void pcb_pstk_proto_del_shape(pcb_pstk_proto_t *proto, pcb_layer_type_t lyt, pcb_layer_combining_t comb); +void pcb_pstk_proto_del_shape_idx(pcb_pstk_proto_t *proto, int idx); + +#define PCB_PSTK_DONT_MIRROR_COORDS RND_MAX_COORD +/* Mirror a padstack (useful for sending to the other side - set swap_side to 1 in that case) + Disabling xmirror is useful if side needs to be swapped but coordinates + are already mirrored so they represent the other-side geometry (e.g. when + importing from old pcb formats). If y_offs is PCB_PSTK_DONT_MIRROR_COORDS, + do not change the y coord */ +void pcb_pstk_mirror(pcb_pstk_t *ps, rnd_coord_t y_offs, int swap_side, int disable_xmirror, rnd_bool undoable); + +/* Create a new proto and scale it for the padstack; center x and y are scaled too */ +void pcb_pstk_scale(pcb_pstk_t *ps, double sx, double sy, int undoable); + + +/* Rotate in place (op wrapper) */ +void pcb_pstk_rotate90(pcb_pstk_t *pstk, rnd_coord_t cx, rnd_coord_t cy, int steps); +void pcb_pstk_rotate(pcb_pstk_t *pstk, rnd_coord_t cx, rnd_coord_t cy, double cosa, double sina, double angle); + +/* High level move (op wrapper; no undo) */ +void pcb_pstk_move(pcb_pstk_t *ps, rnd_coord_t dx, rnd_coord_t dy, rnd_bool more_to_come); + +/* Low level move - updates only the coordinates and the bbox */ +void pcb_pstk_move_(pcb_pstk_t *ps, rnd_coord_t dx, rnd_coord_t dy); + +/* Temporary hack until we have a refcounted objects and ID->pcb_any_obj_t hash */ +extern pcb_data_t *pcb_pstk_data_hack; + +/* Insert a proto in data and return the proto-id. If the proto is already + in data, the fields of the caller's version are free'd, else they are + copied into data. In any case, the caller should not free proto. */ +rnd_cardinal_t pcb_pstk_proto_insert_or_free(pcb_data_t *data, pcb_pstk_proto_t *proto, int quiet, int undoable); + +/* Update caches and hash - must be called after any change to the prototype */ +void pcb_pstk_proto_update(pcb_pstk_proto_t *dst); + +/* Overwrite all fields of a proto in-place; returns the id or INVALID on error */ +rnd_cardinal_t pcb_pstk_proto_replace(pcb_data_t *data, rnd_cardinal_t proto_id, const pcb_pstk_proto_t *src); + +/* Cycle through all (first level) padstacks of data and count how many times + each prototype is referenced by them. The result is returned as an array + of counts per prototype ID; the array is as large as data's prototype array. + len_out is always filled with the length of the array. If the length is 0, + NULL is returned. The caller needs to call free() on the returned array. */ +rnd_cardinal_t *pcb_pstk_proto_used_all(pcb_data_t *data, rnd_cardinal_t *len_out); + +/* Remove a prototype: free all fields and mark it unused */ +void pcb_pstk_proto_del(pcb_data_t *data, rnd_cardinal_t proto_id); + +/* allocate a new shape in proto:tr_idx and return the shape index - + clal this for all transformed shapes! */ +int pcb_pstk_alloc_shape_idx(pcb_pstk_proto_t *proto, int tr_idx); + +/*** layer info ***/ +typedef struct pcb_proto_layer_s { + const char *name; + pcb_layer_type_t mask; + pcb_layer_combining_t comb; + + int auto_from[2]; + rnd_coord_t auto_bloat; +} pcb_proto_layer_t; + +#define PCB_PROTO_MASK_BLOAT RND_MIL_TO_COORD(2*3) + +#define pcb_proto_num_layers 8 +extern const pcb_proto_layer_t pcb_proto_layers[pcb_proto_num_layers]; + + +/* Return the id of a board layer that matches a mask:comb pair or invalid if + nothing matched */ +rnd_layer_id_t pcb_proto_board_layer_for(const pcb_data_t *data, pcb_layer_type_t mask, pcb_layer_combining_t comb); + +/*** hash ***/ +unsigned int pcb_pstk_proto_hash(const pcb_pstk_proto_t *p); +int pcb_pstk_proto_eq(const pcb_pstk_proto_t *p1, const pcb_pstk_proto_t *p2); + +int pcb_pstk_shape_eq(const pcb_pstk_shape_t *sh1, const pcb_pstk_shape_t *sh2); + +/*** loops ***/ +#define PCB_PADSTACK_LOOP(top) do { \ + pcb_pstk_t *padstack; \ + gdl_iterator_t __it__; \ + padstacklist_foreach(&(top)->padstack, &__it__, padstack) { + +#endif +#endif Index: tags/2.3.0/src/obj_pstk_act.c =================================================================== --- tags/2.3.0/src/obj_pstk_act.c (nonexistent) +++ tags/2.3.0/src/obj_pstk_act.c (revision 33253) @@ -0,0 +1,233 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "obj_pstk.h" +#include "obj_pstk_inlines.h" + +#include "funchash_core.h" +#include "board.h" +#include "conf_core.h" +#include "data.h" +#include +#include "search.h" +#include "data_list.h" + +#define PCB do_not_use_PCB + +static const char pcb_acts_padstackconvert[] = "PadstackConvert(buffer|selected, [originx, originy])"; +static const char pcb_acth_padstackconvert[] = "Convert selection or current buffer to padstack"; +fgw_error_t pcb_act_padstackconvert(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + rnd_coord_t x, y; + rnd_cardinal_t pid; + pcb_pstk_proto_t tmp, *p; + pcb_board_t *pcb = PCB_ACT_BOARD; + + RND_ACT_CONVARG(1, FGW_KEYWORD, padstackconvert, op = fgw_keyword(&argv[1])); + + switch(op) { + case F_Selected: + if (argc > 3) { + RND_ACT_CONVARG(2, FGW_COORD, padstackconvert, x = fgw_coord(&argv[2])); + RND_ACT_CONVARG(3, FGW_COORD, padstackconvert, y = fgw_coord(&argv[3])); + } + else { + rnd_hid_get_coords("Click at padstack origin", &x, &y, 0); + /* rather use the snapped corsshair coords */ + x = pcb_crosshair.X; + y = pcb_crosshair.Y; + } + pid = pcb_pstk_conv_selection(pcb, 0, x, y); + + if (pid != PCB_PADSTACK_INVALID) { + pcb_buffer_clear(pcb, PCB_PASTEBUFFER); + p = pcb_vtpadstack_proto_alloc_append(&PCB_PASTEBUFFER->Data->ps_protos, 1); + pcb_pstk_proto_copy(p, &pcb->Data->ps_protos.array[pid]); + p->parent = PCB_PASTEBUFFER->Data; + pid = pcb_pstk_get_proto_id(p); /* should be 0 because of the clear, but just in case... */ + } + break; + case F_Buffer: + pid = pcb_pstk_conv_buffer(0); + + if (pid != PCB_PADSTACK_INVALID) { + /* have to save and restore the prototype around the buffer clear */ + tmp = PCB_PASTEBUFFER->Data->ps_protos.array[pid]; + memset(&PCB_PASTEBUFFER->Data->ps_protos.array[pid], 0, sizeof(PCB_PASTEBUFFER->Data->ps_protos.array[0])); + pcb_buffer_clear(pcb, PCB_PASTEBUFFER); + p = pcb_vtpadstack_proto_alloc_append(&PCB_PASTEBUFFER->Data->ps_protos, 1); + *p = tmp; + p->parent = PCB_PASTEBUFFER->Data; + pid = pcb_pstk_get_proto_id(p); /* should be 0 because of the clear, but just in case... */ + } + break; + default: + RND_ACT_FAIL(padstackconvert); + } + + if (pid != PCB_PADSTACK_INVALID) { + rnd_message(RND_MSG_INFO, "Pad stack registered with ID %d\n", pid); + pcb_pstk_new(PCB_PASTEBUFFER->Data, -1, pid, 0, 0, conf_core.design.clearance, pcb_flag_make(PCB_FLAG_CLEARLINE)); + pcb_set_buffer_bbox(PCB_PASTEBUFFER); + PCB_PASTEBUFFER->X = PCB_PASTEBUFFER->Y = 0; + RND_ACT_IRES(0); + } + else { + rnd_message(RND_MSG_ERROR, "(failed to convert to padstack)\n", pid); + RND_ACT_IRES(1); + } + + return 0; +} + +static const char pcb_acts_padstackbreakup[] = "PadstackBreakup(buffer|selected|objet)"; +static const char pcb_acth_padstackbreakup[] = "Break up a padstack into one non-padstack object per layer type (the hole is ignored)"; +fgw_error_t pcb_act_padstackbreakup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int op; + RND_ACT_CONVARG(1, FGW_KEYWORD, padstackconvert, op = fgw_keyword(&argv[1])); + RND_ACT_IRES(-1); + + switch(op) { + case F_Object: + { + void *ptr1, *ptr2, *ptr3; + pcb_pstk_t *ps; + pcb_objtype_t type; + rnd_coord_t x, y; + + rnd_hid_get_coords("Select a padstack to break up", &x, &y, 0); + if ((type = pcb_search_screen(x, y, PCB_OBJ_PSTK, &ptr1, &ptr2, &ptr3)) != PCB_OBJ_PSTK) { + rnd_message(RND_MSG_ERROR, "Need a padstack under the cursor\n"); + break; + } + ps = (pcb_pstk_t *)ptr2; + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, (pcb_any_obj_t *)ps)) { + rnd_message(RND_MSG_ERROR, "Sorry, that padstack is locked\n"); + break; + } + RND_ACT_IRES(pcb_pstk_proto_breakup(pcb->Data, ps, 1)); + } + break; + case F_Selected: + { + rnd_cardinal_t n; + int ret = 0; + vtp0_t objs; + pcb_any_obj_t **o; + + vtp0_init(&objs); + pcb_data_list_by_flag(pcb->Data, &objs, PCB_OBJ_PSTK, PCB_FLAG_SELECTED); + for(n = 0, o = (pcb_any_obj_t **)objs.array; n < vtp0_len(&objs); n++,o++) + ret |= pcb_pstk_proto_breakup(pcb->Data, (pcb_pstk_t *)*o, 1); + RND_ACT_IRES(ret); + vtp0_uninit(&objs); + } + break; + case F_Buffer: + { + int ret = 0; + PCB_PADSTACK_LOOP(PCB_PASTEBUFFER->Data) { + ret |= pcb_pstk_proto_breakup(PCB_PASTEBUFFER->Data, padstack, 1); + } PCB_END_LOOP; + RND_ACT_IRES(ret); + } + break; + default: + RND_ACT_FAIL(padstackbreakup); + } + return 0; +} + +static const char pcb_acts_padstackplace[] = "PadstackPlace([proto_id|default], [x, y])"; +static const char pcb_acth_padstackplace[] = "Place a pad stack (either proto_id, or if not specified, the default for style)"; +fgw_error_t pcb_act_padstackplace(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *pids = NULL; + rnd_cardinal_t pid; + pcb_pstk_t *ps; + rnd_coord_t x, y; + + RND_ACT_MAY_CONVARG(1, FGW_STR, padstackplace, pids = argv[1].val.str); + + if (argc > 3) { + RND_ACT_CONVARG(2, FGW_COORD, padstackconvert, x = fgw_coord(&argv[2])); + RND_ACT_CONVARG(3, FGW_COORD, padstackconvert, y = fgw_coord(&argv[3])); + } + else { + rnd_hid_get_coords("Click at padstack origin", &x, &y, 0); + /* rather use the snapped corsshair coords */ + x = pcb_crosshair.X; + y = pcb_crosshair.Y; + } + + if ((pids == NULL) || (strcmp(pids, "default") == 0)) { +TODO("pstk: style default proto") + pid = 0; + } + else { + char *end; + pid = strtol(pids, &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Error in proto ID format: need an integer\n"); + return -1; + } + } + + if ((pid >= pcb->Data->ps_protos.used) || (pcb->Data->ps_protos.array[pid].in_use == 0)) { + rnd_message(RND_MSG_ERROR, "Invalid padstack proto %ld\n", (long)pid); + return -1; + } + + ps = pcb_pstk_new(pcb->Data, -1, pid, x, y, conf_core.design.clearance, pcb_no_flags()); + if (ps == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to place padstack\n"); + return -1; + } + + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static rnd_action_t padstack_action_list[] = { + {"PadstackConvert", pcb_act_padstackconvert, pcb_acth_padstackconvert, pcb_acts_padstackconvert}, + {"PadstackBreakup", pcb_act_padstackbreakup, pcb_acth_padstackbreakup, pcb_acts_padstackbreakup}, + {"PadstackPlace", pcb_act_padstackplace, pcb_acth_padstackplace, pcb_acts_padstackplace} +}; + +void pcb_pstk_act_init2(void) +{ + RND_REGISTER_ACTIONS(padstack_action_list, NULL); +} + + Index: tags/2.3.0/src/obj_pstk_draw.h =================================================================== --- tags/2.3.0/src/obj_pstk_draw.h (nonexistent) +++ tags/2.3.0/src/obj_pstk_draw.h (revision 33253) @@ -0,0 +1,57 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "obj_pstk.h" + +#ifndef PCB_OBJ_PSTK_DRAW_H +#define PCB_OBJ_PSTK_DRAW_H + +/* Include rtree.h for these */ +#ifdef RND_RTREE_H + +#include "board.h" +#include "draw.h" + +rnd_r_dir_t pcb_pstk_draw_callback(const rnd_box_t *b, void *cl); +rnd_r_dir_t pcb_pstk_draw_hole_callback(const rnd_box_t *b, void *cl); +rnd_r_dir_t pcb_pstk_draw_slot_callback(const rnd_box_t *b, void *cl); +rnd_r_dir_t pcb_pstk_clear_callback(const rnd_box_t *b, void *cl); +#endif + +rnd_r_dir_t pcb_pstk_draw_mark_callback(const rnd_box_t *b, void *cl); +rnd_r_dir_t pcb_pstk_draw_label_callback(const rnd_box_t *b, void *cl); +void pcb_pstk_draw_label(pcb_draw_info_t *info, pcb_pstk_t *ps, rnd_bool vis_side); +void pcb_pstk_invalidate_erase(pcb_pstk_t *ps); +void pcb_pstk_invalidate_draw(pcb_pstk_t *ps); + +void pcb_pstk_thindraw(pcb_draw_info_t *info, rnd_hid_gc_t gc, pcb_pstk_t *ps); + +/* Draw a padstack for perview; if layers is NULL, draw all layers, else + draw the layers where it is not zero (layers are defined in pcb_proto_layers[]) */ +void pcb_pstk_draw_preview(pcb_board_t *pcb, const pcb_pstk_t *ps, char *layers, rnd_bool mark, rnd_bool label, const rnd_box_t *drawn_area); + + +#endif Index: tags/2.3.0/src/obj_pstk_inlines.h =================================================================== --- tags/2.3.0/src/obj_pstk_inlines.h (nonexistent) +++ tags/2.3.0/src/obj_pstk_inlines.h (revision 33253) @@ -0,0 +1,405 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_PSTK_INLINES_H +#define PCB_OBJ_PSTK_INLINES_H + +#include "board.h" +#include "data.h" +#include "obj_pstk.h" +#include "vtpadstack.h" +#include "layer.h" +#include "thermal.h" + +typedef enum { + PCB_BB_NONE, /* no drill */ + PCB_BB_THRU, /* all way thru */ + PCB_BB_BB, + PCB_BB_INVALID +} pcb_bb_type_t; + +/* Returns the ID of a proto within its parent's cache */ +RND_INLINE rnd_cardinal_t pcb_pstk_get_proto_id(const pcb_pstk_proto_t *proto) +{ + pcb_data_t *data = proto->parent; + if ((proto >= data->ps_protos.array) && (proto < data->ps_protos.array + data->ps_protos.used)) + return proto - data->ps_protos.array; + assert(!"padstack proto is not in its own parent!"); + return PCB_PADSTACK_INVALID; +} + +/* return the padstack prototype for a padstack reference - returns NULL if not found */ +RND_INLINE pcb_pstk_proto_t *pcb_pstk_get_proto_(const pcb_data_t *data, rnd_cardinal_t proto) +{ + if (proto >= data->ps_protos.used) + return NULL; + if (data->ps_protos.array[proto].in_use == 0) + return NULL; + return data->ps_protos.array + proto; +} + +/* return the padstack prototype for a padstack reference - returns NULL if not found */ +RND_INLINE pcb_pstk_proto_t *pcb_pstk_get_proto(const pcb_pstk_t *ps) +{ + return pcb_pstk_get_proto_(ps->parent.data, ps->proto); +} + +/* return the padstack transformed shape. Returns NULL if the proto or the + tshape is not. */ +RND_INLINE pcb_pstk_tshape_t *pcb_pstk_get_tshape_(const pcb_data_t *data, rnd_cardinal_t proto, int protoi) +{ + pcb_pstk_proto_t *pr = pcb_pstk_get_proto_(data, proto); + if (protoi < 0) + return NULL; + if (pr == NULL) + return NULL; + if (protoi >= pr->tr.used) + return NULL; + return &pr->tr.array[protoi]; +} + +/* return the padstack transformed shape for a padstack reference considering its + transformations - returns NULL if not found */ +RND_INLINE pcb_pstk_tshape_t *pcb_pstk_get_tshape(pcb_pstk_t *ps) +{ + if (ps->protoi < 0) { /* need to update this */ + pcb_pstk_proto_t *pr = pcb_pstk_get_proto_(ps->parent.data, ps->proto); + if (pr == NULL) + return NULL; + return pcb_pstk_make_tshape(ps->parent.data, pr, ps->rot, ps->xmirror, ps->smirror, &ps->protoi); + } + return pcb_pstk_get_tshape_(ps->parent.data, ps->proto, ps->protoi); +} + +/* return the padstack *untransformed* prototype for a padstack reference - returns NULL if not found */ +RND_INLINE pcb_pstk_tshape_t *pcb_pstk_get_untshape(pcb_pstk_t *ps) +{ + pcb_pstk_proto_t *pr = pcb_pstk_get_proto_(ps->parent.data, ps->proto); + if (pr == NULL) + return NULL; + return &pr->tr.array[0]; +} + +/* return the type of drill and optionally fill in group IDs of drill ends ; + if proto_out is not NULL, also load it with the proto */ +RND_INLINE pcb_bb_type_t pcb_pstk_bbspan(pcb_board_t *pcb, const pcb_pstk_t *ps, rnd_layergrp_id_t *top, rnd_layergrp_id_t *bottom, pcb_pstk_proto_t **proto_out) +{ + pcb_bb_type_t res; + int topi, boti; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + + if (proto_out != NULL) + *proto_out = proto; + + if (proto == NULL) + return PCB_BB_INVALID; + + /* most common case should be quick */ + if (!PCB_PSTK_PROTO_CUTS(proto)) { + if (top != NULL) *top = -1; + if (bottom != NULL) *bottom = -1; + return PCB_BB_NONE; + } + + if ((proto->htop == 0) && (proto->hbottom == 0)) { + if ((top == NULL) && (bottom == NULL)) + return PCB_BB_THRU; + res = PCB_BB_THRU; + } + else + res = PCB_BB_BB; + + /* slower case: need to look up start and end */ + if (!pcb->LayerGroups.cache.copper_valid) + pcb_layergrp_copper_cache_update(&pcb->LayerGroups); + + if (proto->htop >= 0) { + /* positive: count from top copper down, bump at bottom */ + if (proto->htop < pcb->LayerGroups.cache.copper_len) + topi = proto->htop; + else + topi = pcb->LayerGroups.cache.copper_len - 1; + } + else { + /* negative: count from bottom copper up, bump at top */ + topi = pcb->LayerGroups.cache.copper_len - 1 - proto->htop; + if (topi < 0) + topi = 0; + } + + if (proto->hbottom >= 0) { + /* positive: count from bottom copper up, bump at top */ + if (proto->hbottom < pcb->LayerGroups.cache.copper_len-1) + boti = pcb->LayerGroups.cache.copper_len-1-proto->hbottom; + else + boti = 0; + } + else { + /* positive: count from top copper down, bump at bottom */ + boti = -proto->hbottom; + if (boti > pcb->LayerGroups.cache.copper_len - 1) + boti = pcb->LayerGroups.cache.copper_len - 1; + } + + if (boti <= topi) { + if (top != NULL) *top = -1; + if (bottom != NULL) *bottom = -1; + return PCB_BB_INVALID; + } + + if ((topi < 0) || (boti < 0)) { + /* special case: if there's no top or bottom copper, we do not know where to count from - do not support bbvias */ + return PCB_BB_THRU; + } + + if (top != NULL) *top = pcb->LayerGroups.cache.copper[topi]; + if (bottom != NULL) *bottom = pcb->LayerGroups.cache.copper[boti]; + + return res; +} + +/* return whether a given padstack drills a given group + (does not consider plating, only drill!) */ +RND_INLINE rnd_bool_t pcb_pstk_bb_drills(pcb_board_t *pcb, const pcb_pstk_t *ps, rnd_layergrp_id_t grp, pcb_pstk_proto_t **proto_out) +{ + rnd_layergrp_id_t top, bot; + pcb_bb_type_t res = pcb_pstk_bbspan(pcb, ps, &top, &bot, proto_out); + switch(res) { + case PCB_BB_THRU: return rnd_true; + case PCB_BB_NONE: case PCB_BB_INVALID: return 0; + case PCB_BB_BB: return (grp <= bot) && (grp >= top); + } + return rnd_false; +} + +/* returns the shape the padstack has on the given layer group; + WARNING: does not respect the NOSHAPE thermal, should NOT be + called directly; use pcb_pstk_shape_*() instead. */ +RND_INLINE pcb_pstk_shape_t *pcb_pstk_shape(pcb_pstk_t *ps, pcb_layer_type_t lyt, pcb_layer_combining_t comb) +{ + int n; + pcb_pstk_tshape_t *ts = pcb_pstk_get_tshape(ps); + if (ts == NULL) + return NULL; + + lyt &= (PCB_LYT_ANYTHING | PCB_LYT_ANYWHERE); + for(n = 0; n < ts->len; n++) + if ((lyt == ts->shape[n].layer_mask) && (comb == ts->shape[n].comb)) + return ts->shape+n; + + return 0; +} + +/* returns the shape the non-transformed padstack has on the given layer group; + Useful for GUI dialogs only, for presenting the prototype (not the actual ps transformed reality) + WARNING: does not respect the NOSHAPE thermal, should NOT be + called directly; use pcb_pstk_shape_*() instead. */ +RND_INLINE pcb_pstk_shape_t *pcb_pstk_shape_notransform(pcb_pstk_t *ps, pcb_layer_type_t lyt, pcb_layer_combining_t comb) +{ + int n; + pcb_pstk_tshape_t *ts = pcb_pstk_get_untshape(ps); + + if (ts == NULL) + return NULL; + + lyt &= (PCB_LYT_ANYTHING | PCB_LYT_ANYWHERE); + for(n = 0; n < ts->len; n++) + if ((lyt == ts->shape[n].layer_mask) && (comb == ts->shape[n].comb)) + return ts->shape+n; + + return 0; +} + +/* If force is non-zero, return the shape even if a thermal says no-shape */ +RND_INLINE pcb_pstk_shape_t *pcb_pstk_shape_at_(pcb_board_t *pcb, pcb_pstk_t *ps, pcb_layer_t *layer, int force) +{ + unsigned int lyt = pcb_layer_flags_(layer); + pcb_layer_combining_t comb = layer->comb; + + if (lyt & PCB_LYT_COPPER) { + rnd_layer_id_t lid; + if (lyt & PCB_LYT_INTERN) { + /* apply internal only if that layer has drill */ + if (!pcb_pstk_bb_drills(pcb, ps, pcb_layer_get_group_(layer), NULL)) + return NULL; + } + + /* special case: if thermal says 'no shape' on this layer, omit the shape */ + if (!force) { + layer = pcb_layer_get_real(layer); + if ((layer != NULL) && (layer->parent.data != NULL)) { + lid = pcb_layer_id(layer->parent.data, layer); + if (lid < ps->thermals.used) { + if ((ps->thermals.shape[lid] & PCB_THERMAL_ON) && ((ps->thermals.shape[lid] & 3) == PCB_THERMAL_NOSHAPE)) + return NULL; + } + } + } + } + + /* combining is always 0 for copper */ + if (lyt & PCB_LYT_COPPER) + comb = 0; + else + comb = layer->comb; + + return pcb_pstk_shape(ps, lyt, comb); +} + +RND_INLINE pcb_pstk_shape_t *pcb_pstk_shape_at(pcb_board_t *pcb, pcb_pstk_t *ps, pcb_layer_t *layer) +{ + return pcb_pstk_shape_at_(pcb, ps, layer, 0); +} + + +RND_INLINE pcb_pstk_shape_t *pcb_pstk_shape_gid(pcb_board_t *pcb, pcb_pstk_t *ps, rnd_layergrp_id_t gid, pcb_layer_combining_t comb, pcb_layergrp_t **grp_out) +{ + pcb_layergrp_t *grp = pcb_get_layergrp(pcb, gid); + + if (grp_out != NULL) + *grp_out = grp; + + if ((grp == NULL) || (grp->len < 1)) + return NULL; + + if (grp->ltype & PCB_LYT_COPPER) { + int n, nosh; + + /* blind/buried: intern layer has no shape if no hole */ + if (grp->ltype & PCB_LYT_INTERN) { + /* apply internal only if that layer has drill */ + if (!pcb_pstk_bb_drills(pcb, ps, gid, NULL)) + return NULL; + } + + /* if all layers of the group says no-shape, don't have a shape */ + for(n = 0, nosh = 0; n < grp->len; n++) { + rnd_layer_id_t lid = grp->lid[n]; + if ((lid < ps->thermals.used) && (ps->thermals.shape[lid] & PCB_THERMAL_ON) && ((ps->thermals.shape[lid] & 3) == PCB_THERMAL_NOSHAPE)) + nosh++; + } + if (nosh == grp->len) + return NULL; + } + + /* normal procedure: go by group flags */ + return pcb_pstk_shape(ps, grp->ltype, comb); +} + +/* Returns the mech shape (slot) if it affects grp */ +RND_INLINE pcb_pstk_shape_t *pcb_pstk_shape_mech_gid(pcb_board_t *pcb, pcb_pstk_t *ps, rnd_layergrp_id_t grp) +{ + pcb_pstk_tshape_t *ts; + pcb_pstk_proto_t *proto; + + if (!pcb_pstk_bb_drills(pcb, ps, grp, &proto)) + return NULL; /* span: blind/buried, not reaching grp */ + + if (proto->mech_idx < 0) + return NULL; /* no mech shape -> no slot */ + + ts = pcb_pstk_get_tshape(ps); + return ts->shape + proto->mech_idx; +} + +/* Returns the mech shape (slot) if it affects layer */ +RND_INLINE pcb_pstk_shape_t *pcb_pstk_shape_mech_at(pcb_board_t *pcb, pcb_pstk_t *ps, pcb_layer_t *layer) +{ + layer = pcb_layer_get_real(layer); + if (layer == NULL) + return NULL; + return pcb_pstk_shape_mech_gid(pcb, ps, layer->meta.real.grp); +} + +/* Returns a shape corresponding to the hole or the mech shape (slot) regardless + of layers. + *DO NOT USE*, this call is designed for padstack internal code. Use + pcb_pstk_shape_mech_or_hole_at() instead. (Hole shape is created in holetmp) */ +RND_INLINE pcb_pstk_shape_t *pcb_pstk_shape_mech_or_hole_(pcb_pstk_t *ps, pcb_pstk_proto_t *proto, pcb_pstk_shape_t *holetmp) +{ + pcb_pstk_tshape_t *ts; + + /* hole has priority */ + if (proto->hdia > 0) { + holetmp->shape = PCB_PSSH_CIRC; + holetmp->data.circ.dia = proto->hdia; + holetmp->data.circ.x = holetmp->data.circ.y = 0; + return holetmp; + } + + /* if there's no hole, check for slot */ + if (proto->mech_idx < 0) + return NULL; /* no mech shape -> no slot */ + + if (ps == NULL) + ts = &proto->tr.array[0]; + else + ts = pcb_pstk_get_tshape(ps); + return ts->shape + proto->mech_idx; +} + +/* Returns a shape corresponding to the hole or the mech shape (slot) if + it affects layer; hole shape is created in holetmp */ +RND_INLINE pcb_pstk_shape_t *pcb_pstk_shape_mech_or_hole_at(pcb_board_t *pcb, pcb_pstk_t *ps, pcb_layer_t *layer, pcb_pstk_shape_t *holetmp) +{ + pcb_pstk_proto_t *proto; + + layer = pcb_layer_get_real(layer); + if (layer == NULL) + return NULL; + + if (!pcb_pstk_bb_drills(pcb, ps, pcb_layer_get_group_(layer), &proto)) + return NULL; + + return pcb_pstk_shape_mech_or_hole_(ps, proto, holetmp); +} + +/* Return the shape of the hshadow, if it is not the same as the forbidden + shape. The forbidden shape should be the shape that triggers the lookup. + tmpshp should be a local temporary shape where the circular shape for a + hole can be built. */ +RND_INLINE pcb_pstk_shape_t *pcb_pstk_hshadow_shape(pcb_pstk_t *ps, pcb_pstk_shape_t *forbidden, pcb_pstk_shape_t *tmpshp) +{ + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + pcb_pstk_tshape_t *ts = pcb_pstk_get_tshape(ps); + + /* slot */ + if (proto->mech_idx >= 0) { + pcb_pstk_shape_t *s = ts->shape + proto->mech_idx; + if (s == forbidden) /* self-ref: hshadow in a mech layer type */ + return NULL; + return s; + } + + /* hole */ + tmpshp->shape = PCB_PSSH_CIRC; + tmpshp->data.circ.x = 0; + tmpshp->data.circ.y = 0; + tmpshp->data.circ.dia = proto->hdia; + return tmpshp; +} + +#endif Index: tags/2.3.0/src/obj_pstk_list.c =================================================================== --- tags/2.3.0/src/obj_pstk_list.c (nonexistent) +++ tags/2.3.0/src/obj_pstk_list.c (revision 33253) @@ -0,0 +1,29 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#define TDL_DONT_UNDEF +#include "obj_pstk_list.h" +#include Index: tags/2.3.0/src/obj_pstk_list.h =================================================================== --- tags/2.3.0/src/obj_pstk_list.h (nonexistent) +++ tags/2.3.0/src/obj_pstk_list.h (revision 33253) @@ -0,0 +1,51 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_PSTK_LIST_H +#define PCB_OBJ_PSTK_LIST_H + +#define PCB_PADSTACK_STRUCT_ONLY +#include "obj_pstk.h" + + +/* List of padstatcks */ +#define TDL(x) padstacklist_ ## x +#define TDL_LIST_T padstacklist_t +#define TDL_ITEM_T pcb_pstk_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define padstacklist_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + + +#include +#include + +#undef PCB_PADSTACK_STRUCT_ONLY + +#endif Index: tags/2.3.0/src/obj_pstk_op.c =================================================================== --- tags/2.3.0/src/obj_pstk_op.c (nonexistent) +++ tags/2.3.0/src/obj_pstk_op.c (revision 33253) @@ -0,0 +1,327 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "polygon.h" +#include "rotate.h" + +void *pcb_pstkop_add_to_buffer(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + pcb_pstk_t *p; + rnd_cardinal_t npid; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + if (proto == NULL) + return NULL; + + npid = pcb_pstk_proto_insert_dup(ctx->buffer.dst, proto, 1, 0); + p = pcb_pstk_new_tr(ctx->buffer.dst, -1, npid, ps->x, ps->y, ps->Clearance, pcb_flag_mask(ps->Flags, PCB_FLAG_FOUND | ctx->buffer.extraflg), ps->rot, ps->xmirror, ps->smirror); + if (ctx->buffer.keep_id) pcb_obj_change_id((pcb_any_obj_t *)p, ps->ID); + return pcb_pstk_copy_meta(p, ps); +} + +/* Move between board and buffer */ +void *pcb_pstkop_move_buffer(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + rnd_cardinal_t npid; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + if (proto == NULL) + return NULL; + + npid = pcb_pstk_proto_insert_dup(ctx->buffer.dst, proto, 1, 0); + + pcb_poly_restore_to_poly(ctx->buffer.src, PCB_OBJ_PSTK, NULL, ps); + rnd_r_delete_entry(ctx->buffer.src->padstack_tree, (rnd_box_t *)ps); + + pcb_pstk_unreg(ps); + ps->proto = npid; + ps->protoi = -1; /* only the canonical trshape got copied, not the transofrmed ones */ + pcb_pstk_reg(ctx->buffer.dst, ps); + + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND, ps); + + if (!ctx->buffer.dst->padstack_tree) + ctx->buffer.dst->padstack_tree = rnd_r_create_tree(); + + rnd_r_insert_entry(ctx->buffer.dst->padstack_tree, (rnd_box_t *)ps); + pcb_poly_clear_from_poly(ctx->buffer.dst, PCB_OBJ_PSTK, NULL, ps); + + return ps; +} + +void *pcb_pstkop_copy(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + pcb_pstk_t *nps; + pcb_data_t *data = ctx->copy.pcb->Data; + rnd_cardinal_t npid; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + + if (proto == NULL) + return NULL; + npid = pcb_pstk_proto_insert_dup(data, proto, 1, 0); + + nps = pcb_pstk_new_tr(data, -1, npid, ps->x + ctx->copy.DeltaX, ps->y + ctx->copy.DeltaY, ps->Clearance, pcb_flag_mask(ps->Flags, PCB_FLAG_FOUND), ps->rot, ps->xmirror, ps->smirror); + if (nps == NULL) + return NULL; + + if (ctx->copy.keep_id) + nps->ID = ps->ID; + pcb_pstk_copy_meta(nps, ps); + pcb_pstk_invalidate_draw(nps); + pcb_undo_add_obj_to_create(PCB_OBJ_PSTK, data, nps, nps); + return nps; +} + +void *pcb_pstkop_move_noclip(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + pcb_pstk_invalidate_erase(ps); + pcb_pstk_move_(ps, ctx->move.dx, ctx->move.dy); + pcb_pstk_invalidate_draw(ps); + return ps; +} + +void *pcb_pstkop_move(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + pcb_data_t *data = ps->parent.data; + assert(ps->parent_type = PCB_PARENT_DATA); + + rnd_r_delete_entry(data->padstack_tree, (rnd_box_t *)ps); + pcb_poly_restore_to_poly(data, PCB_OBJ_PSTK, NULL, ps); + pcb_pstkop_move_noclip(ctx, ps); + rnd_r_insert_entry(data->padstack_tree, (rnd_box_t *)ps); + pcb_poly_clear_from_poly(data, PCB_OBJ_PSTK, NULL, ps); + pcb_subc_part_changed(ps); + return ps; +} + +void *pcb_pstkop_clip(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + pcb_data_t *data = ps->parent.data; + assert(ps->parent_type = PCB_PARENT_DATA); + + if (ctx->clip.restore) { + if (data->padstack_tree != NULL) + rnd_r_delete_entry(data->padstack_tree, (rnd_box_t *)ps); + pcb_poly_restore_to_poly(data, PCB_OBJ_PSTK, NULL, ps); + } + if (ctx->clip.clear) { + if (data->padstack_tree != NULL) + rnd_r_insert_entry(data->padstack_tree, (rnd_box_t *)ps); + pcb_poly_clear_from_poly(data, PCB_OBJ_PSTK, NULL, ps); + } + + return ps; +} + +void *pcb_pstkop_remove(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + pcb_pstk_invalidate_erase(ps); + pcb_undo_move_obj_to_remove(PCB_OBJ_PSTK, ps, ps, ps); + pcb_subc_part_changed(ps); + return NULL; +} + +void *pcb_pstkop_destroy(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + rnd_r_delete_entry(ctx->remove.destroy_target->padstack_tree, (rnd_box_t *)ps); + pcb_pstk_free(ps); + return NULL; +} + +void *pcb_pstkop_change_thermal(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, ps)) + return NULL; + + pcb_pstk_set_thermal(ps, ctx->chgtherm.lid, ctx->chgtherm.style, 1); + return ps; +} + +void *pcb_pstkop_change_flag(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + static pcb_flag_values_t pcb_pstk_flags = 0; + + if (pcb_pstk_flags == 0) + pcb_pstk_flags = pcb_obj_valid_flags(PCB_OBJ_PSTK); + + if ((ctx->chgflag.flag & pcb_pstk_flags) != ctx->chgflag.flag) + return NULL; + if ((ctx->chgflag.flag & PCB_FLAG_TERMNAME) && (ps->term == NULL)) + return NULL; + pcb_undo_add_obj_to_flag(ps); + PCB_FLAG_CHANGE(ctx->chgflag.how, ctx->chgflag.flag, ps); + return ps; +} + + +void *pcb_pstkop_rotate(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + double rot = ps->rot; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, ps)) + return NULL; + + if (ps->xmirror) + rot -= (double)ctx->rotate.angle; + else + rot += (double)ctx->rotate.angle; + + if ((rot > 360.0) || (rot < -360.0)) + rot = fmod(rot, 360.0); + + if ((rot == 360.0) || (rot == -360.0)) + rot = 0; + + if (pcb_pstk_change_instance(ps, NULL, NULL, &rot, NULL, NULL) == 0) { + rnd_coord_t nx = ps->x, ny = ps->y; + + + pcb_poly_restore_to_poly(ps->parent.data, PCB_OBJ_PSTK, NULL, ps); + pcb_pstk_invalidate_erase(ps); + if (ps->parent.data->padstack_tree != NULL) + rnd_r_delete_entry(ps->parent.data->padstack_tree, (rnd_box_t *)ps); + + rnd_rotate(&nx, &ny, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.cosa, ctx->rotate.sina); + if ((nx != ps->x) || (ny != ps->y)) + pcb_pstk_move_(ps, nx - ps->x, ny - ps->y); + + pcb_pstk_bbox(ps); + if (ps->parent.data->padstack_tree != NULL) + rnd_r_insert_entry(ps->parent.data->padstack_tree, (rnd_box_t *)ps); + pcb_poly_clear_from_poly(ps->parent.data, PCB_OBJ_PSTK, NULL, ps); + pcb_pstk_invalidate_draw(ps); + + pcb_subc_part_changed(ps); + return ps; + } + return NULL; +} + +void *pcb_pstkop_rotate90(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + ctx->rotate.angle = (double)ctx->rotate.number * 90.0; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, ps)) + return NULL; + + switch(ctx->rotate.number) { + case 0: + ctx->rotate.sina = 0; + ctx->rotate.cosa = 1; + break; + case 1: + ctx->rotate.sina = 1; + ctx->rotate.cosa = 0; + break; + case 2: + ctx->rotate.sina = 0; + ctx->rotate.cosa = -1; + break; + case 3: + ctx->rotate.sina = -1; + ctx->rotate.cosa = 0; + break; + } + return pcb_pstkop_rotate(ctx, ps); +} + +void *pcb_pstkop_change_size(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + pcb_pstk_proto_t proto; + rnd_cardinal_t nproto; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, ps)) + return NULL; + + /* create the new prototype and insert it */ + pcb_pstk_proto_copy(&proto, pcb_pstk_get_proto(ps)); + pcb_pstk_proto_grow(&proto, ctx->chgsize.is_absolute, ctx->chgsize.value); + nproto = pcb_pstk_proto_insert_dup(ps->parent.data, &proto, 1, 0); + pcb_pstk_proto_free_fields(&proto); + + if (nproto == PCB_PADSTACK_INVALID) + return NULL; + + if (pcb_pstk_change_instance(ps, &nproto, NULL, NULL, NULL, NULL) == 0) { + pcb_subc_part_changed(ps); + return ps; + } + + return NULL; +} + +void *pcb_pstkop_change_clear_size(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + rnd_coord_t value = (ctx->chgsize.is_absolute) ? ctx->chgsize.value / 2 : ps->Clearance + ctx->chgsize.value / 2; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, ps)) + return NULL; + if (value < 0) + value = 0; + value = MIN(PCB_MAX_THICKNESS, value); + if (!ctx->chgsize.is_absolute && (ctx->chgsize.value < 0)) + value = 0; + if (ps->Clearance == value) + return NULL; + + if (pcb_pstk_change_instance(ps, NULL, &value, NULL, NULL, NULL) == 0) { + pcb_subc_part_changed(ps); + return ps; + } + + return NULL; +} + + +void *pcb_pstkop_change_2nd_size(pcb_opctx_t *ctx, pcb_pstk_t *ps) +{ + pcb_pstk_proto_t proto; + rnd_cardinal_t nproto; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, ps)) + return NULL; + + /* create the new prototype and insert it */ + pcb_pstk_proto_copy(&proto, pcb_pstk_get_proto(ps)); + if (!ctx->chgsize.is_absolute) { + proto.hdia += ctx->chgsize.value; + if (proto.hdia < 2) + proto.hdia = 2; + } + else + proto.hdia = ctx->chgsize.value; + nproto = pcb_pstk_proto_insert_dup(ps->parent.data, &proto, 1, 0); + pcb_pstk_proto_free_fields(&proto); + + if (nproto == PCB_PADSTACK_INVALID) + return NULL; + + if (pcb_pstk_change_instance(ps, &nproto, NULL, NULL, NULL, NULL) == 0) { + pcb_subc_part_changed(ps); + return ps; + } + + return NULL; +} + Index: tags/2.3.0/src/obj_pstk_op.h =================================================================== --- tags/2.3.0/src/obj_pstk_op.h (nonexistent) +++ tags/2.3.0/src/obj_pstk_op.h (revision 33253) @@ -0,0 +1,54 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/*** Standard operations on padstacks ***/ + +#include "operation.h" + +void *pcb_pstkop_add_to_buffer(pcb_opctx_t *ctx, pcb_pstk_t *ps); +void *pcb_pstkop_move_buffer(pcb_opctx_t *ctx, pcb_pstk_t *ps); + +void *pcb_pstkop_copy(pcb_opctx_t *ctx, pcb_pstk_t *ps); +void *pcb_pstkop_move(pcb_opctx_t *ctx, pcb_pstk_t *ps); +void *pcb_pstkop_move_noclip(pcb_opctx_t *ctx, pcb_pstk_t *ps); +void *pcb_pstkop_clip(pcb_opctx_t *ctx, pcb_pstk_t *ps); +void *pcb_pstkop_remove(pcb_opctx_t *ctx, pcb_pstk_t *ps); +void *pcb_pstkop_destroy(pcb_opctx_t *ctx, pcb_pstk_t *ps); + +void *pcb_pstkop_change_thermal(pcb_opctx_t *ctx, pcb_pstk_t *ps); + +void *pcb_pstkop_change_flag(pcb_opctx_t *ctx, pcb_pstk_t *ps); + +void *pcb_pstkop_rotate90(pcb_opctx_t *ctx, pcb_pstk_t *ps); +void *pcb_pstkop_rotate(pcb_opctx_t *ctx, pcb_pstk_t *ps); + +void *pcb_pstkop_change_size(pcb_opctx_t *ctx, pcb_pstk_t *ps); +void *pcb_pstkop_change_clear_size(pcb_opctx_t *ctx, pcb_pstk_t *ps); /* changes the global clearance */ +void *pcb_pstkop_change_2nd_size(pcb_opctx_t *ctx, pcb_pstk_t *ps); + +/*** TODO: unimplemented ones ***/ + +void *pcb_pstkop_change_clear_size(pcb_opctx_t *ctx, pcb_pstk_t *ps); Index: tags/2.3.0/src/obj_pstk_proto.c =================================================================== --- tags/2.3.0/src/obj_pstk_proto.c (nonexistent) +++ tags/2.3.0/src/obj_pstk_proto.c (revision 33253) @@ -0,0 +1,1743 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include "board.h" +#include "buffer.h" +#include +#include "conf_core.h" +#include "data.h" +#include "data_list.h" +#include "obj_pstk.h" +#include "obj_pstk_op.h" +#include "obj_pstk_inlines.h" +#include "rotate.h" +#include "undo.h" +#include "vtpadstack_t.h" +#include "obj_hash.h" +#include "funchash_core.h" +#include + +static const char core_proto_cookie[] = "padstack prototypes"; + + +void pcb_pstk_proto_free_fields(pcb_pstk_proto_t *dst) +{ + int n, i; + pcb_pstk_tshape_t *ts; + + for(n = 0, ts = &dst->tr.array[0]; n < dst->tr.used; n++,ts++) { + for(i = 0; i < ts->len; i++) + pcb_pstk_shape_free(&ts->shape[i]); + ts->len = 0; + free(ts->shape); + } + free(dst->name); + free(dst->tr.array); + memset(dst, 0, sizeof(pcb_pstk_proto_t)); +} + +void pcb_pstk_proto_update(pcb_pstk_proto_t *dst) +{ + static pcb_pstk_t dummy_ps = {0}; + pcb_pstk_tshape_t *ts = &dst->tr.array[0]; + unsigned int n, coppers = 0; + + dst->hash = pcb_pstk_proto_hash(dst); + dst->mech_idx = -1; + + if (ts != NULL) { + pcb_pstk_shape_t *hole, holetmp; + + /* find and cache the index of the mech shape (slot) */ + for(n = 0; n < ts->len; n++) { + if (ts->shape[n].layer_mask & PCB_LYT_MECH) { + dst->mech_idx = n; + break; + } + } + +/*rnd_trace("pstk_upd:\n");*/ + + /* mark each shape with whether it overlaps with the hole/mech shape or not */ + hole = pcb_pstk_shape_mech_or_hole_(NULL, dst, &holetmp); + dst->all_copper_connd = (hole != NULL); + for(n = 0; n < ts->len; n++) { + if ((ts->shape[n].layer_mask & PCB_LYT_COPPER) && !(ts->shape[n].layer_mask & PCB_LYT_INTERN)) + coppers++; + if (hole == &ts->shape[n]) + ts->shape[n].hconn = 1; + else if (hole != NULL) { + ts->shape[n].hconn = pcb_pstk_shape_intersect(&dummy_ps, &ts->shape[n], &dummy_ps, hole); + if ((ts->shape[n].layer_mask & PCB_LYT_COPPER) && !ts->shape[n].hconn) + dst->all_copper_connd = 0; + } + else + ts->shape[n].hconn = 0; +/*rnd_trace(" [%d]: %d\n", n, ts->shape[n].hconn);*/ + } + + /* special case: if there's only one non-intern copper shape and no hole/slot + (which is the common "SMD pad" case), allow find.c to run the quick + code by admitting all copper shapes are connected */ + if ((hole == NULL) && (coppers == 1)) + dst->all_copper_connd = 1; +/*rnd_trace(" all: %d\n", dst->all_copper_connd);*/ + } +} + +void pcb_pstk_shape_alloc_poly(pcb_pstk_poly_t *poly, int len) +{ + poly->x = malloc(sizeof(poly->x[0]) * len * 2); + poly->y = poly->x + len; + poly->len = len; + poly->pa = NULL; +} + +void pcb_pstk_shape_free_poly(pcb_pstk_poly_t *poly) +{ + if (poly->pa != NULL) + rnd_polyarea_free(&poly->pa); + free(poly->x); + poly->len = 0; +} + +void pcb_pstk_shape_copy_poly(pcb_pstk_poly_t *dst, const pcb_pstk_poly_t *src) +{ + memcpy(dst->x, src->x, sizeof(src->x[0]) * src->len * 2); + pcb_pstk_shape_update_pa(dst); +} + +int pcb_pstk_get_shape_idx(pcb_pstk_tshape_t *ts, pcb_layer_type_t lyt, pcb_layer_combining_t comb) +{ + int n; + for(n = 0; n < ts->len; n++) + if ((lyt == ts->shape[n].layer_mask) && (comb == ts->shape[n].comb)) + return n; + return -1; +} + +pcb_pstk_shape_t *pcb_pstk_alloc_append_shape(pcb_pstk_tshape_t *ts) +{ + int idx = ts->len; + + ts->len++; + ts->shape = realloc(ts->shape, ts->len * sizeof(pcb_pstk_shape_t)); + + return &ts->shape[idx]; +} + +static void append_circle(pcb_pstk_tshape_t *ts, pcb_layer_type_t lyt, pcb_layer_combining_t comb, rnd_coord_t dia) +{ + int idx = ts->len; + + ts->len++; + ts->shape = realloc(ts->shape, ts->len * sizeof(pcb_pstk_shape_t)); + + ts->shape[idx].shape = PCB_PSSH_CIRC; + ts->shape[idx].data.circ.x = ts->shape[idx].data.circ.y = 0; + ts->shape[idx].data.circ.dia = dia; + ts->shape[idx].layer_mask = lyt; + ts->shape[idx].comb = comb; +} + +static void append_tshape(pcb_pstk_tshape_t *ts, pcb_pstk_tshape_t *src, int srci) +{ + int idx = ts->len; + + ts->len++; + ts->shape = realloc(ts->shape, ts->len * sizeof(pcb_pstk_shape_t)); + memcpy(&ts->shape[idx], &src->shape[srci], sizeof(ts->shape[idx])); + switch(src->shape[srci].shape) { + case PCB_PSSH_LINE: + case PCB_PSSH_CIRC: + case PCB_PSSH_HSHADOW: + break; /* do nothing, all fields are copied already by the memcpy */ + case PCB_PSSH_POLY: + pcb_pstk_shape_alloc_poly(&ts->shape[idx].data.poly, src->shape[srci].data.poly.len); + pcb_pstk_shape_copy_poly(&ts->shape[idx].data.poly, &src->shape[srci].data.poly); + break; + } +} + +int pcb_pstk_proto_conv(pcb_data_t *data, pcb_pstk_proto_t *dst, int quiet, vtp0_t *objs, rnd_coord_t ox, rnd_coord_t oy) +{ + int ret = -1, n, m, i, extra_obj = 0, has_slot = 0, has_hole = 0; + pcb_any_obj_t **o; + pcb_pstk_tshape_t *ts, *ts_src; + pcb_pstk_t *pstk = NULL; + pcb_pstk_proto_t *prt; + + dst->in_use = 1; + dst->name = NULL; + pcb_vtpadstack_tshape_init(&dst->tr); + dst->hdia = 0; + dst->htop = dst->hbottom = 0; + + /* allocate shapes on the canonical tshape (tr[0]) */ + ts = pcb_vtpadstack_tshape_alloc_append(&dst->tr, 1); + ts->rot = 0.0; + ts->xmirror = 0; + ts->smirror = 0; + ts->len = 0; + for(n = 0, o = (pcb_any_obj_t **)objs->array; n < vtp0_len(objs); n++,o++) { + pcb_layer_t *ly = (*o)->parent.layer; + pcb_layer_type_t lyt = pcb_layer_flags_(ly); + + if (lyt & PCB_LYT_MECH) { + int purpi; + if (has_slot) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Padstack conversion: multiple mechanical objects (slots) are not allowed\n"); + goto quit; + } + has_slot++; + purpi = pcb_layer_purpose_(ly, NULL); + dst->hplated = !!PCB_LAYER_IS_PROUTE(lyt, purpi); + } + + switch((*o)->type) { + case PCB_OBJ_LINE: + case PCB_OBJ_POLY: + ts->len++; + break; + case PCB_OBJ_PSTK: + if (pstk != NULL) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Padstack conversion: multiple vias/padstacks\n"); + goto quit; + } + pstk = *(pcb_pstk_t **)o; + prt = pcb_pstk_get_proto(pstk); + if (prt == NULL) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Padstack conversion: invalid input padstacks proto\n"); + goto quit; + } + if (prt->hdia > 0) + has_hole = 1; + dst->hdia = prt->hdia; + dst->hplated = prt->hplated; + if ((ox != pstk->x) || (oy != pstk->y)) { + rnd_message(RND_MSG_INFO, "Padstack conversion: adjusting origin to padstack hole\n"); + ox = pstk->x; + oy = pstk->y; + } + extra_obj++; + break; + default:; + if (!quiet) + rnd_message(RND_MSG_ERROR, "Padstack conversion: invalid object type (%x) selected; must be via, padstack, line or polygon\n", (*o)->type); + goto quit; + } + } + + if ((vtp0_len(objs) - extra_obj) > data->LayerN) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Padstack conversion: too many objects selected\n"); + goto quit; + } + + if ((ts->len == 0) && (pstk == NULL)) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Padstack conversion: there are no shapes and there is no via/padstack participating in the conversion; can not create empty padstack\n"); + goto quit; + } + + ts->shape = malloc(ts->len * sizeof(pcb_pstk_shape_t)); + + /* convert local (line/poly) objects */ + for(i = 0, n = -1, o = (pcb_any_obj_t **)objs->array; i < vtp0_len(objs); o++,i++) { + pcb_layer_t *ly; + switch((*o)->type) { + case PCB_OBJ_LINE: + { + pcb_line_t *line = (*(pcb_line_t **)o); + + n++; + if ((line->Point1.X != line->Point2.X) || (line->Point1.Y != line->Point2.Y)) { + ts->shape[n].shape = PCB_PSSH_LINE; + ts->shape[n].data.line.x1 = line->Point1.X - ox; + ts->shape[n].data.line.y1 = line->Point1.Y - oy; + ts->shape[n].data.line.x2 = line->Point2.X - ox; + ts->shape[n].data.line.y2 = line->Point2.Y - oy; + ts->shape[n].data.line.thickness = line->Thickness; + ts->shape[n].data.line.square = 0; + } + else { /* a zero-long line is really a circle - padstacks have a specific shape for that */ + ts->shape[n].shape = PCB_PSSH_CIRC; + ts->shape[n].data.circ.x = line->Point1.X - ox; + ts->shape[n].data.circ.y = line->Point1.Y - oy; + ts->shape[n].data.circ.dia = line->Thickness; + } + ts->shape[n].clearance = line->Clearance; + } + break; + case PCB_OBJ_POLY: + { + rnd_cardinal_t p, len, maxlen = (1L << ((sizeof(int)*8)-1)); + pcb_poly_t *poly = *(pcb_poly_t **)o; + + len = poly->PointN; + n++; + if (poly->HoleIndexN != 0) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Padstack conversion: can not convert polygon with holes\n"); + goto quit; + } + if (len >= maxlen) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Padstack conversion: polygon has too many points (%ld >= %ld)\n", (long)len, (long)maxlen); + goto quit; + } + pcb_pstk_shape_alloc_poly(&ts->shape[n].data.poly, len); + for(p = 0; p < len; p++) { + ts->shape[n].data.poly.x[p] = poly->Points[p].X - ox; + ts->shape[n].data.poly.y[p] = poly->Points[p].Y - oy; + } + pcb_pstk_shape_update_pa(&ts->shape[n].data.poly); + ts->shape[n].shape = PCB_PSSH_POLY; + ts->shape[n].clearance = (*(pcb_poly_t **)o)->Clearance; + } + break; + default: continue; + } + assert((*o)->parent_type == PCB_PARENT_LAYER); + ly = (*o)->parent.layer; + ts->shape[n].layer_mask = pcb_layer_flags_(ly); + ts->shape[n].comb = ly->comb; + + if (ts->shape[n].layer_mask & PCB_LYT_BOUNDARY) { + ts->shape[n].layer_mask &= ~PCB_LYT_BOUNDARY; + ts->shape[n].layer_mask |= PCB_LYT_MECH; + } + if (ts->shape[n].layer_mask & (PCB_LYT_PASTE | PCB_LYT_MASK | PCB_LYT_MECH)) + ts->shape[n].comb |= PCB_LYC_AUTO; + + for(m = 0; m < n; m++) { + if ((ts->shape[n].layer_mask == ts->shape[m].layer_mask) && (ts->shape[n].comb == ts->shape[m].comb)) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Padstack conversion: multiple objects on the same layer\n"); + goto quit; + } + } + if ((ts->shape[n].layer_mask & PCB_LYT_COPPER) && (ts->shape[n].layer_mask & PCB_LYT_INTERN) && (!has_hole) && (!has_slot)) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Padstack conversion: can not have internal copper shape if there is no hole\n"); + goto quit; + } + } + + if (has_hole && has_slot) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Padstack conversion: can not have both hole (padstack) and slot \n"); + goto quit; + } + + /* if there was a padstack, use the padstack's shape on layers that are not specified */ + if (pstk != NULL) { + int srci; + ts_src = pcb_pstk_get_tshape(pstk); + if (ts_src != NULL) { +# define MAYBE_COPY(mask, comb) \ + if ((pcb_pstk_get_shape_idx(ts, mask, comb) == -1) && ((srci = pcb_pstk_get_shape_idx(ts_src, mask, comb)) != -1)) \ + append_tshape(ts, ts_src, srci); + MAYBE_COPY(PCB_LYT_COPPER | PCB_LYT_TOP, 0); + MAYBE_COPY(PCB_LYT_COPPER | PCB_LYT_INTERN, 0); + MAYBE_COPY(PCB_LYT_COPPER | PCB_LYT_BOTTOM, 0); + MAYBE_COPY(PCB_LYT_MASK | PCB_LYT_BOTTOM, PCB_LYC_SUB | PCB_LYC_AUTO); + MAYBE_COPY(PCB_LYT_MASK | PCB_LYT_TOP, PCB_LYC_SUB | PCB_LYC_AUTO); + MAYBE_COPY(PCB_LYT_PASTE | PCB_LYT_BOTTOM, PCB_LYC_AUTO); + MAYBE_COPY(PCB_LYT_PASTE | PCB_LYT_TOP, PCB_LYC_AUTO); + MAYBE_COPY(PCB_LYT_MECH, PCB_LYC_AUTO); +# undef MAYBE_COPY + } + } + + /* all went fine */ + pcb_pstk_proto_update(dst); + ret = 0; + + quit:; + if (ret != 0) + pcb_pstk_proto_free_fields(dst); + return ret; +} + +int pcb_pstk_proto_breakup(pcb_data_t *dst, pcb_pstk_t *src, rnd_bool remove_src) +{ + pcb_pstk_tshape_t *ts = pcb_pstk_get_tshape(src); + int n, i; + pcb_layer_type_t lyt, filt = (PCB_LYT_ANYTHING | PCB_LYT_ANYWHERE); + pcb_any_obj_t *no; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(src); + + if (ts == NULL) + return -1; + + for(n = 0; n < ts->len; n++) { + pcb_pstk_shape_t *shp = &ts->shape[n]; + rnd_layer_id_t lid; + pcb_layer_t *ly, *ly1 = NULL, *ly2 = NULL, *ly3 = NULL; + rnd_coord_t clr; + pcb_poly_t *p; + + if ((shp->layer_mask & PCB_LYT_ANYTHING) == 0) + rnd_message(RND_MSG_ERROR, "ERROR: breaking up padstack prototype: shape %d has invalid layer type, placing it on a random layer\nTHIS PADSTACK PROTOTYPE MUST BE FIXED.\n"); + + /* look up the best layer type */ + for(lid = 0; lid < dst->LayerN; lid++) { + ly = &dst->Layer[lid]; + lyt = pcb_layer_flags_(ly); + +TODO("layer: make a real scoring mechanism here instead of ly1, ly2, ly3") + /* cheat: pretend boundary layers are mech layers because padstack layer types are interested only in mech layers */ + if (lyt & PCB_LYT_BOUNDARY) { + lyt &= ~PCB_LYT_BOUNDARY; + lyt |= PCB_LYT_MECH; + } + + if ((lyt & shp->layer_mask) == shp->layer_mask) { + int comb_match = (shp->comb == ly->comb); + int plate_match = 1; + + if (lyt & PCB_LYT_MECH) { /* check plating only for mech layers */ + int purpi = pcb_layer_purpose_(ly, NULL); + int ly_plated = !!PCB_LAYER_IS_PROUTE(lyt, purpi); + plate_match = (ly_plated == proto->hplated); + } + + if (comb_match && plate_match) { + ly1 = ly; + break; + } + else + ly2 = ly; + } + else if ((lyt & shp->layer_mask & filt) == (shp->layer_mask & filt)) + ly3 = ly; + } + + ly = ly1; + if (ly == NULL) ly = ly2; + if (ly == NULL) ly = ly3; + if (ly == NULL) { + const char *locs, *mats; + locs = pcb_layer_type_bit2str(lyt & PCB_LYT_ANYWHERE); + mats = pcb_layer_type_bit2str(lyt & PCB_LYT_ANYTHING); + if (locs == NULL) locs = ""; + if (mats == NULL) mats = ""; + rnd_message(RND_MSG_WARNING, "Can not create shape on %s %s\n", locs, mats); + continue; + } + + clr = src->Clearance == 0 ? shp->clearance : src->Clearance; + switch(shp->shape) { + case PCB_PSSH_CIRC: + no = (pcb_any_obj_t *)pcb_line_new(ly, + src->x + shp->data.circ.x, src->y + shp->data.circ.y, + src->x + shp->data.circ.x, src->y + shp->data.circ.y, + shp->data.circ.dia, clr, pcb_flag_make(PCB_FLAG_CLEARLINE)); + break; + case PCB_PSSH_LINE: + no = (pcb_any_obj_t *)pcb_line_new(ly, + src->x + shp->data.line.x1, src->y + shp->data.line.y1, + src->x + shp->data.line.x2, src->y + shp->data.line.y2, + shp->data.line.thickness, clr, pcb_flag_make(PCB_FLAG_CLEARLINE)); + break; + case PCB_PSSH_POLY: + p = pcb_poly_new(ly, clr, pcb_flag_make(PCB_FLAG_CLEARPOLYPOLY)); + for(i = 0; i < shp->data.poly.len; i++) + pcb_poly_point_new(p, src->x + shp->data.poly.x[i], src->y + shp->data.poly.y[i]); + pcb_add_poly_on_layer(ly, p); + no = (pcb_any_obj_t *)p; + break; + default: + assert(!"invalid shape"); + continue; + } + if (src->term != NULL) + pcb_attribute_put(&no->Attributes, "term", src->term); + } + + if (remove_src) { + if (src->parent.data->padstack_tree != NULL) + rnd_r_delete_entry(src->parent.data->padstack_tree, (rnd_box_t *)src); + pcb_pstk_free(src); + } + + return -1; +} + +int pcb_pstk_proto_conv_selection(pcb_board_t *pcb, pcb_pstk_proto_t *dst, int quiet, rnd_coord_t ox, rnd_coord_t oy) +{ + int ret; + vtp0_t objs; + + vtp0_init(&objs); + pcb_data_list_by_flag(pcb->Data, &objs, PCB_OBJ_CLASS_REAL, PCB_FLAG_SELECTED); + ret = pcb_pstk_proto_conv(pcb->Data, dst, quiet, &objs, ox, oy); + vtp0_uninit(&objs); + + return ret; +} + + +int pcb_pstk_proto_conv_buffer(pcb_pstk_proto_t *dst, int quiet) +{ + int ret; + vtp0_t objs; + rnd_coord_t ox, oy; + rnd_box_t bb; + + pcb_data_bbox(&bb, PCB_PASTEBUFFER->Data, 0); + + ox = (bb.X1 + bb.X2) / 2; + oy = (bb.Y1 + bb.Y2) / 2; + + vtp0_init(&objs); + pcb_data_list_by_flag(PCB_PASTEBUFFER->Data, &objs, PCB_OBJ_CLASS_REAL, 0); + ret = pcb_pstk_proto_conv(PCB_PASTEBUFFER->Data, dst, quiet, &objs, ox, oy); + vtp0_uninit(&objs); + + return ret; +} + +void pcb_pstk_shape_copy(pcb_pstk_shape_t *dst, pcb_pstk_shape_t *src) +{ + memcpy(dst, src, sizeof(pcb_pstk_shape_t)); + switch(src->shape) { + case PCB_PSSH_LINE: + case PCB_PSSH_CIRC: + case PCB_PSSH_HSHADOW: + break; /* do nothing, all fields are copied already by the memcpy */ + case PCB_PSSH_POLY: + pcb_pstk_shape_alloc_poly(&dst->data.poly, src->data.poly.len); + pcb_pstk_shape_copy_poly(&dst->data.poly, &src->data.poly); + break; + } +} + +void pcb_pstk_shape_free(pcb_pstk_shape_t *s) +{ + switch(s->shape) { + case PCB_PSSH_LINE: + case PCB_PSSH_CIRC: + case PCB_PSSH_HSHADOW: + break; /* no allocation */ + case PCB_PSSH_POLY: + pcb_pstk_shape_free_poly(&s->data.poly); + break; + } +} + +void pcb_pstk_tshape_copy(pcb_pstk_tshape_t *ts_dst, pcb_pstk_tshape_t *ts_src) +{ + int n; + + ts_dst->rot = ts_src->rot; + ts_dst->xmirror = ts_src->xmirror; + ts_dst->smirror = ts_src->smirror; + ts_dst->shape = malloc(sizeof(pcb_pstk_shape_t) * ts_src->len); + ts_dst->len = ts_src->len; + memcpy(ts_dst->shape, ts_src->shape, sizeof(pcb_pstk_shape_t) * ts_src->len); + for(n = 0; n < ts_src->len; n++) { + switch(ts_src->shape[n].shape) { + case PCB_PSSH_LINE: + case PCB_PSSH_CIRC: + case PCB_PSSH_HSHADOW: + break; /* do nothing, all fields are copied already by the memcpy */ + case PCB_PSSH_POLY: + pcb_pstk_shape_alloc_poly(&ts_dst->shape[n].data.poly, ts_src->shape[n].data.poly.len); + pcb_pstk_shape_copy_poly(&ts_dst->shape[n].data.poly, &ts_src->shape[n].data.poly); + break; + } + } +} + +void pcb_pstk_shape_rot(pcb_pstk_shape_t *sh, double sina, double cosa, double angle) +{ + int i; + + switch(sh->shape) { + case PCB_PSSH_LINE: + rnd_rotate(&sh->data.line.x1, &sh->data.line.y1, 0, 0, cosa, sina); + rnd_rotate(&sh->data.line.x2, &sh->data.line.y2, 0, 0, cosa, sina); + break; + case PCB_PSSH_CIRC: + rnd_rotate(&sh->data.circ.x, &sh->data.circ.y, 0, 0, cosa, sina); + break; + case PCB_PSSH_HSHADOW: + break; + case PCB_PSSH_POLY: + if (sh->data.poly.pa != NULL) + rnd_polyarea_free(&sh->data.poly.pa); + for(i = 0; i < sh->data.poly.len; i++) + rnd_rotate(&sh->data.poly.x[i], &sh->data.poly.y[i], 0, 0, cosa, sina); + pcb_pstk_shape_update_pa(&sh->data.poly); + break; + } +} + + +void pcb_pstk_tshape_rot(pcb_pstk_tshape_t *ts, double angle) +{ + int n; + double cosa = cos(angle / RND_RAD_TO_DEG), sina = sin(angle / RND_RAD_TO_DEG); + + for(n = 0; n < ts->len; n++) + pcb_pstk_shape_rot(&ts->shape[n], sina, cosa, angle); +} + +void pcb_pstk_tshape_xmirror(pcb_pstk_tshape_t *ts) +{ + int n, i; + + for(n = 0; n < ts->len; n++) { + pcb_pstk_shape_t *sh = &ts->shape[n]; + switch(sh->shape) { + case PCB_PSSH_LINE: + sh->data.line.y1 = -sh->data.line.y1; + sh->data.line.y2 = -sh->data.line.y2; + break; + case PCB_PSSH_CIRC: + sh->data.circ.y = -sh->data.circ.y; + break; + case PCB_PSSH_HSHADOW: + break; + case PCB_PSSH_POLY: + if (sh->data.poly.pa != NULL) + rnd_polyarea_free(&sh->data.poly.pa); + for(i = 0; i < sh->data.poly.len; i++) + sh->data.poly.y[i] = -sh->data.poly.y[i]; + + /* reverse order of data to keep normals pointing out */ + for(i = 0; i < sh->data.poly.len/2; i++) { + rnd_coord_t tx, ty; + int other = sh->data.poly.len-1-i; + tx = sh->data.poly.x[i]; + ty = sh->data.poly.y[i]; + sh->data.poly.x[i] = sh->data.poly.x[other]; + sh->data.poly.y[i] = sh->data.poly.y[other]; + sh->data.poly.x[other] = tx; + sh->data.poly.y[other] = ty; + } + pcb_pstk_shape_update_pa(&sh->data.poly); + break; + } + } +} + +RND_INLINE void pcb_pstk_shape_smirror_(pcb_pstk_shape_t *sh) +{ + if (sh->layer_mask & PCB_LYT_TOP) { + sh->layer_mask &= ~PCB_LYT_TOP; + sh->layer_mask |= PCB_LYT_BOTTOM; + } + else if (sh->layer_mask & PCB_LYT_BOTTOM) { + sh->layer_mask &= ~PCB_LYT_BOTTOM; + sh->layer_mask |= PCB_LYT_TOP; + } +} + +void pcb_pstk_shape_smirror(pcb_pstk_shape_t *sh) +{ + pcb_pstk_shape_smirror_(sh); +} + +void pcb_pstk_tshape_smirror(pcb_pstk_tshape_t *ts) +{ + int n; + + for(n = 0; n < ts->len; n++) + pcb_pstk_shape_smirror_(&ts->shape[n]); +} + +void pcb_pstk_proto_copy(pcb_pstk_proto_t *dst, const pcb_pstk_proto_t *src) +{ + pcb_pstk_tshape_t *ts_dst, *ts_src; + + memcpy(dst, src, sizeof(pcb_pstk_proto_t)); + if (src->name != NULL) + dst->name = rnd_strdup(src->name); + pcb_vtpadstack_tshape_init(&dst->tr); + + if (src->tr.used > 0) { + ts_src = &src->tr.array[0]; + + /* allocate shapes on the canonical tshape (tr[0]) */ + ts_dst = pcb_vtpadstack_tshape_alloc_append(&dst->tr, 1); + pcb_pstk_tshape_copy(ts_dst, ts_src); + + /* make sure it's the canonical form */ + ts_dst->rot = 0.0; + ts_dst->xmirror = 0; + ts_dst->smirror = 0; + } + + dst->in_use = 1; +} + + +/* Matches proto against all protos in data's cache; returns + PCB_PADSTACK_INVALID (and loads first_free_out) if not found */ +static rnd_cardinal_t pcb_pstk_proto_insert_try(pcb_data_t *data, const pcb_pstk_proto_t *proto, rnd_cardinal_t *first_free_out) +{ + rnd_cardinal_t n, first_free = PCB_PADSTACK_INVALID; + + /* look for the first existing padstack that matches */ + for(n = 0; n < pcb_vtpadstack_proto_len(&data->ps_protos); n++) { + if (!(data->ps_protos.array[n].in_use)) { + if (first_free == PCB_PADSTACK_INVALID) + first_free = n; + } + else if (data->ps_protos.array[n].hash == proto->hash) { + if (pcb_pstk_proto_eq(&data->ps_protos.array[n], proto)) + return n; + } + } + *first_free_out = first_free; + return PCB_PADSTACK_INVALID; +} + +/*** undoable prototype creation ***/ +typedef struct { + pcb_data_t *data; + pcb_pstk_proto_t proto; + long pid; + int in_data; +} undo_proto_set_t; + +static int undo_proto_set_swap(void *udata) +{ + undo_proto_set_t *a = udata; + pcb_pstk_proto_t *np; + + if (a->in_data) { /* move from data proto vector to undo struct */ + int n = pcb_vtpadstack_proto_len(&a->data->ps_protos); + if (n < a->pid) { + rnd_message(RND_MSG_ERROR, "undo_proto_set_swap(): not enough proto in data\n save and exit ASAP and report this bug!\n"); + return -1; + } + a->proto = a->data->ps_protos.array[a->pid]; + a->data->ps_protos.array[a->pid].in_use = 0; + } + else { /* move from undo struct to data proto vector */ + pcb_vtpadstack_proto_enlarge(&a->data->ps_protos, a->pid); + a->data->ps_protos.array[a->pid] = a->proto; + } + a->in_data = !a->in_data; + + np = pcb_vtpadstack_proto_get(&a->data->ps_protos, a->pid, 0); + pcb_pstk_proto_update(np); + + return 0; +} + +static void undo_proto_set_print(void *udata, char *dst, size_t dst_len) +{ + rnd_snprintf(dst, dst_len, "proto set"); +} + +static const uundo_oper_t undo_proto_set = { + core_proto_cookie, + NULL, + undo_proto_set_swap, + undo_proto_set_swap, + undo_proto_set_print +}; + + + +rnd_cardinal_t pcb_pstk_proto_insert_or_free(pcb_data_t *data, pcb_pstk_proto_t *proto, int quiet, int undoable) +{ + rnd_cardinal_t id, n, first_free; + + n = pcb_pstk_proto_insert_try(data, proto, &first_free); + if (n != PCB_PADSTACK_INVALID) { + pcb_pstk_proto_free_fields(proto); + return n; /* already in cache */ + } + + /* no match, have to register a new one */ + if (first_free == PCB_PADSTACK_INVALID) { + pcb_pstk_proto_t *np; + id = n = pcb_vtpadstack_proto_len(&data->ps_protos); + pcb_vtpadstack_proto_append(&data->ps_protos, *proto); + np = pcb_vtpadstack_proto_get(&data->ps_protos, n, 0); + np->parent = data; + pcb_pstk_proto_update(np); + } + else { + memcpy(data->ps_protos.array+first_free, proto, sizeof(pcb_pstk_proto_t)); + data->ps_protos.array[first_free].in_use = 1; + data->ps_protos.array[first_free].parent = data; + pcb_pstk_proto_update(data->ps_protos.array+first_free); + id = first_free; + } + memset(proto, 0, sizeof(pcb_pstk_proto_t)); /* make sure a subsequent free() won't do any harm */ + + if (undoable) { + undo_proto_set_t *a = pcb_undo_alloc(pcb_data_get_top(data), &undo_proto_set, sizeof(undo_proto_set_t)); + a->data = data; + a->pid = id; + a->in_data = 1; + } + + return id; +} + +static rnd_cardinal_t pcb_pstk_proto_insert_dup_(pcb_data_t *data, const pcb_pstk_proto_t *proto, int quiet, int forcedup, int undoable) +{ + rnd_cardinal_t id, n, first_free = PCB_PADSTACK_INVALID; + + n = pcb_pstk_proto_insert_try(data, proto, &first_free); + if ((n != PCB_PADSTACK_INVALID) && (!forcedup)) + return n; /* already in cache */ + + /* no match, have to register a new one, which is a dup of the original */ + if (first_free == PCB_PADSTACK_INVALID) { + pcb_pstk_proto_t *nproto; + n = pcb_vtpadstack_proto_len(&data->ps_protos); + nproto = pcb_vtpadstack_proto_alloc_append(&data->ps_protos, 1); + pcb_pstk_proto_copy(nproto, proto); + nproto->parent = data; + pcb_pstk_proto_update(nproto); + id = n; + } + else { + pcb_pstk_proto_copy(data->ps_protos.array+first_free, proto); + data->ps_protos.array[first_free].in_use = 1; + data->ps_protos.array[first_free].parent = data; + pcb_pstk_proto_update(data->ps_protos.array+first_free); + id = first_free; + } + + if (undoable) { + undo_proto_set_t *a = pcb_undo_alloc(pcb_data_get_top(data), &undo_proto_set, sizeof(undo_proto_set_t)); + a->data = data; + a->pid = id; + a->in_data = 1; + } + + return id; +} + +rnd_cardinal_t pcb_pstk_proto_insert_dup(pcb_data_t *data, const pcb_pstk_proto_t *proto, int quiet, int undoable) +{ + return pcb_pstk_proto_insert_dup_(data, proto, quiet, 0, undoable); +} + +rnd_cardinal_t pcb_pstk_proto_insert_forcedup(pcb_data_t *data, const pcb_pstk_proto_t *proto, int quiet, int undoable) +{ + return pcb_pstk_proto_insert_dup_(data, proto, quiet, 1, undoable); +} + + +rnd_cardinal_t pcb_pstk_proto_replace(pcb_data_t *data, rnd_cardinal_t proto_id, const pcb_pstk_proto_t *src) +{ + pcb_pstk_proto_t *dst; + if ((proto_id < 0) || (proto_id >= pcb_vtpadstack_proto_len(&data->ps_protos))) + return PCB_PADSTACK_INVALID; + + dst = &data->ps_protos.array[proto_id]; + pcb_pstk_proto_free_fields(dst); + + pcb_pstk_proto_copy(dst, src); + dst->in_use = 1; + dst->parent = data; + pcb_pstk_proto_update(dst); + return proto_id; +} + + +rnd_cardinal_t pcb_pstk_conv_selection(pcb_board_t *pcb, int quiet, rnd_coord_t ox, rnd_coord_t oy) +{ + pcb_pstk_proto_t proto; + + if (pcb_pstk_proto_conv_selection(pcb, &proto, quiet, ox, oy) != 0) + return -1; + + return pcb_pstk_proto_insert_or_free(pcb->Data, &proto, quiet, 1); +} + +rnd_cardinal_t pcb_pstk_conv_buffer(int quiet) +{ + pcb_pstk_proto_t proto; + + if (pcb_pstk_proto_conv_buffer(&proto, quiet) != 0) + return -1; + + return pcb_pstk_proto_insert_or_free(PCB_PASTEBUFFER->Data, &proto, quiet, 0); +} + + +void pcb_pstk_shape_update_pa(pcb_pstk_poly_t *poly) +{ + int n; + rnd_vector_t v; + rnd_pline_t *pl; + + v[0] = poly->x[0]; v[1] = poly->y[0]; + pl = rnd_poly_contour_new(v); + for(n = 1; n < poly->len; n++) { + v[0] = poly->x[n]; v[1] = poly->y[n]; + rnd_poly_vertex_include(pl->head->prev, rnd_poly_node_create(v)); + } + rnd_poly_contour_pre(pl, 1); + + poly->pa = rnd_polyarea_create(); + rnd_polyarea_contour_include(poly->pa, pl); + + if (!rnd_poly_valid(poly->pa)) { + poly->pa->contours = NULL; /* keep pl safe from rnd_polyarea_free() */ + rnd_polyarea_free(&poly->pa); + + poly->pa = rnd_polyarea_create(); + rnd_poly_contour_inv(pl); + rnd_polyarea_contour_include(poly->pa, pl); + poly->inverted = 1; + } + else + poly->inverted = 0; +} + +/*** Undoable hole change ***/ + +typedef struct { + long int parent_ID; /* -1 for pcb, positive for a subc */ + rnd_cardinal_t proto; + + int hplated; + rnd_coord_t hdia; + int htop, hbottom; +} padstack_proto_change_hole_t; + +#define swap(a,b,type) \ + do { \ + type tmp = a; \ + a = b; \ + b = tmp; \ + } while(0) + +static int undo_change_hole_swap(void *udata) +{ + padstack_proto_change_hole_t *u = udata; + pcb_data_t *data; + pcb_pstk_proto_t *proto; + + if (u->parent_ID != -1) { + pcb_subc_t *subc = pcb_subc_by_id(PCB->Data, u->parent_ID); + if (subc == NULL) { + rnd_message(RND_MSG_ERROR, "Can't undo padstack prototype hole change: parent subc #%ld is not found\n", u->parent_ID); + return -1; + } + data = subc->data; + } + else + data = PCB->Data; + + proto = pcb_pstk_get_proto_(data, u->proto); + if (proto == NULL) { + rnd_message(RND_MSG_ERROR, "Can't undo padstack prototype hole change: proto ID #%ld is not available\n", u->parent_ID); + return -1; + } + + swap(proto->hplated, u->hplated, int); + swap(proto->hdia, u->hdia, rnd_coord_t); + swap(proto->htop, u->htop, int); + swap(proto->hbottom, u->hbottom, int); + + pcb_pstk_proto_update(proto); + + return 0; +} + +static void undo_change_hole_print(void *udata, char *dst, size_t dst_len) +{ + padstack_proto_change_hole_t *u = udata; + rnd_snprintf(dst, dst_len, "padstack proto hole change: plated=%d dia=%$mm top=%d bottom=%d\n", u->hplated, u->hdia, u->htop, u->hbottom); +} + +static const uundo_oper_t undo_pstk_proto_change_hole = { + core_proto_cookie, + NULL, /* free */ + undo_change_hole_swap, + undo_change_hole_swap, + undo_change_hole_print +}; + +int pcb_pstk_proto_change_hole(pcb_pstk_proto_t *proto, const int *hplated, const rnd_coord_t *hdia, const int *htop, const int *hbottom) +{ + padstack_proto_change_hole_t *u; + long int parent_ID; + + switch(proto->parent->parent_type) { + case PCB_PARENT_BOARD: parent_ID = -1; break; + case PCB_PARENT_SUBC: parent_ID = proto->parent->parent.subc->ID; break; + default: return -1; + } + + u = pcb_undo_alloc(PCB, &undo_pstk_proto_change_hole, sizeof(padstack_proto_change_hole_t)); + u->parent_ID = parent_ID; + u->proto = pcb_pstk_get_proto_id(proto); + u->hplated = hplated ? *hplated : proto->hplated; + u->hdia = hdia ? *hdia : proto->hdia; + u->htop = htop ? *htop : proto->htop; + u->hbottom = hbottom ? *hbottom : proto->hbottom; + undo_change_hole_swap(u); + + pcb_undo_inc_serial(); + return 0; +} + +/*** undoable proto name change ***/ + +typedef struct { + long int parent_ID; /* -1 for pcb, positive for a subc */ + rnd_cardinal_t proto; + + char *name; +} padstack_proto_change_name_t; + +static int undo_change_name_swap(void *udata) +{ + padstack_proto_change_name_t *u = udata; + pcb_data_t *data; + pcb_pstk_proto_t *proto; + + if (u->parent_ID != -1) { + pcb_subc_t *subc = pcb_subc_by_id(PCB->Data, u->parent_ID); + if (subc == NULL) { + rnd_message(RND_MSG_ERROR, "Can't undo padstack prototype hole change: parent subc #%ld is not found\n", u->parent_ID); + return -1; + } + data = subc->data; + } + else + data = PCB->Data; + + proto = pcb_pstk_get_proto_(data, u->proto); + if (proto == NULL) { + rnd_message(RND_MSG_ERROR, "Can't undo padstack prototype hole change: proto ID #%ld is not available\n", u->parent_ID); + return -1; + } + + swap(proto->name, u->name, char *); + return 0; +} + +static void undo_change_name_print(void *udata, char *dst, size_t dst_len) +{ + padstack_proto_change_name_t *u = udata; + rnd_snprintf(dst, dst_len, "padstack proto name change to: '%s'\n", u->name); +} + +static const uundo_oper_t undo_pstk_proto_change_name = { + core_proto_cookie, + NULL, /* free */ + undo_change_name_swap, + undo_change_name_swap, + undo_change_name_print +}; + +int pcb_pstk_proto_change_name(pcb_pstk_proto_t *proto, const char *new_name, int undoable) +{ + char *old_name; + long int parent_ID; + + if (undoable) { + old_name = proto->name; + switch(proto->parent->parent_type) { + case PCB_PARENT_BOARD: parent_ID = -1; break; + case PCB_PARENT_SUBC: parent_ID = proto->parent->parent.subc->ID; break; + default: return -1; + } + } + else + free(proto->name); + + if ((new_name == NULL) || (*new_name == '\0')) + proto->name = NULL; + else + proto->name = rnd_strdup(new_name); + + if (undoable) { + padstack_proto_change_name_t *u = pcb_undo_alloc(PCB, &undo_pstk_proto_change_name, sizeof(padstack_proto_change_name_t)); + u->parent_ID = parent_ID; + u->proto = pcb_pstk_get_proto_id(proto); + u->name = old_name; + pcb_undo_inc_serial(); + } + + + return 0; +} + +#define TSHAPE_ANGLE_TOL 0.01 +#define tshape_angle_eq(a1, a2) (((a1 - a2) >= -TSHAPE_ANGLE_TOL) && ((a1 - a2) <= TSHAPE_ANGLE_TOL)) + +pcb_pstk_tshape_t *pcb_pstk_make_tshape(pcb_data_t *data, pcb_pstk_proto_t *proto, double rot, int xmirror, int smirror, int *out_protoi) +{ + size_t n; + pcb_pstk_tshape_t *ts; + + xmirror = !!xmirror; + smirror = !!smirror; + + /* cheap case: canonical */ + if (tshape_angle_eq(rot, 0.0) && (xmirror == 0) && (smirror == 0)) { + if (out_protoi != NULL) *out_protoi = 0; + return &proto->tr.array[0]; + } + + /* search for an existing version in the cache - we expect only a few + transformations per padstack, the result is cached -> linear search. */ + for(n = 0; n < proto->tr.used; n++) { + if (tshape_angle_eq(proto->tr.array[n].rot, rot) && (proto->tr.array[n].xmirror == xmirror) && (proto->tr.array[n].smirror == smirror)) { + if (out_protoi != NULL) *out_protoi = n; + return &proto->tr.array[n]; + } + } + + /* allocate and render the transformed version for the cache */ + if (out_protoi != NULL) *out_protoi = proto->tr.used; + ts = pcb_vtpadstack_tshape_alloc_append(&proto->tr, 1); + + /* first make a vanilla copy */ + pcb_pstk_tshape_copy(ts, &proto->tr.array[0]); + + if (!tshape_angle_eq(rot, 0.0)) + pcb_pstk_tshape_rot(ts, rot); + + if (xmirror) + pcb_pstk_tshape_xmirror(ts); + + if (smirror) + pcb_pstk_tshape_smirror(ts); + + ts->rot = rot; + ts->xmirror = xmirror; + ts->smirror = smirror; + return ts; +} + +static void pcb_pstk_poly_center(const pcb_pstk_poly_t *poly, rnd_coord_t *cx, rnd_coord_t *cy) +{ + double x = 0.0, y = 0.0; + int n; + + for(n = 0; n < poly->len; n++) { + x += (double)poly->x[n]; + y += (double)poly->y[n]; + } + x /= (double)poly->len; + y /= (double)poly->len; + *cx = rnd_round(x); + *cy = rnd_round(y); +} + + + +void pcb_pstk_shape_grow_(pcb_pstk_shape_t *shp, rnd_bool is_absolute, rnd_coord_t val) +{ + rnd_coord_t cx, cy; + int n; + + switch(shp->shape) { + case PCB_PSSH_LINE: + if (is_absolute) + shp->data.line.thickness = val; + else + shp->data.line.thickness += val; + if (shp->data.line.thickness < 1) + shp->data.line.thickness = 1; + break; + case PCB_PSSH_CIRC: + if (is_absolute) + shp->data.circ.dia = val; + else + shp->data.circ.dia += val; + if (shp->data.circ.dia < 1) + shp->data.circ.dia = 1; + break; + case PCB_PSSH_HSHADOW: + break; + case PCB_PSSH_POLY: + pcb_pstk_poly_center(&shp->data.poly, &cx, &cy); + rnd_polyarea_free(&shp->data.poly.pa); + if (is_absolute) { + int n; + double maxs2 = 0; + /* determine the max edge center distance from the shape center; this + is effectivel the "radius" of the shape measured on sides, not on corners */ + for(n = 0; n < shp->data.poly.len; n++) { + double s2, x = shp->data.poly.x[n], y = shp->data.poly.y[n], xn = shp->data.poly.x[(n+1) % shp->data.poly.len], yn = shp->data.poly.y[(n+1) % shp->data.poly.len]; + x = (x+xn)/2.0; y = (y+yn)/2.0; + s2 = rnd_distance2(cx, cy, x, y); + if (s2 > maxs2) + maxs2 = s2; + + } + if (maxs2 == 0) + break; + + /* calculate the delta value: biggest side distance should match the expected val */ + val = val - (sqrt(maxs2) * 2); + + /* fall through to relative grow */ + } + + /* relative growth */ + { + rnd_polo_t *p, p_st[32]; + double vl = rnd_round(val/2); + + if (shp->data.poly.inverted) + vl = -vl; + + if (shp->data.poly.len >= sizeof(p_st) / sizeof(p_st[0])) + p = malloc(sizeof(rnd_polo_t) * shp->data.poly.len); + else + p = p_st; + + /* relative: move each point radially */ + for(n = 0; n < shp->data.poly.len; n++) { + p[n].x = shp->data.poly.x[n]; + p[n].y = shp->data.poly.y[n]; + } + rnd_polo_norms(p, shp->data.poly.len); + rnd_polo_offs(vl, p, shp->data.poly.len); + for(n = 0; n < shp->data.poly.len; n++) { + shp->data.poly.x[n] = p[n].x; + shp->data.poly.y[n] = p[n].y; + } + if (p != p_st) + free(p); + } + pcb_pstk_shape_update_pa(&shp->data.poly); + break; + } +} + + +static void pcb_pstk_shape_scale_(pcb_pstk_shape_t *shp, double sx, double sy) +{ + rnd_coord_t cx, cy; + int n; + + switch(shp->shape) { + case PCB_PSSH_LINE: + shp->data.line.thickness = rnd_round(shp->data.line.thickness * ((sx+sy)/2.0)); + if (shp->data.line.thickness < 1) + shp->data.line.thickness = 1; + shp->data.line.x1 = rnd_round((double)shp->data.line.x1 * sx); + shp->data.line.y1 = rnd_round((double)shp->data.line.y1 * sy); + shp->data.line.x2 = rnd_round((double)shp->data.line.x2 * sx); + shp->data.line.y2 = rnd_round((double)shp->data.line.y2 * sy); + break; + case PCB_PSSH_CIRC: + shp->data.circ.dia = rnd_round(shp->data.circ.dia * ((sx+sy)/2.0)); + if (shp->data.circ.dia < 1) + shp->data.circ.dia = 1; + shp->data.circ.x = rnd_round((double)shp->data.circ.x * sx); + shp->data.circ.y = rnd_round((double)shp->data.circ.y * sy); + break; + case PCB_PSSH_HSHADOW: + break; + case PCB_PSSH_POLY: + pcb_pstk_poly_center(&shp->data.poly, &cx, &cy); + rnd_polyarea_free(&shp->data.poly.pa); + + for(n = 0; n < shp->data.poly.len; n++) { + shp->data.poly.x[n] = rnd_round((double)shp->data.poly.x[n] * sx); + shp->data.poly.y[n] = rnd_round((double)shp->data.poly.y[n] * sy); + } + pcb_pstk_shape_update_pa(&shp->data.poly); + break; + } +} + +void pcb_pstk_shape_clr_grow_(pcb_pstk_shape_t *shp, rnd_bool is_absolute, rnd_coord_t val) +{ + if (is_absolute) + shp->clearance = val; + else + shp->clearance += val; +} + +/*** undoable proto geo changes ***/ + +typedef struct { + pcb_data_t *data; + long proto_id, tridx, shpidx; + + pcb_pstk_shape_t shp; + rnd_coord_t clr; + + unsigned shp_valid:1; + unsigned clr_valid:1; +} undo_shape_geo_t; + +static void pstk_clip_all_proto(pcb_data_t *data, int proto_id, int pre) +{ + pcb_pstk_t *ps; + gdl_iterator_t it; + pcb_opctx_t ctx = {0}; + + if (pre) { + ctx.clip.clear = 0; + ctx.clip.restore = 1; + } + else { + ctx.clip.clear = 1; + ctx.clip.restore = 0; + } + + padstacklist_foreach(&data->padstack, &it, ps) + if (ps->proto == proto_id) + pcb_pstkop_clip(&ctx, ps); +} + +static int undo_shape_geo_swap(void *udata) +{ + undo_shape_geo_t *g = udata; + pcb_pstk_proto_t *proto; + pcb_pstk_tshape_t *tshp; + pcb_pstk_shape_t *shp; + + if (g->proto_id >= g->data->ps_protos.used) { + rnd_message(RND_MSG_ERROR, "undo_shape_geo_swap(): invalid proto_id %ld >= %ld\n", g->proto_id, g->data->ps_protos.used); + return -1; + } + proto = g->data->ps_protos.array + g->proto_id; + + if (!proto->in_use) { + rnd_message(RND_MSG_ERROR, "undo_shape_geo_swap(): unused proto\n"); + return -1; + } + + if (g->tridx >= proto->tr.used) { + rnd_message(RND_MSG_ERROR, "undo_shape_geo_swap(): invalid tridx %ld >= %ld\n", g->tridx, proto->tr.used); + return -1; + } + tshp = &proto->tr.array[g->tridx]; + + if (g->shpidx >= tshp->len) { + rnd_message(RND_MSG_ERROR, "undo_shape_geo_swap(): invalid shpidx %ld >= %ld\n", g->shpidx, tshp->len); + return -1; + } + shp = &tshp->shape[g->shpidx]; + + pstk_clip_all_proto(g->data, g->proto_id, 1); + + if (g->shp_valid) { + pcb_pstk_shape_t tmp; + tmp = g->shp; + g->shp = *shp; + *shp = tmp; + } + + if (g->clr_valid) { + rnd_coord_t tmp = g->clr; + g->clr = shp->clearance; + shp->clearance = tmp; + } + + pstk_clip_all_proto(g->data, g->proto_id, 0); + + return 0; +} + +static void undo_shape_geo_print(void *udata, char *dst, size_t dst_len) +{ + undo_shape_geo_t *g = udata; + rnd_snprintf(dst, dst_len, "pstk shape geo proto=%d %d/%d shape=%d clearance=%d (%$$ml)", g->proto_id, g->tridx, g->shpidx, g->shp_valid, g->clr_valid, g->clr); +} + +static void undo_shape_geo_free(void *udata) +{ + undo_shape_geo_t *g = udata; + if (g->shp_valid) { + pcb_pstk_shape_free(&g->shp); + g->shp_valid = 0; + } +} + + +static const char core_shape_cookie[] = "core-pstk-proto-shape"; + +static const uundo_oper_t undo_shape_geo = { + core_shape_cookie, + undo_shape_geo_free, + undo_shape_geo_swap, + undo_shape_geo_swap, + undo_shape_geo_print +}; + + +static undo_shape_geo_t *pstk_shape_geo_undo_init(pcb_pstk_proto_t *proto, int tridx, int shpidx) +{ + pcb_data_t *data = proto->parent; + pcb_board_t *pcb; + long pid; + undo_shape_geo_t *g; + + if (data == NULL) + return NULL; + + pcb = pcb_data_get_top(data); + + if ((pcb == NULL) || (!proto->in_use)) + return NULL; + + pid = proto - data->ps_protos.array; + if ((pid < 0) || (pid >= data->ps_protos.used)) + return NULL; + + g = pcb_undo_alloc(data->parent.board, &undo_shape_geo, sizeof(undo_shape_geo_t)); + g->data = data; + g->proto_id = pid; + g->tridx = tridx; + g->shpidx = shpidx; + + g->shp_valid = g->clr_valid = 0; + return g; +} + +void pcb_pstk_shape_clr_grow(pcb_pstk_proto_t *proto, int tridx, int shpidx, rnd_bool is_absolute, rnd_coord_t val, int undoable) +{ + pcb_pstk_tshape_t *tshp = &proto->tr.array[tridx]; + pcb_pstk_shape_t *shp = &tshp->shape[shpidx]; + + if (undoable) { + undo_shape_geo_t *g = pstk_shape_geo_undo_init(proto, tridx, shpidx); + if (g != NULL) { + g->clr = shp->clearance; + g->clr_valid = 1; + pcb_undo_inc_serial(); + } + } + pcb_pstk_shape_clr_grow_(shp, is_absolute, val); +} + +void pcb_pstk_shape_grow(pcb_pstk_proto_t *proto, int tridx, int shpidx, rnd_bool is_absolute, rnd_coord_t val, int undoable) +{ + pcb_pstk_tshape_t *tshp = &proto->tr.array[tridx]; + pcb_pstk_shape_t *shp = &tshp->shape[shpidx]; + + if (undoable) { + undo_shape_geo_t *g = pstk_shape_geo_undo_init(proto, tridx, shpidx); + if (g != NULL) { + pcb_pstk_shape_copy(&g->shp, shp); + g->shp_valid = 1; + pcb_undo_inc_serial(); + } + } + + pcb_pstk_shape_grow_(shp, is_absolute, val); +} + +void pcb_pstk_shape_scale(pcb_pstk_proto_t *proto, int tridx, int shpidx, double sx, double sy, int undoable) +{ + pcb_pstk_tshape_t *tshp = &proto->tr.array[tridx]; + pcb_pstk_shape_t *shp = &tshp->shape[shpidx]; + + if (undoable) { + undo_shape_geo_t *g = pstk_shape_geo_undo_init(proto, tridx, shpidx); + if (g != NULL) { + pcb_pstk_shape_copy(&g->shp, shp); + g->shp_valid = 1; + pcb_undo_inc_serial(); + } + } + + pcb_pstk_shape_scale_(shp, sx, sy); +} + + +void pcb_pstk_proto_grow(pcb_pstk_proto_t *proto, rnd_bool is_absolute, rnd_coord_t val) +{ + int n, i, undoable = 0;; + + /* do the same growth on all shapes of all transformed variants */ + for(n = 0; n < proto->tr.used; n++) + for(i = 0; i < proto->tr.array[n].len; i++) + pcb_pstk_shape_grow(proto, n, i, is_absolute, val, undoable); + pcb_pstk_proto_update(proto); +} + +int pcb_pstk_alloc_shape_idx(pcb_pstk_proto_t *proto, int tr_idx) +{ + int d = proto->tr.array[tr_idx].len; + proto->tr.array[tr_idx].len++; + proto->tr.array[tr_idx].shape = realloc(proto->tr.array[tr_idx].shape, proto->tr.array[tr_idx].len * sizeof(proto->tr.array[tr_idx].shape[0])); + return d; +} + +void pcb_pstk_shape_derive(pcb_pstk_proto_t *proto, int dst_idx, int src_idx, rnd_coord_t bloat, pcb_layer_type_t mask, pcb_layer_combining_t comb) +{ + int n, undoable = 0; + + /* do the same copy on all shapes of all transformed variants */ + for(n = 0; n < proto->tr.used; n++) { + int d = dst_idx; + if (d < 0) + d = pcb_pstk_alloc_shape_idx(proto, n); + else + pcb_pstk_shape_free(&proto->tr.array[n].shape[d]); + pcb_pstk_shape_copy(&proto->tr.array[n].shape[d], &proto->tr.array[n].shape[src_idx]); + proto->tr.array[n].shape[d].layer_mask = mask; + proto->tr.array[n].shape[d].comb = comb; + if (proto->tr.array[n].smirror) + pcb_pstk_shape_smirror_(&proto->tr.array[n].shape[d]); + if (bloat != 0) + pcb_pstk_shape_grow(proto, n, d, rnd_false, bloat, undoable); + } + pcb_pstk_proto_update(proto); +} + +int pcb_pstk_shape_swap_layer(pcb_pstk_proto_t *proto, int idx1, int idx2) +{ + int n; + pcb_layer_type_t lm; + pcb_layer_combining_t lc; + + if ((idx1 < 0) || (idx1 > proto->tr.array[0].len)) + return -1; + if ((idx2 < 0) || (idx2 > proto->tr.array[0].len)) + return -1; + + for(n = 0; n < proto->tr.used; n++) { + lm = proto->tr.array[n].shape[idx1].layer_mask; + lc = proto->tr.array[n].shape[idx1].comb; + proto->tr.array[n].shape[idx1].layer_mask = proto->tr.array[n].shape[idx2].layer_mask; + proto->tr.array[n].shape[idx1].comb = proto->tr.array[n].shape[idx2].comb; + proto->tr.array[n].shape[idx2].layer_mask = lm; + proto->tr.array[n].shape[idx2].comb = lc; + } + return 0; +} + + +void pcb_pstk_shape_add_hshadow(pcb_pstk_proto_t *proto, pcb_layer_type_t mask, pcb_layer_combining_t comb) +{ + int n; + + /* do the same on all shapes of all transformed variants */ + for(n = 0; n < proto->tr.used; n++) { + int d = proto->tr.array[n].len; + proto->tr.array[n].len++; + proto->tr.array[n].shape = realloc(proto->tr.array[n].shape, proto->tr.array[n].len * sizeof(proto->tr.array[n].shape[0])); + proto->tr.array[n].shape[d].shape = PCB_PSSH_HSHADOW; + proto->tr.array[n].shape[d].layer_mask = mask; + proto->tr.array[n].shape[d].comb = comb; + } + pcb_pstk_proto_update(proto); +} + + +static void pcb_pstk_tshape_del_idx(pcb_pstk_tshape_t *shp, int idx) +{ + int n; + for(n = idx; n < shp->len-1; n++) + shp->shape[n] = shp->shape[n+1]; + shp->len--; +} + +void pcb_pstk_proto_del_shape_idx(pcb_pstk_proto_t *proto, int idx) +{ + int n; + + if ((proto->tr.used == 0) || (idx < 0) || (idx >= proto->tr.array[0].len)) + return; + + /* delete the shape from all transformed variants */ + for(n = 0; n < proto->tr.used; n++) + pcb_pstk_tshape_del_idx(&proto->tr.array[n], idx); + + pcb_pstk_proto_update(proto); +} + +void pcb_pstk_proto_del_shape(pcb_pstk_proto_t *proto, pcb_layer_type_t lyt, pcb_layer_combining_t comb) +{ + int idx; + + if (proto->tr.used == 0) + return; + + /* search the 0th transformed, all other tshapes are the same */ + idx = pcb_pstk_get_shape_idx(&proto->tr.array[0], lyt, comb); + pcb_pstk_proto_del_shape_idx(proto, idx); +} + +void pcb_pstk_proto_del(pcb_data_t *data, rnd_cardinal_t proto_id) +{ + pcb_pstk_proto_t *proto = pcb_vtpadstack_proto_get(&data->ps_protos, proto_id, 0); + if (proto == NULL) + return; + pcb_pstk_proto_free_fields(proto); +} + +rnd_cardinal_t *pcb_pstk_proto_used_all(pcb_data_t *data, rnd_cardinal_t *len_out) +{ + rnd_cardinal_t len, *res; + pcb_pstk_t *ps; + + len = data->ps_protos.used; + if (len == 0) { + *len_out = 0; + return NULL; + } + + res = calloc(sizeof(rnd_cardinal_t), len); + for(ps = padstacklist_first(&data->padstack); ps != NULL; ps = padstacklist_next(ps)) { + if ((ps->proto >= 0) && (ps->proto < len)) + res[ps->proto]++; + } + + /* routing styles may also reference to prototypes if we are on a board */ + if (data->parent_type == PCB_PARENT_BOARD) { + pcb_board_t *pcb = data->parent.board; + int n; + + for(n = 0; n < pcb->RouteStyle.used; n++) { + if (pcb->RouteStyle.array[n].via_proto_set) { + rnd_cardinal_t pid = pcb->RouteStyle.array[n].via_proto; + if ((pid >= 0) && (pid < len)) + res[pid]++; + } + } + } + + *len_out = len; + return res; +} + +/*** hash ***/ +static unsigned int pcb_pstk_shape_hash(const pcb_pstk_shape_t *sh) +{ + unsigned int n, ret = murmurhash32(sh->layer_mask) ^ murmurhash32(sh->comb) ^ pcb_hash_coord(sh->clearance); + + switch(sh->shape) { + case PCB_PSSH_POLY: + for(n = 0; n < sh->data.poly.len; n++) + ret ^= pcb_hash_coord(sh->data.poly.x[n]) ^ pcb_hash_coord(sh->data.poly.y[n]); + break; + case PCB_PSSH_LINE: + ret ^= pcb_hash_coord(sh->data.line.x1) ^ pcb_hash_coord(sh->data.line.x2) ^ pcb_hash_coord(sh->data.line.y1) ^ pcb_hash_coord(sh->data.line.y2); + ret ^= pcb_hash_coord(sh->data.line.thickness); + ret ^= sh->data.line.square; + break; + case PCB_PSSH_CIRC: + ret ^= pcb_hash_coord(sh->data.circ.x) ^ pcb_hash_coord(sh->data.circ.y); + ret ^= pcb_hash_coord(sh->data.circ.dia); + break; + case PCB_PSSH_HSHADOW: + break; + } + + return ret; +} + +unsigned int pcb_pstk_proto_hash(const pcb_pstk_proto_t *p) +{ + pcb_pstk_tshape_t *ts = &p->tr.array[0]; + unsigned int n, ret = pcb_hash_coord(p->hdia) ^ pcb_hash_coord(p->htop) ^ pcb_hash_coord(p->hbottom) ^ pcb_hash_coord(p->hplated); + if (ts != NULL) { + ret ^= pcb_hash_coord(ts->len); + for(n = 0; n < ts->len; n++) + ret ^= pcb_pstk_shape_hash(ts->shape + n); + } + return ret; +} + +int pcb_pstk_shape_eq(const pcb_pstk_shape_t *sh1, const pcb_pstk_shape_t *sh2) +{ + int n; + + if (sh1->layer_mask != sh2->layer_mask) return 0; + if (sh1->comb != sh2->comb) return 0; + if (sh1->clearance != sh2->clearance) return 0; + if (sh1->shape != sh2->shape) return 0; + + switch(sh1->shape) { + case PCB_PSSH_POLY: + if (sh1->data.poly.len != sh2->data.poly.len) return 0; + for(n = 0; n < sh1->data.poly.len; n++) { + if (sh1->data.poly.x[n] != sh2->data.poly.x[n]) return 0; + if (sh1->data.poly.y[n] != sh2->data.poly.y[n]) return 0; + } + break; + case PCB_PSSH_LINE: + if (sh1->data.line.x1 != sh2->data.line.x1) return 0; + if (sh1->data.line.x2 != sh2->data.line.x2) return 0; + if (sh1->data.line.y1 != sh2->data.line.y1) return 0; + if (sh1->data.line.y2 != sh2->data.line.y2) return 0; + if (sh1->data.line.thickness != sh2->data.line.thickness) return 0; + if (sh1->data.line.square != sh2->data.line.square) return 0; + break; + case PCB_PSSH_CIRC: + if (sh1->data.circ.x != sh2->data.circ.x) return 0; + if (sh1->data.circ.y != sh2->data.circ.y) return 0; + if (sh1->data.circ.dia != sh2->data.circ.dia) return 0; + break; + case PCB_PSSH_HSHADOW: + break; + } + + return 1; +} + +int pcb_pstk_proto_eq(const pcb_pstk_proto_t *p1, const pcb_pstk_proto_t *p2) +{ + pcb_pstk_tshape_t *ts1 = &p1->tr.array[0], *ts2 = &p2->tr.array[0]; + int n1, n2; + + if (p1->hdia != p2->hdia) return 0; + if (p1->htop != p2->htop) return 0; + if (p1->hbottom != p2->hbottom) return 0; + if (p1->hplated != p2->hplated) return 0; + if ((ts1 == NULL) && (ts2 != NULL)) return 0; + if ((ts2 == NULL) && (ts1 != NULL)) return 0; + + if (ts1 != NULL) { + if (ts1->len != ts2->len) return 0; + for(n1 = 0; n1 < ts1->len; n1++) { + for(n2 = 0; n2 < ts2->len; n2++) + if (pcb_pstk_shape_eq(ts1->shape + n1, ts2->shape + n2)) + goto found; + return 0; + found:; + } + } + + return 1; +} + Index: tags/2.3.0/src/obj_pstk_shape.h =================================================================== --- tags/2.3.0/src/obj_pstk_shape.h (nonexistent) +++ tags/2.3.0/src/obj_pstk_shape.h (revision 33253) @@ -0,0 +1,87 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_PSTK_SHAPE_H +#define PCB_OBJ_PSTK_SHAPE_H + +#include +#include "polygon.h" +#include "layer.h" + +typedef struct pcb_pstk_poly_s { + unsigned int len; /* number of points in polygon */ + rnd_coord_t *x; /* ordered list of points, X coord */ + rnd_coord_t *y; /* ordered list of points, Y coord */ + rnd_polyarea_t *pa; /* cache for the poly code */ + char inverted; /* 1 if x;y has the opposite direction as pa */ +} pcb_pstk_poly_t; + +typedef struct pcb_pstk_line_s { + rnd_coord_t x1, y1, x2, y2, thickness; + unsigned square:1; +} pcb_pstk_line_t; + +typedef struct pcb_pstk_circ_s { + rnd_coord_t dia; /* diameter of the filled circle */ + rnd_coord_t x, y; /* assymetric pads */ +} pcb_pstk_circ_t; + +typedef struct pcb_pstk_shape_s { + pcb_layer_type_t layer_mask; + pcb_layer_combining_t comb; + union { + pcb_pstk_poly_t poly; + pcb_pstk_line_t line; + pcb_pstk_circ_t circ; + } data; + enum { + PCB_PSSH_POLY, + PCB_PSSH_LINE, + PCB_PSSH_CIRC, /* filled circle */ + PCB_PSSH_HSHADOW /* for clearance: pretend the shape is the same as the drill's or slot's; but do not add anything positive to the target layer */ + } shape; + rnd_coord_t clearance; /* per layer clearance: internal layer clearance is sometimes different for production or insulation reasons (IPC2221A) */ + unsigned hconn:1; /* shape is connected to hole/slot; this is abstract, it ignores plating and bbvia aspects; valid only in the non-transformed proto, tr[0] */ +} pcb_pstk_shape_t; + +/* transformed prototype */ +typedef struct pcb_pstk_tshape_s { + double rot; + unsigned xmirror:1; + unsigned smirror:1; + + unsigned char len; /* number of shapes (PCB_PADSTACK_MAX_SHAPES) */ + pcb_pstk_shape_t *shape; /* list of layer-shape pairs */ +} pcb_pstk_tshape_t; + +void pcb_pstk_shape_rot(pcb_pstk_shape_t *sh, double sina, double cosa, double angle); +void pcb_pstk_shape_smirror(pcb_pstk_shape_t *sh); + +/* Return whether shape1 in ps1 intersects with shape2 in ps2 (regardless + of layer positions) */ +rnd_bool_t pcb_pstk_shape_intersect(pcb_pstk_t *ps1, pcb_pstk_shape_t *shape1, pcb_pstk_t *ps2, pcb_pstk_shape_t *shape2); + +#endif Index: tags/2.3.0/src/obj_rat.c =================================================================== --- tags/2.3.0/src/obj_rat.c (nonexistent) +++ tags/2.3.0/src/obj_rat.c (revision 33253) @@ -0,0 +1,517 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include "config.h" + +#include "board.h" +#include "data.h" +#include "data_it.h" +#include "conf_core.h" +#include +#include "undo.h" +#include +#include "search.h" + +#include "obj_line_draw.h" + +#include "obj_rat.h" +#include "obj_rat_list.h" +#include "obj_rat_op.h" + +#include "obj_rat_draw.h" + +/*** allocation ***/ + +void pcb_rat_reg(pcb_data_t *data, pcb_rat_t *rat) +{ + ratlist_append(&data->Rat, rat); + pcb_obj_id_reg(data, rat); + PCB_SET_PARENT(rat, data, data); +} + +void pcb_rat_unreg(pcb_rat_t *rat) +{ + pcb_data_t *data = rat->parent.data; + assert(rat->parent_type == PCB_PARENT_DATA); + ratlist_remove(rat); + pcb_obj_id_del(data, rat); + PCB_CLEAR_PARENT(rat); +} + +pcb_rat_t *pcb_rat_alloc_id(pcb_data_t *data, long int id) +{ + pcb_rat_t *new_obj; + + new_obj = calloc(sizeof(pcb_rat_t), 1); + new_obj->ID = id; + new_obj->type = PCB_OBJ_RAT; + + pcb_rat_reg(data, new_obj); + + return new_obj; +} + +pcb_rat_t *pcb_rat_alloc(pcb_data_t *data) +{ + return pcb_rat_alloc_id(data, pcb_create_ID_get()); +} + +void pcb_rat_free(pcb_rat_t *rat) +{ + if ((rat->parent.data != NULL) && (rat->parent.data->rat_tree != NULL)) + rnd_r_delete_entry(rat->parent.data->rat_tree, (rnd_box_t *)rat); + pcb_rat_unreg(rat); + free(rat->anchor[0]); + free(rat->anchor[1]); + pcb_obj_common_free((pcb_any_obj_t *)rat); + free(rat); +} + +/*** utility ***/ +/* creates a new rat-line */ +pcb_rat_t *pcb_rat_new(pcb_data_t *Data, long int id, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_layergrp_id_t group1, rnd_layergrp_id_t group2, rnd_coord_t Thickness, pcb_flag_t Flags, pcb_any_obj_t *anchor1, pcb_any_obj_t *anchor2) +{ + pcb_rat_t *Line; + + if (id <= 0) + id = pcb_create_ID_get(); + + Line = pcb_rat_alloc_id(Data, id); + if (!Line) + return Line; + + Line->Flags = Flags; + PCB_FLAG_SET(PCB_FLAG_RAT, Line); + Line->Thickness = Thickness; + Line->Point1.X = X1; + Line->Point1.Y = Y1; + Line->Point1.ID = pcb_create_ID_get(); + Line->Point2.X = X2; + Line->Point2.Y = Y2; + Line->Point2.ID = pcb_create_ID_get(); + Line->group1 = group1; + Line->group2 = group2; + pcb_line_bbox((pcb_line_t *) Line); + if (!Data->rat_tree) + Data->rat_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Data->rat_tree, &Line->BoundingBox); + + if (anchor1 != NULL) + Line->anchor[0] = pcb_obj2idpath(anchor1); + if (anchor2 != NULL) + Line->anchor[1] = pcb_obj2idpath(anchor2); + + return Line; +} + +/* DeleteRats - deletes rat lines only + * can delete all rat lines, or only selected one */ +rnd_bool pcb_rats_destroy(rnd_bool selected) +{ + pcb_opctx_t ctx; + rnd_bool changed = rnd_false; + + ctx.remove.pcb = PCB; + ctx.remove.destroy_target = NULL; + + PCB_RAT_LOOP(PCB->Data); + { + if ((!selected) || PCB_FLAG_TEST(PCB_FLAG_SELECTED, line)) { + changed = rnd_true; + pcb_ratop_remove(&ctx, line); + } + } + PCB_END_LOOP; + if (changed) + pcb_undo_inc_serial(); + return changed; +} + +/*** utility ***/ + +static rnd_bool rat_meets_line(pcb_line_t *line, rnd_coord_t x, rnd_coord_t y, rnd_layergrp_id_t gid) +{ + if (gid >= 0) { + pcb_layer_t *ly = pcb_layer_get_real(line->parent.layer); + if ((ly == NULL) || (ly->meta.real.grp != gid)) + return 0; + } + if ((line->Point1.X == x) && (line->Point1.Y == y)) return rnd_true; + if ((line->Point2.X == x) && (line->Point2.Y == y)) return rnd_true; + return pcb_is_point_on_line(x, y, 1, line); +} + + +static rnd_bool rat_meets_arc(pcb_arc_t *arc, rnd_coord_t x, rnd_coord_t y, rnd_layergrp_id_t gid) +{ + if (gid >= 0) { + pcb_layer_t *ly = pcb_layer_get_real(arc->parent.layer); + if ((ly == NULL) || (ly->meta.real.grp != gid)) + return 0; + } + return pcb_is_point_on_arc(x, y, 1, arc); +} + + +static rnd_bool rat_meets_poly(pcb_poly_t *poly, rnd_coord_t x, rnd_coord_t y, rnd_layergrp_id_t gid) +{ + if (gid >= 0) { + pcb_layer_t *ly = pcb_layer_get_real(poly->parent.layer); + if ((ly == NULL) || (ly->meta.real.grp != gid)) + return 0; + } + if ((poly->Clipped == NULL) && (poly->parent.layer != NULL)) + pcb_poly_init_clip_force(poly->parent.layer->parent.data, poly->parent.layer, poly); + return pcb_poly_is_point_in_p(x, y, 1, poly); +} + +static rnd_bool rat_meets_pstk(pcb_data_t *data, pcb_pstk_t *pstk, rnd_coord_t x, rnd_coord_t y, rnd_layergrp_id_t gid) +{ + pcb_layergrp_t *g = pcb_get_layergrp(PCB, gid); + pcb_layer_t *ly; + if (g == NULL) + return rnd_false; + + ly = pcb_get_layer(data, g->lid[0]); + if (ly != NULL) + ly = pcb_layer_get_real(ly); + if (ly == NULL) + return rnd_false; + + if ((pstk->x == x) && (pstk->y == y)) + return rnd_true; + + return pcb_is_point_in_pstk(x, y, 1, pstk, ly); +} + + +/* return the first object (the type that is most likely an endpoint of a rat) + on a point on a layer */ +static pcb_any_obj_t *find_obj_on_layer(rnd_coord_t x, rnd_coord_t y, pcb_layer_t *l) +{ + rnd_rtree_it_t it; + rnd_box_t *n; + rnd_rtree_box_t sb; + + sb.x1 = x; sb.x2 = x+1; + sb.y1 = y; sb.y2 = y+1; + + if (l->line_tree != NULL) + for(n = rnd_rtree_first(&it, l->line_tree, &sb); n != NULL; n = rnd_rtree_next(&it)) + if (rat_meets_line((pcb_line_t *)n, x, y, -1)) + return (pcb_any_obj_t *)n; + + if (l->arc_tree != NULL) + for(n = rnd_rtree_first(&it, l->arc_tree, &sb); n != NULL; n = rnd_rtree_next(&it)) + if (rat_meets_arc((pcb_arc_t *)n, x, y, -1)) + return (pcb_any_obj_t *)n; + + if (l->polygon_tree != NULL) + for(n = rnd_rtree_first(&it, l->polygon_tree, &sb); n != NULL; n = rnd_rtree_next(&it)) + if (rat_meets_poly((pcb_poly_t *)n, x, y, -1)) + return (pcb_any_obj_t *)n; + +TODO("find through text"); +#if 0 + if (l->text_tree != NULL) + for(n = rnd_rtree_first(&it, l->text_tree, &sb); n != NULL; n = rnd_rtree_next(&it)) + if (rat_meets_text((pcb_text_t *)n, x, y, -1)) + return (pcb_any_obj_t *)n; +#endif + return NULL; +} + +/* return the first object (the type that is most likely an endpoint of a rat) + on a point on a layer group */ +static pcb_any_obj_t *find_obj_on_grp(pcb_data_t *data, rnd_coord_t x, rnd_coord_t y, rnd_layergrp_id_t gid) +{ + int i; + rnd_rtree_box_t sb; + rnd_rtree_it_t it; + rnd_box_t *n; + pcb_layergrp_t *g = pcb_get_layergrp(PCB, gid); + + if (g == NULL) + return NULL; + + sb.x1 = x; sb.x2 = x+1; + sb.y1 = y; sb.y2 = y+1; + + if (PCB->Data->padstack_tree != NULL) + for(n = rnd_rtree_first(&it, data->padstack_tree, &sb); n != NULL; n = rnd_rtree_next(&it)) + if (rat_meets_pstk(data, (pcb_pstk_t *)n, x, y, gid)) + return (pcb_any_obj_t *)n; + + for(i = 0; i < g->len; i++) { + pcb_any_obj_t *o = find_obj_on_layer(x, y, &data->Layer[g->lid[i]]); + if (o != NULL) + return o; + } + return NULL; +} + +pcb_any_obj_t *pcb_rat_anchor_guess(pcb_rat_t *rat, int end, rnd_bool update) +{ + pcb_data_t *data = rat->parent.data; + pcb_idpath_t **path = &rat->anchor[!!end]; + rnd_coord_t x = (end == 0) ? rat->Point1.X : rat->Point2.X; + rnd_coord_t y = (end == 0) ? rat->Point1.Y : rat->Point2.Y; + rnd_layergrp_id_t gid = (end == 0) ? rat->group1 : rat->group2; + pcb_any_obj_t *ao; + + /* (relatively) cheap thest if existing anchor is valid */ + if (*path != NULL) { + ao = pcb_idpath2obj_in(data, *path); + if (ao != NULL) { + switch(ao->type) { + case PCB_OBJ_LINE: if (rat_meets_line((pcb_line_t *)ao, x, y, gid)) return ao; break; + case PCB_OBJ_ARC: if (rat_meets_arc((pcb_arc_t *)ao, x, y, gid)) return ao; break; + case PCB_OBJ_POLY: if (rat_meets_poly((pcb_poly_t *)ao, x, y, gid)) return ao; break; + case PCB_OBJ_PSTK: if (rat_meets_pstk(data, (pcb_pstk_t *)ao, x, y, gid)) return ao; break; + TODO("find through text") + default: break; + } + } + } + + /* if we got here, there was no anchor object set or it was outdated - find + the currently valid object by endpoint */ + ao = find_obj_on_grp(data, x, y, gid); + if (update) { + if (*path != NULL) + pcb_idpath_destroy(*path); + if (ao == NULL) + *path = NULL; + else + *path = pcb_obj2idpath(ao); + } + + return ao; +} + +void pcb_rat_all_anchor_guess(pcb_data_t *data) +{ + pcb_rat_t *rat; + gdl_iterator_t it; + ratlist_foreach(&data->Rat, &it, rat) { + pcb_rat_anchor_guess(rat, 0, rnd_true); + pcb_rat_anchor_guess(rat, 1, rnd_true); + } +} + + +/*** ops ***/ +/* copies a rat-line to paste buffer */ +void *pcb_ratop_add_to_buffer(pcb_opctx_t *ctx, pcb_rat_t *Rat) +{ + pcb_rat_t *res = pcb_rat_new(ctx->buffer.dst, -1, Rat->Point1.X, Rat->Point1.Y, + Rat->Point2.X, Rat->Point2.Y, Rat->group1, Rat->group2, Rat->Thickness, + pcb_flag_mask(Rat->Flags, PCB_FLAG_FOUND | ctx->buffer.extraflg), + NULL, NULL); + + res->anchor[0] = Rat->anchor[0] == NULL ? NULL : pcb_idpath_dup(Rat->anchor[0]); + res->anchor[1] = Rat->anchor[1] == NULL ? NULL : pcb_idpath_dup(Rat->anchor[1]); + return res; +} + +/* moves a rat-line between board and buffer */ +void *pcb_ratop_move_buffer(pcb_opctx_t *ctx, pcb_rat_t * rat) +{ + rnd_r_delete_entry(ctx->buffer.src->rat_tree, (rnd_box_t *) rat); + + pcb_rat_unreg(rat); + pcb_rat_reg(ctx->buffer.dst, rat); + + PCB_FLAG_CLEAR(PCB_FLAG_FOUND, rat); + + if (!ctx->buffer.dst->rat_tree) + ctx->buffer.dst->rat_tree = rnd_r_create_tree(); + rnd_r_insert_entry(ctx->buffer.dst->rat_tree, (rnd_box_t *) rat); + + return rat; +} + +/* inserts a point into a rat-line */ +void *pcb_ratop_insert_point(pcb_opctx_t *ctx, pcb_rat_t *Rat) +{ + pcb_line_t *newone; + + newone = pcb_line_new_merge(PCB_CURRLAYER(PCB), Rat->Point1.X, Rat->Point1.Y, + ctx->insert.x, ctx->insert.y, conf_core.design.line_thickness, 2 * conf_core.design.clearance, Rat->Flags); + if (!newone) + return newone; + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, PCB_CURRLAYER(PCB), newone, newone); + pcb_rat_invalidate_erase(Rat); + pcb_line_invalidate_draw(PCB_CURRLAYER(PCB), newone); + newone = pcb_line_new_merge(PCB_CURRLAYER(PCB), Rat->Point2.X, Rat->Point2.Y, + ctx->insert.x, ctx->insert.y, conf_core.design.line_thickness, 2 * conf_core.design.clearance, Rat->Flags); + if (newone) { + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, PCB_CURRLAYER(PCB), newone, newone); + pcb_line_invalidate_draw(PCB_CURRLAYER(PCB), newone); + } + pcb_undo_move_obj_to_remove(PCB_OBJ_RAT, Rat, Rat, Rat); + return newone; +} + +/* move a rat to a layer: convert it into a layer line */ +void *pcb_ratop_move_to_layer(pcb_opctx_t *ctx, pcb_rat_t * Rat) +{ + pcb_line_t *newone; + newone = pcb_line_new(ctx->move.dst_layer, Rat->Point1.X, Rat->Point1.Y, + Rat->Point2.X, Rat->Point2.Y, conf_core.design.line_thickness, 2 * conf_core.design.clearance, Rat->Flags); + if (conf_core.editor.clear_line) + rnd_conf_set_editor(clear_line, 1); + if (!newone) + return NULL; + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, ctx->move.dst_layer, newone, newone); + if (PCB->RatOn) + pcb_rat_invalidate_erase(Rat); + pcb_undo_move_obj_to_remove(PCB_OBJ_RAT, Rat, Rat, Rat); + pcb_line_invalidate_draw(ctx->move.dst_layer, newone); + return newone; +} + +/* destroys a rat */ +void *pcb_ratop_destroy(pcb_opctx_t *ctx, pcb_rat_t *Rat) +{ + if (ctx->remove.destroy_target->rat_tree) + rnd_r_delete_entry(ctx->remove.destroy_target->rat_tree, &Rat->BoundingBox); + + pcb_rat_free(Rat); + return NULL; +} + +/* removes a rat */ +void *pcb_ratop_remove(pcb_opctx_t *ctx, pcb_rat_t *Rat) +{ + /* erase from screen and memory */ + if (PCB->RatOn) + pcb_rat_invalidate_erase(Rat); + pcb_undo_move_obj_to_remove(PCB_OBJ_RAT, Rat, Rat, Rat); + return NULL; +} + +/*** draw ***/ +rnd_r_dir_t pcb_rat_draw_callback(const rnd_box_t * b, void *cl) +{ + pcb_rat_t *rat = (pcb_rat_t *) b; + pcb_draw_info_t *info = cl; + + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED | PCB_FLAG_FOUND, rat)) { + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, rat)) + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.selected); + else + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.connected); + } + else if (PCB_HAS_COLOROVERRIDE(rat)) { + rnd_render->set_color(pcb_draw_out.fgGC, rat->override_color); + } + else + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.rat); + + if (conf_core.appearance.rat_thickness < 20) + rat->Thickness = rnd_pixel_slop * conf_core.appearance.rat_thickness; + /* PCB_FLAG_VIA is set if this rat goes to a containing poly: draw a donut */ + if (PCB_FLAG_TEST(PCB_FLAG_VIA, rat)) { + int w = rat->Thickness; + + if (info->xform->thin_draw || info->xform->wireframe) + rnd_hid_set_line_width(pcb_draw_out.fgGC, 0); + else + rnd_hid_set_line_width(pcb_draw_out.fgGC, w); + rnd_render->draw_arc(pcb_draw_out.fgGC, rat->Point1.X, rat->Point1.Y, w * 2, w * 2, 0, 360); + } + else + pcb_line_draw_(info, (pcb_line_t *) rat, 0); + return RND_R_DIR_FOUND_CONTINUE; +} + +void pcb_rat_invalidate_erase(pcb_rat_t *Rat) +{ + if (PCB_FLAG_TEST(PCB_FLAG_VIA, Rat)) { + rnd_coord_t w = Rat->Thickness; + + rnd_box_t b; + + b.X1 = Rat->Point1.X - w * 2 - w / 2; + b.X2 = Rat->Point1.X + w * 2 + w / 2; + b.Y1 = Rat->Point1.Y - w * 2 - w / 2; + b.Y2 = Rat->Point1.Y + w * 2 + w / 2; + pcb_draw_invalidate(&b); + } + else + pcb_line_invalidate_erase((pcb_line_t *) Rat); + pcb_flag_erase(&Rat->Flags); +} + +void pcb_rat_invalidate_draw(pcb_rat_t *Rat) +{ + if (conf_core.appearance.rat_thickness < 20) + Rat->Thickness = rnd_pixel_slop * conf_core.appearance.rat_thickness; + /* rats.c set PCB_FLAG_VIA if this rat goes to a containing poly: draw a donut */ + if (PCB_FLAG_TEST(PCB_FLAG_VIA, Rat)) { + rnd_coord_t w = Rat->Thickness; + + rnd_box_t b; + + b.X1 = Rat->Point1.X - w * 2 - w / 2; + b.X2 = Rat->Point1.X + w * 2 + w / 2; + b.Y1 = Rat->Point1.Y - w * 2 - w / 2; + b.Y2 = Rat->Point1.Y + w * 2 + w / 2; + pcb_draw_invalidate(&b); + } + else + pcb_line_invalidate_draw(NULL, (pcb_line_t *) Rat); +} + +void pcb_rat_update_obj_removed(pcb_board_t *pcb, pcb_any_obj_t *obj) +{ + pcb_rat_t *rat; + gdl_iterator_t it; + + if (obj->type == PCB_OBJ_SUBC) { + pcb_subc_t *subc = (pcb_subc_t *)obj; + pcb_any_obj_t *o; + pcb_data_it_t it2; + + /* subcircuit means checking against each part object; + this is O(R*P), where R is the number of rat lines and P is the + number of subc parts - maybe an rtree based approach would be better */ + for(o = pcb_data_first(&it2, subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it2)) + pcb_rat_update_obj_removed(pcb, o); + return; + } + + ratlist_foreach(&pcb->Data->Rat, &it, rat) { + if ((pcb_rat_anchor_guess(rat, 0, 1) == obj) || (pcb_rat_anchor_guess(rat, 1, 1) == obj)) { + if (PCB->RatOn) + pcb_rat_invalidate_erase(rat); + pcb_undo_move_obj_to_remove(PCB_OBJ_RAT, rat, rat, rat); + } + } +} + Index: tags/2.3.0/src/obj_rat.h =================================================================== --- tags/2.3.0/src/obj_rat.h (nonexistent) +++ tags/2.3.0/src/obj_rat.h (revision 33253) @@ -0,0 +1,73 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Drawing primitive: rats */ + +#ifndef PCB_OBJ_RAT_H +#define PCB_OBJ_RAT_H + +#include +#include "obj_common.h" +#include "layer_grp.h" +#include "idpath.h" + +struct pcb_rat_line_s { /* a rat-line */ + PCB_ANYLINEFIELDS; + rnd_layergrp_id_t group1, group2; /* the layer group each point is on */ + pcb_idpath_t *anchor[2]; /* endpoint object that were originally connected */ + gdl_elem_t link; /* a rat line is in a list on a design */ +}; + + +pcb_rat_t *pcb_rat_alloc(pcb_data_t *data); +pcb_rat_t *pcb_rat_alloc_id(pcb_data_t *data, long int id); +void pcb_rat_free(pcb_rat_t *data); +void pcb_rat_reg(pcb_data_t *data, pcb_rat_t *rat); +void pcb_rat_unreg(pcb_rat_t *rat); + +/* if id is <= 0, allocate a new id */ +pcb_rat_t *pcb_rat_new(pcb_data_t *Data, long int id, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_layergrp_id_t group1, rnd_layergrp_id_t group2, rnd_coord_t Thickness, pcb_flag_t Flags, pcb_any_obj_t *anchor1, pcb_any_obj_t *anchor2); +rnd_bool pcb_rats_destroy(rnd_bool selected); + +/* Look up the anchor object (object the rat is connected to) for end 0 or + end 1. If update is true, also update rat's field */ +pcb_any_obj_t *pcb_rat_anchor_guess(pcb_rat_t *rat, int end, rnd_bool update); + +/* Call pcb_rat_anchor_guess() on all rats of data, with update=true */ +void pcb_rat_all_anchor_guess(pcb_data_t *data); + +/* Minimal update rats after object removal: remove connected rats */ +void pcb_rat_update_obj_removed(pcb_board_t *pcb, pcb_any_obj_t *obj); + + +#define PCB_RAT_LOOP(top) do { \ + pcb_rat_t *line; \ + gdl_iterator_t __it__; \ + ratlist_foreach(&(top)->Rat, &__it__, line) { + +#endif Index: tags/2.3.0/src/obj_rat_draw.h =================================================================== --- tags/2.3.0/src/obj_rat_draw.h (nonexistent) +++ tags/2.3.0/src/obj_rat_draw.h (revision 33253) @@ -0,0 +1,37 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard draw on rats ***/ + +/* Include rtree.h for these */ +#ifdef RND_RTREE_H +rnd_r_dir_t pcb_rat_draw_callback(const rnd_box_t * b, void *cl); +#endif + +void pcb_rat_invalidate_erase(pcb_rat_t *Rat); +void pcb_rat_invalidate_draw(pcb_rat_t *Rat); Index: tags/2.3.0/src/obj_rat_list.c =================================================================== --- tags/2.3.0/src/obj_rat_list.c (nonexistent) +++ tags/2.3.0/src/obj_rat_list.c (revision 33253) @@ -0,0 +1,34 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "layer_grp.h" +#include "obj_rat.h" + +#define TDL_DONT_UNDEF +#include "obj_rat_list.h" +#include Index: tags/2.3.0/src/obj_rat_list.h =================================================================== --- tags/2.3.0/src/obj_rat_list.h (nonexistent) +++ tags/2.3.0/src/obj_rat_list.h (revision 33253) @@ -0,0 +1,47 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_RAT_LIST_H +#define PCB_OBJ_RAT_LIST_H + +#include "obj_rat.h" + +/* List of Rats */ +#define TDL(x) ratlist_ ## x +#define TDL_LIST_T ratlist_t +#define TDL_ITEM_T pcb_rat_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define ratlist_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + + +#include +#include + +#endif Index: tags/2.3.0/src/obj_rat_op.h =================================================================== --- tags/2.3.0/src/obj_rat_op.h (nonexistent) +++ tags/2.3.0/src/obj_rat_op.h (revision 33253) @@ -0,0 +1,38 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard operations on rat lines ***/ + +#include "operation.h" + +void *pcb_ratop_add_to_buffer(pcb_opctx_t *ctx, pcb_rat_t *Rat); +void *pcb_ratop_move_buffer(pcb_opctx_t *ctx, pcb_rat_t * rat); +void *pcb_ratop_insert_point(pcb_opctx_t *ctx, pcb_rat_t *Rat); +void *pcb_ratop_move_to_layer(pcb_opctx_t *ctx, pcb_rat_t * Rat); +void *pcb_ratop_destroy(pcb_opctx_t *ctx, pcb_rat_t *Rat); +void *pcb_ratop_remove(pcb_opctx_t *ctx, pcb_rat_t *Rat); Index: tags/2.3.0/src/obj_subc.c =================================================================== --- tags/2.3.0/src/obj_subc.c (nonexistent) +++ tags/2.3.0/src/obj_subc.c (revision 33253) @@ -0,0 +1,2712 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017..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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "buffer.h" +#include "board.h" +#include "crosshair.h" +#include "brave.h" +#include "data.h" +#include "data_it.h" +#include +#include "obj_subc.h" +#include "obj_subc_op.h" +#include "obj_subc_parent.h" +#include "obj_poly_op.h" +#include "obj_pstk.h" +#include "obj_pstk_inlines.h" +#include "obj_pstk_draw.h" +#include "obj_line_op.h" +#include "obj_term.h" +#include "obj_text_draw.h" +#include +#include "draw.h" +#include "draw_wireframe.h" +#include "flag.h" +#include "polygon.h" +#include "operation.h" +#include "undo.h" +#include "move.h" +#include +#include +#include "pcb_minuid.h" +#include "conf_core.h" +#include +#include +#include "extobj.h" + +#define SUBC_AUX_NAME "subc-aux" + +static const char core_subc_cookie[] = "core-subc"; + +void pcb_subc_reg(pcb_data_t *data, pcb_subc_t *subc) +{ + pcb_subclist_append(&data->subc, subc); + pcb_obj_id_reg(data, subc); + PCB_SET_PARENT(subc->data, subc, subc); + PCB_SET_PARENT(subc, data, data); +} + +void pcb_subc_unreg(pcb_subc_t *subc) +{ + pcb_data_t *data = subc->parent.data; + assert(subc->parent_type == PCB_PARENT_DATA); + pcb_subclist_remove(subc); + pcb_obj_id_del(data, subc); + PCB_CLEAR_PARENT(subc); +} + +/* Modify dst to include src, if src is not a floater */ +static void pcb_box_bump_box_noflt(rnd_box_t *dst, rnd_box_t *src) +{ + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, ((pcb_any_obj_t *)(src)))) + rnd_box_bump_box(dst, src); +} + +/* update cached values: e.g. looking up refdes in attributes each time the + netlist code needs it would be too expensive. Instead, we maintain a + read-only ->refdes field and update it any time attributes change. */ +static void pcb_subc_attrib_post_change(pcb_attribute_list_t *list, const char *name, const char *value) +{ + pcb_subc_t *sc = (pcb_subc_t *)(((char *)list) - offsetof(pcb_subc_t, Attributes)); + if (strcmp(name, "refdes") == 0) { + const char *inv; + sc->refdes = value; + inv = pcb_obj_id_invalid(sc->refdes); + if (inv != NULL) + rnd_message(RND_MSG_ERROR, "Invalid character '%c' in subc refdes '%s'\n", *inv, sc->refdes); + } + else if (strcmp(name, "extobj") == 0) + sc->extobj = value; + pcb_text_dyn_bbox_update(sc->data); +} + +pcb_subc_t *pcb_subc_alloc_id(long int id) +{ + pcb_subc_t *sc; + sc = calloc(sizeof(pcb_subc_t), 1); + sc->ID = id; + sc->Attributes.post_change = pcb_subc_attrib_post_change; + sc->data = pcb_data_new(NULL); + sc->type = PCB_OBJ_SUBC; + PCB_SET_PARENT(sc->data, subc, sc); + minuid_gen(&pcb_minuid, sc->uid); + pcb_term_init(&sc->terminals); + return sc; +} + +pcb_subc_t *pcb_subc_alloc(void) +{ + return pcb_subc_alloc_id(pcb_create_ID_get()); + +} + + +pcb_subc_t *pcb_subc_new(void) +{ + return pcb_subc_alloc(); +} + +void pcb_subc_free(pcb_subc_t *sc) +{ + pcb_extobj_del_pre(sc); + if ((sc->parent.data != NULL) && (sc->parent.data->subc_tree != NULL)) + rnd_r_delete_entry(sc->parent.data->subc_tree, (rnd_box_t *)sc); + pcb_attribute_free(&sc->Attributes); + if (sc->parent_type != PCB_PARENT_INVALID) + pcb_subc_unreg(sc); + pcb_data_free(sc->data); + pcb_term_uninit(&sc->terminals); + pcb_obj_common_free((pcb_any_obj_t *)sc); + free(sc); +} + +/* Create (and append) a new bound layer to a subc */ +static pcb_layer_t *pcb_subc_layer_create_buff(pcb_subc_t *sc, pcb_layer_t *src) +{ + pcb_layer_t *dst = &sc->data->Layer[sc->data->LayerN++]; + + memcpy(&dst->meta, &src->meta, sizeof(src->meta)); + dst->is_bound = 1; + dst->comb = src->comb; + dst->parent.data = sc->data; + dst->parent_type = PCB_PARENT_DATA; + dst->type = PCB_OBJ_LAYER; + dst->name = rnd_strdup(src->name); + return dst; +} + +pcb_layer_t *pcb_subc_layer_create(pcb_subc_t *sc, const char *name, pcb_layer_type_t type, pcb_layer_combining_t comb, int stack_offs, const char *purpose) +{ + pcb_layer_t *dst = &sc->data->Layer[sc->data->LayerN++]; + + dst->is_bound = 1; + dst->meta.bound.user_specified = 0; + dst->meta.bound.user_lid = -1; + dst->meta.bound.type = type; + dst->comb = comb; + dst->meta.bound.stack_offs = stack_offs; + if (purpose != NULL) + dst->meta.bound.purpose = rnd_strdup(purpose); + else + dst->meta.bound.purpose = NULL; + + dst->parent.data = sc->data; + dst->parent_type = PCB_PARENT_DATA; + dst->type = PCB_OBJ_LAYER; + dst->name = rnd_strdup(name); + return dst; +} + +static pcb_line_t *add_aux_line(pcb_layer_t *aux, const char *key, const char *val, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + pcb_line_t *l = pcb_line_new(aux, x1, y1, x2, y2, RND_MM_TO_COORD(0.1), 0, pcb_no_flags()); + pcb_attribute_put(&l->Attributes, key, val); + return l; +} + +static pcb_line_t *find_aux_line(pcb_layer_t *aux, const char *key) +{ + pcb_line_t *line; + gdl_iterator_t it; + linelist_foreach(&aux->Line, &it, line) { + const char *val = pcb_attribute_get(&line->Attributes, "subc-role"); + if ((val != NULL) && (strcmp(val, key) == 0)) + return line; + } + return NULL; +} + +/* Find and save the aux layer in the cache, of it exists */ +void pcb_subc_cache_find_aux(pcb_subc_t *sc) +{ + int n; + for(n = 0; n < sc->data->LayerN; n++) { + if (strcmp(sc->data->Layer[n].name, SUBC_AUX_NAME) == 0) { + sc->aux_layer = sc->data->Layer + n; + return; + } + } + + if (sc->aux_layer == NULL) + sc->aux_layer = pcb_layer_new_bound(sc->data, PCB_LYT_VIRTUAL | PCB_LYT_NOEXPORT | PCB_LYT_MISC | PCB_LYT_TOP, SUBC_AUX_NAME, NULL); +} + +/* Looking up aux objects for determining orientation/origin of a subc + is somewhat expensive. Instead of doing that every time, we just save + the pointer of those objects/layers. They don't change once the + subc is loaded into memory */ +static int pcb_subc_cache_update(pcb_subc_t *sc) +{ + if (sc->aux_layer == NULL) + pcb_subc_cache_find_aux(sc); + + if (sc->aux_cache[0] != NULL) + return 0; + + if (sc->aux_layer == NULL) { + rnd_message(RND_MSG_WARNING, "Can't find subc aux layer\n"); + return -1; + } + + sc->aux_cache[PCB_SUBCH_ORIGIN] = find_aux_line(sc->aux_layer, "origin"); + sc->aux_cache[PCB_SUBCH_X] = find_aux_line(sc->aux_layer, "x"); + sc->aux_cache[PCB_SUBCH_Y] = find_aux_line(sc->aux_layer, "y"); + + return 0; +} + +rnd_bool pcb_subc_find_aux_point(pcb_subc_t *sc, const char *role, rnd_coord_t *x, rnd_coord_t *y) +{ + pcb_line_t *l; + + if (sc->aux_layer == NULL) + pcb_subc_cache_update(sc); + if (sc->aux_layer == NULL) + return rnd_false; + + l = find_aux_line(sc->aux_layer, role); + if (l == NULL) + return rnd_false; + + *x = l->Point1.X; + *y = l->Point1.Y; + + return rnd_true; +} + +int pcb_subc_get_origin(pcb_subc_t *sc, rnd_coord_t *x, rnd_coord_t *y) +{ + if ((pcb_subc_cache_update(sc) != 0) || (sc->aux_cache[PCB_SUBCH_ORIGIN] == NULL)) + return -1; + + *x = sc->aux_cache[PCB_SUBCH_ORIGIN]->Point1.X; + *y = sc->aux_cache[PCB_SUBCH_ORIGIN]->Point1.Y; + return 0; +} + +int pcb_subc_get_rotation(pcb_subc_t *sc, double *rot) +{ + double r, rr; + if ((pcb_subc_cache_update(sc) != 0) || (sc->aux_cache[PCB_SUBCH_X] == NULL)) + return -1; + + r = -1 * RND_RAD_TO_DEG * atan2(sc->aux_cache[PCB_SUBCH_X]->Point2.Y - sc->aux_cache[PCB_SUBCH_X]->Point1.Y, sc->aux_cache[PCB_SUBCH_X]->Point2.X - sc->aux_cache[PCB_SUBCH_X]->Point1.X); + + /* ugly hack to get round angles where possible: if error to a round angle + is less than 1/10000, it was meant to be round, just got ruined by + rounding errors */ + rr = rnd_round(r*10000.0) / 10000.0; + if (rr - r < 0.0001) + *rot = rr; + else + *rot = r; + return 0; +} + +/* The subc is originally drawn on the top side, and the aux layer gets + the PCB_LYT_TOP flag. If the subc is ever sent to the other side, the + aux layer changed side too. This is to be detected here. */ +int pcb_subc_get_side(pcb_subc_t *sc, int *on_bottom) +{ + if ((pcb_subc_cache_update(sc) != 0) || (sc->aux_layer == NULL)) + return -1; + if (!sc->aux_layer->is_bound) + return -1; + + if (sc->aux_layer->meta.bound.type & PCB_LYT_TOP) + *on_bottom = 0; + else if (sc->aux_layer->meta.bound.type & PCB_LYT_BOTTOM) + *on_bottom = 1; + else + return -1; + + return 0; +} + +int pcb_subc_get_host_trans(pcb_subc_t *sc, pcb_host_trans_t *tr, int neg) +{ + int res = 0; + double rr; + + if (pcb_subc_get_origin(sc, &tr->ox, &tr->oy) != 0) { + tr->ox = tr->oy = 0; + res = -1; + } + + if (pcb_subc_get_rotation(sc, &tr->rot) != 0) { + tr->rot = 0; + res = -1; + } + + if (pcb_subc_get_side(sc, &tr->on_bottom) != 0) { + tr->on_bottom = 0; + res = -1; + } + + rr = tr->rot / RND_RAD_TO_DEG; + + if (neg) { + tr->rot = -tr->rot; + rr = -rr; + tr->ox = -tr->ox; + tr->oy = -tr->oy; + } + + tr->cosa = cos(rr); + tr->sina = sin(rr); + + return res; +} + +static int pcb_subc_move_origin_(pcb_subc_t *sc, rnd_coord_t dx, rnd_coord_t dy, rnd_bool and_undo) +{ + int n; + + if ((dx == 0) && (dy == 0)) + return 0; + + for(n = 0; n < PCB_SUBCH_max; n++) { + pcb_line_t *l = sc->aux_cache[n]; + pcb_line_move(l, dx, dy); + if (and_undo) + pcb_undo_add_obj_to_move(PCB_OBJ_LINE, l->parent.layer, l, l, dx, dy); + } + + return 0; +} + +int pcb_subc_move_origin(pcb_subc_t *sc, rnd_coord_t dx, rnd_coord_t dy, rnd_bool and_undo) +{ + if ((pcb_subc_cache_update(sc) != 0) || (sc->aux_cache[PCB_SUBCH_ORIGIN] == NULL)) + return -1; + return pcb_subc_move_origin_(sc, dx, dy, and_undo); +} + +int pcb_subc_move_origin_to(pcb_subc_t *sc, rnd_coord_t x, rnd_coord_t y, rnd_bool and_undo) +{ + rnd_coord_t ox, oy; + + if ((pcb_subc_cache_update(sc) != 0) || (sc->aux_cache[PCB_SUBCH_ORIGIN] == NULL)) + return -1; + + ox = sc->aux_cache[PCB_SUBCH_ORIGIN]->Point1.X; + oy = sc->aux_cache[PCB_SUBCH_ORIGIN]->Point1.Y; + + return pcb_subc_move_origin_(sc, x-ox, y-oy, and_undo); +} + + +static void pcb_subc_cache_invalidate(pcb_subc_t *sc) +{ + sc->aux_cache[0] = NULL; +} + +/* Convert a square line into a polygon and add it to dst */ +static pcb_poly_t *sqline2term(pcb_layer_t *dst, pcb_line_t *line) +{ + pcb_poly_t *poly; + rnd_coord_t x[4], y[4]; + int n; + + pcb_sqline_to_rect(line, x, y); + + poly = pcb_poly_new(dst, line->Clearance, pcb_no_flags()); + for(n = 0; n < 4; n++) + pcb_poly_point_new(poly, x[n], y[n]); + PCB_FLAG_SET(PCB_FLAG_CLEARPOLYPOLY, poly); + pcb_attribute_copy_all(&poly->Attributes, &line->Attributes); + + pcb_poly_init_clip(dst->parent.data, dst, poly); + pcb_add_poly_on_layer(dst, poly); + + return poly; +} + +pcb_layer_t *pcb_loose_subc_layer(pcb_board_t *pcb, pcb_layer_t *layer, rnd_bool alloc) +{ + pcb_subc_t *sc; + int n; + + if (!pcb->is_footprint) + return layer; + + sc = pcb_subclist_first(&pcb->Data->subc); + if (sc == NULL) + return layer; + + for(n = 0; n < sc->data->LayerN; n++) { + pcb_layer_t *l = &sc->data->Layer[n]; + if (!l->is_bound) + continue; + if (l->meta.bound.real == layer) + return l; + } + + /* the subc does not have that layer */ + if (alloc) { + pcb_layer_t *nlayer = &sc->data->Layer[sc->data->LayerN]; + sc->data->LayerN++; + pcb_layer_real2bound(nlayer, layer, 1); + return nlayer; + } + + return layer; +} + +void pcb_subc_as_board_update(pcb_board_t *pcb) +{ + pcb_subc_t *sc; + + if (!pcb->is_footprint) + return; + sc = pcb_subclist_first(&pcb->Data->subc); + if (sc == NULL) + return; + + pcb_subc_bbox(sc); +} + +static rnd_coord_t read_mask(pcb_any_obj_t *obj) +{ + const char *smask = pcb_attribute_get(&obj->Attributes, "elem_smash_pad_mask"); + rnd_coord_t mask = 0; + + if (smask != NULL) { + rnd_bool success; + mask = rnd_get_value_ex(smask, NULL, NULL, NULL, "mm", &success); + if (!success) + mask = 0; + } + return mask; +} + +static void get_aux_layer(pcb_subc_t *sc, int alloc) +{ + if (sc->aux_layer == NULL) + pcb_subc_cache_find_aux(sc); + pcb_subc_cache_update(sc); +} + +void pcb_subc_create_aux(pcb_subc_t *sc, rnd_coord_t ox, rnd_coord_t oy, double rot, rnd_bool bottom) +{ + double unit = PCB_SUBC_AUX_UNIT; + double cs, sn; + + get_aux_layer(sc, 1); + + if (rot == 0.0) { + cs = 1; + sn = 0; + } + else { + cs = cos(rot/RND_RAD_TO_DEG); + sn = sin(rot/RND_RAD_TO_DEG); + } + + if (bottom) { + assert(sc->aux_layer->is_bound); + sc->aux_layer->meta.bound.type &= ~PCB_LYT_TOP; + sc->aux_layer->meta.bound.type |= PCB_LYT_BOTTOM; + cs = -cs; + } + + add_aux_line(sc->aux_layer, "subc-role", "origin", ox, oy, ox, oy); + add_aux_line(sc->aux_layer, "subc-role", "x", ox, oy, rnd_round((double)ox + cs*unit), rnd_round((double)oy + sn*unit)); + add_aux_line(sc->aux_layer, "subc-role", "y", ox, oy, rnd_round((double)ox + sn*unit), rnd_round((double)oy + cs*unit)); +} + +void pcb_subc_create_aux_point(pcb_subc_t *sc, rnd_coord_t x, rnd_coord_t y, const char *role) +{ + get_aux_layer(sc, 1); + add_aux_line(sc->aux_layer, "subc-role", role, x, y, x, y); +} + +int pcb_subc_convert_from_buffer(pcb_buffer_t *buffer) +{ + pcb_subc_t *sc; + int n, top_pads = 0, bottom_pads = 0, has_refdes_text = 0; + pcb_layer_t *dst_top_mask = NULL, *dst_bottom_mask = NULL, *dst_top_paste = NULL, *dst_bottom_paste = NULL, *dst_top_silk = NULL; + vtp0_t mask_pads, paste_pads; + + vtp0_init(&mask_pads); + vtp0_init(&paste_pads); + + sc = pcb_subc_alloc(); + pcb_subc_reg(buffer->Data, sc); + + /* create layer matches and copy objects */ + for(n = 0; n < PCB_MAX_LAYER; n++) { + pcb_layer_t *dst, *src; + pcb_line_t *line; + pcb_text_t *text; + pcb_poly_t *poly; + pcb_arc_t *arc; + pcb_gfx_t *gfx; + pcb_layer_type_t ltype; + + if (pcb_layer_is_pure_empty(&buffer->Data->Layer[n])) + continue; + + src = &buffer->Data->Layer[n]; + dst = pcb_subc_layer_create_buff(sc, src); + ltype = dst->meta.bound.type; + + if ((dst->comb & PCB_LYC_SUB) == 0) { + if ((ltype & PCB_LYT_PASTE) && (ltype & PCB_LYT_TOP)) + dst_top_paste = dst; + else if ((ltype & PCB_LYT_PASTE) && (ltype & PCB_LYT_BOTTOM)) + dst_bottom_paste = dst; + else if ((ltype & PCB_LYT_SILK) && (ltype & PCB_LYT_TOP)) + dst_top_silk = dst; + } + + if (dst->comb & PCB_LYC_SUB) { + if ((ltype & PCB_LYT_MASK) && (ltype & PCB_LYT_TOP)) + dst_top_mask = dst; + else if ((ltype & PCB_LYT_MASK) && (ltype & PCB_LYT_BOTTOM)) + dst_bottom_mask = dst; + } + + while((line = linelist_first(&src->Line)) != NULL) { + rnd_coord_t mask = 0; + char *np, *sq, *termpad; + const char *term; + + termpad = pcb_attribute_get(&line->Attributes, "elem_smash_pad"); + if (termpad != NULL) { + if (ltype & PCB_LYT_TOP) + top_pads++; + else if (ltype & PCB_LYT_BOTTOM) + bottom_pads++; + mask = read_mask((pcb_any_obj_t *)line); + } + term = pcb_attribute_get(&line->Attributes, "term"); + np = pcb_attribute_get(&line->Attributes, "elem_smash_nopaste"); + sq = pcb_attribute_get(&line->Attributes, "elem_smash_shape_square"); + if ((sq != NULL) && (*sq == '1')) { /* convert to polygon */ + poly = sqline2term(dst, line); + if (termpad != NULL) { + if ((np == NULL) || (*np != '1')) { + poly = sqline2term(dst, line); + vtp0_append(&paste_pads, poly); + } + if (mask > 0) { + line->Thickness = mask; + poly = sqline2term(dst, line); + if (term != NULL) + pcb_attribute_put(&poly->Attributes, "term", term); + vtp0_append(&mask_pads, poly); + } + } + + pcb_line_free(line); + } + else { + /* copy the line */ + pcb_line_unreg(line); + pcb_line_reg(dst, line); + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, line); + + if (termpad != NULL) { + pcb_line_t *nl = pcb_line_dup(dst, line); + if ((np == NULL) || (*np != '1')) + vtp0_append(&paste_pads, nl); + if (mask > 0) { + nl = pcb_line_dup(dst, line); + nl->Thickness = mask; + if (term != NULL) + pcb_attribute_put(&nl->Attributes, "term", term); + vtp0_append(&mask_pads, nl); + } + } + } + } + + while((arc = arclist_first(&src->Arc)) != NULL) { + pcb_arc_unreg(arc); + pcb_arc_reg(dst, arc); + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, arc); + } + + while((gfx = gfxlist_first(&src->Gfx)) != NULL) { + pcb_gfx_unreg(gfx); + pcb_gfx_reg(dst, gfx); + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, gfx); + } + + while((text = textlist_first(&src->Text)) != NULL) { + pcb_text_unreg(text); + pcb_text_reg(dst, text); + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, text); + if (!has_refdes_text && (text->TextString != NULL) && (strstr(text->TextString, "%a.parent.refdes%") != NULL)) + has_refdes_text = 1; + } + + while((poly = polylist_first(&src->Polygon)) != NULL) { + pcb_poly_unreg(poly); + pcb_poly_reg(dst, poly); + + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, poly); + } + } + + /* create paste and mask side effects - needed when importing from footprint */ + { + if (top_pads > 0) { + if (dst_top_paste == NULL) + dst_top_paste = pcb_layer_new_bound(sc->data, PCB_LYT_TOP | PCB_LYT_PASTE, "top paste", NULL); + if (dst_top_mask == NULL) { + dst_top_mask = pcb_layer_new_bound(sc->data, PCB_LYT_TOP | PCB_LYT_MASK, "top mask", NULL); + dst_top_mask->comb = PCB_LYC_SUB; + } + } + if (bottom_pads > 0) { + if (dst_bottom_paste == NULL) + dst_bottom_paste = pcb_layer_new_bound(sc->data, PCB_LYT_BOTTOM | PCB_LYT_PASTE, "bottom paste", NULL); + if (dst_bottom_mask == NULL) { + dst_bottom_mask = pcb_layer_new_bound(sc->data, PCB_LYT_BOTTOM | PCB_LYT_MASK, "bottom mask", NULL); + dst_bottom_mask->comb = PCB_LYC_SUB; + } + } + } + + { /* convert globals */ + pcb_pstk_t *ps; + + while((ps = padstacklist_first(&buffer->Data->padstack)) != NULL) { + const pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + pcb_pstk_unreg(ps); + pcb_pstk_reg(sc->data, ps); + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, ps); + ps->proto = pcb_pstk_proto_insert_dup(sc->data, proto, 1, 0); + ps->protoi = -1; + } + } + + vtp0_uninit(&mask_pads); + vtp0_uninit(&paste_pads); + + pcb_subc_create_aux(sc, buffer->X, buffer->Y, 0.0, rnd_false); + + /* Add refdes */ + if ((conf_core.editor.subc_conv_refdes != NULL) && (*conf_core.editor.subc_conv_refdes != '\0')) { + if (strcmp(conf_core.editor.subc_conv_refdes, "") != 0) + pcb_attribute_put(&sc->Attributes, "refdes", conf_core.editor.subc_conv_refdes); + if (!has_refdes_text) { + if (dst_top_silk == NULL) + dst_top_silk = pcb_layer_new_bound(sc->data, PCB_LYT_TOP | PCB_LYT_SILK, "top-silk", NULL); + if (dst_top_silk != NULL) + pcb_text_new(dst_top_silk, pcb_font(PCB, 0, 0), buffer->X, buffer->Y, 0, 100, 0, "%a.parent.refdes%", pcb_flag_make(PCB_FLAG_DYNTEXT | PCB_FLAG_FLOATER)); + else + rnd_message(RND_MSG_ERROR, "Error: can't create top silk layer in subc for placing the refdes\n"); + } + } + + + return 0; +} + +static void pcb_subc_draw_origin(rnd_hid_gc_t GC, pcb_subc_t *sc, rnd_coord_t DX, rnd_coord_t DY) +{ + pcb_line_t *origin; + pcb_subc_cache_update(sc); + + origin = sc->aux_cache[PCB_SUBCH_ORIGIN]; + + if (origin == NULL) + return; + + DX += (origin->Point1.X + origin->Point2.X) / 2; + DY += (origin->Point1.Y + origin->Point2.Y) / 2; + + rnd_render->draw_line(GC, DX - PCB_EMARK_SIZE, DY, DX, DY - PCB_EMARK_SIZE); + rnd_render->draw_line(GC, DX + PCB_EMARK_SIZE, DY, DX, DY - PCB_EMARK_SIZE); + rnd_render->draw_line(GC, DX - PCB_EMARK_SIZE, DY, DX, DY + PCB_EMARK_SIZE); + rnd_render->draw_line(GC, DX + PCB_EMARK_SIZE, DY, DX, DY + PCB_EMARK_SIZE); + + if (sc->auto_termname_display) { +#define OFX (PCB_EMARK_SIZE/5) + rnd_render->draw_line(GC, DX-OFX, DY-PCB_EMARK_SIZE/3, DX-OFX, DY+PCB_EMARK_SIZE/3); + rnd_render->draw_line(GC, DX-OFX, DY+PCB_EMARK_SIZE/3, DX-OFX+PCB_EMARK_SIZE/3, DY+PCB_EMARK_SIZE/3); +#undef OFX + } +} + +/* Draw a small lock on the bottom right corner at lx;ly */ +static void pcb_subc_draw_locked(rnd_hid_gc_t GC, pcb_subc_t *sc, rnd_coord_t lx, rnd_coord_t ly, int on_bottom) +{ + rnd_coord_t s = on_bottom ? -PCB_EMARK_SIZE : PCB_EMARK_SIZE; + + if (rnd_conf.editor.view.flip_x) + lx += PCB_EMARK_SIZE*1.5; + else + lx -= PCB_EMARK_SIZE*1.5; + + if (on_bottom) + ly += PCB_EMARK_SIZE*1.5; + else + ly -= PCB_EMARK_SIZE*1.5; + + rnd_render->draw_line(GC, lx-PCB_EMARK_SIZE, ly+PCB_EMARK_SIZE, lx+PCB_EMARK_SIZE, ly+PCB_EMARK_SIZE); + rnd_render->draw_line(GC, lx-PCB_EMARK_SIZE, ly-PCB_EMARK_SIZE, lx+PCB_EMARK_SIZE, ly-PCB_EMARK_SIZE); + rnd_render->draw_line(GC, lx-PCB_EMARK_SIZE, ly-PCB_EMARK_SIZE, lx-PCB_EMARK_SIZE, ly+PCB_EMARK_SIZE); + rnd_render->draw_line(GC, lx+PCB_EMARK_SIZE, ly-PCB_EMARK_SIZE, lx+PCB_EMARK_SIZE, ly+PCB_EMARK_SIZE); + rnd_render->draw_line(GC, lx-PCB_EMARK_SIZE, ly+PCB_EMARK_SIZE*1/3, lx+PCB_EMARK_SIZE, ly+PCB_EMARK_SIZE*1/3); + rnd_render->draw_line(GC, lx-PCB_EMARK_SIZE, ly-PCB_EMARK_SIZE*1/3, lx+PCB_EMARK_SIZE, ly-PCB_EMARK_SIZE*1/3); + rnd_render->draw_arc(GC, lx, ly-s, PCB_EMARK_SIZE*2/3, PCB_EMARK_SIZE*2/3, 180, on_bottom ? -180 : 180); +} + +void pcb_xordraw_subc(pcb_subc_t *sc, rnd_coord_t DX, rnd_coord_t DY, int use_curr_side) +{ + int n, mirr; + rnd_coord_t w = 0, h = 0; + + mirr = use_curr_side && conf_core.editor.show_solder_side; + + /* mirror center */ + if (mirr) { + pcb_subc_get_origin(sc, &w, &h); + w *= 2; + h *= 2; + } + + /* draw per layer objects */ + for(n = 0; n < sc->data->LayerN; n++) { + pcb_layer_t *ly = sc->data->Layer + n; + pcb_line_t *line; + pcb_text_t *text; + pcb_poly_t *poly; + pcb_arc_t *arc; + pcb_gfx_t *gfx; + gdl_iterator_t it; + + linelist_foreach(&ly->Line, &it, line) + pcb_draw_wireframe_line(pcb_crosshair.GC, + DX + PCB_CSWAP_X(line->Point1.X, w, mirr), + DY + PCB_CSWAP_Y(line->Point1.Y, h, mirr), + DX + PCB_CSWAP_X(line->Point2.X, w, mirr), + DY + PCB_CSWAP_Y(line->Point2.Y, h, mirr), + line->Thickness, + 0 ); + + arclist_foreach(&ly->Arc, &it, arc) { + if(arc->Width != arc->Height) { +TODO(": The wireframe arc drawing code cannot draw ellipses yet so draw the elliptical arc with a thin line ") + double sa = mirr ? RND_SWAP_ANGLE(arc->StartAngle) : arc->StartAngle; + double da = mirr ? RND_SWAP_DELTA(arc->Delta) : arc->Delta; + rnd_render->draw_arc(pcb_crosshair.GC, DX + PCB_CSWAP_X(arc->X, w, mirr), DY + PCB_CSWAP_Y(arc->Y, h, mirr), arc->Width, arc->Height, sa, da); + } + else { + pcb_arc_t temp_arc; + temp_arc.StartAngle = mirr ? RND_SWAP_ANGLE(arc->StartAngle) : arc->StartAngle; + temp_arc.Delta = mirr ? RND_SWAP_DELTA(arc->Delta) : arc->Delta; + temp_arc.X = DX + PCB_CSWAP_X(arc->X, w, mirr); + temp_arc.Y = DY + PCB_CSWAP_Y(arc->Y, h, mirr); + temp_arc.Width = arc->Width; + temp_arc.Height = arc->Height; + temp_arc.Thickness = arc->Thickness; + pcb_draw_wireframe_arc(pcb_crosshair.GC, &temp_arc, arc->Thickness); + } + } + + gfxlist_foreach(&ly->Gfx, &it, gfx) { + rnd_render->draw_line(pcb_crosshair.GC, DX+gfx->corner[0].X, DY+gfx->corner[0].Y, DX+gfx->corner[1].X, DY+gfx->corner[1].Y); + rnd_render->draw_line(pcb_crosshair.GC, DX+gfx->corner[1].X, DY+gfx->corner[1].Y, DX+gfx->corner[2].X, DY+gfx->corner[2].Y); + rnd_render->draw_line(pcb_crosshair.GC, DX+gfx->corner[2].X, DY+gfx->corner[2].Y, DX+gfx->corner[3].X, DY+gfx->corner[3].Y); + rnd_render->draw_line(pcb_crosshair.GC, DX+gfx->corner[3].X, DY+gfx->corner[3].Y, DX+gfx->corner[0].X, DY+gfx->corner[0].Y); + } + + polylist_foreach(&ly->Polygon, &it, poly) + pcb_xordraw_poly_subc(poly, DX, DY, w, h, mirr); + + textlist_foreach(&ly->Text, &it, text) { + if (mirr) { + pcb_text_t t = {0}; + t = *text; + t.X = PCB_CSWAP_X(text->X, w, mirr); + t.Y = PCB_CSWAP_Y(text->Y, h, mirr); + t.BoundingBox.X1 = PCB_CSWAP_X(text->BoundingBox.X1, w, mirr); + t.BoundingBox.Y1 = PCB_CSWAP_Y(text->BoundingBox.Y1, h, mirr); + t.BoundingBox.X2 = PCB_CSWAP_X(text->BoundingBox.X2, w, mirr); + t.BoundingBox.Y2 = PCB_CSWAP_Y(text->BoundingBox.Y2, h, mirr); + PCB_FLAG_TOGGLE(PCB_FLAG_ONSOLDER, &t); + pcb_text_draw_xor(&t, DX, DY, 1); + } + else + pcb_text_draw_xor(text, DX, DY, 1); + } + } + + /* draw global objects */ + { + pcb_pstk_t *ps; + gdl_iterator_t it; + + padstacklist_foreach(&sc->data->padstack, &it, ps) { + rnd_coord_t ox, oy; + int oxm, pri; + ox = ps->x; + oy = ps->y; + oxm = ps->xmirror; + pri = ps->protoi; + ps->x = PCB_CSWAP_X(ps->x, w, mirr); + ps->y = PCB_CSWAP_Y(ps->y, h, mirr); + ps->x += DX; + ps->y += DY; + if (mirr) { + ps->xmirror = !ps->xmirror; + ps->protoi = -1; + } + pcb_pstk_thindraw(NULL, pcb_crosshair.GC, ps); + ps->x = ox; + ps->y = oy; + ps->xmirror = oxm; + ps->protoi = pri; + } + } + + pcb_subc_draw_origin(pcb_crosshair.GC, sc, DX, DY); +} + +pcb_layer_t *pcb_subc_alloc_layer_like(pcb_subc_t *subc, const pcb_layer_t *sl) +{ + pcb_layer_t *dl; + + if (subc->data->LayerN >= PCB_MAX_LAYER) + return NULL; + + dl = &subc->data->Layer[subc->data->LayerN++]; + dl->is_bound = 1; + dl->type = PCB_OBJ_LAYER; + memcpy(&dl->meta.bound, &sl->meta.bound, sizeof(sl->meta.bound)); + dl->name = rnd_strdup(sl->name); + dl->comb = sl->comb; + if (dl->meta.bound.real != NULL) + pcb_layer_link_trees(dl, dl->meta.bound.real); + + return dl; +} + +#define MAYBE_KEEP_ID(dst, src) \ +do { \ + if ((keep_ids) && (dst != NULL)) \ + dst->ID = src->ID; \ +} while(0) + +pcb_subc_t *pcb_subc_copy_meta(pcb_subc_t *dst, const pcb_subc_t *src) +{ + if (dst == NULL) + return NULL; + pcb_attribute_copy_all(&dst->Attributes, &src->Attributes); + return dst; +} + +void pcb_subc_dup_layer_objs(pcb_subc_t *dst_sc, pcb_layer_t *dl, pcb_layer_t *sl, rnd_coord_t dx, rnd_coord_t dy, rnd_bool keep_ids) +{ + pcb_line_t *line, *nline; + pcb_text_t *text, *ntext; + pcb_arc_t *arc, *narc; + pcb_gfx_t *gfx, *ngfx; + gdl_iterator_t it; + + linelist_foreach(&sl->Line, &it, line) { + nline = pcb_line_dup_at(dl, line, dx, dy); + MAYBE_KEEP_ID(nline, line); + if (nline != NULL) { + PCB_SET_PARENT(nline, layer, dl); + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, nline)) { + pcb_box_bump_box_noflt(&dst_sc->BoundingBox, &nline->BoundingBox); + pcb_box_bump_box_noflt(&dst_sc->bbox_naked, &nline->bbox_naked); + } + } + } + + arclist_foreach(&sl->Arc, &it, arc) { + narc = pcb_arc_dup_at(dl, arc, dx, dy); + MAYBE_KEEP_ID(narc, arc); + if (narc != NULL) { + PCB_SET_PARENT(narc, layer, dl); + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, narc)) { + pcb_box_bump_box_noflt(&dst_sc->BoundingBox, &narc->BoundingBox); + pcb_box_bump_box_noflt(&dst_sc->bbox_naked, &narc->bbox_naked); + } + } + } + + gfxlist_foreach(&sl->Gfx, &it, gfx) { + ngfx = pcb_gfx_dup_at(dl, gfx, dx, dy); + MAYBE_KEEP_ID(ngfx, gfx); + if (ngfx != NULL) { + PCB_SET_PARENT(ngfx, layer, dl); + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, ngfx)) { + pcb_box_bump_box_noflt(&dst_sc->BoundingBox, &ngfx->BoundingBox); + pcb_box_bump_box_noflt(&dst_sc->bbox_naked, &ngfx->bbox_naked); + } + } + } + + textlist_foreach(&sl->Text, &it, text) { + ntext = pcb_text_dup_at(dl, text, dx, dy); + MAYBE_KEEP_ID(ntext, text); + if (ntext != NULL) { + PCB_SET_PARENT(ntext, layer, dl); + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, ntext)) { + pcb_box_bump_box_noflt(&dst_sc->BoundingBox, &ntext->BoundingBox); + pcb_box_bump_box_noflt(&dst_sc->bbox_naked, &ntext->bbox_naked); + } + } + } +} + +pcb_subc_t *pcb_subc_dup_at(pcb_board_t *pcb, pcb_data_t *dst, const pcb_subc_t *src, rnd_coord_t dx, rnd_coord_t dy, rnd_bool keep_ids, rnd_bool undoable) +{ + pcb_board_t *src_pcb; + int n; + pcb_subc_t *sc = pcb_subc_alloc(); + int undoable_psproto = (undoable && (dst->parent_type == PCB_PARENT_BOARD)); + + if (keep_ids) + sc->ID = src->ID; + else + sc->ID = pcb_create_ID_get(); + + sc->copied_from_ID = src->ID; + + minuid_cpy(sc->uid, src->uid); + pcb_subc_reg(dst, sc); + + src_pcb = pcb_data_get_top(src->data); + + pcb_subc_copy_meta(sc, src); + + sc->BoundingBox.X1 = sc->BoundingBox.Y1 = RND_MAX_COORD; + sc->BoundingBox.X2 = sc->BoundingBox.Y2 = -RND_MAX_COORD; + sc->bbox_naked.X1 = sc->bbox_naked.Y1 = RND_MAX_COORD; + sc->bbox_naked.X2 = sc->bbox_naked.Y2 = -RND_MAX_COORD; + + /* make a copy of layer data */ + for(n = 0; n < src->data->LayerN; n++) { + pcb_layer_t *sl = src->data->Layer + n; + pcb_layer_t *dl = sc->data->Layer + n; + + /* bind layer/resolve layers */ + dl->is_bound = 1; + dl->type = PCB_OBJ_LAYER; + if ((pcb != NULL) && (pcb == src_pcb)) { + /* copy within the same board */ + memcpy(&dl->meta.bound, &sl->meta.bound, sizeof(sl->meta.bound)); + dl->name = rnd_strdup(sl->name); + dl->comb = sl->comb; + if (dl->meta.bound.real != NULL) + pcb_layer_link_trees(dl, dl->meta.bound.real); + } + else if (pcb != NULL) { + /* copying from buffer to board */ + memcpy(&dl->meta.bound, &sl->meta.bound, sizeof(sl->meta.bound)); + dl->name = rnd_strdup(sl->name); + dl->meta.bound.real = pcb_layer_resolve_binding(pcb, sl); + dl->comb = sl->comb; + + if (dl->meta.bound.real == NULL) { + if (!(dl->meta.bound.type & PCB_LYT_VIRTUAL)) { + const char *name = dl->name; + if (name == NULL) name = ""; + rnd_message(RND_MSG_WARNING, "Couldn't bind layer %s of subcircuit while placing it\n", name); + } + } + else + pcb_layer_link_trees(dl, dl->meta.bound.real); + } + else { + /* copying from board to buffer */ + memcpy(&dl->meta.bound, &sl->meta.bound, sizeof(sl->meta.bound)); + + dl->meta.bound.real = NULL; + dl->name = rnd_strdup(sl->name); + dl->comb = sl->comb; + } + + pcb_subc_dup_layer_objs(sc, dl, sl, dx, dy, keep_ids); + } + sc->data->LayerN = src->data->LayerN; + + /* bind the via rtree so that vias added in this subc show up on the board */ + if (pcb != NULL) { + if (pcb->Data->padstack_tree == NULL) + pcb->Data->padstack_tree = rnd_r_create_tree(); + sc->data->padstack_tree = pcb->Data->padstack_tree; + } + + { /* make a copy of global data */ + pcb_pstk_t *ps, *nps; + gdl_iterator_t it; + + padstacklist_foreach(&src->data->padstack, &it, ps) { + rnd_cardinal_t pid = pcb_pstk_proto_insert_dup(sc->data, pcb_pstk_get_proto(ps), 1, undoable_psproto); + nps = pcb_pstk_new_tr(sc->data, -1, pid, ps->x+dx, ps->y+dy, ps->Clearance, ps->Flags, ps->rot, ps->xmirror, ps->smirror); + pcb_pstk_copy_meta(nps, ps); + MAYBE_KEEP_ID(nps, ps); + if (nps != NULL) { + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, nps)) { + pcb_box_bump_box_noflt(&sc->BoundingBox, &nps->BoundingBox); + pcb_box_bump_box_noflt(&sc->bbox_naked, &nps->bbox_naked); + } + } + } + } + + /* make a copy of polygons at the end so clipping caused by other objects are calculated only once */ + for(n = 0; n < src->data->LayerN; n++) { + pcb_layer_t *sl = src->data->Layer + n; + pcb_layer_t *dl = sc->data->Layer + n; + pcb_poly_t *poly, *npoly; + gdl_iterator_t it; + + polylist_foreach(&sl->Polygon, &it, poly) { + npoly = pcb_poly_dup_at(dl, poly, dx, dy); + MAYBE_KEEP_ID(npoly, poly); + if (npoly != NULL) { + PCB_SET_PARENT(npoly, layer, dl); + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, npoly)) { + pcb_box_bump_box_noflt(&sc->BoundingBox, &npoly->BoundingBox); + pcb_box_bump_box_noflt(&sc->bbox_naked, &npoly->bbox_naked); + } + pcb_poly_ppclear(npoly); + } + } + } + + memcpy(&sc->Flags, &src->Flags, sizeof(sc->Flags)); + + rnd_close_box(&sc->BoundingBox); + rnd_close_box(&sc->bbox_naked); + + if (pcb != NULL) { + if (!dst->subc_tree) + dst->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(dst->subc_tree, (rnd_box_t *)sc); + } + + return sc; +} + +pcb_subc_t *pcb_subc_dup(pcb_board_t *pcb, pcb_data_t *dst, pcb_subc_t *src) +{ + return pcb_subc_dup_at(pcb, dst, src, 0, 0, rnd_false, rnd_true); +} + +void pcb_subc_bbox(pcb_subc_t *sc) +{ + pcb_data_bbox(&sc->BoundingBox, sc->data, rnd_true); + pcb_data_bbox_naked(&sc->bbox_naked, sc->data, rnd_true); +} + + +/* erases a subc on a layer */ +void EraseSubc(pcb_subc_t *sc) +{ + pcb_draw_invalidate(sc); +/* pcb_flag_erase(&sc->Flags); ??? */ +} + +void DrawSubc(pcb_subc_t *sc) +{ + pcb_draw_invalidate(sc); +} + + +/* Execute an operation on all children on an sc and update the bbox of the sc */ +void *pcb_subc_op(pcb_data_t *Data, pcb_subc_t *sc, pcb_opfunc_t *opfunc, pcb_opctx_t *ctx, pcb_subc_op_undo_t batch_undo) +{ + int n; + + if (!(pcb_brave & PCB_BRAVE_NOCLIPBATCH) && (Data != NULL)) + pcb_data_clip_inhibit_inc(Data); + pcb_subc_part_changed_inhibit_inc(sc); + + switch(batch_undo) { + case PCB_SUBCOP_UNDO_SUBC: + pcb_undo_freeze_serial(); + pcb_undo_freeze_add(); + break; + case PCB_SUBCOP_UNDO_BATCH: + pcb_undo_inc_serial(); + pcb_undo_save_serial(); + pcb_undo_freeze_serial(); + break; + case PCB_SUBCOP_UNDO_NORMAL: + break; + } + + EraseSubc(sc); + if (pcb_data_get_top(Data) != NULL) { + if (Data->subc_tree != NULL) + rnd_r_delete_entry(Data->subc_tree, (rnd_box_t *)sc); + else + Data->subc_tree = rnd_r_create_tree(); + } + + /* for calculating the new bounding box on the fly */ + sc->BoundingBox.X1 = sc->BoundingBox.Y1 = RND_MAX_COORD; + sc->BoundingBox.X2 = sc->BoundingBox.Y2 = -RND_MAX_COORD; + sc->bbox_naked.X1 = sc->bbox_naked.Y1 = RND_MAX_COORD; + sc->bbox_naked.X2 = sc->bbox_naked.Y2 = -RND_MAX_COORD; + + /* execute on layer locals */ + for(n = 0; n < sc->data->LayerN; n++) { + pcb_layer_t *sl = sc->data->Layer + n; + pcb_line_t *line; + pcb_text_t *text; + pcb_poly_t *poly; + pcb_arc_t *arc; + pcb_gfx_t *gfx; + gdl_iterator_t it; + + + linelist_foreach(&sl->Line, &it, line) { + pcb_object_operation(opfunc, ctx, PCB_OBJ_LINE, sl, line, line); + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, line)) { + pcb_box_bump_box_noflt(&sc->BoundingBox, &line->BoundingBox); + pcb_box_bump_box_noflt(&sc->bbox_naked, &line->bbox_naked); + } + } + + arclist_foreach(&sl->Arc, &it, arc) { + pcb_object_operation(opfunc, ctx, PCB_OBJ_ARC, sl, arc, arc); + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, arc)) { + pcb_box_bump_box_noflt(&sc->BoundingBox, &arc->BoundingBox); + pcb_box_bump_box_noflt(&sc->bbox_naked, &arc->bbox_naked); + } + } + + textlist_foreach(&sl->Text, &it, text) { + pcb_object_operation(opfunc, ctx, PCB_OBJ_TEXT, sl, text, text); + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, text)) { + pcb_box_bump_box_noflt(&sc->BoundingBox, &text->BoundingBox); + pcb_box_bump_box_noflt(&sc->bbox_naked, &text->bbox_naked); + } + } + + polylist_foreach(&sl->Polygon, &it, poly) { + pcb_object_operation(opfunc, ctx, PCB_OBJ_POLY, sl, poly, poly); + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, poly)) { + pcb_box_bump_box_noflt(&sc->BoundingBox, &poly->BoundingBox); + pcb_box_bump_box_noflt(&sc->bbox_naked, &poly->bbox_naked); + } + } + + gfxlist_foreach(&sl->Gfx, &it, gfx) { + pcb_object_operation(opfunc, ctx, PCB_OBJ_GFX, sl, gfx, gfx); + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, gfx)) { + pcb_box_bump_box_noflt(&sc->BoundingBox, &gfx->BoundingBox); + pcb_box_bump_box_noflt(&sc->bbox_naked, &gfx->bbox_naked); + } + } + + } + + + /* execute on globals */ + { + pcb_pstk_t *ps; + gdl_iterator_t it; + + padstacklist_foreach(&sc->data->padstack, &it, ps) { + pcb_object_operation(opfunc, ctx, PCB_OBJ_PSTK, ps, ps, ps); + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, ps)) { + pcb_box_bump_box_noflt(&sc->BoundingBox, &ps->BoundingBox); + pcb_box_bump_box_noflt(&sc->bbox_naked, &ps->bbox_naked); + } + } + } + + rnd_close_box(&sc->BoundingBox); + rnd_close_box(&sc->bbox_naked); + if (pcb_data_get_top(Data) != NULL) { + int doit = 1; + if (sc->extobj != NULL) { /* ugly corner case: extobj calls may have added the subc to the rtree already, do not add it twice */ + rnd_rtree_it_t it; + rnd_box_t *b; + + for(b = rnd_r_first(Data->subc_tree, &it); b != NULL; b = rnd_r_next(&it)) { + if (b == (rnd_box_t *)sc) { + doit = 0; + break; + } + } + } + if (doit) + rnd_r_insert_entry(Data->subc_tree, (rnd_box_t *)sc); + } + + sc->part_changed_bbox_dirty = 0; /* we've just recalculated the bbox */ + pcb_subc_part_changed_inhibit_dec(sc); + DrawSubc(sc); + + switch(batch_undo) { + case PCB_SUBCOP_UNDO_SUBC: pcb_undo_unfreeze_add(); pcb_undo_unfreeze_serial(); break; + case PCB_SUBCOP_UNDO_BATCH: pcb_undo_unfreeze_serial(); break; + case PCB_SUBCOP_UNDO_NORMAL: break; + } + + if (!(pcb_brave & PCB_BRAVE_NOCLIPBATCH) && (Data != NULL)) + pcb_data_clip_inhibit_dec(Data, 0); + + return sc; +} + + +/* copies a subcircuit onto the PCB (a.k.a "paste"). Then does a draw. */ +void *pcb_subcop_copy(pcb_opctx_t *ctx, pcb_subc_t *src) +{ + pcb_subc_t *sc; + + sc = pcb_subc_dup_at(PCB, PCB->Data, src, ctx->copy.DeltaX, ctx->copy.DeltaY, ctx->copy.keep_id, rnd_true); + + pcb_undo_add_obj_to_create(PCB_OBJ_SUBC, sc, sc, sc); + + if (ctx->copy.from_outside && conf_core.editor.show_solder_side) { + uundo_serial_t last; + rnd_coord_t w, h; + + /* move-to-the-other-side is not undoable: it's part of the placement */ + pcb_undo_inc_serial(); + last = pcb_undo_serial(); + + pcb_subc_get_origin(sc, &w, &h); + pcb_subc_change_side(sc, 2 * h - PCB->hidlib.size_y); + pcb_undo_truncate_from(last); + + } + + pcb_text_dyn_bbox_update(sc->data); + + return sc; +} + +extern pcb_opfunc_t ClipFunctions, MoveFunctions, MoveFunctions_noclip, Rotate90Functions, RotateFunctions, ChgFlagFunctions, ChangeSizeFunctions, ChangeClearSizeFunctions, Change1stSizeFunctions, Change2ndSizeFunctions; + +/* drag&drop move when not selected */ +void *pcb_subcop_move(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + pcb_board_t *pcb = pcb_data_get_top(sc->data); + pcb_data_t *data = (pcb != NULL ? pcb->Data : NULL); + pcb_opctx_t clip; + + /* restore all pins/pads at once, at the old location */ + clip.clip.restore = 1; clip.clip.clear = 0; + clip.clip.pcb = ctx->move.pcb; + pcb_subc_op(data, sc, &ClipFunctions, &clip, PCB_SUBCOP_UNDO_NORMAL); + + /* do the move without messing with the clipping */ + pcb_subc_op(data, sc, &MoveFunctions_noclip, ctx, PCB_SUBCOP_UNDO_NORMAL); + + /* clear all pins/pads at once, at the new location */ + clip.clip.restore = 0; clip.clip.clear = 1; + pcb_subc_op(data, sc, &ClipFunctions, &clip, PCB_SUBCOP_UNDO_NORMAL); + return sc; +} + +void *pcb_subcop_rotate90(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + pcb_board_t *pcb = pcb_data_get_top(sc->data); + return pcb_subc_op((pcb != NULL ? pcb->Data : NULL), sc, &Rotate90Functions, ctx, PCB_SUBCOP_UNDO_SUBC); +} + +void *pcb_subcop_rotate(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + pcb_data_t *data; + + ctx->rotate.pcb = pcb_data_get_top(sc->data); + data = (ctx->rotate.pcb != NULL ? ctx->rotate.pcb->Data : NULL); + + return pcb_subc_op(data, sc, &RotateFunctions, ctx, PCB_SUBCOP_UNDO_SUBC); +} + +void pcb_subc_rotate90(pcb_subc_t *subc, rnd_coord_t cx, rnd_coord_t cy, int steps) +{ + pcb_opctx_t ctx; + + ctx.rotate.center_x = cx; + ctx.rotate.center_y = cy; + ctx.rotate.number = steps; + pcb_subcop_rotate90(&ctx, subc); +} + +void pcb_subc_rotate(pcb_subc_t *subc, rnd_coord_t cx, rnd_coord_t cy, double cosa, double sina, double angle) +{ + pcb_opctx_t ctx; + + ctx.rotate.center_x = cx; + ctx.rotate.center_y = cy; + ctx.rotate.angle = angle; + ctx.rotate.cosa = cosa; + ctx.rotate.sina = sina; + pcb_subcop_rotate(&ctx, subc); +} + +void pcb_subc_move(pcb_subc_t *sc, rnd_coord_t dx, rnd_coord_t dy, rnd_bool more_to_come) +{ + pcb_opctx_t ctx; + ctx.move.pcb = NULL; + ctx.move.dx = dx; + ctx.move.dy = dy; + ctx.move.more_to_come = more_to_come; + pcb_subcop_move(&ctx, sc); +} + +rnd_bool pcb_selected_subc_change_side(void) +{ + rnd_bool change = rnd_false; + + if (PCB->pstk_on) { + PCB_SUBC_LOOP(PCB->Data); + { + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, subc)) { + change |= pcb_subc_change_side(subc, 2 * pcb_crosshair.Y - PCB->hidlib.size_y); + } + } + PCB_END_LOOP; + } + return change; +} + +static int subc_bind_layer(pcb_layer_t *dl, pcb_layer_t *sl, int dst_is_pcb) +{ + int chg = 0; + + if (!dst_is_pcb) { + /* keep only the layer binding match, unbound other aspects */ + sl->meta.bound.real = NULL; + sl->arc_tree = sl->line_tree = sl->text_tree = sl->polygon_tree = NULL; + chg++; + } + else { + sl->meta.bound.real = dl; + chg++; + } + + return chg; +} + + +static int subc_relocate_layer_objs(pcb_layer_t *dl, pcb_data_t *src_data, pcb_layer_t *sl, int src_has_real_layer, int dst_is_pcb, int move_obj) +{ + pcb_line_t *line; + pcb_text_t *text; + pcb_poly_t *poly; + pcb_arc_t *arc; + pcb_gfx_t *gfx; + gdl_iterator_t it; + int chg = 0; + pcb_data_t *dst_data = dl == NULL ? NULL : dl->parent.data; + + linelist_foreach(&sl->Line, &it, line) { + if (src_has_real_layer) { + pcb_poly_restore_to_poly(src_data, PCB_OBJ_LINE, sl, line); + rnd_r_delete_entry(sl->line_tree, (rnd_box_t *)line); + chg++; + } + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, line); + if ((move_obj) && (dl != NULL)) { + pcb_line_unreg(line); + pcb_line_reg(dl, line); + } + if ((dl != NULL) && (dl->line_tree != NULL)) { + rnd_r_insert_entry(dl->line_tree, (rnd_box_t *)line); + chg++; + } + if (dst_is_pcb && (dl != NULL)) + pcb_poly_clear_from_poly(dst_data, PCB_OBJ_LINE, dl, line); + } + + arclist_foreach(&sl->Arc, &it, arc) { + if (src_has_real_layer) { + pcb_poly_restore_to_poly(src_data, PCB_OBJ_ARC, sl, arc); + rnd_r_delete_entry(sl->arc_tree, (rnd_box_t *)arc); + chg++; + } + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, arc); + if ((move_obj) && (dl != NULL)) { + pcb_arc_unreg(arc); + pcb_arc_reg(dl, arc); + } + if ((dl != NULL) && (dl->arc_tree != NULL)) { + rnd_r_insert_entry(dl->arc_tree, (rnd_box_t *)arc); + chg++; + } + if (dst_is_pcb && (dl != NULL)) + pcb_poly_clear_from_poly(dst_data, PCB_OBJ_ARC, dl, arc); + } + + textlist_foreach(&sl->Text, &it, text) { + if (src_has_real_layer) { + pcb_poly_restore_to_poly(src_data, PCB_OBJ_LINE, sl, text); + rnd_r_delete_entry(sl->text_tree, (rnd_box_t *)text); + chg++; + } + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, text); + if ((move_obj) && (dl != NULL)) { + pcb_text_unreg(text); + pcb_text_reg(dl, text); + } + if ((dl != NULL) && (dl->text_tree != NULL)) { + rnd_r_insert_entry(dl->text_tree, (rnd_box_t *)text); + chg++; + } + if (dst_is_pcb && (dl != NULL)) + pcb_poly_clear_from_poly(dst_data, PCB_OBJ_TEXT, dl, text); + } + + polylist_foreach(&sl->Polygon, &it, poly) { + pcb_poly_pprestore(poly); + if (src_has_real_layer) { + rnd_r_delete_entry(sl->polygon_tree, (rnd_box_t *)poly); + chg++; + } + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, poly); + if ((move_obj) && (dl != NULL)) { + pcb_poly_unreg(poly); + pcb_poly_reg(dl, poly); + } + if ((dl != NULL) && (dl->polygon_tree != NULL)) { + rnd_r_insert_entry(dl->polygon_tree, (rnd_box_t *)poly); + chg++; + } + if (dst_is_pcb && (dl != NULL)) + pcb_poly_ppclear_at(poly, dl); + } + + gfxlist_foreach(&sl->Gfx, &it, gfx) { + if (src_has_real_layer) { + rnd_r_delete_entry(sl->gfx_tree, (rnd_box_t *)gfx); + chg++; + } + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, gfx); + if ((move_obj) && (dl != NULL)) { + pcb_gfx_unreg(gfx); + pcb_gfx_reg(dl, gfx); + } + if ((dl != NULL) && (dl->gfx_tree != NULL)) { + rnd_r_insert_entry(dl->gfx_tree, (rnd_box_t *)gfx); + chg++; + } + } + + return chg + subc_bind_layer(dl, sl, dst_is_pcb); +} + +static int subc_bind_globals(pcb_data_t *dst, pcb_subc_t *sc, int dst_is_pcb) +{ + int chg = 0; + + if ((dst != NULL) && (dst_is_pcb)) { + if (dst->padstack_tree == NULL) + dst->padstack_tree = rnd_r_create_tree(); + sc->data->padstack_tree = dst->padstack_tree; + chg++; + } + else + sc->data->padstack_tree = NULL; + + return chg; +} + +static int subc_relocate_globals(pcb_data_t *dst, pcb_data_t *new_parent, pcb_subc_t *sc, int dst_is_pcb, int move_obj) +{ + pcb_pstk_t *ps; + gdl_iterator_t it; + int chg = 0; + + padstacklist_foreach(&sc->data->padstack, &it, ps) { + const pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + int undoable_psproto = ps->parent.data->parent_type == PCB_PARENT_BOARD; + + assert(proto != NULL); /* the prototype must be accessible at the source else we can't add it in the dest */ + pcb_poly_restore_to_poly(ps->parent.data, PCB_OBJ_PSTK, NULL, ps); + if (sc->data->padstack_tree != NULL) + rnd_r_delete_entry(sc->data->padstack_tree, (rnd_box_t *)ps); + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, ps); + if ((dst != NULL) && (dst->padstack_tree != NULL)) + rnd_r_insert_entry(dst->padstack_tree, (rnd_box_t *)ps); + if ((move_obj) && (dst != NULL)) { + pcb_pstk_unreg(ps); + pcb_pstk_reg(dst, ps); + } + if (dst != NULL) + ps->proto = pcb_pstk_proto_insert_dup(ps->parent.data, proto, 1, undoable_psproto); + ps->protoi = -1; + ps->parent.data = new_parent; + if (dst_is_pcb) + pcb_poly_clear_from_poly(ps->parent.data, PCB_OBJ_PSTK, NULL, ps); + chg++; + } + + return chg + subc_bind_globals(dst, sc, dst_is_pcb); +} + +/* change the parent of all global objects to new_parent */ +static void subc_set_parent_globals(pcb_subc_t *sc, pcb_data_t *new_parent) +{ + pcb_data_set_parent_globals(sc->data, new_parent); +} + +void *pcb_subcop_move_buffer(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + int n; + pcb_board_t *dst_top = pcb_data_get_top(ctx->buffer.dst); + int dst_is_pcb = ((dst_top != NULL) && (dst_top->Data == ctx->buffer.dst)); + pcb_opctx_t clip; + + EraseSubc(sc); + + /* move the subc */ + if ((ctx->buffer.pcb != NULL) && (ctx->buffer.pcb->Data->subc_tree != NULL)) { + if (!dst_is_pcb) { + /* restore all pins/pads at once, at the old location */ + clip.clip.restore = 1; clip.clip.clear = 0; + clip.clip.pcb = ctx->buffer.pcb; + pcb_subc_op(ctx->buffer.pcb->Data, sc, &ClipFunctions, &clip, PCB_SUBCOP_UNDO_SUBC); + } + rnd_r_delete_entry(ctx->buffer.pcb->Data->subc_tree, (rnd_box_t *)sc); + } + + pcb_subc_unreg(sc); + pcb_subc_reg(ctx->buffer.dst, sc); + + if (dst_is_pcb) { + if (ctx->buffer.dst->subc_tree == NULL) + ctx->buffer.dst->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(ctx->buffer.dst->subc_tree, (rnd_box_t *)sc); + } + + if (dst_is_pcb) + PCB_SET_PARENT(sc, data, ctx->buffer.dst); /* have to set sc parent before relocate globals so that poly clearings will work */ + + /* move layer local */ + for(n = 0; n < sc->data->LayerN; n++) { + pcb_layer_t *sl = sc->data->Layer + n; + pcb_layer_t *dl; + int src_has_real_layer = (sl->meta.bound.real != NULL); + + if (dst_is_pcb) { + dl = pcb_layer_resolve_binding(dst_top, sl); + if (dl != NULL) { + pcb_layer_link_trees(sl, dl); + } + else { + /* need to create the trees so that move and other ops work */ + if (sl->line_tree == NULL) sl->line_tree = rnd_r_create_tree(); + if (sl->arc_tree == NULL) sl->arc_tree = rnd_r_create_tree(); + if (sl->text_tree == NULL) sl->text_tree = rnd_r_create_tree(); + if (sl->polygon_tree == NULL) sl->polygon_tree = rnd_r_create_tree(); + if (sl->gfx_tree == NULL) sl->gfx_tree = rnd_r_create_tree(); + if (!(sl->meta.bound.type & PCB_LYT_VIRTUAL)) + rnd_message(RND_MSG_ERROR, "Couldn't bind subc layer %s on buffer move\n", sl->name == NULL ? "" : sl->name); + } + } + else + dl = ctx->buffer.dst->Layer + n; + + if (dst_is_pcb) + subc_bind_layer(dl, sl, dst_is_pcb); + else + subc_relocate_layer_objs(dl, ctx->buffer.src, sl, src_has_real_layer, dst_is_pcb, 0); + } + + if (dst_is_pcb) { + subc_bind_globals(ctx->buffer.dst, sc, dst_is_pcb); + + /* clear all pins/pads at once, at the new location; this does a relocation of all objects recursively */ + clip.clip.restore = 0; clip.clip.clear = 1; + clip.clip.pcb = ctx->buffer.pcb; + pcb_subc_op(ctx->buffer.dst, sc, &ClipFunctions, &clip, PCB_SUBCOP_UNDO_SUBC); + } + else + subc_relocate_globals(ctx->buffer.dst, sc->data, sc, dst_is_pcb, 0); + + + PCB_FLAG_CLEAR(PCB_FLAG_WARN | PCB_FLAG_FOUND | PCB_FLAG_SELECTED, sc); + return sc; +} + +void *pcb_subcop_add_to_buffer(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + pcb_subc_t *nsc; + nsc = pcb_subc_dup_at(NULL, ctx->buffer.dst, sc, 0, 0, ctx->buffer.keep_id, rnd_true); + + if (ctx->buffer.extraflg & PCB_FLAG_SELECTED) { + pcb_undo_freeze_serial(); + pcb_undo_freeze_add(); + pcb_subc_select(NULL, nsc, PCB_CHGFLG_CLEAR, 0); + pcb_undo_unfreeze_add(); + pcb_undo_unfreeze_serial(); + } + + return nsc; +} + +/* break buffer subc into pieces */ +rnd_bool pcb_subc_smash_buffer(pcb_buffer_t *buff) +{ + pcb_subc_t *subc, *next; + int n, bn; + long warn = 0; + + for(subc = pcb_subclist_first(&buff->Data->subc); subc != NULL; subc = next) { + next = pcb_subclist_next(subc); + + for(n = 0; n < subc->data->LayerN; n++) { + pcb_layer_t *sl = subc->data->Layer + n, *brdl, *dl; + + if (strcmp(sl->name, SUBC_AUX_NAME) == 0) + continue; + + brdl = pcb_layer_resolve_binding(PCB, sl); + dl = NULL; + if (brdl != NULL) { + for(bn = 0; bn < buff->Data->LayerN; bn++) { + if (buff->Data->Layer[bn].meta.bound.real == brdl) { + dl = &buff->Data->Layer[bn]; + break; + } + } + } + + if (dl != NULL) + subc_relocate_layer_objs(dl, subc->data, sl, 1, 0, 1); + else + warn++; + } + subc_relocate_globals(buff->Data, buff->Data, subc, 0, 1); + pcb_subc_free(subc); + } + if (warn) + rnd_message(RND_MSG_WARNING, "There are %ld layers that got lost in the smash because they were on unbound subc layers\nThis normally happens if your subcircuits in buffer refer to layers that do not exist on your board.\n", warn); + return rnd_true; +} + +int pcb_subc_rebind(pcb_board_t *pcb, pcb_subc_t *sc) +{ + int n, chgly = 0; + pcb_board_t *dst_top = pcb_data_get_top(sc->data); + int dst_is_pcb = ((dst_top != NULL) && (dst_top->Data == pcb->Data)); + + if (!dst_is_pcb) + return -1; + + EraseSubc(sc); + +/* relocate bindings */ + for(n = 0; n < sc->data->LayerN; n++) { + pcb_layer_t *sl = sc->data->Layer + n; + pcb_layer_t *dl = pcb_layer_resolve_binding(dst_top, sl); + int src_has_real_layer = (sl->meta.bound.real != NULL); + + if (dl != NULL) { + if (sl->meta.bound.real == dl) + continue; + + /* make sure all trees exist on the dest layer - if these are the first objects there we may need to create them */ + if (dl->line_tree == NULL) dl->line_tree = rnd_r_create_tree(); + if (dl->arc_tree == NULL) dl->arc_tree = rnd_r_create_tree(); + if (dl->text_tree == NULL) dl->text_tree = rnd_r_create_tree(); + if (dl->polygon_tree == NULL) dl->polygon_tree = rnd_r_create_tree(); + if (dl->gfx_tree == NULL) dl->gfx_tree = rnd_r_create_tree(); + } + + if (subc_relocate_layer_objs(dl, pcb->Data, sl, src_has_real_layer, 1, 0) > 0) + chgly++; + + if (dl != NULL) + pcb_layer_link_trees(sl, dl); + } + + return chgly; +} + +void pcb_subc_bind_globals(pcb_board_t *pcb, pcb_subc_t *subc) +{ + if (pcb->Data->padstack_tree == NULL) + pcb->Data->padstack_tree = rnd_r_create_tree(); + subc->data->padstack_tree = pcb->Data->padstack_tree; +TODO("subc: subc-in-subc: bind subc rtree") +} + +/*** undoable unbind ***/ +typedef struct { + pcb_board_t *pcb; + pcb_subc_t *sc; + rnd_layer_id_t lid; + int slot; /* layer index within the subc */ + unsigned int unbind:1; +} undo_subc_unbind_t; + +static int undo_subc_unbind_swap(void *udata) +{ + undo_subc_unbind_t *u = udata; + + if (u->unbind) + subc_relocate_layer_objs(NULL, u->pcb->Data, &u->sc->data->Layer[u->slot], 1, 0, 0); + else { + pcb_layer_t *ly = pcb_get_layer(u->pcb->Data, u->lid); + pcb_layer_link_trees(&u->sc->data->Layer[u->slot], ly); + subc_relocate_layer_objs(ly, u->pcb->Data, &u->sc->data->Layer[u->slot], 0, 1, 0); + } + u->unbind = !u->unbind; + + return 0; +} + +static void undo_subc_unbind_print(void *udata, char *dst, size_t dst_len) +{ + undo_subc_unbind_t *u = udata; + rnd_snprintf(dst, dst_len, "subc unbind layer: %s #%ld:%ld", u->unbind ? "unbind" : "rebind", u->sc->ID, u->slot); +} + +static const uundo_oper_t undo_subc_unbind = { + core_subc_cookie, + NULL, + undo_subc_unbind_swap, + undo_subc_unbind_swap, + undo_subc_unbind_print +}; + + +static void pcb_subc_unbind_(pcb_board_t *pcb, pcb_subc_t *sc, rnd_layer_id_t brdlid, int slot, int undoable) +{ + undo_subc_unbind_t utmp, *u = &utmp; + + if (undoable) + u = pcb_undo_alloc(pcb, &undo_subc_unbind, sizeof(undo_subc_unbind_t)); + + u->pcb = pcb; + u->sc = sc; + u->lid = brdlid; + u->slot = slot; + u->unbind = 1; + + undo_subc_unbind_swap(u); + if (undoable) + pcb_undo_inc_serial(); +} + +int pcb_subc_unbind(pcb_board_t *pcb, pcb_subc_t *sc, pcb_layer_t *brdly, int undoable) +{ + int n, res = 0; + + for(n = 0; n < sc->data->LayerN; n++) { + pcb_layer_t *sl = sc->data->Layer + n; + if (sl->meta.bound.real == brdly) { + pcb_subc_unbind_(pcb, sc, brdly - pcb->Data->Layer, n, undoable); + res++; + } + } + if (undoable && (res > 0)) + pcb_undo_inc_serial(); + return res; +} + +long pcb_subc_unbind_all(pcb_board_t *pcb, pcb_layer_t *brdly, int undoable) +{ + long res = 0; + pcb_subc_t *sc; + gdl_iterator_t it; + subclist_foreach(&pcb->Data->subc, &it, sc) { + int r = pcb_subc_unbind(pcb, sc, brdly, undoable); + if (r > 0) + res += r; + } + return res; +} + + +void *pcb_subcop_change_size(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + pcb_subc_op(ctx->chgsize.pcb->Data, sc, &ChangeSizeFunctions, ctx, PCB_SUBCOP_UNDO_BATCH); + return sc; +} + +void *pcb_subcop_change_clear_size(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + pcb_subc_op(ctx->chgsize.pcb->Data, sc, &ChangeClearSizeFunctions, ctx, PCB_SUBCOP_UNDO_BATCH); + return sc; +} + +void *pcb_subcop_change_1st_size(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + pcb_subc_op(ctx->chgsize.pcb->Data, sc, &Change1stSizeFunctions, ctx, PCB_SUBCOP_UNDO_BATCH); + return sc; +} + +void *pcb_subcop_change_2nd_size(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + pcb_subc_op(ctx->chgsize.pcb->Data, sc, &Change2ndSizeFunctions, ctx, PCB_SUBCOP_UNDO_BATCH); + return sc; +} + +void *pcb_subcop_change_nonetlist(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + pcb_undo_add_obj_to_flag(sc); + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, sc)) + return NULL; + PCB_FLAG_TOGGLE(PCB_FLAG_NONETLIST, sc); + + return sc; +} + +void *pcb_subcop_change_name(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + void *old; + if (sc->refdes != NULL) + old = rnd_strdup(sc->refdes); /* strdup because the pcb_attribute_put() is going to free the original */ + else + old = NULL; + pcb_attribute_put(&sc->Attributes, "refdes", ctx->chgname.new_name); + return old; +} + +void *pcb_subcop_destroy(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + if (ctx->remove.pcb->Data->subc_tree != NULL) + rnd_r_delete_entry(ctx->remove.pcb->Data->subc_tree, (rnd_box_t *)sc); + + EraseSubc(sc); + pcb_subc_free(sc); + return NULL; +} + +void *pcb_subcop_remove(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + EraseSubc(sc); + pcb_undo_move_obj_to_remove(PCB_OBJ_SUBC, sc, sc, sc); + return NULL; +} + +void *pcb_subc_remove(pcb_subc_t *sc) +{ + void *res; + pcb_opctx_t ctx; + + ctx.remove.pcb = PCB; + ctx.remove.destroy_target = NULL; +/* PCB_CLEAR_PARENT(subc);*/ + + res = pcb_subcop_remove(&ctx, sc); + pcb_draw(); + return res; +} + +void *pcb_subcop_change_flag(pcb_opctx_t *ctx, pcb_subc_t *sc) +{ + static pcb_flag_values_t pcb_subc_flags = 0; + if (pcb_subc_flags == 0) + pcb_subc_flags = pcb_obj_valid_flags(PCB_OBJ_SUBC); + + if (ctx->chgflag.flag == PCB_FLAG_FLOATER) { +TODO("subc: subc-in-subc: can a whole subc be a floater? - add undo!") + PCB_FLAG_CHANGE(ctx->chgflag.how, ctx->chgflag.flag, sc); + return sc; + } + + pcb_subc_op(ctx->chgflag.pcb->Data, sc, &ChgFlagFunctions, ctx, PCB_SUBCOP_UNDO_NORMAL); + if ((ctx->chgflag.flag & pcb_subc_flags) == ctx->chgflag.flag) { + pcb_undo_add_obj_to_flag(sc); + PCB_FLAG_CHANGE(ctx->chgflag.how, ctx->chgflag.flag, sc); + } + return sc; +} + + +void pcb_subc_select(pcb_board_t *pcb, pcb_subc_t *sc, pcb_change_flag_t how, int redraw) +{ + pcb_opctx_t ctx; + + pcb_undo_add_obj_to_flag(sc); + + ctx.chgflag.pcb = pcb; + ctx.chgflag.how = how; + ctx.chgflag.flag = PCB_FLAG_SELECTED; + + pcb_subc_op((pcb == NULL ? NULL : pcb->Data), sc, &ChgFlagFunctions, &ctx, PCB_SUBCOP_UNDO_NORMAL); + PCB_FLAG_CHANGE(how, PCB_FLAG_SELECTED, sc); + if (redraw) + DrawSubc(sc); +} + +/*** undoable mirror ***/ + +typedef struct { + pcb_subc_t *subc; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + rnd_coord_t y_offs; + rnd_bool smirror; +} undo_subc_mirror_t; + +static int undo_subc_mirror_swap(void *udata) +{ + undo_subc_mirror_t *g = udata; + pcb_data_t *data = g->subc->parent.data; + + if ((data != NULL) && (data->subc_tree != NULL)) + rnd_r_delete_entry(data->subc_tree, (rnd_box_t *)g->subc); + + pcb_undo_freeze_add(); + pcb_data_mirror(g->subc->data, g->y_offs, g->smirror ? PCB_TXM_SIDE : PCB_TXM_COORD, g->smirror, 0); + pcb_undo_unfreeze_add(); + pcb_subc_bbox(g->subc); + + if ((data != NULL) && (data->subc_tree != NULL)) + rnd_r_insert_entry(data->subc_tree, (rnd_box_t *)g->subc); + + return 0; +} + +static void undo_subc_mirror_print(void *udata, char *dst, size_t dst_len) +{ + undo_subc_mirror_t *g = udata; + rnd_snprintf(dst, dst_len, "subc mirror y_offs=%$mm smirror=%d", g->y_offs, g->smirror); +} + +static const uundo_oper_t undo_subc_mirror = { + core_subc_cookie, + NULL, + undo_subc_mirror_swap, + undo_subc_mirror_swap, + undo_subc_mirror_print +}; + + +/* mirrors the coordinates of a subcircuit; an additional offset is passed */ +void pcb_subc_mirror(pcb_data_t *data, pcb_subc_t *subc, rnd_coord_t y_offs, rnd_bool smirror, rnd_bool undoable) +{ + undo_subc_mirror_t gtmp, *g = >mp; + + if (undoable) g = pcb_undo_alloc(pcb_data_get_top(subc->parent.data), &undo_subc_mirror, sizeof(undo_subc_mirror_t)); + + g->subc = subc; + g->y_offs = y_offs; + g->smirror = smirror; + + undo_subc_mirror_swap(g); + if (undoable) pcb_undo_inc_serial(); +} + +void pcb_subc_scale(pcb_data_t *data, pcb_subc_t *subc, double sx, double sy, double sth, int recurse) +{ + if ((data != NULL) && (data->subc_tree != NULL)) + rnd_r_delete_entry(data->subc_tree, (rnd_box_t *)subc); + + pcb_data_scale(subc->data, sx, sy, sth, recurse); + pcb_subc_bbox(subc); + + if ((data != NULL) && (data->subc_tree != NULL)) + rnd_r_insert_entry(data->subc_tree, (rnd_box_t *)subc); +} + + +rnd_bool pcb_subc_change_side(pcb_subc_t *subc, rnd_coord_t yoff) +{ + int n; + pcb_board_t *pcb; + pcb_data_t *data; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, subc)) + return rnd_false; + + pcb_data_clip_inhibit_inc(PCB->Data); + + assert(subc->parent_type = PCB_PARENT_DATA); + data = subc->parent.data; + pcb = pcb_data_get_top(data); + + /* mirror object geometry and stackup */ + + if ((data != NULL) && (data->subc_tree != NULL)) + rnd_r_delete_entry(data->subc_tree, (rnd_box_t *)subc); + + pcb_undo_freeze_add(); + pcb_data_mirror(subc->data, yoff, PCB_TXM_SIDE, 1, 0); + pcb_undo_unfreeze_add(); + + for(n = 0; n < subc->data->LayerN; n++) { + pcb_layer_t *ly = subc->data->Layer + n; + ly->meta.bound.type = pcb_layer_mirror_type(ly->meta.bound.type); + ly->meta.bound.stack_offs = -ly->meta.bound.stack_offs; + } + pcb_subc_rebind(pcb, subc); + + pcb_subc_bbox(subc); + + if ((data != NULL) && (data->subc_tree != NULL)) + rnd_r_insert_entry(data->subc_tree, (rnd_box_t *)subc); + + pcb_undo_add_subc_to_otherside(PCB_OBJ_SUBC, subc, subc, subc, yoff); + + pcb_data_clip_inhibit_dec(PCB->Data, 0); + + return rnd_true; +} + + + /* in per-side mode, do not show subc mark if it is on the other side */ +#define draw_subc_per_layer() \ +do { \ + int per_side = 0; \ + if (cl != NULL) \ + per_side = *(int *)cl; \ + if (per_side) { \ + int on_bottom; \ + if (pcb_subc_get_side(subc, &on_bottom) == 0) { \ + if ((!!on_bottom) != (!!conf_core.editor.show_solder_side)) \ + return RND_R_DIR_FOUND_CONTINUE; \ + } \ + } \ +} while(0) + + +#include "conf_core.h" +#include "draw.h" + + +rnd_r_dir_t pcb_draw_subc_mark(const rnd_box_t *b, void *cl) +{ + pcb_draw_info_t *info = cl; + pcb_subc_t *subc = (pcb_subc_t *) b; + rnd_box_t *bb = &subc->BoundingBox; + int selected, locked; + int freq = conf_core.appearance.subc.dash_freq; + const rnd_color_t *nnclr; + + selected = PCB_FLAG_TEST(PCB_FLAG_SELECTED, subc); + locked = PCB_FLAG_TEST(PCB_FLAG_LOCK, subc); + + draw_subc_per_layer(); + + if (freq > 32) + freq = 32; + + nnclr = (PCB_FLAG_TEST(PCB_FLAG_NONETLIST, subc)) ? &conf_core.appearance.color.subc_nonetlist : &conf_core.appearance.color.subc; + rnd_render->set_color(pcb_draw_out.fgGC, selected ? &conf_core.appearance.color.selected : nnclr); + rnd_hid_set_line_width(pcb_draw_out.fgGC, 0); + pcb_subc_draw_origin(pcb_draw_out.fgGC, subc, 0, 0); + + if (locked) { + int on_bottom = 0; + pcb_subc_get_side(subc, &on_bottom); + if (rnd_conf.editor.view.flip_x) + on_bottom = !on_bottom; + pcb_subc_draw_locked(pcb_draw_out.fgGC, subc, rnd_conf.editor.view.flip_x ? bb->X1 : bb->X2, on_bottom ? bb->Y1 : bb->Y2, on_bottom); + } + + if (freq >= 0) { + pcb_draw_dashed_line(info, pcb_draw_out.fgGC, bb->X1, bb->Y1, bb->X2, bb->Y1, freq, rnd_true); + pcb_draw_dashed_line(info, pcb_draw_out.fgGC, bb->X1, bb->Y1, bb->X1, bb->Y2, freq, rnd_true); + pcb_draw_dashed_line(info, pcb_draw_out.fgGC, bb->X2, bb->Y2, bb->X2, bb->Y1, freq, rnd_true); + pcb_draw_dashed_line(info, pcb_draw_out.fgGC, bb->X2, bb->Y2, bb->X1, bb->Y2, freq, rnd_true); + } + + return RND_R_DIR_FOUND_CONTINUE; +} + +rnd_r_dir_t draw_subc_mark_callback(const rnd_box_t *b, void *cl) +{ + pcb_draw_info_t *info = cl; + pcb_subc_t *subc = (pcb_subc_t *) b; + pcb_extobj_t *extobj = pcb_extobj_get(subc); + + if ((extobj != NULL) && (extobj->draw_mark != NULL)) { + extobj->draw_mark(info, subc); + return RND_R_DIR_FOUND_CONTINUE; + } + + return pcb_draw_subc_mark(b, cl); +} + +rnd_r_dir_t draw_subc_label_callback(const rnd_box_t *b, void *cl) +{ + pcb_draw_info_t *info = cl; + pcb_subc_t *subc = (pcb_subc_t *) b; + rnd_box_t *bb = &subc->BoundingBox; + rnd_coord_t x0, y0, dx, dy; + pcb_font_t *font = &PCB->fontkit.dflt; + + /* do not display anyting from the other-side subcs */ + draw_subc_per_layer(); + + /* calculate where the label ends up - always top-right, even if board is flipped */ + dx = font->MaxWidth/2; + dy = font->MaxHeight/2; + + if (rnd_conf.editor.view.flip_x) { + x0 = bb->X2; + dx = -dx; + } + else + x0 = bb->X1; + + if (rnd_conf.editor.view.flip_y) { + y0 = bb->Y2; + dy = -dy; + } + else + y0 = bb->Y1; + + /* draw the label from template; if template is not available, draw the refdes */ + if ((conf_core.editor.subc_id != NULL) && (*conf_core.editor.subc_id != '\0')) { + static gds_t s; + + s.used = 0; + if (pcb_append_dyntext(&s, (pcb_any_obj_t *)subc, conf_core.editor.subc_id) == 0) { + char *curr, *next; + rnd_coord_t x = x0, y = y0; + + for(curr = s.array; curr != NULL; curr = next) { + int ctrl = 0; + next = strchr(curr, '\\'); + if (next != NULL) { + *next = '\0'; + next++; + ctrl = 1; + } + pcb_label_draw(info, x, y, conf_core.appearance.term_label_size/2, 0, 0, curr, 0); + if (ctrl) { + switch(*next) { + case 'n': y += dy; x = x0; break; + } + next++; + } + } + } + else + pcb_label_draw(info, x0, y0, conf_core.appearance.term_label_size/2.0, 0, 0, "", 0); + } + else if (subc->refdes != NULL) + pcb_label_draw(info, x0, y0, conf_core.appearance.term_label_size/2.0, 0, 0, subc->refdes, 0); + + return RND_R_DIR_FOUND_CONTINUE; +} + +void pcb_subc_draw_preview(const pcb_subc_t *sc, const rnd_box_t *drawn_area) +{ + int n; + pcb_draw_info_t info; + rnd_rtree_it_t it; + pcb_any_obj_t *o; + rnd_xform_t xf = {0}; + pcb_draw_setup_default_gui_xform(&xf); + + /* draw copper only first - order doesn't matter */ + for(n = 0; n < sc->data->LayerN; n++) { + pcb_layer_t *layer = &sc->data->Layer[n]; + if (layer->meta.bound.type & PCB_LYT_COPPER) + pcb_draw_layer_under(PCB, layer, drawn_area, sc->data, &xf); + } + + /* draw padstacks */ + info.pcb = PCB; + info.drawn_area = drawn_area; + info.xform_caller = info.xform_exporter = info.xform = &xf; + info.layer = NULL; + info.objcb.pstk.gid = -1; + info.objcb.pstk.is_current = 1; + info.objcb.pstk.comb = 0; + info.objcb.pstk.shape_mask = PCB_LYT_COPPER | PCB_LYT_TOP; + info.objcb.pstk.holetype = PCB_PHOLE_UNPLATED | PCB_PHOLE_PLATED; + + if (sc->data->padstack_tree != NULL) + for(o = rnd_rtree_first(&it, sc->data->padstack_tree, (rnd_rtree_box_t *)drawn_area); o != NULL; o = rnd_rtree_next(&it)) { + if (pcb_obj_is_under(o, sc->data)) { + pcb_pstk_draw_callback((rnd_box_t *)o, &info); + if (PCB->hole_on) + pcb_pstk_draw_hole_callback((rnd_box_t *)o, &info); + } + } + + /* draw silk and mech and doc layers, above padstacks */ + for(n = 0; n < sc->data->LayerN; n++) { + pcb_layer_t *layer = &sc->data->Layer[n]; + if (layer->meta.bound.type & (PCB_LYT_SILK | PCB_LYT_BOUNDARY | PCB_LYT_MECH | PCB_LYT_DOC)) + pcb_draw_layer_under(PCB, layer, drawn_area, sc->data, &xf); + } + + /* padstack mark goes on top */ + if (sc->data->padstack_tree != NULL) + for(o = rnd_rtree_first(&it, sc->data->padstack_tree, (rnd_rtree_box_t *)drawn_area); o != NULL; o = rnd_rtree_next(&it)) { + if (pcb_obj_is_under(o, sc->data)) { + pcb_pstk_draw_mark_callback((rnd_box_t *)o, &info); + pcb_pstk_draw_label_callback((rnd_box_t *)o, &info); + } + } +} + + +pcb_subc_t *pcb_subc_by_refdes(pcb_data_t *base, const char *name) +{ +TODO("subc: subc-in-subc hierarchy") + PCB_SUBC_LOOP(base); + { + if ((subc->refdes != NULL) && (RND_NSTRCMP(subc->refdes, name) == 0)) + return subc; + } + PCB_END_LOOP; + return NULL; +} + +pcb_subc_t *pcb_subc_by_id(pcb_data_t *base, long int ID) +{ + /* We can not have an rtree based search here: we are often called + in the middle of an operation, after the subc got already removed + from the rtree. It happens in e.g. undoable padstack operations + where the padstack tries to look up its parent subc by ID, while + the subc is being rotated. + + The solution will be the ID hash. */ +TODO("subc: subc-in-subc hierarchy") + PCB_SUBC_LOOP(base); + { + if (subc->ID == ID) + return subc; + } + PCB_END_LOOP; + return NULL; +} + +rnd_bool pcb_subc_is_empty(pcb_subc_t *subc) +{ + return pcb_data_is_empty(subc->data); +} + +pcb_layer_t *pcb_subc_get_layer(pcb_subc_t *sc, pcb_layer_type_t lyt, pcb_layer_combining_t comb, rnd_bool_t alloc, const char *name, rnd_bool req_name_match) +{ + int n; + + /* look for an existing layer with matching lyt and comb first */ + for(n = 0; n < sc->data->LayerN; n++) { + if (sc->data->Layer[n].meta.bound.type != lyt) + continue; + if ((comb != -1) && (sc->data->Layer[n].comb != comb)) + continue; + if (req_name_match && (strcmp(sc->data->Layer[n].name, name) != 0)) + continue; + return &sc->data->Layer[n]; + } + + if (!alloc) + return NULL; + + if (sc->data->LayerN == PCB_MAX_LAYER) + return NULL; + + n = sc->data->LayerN++; + if (name == NULL) + name = ""; + + if (comb == -1) { + /* "any" means default, for the given layer type */ + if (lyt & PCB_LYT_MASK) + comb = PCB_LYC_SUB; + else + comb = 0; /* positive, manual */ + } + + memset(&sc->data->Layer[n], 0, sizeof(sc->data->Layer[n])); + sc->data->Layer[n].name = rnd_strdup(name); + sc->data->Layer[n].comb = comb; + sc->data->Layer[n].is_bound = 1; + sc->data->Layer[n].meta.bound.type = lyt; + sc->data->Layer[n].parent.data = sc->data; + sc->data->Layer[n].parent_type = PCB_PARENT_DATA; + sc->data->Layer[n].type = PCB_OBJ_LAYER; + return &sc->data->Layer[n]; +} + +RND_INLINE void pcb_subc_part_changed__(pcb_subc_t *sc, int force) +{ + /* can't do this incrementally: if a boundary object is smaller than before + it has to make the subc bbox smaller too */ + if (force || sc->part_changed_bbox_dirty) { + pcb_subc_bbox(sc); + sc->part_changed_bbox_dirty = 0; + } +} + + +void pcb_subc_part_changed_(pcb_any_obj_t *obj) +{ + pcb_subc_t *sc = pcb_obj_parent_subc(obj); + if (sc == NULL) + return; + if (sc->part_changed_inhibit) + sc->part_changed_bbox_dirty = 1; + else + pcb_subc_part_changed__(sc, 1); +} + +void pcb_subc_part_changed_inhibit_inc(pcb_subc_t *sc) +{ + sc->part_changed_inhibit++; +} + +void pcb_subc_part_changed_inhibit_dec(pcb_subc_t *sc) +{ + if (sc->part_changed_inhibit > 0) { + sc->part_changed_inhibit--; + if (sc->part_changed_inhibit == 0) + pcb_subc_part_changed__(sc, 0); + } + else + rnd_message(RND_MSG_ERROR, "Internal error: pcb_subc_part_changed_inhibit_dec(): underflow; please reprot this bug\n"); +} + + +const char *pcb_subc_name(pcb_subc_t *subc, const char *local_name) +{ + const char *val; + + if (local_name != NULL) { + val = pcb_attribute_get(&subc->Attributes, local_name); + if (val != NULL) + return val; + } + val = pcb_attribute_get(&subc->Attributes, "visible_footprint"); + if (val != NULL) + return val; + val = pcb_attribute_get(&subc->Attributes, "footprint"); + return val; +} + +/*** subc replace: in-place replacement of a subcircuit with another, trying to keep as much local changes as possible ***/ + +typedef struct pcb_sucbrepl_floater_s pcb_sucbrepl_floater_t; + +struct pcb_sucbrepl_floater_s { /* digest of a floater for matching up */ + /* desired state */ + rnd_coord_t x, y; + double rot; + + /* admiin */ + pcb_sucbrepl_floater_t *next; + + /* matching */ + pcb_objtype_t type; + rnd_layer_id_t lid; + char str[1]; /* dynamic length */ +}; + +typedef struct { + pcb_board_t *pcb; + htsp_t thermal; /* value is (char *) thermal shapes; it's as long as many layers pcb currently has */ + pcb_sucbrepl_floater_t *flt; +} pcb_subc_replace_t; + +static void pcb_subcrepl_map_floater(pcb_subc_replace_t *repl, const pcb_subc_t *src, pcb_any_obj_t *o) +{ + pcb_sucbrepl_floater_t *f; + pcb_text_t *txt = (pcb_text_t *)o; + + if ((txt->type == PCB_OBJ_TEXT) && (txt->TextString != NULL) && (*txt->TextString != '\0')) { + long len = strlen(txt->TextString); + f = malloc(sizeof(pcb_sucbrepl_floater_t) + len + 1); + strcpy(f->str, txt->TextString); + } + else { + f = malloc(sizeof(pcb_sucbrepl_floater_t)); + f->str[0] = '\0'; + } + + f->type = o->type; + if (PCB_OBJ_CLASS_LAYER & o->type) + f->lid = pcb_layer2id(repl->pcb->Data, pcb_layer_get_real(o->parent.layer)); + else + f->lid = -1; + + switch(o->type) { + case PCB_OBJ_ARC: + f->x = ((pcb_arc_t *)o)->X; + f->y = ((pcb_arc_t *)o)->Y; + break; + case PCB_OBJ_LINE: + f->x = ((pcb_line_t *)o)->Point1.X; + f->y = ((pcb_line_t *)o)->Point1.Y; + break; + case PCB_OBJ_TEXT: + f->x = ((pcb_text_t *)o)->X; + f->y = ((pcb_text_t *)o)->Y; + f->rot = ((pcb_text_t *)o)->rot; + break; + case PCB_OBJ_PSTK: + f->x = ((pcb_pstk_t *)o)->x; + f->y = ((pcb_pstk_t *)o)->y; + f->rot = ((pcb_pstk_t *)o)->rot; + break; + case PCB_OBJ_GFX: + f->x = ((pcb_gfx_t *)o)->cx; + f->y = ((pcb_gfx_t *)o)->cy; + f->rot = ((pcb_gfx_t *)o)->rot; + break; + + case PCB_OBJ_SUBC: /* may matter in subc-in-subc, for subc terminals */ + case PCB_OBJ_POLY: /* no idea which point to use */ + case PCB_OBJ_RAT: + case PCB_OBJ_NET: + case PCB_OBJ_NET_TERM: + case PCB_OBJ_LAYER: + case PCB_OBJ_LAYERGRP: + case PCB_OBJ_VOID: + break; + } + f->next = repl->flt; + repl->flt = f; +} + +static void pcb_subcrepl_apply_floater(pcb_subc_replace_t *repl, const pcb_subc_t *src, pcb_any_obj_t *o) +{ + pcb_sucbrepl_floater_t *n; + rnd_layer_id_t lid; + + for(n = repl->flt; n != NULL; n = n->next) { + if (n->type != o->type) continue; + + if (PCB_OBJ_CLASS_LAYER & o->type) + lid = pcb_layer2id(repl->pcb->Data, pcb_layer_get_real(o->parent.layer)); + else + lid = -1; + if (n->lid != lid) continue; + + if (o->type == PCB_OBJ_TEXT) { + const char *s = ((pcb_text_t *)o)->TextString; + if (s == NULL) s = ""; + if (strcmp(n->str, s) != 0) continue; + } + + /* match! */ + switch(o->type) { + case PCB_OBJ_ARC: + pcb_move_obj(o->type, o->parent.any, o, o, n->x - ((pcb_arc_t *)o)->X, n->y - ((pcb_arc_t *)o)->Y); + break; + case PCB_OBJ_LINE: + pcb_move_obj(o->type, o->parent.any, o, o, n->x - ((pcb_line_t *)o)->Point1.X, n->y - ((pcb_line_t *)o)->Point1.Y); + break; + case PCB_OBJ_TEXT: + pcb_move_obj(o->type, o->parent.any, o, o, n->x - ((pcb_text_t *)o)->X, n->y - ((pcb_text_t *)o)->Y); + if (n->rot != ((pcb_text_t *)o)->rot) { + double ang = n->rot - ((pcb_text_t *)o)->rot; + pcb_text_rotate((pcb_text_t *)o, ((pcb_text_t *)o)->X, ((pcb_text_t *)o)->Y, cos(ang), sin(ang), ang); + } + break; + case PCB_OBJ_PSTK: + pcb_move_obj(o->type, o->parent.any, o, o, n->x - ((pcb_pstk_t *)o)->x, n->y - ((pcb_pstk_t *)o)->y); + if (n->rot != ((pcb_pstk_t *)o)->rot) { + double ang = n->rot - ((pcb_text_t *)o)->rot; + pcb_pstk_rotate((pcb_pstk_t *)o, ((pcb_pstk_t *)o)->x, ((pcb_pstk_t *)o)->y, cos(ang), sin(ang), ang); + } + break; + case PCB_OBJ_GFX: + pcb_gfx_chg_geo((pcb_gfx_t *)o, n->x, n->y, ((pcb_gfx_t *)o)->sx, ((pcb_gfx_t *)o)->sy, n->rot, 0); + break; + + case PCB_OBJ_SUBC: /* may matter in subc-in-subc, for subc terminals */ + case PCB_OBJ_POLY: /* no idea which point to use */ + case PCB_OBJ_RAT: + case PCB_OBJ_NET: + case PCB_OBJ_NET_TERM: + case PCB_OBJ_LAYER: + case PCB_OBJ_LAYERGRP: + case PCB_OBJ_VOID: + break; + } + + n->type = PCB_OBJ_VOID; /* use each input floater only once */ + } +} + +static void pcb_subcrepl_free_floaters(pcb_subc_replace_t *repl) +{ + pcb_sucbrepl_floater_t *n, *next; + for(n = repl->flt; n != NULL; n = next) { + next = n->next; + free(n); + } +} + + +/* map thermals and floaters of src to repl */ +static void pcb_subcrepl_map_thermals_floaters(pcb_subc_replace_t *repl, const pcb_subc_t *src) +{ + pcb_any_obj_t *o; + pcb_data_it_t it; + char *s; + + htsp_init(&repl->thermal, strhash, strkeyeq); + + for(o = pcb_data_first(&it, src->data, PCB_OBJ_CLASS_LAYER); o != NULL; o = pcb_data_next(&it)) { + rnd_layer_id_t lid; + + if (PCB_FLAG_TEST(PCB_FLAG_FLOATER, o)) + pcb_subcrepl_map_floater(repl, src, o); + + if ((o->term == NULL) || (o->thermal == 0)) continue; + s = htsp_get(&repl->thermal, o->term); + if (s != NULL) continue; /* save the "first" only */ + + lid = pcb_layer2id(repl->pcb->Data, pcb_layer_get_real(o->parent.layer)); + if (lid == -1) continue; + + s = calloc(repl->pcb->Data->LayerN, 1); + s[lid] = o->thermal; + htsp_set(&repl->thermal, rnd_strdup(o->term), s); + } + + for(o = pcb_data_first(&it, src->data, PCB_OBJ_PSTK); o != NULL; o = pcb_data_next(&it)) { + pcb_pstk_t *ps = (pcb_pstk_t *)o; + + if (PCB_FLAG_TEST(PCB_FLAG_FLOATER, o)) + pcb_subcrepl_map_floater(repl, src, o); + + if ((o->term == NULL) || (ps->thermals.used == 0)) continue; + s = htsp_get(&repl->thermal, o->term); + if (s != NULL) continue; /* save the "first" only */ + + s = calloc(repl->pcb->Data->LayerN, 1); + memcpy(s, ps->thermals.shape, ps->thermals.used); + htsp_set(&repl->thermal, rnd_strdup(o->term), s); + } +} + +/* Set thermals on the new subc terminals from repl; return 1 if there was any + thermal set (and thus polygons need to be updated); also move/rotate floaters + trying to match the original placement */ +static int pcb_subcrepl_apply_thermals_floaters(pcb_subc_replace_t *repl, pcb_subc_t *placed) +{ + pcb_any_obj_t *o; + pcb_data_it_t it; + htsp_entry_t *e; + int has_thermal = 0; + + for(o = pcb_data_first(&it, placed->data, PCB_OBJ_CLASS_LAYER); o != NULL; o = pcb_data_next(&it)) { + rnd_layer_id_t lid; + char *s; + + if (PCB_FLAG_TEST(PCB_FLAG_FLOATER, o)) + pcb_subcrepl_apply_floater(repl, placed, o); + + if ((o->term == NULL) || (o->thermal == 0)) continue; + e = htsp_popentry(&repl->thermal, o->term); + if (e == NULL) continue; /* save the "first" only */ + + lid = pcb_layer2id(repl->pcb->Data, pcb_layer_get_real(o->parent.layer)); + if (lid == -1) continue; + + s = e->value; + o->thermal = s[lid]; + free(e->key); + free(e->value); + has_thermal = 1; + } + + for(o = pcb_data_first(&it, placed->data, PCB_OBJ_PSTK); o != NULL; o = pcb_data_next(&it)) { + pcb_pstk_t *ps = (pcb_pstk_t *)o; + + if (PCB_FLAG_TEST(PCB_FLAG_FLOATER, o)) + pcb_subcrepl_apply_floater(repl, placed, o); + + if ((o->term == NULL) || (ps->thermals.used == 0)) continue; + e = htsp_popentry(&repl->thermal, o->term); + if (e == NULL) continue; /* save the "first" only */ + ps->thermals.used = repl->pcb->Data->LayerN; + ps->thermals.shape = e->value; + + free(e->key); + has_thermal = 1; + } + + genht_uninit_deep(htsp, &repl->thermal, { + free(htent->key); + free(htent->value); + }); + pcb_subcrepl_free_floaters(repl); + return has_thermal; +} + +pcb_subc_t *pcb_subc_replace(pcb_board_t *pcb, pcb_subc_t *dst, pcb_subc_t *src, rnd_bool add_undo, rnd_bool dumb) +{ + pcb_data_t *data = dst->parent.data; + pcb_subc_t *placed; + rnd_coord_t ox, oy, osx, osy; + double rot = 0; + long int target_id; + int dst_on_bottom = 0, src_on_bottom = 0; + static const pcb_flag_values_t fmask = PCB_FLAG_SELECTED | \ + PCB_FLAG_ONSOLDER | PCB_FLAG_AUTO | PCB_FLAG_NONETLIST; + pcb_flag_values_t flags; + pcb_subc_replace_t repl = {0}; + + assert(dst->parent_type == PCB_PARENT_DATA); + assert(src != NULL); + + if (dumb) { + ox = pcb_crosshair.X; + oy = pcb_crosshair.Y; + } + else { + if (pcb_subc_get_origin(dst, &ox, &oy) != 0) { + ox = (dst->BoundingBox.X1 + dst->BoundingBox.X2) / 2; + oy = (dst->BoundingBox.Y1 + dst->BoundingBox.Y2) / 2; + } + pcb_subc_get_rotation(dst, &rot); + pcb_subc_get_side(dst, &dst_on_bottom); + } + + repl.pcb = pcb; + pcb_subcrepl_map_thermals_floaters(&repl, dst); + + if (pcb_subc_get_origin(src, &osx, &osy) != 0) { + osx = (dst->BoundingBox.X1 + dst->BoundingBox.X2) / 2; + osy = (dst->BoundingBox.Y1 + dst->BoundingBox.Y2) / 2; + } + + + placed = pcb_subc_dup_at(pcb, data, src, ox - osx, oy - osy, 0, rnd_true); + pcb_subc_get_side(placed, &src_on_bottom); + + { /* copy attributes */ + int n; + pcb_attribute_list_t *adst = &placed->Attributes, *asrc = &dst->Attributes; + for (n = 0; n < asrc->Number; n++) + if (strcmp(asrc->List[n].name, "footprint") != 0) + pcb_attribute_put(adst, asrc->List[n].name, asrc->List[n].value); + } + + flags = dst->Flags.f & fmask; + + target_id = dst->ID; + pcb_subc_remove(dst); + + pcb_obj_id_del(data, placed); +/* NOTE: Can not keep ID because that would fool the undo system: double-replace + a subc and there will be two instances with the same ID on the undo list + and searching by ID will get fooled! TODO27 */ +/* placed->ID = target_id;*/ (void)target_id; + pcb_obj_id_reg(data, placed); + placed->Flags.f &= ~fmask; + placed->Flags.f |= flags; + + if (rot != 0) { + if (dst_on_bottom != src_on_bottom) + rot = -rot; + pcb_subc_rotate(placed, ox, oy, cos(rot / RND_RAD_TO_DEG), sin(rot / RND_RAD_TO_DEG), rot); + } + + if (dst_on_bottom != src_on_bottom) + pcb_subc_change_side(placed, 2 * oy - PCB->hidlib.size_y); + + if (pcb_subcrepl_apply_thermals_floaters(&repl, placed)) { + pcb_opctx_t clip; + clip.clip.pcb = pcb; + clip.clip.restore = 1; clip.clip.clear = 0; + pcb_subc_op(pcb->Data, placed, &ClipFunctions, &clip, PCB_SUBCOP_UNDO_NORMAL); + clip.clip.restore = 0; clip.clip.clear = 1; + pcb_subc_op(pcb->Data, placed, &ClipFunctions, &clip, PCB_SUBCOP_UNDO_NORMAL); + } + + pcb_undo_freeze_add(); + pcb_subc_select(pcb, placed, (flags & PCB_FLAG_SELECTED) ? PCB_CHGFLG_SET : PCB_CHGFLG_CLEAR, 0); + pcb_undo_unfreeze_add(); + + if (add_undo) + pcb_undo_add_obj_to_create(PCB_OBJ_SUBC, placed, placed, placed); + + + return placed; +} Index: tags/2.3.0/src/obj_subc.h =================================================================== --- tags/2.3.0/src/obj_subc.h (nonexistent) +++ tags/2.3.0/src/obj_subc.h (revision 33253) @@ -0,0 +1,220 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017..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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_SUBC_H +#define PCB_OBJ_SUBC_H + +#include +#include +#include +#include "obj_common.h" +#include "layer.h" +#include +#include + + +typedef enum pcb_subc_cached_s { + PCB_SUBCH_ORIGIN, + PCB_SUBCH_X, + PCB_SUBCH_Y, + PCB_SUBCH_max +} pcb_subc_cached_t; + +struct pcb_subc_s { + PCB_ANY_PRIMITIVE_FIELDS; + const char *extobj; + int extobj_idx; + void *extobj_data; /* the extobj implementation may store decoded data here */ + minuid_bin_t uid; + pcb_data_t *data; + htsp_t terminals; + pcb_line_t *aux_cache[PCB_SUBCH_max]; + pcb_layer_t *aux_layer; + const char *refdes; /* cached from attributes for fast lookup */ + int part_changed_inhibit; + unsigned part_changed_bbox_dirty:1; /* part_changed_inhibit_dec() should recalculate the bbox */ + unsigned auto_termname_display:1; /* display bit, not saved or loaded, only toggled by Display() on subc */ + long int copied_from_ID; /* temporary storage during operation: if a subc is a copy of another subc in the same operation, keep the ID of the original subc to avoid duplicate copies */ + gdl_elem_t link; +}; + +pcb_subc_t *pcb_subc_alloc(void); +pcb_subc_t *pcb_subc_alloc_id(long int id); +pcb_subc_t *pcb_subc_new(void); +void pcb_subc_free(pcb_subc_t *sc); + +void pcb_subc_reg(pcb_data_t *data, pcb_subc_t *subc); +void pcb_subc_unreg(pcb_subc_t *subc); + + +void pcb_subc_select(pcb_board_t *pcb, pcb_subc_t *sc, pcb_change_flag_t how, int redraw); + +void pcb_subc_bbox(pcb_subc_t *sc); + +/* convert buffer contents into a subcircuit, in-place; returns 0 on success */ +int pcb_subc_convert_from_buffer(pcb_buffer_t *buffer); +rnd_bool pcb_subc_smash_buffer(pcb_buffer_t *buff); + +void pcb_subc_mirror(pcb_data_t *data, pcb_subc_t *subc, rnd_coord_t y_offs, rnd_bool smirror, rnd_bool undoable); + +/* Scale coords/pos of a subc by sx,sy with thickness factor sth; + if recurse is non-zero, descend in subc-in-subc */ +void pcb_subc_scale(pcb_data_t *data, pcb_subc_t *subc, double sx, double sy, double sth, int recurse); + +/* changes the side of the board a subc is on; returns rnd_true if done */ +rnd_bool pcb_subc_change_side(pcb_subc_t *subc, rnd_coord_t yoff); + +void pcb_subc_rotate(pcb_subc_t *subc, rnd_coord_t cx, rnd_coord_t cy, double cosa, double sina, double angle); +void pcb_subc_rotate90(pcb_subc_t *subc, rnd_coord_t cx, rnd_coord_t cy, int steps); + +/* High level move (op wrapper; no undo) */ +void pcb_subc_move(pcb_subc_t *sc, rnd_coord_t dx, rnd_coord_t dy, rnd_bool more_to_come); + +/* changes the side of all selected and visible subcs; returns rnd_true if anything has changed */ +rnd_bool pcb_selected_subc_change_side(void); + +/* Draw a subcircuit for a preview (silk, copper and outline only) */ +void pcb_subc_draw_preview(const pcb_subc_t *sc, const rnd_box_t *drawn_area); + +void pcb_xordraw_subc(pcb_subc_t *sc, rnd_coord_t DX, rnd_coord_t DY, int use_curr_side); + +/* Redo the layer binding after the layer binding recipe changed in sc */ +int pcb_subc_rebind(pcb_board_t *pcb, pcb_subc_t *sc); + +/* Do the initial global bindings of subc to pcb (rtree links) */ +void pcb_subc_bind_globals(pcb_board_t *pcb, pcb_subc_t *subc); + +/* Unbind board layer from subc; useful when layer is deleted; returns + the number of unbinds or -1 on error */ +int pcb_subc_unbind(pcb_board_t *pcb, pcb_subc_t *sc, pcb_layer_t *brdly, int undoable); +long pcb_subc_unbind_all(pcb_board_t *pcb, pcb_layer_t *brdly, int undoable); + + +/* Look up a layer by lyt and comb (and name, if req_name_match is true); + if not found and alloc is true, allocate a new layer with the given name. + Return NULL on error. */ +pcb_layer_t *pcb_subc_get_layer(pcb_subc_t *sc, pcb_layer_type_t lyt, pcb_layer_combining_t comb, rnd_bool_t alloc, const char *name, rnd_bool req_name_match); + +#include +rnd_r_dir_t pcb_draw_subc_mark(const rnd_box_t *b, void *cl); /* low level version, does not do extobj */ +rnd_r_dir_t draw_subc_mark_callback(const rnd_box_t *b, void *cl); +rnd_r_dir_t draw_subc_label_callback(const rnd_box_t *b, void *cl); +void DrawSubc(pcb_subc_t *sc); +void EraseSubc(pcb_subc_t *sc); + +/* calculate geometrical properties using the aux layer; return 0 on success */ +int pcb_subc_get_origin(pcb_subc_t *sc, rnd_coord_t *x, rnd_coord_t *y); +int pcb_subc_get_rotation(pcb_subc_t *sc, double *rot); /* in deg */ +int pcb_subc_get_side(pcb_subc_t *sc, int *on_bottom); + +/* get all the above transformatoins at once. If neg is 0, these are the + raw transofrmations ("what happened to the subc from neutral state"), + if neg is non-zero, these are the transformations back to neutral state. */ +int pcb_subc_get_host_trans(pcb_subc_t *sc, pcb_host_trans_t *tr, int neg); + +/* Move the origin, without moving the subcircuit itself */ +int pcb_subc_move_origin(pcb_subc_t *sc, rnd_coord_t dx, rnd_coord_t dy, rnd_bool and_undo); +int pcb_subc_move_origin_to(pcb_subc_t *sc, rnd_coord_t x, rnd_coord_t y, rnd_bool and_undo); + + +/* Search for the named subc; name is relative path in hierarchy. Returns + NULL if not found */ +pcb_subc_t *pcb_subc_by_refdes(pcb_data_t *base, const char *name); + +/* Search subc, "recursively", by ID */ +pcb_subc_t *pcb_subc_by_id(pcb_data_t *base, long int ID); + +/* undoable remove */ +void *pcb_subc_remove(pcb_subc_t *sc); + +/* In board mode return brd_layer; in footprint edit mode, return the subcircuit + layer that matches brd_layer. If not found, either allocate it within + the subc (if alloc is true) or return the brd_layer. */ +pcb_layer_t *pcb_loose_subc_layer(pcb_board_t *pcb, pcb_layer_t *brd_layer, rnd_bool alloc); + +/* Returns whether there's no object in the subc */ +rnd_bool pcb_subc_is_empty(pcb_subc_t *subc); + +/* Return the footprint name; if local_name is not NULL, that attribute + is queried first; if that doesn't exist, "visible_footprint" and then + "footprint" is returned (or NULL if nothing is found) */ +const char *pcb_subc_name(pcb_subc_t *subc, const char *local_name); + + +/* Update the subcircuit (e.g. bbox) after a part of the subcircuit has changed */ +void pcb_subc_part_changed_(pcb_any_obj_t *obj); +#define pcb_subc_part_changed(obj) pcb_subc_part_changed_((pcb_any_obj_t *)obj) +void pcb_subc_part_changed_inhibit_inc(pcb_subc_t *sc); +void pcb_subc_part_changed_inhibit_dec(pcb_subc_t *sc); + + +/*** Internal, low level ***/ +/* Copy layer objects from source layer sl to destination layer dl into dst_sc */ +void pcb_subc_dup_layer_objs(pcb_subc_t *dst_sc, pcb_layer_t *dl, pcb_layer_t *sl, rnd_coord_t dx, rnd_coord_t dy, rnd_bool keep_ids); + +/* Allocate and return a new layer in subc, copying binding and basic + properties from another subc layer (potentially from another subc) from sl */ +pcb_layer_t *pcb_subc_alloc_layer_like(pcb_subc_t *subc, const pcb_layer_t *sl); + +/*** subc creation helpers ***/ + +/* Create the aux layer for a subc, set origin to ox;oy and rotation to rot */ +void pcb_subc_create_aux(pcb_subc_t *sc, rnd_coord_t ox, rnd_coord_t oy, double rot, rnd_bool bottom); + +/* Create a new point on the aux layer using a given role string in attribute */ +void pcb_subc_create_aux_point(pcb_subc_t *sc, rnd_coord_t x, rnd_coord_t y, const char *role); + +/* Look up an aux point and return rnd_true if found; when found, load x and y + with the coords of the point. */ +rnd_bool pcb_subc_find_aux_point(pcb_subc_t *sc, const char *role, rnd_coord_t *x, rnd_coord_t *y); + +/* Find and save the aux layer in the cache, of it exists */ +void pcb_subc_cache_find_aux(pcb_subc_t *sc); + +/* Create (and append) a new bound layer to a subc */ +pcb_layer_t *pcb_subc_layer_create(pcb_subc_t *sc, const char *name, pcb_layer_type_t type, pcb_layer_combining_t comb, int stack_offs, const char *purpose); + + +/* Copy non-layer, non-geometrical metadata (e.g. attributes) */ +pcb_subc_t *pcb_subc_copy_meta(pcb_subc_t *dst, const pcb_subc_t *src); + +pcb_subc_t *pcb_subc_dup_at(pcb_board_t *pcb, pcb_data_t *dst, const pcb_subc_t *src, rnd_coord_t dx, rnd_coord_t dy, rnd_bool keep_ids, rnd_bool undoable); + +/* Replace dst with a copy of src in place (preserving location and orientation + and attributes. If add_undo is true, add the old subc del and the new subc + creation to the undo list. If dub is true, do not try to match rotation or + pick up coords, just use crosshair and current loc. */ +pcb_subc_t *pcb_subc_replace(pcb_board_t *pcb, pcb_subc_t *dst, pcb_subc_t *src, rnd_bool add_undo, rnd_bool dumb); + +/*** loops ***/ + +#define PCB_SUBC_LOOP(top) do { \ + pcb_subc_t *subc; \ + gdl_iterator_t __it__; \ + subclist_foreach(&(top)->subc, &__it__, subc) { + + +#endif Index: tags/2.3.0/src/obj_subc_hash.c =================================================================== --- tags/2.3.0/src/obj_subc_hash.c (nonexistent) +++ tags/2.3.0/src/obj_subc_hash.c (revision 33253) @@ -0,0 +1,166 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "data.h" +#include "layer.h" +#include "obj_subc.h" +#include "obj_arc.h" +#include "obj_line.h" +#include "obj_text.h" +#include "obj_poly.h" +#include "obj_pstk.h" + +int pcb_subc_hash_ignore_uid = 0; + +int pcb_subc_eq(pcb_subc_t *sc1, pcb_subc_t *sc2) +{ + pcb_host_trans_t tr1, tr2; + int lid; + gdl_iterator_t it; + + /* optimization: cheap tests first */ + if (!pcb_subc_hash_ignore_uid && memcmp(&sc1->uid, &sc2->uid, sizeof(sc1->uid)) != 0) return 0; + if (sc1->data->LayerN != sc2->data->LayerN) return 0; + if (padstacklist_length(&sc1->data->padstack) != padstacklist_length(&sc2->data->padstack)) return 0; + if (pcb_subclist_length(&sc1->data->subc) != pcb_subclist_length(&sc2->data->subc)) return 0; + + for(lid = 0; lid < sc1->data->LayerN; lid++) { + pcb_layer_t *ly1 = &sc1->data->Layer[lid]; + pcb_layer_t *ly2 = &sc2->data->Layer[lid]; +TODO("todo") +/* if (!pcb_layer_eq_bound(ly1, tr1.on_bottom, ly2, tr2.on_bottom)) return 0;*/ + if (arclist_length(&ly1->Arc) != arclist_length(&ly2->Arc)) return 0; + } + + pcb_subc_get_host_trans(sc1, &tr1, 1); + pcb_subc_get_host_trans(sc2, &tr2, 1); + + for(lid = 0; lid < sc1->data->LayerN; lid++) { + pcb_line_t *l1, *l2; + pcb_arc_t *a1, *a2; + pcb_text_t *t1, *t2; + pcb_poly_t *p1, *p2; + pcb_layer_t *ly1 = &sc1->data->Layer[lid]; + pcb_layer_t *ly2 = &sc2->data->Layer[lid]; + + + /* assume order of children objects are the same */ + a2 = arclist_first(&ly2->Arc); + arclist_foreach(&ly1->Arc, &it, a1) { + if (!pcb_arc_eq(&tr1, a1, &tr2, a2)) return 0; + a2 = arclist_next(a2); + } + + l2 = linelist_first(&ly2->Line); + linelist_foreach(&ly1->Line, &it, l1) { + if (!pcb_line_eq(&tr1, l1, &tr2, l2)) return 0; + l2 = linelist_next(l2); + } + + t2 = textlist_first(&ly2->Text); + textlist_foreach(&ly1->Text, &it, t1) { + if (!pcb_text_eq(&tr1, t1, &tr2, t2)) return 0; + t2 = textlist_next(t2); + } + + p2 = polylist_first(&ly2->Polygon); + polylist_foreach(&ly1->Polygon, &it, p1) { + if (!pcb_poly_eq(&tr1, p1, &tr2, p2)) return 0; + p2 = polylist_next(p2); + } + } + + /* compare global objects */ + { + pcb_pstk_t *p1, *p2; + + p2 = padstacklist_first(&sc2->data->padstack); + padstacklist_foreach(&sc1->data->padstack, &it, p1) { + if (!pcb_pstk_eq(&tr1, p1, &tr2, p2)) return 0; + p2 = padstacklist_next(p2); + } +TODO("subc: subc-in-subc eq check") + } + + return 1; +} + +unsigned int pcb_subc_hash(pcb_subc_t *sc) +{ + unsigned int hash; + int lid; + pcb_host_trans_t tr; + gdl_iterator_t it; + + pcb_subc_get_host_trans(sc, &tr, 1); + + hash = sc->data->LayerN; + + if (!pcb_subc_hash_ignore_uid) + hash ^= murmurhash(&sc->uid, sizeof(sc->uid)); + + /* hash layers and layer objects */ + + for(lid = 0; lid < sc->data->LayerN; lid++) { + pcb_layer_t *ly = &sc->data->Layer[lid]; + + pcb_line_t *l; + pcb_arc_t *a; + pcb_text_t *t; + pcb_poly_t *p; + + hash ^= pcb_layer_hash_bound(ly, tr.on_bottom); + + arclist_foreach(&ly->Arc, &it, a) + hash ^= pcb_arc_hash(&tr, a); + + linelist_foreach(&ly->Line, &it, l) + hash ^= pcb_line_hash(&tr, l); + + textlist_foreach(&ly->Text, &it, t) + hash ^= pcb_text_hash(&tr, t); + + polylist_foreach(&ly->Polygon, &it, p) + hash ^= pcb_poly_hash(&tr, p); + } + + /* hash global objects */ + { + pcb_pstk_t *ps; +TODO("subc: subc-in-subc: trans in trans") +#if 0 + pcb_subc_t *s; + subclist_foreach(&sc->data->subc, &it, s) + hash ^= pcb_subc_hash_(&tr, p); +#endif + padstacklist_foreach(&sc->data->padstack, &it, ps) + hash ^= pcb_pstk_hash(&tr, ps); + } + return hash; +} + Index: tags/2.3.0/src/obj_subc_list.c =================================================================== --- tags/2.3.0/src/obj_subc_list.c (nonexistent) +++ tags/2.3.0/src/obj_subc_list.c (revision 33253) @@ -0,0 +1,36 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + + + +#include "config.h" + +/* include other lists before TDL_DONT_UNDEF makes them pollute the namespace */ +#include "obj_subc.h" + +#define TDL_DONT_UNDEF +#include "obj_subc_list.h" +#include Index: tags/2.3.0/src/obj_subc_list.h =================================================================== --- tags/2.3.0/src/obj_subc_list.h (nonexistent) +++ tags/2.3.0/src/obj_subc_list.h (revision 33253) @@ -0,0 +1,91 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_SUBC_LIST_H +#define PCB_OBJ_SUBC_LIST_H + +#include "obj_subc.h" + +/* List of Elements */ +#define TDL(x) pcb_subclist_ ## x +#define TDL_LIST_T pcb_subclist_t +#define TDL_ITEM_T pcb_subc_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define subclist_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + +#include "ht_subc.h" +#include + +/* When turned on, temporarily ignore the uid in hash()/eq() - useful for + imported subcircuits that may have random UIDs */ +extern int pcb_subc_hash_ignore_uid; + + +/* Calculate a hash value using the content of the subc. The hash value + represents the actual content of an subc */ +unsigned int pcb_subc_hash(pcb_subc_t *e); + +/* Compare two subcs and return 1 if they are qeual + (their uids match and they contain the same objects). */ +int pcb_subc_eq(pcb_subc_t *sc1, pcb_subc_t *sc2); + +/* Create a new local variable to be used for deduplication */ +#define pcb_subclist_dedup_initializer(state) htscp_t *state = NULL; + +/* Do a "continue" if an subc matching loop_elem has been seen already; + Typically this is invoked as the first statement of an subclist_foreach() + loop. */ +#define pcb_subclist_dedup_skip(state, loop_elem) \ +switch(1) { \ + case 1: { \ + if (state == NULL) \ + state = htscp_alloc(pcb_subc_hash, pcb_subc_eq); \ + if (htscp_has(state, loop_elem)) \ + continue; \ + htscp_set(state, loop_elem, loop_elem); \ + } \ +} + +/* use this after the loop to free all memory used by state */ +#define pcb_subclist_dedup_free(state) \ + do { \ + if (state != NULL) { \ + htscp_free(state); \ + state = NULL; \ + } \ + } while(0) + + +#ifndef LIST_SUBCENT_NOINSTANT +#include +#include +#endif + +#endif Index: tags/2.3.0/src/obj_subc_op.h =================================================================== --- tags/2.3.0/src/obj_subc_op.h (nonexistent) +++ tags/2.3.0/src/obj_subc_op.h (revision 33253) @@ -0,0 +1,57 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_SUBC_OP_H +#define PCB_OBJ_SUBC_OP_H + +#include "operation.h" + +void *pcb_subcop_copy(pcb_opctx_t *ctx, pcb_subc_t *src); +void *pcb_subcop_move(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_rotate90(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_rotate(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_move_buffer(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_add_to_buffer(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_change_size(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_change_clear_size(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_change_1st_size(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_change_2nd_size(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_change_nonetlist(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_change_name(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_destroy(pcb_opctx_t *ctx, pcb_subc_t *sc); +void *pcb_subcop_remove(pcb_opctx_t *ctx, pcb_subc_t *sc); + +void *pcb_subcop_change_flag(pcb_opctx_t *ctx, pcb_subc_t *sc); + +typedef enum pcb_subc_op_undo_e { + PCB_SUBCOP_UNDO_NORMAL, /* each part operation is undone separately */ + PCB_SUBCOP_UNDO_SUBC, /* the undo for the parent subcircuit will handle each part's undo */ + PCB_SUBCOP_UNDO_BATCH /* each part operation has its own undo, but with the same serial */ +} pcb_subc_op_undo_t; + +void *pcb_subc_op(pcb_data_t *Data, pcb_subc_t *sc, pcb_opfunc_t *opfunc, pcb_opctx_t *ctx, pcb_subc_op_undo_t batch_undo); + +#endif Index: tags/2.3.0/src/obj_subc_parent.h =================================================================== --- tags/2.3.0/src/obj_subc_parent.h (nonexistent) +++ tags/2.3.0/src/obj_subc_parent.h (revision 33253) @@ -0,0 +1,106 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_SUBC_PARENT_H +#define PCB_OBJ_SUBC_PARENT_H + +#include "data.h" +#include "data_parent.h" +#include "layer.h" + +/* Returns the subc a global (on-data) object is part of (or NULL if not part of any subc) */ +RND_INLINE pcb_subc_t *pcb_gobj_parent_subc(pcb_parenttype_t pt, const pcb_parent_t *p) +{ + if (pt != PCB_PARENT_DATA) + return NULL; + + if (p->data == NULL) + return NULL; + + if (p->data->parent_type == PCB_PARENT_SUBC) + return p->data->parent.subc; + return NULL; +} + +/* Returns the subc a layer object is part of (or NULL if not part of any subc) */ +RND_INLINE pcb_subc_t *pcb_lobj_parent_subc(pcb_parenttype_t pt, const pcb_parent_t *p) +{ + if (pt != PCB_PARENT_LAYER) + return NULL; + + if (p->layer == NULL) + return NULL; + + if (p->layer->parent.data == NULL) + return NULL; + + if (p->layer->parent.data->parent_type == PCB_PARENT_SUBC) + return p->layer->parent.data->parent.subc; + return NULL; +} + +/* Returns the subc an object is part of (or NULL if not part of any subc) */ +RND_INLINE pcb_subc_t *pcb_obj_parent_subc(const pcb_any_obj_t *obj) +{ + switch(obj->type) { + case PCB_OBJ_PSTK: + case PCB_OBJ_SUBC: + return pcb_gobj_parent_subc(obj->parent_type, &obj->parent); + + case PCB_OBJ_LINE: + case PCB_OBJ_POLY: + case PCB_OBJ_TEXT: + case PCB_OBJ_ARC: + case PCB_OBJ_GFX: + return pcb_lobj_parent_subc(obj->parent_type, &obj->parent); + + default: + /* anything else: virtual */ + return 0; + } + return 0; +} + +RND_INLINE rnd_bool_t pcb_obj_is_under(pcb_any_obj_t *obj, pcb_data_t *data) +{ + for(;;) { + switch(obj->parent_type) { + case PCB_PARENT_INVALID: return rnd_false; + case PCB_PARENT_BOARD: return rnd_false; + case PCB_PARENT_UI: return rnd_false; /* shouldn't happen */ + case PCB_PARENT_LAYER: if (obj->parent.layer->parent.data == data) return rnd_true; break; + case PCB_PARENT_SUBC: if (obj->parent.subc->data == data) return rnd_true; break; + case PCB_PARENT_DATA: if (obj->parent.data == data) return rnd_true; break; + case PCB_PARENT_NET: if (obj->parent.data == data) return rnd_true; break; + } + obj = (pcb_any_obj_t *)pcb_obj_parent_subc(obj); + if (obj == NULL) + return rnd_false; + } +} + + +#endif Index: tags/2.3.0/src/obj_term.c =================================================================== --- tags/2.3.0/src/obj_term.c (nonexistent) +++ tags/2.3.0/src/obj_term.c (revision 33253) @@ -0,0 +1,348 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "change.h" +#include +#include "obj_common.h" +#include "obj_term.h" +#include "obj_subc_parent.h" +#include +#include "undo.h" +#include "polygon.h" + +static const char core_term_cookie[] = "core-term"; + +static int term_name_invalid(const char *tname) +{ + if ((tname == NULL) || (*tname == '\0')) + return 1; + for(;*tname != '\0'; tname++) + if ((!isalnum(*tname)) && (*tname != '_') && (*tname != '-')) + return 1; + return 0; +} + +pcb_term_err_t pcb_term_name_is_valid(const char *tname) +{ + if (term_name_invalid(tname)) + return PCB_TERM_ERR_INVALID_NAME; + + return PCB_TERM_ERR_SUCCESS; +} + +pcb_term_err_t pcb_term_add(htsp_t *terminals, pcb_any_obj_t *obj) +{ + htsp_entry_t *e; + vtp0_t *v; + + if ((obj->term == NULL) || (term_name_invalid(obj->term))) + return PCB_TERM_ERR_INVALID_NAME; + + e = htsp_getentry(terminals, obj->term); + if (e == NULL) { + /* allocate new terminal */ + char *tname = rnd_strdup(obj->term); + v = malloc(sizeof(vtp0_t)); + vtp0_init(v); + htsp_set(terminals, tname, v); + } + else { + /* need to use the ones from the hash to avoid extra allocation/leak */ + v = e->value; + } + + vtp0_append(v, obj); + + return PCB_TERM_ERR_SUCCESS; +} + +pcb_term_err_t pcb_term_del(htsp_t *terminals, const char *termid, pcb_any_obj_t *obj) +{ + vtp0_t *v; + size_t n; + + if (termid == NULL) + return PCB_TERM_ERR_TERM_NOT_FOUND; + + v = htsp_get(terminals, termid); + if (v == NULL) + return PCB_TERM_ERR_TERM_NOT_FOUND; + + for(n = 0; n < v->used; n++) { + if (v->array[n] == obj) { + vtp0_remove(v, n, 1); + if (v->used == 0) + pcb_term_remove(terminals, termid); + return PCB_TERM_ERR_SUCCESS; + } + } + + return PCB_TERM_ERR_NOT_IN_TERMINAL; +} + +pcb_term_err_t pcb_term_del_auto(pcb_any_obj_t *obj) +{ + pcb_subc_t *subc; + + if (obj->term == NULL) + return PCB_TERM_ERR_SUCCESS; + + subc = pcb_obj_parent_subc(obj); + if (subc == NULL) + return PCB_TERM_ERR_SUCCESS; + + return pcb_term_del(&subc->terminals, obj->term, obj); +} + +static pcb_term_err_t pcb_term_remove_entry(htsp_t *terminals, htsp_entry_t *e) +{ + vtp0_t *v = e->value; + char *name = e->key; + size_t n; + + /* unlink all objects from this terminal */ + for(n = 0; n < v->used; n++) { + pcb_any_obj_t *obj = v->array[n]; + obj->term = NULL; + } + + htsp_delentry(terminals, e); + free(name); + vtp0_uninit(v); + free(v); + + return PCB_TERM_ERR_SUCCESS; +} + +pcb_term_err_t pcb_term_remove(htsp_t *terminals, const char *tname) +{ + htsp_entry_t *e; + + e = htsp_getentry(terminals, tname); + if (e == NULL) + return PCB_TERM_ERR_TERM_NOT_FOUND; + + return pcb_term_remove_entry(terminals, e); +} + +pcb_term_err_t pcb_term_init(htsp_t *terminals) +{ + htsp_init(terminals, strhash, strkeyeq); + return PCB_TERM_ERR_SUCCESS; +} + +pcb_term_err_t pcb_term_uninit(htsp_t *terminals) +{ + htsp_entry_t *e; + + for (e = htsp_first(terminals); e; e = htsp_next(terminals, e)) + pcb_term_remove_entry(terminals, e); + htsp_uninit(terminals); + return PCB_TERM_ERR_SUCCESS; +} + +/*** undoable term rename ***/ + +typedef struct { + pcb_any_obj_t *obj; + pcb_flag_t Flags; + char str[1]; /* must be the last item, spans longer than 1 */ +} term_rename_t; + +static int undo_term_rename_swap(void *udata) +{ + char *old_term = NULL, *autofree = NULL; + term_rename_t *r = udata; + int res = 0; + pcb_flag_t ftmp; + + /* remove from previous terminal */ + if (r->obj->term != NULL) { + old_term = rnd_strdup(r->obj->term); + pcb_attribute_remove(&r->obj->Attributes, "term"); + pcb_obj_invalidate_label(r->obj->type, r->obj->parent.any, r->obj, r->obj); + r->obj->term = NULL; + } + + /* add to new terminal */ + if (*r->str != '\0') { + r->obj->term = autofree = rnd_strdup(r->str); + pcb_obj_invalidate_label(r->obj->type, r->obj->parent.any, r->obj, r->obj); + } + + /* swap name: redo & undo are symmetric; we made sure to have enough room for either old or new name */ + if (old_term == NULL) + *r->str = '\0'; + else + strcpy(r->str, old_term); + + free(old_term); + + /* swap flags: redo & undo are symmetric */ + ftmp = r->obj->Flags; + r->obj->Flags = r->Flags; + r->Flags = ftmp; + + /* Update the attributes */ + if (r->obj->term != NULL) + pcb_attribute_put(&r->obj->Attributes, "term", r->obj->term); + else + pcb_attribute_remove(&r->obj->Attributes, "term"); + + if (r->obj->type == PCB_OBJ_POLY) + pcb_poly_init_clip(r->obj->parent.layer->parent.data, r->obj->parent.layer, (pcb_poly_t *)r->obj); + + free(autofree); + return res; +} + +static void undo_term_rename_print(void *udata, char *dst, size_t dst_len) +{ + term_rename_t *r = udata; + rnd_snprintf(dst, dst_len, "term_rename: %s #%ld to '%s'\n", + pcb_obj_type_name(r->obj->type), r->obj->ID, r->str); +} + +static const uundo_oper_t undo_term_rename = { + core_term_cookie, + NULL, /* free */ + undo_term_rename_swap, + undo_term_rename_swap, + undo_term_rename_print +}; + +pcb_term_err_t pcb_term_undoable_rename(pcb_board_t *pcb, pcb_any_obj_t *obj, const char *new_name) +{ + int nname_len = 0, oname_len = 0, len; + term_rename_t *r; + + if ((new_name == NULL) && (obj->term == NULL)) + return PCB_TERM_ERR_NO_CHANGE; + + if (((new_name != NULL) && (obj->term != NULL)) && (strcmp(new_name, obj->term) == 0)) + return PCB_TERM_ERR_NO_CHANGE; + + if (new_name != NULL) + nname_len = strlen(new_name); + + if (obj->term != NULL) + oname_len = strlen(obj->term); + + len = nname_len > oname_len ? nname_len : oname_len; /* +1 for the terminator is implied by sizeof(->str) */ + + r = pcb_undo_alloc(pcb, &undo_term_rename, sizeof(term_rename_t) + len); + r->obj = obj; + memcpy(r->str, new_name, nname_len+1); + r->Flags = obj->Flags; + PCB_FLAG_CLEAR(PCB_FLAG_CLEARPOLY, r); + undo_term_rename_swap(r); + + if (obj->type == PCB_OBJ_POLY) + pcb_poly_init_clip(obj->parent.layer->parent.data, obj->parent.layer, (pcb_poly_t *)obj); + + pcb_undo_inc_serial(); + return PCB_TERM_ERR_SUCCESS; +} + +#define CHECK_TERM_LY(ob) \ + do { \ + if (RND_NSTRCMP(term_name, ob->term) == 0) { \ + if (parent_out != NULL) *parent_out = subc; \ + if (gid_out != NULL) *gid_out = pcb_layer_get_group_(layer); \ + return (pcb_any_obj_t *)ob; \ + } \ + } while(0) + +#define CHECK_TERM_GL(ob) \ + do { \ + if (RND_NSTRCMP(term_name, ob->term) == 0) { \ + if (parent_out != NULL) *parent_out = subc; \ + if (gid_out != NULL) { \ + *gid_out = -1; \ + pcb_layergrp_list(pcb, lyt, gid_out, 1); \ + } \ + return (pcb_any_obj_t *)ob; \ + } \ + } while(0) + +pcb_any_obj_t *pcb_term_find_name(const pcb_board_t *pcb, pcb_data_t *data, pcb_layer_type_t lyt, const char *subc_name, const char *term_name, pcb_subc_t **parent_out, rnd_layergrp_id_t *gid_out) +{ + pcb_subc_t *subc; + pcb_layer_t *layer; + int l; + + if (lyt == 0) + return NULL; + + if ((subc = pcb_subc_by_refdes(data, subc_name)) == NULL) + return NULL; + + if (PCB_FLAG_TEST(PCB_FLAG_NONETLIST, subc)) + return NULL; + + /* search for global objects: padstack */ + if (lyt & (PCB_LYT_COPPER | PCB_LYT_MASK | PCB_LYT_MECH)) { + PCB_PADSTACK_LOOP(subc->data) { + CHECK_TERM_GL(padstack); + } PCB_END_LOOP; + } + + /* search for layer objects */ + layer = subc->data->Layer; + for (l = 0; l < subc->data->LayerN; l++, layer++) { + if ((pcb_layer_flags_(layer) & lyt) == 0) + continue; + PCB_LINE_LOOP(layer) { + CHECK_TERM_LY(line); + } PCB_END_LOOP; + + PCB_ARC_LOOP(layer) { + CHECK_TERM_LY(arc); + } PCB_END_LOOP; + + PCB_POLY_LOOP(layer) { + CHECK_TERM_LY(polygon); + } PCB_END_LOOP; + + + PCB_TEXT_LOOP(layer) { + CHECK_TERM_LY(text); + } PCB_END_LOOP; + } + + return NULL; +} + +#undef CHECK_TERM_LY +#undef CHECK_TERM_GL + Index: tags/2.3.0/src/obj_term.h =================================================================== --- tags/2.3.0/src/obj_term.h (nonexistent) +++ tags/2.3.0/src/obj_term.h (revision 33253) @@ -0,0 +1,92 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Terminals: within a subcircuit, a terminal is a point of netlist connection. + Subcircuit objects can be tagged to belong to a terminal, by terminal ID + (similar tothe old pin number concept). + + A terminals is a str->ptr hash, keyed by terminal name. Each item is + a vtp0_t vector cotaining one or more pcb_any_obj_t * pointers to the + objects making up that terminal. +*/ + +#ifndef PCB_OBJ_TERM_H +#define PCB_OBJ_TERM_H + +#include +#include +#include "obj_common.h" +#include "layer.h" + +typedef enum pcb_term_err_e { + PCB_TERM_ERR_SUCCESS = 0, + PCB_TERM_ERR_ALREADY_TERMINAL, /* object is already in a terminal, can not be added in another */ + PCB_TERM_ERR_NOT_IN_TERMINAL, /* object is not part of any terminal */ + PCB_TERM_ERR_TERM_NOT_FOUND, + PCB_TERM_ERR_NO_CHANGE, + PCB_TERM_ERR_INVALID_NAME +} pcb_term_err_t; + +/* any type that can be a temrinal */ +#define PCB_TERM_OBJ_TYPES \ + (PCB_OBJ_LINE | PCB_OBJ_TEXT | PCB_OBJ_POLY | PCB_OBJ_ARC | PCB_OBJ_PSTK | PCB_OBJ_SUBC) + +/* Initialize a clean hash of terminals for a subcircuit */ +pcb_term_err_t pcb_term_init(htsp_t *terminals); + +/* Remove all objects from all terminals and destroy the hash */ +pcb_term_err_t pcb_term_uninit(htsp_t *terminals); + +/* Determines if tname is a valid terminal name */ +pcb_term_err_t pcb_term_name_is_valid(const char *tname); + +/* Add obj to a list of terminals named tname (obj->term must be set already). */ +pcb_term_err_t pcb_term_add(htsp_t *terminals, pcb_any_obj_t *obj); + +/* Remove obj from terminal terminals. termid is the old terminal name. + Removes terminal if it becomes empty. */ +pcb_term_err_t pcb_term_del(htsp_t *terminals, const char *termid, pcb_any_obj_t *obj); + +/* Automatically call pcb_term_del() on obj if needed - call this before removing an object */ +pcb_term_err_t pcb_term_del_auto(pcb_any_obj_t *obj); + +/* Remove a terminal from, calling pcb_term_del() on all objects in it. */ +pcb_term_err_t pcb_term_remove(htsp_t *terminals, const char *tname); + +/* Returns a vector of (pcb_any_obj_t *) containing all objects for the named + termina. Returns NULL if tname doesn't exist in terminals. */ +#define pcb_term_get(terminals, tname) \ + (vtp0_t *)htsp_get(terminals, (char *)tname) + +/* Rename an object's ->term field in an undoable way */ +pcb_term_err_t pcb_term_undoable_rename(pcb_board_t *pcb, pcb_any_obj_t *obj, const char *new_name); + +/* Look up subc_name/term_name on layers matching lyt. Returns the object + or NULL if not found. If the *out parameters are non-NULL, load them. + Ignores subcircuits marked as nonetlist even if explicitly named. */ +pcb_any_obj_t *pcb_term_find_name(const pcb_board_t *pcb, pcb_data_t *data, pcb_layer_type_t lyt, const char *subc_name, const char *term_name, pcb_subc_t **parent_out, rnd_layergrp_id_t *gid_out); + +#endif Index: tags/2.3.0/src/obj_text.c =================================================================== --- tags/2.3.0/src/obj_text.c (nonexistent) +++ tags/2.3.0/src/obj_text.c (revision 33253) @@ -0,0 +1,1718 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Drawing primitive: text */ + +#include "config.h" + +#include "rotate.h" +#include "board.h" +#include "data.h" +#include +#include +#include "undo.h" +#include "polygon.h" +#include +#include "event.h" +#include "layer.h" + +#include "obj_text.h" +#include "obj_text_op.h" +#include "obj_text_list.h" +#include "obj_poly_draw.h" +#include "obj_arc_draw.h" + +#include "obj_subc_parent.h" +#include "obj_hash.h" + +#include "obj_line_draw.h" +#include "obj_text_draw.h" +#include "conf_core.h" + +/*** allocation ***/ + +void pcb_text_reg(pcb_layer_t *layer, pcb_text_t *text) +{ + textlist_append(&layer->Text, text); + PCB_SET_PARENT(text, layer, layer); + + if (layer->parent_type == PCB_PARENT_UI) + return; + + if (layer->parent_type == PCB_PARENT_DATA) + pcb_obj_id_reg(layer->parent.data, text); +} + +void pcb_text_unreg(pcb_text_t *text) +{ + pcb_layer_t *layer = text->parent.layer; + assert(text->parent_type == PCB_PARENT_LAYER); + textlist_remove(text); + if (layer->parent_type != PCB_PARENT_UI) { + assert(layer->parent_type == PCB_PARENT_DATA); + pcb_obj_id_del(layer->parent.data, text); + } + PCB_CLEAR_PARENT(text); +} + +pcb_text_t *pcb_text_alloc_id(pcb_layer_t *layer, long int id) +{ + pcb_text_t *new_obj; + + new_obj = calloc(sizeof(pcb_text_t), 1); + new_obj->ID = id; + new_obj->type = PCB_OBJ_TEXT; + new_obj->Attributes.post_change = pcb_obj_attrib_post_change; + + pcb_text_reg(layer, new_obj); + + return new_obj; +} + +pcb_text_t *pcb_text_alloc(pcb_layer_t *layer) +{ + return pcb_text_alloc_id(layer, pcb_create_ID_get()); +} + +void pcb_text_free(pcb_text_t *text) +{ + if ((text->parent.layer != NULL) && (text->parent.layer->text_tree != NULL)) + rnd_r_delete_entry(text->parent.layer->text_tree, (rnd_box_t *)text); + pcb_attribute_free(&text->Attributes); + pcb_text_unreg(text); + free(text->TextString); + pcb_obj_common_free((pcb_any_obj_t *)text); + free(text); +} + +/*** utility ***/ + +static const char core_text_cookie[] = "core-text"; + +typedef struct { + pcb_text_t *text; /* it is safe to save the object pointer because it is persistent (through the removed object list) */ + int Scale; + double scale_x, scale_y; + rnd_coord_t X, Y; + rnd_coord_t thickness; + rnd_coord_t clearance; + double rot; +} undo_text_geo_t; + +static int undo_text_geo_swap(void *udata) +{ + undo_text_geo_t *g = udata; + pcb_layer_t *layer = g->text->parent.layer; + pcb_board_t *pcb = pcb_data_get_top(layer->parent.data); + + if (layer->text_tree != NULL) + rnd_r_delete_entry(layer->text_tree, (rnd_box_t *)g->text); + pcb_poly_restore_to_poly(layer->parent.data, PCB_OBJ_TEXT, layer, g->text); + + rnd_swap(int, g->Scale, g->text->Scale); + rnd_swap(double, g->scale_x, g->text->scale_x); + rnd_swap(double, g->scale_y, g->text->scale_y); + rnd_swap(rnd_coord_t, g->X, g->text->X); + rnd_swap(rnd_coord_t, g->Y, g->text->Y); + rnd_swap(rnd_coord_t, g->thickness, g->text->thickness); + rnd_swap(rnd_coord_t, g->clearance, g->text->clearance); + rnd_swap(double, g->rot, g->text->rot); + + if (pcb != NULL) + pcb_text_bbox(pcb_font(pcb, g->text->fid, 1), g->text); + if (layer->text_tree != NULL) + rnd_r_insert_entry(layer->text_tree, (rnd_box_t *)g->text); + pcb_poly_clear_from_poly(layer->parent.data, PCB_OBJ_TEXT, layer, g->text); + + return 0; +} + +static void undo_text_geo_print(void *udata, char *dst, size_t dst_len) +{ + rnd_snprintf(dst, dst_len, "text geo"); +} + +static const uundo_oper_t undo_text_geo = { + core_text_cookie, + NULL, + undo_text_geo_swap, + undo_text_geo_swap, + undo_text_geo_print +}; + + +pcb_text_t *pcb_text_new_(pcb_layer_t *Layer, pcb_font_t *PCBFont, rnd_coord_t X, rnd_coord_t Y, double rot, pcb_text_mirror_t mirror, int Scale, double scx, double scy, rnd_coord_t thickness, const char *TextString, pcb_flag_t Flags) +{ + pcb_text_t *text; + + if (TextString == NULL) + return NULL; + + text = pcb_text_alloc(Layer); + if (text == NULL) + return NULL; + + /* Set up mirroring */ + if (mirror & PCB_TXT_MIRROR_Y) + Flags.f |= PCB_FLAG_ONSOLDER; + if (mirror & PCB_TXT_MIRROR_X) + pcb_attribute_put(&text->Attributes, "mirror_x", "1"); + + /* copy values, width and height are set by drawing routine + * because at this point we don't know which symbols are available + */ + text->X = X; + text->Y = Y; + text->rot = rot; + text->Flags = Flags; + text->Scale = Scale; + text->scale_x = scx; + text->scale_y = scy; + text->thickness = thickness; + text->TextString = rnd_strdup(TextString); + text->fid = PCBFont->id; + + return text; +} + +/* creates a new text on a layer */ +pcb_text_t *pcb_text_new(pcb_layer_t *Layer, pcb_font_t *PCBFont, rnd_coord_t X, rnd_coord_t Y, double rot, int Scale, rnd_coord_t thickness, const char *TextString, pcb_flag_t Flags) +{ + pcb_text_t *text = pcb_text_new_(Layer, PCBFont, X, Y, rot, 0, Scale, 0, 0, thickness, TextString, Flags); + + pcb_add_text_on_layer(Layer, text, PCBFont); + + return text; +} + +pcb_text_t *pcb_text_new_scaled(pcb_layer_t *Layer, pcb_font_t *PCBFont, rnd_coord_t X, rnd_coord_t Y, double rot, pcb_text_mirror_t mirror, int Scale, double scx, double scy, rnd_coord_t thickness, const char *TextString, pcb_flag_t Flags) +{ + pcb_text_t *text = pcb_text_new_(Layer, PCBFont, X, Y, rot, mirror, Scale, scx, scy, thickness, TextString, Flags); + + pcb_add_text_on_layer(Layer, text, PCBFont); + + return text; +} + +pcb_text_t *pcb_text_new_by_bbox(pcb_layer_t *Layer, pcb_font_t *PCBFont, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t bbw, rnd_coord_t bbh, rnd_coord_t anchx, rnd_coord_t anchy, double scxy, pcb_text_mirror_t mirror, double rot, rnd_coord_t thickness, const char *TextString, pcb_flag_t Flags) +{ + rnd_coord_t obw, obh, nbw, nbh, nanchx, nanchy; + double gsc, gscx, gscy, cs, sn, mx = 1, my = 1; + pcb_text_t *t; + + t = pcb_text_new_(Layer, PCBFont, 0, 0, 0, mirror, 100, 1, 1, thickness, TextString, Flags); + + if ((bbw <= 0) || (bbh <= 0)) + rnd_message(RND_MSG_ERROR, "internal error in pcb_text_new_by_bbox(): invalid input bbox\n"); + + t->scale_x = scxy; + t->scale_y = 1; + pcb_text_bbox(PCBFont, t); + + /* determine the final scaling */ + obw = t->bbox_naked.X2 - t->bbox_naked.X1; + obh = t->bbox_naked.Y2 - t->bbox_naked.Y1; + + /*rnd_trace(" pcb-rnd: %ml %ml req: %ml %ml (%s) sc: %f %f\n", obw, obh, bbw, bbh, TextString, t->scale_x, t->scale_y);*/ + + gscx = (double)bbw/(double)obw; + gscy = (double)bbh/(double)obh; + gsc = ((gscx > 0) && (gscx < gscy)) ? gscx : gscy; + + if (gsc <= 0) { + rnd_message(RND_MSG_ERROR, "internal error in pcb_text_new_by_bbox(): invalid text scaling\n"); + gsc = 1; + } + + t->scale_x *= gsc; + t->scale_y *= gsc; + + pcb_text_bbox(PCBFont, t); + + /* figure new anchor points (on the new, typically smaller bbox) */ + nbw = t->bbox_naked.X2 - t->bbox_naked.X1; + nbh = t->bbox_naked.Y2 - t->bbox_naked.Y1; + + nanchx = (double)(anchx) / (double)bbw * (double)nbw; + nanchy = (double)(anchy) / (double)bbh * (double)nbh; + + /* calculate final placement and enable rotation */ + if (mirror & PCB_TXT_MIRROR_X) mx = -1; + if (mirror & PCB_TXT_MIRROR_Y) my = -1; + + cs = cos(rot*mx*my / RND_RAD_TO_DEG); + sn = sin(rot*mx*my / RND_RAD_TO_DEG); + + t->X = X - (nanchx * cs * mx + nanchy * sn * my); + t->Y = Y - (nanchy * cs * my - nanchx * sn * mx); + t->rot = rot; + + /*rnd_trace(" final: %ml %ml (%f %f -> %f) got:%f wanted:%f anch: %ml %ml -> %ml %ml\n", t->bbox_naked.X2 - t->bbox_naked.X1, t->bbox_naked.Y2 - t->bbox_naked.Y1, gscx, gscy, gsc, t->scale_x/t->scale_y, scxy, anchx, anchy, nanchx, nanchy);*/ + + pcb_add_text_on_layer(Layer, t, PCBFont); + return t; +} + + +static pcb_text_t *pcb_text_copy_meta(pcb_text_t *dst, pcb_text_t *src) +{ + if (dst == NULL) + return NULL; + pcb_attribute_copy_all(&dst->Attributes, &src->Attributes); + return dst; +} + +#define text_mirror_bits(t) \ + ((PCB_FLAG_TEST(PCB_FLAG_ONSOLDER, (t)) ? PCB_TXT_MIRROR_Y : 0) | ((t)->mirror_x ? PCB_TXT_MIRROR_X : 0)) + +pcb_text_t *pcb_text_dup(pcb_layer_t *dst, pcb_text_t *src) +{ + pcb_text_t *t = pcb_text_new_scaled(dst, pcb_font(PCB, src->fid, 1), src->X, src->Y, src->rot, text_mirror_bits(src), src->Scale, src->scale_x, src->scale_y, src->thickness, src->TextString, src->Flags); + pcb_text_copy_meta(t, src); + return t; +} + +pcb_text_t *pcb_text_dup_at(pcb_layer_t *dst, pcb_text_t *src, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_text_t *t = pcb_text_new_scaled(dst, pcb_font(PCB, src->fid, 1), src->X+dx, src->Y+dy, src->rot, text_mirror_bits(src), src->Scale, src->scale_x, src->scale_y, src->thickness, src->TextString, src->Flags); + pcb_text_copy_meta(t, src); + return t; +} + +void pcb_add_text_on_layer(pcb_layer_t *Layer, pcb_text_t *text, pcb_font_t *PCBFont) +{ + /* calculate size of the bounding box */ + pcb_text_bbox(PCBFont, text); + if (!Layer->text_tree) + Layer->text_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Layer->text_tree, (rnd_box_t *) text); +} + +static int pcb_text_render_str_cb(void *ctx, gds_t *s, const char **input) +{ + const pcb_text_t *text = ctx; + char *end, key[128], *path, *attrs; + size_t len; + + end = strchr(*input, '%'); + len = end - *input; + if (len > sizeof(key)-1) + return -1; + + strncpy(key, *input, len); + key[len] = '\0'; + *input += len+1; + + if ((key[0] == 'a') && (key[1] == '.')) { + const pcb_attribute_list_t *attr = &text->Attributes; + path = key+2; + if ((path[0] == 'p') && (memcmp(path, "parent.", 7) == 0)) { + pcb_data_t *par = text->parent.layer->parent.data; + + if (par == NULL) + attr = NULL; + else if (par->parent_type == PCB_PARENT_SUBC) + attr = &par->parent.subc->Attributes; + else if (par->parent_type == PCB_PARENT_BOARD) + attr = &par->parent.board->Attributes; + else + attr = NULL; + path+=7; + } + if (attr != NULL) { + attrs = pcb_attribute_get(attr, path); + if (attrs != NULL) + gds_append_str(s, attrs); + } + } + return 0; +} + +/* Render the string of a text, doing substitution if needed - don't allocate if there's no subst */ +static unsigned char *pcb_text_render_str(pcb_text_t *text) +{ + unsigned char *res; + + if (!PCB_FLAG_TEST(PCB_FLAG_DYNTEXT, text)) + return (unsigned char *)text->TextString; + + res = (unsigned char *)rnd_strdup_subst(text->TextString, pcb_text_render_str_cb, text, RND_SUBST_PERCENT | RND_SUBST_CONF); + if (res == NULL) { + res = (unsigned char *)rnd_strdup(""); + } + else if (*res == '\0') { + free(res); + res = (unsigned char *)rnd_strdup(""); + } + + return res; +} + +int pcb_append_dyntext(gds_t *dst, const pcb_any_obj_t *obj, const char *fmt) +{ + return rnd_subst_append(dst, fmt, pcb_text_render_str_cb, (void *)obj, RND_SUBST_PERCENT | RND_SUBST_CONF, 0); +} + +/* Free rendered if it was allocated */ +static void pcb_text_free_str(pcb_text_t *text, unsigned char *rendered) +{ + if ((unsigned char *)text->TextString != rendered) + free(rendered); +} + +void pcb_text_get_scale_xy(pcb_text_t *text, double *scx, double *scy) +{ + double sc = (double)text->Scale / 100.0; + *scx = (text->scale_x > 0) ? text->scale_x : sc; + *scy = (text->scale_y > 0) ? text->scale_y : sc; +} + +int pcb_text_old_scale(pcb_text_t *text, int *scale_out) +{ + double scx, scy; + + if ((text->scale_x <= 0) && (text->scale_y <= 0)) { /* old model */ + *scale_out = text->Scale; + return 0; + } + + pcb_text_get_scale_xy(text, &scx, &scy); + if (fabs(scx - scy) < 0.01) { /* new model but scx == scy */ + *scale_out = rnd_round(scx * 100); + return 0; + } + + *scale_out = rnd_round((scx + scy) / 2.0 * 100); + return -1; +} + +/* creates the bounding box of a text object */ +void pcb_text_bbox(pcb_font_t *FontPtr, pcb_text_t *Text) +{ + pcb_symbol_t *symbol; + unsigned char *s, *rendered = pcb_text_render_str(Text); + int i; + int space; + rnd_coord_t minx, miny, maxx, maxy, tx; + rnd_coord_t min_final_radius; + rnd_coord_t min_unscaled_radius; + rnd_bool first_time = rnd_true; + pcb_poly_t *poly; + double scx, scy; + pcb_xform_mx_t mx = PCB_XFORM_MX_IDENT; + rnd_coord_t cx[4], cy[4]; + pcb_text_mirror_t mirror; + + pcb_text_get_scale_xy(Text, &scx, &scy); + + s = rendered; + + if (FontPtr == NULL) + FontPtr = pcb_font(PCB, Text->fid, 1); + + symbol = FontPtr->Symbol; + + minx = miny = maxx = maxy = tx = 0; + + /* Calculate the bounding box based on the larger of the thicknesses + * the text might clamped at on silk or copper layers. + */ + min_final_radius = MAX(conf_core.design.min_wid, conf_core.design.min_slk) / 2; + + /* Pre-adjust the line radius for the fact we are initially computing the + * bounds of the un-scaled text, and the thickness clamping applies to + * scaled text. + */ + min_unscaled_radius = PCB_UNPCB_SCALE_TEXT(min_final_radius, Text->Scale); + + /* calculate size of the bounding box */ + for (; s && *s; s++) { + if (*s <= PCB_MAX_FONTPOSITION && symbol[*s].Valid) { + pcb_line_t *line = symbol[*s].Line; + pcb_arc_t *arc; + for (i = 0; i < symbol[*s].LineN; line++, i++) { + /* Clamp the width of text lines at the minimum thickness. + * NB: Divide 4 in thickness calculation is comprised of a factor + * of 1/2 to get a radius from the center-line, and a factor + * of 1/2 because some stupid reason we render our glyphs + * at half their defined stroke-width. + */ + rnd_coord_t unscaled_radius = MAX(min_unscaled_radius, line->Thickness / 4); + + if (first_time) { + minx = maxx = line->Point1.X; + miny = maxy = line->Point1.Y; + first_time = rnd_false; + } + + minx = MIN(minx, line->Point1.X - unscaled_radius + tx); + miny = MIN(miny, line->Point1.Y - unscaled_radius); + minx = MIN(minx, line->Point2.X - unscaled_radius + tx); + miny = MIN(miny, line->Point2.Y - unscaled_radius); + maxx = MAX(maxx, line->Point1.X + unscaled_radius + tx); + maxy = MAX(maxy, line->Point1.Y + unscaled_radius); + maxx = MAX(maxx, line->Point2.X + unscaled_radius + tx); + maxy = MAX(maxy, line->Point2.Y + unscaled_radius); + } + + for(arc = arclist_first(&symbol[*s].arcs); arc != NULL; arc = arclist_next(arc)) { + pcb_arc_bbox(arc); + maxx = MAX(maxx, arc->bbox_naked.X2); + maxy = MAX(maxy, arc->bbox_naked.Y2); + } + + for(poly = polylist_first(&symbol[*s].polys); poly != NULL; poly = polylist_next(poly)) { + int n; + rnd_point_t *pnt; + for(n = 0, pnt = poly->Points; n < poly->PointN; n++,pnt++) { + maxx = MAX(maxx, pnt->X + tx); + maxy = MAX(maxy, pnt->Y); + } + } + + space = symbol[*s].Delta; + } + else { + rnd_box_t *ds = &FontPtr->DefaultSymbol; + rnd_coord_t w = ds->X2 - ds->X1; + + minx = MIN(minx, ds->X1 + tx); + miny = MIN(miny, ds->Y1); + minx = MIN(minx, ds->X2 + tx); + miny = MIN(miny, ds->Y2); + maxx = MAX(maxx, ds->X1 + tx); + maxy = MAX(maxy, ds->Y1); + maxx = MAX(maxx, ds->X2 + tx); + maxy = MAX(maxy, ds->Y2); + + space = w / 5; + } + tx += symbol[*s].Width + space; + } + + mirror = text_mirror_bits(Text); + + /* it is enough to do the transformations only once, on the raw bounding box */ + pcb_xform_mx_translate(mx, Text->X, Text->Y); + if (mirror != PCB_TXT_MIRROR_NO) + pcb_xform_mx_scale(mx, (mirror & PCB_TXT_MIRROR_X) ? -1 : 1, (mirror & PCB_TXT_MIRROR_Y) ? -1 : 1); + pcb_xform_mx_rotate(mx, Text->rot); + pcb_xform_mx_scale(mx, scx, scy); + + /* calculate the transformed coordinates of all 4 corners of the raw + (non-axis-aligned) bounding box */ + cx[0] = rnd_round(pcb_xform_x(mx, minx, miny)); + cy[0] = rnd_round(pcb_xform_y(mx, minx, miny)); + cx[1] = rnd_round(pcb_xform_x(mx, maxx, miny)); + cy[1] = rnd_round(pcb_xform_y(mx, maxx, miny)); + cx[2] = rnd_round(pcb_xform_x(mx, maxx, maxy)); + cy[2] = rnd_round(pcb_xform_y(mx, maxx, maxy)); + cx[3] = rnd_round(pcb_xform_x(mx, minx, maxy)); + cy[3] = rnd_round(pcb_xform_y(mx, minx, maxy)); + + /* calculate the axis-aligned version */ + Text->bbox_naked.X1 = Text->bbox_naked.X2 = cx[0]; + Text->bbox_naked.Y1 = Text->bbox_naked.Y2 = cy[0]; + rnd_box_bump_point(&Text->bbox_naked, cx[1], cy[1]); + rnd_box_bump_point(&Text->bbox_naked, cx[2], cy[2]); + rnd_box_bump_point(&Text->bbox_naked, cx[3], cy[3]); + + /* the bounding box covers the extent of influence + * so it must include the clearance values too + */ + Text->BoundingBox.X1 = Text->bbox_naked.X1 - conf_core.design.bloat; + Text->BoundingBox.Y1 = Text->bbox_naked.Y1 - conf_core.design.bloat; + Text->BoundingBox.X2 = Text->bbox_naked.X2 + conf_core.design.bloat; + Text->BoundingBox.Y2 = Text->bbox_naked.Y2 + conf_core.design.bloat; + rnd_close_box(&Text->bbox_naked); + rnd_close_box(&Text->BoundingBox); + pcb_text_free_str(Text, rendered); +} + +int pcb_text_eq(const pcb_host_trans_t *tr1, const pcb_text_t *t1, const pcb_host_trans_t *tr2, const pcb_text_t *t2) +{ + double rotdir1 = tr1->on_bottom ? -1.0 : 1.0, rotdir2 = tr2->on_bottom ? -1.0 : 1.0; + + if (pcb_neqs(t1->TextString, t2->TextString)) return 0; + if (pcb_neqs(t1->term, t2->term)) return 0; + if (pcb_field_neq(t1, t2, thickness)) return 0; + if (pcb_field_neq(t1, t2, fid)) return 0; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, t1) && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, t2)) { + if (pcb_field_neq(t1, t2, Scale)) return 0; + if (pcb_neq_tr_coords(tr1, t1->X, t1->Y, tr2, t2->X, t2->Y)) return 0; + if (floor(fmod((t1->rot * rotdir1) + tr1->rot, 360.0)*10000) != floor(fmod((t2->rot * rotdir2) + tr2->rot, 360.0)*10000)) return 0; + } + + return 1; +} + +unsigned int pcb_text_hash(const pcb_host_trans_t *tr, const pcb_text_t *t) +{ + unsigned int crd = 0; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, t)) { + rnd_coord_t x, y; + double rotdir = tr->on_bottom ? -1.0 : 1.0; + + pcb_hash_tr_coords(tr, &x, &y, t->X, t->Y); + crd = pcb_hash_coord(x) ^ pcb_hash_coord(y) ^ pcb_hash_coord(t->Scale) \ + ^ pcb_hash_scale(t->scale_x) ^ pcb_hash_scale(t->scale_y) \ + ^ pcb_hash_angle(tr, t->rot * rotdir); + } + + return pcb_hash_str(t->TextString) ^ pcb_hash_str(t->term) ^ + pcb_hash_coord(t->thickness) ^ (unsigned)t->fid ^ crd; +} + + +/*** ops ***/ +/* copies a text to buffer */ +void *pcb_textop_add_to_buffer(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + pcb_layer_t *layer = &ctx->buffer.dst->Layer[pcb_layer_id(ctx->buffer.src, Layer)]; + pcb_text_t *t = pcb_text_new_scaled(layer, pcb_font(PCB, Text->fid, 1), Text->X, Text->Y, Text->rot, text_mirror_bits(Text), Text->Scale, Text->scale_x, Text->scale_y, Text->thickness, Text->TextString, pcb_flag_mask(Text->Flags, ctx->buffer.extraflg)); + + pcb_text_copy_meta(t, Text); + if (ctx->buffer.keep_id) pcb_obj_change_id((pcb_any_obj_t *)t, Text->ID); + return t; +} + +/* moves a text without allocating memory for the name between board and buffer */ +void *pcb_textop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t *dstly, pcb_text_t *text) +{ + pcb_layer_t *srcly = text->parent.layer; + + assert(text->parent_type == PCB_PARENT_LAYER); + if ((dstly == NULL) || (dstly == srcly)) { /* auto layer in dst */ + rnd_layer_id_t lid = pcb_layer_id(ctx->buffer.src, srcly); + if (lid < 0) { + rnd_message(RND_MSG_ERROR, "Internal error: can't resolve source layer ID in pcb_textop_move_buffer\n"); + return NULL; + } + dstly = &ctx->buffer.dst->Layer[lid]; + } + + rnd_r_delete_entry(srcly->text_tree, (rnd_box_t *) text); + pcb_poly_restore_to_poly(ctx->buffer.src, PCB_OBJ_TEXT, srcly, text); + + pcb_text_unreg(text); + pcb_text_reg(dstly, text); + + if (!dstly->text_tree) + dstly->text_tree = rnd_r_create_tree(); + rnd_r_insert_entry(dstly->text_tree, (rnd_box_t *) text); + pcb_poly_clear_from_poly(ctx->buffer.dst, PCB_OBJ_TEXT, dstly, text); + + return text; +} + +/* changes the scaling factor of a text object */ +void *pcb_textop_change_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + int value = ctx->chgsize.is_absolute ? RND_COORD_TO_MIL(ctx->chgsize.value) + : Text->Scale + RND_COORD_TO_MIL(ctx->chgsize.value); + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Text)) + return NULL; + if (value <= PCB_MAX_TEXTSCALE && value >= PCB_MIN_TEXTSCALE && value != Text->Scale) { + pcb_undo_add_obj_to_size(PCB_OBJ_TEXT, Layer, Text, Text); + pcb_text_invalidate_erase(Layer, Text); + rnd_r_delete_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + Text->Scale = value; + if (Text->scale_x > 0) + Text->scale_x = (double)value / 100.0; + if (Text->scale_y > 0) + Text->scale_y = (double)value / 100.0; + pcb_text_bbox(pcb_font(PCB, Text->fid, 1), Text); + rnd_r_insert_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + pcb_text_invalidate_draw(Layer, Text); + return Text; + } + return NULL; +} + +/* changes the thickness of a text object */ +void *pcb_textop_change_2nd_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + int value = ctx->chgsize.is_absolute ? ctx->chgsize.value : Text->thickness + ctx->chgsize.value; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Text)) + return NULL; + if (value != Text->thickness) { + pcb_undo_add_obj_to_2nd_size(PCB_OBJ_TEXT, Layer, Text, Text); + pcb_text_invalidate_erase(Layer, Text); + rnd_r_delete_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + Text->thickness = value; + pcb_text_bbox(pcb_font(PCB, Text->fid, 1), Text); + rnd_r_insert_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + pcb_text_invalidate_draw(Layer, Text); + return Text; + } + return NULL; +} + +/* changes the rotation of a text object */ +void *pcb_textop_change_rot(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + int value = ctx->chgsize.is_absolute ? ctx->chgsize.value : Text->rot + ctx->chgsize.value; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Text)) + return NULL; + if (value != Text->rot) { + pcb_undo_add_obj_to_rot(PCB_OBJ_TEXT, Layer, Text, Text); + pcb_text_invalidate_erase(Layer, Text); + rnd_r_delete_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + Text->rot = value; + pcb_text_bbox(pcb_font(PCB, Text->fid, 1), Text); + rnd_r_insert_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + pcb_text_invalidate_draw(Layer, Text); + return Text; + } + return NULL; +} + +/* sets data of a text object and calculates bounding box; memory must have + already been allocated the one for the new string is allocated */ +void *pcb_textop_change_name(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + char *old = Text->TextString; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Text)) + return NULL; + pcb_text_invalidate_erase(Layer, Text); + rnd_r_delete_entry(Layer->text_tree, (rnd_box_t *)Text); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + Text->TextString = ctx->chgname.new_name; + + /* calculate size of the bounding box */ + pcb_text_bbox(pcb_font(PCB, Text->fid, 1), Text); + rnd_r_insert_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + pcb_text_invalidate_draw(Layer, Text); + return old; +} + +/* changes the clearance flag of a text */ +void *pcb_textop_change_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Text)) + return NULL; + pcb_text_invalidate_erase(Layer, Text); + if (PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Text)) { + pcb_undo_add_obj_to_clear_poly(PCB_OBJ_TEXT, Layer, Text, Text, rnd_false); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + } + pcb_undo_add_obj_to_flag(Text); + PCB_FLAG_TOGGLE(PCB_FLAG_CLEARLINE, Text); + if (PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Text)) { + pcb_undo_add_obj_to_clear_poly(PCB_OBJ_TEXT, Layer, Text, Text, rnd_true); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + } + pcb_text_invalidate_draw(Layer, Text); + return Text; +} + +/* sets the clearance flag of a text */ +void *pcb_textop_set_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Text) || PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Text)) + return NULL; + return pcb_textop_change_join(ctx, Layer, Text); +} + +/* clears the clearance flag of a text */ +void *pcb_textop_clear_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, Text) || !PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, Text)) + return NULL; + return pcb_textop_change_join(ctx, Layer, Text); +} + +/* copies a text */ +void *pcb_textop_copy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + pcb_text_t *text; + + text = pcb_text_new_scaled(Layer, pcb_font(PCB, Text->fid, 1), Text->X + ctx->copy.DeltaX, + Text->Y + ctx->copy.DeltaY, Text->rot, text_mirror_bits(Text), Text->Scale, Text->scale_x, Text->scale_y, Text->thickness, Text->TextString, pcb_flag_mask(Text->Flags, PCB_FLAG_FOUND)); + if (ctx->copy.keep_id) + text->ID = Text->ID; + pcb_text_copy_meta(text, Text); + pcb_text_invalidate_draw(Layer, text); + pcb_undo_add_obj_to_create(PCB_OBJ_TEXT, Layer, text, text); + return text; +} + +/* moves a text object */ +void *pcb_textop_move_noclip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + if (Layer->meta.real.vis) { + pcb_text_invalidate_erase(Layer, Text); + pcb_text_move(Text, ctx->move.dx, ctx->move.dy); + pcb_text_invalidate_draw(Layer, Text); + } + else + pcb_text_move(Text, ctx->move.dx, ctx->move.dy); + return Text; +} + +void *pcb_textop_move(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + rnd_r_delete_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + pcb_textop_move_noclip(ctx, Layer, Text); + rnd_r_insert_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + return Text; +} + +void *pcb_textop_clip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + if (ctx->clip.restore) { + rnd_r_delete_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + } + if (ctx->clip.clear) { + rnd_r_insert_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + } + return Text; +} + + +/* moves a text object between layers; lowlevel routines */ +void *pcb_textop_move_to_layer_low(pcb_opctx_t *ctx, pcb_layer_t * Source, pcb_text_t * text, pcb_layer_t * Destination) +{ + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, Source, text); + rnd_r_delete_entry(Source->text_tree, (rnd_box_t *) text); + + pcb_text_unreg(text); + pcb_text_reg(Destination, text); + + if (pcb_layer_flags_(Destination) & PCB_LYT_BOTTOM) + PCB_FLAG_SET(PCB_FLAG_ONSOLDER, text); /* get the text mirrored on display */ + else + PCB_FLAG_CLEAR(PCB_FLAG_ONSOLDER, text); + + /* re-calculate the bounding box (it could be mirrored now) */ + pcb_text_bbox(pcb_font(PCB, text->fid, 1), text); + if (!Destination->text_tree) + Destination->text_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Destination->text_tree, (rnd_box_t *) text); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, Destination, text); + + return text; +} + +/* moves a text object between layers */ +void *pcb_textop_move_to_layer(pcb_opctx_t *ctx, pcb_layer_t * layer, pcb_text_t * text) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, text)) { + rnd_message(RND_MSG_WARNING, "Sorry, text object is locked\n"); + return NULL; + } + if (ctx->move.dst_layer != layer) { + pcb_undo_add_obj_to_move_to_layer(PCB_OBJ_TEXT, layer, text, text); + if (layer->meta.real.vis) + pcb_text_invalidate_erase(layer, text); + text = pcb_textop_move_to_layer_low(ctx, layer, text, ctx->move.dst_layer); + if (ctx->move.dst_layer->meta.real.vis) + pcb_text_invalidate_draw(ctx->move.dst_layer, text); + } + return text; +} + +/* destroys a text from a layer */ +void *pcb_textop_destroy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + pcb_text_free(Text); + return NULL; +} + +/* removes a text from a layer */ +void *pcb_textop_remove(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + /* erase from screen */ + if (Layer->meta.real.vis) { + pcb_text_invalidate_erase(Layer, Text); + rnd_r_delete_entry(Layer->text_tree, (rnd_box_t *)Text); + } + pcb_undo_move_obj_to_remove(PCB_OBJ_TEXT, Layer, Text, Text); + return NULL; +} + +void *pcb_text_destroy(pcb_layer_t *Layer, pcb_text_t *Text) +{ + void *res; + pcb_opctx_t ctx; + + ctx.remove.pcb = PCB; + ctx.remove.destroy_target = NULL; + + res = pcb_textop_remove(&ctx, Layer, Text); + pcb_draw(); + return res; +} + +/* rotates a text in 90 degree steps; only the bounding box is rotated, + text rotation itself is done by the drawing routines */ +void pcb_text_rotate90(pcb_text_t *Text, rnd_coord_t X, rnd_coord_t Y, unsigned Number) +{ + int number = PCB_FLAG_TEST(PCB_FLAG_ONSOLDER, Text) ? (4 - Number) & 3 : Number; + RND_COORD_ROTATE90(Text->X, Text->Y, X, Y, Number); + + Text->rot += number*90.0; + if (Text->rot > 360.0) + Text->rot -= 360.0; + else if (Text->rot < 0.0) + Text->rot += 360.0; + + /* can't optimize with box rotation because of closed boxes */ + pcb_text_bbox(pcb_font(PCB, Text->fid, 1), Text); +} + +/* rotates a text; only the bounding box is rotated, + text rotation itself is done by the drawing routines */ +void pcb_text_rotate(pcb_text_t *Text, rnd_coord_t X, rnd_coord_t Y, double cosa, double sina, double rotdeg) +{ + rnd_rotate(&Text->X, &Text->Y, X, Y, cosa, sina); + Text->rot += rotdeg; + if (Text->rot > 360.0) + Text->rot -= 360.0; + else if (Text->rot < 0.0) + Text->rot += 360.0; + + /* can't optimize with box rotation because of closed boxes */ + pcb_text_bbox(pcb_font(PCB, Text->fid, 1), Text); +} + +/* rotates a text object and redraws it */ +void *pcb_textop_rotate90(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + pcb_text_invalidate_erase(Layer, Text); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + if (Layer->text_tree != NULL) + rnd_r_delete_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_text_rotate90(Text, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.number); + if (Layer->text_tree != NULL) + rnd_r_insert_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + pcb_text_invalidate_draw(Layer, Text); + return Text; +} + +void *pcb_textop_rotate(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + pcb_text_invalidate_erase(Layer, Text); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + if (Layer->text_tree != NULL) + rnd_r_delete_entry(Layer->text_tree, (rnd_box_t *) Text); + + if (Text->rot < 0.0) + Text->rot += 360.0; + + rnd_rotate(&Text->X, &Text->Y, ctx->rotate.center_x, ctx->rotate.center_y, ctx->rotate.cosa, ctx->rotate.sina); + if (PCB_FLAG_TEST(PCB_FLAG_ONSOLDER, Text)) + Text->rot -= ctx->rotate.angle; + else + Text->rot += ctx->rotate.angle; + pcb_text_bbox(NULL, Text); + + if (Layer->text_tree != NULL) + rnd_r_insert_entry(Layer->text_tree, (rnd_box_t *) Text); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, Layer, Text); + pcb_text_invalidate_draw(Layer, Text); + return Text; +} + +void pcb_text_flip_side(pcb_layer_t *layer, pcb_text_t *text, rnd_coord_t y_offs, rnd_bool undoable) +{ + if (layer->text_tree != NULL) + rnd_r_delete_entry(layer->text_tree, (rnd_box_t *) text); + text->X = PCB_SWAP_X(text->X); + text->Y = PCB_SWAP_Y(text->Y) + y_offs; + PCB_FLAG_TOGGLE(PCB_FLAG_ONSOLDER, text); + pcb_text_bbox(pcb_font(PCB, text->fid, 1), text); + if (layer->text_tree != NULL) + rnd_r_insert_entry(layer->text_tree, (rnd_box_t *) text); +} + +void pcb_text_mirror_coords(pcb_text_t *text, rnd_coord_t y_offs, rnd_bool undoable) +{ + undo_text_geo_t gtmp, *g = >mp; + + if (undoable) g = pcb_undo_alloc(pcb_data_get_top(text->parent.layer->parent.data), &undo_text_geo, sizeof(undo_text_geo_t)); + + g->text = text; + g->X = PCB_SWAP_X(text->X); + g->Y = PCB_SWAP_Y(text->Y) + y_offs; + g->Scale = text->Scale; + g->scale_x = text->scale_x; g->scale_y = text->scale_y; + g->thickness = text->thickness; + g->clearance = text->clearance; + g->rot = text->rot; + + undo_text_geo_swap(g); + if (undoable) pcb_undo_inc_serial(); +} + +void pcb_text_scale(pcb_text_t *text, double sx, double sy, double sth) +{ + int onbrd = (text->parent.layer != NULL) && (!text->parent.layer->is_bound); + + if (onbrd) + pcb_text_pre(text); + + if (sx != 1.0) { + text->X = rnd_round((double)text->X * sx); + if (text->scale_x != 0) text->scale_x *= sx; + } + + if (sy != 1.0) { + text->Y = rnd_round((double)text->Y * sy); + if (text->scale_y != 0) text->scale_y *= sy; + } + + if ((sx != 1.0) || (sy != 1.0)) + text->Scale = rnd_round((double)text->Scale * (sy+sx)/2.0); + + if ((sth != 1.0) && (text->thickness > 0.0)) + text->thickness = rnd_round((double)text->thickness * sth); + + pcb_text_bbox(pcb_font(PCB, text->fid, 1), text); + if (onbrd) + pcb_text_post(text); +} + + +void pcb_text_set_font(pcb_text_t *text, pcb_font_id_t fid) +{ + pcb_layer_t *layer = text->parent.layer; + + assert(text->parent_type = PCB_PARENT_LAYER); + + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_TEXT, layer, text); + rnd_r_delete_entry(layer->text_tree, (rnd_box_t *) text); + text->fid = fid; + pcb_text_bbox(pcb_font(PCB, text->fid, 1), text); + rnd_r_insert_entry(layer->text_tree, (rnd_box_t *) text); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_TEXT, layer, text); +} + +void pcb_text_pre(pcb_text_t *text) +{ + pcb_layer_t *ly = pcb_layer_get_real(text->parent.layer); + if (ly == NULL) + return; + if (ly->text_tree != NULL) + rnd_r_delete_entry(ly->text_tree, (rnd_box_t *)text); + pcb_poly_restore_to_poly(ly->parent.data, PCB_OBJ_TEXT, ly, text); +} + +void pcb_text_post(pcb_text_t *text) +{ + pcb_layer_t *ly = pcb_layer_get_real(text->parent.layer); + if (ly == NULL) + return; + if (ly->text_tree != NULL) + rnd_r_insert_entry(ly->text_tree, (rnd_box_t *)text); + pcb_poly_clear_from_poly(ly->parent.data, PCB_OBJ_TEXT, ly, text); +} + + +void pcb_text_update(pcb_layer_t *layer, pcb_text_t *text) +{ + pcb_data_t *data = layer->parent.data; + pcb_board_t *pcb = pcb_data_get_top(data); + + if (pcb == NULL) + return; + + pcb_poly_restore_to_poly(data, PCB_OBJ_TEXT, layer, text); + rnd_r_delete_entry(layer->text_tree, (rnd_box_t *) text); + pcb_text_bbox(pcb_font(pcb, text->fid, 1), text); + rnd_r_insert_entry(layer->text_tree, (rnd_box_t *) text); + pcb_poly_clear_from_poly(data, PCB_OBJ_TEXT, layer, text); +} + +void pcb_text_flagchg_pre(pcb_text_t *Text, unsigned long flagbits, void **save) +{ + pcb_data_t *data = Text->parent.layer->parent.data; + + *save = NULL; + if ((flagbits & PCB_FLAG_CLEARLINE) || (flagbits & PCB_FLAG_ONSOLDER)) + pcb_poly_restore_to_poly(data, PCB_OBJ_TEXT, Text->parent.layer, Text); + if (flagbits & PCB_FLAG_ONSOLDER) { /* bbox will also change, need to do rtree administration */ + *save = Text->parent.layer; + rnd_r_delete_entry(Text->parent.layer->text_tree, (rnd_box_t *)Text); + } +} + +void pcb_text_flagchg_post(pcb_text_t *Text, unsigned long oldflagbits, void **save) +{ + pcb_data_t *data = Text->parent.layer->parent.data; + pcb_layer_t *orig_layer = *save; + unsigned long newflagbits = Text->Flags.f; + + if ((oldflagbits & PCB_FLAG_DYNTEXT) || (newflagbits & PCB_FLAG_DYNTEXT) || (orig_layer != NULL)) + pcb_text_bbox(pcb_font(PCB, Text->fid, 1), Text); + + if (orig_layer != NULL) + rnd_r_insert_entry(orig_layer->text_tree, (rnd_box_t *)Text); + + if ((newflagbits & PCB_FLAG_CLEARLINE) || (orig_layer != NULL)) + pcb_poly_clear_from_poly(data, PCB_OBJ_TEXT, Text->parent.layer, Text); + + *save = NULL; +} + +void *pcb_textop_change_flag(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text) +{ + void *save; + static pcb_flag_values_t pcb_text_flags = 0; + unsigned long oldflg = Text->Flags.f; + + if (pcb_text_flags == 0) + pcb_text_flags = pcb_obj_valid_flags(PCB_OBJ_TEXT); + + if ((ctx->chgflag.flag & pcb_text_flags) != ctx->chgflag.flag) + return NULL; + if ((ctx->chgflag.flag & PCB_FLAG_TERMNAME) && (Text->term == NULL)) + return NULL; + pcb_undo_add_obj_to_flag(Text); + + pcb_text_flagchg_pre(/*ctx->chgflag.pcb->Data, */Text, ctx->chgflag.flag, &save); + PCB_FLAG_CHANGE(ctx->chgflag.how, ctx->chgflag.flag, Text); + pcb_text_flagchg_post(Text, oldflg, &save); + + return Text; +} + +void *pcb_textop_invalidate_label(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_text_t *text) +{ + pcb_text_name_invalidate_draw(text); + return text; +} + +void pcb_text_dyn_bbox_update(pcb_data_t *data) +{ + PCB_TEXT_ALL_LOOP(data); { + if (PCB_FLAG_TEST(PCB_FLAG_DYNTEXT, text)) + pcb_text_update(layer, text); + } PCB_ENDALL_LOOP; +} + +int pcb_text_chg_scale(pcb_text_t *text, double scx, rnd_bool absx, double scy, rnd_bool absy, rnd_bool undoable) +{ + undo_text_geo_t gtmp, *g = >mp; + + if (undoable) g = pcb_undo_alloc(pcb_data_get_top(text->parent.layer->parent.data), &undo_text_geo, sizeof(undo_text_geo_t)); + + g->text = text; + g->X = text->X; + g->Y = text->Y; + g->Scale = text->Scale; + g->scale_x = absx ? scx : text->scale_x + scx; + g->scale_y = absy ? scy : text->scale_y + scy; + g->thickness = text->thickness; + g->clearance = text->clearance; + g->rot = text->rot; + + undo_text_geo_swap(g); + if (undoable) pcb_undo_inc_serial(); + + return 0; +} + +/*** draw ***/ + +#define MAX_SIMPLE_POLY_POINTS 256 +static void draw_text_poly(pcb_draw_info_t *info, pcb_poly_t *poly, pcb_xform_mx_t mx, rnd_coord_t xo, int xordraw, int thindraw, rnd_coord_t xordx, rnd_coord_t xordy, pcb_draw_text_cb cb, void *cb_ctx) +{ + rnd_coord_t x[MAX_SIMPLE_POLY_POINTS], y[MAX_SIMPLE_POLY_POINTS]; + int max, n; + rnd_point_t *p; + + max = poly->PointN; + if (max > MAX_SIMPLE_POLY_POINTS) { + max = MAX_SIMPLE_POLY_POINTS; + } + + /* transform each coordinate */ + for(n = 0, p = poly->Points; n < max; n++,p++) { + x[n] = rnd_round(pcb_xform_x(mx, p->X + xo, p->Y)); + y[n] = rnd_round(pcb_xform_y(mx, p->X + xo, p->Y)); + } + + if ((info != NULL) && (info->xform != NULL) && (info->xform->bloat != 0)) { + rnd_polo_t *p, pp[MAX_SIMPLE_POLY_POINTS]; + double a2, dv; + for(n = 0, p = pp; n < max; n++,p++) { + p->x = x[n]; + p->y = y[n]; + } + rnd_polo_norms(pp, max); + a2 = rnd_polo_2area(pp, max); + if (a2 < 0) + dv = -0.5; + else + dv = 0.5; + rnd_polo_offs(info->xform->bloat*dv, pp, max); + for(n = 0, p = pp; n < max; n++,p++) { + x[n] = rnd_round(p->x); + y[n] = rnd_round(p->y); + } + } + + if (cb != NULL) { + pcb_poly_t po; + rnd_point_t pt[MAX_SIMPLE_POLY_POINTS]; + + memset(&po, 0, sizeof(po)); + po.type = PCB_OBJ_POLY; + po.PointN = max; + po.Points = pt; + for(n = 0, p = po.Points; n < max; n++,p++) { + p->X = x[n]; + p->Y = y[n]; + } + + cb(cb_ctx, (pcb_any_obj_t *)&po); + return; + } + + + if (xordraw || thindraw) { + rnd_hid_gc_t gc = xordraw ? pcb_crosshair.GC : pcb_draw_out.fgGC; + for(n = 1, p = poly->Points+1; n < max; n++,p++) + rnd_render->draw_line(gc, xordx + x[n-1], xordy + y[n-1], xordx + x[n], xordy + y[n]); + rnd_render->draw_line(gc, xordx + x[0], xordy + y[0], xordx + x[max-1], xordy + y[max-1]); + } + else + rnd_render->fill_polygon(pcb_draw_out.fgGC, poly->PointN, x, y); +} + +/* Very rough estimation on the full width of the text */ +rnd_coord_t pcb_text_width(pcb_font_t *font, double scx, const unsigned char *string) +{ + rnd_coord_t w = 0; + const rnd_box_t *defaultsymbol; + if (string == NULL) + return 0; + defaultsymbol = &font->DefaultSymbol; + while(*string) { + /* draw lines if symbol is valid and data is present */ + if (*string <= PCB_MAX_FONTPOSITION && font->Symbol[*string].Valid) + w += (font->Symbol[*string].Width + font->Symbol[*string].Delta); + else + w += (defaultsymbol->X2 - defaultsymbol->X1) * 6 / 5; + string++; + } + return rnd_round((double)w * scx); +} + +rnd_coord_t pcb_text_height(pcb_font_t *font, double scy, const unsigned char *string) +{ + rnd_coord_t h; + if (string == NULL) + return 0; + h = font->MaxHeight; + while(*string != '\0') { + if (*string == '\n') + h += font->MaxHeight; + string++; + } + return rnd_round((double)h * scy); +} + + +RND_INLINE void cheap_text_line(rnd_hid_gc_t gc, pcb_xform_mx_t mx, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t xordx, rnd_coord_t xordy) +{ + rnd_coord_t tx1, ty1, tx2, ty2; + + tx1 = rnd_round(pcb_xform_x(mx, x1, y1)); + ty1 = rnd_round(pcb_xform_y(mx, x1, y1)); + tx2 = rnd_round(pcb_xform_x(mx, x2, y2)); + ty2 = rnd_round(pcb_xform_y(mx, x2, y2)); + + tx1 += xordx; + ty1 += xordy; + tx2 += xordx; + ty2 += xordy; + + rnd_render->draw_line(gc, tx1, ty1, tx2, ty2); +} + + +/* Decreased level-of-detail: draw only a few lines for the whole text */ +RND_INLINE int draw_text_cheap(pcb_font_t *font, pcb_xform_mx_t mx, const unsigned char *string, double scx, double scy, int xordraw, rnd_coord_t xordx, rnd_coord_t xordy, pcb_text_tiny_t tiny) +{ + rnd_coord_t w, h = rnd_round((double)font->MaxHeight * scy); + if (tiny == PCB_TXT_TINY_HIDE) { + if (h <= rnd_render->coord_per_pix*6) /* <= 6 pixel high: unreadable */ + return 1; + } + else if (tiny == PCB_TXT_TINY_CHEAP) { + if (h <= rnd_render->coord_per_pix*2) { /* <= 1 pixel high: draw a single line in the middle */ + w = pcb_text_width(font, scx, string); + if (xordraw) { + cheap_text_line(pcb_crosshair.GC, mx, 0, h/2, w, h/2, xordx, xordy); + } + else { + rnd_hid_set_line_width(pcb_draw_out.fgGC, -1); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_square); + cheap_text_line(pcb_draw_out.fgGC, mx, 0, h/2, w, h/2, 0, 0); + } + return 1; + } + else if (h <= rnd_render->coord_per_pix*4) { /* <= 4 pixel high: draw a mirrored Z-shape */ + w = pcb_text_width(font, scx, string); + if (xordraw) { + h /= 4; + cheap_text_line(pcb_crosshair.GC, mx, 0, h, w, h, xordx, xordy); + cheap_text_line(pcb_crosshair.GC, mx, 0, h, w, h*3, xordx, xordy); + cheap_text_line(pcb_crosshair.GC, mx, 0, h*3, w, h*3, xordx, xordy); + } + else { + h /= 4; + rnd_hid_set_line_width(pcb_draw_out.fgGC, -1); + rnd_hid_set_line_cap(pcb_draw_out.fgGC, rnd_cap_square); + cheap_text_line(pcb_draw_out.fgGC, mx, 0, h, w, h, 0, 0); + cheap_text_line(pcb_draw_out.fgGC, mx, 0, h, w, h*3, 0, 0); + cheap_text_line(pcb_draw_out.fgGC, mx, 0, h*3, w, h*3, 0, 0); + } + return 1; + } + } + return 0; +} + +RND_INLINE void pcb_text_draw_string_(pcb_draw_info_t *info, pcb_font_t *font, const unsigned char *string, rnd_coord_t x0, rnd_coord_t y0, double scx, double scy, double rotdeg, pcb_text_mirror_t mirror, rnd_coord_t thickness, rnd_coord_t min_line_width, int xordraw, rnd_coord_t xordx, rnd_coord_t xordy, pcb_text_tiny_t tiny, pcb_draw_text_cb cb, void *cb_ctx) +{ + rnd_coord_t x = 0; + rnd_cardinal_t n; + pcb_xform_mx_t mx = PCB_XFORM_MX_IDENT; + + pcb_xform_mx_translate(mx, x0, y0); + if (mirror != PCB_TXT_MIRROR_NO) + pcb_xform_mx_scale(mx, (mirror & PCB_TXT_MIRROR_X) ? -1 : 1, (mirror & PCB_TXT_MIRROR_Y) ? -1 : 1); + pcb_xform_mx_rotate(mx, rotdeg); + pcb_xform_mx_scale(mx, scx, scy); + + /* Text too small at this zoom level: cheap draw */ + if ((tiny != PCB_TXT_TINY_ACCURATE) && (cb == NULL)) { + if (draw_text_cheap(font, mx, string, scx, scy, xordraw, xordx, xordy, tiny)) + return; + } + + /* normal draw */ + while (string && *string) { + /* draw lines if symbol is valid and data is present */ + if (*string <= PCB_MAX_FONTPOSITION && font->Symbol[*string].Valid) { + pcb_line_t *line = font->Symbol[*string].Line; + pcb_line_t newline; + pcb_poly_t *p; + pcb_arc_t *a, newarc; + int poly_thin; + + for (n = font->Symbol[*string].LineN; n; n--, line++) { + /* create one line, scale, move, rotate and swap it */ + newline = *line; + newline.Point1.X = rnd_round(pcb_xform_x(mx, line->Point1.X+x, line->Point1.Y)); + newline.Point1.Y = rnd_round(pcb_xform_y(mx, line->Point1.X+x, line->Point1.Y)); + newline.Point2.X = rnd_round(pcb_xform_x(mx, line->Point2.X+x, line->Point2.Y)); + newline.Point2.Y = rnd_round(pcb_xform_y(mx, line->Point2.X+x, line->Point2.Y)); + newline.Thickness = rnd_round(newline.Thickness * (scx+scy) / 4.0); + + if (newline.Thickness < min_line_width) + newline.Thickness = min_line_width; + if (thickness > 0) + newline.Thickness = thickness; + if (cb != NULL) { + newline.type = PCB_OBJ_LINE; + cb(cb_ctx, (pcb_any_obj_t *)&newline); + } + else if (xordraw) + rnd_render->draw_line(pcb_crosshair.GC, xordx + newline.Point1.X, xordy + newline.Point1.Y, xordx + newline.Point2.X, xordy + newline.Point2.Y); + else + pcb_line_draw_(info, &newline, 0); + } + + /* draw the arcs */ + for(a = arclist_first(&font->Symbol[*string].arcs); a != NULL; a = arclist_next(a)) { + newarc = *a; + + newarc.X = rnd_round(pcb_xform_x(mx, a->X + x, a->Y)); + newarc.Y = rnd_round(pcb_xform_y(mx, a->X + x, a->Y)); + newarc.Height = newarc.Width = rnd_round(newarc.Height * scx); + newarc.Thickness = rnd_round(newarc.Thickness * (scx+scy) / 4.0); + newarc.StartAngle += rotdeg; + if (mirror) { + newarc.StartAngle = RND_SWAP_ANGLE(newarc.StartAngle); + newarc.Delta = RND_SWAP_DELTA(newarc.Delta); + } + if (newarc.Thickness < min_line_width) + newarc.Thickness = min_line_width; + if (thickness > 0) + newarc.Thickness = thickness; + if (cb != NULL) { + newarc.type = PCB_OBJ_ARC; + cb(cb_ctx, (pcb_any_obj_t *)&newarc); + } + else if (xordraw) + rnd_render->draw_arc(pcb_crosshair.GC, xordx + newarc.X, xordy + newarc.Y, newarc.Width, newarc.Height, newarc.StartAngle, newarc.Delta); + else + pcb_arc_draw_(info, &newarc, 0); + } + + /* draw the polygons */ + poly_thin = info->xform->thin_draw || info->xform->wireframe; + for(p = polylist_first(&font->Symbol[*string].polys); p != NULL; p = polylist_next(p)) + draw_text_poly(info, p, mx, x, xordraw, poly_thin, xordx, xordy, cb, cb_ctx); + + /* move on to next cursor position */ + x += (font->Symbol[*string].Width + font->Symbol[*string].Delta); + } + else { + /* the default symbol is a filled box */ + rnd_coord_t size = (font->DefaultSymbol.X2 - font->DefaultSymbol.X1) * 6 / 5; + rnd_coord_t px[4], py[4]; + + px[0] = rnd_round(pcb_xform_x(mx, font->DefaultSymbol.X1 + x, font->DefaultSymbol.Y1)); + py[0] = rnd_round(pcb_xform_y(mx, font->DefaultSymbol.X1 + x, font->DefaultSymbol.Y1)); + px[1] = rnd_round(pcb_xform_x(mx, font->DefaultSymbol.X2 + x, font->DefaultSymbol.Y1)); + py[1] = rnd_round(pcb_xform_y(mx, font->DefaultSymbol.X2 + x, font->DefaultSymbol.Y1)); + px[2] = rnd_round(pcb_xform_x(mx, font->DefaultSymbol.X2 + x, font->DefaultSymbol.Y2)); + py[2] = rnd_round(pcb_xform_y(mx, font->DefaultSymbol.X2 + x, font->DefaultSymbol.Y2)); + px[3] = rnd_round(pcb_xform_x(mx, font->DefaultSymbol.X1 + x, font->DefaultSymbol.Y2)); + py[3] = rnd_round(pcb_xform_y(mx, font->DefaultSymbol.X1 + x, font->DefaultSymbol.Y2)); + + /* draw move on to next cursor position */ + if ((cb == NULL) && (xordraw || (info->xform->thin_draw || info->xform->wireframe))) { + if (xordraw) { + rnd_render->draw_line(pcb_crosshair.GC, px[0] + xordx, py[0] + xordy, px[1] + xordx, py[1] + xordy); + rnd_render->draw_line(pcb_crosshair.GC, px[1] + xordx, py[1] + xordy, px[2] + xordx, py[2] + xordy); + rnd_render->draw_line(pcb_crosshair.GC, px[2] + xordx, py[2] + xordy, px[3] + xordx, py[3] + xordy); + rnd_render->draw_line(pcb_crosshair.GC, px[3] + xordx, py[3] + xordy, px[0] + xordx, py[0] + xordy); + } + else { + rnd_render->draw_line(pcb_draw_out.fgGC, px[0], py[0], px[1], py[1]); + rnd_render->draw_line(pcb_draw_out.fgGC, px[1], py[1], px[2], py[2]); + rnd_render->draw_line(pcb_draw_out.fgGC, px[2], py[2], px[3], py[3]); + rnd_render->draw_line(pcb_draw_out.fgGC, px[3], py[3], px[0], py[0]); + } + } + else { + if (cb != NULL) { + pcb_poly_t po; + rnd_point_t pt[4], *p; + + memset(&po, 0, sizeof(po)); + po.type = PCB_OBJ_POLY; + po.PointN = 4; + po.Points = pt; + for(n = 0, p = po.Points; n < po.PointN; n++,p++) { + p->X = px[n]; + p->Y = py[n]; + } + cb(cb_ctx, (pcb_any_obj_t *)&po); + } + else + rnd_render->fill_polygon(pcb_draw_out.fgGC, 4, px, py); + } + x += size; + } + string++; + } +} + +void pcb_text_draw_string(pcb_draw_info_t *info, pcb_font_t *font, const unsigned char *string, rnd_coord_t x0, rnd_coord_t y0, double scx, double scy, double rotdeg, pcb_text_mirror_t mirror, rnd_coord_t thickness, rnd_coord_t min_line_width, int xordraw, rnd_coord_t xordx, rnd_coord_t xordy, pcb_text_tiny_t tiny) +{ + pcb_text_draw_string_(info, font, string, x0, y0, scx, scy, rotdeg, mirror, thickness, min_line_width, xordraw, xordx, xordy, tiny, NULL, NULL); +} + +void pcb_text_draw_string_simple(pcb_font_t *font, const char *string, rnd_coord_t x0, rnd_coord_t y0, double scx, double scy, double rotdeg, pcb_text_mirror_t mirror, rnd_coord_t thickness, int xordraw, rnd_coord_t xordx, rnd_coord_t xordy) +{ + static rnd_xform_t xform = {0}; + static pcb_draw_info_t info = {0}; + + info.xform = &xform; + if (font == NULL) + font = pcb_font(PCB, 0, 0); + + pcb_text_draw_string_(&info, font, (const unsigned char *)string, x0, y0, scx, scy, rotdeg, mirror, thickness, 0, xordraw, xordx, xordy, PCB_TXT_TINY_CHEAP, NULL, NULL); +} + + +void pcb_text_decompose_string(pcb_draw_info_t *info, pcb_font_t *font, const unsigned char *string, rnd_coord_t x0, rnd_coord_t y0, double scx, double scy, double rotdeg, pcb_text_mirror_t mirror, rnd_coord_t thickness, pcb_draw_text_cb cb, void *cb_ctx) +{ + pcb_text_draw_string_(info, font, string, x0, y0, scx, scy, rotdeg, mirror, thickness, 0, 0, 0, 0, PCB_TXT_TINY_ACCURATE, cb, cb_ctx); +} + +void pcb_text_decompose_text(pcb_draw_info_t *info, pcb_text_t *text, pcb_draw_text_cb cb, void *cb_ctx) +{ + unsigned char *rendered = pcb_text_render_str(text); + double scx, scy; + pcb_text_get_scale_xy(text, &scx, &scy); + pcb_text_decompose_string(info, pcb_font(PCB, text->fid, 1), rendered, text->X, text->Y, scx, scy, text->rot, text_mirror_bits(text), text->thickness, cb, cb_ctx); + pcb_text_free_str(text, rendered); +} + + +/* lowlevel drawing routine for text objects */ +static void DrawTextLowLevel_(pcb_draw_info_t *info, pcb_text_t *Text, rnd_coord_t min_line_width, int xordraw, rnd_coord_t xordx, rnd_coord_t xordy, pcb_text_tiny_t tiny) +{ + unsigned char *rendered = pcb_text_render_str(Text); + double scx, scy; + pcb_text_get_scale_xy(Text, &scx, &scy); + pcb_text_draw_string_(info, pcb_font(PCB, Text->fid, 1), rendered, Text->X, Text->Y, scx, scy, Text->rot, text_mirror_bits(Text), Text->thickness, min_line_width, xordraw, xordx, xordy, tiny, NULL, NULL); + pcb_text_free_str(Text, rendered); +} + +static rnd_bool is_text_term_vert(const pcb_text_t *text) +{ + rnd_coord_t dx, dy; + + dx = text->BoundingBox.X2 - text->BoundingBox.X1; + if (dx < 0) + dx = -dx; + + dy = text->BoundingBox.Y2 - text->BoundingBox.Y1; + if (dy < 0) + dy = -dy; + + return dx < dy; +} + + +void pcb_text_name_invalidate_draw(pcb_text_t *text) +{ + if (text->term != NULL) + pcb_term_label_invalidate((text->BoundingBox.X1 + text->BoundingBox.X2)/2, (text->BoundingBox.Y1 + text->BoundingBox.Y2)/2, + 100.0, is_text_term_vert(text), rnd_true, (pcb_any_obj_t *)text); +} + +void pcb_text_draw_label(pcb_draw_info_t *info, pcb_text_t *text, rnd_bool vis_side) +{ + if ((text->term != NULL) && vis_side) + pcb_term_label_draw(info, (text->BoundingBox.X1 + text->BoundingBox.X2)/2, (text->BoundingBox.Y1 + text->BoundingBox.Y2)/2, + conf_core.appearance.term_label_size, is_text_term_vert(text), rnd_true, (pcb_any_obj_t *)text); + if (text->noexport && vis_side) + pcb_obj_noexport_mark(text, (text->BoundingBox.X1 + text->BoundingBox.X2)/2, (text->BoundingBox.Y1 + text->BoundingBox.Y2)/2); +} + + +void pcb_text_draw_(pcb_draw_info_t *info, pcb_text_t *text, rnd_coord_t min_line_width, int allow_term_gfx, pcb_text_tiny_t tiny) +{ + if (delayed_terms_enabled && (text->term != NULL)) { + pcb_draw_delay_obj_add((pcb_any_obj_t *)text); + return; + } + + DrawTextLowLevel_(info, text, min_line_width, 0, 0, 0, tiny); + + if (text->term != NULL) { + if ((allow_term_gfx) && ((pcb_draw_force_termlab) || PCB_FLAG_TEST(PCB_FLAG_TERMNAME, text))) + pcb_draw_delay_label_add((pcb_any_obj_t *)text); + } +} + +static void pcb_text_draw(pcb_draw_info_t *info, pcb_text_t *text, int allow_term_gfx) +{ + int min_silk_line; + unsigned int flg = 0; + const pcb_layer_t *layer = info->layer != NULL ? info->layer : pcb_layer_get_real(text->parent.layer); + + pcb_obj_noexport(info, text, return); + + if (layer == NULL) /* if the layer is inbound, e.g. in preview, fall back using the layer recipe */ + layer = text->parent.layer; + + if (info->xform->flag_color && PCB_FLAG_TEST(PCB_FLAG_SELECTED, text)) { + if (layer->is_bound) { + const rnd_color_t *color; + PCB_OBJ_COLOR_ON_BOUND_LAYER(color, layer, 1); + rnd_render->set_color(pcb_draw_out.fgGC, color); + } + else + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.selected); + } + else if (info->xform->flag_color && PCB_HAS_COLOROVERRIDE(text)) { + rnd_render->set_color(pcb_draw_out.fgGC, text->override_color); + } + else if (layer->is_bound) { + const rnd_color_t *color; + PCB_OBJ_COLOR_ON_BOUND_LAYER(color, layer, 0); + rnd_render->set_color(pcb_draw_out.fgGC, color); + } + else + rnd_render->set_color(pcb_draw_out.fgGC, &layer->meta.real.color); + + if ((!layer->is_bound) && (layer->meta.real.grp >= 0)) + flg = pcb_layergrp_flags(PCB, layer->meta.real.grp); + + if (flg & PCB_LYT_SILK) + min_silk_line = conf_core.design.min_slk; + else + min_silk_line = conf_core.design.min_wid; + + pcb_text_draw_(info, text, min_silk_line, allow_term_gfx, PCB_TXT_TINY_CHEAP); +} + +rnd_r_dir_t pcb_text_draw_callback(const rnd_box_t * b, void *cl) +{ + pcb_text_t *text = (pcb_text_t *) b; + pcb_draw_info_t *info = cl; + + if (pcb_hidden_floater((pcb_any_obj_t*)b, info) || pcb_partial_export((pcb_any_obj_t*)b, info)) + return RND_R_DIR_FOUND_CONTINUE; + + if (!PCB->SubcPartsOn && pcb_lobj_parent_subc(text->parent_type, &text->parent)) + return RND_R_DIR_FOUND_CONTINUE; + + pcb_text_draw(info, text, 0); + return RND_R_DIR_FOUND_CONTINUE; +} + +rnd_r_dir_t pcb_text_draw_term_callback(const rnd_box_t * b, void *cl) +{ + pcb_text_t *text = (pcb_text_t *) b; + pcb_draw_info_t *info = cl; + + if (pcb_hidden_floater((pcb_any_obj_t*)b, info) || pcb_partial_export((pcb_any_obj_t*)b, info)) + return RND_R_DIR_FOUND_CONTINUE; + + if (!PCB->SubcPartsOn && pcb_lobj_parent_subc(text->parent_type, &text->parent)) + return RND_R_DIR_FOUND_CONTINUE; + + pcb_text_draw(info, text, 1); + return RND_R_DIR_FOUND_CONTINUE; +} + +/* erases a text on a layer */ +void pcb_text_invalidate_erase(pcb_layer_t *Layer, pcb_text_t *Text) +{ + pcb_draw_invalidate(Text); +} + +void pcb_text_invalidate_draw(pcb_layer_t *Layer, pcb_text_t *Text) +{ + pcb_draw_invalidate(Text); +} + +static pcb_draw_info_t txor_info; +static rnd_xform_t txor_xform; + +void pcb_text_draw_xor(pcb_text_t *text, rnd_coord_t x, rnd_coord_t y, rnd_bool want_box) +{ + txor_info.xform = &txor_xform; + DrawTextLowLevel_(&txor_info, text, 0, 1, x, y, PCB_TXT_TINY_CHEAP); + if (want_box && (conf_core.appearance.text_host_bbox) && (text->BoundingBox.X1 != text->BoundingBox.X2)) { + rnd_render->draw_line(pcb_crosshair.GC, x + text->BoundingBox.X1, y + text->BoundingBox.Y1, x + text->BoundingBox.X1, y + text->BoundingBox.Y2); + rnd_render->draw_line(pcb_crosshair.GC, x + text->BoundingBox.X1, y + text->BoundingBox.Y1, x + text->BoundingBox.X2, y + text->BoundingBox.Y1); + rnd_render->draw_line(pcb_crosshair.GC, x + text->BoundingBox.X2, y + text->BoundingBox.Y2, x + text->BoundingBox.X1, y + text->BoundingBox.Y2); + rnd_render->draw_line(pcb_crosshair.GC, x + text->BoundingBox.X2, y + text->BoundingBox.Y2, x + text->BoundingBox.X2, y + text->BoundingBox.Y1); + } +} + +/*** init ***/ +static const char *text_cookie = "obj_text"; + +/* Recursively update the text objects of data and subcircuits; returns non-zero + if a redraw is needed */ +static int pcb_text_font_chg_data(pcb_data_t *data, pcb_font_id_t fid) +{ + int need_redraw = 0; + + LAYER_LOOP(data, data->LayerN); { + PCB_TEXT_LOOP(layer); { + if (text->fid == fid) { + pcb_text_update(layer, text); + need_redraw = 1; + } + } PCB_END_LOOP; + } PCB_END_LOOP; + + PCB_SUBC_LOOP(data); { + int chg = pcb_text_font_chg_data(subc->data, fid); + if (chg) { + need_redraw = 1; + rnd_r_delete_entry(data->subc_tree, (rnd_box_t *)subc); + pcb_subc_bbox(subc); + rnd_r_insert_entry(data->subc_tree, (rnd_box_t *)subc); + } + } PCB_END_LOOP; + + return need_redraw; +} + +static void pcb_text_font_chg(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + + if ((argc < 2) || (argv[1].type != RND_EVARG_INT)) + return; + + if (pcb_text_font_chg_data(PCB->Data, argv[1].d.i)) + rnd_gui->invalidate_all(rnd_gui); /* can't just redraw the text, as the old text may have been bigger, before the change! */ + + rnd_trace("font change %d\n", argv[1].d.i); +} + +rnd_bool pcb_text_old_direction(int *dir_out, double rot) +{ + double r; + + r = fmod(rot, 90.0); + + if (dir_out != NULL) { + int d = rnd_round(rot / 90); + if (d < 0) + d += 4; + *dir_out = d; + } + + return (r <= 0.5); +} + +void pcb_text_init(void) +{ + rnd_event_bind(PCB_EVENT_FONT_CHANGED, pcb_text_font_chg, NULL, text_cookie); +} + +void pcb_text_uninit(void) +{ + rnd_event_unbind_allcookie(text_cookie); +} Index: tags/2.3.0/src/obj_text.h =================================================================== --- tags/2.3.0/src/obj_text.h (nonexistent) +++ tags/2.3.0/src/obj_text.h (revision 33253) @@ -0,0 +1,183 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Drawing primitive: text */ + +#ifndef PCB_OBJ_TEXT_H +#define PCB_OBJ_TEXT_H + +#include "obj_common.h" +#include "font.h" +#include + +struct pcb_text_s { + PCB_ANY_PRIMITIVE_FIELDS; + int Scale; /* text scaling in percent */ + double scale_x, scale_y; /* optional; x and y direction scale (1 means original size); if 0, use Scale/100 */ + rnd_coord_t X, Y; /* origin */ + pcb_font_id_t fid; + char *TextString; /* string */ + rnd_coord_t thickness; /* if non-zero, thickness of line/arc within the font */ + rnd_coord_t clearance; /* clearance around the object in polygon if flags have PCB_FLAG_CLEARLINE */ + double rot; /* used when Direction is PCB_TEXT_FREEROT */ + unsigned tight_clearance:1; /* CACHED from attribute: when true, clearance is calculated to follow the true contour of the text; when false, the old, pre-v7 bbox based clearance is applied */ + unsigned mirror_x:1; /* CACHED from attribute: when true, mirror X coords (mirror over the Y axis) */ + gdl_elem_t link; /* a text is in a list of a layer */ +}; + +typedef enum { /* bitfield - order matters for backward compatibility */ + PCB_TXT_MIRROR_NO = 0, + PCB_TXT_MIRROR_Y = 1, /* change Y coords (mirror over the X axis) */ + PCB_TXT_MIRROR_X = 2 /* change X coords (mirror over the Y axis) */ +} pcb_text_mirror_t; + +/* These need to be carefully written to avoid overflows, and return + a Coord type. */ +#define PCB_SCALE_TEXT(COORD,TEXTSCALE) ((rnd_coord_t)rnd_round((COORD) * ((double)(TEXTSCALE) / 100.0))) +#define PCB_UNPCB_SCALE_TEXT(COORD,TEXTSCALE) ((rnd_coord_t)rnd_round((COORD) * (100.0 / (double)(TEXTSCALE)))) + +/* Determine what the Scale value would have been in the old, Scale only + setup and store it in scale_out. Useful for compatibility saves. Returns + 0 on succes, -1 on error (with a best effort estimation left in scale_out) */ +int pcb_text_old_scale(pcb_text_t *text, int *scale_out); + +pcb_text_t *pcb_text_alloc(pcb_layer_t * layer); +pcb_text_t *pcb_text_alloc_id(pcb_layer_t *layer, long int id); +void pcb_text_free(pcb_text_t * data); +pcb_text_t *pcb_text_new(pcb_layer_t *Layer, pcb_font_t *PCBFont, rnd_coord_t X, rnd_coord_t Y, double rot, int Scale, rnd_coord_t thickness, const char *TextString, pcb_flag_t Flags); +pcb_text_t *pcb_text_dup(pcb_layer_t *dst, pcb_text_t *src); +pcb_text_t *pcb_text_dup_at(pcb_layer_t *dst, pcb_text_t *src, rnd_coord_t dx, rnd_coord_t dy); +void *pcb_text_destroy(pcb_layer_t *Layer, pcb_text_t *Text); + +/* creates the text object on the layer without rtree or poly clipping administration */ +pcb_text_t *pcb_text_new_(pcb_layer_t *Layer, pcb_font_t *PCBFont, rnd_coord_t X, rnd_coord_t Y, double rot, pcb_text_mirror_t mirror, int Scale, double scx, double scy, rnd_coord_t thickness, const char *TextString, pcb_flag_t Flags); + +/* Create new text by bounding box: bbw and bbw are the expected bounding box + width and height, scxy is the expected text width/height ratio; place the + text by grabbing at anchor point anchx;anchy on the original bbox. The resulting + text will typically be smaller than the input bounding box, with wither + bbox width or bbox height matching the original, but text aspect ratio kept + and anchor point placed at X;Y. */ +pcb_text_t *pcb_text_new_by_bbox(pcb_layer_t *Layer, pcb_font_t *PCBFont, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t bbw, rnd_coord_t bbh, rnd_coord_t anchx, rnd_coord_t anchy, double scxy, pcb_text_mirror_t mirror, double rot, rnd_coord_t thickness, const char *TextString, pcb_flag_t Flags); + + +/* Add objects without creating them or making any "sanity modifications" to them */ +void pcb_add_text_on_layer(pcb_layer_t *Layer, pcb_text_t *text, pcb_font_t *PCBFont); + +void pcb_text_bbox(pcb_font_t *FontPtr, pcb_text_t *Text); +void pcb_text_rotate90(pcb_text_t *Text, rnd_coord_t X, rnd_coord_t Y, unsigned Number); +void pcb_text_rotate(pcb_text_t *Text, rnd_coord_t X, rnd_coord_t Y, double cosa, double sina, double rotdeg); +void pcb_text_scale(pcb_text_t *text, double sx, double sy, double sth); +void pcb_text_flip_side(pcb_layer_t *layer, pcb_text_t *text, rnd_coord_t y_offs, rnd_bool undoable); +void pcb_text_mirror_coords(pcb_text_t *text, rnd_coord_t y_offs, rnd_bool undoable); /* mirror the coords but do not mirror the text itself (no on-solder) */ +void pcb_text_set_font(pcb_text_t *text, pcb_font_id_t fid); +void pcb_text_update(pcb_layer_t *layer, pcb_text_t *text); + +void pcb_text_reg(pcb_layer_t *layer, pcb_text_t *text); +void pcb_text_unreg(pcb_text_t *text); + +void pcb_text_pre(pcb_text_t *text); +void pcb_text_post(pcb_text_t *text); + +/* Before and after a flag change on text, call these; flagbits should + be the new bits we are changing to; save should be the + address of a local (void *) cache. The calls make sure bbox and rtree + administration are done properly */ +void pcb_text_flagchg_pre(pcb_text_t *Text, unsigned long flagbits, void **save); +void pcb_text_flagchg_post(pcb_text_t *Text, unsigned long oldflagbits, void **save); + +/* Low level draw call for direct rendering on preview */ +void pcb_text_draw_string_simple(pcb_font_t *font, const char *string, rnd_coord_t x0, rnd_coord_t y0, double scx, double scy, double rotdeg, pcb_text_mirror_t mirror, rnd_coord_t thickness, int xordraw, rnd_coord_t xordx, rnd_coord_t xordy); + +/* Recalculate the bounding box of all dynamic text objects that are + directly under data - useful e.g. on parent attr change */ +void pcb_text_dyn_bbox_update(pcb_data_t *data); + +/* Return the old direction value (n*90 deg rotation) for text rotation value. + Returns false if has a rounding error greater than 0.5 deg */ +rnd_bool pcb_text_old_direction(int *dir_out, double rot); + +/* hash and eq */ +int pcb_text_eq(const pcb_host_trans_t *tr1, const pcb_text_t *t1, const pcb_host_trans_t *tr2, const pcb_text_t *t2); +unsigned int pcb_text_hash(const pcb_host_trans_t *tr, const pcb_text_t *t); + +/* Append dyntext fmt rendered from the perspective of obj */ +int pcb_append_dyntext(gds_t *dst, const pcb_any_obj_t *obj, const char *fmt); + +void pcb_text_init(void); +void pcb_text_uninit(void); + +#define pcb_text_move(t,dx,dy) \ + do { \ + rnd_coord_t __dx__ = (dx), __dy__ = (dy); \ + pcb_text_t *__t__ = (t); \ + RND_BOX_MOVE_LOWLEVEL(&((__t__)->BoundingBox), __dx__, __dy__); \ + RND_BOX_MOVE_LOWLEVEL(&((__t__)->bbox_naked), __dx__, __dy__); \ + RND_MOVE_POINT((__t__)->X, (__t__)->Y, __dx__, __dy__); \ + } while(0) + +/* Determines if text is actually visible */ +#define pcb_text_is_visible(b, l, t) ((l)->meta.real.vis) + +#define PCB_TEXT_LOOP(layer) do { \ + pcb_text_t *text; \ + gdl_iterator_t __it__; \ + textlist_foreach(&(layer)->Text, &__it__, text) { + +#define PCB_TEXT_ALL_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + PCB_TEXT_LOOP(layer) + +#define PCB_TEXT_COPPER_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (!(pcb_layer_flags(PCB, l) & PCB_LYT_COPPER)) continue; \ + PCB_TEXT_LOOP(layer) + +#define PCB_SILK_COPPER_LOOP(top) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (top)->Layer; \ + for (l = 0; l < ((top)->LayerN > 0 ? (top)->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + if (!(pcb_layer_flags(PCB, l) & PCB_LYT_SILK)) continue; \ + PCB_TEXT_LOOP(layer) + +#define PCB_TEXT_VISIBLE_LOOP(board) do { \ + rnd_cardinal_t l; \ + pcb_layer_t *layer = (board)->Data->Layer; \ + for (l = 0; l < ((board)->Data->LayerN > 0 ? (board)->Data->LayerN : PCB->Data->LayerN); l++, layer++) \ + { \ + PCB_TEXT_LOOP(layer); \ + if (pcb_text_is_visible((board), layer, text)) + +#endif Index: tags/2.3.0/src/obj_text_draw.h =================================================================== --- tags/2.3.0/src/obj_text_draw.h (nonexistent) +++ tags/2.3.0/src/obj_text_draw.h (revision 33253) @@ -0,0 +1,65 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard draw of text ***/ + +#include "draw.h" + +/* Include rtree.h for these */ +#ifdef RND_RTREE_H +rnd_r_dir_t pcb_text_draw_callback(const rnd_box_t * b, void *cl); +rnd_r_dir_t pcb_text_draw_term_callback(const rnd_box_t * b, void *cl); +#endif + +typedef enum pcb_text_tiny_e { /* How to draw text that is too tiny to be readable */ + PCB_TXT_TINY_HIDE, /* do not draw it at all */ + PCB_TXT_TINY_CHEAP, /* draw a cheaper, simplified approximation that shows there's something there */ + PCB_TXT_TINY_ACCURATE /* always draw text accurately, even if it will end up unreadable */ +} pcb_text_tiny_t; + +void pcb_text_draw_(pcb_draw_info_t *info, pcb_text_t *Text, rnd_coord_t min_line_width, int allow_term_gfx, pcb_text_tiny_t tiny); +void pcb_text_invalidate_erase(pcb_layer_t *Layer, pcb_text_t *Text); +void pcb_text_invalidate_draw(pcb_layer_t *Layer, pcb_text_t *Text); +void pcb_text_draw_xor(pcb_text_t *text, rnd_coord_t x, rnd_coord_t y, rnd_bool want_box); +void pcb_text_name_invalidate_draw(pcb_text_t *txt); +void pcb_text_draw_label(pcb_draw_info_t *info, pcb_text_t *text, rnd_bool vis_side); + +/* lowlevel drawing routine for text strings */ +void pcb_text_draw_string(pcb_draw_info_t *info, pcb_font_t *font, const unsigned char *string, rnd_coord_t x0, rnd_coord_t y0, double scx, double scy, double rotdeg, pcb_text_mirror_t mirror, rnd_coord_t thickness, rnd_coord_t min_line_width, int xordraw, rnd_coord_t xordx, rnd_coord_t xordy, pcb_text_tiny_t tiny); + +/* lowlevel text bounding box calculation */ +rnd_coord_t pcb_text_width(pcb_font_t *font, double scx, const unsigned char *string); +rnd_coord_t pcb_text_height(pcb_font_t *font, double scy, const unsigned char *string); + +/* Call cb(ctx, ...) for every object in a rendered string or text; obj will + be disacrded after the call, can be modified by the callback */ +typedef void (*pcb_draw_text_cb)(void *ctx, pcb_any_obj_t *obj); +void pcb_text_decompose_string(pcb_draw_info_t *info, pcb_font_t *font, const unsigned char *string, rnd_coord_t x0, rnd_coord_t y0, double scx, double scy, double rotdeg, pcb_text_mirror_t mirror, rnd_coord_t thickness, pcb_draw_text_cb cb, void *cb_ctx); +void pcb_text_decompose_text(pcb_draw_info_t *info, pcb_text_t *text, pcb_draw_text_cb cb, void *cb_ctx); + Index: tags/2.3.0/src/obj_text_list.c =================================================================== --- tags/2.3.0/src/obj_text_list.c (nonexistent) +++ tags/2.3.0/src/obj_text_list.c (revision 33253) @@ -0,0 +1,34 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Include these before TDL_DONT_UNDEF to avoid TDL redefs */ +#include "obj_poly_list.h" +#include "obj_arc_list.h" + +#define TDL_DONT_UNDEF +#include "obj_text_list.h" +#include Index: tags/2.3.0/src/obj_text_list.h =================================================================== --- tags/2.3.0/src/obj_text_list.h (nonexistent) +++ tags/2.3.0/src/obj_text_list.h (revision 33253) @@ -0,0 +1,47 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_OBJ_TEXT_LIST_H +#define PCB_OBJ_TEXT_LIST_H + +#include "obj_text.h" + +/* List of Text */ +#define TDL(x) textlist_ ## x +#define TDL_LIST_T textlist_t +#define TDL_ITEM_T pcb_text_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define textlist_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + + +#include +#include + +#endif Index: tags/2.3.0/src/obj_text_op.h =================================================================== --- tags/2.3.0/src/obj_text_op.h (nonexistent) +++ tags/2.3.0/src/obj_text_op.h (revision 33253) @@ -0,0 +1,57 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/*** Standard operations on text ***/ + +#include "operation.h" + +void *pcb_textop_add_to_buffer(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_move_buffer(pcb_opctx_t *ctx, pcb_layer_t * layer, pcb_text_t * text); +void *pcb_textop_change_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_change_2nd_size(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_change_rot(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_change_name(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_change_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_set_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_clear_join(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_copy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_move(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_move_noclip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_clip(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_move_to_layer_low(pcb_opctx_t *ctx, pcb_layer_t * Source, pcb_text_t * text, pcb_layer_t * Destination); +void *pcb_textop_move_to_layer(pcb_opctx_t *ctx, pcb_layer_t * layer, pcb_text_t * text); +void *pcb_textop_destroy(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_remove(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_rotate90(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_rotate(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_change_flag(pcb_opctx_t *ctx, pcb_layer_t *Layer, pcb_text_t *Text); +void *pcb_textop_invalidate_label(pcb_opctx_t *ctx, pcb_layer_t *layer, pcb_text_t *text); + + +/* undoable scale_x and scale_y change */ +int pcb_text_chg_scale(pcb_text_t *text, double scx, rnd_bool absx, double scy, rnd_bool absy, rnd_bool undoable); Index: tags/2.3.0/src/object_act.c =================================================================== --- tags/2.3.0/src/object_act.c (nonexistent) +++ tags/2.3.0/src/object_act.c (revision 33253) @@ -0,0 +1,1124 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" + +#include "conf_core.h" +#include + +#include "data.h" +#include "board.h" +#include +#include "change.h" +#include +#include "undo.h" +#include "event.h" +#include "funchash_core.h" +#include + +#include "search.h" +#include "draw.h" +#include "move.h" +#include "remove.h" +#include "actions_pcb.h" +#include +#include "layer_vis.h" +#include "operation.h" +#include "obj_pstk.h" +#include "rotate.h" +#include +#include "view.h" + +static const char pcb_acts_DisperseElements[] = "DisperseElements(All|Selected)"; +static const char pcb_acth_DisperseElements[] = "Disperses subcircuits."; + +#define GAP RND_MIL_TO_COORD(100) + +/* DOC: disperseelements.html */ + +static void disperse_obj(pcb_board_t *pcb, pcb_any_obj_t *obj, rnd_coord_t ox, rnd_coord_t oy, rnd_coord_t *dx, rnd_coord_t *dy, rnd_coord_t *minx, rnd_coord_t *miny, rnd_coord_t *maxy) +{ + rnd_coord_t newx2, newy2; + + /* If we want to disperse selected objects, maybe we need smarter + code here to avoid putting components on top of others which + are not selected. For now, I'm assuming that this is typically + going to be used either with a brand new design or a scratch + design holding some new components */ + + /* figure out how much to move the object */ + *dx = *minx - obj->BoundingBox.X1; + + /* snap to the grid */ + *dx -= (ox + *dx) % pcb->hidlib.grid; + + /* and add one grid size so we make sure we always space by GAP or more */ + *dx += pcb->hidlib.grid; + + /* Figure out if this row has room. If not, start a new row */ + if (GAP + obj->BoundingBox.X2 + *dx > pcb->hidlib.size_x) { + *miny = *maxy + GAP; + *minx = GAP; + } + + /* figure out how much to move the object */ + *dx = *minx - obj->BoundingBox.X1; + *dy = *miny - obj->BoundingBox.Y1; + + /* snap to the grid */ + *dx -= (ox + *dx) % pcb->hidlib.grid; + *dx += pcb->hidlib.grid; + *dy -= (oy + *dy) % pcb->hidlib.grid; + *dy += pcb->hidlib.grid; + + /* new X2 and Y2 coords with snapping considered */ + newx2 = obj->BoundingBox.X2 + *dx; + newy2 = obj->BoundingBox.Y2 + *dy; + + /* keep track of how tall this row is */ + *minx = newx2 + GAP; + if (*maxy < newy2) { + *maxy = newy2; + if (*maxy > pcb->hidlib.size_y - GAP) { + *maxy = GAP; + rnd_message(RND_MSG_WARNING, "The board is too small for hosting all subcircuits,\ndiesperse restarted from the top.\nExpect overlapping subcircuits\n"); + } + } +} + +static fgw_error_t pcb_act_DisperseElements(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + rnd_coord_t minx = GAP, miny = GAP, maxy = GAP, dx, dy; + int all = 0, id; + + RND_ACT_CONVARG(1, FGW_KEYWORD, DisperseElements, id = fgw_keyword(&argv[1])); + RND_ACT_IRES(0); + + switch(id) { + case F_All: all = 1; break; + case F_Selected: all = 0; break; + default: RND_ACT_FAIL(DisperseElements); + } + + pcb_draw_inhibit_inc(); + PCB_SUBC_LOOP(pcb->Data); + { + if (!PCB_FLAG_TEST(PCB_FLAG_LOCK, subc) && (all || PCB_FLAG_TEST(PCB_FLAG_SELECTED, subc))) { + rnd_coord_t ox, oy; + if (pcb_subc_get_origin(subc, &ox, &oy) != 0) { + ox = (subc->BoundingBox.X1 + subc->BoundingBox.X2)/2; + oy = (subc->BoundingBox.Y1 + subc->BoundingBox.Y2)/2; + } + disperse_obj(pcb, (pcb_any_obj_t *)subc, ox, oy, &dx, &dy, &minx, &miny, &maxy); + pcb_move_obj(PCB_OBJ_SUBC, subc, subc, subc, dx, dy); + } + } + PCB_END_LOOP; + pcb_draw_inhibit_dec(); + + /* done with our action so increment the undo # */ + pcb_undo_inc_serial(); + + rnd_hid_redraw(pcb); + pcb_board_set_changed_flag(pcb, rnd_true); + + return 0; +} + +#undef GAP + +static const char pcb_acts_Flip[] = "Flip(Object|Selected)"; +static const char pcb_acth_Flip[] = "Flip a subcircuit to the opposite side of the board."; +/* DOC: flip.html */ +static fgw_error_t pcb_act_Flip(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_coord_t x, y; + int id; + void *ptrtmp; + + RND_ACT_CONVARG(1, FGW_KEYWORD, Flip, id = fgw_keyword(&argv[1])); + RND_ACT_IRES(0); + + rnd_hid_get_coords("Click on Object or Flip Point", &x, &y, 0); + + switch(id) { + case F_Object: + if ((pcb_search_screen(pcb_crosshair.X, pcb_crosshair.Y, PCB_OBJ_SUBC, &ptrtmp, &ptrtmp, &ptrtmp)) != PCB_OBJ_VOID) { + pcb_subc_t *subc = (pcb_subc_t *)ptrtmp; + pcb_undo_freeze_serial(); + pcb_subc_change_side(subc, 2 * pcb_crosshair.Y - RND_ACT_HIDLIB->size_y); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + pcb_draw(); + } + break; + case F_Selected: + case F_SelectedElements: + pcb_undo_freeze_serial(); + pcb_selected_subc_change_side(); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + pcb_draw(); + break; + default: + RND_ACT_FAIL(Flip); + } + return 0; +} + +static const char pcb_acts_MoveObject[] = "pcb_move_obj(X,Y,[units])"; +static const char pcb_acth_MoveObject[] = "Moves the object under the crosshair."; +/* DOC: moveobject.html */ +static fgw_error_t pcb_act_MoveObject(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char *units = NULL, *saved; + fgw_coords_t *nx, *ny; + rnd_coord_t x, y; + void *ptr1, *ptr2, *ptr3; + int type; + + RND_ACT_MAY_CONVARG(3, FGW_STR, MoveObject, units = argv[3].val.str); + fgw_str2coord_unit_set(saved, units); + RND_ACT_CONVARG(1, FGW_COORDS, MoveObject, nx = fgw_coords(&argv[1])); + RND_ACT_CONVARG(2, FGW_COORDS, MoveObject, ny = fgw_coords(&argv[2])); + fgw_str2coord_unit_restore(saved); + + + rnd_hid_get_coords("Select an Object", &x, &y, 0); + + type = pcb_search_screen(pcb_crosshair.X, pcb_crosshair.Y, PCB_MOVE_TYPES, &ptr1, &ptr2, &ptr3); + if (type == PCB_OBJ_VOID) { + rnd_message(RND_MSG_ERROR, "Nothing found under crosshair\n"); + return 1; + } + + if (nx->absolute[0]) + nx->c[0] -= pcb_crosshair.X; + if (ny->absolute[0]) + ny->c[0] -= pcb_crosshair.Y; + + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_RUBBER_RESET, NULL); + if (conf_core.editor.rubber_band_mode) + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_RUBBER_LOOKUP_LINES, "ippp", type, ptr1, ptr2, ptr3); + if (type == PCB_OBJ_SUBC) + rnd_event(RND_ACT_HIDLIB, PCB_EVENT_RUBBER_LOOKUP_RATS, "ippp", type, ptr1, ptr2, ptr3); + pcb_move_obj_and_rubberband(type, ptr1, ptr2, ptr3, nx->c[0], ny->c[0]); + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_MoveToCurrentLayer[] = "MoveToCurrentLayer(Object|SelectedObjects)"; +static const char pcb_acth_MoveToCurrentLayer[] = "Moves objects to the current layer."; +/* DOC: movetocurrentlayer.html */ +static fgw_error_t pcb_act_MoveToCurrentLayer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int id; + + RND_ACT_CONVARG(1, FGW_KEYWORD, MoveToCurrentLayer, id = fgw_keyword(&argv[1])); + RND_ACT_IRES(0); + + switch(id) { + case F_Object: + { + rnd_coord_t x, y; + int type; + void *ptr1, *ptr2, *ptr3; + + rnd_hid_get_coords("Select an Object", &x, &y, 0); + if ((type = pcb_search_screen(x, y, PCB_MOVETOLAYER_TYPES | PCB_LOOSE_SUBC(pcb), &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) { + pcb_layer_t *target = PCB_CURRLAYER(pcb); + pcb_any_obj_t *o = ptr2; + pcb_layer_t *ly; + + /* if object is part of a subc (must be a floater!), target layer + shall be within the subc too else we would move out the object from + under the subc to under the board as an unwanted side effect */ + if ((o->parent_type == PCB_PARENT_LAYER) && (o->parent.layer->parent.data->parent_type == PCB_PARENT_SUBC)) { + pcb_subc_t *subc= o->parent.layer->parent.data->parent.subc; + pcb_layer_type_t lyt = pcb_layer_flags_(PCB_CURRLAYER(pcb)); + int old_len = subc->data->LayerN; + target = pcb_subc_get_layer(subc, lyt, PCB_CURRLAYER(pcb)->comb, 1, PCB_CURRLAYER(pcb)->name, 0); + if (target == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to find or allocate the matching subc layer\n"); + break; + } + if (old_len != subc->data->LayerN) + pcb_subc_rebind(pcb, subc); /* had to alloc a new layer */ + } + ly = ptr1; + if (((pcb_any_obj_t *)ptr2)->parent_type == PCB_PARENT_LAYER) + ly = ((pcb_any_obj_t *)ptr2)->parent.layer; /* might be a bound layer, and ptr1 is a resolved one; we don't want undo to put the object back on the resolved layer instead of the original bound layer */ + if (pcb_move_obj_to_layer(type, ly, ptr2, ptr3, target, rnd_false)) + pcb_board_set_changed_flag(pcb, rnd_true); + } + break; + } + + case F_SelectedObjects: + case F_Selected: + if (pcb_move_selected_objs_to_layer(PCB_CURRLAYER(pcb))) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + return 0; +} + +static const char pcb_acts_ElementList[] = "ElementList(Start|Done|Need,,,)"; +static const char pcb_acth_ElementList[] = "Adds the given element if it doesn't already exist."; +/* DOC: elementlist.html */ +static int number_of_footprints_not_found; + +static int parse_layout_attribute_units(pcb_board_t *pcb, const char *name, int def) +{ + const char *as = pcb_attrib_get(pcb, name); + if (!as) + return def; + return rnd_get_value(as, NULL, NULL, NULL); +} + +static int subc_differs(pcb_subc_t *sc, const char *expect_name) +{ + const char *got_name = pcb_attribute_get(&sc->Attributes, "footprint"); + if ((expect_name != NULL) && (*expect_name == '\0')) + expect_name = NULL; + if ((got_name != NULL) && (*got_name == '\0')) + got_name = NULL; + if ((got_name == NULL) && (expect_name == NULL)) + return 0; + if ((got_name == NULL) || (expect_name == NULL)) + return 1; + return strcmp(got_name, expect_name); +} + +typedef struct { + enum { PLC_DISPERSE, PLC_FRAME, PLC_FIT } plc_method; + enum { PLC_AT, PLC_MARK, PLC_CENTER } location; + rnd_coord_t lx, ly, dd; + pcb_board_t *pcb; + + /* cursor for some placement methods */ + rnd_coord_t c, cx, cy; + int side; + + /* removal */ + enum { PLC_SELECT, PLC_REMOVE, PLC_LIST } rem_method; + pcb_view_list_t *remlst; +} placer_t; + +static void plc_init(pcb_board_t *pcb, placer_t *plc) +{ + const char *conf_plc_met = conf_core.import.footprint_placement.method; + const char *conf_rem_met = conf_core.import.footprint_removal.method; + + /* fallback: compatible with the original defaults */ + plc->pcb = pcb; + plc->plc_method = PLC_DISPERSE; + plc->rem_method = PLC_SELECT; + plc->location = PLC_AT; + plc->lx = pcb->hidlib.size_x / 2; + plc->ly = pcb->hidlib.size_y / 2; + plc->dd = MIN(pcb->hidlib.size_x, pcb->hidlib.size_y) / 10; + plc->c = plc->cx = plc->cy = 0; + plc->remlst = NULL; + + if ((conf_plc_met != NULL) && (*conf_plc_met != '\0')) { + const char *s; + + plc->lx = conf_core.import.footprint_placement.x; + plc->ly = conf_core.import.footprint_placement.y; + plc->dd = conf_core.import.footprint_placement.disperse; + + if (rnd_strcasecmp(conf_plc_met, "disperse") == 0) plc->plc_method = PLC_DISPERSE; + else if (rnd_strcasecmp(conf_plc_met, "frame") == 0) plc->plc_method = PLC_FRAME; + else if (rnd_strcasecmp(conf_plc_met, "fit") == 0) plc->plc_method = PLC_FIT; + else rnd_message(RND_MSG_ERROR, "Invalid import/footprint_placement/method '%s', falling back to disperse\n", conf_plc_met); + + s = conf_core.import.footprint_placement.location; + if ((s == NULL) || (*s == '\0')) plc->location = PLC_AT; + else if (rnd_strcasecmp(s, "mark") == 0) plc->location = PLC_MARK; + else if (rnd_strcasecmp(s, "center") == 0) plc->location = PLC_CENTER; + else rnd_message(RND_MSG_ERROR, "Invalid import/footprint_placement/location '%s', falling back to coordinates\n", s); + + } + else { + /* use the old import attributes */ + plc->lx = parse_layout_attribute_units(pcb, "import::newX", plc->lx); + plc->ly = parse_layout_attribute_units(pcb, "import::newY", plc->ly); + plc->dd = parse_layout_attribute_units(pcb, "import::disperse", plc->dd); + } + + if ((conf_rem_met != NULL) && (*conf_rem_met != '\0')) { + if (rnd_strcasecmp(conf_rem_met, "select") == 0) plc->rem_method = PLC_SELECT; + else if (rnd_strcasecmp(conf_rem_met, "remove") == 0) plc->rem_method = PLC_REMOVE; + else if (rnd_strcasecmp(conf_rem_met, "list") == 0) plc->rem_method = PLC_LIST; + else rnd_message(RND_MSG_ERROR, "Invalid import/footprint_removal/method '%s', falling back to select\n", conf_plc_met); + } + + switch(plc->location) { + case PLC_AT: break; + case PLC_MARK: + if (pcb_marked.status) { + plc->lx = pcb_marked.X; + plc->ly = pcb_marked.Y; + break; + } + case PLC_CENTER: + plc->lx = pcb->hidlib.size_x / 2; + plc->ly = pcb->hidlib.size_y / 2; + break; + } + + if (plc->rem_method == PLC_LIST) + plc->remlst = calloc(sizeof(pcb_view_list_t), 1); +} + +static void plc_place(placer_t *plc, rnd_coord_t *ox, rnd_coord_t *oy) +{ + rnd_coord_t px = plc->lx, py = plc->ly; + rnd_box_t bbx; + + switch(plc->plc_method) { + case PLC_FIT: + /* not yet implemented */ + case PLC_DISPERSE: + if (plc->dd > 0) { + px += rnd_rand() % (plc->dd * 2) - plc->dd; + py += rnd_rand() % (plc->dd * 2) - plc->dd; + } + break; + case PLC_FRAME: + pcb_data_bbox(&bbx, PCB_PASTEBUFFER->Data, 0); + { + rnd_coord_t bx = bbx.X2 - bbx.X1, by = bbx.Y2 - bbx.Y1; + rnd_coord_t xo = PCB_PASTEBUFFER->X/2, yo = PCB_PASTEBUFFER->Y/2; + rnd_coord_t max = (plc->side % 2) ? plc->pcb->hidlib.size_y : plc->pcb->hidlib.size_x; + rnd_coord_t mdim = (plc->side % 2) ? by : bx; + rnd_coord_t adim = (plc->side % 2) ? bx : by; + + plc->c += (double)mdim * 0.6; + switch(plc->side) { + case 0: px = xo + plc->c; py = yo - (double)(adim) * 0.6; break; /* top */ + case 1: py = yo + plc->c; px = xo + plc->pcb->hidlib.size_x + (double)(adim) * 0.6; break; /* right */ + case 2: px = xo + plc->pcb->hidlib.size_x - plc->c; py = yo + plc->pcb->hidlib.size_y + (double)(adim) * 0.6; break; /* bottom, from right to left */ + case 3: py = yo + plc->pcb->hidlib.size_y - plc->c; px = xo - (double)(adim) * 0.6; break; /* left, from bottom to top */ + } + + plc->c += (double)mdim * 0.6; + if (plc->c > max) { + plc->side++; + if (plc->side > 3) + plc->side = 0; + plc->c = 0; + } + } + break; + } + + *ox = px; + *oy = py; +} + +static void plc_remove(placer_t *plc, pcb_subc_t *sc) +{ + switch(plc->rem_method) { + case PLC_SELECT: + PCB_FLAG_SET(PCB_FLAG_SELECTED, sc); + break; + case PLC_REMOVE: + pcb_remove_object(sc->type, sc->parent.data, sc, sc); + break; + case PLC_LIST: + { + pcb_view_t *v = pcb_view_new(&plc->pcb->hidlib, "removal", RND_UNKNOWN(sc->refdes), "This part is not present on the new netlist"); + pcb_view_append_obj(v, 0, (pcb_any_obj_t *)sc); + pcb_view_set_bbox_by_objs(plc->pcb->Data, v); + pcb_view_list_append(plc->remlst, v); + } + break; + } +} + +static void plc_end(placer_t *plc) +{ + if (plc->rem_method == PLC_LIST) { + fgw_arg_t res; + fgw_arg_t args[4]; + args[1].type = FGW_STR; args[1].val.str = "import_removal"; + args[2].type = FGW_STR; args[2].val.str = "import part removal"; + fgw_ptr_reg(&rnd_fgw, &args[3], PCB_PTR_DOMAIN_VIEWLIST, FGW_PTR | FGW_STRUCT, plc->remlst); + rnd_actionv_bin(&plc->pcb->hidlib, "viewlist", &res, 4, args); + plc->remlst = NULL; + } + if ((number_of_footprints_not_found > 0) && (!rnd_conf.rc.quiet)) + rnd_message(RND_MSG_ERROR, "Footprint import: not all requested footprints were found.\nSee the message log above for details\n"); +} + + +static fgw_error_t pcb_act_ElementList(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int op; + pcb_subc_t *sc; + const char *refdes, *value, *footprint; + fgw_arg_t rs, args[4]; + int fx, fy, fs; + static placer_t plc; + + RND_ACT_CONVARG(1, FGW_KEYWORD, ElementList, op = fgw_keyword(&argv[1])); + +#ifdef DEBUG + printf("Entered pcb_act_ElementList, executing function %s\n", function); +#endif + + if (op == F_Start) { + PCB_SUBC_LOOP(pcb->Data); + { + PCB_FLAG_CLEAR(PCB_FLAG_FOUND, subc); + } + PCB_END_LOOP; + number_of_footprints_not_found = 0; + plc_init(pcb, &plc); + return 0; + } + + if (op == F_Done) { + PCB_SUBC_LOOP(pcb->Data); + { + if (PCB_FLAG_TEST(PCB_FLAG_FOUND, subc)) { + PCB_FLAG_CLEAR(PCB_FLAG_FOUND, subc); + } + else if (!RND_EMPTY_STRING_P(subc->refdes) && (!PCB_FLAG_TEST(PCB_FLAG_NONETLIST, subc))) { + /* Unnamed elements should remain untouched */ + plc_remove(&plc, subc); + } + } + PCB_END_LOOP; + plc_end(&plc); + return 0; + } + + if (op != F_Need) + RND_ACT_FAIL(ElementList); + + RND_ACT_CONVARG(2, FGW_STR, ElementList, refdes = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, ElementList, footprint = argv[3].val.str); + RND_ACT_CONVARG(4, FGW_STR, ElementList, value = argv[4].val.str); + + args[0].type = FGW_FUNC; + args[0].val.argv0.func = NULL; + args[0].val.argv0.user_call_ctx = RND_ACT_HIDLIB; + args[1] = argv[3]; + args[2] = argv[2]; + args[3] = argv[4]; + argc = 4; + + /* turn of flip to avoid mirror/rotat confusion */ + fx = rnd_conf.editor.view.flip_x; + fy = rnd_conf.editor.view.flip_y; + fs = conf_core.editor.show_solder_side; + rnd_conf_force_set_bool(rnd_conf.editor.view.flip_x, 0); + rnd_conf_force_set_bool(rnd_conf.editor.view.flip_y, 0); + rnd_conf_force_set_bool(conf_core.editor.show_solder_side, 0); + +#ifdef DEBUG + printf(" ... footprint = %s\n", footprint); + printf(" ... refdes = %s\n", refdes); + printf(" ... value = %s\n", value); +#endif + + sc = pcb_subc_by_refdes(pcb->Data, refdes); + + if (sc == NULL) { + rnd_coord_t px, py; + +#ifdef DEBUG + printf(" ... Footprint not on board, need to add it.\n"); +#endif + /* Not on board, need to add it. */ + if (RND_ACT_CALL_C(RND_ACT_HIDLIB, pcb_act_LoadFootprint, &rs, argc, args) != 0) { + number_of_footprints_not_found++; + RND_ACT_IRES(1); + return 0; + } + + plc_place(&plc, &px, &py); + + /* Place components onto center of board. */ + pcb_crosshair.Y = py; /* flipping side depends on the crosshair unfortunately */ + if (pcb_buffer_copy_to_layout(pcb, px, py, rnd_false)) + pcb_board_set_changed_flag(pcb, rnd_true); + } + else if (sc && subc_differs(sc, footprint)) { +#ifdef DEBUG + printf(" ... Footprint on board, but different from footprint loaded.\n"); +#endif + int orig_on_top, paste_ok = 0; + rnd_coord_t orig_cx, orig_cy; + double orig_rot; + + /* Different footprint, we need to swap them out. */ + if (RND_ACT_CALL_C(RND_ACT_HIDLIB, pcb_act_LoadFootprint, &rs, argc, args) != 0) { + number_of_footprints_not_found++; + RND_ACT_IRES(1); + return 0; + } + + { + orig_rot = 0.0; + orig_cx = 0; + orig_cy = 0; + orig_on_top = 0; + pcb_subc_get_rotation(sc, &orig_rot); + pcb_subc_get_origin(sc, &orig_cx, &orig_cy); + pcb_subc_get_side(sc, &orig_on_top); + orig_on_top = !orig_on_top; + } + + { + /* replace with subc */ + pcb_subc_t *psc; + psc = pcb_subclist_first(&(PCB_PASTEBUFFER->Data->subc)); + if (psc != NULL) { + rnd_coord_t pcx = 0, pcy = 0; + pcb_subc_get_origin(psc, &pcx, &pcy); + if (!orig_on_top) + pcb_subc_change_side(psc, pcy * 2 - RND_ACT_HIDLIB->size_y); + if (orig_rot != 0) { + double cosa, sina; + cosa = cos(orig_rot / RND_RAD_TO_DEG); + sina = sin(orig_rot / RND_RAD_TO_DEG); + pcb_subc_rotate(psc, pcx, pcy, cosa, sina, orig_rot); + } + +/* Not needed anymore: pcb_buffer_copy_to_layout solves this + pcb_opctx_t op; + op.move.pcb = PCB; + op.move.dx = orig_cx; + op.move.dy = orig_cy; + op.move.dst_layer = NULL; + op.move.more_to_come = rnd_true; + pcb_subcop_move(&op, psc); +*/ + paste_ok = 1; + } + } + + if (paste_ok) { + if (sc != NULL) + pcb_subc_remove(sc); + if (pcb_buffer_copy_to_layout(pcb, orig_cx, orig_cy, rnd_false)) + pcb_board_set_changed_flag(pcb,rnd_true); + } + } + + /* Now reload footprint */ + sc = pcb_subc_by_refdes(pcb->Data, refdes); + if (sc != NULL) { +/* pcb_attribute_put(&sc->Attributes, "refdes", refdes);*/ + pcb_attribute_put(&sc->Attributes, "value", value); + PCB_FLAG_SET(PCB_FLAG_FOUND, sc); + } + +#ifdef DEBUG + printf(" ... Leaving pcb_act_ElementList.\n"); +#endif + + rnd_conf_force_set_bool(rnd_conf.editor.view.flip_x, fx); + rnd_conf_force_set_bool(rnd_conf.editor.view.flip_y, fy); + rnd_conf_force_set_bool(conf_core.editor.show_solder_side, fs); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_ElementSetAttr[] = "ElementSetAttr(refdes,name[,value])"; +static const char pcb_acth_ElementSetAttr[] = "Sets or clears an element-specific attribute."; +/* DOC: elementsetattr */ +static fgw_error_t pcb_act_ElementSetAttr(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + pcb_subc_t *sc; + const char *refdes, *name, *value; + + RND_ACT_CONVARG(1, FGW_STR, ElementList, refdes = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, ElementList, name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, ElementList, value = argv[3].val.str); + + sc = pcb_subc_by_refdes(pcb->Data, refdes); + if (sc == NULL) { + rnd_message(RND_MSG_ERROR, "Can't find subcircuit with refdes '%s'\n", refdes); + RND_ACT_IRES(1); + return 0; + } + + if (value != NULL) + pcb_attribute_put(&sc->Attributes, name, value); + else + pcb_attribute_remove(&sc->Attributes, name); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_RipUp[] = "RipUp(All|Selected|Element)"; +static const char pcb_acth_RipUp[] = "Ripup auto-routed tracks"; +/* DOC: ripup.html */ +static fgw_error_t pcb_act_RipUp(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int op; + rnd_bool changed = rnd_false; + + RND_ACT_CONVARG(1, FGW_KEYWORD, RipUp, op = fgw_keyword(&argv[1])); + + switch(op) { + case F_All: + PCB_LINE_ALL_LOOP(pcb->Data); + { + if (PCB_FLAG_TEST(PCB_FLAG_AUTO, line) && !PCB_FLAG_TEST(PCB_FLAG_LOCK, line)) { + pcb_remove_object(PCB_OBJ_LINE, layer, line, line); + changed = rnd_true; + } + } + PCB_ENDALL_LOOP; + PCB_ARC_ALL_LOOP(pcb->Data); + { + if (PCB_FLAG_TEST(PCB_FLAG_AUTO, arc) && !PCB_FLAG_TEST(PCB_FLAG_LOCK, arc)) { + pcb_remove_object(PCB_OBJ_ARC, layer, arc, arc); + changed = rnd_true; + } + } + PCB_ENDALL_LOOP; + + PCB_PADSTACK_LOOP(pcb->Data); + { + if (PCB_FLAG_TEST(PCB_FLAG_AUTO, padstack) && !PCB_FLAG_TEST(PCB_FLAG_LOCK, padstack)) { + pcb_remove_object(PCB_OBJ_PSTK, padstack, padstack, padstack); + changed = rnd_true; + } + } + PCB_END_LOOP; + + if (changed) { + pcb_undo_inc_serial(); + pcb_board_set_changed_flag(pcb, rnd_true); + } + break; + case F_Selected: + PCB_LINE_VISIBLE_LOOP(pcb->Data); + { + if (PCB_FLAGS_TEST(PCB_FLAG_AUTO | PCB_FLAG_SELECTED, line) + && !PCB_FLAG_TEST(PCB_FLAG_LOCK, line)) { + pcb_remove_object(PCB_OBJ_LINE, layer, line, line); + changed = rnd_true; + } + } + PCB_ENDALL_LOOP; + if (pcb->pstk_on) + PCB_PADSTACK_LOOP(pcb->Data); + { + if (PCB_FLAGS_TEST(PCB_FLAG_AUTO | PCB_FLAG_SELECTED, padstack) + && !PCB_FLAG_TEST(PCB_FLAG_LOCK, padstack)) { + pcb_remove_object(PCB_OBJ_PSTK, padstack, padstack, padstack); + changed = rnd_true; + } + } + PCB_END_LOOP; + if (changed) { + pcb_undo_inc_serial(); + pcb_board_set_changed_flag(pcb, rnd_true); + } + break; + } + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_MoveLayer[] = "MoveLayer(old,new)\nMoveLayer(lid,group,gid)"; +static const char pcb_acth_MoveLayer[] = "Moves/Creates/Deletes Layers."; +/* DOC: movelayer.html */ +extern rnd_layergrp_id_t pcb_actd_EditGroup_gid; +fgw_error_t pcb_act_MoveLayer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *a0, *a1; + int old_index, new_index; + pcb_board_t *pcb = PCB_ACT_BOARD; + + RND_ACT_CONVARG(1, FGW_STR, MoveLayer, a0 = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, MoveLayer, a1 = argv[2].val.str); + + if (strcmp(a0, "c") == 0) + old_index = PCB_CURRLID(pcb); + else + old_index = atoi(a0); + + if (strcmp(a1, "c") == 0) { + new_index = PCB_CURRLID(pcb); + if (new_index < 0) + new_index = 0; + } + else if (strcmp(a1, "gi") == 0) { + pcb_layergrp_t *g = pcb_get_layergrp(pcb, pcb_actd_EditGroup_gid); + if ((g != NULL) && ((g->ltype & PCB_LYT_SUBSTRATE) == 0)) + RND_ACT_IRES(pcb_layer_move(pcb, -1, 0, pcb_actd_EditGroup_gid, 1)); + else + rnd_message(RND_MSG_ERROR, "Can not add layers in a substrate layer group.\n"); + return 0; + } + else if (strcmp(a1, "ga") == 0) { + pcb_layergrp_t *g = pcb_get_layergrp(pcb, pcb_actd_EditGroup_gid); + if ((g != NULL) && ((g->ltype & PCB_LYT_SUBSTRATE) == 0)) + RND_ACT_IRES(pcb_layer_move(pcb, -1, 1, pcb_actd_EditGroup_gid, 1)); + else + rnd_message(RND_MSG_ERROR, "Can not add layers in a substrate layer group.\n"); + return 0; + } + else if (strcmp(a1, "group") == 0) { + long gid; + RND_ACT_CONVARG(3, FGW_LONG, MoveLayer, gid = argv[3].val.nat_long); + pcb_layer_move_to_group(pcb, old_index, gid); + RND_ACT_IRES(0); + return 0; + } + else if (strcmp(a1, "up") == 0) { + new_index = PCB_CURRLID(pcb) - 1; + if (new_index < 0) { + RND_ACT_IRES(1); + return 0; + } + } + else if (strcmp(a1, "down") == 0) { + new_index = PCB_CURRLID(pcb) + 1; + if (new_index >= pcb_max_layer(pcb)) { + RND_ACT_IRES(1); + return 0; + } + } + else if (strncmp(a1, "step", 4) == 0) { + pcb_layer_t *l = PCB_CURRLAYER(pcb); + pcb_layergrp_t *g = pcb_get_layergrp(pcb, l->meta.real.grp); + if (g == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid layer group\n"); + return 1; + } + + RND_ACT_IRES(1); + switch(a1[4]) { + case '+': RND_ACT_IRES(pcb_layergrp_step_layer(pcb, g, pcb_layer_id(pcb->Data, l), +1)); break; + case '-': RND_ACT_IRES(pcb_layergrp_step_layer(pcb, g, pcb_layer_id(pcb->Data, l), -1)); break; + default: rnd_message(RND_MSG_ERROR, "Invalid step direction\n"); + } + return 0; + } + + else + new_index = atoi(a1); + + if (new_index < 0) { + if (pcb_layer_flags(pcb, old_index) & PCB_LYT_SILK) { + pcb_layer_t *l = pcb_get_layer(pcb->Data, old_index); + pcb_layergrp_t *g = pcb_get_layergrp(pcb, l->meta.real.grp); + if (g->len == 1) { + rnd_message(RND_MSG_ERROR, "Removing this layer would result in an empty top or bottom silk group, which is not possible at the moment.\n"); + RND_ACT_IRES(1); + return 0; + } + } + } + + RND_ACT_IRES(pcb_layer_move(pcb, old_index, new_index, -1, 1)); + return 0; +} + +static const char pcb_acts_CreateText[] = "CreateText(layer, fontID, X, Y, direction, scale, text)\n"; +static const char pcb_acth_CreateText[] = "Create a new text object"; +static fgw_error_t pcb_act_CreateText(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *txt; + rnd_coord_t x, y; + pcb_layer_t *ly; + int fid, dir, scale; + pcb_text_t *t; + + RND_ACT_CONVARG(1, FGW_LAYER, CreateText, ly = fgw_layer(&argv[1])); + RND_ACT_CONVARG(2, FGW_INT, CreateText, fid = argv[2].val.nat_int); + RND_ACT_CONVARG(3, FGW_COORD, CreateText, x = fgw_coord(&argv[3])); + RND_ACT_CONVARG(4, FGW_COORD, CreateText, y = fgw_coord(&argv[4])); + RND_ACT_CONVARG(5, FGW_INT, CreateText, dir = argv[5].val.nat_int); + RND_ACT_CONVARG(6, FGW_INT, CreateText, scale = argv[6].val.nat_int); + RND_ACT_CONVARG(7, FGW_STR, CreateText, txt = argv[7].val.str); + + if (scale < 1) { + rnd_message(RND_MSG_ERROR, "Invalid scale (must be larger than zero)\n"); + return 1; + } + + if ((dir < 0) || (dir > 3)) { + rnd_message(RND_MSG_ERROR, "Invalid direction (must be 0, 1, 2 or 3)\n"); + return 1; + } + + t = pcb_text_new(ly, pcb_font(pcb, fid, 1), x, y, dir*90, scale, 0, txt, pcb_no_flags()); + res->type = FGW_LONG; + res->val.nat_long = (t == NULL ? -1 : t->ID); + return 0; +} + +static const char pcb_acts_subc[] = + "subc(hash, [board|selected])\n" + "subc(loose, on|off|toggle|check)\n" + ; +static const char pcb_acth_subc[] = "Various operations on subc"; +static fgw_error_t pcb_act_subc(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int op1, op2 = -2; + + RND_ACT_CONVARG(1, FGW_KEYWORD, subc, op1 = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_KEYWORD, subc, op2 = fgw_keyword(&argv[2])); + RND_ACT_IRES(0); + + switch(op1) { + case F_Loose: + switch(op2) { + case -2: + case F_Toggle: pcb->loose_subc = !pcb->loose_subc; break; + case F_On: pcb->loose_subc = 1; break; + case F_Off: pcb->loose_subc = 0; break; + case F_Check: RND_ACT_IRES(pcb->loose_subc); return 0; + default: RND_ACT_FAIL(subc); return 1; + } + /* have to manually trigger the update as it is not a conf item */ + if ((rnd_gui != NULL) && (rnd_gui->update_menu_checkbox != NULL)) + rnd_gui->update_menu_checkbox(rnd_gui, NULL); + return 0; + case F_Hash: + { + int selected_only = 0; + gdl_iterator_t it; + pcb_subc_t *sc; + + switch(op2) { + case -2: break; + case F_Selected: selected_only = 1; break; + default: RND_ACT_FAIL(subc); return 1; + } + + polylist_foreach(&pcb->Data->subc, &it, sc) { + if (selected_only && !PCB_FLAG_TEST(PCB_FLAG_SELECTED, sc)) + continue; + rnd_message(RND_MSG_INFO, "subc #%ld (%s): %u\n", sc->ID, (sc->refdes == NULL ? "" : sc->refdes), pcb_subc_hash(sc)); + } + } + break; + case F_Eq: + { + int selected_only = 0; + gdl_iterator_t it; + pcb_subc_t *sc; + vtp0_t *vt; + htip_t hash2scs; /* hash to subcircuit vector */ + htip_entry_t *e; + gds_t str; + + gds_init(&str); + htip_init(&hash2scs, longhash, longkeyeq); + switch(op2) { + case -2: break; + case F_Selected: selected_only = 1; break; + default: RND_ACT_FAIL(subc); return 1; + } + polylist_foreach(&pcb->Data->subc, &it, sc) { + unsigned int hash; + if (selected_only && !PCB_FLAG_TEST(PCB_FLAG_SELECTED, sc)) + continue; + hash = pcb_subc_hash(sc); + vt = htip_get(&hash2scs, hash); + if (vt == 0) { + vt = calloc(sizeof(vtp0_t), 1); + htip_set(&hash2scs, hash, vt); + } + vtp0_append(vt, sc); + } + + /* print the result */ + for (e = htip_first(&hash2scs); e; e = htip_next(&hash2scs, e)) { + int n; + + vt = e->value; + str.used = 0; + rnd_append_printf(&str, "subc eq %u:", e->key); + for(n = 0; n < vt->used; n++) { + sc = (pcb_subc_t *)vt->array[n]; + rnd_append_printf(&str, " #%ld(%s):%d", sc->ID, (sc->refdes == NULL ? "" : sc->refdes), pcb_subc_eq(sc, (pcb_subc_t*)vt->array[0])); + } + rnd_message(RND_MSG_INFO, "%s\n", str.array); + vtp0_uninit(vt); + free(vt); + } + gds_uninit(&str); + htip_uninit(&hash2scs); + } + break; + } + + return 0; +} + +static const char pcb_acts_Rotate90[] = "pcb_move_obj(steps)"; +static const char pcb_acth_Rotate90[] = "Rotates the object under the crosshair by 90 degree steps."; +/* DOC: rotate90.html */ +static fgw_error_t pcb_act_Rotate90(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int steps; + rnd_coord_t x, y; + + RND_ACT_CONVARG(1, FGW_INT, Rotate90, steps = argv[1].val.nat_int); + RND_ACT_IRES(0); + + rnd_hid_get_coords("Select an Object", &x, &y, 0); + + if (conf_core.editor.show_solder_side) + steps = -steps; + + steps = steps % 4; + if (steps < 0) + steps = 4+steps; + + pcb_screen_obj_rotate90(PCB_ACT_BOARD, x, y, steps); + + return 0; +} + +static const char pcb_acts_GfxMod[] = + "GfxMod(transparent, [idpath, [#rrggbb]])\n" + "GfxMod(transparent, [idpath, [x, y]])\n" + "GfxMod(resize, [idpath, [pdx, pdy1, len]])" + ; +static const char pcb_acth_GfxMod[] = "Modify a gfx object: set transparent pixel on the pixmap or resize by measurement"; +/* DOC: gfxmod.html */ +static fgw_error_t pcb_act_GfxMod(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + void *ptr1, *ptr2, *ptr3; + pcb_gfx_t *gfx; + rnd_coord_t x, y; + pcb_idpath_t *idp; + long type; + + RND_ACT_CONVARG(1, FGW_KEYWORD, GfxMod, op = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_IDPATH, GfxMod, idp = fgw_idpath(&argv[2])); + + if (argc <= 2) { + rnd_hid_get_coords("Click on a gfx", &x, &y, 0); + type = pcb_search_screen(x, y, PCB_OBJ_GFX, (void **)&ptr1, (void **)&ptr2, (void **)&ptr3); + if (type != PCB_OBJ_GFX) { + rnd_message(RND_MSG_ERROR, "No gfx on that location.\n"); + RND_ACT_IRES(-1); + return 0; + } + gfx = ptr2; + } + else { + gfx = (pcb_gfx_t *)pcb_idpath2obj(PCB, idp); + if ((gfx == NULL) || (gfx->type != PCB_OBJ_GFX)) + return FGW_ERR_ARG_CONV; + } + + switch(op) { + case F_Transparent: + if (argc > 4) { + long px, py; + RND_ACT_CONVARG(3, FGW_LONG, GfxMod, px = argv[3].val.nat_long); + RND_ACT_CONVARG(4, FGW_LONG, GfxMod, py = argv[4].val.nat_long); + RND_ACT_IRES(gfx_set_transparent_by_coord(gfx, px, py)); + return 0; + } + else if (argc > 3) { + rnd_color_t clr; + char *s; + RND_ACT_CONVARG(3, FGW_STR, GfxMod, s = argv[3].val.str); + if (rnd_color_load_str(&clr, s) == 0) + gfx_set_transparent(gfx, clr.r, clr.g, clr.b, 1); + else + RND_ACT_FAIL(GfxMod); + } + else + gfx_set_transparent_gui(gfx); + break; + case F_Resize: + if (argc > 5) { + long pdx, pdy; + rnd_coord_t len; + RND_ACT_CONVARG(3, FGW_LONG, GfxMod, pdx = argv[3].val.nat_long); + RND_ACT_CONVARG(4, FGW_LONG, GfxMod, pdy = argv[4].val.nat_long); + RND_ACT_CONVARG(5, FGW_COORD, GfxMod, len = fgw_coord(&argv[5])); + RND_ACT_IRES(gfx_set_resize_by_pixel_dist(gfx, pdx, pdy, len, 1, 1, 1)); + return 0; + } + else + gfx_set_resize_gui(RND_ACT_HIDLIB, gfx, 1, 1); + break; + default: + RND_ACT_FAIL(GfxMod); + } + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t object_action_list[] = { + {"DisperseElements", pcb_act_DisperseElements, pcb_acth_DisperseElements, pcb_acts_DisperseElements}, + {"Flip", pcb_act_Flip, pcb_acth_Flip, pcb_acts_Flip}, + {"MoveObject", pcb_act_MoveObject, pcb_acth_MoveObject, pcb_acts_MoveObject}, + {"MoveToCurrentLayer", pcb_act_MoveToCurrentLayer, pcb_acth_MoveToCurrentLayer, pcb_acts_MoveToCurrentLayer}, + {"ElementList", pcb_act_ElementList, pcb_acth_ElementList, pcb_acts_ElementList}, + {"ElementSetAttr", pcb_act_ElementSetAttr, pcb_acth_ElementSetAttr, pcb_acts_ElementSetAttr}, + {"RipUp", pcb_act_RipUp, pcb_acth_RipUp, pcb_acts_RipUp}, + {"MoveLayer", pcb_act_MoveLayer, pcb_acth_MoveLayer, pcb_acts_MoveLayer}, + {"subc", pcb_act_subc, pcb_acth_subc, pcb_acts_subc}, + {"CreateText", pcb_act_CreateText, pcb_acth_CreateText, pcb_acts_CreateText}, + {"Rotate90", pcb_act_Rotate90, pcb_acth_Rotate90, pcb_acts_Rotate90}, + {"GfxMod", pcb_act_GfxMod, pcb_acth_GfxMod, pcb_acts_GfxMod} +}; + +void pcb_object_act_init2(void) +{ + RND_REGISTER_ACTIONS(object_action_list, NULL); +} Index: tags/2.3.0/src/operation.c =================================================================== --- tags/2.3.0/src/operation.c (nonexistent) +++ tags/2.3.0/src/operation.c (revision 33253) @@ -0,0 +1,405 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include "operation.h" +#include "board.h" +#include "data.h" +#include "conf_core.h" +#include "undo.h" +#include "brave.h" +#include "extobj.h" + +/* ---------------------------------------------------------------------- + * performs several operations on the passed object + */ +void *pcb_object_operation(pcb_opfunc_t *F, pcb_opctx_t *ctx, int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + pcb_any_obj_t *res = NULL, *exto = NULL; + + if (F->common_pre != NULL) { + if (F->common_pre(ctx, Ptr2, Ptr3) == 1) + return NULL; + } + + if (!F->extobj_inhibit_regen) + exto = pcb_extobj_float_pre(Ptr2); + + switch (Type) { + case PCB_OBJ_LINE: + if (F->Line) + res = F->Line(ctx, (pcb_layer_t *)Ptr1, (pcb_line_t *)Ptr2); + break; + + case PCB_OBJ_ARC: + if (F->Arc) + res = F->Arc(ctx, (pcb_layer_t *)Ptr1, (pcb_arc_t *)Ptr2); + break; + + case PCB_OBJ_GFX: + if (F->Gfx) + res = F->Gfx(ctx, (pcb_layer_t *)Ptr1, (pcb_gfx_t *)Ptr2); + break; + + case PCB_OBJ_LINE_POINT: + if (F->LinePoint) + res = F->LinePoint(ctx, (pcb_layer_t *)Ptr1, (pcb_line_t *)Ptr2, (rnd_point_t *)Ptr3); + break; + + case PCB_OBJ_ARC_POINT: + if (F->ArcPoint) + res = F->ArcPoint(ctx, (pcb_layer_t *)Ptr1, (pcb_arc_t *)Ptr2, (int *)Ptr3); + break; + + case PCB_OBJ_GFX_POINT: + /* at the moment there are no operations on GFX point so it's missing from the op struct */ + break; + + case PCB_OBJ_TEXT: + if (F->Text) + res = F->Text(ctx, (pcb_layer_t *)Ptr1, (pcb_text_t *)Ptr2); + break; + + case PCB_OBJ_POLY: + if (F->Polygon) + res = F->Polygon(ctx, (pcb_layer_t *)Ptr1, (pcb_poly_t *)Ptr2); + break; + + case PCB_OBJ_POLY_POINT: + if (F->Point) + res = F->Point(ctx, (pcb_layer_t *)Ptr1, (pcb_poly_t *)Ptr2, (rnd_point_t *)Ptr3); + break; + + case PCB_OBJ_SUBC: + if (F->subc) + res = F->subc(ctx, (pcb_subc_t *)Ptr2); + break; + + case PCB_OBJ_PSTK: + if (F->padstack) + res = F->padstack(ctx, (pcb_pstk_t *)Ptr2); + break; + + case PCB_OBJ_RAT: + if (F->Rat) + res = F->Rat(ctx, (pcb_rat_t *)Ptr2); + break; + } + + if (exto != NULL) + pcb_extobj_float_geo(exto); + + if (F->common_post != NULL) + F->common_post(ctx, Ptr2, Ptr3); + + return res; +} + +/* ---------------------------------------------------------------------- + * performs several operations on selected objects which are also visible + * The lowlevel procedures are passed together with additional information + * resets the selected flag if requested + * returns rnd_true if anything has changed + */ +static rnd_bool pcb_selected_operation_(pcb_board_t *pcb, pcb_data_t *data, pcb_opfunc_t *F, pcb_opctx_t *ctx, rnd_bool Reset, int type, pcb_op_mode_t mode, rnd_bool floater_only) +{ + rnd_bool changed = rnd_false; + pcb_any_obj_t *exto; + int on_locked_too = (mode & PCB_OP_ON_LOCKED); + int no_subc_part = (mode & PCB_OP_NO_SUBC_PART); + + if (!(pcb_brave & PCB_BRAVE_NOCLIPBATCH) && (data != NULL)) + pcb_data_clip_inhibit_inc(data); + + + /* check lines */ + if (type & PCB_OBJ_LINE && F->Line) { + PCB_LINE_VISIBLE_LOOP(data); + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, line)) + continue; + if (!on_locked_too && PCB_FLAG_TEST(PCB_FLAG_LOCK, line)) + continue; + if (floater_only && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, line)) + continue; + if (no_subc_part && (pcb_lobj_parent_subc(line->parent_type, &line->parent) != NULL)) + continue; + if (Reset) { + pcb_undo_add_obj_to_flag(line); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, line); + } + if (F->common_pre != NULL) + if (F->common_pre(ctx, (pcb_any_obj_t *)line, NULL) == 1) continue; + if (F->extobj_inhibit_regen) + exto = NULL; + else + exto = pcb_extobj_float_pre((pcb_any_obj_t *)line); + F->Line(ctx, layer, line); + if (exto != NULL) pcb_extobj_float_geo(exto); + if (F->common_post != NULL) F->common_post(ctx, (pcb_any_obj_t *)line, NULL); + changed = rnd_true; + } + PCB_ENDALL_LOOP; + } + + /* check arcs */ + if (type & PCB_OBJ_ARC && F->Arc) { + PCB_ARC_VISIBLE_LOOP(data); + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, arc)) + continue; + if (!on_locked_too && PCB_FLAG_TEST(PCB_FLAG_LOCK, arc)) + continue; + if (floater_only && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, arc)) + continue; + if (no_subc_part && (pcb_lobj_parent_subc(arc->parent_type, &arc->parent) != NULL)) + continue; + if (Reset) { + pcb_undo_add_obj_to_flag(arc); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, arc); + } + if (F->common_pre != NULL) + if (F->common_pre(ctx, (pcb_any_obj_t *)arc, NULL) == 1) continue; + if (F->extobj_inhibit_regen) + exto = NULL; + else + exto = pcb_extobj_float_pre((pcb_any_obj_t *)arc); + F->Arc(ctx, layer, arc); + if (exto != NULL) pcb_extobj_float_geo(exto); + if (F->common_post != NULL) F->common_post(ctx, (pcb_any_obj_t *)arc, NULL); + changed = rnd_true; + } + PCB_ENDALL_LOOP; + } + + /* check text */ + if (type & PCB_OBJ_TEXT && F->Text) { + PCB_TEXT_ALL_LOOP(data); + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, text) || !pcb_text_is_visible(PCB, layer, text)) + continue; + if (!on_locked_too && PCB_FLAG_TEST(PCB_FLAG_LOCK, text)) + continue; + if (floater_only && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, text)) + continue; + if (no_subc_part && (pcb_lobj_parent_subc(text->parent_type, &text->parent) != NULL)) + continue; + if (Reset) { + pcb_undo_add_obj_to_flag(text); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, text); + } + if (F->common_pre != NULL) + if (F->common_pre(ctx, (pcb_any_obj_t *)text, NULL) == 1) continue; + if (F->extobj_inhibit_regen) + exto = NULL; + else + exto = pcb_extobj_float_pre((pcb_any_obj_t *)text); + F->Text(ctx, layer, text); + if (exto != NULL) pcb_extobj_float_geo(exto); + if (F->common_post != NULL) F->common_post(ctx, (pcb_any_obj_t *)text, NULL); + changed = rnd_true; + } + PCB_ENDALL_LOOP; + } + + /* check polygons */ + if (type & PCB_OBJ_POLY && F->Polygon) { + PCB_POLY_VISIBLE_LOOP(data); + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, polygon)) + continue; + if (!on_locked_too && PCB_FLAG_TEST(PCB_FLAG_LOCK, polygon)) + continue; + if (floater_only && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, polygon)) + continue; + if (no_subc_part && (pcb_lobj_parent_subc(polygon->parent_type, &polygon->parent) != NULL)) + continue; + if (Reset) { + pcb_undo_add_obj_to_flag(polygon); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, polygon); + } + if (F->common_pre != NULL) + if (F->common_pre(ctx, (pcb_any_obj_t *)polygon, NULL) == 1) continue; + if (F->extobj_inhibit_regen) + exto = NULL; + else + exto = pcb_extobj_float_pre((pcb_any_obj_t *)polygon); + F->Polygon(ctx, layer, polygon); + if (exto != NULL) pcb_extobj_float_geo(exto); + if (F->common_post != NULL) F->common_post(ctx, (pcb_any_obj_t *)polygon, NULL); + changed = rnd_true; + } + PCB_ENDALL_LOOP; + } + + /* check gfx */ + if (type & PCB_OBJ_GFX && F->Gfx) { + PCB_GFX_VISIBLE_LOOP(data); + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, gfx)) + continue; + if (!on_locked_too && PCB_FLAG_TEST(PCB_FLAG_LOCK, gfx)) + continue; + if (floater_only && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, gfx)) + continue; + if (no_subc_part && (pcb_lobj_parent_subc(gfx->parent_type, &gfx->parent) != NULL)) + continue; + if (Reset) { + pcb_undo_add_obj_to_flag(gfx); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, gfx); + } + if (F->common_pre != NULL) + if (F->common_pre(ctx, (pcb_any_obj_t *)gfx, NULL) == 1) continue; + if (F->extobj_inhibit_regen) + exto = NULL; + else + exto = pcb_extobj_float_pre((pcb_any_obj_t *)gfx); + F->Gfx(ctx, layer, gfx); + if (exto != NULL) pcb_extobj_float_geo(exto); + if (F->common_post != NULL) F->common_post(ctx, (pcb_any_obj_t *)gfx, NULL); + changed = rnd_true; + } + PCB_ENDALL_LOOP; + } + + if ((type & (PCB_OBJ_SUBC | PCB_OBJ_SUBC_PART)) && F->subc) { + PCB_SUBC_LOOP(data); + { + if (!on_locked_too && PCB_FLAG_TEST(PCB_FLAG_LOCK, subc) && (subc->extobj == NULL)) /* extobj: even locked means floaters can be operated on */ + continue; + if (floater_only && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, subc)) + continue; + if (no_subc_part && (pcb_gobj_parent_subc(subc->parent_type, &subc->parent) != NULL)) + continue; + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, subc)) { + if (Reset) { + pcb_undo_add_obj_to_flag(subc); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, subc); + } + if (F->common_pre != NULL) + if (F->common_pre(ctx, (pcb_any_obj_t *)subc, NULL) == 1) continue; + if (F->extobj_inhibit_regen) + exto = NULL; + else + exto = pcb_extobj_float_pre((pcb_any_obj_t *)subc); + F->subc(ctx, subc); + if (exto != NULL) pcb_extobj_float_geo(exto); + if (F->common_post != NULL) F->common_post(ctx, (pcb_any_obj_t *)subc, NULL); + changed = rnd_true; + + if (pcb_selected_operation_(pcb, subc->data, F, ctx, Reset, type, mode, 1)) + changed = rnd_true; + } + else if ((pcb->loose_subc) || (type & PCB_OBJ_SUBC_PART) || (subc->extobj != NULL)) { + if (pcb_selected_operation_(pcb, subc->data, F, ctx, Reset, type, mode, 0)) + changed = rnd_true; + } + else + if (pcb_selected_operation_(pcb, subc->data, F, ctx, Reset, type, mode, 1)) + changed = rnd_true; + } + PCB_END_LOOP; + } + else { /* there can be selected objects within subcircuits - but deal only with floaters */ + PCB_SUBC_LOOP(data); + { + if (pcb_selected_operation_(pcb, subc->data, F, ctx, Reset, type, mode, 1)) + changed = rnd_true; + } + PCB_END_LOOP; + } + + /* process padstacks */ + if (type & PCB_OBJ_PSTK && pcb->pstk_on && F->padstack) { + PCB_PADSTACK_LOOP(data); + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, padstack)) + continue; + if (!on_locked_too && PCB_FLAG_TEST(PCB_FLAG_LOCK, padstack)) + continue; + if (floater_only && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, padstack)) + continue; + if (no_subc_part && (pcb_gobj_parent_subc(padstack->parent_type, &padstack->parent) != NULL)) + continue; + if (Reset) { + pcb_undo_add_obj_to_flag(padstack); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, padstack); + } + if (F->common_pre != NULL) + if (F->common_pre(ctx, (pcb_any_obj_t *)padstack, NULL) == 1) continue; + if (F->extobj_inhibit_regen) + exto = NULL; + else + exto = pcb_extobj_float_pre((pcb_any_obj_t *)padstack); + F->padstack(ctx, padstack); + if (exto != NULL) pcb_extobj_float_geo(exto); + if (F->common_post != NULL) F->common_post(ctx, (pcb_any_obj_t *)padstack, NULL); + changed = rnd_true; + } + PCB_END_LOOP; + } + + /* and rat-lines */ + if (type & PCB_OBJ_RAT && pcb->RatOn && F->Rat) { + PCB_RAT_LOOP(data); + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, line)) + continue; + if (!on_locked_too && PCB_FLAG_TEST(PCB_FLAG_LOCK, line)) + continue; + if (floater_only && !PCB_FLAG_TEST(PCB_FLAG_FLOATER, line)) + continue; + if (Reset) { + pcb_undo_add_obj_to_flag(line); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, line); + } + if (F->common_pre != NULL) + if (F->common_pre(ctx, (pcb_any_obj_t *)line, NULL) == 1) continue; + F->Rat(ctx, line); + if (F->common_post != NULL) F->common_post(ctx, (pcb_any_obj_t *)line, NULL); + changed = rnd_true; + } + PCB_END_LOOP; + } + + if (Reset && changed) + pcb_undo_inc_serial(); + + if (!(pcb_brave & PCB_BRAVE_NOCLIPBATCH) && (data != NULL)) + pcb_data_clip_inhibit_dec(data, 0); + + return changed; +} + +rnd_bool pcb_selected_operation(pcb_board_t *pcb, pcb_data_t *data, pcb_opfunc_t *F, pcb_opctx_t *ctx, rnd_bool Reset, int type, pcb_op_mode_t mode) +{ + return pcb_selected_operation_(pcb, data, F, ctx, Reset, type, mode, 0); +} + Index: tags/2.3.0/src/operation.h =================================================================== --- tags/2.3.0/src/operation.h (nonexistent) +++ tags/2.3.0/src/operation.h (revision 33253) @@ -0,0 +1,169 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2004 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_OPERATION_H +#define PCB_OPERATION_H + +#include "global_typedefs.h" + +/* Each object operation gets an operation-context with some operation-specific + configuration, and the board to operate on. Optionally this is the place to + hold temporary states of a multi-call operation too. */ + +typedef struct { + pcb_board_t *pcb; + int extraflg; + unsigned keep_id:1; + unsigned removing:1; + pcb_data_t *dst, *src; + + /* internal */ + pcb_subc_t *post_subc; /* remember the extobj parent subc while removing a floater */ +} pcb_opctx_buffer_t; + +typedef struct { + pcb_board_t *pcb; + int is_primary; /* whether the primary parameter should be changed */ + rnd_bool is_absolute; + rnd_coord_t value; /* delta or absolute (depending on is_absoulute) */ +} pcb_opctx_chgsize_t; + +typedef struct { + pcb_board_t *pcb; + int is_primary; /* whether the primary parameter should be changed */ + rnd_bool is_absolute; + rnd_angle_t value; /* same as above, but for angles */ +} pcb_opctx_chgangle_t; + +typedef struct { + pcb_board_t *pcb; + char *new_name; +} pcb_opctx_chgname_t; + +typedef struct { + pcb_board_t *pcb; + int style; /* the new bits */ + unsigned long lid; /* the layer to operate on */ +} pcb_opctx_chgtherm_t; + +typedef struct { + pcb_board_t *pcb; + rnd_coord_t DeltaX, DeltaY; /* movement vector */ + int from_outside; + int keep_id; +} pcb_opctx_copy_t; + +typedef struct { + pcb_board_t *pcb; + rnd_coord_t x, y; + rnd_cardinal_t idx; /* poly point idx */ + rnd_bool last; + rnd_bool forcible; +} pcb_opctx_insert_t; + +typedef struct { + pcb_board_t *pcb; + rnd_coord_t dx, dy; /* used by local routines as offset */ + pcb_layer_t *dst_layer; + rnd_bool more_to_come; +} pcb_opctx_move_t; + +typedef struct { + pcb_board_t *pcb; + pcb_data_t *destroy_target; +} pcb_opctx_remove_t; + +typedef struct { + pcb_board_t *pcb; + rnd_coord_t center_x, center_y; /* center of rotation */ + unsigned number; /* number of rotations, for 90 deg rotation */ + double cosa, sina, angle; /* for arbitrary angle rotation */ +} pcb_opctx_rotate_t; + +typedef struct { + pcb_board_t *pcb; + unsigned long how; /* pcb_change_flag_t */ + unsigned long flag; /* pcb_flag_values_t */ +} pcb_opctx_chgflag_t; + +typedef struct { + pcb_board_t *pcb; +} pcb_opctx_noarg_t; + +typedef struct { + pcb_board_t *pcb; + int restore; + int clear; +} pcb_opctx_clip_t; + +typedef union { + pcb_opctx_buffer_t buffer; + pcb_opctx_chgname_t chgname; + pcb_opctx_chgsize_t chgsize; + pcb_opctx_chgangle_t chgangle; + pcb_opctx_chgtherm_t chgtherm; + pcb_opctx_copy_t copy; + pcb_opctx_insert_t insert; + pcb_opctx_move_t move; + pcb_opctx_remove_t remove; + pcb_opctx_rotate_t rotate; + pcb_opctx_chgflag_t chgflag; + pcb_opctx_noarg_t noarg; + pcb_opctx_clip_t clip; +} pcb_opctx_t; + +/* pointer to low-level operation (copy, move and rotate) functions */ +typedef struct { + int (*common_pre)(pcb_opctx_t *ctx, pcb_any_obj_t *ptr2, void *ptr3); /* called before anything else (not object-type-dependent); skip the rest of the call for the object if returns 1 */ + void (*common_post)(pcb_opctx_t *ctx, pcb_any_obj_t *ptr2, void *ptr3); /* called after everything else (not object-type-dependent) */ + + void *(*Line)(pcb_opctx_t *ctx, pcb_layer_t *, pcb_line_t *); + void *(*Text)(pcb_opctx_t *ctx, pcb_layer_t *, pcb_text_t *); + void *(*Polygon)(pcb_opctx_t *ctx, pcb_layer_t *, pcb_poly_t *); +/*5*/ + void *(*LinePoint)(pcb_opctx_t *ctx, pcb_layer_t *, pcb_line_t *, rnd_point_t *); + void *(*Point)(pcb_opctx_t *ctx, pcb_layer_t *, pcb_poly_t *, rnd_point_t *); + void *(*Arc)(pcb_opctx_t *ctx, pcb_layer_t *, pcb_arc_t *); + void *(*Gfx)(pcb_opctx_t *ctx, pcb_layer_t *, pcb_gfx_t *); + void *(*Rat)(pcb_opctx_t *ctx, pcb_rat_t *); + void *(*ArcPoint)(pcb_opctx_t *ctx, pcb_layer_t *, pcb_arc_t *, int *end_id); + void *(*subc)(pcb_opctx_t *ctx, pcb_subc_t *); + void *(*padstack)(pcb_opctx_t *ctx, pcb_pstk_t *); + + unsigned int extobj_inhibit_regen:1; +} pcb_opfunc_t; + +typedef enum { + PCB_OP_ON_LOCKED = 1, + PCB_OP_NO_SUBC_PART = 2 /* ignore selected objects which are part of a subc (assume the operation on subc will cover them) */ +} pcb_op_mode_t; + +void *pcb_object_operation(pcb_opfunc_t *F, pcb_opctx_t *ctx, int Type, void *Ptr1, void *Ptr2, void *Ptr3); +rnd_bool pcb_selected_operation(pcb_board_t *pcb, pcb_data_t *data, pcb_opfunc_t *F, pcb_opctx_t *ctx, rnd_bool Reset, int type, pcb_op_mode_t mode); + +#endif Index: tags/2.3.0/src/pcb-conf.lht =================================================================== --- tags/2.3.0/src/pcb-conf.lht (nonexistent) +++ tags/2.3.0/src/pcb-conf.lht (revision 33253) @@ -0,0 +1,296 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:editor { + grid_unit = mil + grid = 25 mil + 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 = 4 + zoom = 1 + mode = -1 + buffer_number = 0 + clear_line = 1 + clear_polypoly = 0 + full_poly = 0 + unique_names = 0 + marker_snaps = 1 + snap_pin = 1 + snap_offgrid_line = 1 + highlight_on_point = 0 + show_solder_side = 0 + save_last_command = 0 + save_in_tmp = 0 + draw_grid = 1 + all_direction_lines = 0 + line_refraction = 1 + rubber_band_mode = 0 + rubber_band_keep_midlinedir = 0 + swap_start_direction = 0 + show_drc = 0 + auto_drc = 0 + conn_find_rat = 1 + show_number = 0 + orthogonal_moves = 0 + reset_after_element = 1 + trace_auto_merge = 1 + auto_place = 0 + lock_names = 0 + only_names = 0 + thin_draw = 0 + thin_draw_poly = 0 + as_drawn_poly = 0 + wireframe_draw = 0 + local_ref = 0 + check_planes = 0 + hide_names = 0 + description = 0 + name_on_pcb = 1 + enable_stroke = 1 + live_routing = 0 + beep_when_finished = 0 + click_time = 200 + click_objlist = 0 + auto_via = 1 + drc_inclusive_bbox = 0; + io_incomp_popup = 1 + io_incomp_style = list + ha:view { + flip_x = 0 + flip_y = 0 + } + ha:selection { + disable_negative = 0 + symmetric_negative = 0 + } + undo_warning_size = 1024 + fullscreen = 0 + move_linepoint_uses_route = 1 + subc_conv_refdes = U0 + } # editor + + ha:rc { + verbose = 0 + quiet = 0 + file_changed_interval = 2 + backup_interval = 60 + hid_fallback = 1 + brave = {} + menu_file = {default} +# font_command = {} +# file_command = {} +# file_path = {} + library_shell = {} + export_basename = 0 + + emergency_name = {PCB.%ld.save} + emergency_format = {lihata} + backup_name = {%F.%P.backup} + backup_format = {lihata} + + li:library_search_paths = { + ?../pcblib + ?~/pcblib/ + $(rc.path.share)/pcblib + } + + keep_save_backups = false + save_command = {} + + li:default_font_file = { + {./default_font} + {$(rc.path.share)/default_font} + } + li:default_pcb_file = { + {./default4.lht} + {$(rc.path.share)/default4.lht} + } + +# script_filename = {} +# action_string = {} +# rat_path = {} +# rat_command = {} + li:preferred_gui = { gtk2_gl; gtk2_gdk; lesstif; batch } + save_final_fallback_fmt = lihata + save_fp_fmt = lihata + } # rc + + ha:design { +# old DRC (design rule checked) section + bloat = 12.00 mil + shrink = 9.00 mil + min_drill = 15.00 mil + min_ring = 10.00 mil + min_slk = 7.00 mil + min_wid = 10.00 mil + line_thickness = 10.00 mil + clearance = 20.00 mil + poly_isle_area = 200000000.2 + + via_thickness = 2000.00 um + via_drilling_hole = 31.50 mil + + text_scale = 100 + text_thickness = 0 + text_font_id = 0 +# poly_isle_area = 0 +# background_image = {} +# fab_author = {} + paste_adjust = 0 + } # design + + ha:appearance { + compact = 1 + rat_thickness = 0.25 mm + mark_size = 50 mil + layer_alpha = 0.75 + drill_alpha = 0.85 + text_host_bbox = true + term_label_size = 50 + subc_layer_per_side = 1 + invis_other_groups = 0 + black_current_group = 0 + smart_labels = 0 + label_thickness = 1nm + + 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} + mark = {#ff0000} + attached = {#ff0000} + drc = {#cdcd00} + selected = {#00ffff} + via = {#707070} + via_far = {#a0a0a0} + pin = {#404040} + pin_far = {#707070} + pin_name = {#ff0000} + element = {#000000} + subc = {#CC0000} + subc_nonetlist = {#cc9900} + extobj = {#EE0000} + padstackmark = {#cc0000} + rat = {#b8860b} + invisible_objects = {#cccccc} + connected = {#00ff00} + off_limit = {#aaaaaa} + grid = {#ff0000} + li:layer = { + {#8b2323}; {#3a5fcd}; {#104e8b}; {#cd3700}; {#548b54}; + {#8b7355}; {#00868b}; {#228b22}; {#8b2323}; {#3a5fcd}; + {#104e8b}; {#cd3700}; {#548b54}; {#8b7355}; {#00868b}; + {#228b22}; + {#8b2323}; {#3a5fcd}; {#104e8b}; {#cd3700}; {#548b54}; + {#8b7355}; {#00868b}; {#228b22}; {#8b2323}; {#3a5fcd}; + {#104e8b}; {#cd3700}; {#548b54}; {#8b7355}; {#00868b}; + {#228b22}; + {#8b2323}; {#3a5fcd}; {#104e8b}; {#cd3700}; {#548b54}; + {#8b7355}; + } + warn = {#ff8000} + mask = {#ff0000} + paste = {#cd00cd} + } + ha:padstack { + cross_thick = 1 + cross_size = 0.1 mm + } + ha:subc { + dash_freq = 5 + } + ha:messages { +# char_per_line = 0 + } +# ha:misc { +# volume = 0 +# } misc; + } # appearance; + + ha:import { + ha:footprint_placement { + method = frame + } + ha:footprint_removal { + method = remove + } + } + + ha:plugins { + ha:lib_hid_common { + ha:cli_history { + file = {$(rc.path.home)/.pcb-rnd/cli_history} + slots = 64 + } + } + ha:io_lihata { + aux_pcb_pattern = {%D.%B.lht.pcb} + } + ha:mincut { + enable = 1 + } + ha:djopt { + auto_only = 1 + } + ha:diag { + auto_integrity = 0 + } + ha:import_sch { + gnetlist_program = gnetlist + make_program = make + verbose = false + } + ha:import_mentor_sch { + li:map_search_paths = { + {./mentor_parts.map} + {$(rc.path.share)/mentor_parts.map} + } + } + ha:hid_gtk { + ha:local_grid { + enable = 0 + radius = 16 + } + ha:global_grid { + sparse = 0 + min_dist_px = 4 + } + ha:dialog { + transient_modal = 1 + transient_modeless = 1 + auto_present = 0 + } + } + ha:report { + columns = 8 + } + ha:fp_wget { + auto_update_gedasymbols = 0 + auto_update_edakrill = 0 + } + ha:export_gerber { + plated_g85_slot = 0 + unplated_g85_slot = 0 + } + } # plugins + + ha:utils { + ha:gsch2pcb-rnd { + remove_unfound_elements = 1 + quiet_mode = 0 + verbose = 0 + } + } # utils + } # main +} # root + Index: tags/2.3.0/src/pcb-menu-default.lht =================================================================== --- tags/2.3.0/src/pcb-menu-default.lht (nonexistent) +++ tags/2.3.0/src/pcb-menu-default.lht (revision 33253) @@ -0,0 +1,988 @@ +ha:rnd-menu-v1 { + li:mouse { + li:left { + li:press = { Tool(Press) } + li:press-shift = { Tool(Press) } + li:press-ctrl = { Tool(Save); Tool(arrow); Tool(Restore); Tool(Press) } + li:release = { Tool(Release) } + li:release-shift = { Tool(Release) } + li:release-ctrl = { Tool(Release) } + } + li:middle { + li:press = { Pan(1) } + li:release = { Pan(0) } + } + li:right { + li:press = { Tool(Stroke) } + li:release = { Tool(Release); Popup(popup-obj, obj-type) } + li:shift-release = { Popup(popup-obj-misc) } + } + 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:via {tip={place a via on the board}} + ha:line {tip={draw a line segment (trace) on the board}} + ha:arc {tip={draw an arc segment (trace) on the board}} + ha:text {tip={draw text on the board}} + ha:rectangle {tip={draw a rectangular polygon on the board}} + ha:poly {tip={draw a polygon on the board}} + ha:polyhole {tip={cut out a hole from existing polygons on the board}} + ha:buffer {tip={paste the current buffer on the board}} + ha:remove {tip={remove an object from the board}} + ha:rotate {tip={rotate an object on the board}} + ha:insert {tip={insert a point in a trace or polygon contour}} + ha:thermal {tip={change thermal connectivity of a pin or via}} + ha:arrow {tip={switch to arrow mode}} + ha:lock {tip={lock or unlock objects on the board}} + } + + li:main_menu { + + ha:File { + li:submenu { + ha:Start New Layout = { li:a={{f;n}; {Ctrln};}; action=New() } + ha:Revert = { a={f;r}; action=Load(Revert,none); tip=Revert to the layout stored on disk } + - + ha:Load layout... = { li:a={{f;o};{f;l};} action=Load(Layout); tip=Load a layout from a file } + - + ha:Save Layout = { li:a={{f;s}; {Ctrls};}; action=Save(Layout); tip=Saves current layout } + ha:Save Layout As... = { li:a={{f;a}; {Shift Ctrls};}; action=Save(LayoutAs); tip=Saves current layout into a new file } + - + ha:Import { + li:submenu { + ha:Import schematics... = { action=ImportSch() } + ha:Configure import schematics... = { action=ImportSch(dialog) } + @import_top + - + ha:Load subcircuit data to paste-buffer = { li:action={PasteBuffer(Clear); Load(ElementTobuffer)} } + ha:Load layout data to paste-buffer = { li:action={PasteBuffer(Clear); Load(LayoutTobuffer)} } + ha:Load pixmap to paste-buffer gfx = { li:action={PasteBuffer(Clear); LoadPixmap(); Tool(buffer);} } + @import_geo + - + @import_sch + ha:Load netlist file = { action=Load(Netlist) } + } + } + - + ha:Save connection data of { + li:submenu { + ha:a single element = { li:action={ Save(ElementConnections) } } + ha:all elements = { action=Save(AllConnections) } + ha:unused pins = { action=Save(AllUnusedPins) } + ha:netlist patch for back annotation = {li:a={{f;x;p}; {a;b;x};}; action=SavePatch() } + } + } + ha:Print layout... = { a={f;p}; action=Print()} + ha:Export layout... = { a={f;e}; action=ExportGUI()} + ha:Export with CAM job...={ a={f;c}; action=cam()} + ha:Reports { + li:submenu { + ha:Generate object report = { a={i;r}; action=ReportObject() } + ha:Generate drill summary = { a={i;d}; action=Report(DrillReport) } + ha:Report found padstacks = { a={i;f}; action=Report(FoundPins) } + } + } + - + ha:Preferences... = { a={i;c;p}; action=preferences} + ha:Maintenance { + li:submenu { + ha:Calibrate Printer... = { a={i;c;c}; action=PrintCalibrate() } + ha:Re-scan the footprint library = { a={i;c;r}; action=fp_rehash() } + ha:Data integrity check = { a={i;c;i}; action=Integrity() } + - + ha:Edit current font = { action=FontEdit() } + ha:Edit on-disk font = { action={ LoadFontFrom("", 126); conf(set, design/text_font_id, 126, design); FontEdit() } } + ha:Save font from font editor = { action=FontSave() } + - + ha:Undo dialog (for debugging) = { a={u;d;}; action=UndoDialog() } + } + } + - + ha:Quit Program = { li:a={{f;q}; {Ctrlq};}; action=Quit() } + } + } # File + + ha:Edit { + li:submenu { + ha:Undo last operation = { li:a={{u; u}; {Ctrlz};}; action=Undo() } + ha:Redo last undone operation = { li:a={{u; r}; {Ctrly};}; action=Redo() } + ha:Clear undo-buffer = { a={u; c}; action=Undo(ClearList) } + - + ha:Cut selection to buffer = { li:a={{e; x}; a=Ctrlx;}; li:action={ GetXY(Click to set the snap point for this buffer); PasteBuffer(Clear); PasteBuffer(MoveSelected); Tool(buffer) } } + ha:Copy selection to buffer = { li:a={{e; c}; {Ctrlc;};}; li:action={ GetXY(Click to set the snap point for this buffer); PasteBuffer(Clear); PasteBuffer(AddSelected); Unselect(All); Tool(buffer) } } + ha:Paste buffer to layout = { li:a={{e; v}; a=Ctrlv;}; action=Tool(buffer) } + - + ha:Remove object = { li:a={{e;d};{Delete};}; li:action={Tool(Save); Tool(remove); Tool(Press); Tool(Restore)} } + ha:Change object { + li:submenu { + ha:Set Same Style = { a={e; s; s}; action=SetSame() } + ha:Flip Object = { a={e; i}; action=Flip(Object) } + ha:Move to current layer = { a={e; l}; action=MoveToCurrentLayer(Object) } + ha:ChangeJoin Object = { a={e; j}; action=ChangeJoin(Object) } + ha:Convert to extended object... = { a={e; s; x}; action=ExtobjConvFrom(Object, @gui) } + ha:Geometry { + li:submenu { + ha:Clearance +2 mil = { a={e; g; c}; action=ChangeClearSize(Object,+2,mil) } + ha:Clearance -2 mil = { a={e; g; Shiftc}; action=ChangeClearSize(Object,-2,mil) } + ha:ChangeSizes to Route style = { a={e; g; y}; action=ChangeSizes(Object,style,mil) } + ha:ChangeSize +5 mil = { a={e; g; s}; action=ChangeSize(Object,+5,mil) } + ha:ChangeSize -5 mil = { a={e; g; Shifts}; action=ChangeSize(Object,-5,mil) } + ha:ChangeDrill +5 mil = { a={e; g; d}; action=ChangeDrillSize(Object,+5,mil) } + ha:ChangeDrill -5 mil = { a={e; g; Shiftd}; action=ChangeDrillSize(Object,-5,mil) } + - + ha:Edit padstack geometry/prototype = {a={e; g; g}; action=padstackedit } + } + } + } + } # Change object + ha:Add/place object { + li:submenu { + ha:Place mark = { li:a={{a;m}; {a;w}; }; action=MarkCrosshair() } + ha:Place via = { a={a;v}; li:action={Tool(Save); Tool(via); Tool(Press); Tool(Restore);} } + ha:Start routing a line = { a={a;l}; li:action={Tool(Save); Tool(line); Tool(Press); } } + ha:Start routing an arc = { a={a;a}; li:action={Tool(Save); Tool(arc); Tool(Press); } } + } + } + - + ha:Edit properties of { + li:submenu { + ha:Layout = { action=Propedit(board) } + ha:Current Layer = { action={Propedit(layer)} } + ha:Current Layer Group = { action={Propedit(layergrp)} } + } + } + ha:Route Styles { + li:submenu { + @routestyles + - + ha:Edit... = { action=AdjustStyle() } + } + } + ha:Board padstack prototypes... = { action=pstklib() } + - + ha:Subcircuit { + li:submenu { + ha:Layer bindings... = { a={e; s; b}; action=LayerBinding() } + ha:External editor... = { a={e; s; e}; li:action={ GetXY(Click on the subcircuit to edit); extedit(object) } } + ha:Refdes = { a={e; s; r}; action=ChangeName(Subc) } + } + } + ha:Object flags... = { a={e; f}; action=FlagEdit() } + ha:Object Properties... = { a={e; p}; action=PropEdit(selection) } + } + } # Edit + + 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=plugins/hid_gtk/local_grid/enable; action=conf(toggle, plugins/hid_gtk/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=plugins/hid_gtk/local_grid/enable; action=conf(toggle, plugins/hid_gtk/local_grid/enable, design) } + - + ha:local grid radius 4 = { checked={conf(iseq, plugins/hid_gtk/local_grid/radius, 4)}; li:action={conf(set, plugins/hid_gtk/local_grid/radius, 4, design); conf(set, plugins/hid_gtk/local_grid/enable, 1, design) } update_on={} } + ha:local grid radius 8 = { checked={conf(iseq, plugins/hid_gtk/local_grid/radius, 8)}; li:action={conf(set, plugins/hid_gtk/local_grid/radius, 8, design); conf(set, plugins/hid_gtk/local_grid/enable, 1, design) } update_on={} } + ha:local grid radius 16 = { checked={conf(iseq, plugins/hid_gtk/local_grid/radius, 16)}; li:action={conf(set, plugins/hid_gtk/local_grid/radius, 16, design); conf(set, plugins/hid_gtk/local_grid/enable, 1, design) } update_on={} } + ha:local grid radius 32 = { checked={conf(iseq, plugins/hid_gtk/local_grid/radius, 32)}; li:action={conf(set, plugins/hid_gtk/local_grid/radius, 32, design); conf(set, plugins/hid_gtk/local_grid/enable, 1, design) } update_on={} } + - + ha:sparse global grid = { checked=plugins/hid_gtk/global_grid/sparse; action=conf(toggle, plugins/hid_gtk/global_grid/sparse, design) } + ha:global grid density 4 = { checked={conf(iseq, plugins/hid_gtk/global_grid/min_dist_px, 4)}; li:action={conf(set, plugins/hid_gtk/global_grid/min_dist_px, 4, design); conf(set, plugins/hid_gtk/local_grid/enable, 0, design) } update_on={} } + ha:global grid density 8 = { checked={conf(iseq, plugins/hid_gtk/global_grid/min_dist_px, 8)}; li:action={conf(set, plugins/hid_gtk/global_grid/min_dist_px, 8, design); conf(set, plugins/hid_gtk/local_grid/enable, 0, design) } update_on={} } + ha:global grid density 16 = { checked={conf(iseq, plugins/hid_gtk/global_grid/min_dist_px, 16)}; li:action={conf(set, plugins/hid_gtk/global_grid/min_dist_px, 16, design); conf(set, plugins/hid_gtk/local_grid/enable, 0, design) } update_on={} } + } + } + ha:Realign grid = { a={g; r}; action={ Display(ToggleGrid) } } + } + } + - + ha:Displayed subcircuit ID { + li:submenu { + ha:refdes = { a={v; s; r}; checked=ChkSubcID(%a.refdes%); action=Display(SubcID, "%a.refdes%"); update_on={editor/subc_id} } + ha:footprint = { a={v; s; f}; checked=ChkSubcID(%a.footprint%); action=Display(SubcID,"%a.footprint%"); update_on={editor/subc_id} } + ha:value = { a={v; s; v}; checked=ChkSubcID(%a.value%); action=Display(SubcID,"%a.value%"); update_on={editor/subc_id} } + ha:refdes+value = { a={v; s; s}; checked=ChkSubcID(%a.refdes%\\n%a.value%); action=Display(SubcID,"%a.refdes%\\\\n%a.value%"); update_on={editor/subc_id} } + ha:user configured = { a={v; s; c}; action=Display(SubcID); } + } + } + ha:Displayed terminal ID { + li:submenu { + ha:term = { a={v; t; t}; checked=ChkTermID(%a.term%); action=Display(TermID, "%a.term%"); update_on={editor/term_id} } + ha:name = { a={v; t; n}; checked=ChkTermID(%a.name%); action=Display(TermID, "%a.name%"); update_on={editor/term_id} } + ha:term+name = { a={v; t; s}; checked=ChkTermID("%a.term%,%a.name%"); action=Display(TermID, "%a.term%,%a.name%"); update_on={editor/term_id} } + ha:user configured = { a={v; t; c}; action=Display(TermID); } + } + } + ha:Zoom and side { + 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) } + ha:Flip left/right = { checked=editor/view/flip_x; a=ShiftTab; action=SwapSides(H) } + ha:Spin 180 degrees = { a=CtrlTab; action=SwapSides(R) } + ha:Swap Sides = { a=Ctrl ShiftTab; action=SwapSides() } + - + ha:Center cursor = { a={v; c} action=Center() } + } + } + ha:Layers { + li:submenu { + ha:Shown Layers { + li:submenu { + @layerview + - + ha:Edit Layer Groups = { action=Preferences("layers") } + } + } + ha:Current Layer { + li:submenu { + anon2=@layerpick + - + ha:Delete current layer = { action=MoveLayer(c,-1) } + ha:Add new layer = { action=MoveLayer(-1,c) } + ha:Move current layer up = { action=MoveLayer(c,step-) } + ha:Move current layer down= { action=MoveLayer(c,step+) } + } + } + } + } + ha:Show padstack numbers in a subc = { a={v; n} action=Display(PinOrPadName) } + ha:Full screen = { checked=editor/fullscreen; a=\\; action=fullscreen(toggle) } + ha:Reset { + li:submenu { + ha:Reset View = { a={v; r; v}; sy:action={/scripts/view_reset}; tip={Reset all visibility related states to make sure all objects are visible} } + ha:Reset GUI = { a={v; r; g}; sy:action={/scripts/gui_reset}; tip={Reset all GUI related states } } + } + } + } + } # View + + ha:Mode = { + li:submenu { + ha:Routing { + li:submenu { + ha:'All-direction' lines = { li:a={{m; l; a}; {.};}; checked=editor/all_direction_lines; action=conf(toggle, editor/all_direction_lines, design); update_on={editor/all_direction_lines} } + ha:Cycle line clip/refraction = { li:a={{m; l; f}; {/};}; action=Display(CycleClip) } + ha:Auto swap line start angle = { checked=editor/swap_start_direction; action=conf(toggle, editor/swap_start_direction, design) } + ha:Auto enforce style clearance = { a={m; l; d}; checked=editor/auto_drc; action=conf(toggle, editor/auto_drc, design) } + ha:Automatic trace merging = { a={m; l; m}; checked=editor/trace_auto_merge; action=conf(toggle, editor/trace_auto_merge, design) } + - + ha:Rubber band mode = { a={m; r; r}; checked=editor/rubber_band_mode; action=conf(toggle, editor/rubber_band_mode, design) } + ha:Rubber band keeps middle line dir= { a={m; r; m}; checked=editor/rubber_band_keep_midlinedir; action=conf(toggle, editor/rubber_band_keep_midlinedir, design) } + - + ha:Route radius +0.5 = { li:a={{r; r; +}; {r; r; p};}; action=conf(delta, editor/route_radius, +0.5, design); } + ha:Route radius -0.5 = { li:a={{r; r; -}; {r; r; m};}; action=conf(delta, editor/route_radius, -0.5, design); } + - + ha:New lines, arcs clear polygons = { a={m; l; c}; checked=editor/clear_line; action=conf(toggle, editor/clear_line, design) } + ha:New polygons are full ones = { a={m; p; f}; checked=editor/full_poly; action=conf(toggle, editor/full_poly, design) } + ha:New polygons clear polygons = { a={m; p; c}; checked=editor/clear_polypoly; action=conf(toggle, editor/clear_polypoly, design) } + ha:Polygon clip inhibit (toggle) = { a={m; p; i}; checked=ClipInhibit(check); action=ClipInhibit(toggle); update_on={temp/clip_inhibit_chg} } + } + } + ha:Cursor/snap { + li:submenu { + ha:Orthogonal moves = { a={m; c; o}; checked=editor/orthogonal_moves; action=conf(toggle, editor/orthogonal_moves, design) } + ha:Crosshair snaps to padstacks = { a={m; c; p}; checked=editor/snap_pin; action=conf(toggle, editor/snap_pin, design) } + ha:Crosshair snaps to off-grid points on lines = { a={m; c; s};checked=editor/snap_offgrid_line; action=conf(toggle, editor/snap_offgrid_line, design) } + ha:Crosshair shows style clearance = { a={m; c; c}; checked=editor/show_drc; action=conf(toggle, editor/show_drc, design) } + } + } + ha:Drawing { + li:submenu { + @indications + ha:Show autorouter trials = { a={m; d; a}; checked=editor/live_routing; action=conf(toggle, editor/live_routing, design) } + ha:Highlighting on line, arc points = { a={m; d; h}; checked=editor/highlight_on_point; action=conf(toggle, editor/highlight_on_point, design) } + ha:Wireframe draw = { li:a={{m; d; w}; {|};}; checked=editor/wireframe_draw; action=conf(toggle, editor/wireframe_draw, design) } + ha:Thin draw = { a={m; d; t}; checked=editor/thin_draw; action=conf(toggle, editor/thin_draw, design) } + ha:Thin draw poly = { a={m; d; p}; checked=editor/thin_draw_poly; action=conf(toggle, editor/thin_draw_poly, design); update_on={editor/thin_draw_poly} } + ha:poly as-drawn frame annotation = { a={m; d; d}; checked=editor/as_drawn_poly; action=conf(toggle, editor/as_drawn_poly, design); update_on={editor/as_drawn_poly} } + ha:Check polygons = { a={m; d; c}; checked=editor/check_planes; action=conf(toggle, editor/check_planes, design) } + ha:Object list popup = { a={m; d; o}; checked=editor/click_objlist; action=conf(toggle, editor/click_objlist, design); tip={If there are multiple objects under the cursor when executing an action, present a popup dialog to select which object to operate on} } + - + ha:Lock floaters = { a={m; f; l}; checked=editor/lock_names; action=conf(toggle, editor/lock_names, design) } + ha:Only floaters = { a={m; f; o}; checked=editor/only_names; action=conf(toggle, editor/only_names, design) } + ha:Hide floaters = { a={m; f; h}; checked=editor/hide_names; action=conf(toggle, editor/hide_names, design) } + - + ha:Line Tool size +5 mil = { a={m; l; +}; action=SetValue(LineSize,+5,mil) } + ha:Line Tool size -5 mil = { a={m; l; -}; action=SetValue(LineSize,-5,mil) } + ha:Text Tool scale +10 mil = { a={m; t; +}; action=SetValue(TextScale,+10,mil) } + ha:Text Tool scale -10 mil = { a={m; t; -}; action=SetValue(TextScale,-10,mil) } + - + ha:Render color override { + li:submenu { + ha:Invisible-color on other groups = { a={m; o; i}; checked=appearance/invis_other_groups; action=conf(toggle, appearance/invis_other_groups, design) } + ha:black current group = { a={m; o; b}; checked=appearance/black_current_group; action=conf(toggle, appearance/black_current_group, design) } + } + } + - + ha:Reset = { a={m; d; r}; sy:action={/scripts/mode_reset}; tip={Reset all the above drawing modes to make sure objects are visible} } + } + } + ha:Mincut on shorts = { checked=plugins/mincut/enable; action=conf(toggle, plugins/mincut/enable, design) } + ha:Auto-zero delta measurements = { checked=editor/local_ref; action=conf(toggle, editor/local_ref, design) } + ha:Brave mode = { action=brave() } + ha:Loose subcircuits (no subc lock) = { a={m; k; s}; checked=subc(loose, check); action=subc(loose, toggle); update_on={} } + ha:Tool { + li:submenu { + ha:Via = { checked=ChkMode(via); li:a={{t;v};{F1};}; action=Tool(via); update_on={editor/mode} } + ha:Line = { checked=ChkMode(line); li:a={{t;l};{F2};}; action=Tool(line); update_on={editor/mode} } + ha:Arc = { checked=ChkMode(arc); li:a={{t;a};{F3};}; action=Tool(arc); update_on={editor/mode} } + ha:Text = { checked=ChkMode(text); li:a={{t;t};{F4};}; action=Tool(text); update_on={editor/mode} } + ha:Rectangle = { checked=ChkMode(rectangle); li:a={{t;r};{F5};}; action=Tool(rectangle); update_on={editor/mode} } + ha:Polygon = { checked=ChkMode(poly); li:a={{t;p};{F6};}; action=Tool(poly); update_on={editor/mode} } + ha:Polygon Hole = { checked=ChkMode(polyhole); a={t;h}; action=Tool(polyhole); update_on={editor/mode} } + ha:Buffer = { checked=ChkMode(buffer); li:a={{t;b};{F7};}; action=Tool(buffer); update_on={editor/mode} } + ha:Del/Remove = { checked=ChkMode(remove); li:a={{t;d};{F8};}; action=Tool(remove); update_on={editor/mode} } + ha:Rotate = { checked=ChkMode(rotate); li:a={{t;o};{F9};}; action=Tool(rotate); update_on={editor/mode} } + ha:Thermal = { checked=ChkMode(thermal); li:a={{t;e};{F10};}; action=Tool(thermal); update_on={editor/mode} } + ha:Arrow = { checked=ChkMode(arrow); li:a={{t;n};{F11};{space};}; action=Tool(arrow); update_on={editor/mode} } + ha:Insert Point = { checked=ChkMode(insert); li:a={{t;i};{Insert};}; action=Tool(insert); update_on={editor/mode} } + ha:Move = { checked=ChkMode(move); a={t;m}; action=Tool(move); update_on={editor/mode} } + ha:Copy = { checked=ChkMode(copy); a={t;c}; action=Tool(copy); update_on={editor/mode} } + ha:Lock = { checked=ChkMode(lock); li:a={{t;k};{F12};}; action=Tool(lock); update_on={editor/mode} } + ha:Cancel = { a={Escape}; action=Tool(Escape) } + } + } # Tool + } + } #Mode + + ha:Select { + li:submenu { + ha:Select all visible objects = { a={s; a; a;}; action=Select(All) } + ha:Select all found objects = { a={s; a; c;}; action=Select(Connection); tip={Select all objects that have the 'found' flag set} } + ha:Unselect all objects = { a={s; u; a;}; action=Unselect(All) } + ha:Unselect all found objects = { a={s; u; c;}; action=Unselect(Connection); tip={Unselect all objects that have the 'found' flag set} } + ha:Invert selection = { a={s; i; }; action=Select(Invert) } + - + ha:Advanced search and select = { a={s; s;} action=SearchDialog() } + - + ha:Move selected subcircuits to other side= { a={s; f;} action=Flip(SelectedElements) } + ha:Move selected objects to current layer = { a={s; l;} action=MoveToCurrentLayer(Selected) } + ha:Remove selected objects = { a={s; r;} action=RemoveSelected() } + ha:Convert selection to subcircuit = { a={s; c; s;} action=Select(ConvertSubc) } + ha:Convert selection to padstack = { a={s; c; p;} li:action={PadstackConvert(selected); Tool(buffer);} } + ha:Convert selection to extended object...= { a={s; c; e;} action=ExtobjConvFrom(Selected, @gui); } + ha:Break selection subcircuits to pieces = { a={s; b; s}; li:action={PasteBuffer(Push); PasteBuffer(5); PasteBuffer(Clear); PasteBuffer(AddSelected); RemoveSelected(); PasteBuffer(Restore); PasteBuffer(ToLayout, crosshair); PasteBuffer(Clear); PasteBuffer(Pop);} } + ha:Break selection padstack to pieces = { a={s; b; p}; action=PadstackBreakup(selected) } + ha:Change selected objects { + li:submenu { + ha:Lines -10 mil = { li:action={ChangeSize(SelectedLines,-10,mil); ChangeSize(SelectedArcs,-10,mil)} } + ha:Lines +10 mil = { li:action={ChangeSize(SelectedLines,+10,mil); ChangeSize(SelectedArcs,+10,mil)} } + ha:Texts -10 mil = { action=ChangeSize(SelectedTexts,-10,mil) } + ha:Texts +10 mil = { action=ChangeSize(SelectedTexts,+10,mil) } + - + ha:Clearance +2 mil = { action=ChangeClearSize(SelectedObjects,+2,mil) } + ha:Clearance -2 mil = { action=ChangeClearSize(SelectedObjects,-2,mil) } + - + ha:Hole -10 mil = { action=ChangeDrillSize(SelectedPadstacks,-10,mil) } + ha:Hole +10 mil = { action=ChangeDrillSize(SelectedPadstacks,+10,mil) } + - + ha:Toggle join = { action=ChangeJoin(SelectedObjects) } + } + } + } + } # Select + + ha:Buffer { + li:submenu { + ha:Rotate buffer 90 deg CCW (left) = { li:a={{b;r;l}; {ShiftF7};}; li:action={Tool(buffer); PasteBuffer(Rotate,1)} } + ha:Rotate buffer 90 deg CW (right) = { a={b;r;r}; li:action={Tool(buffer); PasteBuffer(Rotate,3)} } + ha:Arbitrarily Rotate Buffer = { a={b;r;a}; li:action={Tool(buffer); FreeRotateBuffer()} } + ha:Mirror buffer (up/down) = { a={b;m;u}; li:action={Tool(buffer); PasteBuffer(Mirror)} } + ha:Mirror buffer (left/right) = { a={b;m;l}; li:action={Tool(buffer); PasteBuffer(Rotate,1); PasteBuffer(Mirror); PasteBuffer(Rotate,3)} } + ha:Scale = { action=ScaleBuffer(); } + ha:Normalize = { a={b;n}; li:action={Tool(buffer); PasteBuffer(Rotate,1); PasteBuffer(Normalize);} } + - + ha:Clear buffer = { a={b;c;c;}; action=PasteBuffer(Clear) } + ha:Save buffer content to file = { a={b;f;s;}; action=PasteBuffer(SaveAll) } + ha:Load buffer content from file = { a={b;f;l;}; li:action={PasteBuffer(Clear); PasteBuffer(LoadAll)} } + - + ha:Convert buffer to subcircuit = { a={b;c;s}; action=PasteBuffer(ConvertSubc) } + ha:Convert buffer to padstack = { a={b;c;p}; li:action={PadstackConvert(buffer); Tool(buffer);} } + ha:Convert buffer to extended object... = { a={b;c;e}; li:action={ExtobjConvFrom(buffer, @gui); Tool(buffer);} } + ha:Break buffer subcircuits to pieces = { a={b;s;b}; action=PasteBuffer(Restore) } + ha:Break buffer padstacks to pieces = { a={b;s;p}; action=PadstackBreakup(buffer) } + ha:Save buffer subcircuit to file = { a={b;s;s}; action=Save(PasteBuffer); tip={save one subcircuits from the buffer as a footprint file} } + ha:Save buffer subcircuits as lib... { + li:submenu { + ha:in a single lib file = { a={b;s;l;f}; action=SaveLib(file, buffer); tip={save all subcircuits from the buffer as a footprint lib in a library file} } + ha:in multiple footprint files = { a={b;s;l;d}; action=SaveLib(dir, buffer); tip={save all subcircuits from the buffer in individual, numbered files} } + } + } + - + ha:Layer bindings... = { a={b;b;}; action=LayerBinding(buffer) } + ha:Buffer selection { + li:submenu { + ha:Select Buffer \#1 = { checked=ChkBuffer(1); a={b;1;} action=PasteBuffer(1); update_on={editor/buffer_number} } + ha:Select Buffer \#2 = { checked=ChkBuffer(2); a={b;2;} action=PasteBuffer(2); update_on={editor/buffer_number} } + ha:Select Buffer \#3 = { checked=ChkBuffer(3); a={b;3;} action=PasteBuffer(3); update_on={editor/buffer_number} } + ha:Select Buffer \#4 = { checked=ChkBuffer(4); a={b;4;} action=PasteBuffer(4); update_on={editor/buffer_number} } + ha:Select scratchpad = { checked=ChkBuffer(5); a={b;5;} action=PasteBuffer(5); update_on={editor/buffer_number} } + } + } + } + } # Buffer + + ha:Connects = { + li:submenu { + ha:Rats nest { + li:submenu { + ha:Optimize rats nest = { a={c;r;}; li:action={Atomic(Save); DeleteRats(AllRats); Atomic(Restore); AddRats(AllRats); Atomic(Close)} } + ha:Optimize rats nest - autorouter = { a={c;Shiftr;}; li:action={Atomic(Save); DeleteRats(AllRats); Atomic(Restore); AddRats(AllRats, manhattan); Atomic(Close)} } + ha:Erase rats nest = { a={c;e;}; action=DeleteRats(AllRats) } + - + ha:Select shortest rat = { a={c;s;}; action=AddRats(Close) } + ha:AddRats to selected pins = { li:action={Atomic(Save); DeleteRats(AllRats); Atomic(Restore); AddRats(SelectedRats); Atomic(Close)} } + ha:AddRats Selected = { action=AddRats(SelectedRats) } + ha:Add All Rats = { action=AddRats(AllRats) } + } + } + ha:Network lengths { + li:submenu { + ha:Visual length, from object = { a={n;l;o;}; action=NetLength(object) } + ha:Visual length, clear = { a={n;l;k;}; action=NetLength(clear) } + ha:Netlist dialog, refresh lengths = { a={n;l;l;}; li:action={NetlistDialog(); NetlistDialog(RefreshNetLens);}} + } + } + - + ha:Find Connections = { a={c;f;}; li:action={Connection(Reset); Connection(Find)} } + ha:Clear/reset lookup = { a={c;c;}; li:action={Connection(Reset); Display(Redraw)} } + - + ha:Del/Remove Connected = { a={c;d;}; li:action={Atomic(Save); Connection(Reset); Atomic(Restore); Unselect(All); Atomic(Restore); Connection(Find); Atomic(Restore); Select(Connection); Atomic(Restore); RemoveSelected(); Atomic(Restore); Connection(Reset); Atomic(Restore); Unselect(All); Atomic(Block)} } + - + ha:Subcircuit Placement { + li:submenu { + ha:Auto-place selected subcircuits = { a={a;p;s;}; action=AutoPlaceSelected() } + ha:Disperse all subcircuits = { a={a;d;a;}; action=DisperseElements(All) } + ha:Disperse selected subcircuits = { a={a;d;s;}; action=DisperseElements(Selected) } + } + } + ha:Automatic Routing { + li:submenu { + ha:Auto-route selected rats = { a={a;r;s;}; action=AutoRoute(SelectedRats) } + ha:Auto-route all rats = { a={a;r;a;}; action=AutoRoute(AllRats) } + @autoroute + ha:Rip up selected auto-routed tracks = { a={a;r;t;}; action=RipUp(Selected) } + ha:Rip up all auto-routed tracks = { a={a;r;r;}; action=RipUp(All) } + } + } + ha:Optimize routed tracks { + li:submenu { + ha:Auto-Optimize = { a={a;o;a;}; action=djopt(auto) } + ha:Debumpify = { a={a;o;d;}; action=djopt(debumpify) } + ha:Unjaggy = { a={a;o;u;}; action=djopt(unjaggy) } + ha:Vianudge = { a={a;o;n;}; action=djopt(vianudge) } + ha:Viatrim = { a={a;o;t;}; action=djopt(viatrim) } + ha:Ortho pull = { a={a;o;o;}; action=djopt(orthopull) } + ha:Simple optimization = { a={a;o;s;}; action=djopt(simple) } + ha:Miter = { a={a;o;m;}; action=djopt(miter) } + ha:Puller = { a={a;o;p;}; action=Puller() } + ha:Global Puller { + li:submenu { + ha:Selected = { action=GlobalPuller(selected) } + ha:Found = { action=GlobalPuller(found) } + ha:All = { action=GlobalPuller() } + } + } + - + ha:Only autorouted nets = { checked=plugins/djopt/auto_only; action=conf(toggle, plugins/djopt/auto_only, design) } + } + } + - + ha:Design Rule Checker = { a={a;x;}; action=DRC() } + - + ha:Design changes (back annotation) { + li:submenu { + ha:Swap nets on two selected pins = { a={a;b;s;}; action=net(swap) } + ha:Replace footprint = { a={a;b;f;}; action=ReplaceFootprint() } + - + ha:claim net by object = { a={n;c;o;}; action=ClaimNet(object) } + ha:claim net on found = { a={n;c;f;}; action=ClaimNet(found) } + ha:claim net on selected = { a={n;c;s;}; action=ClaimNet(selected) } + } + } + } + } # Connects + + 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:Library = { a={w;l}; action=LibraryDialog() } + ha:Message Log = { a={w;m}; action=LogDialog() } + ha:DRC Check = { a={w;d}; action=DRC() } + ha:Netlist = { a={w;n}; action=NetlistDialog() } + ha:Command Entry = { li:a={a={w;c}; {:};} action=Command() } + ha:Pinout = { a={w;p}; action=Display(Pinout) } + ha:Font selector = { a={w;f}; action=FontSel() } + - + ha:Key Bindings { + li:submenu { + ha:Cycle object being dragged = { li:a={{,};{e;y;};}; action=CycleDrag() } + + + ha:Step Cursor { + li:submenu { + ha:Step Up = { li:a={{Up};{k;k};}; action=Cursor(Warp,0,-1,grid) } + ha:Step Down = { li:a={{Down};{k;j};}; action=Cursor(Warp,0,1,grid) } + ha:Step Left = { li:a={{Left};{k;h};}; action=Cursor(Warp,-1,0,grid) } + ha:Step Right = { li:a={{Right};{k;l};}; action=Cursor(Warp,1,0,grid) } + ha:Step +Up = { a=ShiftUp; action=Cursor(Pan,0,-50,view) } + ha:Step +Down = { a=ShiftDown; action=Cursor(Pan,0,50,view) } + ha:Step +Left = { a=ShiftLeft; action=Cursor(Pan,-50,0,view) } + ha:Step +Right = { a=ShiftRight; action=Cursor(Pan,50,0,view) } + ha:Scroll Up = { li:a={{CtrlUp};{j;k};}; action=Scroll(up) } + ha:Scroll Down = { li:a={{CtrlDown};{j;j};}; action=Scroll(down) } + ha:Scroll Left = { li:a={{CtrlLeft};{j;h};}; action=Scroll(left) } + ha:Scroll Right = { li:a={{CtrlRight};{j;l};}; action=Scroll(right) } + ha:Click (left) = { li:a={{Enter};{k;space};}; li:action={Tool(Press); Tool(Release)} } + ha:Click (right) = { a={k;r}; li:action={Tool(Release); Popup(popup-obj, obj-type)} } + } + } + ha:attribute layer keys { + li:submenu { + anon3=@layerkeys + } + } + ha:generic layer keys { + li:submenu { + ha:Select previous layer = { a={l; k}; action=LayerByStack(Select, Prev); } + ha:Select next layer = { a={l; l}; action=LayerByStack(Select, Next); } + - + ha:Select Layer 1 = { a=1; action=SelectLayer(1) } + ha:Select Layer 2 = { a=2; action=SelectLayer(2) } + ha:Select Layer 3 = { a=3; action=SelectLayer(3) } + ha:Select Layer 4 = { a=4; action=SelectLayer(4) } + ha:Select Layer 5 = { a=5; action=SelectLayer(5) } + ha:Select Layer 6 = { a=6; action=SelectLayer(6) } + ha:Select Layer 7 = { a=7; action=SelectLayer(7) } + ha:Select Layer 8 = { a=8; action=SelectLayer(8) } + ha:Select Layer 9 = { a=9; action=SelectLayer(9) } + ha:Select Layer 10 = { a=0; action=SelectLayer(10) } + ha:Select Layer 11 = { a=Alt1; action=SelectLayer(11) } + ha:Select Layer 12 = { a=Alt2; action=SelectLayer(12) } + ha:Select Layer 13 = { a=Alt3; action=SelectLayer(13) } + ha:Select Layer 14 = { a=Alt4; action=SelectLayer(14) } + ha:Select Layer 15 = { a=Alt5; action=SelectLayer(15) } + ha:Select Layer 16 = { a=Alt6; action=SelectLayer(16) } + ha:Select Layer 17 = { a=Alt7; action=SelectLayer(17) } + ha:Select Layer 18 = { a=Alt8; action=SelectLayer(18) } + ha:Select Layer 19 = { a=Alt9; action=SelectLayer(19) } + ha:Select Layer 20 = { a=Alt0; action=SelectLayer(20) } + - + ha:Toggle Layer 1 = { a=Ctrl1; action=ToggleView(1) } + ha:Toggle Layer 2 = { a=Ctrl2; action=ToggleView(2) } + ha:Toggle Layer 3 = { a=Ctrl3; action=ToggleView(3) } + ha:Toggle Layer 4 = { a=Ctrl4; action=ToggleView(4) } + ha:Toggle Layer 5 = { a=Ctrl5; action=ToggleView(5) } + ha:Toggle Layer 6 = { a=Ctrl6; action=ToggleView(6) } + ha:Toggle Layer 7 = { a=Ctrl7; action=ToggleView(7) } + ha:Toggle Layer 8 = { a=Ctrl8; action=ToggleView(8) } + ha:Toggle Layer 9 = { a=Ctrl9; action=ToggleView(9) } + ha:Toggle Layer 10 = { a=Ctrl0; action=ToggleView(10) } + ha:Toggle Layer 11 = { a=Ctrl-Alt1; action=ToggleView(11) } + ha:Toggle Layer 12 = { a=Ctrl-Alt2; action=ToggleView(12) } + ha:Toggle Layer 13 = { a=Ctrl-Alt3; action=ToggleView(13) } + ha:Toggle Layer 14 = { a=Ctrl-Alt4; action=ToggleView(14) } + ha:Toggle Layer 15 = { a=Ctrl-Alt5; action=ToggleView(15) } + ha:Toggle Layer 16 = { a=Ctrl-Alt6; action=ToggleView(16) } + ha:Toggle Layer 17 = { a=Ctrl-Alt7; action=ToggleView(17) } + ha:Toggle Layer 18 = { a=Ctrl-Alt8; action=ToggleView(18) } + ha:Toggle Layer 19 = { a=Ctrl-Alt9; action=ToggleView(19) } + ha:Toggle Layer 20 = { a=Ctrl-Alt0; action=ToggleView(20) } + } + } # layer keys + + ha:polygon drawing { + li:submenu { + ha:Polygon PreviousPoint = { a={p; p; p}; action=Polygon(PreviousPoint) } + ha:Polygon Close = { a={p; p; c}; action=Polygon(Close) } + } + } + } + } + ha:About... = { li:a={{w;a}; {i;a};}; action=About() } + } + } # Window + } # main menu + + li:popups { +# context sensitive right click: popup per object type under the cursor + + ha:popup-obj-line { + li:submenu { + ha:Edit properties { action=propedit(object) } + ha:Edit flags... { action=FlagEdit() } + ha:Set Same Style { action=SetSame() } + ha:Convert to extended object... = { action=ExtobjConvFrom(Object, @gui) } + - + ha:Remove line { li:action={Tool(Save); Tool(remove); Tool(Press); Tool(Restore)} } + ha:Copy to buffer { li:action={Unselect(All); Select(object); PasteBuffer(Clear); PasteBuffer(AddSelected); Unselect(All); Tool(buffer) } } + ha:Move to current layer { action=MoveToCurrentLayer(object) } + } + } + + ha:popup-obj-arc { + li:submenu { + ha:Edit properties { action=propedit(object) } + ha:Edit flags... { action=FlagEdit() } + ha:Set Same Style { action=SetSame() } + ha:Convert to extended object... = { action=ExtobjConvFrom(Object, @gui) } + - + ha:Remove arc { li:action={Tool(Save); Tool(remove); Tool(Press); Tool(Restore)} } + ha:Copy to buffer { li:action={Unselect(All); Select(object); PasteBuffer(Clear); PasteBuffer(AddSelected); Unselect(All); Tool(buffer) } } + ha:Move to current layer { action=MoveToCurrentLayer(object) } + } + } + + ha:popup-obj-polygon { + li:submenu { + ha:Edit properties { action=propedit(object) } + ha:Edit flags... { action=FlagEdit() } + ha:Convert to extended object... = { action=ExtobjConvFrom(Object, @gui) } + - + ha:Remove polygon { li:action={Tool(Save); Tool(remove); Tool(Press); Tool(Restore)} } + ha:Copy to buffer { li:action={Unselect(All); Select(object); PasteBuffer(Clear); PasteBuffer(AddSelected); Unselect(All); Tool(buffer) } } + ha:Move to current layer { action=MoveToCurrentLayer(object) } + } + } + + ha:popup-obj-text { + li:submenu { + ha:Edit properties { action=propedit(object) } + ha:Edit flags... { action=FlagEdit() } + ha:Edit text... { li:a={{e;t};}; action=ChangeName(Object) } + ha:Set Same Style { action=SetSame() } + ha:Convert to extended object... = { action=ExtobjConvFrom(Object, @gui) } + ha:Change font... { li:a={{e;o};} action=FontSel(Object) } + ha:Toggle tight clearance { action=PropToggle(object, a/tight_clearance, true); } + - + ha:Remove text { li:action={Tool(Save); Tool(remove); Tool(Press); Tool(Restore)} } + ha:Copy to buffer { li:action={Unselect(All); Select(object); PasteBuffer(Clear); PasteBuffer(AddSelected); Unselect(All); Tool(buffer) } } + ha:Move to current layer { action=MoveToCurrentLayer(object) } + } + } + + ha:popup-obj-padstack { + li:submenu { + ha:Edit properties { action=propedit(object) } + ha:Edit geometry/prototype {action=padstackedit } + ha:Edit flags... { action=FlagEdit() } + ha:Set Same Style { action=SetSame() } + - + ha:Remove padstack { li:action={Tool(Save); Tool(remove); Tool(Press); Tool(Restore)} } + ha:Break up padstack { action=PadstackBreakup(object) } + ha:Copy to buffer { li:action={Unselect(All); Select(object); PasteBuffer(Clear); PasteBuffer(AddSelected); Unselect(All); Tool(buffer) } } + } + } + + ha:popup-obj-padstack-in-subc { + li:submenu { + ha:Edit properties { action=propedit(object) } + ha:Edit geometry/prototype {action=padstackedit } + ha:Set Same Style { action=SetSame() } + } + } + + ha:popup-obj-subcircuit { + li:submenu { + ha:Edit properties { action=propedit(object) } + ha:External editor... { action=extedit(object) } + ha:Edit flags... { action=FlagEdit() } + ha:Edit layer bindings... { action=LayerBinding() } + ha:Change refdes { li:a={{e;r};}; action=ChangeName(Refdes) } + ha:Edit padstack prototypes... = { action=pstklib(object) } + ha:Convert back to extended object { action=ExtobjToggle(object) } + +#TODO: replace from lib + - + ha:Remove subcircuit { li:action={Tool(Save); Tool(remove); Tool(Press); Tool(Restore)} } + ha:Copy to buffer { li:action={Unselect(All); Select(object); PasteBuffer(Clear); PasteBuffer(AddSelected); Unselect(All); Tool(buffer) } } + ha:Move to other side { action=Flip(object) } + } + } + + ha:popup-obj-extobj-subcircuit { + li:submenu { + ha:Edit extobj properties (generic) { action=propedit(subc) } + ha:Edit extobj properties (specific) { action=ExtobjGUIPropEdit(object) } + ha:Edit extobj layer bindings... { action=LayerBinding() } + ha:Edit extobjpadstack prototypes... { action=pstklib(object) } + ha:Convert to plain subcircuit { action=ExtobjToggle(object) } + } + } + + ha:popup-obj-gfx { + li:submenu { + ha:Edit properties { action=propedit(object) } + ha:Edit flags... { action=FlagEdit() } + - + {ha:Render level: under} { action=propset(object, "a/render_level", "under") } + {ha:Render level: above} { action=propset(object, "a/render_level", "above") } + {ha:Set transparent pixel...} { action=GfxMod(transparent) } + {ha:Resize to measured...} { action=GfxMod(resize) } + - + ha:Remove gfx { li:action={Tool(Save); Tool(remove); Tool(Press); Tool(Restore)} } + ha:Copy to buffer { li:action={Unselect(All); Select(object); PasteBuffer(Clear); PasteBuffer(AddSelected); Unselect(All); Tool(buffer) } } + ha:Move to current layer { action=MoveToCurrentLayer(object) } + } + } + + + ha:popup-obj-misc { + li:submenu { + ha:Operations on selections { + li:submenu { + ha:Unselect all objects = { action=Unselect(All) } + ha:Remove selected objects = { action=RemoveSelected() } + ha:Copy selection to buffer = { li:action={GetXY(Click to set the snap point for this buffer); PasteBuffer(Clear); PasteBuffer(AddSelected); Tool(buffer)} } + ha:Cut selection to buffer = { li:action={GetXY(Click to set the snap point for this buffer); PasteBuffer(Clear); PasteBuffer(AddSelected); RemoveSelected(); Tool(buffer)} } + ha:Convert selection to subcircuit = { action=Select(ConvertSubc) } + ha:Convert selection to extended object... = { action=ExtobjConvFrom(selected, @gui) } + ha:Auto place selected subcircuits = { action=AutoPlaceSelected() } + ha:Autoroute selected subcircuits = { action=AutoRoute(SelectedRats) } + ha:Rip up selected auto-routed tracks = { action=RipUp(Selected) } + ha:Rotate selected = { action={GetXY(Click to set the snap point for this buffer); PasteBuffer(Clear); PasteBuffer(AddSelected); RemoveSelected(); Tool(buffer) FreeRotateBuffer(); Tool(buffer); PasteBuffer(Tolayout, crosshair); } } + } + } + ha:Operations on this location { + li:submenu { + ha:Generate object report = { li:action={GetXY(Click on the object); Report(Object)} } + } + } + - + ha:Undo last operation = { action=Undo() } + ha:Redo last undone operation = { action=Redo() } + } + } # popup-obj-misc + + ha:layer { + li:submenu { + ha:Layer name and flags... = { action=EditLayer() } + ha:Layer properties... = { action=Propedit(layer) } + ha:Grouping... (layer preferences) = { action=Preferences("layers") } + ha:Hotkey { + li:submenu { + ha:Selection... = { action=LayerHotkey("¤t", select) } + ha:Visibility... = { action=LayerHotkey("¤t", vis) } + } + } + - + ha:Move up (within group) = { action=MoveLayer(c, step-) } + ha:Move down (within group) = { action=MoveLayer(c, step+) } + - + ha:Remove layer = { action=MoveLayer(c, -1) } + ha:Insert new, before this layer = { action={ MoveLayer(-1, c); EditLayer() } } + ha:Insert new, after this layer = { action={ Undo(FreezeSerial); MoveLayer(-1, c); MoveLayer(c, step+); Undo(UnFreezeSerial); Undo(IncSerial); EditLayer() } } + - + ha:all layers on = { a={l;v;}; action=ToggleView(all, vis, set) } + ha:all layers off = { a={l;h;}; action=ToggleView(all, vis, clear) } + } + } # layer + + ha:group { + li:submenu { + ha:Group name & type... = { action=EditGroup(@) } + ha:Group properties... = { action={Propedit(layergrp:editgroup)} } + ha:Grouping... (layer preferences) = { action=Preferences("layers") } + - + ha:Duplicate group = { action={ DupGroup(@) } } + ha:Create new group { + li:submenu { + ha:Boundary (board outline) { + li:submenu { + ha:Boundary, unplated, routed = { action={ NewGroup(boundary, global, uroute) } } + ha:Boundary, plated, routed = { action={ NewGroup(boundary, global, proute) } } + ha:Boundary, unplated, cut = { action={ NewGroup(boundary, global, ucut) } } + ha:Boundary, unplated, vcut = { action={ NewGroup(boundary, global, uvcut) } } + } + } + ha:Slots, cutouts, adhesive, finish { + li:submenu { + ha:Slot, unplated, routed = { action={ NewGroup(mech, global, uroute, auto) } } + ha:Slot, plated, routed = { action={ NewGroup(mech, global, proute, auto) } } + ha:Adhesive, top side = { action={ NewGroup(mech, top, adhesive, -, top-adhesive) } } + ha:Adhesive, bottom side = { action={ NewGroup(mech, bot, adhesive, -, bot-adhesive) } } + ha:Gold finish, top side = { action={ NewGroup(mech, top, finish.gold, -, top-gold) } } + ha:Gold finish, bottom side = { action={ NewGroup(mech, bot, finish.gold, -, bot-gold) } } + ha:Carbon finish, top side = { action={ NewGroup(mech, top, finish.carbon, -, top-carbon) } } + ha:Carbon finish, bottom side = { action={ NewGroup(mech, bot, finish.carbon, -, bot-carbon) } } + } + } + ha:Keepouts { + li:submenu { + ha:Courtyard (comp. body), top = { action={ NewGroup(doc, top, ko.courtyard, -, top-courtyard, "init-invis=true") } } + ha:Courtyard (comp. body), bottom = { action={ NewGroup(doc, bottom, ko.courtyard, -, bot-courtyard, "init-invis=true") } } + ha:Copper, top side = { action={ NewGroup(doc, top, ko@top-copper, -, top-copper-ko, "init-invis=true") } } + ha:Copper, bottom side = { action={ NewGroup(doc, bottom, ko@bottom-copper, -, bot-copper-ko, "init-invis=true") } } + ha:Silk, top side = { action={ NewGroup(doc, top, ko@top-silk, -, top-silk-ko, "init-invis=true") } } + ha:Silk, bottom side = { action={ NewGroup(doc, bottom, ko@bottom-silk, -, bot-silk-ko, "init-invis=true") } } + ha:Mask, top side = { action={ NewGroup(doc, top, ko@top-mask, -, top-mask-ko, "init-invis=true") } } + ha:Mask, bottom side = { action={ NewGroup(doc, bottom, ko@bottom-mask, -, bot-mask-ko, "init-invis=true") } } + ha:Paste, top side = { action={ NewGroup(doc, top, ko@top-paste, -, top-paste-ko, "init-invis=true") } } + ha:Paste, bottom side = { action={ NewGroup(doc, bottom, ko@bottom-paste, -, bot-paste-ko, "init-invis=true") } } + } + } + ha:Fab & assy { + li:submenu { + ha:assy, top side = { action={ NewGroup(doc, top, assy, -, top-assy, "init-invis=true") } } + ha:assy, bottom side = { action={ NewGroup(doc, bottom, assy, -, bot-assy, "init-invis=true") } } + ha:fab, top side = { action={ NewGroup(doc, top, fab, auto, fab, "init-invis=true") } } + } + } + ha:Doc, misc { + li:submenu { + ha:Doc, top side = { action={ NewGroup(doc, top) } } + ha:Doc, bottom side = { action={ NewGroup(doc, bottom) } } + ha:Doc, global = { action={ NewGroup(doc, global) } } + ha:placement, top side = { action={ NewGroup(doc, top, placement, -, top-place, "init-invis=true") } } + ha:placement, bottom side = { action={ NewGroup(doc, bottom, placement, -, bot-place, "init-invis=true") } } + ha:placement, global = { action={ NewGroup(doc, global, placement, -, place, "init-invis=true") } } + } + } + ha:Physical (silk, mask, paste) { + li:submenu { + ha:Top paste = { action={ NewGroup(paste, top, "", auto, "top_paste", "", unique_first) } } + ha:Top silk = { action={ NewGroup(silk, top, "", auto, "top_silk", "", unique_first) } } + ha:Top mask = { action={ NewGroup(mask, top, "", auto, "top_mask", "", unique_first) } } + ha:Bottom mask = { action={ NewGroup(mask, bottom, "", auto, "bottom_mask", "", unique_last) } } + ha:Bottom silk = { action={ NewGroup(silk, bottom, "", auto, "bottom_silk", "", unique_last) } } + ha:Bottom paste = { action={ NewGroup(paste, bottom, "", auto, "bottom_paste", "", unique_last) } } + } + } + + } + } + ha:Remove group = { action={ DelGroup(@) } } + - + ha:Insert new layer = { action={ MoveLayer(-1, gi); EditLayer() } } + ha:Append new layer = { action={ MoveLayer(-1, ga); EditLayer() } } + - + ha:expand groups = { action=ToggleView(all, open, set) } + ha:collapse groups = { action=ToggleView(all, open, clear) } + ha:all layers on = { action=ToggleView(all, vis, set) } + ha:all layers off = { action=ToggleView(all, vis, clear) } + } + } # group + + } # popups + + ha:scripts { + + # set all visibility related conf nodes (view/mode/drawing in the menu) + # to safe defaults that makes sure everything is visible + mode_reset { + conf(set, editor/live_routing, 0, design); + conf(set, editor/wireframe_draw, 0, design); + conf(set, editor/wireframe_draw, 0, design); + conf(set, editor/thin_draw, 0, design); + conf(set, editor/thin_draw_poly, 0, design); + conf(set, editor/as_drawn_poly, 0, design); + conf(set, editor/check_planes, 0, design); + conf(set, editor/lock_names, 0, design); + conf(set, editor/only_names, 0, design); + conf(set, editor/hide_names, 0, design); + conf(set, appearance/invis_other_groups, 0, design); + conf(set, appearance/black_current_group, 0, design); + } + + # set all visibility related states to safe defaults that makes sure + # everything is visible + li:view_reset { + sy:mdr = {/scripts/mode_reset} + LayerVisReset(); + zoom(); + } + + # set all GUI states to safe defaults to get the UI to a known state + li:gui_reset { + sy:vr = {/scripts/view_reset} + fullscreen(off); + conf(set, editor/draw_grid, 1, design); + conf(set, plugins/hid_gtk/local_grid/enable, 0, design); + Display(SubcID, "%a.refdes%"); + Display(TermID, "%a.term%"); + conf(set, editor/all_direction_lines, 0, design); + conf(set, editor/auto_drc, 0, design); + conf(set, editor/rubber_band_mode, 0, design); + conf(set, editor/orthogonal_moves, 0, design); + conf(set, editor/snap_pin, 1, design); + conf(set, editor/snap_offgrid_line, 1, design); + conf(set, editor/show_drc, 0, design); + conf(set, editor/highlight_on_point, 0, design); + subc(loose, off); + Tool(arrow); + } + } +} # root Index: tags/2.3.0/src/pcb_minuid.c =================================================================== --- tags/2.3.0/src/pcb_minuid.c (nonexistent) +++ tags/2.3.0/src/pcb_minuid.c (revision 33253) @@ -0,0 +1,14 @@ +#include +#include +#include "pcb_minuid.h" + +minuid_session_t pcb_minuid; + + +void pcb_minuid_init(void) +{ + int pid = rnd_getpid(); + minuid_init(&pcb_minuid); + minuid_salt(&pcb_minuid, &pid, sizeof(pid)); +} + Index: tags/2.3.0/src/pcb_minuid.h =================================================================== --- tags/2.3.0/src/pcb_minuid.h (nonexistent) +++ tags/2.3.0/src/pcb_minuid.h (revision 33253) @@ -0,0 +1,4 @@ +#include +extern minuid_session_t pcb_minuid; + +void pcb_minuid_init(void); Index: tags/2.3.0/src/pixmap_pcb.c =================================================================== --- tags/2.3.0/src/pixmap_pcb.c (nonexistent) +++ tags/2.3.0/src/pixmap_pcb.c (revision 33253) @@ -0,0 +1,164 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include +#include +#include "pixmap_pcb.h" +#include "obj_common.h" + +#define ROT_DEBUG 0 + +pcb_pixmap_hash_t pcb_pixmaps; + +void pcb_pixmap_hash_init(pcb_pixmap_hash_t *pmhash) +{ + htpp_init(&pmhash->meta, rnd_pixmap_hash_meta, rnd_pixmap_eq_meta); + htpp_init(&pmhash->pixels, rnd_pixmap_hash_pixels, rnd_pixmap_eq_pixels); +} + +void pcb_pixmap_hash_uninit(pcb_pixmap_hash_t *pmhash) +{ + htpp_uninit(&pmhash->meta); + htpp_uninit(&pmhash->pixels); +} + +rnd_pixmap_t *pcb_pixmap_insert_neutral_or_free(pcb_pixmap_hash_t *pmhash, rnd_pixmap_t *pm) +{ + rnd_pixmap_t *r; + + if ((pm->tr_rot != 0) || pm->tr_xmirror || pm->tr_ymirror) + return NULL; + + r = htpp_get(&pmhash->pixels, pm); + if (r != NULL) { + rnd_pixmap_free(pm); + return r; + } + + htpp_set(&pmhash->meta, pm, pm); + htpp_set(&pmhash->pixels, pm, pm); + + return pm; +} + +rnd_pixmap_t *pcb_pixmap_insert_neutral_dup(rnd_hidlib_t *hl, pcb_pixmap_hash_t *pmhash, const rnd_pixmap_t *pm) +{ + rnd_pixmap_t *r; + + if ((pm->tr_rot != 0) || pm->tr_xmirror || pm->tr_ymirror) + return NULL; + + r = htpp_get(&pmhash->pixels, pm); + if (r != NULL) + return r; + + r = rnd_pixmap_dup(hl, pm); + htpp_set(&pmhash->meta, r, r); + htpp_set(&pmhash->pixels, r, r); + + return r; +} + +rnd_pixmap_t *pcb_pixmap_alloc_insert_transformed(pcb_pixmap_hash_t *pmhash, rnd_pixmap_t *ipm, rnd_angle_t rot, int xmirror, int ymirror) +{ + rnd_pixmap_t *pm; + pcb_xform_mx_t mx = PCB_XFORM_MX_IDENT; + long n, len; + int x, y, ix, iy, ox, oy; + unsigned char *ip, *op; + + if ((rot == 0) && !xmirror && !ymirror) + return ipm; /* xformed == neutral */ + + pm = calloc(sizeof(rnd_pixmap_t), 1); + if (ipm->has_transp) { + pm->tr = ipm->tr; + pm->tg = ipm->tg; + pm->tb = ipm->tb; + } + else + pm->tr = pm->tg = pm->tb = 127; + pm->neutral_oid = ipm->neutral_oid; + pm->tr_rot = rot; + pm->tr_xmirror = xmirror; + pm->tr_ymirror = ymirror; + pm->tr_xscale = 1.0; + pm->tr_yscale = 1.0; + pm->has_transp = 1; + + + TODO("gfx: apply mirrors"); + pcb_xform_mx_rotate(mx, rot); + + + pm->sx = pcb_xform_x(mx, (ipm->sx/2)+1, (ipm->sy/2)+1) * 2; + pm->sy = pcb_xform_y(mx, -(ipm->sx/2)-1, (ipm->sy/2)-1) * 2; + + /* alloc and fill with transparent */ + len = pm->sx * pm->sy * 3; + pm->p = malloc(len); + for(n = 0; n < len; n += 3) { + pm->p[n+0] = pm->tr; + pm->p[n+1] = pm->tg; + pm->p[n+2] = pm->tb + ROT_DEBUG; + } + + ip = ipm->p; + for(y = 0; y < ipm->sy; y++) { + iy = y - ipm->sy/2; + for(x = 0; x < ipm->sx; x++, ip+=3) { + ix = x - ipm->sx/2; + ox = pcb_xform_x(mx, ix, iy) + pm->sx/2; + oy = pcb_xform_y(mx, ix, iy) + pm->sy/2; + if ((ox < 0) || (ox >= pm->sx) || (oy < 0) || (oy >= pm->sy)) + continue; + op = pm->p + (oy * pm->sx + ox) * 3; + op[0] = ip[0]; + op[1] = ip[1]; + op[2] = ip[2]; + } + } + +TODO("create the transformed version if not in the cache already (by headers)"); + + return pm; +} + +void pcb_pixmap_init(void) +{ + pcb_pixmap_hash_init(&pcb_pixmaps); +} + +void pcb_pixmap_uninit(void) +{ + pcb_pixmap_hash_uninit(&pcb_pixmaps); + rnd_pixmap_uninit(); +} Index: tags/2.3.0/src/pixmap_pcb.h =================================================================== --- tags/2.3.0/src/pixmap_pcb.h (nonexistent) +++ tags/2.3.0/src/pixmap_pcb.h (revision 33253) @@ -0,0 +1,68 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* pcb-rnd specific parts (how to store and look up pixmaps) */ + +#ifndef PCB_PIXMAP_PCB_H +#define PCB_PIXMAP_PCB_H + +#include +#include + +#include + +typedef struct pcb_pixmap_hash_s { + htpp_t meta; /* all pixmaps, hashed and compared only by metadata (including natural_oid) - used to look up a specific transformed version */ + htpp_t pixels; /* all pixmaps, hashed and compared by the pixels (but not natural_oid) - used to look up a specific pixel array */ +} pcb_pixmap_hash_t; + +void pcb_pixmap_hash_init(pcb_pixmap_hash_t *pmhash); +void pcb_pixmap_hash_uninit(pcb_pixmap_hash_t *pmhash); + +/* Either inserts pm in the board's pixmap hash, if pm is new there, or frees + pm and returns the matching pixmap from the board's pixmap hash. pm must + be in neutral position (no rotation, no mirror). Returns NULL on error. */ +rnd_pixmap_t *pcb_pixmap_insert_neutral_or_free(pcb_pixmap_hash_t *pmhash, rnd_pixmap_t *pm); + +/* Same but doesn't free pm but dups it when inserted; returns the dup'd pixmap + from the hash. */ +rnd_pixmap_t *pcb_pixmap_insert_neutral_dup(rnd_hidlib_t *hl, pcb_pixmap_hash_t *pmhash, const rnd_pixmap_t *pm); + + +/* Allocate and render a transformed version of pm (or return the one from cache if already cached */ +rnd_pixmap_t *pcb_pixmap_alloc_insert_transformed(pcb_pixmap_hash_t *pmhash, rnd_pixmap_t *pm, rnd_angle_t rot, int xmirror, int ymirror); + + +/*** global state ***/ + +void pcb_pixmap_init(void); +void pcb_pixmap_uninit(void); + +/* global pixmap hash: buffers may reference the same pixmaps so keep a common + cache */ +extern pcb_pixmap_hash_t pcb_pixmaps; + +#endif Index: tags/2.3.0/src/plug_footprint.c =================================================================== --- tags/2.3.0/src/plug_footprint.c (nonexistent) +++ tags/2.3.0/src/plug_footprint.c (revision 33253) @@ -0,0 +1,575 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include + +#include "plug_footprint.h" +#include + +#include +#include +#include "conf_core.h" +#include "actions_pcb.h" +#include "plug_io.h" +#include +#include +#include +#include "event.h" + +static const int PCB_FP_FOPEN_IN_DST_; + +/* This is safe because PCB_FP_FOPEN_IN_DST is never dereferenced */ +FILE *PCB_FP_FOPEN_IN_DST = (FILE *)&PCB_FP_FOPEN_IN_DST_; + + +pcb_plug_fp_t *pcb_plug_fp_chain = NULL; +pcb_fplibrary_t pcb_library; + +static pcb_fplibrary_t *pcb_get_library_memory(pcb_fplibrary_t *parent) +{ + pcb_fplibrary_t *res; + vtlib_t *vt = ((parent) == NULL ? &pcb_library.data.dir.children : &(parent)->data.dir.children); + void *old = vt->array; + + res = vtlib_alloc_append(vt, 1); + res->parent = parent; + + if (vt->array != old) { /* if the vector array had to be relocated, update all parent pointers */ + long n, i; +TODO("TODO39: replace vtlib with vtp0 so no need to update parents"); + for(n = 0; n < vt->used; n++) { + pcb_fplibrary_t *l = &vt->array[n]; + if (l->type == PCB_LIB_DIR) + for(i = 0; i < l->data.dir.children.used; i++) + l->data.dir.children.array[i].parent = l; + } + } + + return res; +} + + +int pcb_fp_dupname(const char *name, char **basename, char **params) +{ + char *newname, *s; + + *basename = newname = rnd_strdup(name); + s = strchr(newname, '('); + if (s == NULL) { + *params = NULL; + return 0; + } + + /* split at '(' */ + *s = '\0'; + *params = s + 1; + + /* strip ')' */ + s = *params + strlen(*params) - 1; + while(isspace(*s) && (s > *params)) s--; + if (*s == ')') + *s = '\0'; + + return 1; +} + +static htsp_t *fp_tags = NULL; + +const void *pcb_fp_tag(const char *tag, int alloc) +{ + htsp_entry_t *e; + static char *counter = NULL; + + if (fp_tags == NULL) + fp_tags = htsp_alloc(strhash, strkeyeq); + e = htsp_getentry(fp_tags, tag); + if ((e == NULL) && alloc) { + htsp_set(fp_tags, rnd_strdup(tag), (void *) counter); + counter++; + e = htsp_getentry(fp_tags, tag); + } + return e == NULL ? NULL : e->key; +} + +void pcb_fp_init() +{ + pcb_library.type = PCB_LIB_DIR; + pcb_library.name = rnd_strdup("/"); /* All names are eventually free()'d */ +} + +void pcb_fp_uninit() +{ + htsp_entry_t *e; + + if (pcb_plug_fp_chain != NULL) + rnd_message(RND_MSG_ERROR, "pcb_plug_fp_chain is not empty; a plugin did not remove itself from the chain. Fix your plugins!\n"); + + pcb_fp_free_children(&pcb_library); + if (fp_tags != NULL) { + for (e = htsp_first(fp_tags); e; e = htsp_next(fp_tags, e)) + free(e->key); + htsp_free(fp_tags); + fp_tags = NULL; + } + free(pcb_library.name); + pcb_library.name = NULL; +} + +const char *pcb_fp_tagname(const void *tagid) +{ + return (char *) tagid; +} + +FILE *pcb_fp_fopen(const rnd_conflist_t *path, const char *name, pcb_fp_fopen_ctx_t *fctx, pcb_data_t *dst) +{ + rnd_conf_listitem_t *ci; + FILE *res = NULL; + char *sep = strstr(name, "::"); + + if (sep != NULL) { + long offs = sep - name; + fctx->filename = rnd_strdup(name); + sep = (char *)fctx->filename + offs; + *sep = '\0'; + fctx->free_filename = 0; + fctx->subfpname = sep+2; + fctx->free_filename = 1; + } + else { + fctx->filename = name; + fctx->subfpname = NULL; + fctx->free_filename = 0; + } + + for(ci = rnd_conflist_first((rnd_conflist_t *)path); ci != NULL; ci = rnd_conflist_next(ci)) { + const char *curr = ci->val.string[0]; + RND_HOOK_CALL(pcb_plug_fp_t, pcb_plug_fp_chain, fp_fopen, res, != NULL, (self, curr, fctx->filename, fctx, dst)); + if (res != NULL) + return res; + } + + fctx->backend = NULL; + return NULL; +} + +void pcb_fp_fclose(FILE * f, pcb_fp_fopen_ctx_t *fctx) +{ + if ((fctx->backend != NULL) && (fctx->backend->fp_fclose != NULL)) + fctx->backend->fp_fclose(fctx->backend, f, fctx); + if (fctx->free_filename) + free((char *)fctx->filename); + fctx->filename = NULL; + fctx->free_filename = 0; +} + +static void **pcb_fp_dup_tags(void *tags[]) +{ + long len = 0; + void **src, **dst, **res; + + if (tags == NULL) + return NULL; + + for(src = tags; *src != NULL; src++) len++; + + res = malloc(sizeof(void *) * (len+1)); + + for(src = tags, dst = res; *src != NULL; src++, dst++) + *dst = *src; /* these are coming from the central hash, it is safe to keep them */ + + *dst = NULL; + return res; +} + +pcb_fplibrary_t *pcb_fp_append_entry(pcb_fplibrary_t *parent, const char *name, pcb_fptype_t type, void *tags[], rnd_bool dup_tags) +{ + pcb_fplibrary_t *entry; /* Pointer to individual menu entry */ + + assert(parent->type == PCB_LIB_DIR); + entry = pcb_get_library_memory(parent); + if (entry == NULL) + return NULL; + + if (type == PCB_FP_PARAMETRIC) { + /* concat name and () */ + /* do not use rnd_strdup_printf or Concat here, do not increase gsch2pcb-rnd deps */ + int nl = strlen(name); + entry->name = malloc(nl+3); + memcpy(entry->name, name, nl); + strcpy(entry->name+nl, "()"); + } + else + entry->name = rnd_strdup(name); + + entry->type = PCB_LIB_FOOTPRINT; + entry->data.fp.type = type; + entry->data.fp.tags = dup_tags ? pcb_fp_dup_tags(tags) : tags; + entry->data.fp.loc_info = NULL; + entry->data.fp.backend_data = NULL; + return entry; +} + +pcb_fplibrary_t *fp_lib_search_len(pcb_fplibrary_t *dir, const char *name, int name_len) +{ + pcb_fplibrary_t *l; + int n; + + if (dir->type != PCB_LIB_DIR) + return NULL; + + for(n = 0, l = dir->data.dir.children.array; n < dir->data.dir.children.used; n++, l++) + if (strncmp(l->name, name, name_len) == 0) + return l; + + return NULL; +} + +pcb_fplibrary_t *pcb_fp_lib_search(pcb_fplibrary_t *dir, const char *name) +{ + pcb_fplibrary_t *l; + int n; + + if (dir->type != PCB_LIB_DIR) + return NULL; + + for(n = 0, l = dir->data.dir.children.array; n < dir->data.dir.children.used; n++, l++) + if (strcmp(l->name, name) == 0) + return l; + + return NULL; +} + + +pcb_fplibrary_t *pcb_fp_mkdir_len(pcb_fplibrary_t *parent, const char *name, int name_len) +{ + pcb_fplibrary_t *l = pcb_get_library_memory(parent); + + if (name_len > 0) + l->name = rnd_strndup(name, name_len); + else + l->name = rnd_strdup(name); + l->type = PCB_LIB_DIR; + l->data.dir.backend = NULL; + vtlib_init(&l->data.dir.children); + return l; +} + +pcb_fplibrary_t *pcb_fp_mkdir_p(const char *path) +{ + pcb_fplibrary_t *l, *parent = NULL; + const char *next; + + /* search for the last existing dir in the path */ + + while(*path == '/') path++; + for(parent = l = &pcb_library; l != NULL; parent = l,path = next) { + next = strchr(path, '/'); + if (next == NULL) + l = pcb_fp_lib_search(l, path); + else + l = fp_lib_search_len(l, path, next-path); + + /* skip path sep */ + if (next != NULL) { + while(*next == '/') next++; + if (*next == '\0') + next = NULL; + } + + /* last elem of the path */ + if (next == NULL) { + if (l != NULL) + return l; + break; /* found a non-existing node */ + } + + if (l == NULL) + break; + } + + /* by now path points to the first non-existing dir, under parent */ + for(;path != NULL; path = next) { + next = strchr(path, '/'); + parent = pcb_fp_mkdir_len(parent, path, next-path); + if (next != NULL) { + while(*next == '/') next++; + if (*next == '\0') + next = NULL; + } + } + + return parent; +} + +static int fp_sort_cb(const void *a, const void *b) +{ + const pcb_fplibrary_t *fa = a, *fb = b; + int res = strcmp(fa->name, fb->name); + return res == 0 ? 1 : res; +} + +void pcb_fp_sort_children(pcb_fplibrary_t *parent) +{ + vtlib_t *v; + int n, i; + + if (parent->type != PCB_LIB_DIR) + return; + + v = &parent->data.dir.children; + qsort(v->array, vtlib_len(v), sizeof(pcb_fplibrary_t), fp_sort_cb); + + for (n = 0; n < vtlib_len(v); n++) { + for(i = 0; i < v->used; i++) /* TODO39 */ + v->array[i].parent = parent; + pcb_fp_sort_children(&v->array[n]); + } +} + +void fp_free_entry(pcb_fplibrary_t *l) +{ + switch(l->type) { + case PCB_LIB_DIR: + pcb_fp_free_children(l); + vtlib_uninit(&(l->data.dir.children)); + break; + case PCB_LIB_FOOTPRINT: + if (l->data.fp.loc_info != NULL) + free(l->data.fp.loc_info); + if (l->data.fp.tags != NULL) + free(l->data.fp.tags); + break; + case PCB_LIB_INVALID: break; /* suppress compiler warning */ + } + if (l->name != NULL) { + free(l->name); + l->name = NULL; + } + l->type = PCB_LIB_INVALID; +} + +void pcb_fp_free_children(pcb_fplibrary_t *parent) +{ + int n; + pcb_fplibrary_t *l; + + assert(parent->type == PCB_LIB_DIR); + + for(n = 0, l = parent->data.dir.children.array; n < parent->data.dir.children.used; n++, l++) + fp_free_entry(l); + + vtlib_truncate(&(parent->data.dir.children), 0); +} + + +void pcb_fp_rmdir(pcb_fplibrary_t *dir) +{ + pcb_fplibrary_t *l, *parent = dir->parent; + int n; + fp_free_entry(dir); + if (parent != NULL) { + for(n = 0, l = parent->data.dir.children.array; n < parent->data.dir.children.used; n++,l++) { + if (l == dir) { + vtlib_remove(&(parent->data.dir.children), n, 1); + break; + } + } + } +} + +/* Debug functions */ +void fp_dump_dir(pcb_fplibrary_t *dir, int level) +{ + pcb_fplibrary_t *l; + int n, p; + + for(n = 0, l = dir->data.dir.children.array; n < dir->data.dir.children.used; n++, l++) { + for(p = 0; p < level; p++) + putchar(' '); + if (l->type == PCB_LIB_DIR) { + printf("%s/\n", l->name); + fp_dump_dir(l, level+1); + } + else if (l->type == PCB_LIB_FOOTPRINT) + printf("%s\n", l->name); + else + printf("*INVALID*\n"); + } +} + +void fp_dump() +{ + fp_dump_dir(&pcb_library, 0); +} + +/* This function loads the newlib footprints into the Library. + * It examines all directories pointed to by the search paths + * (usually from conf node rc/library_search_paths) + * In each directory specified there, it looks both in that directory, + * as well as *one* level down. It calls the subfunction + * fp_fs_load_dir to put the footprints into PCB's internal + * datastructures. + */ +static int fp_read_lib_all_(const rnd_conflist_t *searchpath) +{ + rnd_conf_listitem_t *ci; + char *toppath, toppath_[RND_PATH_MAX + 1]; /* String holding abs path to top level library dir */ + int n_footprints = 0; /* Running count of footprints found */ + int res; + + for(ci = rnd_conflist_first((rnd_conflist_t *)searchpath); ci != NULL; ci = rnd_conflist_next(ci)) { + const char *p = ci->val.string[0]; + int silent_fail = 0; + + /* remove trailing path delimiter */ + strncpy(toppath_, p, sizeof(toppath_) - 1); + toppath_[sizeof(toppath_) - 1] = '\0'; + + /* make paths starting with '?' optional (silently fail) */ + toppath = toppath_; + if (toppath[0] == '?') { + toppath++; + silent_fail = 1; + } + +#ifdef DEBUG + printf("In ParseLibraryTree, looking for newlib footprints inside top level directory %s ... \n", toppath); +#endif + + /* Next read in any footprints in the top level dir */ + res = -1; + RND_HOOK_CALL(pcb_plug_fp_t, pcb_plug_fp_chain, load_dir, res, >= 0, (self, toppath, 0)); + if (res >= 0) + n_footprints += res; + else if (!silent_fail) + rnd_message(RND_MSG_WARNING, "Warning: footprint library list error on %s\n", toppath); + } + +#ifdef DEBUG + printf("Leaving ParseLibraryTree, found %d footprints.\n", n_footprints); +#endif + + return n_footprints; +} + +static gds_t fpds_paths; +static int fpds_inited = 0; + +int pcb_fp_host_uninit(void) +{ + if (fpds_inited) + gds_uninit(&fpds_paths); + return 0; +} + +int pcb_fp_read_lib_all(void) +{ + FILE *resultFP = NULL; + + /* List all footprint libraries. Then sort the whole + * library. + */ + if (fp_read_lib_all_(&conf_core.rc.library_search_paths) > 0 || resultFP != NULL) { + pcb_fp_sort_children(&pcb_library); + return 0; + } + + return 1; +} + +int pcb_fp_rehash(rnd_hidlib_t *hidlib, pcb_fplibrary_t *l) +{ + pcb_plug_fp_t *be; + char *path; + int res; + + if (l == NULL) { + pcb_fp_free_children(&pcb_library); + res = pcb_fp_read_lib_all(); + rnd_event(hidlib, PCB_EVENT_LIBRARY_CHANGED, NULL); + return res; + } + if (l->type != PCB_LIB_DIR) + return -1; + + be = l->data.dir.backend; + if ((be == NULL) || (be->load_dir == NULL)) + return -1; + + path = rnd_strdup(l->name); + pcb_fp_rmdir(l); + res = be->load_dir(be, path, 1); + pcb_fp_sort_children(&pcb_library); + free(path); + + if (res >= 0) { + rnd_event(hidlib, PCB_EVENT_LIBRARY_CHANGED, NULL); + return 0; + } + return -1; +} + +const char *PCB_PTR_DOMAIN_FPMAP = "pcb_fgw_ptr_domain_fpmap"; + +const char *pcb_fp_map_choose(rnd_hidlib_t *hidlib, const pcb_plug_fp_map_t *map) +{ + int numfp; + const pcb_plug_fp_map_t *bestm = NULL, *m; + + /* if there's only one choice, don't present the dialog */ + for(numfp = 0, m = map; m != NULL; m = m->next) { + if (m->type == PCB_FP_FILE) { + numfp++; + bestm = m; + } + } + if (numfp == 1) + return bestm->name; + + + if (RND_HAVE_GUI_ATTR_DLG) { + fgw_arg_t res; + fgw_arg_t args[2]; + + fgw_ptr_reg(&rnd_fgw, &args[1], PCB_PTR_DOMAIN_FPMAP, FGW_PTR | FGW_STRUCT, (void *)map); + rnd_actionv_bin(hidlib, "gui_fpmap_choose", &res, 2, args); + fgw_ptr_unreg(&rnd_fgw, &args[1], PCB_PTR_DOMAIN_FPMAP); + + if (res.type & FGW_STR) + return res.val.str; + } + else { + rnd_message(RND_MSG_ERROR, "No gui available, automatically choosing the first footprint from the available footprints.\n"); + return map->name; + } + + return NULL; +} Index: tags/2.3.0/src/plug_footprint.h =================================================================== --- tags/2.3.0/src/plug_footprint.h (nonexistent) +++ tags/2.3.0/src/plug_footprint.h (revision 33253) @@ -0,0 +1,100 @@ +#ifndef PCB_PLUG_FOOTPRINT_H +#define PCB_PLUG_FOOTPRINT_H + +#include +#include "vtlibrary.h" +#include "data.h" +#include + +typedef struct pcb_plug_fp_s pcb_plug_fp_t; + +typedef struct { + pcb_plug_fp_t *backend; + union { + int i; + void *p; + } field[4]; + + const char *filename; /* basename of the footprint file, with possible sub footprint name truncated from "::" */ + const char *subfpname; /* if the file contains multiple footprints, this holds the footprint name to open */ + int free_filename; /* internal */ +} pcb_fp_fopen_ctx_t; + +/* hook bindings, see below; pcb_fp_fclose() must be called even if pcb_fp_fopen() returned NULL! */ +FILE *pcb_fp_fopen(const rnd_conflist_t *path, const char *name, pcb_fp_fopen_ctx_t *fctx, pcb_data_t *dst); +void pcb_fp_fclose(FILE * f, pcb_fp_fopen_ctx_t *fctx); + +/* duplicates the name and splits it into a basename and params; + params is NULL if the name is not parametric (and "" if parameter list is empty) + returns 1 if name is parametric footprint, 0 if static file footprint. + The caller shall free only *basename at the end. + */ +int pcb_fp_dupname(const char *name, char **basename, char **params); + +/**** tag management ****/ +/* Resolve a tag name to an unique void * ID; create unknown tag if alloc != 0 */ +const void *pcb_fp_tag(const char *tag, int alloc); + +/* Resolve a tag ID to a tag name */ +const char *pcb_fp_tagname(const void *tagid); + +/* init/uninit the footprint lib, free tag key memory */ +void pcb_fp_init(); +void pcb_fp_uninit(); + +/**************************** API definition *********************************/ +extern FILE *PCB_FP_FOPEN_IN_DST; + +struct pcb_plug_fp_s { + pcb_plug_fp_t *next; + void *plugin_data; + + /* returns the number of footprints loaded into the library or -1 on + error; next in chain is run only on error. If force is 1, force doing the + expensive part of the load (e.g. wget) */ + int (*load_dir)(pcb_plug_fp_t *ctx, const char *path, int force); + +/* Open a footprint for reading; if the footprint is parametric, it's run + prefixed with libshell (or executed directly, if libshell is NULL). + If name is not an absolute path, search_path is searched for the first match. + The user has to supply a state integer that will be used by pcb_pcb_fp_fclose(). + Must fill in fctx->backend, may use any other field of fctx as well. + If dst is non-NULL, some backends (e.g. fp_board) may decide to place the + loaded footprint in dst and return PCB_FP_FOPEN_IN_DST. + */ + FILE *(*fp_fopen)(pcb_plug_fp_t *ctx, const char *path, const char *name, pcb_fp_fopen_ctx_t *fctx, pcb_data_t *dst); + +/* Close the footprint file opened by pcb_pcb_fp_fopen(). */ + void (*fp_fclose)(pcb_plug_fp_t *ctx, FILE * f, pcb_fp_fopen_ctx_t *fctx); +}; + +extern pcb_plug_fp_t *pcb_plug_fp_chain; + + +/* Optional pcb-rnd-side glue for some implementations */ + +extern pcb_fplibrary_t pcb_library; /* the footprint library */ + +void pcb_fp_free_children(pcb_fplibrary_t *parent); +void pcb_fp_sort_children(pcb_fplibrary_t *parent); +void pcb_fp_rmdir(pcb_fplibrary_t *dir); +pcb_fplibrary_t *pcb_fp_mkdir_p(const char *path); +pcb_fplibrary_t *pcb_fp_mkdir_len(pcb_fplibrary_t *parent, const char *name, int name_len); +pcb_fplibrary_t *pcb_fp_lib_search(pcb_fplibrary_t *dir, const char *name); + +/* Append a menu entry in the tree */ +pcb_fplibrary_t *pcb_fp_append_entry(pcb_fplibrary_t *parent, const char *name, pcb_fptype_t type, void *tags[], rnd_bool dup_tags); + +/* walk through all lib paths and build the library menu */ +int pcb_fp_read_lib_all(void); + +int pcb_fp_host_uninit(void); + +/* rescan/reload all footprints in the library cache */ +int pcb_fp_rehash(rnd_hidlib_t *hidlib, pcb_fplibrary_t *l); + +/* invoke the GUI to choose one footprint name from a footprint map; if + there's no GUI available, throws a warning and returns the first */ +const char *pcb_fp_map_choose(rnd_hidlib_t *hidlib, const pcb_plug_fp_map_t *map); + +#endif Index: tags/2.3.0/src/plug_footprint_act.c =================================================================== --- tags/2.3.0/src/plug_footprint_act.c (nonexistent) +++ tags/2.3.0/src/plug_footprint_act.c (revision 33253) @@ -0,0 +1,86 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2019 Tibor 'Igor2' Palinkas + * + * This module was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include "board.h" +#include "plug_footprint.h" + +static const char pcb_acts_fp_rehash[] = "fp_rehash()" ; +static const char pcb_acth_fp_rehash[] = "Flush the library index; rescan all library search paths and rebuild the library index. Useful if there are changes in the library during a pcb-rnd session."; +static fgw_error_t pcb_act_fp_rehash(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *name = NULL; + pcb_fplibrary_t *l; + + RND_ACT_MAY_CONVARG(1, FGW_STR, fp_rehash, name = argv[1].val.str); + RND_ACT_IRES(0); + + if (name == NULL) { + pcb_fp_rehash(RND_ACT_HIDLIB, NULL); + return 0; + } + + l = pcb_fp_lib_search(&pcb_library, name); + if (l == NULL) { + rnd_message(RND_MSG_ERROR, "Can't find library path %s\n", name); + RND_ACT_IRES(1); + return 0; + } + + if (l->type != PCB_LIB_DIR) { + rnd_message(RND_MSG_ERROR, "Library path %s is not a directory\n", name); + RND_ACT_IRES(1); + return 0; + } + + if (l->data.dir.backend == NULL) { + rnd_message(RND_MSG_ERROR, "Library path %s is not a top level directory of a fp_ plugin\n", name); + RND_ACT_IRES(1); + return 0; + } + + if (pcb_fp_rehash(RND_ACT_HIDLIB, l) != 0) { + rnd_message(RND_MSG_ERROR, "Failed to rehash %s\n", name); + RND_ACT_IRES(1); + return 0; + } + + return 0; +} + + +static rnd_action_t plug_footprint_list[] = { + {"fp_rehash", pcb_act_fp_rehash, pcb_acth_fp_rehash, pcb_acts_fp_rehash} +}; + +void pcb_plug_footprint_act_init2(void) +{ + RND_REGISTER_ACTIONS(plug_footprint_list, NULL); +} Index: tags/2.3.0/src/plug_import.c =================================================================== --- tags/2.3.0/src/plug_import.c (nonexistent) +++ tags/2.3.0/src/plug_import.c (revision 33253) @@ -0,0 +1,136 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,1997,1998,2005,2006 Thomas Nau + * Copyright (C) 2015,2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* This used to be file.c; it's a hook based plugin API now */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include + +#include +#include "plug_import.h" +#include +#include +#include + + +pcb_plug_import_t *pcb_plug_import_chain = NULL; + +typedef struct { + pcb_plug_import_t *plug; + int prio; +} find_t; + +/* Find the plugin that offers the highest write prio for the format */ +static pcb_plug_import_t *find_importer(unsigned int aspects, const char **args, int numargs) +{ + find_t available[32]; /* wish we had more than 32 import plugins... */ + int n, len = 0, best = 0, bestidx = -1; + +#define cb_append(pl, pr) \ + do { \ + if (pr > 0) { \ + assert(len < sizeof(available)/sizeof(available[0])); \ + available[len].plug = pl; \ + available[len++].prio = pr; \ + } \ + } while(0) + + + RND_HOOK_CALL_ALL(pcb_plug_import_t, pcb_plug_import_chain, fmt_support_prio, cb_append, (self, aspects, args, numargs)); + if (len == 0) + return NULL; + + for(n = 0; n < len; n++) { + if (available[n].prio > best) { + bestidx = n; + best = available[n].prio; + } + } + + if (best == 0) + return NULL; + + return available[bestidx].plug; +#undef cb_append +} + +pcb_plug_import_t *pcb_lookup_importer(const char *name) +{ + pcb_plug_import_t *p; + + if (name == NULL) + return NULL; + + for(p = pcb_plug_import_chain; p != NULL; p = p->next) + if (strcmp(p->name, name) == 0) + return p; + + return NULL; +} + + +int pcb_import(rnd_hidlib_t *hidlib, const char *filename, unsigned int aspect) +{ + pcb_plug_import_t *plug; + + if (!rnd_file_readable(filename)) { + rnd_message(RND_MSG_ERROR, "Error: can't find a suitable netlist parser for %s - might be related: can't open %s for reading\n", filename, filename); + return 1; + } + + if (!filename) { + rnd_message(RND_MSG_ERROR, "Error: need a file name for pcb_import_netlist()\n"); + return 1; /* nothing to do */ + } + + plug = find_importer(aspect, &filename, 1); + if (plug == NULL) { + rnd_message(RND_MSG_ERROR, "Error: can't find a suitable netlist parser for %s\n", filename); + return 1; + } + + return plug->import(plug, aspect, &filename, 1); +} + +int pcb_import_netlist(rnd_hidlib_t *hidlib, const char *filename) +{ + return pcb_import(hidlib, filename, IMPORT_ASPECT_NETLIST); +} + +void pcb_import_uninit(void) +{ + if (pcb_plug_import_chain != NULL) + rnd_message(RND_MSG_ERROR, "pcb_plug_import_chain is not empty; a plugin did not remove itself from the chain. Fix your plugins!\n"); +} Index: tags/2.3.0/src/plug_import.h =================================================================== --- tags/2.3.0/src/plug_import.h (nonexistent) +++ tags/2.3.0/src/plug_import.h (revision 33253) @@ -0,0 +1,90 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,1997,1998,2005,2006 Thomas Nau + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_PLUG_IMPORT_H +#define PCB_PLUG_IMPORT_H + +#include "config.h" +#include + +/**************************** API definition *********************************/ + +typedef enum pcb_plug_import_aspect_e { /* bitfield of aspects that can be imported */ + IMPORT_ASPECT_NETLIST = 1 +} pcb_plug_import_aspect_t; + +typedef struct pcb_plug_import_s pcb_plug_import_t; +struct pcb_plug_import_s { + pcb_plug_import_t *next; + void *plugin_data; + + const char *name; /* short name of the importer, also identifies the importer in import_sch */ + const char *desc; /* long, human readable description of the importer */ + + /* Check if the plugin supports format fmt. Return 0 if not supported or + an integer priority if supported. The higher the prio is the more likely + the plugin gets the next operation on the file. Base prio should be 100 + for native formats. Return non-0 only if all aspects are supported. */ + int (*fmt_support_prio)(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs); + + /* Perform the import; return 0 on success */ + int (*import)(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs); + + int ui_prio; /* priority for plugin listing on the user interface; 100 is highest (top), 0 is lowest */ + unsigned single_arg:1; /* accepts only one arg in each ->import() call */ + unsigned all_filenames:1; /* if set, all arguments are filenames */ + unsigned ext_exec:1; /* if set, import will execute external commands specified by the user (dangerous) */ +}; + +extern pcb_plug_import_t *pcb_plug_import_chain; + +void pcb_import_uninit(void); + +/* Return an importer by it's ->name, or return NULL if not found; + slow linear search */ +pcb_plug_import_t *pcb_lookup_importer(const char *name); + +/********** hook wrappers **********/ +int pcb_import(rnd_hidlib_t *hidlib, const char *filename, unsigned int aspect); +int pcb_import_netlist(rnd_hidlib_t *hidlib, const char *fn); + +/*** macros used by import plugins ***/ + +/* cross-query import_sch verbose setting without introducing plugin dependency; + sets the value in verbose if conf node present, else sets it ti 0 */ +#define PCB_IMPORT_SCH_VERBOSE(verbose) \ +do { \ + rnd_conf_native_t *vn; \ + verbose = 0; \ + vn = rnd_conf_get_field("plugins/import_sch/verbose"); \ + if ((vn != NULL) && (vn->type == RND_CFN_BOOLEAN)) \ + verbose = *(vn->val.boolean); \ +} while(0) + +#endif Index: tags/2.3.0/src/plug_io.c =================================================================== --- tags/2.3.0/src/plug_io.c (nonexistent) +++ tags/2.3.0/src/plug_io.c (revision 33253) @@ -0,0 +1,1198 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,1997,1998,2005,2006 Thomas Nau + * Copyright (C) 2015,2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + + +/* This used to be file.c; some of the code landed in the io_pcb plugin, + the format-independent parts ended up here. */ + +/* file save, load, merge ... routines */ + +/* If emergency format is not configured but emergency file name is, default + to saving in the native format */ +#define DEFAULT_EMERGENCY_FMT "lihata" + +#include "config.h" + +#include "conf_core.h" +#include + +#include +#include +#include +#include +#include +#include + +#include "change.h" +#include +#include "data.h" +#include +#include "plug_io.h" +#include "remove.h" +#include +#include "rats_patch.h" +#include +#include +#include +#include +#include "event.h" +#include +#include "route_style.h" +#include +#include +#include "layer_vis.h" +#include +#include "plug_footprint.h" +#include +#include +#include "view.h" + +pcb_plug_io_t *pcb_plug_io_chain = NULL; +int pcb_io_err_inhibit = 0; +pcb_view_list_t pcb_io_incompat_lst; +static rnd_bool pcb_io_incompat_lst_enable = rnd_false; + +void pcb_plug_io_err(rnd_hidlib_t *hidlib, int res, const char *what, const char *filename) +{ + if (pcb_io_err_inhibit) + return; + if (res != 0) { + const char *reason = "", *comment = ""; + if (pcb_plug_io_chain != NULL) { + if (filename == NULL) { + reason = "none of io plugins could successfully write the file"; + filename = ""; + } + else { + FILE *f; + reason = "none of io plugins could successfully read file"; + f = rnd_fopen(hidlib, filename, "r"); + if (f != NULL) { + fclose(f); + comment = "(unknown/invalid file format?)"; + } + else + comment = "(can not open the file for reading)"; + } + } + else { + reason = "no io plugin loaded, I don't know any file format"; + if (filename == NULL) + filename = ""; + } + rnd_message(RND_MSG_ERROR, "IO error during %s: %s %s %s\n", what, reason, filename, comment); + } +} + +static char *last_design_dir = NULL; +void pcb_set_design_dir(const char *fn) +{ + char *end; + + free(last_design_dir); + last_design_dir = NULL; + + if (fn != NULL) + last_design_dir = rnd_lrealpath(fn); + + if (last_design_dir == NULL) { + last_design_dir = rnd_strdup(""); + rnd_conf_force_set_str(conf_core.rc.path.design, last_design_dir); + rnd_conf_ro("rc/path/design"); + return; + } + + end = strrchr(last_design_dir, RND_DIR_SEPARATOR_C); + if (end != NULL) + *end = '\0'; + + rnd_conf_force_set_str(conf_core.rc.path.design, last_design_dir); + rnd_conf_ro("rc/path/design"); +} + +static int pcb_test_parse_all(FILE *ft, const char *Filename, const char *fmt, pcb_plug_iot_t type, pcb_find_io_t *available, int *accepts, int *accept_total, int maxav, int ignore_missing, int gen_event) +{ + int len, n; + + if (ft == NULL) { + if (!ignore_missing) + rnd_message(RND_MSG_ERROR, "Error: can't open %s for reading (format is %s)\n", Filename, fmt); + return -1; + } + + if (gen_event) + rnd_event(&PCB->hidlib, RND_EVENT_LOAD_PRE, "s", Filename); + + len = pcb_find_io(available, maxav, type, 0, fmt); + if (fmt != NULL) { + /* explicit format */ + for(n = 0; n < len; n++) { + void (*f)(); + switch(type) { + case PCB_IOT_PCB: f = (void (*)())available[n].plug->parse_pcb; break; + default: assert(!"internal error: pcb_test_parse_all: wrong type"); f = NULL; + } + if (f != NULL) { + accepts[n] = 1; /* force-accept - if it can handle the format, and the user explicitly wanted this format, let's try it */ + (*accept_total)++; + } + } + + if (*accept_total <= 0) { + rnd_message(RND_MSG_ERROR, "can't find a IO_ plugin to load a PCB using format %s\n", fmt); + return -1; + } + + if (*accept_total > 1) { + rnd_message(RND_MSG_INFO, "multiple IO_ plugins can handle format %s - I'm going to try them all, but you may want to be more specific next time; formats found:\n", fmt); + for(n = 0; n < len; n++) + rnd_message(RND_MSG_INFO, " %s\n", available[n].plug->description); + } + } + else { + /* test-parse with all plugins to see who can handle the syntax */ + if((fgetc(ft) != EOF)) { + rewind(ft); + for(n = 0; n < len; n++) { + if ((available[n].plug->test_parse == NULL) || (available[n].plug->test_parse(available[n].plug, type, Filename, ft))) { + accepts[n] = 1; + (*accept_total)++; + } + else + accepts[n] = 0; + rewind(ft); + } + } + } + + if (*accept_total == 0) { + rnd_message(RND_MSG_ERROR, "none of the IO_ plugin recognized the file format of %s - it's either not a valid board file or does not match the format specified\n", Filename); + return -1; + } + return len; +} + +int pcb_parse_pcb(pcb_board_t *Ptr, const char *Filename, const char *fmt, int load_settings, int ignore_missing) +{ + int res = -1, len, n; + pcb_find_io_t available[PCB_IO_MAX_FORMATS]; + int accepts[PCB_IO_MAX_FORMATS]; /* test-parse output */ + int accept_total = 0; + FILE *ft; + long design_root_cnt = rnd_conf_main_root_replace_cnt[RND_CFR_DESIGN]; + + ft = rnd_fopen(&Ptr->hidlib, Filename, "r"); + len = pcb_test_parse_all(ft, Filename, fmt, PCB_IOT_PCB, available, accepts, &accept_total, sizeof(available)/sizeof(available[0]), ignore_missing, load_settings); + if (ft != NULL) + fclose(ft); + if (len < 0) + return -1; + + Ptr->Data->loader = NULL; + + pcb_layergrp_inhibit_inc(); + + /* try all plugins that said it could handle the file */ + for(n = 0; n < len; n++) { + if ((available[n].plug->parse_pcb == NULL) || (!accepts[n])) /* can't parse or doesn't want to parse this file */ + continue; + res = available[n].plug->parse_pcb(available[n].plug, Ptr, Filename, load_settings); + if (res == 0) { + if (Ptr->Data->loader == NULL) /* if the loader didn't set this (to some more fine grained, e.g. depending on file format version) */ + Ptr->Data->loader = available[n].plug; + break; + } + } + + pcb_layergrp_inhibit_dec(); + + + if ((res == 0) && (load_settings)) { + if (design_root_cnt == rnd_conf_main_root_replace_cnt[RND_CFR_DESIGN]) /* the newly loaded board did not bring a design root */ + rnd_conf_reset(RND_CFR_DESIGN, ""); + rnd_conf_load_project(NULL, Filename); + } + + if (res == 0) + pcb_set_design_dir(Filename); + + if (load_settings) + rnd_event(&PCB->hidlib, RND_EVENT_LOAD_POST, "si", Filename, res); + rnd_event(&PCB->hidlib, PCB_EVENT_ROUTE_STYLES_CHANGED, NULL); + rnd_conf_set(RND_CFR_DESIGN, "design/text_font_id", 0, "0", RND_POL_OVERWRITE); /* we have only one font now, make sure it is selected */ + + pcb_plug_io_err(&Ptr->hidlib, res, "load pcb", Filename); + return res; +} + +int pcb_parse_footprint(pcb_data_t *Ptr, const char *Filename, const char *fmt) +{ + int res = -1, len, n; + pcb_find_io_t available[PCB_IO_MAX_FORMATS]; + int accepts[PCB_IO_MAX_FORMATS]; /* test-parse output */ + int accept_total = 0; + FILE *f; + pcb_fp_fopen_ctx_t fctx; + + f = pcb_fp_fopen(&conf_core.rc.library_search_paths, Filename, &fctx, Ptr); + if (f == PCB_FP_FOPEN_IN_DST) + return 0; + len = pcb_test_parse_all(f, fctx.filename, fmt, PCB_IOT_FOOTPRINT, available, accepts, &accept_total, sizeof(available)/sizeof(available[0]), 0, 0); + if (len < 0) { + pcb_fp_fclose(f, &fctx); + return -1; + } + + Ptr->loader = NULL; + + /* try all plugins that said it could handle the file */ + for(n = 0; n < len; n++) { + pcb_plug_fp_map_t *map = NULL, head = {0}; + int subfpname_reset = 0; + if ((available[n].plug->parse_footprint == NULL) || (!accepts[n])) /* can't parse or doesn't want to parse this file */ + continue; + + if ((fctx.subfpname == NULL) && (available[n].plug->multi_footprint)) { + subfpname_reset = 1; + rewind(f); + map = available[n].plug->map_footprint(available[n].plug, f, fctx.filename, &head, 0); + rewind(f); + if (map == NULL) + goto skip; + fctx.subfpname = pcb_fp_map_choose(&PCB->hidlib, map); + if (fctx.subfpname == NULL) /* cancel */ + goto skip; + } + + res = available[n].plug->parse_footprint(available[n].plug, Ptr, fctx.filename, fctx.subfpname); + if (res == 0) { + if (Ptr->loader == NULL) /* if the loader didn't set this (to some more fine grained, e.g. depending on file format version) */ + Ptr->loader = available[n].plug; + break; + } + + skip:; + if (subfpname_reset) { + fctx.subfpname = NULL; + if (map != NULL) + pcb_io_fp_map_free(map); + } + } + + /* remove selected/found flag when loading reusable footprints */ + if (res == 0) + pcb_data_flag_change(Ptr, PCB_OBJ_CLASS_REAL, PCB_CHGFLG_CLEAR, PCB_FLAG_FOUND | PCB_FLAG_SELECTED); + + pcb_plug_io_err(&PCB->hidlib, res, "load footprint", Filename); + pcb_fp_fclose(f, &fctx); + return res; +} + +int pcb_parse_font(pcb_font_t *Ptr, const char *Filename) +{ + int res = -1; + RND_HOOK_CALL(pcb_plug_io_t, pcb_plug_io_chain, parse_font, res, == 0, (self, Ptr, Filename)); + + pcb_plug_io_err(&PCB->hidlib, res, "load font", Filename); + return res; +} + +static int find_prio_cmp(const void *p1, const void *p2) +{ + const pcb_find_io_t *f1 = p1, *f2 = p2; + if (f1->prio < f2->prio) + return 1; + return -1; +} + +int pcb_find_io(pcb_find_io_t *available, int avail_len, pcb_plug_iot_t typ, int is_wr, const char *fmt) +{ + int len = 0; + +#define cb_append(pl, pr) \ + do { \ + if (pr > 0) { \ + assert(len < avail_len ); \ + available[len].plug = pl; \ + if (fmt == NULL) \ + available[len].prio = pl->save_preference_prio; \ + else \ + available[len].prio = pr; \ + len++; \ + } \ + } while(0) + + RND_HOOK_CALL_ALL(pcb_plug_io_t, pcb_plug_io_chain, fmt_support_prio, cb_append, (self, typ, is_wr, (fmt == NULL ? self->default_fmt : fmt))); + + if (len > 0) + qsort(available, len, sizeof(available[0]), find_prio_cmp); +#undef cb_append + + return len; +} + +pcb_plug_io_t *pcb_io_find_writer(pcb_plug_iot_t typ, const char *fmt) +{ + pcb_find_io_t available[PCB_IO_MAX_FORMATS]; + int len; + + if (fmt == NULL) { + if (PCB->hidlib.filename != NULL) { /* have a file name, guess from extension */ + int fn_len = strlen(PCB->hidlib.filename); + const char *end = PCB->hidlib.filename + fn_len; + pcb_plug_io_t *n, *best = NULL; + int best_score = 0; + + /* the the plugin that has a matching extension and has the highest save_preference_prio value */ + for(n = pcb_plug_io_chain; n != NULL; n = n->next) { + if (n->default_extension != NULL) { + int elen = strlen(n->default_extension); + if ((elen < fn_len) && (strcmp(end-elen, n->default_extension) == 0)) { + if (n->save_preference_prio > best_score) { + best_score = n->save_preference_prio; + best = n; + } + } + } + } + if (best != NULL) + return best; + } + + /* no file name or format hint, or file name not recognized: choose the ultimate default */ + fmt = conf_core.rc.save_final_fallback_fmt; + if (fmt == NULL) { + rnd_message(RND_MSG_WARNING, "Saving a file with unknown format: failed to guess format from file name, no value configured in rc/save_final_fallback_fmt - CAN NOT SAVE FILE, try save as.\n"); + return NULL; + } + else { + if (PCB->hidlib.filename != NULL) + rnd_message(RND_MSG_WARNING, "Saving a file with unknown format: failed to guess format from file name, falling back to %s as configured in rc/save_final_fallback_fmt\n", fmt); + } + } + + len = pcb_find_io(available, sizeof(available)/sizeof(available[0]), typ, 1, fmt); + + if (len == 0) + return NULL; + + return available[0].plug; +} + +static int pcb_write_data_subcs(pcb_plug_io_t *p, FILE *f, pcb_data_t *data, long subc_idx) +{ + long avail = pcb_subclist_length(&data->subc); + void *udata; + int res; + + if ((subc_idx >= 0) && (subc_idx >= avail)) { + rnd_message(RND_MSG_ERROR, "pcb_write_buffer: subc index out of range"); + return -1; + } + if (subc_idx < 0) { + pcb_subc_t *subc; + gdl_iterator_t sit; + + if (p->write_subcs_head(p, &udata, f, (avail > 1), avail) != 0) { + rnd_message(RND_MSG_ERROR, "pcb_write_buffer: failed to write head"); + return -1; + } + res = 0; + subclist_foreach(&data->subc, &sit, subc) + res |= p->write_subcs_subc(p, &udata, f, subc); + res |= p->write_subcs_tail(p, &udata, f); + return res; + } + else { + if (p->write_subcs_head(p, &udata, f, 0, 1) != 0) { + rnd_message(RND_MSG_ERROR, "pcb_write_buffer: failed to write head"); + return -1; + } + res = p->write_subcs_subc(p, &udata, f, pcb_subclist_nth(&data->subc, subc_idx)); + res |= p->write_subcs_tail(p, &udata, f); + return res; + } +} + +static int pcb_write_buffer(FILE *f, pcb_buffer_t *buff, const char *fmt, rnd_bool subc_only, long subc_idx) +{ + int res/*, newfmt = 0*/; + pcb_plug_io_t *p = pcb_io_find_writer(subc_only ? PCB_IOT_FOOTPRINT : PCB_IOT_BUFFER, fmt); + + if (p != NULL) { + if (subc_only) + res = pcb_write_data_subcs(p, f, buff->Data, subc_idx); + else + res = p->write_buffer(p, f, buff); + /*newfmt = 1;*/ + } + +/* if ((res == 0) && (newfmt)) + PCB->Data->loader = p;*/ + + pcb_plug_io_err(&PCB->hidlib, res, "write buffer", NULL); + return res; +} + +int pcb_write_padstack(FILE *f, pcb_pstk_proto_t *proto, const char *fmt) +{ + int res = -1/*, newfmt = 0*/; + pcb_plug_io_t *p = pcb_io_find_writer(PCB_IOT_PADSTACK, fmt); + + if ((p != NULL) && (p->write_padstack != NULL)) { + res = p->write_padstack(p, f, proto); + /*newfmt = 1;*/ + } + +/* if ((res == 0) && (newfmt)) + PCB->Data->loader = p;*/ + + pcb_plug_io_err(&PCB->hidlib, res, "write padstack", NULL); + return res; +} + +int pcb_load_padstack(rnd_hidlib_t *hidlib, pcb_pstk_proto_t *proto, const char *fn, const char *fmt) +{ + int res = -1, len, n; + pcb_find_io_t available[PCB_IO_MAX_FORMATS]; + int accepts[PCB_IO_MAX_FORMATS]; /* test-parse output */ + int accept_total = 0; + FILE *ft; + + ft = rnd_fopen(hidlib, fn, "r"); + len = pcb_test_parse_all(ft, fn, fmt, PCB_IOT_PADSTACK, available, accepts, &accept_total, sizeof(available)/sizeof(available[0]), 0, 0); + if (ft != NULL) + fclose(ft); + if (len < 0) + return -1; + + /* try all plugins that said it could handle the file */ + for(n = 0; n < len; n++) { + if ((available[n].plug->parse_padstack == NULL) || (!accepts[n])) /* can't parse or doesn't want to parse this file */ + continue; + res = available[n].plug->parse_padstack(available[n].plug, proto, fn); + if (res == 0) + break; + } + + pcb_plug_io_err(hidlib, res, "load padstack", fn); + return res; +} + + +int pcb_write_footprint_data(FILE *f, pcb_data_t *e, const char *fmt, long subc_idx) +{ + int res, newfmt = 0; + pcb_plug_io_t *p = e->loader; + + if ((p == NULL) || ((fmt != NULL) && (*fmt != '\0'))) { + p = pcb_io_find_writer(PCB_IOT_FOOTPRINT, fmt); + newfmt = 1; + } + + if ((p != NULL) && (p->write_subcs_subc != NULL)) + res = pcb_write_data_subcs(p, f, e, subc_idx); + + if ((res == 0) && (newfmt)) + e->loader = p; + + pcb_plug_io_err(&PCB->hidlib, res, "write element", NULL); + return res; +} + +int pcb_write_font(pcb_font_t *Ptr, const char *Filename, const char *fmt) +{ + int res/*, newfmt = 0*/; + pcb_plug_io_t *p = pcb_io_find_writer(PCB_IOT_FONT, fmt); + + if (p != NULL) { + res = p->write_font(p, Ptr, Filename); + /*newfmt = 1;*/ + } + else + res = -1; + +/* if ((res == 0) && (newfmt)) + PCB->Data->loader = p;*/ + + pcb_plug_io_err(&PCB->hidlib, res, "write font", NULL); + return res; +} + + +static int pcb_write_pcb(FILE *f, const char *old_filename, const char *new_filename, const char *fmt, rnd_bool emergency) +{ + int res, newfmt = 0; + pcb_plug_io_t *p = PCB->Data->loader; + + if ((p == NULL) || ((fmt != NULL) && (*fmt != '\0'))) { + p = pcb_io_find_writer(PCB_IOT_PCB, fmt); + newfmt = 1; + } + + if (p != NULL) { + if (p->write_pcb != NULL) { + rnd_event(&PCB->hidlib, RND_EVENT_SAVE_PRE, "s", fmt); + res = p->write_pcb(p, f, old_filename, new_filename, emergency); + rnd_event(&PCB->hidlib, RND_EVENT_SAVE_POST, "si", fmt, res); + } + else { + rnd_message(RND_MSG_ERROR, "Can't write PCB: internal error: io plugin %s doesn't implement write_pcb()\n", p->description); + res = -1; + } + } + + if ((res == 0) && (newfmt)) + PCB->Data->loader = p; + + if (res == 0) + pcb_set_design_dir(new_filename); + + pcb_plug_io_err(&PCB->hidlib, res, "write pcb", NULL); + return res; +} + +/* load PCB: parse the file with enabled 'PCB mode' (see parser); if + successful, update some other stuff. If revert is rnd_true, we pass + "revert" as a parameter to the pcb changed event. */ +static int real_load_pcb(const char *Filename, const char *fmt, rnd_bool revert, rnd_bool require_font, int how) +{ + const char *unit_suffix; + char *new_filename; + pcb_board_t *newPCB = pcb_board_new_(rnd_false); + pcb_board_t *oldPCB; + rnd_conf_role_t settings_dest; + int pres; +#ifdef DEBUG + double elapsed; + clock_t start, end; + + start = clock(); +#endif + + rnd_path_resolve(&PCB->hidlib, Filename, &new_filename, 0, rnd_false); + + oldPCB = PCB; + PCB = newPCB; + + /* mark the default font invalid to know if the file has one */ + newPCB->fontkit.valid = rnd_false; + + switch(how & 0x0F) { + case 0: settings_dest = RND_CFR_DESIGN; break; + case 1: settings_dest = RND_CFR_DEFAULTPCB; break; + case 2: settings_dest = RND_CFR_invalid; break; + default: abort(); + } + + pcb_crosshair_move_absolute(PCB, RND_COORD_MAX, RND_COORD_MAX); /* make sure the crosshair is not above any object so ch* plugins release their highlights */ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); /* pcb_crosshair_move_absolute()'s side effect is leaving the crosshair notify in false state, flush that */ + + /* new data isn't added to the undo list */ + rnd_hid_menu_merge_inhibit_inc(); + pres = pcb_parse_pcb(PCB, new_filename, fmt, settings_dest, how & 0x10); + rnd_hid_menu_merge_inhibit_dec(); + + if (!pres) { + pcb_board_remove(oldPCB); + + pcb_board_new_postproc(PCB, 0); + if (how == 0) { + /* update cursor location */ + PCB->hidlib.ch_x = pcb_crosshair.X = PCB->hidlib.size_x/2; + PCB->hidlib.ch_y = pcb_crosshair.Y = PCB->hidlib.size_y/2; + + /* update cursor confinement and output area (scrollbars) */ + pcb_board_resize(PCB->hidlib.size_x, PCB->hidlib.size_y, 0); + } + + /* have to be called after pcb_board_resize() so vis update is after a board changed update */ + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + pcb_layervis_reset_stack(&PCB->hidlib); + + /* enable default font if necessary */ + if (!PCB->fontkit.valid) { + if ((require_font) && (!PCB->is_footprint) && (!PCB->suppress_warn_missing_font)) + rnd_message(RND_MSG_WARNING, "File '%s' has no font information, using default font\n", new_filename); + PCB->fontkit.valid = rnd_true; + } + + /* footprint edition: let the user directly manipulate subc parts */ + PCB->loose_subc = PCB->is_footprint; + + /* clear 'changed flag' */ + pcb_board_set_changed_flag(PCB, rnd_false); + PCB->hidlib.filename = new_filename; + /* just in case a bad file saved file is loaded */ + + /* geda/pcb compatibility: use attribute PCB::grid::unit as unit, if present */ + unit_suffix = pcb_attrib_get(PCB, "PCB::grid::unit"); + if (unit_suffix && *unit_suffix) { + lht_node_t *nat = rnd_conf_lht_get_at(RND_CFR_DESIGN, "editor/grid_unit", 0); + if (nat == NULL) { + const rnd_unit_t *new_unit = rnd_get_unit_struct(unit_suffix); + if (new_unit) + rnd_conf_set(settings_dest, "editor/grid_unit", -1, unit_suffix, RND_POL_OVERWRITE); + } + } + + pcb_ratspatch_make_edited(PCB); + +/* set route style to the first one, if the current one doesn't + happen to match any. This way, "revert" won't change the route style. */ + { + extern fgw_error_t pcb_act_GetStyle(fgw_arg_t *res, int argc, fgw_arg_t *argv); + fgw_arg_t res, argv; + if (RND_ACT_CALL_C(&PCB->hidlib, pcb_act_GetStyle, &res, 1, &argv) < 0) + pcb_use_route_style_idx(&PCB->RouteStyle, 0); + } + + if ((how == 0) || (revert)) + pcb_board_changed(revert); + +#ifdef DEBUG + end = clock(); + elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; + rnd_message(RND_MSG_INFO, "Loading file %s took %f seconds of CPU time\n", new_filename, elapsed); +#endif + + conf_core.temp.rat_warn = rnd_true; /* make sure the first click can remove warnings */ + rnd_tool_select_by_name(&PCB->hidlib, "arrow"); + + return 0; + } + + free(new_filename); + PCB = oldPCB; + if (PCB == NULL) { + /* bozo: we are trying to revert back to a non-existing pcb... create one to avoid a segfault */ + PCB = pcb_board_new_(rnd_false); + if (PCB == NULL) { + rnd_message(RND_MSG_ERROR, "FATAL: can't create a new empty pcb!"); + exit(1); + } + } + + if (!(how & PCB_INHIBIT_BOARD_CHANGED)) + pcb_board_changed(0); + + /* release unused memory */ + pcb_board_remove(newPCB); + + return 1; +} + +/* Write the pcb file, a footprint or a buffer */ +static int pcb_write_file(FILE *fp, rnd_bool thePcb, const char *old_path, const char *new_path, const char *fmt, rnd_bool emergency, rnd_bool subc_only, long subc_idx) +{ + if (thePcb) { + if (PCB->is_footprint) + return pcb_write_footprint_data(fp, PCB->Data, fmt, subc_idx); + return pcb_write_pcb(fp, old_path, new_path, fmt, emergency); + } + return pcb_write_buffer(fp, PCB_PASTEBUFFER, fmt, subc_only, subc_idx); +} + +/* writes to pipe using the command defined by conf_core.rc.save_command + %f are replaced by the passed filename */ +static int pcb_write_pipe(const char *Filename, rnd_bool thePcb, const char *fmt, rnd_bool subc_only, long subc_idx, int askovr) +{ + FILE *fp; + int result; + const char *p; + static gds_t command; + const char *save_cmd; + + if (RND_EMPTY_STRING_P(conf_core.rc.save_command)) + return pcb_write_pcb_file(Filename, thePcb, fmt, rnd_false, subc_only, subc_idx, askovr); + + save_cmd = conf_core.rc.save_command; + /* setup commandline */ + gds_truncate(&command,0); + for (p = save_cmd; *p; p++) { + /* copy character if not special or add string to command */ + if (!(p[0] == '%' && p[1] == 'f')) + gds_append(&command, *p); + else { + gds_append_str(&command, Filename); + + /* skip the character */ + p++; + } + } + printf("write to pipe \"%s\"\n", command.array); + if ((fp = rnd_popen(&PCB->hidlib, command.array, "w")) == NULL) { + rnd_popen_error_message(command.array); + return (-1); + } + + result = pcb_write_file(fp, thePcb, NULL, NULL, fmt, rnd_false, subc_only, subc_idx); + + return (rnd_pclose(fp) ? (-1) : result); +} + +#if !defined(RND_HAS_ATEXIT) +static char *TMPFilename = NULL; +#endif + +#define F2S(OBJ, TYPE) pcb_strflg_f2s((OBJ)->Flags, TYPE) + +int pcb_save_buffer_subcs(const char *Filename, const char *fmt, long subc_idx) +{ + int result; + + if (conf_core.editor.show_solder_side) + pcb_buffers_flip_side(PCB); + result = pcb_write_pipe(Filename, rnd_false, fmt, rnd_true, subc_idx, 1); + if (conf_core.editor.show_solder_side) + pcb_buffers_flip_side(PCB); + return result; +} + +int pcb_save_buffer(const char *Filename, const char *fmt) +{ + return pcb_write_pipe(Filename, rnd_false, fmt, rnd_false, -1, 1); +} + +int pcb_save_pcb(const char *file, const char *fmt) +{ + int retcode; + + pcb_io_incompat_lst_enable = rnd_true; + if (conf_core.editor.io_incomp_popup) + pcb_view_list_free_fields(&pcb_io_incompat_lst); + + retcode = pcb_write_pipe(file, rnd_true, fmt, rnd_false, -1, 0); + + pcb_io_incompat_lst_enable = rnd_false; + if (conf_core.editor.io_incomp_popup) { + long int len = pcb_view_list_length(&pcb_io_incompat_lst); + if (len > 0) { + rnd_message(RND_MSG_ERROR, "There were %ld save incompatibility errors.\nData in memory is not affected, but the file created may be slightly broken.\nSee the popup view listing for details.\n", len); + rnd_actionva(&PCB->hidlib, "IOincompatList", conf_core.editor.io_incomp_style, "auto", NULL); + } + } + + return retcode; +} + +int pcb_load_pcb(const char *file, const char *fmt, rnd_bool require_font, int how) +{ + int res = real_load_pcb(file, fmt, rnd_false, require_font, how); + if (res == 0) { + rnd_file_loaded_set_at("design", "main", file, PCB->is_footprint ? "footprint" : "board"); + if (PCB->is_footprint) { + rnd_box_t b; + /* a footprint has no board size set, need to invent one */ + pcb_data_bbox(&b, PCB->Data, 0); + if ((b.X2 < b.X1) || (b.Y2 < b.Y1)) { + rnd_message(RND_MSG_ERROR, "Invalid footprint file: can not determine bounding box\n"); + res = -1; + } + else + pcb_board_resize(b.X2*1.5, b.Y2*1.5, 0); + } + } + return res; +} + +int pcb_revert_pcb(void) +{ + return real_load_pcb(PCB->hidlib.filename, NULL, rnd_true, rnd_true, 0); +} + +int pcb_load_buffer(rnd_hidlib_t *hidlib, pcb_buffer_t *buff, const char *fn, const char *fmt) +{ + int res = -1, len, n; + pcb_find_io_t available[PCB_IO_MAX_FORMATS]; + int accepts[PCB_IO_MAX_FORMATS]; /* test-parse output */ + int accept_total = 0; + FILE *ft; + + ft = rnd_fopen(hidlib, fn, "r"); + len = pcb_test_parse_all(ft, fn, fmt, PCB_IOT_BUFFER, available, accepts, &accept_total, sizeof(available)/sizeof(available[0]), 0, 0); + if (ft != NULL) + fclose(ft); + if (len < 0) + return -1; + + /* try all plugins that said it could handle the file */ + for(n = 0; n < len; n++) { + if ((available[n].plug->parse_buffer == NULL) || (!accepts[n])) /* can't parse or doesn't want to parse this file */ + continue; + res = available[n].plug->parse_buffer(available[n].plug, buff, fn); + if (res == 0) + break; + } + + pcb_plug_io_err(hidlib, res, "load buffer", fn); + return res; + +} + + +void pcb_print_quoted_string_(FILE * FP, const char *S) +{ + const char *start; + + for(start = S; *S != '\0'; S++) { + if (*S == '"' || *S == '\\') { + if (start != S) + fwrite(start, S-start, 1, FP); + fputc('\\', FP); + fputc(*S, FP); + start = S+1; + } + } + + if (start != S) + fwrite(start, S-start, 1, FP); +} + +void pcb_print_quoted_string(FILE *FP, const char *S) +{ + fputc('"', FP); + pcb_print_quoted_string_(FP, S); + fputc('"', FP); +} + +/* this is used for fatal errors and does not call the program specified in + 'saveCommand' for safety reasons */ +void pcb_save_in_tmp(void) +{ + char filename[256]; + + /* memory might have been released before this function is called */ + if (PCB && PCB->Changed && (conf_core.rc.emergency_name != NULL) && (*conf_core.rc.emergency_name != '\0')) { + const char *fmt = conf_core.rc.emergency_format == NULL ? DEFAULT_EMERGENCY_FMT : conf_core.rc.emergency_format; + sprintf(filename, conf_core.rc.emergency_name, (long int)rnd_getpid()); + rnd_message(RND_MSG_INFO, "Trying to save your layout in '%s'\n", filename); + pcb_write_pcb_file(filename, rnd_true, fmt, rnd_true, rnd_false, -1, 0); + } +} + +/* front-end for pcb_save_in_tmp() to makes sure it is only called once */ +static rnd_bool dont_save_any_more = rnd_false; +void pcb_emergency_save(void) +{ + + if (!dont_save_any_more) { + dont_save_any_more = rnd_true; + pcb_save_in_tmp(); + } +} + +void pcb_disable_emergency_save(void) +{ + dont_save_any_more = rnd_true; +} + +/*** Autosave ***/ + +static rnd_hidval_t backup_timer; + +/* + * If the backup interval is > 0 then set another timer. Otherwise + * we do nothing and it is up to the GUI to call pcb_enable_autosave() + * after setting conf_core.rc.backup_interval > 0 again. + */ +static void backup_cb(rnd_hidval_t data) +{ + backup_timer.ptr = NULL; + pcb_backup(); + if (conf_core.rc.backup_interval > 0 && rnd_gui->add_timer) + backup_timer = rnd_gui->add_timer(rnd_gui, backup_cb, 1000 * conf_core.rc.backup_interval, data); +} + +void pcb_enable_autosave(void) +{ + rnd_hidval_t x; + + x.ptr = NULL; + + /* If we already have a timer going, then cancel it out */ + if (backup_timer.ptr != NULL && rnd_gui->stop_timer) + rnd_gui->stop_timer(rnd_gui, backup_timer); + + backup_timer.ptr = NULL; + /* Start up a new timer */ + if (conf_core.rc.backup_interval > 0 && rnd_gui->add_timer) + backup_timer = rnd_gui->add_timer(rnd_gui, backup_cb, 1000 * conf_core.rc.backup_interval, x); +} + +/* Saves the board in a backup file using the name configured in + conf_core.rc.backup_name */ +void pcb_backup(void) +{ + char *filename = NULL; + const char *fmt = NULL; + pcb_plug_io_t *orig; + + filename = rnd_build_fn(&PCB->hidlib, conf_core.rc.backup_name); + if (filename == NULL) { + fprintf(stderr, "pcb_backup(): can't build file name for a backup\n"); + exit(1); + } + + if ((conf_core.rc.backup_format != NULL) && (strcmp(conf_core.rc.backup_format, "original") != 0)) + fmt = conf_core.rc.backup_format; + + orig = PCB->Data->loader; + pcb_write_pcb_file(filename, rnd_true, fmt, rnd_true, rnd_false, -1, 0); + PCB->Data->loader = orig; + + free(filename); +} + +int pcb_write_pcb_file(const char *Filename, rnd_bool thePcb, const char *fmt, rnd_bool emergency, rnd_bool subc_only, long subc_idx, int askovr) +{ + FILE *fp; + int result, overwrite = 0; + char *fn_tmp = NULL; + + /* for askovr, do not make a backup copy - if the user explicitly says overwrite, just overwrite */ + if (!askovr) + overwrite = rnd_file_readable(Filename); + + if (overwrite) { + int len = strlen(Filename); + fn_tmp = malloc(len+8); + memcpy(fn_tmp, Filename, len); + strcpy(fn_tmp+len, ".old"); + if (rnd_rename(NULL, Filename, fn_tmp) != 0) { + if (emergency) { + /* Try an alternative emergency file */ + strcpy(fn_tmp+len, ".emr"); + Filename = fn_tmp; + } + else { + rnd_message(RND_MSG_ERROR, "Can't rename %s to %s before save\n", Filename, fn_tmp); + return -1; + } + } + } + + if (askovr) + fp = rnd_fopen_askovr(&PCB->hidlib, Filename, "w", NULL); + else + fp = rnd_fopen(&PCB->hidlib, Filename, "w"); + + if (fp == NULL) { + rnd_open_error_message(Filename); + return (-1); + } + + result = pcb_write_file(fp, thePcb, fn_tmp, Filename, fmt, emergency, subc_only, subc_idx); + + fclose(fp); + if (fn_tmp != NULL) { + if ((result == 0) && (!conf_core.rc.keep_save_backups)) + rnd_unlink(&PCB->hidlib, fn_tmp); + free(fn_tmp); + } + return result; +} + +int pcb_io_list(pcb_io_formats_t *out, pcb_plug_iot_t typ, int wr, int do_digest, pcb_io_list_ext_t ext) +{ + pcb_find_io_t available[PCB_IO_MAX_FORMATS]; + int n; + + memset(out, 0, sizeof(pcb_io_formats_t)); + out->len = pcb_find_io(available, sizeof(available)/sizeof(available[0]), typ, 1, NULL); + + if (out->len == 0) + return 0; + + for(n = 0; n < out->len; n++) { + out->plug[n] = available[n].plug; + switch(ext) { + case PCB_IOL_EXT_NONE: out->extension[n] = NULL; break; + case PCB_IOL_EXT_BOARD: out->extension[n] = out->plug[n]->default_extension; break; + case PCB_IOL_EXT_FP: out->extension[n] = out->plug[n]->fp_extension; break; + } + } + + if (do_digest) { + for(n = 0; n < out->len; n++) + out->digest[n] = rnd_strdup_printf("%s (%s)", out->plug[n]->default_fmt, out->plug[n]->description); + out->digest[n] = NULL; + } + + return out->len; +} + +void pcb_io_list_free(pcb_io_formats_t *out) +{ + int n; + + for(n = 0; n < out->len; n++) { + if (out->digest[n] != NULL) { + free(out->digest[n]); + out->digest[n] = NULL; + } + } +} + + +rnd_cardinal_t pcb_io_incompat_save(pcb_data_t *data, pcb_any_obj_t *obj, const char *type, const char *title, const char *description) +{ + + if ((pcb_io_incompat_lst_enable) && (conf_core.editor.io_incomp_popup)) { + pcb_view_t *violation = pcb_view_new(&PCB->hidlib, type, title, description); + if ((obj != NULL) && (obj->type & PCB_OBJ_CLASS_REAL)) { + pcb_view_append_obj(violation, 0, obj); + pcb_view_set_bbox_by_objs(PCB->Data, violation); + } + pcb_view_list_append(&pcb_io_incompat_lst, violation); + } + else { + rnd_message(RND_MSG_ERROR, "save error: %s\n", title); + if (obj != NULL) { + rnd_coord_t x = (obj->BoundingBox.X1 + obj->BoundingBox.X2)/2; + rnd_coord_t y = (obj->BoundingBox.Y1 + obj->BoundingBox.Y2)/2; + rnd_message(RND_MSG_ERROR, " near %$mm %$mm\n", x, y); + } + if (description != NULL) + rnd_message(RND_MSG_ERROR, " (%s)\n", description); + } + return 0; +} + +pcb_plug_fp_map_t *pcb_io_map_footprint_file(rnd_hidlib_t *hl, const char *fn, pcb_plug_fp_map_t *head, int need_tags) +{ + FILE *f = rnd_fopen(hl, fn, "r"); + pcb_plug_fp_map_t *res = NULL; + pcb_plug_io_t *plug; + + if (f == NULL) { + head->type = PCB_FP_INVALID; + return head; + } + + for(plug = pcb_plug_io_chain; plug != NULL; plug = plug->next) { + if (plug->map_footprint == NULL) continue; + + rewind(f); + head->type = PCB_FP_INVALID; + head->libtype = PCB_LIB_FOOTPRINT; + res = plug->map_footprint(NULL, f, fn, head, need_tags); + if (res == NULL) continue; + if (res->type != PCB_FP_INVALID) + break; /* success */ + vts0_uninit(&res->tags); + } + + + fclose(f); + if (res == NULL) { + res = head; + head->type = PCB_FP_INVALID; + } + return res; +} + +void pcb_io_fp_map_append(pcb_plug_fp_map_t **tail, pcb_plug_fp_map_t *head, const char *filename, const char *fpname) +{ + pcb_plug_fp_map_t *m; + + switch(head->type) { + case PCB_FP_INVALID: /* first append */ + (*tail)->type = PCB_FP_FILE; + (*tail)->name = rnd_strdup(fpname); + break; + case PCB_FP_FILE: /* second append */ + /* clone the existing head */ + m = calloc(sizeof(pcb_plug_fp_map_t), 1); + m->type = PCB_FP_FILE; + m->libtype = PCB_LIB_FOOTPRINT; + m->name = head->name; + + head->type = PCB_FP_DIR; + head->libtype = PCB_LIB_DIR; + head->name = rnd_strdup(filename); + head->next = m; + + *tail = m; + /* fall through adding the second */ + case PCB_FP_DIR: /* third append */ + m = calloc(sizeof(pcb_plug_fp_map_t), 1); + m->type = PCB_FP_FILE; + m->libtype = PCB_LIB_FOOTPRINT; + m->name = rnd_strdup(fpname); + + (*tail)->next = m; + *tail = m; + break; + case PCB_FP_FILEDIR: + case PCB_FP_PARAMETRIC: + assert(!"broken format plugin: shouldn't do PCB_FP_FILDIR or PCB_FP_PARAMETRIC"); + break; + } +} + +void pcb_io_fp_map_free_fields(pcb_plug_fp_map_t *m) +{ +/* + Do NOTE free tag values, they are allocated by the central fp hash + long n; + for(n = 0; n < m->tags.used; n++) + free(m->tags.array[n]); +*/ + vts0_uninit(&m->tags); + free(m->name); + m->name = NULL; + m->type = 0; + m->libtype = 0; +} + +void pcb_io_fp_map_free(pcb_plug_fp_map_t *head) +{ + pcb_plug_fp_map_t *m, *next; + + pcb_io_fp_map_free_fields(head); + + for(m = head->next; m != NULL; m = next) { + next = m->next; + pcb_io_fp_map_free_fields(m); + free(m); + } +} + + +void pcb_io_uninit(void) +{ + pcb_view_list_free_fields(&pcb_io_incompat_lst); + if (pcb_plug_io_chain != NULL) { + rnd_message(RND_MSG_ERROR, "pcb_plug_io_chain is not empty; a plugin did not remove itself from the chain. Fix your plugins!\n"); + rnd_message(RND_MSG_ERROR, "head: desc='%s'\n", pcb_plug_io_chain->description); + } + free(last_design_dir); + last_design_dir = NULL; +} Index: tags/2.3.0/src/plug_io.h =================================================================== --- tags/2.3.0/src/plug_io.h (nonexistent) +++ tags/2.3.0/src/plug_io.h (revision 33253) @@ -0,0 +1,252 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,1997,1998,2005,2006 Thomas Nau + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_PLUG_IO_H +#define PCB_PLUG_IO_H + +#include "global_typedefs.h" +#include "vtlibrary.h" +#include +#include + +typedef enum { /* I/O type bitmask; each bit is one thing to save or load, not all formats support all things */ + PCB_IOT_PCB = 1, + PCB_IOT_FOOTPRINT = 2, + PCB_IOT_FONT = 4, + PCB_IOT_BUFFER = 8, + PCB_IOT_PADSTACK = 16 +} pcb_plug_iot_t; + +/* Returned by map_footprint() to tell what type of footprint(s) a file contains */ +struct pcb_plug_fp_map_s { + pcb_fptype_t type; + pcb_fplibrary_type_t libtype; /* normally LIB_FOOTPRINT */ + vts0_t tags; + char *name; /* strdup'd */ + pcb_plug_fp_map_t *next; +}; + +/**************************** API definition *********************************/ +struct pcb_plug_io_s { + pcb_plug_io_t *next; + void *plugin_data; + + /* Check if the plugin supports format fmt, for writing (if wr != 0) or for + reading (if wr == 0) for I/O type typ. Return 0 if not supported or an + integer priority if supported. The higher the prio is the more likely + the plugin gets the next operation on the file. Base prio should be + 100 for native formats. + NOTE: if any format can be chosen for output, the user will have to pick + one; for ordering plugins in that case, the format-neutral + save_preference_prio field is used. + */ + int (*fmt_support_prio)(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, int wr, const char *fmt); + + /* Test if the given file is readable by the plugin. The plugin should return + 1 if it can handle the file or 0 if it can not. This check is not a deep + syntax analysis; the plugin should read barely enough headers to decide if + the file contains a the format it expect, then return error from parse_pcb + if there are syntax errors later. The file is open for read and positioned + to file begin in f */ + int (*test_parse)(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); + + /* Attempt to load a pcb design from Filename to Ptr. + Conf subtree at settings_dest is replaced by settings loaded from the + file unless it's RND_CFR_invalid. + Return 0 on success. */ + int (*parse_pcb)(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest); + + /* Attempt to load an element from Filename to Ptr. Return 0 on success. */ + int (*parse_footprint)(pcb_plug_io_t *ctx, pcb_data_t *Ptr, const char *name, const char *subfpname); + + /* Scan as little as possible from the file to decide what the file is and extract tags; + For a single file, load head and return it. For a library-type file, load + head with the first footprint then allocate further footprints in a singly + linked list. If need_tags is 0, do not parse for tags */ + pcb_plug_fp_map_t *(*map_footprint)(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags); + + + /* Attempt to load fonts from a file. Return 0 on success. */ + int (*parse_font)(pcb_plug_io_t *ctx, pcb_font_t *Ptr, const char *Filename); + + /* Attempt to load a complete buffer from a file. Return 0 on success. */ + int (*parse_buffer)(pcb_plug_io_t *ctx, pcb_buffer_t *buff, const char *filename); + + /* Attempt to load padstack prototype */ + int (*parse_padstack)(pcb_plug_io_t *ctx, pcb_pstk_proto_t *dst, const char *filename); + + + /* Write a padstack prototype to a file. Return 0 on success. */ + int (*write_padstack)(pcb_plug_io_t *ctx, FILE *f, pcb_pstk_proto_t *dst); + + /* Write the buffer to a file. Return 0 on success. */ + int (*write_buffer)(pcb_plug_io_t *ctx, FILE *f, pcb_buffer_t *buff); + + /* Write subcircuit(s): head, 0 or more subcircuits and tail. udata may be + initialized by head and free'd by tail. If lib is 1, a library of footprints + should be written. + Return 0 on success.*/ + int (*write_subcs_head)(pcb_plug_io_t *ctx, void **udata, FILE *f, int lib, long num_subcs); + int (*write_subcs_subc)(pcb_plug_io_t *ctx, void **udata, FILE *f, pcb_subc_t *subc); + int (*write_subcs_tail)(pcb_plug_io_t *ctx, void **udata, FILE *f); + + /* Write PCB to f; there's a copy of the file we are going to + "overwrite", named in old_filename and the new file name we are + using is new_filename. The file names are NULL if we are saving + into a pipe. If emergency is true, do the safest save possible, + don't mind formatting and extras. + Return 0 on success. */ + int (*write_pcb)(pcb_plug_io_t *ctx, FILE *f, const char *old_filename, const char *new_filename, rnd_bool emergency); + + /* Attempt to write the font to file. Return 0 on success. */ + int (*write_font)(pcb_plug_io_t *ctx, pcb_font_t *font, const char *Filename); + + /* OPTIONAL: save-as subdialog; sub is the parent's, already initialized + subdialog; init() returns an plugin-allocated context that is then + passed to uninit at the end. Note: save_as_subd_init() shall be + unique; if multiple pcb_plug_io_t structs share the same init(), + only one, shared format-setting-tab is created for them. If apply is + true, the dialog box was closed with okay on this format selected. */ + void *(*save_as_subd_init)(const pcb_plug_io_t *ctx, rnd_hid_dad_subdialog_t *sub, pcb_plug_iot_t type); + void (*save_as_subd_uninit)(const pcb_plug_io_t *ctx, void *plg_ctx, rnd_hid_dad_subdialog_t *sub, rnd_bool apply); + void (*save_as_fmt_changed)(const pcb_plug_io_t *ctx, void *plg_ctx, rnd_hid_dad_subdialog_t *sub); + + const char *default_fmt; + const char *description; + const char *default_extension; /* used to generate save-as filename */ + const char *fp_extension; /* used to generate save-as filename for footprints */ + const char *mime_type; + + int save_preference_prio; /* all available save plugins are sorted by this before presenting them to the user to choose one */ + + unsigned multi_footprint:1; /* if a single footprint file may contain multiple footprints (footprint mapping needs to be called for direct load) */ +}; +extern pcb_plug_io_t *pcb_plug_io_chain; + + +/********** hook wrappers **********/ +int pcb_parse_pcb(pcb_board_t *Ptr, const char *Filename, const char *fmt, int load_settings, int ignore_missing); +int pcb_parse_footprint(pcb_data_t *Ptr, const char *name, const char *fmt); +int pcb_parse_font(pcb_font_t *Ptr, const char *Filename); +int pcb_write_footprint_data(FILE *f, pcb_data_t *e, const char *fmt, long subc_idx); +int pcb_write_font(pcb_font_t *Ptr, const char *Filename, const char *fmt); + +/* map a footprint file: always returns head with 0 or 1 or more mapping results */ +pcb_plug_fp_map_t *pcb_io_map_footprint_file(rnd_hidlib_t *hl, const char *fn, pcb_plug_fp_map_t *head, int need_tags); + +/* Append a file name to the footprint map at tail; the first item is appended + assuming there would be only one footprint in the file; from the second item + the head item is converted into a footprint library */ +void pcb_io_fp_map_append(pcb_plug_fp_map_t **tail, pcb_plug_fp_map_t *head, const char *filename, const char *fpname); + +/* Free a map with a statically allocated head */ +void pcb_io_fp_map_free(pcb_plug_fp_map_t *head); +void pcb_io_fp_map_free_fields(pcb_plug_fp_map_t *m); + + + +/********** common function used to be part of file.[ch] and friends **********/ +int pcb_save_pcb(const char *, const char *fmt); +#define PCB_INHIBIT_BOARD_CHANGED 0x20 +int pcb_load_pcb(const char *name, const char *fmt, rnd_bool, int how); /* how: 0=normal pcb; 1=default.pcb, 2=misc (do not load settings) | 0x10: ignore missing file, | PCB_INHIBIT_BOARD_CHANGED: do not send a board changed event */ +void pcb_enable_autosave(void); +void pcb_backup(void); +void pcb_save_in_tmp(void); +void pcb_emergency_save(void); +void pcb_disable_emergency_save(void); +int pcb_revert_pcb(void); +int pcb_save_buffer_subcs(const char *, const char *fmt, long subc_idx); +int pcb_save_buffer(const char *Filename, const char *fmt); +void pcb_print_quoted_string_(FILE *, const char *); /* without wrapping in "" */ +void pcb_print_quoted_string(FILE *, const char *); /* with wrapping in "" */ +int pcb_write_pcb_file(const char *Filename, rnd_bool thePcb, const char *fmt, rnd_bool emergency, rnd_bool subc_only, long subc_idx, int askovr); +void pcb_set_design_dir(const char *fn); +int pcb_load_buffer(rnd_hidlib_t *hidlib, pcb_buffer_t *buff, const char *fn, const char *fmt); +int pcb_write_padstack(FILE *f, pcb_pstk_proto_t *proto, const char *fmt); +int pcb_load_padstack(rnd_hidlib_t *hidlib, pcb_pstk_proto_t *proto, const char *fn, const char *fmt); + +/* Find the plugin that offers the highest write prio for the format */ +pcb_plug_io_t *pcb_io_find_writer(pcb_plug_iot_t typ, const char *fmt); + +/********** helpers **********/ + +/* wish we had more than 32 IO plugins... */ +#define PCB_IO_MAX_FORMATS 32 + +/* A list of format plugins available for a given purpose */ +typedef struct { + int len; + const pcb_plug_io_t *plug[PCB_IO_MAX_FORMATS+1]; + char *digest[PCB_IO_MAX_FORMATS+1]; /* string that contains the format identifier and the description (strdup'd) */ + const char *extension[PCB_IO_MAX_FORMATS+1]; /* default file extension, with the leading . (not strdup'd) */ +} pcb_io_formats_t; + +typedef enum { + PCB_IOL_EXT_NONE, + PCB_IOL_EXT_BOARD, + PCB_IOL_EXT_FP +} pcb_io_list_ext_t; + +/* Search all io plugins to see if typ/wr is supported. Return an ordered + list in out. If do_digest is non-zero, fill in the digest field. Returns + number of suitable io plugins. Call pcb_io_list_free() on out when it is not + needed anymore. */ +int pcb_io_list(pcb_io_formats_t *out, pcb_plug_iot_t typ, int wr, int do_digest, pcb_io_list_ext_t ext); +void pcb_io_list_free(pcb_io_formats_t *out); + +extern int pcb_io_err_inhibit; +#define pcb_io_err_inhibit_inc() pcb_io_err_inhibit++ +#define pcb_io_err_inhibit_dec() \ +do { \ + if (pcb_io_err_inhibit > 0) \ + pcb_io_err_inhibit--; \ +} while(0) + +/* Find all plugins that can handle typ/is_wr and build an ordered list in available[], + highest prio first. If fmt is NULL, use the default fmt for each plugin. + Return the length of the array. */ +typedef struct { + pcb_plug_io_t *plug; + int prio; +} pcb_find_io_t; +int pcb_find_io(pcb_find_io_t *available, int avail_len, pcb_plug_iot_t typ, int is_wr, const char *fmt); + +/* Indicate an incompatibility on save; data and obj may be NULL (they are + used for navigating the user to the problem). Desc should be a short + description (must not be NULL), details should go in hint (can be NULL). + Returns a report ID. */ +rnd_cardinal_t pcb_io_incompat_save(pcb_data_t *data, pcb_any_obj_t *obj, const char *type, const char *title, const char *description); + +void pcb_io_uninit(void); + +void pcb_plug_io_err(rnd_hidlib_t *hidlib, int res, const char *what, const char *filename); + + + +#endif Index: tags/2.3.0/src/polygon.c =================================================================== --- tags/2.3.0/src/polygon.c (nonexistent) +++ tags/2.3.0/src/polygon.c (revision 33253) @@ -0,0 +1,1803 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2010 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* pcb-rnd specific polygon editing routines + see doc/developer/polygon.html for more info */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include + +#include "board.h" +#include +#include "data.h" +#include "draw.h" +#include +#include "polygon.h" +#include "remove.h" +#include "search.h" +#include "thermal.h" +#include "undo.h" +#include "layer.h" +#include "obj_poly_draw.h" +#include "obj_text_draw.h" +#include +#include +#include "event.h" + +#define UNSUBTRACT_BLOAT 10 +#define SUBTRACT_PIN_VIA_BATCH_SIZE 100 +#define SUBTRACT_PADSTACK_BATCH_SIZE 50 +#define SUBTRACT_LINE_BATCH_SIZE 20 + +#define sqr(x) ((x)*(x)) + +#undef min +#undef max +#define min(x, y) ((x) < (y) ? (x) : (y)) +#define max(x, y) ((x) > (y) ? (x) : (y)) + +static int Unsubtract(rnd_polyarea_t * np1, pcb_poly_t * p); + +static const char *polygon_cookie = "core polygon"; + + +void pcb_poly_layers_chg(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pcb_layer_t *ly; + pcb_data_t *data; + + if ((argc < 2) || (argv[1].type != RND_EVARG_PTR)) + return; + ly = argv[1].d.p; + if ((ly->is_bound) || (ly->parent_type != PCB_PARENT_DATA)) + return; + + data = ly->parent.data; + pcb_data_clip_inhibit_inc(data); + PCB_POLY_LOOP(ly); { + polygon->clip_dirty = 1; + } + PCB_END_LOOP; + pcb_data_clip_inhibit_dec(data, 1); +} + +void pcb_polygon_init(void) +{ + rnd_event_bind(PCB_EVENT_LAYER_CHANGED_GRP, pcb_poly_layers_chg, NULL, polygon_cookie); +} + +void pcb_polygon_uninit(void) +{ + rnd_event_unbind_allcookie(polygon_cookie); +} + +rnd_cardinal_t pcb_poly_point_idx(pcb_poly_t *polygon, rnd_point_t *point) +{ + assert(point >= polygon->Points); + assert(point <= polygon->Points + polygon->PointN); + return ((char *) point - (char *) polygon->Points) / sizeof(rnd_point_t); +} + +/* Find contour number: 0 for outer, 1 for first hole etc.. */ +rnd_cardinal_t pcb_poly_contour_point(pcb_poly_t *polygon, rnd_cardinal_t point) +{ + rnd_cardinal_t i; + rnd_cardinal_t contour = 0; + + for (i = 0; i < polygon->HoleIndexN; i++) + if (point >= polygon->HoleIndex[i]) + contour = i + 1; + return contour; +} + +rnd_cardinal_t pcb_poly_contour_next_point(pcb_poly_t *polygon, rnd_cardinal_t point) +{ + rnd_cardinal_t contour; + rnd_cardinal_t this_contour_start; + rnd_cardinal_t next_contour_start; + + contour = pcb_poly_contour_point(polygon, point); + + this_contour_start = (contour == 0) ? 0 : polygon->HoleIndex[contour - 1]; + next_contour_start = (contour == polygon->HoleIndexN) ? polygon->PointN : polygon->HoleIndex[contour]; + + /* Wrap back to the start of the contour we're in if we pass the end */ + if (++point == next_contour_start) + point = this_contour_start; + + return point; +} + +rnd_cardinal_t pcb_poly_contour_prev_point(pcb_poly_t *polygon, rnd_cardinal_t point) +{ + rnd_cardinal_t contour; + rnd_cardinal_t prev_contour_end; + rnd_cardinal_t this_contour_end; + + contour = pcb_poly_contour_point(polygon, point); + + prev_contour_end = (contour == 0) ? 0 : polygon->HoleIndex[contour - 1]; + this_contour_end = (contour == polygon->HoleIndexN) ? polygon->PointN - 1 : polygon->HoleIndex[contour] - 1; + + /* Wrap back to the start of the contour we're in if we pass the end */ + if (point == prev_contour_end) + point = this_contour_end; + else + point--; + + return point; +} + +static void add_noholes_polyarea(rnd_pline_t * pline, void *user_data) +{ + pcb_poly_t *poly = (pcb_poly_t *) user_data; + + /* Prepend the pline into the NoHoles linked list */ + pline->next = poly->NoHoles; + poly->NoHoles = pline; +} + +void pcb_poly_compute_no_holes(pcb_poly_t * poly) +{ + rnd_poly_contours_free(&poly->NoHoles); + if (poly->Clipped) + pcb_poly_no_holes_dicer(poly, NULL, add_noholes_polyarea, poly); + else + printf("Compute_noholes caught poly->Clipped = NULL\n"); + poly->NoHolesValid = 1; +} + +static rnd_polyarea_t *biggest(rnd_polyarea_t * p) +{ + rnd_polyarea_t *n, *top = NULL; + rnd_pline_t *pl; + rnd_rtree_t *tree; + double big = -1; + if (!p) + return NULL; + n = p; + do { +#if 0 + if (n->contours->area < conf_core.design.poly_isle_area) { + n->b->f = n->f; + n->f->b = n->b; + rnd_poly_contour_del(&n->contours); + if (n == p) + p = n->f; + n = n->f; + if (!n->contours) { + free(n); + return NULL; + } + } +#endif + if (n->contours->area > big) { + top = n; + big = n->contours->area; + } + } + while ((n = n->f) != p); + assert(top); + if (top == p) + return p; + pl = top->contours; + tree = top->contour_tree; + top->contours = p->contours; + top->contour_tree = p->contour_tree; + p->contours = pl; + p->contour_tree = tree; + assert(pl); + assert(p->f); + assert(p->b); + return p; +} + +rnd_polyarea_t *pcb_poly_to_polyarea(pcb_poly_t *p, rnd_bool *need_full) +{ + rnd_pline_t *contour = NULL; + rnd_polyarea_t *np1 = NULL, *np = NULL; + rnd_cardinal_t n; + rnd_vector_t v; + int hole = 0; + + *need_full = rnd_false; + + np1 = np = rnd_polyarea_create(); + if (np == NULL) + return NULL; + + /* first make initial polygon contour */ + for (n = 0; n < p->PointN; n++) { + /* No current contour? Make a new one starting at point */ + /* (or) Add point to existing contour */ + + v[0] = p->Points[n].X; + v[1] = p->Points[n].Y; + if (contour == NULL) { + if ((contour = rnd_poly_contour_new(v)) == NULL) + return NULL; + } + else { + rnd_poly_vertex_include(contour->head->prev, rnd_poly_node_create(v)); + } + + /* Is current point last in contour? If so process it. */ + if (n == p->PointN - 1 || (hole < p->HoleIndexN && n == p->HoleIndex[hole] - 1)) { + rnd_poly_contour_pre(contour, rnd_true); + + /* make sure it is a positive contour (outer) or negative (hole) */ + if (contour->Flags.orient != (hole ? RND_PLF_INV : RND_PLF_DIR)) + rnd_poly_contour_inv(contour); + assert(contour->Flags.orient == (hole ? RND_PLF_INV : RND_PLF_DIR)); + + rnd_polyarea_contour_include(np, contour); + contour = NULL; + +TODO("multiple plines within the returned polyarea np does not really work\n"); +#if 0 + if (!rnd_poly_valid(np)) { + rnd_cardinal_t cnt = rnd_polyarea_split_selfint(np); + rnd_message(RND_MSG_ERROR, "Had to split up self-intersecting polygon into %ld parts\n", (long)cnt); + if (cnt > 1) + *need_full = rnd_true; + assert(rnd_poly_valid(np)); + } +#else + assert(rnd_poly_valid(np)); +#endif + + hole++; + } + } + return biggest(np1); +} + +rnd_polyarea_t *pcb_poly_from_poly(pcb_poly_t * p) +{ + rnd_bool tmp; + return pcb_poly_to_polyarea(p, &tmp); +} + + +rnd_polyarea_t *pcb_poly_from_pcb_line(pcb_line_t *L, rnd_coord_t thick) +{ + return rnd_poly_from_line(L->Point1.X, L->Point1.Y, L->Point2.X, L->Point2.Y, thick, PCB_FLAG_TEST(PCB_FLAG_SQUARE, L)); +} + +rnd_polyarea_t *pcb_poly_from_pcb_arc(pcb_arc_t *a, rnd_coord_t thick) +{ + return rnd_poly_from_arc(a->X, a->Y, a->Width, a->Height, a->StartAngle, a->Delta, thick); +} + + +/* clear np1 from the polygon - should be inline with -O3 */ +static int Subtract(rnd_polyarea_t * np1, pcb_poly_t * p, rnd_bool fnp) +{ + rnd_polyarea_t *merged = NULL, *np = np1; + int x; + assert(np); + assert(p); + if (!p->Clipped) { + if (fnp) + rnd_polyarea_free(&np); + return 1; + } + assert(rnd_poly_valid(p->Clipped)); + assert(rnd_poly_valid(np)); + if (fnp) + x = rnd_polyarea_boolean_free(p->Clipped, np, &merged, RND_PBO_SUB); + else { + x = rnd_polyarea_boolean(p->Clipped, np, &merged, RND_PBO_SUB); + rnd_polyarea_free(&p->Clipped); + } + assert(!merged || rnd_poly_valid(merged)); + if (x != rnd_err_ok) { + fprintf(stderr, "Error while clipping RND_PBO_SUB: %d\n", x); + rnd_polyarea_free(&merged); + p->Clipped = NULL; + if (p->NoHoles) + printf("Just leaked in Subtract\n"); + p->NoHoles = NULL; + return -1; + } + p->Clipped = biggest(merged); + assert(!p->Clipped || rnd_poly_valid(p->Clipped)); + if (!p->Clipped) + rnd_message(RND_MSG_WARNING, "Polygon #%ld cleared out of existence near (%$mm, %$mm)\n", + p->ID, (p->BoundingBox.X1 + p->BoundingBox.X2) / 2, (p->BoundingBox.Y1 + p->BoundingBox.Y2) / 2); + return 1; +} + +int pcb_poly_subtract(rnd_polyarea_t *np1, pcb_poly_t *p, rnd_bool fnp) +{ + return Subtract(np1, p, fnp); +} + +static rnd_polyarea_t *pcb_poly_from_box_bloated_(rnd_box_t * box, rnd_coord_t bloat, rnd_coord_t enforce_clr, rnd_coord_t obj_clr) +{ + if ((enforce_clr != 0) && (enforce_clr*2 > obj_clr)) /* in case of poly-side clearance, the bounding box has to be adjusted: original object side clearance removed, larger poly side clearance added */ + bloat += obj_clr - enforce_clr/2; + return rnd_poly_from_rect(box->X1 - bloat, box->X2 + bloat, box->Y1 - bloat, box->Y2 + bloat); +} + +rnd_polyarea_t *pcb_poly_from_box_bloated(rnd_box_t * box, rnd_coord_t bloat) +{ + return pcb_poly_from_box_bloated_(box, bloat, 0, 0); +} + +/* remove the padstack clearance from the polygon */ +static int SubtractPadstack(pcb_data_t *d, pcb_pstk_t *ps, pcb_layer_t *l, pcb_poly_t *p) +{ + rnd_polyarea_t *np; + rnd_layer_id_t i; + + /* ps->Clearance == 0 doesn't mean no clearance because of the per shape clearances */ + if (!PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, ps)) + return 0; + i = pcb_layer_id(d, l); + np = pcb_thermal_area_pstk(pcb_data_get_top(d), ps, i, p); + if (np == 0) + return 0; + + return Subtract(np, p, rnd_true); +} + +/* return the clearance polygon for a line */ +static rnd_polyarea_t *line_clearance_poly(rnd_cardinal_t layernum, pcb_board_t *pcb, pcb_line_t *line, pcb_poly_t *in_poly) +{ + if (line->thermal & PCB_THERMAL_ON) + return pcb_thermal_area_line(pcb, line, layernum, in_poly); + return pcb_poly_from_pcb_line(line, line->Thickness + pcb_obj_clearance_p2(line, in_poly)); +} + +static int SubtractLine(pcb_line_t * line, pcb_poly_t * p) +{ + rnd_polyarea_t *np; + + if (!PCB_NONPOLY_HAS_CLEARANCE(line)) + return 0; + if (!(np = line_clearance_poly(-1, NULL, line, p))) + return -1; + return Subtract(np, p, rnd_true); +} + +static int SubtractArc(pcb_arc_t * arc, pcb_poly_t * p) +{ + rnd_polyarea_t *np; + + if (!PCB_NONPOLY_HAS_CLEARANCE(arc)) + return 0; + if (!(np = pcb_poly_from_pcb_arc(arc, arc->Thickness + pcb_obj_clearance_p2(arc, p)))) + return -1; + return Subtract(np, p, rnd_true); +} + +typedef struct { + pcb_poly_t *poly; + rnd_coord_t clearance; + unsigned sub:1; + rnd_polyarea_t *pa; /* in case of sub==0 the result is accumulated here */ +} poly_poly_text_t; + +static void poly_sub_text_cb(void *ctx_, pcb_any_obj_t *obj) +{ + poly_poly_text_t *ctx = ctx_; + pcb_line_t *line = (pcb_line_t *)obj; + pcb_poly_t *poly = (pcb_poly_t *)obj; + pcb_arc_t *arc = (pcb_arc_t *)obj; + rnd_polyarea_t *np = NULL; + rnd_bool need_full; + + switch(obj->type) { + case PCB_OBJ_LINE: np = pcb_poly_from_pcb_line(line, line->Thickness + RND_MAX(ctx->clearance, ctx->poly->enforce_clearance)); break; + case PCB_OBJ_ARC: np = pcb_poly_from_pcb_arc(arc, arc->Thickness + RND_MAX(ctx->clearance, ctx->poly->enforce_clearance)); break; + case PCB_OBJ_POLY: + poly->Clipped = pcb_poly_to_polyarea(poly, &need_full); + np = pcb_poly_clearance_construct(poly, &ctx->clearance, ctx->poly); + rnd_polyarea_free(&poly->Clipped); + break; + default:; + } + + if (np != NULL) { + if (ctx->sub) { /* subtract from ctx->poly directly (drawing clearance) */ + Subtract(np, ctx->poly, rnd_true); + ctx->poly->NoHolesValid = 0; + } + else { /* add to ctx->pa (constructing the clearance polygon for other purposes) */ + if (ctx->pa != NULL) { + rnd_polyarea_t *tmp; + rnd_polyarea_boolean_free(ctx->pa, np, &tmp, RND_PBO_UNITE); + ctx->pa = tmp; + } + else + ctx->pa = np; + } + } +} + +static pcb_draw_info_t tsub_info; +static rnd_xform_t tsub_xform; + +static int SubtractText(pcb_text_t * text, pcb_poly_t * p) +{ + poly_poly_text_t sctx; + int by_bbox = !text->tight_clearance; + + if (!PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, text)) + return 0; + + if (by_bbox) { + /* old method: clear by bounding box */ + const rnd_box_t *b = &text->BoundingBox; + rnd_coord_t clr = RND_MAX(conf_core.design.bloat, p->enforce_clearance); + rnd_polyarea_t *np; + if (!(np = rnd_poly_from_round_rect(b->X1 + conf_core.design.bloat, b->X2 - conf_core.design.bloat, b->Y1 + conf_core.design.bloat, b->Y2 - conf_core.design.bloat, clr))) + return -1; + return Subtract(np, p, rnd_true); + } + + /* new method: detailed clearance */ + sctx.poly = p; + sctx.clearance = text->clearance + RND_MM_TO_COORD(0.5); + sctx.sub = 1; + tsub_info.xform = &tsub_xform; + pcb_text_decompose_text(&tsub_info, text, poly_sub_text_cb, &sctx); + return 1; +} + +rnd_polyarea_t *pcb_poly_construct_text_clearance(pcb_text_t *text) +{ + poly_poly_text_t sctx; + pcb_poly_t dummy = {0}; + int by_bbox = !text->tight_clearance; + + if (!PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, text)) + return NULL; + + if (by_bbox) { + /* old method: clear by bounding box */ + const rnd_box_t *b = &text->BoundingBox; + rnd_coord_t clr = conf_core.design.bloat; + return rnd_poly_from_round_rect(b->X1 + conf_core.design.bloat, b->X2 - conf_core.design.bloat, b->Y1 + conf_core.design.bloat, b->Y2 - conf_core.design.bloat, clr); + } + + /* new method: detailed clearance */ + sctx.poly = &dummy; + sctx.pa = NULL; + sctx.clearance = text->clearance + RND_MM_TO_COORD(0.5); + sctx.sub = 0; + tsub_info.xform = &tsub_xform; + pcb_text_decompose_text(&tsub_info, text, poly_sub_text_cb, &sctx); + return sctx.pa; +} + + +struct cpInfo { + const rnd_box_t *other; + pcb_data_t *data; + pcb_layer_t *layer; + pcb_poly_t *polygon; + rnd_bool solder; + rnd_polyarea_t *accumulate; + int batch_size; + jmp_buf env; +}; + +static void subtract_accumulated(struct cpInfo *info, pcb_poly_t *polygon) +{ + if (info->accumulate == NULL) + return; + Subtract(info->accumulate, polygon, rnd_true); + info->accumulate = NULL; + info->batch_size = 0; +} + +static int pcb_poly_clip_noop = 0; +static void *pcb_poly_clip_prog_ctx; +static void (*pcb_poly_clip_prog)(void *ctx) = NULL; + +/* call the progress report callback and return if no-op is set */ +#define POLY_CLIP_PROG() \ +do { \ + if (pcb_poly_clip_prog != NULL) \ + pcb_poly_clip_prog(pcb_poly_clip_prog_ctx); \ + if (pcb_poly_clip_noop) \ + return RND_R_DIR_FOUND_CONTINUE; \ +} while(0) + +static rnd_r_dir_t padstack_sub_callback(const rnd_box_t *b, void *cl) +{ + pcb_pstk_t *ps = (pcb_pstk_t *)b; + struct cpInfo *info = (struct cpInfo *)cl; + pcb_poly_t *polygon; + rnd_polyarea_t *np; + rnd_polyarea_t *merged; + rnd_layer_id_t i; + + /* don't subtract the object that was put back! */ + if (b == info->other) + return RND_R_DIR_NOT_FOUND; + polygon = info->polygon; + + /* ps->Clearance == 0 doesn't mean no clearance because of the per shape clearances */ + if (!PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, ps)) + return RND_R_DIR_NOT_FOUND; + + i = pcb_layer_id(info->data, info->layer); + + np = pcb_thermal_area_pstk(pcb_data_get_top(info->data), ps, i, polygon); + if (np == 0) + return RND_R_DIR_FOUND_CONTINUE; + + info->batch_size++; + POLY_CLIP_PROG(); + + rnd_polyarea_boolean_free(info->accumulate, np, &merged, RND_PBO_UNITE); + info->accumulate = merged; + + if (info->batch_size == SUBTRACT_PADSTACK_BATCH_SIZE) + subtract_accumulated(info, polygon); + + return RND_R_DIR_FOUND_CONTINUE; +} + +static rnd_r_dir_t arc_sub_callback(const rnd_box_t * b, void *cl) +{ + pcb_arc_t *arc = (pcb_arc_t *) b; + struct cpInfo *info = (struct cpInfo *) cl; + pcb_poly_t *polygon; + + /* don't subtract the object that was put back! */ + if (b == info->other) + return RND_R_DIR_NOT_FOUND; + if (!PCB_NONPOLY_HAS_CLEARANCE(arc)) + return RND_R_DIR_NOT_FOUND; + + POLY_CLIP_PROG(); + + polygon = info->polygon; + + if (SubtractArc(arc, polygon) < 0) + longjmp(info->env, 1); + return RND_R_DIR_FOUND_CONTINUE; +} + +/* quick create a polygon area from a line, knowing the coords and width */ +static rnd_polyarea_t *poly_sub_callback_line(rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t width) +{ + static pcb_line_t lin; + static int inited = 0; + + if (!inited) { + lin.type = PCB_OBJ_LINE; + lin.Flags = pcb_no_flags(); + PCB_FLAG_SET(PCB_FLAG_CLEARLINE, &lin); + lin.Thickness = 0; + inited = 1; + } + + lin.Point1.X = x1; + lin.Point1.Y = y1; + lin.Point2.X = x2; + lin.Point2.Y = y2; + lin.Clearance = width; + + return pcb_poly_from_pcb_line(&lin, width); +} + +#define pa_append(src) \ + do { \ + rnd_polyarea_boolean(*dst, src, &tmp, RND_PBO_UNITE); \ + rnd_polyarea_free(dst); \ + *dst = tmp; \ + } while(0) + +void pcb_poly_pa_clearance_construct(rnd_polyarea_t **dst, pcb_poly_it_t *it, rnd_coord_t clearance) +{ + rnd_polyarea_t *tmp, *lin; + rnd_coord_t x, y, px, py, x0, y0; + rnd_pline_t *pl; + int go; + rnd_cardinal_t cnt; + + if (*dst != NULL) + pa_append(it->pa); + else + rnd_polyarea_copy0(dst, it->pa); + + if (clearance == 0) + return; + + clearance *= 2; + + /* care about the outer contours only */ + pl = pcb_poly_contour(it); + if (pl != NULL) { + /* iterate over the vectors of the contour */ + for(go = pcb_poly_vect_first(it, &x, &y), cnt = 0; go; go = pcb_poly_vect_next(it, &x, &y), cnt++) { + if (cnt > 0) { + lin = poly_sub_callback_line(px, py, x, y, clearance); + pa_append(lin); + rnd_polyarea_free(&lin); + } + else { + x0 = x; + y0 = y; + } + px = x; + py = y; + } + if (cnt > 0) { + lin = poly_sub_callback_line(px, py, x0, y0, clearance); + pa_append(lin); + rnd_polyarea_free(&lin); + } + } +} +#undef pa_append + +/* Construct a poly area that represents the enlarged subpoly - so it can be + subtracted from the parent poly to form the clearance for subpoly. + If clr_override is not NULL, use that clearance value instead of the subpoly's */ +rnd_polyarea_t *pcb_poly_clearance_construct(pcb_poly_t *subpoly, rnd_coord_t *clr_override, pcb_poly_t *in_poly) +{ + rnd_polyarea_t *ret = NULL, *pa; + pcb_poly_it_t it; + rnd_coord_t clr; + + if (clr_override != NULL) + clr = *clr_override; + else + clr = subpoly->Clearance/2; + + if (in_poly != NULL) + clr = RND_MAX(clr, in_poly->enforce_clearance); + /* iterate over all islands of a polygon */ + for(pa = pcb_poly_island_first(subpoly, &it); pa != NULL; pa = pcb_poly_island_next(&it)) + pcb_poly_pa_clearance_construct(&ret, &it, clr); + + return ret; +} + +/* return the clearance polygon for a line */ +static rnd_polyarea_t *poly_clearance_poly(rnd_cardinal_t layernum, pcb_board_t *pcb, pcb_poly_t *subpoly, pcb_poly_t *in_poly) +{ + if (subpoly->thermal & PCB_THERMAL_ON) + return pcb_thermal_area_poly(pcb, subpoly, layernum, in_poly); + return pcb_poly_clearance_construct(subpoly, NULL, in_poly); +} + + +static int SubtractPolyPoly(pcb_poly_t *subpoly, pcb_poly_t *frompoly) +{ + rnd_polyarea_t *pa; + + if (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, frompoly)) /* two clearing polys won't interact */ + return 0; /* but it's not an error, that'd kill other clearances in the same poly */ + + pa = poly_clearance_poly(-1, NULL, subpoly, frompoly); + if (pa == NULL) + return -1; + + Subtract(pa, frompoly, rnd_true); + frompoly->NoHolesValid = 0; + return 0; +} + + +static int UnsubtractPolyPoly(pcb_poly_t *subpoly, pcb_poly_t *frompoly) +{ + rnd_polyarea_t *pa; + + if (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, frompoly)) /* two clearing polys won't interact */ + return 0; /* but it's not an error, that'd kill other clearances in the same poly */ + + pa = poly_clearance_poly(-1, NULL, subpoly, frompoly); + if (pa == NULL) + return -1; + + if (!Unsubtract(pa, frompoly)) + return -1; + frompoly->NoHolesValid = 0; + return 0; +} + +static rnd_r_dir_t poly_sub_callback(const rnd_box_t *b, void *cl) +{ + pcb_poly_t *subpoly = (pcb_poly_t *)b; + struct cpInfo *info = (struct cpInfo *) cl; + pcb_poly_t *polygon; + + polygon = info->polygon; + + /* don't do clearance in itself */ + if (subpoly == polygon) + return RND_R_DIR_NOT_FOUND; + + /* don't subtract the object that was put back! */ + if (b == info->other) + return RND_R_DIR_NOT_FOUND; + if (!PCB_POLY_HAS_CLEARANCE(subpoly)) + return RND_R_DIR_NOT_FOUND; + + POLY_CLIP_PROG(); + + if (SubtractPolyPoly(subpoly, polygon) < 0) + longjmp(info->env, 1); + + return RND_R_DIR_FOUND_CONTINUE; +} + +static rnd_r_dir_t line_sub_callback(const rnd_box_t * b, void *cl) +{ + pcb_line_t *line = (pcb_line_t *) b; + struct cpInfo *info = (struct cpInfo *) cl; + pcb_poly_t *polygon; + rnd_polyarea_t *np; + rnd_polyarea_t *merged; + + /* don't subtract the object that was put back! */ + if (b == info->other) + return RND_R_DIR_NOT_FOUND; + if (!PCB_NONPOLY_HAS_CLEARANCE(line)) + return RND_R_DIR_NOT_FOUND; + polygon = info->polygon; + + POLY_CLIP_PROG(); + + np = line_clearance_poly(-1, NULL, line, polygon); + if (!np) + longjmp(info->env, 1); + + rnd_polyarea_boolean_free(info->accumulate, np, &merged, RND_PBO_UNITE); + info->accumulate = merged; + info->batch_size++; + + if (info->batch_size == SUBTRACT_LINE_BATCH_SIZE) + subtract_accumulated(info, polygon); + + return RND_R_DIR_FOUND_CONTINUE; +} + +static rnd_r_dir_t text_sub_callback(const rnd_box_t * b, void *cl) +{ + pcb_text_t *text = (pcb_text_t *) b; + struct cpInfo *info = (struct cpInfo *) cl; + pcb_poly_t *polygon; + + /* don't subtract the object that was put back! */ + if (b == info->other) + return RND_R_DIR_NOT_FOUND; + if (!PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, text)) + return RND_R_DIR_NOT_FOUND; + + POLY_CLIP_PROG(); + + polygon = info->polygon; + if (SubtractText(text, polygon) < 0) + longjmp(info->env, 1); + return RND_R_DIR_FOUND_CONTINUE; +} + +static rnd_cardinal_t clearPoly(pcb_data_t *Data, pcb_layer_t *Layer, pcb_poly_t *polygon, const rnd_box_t *here, rnd_coord_t expand, int noop) +{ + rnd_cardinal_t r = 0; + int seen; + rnd_box_t region; + struct cpInfo info; + rnd_layergrp_id_t group; + unsigned int gflg; + pcb_layer_type_t lf; + int old_noop; + + lf = pcb_layer_flags_(Layer); + if (!(lf & PCB_LYT_COPPER)) { /* also handles lf == 0 */ + polygon->NoHolesValid = 0; + return 0; + } + + if (!PCB_FLAG_TEST(PCB_FLAG_CLEARPOLY, polygon)) + return 0; + + old_noop = pcb_poly_clip_noop; + pcb_poly_clip_noop = noop; + + group = pcb_layer_get_group_(Layer); + gflg = pcb_layergrp_flags(PCB, group); + info.solder = (gflg & PCB_LYT_BOTTOM); + info.data = Data; + info.other = here; + info.layer = Layer; + info.polygon = polygon; + if (here) + region = rnd_clip_box(here, &polygon->BoundingBox); + else + region = polygon->BoundingBox; + region = rnd_bloat_box(®ion, expand); + + if (setjmp(info.env) == 0) { + + r = 0; + info.accumulate = NULL; + info.batch_size = 0; + PCB_COPPER_GROUP_LOOP(Data, group); + { + rnd_r_search(layer->line_tree, ®ion, NULL, line_sub_callback, &info, &seen); + r += seen; + subtract_accumulated(&info, polygon); + rnd_r_search(layer->arc_tree, ®ion, NULL, arc_sub_callback, &info, &seen); + r += seen; + rnd_r_search(layer->text_tree, ®ion, NULL, text_sub_callback, &info, &seen); + r += seen; + rnd_r_search(layer->polygon_tree, ®ion, NULL, poly_sub_callback, &info, &seen); + r += seen; + } + PCB_END_LOOP; + rnd_r_search(Data->padstack_tree, ®ion, NULL, padstack_sub_callback, &info, &seen); + r += seen; + subtract_accumulated(&info, polygon); + } + if (!noop) + polygon->NoHolesValid = 0; + pcb_poly_clip_noop = old_noop; + return r; +} + +static int Unsubtract(rnd_polyarea_t * np1, pcb_poly_t * p) +{ + rnd_polyarea_t *merged = NULL, *np = np1; + rnd_polyarea_t *orig_poly, *clipped_np; + int x; + rnd_bool need_full; + assert(np); + assert(p); /* NOTE: p->clipped might be NULL if a poly is "cleared out of existence" and is now coming back */ + + orig_poly = pcb_poly_to_polyarea(p, &need_full); + + x = rnd_polyarea_boolean_free(np, orig_poly, &clipped_np, RND_PBO_ISECT); + if (x != rnd_err_ok) { + fprintf(stderr, "Error while clipping RND_PBO_ISECT: %d\n", x); + rnd_polyarea_free(&clipped_np); + goto fail; + } + + x = rnd_polyarea_boolean_free(p->Clipped, clipped_np, &merged, RND_PBO_UNITE); + if (x != rnd_err_ok) { + fprintf(stderr, "Error while clipping RND_PBO_UNITE: %d\n", x); + rnd_polyarea_free(&merged); + goto fail; + } + p->Clipped = biggest(merged); + assert(!p->Clipped || rnd_poly_valid(p->Clipped)); + return 1; + +fail: + p->Clipped = NULL; + if (p->NoHoles) + printf("Just leaked in Unsubtract\n"); + p->NoHoles = NULL; + return 0; +} + +static int UnsubtractPadstack(pcb_data_t *data, pcb_pstk_t *ps, pcb_layer_t *l, pcb_poly_t *p) +{ + rnd_polyarea_t *np; + + /* overlap a bit to prevent gaps from rounding errors */ + np = pcb_poly_from_box_bloated_(&ps->BoundingBox, UNSUBTRACT_BLOAT * 400000, p->enforce_clearance, ps->Clearance); + + if (!np) + return 0; + if (!Unsubtract(np, p)) + return 0; + + clearPoly(PCB->Data, l, p, (const rnd_box_t *)ps, 2 * UNSUBTRACT_BLOAT * 400000, 0); + return 1; +} + + + +static int UnsubtractArc(pcb_arc_t * arc, pcb_layer_t * l, pcb_poly_t * p) +{ + rnd_polyarea_t *np; + + if (!PCB_NONPOLY_HAS_CLEARANCE(arc)) + return 0; + + /* overlap a bit to prevent gaps from rounding errors */ + np = pcb_poly_from_box_bloated_(&arc->BoundingBox, UNSUBTRACT_BLOAT, p->enforce_clearance, arc->Clearance); + + if (!np) + return 0; + if (!Unsubtract(np, p)) + return 0; + clearPoly(PCB->Data, l, p, (const rnd_box_t *) arc, 2 * UNSUBTRACT_BLOAT, 0); + return 1; +} + +static int UnsubtractLine(pcb_line_t * line, pcb_layer_t * l, pcb_poly_t * p) +{ + rnd_polyarea_t *np; + + if (!PCB_NONPOLY_HAS_CLEARANCE(line)) + return 0; + + /* overlap a bit to prevent notches from rounding errors */ + np = pcb_poly_from_box_bloated_(&line->BoundingBox, UNSUBTRACT_BLOAT, p->enforce_clearance, line->Clearance); + + if (!np) + return 0; + if (!Unsubtract(np, p)) + return 0; + clearPoly(PCB->Data, l, p, (const rnd_box_t *) line, 2 * UNSUBTRACT_BLOAT, 0); + return 1; +} + +static int UnsubtractText(pcb_text_t * text, pcb_layer_t * l, pcb_poly_t * p) +{ + rnd_polyarea_t *np; + + if (!PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, text)) + return 0; + + /* overlap a bit to prevent notches from rounding errors */ + np = pcb_poly_from_box_bloated_(&text->BoundingBox, UNSUBTRACT_BLOAT, p->enforce_clearance, text->clearance); + + if (!np) + return -1; + if (!Unsubtract(np, p)) + return 0; + clearPoly(PCB->Data, l, p, (const rnd_box_t *) text, 2 * UNSUBTRACT_BLOAT, 0); + return 1; +} + +static rnd_bool inhibit = rnd_false; + +int pcb_poly_init_clip_prog(pcb_data_t *Data, pcb_layer_t *layer, pcb_poly_t *p, void (*cb)(void *ctx), void *ctx, int force) +{ + pcb_board_t *pcb; + rnd_bool need_full; + void (*old_cb)(void *ctx); + void *old_ctx; + + if (inhibit) + return 0; + + if ((!force) && (Data->clip_inhibit > 0)) { + p->clip_dirty = 1; + return 0; + } + + if (layer->is_bound) + layer = layer->meta.bound.real; + + if (p->Clipped) + rnd_polyarea_free(&p->Clipped); + p->Clipped = pcb_poly_to_polyarea(p, &need_full); + if (need_full && !PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, p)) { + rnd_message(RND_MSG_WARNING, "Polygon #%ld was self intersecting; it had to be split up and\nthe full poly flag set.\n", (long)p->ID); + PCB_FLAG_SET(PCB_FLAG_FULLPOLY, p); + } + rnd_poly_contours_free(&p->NoHoles); + + p->clip_dirty = 0; + + if (layer == NULL) + return 0; + + if (!p->Clipped) + return 0; + assert(rnd_poly_valid(p->Clipped)); + + /* calculate clipping for the real data (in case of subcircuits) */ + pcb = pcb_data_get_top(Data); + if (pcb != NULL) + Data = pcb->Data; + + old_cb = pcb_poly_clip_prog; + old_ctx = pcb_poly_clip_prog_ctx; + pcb_poly_clip_prog = cb; + pcb_poly_clip_prog_ctx = ctx; + + if (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLY, p)) + clearPoly(Data, layer, p, NULL, 0, 0); + else + p->NoHolesValid = 0; + + pcb_poly_clip_prog = old_cb; + pcb_poly_clip_prog_ctx = old_ctx; + return 1; +} + +int pcb_poly_init_clip(pcb_data_t *Data, pcb_layer_t *layer, pcb_poly_t *p) +{ + return pcb_poly_init_clip_prog(Data, layer, p, NULL, NULL, 0); +} + +int pcb_poly_init_clip_force(pcb_data_t *Data, pcb_layer_t *layer, pcb_poly_t *p) +{ + return pcb_poly_init_clip_prog(Data, layer, p, NULL, NULL, 1); +} + +rnd_cardinal_t pcb_poly_num_clears(pcb_data_t *data, pcb_layer_t *layer, pcb_poly_t *polygon) +{ + rnd_cardinal_t res; + void (*old_cb)(void *ctx); + + if (layer->is_bound) + layer = layer->meta.bound.real; + + old_cb = pcb_poly_clip_prog; + pcb_poly_clip_prog = NULL; + + res = clearPoly(data, layer, polygon, NULL, 0, 1); + + pcb_poly_clip_prog = old_cb; + return res; +} + +/* -------------------------------------------------------------------------- + * remove redundant polygon points. Any point that lies on the straight + * line between the points on either side of it is redundant. + * returns rnd_true if any points are removed + */ +rnd_bool pcb_poly_remove_excess_points(pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + rnd_point_t *p; + rnd_cardinal_t n, prev, next; + pcb_line_t line; + rnd_bool changed = rnd_false; + + if (pcb_undoing()) + return rnd_false; + + for (n = 0; n < Polygon->PointN; n++) { + prev = pcb_poly_contour_prev_point(Polygon, n); + next = pcb_poly_contour_next_point(Polygon, n); + p = &Polygon->Points[n]; + + line.Point1 = Polygon->Points[prev]; + line.Point2 = Polygon->Points[next]; + line.Thickness = 0; + if (pcb_is_point_on_line(p->X, p->Y, 0.0, &line)) { + pcb_remove_object(PCB_OBJ_POLY_POINT, Layer, Polygon, p); + changed = rnd_true; + } + } + return changed; +} + +/* --------------------------------------------------------------------------- + * returns the index of the polygon point which is the end + * point of the segment with the lowest distance to the passed + * coordinates + */ +rnd_cardinal_t pcb_poly_get_lowest_distance_point(pcb_poly_t *Polygon, rnd_coord_t X, rnd_coord_t Y) +{ + double mindistance = (double) RND_MAX_COORD * RND_MAX_COORD; + rnd_point_t *ptr1, *ptr2; + rnd_cardinal_t n, result = 0; + + /* we calculate the distance to each segment and choose the + * shortest distance. If the closest approach between the + * given point and the projected line (i.e. the segment extended) + * is not on the segment, then the distance is the distance + * to the segment end point. + */ + + for (n = 0; n < Polygon->PointN; n++) { + double u, dx, dy; + ptr1 = &Polygon->Points[pcb_poly_contour_prev_point(Polygon, n)]; + ptr2 = &Polygon->Points[n]; + + dx = ptr2->X - ptr1->X; + dy = ptr2->Y - ptr1->Y; + if (dx != 0.0 || dy != 0.0) { + /* projected intersection is at P1 + u(P2 - P1) */ + u = ((X - ptr1->X) * dx + (Y - ptr1->Y) * dy) / (dx * dx + dy * dy); + + if (u < 0.0) { /* ptr1 is closest point */ + u = RND_SQUARE(X - ptr1->X) + RND_SQUARE(Y - ptr1->Y); + } + else if (u > 1.0) { /* ptr2 is closest point */ + u = RND_SQUARE(X - ptr2->X) + RND_SQUARE(Y - ptr2->Y); + } + else { /* projected intersection is closest point */ + u = RND_SQUARE(X - ptr1->X * (1.0 - u) - u * ptr2->X) + RND_SQUARE(Y - ptr1->Y * (1.0 - u) - u * ptr2->Y); + } + if (u < mindistance) { + mindistance = u; + result = n; + } + } + } + return result; +} + +/* --------------------------------------------------------------------------- + * go back to the previous point of the polygon (undo) + */ +void pcb_polygon_go_to_prev_point(void) +{ + switch (pcb_crosshair.AttachedPolygon.PointN) { + /* do nothing if mode has just been entered */ + case 0: + break; + + /* reset number of points line tool state */ + case 1: + pcb_crosshair.AttachedPolygon.PointN = 0; + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_FIRST; + break; + + /* back-up one point */ + default: + { + rnd_point_t *points = pcb_crosshair.AttachedPolygon.Points; + rnd_cardinal_t n = pcb_crosshair.AttachedPolygon.PointN - 2; + + pcb_crosshair.AttachedPolygon.PointN--; + pcb_crosshair.AttachedLine.Point1.X = points[n].X; + pcb_crosshair.AttachedLine.Point1.Y = points[n].Y; + break; + } + } +} + +/* --------------------------------------------------------------------------- + * go forward to the next point of the polygon (redo) + */ +void pcb_polygon_go_to_next_point(void) +{ + if ((pcb_crosshair.AttachedPolygon.PointN > 0) && (pcb_crosshair.AttachedPolygon.PointN < pcb_crosshair.AttachedPolygon_pts)) { + rnd_point_t *points = pcb_crosshair.AttachedPolygon.Points; + rnd_cardinal_t n = pcb_crosshair.AttachedPolygon.PointN; + + pcb_crosshair.AttachedPolygon.PointN++; + pcb_crosshair.AttachedLine.Point1.X = points[n].X; + pcb_crosshair.AttachedLine.Point1.Y = points[n].Y; + } +} + +/* --------------------------------------------------------------------------- + * close polygon if possible + */ +void pcb_polygon_close_poly(void) +{ + rnd_cardinal_t n = pcb_crosshair.AttachedPolygon.PointN; + + /* check number of points */ + if (n >= 3) { + /* if 45 degree lines are what we want do a quick check + * if closing the polygon makes sense + */ + if (!conf_core.editor.all_direction_lines) { + rnd_coord_t dx, dy; + + dx = coord_abs(pcb_crosshair.AttachedPolygon.Points[n - 1].X - pcb_crosshair.AttachedPolygon.Points[0].X); + dy = coord_abs(pcb_crosshair.AttachedPolygon.Points[n - 1].Y - pcb_crosshair.AttachedPolygon.Points[0].Y); + if (!(dx == 0 || dy == 0 || dx == dy)) { + rnd_message(RND_MSG_ERROR, "Cannot close polygon because 45 degree lines are requested.\n"); + return; + } + } + pcb_polygon_copy_attached_to_layer(); + pcb_draw(); + } + else + rnd_message(RND_MSG_ERROR, "A polygon has to have at least 3 points\n"); +} + +static void poly_copy_data(pcb_poly_t *dst, pcb_poly_t *src) +{ + pcb_poly_t p; + void *old_parent = dst->parent.any; + pcb_parenttype_t old_pt = dst->parent_type; + + memcpy(dst, src, ((char *)&p.link - (char *)&p)); + dst->type = PCB_OBJ_POLY; + dst->parent.any = old_parent; + dst->parent_type = old_pt; +} + +/* --------------------------------------------------------------------------- + * moves the data of the attached (new) polygon to the current layer + */ +void pcb_polygon_copy_attached_to_layer(void) +{ + pcb_layer_t *layer = pcb_loose_subc_layer(PCB, PCB_CURRLAYER(PCB), rnd_true); + pcb_poly_t *polygon; + int saveID; + + /* move data to layer and clear attached struct */ + polygon = pcb_poly_new(layer, 0, pcb_no_flags()); + saveID = polygon->ID; + poly_copy_data(polygon, &pcb_crosshair.AttachedPolygon); + polygon->Clearance = 2 * conf_core.design.clearance; + polygon->ID = saveID; + PCB_FLAG_SET(PCB_FLAG_CLEARPOLY, polygon); + if (conf_core.editor.full_poly) + PCB_FLAG_SET(PCB_FLAG_FULLPOLY, polygon); + if (conf_core.editor.clear_polypoly) + PCB_FLAG_SET(PCB_FLAG_CLEARPOLYPOLY, polygon); + + memset(&pcb_crosshair.AttachedPolygon, 0, sizeof(pcb_poly_t)); + + pcb_add_poly_on_layer(layer, polygon); + + pcb_poly_init_clip(PCB->Data, layer, polygon); + pcb_poly_invalidate_draw(layer, polygon); + pcb_board_set_changed_flag(PCB, rnd_true); + + /* reset state of attached line */ + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_FIRST; + + /* add to undo list */ + pcb_undo_add_obj_to_create(PCB_OBJ_POLY, layer, polygon, polygon); + pcb_undo_inc_serial(); +} + +/* --------------------------------------------------------------------------- + * close polygon hole if possible + */ +void pcb_polygon_close_hole(void) +{ + rnd_cardinal_t n = pcb_crosshair.AttachedPolygon.PointN; + + /* check number of points */ + if (n >= 3) { + /* if 45 degree lines are what we want do a quick check + * if closing the polygon makes sense + */ + if (!conf_core.editor.all_direction_lines) { + rnd_coord_t dx, dy; + + dx = coord_abs(pcb_crosshair.AttachedPolygon.Points[n - 1].X - pcb_crosshair.AttachedPolygon.Points[0].X); + dy = coord_abs(pcb_crosshair.AttachedPolygon.Points[n - 1].Y - pcb_crosshair.AttachedPolygon.Points[0].Y); + if (!(dx == 0 || dy == 0 || dx == dy)) { + rnd_message(RND_MSG_ERROR, "Cannot close polygon hole because 45 degree lines are requested.\n"); + return; + } + } + pcb_polygon_hole_create_from_attached(); + pcb_draw(); + } + else + rnd_message(RND_MSG_ERROR, "A polygon hole has to have at least 3 points\n"); +} + +/* --------------------------------------------------------------------------- + * creates a hole of attached polygon shape in the underneath polygon + */ +void pcb_polygon_hole_create_from_attached(void) +{ + rnd_polyarea_t *original, *new_hole, *result; + pcb_flag_t Flags; + + /* Create pcb_polyarea_ts from the original polygon + * and the new hole polygon */ + original = pcb_poly_from_poly((pcb_poly_t *) pcb_crosshair.AttachedObject.Ptr2); + new_hole = pcb_poly_from_poly(&pcb_crosshair.AttachedPolygon); + + /* Subtract the hole from the original polygon shape */ + rnd_polyarea_boolean_free(original, new_hole, &result, RND_PBO_SUB); + + /* Convert the resulting polygon(s) into a new set of nodes + * and place them on the page. Delete the original polygon. + */ + pcb_undo_save_serial(); + Flags = ((pcb_poly_t *) pcb_crosshair.AttachedObject.Ptr2)->Flags; + pcb_poly_to_polygons_on_layer(PCB->Data, (pcb_layer_t *) pcb_crosshair.AttachedObject.Ptr1, result, Flags); + pcb_remove_object(PCB_OBJ_POLY, + pcb_crosshair.AttachedObject.Ptr1, pcb_crosshair.AttachedObject.Ptr2, pcb_crosshair.AttachedObject.Ptr3); + pcb_undo_restore_serial(); + pcb_undo_inc_serial(); + + /* reset state of attached line */ + memset(&pcb_crosshair.AttachedPolygon, 0, sizeof(pcb_poly_t)); + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_FIRST; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; +} + +/* find polygon holes in range, then call the callback function for + * each hole. If the callback returns non-zero, stop + * the search. + */ +int +pcb_poly_holes(pcb_poly_t * polygon, const rnd_box_t * range, int (*callback) (rnd_pline_t * contour, void *user_data), void *user_data) +{ + rnd_polyarea_t *pa = polygon->Clipped; + rnd_pline_t *pl; + /* If this hole is so big the polygon doesn't exist, then it's not + * really a hole. + */ + if (!pa) + return 0; + for (pl = pa->contours->next; pl; pl = pl->next) { + if (range != NULL && (pl->xmin > range->X2 || pl->xmax < range->X1 || pl->ymin > range->Y2 || pl->ymax < range->Y1)) + continue; + if (callback(pl, user_data)) { + return 1; + } + } + return 0; +} + +struct plow_info { + int type; + void *ptr1, *ptr2; + pcb_layer_t *layer; + pcb_data_t *data; + void *user_data; + rnd_r_dir_t (*callback)(pcb_data_t *, pcb_layer_t *, pcb_poly_t *, int, void *, void *, void *user_data); +}; + +static rnd_r_dir_t subtract_plow(pcb_data_t *Data, pcb_layer_t *Layer, pcb_poly_t *Polygon, int type, void *ptr1, void *ptr2, void *user_data) +{ + if (!Polygon->Clipped) + return 0; + switch (type) { + case PCB_OBJ_PSTK: + SubtractPadstack(Data, (pcb_pstk_t *) ptr2, Layer, Polygon); + Polygon->NoHolesValid = 0; + return RND_R_DIR_FOUND_CONTINUE; + case PCB_OBJ_LINE: + SubtractLine((pcb_line_t *) ptr2, Polygon); + Polygon->NoHolesValid = 0; + return RND_R_DIR_FOUND_CONTINUE; + case PCB_OBJ_ARC: + SubtractArc((pcb_arc_t *) ptr2, Polygon); + Polygon->NoHolesValid = 0; + return RND_R_DIR_FOUND_CONTINUE; + case PCB_OBJ_POLY: + if (ptr2 != Polygon) { + SubtractPolyPoly((pcb_poly_t *) ptr2, Polygon); + Polygon->NoHolesValid = 0; + return RND_R_DIR_FOUND_CONTINUE; + } + break; + case PCB_OBJ_TEXT: + SubtractText((pcb_text_t *) ptr2, Polygon); + Polygon->NoHolesValid = 0; + return RND_R_DIR_FOUND_CONTINUE; + } + return RND_R_DIR_NOT_FOUND; +} + +static rnd_r_dir_t add_plow(pcb_data_t *Data, pcb_layer_t *Layer, pcb_poly_t *Polygon, int type, void *ptr1, void *ptr2, void *user_data) +{ + switch (type) { + case PCB_OBJ_PSTK: + UnsubtractPadstack(Data, (pcb_pstk_t *) ptr2, Layer, Polygon); + return RND_R_DIR_FOUND_CONTINUE; + case PCB_OBJ_LINE: + UnsubtractLine((pcb_line_t *) ptr2, Layer, Polygon); + return RND_R_DIR_FOUND_CONTINUE; + case PCB_OBJ_ARC: + UnsubtractArc((pcb_arc_t *) ptr2, Layer, Polygon); + return RND_R_DIR_FOUND_CONTINUE; + case PCB_OBJ_POLY: + if (ptr2 != Polygon) { + UnsubtractPolyPoly((pcb_poly_t *) ptr2, Polygon); + return RND_R_DIR_FOUND_CONTINUE; + } + break; + case PCB_OBJ_TEXT: + UnsubtractText((pcb_text_t *) ptr2, Layer, Polygon); + return RND_R_DIR_FOUND_CONTINUE; + } + return RND_R_DIR_NOT_FOUND; +} + +int pcb_poly_sub_obj(pcb_data_t *Data, pcb_layer_t *Layer, pcb_poly_t *Polygon, int type, void *obj) +{ + if (subtract_plow(Data, Layer, Polygon, type, NULL, obj, NULL) == RND_R_DIR_FOUND_CONTINUE) + return 0; + return -1; +} + +int pcb_poly_unsub_obj(pcb_data_t *Data, pcb_layer_t *Layer, pcb_poly_t *Polygon, int type, void *obj) +{ + if (add_plow(Data, Layer, Polygon, type, NULL, obj, NULL) == RND_R_DIR_FOUND_CONTINUE) + return 0; + return -1; +} + + +static rnd_r_dir_t plow_callback(const rnd_box_t * b, void *cl) +{ + struct plow_info *plow = (struct plow_info *) cl; + pcb_poly_t *polygon = (pcb_poly_t *) b; + + if (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLY, polygon)) + return plow->callback(plow->data, plow->layer, polygon, plow->type, plow->ptr1, plow->ptr2, plow->user_data); + return RND_R_DIR_NOT_FOUND; +} + +/* poly plows while clipping inhibit is on: mark any potentail polygon dirty */ +static rnd_r_dir_t poly_plows_inhibited_cb(pcb_data_t *data, pcb_layer_t *lay, pcb_poly_t *poly, int type, void *ptr1, void *ptr2, void *user_data) +{ + poly->clip_dirty = 1; + return RND_R_DIR_FOUND_CONTINUE; +} + + +int pcb_poly_plows(pcb_data_t *Data, int type, void *ptr1, void *ptr2, + rnd_r_dir_t (*call_back) (pcb_data_t *data, pcb_layer_t *lay, pcb_poly_t *poly, int type, void *ptr1, void *ptr2, void *user_data), + void *user_data) +{ + rnd_box_t sb = ((pcb_any_obj_t *) ptr2)->BoundingBox; + int r = 0, seen; + struct plow_info info; + + if (Data->clip_inhibit > 0) + call_back = poly_plows_inhibited_cb; + + info.type = type; + info.ptr1 = ptr1; + info.ptr2 = ptr2; + info.data = Data; + info.user_data = user_data; + info.callback = call_back; + switch (type) { + case PCB_OBJ_PSTK: + if (Data->parent_type != PCB_PARENT_BOARD) + return 0; + if (ptr1 == NULL) { /* no layer specified: run on all layers */ + LAYER_LOOP(Data, pcb_max_layer(PCB)); + { + if (!(pcb_layer_flags_(layer) & PCB_LYT_COPPER)) + continue; + r += pcb_poly_plows(Data, type, layer, ptr2, call_back, NULL); + } + PCB_END_LOOP; + return r; + } + + /* run on the specified layer (ptr1), if there's any need for clearing */ + /* ps->Clearance == 0 doesn't mean no clearance because of the per shape clearances */ + if (!PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, (pcb_pstk_t *)ptr2)) + return 0; + goto doit; + case PCB_OBJ_POLY: + if (!PCB_POLY_HAS_CLEARANCE((pcb_poly_t *) ptr2)) + return 0; + goto doit; + + case PCB_OBJ_LINE: + case PCB_OBJ_ARC: + /* the cast works equally well for lines and arcs */ + if (!PCB_NONPOLY_HAS_CLEARANCE((pcb_line_t *) ptr2)) + return 0; + goto doit; + + case PCB_OBJ_TEXT: + /* text has no clearance property */ + if (!PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, (pcb_line_t *) ptr2)) + return 0; + /* non-copper (e.g. silk, outline) doesn't plow */ +TODO(": use pcb_layer_flags_ here - but what PCB?") + if (!(pcb_layer_flags(PCB, pcb_layer_id(Data, (pcb_layer_t *) ptr1) & PCB_LYT_COPPER))) + return 0; + doit:; + PCB_COPPER_GROUP_LOOP(Data, pcb_layer_get_group(PCB, pcb_layer_id(Data, ((pcb_layer_t *) ptr1)))); + { + info.layer = layer; + rnd_r_search(layer->polygon_tree, &sb, NULL, plow_callback, &info, &seen); + r += seen; + } + PCB_END_LOOP; + break; + } + return r; +} + +void pcb_poly_restore_to_poly(pcb_data_t * Data, int type, void *ptr1, void *ptr2) +{ + pcb_data_t *dt = Data; + while((dt != NULL) && (dt->parent_type == PCB_PARENT_SUBC)) + dt = dt->parent.subc->parent.data; + if ((dt == NULL) || (dt->parent_type != PCB_PARENT_BOARD)) /* clear/restore only on boards */ + return; + if (type == PCB_OBJ_POLY) + pcb_poly_init_clip(dt, (pcb_layer_t *) ptr1, (pcb_poly_t *) ptr2); + pcb_poly_plows(dt, type, ptr1, ptr2, add_plow, NULL); +} + +void pcb_poly_clear_from_poly(pcb_data_t * Data, int type, void *ptr1, void *ptr2) +{ + pcb_data_t *dt = Data; + while((dt != NULL) && (dt->parent_type == PCB_PARENT_SUBC)) + dt = dt->parent.subc->parent.data; + if ((dt == NULL) || (dt->parent_type != PCB_PARENT_BOARD)) /* clear/restore only on boards */ + return; + if (type == PCB_OBJ_POLY) + pcb_poly_init_clip(dt, (pcb_layer_t *) ptr1, (pcb_poly_t *) ptr2); + pcb_poly_plows(dt, type, ptr1, ptr2, subtract_plow, NULL); +} + +rnd_bool pcb_poly_isects_poly(rnd_polyarea_t * a, pcb_poly_t *p, rnd_bool fr) +{ + rnd_polyarea_t *x; + rnd_bool ans; + ans = rnd_polyarea_touching(a, p->Clipped); + /* argument may be register, so we must copy it */ + x = a; + if (fr) + rnd_polyarea_free(&x); + return ans; +} + + +rnd_bool pcb_poly_is_point_in_p(rnd_coord_t X, rnd_coord_t Y, rnd_coord_t r, pcb_poly_t *p) +{ + rnd_polyarea_t *c; + rnd_vector_t v; + v[0] = X; + v[1] = Y; + if (rnd_polyarea_contour_inside(p->Clipped, v)) + return rnd_true; + + if (PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, p)) { + pcb_poly_t tmp = *p; + + /* Check all clipped-away regions that are now drawn because of full-poly */ + for (tmp.Clipped = p->Clipped->f; tmp.Clipped != p->Clipped; tmp.Clipped = tmp.Clipped->f) + if (rnd_polyarea_contour_inside(tmp.Clipped, v)) + return rnd_true; + } + + if (r < 1) + return rnd_false; + if (!(c = rnd_poly_from_circle(X, Y, r))) + return rnd_false; + return pcb_poly_isects_poly(c, p, rnd_true); +} + + +rnd_bool pcb_poly_is_point_in_p_ignore_holes(rnd_coord_t X, rnd_coord_t Y, pcb_poly_t *p) +{ + rnd_vector_t v; + v[0] = X; + v[1] = Y; + return rnd_poly_contour_inside(p->Clipped->contours, v); +} + +rnd_bool pcb_poly_is_rect_in_p(rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, pcb_poly_t *p) +{ + rnd_polyarea_t *s; + if (!(s = rnd_poly_from_rect(min(X1, X2), max(X1, X2), min(Y1, Y2), max(Y1, Y2)))) + return rnd_false; + return pcb_poly_isects_poly(s, p, rnd_true); +} + +void pcb_poly_no_holes_dicer(pcb_poly_t *p, const rnd_box_t *clip, void (*emit)(rnd_pline_t *, void *), void *user_data) +{ + rnd_polyarea_t *main_contour; + + main_contour = rnd_polyarea_create(); + /* copy the main poly only */ + rnd_polyarea_copy1(main_contour, p->Clipped); + + if (clip == NULL) + rnd_polyarea_no_holes_dicer(main_contour, 0, 0, 0, 0, emit, user_data); + else + rnd_polyarea_no_holes_dicer(main_contour, clip->X1, clip->Y1, clip->X2, clip->Y2, emit, user_data); +} + +/* make a polygon split into multiple parts into multiple polygons */ +rnd_bool pcb_poly_morph(pcb_layer_t *layer, pcb_poly_t *poly) +{ + rnd_polyarea_t *p, *start; + rnd_bool many = rnd_false; + pcb_flag_t flags; + + if (!poly->Clipped || PCB_FLAG_TEST(PCB_FLAG_LOCK, poly)) + return rnd_false; + if (poly->Clipped->f == poly->Clipped) + return rnd_false; + pcb_poly_invalidate_erase(poly); + start = p = poly->Clipped; + /* This is ugly. The creation of the new polygons can cause + * all of the polygon pointers (including the one we're called + * with to change if there is a realloc in pcb_poly_alloc(). + * That will invalidate our original "poly" argument, potentially + * inside the loop. We need to steal the Clipped pointer and + * hide it from the Remove call so that it still exists while + * we do this dirty work. + */ + poly->Clipped = NULL; + if (poly->NoHoles) + printf("Just leaked in MorpyPolygon\n"); + poly->NoHoles = NULL; + flags = poly->Flags; + pcb_poly_remove(layer, poly); + inhibit = rnd_true; + do { + rnd_vnode_t *v; + pcb_poly_t *newone; + + if (p->contours->area > conf_core.design.poly_isle_area) { + newone = pcb_poly_new(layer, poly->Clearance, flags); + if (!newone) + return rnd_false; + many = rnd_true; + v = p->contours->head; + pcb_poly_point_new(newone, v->point[0], v->point[1]); + for (v = v->next; v != p->contours->head; v = v->next) + pcb_poly_point_new(newone, v->point[0], v->point[1]); + newone->BoundingBox.X1 = p->contours->xmin; + newone->BoundingBox.X2 = p->contours->xmax + 1; + newone->BoundingBox.Y1 = p->contours->ymin; + newone->BoundingBox.Y2 = p->contours->ymax + 1; + pcb_undo_add_obj_to_create(PCB_OBJ_POLY, layer, newone, newone); + newone->Clipped = p; + p = p->f; /* go to next pline */ + newone->Clipped->b = newone->Clipped->f = newone->Clipped; /* unlink from others */ + rnd_r_insert_entry(layer->polygon_tree, (rnd_box_t *) newone); + pcb_poly_invalidate_draw(layer, newone); + } + else { + rnd_polyarea_t *t = p; + + p = p->f; + rnd_poly_contour_del(&t->contours); + free(t); + } + } + while (p != start); + inhibit = rnd_false; + pcb_undo_inc_serial(); + return many; +} + +void debug_pline(rnd_pline_t * pl) +{ + rnd_vnode_t *v; + rnd_fprintf(stderr, "\txmin %#mS xmax %#mS ymin %#mS ymax %#mS\n", pl->xmin, pl->xmax, pl->ymin, pl->ymax); + v = pl->head; + while (v) { + rnd_fprintf(stderr, "\t\tvnode: %#mD\n", v->point[0], v->point[1]); + v = v->next; + if (v == pl->head) + break; + } +} + +void debug_polyarea(rnd_polyarea_t * p) +{ + rnd_pline_t *pl; + + fprintf(stderr, "rnd_polyarea_t %p\n", (void *)p); + for (pl = p->contours; pl; pl = pl->next) + debug_pline(pl); +} + +void debug_polygon(pcb_poly_t * p) +{ + rnd_cardinal_t i; + rnd_polyarea_t *pa; + fprintf(stderr, "POLYGON %p %d pts\n", (void *)p, p->PointN); + for (i = 0; i < p->PointN; i++) + rnd_fprintf(stderr, "\t%d: %#mD\n", i, p->Points[i].X, p->Points[i].Y); + if (p->HoleIndexN) { + fprintf(stderr, "%d holes, starting at indices\n", p->HoleIndexN); + for (i = 0; i < p->HoleIndexN; i++) + fprintf(stderr, "\t%d: %d\n", i, p->HoleIndex[i]); + } + else + fprintf(stderr, "it has no holes\n"); + pa = p->Clipped; + while (pa) { + debug_polyarea(pa); + pa = pa->f; + if (pa == p->Clipped) + break; + } +} + +/* Convert a rnd_polyarea_t (and all linked rnd_polyarea_t) to + * raw PCB polygons on the given layer. + */ +void pcb_poly_to_polygons_on_layer(pcb_data_t * Destination, pcb_layer_t * Layer, rnd_polyarea_t * Input, pcb_flag_t Flags) +{ + pcb_poly_t *Polygon; + rnd_polyarea_t *pa; + rnd_pline_t *pline; + rnd_vnode_t *node; + rnd_bool outer; + + if (Input == NULL) + return; + + pa = Input; + do { + Polygon = pcb_poly_new(Layer, 2 * conf_core.design.clearance, Flags); + + pline = pa->contours; + outer = rnd_true; + + do { + if (!outer) + pcb_poly_hole_new(Polygon); + outer = rnd_false; + + node = pline->head; + do { + pcb_poly_point_new(Polygon, node->point[0], node->point[1]); + } + while ((node = node->next) != pline->head); + + } + while ((pline = pline->next) != NULL); + + pcb_poly_init_clip(Destination, Layer, Polygon); + pcb_poly_bbox(Polygon); + if (!Layer->polygon_tree) + Layer->polygon_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + + pcb_poly_invalidate_draw(Layer, Polygon); + /* add to undo list */ + pcb_undo_add_obj_to_create(PCB_OBJ_POLY, Layer, Polygon, Polygon); + } + while ((pa = pa->f) != Input); + + pcb_board_set_changed_flag(PCB, rnd_true); +} + +rnd_bool pcb_pline_is_rectangle(rnd_pline_t *pl) +{ + int n; + rnd_coord_t x[4], y[4]; + rnd_vnode_t *v; + + v = pl->head->next; + n = 0; + do { + x[n] = v->point[0]; + y[n] = v->point[1]; + n++; + v = v->next; + } while((n < 4) && (v != pl->head->next)); + + if (n != 4) + return rnd_false; + + if (sqr(x[0] - x[2]) + sqr(y[0] - y[2]) == sqr(x[1] - x[3]) + sqr(y[1] - y[3])) + return rnd_true; + + return rnd_false; +} + Index: tags/2.3.0/src/polygon.h =================================================================== --- tags/2.3.0/src/polygon.h (nonexistent) +++ tags/2.3.0/src/polygon.h (revision 33253) @@ -0,0 +1,119 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* High level polygon support: pcb-specific polygon operations on complex + polygon objects with islands and holes */ + +#ifndef PCB_POLYGON_H +#define PCB_POLYGON_H + +#include "config.h" +#include "global_typedefs.h" +#include "flag.h" +#include +#include +#include +#include + + +/* Prototypes */ + +void pcb_polygon_init(void); +void pcb_polygon_uninit(void); +rnd_cardinal_t pcb_poly_point_idx(pcb_poly_t *polygon, rnd_point_t *point); +rnd_cardinal_t pcb_poly_contour_point(pcb_poly_t *polygon, rnd_cardinal_t point); +rnd_cardinal_t pcb_poly_contour_prev_point(pcb_poly_t *polygon, rnd_cardinal_t point); +rnd_cardinal_t pcb_poly_contour_next_point(pcb_poly_t *polygon, rnd_cardinal_t point); +rnd_cardinal_t pcb_poly_get_lowest_distance_point(pcb_poly_t *, rnd_coord_t, rnd_coord_t); +rnd_bool pcb_poly_remove_excess_points(pcb_layer_t *, pcb_poly_t *); +void pcb_polygon_go_to_prev_point(void); /* undo */ +void pcb_polygon_go_to_next_point(void); /* redo */ +void pcb_polygon_close_poly(void); +void pcb_polygon_copy_attached_to_layer(void); +void pcb_polygon_close_hole(void); +void pcb_polygon_hole_create_from_attached(void); +int pcb_poly_holes(pcb_poly_t * ptr, const rnd_box_t * range, int (*callback) (rnd_pline_t *, void *user_data), void *user_data); +int pcb_poly_plows(pcb_data_t *Data, int type, void *ptr1, void *ptr2, + rnd_r_dir_t (*cb)(pcb_data_t *data, pcb_layer_t *lay, pcb_poly_t *poly, int type, void *ptr1, void *ptr2, void *user_data), + void *user_data); +void pcb_poly_compute_no_holes(pcb_poly_t * poly); + +/* helpers: create complex shaped polygons */ +rnd_polyarea_t *pcb_poly_from_poly(pcb_poly_t *); +rnd_polyarea_t *pcb_poly_from_pcb_line(pcb_line_t * l, rnd_coord_t thick); +rnd_polyarea_t *pcb_poly_from_pcb_arc(pcb_arc_t * l, rnd_coord_t thick); +rnd_polyarea_t *pcb_poly_from_box_bloated(rnd_box_t * box, rnd_coord_t radius); +rnd_polyarea_t *pcb_poly_clearance_construct(pcb_poly_t *subpoly, rnd_coord_t *clr_override, pcb_poly_t *in_poly); /* clearance shape for when clearpolypoly is set */ + +int pcb_poly_init_clip(pcb_data_t * d, pcb_layer_t * l, pcb_poly_t * p); +int pcb_poly_init_clip_force(pcb_data_t *Data, pcb_layer_t *layer, pcb_poly_t *p); /* bypasses clip inhibit */ +void pcb_poly_restore_to_poly(pcb_data_t *, int, void *, void *); +void pcb_poly_clear_from_poly(pcb_data_t *, int, void *, void *); + +/* Convert a polygon to an unclipped polyarea */ +rnd_polyarea_t *pcb_poly_to_polyarea(pcb_poly_t *p, rnd_bool *need_full); + +/* Same as pcb_poly_init_clip() but also call cb before each operation, + giving the caller a chance to draw a progress bar */ +int pcb_poly_init_clip_prog(pcb_data_t *Data, pcb_layer_t *layer, pcb_poly_t *p, void (*cb)(void *ctx), void *ctx, int force); + +/* Return the number of subtractions that have to be executed by a + pcb_poly_init_clip() on the given polygon */ +rnd_cardinal_t pcb_poly_num_clears(pcb_data_t *data, pcb_layer_t *layer, pcb_poly_t *polygon); + + +rnd_bool pcb_poly_is_point_in_p(rnd_coord_t, rnd_coord_t, rnd_coord_t, pcb_poly_t *); +rnd_bool pcb_poly_is_point_in_p_ignore_holes(rnd_coord_t, rnd_coord_t, pcb_poly_t *); +rnd_bool_t pcb_is_point_in_convex_quad(rnd_vector_t p, rnd_vector_t *q); +rnd_bool pcb_poly_is_rect_in_p(rnd_coord_t, rnd_coord_t, rnd_coord_t, rnd_coord_t, pcb_poly_t *); +rnd_bool pcb_poly_isects_poly(rnd_polyarea_t *, pcb_poly_t *, rnd_bool); +rnd_bool pcb_pline_isect_line(rnd_pline_t *pl, rnd_coord_t lx1, rnd_coord_t ly1, rnd_coord_t lx2, rnd_coord_t ly2, rnd_coord_t *cx, rnd_coord_t *cy); +rnd_bool pcb_pline_isect_circ(rnd_pline_t *pl, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t r); /* cirlce contour crosses polyline contour */ +rnd_bool pcb_pline_embraces_circ(rnd_pline_t *pl, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t r); /* circle is within the polyline; caller must make sure they do not cross! */ +rnd_bool pcb_pline_overlaps_circ(rnd_pline_t *pl, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t r); /* circle is within or is crossing the polyline */ +rnd_bool pcb_poly_morph(pcb_layer_t *, pcb_poly_t *); +void pcb_poly_no_holes_dicer(pcb_poly_t * p, const rnd_box_t * clip, void (*emit) (rnd_pline_t *, void *), void *user_data); +void pcb_poly_to_polygons_on_layer(pcb_data_t *, pcb_layer_t *, rnd_polyarea_t *, pcb_flag_t); + +rnd_bool pcb_pline_is_rectangle(rnd_pline_t *pl); + +/* clear np1 from the polygon; also free np1 if fnp is true. Returns 1 on + success. */ +int pcb_poly_subtract(rnd_polyarea_t *np1, pcb_poly_t *p, rnd_bool fnp); + +/* Subtract or unsubtract obj from poly; Layer is used for looking up thermals */ +int pcb_poly_sub_obj(pcb_data_t *Data, pcb_layer_t *Layer, pcb_poly_t *Polygon, int type, void *obj); +int pcb_poly_unsub_obj(pcb_data_t *Data, pcb_layer_t *Layer, pcb_poly_t *Polygon, int type, void *obj); + + +/* Construct a polygon that represents the clearance around a text object + (assuming a polygon with no enforce clearance). This can be a round rect + (old method) or a complex polygon for tight_clearance */ +rnd_polyarea_t *pcb_poly_construct_text_clearance(pcb_text_t *text); + +#endif Index: tags/2.3.0/src/polygon_act.c =================================================================== --- tags/2.3.0/src/polygon_act.c (nonexistent) +++ tags/2.3.0/src/polygon_act.c (revision 33253) @@ -0,0 +1,134 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" + +#include + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "funchash_core.h" + +#include "polygon.h" +#include "draw.h" +#include "search.h" +#include "crosshair.h" +#include +#include + +#include "obj_poly.h" + +static const char pcb_acts_MorphPolygon[] = "pcb_poly_morph(Object|Selected)"; +static const char pcb_acth_MorphPolygon[] = "Converts dead polygon islands into separate polygons."; +/* DOC: morphpolygon.html */ +static fgw_error_t pcb_act_MorphPolygon(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + + RND_ACT_CONVARG(1, FGW_KEYWORD, MorphPolygon, op = fgw_keyword(&argv[1])); + + switch(op) { + case F_Object: + { + rnd_coord_t x, y; + int type; + void *ptr1, *ptr2, *ptr3; + + rnd_hid_get_coords("Select an Object", &x, &y, 0); + if ((type = pcb_search_screen(x, y, PCB_OBJ_POLY, &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) { + pcb_poly_morph((pcb_layer_t *) ptr1, (pcb_poly_t *) ptr3); + pcb_draw(); + pcb_undo_inc_serial(); + } + break; + } + case F_Selected: + case F_SelectedObjects: + PCB_POLY_ALL_LOOP(PCB->Data); + { + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, polygon)) + pcb_poly_morph(layer, polygon); + } + PCB_ENDALL_LOOP; + pcb_draw(); + pcb_undo_inc_serial(); + break; + } + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_Polygon[] = "Polygon(Close|CloseHole|PreviousPoint)"; +static const char pcb_acth_Polygon[] = "Some polygon related stuff."; +/* DOC: polygon.html */ +static fgw_error_t pcb_act_Polygon(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + + RND_ACT_CONVARG(1, FGW_KEYWORD, Polygon, op = fgw_keyword(&argv[1])); + + if ((argc > 1) && ((rnd_conf.editor.mode == pcb_crosshair.tool_poly) || (rnd_conf.editor.mode == pcb_crosshair.tool_poly_hole))) { + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + switch(op) { + /* close open polygon if possible */ + case F_Close: + pcb_polygon_close_poly(); + break; + + /* close open polygon hole if possible */ + case F_CloseHole: + pcb_polygon_close_hole(); + break; + + /* go back to the previous point */ + case F_PreviousPoint: + pcb_polygon_go_to_prev_point(); + break; + } + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + } + RND_ACT_IRES(0); + return 0; +} + + +static rnd_action_t polygon_action_list[] = { + {"MorphPolygon", pcb_act_MorphPolygon, pcb_acth_MorphPolygon, pcb_acts_MorphPolygon}, + {"Polygon", pcb_act_Polygon, pcb_acth_Polygon, pcb_acts_Polygon} +}; + +void pcb_poly_act_init2(void) +{ + RND_REGISTER_ACTIONS(polygon_action_list, NULL); +} Index: tags/2.3.0/src/rats_act.c =================================================================== --- tags/2.3.0/src/rats_act.c (nonexistent) +++ tags/2.3.0/src/rats_act.c (revision 33253) @@ -0,0 +1,217 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" +#include "conf_core.h" + +#include "board.h" +#include "data.h" +#include +#include "undo.h" +#include "find.h" +#include "remove.h" +#include "funchash_core.h" +#include "obj_rat.h" +#include +#include +#include "netlist.h" +#include "draw.h" + +#include "obj_rat_draw.h" + + +static const char pcb_acts_AddRats[] = "AddRats(AllRats|SelectedRats|Close, [manhattan])"; +static const char pcb_acth_AddRats[] = "Add one or more rat lines to the board."; +/* DOC: addrats.html */ +static fgw_error_t pcb_act_AddRats(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op, flgs = PCB_RATACC_PRECISE; + const char *opts = NULL; + pcb_rat_t *shorty; + float len, small; + + RND_ACT_CONVARG(1, FGW_KEYWORD, AddRats, op = fgw_keyword(&argv[1])); + + TODO("toporouter: autorotuer: remove this when the old autorouter is removed"); + /* temporary hack for the old autorouter */ + RND_ACT_MAY_CONVARG(2, FGW_STR, AddRats, opts = argv[2].val.str); + if ((opts != NULL) && (opts[0] == 'm')) + flgs = PCB_RATACC_ONLY_MANHATTAN; + + if (conf_core.temp.rat_warn) { + pcb_data_clear_flag(PCB->Data, PCB_FLAG_WARN, 1, 0); + pcb_draw(); + } + switch (op) { + case F_AllRats: + if (pcb_net_add_all_rats(PCB, flgs | PCB_RATACC_INFO) > 0) + pcb_board_set_changed_flag(PCB, rnd_true); + break; + case F_SelectedRats: + case F_Selected: + if (pcb_net_add_all_rats(PCB, flgs | PCB_RATACC_INFO | PCB_RATACC_ONLY_SELECTED) > 0) + pcb_board_set_changed_flag(PCB, rnd_true); + break; + case F_Close: + small = RND_SQUARE(RND_MAX_COORD); + shorty = NULL; + PCB_RAT_LOOP(PCB->Data); + { + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, line)) + continue; + len = RND_SQUARE(line->Point1.X - line->Point2.X) + RND_SQUARE(line->Point1.Y - line->Point2.Y); + if (len < small) { + small = len; + shorty = line; + } + } + PCB_END_LOOP; + if (shorty) { + pcb_undo_add_obj_to_flag(shorty); + PCB_FLAG_SET(PCB_FLAG_SELECTED, shorty); + pcb_rat_invalidate_draw(shorty); + pcb_draw(); + pcb_center_display(PCB, (shorty->Point2.X + shorty->Point1.X) / 2, (shorty->Point2.Y + shorty->Point1.Y) / 2); + } + break; + + default: + RND_ACT_FAIL(AddRats); + } + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_Connection[] = "Connection(Find|ResetLinesAndPolygons|ResetPinsAndVias|Reset)"; +static const char pcb_acth_Connection[] = "Searches connections of the object at the cursor position."; +/* DOC: connection.html */ +static fgw_error_t pcb_act_Connection(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + + RND_ACT_CONVARG(1, FGW_KEYWORD, Connection, op = fgw_keyword(&argv[1])); + + switch(op) { + case F_Find: + { + rnd_coord_t x, y; + unsigned long res; + pcb_find_t fctx; + rnd_hid_get_coords("Click on a connection", &x, &y, 0); + memset(&fctx, 0, sizeof(fctx)); + fctx.flag_set = PCB_FLAG_FOUND; + fctx.flag_chg_undoable = 1; + fctx.consider_rats = !!conf_core.editor.conn_find_rat; + res = pcb_find_from_xy(&fctx, PCB->Data, x, y); + rnd_message(RND_MSG_INFO, "found %ld objects\n", res); + pcb_find_free(&fctx); + break; + } + + case F_ResetLinesAndPolygons: + case F_ResetLayerObjects: + if (pcb_data_clear_obj_flag(PCB->Data, PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_TEXT, PCB_FLAG_FOUND, 1, 1) > 0) { + pcb_undo_inc_serial(); + pcb_draw(); + } + break; + + case F_ResetPinsViasAndPads: + case F_ResetPadstacks: + if (pcb_data_clear_obj_flag(PCB->Data, PCB_OBJ_PSTK, PCB_FLAG_FOUND, 1, 1) > 0) { + pcb_undo_inc_serial(); + pcb_draw(); + } + break; + + case F_Reset: + if (pcb_data_clear_flag(PCB->Data, PCB_FLAG_FOUND, 1, 1) > 0) { + pcb_undo_inc_serial(); + pcb_draw(); + } + break; + + default: + RND_ACT_FAIL(Connection); + } + + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_DeleteRats[] = "DeleteRats(AllRats|Selected|SelectedRats)"; +static const char pcb_acth_DeleteRats[] = "Delete rat lines."; +static fgw_error_t pcb_act_DeleteRats(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + + RND_ACT_CONVARG(1, FGW_KEYWORD, DeleteRats, op = fgw_keyword(&argv[1])); + + if (conf_core.temp.rat_warn) { + pcb_data_clear_flag(PCB->Data, PCB_FLAG_WARN, 1, 0); + pcb_draw(); + } + switch(op) { + case F_AllRats: + if (pcb_rats_destroy(rnd_false)) + pcb_board_set_changed_flag(PCB, rnd_true); + break; + case F_SelectedRats: + case F_Selected: + if (pcb_rats_destroy(rnd_true)) + pcb_board_set_changed_flag(PCB, rnd_true); + break; + + default: + RND_ACT_FAIL(DeleteRats); + } + + RND_ACT_IRES(0); + return 0; +} + + +static rnd_action_t rats_action_list[] = { + {"AddRats", pcb_act_AddRats, pcb_acth_AddRats, pcb_acts_AddRats}, + {"Connection", pcb_act_Connection, pcb_acth_Connection, pcb_acts_Connection}, + {"DeleteRats", pcb_act_DeleteRats, pcb_acth_DeleteRats, pcb_acts_DeleteRats} +}; + +void pcb_rats_act_init2(void) +{ + RND_REGISTER_ACTIONS(rats_action_list, NULL); +} + + Index: tags/2.3.0/src/rats_patch.c =================================================================== --- tags/2.3.0/src/rats_patch.c (nonexistent) +++ tags/2.3.0/src/rats_patch.c (revision 33253) @@ -0,0 +1,643 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2015..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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "rats_patch.h" +#include "genht/htsp.h" +#include "genht/hash.h" + +#include "config.h" + +#include + +#include +#include "data.h" +#include +#include "move.h" +#include +#include +#include "funchash_core.h" +#include "search.h" +#include "undo.h" +#include "conf_core.h" +#include "netlist.h" + +static void rats_patch_remove(pcb_board_t *pcb, pcb_ratspatch_line_t * n, int do_free); + +static const char core_ratspatch_cookie[] = "core-rats-patch"; + +const char *pcb_netlist_names[PCB_NUM_NETLISTS] = { + "input", + "edited" +}; + +/*** undoable ratspatch append */ + +typedef struct { + pcb_board_t *pcb; + pcb_rats_patch_op_t op; + char *id; + char *a1; + char *a2; + int used_by_attr; /* can not free */ +} undo_ratspatch_append_t; + +static void pcb_ratspatch_append_(pcb_board_t *pcb, pcb_rats_patch_op_t op, char *id, char *a1, char *a2) +{ + pcb_ratspatch_line_t *n; + + n = malloc(sizeof(pcb_ratspatch_line_t)); + + n->op = op; + n->id = id; + n->arg1.net_name = a1; + if (a2 != NULL) + n->arg2.attrib_val = a2; + else + n->arg2.attrib_val = NULL; + + /* link in */ + n->prev = pcb->NetlistPatchLast; + if (pcb->NetlistPatches != NULL) { + pcb->NetlistPatchLast->next = n; + pcb->NetlistPatchLast = n; + } + else + pcb->NetlistPatchLast = pcb->NetlistPatches = n; + n->next = NULL; +} + +static int undo_ratspatch_append_redo(void *udata) +{ + undo_ratspatch_append_t *a = udata; + pcb_ratspatch_append_(a->pcb, a->op, a->id, a->a1, a->a2); + a->used_by_attr = 1; + return 0; +} + +static int undo_ratspatch_append_undo(void *udata) +{ + undo_ratspatch_append_t *a = udata; + pcb_ratspatch_line_t *n; + + /* because undo and redo should be sequential, we only need to remove the last entry from the rats patch list */ + n = a->pcb->NetlistPatchLast; + assert(n->next == NULL); + + a->pcb->NetlistPatchLast = n->prev; + if (n->prev != NULL) + n->prev->next = NULL; + + if (a->pcb->NetlistPatches == n) + a->pcb->NetlistPatches = NULL; + + free(n); /* do not free the fields: they are shared with the undo slot, allocated at/for the undo slot */ + + a->used_by_attr = 0; + return 0; +} + +static void undo_ratspatch_append_print(void *udata, char *dst, size_t dst_len) +{ + undo_ratspatch_append_t *a = udata; + rnd_snprintf(dst, dst_len, "ratspatch_append: op=%d '%s' '%s' '%s' (used by attr: %d)", a->op, RND_EMPTY(a->id), RND_EMPTY(a->a1), RND_EMPTY(a->a2), a->used_by_attr); +} + +static void undo_ratspatch_append_free(void *udata) +{ + undo_ratspatch_append_t *a = udata; + if (!a->used_by_attr) { + free(a->id); + free(a->a1); + free(a->a2); + } + a->id = a->a1 = a->a2 = NULL; +} + +static const uundo_oper_t undo_ratspatch_append = { + core_ratspatch_cookie, + undo_ratspatch_append_free, + undo_ratspatch_append_undo, + undo_ratspatch_append_redo, + undo_ratspatch_append_print +}; + +void pcb_ratspatch_append(pcb_board_t *pcb, pcb_rats_patch_op_t op, const char *id, const char *a1, const char *a2, int undoable) +{ + undo_ratspatch_append_t *a; + char *nid = NULL, *na1 = NULL, *na2 = NULL; + + if (id != NULL) nid = rnd_strdup(id); + if (a1 != NULL) na1 = rnd_strdup(a1); + if (a2 != NULL) na2 = rnd_strdup(a2); + + if (undoable) { + a = pcb_undo_alloc(pcb, &undo_ratspatch_append, sizeof(undo_ratspatch_append_t)); + a->pcb = pcb; + a->op = op; + a->id = nid; + a->a1 = na1; + a->a2 = na2; + a->used_by_attr = 1; + } + + pcb_ratspatch_append_(pcb, op, nid, na1, na2); +} + +static void rats_patch_free_fields(pcb_ratspatch_line_t *n) +{ + if (n->id != NULL) + free(n->id); + if (n->arg1.net_name != NULL) + free(n->arg1.net_name); + if (n->arg2.attrib_val != NULL) + free(n->arg2.attrib_val); +} + +void pcb_ratspatch_destroy(pcb_board_t *pcb) +{ + pcb_ratspatch_line_t *n, *next; + + for(n = pcb->NetlistPatches; n != NULL; n = next) { + next = n->next; + rats_patch_free_fields(n); + free(n); + } +} + +void pcb_ratspatch_append_optimize(pcb_board_t *pcb, pcb_rats_patch_op_t op, const char *id, const char *a1, const char *a2) +{ + pcb_rats_patch_op_t seek_op; + pcb_ratspatch_line_t *n; + + switch (op) { + case RATP_ADD_CONN: + seek_op = RATP_DEL_CONN; + break; + case RATP_DEL_CONN: + seek_op = RATP_ADD_CONN; + break; + case RATP_CHANGE_ATTRIB: + seek_op = RATP_CHANGE_ATTRIB; + break; + } + + /* keep the list clean: remove the last operation that becomes obsolete by the new one */ + for (n = pcb->NetlistPatchLast; n != NULL; n = n->prev) { + if ((n->op == seek_op) && (strcmp(n->id, id) == 0)) { + switch (op) { + case RATP_CHANGE_ATTRIB: + if (strcmp(n->arg1.attrib_name, a1) != 0) + break; + rats_patch_remove(pcb, n, 1); + goto quit; + case RATP_ADD_CONN: + case RATP_DEL_CONN: + if (strcmp(n->arg1.net_name, a1) != 0) + break; + rats_patch_remove(pcb, n, 1); + goto quit; + } + } + } + +quit:; + pcb_ratspatch_append(pcb, op, id, a1, a2, 0); +} + +/* Unlink n from the list; if do_free is non-zero, also free fields and n */ +static void rats_patch_remove(pcb_board_t *pcb, pcb_ratspatch_line_t * n, int do_free) +{ + /* if we are the first or last... */ + if (n == pcb->NetlistPatches) + pcb->NetlistPatches = n->next; + if (n == pcb->NetlistPatchLast) + pcb->NetlistPatchLast = n->prev; + + /* extra ifs, just in case n is already unlinked */ + if (n->prev != NULL) + n->prev->next = n->next; + if (n->next != NULL) + n->next->prev = n->prev; + + if (do_free) { + rats_patch_free_fields(n); + free(n); + } +} + +static int rats_patch_apply_conn(pcb_board_t *pcb, pcb_ratspatch_line_t *patch, int del) +{ + pcb_net_t *net; + pcb_net_term_t *term; + char *sep, *termid; + int refdeslen; + + + sep = strchr(patch->id, '-'); + if (sep == NULL) + return 1; /* invalid id */ + termid = sep+1; + refdeslen = sep - patch->id; + if (refdeslen < 1) + return 1; /* invalid id */ + + net = pcb_net_get(pcb, &pcb->netlist[PCB_NETLIST_EDITED], patch->arg1.net_name, PCB_NETA_ALLOC); + for(term = pcb_termlist_first(&net->conns); term != NULL; term = pcb_termlist_next(term)) { + if ((strncmp(patch->id, term->refdes, refdeslen) == 0) && (strcmp(termid, term->term) == 0)) { + if (del) { + /* want to delete and it's on the list */ + pcb_net_term_del(net, term); + return 0; + } + /* want to add, and pin is on the list -> already added */ + return 1; + } + } + + /* If we got here, pin is not on the list */ + if (del) + return 1; + + /* Wanted to add, let's add it */ + *sep = '\0'; + term = pcb_net_term_get(net, patch->id, termid, PCB_NETA_ALLOC); + *sep = '-'; + if (term != NULL) + return 0; + return 1; +} + +static int rats_patch_apply_attrib(pcb_board_t *pcb, pcb_ratspatch_line_t *patch) +{ + pcb_net_t *net = pcb_net_get(pcb, &pcb->netlist[PCB_NETLIST_EDITED], patch->id, PCB_NETA_ALLOC); + if (net == NULL) + return 1; + if ((patch->arg2.attrib_val == NULL) || (*patch->arg2.attrib_val == '\0')) + pcb_attribute_remove(&net->Attributes, patch->arg1.attrib_name); + else + pcb_attribute_put(&net->Attributes, patch->arg1.attrib_name, patch->arg2.attrib_val); + return 0; +} + +int pcb_ratspatch_apply(pcb_board_t *pcb, pcb_ratspatch_line_t *patch) +{ + switch (patch->op) { + case RATP_ADD_CONN: + return rats_patch_apply_conn(pcb, patch, 0); + case RATP_DEL_CONN: + return rats_patch_apply_conn(pcb, patch, 1); + case RATP_CHANGE_ATTRIB: + return rats_patch_apply_attrib(pcb, patch); + } + return 0; +} + +void pcb_ratspatch_make_edited(pcb_board_t *pcb) +{ + pcb_ratspatch_line_t *n; + + pcb_netlist_uninit(&(pcb->netlist[PCB_NETLIST_EDITED])); + pcb_netlist_init(&(pcb->netlist[PCB_NETLIST_EDITED])); + pcb_netlist_copy(pcb, &(pcb->netlist[PCB_NETLIST_EDITED]), &(pcb->netlist[PCB_NETLIST_INPUT])); + + for (n = pcb->NetlistPatches; n != NULL; n = n->next) + pcb_ratspatch_apply(pcb, n); +} + +int pcb_rats_patch_export(pcb_board_t *pcb, pcb_ratspatch_line_t *pat, rnd_bool need_info_lines, void (*cb)(void *ctx, pcb_rats_patch_export_ev_t ev, const char *netn, const char *key, const char *val), void *ctx) +{ + pcb_ratspatch_line_t *n; + + if (need_info_lines) { + htsp_t *seen; + seen = htsp_alloc(strhash, strkeyeq); + + /* have to print net_info lines */ + for (n = pat; n != NULL; n = n->next) { + switch (n->op) { + case RATP_ADD_CONN: + case RATP_DEL_CONN: + if (htsp_get(seen, n->arg1.net_name) == NULL) { + { + /* document the original (input) state */ + pcb_net_t *net = pcb_net_get(pcb, &pcb->netlist[PCB_NETLIST_INPUT], n->arg1.net_name, 0); + if (net != NULL) { + pcb_net_term_t *term; + htsp_set(seen, n->arg1.net_name, net); + cb(ctx, PCB_RPE_INFO_BEGIN, n->arg1.net_name, NULL, NULL); + for(term = pcb_termlist_first(&net->conns); term != NULL; term = pcb_termlist_next(term)) { + char *tmp = rnd_concat(term->refdes, "-", term->term, NULL); + cb(ctx, PCB_RPE_INFO_TERMINAL, n->arg1.net_name, NULL, tmp); + free(tmp); + } + cb(ctx, PCB_RPE_INFO_END, n->arg1.net_name, NULL, NULL); + } + } + } + case RATP_CHANGE_ATTRIB: + break; + } + } + htsp_free(seen); + } + + /* action lines */ + for (n = pat; n != NULL; n = n->next) { + switch (n->op) { + case RATP_ADD_CONN: + cb(ctx, PCB_RPE_CONN_ADD, n->arg1.net_name, NULL, n->id); + break; + case RATP_DEL_CONN: + cb(ctx, PCB_RPE_CONN_DEL, n->arg1.net_name, NULL, n->id); + break; + case RATP_CHANGE_ATTRIB: + cb(ctx, PCB_RPE_ATTR_CHG, n->id, n->arg1.attrib_name, n->arg2.attrib_val); + break; + } + } + return 0; +} + +typedef struct { + FILE *f; + const char *q, *po, *pc, *line_prefix; +} fexport_t; + +static void fexport_cb(void *ctx_, pcb_rats_patch_export_ev_t ev, const char *netn, const char *key, const char *val) +{ + fexport_t *ctx = ctx_; + switch(ev) { + case PCB_RPE_INFO_BEGIN: fprintf(ctx->f, "%snet_info%s%s%s%s", ctx->line_prefix, ctx->po, ctx->q, netn, ctx->q); break; + case PCB_RPE_INFO_TERMINAL: fprintf(ctx->f, " %s%s%s", ctx->q, val, ctx->q); break; + case PCB_RPE_INFO_END: fprintf(ctx->f, "%s\n", ctx->pc); break; + case PCB_RPE_CONN_ADD: fprintf(ctx->f, "%sadd_conn%s%s%s%s %s%s%s%s\n", ctx->line_prefix, ctx->po, ctx->q, val, ctx->q, ctx->q, netn, ctx->q, ctx->pc); break; + case PCB_RPE_CONN_DEL: fprintf(ctx->f, "%sdel_conn%s%s%s%s %s%s%s%s\n", ctx->line_prefix, ctx->po, ctx->q, val, ctx->q, ctx->q, netn, ctx->q, ctx->pc); break; + case PCB_RPE_ATTR_CHG: + fprintf(ctx->f, "%schange_attrib%s%s%s%s %s%s%s %s%s%s%s\n", + ctx->line_prefix, ctx->po, + ctx->q, netn, ctx->q, + ctx->q, key, ctx->q, + ctx->q, val, ctx->q, + ctx->pc); + } +} + +int pcb_ratspatch_fexport(pcb_board_t *pcb, FILE *f, int fmt_pcb) +{ + fexport_t ctx; + if (fmt_pcb) { + ctx.q = "\""; + ctx.po = "("; + ctx.pc = ")"; + ctx.line_prefix = "\t"; + } + else { + ctx.q = ""; + ctx.po = " "; + ctx.pc = ""; + ctx.line_prefix = ""; + } + ctx.f = f; + return pcb_rats_patch_export(pcb, pcb->NetlistPatches, !fmt_pcb, fexport_cb, &ctx); +} + +static const char pcb_acts_ReplaceFootprint[] = "ReplaceFootprint([Selected|Object], [footprint], [dumb])\n"; +static const char pcb_acth_ReplaceFootprint[] = "Replace the footprint of the selected components with the footprint specified."; +/* DOC: replacefootprint.html */ + +static int act_replace_footprint_dst(int op, pcb_subc_t **olds) +{ + int found = 0; + + switch(op) { + case F_Selected: + /* check if we have elements selected and quit if not */ + PCB_SUBC_LOOP(PCB->Data); + { + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, subc) && (subc->refdes != NULL)) { + found = 1; + break; + } + } + PCB_END_LOOP; + + if (!(found)) { + rnd_message(RND_MSG_ERROR, "ReplaceFootprint(Selected) called with no selection\n"); + return 1; + } + break; + case F_Object: + { + void *ptr1, *ptr2, *ptr3; + pcb_objtype_t type = pcb_search_screen(pcb_crosshair.X, pcb_crosshair.Y, PCB_OBJ_SUBC, &ptr1, &ptr2, &ptr3); + if ((type != PCB_OBJ_SUBC) || (ptr1 == NULL)) { + rnd_message(RND_MSG_ERROR, "ReplaceFootprint(Object): no subc under cursor\n"); + return 1; + } + *olds = ptr1; + } + break; + + default: + rnd_message(RND_MSG_ERROR, "ReplaceFootprint(): invalid first argument\n"); + return 1; + } + return 0; +} + +static int act_replace_footprint_src(char *fpname, pcb_subc_t **news) +{ + int len, bidx; + const char *what, *what2; + + if (fpname == NULL) { + fpname = rnd_hid_prompt_for(&PCB->hidlib, "Footprint name to use for replacement:", "", "Footprint"); + if (fpname == NULL) { + rnd_message(RND_MSG_ERROR, "No footprint name supplied\n"); + return 1; + } + } + else + fpname = rnd_strdup(fpname); + + if (strcmp(fpname, "@buffer") != 0) { + /* check if the footprint is available */ + bidx = PCB_MAX_BUFFER-1; + pcb_buffer_load_footprint(&pcb_buffers[bidx], fpname, NULL); + what = "Footprint file "; + what2 = fpname; + } + else { + what = "Buffer"; + what2 = ""; + bidx = conf_core.editor.buffer_number; + } + + len = pcb_subclist_length(&pcb_buffers[bidx].Data->subc); + if (len == 0) { + rnd_message(RND_MSG_ERROR, "%s%s contains no subcircuits\n", what, what2); + return 1; + } + + if (len > 1) { + rnd_message(RND_MSG_ERROR, "%s%s contains multiple subcircuits\n", what, what2); + return 1; + } + *news = pcb_subclist_first(&pcb_buffers[bidx].Data->subc); + return 0; +} + + +static int act_replace_footprint(int op, pcb_subc_t *olds, pcb_subc_t *news, char *fpname, int dumb) +{ + int changed = 0; + pcb_subc_t *placed; + + pcb_undo_save_serial(); + switch(op) { + case F_Selected: + PCB_SUBC_LOOP(PCB->Data); + { + + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, subc) || (subc->refdes == NULL)) + continue; + placed = pcb_subc_replace(PCB, subc, news, rnd_true, dumb); + if (placed != NULL) { + if (!dumb) + pcb_ratspatch_append_optimize(PCB, RATP_CHANGE_ATTRIB, placed->refdes, "footprint", fpname); + changed = 1; + } + } + PCB_END_LOOP; + break; + case F_Object: + placed = pcb_subc_replace(PCB, olds, news, rnd_true, dumb); + if (placed != NULL) { + if (!dumb) + pcb_ratspatch_append_optimize(PCB, RATP_CHANGE_ATTRIB, placed->refdes, "footprint", fpname); + changed = 1; + } + break; + } + + + pcb_undo_restore_serial(); + if (changed) { + pcb_undo_inc_serial(); + rnd_gui->invalidate_all(rnd_gui); + } + return 0; +} + + + +static fgw_error_t pcb_act_ReplaceFootprint(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char *fpname = NULL, *dumbs = NULL; + pcb_subc_t *olds = NULL, *news; + int dumb = 0, op = F_Selected; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, ReplaceFootprint, op = fgw_keyword(&argv[1])); + + if (act_replace_footprint_dst(op, &olds) != 0) { + RND_ACT_IRES(1); + return 0; + } + + /* fetch the name of the new footprint */ + RND_ACT_MAY_CONVARG(2, FGW_STR, ReplaceFootprint, fpname = rnd_strdup(argv[2].val.str)); + if (act_replace_footprint_src(fpname, &news) != 0) { + RND_ACT_IRES(1); + return 0; + } + + RND_ACT_MAY_CONVARG(3, FGW_STR, ReplaceFootprint, dumbs = argv[3].val.str); + if ((dumbs != NULL) && (strcmp(dumbs, "dumb") == 0)) + dumb = 1; + + + RND_ACT_IRES(act_replace_footprint(op, olds, news, fpname, dumb)); + free(fpname); + return 0; +} + +static const char pcb_acts_SavePatch[] = "SavePatch(filename)"; +static const char pcb_acth_SavePatch[] = "Save netlist patch for back annotation."; +static fgw_error_t pcb_act_SavePatch(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fn = NULL; + FILE *f; + + RND_ACT_MAY_CONVARG(1, FGW_STR, SavePatch, fn = argv[1].val.str); + + if (fn == NULL) { + char *default_file; + + if (PCB->hidlib.filename != NULL) { + char *end; + int len; + len = strlen(PCB->hidlib.filename); + default_file = malloc(len + 8); + memcpy(default_file, PCB->hidlib.filename, len + 1); + end = strrchr(default_file, '.'); + if ((end == NULL) || (rnd_strcasecmp(end, ".pcb") != 0)) + end = default_file + len; + strcpy(end, ".bap"); + } + else + default_file = rnd_strdup("unnamed.bap"); + + fn = rnd_gui->fileselect(rnd_gui, "Save netlist patch as ...", + "Choose a file to save netlist patch to\n" + "for back annotation\n", default_file, ".bap", NULL, "patch", 0, NULL); + + free(default_file); + } + + f = rnd_fopen(&PCB->hidlib, fn, "w"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can't open netlist patch file %s for writing\n", fn); + RND_ACT_IRES(-1); + return 0; + } + pcb_ratspatch_fexport(PCB, f, 0); + fclose(f); + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t rats_patch_action_list[] = { + {"ReplaceFootprint", pcb_act_ReplaceFootprint, pcb_acth_ReplaceFootprint, pcb_acts_ReplaceFootprint}, + {"SavePatch", pcb_act_SavePatch, pcb_acth_SavePatch, pcb_acts_SavePatch} +}; + +void pcb_rats_patch_init2(void) +{ + RND_REGISTER_ACTIONS(rats_patch_action_list, NULL); +} + + Index: tags/2.3.0/src/rats_patch.h =================================================================== --- tags/2.3.0/src/rats_patch.h (nonexistent) +++ tags/2.3.0/src/rats_patch.h (revision 33253) @@ -0,0 +1,98 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2013..2015 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_RATS_PATCH_H +#define PCB_RATS_PATCH_H + +#include +#include "board.h" + +typedef enum { + RATP_ADD_CONN, + RATP_DEL_CONN, + RATP_CHANGE_ATTRIB +} pcb_rats_patch_op_t; + +struct pcb_ratspatch_line_s { + pcb_rats_patch_op_t op; + char *id; + union { + char *net_name; + char *attrib_name; + } arg1; + union { + char *attrib_val; + } arg2; + + pcb_ratspatch_line_t *prev, *next; +}; + + + +/* Single-word netlist class names */ +extern const char *pcb_netlist_names[PCB_NUM_NETLISTS]; + +/* Allocate and append a patch line to the patch list */ +void pcb_ratspatch_append(pcb_board_t *pcb, pcb_rats_patch_op_t op, const char *id, const char *a1, const char *a2, int undoable); + +/* Free the patch list and all memory claimed by patch list items */ +void pcb_ratspatch_destroy(pcb_board_t *pcb); + +/* Same as pcb_ratspatch_append() but also optimize previous entries so that + redundant entries are removed */ +void pcb_ratspatch_append_optimize(pcb_board_t *pcb, pcb_rats_patch_op_t op, const char *id, const char *a1, const char *a2); + +/* Create [PCB_NETLIST_EDITED] from [PCB_NETLIST_INPUT] applying the patch */ +void pcb_ratspatch_make_edited(pcb_board_t *pcb); + +/* apply a single patch record on [PCB_NETLIST_EDITED]; returns non-zero on failure */ +int pcb_ratspatch_apply(pcb_board_t *pcb, pcb_ratspatch_line_t * patch); + +/**** exporter ****/ + +/* Special text exporter: + save all patch lines as an ordered list of text lines + if fmt is non-zero, generate pcb savefile compatible lines, else generate a back annotation patch */ +int pcb_ratspatch_fexport(pcb_board_t *pcb, FILE * f, int fmt_pcb); + +/* Generic, callback based exporter: */ + + /* EVENT ARGUMENTS */ +typedef enum { /* netn is always the net name, unless specified otherwise */ + PCB_RPE_INFO_BEGIN, /* netn */ + PCB_RPE_INFO_TERMINAL, /* netn; val is the terminal pin/pad name */ + PCB_RPE_INFO_END, /* netn */ + + PCB_RPE_CONN_ADD, /* netn; val is the terminal pin/pad name */ + PCB_RPE_CONN_DEL, /* netn; val is the terminal pin/pad name */ + PCB_RPE_ATTR_CHG /* netn; key is the attribute name, val is the new attribute value */ +} pcb_rats_patch_export_ev_t; + +/* Call cb() for each item to output; PCB_PTRE_INFO* is calculated/called only + if need_info_lines is true; the pcb pointer is used for looking up connections */ +int pcb_rats_patch_export(pcb_board_t *pcb, pcb_ratspatch_line_t *pat, rnd_bool need_info_lines, void (*cb)(void *ctx, pcb_rats_patch_export_ev_t ev, const char *netn, const char *key, const char *val), void *ctx); + +#endif Index: tags/2.3.0/src/remove.c =================================================================== --- tags/2.3.0/src/remove.c (nonexistent) +++ tags/2.3.0/src/remove.c (revision 33253) @@ -0,0 +1,136 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include "config.h" +#include "conf_core.h" + +#include "board.h" +#include "draw.h" +#include "extobj.h" +#include "remove.h" +#include "select.h" +#include "undo.h" +#include "obj_arc_op.h" +#include "obj_line_op.h" +#include "obj_poly_op.h" +#include "obj_text_op.h" +#include "obj_rat_op.h" +#include "obj_subc_op.h" +#include "obj_pstk_op.h" +#include "obj_gfx_op.h" + +static int remove_pre(pcb_opctx_t *ctx, pcb_any_obj_t *obj, void *ptr3); + +pcb_opfunc_t pcb_RemoveFunctions = { + remove_pre, + NULL, /* common_post */ + pcb_lineop_remove, + pcb_textop_remove, + pcb_polyop_remove, + pcb_lineop_remove_point, + pcb_polyop_remove_point, + pcb_arcop_remove, + pcb_gfxop_remove, + pcb_ratop_remove, + pcb_arcop_remove_point, + pcb_subcop_remove, + pcb_pstkop_remove, + 0 /* extobj_inhibit_regen */ +}; + +static pcb_opfunc_t DestroyFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_destroy, + pcb_textop_destroy, + pcb_polyop_destroy, + NULL, + pcb_polyop_destroy_point, + pcb_arcop_destroy, + pcb_gfxop_destroy, + pcb_ratop_destroy, + NULL, + pcb_subcop_destroy, + pcb_pstkop_destroy, + 0 /* extobj_inhibit_regen */ +}; + +static int remove_pre(pcb_opctx_t *ctx, pcb_any_obj_t *obj, void *ptr3) +{ + /* when an edit-object is removed, the corresponding subc obj needs to be removed */ + return pcb_extobj_del_floater(obj); +} + + +/* ---------------------------------------------------------------------- + * removes all selected and visible objects + * returns rnd_true if any objects have been removed + */ +rnd_bool pcb_remove_selected(pcb_op_mode_t mode) +{ + pcb_opctx_t ctx; + + ctx.remove.pcb = PCB; + ctx.remove.destroy_target = NULL; + + if (pcb_selected_operation(PCB, PCB->Data, &pcb_RemoveFunctions, &ctx, rnd_false, PCB_OBJ_ANY & (~PCB_OBJ_SUBC_PART), mode)) { + pcb_undo_inc_serial(); + pcb_draw(); + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * remove object as referred by pointers and type, + * allocated memory is passed to the 'remove undo' list + */ +void *pcb_remove_object(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + pcb_opctx_t ctx; + void *ptr; + + ctx.remove.pcb = PCB; + ctx.remove.destroy_target = NULL; + + ptr = pcb_object_operation(&pcb_RemoveFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); + pcb_draw(); + return ptr; +} + +void *pcb_destroy_object(pcb_data_t *Target, pcb_objtype_t Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + void *res; + pcb_opctx_t ctx; + + ctx.remove.pcb = PCB; + ctx.remove.destroy_target = Target; + + res = pcb_object_operation(&DestroyFunctions, &ctx, Type, Ptr1, Ptr2, Ptr3); + pcb_draw(); + return res; +} Index: tags/2.3.0/src/remove.h =================================================================== --- tags/2.3.0/src/remove.h (nonexistent) +++ tags/2.3.0/src/remove.h (revision 33253) @@ -0,0 +1,50 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Remove objects from the board */ + +#ifndef PCB_REMOVE_H +#define PCB_REMOVE_H + +#include "config.h" +#include "operation.h" + +#define PCB_REMOVE_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_LINE_POINT | PCB_OBJ_LINE | PCB_OBJ_TEXT | PCB_OBJ_SUBC | \ + PCB_OBJ_POLY_POINT | PCB_OBJ_POLY | PCB_OBJ_RAT | PCB_OBJ_ARC | PCB_OBJ_GFX \ + | PCB_OBJ_ARC_POINT) + +rnd_bool pcb_remove_selected(pcb_op_mode_t mode); + +/* Undoable delete (operation wrapper) */ +void *pcb_remove_object(int Type, void *Ptr1, void *Ptr2, void *Ptr3); + +/* Non-undoable delete (operation wrapper) */ +void *pcb_destroy_object(pcb_data_t *Target, pcb_objtype_t Type, void *Ptr1, void *Ptr2, void *Ptr3); + +#endif Index: tags/2.3.0/src/remove_act.c =================================================================== --- tags/2.3.0/src/remove_act.c (nonexistent) +++ tags/2.3.0/src/remove_act.c (revision 33253) @@ -0,0 +1,123 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" +#include "data.h" +#include +#include +#include "remove.h" +#include "board.h" +#include "funchash_core.h" + +#define PCB (do_not_use_PCB) + +static const char pcb_acts_Delete[] = + "Delete(Object [,idpath])\n" + "Delete(Selected)\n" + "Delete(AllRats|SelectedRats)"; +static const char pcb_acth_Delete[] = "Delete stuff."; +static fgw_error_t pcb_act_Delete(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int id; + + RND_ACT_CONVARG(1, FGW_KEYWORD, Delete, id = fgw_keyword(&argv[1])); + + if (id == -1) { /* no arg */ + if (pcb_remove_selected(0) == rnd_false) + id = F_Object; + } + + switch(id) { + case F_Object: + if (argc > 2) { /* delete by idpath */ + pcb_idpath_t *idp; + pcb_any_obj_t *obj; + RND_ACT_CONVARG(2, FGW_IDPATH, Delete, idp = fgw_idpath(&argv[2])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + obj = pcb_idpath2obj(pcb, idp); + if ((obj == NULL) || ((obj->type & PCB_OBJ_CLASS_REAL) == 0)) { + RND_ACT_IRES(-1); + return 0; + } + pcb_remove_object(obj->type, obj->parent.any, obj, obj); + } + else { /* interactive remove */ + rnd_hidlib_t *hidlib = RND_ACT_HIDLIB; + rnd_hid_get_coords("Click on object to delete", &hidlib->tool_x, &hidlib->tool_y, 0); + rnd_tool_save(RND_ACT_HIDLIB); + rnd_tool_select_by_name(RND_ACT_HIDLIB, "remove"); + rnd_tool_do_press(RND_ACT_HIDLIB); + rnd_tool_restore(RND_ACT_HIDLIB); + } + break; + case F_Selected: + pcb_remove_selected(0); + break; + case F_AllRats: + if (pcb_rats_destroy(rnd_false)) + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + break; + case F_SelectedRats: + if (pcb_rats_destroy(rnd_true)) + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + break; + } + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_RemoveSelected[] = "pcb_remove_selected()"; +static const char pcb_acth_RemoveSelected[] = "Removes any selected objects."; +static fgw_error_t pcb_act_RemoveSelected(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + if (pcb_remove_selected(0)) + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + RND_ACT_IRES(0); + return 0; +} + + +static rnd_action_t remove_action_list[] = { + {"Delete", pcb_act_Delete, pcb_acth_Delete, pcb_acts_Delete}, + {"PcbDelete", pcb_act_Delete, NULL, "Alias to Delete()"}, + {"RemoveSelected", pcb_act_RemoveSelected, pcb_acth_RemoveSelected, pcb_acts_RemoveSelected} +}; + +void pcb_remove_act_init2(void) +{ + RND_REGISTER_ACTIONS(remove_action_list, NULL); +} Index: tags/2.3.0/src/rotate.c =================================================================== --- tags/2.3.0/src/rotate.c (nonexistent) +++ tags/2.3.0/src/rotate.c (revision 33253) @@ -0,0 +1,189 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include "config.h" + +#include + +#include "board.h" +#include "data.h" +#include "draw.h" +#include +#include "polygon.h" +#include "rotate.h" +#include "search.h" +#include "select.h" +#include "undo.h" +#include "event.h" +#include "data.h" +#include "conf_core.h" +#include "obj_arc_op.h" +#include "obj_line_op.h" +#include "obj_poly_op.h" +#include "obj_text_op.h" +#include "obj_subc_op.h" +#include "obj_pstk_op.h" +#include "obj_gfx_op.h" + +#include "obj_line_draw.h" +#include "obj_rat_draw.h" + +pcb_opfunc_t Rotate90Functions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_rotate90, + pcb_textop_rotate90, + pcb_polyop_rotate90, + pcb_lineop_rotate90_point, + NULL, + pcb_arcop_rotate90, + pcb_gfxop_rotate90, + NULL, + NULL, + pcb_subcop_rotate90, + pcb_pstkop_rotate90, + 0 /* extobj_inhibit_regen */ +}; + +pcb_opfunc_t RotateFunctions = { + NULL, /* common_pre */ + NULL, /* common_post */ + pcb_lineop_rotate, + pcb_textop_rotate, + pcb_polyop_rotate, + NULL, + NULL, + pcb_arcop_rotate, + pcb_gfxop_rotate, + NULL, + NULL, + pcb_subcop_rotate, + pcb_pstkop_rotate, + 0 /* extobj_inhibit_regen */ +}; + +/* --------------------------------------------------------------------------- + * rotates a point in 90 degree steps + */ +void pcb_point_rotate90(rnd_point_t *Point, rnd_coord_t X, rnd_coord_t Y, unsigned Number) +{ + RND_COORD_ROTATE90(Point->X, Point->Y, X, Y, Number); +} + +pcb_any_obj_t *pcb_obj_rotate90(pcb_board_t *pcb, pcb_any_obj_t *obj, rnd_coord_t X, rnd_coord_t Y, unsigned Steps) +{ + int changed = 0; + pcb_opctx_t ctx; + + pcb_data_clip_inhibit_inc(pcb->Data); + + /* setup default global identifiers */ + ctx.rotate.pcb = pcb; + ctx.rotate.number = Steps; + ctx.rotate.center_x = X; + ctx.rotate.center_y = Y; + + rnd_event(&pcb->hidlib, PCB_EVENT_RUBBER_ROTATE90, "ipppccip", obj->type, obj->parent.any, obj, obj, ctx.rotate.center_x, ctx.rotate.center_y, ctx.rotate.number, &changed); + + if (obj->type != PCB_OBJ_PSTK) /* padstack has its own way doing the rotation-undo */ + pcb_undo_add_obj_to_rotate90(obj->type, obj->parent.any, obj, obj, ctx.rotate.center_x, ctx.rotate.center_y, ctx.rotate.number); + obj = pcb_object_operation(&Rotate90Functions, &ctx, obj->type, obj->parent.any, obj, obj); + changed |= (obj != NULL); + if (changed) { + pcb_draw(); + pcb_undo_inc_serial(); + } + pcb_data_clip_inhibit_dec(pcb->Data, 0); + return obj; +} + +pcb_any_obj_t *pcb_obj_rotate(pcb_board_t *pcb, pcb_any_obj_t *obj, rnd_coord_t X, rnd_coord_t Y, rnd_angle_t angle) +{ + int changed = 0; + pcb_opctx_t ctx; + + pcb_data_clip_inhibit_inc(pcb->Data); + + /* setup default global identifiers */ + ctx.rotate.pcb = pcb; + ctx.rotate.angle = angle; + ctx.rotate.center_x = X; + ctx.rotate.center_y = Y; + + rnd_event(&pcb->hidlib, PCB_EVENT_RUBBER_ROTATE, "ipppccip", obj->type, obj->parent.any, obj, obj, ctx.rotate.center_x, ctx.rotate.center_y, ctx.rotate.angle, &changed); + + if (obj->type != PCB_OBJ_PSTK) /* padstack has its own way doing the rotation-undo */ + pcb_undo_add_obj_to_rotate(obj->type, obj->parent.any, obj, obj, ctx.rotate.center_x, ctx.rotate.center_y, ctx.rotate.angle); + obj = pcb_object_operation(&RotateFunctions, &ctx, obj->type, obj->parent.any, obj, obj); + changed |= (obj != NULL); + if (changed) { + pcb_draw(); + pcb_undo_inc_serial(); + } + pcb_data_clip_inhibit_dec(pcb->Data, 0); + return obj; +} + +void pcb_screen_obj_rotate90(pcb_board_t *pcb, rnd_coord_t X, rnd_coord_t Y, unsigned Steps) +{ + int type; + void *ptr1, *ptr2, *ptr3; + if ((type = pcb_search_screen(X, Y, PCB_ROTATE_TYPES | PCB_LOOSE_SUBC(PCB), &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) { + pcb_any_obj_t *obj = (pcb_any_obj_t *)ptr2; + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, obj)) { + rnd_message(RND_MSG_WARNING, "Sorry, %s object is locked\n", pcb_obj_type_name(obj->type)); + return; + } + rnd_event(&pcb->hidlib, PCB_EVENT_RUBBER_RESET, NULL); + if (conf_core.editor.rubber_band_mode) + rnd_event(&pcb->hidlib, PCB_EVENT_RUBBER_LOOKUP_LINES, "ippp", type, ptr1, ptr2, ptr3); + if (type == PCB_OBJ_SUBC) + rnd_event(&pcb->hidlib, PCB_EVENT_RUBBER_LOOKUP_RATS, "ippp", type, ptr1, ptr2, ptr3); + pcb_obj_rotate90(pcb, obj, X, Y, Steps); + pcb_board_set_changed_flag(pcb, rnd_true); + } +} + +void pcb_screen_obj_rotate(pcb_board_t *pcb, rnd_coord_t X, rnd_coord_t Y, rnd_angle_t angle) +{ + int type; + void *ptr1, *ptr2, *ptr3; + if ((type = pcb_search_screen(X, Y, PCB_ROTATE_TYPES | PCB_LOOSE_SUBC(PCB), &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) { + pcb_any_obj_t *obj = (pcb_any_obj_t *)ptr2; + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, obj)) { + rnd_message(RND_MSG_WARNING, "Sorry, %s object is locked\n", pcb_obj_type_name(obj->type)); + return; + } + rnd_event(&pcb->hidlib, PCB_EVENT_RUBBER_RESET, NULL); + if (conf_core.editor.rubber_band_mode) + rnd_event(&pcb->hidlib, PCB_EVENT_RUBBER_LOOKUP_LINES, "ippp", type, ptr1, ptr2, ptr3); + if (type == PCB_OBJ_SUBC) + rnd_event(&pcb->hidlib, PCB_EVENT_RUBBER_LOOKUP_RATS, "ippp", type, ptr1, ptr2, ptr3); + pcb_obj_rotate(PCB, obj, X, Y, angle); + pcb_board_set_changed_flag(PCB, rnd_true); + } +} Index: tags/2.3.0/src/rotate.h =================================================================== --- tags/2.3.0/src/rotate.h (nonexistent) +++ tags/2.3.0/src/rotate.h (revision 33253) @@ -0,0 +1,48 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_ROTATE_H +#define PCB_ROTATE_H + +#include "global_typedefs.h" +#include + +#define PCB_ROTATE_TYPES (PCB_OBJ_PSTK | PCB_OBJ_SUBC | PCB_OBJ_TEXT | PCB_OBJ_ARC | PCB_OBJ_LINE_POINT | PCB_OBJ_LINE | PCB_OBJ_POLY | PCB_OBJ_GFX | PCB_OBJ_FLOATER) + +/* rotates an object passed; pcb is the parent board or associated board (in + case of buffer) */ +pcb_any_obj_t *pcb_obj_rotate90(pcb_board_t *pcb, pcb_any_obj_t *obj, rnd_coord_t X, rnd_coord_t Y, unsigned Steps); + +/* rotates obj by angle around X;Y. pcb is the current board if obj is on buffer */ +pcb_any_obj_t *pcb_obj_rotate(pcb_board_t *pcb, pcb_any_obj_t *obj, rnd_coord_t X, rnd_coord_t Y, rnd_angle_t angle); + +void pcb_screen_obj_rotate90(pcb_board_t *pcb, rnd_coord_t X, rnd_coord_t Y, unsigned steps); +void pcb_screen_obj_rotate(pcb_board_t *pcb, rnd_coord_t X, rnd_coord_t Y, rnd_angle_t angle); +void pcb_point_rotate90(rnd_point_t *Point, rnd_coord_t X, rnd_coord_t Y, unsigned Number); + +#endif Index: tags/2.3.0/src/route.c =================================================================== --- tags/2.3.0/src/route.c (nonexistent) +++ tags/2.3.0/src/route.c (revision 33253) @@ -0,0 +1,781 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2004 Thomas Nau + * Copyright (C) 2017 Adrian Purser + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include "config.h" + +#include +#include "conf_core.h" +#include +#include +#include "board.h" +#include "data.h" +#include "extobj.h" +#include "find.h" +#include "polygon.h" +#include +#include "route.h" +#include "undo.h" +#include "obj_line_draw.h" +#include "obj_arc_draw.h" +#include "route_draw.h" +#include "obj_line.h" +#include "obj_line_op.h" +#include "obj_subc_parent.h" +#include "draw_wireframe.h" + +void pcb_route_init(pcb_route_t *p_route) +{ + p_route->size = 0; + p_route->capacity = ROUTE_SMALL_DATA_SIZE; + p_route->objects = &p_route->small_data[0]; +} + +void pcb_route_destroy(pcb_route_t *p_route) +{ + if (p_route->capacity > ROUTE_SMALL_DATA_SIZE) + free(p_route->objects); + p_route->size = 0; + p_route->capacity = ROUTE_SMALL_DATA_SIZE; + p_route->objects = &p_route->small_data[0]; +} + +void pcb_route_reset(pcb_route_t *p_route) +{ + /* NOTE: Currently this function just sets the size back to zero. It does not + free any memory used so the capacity will stay the same. + */ + + p_route->size = 0; +} + +void pcb_route_reserve(pcb_route_t *p_route, int size) +{ + int grow; + + if (size <= p_route->capacity) + return; + + grow = size - p_route->capacity; + if (grow < 8) + grow = 8; + + if (p_route->capacity == ROUTE_SMALL_DATA_SIZE) { + p_route->capacity += grow; + p_route->objects = (pcb_route_object_t *) malloc(p_route->capacity * sizeof(pcb_route_object_t)); + memcpy(p_route->objects, &p_route->small_data[0], p_route->size * sizeof(pcb_route_object_t)); + } + else { + p_route->capacity += grow; + p_route->objects = (pcb_route_object_t *) realloc(p_route->objects, p_route->capacity * sizeof(pcb_route_object_t)); + } +} + +void pcb_route_resize(pcb_route_t *p_route, int size) +{ + pcb_route_reserve(p_route, size); + p_route->size = size; +} + +pcb_route_object_t *pcb_route_alloc_object(pcb_route_t *p_route) +{ + pcb_route_resize(p_route, p_route->size + 1); + return &p_route->objects[p_route->size - 1]; +} + +void pcb_route_add_line(pcb_route_t *p_route, rnd_point_t *point1, rnd_point_t *point2, rnd_layer_id_t layer) +{ + pcb_route_object_t *p_object = pcb_route_alloc_object(p_route); + if (p_object == NULL) + return; + + p_object->point1 = *point1; + p_object->point2 = *point2; + p_object->layer = layer; + p_object->type = PCB_OBJ_LINE; + p_route->end_point = *point2; +} + +void pcb_route_add_arc(pcb_route_t *p_route, rnd_point_t *center, rnd_angle_t start_angle, rnd_angle_t delta, rnd_coord_t radius, rnd_layer_id_t layer) +{ + pcb_route_object_t *p_object = pcb_route_alloc_object(p_route); + if (p_object == NULL) + return; + + p_object->point1 = *center; + p_object->start_angle = start_angle; + p_object->delta_angle = delta; + p_object->radius = radius; + p_object->layer = layer; + p_object->type = PCB_OBJ_ARC; + + p_route->end_point.X = rnd_round((double)center->X - ((double)radius * cos((start_angle + delta) * RND_M180))); + p_route->end_point.Y = rnd_round((double)center->Y + ((double)radius * sin((start_angle + delta) * RND_M180))); +} + + +void pcb_route_direct(pcb_board_t *PCB, pcb_route_t *route, rnd_point_t *point1, rnd_point_t *point2, rnd_layer_id_t layer, rnd_coord_t thickness, rnd_coord_t clearance, pcb_flag_t flags) +{ + pcb_route_reset(route); + route->start_point = *point1; + route->end_point = *point2; + route->start_layer = layer; + route->end_layer = layer; + route->thickness = thickness; + route->clearance = clearance; + route->PCB = PCB; + route->flags = flags; + pcb_route_add_line(route, point1, point2, layer); +} + +/*----------------------------------------------------------- + * Calculate an arc fitted to a corner. + *---------------------------------------------------------*/ + +void pcb_route_calculate_corner_arc(const rnd_point_t *point1, const rnd_point_t *point2, const rnd_point_t *point3, double radius, pcb_route_object_t *p_out_obj, rnd_point_t *p_endpoint1, rnd_point_t *p_endpoint2) +{ + const double r_min = 10.0; + + const rnd_coord_t dx1 = point1->X - point2->X; + const rnd_coord_t dy1 = point1->Y - point2->Y; + const rnd_coord_t dx2 = point3->X - point2->X; + const rnd_coord_t dy2 = point3->Y - point2->Y; + + const double angle1 = atan2(dy1, dx1); + const double angle2 = atan2(dy2, dx2); + + const double ad = angle2 - angle1; + const double d = ad > M_PI ? ad - (M_PI * 2.0) : (ad < -M_PI ? ad + (M_PI * 2.0) : ad); + + const double hangle = fabs(d * 0.5); + const double angle3 = angle1 + (d * 0.5); + + /* Vector from point2 to the other points */ + const double vx1 = cos(angle1); + const double vy1 = sin(angle1); + const double vx2 = cos(angle2); + const double vy2 = sin(angle2); + + /* Distance from point2 to the other points */ + const double l1 = fabs(fabs(vx1) > fabs(vy1) ? dx1 / vx1 : dy1 / vy1); + const double l2 = fabs(fabs(vx2) > fabs(vy2) ? dx2 / vx2 : dy2 / vy2); + + /* Calculate maximum possible radius */ + const double rmax = (l1 < l2 ? l1 : l2) * tan(hangle); + const double r = rmax < radius ? rmax : radius; + + if (r >= r_min) { + /* Calculate arc center coordinates. */ + const double sh = sin(hangle); + const rnd_coord_t xc = point2->X + (rnd_coord_t) ((cos(angle3) * r) / sh); + const rnd_coord_t yc = point2->Y + (rnd_coord_t) ((sin(angle3) * r) / sh); + + /* Calculate arc start and delta angles. */ + const double delta = d < 0 ? -(M_PI + d) : M_PI - d; + const double start = (d < 0.0 ? (M_PI * 0.5) - angle1 : ((M_PI * 0.5) - angle2) - delta); + + p_out_obj->point1.X = xc; + p_out_obj->point1.Y = yc; + p_out_obj->start_angle = start * RND_RAD_TO_DEG; /* Start Angle */ + p_out_obj->delta_angle = delta * RND_RAD_TO_DEG; /* Delta Angle */ + p_out_obj->radius = r; + + if (p_endpoint1) { + p_endpoint1->X = xc - (rnd_coord_t) (r * cos(start)); + p_endpoint1->Y = yc + (rnd_coord_t) (r * sin(start)); + } + + if (p_endpoint1) { + p_endpoint2->X = xc - (rnd_coord_t) (r * cos(start + delta)); + p_endpoint2->Y = yc + (rnd_coord_t) (r * sin(start + delta)); + } + } + else { + if (p_endpoint1) + *p_endpoint1 = *point2; + + if (p_endpoint2) + *p_endpoint2 = *point2; + } +} + +void pcb_route_calculate_45(rnd_point_t *start_point, rnd_point_t *target_point) +{ + + rnd_coord_t dx, dy, min; + unsigned direction = 0; + double m; + + /* first calculate direction of line */ + dx = target_point->X - start_point->X; + dy = target_point->Y - start_point->Y; + + if (!dx) { + if (!dy) + /* zero length line, don't draw anything */ + return; + else + direction = dy > 0 ? 0 : 4; + } + else { + m = (double)dy / dx; + direction = 2; + if (m > RND_TAN_30_DEGREE) + direction = m > RND_TAN_60_DEGREE ? 0 : 1; + else if (m < -RND_TAN_30_DEGREE) + direction = m < -RND_TAN_60_DEGREE ? 0 : 3; + } + + if (dx < 0) + direction += 4; + + dx = coord_abs(dx); + dy = coord_abs(dy); + min = MIN(dx, dy); + + /* now set up the second pair of coordinates */ + switch (direction) { + case 0: + case 4: + target_point->X = start_point->X; + break; + + case 2: + case 6: + target_point->Y = start_point->Y; + break; + + case 1: + target_point->X = start_point->X + min; + target_point->Y = start_point->Y + min; + break; + + case 3: + target_point->X = start_point->X + min; + target_point->Y = start_point->Y - min; + break; + + case 5: + target_point->X = start_point->X - min; + target_point->Y = start_point->Y - min; + break; + + case 7: + target_point->X = start_point->X - min; + target_point->Y = start_point->Y + min; + break; + } +} + +void pcb_route_start(pcb_board_t *PCB, pcb_route_t *route, rnd_point_t *point, rnd_layer_id_t layer_id, rnd_coord_t thickness, rnd_coord_t clearance, pcb_flag_t flags) +{ + /* Restart the route */ + pcb_route_reset(route); + route->start_point = *point; + route->end_point = *point; + route->thickness = thickness; + route->clearance = clearance; + route->start_layer = layer_id; + route->end_layer = layer_id; + route->PCB = PCB; + route->flags = flags; +} + +void pcb_route_calculate_to(pcb_route_t *route, rnd_point_t *point, int mod1, int mod2) +{ + TODO("If an external route calculator has been selected then use it instead of this default one.") + TODO("Add DRC Checking") + + rnd_point_t *point1 = &route->end_point; + rnd_point_t *point2 = point; + rnd_layer_id_t layer_id = route->end_layer; + + /* Set radius to 0 for standard 45/90 operation */ + const rnd_coord_t radius = route->thickness * conf_core.editor.route_radius; + + /* If the start point is the same as the end point then add a single 0-length line. + * If a 0-length line is not added then some operations such as moving a line point + * could cause the line to disappear. + */ + if ((point1->X == point2->X) && (point1->Y == point2->Y)) { + route->end_point = *point2; + pcb_route_add_line(route, point1, point2, layer_id); + } + /* If Refraction is 0 then add a single line segment that is horizontal, vertical or 45 degrees. + * This line segment might not end under the crosshair. + */ + else if (conf_core.editor.line_refraction == 0) { + rnd_point_t target = *point2; + pcb_route_calculate_45(point1, &target); + pcb_route_add_line(route, point1, &target, layer_id); + route->end_point = target; + } + else { + /* Refraction is non-zero so add multiple lines (horizontal, vertical and/or 45 degrees). */ + rnd_coord_t dx, dy; + rnd_point_t target; + rnd_bool way = (conf_core.editor.line_refraction == 1 ? rnd_false : rnd_true); + + /* swap the 'way' if mod1 is set (typically the shift key) */ + if (mod1) + way = !way; + + dx = point2->X - point1->X; + dy = point2->Y - point1->Y; + + if (!way) { + if (coord_abs(dx) > coord_abs(dy)) { + target.X = point2->X - SGN(dx) * coord_abs(dy); + target.Y = point1->Y; + } + else { + target.X = point1->X; + target.Y = point2->Y - SGN(dy) * coord_abs(dx); + } + } + else { + if (coord_abs(dx) > coord_abs(dy)) { + target.X = point1->X + SGN(dx) * coord_abs(dy); + target.Y = point2->Y; + } + else { + target.X = point2->X; + target.Y = point1->Y + SGN(dy) * coord_abs(dx);; + } + } + + if (radius > 0.0) { + pcb_route_object_t arc; + rnd_point_t target1; + rnd_point_t target2; + + pcb_route_calculate_corner_arc(point1, &target, point2, radius, &arc, &target1, &target2); + + if ((point1->X != target1.X) || (point1->Y != target1.Y)) + pcb_route_add_line(route, point1, &target1, layer_id); + + if ((target1.X != target2.X) || (target1.Y != target2.Y)) + pcb_route_add_arc(route, &arc.point1, arc.start_angle, arc.delta_angle, arc.radius, layer_id); + + if ((point2->X != target2.X) || (point2->Y != target2.Y)) + pcb_route_add_line(route, &target2, point2, layer_id); + + route->end_point = *point2; + } + else { + if ((point1->X != target.X) || (point1->Y != target.Y)) + pcb_route_add_line(route, point1, &target, layer_id); + if ((point2->X != target.X) || (point2->Y != target.Y)) + pcb_route_add_line(route, &target, point2, layer_id); + route->end_point = *point2; + } + } + +} + +TODO("Pass in other required information such as object flags") +void pcb_route_calculate(pcb_board_t *PCB, pcb_route_t *route, rnd_point_t *point1, rnd_point_t *point2, rnd_layer_id_t layer_id, rnd_coord_t thickness, rnd_coord_t clearance, pcb_flag_t flags, int mod1, int mod2) +{ + /* Set radius to 0 for standard 45/90 operation */ +/* const rnd_coord_t radius = thickness * conf_core.editor.route_radius; - TODO: remove this if not needed */ + + pcb_route_start(PCB, route, point1, layer_id, thickness, clearance, flags); + + /* If the line can be drawn directly to the target then add a single line segment. */ + if (conf_core.editor.all_direction_lines) { + pcb_route_add_line(route, point1, point2, layer_id); + return; + } + + pcb_route_calculate_to(route, point2, mod1, mod2); +} + +int pcb_route_apply(const pcb_route_t *p_route) +{ + return pcb_route_apply_to_line(p_route, NULL, NULL); +} + +/* Return the layer the route code should add new object onot; normally it + is the board layer of the route, but when a floater of a subcircuit is split + e.g. by the line tool code, new floaters within the same subcircuit shall + be created instead */ +static pcb_layer_t *get_route_layer(pcb_board_t *pcb, const pcb_any_obj_t *apply_to, pcb_route_object_t const *p_obj, int *exto_flt) +{ + *exto_flt = 0; + if ((apply_to != NULL) && (PCB_FLAG_TEST(PCB_FLAG_FLOATER, apply_to))) { + pcb_subc_t *psc = pcb_obj_parent_subc(apply_to); + if (psc != NULL) { + *exto_flt = 1; + assert(apply_to->parent_type == PCB_PARENT_LAYER); + return apply_to->parent.layer; + } + } + return pcb_loose_subc_layer(PCB, pcb_get_layer(PCB->Data, p_obj->layer), rnd_true); +} + +int pcb_route_apply_to_line(const pcb_route_t *p_route, pcb_layer_t *apply_to_line_layer, pcb_line_t *apply_to_line) +{ + int i; + int applied = 0; + const pcb_line_t *attr_src = apply_to_line; + pcb_any_obj_t *exto; + + for(i = 0; i < p_route->size; i++) { + pcb_route_object_t const *p_obj = &p_route->objects[i]; + int exto_flt; + pcb_layer_t *layer = get_route_layer(PCB, (const pcb_any_obj_t *)attr_src, p_obj, &exto_flt); + + switch (p_obj->type) { + case PCB_OBJ_LINE: + /* If the route is being applied to an existing line then the existing + line will be used as the first line in the route. This maintains the + ID of the line and line points. This is especially useful if the + route contains a single line. + */ + if (apply_to_line) { + /* Move the existing line points to the position of the route line. */ + if ((p_obj->point1.X != apply_to_line->Point1.X) || (p_obj->point1.Y != apply_to_line->Point1.Y)) + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, apply_to_line_layer, apply_to_line, &apply_to_line->Point1, p_obj->point1.X - apply_to_line->Point1.X, p_obj->point1.Y - apply_to_line->Point1.Y); + + if ((p_obj->point2.X != apply_to_line->Point2.X) || (p_obj->point2.Y != apply_to_line->Point2.Y)) + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, apply_to_line_layer, apply_to_line, &apply_to_line->Point2, p_obj->point2.X - apply_to_line->Point2.X, p_obj->point2.Y - apply_to_line->Point2.Y); + + /* Move the existing line point/s */ + exto = pcb_extobj_float_pre((pcb_any_obj_t *)apply_to_line); + pcb_line_invalidate_erase(apply_to_line); + rnd_r_delete_entry(apply_to_line_layer->line_tree, (rnd_box_t *) apply_to_line); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_LINE, apply_to_line_layer, apply_to_line); + apply_to_line->Point1.X = p_obj->point1.X; + apply_to_line->Point1.Y = p_obj->point1.Y; + apply_to_line->Point2.X = p_obj->point2.X; + apply_to_line->Point2.Y = p_obj->point2.Y; + pcb_line_bbox(apply_to_line); + rnd_r_insert_entry(layer->line_tree, (rnd_box_t *) apply_to_line); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_LINE, layer, apply_to_line); + pcb_line_invalidate_draw(layer, apply_to_line); + apply_to_line_layer = layer; + if (exto != NULL) + pcb_extobj_float_geo(exto); + + /* if the modified line can be merged with an existing line, do it */ + pcb_line_mod_merge(apply_to_line, 1); + + /* The existing line has been used so forget about it. */ + apply_to_line = NULL; + applied = 1; + } + else { + /* Create a new line */ + pcb_line_t *line = pcb_line_new_merge(layer, + p_obj->point1.X, + p_obj->point1.Y, + p_obj->point2.X, + p_obj->point2.Y, + p_route->thickness, + p_route->clearance, + p_route->flags); + if (line) { + pcb_added_lines++; + pcb_obj_add_attribs((pcb_any_obj_t *)line, PCB->pen_attr, NULL); + if (attr_src != NULL) + pcb_obj_add_attribs((pcb_any_obj_t *)line, &attr_src->Attributes, (pcb_any_obj_t *)attr_src); + pcb_line_invalidate_draw(layer, line); + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, layer, line, line); + applied = 1; + if (exto_flt) + pcb_extobj_float_new((pcb_any_obj_t *)line); + } + } + break; + + case PCB_OBJ_ARC: + { + /* Create a new arc */ + pcb_arc_t *arc = pcb_arc_new(layer, + p_obj->point1.X, + p_obj->point1.Y, + p_obj->radius, + p_obj->radius, + p_obj->start_angle, + p_obj->delta_angle, + p_route->thickness, + p_route->clearance, + p_route->flags, rnd_true); + if (arc) { + pcb_added_lines++; + pcb_obj_add_attribs((pcb_any_obj_t *)arc, PCB->pen_attr, NULL); + if (attr_src != NULL) + pcb_obj_add_attribs((pcb_any_obj_t *)arc, &attr_src->Attributes, (pcb_any_obj_t *)attr_src); + pcb_undo_add_obj_to_create(PCB_OBJ_ARC, layer, arc, arc); + pcb_arc_invalidate_draw(layer, arc); + applied = 1; + if (exto_flt) + pcb_extobj_float_new((pcb_any_obj_t *)arc); + } + } + break; + + default: + break; + } + } + + /* If the existing apply-to-line wasn't updated then it should be deleted */ + /* (This can happen if the route does not contain any lines.) */ + if (apply_to_line != NULL) + pcb_line_destroy(apply_to_line_layer, apply_to_line); + + if (applied) + pcb_subc_as_board_update(PCB); + + return applied; +} + +int pcb_route_apply_to_arc(const pcb_route_t *p_route, pcb_layer_t *apply_to_arc_layer, pcb_arc_t *apply_to_arc) +{ + int i; + int applied = 0; + const pcb_arc_t *attr_src = apply_to_arc; + pcb_any_obj_t *exto; + + for(i = 0; i < p_route->size; i++) { + pcb_route_object_t const *p_obj = &p_route->objects[i]; + int exto_flt; + pcb_layer_t *layer = get_route_layer(PCB, (const pcb_any_obj_t *)attr_src, p_obj, &exto_flt); + + switch (p_obj->type) { + case PCB_OBJ_ARC: + /* If the route is being applied to an existing arc then the existing + arc will be used as the first arc in the route. This maintains the + ID of the arc. + */ + if (apply_to_arc) { + int changes = 0; + + /* Move the existing line points to the position of the route line. */ + if ((p_obj->radius != apply_to_arc->Width) || (p_obj->radius != apply_to_arc->Height)) { + pcb_undo_add_obj_to_change_radii(PCB_OBJ_ARC, apply_to_arc, apply_to_arc, apply_to_arc); + ++changes; + } + + if ((p_obj->start_angle != apply_to_arc->StartAngle) || (p_obj->delta_angle != apply_to_arc->Delta)) { + pcb_undo_add_obj_to_change_angles(PCB_OBJ_ARC, apply_to_arc, apply_to_arc, apply_to_arc); + ++changes; + } + + if (p_route->thickness != apply_to_arc->Thickness) { + pcb_undo_add_obj_to_size(PCB_OBJ_ARC, apply_to_arc_layer, apply_to_arc, apply_to_arc); + ++changes; + } + + if ((p_obj->point1.X != apply_to_arc->X) || (p_obj->point1.Y != apply_to_arc->Y)) { + pcb_undo_add_obj_to_move(PCB_OBJ_ARC, apply_to_arc_layer, apply_to_arc, NULL, p_obj->point1.X - apply_to_arc->X, p_obj->point1.Y - apply_to_arc->Y); + ++changes; + } + + if (changes > 0) { + /* Modify the existing arc */ + exto = pcb_extobj_float_pre((pcb_any_obj_t *)apply_to_arc); + pcb_arc_invalidate_erase(apply_to_arc); + + rnd_r_delete_entry(apply_to_arc_layer->arc_tree, (rnd_box_t *) apply_to_arc); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_ARC, apply_to_arc_layer, apply_to_arc); + + apply_to_arc->X = p_obj->point1.X; + apply_to_arc->Y = p_obj->point1.Y; + apply_to_arc->Width = p_obj->radius; + apply_to_arc->Height = p_obj->radius; + apply_to_arc->StartAngle = p_obj->start_angle; + apply_to_arc->Delta = p_obj->delta_angle; + apply_to_arc->Thickness = p_route->thickness; + pcb_arc_bbox(apply_to_arc); + rnd_r_insert_entry(apply_to_arc_layer->arc_tree, (rnd_box_t *) apply_to_arc); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_ARC, apply_to_arc_layer, apply_to_arc); + pcb_arc_invalidate_draw(layer, apply_to_arc); + apply_to_arc_layer = layer; + if (exto != NULL) + pcb_extobj_float_geo(exto); + } + + /* The existing arc has been used so forget about it. */ + apply_to_arc = NULL; + applied = 1; + } + else { + /* Create a new arc */ + pcb_arc_t *arc = pcb_arc_new(layer, + p_obj->point1.X, + p_obj->point1.Y, + p_obj->radius, + p_obj->radius, + p_obj->start_angle, + p_obj->delta_angle, + p_route->thickness, + p_route->clearance, + p_route->flags, rnd_true); + if (arc) { + pcb_added_lines++; + pcb_obj_add_attribs((pcb_any_obj_t *)arc, PCB->pen_attr, NULL); + if (attr_src != NULL) + pcb_obj_add_attribs((pcb_any_obj_t *)arc, &attr_src->Attributes, (pcb_any_obj_t *)attr_src); + pcb_undo_add_obj_to_create(PCB_OBJ_ARC, layer, arc, arc); + pcb_arc_invalidate_draw(layer, arc); + applied = 1; + if (exto_flt) + pcb_extobj_float_new((pcb_any_obj_t *)arc); + } + } + break; + + case PCB_OBJ_LINE: + { + /* Create a new line */ + pcb_line_t *line = pcb_line_new_merge(layer, + p_obj->point1.X, + p_obj->point1.Y, + p_obj->point2.X, + p_obj->point2.Y, + p_route->thickness, + p_route->clearance, + p_route->flags); + if (line) { + pcb_added_lines++; + pcb_obj_add_attribs((pcb_any_obj_t *)line, PCB->pen_attr, NULL); + if (attr_src != NULL) + pcb_obj_add_attribs((pcb_any_obj_t *)line, &attr_src->Attributes, (pcb_any_obj_t *)attr_src); + pcb_line_invalidate_draw(layer, line); + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, layer, line, line); + applied = 1; + if (exto_flt) + pcb_extobj_float_new((pcb_any_obj_t *)line); + } + } + break; + + default: + break; + } + } + + /* If the existing apply-to-arc wasn't updated then it should be deleted */ + /* (This can happen if the route does not contain any arcs.) */ + if (apply_to_arc != NULL) + pcb_arc_destroy(apply_to_arc_layer, apply_to_arc); + + if (applied) + pcb_subc_as_board_update(PCB); + + return applied; +} + +/*============================================================================= + * + * Route Drawing + * + *===========================================================================*/ + +/*----------------------------------------------------------- + * Draws the outline of an arc + *---------------------------------------------------------*/ +void pcb_route_draw_arc(rnd_hid_gc_t GC, rnd_coord_t x, rnd_coord_t y, rnd_angle_t start_angle, rnd_angle_t delta, rnd_coord_t radius, rnd_coord_t thickness) +{ + double x1, y1, x2, y2, wid = thickness / 2; + + if (delta < 0) { + start_angle += delta; + delta = -delta; + } + + x1 = x - (cos(RND_M180 * start_angle) * radius); + y1 = y + (sin(RND_M180 * start_angle) * radius); + x2 = x - (cos(RND_M180 * (start_angle + delta)) * radius); + y2 = y + (sin(RND_M180 * (start_angle + delta)) * radius); + + rnd_render->draw_arc(GC, x, y, radius + wid, radius + wid, start_angle, delta); + if (wid > rnd_pixel_slop) { + rnd_render->draw_arc(GC, x, y, radius - wid, radius - wid, start_angle, delta); + rnd_render->draw_arc(GC, x1, y1, wid, wid, start_angle, -180 * SGN(delta)); + rnd_render->draw_arc(GC, x2, y2, wid, wid, start_angle + delta, 180 * SGN(delta)); + } + +} + +/*----------------------------------------------------------- + * Draws the route as outlines + *---------------------------------------------------------*/ +void pcb_route_draw(pcb_route_t *p_route, rnd_hid_gc_t GC) +{ + int i = 0; + for(i = 0; i < p_route->size; ++i) { + const pcb_route_object_t *p_obj = &p_route->objects[i]; + + pcb_layer_t *layer = pcb_get_layer(PCB->Data, p_obj->layer); + if (layer) + rnd_render->set_color(GC, &layer->meta.real.color); + + switch (p_obj->type) { + case PCB_OBJ_LINE: + pcb_draw_wireframe_line(GC, p_obj->point1.X, p_obj->point1.Y, p_obj->point2.X, p_obj->point2.Y, p_route->thickness, 0); + break; + + case PCB_OBJ_ARC: + pcb_route_draw_arc(GC, p_obj->point1.X, p_obj->point1.Y, p_obj->start_angle, p_obj->delta_angle, p_obj->radius, p_route->thickness); + break; + + default: + break; + } + } +} + +/*----------------------------------------------------------- + * Draws a drc outline around the route + *---------------------------------------------------------*/ +void pcb_route_draw_drc(pcb_route_t *p_route, rnd_hid_gc_t GC) +{ + rnd_coord_t thickness = p_route->thickness + 2 * conf_core.design.clearance; + int i; + + rnd_render->set_color(GC, &conf_core.appearance.color.drc); + + for(i = 0; i < p_route->size; ++i) { + const pcb_route_object_t *p_obj = &p_route->objects[i]; + + switch (p_obj->type) { + case PCB_OBJ_LINE: + pcb_draw_wireframe_line(GC, p_obj->point1.X, p_obj->point1.Y, p_obj->point2.X, p_obj->point2.Y, thickness, 0); + break; + + case PCB_OBJ_ARC: + pcb_route_draw_arc(GC, p_obj->point1.X, p_obj->point1.Y, p_obj->start_angle, p_obj->delta_angle, p_obj->radius, thickness); + break; + + default: + break; + } + } +} Index: tags/2.3.0/src/route.h =================================================================== --- tags/2.3.0/src/route.h (nonexistent) +++ tags/2.3.0/src/route.h (revision 33253) @@ -0,0 +1,82 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2004 Thomas Nau + * Copyright (C) 2017 Adrian Purser + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_ROUTE_H +#define PCB_ROUTE_H + +#define ROUTE_SMALL_DATA_SIZE 4 + +#include "obj_common.h" +#include + +typedef struct { + pcb_objtype_t type; + rnd_point_t point1; /* Line: Start Point, Arc: Center Point */ + rnd_point_t point2; /* Line: End Point */ + rnd_coord_t radius; /* Arc */ + rnd_angle_t start_angle; /* Arc */ + rnd_angle_t delta_angle; /* Arc */ + rnd_layer_id_t layer; +} pcb_route_object_t; + +typedef struct { + rnd_point_t start_point; + rnd_point_t end_point; + rnd_coord_t thickness; + rnd_coord_t clearance; + rnd_layer_id_t start_layer; /* The ID of the layer that the route started on */ + rnd_layer_id_t end_layer; /* The ID of the layer that the route ended on, usually the same as the start for simple routes */ + pcb_board_t *PCB; + pcb_flag_t flags; + int size; /* The number of active objects in the array */ + int capacity; /* The size of the object array */ + pcb_route_object_t *objects; /* Pointer to the object array data */ + pcb_route_object_t small_data[ROUTE_SMALL_DATA_SIZE]; /* Small object array used to avoid allocating memory for small routes */ +} pcb_route_t; + + +void pcb_route_init(pcb_route_t *p_route); +void pcb_route_destroy(pcb_route_t *p_route); +void pcb_route_reset(pcb_route_t *p_route); +void pcb_route_reserve(pcb_route_t *p_route, int size); +void pcb_route_resize(pcb_route_t *p_route, int size); +void pcb_route_start(pcb_board_t *PCB, pcb_route_t *route, rnd_point_t *point, rnd_layer_id_t layer_id, rnd_coord_t thickness, rnd_coord_t clearance, pcb_flag_t flags); + +void pcb_route_add_line(pcb_route_t *p_route, rnd_point_t *point1, rnd_point_t *point2, rnd_layer_id_t layer); +void pcb_route_add_arc(pcb_route_t *p_route, rnd_point_t *center, rnd_angle_t start_angle, rnd_angle_t delta, rnd_coord_t radius, rnd_layer_id_t layer); + +void pcb_route_calculate(pcb_board_t *PCB, pcb_route_t *route, rnd_point_t *point1, rnd_point_t *point2, rnd_layer_id_t layer_id, rnd_coord_t thickness, rnd_coord_t clearance, pcb_flag_t flags, int mod1, int mod2); +void pcb_route_calculate_to(pcb_route_t *route, rnd_point_t *point, int mod1, int mod2); +void pcb_route_direct(pcb_board_t *PCB, pcb_route_t *p_route, rnd_point_t *point1, rnd_point_t *point2, rnd_layer_id_t layer, rnd_coord_t thickness, rnd_coord_t clearance, pcb_flag_t flags); + +int pcb_route_apply(const pcb_route_t *p_route); +int pcb_route_apply_to_line(const pcb_route_t *p_route, pcb_layer_t *Layer, pcb_line_t *apply_to_line); +int pcb_route_apply_to_arc(const pcb_route_t *p_route, pcb_layer_t *apply_to_arc_layer, pcb_arc_t *apply_to_arc); + +#endif Index: tags/2.3.0/src/route_draw.h =================================================================== --- tags/2.3.0/src/route_draw.h (nonexistent) +++ tags/2.3.0/src/route_draw.h (revision 33253) @@ -0,0 +1,10 @@ +#ifndef PCB_ROUTE_DRAW_H +#define PCB_ROUTE_DRAW_H + +#include +#include + +void pcb_route_draw(pcb_route_t *p_route, rnd_hid_gc_t GC); +void pcb_route_draw_drc(pcb_route_t *p_route, rnd_hid_gc_t GC); + +#endif Index: tags/2.3.0/src/route_style.c =================================================================== --- tags/2.3.0/src/route_style.c (nonexistent) +++ tags/2.3.0/src/route_style.c (revision 33253) @@ -0,0 +1,402 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2004,2006 Thomas Nau + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include +#include "config.h" +#include +#include "genvector/gds_char.h" +#include "route_style.h" +#include +#include +#include +#include "board.h" +#include "undo.h" +#include "funchash_core.h" +#include "conf_core.h" +#include "event.h" + +pcb_route_style_t pcb_custom_route_style; + +static const char rst_cookie[] = "core route style"; + +static rnd_coord_t pcb_get_num(char **s, const char *default_unit) +{ + /* Read value */ + rnd_coord_t ret_val = rnd_get_value_ex(*s, NULL, NULL, NULL, default_unit, NULL); + /* Advance pointer */ + while (isalnum(**s) || **s == '.') + (*s)++; + return ret_val; +} + + +/* Serializes the route style list */ +char *pcb_route_string_make(vtroutestyle_t *styles) +{ + gds_t str; + int i; + + gds_init(&str); + for (i = 0; i < vtroutestyle_len(styles); ++i) { + rnd_append_printf(&str, "%s,%mc,%mc,%mc,%mc", styles->array[i].name, + styles->array[i].Thick, styles->array[i].Diameter, + styles->array[i].Hole, styles->array[i].Clearance); + if (i > 0) + gds_append(&str, ':'); + } + return str.array; /* this is the only allocation made, return this and don't uninit */ +} + +/* ---------------------------------------------------------------------- + * parses the routes definition string which is a colon separated list of + * comma separated Name, Dimension, Dimension, Dimension, Dimension + * e.g. Signal,20,40,20,10:Power,40,60,28,10:... + */ +int pcb_route_string_parse1(char **str, pcb_route_style_t *routeStyle, const char *default_unit) +{ + char *s = *str; + char Name[256]; + int i, len; + + while (*s && isspace((int) *s)) + s++; + for (i = 0; *s && *s != ','; i++) + Name[i] = *s++; + Name[i] = '\0'; + len = strlen(Name); + if (len > sizeof(routeStyle->name)-1) { + memcpy(routeStyle->name, Name, sizeof(routeStyle->name)-1); + routeStyle->name[sizeof(routeStyle->name)-1] = '\0'; + rnd_message(RND_MSG_WARNING, "Route style name '%s' too long, truncated to '%s'\n", Name, routeStyle->name); + } + else + strcpy(routeStyle->name, Name); + if (!isdigit((int) *++s)) + goto error; + routeStyle->Thick = pcb_get_num(&s, default_unit); + while (*s && isspace((int) *s)) + s++; + if (*s++ != ',') + goto error; + while (*s && isspace((int) *s)) + s++; + if (!isdigit((int) *s)) + goto error; + routeStyle->Diameter = pcb_get_num(&s, default_unit); + while (*s && isspace((int) *s)) + s++; + if (*s++ != ',') + goto error; + while (*s && isspace((int) *s)) + s++; + if (!isdigit((int) *s)) + goto error; + routeStyle->Hole = pcb_get_num(&s, default_unit); + /* for backwards-compatibility, we use a 10-mil default + * for styles which omit the clearance specification. */ + if (*s != ',') + routeStyle->Clearance = RND_MIL_TO_COORD(10); + else { + s++; + while (*s && isspace((int) *s)) + s++; + if (!isdigit((int) *s)) + goto error; + routeStyle->Clearance = pcb_get_num(&s, default_unit); + while (*s && isspace((int) *s)) + s++; + } + + *str = s; + return 0; + error:; + *str = s; + return -1; +} + +int pcb_route_string_parse(char *s, vtroutestyle_t *styles, const char *default_unit) +{ + int n; + + vtroutestyle_truncate(styles, 0); + for(n = 0;;n++) { + vtroutestyle_enlarge(styles, n+1); + if (pcb_route_string_parse1(&s, &styles->array[n], default_unit) != 0) { + n--; + break; + } + while (*s && isspace((int) *s)) + s++; + if (*s == '\0') + break; + if (*s++ != ':') { + vtroutestyle_truncate(styles, 0); + return -1; + } + } + vtroutestyle_truncate(styles, n+1); + return 0; +} + +void pcb_use_route_style(pcb_route_style_t * rst) +{ + rnd_conf_set_design("design/line_thickness", "%$mS", rst->Thick); + rnd_conf_set_design("design/text_scale", "%d", rst->texts <= 0 ? 100 : rst->texts); + rnd_conf_set_design("design/text_thickness", "%$mS", rst->textt); + rnd_conf_set_design("design/via_thickness", "%$mS", rst->Diameter); + rnd_conf_set_design("design/via_drilling_hole", "%$mS", rst->Hole); + rnd_conf_set_design("design/clearance", "%$mS", rst->Clearance); + PCB->pen_attr = &rst->attr; +} + +int pcb_use_route_style_idx(vtroutestyle_t *styles, int idx) +{ + if ((idx < 0) || (idx >= vtroutestyle_len(styles))) + return -1; + pcb_use_route_style(styles->array+idx); + return 0; +} + +#define cmp(a,b) (((a) != -1) && (coord_abs((a)-(b)) > 32)) +#define cmps(a,b) (((a) != NULL) && (strcmp((a), (b)) != 0)) +int pcb_route_style_match(pcb_route_style_t *rst, rnd_coord_t Thick, rnd_coord_t Diameter, rnd_coord_t Hole, rnd_coord_t Clearance, char *Name) +{ + if (cmp(Thick, rst->Thick)) return 0; + if (cmp(Diameter, rst->Diameter)) return 0; + if (cmp(Hole, rst->Hole)) return 0; + if (cmp(Clearance, rst->Clearance)) return 0; + if (cmps(Name, rst->name)) return 0; + return 1; +} +#undef cmp +#undef cmps + +int pcb_route_style_lookup(vtroutestyle_t *styles, rnd_coord_t Thick, rnd_coord_t Diameter, rnd_coord_t Hole, rnd_coord_t Clearance, char *Name) +{ + int n; + for (n = 0; n < vtroutestyle_len(styles); n++) + if (pcb_route_style_match(&styles->array[n], Thick, Diameter, Hole, Clearance, Name)) + return n; + return -1; +} + + +int pcb_get_style_size(int funcid, rnd_coord_t * out, int type, int size_id) +{ + switch (funcid) { + case F_Object: + switch (type) { + case PCB_OBJ_LINE: + return pcb_get_style_size(F_SelectedLines, out, 0, size_id); + case PCB_OBJ_ARC: + return pcb_get_style_size(F_SelectedArcs, out, 0, size_id); + } + rnd_message(RND_MSG_ERROR, "Sorry, can't fetch the style of that object type (%x)\n", type); + return -1; + case F_SelectedPads: + if (size_id != 2) /* don't mess with pad size */ + return -1; + case F_SelectedVias: + case F_SelectedPins: + case F_SelectedObjects: + case F_Selected: + case F_SelectedElements: + if (size_id == 0) + *out = conf_core.design.via_thickness; + else if (size_id == 1) + *out = conf_core.design.via_drilling_hole; + else + *out = conf_core.design.clearance; + break; + case F_SelectedArcs: + case F_SelectedLines: + if (size_id == 2) + *out = conf_core.design.clearance; + else + *out = conf_core.design.line_thickness; + return 0; + case F_SelectedTexts: + case F_SelectedNames: + rnd_message(RND_MSG_ERROR, "Sorry, can't change style of every selected object\n"); + return -1; + } + return 0; +} + + + +typedef struct { + pcb_board_t *pcb; + int idx; + pcb_route_style_t rst; + enum { RST_SET, RST_NEW, RST_DEL } cmd; +} undo_rst_t; + +static int undo_rst_swap(void *udata) +{ + undo_rst_t *g = udata; + pcb_route_style_t *rst; + + if (g->cmd != RST_NEW) { + rst = vtroutestyle_get(&g->pcb->RouteStyle, g->idx, 0); + if (rst == NULL) { + rnd_message(RND_MSG_ERROR, "undo_rst_swap(): internal error: route %d does not exist\b", g->idx); + return -1; + } + } + else + rst = vtroutestyle_alloc_insert(&g->pcb->RouteStyle, g->idx, 1); + + rnd_swap(pcb_route_style_t, *rst, g->rst); + + if (g->cmd == RST_DEL) + vtroutestyle_remove(&g->pcb->RouteStyle, g->idx, 1); + + /* invert new/del */ + if (g->cmd == RST_NEW) g->cmd = RST_DEL; + else if (g->cmd == RST_DEL) g->cmd = RST_NEW; + + + rnd_event(&g->pcb->hidlib, PCB_EVENT_ROUTE_STYLES_CHANGED, NULL); + pcb_board_set_changed_flag(g->pcb, 1); + + return 0; +} + +static void undo_rst_print(void *udata, char *dst, size_t dst_len) +{ + undo_rst_t *g = udata; + + rnd_snprintf(dst, dst_len, "route style: thick=%.03$mH textt=%.03$mH texts=%.03$mH Clearance=%.03$mH texts=%.03$mH proto=%ld", + g->rst.Thick, g->rst.textt, g->rst.texts, g->rst.Clearance, (long)(g->rst.via_proto_set ? g->rst.via_proto : -1)); +} + +static const uundo_oper_t undo_rst = { + rst_cookie, + NULL, + undo_rst_swap, + undo_rst_swap, + undo_rst_print +}; + + +int pcb_route_style_change(pcb_board_t *pcb, int rstidx, rnd_coord_t *thick, rnd_coord_t *textt, int *texts, rnd_coord_t *clearance, rnd_cardinal_t *via_proto, rnd_bool undoable) +{ + undo_rst_t gtmp, *g = >mp; + pcb_route_style_t *rst = vtroutestyle_get(&pcb->RouteStyle, rstidx, 0); + + if (rst == NULL) + return -1; + + if (undoable) g = pcb_undo_alloc(pcb, &undo_rst, sizeof(undo_rst_t)); + + g->pcb = pcb; + g->idx = rstidx; + g->rst = *rst; + g->cmd = RST_SET; + if (thick != NULL) g->rst.Thick = *thick; + if (textt != NULL) g->rst.textt = *textt; + if (texts != NULL) g->rst.texts = *texts; + if (clearance != NULL) g->rst.Clearance = *clearance; + if (via_proto != NULL) { + g->rst.via_proto = *via_proto; + g->rst.via_proto_set = (*via_proto != -1); + + } + + undo_rst_swap(g); + if (undoable) pcb_undo_inc_serial(); + + return 0; +} + +int pcb_route_style_change_name(pcb_board_t *pcb, int rstidx, const char *new_name, rnd_bool undoable) +{ + undo_rst_t gtmp, *g = >mp; + pcb_route_style_t *rst = vtroutestyle_get(&pcb->RouteStyle, rstidx, 0); + + if (rst == NULL) + return -1; + + if (undoable) g = pcb_undo_alloc(pcb, &undo_rst, sizeof(undo_rst_t)); + + g->pcb = pcb; + g->idx = rstidx; + g->rst = *rst; + g->cmd = RST_SET; + strncpy(g->rst.name, new_name, sizeof(g->rst.name)); + undo_rst_swap(g); + if (undoable) pcb_undo_inc_serial(); + + return 0; +} + +int pcb_route_style_new(pcb_board_t *pcb, const char *name, rnd_bool undoable) +{ + + undo_rst_t gtmp, *g = >mp; + if (undoable) g = pcb_undo_alloc(pcb, &undo_rst, sizeof(undo_rst_t)); + + g->pcb = pcb; + g->idx = vtroutestyle_len(&PCB->RouteStyle); + g->cmd = RST_NEW; + + memset(&g->rst, 0, sizeof(g->rst)); + + strncpy(g->rst.name, name, sizeof(g->rst.name)); + + g->rst.Thick = conf_core.design.line_thickness; + g->rst.textt = conf_core.design.text_thickness; + g->rst.texts = conf_core.design.text_scale; + g->rst.Clearance = conf_core.design.clearance; + g->rst.Diameter = conf_core.design.via_thickness*2; + g->rst.Hole = conf_core.design.via_drilling_hole; + + undo_rst_swap(g); + if (undoable) pcb_undo_inc_serial(); + + return g->idx; +} + +int pcb_route_style_del(pcb_board_t *pcb, int idx, rnd_bool undoable) +{ + undo_rst_t gtmp, *g = >mp; + if (undoable) g = pcb_undo_alloc(pcb, &undo_rst, sizeof(undo_rst_t)); + + g->pcb = pcb; + g->idx = idx; + g->cmd = RST_DEL; + + memset(&g->rst, 0, sizeof(g->rst)); + + undo_rst_swap(g); + if (undoable) pcb_undo_inc_serial(); + + return g->idx; +} + Index: tags/2.3.0/src/route_style.h =================================================================== --- tags/2.3.0/src/route_style.h (nonexistent) +++ tags/2.3.0/src/route_style.h (revision 33253) @@ -0,0 +1,77 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2004 Thomas Nau + * Copyright (C) 2016 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "vtroutestyle.h" + +/* Parse a single route string into one pcb_route_style_t *slot. Returns 0 on success. */ +int pcb_route_string_parse1(char **str, pcb_route_style_t *routeStyle, const char *default_unit); + +/* Parse a ':' separated list of route strings into a styles vector + The vector is initialized before the call. On error the vector is left empty + (but still initialized). Returns 0 on success. */ +int pcb_route_string_parse(char *s, vtroutestyle_t *styles, const char *default_unit); + +char *pcb_route_string_make(vtroutestyle_t *styles); + +/* Set design configuration (the pen we draw with) to a given route style */ +void pcb_use_route_style(pcb_route_style_t *rst); + +/* Same as pcb_use_route_style() but uses one of the styles in a vector; + returns -1 if idx is out of bounds, 0 on success. */ +int pcb_use_route_style_idx(vtroutestyle_t *styles, int idx); + +/* Compare supplied parameters to each style in the vector and return the index + of the first matching style. All non-(-1) parameters need to match to accept + a style. Return -1 on no match. */ +int pcb_route_style_lookup(vtroutestyle_t *styles, rnd_coord_t Thick, rnd_coord_t Diameter, rnd_coord_t Hole, rnd_coord_t Clearance, char *Name); + +/* Return 1 if rst matches the style in supplied args. Same matching rules as + in pcb_route_style_lookup(). */ +int pcb_route_style_match(pcb_route_style_t *rst, rnd_coord_t Thick, rnd_coord_t Diameter, rnd_coord_t Hole, rnd_coord_t Clearance, char *Name); + +extern pcb_route_style_t pcb_custom_route_style; + +/* helper: get route style size for a function and selected object type. + size_id: 0=main size; 1=2nd size (drill); 2=clearance */ +int pcb_get_style_size(int funcid, rnd_coord_t * out, int type, int size_id); + + +/*** Undoable changes to route styles ***/ + +/* Change a field. Returns 0 on success. */ +int pcb_route_style_change(pcb_board_t *pcb, int rstidx, rnd_coord_t *thick, rnd_coord_t *textt, int *texts, rnd_coord_t *clearance, rnd_cardinal_t *via_proto, rnd_bool undoable); + +/* Change the name. Returns 0 on success. */ +int pcb_route_style_change_name(pcb_board_t *pcb, int rstidx, const char *new_name, rnd_bool undoable); + +/* Returns the index (counted from 0) or -1 on error */ +int pcb_route_style_new(pcb_board_t *pcb, const char *name, rnd_bool undoable); + +/* Returns 0 on success. */ +int pcb_route_style_del(pcb_board_t *pcb, int idx, rnd_bool undoable); Index: tags/2.3.0/src/search.c =================================================================== --- tags/2.3.0/src/search.c (nonexistent) +++ tags/2.3.0/src/search.c (revision 33253) @@ -0,0 +1,1921 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + + +/* search routines + * some of the functions use dummy parameters + */ + +#include "config.h" +#include "conf_core.h" + +#include + +#include "actions_pcb.h" +#include "board.h" +#include "data.h" +#include +#include +#include +#include "find.h" +#include "polygon.h" +#include "search.h" +#include "select.h" +#include "obj_subc_parent.h" +#include "obj_pstk_inlines.h" + +static double PosX, PosY; /* search position for subroutines */ +static rnd_coord_t SearchRadius; +static rnd_box_t SearchBox; +static pcb_layer_t *SearchLayer; + +/* --------------------------------------------------------------------------- + * The first parameter includes PCB_OBJ_LOCKED if we + * want to include locked object in the search and PCB_OBJ_SUBC_PART if + * objects that are part of a subcircuit should be found. + */ +static rnd_bool SearchLineByLocation(unsigned long, unsigned long, pcb_layer_t **, pcb_line_t **, pcb_line_t **); +static rnd_bool SearchArcByLocation(unsigned long, unsigned long, pcb_layer_t **, pcb_arc_t **, pcb_arc_t **); +static rnd_bool SearchGfxByLocation(unsigned long, unsigned long, pcb_layer_t **, pcb_gfx_t **, pcb_gfx_t **); +static rnd_bool SearchRatLineByLocation(unsigned long, unsigned long, pcb_rat_t **, pcb_rat_t **, pcb_rat_t **); +static rnd_bool SearchTextByLocation(unsigned long, unsigned long, pcb_layer_t **, pcb_text_t **, pcb_text_t **); +static rnd_bool SearchPolygonByLocation(unsigned long, unsigned long, pcb_layer_t **, pcb_poly_t **, pcb_poly_t **); +static rnd_bool SearchLinePointByLocation(unsigned long, unsigned long, pcb_layer_t **, pcb_line_t **, rnd_point_t **); +static rnd_bool SearchArcPointByLocation(unsigned long, unsigned long, pcb_layer_t **, pcb_arc_t **, int **); +static rnd_bool SearchPointByLocation(unsigned long, unsigned long, unsigned long, pcb_layer_t **, pcb_poly_t **, rnd_point_t **); +static rnd_bool SearchSubcByLocation(unsigned long, unsigned long, pcb_subc_t **, pcb_subc_t **, pcb_subc_t **, rnd_bool); + +/* Return not-found for subc parts and locked items unless objst says otherwise + obj is the object to be checked if part of subc; check lock on locked_obj + Also return not-found if flags are required but the object doesn't have them */ +#define TEST_OBJST_(objst, req_flag, locality, obj, locked_obj, reject) \ +do { \ + if ((req_flag != 0) && (!PCB_FLAG_TEST(req_flag, obj))) \ + reject; \ + if (!(objst & PCB_OBJ_SUBC_PART) && (pcb_ ## locality ## obj_parent_subc(obj->parent_type, &obj->parent))) \ + reject; \ + if (!(objst & PCB_OBJ_LOCKED) && (PCB_FLAG_TEST(objst & PCB_FLAG_LOCK, locked_obj))) \ + reject; \ +} while(0) + +#define TEST_OBJST(objst, req_flag, locality, obj, locked_obj) \ + TEST_OBJST_(objst, req_flag, locality, obj, locked_obj, return RND_R_DIR_NOT_FOUND) + +struct ans_info { + void **ptr1, **ptr2, **ptr3; + rnd_bool BackToo; + double area; + unsigned long objst, req_flag; + int on_current; + pcb_layer_type_t on_lyt; +}; + +/* --------------------------------------------------------------------------- + * searches a padstack + */ +static rnd_r_dir_t padstack_callback(const rnd_box_t *box, void *cl) +{ + struct ans_info *i = (struct ans_info *) cl; + pcb_pstk_t *ps = (pcb_pstk_t *) box; + pcb_data_t *pdata; + + TEST_OBJST(i->objst, i->req_flag, g, ps, ps); + + if (!pcb_is_point_in_pstk(PosX, PosY, SearchRadius, ps, NULL)) + return RND_R_DIR_NOT_FOUND; + if ((i->on_current) && (pcb_pstk_shape_at(PCB, ps, PCB_CURRLAYER(PCB)) == NULL) && (!pcb_pstk_bb_drills(PCB, ps, PCB_CURRLAYER(PCB)->meta.real.grp, NULL))) + return RND_R_DIR_NOT_FOUND; + if ((i->on_lyt != 0) && (pcb_pstk_shape(ps, i->on_lyt, 0) == NULL)) + return RND_R_DIR_NOT_FOUND; + *i->ptr2 = *i->ptr3 = ps; + assert(ps->parent_type == PCB_PARENT_DATA); + pdata = ps->parent.data; + if (pdata->parent_type == PCB_PARENT_SUBC) + *i->ptr1 = pdata->parent.subc; /* padstack of a subcircuit */ + else + *i->ptr1 = ps; /* padstack on a board (e.g. via) */ + return RND_R_DIR_CANCEL; /* found, stop searching */ +} + +static rnd_bool SearchPadstackByLocation(unsigned long objst, unsigned long req_flag, pcb_pstk_t **ps, pcb_pstk_t **Dummy1, pcb_pstk_t **Dummy2, int on_current, pcb_layer_type_t on_lyt) +{ + struct ans_info info; + + /* search only if via-layer is visible */ + if (!PCB->pstk_on) + return rnd_false; + + info.ptr1 = (void **)ps; + info.ptr2 = (void **)Dummy1; + info.ptr3 = (void **)Dummy2; + info.objst = objst; + info.req_flag = req_flag; + info.on_current = on_current; + info.on_lyt = on_lyt; + + if (rnd_r_search(PCB->Data->padstack_tree, &SearchBox, NULL, padstack_callback, &info, NULL) != RND_R_DIR_NOT_FOUND) + return rnd_true; + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * searches ordinary line on the SearchLayer + */ + +struct line_info { + pcb_line_t **Line; + rnd_point_t **Point; + double least; + unsigned long objst, req_flag; +}; + + +static rnd_r_dir_t line_callback(const rnd_box_t * box, void *cl) +{ + struct line_info *i = (struct line_info *) cl; + pcb_line_t *l = (pcb_line_t *) box; + + TEST_OBJST(i->objst, i->req_flag, l, l, l); + + if (!pcb_is_point_in_line(PosX, PosY, SearchRadius, (pcb_any_line_t *)l)) + return RND_R_DIR_NOT_FOUND; + *i->Line = l; + *i->Point = (rnd_point_t *) l; + + return RND_R_DIR_CANCEL; /* found what we were looking for */ +} + + +static rnd_bool SearchLineByLocation(unsigned long objst, unsigned long req_flag, pcb_layer_t ** Layer, pcb_line_t ** Line, pcb_line_t ** Dummy) +{ + struct line_info info; + + info.Line = Line; + info.Point = (rnd_point_t **) Dummy; + info.objst = objst; + info.req_flag = req_flag; + + *Layer = SearchLayer; + if (rnd_r_search(SearchLayer->line_tree, &SearchBox, NULL, line_callback, &info, NULL) != RND_R_DIR_NOT_FOUND) + return rnd_true; + + return rnd_false; +} + +static rnd_r_dir_t rat_callback(const rnd_box_t * box, void *cl) +{ + pcb_line_t *line = (pcb_line_t *) box; + struct ans_info *i = (struct ans_info *) cl; + + TEST_OBJST(i->objst, i->req_flag, l, line, line); + + if (PCB_FLAG_TEST(PCB_FLAG_VIA, line) ? + (rnd_distance(line->Point1.X, line->Point1.Y, PosX, PosY) <= + line->Thickness * 2 + SearchRadius) : pcb_is_point_on_line(PosX, PosY, SearchRadius, line)) { + *i->ptr1 = *i->ptr2 = *i->ptr3 = line; + return RND_R_DIR_CANCEL; + } + return RND_R_DIR_NOT_FOUND; +} + +/* --------------------------------------------------------------------------- + * searches rat lines if they are visible + */ +static rnd_bool SearchRatLineByLocation(unsigned long objst, unsigned long req_flag, pcb_rat_t ** Line, pcb_rat_t ** Dummy1, pcb_rat_t ** Dummy2) +{ + struct ans_info info; + + info.ptr1 = (void **) Line; + info.ptr2 = (void **) Dummy1; + info.ptr3 = (void **) Dummy2; + info.objst = objst; + info.req_flag = req_flag; + + if (rnd_r_search(PCB->Data->rat_tree, &SearchBox, NULL, rat_callback, &info, NULL) != RND_R_DIR_NOT_FOUND) + return rnd_true; + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * searches arc on the SearchLayer + */ +struct arc_info { + pcb_arc_t **Arc, **Dummy; + unsigned long objst, req_flag; + int **arc_pt; /* 0=start, 1=end (start+delta) */ + double least; +}; + +static rnd_r_dir_t arc_callback(const rnd_box_t * box, void *cl) +{ + struct arc_info *i = (struct arc_info *) cl; + pcb_arc_t *a = (pcb_arc_t *) box; + + TEST_OBJST(i->objst, i->req_flag, l, a, a); + + if (!pcb_is_point_on_arc(PosX, PosY, SearchRadius, a)) + return 0; + *i->Arc = a; + *i->Dummy = a; + return RND_R_DIR_CANCEL; /* found */ +} + + +static rnd_bool SearchArcByLocation(unsigned long objst, unsigned long req_flag, pcb_layer_t ** Layer, pcb_arc_t ** Arc, pcb_arc_t ** Dummy) +{ + struct arc_info info; + + info.Arc = Arc; + info.Dummy = Dummy; + info.objst = objst; + info.req_flag = req_flag; + + *Layer = SearchLayer; + if (rnd_r_search(SearchLayer->arc_tree, &SearchBox, NULL, arc_callback, &info, NULL) != RND_R_DIR_NOT_FOUND) + return rnd_true; + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * searches gfx on the SearchLayer + */ +struct gfx_info { + pcb_gfx_t **Gfx, **Dummy; + unsigned long objst, req_flag; + double least; +}; + +static rnd_r_dir_t gfx_callback(const rnd_box_t *box, void *cl) +{ + struct gfx_info *i = (struct gfx_info *)cl; + pcb_gfx_t *g = (pcb_gfx_t *)box; + + TEST_OBJST(i->objst, i->req_flag, l, g, g); + + if (!pcb_is_point_in_gfx(PosX, PosY, SearchRadius, g)) + return 0; + *i->Gfx = g; + *i->Dummy = g; + return RND_R_DIR_CANCEL; /* found */ +} + +static rnd_bool SearchGfxByLocation(unsigned long objst, unsigned long req_flag, pcb_layer_t **Layer, pcb_gfx_t **gfx, pcb_gfx_t **Dummy) +{ + struct gfx_info info; + + info.Gfx = gfx; + info.Dummy = Dummy; + info.objst = objst; + info.req_flag = req_flag; + + *Layer = SearchLayer; + if (rnd_r_search(SearchLayer->gfx_tree, &SearchBox, NULL, gfx_callback, &info, NULL) != RND_R_DIR_NOT_FOUND) + return rnd_true; + return rnd_false; +} + +static rnd_r_dir_t text_callback(const rnd_box_t * box, void *cl) +{ + pcb_text_t *text = (pcb_text_t *) box; + struct ans_info *i = (struct ans_info *) cl; + + TEST_OBJST(i->objst, i->req_flag, l, text, text); + + if (PCB_POINT_IN_BOX(PosX, PosY, &text->BoundingBox)) { + *i->ptr2 = *i->ptr3 = text; + return RND_R_DIR_CANCEL; /* found */ + } + return RND_R_DIR_NOT_FOUND; +} + +/* --------------------------------------------------------------------------- + * searches text on the SearchLayer + */ +static rnd_bool SearchTextByLocation(unsigned long objst, unsigned long req_flag, pcb_layer_t ** Layer, pcb_text_t ** Text, pcb_text_t ** Dummy) +{ + struct ans_info info; + + *Layer = SearchLayer; + info.ptr2 = (void **) Text; + info.ptr3 = (void **) Dummy; + info.objst = objst; + info.req_flag = req_flag; + + if (rnd_r_search(SearchLayer->text_tree, &SearchBox, NULL, text_callback, &info, NULL) != RND_R_DIR_NOT_FOUND) + return rnd_true; + return rnd_false; +} + +static rnd_r_dir_t polygon_callback(const rnd_box_t * box, void *cl) +{ + pcb_poly_t *polygon = (pcb_poly_t *) box; + struct ans_info *i = (struct ans_info *) cl; + + TEST_OBJST(i->objst, i->req_flag, l, polygon, polygon); + + if (polygon->Clipped == NULL) + return RND_R_DIR_NOT_FOUND; /* polygon cleared out of existence */ + + if (pcb_poly_is_point_in_p(PosX, PosY, SearchRadius, polygon)) { + *i->ptr2 = *i->ptr3 = polygon; + return RND_R_DIR_CANCEL; /* found */ + } + return RND_R_DIR_NOT_FOUND; +} + + +/* --------------------------------------------------------------------------- + * searches a polygon on the SearchLayer + */ +static rnd_bool SearchPolygonByLocation(unsigned long objst, unsigned long req_flag, pcb_layer_t ** Layer, pcb_poly_t ** Polygon, pcb_poly_t ** Dummy) +{ + struct ans_info info; + + *Layer = SearchLayer; + info.ptr2 = (void **) Polygon; + info.ptr3 = (void **) Dummy; + info.objst = objst; + info.req_flag = req_flag; + + if (rnd_r_search(SearchLayer->polygon_tree, &SearchBox, NULL, polygon_callback, &info, NULL) != RND_R_DIR_NOT_FOUND) + return rnd_true; + return rnd_false; +} + +static rnd_r_dir_t linepoint_callback(const rnd_box_t * b, void *cl) +{ + pcb_line_t *line = (pcb_line_t *) b; + struct line_info *i = (struct line_info *) cl; + rnd_r_dir_t ret_val = RND_R_DIR_NOT_FOUND; + double d; + + TEST_OBJST(i->objst, i->req_flag, l, line, line); + + /* some stupid code to check both points */ + d = rnd_distance(PosX, PosY, line->Point1.X, line->Point1.Y); + if (d < i->least) { + i->least = d; + *i->Line = line; + *i->Point = &line->Point1; + ret_val = RND_R_DIR_FOUND_CONTINUE; + } + + d = rnd_distance(PosX, PosY, line->Point2.X, line->Point2.Y); + if (d < i->least) { + i->least = d; + *i->Line = line; + *i->Point = &line->Point2; + ret_val = RND_R_DIR_FOUND_CONTINUE; + } + return ret_val; +} + +static rnd_r_dir_t arcpoint_callback(const rnd_box_t * b, void *cl) +{ + rnd_box_t ab; + pcb_arc_t *arc = (pcb_arc_t *) b; + struct arc_info *i = (struct arc_info *) cl; + rnd_r_dir_t ret_val = RND_R_DIR_NOT_FOUND; + double d; + + TEST_OBJST(i->objst, i->req_flag, l, arc, arc); + + /* some stupid code to check both points */ + pcb_arc_get_end(arc, 0, &ab.X1, &ab.Y1); + pcb_arc_get_end(arc, 1, &ab.X2, &ab.Y2); + + d = rnd_distance(PosX, PosY, ab.X1, ab.Y1); + if (d < i->least) { + i->least = d; + *i->Arc = arc; + *i->arc_pt = pcb_arc_start_ptr; + ret_val = RND_R_DIR_FOUND_CONTINUE; + } + + d = rnd_distance(PosX, PosY, ab.X2, ab.Y2); + if (d < i->least) { + i->least = d; + *i->Arc = arc; + *i->arc_pt = pcb_arc_end_ptr; + ret_val = RND_R_DIR_FOUND_CONTINUE; + } + return ret_val; +} + +/* --------------------------------------------------------------------------- + * searches a line-point on all the search layer + */ +static rnd_bool SearchLinePointByLocation(unsigned long objst, unsigned long req_flag, pcb_layer_t ** Layer, pcb_line_t ** Line, rnd_point_t ** Point) +{ + struct line_info info; + *Layer = SearchLayer; + info.Line = Line; + info.Point = Point; + *Point = NULL; + info.least = RND_MAX_LINE_POINT_DISTANCE + SearchRadius; + info.objst = objst; + info.req_flag = req_flag; + + if (rnd_r_search(SearchLayer->line_tree, &SearchBox, NULL, linepoint_callback, &info, NULL)) + return rnd_true; + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * searches a line-point on all the search layer + */ +static rnd_bool SearchArcPointByLocation(unsigned long objst, unsigned long req_flag, pcb_layer_t ** Layer, pcb_arc_t ** Arc, int **Point) +{ + struct arc_info info; + *Layer = SearchLayer; + info.Arc = Arc; + info.arc_pt = Point; + *Point = NULL; + info.least = RND_MAX_LINE_POINT_DISTANCE + SearchRadius; + info.objst = objst; + info.req_flag = req_flag; + + if (rnd_r_search(SearchLayer->arc_tree, &SearchBox, NULL, arcpoint_callback, &info, NULL)) + return rnd_true; + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * searches a polygon-point on all layers that are switched on + * in layerstack order + */ +typedef struct { + double least; + rnd_bool found; + unsigned long Type; + + /* result */ + pcb_poly_t **Polygon; + rnd_point_t **Point; +} ptcb_t; + +static rnd_r_dir_t polypoint_callback(const rnd_box_t *box, void *cl) +{ + pcb_poly_t *polygon = (pcb_poly_t *)box; + ptcb_t *ctx = (ptcb_t *)cl; + double d; + pcb_data_t *dt; + + dt = polygon->parent.layer->parent.data; /* polygon -> layer -> data */ + if ((dt != NULL) && (dt->parent_type == PCB_PARENT_SUBC)) { + /* do not find subc part poly points if not explicitly requested */ + if (!(ctx->Type & PCB_OBJ_SUBC_PART)) + return RND_R_DIR_NOT_FOUND; + + /* don't find subc poly points even as subc part unless we are editing a subc */ + if (!PCB->loose_subc) + return RND_R_DIR_NOT_FOUND; + } + + PCB_POLY_POINT_LOOP(polygon); + { + d = rnd_distance2(point->X, point->Y, PosX, PosY); + if (d < ctx->least) { + ctx->least = d; + *ctx->Polygon = polygon; + *ctx->Point = point; + ctx->found = rnd_true; + } + } + PCB_END_LOOP; + + return RND_R_DIR_NOT_FOUND; +} + +static rnd_bool SearchPointByLocation(unsigned long Type, unsigned long objst, unsigned long req_flag, pcb_layer_t ** Layer, pcb_poly_t ** Polygon, rnd_point_t ** Point) +{ + ptcb_t ctx; + + *Layer = SearchLayer; + ctx.Type = Type; + ctx.Polygon = Polygon; + ctx.Point = Point; + ctx.found = rnd_false;; + ctx.least = SearchRadius + RND_MAX_POLYGON_POINT_DISTANCE; + ctx.least = ctx.least * ctx.least; + rnd_r_search(SearchLayer->polygon_tree, &SearchBox, NULL, polypoint_callback, &ctx, NULL); + + if (ctx.found) + return rnd_true; + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * searches a gfx-point on all layers that are switched on + * in layerstack order + */ +typedef struct { + double least; + rnd_bool found; + unsigned long Type; + + /* result */ + pcb_gfx_t **gfx; + rnd_point_t **Point; +} gfxptcb_t; + +static rnd_r_dir_t gfxpoint_callback(const rnd_box_t *box, void *cl) +{ + pcb_gfx_t *gfx = (pcb_gfx_t *)box; + gfxptcb_t *ctx = (gfxptcb_t *)cl; + double d; + pcb_data_t *dt; + int n; + + dt = gfx->parent.layer->parent.data; /* gfx -> layer -> data */ + if ((dt != NULL) && (dt->parent_type == PCB_PARENT_SUBC)) { + /* do not find subc part poly points if not explicitly requested */ + if (!(ctx->Type & PCB_OBJ_SUBC_PART)) + return RND_R_DIR_NOT_FOUND; + + /* don't find subc poly points even as subc part unless we are editing a subc */ + if (!PCB->loose_subc) + return RND_R_DIR_NOT_FOUND; + } + + for(n = 0; n < 4; n++) { + d = rnd_distance2(gfx->corner[n].X, gfx->corner[n].Y, PosX, PosY); + if (d < ctx->least) { + ctx->least = d; + *ctx->gfx = gfx; + *ctx->Point = &gfx->corner[n]; + ctx->found = rnd_true; + } + } + + return RND_R_DIR_NOT_FOUND; +} + +static rnd_bool SearchGfxPointByLocation(unsigned long Type, unsigned long objst, unsigned long req_flag, pcb_layer_t **Layer, pcb_gfx_t **gfx, rnd_point_t **Point) +{ + gfxptcb_t ctx; + + *Layer = SearchLayer; + ctx.Type = Type; + ctx.gfx = gfx; + ctx.Point = Point; + ctx.found = rnd_false;; + ctx.least = SearchRadius + RND_MAX_POLYGON_POINT_DISTANCE; + ctx.least = ctx.least * ctx.least; + rnd_r_search(SearchLayer->gfx_tree, &SearchBox, NULL, gfxpoint_callback, &ctx, NULL); + + if (ctx.found) + return rnd_true; + return rnd_false; +} + + +static rnd_r_dir_t subc_callback(const rnd_box_t *box, void *cl) +{ + pcb_subc_t *subc = (pcb_subc_t *) box; + struct ans_info *i = (struct ans_info *) cl; + double newarea; + int subc_on_bottom = 0, front; + + pcb_subc_get_side(subc, &subc_on_bottom); + front = subc_on_bottom == conf_core.editor.show_solder_side; + + TEST_OBJST(i->objst, i->req_flag, g, subc, subc); + + if ((front || i->BackToo) && PCB_POINT_IN_BOX(PosX, PosY, &subc->BoundingBox)) { + rnd_coord_t ox, oy; + if ((subc->extobj != NULL) && (pcb_subc_get_origin(subc, &ox, &oy) == 0)) { + /* extended objects are special case: only the origin should be clickable + to avoid problems with large extended objects that cover the board */ + if ((PosX < ox) || (PosX > ox + PCB_SUBC_AUX_UNIT) || (PosY < oy) || (PosY > oy + PCB_SUBC_AUX_UNIT)) + return RND_R_DIR_NOT_FOUND; + } + /* use the subcircuit with the smallest bounding box */ + newarea = (subc->BoundingBox.X2 - subc->BoundingBox.X1) * (double) (subc->BoundingBox.Y2 - subc->BoundingBox.Y1); + if (newarea < i->area) { + i->area = newarea; + *i->ptr1 = *i->ptr2 = *i->ptr3 = subc; + return RND_R_DIR_FOUND_CONTINUE; + } + } + return RND_R_DIR_NOT_FOUND; +} + + +/* --------------------------------------------------------------------------- + * searches a subcircuit + * if more than one subc matches, the smallest one is taken + */ +static rnd_bool +SearchSubcByLocation(unsigned long objst, unsigned long req_flag, pcb_subc_t **subc, pcb_subc_t ** Dummy1, pcb_subc_t ** Dummy2, rnd_bool BackToo) +{ + struct ans_info info; + + /* Both package layers have to be switched on */ + info.ptr1 = (void **) subc; + info.ptr2 = (void **) Dummy1; + info.ptr3 = (void **) Dummy2; + info.area = RND_SQUARE(RND_MAX_COORD); + info.BackToo = (BackToo && PCB->InvisibleObjectsOn); + info.objst = objst; + info.req_flag = req_flag; + + if (rnd_r_search(PCB->Data->subc_tree, &SearchBox, NULL, subc_callback, &info, NULL)) + return rnd_true; + return rnd_false; +} + +/* find the first floater on any layer */ +static rnd_bool SearchSubcFloaterByLocation(unsigned long objst, unsigned long req_flag, pcb_subc_t **out_subc, pcb_text_t **out_txt, void **dummy, rnd_bool other_side) +{ + rnd_rtree_it_t it; + void *obj; + int n; + pcb_layer_type_t my_side_lyt; + + if (other_side) + my_side_lyt = conf_core.editor.show_solder_side ? PCB_LYT_TOP : PCB_LYT_BOTTOM; + else + my_side_lyt = conf_core.editor.show_solder_side ? PCB_LYT_BOTTOM : PCB_LYT_TOP; + + for(n = 0; n < PCB->Data->LayerN; n++) { + pcb_layer_t *ly = &PCB->Data->Layer[n]; + pcb_layer_type_t lyt; + + if ((ly->text_tree == NULL) || (!ly->meta.real.vis)) + continue; + + lyt = pcb_layer_flags_(ly); + if (!(lyt & my_side_lyt)) + continue; + + for(obj = rnd_rtree_first(&it, ly->text_tree, (rnd_rtree_box_t *)&SearchBox); obj != NULL; obj = rnd_rtree_next(&it)) { + pcb_text_t *txt = (pcb_text_t *)obj; + pcb_subc_t *subc; + + if (PCB_FLAG_TEST(PCB_FLAG_FLOATER, txt) == 0) + continue; + + subc = pcb_lobj_parent_subc(txt->parent_type, &txt->parent); + if (subc == NULL) + continue; + + TEST_OBJST_(objst, req_flag, l, txt, subc, continue); + + *out_subc = subc; + *out_txt = txt; + *dummy = txt; + return rnd_true; + } + } + + return rnd_false; +} + +/* for checking if a rat-line end is on a PV */ +rnd_bool pcb_is_point_on_line_end(rnd_coord_t X, rnd_coord_t Y, pcb_rat_t *Line) +{ + if (((X == Line->Point1.X) && (Y == Line->Point1.Y)) || ((X == Line->Point2.X) && (Y == Line->Point2.Y))) + return rnd_true; + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * Calculate the distance (squared) from a point to a line. + * + * let the point be (X,Y) and the line (X1,Y1)(X2,Y2) + * + * Calculate the position along the line that is closest to X,Y. The value + * ranges from 0 to 1 when the point is within the line boundaries with a + * value of 0 being at point X1,Y1 and a value of 1.0 being at point X2,Y2. + * + * t = ((X-X1)*(X2-X1)) + ((Y-Y1)*(Y2-Y1)) + * ----------------------------------- + * (X2-X1)^2 + (Y2-Y1)^2 + * + * let Q be the point of perpendicular projection of (X,Y) onto the line + * + * QX = X1 + t * (X2-X1) + * QY = Y1 + t * (Y2-Y1) + * + * Calculate the distace (squared) using Pythagorean theorem. + * + * distance^2 = (X-QX)^2 + (Y-QY)^2 + */ + +double pcb_point_line_dist2(rnd_coord_t X, rnd_coord_t Y, pcb_line_t *Line) +{ + const double abx = Line->Point2.X - Line->Point1.X; + const double aby = Line->Point2.Y - Line->Point1.Y; + const double apx = X - Line->Point1.X; + const double apy = Y - Line->Point1.Y; + double qx,qy,dx,dy; + + /* Calculate t, the normalised position along the line of the closest point + * to (X,Y). A value between 0 and 1 indicates that the closest point on the + * line is within the bounds of the end points. + */ + double t = ( (apx * abx) + (apy * aby) ) / ( (abx * abx) + (aby * aby) ); + + /* Clamp 't' to the line bounds */ + if(t < 0.0) t = 0.0; + if(t > 1.0) t = 1.0; + + /* Calculate the point Q on the line that is closest to (X,Y) */ + qx = Line->Point1.X + (t * abx); + qy = Line->Point1.Y + (t * aby); + + /* Return the distance from Q to (X,Y), squared */ + dx = X - qx; + dy = Y - qy; + + return (dx * dx) + (dy * dy); +} + +rnd_bool pcb_is_point_on_line(rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Radius, pcb_line_t *Line) +{ + double max = Radius + Line->Thickness / 2; + + return pcb_point_line_dist2(X, Y, Line) < (max * max); +} + +static int is_point_on_line(rnd_coord_t px, rnd_coord_t py, rnd_coord_t lx1, rnd_coord_t ly1, rnd_coord_t lx2, rnd_coord_t ly2) +{ + /* ohh well... let's hope the optimizer does something clever with inlining... */ + pcb_line_t l; + l.Point1.X = lx1; + l.Point1.Y = ly1; + l.Point2.X = lx2; + l.Point2.Y = ly2; + l.Thickness = 1; + return pcb_is_point_on_line(px, py, 1, &l); +} + +rnd_bool pcb_is_point_on_thinline( rnd_coord_t X, rnd_coord_t Y, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2,rnd_coord_t Y2 ) +{ + /* Calculate the cross product of the vector from the first line point to the test point + * and the vector from the first line point to the second line point. If the result is + * not 0 then the point does not lie on the line. + */ + const rnd_coord_t lx = X2 - X1; + const rnd_coord_t ly = Y2 - Y1; + const rnd_coord_t cross = ((X-X1) * ly) - ((Y-Y1) * lx); + + if(cross != 0) + return rnd_false; + + /* If the point does lie on the line then we do a simple check to see if the point is + * between the end points. Use the longest side of the line to perform the check. + */ + if(abs(lx) > abs(ly)) + return (X >= MIN(X1,X2)) && (X <= MAX(X1,X2)) ? rnd_true : rnd_false; + + return (Y >= MIN(Y1,Y2)) && (Y <= MAX(Y1,Y2)) ? rnd_true : rnd_false; +} + +/* checks if a line crosses a rectangle or is within the rectangle */ +rnd_bool pcb_is_line_in_rectangle(rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, pcb_line_t *Line) +{ + pcb_line_t line; + + /* first, see if point 1 is inside the rectangle */ + /* in case the whole line is inside the rectangle */ + if (X1 < Line->Point1.X && X2 > Line->Point1.X && Y1 < Line->Point1.Y && Y2 > Line->Point1.Y) + return rnd_true; + /* construct a set of dummy lines and check each of them */ + line.Thickness = 0; + line.Flags = pcb_no_flags(); + + /* upper-left to upper-right corner */ + line.Point1.Y = line.Point2.Y = Y1; + line.Point1.X = X1; + line.Point2.X = X2; + if (pcb_isc_line_line(pcb_find0, &line, Line)) + return rnd_true; + + /* upper-right to lower-right corner */ + line.Point1.X = X2; + line.Point1.Y = Y1; + line.Point2.Y = Y2; + if (pcb_isc_line_line(pcb_find0, &line, Line)) + return rnd_true; + + /* lower-right to lower-left corner */ + line.Point1.Y = Y2; + line.Point1.X = X1; + line.Point2.X = X2; + if (pcb_isc_line_line(pcb_find0, &line, Line)) + return rnd_true; + + /* lower-left to upper-left corner */ + line.Point2.X = X1; + line.Point1.Y = Y1; + line.Point2.Y = Y2; + if (pcb_isc_line_line(pcb_find0, &line, Line)) + return rnd_true; + + return rnd_false; +} + +/*checks if a point (of null radius) is in a slanted rectangle */ +static int IsPointInQuadrangle(rnd_point_t p[4], rnd_point_t *l) +{ + rnd_coord_t dx, dy, x, y; + double prod0, prod1; + + dx = p[1].X - p[0].X; + dy = p[1].Y - p[0].Y; + x = l->X - p[0].X; + y = l->Y - p[0].Y; + prod0 = (double) x *dx + (double) y *dy; + x = l->X - p[1].X; + y = l->Y - p[1].Y; + prod1 = (double) x *dx + (double) y *dy; + if (prod0 * prod1 <= 0) { + dx = p[1].X - p[2].X; + dy = p[1].Y - p[2].Y; + prod0 = (double) x *dx + (double) y *dy; + x = l->X - p[2].X; + y = l->Y - p[2].Y; + prod1 = (double) x *dx + (double) y *dy; + if (prod0 * prod1 <= 0) + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * checks if a line crosses a quadrangle or is within the quadrangle: almost + * copied from pcb_is_line_in_rectangle() + * Note: actually this quadrangle is a slanted rectangle + */ +rnd_bool pcb_is_line_in_quadrangle(rnd_point_t p[4], pcb_line_t *Line) +{ + pcb_line_t line; + + /* first, see if point 1 is inside the rectangle */ + /* in case the whole line is inside the rectangle */ + if (IsPointInQuadrangle(p, &(Line->Point1))) + return rnd_true; + if (IsPointInQuadrangle(p, &(Line->Point2))) + return rnd_true; + /* construct a set of dummy lines and check each of them */ + line.Thickness = 0; + line.Flags = pcb_no_flags(); + + /* upper-left to upper-right corner */ + line.Point1.X = p[0].X; + line.Point1.Y = p[0].Y; + line.Point2.X = p[1].X; + line.Point2.Y = p[1].Y; + if (pcb_isc_line_line(pcb_find0, &line, Line)) + return rnd_true; + + /* upper-right to lower-right corner */ + line.Point1.X = p[2].X; + line.Point1.Y = p[2].Y; + if (pcb_isc_line_line(pcb_find0, &line, Line)) + return rnd_true; + + /* lower-right to lower-left corner */ + line.Point2.X = p[3].X; + line.Point2.Y = p[3].Y; + if (pcb_isc_line_line(pcb_find0, &line, Line)) + return rnd_true; + + /* lower-left to upper-left corner */ + line.Point1.X = p[0].X; + line.Point1.Y = p[0].Y; + if (pcb_isc_line_line(pcb_find0, &line, Line)) + return rnd_true; + + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * checks if an arc crosses a rectangle (or arc is within the rectangle) + */ +rnd_bool pcb_is_arc_in_rectangle(rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, pcb_arc_t *Arc) +{ + pcb_line_t line; + rnd_coord_t x, y; + rnd_box_t box; + + /* check if any of arc endpoints is inside the rectangle */ + box.X1 = X1; box.Y1 = Y1; + box.X2 = X2; box.Y2 = Y2; + pcb_arc_get_end (Arc, 0, &x, &y); + if (PCB_POINT_IN_BOX(x, y, &box)) + return rnd_true; + pcb_arc_get_end (Arc, 1, &x, &y); + if (PCB_POINT_IN_BOX(x, y, &box)) + return rnd_true; + + /* construct a set of dummy lines and check each of them */ + line.Thickness = 0; + line.Flags = pcb_no_flags(); + + /* upper-left to upper-right corner */ + line.Point1.Y = line.Point2.Y = Y1; + line.Point1.X = X1; + line.Point2.X = X2; + if (pcb_isc_line_arc(pcb_find0, &line, Arc)) + return rnd_true; + + /* upper-right to lower-right corner */ + line.Point1.X = line.Point2.X = X2; + line.Point1.Y = Y1; + line.Point2.Y = Y2; + if (pcb_isc_line_arc(pcb_find0, &line, Arc)) + return rnd_true; + + /* lower-right to lower-left corner */ + line.Point1.Y = line.Point2.Y = Y2; + line.Point1.X = X1; + line.Point2.X = X2; + if (pcb_isc_line_arc(pcb_find0, &line, Arc)) + return rnd_true; + + /* lower-left to upper-left corner */ + line.Point1.X = line.Point2.X = X1; + line.Point1.Y = Y1; + line.Point2.Y = Y2; + if (pcb_isc_line_arc(pcb_find0, &line, Arc)) + return rnd_true; + + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * checks if an gfx crosses a rectangle (or gfx is within the rectangle) + */ +rnd_bool pcb_is_gfx_in_rectangle(const rnd_box_t *b, const pcb_gfx_t *gfx) +{ + pcb_line_t l; + int n, m; + + l.Thickness = 1; + for(n = 0; n < 4; n++) { + m = n+1; + if (m == 4) + m = 0; + l.Point1.X = gfx->corner[n].X; l.Point1.Y = gfx->corner[n].Y; + l.Point2.X = gfx->corner[m].X; l.Point2.Y = gfx->corner[m].Y; + if (PCB_LINE_TOUCHES_BOX(&l, b)) + return rnd_true; + } + + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * Check if a circle of Radius with center at (X, Y) intersects a line. + * Written to enable arbitrary line directions; for rounded/square lines, too. + */ +rnd_bool pcb_is_point_in_line(rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Radius, pcb_any_line_t *Pad) +{ + double r, Sin, Cos; + rnd_coord_t x; + + /* Also used from line_callback with line type smaller than pad type; + use the smallest common subset; ->Thickness is still ok. */ + rnd_coord_t t2 = (Pad->Thickness + 1) / 2, range; + pcb_any_line_t pad = *Pad; + + + /* series of transforms saving range */ + /* move Point1 to the origin */ + X -= pad.Point1.X; + Y -= pad.Point1.Y; + + pad.Point2.X -= pad.Point1.X; + pad.Point2.Y -= pad.Point1.Y; + /* so, pad.Point1.X = pad.Point1.Y = 0; */ + + /* rotate round (0, 0) so that Point2 coordinates be (r, 0) */ + r = rnd_distance(0, 0, pad.Point2.X, pad.Point2.Y); + if (r < .1) { + Cos = 1; + Sin = 0; + } + else { + Sin = pad.Point2.Y / r; + Cos = pad.Point2.X / r; + } + x = X; + X = X * Cos + Y * Sin; + Y = Y * Cos - x * Sin; + /* now pad.Point2.X = r; pad.Point2.Y = 0; */ + + /* take into account the ends */ + if (PCB_FLAG_TEST(PCB_FLAG_SQUARE, Pad)) { + r += Pad->Thickness; + X += t2; + } + if (Y < 0) + Y = -Y; /* range value is evident now */ + + if (PCB_FLAG_TEST(PCB_FLAG_SQUARE, Pad)) { + if (X <= 0) { + if (Y <= t2) + range = -X; + else + return Radius > rnd_distance(0, t2, X, Y); + } + else if (X >= r) { + if (Y <= t2) + range = X - r; + else + return Radius > rnd_distance(r, t2, X, Y); + } + else + range = Y - t2; + } + else { /*Rounded pad: even more simple */ + + if (X <= 0) + return (Radius + t2) > rnd_distance(0, 0, X, Y); + else if (X >= r) + return (Radius + t2) > rnd_distance(r, 0, X, Y); + else + range = Y - t2; + } + return range < Radius; +} + +rnd_bool pcb_is_point_in_box(rnd_coord_t X, rnd_coord_t Y, rnd_box_t *box, rnd_coord_t Radius) +{ + rnd_coord_t width, height, range; + + /* NB: Assumes box has point1 with numerically lower X and Y coordinates */ + + /* Compute coordinates relative to Point1 */ + X -= box->X1; + Y -= box->Y1; + + width = box->X2 - box->X1; + height = box->Y2 - box->Y1; + + if (X <= 0) { + if (Y < 0) + return Radius > rnd_distance(0, 0, X, Y); + else if (Y > height) + return Radius > rnd_distance(0, height, X, Y); + else + range = -X; + } + else if (X >= width) { + if (Y < 0) + return Radius > rnd_distance(width, 0, X, Y); + else if (Y > height) + return Radius > rnd_distance(width, height, X, Y); + else + range = X - width; + } + else { + if (Y < 0) + range = -Y; + else if (Y > height) + range = Y - height; + else + return rnd_true; + } + + return range < Radius; +} + +rnd_bool pcb_arc_in_box(pcb_arc_t *arc, rnd_box_t *b) +{ + rnd_box_t ab = pcb_arc_mini_bbox(arc); + return PCB_BOX_IN_BOX(&ab, b); +} + +rnd_bool pcb_gfx_in_box(pcb_gfx_t *gfx, rnd_box_t *b) +{ + int n; + + for(n = 0; n < 4; n++) + if (!PCB_POINT_IN_BOX(gfx->corner[n].X, gfx->corner[n].Y, b)) + return rnd_false; + + return rnd_true; +} + +/* TODO: this code is BROKEN in the case of non-circular arcs, + * and in the case that the arc thickness is greater than + * the radius. + */ +rnd_bool pcb_is_point_on_arc(rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Radius, pcb_arc_t *Arc) +{ + /* Calculate angle of point from arc center */ + double p_dist = rnd_distance(X, Y, Arc->X, Arc->Y); + double p_cos = (X - Arc->X) / p_dist; + rnd_angle_t p_ang = acos(p_cos) * RND_RAD_TO_DEG; + rnd_angle_t ang1, ang2; +#define angle_in_range(r1, r2, ang) (((ang) >= (r1)) && ((ang) <= (r2))) + + + /* Convert StartAngle, Delta into bounding angles in [0, 720) */ + if (Arc->Delta > 0) { + ang1 = rnd_normalize_angle(Arc->StartAngle); + ang2 = rnd_normalize_angle(Arc->StartAngle + Arc->Delta); + } + else { + ang1 = rnd_normalize_angle(Arc->StartAngle + Arc->Delta); + ang2 = rnd_normalize_angle(Arc->StartAngle); + } + if (ang1 > ang2) + ang2 += 360; + /* Make sure full circles aren't treated as zero-length arcs */ + if (Arc->Delta == 360 || Arc->Delta == -360) + ang2 = ang1 + 360; + + if (Y > Arc->Y) + p_ang = -p_ang; + p_ang += 180; + + + /* Check point is outside arc range, check distance from endpoints + Need to check p_ang+360 too, because after the angle swaps above ang2 + might be larger than 360 and that section of the arc shouldn't be missed + either. */ + if (!angle_in_range(ang1, ang2, p_ang) && !angle_in_range(ang1, ang2, p_ang+360)) { + rnd_coord_t ArcX, ArcY; + ArcX = Arc->X + Arc->Width * cos((Arc->StartAngle + 180) / RND_RAD_TO_DEG); + ArcY = Arc->Y - Arc->Height * sin((Arc->StartAngle + 180) / RND_RAD_TO_DEG); + if (rnd_distance(X, Y, ArcX, ArcY) < Radius + Arc->Thickness / 2) + return rnd_true; + + ArcX = Arc->X + Arc->Width * cos((Arc->StartAngle + Arc->Delta + 180) / RND_RAD_TO_DEG); + ArcY = Arc->Y - Arc->Height * sin((Arc->StartAngle + Arc->Delta + 180) / RND_RAD_TO_DEG); + if (rnd_distance(X, Y, ArcX, ArcY) < Radius + Arc->Thickness / 2) + return rnd_true; + return rnd_false; + } + + if ((Arc->Width == Arc->Height) || (fabs(Arc->Width - Arc->Height) < RND_MM_TO_COORD(0.1))) { + /* Simple circular case: if point is inside the arc range, just compare it to the arc */ + return fabs(rnd_distance(X, Y, Arc->X, Arc->Y) - Arc->Width) < Radius + Arc->Thickness / 2; + } + else { + /* elliptical case: guess where the arc would be in that point, by angle */ + double ang, dx, dy; + rnd_coord_t ax, ay, d; + +TODO(": elliptical arc: rewrite this, as it does not work properly on extreme cases") + dy = (double)(Y - Arc->Y) / (double)Arc->Height; + dx = (double)(X - Arc->X) / (double)Arc->Width; + ang = -atan2(dy, dx); + + ax = Arc->X + cos(ang) * Arc->Width; + ay = Arc->Y - sin(ang) * Arc->Height; + + d = fabs(rnd_distance(X, Y, ax, ay)); + + return d < Arc->Thickness / 2; + } +#undef angle_in_range +} + +rnd_bool pcb_is_point_in_gfx(rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Radius, pcb_gfx_t *gfx) +{ + rnd_vector_t pt, a, b, c; + int n, m; + + pt[0] = X; pt[1] = Y; + a[0] = gfx->corner[0].X; a[1] = gfx->corner[0].Y; + b[0] = gfx->corner[2].X; b[1] = gfx->corner[2].Y; + + c[0] = gfx->corner[1].X; c[1] = gfx->corner[1].Y; + if (rnd_point_in_triangle(a, b, c, pt)) + return rnd_true; + + c[0] = gfx->corner[3].X; c[1] = gfx->corner[3].Y; + if (rnd_point_in_triangle(a, b, c, pt)) + return rnd_true; + + /* the above triangle checks will miss points that are exactly on the triangle edges */ + for(n = 0; n < 4; n++) { + m = n+1; + if (m == 4) + m = 0; + if (pcb_is_point_on_thinline(X, Y, gfx->corner[n].X, gfx->corner[n].Y, gfx->corner[m].X, gfx->corner[m].Y)) + return rnd_true; + } + if (pcb_is_point_on_thinline(X, Y, gfx->corner[0].X, gfx->corner[0].Y, gfx->corner[2].X, gfx->corner[2].Y)) + return rnd_true; + if (pcb_is_point_on_thinline(X, Y, gfx->corner[1].X, gfx->corner[1].Y, gfx->corner[3].X, gfx->corner[3].Y)) + return rnd_true; + + return rnd_false; +} + + +pcb_line_t *pcb_line_center_cross_point(pcb_layer_t *layer, rnd_coord_t x, rnd_coord_t y, rnd_angle_t *ang, rnd_bool no_subc_part, rnd_bool no_term) +{ + rnd_rtree_it_t it; + rnd_rtree_box_t pt; + pcb_line_t *l; + +/* TODO: set pt coords to x and y */ + + for(l = rnd_rtree_first(&it, layer->line_tree, &pt); l != NULL; l = rnd_rtree_next(&it)) { + /* check if line needs to be ignored and "continue;" if so: + l->term is non-NULL if it's a terminal, + pcb_lobj_parent_subc(pcb_parenttype_t pt, pcb_parent_t *p) returns non-NULL if it's in a subc + */ + /* if the line shouldn't be ignored, check if x;y is on the centerline and + "continue;" if bad */ + /* check if angle is required and is correct; "continue;" on mismatch */ + return l; + } + return NULL; /* found nothing */ +} + +pcb_layer_type_t pstk_vis_layers(pcb_board_t *pcb, pcb_layer_type_t material) +{ + pcb_layer_type_t res = 0, lyt; + rnd_layer_id_t lid; + for(lid = 0; lid < pcb->Data->LayerN; lid++) { + pcb_layer_t *ly = &pcb->Data->Layer[lid]; + lyt = pcb_layer_flags_(ly); + if ((ly->meta.real.vis) && (lyt & material)) + res |= (lyt & PCB_LYT_ANYWHERE); + } + return res | material; +} + +static int pcb_search_obj_by_loc_layer(unsigned long Type, void **Result1, void **Result2, void **Result3, unsigned long req_flag, pcb_layer_t *SearchLayer, int HigherAvail, double HigherBound, int objst) +{ + if (SearchLayer->meta.real.vis) { + if ((HigherAvail & (PCB_OBJ_PSTK)) == 0 && + Type & PCB_OBJ_GFX_POINT && + SearchGfxPointByLocation(Type, objst, req_flag, (pcb_layer_t **) Result1, (pcb_gfx_t **) Result2, (rnd_point_t **) Result3)) + return PCB_OBJ_GFX_POINT; + + if ((HigherAvail & (PCB_OBJ_PSTK)) == 0 && + Type & PCB_OBJ_POLY_POINT && + SearchPointByLocation(Type, objst, req_flag, (pcb_layer_t **) Result1, (pcb_poly_t **) Result2, (rnd_point_t **) Result3)) + return PCB_OBJ_POLY_POINT; + + if ((HigherAvail & (PCB_OBJ_PSTK)) == 0 && + Type & PCB_OBJ_LINE_POINT && + SearchLinePointByLocation(objst, req_flag, (pcb_layer_t **) Result1, (pcb_line_t **) Result2, (rnd_point_t **) Result3)) + return PCB_OBJ_LINE_POINT; + + if ((HigherAvail & (PCB_OBJ_PSTK)) == 0 && + Type & PCB_OBJ_ARC_POINT && + SearchArcPointByLocation(objst, req_flag, (pcb_layer_t **) Result1, (pcb_arc_t **) Result2, (int **) Result3)) + return PCB_OBJ_ARC_POINT; + + if ((HigherAvail & (PCB_OBJ_PSTK)) == 0 && Type & PCB_OBJ_LINE + && SearchLineByLocation(objst, req_flag, (pcb_layer_t **) Result1, (pcb_line_t **) Result2, (pcb_line_t **) Result3)) + return PCB_OBJ_LINE; + + if ((HigherAvail & (PCB_OBJ_PSTK)) == 0 && Type & PCB_OBJ_ARC && + SearchArcByLocation(objst, req_flag, (pcb_layer_t **) Result1, (pcb_arc_t **) Result2, (pcb_arc_t **) Result3)) + return PCB_OBJ_ARC; + + if ((HigherAvail & (PCB_OBJ_PSTK)) == 0 && Type & PCB_OBJ_TEXT + && SearchTextByLocation(objst, req_flag, (pcb_layer_t **) Result1, (pcb_text_t **) Result2, (pcb_text_t **) Result3)) + return PCB_OBJ_TEXT; + + if (Type & PCB_OBJ_POLY && + SearchPolygonByLocation(objst, req_flag, (pcb_layer_t **) Result1, (pcb_poly_t **) Result2, (pcb_poly_t **) Result3)) { + if (HigherAvail) { + rnd_box_t *box = &(*(pcb_poly_t **) Result2)->BoundingBox; + double area = (double) (box->X2 - box->X1) * (double) (box->X2 - box->X1); + if (HigherBound < area) + return -1; + else + return PCB_OBJ_POLY; + } + else + return PCB_OBJ_POLY; + } + + if ((HigherAvail & (PCB_OBJ_PSTK)) == 0 && Type & PCB_OBJ_GFX && + SearchGfxByLocation(objst, req_flag, (pcb_layer_t **)Result1, (pcb_gfx_t **)Result2, (pcb_gfx_t **)Result3)) + return PCB_OBJ_GFX; + + } + return 0; +} + +static int pcb_search_obj_by_loc_group(unsigned long Type, void **Result1, void **Result2, void **Result3, unsigned long req_flag, const pcb_layergrp_t *grp, int HigherAvail, double HigherBound, int objst) +{ + rnd_cardinal_t n; + for(n = 0; n < grp->len; n++) { + int found; + pcb_layer_t *oldly, *layer = pcb_get_layer(PCB->Data, grp->lid[n]); + if (layer == NULL) + continue; + oldly = SearchLayer; + SearchLayer = layer; + found = pcb_search_obj_by_loc_layer(Type, Result1, Result2, Result3, req_flag, layer, HigherAvail, HigherBound, objst); + SearchLayer = oldly; + if (found != 0) + return found; + } + return 0; +} + +static int pcb_search_obj_by_loc_group_id(unsigned long Type, void **Result1, void **Result2, void **Result3, unsigned long req_flag, const rnd_layergrp_id_t gid, int HigherAvail, double HigherBound, int objst) +{ + pcb_layergrp_t *grp = pcb_get_layergrp(PCB, gid); + if (grp == NULL) + return 0; + return pcb_search_obj_by_loc_group(Type, Result1, Result2, Result3, req_flag, grp, HigherAvail, HigherBound, objst); +} + + +/* --------------------------------------------------------------------------- + * searches for any kind of object or for a set of object types + * the calling routine passes two pointers to allocated memory for storing + * the results. + * A type value is returned too which is PCB_OBJ_VOID if no objects has been found. + * A set of object types is passed in. + * The object is located by it's position. + * + * The layout is checked in the following order: + * polygon-point, padstack, line, text, polygon, subcircuit + * + * Note that if Type includes PCB_OBJ_LOCKED, then the search includes + * locked items. Otherwise, locked items are ignored. + + * Note that if Type includes PCB_OBJ_SUBC_PART, then the search includes + * objects that are part of subcircuits, else they are ignored. + */ +static int pcb_search_obj_by_location_(unsigned long Type, void **Result1, void **Result2, void **Result3, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Radius, unsigned long req_flag) +{ + void *r1, *r2, *r3; + void **pr1 = &r1, **pr2 = &r2, **pr3 = &r3; + int i; + double HigherBound = 0; + int HigherAvail = PCB_OBJ_VOID; + int objst = Type & (PCB_OBJ_LOCKED | PCB_OBJ_SUBC_PART); + + /* setup variables used by local functions */ + PosX = X; + PosY = Y; + SearchRadius = Radius; + if (Radius) { + SearchBox.X1 = X - Radius; + SearchBox.Y1 = Y - Radius; + SearchBox.X2 = X + Radius; + SearchBox.Y2 = Y + Radius; + } + else { + SearchBox = rnd_point_box(X, Y); + } + + if (conf_core.editor.only_names) { + Type &= PCB_OBJ_TEXT; + } + + if (conf_core.editor.thin_draw || conf_core.editor.thin_draw_poly) { + Type &= ~PCB_OBJ_POLY; + } + + if (Type & PCB_OBJ_RAT && PCB->RatOn && + SearchRatLineByLocation(objst, req_flag, (pcb_rat_t **) Result1, (pcb_rat_t **) Result2, (pcb_rat_t **) Result3)) + return PCB_OBJ_RAT; + + if (Type & PCB_OBJ_PSTK && SearchPadstackByLocation(objst, req_flag, (pcb_pstk_t **) Result1, (pcb_pstk_t **) Result2, (pcb_pstk_t **) Result3, 1, 0)) + return PCB_OBJ_PSTK; + + if (Type & PCB_OBJ_PSTK && SearchPadstackByLocation(objst, req_flag, (pcb_pstk_t **) Result1, (pcb_pstk_t **) Result2, (pcb_pstk_t **) Result3, 0, PCB_LYT_VISIBLE_SIDE() | PCB_LYT_COPPER)) + return PCB_OBJ_PSTK; + + if (Type & PCB_OBJ_PSTK && SearchPadstackByLocation(objst, req_flag, (pcb_pstk_t **) Result1, (pcb_pstk_t **) Result2, (pcb_pstk_t **) Result3, 0, (PCB_LYT_VISIBLE_SIDE() | PCB_LYT_ANYTHING) & pstk_vis_layers(PCB, PCB_LYT_ANYTHING))) + return PCB_OBJ_PSTK; + + if (Type & PCB_OBJ_PSTK && SearchPadstackByLocation(objst, req_flag, (pcb_pstk_t **) Result1, (pcb_pstk_t **) Result2, (pcb_pstk_t **) Result3, 0, pstk_vis_layers(PCB, PCB_LYT_MASK))) + return PCB_OBJ_PSTK; + + if (Type & PCB_OBJ_PSTK && SearchPadstackByLocation(objst, req_flag, (pcb_pstk_t **) Result1, (pcb_pstk_t **) Result2, (pcb_pstk_t **) Result3, 0, pstk_vis_layers(PCB, PCB_LYT_COPPER))) + return PCB_OBJ_PSTK; + + if (Type & PCB_OBJ_PSTK && SearchPadstackByLocation(objst, req_flag, (pcb_pstk_t **) Result1, (pcb_pstk_t **) Result2, (pcb_pstk_t **) Result3, 0, pstk_vis_layers(PCB, PCB_LYT_PASTE))) + return PCB_OBJ_PSTK; + + if (!HigherAvail && (Type & PCB_OBJ_FLOATER) && (Type & PCB_OBJ_TEXT) && + SearchSubcFloaterByLocation(objst, req_flag, (pcb_subc_t **)pr1, (pcb_text_t **) pr2, pr3, rnd_false)) { + *Result1 = ((pcb_text_t *)r2)->parent.layer; + *Result2 = r2; + *Result3 = r3; + return PCB_OBJ_TEXT; + } + + if (!HigherAvail && Type & PCB_OBJ_SUBC && PCB->SubcOn && + SearchSubcByLocation(objst, req_flag, (pcb_subc_t **) pr1, (pcb_subc_t **) pr2, (pcb_subc_t **) pr3, rnd_false)) { + rnd_box_t *box = &((pcb_subc_t *) r1)->BoundingBox; + HigherBound = (double) (box->X2 - box->X1) * (double) (box->Y2 - box->Y1); + HigherAvail = PCB_OBJ_SUBC; + } + + { /* search the front silk layer first */ + int found; + rnd_layergrp_id_t front_silk_id = conf_core.editor.show_solder_side ? pcb_layergrp_get_bottom_silk() : pcb_layergrp_get_top_silk(); + found = pcb_search_obj_by_loc_group_id(Type, Result1, Result2, Result3, req_flag, front_silk_id, HigherAvail, HigherBound, objst); + if (found > 0) + return found; + } + + for(i = 0; i < pcb_max_layer(PCB); i++) { + int found; + if (pcb_layer_flags(PCB, i) & PCB_LYT_SILK) /* special order: silks are searched before/after this loop, if we meet them elsewhere, skip */ + continue; + SearchLayer = PCB_STACKLAYER(PCB, i); + + found = pcb_search_obj_by_loc_layer(Type, Result1, Result2, Result3, req_flag, SearchLayer, HigherAvail, HigherBound, objst); + if (found < 0) + break; + if (found != 0) + return found; + } + + if (PCB->InvisibleObjectsOn) { /* search the back silk layer last, unless it's invisible */ + int found; + rnd_layergrp_id_t back_silk_id = conf_core.editor.show_solder_side ? pcb_layergrp_get_top_silk() : pcb_layergrp_get_bottom_silk(); + found = pcb_search_obj_by_loc_group_id(Type, Result1, Result2, Result3, req_flag, back_silk_id, HigherAvail, HigherBound, objst); + if (found > 0) + return found; + } + + + /* return any previously found objects */ + if (HigherAvail & PCB_OBJ_PSTK) { + *Result1 = r1; + *Result2 = r2; + *Result3 = r3; + return PCB_OBJ_PSTK; + } + + if (HigherAvail & PCB_OBJ_SUBC) { + *Result1 = r1; + *Result2 = r2; + *Result3 = r3; + return PCB_OBJ_SUBC; + } + + /* search the 'invisible objects' last */ + if (!PCB->InvisibleObjectsOn) + return PCB_OBJ_VOID; + + if ((Type & PCB_OBJ_FLOATER) && (Type & PCB_OBJ_TEXT) && + SearchSubcFloaterByLocation(objst, req_flag, (pcb_subc_t **)pr1, (pcb_text_t **) pr2, pr3, rnd_true)) { + *Result1 = ((pcb_text_t *)r2)->parent.layer; + *Result2 = r2; + *Result3 = r3; + return PCB_OBJ_TEXT; + } + + if (Type & PCB_OBJ_SUBC && PCB->SubcOn && + SearchSubcByLocation(objst, req_flag, (pcb_subc_t **) Result1, (pcb_subc_t **) Result2, (pcb_subc_t **) Result3, rnd_true)) + return PCB_OBJ_SUBC; + + return PCB_OBJ_VOID; +} + +int pcb_search_obj_by_location(unsigned long Type, void **Result1, void **Result2, void **Result3, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Radius) +{ + int res; + + if ((conf_core.editor.lock_names) || (conf_core.editor.hide_names)) + Type &= ~ PCB_OBJ_FLOATER; + + res = pcb_search_obj_by_location_(Type, Result1, Result2, Result3, X, Y, Radius, 0); + if ((res != PCB_OBJ_VOID) && (res != PCB_OBJ_SUBC)) + return res; + + /* found a subc because it was still the best option over all the plain + objects; if floaters can be found, repeat the search on them, they + have higher prio than subc, but lower prio than plain objects */ + if ((!conf_core.editor.lock_names) && (!conf_core.editor.hide_names)) { + int fres; + void *fr1, *fr2, *fr3; + Type &= ~PCB_OBJ_SUBC; + Type |= PCB_OBJ_SUBC_PART; + fres = pcb_search_obj_by_location_(Type, &fr1, &fr2, &fr3, X, Y, Radius, PCB_FLAG_FLOATER); + if (fres != PCB_OBJ_VOID) { + *Result1 = fr1; + *Result2 = fr2; + *Result3 = fr3; + return fres; + } + } + + return res; +} + + +/* --------------------------------------------------------------------------- + * searches for a object by it's unique ID. It doesn't matter if + * the object is visible or not. The search is performed on a PCB, a + * buffer or on the remove list. + * The calling routine passes two pointers to allocated memory for storing + * the results. + * A type value is returned too which is PCB_OBJ_VOID if no objects has been found. + */ +int pcb_search_obj_by_id_(pcb_data_t *Base, void **Result1, void **Result2, void **Result3, int ID, int type) +{ + if (type == PCB_OBJ_LINE || type == PCB_OBJ_LINE_POINT) { + PCB_LINE_ALL_LOOP(Base); + { + if (line->ID == ID) { + *Result1 = (void *) layer; + *Result2 = *Result3 = (void *) line; + return PCB_OBJ_LINE; + } + if (line->Point1.ID == ID) { + *Result1 = (void *) layer; + *Result2 = (void *) line; + *Result3 = (void *) &line->Point1; + return PCB_OBJ_LINE_POINT; + } + if (line->Point2.ID == ID) { + *Result1 = (void *) layer; + *Result2 = (void *) line; + *Result3 = (void *) &line->Point2; + return PCB_OBJ_LINE_POINT; + } + } + PCB_ENDALL_LOOP; + } + if (type == PCB_OBJ_ARC || type == PCB_OBJ_ARC_POINT) { + PCB_ARC_ALL_LOOP(Base); + { + if (arc->ID == ID) { + *Result1 = (void *) layer; + *Result2 = *Result3 = (void *) arc; + return PCB_OBJ_ARC; + } + } + PCB_ENDALL_LOOP; + } + + if (type == PCB_OBJ_TEXT) { + PCB_TEXT_ALL_LOOP(Base); + { + if (text->ID == ID) { + *Result1 = (void *) layer; + *Result2 = *Result3 = (void *) text; + return PCB_OBJ_TEXT; + } + } + PCB_ENDALL_LOOP; + } + + if (type == PCB_OBJ_POLY || type == PCB_OBJ_POLY_POINT) { + PCB_POLY_ALL_LOOP(Base); + { + if (polygon->ID == ID) { + *Result1 = (void *) layer; + *Result2 = *Result3 = (void *) polygon; + return PCB_OBJ_POLY; + } + if (type == PCB_OBJ_POLY_POINT) + PCB_POLY_POINT_LOOP(polygon); + { + if (point->ID == ID) { + *Result1 = (void *) layer; + *Result2 = (void *) polygon; + *Result3 = (void *) point; + return PCB_OBJ_POLY_POINT; + } + } + PCB_END_LOOP; + } + PCB_ENDALL_LOOP; + } + + if ((type == PCB_OBJ_GFX) || (type == PCB_OBJ_GFX_POINT)) { + PCB_GFX_ALL_LOOP(Base); + { + if (gfx->ID == ID) { + *Result1 = (void *)layer; + *Result2 = *Result3 = (void *)gfx; + return PCB_OBJ_GFX; + } + if (type == PCB_OBJ_GFX_POINT) { + TODO("gfx: id on point?"); + } + } + PCB_ENDALL_LOOP; + } + + if (type == PCB_OBJ_PSTK) { + PCB_PADSTACK_LOOP(Base); + { + if (padstack->ID == ID) { + *Result1 = *Result2 = *Result3 = (void *)padstack; + return PCB_OBJ_PSTK; + } + } + PCB_END_LOOP; + } + + if (type == PCB_OBJ_RAT || type == PCB_OBJ_LINE_POINT) { + PCB_RAT_LOOP(Base); + { + if (line->ID == ID) { + *Result1 = *Result2 = *Result3 = (void *) line; + return PCB_OBJ_RAT; + } + if (line->Point1.ID == ID) { + *Result1 = (void *) NULL; + *Result2 = (void *) line; + *Result3 = (void *) &line->Point1; + return PCB_OBJ_LINE_POINT; + } + if (line->Point2.ID == ID) { + *Result1 = (void *) NULL; + *Result2 = (void *) line; + *Result3 = (void *) &line->Point2; + return PCB_OBJ_LINE_POINT; + } + } + PCB_END_LOOP; + } + +TODO("subc: once elements are gone, rewrite these to search the rtree instead of recursion") + PCB_SUBC_LOOP(Base); + { + int res; + if (type == PCB_OBJ_SUBC) { + if (subc->ID == ID) { + *Result1 = *Result2 = *Result3 = (void *)subc; + return PCB_OBJ_SUBC; + } + } + + res = pcb_search_obj_by_id_(subc->data, Result1, Result2, Result3, ID, type); + if (res != PCB_OBJ_VOID) + return res; + } + PCB_END_LOOP; + + return PCB_OBJ_VOID; +} + +int pcb_search_obj_by_id(pcb_data_t *Base, void **Result1, void **Result2, void **Result3, int ID, int type) +{ + int res = pcb_search_obj_by_id_(Base, Result1, Result2, Result3, ID, type); + if (res == PCB_OBJ_VOID) + rnd_message(RND_MSG_ERROR, "pcb_search_obj_by_id(): internal error, search for ID %d failed\n", ID); + return res; +} + +int pcb_search_obj_by_id_buf2(pcb_data_t *Base, void **Result1, void **Result2, void **Result3, int ID, int type) +{ + int bid = 0; + long res; + + res = pcb_search_obj_by_id_(Base, Result1, Result2, Result3, ID, type); + if (res != PCB_OBJ_VOID) + return res; + + while(res == PCB_OBJ_VOID) { + res = pcb_search_obj_by_id_(pcb_buffers[bid].Data, Result1, Result2, Result3, ID, type); + if (res != PCB_OBJ_VOID) + return res; + bid++; + if (bid >= PCB_MAX_BUFFER) + break; + } + + rnd_message(RND_MSG_ERROR, "pcb_search_obj_by_id_buf2(): internal error, search for ID %d failed\n", ID); + return PCB_OBJ_VOID; +} + +/* --------------------------------------------------------------------------- + * searches the cursor position for the type + */ +int pcb_search_screen(rnd_coord_t X, rnd_coord_t Y, int Type, void **Result1, void **Result2, void **Result3) +{ + return pcb_search_obj_by_location(Type, Result1, Result2, Result3, X, Y, PCB_SLOP * rnd_pixel_slop); +} + +/* --------------------------------------------------------------------------- + * searches the cursor position for the type + */ +int pcb_search_grid_slop(rnd_coord_t X, rnd_coord_t Y, int Type, void **Result1, void **Result2, void **Result3) +{ + int ans, n; + + for(n = 8; n >= 2; n = n/2) { + ans = pcb_search_obj_by_location(Type, Result1, Result2, Result3, X, Y, PCB->hidlib.grid / n); + if (ans != PCB_OBJ_VOID) return ans; + } + + return ans; +} + +vtp0_t pcb_obj_list_vect; +int pcb_search_screen_selector(rnd_coord_t X, rnd_coord_t Y, int Type, void **Result1, void **Result2, void **Result3) +{ + rnd_box_t box; + rnd_coord_t radius; + pcb_any_obj_t *obj; + + if ((!conf_core.editor.click_objlist) || (!RND_HAVE_GUI_ATTR_DLG)) + return PCB_OBJ_VOID; + + radius = PCB_SLOP * rnd_pixel_slop; + box.X2 = X - radius; + box.Y2 = Y - radius; + box.X1 = X + radius; + box.Y1 = Y + radius; + + vtp0_init(&pcb_obj_list_vect); + pcb_list_block_cb(PCB, &box, (void *(*)(void *, pcb_any_obj_t *))vtp0_append, &pcb_obj_list_vect); + + if (pcb_obj_list_vect.used == 1) { + obj = pcb_obj_list_vect.array[0]; + goto found; + } + + if (pcb_obj_list_vect.used > 1) { + long idx = rnd_actionva(&PCB->hidlib, "dlg_obj_list", NULL); + if ((idx >= 0) && (idx < pcb_obj_list_vect.used)) { + obj = pcb_obj_list_vect.array[idx]; + goto found; + } + } + + vtp0_uninit(&pcb_obj_list_vect); + return PCB_OBJ_VOID; + + found:; + vtp0_uninit(&pcb_obj_list_vect); + *Result1 = obj->parent.any; + *Result2 = *Result3 = obj; + return obj->type; +} + +int pcb_search_screen_maybe_selector(rnd_coord_t X, rnd_coord_t Y, int Type, void **Result1, void **Result2, void **Result3) +{ + int sr = pcb_search_screen_selector(X, Y, Type, Result1, Result2, Result3); + if (sr != PCB_OBJ_VOID) return sr; + return pcb_search_screen(X, Y, Type, Result1, Result2, Result3); +} + + +int pcb_lines_intersect_at(rnd_coord_t ax1, rnd_coord_t ay1, rnd_coord_t ax2, rnd_coord_t ay2, rnd_coord_t bx1, rnd_coord_t by1, rnd_coord_t bx2, rnd_coord_t by2, rnd_coord_t *iscx, rnd_coord_t *iscy) +{ +/* TODO: this should be long double if rnd_coord_t is 64 bits */ + double ua, xi, yi, X1, Y1, X2, Y2, X3, Y3, X4, Y4, tmp; + int is_a_pt, is_b_pt; + + /* degenerate cases: a line is actually a point */ + is_a_pt = (ax1 == ax2) && (ay1 == ay2); + is_b_pt = (bx1 == bx2) && (by1 == by2); + + if (is_a_pt && is_b_pt) + return (ax1 == bx1) && (ay1 == by1); + + if (is_a_pt) + return is_point_on_line(ax1, ay1, bx1, by1, bx2, by2); + if (is_b_pt) + return is_point_on_line(bx1, by1, ax1, ay1, ax2, ay2); + + /* maths from http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ */ + + X1 = ax1; + X2 = ax2; + X3 = bx1; + X4 = bx2; + Y1 = ay1; + Y2 = ay2; + Y3 = by1; + Y4 = by2; + + tmp = ((Y4 - Y3) * (X2 - X1) - (X4 - X3) * (Y2 - Y1)); + + if (tmp == 0) { + /* Corner case: parallel lines; intersect only if the endpoint of either line + is on the other line */ + return + is_point_on_line(ax1, ay1, bx1, by1, bx2, by2) || + is_point_on_line(ax2, ay2, bx1, by1, bx2, by2) || + is_point_on_line(bx1, by1, ax1, ay1, ax2, ay2) || + is_point_on_line(bx2, by2, ax1, ay1, ax2, ay2); + } + + + ua = ((X4 - X3) * (Y1 - Y3) - (Y4 - Y3) * (X1 - X3)) / tmp; +/* ub = ((X2 - X1) * (Y1 - Y3) - (Y2 - Y1) * (X1 - X3)) / tmp;*/ + xi = X1 + ua * (X2 - X1); + yi = Y1 + ua * (Y2 - Y1); + + if (iscx != NULL) + *iscx = xi; + if (iscy != NULL) + *iscy = yi; + +#define check(e1, e2, i) \ + if (e1 < e2) { \ + if ((i < e1) || (i > e2)) \ + return 0; \ + } \ + else { \ + if ((i > e1) || (i < e2)) \ + return 0; \ + } + + check(ax1, ax2, xi); + check(bx1, bx2, xi); + check(ay1, ay2, yi); + check(by1, by2, yi); + return 1; +} + +int pcb_lines_intersect(rnd_coord_t ax1, rnd_coord_t ay1, rnd_coord_t ax2, rnd_coord_t ay2, rnd_coord_t bx1, rnd_coord_t by1, rnd_coord_t bx2, rnd_coord_t by2) +{ + return pcb_lines_intersect_at(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2, NULL, NULL); +} + +rnd_r_dir_t pcb_search_data_by_loc(pcb_data_t *data, pcb_objtype_t type, const rnd_box_t *query_box, rnd_r_dir_t (*cb_)(void *closure, pcb_any_obj_t *obj, void *box), void *closure) +{ + pcb_layer_t *ly; + rnd_layer_id_t lid; + rnd_r_dir_t res; + const rnd_rtree_box_t *query = (const rnd_rtree_box_t *)query_box; + rnd_rtree_dir_t (*cb)(void *, void *, const rnd_rtree_box_t *) = (rnd_rtree_dir_t(*)(void *, void *, const rnd_rtree_box_t *))cb_; + + if ((type & PCB_OBJ_PSTK) && (data->padstack_tree != NULL)) { + res = rnd_rtree_search_any(data->padstack_tree, query, NULL, cb, closure, NULL); + if (res & rnd_RTREE_DIR_STOP) + return res; + } + + if ((type & PCB_OBJ_SUBC) && (data->subc_tree != NULL)) { + res = rnd_rtree_search_any(data->subc_tree, query, NULL, cb, closure, NULL); + if (res & rnd_RTREE_DIR_STOP) + return res; + } + + if ((type & PCB_OBJ_RAT) && (data->rat_tree != NULL)) { + res = rnd_rtree_search_any(data->rat_tree, query, NULL, cb, closure, NULL); + if (res & rnd_RTREE_DIR_STOP) + return res; + } + + for(lid = 0, ly = data->Layer; lid < data->LayerN; lid++,ly++) { + + if ((type & PCB_OBJ_ARC) && (ly->arc_tree != NULL)) { + res = rnd_rtree_search_any(ly->arc_tree, query, NULL, cb, closure, NULL); + if (res & rnd_RTREE_DIR_STOP) + return res; + } + if ((type & PCB_OBJ_LINE) && (ly->line_tree != NULL)) { + res = rnd_rtree_search_any(ly->line_tree, query, NULL, cb, closure, NULL); + if (res & rnd_RTREE_DIR_STOP) + return res; + } + if ((type & PCB_OBJ_POLY) && (ly->polygon_tree != NULL)) { + res = rnd_rtree_search_any(ly->polygon_tree, query, NULL, cb, closure, NULL); + if (res & rnd_RTREE_DIR_STOP) + return res; + } + if ((type & PCB_OBJ_TEXT) && (ly->text_tree != NULL)) { + res = rnd_rtree_search_any(ly->text_tree, query, NULL, cb, closure, NULL); + if (res & rnd_RTREE_DIR_STOP) + return res; + } + if ((type & PCB_OBJ_GFX) && (ly->gfx_tree != NULL)) { + res = rnd_rtree_search_any(ly->gfx_tree, query, NULL, cb, closure, NULL); + if (res & rnd_RTREE_DIR_STOP) + return res; + } + + } + return 0; +} + Index: tags/2.3.0/src/search.h =================================================================== --- tags/2.3.0/src/search.h (nonexistent) +++ tags/2.3.0/src/search.h (revision 33253) @@ -0,0 +1,216 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Search object by location routines */ + +#ifndef PCB_SEARCH_H +#define PCB_SEARCH_H + +#include +#include "layer.h" + +int pcb_lines_intersect_at(rnd_coord_t ax1, rnd_coord_t ay1, rnd_coord_t ax2, rnd_coord_t ay2, rnd_coord_t bx1, rnd_coord_t by1, rnd_coord_t bx2, rnd_coord_t by2, rnd_coord_t *iscx, rnd_coord_t *iscy); +int pcb_lines_intersect(rnd_coord_t ax1, rnd_coord_t ay1, rnd_coord_t ax2, rnd_coord_t ay2, rnd_coord_t bx1, rnd_coord_t by1, rnd_coord_t bx2, rnd_coord_t by2); +rnd_bool pcb_arc_in_box(pcb_arc_t *arc, rnd_box_t *b); +rnd_bool pcb_gfx_in_box(pcb_gfx_t *gfx, rnd_box_t *b); + +#define PCB_SLOP 5 + +/* --------------------------------------------------------------------------- + * some define to check for 'type' in box + */ +#define PCB_POINT_IN_BOX(x,y,b) \ + (PCB_IS_BOX_NEGATIVE(b) ? \ + ((x) >= (b)->X2 && (x) <= (b)->X1 && (y) >= (b)->Y2 && (y) <= (b)->Y1) \ + : \ + ((x) >= (b)->X1 && (x) <= (b)->X2 && (y) >= (b)->Y1 && (y) <= (b)->Y2)) + +#define PCB_VIA_OR_PIN_IN_BOX(v,b) \ + ( \ + PCB_POINT_IN_BOX((v)->X-(v)->Thickness/2,(v)->Y-(v)->Thickness/2,(b)) && \ + PCB_POINT_IN_BOX((v)->X+(v)->Thickness/2,(v)->Y+(v)->Thickness/2,(b)) \ + ) + +#define PCB_LINE_IN_BOX(l,b) \ + (PCB_POINT_IN_BOX((l)->Point1.X,(l)->Point1.Y,(b)) && \ + PCB_POINT_IN_BOX((l)->Point2.X,(l)->Point2.Y,(b))) + +#define PCB_PAD_IN_BOX(p,b) PCB_LINE_IN_BOX((pcb_line_t *)(p),(b)) + +#define PCB_BOX_IN_BOX(b1,b) \ + ((b1)->X1 >= (b)->X1 && (b1)->X2 <= (b)->X2 && \ + ((b1)->Y1 >= (b)->Y1 && (b1)->Y2 <= (b)->Y2)) + +#define PCB_TEXT_IN_BOX(t,b) \ + (PCB_BOX_IN_BOX(&((t)->BoundingBox), (b))) + +#define PCB_POLYGON_IN_BOX(p,b) \ + (PCB_BOX_IN_BOX(&((p)->BoundingBox), (b))) + +#define PCB_SUBC_IN_BOX(s,b) \ + (PCB_BOX_IN_BOX(&((s)->BoundingBox), (b))) + +#define PCB_ELEMENT_IN_BOX(e,b) \ + (PCB_BOX_IN_BOX(&((e)->BoundingBox), (b))) + +/* the bounding box is much larger than the minimum, use it to decide it + it is worth doing the expensive precise calculations */ +#define PCB_ARC_IN_BOX(a,b) \ + ((PCB_BOX_TOUCHES_BOX(&((a)->BoundingBox), (b))) && (pcb_arc_in_box(a,b))) + +#define PCB_GFX_IN_BOX(g,b) \ + ((PCB_BOX_TOUCHES_BOX(&((g)->BoundingBox), (b))) && (pcb_gfx_in_box(g,b))) + +/* == the same but accept if any part of the object touches the box == */ +#define PCB_POINT_IN_CIRCLE(x, y, cx, cy, r) \ + (rnd_distance2(x, y, cx, cy) <= (double)(r) * (double)(r)) + +#define PCB_CIRCLE_TOUCHES_BOX(cx, cy, r, b) \ + ( PCB_POINT_IN_BOX((cx)-(r),(cy),(b)) || PCB_POINT_IN_BOX((cx)+(r),(cy),(b)) || PCB_POINT_IN_BOX((cx),(cy)-(r),(b)) || PCB_POINT_IN_BOX((cx),(cy)+(r),(b)) \ + || PCB_POINT_IN_CIRCLE((b)->X1, (b)->Y1, (cx), (cy), (r)) || PCB_POINT_IN_CIRCLE((b)->X2, (b)->Y1, (cx), (cy), (r)) || PCB_POINT_IN_CIRCLE((b)->X1, (b)->Y2, (cx), (cy), (r)) || PCB_POINT_IN_CIRCLE((b)->X2, (b)->Y2, (cx), (cy), (r))) + +#define PCB_VIA_OR_PIN_TOUCHES_BOX(v,b) \ + PCB_CIRCLE_TOUCHES_BOX((v)->X,(v)->Y,((v)->Thickness + (v)->DrillingHole/2),(b)) + +#define PCB_LINE_TOUCHES_BOX(l,b) \ + ( pcb_lines_intersect((l)->Point1.X,(l)->Point1.Y,(l)->Point2.X,(l)->Point2.Y, (b)->X1, (b)->Y1, (b)->X2, (b)->Y1) \ + || pcb_lines_intersect((l)->Point1.X,(l)->Point1.Y,(l)->Point2.X,(l)->Point2.Y, (b)->X1, (b)->Y1, (b)->X1, (b)->Y2) \ + || pcb_lines_intersect((l)->Point1.X,(l)->Point1.Y,(l)->Point2.X,(l)->Point2.Y, (b)->X2, (b)->Y2, (b)->X1, (b)->Y2) \ + || pcb_lines_intersect((l)->Point1.X,(l)->Point1.Y,(l)->Point2.X,(l)->Point2.Y, (b)->X2, (b)->Y2, (b)->X2, (b)->Y1) \ + || PCB_LINE_IN_BOX((l), (b))) + +#define PCB_XYLINE_ISECTS_BOX(x1,y1,x2,y2,b) \ + ( pcb_lines_intersect(x1,y1,x2,y2, (b)->X1, (b)->Y1, (b)->X2, (b)->Y1) \ + || pcb_lines_intersect(x1,y1,x2,y2, (b)->X1, (b)->Y1, (b)->X1, (b)->Y2) \ + || pcb_lines_intersect(x1,y1,x2,y2, (b)->X2, (b)->Y2, (b)->X1, (b)->Y2) \ + || pcb_lines_intersect(x1,y1,x2,y2, (b)->X2, (b)->Y2, (b)->X2, (b)->Y1) \ + ) + +#define PCB_PAD_TOUCHES_BOX(p,b) PCB_LINE_TOUCHES_BOX((pcb_line_t *)(p),(b)) + +/* a corner of either box is within the other, or edges cross */ +#define PCB_BOX_TOUCHES_BOX(b1,b2) \ + ( PCB_POINT_IN_BOX((b1)->X1,(b1)->Y1,b2) || PCB_POINT_IN_BOX((b1)->X1,(b1)->Y2,b2) || PCB_POINT_IN_BOX((b1)->X2,(b1)->Y1,b2) || PCB_POINT_IN_BOX((b1)->X2,(b1)->Y2,b2) \ + || PCB_POINT_IN_BOX((b2)->X1,(b2)->Y1,b1) || PCB_POINT_IN_BOX((b2)->X1,(b2)->Y2,b1) || PCB_POINT_IN_BOX((b2)->X2,(b2)->Y1,b1) || PCB_POINT_IN_BOX((b2)->X2,(b2)->Y2,b1) \ + || pcb_lines_intersect((b1)->X1,(b1)->Y1, (b1)->X2,(b1)->Y1, (b2)->X1,(b2)->Y1, (b2)->X1,(b2)->Y2) \ + || pcb_lines_intersect((b2)->X1,(b2)->Y1, (b2)->X2,(b2)->Y1, (b1)->X1,(b1)->Y1, (b1)->X1,(b1)->Y2)) + +#define PCB_TEXT_TOUCHES_BOX(t,b) \ + (PCB_BOX_TOUCHES_BOX(&((t)->BoundingBox), (b))) + +#define PCB_POLYGON_TOUCHES_BOX(p,b) \ + (pcb_poly_is_rect_in_p((b)->X2, (b)->Y2, (b)->X1, (b)->Y1, (p))) + +#define PCB_SUBC_TOUCHES_BOX(s,b) \ + (PCB_BOX_TOUCHES_BOX(&((s)->BoundingBox), (b))) + +#define PCB_ELEMENT_TOUCHES_BOX(e,b) \ + (PCB_BOX_TOUCHES_BOX(&((e)->BoundingBox), (b))) + +#define PCB_ARC_TOUCHES_BOX(a,b) \ + (pcb_is_arc_in_rectangle((b)->X2, (b)->Y2, (b)->X1, (b)->Y1, (a))) + +#define PCB_GFX_TOUCHES_BOX(a,b) \ + (pcb_is_gfx_in_rectangle((b), (a))) + + +/* == the combination of *_IN_* and *_TOUCHES_*: use IN for positive boxes == */ +#define PCB_IS_BOX_NEGATIVE(b) (((b)->X2 < (b)->X1) || ((b)->Y2 < (b)->Y1)) + +#define PCB_BOX_NEAR_BOX(b1,b) \ + (PCB_IS_BOX_NEGATIVE(b) ? PCB_BOX_TOUCHES_BOX(b1,b) : PCB_BOX_IN_BOX(b1,b)) + +#define PCB_VIA_OR_PIN_NEAR_BOX(v,b) \ + (PCB_IS_BOX_NEGATIVE(b) ? PCB_VIA_OR_PIN_TOUCHES_BOX(v,b) : PCB_VIA_OR_PIN_IN_BOX(v,b)) + +#define PCB_LINE_NEAR_BOX(l,b) \ + (PCB_IS_BOX_NEGATIVE(b) ? PCB_LINE_TOUCHES_BOX(l,b) : PCB_LINE_IN_BOX(l,b)) + +#define PCB_PAD_NEAR_BOX(p,b) \ + (PCB_IS_BOX_NEGATIVE(b) ? PCB_PAD_TOUCHES_BOX(p,b) : PCB_PAD_IN_BOX(p,b)) + +#define PCB_TEXT_NEAR_BOX(t,b) \ + (PCB_IS_BOX_NEGATIVE(b) ? PCB_TEXT_TOUCHES_BOX(t,b) : PCB_TEXT_IN_BOX(t,b)) + +#define PCB_POLYGON_NEAR_BOX(p,b) \ + (PCB_IS_BOX_NEGATIVE(b) ? PCB_POLYGON_TOUCHES_BOX(p,b) : PCB_POLYGON_IN_BOX(p,b)) + +#define PCB_SUBC_NEAR_BOX(s,b) \ + (PCB_IS_BOX_NEGATIVE(b) ? PCB_SUBC_TOUCHES_BOX(s,b) : PCB_SUBC_IN_BOX(s,b)) + +#define PCB_ELEMENT_NEAR_BOX(e,b) \ + (PCB_IS_BOX_NEGATIVE(b) ? PCB_ELEMENT_TOUCHES_BOX(e,b) : PCB_ELEMENT_IN_BOX(e,b)) + +#define PCB_ARC_NEAR_BOX(a,b) \ + (PCB_IS_BOX_NEGATIVE(b) ? PCB_ARC_TOUCHES_BOX(a,b) : PCB_ARC_IN_BOX(a,b)) + +#define PCB_GFX_NEAR_BOX(a,b) \ + (PCB_IS_BOX_NEGATIVE(b) ? PCB_GFX_TOUCHES_BOX(a,b) : PCB_GFX_IN_BOX(a,b)) + +rnd_bool pcb_is_point_on_line(rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Radius, pcb_line_t *Line); +rnd_bool pcb_is_point_on_thinline( rnd_coord_t X, rnd_coord_t Y, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2,rnd_coord_t Y2 ); +rnd_bool pcb_is_point_on_line_end(rnd_coord_t X, rnd_coord_t Y, pcb_rat_t *Line); +rnd_bool pcb_is_point_on_arc(rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Radius, pcb_arc_t *Arc); +rnd_bool pcb_is_point_in_gfx(rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Radius, pcb_gfx_t *gfx); +rnd_bool pcb_is_line_in_rectangle(rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, pcb_line_t *Line); +rnd_bool pcb_is_line_in_quadrangle(rnd_point_t p[4], pcb_line_t *Line); +rnd_bool pcb_is_arc_in_rectangle(rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, pcb_arc_t *Arc); +rnd_bool pcb_is_gfx_in_rectangle(const rnd_box_t *b, const pcb_gfx_t *gfx); +rnd_bool pcb_is_point_in_line(rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Radius, pcb_any_line_t *Pad); +rnd_bool pcb_is_point_in_box(rnd_coord_t X, rnd_coord_t Y, rnd_box_t *box, rnd_coord_t Radius); + +/* Return the distance^2 between a line-center and a point */ +double pcb_point_line_dist2(rnd_coord_t X, rnd_coord_t Y, pcb_line_t *Line); + +/* Return the first line object that has its centerline crossing the point; + if ang is not NULL, only return lines that are pointing in the right + angle (also accept 180 degree rotation) + if no_subc_part is true, ignore lines that are part of subcircuits; + if no_term is true, ignore lines that are terminals */ +pcb_line_t *pcb_line_center_cross_point(pcb_layer_t *layer, rnd_coord_t x, rnd_coord_t y, rnd_angle_t *ang, rnd_bool no_subc_part, rnd_bool no_term); + +int pcb_search_screen(rnd_coord_t X, rnd_coord_t Y, int Type, void **Result1, void **Result2, void **Result3); + +/* If disabled and there's no GUI: return VOID immediatelly; else search + screen at X,Y for any Type; if 0 or 1 found, return immediately. If + there are more hits, present the object selector dialog (modal) */ +int pcb_search_screen_selector(rnd_coord_t X, rnd_coord_t Y, int Type, void **Result1, void **Result2, void **Result3); + +int pcb_search_screen_maybe_selector(rnd_coord_t X, rnd_coord_t Y, int Type, void **Result1, void **Result2, void **Result3); + + +int pcb_search_grid_slop(rnd_coord_t X, rnd_coord_t Y, int Type, void **Result1, void **Result2, void **Result3); +int pcb_search_obj_by_location(unsigned long Type, void **Result1, void **Result2, void **Result3, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Radius); +int pcb_search_obj_by_id(pcb_data_t *Base, void **Result1, void **Result2, void **Result3, int ID, int type); +int pcb_search_obj_by_id_(pcb_data_t *Base, void **Result1, void **Result2, void **Result3, int ID, int type); /* no-hace version */ + +/* Same as pcb_search_obj_by_id, but search in buffers too */ +int pcb_search_obj_by_id_buf2(pcb_data_t *Base, void **Result1, void **Result2, void **Result3, int ID, int type); + +#endif + Index: tags/2.3.0/src/search_r.h =================================================================== --- tags/2.3.0/src/search_r.h (nonexistent) +++ tags/2.3.0/src/search_r.h (revision 33253) @@ -0,0 +1,37 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Search functions with rtree callbacks; implementation: in search.c */ + +#ifndef PCB_SEARCH_R_H +#define PCB_SEARCH_R_H + +#include + +/* Search data for given object types within a box using the usual rtree conventions for the callback */ +rnd_r_dir_t pcb_search_data_by_loc(pcb_data_t *data, pcb_objtype_t type, const rnd_box_t *query_box, rnd_r_dir_t (*cb_)(void *closure, pcb_any_obj_t *obj, void *box), void *closure); + +#endif Index: tags/2.3.0/src/select.c =================================================================== --- tags/2.3.0/src/select.c (nonexistent) +++ tags/2.3.0/src/select.c (revision 33253) @@ -0,0 +1,542 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + + +/* select routines + */ + +#include "config.h" + +#include "conf_core.h" +#include + +#include "board.h" +#include "data.h" +#include "data_it.h" +#include "draw.h" +#include +#include "polygon.h" +#include "search.h" +#include "select.h" +#include "undo.h" +#include "find.h" +#include "extobj.h" +#include + +#include "obj_arc_draw.h" +#include "obj_line_draw.h" +#include "obj_poly_draw.h" +#include "obj_text_draw.h" +#include "obj_rat_draw.h" +#include "obj_pstk_draw.h" +#include "obj_gfx_draw.h" + +#include + +/* --------------------------------------------------------------------------- + * toggles the selection of any kind of object + * the different types are defined by search.h + */ +rnd_bool pcb_select_object(pcb_board_t *pcb) +{ + void *ptr1, *ptr2, *ptr3; + pcb_layer_t *layer; + int type; + + rnd_bool changed = rnd_true; + + type = pcb_search_screen_maybe_selector(pcb_crosshair.X, pcb_crosshair.Y, PCB_SELECT_TYPES | PCB_LOOSE_SUBC(PCB) | PCB_OBJ_FLOATER, &ptr1, &ptr2, &ptr3); + if (type == PCB_OBJ_VOID || PCB_FLAG_TEST(PCB_FLAG_LOCK, (pcb_any_obj_t *) ptr2)) + return rnd_false; + switch (type) { + + case PCB_OBJ_PSTK: + pcb_undo_add_obj_to_flag(ptr1); + PCB_FLAG_TOGGLE(PCB_FLAG_SELECTED, (pcb_pstk_t *) ptr2); + pcb_pstk_invalidate_draw((pcb_pstk_t *) ptr2); + pcb_extobj_sync_floater_flags(pcb, (const pcb_any_obj_t *)ptr2, 1, 1); + break; + + case PCB_OBJ_LINE: + { + pcb_line_t *line = (pcb_line_t *) ptr2; + + layer = (pcb_layer_t *) ptr1; + pcb_undo_add_obj_to_flag(ptr2); + PCB_FLAG_TOGGLE(PCB_FLAG_SELECTED, line); + pcb_line_invalidate_draw(layer, line); + pcb_extobj_sync_floater_flags(pcb, (const pcb_any_obj_t *)line, 1, 1); + break; + } + + case PCB_OBJ_RAT: + { + pcb_rat_t *rat = (pcb_rat_t *) ptr2; + + pcb_undo_add_obj_to_flag(ptr1); + PCB_FLAG_TOGGLE(PCB_FLAG_SELECTED, rat); + pcb_rat_invalidate_draw(rat); + break; + } + + case PCB_OBJ_ARC: + { + pcb_arc_t *arc = (pcb_arc_t *) ptr2; + + layer = (pcb_layer_t *) ptr1; + pcb_undo_add_obj_to_flag(ptr2); + PCB_FLAG_TOGGLE(PCB_FLAG_SELECTED, arc); + pcb_arc_invalidate_draw(layer, arc); + pcb_extobj_sync_floater_flags(pcb, (const pcb_any_obj_t *)arc, 1, 1); + break; + } + + case PCB_OBJ_TEXT: + { + pcb_text_t *text = (pcb_text_t *) ptr2; + + layer = (pcb_layer_t *) ptr1; + pcb_undo_add_obj_to_flag(ptr2); + PCB_FLAG_TOGGLE(PCB_FLAG_SELECTED, text); + pcb_text_invalidate_draw(layer, text); + pcb_extobj_sync_floater_flags(pcb, (const pcb_any_obj_t *)text, 1, 1); + break; + } + + case PCB_OBJ_POLY: + { + pcb_poly_t *poly = (pcb_poly_t *) ptr2; + + layer = (pcb_layer_t *) ptr1; + pcb_undo_add_obj_to_flag(ptr2); + PCB_FLAG_TOGGLE(PCB_FLAG_SELECTED, poly); + pcb_poly_invalidate_draw(layer, poly); + pcb_extobj_sync_floater_flags(pcb, (const pcb_any_obj_t *)poly, 1, 1); + /* changing memory order no longer effects draw order */ + break; + } + + case PCB_OBJ_GFX: + { + pcb_gfx_t *gfx = (pcb_gfx_t *)ptr2; + + layer = (pcb_layer_t *)ptr1; + pcb_undo_add_obj_to_flag(ptr2); + PCB_FLAG_TOGGLE(PCB_FLAG_SELECTED, gfx); + pcb_gfx_invalidate_draw(layer, gfx); + pcb_extobj_sync_floater_flags(pcb, (const pcb_any_obj_t *)gfx, 1, 1); + break; + } + + + case PCB_OBJ_SUBC: + pcb_subc_select(pcb, (pcb_subc_t *) ptr2, PCB_CHGFLG_TOGGLE, 1); + break; + } + pcb_draw(); + pcb_undo_inc_serial(); + return changed; +} + +static void fix_box_dir(rnd_box_t *Box, int force_pos) +{ +#define swap(a,b) \ +do { \ + rnd_coord_t tmp; \ + tmp = a; \ + a = b; \ + b = tmp; \ +} while(0) + + /* If board view is flipped, box coords need to be flipped too to reflect + the on-screen direction of draw */ + if (rnd_conf.editor.view.flip_x) + swap(Box->X1, Box->X2); + if (rnd_conf.editor.view.flip_y) + swap(Box->Y1, Box->Y2); + + if ((force_pos) || (conf_core.editor.selection.disable_negative)) { + if (Box->X1 > Box->X2) + swap(Box->X1, Box->X2); + if (Box->Y1 > Box->Y2) + swap(Box->Y1, Box->Y2); + } + else { + if (conf_core.editor.selection.symmetric_negative) { + if (Box->Y1 > Box->Y2) + swap(Box->Y1, Box->Y2); + } + /* Make sure our negative box is canonical: always from bottom-right to top-left + This limits all possible box coordinate orders to two, one for positive and + one for negative. */ + if (PCB_IS_BOX_NEGATIVE(Box)) { + if (Box->X1 < Box->X2) + swap(Box->X1, Box->X2); + if (Box->Y1 < Box->Y2) + swap(Box->Y1, Box->Y2); + } + } +#undef swap + +} + +/* ---------------------------------------------------------------------- + * selects/unselects or lists visible objects within the passed box + * If len is NULL: + * Flag determines if the block is to be selected or unselected + * returns non-NULL if the state of any object has changed + * if len is non-NULL: + * returns a list of object IDs matched the search and loads len with the + * length of the list. Returns NULL on no match. + */ +TODO("cleanup: should be rewritten with generic ops and rtree") +static long int *ListBlock_(pcb_board_t *pcb, rnd_box_t *Box, rnd_bool Flag, int *len, void *(cb)(void *ctx, pcb_any_obj_t *obj), void *ctx) +{ + int changed = 0; + int used = 0, alloced = 0; + long int *list = NULL; + + fix_box_dir(Box, 0); +/*rnd_printf("box: %mm %mm - %mm %mm [ %d ] %d %d\n", Box->X1, Box->Y1, Box->X2, Box->Y2, PCB_IS_BOX_NEGATIVE(Box), rnd_conf.editor.view.flip_x, rnd_conf.editor.view.flip_y);*/ + +/* append an object to the return list OR set the flag if there's no list */ +#define append_list(undo_type, p1, obj) \ +do { \ + if (len == NULL) { \ + pcb_undo_add_obj_to_flag(obj); \ + PCB_FLAG_ASSIGN(PCB_FLAG_SELECTED, Flag, obj); \ + } \ + else { \ + if (used >= alloced) { \ + alloced += 64; \ + list = realloc(list, sizeof(*list) * alloced); \ + } \ + list[used] = obj->ID; \ + used++; \ + } \ + changed = 1; \ +} while(0) + +#define append(undo_type, p1, obj) \ +do { \ + if (cb != NULL) { \ + cb(ctx, (pcb_any_obj_t *)obj); \ + used++; \ + } \ + else \ + append_list(undo_type, p1, obj); \ +} while(0) + + if (PCB_IS_BOX_NEGATIVE(Box) && ((Box->X1 == Box->X2) || (Box->Y2 == Box->Y1))) { + if (len != NULL) + *len = 0; + return NULL; + } + + if (pcb->RatOn || !Flag) + PCB_RAT_LOOP(pcb->Data); + { + if (PCB_LINE_NEAR_BOX((pcb_line_t *) line, Box) && !PCB_FLAG_TEST(PCB_FLAG_LOCK, line) && PCB_FLAG_TEST(PCB_FLAG_SELECTED, line) != Flag) { + append(PCB_OBJ_RAT, line, line); + if (pcb->RatOn) + pcb_rat_invalidate_draw(line); + } + } + PCB_END_LOOP; + + /* check layers */ + LAYER_LOOP(pcb->Data, pcb_max_layer(PCB)); + { + unsigned int lflg = pcb_layer_flags(pcb, n); + + if ((lflg & PCB_LYT_SILK) && (PCB_LAYERFLG_ON_VISIBLE_SIDE(lflg))) { + if (!(pcb_silk_on(pcb) || !Flag)) + continue; + } + else if ((lflg & PCB_LYT_SILK) && !(PCB_LAYERFLG_ON_VISIBLE_SIDE(lflg))) { + if (!(pcb->InvisibleObjectsOn || !Flag)) + continue; + } + else if (!(layer->meta.real.vis || !Flag)) + continue; + + PCB_LINE_LOOP(layer); + { + if (PCB_LINE_NEAR_BOX(line, Box) + && !PCB_FLAG_TEST(PCB_FLAG_LOCK, line) + && PCB_FLAG_TEST(PCB_FLAG_SELECTED, line) != Flag) { + append(PCB_OBJ_LINE, layer, line); + if (layer->meta.real.vis) + pcb_line_invalidate_draw(layer, line); + } + } + PCB_END_LOOP; + PCB_ARC_LOOP(layer); + { + if (PCB_ARC_NEAR_BOX(arc, Box) + && !PCB_FLAG_TEST(PCB_FLAG_LOCK, arc) + && PCB_FLAG_TEST(PCB_FLAG_SELECTED, arc) != Flag) { + append(PCB_OBJ_ARC, layer, arc); + if (layer->meta.real.vis) + pcb_arc_invalidate_draw(layer, arc); + } + } + PCB_END_LOOP; + PCB_TEXT_LOOP(layer); + { + if (!Flag || pcb_text_is_visible(PCB, layer, text)) { + if (PCB_TEXT_NEAR_BOX(text, Box) + && !PCB_FLAG_TEST(PCB_FLAG_LOCK, text) + && PCB_FLAG_TEST(PCB_FLAG_SELECTED, text) != Flag) { + append(PCB_OBJ_TEXT, layer, text); + if (pcb_text_is_visible(PCB, layer, text)) + pcb_text_invalidate_draw(layer, text); + } + } + } + PCB_END_LOOP; + PCB_POLY_LOOP(layer); + { + if (PCB_POLYGON_NEAR_BOX(polygon, Box) + && !PCB_FLAG_TEST(PCB_FLAG_LOCK, polygon) + && PCB_FLAG_TEST(PCB_FLAG_SELECTED, polygon) != Flag) { + append(PCB_OBJ_POLY, layer, polygon); + if (layer->meta.real.vis) + pcb_poly_invalidate_draw(layer, polygon); + } + } + PCB_END_LOOP; + PCB_GFX_LOOP(layer); + { + if (PCB_GFX_NEAR_BOX(gfx, Box) + && !PCB_FLAG_TEST(PCB_FLAG_LOCK, gfx) + && PCB_FLAG_TEST(PCB_FLAG_SELECTED, gfx) != Flag) { + append(PCB_OBJ_GFX, layer, gfx); + if (layer->meta.real.vis) + pcb_gfx_invalidate_draw(layer, gfx); + } + } + PCB_END_LOOP; + } + PCB_END_LOOP; + + if (PCB->SubcOn) { + PCB_SUBC_LOOP(pcb->Data); + { + if (PCB_SUBC_NEAR_BOX(subc, Box) + && !PCB_FLAG_TEST(PCB_FLAG_LOCK, subc) + && PCB_FLAG_TEST(PCB_FLAG_SELECTED, subc) != Flag) { + + if (len == NULL) { + pcb_subc_select(PCB, subc, Flag, 1); + } + else { + if (used >= alloced) { + alloced += 64; + list = realloc(list, sizeof(*list) * alloced); + } + list[used] = subc->ID; + used++; + } + changed = 1; + DrawSubc(subc); + } + } + PCB_END_LOOP; + } + + /* end with vias */ + if (pcb->pstk_on || !Flag) { + PCB_PADSTACK_LOOP(pcb->Data); + { + if (pcb_pstk_near_box(padstack, Box, NULL) + && !PCB_FLAG_TEST(PCB_FLAG_LOCK, padstack) + && PCB_FLAG_TEST(PCB_FLAG_SELECTED, padstack) != Flag) { + append(PCB_OBJ_PSTK, padstack, padstack); + if (pcb->pstk_on) + pcb_pstk_invalidate_draw(padstack); + } + } + PCB_END_LOOP; + } + + if (changed) { + pcb_draw(); + pcb_undo_inc_serial(); + } + + if (len == NULL) { + static long int non_zero; + return (changed ? &non_zero : NULL); + } + else { + *len = used; + return list; + } +} + +#undef append + +static int pcb_obj_near_box(pcb_any_obj_t *obj, rnd_box_t *box) +{ + switch(obj->type) { + case PCB_OBJ_RAT: + case PCB_OBJ_LINE: return PCB_LINE_NEAR_BOX((pcb_line_t *)obj, box); + case PCB_OBJ_TEXT: return PCB_TEXT_NEAR_BOX((pcb_text_t *)obj, box); + case PCB_OBJ_POLY: return PCB_POLYGON_NEAR_BOX((pcb_poly_t *)obj, box); + case PCB_OBJ_ARC: return PCB_ARC_NEAR_BOX((pcb_arc_t *)obj, box); + case PCB_OBJ_GFX: return PCB_GFX_NEAR_BOX((pcb_gfx_t *)obj, box); + case PCB_OBJ_PSTK: return pcb_pstk_near_box((pcb_pstk_t *)obj, box, NULL); + case PCB_OBJ_SUBC: return PCB_SUBC_NEAR_BOX((pcb_subc_t *)obj, box); + default: return 0; + } +} + +typedef struct { + pcb_board_t *pcb; + rnd_box_t box; + rnd_bool flag; + rnd_bool invert; +} select_ctx_t; + +static rnd_r_dir_t pcb_select_block_cb(const rnd_box_t *box, void *cl) +{ + select_ctx_t *ctx = cl; + pcb_any_obj_t *obj = (pcb_any_obj_t *)box; + + if (!ctx->invert && (PCB_FLAG_TEST(PCB_FLAG_SELECTED, obj) == ctx->flag)) /* cheap check on the flag: don't do anything if the flag is already right */ + return RND_R_DIR_NOT_FOUND; + + /* do not let locked object selected, but allow deselection */ + if ((PCB_FLAG_TEST(PCB_FLAG_LOCK, obj) == rnd_true) && (ctx->flag)) + return RND_R_DIR_NOT_FOUND; + + if (!pcb_obj_near_box(obj, &ctx->box)) /* detailed box matching */ + return RND_R_DIR_NOT_FOUND; + + pcb_undo_add_obj_to_flag((void *)obj); + pcb_draw_obj(obj); + if (ctx->invert) + PCB_FLAG_TOGGLE(PCB_FLAG_SELECTED, obj); + else + PCB_FLAG_ASSIGN(PCB_FLAG_SELECTED, ctx->flag, obj); + pcb_extobj_sync_floater_flags(ctx->pcb, obj, 1, 1); + return RND_R_DIR_FOUND_CONTINUE; +} + +/* ---------------------------------------------------------------------- + * selects/unselects all visible objects within the passed box + * Flag determines if the block is to be selected or unselected + * returns rnd_true if the state of any object has changed + */ +rnd_bool pcb_select_block(pcb_board_t *pcb, rnd_box_t *Box, rnd_bool flag, rnd_bool vis_only, rnd_bool invert) +{ + select_ctx_t ctx; + + fix_box_dir(Box, 0); + + ctx.pcb = pcb; + ctx.box = *Box; + ctx.flag = flag; + ctx.invert = invert; + + fix_box_dir(Box, 1); + + return pcb_data_r_search(pcb->Data, PCB_OBJ_ANY, Box, NULL, pcb_select_block_cb, &ctx, NULL, vis_only) == RND_R_DIR_FOUND_CONTINUE; +} + +/* ---------------------------------------------------------------------- + * List all visible objects within the passed box + */ +long int *pcb_list_block(pcb_board_t *pcb, rnd_box_t *Box, int *len) +{ + return ListBlock_(pcb, Box, 1, len, NULL, NULL); +} + +int pcb_list_block_cb(pcb_board_t *pcb, rnd_box_t *Box, void *(cb)(void *ctx, pcb_any_obj_t *obj), void *ctx) +{ + int len = 0; + ListBlock_(pcb, Box, -1, &len, cb, ctx); + return len; +} + +/* ---------------------------------------------------------------------- + * selects/unselects all objects which were found during a connection scan + * Flag determines if they are to be selected or unselected + * returns rnd_true if the state of any object has changed + * + * text objects and subcircuits cannot be selected by this routine + */ +static rnd_bool pcb_select_connection_(pcb_data_t *data, rnd_bool Flag) +{ + rnd_bool changed = rnd_false; + pcb_any_obj_t *o; + pcb_data_it_t it; + + for(o = pcb_data_first(&it, data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + if (PCB_FLAG_TEST(PCB_FLAG_FOUND, o)) { + pcb_undo_add_obj_to_flag(o); + PCB_FLAG_ASSIGN(PCB_FLAG_SELECTED, Flag, o); + pcb_draw_obj(o); + changed = rnd_true; + } + if ((o->type == PCB_OBJ_SUBC) && (pcb_select_connection_(((pcb_subc_t *)o)->data, Flag))) + changed = rnd_true; + } + + return changed; +} + +rnd_bool pcb_select_connection(pcb_board_t *pcb, rnd_bool Flag) +{ + return pcb_select_connection_(pcb->Data, Flag); +} + +/* --------------------------------------------------------------------------- + * selects objects as defined by Type by name; + * it's a case insensitive match + * returns rnd_true if any object has been selected + */ +#define REGEXEC(arg) \ + (method == PCB_SM_REGEX ? regexec_match_all(regex, (arg)) : strlst_match(pat, (arg))) + +static int regexec_match_all(re_sei_t *preg, const char *string) +{ + return !!re_sei_exec(preg, string); +} + +/* case insensitive match of each item in the array pat against name + returns 1 if any of them matched */ +static int strlst_match(const char **pat, const char *name) +{ + for (; *pat != NULL; pat++) + if (rnd_strcasecmp(*pat, name) == 0) + return 1; + return 0; +} Index: tags/2.3.0/src/select.h =================================================================== --- tags/2.3.0/src/select.h (nonexistent) +++ tags/2.3.0/src/select.h (revision 33253) @@ -0,0 +1,52 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_SELECT_H +#define PCB_SELECT_H + +#include "config.h" +#include "operation.h" + +#define PCB_SELECT_TYPES \ + (PCB_OBJ_LINE | PCB_OBJ_TEXT | PCB_OBJ_POLY | PCB_OBJ_SUBC | \ + PCB_OBJ_PSTK | PCB_OBJ_RAT | PCB_OBJ_ARC | PCB_OBJ_GFX) + +rnd_bool pcb_select_object(pcb_board_t *pcb); +rnd_bool pcb_select_block(pcb_board_t *pcb, rnd_box_t *Box, rnd_bool flag, rnd_bool vis_only, rnd_bool invert); + +/* List visible objects on screen within a box; return a list of IDs */ +long int *pcb_list_block(pcb_board_t *pcb, rnd_box_t *Box, int *len); + +/* List visible objects on screen within a box; return number of objects, call + a callback on each object found */ +int pcb_list_block_cb(pcb_board_t *pcb, rnd_box_t *Box, void *(cb)(void *ctx, pcb_any_obj_t *obj), void *ctx); + + +rnd_bool pcb_select_connection(pcb_board_t *pcb, rnd_bool); + +#endif Index: tags/2.3.0/src/select_act.c =================================================================== --- tags/2.3.0/src/select_act.c (nonexistent) +++ tags/2.3.0/src/select_act.c (revision 33253) @@ -0,0 +1,260 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" +#include "conf_core.h" + +#include "board.h" +#include "data.h" +#include +#include "undo.h" +#include "funchash_core.h" + +#include +#include "select.h" +#include "draw.h" +#include "remove.h" +#include "move.h" +#include "tool_logic.h" +#include +#include +#include +#include + + +static const char pcb_acts_Select[] = + "Select(Object, [idpath])\n" + "Select(ToggleObject)\n" + "Select(All|Block|Connection|Invert)\n" + "Select(Convert)"; +static const char pcb_acth_Select[] = "Toggles or sets the selection."; +/* DOC: select.html */ +static fgw_error_t pcb_act_Select(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int op; + RND_ACT_CONVARG(1, FGW_KEYWORD, Select, op = fgw_keyword(&argv[1])); + + switch(op) { + + /* select a single object */ + case F_Object: + if (argc > 2) { /* select by idpath */ + pcb_idpath_t *idp; + pcb_any_obj_t *obj; + RND_ACT_CONVARG(2, FGW_IDPATH, Select, idp = fgw_idpath(&argv[2])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + obj = pcb_idpath2obj(PCB, idp); + if ((obj == NULL) || ((obj->type & PCB_OBJ_CLASS_REAL) == 0)) { + RND_ACT_IRES(-1); + return 0; + } + pcb_undo_add_obj_to_flag(obj); + PCB_FLAG_SET(PCB_FLAG_SELECTED, obj); + pcb_draw_invalidate(obj); + pcb_board_set_changed_flag(pcb, rnd_true); + } + else { + case F_ToggleObject: + if (pcb_select_object(PCB)) { + pcb_board_set_changed_flag(pcb, rnd_true); + rnd_gui->invalidate_all(rnd_gui); + } + } + break; + + /* all objects in block */ + case F_Block: + { + rnd_box_t box; + + box.X1 = MIN(pcb_crosshair.AttachedBox.Point1.X, pcb_crosshair.AttachedBox.Point2.X); + box.Y1 = MIN(pcb_crosshair.AttachedBox.Point1.Y, pcb_crosshair.AttachedBox.Point2.Y); + box.X2 = MAX(pcb_crosshair.AttachedBox.Point1.X, pcb_crosshair.AttachedBox.Point2.X); + box.Y2 = MAX(pcb_crosshair.AttachedBox.Point1.Y, pcb_crosshair.AttachedBox.Point2.Y); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + pcb_tool_notify_block(); + if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_THIRD && pcb_select_block(PCB, &box, rnd_true, rnd_true, rnd_false)) { + pcb_board_set_changed_flag(pcb, rnd_true); + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; + } + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + rnd_gui->invalidate_all(rnd_gui); + break; + } + + /* select all visible(?) objects */ + case F_All: + { + rnd_box_t box; + + box.X1 = -RND_MAX_COORD; + box.Y1 = -RND_MAX_COORD; + box.X2 = RND_MAX_COORD; + box.Y2 = RND_MAX_COORD; + if (pcb_select_block(PCB, &box, rnd_true, rnd_true, rnd_false)) { + pcb_board_set_changed_flag(pcb, rnd_true); + rnd_gui->invalidate_all(rnd_gui); + } + break; + } + + case F_Invert: + { + rnd_box_t box; + + box.X1 = -RND_MAX_COORD; + box.Y1 = -RND_MAX_COORD; + box.X2 = RND_MAX_COORD; + box.Y2 = RND_MAX_COORD; + if (pcb_select_block(PCB, &box, rnd_true, rnd_true, rnd_true)) { + pcb_board_set_changed_flag(pcb, rnd_true); + rnd_gui->invalidate_all(rnd_gui); + } + break; + } + + /* all found connections */ + case F_Connection: + if (pcb_select_connection(PCB, rnd_true)) { + pcb_draw(); + pcb_undo_inc_serial(); + pcb_board_set_changed_flag(pcb, rnd_true); + } + break; + + case F_Convert: + case F_ConvertSubc: + { + rnd_coord_t x, y; + pcb_crosshair_note.Buffer = conf_core.editor.buffer_number; + pcb_buffer_set_number(PCB_MAX_BUFFER - 1); + pcb_buffer_clear(PCB, PCB_PASTEBUFFER); + rnd_hid_get_coords("Select the Subcircuit's Origin (mark) Location", &x, &y, 0); + x = rnd_grid_fit(x, RND_ACT_HIDLIB->grid, RND_ACT_HIDLIB->grid_ox); + y = rnd_grid_fit(y, RND_ACT_HIDLIB->grid, RND_ACT_HIDLIB->grid_oy); + pcb_buffer_add_selected(PCB, PCB_PASTEBUFFER, x, y, rnd_true, rnd_false); + pcb_undo_save_serial(); + pcb_remove_selected(0); + pcb_subc_convert_from_buffer(PCB_PASTEBUFFER); + pcb_undo_restore_serial(); + pcb_buffer_copy_to_layout(PCB, x, y, rnd_false); + pcb_buffer_set_number(pcb_crosshair_note.Buffer); + } + break; + + default: + RND_ACT_FAIL(Select); + break; + } + + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_Unselect[] = "Unselect(All|Block|Connection)\n"; +static const char pcb_acth_Unselect[] = "Unselects the object at the pointer location or the specified objects."; +/* DOC: unselect.html */ +static fgw_error_t pcb_act_Unselect(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int op; + RND_ACT_CONVARG(1, FGW_KEYWORD, Unselect, op = fgw_keyword(&argv[1])); + + switch(op) { + + /* all objects in block */ + case F_Block: + { + rnd_box_t box; + + box.X1 = MIN(pcb_crosshair.AttachedBox.Point1.X, pcb_crosshair.AttachedBox.Point2.X); + box.Y1 = MIN(pcb_crosshair.AttachedBox.Point1.Y, pcb_crosshair.AttachedBox.Point2.Y); + box.X2 = MAX(pcb_crosshair.AttachedBox.Point1.X, pcb_crosshair.AttachedBox.Point2.X); + box.Y2 = MAX(pcb_crosshair.AttachedBox.Point1.Y, pcb_crosshair.AttachedBox.Point2.Y); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + pcb_tool_notify_block(); + if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_THIRD && pcb_select_block(PCB, &box, rnd_false, rnd_true, rnd_false)) { + pcb_board_set_changed_flag(pcb, rnd_true); + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; + } + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + break; + } + + /* unselect all visible objects */ + case F_All: + { + rnd_box_t box; + + box.X1 = -RND_MAX_COORD; + box.Y1 = -RND_MAX_COORD; + box.X2 = RND_MAX_COORD; + box.Y2 = RND_MAX_COORD; + if (pcb_select_block(PCB, &box, rnd_false, rnd_false, rnd_false)) + pcb_board_set_changed_flag(pcb, rnd_true); + break; + } + + /* all found connections */ + case F_Connection: + if (pcb_select_connection(PCB, rnd_false)) { + pcb_draw(); + pcb_undo_inc_serial(); + pcb_board_set_changed_flag(pcb, rnd_true); + } + break; + + default: + RND_ACT_FAIL(Unselect); + break; + + } + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t select_action_list[] = { + {"Select", pcb_act_Select, pcb_acth_Select, pcb_acts_Select}, + {"Unselect", pcb_act_Unselect, pcb_acth_Unselect, pcb_acts_Unselect} +}; + +void pcb_select_act_init2(void) +{ + RND_REGISTER_ACTIONS(select_action_list, NULL); +} + + Index: tags/2.3.0/src/stub_draw.c =================================================================== --- tags/2.3.0/src/stub_draw.c (nonexistent) +++ tags/2.3.0/src/stub_draw.c (revision 33253) @@ -0,0 +1,96 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include "config.h" +#include "stub_draw.h" +#include "obj_text.h" +#include "obj_text_draw.h" + +/****** common code ******/ +void dummy_draw_text(pcb_draw_info_t *info, rnd_hid_gc_t gc, const char *str) +{ + pcb_text_t t = {0}; + + rnd_render->set_color(gc, rnd_color_red); + + memset(&t, 0, sizeof(t)); + t.TextString = (char *)str; + t.fid = 0; /* use the default font */ + t.Scale = 150; + t.Flags = pcb_no_flags(); + pcb_text_draw_(info, &t, 0, 0, PCB_TXT_TINY_ACCURATE); +} + +static rnd_bool dummy_mouse(rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + return 0; +} + + +/****** fab ******/ + +int dummy_DrawFab_overhang(void) +{ + return 0; +} + +void dummy_DrawFab(pcb_draw_info_t *info, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + dummy_draw_text(info, gc, "Can't render the fab layer: the draw_fab plugin is not compiled and/or not loaded"); +} + +int (*pcb_stub_draw_fab_overhang)(void) = dummy_DrawFab_overhang; +void (*pcb_stub_draw_fab)(pcb_draw_info_t *info, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) = dummy_DrawFab; + + +/****** csect - cross section of the board ******/ + + +static void dummy_draw_csect(rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + dummy_draw_text(NULL, gc, "Can't render the fab layer: the draw_csect plugin is not compiled and/or not loaded"); +} + + +void (*pcb_stub_draw_csect)(rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) = dummy_draw_csect; +rnd_bool (*pcb_stub_draw_csect_mouse_ev)(rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) = dummy_mouse; + + +/****** font selector GUI ******/ +static void dummy_draw_fontsel(rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e, pcb_text_t *txt) +{ + dummy_draw_text(NULL, gc, "Can't render the font selector: the draw_fontsel plugin is not compiled and/or not loaded"); +} + +static rnd_bool dummy_mouse_fontsel(rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y, pcb_text_t *txt) +{ + return 0; +} + +void (*pcb_stub_draw_fontsel)(rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e, pcb_text_t *txt) = dummy_draw_fontsel; +rnd_bool (*pcb_stub_draw_fontsel_mouse_ev)(rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y, pcb_text_t *txt) = dummy_mouse_fontsel; + Index: tags/2.3.0/src/stub_draw.h =================================================================== --- tags/2.3.0/src/stub_draw.h (nonexistent) +++ tags/2.3.0/src/stub_draw.h (revision 33253) @@ -0,0 +1,51 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* drawing the fab layer is a plugin now */ + +#ifndef PCB_STUB_DRAW_FAB_H +#define PCB_STUB_DRAW_FAB_H + +#include +#include +#include +#include "draw.h" + +/* fab */ +extern int (*pcb_stub_draw_fab_overhang)(void); +extern void (*pcb_stub_draw_fab)(pcb_draw_info_t *info, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e); + +/* csect */ +extern void (*pcb_stub_draw_csect)(rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e); +extern rnd_bool (*pcb_stub_draw_csect_mouse_ev)(rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y); + +/* fontsel */ +extern void (*pcb_stub_draw_fontsel)(rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e, pcb_text_t *txt); +extern rnd_bool (*pcb_stub_draw_fontsel_mouse_ev)(rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y, pcb_text_t *txt); + +#endif Index: tags/2.3.0/src/thermal.c =================================================================== --- tags/2.3.0/src/thermal.c (nonexistent) +++ tags/2.3.0/src/thermal.c (revision 33253) @@ -0,0 +1,979 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "thermal.h" + +#include +#include +#include "data.h" +#include "draw.h" +#include "undo.h" +#include "conf_core.h" +#include "obj_common.h" +#include "obj_pstk.h" +#include "obj_pstk_inlines.h" +#include "obj_pinvia_therm.h" +#include "polygon.h" +#include "funchash_core.h" + +static const char core_thermal_cookie[] = "core/thermal.c"; + +rnd_cardinal_t pcb_themal_style_new2old(unsigned char t) +{ + switch(t) { + case 0: return 0; + case PCB_THERMAL_ON | PCB_THERMAL_SHARP | PCB_THERMAL_DIAGONAL: return 1; + case PCB_THERMAL_ON | PCB_THERMAL_SHARP: return 2; + case PCB_THERMAL_ON | PCB_THERMAL_SOLID: return 3; + case PCB_THERMAL_ON | PCB_THERMAL_ROUND | PCB_THERMAL_DIAGONAL: return 4; + case PCB_THERMAL_ON | PCB_THERMAL_ROUND: return 5; + } + return 0; +} + +unsigned char pcb_themal_style_old2new(rnd_cardinal_t t) +{ + switch(t) { + case 0: return 0; + case 1: return PCB_THERMAL_ON | PCB_THERMAL_SHARP | PCB_THERMAL_DIAGONAL; + case 2: return PCB_THERMAL_ON | PCB_THERMAL_SHARP; + case 3: return PCB_THERMAL_ON | PCB_THERMAL_SOLID; + case 4: return PCB_THERMAL_ON | PCB_THERMAL_ROUND | PCB_THERMAL_DIAGONAL; + case 5: return PCB_THERMAL_ON | PCB_THERMAL_ROUND; + } + return 0; +} + +pcb_thermal_t pcb_thermal_str2bits(const char *str) +{ + /* shape */ + if (strcmp(str, "noshape") == 0) return PCB_THERMAL_NOSHAPE; + if (strcmp(str, "round") == 0) return PCB_THERMAL_ROUND; + if (strcmp(str, "sharp") == 0) return PCB_THERMAL_SHARP; + if (strcmp(str, "solid") == 0) return PCB_THERMAL_SOLID; + + /* orientation */ + if (strcmp(str, "diag") == 0) return PCB_THERMAL_DIAGONAL; + + if (strcmp(str, "on") == 0) return PCB_THERMAL_ON; + + return 0; +} + +const char *pcb_thermal_bits2str(pcb_thermal_t *bit) +{ + if ((*bit) & PCB_THERMAL_ON) { + *bit &= ~PCB_THERMAL_ON; + return "on"; + } + if ((*bit) & PCB_THERMAL_DIAGONAL) { + *bit &= ~PCB_THERMAL_DIAGONAL; + return "diag"; + } + if ((*bit) & 3) { + int shape = (*bit) & 3; + *bit &= ~3; + switch(shape) { + case PCB_THERMAL_NOSHAPE: return "noshape"; + case PCB_THERMAL_ROUND: return "round"; + case PCB_THERMAL_SHARP: return "sharp"; + case PCB_THERMAL_SOLID: return "solid"; + default: return NULL; + } + } + return NULL; +} + +void pcb_thermal_bits2chars(char dst[3], pcb_thermal_t bits) +{ + char *end = dst; + + if (!(bits & PCB_THERMAL_ON)) { + *end = '\0'; + return; + } + + switch(bits & 3) { + case PCB_THERMAL_NOSHAPE: *end++ = 'n'; goto skip_diag; + case PCB_THERMAL_ROUND: *end++ = 'o'; break; + case PCB_THERMAL_SHARP: *end++ = 'x'; break; + case PCB_THERMAL_SOLID: *end++ = '@'; goto skip_diag; + } + + if (bits & PCB_THERMAL_DIAGONAL) + *end++ = 'd'; + + skip_diag:; + *end++ = '\0'; +} + + +/* generate a round-cap line polygon */ +static rnd_polyarea_t *pa_line_at(double x1, double y1, double x2, double y2, rnd_coord_t clr, rnd_bool square) +{ + pcb_line_t ltmp; + if (square) + ltmp.Flags = pcb_flag_make(PCB_FLAG_SQUARE); + else + ltmp.Flags = pcb_no_flags(); + ltmp.Point1.X = rnd_round(x1); ltmp.Point1.Y = rnd_round(y1); + ltmp.Point2.X = rnd_round(x2); ltmp.Point2.Y = rnd_round(y2); + return pcb_poly_from_pcb_line(<mp, clr); +} + +/* generate a round-cap arc polygon knowing the center and endpoints */ +static rnd_polyarea_t *pa_arc_at(double cx, double cy, double r, double e1x, double e1y, double e2x, double e2y, rnd_coord_t clr, double max_span_angle) +{ + double sa, ea, da; + pcb_arc_t atmp; + + sa = atan2(-(e1y - cy), e1x - cx) * RND_RAD_TO_DEG + 180.0; + ea = atan2(-(e2y - cy), e2x - cx) * RND_RAD_TO_DEG + 180.0; + +/* rnd_trace("sa=%f ea=%f diff=%f\n", sa, ea, ea-sa);*/ + + atmp.Flags = pcb_no_flags(); + atmp.X = rnd_round(cx); + atmp.Y = rnd_round(cy); + + da = ea-sa; + if ((da < max_span_angle) && (da > -max_span_angle)) { + atmp.StartAngle = sa; + atmp.Delta = ea-sa; + } + else { + if (ea < sa) { + double tmp = ea; + ea = sa; + sa = tmp; + } + atmp.StartAngle = ea; + atmp.Delta = 360-ea+sa; + } + atmp.Width = atmp.Height = r; + return pcb_poly_from_pcb_arc(&atmp, clr); +} + +rnd_polyarea_t *pcb_thermal_area_line(pcb_board_t *pcb, pcb_line_t *line, rnd_layer_id_t lid, pcb_poly_t *in_poly) +{ + rnd_polyarea_t *pa, *pb, *pc; + double dx, dy, len, vx, vy, nx, ny, clr, clrth, x1, y1, x2, y2, mx, my; + rnd_coord_t th, lclr; + + if ((line->Point1.X == line->Point2.X) && (line->Point1.Y == line->Point2.Y)) { + /* corner case zero-long line is a circle: do the same as for vias */ + lclr = pcb_obj_clearance_o05(line, in_poly); + /* PCB is use for the thermal scale here */ + return ThermPoly_(pcb == NULL ? PCB : pcb, line->Point1.X, line->Point1.Y, line->Thickness, lclr * 2, pcb_themal_style_new2old(line->thermal & 3)); + } + + x1 = line->Point1.X; + y1 = line->Point1.Y; + x2 = line->Point2.X; + y2 = line->Point2.Y; + mx = (x1+x2)/2.0; + my = (y1+y2)/2.0; + dx = x1 - x2; + dy = y1 - y2; + + len = sqrt(dx*dx + dy*dy); + vx = dx / len; + vy = dy / len; + nx = -vy; + ny = vx; + + lclr = pcb_obj_clearance_o05(line, in_poly); + clr = lclr; + clrth = (lclr + line->Thickness) / 2; + + assert(line->thermal & PCB_THERMAL_ON); /* caller should have checked this */ + switch(line->thermal & 3) { + case PCB_THERMAL_NOSHAPE: + case PCB_THERMAL_SOLID: return 0; + + case PCB_THERMAL_ROUND: + if (PCB_FLAG_TEST(PCB_FLAG_SQUARE, line)) { + + if (line->thermal & PCB_THERMAL_DIAGONAL) { + /* side clear lines */ + pa = pa_line_at( + x1 - clrth * nx + clrth * vx - clr*vx, y1 - clrth * ny + clrth * vy - clr*vy, + x2 - clrth * nx - clrth * vx + clr*vx, y2 - clrth * ny - clrth * vy + clr*vy, + clr, rnd_false); + pb = pa_line_at( + x1 + clrth * nx + clrth * vx - clr*vx, y1 + clrth * ny + clrth * vy - clr*vy, + x2 + clrth * nx - clrth * vx + clr*vx, y2 + clrth * ny - clrth * vy + clr*vy, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + /* cross clear lines */ + pa = pc; pc = NULL; + pb = pa_line_at( + x1 - clrth * nx + clrth * vx + clr*nx, y1 - clrth * ny + clrth * vy + clr*ny, + x1 + clrth * nx + clrth * vx - clr*nx, y1 + clrth * ny + clrth * vy - clr*ny, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + pa = pc; pc = NULL; + pb = pa_line_at( + x2 - clrth * nx - clrth * vx + clr*nx, y2 - clrth * ny - clrth * vy + clr*ny, + x2 + clrth * nx - clrth * vx - clr*nx, y2 + clrth * ny - clrth * vy - clr*ny, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + } + else { + /* side clear lines */ + pa = pa_line_at( + x1 - clrth * nx + clrth * vx, y1 - clrth * ny + clrth * vy, + mx - clrth * nx + clr * vx, my - clrth * ny + clr * vy, + clr, rnd_false); + pb = pa_line_at( + x1 + clrth * nx + clrth * vx, y1 + clrth * ny + clrth * vy, + mx + clrth * nx + clr * vx, my + clrth * ny + clr * vy, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + pa = pc; pc = NULL; + pb = pa_line_at( + x2 - clrth * nx - clrth * vx, y2 - clrth * ny - clrth * vy, + mx - clrth * nx - clr * vx, my - clrth * ny - clr * vy, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + pa = pc; pc = NULL; + pb = pa_line_at( + x2 + clrth * nx - clrth * vx, y2 + clrth * ny - clrth * vy, + mx + clrth * nx - clr * vx, my + clrth * ny - clr * vy, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + /* cross clear lines */ + pa = pc; pc = NULL; + pb = pa_line_at( + x1 - clrth * nx + clrth * vx, y1 - clrth * ny + clrth * vy, + x1 - clr * nx + clrth * vx, y1 - clr * ny + clrth * vy, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + pa = pc; pc = NULL; + pb = pa_line_at( + x1 + clrth * nx + clrth * vx, y1 + clrth * ny + clrth * vy, + x1 + clr * nx + clrth * vx, y1 + clr * ny + clrth * vy, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + pa = pc; pc = NULL; + pb = pa_line_at( + x2 - clrth * nx - clrth * vx, y2 - clrth * ny - clrth * vy, + x2 - clr * nx - clrth * vx, y2 - clr * ny - clrth * vy, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + pa = pc; pc = NULL; + pb = pa_line_at( + x2 + clrth * nx - clrth * vx, y2 + clrth * ny - clrth * vy, + x2 + clr * nx - clrth * vx, y2 + clr * ny - clrth * vy, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + } + } + else { + /* round cap line: arcs! */ + if (line->thermal & PCB_THERMAL_DIAGONAL) { + /* side clear lines */ + pa = pa_line_at( + x1 - clrth * nx - clr * vx * 0.75, y1 - clrth * ny - clr * vy * 0.75, + x2 - clrth * nx + clr * vx * 0.75, y2 - clrth * ny + clr * vy * 0.75, + clr, rnd_false); + pb = pa_line_at( + x1 + clrth * nx - clr * vx * 0.75, y1 + clrth * ny - clr * vy * 0.75, + x2 + clrth * nx + clr * vx * 0.75, y2 + clrth * ny + clr * vy * 0.75, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + /* x1;y1 cap arc */ + pa = pc; pc = NULL; + pb = pa_arc_at(x1, y1, clrth, + x1 - clrth * nx + clr * vx * 2.0, y1 - clrth * ny + clr * vy * 2.0, + x1 + clrth * nx + clr * vx * 2.0, y1 + clrth * ny + clr * vy * 2.0, + clr, 180.0); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + /* x2;y2 cap arc */ + pa = pc; pc = NULL; + pb = pa_arc_at(x2, y2, clrth, + x2 - clrth * nx - clr * vx * 2.0, y2 - clrth * ny - clr * vy * 2.0, + x2 + clrth * nx - clr * vx * 2.0, y2 + clrth * ny - clr * vy * 2.0, + clr, 180.0); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + } + else { /* non-diagonal */ + /* split side lines */ + pa = pa_line_at( + x1 - clrth * nx - clr * vx * 0.00, y1 - clrth * ny - clr * vy * 0.00, + mx - clrth * nx + clr * vx * 1.00, my - clrth * ny + clr * vy * 1.00, + clr, rnd_false); + pb = pa_line_at( + x1 + clrth * nx - clr * vx * 0.00, y1 + clrth * ny - clr * vy * 0.00, + mx + clrth * nx + clr * vx * 1.00, my + clrth * ny + clr * vy * 1.00, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + pa = pc; pc = NULL; + pb = pa_line_at( + mx - clrth * nx - clr * vx * 1.00, my - clrth * ny - clr * vy * 1.00, + x2 - clrth * nx + clr * vx * 0.00, y2 - clrth * ny + clr * vy * 0.00, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + pa = pc; pc = NULL; + pb = pa_line_at( + mx + clrth * nx - clr * vx * 1.00, my + clrth * ny - clr * vy * 1.00, + x2 + clrth * nx + clr * vx * 0.00, y2 + clrth * ny + clr * vy * 0.00, + clr, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + /* split round cap, x1;y1 */ + pa = pc; pc = NULL; + pb = pa_arc_at(x1, y1, clrth, + x1 - clrth * nx, y1 - clrth * ny, + x1 + clrth * vx - clr * nx, y1 + clrth * vy - clr * ny, + clr, 180.0); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + pa = pc; pc = NULL; + pb = pa_arc_at(x1, y1, clrth, + x1 + clrth * nx, y1 + clrth * ny, + x1 + clrth * vx + clr * nx, y1 + clrth * vy + clr * ny, + clr, 180.0); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + /* split round cap, x2;y2 */ + pa = pc; pc = NULL; + pb = pa_arc_at(x2, y2, clrth, + x2 - clrth * nx, y2 - clrth * ny, + x2 - clrth * vx - clr * nx, y2 - clrth * vy - clr * ny, + clr, 180.0); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + + pa = pc; pc = NULL; + pb = pa_arc_at(x2, y2, clrth, + x2 + clrth * nx, y2 + clrth * ny, + x2 - clrth * vx + clr * nx, y2 - clrth * vy + clr * ny, + clr, 180.0); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_UNITE); + } + } + return pc; + case PCB_THERMAL_SHARP: + pa = pcb_poly_from_pcb_line(line, line->Thickness + pcb_obj_clearance_p2(line, in_poly)); + th = line->Thickness/2 < clr ? line->Thickness/2 : clr; + clrth *= 2; + if (line->thermal & PCB_THERMAL_DIAGONAL) { + /* x1;y1 V-shape */ + pb = pa_line_at(x1, y1, x1-nx*clrth+vx*clrth, y1-ny*clrth+vy*clrth, th, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_SUB); + + pa = pc; pc = NULL; + pb = pa_line_at(x1, y1, x1+nx*clrth+vx*clrth, y1+ny*clrth+vy*clrth, th, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_SUB); + + /* x2;y2 V-shape */ + pa = pc; pc = NULL; + pb = pa_line_at(x2, y2, x2-nx*clrth-vx*clrth, y2-ny*clrth-vy*clrth, th, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_SUB); + + pa = pc; pc = NULL; + pb = pa_line_at(x2, y2, x2+nx*clrth-vx*clrth, y2+ny*clrth-vy*clrth, th, rnd_false); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_SUB); + } + else { + /* perpendicular */ + pb = pa_line_at(mx-nx*clrth, my-ny*clrth, mx+nx*clrth, my+ny*clrth, th, rnd_true); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_SUB); + + /* straight */ + pa = pc; pc = NULL; + pb = pa_line_at(x1+vx*clrth, y1+vy*clrth, x2-vx*clrth, y2-vy*clrth, th, rnd_true); + rnd_polyarea_boolean_free(pa, pb, &pc, RND_PBO_SUB); + } + return pc; + } + return NULL; +} + +/* combine a base poly-area into the result area (pres) */ +static void polytherm_base(rnd_polyarea_t **pres, const rnd_polyarea_t *src) +{ + rnd_polyarea_t *p; + + if (*pres != NULL) { + rnd_polyarea_boolean(src, *pres, &p, RND_PBO_UNITE); + rnd_polyarea_free(pres); + *pres = p; + } + else + rnd_polyarea_copy0(pres, src); +} + +#define CONG_MAX 256 + +static int cong_map(char *cong, pcb_poly_it_t *it, rnd_coord_t clr) +{ + int n, go, first = 1; + rnd_coord_t cx, cy; + double cl2 = (double)clr * (double)clr * 1.5; + double px, py, x, y; + + for(n = 0, go = pcb_poly_vect_first(it, &cx, &cy); go; go = pcb_poly_vect_next(it, &cx, &cy), n++) { + x = cx; y = cy; + if (first) { +/*rnd_trace("prev %mm;%mm\n", cx, cy);*/ + pcb_poly_vect_peek_prev(it, &cx, &cy); +/*rnd_trace(" %mm;%mm\n", cx, cy);*/ + px = cx; py = cy; + first = 0; + } + if (n >= CONG_MAX-1) { + n++; + break; + } + cong[n] = (rnd_distance2(x, y, px, py) < cl2); + px = x; py = y; + } + return n; +} + +/* combine a round clearance line set into pres; "it" is an iterator + already initialized to a polyarea contour */ +static void polytherm_round(rnd_polyarea_t **pres, pcb_poly_it_t *it, rnd_coord_t clr, rnd_bool is_diag, double tune) +{ + rnd_polyarea_t *ptmp, *p; + double fact = 0.5, fact_ortho=0.75; + rnd_coord_t cx, cy; + double px, py, x, y, dx, dy, vx, vy, nx, ny, mx, my, len; + int n, go, first = 1; + char cong[CONG_MAX]; + + clr -= 2; + if (tune > 0) { + fact *= tune; + fact_ortho *= tune; + } + + cong_map(cong, it, clr); + + /* iterate over the vectors of the contour */ + for(n = 0, go = pcb_poly_vect_first(it, &cx, &cy); go; go = pcb_poly_vect_next(it, &cx, &cy), n++) { + x = cx; y = cy; + if (first) { + pcb_poly_vect_peek_prev(it, &cx, &cy); + px = cx; py = cy; + + first = 0; + } + +/*rnd_trace("[%d] %d %mm;%mm\n", n, cong[n], (rnd_coord_t)x, (rnd_coord_t)y);*/ + + + dx = x - px; + dy = y - py; + mx = (x+px)/2.0; + my = (y+py)/2.0; + + len = sqrt(dx*dx + dy*dy); + vx = dx / len; + vy = dy / len; + + nx = -vy; + ny = vx; + + /* skip points too dense */ + if ((n >= CONG_MAX) || (cong[n])) { + if (!is_diag) { + /* have to draw a short clearance for the small segments */ + ptmp = pa_line_at(x - nx * clr/2, y - ny * clr/2, px - nx * clr/2, py - ny * clr/2, clr+4, rnd_false); + + rnd_polyarea_boolean(ptmp, *pres, &p, RND_PBO_UNITE); + rnd_polyarea_free(pres); + rnd_polyarea_free(&ptmp); + *pres = p; + } + px = x; py = y; + continue; + } + + /* cheat: clr-2+4 to guarantee some overlap with the poly cutout */ + if (is_diag) { + /* one line per edge, slightly shorter than the edge */ + ptmp = pa_line_at(x - vx * clr * fact - nx * clr/2, y - vy * clr * fact - ny * clr/2, px + vx * clr *fact - nx * clr/2, py + vy * clr * fact - ny * clr/2, clr+4, rnd_false); + + rnd_polyarea_boolean(ptmp, *pres, &p, RND_PBO_UNITE); + rnd_polyarea_free(pres); + rnd_polyarea_free(&ptmp); + *pres = p; + } + else { + /* two half lines per edge */ + ptmp = pa_line_at(x - nx * clr/2 , y - ny * clr/2, mx + vx * clr * fact_ortho - nx * clr/2, my + vy * clr * fact_ortho - ny * clr/2, clr+4, rnd_false); + rnd_polyarea_boolean(ptmp, *pres, &p, RND_PBO_UNITE); + rnd_polyarea_free(pres); + rnd_polyarea_free(&ptmp); + *pres = p; + + ptmp = pa_line_at(px - nx * clr/2, py - ny * clr/2, mx - vx * clr * fact_ortho - nx * clr/2, my - vy * clr * fact_ortho - ny * clr/2, clr+4, rnd_false); + rnd_polyarea_boolean(ptmp, *pres, &p, RND_PBO_UNITE); + rnd_polyarea_free(pres); + rnd_polyarea_free(&ptmp); + *pres = p; + + /* optical tuning: make sure the clearance is large enough around corners + even if lines didn't meet - just throw in a big circle */ + ptmp = rnd_poly_from_circle(x, y, clr); + rnd_polyarea_boolean(ptmp, *pres, &p, RND_PBO_UNITE); + rnd_polyarea_free(pres); + rnd_polyarea_free(&ptmp); + *pres = p; + } + px = x; + py = y; + } +} + +static void polytherm_sharp(rnd_polyarea_t **pres, pcb_poly_it_t *it, rnd_coord_t clr, rnd_bool is_diag, double tune) +{ + rnd_polyarea_t *ptmp, *p; + rnd_coord_t cx, cy, x2c, y2c; + double px, py, x, y, dx, dy, vx, vy, nx, ny, mx, my, len, x2, y2, vx2, vy2, len2, dx2, dy2; + int n, go, first = 1; + char cong[CONG_MAX], cong2[CONG_MAX]; + + if (tune <= 0) + tune = 1; + + if (is_diag) { + int start = -1, v = cong_map(cong2, it, clr); + memset(cong, 1, sizeof(cong)); + + /* in case of sharp-diag, draw the bridge in the middle of each congestion; + run *2 and do module v so congestions spanning over the end are no special */ + for(n = 0; n < v*2; n++) { + if (cong2[n % v] == 0) { + if (start >= 0) + cong[((start+n)/2) % v] = 0; + start = n; + } + } + } + else { + /* normal congestion logic: use long edges only */ + cong_map(cong, it, clr); + } + + /* iterate over the vectors of the contour */ + for(n = 0, go = pcb_poly_vect_first(it, &cx, &cy); go; go = pcb_poly_vect_next(it, &cx, &cy), n++) { + x = cx; y = cy; + if (first) { + pcb_poly_vect_peek_prev(it, &cx, &cy); + px = cx; py = cy; + first = 0; + } + +/*rnd_trace("[%d] %d %mm;%mm\n", n, cong[n], (rnd_coord_t)x, (rnd_coord_t)y);*/ + + /* skip points too dense */ + if ((n >= CONG_MAX) || (cong[n])) { + px = x; py = y; + continue; + } + + + dx = x - px; + dy = y - py; + + len = sqrt(dx*dx + dy*dy); + vx = dx / len; + vy = dy / len; + + if (is_diag) { + pcb_poly_vect_peek_next(it, &x2c, &y2c); + x2 = x2c; y2 = y2c; + dx2 = x - x2; + dy2 = y - y2; + len2 = sqrt(dx2*dx2 + dy2*dy2); + vx2 = dx2 / len2; + vy2 = dy2 / len2; + + nx = -(vy2 - vy); + ny = vx2 - vx; + + /* line from each corner at the average angle of the two edges from the corner */ +TODO("can not enable 'tune' here because of a poly lib bug for rectangular poly vs. 20 mil diagonal sharp with tun=1.5"); + ptmp = pa_line_at(x-nx*clr*1.2, y-ny*clr*1.2, x + nx*clr*6, y + ny*clr*6, clr/2*tune, rnd_true); + rnd_polyarea_boolean(*pres, ptmp, &p, RND_PBO_SUB); + rnd_polyarea_free(pres); + rnd_polyarea_free(&ptmp); + *pres = p; + } + else { + nx = -vy; + ny = vx; + mx = (x+px)/2.0; + my = (y+py)/2.0; + + /* perpendicular line from the middle of each edge */ + ptmp = pa_line_at(mx, my, mx - nx*clr, my - ny*clr, clr/2*tune, rnd_true); + rnd_polyarea_boolean(*pres, ptmp, &p, RND_PBO_SUB); + rnd_polyarea_free(pres); + rnd_polyarea_free(&ptmp); + *pres = p; + } + px = x; + py = y; + } +} + +/* generate round thermal around a polyarea specified by the iterator */ +static void pcb_thermal_area_pa_round(rnd_polyarea_t **pres, pcb_poly_it_t *it, rnd_coord_t clr, rnd_bool_t is_diag) +{ + rnd_pline_t *pl; + +/* cut out the poly so terminals will be displayed proerply */ + polytherm_base(pres, it->pa); + + /* generate the clear-lines */ + pl = pcb_poly_contour(it); + if (pl != NULL) + polytherm_round(pres, it, clr, is_diag, 0/*conf_core.design.thermal.poly_scale*/); +} + +/* generate sharp thermal around a polyarea specified by the iterator */ +static void pcb_thermal_area_pa_sharp(rnd_polyarea_t **pres, pcb_poly_it_t *it, rnd_coord_t clr, rnd_bool_t is_diag) +{ + rnd_pline_t *pl; + + /* add the usual clearance glory around the polygon */ + pcb_poly_pa_clearance_construct(pres, it, clr); + + pl = pcb_poly_contour(it); + if (pl != NULL) + polytherm_sharp(pres, it, clr, is_diag, 0/*conf_core.design.thermal.poly_scale*/); + + /* trim internal stubs */ + polytherm_base(pres, it->pa); +} + +rnd_polyarea_t *pcb_thermal_area_poly(pcb_board_t *pcb, pcb_poly_t *poly, rnd_layer_id_t lid, pcb_poly_t *in_poly) +{ + rnd_polyarea_t *pa, *pres = NULL; + rnd_coord_t clr = pcb_obj_clearance_o05(poly, in_poly); + pcb_poly_it_t it; + + assert(poly->thermal & PCB_THERMAL_ON); /* caller should have checked this */ + switch(poly->thermal & 3) { + case PCB_THERMAL_NOSHAPE: + case PCB_THERMAL_SOLID: return NULL; + + case PCB_THERMAL_ROUND: + for(pa = pcb_poly_island_first(poly, &it); pa != NULL; pa = pcb_poly_island_next(&it)) + pcb_thermal_area_pa_round(&pres, &it, clr, (poly->thermal & PCB_THERMAL_DIAGONAL)); + return pres; + + case PCB_THERMAL_SHARP: + for(pa = pcb_poly_island_first(poly, &it); pa != NULL; pa = pcb_poly_island_next(&it)) + pcb_thermal_area_pa_sharp(&pres, &it, clr, (poly->thermal & PCB_THERMAL_DIAGONAL)); + return pres; + } + + return NULL; +} + +/* Generate a clearance around a padstack shape, with no thermal */ +static rnd_polyarea_t *pcb_thermal_area_pstk_nothermal(pcb_board_t *pcb, pcb_pstk_t *ps, rnd_layer_id_t lid, pcb_pstk_shape_t *shp, rnd_coord_t clearance) +{ + pcb_poly_it_t it; + rnd_polyarea_t *pres = NULL; + pcb_pstk_shape_t tmpshp; + + retry:; + switch(shp->shape) { + case PCB_PSSH_HSHADOW: + shp = pcb_pstk_hshadow_shape(ps, shp, &tmpshp); + if (shp == NULL) + return NULL; + goto retry; + case PCB_PSSH_CIRC: + return rnd_poly_from_circle(ps->x + shp->data.circ.x, ps->y + shp->data.circ.y, shp->data.circ.dia/2 + clearance); + case PCB_PSSH_LINE: + return pa_line_at(ps->x + shp->data.line.x1, ps->y + shp->data.line.y1, ps->x + shp->data.line.x2, ps->y + shp->data.line.y2, shp->data.line.thickness + clearance*2, shp->data.line.square); + case PCB_PSSH_POLY: + if (shp->data.poly.pa == NULL) + pcb_pstk_shape_update_pa(&shp->data.poly); + if (shp->data.poly.pa == NULL) + return NULL; + pcb_poly_iterate_polyarea(shp->data.poly.pa, &it); + pcb_poly_pa_clearance_construct(&pres, &it, clearance); + rnd_polyarea_move(pres, ps->x, ps->y); + return pres; + } + return NULL; +} + +rnd_polyarea_t *pcb_thermal_area_pstk(pcb_board_t *pcb, pcb_pstk_t *ps, rnd_layer_id_t lid, pcb_poly_t *in_poly) +{ + unsigned char thr; + pcb_pstk_shape_t *shp, tmpshp; + rnd_polyarea_t *pres = NULL; + pcb_layer_t *layer; + rnd_coord_t clearance, gclearance = ps->Clearance; /* this is a legal direct access to the Clearance field, poly->enforce_clearance is applied later */ + + /* thermal needs a stackup - only a PCB has a stackup, buffers don't */ + if (pcb == NULL) + return NULL; + + /* if we have no clearance, there's no reason to do anything; + ps->Clearance == 0 doesn't mean no clearance because of the per shape clearances */ + if (!PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, ps)) + return NULL; + + layer = pcb_get_layer(pcb->Data, lid); + + /* retrieve shape; assume 0 (no shape) for layers not named */ + if (lid < ps->thermals.used) + thr = ps->thermals.shape[lid]; + else + thr = 0; + + shp = pcb_pstk_shape_at_(pcb, ps, layer, 1); + if (shp == NULL) { + rnd_layergrp_id_t gid; + pcb_layergrp_t *grp; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + if (proto->hdia < 0) + return NULL; + + /* corner case: subtracting a hole from a mech/drill poly (e.g. gcode) */ + gid = pcb_layer_get_group_(layer); + grp = pcb_get_layergrp(pcb, gid); + if (PCB_LAYER_IS_DRILL(grp->ltype, grp->purpi) || ((grp->ltype & PCB_LYT_MECH) && (grp->purpi == (proto->hplated ? F_proute : F_uroute)))) { + thr = 0; + shp = &tmpshp; + shp->shape = PCB_PSSH_CIRC; + shp->data.circ.x = 0; + shp->data.circ.y = 0; + shp->data.circ.dia = proto->hdia; + } + else + return NULL; + } + + if (gclearance <= 0) + clearance = shp->clearance/2; + else + clearance = gclearance; + + /* apply polygon enforced clearance on top of the per shape clearance */ + clearance = RND_MAX(clearance, in_poly->enforce_clearance); + + if (clearance <= 0) { + rnd_layergrp_id_t gid = pcb_layer_get_group_(layer); + pcb_layergrp_t *grp = pcb_get_layergrp(pcb, gid); + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + if (grp == NULL) return NULL; + if (PCB_LAYER_IS_DRILL(grp->ltype, grp->purpi) || ((grp->ltype & PCB_LYT_MECH) && (grp->purpi == (proto->hplated ? F_proute : F_uroute)))) { + /* shape on a slot layer - do it, but without termals! */ + thr = 0; + } + else + return NULL; + } + + if (!(thr & PCB_THERMAL_ON)) + return pcb_thermal_area_pstk_nothermal(pcb, ps, lid, shp, clearance); + + switch(thr & 3) { + case PCB_THERMAL_NOSHAPE: + tmpshp.shape = PCB_PSSH_HSHADOW; + tmpshp.clearance = shp->clearance; + return pcb_thermal_area_pstk_nothermal(pcb, ps, lid, &tmpshp, clearance); + case PCB_THERMAL_SOLID: return NULL; + case PCB_THERMAL_ROUND: + case PCB_THERMAL_SHARP: + retry:; + switch(shp->shape) { + case PCB_PSSH_HSHADOW: + shp = pcb_pstk_hshadow_shape(ps, shp, &tmpshp); + if (shp == NULL) + return NULL; + goto retry; + case PCB_PSSH_CIRC: + return ThermPoly_(pcb, ps->x + shp->data.circ.x, ps->y + shp->data.circ.y, shp->data.circ.dia, clearance*2, pcb_themal_style_new2old(thr)); + case PCB_PSSH_LINE: + { + pcb_line_t ltmp; + if (shp->data.line.square) + ltmp.Flags = pcb_flag_make(PCB_FLAG_SQUARE); + else + ltmp.Flags = pcb_no_flags(); + ltmp.Point1.X = ps->x + shp->data.line.x1; + ltmp.Point1.Y = ps->y + shp->data.line.y1; + ltmp.Point2.X = ps->x + shp->data.line.x2; + ltmp.Point2.Y = ps->y + shp->data.line.y2; + ltmp.Thickness = shp->data.line.thickness; + ltmp.Clearance = clearance*2; + ltmp.thermal = thr; + pres = pcb_thermal_area_line(pcb, <mp, lid, in_poly); + } + return pres; + + case PCB_PSSH_POLY: + { + pcb_poly_it_t it; + if (shp->data.poly.pa == NULL) + pcb_pstk_shape_update_pa(&shp->data.poly); + if (shp->data.poly.pa == NULL) + return NULL; + pcb_poly_iterate_polyarea(shp->data.poly.pa, &it); + if (thr & PCB_THERMAL_ROUND) + pcb_thermal_area_pa_round(&pres, &it, clearance, (thr & PCB_THERMAL_DIAGONAL)); + else + pcb_thermal_area_pa_sharp(&pres, &it, clearance, (thr & PCB_THERMAL_DIAGONAL)); + + if (pres != NULL) + rnd_polyarea_move(pres, ps->x, ps->y); + } + return pres; + } + + } + + return NULL; +} + +rnd_polyarea_t *pcb_thermal_area(pcb_board_t *pcb, pcb_any_obj_t *obj, rnd_layer_id_t lid, pcb_poly_t *in_poly) +{ + switch(obj->type) { + + case PCB_OBJ_LINE: + return pcb_thermal_area_line(pcb, (pcb_line_t *)obj, lid, in_poly); + + case PCB_OBJ_POLY: + return pcb_thermal_area_poly(pcb, (pcb_poly_t *)obj, lid, in_poly); + + case PCB_OBJ_PSTK: + return pcb_thermal_area_pstk(pcb, (pcb_pstk_t *)obj, lid, in_poly); + + case PCB_OBJ_ARC: + break; + + default: break; + } + + return NULL; +} + + +/*** undoable thermal change ***/ +typedef struct { + pcb_board_t *pcb; + pcb_any_obj_t *obj; + unsigned char shape; +} undo_anyobj_thermal_t; + +static int undo_anyobj_thermal_swap(void *udata) +{ + undo_anyobj_thermal_t *t = udata; + unsigned char old, *th = pcb_obj_common_get_thermal(t->obj, 0, 1); + + if (th != NULL) { + pcb_poly_restore_to_poly(t->pcb->Data, t->obj->type, t->obj->parent.layer, t->obj); + + old = *th; + *th = t->shape; + t->shape = old; + + pcb_poly_clear_from_poly(t->pcb->Data, t->obj->type, t->obj->parent.layer, t->obj); + pcb_draw_invalidate(t->obj); + } + return 0; +} + +static void undo_anyobj_thermal_print(void *udata, char *dst, size_t dst_len) +{ + undo_anyobj_thermal_t *t = udata; + rnd_snprintf(dst, dst_len, "anyobj_thermal: #%ld %d", t->obj->ID, t->shape); +} + +static const uundo_oper_t undo_anyobj_thermal = { + core_thermal_cookie, + NULL, /* free */ + undo_anyobj_thermal_swap, + undo_anyobj_thermal_swap, + undo_anyobj_thermal_print +}; + + +int pcb_anyobj_set_thermal(pcb_any_obj_t *obj, unsigned char shape, int undoable) +{ + undo_anyobj_thermal_t *t; + pcb_board_t *pcb = NULL; + + if (obj->type == PCB_OBJ_PSTK) + return -1; /* needs a layer */ + + if (undoable) { + assert(obj->parent_type == PCB_PARENT_LAYER); + pcb = pcb_data_get_top(obj->parent.layer->parent.data); + } + + if (!undoable || (pcb == NULL)) { + unsigned char *th = pcb_obj_common_get_thermal(obj, 0, 1); + if (th != NULL) + *th = shape; + return 0; + } + + t = pcb_undo_alloc(pcb, &undo_anyobj_thermal, sizeof(undo_anyobj_thermal_t)); + t->pcb = pcb; + t->obj = obj; + t->shape = shape; + undo_anyobj_thermal_swap(t); + return 0; +} + +void *pcb_anyop_change_thermal(pcb_opctx_t *ctx, pcb_any_obj_t *obj) +{ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, obj)) + return NULL; + + if (pcb_anyobj_set_thermal(obj, ctx->chgtherm.style, 1) != 0) + return NULL; + + return obj; +} + Index: tags/2.3.0/src/thermal.h =================================================================== --- tags/2.3.0/src/thermal.h (nonexistent) +++ tags/2.3.0/src/thermal.h (revision 33253) @@ -0,0 +1,76 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_THERMAL_H +#define PCB_THERMAL_H + +#include "obj_common.h" +#include "operation.h" +#include "layer.h" +#include + +typedef enum pcb_thermal_e { + /* bit 0 and 1: shape */ + PCB_THERMAL_NOSHAPE = 0, /* padstack: no shape shall be drawn, omit copper, no connection */ + PCB_THERMAL_ROUND = 1, + PCB_THERMAL_SHARP = 2, + PCB_THERMAL_SOLID = 3, + + /* bit 2: orientation */ + PCB_THERMAL_DIAGONAL = 4, + + /* bit 3: do we have a thermal at all? */ + PCB_THERMAL_ON = 8 +} pcb_thermal_t; + +/* convert the textual version of thermal to a bitmask */ +pcb_thermal_t pcb_thermal_str2bits(const char *str); + +/* convert a bitmask to a single word of thermal description and remove the + affected bits from bits. Call this repeatedly until bits == 0 to get + all words. */ +const char *pcb_thermal_bits2str(pcb_thermal_t *bits); + +/* Converts all bits of a thermal bitmask to a string that is: + - empty if there is no thermal + - starts with n, o, x or @ for no-shape, round, sharp or solid + - ends in d if diagonal +*/ +void pcb_thermal_bits2chars(char dst[3], pcb_thermal_t bits); + + +rnd_polyarea_t *pcb_thermal_area(pcb_board_t *p, pcb_any_obj_t *obj, rnd_layer_id_t lid, pcb_poly_t *in_poly); +rnd_polyarea_t *pcb_thermal_area_line(pcb_board_t *pcb, pcb_line_t *line, rnd_layer_id_t lid, pcb_poly_t *in_poly); +rnd_polyarea_t *pcb_thermal_area_poly(pcb_board_t *pcb, pcb_poly_t *poly, rnd_layer_id_t lid, pcb_poly_t *in_poly); +rnd_polyarea_t *pcb_thermal_area_pstk(pcb_board_t *pcb, pcb_pstk_t *ps, rnd_layer_id_t lid, pcb_poly_t *in_poly); + +unsigned char pcb_themal_style_old2new(rnd_cardinal_t t); +rnd_cardinal_t pcb_themal_style_new2old(unsigned char t); + +void *pcb_anyop_change_thermal(pcb_opctx_t *ctx, pcb_any_obj_t *ps); + + +#endif Index: tags/2.3.0/src/tool_logic.c =================================================================== --- tags/2.3.0/src/tool_logic.c (nonexistent) +++ tags/2.3.0/src/tool_logic.c (revision 33253) @@ -0,0 +1,201 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include "event.h" +#include +#include +#include +#include + +#include "board.h" +#include "conf_core.h" +#include "crosshair.h" +#include "data.h" +#include "draw.h" + +#include "tool_logic.h" + +static void tool_logic_chg_layer(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +static void pcb_release_mode(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +static void pcb_press_mode(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); + +/*** Generic part, all rnd apps should do something like this ***/ + +static char tool_logic_cookie[] = "tool_logic"; + +static void tool_logic_chg_tool(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + int *ok = argv[1].d.p; + int id = argv[2].d.i; + pcb_board_t *pcb = (pcb_board_t *)hidlib; + if (pcb->RatDraw && !(rnd_tool_get(id)->user_flags & PCB_TLF_RAT)) { + rnd_message(RND_MSG_WARNING, "That tool can not be used on the rat layer!\n"); + *ok = 0; + } +} + +static void tool_logic_chg_mode(rnd_conf_native_t *cfg, int arr_idx) +{ + rnd_tool_chg_mode(&PCB->hidlib); +} + + +void pcb_tool_logic_init(void) +{ + static rnd_conf_hid_callbacks_t cbs_mode; + static rnd_conf_hid_id_t tool_conf_id; + rnd_conf_native_t *n_mode = rnd_conf_get_field("editor/mode"); + tool_conf_id = rnd_conf_hid_reg(tool_logic_cookie, NULL); + + if (n_mode != NULL) { + memset(&cbs_mode, 0, sizeof(rnd_conf_hid_callbacks_t)); + cbs_mode.val_change_post = tool_logic_chg_mode; + rnd_conf_hid_set_cb(n_mode, tool_conf_id, &cbs_mode); + } + + rnd_event_bind(RND_EVENT_TOOL_SELECT_PRE, tool_logic_chg_tool, NULL, tool_logic_cookie); + rnd_event_bind(RND_EVENT_TOOL_RELEASE, pcb_release_mode, NULL, tool_logic_cookie); + rnd_event_bind(RND_EVENT_TOOL_PRESS, pcb_press_mode, NULL, tool_logic_cookie); + rnd_event_bind(PCB_EVENT_LAYERVIS_CHANGED, tool_logic_chg_layer, NULL, tool_logic_cookie); +} + +void pcb_tool_logic_uninit(void) +{ + rnd_event_unbind_allcookie(tool_logic_cookie); + rnd_conf_hid_unreg(tool_logic_cookie); +} + +/*** pcb-rnd-specific parts ***/ + + +static void tool_logic_chg_layer(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + static int was_rat; + if (PCB->RatDraw && !was_rat && !(rnd_tool_get(rnd_conf.editor.mode)->user_flags & PCB_TLF_RAT)) + rnd_tool_select_by_name(&PCB->hidlib, "line"); + was_rat = PCB->RatDraw; +} + +static void get_grid_lock_coordinates(int type, void *ptr1, void *ptr2, void *ptr3, rnd_coord_t * x, rnd_coord_t * y) +{ + switch (type) { + case PCB_OBJ_LINE: + *x = ((pcb_line_t *) ptr2)->Point1.X; + *y = ((pcb_line_t *) ptr2)->Point1.Y; + break; + case PCB_OBJ_TEXT: + *x = ((pcb_text_t *) ptr2)->X; + *y = ((pcb_text_t *) ptr2)->Y; + break; + case PCB_OBJ_POLY: + *x = ((pcb_poly_t *) ptr2)->Points[0].X; + *y = ((pcb_poly_t *) ptr2)->Points[0].Y; + break; + + case PCB_OBJ_LINE_POINT: + case PCB_OBJ_POLY_POINT: + case PCB_OBJ_GFX_POINT: + *x = ((rnd_point_t *) ptr3)->X; + *y = ((rnd_point_t *) ptr3)->Y; + break; + case PCB_OBJ_ARC: + pcb_arc_get_end((pcb_arc_t *) ptr2, 0, x, y); + break; + case PCB_OBJ_ARC_POINT: + if (ptr3 != NULL) /* need to check because: if snap off, there's no known endpoint (leave x;y as is, then) */ + pcb_arc_get_end((pcb_arc_t *) ptr2, ((*(int **)ptr3) != pcb_arc_start_ptr), x, y); + break; + } +} + +void pcb_tool_attach_for_copy(rnd_hidlib_t *hl, rnd_coord_t PlaceX, rnd_coord_t PlaceY, rnd_bool do_rubberband) +{ + rnd_coord_t mx = 0, my = 0; + + rnd_event(hl, PCB_EVENT_RUBBER_RESET, NULL); + if (!conf_core.editor.snap_pin) { + /* dither the grab point so that the mark, center, etc + * will end up on a grid coordinate + */ + get_grid_lock_coordinates(pcb_crosshair.AttachedObject.Type, + pcb_crosshair.AttachedObject.Ptr1, + pcb_crosshair.AttachedObject.Ptr2, pcb_crosshair.AttachedObject.Ptr3, &mx, &my); + mx = rnd_grid_fit(mx, hl->grid, hl->grid_ox) - mx; + my = rnd_grid_fit(my, hl->grid, hl->grid_oy) - my; + } + pcb_crosshair.AttachedObject.X = PlaceX - mx; + pcb_crosshair.AttachedObject.Y = PlaceY - my; + if ((!pcb_marked.status || conf_core.editor.local_ref) && !pcb_marked.user_placed) + pcb_crosshair_set_local_ref(PlaceX - mx, PlaceY - my, rnd_true); + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_SECOND; + + /* get all attached objects if necessary */ + if (do_rubberband && conf_core.editor.rubber_band_mode) + rnd_event(hl, PCB_EVENT_RUBBER_LOOKUP_LINES, "ippp", pcb_crosshair.AttachedObject.Type, pcb_crosshair.AttachedObject.Ptr1, pcb_crosshair.AttachedObject.Ptr2, pcb_crosshair.AttachedObject.Ptr3); + if (do_rubberband && + (pcb_crosshair.AttachedObject.Type == PCB_OBJ_SUBC || + pcb_crosshair.AttachedObject.Type == PCB_OBJ_PSTK || + pcb_crosshair.AttachedObject.Type == PCB_OBJ_LINE || pcb_crosshair.AttachedObject.Type == PCB_OBJ_LINE_POINT)) + rnd_event(hl, PCB_EVENT_RUBBER_LOOKUP_RATS, "ippp", pcb_crosshair.AttachedObject.Type, pcb_crosshair.AttachedObject.Ptr1, pcb_crosshair.AttachedObject.Ptr2, pcb_crosshair.AttachedObject.Ptr3); +} + +void pcb_tool_notify_block(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + switch (pcb_crosshair.AttachedBox.State) { + case PCB_CH_STATE_FIRST: /* setup first point */ + pcb_crosshair.AttachedBox.Point1.X = pcb_crosshair.AttachedBox.Point2.X = pcb_crosshair.X; + pcb_crosshair.AttachedBox.Point1.Y = pcb_crosshair.AttachedBox.Point2.Y = pcb_crosshair.Y; + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_SECOND; + break; + + case PCB_CH_STATE_SECOND: /* setup second point */ + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_THIRD; + break; + } + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +/*** old helpers ***/ + +static void pcb_release_mode(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pcb_draw(); +} + +static void pcb_press_mode(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pcb_board_t *pcb = (pcb_board_t *)hidlib; + + if (conf_core.temp.rat_warn) { + if (pcb_data_clear_flag(pcb->Data, PCB_FLAG_WARN, 1, 0) > 0) + pcb_board_set_changed_flag(pcb, rnd_true); + } + pcb_draw(); +} Index: tags/2.3.0/src/tool_logic.h =================================================================== --- tags/2.3.0/src/tool_logic.h (nonexistent) +++ tags/2.3.0/src/tool_logic.h (revision 33253) @@ -0,0 +1,42 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_TOOL_LOGIC_H +#define PCB_TOOL_LOGIC_H + +typedef enum { /* bitfield */ + PCB_TLF_RAT = 1, /* tool can be used on the rat layer */ + PCB_TLF_EDIT = 2 /* tool can edit the geometry of existing objects */ +} pcb_tool_user_flags_t; + +void pcb_tool_logic_init(void); +void pcb_tool_logic_uninit(void); + +void pcb_tool_attach_for_copy(rnd_hidlib_t *hl, rnd_coord_t PlaceX, rnd_coord_t PlaceY, rnd_bool do_rubberband); +void pcb_tool_notify_block(void); /* create first or second corner of a marked block (when clicked) */ + + +#endif Index: tags/2.3.0/src/undo.c =================================================================== --- tags/2.3.0/src/undo.c (nonexistent) +++ tags/2.3.0/src/undo.c (revision 33253) @@ -0,0 +1,312 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* functions used to undo operations + * + * Description: + * There are two lists which hold + * - the uundo list (information about a command) + * - data of removed objects + * Both lists are organized as first-in-last-out which means that the undo + * list can always use the last entry of the remove list. + * A serial number is incremented whenever an operation is completed. + * An operation itself may consist of several basic instructions. + * E.g.: removing all selected objects is one operation with exactly one + * serial number even if the remove function is called several times. + * + * a lock flag ensures that no infinite loops occur + */ + +#include "config.h" + +#include +#include + +#include "board.h" +#include "change.h" +#include "data.h" +#include "draw.h" +#include +#include "event.h" +#include "insert.h" +#include "polygon.h" +#include "remove.h" +#include "rotate.h" +#include "search.h" +#include "undo.h" +#include "undo_old.h" +#include "flag_str.h" +#include "conf_core.h" +#include + +#include "obj_poly_draw.h" + +static rnd_bool between_increment_and_restore = rnd_false; +static rnd_bool added_undo_between_increment_and_restore = rnd_false; + +pcb_data_t *pcb_removelist = NULL; /* lists of removed objects */ +static rnd_bool Locked = rnd_false; /* do not add entries if */ +rnd_bool pcb_undo_and_draw = rnd_true; /* flag is set; prevents from infinite loops */ +uundo_list_t pcb_uundo; /* only the undo dialog box should have access to it */ + +void *pcb_undo_alloc(pcb_board_t *pcb, const uundo_oper_t *oper, size_t data_len) +{ + return uundo_append(&pcb_uundo, oper, data_len); +} + +int pcb_undo(rnd_bool draw) +{ + int res; + + pcb_undo_and_draw = draw; + + if (pcb_uundo.num_undo == 0) { + rnd_message(RND_MSG_INFO, "Nothing to undo - buffer is empty\n"); + return -1; + } + + if (pcb_uundo.serial == 0) { + rnd_message(RND_MSG_ERROR, "ERROR: Attempt to pcb_undo() with Serial == 0\n Please save your work and report this bug.\n"); + return -1; + } + + if ((pcb_uundo.tail != NULL) && (pcb_uundo.tail->serial > pcb_uundo.serial)) { + rnd_message(RND_MSG_ERROR, "ERROR: Bad undo serial number %d in undo stack - expecting %d or lower\n" + " Please save your work and report this bug.\n", pcb_uundo.tail->serial, pcb_uundo.serial); + + /* It is likely that the serial number got corrupted through some bad + * use of the pcb_undo_save_serial() / pcb_undo_restore_serial() APIs. + * + * Reset the serial number to be consistent with that of the last + * operation on the undo stack in the hope that this might clear + * the problem and allow the user to hit Undo again. + */ + pcb_uundo.serial = pcb_uundo.tail->serial + 1; + return -1; + } + + pcb_undo_lock(); /* lock undo module to prevent from loops */ + pcb_data_clip_inhibit_inc(PCB->Data); + res = uundo_undo(&pcb_uundo); + pcb_data_clip_inhibit_dec(PCB->Data, 1); + pcb_undo_unlock(); + + if (res != 0) + rnd_message(RND_MSG_ERROR, "ERROR: Failed to undo some operations\n"); + else if (pcb_undo_and_draw) + pcb_draw(); + + rnd_event(&PCB->hidlib, PCB_EVENT_UNDO_POST, "i", PCB_UNDO_EV_UNDO); + + return res; +} + +int pcb_undo_above(uundo_serial_t s_min) +{ + return uundo_undo_above(&pcb_uundo, s_min); +} + +int pcb_redo(rnd_bool draw) +{ + int res; + + pcb_undo_and_draw = draw; + + if (pcb_uundo.num_redo == 0) { + rnd_message(RND_MSG_INFO, "Nothing to redo. Perhaps changes have been made since last undo\n"); + return 0; + } + + if ((pcb_uundo.tail != NULL) && (pcb_uundo.tail->next != NULL) && (pcb_uundo.tail->next->serial > pcb_uundo.serial)) { + + rnd_message(RND_MSG_ERROR, "ERROR: Bad undo serial number %d in redo stack - expecting %d or higher\n" + " Please save your work and report this bug.\n", pcb_uundo.tail->next->serial, pcb_uundo.serial); + + /* It is likely that the serial number got corrupted through some bad + * use of the pcb_undo_save_serial() / pcb_undo_restore_serial() APIs. + * + * Reset the serial number to be consistent with that of the first + * operation on the redo stack in the hope that this might clear + * the problem and allow the user to hit Redo again. + */ + + pcb_uundo.serial = pcb_uundo.tail->next->serial; + return 0; + } + + pcb_undo_lock(); /* lock undo module to prevent from loops */ + uundo_freeze_add(&pcb_uundo); + res = uundo_redo(&pcb_uundo); + uundo_unfreeze_add(&pcb_uundo); + pcb_undo_unlock(); + + if (res != 0) + rnd_message(RND_MSG_ERROR, "ERROR: Failed to redo some operations\n"); + else if (pcb_undo_and_draw) + pcb_draw(); + + rnd_event(&PCB->hidlib, PCB_EVENT_UNDO_POST, "i", PCB_UNDO_EV_REDO); + + return res; +} + +/* --------------------------------------------------------------------------- + * restores the serial number of the undo list + */ +void pcb_undo_restore_serial(void) +{ + if (added_undo_between_increment_and_restore) + rnd_message(RND_MSG_ERROR, "ERROR: Operations were added to the Undo stack with an incorrect serial number\n"); + between_increment_and_restore = rnd_false; + added_undo_between_increment_and_restore = rnd_false; + uundo_restore_serial(&pcb_uundo); +} + +/* --------------------------------------------------------------------------- + * saves the serial number of the undo list + */ +void pcb_undo_save_serial(void) +{ + pcb_bumped = rnd_false; + between_increment_and_restore = rnd_false; + added_undo_between_increment_and_restore = rnd_false; + uundo_save_serial(&pcb_uundo); +} + +/* --------------------------------------------------------------------------- + * increments the serial number of the undo list + * it's not done automatically because some operations perform more + * than one request with the same serial # + */ +void pcb_undo_inc_serial(void) +{ + if (!Locked) { + /* Set the changed flag if anything was added prior to this bump */ + if ((pcb_uundo.tail != NULL) && (pcb_uundo.tail->serial == pcb_uundo.serial)) + pcb_board_set_changed_flag(PCB, rnd_true); + + uundo_inc_serial(&pcb_uundo); + pcb_bumped = rnd_true; + between_increment_and_restore = rnd_true; + } +} + +/* --------------------------------------------------------------------------- + * releases memory of the undo- and remove list + */ +void pcb_undo_clear_list(rnd_bool Force) +{ + if (pcb_uundo.num_undo && (Force || rnd_hid_message_box(&PCB->hidlib, "warning", "clear undo buffer", "Do you reall want to clear 'undo' buffer?", "yes", 1, "no", 0, NULL) == 1)) { + uundo_list_clear(&pcb_uundo); + rnd_event(&PCB->hidlib, PCB_EVENT_UNDO_POST, "i", PCB_UNDO_EV_CLEAR_LIST); + } +} + +/* --------------------------------------------------------------------------- + * set lock flag + */ +void pcb_undo_lock(void) +{ + Locked = rnd_true; +} + +/* --------------------------------------------------------------------------- + * reset lock flag + */ +void pcb_undo_unlock(void) +{ + Locked = rnd_false; +} + +/* --------------------------------------------------------------------------- + * return undo lock state + */ +rnd_bool pcb_undoing(void) +{ + return Locked; +} + +uundo_serial_t pcb_undo_serial(void) +{ + return pcb_uundo.serial; +} + + +void pcb_undo_truncate_from(uundo_serial_t sfirst) +{ + uundo_list_truncate_from(&pcb_uundo, sfirst); + rnd_event(&PCB->hidlib, PCB_EVENT_UNDO_POST, "i", PCB_UNDO_EV_TRUNCATE); +} + +int undo_check(void) +{ + const char *res = uundo_check(&pcb_uundo, NULL); + +#ifndef NDEBUG + if (res != NULL) { + printf("Undo broken: %s\n", res); + uundo_dump(&pcb_uundo, NULL, NULL); + } +#endif + + return (res != NULL); +} + +#ifndef NDEBUG +void undo_dump(void) +{ + uundo_dump(&pcb_uundo, NULL, NULL); +} +#endif + +size_t pcb_num_undo(void) +{ + return pcb_uundo.num_undo; +} + +void pcb_undo_freeze_serial(void) +{ + uundo_freeze_serial(&pcb_uundo); +} + +void pcb_undo_unfreeze_serial(void) +{ + uundo_unfreeze_serial(&pcb_uundo); +} + + +void pcb_undo_freeze_add(void) +{ + uundo_freeze_add(&pcb_uundo); +} + +void pcb_undo_unfreeze_add(void) +{ + uundo_unfreeze_add(&pcb_uundo); +} + Index: tags/2.3.0/src/undo.h =================================================================== --- tags/2.3.0/src/undo.h (nonexistent) +++ tags/2.3.0/src/undo.h (revision 33253) @@ -0,0 +1,80 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_UNDO_H +#define PCB_UNDO_H + +#include +#include + +/* Temporary for compatibility */ +#include "undo_old.h" + +typedef enum pcb_undo_ev_e { + PCB_UNDO_EV_UNDO, + PCB_UNDO_EV_REDO, + PCB_UNDO_EV_CLEAR_LIST, + PCB_UNDO_EV_TRUNCATE +} pcb_undo_ev_t; + +void *pcb_undo_alloc(pcb_board_t *pcb, const uundo_oper_t *oper, size_t data_len); +int pcb_undo(rnd_bool); +int pcb_redo(rnd_bool); +int pcb_undo_above(uundo_serial_t s_min); + +void pcb_undo_inc_serial(void); +void pcb_undo_save_serial(void); +void pcb_undo_restore_serial(void); +void pcb_undo_clear_list(rnd_bool); + +void pcb_undo_lock(void); +void pcb_undo_unlock(void); +rnd_bool pcb_undoing(void); + +uundo_serial_t pcb_undo_serial(void); +void pcb_undo_truncate_from(uundo_serial_t sfirst); + +void pcb_undo_freeze_serial(void); +void pcb_undo_unfreeze_serial(void); +void pcb_undo_freeze_add(void); +void pcb_undo_unfreeze_add(void); + +/* Return the number of undo slots in use */ +size_t pcb_num_undo(void); + +/* Returns 0 if undo integrity is not broken */ +int undo_check(void); + +void undo_dump(void); + +/* temporary */ +#include +extern pcb_data_t *pcb_removelist; +extern rnd_bool pcb_undo_and_draw; + +#endif Index: tags/2.3.0/src/undo_act.c =================================================================== --- tags/2.3.0/src/undo_act.c (nonexistent) +++ tags/2.3.0/src/undo_act.c (revision 33253) @@ -0,0 +1,158 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" +#include "conf_core.h" + +#include "board.h" +#include +#include "data.h" +#include +#include +#include "funchash_core.h" + +#include "undo.h" +#include "undo_act.h" +#include "polygon.h" +#include "search.h" + +#include "obj_line_draw.h" + +#include + +static const char pcb_acts_Atomic[] = "Atomic(Save|Restore|Close|Block)"; +static const char pcb_acth_Atomic[] = "Save or restore the undo serial number."; +/* DOC: atomic.html */ +fgw_error_t pcb_act_Atomic(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + RND_ACT_CONVARG(1, FGW_KEYWORD, Atomic, op = fgw_keyword(&argv[1])); + + switch (op) { + case F_Save: + pcb_undo_save_serial(); + break; + case F_Restore: + pcb_undo_restore_serial(); + break; + case F_Close: + pcb_undo_restore_serial(); + pcb_undo_inc_serial(); + break; + case F_Block: + pcb_undo_restore_serial(); + if (pcb_bumped) + pcb_undo_inc_serial(); + break; + case F_Freeze: + pcb_undo_freeze_serial(); + break; + case F_UnFreeze: + case F_Thaw: + pcb_undo_unfreeze_serial(); + break; + default: + rnd_message(RND_MSG_ERROR, "Invalid argument for Atomic()\n"); + RND_ACT_IRES(-1); + return 0; + } + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_Undo[] = "undo()\n" "undo(ClearList|FreezeSerial|UnfreezeSerial|IncSerial)"; + +static const char pcb_acth_Undo[] = "Undo recent changes."; + +/* DOC: undo.html */ + +fgw_error_t pcb_act_Undo(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *function = NULL; + RND_ACT_MAY_CONVARG(1, FGW_STR, Undo, function = argv[1].val.str); + if (!function || !*function) { + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + if (rnd_tool_undo_act(RND_ACT_HIDLIB)) + if (pcb_undo(rnd_true) == 0) + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + } + else if (function) { + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + if (rnd_strcasecmp(function, "ClearList") == 0) + pcb_undo_clear_list(rnd_false); + else if (rnd_strcasecmp(function, "FreezeSerial") == 0) + pcb_undo_freeze_serial(); + else if (rnd_strcasecmp(function, "UnFreezeSerial") == 0) + pcb_undo_unfreeze_serial(); + else if (rnd_strcasecmp(function, "IncSerial") == 0) + pcb_undo_inc_serial(); + } + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- */ + +static const char pcb_acts_Redo[] = "redo()"; + +static const char pcb_acth_Redo[] = "Redo recent \"undo\" operations."; + +/* DOC: redo.html */ + +fgw_error_t pcb_act_Redo(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_false); + if (rnd_tool_redo_act(RND_ACT_HIDLIB)) + if (pcb_redo(rnd_true)) + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + rnd_hid_notify_crosshair_change(RND_ACT_HIDLIB, rnd_true); + RND_ACT_IRES(0); + return 0; +} + + +static rnd_action_t undo_action_list[] = { + {"Atomic", pcb_act_Atomic, pcb_acth_Atomic, pcb_acts_Atomic}, + {"Undo", pcb_act_Undo, pcb_acth_Undo, pcb_acts_Undo}, + {"Redo", pcb_act_Redo, pcb_acth_Redo, pcb_acts_Redo} +}; + +void pcb_undo_act_init2(void) +{ + RND_REGISTER_ACTIONS(undo_action_list, NULL); +} + + Index: tags/2.3.0/src/undo_act.h =================================================================== --- tags/2.3.0/src/undo_act.h (nonexistent) +++ tags/2.3.0/src/undo_act.h (revision 33253) @@ -0,0 +1,4 @@ +/* Publish actions - these may be useful for other actions */ +fgw_error_t pcb_act_Undo(fgw_arg_t *res, int oargc, fgw_arg_t *oargv); +fgw_error_t pcb_act_Redo(fgw_arg_t *res, int oargc, fgw_arg_t *oargv); +fgw_error_t pcb_act_Atomic(fgw_arg_t *res, int oargc, fgw_arg_t *oargv); Index: tags/2.3.0/src/undo_old.c =================================================================== --- tags/2.3.0/src/undo_old.c (nonexistent) +++ tags/2.3.0/src/undo_old.c (revision 33253) @@ -0,0 +1,1388 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* functions used to undo operations + * + * Description: + * There are two lists which hold + * - information about a command + * - data of removed objects + * Both lists are organized as first-in-last-out which means that the undo + * list can always use the last entry of the remove list. + * A serial number is incremented whenever an operation is completed. + * An operation itself may consist of several basic instructions. + * E.g.: removing all selected objects is one operation with exactly one + * serial number even if the remove function is called several times. + * + * a lock flag ensures that no infinite loops occur + */ + +#include "config.h" + +#include +#include + +#include "board.h" +#include "change.h" +#include "data.h" +#include "draw.h" +#include "move.h" +#include +#include "extobj.h" +#include "insert.h" +#include "polygon.h" +#include "remove.h" +#include "rotate.h" +#include "search.h" +#include "undo.h" +#include "undo_old.h" +#include "flag_str.h" +#include "conf_core.h" +#include +#include "netlist.h" + +#include "obj_poly_draw.h" +#include "obj_subc_parent.h" +#include "obj_term.h" + +#include "brave.h" + +#define Locked pcb_undoing() + +/*** undo_old_str ***/ + +typedef struct { /* information about a change command */ + char *Name; +} ChangeNameType, *ChangeNameTypePtr; + +typedef struct { /* information about a move command */ + rnd_coord_t DX, DY; /* movement vector */ +} MoveType, *MoveTypePtr; + +typedef struct { + long p_subc_id; /* parent subc ID (0 if parent is not a subc) */ + int p_subc_layer; /* parent subc layer index, for layer objects */ +} Removed; + +typedef struct { /* information about removed polygon points */ + rnd_coord_t X, Y; /* data */ + int ID; + rnd_cardinal_t Index; /* index in a polygons array of points */ + rnd_bool last_in_contour; /* Whether the point was the last in its contour */ +} RemovedPointType, *RemovedPointTypePtr; + +typedef struct { /* information about rotation */ + rnd_coord_t CenterX, CenterY; /* center of rotation */ + rnd_cardinal_t Steps; /* number of steps */ +} RotateType, *RotateTypePtr; + +typedef struct { /* information about moves between layers */ + rnd_cardinal_t OriginalLayer; /* the index of the original layer */ +} MoveToLayer; + +typedef struct { /* information about poly clear/restore */ + rnd_bool Clear; /* rnd_true was clear, rnd_false was restore */ + pcb_layer_t *Layer; +} ClearPolyType, *ClearPolyTypePtr; + +typedef struct { + rnd_angle_t angle[2]; +} AngleChangeType; + +typedef struct { /* information about netlist lib changes */ + pcb_net_t *old; + pcb_net_t *lib; +} NetlistChangeType, *NetlistChangeTypePtr; + +typedef struct { /* holds information about an operation */ + int Serial; /* serial number of operation */ + int Type; /* type of operation */ + pcb_objtype_t Kind; /* type of object with given ID */ + long int ID; /* object ID */ + union { /* some additional information */ + ChangeNameType ChangeName; + MoveType Move; + Removed Removed; + RemovedPointType RemovedPoint; + RotateType Rotate; + MoveToLayer MoveToLayer; + pcb_flag_t Flags; + rnd_coord_t Size; + ClearPolyType ClearPoly; + NetlistChangeType NetlistChange; + long int CopyID; + AngleChangeType AngleChange; + rnd_angle_t Angle; + } Data; +} UndoListType, *UndoListTypePtr; + + +/*** undo_old */ + + +#define DRAW_FLAGS (PCB_FLAG_RAT | PCB_FLAG_SELECTED | PCB_FLAG_HIDENAME | PCB_FLAG_HOLE | PCB_FLAG_OCTAGON | PCB_FLAG_FOUND | PCB_FLAG_CLEARLINE | PCB_FLAG_CLEARPOLY | PCB_FLAG_CLEARPOLYPOLY) +#define CLIP_FLAGS (PCB_FLAG_CLEARLINE | PCB_FLAG_CLEARPOLY | PCB_FLAG_CLEARPOLYPOLY) + +static rnd_bool UndoRotate90(UndoListTypePtr); +static rnd_bool UndoRotate(UndoListTypePtr); +static rnd_bool UndoChangeName(UndoListTypePtr); +static rnd_bool UndoCopyOrCreate(UndoListTypePtr); +static rnd_bool UndoMove(UndoListTypePtr); +static rnd_bool UndoRemove(UndoListTypePtr); +static rnd_bool UndoRemovePoint(UndoListTypePtr); +static rnd_bool UndoInsertPoint(UndoListTypePtr); +static rnd_bool UndoRemoveContour(UndoListTypePtr); +static rnd_bool UndoInsertContour(UndoListTypePtr); +static rnd_bool UndoMoveToLayer(UndoListTypePtr); +static rnd_bool UndoFlag(UndoListTypePtr); +static rnd_bool UndoOtherSide(UndoListTypePtr); +static rnd_bool UndoChangeSize(UndoListTypePtr); +static rnd_bool UndoChange2ndSize(UndoListTypePtr); +static rnd_bool UndoChangeAngles(UndoListTypePtr); +static rnd_bool UndoChangeRadii(UndoListTypePtr); +static rnd_bool UndoChangeClearSize(UndoListTypePtr); +static rnd_bool UndoClearPoly(UndoListTypePtr); + +#define PCB_OBJECT_ID(p) (((pcb_any_obj_t *) p)->ID) + +static void pcb_undo_old_free(void *udata); +static int pcb_undo_old_undo(void *udata); + +void pcb_undo_old_print(void *udata, char *dst, size_t dst_len) +{ + UndoListType *slot = udata; +#ifndef NDEBUG + const char *res = undo_type2str(slot->Type); + rnd_snprintf(dst, dst_len, "%s ser=%d id=%d", res, slot->Serial, slot->ID); +#else + sprintf(dst, "%d", slot->Type); +#endif + +} + +static const uundo_oper_t pcb_undo_old_oper = { + "core-old", + pcb_undo_old_free, + pcb_undo_old_undo, + pcb_undo_old_undo, /* redo is the same as undo */ + pcb_undo_old_print +}; + +static UndoListType *GetUndoSlot(int CommandType, long int ID, pcb_objtype_t Kind) +{ + UndoListType *slot = pcb_undo_alloc(PCB, &pcb_undo_old_oper, sizeof(UndoListType)); + + memset(slot, 0, sizeof(UndoListType)); + slot->Type = CommandType; + slot->ID = ID; + slot->Kind = Kind; + + return slot; +} + + +/* --------------------------------------------------------------------------- + * redraws the recovered object + */ +static void DrawRecoveredObject(pcb_any_obj_t *obj) +{ + pcb_draw_obj(obj); +} + +/* --------------------------------------------------------------------------- + * recovers an object from a 90 deg 'rotate' operation + * returns rnd_true if anything has been recovered + */ +static rnd_bool UndoRotate90(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + + /* lookup entry by it's ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type != PCB_OBJ_VOID) { + if (type == PCB_OBJ_LINE_POINT) /* rubber band, needs ptr3 */ + pcb_point_rotate90(ptr3, Entry->Data.Rotate.CenterX, Entry->Data.Rotate.CenterY, (4 - Entry->Data.Rotate.Steps) & 0x03); + else + pcb_obj_rotate90(PCB, ptr2, Entry->Data.Rotate.CenterX, Entry->Data.Rotate.CenterY, (4 - Entry->Data.Rotate.Steps) & 0x03); + Entry->Data.Rotate.Steps = (4 - Entry->Data.Rotate.Steps) & 0x03; + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers an object from an arbitrary angle 'rotate' operation + * returns rnd_true if anything has been recovered + */ +static rnd_bool UndoRotate(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + + /* lookup entry by it's ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type != PCB_OBJ_VOID) { + pcb_obj_rotate(PCB, ptr2, Entry->Data.Rotate.CenterX, Entry->Data.Rotate.CenterY, -(Entry->Data.Angle)); + Entry->Data.Angle = -(Entry->Data.Angle); + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers an object from a clear/restore poly operation + * returns rnd_true if anything has been recovered + */ +static rnd_bool UndoClearPoly(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type != PCB_OBJ_VOID) { + if (Entry->Data.ClearPoly.Clear) + pcb_poly_restore_to_poly(PCB->Data, type, Entry->Data.ClearPoly.Layer, ptr3); + else + pcb_poly_clear_from_poly(PCB->Data, type, Entry->Data.ClearPoly.Layer, ptr3); + Entry->Data.ClearPoly.Clear = !Entry->Data.ClearPoly.Clear; + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers an object from a 'change name' operation + * returns rnd_true if anything has been recovered + */ +static rnd_bool UndoChangeName(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + + /* lookup entry by it's ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type != PCB_OBJ_VOID) { + Entry->Data.ChangeName.Name = (char *) (pcb_chg_obj_name(type, ptr1, ptr2, ptr3, Entry->Data.ChangeName.Name)); + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers an object from a ChangeAngles change operation + */ +static rnd_bool UndoChangeAngles(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + double old_sa, old_da; + + /* lookup entry by ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type == PCB_OBJ_ARC) { + pcb_layer_t *Layer = (pcb_layer_t *) ptr1; + pcb_arc_t *a = (pcb_arc_t *) ptr2; + pcb_poly_restore_to_poly(PCB->Data, a->type, ptr1, ptr2); + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) a); + old_sa = a->StartAngle; + old_da = a->Delta; + if (pcb_undo_and_draw) + pcb_erase_obj(type, Layer, a); + a->StartAngle = Entry->Data.AngleChange.angle[0]; + a->Delta = Entry->Data.AngleChange.angle[1]; + pcb_arc_bbox(a); + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) a); + pcb_poly_clear_from_poly(PCB->Data, a->type, ptr1, ptr2); + Entry->Data.AngleChange.angle[0] = old_sa; + Entry->Data.AngleChange.angle[1] = old_da; + pcb_draw_obj((pcb_any_obj_t *)a); + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers an object from a ChangeRadii change operation + */ +static rnd_bool UndoChangeRadii(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + rnd_coord_t old_w, old_h; + + /* lookup entry by ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type == PCB_OBJ_ARC) { + pcb_layer_t *Layer = (pcb_layer_t *) ptr1; + pcb_arc_t *a = (pcb_arc_t *) ptr2; + rnd_r_delete_entry(Layer->arc_tree, (rnd_box_t *) a); + old_w = a->Width; + old_h = a->Height; + if (pcb_undo_and_draw) + pcb_erase_obj(type, Layer, a); + a->Width = Entry->Data.Move.DX; + a->Height = Entry->Data.Move.DY; + pcb_arc_bbox(a); + rnd_r_insert_entry(Layer->arc_tree, (rnd_box_t *) a); + Entry->Data.Move.DX = old_w; + Entry->Data.Move.DY = old_h; + pcb_draw_obj((pcb_any_obj_t *)a); + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers an object from a clearance size change operation + */ +static rnd_bool UndoChangeClearSize(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + rnd_coord_t swap; + + /* lookup entry by ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type != PCB_OBJ_VOID) { + swap = ((pcb_line_t *) ptr2)->Clearance; + pcb_poly_restore_to_poly(PCB->Data, type, ptr1, ptr2); + if (pcb_undo_and_draw) + pcb_erase_obj(type, ptr1, ptr2); + ((pcb_line_t *) ptr2)->Clearance = Entry->Data.Size; + pcb_poly_clear_from_poly(PCB->Data, type, ptr1, ptr2); + Entry->Data.Size = swap; + if (pcb_undo_and_draw) + pcb_draw_obj((pcb_any_obj_t *)ptr2); + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers an object from a Size change operation + */ +static rnd_bool UndoChangeSize(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3, *ptr1e; + int type; + rnd_coord_t swap; + + /* lookup entry by ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + ptr1e = ptr1; + + if (type != PCB_OBJ_VOID) { + /* Size change for lines and arcs can. Text has it's own mechanism */ + swap = ((pcb_line_t *) ptr2)->Thickness; + pcb_poly_restore_to_poly(PCB->Data, type, ptr1, ptr2); + if ((pcb_undo_and_draw) && (ptr1e != NULL)) + pcb_erase_obj(type, ptr1e, ptr2); + ((pcb_line_t *) ptr2)->Thickness = Entry->Data.Size; + Entry->Data.Size = swap; + pcb_poly_clear_from_poly(PCB->Data, type, ptr1, ptr2); + if (pcb_undo_and_draw) + pcb_draw_obj((pcb_any_obj_t *)ptr2); + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers an object from a 2nd Size change operation + */ +static rnd_bool UndoChange2ndSize(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + rnd_coord_t swap; + + /* lookup entry by ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + + if (type == PCB_OBJ_TEXT) { /* thickness */ + swap = ((pcb_text_t *)ptr2)->thickness; + pcb_text_pre((pcb_text_t *)ptr2); + ((pcb_text_t *)ptr2)->thickness = Entry->Data.Size; + Entry->Data.Size = swap; + pcb_text_post((pcb_text_t *)ptr2); + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers an object from a Size change operation + */ +static rnd_bool UndoChangeRot(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + double swap; + rnd_bool ret = rnd_false; + + /* lookup entry by ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + + if (pcb_undo_and_draw) + pcb_draw_obj((pcb_any_obj_t *)ptr2); + + switch(type) { + case PCB_OBJ_PSTK: + swap = ((pcb_pstk_t *)ptr2)->rot; + pcb_pstk_pre(((pcb_pstk_t *)ptr2)); + ((pcb_pstk_t *)ptr2)->rot = Entry->Data.Size; + Entry->Data.Size = swap; + pcb_pstk_post(((pcb_pstk_t *)ptr2)); + ret = rnd_true; + break; + + case PCB_OBJ_TEXT: + swap = ((pcb_text_t *)ptr2)->rot; + pcb_text_pre(((pcb_text_t *)ptr2)); + ((pcb_text_t *)ptr2)->rot = Entry->Data.Size; + Entry->Data.Size = swap; + pcb_text_post(((pcb_text_t *)ptr2)); + ret = rnd_true; + break; + } + + if (pcb_undo_and_draw) + pcb_draw_obj((pcb_any_obj_t *)ptr2); + return ret; +} + +/* --------------------------------------------------------------------------- + * recovers an object from a FLAG change operation + */ +static rnd_bool UndoFlag(UndoListTypePtr Entry) +{ + void *ptr1, *ptr1e, *ptr2, *ptr3, *txt_save; + int type; + pcb_flag_t swap; + int must_redraw = 0, must_reclip = 0; + unsigned long oldflg; + + /* lookup entry by ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type != PCB_OBJ_VOID) { + pcb_flag_t f1, f2; + pcb_any_obj_t *obj = (pcb_any_obj_t *)ptr2; + + ptr1e = ptr1; + swap = obj->Flags; + + f1 = pcb_flag_mask(obj->Flags, ~DRAW_FLAGS); + f2 = pcb_flag_mask(Entry->Data.Flags, ~DRAW_FLAGS); + if (!PCB_FLAG_EQ(f1, f2)) + must_redraw = 1; + + f1 = pcb_flag_mask(obj->Flags, ~CLIP_FLAGS); + f2 = pcb_flag_mask(Entry->Data.Flags, ~CLIP_FLAGS); + if (!PCB_FLAG_EQ(f1, f2)) + must_reclip = 1; + + if (pcb_undo_and_draw && must_redraw && (ptr1e != NULL)) + pcb_erase_obj(type, ptr1e, ptr2); + + if (must_reclip) + pcb_poly_restore_to_poly(PCB->Data, obj->type, ptr1, ptr2); + + if (obj->type == PCB_OBJ_TEXT) { + oldflg = obj->Flags.f; + pcb_text_flagchg_pre((pcb_text_t *)obj, Entry->Data.Flags.f, &txt_save); + } + + obj->Flags = Entry->Data.Flags; + Entry->Data.Flags = swap; + + if (must_reclip) + pcb_poly_clear_from_poly(PCB->Data, obj->type, ptr1, ptr2); + + if (obj->type == PCB_OBJ_TEXT) + pcb_text_flagchg_post((pcb_text_t *)obj, oldflg, &txt_save); + + if (pcb_undo_and_draw && must_redraw) + pcb_draw_obj((pcb_any_obj_t *)ptr2); + return rnd_true; + } + rnd_message(RND_MSG_ERROR, "hace Internal error: Can't find ID %d type %08x\n", Entry->ID, Entry->Kind); + rnd_message(RND_MSG_ERROR, "for UndoFlag Operation. Previous flags: %s\n", pcb_strflg_f2s(Entry->Data.Flags, 0, NULL, 0)); + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers a subc from an other-side operation + * returns rnd_true if anything has been recovered + */ +static rnd_bool UndoOtherSide(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + + /* lookup entry by ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type == PCB_OBJ_SUBC) { + pcb_subc_t *subc = (pcb_subc_t *)ptr3; + if (pcb_undo_and_draw) + EraseSubc(subc); + pcb_subc_change_side(subc, Entry->Data.Move.DY); + if (pcb_undo_and_draw) + DrawSubc(subc); + return rnd_true; + } + rnd_message(RND_MSG_ERROR, "hace Internal error: UndoOtherside on object type %x\n", type); + return rnd_false; +} + +static void get_subc_parent_data(long subcid, rnd_layer_id_t subclayer, pcb_subc_t **subc, pcb_data_t **data, void **ptr1) +{ + if (subcid > 0) { /* need to use a subc layer - putting back a floater */ + void *p1, *p2, *p3; + if (pcb_search_obj_by_id(PCB->Data, &p1, &p2, &p3, subcid, PCB_OBJ_SUBC) != 0) { + *subc = p2; + if (subclayer < (*subc)->data->LayerN) { + *data = (*subc)->data; + *ptr1 = &(*data)->Layer[subclayer]; + } + } + } +} + +/* --------------------------------------------------------------------------- + * recovers an object from a 'copy' or 'create' operation + * returns rnd_true if anything has been recovered + */ +static rnd_bool UndoCopyOrCreate(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + pcb_subc_t *subc = NULL; + pcb_data_t *data = PCB->Data; + + /* lookup entry by it's ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type != PCB_OBJ_VOID) { + Removed *r = &Entry->Data.Removed; + get_subc_parent_data(r->p_subc_id, r->p_subc_layer, &subc, &data, &ptr1); + if (!pcb_removelist) + pcb_removelist = pcb_buffer_new(NULL); + if (pcb_undo_and_draw) + pcb_erase_obj(type, ptr1, ptr2); + /* in order to make this re-doable we move it to the pcb_removelist */ + pcb_move_obj_to_buffer(PCB, pcb_removelist, data, type, ptr1, ptr2, ptr3); + + if ((subc != NULL) && (((pcb_any_obj_t *)ptr2)->term != NULL)) + pcb_term_del(&subc->terminals, ((pcb_any_obj_t *)ptr2)->term, (pcb_any_obj_t *)ptr2); + + Entry->Type = PCB_UNDO_REMOVE; + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers an object from a 'move' operation + * returns rnd_true if anything has been recovered + */ +static rnd_bool UndoMove(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + + /* lookup entry by it's ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type != PCB_OBJ_VOID) { + pcb_move_obj(type, ptr1, ptr2, ptr3, -Entry->Data.Move.DX, -Entry->Data.Move.DY); + Entry->Data.Move.DX *= -1; + Entry->Data.Move.DY *= -1; + return rnd_true; + } + return rnd_false; +} + +/* ---------------------------------------------------------------------- + * recovers an object from a 'remove' operation + * returns rnd_true if anything has been recovered + */ +static rnd_bool UndoRemove(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + Removed *r = &Entry->Data.Removed; + pcb_data_t *data = PCB->Data; + pcb_subc_t *subc = NULL; + + if (!(pcb_brave & PCB_BRAVE_NOCLIPBATCH)) + pcb_data_clip_inhibit_inc(PCB->Data); + + /* lookup entry by it's ID */ + type = pcb_search_obj_by_id(pcb_removelist, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type != PCB_OBJ_VOID) { + get_subc_parent_data(r->p_subc_id, r->p_subc_layer, &subc, &data, &ptr1); + pcb_move_obj_to_buffer(PCB, data, pcb_removelist, type, ptr1, ptr2, ptr3); + if (pcb_undo_and_draw) + DrawRecoveredObject((pcb_any_obj_t *)ptr2); + Entry->Type = PCB_UNDO_CREATE; + + { /* if extended object's edit-obj is restored, make sure the corresponding subc is updated */ + pcb_any_obj_t *o = ptr2; + pcb_extobj_float_pre(o); + pcb_extobj_float_geo(o); + } + + if (!(pcb_brave & PCB_BRAVE_NOCLIPBATCH)) + pcb_data_clip_inhibit_dec(PCB->Data, 1); + + return rnd_true; + } + + if (!(pcb_brave & PCB_BRAVE_NOCLIPBATCH)) + pcb_data_clip_inhibit_dec(PCB->Data, 1); + + return rnd_false; +} + +/* ---------------------------------------------------------------------- + * recovers an object from a 'move to another layer' operation + * returns rnd_true if anything has been recovered + */ +static rnd_bool UndoMoveToLayer(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + int type; + rnd_layer_id_t swap; + + /* lookup entry by it's ID */ + type = pcb_search_obj_by_id(PCB->Data, &ptr1, &ptr2, &ptr3, Entry->ID, Entry->Kind); + if (type != PCB_OBJ_VOID) { + pcb_data_t *data; + pcb_any_obj_t *o = ptr2; + assert(o->parent_type == PCB_PARENT_LAYER); + assert(o->parent.layer != NULL); + assert(o->parent.layer->parent_type == PCB_PARENT_DATA); + data = o->parent.layer->parent.data; + swap = pcb_layer_id(data, o->parent.layer); + pcb_move_obj_to_layer(type, ptr1, ptr2, ptr3, pcb_get_layer(data, Entry->Data.MoveToLayer.OriginalLayer), rnd_true); + Entry->Data.MoveToLayer.OriginalLayer = swap; + return rnd_true; + } + return rnd_false; +} + +/* --------------------------------------------------------------------------- + * recovers a removed polygon point + * returns rnd_true on success + */ +static rnd_bool UndoRemovePoint(UndoListTypePtr Entry) +{ + pcb_layer_t *layer; + pcb_poly_t *polygon; + void *ptr3; + int type; + + /* lookup entry (polygon not point was saved) by it's ID */ + assert(Entry->Kind == PCB_OBJ_POLY); + type = pcb_search_obj_by_id(PCB->Data, (void **) &layer, (void **) &polygon, &ptr3, Entry->ID, Entry->Kind); + switch (type) { + case PCB_OBJ_POLY: /* restore the removed point */ + { + /* recover the point */ + if (pcb_undo_and_draw && layer->meta.real.vis) + pcb_poly_invalidate_erase(polygon); + pcb_insert_point_in_object(PCB_OBJ_POLY, layer, polygon, + &Entry->Data.RemovedPoint.Index, + Entry->Data.RemovedPoint.X, + Entry->Data.RemovedPoint.Y, rnd_true, Entry->Data.RemovedPoint.last_in_contour); + + polygon->Points[Entry->Data.RemovedPoint.Index].ID = Entry->Data.RemovedPoint.ID; + if (pcb_undo_and_draw && layer->meta.real.vis) + pcb_poly_invalidate_draw(layer, polygon); + Entry->Type = PCB_UNDO_INSERT_POINT; + Entry->ID = Entry->Data.RemovedPoint.ID; + Entry->Kind = PCB_OBJ_POLY_POINT; + return rnd_true; + } + + default: + return rnd_false; + } +} + +/* --------------------------------------------------------------------------- + * recovers an inserted polygon point + * returns rnd_true on success + */ +static rnd_bool UndoInsertPoint(UndoListTypePtr Entry) +{ + pcb_layer_t *layer; + pcb_poly_t *polygon; + rnd_point_t *pnt; + int type; + rnd_cardinal_t point_idx; + rnd_cardinal_t hole; + rnd_bool last_in_contour = rnd_false; + + assert((long int)Entry->Kind == PCB_OBJ_POLY_POINT); + /* lookup entry by it's ID */ + type = pcb_search_obj_by_id(PCB->Data, (void **) &layer, (void **) &polygon, (void **) &pnt, Entry->ID, Entry->Kind); + switch (type) { + case PCB_OBJ_POLY_POINT: /* removes an inserted polygon point */ + { + if (pcb_undo_and_draw && layer->meta.real.vis) + pcb_poly_invalidate_erase(polygon); + + /* Check whether this point was at the end of its contour. + * If so, we need to flag as such when re-adding the point + * so it goes back in the correct place + */ + point_idx = pcb_poly_point_idx(polygon, pnt); + for (hole = 0; hole < polygon->HoleIndexN; hole++) + if (point_idx == polygon->HoleIndex[hole] - 1) + last_in_contour = rnd_true; + if (point_idx == polygon->PointN - 1) + last_in_contour = rnd_true; + Entry->Data.RemovedPoint.last_in_contour = last_in_contour; + + Entry->Data.RemovedPoint.X = pnt->X; + Entry->Data.RemovedPoint.Y = pnt->Y; + Entry->Data.RemovedPoint.ID = pnt->ID; + Entry->ID = polygon->ID; + Entry->Kind = PCB_OBJ_POLY; + Entry->Type = PCB_UNDO_REMOVE_POINT; + Entry->Data.RemovedPoint.Index = point_idx; + pcb_destroy_object(PCB->Data, PCB_OBJ_POLY_POINT, layer, polygon, pnt); + if (pcb_undo_and_draw && layer->meta.real.vis) + pcb_poly_invalidate_draw(layer, polygon); + return rnd_true; + } + + default: + return rnd_false; + } +} + +static rnd_bool UndoSwapCopiedObject(UndoListTypePtr Entry) +{ + void *ptr1, *ptr2, *ptr3; + void *ptr1b, *ptr2b, *ptr3b; + pcb_any_obj_t *obj, *obj2; + int type; + long int swap_id; + + /* lookup entry by it's ID */ + type = pcb_search_obj_by_id(pcb_removelist, &ptr1, &ptr2, &ptr3, Entry->Data.CopyID, Entry->Kind); + if (type == PCB_OBJ_VOID) + return rnd_false; + + type = pcb_search_obj_by_id(PCB->Data, &ptr1b, &ptr2b, &ptr3b, Entry->ID, Entry->Kind); + if (type == PCB_OBJ_VOID) + return rnd_false; + + obj = (pcb_any_obj_t *) ptr2; + obj2 = (pcb_any_obj_t *) ptr2b; + + swap_id = obj->ID; + obj->ID = obj2->ID; + obj2->ID = swap_id; + + pcb_move_obj_to_buffer(PCB, pcb_removelist, PCB->Data, type, ptr1b, ptr2b, ptr3b); + + if (pcb_undo_and_draw) + DrawRecoveredObject((pcb_any_obj_t *)ptr2); + + obj = (pcb_any_obj_t *) pcb_move_obj_to_buffer(PCB, PCB->Data, pcb_removelist, type, ptr1, ptr2, ptr3); + if (Entry->Kind == PCB_OBJ_POLY) + pcb_poly_init_clip(PCB->Data, (pcb_layer_t *) ptr1b, (pcb_poly_t *) obj); + return rnd_true; +} + +/* --------------------------------------------------------------------------- + * recovers an removed polygon point + * returns rnd_true on success + */ +static rnd_bool UndoRemoveContour(UndoListTypePtr Entry) +{ + assert(Entry->Kind == PCB_OBJ_POLY); + return UndoSwapCopiedObject(Entry); +} + +/* --------------------------------------------------------------------------- + * recovers an inserted polygon point + * returns rnd_true on success + */ +static rnd_bool UndoInsertContour(UndoListTypePtr Entry) +{ + assert(Entry->Kind == PCB_OBJ_POLY); + return UndoSwapCopiedObject(Entry); +} + +static int pcb_undo_old_undo(void *ptr_) +{ + UndoListTypePtr ptr = ptr_; + switch (ptr->Type) { + case PCB_UNDO_CHANGENAME: + if (UndoChangeName(ptr)) + return 0; + break; + + case PCB_UNDO_CREATE: + if (UndoCopyOrCreate(ptr)) + return 0; + break; + + case PCB_UNDO_MOVE: + if (UndoMove(ptr)) + return 0; + break; + + case PCB_UNDO_REMOVE: + if (UndoRemove(ptr)) + return 0; + break; + + case PCB_UNDO_REMOVE_POINT: + if (UndoRemovePoint(ptr)) + return 0; + break; + + case PCB_UNDO_INSERT_POINT: + if (UndoInsertPoint(ptr)) + return 0; + break; + + case PCB_UNDO_REMOVE_CONTOUR: + if (UndoRemoveContour(ptr)) + return 0; + break; + + case PCB_UNDO_INSERT_CONTOUR: + if (UndoInsertContour(ptr)) + return 0; + break; + + case PCB_UNDO_ROTATE: + if (UndoRotate(ptr)) + return 0; + break; + + case PCB_UNDO_ROTATE90: + if (UndoRotate90(ptr)) + return 0; + break; + + case PCB_UNDO_CLEAR: + if (UndoClearPoly(ptr)) + return 0; + break; + + case PCB_UNDO_MOVETOLAYER: + if (UndoMoveToLayer(ptr)) + return 0; + break; + + case PCB_UNDO_FLAG: + if (UndoFlag(ptr)) + return 0; + break; + + case PCB_UNDO_CHANGESIZE: + if (UndoChangeSize(ptr)) + return 0; + break; + + case PCB_UNDO_CHANGE2SIZE: + if (UndoChange2ndSize(ptr)) + return 0; + break; + + case PCB_UNDO_CHANGEROT: + if (UndoChangeRot(ptr)) + return 0; + break; + + case PCB_UNDO_CHANGECLEARSIZE: + if (UndoChangeClearSize(ptr)) + return 0; + break; + + case PCB_UNDO_CHANGEANGLES: + if (UndoChangeAngles(ptr)) + return 0; + break; + + case PCB_UNDO_CHANGERADII: + if (UndoChangeRadii(ptr)) + return 0; + break; + + case PCB_UNDO_OTHERSIDE: + if (UndoOtherSide(ptr)) + return 0; + break; + } + return -1; +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of clearpoly objects + */ +void pcb_undo_add_obj_to_clear_poly(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_bool clear) +{ + UndoListTypePtr undo; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_CLEAR, PCB_OBJECT_ID(Ptr3), Type); + undo->Data.ClearPoly.Clear = clear; + undo->Data.ClearPoly.Layer = (pcb_layer_t *) Ptr1; + } +} + +/* --------------------------------------------------------------------------- + * adds an subc to the list of objects tossed to the other side + */ +void pcb_undo_add_subc_to_otherside(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t yoff) +{ + UndoListTypePtr undo; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_OTHERSIDE, PCB_OBJECT_ID(Ptr3), Type); + undo->Data.Move.DY = yoff; + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of 90-deg rotated objects + */ +void pcb_undo_add_obj_to_rotate90(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t CenterX, rnd_coord_t CenterY, unsigned int Steps) +{ + UndoListTypePtr undo; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_ROTATE90, PCB_OBJECT_ID(Ptr3), Type); + undo->Data.Rotate.CenterX = CenterX; + undo->Data.Rotate.CenterY = CenterY; + undo->Data.Rotate.Steps = Steps; + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of rotated objects + */ +void pcb_undo_add_obj_to_rotate(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t CenterX, rnd_coord_t CenterY, rnd_angle_t angle) +{ + UndoListTypePtr undo; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_ROTATE, PCB_OBJECT_ID(Ptr3), Type); + undo->Data.Rotate.CenterX = CenterX; + undo->Data.Rotate.CenterY = CenterY; + undo->Data.Angle = angle; + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of removed objects and removes it from + * the current PCB + */ +void pcb_undo_move_obj_to_remove(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + UndoListTypePtr Entry; + Removed *r; + pcb_any_obj_t *o = Ptr3; + pcb_subc_t *subc; + + if (Locked) + return; + + if (!pcb_removelist) + pcb_removelist = pcb_buffer_new(NULL); + + switch(o->type) { + case PCB_OBJ_SUBC: + /* UI special case: if a selected sucircuit is removed, restore selection after + the undo placed back the subc on the board; this is needed because + the code for subc move-to-buffer will remove selection flags from the + subc. Here we really pretend the user has first unselected the subc. */ + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, o)) + pcb_subc_select(PCB, (pcb_subc_t *)o, PCB_CHGFLG_CLEAR, 0); + break; + default: + break; + } + + Entry = GetUndoSlot(PCB_UNDO_REMOVE, PCB_OBJECT_ID(Ptr3), Type); + r = &Entry->Data.Removed; + r->p_subc_id = 0; + + switch(o->type) { + case PCB_OBJ_LINE: + case PCB_OBJ_ARC: + case PCB_OBJ_TEXT: + case PCB_OBJ_POLY: + case PCB_OBJ_GFX: + subc = pcb_obj_parent_subc(Ptr3); + if (subc != NULL) { + pcb_term_del(&subc->terminals, o->term, o); + r->p_subc_id = subc->ID; + r->p_subc_layer = o->parent.layer - subc->data->Layer; + } + break; + case PCB_OBJ_PSTK: + subc = pcb_obj_parent_subc(Ptr3); + if (subc != NULL) { + pcb_term_del(&subc->terminals, o->term, o); + r->p_subc_id = subc->ID; + } + break; +TODO("subc: floater subc-in-subc should remember its subc parent too") + default: + break; + } + + + pcb_move_obj_to_buffer(PCB, pcb_removelist, PCB->Data, Type, Ptr1, Ptr2, Ptr3); +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of removed polygon/... points + */ +void pcb_undo_add_obj_to_remove_point(int Type, void *Ptr1, void *Ptr2, rnd_cardinal_t index) +{ + UndoListTypePtr undo; + pcb_poly_t *polygon = (pcb_poly_t *) Ptr2; + rnd_cardinal_t hole; + rnd_bool last_in_contour = rnd_false; + + if (!Locked) { + switch (Type) { + case PCB_OBJ_POLY_POINT: + { + /* save the ID of the parent object; else it will be + * impossible to recover the point + */ + undo = GetUndoSlot(PCB_UNDO_REMOVE_POINT, PCB_OBJECT_ID(polygon), PCB_OBJ_POLY); + undo->Data.RemovedPoint.X = polygon->Points[index].X; + undo->Data.RemovedPoint.Y = polygon->Points[index].Y; + undo->Data.RemovedPoint.ID = polygon->Points[index].ID; + undo->Data.RemovedPoint.Index = index; + + /* Check whether this point was at the end of its contour. + * If so, we need to flag as such when re-adding the point + * so it goes back in the correct place + */ + for (hole = 0; hole < polygon->HoleIndexN; hole++) + if (index == polygon->HoleIndex[hole] - 1) + last_in_contour = rnd_true; + if (index == polygon->PointN - 1) + last_in_contour = rnd_true; + undo->Data.RemovedPoint.last_in_contour = last_in_contour; + } + break; + } + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of inserted polygon/... points + */ +void pcb_undo_add_obj_to_insert_point(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + if (!Locked) + GetUndoSlot(PCB_UNDO_INSERT_POINT, PCB_OBJECT_ID(Ptr3), Type); +} + +static void CopyObjectToUndoList(int undo_type, int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + UndoListTypePtr undo; + pcb_any_obj_t *copy; + + if (Locked) + return; + + if (!pcb_removelist) + pcb_removelist = pcb_buffer_new(NULL); + + undo = GetUndoSlot(undo_type, PCB_OBJECT_ID(Ptr2), Type); + copy = (pcb_any_obj_t *) pcb_copy_obj_to_buffer(PCB, pcb_removelist, PCB->Data, Type, Ptr1, Ptr2, Ptr3); + undo->Data.CopyID = copy->ID; +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of removed contours + * (Actually just takes a copy of the whole polygon to restore) + */ +void pcb_undo_add_obj_to_remove_contour(int Type, pcb_layer_t * Layer, pcb_poly_t * Polygon) +{ + CopyObjectToUndoList(PCB_UNDO_REMOVE_CONTOUR, Type, Layer, Polygon, NULL); +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of insert contours + * (Actually just takes a copy of the whole polygon to restore) + */ +void pcb_undo_add_obj_to_insert_contour(int Type, pcb_layer_t * Layer, pcb_poly_t * Polygon) +{ + CopyObjectToUndoList(PCB_UNDO_INSERT_CONTOUR, Type, Layer, Polygon, NULL); +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of moved objects + */ +void pcb_undo_add_obj_to_move(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t DX, rnd_coord_t DY) +{ + UndoListTypePtr undo; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_MOVE, PCB_OBJECT_ID(Ptr3), Type); + undo->Data.Move.DX = DX; + undo->Data.Move.DY = DY; + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of objects with changed names + */ +void pcb_undo_add_obj_to_change_name(int Type, void *Ptr1, void *Ptr2, void *Ptr3, char *OldName) +{ + UndoListTypePtr undo; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_CHANGENAME, PCB_OBJECT_ID(Ptr3), Type); + undo->Data.ChangeName.Name = OldName; + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of objects moved to another layer + */ +void pcb_undo_add_obj_to_move_to_layer(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + UndoListTypePtr undo; + + if (!Locked) { + pcb_layer_t *ly = Ptr1; + undo = GetUndoSlot(PCB_UNDO_MOVETOLAYER, PCB_OBJECT_ID(Ptr3), Type); + undo->Data.MoveToLayer.OriginalLayer = pcb_layer_id(ly->parent.data, ly); + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of created objects + */ +void pcb_undo_add_obj_to_create(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + if (!Locked) + GetUndoSlot(PCB_UNDO_CREATE, PCB_OBJECT_ID(Ptr3), Type); + pcb_poly_clear_from_poly(PCB->Data, Type, Ptr1, Ptr2); +} + +void pcb_undo_add_obj_to_create_noclear(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + if (!Locked) + GetUndoSlot(PCB_UNDO_CREATE, PCB_OBJECT_ID(Ptr3), Type); +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of objects with flags changed + */ +void pcb_undo_add_obj_to_flag(void *obj_) +{ + UndoListTypePtr undo; + pcb_any_obj_t *obj = obj_; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_FLAG, PCB_OBJECT_ID(obj), obj->type); + undo->Data.Flags = obj->Flags; + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of objects with Size changes + */ +void pcb_undo_add_obj_to_size(int Type, void *ptr1, void *ptr2, void *ptr3) +{ + UndoListTypePtr undo; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_CHANGESIZE, PCB_OBJECT_ID(ptr2), Type); + switch (Type) { + case PCB_OBJ_LINE: + undo->Data.Size = ((pcb_line_t *) ptr2)->Thickness; + break; + case PCB_OBJ_TEXT: + undo->Data.Size = ((pcb_text_t *) ptr2)->Scale; + break; + case PCB_OBJ_ARC: + undo->Data.Size = ((pcb_arc_t *) ptr2)->Thickness; + break; + } + } +} + + +/* --------------------------------------------------------------------------- + * adds an object to the list of objects with Size changes + */ +void pcb_undo_add_obj_to_2nd_size(int Type, void *ptr1, void *ptr2, void *ptr3) +{ + UndoListTypePtr undo; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_CHANGE2SIZE, PCB_OBJECT_ID(ptr2), Type); + switch (Type) { + case PCB_OBJ_TEXT: + undo->Data.Size = ((pcb_text_t *) ptr2)->thickness; + break; + } + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of objects with rot changes + */ +void pcb_undo_add_obj_to_rot(int Type, void *ptr1, void *ptr2, void *ptr3) +{ + UndoListTypePtr undo; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_CHANGEROT, PCB_OBJECT_ID(ptr2), Type); + switch (Type) { + case PCB_OBJ_PSTK: + undo->Data.Size = ((pcb_pstk_t *) ptr2)->rot; + break; + case PCB_OBJ_TEXT: + undo->Data.Size = ((pcb_text_t *) ptr2)->rot; + break; + } + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of objects with Size changes + */ +void pcb_undo_add_obj_to_clear_size(int Type, void *ptr1, void *ptr2, void *ptr3) +{ + UndoListTypePtr undo; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_CHANGECLEARSIZE, PCB_OBJECT_ID(ptr2), Type); + switch (Type) { + case PCB_OBJ_LINE: + undo->Data.Size = ((pcb_line_t *) ptr2)->Clearance; + break; + case PCB_OBJ_ARC: + undo->Data.Size = ((pcb_arc_t *) ptr2)->Clearance; + break; + } + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of changed angles. Note that you must + * call this before changing the angles, passing the new start/delta. + */ +void pcb_undo_add_obj_to_change_angles(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + UndoListTypePtr undo; + pcb_arc_t *a = (pcb_arc_t *) Ptr3; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_CHANGEANGLES, PCB_OBJECT_ID(Ptr3), Type); + undo->Data.AngleChange.angle[0] = a->StartAngle; + undo->Data.AngleChange.angle[1] = a->Delta; + } +} + +/* --------------------------------------------------------------------------- + * adds an object to the list of changed radii. Note that you must + * call this before changing the radii, passing the new width/height. + */ +void pcb_undo_add_obj_to_change_radii(int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + UndoListTypePtr undo; + pcb_arc_t *a = (pcb_arc_t *) Ptr3; + + if (!Locked) { + undo = GetUndoSlot(PCB_UNDO_CHANGERADII, PCB_OBJECT_ID(Ptr3), Type); + undo->Data.Move.DX = a->Width; + undo->Data.Move.DY = a->Height; + } +} + +#ifndef NDEBUG +const char *undo_type2str(int type) +{ + static char buff[32]; + switch(type) { + case PCB_UNDO_CHANGENAME: return "changename"; + case PCB_UNDO_MOVE: return "move"; + case PCB_UNDO_REMOVE: return "remove"; + case PCB_UNDO_REMOVE_POINT: return "remove_point"; + case PCB_UNDO_INSERT_POINT: return "insert_point"; + case PCB_UNDO_REMOVE_CONTOUR: return "remove_contour"; + case PCB_UNDO_INSERT_CONTOUR: return "insert_contour"; + case PCB_UNDO_ROTATE90: return "rotate90"; + case PCB_UNDO_ROTATE: return "rotate"; + case PCB_UNDO_CREATE: return "create"; + case PCB_UNDO_MOVETOLAYER: return "movetolayer"; + case PCB_UNDO_FLAG: return "flag"; + case PCB_UNDO_CHANGESIZE: return "changesize"; + case PCB_UNDO_CHANGEROT: return "changerot"; + case PCB_UNDO_OTHERSIDE: return "otherside"; + case PCB_UNDO_CHANGECLEARSIZE: return "chngeclearsize"; + case PCB_UNDO_CHANGEANGLES: return "changeangles"; + case PCB_UNDO_CHANGERADII: return "changeradii"; + case PCB_UNDO_CLEAR: return "clear"; + } + sprintf(buff, "Unknown %d", type); + return buff; +} + +#endif + +static void pcb_undo_old_free(void *ptr_) +{ + UndoListTypePtr ptr = ptr_; + void *ptr1, *ptr2, *ptr3; + int type; + + switch (ptr->Type) { + case PCB_UNDO_CHANGENAME: + free(ptr->Data.ChangeName.Name); + break; + case PCB_UNDO_REMOVE: + type = pcb_search_obj_by_id(pcb_removelist, &ptr1, &ptr2, &ptr3, ptr->ID, ptr->Kind); + if (type != PCB_OBJ_VOID) + pcb_destroy_object(pcb_removelist, type, ptr1, ptr2, ptr3); + break; + default: + break; + } +} Index: tags/2.3.0/src/undo_old.h =================================================================== --- tags/2.3.0/src/undo_old.h (nonexistent) +++ tags/2.3.0/src/undo_old.h (revision 33253) @@ -0,0 +1,89 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* old undo infra: should be replaced by per operation local undo */ + +#ifndef PCB_UNDO_OLD_H +#define PCB_UNDO_OLD_H + +#include "global_typedefs.h" + +void pcb_undo_move_obj_to_remove(int, void *, void *, void *); +void pcb_undo_add_obj_to_remove_point(int, void *, void *, rnd_cardinal_t); +void pcb_undo_add_obj_to_insert_point(int, void *, void *, void *); +void pcb_undo_add_obj_to_remove_contour(int, pcb_layer_t *, pcb_poly_t *); +void pcb_undo_add_obj_to_insert_contour(int, pcb_layer_t *, pcb_poly_t *); +void pcb_undo_add_obj_to_move(int, void *, void *, void *, rnd_coord_t, rnd_coord_t); +void pcb_undo_add_obj_to_change_name(int, void *, void *, void *, char *); +void pcb_undo_add_obj_to_change_pinnum(int, void *, void *, void *, char *); +void pcb_undo_add_obj_to_rotate90(int, void *, void *, void *, rnd_coord_t, rnd_coord_t, unsigned int); +void pcb_undo_add_obj_to_rotate(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t CenterX, rnd_coord_t CenterY, rnd_angle_t angle); +void pcb_undo_add_obj_to_create(int, void *, void *, void *); +void pcb_undo_add_obj_to_create_noclear(int Type, void *Ptr1, void *Ptr2, void *Ptr3); +void pcb_undo_add_obj_to_create_nocreate(int, void *, void *, void *); +void pcb_undo_add_subc_to_otherside(int Type, void *Ptr1, void *Ptr2, void *Ptr3, rnd_coord_t yoff); +void pcb_undo_add_obj_to_move_to_layer(int, void *, void *, void *); +void pcb_undo_add_obj_to_flag(void *obj); +void pcb_undo_add_obj_to_size(int, void *, void *, void *); +void pcb_undo_add_obj_to_2nd_size(int Type, void *ptr1, void *ptr2, void *ptr3); +void pcb_undo_add_obj_to_rot(int Type, void *ptr1, void *ptr2, void *ptr3); +void pcb_undo_add_obj_to_clear_size(int, void *, void *, void *); +void pcb_undo_add_obj_to_change_angles(int, void *, void *, void *); +void pcb_undo_add_obj_to_change_radii(int, void *, void *, void *); +void pcb_undo_add_obj_to_clear_poly(int, void *, void *, void *, rnd_bool); + +/* --------------------------------------------------------------------------- + * define supported types of undo operations + * note these must be separate bits now + */ +typedef enum { + PCB_UNDO_CHANGENAME = 0x000001, /* change of names */ + PCB_UNDO_MOVE = 0x000002, /* moving objects */ + PCB_UNDO_REMOVE = 0x000004, /* removing objects */ + PCB_UNDO_REMOVE_POINT = 0x000008, /* removing polygon/... points */ + PCB_UNDO_INSERT_POINT = 0x000010, /* inserting polygon/... points */ + PCB_UNDO_REMOVE_CONTOUR = 0x000020, /* removing a contour from a polygon */ + PCB_UNDO_INSERT_CONTOUR = 0x000040, /* inserting a contour from a polygon */ + PCB_UNDO_ROTATE90 = 0x000080, /* rotations by 90 deg steps */ + PCB_UNDO_CREATE = 0x000100, /* creation of objects */ + PCB_UNDO_MOVETOLAYER = 0x000200, /* moving objects to */ + PCB_UNDO_FLAG = 0x000400, /* toggling SELECTED flag */ + PCB_UNDO_CHANGESIZE = 0x000800, /* change size of object */ + PCB_UNDO_CHANGECLEARSIZE = 0x004000, /* change clearance size */ + PCB_UNDO_CHANGEANGLES = 0x010000, /* change arc angles */ + PCB_UNDO_CLEAR = 0x040000, /* clear/restore to polygons */ + PCB_UNDO_CHANGERADII = 0x200000, /* change arc radii */ + PCB_UNDO_OTHERSIDE = 0x400000, /* change side of board (subcircuit) */ + PCB_UNDO_ROTATE = 0x800000, /* rotations at arbitrary angle */ + PCB_UNDO_CHANGEROT = 0x1000000, /* change internal/self rotation of an object */ + PCB_UNDO_CHANGE2SIZE = 0x2000000 /* change 2nd size of object */ +} pcb_undo_op_t; + +const char *undo_type2str(int type); + +#endif Index: tags/2.3.0/src/view.c =================================================================== --- tags/2.3.0/src/view.c (nonexistent) +++ tags/2.3.0/src/view.c (revision 33253) @@ -0,0 +1,576 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include "config.h" + +#include "idpath.h" +#include + +#define TDL_DONT_UNDEF +#include "view.h" +#include +#undef TDL_DONT_UNDEF +#include + +#include + +#include + +#include +#include +#include +#include + +#include "conf_core.h" + +static unsigned long int pcb_view_next_uid = 0; + +void pcb_view_free(pcb_view_t *item) +{ + pcb_view_list_remove(item); + pcb_idpath_list_clear(&item->objs[0]); + pcb_idpath_list_clear(&item->objs[1]); + free(item->title); + + if (item->long_desc.used == 0) + free(item->description); + else + gds_uninit(&item->long_desc); + + free(item); +} + +void pcb_view_list_free_fields(pcb_view_list_t *lst) +{ + for(;;) { + pcb_view_t *item = pcb_view_list_first(lst); + if (item == NULL) + break; + pcb_view_free(item); + } +} + +void pcb_view_list_free(pcb_view_list_t *lst) +{ + pcb_view_list_free_fields(lst); + free(lst); +} + +pcb_view_t *pcb_view_by_uid(const pcb_view_list_t *lst, unsigned long int uid) +{ + pcb_view_t *v; + + for(v = pcb_view_list_first((pcb_view_list_t *)lst); v != NULL; v = pcb_view_list_next(v)) + if (v->uid == uid) + return v; + + return NULL; +} + +pcb_view_t *pcb_view_by_uid_cnt(const pcb_view_list_t *lst, unsigned long int uid, long *cnt) +{ + pcb_view_t *v; + long c = 0; + + for(v = pcb_view_list_first((pcb_view_list_t *)lst); v != NULL; v = pcb_view_list_next(v), c++) { + if (v->uid == uid) { + *cnt = c; + return v; + } + } + + *cnt = -1; + return NULL; +} + +void pcb_view_goto(pcb_view_t *item) +{ + if (item->have_bbox) { + fgw_arg_t res, argv[5]; + + argv[1].type = FGW_COORD; fgw_coord(&argv[1]) = item->bbox.X1; + argv[2].type = FGW_COORD; fgw_coord(&argv[2]) = item->bbox.Y1; + argv[3].type = FGW_COORD; fgw_coord(&argv[3]) = item->bbox.X2; + argv[4].type = FGW_COORD; fgw_coord(&argv[4]) = item->bbox.Y2; + rnd_actionv_bin(item->hidlib, "zoom", &res, 5, argv); + } +} + +pcb_view_t *pcb_view_new(rnd_hidlib_t *hl, const char *type, const char *title, const char *description) +{ + pcb_view_t *v = calloc(sizeof(pcb_view_t), 1); + + pcb_view_next_uid++; + v->uid = pcb_view_next_uid; + + if (type == NULL) type = ""; + if (title == NULL) title = ""; + if (description == NULL) description = ""; + + v->type = rnd_strdup(type); + v->title = rnd_strdup(title); + v->description = rnd_strdup(description); + v->hidlib = hl; + + return v; +} + +void pcb_view_append_obj(pcb_view_t *view, int grp, pcb_any_obj_t *obj) +{ + pcb_idpath_t *idp; + + assert((grp == 0) || (grp == 1)); + + switch(obj->type) { + case PCB_OBJ_TEXT: + case PCB_OBJ_SUBC: + case PCB_OBJ_LINE: + case PCB_OBJ_ARC: + case PCB_OBJ_POLY: + case PCB_OBJ_PSTK: + case PCB_OBJ_RAT: + case PCB_OBJ_GFX: + idp = pcb_obj2idpath(obj); + if (idp == NULL) + rnd_message(RND_MSG_ERROR, "Internal error in pcb_drc_append_obj: can not resolve object id path\n"); + else + pcb_idpath_list_append(&view->objs[grp], idp); + break; + default: + rnd_message(RND_MSG_ERROR, "Internal error in pcb_drc_append_obj: unknown object type %i\n", obj->type); + } +} + +void pcb_view_set_bbox_by_objs(pcb_data_t *data, pcb_view_t *v) +{ + int g; + rnd_box_t b; + pcb_any_obj_t *obj; + pcb_idpath_t *idp; + + /* special case: no object - leave coords unloaded/invalid */ + if ((pcb_idpath_list_length(&v->objs[0]) < 1) && (pcb_idpath_list_length(&v->objs[1]) < 1)) + return; + + /* special case: single objet in group A, use the center */ + if (!conf_core.editor.drc_inclusive_bbox && (pcb_idpath_list_length(&v->objs[0]) == 1)) { + idp = pcb_idpath_list_first(&v->objs[0]); + obj = pcb_idpath2obj_in(data, idp); + if (obj != NULL) { + v->have_bbox = 1; + pcb_obj_center(obj, &v->x, &v->y); + memcpy(&v->bbox, &obj->BoundingBox, sizeof(obj->BoundingBox)); + rnd_box_enlarge(&v->bbox, 0.25, 0.25); + return; + } + } + + b.X1 = b.Y1 = RND_MAX_COORD; + b.X2 = b.Y2 = -RND_MAX_COORD; + for(g = 0; g < 2; g++) { + for(idp = pcb_idpath_list_first(&v->objs[g]); idp != NULL; idp = pcb_idpath_list_next(idp)) { + obj = pcb_idpath2obj_in(data, idp); + if (obj != NULL) { + v->have_bbox = 1; + rnd_box_bump_box(&b, &obj->BoundingBox); + } + } + } + + if (v->have_bbox) { + v->x = (b.X1 + b.X2)/2; + v->y = (b.Y1 + b.Y2)/2; + memcpy(&v->bbox, &b, sizeof(b)); + rnd_box_enlarge(&v->bbox, 0.25, 0.25); + } +} + +static void view_append_str(gds_t *dst, const char *prefix, const char *key, const char *value) +{ + const char *s; + rnd_append_printf(dst, "%s %s = {", prefix, key); + for(s = value; *s != '\0'; s++) { + switch(*s) { + case '\\': + case '}': + gds_append(dst, '\\'); + break; + } + gds_append(dst, *s); + } + gds_append_str(dst, "}\n"); +} + +void pcb_view_save_list_begin(gds_t *dst, const char *prefix) +{ + if (prefix != NULL) + gds_append_str(dst, prefix); + gds_append_str(dst, "li:view-list-v1 {\n"); +} + +void pcb_view_save_list_end(gds_t *dst, const char *prefix) +{ + if (prefix != NULL) + gds_append_str(dst, prefix); + gds_append_str(dst, "}\n"); +} + +void pcb_view_save(pcb_view_t *v, gds_t *dst, const char *prefix) +{ + int g, n; + + if (prefix == NULL) + prefix = ""; + + rnd_append_printf(dst, "%sha:view.%lu {\n", prefix, v->uid); + view_append_str(dst, prefix, "type", v->type); + view_append_str(dst, prefix, "title", v->title); + view_append_str(dst, prefix, "description", v->description); + if (v->have_bbox) + rnd_append_printf(dst, "%s li:bbox = {%.08$$mm; %.08$$mm; %.08$$mm; %.08$$mm;}\n", prefix, v->bbox.X1, v->bbox.Y1, v->bbox.X2, v->bbox.Y2); + if (v->have_xy) + rnd_append_printf(dst, "%s li:xy = {%.08$$mm; %.08$$mm;}\n", prefix, v->x, v->y); + + for(g = 0; g < 2; g++) { + if (pcb_idpath_list_length(&v->objs[g]) > 0) { + pcb_idpath_t *i; + rnd_append_printf(dst, "%s li:objs.%d {\n", prefix, g); + for(i = pcb_idpath_list_first(&v->objs[g]); i != NULL; i = pcb_idpath_list_next(i)) { + rnd_append_printf(dst, "%s li:id {", prefix); + for(n = 0; n < i->len; n++) + rnd_append_printf(dst, "%ld;", i->id[n]); + rnd_append_printf(dst, "}\n", prefix); + } + rnd_append_printf(dst, "%s }\n", prefix); + } + } + + switch(v->data_type) { + case PCB_VIEW_PLAIN: + rnd_append_printf(dst, "%s data_type = plain\n", prefix); + break; + case PCB_VIEW_DRC: + rnd_append_printf(dst, "%s data_type = drc\n", prefix); + rnd_append_printf(dst, "%s ha:data {\n", prefix); + rnd_append_printf(dst, "%s required_value = %mw\n", prefix, v->data.drc.required_value); + if (v->data.drc.have_measured) + rnd_append_printf(dst, "%s measured_value = %mw\n", prefix, v->data.drc.measured_value); + rnd_append_printf(dst, "%s }\n", prefix); + break; + } + + rnd_append_printf(dst, "%s}\n", prefix); +} + +typedef struct { + lht_doc_t *doc; + lht_node_t *next; +} load_ctx_t; + +void pcb_view_load_end(void *load_ctx) +{ + load_ctx_t *ctx = load_ctx; + lht_dom_uninit(ctx->doc); + free(ctx); +} + +static void *view_load_post(load_ctx_t *ctx) +{ + if (ctx->doc->root == NULL) + goto error; + + if (ctx->doc->root->type == LHT_LIST) { + if (strcmp(ctx->doc->root->name, "view-list-v1") != 0) + goto error; + ctx->next = ctx->doc->root->data.list.first; + return ctx; + } + + if (ctx->doc->root->type == LHT_HASH) { + if (strncmp(ctx->doc->root->name, "view.", 5) != 0) + goto error; + ctx->next = ctx->doc->root; + return ctx; + } + + error:; + pcb_view_load_end(ctx); + return NULL; +} + +void *pcb_view_load_start_str(const char *src) +{ + load_ctx_t *ctx = malloc(sizeof(load_ctx_t)); + + ctx->doc = lht_dom_init(); + + for(; *src != '\0'; src++) { + lht_err_t err = lht_dom_parser_char(ctx->doc, *src); + if ((err != LHTE_SUCCESS) && (err != LHTE_STOP)) { + pcb_view_load_end(ctx); + return NULL; + } + } + return view_load_post(ctx); +} + +void *pcb_view_load_start_file(FILE *f) +{ + int c; + load_ctx_t *ctx = malloc(sizeof(load_ctx_t)); + + ctx->doc = lht_dom_init(); + + while((c = fgetc(f)) != EOF) { + lht_err_t err = lht_dom_parser_char(ctx->doc, c); + if ((err != LHTE_SUCCESS) && (err != LHTE_STOP)) { + pcb_view_load_end(ctx); + return NULL; + } + } + return view_load_post(ctx); +} + +#define LOADERR "Error loading view: " + +static void pcb_view_load_objs(pcb_view_t *dst, int grp, lht_node_t *olist) +{ + lht_node_t *n, *m; + for(n = olist->data.list.first; n != NULL; n = n->next) { + if ((n->type == LHT_LIST) && (strcmp(n->name, "id") == 0)) { + pcb_idpath_t *i; + int len, cnt; + + for(m = n->data.list.first, len = 0; m != NULL; m = m->next) { + if (m->type != LHT_TEXT) { + rnd_message(RND_MSG_ERROR, LOADERR "Invalid object id (non-text)\n"); + goto nope; + } + len++; + } + + i = pcb_idpath_alloc(len); + for(m = n->data.list.first, cnt = 0; m != NULL; m = m->next, cnt++) + i->id[cnt] = strtol(m->data.text.value, NULL, 10); + + pcb_idpath_list_append(&dst->objs[grp], i); + } + else + rnd_message(RND_MSG_ERROR, LOADERR "Invalid object id-path\n"); + nope:; + } +} + +static fgw_arg_t load_drc_val(const char *val) +{ + const rnd_unit_t *u; + double d; + fgw_arg_t a; + char *end; + + if (rnd_get_value_unit(val, NULL, 1, &d, &u)) { + a.type = FGW_COORD; + fgw_coord(&a) = d; + return a; + } + + if (strchr(val, '.')) { + d = strtod(val, &end); + if (*end == '\0') { + a.type = FGW_DOUBLE; + a.val.nat_double = d; + return a; + } + } + else { + long l = strtol(val, &end, 10); + if (*end == '\0') { + a.type = FGW_LONG; + a.val.nat_long = l; + return a; + } + } + + a.type = FGW_VOID; + return a; +} + +pcb_view_t *pcb_view_load_next(void *load_ctx, pcb_view_t *dst) +{ + load_ctx_t *ctx = load_ctx; + lht_node_t *n, *c; + unsigned long int uid; + char *end; + pcb_view_type_t data_type; + rnd_bool succ; + + if (ctx->next == NULL) + return NULL; + + if ((ctx->next->type != LHT_HASH) || (strncmp(ctx->next->name, "view.", 5) != 0)) + return NULL; + + uid = strtoul(ctx->next->name + 5, &end, 10); + if (*end != '\0') + return NULL; + + data_type = PCB_VIEW_PLAIN; + n = lht_dom_hash_get(ctx->next, "data_type"); + if ((n != NULL) && (n->type == LHT_TEXT)) { + if (strcmp(n->data.text.value, "drc") == 0) + data_type = PCB_VIEW_DRC; + else if (strcmp(n->data.text.value, "plain") == 0) + data_type = PCB_VIEW_PLAIN; + else { + rnd_message(RND_MSG_ERROR, LOADERR "Invalid data type: '%s'\n", n->data.text.value); + return NULL; + } + } + + if (dst == NULL) + dst = calloc(sizeof(pcb_view_t), 1); + + dst->uid = uid; + dst->data_type= data_type; + + n = lht_dom_hash_get(ctx->next, "type"); + if ((n != NULL) && (n->type == LHT_TEXT)) { + dst->type = n->data.text.value; + n->data.text.value = NULL; + } + + n = lht_dom_hash_get(ctx->next, "title"); + if ((n != NULL) && (n->type == LHT_TEXT)) { + dst->title = n->data.text.value; + n->data.text.value = NULL; + } + + n = lht_dom_hash_get(ctx->next, "description"); + if ((n != NULL) && (n->type == LHT_TEXT)) { + dst->description = n->data.text.value; + n->data.text.value = NULL; + } + + n = lht_dom_hash_get(ctx->next, "bbox"); + if ((n != NULL) && (n->type == LHT_LIST)) { + int ok = 0; + + c = n->data.list.first; + if ((c != NULL) && (c->type == LHT_TEXT)) { + dst->bbox.X1 = rnd_get_value(c->data.text.value, NULL, NULL, &succ); + if (succ) ok++; + c = c->next; + } + if ((c != NULL) && (c->type == LHT_TEXT)) { + dst->bbox.Y1 = rnd_get_value(c->data.text.value, NULL, NULL, &succ); + if (succ) ok++; + c = c->next; + } + if ((c != NULL) && (c->type == LHT_TEXT)) { + dst->bbox.X2 = rnd_get_value(c->data.text.value, NULL, NULL, &succ); + if (succ) ok++; + c = c->next; + } + if ((c != NULL) && (c->type == LHT_TEXT)) { + dst->bbox.Y2 = rnd_get_value(c->data.text.value, NULL, NULL, &succ); + if (succ) ok++; + c = c->next; + } + if ((c == NULL) && (ok == 4)) + dst->have_bbox = 1; + else + rnd_message(RND_MSG_ERROR, LOADERR "Invalid bbox values\n"); + } + + n = lht_dom_hash_get(ctx->next, "xy"); + if ((n != NULL) && (n->type == LHT_LIST)) { + int ok = 0; + + c = n->data.list.first; + if ((c != NULL) && (c->type == LHT_TEXT)) { + dst->x = rnd_get_value(c->data.text.value, NULL, NULL, &succ); + if (succ) ok++; + c = c->next; + } + if ((c != NULL) && (c->type == LHT_TEXT)) { + dst->y = rnd_get_value(c->data.text.value, NULL, NULL, &succ); + if (succ) ok++; + c = c->next; + } + if ((c == NULL) && (ok == 2)) + dst->have_bbox = 1; + else + rnd_message(RND_MSG_ERROR, LOADERR "Invalid xy values\n"); + } + + n = lht_dom_hash_get(ctx->next, "objs.0"); + if ((n != NULL) && (n->type == LHT_LIST)) + pcb_view_load_objs(dst, 0, n); + + n = lht_dom_hash_get(ctx->next, "objs.1"); + if ((n != NULL) && (n->type == LHT_LIST)) + pcb_view_load_objs(dst, 1, n); + + switch(dst->data_type) { + case PCB_VIEW_PLAIN: break; + case PCB_VIEW_DRC: + n = lht_dom_hash_get(ctx->next, "data"); + if ((n != NULL) && (n->type == LHT_HASH)) { + c = lht_dom_hash_get(n, "required_value"); + if ((c != NULL) && (c->type == LHT_TEXT)) { + dst->data.drc.required_value = load_drc_val(c->data.text.value); + + if (!succ) + rnd_message(RND_MSG_ERROR, LOADERR "invalid drc required value: '%s'\n", c->data.text.value); + } + c = lht_dom_hash_get(n, "measured_value"); + if ((c != NULL) && (c->type == LHT_TEXT)) { + dst->data.drc.measured_value = load_drc_val(c->data.text.value); + if (succ) + dst->data.drc.have_measured = 1; + else + rnd_message(RND_MSG_ERROR, LOADERR "invalid drc measured value: '%s'\n", c->data.text.value); + } + } + break; + } + + ctx->next = ctx->next->next; + return dst; +} + + +void pcb_view_append_text(pcb_view_t *view, const char *txt) +{ + if (view->long_desc.used == 0) { + gds_append_str(&view->long_desc, view->description); + gds_append_str(&view->long_desc, " Details: "); + free(view->description); + } + gds_append_str(&view->long_desc, txt); + view->description = view->long_desc.array; +} Index: tags/2.3.0/src/view.h =================================================================== --- tags/2.3.0/src/view.h (nonexistent) +++ tags/2.3.0/src/view.h (revision 33253) @@ -0,0 +1,155 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#ifndef PCB_VIEW_H +#define PCB_VIEW_H + +#include +#include +#include +#include +#include "global_typedefs.h" +#include +#include "idpath.h" +#include + +/* A saved view on the board (e.g. a drc violation); metadata includes two lists + of objects to highlight on preview and some optional, application-specific + data (e.g. drc size values) */ + +typedef enum pcb_view_type_e { + PCB_VIEW_PLAIN, /* has no data */ + PCB_VIEW_DRC +} pcb_view_type_t; + +struct pcb_view_s { + unsigned long int uid; /* ID unique for each view (for GUI identification) - 0 means invalid */ + + rnd_hidlib_t *hidlib; + + char *type; + char *title; + char *description; + + /* these indicate whether some of the following fields are valid */ + unsigned have_bbox:1; + unsigned have_xy:1; + + rnd_box_t bbox; /* bounding box of all error objects (in both groups) */ + + rnd_coord_t x, y; /* optional: a coord to mark on the preview */ + pcb_idpath_list_t objs[2]; /* optional: two groups of objects to highlight on preview */ + + gds_t long_desc; /* optional: if non-empty, description shall point to long_desc.array */ + + pcb_view_type_t data_type; + union { + struct { + unsigned have_measured:1; + fgw_arg_t measured_value; /* should be long, double or coord */ + fgw_arg_t required_value; /* should be long, double or coord */ + } drc; + } data; + + gdl_elem_t link; /* always part of a list */ +}; + +/* List of drc violations */ +#define TDL(x) pcb_view_list_ ## x +#define TDL_LIST_T pcb_view_list_t +#define TDL_ITEM_T pcb_view_t +#define TDL_FIELD link +#define TDL_SIZE_T size_t +#define TDL_FUNC + +#define pcb_view_list_foreach(list, iterator, loop_elem) \ + gdl_foreach_((&((list)->lst)), (iterator), (loop_elem)) + +#include +#include + +/* Free all fields and the view pointer too */ +void pcb_view_free(pcb_view_t *item); + +/* Free all items and empty the list but do not free the list pointer */ +void pcb_view_list_free_fields(pcb_view_list_t *lst); + +void pcb_view_list_free(pcb_view_list_t *lst); + + +/* Slow, linear search for an UID in a list; returns NULL if not found; + optionally count the number of preceeding items and sotre it in cnt. */ +pcb_view_t *pcb_view_by_uid(const pcb_view_list_t *lst, unsigned long int uid); +pcb_view_t *pcb_view_by_uid_cnt(const pcb_view_list_t *lst, unsigned long int uid, long *cnt); + +/* Zoom the drawing area to the drc error */ +void pcb_view_goto(pcb_view_t *item); + +/* Allocate a new, floating (unlinked) view with no data or bbox */ +pcb_view_t *pcb_view_new(rnd_hidlib_t *hl, const char *type, const char *title, const char *description); + +/* Append obj to one of the object groups in view (resolving to idpath) */ +void pcb_view_append_obj(pcb_view_t *view, int grp, pcb_any_obj_t *obj); + +/* Calculate and set v->bbox from v->objs[] bboxes */ +void pcb_view_set_bbox_by_objs(pcb_data_t *data, pcb_view_t *v); + + +/*** Save a serialized view (or list of views) ***/ + +/* In case of saving a list or saving into a file, call begin/end before/after + saving the view item */ +void pcb_view_save_list_begin(gds_t *dst, const char *prefix); +void pcb_view_save_list_end(gds_t *dst, const char *prefix); + +/* Serialize/save a view into dst as a lihata string, each line optionally + prefixed (prefix can be NULL) */ +void pcb_view_save(pcb_view_t *v, gds_t *dst, const char *prefix); + + +/*** Load a serialized view (or list of views) ***/ + +/* Parse a serialized string/file into memory; returns a load_ctx or NULL on + error. Does not close the file. */ +void *pcb_view_load_start_str(const char *src); +void *pcb_view_load_start_file(FILE *f); + +/* Load the next item from load_ctx; returns NULL on error if there are no + more items. If dst is not NULL, it's returned on success; else a newly + allocated pcb_view_t is returned on success. */ +pcb_view_t *pcb_view_load_next(void *load_ctx, pcb_view_t *dst); + +/* call after the last item or to cancel the load */ +void pcb_view_load_end(void *load_ctx); + +/*** utility ***/ + +/* append txt to description */ +void pcb_view_append_text(pcb_view_t *view, const char *txt); + + +#endif Index: tags/2.3.0/src/vtlibrary.c =================================================================== --- tags/2.3.0/src/vtlibrary.c (nonexistent) +++ tags/2.3.0/src/vtlibrary.c (revision 33253) @@ -0,0 +1,3 @@ +#define GVT_DONT_UNDEF +#include "vtlibrary.h" +#include Index: tags/2.3.0/src/vtlibrary.h =================================================================== --- tags/2.3.0/src/vtlibrary.h (nonexistent) +++ tags/2.3.0/src/vtlibrary.h (revision 33253) @@ -0,0 +1,82 @@ +#ifndef PCB_VTLIBRARY_H +#define PCB_VTLIBRARY_H +#include +#include + +typedef enum { + PCB_LIB_INVALID, + PCB_LIB_DIR, + PCB_LIB_FOOTPRINT +} pcb_fplibrary_type_t; + +typedef enum { + PCB_FP_INVALID, + PCB_FP_DIR, /* used temporarily during the mapping - a finalized tree wouldn't have this */ + PCB_FP_FILEDIR, /* used temporarily during the mapping - a finalized tree wouldn't have this */ + PCB_FP_FILE, + PCB_FP_PARAMETRIC +} pcb_fptype_t; + + +typedef struct pcb_fplibrary_s pcb_fplibrary_t; + +/* Elem=library_t; init=none */ + +/* all public symbols are wrapped in GVT() - see vt_t(7) */ +#define GVT(x) vtlib_ ## x + +/* Array elem type - see vt_t(7) */ +#define GVT_ELEM_TYPE pcb_fplibrary_t + +/* Type that represents array lengths - see vt_t(7) */ +#define GVT_SIZE_TYPE size_t + +/* Below this length, always double allocation size when the array grows */ +#define GVT_DOUBLING_THRS 64 + +/* Initial array size when the first element is written */ +#define GVT_START_SIZE 8 + +/* Optional prefix for function definitions (e.g. static inline) */ +#define GVT_FUNC + +/* Enable this to set all new bytes ever allocated to this value - see + vt_set_new_bytes_to(7) */ +#define GVT_SET_NEW_BYTES_TO 0 + + +/* Include the actual header implementation */ +#include + +/* Memory allocator - see vt_allocation(7) */ +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) + +/* clean up #defines */ +#include + +/* An element of a library: either a directory or a footprint */ +struct pcb_fplibrary_s { + char *name; /* visible name */ + pcb_fplibrary_type_t type; + pcb_fplibrary_t *parent; + + union { + struct { /* type == LIB_DIR */ + vtlib_t children; + void *backend; /* pcb_plug_fp_t* */ + } dir; + struct { /* type == LIB_FOOTPRINT */ + char *loc_info; + void *backend_data; + pcb_fptype_t type; + + /* an array of void * tag IDs; last tag ID is NULL; the array is + locally allocated but values are stored in a central hash and + must be allocated by pcb_fp_tag() and never free'd manually */ + void **tags; + } fp; + } data; +} ; + +#endif Index: tags/2.3.0/src/vtpadstack.c =================================================================== --- tags/2.3.0/src/vtpadstack.c (nonexistent) +++ tags/2.3.0/src/vtpadstack.c (revision 33253) @@ -0,0 +1,6 @@ +#include "obj_pstk.h" + +#define GVT_DONT_UNDEF +#include "vtpadstack.h" +#include + Index: tags/2.3.0/src/vtpadstack.h =================================================================== --- tags/2.3.0/src/vtpadstack.h (nonexistent) +++ tags/2.3.0/src/vtpadstack.h (revision 33253) @@ -0,0 +1,41 @@ +#ifndef PCB_VTPADSTACK_H +#define PCB_VTPADSTACK_H + +/* Elem=pcb_pstk_proto_t; init=none */ + +#include "obj_pstk.h" + +/* all public symbols are wrapped in GVT() - see vt_t(7) */ +#define GVT(x) pcb_vtpadstack_proto_ ## x + +/* Array elem type - see vt_t(7) */ +#define GVT_ELEM_TYPE pcb_pstk_proto_t + +/* Type that represents array lengths - see vt_t(7) */ +#define GVT_SIZE_TYPE size_t + +/* Below this length, always double allocation size when the array grows */ +#define GVT_DOUBLING_THRS 64 + +/* Initial array size when the first element is written */ +#define GVT_START_SIZE 8 + +/* Optional prefix for function definitions (e.g. static inline) */ +#define GVT_FUNC + +/* Enable this to set all new bytes ever allocated to this value - see + vt_set_new_bytes_to(7) */ +#define GVT_SET_NEW_BYTES_TO 0 + + +/* Include the actual header implementation */ +#include + +/* Memory allocator - see vt_allocation(7) */ +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) + +/* clean up #defines */ +#include + +#endif Index: tags/2.3.0/src/vtpadstack_t.c =================================================================== --- tags/2.3.0/src/vtpadstack_t.c (nonexistent) +++ tags/2.3.0/src/vtpadstack_t.c (revision 33253) @@ -0,0 +1,6 @@ +#include +#include +#include +#define GVT_DONT_UNDEF +#include "vtpadstack_t.h" +#include Index: tags/2.3.0/src/vtpadstack_t.h =================================================================== --- tags/2.3.0/src/vtpadstack_t.h (nonexistent) +++ tags/2.3.0/src/vtpadstack_t.h (revision 33253) @@ -0,0 +1,41 @@ +#ifndef PCB_VTPADSTACK_T_H +#define PCB_VTPADSTACK_T_H + +/* Elem=pcb_pstk_proto_t; init=none */ + +#include "obj_pstk_shape.h" + +/* all public symbols are wrapped in GVT() - see vt_t(7) */ +#define GVT(x) pcb_vtpadstack_tshape_ ## x + +/* Array elem type - see vt_t(7) */ +#define GVT_ELEM_TYPE pcb_pstk_tshape_t + +/* Type that represents array lengths - see vt_t(7) */ +#define GVT_SIZE_TYPE size_t + +/* Below this length, always double allocation size when the array grows */ +#define GVT_DOUBLING_THRS 32 + +/* Initial array size when the first element is written */ +#define GVT_START_SIZE 6 + +/* Optional prefix for function definitions (e.g. static inline) */ +#define GVT_FUNC + +/* Enable this to set all new bytes ever allocated to this value - see + vt_set_new_bytes_to(7) */ +#define GVT_SET_NEW_BYTES_TO 0 + + +/* Include the actual header implementation */ +#include + +/* Memory allocator - see vt_allocation(7) */ +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) + +/* clean up #defines */ +#include + +#endif Index: tags/2.3.0/src/vtr0.c =================================================================== --- tags/2.3.0/src/vtr0.c (nonexistent) +++ tags/2.3.0/src/vtr0.c (revision 33253) @@ -0,0 +1,3 @@ +#define GVT_DONT_UNDEF +#include "vtr0.h" +#include Index: tags/2.3.0/src/vtr0.h =================================================================== --- tags/2.3.0/src/vtr0.h (nonexistent) +++ tags/2.3.0/src/vtr0.h (revision 33253) @@ -0,0 +1,31 @@ +#ifndef VTR0_H +#define VTR0_H + +#include "config.h" +#include +#include + +typedef struct pcb_range_s { + rnd_coord_t begin, end; + union { + long l; + rnd_coord_t c; + double d; + void *ptr; + } data[4]; +} pcb_range_t; + +#define GVT(x) vtr0_ ## x +#define GVT_ELEM_TYPE pcb_range_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 + +#endif Index: tags/2.3.0/src/vtroutestyle.c =================================================================== --- tags/2.3.0/src/vtroutestyle.c (nonexistent) +++ tags/2.3.0/src/vtroutestyle.c (revision 33253) @@ -0,0 +1,3 @@ +#define GVT_DONT_UNDEF +#include "vtroutestyle.h" +#include Index: tags/2.3.0/src/vtroutestyle.h =================================================================== --- tags/2.3.0/src/vtroutestyle.h (nonexistent) +++ tags/2.3.0/src/vtroutestyle.h (revision 33253) @@ -0,0 +1,85 @@ +#ifndef PCB_VTROUTESTYLE_H +#define PCB_VTROUTESTYLE_H +#include +#include +#include +#include "attrib.h" +#include + +/* Elem=RouteStyle; init=0 */ + +#define PCB_RST_NAME_LEN 32 + +typedef struct { + rnd_coord_t Thick; /* line thickness */ + rnd_coord_t textt; /* text thickness */ + int texts; /* text scale */ + rnd_coord_t Clearance; /* min. separation from other nets */ + rnd_cardinal_t via_proto; /* via padstack prototype ID */ + int via_proto_set; /* 1 if via_proto is set/valid, 0 for old file formats */ + rnd_coord_t Diameter, Hole; /* OBSOLETE: via diameter and drill hole; kept for compatibility with old file formats (lihata board v1..v4) */ + char name[PCB_RST_NAME_LEN]; /* fixed length name to save malloc/free */ + pcb_attribute_list_t attr; +} pcb_route_style_t; + +/* all public symbols are wrapped in GVT() - see vt_t(7) */ +#define GVT(x) vtroutestyle_ ## x +#define HAVE_VTROUTESTYLE_T + +/* Array elem type - see vt_t(7) */ +#define GVT_ELEM_TYPE pcb_route_style_t + +/* Type that represents array lengths - see vt_t(7) */ +#define GVT_SIZE_TYPE size_t + +/* Below this length, always double allocation size when the array grows */ +#define GVT_DOUBLING_THRS 16 + +/* Initial array size when the first element is written */ +#define GVT_START_SIZE 4 + +/* Optional terminator; when present, it is always appended at the end - see + vt_term(7)*/ +/* #define GVT_TERM '\0' */ + +/* Optional prefix for function definitions (e.g. static inline) */ +#define GVT_FUNC + +/* Enable this to set all new bytes ever allocated to this value - see + vt_set_new_bytes_to(7) */ +#define GVT_SET_NEW_BYTES_TO 0 + +/* Enable GVT_INIT_ELEM_FUNC and an user configured function is called + for each new element allocated (even between used and alloced). + See vt_init_elem(7) */ +/*#define GVT_INIT_ELEM_FUNC*/ + +/* Enable GVT_ELEM_CONSTRUCTOR and an user configured function is called + for each element that is getting within the range of ->used. + See vt_construction(7) */ +/*#define GVT_ELEM_CONSTRUCTOR */ + +/* Enable GVT_ELEM_DESTRUCTOR and an user configured function is called + for each element that was once constructed and now getting beyond ->used. + See vt_construction(7) */ +/*#define GVT_ELEM_DESTRUCTOR */ + +/* Enable GVT_ELEM_COPY and an user configured function is called + for copying elements into the array. + See vt_construction(7) */ +/*#define GVT_ELEM_COPY */ + +/* Optional extra fields in the vector struct - see vt_user_fields(7) */ +/* #define GVT_USER_FIELDS int foo; char bar[12]; */ + +/* Include the actual header implementation */ +#include + +/* Memory allocator - see vt_allocation(7) */ +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) + +/* clean up #defines */ +#include + +#endif Index: tags/2.3.0/src_3rd/Makefile.conf =================================================================== --- tags/2.3.0/src_3rd/Makefile.conf (nonexistent) +++ tags/2.3.0/src_3rd/Makefile.conf (revision 33253) @@ -0,0 +1 @@ +# placeholder for genvector Index: tags/2.3.0/src_3rd/README =================================================================== --- tags/2.3.0/src_3rd/README (nonexistent) +++ tags/2.3.0/src_3rd/README (revision 33253) @@ -0,0 +1 @@ +3rd party software libs Index: tags/2.3.0/src_3rd/libcdtr/Makefile =================================================================== --- tags/2.3.0/src_3rd/libcdtr/Makefile (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/Makefile (revision 33253) @@ -0,0 +1,36 @@ +#CFLAGS_DBG=-Wall -O0 -g3 +CFLAGS=$(CFLAGS_DBG) $(CFLAGS_LIBCDTR) -I. -I.. -I../.. +LDFLAGS=-lm $(LDFLAGS_LIBCDTR) + +OBJS= cdt.o point.o edge.o triangle.o +LIBA=libcdtr.a + +cdt_test: cdt_test.o $(OBJS) + +include Makefile.dep + +$(LIBA): $(OBJS) + -rm $(LIBA) + ar ru $(LIBA) $(OBJS) + +cdt_test.o: cdt_test.c + $(CC) $(CFLAGS) -c cdt_test.c -o $@ + +cdt.o: cdt.c + $(CC) $(CFLAGS) -c cdt.c -o $@ + +point.o: point.c + $(CC) $(CFLAGS) -c point.c -o $@ + +edge.o: edge.c + $(CC) $(CFLAGS) -c edge.c -o $@ + +triangle.o: triangle.c + $(CC) $(CFLAGS) -c triangle.c -o $@ + +dep: + echo $(OBJS) | ./dep.sh $(CFLAGS) > Makefile.dep + +clean: + -touch $(LIBA) $(OBJS) cdt_test.o cdt_test + -rm $(LIBA) $(OBJS) cdt_test.o cdt_test Index: tags/2.3.0/src_3rd/libcdtr/Makefile.dep =================================================================== --- tags/2.3.0/src_3rd/libcdtr/Makefile.dep (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/Makefile.dep (revision 33253) @@ -0,0 +1,15 @@ +cdt_test.o: cdt_test.c cdt.h typedefs.h point.h ../libcdtr/list/list.h \ + ../genvector/genvector_impl.h ../genvector/genvector_undef.h edge.h \ + triangle.h +cdt.o: cdt.c cdt.h typedefs.h point.h ../libcdtr/list/list.h \ + ../genvector/genvector_impl.h ../genvector/genvector_undef.h edge.h \ + triangle.h +point.o: point.c point.h typedefs.h ../libcdtr/list/list.h \ + ../genvector/genvector_impl.h ../genvector/genvector_undef.h \ + ../libcdtr/list/list.c ../genvector/genvector_impl.c +edge.o: edge.c edge.h typedefs.h ../libcdtr/list/list.h \ + ../genvector/genvector_impl.h ../genvector/genvector_undef.h \ + ../libcdtr/list/list.c ../genvector/genvector_impl.c +triangle.o: triangle.c triangle.h typedefs.h ../libcdtr/list/list.h \ + ../genvector/genvector_impl.h ../genvector/genvector_undef.h \ + ../libcdtr/list/list.c ../genvector/genvector_impl.c Index: tags/2.3.0/src_3rd/libcdtr/cdt.c =================================================================== --- tags/2.3.0/src_3rd/libcdtr/cdt.c (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/cdt.c (revision 33253) @@ -0,0 +1,865 @@ +/* + libcdtr - Constrained Delaunay Triangulation using incremental algorithm + + Copyright (C) 2018 Wojciech Krutnik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Constrained Delaunay Triangulation using incremental algorithm, as described in: + Yizhi Lu and Wayne Wei-Ming Dai, "A numerical stable algorithm for constructing + constrained Delaunay triangulation and application to multichip module layout," + China., 1991 International Conference on Circuits and Systems, Shenzhen, 1991, + pp. 644-647 vol.2. + */ + +#include +#include +#include + +#include "cdt.h" + +#define DEBUG + +#define LEFTPOINT(p1, p2) ((p1)->pos.x < (p2)->pos.x || ((p1)->pos.x == (p2)->pos.x && (p1)->pos.y > (p2)->pos.y)) + + +static point_t *new_point(cdt_t *cdt, pos_t pos) +{ + point_t *p = *vtpoint_alloc_append(&cdt->points, 1); + p->pos = pos; + return p; +} + +static edge_t *new_edge(cdt_t *cdt, point_t *p1, point_t *p2, int constrain) +{ + edge_t *e; + assert(p1->pos.x != p2->pos.x || p1->pos.y != p2->pos.y); + e = *vtedge_alloc_append(&cdt->edges, 1); + /* always orient the edge to the right (or down when x1==x2; requires epsilon check?) */ + if (LEFTPOINT(p1, p2)) { + e->endp[0] = p1; + e->endp[1] = p2; + } + else { + e->endp[0] = p2; + e->endp[1] = p1; + } + e->is_constrained = constrain; + p1->adj_edges = edgelist_prepend(p1->adj_edges, &e); + p2->adj_edges = edgelist_prepend(p2->adj_edges, &e); + return e; +} + +edge_t *get_edge_from_points(point_t *p1, point_t *p2) +{ + EDGELIST_FOREACH(e1, p1->adj_edges) + EDGELIST_FOREACH(e2, p2->adj_edges) + if (e1 == e2) + return e1; + POINTLIST_FOREACH_END(); + EDGELIST_FOREACH_END(); + return NULL; +} + +static void order_triangle_points_ccw(point_t **p1, point_t **p2, point_t **p3) +{ + pointlist_node_t *points = NULL; + points = pointlist_prepend(points, p1); + points = pointlist_prepend(points, p2); + points = pointlist_prepend(points, p3); + + /* first point */ + *p1 = LEFTPOINT(*p1, *p2) ? *p1 : *p2; + *p1 = LEFTPOINT(*p1, *p3) ? *p1 : *p3; + points = pointlist_remove_item(points, p1); + + /* two other points */ + if (ORIENT_CCW(*p1, points->item, points->next->item)) { + *p2 = points->item; + *p3 = points->next->item; + } else { + *p2 = points->next->item; + *p3 = points->item; + } + points = pointlist_remove_front(points); + points = pointlist_remove_front(points); +} + +static triangle_t *new_triangle(cdt_t *cdt, point_t *p1, point_t *p2, point_t *p3) +{ + edge_t *e1, *e2, *e3; + triangle_t *t = *vttriangle_alloc_append(&cdt->triangles, 1); + + assert(!ORIENT_COLLINEAR(p1, p2, p3)); /* points cannot be colinear */ + + order_triangle_points_ccw(&p1, &p2, &p3); + t->p[0] = p1; + t->p[1] = p2; + t->p[2] = p3; + p1->adj_triangles = trianglelist_prepend(p1->adj_triangles, &t); + p2->adj_triangles = trianglelist_prepend(p2->adj_triangles, &t); + p3->adj_triangles = trianglelist_prepend(p3->adj_triangles, &t); + + e1 = get_edge_from_points(p1, p2); + e2 = get_edge_from_points(p2, p3); + e3 = get_edge_from_points(p3, p1); + assert(e1 != NULL && e2 != NULL && e3 != NULL); + t->e[0] = e1; + t->e[1] = e2; + t->e[2] = e3; + +#define connect_adjacent_triangle(_t_, _edge_num_, _e_) \ + if ((_e_)->adj_t[0] == NULL && (_e_)->adj_t[1] == NULL) \ + (_e_)->adj_t[0] = (_t_); \ + else { \ + int i = (_e_)->adj_t[0] == NULL ? 0 : 1; \ + (_e_)->adj_t[i] = (_t_); \ + (_t_)->adj_t[(_edge_num_)] = (_e_)->adj_t[i^1]; \ + if ((_t_)->adj_t[(_edge_num_)] != NULL) { \ + for (i = 0; i < 3; i++) { \ + if ((_t_)->adj_t[(_edge_num_)]->e[i] == (_e_)) \ + (_t_)->adj_t[(_edge_num_)]->adj_t[i] = (_t_); \ + } \ + } \ + } + + connect_adjacent_triangle(t, 0, e1); + connect_adjacent_triangle(t, 1, e2); + connect_adjacent_triangle(t, 2, e3); +#undef connect_adjacent_triangle + + return t; +} + +static void remove_triangle(cdt_t *cdt, triangle_t *t) +{ + int i, j; + + for (i = 0; i < 3; i++) { + /* disconnect adjacent points */ + t->p[i]->adj_triangles = trianglelist_remove_item(t->p[i]->adj_triangles, &t); + /* disconnect adjacent edges */ + for (j = 0; j < 2; j++) + if (t->e[i]->adj_t[j] == t) + t->e[i]->adj_t[j] = NULL; + /* disconnect adjacent triangles */ + for (j = 0; j < 3; j++) { + triangle_t *adj_t = t->adj_t[i]; + if (adj_t != NULL && adj_t->adj_t[j] == t) + adj_t->adj_t[j] = NULL; + } + } + + /* remove triangle */ + for(i = 0; i < vttriangle_len(&cdt->triangles); i++) { + if (cdt->triangles.array[i] == t) { + vttriangle_remove(&cdt->triangles, i, 1); + break; + } + } +} + +static void remove_edge(cdt_t *cdt, edge_t *e) +{ + int i; + + assert(e != NULL); + + /* disconnect adjacent triangles */ + for (i = 0; i < 2; i++) + if (e->adj_t[i]) + remove_triangle(cdt, e->adj_t[i]); + /* disconnect endpoints */ + for (i = 0; i < 2; i++) + e->endp[i]->adj_edges = edgelist_remove_item(e->endp[i]->adj_edges, &e); + + /* remove edge */ + for(i = 0; i < vtedge_len(&cdt->edges); i++) { + if (cdt->edges.array[i] == e) { + vtedge_remove(&cdt->edges, i, 1); + break; + } + } +} + +static int is_point_in_circumcircle(point_t *p, triangle_t *t) +{ + double x1 = t->p[0]->pos.x, x2 = t->p[1]->pos.x, x3 = t->p[2]->pos.x; + double y1 = t->p[0]->pos.y, y2 = t->p[1]->pos.y, y3 = t->p[2]->pos.y; + double d1, d2, d3, d4; + double n1, n2, n3; + double px = p->pos.x, py = p->pos.y; + + n1 = (x1 * x1) + (y1 * y1); + n2 = (x2 * x2) + (y2 * y2); + n3 = (x3 * x3) + (y3 * y3); + + d1 = (x1 * y2) + (x2 * y3) + (x3 * y1) - (x3 * y2) - (x1 * y3) - (x2 * y1); + d2 = (n1 * y2) + (n2 * y3) + (n3 * y1) - (n3 * y2) - (n1 * y3) - (n2 * y1); + d3 = (n1 * x2) + (n2 * x3) + (n3 * x1) - (n3 * x2) - (n1 * x3) - (n2 * x1); + d4 = (n1 * x2 * y3) + (n2 * x3 * y1) + (n3 * x1 * y2) - (n3 * x2 * y1) - (n1 * x3 * y2) - (n2 * x1 * y3); + + return d1 * ( (px * (px*d1 - d2)) + (py * (py*d1 + d3)) - d4 ) < 0 ? 1 : 0; +} + +static void init_bbox(cdt_t *cdt, coord_t bbox_x1, coord_t bbox_y1, coord_t bbox_x2, coord_t bbox_y2) +{ + pos_t bbox; + point_t *p_tl, *p_tr, *p_bl, *p_br; + + bbox.x = bbox_x1; + bbox.y = bbox_y1; + cdt->bbox_tl = bbox; + p_bl = new_point(cdt, bbox); + bbox.x = bbox_x2; + bbox.y = bbox_y1; + p_br = new_point(cdt, bbox); + bbox.x = bbox_x1; + bbox.y = bbox_y2; + p_tl = new_point(cdt, bbox); + bbox.x = bbox_x2; + bbox.y = bbox_y2; + p_tr = new_point(cdt, bbox); + cdt->bbox_br = bbox; + + new_edge(cdt, p_tl, p_bl, 1); + new_edge(cdt, p_bl, p_br, 1); + new_edge(cdt, p_br, p_tr, 1); + new_edge(cdt, p_tr, p_tl, 1); + new_edge(cdt, p_bl, p_tr, 0); /* diagonal */ + + new_triangle(cdt, p_bl, p_br, p_tr); + new_triangle(cdt, p_tl, p_bl, p_tr); +} + +void cdt_init(cdt_t *cdt, coord_t bbox_x1, coord_t bbox_y1, coord_t bbox_x2, coord_t bbox_y2) +{ + cdt->points.elem_constructor = vtpoint_constructor; + cdt->points.elem_destructor = vtpoint_destructor; + cdt->points.elem_copy = NULL; + vtpoint_init(&cdt->points); + cdt->edges.elem_constructor = vtedge_constructor; + cdt->edges.elem_destructor = vtedge_destructor; + cdt->edges.elem_copy = NULL; + vtedge_init(&cdt->edges); + cdt->triangles.elem_constructor = vttriangle_constructor; + cdt->triangles.elem_destructor = vttriangle_destructor; + cdt->triangles.elem_copy = NULL; + vttriangle_init(&cdt->triangles); + + init_bbox(cdt, bbox_x1, bbox_y1, bbox_x2, bbox_y2); +} + +void cdt_free(cdt_t *cdt) +{ + vttriangle_uninit(&cdt->triangles); + vtedge_uninit(&cdt->edges); + VTPOINT_FOREACH(p, &cdt->points) + trianglelist_free(p->adj_triangles); + edgelist_free(p->adj_edges); + VTPOINT_FOREACH_END(); + vtpoint_uninit(&cdt->points); +} + +static int is_point_in_triangle(point_t *p, triangle_t *t) +{ + return ORIENT_CCW_CL(t->p[0], t->p[1], p) && ORIENT_CCW_CL(t->p[1], t->p[2], p) && ORIENT_CCW_CL(t->p[2], t->p[0], p); +} + +typedef struct { + edgelist_node_t *border_edges; + edgelist_node_t *edges_to_remove; +} retriangulation_region_t; + +static void check_adjacent_triangle(triangle_t *adj_t, edge_t *adj_e, point_t *new_p, retriangulation_region_t *region) +{ + int i; + + assert(adj_t != NULL && adj_e != NULL); + + if (is_point_in_circumcircle(new_p, adj_t)) { + region->edges_to_remove = edgelist_prepend(region->edges_to_remove, &adj_e); + region->border_edges = edgelist_remove_item(region->border_edges, &adj_e); + for (i = 0; i < 3; i++) { + if (adj_t->e[i] == adj_e) + continue; + else { + edge_t *next_adj_e = adj_t->e[i]; + triangle_t *next_adj_t = adj_t->adj_t[i]; + + region->border_edges = edgelist_prepend(region->border_edges, &next_adj_e); + if (!next_adj_e->is_constrained) + check_adjacent_triangle(next_adj_t, next_adj_e, new_p, region); /* recursive call */ + } + } + } +} + +#ifdef DEBUG +void dump_pointlist(pointlist_node_t *list) +{ + POINTLIST_FOREACH(p, list) + fprintf(stderr, "\t{pos=(%d, %d) adj_t=(", p->pos.x, p->pos.y); + TRIANGLELIST_FOREACH(t, p->adj_triangles) + fprintf(stderr, "%p", (void*)t); + if(_node_->next != NULL) + fprintf(stderr, ", "); + TRIANGLELIST_FOREACH_END(); + fprintf(stderr, ") adj_e=("); + EDGELIST_FOREACH(t, p->adj_edges) + fprintf(stderr, "%p", (void*)t); + if(_node_->next != NULL) + fprintf(stderr, ", "); + EDGELIST_FOREACH_END(); + fprintf(stderr, ")}\n"); + POINTLIST_FOREACH_END(); +} + +void dump_edgelist(edgelist_node_t *list) +{ + EDGELIST_FOREACH(e, list) + fprintf(stderr, "\t{endp1=(%p (pos=(%d, %d))) endp2=(%p (pos=(%d, %d))) adj_t=(", + (void*)e->endp[0], e->endp[0]->pos.x, e->endp[0]->pos.y, (void*)e->endp[1], e->endp[1]->pos.x, e->endp[1]->pos.y); + fprintf(stderr, "%p, %p)", (void*)e->adj_t[0], (void*)e->adj_t[1]); + fprintf(stderr, " %s}\n", e->is_constrained ? "constrained" : ""); + EDGELIST_FOREACH_END(); +} + +void dump_trianglelist(trianglelist_node_t *list) +{ + TRIANGLELIST_FOREACH(t, list) + fprintf(stderr, "\t{p1=(%d, %d) p2=(%d, %d) p3=(%d, %d)", + t->p[0]->pos.x, t->p[0]->pos.y, t->p[1]->pos.x, t->p[1]->pos.y, t->p[2]->pos.x, t->p[2]->pos.y); + fprintf(stderr, " adj_e=(%p, %p, %p)", (void*)t->e[0], (void*)t->e[1], (void*)t->e[2]); + fprintf(stderr, " adj_t=(%p, %p, %p)}\n", (void*)t->adj_t[0], (void*)t->adj_t[1], (void*)t->adj_t[2]); + TRIANGLELIST_FOREACH_END(); +} +#endif + +static pointlist_node_t *order_edges_adjacently(edgelist_node_t *edges) +{ + pointlist_node_t *plist_ordered = NULL; + edge_t *e1 = edges->item; + point_t *p = e1->endp[0]; + int i = 1; + + plist_ordered = pointlist_prepend(plist_ordered, &p); + edges = edgelist_remove_front(edges); + + while (edges != NULL) { + p = e1->endp[i]; + EDGELIST_FOREACH(e2, edges) + if (e2->endp[0] == p || e2->endp[1] == p) { + plist_ordered = pointlist_prepend(plist_ordered, &p); + edges = edgelist_remove(edges, _node_); + i = e2->endp[0] == p ? 1 : 0; + e1 = e2; + break; + } + EDGELIST_FOREACH_END(); + } + + return plist_ordered; +} + +static void triangulate_polygon(cdt_t *cdt, pointlist_node_t *polygon) +{ + pointlist_node_t *current_point_node; + point_t *p[3]; + int i; + + assert(pointlist_length(polygon) >= 3); + + current_point_node = polygon; + while (pointlist_length(polygon) > 3) { + triangle_t candidate_t; + edge_t candidate_e; + pointlist_node_t *pnode; + + candidate_t.p[0] = current_point_node->item; + candidate_e.endp[0] = candidate_t.p[0]; + if (current_point_node->next == NULL) + current_point_node = polygon; /* wrap around */ + else + current_point_node = current_point_node->next; + candidate_t.p[1] = current_point_node->item; + if (current_point_node->next == NULL) + candidate_t.p[2] = polygon->item; /* wrap around */ + else + candidate_t.p[2] = current_point_node->next->item; + candidate_e.endp[1] = candidate_t.p[2]; + + if (ORIENT_COLLINEAR(candidate_t.p[0], candidate_t.p[1], candidate_t.p[2])) + goto skip; + + /* case 1: another point of the polygon violates the circle criterion */ + POINTLIST_FOREACH(p, polygon) + if (p != candidate_t.p[0] && p != candidate_t.p[1] && p != candidate_t.p[2]) + if (is_point_in_circumcircle(p, &candidate_t)) + goto skip; + POINTLIST_FOREACH_END(); + + /* case 2: edge to be added already exists */ + EDGELIST_FOREACH(e1, candidate_e.endp[0]->adj_edges) + EDGELIST_FOREACH(e2, candidate_e.endp[1]->adj_edges) + if (e1 == e2) + goto skip; + EDGELIST_FOREACH_END(); + EDGELIST_FOREACH_END(); + + /* case 3: edge to be added intersects an existing edge */ + /* case 4: a point adjacent to the current_point is in the candidate triangle */ + EDGELIST_FOREACH(e, candidate_t.p[1]->adj_edges) + if (e != get_edge_from_points(candidate_t.p[0], candidate_t.p[1]) + && e != get_edge_from_points(candidate_t.p[1], candidate_t.p[2])) { + triangle_t ord_t; + if (LINES_INTERSECT(candidate_e.endp[0], candidate_e.endp[1], e->endp[0], e->endp[1])) + goto skip; + ord_t.p[0] = candidate_t.p[0]; + ord_t.p[1] = candidate_t.p[1]; + ord_t.p[2] = candidate_t.p[2]; + order_triangle_points_ccw(&ord_t.p[0], &ord_t.p[1], &ord_t.p[2]); + if (is_point_in_triangle(e->endp[0] != candidate_t.p[1] ? e->endp[0] : e->endp[1], &ord_t)) + goto skip; + } + EDGELIST_FOREACH_END(); + + new_edge(cdt, candidate_e.endp[0], candidate_e.endp[1], 0); + new_triangle(cdt, candidate_t.p[0], candidate_t.p[1], candidate_t.p[2]); + + /* update polygon: remove the point now covered by the new edge */ + if (current_point_node->next == NULL) + pnode = polygon; /* wrap around */ + else + pnode = current_point_node->next; + polygon = pointlist_remove(polygon, current_point_node); + current_point_node = pnode; + +skip: + continue; + } + + /* create triangle from the remaining edges */ + for (i = 0; i < 3; i++) { + p[i] = polygon->item; + polygon = pointlist_remove_front(polygon); + } + new_triangle(cdt, p[0], p[1], p[2]); +} + +static void insert_point_(cdt_t *cdt, point_t *new_p) +{ + triangle_t *enclosing_triangle = NULL; + retriangulation_region_t region = {NULL, NULL}; + pointlist_node_t *points_to_attach, *prev_point_node; + int i; + + /* find enclosing triangle */ + VTTRIANGLE_FOREACH(t, &cdt->triangles) + if (is_point_in_triangle(new_p, t)) { + enclosing_triangle = t; + break; + } + VTTRIANGLE_FOREACH_END(); + assert(enclosing_triangle != NULL); + + /* remove invalid edges and attach enclosing points */ + for (i = 0; i < 3; i++) { + edge_t *adj_e = enclosing_triangle->e[i]; + triangle_t *adj_t = enclosing_triangle->adj_t[i]; + + region.border_edges = edgelist_prepend(region.border_edges, &adj_e); + if (!adj_e->is_constrained && adj_t != NULL) + check_adjacent_triangle(adj_t, adj_e, new_p, ®ion); + } + remove_triangle(cdt, enclosing_triangle); + EDGELIST_FOREACH(e, region.edges_to_remove) + remove_edge(cdt, e); + EDGELIST_FOREACH_END(); + edgelist_free(region.edges_to_remove); + + points_to_attach = order_edges_adjacently(region.border_edges); + prev_point_node = points_to_attach; + new_edge(cdt, points_to_attach->item, new_p, 0); + POINTLIST_FOREACH(p, points_to_attach->next) + point_t *prev_p = prev_point_node->item; + new_edge(cdt, p, new_p, 0); + new_triangle(cdt, prev_p, p, new_p); + prev_point_node = _node_; + POINTLIST_FOREACH_END(); + new_triangle(cdt, prev_point_node->item, points_to_attach->item, new_p); + pointlist_free(points_to_attach); +} + +point_t *cdt_insert_point(cdt_t *cdt, coord_t x, coord_t y) +{ + pos_t pos; + point_t *new_p; + + pos.x = x; + pos.y = y; + VTPOINT_FOREACH(p, &cdt->points) + if (p->pos.x == pos.x && p->pos.y == pos.y) /* point in the same pos already exists */ + return p; + VTPOINT_FOREACH_END(); + + new_p = new_point(cdt, pos); + insert_point_(cdt, new_p); + + return new_p; +} + +void cdt_delete_point(cdt_t *cdt, point_t *p) +{ + edgelist_node_t *polygon_edges = NULL; + pointlist_node_t *polygon_points; + int i; + + /* find opposite edges of adjacent triangles and add them to the polygon */ + TRIANGLELIST_FOREACH(t, p->adj_triangles) + i = 0; + while(i < 3) { + edge_t *edge_of_triangle = t->e[i]; + EDGELIST_FOREACH(edge_of_point, p->adj_edges) + if (edge_of_point == edge_of_triangle) + goto next_i; + EDGELIST_FOREACH_END(); + polygon_edges = edgelist_prepend(polygon_edges, &edge_of_triangle); + break; +next_i: + i++; + } + TRIANGLELIST_FOREACH_END(); + + /* remove adjacent edges */ + EDGELIST_FOREACH(e, p->adj_edges) + assert(e->is_constrained == 0); + _node_ = _node_->next; + remove_edge(cdt, e); + continue; + EDGELIST_FOREACH_END(); + + /* remove point */ + for(i = 0; i < vtpoint_len(&cdt->points); i++) { + if (cdt->points.array[i] == p) { + vtpoint_remove(&cdt->points, i, 1); + break; + } + } + + polygon_points = order_edges_adjacently(polygon_edges); + triangulate_polygon(cdt, polygon_points); +} + +static trianglelist_node_t *triangles_intersecting_line(point_t *p1, point_t *p2) +{ + trianglelist_node_t *triangles = NULL; + triangle_t *next_t = NULL; + edge_t *adj_e; + int i; + + /* find first triangle */ + TRIANGLELIST_FOREACH(t, p1->adj_triangles) + for (i = 0; i < 3; i++) + if (t->e[i]->endp[0] != p1 && t->e[i]->endp[1] != p1) /* opposite edge */ + if (LINES_INTERSECT(p1, p2, t->e[i]->endp[0], t->e[i]->endp[1])) { + adj_e = t->e[i]; + next_t = adj_e->adj_t[0] != t ? adj_e->adj_t[0] : adj_e->adj_t[1]; + triangles = trianglelist_prepend(triangles, &t); + goto first_triangle_found; + } + TRIANGLELIST_FOREACH_END(); + +first_triangle_found: + assert(next_t != NULL); + + /* follow the path */ + while (next_t->p[0] != p2 && next_t->p[1] != p2 && next_t->p[2] != p2) { + triangle_t *t = next_t; + for (i = 0; i < 3; i++) + if (t->e[i] != adj_e && LINES_INTERSECT(p1, p2, t->e[i]->endp[0], t->e[i]->endp[1])) { + adj_e = t->e[i]; + next_t = adj_e->adj_t[0] != t ? adj_e->adj_t[0] : adj_e->adj_t[1]; + triangles = trianglelist_prepend(triangles, &t); + break; + } + } + + triangles = trianglelist_prepend(triangles, &next_t); + return triangles; +} + +static void insert_constrained_edge_(cdt_t *cdt, point_t *p1, point_t *p2, pointlist_node_t **left_poly, pointlist_node_t **right_poly) +{ + edge_t *e; + triangle_t *t; + trianglelist_node_t *triangles; + pointlist_node_t *left_polygon = NULL, *right_polygon = NULL; + int i; + + /* find intersecting edges and remove them */ + triangles = triangles_intersecting_line(p1, p2); + t = triangles->item; + triangles = trianglelist_remove_front(triangles); + left_polygon = pointlist_prepend(left_polygon, &p2); /* triangle list begins from p2 */ + right_polygon = pointlist_prepend(right_polygon, &p2); + for (i = 0; i < 3; i++) + if (t->p[i] != p2) { + if (ORIENT_CCW(p1, p2, t->p[i])) + left_polygon = pointlist_prepend(left_polygon, &t->p[i]); + else + right_polygon = pointlist_prepend(right_polygon, &t->p[i]); + } + + while (triangles->next != NULL) { + t = triangles->item; + triangles = trianglelist_remove_front(triangles); + e = get_edge_from_points(left_polygon->item, right_polygon->item); + for (i = 0; i < 3; i++) + if (t->p[i] != left_polygon->item && t->p[i] != right_polygon->item) { + if (ORIENT_CCW(p1, p2, t->p[i])) + left_polygon = pointlist_prepend(left_polygon, &t->p[i]); + else + right_polygon = pointlist_prepend(right_polygon, &t->p[i]); + break; + } + remove_edge(cdt, e); + } + triangles = trianglelist_remove_front(triangles); + remove_edge(cdt, get_edge_from_points(left_polygon->item, right_polygon->item)); + left_polygon = pointlist_prepend(left_polygon, &p1); + right_polygon = pointlist_prepend(right_polygon, &p1); + *left_poly = left_polygon; + *right_poly = right_polygon; +} + +edge_t *cdt_insert_constrained_edge(cdt_t *cdt, point_t *p1, point_t *p2) +{ + edge_t *e; + pointlist_node_t *left_polygon, *right_polygon; + + /* edge already exists - just constrain it */ + e = get_edge_from_points(p1, p2); + if (e != NULL) { + e->is_constrained = 1; + return e; + } + + insert_constrained_edge_(cdt, p1, p2, &left_polygon, &right_polygon); + + /* add new edge */ + e = new_edge(cdt, p1, p2, 1); + + /* triangulate the created polygons */ + triangulate_polygon(cdt, left_polygon); + triangulate_polygon(cdt, right_polygon); + + return e; +} + +void cdt_delete_constrained_edge(cdt_t *cdt, edge_t *edge) +{ + pointlist_node_t *polygon = NULL; + edgelist_node_t *border_edges = NULL; + edgelist_node_t *constrained_edges_within_scope = NULL; + pointlist_node_t *isolated_points = NULL; + int i, j; + + assert(edge->is_constrained); + + /* initial polygon */ + polygon = pointlist_prepend(polygon, &edge->endp[0]); + polygon = pointlist_prepend(polygon, &edge->endp[1]); + for (i = 0; i < 2; i++) { + triangle_t *t = edge->adj_t[i]; + for(j = 0; j < 3; j++) { + if (t->p[j] != edge->endp[0] && t->p[j] != edge->endp[1]) + polygon = pointlist_prepend(polygon, &edge->adj_t[i]->p[j]); + if (t->e[j] != edge) + border_edges = edgelist_prepend(border_edges, &t->e[j]); + } + } + remove_edge(cdt, edge); + + /* find invalid edges and remove them */ + EDGELIST_FOREACH(e, border_edges) + triangle_t *t = e->adj_t[0] != NULL ? e->adj_t[0] : e->adj_t[1]; + edgelist_node_t *e_node = _node_; + int invalid_edge = 0; + if (t != NULL) { + POINTLIST_FOREACH(p, polygon) + if (p != t->p[0] && p != t->p[1] && p != t->p[2] && is_point_in_circumcircle(p, t)) { + for (i = 0; i < 3; i++) { + if (t->p[i] != e->endp[0] && t->p[i] != e->endp[1]) + polygon = pointlist_prepend(polygon, &t->p[i]); + if (t->e[i] != e) + border_edges = edgelist_prepend(border_edges, &t->e[i]); + } + if (e->is_constrained) { /* don't remove constrained edges - only detach them */ + constrained_edges_within_scope = edgelist_prepend(constrained_edges_within_scope, &e); + for (i = 0; i < 2; i++) + e->endp[i]->adj_edges = edgelist_remove_item(e->endp[i]->adj_edges, &e); + remove_triangle(cdt, t); + } + else + remove_edge(cdt, e); + border_edges = edgelist_remove(border_edges, e_node); + invalid_edge = 1; + break; + } + POINTLIST_FOREACH_END(); + } + else { /* triangle beyond a border edge was removed earlier - the edge should be removed too */ + point_t *endp[2]; + endp[0] = e->endp[0]; + endp[1] = e->endp[1]; + for (i = 0; i < 2; i++) /* check if the edge is not bbox of the triangulation */ + if ((e->endp[i]->pos.x == cdt->bbox_tl.x && e->endp[i]->pos.y == cdt->bbox_tl.y) + || (e->endp[i]->pos.x == cdt->bbox_br.x && e->endp[i]->pos.y == cdt->bbox_br.y)) + goto next_edge; + border_edges = edgelist_remove(border_edges, e_node); + border_edges = edgelist_remove_item(border_edges, &e); + invalid_edge = 1; /* TODO: the loop doesn't have to start from the beginning, but border removal should preserve current node */ + if (e->is_constrained) { + constrained_edges_within_scope = edgelist_prepend(constrained_edges_within_scope, &e); + for (i = 0; i < 2; i++) + endp[i]->adj_edges = edgelist_remove_item(endp[i]->adj_edges, &e); /* detach the edge */ + } + else + remove_edge(cdt, e); + for (i = 0; i < 2; i++) { + if (endp[i]->adj_edges == NULL) { /* isolated point */ + polygon = pointlist_remove_item(polygon, &endp[i]); + isolated_points = pointlist_prepend(isolated_points, &endp[i]); + } + } + } + if (invalid_edge) { + _node_ = border_edges; /* start from the beginning (new point to check was added) */ + continue; + } +next_edge: + EDGELIST_FOREACH_END(); + pointlist_free(polygon); + + /* triangulate the resultant polygon */ + polygon = order_edges_adjacently(border_edges); + triangulate_polygon(cdt, polygon); + + /* reattach isolated points and constrained edges */ + POINTLIST_FOREACH(p, isolated_points) + insert_point_(cdt, p); + POINTLIST_FOREACH_END(); + pointlist_free(isolated_points); + EDGELIST_FOREACH(e, constrained_edges_within_scope) + pointlist_node_t *left_polygon, *right_polygon; + insert_constrained_edge_(cdt, e->endp[0], e->endp[1], &left_polygon, &right_polygon); + for (i = 0; i < 2; i++) + e->endp[i]->adj_edges = edgelist_prepend(e->endp[i]->adj_edges, &e); /* reattach the edge to the endpoints */ + triangulate_polygon(cdt, left_polygon); + triangulate_polygon(cdt, right_polygon); + EDGELIST_FOREACH_END(); + edgelist_free(constrained_edges_within_scope); +} + +static void circumcircle(const triangle_t *t, pos_t *p, int *r) +{ + double x1 = t->p[0]->pos.x, x2 = t->p[1]->pos.x, x3 = t->p[2]->pos.x; + double y1 = t->p[0]->pos.y, y2 = t->p[1]->pos.y, y3 = t->p[2]->pos.y; + double d1, d2, d3, d4; + double n1, n2, n3; + + n1 = (x1 * x1) + (y1 * y1); + n2 = (x2 * x2) + (y2 * y2); + n3 = (x3 * x3) + (y3 * y3); + + d1 = (x1 * y2) + (x2 * y3) + (x3 * y1) - (x3 * y2) - (x1 * y3) - (x2 * y1); + d2 = (n1 * y2) + (n2 * y3) + (n3 * y1) - (n3 * y2) - (n1 * y3) - (n2 * y1); + d3 = (n1 * x2) + (n2 * x3) + (n3 * x1) - (n3 * x2) - (n1 * x3) - (n2 * x1); + d4 = (n1 * x2 * y3) + (n2 * x3 * y1) + (n3 * x1 * y2) - (n3 * x2 * y1) - (n1 * x3 * y2) - (n2 * x1 * y3); + + p->x = d2/(2*d1); + p->y = -d3/(2*d1); + *r = sqrt((d2*d2)/(d1*d1) + (d3*d3)/(d1*d1) + 4*d4/d1)/2; +} + +void cdt_dump_animator(cdt_t *cdt, int show_circles, pointlist_node_t *point_violations, trianglelist_node_t *triangle_violations) +{ + int last_c = 0; + int triangle_num = 0; + printf("frame\n"); + printf("scale 0.9\n"); + printf("viewport %f %f - %f %f\n", (double)cdt->bbox_tl.x - 1.0, (double)cdt->bbox_tl.y - 1.0, (double)cdt->bbox_br.x + 1.0, (double)cdt->bbox_br.y + 1.0); + + VTEDGE_FOREACH(edge, &cdt->edges) + if(last_c != edge->is_constrained) { + printf("color %s\n", edge->is_constrained ? "red" : "black"); + printf("thick %s\n", edge->is_constrained ? "2" : "1"); + last_c = edge->is_constrained; + } + printf("line %d %d %d %d\n", edge->endp[0]->pos.x, edge->endp[0]->pos.y, edge->endp[1]->pos.x, edge->endp[1]->pos.y); + VTEDGE_FOREACH_END(); + + printf("color green\n"); + VTTRIANGLE_FOREACH(triangle, &cdt->triangles) + pos_t pos; + int r; + if (show_circles) { + circumcircle(triangle, &pos, &r); + printf("circle %d %d %d 50\n", pos.x, pos.y, r); + } + triangle_num++; + VTTRIANGLE_FOREACH_END(); + + printf("color red\n"); + if (point_violations) { + POINTLIST_FOREACH(p, point_violations) + printf("circle %d %d 50 10\n", p->pos.x, p->pos.y); + POINTLIST_FOREACH_END(); + } + + printf("color darkred\n"); + if (triangle_violations) { + TRIANGLELIST_FOREACH(t, triangle_violations) + pos_t pos; + int r; + circumcircle(t, &pos, &r); + printf("circle %d %d %d 50\n", pos.x, pos.y, r); + TRIANGLELIST_FOREACH_END(); + } + + printf("flush\n"); + fprintf(stderr, "triangle num: %d\n", triangle_num); +} + +int cdt_check_delaunay(cdt_t *cdt, pointlist_node_t **point_violations, trianglelist_node_t **triangle_violations) +{ + int delaunay = 1; + VTTRIANGLE_FOREACH(triangle, &cdt->triangles) + VTPOINT_FOREACH(point, &cdt->points) + if (is_point_in_circumcircle(point, triangle) + && point != triangle->p[0] + && point != triangle->p[1] + && point != triangle->p[2]) { + delaunay = 0; + if (point_violations != NULL) + *point_violations = pointlist_prepend(*point_violations, &point); + if (triangle_violations != NULL) + *triangle_violations = trianglelist_prepend(*triangle_violations, &triangle); + } + VTPOINT_FOREACH_END(); + VTTRIANGLE_FOREACH_END(); + return delaunay; +} Index: tags/2.3.0/src_3rd/libcdtr/cdt.h =================================================================== --- tags/2.3.0/src_3rd/libcdtr/cdt.h (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/cdt.h (revision 33253) @@ -0,0 +1,83 @@ +/* + libcdtr - Constrained Delaunay Triangulation using incremental algorithm + + Copyright (C) 2018 Wojciech Krutnik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + + Constrained Delaunay Triangulation using incremental algorithm, as described in: + Yizhi Lu and Wayne Wei-Ming Dai, "A numerical stable algorithm for constructing + constrained Delaunay triangulation and application to multichip module layout," + China., 1991 International Conference on Circuits and Systems, Shenzhen, 1991, + pp. 644-647 vol.2. + */ + +#ifndef CDT_H +#define CDT_H + +#include "typedefs.h" +#include "point.h" +#include "edge.h" +#include "triangle.h" + + +typedef struct { + vtpoint_t points; + vtedge_t edges; + vttriangle_t triangles; + + pos_t bbox_tl; + pos_t bbox_br; +} cdt_t; + + +void cdt_init(cdt_t *cdt, coord_t bbox_x1, coord_t bbox_y1, coord_t bbox_x2, coord_t bbox_y2); +void cdt_free(cdt_t *cdt); + +point_t *cdt_insert_point(cdt_t *cdt, coord_t x, coord_t y); +void cdt_delete_point(cdt_t *cdt, point_t *p); /* any edge adjecent to this point cannot be constrained */ +edge_t *cdt_insert_constrained_edge(cdt_t *cdt, point_t *p1, point_t *p2); +void cdt_delete_constrained_edge(cdt_t *cdt, edge_t *edge); + +int cdt_check_delaunay(cdt_t *cdt, pointlist_node_t **point_violations, trianglelist_node_t **triangle_violations); +void cdt_dump_animator(cdt_t *cdt, int show_circles, pointlist_node_t *point_violations, trianglelist_node_t *triangle_violations); + + +edge_t *get_edge_from_points(point_t *p1, point_t *p2); + +#define ORIENT_CCW(a, b, c) (orientation(a, b, c) < 0) +#define ORIENT_CW(a, b, c) (orientation(a, b, c) > 0) +#define ORIENT(dir, a, b, c) ((dir) ? ORIENT_CW(a, b, c) : ORIENT_CCW(a, b, c)) +/* TODO: check epsilon for collinear case? */ +#define ORIENT_COLLINEAR(a, b, c) (orientation(a, b, c) == 0) +#define ORIENT_CCW_CL(a, b, c) (orientation(a, b, c) <= 0) +static inline double orientation(point_t *p1, point_t *p2, point_t *p3) +{ + return ((double)p2->pos.y - (double)p1->pos.y) * ((double)p3->pos.x - (double)p2->pos.x) + - ((double)p2->pos.x - (double)p1->pos.x) * ((double)p3->pos.y - (double)p2->pos.y); +} + +#define LINES_INTERSECT(p1, q1, p2, q2) \ + (ORIENT_CCW(p1, q1, p2) != ORIENT_CCW(p1, q1, q2) && ORIENT_CCW(p2, q2, p1) != ORIENT_CCW(p2, q2, q1)) + +#define EDGE_OTHER_POINT(edge, point) \ + ((edge)->endp[0] != (point) ? (edge)->endp[0] : (edge)->endp[1]) + +#define DIST2(p, q) \ + (((double)((p)->pos.x - (q)->pos.x) * (double)((p)->pos.x - (q)->pos.x)) \ + + ((double)((p)->pos.y - (q)->pos.y) * (double)((p)->pos.y - (q)->pos.y))) + +#endif Index: tags/2.3.0/src_3rd/libcdtr/cdt_test.c =================================================================== --- tags/2.3.0/src_3rd/libcdtr/cdt_test.c (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/cdt_test.c (revision 33253) @@ -0,0 +1,211 @@ +#include +#include +#include "cdt.h" + +cdt_t cdt; + +int main(void) +{ + point_t *p1, *p2; + edge_t *ed[500]; + int i, j, e_num; + pointlist_node_t *p_violations = NULL; + + //cdt_init(&cdt, 1000, 1000, 5000, 5000); + cdt_init(&cdt, 0, 0, 100000, 100000); + + /* + point_t *p, *pd[1000]; + edge_t *e, + cdt_insert_point(&cdt, 2500, 3000); + cdt_insert_point(&cdt, 2600, 3000); + cdt_insert_point(&cdt, 2700, 3000); + cdt_insert_point(&cdt, 2800, 3000); + cdt_insert_point(&cdt, 2900, 3000); + cdt_insert_point(&cdt, 3000, 3000); + cdt_insert_point(&cdt, 3100, 3000); + cdt_insert_point(&cdt, 3200, 3000); + cdt_insert_point(&cdt, 3300, 3000); + cdt_insert_point(&cdt, 2800, 4800); + */ + + /* + cdt_insert_point(&cdt, 2700, 2700); + cdt_insert_point(&cdt, 2400, 2400); + cdt_insert_point(&cdt, 2400, 3000); + + cdt_insert_point(&cdt, 3400, 2700); + cdt_insert_point(&cdt, 3700, 2400); + cdt_insert_point(&cdt, 3700, 3000); + + cdt_insert_point(&cdt, 2900, 2700); + cdt_insert_point(&cdt, 3000, 2700); + cdt_insert_point(&cdt, 3100, 2700); + cdt_insert_point(&cdt, 3200, 2700); + */ + + /* + clock_t t; + srand(time(NULL)); + t = clock(); + for (i = 0; i < 1000; i++) { + cdt_insert_point(&cdt, rand()%99999 + 1, rand()%99999 + 1); + } + t = clock() - t; + fprintf(stderr, "Triangulation time: %f\n", ((float)t)/CLOCKS_PER_SEC); + */ + + /* octagon */ + /* + cdt_insert_point(&cdt, 4000, 3000); + cdt_insert_point(&cdt, 3700, 3700); + cdt_insert_point(&cdt, 3000, 4000); + cdt_insert_point(&cdt, 2300, 3700); + cdt_insert_point(&cdt, 2000, 3000); + cdt_insert_point(&cdt, 2300, 2300); + cdt_insert_point(&cdt, 3000, 2000); + cdt_insert_point(&cdt, 3700, 2300); + + p = cdt_insert_point(&cdt, 3000, 3000); + cdt_delete_point(&cdt, p); + */ + + /* concave poly */ + /* + cdt_insert_point(&cdt, 2000, 4000); + cdt_insert_point(&cdt, 3000, 3500); + cdt_insert_point(&cdt, 4000, 4000); + cdt_insert_point(&cdt, 4000, 2000); + cdt_insert_point(&cdt, 2000, 2000); + + p = cdt_insert_point(&cdt, 3000, 3000); + cdt_delete_point(&cdt, p); + */ + + /* constrained edge */ + /* + p1 = cdt_insert_point(&cdt, 1500, 3000); + cdt_insert_point(&cdt, 2000, 3500); + cdt_insert_point(&cdt, 2500, 2500); + cdt_insert_point(&cdt, 3000, 3500); + cdt_insert_point(&cdt, 3500, 2500); + cdt_insert_point(&cdt, 4000, 3500); + p2 = cdt_insert_point(&cdt, 4500, 3000); + + e = cdt_insert_constrained_edge(&cdt, p1, p2); + cdt_delete_constrained_edge(&cdt, e); + */ + + /* constrained edge 2 */ + /* + p1 = cdt_insert_point(&cdt, 1500, 3800); + cdt_insert_point(&cdt, 2700, 3000); + cdt_insert_point(&cdt, 2800, 3000); + cdt_insert_point(&cdt, 2900, 3000); + cdt_insert_point(&cdt, 3000, 3000); + cdt_insert_point(&cdt, 3100, 3000); + cdt_insert_point(&cdt, 3200, 3000); + cdt_insert_point(&cdt, 3300, 3000); + p2 = cdt_insert_point(&cdt, 4500, 3800); + cdt_insert_point(&cdt, 3000, 4800); + + e = cdt_insert_constrained_edge(&cdt, p1, p2); + */ + + /* + srand(time(NULL)); + for (i = 0; i < 1000; i++) { + cdt_insert_point(&cdt, rand()%99999 + 1, rand()%99999 + 1); + pd[i] = cdt_insert_point(&cdt, rand()%99999 + 1, rand()%99999 + 1); + } + for (i = 0; i < 1000; i++) { + cdt_delete_point(&cdt, pd[i]); + } + */ + + /* tricky case for triangulate_polygon */ + /* + p = cdt_insert_point(&cdt, 98347, 51060); + cdt_insert_point(&cdt, 92086, 47852); + cdt_insert_point(&cdt, 95806, 44000); + cdt_insert_point(&cdt, 95030, 41242); + cdt_insert_point(&cdt, 94644, 55629); + cdt_insert_point(&cdt, 94000, 45300); + + cdt_delete_point(&cdt, p); + */ + + /* delete constrained edge */ + /* + p1 = cdt_insert_point(&cdt, 1500, 3000); + cdt_insert_point(&cdt, 2000, 3500); + cdt_insert_point(&cdt, 1900, 2500); + cdt_insert_point(&cdt, 2400, 2500); + + cdt_insert_point(&cdt, 2800, 3500); + cdt_insert_point(&cdt, 3000, 3500); + cdt_insert_point(&cdt, 3200, 3500); + + cdt_insert_point(&cdt, 3600, 2500); + cdt_insert_point(&cdt, 4100, 2500); + cdt_insert_point(&cdt, 4000, 3500); + p2 = cdt_insert_point(&cdt, 4500, 3000); + + e = cdt_insert_constrained_edge(&cdt, p1, p2); + cdt_delete_constrained_edge(&cdt, e); + */ + + /* delete 2 constrained edges */ + /* + p1 = cdt_insert_point(&cdt, 2400, 1500); + cdt_insert_point(&cdt, 2200, 3500); + cdt_insert_point(&cdt, 2200, 2000); + p2 = cdt_insert_point(&cdt, 2400, 4000); + ed[0] = cdt_insert_constrained_edge(&cdt, p1, p2); + + p1 = cdt_insert_point(&cdt, 2500, 3000); + cdt_insert_point(&cdt, 3000, 2800); + cdt_insert_point(&cdt, 3500, 2800); + cdt_insert_point(&cdt, 2800, 3200); + cdt_insert_point(&cdt, 3500, 3200); + p2 = cdt_insert_point(&cdt, 4500, 3000); + ed[1] = cdt_insert_constrained_edge(&cdt, p1, p2); + + p2 = cdt_insert_point(&cdt, 3500, 3500); + ed[2] = cdt_insert_constrained_edge(&cdt, p1, p2); + + cdt_delete_constrained_edge(&cdt, ed[0]); + cdt_delete_constrained_edge(&cdt, ed[1]); + cdt_delete_constrained_edge(&cdt, ed[2]); + */ + + srand(time(NULL)); + e_num = 0; + for (i = 0; i < 100; i++) { + int isect = 0; + p1 = cdt_insert_point(&cdt, rand()%99999 + 1, rand()%99999 + 1); + p2 = cdt_insert_point(&cdt, rand()%99999 + 1, rand()%99999 + 1); + for (j = 0; j < e_num; j++) + if (LINES_INTERSECT(p1, p2, ed[j]->endp[0], ed[j]->endp[1])) { + isect = 1; + break; + } + if (!isect) { + ed[e_num] = cdt_insert_constrained_edge(&cdt, p1, p2); + e_num++; + } + } + for (i = 0; i < e_num; i++) { + fprintf(stderr, "deleting edge (%d, %d) - (%d, %d)\n", ed[i]->endp[0]->pos.x, ed[i]->endp[0]->pos.y, ed[i]->endp[1]->pos.x, ed[i]->endp[1]->pos.y); + cdt_delete_constrained_edge(&cdt, ed[i]); + } + + + if (cdt_check_delaunay(&cdt, &p_violations, NULL)) + fprintf(stderr, "delaunay\n"); + else + fprintf(stderr, "not delaunay\n"); + cdt_dump_animator(&cdt, 0, p_violations, NULL); + pointlist_free(p_violations); + cdt_free(&cdt); +} Index: tags/2.3.0/src_3rd/libcdtr/dep.sh =================================================================== --- tags/2.3.0/src_3rd/libcdtr/dep.sh (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/dep.sh (revision 33253) @@ -0,0 +1,8 @@ +#!/bin/sh + +cflags="$@" +tr " " "\n" | while read obj +do + c=${obj%%.o}.c + gcc -MT $obj -MM $c $cflags +done Property changes on: tags/2.3.0/src_3rd/libcdtr/dep.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/src_3rd/libcdtr/edge.c =================================================================== --- tags/2.3.0/src_3rd/libcdtr/edge.c (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/edge.c (revision 33253) @@ -0,0 +1,22 @@ +#define LST_DONT_UNDEF +#define GVT_DONT_UNDEF +#include "edge.h" + +static int LST(compare_func)(LST_ITEM_T *a, LST_ITEM_T *b) +{ + return *a == *b; +} + +int GVT(constructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem) +{ + *elem = calloc(1, sizeof(**elem)); + return *elem == NULL; +} + +void GVT(destructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem) +{ + free(*elem); +} + +#include +#include Index: tags/2.3.0/src_3rd/libcdtr/edge.h =================================================================== --- tags/2.3.0/src_3rd/libcdtr/edge.h (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/edge.h (revision 33253) @@ -0,0 +1,72 @@ +#ifndef EDGE_H +#define EDGE_H + +#include +#include + +#include "typedefs.h" + +struct edge_s { + point_t *endp[2]; + triangle_t *adj_t[2]; + + int is_constrained; + void *data; +}; + +typedef edge_t* edge_ptr_t; + + +/* List */ +#define LST(x) edgelist_ ## x +#define LST_ITEM_T edge_ptr_t +#define LST_DONT_TYPEDEF_NODE + +#include + +#ifndef LST_DONT_UNDEF + #undef LST + #undef LST_ITEM_T + #undef LST_DONT_TYPEDEF_NODE +#endif + +#define EDGELIST_FOREACH(_loop_item_, _list_) do { \ + edgelist_node_t *_node_ = _list_; \ + while (_node_ != NULL) { \ + edge_t *_loop_item_ = _node_->item; + +#define EDGELIST_FOREACH_END() \ + _node_ = _node_->next; \ + } \ +} while(0) + + +/* Vector */ +#define GVT(x) vtedge_ ## x +#define GVT_ELEM_TYPE edge_ptr_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 +#define GVT_ELEM_CONSTRUCTOR +#define GVT_ELEM_DESTRUCTOR +#define GVT_ELEM_COPY + +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +int GVT(constructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem); +void GVT(destructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem); +#include + +#define VTEDGE_FOREACH(_loop_item_, _vt_) do { \ + int _i_; \ + for (_i_ = 0; _i_ < vtedge_len(_vt_); _i_++) { \ + edge_t *_loop_item_ = (_vt_)->array[_i_]; + +#define VTEDGE_FOREACH_END() \ + } \ +} while(0) + +#endif Index: tags/2.3.0/src_3rd/libcdtr/list/list.c =================================================================== --- tags/2.3.0/src_3rd/libcdtr/list/list.c (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/list/list.c (revision 33253) @@ -0,0 +1,134 @@ +#include + +static LST(node_t) *LST(create)(LST_ITEM_T *item, LST(node_t) *next) +{ + LST(node_t) *new_node = (LST(node_t)*) malloc(sizeof(LST(node_t))); + new_node->item = *item; + new_node->next = next; + return new_node; +} + +LST(node_t) *LST(prepend)(LST(node_t) *list, LST_ITEM_T *item) +{ + LST(node_t) *new_head = LST(create)(item, list); + return new_head; +} + +LST(node_t) *LST(insert_after)(LST(node_t) *node, LST_ITEM_T *item) +{ + LST(node_t) *new_node; + if (node == NULL) + return NULL; + new_node = LST(create)(item, node->next); + node->next = new_node; + return new_node; +} + +LST(node_t) *LST(insert_after_nth)(LST(node_t) *list, int n, LST_ITEM_T *item) +{ + return LST(insert_after)(LST(nth)(list, n), item); +} + +LST(node_t) *LST(remove_front)(LST(node_t) *list) +{ + LST(node_t) *new_head; + if (list == NULL) + return NULL; + new_head = list->next; + free(list); + return new_head; +} + +LST(node_t) *LST(remove)(LST(node_t) *list, LST(node_t) *node) +{ + LST(node_t) *prev_node; + if (list == NULL) + return NULL; + if (list == node) + return LST(remove_front)(list); + for (prev_node = list; prev_node->next != NULL; prev_node = prev_node->next) { + if (prev_node->next == node) { + prev_node->next = node->next; + free(node); + break; + } + } + return list; +} + +LST(node_t) *LST(remove_item)(LST(node_t) *list, LST_ITEM_T *item) +{ + LST(node_t) *prev_node, *node; + if (list == NULL) + return NULL; + if (LST(compare_func)(&list->item, item)) + return LST(remove_front)(list); + for (prev_node = list, node = prev_node->next; node != NULL; prev_node = prev_node->next, node = node->next) { + if (LST(compare_func)(&node->item, item)) { + prev_node->next = node->next; + free(node); + break; + } + } + return list; +} + +LST(node_t) *LST(find)(LST(node_t) *list, LST_ITEM_T *item) +{ + LST(node_t) *node; + for (node = list; node != NULL; node = node->next) { + if (LST(compare_func)(&node->item, item)) { + return node; + } + } + return NULL; +} + +LST(node_t) *LST(nth)(LST(node_t) *list, int n) +{ + int i; + for (i = 0; i < n && list != NULL; i++) + list = list->next; + return list; +} + +LST(node_t) *LST(last)(LST(node_t) *list) +{ + if (list == NULL) + return NULL; + while (list->next != NULL) + list = list->next; + return list; +} + +size_t LST(length)(LST(node_t) *list) +{ + size_t len = 0; + if (list == NULL) + return 0; + for (; list != NULL; list = list->next) + len++; + return len; +} + +int LST(get_index)(LST(node_t) *list, LST(node_t) *node) +{ + int i; + if (list == NULL) + return -1; + for (i = 0; list != node && list != NULL; list = list->next) + i++; + if (list == NULL) + return -1; + return i; +} + +void LST(free)(LST(node_t) *list) +{ + LST(node_t) *node, *next_node; + if (list == NULL) + return; + for (node = list, next_node = node->next; next_node != NULL; node = next_node, next_node = next_node->next) + free(node); + free(node); +} Index: tags/2.3.0/src_3rd/libcdtr/list/list.h =================================================================== --- tags/2.3.0/src_3rd/libcdtr/list/list.h (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/list/list.h (revision 33253) @@ -0,0 +1,24 @@ + +struct LST(node_s) { + LST_ITEM_T item; + struct LST(node_s) *next; +}; + +#ifndef LST_DONT_TYPEDEF_NODE +typedef struct LST(node_s) LST(node_t); +#endif + +LST(node_t) *LST(prepend)(LST(node_t) *list, LST_ITEM_T *item); +LST(node_t) *LST(insert_after)(LST(node_t) *node, LST_ITEM_T *item); +LST(node_t) *LST(insert_after_nth)(LST(node_t) *list, int n, LST_ITEM_T *item); +LST(node_t) *LST(remove_front)(LST(node_t) *list); +LST(node_t) *LST(remove)(LST(node_t) *list, LST(node_t) *node); +LST(node_t) *LST(remove_item)(LST(node_t) *list, LST_ITEM_T *item); +LST(node_t) *LST(find)(LST(node_t) *list, LST_ITEM_T *item); +LST(node_t) *LST(nth)(LST(node_t) *list, int n); +LST(node_t) *LST(last)(LST(node_t) *list); + +size_t LST(length)(LST(node_t) *list); +int LST(get_index)(LST(node_t) *list, LST(node_t) *node); + +void LST(free)(LST(node_t) *list); Index: tags/2.3.0/src_3rd/libcdtr/list/testlist.c =================================================================== --- tags/2.3.0/src_3rd/libcdtr/list/testlist.c (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/list/testlist.c (revision 33253) @@ -0,0 +1,88 @@ +#include + +typedef struct { + int x; + int y; +} pos_t; + +#define LST(x) poslist_ ## x +#define LST_ITEM_T pos_t +int LST(compare_func)(LST_ITEM_T *a, LST_ITEM_T *b) +{ + return a->x == b->x && a->y == b->y; +} +#include "list.h" +#include "list.c" +#define POSLIST_FOREACH(loop_item, list) do { \ + poslist_node_t *node = list; \ + pos_t *loop_item; \ + while (node != NULL) { \ + loop_item = &node->item; + +#define POSLIST_FOREACH_END() \ + node = node->next; \ + } \ +} while(0) +#undef LST +#undef LST_ITEM_T + +#define LST(x) intlist_ ## x +#define LST_ITEM_T int +int LST(compare_func)(LST_ITEM_T *a, LST_ITEM_T *b) +{ + return *a == *b; +} +#include "list.h" +#include "list.c" +#define INTLIST_FOREACH(loop_item, list) do { \ + intlist_node_t *node = list; \ + int *loop_item; \ + while (node != NULL) { \ + loop_item = &node->item; + +#define INTLIST_FOREACH_END() \ + node = node->next; \ + } \ +} while(0) + + +int main(void) +{ + poslist_node_t *list1 = NULL; + intlist_node_t *list2 = NULL; + intlist_node_t *list2_node = NULL; + + pos_t p = {1, 2}; + int i = 4; + + list1 = poslist_prepend(list1, &p); p.x = 4; p.y = 5; + list1 = poslist_prepend(list1, &p); p.x = 8; p.y = 1; + list1 = poslist_prepend(list1, &p); + + list2 = intlist_prepend(list2, &i); i = 1; + list2 = intlist_prepend(list2, &i); i = 5; + list2 = intlist_prepend(list2, &i); + + i = 5; + list2 = intlist_remove_item(list2, &i); + + //~ list2_node = list2->next; + //~ list2 = intlist_remove(list2, list2_node); + + //~ list2 = intlist_remove_front(list2); + //~ list2 = intlist_remove_front(list2); + //~ list2 = intlist_remove_front(list2); + //~ list2 = intlist_remove_front(list2); + //~ list2 = intlist_remove_front(list2); i = 423; + //~ list2 = intlist_prepend(list2, &i); + + printf("list1:\n"); + POSLIST_FOREACH(pos, list1) + printf("%d, %d\n", pos->x, pos->y); + POSLIST_FOREACH_END(); + + printf("list2:\n"); + INTLIST_FOREACH(num, list2) + printf("%d\n", *num); + INTLIST_FOREACH_END(); +} Index: tags/2.3.0/src_3rd/libcdtr/point.c =================================================================== --- tags/2.3.0/src_3rd/libcdtr/point.c (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/point.c (revision 33253) @@ -0,0 +1,22 @@ +#define LST_DONT_UNDEF +#define GVT_DONT_UNDEF +#include "point.h" + +static int LST(compare_func)(LST_ITEM_T *a, LST_ITEM_T *b) +{ + return *a == *b; +} + +int GVT(constructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem) +{ + *elem = calloc(1, sizeof(**elem)); + return *elem == NULL; +} + +void GVT(destructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem) +{ + free(*elem); +} + +#include +#include Index: tags/2.3.0/src_3rd/libcdtr/point.h =================================================================== --- tags/2.3.0/src_3rd/libcdtr/point.h (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/point.h (revision 33253) @@ -0,0 +1,72 @@ +#ifndef POINT_H +#define POINT_H + +#include +#include + +#include "typedefs.h" + +struct point_s { + pos_t pos; + edgelist_node_t *adj_edges; + trianglelist_node_t *adj_triangles; + + void *data; +}; + +typedef point_t* point_ptr_t; + + +/* List */ +#define LST(x) pointlist_ ## x +#define LST_ITEM_T point_ptr_t +#define LST_DONT_TYPEDEF_NODE + +#include + +#ifndef LST_DONT_UNDEF + #undef LST + #undef LST_ITEM_T + #undef LST_DONT_TYPEDEF_NODE +#endif + +#define POINTLIST_FOREACH(_loop_item_, _list_) do { \ + pointlist_node_t *_node_ = _list_; \ + while (_node_ != NULL) { \ + point_t *_loop_item_ = _node_->item; + +#define POINTLIST_FOREACH_END() \ + _node_ = _node_->next; \ + } \ +} while(0) + + +/* Vector */ +#define GVT(x) vtpoint_ ## x +#define GVT_ELEM_TYPE point_ptr_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 +#define GVT_ELEM_CONSTRUCTOR +#define GVT_ELEM_DESTRUCTOR +#define GVT_ELEM_COPY + +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +int GVT(constructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem); +void GVT(destructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem); +#include + +#define VTPOINT_FOREACH(_loop_item_, _vt_) do { \ + int _i_; \ + for (_i_ = 0; _i_ < vtpoint_len(_vt_); _i_++) { \ + point_t *_loop_item_ = (_vt_)->array[_i_]; + +#define VTPOINT_FOREACH_END() \ + } \ +} while(0) + +#endif Index: tags/2.3.0/src_3rd/libcdtr/triangle.c =================================================================== --- tags/2.3.0/src_3rd/libcdtr/triangle.c (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/triangle.c (revision 33253) @@ -0,0 +1,22 @@ +#define LST_DONT_UNDEF +#define GVT_DONT_UNDEF +#include "triangle.h" + +static int LST(compare_func)(LST_ITEM_T *a, LST_ITEM_T *b) +{ + return *a == *b; +} + +int GVT(constructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem) +{ + *elem = calloc(1, sizeof(**elem)); + return *elem == NULL; +} + +void GVT(destructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem) +{ + free(*elem); +} + +#include +#include Index: tags/2.3.0/src_3rd/libcdtr/triangle.h =================================================================== --- tags/2.3.0/src_3rd/libcdtr/triangle.h (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/triangle.h (revision 33253) @@ -0,0 +1,70 @@ +#ifndef TRIANGLE_H +#define TRIANGLE_H + +#include +#include + +#include "typedefs.h" + +struct triangle_s { + point_t *p[3]; + edge_t *e[3]; + triangle_t *adj_t[3]; +}; + +typedef triangle_t* triangle_ptr_t; + + +/* List */ +#define LST(x) trianglelist_ ## x +#define LST_ITEM_T triangle_ptr_t +#define LST_DONT_TYPEDEF_NODE + +#include + +#ifndef LST_DONT_UNDEF + #undef LST + #undef LST_ITEM_T + #undef LST_DONT_TYPEDEF_NODE +#endif + +#define TRIANGLELIST_FOREACH(_loop_item_, _list_) do { \ + trianglelist_node_t *_node_ = _list_; \ + while (_node_ != NULL) { \ + triangle_t *_loop_item_ = _node_->item; + +#define TRIANGLELIST_FOREACH_END() \ + _node_ = _node_->next; \ + } \ +} while(0) + + +/* Vector */ +#define GVT(x) vttriangle_ ## x +#define GVT_ELEM_TYPE triangle_ptr_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 +#define GVT_ELEM_CONSTRUCTOR +#define GVT_ELEM_DESTRUCTOR +#define GVT_ELEM_COPY + +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +int GVT(constructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem); +void GVT(destructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem); +#include + +#define VTTRIANGLE_FOREACH(_loop_item_, _vt_) do { \ + int _i_; \ + for (_i_ = 0; _i_ < vttriangle_len(_vt_); _i_++) { \ + triangle_t *_loop_item_ = (_vt_)->array[_i_]; + +#define VTTRIANGLE_FOREACH_END() \ + } \ +} while(0) + +#endif Index: tags/2.3.0/src_3rd/libcdtr/typedefs.h =================================================================== --- tags/2.3.0/src_3rd/libcdtr/typedefs.h (nonexistent) +++ tags/2.3.0/src_3rd/libcdtr/typedefs.h (revision 33253) @@ -0,0 +1,24 @@ +#ifndef TYPEDEFS_H +#define TYPEDEFS_H + +#ifdef CDT_COORD_T + typedef CDT_COORD_T coord_t; +#else + typedef int coord_t; +#endif + + +typedef struct { + coord_t x; + coord_t y; +} pos_t; + +typedef struct point_s point_t; +typedef struct edge_s edge_t; +typedef struct triangle_s triangle_t; + +typedef struct pointlist_node_s pointlist_node_t; +typedef struct edgelist_node_s edgelist_node_t; +typedef struct trianglelist_node_s trianglelist_node_t; + +#endif Index: tags/2.3.0/src_3rd/libfungwbind/README =================================================================== --- tags/2.3.0/src_3rd/libfungwbind/README (nonexistent) +++ tags/2.3.0/src_3rd/libfungwbind/README (revision 33253) @@ -0,0 +1,4 @@ +This is the fallback scripting facility: if system installed fungw is not +found, the local libfungw extern is used and the script plugin will static +link this one binding. This binding does not have any external dependency +and provides multiple scripting languages. Index: tags/2.3.0/src_3rd/libfungwbind =================================================================== --- tags/2.3.0/src_3rd/libfungwbind (nonexistent) +++ tags/2.3.0/src_3rd/libfungwbind (revision 33253) Property changes on: tags/2.3.0/src_3rd/libfungwbind ___________________________________________________________________ Added: svn:externals ## -0,0 +1,2 ## +fawk -r599 svn://svn.repo.hu/fungw/trunk/libfungwbind/fawk +c -r599 svn://svn.repo.hu/fungw/trunk/libfungwbind/c Index: tags/2.3.0/src_3rd/libporty_net/Makefile =================================================================== --- tags/2.3.0/src_3rd/libporty_net/Makefile (nonexistent) +++ tags/2.3.0/src_3rd/libporty_net/Makefile (revision 33253) @@ -0,0 +1,15 @@ +ROOT=../.. + +#CFLAGS = -Wall -O3 + +libportytcp4.o: libportytcp4.c libportytcp4.h + +libportytcp4.c libportytcp4.h: concat.sh + ./concat.sh + +include ../../Makefile.conf + +clean: + +distclean: + $(SCCBOX) rm -f -q os_includes.h pnet_config.h phost_types.h \ No newline at end of file Index: tags/2.3.0/src_3rd/libporty_net/concat.sh =================================================================== --- tags/2.3.0/src_3rd/libporty_net/concat.sh (nonexistent) +++ tags/2.3.0/src_3rd/libporty_net/concat.sh (revision 33253) @@ -0,0 +1,31 @@ +#!/bin/sh + +tmp=net + +fixinc() +{ + grep -v "^#include \"\|^#include pnet_config.h.in +svn cat svn://repo.hu/libporty/trunk/src/libporty/host/types.h.in > phost_types.h.in +svn cat svn://repo.hu/libporty/trunk/src/libporty/host/time.c > time.c +svn cat svn://repo.hu/libporty/trunk/src/libporty/host/time.h > time.h +cp net/os_includes.h.in . + +(echo ' +#define _DEFAULT_SOURCE +#ifndef WIN32 +#include +#endif +#include "os_includes.h" +#include "pnet_config.h" +#include "phost_types.h" +' +cat $tmp/os_dep.h time.h $tmp/network.h $tmp/tcp4.h $tmp/dns4.h $tmp/uninit_chain.h | fixinc) > libportytcp4.h + +(echo '#include "libportytcp4.h"' +cat $tmp/os_dep.c time.c $tmp/tcp4.c $tmp/dns4.c $tmp/uninit_chain.c | fixinc) > libportytcp4.c + + Property changes on: tags/2.3.0/src_3rd/libporty_net/concat.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/src_3rd/libporty_net/hooks_net.c =================================================================== --- tags/2.3.0/src_3rd/libporty_net/hooks_net.c (nonexistent) +++ tags/2.3.0/src_3rd/libporty_net/hooks_net.c (revision 33253) @@ -0,0 +1,68 @@ +void libporty_net_detect_target() +{ + require("sys/byte_order", 1, 1); + require("cc/inline", 1, 0); + +/* for bgtask */ + require("libs/lpthread", 1, 0); + + require("libs/time/usleep/presents", 1, 0); + require("libs/time/Sleep/presents", 1, 0); + + /* find a suitable way to query subsecond time - prefer gettimeofday over ftime */ + if (require("libs/time/gettimeofday/presents", 1, 0)) + require("libs/time/ftime/presents", 1, 1); + + /* for P_quick_exit() */ + if (require("cc/_exit/presents", 1, 0)) { + require("signal/raise/presents", 1, 1); + require("signal/names/*", 1, 1); + } + + + /* socket library for net */ + require("libs/socket/poll/presents", 1, 0); + require("libs/socket/select/presents", 1, 0); + require("libs/socket/closesocket/presents", 1, 0); + require("libs/vdprintf", 1, 0); + require("libs/vsnprintf", 1, 0); + require("libs/snprintf", 1, 0); + + require("libs/socket/socketpair/presents", 1, 0); + require("libs/socket/ioctl/presents", 1, 0); + require("libs/socket/ioctl/fionbio/presents", 1, 1); /* fatal because there is no alternative at the moment */ + require("libs/socket/lac/presents", 1, 1); + require("libs/socket/recvsend/presents", 1, 1); + require("libs/socket/readwrite/presents", 1, 0); + require("libs/socket/shutdown/presents", 1, 1); + require("libs/socket/ntoh/presents", 1, 1); + require("libs/socket/socklen_t/*", 1, 0); + require("libs/socket/gethostname/presents", 1, 1); + if (require("libs/socket/getaddrinfo/presents", 1, 0)) + put("local/net/use_porty_resolver", strue); + else + put("local/net/use_porty_resolver", sfalse); + + + /* Try to find constants for shutdown - SHUT_* on POSIX and SD_* on win32. + If none found we will fall back using hardwired integers. */ + if (require("libs/socket/SHUT/presents", 1, 0)) + require("libs/socket/SD/presents", 1, 0); + + if (require("libs/fs/readdir/presents", 1, 0)) + require("libs/fs/findnextfile/presents", 1, 1); + + + /* detect integer types for host/types.h */ + require("sys/types/size/1_u_int", 1, 1); + require("sys/types/size/2_u_int", 1, 1); + require("sys/types/size/4_u_int", 1, 1); + require("sys/types/size/1_s_int", 1, 1); + require("sys/types/size/2_s_int", 1, 1); + require("sys/types/size/4_s_int", 1, 1); + + require("sys/ptrwidth", 1, 1); + require("sys/types/size_t/broken", 1, 0); + require("sys/types/off_t/broken", 1, 0); + require("sys/types/ptrdiff_t/broken", 1, 0); +} Index: tags/2.3.0/src_3rd/libporty_net/libportytcp4.c =================================================================== --- tags/2.3.0/src_3rd/libporty_net/libportytcp4.c (nonexistent) +++ tags/2.3.0/src_3rd/libporty_net/libportytcp4.c (revision 33253) @@ -0,0 +1,875 @@ +#include "libportytcp4.h" +/* + libporty - collection of random system-dependent network code + Copyright (C) 2005 gpmi-extension project + Copyright (C) 2010..2012 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Project page: http://repo.hu/projects/libporty + Author: libporty@igor2.repo.hu +*/ + +#include + +int P_net_close(P_net_socket s) +{ +#ifdef P_NET_CLOSESOCKET + if (P_net_shutdown(s, P_SHUT_RDWR) != 0) + return -1; + return closesocket(s); +#else + return close(s); +#endif +} + + +int P_net_set_nonblocking(int sock) +{ +#ifdef WIN32 + u_long nonblocking = 1; +#else + int nonblocking = 1; +#endif + return P_ioctl_socket(sock, FIONBIO, &nonblocking); +} + +int P_net_set_blocking(int sock) +{ +#ifdef WIN32 + u_long nonblocking = 0; +#else + int nonblocking = 0; +#endif + + return P_ioctl_socket(sock, FIONBIO, &nonblocking); +} + +/* UDP only! */ +int P_net_enable_broadcast(int sock) +{ + /* Enable broadcast */ + unsigned long val = 1; + return setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&val , sizeof(val)); +} + +/* alternative poll() implementations, in case we don't have native poll() */ +#ifndef P_NET_POLL + +#ifdef P_NET_SELECT +#include +#include +#include +int P_poll_select(struct P_pollfd *fds, nfds_t nfds, int timeout) +{ + fd_set rd, wr; + int snfds, n, ret; + struct timeval to; + + snfds = -1; + FD_ZERO(&rd); + FD_ZERO(&wr); +# warning TODO: reproduce odd behavior of poll() returning HUP even if events is 0 + for(n = 0; n < nfds; n++) { + if ((fds[n].events != 0) && (fds[n].fd >= 0)) { + if (fds[n].fd >= snfds) + snfds = fds[n].fd; + if (fds[n].events & P_POLLIN) + FD_SET(fds[n].fd, &rd); + if (fds[n].events & P_POLLOUT) + FD_SET(fds[n].fd, &wr); + } else { + fds[n].revents = 0; + } +# warning add support for POLLPRI? + } + if (snfds == -1) { + P_usleep(timeout * 1000); + return 0; + } + + to.tv_sec = timeout / 1000; + to.tv_usec = (timeout - (to.tv_sec * 1000)) * 1000; + ret = select(snfds + 1, &rd, &wr, NULL, &to); + if (ret < 0) + return ret; + ret = 0; + for(n = 0; n < nfds; n++) { + fds[n].revents = 0; + if (FD_ISSET(fds[n].fd, &rd)) + fds[n].revents |= P_POLLIN; + if (FD_ISSET(fds[n].fd, &wr)) + fds[n].revents |= P_POLLOUT; + if (fds[n].revents != 0) + ret++; +# warning add support for the other standard poll outputs + } + return ret; +} + +#else +int P_poll_busyloop(struct P_pollfd *fds, nfds_t nfds, int timeout) +{ + fprintf(stderr, "P_poll_busyloop() unimplemented yet (TODO)\n"); + abort(); +} +#endif + +#endif + + +#ifndef WIN32 + +/* Sockets can be written and read; async stdio may not be a socket + thus recv() and send() would fail */ +P_size_t P_net_read(P_net_socket s, void *buf, P_size_t count) +{ + return read(s, buf, count); +} + +P_size_t P_net_write(P_net_socket s, void *buf, P_size_t count) +{ + return write(s, buf, count); +} + +#else + +/* Sockets can not be handled by read() and write(); we made sure + async stdio has a real socket and a thread/fork. */ +P_size_t P_net_read(P_net_socket s, void *buf, P_size_t count) +{ + return recv(s, buf, count, 0); +} + +P_size_t P_net_write(P_net_socket s, void *buf, P_size_t count) +{ + return send(s, buf, count, 0); +} +#endif + + +int P_net_printf_minbuff = 1024; +int P_net_printf_maxbuff = 65536; + +#ifdef P_HAVE_VDPRINTF +#include +P_size_t P_net_printf(P_net_socket s, const char *format, ...) +{ + int ret; + va_list ap; + va_start(ap, format); + ret = vdprintf(s, format, ap); + va_end(ap); + return ret; +} +#else +/* we can't use fdopen as an alternative because fclose() would close the +socket. We could hash P_net_socket -> FILE *, but we wouldn't notice +if the fd was replaced meanwhile and the system will most probably +reuse fd numbers. (Or else all libporty calls that could affect what an fd +means would need to maintain the hash). */ +#include +#include + +#ifdef P_HAVE_VSNPRINTF +# ifdef P_HAVE_VSNPRINTF_SAFE +# define SAFETY 0 +# else +# define SAFETY 1 +# endif +P_size_t P_net_printf(P_net_socket s, const char *format, ...) +{ + int size; + char *buff; + int ret; + va_list ap; + + for(size = P_net_printf_minbuff; size <= P_net_printf_maxbuff; size = size * 2) { + buff = malloc(size + SAFETY); + if (buff == NULL) + return 0; + va_start(ap, format); + ret = vsnprintf(buff, size, format, ap); + va_end(ap); + if (ret <= size && ret != -1) + break; + } + if (ret <= size && ret >= 0) + ret = P_net_write(s, buff, ret); + + free(buff); + + + if (ret <= size) + return ret; + return -1; +} +#else +/* we don't have anything advanced so allocate a 'large enough' buffer and +check for overflow */ +#include +#include +P_size_t P_net_printf(P_net_socket s, const char *format, ...) +{ + char *buff; + int len; + va_list ap; + va_start(ap, format); + + buff = malloc(P_net_printf_maxbuff); + len = vsprintf(buff, format, ap); + if (len >= P_net_printf_maxbuff) { + fprintf(stderr, "P_net_printf: buffer (%d) too small (need %d); please increase P_net_printf_maxbuff\n", P_net_printf_maxbuff, len); + abort(); + } + len = P_net_write(s, buff, len); + + free(buff); + va_end(ap); + return len; +} +#endif +#endif + +static long P_net_inited = 0; + +#ifdef WIN32 +int P_net_init(void) +{ + WSADATA w; + P_net_inited++; + if (P_net_inited == 1) + return WSAStartup(MAKEWORD(2,2), &w); + return 0; +} + +int P_net_uninit(void) +{ + P_net_inited--; + if (P_net_inited > 0) + return 0; + P_net_uninit_chain(); + return WSACleanup(); +} +#else +#include +int P_net_init(void) +{ + P_net_inited++; + if (P_net_inited == 1) + signal(SIGPIPE, SIG_IGN); + return 0; +} + +int P_net_uninit(void) +{ + P_net_inited--; + if (P_net_inited > 0) + return 0; + P_net_uninit_chain(); + return 0; +} +#endif + +#ifdef WIN32 +P_net_socket P_socket(int af, int protocol, int type) +{ + return WSASocket(af, protocol, type, NULL, 0, 0); +} +#endif +/* + libporty - time/date functions + Copyright (C) 2011..2012 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Project page: http://repo.hu/projects/libporty + Author: libporty@igor2.repo.hu +*/ + +#include + + +#ifdef P_HAVE_GETTIMEOFDAY +# include +#else +# ifdef P_HAVE_FTIME +# include +# else +# error We have no gettimeofday() or ftime() - can not query for time! +# endif +#endif + + +void P_ltime(P_time_t *secs, P_time_t *usecs) +{ +#ifdef P_HAVE_GETTIMEOFDAY + struct timeval tv; + gettimeofday(&tv, NULL); + *secs = tv.tv_sec; + if (usecs != NULL) + *usecs = tv.tv_usec; +#else +# ifdef P_HAVE_FTIME + struct timeb tb; + ftime(&tb); + *secs = tb.time; + if (usecs != NULL) + *usecs = (P_time_t)(tb.millitm) * 1000; +# endif +#endif +} + +double P_dtime(void) +{ + P_time_t s, u; + + P_ltime(&s, &u); + return (double)u / 1000000.0 + (double)s; +} + +void P_usleep(long int usecs) +{ +#ifdef P_HAVE_USLEEP +# define USLEEP_MAX (1000000-1) + while(usecs > USLEEP_MAX) { + usleep(USLEEP_MAX); + usecs -= USLEEP_MAX; + } + usleep(usecs); +#else +# ifdef P_HAVE_WSLEEP + int ms = usecs/1000; + if (ms < 1) ms = 1; + Sleep(ms); +# else +# ifdef P_NET_SELECT + fd_set s; + struct timeval tv; + + FD_ZERO(&s); + tv.tv_sec = 0; + tv.tv_usec = usecs; + select(0, &s, &s, &s, &tv); +# endif +# endif +#endif +} + +void P_dsleep(double secs) +{ + double finish_at, remaining; + + finish_at = P_dtime() + secs; + remaining = secs * 1000000.0; + + while(remaining > 0) { + if (remaining > 1000000) + remaining = 1000000; + P_usleep(remaining); + remaining = (finish_at - P_dtime()) * 1000000.0; + } +} + +/* + libporty - IPv4 TCP + Copyright (C) 2005 gpmi-extension project + Copyright (C) 2010..2012 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Project page: http://repo.hu/projects/libporty + Author: libporty@igor2.repo.hu +*/ + +#include +#include + +/** + * Opens a listen-socket on TCP for IPv4. + * + * @param socket The socket that will get the listener + * @param hostname The hostname (may be an IP) to bind to + * @param port The bind-port + * @param non_blocking Bitfield P_net_nonblock_net_nonblock_operation + * @param backlog Size of backlog (see 'man listen') + * @return see enum P_net_err + */ +int P_tcp4_listen(P_net_socket *sock, const char *hostname, int port, P_net_nonblock_t non_blocking, int backlog) +{ + P_ipv4_addr_t ip; + struct sockaddr_in sin; + int reuse = 1; + + + if (P_dns4_name_to_IP(&ip, hostname) != 0) + return P_net_err_dns; + + /* Create the socket */ + *sock = P_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (*sock == P_NET_INVALID_SOCKET) + return P_net_err_socket; + + { /* Set the socket to reuse */ + /* The (const char*) cast is needed for windows!! */ + if (setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) == -1) { + P_net_close(*sock); + return P_net_err_reuse; + } + } + + /* Switch to non-blocking, if needed */ + if (non_blocking & P_net_nonblock_socket) { + if (P_net_set_nonblocking(*sock) != 0 && (non_blocking & P_net_nonblock_quit_on_error)) { + P_net_close(*sock); + return P_net_err_nonblock; + } + } + + /* Create the data for the bind */ + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = ip; + sin.sin_port = htons(port); + + /* Bind */ + if (bind(*sock, (struct sockaddr *)&sin, sizeof(sin)) != 0) { + P_net_close(*sock); + return P_net_err_bind; + } + + /* Start listener */ + if (listen(*sock, backlog) != 0) { + P_net_close(*sock); + return P_net_err_listen; + } + + return 0; +} + +/** + * Connect to a hostname / port. + * + * @param sock The socket which will connect + * @param hostname The host to connect to + * @param port The port to connect to + * @param non_blocking Bitfield, enum P_net_nonblock + + Bit 1: quit on error, bit 2: connect non-blocking (watch out with this!), + * bit 4: set non-blocking after connect + * @return see enum P_net_err + */ +int P_tcp4_connect(P_net_socket *sock, const char *rem_hostname, int rem_port, const char *loc_hostname, int loc_port, P_net_nonblock_t non_blocking) +{ + P_ipv4_addr_t ip, loc_ip; + struct sockaddr_in sin; + + if (P_dns4_name_to_IP(&ip, rem_hostname) != 0) + return P_net_err_dns; + + *sock = P_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (*sock == P_NET_INVALID_SOCKET) + return P_net_err_socket; + + + /* Switch to non-blocking, if needed */ + if (non_blocking & P_net_nonblock_connect) { + if (P_net_set_nonblocking(*sock) != 0 && (non_blocking & P_net_nonblock_quit_on_error)) { + P_net_close(*sock); + return P_net_err_nonblock; + } + } + + /* set up sin for local and remote host/port */ + memset((char *) &sin, 0, sizeof(struct sockaddr_in)); + sin.sin_family = AF_INET; + + /* set local host if needed */ + if (loc_hostname != NULL) { + if (P_dns4_name_to_IP(&loc_ip, loc_hostname) != 0) + return P_net_err_dns; + + sin.sin_addr.s_addr = loc_ip; + } + + /* set local port if needed */ + if (loc_port > 0) + sin.sin_port = htons(loc_port); + + /* bind if anything local was set */ + if ((loc_hostname != NULL) || (loc_port > 0)) { + if (bind(*sock, (struct sockaddr *) &sin, sizeof(sin)) != 0) + return P_net_err_bind; + } + + /* set up remote host and port */ + + sin.sin_addr.s_addr = ip; + sin.sin_port = htons(rem_port); + + if ((connect(*sock, (struct sockaddr*) &sin, sizeof(sin)) != 0) && (!P_net_inprogress)) { + P_net_close(*sock); + return P_net_err_connect; + } + + /* Switch to non-blocking, if needed */ + if (non_blocking & P_net_nonblock_socket) { + if (P_net_set_nonblocking(*sock) != 0 && (non_blocking & P_net_nonblock_quit_on_error)) { + P_net_close(*sock); + return P_net_err_nonblock; + } + } + + return 0; +} + +int P_tcp4_accept(P_net_socket *new_socket, P_net_socket listen_sock, P_ipv4_addr_t *rem_ip, char **rem_host, int *rem_port, P_net_nonblock_t non_blocking) +{ + struct sockaddr_in sin; + int ret; + P_socklen_t len; + + len = sizeof(sin); + ret = accept(listen_sock, (struct sockaddr *)&sin, &len); + if (ret < 0) + return P_net_err_accept; + + *new_socket = ret; + if (rem_ip != NULL) + *rem_ip = ntohl(sin.sin_addr.s_addr); + if (rem_port != NULL) + *rem_port = ntohs(sin.sin_port); + if (rem_host != NULL) { + P_ipv4_addr_t ip; + ip = sin.sin_addr.s_addr; + P_dns4_IP_to_name(rem_host, &ip); + } + + /* Switch newly accepted socket to non-blocking, if needed */ + if (non_blocking & P_net_nonblock_socket) { + if (P_net_set_nonblocking(*new_socket) != 0 && (non_blocking & P_net_nonblock_quit_on_error)) { + P_net_close(*new_socket); + return P_net_err_nonblock; + } + } + + return 0; +} + +/* + libporty - IPv4 dns + Copyright (C) 2005 gpmi-extension project + Copyright (C) 2010..2012 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Project page: http://repo.hu/projects/libporty + Author: libporty@igor2.repo.hu +*/ + +#include +#include +#include +#include +#define P_NET_HOSTNAME_SIZE 256 + +#ifdef WIN32 +/* this define is needed for getaddrinfo, freeaddrinfo and getnameinfo + * because mingw enclose their declarations in #if (_WIN32_WINNT >= 0x0501) + * but they are available on all windows version (accordiing msdn) + */ +#define _WIN32_WINNT 0x0501 +#endif + + +#ifdef P_USE_PORTY_RESOLVER + +/* include libporty's own resolver here */ +#define P_NET_RESOLVER_LOCAL_USE +#undef P_NET_RESOLVER_LOCAL_USE + + +int P_dns4_name_to_IP(P_ipv4_addr_t *ip, const char *hostname) +{ + char *ips; + int ret; + + /* P_net_resolv will eventually call us again with the IP of the name server; + we must handle IP numbers as special; otherwise this also speeds up + thing as if the original request was an IP address (from a connect for + example) we wouldn't be able to resolve it through DNS anyway */ + if (P_dns4_is_addr(hostname)) + return P_dns4_addr_to_IP(ip, hostname); + + if (hostname == NULL) + return - 257; + ips = NULL; + ret = P_net_resolv((char **)&hostname, &ips); + if (ret != 0) + return ret; + + ret = P_dns4_addr_to_IP(ip, ips); + free(ips); + return ret; +} + +int P_dns4_IP_to_name(char **hostname, P_ipv4_addr_t *ip) +{ + char *ips; + + ips = malloc(256); + + if (P_dns4_IP_to_addr(ip, ips) != 0) + return -257; + + *hostname = NULL; + return P_net_resolv(hostname, &ips); +} + + +#else + +/* If return is non-zero, something went wrong! */ +int P_dns4_name_to_IP(P_ipv4_addr_t *ip, const char *hostname) +{ + struct addrinfo req, *ans; + int code; + + memset(&req, 0, sizeof(req)); + req.ai_flags = 0; + req.ai_family = PF_INET; + req.ai_socktype = SOCK_STREAM; + req.ai_protocol = IPPROTO_TCP; + + if ((code = getaddrinfo(hostname, NULL, &req, &ans)) != 0) + return code; + + *ip = ((struct sockaddr_in *)ans->ai_addr)->sin_addr.s_addr; + + freeaddrinfo(ans); + + return 0; +} + +int P_dns4_IP_to_name(char **hostname, P_ipv4_addr_t *ip) +{ + struct sockaddr_in sa; + char *buf; + + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = *ip; + + /* we expect getnameinfo to be succesfull most of the time, so we allocate in + any way and then free if we failed */ + buf = malloc(P_NET_HOSTNAME_SIZE); + if (getnameinfo((struct sockaddr *)&sa, sizeof(sa), buf, P_NET_HOSTNAME_SIZE, NULL, 0, 0)) { + free(buf); + return P_net_err_dns; + } + + *hostname = buf; + + return 0; +} + +#endif + +char *P_dns4_get_my_name(void) +{ + char *buf; + + buf = malloc(P_NET_HOSTNAME_SIZE); + gethostname(buf, P_NET_HOSTNAME_SIZE); + + return buf; +} + +P_ipv4_addr_t P_dns4_get_my_IP(void) +{ + P_ipv4_addr_t ip; + char *name = P_dns4_get_my_name(); + + ip = 0xFFFFFFFF; + P_dns4_name_to_IP(&ip, name); + free(name); + + return ip; +} + +int P_dns4_is_addr(const char *name) +{ + char tmp[4]; + char *d; + const char *s; + int c; + + *tmp = '\0'; + tmp[3] = '\0'; + + for(s = name, c = 3, d = tmp;; s++) { + if (isdigit(*s)) { + /* None of the tags may be longer than 3 characters */ + c--; + if (c < 0) + return 0; + + *d = *s; + d++; + } + else if ((*s == '.') || (*s == '\0')) { /* A separator */ + *d = '\0'; + c = atoi(tmp); + /* a tag is out of range */ + if ((*tmp == '\0') || (c < 0) || (c > 255)) + return 0; + + /* Check if end of the string, if so, return true */ + if (*s == '\0') + return 1; + + c = 3; + d = tmp; + *d = 0; + } + else /* Contains a char that is neither a digit nor a dot */ + return 0; + } + + /* We can't get here */ + return 0; +} + +int P_dns4_IP_to_addr(P_ipv4_addr_t *ip_in, char *addr_out) +{ + P_ipv4_addr_t ip_ = htonl(*ip_in); + unsigned char *ip = (unsigned char *)&ip_; + char *s; + int n; + + s = addr_out; + for(n = 0; n < 4; n++) { + s += sprintf(s, "%d.", ip[n]); + } + if (s > addr_out) + s--; + *s = '\0'; + return 0; +} + +int P_dns4_addr_to_IP(P_ipv4_addr_t *ip_out, const char *addr_in) +{ + const char *start; + char *end; + int token, n; + unsigned char *ip = (unsigned char *)ip_out; + + start = addr_in; + for(n = 0; n < 4; n++) { + token = strtol(start, &end, 10); + if ((*end != '.') && (*end != '\0')) + return -1; + if ((*end == '\0') && (n != 3)) + return -2; + ip[3-n] = token; + start = end + 1; + } + *ip_out = ntohl(*ip_out); + return 0; +} +/* + libporty - network uninit chains + Copyright (C) 2012 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Project page: http://repo.hu/projects/libporty + Author: libporty@igor2.repo.hu +*/ + +#include + +P_net_uninit_t *P_net_uninits = NULL; + +void P_net_uninit_chain(void) +{ + P_net_uninit_t *u, *next; + + /* walk through the list and call each item then free it */ + for(u = P_net_uninits; u != NULL; u = next) { + next = u->next; + u->cb(); + free(u); + } + P_net_uninits = NULL; +} + +void P_net_uninit_reg(void (*cb)()) +{ + P_net_uninit_t *u; + + u = malloc(sizeof(P_net_uninit_t)); + u->cb = cb; + u->next = P_net_uninits; + P_net_uninits = u; +} Index: tags/2.3.0/src_3rd/libporty_net/libportytcp4.h =================================================================== --- tags/2.3.0/src_3rd/libporty_net/libportytcp4.h (nonexistent) +++ tags/2.3.0/src_3rd/libporty_net/libportytcp4.h (revision 33253) @@ -0,0 +1,283 @@ + +#define _DEFAULT_SOURCE +#ifndef WIN32 +#include +#endif +#include "os_includes.h" +#include "pnet_config.h" +#include "phost_types.h" + + +#ifdef P_HAVE_SOCKLEN_T + typedef socklen_t P_socklen_t; +#else + typedef int P_socklen_t; +#endif + +/* UNIX */ +#if defined(UNIX) + +/* get netdb.h to declare addrinfo on glibc */ +#ifndef __USE_POSIX +# define __USE_POSIX +#endif + +# define P_net_socket int +# define P_NET_INVALID_SOCKET -1 +# define GET_LAST_ERROR() (errno) + + typedef struct ifreq IFREQ; +# include +# include + +# if defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1) + typedef uint32_t in_addr_t; +# endif +#endif +/* UNIX */ + + +/* WIN32 */ +#if defined(WIN32) + +# define P_net_socket SOCKET +# define P_NET_INVALID_SOCKET -1 + +# include + +# if !(defined(__MINGW32__) || defined(__CYGWIN__)) + typedef SSIZE_T ssize_t; +# endif + +# define GET_LAST_ERROR() WSAGetLastError() +# define EWOULDBLOCK WSAEWOULDBLOCK + + typedef unsigned long in_addr_t; + typedef INTERFACE_INFO IFREQ; +#endif +/* WIN32 */ + +#ifndef P_HAVE_IOCTLSOCKET +# define P_ioctl_socket ioctl +#else +# define P_ioctl_socket ioctlsocket +#endif + +/* os_net_inprogress: an expression to check for "in progress" after a call (so it's not returned as an error) */ +#if defined(UNIX) +# define P_net_inprogress ((errno == EINPROGRESS) || (errno == EAGAIN)) +#elif defined(WIN32) +# define P_net_inprogress ((WSAGetLastError() == WSAEINPROGRESS) || (WSAGetLastError() == WSAEWOULDBLOCK)) +#else +# error einprogress not ported +#endif + + +/* === P_poll() start === */ +#ifdef P_NET_POLL + +/* use native poll */ +#define P_POLLIN POLLIN +#define P_POLLPRI POLLPRI +#define P_POLLOUT POLLOUT +#define P_POLLERR POLLERR +#define P_POLLHUP POLLHUP +#define P_POLLNVAL POLLNVAL + +#define P_poll poll +#define P_pollfd pollfd + +#else +/* define our own struct and constants */ +struct P_pollfd { + int fd; + short events; + short revents; +}; + +#define P_POLLIN 0x001 +#define P_POLLPRI 0x002 +#define P_POLLOUT 0x004 +#define P_POLLERR 0x008 +#define P_POLLHUP 0x010 +#define P_POLLNVAL 0x020 + +typedef unsigned long int nfds_t; + +# ifdef P_NET_SELECT +# define P_poll P_poll_select +int P_poll_select(struct P_pollfd *fds, nfds_t nfds, int timeout); +# else +# define P_poll P_poll_busyloop +int P_poll_busyloop(struct P_pollfd *fds, nfds_t nfds, int timeout); +# endif +#endif +/* === P_poll() end === */ + +#ifdef P_HAVE_SHUT +# define P_SHUT_RD SHUT_RD +# define P_SHUT_WR SHUT_WR +# define P_SHUT_RDWR SHUT_RDWR +#else +# ifdef P_HAVE_SD +# define P_SHUT_RD 0 +# define P_SHUT_WR 1 +# define P_SHUT_RDWR 2 +# else +# define P_SHUT_RD SD_RECEIVE +# define P_SHUT_WR SD_SEND +# define P_SHUT_RDWR SD_BOTH +# endif +#endif + +#ifdef WIN32 +P_net_socket P_socket(int af, int protocol, int type); +#else +#define P_socket socket +#endif + +/* sub-second time queries; precision depends on system but is guaranteed + to be at least in the milliseconds range */ + +/* 32 bit unsigned should be sufficient until around 2106 */ +typedef P_uint32_t P_time_t; + +/* return current time in double */ +double P_dtime(void); + +/* return current time in secs/usecs; usecs may be NULL, in which case + only secs is filled in. WARNING: granularity depends on system; it + is wise not to expect anything better than milisecond resolution. */ +void P_ltime(P_time_t *secs, P_time_t *usecs); + +/* sleep for some microseconds; actual sleep may be longer (because + of granularity and system overhead) and system calls (and signals) + may interrupt the sleep. Maximum value for usecs is 1000000. + Use this for short, inprecise timing. */ +void P_usleep(long int usecs); + +/* same as P_usleep, plus + - it takes a double argument in seconds (actual resolution won't be better tho) + - it can sleep slightly longer as well + - but it will never sleep less than specified + - there's no upper limit for secs + Use this for longer, guaranteed sleeps; has considerably higher + overhead than P_usleep(). +*/ +void P_dsleep(double secs); + +#ifndef P_NETWORK_H +#define P_NETWORK_H + +/* address type for IPv4 IP addresses */ +typedef P_uint32_t P_ipv4_addr_t; + +/* Must be called before any other network related call; returns 0 on success */ +int P_net_init(void); + +/* Must be called at the end of the program; on some system this is required to + shut down open connections. */ +int P_net_uninit(void); + + + +typedef enum P_net_err { + P_net_err_dns = -1, + P_net_err_socket = -2, + P_net_err_reuse = -3, + P_net_err_nonblock = -4, + P_net_err_bind = -5, + P_net_err_listen = -6, + P_net_err_connect = -7, + P_net_err_broadcast = -8, + P_net_err_accept = -9, + P_net_err_alloc = -10 +} P_net_err_t ; + +typedef enum P_net_nonblock_e { + P_net_nonblock_connect = 1, /* switch to non-blocking for connect */ + P_net_nonblock_socket = 2, /* switch to non-blocking after connect */ + P_net_nonblock_full = 3, /* do everything in non-blocking */ + P_net_nonblock_quit_on_error = 4 /* quit if can't be set to nonblock */ +} P_net_nonblock_t; + +typedef enum P_net_broadcast { + P_net_broadcast_socket = 1, /* switch the socket to broadcast */ + P_net_broadcast_quit_on_error = 2 /* quit if can't be set to broadcast */ +} P_net_broadcast_t; + +int P_net_close(P_net_socket s); + +/* use the following two calls exclusively for reading and writing sockets */ +P_size_t P_net_read(P_net_socket s, void *buf, P_size_t count); +P_size_t P_net_write(P_net_socket s, void *buf, P_size_t count); +extern int P_net_printf_minbuff, P_net_printf_maxbuff; /* buffer size control (writable); irrelevant on systems supporting vdprintf() */ +P_size_t P_net_printf(P_net_socket s, const char *format, ...); + +/* set socket properties */ +int P_net_set_nonblocking(int sock); +int P_net_set_blocking(int sock); +int P_net_enable_broadcast(int sock); + +/* shutdown() compatibility */ +#define P_net_shutdown(s, how) shutdown(s, how) + +#endif /* P_NETWORK_H */ +#ifndef P_NET_TCP4_H +#define P_NET_TCP4_H + + +int P_tcp4_listen(P_net_socket *sock, const char *loc_hostname, int loc_port, P_net_nonblock_t non_blocking, int backlog); +int P_tcp4_connect(P_net_socket *sock, const char *rem_hostname, int rem_port, const char *loc_hostname, int loc_port, P_net_nonblock_t non_blocking); + +int P_tcp4_accept(P_net_socket *new_socket, P_net_socket listen_sock, P_ipv4_addr_t *rem_ip, char **rem_host, int *rem_port, P_net_nonblock_t non_blocking); + +#endif /* P_NET_TCP4_H */ +#ifndef P_NET_DNS4_H +#define P_NET_DNS4_H + + +/* Resolve hostname to IP; returns 0 on success. */ +int P_dns4_name_to_IP(P_ipv4_addr_t *ip, const char *hostname); + +/* Resolve IP to hostname; returns 0 on success. */ +int P_dns4_IP_to_name(char **hostname, P_ipv4_addr_t *ip); + +/* Returns host's hostname */ +char *P_dns4_get_my_name(void); + +/* Returns host's IP address */ +P_ipv4_addr_t P_dns4_get_my_IP(void); + +/* Returns non-zero if name is a valid IP address */ +int P_dns4_is_addr(const char *name); + + +/* Convert ipv4 address to string; string must be long enough (>=16 characers) + Return 0 on success. */ +int P_dns4_IP_to_addr(P_ipv4_addr_t *ip_in, char *addr_out); + +/* Convert ipv4 string to address + Return 0 on success. */ +int P_dns4_addr_to_IP(P_ipv4_addr_t *ip_out, const char *addr_in); + +#endif /* P_NET_DNS4_H */ +/* register a callback for P_net_uninit() */ +void P_net_uninit_reg(void (*cb)()); + + +/* interanls */ + +typedef struct P_net_uninit_s P_net_uninit_t; + +struct P_net_uninit_s { + void (*cb)(void); + P_net_uninit_t *next; +}; + +extern P_net_uninit_t *P_net_uninits; + + +/* call all pending uninit callbacks and free resources */ +void P_net_uninit_chain(void); + Index: tags/2.3.0/src_3rd/libporty_net/os_includes.h.in =================================================================== --- tags/2.3.0/src_3rd/libporty_net/os_includes.h.in (nonexistent) +++ tags/2.3.0/src_3rd/libporty_net/os_includes.h.in (revision 33253) @@ -0,0 +1,3 @@ +###uniq \n libs/socket/poll/includes libs/socket/select/includes libs/socket/closesocket/includes libs/socket/socketpair/includes libs/socket/ioctl/includes libs/socket/ioctl/fionbio/includes libs/socket/sockaddr_in/includes libs/socket/lac/includes libs/socket/recvsend/includes libs/socket/readwrite/includes libs/socket/shutdown/includes libs/socket/SHUT/includes libs/socket/getnameinfo/includes libs/socket/gethostname/includes libs/socket/socklent/includes### + +#define P_AF_LOCAL ###libs/socket/socketpair/af_local### Index: tags/2.3.0/src_3rd/libporty_net/phost_types.h.in =================================================================== --- tags/2.3.0/src_3rd/libporty_net/phost_types.h.in (nonexistent) +++ tags/2.3.0/src_3rd/libporty_net/phost_types.h.in (revision 33253) @@ -0,0 +1,37 @@ +#ifndef P_TYPES_H +#define P_TYPES_H +/* Unsigned and signed integer types per width; do not support 64 bits as there + are platforms not offering any way to have 64 bit integers. */ +###if libs/types/stdint/presents### +#include +###endif### +###uniq \n sys/types/size_t/includes sys/types/off_t/includes sys/types/ptrdiff_t/includes### + + +typedef ###sys/types/size/1_u_int### P_uint8_t; +typedef ###sys/types/size/2_u_int### P_uint16_t; +typedef ###sys/types/size/4_u_int### P_uint32_t; + +typedef ###sys/types/size/1_s_int### P_int8_t; +typedef ###sys/types/size/2_s_int### P_int16_t; +typedef ###sys/types/size/4_s_int### P_int32_t; + +###if sys/types/off_t/broken == false### +typedef off_t P_off_t; +###else### +typedef P_uint###sys/ptrwidth###_t P_off_t; +###endif### + +###if sys/types/ptrdiff_t/broken == false### +typedef off_t P_ptrdiff_t; +###else### +typedef P_int###sys/ptrwidth###_t P_ptrdiff_t; +###endif### + +###if sys/types/size_t/broken == false### +typedef size_t P_size_t; +###else### +typedef P_off_t P_size_t; +###endif### + +#endif Index: tags/2.3.0/src_3rd/libporty_net/pnet_config.h.in =================================================================== --- tags/2.3.0/src_3rd/libporty_net/pnet_config.h.in (nonexistent) +++ tags/2.3.0/src_3rd/libporty_net/pnet_config.h.in (revision 33253) @@ -0,0 +1,213 @@ +/* === temporary: for -DUNIX, -DWIN32, etc. - long term we won't depend on this */ +#define ###sys/class### 1 + +/* === P_poll() backend */ +###if libs/socket/poll/presents### +#define P_NET_POLL 1 +/*#define P_NET_SELECT 1*/ +###else### +###if libs/socket/select/presents### +/*#define P_NET_POLL 1 */ +#define P_NET_SELECT 1 +###endif### +###endif### + +/* === socket pair for local net */ +###if libs/socket/socketpair/presents### +#define P_HAVE_SOCKETPAIR +###else### +/*#define P_HAVE_SOCKETPAIR */ +###endif### + +/* === socklen_t */ +###if libs/socket/socklen_t/presents### +#define P_HAVE_SOCKLEN_T +###else### +/*#define P_HAVE_SOCKLEN_T */ +###endif### + + + +/* === precision time query and sleep */ +###if libs/time/usleep/presents### +/* we have usleep, we won't need select() or Sleep() for subsecond sleeping */ +#define P_HAVE_USLEEP +/*#define P_HAVE_WSLEEP*/ +#define P_TIME_INCLUDES_UNISTD +###else### +###if libs/time/Sleep/presents### +/* we do not have usleep, but we have Sleep - must be windows... */ +/* #define P_HAVE_USLEEP */ +#define P_HAVE_WSLEEP +#define P_TIME_INCLUDES_WSLEEP 1 +###else### +/* we do not have usleep or Sleep, we need select() to emulate it*/ +/* #define P_HAVE_USLEEP */ +/* #define P_HAVE_WSLEEP */ +###if libs/socket/select/presents### +/* we may (ab)use select if usleep is missing, even if we do P_NET_POLL for + networking */ +#define P_HAVE_SELECT 1 +#define P_TIME_INCLUDES_SELECT 1 +###else### +#error can not find any way to do subsecond sleep; tried usleep(), Sleep() and select(), but this system does not have any of these. +###endif### +###endif### +###endif### + + +/* subsecond time query */###if libs/time/gettimeofday/presents### +#define P_HAVE_GETTIMEOFDAY 1 +/* #define P_HAVE_FTIME 1 */ +###else### +###if libs/time/ftime/presents### +/* #define P_HAVE_GETTIMEOFDAY 1 */ +#define P_HAVE_FTIME 1 +###else### +#error neither gettimeofday() nor ftime() found on your system. +###endif### +###endif### + +/* === socket related properties */ +/* if we have closesocket, we need to use that over close() */ +###if libs/socket/closesocket/presents### +#define P_NET_CLOSESOCKET 1 +###else### +/*#define P_NET_CLOSESOCKET 1*/ +###endif### + +/* if we have ioctlsocket, we need to use that over ioctl() on sockets */ +###if libs/socket/ioctlsocket/presents### +#define P_HAVE_IOCTLSOCKET 1 +###else### +/*#define P_HAVE_IOCTLSOCKET 1*/ +###endif### + +/* do we have the easy way for P_printf? */ +###if libs/vdprintf### +#define P_HAVE_VDPRINTF +###else### +/*#define P_HAVE_VDPRINTF*/ +###endif### + +/* vsnprintf is an alternative */ +###if libs/vsnprintf### +#define P_HAVE_VSNPRINTF +###else### +/*#define P_HAVE_VSNPRINTF*/ +###endif### + +###if libs/snprintf### +#define P_HAVE_SNPRINTF +###else### +/*#define P_HAVE_SNPRINTF*/ +###endif### + +###if libs/snprintf_safe### +#define P_HAVE_SNPRINTF_SAFE +###else### +/*#define P_HAVE_SNPRINTF_SAFE*/ +###endif### + +/* are SHUT_* constants available? */ +###if libs/socket/SHUT/presents### +#define P_HAVE_SHUT +###else### +/*#define P_HAVE_SHUT*/ +###endif### + +/* are SD_* constants available? */ +###if libs/socket/SD/presents### +#define P_HAVE_SD +###else### +/*#define P_HAVE_SD*/ +###endif### + + +###if local/net/use_porty_resolver### +#define P_USE_PORTY_RESOLVER +###else### +/*#define P_USE_PORTY_RESOLVER*/ +###endif### + +/* === hardware specific settings */ +/* Byte order */ +#define P_HOST_###sys/byte_order### 1 + +/* === stdio properties */ +###if sys/class ~ WIN### +/* on windows we assume stdio blocks */ +#define P_NET_STDIO_BLOCKS 1 +###else### +/*#define P_NET_STDIO_BLOCKS 1*/ +###endif### + +/* === compiler settings */ +###if cc/inline### +#define P_inline inline +###else### +#define P_inline +###endif### + +###if cc/_exit/presents### +#define P_HAVE__EXIT 1 +###else### +/*#define P_HAVE__EXIT 1*/ +###endif### + +###if singal/names/SIGINT/terminates### +#define P_SIGINT_TERMINATES 1 +###else### +/*#define P_SIGINT_TERMINATES 1*/ +###endif### + + +/* === file system */ +###if libs/fs/readdir/presents### +#define P_HAVE_READDIR +###else### +/*#define P_HAVE_READDIR*/ +###endif### + +###if libs/fs/findnextfile/presents### +#define P_HAVE_FINDNEXTFILE +###else### +/*#define P_HAVE_FINDNEXTFILE*/ +###endif### + +/* === shell */ +#define P_SHELL "###sys/shell###" +###if sys/shell_needs_quote### +#define P_SHELL_QUOTE "\"" +###else### +#define P_SHELL_QUOTE "" +###endif### + +/* === bgtask */ +###if libs/lpthread @### +/* #define P_HAVE_PTHREAD */ +###else### +#define P_HAVE_PTHREAD +###endif### + + +/* === math_wrap */ +/* log() */ +###if libs/math/cc/log/m_0/errno == 0### +#define P_MBROKEN_LOG_M_0 +###else### +/* #define P_MBROKEN_LOG_M_0 */ +###endif### + +###if libs/math/cc/log/p_0/errno == 0### +#define P_MBROKEN_LOG_P_0 +###else### +/* #define P_MBROKEN_LOG_P_0 */ +###endif### + +###if libs/math/cc/log/p_1/errno == 0### +#define P_MBROKEN_LOG_P_1 +###else### +/* #define P_MBROKEN_LOG_P_1 */ +###endif### + Index: tags/2.3.0/src_3rd/libuhpgl/Makefile =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/Makefile (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/Makefile (revision 33253) @@ -0,0 +1,4 @@ +CFLAGS = -Wall -g -ansi -pedantic + +parse.o: parse.c uhpgl_math.h libuhpgl.h arc_iterate.h + Index: tags/2.3.0/src_3rd/libuhpgl/README =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/README (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/README (revision 33253) @@ -0,0 +1,15 @@ +The micro HP-GL library +~~~~~~~~~~~~~~~~~~~~~~~ + +Libuhpgl is a small, portable (C89) library for parsing and generating +HP-GL data. It is designed for use as a converter in an application that +has its own 2d object model. + +To accomodate to the object model of the application, the lib offers different +options for the drawing primitives, e.g. the application may chose whether to +support filled polygons or vurves (arcs, circles). The lib loads a sequence +of HP-GL instructions, builds a complex object (such as a polygon) in memory +and passes it to the application when all details of the object is already +known. + + Index: tags/2.3.0/src_3rd/libuhpgl/arc_iterate.h =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/arc_iterate.h (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/arc_iterate.h (revision 33253) @@ -0,0 +1,125 @@ +/* + libuhpgl - the micro HP-GL library + Copyright (C) 2017 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + + This library is part of pcb-rnd: http://repo.hu/projects/pcb-rnd +*/ + +/* Arc approximation loops for internal use - not intended to be + included by the library user */ + +#ifndef LIBUHPGL_ARC_ITERATE_H +#define LIBUHPGL_ARC_ITERATE_H + +/* Arc approximation loops */ + +typedef struct uhpgl_arc_it_s { + const uhpgl_arc_t *arc; + double step; /* stepping angle */ + double ang; + uhpgl_point_t pt; + int remain; +} uhpgl_arc_it_t; + +/* Do not call directly. Set up iterator for angle based steps. */ +static uhpgl_point_t *uhpgl_arc_it_first_ang(uhpgl_arc_it_t *it, const uhpgl_arc_t *arc, double step) +{ + double minstep = 360.0 / (arc->r*CONST_PI*2.0); + + if (step < 0) + step = -step; + else if (step == 0) + step = 5; + + if (step < minstep) + step = minstep; + + if (arc->deltaa < 0) + step = -step; + + it->arc = arc; + it->step = step; + it->remain = floor(arc->deltaa / step)+2; + + it->pt = arc->startp; + it->ang = arc->starta; + return &it->pt; +} + +/* Do not call directly. Set up iterator for radius error based steps. */ +static uhpgl_point_t *uhpgl_arc_it_first_err(uhpgl_arc_it_t *it, const uhpgl_arc_t *arc, double err) +{ + double step; + + if (err > arc->r / 4) + return uhpgl_arc_it_first_ang(it, arc, 0); + + step = RAD2DEG(acos((arc->r - err) / arc->r) * 2); + if (step < 0) + step = -step; + + if (step < 0.1) + step = 0.1; + else if (step > 15) + step = 15; + + return uhpgl_arc_it_first_ang(it, arc, step); +} + +/* Start an iteration, return the first point */ +static uhpgl_point_t *uhpgl_arc_it_first(uhpgl_ctx_t *ctx, uhpgl_arc_it_t *it, const uhpgl_arc_t *arc, double resolution) +{ + if (ctx->state.ct == 0) + return uhpgl_arc_it_first_ang(it, arc, resolution); + return uhpgl_arc_it_first_err(it, arc, resolution); +} + +/* Return the next point or NULL if there are no more points */ +static uhpgl_point_t *uhpgl_arc_it_next(uhpgl_arc_it_t *it) +{ + uhpgl_coord_t x, y; + it->remain--; + switch(it->remain) { + case 0: /* beyond the endpoint */ + return NULL; + case 1: /* at the endpoint */ + last_pt:; + /* special case: endpoint reached in the previous iterationm remaining correction path is 0 long */ + if ((it->pt.x == it->arc->endp.x) && (it->pt.y == it->arc->endp.y)) + return NULL; + it->pt = it->arc->endp; + return &it->pt; + default: + for(;;) { + it->ang += it->step; + x = ROUND((double)it->arc->center.x + it->arc->r * cos(DEG2RAD(it->ang))); + y = ROUND((double)it->arc->center.y + it->arc->r * sin(DEG2RAD(it->ang))); + if ((it->pt.x != x) || (it->pt.y != y)) { + it->pt.x = x; + it->pt.y = y; + return &it->pt; + } + it->remain--; + if (it->remain == 1) + goto last_pt; + } + } + return NULL; +} + +#endif Index: tags/2.3.0/src_3rd/libuhpgl/examples/Makefile =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/examples/Makefile (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/examples/Makefile (revision 33253) @@ -0,0 +1,7 @@ +CFLAGS = -I../.. +CFLAGS += -Wall -g -ansi -pedantic +LDFLAGS = -lm + +dump_hpgl: dump_hpgl.o ../parse.o + +dump_hpgl.o: dump_hpgl.c Index: tags/2.3.0/src_3rd/libuhpgl/examples/aa.hpgl =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/examples/aa.hpgl (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/examples/aa.hpgl (revision 33253) @@ -0,0 +1,10 @@ +IN; +SP1; +CT1; +PU; +PA5,0; +PD; +AA5,5,-180,0.1; +PA15,10; +AA15,5,-180,0.4; +PA5,0; Index: tags/2.3.0/src_3rd/libuhpgl/examples/circ.hpgl =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/examples/circ.hpgl (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/examples/circ.hpgl (revision 33253) @@ -0,0 +1,7 @@ +IN; + +SP1; + +PA50,50; +CI20,10; + Index: tags/2.3.0/src_3rd/libuhpgl/examples/dump_hpgl.c =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/examples/dump_hpgl.c (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/examples/dump_hpgl.c (revision 33253) @@ -0,0 +1,102 @@ +/* + libuhpgl - the micro HP-GL library + Copyright (C) 2017 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + + This library is part of pcb-rnd: http://repo.hu/projects/pcb-rnd +*/ + +#include +#include +#include +#include + + +static int dump_line(uhpgl_ctx_t *ctx, uhpgl_line_t *line) +{ + printf("line {%d}: %ld;%ld %ld;%ld\n", line->pen, line->p1.x, line->p1.y, line->p2.x, line->p2.y); + return 0; +} + +static void dump_arc_(uhpgl_ctx_t *ctx, uhpgl_arc_t *arc, const char *type) +{ + printf("%s {%d}: %ld;%ld;%ld %f->%f (%f) (%ld;%ld->%ld;%ld)\n", type, arc->pen, + arc->center.x, arc->center.y, arc->r, + arc->starta, arc->enda, arc->deltaa, + arc->startp.x, arc->startp.y, arc->endp.x, arc->endp.y); +} + +static int dump_arc(uhpgl_ctx_t *ctx, uhpgl_arc_t *arc) +{ + dump_arc_(ctx, arc, "arc"); + return 0; +} + + +static int dump_circ(uhpgl_ctx_t *ctx, uhpgl_arc_t *circ) +{ + printf("circ {%d}: %ld;%ld;%ld\n", circ->pen, + circ->center.x, circ->center.y, circ->r); + return 0; +} + +static int dump_poly(uhpgl_ctx_t *ctx, uhpgl_poly_t *poly) +{ +/*#warning TODO*/ + return 0; +} + +static int dump_wedge(uhpgl_ctx_t *ctx, uhpgl_wedge_t *wedge) +{ + dump_arc_(ctx, &wedge->arc, "wedge"); + return 0; +} + +static int dump_rect(uhpgl_ctx_t *ctx, uhpgl_rect_t *rect) +{ + printf("rect {%d}: %ld;%ld %ld;%ld\n", rect->pen, rect->p1.x, rect->p1.y, rect->p2.x, rect->p2.y); + return 0; +} + +static int print_error(uhpgl_ctx_t *ctx) +{ + fprintf(stderr, "Error on stdin:%d.%d: %s\n", ctx->error.line, ctx->error.col, ctx->error.msg); + return -1; +} + +int main() +{ + uhpgl_ctx_t ctx; + + memset(&ctx, 0, sizeof(ctx)); + + ctx.conf.line = dump_line; + ctx.conf.arc = dump_arc; + ctx.conf.circ = dump_circ; + ctx.conf.poly = dump_poly; + ctx.conf.wedge = dump_wedge; + ctx.conf.rect = dump_rect; + + if (uhpgl_parse_open(&ctx) != 0) + return print_error(&ctx); + if (uhpgl_parse_file(&ctx, stdin) != 0) + return print_error(&ctx); + if (uhpgl_parse_close(&ctx) != 0) + return print_error(&ctx); + return 0; +} + Index: tags/2.3.0/src_3rd/libuhpgl/examples/rect.hpgl =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/examples/rect.hpgl (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/examples/rect.hpgl (revision 33253) @@ -0,0 +1,13 @@ +IN; + +SP1; + +PA0,0; + +PD; +PA200,0; +PA200,200; +PA0,200; +PR0,-200; +PU; + Index: tags/2.3.0/src_3rd/libuhpgl/examples/rect_bound.hpgl =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/examples/rect_bound.hpgl (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/examples/rect_bound.hpgl (revision 33253) @@ -0,0 +1,13 @@ +IN; +IP0,0,4000,4000; +SC0,200,0,200; +SP1; +PA0,0; + +PD; +PA200,0; +PA200,200; +PA0,200; +PA0,0; +PU; + Index: tags/2.3.0/src_3rd/libuhpgl/examples/vararg.hpgl =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/examples/vararg.hpgl (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/examples/vararg.hpgl (revision 33253) @@ -0,0 +1,9 @@ +IN; +SP1; +PU; +PA10,10; +PD; +PD20,10,20,20,10,20,10,10; +PR2,2,-3,3; +PA5,5,3,7; +PU; Index: tags/2.3.0/src_3rd/libuhpgl/libuhpgl.h =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/libuhpgl.h (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/libuhpgl.h (revision 33253) @@ -0,0 +1,151 @@ +/* + libuhpgl - the micro HP-GL library + Copyright (C) 2017 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + + This library is part of pcb-rnd: http://repo.hu/projects/pcb-rnd +*/ + +#ifndef LIBUHPGL_H +#define LIBUHPGL_H + +#include + +/*** low level types ***/ +typedef long int uhpgl_coord_t; /* 1 unit is 0.025 mm */ +typedef double uhpgl_angle_t; /* in degrees; absolute angles are [0..360], relative angles are [-360..+360] */ + +typedef enum uhpgl_obj_type_s { + UHPGL_OBJ_INVALID, + UHPGL_OBJ_LINE, + UHPGL_OBJ_ARC, + UHPGL_OBJ_WEDGE, + UHPGL_OBJ_RECT, + UHPGL_OBJ_POLY +} uhpgl_obj_type_t; + +typedef enum uhpgl_fill_type_s { + UHPGL_FILL_NONE, + UHPGL_FILL_PAINT1, + UHPGL_FILL_PAINT2, + UHPGL_FILL_SINGLE, + UHPGL_FILL_CROSS +} uhpgl_fill_type_t; + +typedef struct uhpgl_fill_stroke_s { + uhpgl_fill_type_t type; /* UHPGL_FILL_NONE if no fill */ + uhpgl_coord_t spacing; + uhpgl_angle_t angle; + double pen_thick; + unsigned stroke:1; /* 1 if stroked */ +} uhpgl_fill_stroke_t; + +typedef struct uhpgl_point_s { + uhpgl_coord_t x, y; +} uhpgl_point_t; + +typedef struct uhpgl_obj_s uhpgl_obj_t; + +/*** drawing objects ***/ +typedef struct uhpgl_line_s { + int pen; + uhpgl_point_t p1, p2; +} uhpgl_line_t; + +typedef struct uhpgl_arc_s { + int pen; + uhpgl_point_t center; + uhpgl_coord_t r; + uhpgl_point_t startp, endp; + uhpgl_angle_t starta, enda, deltaa; +} uhpgl_arc_t; + +typedef struct uhpgl_wedge_s { + int pen; + uhpgl_arc_t arc; + uhpgl_fill_stroke_t fill_stroke; +} uhpgl_wedge_t; + +typedef struct uhpgl_rect_s { + int pen; + uhpgl_point_t p1, p2; /* p1 is the minimal x;y and p2 is the maximal x;y */ + uhpgl_fill_stroke_t fill_stroke; +} uhpgl_rect_t; + +typedef struct uhpgl_poly_s { + int pen; + uhpgl_point_t bb1, bb2; /* bounding box; bb1 is the minimal x;y and bb2 is the maximal x;y */ + uhpgl_obj_t *outline; /* outer contour (linked list of non-poly objects) */ + int num_holes; + uhpgl_obj_t **holes; /* inner/hole contours (each is a linked list of non-poly objects) */ + uhpgl_fill_stroke_t fill_stroke; +} uhpgl_poly_t; + +/*** common object and context ***/ +struct uhpgl_obj_s { + uhpgl_obj_type_t type; + union { + uhpgl_line_t line; + uhpgl_arc_t arc; + uhpgl_wedge_t wedge; + uhpgl_rect_t rect; + uhpgl_poly_t poly; + } obj; + uhpgl_obj_t *next; /* singly linked list of objects, NULL terminates the list */ +}; + +typedef struct uhpgl_ctx_s uhpgl_ctx_t; +struct uhpgl_ctx_s { + /* configuration: read-only for the lib, written by the caller */ + struct { + unsigned approx_curve_in_poly:1; /* if 1, use line approx in polygons even if arc() is non-NULL */ + + /* callbacks for objects found; if returns non-zero, parsing is abandoned */ + int (*line)(uhpgl_ctx_t *ctx, uhpgl_line_t *line); /* must NOT be NULL */ + int (*arc)(uhpgl_ctx_t *ctx, uhpgl_arc_t *arc); /* if NULL, use line() approx */ + int (*circ)(uhpgl_ctx_t *ctx, uhpgl_arc_t *circ); /* if NULL, use arc() */ + int (*poly)(uhpgl_ctx_t *ctx, uhpgl_poly_t *poly); /* if NULL, use draw the outline only (even for filled polygons) */ + int (*wedge)(uhpgl_ctx_t *ctx, uhpgl_wedge_t *wedge); /* if NULL, use polygon() */ + int (*rect)(uhpgl_ctx_t *ctx, uhpgl_rect_t *rect); /* if NULL, use polygon() */ + } conf; + + /* current state: read-only for the caller, written by the lib */ + struct { + int pen; /* selected pen [0..255] */ + int pen_speed; + unsigned pen_down:1; /* whether pen is down (drawing) */ + uhpgl_point_t at; /* last known coordinate of the pen */ + int ct; /* Chord Tolerance */ + uhpgl_fill_stroke_t fill; + + /* last char parsed */ + size_t offs; + size_t line, col; + } state; + + /* parser error report: written by the lib, read-only for the caller */ + struct { + size_t offs; + size_t line, col; + const char *msg; + } error; + + void *parser; /* opaque parser data */ + void *user_data; /* only used by the caller */ +}; + +#endif Index: tags/2.3.0/src_3rd/libuhpgl/parse.c =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/parse.c (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/parse.c (revision 33253) @@ -0,0 +1,503 @@ +/* + libuhpgl - the micro HP-GL library + Copyright (C) 2017 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + + This library is part of pcb-rnd: http://repo.hu/projects/pcb-rnd +*/ + +#include +#include +#include "uhpgl_math.h" +#include "libuhpgl.h" +#include "parse.h" +#include "arc_iterate.h" + +#define inst2num(s1, s2) ((((int)s1) << 8) | (int)s2) + +typedef enum state_e { + ST_IDLE, + ST_INST, + ST_INST_END, + ST_NUMBERS_OR_END, + ST_SPC_NUMBERS_OR_END, + ST_NUMBERS, + ST_ESCAPED +} state_t; + +typedef struct { + size_t token_offs; + size_t token_line, token_col; + char inst[2]; + char token[32]; + int len; /* token length */ + + double argv[32]; + int argc; + + state_t state; + unsigned error:1; + unsigned eof:1; +} parse_t; + +static int error(uhpgl_ctx_t *ctx, const char *msg) +{ + parse_t *p = ctx->parser; + + ctx->error.offs = p->token_offs; + ctx->error.line = p->token_line; + ctx->error.col = p->token_col; + ctx->error.msg = msg; + + p->error = 1; + return -1; +} + +static const char *err_beyond_end = "Character after EOF"; +static const char *err_not_open = "Parser is not open"; + +#define decl_parser_ctx \ + parse_t *p = ctx->parser; \ + if (p == NULL) {\ + ctx->error.msg = err_not_open; \ + return -1; \ + } \ + if (p->error) \ + return -1; \ + if (p->eof) \ + return error(ctx, err_beyond_end); + +int uhpgl_parse_str(uhpgl_ctx_t *ctx, const char *str) +{ + int ret; + decl_parser_ctx; + + for(;*str != '\0'; str++) { + ret = uhpgl_parse_char(ctx, *str); + if (ret != 0) + return ret; + } + return 0; +} + +int uhpgl_parse_file(uhpgl_ctx_t *ctx, FILE *f) +{ + int ret, c; + decl_parser_ctx; + + while((c = fgetc(f)) != EOF) { + ret = uhpgl_parse_char(ctx, c); + if (ret != 0) + return ret; + } + return 0; +} + +int uhpgl_parse_open(uhpgl_ctx_t *ctx) +{ + if (ctx->parser != NULL) { + ctx->error.msg = "Parser already open"; + return -1; + } + ctx->parser = calloc(sizeof(parse_t), 1); + ctx->state.offs = 0; + ctx->state.line = 1; + ctx->state.col = 1; + return 0; +} + +int uhpgl_parse_close(uhpgl_ctx_t *ctx) +{ + decl_parser_ctx; + if (p->state != ST_IDLE) { + error(ctx, "premature end of stream"); + free(p); + ctx->parser = NULL; + return -1; + } + + free(p); + ctx->parser = NULL; + return 0; +} + +/*** execute ***/ +static void move_to(uhpgl_ctx_t *ctx, uhpgl_coord_t x, uhpgl_coord_t y) +{ + ctx->state.at.x = x; + ctx->state.at.y = y; +} + +static int draw_line(uhpgl_ctx_t *ctx, uhpgl_coord_t x1, uhpgl_coord_t y1, uhpgl_coord_t x2, uhpgl_coord_t y2) +{ + uhpgl_line_t line; + line.pen = ctx->state.pen; + line.p1.x = x1; + line.p1.y = y1; + line.p2.x = x2; + line.p2.y = y2; + move_to(ctx, x2, y2); + return ctx->conf.line(ctx, &line); +} + +static int draw_arc_(uhpgl_ctx_t *ctx, uhpgl_arc_t *arc, double resolution) +{ + uhpgl_arc_it_t it; + int cnt; + uhpgl_point_t *p, prev; + + move_to(ctx, arc->endp.x, arc->endp.y); + if (ctx->conf.arc != NULL) + return ctx->conf.arc(ctx, arc); + + for(cnt = 0, p = uhpgl_arc_it_first(ctx, &it, arc, resolution); p != NULL; cnt++, p = uhpgl_arc_it_next(&it)) { + if (cnt > 0) { + if (draw_line(ctx, prev.x, prev.y, p->x, p->y) != 0) + return -1; + } + prev = *p; + } + + return 0; +} + +static int draw_arc(uhpgl_ctx_t *ctx, uhpgl_coord_t cx, uhpgl_coord_t cy, double da, double res) +{ + uhpgl_arc_t arc; + arc.pen = ctx->state.pen; + arc.center.x = cx; + arc.center.y = cy; + arc.startp.x = ctx->state.at.x; + arc.startp.y = ctx->state.at.y; + arc.r = ROUND(DDIST(arc.startp.y - arc.center.y, arc.startp.x - arc.center.x)); + arc.deltaa = da; + + arc.starta = RAD2DEG(atan2(arc.startp.y - arc.center.y, arc.startp.x - arc.center.x)); + arc.enda = arc.starta + da; + + arc.endp.x = ROUND((double)cx + arc.r * cos(DEG2RAD(arc.enda))); + arc.endp.y = ROUND((double)cy + arc.r * sin(DEG2RAD(arc.enda))); + + return draw_arc_(ctx, &arc, res); +} + + +static int draw_circ(uhpgl_ctx_t *ctx, uhpgl_coord_t cx, uhpgl_coord_t cy, uhpgl_coord_t r, uhpgl_coord_t res) +{ + uhpgl_arc_t arc; + arc.pen = ctx->state.pen; + arc.center.x = cx; + arc.center.y = cy; + arc.r = r; + arc.startp.x = cx + r; + arc.startp.y = cy; + arc.endp.x = cx + r; + arc.endp.y = cy; + arc.starta = 0; + arc.enda = 360; + arc.deltaa = 360; + if (ctx->conf.circ != NULL) { + move_to(ctx, arc.endp.x, arc.endp.y); + return ctx->conf.circ(ctx, &arc); + } + return draw_arc_(ctx, &arc, res); +} + + +/*** the actual parser: high level (grammar) ***/ +static int parse_inst(uhpgl_ctx_t *ctx) +{ + parse_t *p = ctx->parser; + p->inst[0] = p->token[0]; + p->inst[1] = p->token[1]; + switch(inst2num(p->inst[0], p->inst[1])) { + case inst2num('I','N'): + /* ignore */ + p->state = ST_INST_END; + return 0; + case inst2num('P','U'): + ctx->state.pen_down = 0; + p->state = ST_NUMBERS_OR_END; + return 0; + case inst2num('P','D'): + ctx->state.pen_down = 1; + p->state = ST_NUMBERS_OR_END; + return 0; + case inst2num('W','U'): + case inst2num('P','W'): + case inst2num('L','T'): + p->state = ST_NUMBERS_OR_END; + return 0; + + case inst2num('P','A'): + case inst2num('P','R'): + case inst2num('S','P'): + case inst2num('C','T'): + case inst2num('C','I'): + case inst2num('A','A'): + case inst2num('A','R'): + case inst2num('F','T'): + case inst2num('P','T'): +/* + case inst2num('L','T'): + case inst2num('W','G'): + case inst2num('E','W'): + case inst2num('R','A'): + case inst2num('E','A'): + case inst2num('R','R'): + case inst2num('E','R'): + case inst2num('P','M'): + case inst2num('E','P'): + case inst2num('F','P'): +*/ + /* prepare to read coords */ + p->state = ST_NUMBERS; + return 0; + case inst2num('V','S'): + p->state = ST_SPC_NUMBERS_OR_END; + return 0; + } + return error(ctx, "unimplemented instruction"); +} + +/* Consume all current arguments and report end or go on for the next set + of arguments; useful for vararg instructions like PA */ +#define shift_all() \ +do { \ + if (!is_last) {\ + p->argc = 0; \ + p->state = ST_NUMBERS; \ + } \ + else \ + p->state = ST_INST_END; \ +} while(0) + +static int parse_coord(uhpgl_ctx_t *ctx, double coord, int is_last) +{ + parse_t *p = ctx->parser; + p->argv[p->argc] = coord; + p->argc++; + switch(inst2num(p->inst[0], p->inst[1])) { + case inst2num('S','P'): + if ((coord < 0) || (coord > 255)) + return error(ctx, "invalid pen index"); + ctx->state.pen = coord; + p->state = ST_INST_END; + return 0; + case inst2num('C','T'): + ctx->state.ct = coord; + p->state = ST_INST_END; + return 0; + case inst2num('P','U'): + case inst2num('P','A'): + case inst2num('P','D'): + p->state = ST_NUMBERS; /* make sure to load even a single pair */ + if (p->argc == 2) { + if (ctx->state.pen_down) { + if (draw_line(ctx, ctx->state.at.x, ctx->state.at.y, p->argv[0], p->argv[1]) < 0) + return -1; + } + else + move_to(ctx, p->argv[0], p->argv[1]); + shift_all(); + } + return 0; + case inst2num('P','R'): + if (p->argc == 2) { + if (ctx->state.pen_down) { + if (draw_line(ctx, ctx->state.at.x, ctx->state.at.y, ctx->state.at.x + p->argv[0], ctx->state.at.y + p->argv[1]) < 0) + return -1; + } + else + move_to(ctx, ctx->state.at.x + p->argv[0], ctx->state.at.y + p->argv[1]); + shift_all(); + } + return 0; + case inst2num('C','I'): + if ((p->argc == 2) || (is_last)) { + p->state = ST_INST_END; + if (draw_circ(ctx, ctx->state.at.x, ctx->state.at.y, p->argv[0], (p->argc == 2 ? p->argv[1] : -1)) < 0) + return -1; + } + return 0; + case inst2num('A','A'): + if ((p->argc == 4) || (is_last)) { + p->state = ST_INST_END; + if (draw_arc(ctx, p->argv[0], p->argv[1], p->argv[2], (p->argc == 4 ? p->argv[3] : 0)) < 0) + return -1; + } + return 0; + case inst2num('A','R'): + if ((p->argc == 4) || (is_last)) { + p->state = ST_INST_END; + if (draw_arc(ctx, ctx->state.at.x + p->argv[0], ctx->state.at.y + p->argv[1], p->argv[2], (p->argc == 4 ? p->argv[3] : 0)) < 0) + return -1; + } + return 0; + case inst2num('F','T'): + if (is_last) { + switch(p->argc) { + case 3: ctx->state.fill.angle = p->argv[2]; + case 2: ctx->state.fill.spacing = p->argv[1]; + case 1: ctx->state.fill.type = p->argv[0]; break; + case 0: ctx->state.fill.type = 1; break; + default: + return error(ctx, "Wrong number of arguments (expected 0, 1, 2 or 3)"); + } + } + return 0; + case inst2num('P','T'): + if ((p->argc == 1) && (is_last)) { + ctx->state.fill.pen_thick = p->argv[0]; + return 0; + } + return error(ctx, "PT needs 1 argument"); + case inst2num('L','T'): + if (is_last) { + if ((p->argc <= 3) && (is_last)) + return 0; + return error(ctx, "LT needs at most 3 argument"); + } + return 0; + case inst2num('V','S'): + if (is_last) { + if ((p->argc == 1) || (p->argc == 2)) { + ctx->state.pen_speed = p->argv[0]; + p->state = ST_INST_END; + return 0; + } + printf("argc=%d\n", p->argc); + return error(ctx, "VS needs 1 or 2 arguments"); + } + return 0; + case inst2num('W','U'): /* unknown */ + if (is_last) { + if (p->argc == 1) + return 0; + return error(ctx, "WU needs 1 argument"); + } + return 0; + case inst2num('P','W'): /* unknown; maybe pen width? */ + if (is_last) { + if (p->argc == 2) + return 0; + return error(ctx, "PW needs 2 arguments"); + } + return 0; + } + return error(ctx, "unimplemented coord instruction"); +} + +/*** the actual parser: low level (tokens) ***/ +#define token_start() \ +do { \ + p->len = 0; \ + p->token_offs = ctx->state.offs; \ + p->token_line = ctx->state.line; \ + p->token_col = ctx->state.col-1; \ +} while(0) + +int uhpgl_parse_char(uhpgl_ctx_t *ctx, int c) +{ + int res; + decl_parser_ctx; + + ctx->state.col++; + switch(c) { + case EOF: + p->eof = 1; + return 0; + case '\n': + ctx->state.line++; + ctx->state.col = 1; + return 0; + case '\r': + case '\t': + return 0; + case ' ': + if ((p->state == ST_NUMBERS) || (p->state == ST_NUMBERS_OR_END)) + break; + return 0; + } + + switch(p->state) { + case ST_IDLE: + if (c == 0x1B) { /* starting at ESC, spans till the first ':' - ignore it */ + p->state = ST_ESCAPED; + return 0; + } + if (c == ';') /* be liberal: accept multiple terminators or empty instructions */ + return 0; + p->state = ST_INST; + p->argc = 0; + token_start(); + /* fall through to read the first char */ + case ST_INST: + if (!isalpha(c)) + return error(ctx, "Invalid character in instruction (must be alpha)"); + p->token[p->len] = toupper(c); + p->len++; + if (p->len == 2) { + p->len = 0; + return parse_inst(ctx); + } + return 0; + case ST_INST_END: + got_end:; + if (c != ';') + return error(ctx, "Expected semicolon to terminate instruction"); + p->state = ST_IDLE; + return 0; + case ST_SPC_NUMBERS_OR_END: + if (c == ' ') + return 0; + p->state = ST_NUMBERS; + /* fall thru: number */ + case ST_NUMBERS_OR_END: + if (c == ';') + goto got_end; + /* fall thru: number */ + case ST_NUMBERS: + if ((c == ',') || (c == ' ') || (c == ';')) { + char *end; + int last = (c == ';'); + p->token[p->len] = '\0'; + res = parse_coord(ctx, strtod(p->token, &end), last); + if (*end != '\0') + return error(ctx, "Invalid numeric format"); + token_start(); + if ((p->state == ST_INST_END) && (!last)) + return error(ctx, "Expected semicolon"); + else if ((p->state != ST_INST_END) && (last)) + return error(ctx, "Premature semicolon"); + else if ((p->state == ST_INST_END) && (last)) + p->state = ST_IDLE; /* wanted to finish and finished */ + return res; + } + if (isdigit(c) || (c == '.') || ((c == '-') && (p->len == 0))) { + p->token[p->len] = c; + p->len++; + return 0; + } + return error(ctx, "Expected digit or separator in number"); + case ST_ESCAPED: + if (c == ':') + p->state = ST_IDLE; + return 0; + } + return error(ctx, "Internal error: broken state machine"); +} Index: tags/2.3.0/src_3rd/libuhpgl/parse.h =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/parse.h (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/parse.h (revision 33253) @@ -0,0 +1,45 @@ +/* + libuhpgl - the micro HP-GL library + Copyright (C) 2017 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + + This library is part of pcb-rnd: http://repo.hu/projects/pcb-rnd +*/ + + +#ifndef LIBUHPGL_PRASE_H +#define LIBUHPGL_PRASE_H + +#include +#include "libuhpgl.h" + +/* Shall be called before parsing starts (call uhpgl_parse_open() at the end) */ +int uhpgl_parse_open(uhpgl_ctx_t *ctx); + +/* Parse next character of a stream; c may be EOF; returns 0 on success */ +int uhpgl_parse_char(uhpgl_ctx_t *ctx, int c); + +/* Parse next portion of a stream from a string; returns 0 on success */ +int uhpgl_parse_str(uhpgl_ctx_t *ctx, const char *str); + +/* Parse next portion of a stream from a file; returns 0 on success */ +int uhpgl_parse_file(uhpgl_ctx_t *ctx, FILE *f); + +/* Shall be called after the last portion parsed; returns 0 on success */ +int uhpgl_parse_close(uhpgl_ctx_t *ctx); + +#endif Index: tags/2.3.0/src_3rd/libuhpgl/uhpgl_math.h =================================================================== --- tags/2.3.0/src_3rd/libuhpgl/uhpgl_math.h (nonexistent) +++ tags/2.3.0/src_3rd/libuhpgl/uhpgl_math.h (revision 33253) @@ -0,0 +1,54 @@ +/* + libuhpgl - the micro HP-GL library + Copyright (C) 2017 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + + This library is part of pcb-rnd: http://repo.hu/projects/pcb-rnd +*/ + +/* Math helper for internal use - not intended to be included by the + library user */ + +#ifndef LIBUHPGL_MATH_H +#define LIBUHPGL_MATH_H + +#include + +#define CONST_PI 3.14159265358979323846 +#define RAD2DEG(r) ((r) * 180.0 / CONST_PI) +#define DEG2RAD(d) ((d) * CONST_PI / 180.0) +#define DDIST(dx, dy) sqrt((double)(dx)*(double)(dx) + (double)(dy)*(double)(dy)) + +/* Implementation idea borrowed from an old gcc */ +static double ROUND(double x) +{ + double t; + + 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; +} + +#endif Index: tags/2.3.0/src_3rd/libuirc/Makefile =================================================================== --- tags/2.3.0/src_3rd/libuirc/Makefile (nonexistent) +++ tags/2.3.0/src_3rd/libuirc/Makefile (revision 33253) @@ -0,0 +1,9 @@ +CFLAGS = -Wall -g -I.. -DLIBUIRC_TRACE +LDFLAGS = -lm +LIBS = ../libporty_net/libportytcp4.o ../genvector/gds_char.o ../../src/librnd/core/compat_misc.o + +main: main.o libuirc.o $(LIBS) + +main.o: main.c + +libuirc.o: libuirc.c libuirc.h Index: tags/2.3.0/src_3rd/libuirc/libuirc.c =================================================================== --- tags/2.3.0/src_3rd/libuirc/libuirc.c (nonexistent) +++ tags/2.3.0/src_3rd/libuirc/libuirc.c (revision 33253) @@ -0,0 +1,431 @@ +/* + libuirc - minimal IRC protocol + Copyright (C) 2020 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: libporty (at) igor2.repo.hu +*/ + + +#include "libuirc.h" +#include + +#include + +static int uirc_query_alloc(uirc_t *ctx) +{ + int n; + for(n = 0; n < UIRC_MAX_QUERIES; n++) + if (ctx->query[n].type == UIRC_UNUSED) + return n; + return -1; +} + +static int uirc_query_search(uirc_t *ctx, char *name) +{ + int n; + for(n = 0; n < UIRC_MAX_QUERIES; n++) { + if ((ctx->query[n].type != UIRC_CHAN) && (ctx->query[n].type != UIRC_PRIV)) + continue; + if (strcmp(name, ctx->query[n].name) == 0) + return n; + } + return -1; +} + + +int uirc_connect(uirc_t *ctx, const char *server, int port, char *user) +{ + P_net_init(); + if (P_tcp4_connect(&ctx->sk, server, port, NULL, 0, P_net_nonblock_full) != 0) + return -1; + ctx->connecting = 1; + ctx->alive = 1; + gds_init(&ctx->ibuf); + gds_init(&ctx->obuf); + gds_append_str(&ctx->obuf, "user libuirc a b :"); + gds_append_str(&ctx->obuf, user); + gds_append_str(&ctx->obuf, "\nnick "); + gds_append_str(&ctx->obuf, ctx->nick); + gds_append(&ctx->obuf, '\n'); + + ctx->query[0].type = UIRC_SERVER; + ctx->query[0].name = NULL; + + return 0; +} + +void uirc_disconnect(uirc_t *ctx) +{ + P_net_close(ctx->sk); + ctx->alive = 0; +} + + +static uirc_event_t uirc_parse_001(uirc_t *ctx, char *arg) +{ + if (ctx->on_connect != NULL) + ctx->on_connect(ctx); + return UIRC_CONNECT; +} + +#define irc_strcasecmp rnd_strcasecmp + +static uirc_event_t uirc_parse_join(uirc_t *ctx, char *nick, char *arg) +{ + int q; + + if (*arg == ':') arg++; + + q = uirc_query_search(ctx, arg); + if (irc_strcasecmp(nick, ctx->nick) == 0) { + uirc_event_t res = 0; + if (q < 0) { + q = uirc_query_alloc(ctx); + if (q < 0) { + gds_append_str(&ctx->obuf, "part "); + gds_append_str(&ctx->obuf, arg); + gds_append_str(&ctx->obuf, " :I am on too many channels already.\n"); + return 0; + } + ctx->query[q].type = UIRC_CHAN; + ctx->query[q].name = rnd_strdup(arg); + ctx->last_new_query = q; + res |= UIRC_QUERY_BEGIN; + } + + if (ctx->on_me_join != NULL) + ctx->on_me_join(ctx, q, arg); + return res | UIRC_ME_JOIN; + } + + if ((q >= 0) && (ctx->on_join != NULL)) { + ctx->on_join(ctx, nick, q, arg); + return UIRC_JOIN; + } + + return 0; +} + +#define payload(dst, src) \ +do { \ + dst = strpbrk(src, " \t"); \ + if (dst != NULL) { \ + *dst++ = '\0'; \ + if (*dst == ':') dst++; \ + } \ +} while(0) + +static uirc_event_t uirc_parse_part(uirc_t *ctx, char *nick, char *arg) +{ + char *reason; + int q; + + if (*arg == ':') arg++; + payload(reason, arg); + + q = uirc_query_search(ctx, arg); + if (q < 0) + return 0; + + if (irc_strcasecmp(nick, ctx->nick) == 0) { + if (ctx->on_me_part != NULL) + ctx->on_me_part(ctx, q, arg); + if (ctx->on_query_end != NULL) + ctx->on_query_end(ctx, q); + ctx->query[q].type = UIRC_UNUSED; + free(ctx->query[q].name); + ctx->query[q].name = NULL; + return UIRC_ME_PART | UIRC_QUERY_END; + } + + if (ctx->on_part != NULL) { + ctx->on_part(ctx, nick, q, arg, reason); + return UIRC_PART; + } + + return 0; +} + +static uirc_event_t uirc_parse_kick(uirc_t *ctx, char *nick, char *arg) +{ + char *victim, *reason; + int q; + uirc_event_t res = 0; + + payload(victim, arg); + payload(reason, victim); + + q = uirc_query_search(ctx, arg); + if (q < 0) + return 0; + + if (irc_strcasecmp(victim, ctx->nick) == 0) { + if (ctx->on_me_part != NULL) + ctx->on_me_part(ctx, q, arg); + if (ctx->on_query_end != NULL) + ctx->on_query_end(ctx, q); + ctx->query[q].type = UIRC_UNUSED; + free(ctx->query[q].name); + ctx->query[q].name = NULL; + res |= UIRC_ME_PART | UIRC_QUERY_END; + } + + if (ctx->on_kick != NULL) { + ctx->on_kick(ctx, nick, q, arg, victim, reason); + res |= UIRC_KICK; + } + + return res; +} + +static uirc_event_t uirc_parse_msg(uirc_t *ctx, char *nick, char *arg) +{ + char *text; + int q; + + if (*arg == ':') arg++; + payload(text, arg); + + q = uirc_query_search(ctx, arg); + + if (ctx->on_msg != NULL) { + ctx->on_msg(ctx, nick, q, arg, text); + return UIRC_MSG; + } + + return 0; +} + +static uirc_event_t uirc_parse_notice(uirc_t *ctx, char *nick, char *arg) +{ + char *text; + int q; + + if (*arg == ':') arg++; + payload(text, arg); + + q = uirc_query_search(ctx, arg); + + if (ctx->on_notice != NULL) { + ctx->on_notice(ctx, nick, q, arg, text); + return UIRC_NOTICE; + } + + return 0; +} + +static uirc_event_t uirc_parse_topic(uirc_t *ctx, char *nick, char *arg, int numeric) +{ + char *text; + int q; + + if (*arg == ':') arg++; + payload(text, arg); + + q = uirc_query_search(ctx, arg); + + if (ctx->on_topic != NULL) { + if (numeric) + nick = NULL; + ctx->on_topic(ctx, nick, q, arg, text); + return UIRC_TOPIC; + } + + return 0; +} + +static void uirc_new_nick(uirc_t *ctx) +{ + int len = strlen(ctx->nick); + if (len == 0) { + free(ctx->nick); + ctx->nick = rnd_strdup("libuirc"); + len = 7; + } + if (len < 9) { + char *nick = malloc(len+2); + memcpy(nick, ctx->nick, len); + nick[len] = (rand() % ('a'-'z')) + 'a'; + nick[len+1] = '\0'; + free(ctx->nick); + ctx->nick = nick; + } + else + ctx->nick[rand() % len] = (rand() % ('a'-'z')) + 'a'; + gds_append_str(&ctx->obuf, "nick "); + gds_append_str(&ctx->obuf, ctx->nick); + gds_append(&ctx->obuf, '\n'); +} + +static uirc_event_t uirc_parse(uirc_t *ctx, char *line) +{ + char *end, *arg, *cmd, *from = line; + uirc_event_t res = 0; + +#ifdef LIBUIRC_TRACE +printf("line='%s'\n", line); +#endif + + if (strncmp(line, "PING", 4) == 0) { + from[1] = 'O'; + uirc_raw(ctx, line); + return 0; + } + + cmd = strpbrk(line, " \t\r\n"); + if (cmd == NULL) + return 0; + *cmd = '\0'; + cmd++; + + if (strchr(from, '@') == 0) { + if (ctx->on_got_misc != NULL) + ctx->on_got_misc(ctx, 0, cmd); + res |= UIRC_GOT_MISC; + } + + end = strchr(from, '!'); + if (end != NULL) { + if (*from == ':') + from++; + *end = 0; + } + + arg = strpbrk(cmd, " \t\r\n"); + if (arg != NULL) { + *arg = '\0'; + arg++; + } + + end = strpbrk(arg, "\r\n"); + if (end != NULL) + *end = '\0'; + + if (strcmp(cmd, "001") == 0) return res | uirc_parse_001(ctx, arg); + if (irc_strcasecmp(cmd, "join") == 0) return res | uirc_parse_join(ctx, from, arg); + if (irc_strcasecmp(cmd, "part") == 0) return res | uirc_parse_part(ctx, from, arg); + if (irc_strcasecmp(cmd, "kick") == 0) return res | uirc_parse_kick(ctx, from, arg); + if (irc_strcasecmp(cmd, "privmsg") == 0) return res | uirc_parse_msg(ctx, from, arg); + if (irc_strcasecmp(cmd, "notice") == 0) return res | uirc_parse_notice(ctx, from, arg); + if (irc_strcasecmp(cmd, "topic") == 0) return res | uirc_parse_topic(ctx, from, arg, 0); + if (irc_strcasecmp(cmd, "332") == 0) return res | uirc_parse_topic(ctx, from, arg, 1); + if (irc_strcasecmp(cmd, "433") == 0) uirc_new_nick(ctx); + + return res; +} + +uirc_event_t uirc_poll(uirc_t *ctx) +{ + struct P_pollfd fds[1]; + int new_data = 0; + char *nl; + uirc_event_t res = 0; + + fds[0].fd = ctx->sk; + + for(;;) { + fds[0].events = P_POLLIN; + if (ctx->obuf.used > 0) + fds[0].events |= P_POLLOUT; + + if (P_poll(fds, 1, 0) < 1) + break; + + if (fds[0].revents & P_POLLIN) { + P_size_t len, oused = ctx->ibuf.used; + gds_enlarge(&ctx->ibuf, ctx->ibuf.used + 600); + ctx->ibuf.used = oused; + len = P_net_read(ctx->sk, ctx->ibuf.array + ctx->ibuf.used, 600); + if (len < 0) { + if (P_net_inprogress) + continue; + uirc_disconnect(ctx); + return res | UIRC_DISCONNECT; + } + if (len == 0) { + uirc_disconnect(ctx); + return res | UIRC_DISCONNECT; + } + if (len > 0) { + ctx->ibuf.used += len; + new_data = 1; + } + } + if ((fds[0].revents & P_POLLOUT) && (ctx->obuf.used > 0)) { + P_size_t len = P_net_write(ctx->sk, ctx->obuf.array, ctx->obuf.used); + ctx->connecting = 0; + if (len < 0) { + if (P_net_inprogress) + continue; + uirc_disconnect(ctx); + return res | UIRC_DISCONNECT; + } + if (len == 0) { + uirc_disconnect(ctx); + return res | UIRC_DISCONNECT; + } + if (len > 0) + gds_remove(&ctx->obuf, 0, len); + } + if (fds[0].revents & (~(P_POLLIN | P_POLLOUT))) { + uirc_disconnect(ctx); + return res | UIRC_DISCONNECT; + } + } + + /* call the protocol parse */ + if (!new_data) + return res; + + for(;;) { + nl = strchr(ctx->ibuf.array, '\n'); + if (nl == NULL) + break; + *nl = '\0'; + res |= uirc_parse(ctx, ctx->ibuf.array); + gds_remove(&ctx->ibuf, 0, nl - ctx->ibuf.array+1); + } + return res; +} + + +void uirc_join(uirc_t *ctx, const char *chan) +{ + +} + +void uirc_close(uirc_t *ctx, int query) +{ + +} + +void uirc_privmsg(uirc_t *ctx, const char *target, const char *msg) +{ + gds_append_str(&ctx->obuf, "PRIVMSG "); + gds_append_str(&ctx->obuf, target); + gds_append_str(&ctx->obuf, " :"); + gds_append_str(&ctx->obuf, (char *)msg); + gds_append(&ctx->obuf, '\n'); +} + +void uirc_raw(uirc_t *ctx, const char *msg) +{ + gds_append_str(&ctx->obuf, (char *)msg); + gds_append(&ctx->obuf, '\n'); +} + + Index: tags/2.3.0/src_3rd/libuirc/libuirc.h =================================================================== --- tags/2.3.0/src_3rd/libuirc/libuirc.h (nonexistent) +++ tags/2.3.0/src_3rd/libuirc/libuirc.h (revision 33253) @@ -0,0 +1,101 @@ +/* + libuirc - minimal IRC protocol + Copyright (C) 2020 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + Author: libporty (at) igor2.repo.hu +*/ + + +#include +#include + +#define UIRC_MAX_QUERIES 16 + +typedef enum { + UIRC_UNUSED = 0, + UIRC_SERVER, + UIRC_CHAN, + UIRC_PRIV +} uirc_query_type_t; + +typedef struct { + uirc_query_type_t type; + char *name; + +#if 0 + /* channel: */ + gds_t *nicks; /* , separated list of nicknames for a channel; first char is one of @, + or space */ + char *topic; +#endif +} uirc_query_t; + +typedef enum { /* bitfield */ + UIRC_CONNECT = 0x0001, + UIRC_DISCONNECT = 0x0002, + UIRC_TOPIC = 0x0004, + UIRC_GOT_MISC = 0x0008, + UIRC_QUERY_BEGIN = 0x0010, + UIRC_QUERY_END = 0x0020, + UIRC_ME_QUIT = 0x0040, + UIRC_ME_JOIN = 0x0080, + UIRC_JOIN = 0x0100, + UIRC_ME_PART = 0x0200, + UIRC_PART = 0x0400, + UIRC_MSG = 0x0800, + UIRC_NOTICE = 0x1000, + UIRC_KICK = 0x2000 +} uirc_event_t; + +typedef struct uirc_s uirc_t; +struct uirc_s { + char *nick; + uirc_query_t query[UIRC_MAX_QUERIES]; /* query 0 is special: server "window" */ + int curr_query, last_new_query; + + void *user_data; + void (*on_connect)(uirc_t *ctx); + void (*on_disconnect)(uirc_t *ctx); + void (*on_got_misc)(uirc_t *ctx, int query_to, const char *msg); + void (*on_query_begin)(uirc_t *ctx, int query_to); + void (*on_query_end)(uirc_t *ctx, int query_to); /* called on leaving the channel for any reason */ + void (*on_me_quit)(uirc_t *ctx); + void (*on_me_join)(uirc_t *ctx, int query, char *chan); + void (*on_join)(uirc_t *ctx, char *nick, int query, char *chan); + void (*on_me_part)(uirc_t *ctx, int query, char *chan); + void (*on_part)(uirc_t *ctx, char *nick, int query, char *chan, char *reason); + void (*on_kick)(uirc_t *ctx, char *nick, int query, char *chan, char *victim, char *reason); + void (*on_msg)(uirc_t *ctx, char *from, int query, char *to, char *text); + void (*on_notice)(uirc_t *ctx, char *from, int query, char *to, char *text); + void (*on_topic)(uirc_t *ctx, char *from, int query, char *to, char *text); + + /* internal */ + P_net_socket sk; + gds_t ibuf, obuf; + int dummy[2]; + unsigned connecting:1; + unsigned alive:1; +}; + +int uirc_connect(uirc_t *ctx, const char *server, int port, char *user); +void uirc_disconnect(uirc_t *ctx); +uirc_event_t uirc_poll(uirc_t *ctx); + +void uirc_join(uirc_t *ctx, const char *chan); +void uirc_close(uirc_t *ctx, int query); +void uirc_privmsg(uirc_t *ctx, const char *target, const char *msg); +void uirc_raw(uirc_t *ctx, const char *msg); + Index: tags/2.3.0/src_3rd/libuirc/main.c =================================================================== --- tags/2.3.0/src_3rd/libuirc/main.c (nonexistent) +++ tags/2.3.0/src_3rd/libuirc/main.c (revision 33253) @@ -0,0 +1,87 @@ +#include +#include +#include +#include "libuirc.h" + +static void on_me_part(uirc_t *ctx, int query, char *chan) +{ + printf("### left channel %s\n", chan); +} + +static void on_msg(uirc_t *ctx, char *from, int query, char *to, char *text) +{ + printf("(msg:%s) <%s> %s\n", to, from, text); +} + +static void on_notice(uirc_t *ctx, char *from, int query, char *to, char *text) +{ + printf("(msg:%s) -%s- %s\n", to, from, text); +} + + +static void on_topic(uirc_t *ctx, char *from, int query, char *to, char *text) +{ + printf("(by:%s) [%s] topic=%s\n", from, to, text); +} + +static void on_kick(uirc_t *ctx, char *nick, int query, char *chan, char *victim, char *reason) +{ + printf("(kick: %s kick %s from %s reason=%s\n", nick, victim, chan, reason); +} + + +static void read_stdin(uirc_t *ctx) +{ + struct P_pollfd fds[1]; + + fds[0].fd = 0; + fds[0].events = P_POLLIN; + + if (P_poll(fds, 1, 0) == 1) { + char line[600]; + fgets(line, sizeof(line), stdin); + if (*line == '/') { + uirc_raw(ctx, line+1); + } + else { + if (ctx->query[ctx->curr_query].name != NULL) + uirc_privmsg(ctx, ctx->query[ctx->curr_query].name, line); + } + } +} + +int main() +{ + uirc_t irc; + + memset(&irc, 0, sizeof(irc)); + irc.on_me_part = on_me_part; + irc.on_msg = on_msg; + irc.on_notice = on_notice; + irc.on_topic = on_topic; + irc.on_kick = on_kick; + + irc.nick = strdup("libuirc"); + if (uirc_connect(&irc, "10.0.0.2", 6667, "libuirc test client") != 0) { + printf("Failed to connect.\n"); + return 1; + } + + for(;irc.alive;) { + uirc_event_t ev = uirc_poll(&irc); + if (ev & UIRC_CONNECT) { + printf("joining\n"); + uirc_raw(&irc, "join :#dev"); + } + if (ev & UIRC_QUERY_BEGIN) { + irc.curr_query = irc.last_new_query; + printf("### begin query with %s\n", irc.query[irc.curr_query].name); + } + + read_stdin(&irc); + usleep(100); + } + + return 0; +} + Index: tags/2.3.0/src_3rd/qparse/Makefile =================================================================== --- tags/2.3.0/src_3rd/qparse/Makefile (nonexistent) +++ tags/2.3.0/src_3rd/qparse/Makefile (revision 33253) @@ -0,0 +1,14 @@ +#CFLAGS = -Wall -Wextra -g +CFLAGS = -g + +all: example_dynamic example_static + +example_dynamic: example_dynamic.o qparse.o + +example_static: example_static.o qparse.o + +qparse.o: qparse.c qparse.h + $(CC) $(CFLAGS) -c qparse.c -o qparse.o + +clean: + rm qparse.o example example.o ; true Index: tags/2.3.0/src_3rd/qparse/example_dynamic.c =================================================================== --- tags/2.3.0/src_3rd/qparse/example_dynamic.c (nonexistent) +++ tags/2.3.0/src_3rd/qparse/example_dynamic.c (revision 33253) @@ -0,0 +1,29 @@ +#include +#include +#include "qparse.h" + +/* Read lines of text from stdin and split them in fields using qparse. + Uses dynamic allocations. */ + +int main() +{ + char s[1024]; + while(fgets(s, sizeof(s), stdin) != NULL) { + int n, argc; + char *end, **argv; + size_t cons = 424242; + + /* remove trailing newline (if we don't we just get an extra empty field at the end) */ + for(end = s + strlen(s) - 1; (end >= s) && ((*end == '\r') || (*end == '\n')); end--) + *end = '\0'; + + /* split and print fields */ + printf("Splitting '%s':\n", s); + argc = qparse3(s, &argv, QPARSE_DOUBLE_QUOTE | QPARSE_SINGLE_QUOTE | QPARSE_TERM_SEMICOLON | QPARSE_SEP_COMMA | QPARSE_COLON_LAST, &cons); + for(n = 0; n < argc; n++) + printf(" [%d] '%s'\n", n, argv[n]); + qparse_free(argc, &argv); + printf("consumed: %ld bytes\n", cons); + } + return 0; +} Index: tags/2.3.0/src_3rd/qparse/example_static.c =================================================================== --- tags/2.3.0/src_3rd/qparse/example_static.c (nonexistent) +++ tags/2.3.0/src_3rd/qparse/example_static.c (revision 33253) @@ -0,0 +1,45 @@ +#include +#include +#include "qparse.h" + +/* Read lines of text from stdin and split them in fields using qparse. + Uses static argv[] and buffer */ + +#define SYNTAX QPARSE_DOUBLE_QUOTE | QPARSE_SINGLE_QUOTE | QPARSE_TERM_SEMICOLON | QPARSE_SEP_COMMA | QPARSE_COLON_LAST | QPARSE_NO_ARGV_REALLOC + +int main() +{ + char s[1024]; + const char *start[3] = {0}; + char *tmp, *argv_static[8] = {0}, **argv = argv_static; + unsigned int argv_alloced = 8; + size_t tmp_len; + + tmp_len = sizeof(s)+8; + tmp = malloc(tmp_len); + + while(fgets(s, sizeof(s), stdin) != NULL) { + int n, argc; + char *end; + + size_t cons = 424242; + + /* remove trailing newline (if we don't we just get an extra empty field at the end) */ + for(end = s + strlen(s) - 1; (end >= s) && ((*end == '\r') || (*end == '\n')); end--) + *end = '\0'; + + /* split and print fields */ + printf("Splitting '%s':\n", s); + argc = qparse4(s, &argv, &argv_alloced, SYNTAX, &cons, &tmp, &tmp_len, start, 3); + for(n = 0; n < argc; n++) + printf(" [%d] '%s'\n", n, argv[n]); + qparse_free_strs(argc, &argv); + printf("consumed: %ld bytes, starts at", cons); + for(n = 0; (n < argc) && (n < 3); n++) + printf(" '%s'", start[n]); + printf("\n"); + } + qparse4_free(&argv, &argv_alloced, SYNTAX, &tmp, &tmp_len); + + return 0; +} Index: tags/2.3.0/src_3rd/qparse/qparse.c =================================================================== --- tags/2.3.0/src_3rd/qparse/qparse.c (nonexistent) +++ tags/2.3.0/src_3rd/qparse/qparse.c (revision 33253) @@ -0,0 +1,314 @@ +/* + libgpmi - General Package/Module Interface - qparse package + Copyright (C) 2006-2007, 2017 Tibor 'Igor2' Palinkas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include +#include +#include +#include "qparse.h" + +typedef enum qp_state_e { + qp_normal, + qp_dquote, + qp_squote, + qp_paren, + qp_lastarg +} qp_state_t; + +#define qpush(chr) \ + { \ + if ((buff_used == 0) && (start != NULL) && (argc < start_len)) \ + start[argc] = s; \ + if (buff_used >= buff_len) { \ + buff_len += 128; \ + buff = realloc(buff, buff_len); \ + } \ + buff[buff_used] = chr; \ + buff_used++; \ + } + +#define qbackslash(chr) \ + switch(chr) { \ + case 'n': qpush('\n'); break; \ + case 'r': qpush('\r'); break; \ + case 't': qpush('\t'); break; \ + case 'b': qpush('\b'); break; \ + case '"': qpush('"'); break; \ + case '\'': qpush('\''); break; \ + case ' ': qpush(' '); break; \ + case '\0': break; \ + default: \ + qpush('\\'); \ + qpush(chr); \ + } + +#define qnext() \ + do { \ + int ran_out = 0; \ + if (argc >= *argv_allocated) { \ + if (!(flg & QPARSE_NO_ARGV_REALLOC)) { \ + *argv_allocated += 8; \ + argv = realloc(argv, sizeof(char *) * (*argv_allocated)); \ + } \ + else \ + ran_out = 1; \ + } \ + if (!ran_out) { \ + buff[buff_used] = '\0'; \ + argv[argc] = qparse_strdup(buff); \ + argc++; \ + *buff = '\0'; \ + buff_used = 0; \ + } \ + } while(0) + +int qparse4(const char *input, char **argv_ret[], unsigned int *argv_allocated, flags_t flg, size_t *consumed_out, char **buffer, size_t *buffer_alloced, const char **start, int start_len) +{ + int argc, allocated_; + qp_state_t state; + const char *s; + char *buff; + size_t buff_len, buff_used; + char **argv; + int num_fparens = 0; + + if (argv_allocated == NULL) { + argv = NULL; + allocated_ = 0; + argv_allocated = &allocated_; + } + else + argv = *argv_ret; + + argc = 0; + state = qp_normal; + + if (buffer == NULL) { + buff_len = 128; + buff = malloc(buff_len); + } + else { + buff_len = *buffer_alloced; + buff = *buffer; + } + buff_used = 0; + + for(s = input; *s != '\0'; s++) { + switch (state) { + case qp_lastarg: + switch (*s) { + case '\n': + case '\r': + if (flg & QPARSE_TERM_NEWLINE) + goto stop; + default: + qpush(*s); + } + break; + case qp_normal: + switch (*s) { + case '"': + if (flg & QPARSE_DOUBLE_QUOTE) + state = qp_dquote; + else + qpush(*s); + break; + case '\'': + if (flg & QPARSE_SINGLE_QUOTE) + state = qp_squote; + else + qpush(*s); + break; + case ')': + if ((flg & QPARSE_PAREN_FUNC) && (num_fparens == 1)) + goto stop; + qpush(*s); /* plain ')', don't care */ + break; + case '(': + if ((flg & QPARSE_PAREN_FUNC) && (num_fparens == 0)) { + num_fparens++; + qnext(); + break; + } + if (flg & QPARSE_PAREN) + state = qp_paren; + else + qpush(*s); + break; + + case '\\': + s++; + qbackslash(*s); + break; + + case ';': + if (flg & QPARSE_TERM_SEMICOLON) + goto stop; + qpush(*s); /* plain ';', don't care */ + break; + + case '\n': + case '\r': + if (flg & QPARSE_TERM_NEWLINE) + goto stop; + case ',': + if (!(flg & QPARSE_SEP_COMMA)) { + qpush(*s); /* plain ',', don't care */ + break; + } + case ' ': + case '\t': + if (flg & QPARSE_MULTISEP) + while(isspace(s[1])) s++; + qnext(); + break; + default: + if ((flg & QPARSE_COLON_LAST) && (buff_used == 0) && *s == ':') { + state = qp_lastarg; + break; + } + qpush(*s); + } + /* End of qp_normal */ + break; + + case qp_dquote: + switch (*s) { + case '\\': + s++; + qbackslash(*s); + break; + case '"': + state = qp_normal; + break; + default: + qpush(*s); + } + /* End of qp_dquote */ + break; + + case qp_squote: + switch (*s) { + case '\\': + s++; + qbackslash(*s); + break; + case '\'': + state = qp_normal; + break; + default: + qpush(*s); + } + /* End of qp_dquote */ + break; + + case qp_paren: + switch (*s) { + case '\\': + s++; + qbackslash(*s); + break; + case ')': + state = qp_normal; + break; + default: + qpush(*s); + } + /* End of qp_paren */ + break; + } + } + + stop:; + + qnext(); + + if (buffer == NULL) { + if (buff != NULL) + free(buff); + } + else { + *buffer = buff; + *buffer_alloced = buff_len; + } + + if (consumed_out != NULL) + *consumed_out = s-input; + *argv_ret = argv; + return argc; +} + +int qparse3(const char *input, char **argv_ret[], flags_t flg, size_t *consumed_out) +{ + return qparse4(input, argv_ret, 0, flg, consumed_out, NULL, NULL, NULL, 0); +} + + +int qparse2(const char *input, char **argv_ret[], flags_t flg) +{ + return qparse4(input, argv_ret, 0, flg, NULL, NULL, NULL, NULL, 0); +} + +int qparse(const char *input, char **argv_ret[]) +{ + return qparse4(input, argv_ret, 0, QPARSE_DOUBLE_QUOTE, NULL, NULL, NULL, NULL, 0); +} + + +void qparse_free_strs(int argc, char **argv_ret[]) +{ + int n; + for (n = 0; n < argc; n++) { + free((*argv_ret)[n]); + (*argv_ret)[n] = NULL; + } +} + +void qparse_free(int argc, char **argv_ret[]) +{ + qparse_free_strs(argc, argv_ret); + + free(*argv_ret); + *argv_ret = NULL; +} + +void qparse4_free(char **argv_ret[], unsigned int *argv_allocated, flags_t flg, char **buffer, size_t *buffer_alloced) +{ + qparse_free_strs(*argv_allocated, argv_ret); + + if (!(flg & QPARSE_NO_ARGV_REALLOC)) { + free(*argv_ret); + *argv_ret = NULL; + *argv_allocated = 0; + } + + if (*buffer != NULL) { + free(*buffer); + *buffer_alloced = 0; + } +} + + +char *qparse_strdup(const char *s) +{ + int l = strlen(s); + char *o; + o = malloc(l+1); + memcpy(o, s, l+1); + return o; +} Index: tags/2.3.0/src_3rd/qparse/qparse.h =================================================================== --- tags/2.3.0/src_3rd/qparse/qparse.h (nonexistent) +++ tags/2.3.0/src_3rd/qparse/qparse.h (revision 33253) @@ -0,0 +1,47 @@ +#include + +/* Split input into a list of strings in argv_ret[] using whitepsace as field + separator. It supports double quoted fields and backslash as escape character. + Returns the number of arguments. argv_ret should be free'd using + qparse_free(). */ +int qparse(const char *input, char **argv_ret[]); + +/* Free an argv_ret array allocated by qparse. */ +void qparse_free(int argc, char **argv_ret[]); + +/* for C89 - that doesn't have strdup()*/ +char *qparse_strdup(const char *s); + +/* More advanced API with more control over the format */ +typedef enum { + QPARSE_DOUBLE_QUOTE = 1, + QPARSE_SINGLE_QUOTE = 2, + QPARSE_PAREN = 4, + QPARSE_MULTISEP = 8, /* multiple separators are taken as a single separator */ + QPARSE_TERM_NEWLINE = 16, /* terminate parsing at newline */ + QPARSE_TERM_SEMICOLON = 32, /* terminate parsing at semicolon */ + QPARSE_SEP_COMMA = 64, /* comma is a separator, like whitespace */ + QPARSE_COLON_LAST = 128, /* if an argument starts with a colon, it's the last argument until the end of the message or line (IRC) */ + QPARSE_PAREN_FUNC = 256, /* func(...) where func will be argv[0] */ + + QPARSE_NO_ARGV_REALLOC = 512 /* in qparse4: do not realloc() argv_ret (caller uses a static variant); if argc == *allocated, extra arguments are concatenated */ +} flags_t; + +int qparse2(const char *input, char **argv_ret[], flags_t flg); + +/* This variant returns the number of characters consumed from the input + so it can be used for multi-command parsing */ +int qparse3(const char *input, char **argv_ret[], flags_t flg, size_t *consumed_out); + +/* This variant keeps track of argv_ret[] size in user supplied 'argv_allocated' so + it can be persistent across calls, can save mallocs and frees. If buffer + and buffer_alloced are not NULL, temporary field buffer is persistent + across calls. If start is not NULL, the start of the first start_len + words are saved there. + Call qparse_free_strs() after the call to get rid of the strings (this + won't free argv[] itself). After the last parse, call qparse4_free() to + free everything */ +int qparse4(const char *input, char **argv_ret[], unsigned int *argv_allocated, flags_t flg, size_t *consumed_out, char **buffer, size_t *buffer_alloced, const char **start, int start_len); +void qparse_free_strs(int argc, char **argv_ret[]); +void qparse4_free(char **argv_ret[], unsigned int *argv_allocated, flags_t flg, char **buffer, size_t *buffer_alloced); + Index: tags/2.3.0/src_3rd =================================================================== --- tags/2.3.0/src_3rd (nonexistent) +++ tags/2.3.0/src_3rd (revision 33253) Property changes on: tags/2.3.0/src_3rd ___________________________________________________________________ Added: svn:externals ## -0,0 +1,16 ## +genht -r90 svn://svn.repo.hu/genht/trunk/src +genlist -r113 svn://svn.repo.hu/genlist/trunk/genlist +genvector -r180 svn://svn.repo.hu/genvector/trunk/genvector +liblihata -r1255 svn://svn.repo.hu/lihata/trunk/src/liblihata +liblhtpers -r1255 svn://svn.repo.hu/lihata/trunk/src/liblhtpers +genregex -r98 svn://svn.repo.hu/genregex/trunk/src +sphash -r62 svn://svn.repo.hu/sphash/trunk +gensexpr -r65 svn://svn.repo.hu/gensexpr/trunk/gensexpr +puplug -r272 svn://svn.repo.hu/puplug/trunk/puplug +libminuid -r31 svn://svn.repo.hu/libminuid/trunk/libminuid +libuundo -r77 svn://svn.repo.hu/libuundo/trunk/libuundo +genrtree -r97 svn://svn.repo.hu/genrtree/trunk/genrtree +libfungw -r599 svn://svn.repo.hu/fungw/trunk/libfungw +fast89-poly2tri -r36 svn://svn.repo.hu/fast89-poly2tri/trunk/src +libulzw -r22 svn://svn.repo.hu/libulzw/trunk/libulzw +librnd -r32454 svn://svn.repo.hu/librnd/trunk/src/librnd Index: tags/2.3.0/src_plugins/Buildin.tmpasm =================================================================== --- tags/2.3.0/src_plugins/Buildin.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/Buildin.tmpasm (revision 33253) @@ -0,0 +1,43 @@ +# tmpasm script for compiling a plugin_src/ module as a buildin +# Requires variables before the include: +# /local/pcb/mod basename of the module (e.g. autoplace) +# /local/pcb/mod/OBJS full path of all object files +# /local/pcb/mod/OBJS_C99 full path of all object files for non-c89 +# /local/pcb/mod/CONF config file name + +append /local/pcb/buildin_init_extern [@extern pcb_uninit_t hid_@/local/pcb/mod@_init();@] {\n} + + +append /local/pcb/buildin_init_code [@ + uninit_func = hid_@/local/pcb/mod@_init(); + pcb_plugin_register("@/local/pcb/mod@", "<@/local/pcb/mod@>", NULL, 0, uninit_func); +@] {\n} + +append /local/pcb/OBJS ?/local/pcb/mod/OBJS +append /local/pcb/OBJS_C99 ?/local/pcb/mod/OBJS_C99 +append /local/pcb/LDFLAGS /local/pcb/mod/LDFLAGS +append /local/pcb/CFLAGS /local/pcb/mod/CFLAGS +append /local/pcb/RULES [@ + +mod_@/local/pcb/mod@: all + +@] + +# if plugin is part of the hidlib system, also append the objects +# to the hidlib object lists +put /local/pcb/mod/is_hidlib [@/local/pcb/@/local/pcb/mod@/hidlib@] +resolve /local/pcb/mod/is_hidlib ?/local/pcb/mod/is_hidlib +if ?/local/pcb/mod/is_hidlib +then + append /local/pcb/HIDLIB_PLG /local/pcb/mod + append /local/pcb/OBJS_HIDLIB_PLG ?/local/pcb/mod/OBJS + append /local/pcb/OBJS_C99_HIDLIB_PLG ?/local/pcb/mod/OBJS_C99 + append /local/pcb/buildin_hidlib_pups [@@/local/pcb/mod@=@/local/pcb/mod@/@/local/pcb/mod@.pup@] {\n} + + append /local/pcb/LDFLAGS_HIDLIB_STATIC /local/pcb/mod/LDFLAGS + append /local/pcb/CFLAGS_HIDLIB_STATIC /local/pcb/mod/CFLAGS +else + append /local/pcb/buildin_pups [@@/local/pcb/mod@=@/local/pcb/mod@/@/local/pcb/mod@.pup@] {\n} +end + +include /local/pcb/tmpasm/common_enabled Index: tags/2.3.0/src_plugins/Common_enabled.tmpasm =================================================================== --- tags/2.3.0/src_plugins/Common_enabled.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/Common_enabled.tmpasm (revision 33253) @@ -0,0 +1,147 @@ +# explicit rules: .y -> .c (bison) +# 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/pcb/mod/YACC + case {^$} end + default + foreach /local/n in /local/pcb/mod/YACC + put /local/bn /local/n + sub {/local/bn} {^.*/} {} + put /local/dn /local/n + sub {/local/dn} {/[^/]*$} {} + + if /local/pcb/want_parsgen + then + append /local/pcb/RULES [@ +# yacc for @/local/pcb/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/pcb/RULES [@ +# dummy yacc for @/local/pcb/mod@ +@/local/n@.c @/local/n@.h: + echo "skipping yacc..." +@] + end + end + end +end + +# explicit rules: .l -> .c (flex) +# 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/pcb/mod/LEX + case {^$} end + default + foreach /local/n in /local/pcb/mod/LEX + if /local/pcb/want_parsgen + then + put /local/bn /local/n + sub {/local/bn} {^.*/} {} + put /local/dn /local/n + sub {/local/dn} {/[^/]*$} {} + + append /local/pcb/RULES [@ +# lex for @/local/pcb/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/pcb/RULES [@ +# dummy lex for @/local/pcb/mod@ +@/local/n@.c: + echo "skipping flex..." +@] + end + end + end +end + + + +# explicit rules: .y -> .c (byaccic) +switch /local/pcb/mod/BYACCIC + case {^$} end + default + foreach /local/n in /local/pcb/mod/BYACCIC + put /local/bn /local/n + sub {/local/bn} {^.*/} {} + put /local/dn /local/n + sub {/local/dn} {/[^/]*$} {} + + if /local/pcb/want_parsgen_byaccic + then + append /local/pcb/RULES [@ +# byaccic for @/local/pcb/mod@ +@/local/n@.c @/local/n@.h: @/local/n@.y + cd @/local/dn@ && byaccic -o @/local/bn@.c -H @/local/bn@.h -v @/local/bn@.desc @/local/bn@.y +@] + else + append /local/pcb/RULES [@ +# dummy byaccic for @/local/pcb/mod@ +@/local/n@.c @/local/n@.h: + echo "skipping byaccic..." +@] + end + end + end +end + +# explicit rules: .l -> .c (ureglex) +switch /local/pcb/mod/UREGLEX + case {^$} end + default + foreach /local/n in /local/pcb/mod/UREGLEX + if /local/pcb/want_parsgen_byaccic + then + put /local/bn /local/n + sub {/local/bn} {^.*/} {} + put /local/dn /local/n + sub {/local/dn} {/[^/]*$} {} + + append /local/pcb/RULES [@ +# lex for @/local/pcb/mod@ +@/local/n@.c @/local/n@.h: @/local/n@.ul + cd @/local/dn@ && ureglex -c @/local/bn@.c -h @/local/bn@.h -l @/local/bn@.ul +@] + else + append /local/pcb/RULES [@ +# dummy ureglex for @/local/pcb/mod@ +@/local/n@.c: + echo "skipping ureglex..." +@] + end + end + end +end + + +put /local/pcb/mod/enabled {1} + +include /local/pcb/tmpasm/plugin_conf +include /local/pcb/tmpasm/plugin_sphash +include /local/pcb/tmpasm/plugin_intconf +include /local/pcb/tmpasm/plugin_intmenu + +append /local/pcb/CLEANFILES ?/local/pcb/mod/CLEANFILES +append /local/pcb/DISTCLEANFILES ?/local/pcb/mod/DISTCLEANFILES + +put /local/pcb/mod/enabled {} +put /local/pcb/mod/OBJS {} +put /local/pcb/mod/OBJS_C99 {} +put /local/pcb/mod/LDFLAGS {} +put /local/pcb/mod/CFLAGS {} +put /local/pcb/mod/YACC {} +put /local/pcb/mod/LEX {} +put /local/pcb/mod/BYACCIC {} +put /local/pcb/mod/UREGLEX {} +put /local/pcb/mod/SPHASH {} +put /local/pcb/mod/SPHASH_ARGS {} +put /local/pcb/mod/CLEANFILES {} +put /local/pcb/mod/DISTCLEANFILES {} +put /local/pcb/mod {} +put /local/pcb/mod/CONFFILE {} +put /local/pcb/mod/CONFVAR {} +put /local/pcb/mod/MENUFILE {} +put /local/pcb/mod/MENUVAR {} Index: tags/2.3.0/src_plugins/Disable.tmpasm =================================================================== --- tags/2.3.0/src_plugins/Disable.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/Disable.tmpasm (revision 33253) @@ -0,0 +1,24 @@ +# tmpasm script for disable a plugin_src/ module +# Requires variables before the include: +# /local/pcb/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/pcb/mod/OBJS +append /local/pcb/DEPSRCS ?/local/pcb/mod/OBJS_C99 + +put /local/pcb/mod/enabled {0} + +include /local/pcb/tmpasm/plugin_conf +include /local/pcb/tmpasm/plugin_sphash +include /local/pcb/tmpasm/plugin_intconf + +put /local/pcb/mod/enabled {} +put /local/pcb/mod/OBJS {} +put /local/pcb/mod/OBJS_C99 {} +put /local/pcb/mod/CONF {} +put /local/pcb/mod/LDFLAGS {} +put /local/pcb/mod/CFLAGS {} +put /local/pcb/mod {} +put /local/pcb/mod/CONFFILE {} +put /local/pcb/mod/CONFVAR {} Index: tags/2.3.0/src_plugins/Plugin.tmpasm =================================================================== --- tags/2.3.0/src_plugins/Plugin.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/Plugin.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +# temporary solution for dispathcing compilation of hidlib plugins and +# local plugins for the transition, while we are still compiling librnd +# locally. Will be removed once pcb-rnd depends on librnd as external dep. + +put /local/pcb/mod/is_hidlib [@/local/pcb/@/local/pcb/mod@/hidlib@] +resolve /local/pcb/mod/is_hidlib ?/local/pcb/mod/is_hidlib +if ?/local/pcb/mod/is_hidlib +then + include /local/pcb/tmpasm/plugin_librnd; +else + include /local/pcb/tmpasm/plugin_local; +end Index: tags/2.3.0/src_plugins/Plugin_librnd.tmpasm =================================================================== --- tags/2.3.0/src_plugins/Plugin_librnd.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/Plugin_librnd.tmpasm (revision 33253) @@ -0,0 +1,48 @@ +# tmpasm script for compiling a plugin_src/ module as a plugin +# Requires variables before the include: +# /local/pcb/mod basename of the module (e.g. autoplace) +# /local/pcb/mod/OBJS full path of all object files +# /local/pcb/mod/OBJS_C99 full path of all object files for non-c89 + +# clean up input vars +uniq /local/pcb/mod/OBJS +uniq /local/pcb/mod/OBJS_C99 +uniq /local/pcb/mod/CFLAGS +uniq /local/pcb/mod/LDFLAGS +uniq /local/pcb/mod/LIBS + +# generate .c -> .o rules in /local/comp/output +put /local/comp/OBJS ?/local/pcb/mod/OBJS +put /local/comp/OBJS_C99 ?/local/pcb/mod/OBJS_C99 +put /local/comp/CFLAGS /local/pcb/mod/CFLAGS +include {../src_3rd/librnd/scconfig/template/comp_var.tmpasm} + +append /local/pcb/all [@ $(PLUGIDIR)/@/local/pcb/mod@.so @] + +append /local/pcb/rules/install_ [@ + $(SCCBOX) $(HOW) "$(LIBRND_PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so" "$(LIBDIR)/plugins/@/local/pcb/mod@.so" + $(SCCBOX) $(HOW) "$(LIBRND_PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.pup" "$(LIBDIR)/plugins/@/local/pcb/mod@.pup"@] + +append /local/pcb/CLEANFILES [@ $(LIBRND_PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so $(PLUGIDIR)/@/local/pcb/mod@.so @/local/pcb/mod/OBJS@ @/local/pcb/mod/OBJS_C99@ @] + +append /local/pcb/RULES [@ + +### Module @/local/pcb/mod@: plugin ### + +$(LIBRND_PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so: @/local/pcb/mod/OBJS@ @/local/pcb/mod/OBJS_C99@ + $(CC) -shared @cc/rdynamic@ -o $(LIBRND_PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so @/local/pcb/mod/OBJS@ @/local/pcb/mod/OBJS_C99@ $(LDFLAGS) @/local/pcb/mod/LDFLAGS@ + +mod_@/local/pcb/mod@: $(PLUGIDIR)/@/local/pcb/mod@.so + +$(PLUGIDIR)/@/local/pcb/mod@.so: $(LIBRND_PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so + $(MKDIR) $(PLUGIDIR) + $(CP) $(LIBRND_PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so $(PLUGIDIR)/@/local/pcb/mod@.so + $(CP) $(LIBRND_PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.pup $(PLUGIDIR)/@/local/pcb/mod@.pup + +# module .c -> .o rules +@/local/comp/output@ + +### Module @/local/pcb/mod@ end ### +@] + +include /local/pcb/tmpasm/common_enabled Index: tags/2.3.0/src_plugins/Plugin_local.tmpasm =================================================================== --- tags/2.3.0/src_plugins/Plugin_local.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/Plugin_local.tmpasm (revision 33253) @@ -0,0 +1,48 @@ +# tmpasm script for compiling a plugin_src/ module as a plugin +# Requires variables before the include: +# /local/pcb/mod basename of the module (e.g. autoplace) +# /local/pcb/mod/OBJS full path of all object files +# /local/pcb/mod/OBJS_C99 full path of all object files for non-c89 + +# clean up input vars +uniq /local/pcb/mod/OBJS +uniq /local/pcb/mod/OBJS_C99 +uniq /local/pcb/mod/CFLAGS +uniq /local/pcb/mod/LDFLAGS +uniq /local/pcb/mod/LIBS + +# generate .c -> .o rules in /local/comp/output +put /local/comp/OBJS ?/local/pcb/mod/OBJS +put /local/comp/OBJS_C99 ?/local/pcb/mod/OBJS_C99 +put /local/comp/CFLAGS /local/pcb/mod/CFLAGS +include {../src_3rd/librnd/scconfig/template/comp_var.tmpasm} + +append /local/pcb/all [@ $(PLUGIDIR)/@/local/pcb/mod@.so @] + +append /local/pcb/rules/install_ [@ + $(SCCBOX) $(HOW) "$(PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so" "$(LIBDIR)/plugins/@/local/pcb/mod@.so" + $(SCCBOX) $(HOW) "$(PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.pup" "$(LIBDIR)/plugins/@/local/pcb/mod@.pup"@] + +append /local/pcb/CLEANFILES [@ $(PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so $(PLUGIDIR)/@/local/pcb/mod@.so @/local/pcb/mod/OBJS@ @/local/pcb/mod/OBJS_C99@ @] + +append /local/pcb/RULES [@ + +### Module @/local/pcb/mod@: plugin ### + +$(PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so: @/local/pcb/mod/OBJS@ @/local/pcb/mod/OBJS_C99@ + $(CC) -shared @cc/rdynamic@ -o $(PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so @/local/pcb/mod/OBJS@ @/local/pcb/mod/OBJS_C99@ $(LDFLAGS) @/local/pcb/mod/LDFLAGS@ + +mod_@/local/pcb/mod@: $(PLUGIDIR)/@/local/pcb/mod@.so + +$(PLUGIDIR)/@/local/pcb/mod@.so: $(PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so + $(MKDIR) $(PLUGIDIR) + $(CP) $(PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.so $(PLUGIDIR)/@/local/pcb/mod@.so + $(CP) $(PLUGDIR)/@/local/pcb/mod@/@/local/pcb/mod@.pup $(PLUGIDIR)/@/local/pcb/mod@.pup + +# module .c -> .o rules +@/local/comp/output@ + +### Module @/local/pcb/mod@ end ### +@] + +include /local/pcb/tmpasm/common_enabled Index: tags/2.3.0/src_plugins/README =================================================================== --- tags/2.3.0/src_plugins/README (nonexistent) +++ tags/2.3.0/src_plugins/README (revision 33253) @@ -0,0 +1,13 @@ +This directory hosts core plugins. They are feature, IO, lib and hid plugins. + +Each subdirectory is a standalone plugin that can be selected to be a +(static linked) buildin, a (dynamic linked) plugin or disabled +(not compiled at all). The selection is made in ./configure. + +HID plugins are user interfaces; IO plugins convert the current design to +an alien format or imports from those formats; feature plugins create +actions or otherwise add functionality to the system independent of which +HID is running. Lib plugins provide common code for other plugins to use. + +Some of the plugins depend on ../src_3rd and all of them depend on +core (../src). There are also internal plugin-plugin dependencies. Index: tags/2.3.0/src_plugins/acompnet/Makefile =================================================================== --- tags/2.3.0/src_plugins/acompnet/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/acompnet/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_acompnet + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/acompnet/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/acompnet/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/acompnet/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {acompnet} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/acompnet/acompnet.o + $(PLUGDIR)/acompnet/meshgraph.o +@] + +switch /local/pcb/acompnet/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/acompnet/acompnet.c =================================================================== --- tags/2.3.0/src_plugins/acompnet/acompnet.c (nonexistent) +++ tags/2.3.0/src_plugins/acompnet/acompnet.c (revision 33253) @@ -0,0 +1,239 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "board.h" +#include "data.h" +#include "layer.h" +#include "layer_ui.h" +/*#include "acompnet_conf.h"*/ +#include +#include +#include "search.h" +#include "polygon.h" +#include +#include "conf_core.h" +#include +#include +#include "meshgraph.h" + +static pcb_layer_t *ly; + +typedef struct { + rnd_coord_t x, y; + rnd_coord_t r; +} overlap_t; + +static rnd_r_dir_t overlap(const rnd_box_t *box, void *closure) +{ + pcb_any_obj_t *obj = (pcb_any_obj_t *)box; + overlap_t *ovl = (overlap_t *)closure; + switch(obj->type) { + case PCB_OBJ_LINE: + if (pcb_is_point_in_line(ovl->x, ovl->y, ovl->r, (pcb_any_line_t *)obj)) + return RND_R_DIR_CANCEL; + break; + case PCB_OBJ_ARC: + if (pcb_is_point_on_arc(ovl->x, ovl->y, ovl->r, (pcb_arc_t *)obj)) + return RND_R_DIR_CANCEL; + break; + case PCB_OBJ_TEXT: + if (pcb_is_point_in_box(ovl->x, ovl->y, &obj->bbox_naked, ovl->r)) + return RND_R_DIR_CANCEL; + break; + case PCB_OBJ_POLY: + if (pcb_poly_is_point_in_p(ovl->x, ovl->y, ovl->r, (pcb_poly_t *)obj)) + return RND_R_DIR_CANCEL; + break; + default: break; + } + return RND_R_DIR_NOT_FOUND; +} + +TODO("move this to search.[ch]") +/* Search for object(s) on a specific layer */ +static rnd_r_dir_t pcb_search_on_layer(pcb_layer_t *layer, const rnd_box_t *bbox, rnd_r_dir_t (*cb)(const rnd_box_t *box, void *closure), void *closure) +{ + rnd_r_dir_t res, fin = 0; + + if ((res = rnd_r_search(layer->line_tree, bbox, NULL, cb, closure, NULL)) == RND_R_DIR_CANCEL) + return res; + fin |= res; + + if ((res = rnd_r_search(layer->arc_tree, bbox, NULL, cb, closure, NULL)) == RND_R_DIR_CANCEL) + return res; + fin |= res; + + if ((res = rnd_r_search(layer->polygon_tree, bbox, NULL, cb, closure, NULL)) == RND_R_DIR_CANCEL) + return res; + fin |= res; + + if ((res = rnd_r_search(layer->text_tree, bbox, NULL, cb, closure, NULL)) == RND_R_DIR_CANCEL) + return res; + fin |= res; + +TODO("padstack too"); + + return res; +} + + +pcb_flag_t flg_mesh_pt; +static void acompnet_mesh_addpt(pcb_meshgraph_t *gr, pcb_layer_t *layer, double x, double y, int score, double sep) +{ + overlap_t ovl; + rnd_box_t bbox; + + x = rnd_round(x); + y = rnd_round(y); + + ovl.x = x; + ovl.y = y; + ovl.r = rnd_round(sep/2-1); + bbox.X1 = x - ovl.r; + bbox.X2 = x + ovl.r; + bbox.Y1 = y - ovl.r; + bbox.Y2 = y + ovl.r; + + if (pcb_search_on_layer(layer, &bbox, overlap, &ovl) == RND_R_DIR_NOT_FOUND) { + bbox.X1 = x; + bbox.X2 = x+1; + bbox.Y1 = y; + bbox.Y2 = y+1; + pcb_msgr_add_node(gr, &bbox, score); + pcb_line_new(ly, x, y, x, y, conf_core.design.line_thickness, conf_core.design.bloat, flg_mesh_pt); + } +} + +static void acompnet_mesh(pcb_meshgraph_t *gr, pcb_layer_t *layer) +{ + double sep = conf_core.design.line_thickness + conf_core.design.bloat; + int n; + + PCB_LINE_LOOP(PCB_CURRLAYER(PCB)) { + double i, len, vx, vy, x1, y1, x2, y2, nx, ny; + x1 = line->Point1.X; + x2 = line->Point2.X; + y1 = line->Point1.Y; + y2 = line->Point2.Y; + vx = x2 - x1; + vy = y2 - y1; + len = sqrt(vx*vx + vy*vy); + vx = vx/len; + vy = vy/len; + nx = vy; + ny = -vx; + + /* straight line extension points */ + acompnet_mesh_addpt(gr, layer, x1 - vx*sep, y1 - vy*sep, 0, sep); + acompnet_mesh_addpt(gr, layer, x2 + vx*sep, y2 + vy*sep, 0, sep); + + /* side and extended points; n is in-line offset from endpoint */ + for(n = 0; n <= 1; n++) { + acompnet_mesh_addpt(gr, layer, x1 - n*vx*sep + nx*sep, y1 - n*vy*sep + ny*sep, 1, sep); + acompnet_mesh_addpt(gr, layer, x1 - n*vx*sep - nx*sep, y1 - n*vy*sep - ny*sep, 1, sep); + + acompnet_mesh_addpt(gr, layer, x2 + n*vx*sep + nx*sep, y2 + n*vy*sep + ny*sep, 1, sep); + acompnet_mesh_addpt(gr, layer, x2 + n*vx*sep - nx*sep, y2 + n*vy*sep - ny*sep, 1, sep); + } + + for(i = 2*sep; i <= len - 2*sep; i += sep*3) { + acompnet_mesh_addpt(gr, layer, x1 + i*vx + nx*sep, y1 + i*vy + ny*sep, 2, sep); + acompnet_mesh_addpt(gr, layer, x1 + i*vx - nx*sep, y1 + i*vy - ny*sep, 2, sep); + } + } + PCB_END_LOOP; +} + + +static const char pcb_acts_acompnet[] = "acompnet()\n" ; +static const char pcb_acth_acompnet[] = "Attempt to auto-complete the current network"; + +static fgw_error_t pcb_act_acompnet(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_meshgraph_t gr; + long int is, ie; + + pcb_msgr_init(&gr); + acompnet_mesh(&gr, PCB_CURRLAYER(PCB)); + + { /* temporary hack for testing: fixed, off-mesh start/end */ + rnd_box_t bbox; + bbox.X1 = RND_MM_TO_COORD(6.35); bbox.X2 = bbox.X1+1; + bbox.Y1 = RND_MM_TO_COORD(21.5); bbox.Y2 = bbox.Y1+1; + is = pcb_msgr_add_node(&gr, &bbox, 0); + bbox.X1 = RND_MM_TO_COORD(12); bbox.X2 = bbox.X1+1; + bbox.Y1 = RND_MM_TO_COORD(3.8); bbox.Y2 = bbox.Y1+1; + ie = pcb_msgr_add_node(&gr, &bbox, 0); + } + + pcb_msgr_astar(&gr, is, ie); + + { /* temporary visualisation code */ + long int id = ie; + for(;;) { + pcb_meshnode_t *curr, *prev; + curr = htip_get(&gr.id2node, id); + id = curr->came_from; + if (id == 0) + break; + prev = htip_get(&gr.id2node, id); + pcb_line_new(ly, curr->bbox.X1, curr->bbox.Y1, prev->bbox.X1, prev->bbox.Y1, conf_core.design.line_thickness/2, conf_core.design.bloat/2, flg_mesh_pt); +TODO("use pcb_drc_lines(), probably during A*, saving mid-point, and draw pairs of lines here"); + } + } + RND_ACT_IRES(0); + return 0; +} + +rnd_action_t acompnet_action_list[] = { + {"acompnet", pcb_act_acompnet, pcb_acth_acompnet, pcb_acts_acompnet}, +}; + +static const char *acompnet_cookie = "acompnet plugin"; + +int pplg_check_ver_acompnet(int ver_needed) { return 0; } + +void pplg_uninit_acompnet(void) +{ + rnd_remove_actions_by_cookie(acompnet_cookie); + pcb_uilayer_free_all_cookie(acompnet_cookie); +} + +int pplg_init_acompnet(void) +{ + static rnd_color_t clr; + + RND_API_CHK_VER; + + if (clr.str[0] != '#') + rnd_color_load_str(&clr, "#c09920"); + + RND_REGISTER_ACTIONS(acompnet_action_list, acompnet_cookie) + ly = pcb_uilayer_alloc(acompnet_cookie, "autocomp-net", &clr); + + return 0; +} Index: tags/2.3.0/src_plugins/acompnet/acompnet.pup =================================================================== --- tags/2.3.0/src_plugins/acompnet/acompnet.pup (nonexistent) +++ tags/2.3.0/src_plugins/acompnet/acompnet.pup (revision 33253) @@ -0,0 +1,6 @@ +$class feature +$short net auto-completion +$long Auto-complete the current network. A very limited autorouter/assistant. +$state WIP +default disable +autoload 1 Index: tags/2.3.0/src_plugins/acompnet/meshgraph.c =================================================================== --- tags/2.3.0/src_plugins/acompnet/meshgraph.c (nonexistent) +++ tags/2.3.0/src_plugins/acompnet/meshgraph.c (revision 33253) @@ -0,0 +1,161 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include "board.h" +#include "conf_core.h" +#include "data.h" +#include "meshgraph.h" +#include +#include "layer.h" +#include "route.h" + +#define INF_SCORE 9000000000.0 +#define SEARCHR RND_MM_TO_COORD(5) + +void pcb_msgr_init(pcb_meshgraph_t *gr) +{ + rnd_rtree_init(&gr->ntree); + htip_init(&gr->id2node, longhash, longkeyeq); + gr->next_id = 1; +} + +long int pcb_msgr_add_node(pcb_meshgraph_t *gr, rnd_box_t *bbox, int score) +{ + pcb_meshnode_t *nd = malloc(sizeof(pcb_meshnode_t)); + nd->bbox = *bbox; + nd->id = gr->next_id; + nd->came_from = 0; + nd->gscore = INF_SCORE; + nd->fscore = INF_SCORE; + nd->iscore = score; + + rnd_rtree_insert(&gr->ntree, nd, (rnd_rtree_box_t *)nd); + htip_set(&gr->id2node, nd->id, nd); + gr->next_id++; + return nd->id; +} + +static double msgr_connect(pcb_meshnode_t *curr, pcb_meshnode_t *next) +{ + rnd_point_t np, cp; + pcb_route_t route; + pcb_route_init(&route); + + np.X = next->bbox.X1; + np.Y = next->bbox.Y1; + cp.X = curr->bbox.X1; + cp.Y = curr->bbox.Y1; + pcb_route_calculate(PCB, &route, &np, &cp, PCB_CURRLID(PCB), conf_core.design.line_thickness, conf_core.design.bloat, pcb_flag_make(PCB_FLAG_CLEARLINE), 0, 0); + + rnd_trace("size=%d\n", route.size); + + return curr->gscore + rnd_distance(curr->bbox.X1, curr->bbox.Y1, next->bbox.X1, next->bbox.Y1) * (next->iscore + 1.0); +} + +static double msgr_heurist(pcb_meshnode_t *curr, pcb_meshnode_t *end) +{ + return rnd_distance(curr->bbox.X1, curr->bbox.Y1, end->bbox.X1, end->bbox.Y1); +} + +int pcb_msgr_astar(pcb_meshgraph_t *gr, long int startid, long int endid) +{ + htip_t closed, open; + htip_entry_t *e; + pcb_meshnode_t *curr, *next, *end; + + curr = htip_get(&gr->id2node, startid); + if (curr == NULL) + return -1; + + end = htip_get(&gr->id2node, endid); + if (end == NULL) + return -1; + + htip_init(&closed, longhash, longkeyeq); + htip_init(&open, longhash, longkeyeq); + + htip_set(&open, startid, curr); + for(;;) { + rnd_rtree_box_t sb; + rnd_box_t *b; + rnd_rtree_it_t it; + double tentative_g, best; + +TODO("should use a faster way for picking lowest fscore") + /* get the best looking item from the open list */ + curr = NULL; + best = INF_SCORE; + for(e = htip_first(&open); e != NULL; e = htip_next(&open, e)) { + next = e->value; + if (next->fscore <= best) { + best = next->fscore; + curr = next; + } + } + + if (curr == NULL) { +rnd_trace("NO PATH\n"); + return 0; + } + htip_pop(&open, curr->id); + if (curr->id == endid) { +rnd_trace("found path\n"); + return 1; + } + htip_set(&closed, curr->id, curr); +rnd_trace("first: %ld\n", curr->id); + + /* search potential neighbors */ + sb.x1 = curr->bbox.X1 - SEARCHR; + sb.x2 = curr->bbox.X2 + SEARCHR; + sb.y1 = curr->bbox.Y1 - SEARCHR; + sb.y2 = curr->bbox.Y2 + SEARCHR; + for(b = rnd_rtree_first(&it, &gr->ntree, &sb); b != NULL; b = rnd_rtree_next(&it)) { + next = (pcb_meshnode_t *)b; + if (htip_get(&closed, next->id) != NULL) + continue; + + tentative_g = msgr_connect(curr, next); + if (tentative_g < 0) + continue; + + if (htip_get(&open, next->id) == NULL) /* not in open */ + htip_set(&open, next->id, next); + else if (tentative_g > next->gscore) + continue; + +rnd_trace("add: %ld\n", next->id); + next->came_from = curr->id; + next->gscore = tentative_g; + next->fscore = msgr_heurist(curr, end); + } + } +} + + Index: tags/2.3.0/src_plugins/acompnet/meshgraph.h =================================================================== --- tags/2.3.0/src_plugins/acompnet/meshgraph.h (nonexistent) +++ tags/2.3.0/src_plugins/acompnet/meshgraph.h (revision 33253) @@ -0,0 +1,26 @@ +#ifndef PCB_ACOMPNET_MESHGRAPH_H +#define PCB_ACOMPNET_MESHGRAPH_H +#include +#include +#include + +typedef struct { + rnd_box_t bbox; + long int id; + long int came_from; + double gscore, fscore; + int iscore; /* input score: how much we prefer to use this node */ +} pcb_meshnode_t; + + +typedef struct { + rnd_rtree_t ntree; + htip_t id2node; + long int next_id; +} pcb_meshgraph_t; + +void pcb_msgr_init(pcb_meshgraph_t *gr); +long int pcb_msgr_add_node(pcb_meshgraph_t *gr, rnd_box_t *bbox, int score); +int pcb_msgr_astar(pcb_meshgraph_t *gr, long int startid, long int endid); + +#endif Index: tags/2.3.0/src_plugins/act_draw/Makefile =================================================================== --- tags/2.3.0/src_plugins/act_draw/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/act_draw/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_act_draw + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/act_draw/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/act_draw/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/act_draw/Plug.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +put /local/pcb/mod {act_draw} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/act_draw/act_draw.o + $(PLUGDIR)/act_draw/keywords_sphash.o +@] +put /local/pcb/mod/SPHASH {$(PLUGDIR)/act_draw/keywords.sphash} + +switch /local/pcb/act_draw/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/act_draw/act_draw.c =================================================================== --- tags/2.3.0/src_plugins/act_draw/act_draw.c (nonexistent) +++ tags/2.3.0/src_plugins/act_draw/act_draw.c (revision 33253) @@ -0,0 +1,635 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include "board.h" +#include +#include "flag_str.h" +#include "obj_arc.h" +#include "obj_line.h" +#include "obj_pstk.h" +#include "obj_text.h" +#include +#include "undo.h" + +#include "obj_text.h" +#include "obj_line.h" +#include "obj_text_draw.h" +#include "obj_line_draw.h" + +#include "keywords_sphash.h" + +#define PCB (do_not_use_PCB) + +static const char *PTR_DOMAIN_POLY = "fgw_ptr_domain_poly"; + +static int flg_error(const char *msg) +{ + rnd_message(RND_MSG_ERROR, "act_draw flag conversion error: %s\n", msg); + return 0; +} + +#define DRAWOPTARG \ + int noundo = 0, ao = 0; \ + if (((argv[1].type & FGW_STR) == FGW_STR) && (strcmp(argv[1].val.str, "noundo") == 0)) { \ + noundo = 1; \ + ao++; \ + } + +#define RET_IDPATH(obj) \ + do { \ + pcb_idpath_t *idp = pcb_obj2idpath((pcb_any_obj_t *)obj); \ + res->type = FGW_IDPATH; \ + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); \ + } while(0) + +#include "act_pstk_proto.c" +#include "act_polybool.c" + +static const char pcb_acts_LineNew[] = "LineNew([noundo,] data, layer, X1, Y1, X2, Y2, Thickness, Clearance, Flags)"; +static const char pcb_acth_LineNew[] = "Create a pcb line segment on a layer. For now data must be \"pcb\". Returns the idpath of the new object or 0 on error."; +static fgw_error_t pcb_act_LineNew(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *sflg; + pcb_line_t *line; + pcb_data_t *data; + pcb_layer_t *layer; + rnd_coord_t x1, y1, x2, y2, th, cl; + pcb_flag_t flags; + DRAWOPTARG; + + RND_ACT_IRES(0); + RND_ACT_CONVARG(1+ao, FGW_DATA, LineNew, data = fgw_data(&argv[1+ao])); + RND_ACT_CONVARG(2+ao, FGW_LAYER, LineNew, layer = fgw_layer(&argv[2+ao])); + RND_ACT_CONVARG(3+ao, FGW_COORD, LineNew, x1 = fgw_coord(&argv[3+ao])); + RND_ACT_CONVARG(4+ao, FGW_COORD, LineNew, y1 = fgw_coord(&argv[4+ao])); + RND_ACT_CONVARG(5+ao, FGW_COORD, LineNew, x2 = fgw_coord(&argv[5+ao])); + RND_ACT_CONVARG(6+ao, FGW_COORD, LineNew, y2 = fgw_coord(&argv[6+ao])); + RND_ACT_CONVARG(7+ao, FGW_COORD, LineNew, th = fgw_coord(&argv[7+ao])); + RND_ACT_CONVARG(8+ao, FGW_COORD, LineNew, cl = fgw_coord(&argv[8+ao])); + RND_ACT_CONVARG(9+ao, FGW_STR, LineNew, sflg = argv[9+ao].val.str); + + if ((data != pcb->Data) || (layer == NULL)) + return 0; + + flags = pcb_strflg_s2f(sflg, flg_error, NULL, 0); + line = pcb_line_new(layer, x1, y1, x2, y2, th, cl*2, flags); + + if (line != NULL) { + RET_IDPATH(line); + if (!noundo) + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, layer, line, line); + } + return 0; +} + +static const char pcb_acts_ArcNew[] = "ArcNew([noundo,] data, layer, centx, centy, radiusx, radiusy, start_ang, delta_ang, thickness, clearance, flags)"; +static const char pcb_acth_ArcNew[] = "Create a pcb arc segment on a layer. For now data must be \"pcb\". Returns the idpath of the new object or 0 on error."; +static fgw_error_t pcb_act_ArcNew(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *sflg; + pcb_arc_t *arc; + pcb_data_t *data; + pcb_layer_t *layer; + rnd_coord_t cx, cy, hr, wr, th, cl; + double sa, da; + pcb_flag_t flags; + DRAWOPTARG; + + RND_ACT_IRES(0); + RND_ACT_CONVARG(1+ao, FGW_DATA, ArcNew, data = fgw_data(&argv[1+ao])); + RND_ACT_CONVARG(2+ao, FGW_LAYER, ArcNew, layer = fgw_layer(&argv[2+ao])); + RND_ACT_CONVARG(3+ao, FGW_COORD, ArcNew, cx = fgw_coord(&argv[3+ao])); + RND_ACT_CONVARG(4+ao, FGW_COORD, ArcNew, cy = fgw_coord(&argv[4+ao])); + RND_ACT_CONVARG(5+ao, FGW_COORD, ArcNew, wr = fgw_coord(&argv[5+ao])); + RND_ACT_CONVARG(6+ao, FGW_COORD, ArcNew, hr = fgw_coord(&argv[6+ao])); + RND_ACT_CONVARG(7+ao, FGW_DOUBLE, ArcNew, sa = argv[7+ao].val.nat_double); + RND_ACT_CONVARG(8+ao, FGW_DOUBLE, ArcNew, da = argv[8+ao].val.nat_double); + RND_ACT_CONVARG(9+ao, FGW_COORD, ArcNew, th = fgw_coord(&argv[9+ao])); + RND_ACT_CONVARG(10+ao, FGW_COORD, ArcNew, cl = fgw_coord(&argv[10+ao])); + RND_ACT_CONVARG(11+ao, FGW_STR, ArcNew, sflg = argv[11+ao].val.str); + + if ((data != pcb->Data) || (layer == NULL)) + return 0; + + flags = pcb_strflg_s2f(sflg, flg_error, NULL, 0); + arc = pcb_arc_new(layer, cx, cy, wr, hr, sa, da, th, cl*2, flags, 0); + + if (arc != NULL) { + RET_IDPATH(arc); + if (!noundo) + pcb_undo_add_obj_to_create(PCB_OBJ_ARC, layer, arc, arc); + } + return 0; +} + +static const char pcb_acts_TextNew[] = "TextNew([noundo,] data, layer, fontID, x, y, rot, scale, thickness, text_string, flags)"; +static const char pcb_acth_TextNew[] = "Create a pcb text on a layer. For now data must be \"pcb\". Font id 0 is the default font. Thickness 0 means default, calculated thickness. Scale=100 is the original font size. Returns the idpath of the new object or 0 on error."; +static fgw_error_t pcb_act_TextNew(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *sflg, *str; + pcb_text_t *text = NULL; + pcb_data_t *data; + pcb_layer_t *layer; + rnd_coord_t x, y, th; + int scale, fontid; + double rot; + pcb_flag_t flags; + pcb_font_t *font; + DRAWOPTARG; + + RND_ACT_IRES(0); + RND_ACT_CONVARG(1+ao, FGW_DATA, TextNew, data = fgw_data(&argv[1+ao])); + RND_ACT_CONVARG(2+ao, FGW_LAYER, TextNew, layer = fgw_layer(&argv[2+ao])); + RND_ACT_CONVARG(3+ao, FGW_INT, TextNew, fontid = argv[3+ao].val.nat_int); + RND_ACT_CONVARG(4+ao, FGW_COORD, TextNew, x = fgw_coord(&argv[4+ao])); + RND_ACT_CONVARG(5+ao, FGW_COORD, TextNew, y = fgw_coord(&argv[5+ao])); + RND_ACT_CONVARG(6+ao, FGW_DOUBLE, TextNew, rot = argv[6+ao].val.nat_double); + RND_ACT_CONVARG(7+ao, FGW_INT, TextNew, scale = argv[7+ao].val.nat_int); + RND_ACT_CONVARG(8+ao, FGW_COORD, TextNew, th = fgw_coord(&argv[8+ao])); + RND_ACT_CONVARG(9+ao, FGW_STR, TextNew, str = argv[9+ao].val.str); + RND_ACT_CONVARG(10+ao, FGW_STR, TextNew, sflg = argv[10+ao].val.str); + + if ((data != pcb->Data) || (layer == NULL)) + return 0; + + font = pcb_font(pcb, fontid, 0); + if (font != NULL) { + flags = pcb_strflg_s2f(sflg, flg_error, NULL, 0); + text = pcb_text_new(layer, font, x, y, rot, scale, th, str, flags); + } + else + rnd_message(RND_MSG_ERROR, "NewText: font %d not found\n", fontid); + + if (text != NULL) { + RET_IDPATH(text); + if (!noundo) + pcb_undo_add_obj_to_create(PCB_OBJ_TEXT, layer, text, text); + } + return 0; +} + +static const char pcb_acts_PstkNew[] = "PstkNew([noundo,] data, protoID, x, y, glob_clearance, flags)"; +static const char pcb_acth_PstkNew[] = "Create a padstack. For now data must be \"pcb\". glob_clearance=0 turns off global clearance. Returns the idpath of the new object or 0 on error."; +static fgw_error_t pcb_act_PstkNew(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *sflg; + pcb_pstk_t *pstk; + pcb_data_t *data; + long proto; + rnd_coord_t x, y, cl; + pcb_flag_t flags; + DRAWOPTARG; + + RND_ACT_IRES(0); + RND_ACT_CONVARG(1+ao, FGW_DATA, PstkNew, data = fgw_data(&argv[1+ao])); + RND_ACT_CONVARG(2+ao, FGW_LONG, PstkNew, proto = argv[2+ao].val.nat_int); + RND_ACT_CONVARG(3+ao, FGW_COORD, PstkNew, x = fgw_coord(&argv[3+ao])); + RND_ACT_CONVARG(4+ao, FGW_COORD, PstkNew, y = fgw_coord(&argv[4+ao])); + RND_ACT_CONVARG(5+ao, FGW_COORD, PstkNew, cl = fgw_coord(&argv[5+ao])); + RND_ACT_CONVARG(6+ao, FGW_STR, PstkNew, sflg = argv[6+ao].val.str); + + flags = pcb_strflg_s2f(sflg, flg_error, NULL, 0); + pstk = pcb_pstk_new(data, -1, proto, x, y, cl, flags); + + if (pstk != NULL) { + RET_IDPATH(pstk); + if (!noundo) + pcb_undo_add_obj_to_create(PCB_OBJ_PSTK, data, pstk, pstk); + } + return 0; +} + +static const char pcb_acts_PolyNewFromRectangle[] = "PolyNewFromRectangle([noundo,] data, layer, x1, y1, x2, y2, clearance, flags)"; +static const char pcb_acth_PolyNewFromRectangle[] = "Create a rectangular polygon. For now data must be \"pcb\". Returns the idpath of the new object or 0 on error."; +static fgw_error_t pcb_act_PolyNewFromRectangle(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *sflg; + pcb_poly_t *poly; + pcb_data_t *data; + pcb_layer_t *layer; + rnd_coord_t x1, y1, x2, y2, cl; + pcb_flag_t flags; + DRAWOPTARG; + + RND_ACT_IRES(0); + RND_ACT_CONVARG(1+ao, FGW_DATA, PolyNewFromRectangle, data = fgw_data(&argv[1+ao])); + RND_ACT_CONVARG(2+ao, FGW_LAYER, PolyNewFromRectangle, layer = fgw_layer(&argv[2+ao])); + RND_ACT_CONVARG(3+ao, FGW_COORD, PolyNewFromRectangle, x1 = fgw_coord(&argv[3+ao])); + RND_ACT_CONVARG(4+ao, FGW_COORD, PolyNewFromRectangle, y1 = fgw_coord(&argv[4+ao])); + RND_ACT_CONVARG(5+ao, FGW_COORD, PolyNewFromRectangle, x2 = fgw_coord(&argv[5+ao])); + RND_ACT_CONVARG(6+ao, FGW_COORD, PolyNewFromRectangle, y2 = fgw_coord(&argv[6+ao])); + RND_ACT_CONVARG(7+ao, FGW_COORD, PolyNewFromRectangle, cl = fgw_coord(&argv[7+ao])); + RND_ACT_CONVARG(8+ao, FGW_STR, PolyNewFromRectangle, sflg = argv[8+ao].val.str); + + if (data != pcb->Data) + return 0; + + flags = pcb_strflg_s2f(sflg, flg_error, NULL, 0); + poly = pcb_poly_new_from_rectangle(layer, x1, y1, x2, y2, cl*2, flags); + + if (poly != NULL) { + RET_IDPATH(poly); + if (!noundo) + pcb_undo_add_obj_to_create(PCB_OBJ_POLY, layer, poly, poly); + } + return 0; +} + +static long poly_append_ptlist(pcb_poly_t *poly, const char *ptlist) +{ + long len; + char *s, *next, *tmp = rnd_strdup(ptlist); + double c[2]; + rnd_bool success; + + s = tmp; + while (isspace(*s) || (*s == ',')) s++; + for(len = 0; s != NULL; s = next, len++) { + next = strchr(s, ','); + if (next != NULL) { + *next = '\0'; + next++; + while (isspace(*next) || (*next == ',')) next++; + if (*next == '\0') + next = NULL; + } + c[len % 2] = rnd_get_value_ex(s, NULL, NULL, NULL, "mm", &success); + if (!success) { + rnd_message(RND_MSG_ERROR, "act_draw ptlist processing: '%s' is not a valid coordinate\n", s); + free(tmp); + return -1; + } + if ((len % 2) == 1) + pcb_poly_point_new(poly, c[0], c[1]); + } + free(tmp); + if ((len % 2) == 1) { + rnd_message(RND_MSG_ERROR, "act_draw ptlist processing: odd number of points\n"); + return -1; + } + return len/2; +} + +static const char pcb_acts_PolyNewFromPoints[] = "PolyNewFromRectangle([noundo,] data, layer, ptlist, clearance, flags)"; +static const char pcb_acth_PolyNewFromPoints[] = "Create a polygon. For now data must be \"pcb\". ptlist is a comma separated list of coordinates (untiless coordinates are treated as mm). Returns the idpath of the new object or 0 on error."; +static fgw_error_t pcb_act_PolyNewFromPoints(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *sflg, *ptlist; + pcb_poly_t *poly; + pcb_data_t *data; + pcb_layer_t *layer; + rnd_coord_t cl; + pcb_flag_t flags; + DRAWOPTARG; + + RND_ACT_IRES(0); + RND_ACT_CONVARG(1+ao, FGW_DATA, PolyNewFromPoints, data = fgw_data(&argv[1+ao])); + RND_ACT_CONVARG(2+ao, FGW_LAYER, PolyNewFromPoints, layer = fgw_layer(&argv[2+ao])); + RND_ACT_CONVARG(3+ao, FGW_STR, PolyNewFromPoints, ptlist = argv[3+ao].val.str); + RND_ACT_CONVARG(4+ao, FGW_COORD, PolyNewFromPoints, cl = fgw_coord(&argv[4+ao])); + RND_ACT_CONVARG(5+ao, FGW_STR, PolyNewFromPoints, sflg = argv[5+ao].val.str); + + if (data != pcb->Data) + return 0; + + flags = pcb_strflg_s2f(sflg, flg_error, NULL, 0); + poly = pcb_poly_new(layer, cl*2, flags); + + if (poly != NULL) { + if (poly_append_ptlist(poly, ptlist) > 2) { + pcb_poly_init_clip(data, layer, poly); + pcb_add_poly_on_layer(layer, poly); + RET_IDPATH(poly); + if (!noundo) + pcb_undo_add_obj_to_create(PCB_OBJ_POLY, layer, poly, poly); + } + } + return 0; +} + +static const char pcb_acts_PolyNew[] = "PolyNew([noundo,] data, layer, ptlist, clearance, flags)"; +static const char pcb_acth_PolyNew[] = "Create an empty polygon. For now data must be \"pcb\". Use PolyNewPoint to add points. Returns a polygon pointer valid until PolyNewEnd() is called."; +static fgw_error_t pcb_act_PolyNew(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *sflg; + pcb_poly_t *poly; + pcb_data_t *data; + pcb_layer_t *layer; + rnd_coord_t cl; + pcb_flag_t flags; + DRAWOPTARG; + (void)noundo; + + RND_ACT_IRES(0); + RND_ACT_CONVARG(1+ao, FGW_DATA, PolyNewFromPoints, data = fgw_data(&argv[1+ao])); + RND_ACT_CONVARG(2+ao, FGW_LAYER, PolyNewFromPoints, layer = fgw_layer(&argv[2+ao])); + RND_ACT_CONVARG(3+ao, FGW_COORD, PolyNewFromPoints, cl = fgw_coord(&argv[3+ao])); + RND_ACT_CONVARG(4+ao, FGW_STR, PolyNewFromPoints, sflg = argv[4+ao].val.str); + + if (data != pcb->Data) + return 0; + + flags = pcb_strflg_s2f(sflg, flg_error, NULL, 0); + poly = pcb_poly_new(layer, cl*2, flags); + + if (poly != NULL) + fgw_ptr_reg(&rnd_fgw, res, PTR_DOMAIN_POLY, FGW_PTR, poly); + return 0; +} + +static const char pcb_acts_PolyNewPoints[] = "PolyNewPoints([noundo,] poly, ptlist)"; +static const char pcb_acth_PolyNewPoints[] = "Add a list of points to a polygon created by PolyNew. Returns 0 on success."; +static fgw_error_t pcb_act_PolyNewPoints(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_poly_t *poly; + const char *ptlist; + DRAWOPTARG; + (void)noundo; + + RND_ACT_CONVARG(1+ao, FGW_PTR, PolyNewPoints, poly = argv[1+ao].val.ptr_void); + RND_ACT_CONVARG(2+ao, FGW_STR, PolyNewPoints, ptlist = argv[2+ao].val.str); + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[1], PTR_DOMAIN_POLY)) { + rnd_message(RND_MSG_ERROR, "PolyNewPoints: invalid polygon pointer\n"); + RND_ACT_IRES(-1); + return 0; + } + if (poly_append_ptlist(poly, ptlist) < 0) { + RND_ACT_IRES(-1); + return 0; + } + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_PolyNewEnd[] = "PolyNewEnd([noundo,] data, layer, poly)"; +static const char pcb_acth_PolyNewEnd[] = "Close and place a polygon started by PolyNew. Returns the idpath of the new object or 0 on error."; +static fgw_error_t pcb_act_PolyNewEnd(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_poly_t *poly; + pcb_data_t *data; + pcb_layer_t *layer; + DRAWOPTARG; + + RND_ACT_CONVARG(1+ao, FGW_DATA, PolyNewFromPoints, data = fgw_data(&argv[1+ao])); + RND_ACT_CONVARG(2+ao, FGW_LAYER, PolyNewFromPoints, layer = fgw_layer(&argv[2+ao])); + RND_ACT_CONVARG(3+ao, FGW_PTR, PolyNewPoints, poly = argv[3+ao].val.ptr_void); + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[1], PTR_DOMAIN_POLY)) { + rnd_message(RND_MSG_ERROR, "PolyNewEnd: invalid polygon pointer\n"); + RND_ACT_IRES(0); + return 0; + } + if (poly->PointN < 3) { + rnd_message(RND_MSG_ERROR, "PolyNewEnd: can not finish polygon, need at least 3 points\n"); + RND_ACT_IRES(0); + return 0; + } + + pcb_poly_init_clip(data, layer, poly); + pcb_add_poly_on_layer(layer, poly); + + RET_IDPATH(poly); + if (!noundo) + pcb_undo_add_obj_to_create(PCB_OBJ_POLY, layer, poly, poly); + fgw_ptr_unreg(&rnd_fgw, &argv[1], PTR_DOMAIN_POLY); + return 0; +} + +static const char pcb_acts_LayerObjDup[] = "LayerObjDup([noundo,] data, layer, srcobj)"; +static const char pcb_acth_LayerObjDup[] = "Duplicate srcobj on a layer. Srcobj is specified by an idpath. For now data must be \"pcb\". Returns the idpath of the new object or 0 on error."; +static fgw_error_t pcb_act_LayerObjDup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + pcb_data_t *data; + pcb_layer_t *layer; + pcb_any_obj_t *src, *dst; + pcb_idpath_t *idp; + DRAWOPTARG; + +TODO("implement noundo"); + (void)noundo; + + RND_ACT_IRES(0); + RND_ACT_CONVARG(1+ao, FGW_DATA, LayerObjDup, data = fgw_data(&argv[1+ao])); + RND_ACT_CONVARG(2+ao, FGW_LAYER, LayerObjDup, layer = fgw_layer(&argv[2+ao])); + RND_ACT_CONVARG(3+ao, FGW_PTR, LayerObjDup, idp = argv[3+ao].val.ptr_void); + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[3], RND_PTR_DOMAIN_IDPATH)) { + rnd_message(RND_MSG_ERROR, "LayerObjDup: invalid object pointer\n"); + return FGW_ERR_PTR_DOMAIN; + } + src = pcb_idpath2obj(pcb, idp); + if (src == NULL) + return FGW_ERR_ARG_CONV; + + switch(src->type) { + case PCB_OBJ_ARC: dst = (pcb_any_obj_t *)pcb_arc_dup(layer, (pcb_arc_t *)src); break; + case PCB_OBJ_LINE: dst = (pcb_any_obj_t *)pcb_line_dup(layer, (pcb_line_t *)src); break; + case PCB_OBJ_POLY: dst = (pcb_any_obj_t *)pcb_poly_dup(layer, (pcb_poly_t *)src); break; + case PCB_OBJ_TEXT: dst = (pcb_any_obj_t *)pcb_text_dup(layer, (pcb_text_t *)src); break; + default: + return FGW_ERR_ARG_CONV; + } + + if (dst != NULL) { + idp = pcb_obj2idpath(dst); + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + + pcb_poly_clear_from_poly(data, dst->type, layer, dst); + } + + return 0; +} + +/*** low level draw, e.g. for preview widgets ***/ +static pcb_draw_info_t def_info; +static rnd_xform_t def_xform; + +static const char pcb_acts_DrawText[] = "DrawText(gc, x, y, string, rot, scale_percent)"; +static const char pcb_acth_DrawText[] = "Low level draw (render) a text object using graphic context gc."; +static fgw_error_t pcb_act_DrawText(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + static pcb_text_t t = {0}; + rnd_hid_gc_t gc, ogc; + + RND_ACT_CONVARG(1, FGW_PTR, DrawText, gc = argv[1].val.ptr_void); + RND_ACT_CONVARG(2, FGW_COORD, DrawText, t.X = fgw_coord(&argv[2])); + RND_ACT_CONVARG(3, FGW_COORD, DrawText, t.Y = fgw_coord(&argv[3])); + RND_ACT_CONVARG(4, FGW_STR, DrawText, t.TextString = argv[4].val.str); + RND_ACT_CONVARG(5, FGW_DOUBLE, DrawText, t.rot = argv[5].val.nat_double); + RND_ACT_CONVARG(6, FGW_INT, DrawText, t.Scale = argv[6].val.nat_int); + + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[1], RND_PTR_DOMAIN_GC)) { + rnd_message(RND_MSG_ERROR, "DrawText(): invalid gc (pointer domain error)\n"); + return FGW_ERR_ARG_CONV; + } + + + t.fid = 0; /* use the default font */ + t.Flags = pcb_no_flags(); + ogc = pcb_draw_out.fgGC; + pcb_draw_out.fgGC = gc; + pcb_text_draw_(&def_info, &t, 0, 0, PCB_TXT_TINY_ACCURATE); + pcb_draw_out.fgGC = ogc; + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_DrawLine[] = "DrawLine(gc, x1, y1, x2, y2, thickness)"; +static const char pcb_acth_DrawLine[] = "Low level draw (render) a line using graphic context gc."; +static fgw_error_t pcb_act_DrawLine(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_hid_gc_t gc, ogc; + pcb_line_t l = {0}; + + RND_ACT_CONVARG(1, FGW_PTR, DrawLine, gc = argv[1].val.ptr_void); + RND_ACT_CONVARG(2, FGW_COORD, DrawLine, l.Point1.X = fgw_coord(&argv[2])); + RND_ACT_CONVARG(3, FGW_COORD, DrawLine, l.Point1.Y = fgw_coord(&argv[3])); + RND_ACT_CONVARG(4, FGW_COORD, DrawLine, l.Point2.X = fgw_coord(&argv[4])); + RND_ACT_CONVARG(5, FGW_COORD, DrawLine, l.Point2.Y = fgw_coord(&argv[5])); + RND_ACT_CONVARG(6, FGW_COORD, DrawLine, l.Thickness = fgw_coord(&argv[6])); + + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[1], RND_PTR_DOMAIN_GC)) { + rnd_message(RND_MSG_ERROR, "DrawLine(): invalid gc (pointer domain error)\n"); + return FGW_ERR_ARG_CONV; + } + + ogc = pcb_draw_out.fgGC; + pcb_draw_out.fgGC = gc; + pcb_line_draw_(&def_info, &l, 0); + pcb_draw_out.fgGC = ogc; + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_DrawPoly[] = "DrawPoly(gc, x, y, x, y, x, y, [x, y...])"; +static const char pcb_acth_DrawPoly[] = "Low level draw (render) a polygon using graphic context gc."; +static fgw_error_t pcb_act_DrawPoly(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int n, len; + rnd_coord_t x[128], y[128]; + rnd_hid_gc_t gc; + + if (argc < 7) { + rnd_message(RND_MSG_ERROR, "DrawPoly(): need at least 3 pairs of coordinates\n"); + return FGW_ERR_ARGC; + } + + if ((argc % 2) != 0) { + rnd_message(RND_MSG_ERROR, "DrawPoly(): coordinates need to be in x,y pairs\n"); + return FGW_ERR_ARGC; + } + + if (argc-1 >= (sizeof(x)/sizeof(x[0]))*2) { + rnd_message(RND_MSG_ERROR, "DrawPoly(): too many pairs of coordinates\n"); + return FGW_ERR_ARGC; + } + + RND_ACT_CONVARG(1, FGW_PTR, DrawPoly, gc = argv[1].val.ptr_void); + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[1], RND_PTR_DOMAIN_GC)) { + rnd_message(RND_MSG_ERROR, "DrawPoly(): invalid gc (pointer domain error)\n"); + return FGW_ERR_ARG_CONV; + } + + for(len = 0, n = 2; n < argc; n += 2, len++) { + RND_ACT_CONVARG(n+0, FGW_COORD, DrawPoly, x[len] = fgw_coord(&argv[n+0])); + RND_ACT_CONVARG(n+1, FGW_COORD, DrawPoly, y[len] = fgw_coord(&argv[n+1])); + } + + rnd_render->fill_polygon(gc, len, x, y); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_DrawColor[] = "DrawColor(gc, colorstr)"; +static const char pcb_acth_DrawColor[] = "Set pen color in of a gc."; +static fgw_error_t pcb_act_DrawColor(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_hid_gc_t gc, ogc; + static rnd_color_t clr; + const char *scolor; + + RND_ACT_CONVARG(1, FGW_PTR, DrawColor, gc = argv[1].val.ptr_void); + RND_ACT_CONVARG(2, FGW_STR, DrawColor, scolor = argv[2].val.str); + + if (rnd_color_load_str(&clr, scolor) != 0) { + rnd_message(RND_MSG_ERROR, "DrawColor(): invalid color value '%s'\n", scolor); + return FGW_ERR_ARG_CONV; + } + + ogc = pcb_draw_out.fgGC; + pcb_draw_out.fgGC = gc; + rnd_render->set_color(gc, &clr); + pcb_draw_out.fgGC = ogc; + RND_ACT_IRES(0); + return 0; +} + +rnd_action_t act_draw_action_list[] = { + {"LineNew", pcb_act_LineNew, pcb_acth_LineNew, pcb_acts_LineNew}, + {"ArcNew", pcb_act_ArcNew, pcb_acth_ArcNew, pcb_acts_ArcNew}, + {"TextNew", pcb_act_TextNew, pcb_acth_TextNew, pcb_acts_TextNew}, + {"PstkNew", pcb_act_PstkNew, pcb_acth_PstkNew, pcb_acts_PstkNew}, + {"PolyNewFromRectangle", pcb_act_PolyNewFromRectangle, pcb_acth_PolyNewFromRectangle, pcb_acts_PolyNewFromRectangle}, + {"PolyNewFromPoints", pcb_act_PolyNewFromPoints, pcb_acth_PolyNewFromPoints, pcb_acts_PolyNewFromPoints}, + {"PolyNew", pcb_act_PolyNew, pcb_acth_PolyNew, pcb_acts_PolyNew}, + {"PolyNewPoints", pcb_act_PolyNewPoints, pcb_acth_PolyNewPoints, pcb_acts_PolyNewPoints}, + {"PolyNewEnd", pcb_act_PolyNewEnd, pcb_acth_PolyNewEnd, pcb_acts_PolyNewEnd}, + {"PstkProtoTmp", pcb_act_PstkProtoTmp, pcb_acth_PstkProtoTmp, pcb_acts_PstkProtoTmp}, + {"PstkProtoEdit", pcb_act_PstkProtoEdit, pcb_acth_PstkProtoEdit, pcb_acts_PstkProtoEdit}, + {"LayerObjDup", pcb_act_LayerObjDup, pcb_acth_LayerObjDup, pcb_acts_LayerObjDup}, + {"DrawText", pcb_act_DrawText, pcb_acth_DrawText, pcb_acts_DrawText}, + {"DrawLine", pcb_act_DrawLine, pcb_acth_DrawLine, pcb_acts_DrawLine}, + {"DrawPoly", pcb_act_DrawPoly, pcb_acth_DrawPoly, pcb_acts_DrawPoly}, + {"DrawColor", pcb_act_DrawColor, pcb_acth_DrawColor, pcb_acts_DrawColor}, + {"PolyBool", pcb_act_PolyBool, pcb_acth_PolyBool, pcb_acts_PolyBool} +}; + +static const char *act_draw_cookie = "act_draw"; + +int pplg_check_ver_act_draw(int ver_needed) { return 0; } + +void pplg_uninit_act_draw(void) +{ + rnd_remove_actions_by_cookie(act_draw_cookie); +} + +int pplg_init_act_draw(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(act_draw_action_list, act_draw_cookie) + def_info.xform = &def_xform; + return 0; +} Index: tags/2.3.0/src_plugins/act_draw/act_draw.pup =================================================================== --- tags/2.3.0/src_plugins/act_draw/act_draw.pup (nonexistent) +++ tags/2.3.0/src_plugins/act_draw/act_draw.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short action wrappers for drawing +$long Expose drawing related API as actions +$state works +$package (core) +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/act_draw/act_polybool.c =================================================================== --- tags/2.3.0/src_plugins/act_draw/act_polybool.c (nonexistent) +++ tags/2.3.0/src_plugins/act_draw/act_polybool.c (revision 33253) @@ -0,0 +1,151 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* included from act_draw.c */ +#include "search.h" +#include "obj_poly.h" +#include "data_list.h" + +/* returns number of objects added before esc */ +static int pick_obj(vtp0_t *objs, const char *ask_first, const char *ask_subseq) +{ + rnd_coord_t x, y; + const char *msg = objs->used == 0 ? ask_first : ask_subseq; + for(;;) { + int res = rnd_hid_get_coords(msg, &x, &y, 1); + void *p1, *p2, *p3; + if (res < 0) + return 0; + res = pcb_search_screen(x, y, PCB_OBJ_POLY, &p1, &p2, &p3); + if (res == PCB_OBJ_POLY) { + int n, found = 0; + for(n = 0; n < objs->used; n++) { + if (objs->array[n] == p2) { + found = 1; + break; + } + } + if (found) { + rnd_message(RND_MSG_ERROR, "That polygon is already on the list! Try again or press esc!\n"); + continue; + } + vtp0_append(objs, p2); + return 1; + } + rnd_message(RND_MSG_ERROR, "There's no polygon there. Try again or press esc!\n"); + } +} + +static const char pcb_acts_PolyBool[] = "PstkProto([noundo,] unite|isect|sub, [poly1, poly2, [poly...]])\n"; +static const char pcb_acth_PolyBool[] = "Perform polygon boolean operation on the clipped polygons referred. A poly is either and idpath, selected, found or object (for the object under the cursor). When not specified, two object polygons are used."; +/* doc: polybool.html */ +static fgw_error_t pcb_act_PolyBool(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + char *cmd; + int cmdi, n; + vtp0_t objs; + rnd_bool_op_t bop; + const char *ask_first, *ask_subseq; + rnd_polyarea_t *pa, *ptmp; + DRAWOPTARG; + + + RND_ACT_CONVARG(1+ao, FGW_STR, PolyBool, cmd = argv[1+ao].val.str); + + cmdi = act_draw_keywords_sphash(cmd); + switch(cmdi) { + case act_draw_keywords_unite: bop = RND_PBO_UNITE; ask_first = ask_subseq = "click on polygon to unite, press esc after the last"; break; + case act_draw_keywords_isect: bop = RND_PBO_ISECT; ask_first = ask_subseq = "click on polygon to contribute in intersection, press esc after the last"; break; + case act_draw_keywords_sub: bop = RND_PBO_SUB; ask_first = "click on polygon to subtract other polygons from"; ask_subseq = "click on polygon to subtract from the first, press esc after the last"; break; +/* case act_draw_keywords_xor: bop = RND_PBO_XOR; ask_first = ask_subseq = "click on polygon to xor, press esc after the last"; break;*/ + default: + RND_ACT_FAIL(PolyBool); + } + + RND_ACT_IRES(-1); + vtp0_init(&objs); + for(n = 2+ao; n < argc; n++) { + if ((argv[n].type & FGW_STR) == FGW_STR) { + if (strcmp(argv[n].val.str, "object") == 0) + pick_obj(&objs, ask_first, ask_subseq); + else if (strcmp(argv[n].val.str, "selected") == 0) + pcb_data_list_by_flag(pcb->Data, &objs, PCB_OBJ_POLY, PCB_FLAG_SELECTED); + else if (strcmp(argv[n].val.str, "found") == 0) + pcb_data_list_by_flag(pcb->Data, &objs, PCB_OBJ_POLY, PCB_FLAG_FOUND); + else + goto try_idp; + } + else { + pcb_idpath_t *idp; + pcb_any_obj_t *obj; + try_idp:; + RND_ACT_MAY_CONVARG(n, FGW_IDPATH, PolyBool, idp = fgw_idpath(&argv[n])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[n], RND_PTR_DOMAIN_IDPATH)) { + rnd_message(RND_MSG_ERROR, "Invalid polygon specification idpath in arg %d: pointer domain error\n", n); + goto error; + } + obj = pcb_idpath2obj(pcb, idp); + if ((obj == NULL) || (obj->type != PCB_OBJ_POLY)) { + rnd_message(RND_MSG_ERROR, "Invalid polygon specification idpath in arg %d: object is not a polygon\n", n); + goto error; + } + vtp0_append(&objs, obj); + } + } + + while(objs.used < 2) { + if (pick_obj(&objs, ask_first, ask_subseq) == 0) + goto error; /* aborted */ + } + + /* set up the base poly in pa */ + if (!rnd_polyarea_m_copy0(&pa, ((pcb_poly_t *)objs.array[0])->Clipped)) { + rnd_message(RND_MSG_ERROR, "Failed to copy the first polygon\n", n); + goto error; + } + + /* peform the boolean ops */ + for(n = 1; n < objs.used; n++) { + rnd_polyarea_boolean(pa, ((pcb_poly_t *)objs.array[n])->Clipped, &ptmp, bop); + rnd_polyarea_free(&pa); + pa = ptmp; + } + + if (noundo) + pcb_undo_freeze_add(); + pcb_poly_to_polygons_on_layer(pcb->Data, PCB_CURRLAYER(pcb), pa, pcb_flag_make(PCB_FLAG_CLEARLINE)); + if (noundo) + pcb_undo_unfreeze_add(); + + + rnd_polyarea_free(&pa); + + error:; + vtp0_uninit(&objs); + return 0; +} + Index: tags/2.3.0/src_plugins/act_draw/act_pstk_proto.c =================================================================== --- tags/2.3.0/src_plugins/act_draw/act_pstk_proto.c (nonexistent) +++ tags/2.3.0/src_plugins/act_draw/act_pstk_proto.c (revision 33253) @@ -0,0 +1,260 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* included from act_draw.c */ + +#include "obj_pstk_inlines.h" + +static const char *PCB_PTR_DOMAIN_PSTK_PROTO = "fgw_ptr_domain_pstk_proto"; + +static const char pcb_acts_PstkProtoTmp[] = + "PstkProto([noundo,] new)\n" + "PstkProto([noundo,] dup, idpath)\n" + "PstkProto([noundo,] dup, data, src_proto_id)\n" + "PstkProto([noundo,] insert, idpath|data, proto)\n" + "PstkProto([noundo,] insert_dup, idpath|data, proto)\n" + "PstkProto([noundo,] free, proto)"; +static const char pcb_acth_PstkProtoTmp[] = "Allocate, insert or free a temporary padstack prototype"; + +static int get_obj_and_data_from_idp(int argc, fgw_arg_t *argv, int aidx, pcb_any_obj_t **obj_out, pcb_data_t **data_out) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + pcb_any_obj_t *obj; + pcb_idpath_t *idp; + + if (((argv[aidx].type & FGW_STR) == FGW_STR) && (argv[aidx].val.str[0] == 'b') && ((argv[aidx].val.str[1] == 'u') || (argv[aidx].val.str[1] == 'o'))) { + RND_ACT_CONVARG(aidx, FGW_DATA, PstkProtoTmp, *data_out = fgw_data(&argv[aidx])); + *obj_out = NULL; + return 0; + } + + RND_ACT_CONVARG(aidx, FGW_IDPATH, PstkProtoTmp, idp = fgw_idpath(&argv[aidx])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[aidx], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + obj = pcb_idpath2obj(pcb, idp); + if ((obj == NULL) || (obj->type != PCB_OBJ_PSTK) || (obj->parent_type != PCB_PARENT_DATA)) + return -1; + *obj_out = obj; + *data_out = obj->parent.data; + return 0; +} + +static fgw_error_t pcb_act_PstkProtoTmp(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char *cmd; + int cmdi; + pcb_pstk_proto_t *proto, *src; + pcb_data_t *data; + pcb_any_obj_t *obj; + long src_id; + DRAWOPTARG; + + res->type = FGW_PTR | FGW_STRUCT; + res->val.ptr_void = NULL; + + RND_ACT_CONVARG(1+ao, FGW_STR, PstkProtoTmp, cmd = argv[1+ao].val.str); + + cmdi = act_draw_keywords_sphash(cmd); + switch(cmdi) { + case act_draw_keywords_new: + proto = calloc(sizeof(pcb_pstk_proto_t), 1); + fgw_ptr_reg(&rnd_fgw, res, PCB_PTR_DOMAIN_PSTK_PROTO, FGW_PTR | FGW_STRUCT, proto); + res->val.ptr_void = proto; + pcb_vtpadstack_tshape_init(&proto->tr); + pcb_vtpadstack_tshape_alloc_append(&proto->tr, 1); + return 0; + + case act_draw_keywords_dup: + if (argc < 4) { + if (get_obj_and_data_from_idp(argc, argv, 2+ao, &obj, &data) != 0) { + RND_ACT_IRES(-1); + return 0; + } + src = pcb_pstk_get_proto((pcb_pstk_t *)obj); + } + else { + RND_ACT_CONVARG(2+ao, FGW_DATA, PstkProtoTmp, data = fgw_data(&argv[2+ao])); + RND_ACT_CONVARG(3+ao, FGW_LONG, PstkProtoTmp, src_id = argv[3+ao].val.nat_long); + if (data == NULL) + return 0; + src = pcb_pstk_get_proto_(data, src_id); + } + if (src == NULL) + return 0; + proto = calloc(sizeof(pcb_pstk_proto_t), 1); + fgw_ptr_reg(&rnd_fgw, res, PCB_PTR_DOMAIN_PSTK_PROTO, FGW_PTR | FGW_STRUCT, proto); + pcb_pstk_proto_copy(proto, src); + res->val.ptr_void = proto; + return 0; + + case act_draw_keywords_insert: + case act_draw_keywords_insert_dup: + if (argc < 3) + RND_ACT_FAIL(PstkProtoTmp); + if (get_obj_and_data_from_idp(argc, argv, 2+ao, &obj, &data) != 0) { + RND_ACT_IRES(-1); + return 0; + } + RND_ACT_CONVARG(3+ao, FGW_PTR, PstkProtoTmp, proto = argv[3+ao].val.ptr_void); + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[3+ao], PCB_PTR_DOMAIN_PSTK_PROTO) || (proto == NULL)) { + rnd_message(RND_MSG_ERROR, "PstkProtoTmp: invalid proto pointer\n"); + RND_ACT_IRES(-1); + return 0; + } + res->type = FGW_LONG; + if (cmdi == act_draw_keywords_insert_dup) + res->val.nat_long = pcb_pstk_proto_insert_forcedup(data, proto, 1, !noundo); + else + res->val.nat_long = pcb_pstk_proto_insert_dup(data, proto, 1, !noundo); + return 0; + + case act_draw_keywords_free: + TODO("implement this"); + + case act_draw_keywords_SPHASH_INVALID: + default: + return FGW_ERR_ARG_CONV; + } + + return 0; +} + +static const char pcb_acts_PstkProtoEdit[] = + "PstkProto([noundo,] proto, remove, layer_type)\n" + "PstkProto([noundo,] proto, copy, dst_layer_type, src_layer_type)\n" + "PstkProto([noundo,] proto, hdia, dia)\n" + "PstkProto([noundo,] proto, shape:line, layer_type, x1, y1, x2, y2, th, [square])\n" + ; +static const char pcb_acth_PstkProtoEdit[] = "Edit a padstack prototype specified by its pointer."; +static fgw_error_t pcb_act_PstkProtoEdit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd, *tmp; + pcb_pstk_proto_t *proto; + pcb_layer_type_t slyt, dlyt; + pcb_layer_combining_t slyc, dlyc; + int src_idx, dst_idx, n; + pcb_pstk_tshape_t *ts; + rnd_coord_t crd; + DRAWOPTARG; + + RND_ACT_CONVARG(1+ao, FGW_PTR, PstkProtoEdit, proto = argv[1+ao].val.ptr_void); + RND_ACT_CONVARG(2+ao, FGW_STR, PstkProtoEdit, cmd = argv[2+ao].val.str); + + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[1+ao], PCB_PTR_DOMAIN_PSTK_PROTO) || (proto == NULL)) { + rnd_message(RND_MSG_ERROR, "PstkProtoEdit: invalid proto pointer\n"); + RND_ACT_IRES(-1); + return 0; + } + ts = &proto->tr.array[0]; + + switch(act_draw_keywords_sphash(cmd)) { + case act_draw_keywords_remove: + RND_ACT_CONVARG(3+ao, FGW_STR, PstkProtoEdit, tmp = argv[3+ao].val.str); + if (pcb_layer_typecomb_str2bits(tmp, &dlyt, &dlyc, 1) != 0) + return FGW_ERR_ARG_CONV; + pcb_pstk_proto_del_shape(proto, dlyt, dlyc); + break; + + case act_draw_keywords_copy: + RND_ACT_CONVARG(3+ao, FGW_STR, PstkProtoEdit, tmp = argv[3+ao].val.str); + if (pcb_layer_typecomb_str2bits(tmp, &dlyt, &dlyc, 1) != 0) + return FGW_ERR_ARG_CONV; + RND_ACT_CONVARG(4+ao, FGW_STR, PstkProtoEdit, tmp = argv[4+ao].val.str); + if (pcb_layer_typecomb_str2bits(tmp, &slyt, &slyc, 1) != 0) + return FGW_ERR_ARG_CONV; + + src_idx = pcb_pstk_get_shape_idx(ts, slyt, slyc); + if (src_idx < 0) { + RND_ACT_IRES(-1); + return 0; + } + dst_idx = pcb_pstk_get_shape_idx(ts, dlyt, dlyc); + for(n = 0; n < proto->tr.used; n++) { + if (dst_idx < 0) + dst_idx = pcb_pstk_alloc_shape_idx(proto, n); + else + pcb_pstk_shape_free(&proto->tr.array[n].shape[dst_idx]); + pcb_pstk_shape_copy(&proto->tr.array[n].shape[dst_idx], &proto->tr.array[n].shape[src_idx]); + proto->tr.array[n].shape[dst_idx].layer_mask = dlyt; + proto->tr.array[n].shape[dst_idx].comb = dlyc; + if (proto->tr.array[n].smirror) + pcb_pstk_shape_smirror(&proto->tr.array[n].shape[dst_idx]); + } + pcb_pstk_proto_update(proto); + RND_ACT_IRES(0); + return 0; + + case act_draw_keywords_hdia: + + RND_ACT_CONVARG(3+ao, FGW_COORD, PstkProtoEdit, crd = fgw_coord(&argv[3+ao])); + proto->hdia = crd; + pcb_pstk_proto_update(proto); + RND_ACT_IRES(0); + return 0; + + case act_draw_keywords_shape_line: + { + rnd_coord_t x1, y1, x2, y2, th; + int sq = 0; + + RND_ACT_CONVARG(3+ao, FGW_STR, PstkProtoEdit, tmp = argv[3+ao].val.str); + RND_ACT_CONVARG(4+ao, FGW_COORD, PstkProtoEdit, x1 = fgw_coord(&argv[4+ao])); + RND_ACT_CONVARG(5+ao, FGW_COORD, PstkProtoEdit, y1 = fgw_coord(&argv[5+ao])); + RND_ACT_CONVARG(6+ao, FGW_COORD, PstkProtoEdit, x2 = fgw_coord(&argv[6+ao])); + RND_ACT_CONVARG(7+ao, FGW_COORD, PstkProtoEdit, y2 = fgw_coord(&argv[7+ao])); + RND_ACT_CONVARG(8+ao, FGW_COORD, PstkProtoEdit, th = fgw_coord(&argv[8+ao])); + if (pcb_layer_typecomb_str2bits(tmp, &dlyt, &dlyc, 1) != 0) + return FGW_ERR_ARG_CONV; + + tmp = NULL; + RND_ACT_MAY_CONVARG(9+ao, FGW_STR, PstkProtoEdit, tmp = argv[9+ao].val.str); + if ((tmp != NULL) && (*tmp == 's')) + sq = 1; + + pcb_pstk_proto_del_shape(proto, dlyt, dlyc); + for(n = 0; n < proto->tr.used; n++) { + pcb_pstk_shape_t *sh = pcb_pstk_alloc_append_shape(&proto->tr.array[n]); + memset(sh, 0, sizeof(pcb_pstk_shape_t)); + sh->layer_mask = dlyt; + sh->comb = dlyc; + sh->shape = PCB_PSSH_LINE; + sh->data.line.x1 = x1; + sh->data.line.y1 = y1; + sh->data.line.x2 = x2; + sh->data.line.y2 = y2; + sh->data.line.thickness = th; + sh->data.line.square = sq; + } + } + break; + + default: + return FGW_ERR_ARG_CONV; + } + + RND_ACT_IRES(-1); + return 0; +} Index: tags/2.3.0/src_plugins/act_draw/keywords.sphash =================================================================== --- tags/2.3.0/src_plugins/act_draw/keywords.sphash (nonexistent) +++ tags/2.3.0/src_plugins/act_draw/keywords.sphash (revision 33253) @@ -0,0 +1,13 @@ +new +dup +insert +insert_dup +free +copy +remove +hdia +shape:line +unite +isect +sub +xor Index: tags/2.3.0/src_plugins/act_read/Makefile =================================================================== --- tags/2.3.0/src_plugins/act_read/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/act_read/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_act_read + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/act_read/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/act_read/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/act_read/Plug.tmpasm (revision 33253) @@ -0,0 +1,13 @@ +put /local/pcb/mod {act_read} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/act_read/act_read.o + $(PLUGDIR)/act_read/keywords_sphash.o +@] +put /local/pcb/mod/SPHASH {$(PLUGDIR)/act_read/keywords.sphash} + + +switch /local/pcb/act_read/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/act_read/act_geo.c =================================================================== --- tags/2.3.0/src_plugins/act_read/act_geo.c (nonexistent) +++ tags/2.3.0/src_plugins/act_read/act_geo.c (revision 33253) @@ -0,0 +1,137 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "board.h" +#include +#include +#include +#include "idpath.h" +#include "search.h" +#include "find.h" + +static const char pcb_acts_IsPointOnLine[] = "IsPointOnLine(x, y, r, idpath)"; +static const char pcb_acth_IsPointOnLine[] = "Returns 1 if point x;y with radius r is on the line addressed by idpath, 0 else."; +static fgw_error_t pcb_act_IsPointOnLine(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + rnd_coord_t x, y, r; + pcb_idpath_t *idp; + pcb_any_obj_t *obj; + + RND_ACT_CONVARG(1, FGW_COORD, IsPointOnLine, x = fgw_coord(&argv[1])); + RND_ACT_CONVARG(2, FGW_COORD, IsPointOnLine, y = fgw_coord(&argv[2])); + RND_ACT_CONVARG(3, FGW_COORD, IsPointOnLine, r = fgw_coord(&argv[3])); + RND_ACT_CONVARG(4, FGW_IDPATH, IsPointOnLine, idp = fgw_idpath(&argv[4])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[4], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + obj = pcb_idpath2obj(pcb, idp); + if ((obj == NULL) || (obj->type != PCB_OBJ_LINE)) + return FGW_ERR_ARG_CONV; + + RND_ACT_IRES(pcb_is_point_on_line(x, y, r, (pcb_line_t *)obj)); + return 0; +} + + +static const char pcb_acts_IsPointOnArc[] = "IsPointOnArc(x, y, r, idpath)"; +static const char pcb_acth_IsPointOnArc[] = "Returns 1 if point x;y with radius r is on the arc addressed by idpath, 0 else."; +static fgw_error_t pcb_act_IsPointOnArc(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + rnd_coord_t x, y, r; + pcb_idpath_t *idp; + pcb_any_obj_t *obj; + + RND_ACT_CONVARG(1, FGW_COORD, IsPointOnArc, x = fgw_coord(&argv[1])); + RND_ACT_CONVARG(2, FGW_COORD, IsPointOnArc, y = fgw_coord(&argv[2])); + RND_ACT_CONVARG(3, FGW_COORD, IsPointOnArc, r = fgw_coord(&argv[3])); + RND_ACT_CONVARG(4, FGW_IDPATH, IsPointOnArc, idp = fgw_idpath(&argv[4])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[4], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + obj = pcb_idpath2obj(pcb, idp); + if ((obj == NULL) || (obj->type != PCB_OBJ_ARC)) + return FGW_ERR_ARG_CONV; + + RND_ACT_IRES(pcb_is_point_on_arc(x, y, r, (pcb_arc_t *)obj)); + return 0; +} + + +static const char pcb_acts_IntersectObjObj[] = "IntersectObjObj(idpath, idpath)"; +static const char pcb_acth_IntersectObjObj[] = "Returns 1 if point x;y with radius r is on the arc addressed by idpath, 0 else."; +static fgw_error_t pcb_act_IntersectObjObj(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + pcb_idpath_t *idp1, *idp2; + pcb_any_obj_t *obj1, *obj2; + + RND_ACT_CONVARG(1, FGW_IDPATH, IntersectObjObj, idp1 = fgw_idpath(&argv[1])); + RND_ACT_CONVARG(2, FGW_IDPATH, IntersectObjObj, idp2 = fgw_idpath(&argv[2])); + if ((idp1 == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[1], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + if ((idp2 == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + obj1 = pcb_idpath2obj(pcb, idp1); + obj2 = pcb_idpath2obj(pcb, idp2); + if ((obj1 == NULL) || ((obj1->type & PCB_OBJ_CLASS_REAL) == 0) || (obj2 == NULL) || ((obj2->type & PCB_OBJ_CLASS_REAL) == 0)) + return FGW_ERR_ARG_CONV; + + RND_ACT_IRES(pcb_intersect_obj_obj(pcb_find0, obj1, obj2)); + return 0; +} + + +static const char pcb_acts_ObjCenter[] = "ObjCenter(idpath, x|y)"; +static const char pcb_acth_ObjCenter[] = "Returns the x or y coordinate of the center of an object"; +static fgw_error_t pcb_act_ObjCenter(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + pcb_idpath_t *idp; + pcb_any_obj_t *obj; + const char *which; + rnd_coord_t x, y; + + RND_ACT_CONVARG(1, FGW_IDPATH, ObjCenter, idp = fgw_idpath(&argv[1])); + RND_ACT_CONVARG(2, FGW_STR, ObjCenter, which = argv[2].val.str); + + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[1], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + obj = pcb_idpath2obj(pcb, idp); + if ((obj == NULL) || ((obj->type & PCB_OBJ_CLASS_REAL) == 0)) + return FGW_ERR_ARG_CONV; + + pcb_obj_center(obj, &x, &y); + res->type = FGW_DOUBLE; + switch(*which) { + case 'x': case 'X': res->val.nat_double = x; return 0; + case 'y': case 'Y': res->val.nat_double = y; return 0; + } + + return FGW_ERR_ARG_CONV; +} + Index: tags/2.3.0/src_plugins/act_read/act_idpath.c =================================================================== --- tags/2.3.0/src_plugins/act_read/act_idpath.c (nonexistent) +++ tags/2.3.0/src_plugins/act_read/act_idpath.c (revision 33253) @@ -0,0 +1,228 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* includeed from act_read.c */ + +static const char pcb_acts_IDPList[] = + "IDPList(alloc)\n" + "IDPList(free|clear|print|dup|length, list)\n" + "IDPList(get|pop|remove, list, idx)\n" + "IDPList(prepend|append|push, list, idpath)" + ; +static const char pcb_acth_IDPList[] = "Basic idpath list manipulation."; +static fgw_error_t pcb_act_IDPList(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd_; + pcb_idpath_list_t *list; + pcb_idpath_t *idp; + int cmd; + long idx; + + RND_ACT_CONVARG(1, FGW_STR, IDPList, cmd_ = argv[1].val.str); + + cmd = act_read_keywords_sphash(cmd_); + if (cmd == act_read_keywords_alloc) { + list = calloc(sizeof(pcb_idpath_list_t), 1); + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH_LIST, FGW_PTR | FGW_STRUCT, list); + return 0; + } + RND_ACT_CONVARG(2, FGW_IDPATH_LIST, IDPList, list = fgw_idpath_list(&argv[2])); + + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH_LIST)) + return FGW_ERR_PTR_DOMAIN; + + switch(cmd) { + case act_read_keywords_clear: + pcb_idpath_list_clear(list); + RND_ACT_IRES(0); + return 0; + + case act_read_keywords_length: + RND_ACT_IRES(pcb_idpath_list_length(list)); + return 0; + + case act_read_keywords_free: + fgw_ptr_unreg(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH_LIST); + pcb_idpath_list_clear(list); + free(list); + RND_ACT_IRES(0); + return 0; + + case act_read_keywords_append: + case act_read_keywords_push: + case act_read_keywords_prepend: + RND_ACT_CONVARG(3, FGW_IDPATH, IDPList, idp = fgw_idpath(&argv[3])); + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[3], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + if (cmd == act_read_keywords_append) + pcb_idpath_list_append(list, idp); + else /* prepend or push */ + pcb_idpath_list_insert(list, idp); + RND_ACT_IRES(0); + return 0; + + case act_read_keywords_remove: + RND_ACT_CONVARG(3, FGW_LONG, IDPList, idx = argv[3].val.nat_long); + idp = pcb_idpath_list_nth(list, idx); + if (idp == NULL) { + RND_ACT_IRES(-1); + return 0; + } + pcb_idpath_list_remove(idp); + RND_ACT_IRES(0); + return 0; + + case act_read_keywords_get: + RND_ACT_CONVARG(3, FGW_LONG, IDPList, idx = argv[3].val.nat_long); + idp = pcb_idpath_list_nth(list, idx); + if (idp == NULL) { + res->type = FGW_PTR; + res->val.ptr_struct = NULL; + return 0; + } + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + return 0; + + case act_read_keywords_pop: + idp = pcb_idpath_list_first(list); + if (idp == NULL) { + res->type = FGW_PTR; + res->val.ptr_struct = NULL; + return 0; + } + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + pcb_idpath_list_remove(idp); + return 0; + + case act_read_keywords_print: + { + gds_t tmp; + int first = 1; + + gds_init(&tmp); + for(idp = pcb_idpath_list_first(list); idp != NULL; idp = pcb_idpath_list_next(idp)) { + if (!first) + gds_append(&tmp, ' '); + pcb_append_idpath(&tmp, idp, 0); + first = 0; + } + res->type = FGW_STR | FGW_DYN; + res->val.str = tmp.array; + } + return 0; + + } + + return -1; +} + +static const char pcb_acts_IDP[] = "IDP([print|free|dup], idpath)\n"; +static const char pcb_acth_IDP[] = "Basic idpath manipulation."; +static fgw_error_t pcb_act_IDP(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *cmd; + pcb_idpath_t *idp; + pcb_any_obj_t *obj; + + RND_ACT_CONVARG(1, FGW_STR, IDP, cmd = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_IDPATH, IDPList, idp = fgw_idpath(&argv[2])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + + + switch(act_read_keywords_sphash(cmd)) { + case act_read_keywords_free: + pcb_idpath_list_remove(idp); + fgw_ptr_unreg(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH); + free(idp); + RND_ACT_IRES(0); + return 0; + + case act_read_keywords_dup: + obj = pcb_idpath2obj(pcb, idp); + idp = pcb_obj2idpath(obj); + res->type = FGW_IDPATH; + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, idp); + return 0; + + case act_read_keywords_print: + res->type = FGW_STR | FGW_DYN; + res->val.str = pcb_idpath2str(idp, 0); + return 0; + } + + return -1; +} + +static const char pcb_acts_GetParentData[] = "GetParentData([root_data,] idpath)\n"; +static const char pcb_acth_GetParentData[] = "Return the closest upstream pcb_data_t * parent of an object"; +static fgw_error_t pcb_act_GetParentData(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + pcb_idpath_t *idp; + pcb_data_t *root_data = pcb->Data; + int iidx = 1; + pcb_any_obj_t *obj; + + res->type = FGW_PTR | FGW_STRUCT; + res->val.ptr_void = NULL; + + if (argc > 2) { + RND_ACT_CONVARG(1, FGW_DATA, GetParentData, root_data = fgw_data(&argv[1])); + iidx++; + } + + RND_ACT_CONVARG(iidx, FGW_IDPATH, IDPList, idp = fgw_idpath(&argv[iidx])); + if ((idp == NULL) || !fgw_ptr_in_domain(&rnd_fgw, &argv[iidx], RND_PTR_DOMAIN_IDPATH)) + return FGW_ERR_PTR_DOMAIN; + + obj = pcb_idpath2obj_in(root_data, idp); + if (obj == NULL) + return 0; + + switch(obj->parent_type) { + case PCB_PARENT_LAYER: + assert(obj->parent.layer != NULL); + assert(obj->parent.layer->parent_type == PCB_PARENT_DATA); + res->val.ptr_void = obj->parent.layer->parent.data; + break; + case PCB_PARENT_SUBC: + assert(obj->parent.subc != NULL); + assert(obj->parent.subc->parent_type == PCB_PARENT_DATA); + res->val.ptr_void = obj->parent.subc->parent.data; + break; + case PCB_PARENT_DATA: + res->val.ptr_void = obj->parent.data; + break; + case PCB_PARENT_BOARD: + case PCB_PARENT_NET: + case PCB_PARENT_UI: + case PCB_PARENT_INVALID: + break; + } + return 0; +} Index: tags/2.3.0/src_plugins/act_read/act_layer.c =================================================================== --- tags/2.3.0/src_plugins/act_read/act_layer.c (nonexistent) +++ tags/2.3.0/src_plugins/act_read/act_layer.c (revision 33253) @@ -0,0 +1,148 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "board.h" +#include "data.h" +#include "layer.h" +#include +#include "actions_pcb.h" +#include +#include +#include "idpath.h" +#include "search.h" +#include "find.h" + +static void append_type_bit(void *ctx, pcb_layer_type_t bit, const char *name, int class, const char *class_name) +{ + gds_t *s = ctx; + if (s->used > 0) + gds_append(s, ','); + gds_append_str(s, name); +} + +static const char pcb_acts_ReadGroup[] = + "ReadGroup(length)\n" + "ReadGroup(field, group, [init_invis|ltype|ltypestr|ltypehas|name|open|purpose|vis|length])\n" + "ReadGroup(layerid, group, idx)\n" + ; +static const char pcb_acth_ReadGroup[] = "Length returns the number of groups on the current PCB. Field returns one of the fields of the group named in groupid. Layerid returns the integer layer ID (as interpreted within data) for the idxth layer of the group."; +static fgw_error_t pcb_act_ReadGroup(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int cmd, fld; + char *cmds, *flds, *target; + rnd_layergrp_id_t gid; + pcb_layergrp_t *grp; + pcb_layer_type_t lyt; + long idx; + + RND_ACT_CONVARG(1, FGW_STR, ReadGroup, cmds = argv[1].val.str); + cmd = act_read_keywords_sphash(cmds); + switch(cmd) { + case act_read_keywords_length: + res->type = FGW_LONG; res->val.nat_long = pcb->LayerGroups.len; + return 0; + case act_read_keywords_layerid: + RND_ACT_CONVARG(2, FGW_LAYERGRPID, ReadGroup, gid = fgw_layergrpid(&argv[2])); + grp = pcb_get_layergrp(pcb, gid); + if (grp == NULL) + return FGW_ERR_ARG_CONV; + RND_ACT_CONVARG(3, FGW_LONG, ReadGroup, idx = argv[3].val.nat_long); + if ((idx < 0) || (idx >= grp->len)) + return FGW_ERR_ARG_CONV; + res->type = FGW_LONG; res->val.nat_long = grp->lid[idx]; + return 0; + case act_read_keywords_field: + RND_ACT_CONVARG(2, FGW_LAYERGRPID, ReadGroup, gid = fgw_layergrpid(&argv[2])); + grp = pcb_get_layergrp(pcb, gid); + if (grp == NULL) + return FGW_ERR_ARG_CONV; + RND_ACT_CONVARG(3, FGW_STR, ReadGroup, flds = argv[3].val.str); + fld = act_read_keywords_sphash(flds); + switch(fld) { + case act_read_keywords_name: + res->type = FGW_STR; res->val.str = grp->name; + return 0; + case act_read_keywords_purpose: + res->type = FGW_STR; res->val.str = grp->purpose; + return 0; + case act_read_keywords_ltype: + res->type = FGW_LONG; res->val.nat_long = grp->ltype; + return 0; + case act_read_keywords_ltype_anywhere: + res->type = FGW_LONG; res->val.nat_long = grp->ltype & PCB_LYT_ANYWHERE; + return 0; + case act_read_keywords_ltype_anything: + res->type = FGW_LONG; res->val.nat_long = grp->ltype & PCB_LYT_ANYTHING; + return 0; + case act_read_keywords_ltypestr: + lyt = grp->ltype; + ltypestr:; + { + gds_t tmp; + gds_init(&tmp); + pcb_layer_type_map(lyt, &tmp, append_type_bit); + res->type = FGW_STR | FGW_DYN; res->val.str = tmp.array; + } + return 0; + case act_read_keywords_ltypehas: + RND_ACT_CONVARG(4, FGW_STR, ReadGroup, target = argv[4].val.str); + lyt = pcb_layer_type_str2bit(target); + if (lyt == 0) { + rnd_message(RND_MSG_ERROR, "ReadGroup(): unknown layer type name: '%s'\n", target); + return FGW_ERR_ARG_CONV; + } + RND_ACT_IRES(!!(grp->ltype & lyt)); + return 0; + case act_read_keywords_ltypestr_anything: + lyt = grp->ltype & PCB_LYT_ANYTHING; + goto ltypestr; + case act_read_keywords_ltypestr_anywhere: + lyt = grp->ltype & PCB_LYT_ANYWHERE; + goto ltypestr; + case act_read_keywords_length: + res->type = FGW_LONG; res->val.nat_long = grp->len; + return 0; + case act_read_keywords_vis: + res->type = FGW_INT; res->val.nat_int = grp->vis; + return 0; + case act_read_keywords_init_invis: + res->type = FGW_INT; res->val.nat_int = grp->init_invis; + return 0; + case act_read_keywords_open: + res->type = FGW_INT; res->val.nat_int = grp->open; + return 0; + default: + return FGW_ERR_ARG_CONV; + } + default: + return FGW_ERR_ARG_CONV; + } + + return FGW_ERR_ARG_CONV; +} Index: tags/2.3.0/src_plugins/act_read/act_read.c =================================================================== --- tags/2.3.0/src_plugins/act_read/act_read.c (nonexistent) +++ tags/2.3.0/src_plugins/act_read/act_read.c (revision 33253) @@ -0,0 +1,134 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "board.h" +#include "data_parent.h" +#include +#include "crosshair.h" +#include +#include +#include "idpath.h" +#include "obj_subc.h" + +#include "keywords_sphash.h" + +#define PCB (do_not_use_PCB) + +#include "act_idpath.c" +#include "act_geo.c" +#include "act_layer.c" + +static const char pcb_acts_GetValue[] = "GetValue(input, units, relative, default_unit)"; +static const char pcb_acth_GetValue[] = "Convert a coordinate value. Returns an unitless double or FGW_ERR_ARG_CONV. The 3rd parameter controls whether to require relative coordinates (+- prefix). Wraps rnd_get_value_ex()."; +static fgw_error_t pcb_act_GetValue(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *input, *units, *def_unit; + int relative, a; + double v; + rnd_bool success; + + RND_ACT_CONVARG(1, FGW_STR, GetValue, input = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, GetValue, units = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_INT, GetValue, relative = argv[3].val.nat_int); + RND_ACT_CONVARG(4, FGW_STR, GetValue, def_unit = argv[1].val.str); + + if (*units == '\0') + units = NULL; + + v = rnd_get_value_ex(input, units, &a, NULL, def_unit, &success); + if (!success || (relative && a)) + return FGW_ERR_ARG_CONV; + + res->type = FGW_DOUBLE; + res->val.nat_double = v; + return 0; +} + +static const char pcb_acts_GetMark[] = "GetMark(active|user_placed|x|y)"; +static const char pcb_acth_GetMark[] = "Return mark properties in numeric form."; +static fgw_error_t pcb_act_GetMark(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd; + + RND_ACT_CONVARG(1, FGW_STR, GetMark, cmd = argv[1].val.str); + switch(*cmd) { + case 'a': res->type = FGW_INT; res->val.nat_int = pcb_marked.status; break; + case 'u': res->type = FGW_INT; res->val.nat_int = pcb_marked.user_placed; break; + case 'x': res->type = FGW_DOUBLE; res->val.nat_double = pcb_marked.X; break; + case 'y': res->type = FGW_DOUBLE; res->val.nat_double = pcb_marked.Y; break; + default: + RND_ACT_FAIL(GetMark); + } + return 0; +} + +static int flg_error(const char *msg) +{ + rnd_message(RND_MSG_ERROR, "act_read flag conversion error: %s\n", msg); + return 0; +} + +#define DRAWOPTARG \ + int noundo = 0, ao = 0; \ + if ((argv[1].type == FGW_STR) && (strcmp(argv[1].val.str, "noundo") == 0)) { \ + noundo = 1; \ + ao++; \ + } + + +rnd_action_t act_read_action_list[] = { + {"GetValue", pcb_act_GetValue, pcb_acth_GetValue, pcb_acts_GetValue}, + {"IDPList", pcb_act_IDPList, pcb_acth_IDPList, pcb_acts_IDPList}, + {"IDP", pcb_act_IDP, pcb_acth_IDP, pcb_acts_IDP}, + {"GetParentData", pcb_act_GetParentData, pcb_acth_GetParentData, pcb_acts_GetParentData}, + + {"GetMark", pcb_act_GetMark, pcb_acth_GetMark, pcb_acts_GetMark}, + + {"ReadGroup", pcb_act_ReadGroup, pcb_acth_ReadGroup, pcb_acts_ReadGroup}, + + {"IsPointOnArc", pcb_act_IsPointOnArc, pcb_acth_IsPointOnArc, pcb_acts_IsPointOnArc}, + {"IsPointOnLine", pcb_act_IsPointOnLine, pcb_acth_IsPointOnLine, pcb_acts_IsPointOnLine}, + {"IntersectObjObj", pcb_act_IntersectObjObj, pcb_acth_IntersectObjObj, pcb_acts_IntersectObjObj}, + {"ObjCenter", pcb_act_ObjCenter, pcb_acth_ObjCenter, pcb_acts_ObjCenter} +}; + +static const char *act_read_cookie = "act_read"; + +int pplg_check_ver_act_read(int ver_needed) { return 0; } + +void pplg_uninit_act_read(void) +{ + rnd_remove_actions_by_cookie(act_read_cookie); +} + +int pplg_init_act_read(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(act_read_action_list, act_read_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/act_read/act_read.pup =================================================================== --- tags/2.3.0/src_plugins/act_read/act_read.pup (nonexistent) +++ tags/2.3.0/src_plugins/act_read/act_read.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short action wrappers for data access +$long Data access related API as actions +$state works +$package (core) +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/act_read/keywords.sphash =================================================================== --- tags/2.3.0/src_plugins/act_read/keywords.sphash (nonexistent) +++ tags/2.3.0/src_plugins/act_read/keywords.sphash (revision 33253) @@ -0,0 +1,27 @@ +alloc +append +clear +dup +field +free +get +layerid +length +pop +push +prepend +print +remove + +init_invis +ltype +ltypehas +ltype_anything +ltype_anywhere +ltypestr +ltypestr_anything +ltypestr_anywhere +name +open +purpose +vis Index: tags/2.3.0/src_plugins/ar_cpcb/Makefile =================================================================== --- tags/2.3.0/src_plugins/ar_cpcb/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/ar_cpcb/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_ar_cpcb + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/ar_cpcb/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/ar_cpcb/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/ar_cpcb/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {ar_cpcb} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/ar_cpcb/ar_cpcb.o +@] + +switch /local/pcb/ar_cpcb/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/ar_cpcb/ar_cpcb.c =================================================================== --- tags/2.3.0/src_plugins/ar_cpcb/ar_cpcb.c (nonexistent) +++ tags/2.3.0/src_plugins/ar_cpcb/ar_cpcb.c (revision 33253) @@ -0,0 +1,425 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * auto routing with c-pcb (selective import/export in c-pcb format) + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "data.h" +#include +#include +#include +#include "conf_core.h" +#include "obj_pstk_inlines.h" +#include "src_plugins/lib_compat_help/pstk_compat.h" +#include "src_plugins/lib_netmap/netmap.h" + +static const char *cpcb_cookie = "cpcb plugin"; + +typedef struct { + int maxlayer; + pcb_layer_t *copper[PCB_MAX_LAYERGRP]; +} cpcb_layers_t; + +typedef struct { + pcb_netmap_t netmap; + + /* int -> net conversion */ + pcb_net_t **i2n; + int maxnets; + + /* net->int conversion */ + htpi_t n2i; +} cpcb_netmap_t; + +static void cpcb_map_layers(pcb_board_t *pcb, cpcb_layers_t *dst) +{ + int gid; + pcb_layergrp_t *grp; + /* map copper layers from top to bottom */ + dst->maxlayer = 0; + for(gid = 0, grp = pcb->LayerGroups.grp; gid < pcb->LayerGroups.len; gid++,grp++) { + if ((grp->ltype & PCB_LYT_COPPER) && (grp->len > 0) && (grp->vis)) { + dst->copper[dst->maxlayer] = pcb_get_layer(pcb->Data, grp->lid[0]); + dst->maxlayer++; + } + } +} + +static int cpcb_map_nets(pcb_board_t *pcb, cpcb_netmap_t *dst) +{ + htpp_entry_t *e; + long id; + + if (pcb_netmap_init(&dst->netmap, pcb, 0) != 0) + return -1; + + dst->maxnets = 0; + for(e = htpp_first(&dst->netmap.o2n); e != NULL; e = htpp_next(&dst->netmap.o2n, e)) + dst->maxnets++; + + if (dst->maxnets == 0) + return -1; + + dst->i2n = malloc(sizeof(pcb_net_t *) * dst->maxnets); + htpi_init(&dst->n2i, ptrhash, ptrkeyeq); + + id = 0; + for(e = htpp_first(&dst->netmap.n2o); e != NULL; e = htpp_next(&dst->netmap.n2o, e)) { + dst->i2n[id] = (pcb_net_t *)e->key; + htpi_set(&dst->n2i, e->key, id); + id++; + } + + return 0; +} + + +static void cpcb_free_nets(cpcb_netmap_t *dst) +{ + htpi_uninit(&dst->n2i); + free(dst->i2n); + pcb_netmap_uninit(&dst->netmap); +} + + +static int cpcb_load(pcb_board_t *pcb, FILE *f, cpcb_layers_t *stack, cpcb_netmap_t *nmap) +{ + gsx_parse_res_t res; + gsxl_dom_t dom; + gsxl_node_t *rn, *n; + int c; + + /* low level s-expression parse */ + gsxl_init(&dom, gsxl_node_t); + dom.parse.line_comment_char = '#'; + gsxl_parse_char(&dom, '('); /* have to fake the whole file is a single expression */ + do { + c = fgetc(f); + if (c == EOF) + gsxl_parse_char(&dom, ')'); /* have to fake the whole file is a single expression */ + } while((res = gsxl_parse_char(&dom, c)) == GSX_RES_NEXT); + if (res != GSX_RES_EOE) + return -1; + + for(rn = gsxl_children(dom.root); rn != NULL; rn = gsxl_next(rn)) { + int numch = 0; + gsxl_node_t *p, *nid, *ntr, *nvr, *ngap, *npads, *npaths, *nx, *ny, *nl; + rnd_coord_t thick, clear, via_dia; + char *end; + + for(n = gsxl_children(rn); n != NULL; n = gsxl_next(n)) numch++; + switch(numch) { + case 0: + printf("EOF\n"); + break; + case 3: + printf("dim: %s %s ly=%s\n", gsxl_nth(rn, 1)->str, gsxl_nth(rn, 2)->str, gsxl_nth(rn, 3)->str); + break; + case 6: /* tracks */ + nid = gsxl_nth(rn, 1); + ntr = gsxl_next(nid); thick = 2*RND_MM_TO_COORD(strtod(ntr->str, NULL)); + nvr = gsxl_next(ntr); via_dia = 2*RND_MM_TO_COORD(strtod(nvr->str, NULL)); + ngap = gsxl_next(nvr); clear = RND_MM_TO_COORD(strtod(ngap->str, NULL)); + npads = gsxl_next(ngap); + npaths = gsxl_next(npads); + + for(n = gsxl_children(npaths); n != NULL; n = gsxl_next(n)) { /* iterate over all paths of the track */ + rnd_coord_t lx, ly, x, y; + int len = 0, lidx, llidx; + + for(p = gsxl_children(n); p != NULL; p = gsxl_next(p)) { /* iterate over all points of the path */ + pcb_line_t *line; + nx = gsxl_children(p); x = RND_MM_TO_COORD(strtod(nx->str, NULL)); + ny = gsxl_next(nx); y = RND_MM_TO_COORD(strtod(ny->str, NULL)); + nl = gsxl_next(ny); + + lidx = strtol(nl->str, &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Ignoring invalid layer index '%s' (not an integer) in line %ld\n", nl->str, (long)nl->line); + continue; + } + if ((lidx < 0) || (lidx >= stack->maxlayer)) { + rnd_message(RND_MSG_ERROR, "Ignoring invalid layer index '%s' (out of range) in line %ld\n", nl->str, (long)nl->line); + continue; + } + + if (len > 0) { + if (llidx != lidx) { + if ((lx == x) && (ly == y)) { + pcb_pstk_t *ps = pcb_pstk_new_compat_via(pcb->Data, -1, x, y, + conf_core.design.via_drilling_hole, via_dia, conf_core.design.clearance, + 0, PCB_PSTK_COMPAT_ROUND, rnd_true); + } + else + rnd_message(RND_MSG_ERROR, "Invalid via: not vertical, in line %ld:%ld\n", (long)nl->line, (long)nl->col); + } + else + line = pcb_line_new(stack->copper[lidx], lx, ly, x, y, thick, clear, pcb_flag_make(PCB_FLAG_CLEARLINE)); + } + lx = x; + ly = y; + llidx = lidx; + len++; + } + } + break; + } + } + + return 0; +} + +static void cpcb_print_pads(pcb_board_t *pcb, FILE *f, pcb_any_obj_t *o, cpcb_layers_t *stack) +{ + int lidx; + + switch(o->type) { + case PCB_OBJ_PSTK: + for(lidx = 0; lidx < stack->maxlayer; lidx++) { + int n; + pcb_pstk_t *ps = (pcb_pstk_t *)o; + pcb_pstk_shape_t *shp = pcb_pstk_shape_at(pcb, ps, stack->copper[lidx]); + if (shp == NULL) + continue; + switch(shp->shape) { + case PCB_PSSH_LINE: + case PCB_PSSH_HSHADOW: + TODO("generate a poly"); + break; + case PCB_PSSH_POLY: + rnd_fprintf(f, "(0 %mm (%mm %mm %d) (", conf_core.design.clearance, ps->x, ps->y, lidx); + for(n = 0; n < shp->data.poly.len; n++) + rnd_fprintf(f, "(%mm %mm)", shp->data.poly.x[n], shp->data.poly.y[n]); + fprintf(f, "))"); + break; + case PCB_PSSH_CIRC: + rnd_fprintf(f, "(%mm %mm (%mm %mm %d) ())", shp->data.circ.dia/2, conf_core.design.clearance, ps->x, ps->y, lidx); + break; + } + } + break; + case PCB_OBJ_LINE: + break; + case PCB_OBJ_POLY: + break; + case PCB_OBJ_TEXT: + case PCB_OBJ_ARC: + case PCB_OBJ_GFX: + break; + +TODO("subc-in-subc: subc as terminal") + case PCB_OBJ_SUBC: + break; + + /* these can not ever be terminals */ + case PCB_OBJ_VOID: + case PCB_OBJ_RAT: + case PCB_OBJ_NET: + case PCB_OBJ_NET_TERM: + case PCB_OBJ_LAYER: + case PCB_OBJ_LAYERGRP: + break; + } +} + +static int cpcb_save(pcb_board_t *pcb, FILE *f, cpcb_layers_t *stack, cpcb_netmap_t *nmap) +{ + htpp_entry_t *e; + + /* print dims */ + rnd_fprintf(f, "(%d %d %d)\n", (int)(RND_COORD_TO_MM(pcb->hidlib.size_x)+0.5), (int)(RND_COORD_TO_MM(pcb->hidlib.size_y)+0.5), stack->maxlayer); + + /* print tracks */ + for(e = htpp_first(&nmap->netmap.n2o); e != NULL; e = htpp_next(&nmap->netmap.n2o, e)) { + pcb_net_t *net = e->key; + dyn_obj_t *o, *olist = e->value; + long id = htpi_get(&nmap->n2i, net); + +/* rnd_fprintf(f, "# %s: %ld\n", net->Name, id);*/ + rnd_fprintf(f, "(%ld %mm %mm %mm\n", id, conf_core.design.line_thickness/2, conf_core.design.via_thickness/2, conf_core.design.clearance); + + /* print pads (terminals) */ + rnd_fprintf(f, " ("); + for(o = olist; o != NULL; o = o->next) + if (o->obj->term != NULL) + cpcb_print_pads(pcb, f, o->obj, stack); + rnd_fprintf(f, ")\n"); + + fprintf(f, " ()\n"); + + fprintf(f, ")\n"); + } + + /* print eof marker */ + fprintf(f, "()\n"); + return 0; +} + +static const char pcb_acts_import_cpcb[] = "ImportcpcbFrom(filename)"; +static const char pcb_acth_import_cpcb[] = "Loads the auto-routed tracks from the specified c-pcb output."; +fgw_error_t pcb_act_import_cpcb(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fn; + FILE *f; + cpcb_layers_t stk; + + RND_ACT_CONVARG(1, FGW_STR, import_cpcb, fn = argv[1].val.str); + + f = rnd_fopen(&PCB->hidlib, fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can not open %s for read\n", fn); + RND_ACT_IRES(-1); + return 0; + } + + cpcb_map_layers(PCB, &stk); + cpcb_load(PCB, f, &stk, NULL); + + fclose(f); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_export_cpcb[] = "ExportcpcbTo(filename)"; +static const char pcb_acth_export_cpcb[] = "Dumps the current board in c-pcb format."; +fgw_error_t pcb_act_export_cpcb(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fn; + FILE *f; + cpcb_layers_t stk; + cpcb_netmap_t nmap; + + RND_ACT_CONVARG(1, FGW_STR, export_cpcb, fn = argv[1].val.str); + + f = rnd_fopen(&PCB->hidlib, fn, "w"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can not open %s for write\n", fn); + RND_ACT_IRES(-1); + return 0; + } + + if (cpcb_map_nets(PCB, &nmap) != 0) { + fclose(f); + rnd_message(RND_MSG_ERROR, "Failed to map nets\n"); + RND_ACT_IRES(-1); + return 0; + } + + cpcb_map_layers(PCB, &stk); + cpcb_save(PCB, f, &stk, &nmap); + cpcb_free_nets(&nmap); + + fclose(f); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_cpcb[] = "cpcb(board|selected, [command])"; +static const char pcb_acth_cpcb[] = "Executed external autorouter cpcb to route the board or parts of the board"; +fgw_error_t pcb_act_cpcb(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *scope, *cmd = "cpcb", *tmpfn = "cpcb.tmp"; + char *cmdline; + FILE *f; + cpcb_layers_t stk; + cpcb_netmap_t nmap; + + RND_ACT_CONVARG(1, FGW_STR, cpcb, scope = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, cpcb, cmd = argv[2].val.str); + + if (strcmp(scope, "board") != 0) { + rnd_message(RND_MSG_ERROR, "Only board routing is supported at the moment\n"); + RND_ACT_IRES(-1); + return 0; + } + + f = rnd_fopen(&PCB->hidlib, tmpfn, "w"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can not open temp file %s for write\n", tmpfn); + RND_ACT_IRES(-1); + return 0; + } + + if (cpcb_map_nets(PCB, &nmap) != 0) { + fclose(f); + rnd_message(RND_MSG_ERROR, "Failed to map nets\n"); + RND_ACT_IRES(-1); + return 0; + } + + cpcb_map_layers(PCB, &stk); + cpcb_save(PCB, f, &stk, &nmap); + fclose(f); + + cmdline = rnd_strdup_printf("%s < %s", cmd, tmpfn); + f = rnd_popen(&PCB->hidlib, cmdline, "r"); + if (f != NULL) { + cpcb_load(PCB, f, &stk, NULL); + pclose(f); + RND_ACT_IRES(0); + } + else { + rnd_message(RND_MSG_ERROR, "Failed to execute c-pcb\n"); + RND_ACT_IRES(-1); + return 0; + } + +/* rnd_remove(&PCB->hidlib, tmpfn);*/ + free(cmdline); + cpcb_free_nets(&nmap); + return 0; +} + +static rnd_action_t cpcb_action_list[] = { + {"ImportcpcbFrom", pcb_act_import_cpcb, pcb_acth_import_cpcb, pcb_acts_import_cpcb}, + {"ExportcpcbTo", pcb_act_export_cpcb, pcb_acth_export_cpcb, pcb_acts_export_cpcb}, + {"cpcb", pcb_act_cpcb, pcb_acth_cpcb, pcb_acts_cpcb} +}; + +int pplg_check_ver_ar_cpcb(int ver_needed) { return 0; } + +void pplg_uninit_ar_cpcb(void) +{ + rnd_remove_actions_by_cookie(cpcb_cookie); +} + + +int pplg_init_ar_cpcb(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(cpcb_action_list, cpcb_cookie) + + return 0; +} Index: tags/2.3.0/src_plugins/ar_cpcb/ar_cpcb.pup =================================================================== --- tags/2.3.0/src_plugins/ar_cpcb/ar_cpcb.pup (nonexistent) +++ tags/2.3.0/src_plugins/ar_cpcb/ar_cpcb.pup (revision 33253) @@ -0,0 +1,11 @@ +$class feature +$short autoroute with c-pcb +$long Autoroute using external tool c-pcb +$state WIP +$package auto +default buildin +dep lib_gensexpr +dep lib_compat_help +dep lib_netmap +autoload 1 + Index: tags/2.3.0/src_plugins/ar_extern/Makefile =================================================================== --- tags/2.3.0/src_plugins/ar_extern/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/ar_extern/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_ar_extern + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/ar_extern/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/ar_extern/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/ar_extern/Plug.tmpasm (revision 33253) @@ -0,0 +1,15 @@ +put /local/pcb/mod {ar_extern} +put /local/pcb/mod/MENUFILE {ar_extern-menu.lht} +put /local/pcb/mod/MENUVAR {ar_extern_menu} +put /local/pcb/mod/CONF {$(PLUGDIR)/ar_extern/ar_extern_conf.h} +put /local/pcb/mod/CONFFILE {ar_extern.conf} +put /local/pcb/mod/CONFVAR {ar_extern_conf_internal} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/ar_extern/ar_extern.o +@] + +switch /local/pcb/ar_extern/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/ar_extern/ar_extern-menu.lht =================================================================== --- tags/2.3.0/src_plugins/ar_extern/ar_extern-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/ar_extern/ar_extern-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@autoroute { + li:submenu { + ha:External autorouter = { action=ExtRoute() } + } + } + } +} Index: tags/2.3.0/src_plugins/ar_extern/ar_extern.c =================================================================== --- tags/2.3.0/src_plugins/ar_extern/ar_extern.c (nonexistent) +++ tags/2.3.0/src_plugins/ar_extern/ar_extern.c (revision 33253) @@ -0,0 +1,265 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * auto routing with external router process + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include "board.h" +#include "data.h" +#include +#include +#include +#include +#include +#include +#include "conf_core.h" +#include "obj_pstk_inlines.h" +#include "src_plugins/lib_compat_help/pstk_compat.h" +#include "src_plugins/lib_netmap/netmap.h" +#include "ar_extern_conf.h" + +#define AR_EXTERN_CONF_FN "ar_extern.conf" +conf_ar_extern_t conf_ar_extern; + +static const char *extern_cookie = "extern autorouter plugin"; + +#include "conf_internal.c" +#include "menu_internal.c" + +typedef enum { + ERSC_BOARD, ERSC_SELECTED +} ext_route_scope_t; + +typedef struct { + const char *name; + int (*route)(pcb_board_t *pcb, ext_route_scope_t scope, const char *method, int argc, fgw_arg_t *argv); + int (*list_methods)(rnd_hidlib_t *hl, vts0_t *dst); + rnd_export_opt_t *(*list_conf)(rnd_hidlib_t *hl, const char *method); +} ext_router_t; + +#include "e_route-rnd.c" + +static const ext_router_t *routers[] = { &route_rnd, NULL }; + +static const ext_router_t *find_router(const char *name) +{ + const ext_router_t **r; + + for(r = routers; *r != NULL; r++) + if (strcmp((*r)->name, name) == 0) + return *r; + + return NULL; +} + +/*** route confkey listing ***/ +typedef struct router_method_s { + const ext_router_t *router; + char *name, *desc; + int len; + rnd_export_opt_t *confkeys; + rnd_hid_attr_val_t *val; /* current values (user set) */ + int *w; /* widget ID when dialog is open */ +} router_method_t; + +typedef struct router_api_s { + const ext_router_t *router; + int num_methods; + router_method_t *methods; +} router_api_t; + +static vtp0_t router_apis; /* of router_api_t */ +static int router_api_inited = 0; + +static void extroute_free_method(router_method_t *method) +{ + int n; + + for(n = 0; n < method->len; n++) { + free((char *)method->confkeys[n].name); + free((char *)method->confkeys[n].help_text); + if (method->confkeys[n].type == RND_HATT_STRING) + free((char *)method->confkeys[n].default_val.str); + + } + free(method->confkeys); + + free(method->w); + free(method->name); + free(method->desc); + free(method->val); +} + +static void extroute_free_conf(void) +{ + long n; + for(n = 0; n < router_apis.used; n++) { + router_api_t *r = router_apis.array[n]; + int i; + + for(i = 0; i < r->num_methods; i++) + extroute_free_method(&r->methods[i]); + + free(r->methods); + free(r); + } + vtp0_uninit(&router_apis); +} + +static void extroute_query_conf(pcb_board_t *pcb) +{ + const ext_router_t **r; + vts0_t methods = {0}; + + if (router_api_inited) + return; + + for(r = routers; *r != NULL; r++) { + router_api_t *rapi; + int n, m, i; + rnd_export_opt_t *cfg; + + printf(" router=%s\n", (*r)->name); + methods.used = 0; + (*r)->list_methods(&pcb->hidlib, &methods); + if (methods.used == 0) + continue; + rapi = calloc(sizeof(router_api_t), 1); + rapi->router = *r; + rapi->num_methods = methods.used/2; + rapi->methods = calloc(sizeof(router_method_t), rapi->num_methods); + vtp0_append(&router_apis, rapi); + + for(m = n = 0; n < methods.used; m++, n+=2) { + printf(" method=%s (%s)\n", methods.array[n], methods.array[n+1]); + rapi->methods[m].router = *r; + rapi->methods[m].confkeys = (*r)->list_conf(&pcb->hidlib, methods.array[n]); + rapi->methods[m].name = methods.array[n]; /* allocation ownership taken over to rapi->methods[m] */ + rapi->methods[m].desc = methods.array[n+1]; /* allocation ownership taken over to rapi->methods[m] */ + + for(cfg = rapi->methods[m].confkeys; cfg->name != NULL; cfg++) { + rapi->methods[m].len++; + printf(" %s: %s\n", cfg->name, cfg->help_text); + } + rapi->methods[m].w = malloc(sizeof(int) * rapi->methods[m].len); + rapi->methods[m].val = malloc(sizeof(rnd_hid_attr_val_t) * rapi->methods[m].len); + for(i = 0, cfg = rapi->methods[m].confkeys; cfg->name != NULL; i++, cfg++) + rapi->methods[m].val[i] = cfg->default_val; + } + } + vts0_uninit(&methods); + router_api_inited = 1; +} + +#include "dlg_extroute.c" + +/*** actions ***/ +static const char pcb_acts_extroute[] = "extroute(board|selected, router, [confkey=value, ...])"; +static const char pcb_acth_extroute[] = "Executed external autorouter to route the board or parts of the board"; +fgw_error_t pcb_act_extroute(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *scope, *router_; + char *router, *method; + ext_route_scope_t scp; + const ext_router_t *r; + pcb_board_t *pcb = PCB_ACT_BOARD; + + RND_ACT_IRES(0); + if (argc < 2) { + extroute_gui(pcb); + /* GUI is non-modal so always succesful */ + return 0; + } + + RND_ACT_CONVARG(1, FGW_STR, extroute, scope = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, extroute, router_ = argv[2].val.str); + + if (strcmp(scope, "board") == 0) scp = ERSC_BOARD; + else if (strcmp(scope, "selected") == 0) scp = ERSC_SELECTED; + else { + rnd_message(RND_MSG_ERROR, "Invalid scope: '%s'\n", scope); + return FGW_ERR_ARG_CONV; + } + + router = rnd_strdup(router_); + method = strchr(router, '/'); + if (method != NULL) { + *method = '\0'; + method++; + if (*method == '\0') + method = NULL; + } + + r = find_router(router); + if (r == NULL) { + free(router); + rnd_message(RND_MSG_ERROR, "Invalid router: '%s'\n", scope); + return FGW_ERR_ARG_CONV; + } + + if (r->route != NULL) + RND_ACT_IRES(r->route(pcb, scp, method, argc-3, argv+3)); + + free(router); + return 0; +} + +static rnd_action_t extern_action_list[] = { + {"extroute", pcb_act_extroute, pcb_acth_extroute, pcb_acts_extroute} +}; + +int pplg_check_ver_ar_extern(int ver_needed) { return 0; } + +void pplg_uninit_ar_extern(void) +{ + extroute_free_conf(); + rnd_conf_unreg_file(AR_EXTERN_CONF_FN, ar_extern_conf_internal); + rnd_conf_unreg_fields("plugins/ar_extern/"); + rnd_remove_actions_by_cookie(extern_cookie); + rnd_hid_menu_unload(rnd_gui, extern_cookie); +} + + +int pplg_init_ar_extern(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(extern_action_list, extern_cookie) + + rnd_conf_reg_file(AR_EXTERN_CONF_FN, ar_extern_conf_internal); + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_ar_extern, field,isarray,type_name,cpath,cname,desc,flags); +#include "ar_extern_conf_fields.h" + + rnd_hid_menu_load(rnd_gui, NULL, extern_cookie, 100, NULL, 0, ar_extern_menu, "plugin: ar_extern"); + + return 0; +} Index: tags/2.3.0/src_plugins/ar_extern/ar_extern.conf =================================================================== --- tags/2.3.0/src_plugins/ar_extern/ar_extern.conf (nonexistent) +++ tags/2.3.0/src_plugins/ar_extern/ar_extern.conf (revision 33253) @@ -0,0 +1,13 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:ar_extern { + ha:route_rnd { + exe = route-rnd + debug = 0 + } + } + } + } +} + Index: tags/2.3.0/src_plugins/ar_extern/ar_extern.pup =================================================================== --- tags/2.3.0/src_plugins/ar_extern/ar_extern.pup (nonexistent) +++ tags/2.3.0/src_plugins/ar_extern/ar_extern.pup (revision 33253) @@ -0,0 +1,9 @@ +$class feature +$short external autorouter +$long Autoroute using external process +$state WIP +$package auto +default buildin +dep io_tedax +autoload 1 + Index: tags/2.3.0/src_plugins/ar_extern/ar_extern_conf.h =================================================================== --- tags/2.3.0/src_plugins/ar_extern/ar_extern_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/ar_extern/ar_extern_conf.h (revision 33253) @@ -0,0 +1,17 @@ +#ifndef PCB_AR_EXTERN_CONF_H +#define PCB_AR_EXTERN_CONF_H + +#include + +typedef struct { + const struct { + const struct { + const struct route_rnd { + RND_CFT_STRING exe; + RND_CFT_BOOLEAN debug; + } route_rnd; + } ar_extern; + } plugins; +} conf_ar_extern_t; + +#endif Index: tags/2.3.0/src_plugins/ar_extern/dlg_extroute.c =================================================================== --- tags/2.3.0/src_plugins/ar_extern/dlg_extroute.c (nonexistent) +++ tags/2.3.0/src_plugins/ar_extern/dlg_extroute.c (revision 33253) @@ -0,0 +1,434 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * auto routing with external router process: dialog box + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ + vts0_t tabs; + int wtabs; +} ar_ctx_t; + +static ar_ctx_t ar_ctx; + +/* copy values from the dialog box to the memory representation (router_apis) */ +static void dlg2mem(void) +{ + int an, mn; + + if (!ar_ctx.active) + return; + + for(an = 0; an < router_apis.used; an++) { + router_api_t *a = router_apis.array[an]; + for(mn = 0; mn < a->num_methods; mn++) { + router_method_t *m = &a->methods[mn]; + int *wid; + rnd_hid_attr_val_t *val; + rnd_export_opt_t *cfg; + + for(cfg = m->confkeys, wid = m->w, val = m->val; cfg->name != NULL; cfg++, wid++, val++) + *val = ar_ctx.dlg[*wid].val; + } + } +} + +static void save_conf(FILE *f) +{ + int an, mn; + + dlg2mem(); + fprintf(f, "ha:autorouter-settings-v1 {\n"); + fprintf(f, " ha:confkeys {\n"); + + for(an = 0; an < router_apis.used; an++) { + router_api_t *a = router_apis.array[an]; + fprintf(f, " ha:%s {\n", a->router->name); + for(mn = 0; mn < a->num_methods; mn++) { + router_method_t *m = &a->methods[mn]; + int *wid; + rnd_hid_attr_val_t *val; + rnd_export_opt_t *cfg; + + fprintf(f, " ha:%s {\n", m->name); + for(cfg = m->confkeys, wid = m->w, val = m->val; cfg->name != NULL; cfg++, wid++, val++) { + switch(cfg->type) { + case RND_HATT_BOOL: + case RND_HATT_INTEGER: + fprintf(f, " %s=%ld\n", cfg->name, val->lng); + break; + case RND_HATT_REAL: + fprintf(f, " %s=%f\n", cfg->name, val->dbl); + break; + case RND_HATT_COORD: + rnd_fprintf(f, " %s=%$mH", cfg->name, val->crd); + fprintf(f, "\n"); + break; + case RND_HATT_STRING: + fprintf(f, " %s={%s}\n", cfg->name, val->str); + break; + default: break; + } + } + fprintf(f, " }\n"); + } + fprintf(f, " }\n"); + } + fprintf(f, " }\n"); + fprintf(f, "}\n"); +} + +static void load_conf(FILE *f, const char *fn) +{ + char *errmsg = NULL; + int an, mn; + lht_doc_t *doc = lht_dom_load(fn, &errmsg); + lht_node_t *croot, *nrouter, *nmethod, *n; + + if (doc == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to parse autorouter settings: %s\n", errmsg); + free(errmsg); + return; + } + free(errmsg); + + if ((doc->root == NULL) || (doc->root->type != LHT_HASH) || (strcmp(doc->root->name, "autorouter-settings-v1") != 0)) { + rnd_message(RND_MSG_ERROR, "Failed to load autorouter settings from %s: invalid root node (expected ha:autorouter-settings-v1)\n", fn); + return; + } + + croot = lht_dom_hash_get(doc->root, "confkeys"); + if ((croot == NULL) || (croot->type != LHT_HASH)) { + rnd_message(RND_MSG_ERROR, "Failed to load autorouter settings from %s: no confkeys under\n", fn); + return; + } + + + for(an = 0; an < router_apis.used; an++) { + router_api_t *a = router_apis.array[an]; + nrouter = lht_dom_hash_get(croot, a->router->name); + if ((nrouter == NULL) || (nrouter->type != LHT_HASH)) + continue; + for(mn = 0; mn < a->num_methods; mn++) { + router_method_t *m = &a->methods[mn]; + int *wid; + rnd_hid_attr_val_t *val; + rnd_export_opt_t *cfg; + + nmethod = lht_dom_hash_get(nrouter, m->name); + if ((nmethod == NULL) || (nmethod->type != LHT_HASH)) + continue; + + for(cfg = m->confkeys, wid = m->w, val = m->val; cfg->name != NULL; cfg++, wid++, val++) { + char *end; + long l; + double d; + rnd_bool succ; + + n = lht_dom_hash_get(nmethod, cfg->name); + if ((n == NULL) || (n->type != LHT_TEXT)) + continue; + + switch(cfg->type) { + case RND_HATT_BOOL: + case RND_HATT_INTEGER: + l = strtol(n->data.text.value, &end, 10); + if (*end == '\0') + val->lng = l; + break; + case RND_HATT_REAL: + d = strtod(n->data.text.value, &end); + if (*end == '\0') + val->dbl = d; + break; + case RND_HATT_COORD: + d = rnd_get_value(n->data.text.value, NULL, NULL, &succ); + if (succ) + val->crd = d; + break; + case RND_HATT_STRING: + free((char *)val->str); + val->str = n->data.text.value; + n->data.text.value = NULL; /* took over ownership */ + break; + default: break; + } + rnd_gui->attr_dlg_set_value(ar_ctx.dlg_hid_ctx, *wid, val); + } + } + } + + lht_dom_uninit(doc); +} + +static void save_conf_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + FILE *f; + char *fname; + rnd_hidlib_t *hl = rnd_gui->get_dad_hidlib(hid_ctx); + + fname = rnd_gui->fileselect(rnd_gui, "Save autoroute settings to...", + "Pick a file for saving autoroute settings to.\n", + "autoroute.cfg.lht", ".lht", NULL, "ar_extern", RND_HID_FSD_MAY_NOT_EXIST, NULL); + + if (fname == NULL) + return; + + f = rnd_fopen(hl, fname, "w"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to open '%s' for write\n", fname); + return; + } + + save_conf(f); + fclose(f); + free(fname); +} + +static void load_conf_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + FILE *f; + char *fname; + rnd_hidlib_t *hl = rnd_gui->get_dad_hidlib(hid_ctx); + + fname = rnd_gui->fileselect(rnd_gui, "Load autoroute settings from...", + "Pick a file for loading autoroute settings from.\n", + "autoroute.cfg.lht", ".lht", NULL, "ar_extern", 0, NULL); + + if (fname == NULL) + return; + + f = rnd_fopen(hl, fname, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to open '%s' for read\n", fname); + return; + } + + load_conf(f, fname); + fclose(f); + free(fname); +} + +static int val_eq(rnd_hid_attr_type_t type, const rnd_hid_attr_val_t *v1, const rnd_hid_attr_val_t *v2) +{ + switch(type) { + case RND_HATT_BOOL: + case RND_HATT_INTEGER: return v1->lng == v2->lng; + case RND_HATT_REAL: return v1->dbl == v2->dbl; + case RND_HATT_COORD: return v1->crd == v2->crd; + case RND_HATT_STRING: return strcmp(v1->str, v2->str) == 0; + default: rnd_message(RND_MSG_ERROR, "external router: internal error: unhandled val type - report this bug!\n"); + } + return 0; /* better stay with the default */ +} + +static void route_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int argc, an, mn, cnt = 0, target = ar_ctx.dlg[ar_ctx.wtabs].val.lng; + rnd_export_opt_t *cfg; + router_method_t *m; + rnd_hid_attr_val_t *val; + router_api_t *a; + fgw_arg_t *argv; + + /* count with cnt until reaching target; mn is then the method */ + for(an = 0; an < router_apis.used; an++) { + a = router_apis.array[an]; + for(mn = 0; mn < a->num_methods; mn++) + if (cnt++ == target) + goto out; + } + + rnd_message(RND_MSG_ERROR, "external router: can't find the router for this tab (%d/%d; internal error)\n", cnt, target); + + out:; + + if (a->router->route == NULL) { + rnd_message(RND_MSG_ERROR, "external router: internal error: this router does not implement the ->route call\n"); + return; + } + + dlg2mem(); + m = &a->methods[mn]; + argc = 0; + argv = calloc(sizeof(fgw_arg_t), m->len); + for(cfg = m->confkeys, val = m->val; cfg->name != NULL; cfg++, val++) { + char *s = NULL; + + if (val_eq(cfg->type, val, &cfg->default_val)) + continue; + + switch(cfg->type) { + case RND_HATT_BOOL: + case RND_HATT_INTEGER: + s = rnd_strdup_printf("%s=%d", cfg->name, val->lng); + break; + case RND_HATT_REAL: + s = rnd_strdup_printf("%s=%f", cfg->name, val->dbl); + break; + case RND_HATT_COORD: + s = rnd_strdup_printf("%s=%.06mm", cfg->name, val->crd); + break; + case RND_HATT_STRING: + s = rnd_concat(cfg->name, "=", val->str, NULL); + break; + default: break; + } + argv[argc].type = FGW_STR; argv[argc].val.str = s; + argc++; + } + + a->router->route(PCB, ERSC_BOARD, m->name, argc, argv); + rnd_gui->invalidate_all(rnd_gui); + + fgw_argv_free(&rnd_fgw, argc, argv); + free(argv); +} + +static void reroute_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&PCB->hidlib, "RipUp", "All", NULL); + route_cb(hid_ctx, caller_data, attr); +} + + + +static void ar_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + ar_ctx_t *ctx = caller_data; + dlg2mem(); + RND_DAD_FREE(ctx->dlg); + vts0_uninit(&ctx->tabs); + memset(ctx, 0, sizeof(ar_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void extroute_gui(pcb_board_t *pcb) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + long an, mn; + + if (ar_ctx.active) + return; /* do not open another */ + + extroute_query_conf(pcb); + + if (router_apis.used < 1) { + rnd_message(RND_MSG_ERROR, "No external autorouter installed. Please install one, e.g.\nfrom http://www.repo.hu/projects/route-rnd/\n"); + return; + } + + for(an = 0; an < router_apis.used; an++) { + router_api_t *a = router_apis.array[an]; + for(mn = 0; mn < a->num_methods; mn++) + vts0_append(&ar_ctx.tabs, a->methods[mn].name); + } + + RND_DAD_BEGIN_VBOX(ar_ctx.dlg); + RND_DAD_BEGIN_TABBED(ar_ctx.dlg, ar_ctx.tabs.array); + RND_DAD_COMPFLAG(ar_ctx.dlg, RND_HATF_LEFT_TAB|RND_HATF_EXPFILL); + ar_ctx.wtabs = RND_DAD_CURRENT(ar_ctx.dlg); + for(an = 0; an < router_apis.used; an++) { + router_api_t *a = router_apis.array[an]; + for(mn = 0; mn < a->num_methods; mn++) { + router_method_t *m = &a->methods[mn]; + char *title; + int *wid; + rnd_hid_attr_val_t *val; + rnd_export_opt_t *cfg; + + RND_DAD_BEGIN_VBOX(ar_ctx.dlg); + if (m->len > 10) + RND_DAD_COMPFLAG(ar_ctx.dlg, RND_HATF_SCROLL); + + title = rnd_concat(m->router->name, " / ", m->name, NULL); + RND_DAD_LABEL(ar_ctx.dlg, title); + RND_DAD_LABEL(ar_ctx.dlg, m->desc); + free(title); + + for(cfg = m->confkeys, wid = m->w, val = m->val; cfg->name != NULL; cfg++, wid++, val++) { + RND_DAD_BEGIN_HBOX(ar_ctx.dlg); + switch(cfg->type) { + case RND_HATT_BOOL: + RND_DAD_BOOL(ar_ctx.dlg); + RND_DAD_DEFAULT_NUM(ar_ctx.dlg, val->lng); + break; + case RND_HATT_INTEGER: + RND_DAD_INTEGER(ar_ctx.dlg); + RND_DAD_MINMAX(ar_ctx.dlg, cfg->min_val, cfg->max_val); + RND_DAD_DEFAULT_NUM(ar_ctx.dlg, val->lng); + break; + case RND_HATT_REAL: + RND_DAD_REAL(ar_ctx.dlg); + RND_DAD_MINMAX(ar_ctx.dlg, cfg->min_val, cfg->max_val); + RND_DAD_DEFAULT_NUM(ar_ctx.dlg, val->dbl); + break; + case RND_HATT_COORD: + RND_DAD_COORD(ar_ctx.dlg); + RND_DAD_MINMAX(ar_ctx.dlg, cfg->min_val, cfg->max_val); + RND_DAD_DEFAULT_NUM(ar_ctx.dlg, val->crd); + break; + case RND_HATT_STRING: + RND_DAD_STRING(ar_ctx.dlg); + RND_DAD_DEFAULT_PTR(ar_ctx.dlg, val->str); + break; + default: + break; + } + *wid = RND_DAD_CURRENT(ar_ctx.dlg); + RND_DAD_LABEL(ar_ctx.dlg, cfg->name); + RND_DAD_END(ar_ctx.dlg); + } + RND_DAD_END(ar_ctx.dlg); + } + } + RND_DAD_END(ar_ctx.dlg); + + RND_DAD_BEGIN_HBOX(ar_ctx.dlg); + RND_DAD_BUTTON(ar_ctx.dlg, "Route"); + RND_DAD_CHANGE_CB(ar_ctx.dlg, route_cb); + RND_DAD_BUTTON(ar_ctx.dlg, "Re-route"); + RND_DAD_CHANGE_CB(ar_ctx.dlg, reroute_cb); + RND_DAD_BUTTON(ar_ctx.dlg, "Save"); + RND_DAD_CHANGE_CB(ar_ctx.dlg, save_conf_cb); + RND_DAD_BUTTON(ar_ctx.dlg, "Load"); + RND_DAD_CHANGE_CB(ar_ctx.dlg, load_conf_cb); + RND_DAD_BEGIN_HBOX(ar_ctx.dlg); + RND_DAD_COMPFLAG(ar_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_PROGRESS(ar_ctx.dlg); + RND_DAD_END(ar_ctx.dlg); + RND_DAD_BUTTON_CLOSES(ar_ctx.dlg, clbtn); + RND_DAD_END(ar_ctx.dlg); + RND_DAD_END(ar_ctx.dlg); + + /* set up the context */ + ar_ctx.active = 1; + + RND_DAD_NEW("external_autorouter", ar_ctx.dlg, "External autorouter", &ar_ctx, rnd_false, ar_close_cb); +} Index: tags/2.3.0/src_plugins/ar_extern/e_route-rnd.c =================================================================== --- tags/2.3.0/src_plugins/ar_extern/e_route-rnd.c (nonexistent) +++ tags/2.3.0/src_plugins/ar_extern/e_route-rnd.c (revision 33253) @@ -0,0 +1,158 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * auto routing with external router process + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +static int rtrnd_route(pcb_board_t *pcb, ext_route_scope_t scope, const char *method, int argc, fgw_arg_t *argv) +{ + const char *route_req = "rtrnd.1.tdx", *route_res = "rtrnd.2.tdx"; + rnd_hidlib_t *hl = &pcb->hidlib; + char *cmd; + int n, r, sargc, rv = 1; + fgw_arg_t sres = {0}, *sargv; + + sargc = argc + 3; + sargv = calloc(sizeof(fgw_arg_t), sargc); + sargv[1].type = FGW_STR; sargv[1].val.cstr = "route_req"; + sargv[2].type = FGW_STR; sargv[2].val.cstr = route_req; + + /* copy the rest of the conf arguments */ + for(n = 0; n < argc; n++) { + sargv[n+3] = argv[n]; + sargv[n+3].type &= ~FGW_DYN; + } + + /* export */ + r = rnd_actionv_bin(hl, "SaveTedax", &sres, sargc, sargv); + free(sargv); + fgw_arg_conv(&rnd_fgw, &sres, FGW_INT); + if ((r != 0) || (sres.val.nat_int != 0)) { + rnd_message(RND_MSG_ERROR, "route-rnd: failed to export route request in tEDAx\n"); + goto exit; + } + + /* run the router */ + if (method != NULL) + cmd = rnd_strdup_printf("%s '%s' -m '%s' -o '%s'", conf_ar_extern.plugins.ar_extern.route_rnd.exe, route_req, method, route_res); + else + cmd = rnd_strdup_printf("%s '%s' -o '%s'", conf_ar_extern.plugins.ar_extern.route_rnd.exe, route_req, route_res); + r = rnd_system(hl, cmd); + if (r != 0) { + rnd_message(RND_MSG_ERROR, "route-rnd: failed to execute the router: '%s'\n", cmd); + free(cmd); + goto exit; + } + free(cmd); + + r = rnd_actionva(hl, "LoadTedaxFrom", "route_res", route_res, NULL); + if (r != 0) { + rnd_message(RND_MSG_ERROR, "route-rnd: failed to import the route result from tEDAx\n"); + goto exit; + } + + rv = 0; /* success! */ + + exit:; + if (!conf_ar_extern.plugins.ar_extern.route_rnd.debug) { + rnd_unlink(hl, route_req); + rnd_unlink(hl, route_res); + } + return rv; +} + +static int rtrnd_list_methods(rnd_hidlib_t *hl, vts0_t *dst) +{ + FILE *f; + char *cmd, line[1024]; + + cmd = rnd_strdup_printf("%s -M", conf_ar_extern.plugins.ar_extern.route_rnd.exe); + f = rnd_popen(hl, cmd, "r"); + free(cmd); + if (f == NULL) + return -1; + + while(fgets(line, sizeof(line), f) != NULL) { + char *name, *desc; + name = line; + while(isspace(*name)) name++; + if (*name == '\0') continue; + desc = strchr(name, '\t'); + if (desc != NULL) { + *desc = '\0'; + desc++; + } + else + desc = "n/a"; + vts0_append(dst, rnd_strdup(name)); + vts0_append(dst, rnd_strdup(desc)); + } + + fclose(f); + return 0; +} + + +static rnd_export_opt_t *rtrnd_list_conf(rnd_hidlib_t *hl, const char *method) +{ + char *cmd; + const char *route_lst = "rtrnd.l.tdx"; + int r; + fgw_error_t err; + fgw_arg_t res; + fgw_arg_t argv[3]; + rnd_export_opt_t *rv = NULL; + + cmd = rnd_strdup_printf("%s -l -m '%s' > '%s'", conf_ar_extern.plugins.ar_extern.route_rnd.exe, method, route_lst); + r = rnd_system(hl, cmd); + if (r != 0) { + rnd_message(RND_MSG_ERROR, "route-rnd: failed to execute the router: '%s'\n", cmd); + free(cmd); + goto exit; + } + free(cmd); + + argv[1].type = FGW_STR; argv[1].val.cstr = "route_conf_keys"; + argv[2].type = FGW_STR; argv[2].val.cstr = route_lst; + err = rnd_actionv_bin(hl, "LoadTedaxFrom", &res, 3, argv); + if ((err != 0) || !(res.type & FGW_PTR)) { + rnd_message(RND_MSG_ERROR, "route-rnd: failed to import the conf key list from tEDAx\n"); + goto exit; + } + + rv = res.val.ptr_void; /* success! */ + + exit:; + if (!conf_ar_extern.plugins.ar_extern.route_rnd.debug) + rnd_unlink(hl, route_lst); + return rv; +} + +static const ext_router_t route_rnd = { + "route-rnd", + rtrnd_route, + rtrnd_list_methods, + rtrnd_list_conf +}; Index: tags/2.3.0/src_plugins/asm/Makefile =================================================================== --- tags/2.3.0/src_plugins/asm/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/asm/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_asm + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/asm/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/asm/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/asm/Plug.tmpasm (revision 33253) @@ -0,0 +1,16 @@ +put /local/pcb/mod {asm} +put /local/pcb/mod/CONF {$(PLUGDIR)/asm/asm_conf.h} +put /local/pcb/mod/CONFFILE {asm.conf} +put /local/pcb/mod/CONFVAR {asm_conf_internal} +put /local/pcb/mod/MENUFILE {asm-menu.lht} +put /local/pcb/mod/MENUVAR {asm_menu} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/asm/asm.o +@] + + +switch /local/pcb/asm/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/asm/asm-menu.lht =================================================================== --- tags/2.3.0/src_plugins/asm/asm-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/asm/asm-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@feature_plugins { + li:submenu { + ha:Assembly helper (interactive) = { action=asm() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/asm/asm.c =================================================================== --- tags/2.3.0/src_plugins/asm/asm.c (nonexistent) +++ tags/2.3.0/src_plugins/asm/asm.c (revision 33253) @@ -0,0 +1,657 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * hand assembly assistant GUI + * pcb-rnd Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "data.h" +#include +#include +#include +#include "obj_subc.h" +#include +#include +#include +#include +#include "search.h" +#include "draw.h" +#include "select.h" +#include "asm_conf.h" +#include "../src_plugins/asm/conf_internal.c" +#include "menu_internal.c" + +conf_asm_t conf_asm; +#define ASM_CONF_FN "asm.conf" + + +static const char *asm_cookie = "asm plugin"; + +/*** internal list of all parts, grouped; have to be arrays for qsort(), so can't + avoid it and just use tree-table list based trees ***/ +typedef enum { + TT_ATTR, + TT_SIDE, + TT_X, + TT_Y +} ttype_t; + +typedef struct { + ttype_t type; + const char *key; + gdl_elem_t link; +} template_t; + +typedef struct { + int is_grp; + char *name; + rnd_hid_row_t *row; + vtp0_t parts; +} group_t; + +typedef struct { + int is_grp; + char *name; + long int id; + int done; + rnd_hid_row_t *row; + group_t *parent; +} part_t; + +/* dialog context */ +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + vtp0_t grps; + vtclr_t layer_colors; /* saved before greying out */ + int wtbl, wskipg, wdoneg, wskipp, wdonep; + int active; /* already open - allow only one instance */ +} asm_ctx_t; + +asm_ctx_t asm_ctx; + +/*** template compiling ***/ +static void templ_append(gdl_list_t *dst, ttype_t type, const char *key) +{ + template_t *t = calloc(sizeof(template_t), 1); + t->type = type; + t->key = key; + gdl_append(dst, t, link); +} + +static char *templ_compile(gdl_list_t *dst, const char *src_) +{ + char *s, *next, *src = rnd_strdup(src_); + + for(s = src; (s != NULL) && (*s != '\0'); s = next) { + while(isspace(*s) || (*s == ',')) s++; + next = strpbrk(s, " \t\r\n,"); + if (next != NULL) { + *next = '\0'; + next++; + } + if ((s[0] == 'a') && (s[1] == '.')) { + s+=2; + templ_append(dst, TT_ATTR, s); + } + else if (strcmp(s, "side") == 0) + templ_append(dst, TT_SIDE, NULL); + else if (strcmp(s, "x") == 0) + templ_append(dst, TT_X, NULL); + else if (strcmp(s, "y") == 0) + templ_append(dst, TT_Y, NULL); + else + rnd_message(RND_MSG_ERROR, "Ignoring unknown asm template entry: '%s'\n", s); + } + return src; +} + +/* allocate a string and build a sortable text summary of a subc using the template */ +static char *templ_exec(pcb_subc_t *subc, gdl_list_t *temp) +{ + gds_t s; + template_t *t; + int n, bot, have_coords = 0; + char *tmp; + rnd_coord_t x = 0, y = 0; + + gds_init(&s); + for(n = 0, t = gdl_first(temp); t != NULL; n++, t = gdl_next(temp, t)) { + if (n != 0) + gds_append(&s, ','); + switch(t->type) { + case TT_ATTR: + tmp = pcb_attribute_get(&subc->Attributes, t->key); + if (tmp != NULL) + gds_append_str(&s, tmp); + break; + case TT_SIDE: + bot = 0; + pcb_subc_get_side(subc, &bot); + gds_append_str(&s, (bot ? "1/bottom" : "0/top")); + break; + case TT_X: + if (!have_coords) { + pcb_subc_get_origin(subc, &x, &y); + have_coords = 1; + } + rnd_append_printf(&s, "%.08mm", x); + break; + case TT_Y: + if (!have_coords) { + pcb_subc_get_origin(subc, &x, &y); + have_coords = 1; + } + rnd_append_printf(&s, "%.08mm", y); + break; + } + } + return s.array; +} + +static void templ_free(char *tmp, gdl_list_t *dst) +{ + template_t *t; + + for(t = gdl_first(dst); t != NULL; t = gdl_first(dst)) { + gdl_remove(dst, t, link); + free(t); + } + + free(tmp); +} + +static group_t *group_lookup(vtp0_t *grps, htsp_t *gh, char *name, int alloc) +{ + group_t *g = htsp_get(gh, name); + if (g != NULL) { + free(name); + return g; + } + + g = calloc(sizeof(group_t), 1); + g->is_grp = 1; + g->name = name; + + vtp0_append(grps, g); + htsp_set(gh, name, g); + return g; +} + +static void part_append(group_t *g, char *sortstr, long int id) +{ + part_t *p = malloc(sizeof(part_t)); + p->is_grp = 0; + p->name = sortstr; + p->id = id; + p->done = 0; + p->parent = g; + vtp0_append(&g->parts, p); +} + +/* Extract the part list from data */ +static void asm_extract(vtp0_t *dst, pcb_data_t *data, const char *group_template, const char *sort_template) +{ + gdl_list_t cgroup, csort; + char *tmp_group, *tmp_sort; + htsp_t gh; + + memset(&cgroup, 0, sizeof(cgroup)); + memset(&csort, 0, sizeof(csort)); + tmp_group = templ_compile(&cgroup, group_template); + tmp_sort = templ_compile(&csort, sort_template); + + htsp_init(&gh, strhash, strkeyeq); + + PCB_SUBC_LOOP(data); + { + char *grp, *srt; + group_t *g; + + grp = templ_exec(subc, &cgroup); + srt = templ_exec(subc, &csort); + g = group_lookup(dst, &gh, grp, 1); + part_append(g, srt, subc->ID); + /* no need to free grp or srt, they are stored in the group and part structs */ + } + PCB_END_LOOP; + + htsp_uninit(&gh); + templ_free(tmp_group, &cgroup); + templ_free(tmp_sort, &csort); +} + +/*** Sort the part list ***/ +static int group_cmp(const void *ga_, const void *gb_) +{ + const group_t * const *ga = ga_; + const group_t * const *gb = gb_; + return strcmp((*ga)->name, (*gb)->name); +} + +static int part_cmp(const void *pa_, const void *pb_) +{ + const part_t * const *pa = pa_; + const part_t * const *pb = pb_; + return strcmp((*pa)->name, (*pb)->name); +} + +static void asm_sort(vtp0_t *gv) +{ + group_t **g; + long n; + + qsort(gv->array, gv->used, sizeof(void *), group_cmp); + for(g = (group_t **)gv->array, n = 0; n < gv->used; g++,n++) + qsort((*g)->parts.array, (*g)->parts.used, sizeof(void *), part_cmp); +} + +/*** Gray out all layers to make selection stick out more ***/ +static int fade(int c, int factor) +{ + if (c > 127) + return 127 + (c - 127) / factor; + return 127 - (127 - c) / factor; +} + +static void asm_greyout(int grey) +{ + int n; + pcb_data_t *data = PCB->Data; + pcb_layer_t *ly; + + if (grey) { + vtclr_init(&asm_ctx.layer_colors); + vtclr_enlarge(&asm_ctx.layer_colors, data->LayerN); + for(n = 0, ly = data->Layer; n < data->LayerN; n++,ly++) { + int r, g, b; + + vtclr_set(&asm_ctx.layer_colors, n, ly->meta.real.color); + r = ly->meta.real.color.r; + g = ly->meta.real.color.g; + b = ly->meta.real.color.b; + r = fade(r, 4); + g = fade(g, 4); + b = fade(b, 4); + rnd_color_load_int(&ly->meta.real.color, r, g, b, 255); + } + } + else { + for(n = 0, ly = data->Layer; n < data->LayerN; n++,ly++) + ly->meta.real.color = asm_ctx.layer_colors.array[n]; + vtclr_uninit(&asm_ctx.layer_colors); + } + rnd_hid_redraw(PCB); +} + +/*** UI callbacks ***/ +static void asm_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + group_t **g; + part_t **p; + long i, n; + asm_ctx_t *ctx = caller_data; + asm_greyout(0); + + for(g = (group_t **)asm_ctx.grps.array, n = 0; n < asm_ctx.grps.used; g++,n++) { + for(p = (part_t **)(*g)->parts.array, i = 0; i < (*g)->parts.used; p++,i++) + free(*p); + vtp0_uninit(&(*g)->parts); + free(*g); + } + vtp0_uninit(&asm_ctx.grps); + + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(asm_ctx_t)); +} + +static void select_part(part_t *p) +{ + void *r1, *r2, *r3; + pcb_subc_t *sc; + pcb_objtype_t type; + rnd_box_t view; + + type = pcb_search_obj_by_id_(PCB->Data, &r1, &r2, &r3, p->id, PCB_OBJ_SUBC); + if (type != PCB_OBJ_SUBC) + return; + + sc = (pcb_subc_t *)r2; + pcb_subc_select(PCB, sc, PCB_CHGFLG_SET, 1); + + /* if the part is out of the screen, pan there */ + rnd_gui->view_get(rnd_gui, &view); + if ((view.X2 < sc->BoundingBox.X1) || (view.X1 > sc->BoundingBox.X2) || (view.Y2 < sc->BoundingBox.Y1) || (view.Y1 > sc->BoundingBox.Y2)) + rnd_gui->pan(rnd_gui, (sc->BoundingBox.X1+sc->BoundingBox.X2)/2, (sc->BoundingBox.Y1+sc->BoundingBox.Y2)/2, 0); +} + +static void asm_row_selected(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + long n; + int isgrp = 0, ispart = 0; + rnd_box_t box; + + /* unselect all */ + box.X1 = -RND_MAX_COORD; + box.Y1 = -RND_MAX_COORD; + box.X2 = RND_MAX_COORD; + box.Y2 = RND_MAX_COORD; + if (pcb_select_block(PCB, &box, rnd_false, rnd_false, rnd_false)) + pcb_board_set_changed_flag(PCB, rnd_true); + + if (row == NULL) { + goto skip; + } + if (*(int *)row->user_data) { + group_t *g = row->user_data; + part_t **p; + isgrp = 1; + for(n = 0, p = (part_t **)g->parts.array; n < g->parts.used; n++,p++) + select_part(*p); + } + else { + part_t *p = row->user_data; + ispart = 1; + select_part(p); + } + + skip:; + rnd_gui->attr_dlg_widget_state(hid_ctx, asm_ctx.wskipg, isgrp | ispart); + rnd_gui->attr_dlg_widget_state(hid_ctx, asm_ctx.wdoneg, isgrp | ispart); + rnd_gui->attr_dlg_widget_state(hid_ctx, asm_ctx.wskipp, ispart); + rnd_gui->attr_dlg_widget_state(hid_ctx, asm_ctx.wdonep, ispart); + rnd_hid_redraw(PCB); /* for displaying the new selection */ +} + +static void skip(void *hid_ctx, int pick_grp, rnd_hid_row_t *row) +{ + rnd_hid_row_t *nr = NULL; + int is_grp = *(int *)row->user_data; + + if (pick_grp && !is_grp) { + /* special case: next group from a part: skip the whole group */ + goto skip_parent; + } + else if (!pick_grp || is_grp) { + /* try to pick the next row first */ + nr = row->link.next; + } + + if (nr == NULL) { + part_t *p; + if (is_grp) + goto last; /* skipping from the last group -> unselect all */ + /* skipping from last part in a group -> jump to next group's first part */ + skip_parent:; + p = row->user_data; + nr = p->parent->row; + nr = nr->link.next; + if (nr == NULL) + goto last; /* skipping from the last part of the last group -> unselect all */ + nr = gdl_first(&nr->children); + } + rnd_dad_tree_jumpto(&asm_ctx.dlg[asm_ctx.wtbl], nr); + return; + + last:; + /* what happens after the last */ + rnd_dad_tree_jumpto(&asm_ctx.dlg[asm_ctx.wtbl], NULL); + return; +} + +static void group_progress_update(void *hid_ctx, group_t *grp) +{ + long n, done = 0, total = vtp0_len(&grp->parts); + char *tmp; + + for(n = 0; n < total; n++) { + part_t *p = grp->parts.array[n]; + if (p->done) + done++; + } + + tmp = rnd_strdup_printf("%d/%d", done, total); + rnd_dad_tree_modify_cell(&asm_ctx.dlg[asm_ctx.wtbl], grp->row, 5, tmp); +} + +static void done(void *hid_ctx, part_t *part, int done) +{ + part->done = done; + if (done) + rnd_dad_tree_modify_cell(&asm_ctx.dlg[asm_ctx.wtbl], part->row, 5, "yes"); + else + rnd_dad_tree_modify_cell(&asm_ctx.dlg[asm_ctx.wtbl], part->row, 5, "-"); + group_progress_update(hid_ctx, part->parent); +} + +static void asm_done_part(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&asm_ctx.dlg[asm_ctx.wtbl]); + if (*(int *)row->user_data) + return; + done(hid_ctx, row->user_data, 1); + skip(hid_ctx, 0, row); +} + +static void asm_undo_part(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&asm_ctx.dlg[asm_ctx.wtbl]); + if (*(int *)row->user_data) + return; + done(hid_ctx, row->user_data, 0); + skip(hid_ctx, 0, row); +} + +static void asm_skip_part(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&asm_ctx.dlg[asm_ctx.wtbl]); + if (*(int *)row->user_data) + return; + skip(hid_ctx, 0, row); +} + +static void asm_done_group_(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr, int dn) +{ + long n; + group_t *g; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&asm_ctx.dlg[asm_ctx.wtbl]); + + if (!*(int *)row->user_data) { + part_t *p = row->user_data; + g = p->parent; + } + else + g = row->user_data; + + for(n = 0; n < g->parts.used; n++) + done(hid_ctx, g->parts.array[n], dn); + skip(hid_ctx, 1, row); +} + +static void asm_done_group(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + asm_done_group_(hid_ctx, caller_data, attr, 1); +} + +static void asm_undo_group(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + asm_done_group_(hid_ctx, caller_data, attr, 0); +} + + +static void asm_skip_group(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&asm_ctx.dlg[asm_ctx.wtbl]); + + skip(hid_ctx, 1, row); +} + + +static const char pcb_acts_asm[] = "asm()"; +static const char pcb_acth_asm[] = "Interactive assembly assistant"; +fgw_error_t pcb_act_asm(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *hdr[] = { "name", "refdes", "footprint", "value", "comments", "done", NULL }; + char *row[7]; + group_t **g; + part_t **p; + long n, i; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + if (asm_ctx.active) { + RND_ACT_IRES(0); + return 0; + } + + vtp0_init(&asm_ctx.grps); + asm_extract(&asm_ctx.grps, PCB->Data, conf_asm.plugins.asm1.group_template, conf_asm.plugins.asm1.sort_template); + asm_sort(&asm_ctx.grps); + + asm_greyout(1); + + RND_DAD_BEGIN_VBOX(asm_ctx.dlg); + RND_DAD_COMPFLAG(asm_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(asm_ctx.dlg, 6, 1, hdr); + asm_ctx.wtbl = RND_DAD_CURRENT(asm_ctx.dlg); + RND_DAD_COMPFLAG(asm_ctx.dlg, RND_HATF_SCROLL); + for(g = (group_t **)asm_ctx.grps.array, n = 0; n < asm_ctx.grps.used; g++,n++) { + rnd_hid_row_t *parent, *child; + row[0] = (*g)->name; + row[1] = ""; + row[2] = ""; + row[3] = ""; + row[4] = ""; + row[5] = ""; + row[6] = NULL; + parent = RND_DAD_TREE_APPEND(asm_ctx.dlg, NULL, row); + parent->user_data = *g; + (*g)->row = parent; + for(p = (part_t **)(*g)->parts.array, i = 0; i < (*g)->parts.used; p++,i++) { + void *r1, *r2, *r3; + pcb_subc_t *sc; + pcb_objtype_t type; + + type = pcb_search_obj_by_id_(PCB->Data, &r1, &r2, &r3, (*p)->id, PCB_OBJ_SUBC); + sc = r2; + + row[0] = (*p)->name; + if (type == PCB_OBJ_SUBC) { + int m; + row[1] = (char *)sc->refdes; + row[2] = pcb_attribute_get(&sc->Attributes, "footprint"); + row[3] = pcb_attribute_get(&sc->Attributes, "value"); + row[4] = pcb_attribute_get(&sc->Attributes, "asm::comment"); + row[5] = ""; + for(m = 1; m < 6; m++) + if (row[m] == NULL) + row[m] = ""; + } + else { + row[1] = ""; + row[2] = ""; + row[3] = ""; + row[4] = ""; + row[5] = ""; + } + row[6] = NULL; + child = RND_DAD_TREE_APPEND_UNDER(asm_ctx.dlg, parent, row); + child->user_data = *p; + (*p)->row = child; + } + } + RND_DAD_TREE_SET_CB(asm_ctx.dlg, selected_cb, asm_row_selected); + RND_DAD_BEGIN_HBOX(asm_ctx.dlg); + RND_DAD_BUTTON(asm_ctx.dlg, "skip part"); + asm_ctx.wskipp = RND_DAD_CURRENT(asm_ctx.dlg); + RND_DAD_HELP(asm_ctx.dlg, "Do not populate this part,\ncontinue with the next part"); + RND_DAD_CHANGE_CB(asm_ctx.dlg, asm_skip_part); + RND_DAD_BUTTON(asm_ctx.dlg, "skip group"); + asm_ctx.wskipg = RND_DAD_CURRENT(asm_ctx.dlg); + RND_DAD_HELP(asm_ctx.dlg, "Stop populating this group,\ncontinue with the next group"); + RND_DAD_CHANGE_CB(asm_ctx.dlg, asm_skip_group); + RND_DAD_BUTTON(asm_ctx.dlg, "done part"); + asm_ctx.wdonep = RND_DAD_CURRENT(asm_ctx.dlg); + RND_DAD_HELP(asm_ctx.dlg, "Mark current part done,\ncontinue with the next part"); + RND_DAD_CHANGE_CB(asm_ctx.dlg, asm_done_part); + RND_DAD_BUTTON(asm_ctx.dlg, "undo part"); + asm_ctx.wdonep = RND_DAD_CURRENT(asm_ctx.dlg); + RND_DAD_HELP(asm_ctx.dlg, "Remove the done mark from the current part,\njump to the next part"); + RND_DAD_CHANGE_CB(asm_ctx.dlg, asm_undo_part); + RND_DAD_BUTTON(asm_ctx.dlg, "done group"); + asm_ctx.wdoneg = RND_DAD_CURRENT(asm_ctx.dlg); + RND_DAD_HELP(asm_ctx.dlg, "Mark all parts in this group done,\ncontinue with the next group"); + RND_DAD_CHANGE_CB(asm_ctx.dlg, asm_done_group); + RND_DAD_BUTTON(asm_ctx.dlg, "undo group"); + asm_ctx.wdoneg = RND_DAD_CURRENT(asm_ctx.dlg); + RND_DAD_HELP(asm_ctx.dlg, "Remove the done mark from all parts in this group done,\ncontinue with the next group"); + RND_DAD_CHANGE_CB(asm_ctx.dlg, asm_undo_group); + RND_DAD_END(asm_ctx.dlg); + RND_DAD_BUTTON_CLOSES(asm_ctx.dlg, clbtn); + RND_DAD_END(asm_ctx.dlg); + + asm_ctx.active = 1; + RND_DAD_NEW("asm", asm_ctx.dlg, "Hand assembly with pcb-rnd", &asm_ctx, rnd_false, asm_close_cb); + + /* expand all groups by default */ + for(g = (group_t **)asm_ctx.grps.array, n = 0; n < asm_ctx.grps.used; g++,n++) + rnd_dad_tree_expcoll(&asm_ctx.dlg[asm_ctx.wtbl], (*g)->row, 1, 0); + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t asm_action_list[] = { + {"asm", pcb_act_asm, pcb_acth_asm, pcb_acts_asm} +}; + +int pplg_check_ver_asm(int ver_needed) { return 0; } + +void pplg_uninit_asm(void) +{ + rnd_hid_menu_unload(rnd_gui, asm_cookie); + rnd_remove_actions_by_cookie(asm_cookie); + rnd_conf_unreg_file(ASM_CONF_FN, asm_conf_internal); + rnd_conf_unreg_fields("plugins/asm1/"); +} + +int pplg_init_asm(void) +{ + RND_API_CHK_VER; + rnd_conf_reg_file(ASM_CONF_FN, asm_conf_internal); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_asm, field,isarray,type_name,cpath,cname,desc,flags); +#include "asm_conf_fields.h" + + RND_REGISTER_ACTIONS(asm_action_list, asm_cookie) + + rnd_hid_menu_load(rnd_gui, NULL, asm_cookie, 175, NULL, 0, asm_menu, "plugin: asm"); + + return 0; +} Index: tags/2.3.0/src_plugins/asm/asm.conf =================================================================== --- tags/2.3.0/src_plugins/asm/asm.conf (nonexistent) +++ tags/2.3.0/src_plugins/asm/asm.conf (revision 33253) @@ -0,0 +1,10 @@ +li:pcb-rnd-conf-v1 { + ha:append { + ha:plugins { + ha:asm1 { + group_template = {side, a.footprint, a.value, a.asm::group} + sort_template = {a.footprint, a.value, a.asm::group, side, x, y} + } + } + } +} Index: tags/2.3.0/src_plugins/asm/asm.pup =================================================================== --- tags/2.3.0/src_plugins/asm/asm.pup (nonexistent) +++ tags/2.3.0/src_plugins/asm/asm.pup (revision 33253) @@ -0,0 +1,8 @@ +$class feature +$short assembly GUI +$long hand assembly assistant GUI +$state works +$package auto +default buildin +autoload 1 + Index: tags/2.3.0/src_plugins/asm/asm_conf.h =================================================================== --- tags/2.3.0/src_plugins/asm/asm_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/asm/asm_conf.h (revision 33253) @@ -0,0 +1,15 @@ +#ifndef PCB_ASM_CONF_H +#define PCB_ASM_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_STRING group_template; /* asm template that determines grouping (parts resulting in the same string will be put in the same group) */ + RND_CFT_STRING sort_template; /* asm template that determines order of groups and parts within groups */ + } asm1; + } plugins; +} conf_asm_t; + +#endif Index: tags/2.3.0/src_plugins/autocrop/Makefile =================================================================== --- tags/2.3.0/src_plugins/autocrop/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/autocrop/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_autocrop + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/autocrop/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/autocrop/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/autocrop/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {autocrop} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/autocrop/autocrop.o @] + +switch /local/pcb/autocrop/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/autocrop/autocrop.c =================================================================== --- tags/2.3.0/src_plugins/autocrop/autocrop.c (nonexistent) +++ tags/2.3.0/src_plugins/autocrop/autocrop.c (revision 33253) @@ -0,0 +1,93 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2020 Tibor 'Igor2' Palinkas + * + * This module, debug, was written and is Copyright (C) by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ +#include "config.h" + +#include +#include + +#include "board.h" +#include "data.h" +#include "draw.h" +#include "undo.h" +#include +#include + +static const char pcb_acth_autocrop[] = "Autocrops the board dimensions to (extants + a margin of 1 grid), keeping the move and board size grid aligned"; +static const char pcb_acts_autocrop[] = "autocrop()"; +static fgw_error_t pcb_act_autocrop(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_box_t box; + rnd_coord_t dx, dy, w, h; + + if (pcb_data_is_empty(PCB->Data)) + return 0; + + pcb_data_bbox(&box, PCB->Data, 0); + dx = -((box.X1 / PCB->hidlib.grid - 1) * PCB->hidlib.grid); + dy = -((box.Y1 / PCB->hidlib.grid - 1) * PCB->hidlib.grid); + w = ((box.X2 + dx) / PCB->hidlib.grid + 2) * PCB->hidlib.grid; + h = ((box.Y2 + dy) / PCB->hidlib.grid + 2) * PCB->hidlib.grid; + + if ((dx == 0) && (dy == 0) && (w == PCB->hidlib.size_x) && (h == PCB->hidlib.size_y)) + return 0; + + pcb_draw_inhibit_inc(); + pcb_data_clip_inhibit_inc(PCB->Data); + pcb_data_move(PCB->Data, dx, dy, 1); + pcb_board_resize(w, h, 1); + pcb_data_clip_inhibit_dec(PCB->Data, 1); + pcb_draw_inhibit_dec(); + + pcb_undo_inc_serial(); + rnd_hid_redraw(PCB); + pcb_board_set_changed_flag(PCB, 1); + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t autocrop_action_list[] = { + {"autocrop", pcb_act_autocrop, pcb_acth_autocrop, pcb_acts_autocrop} +}; + +char *autocrop_cookie = "autocrop plugin"; + +int pplg_check_ver_autocrop(int ver_needed) { return 0; } + +void pplg_uninit_autocrop(void) +{ + rnd_remove_actions_by_cookie(autocrop_cookie); +} + +int pplg_init_autocrop(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(autocrop_action_list, autocrop_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/autocrop/autocrop.pup =================================================================== --- tags/2.3.0/src_plugins/autocrop/autocrop.pup (nonexistent) +++ tags/2.3.0/src_plugins/autocrop/autocrop.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short crop board to fit objects +$long Reduce the board dimensions to just enclose the objects on the board. +$package (core) +$state works +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/autoplace/Makefile =================================================================== --- tags/2.3.0/src_plugins/autoplace/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/autoplace/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_autoplace + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/autoplace/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/autoplace/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/autoplace/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {autoplace} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/autoplace/autoplace.o $(PLUGDIR)/autoplace/action.o @] + +switch /local/pcb/autoplace/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/autoplace/action.c =================================================================== --- tags/2.3.0/src_plugins/autoplace/action.c (nonexistent) +++ tags/2.3.0/src_plugins/autoplace/action.c (revision 33253) @@ -0,0 +1,75 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" +#include "autoplace.h" +#include +#include +#include "board.h" +#include + +static const char autoplace_syntax[] = "AutoPlaceSelected()"; +static const char autoplace_help[] = "Auto-place selected components."; +/* DOC: autoplaceselected */ +static fgw_error_t pcb_act_AutoPlaceSelected(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_hid_busy(PCB, 1); + if (rnd_hid_message_box(RND_ACT_HIDLIB, "question", "Autoplace start", "Auto-placement can NOT be undone.\nDo you want to continue anyway?", "no", 0, "yes", 1, NULL) == 1) { + if (AutoPlaceSelected()) + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + } + rnd_hid_busy(PCB, 0); + RND_ACT_IRES(0); + return 0; +} + +static const char *autoplace_cookie = "autoplace plugin"; + +rnd_action_t autoplace_action_list[] = { + {"AutoPlaceSelected", pcb_act_AutoPlaceSelected, autoplace_help, autoplace_syntax} +}; + +int pplg_check_ver_autoplace(int ver_needed) { return 0; } + +void pplg_uninit_autoplace(void) +{ + rnd_remove_actions_by_cookie(autoplace_cookie); +} + +int pplg_init_autoplace(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(autoplace_action_list, autoplace_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/autoplace/autoplace.c =================================================================== --- tags/2.3.0/src_plugins/autoplace/autoplace.c (nonexistent) +++ tags/2.3.0/src_plugins/autoplace/autoplace.c (revision 33253) @@ -0,0 +1,820 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1998,1999,2000,2001 harry eaton + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +/* + * This moduel, autoplace.c, was written by and is + * Copyright (c) 2001 C. Scott Ananian + */ + +/* functions used to autoplace subcircuits. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "board.h" +#include "autoplace.h" +#include +#include +#include "box_dir.h" +#include "data.h" +#include "draw.h" +#include +#include "layer.h" +#include "intersect.h" +#include +#include "move.h" +#include "netlist.h" +#include "remove.h" +#include "rotate.h" +#include "obj_rat.h" +#include "obj_term.h" +#include "obj_pstk_inlines.h" +#include "board.h" +#include "data_it.h" +#include + +#define EXPANDRECTXY(r1, x1, y1, x2, y2) { \ + r1->X1=MIN(r1->X1, x1); r1->Y1=MIN(r1->Y1, y1); \ + r1->X2=MAX(r1->X2, x2); r1->Y2=MAX(r1->Y2, y2); \ +} +#define EXPANDRECT(r1, r2) EXPANDRECTXY(r1, r2->X1, r2->Y1, r2->X2, r2->Y2) + +const struct { + double via_cost; + double congestion_penalty; /* penalty length / unit area */ + double overlap_penalty_min; /* penalty length / unit area at start */ + double overlap_penalty_max; /* penalty length / unit area at end */ + double out_of_bounds_penalty; /* assessed for each component oob */ + double overall_area_penalty; /* penalty length / unit area */ + double matching_neighbor_bonus; /* length bonus per same-type neigh. */ + double aligned_neighbor_bonus; /* length bonus per aligned neigh. */ + double oriented_neighbor_bonus; /* length bonus per same-rot neigh. */ +#if 0 + double pin_alignment_bonus; /* length bonus per exact alignment */ + double bound_alignment_bonus; /* length bonus per exact alignment */ +#endif + double m; /* annealing stage cutoff constant */ + double gamma; /* annealing schedule constant */ + int good_ratio; /* ratio of moves to good moves for halting */ + rnd_bool fast; /* ignore SMD/pin conflicts */ + rnd_coord_t large_grid_size; /* snap perturbations to this grid when T is high */ + rnd_coord_t small_grid_size; /* snap to this grid when T is small. */ +} +/* wire cost is manhattan distance (in mils), thus 1 inch = 1000 */ CostParameter = +{ + 3e3, /* via cost */ + 2e-2, /* congestion penalty */ + 1e-2, /* initial overlap penalty */ + 1e2, /* final overlap penalty */ + 1e3, /* out of bounds penalty */ + 1e0, /* penalty for total area used */ + 1e0, /* subtract 1000 from cost for every same-type neighbor */ + 1e0, /* subtract 1000 from cost for every aligned neighbor */ + 1e0, /* subtract 1000 from cost for every same-rotation neighbor */ + 20, /* move on when each module has been profitably moved 20 times */ + 0.75, /* annealing schedule constant: 0.85 */ + 40, /* halt when there are 60 times as many moves as good moves */ + rnd_false, /* don't ignore SMD/pin conflicts */ + RND_MIL_TO_COORD(100), /* coarse grid is 100 mils */ + RND_MIL_TO_COORD(10), /* fine grid is 10 mils */ +}; + +enum ewhich { SHIFT, ROTATE, EXCHANGE }; + +typedef struct { + pcb_any_obj_t *comp; + enum ewhich which; + rnd_coord_t DX, DY; /* for shift */ + unsigned rotate; /* for rotate/flip */ + pcb_any_obj_t *other; /* for exchange */ +} PerturbationType; + +TODO("cleanup: remove this and use genvect") +#define STEP_POINT 100 + +/* get next slot for a box, allocates memory if necessary */ +static rnd_box_t *pcb_box_new(rnd_box_list_t *Boxes) +{ + rnd_box_t *box = Boxes->Box; + + /* realloc new memory if necessary and clear it */ + if (Boxes->BoxN >= Boxes->BoxMax) { + Boxes->BoxMax = STEP_POINT + (2 * Boxes->BoxMax); + box = (rnd_box_t *) realloc(box, Boxes->BoxMax * sizeof(rnd_box_t)); + Boxes->Box = box; + memset(box + Boxes->BoxN, 0, (Boxes->BoxMax - Boxes->BoxN) * sizeof(rnd_box_t)); + } + return (box + Boxes->BoxN++); +} + +/* frees memory used by a box list */ +static void pcb_box_free(rnd_box_list_t *Boxlist) +{ + if (Boxlist) { + free(Boxlist->Box); + memset(Boxlist, 0, sizeof(rnd_box_list_t)); + } +} + +/* Return a terminal's preferred layer group ID or -1 on error */ +static rnd_layergrp_id_t obj_layergrp(const pcb_any_obj_t *obj) +{ + rnd_layergrp_id_t SLayer = -1; + pcb_layer_t *layer; + + switch (obj->type) { + case PCB_OBJ_PSTK: + pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_COPPER, &SLayer, 1); + return SLayer; /* any layer will do */ + break; + + /* terminals on layer */ + case PCB_OBJ_LINE: + case PCB_OBJ_ARC: + case PCB_OBJ_TEXT: + case PCB_OBJ_POLY: + layer = pcb_layer_get_real(obj->parent.layer); + if (layer != NULL) + return layer->meta.real.grp; + return SLayer; /* any layer will do */ + default: + rnd_message(RND_MSG_ERROR, "Odd terminal type encountered in obj_layergrp()\n"); + } + return -1; +} + +/* --------------------------------------------------------------------------- + * Create a list of selected subcircuits + */ +static vtp0_t collectSelectedSubcircuits() +{ + vtp0_t list; + + vtp0_init(&list); + PCB_SUBC_LOOP(PCB->Data); + { + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, subc)) { + pcb_subc_t **epp = (pcb_subc_t **)vtp0_alloc_append(&list, 1); + *epp = subc; + } + } + PCB_END_LOOP; + return list; +} + +#if 0 /* only for debugging box lists */ +/* makes a line on the solder layer surrounding all boxes in blist */ +static void showboxes(rnd_box_list_t *blist) +{ + rnd_cardinal_t i; + pcb_layer_t *SLayer = &(PCB->Data->Layer[pcb_solder_silk_layer]); + for (i = 0; i < blist->BoxN; i++) { + pcb_line_new(SLayer, blist->Box[i].X1, blist->Box[i].Y1, blist->Box[i].X2, blist->Box[i].Y1, 1, 1, 0); + pcb_line_new(SLayer, blist->Box[i].X1, blist->Box[i].Y2, blist->Box[i].X2, blist->Box[i].Y2, 1, 1, 0); + pcb_line_new(SLayer, blist->Box[i].X1, blist->Box[i].Y1, blist->Box[i].X1, blist->Box[i].Y2, 1, 1, 0); + pcb_line_new(SLayer, blist->Box[i].X2, blist->Box[i].Y1, blist->Box[i].X2, blist->Box[i].Y2, 1, 1, 0); + } +} +#endif + +/* --------------------------------------------------------------------------- + * Helper function to compute "closest neighbor" for a box in a rtree. + * The closest neighbor on a certain side is the closest one in a trapezoid + * emanating from that side. + */ +/*------ r_find_neighbor ------*/ +struct r_neighbor_info { + const rnd_box_t *neighbor; + rnd_box_t trap; + rnd_direction_t search_dir; +}; +#define ROTATEBOX(box) { rnd_coord_t t;\ + t = (box).X1; (box).X1 = - (box).Y1; (box).Y1 = t;\ + t = (box).X2; (box).X2 = - (box).Y2; (box).Y2 = t;\ + t = (box).X1; (box).X1 = (box).X2; (box).X2 = t;\ +} +/* helper methods for __r_find_neighbor */ +static rnd_r_dir_t __r_find_neighbor_reg_in_sea(const rnd_box_t * region, void *cl) +{ + struct r_neighbor_info *ni = (struct r_neighbor_info *) cl; + rnd_box_t query = *region; + RND_BOX_ROTATE_TO_NORTH(query, ni->search_dir); + /* ______________ __ trap.y1 __ + * \ / |__| query rect. + * \__________/ __ trap.y2 + * | | + * trap.x1 trap.x2 sides at 45-degree angle + */ + if ((query.Y2 > ni->trap.Y1) && (query.Y1 < ni->trap.Y2) && (query.X2 + ni->trap.Y2 > ni->trap.X1 + query.Y1) && (query.X1 + query.Y1 < ni->trap.X2 + ni->trap.Y2)) + return RND_R_DIR_FOUND_CONTINUE; + return RND_R_DIR_NOT_FOUND; +} + +static rnd_r_dir_t __r_find_neighbor_rect_in_reg(const rnd_box_t * box, void *cl) +{ + struct r_neighbor_info *ni = (struct r_neighbor_info *) cl; + rnd_box_t query = *box; + int r; + RND_BOX_ROTATE_TO_NORTH(query, ni->search_dir); + /* ______________ __ trap.y1 __ + * \ / |__| query rect. + * \__________/ __ trap.y2 + * | | + * trap.x1 trap.x2 sides at 45-degree angle + */ + r = (query.Y2 > ni->trap.Y1) && (query.Y1 < ni->trap.Y2) && + (query.X2 + ni->trap.Y2 > ni->trap.X1 + query.Y1) && (query.X1 + query.Y1 < ni->trap.X2 + ni->trap.Y2); + r = r && (query.Y2 <= ni->trap.Y2); + if (r) { + ni->trap.Y1 = query.Y2; + ni->neighbor = box; + } + return r ? RND_R_DIR_FOUND_CONTINUE : RND_R_DIR_NOT_FOUND; +} + +/* main r_find_neighbor routine. Returns NULL if no neighbor in the + * requested direction. */ +static const rnd_box_t *r_find_neighbor(rnd_rtree_t * rtree, const rnd_box_t * box, rnd_direction_t search_direction) +{ + struct r_neighbor_info ni; + rnd_box_t bbox; + + ni.neighbor = NULL; + ni.trap = *box; + ni.search_dir = search_direction; + + bbox.X1 = bbox.Y1 = 0; + bbox.X2 = PCB->hidlib.size_x; + bbox.Y2 = PCB->hidlib.size_y; + /* rotate so that we can use the 'north' case for everything */ + RND_BOX_ROTATE_TO_NORTH(bbox, search_direction); + RND_BOX_ROTATE_TO_NORTH(ni.trap, search_direction); + /* shift Y's such that trap contains full bounds of trapezoid */ + ni.trap.Y2 = ni.trap.Y1; + ni.trap.Y1 = bbox.Y1; + /* do the search! */ + rnd_r_search(rtree, NULL, __r_find_neighbor_reg_in_sea, __r_find_neighbor_rect_in_reg, &ni, NULL); + return ni.neighbor; +} + +static int pstk_ispad(pcb_pstk_t *ps) +{ + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + return !PCB_PSTK_PROTO_CUTS(proto); +} + +/* --------------------------------------------------------------------------- + * Compute cost function. + * note that area overlap cost is correct for SMD devices: SMD devices on + * opposite sides of the board don't overlap. + * + * Algorithms follow those described in sections 4.1 of + * "Placement and Routing of Electronic Modules" edited by Michael Pecht + * Marcel Dekker, Inc. 1993. ISBN: 0-8247-8916-4 TK7868.P7.P57 1993 + */ +static double ComputeCost(double T0, double T) +{ + double W = 0; /* wire cost */ + double delta1 = 0; /* wire congestion penalty function */ + double delta2 = 0; /* module overlap penalty function */ + double delta3 = 0; /* out of bounds penalty */ + double delta4 = 0; /* alignment bonus */ + double delta5 = 0; /* total area penalty */ + rnd_cardinal_t i; + rnd_coord_t minx, maxx, miny, maxy; + rnd_bool allpads, allsameside; + rnd_cardinal_t thegroup; + rnd_box_list_t bounds = { 0, 0, NULL }; /* save bounding rectangles here */ + rnd_box_list_t solderside = { 0, 0, NULL }; /* solder side component bounds */ + rnd_box_list_t componentside = { 0, 0, NULL }; /* component side bounds */ + + + { + htsp_entry_t *e; + + /* wire length term. approximated by half-perimeter of minimum + * rectangle enclosing the net. Note that we penalize vias in + * all-SMD nets by making the rectangle a cube and weighting + * the "layer height" of the net. */ + + for(e = htsp_first(&PCB->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&PCB->netlist[PCB_NETLIST_EDITED], e)) { + pcb_net_t *net = e->value; + pcb_net_term_t *t; + pcb_any_obj_t *obj; + if (pcb_termlist_length(&net->conns) < 2) + continue; /* no cost to go nowhere */ + + t = pcb_termlist_first(&net->conns); + obj = pcb_term_find_name(PCB, PCB->Data, PCB_LYT_COPPER, t->refdes, t->term, NULL, NULL); + pcb_obj_center(obj, &maxx, &maxy); + minx = maxx; + miny = maxy; + thegroup = obj_layergrp(obj); + allpads = pstk_ispad((pcb_pstk_t *)obj); + allsameside = rnd_true; + + for(t = pcb_termlist_next(t); t != NULL; t = pcb_termlist_next(t)) { + rnd_coord_t X, Y; + obj = pcb_term_find_name(PCB, PCB->Data, PCB_LYT_COPPER, t->refdes, t->term, NULL, NULL); + pcb_obj_center(obj, &X, &Y); + RND_MAKE_MIN(minx, X); + RND_MAKE_MAX(maxx, X); + RND_MAKE_MIN(miny, Y); + RND_MAKE_MAX(maxy, Y); + if (!pstk_ispad((pcb_pstk_t *)obj)) + allpads = rnd_false; + if (obj_layergrp(obj) != thegroup) + allsameside = rnd_false; + } + /* okay, add half-perimeter to cost! */ + W += RND_COORD_TO_MIL(maxx - minx) + RND_COORD_TO_MIL(maxy - miny) + ((allpads && !allsameside) ? CostParameter.via_cost : 0); + } + } + + /* now compute penalty function Wc which is proportional to + * amount of overlap and congestion. */ + /* delta1 is congestion penalty function */ + delta1 = CostParameter.congestion_penalty * sqrt(fabs(pcb_intersect_box_box(&bounds))); +#if 0 + printf("Wire Congestion Area: %f\n", pcb_intersect_box_box(&bounds)); +#endif + /* free bounding rectangles */ + pcb_box_free(&bounds); + /* now collect module areas (bounding rect of pins/pads) */ + /* two lists for solder side / component side. */ + PCB_SUBC_LOOP(PCB->Data); + { + rnd_box_list_t *thisside, *otherside; + rnd_box_t *box, *lastbox = NULL; + rnd_coord_t clearance; + pcb_any_obj_t *o; + pcb_data_it_t it; + int onbtm = 0; + + pcb_subc_get_side(subc, &onbtm); +TODO("subc: this ignores the possibility of other-side pads; need to do this on a per object basis") + if (onbtm) { + thisside = &solderside; + otherside = &componentside; + } + else { + thisside = &componentside; + otherside = &solderside; + } + box = pcb_box_new(thisside); + /* initialize box so that it will take the dimensions of the first pin/pad outside of the normal bounding subc box */ + *box = subc->BoundingBox; + for(o = pcb_data_first(&it, subc->data, PCB_TERM_OBJ_TYPES); o != NULL; o = pcb_data_next(&it)) { +TODO("Revise this: why only terminals?! any copper or silk can collide"); + if (o->term == NULL) + continue; /* we are interested in terminals only */ + +TODO("subc: look up clearance") + clearance = 0; + EXPANDRECTXY(box, + o->BoundingBox.X1 - clearance, o->BoundingBox.Y1 - clearance, + o->BoundingBox.X2 + clearance, o->BoundingBox.Y2 + clearance); + + /* add a box for each thru-hole pin to the "opposite side": + * surface mount components can't sit on top of pins */ + if ((!CostParameter.fast) && (o->type == PCB_OBJ_PSTK)) { + rnd_box_t box2; + box2.X1 = o->BoundingBox.X1 - clearance; + box2.Y1 = o->BoundingBox.Y1 - clearance; + box2.X2 = o->BoundingBox.X2 + clearance; + box2.Y2 = o->BoundingBox.Y2 + clearance; + /* speed hack! coalesce with last box if we can */ + if (lastbox != NULL && + ((lastbox->X1 == box2.X1 && + lastbox->X2 == box2.X2 && + MIN(labs(lastbox->Y1 - box2.Y2), labs(box2.Y1 - lastbox->Y2)) < clearance) || + (lastbox->Y1 == box2.Y1 && lastbox->Y2 == box2.Y2 && MIN(labs(lastbox->X1 - box2.X2), labs(box2.X1 - lastbox->X2)) < clearance))) { + EXPANDRECT(lastbox, box); + otherside->BoxN--; + } + else + lastbox = box; + } + } + } + PCB_END_LOOP; + + /* compute intersection area of module areas box list */ + delta2 = sqrt(fabs(pcb_intersect_box_box(&solderside) + pcb_intersect_box_box(&componentside))) * (CostParameter.overlap_penalty_min + (1 - (T / T0)) * CostParameter.overlap_penalty_max); +#if 0 + printf("Module Overlap Area (solder): %f\n", pcb_intersect_box_box(&solderside)); + printf("Module Overlap Area (component): %f\n", pcb_intersect_box_box(&componentside)); +#endif + pcb_box_free(&solderside); + pcb_box_free(&componentside); + /* reward pin/pad x/y alignment */ + /* score higher if pins/pads belong to same *type* of component */ + /* XXX: subkey should be *distance* from thing aligned with, so that + * aligning to something far away isn't profitable */ + { + /* create r tree */ + vtp0_t seboxes, ceboxes; + struct ebox { + rnd_box_t box; +TODO("subc: when elements are removed, turn this into pcb_subc_t * and remove the fields below") + pcb_any_obj_t *comp; + const char *refdes; + int rot90; + rnd_box_t *vbox; + }; + rnd_direction_t dir[4] = { RND_NORTH, RND_EAST, RND_SOUTH, RND_WEST }; + struct ebox **boxpp, *boxp; + rnd_rtree_t *rt_s, *rt_c; + int factor; + + vtp0_init(&seboxes); + vtp0_init(&ceboxes); + + PCB_SUBC_LOOP(PCB->Data); + { + int onbtm = 0; + double rot = 0; + + pcb_subc_get_side(subc, &onbtm); + boxpp = (struct ebox **) vtp0_alloc_append(onbtm ? &seboxes : &ceboxes, 1); + *boxpp = (struct ebox *) malloc(sizeof(**boxpp)); + if (*boxpp == NULL) { + fprintf(stderr, "malloc() failed in ComputeCost\n"); + exit(1); + } + + pcb_subc_get_rotation(subc, &rot); + (*boxpp)->box = subc->BoundingBox; + (*boxpp)->comp = (pcb_any_obj_t *)subc; + (*boxpp)->refdes = subc->refdes; + (*boxpp)->rot90 = rnd_round(rot / 90.0); + (*boxpp)->vbox = &subc->BoundingBox; + } + PCB_END_LOOP; + + rt_s = rnd_r_create_tree(); + rnd_r_insert_array(rt_s, (const rnd_box_t **) seboxes.array, vtp0_len(&seboxes)); + rt_c = rnd_r_create_tree(); + rnd_r_insert_array(rt_c, (const rnd_box_t **) ceboxes.array, vtp0_len(&ceboxes)); + vtp0_uninit(&seboxes); + vtp0_uninit(&ceboxes); + /* now, for each subcircuit, find its neighbor on all four sides */ + delta4 = 0; + for (i = 0; i < 4; i++) { + PCB_SUBC_LOOP(PCB->Data); + { + int onbtm = 0, rot90; + double rot = 0; + + pcb_subc_get_side(subc, &onbtm); + pcb_subc_get_rotation(subc, &rot); + rot90 = rnd_round(rot / 90.0); + + boxp = (struct ebox *)r_find_neighbor(onbtm ? rt_s : rt_c, &subc->BoundingBox, dir[i]); + /* score bounding box alignments */ + if (!boxp) + continue; + factor = 1; + if (subc->refdes && boxp->refdes && 0 == RND_NSTRCMP(subc->refdes, boxp->refdes)) { + delta4 += CostParameter.matching_neighbor_bonus; + factor++; + } + if (rot90 == boxp->rot90) + delta4 += factor * CostParameter.oriented_neighbor_bonus; + if (subc->BoundingBox.X1 == boxp->vbox->X1 || + subc->BoundingBox.X1 == boxp->vbox->X2 || + subc->BoundingBox.X2 == boxp->vbox->X1 || + subc->BoundingBox.X2 == boxp->vbox->X2 || + subc->BoundingBox.Y1 == boxp->vbox->Y1 || + subc->BoundingBox.Y1 == boxp->vbox->Y2 || + subc->BoundingBox.Y2 == boxp->vbox->Y1 || + subc->BoundingBox.Y2 == boxp->vbox->Y2) + delta4 += factor * CostParameter.aligned_neighbor_bonus; + } + PCB_END_LOOP; + } + /* free k-d tree memory */ + rnd_r_free_tree_data(rt_s, free); + rnd_r_free_tree_data(rt_c, free); + rnd_r_destroy_tree(&rt_s); + rnd_r_destroy_tree(&rt_c); + } + /* penalize total area used by this layout */ + { + rnd_coord_t minX = RND_MAX_COORD, minY = RND_MAX_COORD; + rnd_coord_t maxX = -RND_MAX_COORD, maxY = -RND_MAX_COORD; + PCB_SUBC_LOOP(PCB->Data); + { + RND_MAKE_MIN(minX, subc->BoundingBox.X1); + RND_MAKE_MIN(minY, subc->BoundingBox.Y1); + RND_MAKE_MAX(maxX, subc->BoundingBox.X2); + RND_MAKE_MAX(maxY, subc->BoundingBox.Y2); + } + PCB_END_LOOP; + if (minX < maxX && minY < maxY) + delta5 = CostParameter.overall_area_penalty * sqrt(RND_COORD_TO_MIL(maxX - minX) * RND_COORD_TO_MIL(maxY - minY)); + } + if (T == 5) { + T = W + delta1 + delta2 + delta3 - delta4 + delta5; + printf("cost components are %.3f %.3f %.3f %.3f %.3f %.3f\n", + W / T, delta1 / T, delta2 / T, delta3 / T, -delta4 / T, delta5 / T); + } + /* done! */ + return W + (delta1 + delta2 + delta3 - delta4 + delta5); +} + +static rnd_bool is_smd(const pcb_any_obj_t *obj) +{ + pcb_subc_t *sc = (pcb_subc_t *)obj; + pcb_pstk_t *ps; + + + for(ps = padstacklist_first(&sc->data->padstack); ps != NULL; ps = padstacklist_next(ps)) { + pcb_pstk_proto_t *pr = pcb_pstk_get_proto(ps); + + if (pr == NULL) + continue; + + if ((pr->hdia > 0) || (pr->mech_idx >= 0)) /* a hole or slot means non-smd */ + return 0; + } + + return 1; +} + +static rnd_bool on_bottom(const pcb_any_obj_t *obj) +{ + int onbtm = 0; + pcb_subc_get_side((pcb_subc_t *)obj, &onbtm); + return onbtm; +} + +/* --------------------------------------------------------------------------- + * Perturb: + * 1) flip SMD from solder side to component side or vice-versa. + * 2) rotate component 90, 180, or 270 degrees. + * 3) shift component random + or - amount in random direction. + * (magnitude of shift decreases over time) + * -- Only perturb selected subcircuits (need count/list of selected?) -- + */ +PerturbationType createPerturbation(vtp0_t *selected, double T) +{ + PerturbationType pt = { 0 }; + /* pick subcircuit to perturb */ + pt.comp = (pcb_any_obj_t *) selected->array[rnd_rand() % vtp0_len(selected)]; + /* exchange, flip/rotate or shift? */ + switch (rnd_rand() % ((vtp0_len(selected) > 1) ? 3 : 2)) { + case 0: + { /* shift! */ + rnd_coord_t grid; + double scaleX = RND_CLAMP(sqrt(T), RND_MIL_TO_COORD(2.5), PCB->hidlib.size_x / 3); + double scaleY = RND_CLAMP(sqrt(T), RND_MIL_TO_COORD(2.5), PCB->hidlib.size_y / 3); + pt.which = SHIFT; + pt.DX = scaleX * 2 * ((((double) rnd_rand()) / RAND_MAX) - 0.5); + pt.DY = scaleY * 2 * ((((double) rnd_rand()) / RAND_MAX) - 0.5); + /* snap to grid. different grids for "high" and "low" T */ + grid = (T > RND_MIL_TO_COORD(10)) ? CostParameter.large_grid_size : CostParameter.small_grid_size; + /* (round away from zero) */ + pt.DX = ((pt.DX / grid) + SGN(pt.DX)) * grid; + pt.DY = ((pt.DY / grid) + SGN(pt.DY)) * grid; + /* limit DX/DY so we don't fall off board */ + { + pcb_subc_t *s = (pcb_subc_t *)pt.comp; + pt.DX = MAX(pt.DX, -s->BoundingBox.X1); + pt.DX = MIN(pt.DX, PCB->hidlib.size_x - s->BoundingBox.X2); + pt.DY = MAX(pt.DY, -s->BoundingBox.Y1); + pt.DY = MIN(pt.DY, PCB->hidlib.size_y - s->BoundingBox.Y2); + } + /* all done but the movin' */ + break; + } + case 1: + { /* flip/rotate! */ + /* only flip if it's an SMD component */ + rnd_bool isSMD = is_smd(pt.comp); + + pt.which = ROTATE; + pt.rotate = isSMD ? (rnd_rand() & 3) : (1 + (rnd_rand() % 3)); + /* 0 - flip; 1-3, rotate. */ + break; + } + case 2: + { /* exchange! */ + pt.which = EXCHANGE; + pt.other = (pcb_any_obj_t *)selected->array[rnd_rand() % (vtp0_len(selected) - 1)]; + if (pt.other == pt.comp) + pt.other = (pcb_any_obj_t *)selected->array[vtp0_len(selected) - 1]; + /* don't allow exchanging a solderside-side SMD component + * with a non-SMD component. */ + if ((!is_smd(pt.comp) && on_bottom(pt.other)) || + (!is_smd(pt.other) && on_bottom(pt.comp))) + return createPerturbation(selected, T); + break; + } + default: + assert(0); + } + return pt; +} + +void doPerturb(vtp0_t *selected, PerturbationType *pt, rnd_bool undo) +{ + rnd_box_t *bb; + rnd_coord_t bbcx, bbcy; + pcb_subc_t *subc = (pcb_subc_t *)pt->comp; + /* compute center of element bounding box */ + + bb = &subc->BoundingBox; + bbcx = (bb->X1 + bb->X2) / 2; + bbcy = (bb->Y1 + bb->Y2) / 2; + /* do exchange, shift or flip/rotate */ + switch (pt->which) { + case SHIFT: + { + rnd_coord_t DX = pt->DX, DY = pt->DY; + if (undo) { + DX = -DX; + DY = -DY; + } + pcb_subc_move(subc, DX, DY, 1); + return; + } + case ROTATE: + { + unsigned b = pt->rotate; + if (undo) + b = (4 - b) & 3; + /* 0 - flip; 1-3, rotate. */ + if (b) { + pcb_subc_rotate90(subc, bbcx, bbcy, b); + } + else { + rnd_cardinal_t n; + rnd_coord_t y = bb->Y1; + pcb_subc_change_side(subc, (bb->Y1+bb->Y2)/2); + /* mirroring moves the subc. move it back. */ + pcb_subc_move(subc, 0, y - subc->BoundingBox.Y1, 1); + for(n = 0; n < vtp0_len(selected); n++) + if (selected->array[n] == pt->comp) + selected->array[n] = subc; + pt->comp = (pcb_any_obj_t *)subc; + } + return; + } + case EXCHANGE: + { + /* first exchange positions */ + rnd_coord_t x1 = bb->X1; + rnd_coord_t y1 = bb->Y1; + rnd_coord_t x2 = pt->other->BoundingBox.X1; + rnd_coord_t y2 = pt->other->BoundingBox.Y1; + + pcb_subc_move(subc, x2 - x1, y2 - y1, 1); + pcb_subc_move((pcb_subc_t *)pt->other, x1 - x2, y1 - y2, 1); + + /* then flip both subcircuits if they are on opposite sides */ + if (on_bottom(pt->comp) != on_bottom(pt->other)) { + PerturbationType mypt; + mypt.comp = pt->comp; + mypt.which = ROTATE; + mypt.rotate = 0; /* flip */ + doPerturb(selected, &mypt, undo); + pt->comp = mypt.comp; + mypt.comp = pt->other; + doPerturb(selected, &mypt, undo); + pt->other = mypt.comp; + } + /* done */ + return; + } + default: + assert(0); + } +} + +/* --------------------------------------------------------------------------- + * Auto-place selected components. + */ +rnd_bool AutoPlaceSelected(void) +{ + vtp0_t Selected; + PerturbationType pt; + double C00, C0, T0; + rnd_bool changed = rnd_false; + + vtp0_init(&Selected); + + Selected = collectSelectedSubcircuits(); + if (vtp0_len(&Selected) == 0) { + rnd_message(RND_MSG_ERROR, "No subcircuits selected to autoplace.\n"); + goto done; + } + + /* simulated annealing */ + { /* compute T0 by doing a random series of moves. */ + const int TRIALS = 10; + const double Tx = RND_MIL_TO_COORD(300), P = 0.95; + double Cs = 0.0; + int i; + C00 = C0 = ComputeCost(Tx, Tx); + for (i = 0; i < TRIALS; i++) { + pt = createPerturbation(&Selected, RND_INCH_TO_COORD(1)); + doPerturb(&Selected, &pt, rnd_false); + Cs += fabs(ComputeCost(Tx, Tx) - C0); + doPerturb(&Selected, &pt, rnd_true); + } + T0 = -(Cs / TRIALS) / log(P); + printf("Initial T: %f\n", T0); + } + /* now anneal in earnest */ + { + double T = T0; + long steps = 0; + int good_moves = 0, moves = 0; + const int good_move_cutoff = CostParameter.m * vtp0_len(&Selected); + const int move_cutoff = 2 * good_move_cutoff; + printf("Starting cost is %.0f\n", ComputeCost(T0, 5)); + C0 = ComputeCost(T0, T); + while (1) { + double Cprime; + pt = createPerturbation(&Selected, T); + doPerturb(&Selected, &pt, rnd_false); + Cprime = ComputeCost(T0, T); + if (Cprime < C0) { /* good move! */ + C0 = Cprime; + good_moves++; + steps++; + } + else if ((rnd_rand() / (double) RAND_MAX) < exp(MIN(MAX(-20, (C0 - Cprime) / T), 20))) { + /* not good but keep it anyway */ + C0 = Cprime; + steps++; + } + else + doPerturb(&Selected, &pt, rnd_true); /* undo last change */ + moves++; + /* are we at the end of a stage? */ + if (good_moves >= good_move_cutoff || moves >= move_cutoff) { + printf("END OF STAGE: COST %.0f\t" "GOOD_MOVES %d\tMOVES %d\t" "T: %.1f\n", C0, good_moves, moves, T); + pcb_draw(); + if (rnd_hid_progress(C00-T, C00, "Optimizing the placement...")) + break; + /* is this the end? */ + if (T < 5 || good_moves < moves / CostParameter.good_ratio) + break; + /* nope, adjust T and continue */ + moves = good_moves = 0; + T *= CostParameter.gamma; + /* cost is T dependent, so recompute */ + C0 = ComputeCost(T0, T); + } + } + changed = (steps > 0); + } +done: + rnd_hid_progress(0, 0, NULL); + if (changed) { + pcb_rats_destroy(rnd_false); + pcb_net_add_all_rats(PCB, PCB_RATACC_PRECISE); + rnd_hid_redraw(PCB); + } + vtp0_uninit(&Selected); + return changed; +} Index: tags/2.3.0/src_plugins/autoplace/autoplace.h =================================================================== --- tags/2.3.0/src_plugins/autoplace/autoplace.h (nonexistent) +++ tags/2.3.0/src_plugins/autoplace/autoplace.h (revision 33253) @@ -0,0 +1,45 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1998,1999,2000,2001 harry eaton + * + * this file, autoplace.h, was written and is + * Copyright (c) 2001 C. Scott Ananian. + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#ifndef PCB_AUTOPLACE_H +#define PCB_AUTOPLACE_H + +#include + +rnd_bool AutoPlaceSelected(void); + +#endif Index: tags/2.3.0/src_plugins/autoplace/autoplace.pup =================================================================== --- tags/2.3.0/src_plugins/autoplace/autoplace.pup (nonexistent) +++ tags/2.3.0/src_plugins/autoplace/autoplace.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short auto place components +$long Automatically place subcircuits. +$package auto +$state works +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/autoroute/Makefile =================================================================== --- tags/2.3.0/src_plugins/autoroute/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/autoroute/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_autoroute + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/autoroute/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/autoroute/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/autoroute/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {autoroute} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/autoroute/autoroute.o $(PLUGDIR)/autoroute/mtspace.o $(PLUGDIR)/autoroute/action.o $(PLUGDIR)/autoroute/vector.o @] + +switch /local/pcb/autoroute/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/autoroute/action.c =================================================================== --- tags/2.3.0/src_plugins/autoroute/action.c (nonexistent) +++ tags/2.3.0/src_plugins/autoroute/action.c (revision 33253) @@ -0,0 +1,90 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" +#include "autoroute.h" +#include +#include +#include +#include "funchash_core.h" + +static const char pcb_acts_AutoRoute[] = "AutoRoute(AllRats|SelectedRats)"; +static const char pcb_acth_AutoRoute[] = "Auto-route some or all rat lines."; +/* DOC: autoroute.html */ +static fgw_error_t pcb_act_AutoRoute(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + + RND_ACT_CONVARG(1, FGW_KEYWORD, AutoRoute, op = fgw_keyword(&argv[1])); + + rnd_hid_busy(PCB, 1); + switch(op) { + case F_AllRats: + case F_All: + if (AutoRoute(rnd_false)) + pcb_board_set_changed_flag(PCB, rnd_true); + break; + case F_SelectedRats: + case F_Selected: + if (AutoRoute(rnd_true)) + pcb_board_set_changed_flag(PCB, rnd_true); + break; + default: + RND_ACT_FAIL(AutoRoute); + return 1; + } + rnd_hid_busy(PCB, 0); + RND_ACT_IRES(0); + return 0; +} + +static const char *autoroute_cookie = "autoroute plugin"; + +rnd_action_t autoroute_action_list[] = { + {"AutoRoute", pcb_act_AutoRoute, pcb_acth_AutoRoute, pcb_acts_AutoRoute}, +}; + +int pplg_check_ver_autoroute(int ver_needed) { return 0; } + +void pplg_uninit_autoroute(void) +{ + rnd_remove_actions_by_cookie(autoroute_cookie); +} + +int pplg_init_autoroute(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(autoroute_action_list, autoroute_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/autoroute/autoroute.c =================================================================== --- tags/2.3.0/src_plugins/autoroute/autoroute.c (nonexistent) +++ tags/2.3.0/src_plugins/autoroute/autoroute.c (revision 33253) @@ -0,0 +1,4783 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1998,1999,2000,2001 harry eaton + * + * this file, autoroute.c, was written and is + * Copyright (c) 2001 C. Scott Ananian + * Copyright (c) 2006 harry eaton + * Copyright (c) 2009 harry eaton + * + * Updated for pcb-rnd for subcircuits, padstacks and netlist + * Copyright (c) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +/* + *------------------------------------------------------------------- + * This file implements a rectangle-expansion router, based on + * "A Method for Gridless Routing of Printed Circuit Boards" by + * A. C. Finch, K. J. Mackenzie, G. J. Balsdon, and G. Symonds in the + * 1985 Proceedings of the 22nd ACM/IEEE Design Automation Conference. + * This reference is available from the ACM Digital Library at + * http://www.acm.org/dl for those with institutional or personal + * access to it. It's also available from your local engineering + * library. + * + * The code is much closer to what is described in the paper now, + * in that expansion areas can grow from corners and in all directions + * at once. Previously, these were emulated with discrete boxes moving + * in the cardinal directions. With the new method, there are fewer but + * larger expansion boxes that one might do a better job of routing in. + *-------------------------------------------------------------------- + */ +#define NET_HEAP 1 +#include "config.h" +#include "conf_core.h" + +#include +#include + +#include "data.h" +#include "autoroute.h" +#include +#include "draw.h" +#include "box_dir.h" +#include +#include "find.h" +#include +#include +#include "netlist.h" +#include "mtspace.h" +#include "polygon.h" +#include "remove.h" +#include "obj_pinvia_therm.h" +#include "undo.h" +#include "vector.h" +#include +#include "layer.h" +#include +#include "layer.h" + +#include "obj_line_draw.h" +#include "obj_pstk_draw.h" +#include "obj_pstk_inlines.h" + +TODO("padstack: when style contains proto, remove this") +#include "src_plugins/lib_compat_help/pstk_compat.h" + +#define autoroute_therm_style 4 + +/* #defines to enable some debugging output */ +/* +#define ROUTE_VERBOSE +*/ + +/* +#define ROUTE_DEBUG +//#define DEBUG_SHOW_ROUTE_BOXES +#define DEBUG_SHOW_EXPANSION_BOXES +//#define DEBUG_SHOW_EDGES +//#define DEBUG_SHOW_VIA_BOXES +#define DEBUG_SHOW_TARGETS +#define DEBUG_SHOW_SOURCES +//#define DEBUG_SHOW_ZIGZAG +*/ + +static rnd_direction_t directionIncrement(rnd_direction_t dir) +{ + switch (dir) { + case RND_NORTH: + dir = RND_EAST; + break; + case RND_EAST: + dir = RND_SOUTH; + break; + case RND_SOUTH: + dir = RND_WEST; + break; + case RND_WEST: + dir = RND_NE; + break; + case RND_NE: + dir = RND_SE; + break; + case RND_SE: + dir = RND_SW; + break; + case RND_SW: + dir = RND_NW; + break; + case RND_NW: + dir = RND_ANY_DIR; + break; + case RND_ANY_DIR: + dir = RND_NORTH; + break; + } + return dir; +} + +#ifdef ROUTE_DEBUG +rnd_hid_t *ddraw = NULL; +static rnd_hid_gc_t ar_gc = 0; +#endif + +#define EXPENSIVE 3e28 +/* round up "half" thicknesses */ +#define HALF_THICK(x) (((x)+1)/2) +/* a styles maximum bloat is its clearance plus the larger of its via radius + * or line half-thickness. */ +#define BLOAT(style)\ + ((style)->Clearance + HALF_THICK((style)->Thick)) +/* conflict penalty is less for traces laid down during previous pass than + * it is for traces already laid down in this pass. */ +#define CONFLICT_LEVEL(rb)\ + (((rb)->flags.is_odd==AutoRouteParameters.is_odd) ?\ + HI_CONFLICT : LO_CONFLICT ) +#define CONFLICT_PENALTY(rb)\ + ((CONFLICT_LEVEL(rb)==HI_CONFLICT ? \ + AutoRouteParameters.ConflictPenalty : \ + CONFLICT_LEVEL(rb)==LO_CONFLICT ? \ + AutoRouteParameters.LastConflictPenalty : 1) * (rb)->pass) + +#define _NORTH 1 +#define _EAST 2 +#define _SOUTH 4 +#define _WEST 8 + +#define LIST_LOOP(init, which, x) do {\ + routebox_t *__next_one__ = (init);\ + x = NULL;\ + if (!__next_one__)\ + assert(__next_one__);\ + else\ + while (!x || __next_one__ != (init)) {\ + x = __next_one__;\ + /* save next one first in case the command modifies or frees it */\ + __next_one__ = x->which.next +#define FOREACH_SUBNET(net, p) do {\ + routebox_t *_pp_;\ + /* iterate through *distinct* subnets */\ + LIST_LOOP(net, same_net, p); \ + if (!p->flags.subnet_processed) {\ + LIST_LOOP(p, same_subnet, _pp_);\ + _pp_->flags.subnet_processed=1;\ + PCB_END_LOOP +#define END_FOREACH(net, p) \ + }; \ + PCB_END_LOOP;\ + /* reset subnet_processed flags */\ + LIST_LOOP(net, same_net, p); \ + p->flags.subnet_processed=0;\ + PCB_END_LOOP;\ +} while (0) +#define SWAP(t, f, s) do { t a=s; s=f; f=a; } while (0) +/* notes: + * all rectangles are assumed to be closed on the top and left and + * open on the bottom and right. That is, they include their top-left + * corner but don't include their bottom and right edges. + * + * expansion regions are always half-closed. This means that when + * tracing paths, you must steer clear of the bottom and right edges., + * because these are not actually in the allowed box. + * + * All routeboxes *except* EXPANSION_AREAS now have their "box" bloated by + * their particular required clearance. This simplifies the tree searching. + * the "sbox" contains the unbloated box. + */ + +/* enumerated type for conflict levels */ +typedef enum { NO_CONFLICT = 0, LO_CONFLICT = 1, HI_CONFLICT = 2 } conflict_t; + +typedef struct routebox_s routebox_t; + +typedef struct routebox_list_s { + routebox_t *next, *prev; +} routebox_list_t; + +typedef enum etype { TERM, VIA, VIA_SHADOW, LINE, OTHER, EXPANSION_AREA, PLANE, THERMAL } etype; + +struct routebox_s { + rnd_box_t box, sbox; + struct { + rnd_coord_t x1, y1, x2, y2; + } line; /* exact coords of the line we are going to draw if type is line; reverse engineering these from the bounding box using halfthick and other hacks lead to rounding errors, a few LSB flicker in coords, e.g. breaking rubber band */ + union { + pcb_pstk_t *via; + pcb_any_obj_t *term; + routebox_t *via_shadow; /* points to the via in r-tree which + * points to the pcb_pstk_t in the PCB. */ + pcb_line_t *line; + void *generic; /* 'other' is polygon, arc, text */ + routebox_t *expansion_area; /* previous expansion area in search */ + } parent; + unsigned short group; + unsigned short layer; + etype type; + struct { + unsigned nonstraight:1; + unsigned fixed:1; + /* for searches */ + unsigned source:1; + unsigned target:1; + /* rects on same net as source and target don't need clearance areas */ + unsigned nobloat:1; + /* mark circular pins, so that we be sure to connect them up properly */ + unsigned circular:1; + /* we sometimes create routeboxen that don't actually belong to a + * r-tree yet -- make sure refcount of homelesss is set properly */ + unsigned homeless:1; + /* was this nonfixed obstacle generated on an odd or even pass? */ + unsigned is_odd:1; + /* fixed route boxes that have already been "routed through" in this + * search have their "touched" flag set. */ + unsigned touched:1; + /* this is a status bit for iterating through *different* subnets */ + unsigned subnet_processed:1; + /* some expansion_areas represent via candidates */ + unsigned is_via:1; + /* mark non-straight lines which go from bottom-left to upper-right, + * instead of from upper-left to bottom-right. */ + unsigned bl_to_ur:1; + /* mark polygons which are "transparent" for via-placement; that is, + * vias through the polygon will automatically be given a clearance + * and will not electrically connect to the polygon. */ + unsigned clear_poly:1; + /* this marks "conflicting" routes that must be torn up to obtain + * a correct routing. This flag allows us to return a correct routing + * even if the user cancels auto-route after a non-final pass. */ + unsigned is_bad:1; + /* for assertion that 'box' is never changed after creation */ + unsigned inited:1; + /* indicate this expansion ares is a thermal between the pin and plane */ + unsigned is_thermal; + } flags; + /* indicate the direction an expansion box came from */ + rnd_heap_cost_t cost; + rnd_cheap_point_t cost_point; + /* reference count for homeless routeboxes; free when refcount==0 */ + int refcount; + /* when routing with conflicts, we keep a record of what we're + * conflicting with. + */ + vector_t *conflicts_with; + /* route style of the net associated with this routebox */ + pcb_route_style_t *style; + /* congestion values for the edges of an expansion box */ + unsigned char n, e, s, w; + /* what pass this this track was laid down on */ + unsigned char pass; + /* the direction this came from, if any */ + rnd_direction_t came_from; + /* circular lists with connectivity information. */ + routebox_list_t same_net, same_subnet, original_subnet, different_net; + union { + pcb_pstk_t *via; + pcb_line_t *line; + } livedraw_obj; +}; + +typedef struct routedata_s { + int max_styles; + /* one rtree per layer *group */ + rnd_rtree_t *layergrouptree[PCB_MAX_LAYERGRP]; /* no silkscreen layers here =) */ + /* root pointer into connectivity information */ + routebox_t *first_net; + /* default routing style */ + pcb_route_style_t defaultstyle; + /* style structures */ + pcb_route_style_t **styles; /* [max_styles+1] */ + /* what is the maximum bloat (clearance+line half-width or + * clearance+via_radius) for any style we've seen? */ + rnd_coord_t max_bloat; + rnd_coord_t max_keep; + mtspace_t *mtspace; +} routedata_t; + +typedef struct edge_struct_s { + routebox_t *rb; /* path expansion edges are real routeboxen. */ + rnd_cheap_point_t cost_point; + rnd_heap_cost_t pcb_cost_to_point; /* from source */ + rnd_heap_cost_t cost; /* cached edge cost */ + routebox_t *minpcb_cost_target; /* minimum cost from cost_point to any target */ + vetting_t *work; /* for via search edges */ + rnd_direction_t expand_dir; + struct { + /* this indicates that this 'edge' is a via candidate. */ + unsigned is_via:1; + /* record "conflict level" of via candidates, in case we need to split + * them later. */ + unsigned via_conflict_level:2; /* conflict_t */ + /* when "routing with conflicts", sometimes edge is interior. */ + unsigned is_interior:1; + /* this is a fake edge used to defer searching for via spaces */ + unsigned via_search:1; + /* this is a via edge in a plane where the cost point moves for free */ + unsigned in_plane:1; + } flags; +} edge_t; + +static struct AutoRouteParameters_s { + /* net style parameters */ + pcb_route_style_t *style; + /* the present bloat */ + rnd_coord_t bloat; + /* cost parameters */ + rnd_heap_cost_t ViaCost, /* additional "length" cost for using a via */ + LastConflictPenalty, /* length mult. for routing over last pass' trace */ + ConflictPenalty, /* length multiplier for routing over another trace */ + JogPenalty, /* additional "length" cost for changing direction */ + CongestionPenalty, /* (rational) length multiplier for routing in */ + NewLayerPenalty, /* penalty for routing on a previously unused layer */ + MinPenalty; /* smallest Direction Penalty */ + /* maximum conflict incidence before calling it "no path found" */ + int hi_conflict; + /* are vias allowed? */ + rnd_bool use_vias; + /* is this an odd or even pass? */ + rnd_bool is_odd; + /* permit conflicts? */ + rnd_bool with_conflicts; + /* is this a final "smoothing" pass? */ + rnd_bool is_smoothing; + /* rip up nets regardless of conflicts? */ + rnd_bool rip_always; + rnd_bool last_smooth; + unsigned char pass; +} AutoRouteParameters; + +typedef struct routeone_state_s { + /* heap of all candidate expansion edges */ + rnd_heap_t *workheap; + /* information about the best path found so far. */ + routebox_t *best_path, *best_target; + rnd_heap_cost_t best_cost; +} routeone_state_t; + + +static routebox_t *CreateExpansionArea(const rnd_box_t * area, rnd_cardinal_t group, + routebox_t * parent, rnd_bool relax_edge_requirements, edge_t * edge); + +static rnd_heap_cost_t edge_cost(const edge_t * e, const rnd_heap_cost_t too_big); +static void best_path_candidate(routeone_state_t *s, edge_t * e, routebox_t * best_target); + +static rnd_box_t edge_to_box(const routebox_t * rb, rnd_direction_t expand_dir); + +static void add_or_destroy_edge(routeone_state_t *s, edge_t * e); + +static void +RD_DrawThermal(routedata_t * rd, rnd_coord_t X, rnd_coord_t Y, rnd_cardinal_t group, rnd_cardinal_t layer, routebox_t * subnet, rnd_bool is_bad); +static void ResetSubnet(routebox_t * net); +#ifdef ROUTE_DEBUG +static int showboxen = -2; +static int aabort = 0; +static void showroutebox(routebox_t * rb); +#endif + +/* group number of groups that hold surface mount pads */ +static rnd_layergrp_id_t front, back; +static rnd_bool usedGroup[PCB_MAX_LAYERGRP]; +static int x_cost[PCB_MAX_LAYERGRP], y_cost[PCB_MAX_LAYERGRP]; +static rnd_bool is_layer_group_active[PCB_MAX_LAYERGRP]; +static int ro = 0; +static int smoothes = 1; +static int passes = 12; +static int routing_layers = 0; +static float total_wire_length = 0; +static int total_via_count = 0; + +/* assertion helper for routeboxen */ +#ifndef NDEBUG +static int __routepcb_box_is_good(routebox_t * rb) +{ + assert(rb && (rb->group < pcb_max_group(PCB)) && + (rb->box.X1 <= rb->box.X2) && (rb->box.Y1 <= rb->box.Y2) && + (rb->flags.homeless ? + (rb->box.X1 != rb->box.X2) || (rb->box.Y1 != rb->box.Y2) : (rb->box.X1 != rb->box.X2) && (rb->box.Y1 != rb->box.Y2))); + assert((rb->flags.source ? rb->flags.nobloat : 1) && + (rb->flags.target ? rb->flags.nobloat : 1) && + (rb->flags.homeless ? !rb->flags.touched : rb->refcount == 0) && (rb->flags.touched ? rb->type != EXPANSION_AREA : 1)); + assert((rb->flags.is_odd ? (!rb->flags.fixed) && + (rb->type == VIA || rb->type == VIA_SHADOW || rb->type == LINE || rb->type == PLANE) : 1)); + assert(rb->flags.clear_poly ? ((rb->type == OTHER || rb->type == PLANE) && rb->flags.fixed && !rb->flags.homeless) : 1); + assert(rb->flags.inited); +/* run through conflict list showing none are homeless, targets or sources */ + if (rb->conflicts_with) { + int i; + for (i = 0; i < vector_size(rb->conflicts_with); i++) { + routebox_t *c = vector_element(rb->conflicts_with, i); + assert(!c->flags.homeless && !c->flags.source && !c->flags.target && !c->flags.fixed); + } + } + assert(rb->style != NULL && rb->style != NULL); + assert(rb->type == EXPANSION_AREA + || (rb->same_net.next && rb->same_net.prev && rb->same_subnet.next + && rb->same_subnet.prev && rb->original_subnet.next + && rb->original_subnet.prev && rb->different_net.next && rb->different_net.prev)); + return 1; +} + +static int __edge_is_good(edge_t * e) +{ + assert(e && e->rb && __routepcb_box_is_good(e->rb)); + assert((e->rb->flags.homeless ? e->rb->refcount > 0 : 1)); + assert((0 <= e->expand_dir) && (e->expand_dir < 9) + && (e->flags.is_interior ? (e->expand_dir == RND_ANY_DIR && e->rb->conflicts_with) : 1)); + assert((e->flags.is_via ? e->rb->flags.is_via : 1) + && (e->flags.via_conflict_level >= 0 && e->flags.via_conflict_level <= 2) + && (e->flags.via_conflict_level != 0 ? e->flags.is_via : 1)); + assert((e->pcb_cost_to_point >= 0) && e->cost >= 0); + return 1; +} + +int no_planes(const rnd_box_t * b, void *cl) +{ + routebox_t *rb = (routebox_t *) b; + if (rb->type == PLANE) + return 0; + return 1; +} +#endif /* !NDEBUG */ + +/*--------------------------------------------------------------------- + * route utility functions. + */ + +enum boxlist { NET, SUBNET, ORIGINAL, DIFFERENT_NET }; +static routebox_list_t *__select_list(routebox_t * r, enum boxlist which) +{ + assert(r); + switch (which) { + default: + assert(0); + case NET: + return &(r->same_net); + case SUBNET: + return &(r->same_subnet); + case ORIGINAL: + return &(r->original_subnet); + case DIFFERENT_NET: + return &(r->different_net); + } +} + +static void InitLists(routebox_t * r) +{ + static enum boxlist all[] = { NET, SUBNET, ORIGINAL, DIFFERENT_NET } + , *p; + for (p = all; p < all + (sizeof(all) / sizeof(*p)); p++) { + routebox_list_t *rl = __select_list(r, *p); + rl->prev = rl->next = r; + } +} + +static void MergeNets(routebox_t * a, routebox_t * b, enum boxlist which) +{ + routebox_list_t *al, *bl, *anl, *bnl; + routebox_t *an, *bn; + assert(a && b); + assert(a != b); + assert(a->type != EXPANSION_AREA); + assert(b->type != EXPANSION_AREA); + al = __select_list(a, which); + bl = __select_list(b, which); + assert(al && bl); + an = al->next; + bn = bl->next; + assert(an && bn); + anl = __select_list(an, which); + bnl = __select_list(bn, which); + assert(anl && bnl); + bl->next = an; + anl->prev = b; + al->next = bn; + bnl->prev = a; +} + +static void RemoveFromNet(routebox_t * a, enum boxlist which) +{ + routebox_list_t *al, *anl, *apl; + routebox_t *an, *ap; + assert(a); + al = __select_list(a, which); + assert(al); + an = al->next; + ap = al->prev; + if (an == a || ap == a) + return; /* not on any list */ + assert(an && ap); + anl = __select_list(an, which); + apl = __select_list(ap, which); + assert(anl && apl); + anl->prev = ap; + apl->next = an; + al->next = al->prev = a; + return; +} + +static void init_const_box(routebox_t * rb, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t clearance) +{ + rnd_box_t *bp = (rnd_box_t *) & rb->box; /* note discarding const! */ + assert(!rb->flags.inited); + assert(X1 <= X2 && Y1 <= Y2); + bp->X1 = X1 - clearance; + bp->Y1 = Y1 - clearance; + bp->X2 = X2 + clearance; + bp->Y2 = Y2 + clearance; + bp = (rnd_box_t *) & rb->sbox; + bp->X1 = X1; + bp->Y1 = Y1; + bp->X2 = X2; + bp->Y2 = Y2; + rb->flags.inited = 1; +} + +static inline rnd_box_t shrink_routebox(const routebox_t * rb) +{ + return rb->sbox; +} + +static inline rnd_heap_cost_t box_area(const rnd_box_t b) +{ + rnd_heap_cost_t ans = b.X2 - b.X1; + return ans * (b.Y2 - b.Y1); +} + +static inline rnd_cheap_point_t closest_point_in_routebox(const rnd_cheap_point_t * from, const routebox_t * rb) +{ + return rnd_closest_cheap_point_in_box(from, &rb->sbox); +} + +static inline rnd_bool point_in_shrunk_box(const routebox_t * box, rnd_coord_t X, rnd_coord_t Y) +{ + rnd_box_t b = shrink_routebox(box); + return rnd_point_in_box(&b, X, Y); +} + +/*--------------------------------------------------------------------- + * routedata initialization functions. + */ +static routebox_t *AddTerm_(vtp0_t layergroupboxes[], pcb_any_obj_t *term, pcb_route_style_t *style, pcb_layer_t *layer) +{ + routebox_t **rbpp; + pcb_layer_type_t lyt; + int layergroup = -1; + rnd_coord_t clr; + + lyt = pcb_layer_flags_(layer); + if (!(lyt & PCB_LYT_COPPER)) + return NULL; + if (lyt & PCB_LYT_TOP) + layergroup = front; + else if (lyt & PCB_LYT_BOTTOM) + layergroup = back; + else { + if (term->type != PCB_OBJ_PSTK) + assert(!"won't route to pad on internal layer"); + layergroup = pcb_layer_get_group_(layer); + } + assert(0 <= layergroup && layergroup < pcb_max_group(PCB)); + + assert(PCB->LayerGroups.grp[layergroup].len > 0); + rbpp = (routebox_t **)vtp0_alloc_append(&layergroupboxes[layergroup], 1); + assert(rbpp); + *rbpp = (routebox_t *)calloc(sizeof(**rbpp), 1); + assert(*rbpp); + (*rbpp)->group = layergroup; + clr = pcb_obj_clearance_at(PCB, term, layer); + init_const_box(*rbpp, + /*X1 */ term->BoundingBox.X1 + clr, + /*Y1 */ term->BoundingBox.Y1 + clr, + /*X2 */ term->BoundingBox.X2 - clr, + /*Y2 */ term->BoundingBox.Y2 - clr, + style->Clearance); + /* kludge for non-manhattan pads (which are not allowed at present) */ +TODO("term:") +/* + if (pad->Point1.X != pad->Point2.X && pad->Point1.Y != pad->Point2.Y) + (*rbpp)->flags.nonstraight = 1; +*/ + (*rbpp)->flags.nonstraight = 0; /* otherwise the autorouter just ignores it */ + /* set aux. properties */ + (*rbpp)->type = TERM; + (*rbpp)->parent.term = term; + (*rbpp)->flags.fixed = 1; + (*rbpp)->came_from = RND_ANY_DIR; + (*rbpp)->style = style; + /* circular lists */ + InitLists(*rbpp); + return *rbpp; +} + +static routebox_t *AddTerm(vtp0_t layergroupboxes[], pcb_any_obj_t *term, pcb_route_style_t *style) +{ + assert(term->parent_type == PCB_PARENT_LAYER); + return AddTerm_(layergroupboxes, term, style, term->parent.layer); +} + +static routebox_t *AddPstk(vtp0_t layergroupboxes[], pcb_pstk_t *ps, pcb_route_style_t *style) +{ + int i; + routebox_t *r, *last = NULL; + + for (i = 0; i < pcb_max_group(PCB); i++) { + if (pcb_pstk_shape_at(PCB, ps, &PCB->Data->Layer[i]) != NULL) { + r = AddTerm_(layergroupboxes, (pcb_any_obj_t *)ps, style, &PCB->Data->Layer[i]); + if (r != NULL) { + if (last != NULL) { + MergeNets(r, last, NET); + MergeNets(r, last, SUBNET); + MergeNets(r, last, ORIGINAL); + } + last = r; + } + } + } + + return last; +} + + +static routebox_t *AddLine(vtp0_t layergroupboxes[], int layergroup, pcb_line_t *line, + pcb_line_t *ptr, pcb_route_style_t * style) +{ + routebox_t **rbpp; + assert(layergroupboxes && line); + assert(0 <= layergroup && layergroup < pcb_max_group(PCB)); + assert(PCB->LayerGroups.grp[layergroup].len > 0); + + rbpp = (routebox_t **) vtp0_alloc_append(&layergroupboxes[layergroup], 1); + *rbpp = (routebox_t *) malloc(sizeof(**rbpp)); + memset(*rbpp, 0, sizeof(**rbpp)); + (*rbpp)->group = layergroup; + init_const_box(*rbpp, + /*X1 */ MIN(line->Point1.X, + line->Point2.X) - HALF_THICK(line->Thickness), + /*Y1 */ MIN(line->Point1.Y, + line->Point2.Y) - HALF_THICK(line->Thickness), + /*X2 */ MAX(line->Point1.X, + line->Point2.X) + HALF_THICK(line->Thickness), + /*Y2 */ MAX(line->Point1.Y, + line->Point2.Y) + HALF_THICK(line->Thickness), style->Clearance); + /* kludge for non-manhattan lines */ + if (line->Point1.X != line->Point2.X && line->Point1.Y != line->Point2.Y) { + (*rbpp)->flags.nonstraight = 1; + (*rbpp)->flags.bl_to_ur = + (MIN(line->Point1.X, line->Point2.X) == line->Point1.X) != (MIN(line->Point1.Y, line->Point2.Y) == line->Point1.Y); +#if defined(ROUTE_DEBUG) && defined(DEBUG_SHOW_ZIGZAG) + showroutebox(*rbpp); +#endif + } + /* set aux. properties */ + (*rbpp)->type = LINE; + (*rbpp)->line.x1 = line->Point1.X; + (*rbpp)->line.y1 = line->Point1.Y; + (*rbpp)->line.x2 = line->Point2.X; + (*rbpp)->line.y2 = line->Point2.Y; + (*rbpp)->parent.line = ptr; + (*rbpp)->flags.fixed = 1; + (*rbpp)->came_from = RND_ANY_DIR; + (*rbpp)->style = style; + /* circular lists */ + InitLists(*rbpp); + return *rbpp; +} + +static routebox_t *AddIrregularObstacle(vtp0_t layergroupboxes[], + rnd_coord_t X1, rnd_coord_t Y1, + rnd_coord_t X2, rnd_coord_t Y2, rnd_cardinal_t layergroup, void *parent, pcb_route_style_t * style) +{ + routebox_t **rbpp; + rnd_coord_t keep = style->Clearance; + assert(layergroupboxes && parent); + assert(X1 <= X2 && Y1 <= Y2); + assert(0 <= layergroup && layergroup < pcb_max_group(PCB)); + assert(PCB->LayerGroups.grp[layergroup].len > 0); + + rbpp = (routebox_t **) vtp0_alloc_append(&layergroupboxes[layergroup], 1); + *rbpp = (routebox_t *) malloc(sizeof(**rbpp)); + memset(*rbpp, 0, sizeof(**rbpp)); + (*rbpp)->group = layergroup; + init_const_box(*rbpp, X1, Y1, X2, Y2, keep); + (*rbpp)->flags.nonstraight = 1; + (*rbpp)->type = OTHER; + (*rbpp)->parent.generic = parent; + (*rbpp)->flags.fixed = 1; + (*rbpp)->style = style; + /* circular lists */ + InitLists(*rbpp); + return *rbpp; +} + +static routebox_t *AddPolygon(vtp0_t layergroupboxes[], rnd_cardinal_t layer, pcb_poly_t *polygon, pcb_route_style_t * style) +{ + int is_not_rectangle = 1; + rnd_layergrp_id_t layergroup = pcb_layer_get_group(PCB, layer); + routebox_t *rb; + assert(0 <= layergroup && layergroup < pcb_max_group(PCB)); + rb = AddIrregularObstacle(layergroupboxes, + polygon->BoundingBox.X1, + polygon->BoundingBox.Y1, + polygon->BoundingBox.X2, polygon->BoundingBox.Y2, layergroup, polygon, style); + if (polygon->PointN == 4 && + polygon->HoleIndexN == 0 && + (polygon->Points[0].X == polygon->Points[1].X || + polygon->Points[0].Y == polygon->Points[1].Y) && + (polygon->Points[1].X == polygon->Points[2].X || + polygon->Points[1].Y == polygon->Points[2].Y) && + (polygon->Points[2].X == polygon->Points[3].X || + polygon->Points[2].Y == polygon->Points[3].Y) && + (polygon->Points[3].X == polygon->Points[0].X || polygon->Points[3].Y == polygon->Points[0].Y)) + is_not_rectangle = 0; + rb->flags.nonstraight = is_not_rectangle; + rb->layer = layer; + rb->came_from = RND_ANY_DIR; + if (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLY, polygon)) { + rb->flags.clear_poly = 1; + if (!is_not_rectangle) + rb->type = PLANE; + } + return rb; +} + +static void AddText(vtp0_t layergroupboxes[], rnd_cardinal_t layergroup, pcb_text_t *text, pcb_route_style_t * style) +{ + AddIrregularObstacle(layergroupboxes, + text->BoundingBox.X1, text->BoundingBox.Y1, + text->BoundingBox.X2, text->BoundingBox.Y2, layergroup, text, style); +} + +static routebox_t *AddArc(vtp0_t layergroupboxes[], rnd_cardinal_t layergroup, pcb_arc_t *arc, pcb_route_style_t * style) +{ + return AddIrregularObstacle(layergroupboxes, + arc->BoundingBox.X1, arc->BoundingBox.Y1, + arc->BoundingBox.X2, arc->BoundingBox.Y2, layergroup, arc, style); +} + +struct rb_info { + rnd_box_t query; + routebox_t *winner; + jmp_buf env; +}; + +static rnd_r_dir_t __found_one_on_lg(const rnd_box_t * box, void *cl) +{ + struct rb_info *inf = (struct rb_info *) cl; + routebox_t *rb = (routebox_t *) box; + rnd_box_t sb; + + if (rb->flags.nonstraight) + return RND_R_DIR_NOT_FOUND; + sb = rnd_shrink_box(&rb->box, rb->style->Clearance); + if (inf->query.X1 >= sb.X2 || inf->query.X2 <= sb.X1 || inf->query.Y1 >= sb.Y2 || inf->query.Y2 <= sb.Y1) + return RND_R_DIR_NOT_FOUND; + inf->winner = rb; + if (rb->type == PLANE) + return RND_R_DIR_FOUND_CONTINUE; /* keep looking for something smaller if a plane was found */ + longjmp(inf->env, 1); + return RND_R_DIR_NOT_FOUND; +} + +static routebox_t *FindRouteBoxOnLayerGroup(routedata_t * rd, rnd_coord_t X, rnd_coord_t Y, rnd_cardinal_t layergroup) +{ + struct rb_info info; + info.winner = NULL; + info.query = rnd_point_box(X, Y); + if (setjmp(info.env) == 0) + rnd_r_search(rd->layergrouptree[layergroup], &info.query, NULL, __found_one_on_lg, &info, NULL); + return info.winner; +} + +#ifdef ROUTE_DEBUG_VERBOSE +static void DumpRouteBox(routebox_t * rb) +{ + rnd_printf("RB: %#mD-%#mD l%d; ", rb->box.X1, rb->box.Y1, rb->box.X2, rb->box.Y2, (int) rb->group); + switch (rb->type) { + case TERM: + printf("TERM[%s] ", rb->parent.term->term); + break; + case LINE: + printf("LINE "); + break; + case OTHER: + printf("OTHER "); + break; + case EXPANSION_AREA: + printf("EXPAREA "); + break; + default: + printf("UNKNOWN "); + break; + } + if (rb->flags.nonstraight) + printf("(nonstraight) "); + if (rb->flags.fixed) + printf("(fixed) "); + if (rb->flags.source) + printf("(source) "); + if (rb->flags.target) + printf("(target) "); + if (rb->flags.homeless) + printf("(homeless) "); + printf("\n"); +} +#endif + +/* Add obstacles extracting them from data (subc-recursive) */ +static void CreateRouteData_subc(routedata_t *rd, vtp0_t layergroupboxes[], pcb_data_t *data) +{ + int i; + + PCB_PADSTACK_LOOP(data); + { + if (PCB_FLAG_TEST(PCB_FLAG_DRC, padstack)) + PCB_FLAG_CLEAR(PCB_FLAG_DRC, padstack); + else + AddPstk(layergroupboxes, padstack, rd->styles[rd->max_styles]); + } + PCB_END_LOOP; + + for (i = 0; i < data->LayerN; i++) { + rnd_layergrp_id_t layergroup; + pcb_layer_t *ly = &data->Layer[i]; + + if (!(pcb_layer_flags_(ly) & PCB_LYT_COPPER)) + continue; + + layergroup = pcb_layer_get_group_(ly); + + /* add all (non-rat) lines */ + PCB_LINE_LOOP(ly); + { + if (PCB_FLAG_TEST(PCB_FLAG_DRC, line)) { + PCB_FLAG_CLEAR(PCB_FLAG_DRC, line); + continue; + } + /* dice up non-straight lines into many tiny obstacles */ + if (line->Point1.X != line->Point2.X && line->Point1.Y != line->Point2.Y) { + pcb_line_t fake_line = *line; + rnd_coord_t dx = (line->Point2.X - line->Point1.X); + rnd_coord_t dy = (line->Point2.Y - line->Point1.Y); + int segs = MAX(RND_ABS(dx), RND_ABS(dy)) / (4 * rd->max_bloat + 1); + int qq; + segs = RND_CLAMP(segs, 1, 32); /* don't go too crazy */ + dx /= segs; + dy /= segs; + for (qq = 0; qq < segs - 1; qq++) { + fake_line.Point2.X = fake_line.Point1.X + dx; + fake_line.Point2.Y = fake_line.Point1.Y + dy; + if (fake_line.Point2.X == line->Point2.X && fake_line.Point2.Y == line->Point2.Y) + break; + AddLine(layergroupboxes, layergroup, &fake_line, line, rd->styles[rd->max_styles]); + fake_line.Point1 = fake_line.Point2; + } + fake_line.Point2 = line->Point2; + AddLine(layergroupboxes, layergroup, &fake_line, line, rd->styles[rd->max_styles]); + } + else { + AddLine(layergroupboxes, layergroup, line, line, rd->styles[rd->max_styles]); + } + } + PCB_END_LOOP; + /* add all polygons */ + PCB_POLY_LOOP(ly); + { + if (PCB_FLAG_TEST(PCB_FLAG_DRC, polygon)) + PCB_FLAG_CLEAR(PCB_FLAG_DRC, polygon); + else + AddPolygon(layergroupboxes, i, polygon, rd->styles[rd->max_styles]); + } + PCB_END_LOOP; + /* add all copper text */ + PCB_TEXT_LOOP(ly); + { + AddText(layergroupboxes, layergroup, text, rd->styles[rd->max_styles]); + } + PCB_END_LOOP; + /* add all arcs */ + PCB_ARC_LOOP(ly); + { + AddArc(layergroupboxes, layergroup, arc, rd->styles[rd->max_styles]); + } + PCB_END_LOOP; + } + + /* subc recursion - re-add terms */ + PCB_SUBC_LOOP(data); + { + CreateRouteData_subc(rd, layergroupboxes, subc->data); + } + PCB_END_LOOP; + +} + +static routebox_t *crd_add_line(routedata_t *rd, vtp0_t *layergroupboxes, rnd_layergrp_id_t group, pcb_any_obj_t *obj, int j, routebox_t **last_in_net, routebox_t **last_in_subnet) +{ + routebox_t *rb = NULL; + pcb_line_t *line = (pcb_line_t *) obj; + + /* dice up non-straight lines into many tiny obstacles */ + if (line->Point1.X != line->Point2.X && line->Point1.Y != line->Point2.Y) { + pcb_line_t fake_line = *line; + rnd_coord_t dx = (line->Point2.X - line->Point1.X); + rnd_coord_t dy = (line->Point2.Y - line->Point1.Y); + int segs = MAX(RND_ABS(dx), RND_ABS(dy)) / (4 * BLOAT(rd->styles[j]) + 1); + int qq; + segs = RND_CLAMP(segs, 1, 32); /* don't go too crazy */ + dx /= segs; + dy /= segs; + for (qq = 0; qq < segs - 1; qq++) { + fake_line.Point2.X = fake_line.Point1.X + dx; + fake_line.Point2.Y = fake_line.Point1.Y + dy; + if (fake_line.Point2.X == line->Point2.X && fake_line.Point2.Y == line->Point2.Y) + break; + rb = AddLine(layergroupboxes, group, &fake_line, line, rd->styles[j]); + if (*last_in_subnet && rb != *last_in_subnet) + MergeNets(*last_in_subnet, rb, ORIGINAL); + if (*last_in_net && rb != *last_in_net) + MergeNets(*last_in_net, rb, NET); + *last_in_subnet = *last_in_net = rb; + fake_line.Point1 = fake_line.Point2; + } + fake_line.Point2 = line->Point2; + rb = AddLine(layergroupboxes, group, &fake_line, line, rd->styles[j]); + } + else + rb = AddLine(layergroupboxes, group, line, line, rd->styles[j]); + + return rb; +} + +static routebox_t *crd_add_misc(routedata_t *rd, vtp0_t *layergroupboxes, pcb_any_obj_t *obj, int j) +{ + routebox_t *rb = NULL; + + switch (obj->type) { + case PCB_OBJ_VOID: break; + case PCB_OBJ_PSTK: + rb = AddPstk(layergroupboxes, (pcb_pstk_t *)obj, rd->styles[j]); + break; + case PCB_OBJ_POLY: + { + pcb_poly_t *poly = (pcb_poly_t *)obj; + pcb_layer_t *layer = obj->parent.layer; + if (poly->term != NULL) + rb = AddTerm(layergroupboxes, obj, rd->styles[j]); + else + rb = AddPolygon(layergroupboxes, pcb_layer_id(PCB->Data, layer), poly, rd->styles[j]); + } + break; + case PCB_OBJ_LINE: + case PCB_OBJ_TEXT: + case PCB_OBJ_ARC: + if (obj->term != NULL) + rb = AddTerm(layergroupboxes, obj, rd->styles[j]); + break; + + case PCB_OBJ_GFX: + case PCB_OBJ_RAT: + case PCB_OBJ_SUBC: + case PCB_OBJ_NET: + case PCB_OBJ_NET_TERM: + case PCB_OBJ_LAYER: + case PCB_OBJ_LAYERGRP: + break; /* don't care about these */ + } + return rb; +} + +static void CreateRouteData_subnet(routedata_t *rd, vtp0_t *layergroupboxes, vtp0_t *objs, routebox_t **last_in_net, int j) +{ + routebox_t *last_in_subnet = NULL; + size_t oi; + + for(oi = 0; oi < vtp0_len(objs); oi++) { + routebox_t *rb = NULL; + pcb_any_obj_t *obj = objs->array[oi]; + + if (obj->type == PCB_OBJ_RAT) + continue; + + if (obj->term != NULL) + last_in_subnet = NULL; + + PCB_FLAG_SET(PCB_FLAG_DRC, obj); + + if ((obj->type == PCB_OBJ_LINE) && (obj->term != NULL)) + rb = AddTerm(layergroupboxes, obj, rd->styles[j]); + else if (obj->type == PCB_OBJ_LINE) { + pcb_layer_t *layer = pcb_layer_get_real(obj->parent.layer); + rnd_layergrp_id_t group = layer->meta.real.grp; + rb = crd_add_line(rd, layergroupboxes, group, obj, j, last_in_net, &last_in_subnet); + } + else + rb = crd_add_misc(rd, layergroupboxes, obj, j); + + assert(rb); + + /* update circular connectivity lists */ + if (last_in_subnet && rb != last_in_subnet) + MergeNets(last_in_subnet, rb, ORIGINAL); + if (*last_in_net && rb != *last_in_net) + MergeNets(*last_in_net, rb, NET); + last_in_subnet = *last_in_net = rb; + rd->max_bloat = MAX(rd->max_bloat, BLOAT(rb->style)); + rd->max_keep = MAX(rd->max_keep, rb->style->Clearance); + } +} + +static void CreateRouteData_nets(routedata_t *rd, vtp0_t *layergroupboxes) +{ + htsp_entry_t *e; + pcb_short_ctx_t sctx; + vtp0_t subnets; + routebox_t *last_net = NULL; + + vtp0_init(&subnets); + pcb_net_short_ctx_init(&sctx, PCB, NULL); + + for(e = htsp_first(&PCB->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&PCB->netlist[PCB_NETLIST_EDITED], e)) { + size_t sni; + routebox_t *last_in_net = NULL; + pcb_net_t *net = e->value; + const char *style = pcb_attribute_get(&net->Attributes, "style"); + int j; + + if (style == NULL) + style = ""; + + for (j = 0; j < rd->max_styles; j++) + if (strcmp(style, rd->styles[j]->name) == 0) + break; + + sctx.current_net = (pcb_net_t *)e->value; + pcb_net_map_subnets(&sctx, PCB_RATACC_ONLY_MANHATTAN, &subnets); + for(sni = 0; sni < vtp0_len(&subnets); sni++) + CreateRouteData_subnet(rd, layergroupboxes, subnets.array[sni], &last_in_net, j); + pcb_net_reset_subnets(&subnets); + + if (last_net && last_in_net) + MergeNets(last_net, last_in_net, DIFFERENT_NET); + last_net = last_in_net; + } + rd->first_net = last_net; + + vtp0_uninit(&subnets); + pcb_net_short_ctx_uninit(&sctx); + + /* reset all nets to "original" connectivity (which we just set) */ + { + routebox_t *net; + LIST_LOOP(rd->first_net, different_net, net); + ResetSubnet(net); + PCB_END_LOOP; + } +} + +static routedata_t *CreateRouteData() +{ + vtp0_t layergroupboxes[PCB_MAX_LAYERGRP]; + rnd_box_t bbox; + routedata_t *rd; + int group, i; + + /* check which layers are active first */ + routing_layers = 0; + for (group = 0; group < pcb_max_group(PCB); group++) { + for (i = 0; i < PCB->LayerGroups.grp[group].len; i++) { + rnd_layer_id_t lid = PCB->LayerGroups.grp[group].lid[i]; + /* layer must be 1) copper and 2) on */ + if ((pcb_layer_flags(PCB, lid) & PCB_LYT_COPPER) && PCB->Data->Layer[lid].meta.real.vis) { + routing_layers++; + is_layer_group_active[group] = rnd_true; + break; + } + else + is_layer_group_active[group] = rnd_false; + } + } + /* if via visibility is turned off, don't use them */ + AutoRouteParameters.use_vias = routing_layers > 1 && PCB->pstk_on; + + back = front = -1; + if (pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_COPPER, &back, 1) <= 0) + return NULL; + if (pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_COPPER, &front, 1) <= 0) + return NULL; + + /* determine preferred routing direction on each group */ + for (i = 0; i < pcb_max_group(PCB); i++) { + if (i != back && i != front) { + x_cost[i] = (i & 1) ? 2 : 1; + y_cost[i] = (i & 1) ? 1 : 2; + } + else if (i == back) { + x_cost[i] = 4; + y_cost[i] = 2; + } + else { + x_cost[i] = 2; + y_cost[i] = 2; + } + } + /* create routedata */ + rd = (routedata_t *) malloc(sizeof(*rd)); + memset((void *) rd, 0, sizeof(*rd)); + + rd->max_styles = vtroutestyle_len(&PCB->RouteStyle); +/* rd->layergrouptree = calloc(sizeof(rd->layergrouptree[0]), rd->max_layers);*/ + rd->styles = calloc(sizeof(rd->styles[0]), rd->max_styles+1); + + /* create default style */ + rd->defaultstyle.Thick = conf_core.design.line_thickness; + rd->defaultstyle.Diameter = conf_core.design.via_thickness; + rd->defaultstyle.Hole = conf_core.design.via_drilling_hole; + rd->defaultstyle.Clearance = conf_core.design.clearance; + rd->max_bloat = BLOAT(&rd->defaultstyle); + rd->max_keep = conf_core.design.clearance; + /* create styles structures */ + bbox.X1 = bbox.Y1 = 0; + bbox.X2 = PCB->hidlib.size_x; + bbox.Y2 = PCB->hidlib.size_y; + for (i = 0; i < rd->max_styles + 1; i++) { + pcb_route_style_t *style = (i < rd->max_styles) ? &PCB->RouteStyle.array[i] : &rd->defaultstyle; + rd->styles[i] = style; + } + + /* initialize pointer vectors */ + for (i = 0; i < pcb_max_group(PCB); i++) { + vtp0_init(&layergroupboxes[i]); + PCB_COPPER_GROUP_LOOP(PCB->Data, i); + { + if (!RND_RTREE_EMPTY(layer->line_tree) || !RND_RTREE_EMPTY(layer->arc_tree)) + usedGroup[i] = rnd_true; + else + usedGroup[i] = rnd_false; + } + PCB_END_LOOP; + } + usedGroup[front] = rnd_true; + usedGroup[back] = rnd_true; + + CreateRouteData_nets(rd, layergroupboxes); + + /* subc-recursively add all obstacles */ + CreateRouteData_subc(rd, layergroupboxes, PCB->Data); + + /* create r-trees from pointer lists */ + for (i = 0; i < pcb_max_group(PCB); i++) { + /* create the r-tree */ + rd->layergrouptree[i] = rnd_r_create_tree(); + rnd_r_insert_array(rd->layergrouptree[i], (const rnd_box_t **) layergroupboxes[i].array, vtp0_len(&layergroupboxes[i])); + } + + if (AutoRouteParameters.use_vias) { + rd->mtspace = mtspace_create(); + + /* create "empty-space" structures for via placement (now that we know + * appropriate clearances for all the fixed elements) */ + for (i = 0; i < pcb_max_group(PCB); i++) { + int ip; + for(ip = 0; ip < vtp0_len(&layergroupboxes[i]); ip++) { + void **ptr = &layergroupboxes[i].array[ip]; + routebox_t *rb = (routebox_t *) * ptr; + if (!rb->flags.clear_poly) + mtspace_add(rd->mtspace, &rb->box, FIXED, rb->style->Clearance); + } + } + } + /* free pointer lists */ + for (i = 0; i < pcb_max_group(PCB); i++) + vtp0_uninit(&layergroupboxes[i]); + /* done! */ + return rd; +} + +void DestroyRouteData(routedata_t ** rd) +{ + int i; + for (i = 0; i < pcb_max_group(PCB); i++) { + rnd_r_free_tree_data((*rd)->layergrouptree[i], free); + rnd_r_destroy_tree(&(*rd)->layergrouptree[i]); + } + if (AutoRouteParameters.use_vias) + mtspace_destroy(&(*rd)->mtspace); +/* free((*rd)->layergrouptree);*/ + free((*rd)->styles); + free(*rd); + *rd = NULL; +} + +/*----------------------------------------------------------------- + * routebox reference counting. + */ + +/* increment the reference count on a routebox. */ +static void RB_up_count(routebox_t * rb) +{ + assert(rb->flags.homeless); + rb->refcount++; +} + +/* decrement the reference count on a routebox, freeing if this box becomes + * unused. */ +static void RB_down_count(routebox_t * rb) +{ + assert(rb->type == EXPANSION_AREA); + assert(rb->flags.homeless); + assert(rb->refcount > 0); + if (--rb->refcount == 0) { + if (rb->parent.expansion_area->flags.homeless) + RB_down_count(rb->parent.expansion_area); + free(rb); + } +} + +/*----------------------------------------------------------------- + * Rectangle-expansion routing code. + */ + +static void ResetSubnet(routebox_t * net) +{ + routebox_t *rb; + /* reset connectivity of everything on this net */ + LIST_LOOP(net, same_net, rb); + rb->same_subnet = rb->original_subnet; + PCB_END_LOOP; +} + +static inline rnd_heap_cost_t pcb_cost_to_point_on_layer(const rnd_cheap_point_t * p1, const rnd_cheap_point_t * p2, rnd_cardinal_t point_layer) +{ + rnd_heap_cost_t x_dist = p1->X - p2->X, y_dist = p1->Y - p2->Y, r; + x_dist *= x_cost[point_layer]; + y_dist *= y_cost[point_layer]; + /* cost is proportional to orthogonal distance. */ + r = RND_ABS(x_dist) + RND_ABS(y_dist); + if (p1->X != p2->X && p1->Y != p2->Y) + r += AutoRouteParameters.JogPenalty; + return r; +} + +static rnd_heap_cost_t pcb_cost_to_point(const rnd_cheap_point_t * p1, rnd_cardinal_t point_layer1, const rnd_cheap_point_t * p2, rnd_cardinal_t point_layer2) +{ + rnd_heap_cost_t r = pcb_cost_to_point_on_layer(p1, p2, point_layer1); + /* apply via cost penalty if layers differ */ + if (point_layer1 != point_layer2) + r += AutoRouteParameters.ViaCost; + return r; +} + +/* return the minimum *cost* from a point to a box on any layer. + * It's safe to return a smaller than minimum cost + */ +static rnd_heap_cost_t pcb_cost_to_layerless_box(const rnd_cheap_point_t * p, rnd_cardinal_t point_layer, const rnd_box_t * b) +{ + rnd_cheap_point_t p2 = rnd_closest_cheap_point_in_box(p, b); + register rnd_heap_cost_t c1, c2; + + c1 = p2.X - p->X; + c2 = p2.Y - p->Y; + + c1 = RND_ABS(c1); + c2 = RND_ABS(c2); + if (c1 < c2) + return c1 * AutoRouteParameters.MinPenalty + c2; + else + return c2 * AutoRouteParameters.MinPenalty + c1; +} + +/* get to actual pins/pad target coordinates */ +rnd_bool TargetPoint(rnd_cheap_point_t * nextpoint, const routebox_t * target) +{ +/* if (target->type == PIN) { + nextpoint->X = target->parent.pin->X; + nextpoint->Y = target->parent.pin->Y; + return rnd_true; + }*/ + nextpoint->X = RND_BOX_CENTER_X(target->sbox); + nextpoint->Y = RND_BOX_CENTER_Y(target->sbox); + return rnd_false; +} + +/* return the *minimum cost* from a point to a route box, including possible + * via costs if the route box is on a different layer. + * assume routbox is bloated unless it is an expansion area + */ +static rnd_heap_cost_t pcb_cost_to_routebox(const rnd_cheap_point_t * p, rnd_cardinal_t point_layer, const routebox_t * rb) +{ + register rnd_heap_cost_t trial = 0; + rnd_cheap_point_t p2 = closest_point_in_routebox(p, rb); + if (!usedGroup[point_layer] || !usedGroup[rb->group]) + trial = AutoRouteParameters.NewLayerPenalty; + if ((p2.X - p->X) * (p2.Y - p->Y) != 0) + trial += AutoRouteParameters.JogPenalty; + /* special case for defered via searching */ + if (point_layer > pcb_max_group(PCB) || point_layer == rb->group) + return trial + RND_ABS(p2.X - p->X) + RND_ABS(p2.Y - p->Y); + /* if this target is only a via away, then the via is cheaper than the congestion */ + if (p->X == p2.X && p->Y == p2.Y) + return trial + 1; + trial += AutoRouteParameters.ViaCost; + trial += RND_ABS(p2.X - p->X) + RND_ABS(p2.Y - p->Y); + return trial; +} + + +static rnd_box_t bloat_routebox(routebox_t * rb) +{ + rnd_box_t r; + rnd_coord_t clearance; + assert(__routepcb_box_is_good(rb)); + + if (rb->flags.nobloat) + return rb->sbox; + + /* Obstacle exclusion zones get bloated by the larger of + * the two required clearances plus half the track width. + */ + clearance = MAX(AutoRouteParameters.style->Clearance, rb->style->Clearance); + r = rnd_bloat_box(&rb->sbox, clearance + HALF_THICK(AutoRouteParameters.style->Thick)); + return r; +} + + +#ifdef ROUTE_DEBUG /* only for debugging expansion areas */ + +typedef short pcb_dimension_t; +/* makes a line on the solder layer silk surrounding the box */ +static void showbox(rnd_box_t b, pcb_dimension_t thickness, int group) +{ + pcb_line_t *line; + pcb_layer_t *csl, *SLayer = pcb_get_layer(PCB->Data, group); + rnd_layer_id_t cs_id; + if (showboxen < -1) + return; + if (showboxen != -1 && showboxen != group) + return; + + if (ddraw != NULL) { + ddraw->set_line_width(ar_gc, thickness); + ddraw->set_line_cap(ar_gc, rnd_cap_round); + ddraw->set_color(ar_gc, SLayer->Color); + + ddraw->draw_line(ar_gc, b.X1, b.Y1, b.X2, b.Y1); + ddraw->draw_line(ar_gc, b.X1, b.Y2, b.X2, b.Y2); + ddraw->draw_line(ar_gc, b.X1, b.Y1, b.X1, b.Y2); + ddraw->draw_line(ar_gc, b.X2, b.Y1, b.X2, b.Y2); + } + +#if 1 + if (pcb_layer_find(PCB_LYT_TOP | PCB_LYT_SILK, &cs_id, 1) > 0) { + csl = pcb_get_layer(PCB->Data, cs_id); + if (b.Y1 == b.Y2 || b.X1 == b.X2) + thickness = 5; + line = pcb_line_new(csl, b.X1, b.Y1, b.X2, b.Y1, thickness, 0, pcb_flag_make(0)); + pcb_undo_add_obj_to_create(csl, line, line); + if (b.Y1 != b.Y2) { + line = pcb_line_new(csl, b.X1, b.Y2, b.X2, b.Y2, thickness, 0, pcb_flag_make(0)); + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, csl, line, line); + } + line = pcb_line_new(csl, b.X1, b.Y1, b.X1, b.Y2, thickness, 0, pcb_flag_make(0)); + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, csl, line, line); + if (b.X1 != b.X2) { + line = pcb_line_new(csl, b.X2, b.Y1, b.X2, b.Y2, thickness, 0, pcb_flag_make(0)); + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, csl, line, line); + } + } +#endif +} +#endif + +#if defined(ROUTE_DEBUG) +static void showedge(edge_t * e) +{ + rnd_box_t *b = (rnd_box_t *) e->rb; + + if (ddraw == NULL) + return; + + ddraw->set_line_cap(ar_gc, rnd_cap_round); + ddraw->set_line_width(ar_gc, 1); + ddraw->set_color(ar_gc, Settings.MaskColor); + + switch (e->expand_dir) { + case RND_NORTH: + ddraw->draw_line(ar_gc, b->X1, b->Y1, b->X2, b->Y1); + break; + case RND_SOUTH: + ddraw->draw_line(ar_gc, b->X1, b->Y2, b->X2, b->Y2); + break; + case RND_WEST: + ddraw->draw_line(ar_gc, b->X1, b->Y1, b->X1, b->Y2); + break; + case RND_EAST: + ddraw->draw_line(ar_gc, b->X2, b->Y1, b->X2, b->Y2); + break; + default: + break; + } +} +#endif + +#if defined(ROUTE_DEBUG) +static void showroutebox(routebox_t * rb) +{ + pcb_layerid_t cs_id; + if (pcb_layer_find(PCB_LYT_TOP | PCB_LYT_SILK, &cs_id, 1) > 0) + showbox(rb->sbox, rb->flags.source ? 20 : (rb->flags.target ? 10 : 1), rb->flags.is_via ? pcb_get_layer(PCB->Data, cs_id) : rb->group); +} +#endif + +/* return a "parent" of this edge which immediately precedes it in the route.*/ +static routebox_t *route_parent(routebox_t * rb) +{ + while (rb->flags.homeless && !rb->flags.is_via && !rb->flags.is_thermal) { + assert(rb->type == EXPANSION_AREA); + rb = rb->parent.expansion_area; + assert(rb); + } + return rb; +} + +static vector_t *path_conflicts(routebox_t * rb, routebox_t * conflictor, rnd_bool branch) +{ + if (branch) + rb->conflicts_with = vector_duplicate(rb->conflicts_with); + else if (!rb->conflicts_with) + rb->conflicts_with = vector_create(); + vector_append(rb->conflicts_with, conflictor); + return rb->conflicts_with; +} + +/* Touch everything (except fixed) on each net found + * in the conflicts vector. If the vector is different + * from the last one touched, untouch the last batch + * and touch the new one. Always call with touch=1 + * (except for recursive call). Call with NULL, 1 to + * clear the last batch touched. + * + * touched items become invisible to current path + * so we don't encounter the same conflictor more + * than once + */ + +static void touch_conflicts(vector_t * conflicts, int touch) +{ + static vector_t *last = NULL; + static int last_size = 0; + int i, n; + i = 0; + if (touch) { + if (last && conflicts != last) + touch_conflicts(last, 0); + if (!conflicts) + return; + last = conflicts; + i = last_size; + } + n = vector_size(conflicts); + for (; i < n; i++) { + routebox_t *rb = (routebox_t *) vector_element(conflicts, i); + routebox_t *p; + LIST_LOOP(rb, same_net, p); + if (!p->flags.fixed) + p->flags.touched = touch; + PCB_END_LOOP; + } + if (!touch) { + last = NULL; + last_size = 0; + } + else + last_size = n; +} + +/* return a "parent" of this edge which resides in a r-tree somewhere */ +/* -- actually, this "parent" *may* be a via box, which doesn't live in + * a r-tree. -- */ +static routebox_t *nonhomeless_parent(routebox_t * rb) +{ + return route_parent(rb); +} + +/* some routines to find the minimum *cost* from a cost point to + * a target (any target) */ +struct minpcb_cost_target_closure { + const rnd_cheap_point_t *CostPoint; + rnd_cardinal_t CostPointLayer; + routebox_t *nearest; + rnd_heap_cost_t nearest_cost; +}; +static rnd_r_dir_t __region_within_guess(const rnd_box_t * region, void *cl) +{ + struct minpcb_cost_target_closure *mtc = (struct minpcb_cost_target_closure *) cl; + rnd_heap_cost_t pcb_cost_to_region; + if (mtc->nearest == NULL) + return RND_R_DIR_FOUND_CONTINUE; + pcb_cost_to_region = pcb_cost_to_layerless_box(mtc->CostPoint, mtc->CostPointLayer, region); + assert(pcb_cost_to_region >= 0); + /* if no guess yet, all regions are "close enough" */ + /* note that cost is *strictly more* than minimum distance, so we'll + * always search a region large enough. */ + return (pcb_cost_to_region < mtc->nearest_cost) ? RND_R_DIR_FOUND_CONTINUE : RND_R_DIR_NOT_FOUND; +} + +static rnd_r_dir_t __found_new_guess(const rnd_box_t * box, void *cl) +{ + struct minpcb_cost_target_closure *mtc = (struct minpcb_cost_target_closure *) cl; + routebox_t *guess = (routebox_t *) box; + rnd_heap_cost_t pcb_cost_to_guess = pcb_cost_to_routebox(mtc->CostPoint, mtc->CostPointLayer, guess); + assert(pcb_cost_to_guess >= 0); + /* if this is cheaper than previous guess... */ + if (pcb_cost_to_guess < mtc->nearest_cost) { + mtc->nearest = guess; + mtc->nearest_cost = pcb_cost_to_guess; /* this is our new guess! */ + return RND_R_DIR_FOUND_CONTINUE; + } + else + return RND_R_DIR_NOT_FOUND; /* not less expensive than our last guess */ +} + +/* target_guess is our guess at what the nearest target is, or NULL if we + * just plum don't have a clue. */ +static routebox_t *minpcb_cost_target_to_point(const rnd_cheap_point_t * CostPoint, + rnd_cardinal_t CostPointLayer, rnd_rtree_t * targets, routebox_t * target_guess) +{ + struct minpcb_cost_target_closure mtc; + assert(target_guess == NULL || target_guess->flags.target); /* this is a target, right? */ + mtc.CostPoint = CostPoint; + mtc.CostPointLayer = CostPointLayer; + mtc.nearest = target_guess; + if (mtc.nearest) + mtc.nearest_cost = pcb_cost_to_routebox(mtc.CostPoint, mtc.CostPointLayer, mtc.nearest); + else + mtc.nearest_cost = EXPENSIVE; + rnd_r_search(targets, NULL, __region_within_guess, __found_new_guess, &mtc, NULL); + assert(mtc.nearest != NULL && mtc.nearest_cost >= 0); + assert(mtc.nearest->flags.target); /* this is a target, right? */ + return mtc.nearest; +} + +/* create edge from field values */ +/* minpcb_cost_target_guess can be NULL */ +static edge_t *CreateEdge(routebox_t * rb, + rnd_coord_t CostPointX, rnd_coord_t CostPointY, + rnd_heap_cost_t pcb_cost_to_point, routebox_t * minpcb_cost_target_guess, rnd_direction_t expand_dir, rnd_rtree_t * targets) +{ + edge_t *e; + assert(__routepcb_box_is_good(rb)); + e = (edge_t *) malloc(sizeof(*e)); + memset((void *) e, 0, sizeof(*e)); + assert(e); + e->rb = rb; + if (rb->flags.homeless) + RB_up_count(rb); + e->cost_point.X = CostPointX; + e->cost_point.Y = CostPointY; + e->pcb_cost_to_point = pcb_cost_to_point; + e->flags.via_search = 0; + /* if this edge is created in response to a target, use it */ + if (targets) + e->minpcb_cost_target = minpcb_cost_target_to_point(&e->cost_point, rb->group, targets, minpcb_cost_target_guess); + else + e->minpcb_cost_target = minpcb_cost_target_guess; + e->expand_dir = expand_dir; + assert(e->rb && e->minpcb_cost_target); /* valid edge? */ + assert(!e->flags.is_via || e->expand_dir == RND_ANY_DIR); + /* cost point should be on edge (unless this is a plane/via/conflict edge) */ +#if 0 + assert(rb->type == PLANE || rb->conflicts_with != NULL || rb->flags.is_via + || rb->flags.is_thermal + || ((expand_dir == RND_NORTH || expand_dir == RND_SOUTH) ? rb->sbox.X1 <= + CostPointX && CostPointX < rb->sbox.X2 && CostPointY == (expand_dir == RND_NORTH ? rb->sbox.Y1 : rb->sbox.Y2 - 1) : + /* expand_dir==EAST || expand_dir==WEST */ + rb->sbox.Y1 <= CostPointY && CostPointY < rb->sbox.Y2 && + CostPointX == (expand_dir == RND_EAST ? rb->sbox.X2 - 1 : rb->sbox.X1))); +#endif + assert(__edge_is_good(e)); + /* done */ + return e; +} + +/* create edge, using previous edge to fill in defaults. */ +/* most of the work here is in determining a new cost point */ +static edge_t *CreateEdge2(routebox_t * rb, rnd_direction_t expand_dir, + edge_t * previous_edge, rnd_rtree_t * targets, routebox_t * guess) +{ + rnd_box_t thisbox; + rnd_cheap_point_t thiscost, prevcost; + rnd_heap_cost_t d; + + assert(rb && previous_edge); + /* okay, find cheapest costpoint to costpoint of previous edge */ + thisbox = edge_to_box(rb, expand_dir); + prevcost = previous_edge->cost_point; + /* find point closest to target */ + thiscost = rnd_closest_cheap_point_in_box(&prevcost, &thisbox); + /* compute cost-to-point */ + d = pcb_cost_to_point_on_layer(&prevcost, &thiscost, rb->group); + /* add in jog penalty */ + if (previous_edge->expand_dir != expand_dir) + d += AutoRouteParameters.JogPenalty; + /* okay, new edge! */ + return CreateEdge(rb, thiscost.X, thiscost.Y, + previous_edge->pcb_cost_to_point + d, guess ? guess : previous_edge->minpcb_cost_target, expand_dir, targets); +} + +/* create via edge, using previous edge to fill in defaults. */ +static edge_t *CreateViaEdge(const rnd_box_t * area, rnd_cardinal_t group, + routebox_t * parent, edge_t * previous_edge, + conflict_t to_site_conflict, conflict_t through_site_conflict, rnd_rtree_t * targets) +{ + routebox_t *rb; + rnd_cheap_point_t costpoint; + rnd_heap_cost_t d; + edge_t *ne; + rnd_heap_cost_t scale[3]; + + scale[0] = 1; + scale[1] = AutoRouteParameters.LastConflictPenalty; + scale[2] = AutoRouteParameters.ConflictPenalty; + + assert(rnd_box_is_good(area)); + assert(AutoRouteParameters.with_conflicts || (to_site_conflict == NO_CONFLICT && through_site_conflict == NO_CONFLICT)); + rb = CreateExpansionArea(area, group, parent, rnd_true, previous_edge); + rb->flags.is_via = 1; + rb->came_from = RND_ANY_DIR; +#if defined(ROUTE_DEBUG) && defined(DEBUG_SHOW_VIA_BOXES) + showroutebox(rb); +#endif /* ROUTE_DEBUG && DEBUG_SHOW_VIA_BOXES */ + /* for planes, choose a point near the target */ + if (previous_edge->flags.in_plane) { + routebox_t *target; + rnd_cheap_point_t pnt; + /* find a target near this via box */ + pnt.X = RND_BOX_CENTER_X(*area); + pnt.Y = RND_BOX_CENTER_Y(*area); + target = minpcb_cost_target_to_point(&pnt, rb->group, targets, previous_edge->minpcb_cost_target); + /* now find point near the target */ + pnt.X = RND_BOX_CENTER_X(target->box); + pnt.Y = RND_BOX_CENTER_Y(target->box); + costpoint = closest_point_in_routebox(&pnt, rb); + /* we moved from the previous cost point through the plane which is free travel */ + d = (scale[through_site_conflict] * pcb_cost_to_point(&costpoint, group, &costpoint, previous_edge->rb->group)); + ne = CreateEdge(rb, costpoint.X, costpoint.Y, previous_edge->pcb_cost_to_point + d, target, RND_ANY_DIR, NULL); + ne->minpcb_cost_target = target; + } + else { + routebox_t *target; + target = previous_edge->minpcb_cost_target; + costpoint = closest_point_in_routebox(&previous_edge->cost_point, rb); + d = + (scale[to_site_conflict] * + pcb_cost_to_point_on_layer(&costpoint, &previous_edge->cost_point, + previous_edge->rb->group)) + + (scale[through_site_conflict] * pcb_cost_to_point(&costpoint, group, &costpoint, previous_edge->rb->group)); + /* if the target is just this via away, then this via is cheaper */ + if (target->group == group && point_in_shrunk_box(target, costpoint.X, costpoint.Y)) + d -= AutoRouteParameters.ViaCost / 2; + ne = + CreateEdge(rb, costpoint.X, costpoint.Y, previous_edge->pcb_cost_to_point + d, previous_edge->minpcb_cost_target, RND_ANY_DIR, targets); + } + ne->flags.is_via = 1; + ne->flags.via_conflict_level = to_site_conflict; + assert(__edge_is_good(ne)); + return ne; +} + +/* create "interior" edge for routing with conflicts */ +/* Presently once we "jump inside" the conflicting object + * we consider it a routing highway to travel inside since + * it will become available if the conflict is elliminated. + * That is why we ignore the interior_edge argument. + */ +static edge_t *CreateEdgeWithConflicts(const rnd_box_t * interior_edge, + routebox_t * container, edge_t * previous_edge, + rnd_heap_cost_t cost_penalty_to_box, rnd_rtree_t * targets) +{ + routebox_t *rb; + rnd_cheap_point_t costpoint; + rnd_heap_cost_t d; + edge_t *ne; + assert(interior_edge && container && previous_edge && targets); + assert(!container->flags.homeless); + assert(AutoRouteParameters.with_conflicts); + assert(container->flags.touched == 0); + assert(previous_edge->rb->group == container->group); + /* use the caller's idea of what this box should be */ + rb = CreateExpansionArea(interior_edge, previous_edge->rb->group, previous_edge->rb, rnd_true, previous_edge); + path_conflicts(rb, container, rnd_true); /* crucial! */ + costpoint = rnd_closest_cheap_point_in_box(&previous_edge->cost_point, interior_edge); + d = pcb_cost_to_point_on_layer(&costpoint, &previous_edge->cost_point, previous_edge->rb->group); + d *= cost_penalty_to_box; + d += previous_edge->pcb_cost_to_point; + ne = CreateEdge(rb, costpoint.X, costpoint.Y, d, NULL, RND_ANY_DIR, targets); + ne->flags.is_interior = 1; + assert(__edge_is_good(ne)); + return ne; +} + +static void KillEdge(void *edge) +{ + edge_t *e = (edge_t *) edge; + assert(e); + if (e->rb->flags.homeless) + RB_down_count(e->rb); + if (e->flags.via_search) + mtsFreeWork(&e->work); + free(e); +} + +static void DestroyEdge(edge_t ** e) +{ + assert(e && *e); + KillEdge(*e); + *e = NULL; +} + +/* cost function for an edge. */ +static rnd_heap_cost_t edge_cost(const edge_t * e, const rnd_heap_cost_t too_big) +{ + rnd_heap_cost_t penalty = e->pcb_cost_to_point; + if (e->rb->flags.is_thermal || e->rb->type == PLANE) + return penalty; /* thermals are cheap */ + if (penalty > too_big) + return penalty; + + /* pcb_cost_to_routebox adds in our via correction, too. */ + return penalty + pcb_cost_to_routebox(&e->cost_point, e->rb->group, e->minpcb_cost_target); +} + +/* given an edge of a box, return a box containing exactly the points on that + * edge. Note that the return box is treated as closed; that is, the bottom and + * right "edges" consist of points (just barely) not in the (half-open) box. */ +static rnd_box_t edge_to_box(const routebox_t * rb, rnd_direction_t expand_dir) +{ + rnd_box_t b = shrink_routebox(rb); + /* narrow box down to just the appropriate edge */ + switch (expand_dir) { + case RND_NORTH: + b.Y2 = b.Y1 + 1; + break; + case RND_EAST: + b.X1 = b.X2 - 1; + break; + case RND_SOUTH: + b.Y1 = b.Y2 - 1; + break; + case RND_WEST: + b.X2 = b.X1 + 1; + break; + default: + /* This used to be an assert(0), but it seems a polygon connected to + a terminal triggers it while simply falling through doesn't cause + any problem. This bug is present in both the 2011 version of + PCB and in PCB 4.2.0 as well. */ + break; + } + /* done! */ + return b; +} + +struct broken_boxes { + rnd_box_t left, center, right; + rnd_bool is_valid_left, is_valid_center, is_valid_right; +}; + +static struct broken_boxes break_box_edge(const rnd_box_t * original, rnd_direction_t which_edge, routebox_t * breaker) +{ + rnd_box_t origbox, breakbox; + struct broken_boxes result; + + assert(original && breaker); + + origbox = *original; + breakbox = bloat_routebox(breaker); + RND_BOX_ROTATE_TO_NORTH(origbox, which_edge); + RND_BOX_ROTATE_TO_NORTH(breakbox, which_edge); + result.right.Y1 = result.center.Y1 = result.left.Y1 = origbox.Y1; + result.right.Y2 = result.center.Y2 = result.left.Y2 = origbox.Y1 + 1; + /* validity of breaker is not important because the boxes are marked invalid */ + /*assert (breakbox.X1 <= origbox.X2 && breakbox.X2 >= origbox.X1); */ + /* left edge piece */ + result.left.X1 = origbox.X1; + result.left.X2 = breakbox.X1; + /* center (ie blocked) edge piece */ + result.center.X1 = MAX(breakbox.X1, origbox.X1); + result.center.X2 = MIN(breakbox.X2, origbox.X2); + /* right edge piece */ + result.right.X1 = breakbox.X2; + result.right.X2 = origbox.X2; + /* validity: */ + result.is_valid_left = (result.left.X1 < result.left.X2); + result.is_valid_center = (result.center.X1 < result.center.X2); + result.is_valid_right = (result.right.X1 < result.right.X2); + /* rotate back */ + RND_BOX_ROTATE_FROM_NORTH(result.left, which_edge); + RND_BOX_ROTATE_FROM_NORTH(result.center, which_edge); + RND_BOX_ROTATE_FROM_NORTH(result.right, which_edge); + /* done */ + return result; +} + +#ifndef NDEBUG +static int share_edge(const rnd_box_t * child, const rnd_box_t * parent) +{ + return + (child->X1 == parent->X2 || child->X2 == parent->X1 || + child->Y1 == parent->Y2 || child->Y2 == parent->Y1) && + ((parent->X1 <= child->X1 && child->X2 <= parent->X2) || (parent->Y1 <= child->Y1 && child->Y2 <= parent->Y2)); +} + +static int edge_intersect(const rnd_box_t * child, const rnd_box_t * parent) +{ + return (child->X1 <= parent->X2) && (child->X2 >= parent->X1) && (child->Y1 <= parent->Y2) && (child->Y2 >= parent->Y1); +} +#endif + +/* area is the expansion area, on layer group 'group'. 'parent' is the + * immediately preceding expansion area, for backtracing. 'lastarea' is + * the last expansion area created, we string these together in a loop + * so we can remove them all easily at the end. */ +static routebox_t *CreateExpansionArea(const rnd_box_t * area, rnd_cardinal_t group, + routebox_t * parent, rnd_bool relax_edge_requirements, edge_t * src_edge) +{ + routebox_t *rb = (routebox_t *) malloc(sizeof(*rb)); + memset((void *) rb, 0, sizeof(*rb)); + assert(area && parent); + init_const_box(rb, area->X1, area->Y1, area->X2, area->Y2, 0); + rb->group = group; + rb->type = EXPANSION_AREA; + /* should always share edge or overlap with parent */ +#ifndef NDEBUG + { + /* work around rounding errors: grow both boxes by 2 nm */ + rnd_box_t b1 = rb->sbox, b2 = parent->sbox; + b1.X1--;b1.Y1--;b1.X2++;b1.Y2++; + b2.X1--;b2.Y1--;b2.X2++;b2.Y2++; + assert(relax_edge_requirements ? rnd_box_intersect(&b1, &b2) + : share_edge(&rb->sbox, &parent->sbox)); + } +#endif + rb->parent.expansion_area = route_parent(parent); + rb->cost_point = rnd_closest_cheap_point_in_box(&rb->parent.expansion_area->cost_point, area); + rb->cost = + rb->parent.expansion_area->cost + + pcb_cost_to_point_on_layer(&rb->parent.expansion_area->cost_point, &rb->cost_point, rb->group); + assert(relax_edge_requirements ? edge_intersect(&rb->sbox, &parent->sbox) + : share_edge(&rb->sbox, &parent->sbox)); + if (rb->parent.expansion_area->flags.homeless) + RB_up_count(rb->parent.expansion_area); + rb->flags.homeless = 1; + rb->flags.nobloat = 1; + rb->style = AutoRouteParameters.style; + rb->conflicts_with = parent->conflicts_with; +/* we will never link an EXPANSION_AREA into the nets because they + * are *ONLY* used for path searching. No need to call InitLists () + */ + rb->came_from = src_edge->expand_dir; +#if defined(ROUTE_DEBUG) && defined(DEBUG_SHOW_EXPANSION_BOXES) + showroutebox(rb); +#endif /* ROUTE_DEBUG && DEBUG_SHOW_EXPANSION_BOXES */ + return rb; +} + +/*------ Expand ------*/ +struct E_result { + routebox_t *parent; + routebox_t *n, *e, *s, *w; + rnd_coord_t keep, bloat; + rnd_box_t inflated, orig; + int done; +}; + +/* test method for Expand() + * this routebox potentially is a blocker limiting expansion + * if this is so, we limit the inflate box so another exactly + * like it wouldn't be seen. We do this while keep the inflated + * box as large as possible. + */ +static rnd_r_dir_t __Expand_this_rect(const rnd_box_t * box, void *cl) +{ + struct E_result *res = (struct E_result *) cl; + routebox_t *rb = (routebox_t *) box; + rnd_box_t rbox; + rnd_coord_t dn, de, ds, dw, bloat; + + /* we don't see conflicts already encountered */ + if (rb->flags.touched) + return RND_R_DIR_NOT_FOUND; + + /* The inflated box outer edges include its own + * track width plus its own clearance. + * + * To check for intersection, we need to expand + * anything with greater clearance by its excess + * clearance. + * + * If something has nobloat then we need to shrink + * the inflated box back and see if it still touches. + */ + + if (rb->flags.nobloat) { + rbox = rb->sbox; + bloat = res->bloat; + if (rbox.X2 <= res->inflated.X1 + bloat || + rbox.X1 >= res->inflated.X2 - bloat || rbox.Y1 >= res->inflated.Y2 - bloat || rbox.Y2 <= res->inflated.Y1 + bloat) + return RND_R_DIR_NOT_FOUND; /* doesn't touch */ + } + else { + if (rb->style->Clearance > res->keep) + rbox = rnd_bloat_box(&rb->sbox, rb->style->Clearance - res->keep); + else + rbox = rb->sbox; + + if (rbox.X2 <= res->inflated.X1 || rbox.X1 >= res->inflated.X2 + || rbox.Y1 >= res->inflated.Y2 || rbox.Y2 <= res->inflated.Y1) + return RND_R_DIR_NOT_FOUND; /* doesn't touch */ + bloat = 0; + } + + /* this is an intersecting box; it has to jump through a few more hoops */ + if (rb == res->parent || rb->parent.expansion_area == res->parent) + return RND_R_DIR_NOT_FOUND; /* don't see what we came from */ + + /* if we are expanding a source edge, don't let other sources + * or their expansions stop us. + */ +#if 1 + if (res->parent->flags.source) + if (rb->flags.source || (rb->type == EXPANSION_AREA && rb->parent.expansion_area->flags.source)) + return RND_R_DIR_NOT_FOUND; +#endif + + /* we ignore via expansion boxes because maybe its + * cheaper to get there without the via through + * the path we're exploring now. + */ + if (rb->flags.is_via && rb->type == EXPANSION_AREA) + return RND_R_DIR_NOT_FOUND; + + if (rb->type == PLANE) { /* expanding inside a plane is not good */ + if (rbox.X1 < res->orig.X1 && rbox.X2 > res->orig.X2 && rbox.Y1 < res->orig.Y1 && rbox.Y2 > res->orig.Y2) { + res->inflated = rnd_bloat_box(&res->orig, res->bloat); + return RND_R_DIR_FOUND_CONTINUE; + } + } + /* calculate the distances from original box to this blocker */ + dn = de = ds = dw = 0; + if (!(res->done & _NORTH) && rbox.Y1 <= res->orig.Y1 && rbox.Y2 > res->inflated.Y1) + dn = res->orig.Y1 - rbox.Y2; + if (!(res->done & _EAST) && rbox.X2 >= res->orig.X2 && rbox.X1 < res->inflated.X2) + de = rbox.X1 - res->orig.X2; + if (!(res->done & _SOUTH) && rbox.Y2 >= res->orig.Y2 && rbox.Y1 < res->inflated.Y2) + ds = rbox.Y1 - res->orig.Y2; + if (!(res->done & _WEST) && rbox.X1 <= res->orig.X1 && rbox.X2 > res->inflated.X1) + dw = res->orig.X1 - rbox.X2; + if (dn <= 0 && de <= 0 && ds <= 0 && dw <= 0) + return RND_R_DIR_FOUND_CONTINUE; + /* now shrink the inflated box to the largest blocking direction */ + if (dn >= de && dn >= ds && dn >= dw) { + res->inflated.Y1 = rbox.Y2 - bloat; + res->n = rb; + } + else if (de >= ds && de >= dw) { + res->inflated.X2 = rbox.X1 + bloat; + res->e = rb; + } + else if (ds >= dw) { + res->inflated.Y2 = rbox.Y1 + bloat; + res->s = rb; + } + else { + res->inflated.X1 = rbox.X2 - bloat; + res->w = rb; + } + return RND_R_DIR_FOUND_CONTINUE; +} + +static rnd_bool boink_box(routebox_t * rb, struct E_result *res, rnd_direction_t dir) +{ + rnd_coord_t bloat; + if (rb->style->Clearance > res->keep) + bloat = res->keep - rb->style->Clearance; + else + bloat = 0; + if (rb->flags.nobloat) + bloat = res->bloat; + switch (dir) { + case RND_NORTH: + case RND_SOUTH: + if (rb->sbox.X2 <= res->inflated.X1 + bloat || rb->sbox.X1 >= res->inflated.X2 - bloat) + return rnd_false; + return rnd_true; + case RND_EAST: + case RND_WEST: + if (rb->sbox.Y1 >= res->inflated.Y2 - bloat || rb->sbox.Y2 <= res->inflated.Y1 + bloat) + return rnd_false; + return rnd_true; + break; + default: + assert(0); + } + return rnd_false; +} + +/* main Expand routine. + * + * The expansion probe edge includes the clearance and half thickness + * as the search is performed in order to see everything relevant. + * The result is backed off by this amount before being returned. + * Targets (and other no-bloat routeboxes) go all the way to touching. + * This is accomplished by backing off the probe edge when checking + * for touch against such an object. Usually the expanding edge + * bumps into neighboring pins on the same device that require a + * clearance, preventing seeing a target immediately. Rather than await + * another expansion to actually touch the target, the edge breaker code + * looks past the clearance to see these targets even though they + * weren't actually touched in the expansion. + */ +struct E_result *Expand(rnd_rtree_t * rtree, edge_t * e, const rnd_box_t * box) +{ + static struct E_result ans; + int noshrink; /* bit field of which edges to not shrink */ + + ans.bloat = AutoRouteParameters.bloat; + ans.orig = *box; + ans.n = ans.e = ans.s = ans.w = NULL; + + /* the inflated box must be bloated in all directions that it might + * hit something in order to guarantee that we see object in the + * tree it might hit. The tree holds objects bloated by their own + * clearance so we are guaranteed to honor that. + */ + switch (e->expand_dir) { + case RND_ANY_DIR: + ans.inflated.X1 = (e->rb->came_from == RND_EAST ? ans.orig.X1 : 0); + ans.inflated.Y1 = (e->rb->came_from == RND_SOUTH ? ans.orig.Y1 : 0); + ans.inflated.X2 = (e->rb->came_from == RND_WEST ? ans.orig.X2 : PCB->hidlib.size_x); + ans.inflated.Y2 = (e->rb->came_from == RND_NORTH ? ans.orig.Y2 : PCB->hidlib.size_y); + if (e->rb->came_from == RND_NORTH) + ans.done = noshrink = _SOUTH; + else if (e->rb->came_from == RND_EAST) + ans.done = noshrink = _WEST; + else if (e->rb->came_from == RND_SOUTH) + ans.done = noshrink = _NORTH; + else if (e->rb->came_from == RND_WEST) + ans.done = noshrink = _EAST; + else + ans.done = noshrink = 0; + break; + case RND_NORTH: + ans.done = _SOUTH + _EAST + _WEST; + noshrink = _SOUTH; + ans.inflated.X1 = box->X1 - ans.bloat; + ans.inflated.X2 = box->X2 + ans.bloat; + ans.inflated.Y2 = box->Y2; + ans.inflated.Y1 = 0; /* far north */ + break; + case RND_NE: + ans.done = _SOUTH + _WEST; + noshrink = 0; + ans.inflated.X1 = box->X1 - ans.bloat; + ans.inflated.X2 = PCB->hidlib.size_x; + ans.inflated.Y2 = box->Y2 + ans.bloat; + ans.inflated.Y1 = 0; + break; + case RND_EAST: + ans.done = _NORTH + _SOUTH + _WEST; + noshrink = _WEST; + ans.inflated.Y1 = box->Y1 - ans.bloat; + ans.inflated.Y2 = box->Y2 + ans.bloat; + ans.inflated.X1 = box->X1; + ans.inflated.X2 = PCB->hidlib.size_x; + break; + case RND_SE: + ans.done = _NORTH + _WEST; + noshrink = 0; + ans.inflated.X1 = box->X1 - ans.bloat; + ans.inflated.X2 = PCB->hidlib.size_x; + ans.inflated.Y2 = PCB->hidlib.size_y; + ans.inflated.Y1 = box->Y1 - ans.bloat; + break; + case RND_SOUTH: + ans.done = _NORTH + _EAST + _WEST; + noshrink = _NORTH; + ans.inflated.X1 = box->X1 - ans.bloat; + ans.inflated.X2 = box->X2 + ans.bloat; + ans.inflated.Y1 = box->Y1; + ans.inflated.Y2 = PCB->hidlib.size_y; + break; + case RND_SW: + ans.done = _NORTH + _EAST; + noshrink = 0; + ans.inflated.X1 = 0; + ans.inflated.X2 = box->X2 + ans.bloat; + ans.inflated.Y2 = PCB->hidlib.size_y; + ans.inflated.Y1 = box->Y1 - ans.bloat; + break; + case RND_WEST: + ans.done = _NORTH + _SOUTH + _EAST; + noshrink = _EAST; + ans.inflated.Y1 = box->Y1 - ans.bloat; + ans.inflated.Y2 = box->Y2 + ans.bloat; + ans.inflated.X1 = 0; + ans.inflated.X2 = box->X2; + break; + case RND_NW: + ans.done = _SOUTH + _EAST; + noshrink = 0; + ans.inflated.X1 = 0; + ans.inflated.X2 = box->X2 + ans.bloat; + ans.inflated.Y2 = box->Y2 + ans.bloat; + ans.inflated.Y1 = 0; + break; + default: + noshrink = ans.done = 0; + assert(0); + } + ans.keep = e->rb->style->Clearance; + ans.parent = nonhomeless_parent(e->rb); + rnd_r_search(rtree, &ans.inflated, NULL, __Expand_this_rect, &ans, NULL); +/* because the overlaping boxes are found in random order, some blockers + * may have limited edges prematurely, so we check if the blockers realy + * are blocking, and make another try if not + */ + if (ans.n && !boink_box(ans.n, &ans, RND_NORTH)) + ans.inflated.Y1 = 0; + else + ans.done |= _NORTH; + if (ans.e && !boink_box(ans.e, &ans, RND_EAST)) + ans.inflated.X2 = PCB->hidlib.size_x; + else + ans.done |= _EAST; + if (ans.s && !boink_box(ans.s, &ans, RND_SOUTH)) + ans.inflated.Y2 = PCB->hidlib.size_y; + else + ans.done |= _SOUTH; + if (ans.w && !boink_box(ans.w, &ans, RND_WEST)) + ans.inflated.X1 = 0; + else + ans.done |= _WEST; + if (ans.done != _NORTH + _EAST + _SOUTH + _WEST) { + rnd_r_search(rtree, &ans.inflated, NULL, __Expand_this_rect, &ans, NULL); + } + if ((noshrink & _NORTH) == 0) + ans.inflated.Y1 += ans.bloat; + if ((noshrink & _EAST) == 0) + ans.inflated.X2 -= ans.bloat; + if ((noshrink & _SOUTH) == 0) + ans.inflated.Y2 -= ans.bloat; + if ((noshrink & _WEST) == 0) + ans.inflated.X1 += ans.bloat; + return &ans; +} + +/* blocker_to_heap puts the blockers into a heap so they + * can be retrieved in clockwise order. If a blocker + * is also a target, it gets put into the vector too. + * It returns 1 for any fixed blocker that is not part + * of this net and zero otherwise. + */ +static int blocker_to_heap(rnd_heap_t * heap, routebox_t * rb, rnd_box_t * box, rnd_direction_t dir) +{ + rnd_box_t b = rb->sbox; + if (rb->style->Clearance > AutoRouteParameters.style->Clearance) + b = rnd_bloat_box(&b, rb->style->Clearance - AutoRouteParameters.style->Clearance); + b = rnd_clip_box(&b, box); + assert(rnd_box_is_good(&b)); + /* we want to look at the blockers clockwise around the box */ + switch (dir) { + /* we need to use the other coordinate fraction to resolve + * ties since we want the shorter of the furthest + * first. + */ + case RND_NORTH: + rnd_heap_insert(heap, b.X1 - b.X1 / (b.X2 + 1.0), rb); + break; + case RND_EAST: + rnd_heap_insert(heap, b.Y1 - b.Y1 / (b.Y2 + 1.0), rb); + break; + case RND_SOUTH: + rnd_heap_insert(heap, -(b.X2 + b.X1 / (b.X2 + 1.0)), rb); + break; + case RND_WEST: + rnd_heap_insert(heap, -(b.Y2 + b.Y1 / (b.Y2 + 1.0)), rb); + break; + default: + assert(0); + } + if (rb->flags.fixed && !rb->flags.target && !rb->flags.source) + return 1; + return 0; +} + +/* this creates an EXPANSION_AREA to bridge small gaps or, + * (more commonly) create a supper-thin box to provide a + * home for an expansion edge. + */ +static routebox_t *CreateBridge(const rnd_box_t * area, routebox_t * parent, rnd_direction_t dir) +{ + routebox_t *rb = (routebox_t *) malloc(sizeof(*rb)); + memset((void *) rb, 0, sizeof(*rb)); + assert(area && parent); + init_const_box(rb, area->X1, area->Y1, area->X2, area->Y2, 0); + rb->group = parent->group; + rb->type = EXPANSION_AREA; + rb->came_from = dir; + rb->cost_point = rnd_closest_cheap_point_in_box(&parent->cost_point, area); + rb->cost = parent->cost + pcb_cost_to_point_on_layer(&parent->cost_point, &rb->cost_point, rb->group); + rb->parent.expansion_area = route_parent(parent); + if (rb->parent.expansion_area->flags.homeless) + RB_up_count(rb->parent.expansion_area); + rb->flags.homeless = 1; + rb->flags.nobloat = 1; + rb->style = parent->style; + rb->conflicts_with = parent->conflicts_with; +#if defined(ROUTE_DEBUG) && defined(DEBUG_SHOW_EDGES) + showroutebox(rb); +#endif + return rb; +} + +/* moveable_edge prepares the new search edges based on the + * starting box, direction and blocker if any. + */ +void +moveable_edge(vector_t * result, const rnd_box_t * box, rnd_direction_t dir, + routebox_t * rb, + routebox_t * blocker, edge_t * e, rnd_rtree_t * targets, + routeone_state_t *s, rnd_rtree_t * tree, vector_t * area_vec) +{ + rnd_box_t b; + assert(rnd_box_is_good(box)); + b = *box; + /* for the cardinal directions, move the box to overlap the + * the parent by 1 unit. Corner expansions overlap more + * and their starting boxes are pre-prepared. + * Check if anything is headed off the board edges + */ + switch (dir) { + default: + break; + case RND_NORTH: + b.Y2 = b.Y1; + b.Y1--; + if (b.Y1 <= AutoRouteParameters.bloat) + return; /* off board edge */ + break; + case RND_EAST: + b.X1 = b.X2; + b.X2++; + if (b.X2 >= PCB->hidlib.size_x - AutoRouteParameters.bloat) + return; /* off board edge */ + break; + case RND_SOUTH: + b.Y1 = b.Y2; + b.Y2++; + if (b.Y2 >= PCB->hidlib.size_y - AutoRouteParameters.bloat) + return; /* off board edge */ + break; + case RND_WEST: + b.X2 = b.X1; + b.X1--; + if (b.X1 <= AutoRouteParameters.bloat) + return; /* off board edge */ + break; + case RND_NE: + if (b.Y1 <= AutoRouteParameters.bloat + 1 && b.X2 >= PCB->hidlib.size_x - AutoRouteParameters.bloat - 1) + return; /* off board edge */ + if (b.Y1 <= AutoRouteParameters.bloat + 1) + dir = RND_EAST; /* north off board edge */ + if (b.X2 >= PCB->hidlib.size_x - AutoRouteParameters.bloat - 1) + dir = RND_NORTH; /* east off board edge */ + break; + case RND_SE: + if (b.Y2 >= PCB->hidlib.size_y - AutoRouteParameters.bloat - 1 && b.X2 >= PCB->hidlib.size_x - AutoRouteParameters.bloat - 1) + return; /* off board edge */ + if (b.Y2 >= PCB->hidlib.size_y - AutoRouteParameters.bloat - 1) + dir = RND_EAST; /* south off board edge */ + if (b.X2 >= PCB->hidlib.size_x - AutoRouteParameters.bloat - 1) + dir = RND_SOUTH; /* east off board edge */ + break; + case RND_SW: + if (b.Y2 >= PCB->hidlib.size_y - AutoRouteParameters.bloat - 1 && b.X1 <= AutoRouteParameters.bloat + 1) + return; /* off board edge */ + if (b.Y2 >= PCB->hidlib.size_y - AutoRouteParameters.bloat - 1) + dir = RND_WEST; /* south off board edge */ + if (b.X1 <= AutoRouteParameters.bloat + 1) + dir = RND_SOUTH; /* west off board edge */ + break; + case RND_NW: + if (b.Y1 <= AutoRouteParameters.bloat + 1 && b.X1 <= AutoRouteParameters.bloat + 1) + return; /* off board edge */ + if (b.Y1 <= AutoRouteParameters.bloat + 1) + dir = RND_WEST; /* north off board edge */ + if (b.X1 <= AutoRouteParameters.bloat + 1) + dir = RND_NORTH; /* west off board edge */ + break; + } + + if (!blocker) { + edge_t *ne; + routebox_t *nrb = CreateBridge(&b, rb, dir); + /* move the cost point in corner expansions + * these boxes are bigger, so move close to the target + */ + if (dir == RND_NE || dir == RND_SE || dir == RND_SW || dir == RND_NW) { + rnd_cheap_point_t p; + p = rnd_closest_cheap_point_in_box(&nrb->cost_point, &e->minpcb_cost_target->sbox); + p = rnd_closest_cheap_point_in_box(&p, &b); + nrb->cost += pcb_cost_to_point_on_layer(&p, &nrb->cost_point, nrb->group); + nrb->cost_point = p; + } + ne = CreateEdge(nrb, nrb->cost_point.X, nrb->cost_point.Y, nrb->cost, NULL, dir, targets); + vector_append(result, ne); + } + else if (AutoRouteParameters.with_conflicts && !blocker->flags.target + && !blocker->flags.fixed && !blocker->flags.touched && !blocker->flags.source && blocker->type != EXPANSION_AREA) { + edge_t *ne; + routebox_t *nrb; + /* make a bridge to the edge of the blocker + * in all directions from there + */ + switch (dir) { + case RND_NORTH: + b.Y1 = blocker->sbox.Y2 - 1; + break; + case RND_EAST: + b.X2 = blocker->sbox.X1 + 1; + break; + case RND_SOUTH: + b.Y2 = blocker->sbox.Y1 + 1; + break; + case RND_WEST: + b.X1 = blocker->sbox.X2 - 1; + break; + default: + assert(0); + } + if (!rnd_box_is_good(&b)) + return; /* how did this happen ? */ + nrb = CreateBridge(&b, rb, dir); + rnd_r_insert_entry(tree, &nrb->box); + vector_append(area_vec, nrb); + nrb->flags.homeless = 0; /* not homeless any more */ + /* mark this one as conflicted */ + path_conflicts(nrb, blocker, rnd_true); + /* and make an expansion edge */ + nrb->cost_point = rnd_closest_cheap_point_in_box(&nrb->cost_point, &blocker->sbox); + nrb->cost += + pcb_cost_to_point_on_layer(&nrb->parent.expansion_area->cost_point, &nrb->cost_point, nrb->group) * CONFLICT_PENALTY(blocker); + + ne = CreateEdge(nrb, nrb->cost_point.X, nrb->cost_point.Y, nrb->cost, NULL, RND_ANY_DIR, targets); + ne->flags.is_interior = 1; + vector_append(result, ne); + } +#if 1 + else if (blocker->type == EXPANSION_AREA) { + if (blocker->cost < rb->cost || blocker->cost <= rb->cost + + pcb_cost_to_point_on_layer(&blocker->cost_point, &rb->cost_point, rb->group)) + return; + if (blocker->conflicts_with || rb->conflicts_with) + return; + /* does the blocker overlap this routebox ?? */ + /* does this re-parenting operation leave a memory leak? */ + if (blocker->parent.expansion_area->flags.homeless) + RB_down_count(blocker->parent.expansion_area); + blocker->parent.expansion_area = rb; + return; + } +#endif + else if (blocker->flags.target) { + routebox_t *nrb; + edge_t *ne; + b = rnd_bloat_box(&b, 1); + if (!rnd_box_intersect(&b, &blocker->sbox)) { + /* if the expansion edge stopped before touching, expand the bridge */ + switch (dir) { + case RND_NORTH: + b.Y1 -= AutoRouteParameters.bloat + 1; + break; + case RND_EAST: + b.X2 += AutoRouteParameters.bloat + 1; + break; + case RND_SOUTH: + b.Y2 += AutoRouteParameters.bloat + 1; + break; + case RND_WEST: + b.X1 -= AutoRouteParameters.bloat + 1; + break; + default: + assert(0); + } + } + assert(rnd_box_intersect(&b, &blocker->sbox)); + b = rnd_shrink_box(&b, 1); + nrb = CreateBridge(&b, rb, dir); + rnd_r_insert_entry(tree, &nrb->box); + vector_append(area_vec, nrb); + nrb->flags.homeless = 0; /* not homeless any more */ + ne = CreateEdge(nrb, nrb->cost_point.X, nrb->cost_point.Y, nrb->cost, blocker, dir, NULL); + best_path_candidate(s, ne, blocker); + DestroyEdge(&ne); + } +} + +struct break_info { + rnd_heap_t *heap; + routebox_t *parent; + rnd_box_t box; + rnd_direction_t dir; + rnd_bool ignore_source; +}; + +static rnd_r_dir_t __GatherBlockers(const rnd_box_t * box, void *cl) +{ + routebox_t *rb = (routebox_t *) box; + struct break_info *bi = (struct break_info *) cl; + rnd_box_t b; + + if (bi->parent == rb || rb->flags.touched || bi->parent->parent.expansion_area == rb) + return RND_R_DIR_NOT_FOUND; + if (rb->flags.source && bi->ignore_source) + return RND_R_DIR_NOT_FOUND; + b = rb->sbox; + if (rb->style->Clearance > AutoRouteParameters.style->Clearance) + b = rnd_bloat_box(&b, rb->style->Clearance - AutoRouteParameters.style->Clearance); + if (b.X2 <= bi->box.X1 || b.X1 >= bi->box.X2 || b.Y1 >= bi->box.Y2 || b.Y2 <= bi->box.Y1) + return RND_R_DIR_NOT_FOUND; + if (blocker_to_heap(bi->heap, rb, &bi->box, bi->dir)) + return RND_R_DIR_FOUND_CONTINUE; + return RND_R_DIR_NOT_FOUND; +} + +/* shrink the box to the last limit for the previous direction, + * i.e. if dir is SOUTH, then this means fixing up an EAST leftover + * edge, which would be the southern most edge for that example. + */ +static inline rnd_box_t previous_edge(rnd_coord_t last, rnd_direction_t i, const rnd_box_t * b) +{ + rnd_box_t db = *b; + switch (i) { + case RND_EAST: + db.X1 = last; + break; + case RND_SOUTH: + db.Y1 = last; + break; + case RND_WEST: + db.X2 = last; + break; + default: + rnd_message(RND_MSG_ERROR, "previous edge bogus direction!"); + assert(0); + } + return db; +} + +/* Break all the edges of the box that need breaking, handling + * targets as they are found, and putting any moveable edges + * in the return vector. + */ +vector_t *BreakManyEdges(routeone_state_t * s, rnd_rtree_t * targets, rnd_rtree_t * tree, + vector_t * area_vec, struct E_result * ans, routebox_t * rb, edge_t * e) +{ + struct break_info bi; + vector_t *edges; + rnd_heap_t *heap[4]; + rnd_coord_t first, last; + rnd_coord_t bloat; + rnd_direction_t dir; + routebox_t fake; + + edges = vector_create(); + bi.ignore_source = rb->parent.expansion_area->flags.source; + bi.parent = rb; + /* we add 2 to the bloat. + * 1 will get us to the actual blocker that Expand() hit + * but 1 more is needed because the new expansion edges + * move out by 1 so they don't overlap their parents + * this extra expansion could "trap" the edge if + * there is a blocker 2 units from the original rb, + * it is 1 unit from the new expansion edge which + * would prevent expansion. So we want to break the + * edge on it now to avoid the trap. + */ + + bloat = AutoRouteParameters.bloat + 2; + /* for corner expansion, we need to have a fake blocker + * to prevent expansion back where we came from since + * we still need to break portions of all 4 edges + */ + if (e->expand_dir == RND_NE || e->expand_dir == RND_SE || e->expand_dir == RND_SW || e->expand_dir == RND_NW) { + rnd_box_t *fb = (rnd_box_t *) & fake.sbox; + memset(&fake, 0, sizeof(fake)); + *fb = e->rb->sbox; + fake.flags.fixed = 1; /* this stops expansion there */ + fake.type = LINE; + fake.style = AutoRouteParameters.style; +#ifndef NDEBUG + /* the routbox_is_good checker wants a lot more! */ + fake.flags.inited = 1; + fb = (rnd_box_t *) & fake.box; + *fb = e->rb->sbox; + fake.same_net.next = fake.same_net.prev = &fake; + fake.same_subnet.next = fake.same_subnet.prev = &fake; + fake.original_subnet.next = fake.original_subnet.prev = &fake; + fake.different_net.next = fake.different_net.prev = &fake; +#endif + } + /* gather all of the blockers in heaps so they can be accessed + * in clockwise order, which allows finding corners that can + * be expanded. + */ + for (dir = RND_NORTH; dir <= RND_WEST; dir = directionIncrement(dir)) { + int tmp; + /* don't break the edge we came from */ + if (e->expand_dir != ((dir + 2) % 4)) { + heap[dir] = rnd_heap_create(); + bi.box = rnd_bloat_box(&rb->sbox, bloat); + bi.heap = heap[dir]; + bi.dir = dir; + /* convert to edge */ + switch (dir) { + case RND_NORTH: + bi.box.Y2 = bi.box.Y1 + bloat + 1; + /* for corner expansion, block the start edges and + * limit the blocker search to only the new edge segment + */ + if (e->expand_dir == RND_SE || e->expand_dir == RND_SW) + blocker_to_heap(heap[dir], &fake, &bi.box, dir); + if (e->expand_dir == RND_SE) + bi.box.X1 = e->rb->sbox.X2; + if (e->expand_dir == RND_SW) + bi.box.X2 = e->rb->sbox.X1; + rnd_r_search(tree, &bi.box, NULL, __GatherBlockers, &bi, &tmp); + rb->n = tmp; + break; + case RND_EAST: + bi.box.X1 = bi.box.X2 - bloat - 1; + /* corner, same as above */ + if (e->expand_dir == RND_SW || e->expand_dir == RND_NW) + blocker_to_heap(heap[dir], &fake, &bi.box, dir); + if (e->expand_dir == RND_SW) + bi.box.Y1 = e->rb->sbox.Y2; + if (e->expand_dir == RND_NW) + bi.box.Y2 = e->rb->sbox.Y1; + rnd_r_search(tree, &bi.box, NULL, __GatherBlockers, &bi, &tmp); + rb->e = tmp; + break; + case RND_SOUTH: + bi.box.Y1 = bi.box.Y2 - bloat - 1; + /* corner, same as above */ + if (e->expand_dir == RND_NE || e->expand_dir == RND_NW) + blocker_to_heap(heap[dir], &fake, &bi.box, dir); + if (e->expand_dir == RND_NE) + bi.box.X1 = e->rb->sbox.X2; + if (e->expand_dir == RND_NW) + bi.box.X2 = e->rb->sbox.X1; + rnd_r_search(tree, &bi.box, NULL, __GatherBlockers, &bi, &tmp); + rb->s = tmp; + break; + case RND_WEST: + bi.box.X2 = bi.box.X1 + bloat + 1; + /* corner, same as above */ + if (e->expand_dir == RND_NE || e->expand_dir == RND_SE) + blocker_to_heap(heap[dir], &fake, &bi.box, dir); + if (e->expand_dir == RND_SE) + bi.box.Y1 = e->rb->sbox.Y2; + if (e->expand_dir == RND_NE) + bi.box.Y2 = e->rb->sbox.Y1; + rnd_r_search(tree, &bi.box, NULL, __GatherBlockers, &bi, &tmp); + rb->w = tmp; + break; + default: + assert(0); + } + } + else + heap[dir] = NULL; + } +#if 1 + rb->cost += (rb->n + rb->e + rb->s + rb->w) * AutoRouteParameters.CongestionPenalty / box_area(rb->sbox); +#endif +/* now handle the blockers: + * Go around the expansion area clockwise (North->East->South->West) + * pulling blockers from the heap (which makes them come out in the right + * order). Break the edges on the blocker and make the segments and corners + * moveable as possible. + */ + first = last = -1; + for (dir = RND_NORTH; dir <= RND_WEST; dir = directionIncrement(dir)) { + if (heap[dir] && !rnd_heap_is_empty(heap[dir])) { + /* pull the very first one out of the heap outside of the + * heap loop because it is special; it can be part of a corner + */ + routebox_t *blk = (routebox_t *) rnd_heap_remove_smallest(heap[dir]); + rnd_box_t b = rb->sbox; + struct broken_boxes broke = break_box_edge(&b, dir, blk); + if (broke.is_valid_left) { + /* if last > 0, then the previous edge had a segment + * joining this one, so it forms a valid corner expansion + */ + if (last > 0) { + /* make a corner expansion */ + rnd_box_t db = b; + switch (dir) { + case RND_EAST: + /* possible NE expansion */ + db.X1 = last; + db.Y2 = MIN(db.Y2, broke.left.Y2); + break; + case RND_SOUTH: + /* possible SE expansion */ + db.Y1 = last; + db.X1 = MAX(db.X1, broke.left.X1); + break; + case RND_WEST: + /* possible SW expansion */ + db.X2 = last; + db.Y1 = MAX(db.Y1, broke.left.Y1); + break; + default: + assert(0); + break; + } + moveable_edge(edges, &db, (rnd_direction_t) (dir + 3), rb, NULL, e, targets, s, NULL, NULL); + } + else if (dir == RND_NORTH) { /* north is start, so nothing "before" it */ + /* save for a possible corner once we've + * finished circling the box + */ + first = MAX(b.X1, broke.left.X2); + } + else { + /* this is just a boring straight expansion + * since the orthogonal segment was blocked + */ + moveable_edge(edges, &broke.left, dir, rb, NULL, e, targets, s, NULL, NULL); + } + } /* broke.is_valid_left */ + else if (last > 0) { + /* if the last one didn't become a corner, + * we still want to expand it straight out + * in the direction of the previous edge, + * which it belongs to. + */ + rnd_box_t db = previous_edge(last, dir, &rb->sbox); + moveable_edge(edges, &db, (rnd_direction_t) (dir - 1), rb, NULL, e, targets, s, NULL, NULL); + } + if (broke.is_valid_center && !blk->flags.source) + moveable_edge(edges, &broke.center, dir, rb, blk, e, targets, s, tree, area_vec); + /* this is the heap extraction loop. We break out + * if there's nothing left in the heap, but if we * are blocked all the way to the far edge, we can + * just leave stuff in the heap when it is destroyed + */ + while (broke.is_valid_right) { + /* move the box edge to the next potential free point */ + switch (dir) { + case RND_NORTH: + last = b.X1 = MAX(broke.right.X1, b.X1); + break; + case RND_EAST: + last = b.Y1 = MAX(broke.right.Y1, b.Y1); + break; + case RND_SOUTH: + last = b.X2 = MIN(broke.right.X2, b.X2); + break; + case RND_WEST: + last = b.Y2 = MIN(broke.right.Y2, b.Y2); + break; + default: + assert(0); + } + if (rnd_heap_is_empty(heap[dir])) + break; + blk = (routebox_t *) rnd_heap_remove_smallest(heap[dir]); + broke = break_box_edge(&b, dir, blk); + if (broke.is_valid_left) + moveable_edge(edges, &broke.left, dir, rb, NULL, e, targets, s, NULL, NULL); + if (broke.is_valid_center && !blk->flags.source) + moveable_edge(edges, &broke.center, dir, rb, blk, e, targets, s, tree, area_vec); + } + if (!broke.is_valid_right) + last = -1; + } + else { /* if (heap[dir]) */ + + /* nothing touched this edge! Expand the whole edge unless + * (1) it hit the board edge or (2) was the source of our expansion + * + * for this case (of hitting nothing) we give up trying for corner + * expansions because it is likely that they're not possible anyway + */ + if ((e->expand_dir == RND_ANY_DIR ? e->rb->came_from : e->expand_dir) != ((dir + 2) % 4)) { + /* ok, we are not going back on ourselves, and the whole edge seems free */ + moveable_edge(edges, &rb->sbox, dir, rb, NULL, e, targets, s, NULL, NULL); + } + + if (last > 0) { + /* expand the leftover from the prior direction */ + rnd_box_t db = previous_edge(last, dir, &rb->sbox); + moveable_edge(edges, &db, (rnd_direction_t) (dir - 1), rb, NULL, e, targets, s, NULL, NULL); + } + last = -1; + } + } /* for loop */ + /* finally, check for the NW corner now that we've come full circle */ + if (first > 0 && last > 0) { + rnd_box_t db = rb->sbox; + db.X2 = first; + db.Y2 = last; + moveable_edge(edges, &db, RND_NW, rb, NULL, e, targets, s, NULL, NULL); + } + else { + if (first > 0) { + rnd_box_t db = rb->sbox; + db.X2 = first; + moveable_edge(edges, &db, RND_NORTH, rb, NULL, e, targets, s, NULL, NULL); + } + else if (last > 0) { + rnd_box_t db = rb->sbox; + db.Y2 = last; + moveable_edge(edges, &db, RND_WEST, rb, NULL, e, targets, s, NULL, NULL); + } + } + /* done with all expansion edges of this box */ + for (dir = RND_NORTH; dir <= RND_WEST; dir = directionIncrement(dir)) { + if (heap[dir]) + rnd_heap_destroy(&heap[dir]); + } + return edges; +} + +static routebox_t *rb_source(routebox_t * rb) +{ + while (rb && !rb->flags.source) { + assert(rb->type == EXPANSION_AREA); + rb = rb->parent.expansion_area; + } + assert(rb); + return rb; +} + +/* ------------ */ + +struct foib_info { + const rnd_box_t *box; + routebox_t *intersect; + jmp_buf env; +}; + +static rnd_r_dir_t foib_rect_in_reg(const rnd_box_t * box, void *cl) +{ + struct foib_info *foib = (struct foib_info *) cl; + rnd_box_t rbox; + routebox_t *rb = (routebox_t *) box; + if (rb->flags.touched) + return RND_R_DIR_NOT_FOUND; +/* if (rb->type == EXPANSION_AREA && !rb->flags.is_via)*/ + /* return RND_R_DIR_NOT_FOUND; */ + rbox = bloat_routebox(rb); + if (!rnd_box_intersect(&rbox, foib->box)) + return RND_R_DIR_NOT_FOUND; + /* this is an intersector! */ + foib->intersect = (routebox_t *) box; + longjmp(foib->env, 1); /* skip to the end! */ + return RND_R_DIR_FOUND_CONTINUE; +} + +static routebox_t *FindOneInBox(rnd_rtree_t * rtree, routebox_t * rb) +{ + struct foib_info foib; + rnd_box_t r; + + r = rb->sbox; + foib.box = &r; + foib.intersect = NULL; + + if (setjmp(foib.env) == 0) + rnd_r_search(rtree, &r, NULL, foib_rect_in_reg, &foib, NULL); + return foib.intersect; +} + +struct therm_info { + routebox_t *plane; + rnd_box_t query; + jmp_buf env; +}; +static rnd_r_dir_t ftherm_rect_in_reg(const rnd_box_t * box, void *cl) +{ + routebox_t *rbox = (routebox_t *) box; + struct therm_info *ti = (struct therm_info *) cl; + rnd_box_t sq, sb; + + if (rbox->type != TERM) + return RND_R_DIR_NOT_FOUND; + if (rbox->group != ti->plane->group) + return RND_R_DIR_NOT_FOUND; + + sb = shrink_routebox(rbox); + switch (rbox->type) { + case TERM: + case VIA_SHADOW: + sq = rnd_shrink_box(&ti->query, rbox->style->Diameter); + if (!rnd_box_intersect(&sb, &sq)) + return RND_R_DIR_NOT_FOUND; + sb.X1 = RND_BOX_CENTER_X(sb); + sb.Y1 = RND_BOX_CENTER_Y(sb); + break; + default: + assert(0); + } + ti->plane = rbox; + longjmp(ti->env, 1); + return RND_R_DIR_FOUND_CONTINUE; +} + +/* check for a pin or via target that a polygon can just use a thermal to connect to */ +routebox_t *FindThermable(rnd_rtree_t * rtree, routebox_t * rb) +{ + struct therm_info info; + + info.plane = rb; + info.query = shrink_routebox(rb); + + if (setjmp(info.env) == 0) { + rnd_r_search(rtree, &info.query, NULL, ftherm_rect_in_reg, &info, NULL); + return NULL; + } + return info.plane; +} + +/*-------------------------------------------------------------------- + * Route-tracing code: once we've got a path of expansion boxes, trace + * a line through them to actually create the connection. + */ +static void RD_DrawThermal(routedata_t * rd, rnd_coord_t X, rnd_coord_t Y, rnd_cardinal_t group, rnd_cardinal_t layer, routebox_t * subnet, rnd_bool is_bad) +{ + routebox_t *rb; + rb = (routebox_t *) malloc(sizeof(*rb)); + memset((void *) rb, 0, sizeof(*rb)); + init_const_box(rb, X, Y, X + 1, Y + 1, 0); + rb->group = group; + rb->layer = layer; + rb->flags.fixed = 0; + rb->flags.is_bad = is_bad; + rb->flags.is_odd = AutoRouteParameters.is_odd; + rb->flags.circular = 0; + rb->style = AutoRouteParameters.style; + rb->type = THERMAL; + InitLists(rb); + MergeNets(rb, subnet, NET); + MergeNets(rb, subnet, SUBNET); + /* add it to the r-tree, this may be the whole route! */ + rnd_r_insert_entry(rd->layergrouptree[rb->group], &rb->box); + rb->flags.homeless = 0; +} + +static void RD_DrawVia(routedata_t * rd, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t radius, routebox_t * subnet, rnd_bool is_bad) +{ + routebox_t *rb, *first_via = NULL; + int i; + int ka = AutoRouteParameters.style->Clearance; + pcb_pstk_t *live_via = NULL; + + if (conf_core.editor.live_routing) { +TODO("padstack: when style contains proto, remove this") + live_via = pcb_pstk_new_compat_via(PCB->Data, -1, X, Y, AutoRouteParameters.style->Hole, radius * 2, 2 * AutoRouteParameters.style->Clearance, 0, PCB_PSTK_COMPAT_ROUND, 1); + if (live_via != NULL) + pcb_pstk_invalidate_draw(live_via); + } + + /* a via cuts through every layer group */ + for (i = 0; i < pcb_max_group(PCB); i++) { + if (!is_layer_group_active[i]) + continue; + rb = (routebox_t *) malloc(sizeof(*rb)); + memset((void *) rb, 0, sizeof(*rb)); + init_const_box(rb, + /*X1 */ X - radius, /*Y1 */ Y - radius, + /*X2 */ X + radius + 1, /*Y2 */ Y + radius + 1, ka); + rb->group = i; + rb->flags.fixed = 0; /* indicates that not on PCB yet */ + rb->flags.is_odd = AutoRouteParameters.is_odd; + rb->flags.is_bad = is_bad; + rb->came_from = RND_ANY_DIR; + rb->flags.circular = rnd_true; + rb->style = AutoRouteParameters.style; + rb->pass = AutoRouteParameters.pass; + if (first_via == NULL) { + rb->type = VIA; + rb->parent.via = NULL; /* indicates that not on PCB yet */ + first_via = rb; + /* only add the first via to mtspace, not the shadows too */ + mtspace_add(rd->mtspace, &rb->box, rb->flags.is_odd ? ODD : EVEN, rb->style->Clearance); + } + else { + rb->type = VIA_SHADOW; + rb->parent.via_shadow = first_via; + } + InitLists(rb); + /* add these to proper subnet. */ + MergeNets(rb, subnet, NET); + MergeNets(rb, subnet, SUBNET); + assert(__routepcb_box_is_good(rb)); + /* and add it to the r-tree! */ + rnd_r_insert_entry(rd->layergrouptree[rb->group], &rb->box); + rb->flags.homeless = 0; /* not homeless anymore */ + rb->livedraw_obj.via = live_via; + } +} + +static void +RD_DrawLine(routedata_t * rd, + rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, + rnd_coord_t Y2, rnd_coord_t halfthick, rnd_cardinal_t group, routebox_t * subnet, rnd_bool is_bad, rnd_bool is_45) +{ + /* we hold the line in a queue to concatenate segments that + * ajoin one another. That reduces the number of things in + * the trees and allows conflict boxes to be larger, both of + * which are really useful. + */ + static rnd_coord_t qX1 = -1, qY1, qX2, qY2; + static rnd_coord_t qhthick; + static rnd_cardinal_t qgroup; + static rnd_bool qis_45, qis_bad; + static routebox_t *qsn; + + routebox_t *rb; + rnd_coord_t ka = AutoRouteParameters.style->Clearance; + + /* don't draw zero-length segments. */ + if (X1 == X2 && Y1 == Y2) + return; + if (qX1 == -1) { /* first ever */ + qX1 = X1; + qY1 = Y1; + qX2 = X2; + qY2 = Y2; + qhthick = halfthick; + qgroup = group; + qis_45 = is_45; + qis_bad = is_bad; + qsn = subnet; + return; + } + /* Check if the lines concatenat. We only check the + * normal expected nextpoint=lastpoint condition + */ + if (X1 == qX2 && Y1 == qY2 && qhthick == halfthick && qgroup == group) { + if (qX1 == qX2 && X1 == X2) { /* everybody on the same X here */ + qY2 = Y2; + return; + } + if (qY1 == qY2 && Y1 == Y2) { /* same Y all around */ + qX2 = X2; + return; + } + } + /* dump the queue, no match here */ + if (qX1 == -1) + return; /* but not this! */ + rb = (routebox_t *) malloc(sizeof(*rb)); + memset((void *) rb, 0, sizeof(*rb)); + assert(is_45 ? (RND_ABS(qX2 - qX1) == RND_ABS(qY2 - qY1)) /* line must be 45-degrees */ + : (qX1 == qX2 || qY1 == qY2) /* line must be ortho */ ); + init_const_box(rb, + /*X1 */ MIN(qX1, qX2) - qhthick, + /*Y1 */ MIN(qY1, qY2) - qhthick, + /*X2 */ MAX(qX1, qX2) + qhthick + 1, + /*Y2 */ MAX(qY1, qY2) + qhthick + 1, ka); + rb->group = qgroup; + rb->type = LINE; + rb->line.x1 = qX1; + rb->line.x2 = qX2; + rb->line.y1 = qY1; + rb->line.y2 = qY2; + rb->parent.line = NULL; /* indicates that not on PCB yet */ + rb->flags.fixed = 0; /* indicates that not on PCB yet */ + rb->flags.is_odd = AutoRouteParameters.is_odd; + rb->flags.is_bad = qis_bad; + rb->came_from = RND_ANY_DIR; + rb->flags.homeless = 0; /* we're putting this in the tree */ + rb->flags.nonstraight = qis_45; + rb->flags.bl_to_ur = ((qX2 >= qX1 && qY2 <= qY1) + || (qX2 <= qX1 && qY2 >= qY1)); + rb->style = AutoRouteParameters.style; + rb->pass = AutoRouteParameters.pass; + InitLists(rb); + /* add these to proper subnet. */ + MergeNets(rb, qsn, NET); + MergeNets(rb, qsn, SUBNET); + assert(__routepcb_box_is_good(rb)); + /* and add it to the r-tree! */ + rnd_r_insert_entry(rd->layergrouptree[rb->group], &rb->box); + + if (conf_core.editor.live_routing) { + pcb_layer_t *layer = pcb_get_layer(PCB->Data, PCB->LayerGroups.grp[rb->group].lid[0]); + pcb_line_t *line = pcb_line_new(layer, qX1, qY1, qX2, qY2, + 2 * qhthick, 0, pcb_flag_make(0)); + rb->livedraw_obj.line = line; + if (line != NULL) + pcb_line_invalidate_draw(layer, line); + } + + /* and to the via space structures */ + if (AutoRouteParameters.use_vias) + mtspace_add(rd->mtspace, &rb->box, rb->flags.is_odd ? ODD : EVEN, rb->style->Clearance); + usedGroup[rb->group] = rnd_true; + /* and queue this one */ + qX1 = X1; + qY1 = Y1; + qX2 = X2; + qY2 = Y2; + qhthick = halfthick; + qgroup = group; + qis_45 = is_45; + qis_bad = is_bad; + qsn = subnet; +} + +static rnd_bool +RD_DrawManhattanLine(routedata_t * rd, + const rnd_box_t * box1, const rnd_box_t * box2, + rnd_cheap_point_t start, rnd_cheap_point_t end, + rnd_coord_t halfthick, rnd_cardinal_t group, routebox_t * subnet, rnd_bool is_bad, rnd_bool last_was_x) +{ + rnd_cheap_point_t knee = start; + if (end.X == start.X) { + RD_DrawLine(rd, start.X, start.Y, end.X, end.Y, halfthick, group, subnet, is_bad, rnd_false); + return rnd_false; + } + else if (end.Y == start.Y) { + RD_DrawLine(rd, start.X, start.Y, end.X, end.Y, halfthick, group, subnet, is_bad, rnd_false); + return rnd_true; + } + /* find where knee belongs */ + if (rnd_point_in_box(box1, end.X, start.Y) + || rnd_point_in_box(box2, end.X, start.Y)) { + knee.X = end.X; + knee.Y = start.Y; + } + else { + knee.X = start.X; + knee.Y = end.Y; + } + if ((knee.X == end.X && !last_was_x) && (rnd_point_in_box(box1, start.X, end.Y) + || rnd_point_in_box(box2, start.X, end.Y))) { + knee.X = start.X; + knee.Y = end.Y; + } + assert(AutoRouteParameters.is_smoothing || rnd_point_in_closed_box(box1, knee.X, knee.Y) + || rnd_point_in_closed_box(box2, knee.X, knee.Y)); + + if (1 || !AutoRouteParameters.is_smoothing) { + /* draw standard manhattan paths */ + RD_DrawLine(rd, start.X, start.Y, knee.X, knee.Y, halfthick, group, subnet, is_bad, rnd_false); + RD_DrawLine(rd, knee.X, knee.Y, end.X, end.Y, halfthick, group, subnet, is_bad, rnd_false); + } + else { + /* draw 45-degree path across knee */ + rnd_coord_t len45 = MIN(RND_ABS(start.X - end.X), RND_ABS(start.Y - end.Y)); + rnd_cheap_point_t kneestart = knee, kneeend = knee; + if (kneestart.X == start.X) + kneestart.Y += (kneestart.Y > start.Y) ? -len45 : len45; + else + kneestart.X += (kneestart.X > start.X) ? -len45 : len45; + if (kneeend.X == end.X) + kneeend.Y += (kneeend.Y > end.Y) ? -len45 : len45; + else + kneeend.X += (kneeend.X > end.X) ? -len45 : len45; + RD_DrawLine(rd, start.X, start.Y, kneestart.X, kneestart.Y, halfthick, group, subnet, is_bad, rnd_false); + RD_DrawLine(rd, kneestart.X, kneestart.Y, kneeend.X, kneeend.Y, halfthick, group, subnet, is_bad, rnd_true); + RD_DrawLine(rd, kneeend.X, kneeend.Y, end.X, end.Y, halfthick, group, subnet, is_bad, rnd_false); + } + return (knee.X != end.X); +} + +/* for smoothing, don't pack traces to min clearance gratuitously */ +#if 0 +static void add_clearance(rnd_cheap_point_t * nextpoint, const rnd_box_t * b) +{ + if (nextpoint->X == b->X1) { + if (nextpoint->X + AutoRouteParameters.style->Clearance < (b->X1 + b->X2) / 2) + nextpoint->X += AutoRouteParameters.style->Clearance; + else + nextpoint->X = (b->X1 + b->X2) / 2; + } + else if (nextpoint->X == b->X2) { + if (nextpoint->X - AutoRouteParameters.style->Clearance > (b->X1 + b->X2) / 2) + nextpoint->X -= AutoRouteParameters.style->Clearance; + else + nextpoint->X = (b->X1 + b->X2) / 2; + } + else if (nextpoint->Y == b->Y1) { + if (nextpoint->Y + AutoRouteParameters.style->Clearance < (b->Y1 + b->Y2) / 2) + nextpoint->Y += AutoRouteParameters.style->Clearance; + else + nextpoint->Y = (b->Y1 + b->Y2) / 2; + } + else if (nextpoint->Y == b->Y2) { + if (nextpoint->Y - AutoRouteParameters.style->Clearance > (b->Y1 + b->Y2) / 2) + nextpoint->Y -= AutoRouteParameters.style->Clearance; + else + nextpoint->Y = (b->Y1 + b->Y2) / 2; + } +} +#endif + +/* This back-traces the expansion boxes along the best path + * it draws the lines that will make the actual path. + * during refinement passes, it should try to maximize the area + * for other tracks so routing completion is easier. + * + * during smoothing passes, it should try to make a better path, + * possibly using diagonals, etc. The path boxes are larger on + * average now so there is more possiblity to decide on a nice + * path. Any combination of lines and arcs is possible, so long + * as they don't poke more than half thick outside the path box. + */ + +static void TracePath(routedata_t * rd, routebox_t * path, const routebox_t * target, routebox_t * subnet, rnd_bool is_bad) +{ + rnd_bool last_x = rnd_false; + rnd_coord_t halfwidth = HALF_THICK(AutoRouteParameters.style->Thick); + rnd_coord_t radius = HALF_THICK(AutoRouteParameters.style->Diameter); + rnd_cheap_point_t lastpoint, nextpoint; + routebox_t *lastpath; + rnd_box_t b; + + assert(subnet->style == AutoRouteParameters.style); + /*XXX: because we round up odd thicknesses, there's the possibility that + * a connecting line end-point might be 0.005 mil off the "real" edge. + * don't worry about this because line *thicknesses* are always >= 0.01 mil. */ + + /* if we start with a thermal the target was a plane + * or the target was a pin and the source a plane + * in which case this thermal is the whole path + */ + if (path->flags.is_thermal) { + /* the target was a plane, so we need to find a good spot for the via + * now. It's logical to place it close to the source box which + * is where we're utlimately headed on this path. However, it + * must reside in the plane as well as the via area too. + */ + nextpoint.X = RND_BOX_CENTER_X(path->sbox); + nextpoint.Y = RND_BOX_CENTER_Y(path->sbox); + if (path->parent.expansion_area->flags.is_via) { + TargetPoint(&nextpoint, rb_source(path)); + /* nextpoint is the middle of the source terminal now */ + b = rnd_clip_box(&path->sbox, &path->parent.expansion_area->sbox); + nextpoint = rnd_closest_cheap_point_in_box(&nextpoint, &b); + /* now it's in the via and plane near the source */ + } + else { /* no via coming, target must have been a pin */ + + assert(target->type == TERM); + TargetPoint(&nextpoint, target); + } + assert(rnd_point_in_box(&path->sbox, nextpoint.X, nextpoint.Y)); + RD_DrawThermal(rd, nextpoint.X, nextpoint.Y, path->group, path->layer, subnet, is_bad); + } + else { + /* start from best place of target box */ + lastpoint.X = RND_BOX_CENTER_X(target->sbox); + lastpoint.Y = RND_BOX_CENTER_Y(target->sbox); + TargetPoint(&lastpoint, target); + if (AutoRouteParameters.last_smooth && rnd_box_in_box(&path->sbox, &target->sbox)) + path = path->parent.expansion_area; + b = path->sbox; + if (path->flags.circular) + b = rnd_shrink_box(&b, MIN(b.X2 - b.X1, b.Y2 - b.Y1) / 5); + nextpoint = rnd_closest_cheap_point_in_box(&lastpoint, &b); + if (AutoRouteParameters.last_smooth) + RD_DrawLine(rd, lastpoint.X, lastpoint.Y, nextpoint.X, nextpoint.Y, halfwidth, path->group, subnet, is_bad, rnd_true); + else + last_x = RD_DrawManhattanLine(rd, &target->sbox, &path->sbox, + lastpoint, nextpoint, halfwidth, path->group, subnet, is_bad, last_x); + } +#if defined(ROUTE_DEBUG) && defined(DEBUG_SHOW_ROUTE_BOXES) + showroutebox(path); +#if defined(ROUTE_VERBOSE) + rnd_printf("TRACEPOINT start %#mD\n", nextpoint.X, nextpoint.Y); +#endif +#endif + + do { + lastpoint = nextpoint; + lastpath = path; + assert(path->type == EXPANSION_AREA); + path = path->parent.expansion_area; + b = path->sbox; + if (path->flags.circular) + b = rnd_shrink_box(&b, MIN(b.X2 - b.X1, b.Y2 - b.Y1) / 5); + assert(b.X1 != b.X2 && b.Y1 != b.Y2); /* need someplace to put line! */ + /* find point on path perimeter closest to last point */ + /* if source terminal, try to hit a good place */ + nextpoint = rnd_closest_cheap_point_in_box(&lastpoint, &b); +#if 0 + /* leave more clearance if this is a smoothing pass */ + if (AutoRouteParameters.is_smoothing && (nextpoint.X != lastpoint.X || nextpoint.Y != lastpoint.Y)) + add_clearance(&nextpoint, &b); +#endif + if (path->flags.source && path->type != PLANE) + TargetPoint(&nextpoint, path); + assert(rnd_point_in_box(&lastpath->box, lastpoint.X, lastpoint.Y)); + assert(rnd_point_in_box(&path->box, nextpoint.X, nextpoint.Y)); +#if defined(ROUTE_DEBUG_VERBOSE) + printf("TRACEPATH: "); + DumpRouteBox(path); + rnd_printf("TRACEPATH: point %#mD to point %#mD layer %d\n", + lastpoint.X, lastpoint.Y, nextpoint.X, nextpoint.Y, path->group); +#endif + + /* draw orthogonal lines from lastpoint to nextpoint */ + /* knee is placed in lastpath box */ + /* should never cause line to leave union of lastpath/path boxes */ + if (AutoRouteParameters.last_smooth) + RD_DrawLine(rd, lastpoint.X, lastpoint.Y, nextpoint.X, nextpoint.Y, halfwidth, path->group, subnet, is_bad, rnd_true); + else + last_x = RD_DrawManhattanLine(rd, &lastpath->sbox, &path->sbox, + lastpoint, nextpoint, halfwidth, path->group, subnet, is_bad, last_x); + if (path->flags.is_via) { /* if via, then add via */ +#ifdef ROUTE_VERBOSE + printf(" (vias)"); +#endif + assert(rnd_point_in_box(&path->box, nextpoint.X, nextpoint.Y)); + RD_DrawVia(rd, nextpoint.X, nextpoint.Y, radius, subnet, is_bad); + } + + assert(lastpath->flags.is_via || path->group == lastpath->group); + +#if defined(ROUTE_DEBUG) && defined(DEBUG_SHOW_ROUTE_BOXES) + showroutebox(path); +#endif /* ROUTE_DEBUG && DEBUG_SHOW_ROUTE_BOXES */ + /* if this is connected to a plane, draw the thermal */ + if (path->flags.is_thermal || path->type == PLANE) + RD_DrawThermal(rd, lastpoint.X, lastpoint.Y, path->group, path->layer, subnet, is_bad); + /* when one hop from the source, make an extra path in *this* box */ + if (path->type == EXPANSION_AREA && path->parent.expansion_area->flags.source && path->parent.expansion_area->type != PLANE) { + /* find special point on source (if it exists) */ + if (TargetPoint(&lastpoint, path->parent.expansion_area)) { + lastpoint = closest_point_in_routebox(&lastpoint, path); + b = shrink_routebox(path); +#if 0 + if (AutoRouteParameters.is_smoothing) + add_clearance(&lastpoint, &b); +#else + if (AutoRouteParameters.last_smooth) + RD_DrawLine(rd, lastpoint.X, lastpoint.Y, nextpoint.X, nextpoint.Y, halfwidth, path->group, subnet, is_bad, rnd_true); + else +#endif + last_x = RD_DrawManhattanLine(rd, &b, &b, nextpoint, lastpoint, halfwidth, path->group, subnet, is_bad, last_x); +#if defined(ROUTE_DEBUG_VERBOSE) + printf("TRACEPATH: "); + DumpRouteBox(path); + pcb_printf + ("TRACEPATH: (to source) point %#mD to point %#mD layer %d\n", + nextpoint.X, nextpoint.Y, lastpoint.X, lastpoint.Y, path->group); +#endif + + nextpoint = lastpoint; + } + } + } + while (!path->flags.source); + /* flush the line queue */ + RD_DrawLine(rd, -1, 0, 0, 0, 0, 0, NULL, rnd_false, rnd_false); + + if (conf_core.editor.live_routing) + pcb_draw(); + +#ifdef ROUTE_DEBUG + if (ddraw != NULL) + ddraw->flush_debug_draw(); +#endif +} + +/* create a fake "edge" used to defer via site searching. */ +static void +CreateSearchEdge(routeone_state_t *s, vetting_t * work, edge_t * parent, + routebox_t * rb, conflict_t conflict, rnd_rtree_t * targets, rnd_bool in_plane) +{ + routebox_t *target; + rnd_box_t b; + rnd_heap_cost_t cost; + assert(__routepcb_box_is_good(rb)); + /* find the cheapest target */ +#if 0 + target = minpcb_cost_target_to_point(&parent->cost_point, pcb_max_group(PCB) + 1, targets, parent->minpcb_cost_target); +#else + target = parent->minpcb_cost_target; +#endif + b = shrink_routebox(target); + cost = parent->pcb_cost_to_point + AutoRouteParameters.ViaCost + pcb_cost_to_layerless_box(&rb->cost_point, 0, &b); + if (cost < s->best_cost) { + edge_t *ne; + ne = (edge_t *) malloc(sizeof(*ne)); + memset((void *) ne, 0, sizeof(*ne)); + assert(ne); + ne->flags.via_search = 1; + ne->flags.in_plane = in_plane; + ne->rb = rb; + if (rb->flags.homeless) + RB_up_count(rb); + ne->work = work; + ne->minpcb_cost_target = target; + ne->flags.via_conflict_level = conflict; + ne->pcb_cost_to_point = parent->pcb_cost_to_point; + ne->cost_point = parent->cost_point; + ne->cost = cost; + rnd_heap_insert(s->workheap, ne->cost, ne); + } + else { + mtsFreeWork(&work); + } +} + +static void add_or_destroy_edge(routeone_state_t *s, edge_t * e) +{ + e->cost = edge_cost(e, s->best_cost); + assert(__edge_is_good(e)); + assert(is_layer_group_active[e->rb->group]); + if (e->cost < s->best_cost) + rnd_heap_insert(s->workheap, e->cost, e); + else + DestroyEdge(&e); +} + +static void best_path_candidate(routeone_state_t *s, edge_t * e, routebox_t * best_target) +{ + e->cost = edge_cost(e, EXPENSIVE); + if (s->best_path == NULL || e->cost < s->best_cost) { +#if defined(ROUTE_DEBUG) && defined (ROUTE_VERBOSE) + printf("New best path seen! cost = %f\n", e->cost); +#endif + /* new best path! */ + if (s->best_path && s->best_path->flags.homeless) + RB_down_count(s->best_path); + s->best_path = e->rb; + s->best_target = best_target; + s->best_cost = e->cost; + assert(s->best_cost >= 0); + /* don't free this when we destroy edge! */ + if (s->best_path->flags.homeless) + RB_up_count(s->best_path); + } +} + + +/* vectors for via site candidates (see mtspace.h) */ +struct routeone_via_site_state { + vector_t *free_space_vec; + vector_t *lo_conflict_space_vec; + vector_t *hi_conflict_space_vec; +}; + +void +add_via_sites(routeone_state_t *s, + struct routeone_via_site_state *vss, + mtspace_t * mtspace, routebox_t * within, + conflict_t within_conflict_level, edge_t * parent_edge, rnd_rtree_t * targets, rnd_coord_t shrink, rnd_bool in_plane) +{ + rnd_coord_t radius, clearance; + vetting_t *work; + rnd_box_t region = shrink_routebox(within); + rnd_shrink_box(®ion, shrink); + + radius = HALF_THICK(AutoRouteParameters.style->Diameter); + clearance = AutoRouteParameters.style->Clearance; + assert(AutoRouteParameters.use_vias); + /* XXX: need to clip 'within' to shrunk_pcb_bounds, because when + XXX: routing with conflicts may poke over edge. */ + + /* ask for a via box near our cost_point first */ + work = mtspace_query_rect(mtspace, ®ion, radius, clearance, + NULL, vss->free_space_vec, + vss->lo_conflict_space_vec, + vss->hi_conflict_space_vec, + AutoRouteParameters.is_odd, AutoRouteParameters.with_conflicts, &parent_edge->cost_point); + if (!work) + return; + CreateSearchEdge(s, work, parent_edge, within, within_conflict_level, targets, in_plane); +} + +void +do_via_search(edge_t * search, routeone_state_t *s, + struct routeone_via_site_state *vss, mtspace_t * mtspace, rnd_rtree_t * targets) +{ + int i, j, count = 0; + rnd_coord_t radius, clearance; + vetting_t *work; + routebox_t *within; + conflict_t within_conflict_level; + + radius = HALF_THICK(AutoRouteParameters.style->Diameter); + clearance = AutoRouteParameters.style->Clearance; + work = mtspace_query_rect(mtspace, NULL, 0, 0, + search->work, vss->free_space_vec, + vss->lo_conflict_space_vec, + vss->hi_conflict_space_vec, AutoRouteParameters.is_odd, AutoRouteParameters.with_conflicts, NULL); + within = search->rb; + within_conflict_level = search->flags.via_conflict_level; + for (i = 0; i < 3; i++) { + vector_t *v = + (i == NO_CONFLICT ? vss->free_space_vec : + i == LO_CONFLICT ? vss->lo_conflict_space_vec : i == HI_CONFLICT ? vss->hi_conflict_space_vec : NULL); + assert(v); + while (!vector_is_empty(v)) { + rnd_box_t cliparea; + rnd_box_t *area = (rnd_box_t *) vector_remove_last(v); + if (!(i == NO_CONFLICT || AutoRouteParameters.with_conflicts)) { + free(area); + continue; + } + /* answers are bloated by radius + clearance */ + cliparea = rnd_shrink_box(area, radius + clearance); + rnd_close_box(&cliparea); + free(area); + assert(rnd_box_is_good(&cliparea)); + count++; + for (j = 0; j < pcb_max_group(PCB); j++) { + edge_t *ne; + if (j == within->group || !is_layer_group_active[j]) + continue; + ne = CreateViaEdge(&cliparea, j, within, search, within_conflict_level, (conflict_t) i, targets); + add_or_destroy_edge(s, ne); + } + } + } + /* prevent freeing of work when this edge is destroyed */ + search->flags.via_search = 0; + if (!work) + return; + CreateSearchEdge(s, work, search, within, within_conflict_level, targets, search->flags.in_plane); + assert(vector_is_empty(vss->free_space_vec)); + assert(vector_is_empty(vss->lo_conflict_space_vec)); + assert(vector_is_empty(vss->hi_conflict_space_vec)); +} + +/* vector of expansion areas to be eventually removed from r-tree + * this is a global for troubleshooting + */ +vector_t *area_vec; + +/* some routines for use in gdb while debugging */ +#if defined(ROUTE_DEBUG) +static void list_conflicts(routebox_t * rb) +{ + int i, n; + if (!rb->conflicts_with) + return; + n = vector_size(rb->conflicts_with); + for (i = 0; i < n; i++) + printf("%p, ", (void *)vector_element(rb->conflicts_with, i)); +} + +static void show_area_vec(int lay) +{ + int n, save; + + if (!area_vec) + return; + save = showboxen; + showboxen = lay; + for (n = 0; n < vector_size(area_vec); n++) { + routebox_t *rb = (routebox_t *) vector_element(area_vec, n); + showroutebox(rb); + } + showboxen = save; +} + +static rnd_bool net_id(routebox_t * rb, long int id) +{ + routebox_t *p; + LIST_LOOP(rb, same_net, p); + if (p->flags.source && p->parent.pad->ID == id) + return rnd_true; + PCB_END_LOOP; + return rnd_false; +} + +static void trace_parents(routebox_t * rb) +{ + while (rb && rb->type == EXPANSION_AREA) { + printf(" %p ->", (void *)rb); + rb = rb->parent.expansion_area; + } + if (rb) + printf(" %p is source\n", (void *)rb); + else + printf("NULL!\n"); +} + +static void show_one(routebox_t * rb) +{ + int save = showboxen; + showboxen = -1; + showroutebox(rb); + showboxen = save; +} + +static void show_path(routebox_t * rb) +{ + while (rb && rb->type == EXPANSION_AREA) { + show_one(rb); + rb = rb->parent.expansion_area; + } + show_one(rb); +} + +static void show_sources(routebox_t * rb) +{ + routebox_t *p; + if (!rb->flags.source && !rb->flags.target) { + printf("start with a source or target please\n"); + return; + } + LIST_LOOP(rb, same_net, p); + if (p->flags.source) + show_one(p); + PCB_END_LOOP; +} + +#endif + +static rnd_r_dir_t __conflict_source(const rnd_box_t * box, void *cl) +{ + routebox_t *rb = (routebox_t *) box; + if (rb->flags.touched || rb->flags.fixed) + return RND_R_DIR_NOT_FOUND; + else { + routebox_t *dis = (routebox_t *) cl; + path_conflicts(dis, rb, rnd_false); + touch_conflicts(dis->conflicts_with, 1); + } + return RND_R_DIR_FOUND_CONTINUE; +} + +static void source_conflicts(rnd_rtree_t * tree, routebox_t * rb) +{ + if (!AutoRouteParameters.with_conflicts) + return; + rnd_r_search(tree, &rb->sbox, NULL, __conflict_source, rb, NULL); + touch_conflicts(NULL, 1); +} + +typedef struct routeone_status_s { + rnd_bool found_route; + int route_had_conflicts; + rnd_heap_cost_t best_route_cost; + rnd_bool net_completely_routed; +} routeone_status_t; + + +static routeone_status_t RouteOne(routedata_t * rd, routebox_t * from, routebox_t * to, int max_edges) +{ + routeone_status_t result; + routebox_t *p; + int seen, i; + const rnd_box_t **target_list; + int num_targets; + rnd_rtree_t *targets; + /* vector of source edges for filtering */ + vector_t *source_vec; + /* working vector */ + vector_t *edge_vec; + + routeone_state_t s; + struct routeone_via_site_state vss; + + assert(rd && from); + result.route_had_conflicts = 0; + /* no targets on to/from net need clearance areas */ + LIST_LOOP(from, same_net, p); + p->flags.nobloat = 1; + PCB_END_LOOP; + /* set 'source' flags */ + LIST_LOOP(from, same_subnet, p); + if (!p->flags.nonstraight) + p->flags.source = 1; + PCB_END_LOOP; + + /* count up the targets */ + num_targets = 0; + seen = 0; + /* remove source/target flags from non-straight obstacles, because they + * don't fill their bounding boxes and so connecting to them + * after we've routed is problematic. Better solution? */ + if (to) { /* if we're routing to a specific target */ + if (!to->flags.source) { /* not already connected */ + /* check that 'to' and 'from' are on the same net */ + seen = 0; +#ifndef NDEBUG + LIST_LOOP(from, same_net, p); + if (p == to) + seen = 1; + PCB_END_LOOP; +#endif + assert(seen); /* otherwise from and to are on different nets! */ + /* set target flags only on 'to's subnet */ + LIST_LOOP(to, same_subnet, p); + if (!p->flags.nonstraight && is_layer_group_active[p->group]) { + p->flags.target = 1; + num_targets++; + } + PCB_END_LOOP; + } + } + else { + /* all nodes on the net but not connected to from are targets */ + LIST_LOOP(from, same_net, p); + if (!p->flags.source && is_layer_group_active[p->group] + && !p->flags.nonstraight) { + p->flags.target = 1; + num_targets++; + } + PCB_END_LOOP; + } + + /* if no targets, then net is done! reset flags and return. */ + if (num_targets == 0) { + LIST_LOOP(from, same_net, p); + p->flags.source = p->flags.target = p->flags.nobloat = 0; + PCB_END_LOOP; + result.found_route = rnd_false; + result.net_completely_routed = rnd_true; + result.best_route_cost = 0; + result.route_had_conflicts = 0; + + return result; + } + result.net_completely_routed = rnd_false; + + /* okay, there's stuff to route */ + assert(!from->flags.target); + assert(num_targets > 0); + /* create list of target pointers and from that a r-tree of targets */ + target_list = (const rnd_box_t **) malloc(num_targets * sizeof(*target_list)); + i = 0; + LIST_LOOP(from, same_net, p); + if (p->flags.target) { + target_list[i++] = &p->box; +#if defined(ROUTE_DEBUG) && defined(DEBUG_SHOW_TARGETS) + showroutebox(p); +#endif + } + PCB_END_LOOP; + targets = rnd_r_create_tree(); + rnd_r_insert_array(targets, (const rnd_box_t **)target_list, i); + assert(i <= num_targets); + free(target_list); + + source_vec = vector_create(); + /* touch the source subnet to prepare check for conflictors */ + LIST_LOOP(from, same_subnet, p); + p->flags.touched = 1; + PCB_END_LOOP; + LIST_LOOP(from, same_subnet, p); + { + /* we need the test for 'source' because this box may be nonstraight */ + if (p->flags.source && is_layer_group_active[p->group]) { + rnd_cheap_point_t cp; + edge_t *e; + rnd_box_t b = shrink_routebox(p); + +#if defined(ROUTE_DEBUG) && defined(DEBUG_SHOW_SOURCES) + showroutebox(p); +#endif + /* may expand in all directions from source; center edge cost point. */ + /* note that planes shouldn't really expand, but we need an edge */ + + cp.X = RND_BOX_CENTER_X(b); + cp.Y = RND_BOX_CENTER_Y(b); + e = CreateEdge(p, cp.X, cp.Y, 0, NULL, RND_ANY_DIR, targets); + cp = rnd_closest_cheap_point_in_box(&cp, &e->minpcb_cost_target->sbox); + cp = rnd_closest_cheap_point_in_box(&cp, &b); + e->cost_point = cp; + p->cost_point = cp; + source_conflicts(rd->layergrouptree[p->group], p); + vector_append(source_vec, e); + } + } + PCB_END_LOOP; + LIST_LOOP(from, same_subnet, p); + p->flags.touched = 0; + PCB_END_LOOP; + /* break source edges; some edges may be too near obstacles to be able + * to exit from. */ + + /* okay, main expansion-search routing loop. */ + /* set up the initial activity heap */ + s.workheap = rnd_heap_create(); + assert(s.workheap); + while (!vector_is_empty(source_vec)) { + edge_t *e = (edge_t *) vector_remove_last(source_vec); + assert(is_layer_group_active[e->rb->group]); + e->cost = edge_cost(e, EXPENSIVE); + rnd_heap_insert(s.workheap, e->cost, e); + } + vector_destroy(&source_vec); + /* okay, process items from heap until it is empty! */ + s.best_path = NULL; + s.best_cost = EXPENSIVE; + area_vec = vector_create(); + edge_vec = vector_create(); + vss.free_space_vec = vector_create(); + vss.lo_conflict_space_vec = vector_create(); + vss.hi_conflict_space_vec = vector_create(); + while (!rnd_heap_is_empty(s.workheap)) { + edge_t *e = (edge_t *) rnd_heap_remove_smallest(s.workheap); +#ifdef ROUTE_DEBUG + if (aabort) + goto dontexpand; +#endif + /* don't bother expanding this edge if the minimum possible edge cost + * is already larger than the best edge cost we've found. */ + if (s.best_path && e->cost >= s.best_cost) { + rnd_heap_free(s.workheap, KillEdge); + goto dontexpand; /* skip this edge */ + } + /* surprisingly it helps to give up and not try too hard to find + * a route! This is not only faster, but results in better routing. + * who would have guessed? + */ + if (seen++ > max_edges) + goto dontexpand; + assert(__edge_is_good(e)); + /* mark or unmark conflictors as needed */ + touch_conflicts(e->rb->conflicts_with, 1); + if (e->flags.via_search) { + do_via_search(e, &s, &vss, rd->mtspace, targets); + goto dontexpand; + } + /* we should never add edges on inactive layer groups to the heap. */ + assert(is_layer_group_active[e->rb->group]); +#if defined(ROUTE_DEBUG) && defined(DEBUG_SHOW_EXPANSION_BOXES) + /*showedge (e); */ +#endif + if (e->rb->flags.is_thermal) { + best_path_candidate(&s, e, e->minpcb_cost_target); + goto dontexpand; + } + /* for a plane, look for quick connections with thermals or vias */ + if (e->rb->type == PLANE) { + routebox_t *pin = FindThermable(targets, e->rb); + if (pin) { + rnd_box_t b = shrink_routebox(pin); + edge_t *ne; + routebox_t *nrb; + assert(pin->flags.target); + nrb = CreateExpansionArea(&b, e->rb->group, e->rb, rnd_true, e); + nrb->flags.is_thermal = 1; + /* moving through the plane is free */ + e->cost_point.X = b.X1; + e->cost_point.Y = b.Y1; + ne = CreateEdge2(nrb, e->expand_dir, e, NULL, pin); + best_path_candidate(&s, ne, pin); + DestroyEdge(&ne); + } + else { + /* add in possible via sites in plane */ + if (AutoRouteParameters.use_vias && e->cost + AutoRouteParameters.ViaCost < s.best_cost) { + /* we need a giant thermal */ + routebox_t *nrb = CreateExpansionArea(&e->rb->sbox, e->rb->group, e->rb, + rnd_true, e); + edge_t *ne = CreateEdge2(nrb, e->expand_dir, e, NULL, + e->minpcb_cost_target); + nrb->flags.is_thermal = 1; + add_via_sites(&s, &vss, rd->mtspace, nrb, NO_CONFLICT, ne, targets, e->rb->style->Diameter, rnd_true); + } + } + goto dontexpand; /* planes only connect via thermals */ + } + if (e->flags.is_via) { /* special case via */ + routebox_t *intersecting; + assert(AutoRouteParameters.use_vias); + assert(e->expand_dir == RND_ANY_DIR); + assert(vector_is_empty(edge_vec)); + /* if there is already something here on this layer (like an + * EXPANSION_AREA), then we don't want to expand from here + * at least not inside the expansion area. A PLANE on the + * other hand may be a target, or not. + */ + intersecting = FindOneInBox(rd->layergrouptree[e->rb->group], e->rb); + + if (intersecting && intersecting->flags.target && intersecting->type == PLANE) { + /* we have hit a plane */ + edge_t *ne; + routebox_t *nrb; + rnd_box_t b = shrink_routebox(e->rb); + /* limit via region to that inside the plane */ + rnd_clip_box(&b, &intersecting->sbox); + nrb = CreateExpansionArea(&b, e->rb->group, e->rb, rnd_true, e); + nrb->flags.is_thermal = 1; + ne = CreateEdge2(nrb, e->expand_dir, e, NULL, intersecting); + best_path_candidate(&s, ne, intersecting); + DestroyEdge(&ne); + goto dontexpand; + } + else if (intersecting == NULL) { + /* this via candidate is in an open area; add it to r-tree as + * an expansion area */ + assert(e->rb->type == EXPANSION_AREA && e->rb->flags.is_via); + /*assert (!rnd_r_search(rd->layergrouptree[e->rb->group], + &e->rb->box, NULL, no_planes,0)); + */ + rnd_r_insert_entry(rd->layergrouptree[e->rb->group], &e->rb->box); + e->rb->flags.homeless = 0; /* not homeless any more */ + /* add to vector of all expansion areas in r-tree */ + vector_append(area_vec, e->rb); + /* mark reset refcount to 0, since this is not homeless any more. */ + e->rb->refcount = 0; + /* go ahead and expand this edge! */ + } + else if (1) + goto dontexpand; + else if (0) { /* XXX: disabling this causes no via + collisions. */ + rnd_box_t a = bloat_routebox(intersecting), b; + edge_t *ne; + int i, j; + /* something intersects this via candidate. split via candidate + * into pieces and add these pieces to the workheap. */ + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + b = shrink_routebox(e->rb); + switch (i) { + case 0: + b.X2 = MIN(b.X2, a.X1); + break; /* left */ + case 1: + b.X1 = MAX(b.X1, a.X1); + b.X2 = MIN(b.X2, a.X2); + break; /*c */ + case 2: + b.X1 = MAX(b.X1, a.X2); + break; /* right */ + default: + assert(0); + } + switch (j) { + case 0: + b.Y2 = MIN(b.Y2, a.Y1); + break; /* top */ + case 1: + b.Y1 = MAX(b.Y1, a.Y1); + b.Y2 = MIN(b.Y2, a.Y2); + break; /*c */ + case 2: + b.Y1 = MAX(b.Y1, a.Y2); + break; /* bottom */ + default: + assert(0); + } + /* skip if this box is not valid */ + if (!(b.X1 < b.X2 && b.Y1 < b.Y2)) + continue; + if (i == 1 && j == 1) { + /* this bit of the via space is obstructed. */ + if (intersecting->type == EXPANSION_AREA || intersecting->flags.fixed) + continue; /* skip this bit, it's already been done. */ + /* create an edge with conflicts, if enabled */ + if (!AutoRouteParameters.with_conflicts) + continue; + ne = CreateEdgeWithConflicts(&b, intersecting, e, 1 + /*cost penalty to box */ + , targets); + add_or_destroy_edge(&s, ne); + } + else { + /* if this is not the intersecting piece, create a new + * (hopefully unobstructed) via edge and add it back to the + * workheap. */ + ne = CreateViaEdge(&b, e->rb->group, e->rb->parent.expansion_area, e, e->flags.via_conflict_level, NO_CONFLICT + /* value here doesn't matter */ + , targets); + add_or_destroy_edge(&s, ne); + } + } + } + goto dontexpand; + } + /* between the time these edges are inserted and the + * time they are processed, new expansion boxes (which + * conflict with these edges) may be added to the graph! + * w.o vias this isn't a problem because the broken box + * is not homeless. */ + } + if (1) { + routebox_t *nrb; + struct E_result *ans; + rnd_box_t b; + vector_t *broken; + if (e->flags.is_interior) { + assert(AutoRouteParameters.with_conflicts); /* no interior edges unless + routing with conflicts! */ + assert(e->rb->conflicts_with); + b = e->rb->sbox; + switch (e->rb->came_from) { + case RND_NORTH: + b.Y2 = b.Y1 + 1; + b.X1 = RND_BOX_CENTER_X(b); + b.X2 = b.X1 + 1; + break; + case RND_EAST: + b.X1 = b.X2 - 1; + b.Y1 = RND_BOX_CENTER_Y(b); + b.Y2 = b.Y1 + 1; + break; + case RND_SOUTH: + b.Y1 = b.Y2 - 1; + b.X1 = RND_BOX_CENTER_X(b); + b.X2 = b.X1 + 1; + break; + case RND_WEST: + b.X2 = b.X1 + 1; + b.Y1 = RND_BOX_CENTER_Y(b); + b.Y2 = b.Y1 + 1; + break; + default: + assert(0); + } + } + /* sources may not expand to their own edges because of + * adjacent blockers. + */ + else if (e->rb->flags.source) + b = rnd_box_center(&e->rb->sbox); + else + b = e->rb->sbox; + ans = Expand(rd->layergrouptree[e->rb->group], e, &b); + if (!rnd_box_intersect(&ans->inflated, &ans->orig)) + goto dontexpand; +#if 0 + /* skip if it didn't actually expand */ + if (ans->inflated.X1 >= e->rb->sbox.X1 && + ans->inflated.X2 <= e->rb->sbox.X2 && ans->inflated.Y1 >= e->rb->sbox.Y1 && ans->inflated.Y2 <= e->rb->sbox.Y2) + goto dontexpand; +#endif + + if (!rnd_box_is_good(&ans->inflated)) + goto dontexpand; + nrb = CreateExpansionArea(&ans->inflated, e->rb->group, e->rb, rnd_true, e); + rnd_r_insert_entry(rd->layergrouptree[nrb->group], &nrb->box); + vector_append(area_vec, nrb); + nrb->flags.homeless = 0; /* not homeless any more */ + broken = BreakManyEdges(&s, targets, rd->layergrouptree[nrb->group], area_vec, ans, nrb, e); + while (!vector_is_empty(broken)) { + edge_t *ne = (edge_t *) vector_remove_last(broken); + add_or_destroy_edge(&s, ne); + } + vector_destroy(&broken); + + /* add in possible via sites in nrb */ + if (AutoRouteParameters.use_vias && !e->rb->flags.is_via && e->cost + AutoRouteParameters.ViaCost < s.best_cost) + add_via_sites(&s, &vss, rd->mtspace, nrb, NO_CONFLICT, e, targets, 0, rnd_false); + goto dontexpand; + } + dontexpand: + DestroyEdge(&e); + } + touch_conflicts(NULL, 1); + rnd_heap_destroy(&s.workheap); + rnd_r_destroy_tree(&targets); + assert(vector_is_empty(edge_vec)); + vector_destroy(&edge_vec); + + /* we should have a path in best_path now */ + if (s.best_path) { + routebox_t *rb; +#ifdef ROUTE_VERBOSE + printf("%d:%d RC %.0f", ro++, seen, s.best_cost); +#endif + result.found_route = rnd_true; + result.best_route_cost = s.best_cost; + /* determine if the best path had conflicts */ + result.route_had_conflicts = 0; + if (AutoRouteParameters.with_conflicts && s.best_path->conflicts_with) { + while (!vector_is_empty(s.best_path->conflicts_with)) { + rb = (routebox_t *) vector_remove_last(s.best_path->conflicts_with); + rb->flags.is_bad = 1; + result.route_had_conflicts++; + } + } +#ifdef ROUTE_VERBOSE + if (result.route_had_conflicts) + printf(" (%d conflicts)", result.route_had_conflicts); +#endif + if (result.route_had_conflicts < AutoRouteParameters.hi_conflict) { + /* back-trace the path and add lines/vias to r-tree */ + TracePath(rd, s.best_path, s.best_target, from, result.route_had_conflicts); + MergeNets(from, s.best_target, SUBNET); + } + else { +#ifdef ROUTE_VERBOSE + printf(" (too many in fact)"); +#endif + result.found_route = rnd_false; + } +#ifdef ROUTE_VERBOSE + printf("\n"); +#endif + } + else { +#ifdef ROUTE_VERBOSE + printf("%d:%d NO PATH FOUND.\n", ro++, seen); +#endif + result.best_route_cost = s.best_cost; + result.found_route = rnd_false; + } + /* now remove all expansion areas from the r-tree. */ + while (!vector_is_empty(area_vec)) { + routebox_t *rb = (routebox_t *) vector_remove_last(area_vec); + assert(!rb->flags.homeless); + if (rb->conflicts_with && rb->parent.expansion_area->conflicts_with != rb->conflicts_with) + vector_destroy(&rb->conflicts_with); + rnd_r_delete_entry_free_data(rd->layergrouptree[rb->group], &rb->box, free); + } + vector_destroy(&area_vec); + /* clean up; remove all 'source', 'target', and 'nobloat' flags */ + LIST_LOOP(from, same_net, p); + if (p->flags.source && p->conflicts_with) + vector_destroy(&p->conflicts_with); + p->flags.touched = p->flags.source = p->flags.target = p->flags.nobloat = 0; + PCB_END_LOOP; + + vector_destroy(&vss.free_space_vec); + vector_destroy(&vss.lo_conflict_space_vec); + vector_destroy(&vss.hi_conflict_space_vec); + + return result; +} + +static void InitAutoRouteParameters(int pass, pcb_route_style_t * style, rnd_bool with_conflicts, rnd_bool is_smoothing, rnd_bool lastpass) +{ + int i; + /* routing style */ + AutoRouteParameters.style = style; + AutoRouteParameters.bloat = style->Clearance + HALF_THICK(style->Thick); + /* costs */ + AutoRouteParameters.ViaCost = RND_INCH_TO_COORD(3.5) + style->Diameter * (is_smoothing ? 80 : 30); + AutoRouteParameters.LastConflictPenalty = (400 * pass / passes + 2) / (pass + 1); + AutoRouteParameters.ConflictPenalty = 4 * AutoRouteParameters.LastConflictPenalty; + AutoRouteParameters.JogPenalty = 1000 * (is_smoothing ? 20 : 4); + AutoRouteParameters.CongestionPenalty = 1e6; + AutoRouteParameters.MinPenalty = EXPENSIVE; + for (i = 0; i < pcb_max_group(PCB); i++) { + if (is_layer_group_active[i]) { + AutoRouteParameters.MinPenalty = MIN(x_cost[i], AutoRouteParameters.MinPenalty); + AutoRouteParameters.MinPenalty = MIN(y_cost[i], AutoRouteParameters.MinPenalty); + } + } + AutoRouteParameters.NewLayerPenalty = is_smoothing ? 0.5 * EXPENSIVE : 10 * AutoRouteParameters.ViaCost; + /* other */ + AutoRouteParameters.hi_conflict = MAX(8 * (passes - pass + 1), 6); + AutoRouteParameters.is_odd = (pass & 1); + AutoRouteParameters.with_conflicts = with_conflicts; + AutoRouteParameters.is_smoothing = is_smoothing; + AutoRouteParameters.rip_always = is_smoothing; + AutoRouteParameters.last_smooth = 0; /*lastpass; */ + AutoRouteParameters.pass = pass + 1; +} + +#ifndef NDEBUG +rnd_r_dir_t bad_boy(const rnd_box_t * b, void *cl) +{ + routebox_t *box = (routebox_t *) b; + if (box->type == EXPANSION_AREA) + return RND_R_DIR_FOUND_CONTINUE; + return RND_R_DIR_NOT_FOUND; +} + +rnd_bool no_expansion_boxes(routedata_t * rd) +{ + int i; + rnd_box_t big; + big.X1 = 0; + big.X2 = RND_MAX_COORD; + big.Y1 = 0; + big.Y2 = RND_MAX_COORD; + for (i = 0; i < pcb_max_group(PCB); i++) { + if (rnd_r_search(rd->layergrouptree[i], &big, NULL, bad_boy, NULL, NULL)) + return rnd_false; + } + return rnd_true; +} +#endif + +static void ripout_livedraw_obj(routebox_t * rb) +{ + if (rb->type == LINE && rb->livedraw_obj.line) { + pcb_layer_t *layer = pcb_get_layer(PCB->Data, PCB->LayerGroups.grp[rb->group].lid[0]); + pcb_line_invalidate_erase(rb->livedraw_obj.line); + pcb_destroy_object(PCB->Data, PCB_OBJ_LINE, layer, rb->livedraw_obj.line, NULL); + rb->livedraw_obj.line = NULL; + } + + if (rb->type == VIA && rb->livedraw_obj.via) { + pcb_pstk_invalidate_erase(rb->livedraw_obj.via); + pcb_destroy_object(PCB->Data, PCB_OBJ_PSTK, rb->livedraw_obj.via, NULL, NULL); + rb->livedraw_obj.via = NULL; + } +} + +static rnd_r_dir_t ripout_livedraw_obj_cb(const rnd_box_t * b, void *cl) +{ + routebox_t *box = (routebox_t *) b; + ripout_livedraw_obj(box); + return RND_R_DIR_NOT_FOUND; +} + +struct routeall_status { + /* --- for completion rate statistics ---- */ + int total_subnets; + /* total subnets routed without conflicts */ + int routed_subnets; + /* total subnets routed with conflicts */ + int conflict_subnets; + /* net failted entirely */ + int failed; + /* net was ripped */ + int ripped; + int total_nets_routed; +}; + +static double calculate_progress(double this_heap_item, double this_heap_size, struct routeall_status *ras) +{ + double total_passes = passes + smoothes + 1; /* + 1 is the refinement pass */ + double this_pass = AutoRouteParameters.pass - 1; /* Number passes from zero */ + double heap_fraction = (double) (ras->routed_subnets + ras->conflict_subnets + ras->failed) / (double) ras->total_subnets; + double pass_fraction = (this_heap_item + heap_fraction) / this_heap_size; + double process_fraction = (this_pass + pass_fraction) / total_passes; + + return process_fraction; +} + +struct routeall_status RouteAll(routedata_t * rd) +{ + struct routeall_status ras; + routeone_status_t ros; + rnd_bool rip; + int request_cancel; +#ifdef NET_HEAP + rnd_heap_t *net_heap; +#endif + rnd_heap_t *this_pass, *next_pass, *tmp; + routebox_t *net, *p, *pp; + rnd_heap_cost_t total_net_cost, last_cost = 0, this_cost = 0; + int i; + int this_heap_size; + int this_heap_item; + + /* initialize heap for first pass; + * do smallest area first; that makes + * the subsequent costs more representative */ + this_pass = rnd_heap_create(); + next_pass = rnd_heap_create(); +#ifdef NET_HEAP + net_heap = rnd_heap_create(); +#endif + LIST_LOOP(rd->first_net, different_net, net); + { + double area; + rnd_box_t bb = shrink_routebox(net); + LIST_LOOP(net, same_net, p); + { + RND_MAKE_MIN(bb.X1, p->sbox.X1); + RND_MAKE_MIN(bb.Y1, p->sbox.Y1); + RND_MAKE_MAX(bb.X2, p->sbox.X2); + RND_MAKE_MAX(bb.Y2, p->sbox.Y2); + } + PCB_END_LOOP; + area = (double) (bb.X2 - bb.X1) * (bb.Y2 - bb.Y1); + rnd_heap_insert(this_pass, area, net); + } + PCB_END_LOOP; + + ras.total_nets_routed = 0; + /* refinement/finishing passes */ + for (i = 0; i <= passes + smoothes; i++) { +#ifdef ROUTE_VERBOSE + if (i > 0 && i <= passes) + printf("--------- STARTING REFINEMENT PASS %d ------------\n", i); + else if (i > passes) + printf("--------- STARTING SMOOTHING PASS %d -------------\n", i - passes); +#endif + ras.total_subnets = ras.routed_subnets = ras.conflict_subnets = ras.failed = ras.ripped = 0; + assert(rnd_heap_is_empty(next_pass)); + + this_heap_size = rnd_heap_size(this_pass); + for (this_heap_item = 0; !rnd_heap_is_empty(this_pass); this_heap_item++) { +#ifdef ROUTE_DEBUG + if (aabort) + break; +#endif + net = (routebox_t *) rnd_heap_remove_smallest(this_pass); + InitAutoRouteParameters(i, net->style, i < passes, i > passes, i == passes + smoothes); + if (i > 0) { + /* rip up all unfixed traces in this net ? */ + if (AutoRouteParameters.rip_always) + rip = rnd_true; + else { + rip = rnd_false; + LIST_LOOP(net, same_net, p); + if (p->flags.is_bad) { + rip = rnd_true; + break; + } + PCB_END_LOOP; + } + + LIST_LOOP(net, same_net, p); + p->flags.is_bad = 0; + if (!p->flags.fixed) { +#ifndef NDEBUG + rnd_bool del; +#endif + assert(!p->flags.homeless); + if (rip) { + RemoveFromNet(p, NET); + RemoveFromNet(p, SUBNET); + } + if (AutoRouteParameters.use_vias && p->type != VIA_SHADOW && p->type != PLANE) { + mtspace_remove(rd->mtspace, &p->box, p->flags.is_odd ? ODD : EVEN, p->style->Clearance); + if (!rip) + mtspace_add(rd->mtspace, &p->box, p->flags.is_odd ? EVEN : ODD, p->style->Clearance); + } + if (rip) { + if (conf_core.editor.live_routing) + ripout_livedraw_obj(p); +#ifndef NDEBUG + del = +#endif + rnd_r_delete_entry_free_data(rd->layergrouptree[p->group], &p->box, free); +#ifndef NDEBUG + assert(del); +#endif + } + else { + p->flags.is_odd = AutoRouteParameters.is_odd; + } + } + PCB_END_LOOP; + if (conf_core.editor.live_routing) + pcb_draw(); + /* reset to original connectivity */ + if (rip) { + ras.ripped++; + ResetSubnet(net); + } + else { + rnd_heap_insert(next_pass, 0, net); + continue; + } + } + /* count number of subnets */ + FOREACH_SUBNET(net, p); + ras.total_subnets++; + END_FOREACH(net, p); + /* the first subnet doesn't require routing. */ + ras.total_subnets--; + /* and re-route! */ + total_net_cost = 0; + /* only route that which isn't fully routed */ +#ifdef ROUTE_DEBUG + if (ras.total_subnets == 0 || aabort) +#else + if (ras.total_subnets == 0) +#endif + { + rnd_heap_insert(next_pass, 0, net); + continue; + } + + /* the loop here ensures that we get to all subnets even if + * some of them are unreachable from the first subnet. */ + LIST_LOOP(net, same_net, p); + { +#ifdef NET_HEAP + rnd_box_t b = shrink_routebox(p); + /* using a heap allows us to start from smaller objects and + * end at bigger ones. also prefer to start at planes, then pads */ + rnd_heap_insert(net_heap, (float) (b.X2 - b.X1) * +#if defined(ROUTE_RANDOMIZED) + (0.3 + rnd_rand() / (RAND_MAX + 1.0)) * +#endif + (b.Y2 - b.Y1) * (p->type == PLANE ? -1 : ((p->type == TERM) ? 1 : 10)), p); + } + PCB_END_LOOP; + ros.net_completely_routed = 0; + while (!rnd_heap_is_empty(net_heap)) { + p = (routebox_t *) rnd_heap_remove_smallest(net_heap); +#endif + if (!p->flags.fixed || p->flags.subnet_processed || p->type == OTHER) + continue; + + while (!ros.net_completely_routed) { + double percent; + + assert(no_expansion_boxes(rd)); + /* FIX ME: the number of edges to examine should be in autoroute parameters + * i.e. the 2000 and 800 hard-coded below should be controllable by the user + */ + ros = RouteOne(rd, p, NULL, ((AutoRouteParameters.is_smoothing ? 2000 : 800) * (i + 1)) * routing_layers); + total_net_cost += ros.best_route_cost; + if (ros.found_route) { + if (ros.route_had_conflicts) + ras.conflict_subnets++; + else { + ras.routed_subnets++; + ras.total_nets_routed++; + } + } + else { + if (!ros.net_completely_routed) + ras.failed++; + /* don't bother trying any other source in this subnet */ + LIST_LOOP(p, same_subnet, pp); + pp->flags.subnet_processed = 1; + PCB_END_LOOP; + break; + } + /* note that we can infer nothing about ras.total_subnets based + * on the number of calls to RouteOne, because we may be unable + * to route a net from a particular starting point, but perfectly + * able to route it from some other. */ + percent = calculate_progress(this_heap_item, this_heap_size, &ras); + request_cancel = rnd_hid_progress(percent * 100., 100, "Autorouting tracks"); + if (request_cancel) { + ras.total_nets_routed = 0; + ras.conflict_subnets = 0; + rnd_message(RND_MSG_INFO, "Autorouting cancelled\n"); + goto out; + } + } + } +#ifndef NET_HEAP + PCB_END_LOOP; +#endif + if (!ros.net_completely_routed) + net->flags.is_bad = 1; /* don't skip this the next round */ + + /* Route easiest nets from this pass first on next pass. + * This works best because it's likely that the hardest + * is the last one routed (since it has the most obstacles) + * but it will do no good to rip it up and try it again + * without first changing any of the other routes + */ + rnd_heap_insert(next_pass, total_net_cost, net); + if (total_net_cost < EXPENSIVE) + this_cost += total_net_cost; + /* reset subnet_processed flags */ + LIST_LOOP(net, same_net, p); + { + p->flags.subnet_processed = 0; + } + PCB_END_LOOP; + } + /* swap this_pass and next_pass and do it all over again! */ + ro = 0; + assert(rnd_heap_is_empty(this_pass)); + tmp = this_pass; + this_pass = next_pass; + next_pass = tmp; +#if defined(ROUTE_DEBUG) || defined (ROUTE_VERBOSE) + printf + ("END OF PASS %d: %d/%d subnets routed without conflicts at cost %.0f, %d conflicts, %d failed %d ripped\n", + i, ras.routed_subnets, ras.total_subnets, this_cost, ras.conflict_subnets, ras.failed, ras.ripped); +#endif +#ifdef ROUTE_DEBUG + if (aabort) + break; +#endif + /* if no conflicts found, skip directly to smoothing pass! */ + if (ras.conflict_subnets == 0 && ras.routed_subnets == ras.total_subnets && i <= passes) + i = passes - (smoothes ? 0 : 1); + /* if no changes in a smoothing round, then we're done */ + if (this_cost == last_cost && i > passes && i < passes + smoothes) + i = passes + smoothes - 1; + last_cost = this_cost; + this_cost = 0; + } + + rnd_message(RND_MSG_INFO, "%d of %d nets successfully routed.\n", ras.routed_subnets, ras.total_subnets); + +out: + rnd_heap_destroy(&this_pass); + rnd_heap_destroy(&next_pass); +#ifdef NET_HEAP + rnd_heap_destroy(&net_heap); +#endif + + /* no conflicts should be left at the end of the process. */ + assert(ras.conflict_subnets == 0); + + return ras; +} + +struct fpin_info { + pcb_pstk_t *ps; + rnd_coord_t x, y; + jmp_buf env; +}; + +static rnd_r_dir_t fpstk_rect(const rnd_box_t * b, void *cl) +{ + pcb_pstk_t *ps = (pcb_pstk_t *)b; + struct fpin_info *info = (struct fpin_info *) cl; + if (ps->x == info->x && ps->y == info->y) { + info->ps = ps; + longjmp(info->env, 1); + } + return RND_R_DIR_NOT_FOUND; +} + +static int FindPin(const rnd_box_t *box, pcb_pstk_t **ps_out) +{ + struct fpin_info info; + + info.ps = NULL; + info.x = box->X1; + info.y = box->Y1; + if (setjmp(info.env) == 0) { + rnd_r_search(PCB->Data->padstack_tree, box, NULL, fpstk_rect, &info, NULL); + } + else { + *ps_out = info.ps; + return PCB_OBJ_PSTK; + } + + *ps_out = NULL; + return PCB_OBJ_VOID; +} + + +/* paths go on first 'on' layer in group */ +/* returns 'rnd_true' if any paths were added. */ +rnd_bool IronDownAllUnfixedPaths(routedata_t * rd) +{ + rnd_bool changed = rnd_false; + pcb_layer_t *layer; + routebox_t *net, *p; + int i; + LIST_LOOP(rd->first_net, different_net, net); + { + LIST_LOOP(net, same_net, p); + { + if (!p->flags.fixed) { + /* find first on layer in this group */ + assert(PCB->LayerGroups.grp[p->group].len > 0); + assert(is_layer_group_active[p->group]); + for (i = 0, layer = NULL; i < PCB->LayerGroups.grp[p->group].len; i++) { + layer = pcb_get_layer(PCB->Data, PCB->LayerGroups.grp[p->group].lid[i]); + if (layer->meta.real.vis) + break; + } + assert(layer && layer->meta.real.vis); /*at least one layer must be on in this group! */ + assert(p->type != EXPANSION_AREA); + if (p->type == LINE) { + rnd_coord_t halfwidth = HALF_THICK(p->style->Thick); + double th = halfwidth * 2 + 1; + rnd_box_t b; + assert(p->parent.line == NULL); + /* orthogonal; thickness is 2*halfwidth */ + /* flip coordinates, if bl_to_ur */ + b = p->sbox; + total_wire_length += sqrt((b.X2 - b.X1 - th) * (b.X2 - b.X1 - th) + (b.Y2 - b.Y1 - th) * (b.Y2 - b.Y1 - th)); + b = rnd_shrink_box(&b, halfwidth); + if (b.X2 == b.X1 + 1) + b.X2 = b.X1; + if (b.Y2 == b.Y1 + 1) + b.Y2 = b.Y1; + if (p->flags.bl_to_ur) { + rnd_coord_t t; + t = b.X1; + b.X1 = b.X2; + b.X2 = t; + } + /* using CreateDrawn instead of CreateNew concatenates sequential lines */ + p->parent.line = pcb_line_new_merge + (layer, p->line.x1, p->line.y1, p->line.x2, p->line.y2, + p->style->Thick, p->style->Clearance * 2, pcb_flag_make(PCB_FLAG_AUTO | (conf_core.editor.clear_line ? PCB_FLAG_CLEARLINE : 0))); + + if (p->parent.line) { + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, layer, p->parent.line, p->parent.line); + changed = rnd_true; + } + } + else if (p->type == VIA || p->type == VIA_SHADOW) { + routebox_t *pp = (p->type == VIA_SHADOW) ? p->parent.via_shadow : p; + rnd_coord_t radius = HALF_THICK(pp->style->Diameter); + rnd_box_t b = shrink_routebox(p); + total_via_count++; + assert(pp->type == VIA); + if (pp->parent.via == NULL) { + assert(labs((b.X1 + radius) - (b.X2 - radius)) < 2); + assert(labs((b.Y1 + radius) - (b.Y2 - radius)) < 2); +TODO("padstack: when style contains proto, remove this") + pp->parent.via = pcb_pstk_new_compat_via(PCB->Data, -1, + b.X1 + radius, b.Y1 + radius, + pp->style->Hole, pp->style->Diameter, 2 * pp->style->Clearance, 0, PCB_PSTK_COMPAT_ROUND, 1); + assert(pp->parent.via); + PCB_FLAG_SET(PCB_FLAG_AUTO, pp->parent.via); + if (pp->parent.via) { + pcb_undo_add_obj_to_create(PCB_OBJ_PSTK, pp->parent.via, pp->parent.via, pp->parent.via); + changed = rnd_true; + } + } + assert(pp->parent.via); + if (p->type == VIA_SHADOW) { + p->type = VIA; + p->parent.via = pp->parent.via; + } + } + else if (p->type == THERMAL) + /* nothing to do because, the via might not be there yet */ ; + else + assert(0); + } + } + PCB_END_LOOP; + /* loop again to place all the thermals now that the vias are down */ + LIST_LOOP(net, same_net, p); + { + if (p->type == THERMAL) { + pcb_pstk_t *pin = NULL; + /* thermals are alread a single point search, no need to shrink */ + int type = FindPin(&p->box, &pin); + if (pin) { + pcb_undo_add_obj_to_clear_poly(type, pin->parent.data, pin, pin, rnd_false); + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_PSTK, pcb_get_layer(PCB->Data, p->layer), pin); + pcb_undo_add_obj_to_flag(pin); + PCB_FLAG_THERM_ASSIGN(p->layer, autoroute_therm_style, pin); + pcb_undo_add_obj_to_clear_poly(type, pin->parent.data, pin, pin, rnd_true); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_PSTK, pcb_get_layer(PCB->Data, p->layer), pin); + changed = rnd_true; + } + } + } + PCB_END_LOOP; + } + PCB_END_LOOP; + return changed; +} + +rnd_bool AutoRoute(rnd_bool selected) +{ + rnd_bool changed = rnd_false; + routedata_t *rd; + int i; + + total_wire_length = 0; + total_via_count = 0; + +#ifdef ROUTE_DEBUG + ddraw = rnd_gui->request_debug_draw(); + if (ddraw != NULL) { + ar_gc = ddraw->make_gc(); + ddraw->set_line_cap(ar_gc, rnd_cap_round); + } +#endif + + for (i = 0; i < vtroutestyle_len(&PCB->RouteStyle); i++) { + if (PCB->RouteStyle.array[i].Thick == 0 || + PCB->RouteStyle.array[i].Diameter == 0 || PCB->RouteStyle.array[i].Hole == 0 || PCB->RouteStyle.array[i].Clearance == 0) { + rnd_message(RND_MSG_ERROR, "You must define proper routing styles\n" "before auto-routing.\n"); + return rnd_false; + } + } + if (ratlist_length(&PCB->Data->Rat) == 0) + return rnd_false; + rd = CreateRouteData(); + if (rd == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to initialize data; might be missing\n" "top or bottom copper layer.\n"); + return rnd_false; + } + + if (1) { + routebox_t *net, *rb, *last; + int i = 0; + /* count number of rats selected */ + PCB_RAT_LOOP(PCB->Data); + { + if (!selected || PCB_FLAG_TEST(PCB_FLAG_SELECTED, line)) + i++; + } + PCB_END_LOOP; +#ifdef ROUTE_VERBOSE + printf("%d nets!\n", i); +#endif + if (i == 0) + goto donerouting; /* nothing to do here */ + /* if only one rat selected, do things the quick way. =) */ + if (i == 1) { + PCB_RAT_LOOP(PCB->Data); + if (!selected || PCB_FLAG_TEST(PCB_FLAG_SELECTED, line)) { + /* look up the end points of this rat line */ + routebox_t *a; + routebox_t *b; + a = FindRouteBoxOnLayerGroup(rd, line->Point1.X, line->Point1.Y, line->group1); + b = FindRouteBoxOnLayerGroup(rd, line->Point2.X, line->Point2.Y, line->group2); + assert(a != NULL && b != NULL); + assert(a->style == b->style); +/* + if (a->type != PAD && b->type == PAD) + { + routebox_t *t = a; + a = b; + b = t; + } +*/ + /* route exactly one net, without allowing conflicts */ + InitAutoRouteParameters(0, a->style, rnd_false, rnd_true, rnd_true); + /* hace planes work better as sources than targets */ + changed = RouteOne(rd, a, b, 150000).found_route || changed; + goto donerouting; + } + PCB_END_LOOP; + } + /* otherwise, munge the netlists so that only the selected rats + * get connected. */ + /* first, separate all sub nets into separate nets */ + /* note that this code works because LIST_LOOP is clever enough not to + * be fooled when the list is changing out from under it. */ + last = NULL; + LIST_LOOP(rd->first_net, different_net, net); + { + FOREACH_SUBNET(net, rb); + { + if (last) { + last->different_net.next = rb; + rb->different_net.prev = last; + } + last = rb; + } + END_FOREACH(net, rb); + LIST_LOOP(net, same_net, rb); + { + rb->same_net = rb->same_subnet; + } + PCB_END_LOOP; + /* at this point all nets are equal to their subnets */ + } + PCB_END_LOOP; + if (last) { + last->different_net.next = rd->first_net; + rd->first_net->different_net.prev = last; + } + + /* now merge only those subnets connected by a rat line */ + PCB_RAT_LOOP(PCB->Data); + if (!selected || PCB_FLAG_TEST(PCB_FLAG_SELECTED, line)) { + /* look up the end points of this rat line */ + routebox_t *a; + routebox_t *b; + a = FindRouteBoxOnLayerGroup(rd, line->Point1.X, line->Point1.Y, line->group1); + b = FindRouteBoxOnLayerGroup(rd, line->Point2.X, line->Point2.Y, line->group2); + if (!a || !b) { +#ifdef DEBUG_STALE_RATS + pcb_undo_add_obj_to_flag(line); + PCB_FLAG_ASSIGN(PCB_FLAG_SELECTED, rnd_true, line); + pcb_rat_invalidate_draw(line, 0); +#endif /* DEBUG_STALE_RATS */ + rnd_message(RND_MSG_ERROR, "The rats nest is stale! Aborting autoroute...\nNOTE: you need to use the autoroute-specific rats\n the usual rats optimization won't work (check in the menu)!\n"); + goto donerouting; + } + /* merge subnets into a net! */ + MergeNets(a, b, NET); + } + PCB_END_LOOP; + /* now 'different_net' may point to too many different nets. Reset. */ + LIST_LOOP(rd->first_net, different_net, net); + { + if (!net->flags.touched) { + LIST_LOOP(net, same_net, rb); + rb->flags.touched = 1; + PCB_END_LOOP; + } + else /* this is not a "different net"! */ + RemoveFromNet(net, DIFFERENT_NET); + } + PCB_END_LOOP; + /* reset "touched" flag */ + LIST_LOOP(rd->first_net, different_net, net); + { + LIST_LOOP(net, same_net, rb); + { + assert(rb->flags.touched); + rb->flags.touched = 0; + } + PCB_END_LOOP; + } + PCB_END_LOOP; + } + /* okay, rd's idea of netlist now corresponds to what we want routed */ + /* auto-route all nets */ + changed = (RouteAll(rd).total_nets_routed > 0) || changed; +donerouting: + rnd_hid_progress(0, 0, NULL); + if (conf_core.editor.live_routing) { + int i; + rnd_box_t big = { 0, 0, RND_MAX_COORD, RND_MAX_COORD }; + for (i = 0; i < pcb_max_group(PCB); i++) { + rnd_r_search(rd->layergrouptree[i], &big, NULL, ripout_livedraw_obj_cb, NULL, NULL); + } + } +#ifdef ROUTE_DEBUG + if (ddraw != NULL) + ddraw->finish_debug_draw(); +#endif + + if (changed) + changed = IronDownAllUnfixedPaths(rd); + rnd_message(RND_MSG_INFO, "Total added wire length = %$mS, %d vias added\n", (rnd_coord_t) total_wire_length, total_via_count); + DestroyRouteData(&rd); + if (changed) { + pcb_undo_save_serial(); + + /* optimize rats, we've changed connectivity a lot. */ + pcb_rats_destroy(rnd_false /*all rats */ ); + pcb_undo_restore_serial(); + pcb_net_add_all_rats(PCB, PCB_RATACC_ONLY_MANHATTAN); + pcb_undo_restore_serial(); + + pcb_undo_inc_serial(); + + rnd_hid_redraw(PCB); + } +#if defined (ROUTE_DEBUG) + aabort = 0; +#endif + return changed; +} Index: tags/2.3.0/src_plugins/autoroute/autoroute.h =================================================================== --- tags/2.3.0/src_plugins/autoroute/autoroute.h (nonexistent) +++ tags/2.3.0/src_plugins/autoroute/autoroute.h (revision 33253) @@ -0,0 +1,46 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1998,1999,2000,2001 harry eaton + * + * this file, autoroute.h, was written and is + * Copyright (c) 2001 C. Scott Ananian. + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#ifndef PCB_AUTOROUTE_H +#define PCB_AUTOROUTE_H + +#include "config.h" +#include "board.h" + +rnd_bool AutoRoute(rnd_bool); + +#endif Index: tags/2.3.0/src_plugins/autoroute/autoroute.pup =================================================================== --- tags/2.3.0/src_plugins/autoroute/autoroute.pup (nonexistent) +++ tags/2.3.0/src_plugins/autoroute/autoroute.pup (revision 33253) @@ -0,0 +1,8 @@ +$class feature +$short the original autorouter +$long Automatically route selected or all rats. This is the original autorouter. +$package auto +$state works +default buildin +dep lib_compat_help +autoload 1 Index: tags/2.3.0/src_plugins/autoroute/mtspace.c =================================================================== --- tags/2.3.0/src_plugins/autoroute/mtspace.c (nonexistent) +++ tags/2.3.0/src_plugins/autoroute/mtspace.c (revision 33253) @@ -0,0 +1,527 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1998,1999,2000,2001 harry eaton + * + * this file, mtspace.c, was written and is + * Copyright (c) 2001 C. Scott Ananian. + * Copyright (c) 2006 harry eaton. + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA + * haceaton@aplcomm.jhuapl.edu + * + */ + + +/* implementation for "empty space" routines (needed for via-space tracking + * in the auto-router. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include "box_dir.h" +#include "mtspace.h" +#include "vector.h" +#include + +/* mtspace data structures are built on r-trees. */ + +typedef struct mtspacebox { + const rnd_box_t box; + rnd_coord_t clearance; /* the smallest clearance around this box */ +} mtspacebox_t; + +/* this is an mtspace_t */ +struct mtspace { + /* rtrees keeping track of regions expanded by their required clearance. */ + /* one for fixed, even, and odd */ + rnd_rtree_t *ftree, *etree, *otree; +}; + +typedef union { + vector_t *v; + rnd_heap_t *h; +} heap_or_vector; + +/* this is a vetting_t */ +struct vetting { + heap_or_vector untested; + heap_or_vector no_fix; + heap_or_vector no_hi; + heap_or_vector hi_candidate; + rnd_coord_t radius; + rnd_coord_t clearance; + rnd_cheap_point_t desired; +}; + +#define SPECIAL 823157 + +mtspacebox_t *mtspace_create_box(const rnd_box_t * box, rnd_coord_t clearance) +{ + mtspacebox_t *mtsb; + assert(rnd_box_is_good(box)); + mtsb = (mtspacebox_t *) malloc(sizeof(*mtsb)); + /* the box was sent to us pre-bloated by the clearance amount */ + *((rnd_box_t *) & mtsb->box) = *box; + mtsb->clearance = clearance; + assert(rnd_box_is_good(&mtsb->box)); + return mtsb; +} + +/* create an "empty space" representation */ +mtspace_t *mtspace_create(void) +{ + mtspace_t *mtspace; + + /* create mtspace data structure */ + mtspace = (mtspace_t *) malloc(sizeof(*mtspace)); + mtspace->ftree = rnd_r_create_tree(); + mtspace->etree = rnd_r_create_tree(); + mtspace->otree = rnd_r_create_tree(); + /* done! */ + return mtspace; +} + +/* destroy an "empty space" representation. */ +void mtspace_destroy(mtspace_t ** mtspacep) +{ + assert(mtspacep); + rnd_r_free_tree_data((*mtspacep)->ftree, free); + rnd_r_free_tree_data((*mtspacep)->etree, free); + rnd_r_free_tree_data((*mtspacep)->otree, free); + rnd_r_destroy_tree(&(*mtspacep)->ftree); + rnd_r_destroy_tree(&(*mtspacep)->etree); + rnd_r_destroy_tree(&(*mtspacep)->otree); + free(*mtspacep); + *mtspacep = NULL; +} + +struct mts_info { + rnd_coord_t clearance; + rnd_box_t box; + rnd_rtree_t *tree; + jmp_buf env; +}; + +static rnd_r_dir_t mts_remove_one(const rnd_box_t * b, void *cl) +{ + struct mts_info *info = (struct mts_info *) cl; + mtspacebox_t *box = (mtspacebox_t *) b; + + /* there can be duplicate boxes, we just remove one */ + /* the info box is pre-bloated, so just check equality */ + if (b->X1 == info->box.X1 && b->X2 == info->box.X2 && + b->Y1 == info->box.Y1 && b->Y2 == info->box.Y2 && box->clearance == info->clearance) { + rnd_r_delete_entry_free_data(info->tree, (rnd_box_t *)b, free); + longjmp(info->env, 1); + } + return RND_R_DIR_NOT_FOUND; +} + +rnd_rtree_t *which_tree(mtspace_t * mtspace, mtspace_type_t which) +{ + switch (which) { + case FIXED: + return mtspace->ftree; + case EVEN: + return mtspace->etree; + default: + return mtspace->otree; + } +} + +/* add a space-filler to the empty space representation. */ +void mtspace_add(mtspace_t * mtspace, const rnd_box_t * box, mtspace_type_t which, rnd_coord_t clearance) +{ + mtspacebox_t *filler = mtspace_create_box(box, clearance); + rnd_r_insert_entry(which_tree(mtspace, which), (const rnd_box_t *) filler); +} + +/* remove a space-filler from the empty space representation. */ +void mtspace_remove(mtspace_t * mtspace, const rnd_box_t * box, mtspace_type_t which, rnd_coord_t clearance) +{ + struct mts_info cl; + rnd_box_t small_search; + + cl.clearance = clearance; + cl.box = *box; + cl.tree = which_tree(mtspace, which); + small_search = rnd_box_center(box); + if (setjmp(cl.env) == 0) { + rnd_r_search(cl.tree, &small_search, NULL, mts_remove_one, &cl, NULL); + assert(0); /* didn't find it?? */ + } +} + +struct query_closure { + rnd_box_t *cbox; + heap_or_vector checking; + heap_or_vector touching; + rnd_cheap_point_t *desired; + rnd_coord_t radius, clearance; + jmp_buf env; + rnd_bool touch_is_vec; +}; + +static inline void heap_append(rnd_heap_t * heap, rnd_cheap_point_t * desired, rnd_box_t * newone) +{ + rnd_cheap_point_t p = *desired; + assert(desired); + rnd_closest_cheap_point_in_box(&p, newone); + rnd_heap_insert(heap, RND_ABS(p.X - desired->X) + (p.Y - desired->Y), newone); +} + +static inline void append(struct query_closure *qc, rnd_box_t * newone) +{ + if (qc->desired) + heap_append(qc->checking.h, qc->desired, newone); + else + vector_append(qc->checking.v, newone); +} + +/* we found some space filler that may intersect this query. + * First check if it does intersect, then break it into + * overlaping regions that don't intersect this box. + */ +static rnd_r_dir_t query_one(const rnd_box_t * box, void *cl) +{ + struct query_closure *qc = (struct query_closure *) cl; + mtspacebox_t *mtsb = (mtspacebox_t *) box; + rnd_coord_t shrink; + +#ifndef NDEBUG + { + /* work around rounding errors: grow both boxes by 2 nm */ + rnd_box_t b1 = *qc->cbox, b2 = mtsb->box; + b1.X1--;b1.Y1--;b1.X2++;b1.Y2++; + b2.X1--;b2.Y1--;b2.X2++;b2.Y2++; + assert(rnd_box_intersect(&b1, &b2)); + } +#endif + + /* we need to satisfy the larger of the two clearances */ + if (qc->clearance > mtsb->clearance) + shrink = mtsb->clearance; + else + shrink = qc->clearance; + /* if we shrink qc->box by this amount and it doesn't intersect + * then we didn't actually touch this box */ + if (qc->cbox->X1 + shrink >= mtsb->box.X2 || + qc->cbox->X2 - shrink <= mtsb->box.X1 || qc->cbox->Y1 + shrink >= mtsb->box.Y2 || qc->cbox->Y2 - shrink <= mtsb->box.Y1) + return RND_R_DIR_NOT_FOUND; + /* ok, we do touch this box, now create up to 4 boxes that don't */ + if (mtsb->box.Y1 > qc->cbox->Y1 + shrink) { /* top region exists */ + rnd_coord_t Y1 = qc->cbox->Y1; + rnd_coord_t Y2 = mtsb->box.Y1 + shrink; + if (Y2 - Y1 >= 2 * (qc->radius + qc->clearance)) { + rnd_box_t *newone = (rnd_box_t *) malloc(sizeof(rnd_box_t)); + newone->X1 = qc->cbox->X1; + newone->X2 = qc->cbox->X2; + newone->Y1 = Y1; + newone->Y2 = Y2; + assert(newone->Y2 < qc->cbox->Y2); + append(qc, newone); + } + } + if (mtsb->box.Y2 < qc->cbox->Y2 - shrink) { /* bottom region exists */ + rnd_coord_t Y1 = mtsb->box.Y2 - shrink; + rnd_coord_t Y2 = qc->cbox->Y2; + if (Y2 - Y1 >= 2 * (qc->radius + qc->clearance)) { + rnd_box_t *newone = (rnd_box_t *) malloc(sizeof(rnd_box_t)); + newone->X1 = qc->cbox->X1; + newone->X2 = qc->cbox->X2; + newone->Y2 = qc->cbox->Y2; + newone->Y1 = Y1; + assert(newone->Y1 > qc->cbox->Y1); + append(qc, newone); + } + } + if (mtsb->box.X1 > qc->cbox->X1 + shrink) { /* left region exists */ + rnd_coord_t X1 = qc->cbox->X1; + rnd_coord_t X2 = mtsb->box.X1 + shrink; + if (X2 - X1 >= 2 * (qc->radius + qc->clearance)) { + rnd_box_t *newone; + newone = (rnd_box_t *) malloc(sizeof(rnd_box_t)); + newone->Y1 = qc->cbox->Y1; + newone->Y2 = qc->cbox->Y2; + newone->X1 = qc->cbox->X1; + newone->X2 = X2; + assert(newone->X2 < qc->cbox->X2); + append(qc, newone); + } + } + if (mtsb->box.X2 < qc->cbox->X2 - shrink) { /* right region exists */ + rnd_coord_t X1 = mtsb->box.X2 - shrink; + rnd_coord_t X2 = qc->cbox->X2; + if (X2 - X1 >= 2 * (qc->radius + qc->clearance)) { + rnd_box_t *newone = (rnd_box_t *) malloc(sizeof(rnd_box_t)); + newone->Y1 = qc->cbox->Y1; + newone->Y2 = qc->cbox->Y2; + newone->X2 = qc->cbox->X2; + newone->X1 = X1; + assert(newone->X1 > qc->cbox->X1); + append(qc, newone); + } + } + if (qc->touching.v) { + if (qc->touch_is_vec || !qc->desired) + vector_append(qc->touching.v, qc->cbox); + else + heap_append(qc->touching.h, qc->desired, qc->cbox); + } + else + free(qc->cbox); /* done with this one */ + longjmp(qc->env, 1); + return RND_R_DIR_FOUND_CONTINUE; /* never reached */ +} + +/* qloop takes a vector (or heap) of regions to check (checking) if they don't intersect + * anything. If a region does intersect something, it is broken into + * pieces that don't intersect that thing (if possible) which are + * put back into the vector/heap of regions to check. + * qloop returns rnd_false when it finds the first empty region + * it returns rnd_true if it has exhausted the region vector/heap and never + * found an empty area. + */ +static void qloop(struct query_closure *qc, rnd_rtree_t * tree, heap_or_vector res, rnd_bool is_vec) +{ + rnd_box_t *cbox; + int n; + + while (!(qc->desired ? rnd_heap_is_empty(qc->checking.h) : vector_is_empty(qc->checking.v))) { + cbox = qc->desired ? (rnd_box_t *) rnd_heap_remove_smallest(qc->checking.h) : (rnd_box_t *) vector_remove_last(qc->checking.v); + if (setjmp(qc->env) == 0) { + assert(rnd_box_is_good(cbox)); + qc->cbox = cbox; + rnd_r_search(tree, cbox, NULL, query_one, qc, &n); + assert(n == 0); + /* nothing intersected with this tree, put it in the result vector */ + if (is_vec) + vector_append(res.v, cbox); + else { + if (qc->desired) + heap_append(res.h, qc->desired, cbox); + else + vector_append(res.v, cbox); + } + return; /* found one - perhaps one answer is good enough */ + } + } +} + +/* free the memory used by the vetting structure */ +void mtsFreeWork(vetting_t ** w) +{ + vetting_t *work = (*w); + if (work->desired.X != -SPECIAL || work->desired.Y != -SPECIAL) { + rnd_heap_free(work->untested.h, free); + rnd_heap_destroy(&work->untested.h); + rnd_heap_free(work->no_fix.h, free); + rnd_heap_destroy(&work->no_fix.h); + rnd_heap_free(work->no_hi.h, free); + rnd_heap_destroy(&work->no_hi.h); + rnd_heap_free(work->hi_candidate.h, free); + rnd_heap_destroy(&work->hi_candidate.h); + } + else { + while (!vector_is_empty(work->untested.v)) + free(vector_remove_last(work->untested.v)); + vector_destroy(&work->untested.v); + while (!vector_is_empty(work->no_fix.v)) + free(vector_remove_last(work->no_fix.v)); + vector_destroy(&work->no_fix.v); + while (!vector_is_empty(work->no_hi.v)) + free(vector_remove_last(work->no_hi.v)); + vector_destroy(&work->no_hi.v); + while (!vector_is_empty(work->hi_candidate.v)) + free(vector_remove_last(work->hi_candidate.v)); + vector_destroy(&work->hi_candidate.v); + } + free(work); + (*w) = NULL; +} + + +/* returns some empty spaces in 'region' (or former narrowed regions) + * that may hold a feature with the specified radius and clearance + * It tries first to find Completely empty regions (which are appended + * to the free_space_vec vector). If that fails, it looks for regions + * filled only by objects generated by the previous pass (which are + * appended to the lo_conflict_space_vec vector). Then it looks for + * regions that are filled by objects generated during *this* pass + * (which are appended to the hi_conflict_space_vec vector). The + * current pass identity is given by 'is_odd'. As soon as one completely + * free region is found, it returns with that answer. It saves partially + * searched regions in vectors "untested", "no_fix", "no_hi", and + * "hi_candidate" which can be passed to future calls of this function + * to search harder for such regions if the computation becomes + * necessary. + */ +vetting_t *mtspace_query_rect(mtspace_t * mtspace, const rnd_box_t * region, + rnd_coord_t radius, rnd_coord_t clearance, + vetting_t * work, + vector_t * free_space_vec, + vector_t * lo_conflict_space_vec, + vector_t * hi_conflict_space_vec, rnd_bool is_odd, rnd_bool with_conflicts, rnd_cheap_point_t * desired) +{ + struct query_closure qc; + + /* pre-assertions */ + assert(free_space_vec); + assert(lo_conflict_space_vec); + assert(hi_conflict_space_vec); + /* search out to anything that might matter */ + if (region) { + rnd_box_t *cbox; + assert(work == NULL); + assert(rnd_box_is_good(region)); + assert(vector_is_empty(free_space_vec)); + assert(vector_is_empty(lo_conflict_space_vec)); + assert(vector_is_empty(hi_conflict_space_vec)); + work = (vetting_t *) malloc(sizeof(vetting_t)); + work->clearance = clearance; + work->radius = radius; + cbox = (rnd_box_t *) malloc(sizeof(rnd_box_t)); + *cbox = rnd_bloat_box(region, clearance + radius); + if (desired) { + work->untested.h = rnd_heap_create(); + work->no_fix.h = rnd_heap_create(); + work->hi_candidate.h = rnd_heap_create(); + work->no_hi.h = rnd_heap_create(); + assert(work->untested.h && work->no_fix.h && work->no_hi.h && work->hi_candidate.h); + rnd_heap_insert(work->untested.h, 0, cbox); + work->desired = *desired; + } + else { + work->untested.v = vector_create(); + work->no_fix.v = vector_create(); + work->hi_candidate.v = vector_create(); + work->no_hi.v = vector_create(); + assert(work->untested.v && work->no_fix.v && work->no_hi.v && work->hi_candidate.v); + vector_append(work->untested.v, cbox); + work->desired.X = work->desired.Y = -SPECIAL; + } + return work; + } + qc.clearance = work->clearance; + qc.radius = work->radius; + if (work->desired.X == -SPECIAL && work->desired.Y == -SPECIAL) + qc.desired = NULL; + else + qc.desired = &work->desired; + /* do the query */ + do { + heap_or_vector temporary; + temporary.v = free_space_vec; + + /* search the fixed object tree discarding any intersections + * and placing empty regions in the no_fix vector. + */ + qc.checking = work->untested; + qc.touching.v = NULL; + qloop(&qc, mtspace->ftree, work->no_fix, rnd_false); + /* search the hi-conflict tree placing intersectors in the + * hi_candidate vector (if conflicts are allowed) and + * placing empty regions in the no_hi vector. + */ + qc.checking.v = work->no_fix.v; + qc.touching.v = with_conflicts ? work->hi_candidate.v : NULL; + qc.touch_is_vec = rnd_false; + qloop(&qc, is_odd ? mtspace->otree : mtspace->etree, work->no_hi, rnd_false); + /* search the lo-conflict tree placing intersectors in the + * lo-conflict answer vector (if conflicts allowed) and + * placing emptry regions in the free-space answer vector. + */ + qc.checking = work->no_hi; +/* XXX lo_conflict_space_vec will be treated like a heap! */ + qc.touching.v = (with_conflicts ? lo_conflict_space_vec : NULL); + qc.touch_is_vec = rnd_true; + qloop(&qc, is_odd ? mtspace->etree : mtspace->otree, temporary, rnd_true); + + /* qloop (&qc, is_odd ? mtspace->etree : mtspace->otree, (heap_or_vector)free_space_vec, rnd_true); */ + if (!vector_is_empty(free_space_vec)) { + if (qc.desired) { + if (rnd_heap_is_empty(work->untested.h)) + break; + } + else { + if (vector_is_empty(work->untested.v)) + break; + } + return work; + } + /* finally check the hi-conflict intersectors against the + * lo-conflict tree discarding intersectors (two types of conflict is real bad) + * and placing empty regions in the hi-conflict answer vector. + */ + if (with_conflicts) { + heap_or_vector temporary; + temporary.v = hi_conflict_space_vec; + + qc.checking = work->hi_candidate; + qc.touching.v = NULL; + qloop(&qc, is_odd ? mtspace->etree : mtspace->otree, temporary, rnd_true); + + /* qloop (&qc, is_odd ? mtspace->etree : mtspace->otree, */ + /* (heap_or_vector)hi_conflict_space_vec, rnd_true); */ + } + } + while (!(qc.desired ? rnd_heap_is_empty(work->untested.h) : vector_is_empty(work->untested.v))); + if (qc.desired) { + if (rnd_heap_is_empty(work->no_fix.h) && rnd_heap_is_empty(work->no_hi.h) && rnd_heap_is_empty(work->hi_candidate.h)) { + mtsFreeWork(&work); + return NULL; + } + } + else { + if (vector_is_empty(work->no_fix.v) && vector_is_empty(work->no_hi.v) && vector_is_empty(work->hi_candidate.v)) { + mtsFreeWork(&work); + return NULL; + } + } + return work; +} + +int mtsBoxCount(vetting_t * w) +{ +#if 0 + int ans; + ans = 3 * vector_size(w->untested); + ans += 2 * vector_size(w->no_fix); + ans += vector_size(w->no_hi); + ans += vector_size(w->hi_candidate); + return ans; +#endif + return 100; +} Index: tags/2.3.0/src_plugins/autoroute/mtspace.h =================================================================== --- tags/2.3.0/src_plugins/autoroute/mtspace.h (nonexistent) +++ tags/2.3.0/src_plugins/autoroute/mtspace.h (revision 33253) @@ -0,0 +1,81 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1998,1999,2000,2001 harry eaton + * + * this file, mtspace.h, was written and is + * Copyright (c) 2001 C. Scott Ananian. + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +/* "empty space" routines (needed for via-space tracking in the auto-router. */ + +#ifndef PCB_MTSPACE_H +#define PCB_MTSPACE_H + +/* mtspace data structures are built on r-trees. */ + +#include "config.h" +#include "vector.h" /* for vector_t in mtspace_query_rect prototype */ + +typedef struct mtspace mtspace_t; +typedef enum { FIXED, ODD, EVEN } mtspace_type_t; +typedef struct vetting vetting_t; + +/* create an "empty space" representation with a shrunken boundary */ +mtspace_t *mtspace_create(void); +/* destroy an "empty space" representation. */ +void mtspace_destroy(mtspace_t ** mtspacep); + +/* -- mutation -- */ + +/* add a space-filler to the empty space representation. The given box + * should *not* be bloated; it should be "true". The feature will fill + * *at least* a radius of clearance around it; + */ +void mtspace_add(mtspace_t * mtspace, const rnd_box_t * box, mtspace_type_t which, rnd_coord_t clearance); +/* remove a space-filler from the empty space representation. The given box + * should *not* be bloated; it should be "true". The feature will fill + * *at least* a radius of clearance around it; + */ +void mtspace_remove(mtspace_t * mtspace, const rnd_box_t * box, mtspace_type_t which, rnd_coord_t clearance); + + +vetting_t *mtspace_query_rect(mtspace_t * mtspace, const rnd_box_t * region, + rnd_coord_t radius, rnd_coord_t clearance, + vetting_t * work, + vector_t * free_space_vec, + vector_t * lo_conflict_space_vec, + vector_t * hi_conflict_space_vec, rnd_bool is_odd, rnd_bool with_conflicts, rnd_cheap_point_t * desired); + +void mtsFreeWork(vetting_t **); +int mtsBoxCount(vetting_t *); + +#endif /* ! PCB_MTSPACE_H */ Index: tags/2.3.0/src_plugins/autoroute/vector.c =================================================================== --- tags/2.3.0/src_plugins/autoroute/vector.c (nonexistent) +++ tags/2.3.0/src_plugins/autoroute/vector.c (revision 33253) @@ -0,0 +1,205 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1998,1999,2000,2001 harry eaton + * + * this file, vector.c, was written and is + * Copyright (c) 2001 C. Scott Ananian. + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +/* operations on vectors. */ + +#include "config.h" + +#include +#include +#include + +#include +#include "vector.h" + +struct vector_struct { + vector_element_t *element; + int size, max; +}; + +/* helper function for assertions */ +#ifndef NDEBUG +static int __vector_is_good(vector_t * vector) +{ + return vector && (vector->max == 0 || vector->element) && + (vector->max >= 0) && (vector->size >= 0) && (vector->size <= vector->max) && 1; +} +#endif /* !NDEBUG */ + +/* create an empty vector */ +vector_t *vector_create() +{ + vector_t *vector; + /* okay, create empty vector */ + vector = (vector_t *) calloc(1, sizeof(*vector)); + assert(vector); + assert(__vector_is_good(vector)); + return vector; +} + +/* destroy a vector */ +void vector_destroy(vector_t ** vector) +{ + assert(vector && *vector); + assert(__vector_is_good(*vector)); + if ((*vector)->element) + free((*vector)->element); + free(*vector); + *vector = NULL; +} + +/* -- interrogation -- */ +int vector_is_empty(vector_t * vector) +{ + assert(__vector_is_good(vector)); + return (vector->size == 0); +} + +int vector_size(vector_t * vector) +{ + assert(__vector_is_good(vector)); + return (vector->size); +} + +vector_element_t vector_element(vector_t * vector, int N) +{ + assert(__vector_is_good(vector)); + assert(N < vector->size); + return vector->element[N]; +} + +/* return the first element of the vector. */ +vector_element_t vector_element_first(vector_t * vector) +{ + assert(__vector_is_good(vector)); + assert(vector->size > 0); + return vector_element(vector, 0); +} + +/* return the last element of the vector. */ +vector_element_t vector_element_last(vector_t * vector) +{ + assert(__vector_is_good(vector)); + assert(vector->size > 0); + return vector_element(vector, vector->size - 1); +} + +/* -- mutation -- */ +/* add data to end of vector */ +void vector_append(vector_t * vector, vector_element_t data) +{ + vector_insert_many(vector, vector->size, &data, 1); +} + +void vector_append_many(vector_t * vector, vector_element_t data[], int count) +{ + vector_insert_many(vector, vector->size, data, count); +} + +void vector_append_vector(vector_t * vector, vector_t * other_vector) +{ + vector_append_many(vector, other_vector->element, other_vector->size); +} + +void vector_insert(vector_t * vector, int N, vector_element_t data) +{ + vector_insert_many(vector, N, &data, 1); +} + +/* add data at specified position of vector */ +void vector_insert_many(vector_t * vector, int N, vector_element_t data[], int count) +{ + assert(__vector_is_good(vector)); + assert(N <= vector->size); + if (count == 0) + return; + assert(data && count > 0); + if (vector->size + count > vector->max) { + vector->max = MAX(32, MAX(vector->size + count, vector->max * 2)); + vector->element = (void **) realloc(vector->element, vector->max * sizeof(*vector->element)); + } + memmove(vector->element + N + count, vector->element + N, (vector->size - N) * sizeof(*vector->element)); + memmove(vector->element + N, data, count * sizeof(*data)); + vector->size += count; + assert(__vector_is_good(vector)); +} + +vector_t *vector_duplicate(vector_t * orig) +{ + vector_t *newone = vector_create(); + if (!orig) + return newone; + newone->element = (void **) malloc(orig->max * sizeof(*orig->element)); + newone->max = orig->max; + newone->size = orig->size; + memcpy(newone->element, orig->element, orig->size * sizeof(vector_element_t)); + assert(__vector_is_good(newone)); + return newone; +} + +/* return and delete the *last* element of vector */ +vector_element_t vector_remove_last(vector_t * vector) +{ + assert(vector->size > 0); + return vector_remove(vector, vector->size - 1); +} + +/* return and delete data at specified position of vector */ +vector_element_t vector_remove(vector_t * vector, int N) +{ + vector_element_t old; + assert(__vector_is_good(vector)); + assert(N < vector->size); + old = vector->element[N]; + memmove(vector->element + N, vector->element + N + 1, (vector->size - (N + 1)) * sizeof(*vector->element)); + vector->size--; + assert(__vector_is_good(vector)); + return old; +} + +/* replace the data at the specified position with the given data. + * returns the old data. */ +vector_element_t vector_replace(vector_t * vector, vector_element_t data, int N) +{ + vector_element_t old; + assert(__vector_is_good(vector)); + assert(N < vector->size); + old = vector->element[N]; + vector->element[N] = data; + assert(__vector_is_good(vector)); + return old; +} Index: tags/2.3.0/src_plugins/autoroute/vector.h =================================================================== --- tags/2.3.0/src_plugins/autoroute/vector.h (nonexistent) +++ tags/2.3.0/src_plugins/autoroute/vector.h (revision 33253) @@ -0,0 +1,79 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1998,1999,2000,2001 harry eaton + * + * this file, vector.h, was written and is + * Copyright (c) 2001 C. Scott Ananian. + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#ifndef PCB_VECTOR_H +#define PCB_VECTOR_H + +/* what a vector looks like */ +typedef struct vector_struct vector_t; +/* what data in a vector looks like */ +typedef void *vector_element_t; + +/* create an empty vector */ +vector_t *vector_create(); +/* destroy a vector */ +void vector_destroy(vector_t ** vector); +/* copy a vector */ +vector_t *vector_duplicate(vector_t * vector); + +/* -- interrogation -- */ +int vector_is_empty(vector_t * vector); +int vector_size(vector_t * vector); +vector_element_t vector_element(vector_t * vector, int N); +vector_element_t vector_element_first(vector_t * vector); +vector_element_t vector_element_last(vector_t * vector); + +/* -- mutation -- */ +/* add data to end of vector */ +void vector_append(vector_t * vector, vector_element_t data); +/* add multiple elements to end of vector */ +void vector_append_many(vector_t * vector, vector_element_t data[], int count); +/* add a vector of elements to the end of vector */ +void vector_append_vector(vector_t * vector, vector_t * other_vector); +/* add data at specified position of vector */ +void vector_insert(vector_t * vector, int N, vector_element_t data); +/* add multiple elements at specified position of vector */ +void vector_insert_many(vector_t * vector, int N, vector_element_t data[], int count); +/* return and delete the *last* element of vector */ +vector_element_t vector_remove_last(vector_t * vector); +/* return and delete data at specified position of vector */ +vector_element_t vector_remove(vector_t * vector, int N); +/* replace the data at the specified position with the given data. + * returns the old data. */ +vector_element_t vector_replace(vector_t * vector, vector_element_t data, int N); + +#endif /* PCB_VECTOR_H */ Index: tags/2.3.0/src_plugins/cam/Makefile =================================================================== --- tags/2.3.0/src_plugins/cam/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/cam/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_cam + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/cam/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/cam/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/cam/Plug.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +put /local/pcb/mod {cam} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/cam/cam.o @] +put /local/pcb/mod/CONF {$(PLUGDIR)/cam/cam_conf.h} +put /local/pcb/mod/CONFFILE {cam.conf} +put /local/pcb/mod/CONFVAR {cam_conf_internal} + +switch /local/pcb/cam/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end + Index: tags/2.3.0/src_plugins/cam/cam.c =================================================================== --- tags/2.3.0/src_plugins/cam/cam.c (nonexistent) +++ tags/2.3.0/src_plugins/cam/cam.c (revision 33253) @@ -0,0 +1,322 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * cam export jobs plugin + * pcb-rnd Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "hid_cam.h" +#include +#include +#include +#include +#include +#include "cam_conf.h" +#include +#include +#include "../src_plugins/cam/conf_internal.c" + +static const char *cam_cookie = "cam exporter"; + +conf_cam_t conf_cam; +#define CAM_CONF_FN "cam.conf" + +#include "cam_compile.c" + +static void cam_init_inst_fn(cam_ctx_t *ctx) +{ + if ((PCB != NULL) && (PCB->hidlib.filename != NULL)) { + char *fn = pcb_derive_default_filename_(PCB->hidlib.filename, ""); + char *val, *end = strrchr(fn, RND_DIR_SEPARATOR_C); + if (end != NULL) + val = rnd_strdup(end+1); + else + val = rnd_strdup(fn); + pcb_cam_set_var(ctx->vars, rnd_strdup("base"), val); + free(fn); + } +} + +static void cam_init_inst(cam_ctx_t *ctx) +{ + memset(ctx, 0, sizeof(cam_ctx_t)); + + ctx->vars = pcb_cam_vars_alloc(); + cam_init_inst_fn(ctx); +} + +static void cam_uninit_inst(cam_ctx_t *ctx) +{ + pcb_cam_vars_free(ctx->vars); + cam_free_code(ctx); + free(ctx->prefix); + free(ctx->args); + gds_uninit(&ctx->tmp); +} + +/* look up a job by name in the config */ +static const char *cam_find_job(const char *job) +{ + rnd_conf_listitem_t *j; + int idx; + + rnd_conf_loop_list(&conf_cam.plugins.cam.jobs, j, idx) + if (strcmp(j->name, job) == 0) + return j->payload; + + return NULL; +} + +/* execute the instructions of a job specified by name */ +static int cam_call(const char *job, cam_ctx_t *ctx) +{ + const char *script = cam_find_job(job); + + if (script != NULL) { + if (cam_compile(ctx, script) != 0) + return -1; + return cam_exec(ctx); + } + + rnd_message(RND_MSG_ERROR, "cam: can not find job configuration '%s'\n", job); + return -1; +} + +static int cam_parse_opt_outfile(cam_ctx_t *ctx, const char *optval, rnd_bool nomkdir) +{ + char *fn, *tmp = rnd_strdup(optval); + int dirlen = prefix_mkdir(tmp, &fn, nomkdir); + + free(ctx->prefix); + if (dirlen > 0) { + ctx->prefix = malloc(dirlen+2); + memcpy(ctx->prefix, optval, dirlen); + ctx->prefix[dirlen] = RND_DIR_SEPARATOR_C; + ctx->prefix[dirlen+1] = '\0'; + } + else + ctx->prefix = NULL; + pcb_cam_set_var(ctx->vars, rnd_strdup("base"), rnd_strdup(fn)); + free(tmp); + return 0; +} + +static int cam_parse_set_var(cam_ctx_t *ctx, const char *opt) +{ + char *key, *val, *sep = strchr(opt, '='); + + if (sep == NULL) + return 1; + + key = rnd_strndup(opt, sep-opt); + val = rnd_strdup(sep+1); + pcb_cam_set_var(ctx->vars, key, val); + return 0; +} + +static int cam_parse_opt(cam_ctx_t *ctx, const char *opt) +{ + if (strncmp(opt, "outfile=", 8) == 0) + return cam_parse_opt_outfile(ctx, opt+8, 0); + else + return cam_parse_set_var(ctx, opt); + + return 1; +} + +#include "cam_gui.c" + +static const char pcb_acts_cam[] = "cam(exec, script, [options])\ncam(call, jobname, [options])\ncam([gui])"; +static const char pcb_acth_cam[] = "Export jobs for feeding cam processes"; +static fgw_error_t pcb_act_cam(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + cam_ctx_t ctx; + const char *cmd = "gui", *arg = NULL, *opt; + int n, rs = -1; + + RND_ACT_MAY_CONVARG(1, FGW_STR, cam, cmd = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, cam, arg = argv[2].val.str); + + cam_init_inst(&ctx); + for(n = 3; n < argc; n++) { + RND_ACT_CONVARG(n, FGW_STR, cam, opt = argv[n].val.str); + if (cam_parse_opt(&ctx, opt) != 0) { + rnd_message(RND_MSG_ERROR, "cam: invalid action option '%s'\n", opt); + cam_uninit_inst(&ctx); + RND_ACT_IRES(1); + return 0; + } + } + + if (rnd_strcasecmp(cmd, "gui") == 0) { + rs = cam_gui(RND_ACT_HIDLIB, arg); + } + else { + if (arg == NULL) { + rnd_message(RND_MSG_ERROR, "cam: need one more argument for '%s'\n", cmd); + cam_uninit_inst(&ctx); + RND_ACT_IRES(1); + return 0; + } + if (rnd_strcasecmp(cmd, "exec") == 0) { + rs = cam_compile(&ctx, arg); + if (rs == 0) + rs = cam_exec(&ctx); + } + else if (rnd_strcasecmp(cmd, "call") == 0) + rs = cam_call(arg, &ctx); + } + + cam_uninit_inst(&ctx); + RND_ACT_IRES(rs); + return 0; +} + + +static rnd_action_t cam_action_list[] = { + {"cam", pcb_act_cam, pcb_acth_cam, pcb_acts_cam} +}; + +static rnd_export_opt_t *export_cam_get_export_options(rnd_hid_t *hid, int *n) +{ + return 0; +} + +static int export_cam_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nThe cam exporter shorthand:\n\n"); + fprintf(stderr, "\nUsage: pcb-rnd -x cam jobname [cam-opts] [pcb-rnd-options] filename"); + fprintf(stderr, "\n\ncam-opts:"); + fprintf(stderr, "\n --outfile path set the output file path (affets prefix and %%base%%)"); + fprintf(stderr, "\n -o key=value set %%key%% to value"); + fprintf(stderr, "\n\n"); + return 0; +} + +static char *cam_export_job; +static cam_ctx_t cam_export_ctx; +static int cam_export_has_outfile; +static int export_cam_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + int d, s, oargc; + if (*argc < 1) { + rnd_message(RND_MSG_ERROR, "-x cam needs a job name\n"); + return -1; + } + + cam_export_has_outfile = 0; + cam_init_inst(&cam_export_ctx); + cam_export_job = rnd_strdup((*argv)[0]); + oargc = (*argc); + (*argc)--; + for(d = 0, s = 1; s < oargc; s++) { + char *opt = (*argv)[s]; + if (strcmp(opt, "--outfile") == 0) { + s++; (*argc)--; + cam_parse_opt_outfile(&cam_export_ctx, (*argv)[s], 0); + cam_export_has_outfile = 1; + } + else if (strcmp(opt, "-o") == 0) { + s++; (*argc)--; + if (cam_parse_set_var(&cam_export_ctx, (*argv)[s]) != 0) { + rnd_message(RND_MSG_ERROR, "cam -o requires a key=value argument\n"); + goto err; + } + } + else { /* copy over for pcb */ + (*argv)[d] = opt; + d++; + } + } + return 0; + + err:; + cam_uninit_inst(&cam_export_ctx); + free(cam_export_job); + cam_export_job = NULL; + return 1; +} + +static void export_cam_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + if (!cam_export_has_outfile) + cam_init_inst_fn(&cam_export_ctx); + + if (cam_call(cam_export_job, &cam_export_ctx) != 0) + rnd_message(RND_MSG_ERROR, "CAM job %s failed\n", cam_export_job); + + cam_uninit_inst(&cam_export_ctx); + free(cam_export_job); + cam_export_job = NULL; +} + +rnd_hid_t export_cam_hid; + +int pplg_check_ver_cam(int ver_needed) { return 0; } + +void pplg_uninit_cam(void) +{ + rnd_conf_unreg_file(CAM_CONF_FN, cam_conf_internal); + rnd_conf_unreg_fields("plugins/cam/"); + rnd_remove_actions_by_cookie(cam_cookie); + rnd_export_remove_opts_by_cookie(cam_cookie); + rnd_hid_remove_hid(&export_cam_hid); +} + +int pplg_init_cam(void) +{ + RND_API_CHK_VER; + rnd_conf_reg_file(CAM_CONF_FN, cam_conf_internal); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_cam, field,isarray,type_name,cpath,cname,desc,flags); +#include "cam_conf_fields.h" + + RND_REGISTER_ACTIONS(cam_action_list, cam_cookie) + + memset(&export_cam_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&export_cam_hid); + + export_cam_hid.struct_size = sizeof(rnd_hid_t); + export_cam_hid.name = "cam"; + export_cam_hid.description = "Shorthand for exporting by can job name"; + export_cam_hid.exporter = 1; + export_cam_hid.hide_from_gui = 1; + + export_cam_hid.get_export_options = export_cam_get_export_options; + export_cam_hid.do_export = export_cam_do_export; + export_cam_hid.parse_arguments = export_cam_parse_arguments; + + export_cam_hid.usage = export_cam_usage; + + rnd_hid_register_hid(&export_cam_hid); + return 0; +} Index: tags/2.3.0/src_plugins/cam/cam.conf =================================================================== --- tags/2.3.0/src_plugins/cam/cam.conf (nonexistent) +++ tags/2.3.0/src_plugins/cam/cam.conf (revision 33253) @@ -0,0 +1,230 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:cam { + li:jobs { + doc_png { + desc export top and bottom copper and silk in 600 DPI pngs + plugin png --dpi 600 + write %base%.top.png=top-copper,top-silk + write %base%.bottom.png=bottom-copper,bottom-silk + } + {gerber:eagle} { + desc gerber export compatible with Eagle's gerber file names + plugin gerber --all-layers + write %base%.cmp=top-copper + write %base%.sol=bottom-copper + write %base%.ly%top_offs+1%=intern-copper + write %base%.plc=top-silk + write %base%.pls=bottom-silk + write %base%.stc=top-mask + write %base%.sts=bottom-mask + write %base%.crc=top-paste + write %base%.crs=bottom-paste + write %base%.oln=boundary + write %base%.ast=top-virtual(purpose=assy),top-doc(purpose=assy) + write %base%.asb=bottom-virtual(purpose=assy),bottom-doc(purpose=assy) + write %base%.fab=virtual(purpose=fab),top-doc(purpose=fab) + plugin excellon + write %base%.drd=[okempty] virtual(purpose=pdrill) + write %base%.dru=[okempty] virtual(purpose=udrill) + } + {gerber:fixed_topbottom} { + desc gerber export almost compatible with old 'fixed' naming style, with special casing top and bottom copper + plugin gerber --all-layers + write %base%.top.gbr=top-copper + write %base%.bottom.gbr=bottom-copper + write %base%.group%top_offs%=intern-copper + write %base%.topsilk.gbr=top-silk + write %base%.bottomsilk.gbr=bottom-silk + write %base%.topmask.gbr=top-mask + write %base%.bottommask.gbr=bottom-mask + write %base%.toppaste.gbr=top-paste + write %base%.bottompaste.gbr=bottom-paste + write %base%.outline.gbr=boundary + write %base%.topassy.gbr=top-virtual(purpose=assy),top-doc(purpose=assy) + write %base%.bottomassy.gbr=bottom-virtual(purpose=assy),bottom-doc(purpose=assy) + write %base%.fab.gbr=virtual(purpose=fab),top-doc(purpose=fab) + plugin excellon + write %base%.plated-drill.cnc=[okempty] virtual(purpose=pdrill) + write %base%.unplated-drill.cnc=[okempty] virtual(purpose=udrill) + } + {gerber:fixed} { + desc gerber export almost compatible with old 'fixed' - top and bottom copper are not special cased but numbered from group0 (top) + plugin gerber --all-layers + write %base%.group%top_offs%.gbr=top-copper + write %base%.group%top_offs%.gbr=bottom-copper + write %base%.group%top_offs%.gbr=intern-copper + write %base%.topsilk.gbr=top-silk + write %base%.bottomsilk.gbr=bottom-silk + write %base%.topmask.gbr=top-mask + write %base%.bottommask.gbr=bottom-mask + write %base%.toppaste.gbr=top-paste + write %base%.bottompaste.gbr=bottom-paste + write %base%.outline.gbr=boundary + write %base%.topassy.gbr=top-virtual(purpose=assy),top-doc(purpose=assy) + write %base%.bottomassy.gbr=bottom-virtual(purpose=assy),bottom-doc(purpose=assy) + write %base%.fab.gbr=virtual(purpose=fab),top-doc(purpose=fab) + plugin excellon + write %base%.plated-drill.cnc=[okempty] virtual(purpose=pdrill) + write %base%.unplated-drill.cnc=[okempty] virtual(purpose=udrill) + } + {gerber:universal} { + desc gerber export compatible with old 'univeral' include group name and suffix with eagle-like extensions + plugin gerber --all-layers + write %base%.%name%.gtl=top-copper + write %base%.%name%.gbl=bottom-copper + write %base%.%name%.g%top_offs%=intern-copper + write %base%.%name%.gto=top-silk + write %base%.%name%.gbo=bottom-silk + write %base%.%name%.gts=top-mask + write %base%.%name%.gbs=bottom-mask + write %base%.%name%.gtp=top-paste + write %base%.%name%.gbp=bottom-paste + write %base%.%name%.gko=boundary + write %base%.fab=virtual(purpose=fab),top-doc(purpose=fab) + plugin excellon + write %base%.drl=[okempty] virtual(purpose=pdrill) + write %base%_NPTH.drl=[okempty] virtual(purpose=udrill) + } + {gerber:OSH_Park} { + desc gerber export compatible with OSH Park's recommendations + plugin gerber --all-layers + write %base%.gtl=top-copper + write %base%.gbl=bottom-copper + write %base%.g%top_offs+1%l=intern-copper + write %base%.gto=top-silk + write %base%.gbo=bottom-silk + write %base%.gts=top-mask + write %base%.gbs=bottom-mask + write %base%.gtp=top-paste + write %base%.gbp=bottom-paste + write %base%.gko=boundary + write %base%.ast=top-virtual(purpose=assy),top-doc(purpose=assy) + write %base%.asb=bottom-virtual(purpose=assy),bottom-doc(purpose=assy) + write %base%.fab=virtual(purpose=fab),top-doc(purpose=fab) + plugin excellon + write %base%.xln=[okempty] virtual(purpose=pdrill),virtual(purpose=udrill) + } + {gerber:Seeed} { + desc gerber export compatible with Seeed Studio's recommendations + plugin gerber + write %base%.GTL=top-copper + write %base%.GBL=bottom-copper + write %base%.GL%top_offs+1%=intern-copper + write %base%.GTO=top-silk + write %base%.GBO=bottom-silk + write %base%.GTS=top-mask + write %base%.GBS=bottom-mask + write %base%.GTP=top-paste + write %base%.GBP=bottom-paste + write %base%.GML=boundary + write %base%.AST=top-virtual(purpose=assy),top-doc(purpose=assy) + write %base%.ASB=bottom-virtual(purpose=assy),bottom-doc(purpose=assy) + write %base%.FAB=virtual(purpose=fab),top-doc(purpose=fab) + plugin excellon + write %base%.TXT=[okempty] virtual(purpose=pdrill),virtual(purpose=udrill) + } +# JLC job tested and contributed by keantoken + {gerber:JLC_PCB} { + desc gerber export for JLC PCB's filename convention + plugin gerber + write %base%.gtl=top-copper + write %base%.gbl=bottom-copper + write %base%.g%top_offs+1%l=intern-copper + write %base%.gto=top-silk + write %base%.gbo=bottom-silk + write %base%.gts=top-mask + write %base%.gbs=bottom-mask + write %base%.gtp=top-paste + write %base%.gbp=bottom-paste + write %base%.gko=boundary + write %base%.ast=top-virtual(purpose=assy),top-doc(purpose=assy) + write %base%.asb=bottom-virtual(purpose=assy),bottom-doc(purpose=assy) + write %base%.fab=virtual(purpose=fab),top-doc(purpose=fab) + plugin excellon + write %base%.xln=[okempty] virtual(purpose=pdrill),virtual(purpose=udrill),mech(purpose=proute),mech(purpose=uroute) + } + +# protel job tested and contributed by keantoken + {gerber:protel} { + desc gerber export for a filename convention similar to protel's + plugin gerber + write %base%.gtl=top-copper + write %base%.gbl=bottom-copper + write %base%.g%top_offs+1%l=intern-copper + write %base%.gto=top-silk + write %base%.gbo=bottom-silk + write %base%.gts=top-mask + write %base%.gbs=bottom-mask + write %base%.gtp=top-paste + write %base%.gbp=bottom-paste + write %base%.gko=boundary + write %base%.ast=top-virtual(purpose=assy),top-doc(purpose=assy) + write %base%.asb=bottom-virtual(purpose=assy),bottom-doc(purpose=assy) + write %base%.fab=virtual(purpose=fab),top-doc(purpose=fab) + plugin excellon + write %base%.xln=[okempty] virtual(purpose=pdrill),virtual(purpose=udrill) + } + + {gerber:PCBWay} { + desc gerber export for PCBWay's filename convention + plugin gerber + write %base%-copper_top_l1.gbr=top-copper + write %base%-copper_bottom_l%top_offs+1%.gbr=bottom-copper + write %base%-copper_innter_l%top_offs+1%.gbr=intern-copper + write %base%-silkscreen_top.gbr=top-silk + write %base%-silkscreen_bottom.gbr=bottom-silk + write %base%-soldermask_top.gbr=top-mask + write %base%-soldermask_bottom.gbr=bottom-mask + write %base%-solderpaste_top.gbr=top-paste + write %base%-solderpaste_bottom.gbr=bottom-paste + write %base%-profile.gbr=boundary + plugin excellon + write %base%-drills.xln=[okempty] virtual(purpose=pdrill),virtual(purpose=udrill) + } + + {gerber:Elecrow} { + desc gerber export for Elecrow's filename convention including unplated holes (Untested) + plugin gerber + write %base%.GTL=top-copper + write %base%.GTS=top-mask + write %base%.GTO=top-silk + write %base%.GTP=top-paste + write %base%.GBL=bottom-copper + write %base%.GBS=bottom-mask + write %base%.GBO=bottom-silk + write %base%.GBP=bottom-paste + write %base%.GML=boundary + write %base%.FAB=virtual(purpose=fab),top-doc(purpose=fab) + write %base%.GL%top_offs+1%=intern-copper + plugin excellon + write %base%.TXT=[okempty] virtual(purpose=pdrill) + write %base%-NPTH.txt=[okempty] virtual(purpose=udrill) + } + + {gerber:orcad} { + desc gerber export compatible with Orcad's gerber file names + plugin gerber --all-layers + write %base%.top=top-copper + write %base%.bot=bottom-copper +# write %base%.ly%top_offs+1%=intern-copper + write %base%.sst=top-silk + write %base%.ssb=bottom-silk + write %base%.smt=top-mask + write %base%.smb=bottom-mask +# write %base%.spt=top-paste +# write %base%.spb=bottom-paste + write %base%.fab=boundary +# write %base%.ast=top-virtual(purpose=assy),top-doc(purpose=assy) +# write %base%.asb=bottom-virtual(purpose=assy),bottom-doc(purpose=assy) +# write %base%.fab.gbr=virtual(purpose=fab),top-doc(purpose=fab) + plugin excellon + write %base%.thruhole.tap=[okempty] virtual(purpose=pdrill) + write %base%.thruhole-unplated.tap=[okempty] virtual(purpose=udrill) + } + } + } + } + } +} Index: tags/2.3.0/src_plugins/cam/cam.pup =================================================================== --- tags/2.3.0/src_plugins/cam/cam.pup (nonexistent) +++ tags/2.3.0/src_plugins/cam/cam.pup (revision 33253) @@ -0,0 +1,8 @@ +$class export +$short cam/job based export +$long Configurable output job based batch exporting +$state works +$package export +dep query +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/cam/cam_compile.c =================================================================== --- tags/2.3.0/src_plugins/cam/cam_compile.c (nonexistent) +++ tags/2.3.0/src_plugins/cam/cam_compile.c (revision 33253) @@ -0,0 +1,323 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * cam export jobs plugin - compile/decompile jobs + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "data.h" + +#define GVT_DONT_UNDEF +#include "cam_compile.h" +#include "layer_vis.h" +#include "event.h" +#include +#include + + +/* mkdir -p on arg - changes the string in arg */ +static int prefix_mkdir(char *arg, char **filename, rnd_bool nomkdir) +{ + char *curr, *next, *end; + int res; + + /* mkdir -p if there's a path sep in the prefix */ + end = strrchr(arg, RND_DIR_SEPARATOR_C); + if (end == NULL) { + if (filename != NULL) + *filename = arg; + return 0; + } + + *end = '\0'; + res = end - arg; + if (filename != NULL) + *filename = end+1; + + for(curr = arg; curr != NULL; curr = next) { + next = strrchr(curr, RND_DIR_SEPARATOR_C); + if (next != NULL) + *next = '\0'; + if (!nomkdir) + rnd_mkdir(&PCB->hidlib, arg, 0755); + if (next != NULL) { + *next = RND_DIR_SEPARATOR_C; + next++; + } + } + return res; +} + +static int cam_exec_inst(cam_ctx_t *ctx, pcb_cam_code_t *code) +{ + int argc; + char **argv; + + switch(code->inst) { + case PCB_CAM_DESC: + /* ignore */ + break; + + case PCB_CAM_PARTIAL: + if (code->op.partial.arg != NULL) { + ctx->partial = 1; + rnd_actionva(&PCB->hidlib, "query", "setflag:exportsel", code->op.partial.arg, NULL); + } + else { + if (ctx->partial) { + pcb_data_clear_flag(PCB->Data, PCB_FLAG_EXPORTSEL, 0, 0); + ctx->partial = 0; + } + } + break; + + case PCB_CAM_WRITE: + if (ctx->exporter == NULL) { + rnd_message(RND_MSG_ERROR, "cam: no exporter selected before write\n"); + return -1; + } + + /* build the --cam args using the prefix */ + ctx->argv[0] = "--cam"; + gds_truncate(&ctx->tmp, 0); + if (ctx->prefix != NULL) + gds_append_str(&ctx->tmp, ctx->prefix); + gds_append_str(&ctx->tmp, code->op.write.arg); + ctx->argv[1] = ctx->tmp.array; + + argc = ctx->argc; + argv = ctx->argv; + if (ctx->exporter->parse_arguments(ctx->exporter, &argc, &argv) != 0) { + rnd_message(RND_MSG_ERROR, "cam: exporter '%s' refused the arguments\n", code->op.write.arg); + ctx->argv[0] = NULL; + ctx->argv[1] = NULL; + return -1; + } + + { /* call the exporter */ + void *old_vars, *tmp; + old_vars = pcb_cam_vars_use(ctx->vars); + ctx->exporter->do_export(ctx->exporter, 0); + tmp = pcb_cam_vars_use(old_vars); + assert(tmp == ctx->vars); /* we must be restoring from our own context else the recursion is broken */ + } + + ctx->argv[0] = NULL; + ctx->argv[1] = NULL; + break; + + case PCB_CAM_PLUGIN: + ctx->exporter = code->op.plugin.exporter; + ctx->argc = code->op.plugin.argc; + ctx->argv = code->op.plugin.argv; + break; + + default: + assert(!"invalid cam code"); + } + return 0; +} + + +static int cam_exec(cam_ctx_t *ctx) +{ + int res = 0, n, have_gui, currly = PCB_CURRLID(PCB); + int save_l_ons[PCB_MAX_LAYER], save_g_ons[PCB_MAX_LAYERGRP]; + int ovr = 0, *old_ovr; + + old_ovr = rnd_batched_ask_ovr_init(&PCB->hidlib, &ovr); + + if (ctx->has_partial) + pcb_data_clear_flag(PCB->Data, PCB_FLAG_EXPORTSEL, 0, 0); + + have_gui = (rnd_gui != NULL) && rnd_gui->gui; + if (have_gui) { + pcb_hid_save_and_show_layer_ons(save_l_ons); + pcb_hid_save_and_show_layergrp_ons(save_g_ons); + } + + rnd_event(&PCB->hidlib, RND_EVENT_EXPORT_SESSION_BEGIN, NULL); + for(n = 0; n < ctx->code.used; n++) { + if (cam_exec_inst(ctx, &ctx->code.array[n]) != 0) { + res = 1; + break; + } + } + rnd_event(&PCB->hidlib, RND_EVENT_EXPORT_SESSION_END, NULL); + + if (ctx->partial) { + pcb_data_clear_flag(PCB->Data, PCB_FLAG_EXPORTSEL, 0, 0); + ctx->partial = 0; + } + + if (have_gui) { + pcb_hid_restore_layer_ons(save_l_ons); + pcb_hid_restore_layergrp_ons(save_g_ons); + pcb_layervis_change_group_vis(&PCB->hidlib, currly, 1, 1); + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERVIS_CHANGED, NULL); + } + + rnd_batched_ask_ovr_uninit(&PCB->hidlib, old_ovr); + return res; +} + +static int cam_compile_line(cam_ctx_t *ctx, char *cmd, char *arg, pcb_cam_code_t *code) +{ + + if (strcmp(cmd, "desc") == 0) { + code->inst = PCB_CAM_DESC; + code->op.desc.arg = rnd_strdup(arg); + } + else if (strcmp(cmd, "write") == 0) { + code->inst = PCB_CAM_WRITE; + code->op.write.arg = rnd_strdup(arg); + } + else if (strcmp(cmd, "partial") == 0) { + ctx->has_partial = 1; + code->inst = PCB_CAM_PARTIAL; + if ((arg == NULL) || (*arg == '\0')) + code->op.partial.arg = NULL; + else + code->op.partial.arg = rnd_strdup(arg); + } + else if (strcmp(cmd, "full") == 0) { + code->inst = PCB_CAM_PARTIAL; + code->op.write.arg = NULL; + } + else if (strcmp(cmd, "plugin") == 0) { + char *curr, *next; + int maxa; + char *s; + + code->inst = PCB_CAM_PLUGIN; + curr = strpbrk(arg, " \t"); + if (curr != NULL) { + *curr = '\0'; + curr++; + } + code->op.plugin.exporter = rnd_hid_find_exporter(arg); + if (code->op.plugin.exporter == NULL) { + rnd_message(RND_MSG_ERROR, "cam: can not find export plugin: '%s'\n", arg); + return -1; + } + free(ctx->args); + + curr = rnd_strdup(curr == NULL ? "" : curr); + for(maxa = 0, s = curr; *s != '\0'; s++) + if (isspace(*s)) + maxa++; + + code->op.plugin.argc = 2; /* [0] and [1] are reserved for the --cam argument */ + code->op.plugin.argv = malloc(sizeof(char *) * (maxa+3)); + code->op.plugin.argv[0] = NULL; + code->op.plugin.argv[1] = NULL; + if (code->op.plugin.argv == NULL) + return 1; + for(; curr != NULL; curr = next) { + while(isspace(*curr)) curr++; + next = strpbrk(curr, " \t"); + if (next != NULL) { + *next = '\0'; + next++; + } + if (*curr == '\0') + continue; + code->op.plugin.argv[code->op.plugin.argc] = rnd_strdup(curr); + code->op.plugin.argc++; + + } + code->op.plugin.argv[ctx->argc] = NULL; + } + else { + rnd_message(RND_MSG_ERROR, "cam: syntax error (unknown instruction): '%s'\n", cmd); + return -1; + } + return 0; +} + +static int cam_compile(cam_ctx_t *ctx, const char *script_in) +{ + char *arg, *curr, *next, *script = rnd_strdup(script_in); + int res = 0, r; + + for(curr = script; curr != NULL; curr = next) { + pcb_cam_code_t code; + + while(isspace(*curr)) curr++; + next = strpbrk(curr, ";\r\n"); + if (next != NULL) { + *next = '\0'; + next++; + } + if (*curr == '\0') + continue; + arg = strpbrk(curr, " \t"); + if (arg != NULL) { + *arg = '\0'; + arg++; + } + if ((*curr == '#') || (*curr == '\0')) + continue; + r = cam_compile_line(ctx, curr, arg, &code); + if (r == 0) + vtcc_append(&ctx->code, code); + else + res = 1; + } + + free(script); + return res; +} + +static void cam_free_inst(cam_ctx_t *ctx, pcb_cam_code_t *code) +{ + int n; + + switch(code->inst) { + case PCB_CAM_DESC: + break; + + case PCB_CAM_WRITE: + free(code->op.write.arg); + break; + + case PCB_CAM_PARTIAL: + free(code->op.partial.arg); + break; + + case PCB_CAM_PLUGIN: + for(n = 0; n < code->op.plugin.argc; n++) + free(code->op.plugin.argv[n]); + free(code->op.plugin.argv); + break; + } +} + +static void cam_free_code(cam_ctx_t *ctx) +{ + int n; + for(n = 0; n < ctx->code.used; n++) + cam_free_inst(ctx, &ctx->code.array[n]); + vtcc_uninit(&ctx->code); +} Index: tags/2.3.0/src_plugins/cam/cam_compile.h =================================================================== --- tags/2.3.0/src_plugins/cam/cam_compile.h (nonexistent) +++ tags/2.3.0/src_plugins/cam/cam_compile.h (revision 33253) @@ -0,0 +1,93 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * cam export jobs plugin - compile/decompile jobs + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_CAM_COMPILE_H +#define PCB_CAM_COMPILE_H + +typedef enum { + PCB_CAM_DESC, + PCB_CAM_PLUGIN, + PCB_CAM_WRITE, + PCB_CAM_PARTIAL +} pcb_cam_inst_t; + +typedef struct { + pcb_cam_inst_t inst; + union { + struct { + char *arg; + } desc; + struct { + rnd_hid_t *exporter; + int argc; + char **argv; + } plugin; + struct { + char *arg; + } write; + struct { + char *arg; + } partial; + struct { + char *arg; + } prefix; + } op; +} pcb_cam_code_t; + +#define GVT(x) vtcc_ ## x +#define GVT_ELEM_TYPE pcb_cam_code_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 { + rnd_hidlib_t *hidlib; + char *prefix; /* strdup'd file name prefix from the last prefix command */ + rnd_hid_t *exporter; + unsigned partial:1; /* when 1, there are objects marked with the EXPORTSEL flag */ + + unsigned has_partial:1; /* the code has partial in it so an initial flag reset is needed */ + + char *args; /* strdup'd argument string from the last plugin command - already split up */ + char **argv; /* [0] and [1] are for --cam; the rest point into args */ + int argc; + + vtcc_t code; + void *vars; + + gds_t tmp; +} cam_ctx_t; + +#endif Index: tags/2.3.0/src_plugins/cam/cam_conf.h =================================================================== --- tags/2.3.0/src_plugins/cam/cam_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/cam/cam_conf.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_CAM_CONF_H +#define PCB_CAM_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_LIST jobs; /* named cam scripts */ + } cam; + } plugins; +} conf_cam_t; + +#endif Index: tags/2.3.0/src_plugins/cam/cam_gui.c =================================================================== --- tags/2.3.0/src_plugins/cam/cam_gui.c (nonexistent) +++ tags/2.3.0/src_plugins/cam/cam_gui.c (revision 33253) @@ -0,0 +1,359 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * cam export jobs plugin: GUI dialog + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include + +static const char *OUTFILE_HELP = "Output file name sample, which will\nbe split to prefix and base name (%base%)\nto be used in file name templates"; +static const char *PREFIX_HELP = "File name prefix: every output file\npath will start with this prefix.\nIt is derived from outfile."; + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + cam_ctx_t cam; + int wjobs, wdigest, wtxt, woutfile, wprefix, wopts; +} cam_dlg_t; + +static void cam_gui_jobs2dlg(cam_dlg_t *ctx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[2], *cursor_path = NULL; + rnd_conf_native_t *cn; + + attr = &ctx->dlg[ctx->wjobs]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all new items */ + cn = rnd_conf_get_field("plugins/cam/jobs"); + if (cn != NULL) { + rnd_conf_listitem_t *item; + int idx; + + cell[1] = NULL; + rnd_conf_loop_list(cn->val.list, item, idx) { + cell[0] = rnd_strdup(item->name); + rnd_dad_tree_append(attr, NULL, cell); + } + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wjobs, &hv); + } +} + +static void cam_gui_digest2dlg(cam_dlg_t *ctx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + pcb_cam_code_t *c, *plugin = NULL; + char *cell[4], tmp[1024]; + int n; + + attr = &ctx->dlg[ctx->wdigest]; + tree = attr->wdata; + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all new items */ + for(n = 0, c = ctx->cam.code.array; n < ctx->cam.code.used; n++,c++) { + switch(c->inst) { + case PCB_CAM_DESC: + case PCB_CAM_PARTIAL: + break; + case PCB_CAM_PLUGIN: + plugin = c; + break; + case PCB_CAM_WRITE: + strncpy(tmp, c->op.write.arg, sizeof(tmp)); + + cell[0] = tmp; + cell[2] = strchr(tmp, '='); + if (cell[2] != NULL) { + *cell[2] = '\0'; + (cell[2])++; + } + else + cell[2] = ""; + + if (plugin != NULL) + cell[1] = rnd_strdup(plugin->op.plugin.exporter->name); + else + cell[1] = ""; + + cell[3] = NULL; + rnd_dad_tree_append(attr, NULL, cell); + break; + } + } +} + + +static void cam_gui_opts2dlg(cam_dlg_t *ctx) +{ + htsp_t *vars = ctx->cam.vars; + htsp_entry_t *e; + rnd_hid_attr_val_t hv; + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[3], *cursor_path = NULL; + + cam_parse_opt_outfile(&ctx->cam, ctx->dlg[ctx->woutfile].val.str, 1); + hv.str = ctx->cam.prefix == NULL ? "" : ctx->cam.prefix; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wprefix, &hv); + + attr = &ctx->dlg[ctx->wopts]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all new items */ + for(e = htsp_first(vars); e != NULL; e = htsp_next(vars, e)) { + cell[0] = rnd_strdup(e->key); + cell[1] = rnd_strdup(e->value); + cell[2] = NULL; + rnd_dad_tree_append(attr, NULL, cell); + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wopts, &hv); + } +} + +static void cam_gui_outfile_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + cam_dlg_t *ctx = caller_data; + cam_gui_opts2dlg(ctx); +} + +static void cam_gui_filter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + cam_dlg_t *ctx = caller_data; + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + const char *text; + + attr = &ctx->dlg[ctx->wjobs]; + tree = attr->wdata; + text = attr_inp->val.str; + + rnd_dad_tree_hide_all(tree, &tree->rows, 1); + rnd_dad_tree_unhide_filter(tree, &tree->rows, 0, text); + rnd_dad_tree_update_hide(attr); +} + +static void cam_gui_export_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + cam_dlg_t *ctx = caller_data; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wjobs]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(attr); + + if (row != NULL) { + const char *outfile = ctx->dlg[ctx->woutfile].val.str; + char *tmp = rnd_strdup_printf("outfile=%s", outfile); + rnd_actionva(ctx->cam.hidlib, "cam", "call", row->cell[0], tmp, NULL); + free(tmp); + } +} + +static char *kill_tabs(const char *str_in) +{ + char *res, *o; + res = rnd_strdup(str_in); + for(o = res; *o != '\0'; o++) + if (*o == '\t') + *o = ' '; + return res; +} + +static void cam_job_select_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + cam_dlg_t *ctx = tree->user_ctx; + + if (row != NULL) { + char *script = kill_tabs(cam_find_job(row->cell[0])); + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + + txt->hid_set_text(atxt, hid_ctx, RND_HID_TEXT_REPLACE, script); + + cam_free_code(&ctx->cam); + if (script != NULL) + cam_compile(&ctx->cam, script); + cam_gui_digest2dlg(ctx); + + free(script); + } +} + +static void cam_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + cam_dlg_t *ctx = caller_data; + cam_uninit_inst(&ctx->cam); + RND_DAD_FREE(ctx->dlg); + free(ctx); +} + +/* center aligned label */ +static void header_label(cam_dlg_t *ctx, const char *text) +{ + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, text); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); +} + +static int cam_gui(rnd_hidlib_t *hidlib, const char *arg) +{ + cam_dlg_t *ctx = calloc(sizeof(cam_dlg_t), 1); + const char *opt_hdr[] = {"key", "option value", NULL}; + const char *script_tabs[] = {"digest", "raw", NULL}; + const char *digest_hdr[] = {"file", "plugin", "layer groups", NULL}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + ctx->cam.hidlib = hidlib; + ctx->cam.vars = pcb_cam_vars_alloc(); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* left */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 1, 0, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, cam_job_select_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + ctx->wjobs = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); /* command section */ + RND_DAD_STRING(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "Filter text:\nlist jobs with matching name only"); + RND_DAD_CHANGE_CB(ctx->dlg, cam_gui_filter_cb); + RND_DAD_BEGIN_VBOX(ctx->dlg); /* filler */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "export!"); + RND_DAD_CHANGE_CB(ctx->dlg, cam_gui_export_cb); + RND_DAD_HELP(ctx->dlg, "Export the current board using the above selected CAM job\nand the options set on the right"); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* right */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VPANE(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); /* top */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + header_label(ctx, "CAM job script"); + RND_DAD_BEGIN_TABBED(ctx->dlg, script_tabs); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_TREE(ctx->dlg, 3, 0, digest_hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wdigest = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_TEXT(ctx->dlg, ctx); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wtxt = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); /* bottom */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + header_label(ctx, "CAM options"); + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); /* special options */ + RND_DAD_LABEL(ctx->dlg, "outfile"); + RND_DAD_HELP(ctx->dlg, OUTFILE_HELP); + RND_DAD_STRING(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, cam_gui_outfile_cb); + ctx->woutfile = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, OUTFILE_HELP); + RND_DAD_LABEL(ctx->dlg, "prefix"); + RND_DAD_HELP(ctx->dlg, PREFIX_HELP); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->wprefix = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, PREFIX_HELP); + RND_DAD_END(ctx->dlg); + + RND_DAD_TREE(ctx->dlg, 2, 0, opt_hdr); /* option table */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wopts = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_NEW("cam", ctx->dlg, "CAM export", ctx, rnd_false, cam_close_cb); + + { /* set default outfile */ + rnd_hid_attr_val_t hv; + hv.str = pcb_derive_default_filename_(PCB->hidlib.filename, ""); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->woutfile, &hv); + free((char *)hv.str); + cam_gui_opts2dlg(ctx); + } + + { /* set right top text read-only */ + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + txt->hid_set_readonly(atxt, ctx->dlg_hid_ctx, 1); + } + + cam_gui_jobs2dlg(ctx); + + return 0; +} Index: tags/2.3.0/src_plugins/ch_editpoint/Makefile =================================================================== --- tags/2.3.0/src_plugins/ch_editpoint/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/ch_editpoint/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_ch_editpoint + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/ch_editpoint/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/ch_editpoint/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/ch_editpoint/Plug.tmpasm (revision 33253) @@ -0,0 +1,16 @@ +put /local/pcb/mod {ch_editpoint} +put /local/pcb/mod/CONF {$(PLUGDIR)/ch_editpoint/ch_editpoint_conf.h} +put /local/pcb/mod/CONFFILE {ch_editpoint.conf} +put /local/pcb/mod/CONFVAR {ch_editpoint_conf_internal} +put /local/pcb/mod/MENUFILE {ch_editpoint-menu.lht} +put /local/pcb/mod/MENUVAR {ch_editpoint_menu} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/ch_editpoint/ch_editpoint.o +@] + + +switch /local/pcb/ch_editpoint/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint-menu.lht =================================================================== --- tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@indications { + li:submenu { + ha:Indicate edit points on hover = { a={m; d; e}; checked=plugins/ch_editpoint/enable; action=conf(toggle, plugins/ch_editpoint/enable, design) } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint.c =================================================================== --- tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint.c (nonexistent) +++ tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint.c (revision 33253) @@ -0,0 +1,191 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * crosshair: display edit points of the objects that are under the cursor + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Draw the editpoints of objects which are under the crosshair */ + +#include "config.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "board.h" +#include "conf_core.h" +#include "crosshair.h" +#include "data.h" +#include "draw.h" +#include "event.h" +#include "obj_pstk.h" +#include "polygon.h" +#include "search.h" +#include "tool_logic.h" +#include "../src_plugins/ch_editpoint/ch_editpoint_conf.h" + +#include "../src_plugins/ch_editpoint/conf_internal.c" +#include "../src_plugins/ch_editpoint/menu_internal.c" + +conf_ch_editpoint_t conf_ch_editpoint; +#define CH_EDITPOINT_CONF_FN "ch_editpoint.conf" + + +static const char pcb_ch_editpoint_cookie[] = "ch_editpoint plugin"; + +static vtp0_t editpoint_raw[2]; +static vtp0_t *editpoint_objs = &editpoint_raw[0], *old_editpoint_objs = &editpoint_raw[1]; + +static rnd_r_dir_t editpoint_callback(const rnd_box_t *box, void *cl) +{ + pcb_crosshair_t *crosshair = cl; + pcb_any_obj_t *obj = (pcb_any_obj_t *)box; + + switch(obj->type) { + case PCB_OBJ_LINE: if (!pcb_is_point_on_line(crosshair->X, crosshair->Y, PCB_SLOP * rnd_pixel_slop, (pcb_line_t *)obj)) return RND_R_DIR_FOUND_CONTINUE; break; + case PCB_OBJ_ARC: if (!pcb_is_point_on_arc(crosshair->X, crosshair->Y, PCB_SLOP * rnd_pixel_slop, (pcb_arc_t *)obj)) return RND_R_DIR_FOUND_CONTINUE; break; + case PCB_OBJ_POLY: if (!pcb_poly_is_point_in_p(crosshair->X, crosshair->Y, PCB_SLOP * rnd_pixel_slop, (pcb_poly_t *)obj)) return RND_R_DIR_FOUND_CONTINUE; break; + case PCB_OBJ_PSTK: if (!pcb_is_point_in_pstk(crosshair->X, crosshair->Y, PCB_SLOP * rnd_pixel_slop, (pcb_pstk_t *)obj, NULL)) return RND_R_DIR_FOUND_CONTINUE; break; + default: break; + } + + vtp0_append(editpoint_objs, obj); + obj->ind_editpoint = 1; + return RND_R_DIR_FOUND_CONTINUE; +} + +static void *editpoint_find(vtp0_t *vect, pcb_any_obj_t *obj_ptr) +{ + int n; + + for(n = 0; n < vect->used; n++) { + pcb_any_obj_t *op = vect->array[n]; + if (op == obj_ptr) + return op; + } + return NULL; +} + +/* Searches for lines/arcs which have points that are exactly at the given coords + and adds them to the object list along with their respective type. */ +static void editpoint_work(pcb_crosshair_t *crosshair, rnd_coord_t X, rnd_coord_t Y) +{ + rnd_box_t SearchBox = rnd_point_box(X, Y); + int n; + rnd_bool redraw = rnd_false; + vtp0_t *tmp; + + /* swap old and new */ + tmp = editpoint_objs; + editpoint_objs = old_editpoint_objs; + old_editpoint_objs = tmp; + + /* Do not truncate to 0 because that may free the array */ + vtp0_truncate(editpoint_objs, 1); + editpoint_objs->used = 0; + + for(n = 0; n < pcb_max_layer(PCB); n++) { + pcb_layer_t *layer = &PCB->Data->Layer[n]; + /* Only find points of arcs and lines on currently visible layers. */ + if (!layer->meta.real.vis) + continue; + rnd_r_search(layer->line_tree, &SearchBox, NULL, editpoint_callback, crosshair, NULL); + rnd_r_search(layer->arc_tree, &SearchBox, NULL, editpoint_callback, crosshair, NULL); + rnd_r_search(layer->polygon_tree, &SearchBox, NULL, editpoint_callback, crosshair, NULL); + } + rnd_r_search(PCB->Data->padstack_tree, &SearchBox, NULL, editpoint_callback, crosshair, NULL); + + + /* Undraw the old objects */ + for(n = 0; n < old_editpoint_objs->used; n++) { + pcb_any_obj_t *op = old_editpoint_objs->array[n]; + + /* only remove and redraw those which aren't in the new list */ + if (editpoint_find(editpoint_objs, op) != NULL) + continue; + + op->ind_editpoint = 0; + pcb_draw_obj(op); + redraw = rnd_true; + } + + /* draw the new objects */ + for(n = 0; n < editpoint_objs->used; n++) { + pcb_any_obj_t *op = editpoint_objs->array[n]; + + /* only draw those which aren't in the old list */ + if (editpoint_find(old_editpoint_objs, op) != NULL) + continue; + pcb_draw_obj(op); + redraw = rnd_true; + } + + if (redraw) + rnd_hid_redraw(PCB); +} + +static void pcb_ch_editpoint(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pcb_crosshair_t *ch = argv[1].d.p; + if (conf_ch_editpoint.plugins.ch_editpoint.enable) { + const rnd_tool_t *tool = rnd_tool_get(rnd_conf.editor.mode); + if ((tool != NULL) && (tool->user_flags & PCB_TLF_EDIT)) + editpoint_work(ch, ch->X, ch->Y); + } +} + +int pplg_check_ver_ch_editpoint(int ver_needed) { return 0; } + +void pplg_uninit_ch_editpoint(void) +{ + rnd_event_unbind_allcookie(pcb_ch_editpoint_cookie); + vtp0_uninit(editpoint_objs); + vtp0_uninit(old_editpoint_objs); + + rnd_conf_unreg_file(CH_EDITPOINT_CONF_FN, ch_editpoint_conf_internal); + rnd_hid_menu_unload(rnd_gui, pcb_ch_editpoint_cookie); + rnd_conf_unreg_fields("plugins/ch_editpoint/"); +} + +int pplg_init_ch_editpoint(void) +{ + RND_API_CHK_VER; + + rnd_conf_reg_file(CH_EDITPOINT_CONF_FN, ch_editpoint_conf_internal); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_ch_editpoint, field,isarray,type_name,cpath,cname,desc,flags); +#include "ch_editpoint_conf_fields.h" + + rnd_event_bind(PCB_EVENT_CROSSHAIR_NEW_POS, pcb_ch_editpoint, NULL, pcb_ch_editpoint_cookie); + + rnd_hid_menu_load(rnd_gui, NULL, pcb_ch_editpoint_cookie, 100, NULL, 0, ch_editpoint_menu, "plugin: ch_editpoint"); + + return 0; +} Index: tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint.conf =================================================================== --- tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint.conf (nonexistent) +++ tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint.conf (revision 33253) @@ -0,0 +1,9 @@ +li:pcb-rnd-conf-v1 { + ha:append { + ha:plugins { + ha:ch_editpoint { + enable = 1 + } + } + } +} Index: tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint.pup =================================================================== --- tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint.pup (nonexistent) +++ tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint.pup (revision 33253) @@ -0,0 +1,8 @@ +$class feature +$short crosshair: on-point highlight +$long crosshair: highlight object upon crosshair on edit point +$state works +$package core +default buildin +autoload 1 + Index: tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint_conf.h =================================================================== --- tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/ch_editpoint/ch_editpoint_conf.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_CH_EDITPOINT_CONF_H +#define PCB_CH_EDITPOINT_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN enable; /* indicate edit points when the cursor is over an object */ + } ch_editpoint; + } plugins; +} conf_ch_editpoint_t; + +#endif Index: tags/2.3.0/src_plugins/ch_onpoint/Makefile =================================================================== --- tags/2.3.0/src_plugins/ch_onpoint/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/ch_onpoint/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_ch_onpoint + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/ch_onpoint/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/ch_onpoint/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/ch_onpoint/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {ch_onpoint} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/ch_onpoint/ch_onpoint.o +@] + + +switch /local/pcb/ch_onpoint/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/ch_onpoint/ch_onpoint.c =================================================================== --- tags/2.3.0/src_plugins/ch_onpoint/ch_onpoint.c (nonexistent) +++ tags/2.3.0/src_plugins/ch_onpoint/ch_onpoint.c (revision 33253) @@ -0,0 +1,221 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * crosshair: highlight objects that are under the cursor + * original onpoint patch Copyright (C) 2015 Robert Drehmel + * pcb-rnd Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Implementation of the "highlight on endpoint" functionality. This highlights + lines and arcs when the crosshair is on of their (two) endpoints. */ + +#include "config.h" + +#include + +#include +#include +#include +#include +#include +#include +#include "tool_logic.h" +#include "board.h" +#include "conf_core.h" +#include "crosshair.h" +#include "data.h" +#include "event.h" +#include "obj_arc.h" +#include "obj_arc_draw.h" +#include "obj_line_draw.h" + +static const char pcb_ch_onpoint_cookie[] = "ch_onpoint plugin"; + +static vtp0_t onpoint_raw[2]; +static vtp0_t *onpoint_objs = &onpoint_raw[0], *old_onpoint_objs = &onpoint_raw[1]; + +struct onpoint_search_info { + pcb_crosshair_t *crosshair; + rnd_coord_t X; + rnd_coord_t Y; +}; + +static rnd_r_dir_t onpoint_line_callback(const rnd_box_t *box, void *cl) +{ + struct onpoint_search_info *info = (struct onpoint_search_info *)cl; + pcb_line_t *line = (pcb_line_t *)box; + +#ifdef DEBUG_ONPOINT + rnd_trace("onpoint X=%mm Y=%mm X1=%mm Y1=%mm X2=%mm Y2=%mm\n", + info->X, info->Y, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); +#endif + if ((line->Point1.X == info->X && line->Point1.Y == info->Y) || (line->Point2.X == info->X && line->Point2.Y == info->Y)) { + vtp0_append(onpoint_objs, line); + line->ind_onpoint = 1; + pcb_line_invalidate_draw(NULL, line); + return RND_R_DIR_FOUND_CONTINUE; + } + else + return RND_R_DIR_NOT_FOUND; +} + +#define close_enough(v1, v2) (coord_abs((v1)-(v2)) < 10) + +static rnd_r_dir_t onpoint_arc_callback(const rnd_box_t *box, void *cl) +{ + struct onpoint_search_info *info = (struct onpoint_search_info *)cl; + pcb_arc_t *arc = (pcb_arc_t *)box; + rnd_coord_t p1x, p1y, p2x, p2y; + + pcb_arc_get_end(arc, 0, &p1x, &p1y); + pcb_arc_get_end(arc, 1, &p2x, &p2y); + +#ifdef DEBUG_ONPOINT + rnd_trace("onpoint p1=%mm;%mm p2=%mm;%mm info=%mm;%mm\n", p1x, p1y, p2x, p2y, info->X, info->Y); +#endif + + if ((close_enough(p1x, info->X) && close_enough(p1y, info->Y)) || (close_enough(p2x, info->X) && close_enough(p2y, info->Y))) { + vtp0_append(onpoint_objs, arc); + arc->ind_onpoint = 1; + pcb_arc_invalidate_draw(NULL, arc); + return RND_R_DIR_FOUND_CONTINUE; + } + else + return RND_R_DIR_NOT_FOUND; +} + +static void draw_line_or_arc(pcb_any_obj_t *o) +{ + switch(o->type) { + case PCB_OBJ_LINE: pcb_line_invalidate_draw(o->parent.layer, (pcb_line_t *)o); break; + case PCB_OBJ_ARC: pcb_arc_invalidate_draw(o->parent.layer, (pcb_arc_t *)o); break; + break; + default: assert(!"draw_line_or_arc() expects line or arc point"); + } +} + + +#define op_swap(crosshair) \ +do { \ + vtp0_t *__tmp__ = onpoint_objs; \ + onpoint_objs = old_onpoint_objs; \ + old_onpoint_objs = __tmp__; \ +} while(0) + +static void *onpoint_find(vtp0_t *vect, pcb_any_obj_t *obj_ptr) +{ + int i; + + for (i = 0; i < vect->used; i++) { + pcb_any_obj_t *op = vect->array[i]; + if (op == obj_ptr) + return op; + } + return NULL; +} + +/* Searches for lines/arcs which have points that are exactly at the given coords + and adds them to the object list along with their respective type. */ +static void onpoint_work(pcb_crosshair_t *crosshair, rnd_coord_t X, rnd_coord_t Y) +{ + rnd_box_t SearchBox = rnd_point_box(X, Y); + struct onpoint_search_info info; + int i; + rnd_bool redraw = rnd_false; + + op_swap(crosshair); + + /* Do not truncate to 0 because that may free the array */ + vtp0_truncate(onpoint_objs, 1); + onpoint_objs->used = 0; + + + info.crosshair = crosshair; + info.X = X; + info.Y = Y; + + for (i = 0; i < pcb_max_layer(PCB); i++) { + pcb_layer_t *layer = &PCB->Data->Layer[i]; + /* Only find points of arcs and lines on currently visible layers. */ + if (!layer->meta.real.vis) + continue; + rnd_r_search(layer->line_tree, &SearchBox, NULL, onpoint_line_callback, &info, NULL); + rnd_r_search(layer->arc_tree, &SearchBox, NULL, onpoint_arc_callback, &info, NULL); + } + + /* Undraw the old objects */ + for (i = 0; i < old_onpoint_objs->used; i++) { + pcb_any_obj_t *op = old_onpoint_objs->array[i]; + + /* only remove and redraw those which aren't in the new list */ + if (onpoint_find(onpoint_objs, op) != NULL) + continue; + + op->ind_onpoint = 0; + draw_line_or_arc(op); + redraw = rnd_true; + } + + /* draw the new objects */ + for (i = 0; i < onpoint_objs->used; i++) { + pcb_any_obj_t *op = onpoint_objs->array[i]; + + /* only draw those which aren't in the old list */ + if (onpoint_find(old_onpoint_objs, op) != NULL) + continue; + draw_line_or_arc(op); + redraw = rnd_true; + } + + if (redraw) + rnd_hid_redraw(PCB); +} + +static void pcb_ch_onpoint(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pcb_crosshair_t *ch = argv[1].d.p; + if (conf_core.editor.highlight_on_point) { + const rnd_tool_t *tool = rnd_tool_get(rnd_conf.editor.mode); + if ((tool != NULL) && (tool->user_flags & PCB_TLF_EDIT)) + onpoint_work(ch, ch->X, ch->Y); + } +} + +int pplg_check_ver_ch_onpoint(int ver_needed) { return 0; } + +void pplg_uninit_ch_onpoint(void) +{ + rnd_event_unbind_allcookie(pcb_ch_onpoint_cookie); + vtp0_uninit(onpoint_objs); + vtp0_uninit(old_onpoint_objs); +} + +int pplg_init_ch_onpoint(void) +{ + RND_API_CHK_VER; + + rnd_event_bind(PCB_EVENT_CROSSHAIR_NEW_POS, pcb_ch_onpoint, NULL, pcb_ch_onpoint_cookie); + + return 0; +} Index: tags/2.3.0/src_plugins/ch_onpoint/ch_onpoint.pup =================================================================== --- tags/2.3.0/src_plugins/ch_onpoint/ch_onpoint.pup (nonexistent) +++ tags/2.3.0/src_plugins/ch_onpoint/ch_onpoint.pup (revision 33253) @@ -0,0 +1,8 @@ +$class feature +$short crosshair: on-point highlight +$long crosshair: highlight object upon crosshair on edit point +$state works +$package core +default buildin +autoload 1 + Index: tags/2.3.0/src_plugins/ddraft/Makefile =================================================================== --- tags/2.3.0/src_plugins/ddraft/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_ddraft + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/ddraft/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/ddraft/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/Plug.tmpasm (revision 33253) @@ -0,0 +1,13 @@ +put /local/pcb/mod {ddraft} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/ddraft/ddraft.o + $(PLUGDIR)/ddraft/centgeo.o + $(PLUGDIR)/ddraft/fields_sphash.o +@] +put /local/pcb/mod/SPHASH {$(PLUGDIR)/ddraft/fields.sphash} + +switch /local/pcb/ddraft/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/ddraft/centgeo.c =================================================================== --- tags/2.3.0/src_plugins/ddraft/centgeo.c (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/centgeo.c (revision 33253) @@ -0,0 +1,419 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2005 Thomas Nau + * pcb-rnd Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * 2d drafting plugin: center line geometry + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "centgeo.h" + +#include "obj_line.h" +#include "obj_arc.h" +#include +#include +#include "search.h" + +/* Note about all intersection code: same basic algo as in find_geo.c - + see comment for the algo description there */ + +int pcb_intersect_cline_cline(pcb_line_t *Line1, pcb_line_t *Line2, rnd_box_t *ip, double offs[2]) +{ + double s, r; + double line1_dx, line1_dy, line2_dx, line2_dy, point1_dx, point1_dy; + + /* setup some constants */ + line1_dx = Line1->Point2.X - Line1->Point1.X; + line1_dy = Line1->Point2.Y - Line1->Point1.Y; + line2_dx = Line2->Point2.X - Line2->Point1.X; + line2_dy = Line2->Point2.Y - Line2->Point1.Y; + point1_dx = Line1->Point1.X - Line2->Point1.X; + point1_dy = Line1->Point1.Y - Line2->Point1.Y; + + /* set s to cross product of Line1 and the line + * Line1.Point1--Line2.Point1 (as vectors) */ + s = point1_dy * line1_dx - point1_dx * line1_dy; + + /* set r to cross product of both lines (as vectors) */ + r = line1_dx * line2_dy - line1_dy * line2_dx; + + /* No cross product means parallel or overlapping lines */ + if (r == 0.0) { + if (s == 0.0) { /* overlap; r and [0] will be Line2's point offset within Line1; s and [1] will be an endpoint of line1 */ + + r = pcb_cline_pt_offs(Line1, Line2->Point1.X, Line2->Point1.Y); + if ((r < 0.0) || (r > 1.0)) + r = pcb_cline_pt_offs(Line1, Line2->Point2.X, Line2->Point2.Y); + + s = pcb_cline_pt_offs(Line2, Line1->Point1.X, Line1->Point1.Y); + if ((s < 0.0) || (s > 1.0)) + s = 0.0; + else + s = 1.0; + + if (ip != NULL) { + ip->X1 = rnd_round((double)Line1->Point1.X + r * line1_dx); + ip->Y1 = rnd_round((double)Line1->Point1.Y + r * line1_dy); + if (s == 1.0) { + ip->X2 = Line1->Point2.X; + ip->Y2 = Line1->Point2.Y; + } + else { + ip->X2 = Line1->Point1.X; + ip->Y2 = Line1->Point1.Y; + } + } + if (offs != NULL) { + offs[0] = r; + offs[1] = s; + } + return 2; + } + return 0; + } + + s /= r; + r = (point1_dy * line2_dx - point1_dx * line2_dy) / r; + + /* intersection is at least on AB */ + if (r >= 0.0 && r <= 1.0) { + if (s >= 0.0 && s <= 1.0) { + if (ip != NULL) { + ip->X1 = rnd_round((double)Line1->Point1.X + r * line1_dx); + ip->Y1 = rnd_round((double)Line1->Point1.Y + r * line1_dy); + } + if (offs != NULL) + offs[0] = r; + return 1; + } + return 0; + } + + /* intersection is at least on CD */ + /* [removed this case since it always returns rnd_false --asp] */ + return 0; +} + +void pcb_cline_offs(pcb_line_t *line, double offs, rnd_coord_t *dstx, rnd_coord_t *dsty) +{ + double line_dx, line_dy; + + line_dx = line->Point2.X - line->Point1.X; + line_dy = line->Point2.Y - line->Point1.Y; + + *dstx = rnd_round((double)line->Point1.X + offs * line_dx); + *dsty = rnd_round((double)line->Point1.Y + offs * line_dy); +} + +double pcb_cline_pt_offs(pcb_line_t *line, rnd_coord_t px, rnd_coord_t py) +{ + double line_dx, line_dy, pt_dx, pt_dy; + + line_dx = line->Point2.X - line->Point1.X; + line_dy = line->Point2.Y - line->Point1.Y; + + pt_dx = px - line->Point1.X; + pt_dy = py - line->Point1.Y; + + return (line_dx * pt_dx + line_dy * pt_dy) / (line_dx*line_dx + line_dy*line_dy); +} + +static int line_ep(pcb_line_t *line, rnd_coord_t x, rnd_coord_t y) +{ + if ((line->Point1.X == x) && (line->Point1.Y == y)) return 1; + if ((line->Point2.X == x) && (line->Point2.Y == y)) return 1; + return 0; +} + +/* Assumme there will be at two intersection points; load ofs/ix/iy in the + next slot of the result, return from the function if both intersections + found */ +#define append(ofs, ix, iy) \ +do { \ + if (ip != NULL) { \ + if (found == 0) { \ + ip->X1 = ix; \ + ip->Y1 = iy; \ + } \ + else { \ + ip->X2 = ix; \ + ip->Y2 = iy; \ + } \ + } \ + if (offs != NULL) \ + offs[found] = ofs; \ + found++; \ + if (found == 2) \ + return found; \ +} while(0) + +static int intersect_cline_carc(pcb_line_t *Line, pcb_arc_t *Arc, rnd_box_t *ip, double offs[2], int oline) +{ + double dx, dy, dx1, dy1, l, d, r, r2, Radius; + rnd_coord_t ex, ey, ix, iy; + int found = 0; + + dx = Line->Point2.X - Line->Point1.X; + dy = Line->Point2.Y - Line->Point1.Y; + dx1 = Line->Point1.X - Arc->X; + dy1 = Line->Point1.Y - Arc->Y; + l = dx * dx + dy * dy; + d = dx * dy1 - dy * dx1; + d *= d; + + /* use the larger diameter circle first */ + Radius = Arc->Width; + Radius *= Radius; + r2 = Radius * l - d; + /* projection doesn't even intersect circle when r2 < 0 */ + if (r2 < 0) + return 0; + + /* line ends on arc? */ + if (pcb_is_point_on_arc(Line->Point1.X, Line->Point1.Y, 0, Arc)) { + if (oline) + append(0, Line->Point1.X, Line->Point1.Y); + else + append(pcb_carc_pt_offs(Arc, Line->Point1.X, Line->Point1.Y), Line->Point1.X, Line->Point1.Y); + } + if (pcb_is_point_on_arc(Line->Point2.X, Line->Point2.Y, 0, Arc)) { + if (oline) + append(1, Line->Point2.X, Line->Point2.Y); + else + append(pcb_carc_pt_offs(Arc, Line->Point2.X, Line->Point2.Y), Line->Point2.X, Line->Point2.Y); + } + + /* if line is a single point, there is no other way an intersection can happen */ + if (l == 0.0) + return found; + + r2 = sqrt(r2); + Radius = -(dx * dx1 + dy * dy1); + r = (Radius + r2) / l; + + if ((r >= 0) && (r <= 1)) { + ix = rnd_round(Line->Point1.X + r * dx); + iy = rnd_round(Line->Point1.Y + r * dy); + if (!line_ep(Line, ix, iy) && pcb_is_point_on_arc(ix, iy, 1, Arc)) { + if (oline) + append(r, ix, iy); + else + append(pcb_carc_pt_offs(Arc, ix, iy), ix, iy); + } + } + + r = (Radius - r2) / l; + if ((r >= 0) && (r <= 1)) { + ix = rnd_round(Line->Point1.X + r * dx); + iy = rnd_round(Line->Point1.Y + r * dy); + if (!line_ep(Line, ix, iy) && pcb_is_point_on_arc(ix, iy, 1, Arc)) { + if (oline) + append(r, ix, iy); + else + append(pcb_carc_pt_offs(Arc, ix, iy), ix, iy); + } + } + + /* check if an arc end point is on the line */ + pcb_arc_get_end(Arc, 0, &ex, &ey); + if (pcb_is_point_in_line(ex, ey, 1, (pcb_any_line_t *) Line)) { + if (oline) { + r = pcb_cline_pt_offs(Line, ex, ey); + append(r, ex, ey); + } + else + append(0, ex, ey); + } + pcb_arc_get_end(Arc, 1, &ex, &ey); + if (pcb_is_point_in_line(ex, ey, 1, (pcb_any_line_t *) Line)) { + if (oline) { + r = pcb_cline_pt_offs(Line, ex, ey); + append(r, ex, ey); + } + else + append(1, ex, ey); + } + + return found; +} + +int pcb_intersect_cline_carc(pcb_line_t *Line, pcb_arc_t *Arc, rnd_box_t *ip, double offs[2]) +{ + return intersect_cline_carc(Line, Arc, ip, offs, 1); +} + +int pcb_intersect_carc_cline(pcb_arc_t *Arc, pcb_line_t *Line, rnd_box_t *ip, double offs[2]) +{ + return intersect_cline_carc(Line, Arc, ip, offs, 0); +} + + +void pcb_carc_offs(pcb_arc_t *arc, double offs, rnd_coord_t *dstx, rnd_coord_t *dsty) +{ + double ang = (arc->StartAngle + offs * arc->Delta) / RND_RAD_TO_DEG; + + *dstx = arc->X + cos(ang) * arc->Width; + *dsty = arc->Y - sin(ang) * arc->Height; +} + +double pcb_carc_pt_offs(pcb_arc_t *arc, rnd_coord_t px, rnd_coord_t py) +{ + double dx, dy, ang, end; + + /* won't work with elliptical arc - see also pcb_is_point_on_arc */ + dy = (double)(py - arc->Y) / (double)arc->Height; + dx = (double)(px - arc->X) / (double)arc->Width; + ang = (-atan2(dy, dx)) * RND_RAD_TO_DEG + 180; + end = arc->StartAngle + arc->Delta; + + /* normalize the angle: there are multiple ways an arc can cover the same + angle range, e.g. -10+30 and +20-30 - make sure the angle falls between + the start/end (generic) range */ + if (arc->StartAngle < end) { + if (ang > end) + ang -= 360; + if (ang < arc->StartAngle) + ang += 360; + } + else { + if (ang > arc->StartAngle) + ang -= 360; + if (ang < end) + ang += 360; + } + + ang = (ang - arc->StartAngle) / arc->Delta; + + return ang; +} + + +static void get_arc_ends(rnd_coord_t *box, pcb_arc_t *arc) +{ + box[0] = arc->X - arc->Width * cos(RND_M180 * arc->StartAngle); + box[1] = arc->Y + arc->Height * sin(RND_M180 * arc->StartAngle); + box[2] = arc->X - arc->Width * cos(RND_M180 * (arc->StartAngle + arc->Delta)); + box[3] = arc->Y + arc->Height * sin(RND_M180 * (arc->StartAngle + arc->Delta)); +} + +/* reduce arc start angle and delta to 0..360 */ +static void normalize_angles(rnd_angle_t *sa, rnd_angle_t *d) +{ + if (*d < 0) { + *sa += *d; + *d = -*d; + } + if (*d > 360) /* full circle */ + *d = 360; + *sa = rnd_normalize_angle(*sa); +} + +static int radius_crosses_arc(double x, double y, pcb_arc_t *arc) +{ + double alpha = atan2(y - arc->Y, -x + arc->X) * RND_RAD_TO_DEG; + rnd_angle_t sa = arc->StartAngle, d = arc->Delta; + + normalize_angles(&sa, &d); + if (alpha < 0) + alpha += 360; + if (sa <= alpha) + return (sa + d) >= alpha; + return (sa + d - 360) >= alpha; +} + +int pcb_intersect_carc_carc(pcb_arc_t *Arc1, pcb_arc_t *Arc2, rnd_box_t *ip, double offs[2]) +{ + double x, y, dx, dy, r1, r2, a, d, l, dl; + rnd_coord_t pdx, pdy; + rnd_coord_t box[8]; + int found = 0; + + /* try the end points first */ + get_arc_ends(&box[0], Arc1); + get_arc_ends(&box[4], Arc2); + if (pcb_is_point_on_arc(box[0], box[1], 1, Arc2)) append(0, box[0], box[1]); + if (pcb_is_point_on_arc(box[2], box[3], 1, Arc2)) append(1, box[2], box[3]); + if (pcb_is_point_on_arc(box[4], box[5], 1, Arc1)) append(pcb_carc_pt_offs(Arc1, box[4], box[5]), box[4], box[5]); + if (pcb_is_point_on_arc(box[6], box[7], 1, Arc1)) append(pcb_carc_pt_offs(Arc1, box[6], box[7]), box[6], box[7]); + + pdx = Arc2->X - Arc1->X; + pdy = Arc2->Y - Arc1->Y; + dl = rnd_distance(Arc1->X, Arc1->Y, Arc2->X, Arc2->Y); + + /* the original code used to do angle checks for concentric case here but + those cases are already handled by the above endpoint checks. */ + + r1 = Arc1->Width; + r2 = Arc2->Width; + /* arcs centerlines are too far or too near */ + if (dl > r1 + r2 || dl + r1 < r2 || dl + r2 < r1) { + /* check the nearest to the other arc's center point */ + dx = pdx * r1 / dl; + dy = pdy * r1 / dl; + if (dl + r1 < r2) { /* Arc1 inside Arc2 */ + dx = -dx; + dy = -dy; + } + + if (radius_crosses_arc(Arc1->X + dx, Arc1->Y + dy, Arc1) && pcb_is_point_on_arc(Arc1->X + dx, Arc1->Y + dy, 1, Arc2)) + append(pcb_carc_pt_offs(Arc1, Arc1->X + dx, Arc1->Y + dy), Arc1->X + dx, Arc1->Y + dy); + + dx = -pdx * r2 / dl; + dy = -pdy * r2 / dl; + if (dl + r2 < r1) { /* Arc2 inside Arc1 */ + dx = -dx; + dy = -dy; + } + + if (radius_crosses_arc(Arc2->X + dx, Arc2->Y + dy, Arc2) && pcb_is_point_on_arc(Arc2->X + dx, Arc2->Y + dy, 1, Arc1)) + append(pcb_carc_pt_offs(Arc1, Arc2->X + dx, Arc2->Y + dy), Arc2->X + dx, Arc2->Y + dy); + } + + l = dl * dl; + r1 *= r1; + r2 *= r2; + a = 0.5 * (r1 - r2 + l) / l; + r1 = r1 / l; + d = r1 - a * a; + /* the circles are too far apart to touch or probably just touch: + check the nearest point */ + if (d < 0) + d = 0; + else + d = sqrt(d); + x = Arc1->X + a * pdx; + y = Arc1->Y + a * pdy; + dx = d * pdx; + dy = d * pdy; + if ((radius_crosses_arc(x + dy, y - dx, Arc1) && pcb_is_point_on_arc(x + dy, y - dx, 1, Arc2)) || (radius_crosses_arc(x + dy, y - dx, Arc2) && pcb_is_point_on_arc(x + dy, y - dx, 1, Arc1))) + append(pcb_carc_pt_offs(Arc1, x + dy, y - dx), x + dy, y - dx); + + if ((radius_crosses_arc(x - dy, y + dx, Arc1) && pcb_is_point_on_arc(x - dy, y + dx, 1, Arc2)) || (radius_crosses_arc(x - dy, y + dx, Arc2) && pcb_is_point_on_arc(x - dy, y + dx, 1, Arc1))) + append(pcb_carc_pt_offs(Arc1, x - dy, y + dx), x - dy, y + dx); + + return found; +} + Index: tags/2.3.0/src_plugins/ddraft/centgeo.h =================================================================== --- tags/2.3.0/src_plugins/ddraft/centgeo.h (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/centgeo.h (revision 33253) @@ -0,0 +1,41 @@ +#ifndef PCB_CENTGEO_H +#define PCB_CENTGEO_H + +#include "obj_line.h" + +/*** Calculate centerpoint intersections of objects (thickness ignored) ***/ + +/* Calculate the intersection point(s) of two lines and store them in ip + and/or offs (on Line1) if they are not NULL. Returns: + 0 = no intersection + 1 = one intersection (X1;Y1 of ip is loaded) + 2 = overlapping segments (overlap endpoitns are stored in X1;Y1 and X2;Y2 of ip) */ +int pcb_intersect_cline_cline(pcb_line_t *Line1, pcb_line_t *Line2, rnd_box_t *ip, double offs[2]); + +/* Calculate the intersection point(s) of a lines and an arc and store them + in ip and/or offs if they are not NULL. Returns: + 0 = no intersection + 1 = one intersection (X1;Y1 of ip is loaded) + 2 = two intersections (stored in X1;Y1 and X2;Y2 of ip) */ +int pcb_intersect_cline_carc(pcb_line_t *Line, pcb_arc_t *Arc, rnd_box_t *ip, double offs_line[2]); +int pcb_intersect_carc_cline(pcb_arc_t *Arc, pcb_line_t *Line, rnd_box_t *ip, double offs_arc[2]); + +/* Calculate the intersection point(s) of two arcs and store them in ip + and/or offs (on Line1) if they are not NULL. Returns: + 0 = no intersection + 1 = one intersection (X1;Y1 of ip is loaded) + 2 = two intersections or overlapping segments (overlap endpoints are stored in X1;Y1 and X2;Y2 of ip) */ +int pcb_intersect_carc_carc(pcb_arc_t *Arc1, pcb_arc_t *Arc2, rnd_box_t *ip, double offs[2]); + + +/* Calculate the point on an object corresponding to a [0..1] offset and store + the result in dstx;dsty. */ +void pcb_cline_offs(pcb_line_t *line, double offs, rnd_coord_t *dstx, rnd_coord_t *dsty); +void pcb_carc_offs(pcb_arc_t *arc, double offs, rnd_coord_t *dstx, rnd_coord_t *dsty); + +/* Project a point (px;py) onto an object and return the offset from point1 */ +double pcb_cline_pt_offs(pcb_line_t *line, rnd_coord_t px, rnd_coord_t py); +double pcb_carc_pt_offs(pcb_arc_t *arc, rnd_coord_t px, rnd_coord_t py); + + +#endif Index: tags/2.3.0/src_plugins/ddraft/cli.c =================================================================== --- tags/2.3.0/src_plugins/ddraft/cli.c (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/cli.c (revision 33253) @@ -0,0 +1,582 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * 2d drafting plugin + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include "conf_core.h" +#include + +#define CLI_MAX_INS_LEN 128 + +typedef struct cli_node_s cli_node_t; + +typedef struct { + const char *name; + int (*exec)(char *line, int argc, cli_node_t *argv); /* command line entered (finished, accepted) */ + int (*click)(char *line, int cursor, int argc, cli_node_t *argv); /* user clicked on the GUI while editing the command line */ + int (*tab)(char *line, int cursor, int argc, cli_node_t *argv); /* tab completion */ + int (*edit)(char *line, int cursor, int argc, cli_node_t *argv); /* called after editing the line or moving the cursor */ +} ddraft_op_t; + +typedef enum cli_ntype_e { + CLI_INVALID, + CLI_FROM, + CLI_TO, + CLI_ANGLE, + CLI_ABSOLUTE, + CLI_RELATIVE, + + CLI_PERP, + CLI_PARAL, + CLI_TANGENT, + CLI_CENTER, + CLI_START, + CLI_END, + + CLI_DIST, + CLI_OFFS, + CLI_COORD +} cli_ntype_t; + +#define case_object \ + case CLI_PERP: case CLI_PARAL: case CLI_TANGENT: case CLI_CENTER: \ + case CLI_START: case CLI_END + +typedef struct cli_ntname_s { + const char *name; + cli_ntype_t type; +} cli_ntname_t; + +static const cli_ntname_t cli_tnames[] = { + {"from", CLI_FROM}, + {"to", CLI_TO}, + {"angle", CLI_ANGLE}, + {"absolute", CLI_ABSOLUTE}, + {"relative", CLI_RELATIVE}, + {"perpendicular", CLI_PERP}, + {"parallel", CLI_PARAL}, + {"tangential", CLI_TANGENT}, + {"center", CLI_CENTER}, + {"start", CLI_START}, + {"end", CLI_END}, + {"coord", CLI_COORD}, + {"distance", CLI_DIST}, + {"length", CLI_DIST}, + {"offset", CLI_OFFS}, + {NULL, 0} +}; + +struct cli_node_s { + cli_ntype_t type; + int begin, end; /* cursor pos */ + int invalid; + + rnd_coord_t x, y, dist; + rnd_angle_t angle, offs; + rnd_cardinal_t id; +}; + +static const cli_ntype_t find_type(const char *type, int typelen) +{ + const cli_ntname_t *p, *found = NULL; + + if (typelen < 1) + return CLI_INVALID; + + for(p = cli_tnames; p->name != NULL; p++) { + if (rnd_strncasecmp(p->name, type, typelen) == 0) { + if (found != NULL) + return CLI_INVALID; /* multiple match */ + found = p; + } + } + + if (found == NULL) + return CLI_INVALID; + return found->type; +} + +static const char *find_rev_type(cli_ntype_t type) +{ + const cli_ntname_t *p; + + for(p = cli_tnames; p->name != NULL; p++) + if (p->type == type) + return p->name; + + return "INVALID"; +} + +#define APPEND(type_, end_) \ +do { \ + memset(&dst[i], 0, sizeof(cli_node_t)); \ + dst[i].type = type_; \ + dst[i].begin = s - line; \ + dst[i].end = end_ - line; \ + i++; \ + if (i >= dstlen) \ + return i; \ +} while(0) + +#define iscrd(c) ((c == '+') || (c == '-') || (c == '.') || isdigit(c)) +#define last_type ((i > 0) ? dst[i-1].type : CLI_INVALID) + +static int cli_parse(cli_node_t *dst, int dstlen, const char *line) +{ + char tmp[128]; + char *sep, *s = strchr(line, ' '), *next; /* skip the instruction */ + int i; + rnd_bool succ; + + if (s == NULL) + return 0; + + for(i = 0;; s = next) { + while(isspace(*s)) s++; + if (*s == '\0') + break; + switch(*s) { + case '@': + next = s+1; + APPEND(CLI_RELATIVE, next); + continue; + case '*': + next = s+1; + APPEND(CLI_ABSOLUTE, next); + continue; + case '<': + next = s+1; + APPEND(CLI_ANGLE, next); + continue; + case '%': + APPEND(CLI_OFFS, next); + dst[i-1].offs = strtod(s+1, &next); + dst[i-1].invalid = (next == s); + continue; + case '~': + next = s+1; + APPEND(CLI_DIST, next); + break; + default: + next = strchr(s, ' '); + if (next == NULL) + next = s+strlen(s); + if (iscrd(*s)) { + switch(last_type) { + case CLI_INVALID: + case CLI_FROM: + case CLI_TO: + APPEND(CLI_ABSOLUTE, s); + case CLI_RELATIVE: + case CLI_ABSOLUTE: + APPEND(CLI_COORD, next); + sep = strchr(s, ','); + if ((sep == NULL) || ((sep - s) > sizeof(tmp)-2)) { + dst[i-1].invalid = 1; + break; + } + memcpy(tmp, s, sep-s); + tmp[sep-s] = '\0'; + dst[i-1].x = rnd_get_value_ex(tmp, NULL, NULL, NULL, rnd_conf.editor.grid_unit->suffix, &succ); + if (!succ) + dst[i-1].invalid = 1; + + sep++; + if ((next - sep) > sizeof(tmp)-2) { + dst[i-1].invalid = 1; + break; + } + memcpy(tmp, sep, next-sep); + tmp[next-sep] = '\0'; + dst[i-1].y = rnd_get_value_ex(tmp, NULL, NULL, NULL, rnd_conf.editor.grid_unit->suffix, &succ); + if (!succ) + dst[i-1].invalid = 1; + break; + case CLI_DIST: + dst[i-1].dist = rnd_get_value_ex(s, NULL, NULL, NULL, rnd_conf.editor.grid_unit->suffix, &succ); + dst[i-1].invalid = !succ; + dst[i-1].end = next - line; + break; + case CLI_ANGLE: + dst[i-1].angle = strtod(s, &next); + dst[i-1].invalid = (dst[i-1].angle > 360.0) || (dst[i-1].angle < -360.0); + dst[i-1].end = next - line; + break; + case_object : + dst[i-1].id = strtol(s, &next, 10); + dst[i-1].end = next - line; + break; + default: + APPEND(CLI_INVALID, next); + } + } + else + APPEND(find_type(s, next-s), next); + } + if ((next == NULL) || (*next == '\0')) + break; + } + + return i; +} + +#undef APPEND +#undef iscrd +#undef last_type + +static int cli_cursor_arg(int argc, cli_node_t *argv, int cursor) +{ + int n; + for(n = 0; n < argc; n++) + if ((cursor >= argv[n].begin) && (cursor <= argv[n].end)) + return n; + return -1; +} + +static void cli_str_remove(char *str, int from, int to) +{ + if (from >= to) + return; + memmove(str+from, str+to, strlen(str+to)+1); +} + + +static int cli_str_insert(char *str, int from, char *ins, int enforce_space_before) +{ + int inslen = strlen(ins), remain = strlen(str+from), extra = 0; + if (enforce_space_before && (str[from-1] != ' ')) + extra=1; + memmove(str+from+inslen+extra, str+from, remain+1); + if (extra) + str[from] = ' '; + memcpy(str+from+extra, ins, inslen); + return from + inslen + extra; +} + +static int cli_apply_coord(cli_node_t *argv, int start, int end, rnd_coord_t *ox, rnd_coord_t *oy, int annot) +{ + int n, relative = 0, have_angle = 0, have_dist = 0, len = (start > 1); + double angle = 0, dist = 0, lx, ly, x = *ox, y = *oy; + rnd_coord_t tx, ty; + + for(n = start; n < end; n++) { + int moved = 0; + pcb_any_obj_t *to = NULL; + + /* look up the target object for instructions referencing an object */ + switch(argv[n].type) { + case_object : + if (argv[n].id > 0) { + void *p1, *p2, *p3; + int res; + res = pcb_search_obj_by_id_(PCB->Data, &p1, &p2, &p3, argv[n].id, PCB_OBJ_LINE); + if (res == 0) + res = pcb_search_obj_by_id_(PCB->Data, &p1, &p2, &p3, argv[n].id, PCB_OBJ_ARC); + if (res == 0) + res = pcb_search_obj_by_id_(PCB->Data, &p1, &p2, &p3, argv[n].id, PCB_OBJ_POLY); + if (res != 0) + to = p2; + } + if (to == NULL) + return -1; + break; + default:; + } + + switch(argv[n].type) { + case CLI_ABSOLUTE: + relative = 0; + len = 0; + lx = ly = 0; + break; + case CLI_RELATIVE: + relative = 1; + break; + + case CLI_ANGLE: + have_angle = 1; + if (relative) { + angle += argv[n].angle; + relative = 0; + } + else + angle = argv[n].angle; + goto apply; + + case CLI_DIST: + have_dist = 1; + if (relative) { + dist += argv[n].dist; + relative = 0; + } + else + dist = argv[n].dist; + goto apply; + + case CLI_COORD: + if (relative) { + x += argv[n].x; + y += argv[n].y; + relative = 0; + moved = 1; + } + else { + x = argv[n].x; + y = argv[n].y; + len = 0; + lx = ly = 0; + moved = 1; + } + break; + + case CLI_PERP: + rnd_message(RND_MSG_ERROR, "perp not yet implemented\n"); + return -1; + case CLI_PARAL: + rnd_message(RND_MSG_ERROR, "paral not yet implemented\n"); + return -1; + case CLI_TANGENT: + rnd_message(RND_MSG_ERROR, "tangent not yet implemented\n"); + return -1; + + case CLI_CENTER: + switch(to->type) { + case PCB_OBJ_LINE: + x = (((pcb_line_t *)to)->Point1.X + ((pcb_line_t *)to)->Point2.X)/2; + y = (((pcb_line_t *)to)->Point1.Y + ((pcb_line_t *)to)->Point2.Y)/2; + break; + case PCB_OBJ_ARC: + x = ((pcb_arc_t *)to)->X; + y = ((pcb_arc_t *)to)->Y; + break; + default: + return -1; + } + break; + case CLI_START: + switch(to->type) { + case PCB_OBJ_LINE: + x = ((pcb_line_t *)to)->Point1.X; + y = ((pcb_line_t *)to)->Point1.Y; + break; + case PCB_OBJ_ARC: + pcb_arc_get_end((pcb_arc_t *)to, 0, &tx, &ty); + x = tx; + y = ty; + break; + default: + return -1; + } + break; + case CLI_END: + switch(to->type) { + case PCB_OBJ_LINE: + x = ((pcb_line_t *)to)->Point2.X; + y = ((pcb_line_t *)to)->Point2.Y; + break; + case PCB_OBJ_ARC: + pcb_arc_get_end((pcb_arc_t *)to, 1, &tx, &ty); + x = tx; + y = ty; + break; + default: + return -1; + } + break; + + default: + goto over; + apply:; + if (have_angle && have_dist) { + x += cos(angle / RND_RAD_TO_DEG) * dist; + y += sin(angle / RND_RAD_TO_DEG) * dist; + have_angle = have_dist = 0; + moved = 1; + } + break; + } + if (argv[n].invalid) + return -1; + + if (moved) { + if ((annot) && (len > 0)) { + rnd_coord_t *c = vtc0_alloc_append(&pcb_ddraft_attached.annot_lines, 4); + c[0] = rnd_round(lx); + c[1] = rnd_round(ly); + c[2] = rnd_round(x); + c[3] = rnd_round(y); + } + angle = atan2(y - ly, x - lx) * RND_RAD_TO_DEG; + lx = x; + ly = y; + len++; + } + } + + over:; + if (have_angle || have_dist) /* could not apply */ + return -1; + *ox = rnd_round(x); + *oy = rnd_round(y); + return n; +} + +static void cli_print_args(int argc, cli_node_t *argv) +{ + int n; + for(n = 0; n < argc; n++) { + rnd_trace(" [%d] %s/%d {%d..%d}", n, find_rev_type(argv[n].type), argv[n].type, argv[n].begin, argv[n].end); + if (!argv[n].invalid) { + switch(argv[n].type) { + case CLI_COORD: rnd_trace(": %$mm,%$mm", argv[n].x, argv[n].y); break; + case CLI_ANGLE: rnd_trace(": %f", argv[n].angle); break; + case CLI_DIST: rnd_trace(": %$mm", argv[n].dist); break; + case CLI_OFFS: rnd_trace(": %f", argv[n].offs); break; + case_object: rnd_trace(": %ld", (long)argv[n].id); break; + default:; + } + rnd_trace("\n"); + } + else + rnd_trace(": INVALID\n"); + } +} + +#include "cli_line.c" + +static const ddraft_op_t ddraft_ops[] = { + {"line", line_exec, line_click, line_tab, line_edit}, + {NULL, NULL, NULL, NULL, NULL} +}; + +static const ddraft_op_t *find_op(const char *op, int oplen) +{ + const ddraft_op_t *p, *found = NULL; + + if (oplen < 1) + return NULL; + + for(p = ddraft_ops; p->name != NULL; p++) { + if (rnd_strncasecmp(p->name, op, oplen) == 0) { + if (found != NULL) + return NULL; /* multiple match */ + found = p; + } + } + + return found; +} + +static const char pcb_acts_ddraft[] = "ddraft([command])"; +static const char pcb_acth_ddraft[] = "Enter 2d drafting CLI mode or execute command"; +static fgw_error_t pcb_act_ddraft(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char *args, *cmd, *line, sline[1024], *op; + const char *cline = NULL; + int cursor, len, oplen; + const ddraft_op_t *opp; + cli_node_t nd[128]; + int ndlen; + + if (argc == 1) { + rnd_cli_enter("ddraft", "ddraft"); + rnd_tool_select_by_id(&PCB->hidlib, pcb_ddraft_tool); + RND_ACT_IRES(0); + return 0; + } + + RND_ACT_CONVARG(1, FGW_STR, ddraft, cmd = argv[1].val.str); + if (strcmp(cmd, "/exit") == 0) { + rnd_cli_leave(); + RND_ACT_IRES(0); + return 0; + } + + /* make a safe copy of the command line, either on stack or on heap if too large */ + if ((cmd != NULL) && (*cmd != '/')) + cline = cmd; + else + cline = rnd_hid_command_entry(NULL, &cursor); + if (cline == NULL) + cline = ""; + + while(isspace(*cline)) cline++; + if ((*cline == '\n') || (*cline == '#') || (*cline == '\0')) { /* empty or comment */ + RND_ACT_IRES(0); + return 0; + } + + len = strlen(cline); + if (len >= sizeof(cline) - CLI_MAX_INS_LEN) + line = malloc(len + 1 + CLI_MAX_INS_LEN); + else + line = sline; + memcpy(line, cline, len+1); + + /* split op and arguments; recalculate cursor so it's within the arguments */ + op = line; + args = strpbrk(op, " \t"); + if (args != NULL) + oplen = args - op; + else + oplen = len; + + /* look up op */ + opp = find_op(op, oplen); + if (opp == NULL) { + if (strcmp(cmd, "/edit") != 0) + rnd_message(RND_MSG_ERROR, "ddraft: unknown operator '%s'\n", op); + RND_ACT_IRES(-1); + goto ret0; + } + + reparse:; + ndlen = cli_parse(nd, sizeof(nd) / sizeof(nd[0]), line); + + if (*cmd == '/') { + if (strcmp(cmd, "/click") == 0) { + RND_ACT_IRES(opp->click(line, cursor, ndlen, nd)); + cmd = "/edit"; + goto reparse; + } + else if (strcmp(cmd, "/tab") == 0) + RND_ACT_IRES(opp->tab(line, cursor, ndlen, nd)); + else if (strcmp(cmd, "/edit") == 0) + RND_ACT_IRES(opp->edit(line, cursor, ndlen, nd)); + else + RND_ACT_IRES(0); /* ignore anything unhandled */ + goto ret0; + } + + RND_ACT_IRES(opp->exec(line, ndlen, nd)); + + ret0:; + if (line != sline) + free(line); + return 0; +} Index: tags/2.3.0/src_plugins/ddraft/cli_line.c =================================================================== --- tags/2.3.0/src_plugins/ddraft/cli_line.c (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/cli_line.c (revision 33253) @@ -0,0 +1,223 @@ +static int line_parse(char *line, int argc, cli_node_t *argv, rnd_box_t *box, int verbose, int annot) +{ + int n = 0; + + if (argv[n].type == CLI_FROM) + n++; + else if (argv[n].type == CLI_TO) { + rnd_message(RND_MSG_ERROR, "Incremental line drawing is not yet supported\n"); + return -1; + } + n = cli_apply_coord(argv, n, argc, &box->X1, &box->Y1, annot); + if (n < 0) { + if (verbose) + rnd_message(RND_MSG_ERROR, "Invalid 'from' coord\n"); + return -1; + } + if (argv[n].type != CLI_TO) { + if (verbose) + rnd_message(RND_MSG_ERROR, "Missing 'to'\n"); + return -1; + } + n++; + box->X2 = box->X1; + box->Y2 = box->Y1; + n = cli_apply_coord(argv, n, argc, &box->X2, &box->Y2, annot); + if (n < 0) { + if (verbose) + rnd_message(RND_MSG_ERROR, "Invalid 'to' coord\n"); + return -1; + } + if (n != argc) { + if (verbose) + rnd_message(RND_MSG_ERROR, "Excess tokens after the to coord\n"); + return -1; + } + return 0; +} + +static int line_exec(char *line, int argc, cli_node_t *argv) +{ + int res; + rnd_box_t box; + + rnd_trace("line e: '%s'\n", line); + + memset(&box, 0, sizeof(box)); + res = line_parse(line, argc, argv, &box, 1, 0); + if (res == 0) { + rnd_trace("line_exec: %mm;%mm -> %mm;%mm\n", box.X1, box.Y1, box.X2, box.Y2); + pcb_line_new(PCB_CURRLAYER(PCB), box.X1, box.Y1, box.X2, box.Y2, + conf_core.design.line_thickness, 2 * conf_core.design.clearance, + pcb_flag_make(conf_core.editor.clear_line ? PCB_FLAG_CLEARLINE : 0)); + } + pcb_ddraft_attached_reset(); + return res; +} + +static int line_edit(char *line, int cursor, int argc, cli_node_t *argv) +{ + int res; + rnd_box_t box; + + pcb_ddraft_attached_reset(); + + if (rnd_tool_next_id != pcb_ddraft_tool) + rnd_tool_select_by_id(&PCB->hidlib, pcb_ddraft_tool); + + rnd_trace("line e: '%s':%d\n", line, cursor); + memset(&box, 0, sizeof(box)); + res = line_parse(line, argc, argv, &box, 0, 1); + if (res == 0) { + pcb_ddraft_attached.line_valid = 1; + pcb_ddraft_attached.line.Point1.X = box.X1; + pcb_ddraft_attached.line.Point1.Y = box.Y1; + pcb_ddraft_attached.line.Point2.X = box.X2; + pcb_ddraft_attached.line.Point2.Y = box.Y2; + rnd_gui->invalidate_all(rnd_gui); + } + return res; +} + +static int get_rel_coord(int argc, cli_node_t *argv, int argn, rnd_coord_t *ox, rnd_coord_t *oy) +{ + int nto, res; + + for(nto = 0; nto < argc; nto++) + if (argv[nto].type == CLI_TO) + break; + + *ox = *oy = 0; + res = 0; + if (argv[res].type == CLI_FROM) + res++; + if (argn < nto) { + res = cli_apply_coord(argv, res, argn, ox, oy, 0); + } + else { + res = cli_apply_coord(argv, res, nto, ox, oy, 0); /* 'to' may be relative to 'from', so eval 'from' first */ + res |= cli_apply_coord(argv, nto+1, argn, ox, oy, 0); + } + + return res; +} + +static int line_click(char *line, int cursor, int argc, cli_node_t *argv) +{ + int argn = cli_cursor_arg(argc, argv, cursor); + int replace = 0, by, res; + rnd_coord_t ox, oy; + char buff[CLI_MAX_INS_LEN]; + + rnd_trace("line c: '%s':%d (argn=%d)\n", line, cursor, argn); + cli_print_args(argc, argv); + + if (argn < 0) { + /* at the end */ + argn = argc - 1; + if (argn < 0) { + /* empty arg list */ + rnd_snprintf(buff, sizeof(buff), " from %.08$$mm,%.08$$mm", pcb_crosshair.X, pcb_crosshair.Y); + printf("append: '%s'\n", buff); + cursor = cli_str_insert(line, strlen(line), buff, 1); + goto update; + } + } + + *buff = '\0'; + by = argn; + + + retry:; + + switch(argv[by].type) { + case CLI_COORD: + if (by > 0) { + by--; + replace = 1; + goto retry; + } + /* fall through: when clicked at the first coord */ + case CLI_ABSOLUTE: + case CLI_FROM: + case CLI_TO: + rnd_trace("abs"); + rnd_snprintf(buff, sizeof(buff), "%.08$$mm,%.08$$mm", pcb_crosshair.X, pcb_crosshair.Y); + goto maybe_replace_after; + break; + case CLI_RELATIVE: + res = get_rel_coord(argc, argv, argn, &ox, &oy); + if (res < 0) { + rnd_message(RND_MSG_ERROR, "Failed to interpret coords already entered\n"); + return 0; + } + rnd_trace("rel from %$mm,%$mm", ox, oy); + rnd_snprintf(buff, sizeof(buff), "%.08$$mm,%.08$$mm", pcb_crosshair.X - ox, pcb_crosshair.Y - oy); + maybe_replace_after:; + if ((by+1 < argc) && (argv[by+1].type == CLI_COORD)) { + argn = by+1; + replace = 1; + } + break; + case CLI_ANGLE: + res = get_rel_coord(argc, argv, argn, &ox, &oy); + if (res < 0) { + rnd_message(RND_MSG_ERROR, "Failed to interpret coords already entered\n"); + return 0; + } + replace=1; + rnd_snprintf(buff, sizeof(buff), "<%f", atan2(pcb_crosshair.Y - oy, pcb_crosshair.X - ox) * RND_RAD_TO_DEG); + break; + case CLI_DIST: + res = get_rel_coord(argc, argv, argn, &ox, &oy); + if (res < 0) { + rnd_message(RND_MSG_ERROR, "Failed to interpret coords already entered\n"); + return 0; + } + replace=1; + rnd_snprintf(buff, sizeof(buff), "~%.08$$mm", rnd_distance(pcb_crosshair.X, pcb_crosshair.Y, ox, oy)); + break; + case_object: ; + { + void *p1, *p2, *p3; + pcb_any_obj_t *o; + if (pcb_search_screen(pcb_crosshair.X, pcb_crosshair.Y, PCB_OBJ_LINE | PCB_OBJ_ARC, &p1, &p2, &p3) == 0) + return 0; + o = p2; + replace=1; + rnd_snprintf(buff, sizeof(buff), "%s %ld", find_rev_type(argv[by].type), (long)o->ID); + } + break; + default: + return 0; + } + + if (*buff == '\0') { + rnd_trace("nope...\n"); + return 0; + } + + if (replace) { + rnd_trace(" replace %d: '%s'\n", argn, buff); + cli_str_remove(line, argv[argn].begin, argv[argn].end); + cursor = cli_str_insert(line, argv[argn].begin, buff, 1); + + } + else { + rnd_trace(" insert-after %d: '%s'\n", argn, buff); + cursor = cli_str_insert(line, argv[argn].end, buff, 1); + } + +rnd_trace("line='%s'\n", line); + update:; + rnd_hid_command_entry(line, &cursor); + + return 0; +} + +static int line_tab(char *line, int cursor, int argc, cli_node_t *argv) +{ + rnd_trace("line t: '%s':%d\n", line, cursor); + return -1; +} + Index: tags/2.3.0/src_plugins/ddraft/constraint.c =================================================================== --- tags/2.3.0/src_plugins/ddraft/constraint.c (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/constraint.c (revision 33253) @@ -0,0 +1,183 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * 2d drafting plugin: trim objects + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "crosshair.h" +#include "obj_line.h" +#include + +typedef struct { + double line_angle[32], move_angle[32]; + rnd_coord_t line_length[32], move_length[32]; + double line_angle_mod, move_angle_mod; + rnd_coord_t line_length_mod, move_length_mod; + + int line_angle_len, line_length_len, move_angle_len, move_length_len; +} ddraft_cnst_t; + +static ddraft_cnst_t cons; + +static int find_best_angle(double *out_ang, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, double *angles, int anglen, double angle_mod) +{ + double diff, ang, best_diff, target_ang; + int n, best; + + ang = atan2(y2 - y1, x2 - x1) * RND_RAD_TO_DEG; + + if (anglen > 0) { + /* find the best matching constraint angle */ + best = -1; + best_diff = 1000.0; + for(n = 0; n < anglen; n++) { + if (angles[n] < 180) + diff = fabs(ang - angles[n]); + else + diff = fabs(ang + (angles[n]-180)); + if (diff < best_diff) { + best_diff = diff; + best = n; + } + } + if (best < 0) + return -1; + + target_ang = angles[best]; + } + else + target_ang = ang; + + if (angle_mod > 0) + target_ang = floor(target_ang / angle_mod) * angle_mod; + + target_ang /= RND_RAD_TO_DEG; + *out_ang = target_ang; + return 0; +} + +static int find_best_length(double *out_len, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t *lengths, int lengthlen, rnd_coord_t length_mod) +{ + double len, best_diff, diff, target_len; + int n, best; + + len = rnd_distance(x1, y1, x2, y2); + + if (lengthlen > 0) { + /* find the best matching constraint length */ + best = -1; + best_diff = RND_COORD_MAX; + for(n = 0; n < lengthlen; n++) { + diff = fabs(len - lengths[n]); + if (diff < best_diff) { + best_diff = diff; + best = n; + } + } + if (best < 0) + return -1; + + target_len = lengths[best]; + } + else + target_len = len; + + if (length_mod > 0) + target_len = floor(target_len / (double)length_mod) * (double)length_mod; + + *out_len = target_len; + return 0; +} + +static void cnst_line_anglen(ddraft_cnst_t *cn) +{ + double target_ang, dx, dy, target_len; + pcb_route_object_t *line; + int res; + + if (((cn->line_angle_len == 0) && (cn->line_length_len == 0) && (cn->line_angle_mod <= 0) && (cn->line_length_mod <= 0)) || (pcb_crosshair.Route.size < 1)) + return; + + line = &pcb_crosshair.Route.objects[pcb_crosshair.Route.size-1]; + if (line->type != PCB_OBJ_LINE) + return; + + res = find_best_angle(&target_ang, + line->point1.X, line->point1.Y, pcb_crosshair.X, pcb_crosshair.Y, + cn->line_angle, cn->line_angle_len, cn->line_angle_mod); + if (res < 0) return; + + res = find_best_length(&target_len, + line->point1.X, line->point1.Y, pcb_crosshair.X, pcb_crosshair.Y, + cn->line_length, cn->line_length_len, cn->line_length_mod); + if (res < 0) return; + + dx = target_len * cos(target_ang); + dy = target_len * sin(target_ang); + + line->point2.X = line->point1.X + dx; + line->point2.Y = line->point1.Y + dy; +} + +static void cnst_line2(ddraft_cnst_t *cn) +{ + cnst_line_anglen(cn); +} + +static void cnst_move(ddraft_cnst_t *cn) +{ + double target_ang, dx, dy, target_len; + int res; + + if (((cn->move_angle_len == 0) && (cn->move_length_len == 0) && (cn->move_angle_mod <= 0) && (cn->move_length_mod <= 0))) + return; + + res = find_best_angle(&target_ang, + pcb_crosshair.AttachedObject.X, pcb_crosshair.AttachedObject.Y, pcb_crosshair.X, pcb_crosshair.Y, + cn->move_angle, cn->move_angle_len, cn->move_angle_mod); + if (res < 0) return; + + res = find_best_length(&target_len, + pcb_crosshair.AttachedObject.X, pcb_crosshair.AttachedObject.Y, pcb_crosshair.X, pcb_crosshair.Y, + cn->move_length, cn->move_length_len, cn->move_length_mod); + if (res < 0) return; + + dx = target_len * cos(target_ang); + dy = target_len * sin(target_ang); + + pcb_crosshair.AttachedObject.tx = pcb_crosshair.AttachedObject.X + dx; + pcb_crosshair.AttachedObject.ty = pcb_crosshair.AttachedObject.Y + dy; +} + +static void cnst_enforce(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((pcb_crosshair.AttachedLine.State == PCB_CH_STATE_SECOND) || (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_THIRD)) + cnst_line2(&cons); + else if (pcb_crosshair.AttachedObject.State == PCB_CH_STATE_SECOND) /* normal d&d move or copy */ + cnst_move(&cons); + else if (pcb_crosshair_note.Moving) /* selected copy (buffer mode) */ + cnst_move(&cons); + +} Index: tags/2.3.0/src_plugins/ddraft/constraint_gui.c =================================================================== --- tags/2.3.0/src_plugins/ddraft/constraint_gui.c (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/constraint_gui.c (revision 33253) @@ -0,0 +1,332 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * 2d drafting plugin: trim objects + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ + + /* widget IDs */ + int alldir; + int line_angle, move_angle; + int line_length, move_length; + int line_angle_mod, move_angle_mod; + int line_length_mod, move_length_mod; + + int inhibit_confchg; +} cnstgui_ctx_t; + +cnstgui_ctx_t cnstgui_ctx; + +static void cnstgui_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + cnstgui_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(cnstgui_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + + +#define c2g_array(name, fmt) \ +do { \ + int n, l, len = sizeof(buff)-1; \ + char *end = buff; \ + *end = 0; \ + for(n = 0; n < cons.name ## _len; n++) { \ + if (n > 0) { \ + *end++ = ' '; \ + len--; \ + } \ + l = rnd_snprintf(end, len, fmt, cons.name[n]); \ + len -= l; \ + end += l; \ + } \ + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.name, str, rnd_strdup(buff)); \ +} while(0) + +#define c2g_float(name) \ +do { \ + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.name, dbl, cons.name); \ +} while(0) + +#define c2g_coord(name) \ +do { \ + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.name, crd, cons.name); \ +} while(0) + +/* copy all cons fields into the GUI struct */ +static void cons_changed(void) +{ + char buff[1024]; + + c2g_array(line_angle, "%f"); + c2g_float(line_angle_mod); + c2g_array(line_length, "%.08$$mH"); + c2g_coord(line_length_mod); + + c2g_array(move_angle, "%f"); + c2g_float(move_angle_mod); + c2g_array(move_length, "%.08$$mH"); + c2g_coord(move_length_mod); +} + +#define g2c_array(name, conv) \ +do { \ + const char *inp = cnstgui_ctx.dlg[cnstgui_ctx.name].val.str; \ + char *curr, *next; \ + cons.name ## _len = 0; \ + if (inp == NULL) break; \ + strncpy(buff, inp, sizeof(buff)); \ + for(curr = buff; curr != NULL; curr = next) { \ + while(isspace(*curr)) curr++; \ + if (*curr == '\0') break; \ + next = strpbrk(curr, ",; "); \ + if (next != NULL) { \ + *next = '\0'; \ + next++; \ + while(isspace(*next)) next++; \ + } \ + cons.name[cons.name ## _len++] = conv; \ + } \ +} while(0) + +#define g2c_scalar(name, valty) \ +do { \ + cons.name = cnstgui_ctx.dlg[cnstgui_ctx.name].val.valty; \ +} while(0) + + +/* copy all GUI fields into the cons struct */ +static void gui2cons(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + char *end, buff[1024]; + rnd_bool succ; + + g2c_array(line_angle, strtod(curr, &end)); + g2c_scalar(line_angle_mod, dbl); + g2c_array(line_length, rnd_get_value(curr, NULL, NULL, &succ)); + g2c_scalar(line_length_mod, crd); + + g2c_array(move_angle, strtod(curr, &end)); + g2c_scalar(move_angle_mod, dbl); + g2c_array(move_length, rnd_get_value(curr, NULL, NULL, &succ)); + g2c_scalar(move_length_mod, crd); +} + +static void reset_line(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.line_angle, str, rnd_strdup("")); + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.line_angle_mod, dbl, 0); + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.line_length, str, rnd_strdup("")); + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.line_length_mod, crd, 0); + gui2cons(hid_ctx, caller_data, attr); +} + +static void reset_move(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.move_angle, str, rnd_strdup("")); + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.move_angle_mod, dbl, 0); + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.move_length, str, rnd_strdup("")); + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.move_length_mod, crd, 0); + gui2cons(hid_ctx, caller_data, attr); +} + +static void set_paral(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&PCB->hidlib, "paral", NULL); +} + +static void set_perp(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&PCB->hidlib, "perp", NULL); +} + + +static void set_tang(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&PCB->hidlib, "tang", NULL); +} + +void cons_gui_confchg(rnd_conf_native_t *cfg, int arr_idx) +{ + if (!cnstgui_ctx.active || cnstgui_ctx.inhibit_confchg) + return; + + cnstgui_ctx.inhibit_confchg++; + RND_DAD_SET_VALUE(cnstgui_ctx.dlg_hid_ctx, cnstgui_ctx.alldir, lng, conf_core.editor.all_direction_lines); + cnstgui_ctx.inhibit_confchg--; +} + +static void set_alldir(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + const char *nv; + if (cnstgui_ctx.inhibit_confchg) + return; + + cnstgui_ctx.inhibit_confchg++; + nv = (cnstgui_ctx.dlg[cnstgui_ctx.alldir].val.lng) ? "1" : "0"; + rnd_conf_set(RND_CFR_DESIGN, "editor/all_direction_lines", -1, nv, RND_POL_OVERWRITE); + cnstgui_ctx.inhibit_confchg--; +} + + + +int constraint_gui(void) +{ + const char *tab_names[] = {"line", "move", NULL}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + if (cnstgui_ctx.active) + return 0; /* do not open another */ + + RND_DAD_BEGIN_VBOX(cnstgui_ctx.dlg); + RND_DAD_COMPFLAG(cnstgui_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(cnstgui_ctx.dlg, tab_names); + + /* line */ + RND_DAD_BEGIN_VBOX(cnstgui_ctx.dlg); + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_LABEL(cnstgui_ctx.dlg, "All direction lines:"); + RND_DAD_BOOL(cnstgui_ctx.dlg); + cnstgui_ctx.alldir = RND_DAD_CURRENT(cnstgui_ctx.dlg); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, set_alldir); + RND_DAD_HELP(cnstgui_ctx.dlg, "Constraints work well only when\nthe all-direction-lines is enabled"); + RND_DAD_END(cnstgui_ctx.dlg); + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_LABEL(cnstgui_ctx.dlg, "Fixed angles:"); + RND_DAD_STRING(cnstgui_ctx.dlg); + cnstgui_ctx.line_angle = RND_DAD_CURRENT(cnstgui_ctx.dlg); + RND_DAD_HELP(cnstgui_ctx.dlg, "space separated list of valid line angles in degree"); + RND_DAD_BUTTON(cnstgui_ctx.dlg, "apply"); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, gui2cons); + RND_DAD_END(cnstgui_ctx.dlg); + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_LABEL(cnstgui_ctx.dlg, "Angle modulo:"); + RND_DAD_REAL(cnstgui_ctx.dlg); + cnstgui_ctx.line_angle_mod = RND_DAD_CURRENT(cnstgui_ctx.dlg); + RND_DAD_MINVAL(cnstgui_ctx.dlg, 0); + RND_DAD_MAXVAL(cnstgui_ctx.dlg, 180); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, gui2cons); + RND_DAD_HELP(cnstgui_ctx.dlg, "if non-zero:\nline angle must be an integer multiply of this value"); + RND_DAD_END(cnstgui_ctx.dlg); + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_LABEL(cnstgui_ctx.dlg, "Fixed lengths:"); + RND_DAD_STRING(cnstgui_ctx.dlg); + cnstgui_ctx.line_length = RND_DAD_CURRENT(cnstgui_ctx.dlg); + RND_DAD_HELP(cnstgui_ctx.dlg, "space separated list of valid line lengths"); + RND_DAD_BUTTON(cnstgui_ctx.dlg, "apply"); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, gui2cons); + RND_DAD_END(cnstgui_ctx.dlg); + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_LABEL(cnstgui_ctx.dlg, "Length modulo:"); + RND_DAD_COORD(cnstgui_ctx.dlg); + cnstgui_ctx.line_length_mod = RND_DAD_CURRENT(cnstgui_ctx.dlg); + RND_DAD_MINVAL(cnstgui_ctx.dlg, 0); + RND_DAD_MAXVAL(cnstgui_ctx.dlg, RND_MM_TO_COORD(1000)); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, gui2cons); + RND_DAD_HELP(cnstgui_ctx.dlg, "if non-zero:\nline length must be an integer multiply of this value"); + RND_DAD_END(cnstgui_ctx.dlg); + + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_BUTTON(cnstgui_ctx.dlg, "perpendicular to line"); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, set_perp); + RND_DAD_HELP(cnstgui_ctx.dlg, "sets the angle constraint perpendicular to a line\nselected on the drawing"); + RND_DAD_BUTTON(cnstgui_ctx.dlg, "parallel with line"); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, set_paral); + RND_DAD_HELP(cnstgui_ctx.dlg, "sets the angle constraint parallel to a line\nselected on the drawing"); + RND_DAD_END(cnstgui_ctx.dlg); + + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_BUTTON(cnstgui_ctx.dlg, "tangential to arc"); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, set_tang); + RND_DAD_HELP(cnstgui_ctx.dlg, "sets the angle constraint to be tangential to the circle of an arc\nselected on the drawing"); + RND_DAD_END(cnstgui_ctx.dlg); + + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_BUTTON(cnstgui_ctx.dlg, "Reset"); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, reset_line); + RND_DAD_HELP(cnstgui_ctx.dlg, "clear line constraint values"); + RND_DAD_END(cnstgui_ctx.dlg); + + RND_DAD_END(cnstgui_ctx.dlg); + + /* move */ + RND_DAD_BEGIN_VBOX(cnstgui_ctx.dlg); + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_LABEL(cnstgui_ctx.dlg, "Fixed angles:"); + RND_DAD_STRING(cnstgui_ctx.dlg); + cnstgui_ctx.move_angle = RND_DAD_CURRENT(cnstgui_ctx.dlg); + RND_DAD_HELP(cnstgui_ctx.dlg, "space separated list of valid move vector angles in degree"); + RND_DAD_BUTTON(cnstgui_ctx.dlg, "apply"); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, gui2cons); + RND_DAD_END(cnstgui_ctx.dlg); + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_LABEL(cnstgui_ctx.dlg, "Angle modulo:"); + RND_DAD_REAL(cnstgui_ctx.dlg); + cnstgui_ctx.move_angle_mod = RND_DAD_CURRENT(cnstgui_ctx.dlg); + RND_DAD_MINVAL(cnstgui_ctx.dlg, 0); + RND_DAD_MAXVAL(cnstgui_ctx.dlg, 180); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, gui2cons); + RND_DAD_HELP(cnstgui_ctx.dlg, "if non-zero:\nmove vector angle must be an integer multiply of this value"); + RND_DAD_END(cnstgui_ctx.dlg); + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_LABEL(cnstgui_ctx.dlg, "Fixed lengths:"); + RND_DAD_STRING(cnstgui_ctx.dlg); + cnstgui_ctx.move_length = RND_DAD_CURRENT(cnstgui_ctx.dlg); + RND_DAD_HELP(cnstgui_ctx.dlg, "space separated list of valid move distances"); + RND_DAD_BUTTON(cnstgui_ctx.dlg, "apply"); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, gui2cons); + RND_DAD_END(cnstgui_ctx.dlg); + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_LABEL(cnstgui_ctx.dlg, "Length modulo:"); + RND_DAD_COORD(cnstgui_ctx.dlg); + cnstgui_ctx.move_length_mod = RND_DAD_CURRENT(cnstgui_ctx.dlg); + RND_DAD_MINVAL(cnstgui_ctx.dlg, 0); + RND_DAD_MAXVAL(cnstgui_ctx.dlg, RND_MM_TO_COORD(1000)); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, gui2cons); + RND_DAD_HELP(cnstgui_ctx.dlg, "if non-zero:\nmove distance must be an integer multiply of this value"); + RND_DAD_END(cnstgui_ctx.dlg); + RND_DAD_BEGIN_HBOX(cnstgui_ctx.dlg); + RND_DAD_BUTTON(cnstgui_ctx.dlg, "Reset"); + RND_DAD_CHANGE_CB(cnstgui_ctx.dlg, reset_move); + RND_DAD_HELP(cnstgui_ctx.dlg, "clear move constraint values"); + RND_DAD_END(cnstgui_ctx.dlg); + RND_DAD_END(cnstgui_ctx.dlg); + + RND_DAD_END(cnstgui_ctx.dlg); + RND_DAD_BUTTON_CLOSES(cnstgui_ctx.dlg, clbtn); + RND_DAD_END(cnstgui_ctx.dlg); + + /* set up the context */ + cnstgui_ctx.active = 1; + + RND_DAD_NEW("constraint", cnstgui_ctx.dlg, "Drawing constraints", &cnstgui_ctx, rnd_false, cnstgui_close_cb); + + cons_changed(); + + return 0; +} Index: tags/2.3.0/src_plugins/ddraft/ddraft.c =================================================================== --- tags/2.3.0/src_plugins/ddraft/ddraft.c (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/ddraft.c (revision 33253) @@ -0,0 +1,567 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * 2d drafting plugin + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include +#include "event.h" +#include +#include "funchash_core.h" +#include "search.h" +#include "centgeo.h" +#include +#include "board.h" +#include "data_it.h" +#include "obj_line.h" +#include "undo.h" +#include "fields_sphash.h" +#include "draw_wireframe.h" +#include "conf_core.h" +#include +#include + +static const char *ddraft_cookie = "ddraft plugin"; +static int pcb_ddraft_tool; + +typedef struct { + pcb_line_t line; + int line_valid; + + vtc0_t annot_lines; /* each 4 coords specify a line */ +} pcb_ddraft_attached_t; + +pcb_ddraft_attached_t pcb_ddraft_attached; + +void pcb_ddraft_attached_reset(void) +{ + pcb_ddraft_attached.line_valid = 0; + vtc0_truncate(&pcb_ddraft_attached.annot_lines, 0); +} + +#define EDGE_TYPES (PCB_OBJ_LINE | PCB_OBJ_ARC) +#define CUT_TYPES (PCB_OBJ_LINE | PCB_OBJ_ARC) + +static void list_by_flag(pcb_data_t *data, vtp0_t *dst, unsigned long types, unsigned long flag) +{ + pcb_any_obj_t *o; + pcb_data_it_t it; + + for(o = pcb_data_first(&it, data, types); o != NULL; o = pcb_data_next(&it)) + if (PCB_FLAG_TEST(flag, o)) + vtp0_append(dst, o); +} + +#include "trim.c" +#include "constraint.c" + +static long do_trim_split(vtp0_t *edges, int kwobj, int trim) +{ + pcb_objtype_t type; + void *ptr1, *ptr2, *ptr3; + rnd_coord_t x, y; + long res = 0; + + switch(kwobj) { + case F_Object: + for(;;) { + int cr = rnd_hid_get_coords("Select an object to cut or press esc", &x, &y, 1); + if (cr < 0) + break; + + type = pcb_search_screen(x, y, CUT_TYPES, &ptr1, &ptr2, &ptr3); + if (type == 0) { + rnd_message(RND_MSG_ERROR, "Can't cut that object\n"); + continue; + } + res += pcb_trim_split(edges, NULL, (pcb_any_obj_t *)ptr2, REMO_INVALID, x, y, trim); + rnd_gui->invalidate_all(rnd_gui); + } + break; + default: + rnd_message(RND_MSG_ERROR, "Invalid second argument\n"); + return -1; + } + + return res; +} + +static const char pcb_acts_trim_split[] = "trim([selected|found|object], [selected|found|object])\nsplit([selected|found|object], [selected|found|object])"; +static const char pcb_acth_trim_split[] = "Use one or more objects as cutting edge and trim or split other objects. First argument is the cutting edge"; +static fgw_error_t pcb_act_trim_split(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *actname = argv[0].val.func->name; + int kwcut = F_Object, kwobj = F_Object; + pcb_objtype_t type; + void *ptr1, *ptr2, *ptr3; + rnd_coord_t x, y; + vtp0_t edges; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, trim_split, kwcut = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_KEYWORD, trim_split, kwobj = fgw_keyword(&argv[2])); + + vtp0_init(&edges); + + if ((kwobj == kwcut) && (kwobj != F_Object)) { + rnd_message(RND_MSG_ERROR, "Both cutting edge and objects to cut can't be '%s'\n", kwcut == F_Selected ? "selected" : "found"); + goto err; + } + + switch(kwcut) { + case F_Object: + rnd_hid_get_coords("Select cutting edge object", &x, &y, 0); + type = pcb_search_screen(x, y, EDGE_TYPES, &ptr1, &ptr2, &ptr3); + if (type == 0) { + rnd_message(RND_MSG_ERROR, "Invalid cutting edge object\n"); + goto err; + } + vtp0_append(&edges, ptr2); + break; + case F_Selected: + list_by_flag(PCB->Data, &edges, EDGE_TYPES, PCB_FLAG_SELECTED); + break; + case F_Found: + list_by_flag(PCB->Data, &edges, EDGE_TYPES, PCB_FLAG_FOUND); + break; + default: + rnd_message(RND_MSG_ERROR, "Invalid first argument\n"); + goto err; + } + + if (vtp0_len(&edges) < 1) { + rnd_message(RND_MSG_ERROR, "No cutting edge found\n"); + goto err; + } + + + if (do_trim_split(&edges, kwobj, (*actname == 't')) < 0) + goto err; + + RND_ACT_IRES(0); + vtp0_uninit(&edges); + return 0; + + err:; + RND_ACT_IRES(-1); + vtp0_uninit(&edges); + return 0; +} + + +static const char pcb_acts_split_idp[] = "PcbSplit(cutting_edges, objs)"; +static const char pcb_acth_split_idp[] = "Split objects (idpath or idpath list) with cutting edges (idpath or idpath list), returning the idpath list of the newly created objects"; +static fgw_error_t pcb_act_split_idp(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_idpath_t *idp; + pcb_idpath_list_t *idpl; + gdl_iterator_t it; + pcb_any_obj_t *obj; + vtp0_t edges, objs, newobjs, *vect; + long n; + + vtp0_init(&edges); + vtp0_init(&objs); + vtp0_init(&newobjs); + + /* read two obj or objlist args */ + for(n = 1; n < 3; n++) { + vect = (n == 1) ? &edges : &objs; + + RND_ACT_CONVARG(n, FGW_IDPATH, split_idp, idp = fgw_idpath(&argv[n])); + if (idp == NULL) + goto invptr; + if (fgw_ptr_in_domain(&rnd_fgw, &argv[n], RND_PTR_DOMAIN_IDPATH)) { + obj = pcb_idpath2obj(PCB, idp); + if ((obj == NULL) || ((obj->type & PCB_OBJ_CLASS_REAL) == 0)) + goto invptr; + vtp0_append(vect, obj); + } + else if (fgw_ptr_in_domain(&rnd_fgw, &argv[n], RND_PTR_DOMAIN_IDPATH_LIST)) { + idpl = (pcb_idpath_list_t *)idp; + pcb_idpath_list_foreach(idpl, &it, idp) { + obj = pcb_idpath2obj(PCB, idp); + if ((obj == NULL) || ((obj->type & PCB_OBJ_CLASS_REAL) == 0)) + goto invptr; + vtp0_append(vect, obj); + } + } + else + goto invptr; + } + + /* execute the splits */ + for(n = 0; n < vtp0_len(&objs); n++) + pcb_trim_split(&edges, &newobjs, objs.array[n], 0, 0, 0, 0); + + /* copy over the objects to an idpath_list that is then returned */ + idpl = calloc(sizeof(pcb_idpath_list_t), 1); + fgw_ptr_reg(&rnd_fgw, res, RND_PTR_DOMAIN_IDPATH_LIST, FGW_PTR | FGW_STRUCT, idpl); + for(n = 0; n < vtp0_len(&newobjs); n++) { + idp = pcb_obj2idpath(newobjs.array[n]); + if (idp != NULL) + pcb_idpath_list_append(idpl, idp); + } + + vtp0_uninit(&edges); + vtp0_uninit(&objs); + vtp0_uninit(&newobjs); + return 0; + + invptr:; + vtp0_uninit(&edges); + vtp0_uninit(&objs); + vtp0_uninit(&newobjs); + return FGW_ERR_PTR_DOMAIN; +} + + +#include "constraint_gui.c" + +#define load_arr(arr, ctr, msg, fgw_type_, fgw_val_) \ +do { \ + int n; \ + if (argc-2 >= sizeof(arr) / sizeof(arr[0])) { \ + rnd_message(RND_MSG_ERROR, "constraint: Too many " msg "\n"); \ + RND_ACT_IRES(-1); \ + return 0; \ + } \ + ctr = 0; \ + for(n = 2; n < argc; n++) { \ + RND_ACT_CONVARG(n, fgw_type_, constraint, arr[ctr] = fgw_val_); \ + ctr++; \ + } \ +} while(0) + +static const char pcb_acts_constraint[] = "constraint(type, off)\nconstraint(type, value, [value...])"; +static const char pcb_acth_constraint[] = "Configure or remove a drawing constraint"; +static fgw_error_t pcb_act_constraint(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char *stype = NULL; + int type; + + RND_ACT_MAY_CONVARG(1, FGW_STR, constraint, stype = argv[1].val.str); + if (stype == NULL) { + RND_ACT_IRES(constraint_gui()); + return 0; + } + type = ddraft_fields_sphash(stype); + switch(type) { + case ddraft_fields_line_angle: + load_arr(cons.line_angle, cons.line_angle_len, "line angles", FGW_DOUBLE, argv[n].val.nat_double); + cons_changed(); + break; + case ddraft_fields_move_angle: + load_arr(cons.move_angle, cons.move_angle_len, "move angles", FGW_DOUBLE, argv[n].val.nat_double); + cons_changed(); + break; + case ddraft_fields_line_angle_mod: + cons.line_angle_mod = 0; + RND_ACT_MAY_CONVARG(2, FGW_DOUBLE, constraint, cons.line_angle_mod = argv[2].val.nat_double); + cons_changed(); + break; + case ddraft_fields_move_angle_mod: + cons.move_angle_mod = 0; + RND_ACT_MAY_CONVARG(2, FGW_DOUBLE, constraint, cons.move_angle_mod = argv[2].val.nat_double); + cons_changed(); + break; + case ddraft_fields_line_length: + load_arr(cons.line_length, cons.line_length_len, "line lengths", FGW_COORD, fgw_coord(&argv[n])); + cons_changed(); + break; + case ddraft_fields_move_length: + load_arr(cons.move_length, cons.move_length_len, "move lengths", FGW_COORD, fgw_coord(&argv[n])); + cons_changed(); + break; + case ddraft_fields_line_length_mod: + cons.line_length_mod = 0; + RND_ACT_MAY_CONVARG(2, FGW_COORD, constraint, cons.line_length_mod = fgw_coord(&argv[2])); + cons_changed(); + break; + case ddraft_fields_move_length_mod: + cons.move_length_mod = 0; + RND_ACT_MAY_CONVARG(2, FGW_COORD, constraint, cons.move_length_mod = fgw_coord(&argv[2])); + cons_changed(); + break; + + case ddraft_fields_reset: + memset(&cons, 0, sizeof(cons)); + cons_changed(); + break; + case ddraft_fields_SPHASH_INVALID: + rnd_message(RND_MSG_ERROR, "constraint: invalid field '%s'\n", stype); + RND_ACT_IRES(-1); + return 0; + break; + } + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_perp_paral[] = "perp()"; +static const char pcb_acth_perp_paral[] = "Draw a line perpendicular to another line"; +static fgw_error_t pcb_act_perp_paral(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *actname = argv[0].val.func->name; + pcb_objtype_t type; + void *ptr1, *ptr2, *ptr3; + rnd_coord_t x, y; + double dx, dy; + pcb_line_t *line; + + rnd_hid_get_coords("Select target object", &x, &y, 0); + type = pcb_search_screen(x, y, EDGE_TYPES, &ptr1, &ptr2, &ptr3); + + if (type != PCB_OBJ_LINE) { + rnd_hid_get_coords("Select target object", &x, &y, 1); + type = pcb_search_screen(x, y, EDGE_TYPES, &ptr1, &ptr2, &ptr3); + } + + if (type != PCB_OBJ_LINE) { + rnd_message(RND_MSG_ERROR, "%s: target object must be a line\n", actname); + RND_ACT_IRES(-1); + return 0; + } + + line = (pcb_line_t *)ptr2; + dx = line->Point2.X - line->Point1.X; + dy = line->Point2.Y - line->Point1.Y; + if ((dx == 0.0) && (dy == 0.0)) { + rnd_message(RND_MSG_ERROR, "%s: target line must be longer than 0\n", actname); + RND_ACT_IRES(-1); + return 0; + } + + cons.line_angle_len = 2; + cons.line_angle[0] = atan2(dy, dx) * RND_RAD_TO_DEG; + if (actname[1] == 'e') /* perp */ + cons.line_angle[0] += 90; + cons.line_angle[1] = fmod(cons.line_angle[0]+180, 360); + cons_changed(); + + RND_ACT_IRES(0); + return 0; +} + + +static const char pcb_acts_tang[] = "tang()"; +static const char pcb_acth_tang[] = "Draw a line to be tangential to a circle"; +static fgw_error_t pcb_act_tang(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_objtype_t type; + void *ptr1, *ptr2, *ptr3; + rnd_coord_t x, y; + double d, r, base; + pcb_route_object_t *line; + pcb_arc_t *arc; + + + if (((pcb_crosshair.AttachedLine.State != PCB_CH_STATE_SECOND) && (pcb_crosshair.AttachedLine.State != PCB_CH_STATE_THIRD)) || (pcb_crosshair.Route.size < 1)) { + err_nonline:; + rnd_message(RND_MSG_ERROR, "tang: must be in line drawing mode with the first point already set\n"); + RND_ACT_IRES(-1); + return 0; + } + + line = &pcb_crosshair.Route.objects[pcb_crosshair.Route.size-1]; + if (line->type != PCB_OBJ_LINE) + goto err_nonline; + + + rnd_hid_get_coords("Select target arc", &x, &y, 0); + type = pcb_search_screen(x, y, EDGE_TYPES, &ptr1, &ptr2, &ptr3); + + if (type != PCB_OBJ_ARC) { + rnd_hid_get_coords("Select target arc", &x, &y, 1); + type = pcb_search_screen(x, y, EDGE_TYPES, &ptr1, &ptr2, &ptr3); + } + + if (type != PCB_OBJ_ARC) { + rnd_message(RND_MSG_ERROR, "tang: target object must be an arc\n"); + RND_ACT_IRES(-1); + return 0; + } + + arc = (pcb_arc_t *)ptr2; + if (fabs((double)(arc->Height - arc->Width)) > 100) { + rnd_message(RND_MSG_ERROR, "tang: elliptical arcs are not supported (%$mm != %$mm)\n", arc->Height, arc->Width); + RND_ACT_IRES(-1); + return 0; + } + + d = rnd_distance(arc->X, arc->Y, line->point1.X, line->point1.Y); + r = arc->Width; + + if (d <= r) { + rnd_message(RND_MSG_ERROR, "tang: line must start outside of the circle\n"); + RND_ACT_IRES(-1); + return 0; + } + + base = atan2(arc->Y - line->point1.Y, arc->X - line->point1.X); + + cons.line_angle_len = 2; + cons.line_angle[0] = (base + asin(r / d)) * RND_RAD_TO_DEG; + cons.line_angle[1] = (base + asin(-r / d)) * RND_RAD_TO_DEG; + cons_changed(); + + RND_ACT_IRES(0); + return 0; +} + +void ddraft_tool_draw_attached(rnd_hidlib_t *hl) +{ + int n; + rnd_render->set_line_cap(pcb_crosshair.GC, rnd_cap_round); + rnd_render->set_line_width(pcb_crosshair.GC, 1); + rnd_render->set_color(pcb_crosshair.GC, rnd_color_grey33); + for(n = 0; n < vtc0_len(&pcb_ddraft_attached.annot_lines); n += 4) { + rnd_coord_t *c = &pcb_ddraft_attached.annot_lines.array[n]; + rnd_render->draw_line(pcb_crosshair.GC, c[0], c[1], c[2], c[3]); + } + + if (pcb_ddraft_attached.line_valid) { + rnd_render->set_color(pcb_crosshair.GC, &PCB_CURRLAYER(PCB)->meta.real.color); + pcb_draw_wireframe_line(pcb_crosshair.GC, + pcb_ddraft_attached.line.Point1.X, pcb_ddraft_attached.line.Point1.Y, pcb_ddraft_attached.line.Point2.X, pcb_ddraft_attached.line.Point2.Y, + conf_core.design.line_thickness, 0); + } +} + +#include "cli.c" + +static rnd_action_t ddraft_action_list[] = { + {"trim", pcb_act_trim_split, pcb_acth_trim_split, pcb_acts_trim_split}, + {"split", pcb_act_trim_split, pcb_acth_trim_split, pcb_acts_trim_split}, + {"pcbsplit", pcb_act_split_idp, pcb_acth_split_idp, pcb_acts_split_idp}, + {"constraint", pcb_act_constraint, pcb_acth_constraint, pcb_acts_constraint}, + {"perp", pcb_act_perp_paral, pcb_acth_perp_paral, pcb_acts_perp_paral}, + {"paral", pcb_act_perp_paral, pcb_acth_perp_paral, pcb_acts_perp_paral}, + {"tang", pcb_act_tang, pcb_acth_tang, pcb_acts_tang}, + {"ddraft", pcb_act_ddraft, pcb_acth_ddraft, pcb_acts_ddraft} +}; + +/* XPM */ +static const char *ddraft_xpm[] = { +"21 21 3 1", +" c None", +". c #000000", +"+ c #6EA5D7", +" ", +" ", +" . ", +" . ", +" .+ ", +" . + ", +" . + ", +" . + ", +" . + ", +" . + ", +" .++++++++++ ", +" ", +" ... .... ", +" . . . . ", +" . . . ", +" . . . ", +" . . . ", +" . . . ", +" . . . ", +" ..... .... ", +" "}; + +static rnd_tool_t tool_ddraft = { + "ddraft", "2 dimensional drafting", + NULL, 1000, ddraft_xpm, RND_TOOL_CURSOR_NAMED(NULL), 1, + NULL, + NULL, + NULL, + NULL, + NULL, + ddraft_tool_draw_attached, + NULL, + NULL, + NULL, /* escape */ + rnd_false +}; + + +static void mode_confchg(rnd_conf_native_t *cfg, int arr_idx) +{ + static int ddraft_tool_selected = 0; + + if (rnd_conf.editor.mode == pcb_ddraft_tool) { + if (!ddraft_tool_selected) { + ddraft_tool_selected = 1; + rnd_cli_enter("ddraft", "ddraft"); + rnd_gui->open_command(rnd_gui); + } + } + else if (ddraft_tool_selected) { + rnd_cli_leave(); + ddraft_tool_selected = 0; + } +} + +int pplg_check_ver_ddraft(int ver_needed) { return 0; } + +void pplg_uninit_ddraft(void) +{ + rnd_conf_hid_unreg(ddraft_cookie); + rnd_event_unbind_allcookie(ddraft_cookie); + rnd_remove_actions_by_cookie(ddraft_cookie); + rnd_tool_unreg_by_cookie(ddraft_cookie); +} + +static const rnd_conf_hid_callbacks_t conf_cbs_adl = { NULL, cons_gui_confchg, NULL, NULL }; +static const rnd_conf_hid_callbacks_t conf_cbs_mode = { NULL, mode_confchg, NULL, NULL }; + +int pplg_init_ddraft(void) +{ + rnd_conf_native_t *cn; + rnd_conf_hid_id_t confid; + + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(ddraft_action_list, ddraft_cookie) + rnd_event_bind(PCB_EVENT_DRAW_CROSSHAIR_CHATT, cnst_enforce, NULL, ddraft_cookie); + + pcb_ddraft_tool = rnd_tool_reg(&tool_ddraft, ddraft_cookie); + + confid = rnd_conf_hid_reg(ddraft_cookie, NULL); + cn = rnd_conf_get_field("editor/all_direction_lines"); + rnd_conf_hid_set_cb(cn, confid, &conf_cbs_adl); + cn = rnd_conf_get_field("editor/mode"); + rnd_conf_hid_set_cb(cn, confid, &conf_cbs_mode); + return 0; +} Index: tags/2.3.0/src_plugins/ddraft/ddraft.pup =================================================================== --- tags/2.3.0/src_plugins/ddraft/ddraft.pup (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/ddraft.pup (revision 33253) @@ -0,0 +1,7 @@ +$class export +$short 2D drafting helper +$long Actions and a command interpreter for supporting advanced/precise 2 dimensional drafting +$state WIP +$package core +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/ddraft/fields.sphash =================================================================== --- tags/2.3.0/src_plugins/ddraft/fields.sphash (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/fields.sphash (revision 33253) @@ -0,0 +1,9 @@ +line_angle +line_length +line_angle_mod +line_length_mod +move_angle +move_length +move_angle_mod +move_length_mod +reset Index: tags/2.3.0/src_plugins/ddraft/trim.c =================================================================== --- tags/2.3.0/src_plugins/ddraft/trim.c (nonexistent) +++ tags/2.3.0/src_plugins/ddraft/trim.c (revision 33253) @@ -0,0 +1,388 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * 2d drafting plugin: trim objects + * pcb-rnd Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "undo_old.h" + +#define REMO_INVALID -1000.0 +#define remo_is_valid(v) ((v) > REMO_INVALID) + +/* Move a line endpoint to a new absoltue coord in an undoable way */ +static void move_lp(pcb_line_t *line, int pt_idx, rnd_coord_t x, rnd_coord_t y) +{ + rnd_point_t *pt; + + switch(pt_idx) { + case 1: pt = &line->Point1; break; + case 2: pt = &line->Point2; break; + default: + abort(); + } + + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, line->parent.layer, line, pt, x - pt->X, y - pt->Y); + pcb_line_pre(line); + pt->X = x; + pt->Y = y; + pcb_line_post(line); +} + +/* normallize mino and maxo: make sure they are in the [0..1] range */ +#define norm_minmaxo() \ + do { \ + if (mino < 0.0) \ + mino = 0.0; \ + if (maxo > 1.0) \ + mino = 1.0; \ + } while(0) + +static int pcb_trim_line(vtp0_t *cut_edges, pcb_line_t *line, double remo_in, rnd_coord_t rem_x, rnd_coord_t rem_y) +{ + int p, n; + double io[2]; + double mino = 0.0, maxo = 1.0, remo = remo_in; + rnd_coord_t x, y; + + if (!remo_is_valid(remo)) + remo = pcb_cline_pt_offs(line, rem_x, rem_y); + + for(n = 0; n < vtp0_len(cut_edges); n++) { + pcb_any_obj_t *cut_edge = (pcb_any_obj_t *)cut_edges->array[n]; + + p = 0; + switch(cut_edge->type) { + case PCB_OBJ_LINE: + p = pcb_intersect_cline_cline(line, (pcb_line_t *)cut_edge, NULL, io); + break; + case PCB_OBJ_ARC: + p = pcb_intersect_cline_carc(line, (pcb_arc_t *)cut_edge, NULL, io); + break; + default: continue; + } + + switch(p) { + case 0: continue; /* no intersection, skip to the next potential cutting edge */ + case 2: + if (io[1] < remo) { + if (io[1] > mino) mino = io[1]; + } + else { + if (io[1] < maxo) maxo = io[1]; + } + case 1: + if (io[0] < remo) { + if (io[0] > mino) mino = io[0]; + } + else { + if (io[0] < maxo) maxo = io[0]; + } + break; + } + } + + norm_minmaxo(); + + if ((mino == 0.0) && (maxo == 1.0)) + return 0; /* nothing to be done */ + + if (mino == maxo) + return 0; /* refuse to end up with 0-length lines */ + + /* mino and maxo holds the two endpoint offsets after the cuts, in respect + to the original line. Cut/split the line using them. */ + if ((mino > 0.0) && (maxo < 1.0)) { /* remove (shortest) middle section */ + pcb_line_t *new_line = pcb_line_dup(line->parent.layer, line); + + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, new_line->parent.layer, new_line, new_line); + + pcb_cline_offs(line, maxo, &x, &y); + move_lp(line, 1, x, y); + + pcb_cline_offs(new_line, mino, &x, &y); + move_lp(new_line, 2, x, y); + } + else if ((mino == 0.0) && (maxo < 1.0)) { /* truncate at point1 (shortest overdue) */ + pcb_cline_offs(line, maxo, &x, &y); + move_lp(line, 1, x, y); + } + else if ((mino > 0.0) && (maxo == 1.0)) { /* truncate at point2 (shortest overdue) */ + pcb_cline_offs(line, mino, &x, &y); + move_lp(line, 2, x, y); + } + else + return -1; + + return 1; +} + +/* Move arc start or end angle to a specific absolute angle (undoable) */ +static void move_arc_angs(pcb_arc_t *arc, int ep, double offs) +{ + double chg = offs * arc->Delta; + + pcb_undo_add_obj_to_change_angles(PCB_OBJ_ARC, arc->parent.layer, arc, arc); + pcb_arc_pre(arc); + switch(ep) { + case 1: + arc->StartAngle += chg; + arc->Delta -= chg; + break; + case 2: + arc->Delta = chg; + break; + } + pcb_arc_post(arc); +} + + +static int pcb_trim_arc(vtp0_t *cut_edges, pcb_arc_t *arc, double remo_in, rnd_coord_t rem_x, rnd_coord_t rem_y) +{ + int p, n; + double io[2]; + double mino = 0.0, maxo = 1.0, remo = remo_in; + + if (!remo_is_valid(remo)) + remo = pcb_carc_pt_offs(arc, rem_x, rem_y); + + for(n = 0; n < vtp0_len(cut_edges); n++) { + pcb_any_obj_t *cut_edge = (pcb_any_obj_t *)cut_edges->array[n]; + + p = 0; + switch(cut_edge->type) { + case PCB_OBJ_LINE: + p = pcb_intersect_carc_cline(arc, (pcb_line_t *)cut_edge, NULL, io); + break; + case PCB_OBJ_ARC: + p = pcb_intersect_carc_carc(arc, (pcb_arc_t *)cut_edge, NULL, io); + break; + default: continue; + } + + switch(p) { + case 0: continue; /* no intersection, skip to the next potential cutting edge */ + case 2: + if (io[1] < remo) { + if (io[1] > mino) mino = io[1]; + } + else { + if (io[1] < maxo) maxo = io[1]; + } + case 1: + if (io[0] < remo) { + if (io[0] > mino) mino = io[0]; + } + else { + if (io[0] < maxo) maxo = io[0]; + } + break; + } + } + + norm_minmaxo(); + + if ((mino == 0.0) && (maxo == 1.0)) + return 0; /* nothing to be done */ + + if (mino == maxo) + return 0; /* refuse to end up with 0-length lines */ + + /* mino and maxo holds the two endpoint offsets after the cuts, in respect + to the original line. Cut/split the line using them. */ + if ((mino > 0.0) && (maxo < 1.0)) { /* remove (shortest) middle section */ + pcb_arc_t *new_arc = pcb_arc_dup(arc->parent.layer, arc); + + pcb_undo_add_obj_to_create(PCB_OBJ_ARC, new_arc->parent.layer, new_arc, new_arc); + + move_arc_angs(arc, 1, maxo); + move_arc_angs(new_arc, 2, mino); + } + else if ((mino == 0.0) && (maxo < 1.0)) { /* truncate at point1 (shortest overdue) */ + move_arc_angs(arc, 1, maxo); + } + else if ((mino > 0.0) && (maxo == 1.0)) { /* truncate at point2 (shortest overdue) */ + move_arc_angs(arc, 2, mino); + } + else + return -1; + return 1; +} + +/* Split a line in two lines at a specific offset (undoable) */ +static pcb_line_t *split_lp(pcb_line_t *line, double offs) +{ + rnd_coord_t x, y; + pcb_line_t *new_line = pcb_line_dup(line->parent.layer, line); + + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, new_line->parent.layer, new_line, new_line); + + pcb_cline_offs(line, offs, &x, &y); + move_lp(line, 2, x, y); + move_lp(new_line, 1, x, y); + + return new_line; +} + +/* Split an arc in two arcs at a specific offset (undoable) */ +static pcb_arc_t *split_arcp(pcb_arc_t *arc, double offs) +{ + pcb_arc_t *new_arc = pcb_arc_dup(arc->parent.layer, arc); + + pcb_undo_add_obj_to_create(PCB_OBJ_ARC, new_arc->parent.layer, new_arc, new_arc); + + move_arc_angs(arc, 2, offs); + move_arc_angs(new_arc, 1, offs); + + return new_arc; +} + +static int near(double v1, double v2) +{ + v1 -= v2; + if (v1 < 0) v1 = -v1; + return (v1 < 0.0001); +} + +static int pcb_split_line(vtp0_t *cut_edges, vtp0_t *new_objs, pcb_line_t *line, double remo_in, rnd_coord_t rem_x, rnd_coord_t rem_y) +{ + int p, n, numsplt = 0, res; + double io[2]; + pcb_line_t *new_line; + + for(n = 0; n < vtp0_len(cut_edges); n++) { + pcb_any_obj_t *cut_edge = (pcb_any_obj_t *)cut_edges->array[n]; + p = 0; + switch(cut_edge->type) { + case PCB_OBJ_LINE: + p = pcb_intersect_cline_cline(line, (pcb_line_t *)cut_edge, NULL, io); + break; + case PCB_OBJ_ARC: + p = pcb_intersect_cline_carc(line, (pcb_arc_t *)cut_edge, NULL, io); + break; + default: continue; + } + switch(p) { + case 0: continue; /* no intersection, skip to the next potential cutting edge */ + case 2: + if (!near(io[1], 0.0) && !near(io[1], 1.0)) { + new_line = split_lp(line, io[1]); + numsplt++; + if (new_objs != NULL) vtp0_append(new_objs, new_line); + res = pcb_split_line(cut_edges, new_objs, line, remo_in, rem_x, rem_y); + if (res > 0) numsplt += res; + res = pcb_split_line(cut_edges, new_objs, new_line, remo_in, rem_x, rem_y); + if (res > 0) numsplt += res; + break; /* can't use the other point if we did a split here, because that changes the meaning of offsets */ + } + case 1: + if (!near(io[0], 0.0) && !near(io[0], 1.0)) { + new_line = split_lp(line, io[0]); + numsplt++; + if (new_objs != NULL) vtp0_append(new_objs, new_line); + res = pcb_split_line(cut_edges, new_objs, line, remo_in, rem_x, rem_y); + if (res > 0) numsplt += res; + res = pcb_split_line(cut_edges, new_objs, new_line, remo_in, rem_x, rem_y); + if (res > 0) numsplt += res; + } + break; + } + } + + return numsplt; +} + +static int pcb_split_arc(vtp0_t *cut_edges, vtp0_t *new_objs, pcb_arc_t *arc, double remo_in, rnd_coord_t rem_x, rnd_coord_t rem_y) +{ + int p, n, numsplt = 0, res; + double io[2]; + pcb_arc_t *new_arc; + + for(n = 0; n < vtp0_len(cut_edges); n++) { + pcb_any_obj_t *cut_edge = (pcb_any_obj_t *)cut_edges->array[n]; + p = 0; + switch(cut_edge->type) { + case PCB_OBJ_LINE: + p = pcb_intersect_carc_cline(arc, (pcb_line_t *)cut_edge, NULL, io); + break; + case PCB_OBJ_ARC: + p = pcb_intersect_carc_carc(arc, (pcb_arc_t *)cut_edge, NULL, io); + break; + default: continue; + } + switch(p) { + case 0: continue; /* no intersection, skip to the next potential cutting edge */ + case 2: + if (!near(io[1], 0.0) && !near(io[1], 1.0)) { + new_arc = split_arcp(arc, io[1]); + numsplt++; + if (new_objs != NULL) vtp0_append(new_objs, new_arc); + res = pcb_split_arc(cut_edges, new_objs, arc, remo_in, rem_x, rem_y); + if (res > 0) numsplt += res; + res = pcb_split_arc(cut_edges, new_objs, new_arc, remo_in, rem_x, rem_y); + if (res > 0) numsplt += res; + break; /* can't use the other point if we did a split here, because that changes the meaning of offsets */ + } + case 1: + if (!near(io[0], 0.0) && !near(io[0], 1.0)) { + new_arc = split_arcp(arc, io[0]); + numsplt++; + if (new_objs != NULL) vtp0_append(new_objs, new_arc); + res = pcb_split_arc(cut_edges, new_objs, arc, remo_in, rem_x, rem_y); + if (res > 0) numsplt += res; + res = pcb_split_arc(cut_edges, new_objs, new_arc, remo_in, rem_x, rem_y); + if (res > 0) numsplt += res; + } + break; + } + } + + return numsplt; +} + +int pcb_trim_split(vtp0_t *cut_edges, vtp0_t *new_objs, pcb_any_obj_t *obj, double remo, rnd_coord_t rem_x, rnd_coord_t rem_y, int trim) +{ + int res = 0; + switch(obj->type) { + case PCB_OBJ_LINE: + if (trim) + res = pcb_trim_line(cut_edges, (pcb_line_t *)obj, remo, rem_x, rem_y); + else + res = pcb_split_line(cut_edges, new_objs, (pcb_line_t *)obj, remo, rem_x, rem_y); + break; + case PCB_OBJ_ARC: + if (trim) + res = pcb_trim_arc(cut_edges, (pcb_arc_t *)obj, remo, rem_x, rem_y); + else + res = pcb_split_arc(cut_edges, new_objs, (pcb_arc_t *)obj, remo, rem_x, rem_y); + break; + default: + return -1; + } + + if (res > 0) + pcb_undo_inc_serial(); + return res; +} + Index: tags/2.3.0/src_plugins/diag/Makefile =================================================================== --- tags/2.3.0/src_plugins/diag/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/diag/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_diag + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/diag/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/diag/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/diag/Plug.tmpasm (revision 33253) @@ -0,0 +1,14 @@ +put /local/pcb/mod {diag} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/diag/diag.o + $(PLUGDIR)/diag/diag_conf.o + $(PLUGDIR)/diag/integrity.o +@] +put /local/pcb/mod/CONF {$(PLUGDIR)/diag/diag_conf.h} + + +switch /local/pcb/diag/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/diag/diag.c =================================================================== --- tags/2.3.0/src_plugins/diag/diag.c (nonexistent) +++ tags/2.3.0/src_plugins/diag/diag.c (revision 33253) @@ -0,0 +1,602 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2019 Tibor 'Igor2' Palinkas + * + * This module, diag, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "board.h" +#include "data.h" +#include "data_it.h" +#include "flag_str.h" +#include "layer.h" +#include "diag_conf.h" +#include +#include +#include +#include +#include +#include "integrity.h" +#include +#include +#include +#include "search.h" +#include "plug_footprint.h" +#include "plug_io.h" +#include "funchash_core.h" +#include "conf_core.h" + +conf_diag_t conf_diag; + +static const char pcb_acts_DumpConf[] = + "dumpconf(native, [verbose], [prefix]) - dump the native (binary) config tree to stdout\n" + "dumpconf(lihata, role, [prefix]) - dump in-memory lihata representation of a config tree\n" + ; +static const char pcb_acth_DumpConf[] = "Perform various operations on the configuration tree."; + +extern lht_doc_t *pcb_conf_main_root[]; +extern lht_doc_t *pcb_conf_plug_root[]; +static fgw_error_t pcb_act_DumpConf(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + + RND_ACT_CONVARG(1, FGW_KEYWORD, DumpConf, op = fgw_keyword(&argv[1])); + + switch(op) { + case F_Native: + { + int verbose = 0; + const char *prefix = ""; + RND_ACT_MAY_CONVARG(2, FGW_INT, DumpConf, verbose = argv[2].val.nat_int); + RND_ACT_MAY_CONVARG(3, FGW_STR, DumpConf, prefix = argv[3].val.str); + conf_dump(stdout, prefix, verbose, NULL); + } + break; + case F_Lihata: + { + rnd_conf_role_t role; + const char *srole, *prefix = ""; + RND_ACT_CONVARG(2, FGW_STR, DumpConf, srole = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, DumpConf, prefix = argv[3].val.str); + role = rnd_conf_role_parse(srole); + if (role == RND_CFR_invalid) { + rnd_message(RND_MSG_ERROR, "Invalid role: '%s'\n", argv[1]); + RND_ACT_IRES(1); + return 0; + } + if (pcb_conf_main_root[role] != NULL) { + printf("%s### main\n", prefix); + if (pcb_conf_main_root[role] != NULL) + lht_dom_export(pcb_conf_main_root[role]->root, stdout, prefix); + printf("%s### plugin\n", prefix); + if (pcb_conf_plug_root[role] != NULL) + lht_dom_export(pcb_conf_plug_root[role]->root, stdout, prefix); + } + else + printf("%s \n", prefix); + } + break; + default: + RND_ACT_FAIL(DumpConf); + return 1; + } + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_EvalConf[] = + "EvalConf(path) - evaluate a config path in different config sources to figure how it ended up in the native database\n" + ; +static const char pcb_acth_EvalConf[] = "Perform various operations on the configuration tree."; + +static fgw_error_t pcb_act_EvalConf(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *path; + rnd_conf_native_t *nat; + int role; + + RND_ACT_CONVARG(1, FGW_STR, EvalConf, path = argv[1].val.str); + + nat = rnd_conf_get_field(path); + if (nat == NULL) { + rnd_message(RND_MSG_ERROR, "EvalConf: invalid path %s - no such config setting\n", path); + RND_ACT_IRES(-1); + return 0; + } + + printf("Conf node %s\n", path); + for(role = 0; role < RND_CFR_max_real; role++) { + lht_node_t *n; + printf(" Role: %s\n", rnd_conf_role_name(role)); + n = rnd_conf_lht_get_at(role, path, 0); + if (n != NULL) { + rnd_conf_policy_t pol = -1; + long prio = rnd_conf_default_prio[role]; + + + if (rnd_conf_get_policy_prio(n, &pol, &prio) == 0) + printf(" * policy=%s\n * prio=%ld\n", rnd_conf_policy_name(pol), prio); + + if (n->file_name != NULL) + printf(" * from=%s:%d.%d\n", n->file_name, n->line, n->col); + else + printf(" * from=(unknown)\n"); + + lht_dom_export(n, stdout, " "); + } + else + printf(" * not present\n"); + } + + printf(" Native:\n"); + rnd_conf_print_native((rnd_conf_pfn)rnd_fprintf, stdout, " ", 1, nat); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_DumpLayers[] = "dumplayers([all])\n"; +static const char pcb_acth_DumpLayers[] = "Print info about each layer"; + +extern lht_doc_t *pcb_conf_main_root[]; +static fgw_error_t pcb_act_DumpLayers(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op = -2, g, n, used; + rnd_layer_id_t arr[128]; /* WARNING: this assumes we won't have more than 128 layers */ + rnd_layergrp_id_t garr[128]; /* WARNING: this assumes we won't have more than 128 layers */ + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, DumpLayers, op = fgw_keyword(&argv[1])); + + if (op == F_All) { + printf("Per group:\n"); + for(g = 0; g < PCB->LayerGroups.len; g++) { + pcb_layergrp_t *grp = &PCB->LayerGroups.grp[g]; + printf(" Group %d: '%s' %x\n", g, grp->name, grp->ltype); + for(n = 0; n < grp->len; n++) { + pcb_layer_t *ly = pcb_get_layer(PCB->Data, grp->lid[n]); + if (ly != NULL) { + printf(" layer %d: '%s'\n", n, ly->name); + if (ly->meta.real.grp != g) + printf(" ERROR: invalid back-link to group: %ld should be %d\n", ly->meta.real.grp, g); + } + else + printf(" layer %d: \n", g); + } + } + + printf("Per layer:\n"); + for(n = 0; n < PCB->Data->LayerN; n++) { + pcb_layer_t *ly = &PCB->Data->Layer[n]; + printf(" layer %d: '%s'\n", n, ly->name); + if (ly->meta.real.grp >= 0) { + pcb_layergrp_t *grp = &PCB->LayerGroups.grp[ly->meta.real.grp]; + int i, ok = 0; + for(i = 0; i < grp->len; i++) { + if (grp->lid[i] == n) { + ok = 1; + break; + } + } + if (!ok) + printf(" ERROR: invalid back-link to group: %ld\n", ly->meta.real.grp); + } + } + + RND_ACT_IRES(0); + return 0; + } + + printf("Max: theoretical=%d current_board=%d\n", PCB_MAX_LAYER, pcb_max_layer(PCB)); + used = pcb_layer_list_any(PCB, PCB_LYT_ANYTHING | PCB_LYT_ANYWHERE | PCB_LYT_VIRTUAL, arr, sizeof(arr)/sizeof(arr[0])); + for(n = 0; n < used; n++) { + rnd_layer_id_t layer_id = arr[n]; + rnd_layergrp_id_t grp = pcb_layer_get_group(PCB, layer_id); + printf(" [%lx] %04x group=%ld %s\n", layer_id, pcb_layer_flags(PCB, layer_id), grp, pcb_layer_name(PCB->Data, layer_id)); + } + + /* query by logical layer: any bottom copper */ + used = pcb_layer_list(PCB, PCB_LYT_COPPER | PCB_LYT_BOTTOM, arr, sizeof(arr)/sizeof(arr[0])); + printf("All %d bottom copper layers are:\n", used); + for(n = 0; n < used; n++) { + rnd_layer_id_t layer_id = arr[n]; + printf(" [%lx] %s \n", layer_id, PCB->Data->Layer[layer_id].name); + } + + /* query by groups (physical layers): any copper in group */ + used = pcb_layergrp_list(PCB, PCB_LYT_COPPER, garr, sizeof(garr)/sizeof(garr[0])); + printf("All %d groups containing copper layers are:\n", used); + for(g = 0; g < used; g++) { + rnd_layergrp_id_t group_id = garr[g]; + printf(" group %ld (%d layers)\n", group_id, PCB->LayerGroups.grp[group_id].len); + for(n = 0; n < PCB->LayerGroups.grp[group_id].len; n++) { + rnd_layer_id_t layer_id = PCB->LayerGroups.grp[group_id].lid[n]; + printf(" [%lx] %s\n", layer_id, PCB->Data->Layer[layer_id].name); + } + } + + RND_ACT_IRES(0); + return 0; +} + + +static void print_font(pcb_font_t *f, const char *prefix) +{ + int n, g = 0, gletter = 0, gdigit = 0; + const char *name; + + /* count valid glyphs and classes */ + for(n = 0; n < PCB_MAX_FONTPOSITION + 1; n++) { + if (f->Symbol[n].Valid) { + g++; + if (isalpha(n)) gletter++; + if (isdigit(n)) gdigit++; + } + } + + name = f->name == NULL ? "" : f->name; + rnd_printf("%s: %d %s; dim: %$$mm * %$$mm glyphs: %d (letter: %d, digit: %d)\n", prefix, f->id, name, f->MaxWidth, f->MaxHeight, g, gletter, gdigit); +} + +static const char dump_fonts_syntax[] = "dumpfonts()\n"; +static const char dump_fonts_help[] = "Print info about fonts"; +static fgw_error_t pcb_act_DumpFonts(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + printf("Font summary:\n"); + print_font(&PCB->fontkit.dflt, " Default"); + if (PCB->fontkit.hash_inited) { + htip_entry_t *e; + for (e = htip_first(&PCB->fontkit.fonts); e; e = htip_next(&PCB->fontkit.fonts, e)) + print_font(e->value, " Extra "); + } + else + printf(" \n"); + RND_ACT_IRES(0); + return 0; +} + +#ifndef NDEBUG +extern void undo_dump(void); +static const char dump_undo_syntax[] = "dumpfonts()\n"; +static const char dump_undo_help[] = "Print info about fonts"; +static fgw_error_t pcb_act_DumpUndo(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + printf("Undo:\n"); + undo_dump(); + RND_ACT_IRES(0); + return 0; +} +#endif + +typedef enum { /* bitfield */ + DD_DRC = 1, + DD_COPPER_ONLY = 2 +} dd_flags; + +static void dump_data(pcb_data_t *data, dd_flags what, int ind, const char *parent) +{ + pcb_any_obj_t *o; + pcb_data_it_t it; + ind++; + for(o = pcb_data_first(&it, data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + const char *type = pcb_obj_type_name(o->type); + rnd_coord_t cx, cy; + + if ((what & DD_COPPER_ONLY) && (o->type == PCB_OBJ_SUBC)) + goto skip; + + if ((what & DD_COPPER_ONLY) && (o->parent_type == PCB_PARENT_LAYER)) { + pcb_layer_type_t lyt = pcb_layer_flags_(o->parent.layer); + if (!(lyt & PCB_LYT_COPPER)) + goto skip; + } + + cx = (o->BoundingBox.X1+o->BoundingBox.X2)/2; + cy = (o->BoundingBox.Y1+o->BoundingBox.Y2)/2; + printf("%*s %s", ind, "", type); + rnd_printf(" #%ld %mm;%mm ", o->ID, cx, cy); + + if (parent != NULL) + printf("%s", parent); + printf("-"); + if (o->term != NULL) + printf("%s", o->term); + + if (what & DD_DRC) + printf(" DRC=%c%c", PCB_FLAG_TEST(PCB_FLAG_FOUND, o) ? 'f':'.', PCB_FLAG_TEST(PCB_FLAG_SELECTED, o) ? 's':'.'); + + printf("\n"); + + skip:; + if (o->type == PCB_OBJ_SUBC) + dump_data(((pcb_subc_t *)o)->data, what, ind, ((pcb_subc_t *)o)->refdes); + } +} + +static const char dump_data_syntax[] = "dumpdata()\n"; +static const char dump_data_help[] = "Dump an aspect of the data"; +static fgw_error_t pcb_act_DumpData(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + dd_flags what = DD_DRC | DD_COPPER_ONLY; + printf("DumpData:\n"); + dump_data(PCB->Data, what, 0, NULL); + printf("\n"); + RND_ACT_IRES(0); + return 0; +} + +static const char integrity_syntax[] = "integrity()\n"; +static const char integrity_help[] = "perform integrirty check on the current board and generate errors if needed"; +static fgw_error_t pcb_act_integrity(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_check_integrity(PCB); + RND_ACT_IRES(0); + return 0; +} + +static int dumpflag_cb(void *ctx, gds_t *s, const char **input) +{ + pcb_flag_bits_t *flag = (pcb_flag_bits_t *)ctx; + switch(**input) { + case 'm': (*input)++; rnd_append_printf(s, "%lx", flag->mask); break; + case 'M': (*input)++; gds_append_str(s, flag->mask_name); break; + case 'N': (*input)++; gds_append_str(s, flag->name); break; + case 't': (*input)++; rnd_append_printf(s, "%lx", flag->object_types); break; + case 'H': (*input)++; gds_append_str(s, flag->name); break; + default: + return -1; + } + return 0; +} + +static const char pcb_acts_dumpflags[] = "dumpflags([fmt])\n"; +static const char pcb_acth_dumpflags[] = "dump flags, optionally using the format string provided by the user"; +static fgw_error_t pcb_act_dumpflags(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int n; + const char *default_fmt = "%m (%M %N) for %t:\n %H\n"; + const char *fmt = default_fmt; + + RND_ACT_MAY_CONVARG(1, FGW_STR, dumpflags, fmt = argv[1].val.str); + + for(n = 0; n < pcb_object_flagbits_len; n++) { + char *tmp; + tmp = rnd_strdup_subst(fmt, dumpflag_cb, &pcb_object_flagbits[n], RND_SUBST_PERCENT /*| RND_SUBST_BACKSLASH*/); + printf("%s", tmp); + free(tmp); + } + + RND_ACT_IRES(0); + return 0; +} + +static void ev_ui_post(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + + if (conf_diag.plugins.diag.auto_integrity) { + static int cnt = 0; + if ((cnt++ % 100) == 0) { + rnd_trace("Number of integrity checks so far: %d\n", cnt); + } + pcb_check_integrity(PCB); + } +} + +static const char pcb_acts_d1[] = "d1()\n"; +static const char pcb_acth_d1[] = "debug action for development"; +static fgw_error_t pcb_act_d1(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_DumpIDs[] = "DumpIDs()\n"; +static const char pcb_acth_DumpIDs[] = "Dump the ID hash"; +static fgw_error_t pcb_act_DumpIDs(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_data_t *data = PCB->Data; + htip_entry_t *e; + + for(e = htip_first(&data->id2obj); e; e = htip_next(&data->id2obj, e)) { + pcb_any_obj_t *o = e->value; + if (o == NULL) + printf("%ld: NULL\n", e->key); + else + printf("%ld: %p %ld %s%s\n", e->key, (void *)o, o->ID, pcb_obj_type_name(o->type), (o->ID == e->key) ? "" : " BROKEN"); + } + + RND_ACT_IRES(0); + return 0; +} + +#include "find.h" +static const char pcb_acts_Find2Perf[] = "find2perf()\n"; +static const char pcb_acth_Find2Perf[] = "Measure the peformance of find2.c"; +static fgw_error_t pcb_act_Find2Perf(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + double from, now, end, duration = 4.0; + long its = 0, pins = 0; + pcb_find_t fctx; + + memset(&fctx, 0, sizeof(fctx)); + + PCB_SUBC_LOOP(PCB->Data) { + PCB_PADSTACK_LOOP(subc->data) { + pins++; + } + PCB_END_LOOP; + } + PCB_END_LOOP; + + rnd_message(RND_MSG_INFO, "Measuring find.c peformance for %f seconds starting from %ld pins...\n", duration, pins); + + from = rnd_dtime(); + end = from + duration; + do { + PCB_SUBC_LOOP(PCB->Data) { + PCB_PADSTACK_LOOP(subc->data) { + pcb_find_from_obj(&fctx, PCB->Data, (pcb_any_obj_t *)padstack); + pcb_find_free(&fctx); + } + PCB_END_LOOP; + } + PCB_END_LOOP; + its++; + now = rnd_dtime(); + } while(now < end); + rnd_message(RND_MSG_INFO, "find2.c peformance: %d %f pin find per second\n", its, (double)its * (double)pins / (now-from)); + RND_ACT_IRES(0); + return 0; +} + + +#define DLF_PREFIX " " +#define SCRATCH pcb_buffers[PCB_MAX_BUFFER-1] +static const char pcb_acts_DumpLibFootprint[] = "DumpLibFootprint(footprintname, [bbox|origin])\n"; +static const char pcb_acth_DumpLibFootprint[] = "print footprint file and metadata to stdout"; +static fgw_error_t pcb_act_DumpLibFootprint(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fpn, *opt; + FILE *f; + pcb_fp_fopen_ctx_t fctx; + int n, want_bbox = 0, want_origin = 0; + + RND_ACT_CONVARG(1, FGW_STR, DumpLibFootprint, fpn = argv[1].val.str); + + for(n = 2; n < argc; n++) { + RND_ACT_CONVARG(n, FGW_STR, DumpLibFootprint, opt = argv[n].val.str); + if (strcmp(opt, "bbox") == 0) want_bbox = 1; + else if (strcmp(opt, "origin") == 0) want_origin = 1; + else RND_ACT_FAIL(DumpLibFootprint); + } + + f = pcb_fp_fopen(&conf_core.rc.library_search_paths, fpn, &fctx, PCB->Data); + if ((f != PCB_FP_FOPEN_IN_DST) && (f != NULL)) { + + /* dump file content */ + printf(DLF_PREFIX "data begin\n"); + while(!feof(f)) { + char buff[1024]; + int len = fread(buff, 1, sizeof(buff), f); + if (len > 0) + fwrite(buff, 1, len, stdout); + } + printf(DLF_PREFIX "data end\n"); + pcb_fp_fclose(f, &fctx); + + /* print exrtas */ + if (want_bbox || want_origin) { + pcb_buffer_clear(PCB, &SCRATCH); + if (!pcb_buffer_load_footprint(&SCRATCH, fctx.filename, NULL)) { + RND_ACT_IRES(1); + return 0; + } + } + + if (want_bbox) + rnd_printf(DLF_PREFIX "bbox mm %mm %mm %mm %mm\n", SCRATCH.BoundingBox.X1, SCRATCH.BoundingBox.Y1, SCRATCH.BoundingBox.X2, SCRATCH.BoundingBox.Y2); + if (want_origin) + rnd_printf(DLF_PREFIX "origin mm %mm %mm\n", SCRATCH.X, SCRATCH.Y); + + RND_ACT_IRES(0); + } + else { + pcb_fp_fclose(f, &fctx); + printf(DLF_PREFIX "error file not found\n"); + RND_ACT_IRES(1); + } + + return 0; +} + +#define PCB_FORCECOLOR_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_TEXT | PCB_OBJ_SUBC | PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_SUBC_PART | PCB_OBJ_SUBC | PCB_OBJ_RAT) + +static const char pcb_acts_forcecolor[] = "forcecolor(#RRGGBB)\n"; +static const char pcb_acth_forcecolor[] = "change selected objects' color to #RRGGBB, reset if does not start with '#'"; +static fgw_error_t pcb_act_forcecolor(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_coord_t x, y; + int type; + void *ptr1, *ptr2, *ptr3; + const char *new_color; + + RND_ACT_CONVARG(1, FGW_STR, forcecolor, new_color = argv[1].val.str); + + rnd_hid_get_coords("Click on object to change", &x, &y, 0); + + if ((type = pcb_search_screen(x, y, PCB_FORCECOLOR_TYPES, &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) { + pcb_any_obj_t *o = (pcb_any_obj_t *)ptr2; + if (o->override_color == NULL) + o->override_color = malloc(sizeof(rnd_color_t)); + rnd_color_load_str(o->override_color, new_color); + } + + RND_ACT_IRES(0); + return 0; +} + +rnd_action_t diag_action_list[] = { + {"dumpconf", pcb_act_DumpConf, pcb_acth_DumpConf, pcb_acts_DumpConf}, + {"dumplayers", pcb_act_DumpLayers, pcb_acth_DumpLayers, pcb_acts_DumpLayers}, + {"dumpfonts", pcb_act_DumpFonts, dump_fonts_help, dump_fonts_syntax}, + {"dumpdata", pcb_act_DumpData, dump_data_help, dump_data_syntax}, +#ifndef NDEBUG + {"dumpundo", pcb_act_DumpUndo, dump_undo_help, dump_undo_syntax}, +#endif + {"EvalConf", pcb_act_EvalConf, pcb_acth_EvalConf, pcb_acts_EvalConf}, + {"d1", pcb_act_d1, pcb_acth_d1, pcb_acts_d1}, + {"find2perf", pcb_act_Find2Perf, pcb_acth_Find2Perf, pcb_acts_Find2Perf}, + {"integrity", pcb_act_integrity, integrity_help, integrity_syntax}, + {"dumpflags", pcb_act_dumpflags, pcb_acth_dumpflags, pcb_acts_dumpflags}, + {"dumpids", pcb_act_DumpIDs, pcb_acth_DumpIDs, pcb_acts_DumpIDs}, + {"DumpLibFootprint", pcb_act_DumpLibFootprint, pcb_acth_DumpLibFootprint, pcb_acts_DumpLibFootprint}, + {"forcecolor", pcb_act_forcecolor, pcb_acth_forcecolor, pcb_acts_forcecolor} +}; + +static const char *diag_cookie = "diag plugin"; + +int pplg_check_ver_diag(int ver_needed) { return 0; } + +void pplg_uninit_diag(void) +{ + rnd_remove_actions_by_cookie(diag_cookie); + rnd_conf_unreg_fields("plugins/diag/"); + rnd_event_unbind_allcookie(diag_cookie); +} + +int pplg_init_diag(void) +{ + RND_API_CHK_VER; + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_diag, field,isarray,type_name,cpath,cname,desc,flags); +#include "diag_conf_fields.h" + + rnd_event_bind(RND_EVENT_USER_INPUT_POST, ev_ui_post, NULL, diag_cookie); + RND_REGISTER_ACTIONS(diag_action_list, diag_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/diag/diag.pup =================================================================== --- tags/2.3.0/src_plugins/diag/diag.pup (nonexistent) +++ tags/2.3.0/src_plugins/diag/diag.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short diagnostic acts. for devs +$long Actions for pcb-rnd core diagnostics, intended for developers. These are not in core because end users normally don't need these. As a plugin, due to dynamic loading, it can be dropped on an existing pcb-rnd installation with minimal risk of scaring away a reproducible bug. +$package debug +$state works +default disable +autoload 1 Index: tags/2.3.0/src_plugins/diag/diag_conf.c =================================================================== --- tags/2.3.0/src_plugins/diag/diag_conf.c (nonexistent) +++ tags/2.3.0/src_plugins/diag/diag_conf.c (revision 33253) @@ -0,0 +1,46 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include + +void conf_dump(FILE *f, const char *prefix, int verbose, const char *match_prefix) +{ + htsp_entry_t *e; + int pl; + + if (match_prefix != NULL) + pl = strlen(match_prefix); + + for (e = htsp_first(rnd_conf_fields); e; e = htsp_next(rnd_conf_fields, e)) { + rnd_conf_native_t *node = (rnd_conf_native_t *)e->value; + if (match_prefix != NULL) { + if (strncmp(node->hash_path, match_prefix, pl) != 0) + continue; + } + rnd_conf_print_native((rnd_conf_pfn)rnd_fprintf, f, prefix, verbose, node); + } +} Index: tags/2.3.0/src_plugins/diag/diag_conf.h =================================================================== --- tags/2.3.0/src_plugins/diag/diag_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/diag/diag_conf.h (revision 33253) @@ -0,0 +1,20 @@ +#ifndef PCB_DIAG_CONF_H +#define PCB_DIAG_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN auto_integrity; /* Enable (expensive) automatic integrity check after each user action */ + } diag; + } plugins; +} conf_diag_t; + +extern conf_diag_t conf_diag; + +/* Print all configuration items to f, prefixing each line with prefix + If match_prefix is not NULL, print only items with matching path prefix */ +void conf_dump(FILE *f, const char *prefix, int verbose, const char *match_prefix); + +#endif Index: tags/2.3.0/src_plugins/diag/integrity.c =================================================================== --- tags/2.3.0/src_plugins/diag/integrity.c (nonexistent) +++ tags/2.3.0/src_plugins/diag/integrity.c (revision 33253) @@ -0,0 +1,355 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "board.h" +#include "data.h" +#include +#include "undo.h" + +#define CHK "Broken integrity: " + +#define check_type(obj, exp_type) \ + do { \ + pcb_any_obj_t *__obj__ = (pcb_any_obj_t *)(obj); \ + if (__obj__->type != exp_type) \ + rnd_message(RND_MSG_ERROR, CHK "%s %ld type broken (%d != %d)\n", pcb_obj_type_name(exp_type), __obj__->ID, __obj__->type, exp_type); \ + } while(0) + +#define check_parent(name, obj, pt, prnt) \ + do { \ + if (obj->parent_type != pt) \ + rnd_message(RND_MSG_ERROR, CHK "%s " name " %ld parent type broken (%d != %d)\n", whose, obj->ID, obj->parent_type, pt); \ + else if (obj->parent.any != prnt) \ + rnd_message(RND_MSG_ERROR, CHK "%s " name " %ld parent type broken (%p != %p)\n", whose, obj->ID, obj->parent.any, prnt); \ + } while(0) + +#define check_obj_id(name, data, obj) \ + do { \ + pcb_any_obj_t *__ao__ = htip_get(&data->id2obj, obj->ID); \ + if (__ao__ != (pcb_any_obj_t *)obj) \ + rnd_message(RND_MSG_ERROR, CHK "%s " name " %ld id hash broken (%p != %p)\n", whose, obj->ID, obj, __ao__); \ + id_chk_cnt++; \ + } while(0) + + +#define chk_attr(name, obj) \ + do { \ + if (((obj)->Attributes.Number > 0) && ((obj)->Attributes.List == NULL)) \ + rnd_message(RND_MSG_ERROR, CHK "%s " name " %ld broken empty attribute list\n", whose, (obj)->ID); \ + } while(0) + +#define check_field_eq(name, obj, st1, st2, fld, fmt) \ + do { \ + if ((st1)->fld != (st2)->fld) \ + rnd_message(RND_MSG_ERROR, CHK "%s " name " field ." #fld " value mismatch (" fmt " != " fmt ")\n", whose, obj->ID, (st1)->fld, (st2)->fld); \ + } while(0) + +static void chk_layers(const char *whose, pcb_data_t *data, pcb_parenttype_t pt, void *parent, int name_chk); + +static void chk_term(const char *whose, pcb_any_obj_t *obj) +{ + const char *aterm = pcb_attribute_get(&obj->Attributes, "term"); + const char *s_intconn = pcb_attribute_get(&obj->Attributes, "intconn"); + + if (pcb_obj_id_invalid(aterm)) + rnd_message(RND_MSG_ERROR, CHK "%s %ld has term attribute '%s' with invalid characters\n", whose, obj->ID, aterm); + + if ((aterm == NULL) && (obj->term == NULL)) + return; + if (obj->term == NULL) { + rnd_message(RND_MSG_ERROR, CHK "%s %ld has term attribute '%s' but no ->term set\n", whose, obj->ID, aterm); + return; + } + if (aterm == NULL) { + rnd_message(RND_MSG_ERROR, CHK "%s %ld has ->term '%s' but no attribute term set\n", whose, obj->ID, obj->term); + return; + } + if (aterm != obj->term) { + rnd_message(RND_MSG_ERROR, CHK "%s %ld has mismatching pointer of ->term ('%s') and attribute term ('%s')\n", whose, obj->ID, obj->term, aterm); + return; + } + + if (s_intconn != NULL) { + char *end; + long intconn = strtol(s_intconn, &end, 10); + if (*end == '\0') { + if (intconn != obj->intconn) { + rnd_message(RND_MSG_ERROR, CHK "%s %ld has mismatching intconn: cached is %d, attribute is '%s'\n", whose, obj->ID, obj->intconn, s_intconn); + return; + } + } + } +} + +static void chk_subc_cache(pcb_subc_t *subc) +{ + const char *arefdes = pcb_attribute_get(&subc->Attributes, "refdes"); + + if (pcb_obj_id_invalid(arefdes)) + rnd_message(RND_MSG_ERROR, CHK "subc %ld has refdes attribute '%s' with invalid characters\n", subc->ID, arefdes); + + if ((subc->BoundingBox.X2 < 0) || (subc->BoundingBox.Y2 < 0)) + rnd_message(RND_MSG_ERROR, CHK "subc %ld is on negative coordinates; its bottom right corner is %$mm;%$mm\n", subc->ID, subc->BoundingBox.X2, subc->BoundingBox.Y2); + + if ((subc->BoundingBox.X1 > PCB->hidlib.size_x) || (subc->BoundingBox.Y1 > PCB->hidlib.size_y)) + rnd_message(RND_MSG_ERROR, CHK "subc %ld is olost beyond board extents; its top left corner is %$mm;%$mm\n", subc->ID, subc->BoundingBox.X1, subc->BoundingBox.Y1); + + if ((arefdes == NULL) && (subc->refdes == NULL)) + return; + if (subc->refdes == NULL) { + rnd_message(RND_MSG_ERROR, CHK "subc %ld has refdes attribute '%s' but no ->refdes set\n", subc->ID, arefdes); + return; + } + if (arefdes == NULL) { + rnd_message(RND_MSG_ERROR, CHK "subc %ld has ->refdes '%s' but no attribute refdes set\n", subc->ID, subc->refdes); + return; + } + if (arefdes != subc->refdes) { + rnd_message(RND_MSG_ERROR, CHK "subc %ld has mismatching pointer of ->refdes ('%s') and attribute refdes ('%s')\n", subc->ID, subc->refdes, arefdes); + return; + } +} + + +static void chk_subc(const char *whose, pcb_subc_t *subc) +{ + int n; + pcb_pstk_t *ps; + rnd_coord_t dummy; + double dummy2; + + chk_layers("subc", subc->data, PCB_PARENT_SUBC, subc, 0); + chk_subc_cache(subc); + + if (pcb_subc_get_origin(subc, &dummy, &dummy) != 0) + rnd_message(RND_MSG_ERROR, CHK "%s %ld: can not determine subc origin\n", whose, subc->ID); + if (pcb_subc_get_rotation(subc, &dummy2) != 0) + rnd_message(RND_MSG_ERROR, CHK "%s %ld: can not determine subc rotation\n", whose, subc->ID); + if (pcb_subc_get_side(subc, &dummy) != 0) + rnd_message(RND_MSG_ERROR, CHK "%s %ld: can not determine subc side\n", whose, subc->ID); + + /* check term chaches */ + for(ps = padstacklist_first(&subc->data->padstack); ps != NULL; ps = padstacklist_next(ps)) + chk_term("padstack", (pcb_any_obj_t *)ps); + + for(n = 0; n < subc->data->LayerN; n++) { + pcb_layer_t *ly = &subc->data->Layer[n]; + pcb_line_t *lin; + pcb_arc_t *arc; + pcb_text_t *txt; + pcb_poly_t *pol; + + if (!ly->is_bound) + rnd_message(RND_MSG_ERROR, CHK "%ld subc layer %ld is not a bound layer\n", subc->ID, n); + + for(lin = linelist_first(&ly->Line); lin != NULL; lin = linelist_next(lin)) + chk_term("line", (pcb_any_obj_t *)lin); + + for(arc = arclist_first(&ly->Arc); arc != NULL; arc = arclist_next(arc)) + chk_term("arc", (pcb_any_obj_t *)arc); + + for(txt = textlist_first(&ly->Text); txt != NULL; txt = textlist_next(txt)) + chk_term("text", (pcb_any_obj_t *)txt); + + for(pol = polylist_first(&ly->Polygon); pol != NULL; pol = polylist_next(pol)) + chk_term("polygon", (pcb_any_obj_t *)pol); + } +} + +/* Check layers and objects: walk the tree top->down and check ->parent + references from any node */ +static void chk_layers(const char *whose, pcb_data_t *data, pcb_parenttype_t pt, void *parent, int name_chk) +{ + rnd_layer_id_t n; + long id_chk_cnt = 0; + htip_entry_t *e; + + if (data->parent_type != pt) + rnd_message(RND_MSG_ERROR, CHK "%s data: parent type broken (%d != %d)\n", whose, data->parent_type, pt); + else if (data->parent.any != parent) + rnd_message(RND_MSG_ERROR, CHK "%s data: parent broken (%p != %p)\n", whose, data->parent, parent); + + + for(n = 0; n < data->LayerN; n++) { + pcb_line_t *lin; + pcb_text_t *txt; + pcb_arc_t *arc; + pcb_poly_t *poly; + pcb_layergrp_t *grp; + + /* check layers */ + if (data->Layer[n].parent.data != data) + rnd_message(RND_MSG_ERROR, CHK "%s layer %ld/%s parent broken (%p != %p)\n", whose, n, data->Layer[n].name, data->Layer[n].parent, data); + if (name_chk && ((data->Layer[n].name == NULL) || (*data->Layer[n].name == '\0'))) + rnd_message(RND_MSG_ERROR, CHK "%s layer %ld has invalid name\n", whose, n); + check_type(&data->Layer[n], PCB_OBJ_LAYER); + check_parent("layer", (&data->Layer[n]), PCB_PARENT_DATA, data); + chk_attr("layer", &data->Layer[n]); + + if (!data->Layer[n].is_bound) { + grp = pcb_get_layergrp(data->parent.board, data->Layer[n].meta.real.grp); + if (grp != NULL) { + int i, found = 0; + for(i = 0; i < grp->len; i++) { + if (grp->lid[i] == n) { + found = 1; + break; + } + } + if (!found) + rnd_message(RND_MSG_ERROR, CHK "%s layer %ld is linked to group %ld but the group does not link back to the layer\n", whose, n, data->Layer[n].meta.real.grp); + } + else + rnd_message(RND_MSG_ERROR, CHK "%s layer %ld is linked to non-existing group %ld\n", whose, n, data->Layer[n].meta.real.grp); + } + + if (data->Layer[n].is_bound) { + if ((data->Layer[n].meta.bound.type & PCB_LYT_BOUNDARY) && (data->Layer[n].meta.bound.type & PCB_LYT_ANYWHERE)) + rnd_message(RND_MSG_ERROR, CHK "%s layer %ld/%s is a non-global boundary (bound layer)\n", whose, n, data->Layer[n].name); + } + + /* check layer objects */ + for(lin = linelist_first(&data->Layer[n].Line); lin != NULL; lin = linelist_next(lin)) { + check_parent("line", lin, PCB_PARENT_LAYER, &data->Layer[n]); + check_obj_id("line", data, lin); + check_type(lin, PCB_OBJ_LINE); + chk_attr("line", lin); + } + + for(txt = textlist_first(&data->Layer[n].Text); txt != NULL; txt = textlist_next(txt)) { + check_parent("text", txt, PCB_PARENT_LAYER, &data->Layer[n]); + check_obj_id("text", data, txt); + check_type(txt, PCB_OBJ_TEXT); + chk_attr("text", txt); + } + + for(poly = polylist_first(&data->Layer[n].Polygon); poly != NULL; poly = polylist_next(poly)) { + check_parent("polygon", poly, PCB_PARENT_LAYER, &data->Layer[n]); + check_obj_id("polygon", data, poly); + check_type(poly, PCB_OBJ_POLY); + chk_attr("polygon", poly); + } + + for(arc = arclist_first(&data->Layer[n].Arc); arc != NULL; arc = arclist_next(arc)) { + check_parent("arc", arc, PCB_PARENT_LAYER, &data->Layer[n]); + check_obj_id("arc", data, arc); + check_type(arc, PCB_OBJ_ARC); + chk_attr("arc", arc); + } + } + + /* check global objects */ + { + pcb_subc_t *subc; + pcb_pstk_t *ps; + pcb_rat_t *rat; + + for(ps = padstacklist_first(&data->padstack); ps != NULL; ps = padstacklist_next(ps)) { + check_parent("padstack", ps, PCB_PARENT_DATA, data); + check_obj_id("padstack", data, ps); + check_type(ps, PCB_OBJ_PSTK); + chk_attr("padstack", ps); + chk_term("padstack", (pcb_any_obj_t *)ps); + } + + for(subc = pcb_subclist_first(&data->subc); subc != NULL; subc = pcb_subclist_next(subc)) { + check_parent("subc", subc, PCB_PARENT_DATA, data); + check_obj_id("subc", data, subc); + check_type(subc, PCB_OBJ_SUBC); + chk_subc(whose, subc); + chk_attr("subc", subc); + } + + /* check rat line objects */ + for(rat = ratlist_first(&data->Rat); rat != NULL; rat = ratlist_next(rat)) { + check_parent("rat", rat, PCB_PARENT_DATA, data); + check_obj_id("rat", data, rat); + check_type(rat, PCB_OBJ_RAT); + chk_attr("rat", rat); + } + } + + /* Safe check for the other way around: if the hash contains more entries + than the objects we checked above, we have some garbage left; the check + is safe because it is not needed to dereference the garbage */ + for(e = htip_first(&data->id2obj); e; e = htip_next(&data->id2obj, e)) { + id_chk_cnt--; + } + if (id_chk_cnt != 0) + rnd_message(RND_MSG_ERROR, CHK "id hash contains %ld excess IDs in %s\n", id_chk_cnt, whose); +} + +static void chk_layergrps(pcb_board_t *pcb) +{ + rnd_layergrp_id_t n; + const char *whose = "board"; + + for(n = 0; n < pcb->LayerGroups.len; n++) { + pcb_layergrp_t *grp = &pcb->LayerGroups.grp[n]; + int i, i2; + + check_parent("layer_group", grp, PCB_PARENT_BOARD, pcb); + check_type(grp, PCB_OBJ_LAYERGRP); + if ((grp->ltype & PCB_LYT_BOUNDARY) && (grp->ltype & PCB_LYT_ANYWHERE)) + rnd_message(RND_MSG_ERROR, CHK "layer group %ld/%s is a non-global boundary\n", n, grp->name); + + for(i = 0; i < grp->len; i++) { + pcb_layer_t *ly; + + for(i2 = 0; i2 < i; i2++) + if (grp->lid[i] == grp->lid[i2]) + rnd_message(RND_MSG_ERROR, CHK "layer group %ld/%s has duplicate layer entry: %ld\n", n, grp->name, (long)grp->lid[i]); + + ly = pcb_get_layer(pcb->Data, grp->lid[i]); + if (ly != NULL) { + if (ly->meta.real.grp != n) + rnd_message(RND_MSG_ERROR, CHK "layer group %ld/%s conains layer %ld/%s but it doesn't link back to the group but links to %ld instead \n", n, grp->name, (long)grp->lid[i], ly->name, ly->meta.real.grp); + } + else + rnd_message(RND_MSG_ERROR, CHK "layer group %ld/%s contains invalid layer entry: %ld\n", n, grp->name, (long)grp->lid[i]); + } + } +} + + +void pcb_check_integrity(pcb_board_t *pcb) +{ + int n; + + chk_layergrps(pcb); + chk_layers("board", pcb->Data, PCB_PARENT_BOARD, pcb, 1); + + for (n = 0; n < PCB_MAX_BUFFER; n++) { + char bn[16]; + sprintf(bn, "buffer #%d", n); + chk_layers(bn, pcb_buffers[n].Data, PCB_PARENT_INVALID, NULL, 0); + } + + if (undo_check() != 0) + rnd_message(RND_MSG_ERROR, CHK "undo\n"); +} Index: tags/2.3.0/src_plugins/diag/integrity.h =================================================================== --- tags/2.3.0/src_plugins/diag/integrity.h (nonexistent) +++ tags/2.3.0/src_plugins/diag/integrity.h (revision 33253) @@ -0,0 +1,3 @@ +#include "board.h" +void pcb_check_integrity(pcb_board_t *pcb); + Index: tags/2.3.0/src_plugins/dialogs/Makefile =================================================================== --- tags/2.3.0/src_plugins/dialogs/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_dialogs + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/dialogs/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/dialogs/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/Plug.tmpasm (revision 33253) @@ -0,0 +1,23 @@ +put /local/pcb/mod {dialogs} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/dialogs/dialogs.o + $(PLUGDIR)/dialogs/dlg_about.o + $(PLUGDIR)/dialogs/dlg_export.o + $(PLUGDIR)/dialogs/dlg_flag_edit.o + $(PLUGDIR)/dialogs/dlg_fontsel.o + $(PLUGDIR)/dialogs/dlg_layer_binding.o + $(PLUGDIR)/dialogs/dlg_layer_flags.o + $(PLUGDIR)/dialogs/dlg_infobar.o + $(PLUGDIR)/dialogs/dlg_lib_pstk.o + $(PLUGDIR)/dialogs/dlg_library.o + $(PLUGDIR)/dialogs/dlg_loadsave.o + $(PLUGDIR)/dialogs/dlg_padstack.o + $(PLUGDIR)/dialogs/dlg_pref.o + $(PLUGDIR)/dialogs/dlg_view.o +@] + +switch /local/pcb/dialogs/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/dialogs/dialogs.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dialogs.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dialogs.c (revision 33253) @@ -0,0 +1,132 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017..2019 Tibor 'Igor2' Palinkas + * + * This module, dialogs, was written and is Copyright (C) 2017 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include "funchash_core.h" +#include + +/* from lib_hid_common */ +extern conf_dialogs_t dialogs_conf; + +/* include them all for static inlines */ +#include "dlg_test.c" +#include "dlg_about.h" +#include "dlg_export.h" +#include "dlg_flag_edit.h" +#include "dlg_fontsel.h" +#include "dlg_infobar.h" +#include "dlg_layer_binding.h" +#include "dlg_layer_flags.h" +#include "dlg_lib_pstk.h" +#include "dlg_library.h" +#include "dlg_loadsave.h" +#include "dlg_padstack.h" +#include "dlg_pinout.c" +#include "dlg_undo.c" +#include "dlg_fpmap.c" +#include "dlg_obj_list.c" +#include "dlg_netlist.c" +#include "dlg_plugins.c" +#include "dlg_printcalib.c" + +#include "dlg_view.h" +#include "dlg_pref.h" + +extern const char pcb_acts_dlg_confval_edit[]; +extern const char pcb_acth_dlg_confval_edit[]; +extern fgw_error_t pcb_act_dlg_confval_edit(fgw_arg_t *res, int argc, fgw_arg_t *argv); + + +rnd_action_t dialogs_action_list[] = { + {"dlg_test", pcb_act_dlg_test, dlg_test_help, dlg_test_syntax}, + {"dlg_confval_edit", pcb_act_dlg_confval_edit, pcb_acth_dlg_confval_edit, pcb_acts_dlg_confval_edit}, + {"LayerBinding", pcb_act_LayerBinding, pcb_acth_LayerBinding, pcb_acts_LayerBinding}, + {"FlagEdit", pcb_act_FlagEdit, pcb_acth_FlagEdit, pcb_acts_FlagEdit}, + {"PadstackEdit", pcb_act_PadstackEdit, pcb_acth_PadstackEdit, pcb_acts_PadstackEdit}, + {"About", pcb_act_About, pcb_acth_About, pcb_acts_About}, + {"Pinout", pcb_act_Pinout, pcb_acth_Pinout, pcb_acts_Pinout}, + {"ExportGUI", pcb_act_ExportGUI, pcb_acth_ExportGUI, pcb_acts_ExportGUI}, + {"PrintGUI", pcb_act_PrintGUI, pcb_acth_PrintGUI, pcb_acts_PrintGUI}, + {"GroupPropGui", pcb_act_GroupPropGui, pcb_acth_GroupPropGui, pcb_acts_GroupPropGui}, + {"LayerPropGui", pcb_act_LayerPropGui, pcb_acth_LayerPropGui, pcb_acts_LayerPropGui}, + {"Preferences", pcb_act_Preferences, pcb_acth_Preferences, pcb_acts_Preferences}, + {"pstklib", pcb_act_pstklib, pcb_acth_pstklib, pcb_acts_pstklib}, + {"UndoDialog", pcb_act_UndoDialog, pcb_acth_UndoDialog, pcb_acts_UndoDialog}, + {"NetlistDialog", pcb_act_NetlistDialog, pcb_acth_NetlistDialog, pcb_acts_NetlistDialog}, + {"ManagePlugins", pcb_act_ManagePlugins, pcb_acth_ManagePlugins, pcb_acts_ManagePlugins}, + {"DrcDialog", pcb_act_DrcDialog, pcb_acth_DrcDialog, pcb_acts_DrcDialog}, + {"IOIncompatListDialog", pcb_act_IOIncompatListDialog, pcb_acth_IOIncompatListDialog, pcb_acts_IOIncompatListDialog}, + {"ViewList", pcb_act_ViewList, pcb_acth_ViewList, pcb_acts_ViewList}, + {"Fontsel", pcb_act_Fontsel, pcb_acth_Fontsel, pcb_acts_Fontsel}, + {"PrintCalibrate", pcb_act_PrintCalibrate, pcb_acth_PrintCalibrate, pcb_acts_PrintCalibrate}, + {"Load", pcb_act_Load, pcb_acth_Load, pcb_acts_Load}, + {"Save", pcb_act_Save, pcb_acth_Save, pcb_acts_Save}, + {"LibraryDialog", pcb_act_LibraryDialog, pcb_acth_LibraryDialog, pcb_acts_LibraryDialog}, + {"InfoBarFileChanged", pcb_act_InfoBarFileChanged, pcb_acth_InfoBarFileChanged, pcb_acts_InfoBarFileChanged}, + {"dlg_obj_list", pcb_act_dlg_obj_list, pcb_acth_dlg_obj_list, pcb_acts_dlg_obj_list}, + {"gui_fpmap_choose", pcb_act_gui_fpmap_choose, pcb_acth_gui_fpmap_choose, pcb_acts_gui_fpmap_choose} +}; + +static const char *dialogs_cookie = "dialogs plugin"; + +int pplg_check_ver_dialogs(int ver_needed) { return 0; } + +void pplg_uninit_dialogs(void) +{ + pcb_dlg_library_uninit(); + pcb_dlg_netlist_uninit(); + pcb_dlg_undo_uninit(); + pcb_dlg_pstklib_uninit(); + pcb_dlg_pref_uninit(); + rnd_remove_actions_by_cookie(dialogs_cookie); + pcb_view_dlg_uninit(); + pcb_dlg_fontsel_uninit(); + rnd_conf_unreg_fields("plugins/dialogs/"); +} + +int pplg_init_dialogs(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(dialogs_action_list, dialogs_cookie) + pcb_dlg_pref_init(); + pcb_dlg_pstklib_init(); + pcb_dlg_undo_init(); + pcb_dlg_netlist_init(); + pcb_view_dlg_init(); + pcb_dlg_fontsel_init(); + pcb_dlg_library_init(); + + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dialogs.pup =================================================================== --- tags/2.3.0/src_plugins/dialogs/dialogs.pup (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dialogs.pup (revision 33253) @@ -0,0 +1,11 @@ +$class feature +$short HID-independent GUI dialogs +$long Interactive core functionality: HID-independent GUI dialogs (enabled by GUI HIDs) +$package lib-gui +$state works +dep draw_fontsel +dep draw_csect +dep lib_hid_common +dep lib_hid_pcbui +default disable +autoload 1 Index: tags/2.3.0/src_plugins/dialogs/dlg_about.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_about.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_about.c (revision 33253) @@ -0,0 +1,118 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include "build_run.h" +#include +#include +#include +#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 pcb_dlg_about(void) +{ + const char *tabs[] = { "About pcb-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, pcb_get_info_program()); + RND_DAD_LABEL(about_ctx.dlg, pcb_get_info_copyright()); + RND_DAD_LABEL(about_ctx.dlg, pcb_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, pcb_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, pcb_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; + + /* this is the modal version - please consider using the non-modal version */ + RND_DAD_NEW("about", about_ctx.dlg, "About pcb-rnd", &about_ctx, rnd_false, about_close_cb); +} + +const char pcb_acts_About[] = "About()\n"; +const char pcb_acth_About[] = "Present the about box"; +fgw_error_t pcb_act_About(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_dlg_about(); + RND_ACT_IRES(0); + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_about.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_about.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_about.h (revision 33253) @@ -0,0 +1,3 @@ +extern const char pcb_acts_About[]; +extern const char pcb_acth_About[]; +fgw_error_t pcb_act_About(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/2.3.0/src_plugins/dialogs/dlg_export.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_export.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_export.c (revision 33253) @@ -0,0 +1,268 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include "board.h" +#include "data.h" +#include "layer_vis.h" +#include "event.h" +#include +#include +#include +#include +#include "dlg_export.h" + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ + + int tabs, len; + + /* per exporter data */ + rnd_hid_t **hid; + const char **tab_name; + int **exp_attr; /* widget IDs of the attributes holding the actual data; outer array is indexed by exporter, inner array is by exporter option index from 0*/ + int *button; /* widget ID of the export button for a specific exporter */ + int *numo; /* number of exporter options */ + rnd_export_opt_t **ea; /* original export option arrays */ +} export_ctx_t; + +export_ctx_t export_ctx; + +static rnd_hid_attr_val_t *get_results(export_ctx_t *export_ctx, int id) +{ + rnd_hid_attr_val_t *r; + int *exp_attr, n, numo = export_ctx->numo[id]; + + r = malloc(sizeof(rnd_hid_attr_val_t) * numo); + + exp_attr = export_ctx->exp_attr[id]; + for(n = 0; n < numo; n++) { + int src = exp_attr[n]; + memcpy(&r[n], &(export_ctx->dlg[src].val), sizeof(rnd_hid_attr_val_t)); + } + return r; +} + +static void export_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + export_ctx_t *export_ctx = caller_data; + int h, wid; + int have_gui, currly = PCB_CURRLID(PCB); + int save_l_ons[PCB_MAX_LAYER], save_g_ons[PCB_MAX_LAYERGRP]; + + have_gui = (rnd_gui != NULL) && rnd_gui->gui; + if (have_gui) { + pcb_hid_save_and_show_layer_ons(save_l_ons); + pcb_hid_save_and_show_layergrp_ons(save_g_ons); + } + + wid = attr - export_ctx->dlg; + for(h = 0; h < export_ctx->len; h++) { + if (export_ctx->button[h] == wid) { + rnd_hid_attr_val_t *results = get_results(export_ctx, h); + rnd_event(&PCB->hidlib, RND_EVENT_EXPORT_SESSION_BEGIN, NULL); + export_ctx->hid[h]->do_export(export_ctx->hid[h], results); + rnd_event(&PCB->hidlib, RND_EVENT_EXPORT_SESSION_END, NULL); + free(results); + rnd_message(RND_MSG_INFO, "Export done using exporter: %s\n", export_ctx->hid[h]->name); + goto done; + } + } + + rnd_message(RND_MSG_ERROR, "Internal error: can not find which exporter to call\n"); + done:; + + if (have_gui) { + pcb_hid_restore_layer_ons(save_l_ons); + pcb_hid_restore_layergrp_ons(save_g_ons); + pcb_layervis_change_group_vis(&PCB->hidlib, currly, 1, 1); + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERVIS_CHANGED, NULL); + } +} + +/* copy back the attribute values from the DAD dialog to exporter dialog so + that values are preserved */ +static void copy_attrs_back(export_ctx_t *ctx) +{ + int n, i; + + for(n = 0; n < ctx->len; n++) { + int *exp_attr = export_ctx.exp_attr[n]; + int numo = export_ctx.numo[n]; + rnd_export_opt_t *opts = export_ctx.ea[n]; + + for(i = 0; i < numo; i++) + memcpy(&opts[i].default_val, &ctx->dlg[exp_attr[i]].val, sizeof(rnd_hid_attr_val_t)); + } +} + +static void export_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + export_ctx_t *ctx = caller_data; + int n; + + copy_attrs_back(ctx); + + RND_DAD_FREE(ctx->dlg); + free(ctx->hid); + free(ctx->tab_name); + for(n = 0; n < export_ctx.len; n++) + free(ctx->exp_attr[n]); + free(ctx->exp_attr); + free(ctx->button); + free(ctx->numo); + free(ctx->ea); + memset(ctx, 0, sizeof(export_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void pcb_dlg_export(const char *title, int exporters, int printers) +{ + rnd_hid_t **hids; + int n, i, *exp_attr; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + if (export_ctx.active) + return; /* do not open another */ + + hids = rnd_hid_enumerate(); + for(n = 0, export_ctx.len = 0; hids[n] != NULL; n++) { + if (((exporters && hids[n]->exporter) || (printers && hids[n]->printer)) && (!hids[n]->hide_from_gui)) + export_ctx.len++; + } + + if (export_ctx.len == 0) { + rnd_message(RND_MSG_ERROR, "Can not export: there are no export plugins available\n"); + return; + } + + export_ctx.tab_name = malloc(sizeof(char *) * (export_ctx.len+1)); + export_ctx.hid = malloc(sizeof(rnd_hid_t *) * (export_ctx.len)); + export_ctx.exp_attr = malloc(sizeof(int *) * (export_ctx.len)); + export_ctx.button = malloc(sizeof(int) * (export_ctx.len)); + export_ctx.numo = malloc(sizeof(int) * (export_ctx.len)); + export_ctx.ea = malloc(sizeof(rnd_hid_attribute_t *) * (export_ctx.len)); + + for(i = n = 0; hids[n] != NULL; n++) { + if (((exporters && hids[n]->exporter) || (printers && hids[n]->printer)) && (!hids[n]->hide_from_gui)) { + export_ctx.tab_name[i] = hids[n]->name; + export_ctx.hid[i] = hids[n]; + i++; + } + } + + export_ctx.tab_name[i] = NULL; + + RND_DAD_BEGIN_VBOX(export_ctx.dlg); + RND_DAD_COMPFLAG(export_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(export_ctx.dlg, export_ctx.tab_name); + RND_DAD_COMPFLAG(export_ctx.dlg, RND_HATF_LEFT_TAB|RND_HATF_EXPFILL); + export_ctx.tabs = RND_DAD_CURRENT(export_ctx.dlg); + for(n = 0; n < export_ctx.len; n++) { + int numo; + rnd_export_opt_t *opts = export_ctx.hid[n]->get_export_options(export_ctx.hid[n], &numo); + export_ctx.numo[n] = numo; + export_ctx.ea[n] = opts; + if (numo < 1) { + RND_DAD_LABEL(export_ctx.dlg, "Exporter unavailable for direct export"); + continue; + } + RND_DAD_BEGIN_VBOX(export_ctx.dlg); + if (numo > 12) + RND_DAD_COMPFLAG(export_ctx.dlg, RND_HATF_SCROLL); + export_ctx.exp_attr[n] = exp_attr = malloc(sizeof(int) * numo); + for(i = 0; i < numo; i++) { + RND_DAD_BEGIN_HBOX(export_ctx.dlg) + + switch(opts[i].type) { + case RND_HATT_COORD: + RND_DAD_COORD(export_ctx.dlg); + RND_DAD_MINMAX(export_ctx.dlg, opts[i].min_val, opts[i].max_val); + RND_DAD_DEFAULT_NUM(export_ctx.dlg, opts[i].default_val.crd); + break; + case RND_HATT_INTEGER: + RND_DAD_INTEGER(export_ctx.dlg); + RND_DAD_MINMAX(export_ctx.dlg, opts[i].min_val, opts[i].max_val); + RND_DAD_DEFAULT_NUM(export_ctx.dlg, opts[i].default_val.lng); + break; + case RND_HATT_REAL: + RND_DAD_REAL(export_ctx.dlg); + RND_DAD_MINMAX(export_ctx.dlg, opts[i].min_val, opts[i].max_val); + RND_DAD_DEFAULT_NUM(export_ctx.dlg, opts[i].default_val.dbl); + break; + case RND_HATT_UNIT: + RND_DAD_UNIT(export_ctx.dlg, RND_UNIT_METRIC | RND_UNIT_IMPERIAL); + RND_DAD_DEFAULT_NUM(export_ctx.dlg, opts[i].default_val.lng); + break; + default: + if (RND_HATT_IS_COMPOSITE(opts[i].type)) { + rnd_hid_export_opt_func_t fnc = opts[i].default_val.func; + if (fnc != NULL) + fnc(RND_HIDEOF_DAD, &export_ctx, &opts[i]); + } + else + RND_DAD_DUP_EXPOPT(export_ctx.dlg, &(opts[i])); + } + exp_attr[i] = RND_DAD_CURRENT(export_ctx.dlg); + if (opts[i].name != NULL) + RND_DAD_LABEL(export_ctx.dlg, opts[i].name); + RND_DAD_END(export_ctx.dlg); + } + RND_DAD_LABEL(export_ctx.dlg, " "); /* ugly way of inserting some vertical spacing */ + RND_DAD_BEGIN_HBOX(export_ctx.dlg) + RND_DAD_LABEL(export_ctx.dlg, "Apply attributes and export: "); + RND_DAD_BUTTON(export_ctx.dlg, "Export!"); + export_ctx.button[n] = RND_DAD_CURRENT(export_ctx.dlg); + RND_DAD_CHANGE_CB(export_ctx.dlg, export_cb); + RND_DAD_END(export_ctx.dlg); + RND_DAD_END(export_ctx.dlg); + } + RND_DAD_END(export_ctx.dlg); + RND_DAD_BUTTON_CLOSES(export_ctx.dlg, clbtn); + RND_DAD_END(export_ctx.dlg); + + /* set up the context */ + export_ctx.active = 1; + + RND_DAD_NEW("export", export_ctx.dlg, title, &export_ctx, rnd_false, export_close_cb); +} + +const char pcb_acts_ExportGUI[] = "ExportGUI()\n"; +const char pcb_acth_ExportGUI[] = "Open the export dialog."; +fgw_error_t pcb_act_ExportGUI(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv) +{ + pcb_dlg_export("Export to file", 1, 0); + return 0; +} + +const char pcb_acts_PrintGUI[] = "PrintGUI()\n"; +const char pcb_acth_PrintGUI[] = "Open the print dialog."; +fgw_error_t pcb_act_PrintGUI(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv) +{ + pcb_dlg_export("Print", 0, 1); + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_export.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_export.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_export.h (revision 33253) @@ -0,0 +1,7 @@ +extern const char pcb_acts_ExportGUI[]; +extern const char pcb_acth_ExportGUI[]; +fgw_error_t pcb_act_ExportGUI(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv); + +extern const char pcb_acts_PrintGUI[]; +extern const char pcb_acth_PrintGUI[]; +fgw_error_t pcb_act_PrintGUI(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv); Index: tags/2.3.0/src_plugins/dialogs/dlg_flag_edit.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_flag_edit.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_flag_edit.c (revision 33253) @@ -0,0 +1,167 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include "flag.h" +#include "flag_str.h" +#include "change.h" +#include "undo.h" +#include "search.h" +#include "funchash_core.h" +#include "dlg_flag_edit.h" + +typedef struct{ + unsigned long flag_bit[64]; + int wid[64]; + int len; + pcb_board_t *pcb; + int obj_type; + void *ptr1; + pcb_any_obj_t *obj; + rnd_hid_attribute_t *attrs; +} fe_ctx_t; + +#define PCB_FLAGEDIT_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_LINE | PCB_OBJ_POLY | \ + PCB_OBJ_TEXT | PCB_OBJ_SUBC | PCB_OBJ_ARC | PCB_OBJ_GFX) + +static void fe_attr_chg(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int n; + fe_ctx_t *ctx = caller_data; + unsigned long set = 0, clr = 0; + + for(n = 0; n < ctx->len; n++) { + int wid = ctx->wid[n]; + if ((ctx->attrs[wid].val.lng) && (!PCB_FLAG_TEST(ctx->flag_bit[n], ctx->obj))) + set |= ctx->flag_bit[n]; + else if (!(ctx->attrs[wid].val.lng) && PCB_FLAG_TEST(ctx->flag_bit[n], ctx->obj)) + clr |= ctx->flag_bit[n]; + } + + if ((set == 0) && (clr == 0)) + return; + + /* Note: this function is called upon each change so only one of these will be non-zero: */ + + if (set || clr) + pcb_undo_add_obj_to_flag(ctx->obj); + + + if (set != 0) + pcb_flag_change(ctx->pcb, PCB_CHGFLG_SET, set, ctx->obj_type, ctx->ptr1, ctx->obj, ctx->obj); + + if (clr != 0) + pcb_flag_change(ctx->pcb, PCB_CHGFLG_CLEAR, clr, ctx->obj_type, ctx->ptr1, ctx->obj, ctx->obj); + + rnd_gui->invalidate_all(rnd_gui); +} + + + +const char pcb_acts_FlagEdit[] = "FlagEdit(object)\n"; +const char pcb_acth_FlagEdit[] = "Change the layer binding."; +fgw_error_t pcb_act_FlagEdit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op = F_Object; + fe_ctx_t ctx; + rnd_hid_attr_val_t val; + int type; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + memset(&ctx, 0, sizeof(ctx)); + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, FlagEdit, op = fgw_keyword(&argv[1])); + + if (op == F_Object) { + rnd_coord_t x, y; + void *ptr1, *ptr2, *ptr3; + rnd_hid_get_coords("Click on object to change flags of", &x, &y, 0); + type = pcb_search_screen(x, y, PCB_FLAGEDIT_TYPES | PCB_LOOSE_SUBC(PCB), &ptr1, &ptr2, &ptr3); + ctx.ptr1 = ptr1; + ctx.obj = (pcb_any_obj_t *)ptr2; + ctx.obj_type = (type & 0xFFFF) | (type & PCB_OBJ_PSTK); + } + else + RND_ACT_FAIL(FlagEdit); + + if ((ctx.obj_type != 0) && (PCB_FLAG_TEST(PCB_FLAG_LOCK, ctx.obj))) { + rnd_message(RND_MSG_ERROR, "Can't edit the flags of a locked object, unlock first.\n"); + RND_ACT_IRES(-1); + return 0; + } + + if (ctx.obj_type != 0) { /* interactive mode */ + int n; + char tmp[128]; + RND_DAD_DECL(dlg); + + ctx.pcb = PCB; + ctx.len = 0; + + pcb_undo_save_serial(); + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + sprintf(tmp, "Object flags of %s #%ld\n", pcb_obj_type_name(ctx.obj_type), ctx.obj->ID); + RND_DAD_LABEL(dlg, tmp); + + for(n = 0; n < pcb_object_flagbits_len; n++) { + if (pcb_object_flagbits[n].object_types & ctx.obj_type) { + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_BOOL(dlg); + RND_DAD_HELP(dlg, pcb_object_flagbits[n].help); + ctx.wid[ctx.len] = RND_DAD_CURRENT(dlg); + ctx.flag_bit[ctx.len] = pcb_object_flagbits[n].mask; + if (PCB_FLAG_TEST(ctx.flag_bit[ctx.len], ctx.obj)) + RND_DAD_DEFAULT_NUM(dlg, 1); + RND_DAD_LABEL(dlg, pcb_object_flagbits[n].name); + ctx.len++; + RND_DAD_END(dlg); + } + } + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + ctx.attrs = dlg; + + RND_DAD_NEW("flags", dlg, "Edit flags", &ctx, rnd_true, NULL); + + val.func = fe_attr_chg; + rnd_gui->attr_dlg_property(dlg_hid_ctx, RND_HATP_GLOBAL_CALLBACK, &val); + + RND_DAD_RUN(dlg); + + RND_DAD_FREE(dlg); + pcb_undo_restore_serial(); + pcb_undo_inc_serial(); + } + + RND_ACT_IRES(0); + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_flag_edit.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_flag_edit.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_flag_edit.h (revision 33253) @@ -0,0 +1,3 @@ +extern const char pcb_acts_FlagEdit[]; +extern const char pcb_acth_FlagEdit[]; +fgw_error_t pcb_act_FlagEdit(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/2.3.0/src_plugins/dialogs/dlg_fontsel.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_fontsel.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_fontsel.c (revision 33253) @@ -0,0 +1,297 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include "board.h" +#include "change.h" +#include "conf_core.h" +#include "event.h" +#include +#include "stub_draw.h" +#include "idpath.h" +#include "search.h" +#include "dlg_fontsel.h" + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + pcb_board_t *pcb; + int wprev; + + unsigned active:1; + unsigned alloced:1; + + pcb_idpath_t *txt_id; + void *last_fobj; + pcb_font_id_t last_fid; + gdl_elem_t link; +} fontsel_ctx_t; + +gdl_list_t fontsels; /* object font selectors */ +fontsel_ctx_t fontsel_brd; + +static const char *fontsel_cookie = "dlg_fontsel"; + +static void fontsel_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + fontsel_ctx_t *ctx = caller_data; + + if (ctx->txt_id != NULL) + pcb_idpath_destroy(ctx->txt_id); + + RND_DAD_FREE(ctx->dlg); + if (ctx->alloced) { + gdl_remove(&fontsels, ctx, link); + free(ctx); + } + else + memset(ctx, 0, sizeof(fontsel_ctx_t)); +} + +void fontsel_expose_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + fontsel_ctx_t *ctx = prv->user_ctx; + + if (ctx->txt_id != NULL) { + pcb_text_t *txt = (pcb_text_t *)pcb_idpath2obj_in(ctx->pcb->Data, ctx->txt_id); + if (txt != NULL) + pcb_stub_draw_fontsel(gc, e, txt); + ctx->last_fobj = txt; + ctx->last_fid = txt->fid; + } + else { + pcb_stub_draw_fontsel(gc, e, NULL); + ctx->last_fobj = NULL; + } +} + +rnd_bool fontsel_mouse_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + fontsel_ctx_t *ctx = prv->user_ctx; + + if (ctx->txt_id != NULL) { + pcb_text_t *txt = (pcb_text_t *)pcb_idpath2obj_in(ctx->pcb->Data, ctx->txt_id); + if (txt == NULL) + return 0; + return pcb_stub_draw_fontsel_mouse_ev(kind, x, y, txt); + } + return pcb_stub_draw_fontsel_mouse_ev(kind, x, y, NULL); +} + +void fontsel_free_cb(rnd_hid_attribute_t *attrib, void *user_ctx, void *hid_ctx) +{ +} + +static void fontsel_preview_update(fontsel_ctx_t *ctx) +{ + rnd_hid_attr_val_t hv; + + if ((ctx == NULL) || (!ctx->active)) + return; + + hv.str = NULL; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wprev, &hv); +} + + +static void btn_load_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&PCB->hidlib, "LoadFontFrom", NULL); /* modal, blocking */ + fontsel_preview_update((fontsel_ctx_t *)caller_data); +} + +static void btn_replace_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + char file[1] = "", id[5]; + rnd_snprintf(id, sizeof(id), "%ld", conf_core.design.text_font_id); + rnd_actionva(&PCB->hidlib, "LoadFontFrom", file, id, NULL); /* modal, blocking */ + fontsel_preview_update((fontsel_ctx_t *)caller_data); +} + +static void btn_remove_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + if (conf_core.design.text_font_id == 0) { + rnd_message(RND_MSG_ERROR, "Can not remove the default font.\n"); + return; + } + pcb_del_font(&PCB->fontkit, conf_core.design.text_font_id); + rnd_conf_set(RND_CFR_DESIGN, "design/text_font_id", 0, "0", RND_POL_OVERWRITE); + fontsel_preview_update((fontsel_ctx_t *)caller_data); +} + + +static void pcb_dlg_fontsel(pcb_board_t *pcb, int modal, int global, pcb_text_t *txt_obj) +{ + rnd_box_t vbox = {0, 0, RND_MM_TO_COORD(55), RND_MM_TO_COORD(55)}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + fontsel_ctx_t *c, *ctx = NULL; + + if (global) { + if (fontsel_brd.active) + return; /* do not open another */ + ctx = &fontsel_brd; + ctx->alloced = 0; + } + else { + for(c = gdl_first(&fontsels); c != NULL; c = gdl_next(&fontsels, c)) { + pcb_text_t *txt = (pcb_text_t *)pcb_idpath2obj_in(c->pcb->Data, c->txt_id); + if (txt == txt_obj) { + rnd_message(RND_MSG_ERROR, "There is already an active fontedit dialog for that object,\nnot going to open a second dialog.\n"); + return; + } + } + ctx = calloc(sizeof(fontsel_ctx_t), 1); + ctx->alloced = 1; + gdl_insert(&fontsels, ctx, link); + } + + ctx->pcb = pcb; + if (txt_obj != NULL) + ctx->txt_id = pcb_obj2idpath((pcb_any_obj_t *)txt_obj); + else + ctx->txt_id = NULL; + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_PREVIEW(ctx->dlg, fontsel_expose_cb, fontsel_mouse_cb, NULL, fontsel_free_cb, &vbox, 200, 200, ctx); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + ctx->wprev = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Load font"); + RND_DAD_CHANGE_CB(ctx->dlg, btn_load_cb); + RND_DAD_HELP(ctx->dlg, "Load new font from disk"); + RND_DAD_BUTTON(ctx->dlg, "Replace font"); + RND_DAD_CHANGE_CB(ctx->dlg, btn_replace_cb); + RND_DAD_HELP(ctx->dlg, "Replace currently selected font\nwith new font loaded from disk"); + RND_DAD_BUTTON(ctx->dlg, "Remove font"); + RND_DAD_CHANGE_CB(ctx->dlg, btn_remove_cb); + RND_DAD_HELP(ctx->dlg, "Remove currently selected font"); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + ctx->active = 1; + RND_DAD_DEFSIZE(ctx->dlg, 250, 200); + RND_DAD_NEW("fontsel", ctx->dlg, "Font selection", ctx, modal, fontsel_close_cb); +} + +const char pcb_acts_Fontsel[] = "Fontsel()\n"; +const char pcb_acth_Fontsel[] = "Open the font selection dialog"; +fgw_error_t pcb_act_Fontsel(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *op = NULL; + int modal = 0, global = 1; + pcb_text_t *txt_obj = NULL; + + if (argc > 2) + RND_ACT_FAIL(Fontsel); + + RND_ACT_MAY_CONVARG(1, FGW_STR, Fontsel, op = argv[1].val.str); + + if (op != NULL) { + if (rnd_strcasecmp(op, "Object") == 0) { + rnd_coord_t x, y; + int type; + void *ptr1, *ptr2, *ptr3; + rnd_hid_get_coords("Select an Object", &x, &y, 0); + if ((type = pcb_search_screen(x, y, PCB_CHANGENAME_TYPES, &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) { + txt_obj = ptr2; + modal = 0; + global = 0; + } + } + else + RND_ACT_FAIL(Fontsel); + } + pcb_dlg_fontsel(PCB, modal, global, txt_obj); + return 0; +} + +static void fontsel_mchanged_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + fontsel_ctx_t *c; + + if (fontsel_brd.active) + fontsel_preview_update(&fontsel_brd); + + for(c = gdl_first(&fontsels); c != NULL; c = gdl_next(&fontsels, c)) + fontsel_preview_update(c); +} + +static void fontsel_bchanged_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + fontsel_ctx_t *c, *next; + rnd_dad_retovr_t retovr; + + if (fontsel_brd.active) + fontsel_preview_update(&fontsel_brd); + + for(c = gdl_first(&fontsels); c != NULL; c = next) { + next = gdl_next(&fontsels, c); + rnd_hid_dad_close(c->dlg_hid_ctx, &retovr, 0); + } +} + +static int fontsel_timer_active = 0; +static rnd_hidval_t fontsel_timer; + +static void fontsel_timer_cb(rnd_hidval_t user_data) +{ + fontsel_ctx_t *c; + + for(c = gdl_first(&fontsels); c != NULL; c = gdl_next(&fontsels, c)) { + pcb_text_t *txt; + + if (c->txt_id == NULL) + continue; + + txt = (pcb_text_t *)pcb_idpath2obj_in(c->pcb->Data, c->txt_id); + if ((txt != c->last_fobj) || (txt != NULL && (txt->fid != c->last_fid))) + fontsel_preview_update(c); + } + fontsel_timer = rnd_gui->add_timer(rnd_gui, fontsel_timer_cb, 500, fontsel_timer); +} + +static void fontsel_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + fontsel_timer_cb(fontsel_timer); + fontsel_timer_active = 1; +} + +void pcb_dlg_fontsel_uninit(void) +{ + if ((fontsel_timer_active) && (rnd_gui != NULL) && (rnd_gui->stop_timer != NULL)) + rnd_gui->stop_timer(rnd_gui, fontsel_timer); + rnd_event_unbind_allcookie(fontsel_cookie); +} + +void pcb_dlg_fontsel_init(void) +{ + rnd_event_bind(RND_EVENT_BOARD_CHANGED, fontsel_bchanged_ev, NULL, fontsel_cookie); + rnd_event_bind(RND_EVENT_BOARD_META_CHANGED, fontsel_mchanged_ev, NULL, fontsel_cookie); + rnd_event_bind(PCB_EVENT_FONT_CHANGED, fontsel_mchanged_ev, NULL, fontsel_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, fontsel_gui_init_ev, NULL, fontsel_cookie); +} + Index: tags/2.3.0/src_plugins/dialogs/dlg_fontsel.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_fontsel.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_fontsel.h (revision 33253) @@ -0,0 +1,6 @@ +extern const char pcb_acts_Fontsel[]; +extern const char pcb_acth_Fontsel[]; +fgw_error_t pcb_act_Fontsel(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void pcb_dlg_fontsel_uninit(void); +void pcb_dlg_fontsel_init(void); Index: tags/2.3.0/src_plugins/dialogs/dlg_fpmap.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_fpmap.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_fpmap.c (revision 33253) @@ -0,0 +1,83 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "event.h" +#include "actions_pcb.h" +#include "plug_footprint.h" +#include "plug_io.h" + + +static void fpmap_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + static rnd_dad_retovr_t retovr; + char **resname = caller_data; + *resname = attr->user_data; + rnd_hid_dad_close(hid_ctx, &retovr, 0); +} + +static const char pcb_acts_gui_fpmap_choose[] = "gui_fpmap_choose(map)\n"; +static const char pcb_acth_gui_fpmap_choose[] = "Internal call action for a dialog to select a footprint from a map."; +static fgw_error_t pcb_act_gui_fpmap_choose(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *resname = NULL; + const pcb_plug_fp_map_t *map, *m; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 0}, {NULL, 0}}; + RND_DAD_DECL(dlg); + + RND_ACT_MAY_CONVARG(1, FGW_PTR, gui_fpmap_choose, map = argv[1].val.ptr_void); + + if ((map == NULL) || (!fgw_ptr_in_domain(&rnd_fgw, &argv[1], PCB_PTR_DOMAIN_FPMAP))) + return -1; + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(dlg, "Multiple footprints available."); + RND_DAD_LABEL(dlg, "Choose one."); + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + for(m = map; m != NULL; m = m->next) { + if (m->type == PCB_FP_FILE) { + RND_DAD_BUTTON(dlg, m->name); + RND_DAD_CHANGE_CB(dlg, fpmap_cb); + RND_DAD_SET_ATTR_FIELD(dlg, user_data, m->name); + } + } + RND_DAD_END(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + RND_DAD_DEFSIZE(dlg, 250, 350); + + RND_DAD_NEW("fpmap", dlg, "Choose footprint", &resname, rnd_true, NULL); + RND_DAD_RUN(dlg); + RND_DAD_FREE(dlg); + + + res->type = FGW_STR; + res->val.cstr = resname; + return 0; +} + Index: tags/2.3.0/src_plugins/dialogs/dlg_infobar.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_infobar.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_infobar.c (revision 33253) @@ -0,0 +1,118 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Common dialogs: simple, modal dialogs and info bars. + Even the core will run some of these, through a dispatcher (e.g. + action). */ + +#include "config.h" +#include +#include "board.h" +#include +#include +#include +#include "plug_io.h" + +static void ifb_file_chg_reload_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_revert_pcb(); + rnd_actionva(&PCB->hidlib, "InfoBarFileChanged", "close", NULL); +} + +static void ifb_file_chg_close_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&PCB->hidlib, "InfoBarFileChanged", "close", NULL); +} + +const char pcb_acts_InfoBarFileChanged[] = "InfoBarFileChanged(open|close)\n"; +const char pcb_acth_InfoBarFileChanged[] = "Present the \"file changed\" warning info bar with buttons to reload or cancel"; +fgw_error_t pcb_act_InfoBarFileChanged(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + static rnd_hid_dad_subdialog_t sub; + static int active = 0, wlab[2]; + rnd_hid_attr_val_t hv; + const char *cmd; + + if (!RND_HAVE_GUI_ATTR_DLG) { + RND_ACT_IRES(0); + return 0; + } + + RND_ACT_CONVARG(1, FGW_STR, InfoBarFileChanged, cmd = argv[1].val.str); + + if (strcmp(cmd, "open") == 0) { + if (!active) { + RND_DAD_BEGIN_HBOX(sub.dlg); + RND_DAD_COMPFLAG(sub.dlg, RND_HATF_EXPFILL | RND_HATF_FRAME); + RND_DAD_BEGIN_VBOX(sub.dlg); + RND_DAD_PICTURE(sub.dlg, pcp_dlg_xpm_by_name("warning")); + RND_DAD_END(sub.dlg); + RND_DAD_BEGIN_VBOX(sub.dlg); + RND_DAD_COMPFLAG(sub.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(sub.dlg); RND_DAD_COMPFLAG(sub.dlg, RND_HATF_EXPFILL); RND_DAD_END(sub.dlg); + RND_DAD_LABEL(sub.dlg, "line0"); + wlab[0] = RND_DAD_CURRENT(sub.dlg); + RND_DAD_LABEL(sub.dlg, "line1"); + wlab[1] = RND_DAD_CURRENT(sub.dlg); + RND_DAD_BEGIN_HBOX(sub.dlg); RND_DAD_COMPFLAG(sub.dlg, RND_HATF_EXPFILL); RND_DAD_END(sub.dlg); + RND_DAD_END(sub.dlg); + RND_DAD_BEGIN_VBOX(sub.dlg); + RND_DAD_BUTTON(sub.dlg, "Reload"); + RND_DAD_HELP(sub.dlg, "Load the new verison of the file from disk,\ndiscarding any in-memory change on the board"); + RND_DAD_CHANGE_CB(sub.dlg, ifb_file_chg_reload_cb); + RND_DAD_BEGIN_HBOX(sub.dlg); RND_DAD_COMPFLAG(sub.dlg, RND_HATF_EXPFILL); RND_DAD_END(sub.dlg); + RND_DAD_BUTTON(sub.dlg, "Cancel"); + RND_DAD_HELP(sub.dlg, "Hide this info bar until the file changes again on disk"); + RND_DAD_CHANGE_CB(sub.dlg, ifb_file_chg_close_cb); + RND_DAD_END(sub.dlg); + RND_DAD_END(sub.dlg); + if (rnd_hid_dock_enter(&sub, RND_HID_DOCK_TOP_INFOBAR, "file_changed") != 0) { + RND_ACT_IRES(1); + return 0; + } + active = 1; + } + + /* update labels */ + hv.str = rnd_strdup_printf("The file %s has changed on disk", PCB->hidlib.filename); + rnd_gui->attr_dlg_set_value(sub.dlg_hid_ctx, wlab[0], &hv); + free((char *)hv.str); + + hv.str = (PCB->Changed ? "Do you want to drop your changes and reload the file?" : "Do you want to reload the file?"); + rnd_gui->attr_dlg_set_value(sub.dlg_hid_ctx, wlab[1], &hv); + } + else if (strcmp(cmd, "close") == 0) { + if (active) { + rnd_hid_dock_leave(&sub); + active = 0; + } + } + else + RND_ACT_FAIL(InfoBarFileChanged); + + RND_ACT_IRES(0); + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_infobar.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_infobar.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_infobar.h (revision 33253) @@ -0,0 +1,7 @@ +fgw_error_t pcb_act_gui_PromptFor(fgw_arg_t *res, int argc, fgw_arg_t *argv); +fgw_error_t pcb_act_gui_MessageBox(fgw_arg_t *res, int argc, fgw_arg_t *argv); +fgw_error_t pcb_act_gui_FallbackColorPick(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char pcb_acts_InfoBarFileChanged[]; +extern const char pcb_acth_InfoBarFileChanged[]; +fgw_error_t pcb_act_InfoBarFileChanged(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/2.3.0/src_plugins/dialogs/dlg_layer_binding.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_layer_binding.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_layer_binding.c (revision 33253) @@ -0,0 +1,424 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include "board.h" +#include "data.h" +#include +#include "conf_core.h" +#include +#include +#include "funchash_core.h" +#include "obj_subc.h" +#include "search.h" +#include "dlg_layer_binding.h" + +const char *pcb_lb_comp[] = { "+manual", "-manual", "+auto", "-auto", NULL }; +const char *pcb_lb_types[] = { "UNKNOWN", "paste", "mask", "silk", "copper", "boundary", "mech", "doc", "virtual", NULL }; +const char *pcb_lb_side[] = { "top", "bottom", "global", NULL }; + +typedef struct { + int name, comp, type, offs, from, side, purpose, layer; /* widet indices */ +} lb_widx_t; + +typedef struct { + const char **layer_names; + lb_widx_t *widx; + pcb_data_t *data; + pcb_subc_t *subc; + pcb_board_t *pcb; + int no_layer; /* the "invalid layer" in the layer names enum */ + rnd_hid_attribute_t *attrs; +} lb_ctx_t; + +int pcb_ly_type2enum(pcb_layer_type_t type) +{ + if (type & PCB_LYT_PASTE) return 1; + else if (type & PCB_LYT_MASK) return 2; + else if (type & PCB_LYT_SILK) return 3; + else if (type & PCB_LYT_COPPER) return 4; + else if (type & PCB_LYT_BOUNDARY) return 5; + else if (type & PCB_LYT_MECH) return 6; + else if (type & PCB_LYT_DOC) return 7; + else if (type & PCB_LYT_VIRTUAL) return 8; + return 0; +} + +static void set_ly_type(void *hid_ctx, int wid, pcb_layer_type_t type) +{ + RND_DAD_SET_VALUE(hid_ctx, wid, lng, pcb_ly_type2enum(type)); +} + +static pcb_layer_type_t int2side(int i) +{ + switch(i) { + case 0: return PCB_LYT_TOP; + case 1: return PCB_LYT_BOTTOM; + case 2: return 0; + } + return 0; +} + +static int side2int(pcb_layer_type_t s) +{ + if (s & PCB_LYT_TOP) return 0; + if (s & PCB_LYT_BOTTOM) return 1; + return 2; +} + +void pcb_get_ly_type_(int combo_type, pcb_layer_type_t *type) +{ + /* clear relevant flags */ + *type &= ~(PCB_LYT_ANYTHING | PCB_LYT_ANYWHERE | PCB_LYT_VIRTUAL); + + /* set type */ + switch(combo_type) { + case 1: *type |= PCB_LYT_PASTE; break; + case 2: *type |= PCB_LYT_MASK; break; + case 3: *type |= PCB_LYT_SILK; break; + case 4: *type |= PCB_LYT_COPPER; break; + case 5: *type |= PCB_LYT_BOUNDARY; break; + case 6: *type |= PCB_LYT_MECH; break; + case 7: *type |= PCB_LYT_DOC; break; + case 8: *type |= PCB_LYT_VIRTUAL; break; + } +} + + +static void get_ly_type(int combo_type, int combo_side, int dlg_offs, pcb_layer_type_t *type, int *offs) +{ + pcb_get_ly_type_(combo_type, type); + + if (PCB_LAYER_SIDED(*type)) { + /* set side and offset */ + if (dlg_offs == 0) { + *type |= int2side(combo_side); + } + else { + if (combo_side != 0) + dlg_offs = -dlg_offs; + *type |= PCB_LYT_INTERN; + } + } + *offs = dlg_offs; +} + + +#define layer_name_mismatch(w, layer) \ +((ctx->attrs[w->name].val.str == NULL) || (strcmp(layer->name, ctx->attrs[w->name].val.str) != 0)) + +#define layer_purpose_mismatch(w, layer) \ +((ctx->attrs[w->purpose].val.str == NULL) || (layer->meta.bound.purpose == NULL) || (strcmp(layer->meta.bound.purpose, ctx->attrs[w->purpose].val.str) != 0)) + +static void lb_data2dialog(void *hid_ctx, lb_ctx_t *ctx) +{ + int n; + rnd_bool enable; + + for(n = 0; n < ctx->data->LayerN; n++) { + lb_widx_t *w = ctx->widx + n; + pcb_layer_t *layer = ctx->data->Layer + n; + rnd_layer_id_t lid; + int ofs; + + /* disable comp for copper and outline */ + enable = !(layer->meta.bound.type & PCB_LYT_COPPER) && !(layer->meta.bound.type & PCB_LYT_BOUNDARY); + rnd_gui->attr_dlg_widget_state(hid_ctx, w->comp, enable); + if (!enable) + layer->comb = 0; /* copper and outline must be +manual */ + + /* name and type */ + if (layer_name_mismatch(w, layer)) + RND_DAD_SET_VALUE(hid_ctx, w->name, str, rnd_strdup(layer->name)); + + if (layer_purpose_mismatch(w, layer)) { + char *purp = layer->meta.bound.purpose; + if (purp == NULL) + purp = ""; + RND_DAD_SET_VALUE(hid_ctx, w->purpose, str, rnd_strdup(purp)); + } + + RND_DAD_SET_VALUE(hid_ctx, w->comp, lng, layer->comb); + + set_ly_type(hid_ctx, w->type, layer->meta.bound.type); + + /* disable side for non-sided */ + if (PCB_LAYER_SIDED(layer->meta.bound.type)) { + /* side & offset */ + RND_DAD_SET_VALUE(hid_ctx, w->side, lng, side2int(layer->meta.bound.type)); + rnd_gui->attr_dlg_widget_state(hid_ctx, w->side, 1); + } + else + rnd_gui->attr_dlg_widget_state(hid_ctx, w->side, 0); + + ofs = layer->meta.bound.stack_offs; + if (ofs < 0) { + RND_DAD_SET_VALUE(hid_ctx, w->side, lng, 1); + ofs = -layer->meta.bound.stack_offs; + } + RND_DAD_SET_VALUE(hid_ctx, w->offs, lng, ofs); + + /* enable offset only for copper */ + enable = (layer->meta.bound.type & PCB_LYT_COPPER); + rnd_gui->attr_dlg_widget_state(hid_ctx, w->offs, enable); + rnd_gui->attr_dlg_widget_state(hid_ctx, w->from, enable); + + /* real layer */ + if (layer->meta.bound.real != NULL) + lid = pcb_layer_id(PCB->Data, layer->meta.bound.real); + else + lid = ctx->no_layer; + RND_DAD_SET_VALUE(hid_ctx, w->layer, lng, lid); + } +} + +static void lb_dialog2data(void *hid_ctx, lb_ctx_t *ctx) +{ + int n; + + for(n = 0; n < ctx->data->LayerN; n++) { + lb_widx_t *w = ctx->widx + n; + pcb_layer_t *layer = ctx->data->Layer + n; + + if (layer_name_mismatch(w, layer)) { + free((char *)layer->name); + layer->name = rnd_strdup(ctx->attrs[w->name].val.str); + } + + if (layer_purpose_mismatch(w, layer)) { + const char *purp = ctx->attrs[w->purpose].val.str; + free((char *)layer->meta.bound.purpose); + if ((purp == NULL) || (*purp == '\0')) + layer->meta.bound.purpose = NULL; + else + layer->meta.bound.purpose = rnd_strdup(purp); + } + + layer->comb = ctx->attrs[w->comp].val.lng; + get_ly_type(ctx->attrs[w->type].val.lng, ctx->attrs[w->side].val.lng, ctx->attrs[w->offs].val.lng, &layer->meta.bound.type, &layer->meta.bound.stack_offs); + + /* enforce some sanity rules */ + if (layer->meta.bound.type & PCB_LYT_BOUNDARY) { + /* outline must be positive global */ + layer->comb = 0; + layer->meta.bound.type &= ~PCB_LYT_ANYWHERE; + } + if (!(layer->meta.bound.type & PCB_LYT_COPPER)) { + /* temporary: offset is useful only for copper layers */ + layer->meta.bound.stack_offs = 0; + } + } +} + +static void lb_update_left2right(void *hid_ctx, lb_ctx_t *ctx) +{ +rnd_trace("l2r!\n"); + lb_dialog2data(hid_ctx, ctx); + if (ctx->subc != NULL) { + if (pcb_subc_rebind(ctx->pcb, ctx->subc) > 0) + rnd_gui->invalidate_all(rnd_gui); + } + else { /* buffer */ + pcb_data_binding_update(ctx->pcb, ctx->data); + rnd_gui->invalidate_all(rnd_gui); + } + lb_data2dialog(hid_ctx, ctx); /* update disables */ +} + +static void lb_attr_chg(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + if (attr->user_data == NULL) /* do not handle widgets globally if they have data - they then have a local callback too */ + lb_update_left2right(hid_ctx, caller_data); +} + +static void lb_attr_layer_chg(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + lb_ctx_t *ctx = caller_data; + lb_widx_t *w = attr->user_data; + int didx = w - ctx->widx; + rnd_layer_id_t lid = attr->val.lng; + pcb_layer_t tmply, *dstly; + + if ((lid < 0) || (lid >= PCB->Data->LayerN)) + goto skip; + + if ((didx < 0) || (didx >= ctx->data->LayerN)) { + rnd_message(RND_MSG_ERROR, "Internal error: lb_attr_layer_chg(): invalid idx %d (%d)\n", didx, ctx->data->LayerN); + goto skip; + } + + /* change on the right side, target layer */ + rnd_trace("layer! %d to %d\n", didx, lid); + + memset(&tmply, 0, sizeof(tmply)); + pcb_layer_real2bound(&tmply, &PCB->Data->Layer[lid], 0); + if (ctx->subc != NULL) + dstly = &ctx->subc->data->Layer[didx]; + else + dstly = &ctx->data->Layer[didx]; + + dstly->meta.bound.type = tmply.meta.bound.type; + dstly->meta.bound.stack_offs = tmply.meta.bound.stack_offs; + free(dstly->meta.bound.purpose); + dstly->meta.bound.purpose = tmply.meta.bound.purpose; + + lb_data2dialog(hid_ctx, ctx); + + skip:; + lb_update_left2right(hid_ctx, ctx); +} + +const char pcb_acts_LayerBinding[] = "LayerBinding(object)\nLayerBinding(buffer)\n"; +const char pcb_acth_LayerBinding[] = "Change the layer binding."; +fgw_error_t pcb_act_LayerBinding(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op = F_Object; + lb_ctx_t ctx; + int num_copper; + rnd_hid_attr_val_t val; + + memset(&ctx, 0, sizeof(ctx)); + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, LayerBinding, op = fgw_keyword(&argv[1])); + + if (op == F_Object) { + rnd_coord_t x, y; + int type; + void *ptr1, *ptr2, *ptr3; + rnd_hid_get_coords("Click on subc to change the layer binding of", &x, &y, 0); + type = pcb_search_screen(x, y, PCB_OBJ_SUBC, &ptr1, &ptr2, &ptr3); + if (type != PCB_OBJ_SUBC) { + rnd_message(RND_MSG_ERROR, "No subc under the cursor\n"); + return -1; + } + ctx.subc = ptr2; + ctx.data = ctx.subc->data; + } + else if (op == F_Buffer) { + ctx.data = PCB_PASTEBUFFER->Data; + } + else + RND_ACT_FAIL(LayerBinding); + + { /* interactive mode */ + int n; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + RND_DAD_DECL(dlg); + + ctx.pcb = PCB; + ctx.widx = malloc(sizeof(lb_widx_t) * ctx.data->LayerN); + ctx.layer_names = calloc(sizeof(char *), PCB->Data->LayerN+2); + for(n = 0; n < PCB->Data->LayerN; n++) + ctx.layer_names[n] = PCB->Data->Layer[n].name; + ctx.no_layer = n; + ctx.layer_names[n] = "invalid/unbound"; + n++; + ctx.layer_names[n] = NULL; + + for(n = 0, num_copper = -1; n < PCB->LayerGroups.len; n++) + if (pcb_layergrp_flags(PCB, n) & PCB_LYT_COPPER) + num_copper++; + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABLE(dlg, 2); + RND_DAD_COMPFLAG(dlg, RND_HATF_SCROLL | RND_HATF_EXPFILL); + for(n = 0; n < ctx.data->LayerN; n++) { + lb_widx_t *w = ctx.widx+n; + /* left side */ + RND_DAD_BEGIN_VBOX(dlg); + if (n == 0) + RND_DAD_LABEL(dlg, "RECIPE"); + else + RND_DAD_LABEL(dlg, "\n"); + + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_LABEL(dlg, "Name:"); + RND_DAD_STRING(dlg); + w->name = RND_DAD_CURRENT(dlg); + RND_DAD_END(dlg); + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_ENUM(dlg, pcb_lb_comp); /* coposite */ + w->comp = RND_DAD_CURRENT(dlg); + RND_DAD_ENUM(dlg, pcb_lb_types); /* lyt */ + w->type = RND_DAD_CURRENT(dlg); + RND_DAD_END(dlg); + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_INTEGER(dlg); + RND_DAD_MINVAL(dlg, 0); + RND_DAD_MAXVAL(dlg, num_copper); + w->offs = RND_DAD_CURRENT(dlg); + RND_DAD_LABEL(dlg, "from"); + w->from = RND_DAD_CURRENT(dlg); + RND_DAD_ENUM(dlg, pcb_lb_side); + w->side = RND_DAD_CURRENT(dlg); + RND_DAD_END(dlg); + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_LABEL(dlg, "Purpose:"); + RND_DAD_STRING(dlg); + w->purpose = RND_DAD_CURRENT(dlg); + RND_DAD_END(dlg); + + RND_DAD_END(dlg); + + /* right side */ + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_LABELF(dlg, ("\n\n layer #%d ", n)); + RND_DAD_BEGIN_VBOX(dlg); + if (n == 0) + RND_DAD_LABEL(dlg, "BOARD LAYER"); + else + RND_DAD_LABEL(dlg, "\n\n"); + RND_DAD_LABEL(dlg, "Automatic"); + RND_DAD_ENUM(dlg, ctx.layer_names); + w->layer = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, lb_attr_layer_chg); + RND_DAD_SET_ATTR_FIELD(dlg, user_data, w); + RND_DAD_END(dlg); + RND_DAD_END(dlg); + } + RND_DAD_END(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + ctx.attrs = dlg; + + RND_DAD_DEFSIZE(dlg, 500, 500); + RND_DAD_NEW("layer_binding", dlg, "Layer bindings", &ctx, rnd_true, NULL); + val.func = lb_attr_chg; + rnd_gui->attr_dlg_property(dlg_hid_ctx, RND_HATP_GLOBAL_CALLBACK, &val); + lb_data2dialog(dlg_hid_ctx, &ctx); + + RND_DAD_RUN(dlg); + + RND_DAD_FREE(dlg); + free(ctx.widx); + free(ctx.layer_names); + } + + RND_ACT_IRES(0); + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_layer_binding.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_layer_binding.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_layer_binding.h (revision 33253) @@ -0,0 +1,15 @@ +#ifndef PCB_DLG_LAYRE_BINDING_H +#define PCB_DLG_LAYRE_BINDING_H + +extern const char pcb_acts_LayerBinding[]; +extern const char pcb_acth_LayerBinding[]; +fgw_error_t pcb_act_LayerBinding(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char *pcb_lb_comp[]; +extern const char *pcb_lb_types[]; +extern const char *pcb_lb_side[]; + +int pcb_ly_type2enum(pcb_layer_type_t type); +void pcb_get_ly_type_(int combo_type, pcb_layer_type_t *type); + +#endif Index: tags/2.3.0/src_plugins/dialogs/dlg_layer_flags.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_layer_flags.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_layer_flags.c (revision 33253) @@ -0,0 +1,222 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "board.h" +#include +#include "event.h" +#include +#include "dlg_layer_binding.h" +#include "dlg_layer_flags.h" + +const char pcb_acts_LayerPropGui[] = "LayerPropGui(layerid)"; +const char pcb_acth_LayerPropGui[] = "Change layer flags and properties"; +fgw_error_t pcb_act_LayerPropGui(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + RND_DAD_DECL(dlg) + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 1}, {"OK", 0}, {NULL, 0}}; + int wname, wsub, wauto, failed, ar = 0; + pcb_layer_t *ly; + rnd_layer_id_t lid; + + + RND_ACT_MAY_CONVARG(1, FGW_LONG, LayerPropGui, lid = argv[1].val.nat_long); + ly = pcb_get_layer(PCB->Data, lid); + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_BEGIN_TABLE(dlg, 2); + RND_DAD_LABEL(dlg, "name"); + RND_DAD_STRING(dlg); + RND_DAD_HELP(dlg, "logical layer name"); + wname = RND_DAD_CURRENT(dlg); + RND_DAD_LABEL(dlg, "sub"); + RND_DAD_BOOL(dlg); + RND_DAD_HELP(dlg, "Layer is drawn negatively in composition\n(will not work on copper)"); + wsub = RND_DAD_CURRENT(dlg); + RND_DAD_LABEL(dlg, "auto"); + RND_DAD_BOOL(dlg); + RND_DAD_HELP(dlg, "Layer is target for autogenerated objects\nand side effects, e.g. padstack shapes"); + wauto = RND_DAD_CURRENT(dlg); + RND_DAD_END(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + + dlg[wname].val.str = rnd_strdup(ly->name); + dlg[wsub].val.lng = ly->comb & PCB_LYC_SUB; + dlg[wauto].val.lng = ly->comb & PCB_LYC_AUTO; + + RND_DAD_AUTORUN("layer_prop", dlg, "Properties of a logical layer", NULL, failed); + + if (failed == 0) { + pcb_layer_combining_t comb = 0; + if (strcmp(ly->name, dlg[wname].val.str) != 0) { + ar |= pcb_layer_rename_(ly, (char *)dlg[wname].val.str, 1); + pcb_board_set_changed_flag(PCB, rnd_true); + } + if (dlg[wsub].val.lng) comb |= PCB_LYC_SUB; + if (dlg[wauto].val.lng) comb |= PCB_LYC_AUTO; + if (ly->comb != comb) { + if (pcb_layer_recomb(ly, comb, 1) == 0) + rnd_gui->invalidate_all(rnd_gui); + } + } + else + ar = 1; + RND_DAD_FREE(dlg); + + RND_ACT_IRES(ar); + return 0; +} + +const char pcb_acts_GroupPropGui[] = "GroupPropGui(groupid)"; +const char pcb_acth_GroupPropGui[] = "Change group flags and properties"; +fgw_error_t pcb_act_GroupPropGui(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + RND_DAD_DECL(dlg) + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 1}, {"OK", 0}, {NULL, 0}}; + int wname, wtype, wpurp, wloc; + int failed, n, ar = 0, orig_type, changed = 0, omit_loc = 0, orig_loc = -1, def_loc; + rnd_layergrp_id_t gid; + pcb_layergrp_t *g; + static const char *ltypes[] = { "top", "bottom", "any intern", "global", NULL }; + pcb_layer_type_t ltype_bits[] = { PCB_LYT_TOP, PCB_LYT_BOTTOM, PCB_LYT_INTERN, 0 }; +#define LOC_TYPES (PCB_LYT_DOC) + + RND_ACT_MAY_CONVARG(1, FGW_LONG, GroupPropGui, gid = argv[1].val.nat_long); + g = pcb_get_layergrp(PCB, gid); + + if (g->ltype & LOC_TYPES) { + for(n = 0; ltype_bits[n] != 0; n++) + if (g->ltype & ltype_bits[n]) + def_loc = n; + } + else + omit_loc = 1; + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_BEGIN_TABLE(dlg, 2); + RND_DAD_LABEL(dlg, "name"); + RND_DAD_STRING(dlg); + RND_DAD_HELP(dlg, "group name"); + wname = RND_DAD_CURRENT(dlg); + RND_DAD_LABEL(dlg, "type"); + RND_DAD_ENUM(dlg, pcb_lb_types); + RND_DAD_HELP(dlg, "type/material of the group"); + wtype = RND_DAD_CURRENT(dlg); + if (!omit_loc) { + RND_DAD_LABEL(dlg, "location"); + RND_DAD_ENUM(dlg, ltypes); + RND_DAD_HELP(dlg, "location of the group in the stack"); + wloc = RND_DAD_CURRENT(dlg); + } + RND_DAD_LABEL(dlg, "purpose"); + RND_DAD_STRING(dlg); + RND_DAD_HELP(dlg, "purpose"); + wpurp = RND_DAD_CURRENT(dlg); + RND_DAD_HELP(dlg, "subtype of the layer\nmeaning depends on the main type"); + RND_DAD_END(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + + dlg[wname].val.str = rnd_strdup(g->name); + dlg[wtype].val.lng = orig_type = pcb_ly_type2enum(g->ltype); + dlg[wpurp].val.str = rnd_strdup(g->purpose == NULL ? "" : g->purpose); + if (!omit_loc) + dlg[wloc].val.lng = def_loc; + + if (!omit_loc) { + pcb_layer_type_t loc = g->ltype & PCB_LYT_ANYWHERE; + dlg[wloc].val.lng = 3; + if (loc != 0) { + for(n = 0; ltypes[n] != NULL; n++) { + if ((loc & ltype_bits[n]) == loc) { + dlg[wloc].val.lng = n; + break; + } + } + } + orig_loc = dlg[wloc].val.lng; + } + + RND_DAD_AUTORUN("layer_grp_prop", dlg, "Edit the properties of a layer group (physical layer)", NULL, failed); + if (failed == 0) { + if (strcmp(g->name, dlg[wname].val.str) != 0) { + ar |= pcb_layergrp_rename_(g, (char *)dlg[wname].val.str, 1); + dlg[wname].val.str = NULL; + pcb_board_set_changed_flag(PCB, rnd_true); + } + + if (dlg[wtype].val.lng != orig_type) { + pcb_layer_type_t lyt = g->ltype, olyt = 0; + pcb_get_ly_type_(dlg[wtype].val.lng, &olyt); + lyt &= ~PCB_LYT_ANYTHING; + lyt |= olyt; + pcb_layergrp_set_ltype(g, lyt, 1); + changed = 1; + } + + if ((!omit_loc) && (dlg[wloc].val.lng != orig_loc)) { + if (PCB_LAYER_SIDED(g->ltype)) { + pcb_layer_type_t lyt = (g->ltype & ~PCB_LYT_ANYWHERE); + if (dlg[wloc].val.lng >= 0) + lyt |= ltype_bits[dlg[wloc].val.lng]; + pcb_layergrp_set_ltype(g, lyt, 1); + changed = 1; + } + else + rnd_message(RND_MSG_ERROR, "Ignoring location - for this layer group type it is determined by the stackup\n"); + } + + if (dlg[wpurp].val.str == NULL) { + if (g->purpose != NULL) { + pcb_layergrp_set_purpose__(g, NULL, 1); + changed = 1; + } + } + else if ((g->purpose == NULL) || (strcmp(g->purpose, dlg[wpurp].val.str) != 0)) { + if (*dlg[wpurp].val.str == '\0') + pcb_layergrp_set_purpose__(g, NULL, 1); + else + pcb_layergrp_set_purpose__(g, rnd_strdup(dlg[wpurp].val.str), 1); + changed = 1; + } + + if (changed) { + pcb_board_set_changed_flag(PCB, rnd_true); + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + } + } + else + ar = 1; + + RND_DAD_FREE(dlg); + + RND_ACT_IRES(ar); + return 0; +} +#undef LOC_TYPES Index: tags/2.3.0/src_plugins/dialogs/dlg_layer_flags.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_layer_flags.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_layer_flags.h (revision 33253) @@ -0,0 +1,6 @@ +extern const char pcb_acts_LayerPropGui[]; +extern const char pcb_acth_LayerPropGui[]; +fgw_error_t pcb_act_LayerPropGui(fgw_arg_t *res, int argc, fgw_arg_t *argv); +extern const char pcb_acts_GroupPropGui[]; +extern const char pcb_acth_GroupPropGui[]; +fgw_error_t pcb_act_GroupPropGui(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/2.3.0/src_plugins/dialogs/dlg_lib_pstk.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_lib_pstk.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_lib_pstk.c (revision 33253) @@ -0,0 +1,767 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Padstack library dialog */ + +#include "config.h" +#include +#include "data.h" +#include "obj_subc.h" +#include "vtpadstack.h" +#include +#include +#include +#include +#include "obj_pstk.h" +#include "obj_pstk_inlines.h" +#include "obj_text_draw.h" +#include "obj_pstk_draw.h" +#include "undo_old.h" +#include "plug_io.h" +#include "select.h" +#include "search.h" +#include "dlg_padstack.h" +#include "dlg_lib_pstk.h" + +htip_t pstk_libs; /* id -> pstk_lib_ctx_t */ + +typedef struct pstk_lib_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + pcb_board_t *pcb; + int wlist, wprev, wgrid; + int wlayerv[pcb_proto_num_layers], wlayerc[pcb_proto_num_layers]; /* layer visibility/current */ + long subc_id; + rnd_cardinal_t proto_id; + rnd_cardinal_t *stat; /* temporary usage stat */ + rnd_box_t drawbox; + rnd_bool modal; +} pstk_lib_ctx_t; + +static rnd_cardinal_t pstklib_last_proto_id; /* set on close to preserve the id after free'ing the context; useful only for modal windows because of blocking calls */ + +static pcb_data_t *get_data(pstk_lib_ctx_t *ctx, long id, pcb_subc_t **sc_out) +{ + int type; + void *r1, *r2, *r3; + pcb_subc_t *sc; + + if (id < 0) + return ctx->pcb->Data; + + type = pcb_search_obj_by_id_(ctx->pcb->Data, &r1, &r2, &r3, id, PCB_OBJ_SUBC); + if (type != PCB_OBJ_SUBC) + return NULL; + + sc = r2; + + if (sc_out != NULL) + *sc_out = sc; + + return sc->data; +} + +static int pstklib_data2dlg(pstk_lib_ctx_t *ctx) +{ + pcb_pstk_proto_t *proto; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[4], *cursor_path = NULL; + long id; + + if (data == NULL) + return -1; + + attr = &ctx->dlg[ctx->wlist]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + cell[3] = NULL; + for(id = 0, proto = data->ps_protos.array; id < pcb_vtpadstack_proto_len(&data->ps_protos); proto++,id++) { + if (!proto->in_use) + continue; + cell[0] = rnd_strdup_printf("%ld", id); + cell[1] = rnd_strdup(proto->name == NULL ? "" : proto->name); + if (ctx->stat != NULL) + cell[2] = rnd_strdup_printf("%d", ctx->stat[id]); + else + cell[2] = rnd_strdup(""); + rnd_dad_tree_append(attr, NULL, cell); + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlist, &hv); + free(cursor_path); + } + return 0; +} + +static void pstklib_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + pstk_lib_ctx_t *ctx = caller_data; + + if (!ctx->modal) + htip_pop(&pstk_libs, ctx->subc_id); + pstklib_last_proto_id = ctx->proto_id; + RND_DAD_FREE(ctx->dlg); + free(ctx); +} + +static void pstklib_setps(pcb_pstk_t *ps, pcb_data_t *data, rnd_cardinal_t proto_id) +{ + memset(ps, 0, sizeof(pcb_pstk_t)); + ps->parent_type = PCB_PARENT_DATA; + ps->parent.data = data; + ps->proto = proto_id; + ps->ID = -1; /* disable undo and clipping */ +} + +static void pstklib_expose(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + pstk_lib_ctx_t *ctx = prv->user_ctx; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + pcb_pstk_t ps; + char layers[pcb_proto_num_layers]; + int n; + rnd_coord_t x1, y1, x2, y2, x, y, grid; + + if (data == NULL) { + return; + } + + if (ctx->proto_id == PCB_PADSTACK_INVALID) + return; + + pstklib_setps(&ps, data, ctx->proto_id); + + /* draw the shapes */ + for(n = 0; n < pcb_proto_num_layers; n++) + layers[n] = !!ctx->dlg[ctx->wlayerv[n]].val.lng + !!ctx->dlg[ctx->wlayerc[n]].val.lng; + + pcb_pstk_draw_preview(PCB, &ps, layers, 0, 0, &e->view); + + rnd_render->set_color(gc, rnd_color_black); + rnd_hid_set_line_cap(gc, rnd_cap_round); + rnd_hid_set_line_width(gc, -1); + + x1 = ctx->drawbox.X1; + y1 = ctx->drawbox.Y1; + x2 = ctx->drawbox.X2; + y2 = ctx->drawbox.Y2; + + grid = ctx->dlg[ctx->wgrid].val.crd; + for(x = 0; x < x2; x += grid) + rnd_render->draw_line(gc, x, y1, x, y2); + for(x = -grid; x > x1; x -= grid) + rnd_render->draw_line(gc, x, y1, x, y2); + for(y = 0; y < y2; y += grid) + rnd_render->draw_line(gc, x1, y, x2, y); + for(y = -grid; y > y1; y -= grid) + rnd_render->draw_line(gc, x1, y, x2, y); + + /* draw the mark only */ + for(n = 0; n < pcb_proto_num_layers; n++) + layers[n] = 0; + pcb_pstk_draw_preview(PCB, &ps, layers, 1, 0, &e->view); +} + +static void pstklib_force_redraw(pstk_lib_ctx_t *ctx, pcb_pstk_t *ps) +{ + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + + if (proto == NULL) + return; + + pcb_pstk_bbox(ps); + ps->BoundingBox.X1 -= RND_MM_TO_COORD(0.5); + ps->BoundingBox.Y1 -= RND_MM_TO_COORD(0.5); + ps->BoundingBox.X2 += RND_MM_TO_COORD(0.5); + ps->BoundingBox.Y2 += RND_MM_TO_COORD(0.5); + memcpy(&ctx->drawbox, &ps->BoundingBox, sizeof(rnd_box_t)); + rnd_dad_preview_zoomto(&ctx->dlg[ctx->wprev], &ctx->drawbox); +} + +static void pstklib_select(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_attr_val_t hv; + rnd_hid_tree_t *tree = attrib->wdata; + pstk_lib_ctx_t *ctx = tree->user_ctx; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + pcb_pstk_t ps; + + if ((row != NULL) && (data != NULL)) { + ctx->proto_id = strtol(row->cell[0], NULL, 10); + pstklib_setps(&ps, data, ctx->proto_id); + pstklib_force_redraw(ctx, &ps); + } + else + ctx->proto_id = PCB_PADSTACK_INVALID; + + hv.str = NULL; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wprev, &hv); +} + +static void pstklib_update_prv(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pstk_lib_ctx_t *ctx = caller_data; + rnd_dad_preview_zoomto(&ctx->dlg[ctx->wprev], &ctx->drawbox); +} + +static void pstklib_update_layerc(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pstk_lib_ctx_t *ctx = caller_data; + int n, idx = -1, widx = attr - ctx->dlg; + rnd_hid_attr_val_t hv; + + for(n = 0; n < pcb_proto_num_layers; n++) { + if (ctx->wlayerc[n] == widx) { + hv.lng = 1; + idx = n; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlayerv[n], &hv); /* current must be visible as well */ + } + else + hv.lng = 0; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlayerc[n], &hv); + } + if (idx < 0) + return; + + pstklib_update_prv(hid_ctx, caller_data, attr); +} + + +static void pstklib_filter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + pstk_lib_ctx_t *ctx = caller_data; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + const char *text; + + if (data == NULL) + return; + + attr = &ctx->dlg[ctx->wlist]; + tree = attr->wdata; + text = attr_inp->val.str; + + if ((text == NULL) || (*text == '\0')) { + for(r = gdl_first(&tree->rows); r != NULL; r = gdl_next(&tree->rows, r)) + r->hide = 0; + } + else { + for(r = gdl_first(&tree->rows); r != NULL; r = gdl_next(&tree->rows, r)) + r->hide = (strstr(r->cell[1], text) == NULL); + } + + rnd_dad_tree_update_hide(attr); +} + + +static void pstklib_proto_edit_change_cb(pse_t *pse) +{ + pstklib_force_redraw(pse->user_data, pse->ps); +} + +static void pstklib_proto_edit_common(pstk_lib_ctx_t *ctx, pcb_data_t *data, rnd_cardinal_t proto_id, int tab) +{ + pcb_pstk_t ps; + pse_t pse; + + pstklib_setps(&ps, data, proto_id); + memset(&pse, 0, sizeof(pse)); + pse.pcb = ctx->pcb; + pse.data = data; + pse.ps = &ps; + pse.disable_instance_tab = 1; + pse.user_data = ctx; + pse.change_cb = pstklib_proto_edit_change_cb; + pse.gen_shape_in_place = 1; + + pcb_pstkedit_dialog(&pse, tab); +} + + +static void pstklib_proto_edit(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pstk_lib_ctx_t *ctx = caller_data; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wlist]); + + if ((row == NULL) || (data == NULL)) + return; + + pstklib_proto_edit_common(ctx, data, strtol(row->cell[0], NULL, 10), 1); +} + +static void pstklib_proto_new_(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr, int dup) +{ + pstk_lib_ctx_t *ctx = caller_data; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + pcb_pstk_proto_t proto_, *proto; + rnd_hid_attr_val_t hv; + char tmp[64]; + int tab; + + if (data == NULL) + return; + + if (dup) { + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wlist]); + if (row == NULL) + return; + proto = pcb_pstk_get_proto_(data, strtol(row->cell[0], NULL, 10)); + ctx->proto_id = pcb_pstk_proto_insert_forcedup(data, proto, 0, (pcb_data_get_top(data) == ctx->pcb)); + tab = 1; + } + else { + memset(&proto_, 0, sizeof(proto_)); + pcb_pstk_proto_update(&proto_); + proto = &proto_; + ctx->proto_id = pcb_pstk_proto_insert_dup(data, proto, 1, (pcb_data_get_top(data) == ctx->pcb)); + tab = 2; + } + + /* make sure the new item appears in the list and is selected */ + pstklib_data2dlg(ctx); + sprintf(tmp, "%u", ctx->proto_id); + hv.str = tmp; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlist, &hv); + + pstklib_proto_edit_common(ctx, data, ctx->proto_id, tab); +} + +static void pstklib_proto_new(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pstklib_proto_new_(hid_ctx, caller_data, attr, 0); +} + +static void pstklib_proto_dup(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pstklib_proto_new_(hid_ctx, caller_data, attr, 1); +} + +static char *proto_save_fn = NULL, *proto_load_fn = NULL; + +static void pstklib_save(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pstk_lib_ctx_t *ctx = caller_data; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wlist]); + pcb_pstk_proto_t *proto; + FILE *f; + char *old_fn; + + if (data == NULL) + return; + + if (row == NULL) { + rnd_message(RND_MSG_ERROR, "First select a prototype to save\n"); + return; + } + + + proto = pcb_pstk_get_proto_(data, strtol(row->cell[0], NULL, 10)); + if (proto == NULL) + return; + + if (proto_save_fn == NULL) + proto_save_fn = rnd_strdup("padstack.lht"); + old_fn = proto_save_fn; + proto_save_fn = rnd_gui->fileselect(rnd_gui, "Save padstack", "Select a file the padstack prototype is saved to", old_fn, ".lht", NULL, "padstack", 0, NULL); + if (proto_save_fn == NULL) + return; /* cancel */ + free(old_fn); + + f = rnd_fopen(&ctx->pcb->hidlib, proto_save_fn, "w"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to open %s for write.\n", proto_save_fn); + return; + } + + if (pcb_write_padstack(f, proto, "lihata") == 0) + rnd_message(RND_MSG_INFO, "Padstack saved to %s.\n", proto_save_fn); + else + rnd_message(RND_MSG_ERROR, "Padstack not saved to %s.\n", proto_save_fn); +} + +static void pstklib_load(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pstk_lib_ctx_t *ctx = caller_data; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wlist]); + pcb_pstk_proto_t *proto; + char *old_fn; + rnd_hid_attr_val_t hv; + + if (data == NULL) + return; + + if (row == NULL) { + rnd_message(RND_MSG_ERROR, "First select a prototype to load into\n"); + return; + } + + proto = pcb_pstk_get_proto_(data, strtol(row->cell[0], NULL, 10)); + if (proto == NULL) + return; + + if (proto_load_fn == NULL) + proto_load_fn = rnd_strdup("padstack.lht"); + old_fn = proto_load_fn; + proto_load_fn = rnd_gui->fileselect(rnd_gui, "Save padstack", "Select a file the padstack prototype is loaded from", old_fn, ".lht", NULL, "padstack", RND_HID_FSD_READ, NULL); + if (proto_load_fn == NULL) + return; /* cancel */ + free(old_fn); + + if (pcb_load_padstack(&ctx->pcb->hidlib, proto, proto_load_fn, NULL) == 0) + rnd_message(RND_MSG_INFO, "Padstack loaded from %s.\n", proto_load_fn); + else + rnd_message(RND_MSG_ERROR, "Padstack failed to load from %s.\n", proto_load_fn); + + proto->parent = data; + + /* redraw */ + hv.str = NULL; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wprev, &hv); +} + +static void pstklib_proto_switch(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + pstk_lib_ctx_t *ctx = caller_data; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + rnd_hid_attribute_t *attr; + rnd_hid_row_t *r; + rnd_cardinal_t from_pid, to_pid; + pcb_pstk_t *ps; + + if (data == NULL) + return; + + attr = &ctx->dlg[ctx->wlist]; + r = rnd_dad_tree_get_selected(attr); + if (r == NULL) + return; + + from_pid = strtol(r->cell[0], NULL, 10); + to_pid = pcb_dlg_pstklib(ctx->pcb, ctx->subc_id, rnd_true, "Select a prototype to switch to"); + if ((to_pid == PCB_PADSTACK_INVALID) || (to_pid == from_pid)) + return; + + for(ps = padstacklist_first(&data->padstack); ps != NULL; ps = padstacklist_next(ps)) { + if (ps->proto == from_pid) + pcb_pstk_change_instance(ps, &to_pid, NULL, NULL, NULL, NULL); + } + + rnd_gui->invalidate_all(rnd_gui); +} + + +static void pstklib_proto_select(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + pstk_lib_ctx_t *ctx = caller_data; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + rnd_hid_attribute_t *attr; + rnd_hid_row_t *r; + long pid; + rnd_box_t box; + int changed = 0; + pcb_pstk_t *ps; + + if (data == NULL) + return; + + attr = &ctx->dlg[ctx->wlist]; + r = rnd_dad_tree_get_selected(attr); + if (r == NULL) + return; + + pid = strtol(r->cell[0], NULL, 10); + + /* unselect all */ + box.X1 = -RND_MAX_COORD; + box.Y1 = -RND_MAX_COORD; + box.X2 = RND_MAX_COORD; + box.Y2 = RND_MAX_COORD; + if (pcb_select_block(PCB, &box, rnd_false, rnd_false, rnd_false)) + changed = 1; + + for(ps = padstacklist_first(&data->padstack); ps != NULL; ps = padstacklist_next(ps)) { + if (ps->proto == pid) { + changed = 1; + pcb_undo_add_obj_to_flag(ps); + PCB_FLAG_TOGGLE(PCB_FLAG_SELECTED, ps); + } + } + + if (changed) { + pcb_board_set_changed_flag(PCB, rnd_true); + rnd_gui->invalidate_all(rnd_gui); + } +} + +static void pstklib_count_uses(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_cardinal_t len; + pstk_lib_ctx_t *ctx = caller_data; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + + if (data == NULL) + return; + + ctx->stat = pcb_pstk_proto_used_all(data, &len); + pstklib_data2dlg(ctx); + free(ctx->stat); + ctx->stat = NULL; +} + +static void pstklib_del_unused(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_cardinal_t len, n; + pstk_lib_ctx_t *ctx = caller_data; + pcb_data_t *data = get_data(ctx, ctx->subc_id, NULL); + + if (data == NULL) + return; + + ctx->stat = pcb_pstk_proto_used_all(data, &len); + for(n = 0; n < len; n++) { + if (ctx->stat[n] == 0) + pcb_pstk_proto_del(data, n); + } + pstklib_data2dlg(ctx); + free(ctx->stat); + ctx->stat = NULL; +} + +rnd_cardinal_t pcb_dlg_pstklib(pcb_board_t *pcb, long subc_id, rnd_bool modal, const char *hint) +{ + static const char *hdr[] = {"ID", "name", "used", NULL}; + pcb_subc_t *sc; + pcb_data_t *data; + pstk_lib_ctx_t *ctx; + int n; + char *name; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + rnd_hid_dad_buttons_t clbtn_modal[] = {{"Cancel", -1}, {"Use selected", 0}, {NULL, 0}}; + + if (subc_id <= 0) + subc_id = -1; + + if ((!modal) && (htip_get(&pstk_libs, subc_id) != NULL)) + return 0; /* already open - have only one per id */ + + ctx = calloc(sizeof(pstk_lib_ctx_t), 1); + ctx->pcb = pcb; + ctx->subc_id = subc_id; + ctx->proto_id = PCB_PADSTACK_INVALID; + ctx->modal = modal; + + data = get_data(ctx, subc_id, &sc); + if (data == NULL) { + free(ctx); + return PCB_PADSTACK_INVALID; + } + + if (!modal) + htip_set(&pstk_libs, subc_id, ctx); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + if (hint != NULL) + RND_DAD_LABEL(ctx->dlg, hint); + + /* create the dialog box */ + RND_DAD_BEGIN_HPANE(ctx->dlg); + /* left */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 3, 0, hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, pstklib_select); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + ctx->wlist = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_STRING(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "Filter text:\nlist padstacks with matching name only"); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_filter_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_HELP(ctx->dlg, "Edit the selected prototype\nusing the padstack editor"); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_proto_edit); + RND_DAD_BUTTON(ctx->dlg, "New..."); + RND_DAD_HELP(ctx->dlg, "Create a new prototype and edit it\nusing the padstack editor"); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_proto_new); + RND_DAD_BUTTON(ctx->dlg, "Switch"); + RND_DAD_HELP(ctx->dlg, "Find all padstacks using this prototype\nand modify them to use a different prototype\nmaking this prototype unused"); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_proto_switch); + RND_DAD_BUTTON(ctx->dlg, "Select"); + RND_DAD_HELP(ctx->dlg, "Select all padstack ref. objects that\nreference (use) this prototype"); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_proto_select); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Dup..."); + RND_DAD_HELP(ctx->dlg, "Create a new prototype by duplicating\nthe currently selected on and\n edit it using the padstack editor"); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_proto_dup); + RND_DAD_BUTTON(ctx->dlg, "Count uses"); + RND_DAD_HELP(ctx->dlg, "Count how many times each prototype\nis used and update the \"used\"\ncolumn of the table"); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_count_uses); + RND_DAD_BUTTON(ctx->dlg, "Del unused"); + RND_DAD_HELP(ctx->dlg, "Update prototype usage stats and\nremove prototypes that are not\nused by any padstack"); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_del_unused); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Load..."); + RND_DAD_HELP(ctx->dlg, "Replace the selected padstack with one loaded from a file"); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_load); + RND_DAD_BUTTON(ctx->dlg, "Save..."); + RND_DAD_HELP(ctx->dlg, "Save the selected padstack to a file"); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_save); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* right */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_PREVIEW(ctx->dlg, pstklib_expose, NULL, NULL, NULL, NULL, 200, 200, ctx); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + ctx->wprev = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + RND_DAD_LABEL(ctx->dlg, "Grid:"); + RND_DAD_COORD(ctx->dlg); + ctx->wgrid = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, RND_MM_TO_COORD(0.01), RND_MM_TO_COORD(10)); + RND_DAD_DEFAULT_NUM(ctx->dlg, (rnd_coord_t)RND_MM_TO_COORD(1)); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_update_prv); + + RND_DAD_LABEL(ctx->dlg, ""); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Vis"); + RND_DAD_HELP(ctx->dlg, "layer is visible"); + RND_DAD_LABEL(ctx->dlg, "Curr"); + RND_DAD_HELP(ctx->dlg, "layer is set to current/primary\nfor display (color emphasis)"); + RND_DAD_END(ctx->dlg); + for(n = 0; n < pcb_proto_num_layers; n++) { + RND_DAD_LABEL(ctx->dlg, pcb_proto_layers[n].name); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BOOL(ctx->dlg); + RND_DAD_DEFAULT_NUM(ctx->dlg, 1); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_update_prv); + ctx->wlayerv[n] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BOOL(ctx->dlg); + RND_DAD_DEFAULT_NUM(ctx->dlg, (pcb_proto_layers[n].mask == (PCB_LYT_TOP | PCB_LYT_COPPER))); + RND_DAD_CHANGE_CB(ctx->dlg, pstklib_update_layerc); + ctx->wlayerc[n] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + } + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BUTTON_CLOSES(ctx->dlg, (modal ? clbtn_modal : clbtn)); + RND_DAD_END(ctx->dlg); + + if (subc_id > 0) { + if (sc->refdes != NULL) + name = rnd_strdup_printf("pcb-rnd padstacks - subcircuit #%ld (%s)", subc_id, sc->refdes); + else + name = rnd_strdup_printf("pcb-rnd padstacks - subcircuit #%ld", subc_id); + } + else + name = rnd_strdup("pcb-rnd padstacks - board"); + + RND_DAD_NEW("pstk_lib", ctx->dlg, name, ctx, modal, pstklib_close_cb); + + pstklib_data2dlg(ctx); + free(name); + + if (modal) { + if (RND_DAD_RUN(ctx->dlg) != 0) + return PCB_PADSTACK_INVALID; + return pstklib_last_proto_id; + } + + return 0; +} + +const char pcb_acts_pstklib[] = "pstklib([board|subcid|object])\n"; +const char pcb_acth_pstklib[] = "Present the padstack library dialog on board padstacks or the padstacks of a subcircuit"; +fgw_error_t pcb_act_pstklib(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + long id = -1; + const char *cmd = NULL; + RND_ACT_MAY_CONVARG(1, FGW_STR, pstklib, cmd = argv[1].val.str); + if ((cmd != NULL) && (strcmp(cmd, "object") == 0)) { + rnd_coord_t x, y; + void *r1, *r2, *r3; + pcb_subc_t *sc; + int type; + rnd_hid_get_coords("Pick a subcircuit for padstack lib editing", &x, &y, 0); + type = pcb_search_obj_by_location(PCB_OBJ_SUBC, &r1, &r2, &r3, x, y, PCB_SLOP * rnd_pixel_slop); + if (type != PCB_OBJ_SUBC) { + RND_ACT_IRES(-1); + return 0; + } + sc = r2; + id = sc->ID; + } + else + RND_ACT_MAY_CONVARG(1, FGW_LONG, pstklib, id = argv[1].val.nat_long); + if (pcb_dlg_pstklib(PCB, id, rnd_false, NULL) == PCB_PADSTACK_INVALID) + RND_ACT_IRES(-1); + else + RND_ACT_IRES(0); + return 0; +} + +void pcb_dlg_pstklib_init(void) +{ + htip_init(&pstk_libs, longhash, longkeyeq); +} + +void pcb_dlg_pstklib_uninit(void) +{ + htip_entry_t *e; + for(e = htip_first(&pstk_libs); e != NULL; e = htip_next(&pstk_libs, e)) + pstklib_close_cb(e->value, 0); + htip_uninit(&pstk_libs); + free(proto_save_fn); + free(proto_load_fn); + proto_save_fn = proto_load_fn = NULL; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_lib_pstk.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_lib_pstk.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_lib_pstk.h (revision 33253) @@ -0,0 +1,12 @@ +/* Open a padstack library dialog box for a subc (or for the board if subc_id + is 0). If modal, returns the selected prototype or PCB_PADSTACK_INVALID when + nothing is selected or the operation cancelled. In non-modal mode return + 0 on success and PCB_PADSTACK_INVALID on error. */ +rnd_cardinal_t pcb_dlg_pstklib(pcb_board_t *pcb, long subc_id, rnd_bool modal, const char *hint); + +extern const char pcb_acts_pstklib[]; +extern const char pcb_acth_pstklib[]; +fgw_error_t pcb_act_pstklib(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void pcb_dlg_pstklib_init(void); +void pcb_dlg_pstklib_uninit(void); Index: tags/2.3.0/src_plugins/dialogs/dlg_library.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_library.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_library.c (revision 33253) @@ -0,0 +1,748 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include "board.h" +#include "buffer.h" +#include "conf_core.h" +#include "data.h" +#include "draw.h" +#include "event.h" +#include "obj_subc.h" +#include "plug_footprint.h" +#include +#include "undo.h" + +#include +#include +#include +#include + +#include "dlg_library.h" + +static const char *library_cookie = "dlg_library"; + +#define MAX_PARAMS 128 + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int wtree, wpreview, wtags, wfilt, wpend, wnopend, wedit; + + int active; /* already open - allow only one instance */ + + pcb_subc_t *sc; + pcb_board_t *prev_pcb; /* sc must be in here so buffer changes don't ruin it */ + + rnd_hidval_t timer; + int timer_active; + + /* for the parametric */ + int pactive; /* already open - allow only one instance */ + int pwdesc; + RND_DAD_DECL_NOINIT(pdlg) + pcb_fplibrary_t *last_l; + char *example, *help_params; + htsi_t param_names; /* param_name -> param_idx */ + int pwid[MAX_PARAMS]; /* param_idx -> widget_idx (for the input field widget) */ + char *pnames[MAX_PARAMS]; /* param_idx -> parameter_name (also key stored in the param_names hash */ + int num_params, first_optional; + unsigned last_clicked:1; /* 1 if the last user action was a click in the tree, 0 if it was an edit of the filter text */ + gds_t descr; +} library_ctx_t; + +library_ctx_t library_ctx; + + +/* XPM */ +static const char *xpm_edit_param[] = { +"16 16 4 1", +"@ c #000000", +"* c #7A8584", +"+ c #6EA5D7", +" c None", +" ", +" @ @ ", +" @ ++++++++ @ ", +" @ + + @ ", +" @ + @@@@ + @ ", +" @ + + @ ", +"@ + @@ + @", +"@ + + @", +"@ + @ @ @+ @", +"@ + + @", +" @ + @@ + @ ", +" @ + @@@@ + @ ", +" @ + + @ ", +" @ ++++++++ @ ", +" @ @ ", +" " +}; + + +/* XPM */ +static const char *xpm_refresh[] = { +"16 16 4 1", +"@ c #000000", +"* c #7A8584", +"+ c #6EA5D7", +" c None", +" @ ", +" @@@@@@@ ", +" @@@ @@ ", +" @@@@ @ ", +" @ ", +" @ ", +" @ ", +" @ @ ", +" @ @ ", +" @ ", +" @ ", +" @ ", +" @ @@@@ ", +" @@ @@@ ", +" @@@@@@@ ", +" @ ", +}; + +static void library_update_preview(library_ctx_t *ctx, pcb_subc_t *sc, pcb_fplibrary_t *l) +{ + rnd_box_t bbox; + rnd_hid_attr_val_t hv; + gds_t tmp; + + if (ctx->sc != NULL) { + pcb_undo_freeze_add(); + pcb_subc_remove(ctx->sc); + pcb_undo_unfreeze_add(); + ctx->sc = NULL; + } + + gds_init(&tmp); + if (sc != NULL) { + ctx->sc = pcb_subc_dup_at(ctx->prev_pcb, ctx->prev_pcb->Data, sc, 0, 0, 1, rnd_false); + pcb_data_bbox(&bbox, ctx->sc->data, 0); + rnd_dad_preview_zoomto(&ctx->dlg[ctx->wpreview], &bbox); + } + + if (l != NULL) { + void **t; + +TODO("Use rich text for this with explicit wrap marks\n"); + /* update tags */ + for (t = l->data.fp.tags; ((t != NULL) && (*t != NULL)); t++) { + const char *name = pcb_fp_tagname(*t); + if (name != NULL) { + gds_append_str(&tmp, "\n "); + gds_append_str(&tmp, name); + } + } + gds_append_str(&tmp, "\nLocation:\n "); + gds_append_str(&tmp, l->data.fp.loc_info); + gds_append_str(&tmp, "\n"); + + hv.str = tmp.array; + } + else + hv.str = ""; + + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtags, &hv); + gds_uninit(&tmp); +} + +static void timed_update_preview_(library_ctx_t *ctx, const char *otext) +{ + if (otext != NULL) { + if (pcb_buffer_load_footprint(PCB_PASTEBUFFER, otext, NULL)) { + rnd_tool_select_by_name(&PCB->hidlib, "buffer"); + if (pcb_subclist_length(&PCB_PASTEBUFFER->Data->subc) != 0) + library_update_preview(ctx, pcb_subclist_first(&PCB_PASTEBUFFER->Data->subc), NULL); + rnd_gui->invalidate_all(rnd_gui); + } + } + else + pcb_buffer_clear(PCB, PCB_PASTEBUFFER); + ctx->timer_active = 0; + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wpend, 1); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wnopend, 0); +} + +static void timed_update_preview_cb(rnd_hidval_t user_data) +{ + library_ctx_t *ctx = user_data.ptr; + const char *otext = ctx->dlg[ctx->wfilt].val.str; + timed_update_preview_(ctx, otext); +} + +static void timed_update_preview(library_ctx_t *ctx, int active) +{ + if (ctx->timer_active) { + rnd_gui->stop_timer(rnd_gui, ctx->timer); + ctx->timer_active = 0; + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wpend, 1); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wnopend, 0); + } + + if (active) { + rnd_hidval_t user_data; + user_data.ptr = ctx; + ctx->timer = rnd_gui->add_timer(rnd_gui, timed_update_preview_cb, 500, user_data); + ctx->timer_active = 1; + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wpend, 0); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wnopend, 1); + } +} + +static void update_edit_button(library_ctx_t *ctx) +{ + const char *otext = ctx->dlg[ctx->wfilt].val.str; + int param_entered = 0, param_selected = 0; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&(ctx->dlg[ctx->wtree])); + + if (row != NULL) { + pcb_fplibrary_t *l = row->user_data; + param_selected = (l != NULL) && (l->type == PCB_LIB_FOOTPRINT) && (l->data.fp.type == PCB_FP_PARAMETRIC); + } + + param_entered = !ctx->pactive && (otext != NULL) && (strchr(otext, '(') != NULL); + + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wedit, param_selected || param_entered); +} + +#include "dlg_library_param.c" + +static void library_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + library_ctx_t *ctx = caller_data; + + if (ctx->pactive) { + ctx->pactive = 0; + RND_DAD_FREE(ctx->pdlg); + } + + timed_update_preview(ctx, 0); + pcb_board_free(ctx->prev_pcb); + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(library_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void create_lib_tree_model_recurse(rnd_hid_attribute_t *attr, pcb_fplibrary_t *parent_lib, rnd_hid_row_t *parent_row) +{ + char *cell[2]; + pcb_fplibrary_t *l; + int n; + + cell[1] = NULL; + for(l = parent_lib->data.dir.children.array, n = 0; n < parent_lib->data.dir.children.used; l++, n++) { + rnd_hid_row_t *row; + + cell[0] = rnd_strdup(l->name); + row = rnd_dad_tree_append_under(attr, parent_row, cell); + row->user_data = l; + if (l->type == PCB_LIB_DIR) + create_lib_tree_model_recurse(attr, l, row); + } +} + + +static void library_lib2dlg(library_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cursor_path = NULL; + + attr = &ctx->dlg[ctx->wtree]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items recursively */ + create_lib_tree_model_recurse(attr, &pcb_library, NULL); + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtree, &hv); + free(cursor_path); + } +} + +static void library_select_show_param_example(library_ctx_t *ctx, pcb_fplibrary_t *l) +{ + char line[1024], *arg, *cmd, *end; + FILE *f = library_param_get_help(ctx, l); + while(fgets(line, sizeof(line), f) != NULL) { + cmd = strchr(line, '@'); + if ((cmd == NULL) || (cmd[1] != '@')) + continue; + cmd+=2; + arg = strpbrk(cmd, " \t\r\n"); + if (arg != NULL) { + *arg = '\0'; + arg++; + while(isspace(*arg)) arg++; + } + if (strcmp(cmd, "example") == 0) { + if ((arg != NULL) && (*arg != '\0')) { + end = strpbrk(arg, "\r\n"); + if (end != NULL) + *end = '\0'; + timed_update_preview_(ctx, arg); + break; + } + } + } + rnd_pclose(f); +} + +static void library_select(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_attr_val_t hv; + rnd_hid_tree_t *tree = attrib->wdata; + library_ctx_t *ctx = tree->user_ctx; + int close_param = 1; + static pcb_fplibrary_t *last = NULL; + + ctx->last_clicked = 1; + + timed_update_preview(ctx, 0); + + library_update_preview(ctx, NULL, NULL); + if (row != NULL) { + pcb_fplibrary_t *l = row->user_data; + if ((l != NULL) && (l->type == PCB_LIB_FOOTPRINT)) { + if ((l->data.fp.type == PCB_FP_PARAMETRIC)) { + if (last != l) { /* first click */ + library_select_show_param_example(ctx, l); + update_edit_button(ctx); + } + else { /* second click */ + library_param_dialog(ctx, l); + close_param = 0; + } + } + else { + if (pcb_buffer_load_footprint(PCB_PASTEBUFFER, l->data.fp.loc_info, NULL)) { + rnd_tool_select_by_name(&PCB->hidlib, "buffer"); + if (pcb_subclist_length(&PCB_PASTEBUFFER->Data->subc) != 0) + library_update_preview(ctx, pcb_subclist_first(&PCB_PASTEBUFFER->Data->subc), l); + update_edit_button(ctx); + rnd_gui->invalidate_all(rnd_gui); + } + } + } + last = l; + } + + if (close_param) + library_param_dialog(ctx, NULL); + + hv.str = NULL; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wpreview, &hv); + +} + +static void library_expose(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + library_ctx_t *ctx = prv->user_ctx; + int orig_po = pcb_draw_force_termlab; + if (ctx->sc != NULL) { + pcb_draw_force_termlab = rnd_false; + pcb_subc_draw_preview(ctx->sc, &e->view); + pcb_draw_force_termlab = orig_po; + } +} + +static int tag_match(pcb_fplibrary_t *l, vtp0_t *taglist) +{ + size_t n; + + if (taglist->used == 0) + return 1; + + if (l->data.fp.tags == NULL) + return 0; + + for(n = 0; n < taglist->used; n++) { + void **t; + const void *need = pcb_fp_tag((const char *)taglist->array[n], 0); + int found = 0; + for(t = l->data.fp.tags, found = 0; *t != NULL; t++) { + if (*t == need) { + found = 1; + break; + } + } + + if (!found) + return 0; + } + + return 1; +} + +static void library_tree_unhide(rnd_hid_tree_t *tree, gdl_list_t *rowlist, re_sei_t *preg, vtp0_t *taglist) +{ + rnd_hid_row_t *r, *pr; + + for(r = gdl_first(rowlist); r != NULL; r = gdl_next(rowlist, r)) { + if (((preg == NULL) || (re_sei_exec(preg, r->cell[0]))) && tag_match(r->user_data, taglist)) { + rnd_dad_tree_hide_all(tree, &r->children, 0); /* if this is a node with children, show all children */ + for(pr = r; pr != NULL; pr = rnd_dad_tree_parent_row(tree, pr)) /* also show all parents so it is visible */ + pr->hide = 0; + } + library_tree_unhide(tree, &r->children, preg, taglist); + } +} + +static void library_filter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + library_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + const char *otext; + char *text, *sep, *para_start; + int have_filter_text, is_para, is_para_closed = 0; + + ctx->last_clicked = 0; + + attr = &ctx->dlg[ctx->wtree]; + tree = attr->wdata; + otext = attr_inp->val.str; + text = rnd_strdup(otext); + have_filter_text = (*text != '\0'); + + para_start = strchr(otext, '('); + is_para = (para_start != NULL); + if (is_para) + is_para_closed = (strchr(para_start, ')') != NULL); + + sep = strpbrk(text, " ()\t\r\n"); + if (sep != NULL) + *sep = '\0'; + + /* if an '(' is entered, stop new filtering, keep filter as is */ + if (is_para) + goto skip_filter; + + /* hide or unhide everything */ + + if (have_filter_text) { + /* need to unhide for expand to work */ + rnd_dad_tree_hide_all(tree, &tree->rows, 0); + rnd_dad_tree_update_hide(attr); + rnd_dad_tree_expcoll(attr, NULL, 1, 1); + rnd_dad_tree_hide_all(tree, &tree->rows, 1); + } + else + rnd_dad_tree_hide_all(tree, &tree->rows, 0); + + if (have_filter_text) { /* unhide hits and all their parents */ + char *tag, *next, *tags = NULL; + vtp0_t taglist; + re_sei_t *regex = NULL; + + if (!is_para) { + tags = strchr(otext, ' '); + if (tags != NULL) { + *tags = '\0'; + tags++; + while(isspace(*tags)) + tags++; + if (*tags == '\0') + tags = NULL; + } + } + + vtp0_init(&taglist); + if (tags != NULL) { + tags = rnd_strdup(tags); + for (tag = tags; tag != NULL; tag = next) { + next = strpbrk(tag, " \t\r\n"); + if (next != NULL) { + *next = '\0'; + next++; + while (isspace(*next)) + next++; + } + vtp0_append(&taglist, tag); + } + } + + if ((text != NULL) && (*text != '\0')) + regex = re_sei_comp(text); + + library_tree_unhide(tree, &tree->rows, regex, &taglist); + + if (regex != NULL) + re_sei_free(regex); + vtp0_uninit(&taglist); + free(tags); + } + + rnd_dad_tree_update_hide(attr); + + skip_filter:; + + /* parametric footprints need to be refreshed on edit */ + if (is_para_closed) + timed_update_preview(ctx, 1); + + update_edit_button(ctx); + + free(text); +} + +static rnd_hid_row_t *find_fp_prefix_(rnd_hid_tree_t *tree, gdl_list_t *rowlist, const char *name, int namelen) +{ + rnd_hid_row_t *r, *pr; + + for(r = gdl_first(rowlist); r != NULL; r = gdl_next(rowlist, r)) { + pcb_fplibrary_t *l = r->user_data; + if ((rnd_strncasecmp(r->cell[0], name, namelen) == 0) && (l->type == PCB_LIB_FOOTPRINT) && (l->data.fp.type == PCB_FP_PARAMETRIC)) + return r; + pr = find_fp_prefix_(tree, &r->children, name, namelen); + if (pr != NULL) + return pr; + } + return NULL; +} + +static rnd_hid_row_t *find_fp_prefix(library_ctx_t *ctx, const char *name, int namelen) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + + attr = &ctx->dlg[ctx->wtree]; + tree = attr->wdata; + + return find_fp_prefix_(tree, &tree->rows, name, namelen); +} + + +static void library_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + library_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr; + rnd_hid_row_t *r, *rnew; + const char *otext = ctx->dlg[ctx->wfilt].val.str; + char *name, *sep; + int namelen; + + attr = &ctx->dlg[ctx->wtree]; + r = rnd_dad_tree_get_selected(attr); + + if (!ctx->last_clicked && (otext != NULL)) { + name = rnd_strdup(otext); + sep = strchr(name, '('); + if (sep != NULL) + *sep = '\0'; + } + else { + pcb_fplibrary_t *l = r->user_data; + name = rnd_strdup(l->name); + if (name != NULL) { + rnd_hid_attr_val_t hv; + hv.str = name; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wfilt, &hv); + } + } + + if ((name == NULL) || (*name == '\0')) { + rnd_message(RND_MSG_ERROR, "Filed to figure the name of the parametric footprint\n"); + return; + } + namelen = strlen(name); + + if ((r == NULL) || (rnd_strncasecmp(name, r->cell[0], namelen) != 0)) { + /* no selection or wrong selection: go find the right one */ + rnew = find_fp_prefix(ctx, name, namelen); + } + else + rnew = r; + + if (rnew != NULL) { + if (r != rnew) + rnd_dad_tree_jumpto(attr, rnew); + library_param_dialog(ctx, rnew->user_data); + } + else + rnd_message(RND_MSG_ERROR, "No such parametric footprint: '%s'\n", name); + + free(name); +} + +static void library_refresh_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + library_ctx_t *ctx = caller_data; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(&(ctx->dlg[ctx->wtree])); + pcb_fplibrary_t *l; + char *oname; + + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "Need to select a subtree for refresh\n"); + return; + } + + l = r->user_data; + if ((l == NULL) || (l->parent == NULL)) { + rnd_message(RND_MSG_ERROR, "Selection can not be refreshed: unknown parent (please select the parent)\n", l); + return; + } + + while((l->parent != NULL) && (l->parent->parent != NULL)) l = l->parent; + + oname = rnd_strdup(l->name); /* need to save the name because refresh invalidates l */ + + if (pcb_fp_rehash(&PCB->hidlib, l) == 0) + rnd_message(RND_MSG_INFO, "Refreshed library '%s'\n", oname); + else + rnd_message(RND_MSG_ERROR, "Failed to refresh library '%s'\n", oname); + + free(oname); +} + + +static rnd_bool library_mouse(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + return rnd_false; +} + +static void pcb_dlg_library(void) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + const pcb_dflgmap_t *g; + int n; + + if (library_ctx.active) + return; /* do not open another */ + + library_ctx.prev_pcb = pcb_board_new_(1); + + for(g = pcb_dflgmap, n = 0; g->name != NULL; g++,n++) + pcb_layergrp_set_dflgly(library_ctx.prev_pcb, &(library_ctx.prev_pcb->LayerGroups.grp[n]), g, g->name, g->name); + library_ctx.prev_pcb->LayerGroups.len = n; + + RND_DAD_BEGIN_VBOX(library_ctx.dlg); + RND_DAD_COMPFLAG(library_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(library_ctx.dlg); + /* left */ + RND_DAD_BEGIN_VBOX(library_ctx.dlg); + RND_DAD_COMPFLAG(library_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(library_ctx.dlg, 1, 1, NULL); + RND_DAD_COMPFLAG(library_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_TREE_SET_CB(library_ctx.dlg, selected_cb, library_select); + RND_DAD_TREE_SET_CB(library_ctx.dlg, ctx, &library_ctx); + library_ctx.wtree = RND_DAD_CURRENT(library_ctx.dlg); + RND_DAD_BEGIN_HBOX(library_ctx.dlg); + RND_DAD_STRING(library_ctx.dlg); + RND_DAD_COMPFLAG(library_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_INIT_FOCUS); + RND_DAD_HELP(library_ctx.dlg, "filter: display only footprints matching this text\n(if empty: display all)"); + RND_DAD_CHANGE_CB(library_ctx.dlg, library_filter_cb); + library_ctx.wfilt = RND_DAD_CURRENT(library_ctx.dlg); + RND_DAD_PICBUTTON(library_ctx.dlg, xpm_edit_param); + RND_DAD_HELP(library_ctx.dlg, "open GUI to edit the parameters\nof a parametric footprint"); + RND_DAD_CHANGE_CB(library_ctx.dlg, library_edit_cb); + library_ctx.wedit = RND_DAD_CURRENT(library_ctx.dlg); + RND_DAD_PICBUTTON(library_ctx.dlg, xpm_refresh); + RND_DAD_HELP(library_ctx.dlg, "reload and refresh the current\nmain tree of the library"); + RND_DAD_CHANGE_CB(library_ctx.dlg, library_refresh_cb); + RND_DAD_END(library_ctx.dlg); + RND_DAD_END(library_ctx.dlg); + + /* right */ + RND_DAD_BEGIN_VPANE(library_ctx.dlg); + RND_DAD_COMPFLAG(library_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_FRAME); + /* right top */ + RND_DAD_PREVIEW(library_ctx.dlg, library_expose, library_mouse, NULL, NULL, NULL, 100, 100, &library_ctx); + library_ctx.wpreview = RND_DAD_CURRENT(library_ctx.dlg); + + /* right bottom */ + RND_DAD_BEGIN_VBOX(library_ctx.dlg); + RND_DAD_COMPFLAG(library_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(library_ctx.dlg, "Refreshing"); + RND_DAD_COMPFLAG(library_ctx.dlg, RND_HATF_HIDE); + library_ctx.wpend = RND_DAD_CURRENT(library_ctx.dlg); + RND_DAD_LABEL(library_ctx.dlg, " "); + library_ctx.wnopend = RND_DAD_CURRENT(library_ctx.dlg); + TODO("rich text label"); + RND_DAD_LABEL(library_ctx.dlg, ""); + library_ctx.wtags = RND_DAD_CURRENT(library_ctx.dlg); + RND_DAD_END(library_ctx.dlg); + RND_DAD_END(library_ctx.dlg); + RND_DAD_END(library_ctx.dlg); + + /* bottom */ + RND_DAD_BUTTON_CLOSES(library_ctx.dlg, clbtn); + RND_DAD_END(library_ctx.dlg); + + /* set up the context */ + library_ctx.active = 1; + + RND_DAD_NEW("library", library_ctx.dlg, "pcb-rnd Footprint Library", &library_ctx, rnd_false, library_close_cb); + + library_lib2dlg(&library_ctx); + rnd_gui->attr_dlg_widget_state(library_ctx.dlg_hid_ctx, library_ctx.wedit, 0); +} + +const char pcb_acts_LibraryDialog[] = "libraryDialog()\n"; +const char pcb_acth_LibraryDialog[] = "Open the library dialog."; +fgw_error_t pcb_act_LibraryDialog(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv) +{ + pcb_dlg_library(); + return 0; +} + +static void library_changed_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (library_ctx.active) + library_lib2dlg(&library_ctx); +} + +void pcb_dlg_library_uninit(void) +{ + rnd_event_unbind_allcookie(library_cookie); +} + +void pcb_dlg_library_init(void) +{ + rnd_event_bind(PCB_EVENT_LIBRARY_CHANGED, library_changed_ev, NULL, library_cookie); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_library.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_library.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_library.h (revision 33253) @@ -0,0 +1,6 @@ +extern const char pcb_acts_LibraryDialog[]; +extern const char pcb_acth_LibraryDialog[]; +fgw_error_t pcb_act_LibraryDialog(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv); + +void pcb_dlg_library_uninit(void); +void pcb_dlg_library_init(void); Index: tags/2.3.0/src_plugins/dialogs/dlg_library_param.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_library_param.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_library_param.c (revision 33253) @@ -0,0 +1,636 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + + +static void library_param_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + library_ctx_t *ctx = caller_data; + htsi_entry_t *e; + + gds_uninit(&ctx->descr); + free(ctx->help_params); + ctx->help_params = NULL; + + for(e = htsi_first(&ctx->param_names); e != NULL; e = htsi_next(&ctx->param_names, e)) + free(e->key); + htsi_uninit(&ctx->param_names); + if (ctx->pactive) { + ctx->pactive = 0; + RND_DAD_FREE(ctx->pdlg); + } + update_edit_button(ctx); +} + +#define colsplit() \ +do { \ + col = strchr(col, ':'); \ + if (col != NULL) { \ + *col = '\0'; \ + col++; \ + } \ +} while(0) + +static void set_attr(library_ctx_t *ctx, int pidx, char *val) +{ + rnd_hid_attr_val_t hv; + rnd_hid_attribute_t *a = &ctx->pdlg[ctx->pwid[pidx]]; + const char **s; + char *desc; + int vlen, len, n; + + switch(a->type) { + case RND_HATT_ENUM: + hv.lng = 0; /* fallback in case the loop doesn't find any match */ + vlen = strlen(val); + for(n = 0, s = a->wdata; *s != NULL; s++,n++) { + desc = strstr(*s, " ("); + if (desc != NULL) + len = desc - *s; + else + len = strlen(*s); + if ((len == vlen) && (strncmp(*s, val, len) == 0)) { + hv.lng = n; + break; + } + } + break; + case RND_HATT_STRING: + hv.str = val; + break; + case RND_HATT_BOOL: + if ((val == NULL) || (*val == '\0')) + return; + hv.lng = \ + (*val == '1') || (*val == 't') || (*val == 'T') || (*val == 'y') || (*val == 'Y') || \ + (((val[0] == 'o') || (val[0] == 'O')) && ((val[1] == 'n') || (val[1] == 'N'))); + break; + case RND_HATT_COORD: + case RND_HATT_END: /* compound widget for the spinbox! */ + hv.crd = rnd_get_value_ex(val, NULL, NULL, NULL, "mil", NULL); + break; + default: + assert(!"set_attr() can't set non-data field!\n"); + return; + } + rnd_gui->attr_dlg_set_value(ctx->pdlg_hid_ctx, ctx->pwid[pidx], &hv); +} + +static void library_param_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp); + +#define pre_append() \ +do { \ + if (help_def != NULL) { \ + if (help != NULL) { \ + char *tmp = rnd_concat(help, "\nDefault: ", help_def, NULL); \ + free(help); \ + free(help_def); \ + help = tmp; \ + } \ + else \ + help = help_def; \ + help_def = NULL; \ + } \ +} while(0) + +#define post_append() \ +do { \ + vtp0_uninit(&curr_enum); \ + free(name); name = NULL; \ + free(help); help = NULL; \ + curr_type = RND_HATT_END; \ + curr = -1; \ + vtp0_init(&curr_enum); \ + vtp0_append(&curr_enum, rnd_strdup("")); \ + numrows++; \ +} while(0) + +#define append() \ +do { \ + if (curr >= MAX_PARAMS) { \ + if (curr == MAX_PARAMS) \ + rnd_message(RND_MSG_ERROR, "too many parameters, displaying only the first %d\n", MAX_PARAMS); \ + break; \ + } \ + if (curr_type == RND_HATT_END) \ + break; \ + pre_append(); \ + RND_DAD_LABEL(library_ctx.pdlg, name); \ + RND_DAD_HELP(library_ctx.pdlg, rnd_strdup(help)); \ + switch(curr_type) { \ + case RND_HATT_COORD: \ + case RND_HATT_END: \ + RND_DAD_COORD(library_ctx.pdlg); \ + ctx->pwid[curr] = RND_DAD_CURRENT(library_ctx.pdlg); \ + RND_DAD_MINMAX(library_ctx.pdlg, 0, RND_MM_TO_COORD(512)); \ + RND_DAD_CHANGE_CB(library_ctx.pdlg, library_param_cb); \ + break; \ + case RND_HATT_STRING: \ + RND_DAD_STRING(library_ctx.pdlg); \ + ctx->pwid[curr] = RND_DAD_CURRENT(library_ctx.pdlg); \ + RND_DAD_CHANGE_CB(library_ctx.pdlg, library_param_cb); \ + break; \ + case RND_HATT_BOOL: \ + RND_DAD_BOOL(library_ctx.pdlg); \ + ctx->pwid[curr] = RND_DAD_CURRENT(library_ctx.pdlg); \ + RND_DAD_CHANGE_CB(library_ctx.pdlg, library_param_cb); \ + break; \ + case RND_HATT_ENUM: \ + RND_DAD_ENUM(library_ctx.pdlg, (const char **)curr_enum.array); \ + ctx->pwid[curr] = RND_DAD_CURRENT(library_ctx.pdlg); \ + RND_DAD_CHANGE_CB(library_ctx.pdlg, library_param_cb); \ + vtp0_init(&curr_enum); \ + vtp0_append(&curr_enum, rnd_strdup("")); \ + break; \ + default: \ + RND_DAD_LABEL(library_ctx.pdlg, "internal error: invalid type"); \ + } \ + RND_DAD_HELP(library_ctx.pdlg, rnd_strdup(help)); \ + ctx->pnames[curr] = rnd_strdup(name); \ + htsi_set(&ctx->param_names, ctx->pnames[curr], curr); \ + post_append(); \ +} while(0) + +static int library_param_build(library_ctx_t *ctx, pcb_fplibrary_t *l, FILE *f) +{ + char line[1024]; + char *name = NULL, *help = NULL, *help_def = NULL; + vtp0_t curr_enum; + int curr, examples = 0, numrows = 0; + rnd_hid_attr_type_t curr_type = RND_HATT_END; + + curr = -1; + + free(ctx->example); + ctx->example = NULL; + ctx->num_params = 0; + + vtp0_init(&curr_enum); + vtp0_append(&curr_enum, rnd_strdup("")); + + while(fgets(line, sizeof(line), f) != NULL) { + char *end, *col, *arg, *cmd = line; + + /* rtrim */ + end = line + strlen(line) - 1; + while((end >= line) && ((*end == '\r') || (*end == '\n'))) { + *end = '\0'; + end--; + } + + /* ltrim */ + cmd = strchr(cmd, '@'); + if ((cmd == NULL) || (cmd[1] != '@')) + continue; + cmd+=2; + arg = strpbrk(cmd, " \t\r\n"); + if (arg != NULL) { + *arg = '\0'; + arg++; + while(isspace(*arg)) arg++; + } + col = cmd; + + /* parse */ + if (strcmp(cmd, "desc") == 0) { + if (examples < 2) { + gds_append_str(&ctx->descr, arg); + gds_append(&ctx->descr, '\n'); + } + } + else if (strcmp(cmd, "params") == 0) { + free(ctx->help_params); + ctx->help_params = rnd_strdup(arg); + } + else if (strcmp(cmd, "example") == 0) { + if (examples == 0) { + free(ctx->example); + ctx->example = rnd_strdup(arg); + } + examples++; + } + else if (strncmp(cmd, "optional:", 9) == 0) { + if (ctx->first_optional < 0) + ctx->first_optional = ctx->num_params-1; + } + else if (strncmp(cmd, "param:", 6) == 0) { + append(); + colsplit(); + curr = ctx->num_params; + ctx->num_params++; + free(name); + free(help); + name = rnd_strdup(col); + help = rnd_strdup(arg); + curr_type = RND_HATT_STRING; /* assume string until a dim or enum overrides that */ + } + else if (strncmp(cmd, "default:", 6) == 0) { + free(help_def); + if (arg == NULL) + arg = ""; + help_def = rnd_strdup(arg); + } + else if (strncmp(cmd, "dim:", 4) == 0) { + curr_type = RND_HATT_COORD; + } + else if (strncmp(cmd, "bool:", 5) == 0) { + curr_type = RND_HATT_BOOL; + } + else if (strncmp(cmd, "enum:", 5) == 0) { + char *evl; + + curr_type = RND_HATT_ENUM; + colsplit(); colsplit(); + if (arg != NULL) { + if (strlen(arg) > 32) { + arg[32] = '\0'; + evl = rnd_strdup_printf("%s (%s...)", col, arg); + } + else + evl = rnd_strdup_printf("%s (%s)", col, arg); + } + else + evl = rnd_strdup(col); + vtp0_append(&curr_enum, evl); + } + } + append(); + return numrows; +} + +static char *gen_cmd(library_ctx_t *ctx) +{ + int n, pushed = 0; + gds_t sres; + char *tmp; + + memset(&sres, 0, sizeof(sres)); + + gds_append_str(&sres, ctx->last_l->name); + + /* cut original name at "(" */ + tmp = strchr(sres.array, '('); + if (tmp != NULL) + gds_truncate(&sres, tmp - sres.array); + + gds_append_str(&sres, "("); + + for(n = 0; n < ctx->num_params; n++) { + char *desc, buff[128]; + const char *val; + rnd_hid_attribute_t *a = &ctx->pdlg[ctx->pwid[n]]; + + if (((n >= ctx->first_optional) && (!a->changed)) || (a->empty)) + continue; + + switch(a->type) { + case RND_HATT_LABEL: + case RND_HATT_BEGIN_TABLE: + continue; + case RND_HATT_ENUM: + val = ((const char **)(a->wdata))[a->val.lng]; + if (val != NULL) { + if (*val != '\0') { + desc = strstr((char *)val, " ("); + if (desc != NULL) + *desc = '\0'; + } + else + val = NULL; + } + break; + case RND_HATT_STRING: + val = a->val.str; + if ((val != NULL) && (*val == '\0')) + continue; + break; + case RND_HATT_BOOL: + val = a->val.lng ? "yes" : "no"; + break; + case RND_HATT_COORD: + case RND_HATT_END: + val = buff; + rnd_snprintf(buff, sizeof(buff), "%.09$$mH", a->val.crd); + break; + default:; + } + + if (val == NULL) + continue; + + if (pushed) + gds_append_str(&sres, ", "); + + if ((n == pushed) && (n < ctx->first_optional)) + gds_append_str(&sres, val); /* positional */ + else + rnd_append_printf(&sres, "%s=%s", ctx->pnames[n], val); + pushed++; + } + + gds_append_str(&sres, ")"); + return sres.array; +} + +static void library_param_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + library_ctx_t *ctx = caller_data; + char *cmd = gen_cmd(ctx); + rnd_hid_attr_val_t hv; + + hv.str = cmd; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wfilt, &hv); + free(cmd); + timed_update_preview(ctx, 1); +} + +static int param_split(char *buf, char *argv[], int amax) +{ + int n; + char *next, *bump; + + for(n=0; ;n++) { + if (n >= amax) + return n+1; + + /* ltrim */ + while(isspace(*buf)) buf++; + argv[n] = buf; + + /* find next param */ + bump = buf; + next = strchr(buf, ','); + if (next == NULL) + return n+1; + buf = next+1; + + /* rtrim */ + *next = '\0'; + next--; + while((next >= bump) && (isspace(*next))) { + *next = '\0'; + next--; + } + } + return -1; +} + +static void load_params(library_ctx_t *ctx, char *user_params) +{ + char *parain; + char *parahlp; + int argc_in, argc_help, posi, n; + char *end, *argv_in[MAX_PARAMS], *argv_help[MAX_PARAMS]; + char *help_params = ctx->help_params; + + if (user_params == NULL) + user_params = ""; + if (help_params == NULL) + help_params = ""; + + + parain = rnd_strdup(user_params); + parahlp = rnd_strdup(help_params); + + /* truncate trailing ")" */ + if (*parain != '\0') { + end = parain + strlen(parain) - 1; + if (*end == ')') + *end = '\0'; + } + + argc_in = param_split(parain, argv_in, MAX_PARAMS); + argc_help = param_split(parahlp, argv_help, MAX_PARAMS); + + /* iterate and assign default values and mark them changed to get them back */ + for(posi = n = 0; n < argc_in; n++) { + char *key, *val, *sep; + htsi_entry_t *e; + int pidx; + + sep = strchr(argv_in[n], '='); + if (sep != NULL) { + key = argv_in[n]; + *sep = '\0'; + val = sep+1; + + /* rtrim key */ + sep--; + while((sep >= key) && (isspace(*sep))) { + *sep = '\0'; + sep--; + } + + /* ltrim val */ + while(isspace(*val)) val++; + } + else { + if (posi >= argc_help) { + rnd_message(RND_MSG_ERROR, "More positional parameters than expected - ignoring %s", argv_in[n]); + continue; + } + key = argv_help[posi]; + val = argv_in[n]; + posi++; + } + + e = htsi_getentry(&ctx->param_names, key); + if (e == NULL) { + rnd_message(RND_MSG_ERROR, "Unknown parameter %s - ignoring value %s", key, val); + continue; + } + pidx = e->value; + set_attr(ctx, pidx, val); + } + + /* clean up */ + free(parain); + free(parahlp); +} + +int pcb_library_param_fillin(library_ctx_t *ctx, pcb_fplibrary_t *l) +{ + rnd_hid_attr_val_t hv; + const char *filter_txt = ctx->dlg[ctx->wfilt].val.str; + + if (filter_txt != NULL) { + char *sep; + int len; + sep = strchr(l->name, '('); + if (sep != NULL) + len = sep - l->name; + else + len = strlen(l->name); + if (strncmp(filter_txt, l->name, len) != 0) { + /* clicked away from the previous parametric, but the filter text is still for that one; replace it */ + filter_txt = NULL; + } + } + + + if (filter_txt == NULL) { + + filter_txt = ctx->example; + + hv.str = filter_txt; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wfilt, &hv); + } + + if (filter_txt != NULL) { + const char *n1, *n2; + char *prm = strchr(filter_txt, '('); + + /* if filter text doesn't have parameters, try the example */ + if ((prm == NULL) || (prm[1] == ')')) { + if (ctx->example != NULL) { + filter_txt = ctx->example; + hv.str = filter_txt; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wfilt, &hv); + prm = strchr(filter_txt, '('); + } + } + + /* do not load parameters from the comamnd of a differently named + footprint to avoid invalid mixing of similar named parameters; in + that case rather fill in the dialog with the example */ + for(n1 = filter_txt, n2 = l->name;; n1++, n2++) { + if (*n1 != *n2) { + prm = ctx->example; + if (prm == NULL) + return -1; + while((*prm != '(') && (*prm != '\0')) prm++; + break; + } + else if ((*n1 == '(') || (*n1 == '\0')) + break; + } + + if (prm != NULL) + load_params(ctx, prm+1); + } + + hv.str = ctx->descr.array; + if (hv.str == NULL) + hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->pdlg_hid_ctx, ctx->pwdesc, &hv); + timed_update_preview(ctx, 1); + return 0; +} + +static int library_param_open(library_ctx_t *ctx, pcb_fplibrary_t *l, FILE *f) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + int w, oversized = 0; + + RND_DAD_BEGIN_VBOX(library_ctx.pdlg); + RND_DAD_COMPFLAG(library_ctx.pdlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(library_ctx.pdlg, "n/a"); + ctx->pwdesc = RND_DAD_CURRENT(library_ctx.pdlg); + RND_DAD_BEGIN_TABLE(library_ctx.pdlg, 2); + RND_DAD_COMPFLAG(library_ctx.pdlg, RND_HATF_EXPFILL); + w = RND_DAD_CURRENT(library_ctx.pdlg); + if (library_param_build(ctx, l, f) > 16) { + library_ctx.pdlg[w].rnd_hatt_flags |= RND_HATF_SCROLL; + oversized = 1; + } + RND_DAD_END(library_ctx.pdlg); + RND_DAD_BUTTON_CLOSES(library_ctx.pdlg, clbtn); + RND_DAD_END(library_ctx.pdlg); + return oversized; +} + +static FILE *library_param_get_help(library_ctx_t *ctx, pcb_fplibrary_t *l) +{ + FILE *f; + char *cmd; + +#ifdef __WIN32__ + { + char *s; + cmd = rnd_strdup_printf("%s/sh -c \"%s --help\"", rnd_w32_bindir, l->data.fp.loc_info); + for(s = cmd; *s != '\0'; s++) + if (*s == '\\') + *s = '/'; + } +#else + cmd = rnd_strdup_printf("%s --help", l->data.fp.loc_info); +#endif + f = rnd_popen(NULL, cmd, "r"); + free(cmd); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can not execute parametric footprint %s\n", l->data.fp.loc_info); + return NULL; + } + + return f; +} + +static void library_param_dialog(library_ctx_t *ctx, pcb_fplibrary_t *l) +{ + FILE *f; + + if (ctx->last_l != l) { + if (ctx->pactive) { + ctx->pactive = 0; + RND_DAD_FREE(ctx->pdlg); + } + update_edit_button(ctx); + } + else if (ctx->pactive) /* reopening the same -> nop */ + return; + + ctx->last_l = l; + + if (l == NULL) + return; + + f = library_param_get_help(ctx, l); + if (f == NULL) + return; + + htsi_init(&ctx->param_names, strhash, strkeyeq); + gds_init(&ctx->descr); + ctx->first_optional = -1; + + + ctx->pactive = 1; + if (library_param_open(ctx, l, f)) { + /* oversized dialog got the scroll bar, which would make it small; + set preferred size so it opens in reasonable area even when win size + not persistent (window palcement code) */ + RND_DAD_DEFSIZE(library_ctx.pdlg, 700, 500); + } + rnd_pclose(f); + + RND_DAD_NEW("lib_param", library_ctx.pdlg, "pcb-rnd parametric footprint", ctx, rnd_false, library_param_close_cb); + + update_edit_button(ctx); + pcb_library_param_fillin(ctx, l); +} + Index: tags/2.3.0/src_plugins/dialogs/dlg_loadsave.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_loadsave.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_loadsave.c (revision 33253) @@ -0,0 +1,618 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include "board.h" +#include "data.h" +#include +#include +#include +#include "conf_core.h" +#include +#include "plug_io.h" +#include + +#include "dlg_loadsave.h" + +extern conf_dialogs_t dialogs_conf; + +extern fgw_error_t pcb_act_LoadFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv); +extern fgw_error_t pcb_act_SaveTo(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +static char *dup_cwd(void) +{ + char tmp[RND_PATH_MAX + 1]; + return rnd_strdup(rnd_get_wd(tmp)); +} + +const char pcb_acts_Load[] = "Load()\n" "Load(Layout|LayoutToBuffer|ElementToBuffer|Netlist|Revert)"; +const char pcb_acth_Load[] = "Load layout data from a user-selected file."; +/* DOC: load.html */ +fgw_error_t pcb_act_Load(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + static char *last_footprint = NULL, *last_layout = NULL, *last_netlist = NULL; + const char *function = "Layout"; + char *name = NULL; + + if (last_footprint == NULL) last_footprint = dup_cwd(); + if (last_layout == NULL) last_layout = dup_cwd(); + if (last_netlist == NULL) last_netlist = dup_cwd(); + + /* Called with both function and file name -> no gui */ + if (argc > 2) + return RND_ACT_CALL_C(RND_ACT_HIDLIB, pcb_act_LoadFrom, res, argc, argv); + + RND_ACT_MAY_CONVARG(1, FGW_STR, Load, function = argv[1].val.str); + + if (rnd_strcasecmp(function, "Netlist") == 0) + name = rnd_gui->fileselect(rnd_gui, "Load netlist file", "Import netlist from file", last_netlist, ".net", NULL, "netlist", RND_HID_FSD_READ, NULL); + else if ((rnd_strcasecmp(function, "FootprintToBuffer") == 0) || (rnd_strcasecmp(function, "ElementToBuffer") == 0)) + name = rnd_gui->fileselect(rnd_gui, "Load footprint to buffer", "Import footprint from file", last_footprint, NULL, NULL, "footprint", RND_HID_FSD_READ, NULL); + else if (rnd_strcasecmp(function, "LayoutToBuffer") == 0) + name = rnd_gui->fileselect(rnd_gui, "Load layout to buffer", "load layout (board) to buffer", last_layout, NULL, NULL, "board", RND_HID_FSD_READ, NULL); + else if (rnd_strcasecmp(function, "Layout") == 0) + name = rnd_gui->fileselect(rnd_gui, "Load layout file", "load layout (board) as board to edit", last_layout, NULL, NULL, "board", RND_HID_FSD_READ, NULL); + else { + rnd_message(RND_MSG_ERROR, "Invalid subcommand for Load(): '%s'\n", function); + RND_ACT_IRES(1); + return 0; + } + + if (name != NULL) { + if (rnd_conf.rc.verbose) + fprintf(stderr, "Load: Calling LoadFrom(%s, %s)\n", function, name); + rnd_actionva(RND_ACT_HIDLIB, "LoadFrom", function, name, NULL); + free(name); + } + + RND_ACT_IRES(0); + return 0; +} + +/*** Save ***/ + +typedef struct { + rnd_hid_dad_subdialog_t *fmtsub; + pcb_io_formats_t *avail; + int *opt_tab; /* plugion options tab index for each avail[]; 0 means "no options" (the first tab) */ + const char **fmt_tab_names; + void **fmt_plug_data; + int tabs; /* number of option tabs, including the dummy 0th tab */ + int wfmt, wguess, wguess_err, wopts; + int pick, num_fmts; + rnd_hidval_t timer; + char last_ext[32]; + unsigned fmt_chg_lock:1; + unsigned timer_active:1; + unsigned inited:1; +} save_t; + +static void update_opts(save_t *save) +{ + rnd_hid_attr_val_t hv; + int selection = save->fmtsub->dlg[save->wfmt].val.lng; + + hv.lng = save->opt_tab[selection]; + rnd_gui->attr_dlg_set_value(save->fmtsub->dlg_hid_ctx, save->wopts, &hv); +} + +static void fmt_chg(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_dad_subdialog_t *fmtsub = caller_data; + save_t *save = fmtsub->sub_ctx; + char *bn, *fn, *s; + const char *ext; + rnd_event_arg_t res, argv[4]; + int selection = attr->val.lng; + rnd_hid_attr_val_t hv; + + if ((save->avail == NULL) || save->fmt_chg_lock) + return; + + if (fmtsub->parent_poke(fmtsub, "get_path", &res, 0, NULL) != 0) + return; + + /* turn off guessing becuase the user explicitly selected a format */ + hv.lng = 0; + rnd_gui->attr_dlg_set_value(save->fmtsub->dlg_hid_ctx, save->wguess, &hv); + + fn = (char *)res.d.s; + + /* find and truncate extension */ + for (s = fn + strlen(fn) - 1; *s != '.'; s--) { + if ((s <= fn) || (*s == RND_DIR_SEPARATOR_C)) { + free(fn); + return; + } + } + *s = '\0'; + + /* calculate basename in bn */ + bn = strrchr(fn, RND_DIR_SEPARATOR_C); + if (bn == NULL) + bn = fn; + else + bn++; + + /* fetch the desired extension */ + ext = save->avail->extension[selection]; + if (ext == NULL) + ext = "."; + + /* build a new file name with the right extension */ + + argv[0].type = RND_EVARG_STR; + argv[0].d.s = rnd_concat(bn, ext, NULL);; + fmtsub->parent_poke(fmtsub, "set_file_name", &res, 1, argv); + free(fn); + + /* remember the selection for the save action */ + save->pick = selection; + + /* set the tab for format specific settings */ + update_opts(save); +} + +static void guess_chg(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_dad_subdialog_t *fmtsub = caller_data; + save_t *save = fmtsub->sub_ctx; + + if (save->fmtsub->dlg[save->wguess].val.lng) { + /* when guess is activated, make sure to recalculate the guess whatever + the format or the last file name was - this closes out all corner cases + with initial format mismatching the file name and multiple formats for + an ext */ + save->last_ext[0] = '\0'; + } +} + + +static void save_guess_format(save_t *save, const char *ext) +{ + int n; + + if (strcmp(ext, save->last_ext) == 0) + return; + + strncpy(save->last_ext, ext, sizeof(save->last_ext)); + + for(n = 0; n < save->num_fmts; n++) { + if (strcmp(save->avail->extension[n], ext) == 0) { + rnd_hid_attr_val_t hv; + save->fmt_chg_lock = 1; + hv.lng = n; + rnd_gui->attr_dlg_set_value(save->fmtsub->dlg_hid_ctx, save->wfmt, &hv); + save->fmt_chg_lock = 0; + update_opts(save); + rnd_gui->attr_dlg_widget_hide(save->fmtsub->dlg_hid_ctx, save->wguess_err, 1); + fmt_chg(save->fmtsub->dlg_hid_ctx, save->fmtsub, save->fmtsub->dlg+save->wfmt); + /* turn on guessing - was turned off by the call above */ + hv.lng = 1; + rnd_gui->attr_dlg_set_value(save->fmtsub->dlg_hid_ctx, save->wguess, &hv); + return; + } + } + rnd_gui->attr_dlg_widget_hide(save->fmtsub->dlg_hid_ctx, save->wguess_err, 0); +} + +static void save_timer(rnd_hidval_t user_data) +{ + save_t *save = user_data.ptr; + + if ((save->fmtsub == NULL) || (save->avail == NULL)) { + save->timer_active = 0; + return; /* do not even restart the timer */ + } + + if (!save->inited) { + update_opts(save); + save->inited = 1; + } + + save->timer = rnd_gui->add_timer(rnd_gui, save_timer, 300, user_data); + + if ((save->fmtsub->parent_poke != NULL) && (save->fmtsub->dlg_hid_ctx != NULL) && (save->fmtsub->dlg[save->wguess].val.lng)) { + rnd_event_arg_t res; + char *end; + + save->fmtsub->parent_poke(save->fmtsub, "get_path", &res, 0, NULL); + end = strrchr(res.d.s, '.'); + if (end != NULL) + save_guess_format(save, end); + + free((char *)res.d.s); + } +} + +static void save_on_close(rnd_hid_dad_subdialog_t *sub, rnd_bool ok) +{ + save_t *save = sub->sub_ctx; + int n, i; + char *seen; + int tab_selection = save->opt_tab[save->fmtsub->dlg[save->wfmt].val.lng]; + + seen = calloc(1, save->tabs); + for(n = 1; n < save->tabs; n++) { + for(i = 0; i < save->num_fmts; i++) { + if ((seen[n] == 0) && (save->opt_tab[i] == n)) { + const pcb_plug_io_t *plug = save->avail->plug[i]; + seen[n] = 1; + if (plug->save_as_subd_uninit != NULL) + plug->save_as_subd_uninit(plug, save->fmt_plug_data[n], sub, (ok && (n == tab_selection))); + } + } + } + free(seen); +} + + +static void setup_fmt_tabs(save_t *save, pcb_plug_iot_t save_type) +{ + int n, i, tabs; + + save->opt_tab = calloc(sizeof(int), save->num_fmts); + for(n = 0, tabs = 0; n < save->num_fmts; n++) { + const pcb_plug_io_t *plug = save->avail->plug[n]; + if (plug->save_as_subd_init != NULL) { + int link = -1; + + /* check if init() matches an already existing tab's and link them if so */ + for(i = 0; i < n; i++) { + const pcb_plug_io_t *old_plug = save->avail->plug[i]; + if (plug->save_as_subd_init == old_plug->save_as_subd_init) { + link = save->opt_tab[i]; + break; + } + } + + if (link < 0) { + save->opt_tab[n] = tabs+1; + tabs++; + } + else + save->opt_tab[n] = link; + } + } + + /* tab 0 is for the no-option tab (most plugs will use that) */ + save->fmt_tab_names = calloc(tabs+2, sizeof(char *)); + save->fmt_plug_data = calloc(tabs+2, sizeof(void *)); + save->fmt_tab_names[0] = "no-opt"; + + /* fill in rest of the tabs - not visible, only for debugging */ + for(n = 0; n < save->num_fmts; n++) { + const pcb_plug_io_t *plug = save->avail->plug[n]; + if ((plug->save_as_subd_init != NULL) && (save->opt_tab[n] >= 0)) + save->fmt_tab_names[save->opt_tab[n]] = plug->description; + } + save->fmt_tab_names[tabs+1] = NULL; + + RND_DAD_BEGIN_TABBED(save->fmtsub->dlg, save->fmt_tab_names); + RND_DAD_COMPFLAG(save->fmtsub->dlg, RND_HATF_HIDE_TABLAB); + save->wopts = RND_DAD_CURRENT(save->fmtsub->dlg); +/* pre-creation tab switch not yet supported: RND_DAD_DEFAULT_NUM(save->fmtsub->dlg, save->opt_tab[0]);*/ + + /* the no-options tab */ + RND_DAD_LABEL(save->fmtsub->dlg, "(no format options)"); + RND_DAD_HELP(save->fmtsub->dlg, "Some formats offer format-specific options\nwhich are normally displayed here.\nThe currently selected format does\nnot offer any options."); + + /* all other tabs, filled in by the plug code */ + for(n = 1; n < tabs+1; n++) { + for(i = 0; i < save->num_fmts; i++) { + if (save->opt_tab[i] == n) { + const pcb_plug_io_t *plug = save->avail->plug[i]; + RND_DAD_BEGIN_VBOX(save->fmtsub->dlg); + save->fmt_plug_data[n] = plug->save_as_subd_init(plug, save->fmtsub, save_type); + RND_DAD_END(save->fmtsub->dlg); + break; + } + } + } + save->tabs = tabs+1; + RND_DAD_END(save->fmtsub->dlg); +} + +static void setup_fmt_sub(save_t *save, pcb_plug_iot_t save_type) +{ + const char *guess_help = + "allow guessing format from the file name:\n" + "when enabled, the format is automatically determined\n" + "from the file name after an edit to the file name\n" + "(guessing will NOT change the initial format selection\n" + "when the dialog box is fresh open)"; + + RND_DAD_BEGIN_VBOX(save->fmtsub->dlg); + RND_DAD_BEGIN_HBOX(save->fmtsub->dlg); + RND_DAD_LABEL(save->fmtsub->dlg, "File format:"); + RND_DAD_ENUM(save->fmtsub->dlg, (const char **)save->avail->digest); + save->wfmt = RND_DAD_CURRENT(save->fmtsub->dlg); + RND_DAD_DEFAULT_NUM(save->fmtsub->dlg, save->pick); + RND_DAD_CHANGE_CB(save->fmtsub->dlg, fmt_chg); + RND_DAD_END(save->fmtsub->dlg); + RND_DAD_BEGIN_HBOX(save->fmtsub->dlg); + RND_DAD_LABEL(save->fmtsub->dlg, "Guess format:"); + RND_DAD_HELP(save->fmtsub->dlg, guess_help); + RND_DAD_BOOL(save->fmtsub->dlg); + save->wguess = RND_DAD_CURRENT(save->fmtsub->dlg); + RND_DAD_CHANGE_CB(save->fmtsub->dlg, guess_chg); + RND_DAD_DEFAULT_NUM(save->fmtsub->dlg, !!dialogs_conf.plugins.dialogs.file_select_dialog.save_as_format_guess); + RND_DAD_HELP(save->fmtsub->dlg, guess_help); + RND_DAD_LABEL(save->fmtsub->dlg, "(guess failed)"); + RND_DAD_COMPFLAG(save->fmtsub->dlg, RND_HATF_HIDE); + RND_DAD_HELP(save->fmtsub->dlg, "This file name is not naturally connected to\nany file format; file format\nis left on what was last selected/recognized"); + save->wguess_err = RND_DAD_CURRENT(save->fmtsub->dlg); + RND_DAD_END(save->fmtsub->dlg); + + + setup_fmt_tabs(save, save_type); + RND_DAD_END(save->fmtsub->dlg); +} + +const char pcb_acts_Save[] = + "Save()\n" + "Save(Layout|LayoutAs)\n" + "Save(AllConnections|AllUnusedPins|ElementConnections)\n" + "Save(PasteBuffer)\n" + "Save(DialogByPattern, pcb|footprint|font|buffer, none|board|fp, prompt, [default_pattern])"; +const char pcb_acth_Save[] = "Save layout data to a user-selected file."; +/* DOC: save.html */ +fgw_error_t pcb_act_Save(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *function = "Layout"; + static char *cwd = NULL; + rnd_hid_dad_subdialog_t *fmtsub = NULL, fmtsub_local; + char *final_name, *name_in = NULL; + const char *prompt; + pcb_io_formats_t avail; + const char **extensions_param = NULL; + int num_fmts, fmt, *fmt_param = NULL; + save_t save; + rnd_hidval_t timer_ctx; + const char *default_pattern = NULL; + pcb_plug_iot_t list_iot; + pcb_io_list_ext_t list_ext; + int dialog_by_pattern = 0, is_dialog; + + if (cwd == NULL) cwd = dup_cwd(); + + + RND_ACT_MAY_CONVARG(1, FGW_STR, Save, function = argv[1].val.str); + + is_dialog = (function != NULL) && (rnd_strncasecmp(function, "Dialog", 6) == 0); + + if ((!is_dialog) && (argc > 2)) + return RND_ACT_CALL_C(RND_ACT_HIDLIB, pcb_act_SaveTo, res, argc, argv); + + memset(&save, 0, sizeof(save)); + + if (rnd_strcasecmp(function, "Layout") == 0) + if (PCB->hidlib.filename != NULL) + return rnd_actionva(RND_ACT_HIDLIB, "SaveTo", "Layout", NULL); + + if (is_dialog) { + const char *siot, *sext; + + RND_ACT_CONVARG(2, FGW_STR, Save, siot = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, Save, sext = argv[3].val.str); + RND_ACT_CONVARG(4, FGW_STR, Save, prompt = argv[4].val.str); + RND_ACT_MAY_CONVARG(5, FGW_STR, Save, default_pattern = argv[5].val.str); + + if (rnd_strcasecmp(siot, "pcb") == 0) list_iot = PCB_IOT_PCB; + else if (rnd_strcasecmp(siot, "footprint") == 0) list_iot = PCB_IOT_FOOTPRINT; + else if (rnd_strcasecmp(siot, "font") == 0) list_iot = PCB_IOT_FONT; + else if (rnd_strcasecmp(siot, "buffer") == 0) list_iot = PCB_IOT_BUFFER; + else RND_ACT_FAIL(Save); + + if (rnd_strcasecmp(sext, "none") == 0) list_ext = PCB_IOL_EXT_NONE; + else if (rnd_strcasecmp(sext, "board") == 0) list_ext = PCB_IOL_EXT_BOARD; + else if (rnd_strcasecmp(sext, "fp") == 0) list_ext = PCB_IOL_EXT_FP; + else RND_ACT_FAIL(Save); + } + + if (rnd_strcasecmp(function, "PasteBuffer") == 0) { + default_pattern = conf_core.rc.save_fp_fmt; + num_fmts = pcb_io_list(&avail, PCB_IOT_FOOTPRINT, 1, 1, PCB_IOL_EXT_FP); + prompt = "Save subcircuit as"; + list_iot = PCB_IOT_FOOTPRINT; + list_ext = PCB_IOL_EXT_FP; + goto list_by_pattern; + } + else if (rnd_strcasecmp(function, "DialogByPattern") == 0) { + int n; + + dialog_by_pattern = 1; + + list_by_pattern:; + num_fmts = pcb_io_list(&avail, list_iot, 1, 1, list_ext); + if (num_fmts > 0) { + extensions_param = (const char **)avail.extension; + fmt_param = &fmt; + fmt = -1; + + if (default_pattern != NULL) { + /* look for exact match, case sensitive */ + for (n = 0; n < num_fmts; n++) + if (strcmp(avail.plug[n]->description, default_pattern) == 0) + fmt = n; + + /* look for exact match, case insensitive */ + if (fmt < 0) + for (n = 0; n < num_fmts; n++) + if (rnd_strcasecmp(avail.plug[n]->description, default_pattern) == 0) + fmt = n; + + /* look for partial match */ + if (fmt < 0) { + for (n = 0; n < num_fmts; n++) { + if (strstr(avail.plug[n]->description, default_pattern) != NULL) { + fmt = n; + break; /* pick the first one, that has the highest prio */ + } + } + } + + if (fmt < 0) { + static int warned = 0; + if (!warned) + rnd_message(RND_MSG_WARNING, "Could not find an io_ plugin for the preferred footprint save format (configured in rc/save_fp_fmt): '%s'\n", default_pattern); + warned = 1; + } + } + + fmtsub = &fmtsub_local; + + if (fmt < 0) /* fallback: choose the frist format */ + fmt = 0; + + name_in = rnd_concat("unnamed", avail.plug[fmt]->fp_extension, NULL); + } + else { + rnd_message(RND_MSG_ERROR, "Error: no IO plugin avaialble for saving a buffer."); + RND_ACT_IRES(-1); + return 0; + } + } + else { + int n; + prompt = "Save layout as"; + num_fmts = pcb_io_list(&avail, PCB_IOT_PCB, 1, 1, PCB_IOL_EXT_BOARD); + if (num_fmts > 0) { + extensions_param = (const char **)avail.extension; + fmt_param = &fmt; + fmt = 0; + if (PCB->Data->loader != NULL) { + for (n = 0; n < num_fmts; n++) { + if (avail.plug[n] == PCB->Data->loader) { + fmt = n; + break; + } + } + } + fmtsub = &fmtsub_local; + } + else { + rnd_message(RND_MSG_ERROR, "Error: no IO plugin avaialble for saving a buffer."); + RND_ACT_IRES(-1); + return 0; + } + } + + if (fmtsub != NULL) { + memset(&fmtsub_local, 0, sizeof(fmtsub_local)); + save.avail = &avail; + save.num_fmts = num_fmts; + save.fmtsub = fmtsub; + save.pick = fmt; + fmtsub->on_close = save_on_close; + fmtsub->sub_ctx = &save; + setup_fmt_sub(&save, PCB_IOT_PCB); + } + + /* construct the input file name and run a file selection dialog to get the final file name */ + if (name_in == NULL) { + if (PCB->hidlib.filename == NULL) + name_in = rnd_concat("unnamed", extensions_param[fmt], NULL); + else + name_in = rnd_strdup(PCB->hidlib.filename); + } + + + { + /* save initial extension so the timer doesn't immedaitely overwrite the + original format with a guess - important when the format is known + but doesn't match the name and guessing is enabled */ + const char *end; + end = strrchr(name_in, '.'); + if (end != NULL) + strncpy(save.last_ext, end, sizeof(save.last_ext)); + } + + timer_ctx.ptr = &save; + save.timer_active = 1; + save.timer = rnd_gui->add_timer(rnd_gui, save_timer, 300, timer_ctx); /* the timer needs to run at least once, to get some initialization done that can be done only after fmtsub got created */ + final_name = rnd_gui->fileselect(rnd_gui, prompt, NULL, name_in, NULL, NULL, "board", RND_HID_FSD_MAY_NOT_EXIST, fmtsub); + if (save.timer_active) + rnd_gui->stop_timer(rnd_gui, save.timer); + free(name_in); + free(save.fmt_tab_names); + free(save.fmt_plug_data); + + /* early return for dialog-by-pattern: don't do anything real, just build a string and return */ + if (dialog_by_pattern) { + const char *sfmt = NULL; + if (fmt_param != NULL) + sfmt = avail.plug[save.pick]->default_fmt; + res->type = FGW_STR | FGW_DYN; + if (final_name != NULL) + res->val.str = rnd_concat(final_name, "*", sfmt, NULL); + else + res->val.str = NULL; + free(final_name); + pcb_io_list_free(&avail); + return 0; + } + + if (final_name == NULL) { /* cancel */ + pcb_io_list_free(&avail); + RND_ACT_IRES(1); + return 0; + } + + + if (rnd_conf.rc.verbose) + fprintf(stderr, "Save: Calling SaveTo(%s, %s)\n", function, final_name); + + if (rnd_strcasecmp(function, "PasteBuffer") == 0) { + const char *sfmt = avail.plug[fmt]->description; + if (fmt_param != NULL) + sfmt = avail.plug[save.pick]->description; + rnd_actionva(RND_ACT_HIDLIB, "PasteBuffer", "Save", final_name, sfmt, NULL); + } + else { + const char *sfmt = NULL; + if (fmt_param != NULL) + sfmt = avail.plug[save.pick]->description; + /* + * if we got this far and the function is Layout, then + * we really needed it to be a LayoutAs. Otherwise + * ActionSaveTo() will ignore the new file name we + * just obtained. + */ + if (rnd_strcasecmp(function, "Layout") == 0) + rnd_actionva(RND_ACT_HIDLIB, "SaveTo", "LayoutAs", final_name, sfmt, NULL); + else + rnd_actionva(RND_ACT_HIDLIB, "SaveTo", function, final_name, sfmt, NULL); + } + + free(final_name); + pcb_io_list_free(&avail); + RND_ACT_IRES(0); + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_loadsave.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_loadsave.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_loadsave.h (revision 33253) @@ -0,0 +1,7 @@ +extern const char pcb_acts_Load[]; +extern const char pcb_acth_Load[]; +fgw_error_t pcb_act_Load(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char pcb_acts_Save[]; +extern const char pcb_acth_Save[]; +fgw_error_t pcb_act_Save(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/2.3.0/src_plugins/dialogs/dlg_netlist.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_netlist.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_netlist.c (revision 33253) @@ -0,0 +1,629 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "event.h" +#include "netlist.h" +#include +#include + +const char *dlg_netlist_cookie = "netlist dialog"; + +/* timeout for handling two clicks as a double click */ +#define DBL_CLICK_TIME 0.7 + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + pcb_board_t *pcb; + rnd_box_t bb_prv; + int wnetlist, wprev, wtermlist; + int wsel, wunsel, wfind, wunfind, wrats, wnorats, wallrats, wnoallrats, wripup, waddrats, wrename, wmerge, wattr, wnlcalc, wnlon, wnloff; + void *last_selected_row; + double last_selected_time; + int active; /* already open - allow only one instance */ +} netlist_ctx_t; + +netlist_ctx_t netlist_ctx; + +static void netlist_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + netlist_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(netlist_ctx_t)); + rnd_event(&PCB->hidlib, RND_EVENT_GUI_LEAD_USER, "cci", 0, 0, 0); +} + +/* returns allocated net name for the currently selected net */ +static char *netlist_data2dlg_netlist(netlist_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[6], *cursor_path = NULL; + pcb_net_t **n, **nets; + + attr = &ctx->dlg[ctx->wnetlist]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + nets = pcb_netlist_sort(&ctx->pcb->netlist[1]); + if (nets != NULL) { + cell[4] = NULL; + for(n = nets; *n != NULL; n++) { + cell[0] = rnd_strdup((*n)->name); + cell[1] = rnd_strdup((*n)->inhibit_rats ? "*" : ""); + cell[2] = rnd_strdup((*n)->auto_len ? "*" : ""); + cell[3] = rnd_strdup(""); + rnd_dad_tree_append(attr, NULL, cell); + } + free(nets); + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wnetlist, &hv); + } + } + return cursor_path; +} + +static void netlist_data2dlg_connlist(netlist_ctx_t *ctx, pcb_net_t *net) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[2], *cursor_path = NULL; + pcb_net_term_t *t; + + attr = &ctx->dlg[ctx->wtermlist]; + tree = attr->wdata; + + /* remember cursor */ + if (net != NULL) { + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + } + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + if (net == NULL) + return; + + cell[1] = NULL; + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) { + cell[0] = rnd_concat(t->refdes, "-", t->term, NULL); + rnd_dad_tree_append(attr, NULL, cell); + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtermlist, &hv); + free(cursor_path); + } +} + + +static void netlist_data2dlg(netlist_ctx_t *ctx) +{ + pcb_net_t *curnet = NULL; + char *curnetname = netlist_data2dlg_netlist(ctx); + + if (curnetname != NULL) + curnet = pcb_net_get(ctx->pcb, &ctx->pcb->netlist[PCB_NETLIST_EDITED], curnetname, 0); + free(curnetname); + netlist_data2dlg_connlist(ctx, curnet); +} + +static void netlist_force_redraw(netlist_ctx_t *ctx) +{ + rnd_dad_preview_zoomto(&ctx->dlg[ctx->wprev], &ctx->bb_prv); +} + + +static void netlist_row_selected(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + netlist_ctx_t *ctx= tree->user_ctx; + const char *netname = NULL; + pcb_net_t *net = NULL; + + if (row != NULL) { + netname = row->cell[0]; + if ((row == ctx->last_selected_row) && ((rnd_dtime() - ctx->last_selected_time) < DBL_CLICK_TIME)) { + int disabled = (row->cell[1][0] == '*'); + if (netname != NULL) + rnd_actionva(&ctx->pcb->hidlib, "netlist", disabled ? "rats" : "norats", netname, NULL); + ctx->last_selected_row = NULL; + return; + } + } + if (netname != NULL) + net = pcb_net_get(ctx->pcb, &ctx->pcb->netlist[PCB_NETLIST_EDITED], netname, 0); + netlist_data2dlg_connlist(ctx, net); + rnd_event(&PCB->hidlib, RND_EVENT_GUI_LEAD_USER, "cci", 0, 0, 0); + netlist_force_redraw(ctx); + + ctx->last_selected_row = row; + ctx->last_selected_time = rnd_dtime(); +} + +static void termlist_row_selected(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + netlist_ctx_t *ctx= tree->user_ctx; + char *refdes, *term; + pcb_any_obj_t *obj; + + rnd_event(&PCB->hidlib, RND_EVENT_GUI_LEAD_USER, "cci", 0, 0, 0); + if (row == NULL) + return; + refdes = rnd_strdup(row->cell[0]); + term = strchr(refdes, '-'); + if (term != NULL) { + *term = '\0'; + term++; + obj = pcb_term_find_name(ctx->pcb, ctx->pcb->Data, PCB_LYT_COPPER, refdes, term, NULL, NULL); + if (obj != NULL) { + rnd_coord_t x, y; + pcb_obj_center(obj, &x, &y); + rnd_event(&PCB->hidlib, RND_EVENT_GUI_LEAD_USER, "cci", x, y, 1); + } + } + free(refdes); +} + +static void netlist_update_len_by_row(netlist_ctx_t *ctx, rnd_hid_row_t *row) +{ + rnd_hid_attribute_t *atree = &ctx->dlg[ctx->wnetlist]; + const char *name = rnd_strdup(row->cell[0]); + fgw_arg_t nlres; + fgw_arg_t nlargv[2]; + fgw_error_t err; + + nlargv[1].type = FGW_STR; nlargv[1].val.cstr = name; + err = rnd_actionv_bin(&ctx->pcb->hidlib, "QueryCalcNetLen", &nlres, 2, nlargv); + if (err != 0) { + rnd_message(RND_MSG_ERROR, "Internal error: failed to execute QueryCalcNetLen() - is the query plugin enabled?\n"); + return; + } + + if (nlres.type == FGW_COORD) { + char tmp[128]; + rnd_snprintf(tmp, sizeof(tmp), "%$m*", rnd_conf.editor.grid_unit->suffix, fgw_coord(&nlres)); + rnd_dad_tree_modify_cell(atree, row, 3, tmp); + } + else if ((nlres.type & FGW_STR) == FGW_STR) + rnd_dad_tree_modify_cell(atree, row, 3, nlres.val.str); + else + rnd_dad_tree_modify_cell(atree, row, 3, "invalid return"); +} + +#if 0 +static void netlist_update_len_by_name(netlist_ctx_t *ctx, const char *name) +{ + rnd_hid_attribute_t *atree = &ctx->dlg[ctx->wnetlist]; + rnd_hid_tree_t *tree = atree->wdata; + rnd_hid_row_t *row = htsp_get(&tree->paths, name); + if (row != NULL) + netlist_update_len_by_row(ctx, row); +} +#endif + +static void netlist_button_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + netlist_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *atree; + int w = attr - ctx->dlg; + rnd_hid_row_t *r; + const char *name; + + atree = &ctx->dlg[ctx->wnetlist]; + + /* no selection required */ + if (w == ctx->wallrats) { + rnd_actionva(&ctx->pcb->hidlib, "netlist", "allrats", NULL); + return; + } + else if (w == ctx->wnoallrats) { + rnd_actionva(&ctx->pcb->hidlib, "netlist", "noallrats", NULL); + return; + } + + r = rnd_dad_tree_get_selected(atree); + if (r == NULL) + return; + name = rnd_strdup(r->cell[0]); + + if (w == ctx->wsel) + rnd_actionva(&ctx->pcb->hidlib, "netlist", "select", name, NULL); + else if (w == ctx->wunsel) + rnd_actionva(&ctx->pcb->hidlib, "netlist", "unselect", name, NULL); + else if (w == ctx->wfind) { + rnd_actionva(&ctx->pcb->hidlib, "connection", "reset", NULL); + rnd_actionva(&ctx->pcb->hidlib, "netlist", "find", name, NULL); + } + else if (w == ctx->wunfind) + rnd_actionva(&ctx->pcb->hidlib, "connection", "reset", NULL); + else if (w == ctx->wrats) + rnd_actionva(&ctx->pcb->hidlib, "netlist", "rats", name, NULL); + else if (w == ctx->wnorats) + rnd_actionva(&ctx->pcb->hidlib, "netlist", "norats", name, NULL); + else if (w == ctx->wripup) + rnd_actionva(&ctx->pcb->hidlib, "netlist", "ripup", name, NULL); + else if (w == ctx->waddrats) + rnd_actionva(&ctx->pcb->hidlib, "netlist", "AddRats", name, NULL); + else if (w == ctx->wrename) + rnd_actionva(&ctx->pcb->hidlib, "netlist", "rename", name, NULL); + else if (w == ctx->wmerge) + rnd_actionva(&ctx->pcb->hidlib, "netlist", "merge", name, NULL); + else if (w == ctx->wattr) { + char *tmp = rnd_concat("net:", name, NULL); + rnd_actionva(&ctx->pcb->hidlib, "propedit", tmp, NULL); + free(tmp); + } + else if (w == ctx->wnlcalc) + netlist_update_len_by_row(ctx, r); + else if (w == ctx->wnlon) + rnd_actionva(&ctx->pcb->hidlib, "netlist", "autolen", name, NULL); + else if (w == ctx->wnloff) + rnd_actionva(&ctx->pcb->hidlib, "netlist", "noautolen", name, NULL); + else { + rnd_message(RND_MSG_ERROR, "Internal error: netlist_button_cb() called from an invalid widget\n"); + return; + } + rnd_gui->invalidate_all(rnd_gui); +} + +static void netlist_claim_obj_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + netlist_ctx_t *ctx = caller_data; + rnd_actionva(&ctx->pcb->hidlib, "ClaimNet", "object", NULL); +} + +static void netlist_claim_sel_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + netlist_ctx_t *ctx = caller_data; + rnd_actionva(&ctx->pcb->hidlib, "ClaimNet", "selected", NULL); +} + +static void netlist_claim_fnd_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + netlist_ctx_t *ctx = caller_data; + rnd_actionva(&ctx->pcb->hidlib, "ClaimNet", "found", NULL); +} + +static void netlist_len_refresh(netlist_ctx_t *ctx) +{ + rnd_hid_attribute_t *atree = &ctx->dlg[ctx->wnetlist]; + rnd_hid_tree_t *tree = atree->wdata; + htsp_entry_t *e; + long cnt = 0; + + for(e = htsp_first(&tree->paths); e != NULL; e = htsp_next(&tree->paths, e)) { + rnd_hid_row_t *row = e->value; + if (row->cell[2][0] == '*') { + netlist_update_len_by_row(ctx, row); + cnt++; + } + } + + if (cnt == 0) + rnd_message(RND_MSG_ERROR, "You need to enable auto-len on at least one network first\n"); +} + +static void netlist_len_refresh_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + netlist_len_refresh((netlist_ctx_t *)caller_data); +} + + +static vtp0_t netlist_color_save; + +static void netlist_expose(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + netlist_ctx_t *ctx = prv->user_ctx; + rnd_xform_t xform; + size_t n; + void **p; + rnd_hid_attribute_t *attr; + rnd_hid_row_t *r; + pcb_net_t *net = NULL; + + attr = &ctx->dlg[ctx->wnetlist]; + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + net = pcb_net_get(ctx->pcb, &ctx->pcb->netlist[PCB_NETLIST_EDITED], r->cell[0], 0); + + if (net != NULL) { /* save term object colors */ + pcb_net_term_t *t; + vtp0_truncate(&netlist_color_save, 0); + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) { + pcb_any_obj_t *obj = pcb_term_find_name(ctx->pcb, ctx->pcb->Data, PCB_LYT_COPPER, t->refdes, t->term, NULL, NULL); + if (obj == NULL) + continue; + + vtp0_append(&netlist_color_save, obj); + if (obj->override_color != NULL) + vtp0_append(&netlist_color_save, (char *)obj->override_color); + else + vtp0_append(&netlist_color_save, NULL); + obj->override_color = rnd_color_magenta; + } + } + + /* draw the board */ + memset(&xform, 0, sizeof(xform)); + xform.layer_faded = 1; + rnd_expose_main(rnd_gui, e, &xform); + + if (net != NULL) {/* restore object color */ + for(n = 0, p = netlist_color_save.array; n < netlist_color_save.used; n+=2,p+=2) { + pcb_any_obj_t *obj = p[0]; + rnd_color_t *s = p[1]; + obj->override_color = s; + } + vtp0_truncate(&netlist_color_save, 0); + } +} + +static rnd_bool netlist_mouse(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + return rnd_false; +} + +static void pcb_dlg_netlist(pcb_board_t *pcb) +{ + static const char *hdr[] = {"network", "!rat", "len", "network length", NULL}; + static const char *hdr2[] = {"terminals", NULL}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + int whpan, wvpan; + + if (netlist_ctx.active) + return; /* do not open another */ + + netlist_ctx.bb_prv.X1 = 0; + netlist_ctx.bb_prv.Y1 = 0; + netlist_ctx.bb_prv.X2 = pcb->hidlib.size_x; + netlist_ctx.bb_prv.Y2 = pcb->hidlib.size_y; + netlist_ctx.pcb = pcb; + + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); /* layout */ + RND_DAD_COMPFLAG(netlist_ctx.dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_HPANE(netlist_ctx.dlg); + RND_DAD_COMPFLAG(netlist_ctx.dlg, RND_HATF_EXPFILL); + whpan = RND_DAD_CURRENT(netlist_ctx.dlg); + + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); /* left */ + RND_DAD_COMPFLAG(netlist_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(netlist_ctx.dlg, 4, 0, hdr); + RND_DAD_COMPFLAG(netlist_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + netlist_ctx.wnetlist = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_TREE_SET_CB(netlist_ctx.dlg, selected_cb, netlist_row_selected); + RND_DAD_TREE_SET_CB(netlist_ctx.dlg, ctx, &netlist_ctx); + RND_DAD_END(netlist_ctx.dlg); + + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); /* right */ + RND_DAD_COMPFLAG(netlist_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VPANE(netlist_ctx.dlg); + RND_DAD_COMPFLAG(netlist_ctx.dlg, RND_HATF_EXPFILL); + wvpan = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); /* right-top */ + RND_DAD_COMPFLAG(netlist_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_PREVIEW(netlist_ctx.dlg, netlist_expose, netlist_mouse, NULL, NULL, &netlist_ctx.bb_prv, 100, 100, &netlist_ctx); + RND_DAD_COMPFLAG(netlist_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_PRV_BOARD); + netlist_ctx.wprev = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); /* right-bottom */ + RND_DAD_COMPFLAG(netlist_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(netlist_ctx.dlg, 1, 0, hdr2); + RND_DAD_COMPFLAG(netlist_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + netlist_ctx.wtermlist = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_TREE_SET_CB(netlist_ctx.dlg, selected_cb, termlist_row_selected); + RND_DAD_TREE_SET_CB(netlist_ctx.dlg, ctx, &netlist_ctx); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_END(netlist_ctx.dlg); + + RND_DAD_BEGIN_HBOX(netlist_ctx.dlg); /* bottom button row */ + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); + RND_DAD_BUTTON(netlist_ctx.dlg, "select"); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + RND_DAD_HELP(netlist_ctx.dlg, "select all objects on the selected network"); + netlist_ctx.wsel = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_BUTTON(netlist_ctx.dlg, "unsel."); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + netlist_ctx.wunsel = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_HELP(netlist_ctx.dlg, "unselect all objects on the selected network"); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); + RND_DAD_BUTTON(netlist_ctx.dlg, "find "); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + netlist_ctx.wfind = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_HELP(netlist_ctx.dlg, "find-mark (green) all object on the selected network"); + RND_DAD_BUTTON(netlist_ctx.dlg, "clear"); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + netlist_ctx.wunfind = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_HELP(netlist_ctx.dlg, "remove find-mark (green) from all object on the selected network"); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); + RND_DAD_BUTTON(netlist_ctx.dlg, "rat disable"); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + netlist_ctx.wnorats = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_HELP(netlist_ctx.dlg, "disable adding rats for missing connection for the selected network"); + RND_DAD_BUTTON(netlist_ctx.dlg, "rat enable"); + netlist_ctx.wrats = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + RND_DAD_HELP(netlist_ctx.dlg, "re-enable adding rats for missing connection for the selected network"); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); + RND_DAD_BUTTON(netlist_ctx.dlg, "all disable"); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + netlist_ctx.wnoallrats = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_HELP(netlist_ctx.dlg, "disable adding rats for missing connection for all networks"); + RND_DAD_BUTTON(netlist_ctx.dlg, "all enable"); + netlist_ctx.wallrats = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + RND_DAD_HELP(netlist_ctx.dlg, "re-enable adding rats for missing connection for all networks"); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); + RND_DAD_BUTTON(netlist_ctx.dlg, "add rats"); + netlist_ctx.waddrats = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + RND_DAD_HELP(netlist_ctx.dlg, "add rats for missing connections within the selected network"); + RND_DAD_BUTTON(netlist_ctx.dlg, "rip up "); + netlist_ctx.wripup = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + RND_DAD_HELP(netlist_ctx.dlg, "remove all objects (except for terminals) on the selected network"); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); + RND_DAD_BUTTON(netlist_ctx.dlg, "rename"); + netlist_ctx.wrename = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + RND_DAD_HELP(netlist_ctx.dlg, "change the name of the selected network"); + RND_DAD_BEGIN_HBOX(netlist_ctx.dlg); + RND_DAD_BUTTON(netlist_ctx.dlg, "merge"); + netlist_ctx.wmerge = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + RND_DAD_HELP(netlist_ctx.dlg, "merge the selected network into another network"); + RND_DAD_BUTTON(netlist_ctx.dlg, "attr"); + netlist_ctx.wattr = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + RND_DAD_HELP(netlist_ctx.dlg, "change attributes of the selected network"); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_END(netlist_ctx.dlg); + + RND_DAD_BEGIN_HBOX(netlist_ctx.dlg); /* bottom button row */ + RND_DAD_LABEL(netlist_ctx.dlg, "Claim:"); + RND_DAD_HELP(netlist_ctx.dlg, "Map galvanic connection of existing objects and convert them into a network on the netlist"); + RND_DAD_BUTTON(netlist_ctx.dlg, "click"); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_claim_obj_cb); + RND_DAD_HELP(netlist_ctx.dlg, "Click on an object to create a new network of all connected objects from there"); + RND_DAD_BUTTON(netlist_ctx.dlg, "select"); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_claim_sel_cb); + RND_DAD_HELP(netlist_ctx.dlg, "create a new network of all selected objects"); + RND_DAD_BUTTON(netlist_ctx.dlg, "found"); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_claim_fnd_cb); + RND_DAD_HELP(netlist_ctx.dlg, "create a new network of all found (green) objects"); + + RND_DAD_LABEL(netlist_ctx.dlg, "Len:"); + RND_DAD_BUTTON(netlist_ctx.dlg, "calc"); + netlist_ctx.wnlcalc = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + RND_DAD_HELP(netlist_ctx.dlg, "Calculate the length of the selected network immediately"); + RND_DAD_BUTTON(netlist_ctx.dlg, "on"); + netlist_ctx.wnlon = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + RND_DAD_HELP(netlist_ctx.dlg, "Turn on auto-recaculate net length on refresh for the selected network"); + RND_DAD_BUTTON(netlist_ctx.dlg, "off"); + netlist_ctx.wnloff = RND_DAD_CURRENT(netlist_ctx.dlg); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_button_cb); + RND_DAD_HELP(netlist_ctx.dlg, "Turn off auto-recaculate net length on refresh for the selected network"); + RND_DAD_BUTTON(netlist_ctx.dlg, "refresh"); + RND_DAD_CHANGE_CB(netlist_ctx.dlg, netlist_len_refresh_cb); + RND_DAD_HELP(netlist_ctx.dlg, "Re-calculate the length of all networks marked for auto-recalculate"); + + RND_DAD_BEGIN_VBOX(netlist_ctx.dlg); /* fill between buttons and close */ + RND_DAD_COMPFLAG(netlist_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_END(netlist_ctx.dlg); + + RND_DAD_BUTTON_CLOSES(netlist_ctx.dlg, clbtn); + RND_DAD_END(netlist_ctx.dlg); + RND_DAD_END(netlist_ctx.dlg); + + /* set up the context */ + netlist_ctx.active = 1; + + RND_DAD_DEFSIZE(netlist_ctx.dlg, 300, 350); + RND_DAD_NEW("netlist", netlist_ctx.dlg, "pcb-rnd netlist", &netlist_ctx, rnd_false, netlist_close_cb); + + { + rnd_hid_attr_val_t hv; + hv.dbl = 0.60; + rnd_gui->attr_dlg_set_value(netlist_ctx.dlg_hid_ctx, whpan, &hv); + hv.dbl = 0.33; + rnd_gui->attr_dlg_set_value(netlist_ctx.dlg_hid_ctx, wvpan, &hv); + } + + netlist_data2dlg(&netlist_ctx); +} + +static const char pcb_acts_NetlistDialog[] = "NetlistDialog([RefreshNetLens])\n"; +static const char pcb_acth_NetlistDialog[] = "Open the netlist dialog or refresh network lengths in an already open dialog."; +static fgw_error_t pcb_act_NetlistDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd = NULL; + RND_ACT_MAY_CONVARG(1, FGW_STR, NetlistDialog, cmd = argv[1].val.str); + + if (cmd != NULL) { + RND_ACT_IRES(0); + if (rnd_strcasecmp(cmd, "RefreshNetLens") == 0) { + if (!netlist_ctx.active) + return 0; + netlist_len_refresh(&netlist_ctx); + } + + RND_ACT_IRES(-1); + return 0; + } + + pcb_dlg_netlist(PCB); + RND_ACT_IRES(0); + return 0; +} + +/* update the dialog after a netlist change */ +static void pcb_dlg_netlist_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + netlist_ctx_t *ctx = user_data; + if (!ctx->active) + return; + netlist_data2dlg(ctx); +} +static void pcb_dlg_netlist_init(void) +{ + rnd_event_bind(PCB_EVENT_NETLIST_CHANGED, pcb_dlg_netlist_ev, &netlist_ctx, dlg_netlist_cookie); +} + +static void pcb_dlg_netlist_uninit(void) +{ + rnd_event_unbind_allcookie(dlg_netlist_cookie); + vtp0_uninit(&netlist_color_save); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_obj_list.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_obj_list.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_obj_list.c (revision 33253) @@ -0,0 +1,99 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +extern vtp0_t pcb_obj_list_vect; + +static long result_idx; +RND_DAD_DECL_NOINIT(dlg) + + +static void view_expose_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + rnd_xform_t xform; + rnd_color_t *saved_color; + long oidx = (pcb_any_obj_t **)prv->user_ctx - (pcb_any_obj_t **)pcb_obj_list_vect.array; + pcb_any_obj_t *obj = pcb_obj_list_vect.array[oidx]; + + rnd_dad_preview_zoomto(attrib, &obj->BoundingBox); + + /* save object color and make it red */ + saved_color = obj->override_color; + obj->override_color = (rnd_color_t *)rnd_color_red; + + /* draw the board */ + memset(&xform, 0, sizeof(xform)); + xform.layer_faded = 1; + rnd_expose_main(rnd_gui, e, &xform); + + /* restore object color */ + obj->override_color = saved_color; +} + + +static rnd_bool view_mouse_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + if (kind == RND_HID_MOUSE_PRESS) { + result_idx = (pcb_any_obj_t **)prv->user_ctx - (pcb_any_obj_t **)pcb_obj_list_vect.array; + RND_DAD_FREE(dlg); + } + return rnd_false; /* don't redraw */ +} + + +static const char pcb_acts_dlg_obj_list[] = "dlg_obj_list()"; +static const char pcb_acth_dlg_obj_list[] = "Let the user select an object from a list of objects"; +static fgw_error_t pcb_act_dlg_obj_list(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {NULL, 0}}; + long n; + + if (pcb_obj_list_vect.used == 0) { + RND_ACT_IRES(-1); + return 0; + } + + result_idx = -1; + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(dlg, "There are multiple objects at this location."); + RND_DAD_LABEL(dlg, "Please pick one of them:"); + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + for(n = 0; n < pcb_obj_list_vect.used; n++) { + RND_DAD_PREVIEW(dlg, view_expose_cb, view_mouse_cb, NULL, NULL, NULL, 100, 100, &pcb_obj_list_vect.array[n]); + } + RND_DAD_END(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + RND_DAD_DEFSIZE(dlg, 150, 350); + RND_DAD_NEW("obj_list", dlg, "pick one from available objects", NULL, rnd_true, NULL); + RND_DAD_RUN(dlg); + RND_DAD_FREE(dlg); + + RND_ACT_IRES(result_idx); + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_padstack.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_padstack.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_padstack.c (revision 33253) @@ -0,0 +1,1139 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include +#include "funchash_core.h" +#include "obj_pstk.h" +#include "obj_pstk_op.h" +#include "obj_pstk_inlines.h" +#include "obj_subc_parent.h" +#include "search.h" +#include "operation.h" +#include "undo.h" +#include "dlg_lib_pstk.h" +#include "dlg_padstack.h" + +static const char *shapes[] = { "circle", "square", NULL }; +static const char *sides[] = { "all (top, bottom, intern)", "top & bottom only", "top only", "bottom only", "none", NULL }; +static pcb_layer_type_t sides_lyt[] = { PCB_LYT_TOP | PCB_LYT_BOTTOM | PCB_LYT_INTERN, PCB_LYT_TOP | PCB_LYT_BOTTOM, PCB_LYT_TOP, PCB_LYT_BOTTOM, 0 }; +static const char *thermal_type[] = {"no thermal", "round", "sharp", "diagonal round", "diagonal sharp", "solid connection", "no shape", NULL}; +static pcb_thermal_t thermal_bit[] = {0, PCB_THERMAL_ON|PCB_THERMAL_ROUND, PCB_THERMAL_ON|PCB_THERMAL_SHARP, PCB_THERMAL_ON|PCB_THERMAL_ROUND|PCB_THERMAL_DIAGONAL, PCB_THERMAL_ON|PCB_THERMAL_SHARP|PCB_THERMAL_DIAGONAL, PCB_THERMAL_ON|PCB_THERMAL_SOLID, PCB_THERMAL_ON|PCB_THERMAL_NOSHAPE}; + +/* build a group/layer name string in tmp */ +char *pse_group_string(pcb_board_t *pcb, pcb_layergrp_t *grp, char *out, int size) +{ + const char *lname = "", *gname = ""; + + if (grp != NULL) { + gname = grp->name; + if (grp->len > 0) { + pcb_layer_t *l = pcb_get_layer(pcb->Data, grp->lid[0]); + if (l != NULL) + lname = l->name; + } + } + + rnd_snprintf(out, size, "%s\n[%s]", gname, lname); + return out; +} + +/* Convert from padstack to dialog */ +static void pse_ps2dlg(void *hid_ctx, pse_t *pse) +{ + char tmp[256], *s; + const char *prn = ""; + int n, i; + pcb_pstk_proto_t *proto; + rnd_layergrp_id_t top_gid, bottom_gid; + pcb_layergrp_t *top_grp, *bottom_grp; + pcb_bb_type_t htype; + char shp_found[32]; + pcb_pstk_tshape_t *ts = pcb_pstk_get_untshape(pse->ps); + + if (ts == NULL) + return; + + rnd_gui->attr_dlg_widget_hide(hid_ctx, pse->prsmirror, !pse->ps->smirror); + + htype = pcb_pstk_bbspan(pse->pcb, pse->ps, &top_gid, &bottom_gid, &proto); + top_grp = pcb_get_layergrp(pse->pcb, top_gid); + bottom_grp = pcb_get_layergrp(pse->pcb, bottom_gid); + + /* instance - main */ + if ((proto != NULL) && (proto->name != NULL)) + prn = proto->name; + rnd_snprintf(tmp, sizeof(tmp), "#%ld:%d (%s)", (long int)pse->ps->proto, pse->ps->protoi, prn); + RND_DAD_SET_VALUE(hid_ctx, pse->proto_id, str, tmp); + RND_DAD_SET_VALUE(hid_ctx, pse->clearance, crd, pse->ps->Clearance); + RND_DAD_SET_VALUE(hid_ctx, pse->rot, dbl, pse->ps->rot); + RND_DAD_SET_VALUE(hid_ctx, pse->xmirror, lng, pse->ps->xmirror); + RND_DAD_SET_VALUE(hid_ctx, pse->smirror, lng, pse->ps->smirror); + + /* instance - thermals */ + for(n = 0; n < pse->thermal.len; n++) { + rnd_layer_id_t lid = pse->thermal.lid[n]; + int th = lid < pse->ps->thermals.used ? pse->ps->thermals.shape[lid] : 0; + for(i = 0; i < sizeof(thermal_bit) / sizeof(thermal_bit[0]); i++) { + if (thermal_bit[i] == th) { + RND_DAD_SET_VALUE(hid_ctx, pse->thermal.wtype[n], lng, i); + break; + } + } + } + + /* proto - layers */ + memset(shp_found, 0, sizeof(shp_found)); + for(n = 0; n < pcb_proto_num_layers; n++) { + pcb_pstk_shape_t *shape = pcb_pstk_shape_notransform(pse->ps, pcb_proto_layers[n].mask, pcb_proto_layers[n].comb); + + if (shape != NULL) { + int shape_idx = shape - ts->shape; + if ((shape_idx >= 0) && (shape_idx < sizeof(shp_found))) + shp_found[shape_idx] = 1; + switch(shape->shape) { + case PCB_PSSH_HSHADOW: + *tmp = '\0'; + RND_DAD_SET_VALUE(hid_ctx, pse->proto_shape[n], str, "hshadow"); + break; + case PCB_PSSH_CIRC: + RND_DAD_SET_VALUE(hid_ctx, pse->proto_shape[n], str, "circle"); + if ((shape->data.circ.x != 0) || (shape->data.circ.y != 0)) + rnd_snprintf(tmp, sizeof(tmp), "%m+dia=%.06$mS\nat %.06$mS;%.06$mS", rnd_conf.editor.grid_unit->allow, shape->data.circ.dia, shape->data.circ.x, shape->data.circ.y); + else + rnd_snprintf(tmp, sizeof(tmp), "%m+dia=%.06$mS", rnd_conf.editor.grid_unit->allow, shape->data.circ.dia); + break; + case PCB_PSSH_LINE: + if (shape->data.line.square) + RND_DAD_SET_VALUE(hid_ctx, pse->proto_shape[n], str, "square line"); + else + RND_DAD_SET_VALUE(hid_ctx, pse->proto_shape[n], str, "round line"); + rnd_snprintf(tmp, sizeof(tmp), "%m+thickness=%.06$mS", rnd_conf.editor.grid_unit->allow, shape->data.line.thickness); + break; + case PCB_PSSH_POLY: + RND_DAD_SET_VALUE(hid_ctx, pse->proto_shape[n], str, "polygon"); + rnd_snprintf(tmp, sizeof(tmp), "corners=%d", shape->data.poly.len); + break; + default: + RND_DAD_SET_VALUE(hid_ctx, pse->proto_shape[n], str, ""); + strcpy(tmp, ""); + } + RND_DAD_SET_VALUE(hid_ctx, pse->proto_info[n], str, tmp); + RND_DAD_SET_VALUE(hid_ctx, pse->proto_clr[n], crd, shape->clearance); + } + else { + RND_DAD_SET_VALUE(hid_ctx, pse->proto_shape[n], str, ""); + RND_DAD_SET_VALUE(hid_ctx, pse->proto_info[n], str, ""); + RND_DAD_SET_VALUE(hid_ctx, pse->proto_clr[n], crd, 0); + } + } + + { + int not_found = 0; + for(n = 0; n < MIN((int)ts->len, (int)sizeof(shp_found)); n++) + if (shp_found[n] == 0) + not_found++; + if (not_found) + rnd_message(RND_MSG_ERROR, "This padstack has %d shape(s) that are not listed in the padstack editor\nFor editing all shapes, please break the padstack up\n", not_found); + } + + /* proto - hole */ + if (proto->mech_idx >= 0) { + s = "Slot geometry ():"; + switch(htype) { + case PCB_BB_NONE: s = "Slot geometry (there is no slot in this padstack):"; break; + case PCB_BB_THRU: s = "Slot geometry (all-way-through slot):"; break; + case PCB_BB_BB: s = "Slot geometry (blind and/or buried slot):"; break; + case PCB_BB_INVALID: s = "Slot geometry (INVALID SLOT):"; break; + } + rnd_gui->attr_dlg_widget_state(hid_ctx, pse->hdia, 0); + } + else { + s = "Hole geometry ():"; + switch(htype) { + case PCB_BB_NONE: s = "Hole geometry (there is no hole in this padstack):"; break; + case PCB_BB_THRU: s = "Hole geometry (all-way-through hole):"; break; + case PCB_BB_BB: s = "Hole geometry (blind and/or buried hole):"; break; + case PCB_BB_INVALID: s = "Hole geometry (INVALID HOLE):"; break; + } + rnd_gui->attr_dlg_widget_state(hid_ctx, pse->hdia, 1); + } + RND_DAD_SET_VALUE(hid_ctx, pse->hole_header, str, s); + + free((char *)pse->attrs[pse->prname].val.str); + pse->attrs[pse->prname].val.str = NULL; + RND_DAD_SET_VALUE(hid_ctx, pse->prname, str, rnd_strdup(proto->name == NULL ? "" : proto->name)); + RND_DAD_SET_VALUE(hid_ctx, pse->hdia, crd, proto->hdia); + RND_DAD_SET_VALUE(hid_ctx, pse->hplated, lng, proto->hplated); + RND_DAD_SET_VALUE(hid_ctx, pse->htop_val, lng, proto->htop); + RND_DAD_SET_VALUE(hid_ctx, pse->hbot_val, lng, proto->hbottom); + + if (proto->htop == 0) + strcpy(tmp, "top copper group"); + else + sprintf(tmp, "%d groups from\nthe %s copper group", proto->htop, proto->htop > 0 ? "top" : "bottom"); + RND_DAD_SET_VALUE(hid_ctx, pse->htop_text, str, tmp); + RND_DAD_SET_VALUE(hid_ctx, pse->htop_layer, str, pse_group_string(pse->pcb, top_grp, tmp, sizeof(tmp))); + + if (proto->hbottom == 0) + strcpy(tmp, "bottom copper group"); + else + sprintf(tmp, "%d groups from\nthe %s copper group", proto->hbottom, proto->hbottom > 0 ? "bottom" : "top"); + RND_DAD_SET_VALUE(hid_ctx, pse->hbot_text, str, tmp); + RND_DAD_SET_VALUE(hid_ctx, pse->hbot_layer, str, pse_group_string(pse->pcb, bottom_grp, tmp, sizeof(tmp))); + +} + +static void pse_changed(pse_t *pse) +{ + pcb_data_t *pdt; + + if (pse->change_cb != NULL) + pse->change_cb(pse); + + /* if the padstack is within a subc, parent subc bbox needs to be recalculated because any pstk geometry change may have changed that too */ + assert(pse->ps->parent_type == PCB_PARENT_DATA); + pdt = pse->ps->parent.data; + if (pdt->parent_type == PCB_PARENT_SUBC) + pcb_subc_bbox(pdt->parent.subc); + + if (pcb_data_get_top(pse->data) != NULL) + pcb_board_set_changed_flag(PCB, 1); +} + +static void pse_chg_protoid(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + rnd_cardinal_t proto_id; + pcb_subc_t *subc; + static int lock = 0; + + if (lock != 0) + return; + + subc = pcb_obj_parent_subc((pcb_any_obj_t *)pse->ps); + proto_id = pcb_dlg_pstklib(pse->pcb, (subc == NULL ? 0 : subc->ID), rnd_true, "Select a new prototype to be used on the padstack"); + if (proto_id == PCB_PADSTACK_INVALID) + return; + + pcb_pstk_change_instance(pse->ps, &proto_id, NULL, NULL, NULL, NULL); + + lock++; + pse_ps2dlg(hid_ctx, pse); /* to get the button text updated with proto name */ + lock--; + + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pse_chg_protodup(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + rnd_cardinal_t proto_id; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(pse->ps); + + assert(pse->ps->parent_type == PCB_PARENT_DATA); + if (proto == NULL) { + rnd_message(RND_MSG_ERROR, "Internal error: can't determine prototype\n"); + return; + } + proto_id = pcb_pstk_proto_insert_forcedup(pse->ps->parent.data, proto, 0, pcb_data_get_top(pse->ps->parent.data) == pse->pcb); + pcb_pstk_change_instance(pse->ps, &proto_id, NULL, NULL, NULL, NULL); + pse_ps2dlg(hid_ctx, pse); + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pse_chg_instance(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + static int lock = 0; + int xm, sm; + + if (lock != 0) + return; + + xm = pse->attrs[pse->xmirror].val.lng; + sm = pse->attrs[pse->smirror].val.lng; + pcb_pstk_change_instance(pse->ps, + NULL, + &pse->attrs[pse->clearance].val.crd, + &pse->attrs[pse->rot].val.dbl, + &xm, &sm); + pse->attrs[pse->xmirror].val.lng = xm; + pse->attrs[pse->smirror].val.lng = sm; + + lock++; + pse_ps2dlg(hid_ctx, pse); /* to get calculated text fields updated */ + lock--; + + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pse_chg_thermal(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + int thi, wid = attr - pse->attrs; + + for(thi = 0; thi < pse->thermal.len; thi++) { + if (pse->thermal.wtype[thi] == wid) { + pcb_pstk_set_thermal(pse->ps, pse->thermal.lid[thi], thermal_bit[attr->val.lng], 1); + pcb_undo_inc_serial(); + rnd_gui->invalidate_all(rnd_gui); + return; + } + } + + rnd_message(RND_MSG_ERROR, "pse_chg_thermal(): internal error: invalid widget\n"); +} + +static void pse_chg_prname(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(pse->ps); + static int lock = 0; + const char *new_name = pse->attrs[pse->prname].val.str; + + if ((lock != 0) || (proto == NULL)) + return; + + if (proto->name == NULL) { + if ((new_name == NULL) || (*new_name == '\0')) + return; + } + else { + if (strcmp(proto->name, new_name) == 0) + return; + } + + pcb_pstk_proto_change_name(proto, new_name, 1); + + lock++; + pse_ps2dlg(hid_ctx, pse); /* to get calculated text fields updated */ + lock--; + + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pse_chg_hole(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(pse->ps); + static int lock = 0; + + if (lock != 0) + return; + + if (proto != NULL) { + int hp = pse->attrs[pse->hplated].val.lng, ht = pse->attrs[pse->htop_val].val.lng, hb = pse->attrs[pse->hbot_val].val.lng; + pcb_pstk_proto_change_hole(proto, &hp, &pse->attrs[pse->hdia].val.crd, &ht, &hb); + pse->attrs[pse->hplated].val.lng = hp; + pse->attrs[pse->htop_val].val.lng = ht; + pse->attrs[pse->hbot_val].val.lng = hb; + + /* make sure the hash and other caches are updated */ + pcb_pstk_proto_update(proto); + } + + lock++; + pse_ps2dlg(hid_ctx, pse); /* to get calculated text fields updated */ + lock--; + + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pse_chg_proto_clr(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(pse->ps); + static int lock = 0; + + if (lock != 0) + return; + + if (proto != NULL) { + int n, idx = -1, sidx; + pcb_opctx_t ctx; + + for(n = 0; n < pcb_proto_num_layers; n++) + if (pse->proto_clr[n] == (attr - pse->attrs)) + idx = n; + if (idx < 0) { + rnd_message(RND_MSG_ERROR, "Can't find shape - clearance unchanged (a)\n"); + return; + } + + sidx = pcb_pstk_get_shape_idx(&proto->tr.array[0], pcb_proto_layers[idx].mask, pcb_proto_layers[idx].comb); + if (sidx < 0) { + rnd_message(RND_MSG_ERROR, "Can't find shape - clearance unchanged (b)\n"); + return; + } + + + pcb_undo_freeze_serial(); + + ctx.clip.clear = 0; + ctx.clip.restore = 1; + pcb_pstkop_clip(&ctx, pse->ps); + + for(n = 0; n < proto->tr.used; n++) + pcb_pstk_shape_clr_grow(proto, n, sidx, rnd_true, pse->attrs[pse->proto_clr[idx]].val.crd, 1); + + ctx.clip.clear = 1; + ctx.clip.restore = 0; + pcb_pstkop_clip(&ctx, pse->ps); + + /* make sure the hash and other caches are updated */ + pcb_pstk_proto_update(proto); + + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + } + + lock++; + pse_ps2dlg(hid_ctx, pse); /* to get calculated text fields updated */ + lock--; + + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pse_shape_del(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(pse->ps); + pcb_pstk_proto_del_shape(proto, pcb_proto_layers[pse->editing_shape].mask, pcb_proto_layers[pse->editing_shape].comb); + + pse_ps2dlg(pse->parent_hid_ctx, pse); + + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pse_shape_hshadow(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(pse->ps); + pcb_pstk_proto_del_shape(proto, pcb_proto_layers[pse->editing_shape].mask, pcb_proto_layers[pse->editing_shape].comb); + pcb_pstk_shape_add_hshadow(proto, pcb_proto_layers[pse->editing_shape].mask, pcb_proto_layers[pse->editing_shape].comb); + pse_ps2dlg(pse->parent_hid_ctx, pse); + + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pse_shape_auto(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int n, src_idx = -1; + pse_t *pse = caller_data; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(pse->ps); + pcb_pstk_tshape_t *ts = &proto->tr.array[0]; + int dst_idx; + char src_shape_names[128]; + char *end = src_shape_names; + + + if (ts == NULL) { + rnd_message(RND_MSG_ERROR, "Can't derive shape: no shapes (empty padstack)\n"); + return; + } + + dst_idx = pcb_pstk_get_shape_idx(ts, pcb_proto_layers[pse->editing_shape].mask, pcb_proto_layers[pse->editing_shape].comb); + + for(n = 0; n < 2; n++) { + int from = pcb_proto_layers[pse->editing_shape].auto_from[n]; + if (from < 0) + continue; + src_idx = pcb_pstk_get_shape_idx(ts, pcb_proto_layers[from].mask, pcb_proto_layers[from].comb); + if (src_idx >= 0) + break; + strcpy(end, pcb_proto_layers[from].name); + end += strlen(pcb_proto_layers[from].name); + *end = ','; + end++; + } + + if (src_idx < 0) { + if (end > src_shape_names) + end--; + *end = 0; + rnd_message(RND_MSG_ERROR, "Can't derive shape: source shapes (%s) are empty\n", src_shape_names); + return; + } + + pcb_pstk_shape_derive(proto, dst_idx, src_idx, pcb_proto_layers[pse->editing_shape].auto_bloat, pcb_proto_layers[pse->editing_shape].mask, pcb_proto_layers[pse->editing_shape].comb); + + pse_ps2dlg(pse->parent_hid_ctx, pse); + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pse_shape_copy(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(pse->ps); + pcb_pstk_tshape_t *ts = &proto->tr.array[0]; + int from = pse->shape_chg[pse->copy_from].val.lng; + int dst_idx; + int src_idx; + + if (ts == NULL) { + rnd_message(RND_MSG_ERROR, "Can't copy shape: no such source shape (empty padstack)\n"); + return; + } + + dst_idx = pcb_pstk_get_shape_idx(ts, pcb_proto_layers[pse->editing_shape].mask, pcb_proto_layers[pse->editing_shape].comb); + src_idx = pcb_pstk_get_shape_idx(ts, pcb_proto_layers[from].mask, pcb_proto_layers[from].comb); + + if (src_idx < 0) { + rnd_message(RND_MSG_ERROR, "Can't copy shape: source shape (%s) is empty\n", pcb_proto_layers[from].name); + return; + } + + if (src_idx == dst_idx) { + rnd_message(RND_MSG_ERROR, "Can't copy shape: source shape and destination shape are the same layer type\n"); + return; + } + + pcb_pstk_shape_derive(proto, dst_idx, src_idx, 0, pcb_proto_layers[pse->editing_shape].mask, pcb_proto_layers[pse->editing_shape].comb); + + pse_ps2dlg(pse->parent_hid_ctx, pse); + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pse_shape_swap(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(pse->ps); + pcb_pstk_tshape_t *ts = &proto->tr.array[0]; + int from = pse->shape_chg[pse->copy_from].val.lng; + int dst_idx; + int src_idx; + + if (ts == NULL) { + rnd_message(RND_MSG_ERROR, "Can't swap shape: no such shapes (empty padstack)\n"); + return; + } + + dst_idx = pcb_pstk_get_shape_idx(ts, pcb_proto_layers[pse->editing_shape].mask, pcb_proto_layers[pse->editing_shape].comb); + src_idx = pcb_pstk_get_shape_idx(ts, pcb_proto_layers[from].mask, pcb_proto_layers[from].comb); + + if (src_idx < 0) { + rnd_message(RND_MSG_ERROR, "Can't swap shape: source shape (%s) is empty\n", pcb_proto_layers[from].name); + return; + } + + if (src_idx == dst_idx) { + rnd_message(RND_MSG_ERROR, "Can't swap shape: source shape and destination shape are the same layer type\n"); + return; + } + + pcb_pstk_shape_swap_layer(proto, dst_idx, src_idx); + + pse_ps2dlg(pse->parent_hid_ctx, pse); + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + + +static void pse_shape_bloat(void *hid_ctx, void *caller_data, rnd_coord_t sign) +{ + pse_t *pse = caller_data; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(pse->ps); + pcb_pstk_tshape_t *ts = &proto->tr.array[0]; + int n, dst_idx = pcb_pstk_get_shape_idx(ts, pcb_proto_layers[pse->editing_shape].mask, pcb_proto_layers[pse->editing_shape].comb); + rnd_coord_t bloat = pse->shape_chg[pse->amount].val.crd; + + if (bloat <= 0) + return; + + if (dst_idx < 0) { + rnd_message(RND_MSG_ERROR, "Can't copy shape: source shape (%s) is empty\n", pcb_proto_layers[pse->editing_shape].name); + return; + } + + pcb_undo_freeze_serial(); + + if (sign == 0) { + for(n = 0; n < proto->tr.used; n++) + pcb_pstk_shape_grow(proto, n, dst_idx, rnd_true, bloat, 1); + } + else { + bloat *= sign; + for(n = 0; n < proto->tr.used; n++) + pcb_pstk_shape_grow(proto, n, dst_idx, rnd_false, bloat, 1); + } + + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + pcb_pstk_proto_update(proto); + + pse_ps2dlg(pse->parent_hid_ctx, pse); + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +static void pse_shape_shrink(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_shape_bloat(hid_ctx, caller_data, -1); +} + +static void pse_shape_grow(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_shape_bloat(hid_ctx, caller_data, +1); +} + +static void pse_shape_setsize(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_shape_bloat(hid_ctx, caller_data, 0); +} + +static void pse_chg_shape(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pse_t *pse = caller_data; + int n; + char tmp[256]; + const char *copy_from_names[pcb_proto_num_layers+1]; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + RND_DAD_DECL(dlg); + + pse->parent_hid_ctx = hid_ctx; + + for(n = 0; n < pcb_proto_num_layers; n++) + copy_from_names[n] = pcb_proto_layers[n].name; + copy_from_names[n] = NULL; + + pse->editing_shape = -1; + for(n = 0; n < pcb_proto_num_layers; n++) { + if (pse->proto_change[n] == (attr - pse->attrs)) { + pse->editing_shape = n; + break; + } + } + + RND_DAD_BEGIN_VBOX(dlg); + sprintf(tmp, "Automatically generate shape for ..."); + RND_DAD_LABEL(dlg, tmp); + RND_DAD_LABEL(dlg, ""); + pse->text_shape = RND_DAD_CURRENT(dlg); + RND_DAD_BUTTON(dlg, "Delete (no shape)"); + pse->del = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_shape_del); + RND_DAD_HELP(dlg, "Remove the shape from this layer type"); + RND_DAD_BUTTON(dlg, "Replace shape with hshadow"); + pse->hshadow = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_shape_hshadow); + RND_DAD_HELP(dlg, "Set shape to hshadow on this layer type\n(invisible shape with the same\ngeometry as the hole or slot, for proper clearance)"); + RND_DAD_BUTTON(dlg, "Derive automatically"); + pse->derive = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_shape_auto); + RND_DAD_HELP(dlg, "Derive the shape for this layer type\nfrom other, existing shapes of this padstack\n(automatic)"); + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_BUTTON(dlg, "Copy shape from"); + pse->copy_do = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_shape_copy); + RND_DAD_HELP(dlg, "Copy the shape for this layer type\nfrom other, existing shapes of this padstack\nfrom the layer type selected"); + RND_DAD_BUTTON(dlg, "Swap shape with"); + pse->copy_do = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_shape_swap); + RND_DAD_HELP(dlg, "Swap the shape for this layer type\nwith another, existing shapes of this padstack\nfrom the layer type selected"); + RND_DAD_HELP(dlg, "Select the other layer type for swapping shape"); + RND_DAD_END(dlg); + RND_DAD_ENUM(dlg, copy_from_names); /* coposite */ + pse->copy_from = RND_DAD_CURRENT(dlg); + RND_DAD_HELP(dlg, "Select the source layer type for\nmanual shape copy or shape swap"); + RND_DAD_END(dlg); + + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_BUTTON(dlg, "Shrink"); + pse->shrink = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_shape_shrink); + RND_DAD_HELP(dlg, "Make the shape smaller by the selected amount"); + RND_DAD_COORD(dlg); + pse->amount = RND_DAD_CURRENT(dlg); + RND_DAD_MINMAX(dlg, 1, RND_MM_TO_COORD(100)); + RND_DAD_BUTTON(dlg, "Grow"); + pse->grow = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_shape_grow); + RND_DAD_HELP(dlg, "Make the shape larger by the selected amount"); + RND_DAD_BUTTON(dlg, "Set"); + pse->grow = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_shape_setsize); + RND_DAD_HELP(dlg, "Set shape size to absolute value; this means, per shape:\nline - set thickness\ncircle - set diameter\npolygon - set the biggest edge distance (\"set longer side\")"); + RND_DAD_END(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + RND_DAD_NEW("padstack_shape", dlg, "Edit padstack shape", pse, rnd_true, NULL); + pse->shape_chg = dlg; + +/* pse_ps2dlg(dlg_hid_ctx, pse);*/ + RND_DAD_RUN(dlg); + + pse->shape_chg = NULL; + RND_DAD_FREE(dlg); + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +/* Auto gen shape on a single layer */ +static int pse_gen_shape(pcb_pstk_tshape_t *ts, pcb_layer_type_t lyt, int shape, rnd_coord_t size) +{ + int idx = ts->len; + + if (size <= 0) { + rnd_message(RND_MSG_ERROR, "Invalid size - has to be larger than 0\n"); + return -1; + } + + ts->len++; + ts->shape = realloc(ts->shape, ts->len * sizeof(pcb_pstk_shape_t)); + + ts->shape[idx].layer_mask = lyt; + ts->shape[idx].comb = 0; + ts->shape[idx].clearance = 0; + + switch(shape) { + case 0: + ts->shape[idx].shape = PCB_PSSH_CIRC; + ts->shape[idx].data.circ.x = ts->shape[idx].data.circ.y = 0; + ts->shape[idx].data.circ.dia = size; + break; + case 1: + ts->shape[idx].shape = PCB_PSSH_POLY; + pcb_pstk_shape_alloc_poly(&ts->shape[idx].data.poly, 4); + ts->shape[idx].data.poly.x[0] = -size/2; + ts->shape[idx].data.poly.y[0] = -size/2; + ts->shape[idx].data.poly.x[1] = ts->shape[idx].data.poly.x[0]; + ts->shape[idx].data.poly.y[1] = ts->shape[idx].data.poly.y[0] + size; + ts->shape[idx].data.poly.x[2] = ts->shape[idx].data.poly.x[0] + size; + ts->shape[idx].data.poly.y[2] = ts->shape[idx].data.poly.y[0] + size; + ts->shape[idx].data.poly.x[3] = ts->shape[idx].data.poly.x[0] + size; + ts->shape[idx].data.poly.y[3] = ts->shape[idx].data.poly.y[0]; + break; + } + return 0; +} + +/* Auto derive shape from the related copper layer */ +static void pse_drv_shape(pcb_pstk_proto_t *proto, pcb_pstk_tshape_t *ts, pcb_layer_type_t lyt, int paste) +{ + int srci = (lyt & PCB_LYT_TOP) ? 0 : 1; + if (srci >= proto->tr.array[0].len) srci--; + if ((srci < 0) || (srci >= proto->tr.array[0].len)) return; + pcb_pstk_shape_derive(proto, -1, srci, PCB_PROTO_MASK_BLOAT, lyt | PCB_LYT_MASK, PCB_LYC_SUB|PCB_LYC_AUTO); + if (paste) + pcb_pstk_shape_derive(proto, -1, srci, 0, lyt | PCB_LYT_PASTE, PCB_LYC_AUTO); +} + +/* Auto gen shapes for all layers the user selected on the dialog plus add the hole */ +static void pse_gen(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int err = 0; + pse_t *pse = caller_data; + pcb_pstk_proto_t proto; + int sides = pse->attrs[pse->gen_sides].val.lng; + int shape = pse->attrs[pse->gen_shp].val.lng; + int expose = pse->attrs[pse->gen_expose].val.lng; + int paste = pse->attrs[pse->gen_paste].val.lng; + rnd_coord_t size = pse->attrs[pse->gen_size].val.crd; + pcb_layer_type_t lyt = sides_lyt[sides]; + pcb_pstk_tshape_t *ts; + rnd_cardinal_t pid; + + memset(&proto, 0, sizeof(proto)); + + ts = pcb_vtpadstack_tshape_alloc_append(&proto.tr, 1); + ts->rot = 0.0; + ts->xmirror = 0; + ts->smirror = 0; + ts->len = 0; + + if (lyt & PCB_LYT_TOP) err |= pse_gen_shape(ts, PCB_LYT_COPPER | PCB_LYT_TOP, shape, size); + if (lyt & PCB_LYT_BOTTOM) err |= pse_gen_shape(ts, PCB_LYT_COPPER | PCB_LYT_BOTTOM, shape, size); + if (lyt & PCB_LYT_INTERN) err |= pse_gen_shape(ts, PCB_LYT_COPPER | PCB_LYT_INTERN, shape, size); + if (err) + return; + if (expose) { + if (lyt & PCB_LYT_TOP) pse_drv_shape(&proto, ts, PCB_LYT_TOP, paste); + if (lyt & PCB_LYT_BOTTOM) pse_drv_shape(&proto, ts, PCB_LYT_BOTTOM, paste); + } + + proto.hdia = pse->attrs[pse->gen_drill].val.crd; + proto.hplated = 1; + + pcb_pstk_proto_update(&proto); + if (pse->gen_shape_in_place) { + if (pcb_pstk_proto_replace(pse->data, pse->ps->proto, &proto) == PCB_PADSTACK_INVALID) + rnd_message(RND_MSG_ERROR, "Internal error: pse_gen() failed to raplace padstack prototype\n"); + } + else { + pid = pcb_pstk_proto_insert_dup(pse->data, &proto, 1, 1); + if (pid == PCB_PADSTACK_INVALID) + rnd_message(RND_MSG_ERROR, "Internal error: pse_gen() failed to insert padstack prototype\n"); + else + pcb_pstk_change_instance(pse->ps, &pid, NULL, NULL, NULL, NULL); + } + + pse_ps2dlg(hid_ctx, pse); + RND_DAD_SET_VALUE(hid_ctx, pse->tab, lng, 1); /* switch to the prototype view where the new attributes are visible */ + pse_changed(pse); + rnd_gui->invalidate_all(rnd_gui); +} + +#define spring(dlg) \ + RND_DAD_BEGIN_VBOX(dlg); \ + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); \ + RND_DAD_END(dlg); + +void pcb_pstkedit_dialog(pse_t *pse, int target_tab) +{ + int n; + const char *tabs[] = { "this instance", "prototype", "generate common geometry", NULL }; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + RND_DAD_DECL(dlg); + + pse->disable_instance_tab = !!pse->disable_instance_tab; + target_tab -= pse->disable_instance_tab; + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(dlg, tabs + pse->disable_instance_tab); + pse->tab = RND_DAD_CURRENT(dlg); + + if (!pse->disable_instance_tab) { + /* Tab 0: this instance */ + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VBOX(dlg); /* upper frame: instance settings */ + RND_DAD_COMPFLAG(dlg, RND_HATF_FRAME); + RND_DAD_LABEL(dlg, "Settings that affect only this padstack instance"); + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_LABEL(dlg, "prototype"); + RND_DAD_BUTTON(dlg, "#5"); + pse->proto_id = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_chg_protoid); + RND_DAD_HELP(dlg, "Padstack prototype ID\n(click to use a different prototype)"); + RND_DAD_BUTTON(dlg, "Duplicate"); + RND_DAD_HELP(dlg, "Copy padstack prototype to create a new prototype\nfor this padstack instance. Changes to the new\nprototype will not affect other users of the\noriginal prototye."); + RND_DAD_CHANGE_CB(dlg, pse_chg_protodup); + RND_DAD_END(dlg); + RND_DAD_BEGIN_TABLE(dlg, 2); + RND_DAD_LABEL(dlg, "Clearance"); + RND_DAD_COORD(dlg); + pse->clearance = RND_DAD_CURRENT(dlg); + RND_DAD_MINVAL(dlg, 0); + RND_DAD_MAXVAL(dlg, RND_MM_TO_COORD(1000)); + RND_DAD_CHANGE_CB(dlg, pse_chg_instance); + RND_DAD_HELP(dlg, "global clearance (affects all layers)"); + RND_DAD_LABEL(dlg, "Rotation"); + RND_DAD_REAL(dlg); + pse->rot = RND_DAD_CURRENT(dlg); + RND_DAD_MINVAL(dlg, 0); + RND_DAD_MAXVAL(dlg, 360); + RND_DAD_CHANGE_CB(dlg, pse_chg_instance); + RND_DAD_LABEL(dlg, "X-mirror"); + RND_DAD_BOOL(dlg); + pse->xmirror = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_chg_instance); + RND_DAD_LABEL(dlg, "S-mirror"); + RND_DAD_BOOL(dlg); + pse->smirror = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_chg_instance); + RND_DAD_END(dlg); + RND_DAD_END(dlg); + RND_DAD_BEGIN_VBOX(dlg); /* lower frame: thermals */ + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_LABEL(dlg, "Thermals per layer"); + RND_DAD_BEGIN_TABLE(dlg, 2); + { + rnd_layergrp_id_t gid; + pse->thermal.len = 0; + for(gid = 0; gid < pse->pcb->LayerGroups.len; gid++) { + pcb_layergrp_t *g = &pse->pcb->LayerGroups.grp[gid]; + if (!(g->ltype & PCB_LYT_COPPER)) + continue; + for(n = 0; n < g->len; n++) { + pcb_layer_t *ly = pcb_get_layer(pse->pcb->Data, g->lid[n]); + if (ly == NULL) + continue; + RND_DAD_LABEL(dlg, ly->name); + pse->thermal.lid[pse->thermal.len] = g->lid[n]; + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_ENUM(dlg, thermal_type); + pse->thermal.wtype[pse->thermal.len] = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_chg_thermal); + RND_DAD_END(dlg); + pse->thermal.len++; + } + } + } + RND_DAD_END(dlg); + RND_DAD_END(dlg); + RND_DAD_END(dlg); + } + + /* Tab 1: prototype */ + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_BEGIN_VBOX(dlg); + + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(dlg, "Geometry of all padstacks with this proto"); + RND_DAD_LABEL(dlg, "[SMIRROR]"); + RND_DAD_HELP(dlg, "The layer stack of this specific padstack is mirrored.\nEditing the prototype will have mirrored effect,\ne.g. editing top side will affect the bottom side\nof this padstack instance."); + pse->prsmirror = RND_DAD_CURRENT(dlg); + spring(dlg); + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_FRAME); + RND_DAD_LABEL(dlg, "Prototype name:"); + RND_DAD_STRING(dlg); + RND_DAD_CHANGE_CB(dlg, pse_chg_prname); + pse->prname = RND_DAD_CURRENT(dlg); + RND_DAD_END(dlg); + RND_DAD_END(dlg); + + RND_DAD_COMPFLAG(dlg, RND_HATF_FRAME); + RND_DAD_BEGIN_TABLE(dlg, 3); + RND_DAD_COMPFLAG(dlg, RND_HATF_FRAME); + + /* header */ + RND_DAD_LABEL(dlg, "Per layer-type shape"); + RND_DAD_LABEL(dlg, "Shape geometry"); + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_LABEL(dlg, "Change shape"); + spring(dlg); + RND_DAD_LABEL(dlg, "Local clearance"); + RND_DAD_END(dlg); + + /* content */ + for(n = 0; n < pcb_proto_num_layers; n++) { + const char *layname = pcb_proto_layers[n].name; + char *layname_tmp = NULL; + char *help = NULL; + + if (pcb_proto_board_layer_for(PCB->Data, pcb_proto_layers[n].mask, pcb_proto_layers[n].comb) == -1) { + layname = layname_tmp = rnd_strdup_printf("(%s)", pcb_proto_layers[n].name); + help = "No board layer available for this layer type.\nThis shape will not show on the board\nuntil the corresponding layer in the matching layer group type is created."; + } + + /* col 1 */ + RND_DAD_LABEL(dlg, layname); + if (help != NULL) + RND_DAD_HELP(dlg, help); + + /* col 2 */ + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_LABEL(dlg, "-"); + pse->proto_shape[n] = RND_DAD_CURRENT(dlg); + RND_DAD_LABEL(dlg, " "); + RND_DAD_LABEL(dlg, "-"); + pse->proto_info[n] = RND_DAD_CURRENT(dlg); + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL | RND_HATF_TIGHT); + RND_DAD_END(dlg); + RND_DAD_END(dlg); + + /* col 3 */ + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_BUTTON(dlg, "Change"); + pse->proto_change[n] = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_chg_shape); + RND_DAD_HELP(dlg, "Change the shape on this layer type"); + RND_DAD_LABEL(dlg, " "); + RND_DAD_COORD(dlg); + pse->proto_clr[n] = RND_DAD_CURRENT(dlg); + RND_DAD_MINVAL(dlg, 1); + RND_DAD_MAXVAL(dlg, RND_MM_TO_COORD(1000)); + RND_DAD_CHANGE_CB(dlg, pse_chg_proto_clr); + RND_DAD_WIDTH_CHR(dlg, 8); + RND_DAD_HELP(dlg, "local, per layer type clearance\n(only when global padstack clearance is 0)"); + free(layname_tmp); + RND_DAD_END(dlg); + } + RND_DAD_END(dlg); + + + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_LABEL(dlg, "Hole properties:"); + pse->hole_header = RND_DAD_CURRENT(dlg); + spring(dlg); + RND_DAD_LABEL(dlg, "Hole diameter:"); + RND_DAD_COORD(dlg); + pse->hdia = RND_DAD_CURRENT(dlg); + RND_DAD_MINVAL(dlg, 0); + RND_DAD_MAXVAL(dlg, RND_MM_TO_COORD(1000)); + RND_DAD_CHANGE_CB(dlg, pse_chg_hole); + RND_DAD_WIDTH_CHR(dlg, 10); + spring(dlg); + RND_DAD_LABEL(dlg, "Hole/slot plating:"); + RND_DAD_BOOL(dlg); + pse->hplated = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_chg_hole); + RND_DAD_HELP(dlg, "A plated hole galvanically connects layers"); + + RND_DAD_END(dlg); + + RND_DAD_BEGIN_TABLE(dlg, 4); + /* table row 1 */ + RND_DAD_LABEL(dlg, "Hole/slot top:"); + RND_DAD_INTEGER(dlg); + pse->htop_val = RND_DAD_CURRENT(dlg); + RND_DAD_MINVAL(dlg, -(pse->pcb->LayerGroups.cache.copper_len-1)); + RND_DAD_MAXVAL(dlg, pse->pcb->LayerGroups.cache.copper_len-1); + RND_DAD_CHANGE_CB(dlg, pse_chg_hole); + RND_DAD_HELP(dlg, "Blind/buried via/slot: top end of the hole"); + RND_DAD_WIDTH_CHR(dlg, 6); + RND_DAD_LABEL(dlg, ""); + pse->htop_text = RND_DAD_CURRENT(dlg); + RND_DAD_LABEL(dlg, ""); + pse->htop_layer = RND_DAD_CURRENT(dlg); + + /* table row 2 */ + RND_DAD_LABEL(dlg, "Hole/slot bottom:"); + RND_DAD_INTEGER(dlg); + pse->hbot_val = RND_DAD_CURRENT(dlg); + RND_DAD_MINVAL(dlg, -(pse->pcb->LayerGroups.cache.copper_len-1)); + RND_DAD_MAXVAL(dlg, pse->pcb->LayerGroups.cache.copper_len-1); + RND_DAD_CHANGE_CB(dlg, pse_chg_hole); + RND_DAD_HELP(dlg, "Blind/buried via/slot: bottom end of the hole"); + RND_DAD_WIDTH_CHR(dlg, 6); + RND_DAD_LABEL(dlg, ""); + pse->hbot_text = RND_DAD_CURRENT(dlg); + RND_DAD_LABEL(dlg, ""); + pse->hbot_layer = RND_DAD_CURRENT(dlg); + + RND_DAD_END(dlg); + RND_DAD_END(dlg); + RND_DAD_END(dlg); + + /* Tab 2: generate common geometry */ + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_LABEL(dlg, "Generate a new prototype using a few numeric input"); + + RND_DAD_BEGIN_TABLE(dlg, 2); + RND_DAD_LABEL(dlg, "Copper shape:"); + RND_DAD_ENUM(dlg, shapes); + pse->gen_shp = RND_DAD_CURRENT(dlg); + + RND_DAD_LABEL(dlg, "Size (circle diameter or square side):"); + RND_DAD_COORD(dlg); + pse->gen_size = RND_DAD_CURRENT(dlg); + RND_DAD_MINVAL(dlg, 1); + RND_DAD_MAXVAL(dlg, RND_MM_TO_COORD(1000)); + + RND_DAD_LABEL(dlg, "Drill diameter (0 means no hole):"); + RND_DAD_COORD(dlg); + pse->gen_drill = RND_DAD_CURRENT(dlg); + RND_DAD_MINVAL(dlg, 1); + RND_DAD_MAXVAL(dlg, RND_MM_TO_COORD(1000)); + + RND_DAD_LABEL(dlg, "Copper shapes on:"); + RND_DAD_ENUM(dlg, sides); + pse->gen_sides = RND_DAD_CURRENT(dlg); + + RND_DAD_LABEL(dlg, "Expose top/bottom copper:"); + RND_DAD_BOOL(dlg); + pse->gen_expose = RND_DAD_CURRENT(dlg); + + RND_DAD_LABEL(dlg, "Paste exposed copper:"); + RND_DAD_BOOL(dlg); + pse->gen_paste = RND_DAD_CURRENT(dlg); + + RND_DAD_LABEL(dlg, ""); + RND_DAD_BUTTON(dlg, "Generate!"); + pse->gen_do = RND_DAD_CURRENT(dlg); + RND_DAD_CHANGE_CB(dlg, pse_gen); + RND_DAD_END(dlg); + RND_DAD_END(dlg); + RND_DAD_END(dlg); + RND_DAD_END(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + RND_DAD_NEW("padstack", dlg, "Edit padstack", pse, rnd_true, NULL); + pse->attrs = dlg; + pse_ps2dlg(dlg_hid_ctx, pse); + if (target_tab > 0) + RND_DAD_SET_VALUE(dlg_hid_ctx, pse->tab, lng, target_tab); + RND_DAD_RUN(dlg); + + free((char *)pse->attrs[pse->prname].val.str); + + RND_DAD_FREE(dlg); +} + +const char pcb_acts_PadstackEdit[] = "PadstackEdit(object, [tab])\n"; +const char pcb_acth_PadstackEdit[] = "interactive pad stack editor"; +fgw_error_t pcb_act_PadstackEdit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op = F_Object, target_tab = -1; + pse_t pse; + + memset(&pse, 0, sizeof(pse)); + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, PadstackEdit, op = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_INT, PadstackEdit, target_tab = argv[2].val.nat_int); + RND_ACT_IRES(0); + + if (op == F_Object) { + rnd_coord_t x, y; + void *ptr1, *ptr2 = NULL, *ptr3; + long type; + rnd_hid_get_coords("Click on a padstack to edit", &x, &y, 0); + type = pcb_search_screen(x, y, PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART | PCB_LOOSE_SUBC(PCB), &ptr1, &ptr2, &ptr3); + if (type != PCB_OBJ_PSTK) { + rnd_message(RND_MSG_ERROR, "Need a padstack.\n"); + RND_ACT_IRES(1); + return 0; + } + pse.ps = ptr2; + } + else + RND_ACT_FAIL(PadstackEdit); + + pse.pcb = pcb_data_get_top(pse.ps->parent.data); + if (pse.pcb == NULL) + pse.pcb = PCB; + + pse.data = pse.ps->parent.data; + assert(pse.ps->parent_type == PCB_PARENT_DATA); + + pcb_pstkedit_dialog(&pse, target_tab); + + RND_ACT_IRES(0); + return 0; +} + Index: tags/2.3.0/src_plugins/dialogs/dlg_padstack.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_padstack.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_padstack.h (revision 33253) @@ -0,0 +1,51 @@ +#include "obj_pstk.h" + +typedef struct pse_s pse_t; +struct pse_s { + /* caller conf */ + int disable_instance_tab, gen_shape_in_place; + rnd_hid_attribute_t *attrs; + pcb_board_t *pcb; + pcb_data_t *data; /* parent data where the proto is sitting; might be a subc */ + pcb_pstk_t *ps; + + /* optional hooks */ + void *user_data; /* owned by the caller who sets up the struct */ + void (*change_cb)(pse_t *pse); + + /* internal states */ + int tab; + struct { + int len; + long lid[PCB_MAX_LAYER]; + int wtype[PCB_MAX_LAYER]; + } thermal; + + /* widget IDs */ + int but_instance, but_prototype; + int proto_id, clearance, rot, xmirror, smirror; + int proto_shape[pcb_proto_num_layers]; + int proto_info[pcb_proto_num_layers]; + int proto_change[pcb_proto_num_layers]; + rnd_coord_t proto_clr[pcb_proto_num_layers]; + int prname, prsmirror; + int hole_header; + int hdia, hplated; + int htop_val, htop_text, htop_layer; + int hbot_val, hbot_text, hbot_layer; + int gen_shp, gen_size, gen_drill, gen_sides, gen_expose, gen_paste, gen_do; + + /* sub-dialog: shape change */ + void *parent_hid_ctx; + int editing_shape; /* index of the shape being edited */ + rnd_hid_attribute_t *shape_chg; + int text_shape, del, derive, hshadow; + int copy_do, copy_from; + int shrink, amount, grow; +}; + +void pcb_pstkedit_dialog(pse_t *pse, int target_tab); + +extern const char pcb_acts_PadstackEdit[]; +extern const char pcb_acth_PadstackEdit[]; +fgw_error_t pcb_act_PadstackEdit(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/2.3.0/src_plugins/dialogs/dlg_pinout.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pinout.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pinout.c (revision 33253) @@ -0,0 +1,194 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include "build_run.h" +#include +#include "obj_subc_parent.h" +#include "draw.h" +#include "obj_term.h" +#include +#include "search.h" +#include "search_r.h" +#include "netlist.h" + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + pcb_board_t *pcb; /* for netlist lookups */ + pcb_data_t *data; + long subc_id; + + int w_lab_num, w_lab_name, w_lab_net; + + pcb_subc_t *tempsc; /* non-persistent, should be used only within the scope of a callback, recirsively down */ +} pinout_ctx_t; + +pinout_ctx_t pinout_ctx; + +static void pinout_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + pinout_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + free(ctx); +} + + +static void pinout_expose(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + pinout_ctx_t *ctx = prv->user_ctx; + void *r1, *r2, *r3; + + pcb_objtype_t type = pcb_search_obj_by_id_(ctx->data, &r1, &r2, &r3, ctx->subc_id, PCB_OBJ_SUBC); + if (type == PCB_OBJ_SUBC) { + pcb_subc_t *sc = r2; + int orig_po = pcb_draw_force_termlab; + pcb_draw_force_termlab = rnd_true; + pcb_subc_draw_preview(sc, &e->view); + pcb_draw_force_termlab = orig_po; + } + else { + char tmp[128]; + rnd_box_t bbox; + sprintf(tmp, "Subcircuit #%ld not found.", ctx->subc_id); + bbox.X1 = bbox.Y1 = 0; + bbox.X2 = bbox.Y2 = RND_MM_TO_COORD(10); + rnd_dad_preview_zoomto(attrib, &bbox); + rnd_render->set_color(gc, rnd_color_red); + pcb_text_draw_string_simple(NULL, tmp, RND_MM_TO_COORD(1), RND_MM_TO_COORD(20), 1.0, 1.0, 0, 0, 0, 0, 0, 0); + } +} + +static rnd_r_dir_t pinout_mouse_search_cb(void *closure, pcb_any_obj_t *obj, void *box) +{ + pinout_ctx_t *ctx = closure; + rnd_hid_attr_val_t val; + + if ((obj->term != NULL) && (pcb_obj_parent_subc(obj) == ctx->tempsc) && (obj->term != NULL)) { + val.str = obj->term; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->w_lab_num, &val); + val.str = pcb_attribute_get(&obj->Attributes, "name"); + if (val.str != NULL) + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->w_lab_name, &val); + if (ctx->pcb != NULL) { + { + pcb_net_term_t *term = pcb_net_find_by_obj(&ctx->pcb->netlist[PCB_NETLIST_EDITED], obj); + if (term != NULL) { + val.str = term->parent.net->name; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->w_lab_net, &val); + } + } + } + } + return RND_R_DIR_NOT_FOUND; +} + +static rnd_bool pinout_mouse(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + if (kind == RND_HID_MOUSE_RELEASE) { + pinout_ctx_t *ctx = prv->user_ctx; + void *r1, *r2, *r3; + pcb_objtype_t type; + rnd_box_t b; + rnd_hid_attr_val_t val; + + val.str = "n/a"; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->w_lab_num, &val); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->w_lab_name, &val); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->w_lab_net, &val); + + type = pcb_search_obj_by_id_(ctx->data, &r1, &r2, &r3, ctx->subc_id, PCB_OBJ_SUBC); + if (type != PCB_OBJ_SUBC) + return rnd_false; + ctx->tempsc = r2; + + b.X1 = x; + b.Y1 = y; + b.X2 = x+1; + b.Y2 = y+1; + pcb_search_data_by_loc(ctx->data, PCB_TERM_OBJ_TYPES, &b, pinout_mouse_search_cb, ctx); + ctx->tempsc = NULL; + } + + return rnd_false; +} + +static void pcb_dlg_pinout(pcb_board_t *pcb, pcb_data_t *data, pcb_subc_t *sc) +{ + char title[64]; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + pinout_ctx_t *ctx = calloc(sizeof(pinout_ctx_t), 1); + + ctx->pcb = pcb; + ctx->data = data; + ctx->subc_id = sc->ID; + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_PREVIEW(ctx->dlg, pinout_expose, pinout_mouse, NULL, NULL, &sc->BoundingBox, 200, 200, ctx); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Term ID:"); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->w_lab_num = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Term name:"); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->w_lab_name = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Net:"); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->w_lab_net = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + if (sc->refdes != NULL) + sprintf(title, "Subcircuit #%ld (%s) pinout", sc->ID, sc->refdes); + else + sprintf(title, "Subcircuit #%ld pinout", sc->ID); + RND_DAD_NEW("pinout", ctx->dlg, title, ctx, rnd_false, pinout_close_cb); +} + +static const char pcb_acts_Pinout[] = "Pinout()\n"; +static const char pcb_acth_Pinout[] = "Present the subcircuit pinout box"; +static fgw_error_t pcb_act_Pinout(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + void *r1, *r2, *r3; + rnd_coord_t x, y; + pcb_objtype_t type; + + rnd_hid_get_coords("Click on a subcircuit", &x, &y, 0); + type = pcb_search_obj_by_location(PCB_OBJ_SUBC, &r1, &r2, &r3, x, y, 1); + if (type == PCB_OBJ_SUBC) { + pcb_subc_t *sc = r2; + pcb_dlg_pinout(PCB, PCB->Data, sc); + RND_ACT_IRES(0); + } + else { + rnd_message(RND_MSG_ERROR, "pinout dialog: there's no subcircuit there\n"); + RND_ACT_IRES(-1); + } + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_plugins.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_plugins.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_plugins.c (revision 33253) @@ -0,0 +1,146 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2015,2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ + int wtree; +} plugins_ctx_t; + +plugins_ctx_t plugins_ctx; + +static void plugins_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + plugins_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(plugins_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static int plugin_cmp(const void *v1, const void *v2) +{ + const pup_plugin_t **p1 = (const pup_plugin_t **)v1, **p2 = (const pup_plugin_t **)v2; + return strcmp((*p1)->name, (*p2)->name); +} + +static void plugins2dlg(plugins_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr= &ctx->dlg[ctx->wtree]; + rnd_hid_tree_t *tree = attr->wdata; + char *cell[4]; + pup_plugin_t *p; + vtp0_t tmp; + long n; + + rnd_dad_tree_clear(tree); + + /* sort plugins */ + vtp0_init(&tmp); + for(p = rnd_pup.plugins; p != NULL; p = p->next) + vtp0_append(&tmp, p); + + qsort(tmp.array, tmp.used, sizeof(pup_plugin_t *), plugin_cmp); + + + /* add all items */ + for(n = 0; n < tmp.used; n++) { + rnd_hid_row_t *row; + + p = tmp.array[n]; + cell[0] = rnd_strdup(p->name); + cell[1] = rnd_strdup((p->flags & PUP_FLG_STATIC) ? "buildin" : "plugin"); + cell[2] = rnd_strdup_printf("%d", p->references); + row = rnd_dad_tree_append(attr, NULL, cell); + row->user_data = p; + } + + vtp0_uninit(&tmp); +} + +static void unload_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + plugins_ctx_t *ctx = caller_data; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&(ctx->dlg[ctx->wtree])); + pup_plugin_t *p; + + if (row == NULL) + return; + + p = row->user_data; + if (p->flags & PUP_FLG_STATIC) { + rnd_message(RND_MSG_ERROR, "Can not unload '%s', it is builtin (static linked into the executable)\n", p->name); + return; + } + + if (p->references > 1) { + rnd_message(RND_MSG_ERROR, "Can not unload '%s' while other active plugins still depend on it\n", p->name); + return; + } + + pup_unload(&rnd_pup, p, NULL); + + /* rebuild the whole tree since we may have unloaded more than one plugins */ + plugins2dlg(ctx); +} + +static const char pcb_acts_ManagePlugins[] = "ManagePlugins()\n"; +static const char pcb_acth_ManagePlugins[] = "Manage plugins dialog."; +static fgw_error_t pcb_act_ManagePlugins(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + static const char *hdr[] = {"plugin", "type", "refco", NULL}; + plugins_ctx_t *ctx = &plugins_ctx; + + RND_ACT_IRES(0); + if (ctx->active) + return 0; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 3, 0, hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); +/* RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, library_select); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, &library_ctx);*/ + ctx->wtree = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Unload selected"); + RND_DAD_CHANGE_CB(ctx->dlg, unload_cb); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 400); + + plugins2dlg(ctx); + + RND_DAD_NEW("plugins", ctx->dlg, "Manage plugins", ctx, rnd_false, plugins_close_cb); + + ctx->active = 1; + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref.c (revision 33253) @@ -0,0 +1,488 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* The preferences dialog, invoked by the Preferences() action */ + +#include "config.h" + +#include +#include +#include +#include "build_run.h" +#include +#include +#include "event.h" +#include +#include +#include +#include + +#include "dlg_pref.h" + +#define PREF_TABS 10 +static const char *pref_tabs[PREF_TABS+1] = { "General", "Board meta", "Sizes & DRC", "Library", "Layers", "Colors", "Window", "Key", "Menu", "Config tree", NULL }; +static const int pref_tab_cfgs[PREF_TABS] = { 1, 0, 1, 1, 0, 1, 1, 0, 0, 0 }; + +static lht_node_t *pref_dlg2conf_pre(pref_ctx_t *ctx); +static void pref_dlg2conf_post(pref_ctx_t *ctx); + +#include "dlg_pref_sizes.c" +#include "dlg_pref_board.c" +#include "dlg_pref_general.c" +#include "dlg_pref_lib.c" +#include "dlg_pref_layer.c" +#include "dlg_pref_color.c" +#include "dlg_pref_win.c" +#include "dlg_pref_key.c" +#include "dlg_pref_menu.c" +#include "dlg_pref_conf.c" + +pref_ctx_t pref_ctx; +static const char *pref_cookie = "preferences dialog"; +rnd_conf_hid_id_t pref_hid; + +static const char *role_names[] = { "user", "project", "design", "cli", NULL }; +static const rnd_conf_role_t roles[] = { RND_CFR_USER, RND_CFR_PROJECT, RND_CFR_DESIGN, RND_CFR_CLI, 0 }; + +static lht_node_t *pref_dlg2conf_pre(pref_ctx_t *ctx) +{ + lht_node_t *m; + + m = rnd_conf_lht_get_first(ctx->role, 0); + if (m == NULL) { + if (ctx->role == RND_CFR_PROJECT) { + const char *pcb_fn = (PCB == NULL ? NULL : PCB->hidlib.filename); + const char *try, *fn = rnd_conf_get_project_conf_name(NULL, pcb_fn, &try); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create the project file\n"); + return NULL; + } + rnd_conf_reset(ctx->role, fn); + rnd_conf_makedirty(ctx->role); + rnd_conf_save_file(&PCB->hidlib, fn, pcb_fn, ctx->role, NULL); + m = rnd_conf_lht_get_first(ctx->role, 0); + if (m == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create the project file %s\n", fn); + return NULL; + } + rnd_message(RND_MSG_INFO, "Created the project file\n"); + } + else { + rnd_message(RND_MSG_ERROR, "Failed to create config file for role %s\n", rnd_conf_role_name(ctx->role)); + return NULL; + } + } + + return m; +} + +static void pref_dlg2conf_post(pref_ctx_t *ctx) +{ + if ((ctx->role == RND_CFR_USER) || (ctx->role == RND_CFR_PROJECT)) + rnd_conf_save_file(&PCB->hidlib, NULL, (PCB == NULL ? NULL : PCB->hidlib.filename), ctx->role, NULL); + else if (ctx->role == RND_CFR_DESIGN) + pcb_board_set_changed_flag(PCB, 1); +} + +void pcb_pref_conf2dlg_item(rnd_conf_native_t *cn, pref_confitem_t *item) +{ + switch(cn->type) { + case RND_CFN_COORD: + RND_DAD_SET_VALUE(pref_ctx.dlg_hid_ctx, item->wid, crd, cn->val.coord[0]); + break; + case RND_CFN_BOOLEAN: + case RND_CFN_INTEGER: + RND_DAD_SET_VALUE(pref_ctx.dlg_hid_ctx, item->wid, lng, cn->val.integer[0]); + break; + case RND_CFN_REAL: + RND_DAD_SET_VALUE(pref_ctx.dlg_hid_ctx, item->wid, dbl, cn->val.real[0]); + break; + case RND_CFN_STRING: + RND_DAD_SET_VALUE(pref_ctx.dlg_hid_ctx, item->wid, str, cn->val.string[0]); + break; + default: rnd_message(RND_MSG_ERROR, "pcb_pref_conf2dlg_item(): widget type not handled\n"); + } +} + +void pcb_pref_dlg2conf_item(pref_ctx_t *ctx, pref_confitem_t *item, rnd_hid_attribute_t *attr) +{ + pref_confitem_t *old = ctx->pcb_conf_lock; + rnd_conf_native_t *cn = rnd_conf_get_field(item->confpath); + + if (cn == NULL) + return; + + ctx->pcb_conf_lock = item; + switch(cn->type) { + case RND_CFN_COORD: + if (cn->val.coord[0] != attr->val.crd) + rnd_conf_setf(ctx->role, item->confpath, -1, "%.8$mm", attr->val.crd); + break; + case RND_CFN_BOOLEAN: + case RND_CFN_INTEGER: + if (cn->val.integer[0] != attr->val.lng) + rnd_conf_setf(ctx->role, item->confpath, -1, "%d", attr->val.lng); + break; + case RND_CFN_REAL: + if (cn->val.real[0] != attr->val.dbl) + rnd_conf_setf(ctx->role, item->confpath, -1, "%f", attr->val.dbl); + break; + case RND_CFN_STRING: + if (strcmp(cn->val.string[0], attr->val.str) != 0) + rnd_conf_set(ctx->role, item->confpath, -1, attr->val.str, RND_POL_OVERWRITE); + break; + default: rnd_message(RND_MSG_ERROR, "pcb_pref_dlg2conf_item(): widget type not handled\n"); + } + ctx->pcb_conf_lock = old; +} + +rnd_bool pcb_pref_dlg2conf_table(pref_ctx_t *ctx, pref_confitem_t *list, rnd_hid_attribute_t *attr) +{ + pref_confitem_t *c; + int wid = attr - ctx->dlg; + + for(c = list; c->confpath != NULL; c++) { + if (c->wid == wid) { + pcb_pref_dlg2conf_item(ctx, c, attr); + return 1; + } + } + return 0; +} + + +void pcb_pref_create_conf_item(pref_ctx_t *ctx, pref_confitem_t *item, void (*change_cb)(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr)) +{ + rnd_conf_native_t *cn = rnd_conf_get_field(item->confpath); + + if (cn == NULL) { + rnd_message(RND_MSG_ERROR, "Internal error: pcb_pref_create_conf_item(): invalid conf node %s\n", item->confpath); + item->wid = -1; + return; + } + + RND_DAD_LABEL(ctx->dlg, item->label); + RND_DAD_HELP(ctx->dlg, cn->description); + + switch(cn->type) { + case RND_CFN_COORD: + RND_DAD_COORD(ctx->dlg); + item->wid = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, 0, RND_MAX_COORD); + RND_DAD_DEFAULT_NUM(ctx->dlg, cn->val.coord[0]); + RND_DAD_HELP(ctx->dlg, cn->description); + RND_DAD_CHANGE_CB(ctx->dlg, change_cb); + break; + case RND_CFN_BOOLEAN: + RND_DAD_BOOL(ctx->dlg); + item->wid = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_DEFAULT_NUM(ctx->dlg, cn->val.integer[0]); + RND_DAD_HELP(ctx->dlg, cn->description); + RND_DAD_CHANGE_CB(ctx->dlg, change_cb); + break; + case RND_CFN_INTEGER: + RND_DAD_INTEGER(ctx->dlg); + item->wid = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, 0, INT_MAX); + RND_DAD_DEFAULT_NUM(ctx->dlg, cn->val.integer[0]); + RND_DAD_HELP(ctx->dlg, cn->description); + RND_DAD_CHANGE_CB(ctx->dlg, change_cb); + break; + case RND_CFN_REAL: + RND_DAD_REAL(ctx->dlg); + item->wid = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, 0, INT_MAX); + ctx->dlg[item->wid].val.dbl = cn->val.real[0]; + RND_DAD_HELP(ctx->dlg, cn->description); + RND_DAD_CHANGE_CB(ctx->dlg, change_cb); + break; + case RND_CFN_STRING: + RND_DAD_STRING(ctx->dlg); + item->wid = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[item->wid].val.str = rnd_strdup(cn->val.string[0]); + RND_DAD_HELP(ctx->dlg, cn->description); + RND_DAD_CHANGE_CB(ctx->dlg, change_cb); + break; + default: + RND_DAD_LABEL(ctx->dlg, "Internal error: pcb_pref_create_conf_item(): unhandled type"); + item->wid = -1; + return; + } + + item->cnext = rnd_conf_hid_get_data(cn, pref_hid); + rnd_conf_hid_set_data(cn, pref_hid, item); +} + +void pcb_pref_create_conftable(pref_ctx_t *ctx, pref_confitem_t *list, void (*change_cb)(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr)) +{ + pref_confitem_t *c; + for(c = list; c->confpath != NULL; c++) + pcb_pref_create_conf_item(ctx, c, change_cb); +} + +void pcb_pref_conflist_remove(pref_ctx_t *ctx, pref_confitem_t *list) +{ + pref_confitem_t *c; + for(c = list; c->confpath != NULL; c++) { + rnd_conf_native_t *cn = rnd_conf_get_field(c->confpath); + c->cnext = NULL; + if (cn != NULL) + rnd_conf_hid_set_data(cn, pref_hid, NULL); + } +} + +static void pref_role_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + ctx->role = roles[attr->val.lng]; +} + +static void pref_tab_chosen(pref_ctx_t *ctx, int tab) +{ + rnd_trace("tab: %d %d\n", tab, pref_tab_cfgs[tab]); + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wrolebox, !pref_tab_cfgs[tab]); +} + +static void pref_tab_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_tab_chosen(caller_data, attr->val.lng); +} + +static void pref_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + long n; + pref_ctx_t *ctx = caller_data; + + pcb_dlg_pref_sizes_close(ctx); + pcb_dlg_pref_board_close(ctx); + pcb_dlg_pref_general_close(ctx); + pcb_dlg_pref_lib_close(ctx); + pcb_dlg_pref_color_close(ctx); + pcb_dlg_pref_win_close(ctx); + pcb_dlg_pref_menu_close(ctx); + + for(n = 0; n < ctx->auto_free.used; n++) + free(ctx->auto_free.array[n]); + vtp0_uninit(&ctx->auto_free); + + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(pref_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +/* Compare inp to fixed in case insensitive manner; accept full length match + or if inp contains the first word of fixed. Returns 0 on accept. */ +static int pref_strcmp(const char *fixed, const char *inp) +{ + for(;;) { + if ((*inp == '\0') && ((*fixed == '\0') || (*fixed == ' '))) + return 0; + if (tolower(*fixed) != tolower(*inp)) + return -1; + fixed++; + inp++; + } +} + +static void pcb_dlg_pref(const char *target_tab_str, const char *tabarg) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + int target_tab = -1; + + if ((target_tab_str != NULL) && (*target_tab_str != '\0')) { + const char **t; + int tt; + + for(tt = 0, t = pref_tabs; *t != NULL; t++,tt++) { + if (pref_strcmp(*t, target_tab_str) == 0) { + target_tab = tt; + break; + } + } + } + + if (pref_ctx.active) { + if (target_tab >= 0) + RND_DAD_SET_VALUE(pref_ctx.dlg_hid_ctx, pref_ctx.wtab, lng, target_tab); + return; + } + + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); + RND_DAD_COMPFLAG(pref_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(pref_ctx.dlg, pref_tabs); + RND_DAD_COMPFLAG(pref_ctx.dlg, RND_HATF_EXPFILL); + pref_ctx.wtab = RND_DAD_CURRENT(pref_ctx.dlg); + RND_DAD_CHANGE_CB(pref_ctx.dlg, pref_tab_cb); + + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); /* General */ + pcb_dlg_pref_general_create(&pref_ctx); + RND_DAD_END(pref_ctx.dlg); + + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); /* Board meta */ + pcb_dlg_pref_board_create(&pref_ctx); + RND_DAD_END(pref_ctx.dlg); + + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); /* Sizes & DRC */ + pcb_dlg_pref_sizes_create(&pref_ctx); + RND_DAD_END(pref_ctx.dlg); + + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); /* Library */ + pcb_dlg_pref_lib_create(&pref_ctx); + RND_DAD_END(pref_ctx.dlg); + + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); /* Layers */ + pcb_dlg_pref_layer_create(&pref_ctx); + RND_DAD_END(pref_ctx.dlg); + + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); /* Colors */ + pcb_dlg_pref_color_create(&pref_ctx); + RND_DAD_END(pref_ctx.dlg); + + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); /* Window */ + pcb_dlg_pref_win_create(&pref_ctx); + RND_DAD_END(pref_ctx.dlg); + + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); /* Key */ + pcb_dlg_pref_key_create(&pref_ctx); + RND_DAD_END(pref_ctx.dlg); + + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); /* Menu */ + pcb_dlg_pref_menu_create(&pref_ctx); + RND_DAD_END(pref_ctx.dlg); + + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); /* Config tree */ + pcb_dlg_pref_conf_create(&pref_ctx); + RND_DAD_END(pref_ctx.dlg); + + RND_DAD_END(pref_ctx.dlg); + RND_DAD_BEGIN_VBOX(pref_ctx.dlg); + RND_DAD_BEGIN_HBOX(pref_ctx.dlg); + RND_DAD_COMPFLAG(pref_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(pref_ctx.dlg); + pref_ctx.wrolebox = RND_DAD_CURRENT(pref_ctx.dlg); + RND_DAD_LABEL(pref_ctx.dlg, "All changes are made to role:"); + RND_DAD_ENUM(pref_ctx.dlg, role_names); + pref_ctx.wrole = RND_DAD_CURRENT(pref_ctx.dlg); + RND_DAD_CHANGE_CB(pref_ctx.dlg, pref_role_cb); + RND_DAD_END(pref_ctx.dlg); + RND_DAD_BUTTON_CLOSES_NAKED(pref_ctx.dlg, clbtn); + RND_DAD_END(pref_ctx.dlg); + RND_DAD_END(pref_ctx.dlg); + RND_DAD_END(pref_ctx.dlg); + + /* set up the context */ + pref_ctx.active = 1; + + RND_DAD_NEW("preferences", pref_ctx.dlg, "pcb-rnd preferences", &pref_ctx, rnd_false, pref_close_cb); + + RND_DAD_SET_VALUE(pref_ctx.dlg_hid_ctx, pref_ctx.wrole, lng, 2); + pref_ctx.role = RND_CFR_DESIGN; + + pcb_dlg_pref_lib_open(&pref_ctx); + pcb_dlg_pref_color_open(&pref_ctx); + pcb_dlg_pref_win_open(&pref_ctx); + pcb_dlg_pref_key_open(&pref_ctx); + pcb_dlg_pref_menu_open(&pref_ctx); + pcb_dlg_pref_conf_open(&pref_ctx, (target_tab == PREF_TABS - 2) ? tabarg : NULL); + if ((target_tab >= 0) && (target_tab < PREF_TABS)) { + RND_DAD_SET_VALUE(pref_ctx.dlg_hid_ctx, pref_ctx.wtab, lng, target_tab); + pref_tab_chosen(&pref_ctx, target_tab); + } + else + pref_tab_chosen(&pref_ctx, 0); +} + +static void pref_ev_board_changed(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pref_ctx_t *ctx = user_data; + if (!pref_ctx.active) + return; + + pref_sizes_brd2dlg(ctx); + pref_board_brd2dlg(ctx); + pref_color_brd2dlg(ctx); + pref_win_brd2dlg(ctx); +} + +static void pref_ev_board_meta_changed(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pref_ctx_t *ctx = user_data; + if (!pref_ctx.active) + return; + + pref_sizes_brd2dlg(ctx); + pref_board_brd2dlg(ctx); + pref_color_brd2dlg(ctx); + pref_win_brd2dlg(ctx); +} + +static void pref_ev_menu_changed(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pref_ctx_t *ctx = user_data; + if (!pref_ctx.active) + return; + pref_menu_brd2dlg(ctx); +} + +void pref_conf_changed(rnd_conf_native_t *cfg, int arr_idx) +{ + pref_confitem_t *i; + + for(i = rnd_conf_hid_get_data(cfg, pref_hid); i != NULL; i = i->cnext) + if (i != pref_ctx.pcb_conf_lock) + pcb_pref_conf2dlg_item(cfg, i); + + pcb_pref_dlg_conf_changed_cb(&pref_ctx, cfg, arr_idx); +} + +static rnd_conf_hid_callbacks_t pref_conf_cb; +void pcb_dlg_pref_init(void) +{ + pref_conf_cb.val_change_post = pref_conf_changed; + rnd_event_bind(RND_EVENT_BOARD_CHANGED, pref_ev_board_changed, &pref_ctx, pref_cookie); + rnd_event_bind(RND_EVENT_BOARD_META_CHANGED, pref_ev_board_meta_changed, &pref_ctx, pref_cookie); + rnd_event_bind(RND_EVENT_MENU_CHANGED, pref_ev_menu_changed, &pref_ctx, pref_cookie); + pref_hid = rnd_conf_hid_reg(pref_cookie, &pref_conf_cb); + pcb_dlg_pref_sizes_init(&pref_ctx); + pcb_dlg_pref_lib_init(&pref_ctx); +} + +void pcb_dlg_pref_uninit(void) +{ + rnd_event_unbind_allcookie(pref_cookie); + rnd_conf_hid_unreg(pref_cookie); +} + +const char pcb_acts_Preferences[] = "Preferences([tabname])\n"; +const char pcb_acth_Preferences[] = "Present the preferences dialog, optionally opening the tab requested."; +fgw_error_t pcb_act_Preferences(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *tab = NULL, *tabarg = NULL; + RND_ACT_MAY_CONVARG(1, FGW_STR, Preferences, tab = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, Preferences, tabarg = argv[2].val.str); + pcb_dlg_pref(tab, tabarg); + RND_ACT_IRES(0); + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref.h (revision 33253) @@ -0,0 +1,73 @@ +#ifndef PCB_DLG_PREF_H +#define PCB_DLG_PREF_H + +typedef struct pref_ctx_s pref_ctx_t; + +#include +#include +#include "dlg_pref_sizes.h" +#include "dlg_pref_board.h" +#include "dlg_pref_general.h" +#include "dlg_pref_lib.h" +#include "dlg_pref_color.h" +#include "dlg_pref_win.h" +#include "dlg_pref_key.h" +#include "dlg_pref_menu.h" +#include "dlg_pref_conf.h" + +typedef struct pref_conflist_s pref_confitem_t; +struct pref_conflist_s { + const char *label; + const char *confpath; + int wid; + pref_confitem_t *cnext; /* linked list for conf callback - should be NULL initially */ +}; + +struct pref_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + int wtab, wrole, wrolebox; + int active; /* already open - allow only one instance */ + + pref_sizes_t sizes; + pref_board_t board; + pref_general_t general; + pref_lib_t lib; + pref_color_t color; + pref_win_t win; + pref_key_t key; + pref_menu_t menu; + pref_conf_t conf; + + rnd_conf_role_t role; /* where changes are saved to */ + + pref_confitem_t *pcb_conf_lock; /* the item being changed - should be ignored in a conf change callback */ + vtp0_t auto_free; /* free() each item on close */ +}; + +extern pref_ctx_t pref_ctx; + +/* Create label-input widget pair for editing a conf item, or create whole + list of them */ +void pcb_pref_create_conf_item(pref_ctx_t *ctx, pref_confitem_t *item, void (*change_cb)(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr)); +void pcb_pref_create_conftable(pref_ctx_t *ctx, pref_confitem_t *list, void (*change_cb)(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr)); + +/* Set the config node from the current widget value of a conf item, or + create whole list of them; the table version returns whether the item is found. */ +void pcb_pref_dlg2conf_item(pref_ctx_t *ctx, pref_confitem_t *item, rnd_hid_attribute_t *attr); +rnd_bool pcb_pref_dlg2conf_table(pref_ctx_t *ctx, pref_confitem_t *list, rnd_hid_attribute_t *attr); + +/* Remove conf change binding - shall be called when widgets are removed + (i.e. on dialog box close) */ +void pcb_pref_conflist_remove(pref_ctx_t *ctx, pref_confitem_t *list); + +extern rnd_conf_hid_id_t pref_hid; + +/*** pulbic API for the caller ***/ +void pcb_dlg_pref_init(void); +void pcb_dlg_pref_uninit(void); + +extern const char pcb_acts_Preferences[]; +extern const char pcb_acth_Preferences[]; +fgw_error_t pcb_act_Preferences(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +#endif Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_board.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_board.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_board.c (revision 33253) @@ -0,0 +1,105 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, board tab */ + +#include "dlg_pref.h" +#include +#include "conf_core.h" + +#define RND_EMPTY(a) ((a) ? (a) : "") + +/* Actual board meta to dialog box */ +static void pref_board_brd2dlg(pref_ctx_t *ctx) +{ + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->board.wname, str, RND_EMPTY(PCB->hidlib.name)); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->board.wthermscale, dbl, PCB->ThermScale); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->board.wtype, str, (PCB->is_footprint ? "footprint" : "PCB board")); +} + +/* Dialog box to actual board meta */ +static void pref_board_dlg2brd(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int changed = 0; + const char *newname, *oldname; + double newtherm; + pref_ctx_t *ctx = caller_data; + + newname = RND_EMPTY(ctx->dlg[ctx->board.wname].val.str); + oldname = RND_EMPTY(PCB->hidlib.name); + if (strcmp(oldname, newname) != 0) { + free(PCB->hidlib.name); + PCB->hidlib.name = rnd_strdup(newname); + changed = 1; + } + + newtherm = ctx->dlg[ctx->board.wthermscale].val.dbl; + if (PCB->ThermScale != newtherm) { + PCB->ThermScale = newtherm; + changed = 1; + } + + if (changed) { + PCB->Changed = 1; + rnd_event(&PCB->hidlib, RND_EVENT_BOARD_META_CHANGED, NULL); /* always generate the event to make sure visible changes are flushed */ + } +} + +static void pref_board_edit_attr(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&PCB->hidlib, "Propedit", "board", NULL); +} + + +void pcb_dlg_pref_board_close(pref_ctx_t *ctx) +{ + pcb_pref_conflist_remove(ctx, limit_sizes); +} + +void pcb_dlg_pref_board_create(pref_ctx_t *ctx) +{ + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + RND_DAD_LABEL(ctx->dlg, "Board name"); + RND_DAD_STRING(ctx->dlg); + ctx->board.wname = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[ctx->board.wname].val.str = rnd_strdup(RND_EMPTY(PCB->hidlib.name)); + RND_DAD_CHANGE_CB(ctx->dlg, pref_board_dlg2brd); + RND_DAD_LABEL(ctx->dlg, "Thermal scale"); + RND_DAD_REAL(ctx->dlg); + ctx->board.wthermscale = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, 0.01, 100); + ctx->dlg[ctx->board.wthermscale].val.dbl = PCB->ThermScale; + RND_DAD_CHANGE_CB(ctx->dlg, pref_board_dlg2brd); + RND_DAD_LABEL(ctx->dlg, "Type"); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->board.wtype = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[ctx->board.wtype].name = rnd_strdup((PCB->is_footprint ? "footprint" : "PCB board")); + RND_DAD_CHANGE_CB(ctx->dlg, pref_board_dlg2brd); + RND_DAD_LABEL(ctx->dlg, "Board attributes"); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_CHANGE_CB(ctx->dlg, pref_board_edit_attr); + RND_DAD_END(ctx->dlg); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_board.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_board.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_board.h (revision 33253) @@ -0,0 +1,11 @@ +#ifndef PCB_DLG_PREF_BOARD_H +#define PCB_DLG_PREF_BOARD_H + +typedef struct { + int wname, wthermscale, wtype; +} pref_board_t; + +void pcb_dlg_pref_board_close(pref_ctx_t *ctx); +void pcb_dlg_pref_board_create(pref_ctx_t *ctx); + +#endif Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_color.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_color.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_color.c (revision 33253) @@ -0,0 +1,169 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, color tab */ + +#include "dlg_pref.h" +#include +#include "conf_core.h" + +static void pref_color_brd2dlg(pref_ctx_t *ctx) +{ + rnd_conf_native_t *nat; + int n; + + if (ctx->color.wlayer != NULL) { + nat = rnd_conf_get_field("appearance/color/layer"); + for (n = 0; n < nat->used; n++) + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->color.wlayer[n], clr, nat->val.color[n]); + } + + for(n = 0; n < ctx->color.ngen; n++) { + int w = ctx->color.wgen[n]; + const char *path = ctx->dlg[w].user_data; + nat = rnd_conf_get_field(path); + if (nat != NULL) + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, w, clr, nat->val.color[0]); + } +} + + +void pcb_dlg_pref_color_open(pref_ctx_t *ctx) +{ + pref_color_brd2dlg(ctx); +} + +void pcb_dlg_pref_color_close(pref_ctx_t *ctx) +{ + int n; + + for(n = 0; n < ctx->color.ngen; n++) { + int w = ctx->color.wgen[n]; + free(ctx->dlg[w].user_data); + } + + free(ctx->color.wgen); + free(ctx->color.wlayer); +} + +static void pref_color_gen_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + const char *path = attr->user_data; + + if (pref_dlg2conf_pre(ctx) == NULL) + return; + + rnd_conf_setf(ctx->role, path, -1, "%s", attr->val.clr.str); + + pref_dlg2conf_post(ctx); + + rnd_gui->invalidate_all(rnd_gui); +} + +static void pref_color_layer_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + int idx = (int *)attr->user_data - ctx->color.wlayer; + + if (pref_dlg2conf_pre(ctx) == NULL) + return; + + rnd_conf_setf(ctx->role, "appearance/color/layer", idx, "%s", attr->val.clr.str); + + pref_dlg2conf_post(ctx); +} + + +void pcb_dlg_pref_color_create(pref_ctx_t *ctx) +{ + static const char *tabs[] = { "Generic colors", "Default layer colors", NULL }; + rnd_conf_native_t *nat; + htsp_entry_t *e; + int n, pl, w; + const char *path_prefix = "appearance/color"; + + + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(ctx->dlg, tabs); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_LEFT_TAB); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* generic */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + pl = strlen(path_prefix); + + ctx->color.ngen = 0; + rnd_conf_fields_foreach(e) { + nat = e->value; + if ((strncmp(e->key, path_prefix, pl) == 0) && (nat->type == RND_CFN_COLOR) && (nat->array_size == 1)) + ctx->color.ngen++; + } + ctx->color.wgen = calloc(sizeof(int), ctx->color.ngen); + + n = 0; + rnd_conf_fields_foreach(e) { + nat = e->value; + if ((strncmp(e->key, path_prefix, pl) == 0) && (nat->type == RND_CFN_COLOR) && (nat->array_size == 1)) { + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COLOR(ctx->dlg); + ctx->color.wgen[n] = w = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[w].user_data = rnd_strdup(e->key); + RND_DAD_CHANGE_CB(ctx->dlg, pref_color_gen_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, nat->description); + n++; + RND_DAD_END(ctx->dlg); + } + } + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); /* layer */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + nat = rnd_conf_get_field("appearance/color/layer"); + if (nat->type == RND_CFN_COLOR) { + RND_DAD_LABEL(ctx->dlg, "NOTE: these colors are used only\nwhen creating new layers."); + ctx->color.wlayer = calloc(sizeof(int), nat->used); + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + for (n = 0; n < nat->used; n++) { + char tmp[32]; + RND_DAD_COLOR(ctx->dlg); + ctx->color.wlayer[n] = w = RND_DAD_CURRENT(ctx->dlg); + ctx->dlg[w].user_data = &ctx->color.wlayer[n]; + RND_DAD_CHANGE_CB(ctx->dlg, pref_color_layer_cb); + sprintf(tmp, "Layer %d", n); + RND_DAD_LABEL(ctx->dlg, tmp); + } + RND_DAD_END(ctx->dlg); + } + else { + ctx->color.wlayer = NULL; + RND_DAD_LABEL(ctx->dlg, "Broken internal configuration:\nno layer colors"); + } + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_color.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_color.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_color.h (revision 33253) @@ -0,0 +1,11 @@ +#ifndef PCB_DLG_PREF_COLOR_H +#define PCB_DLG_PREF_COLOR_H + +typedef struct { + int *wgen, *wlayer; + int ngen; +} pref_color_t; + +void pcb_dlg_pref_color_create(pref_ctx_t *ctx); + +#endif Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_conf.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_conf.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_conf.c (revision 33253) @@ -0,0 +1,497 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, conf tree tab */ + +#include "dlg_pref.h" +#include +#include "conf_core.h" +#include + +static const char *pref_conf_get_val(const lht_node_t *nd, const rnd_conf_native_t *nat, int idx); +#include "dlg_pref_confedit.c" + +/* how many chars per line in conf node description (determines window width vs. + window height */ +#define DESC_WRAP_WIDTH 50 + +static const char *type_tabs[RND_CFN_max+2] = /* MUST MATCH rnd_conf_native_type_t */ + {"STRING", "BOOLEAN", "INTEGER", "REAL", "COORD", "UNIT", "COLOR", "LIST", "invalid", NULL}; + +static int conf_tree_cmp(const void *v1, const void *v2) +{ + const htsp_entry_t **e1 = (const htsp_entry_t **) v1, **e2 = (const htsp_entry_t **) v2; + return strcmp((*e1)->key, (*e2)->key); +} + +static void setup_tree(pref_ctx_t *ctx) +{ + char *cell[2] = {NULL}; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->conf.wtree]; + rnd_hid_tree_t *tree = attr->wdata; + htsp_entry_t *e; + htsp_entry_t **sorted; + int num_paths, n; + char path[1024]; + + /* alpha sort keys for the more consistend UI */ + for(e = htsp_first(rnd_conf_fields), num_paths = 0; e; e = htsp_next(rnd_conf_fields, e)) + num_paths++; + sorted = malloc(sizeof(htsp_entry_t *) * num_paths); + for(e = htsp_first(rnd_conf_fields), n = 0; e; e = htsp_next(rnd_conf_fields, e), n++) + sorted[n] = e; + qsort(sorted, num_paths, sizeof(htsp_entry_t *), conf_tree_cmp); + + for(n = 0; n < num_paths; n++) { + char *basename, *bnsep; + rnd_hid_row_t *parent; + rnd_conf_native_t *nat; + + e = sorted[n]; + if (strlen(e->key) > sizeof(path) - 1) { + rnd_message(RND_MSG_WARNING, "Warning: can't create config item for %s: path too long\n", e->key); + continue; + } + strcpy(path, e->key); + basename = strrchr(path, '/'); + if ((basename == NULL) || (basename == path)) { + rnd_message(RND_MSG_WARNING, "Warning: can't create config item for %s: invalid path (node in root)\n", e->key); + continue; + } + bnsep = basename; + *basename = '\0'; + basename++; + + parent = rnd_dad_tree_mkdirp(tree, path, NULL); + if (parent == NULL) { + rnd_message(RND_MSG_WARNING, "Warning: can't create config item for %s: invalid path\n", e->key); + continue; + } + + nat = e->value; + if (nat->array_size > 1) { + int i; + *bnsep = '/'; + parent = rnd_dad_tree_mkdirp(tree, path, NULL); + for(i = 0; i < nat->array_size; i++) { + cell[0] = rnd_strdup_printf("[%d]", i); + rnd_dad_tree_append_under(attr, parent, cell); + } + } + else { + cell[0] = rnd_strdup(basename); + rnd_dad_tree_append_under(attr, parent, cell); + } + } + free(sorted); +} + +static const char *pref_conf_get_val(const lht_node_t *nd, const rnd_conf_native_t *nat, int idx) +{ + lht_node_t *ni; + + switch (nd->type) { + case LHT_TEXT: return nd->data.text.value; break; + case LHT_LIST: + if (nat->array_size > 1) { + int idx2 = idx; + for(ni = nd->data.list.first; ni != NULL; ni = ni->next) { + if (idx2 == 0) { + if (ni->type == LHT_TEXT) + return ni->data.text.value; + return ""; + } + idx2--; + } + } + return ""; + case LHT_HASH: return ""; break; + case LHT_TABLE: return ""; break; + case LHT_SYMLINK: return ""; break; + case LHT_INVALID_TYPE: return ""; break; + } + return ""; +} + +static void setup_intree(pref_ctx_t *ctx, rnd_conf_native_t *nat, int idx) +{ + rnd_conf_role_t n; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->conf.wintree]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + + rnd_dad_tree_clear(tree); + + for(n = 0; n < RND_CFR_max_real; n++) { + char *cell[5]= {NULL}; + cell[0] = rnd_strdup(rnd_conf_role_name(n)); + if (nat != NULL) { + lht_node_t *nd; + long prio = rnd_conf_default_prio[n]; + rnd_conf_policy_t pol = RND_POL_OVERWRITE; + + nd = rnd_conf_lht_get_at_mainplug(n, nat->hash_path, 1, 0); + if (nd != NULL) { /* role, prio, policy, value */ + rnd_conf_get_policy_prio(nd, &pol, &prio); + cell[1] = rnd_strdup_printf("%ld", prio); + cell[2] = rnd_strdup(rnd_conf_policy_name(pol)); + cell[3] = rnd_strdup(pref_conf_get_val(nd, nat, idx)); + } + } + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data2.lng = n; + } +} + +static const char *print_conf_val(rnd_conf_native_type_t type, const rnd_confitem_t *val, char *buf, int sizebuf) +{ + const char *ret = buf; + + *buf = '\0'; + switch(type) { + case RND_CFN_STRING: if (*val->string != NULL) ret = *val->string; break; + case RND_CFN_BOOLEAN: strcpy(buf, *val->boolean ? "true" : "false"); break; + case RND_CFN_INTEGER: sprintf(buf, "%ld", *val->integer); break; + case RND_CFN_REAL: sprintf(buf, "%f", *val->real); break; + case RND_CFN_COORD: rnd_snprintf(buf, sizebuf, "%mH\n%mm\n%ml", *val->coord, *val->coord, *val->coord); break; + case RND_CFN_UNIT: strcpy(buf, (*val->unit)->suffix); break; + case RND_CFN_COLOR: strcpy(buf, val->color->str); break; + case RND_CFN_LIST: strcpy(buf, ""); break; + case RND_CFN_HLIST: strcpy(buf, ""); break; + case RND_CFN_max: strcpy(buf, ""); break; + } + return ret; +} + +static void dlg_conf_select_node(pref_ctx_t *ctx, const char *path, rnd_conf_native_t *nat, int idx) +{ + rnd_hid_attr_val_t hv; + char *tmp, buf[128]; + const char *rolename; + lht_node_t *src; + + if ((path != NULL) && (nat == NULL)) + nat = rnd_conf_get_field(path); + + if ((path == NULL) && (nat != NULL)) + path = nat->hash_path; + + ctx->conf.selected_nat = nat; + ctx->conf.selected_idx = idx; + + if (nat == NULL) { + hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->conf.wname, &hv); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->conf.wdesc, &hv); + setup_intree(ctx, NULL, 0); + + hv.lng = RND_CFN_max; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->conf.wnattype, &hv); + + return; + } + + hv.str = path == NULL ? "" : path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->conf.wname, &hv); + + tmp = rnd_strdup(nat->description); + rnd_text_wrap(tmp, DESC_WRAP_WIDTH, '\n', ' '); + hv.str = tmp; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->conf.wdesc, &hv); + free(tmp); + + /* display lht value */ + setup_intree(ctx, nat, idx); + + /* display native value */ + hv.lng = nat->type; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->conf.wnattype, &hv); + + if ((nat->type == RND_CFN_LIST) || (nat->type == RND_CFN_HLIST)) { + /* non-default: lists are manually loaded */ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->conf.wnatval[nat->type]]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_conf_listitem_t *n; + char *cell[4]; + + rnd_dad_tree_clear(tree); + for (n = rnd_conflist_first(&nat->val.list[idx]); n != NULL; n = rnd_conflist_next(n)) { + const char *strval; + rolename = rnd_conf_role_name(rnd_conf_lookup_role(n->prop.src)); + if (nat->type == RND_CFN_HLIST) + strval = n->name; + else + strval = print_conf_val(n->type, &n->val, buf, sizeof(buf)); + + cell[0] = rolename == NULL ? rnd_strdup("") : rnd_strdup(rolename); + cell[1] = rnd_strdup_printf("%ld", n->prop.prio); + cell[2] = rnd_strdup(strval); + cell[3] = 0; + rnd_dad_tree_append(attr, NULL, cell); + } + return; + } + + /* default: set the value of the given node from hv loaded above */ + hv.str = print_conf_val(nat->type, &nat->val, buf, sizeof(buf)); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->conf.wnatval[nat->type], &hv); + + src = nat->prop[idx].src; + if (src != NULL) { + rolename = rnd_conf_role_name(rnd_conf_lookup_role(nat->prop[idx].src)); + hv.str = tmp = rnd_strdup_printf("prio: %d role: %s\nsource: %s:%d.%d", nat->prop[idx].prio, rolename, src->file_name, src->line, src->col); + } + else + hv.str = tmp = rnd_strdup_printf("prio: %d\nsource: ", nat->prop[idx].prio); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->conf.wsrc[nat->type], &hv); + free(tmp); + + return; +} + +static void dlg_conf_select_node_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + char *end, *end2; + rnd_conf_native_t *nat; + + if (row == NULL) { /* deselect */ + dlg_conf_select_node((pref_ctx_t *)tree->user_ctx, NULL, NULL, 0); + return; + } + + end = strrchr(row->path, '/'); + if ((end != NULL) && (end[1] == '[')) { + int idx = strtol(end+2, &end2, 10); + /* if last segment is an [integer], it is an array */ + if (*end2 == ']') { + char tmp[1024]; + int len = end - row->path; + if ((len <= 0) || (len > sizeof(tmp)-1)) { + rnd_message(RND_MSG_WARNING, "Warning: can't show array item %s: path too long\n", row->path); + return; + } + memcpy(tmp, row->path, len); + tmp[len] = '\0'; + dlg_conf_select_node((pref_ctx_t *)tree->user_ctx, tmp, NULL, idx); + } + return; + } + + /* non-array selection */ + nat = rnd_conf_get_field(row->path); + if ((nat != NULL) && (nat->array_size > 1)) { /* array head: do not display for now */ + dlg_conf_select_node((pref_ctx_t *)tree->user_ctx, NULL, NULL, 0); + return; + } + dlg_conf_select_node((pref_ctx_t *)tree->user_ctx, row->path, nat, 0); +} + + +void pcb_pref_dlg_conf_changed_cb(pref_ctx_t *ctx, rnd_conf_native_t *cfg, int arr_idx) +{ + if (ctx->conf.selected_nat == cfg) + dlg_conf_select_node(ctx, NULL, cfg, ctx->conf.selected_idx); +} + + +static void pcb_pref_dlg_conf_filter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + pref_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + const char *text; + int have_filter_text; + + attr = &ctx->dlg[ctx->conf.wtree]; + tree = attr->wdata; + text = attr_inp->val.str; + have_filter_text = (*text != '\0'); + + /* hide or unhide everything */ + rnd_dad_tree_hide_all(tree, &tree->rows, have_filter_text); + + if (have_filter_text) /* unhide hits and all their parents */ + rnd_dad_tree_unhide_filter(tree, &tree->rows, 0, text); + + rnd_dad_tree_update_hide(attr); +} + + +static void build_natval(pref_ctx_t *ctx) +{ + static const char *hdr_nat[] = {"role", "prio", "value", NULL}; + + RND_DAD_BEGIN_TABBED(pref_ctx.dlg, type_tabs); + RND_DAD_COMPFLAG(pref_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_HIDE_TABLAB); + ctx->conf.wnattype = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: string"); + RND_DAD_LABEL(ctx->dlg, "role/prio"); + ctx->conf.wsrc[0] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(data)"); + ctx->conf.wnatval[0] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: boolean"); + RND_DAD_LABEL(ctx->dlg, "role/prio"); + ctx->conf.wsrc[1] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(data)"); + ctx->conf.wnatval[1] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: integer"); + RND_DAD_LABEL(ctx->dlg, "role/prio"); + ctx->conf.wsrc[2] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(data)"); + ctx->conf.wnatval[2] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: real"); + RND_DAD_LABEL(ctx->dlg, "role/prio"); + ctx->conf.wsrc[3] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(data)"); + ctx->conf.wnatval[3] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: coord"); + RND_DAD_LABEL(ctx->dlg, "role/prio"); + ctx->conf.wsrc[4] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(data)"); + ctx->conf.wnatval[4] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: unit"); + RND_DAD_LABEL(ctx->dlg, "role/prio"); + ctx->conf.wsrc[5] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(data)"); + ctx->conf.wnatval[5] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: color"); + RND_DAD_LABEL(ctx->dlg, "role/prio"); + ctx->conf.wsrc[6] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(data)"); + ctx->conf.wnatval[6] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, "Data type: list of strings"); + ctx->conf.wsrc[7] = -1; + RND_DAD_TREE(ctx->dlg, 3, 0, hdr_nat); /* input state */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->conf.wnatval[7] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, "Data type: list of hash subtrees"); + ctx->conf.wsrc[8] = -1; + RND_DAD_TREE(ctx->dlg, 3, 0, hdr_nat); /* input state */ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->conf.wnatval[8] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(no conf node selected)"); + ctx->conf.wnatval[9] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); +} + +void pcb_dlg_pref_conf_create(pref_ctx_t *ctx) +{ + static const char *hdr_intree[] = {"role", "prio", "policy", "value", NULL}; + + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + ctx->conf.wmainp = RND_DAD_CURRENT(ctx->dlg); + + /* left: tree */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 1, 1, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->conf.wtree = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, dlg_conf_select_node_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + RND_DAD_STRING(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "Filter text:\nlist conf nodes with\nmatching name only"); + RND_DAD_CHANGE_CB(ctx->dlg, pcb_pref_dlg_conf_filter_cb); + ctx->conf.wfilter = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* right: details */ + RND_DAD_BEGIN_VPANE(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + /* right/top: conf file */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->conf.wname = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->conf.wdesc = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "INPUT: configuration node (\"file\" version)"); + RND_DAD_TREE(ctx->dlg, 4, 0, hdr_intree); /* input state */ + ctx->conf.wintree = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Edit selected..."); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_edit_cb); + RND_DAD_BUTTON(ctx->dlg, "Remove selected"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_del_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* right/bottom: native file */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, "NATIVE: in-memory conf node after the merge"); + build_natval(ctx); + + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + setup_tree(ctx); + setup_intree(ctx, NULL, 0); +} + +void pcb_dlg_pref_conf_open(pref_ctx_t *ctx, const char *tabarg) +{ + rnd_hid_attr_val_t hv; + hv.dbl = 0.25; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->conf.wmainp, &hv); + + if (tabarg != NULL) { + rnd_hid_attr_val_t hv; + hv.str = rnd_strdup(tabarg); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->conf.wfilter, &hv); + pcb_pref_dlg_conf_filter_cb(ctx->dlg_hid_ctx, ctx, &ctx->dlg[ctx->conf.wfilter]); + rnd_dad_tree_expcoll(&ctx->dlg[ctx->conf.wtree], NULL, 1, 1); + } +} + + Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_conf.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_conf.h (revision 33253) @@ -0,0 +1,19 @@ +#ifndef PCB_DLG_PREF_CONF_H +#define PCB_DLG_PREF_CONF_H + +#include + +typedef struct { + int wtree, wintree, wdesc, wname, wmainp, wnattype, wfilter; + int wnatval[RND_CFN_max+1], wsrc[RND_CFN_max+1]; + rnd_conf_native_t *selected_nat; + int selected_idx; +} pref_conf_t; + +void pcb_dlg_pref_conf_close(pref_ctx_t *ctx); +void pcb_dlg_pref_conf_create(pref_ctx_t *ctx); +void pcb_dlg_pref_conf_open(pref_ctx_t *ctx, const char *tabarg); + +void pcb_pref_dlg_conf_changed_cb(pref_ctx_t *ctx, rnd_conf_native_t *cfg, int arr_idx); /* global conf change */ + +#endif Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_confedit.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_confedit.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_confedit.c (revision 33253) @@ -0,0 +1,484 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, conf tree tab -> edit conf node (input side) popup */ + +#include + +#define is_read_only(ctx) rnd_conf_is_read_only(ctx->role) + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + + rnd_conf_native_t *nat; + int idx; + rnd_conf_role_t role; + + int wnewval, winsa; +} confedit_ctx_t; + +static void pref_conf_edit_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + pref_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + free(ctx); +} + +/* Returns true if the value being edited is not yet created in the conf tree */ +static int confedit_node_is_uninitialized(confedit_ctx_t *ctx) +{ + return (rnd_conf_lht_get_at(ctx->role, ctx->nat->hash_path, 0) == NULL); +} + +static void confedit_brd2dlg(confedit_ctx_t *ctx) +{ + rnd_hid_attr_val_t hv; + lht_node_t *nl, *nd = rnd_conf_lht_get_at(ctx->role, ctx->nat->hash_path, 1); + const char *val; + + if (ctx->idx >= ctx->nat->array_size) + return; /* shouldn't ever happen - we have checked this before creating the dialog! */ + + val = pref_conf_get_val(nd, ctx->nat, ctx->idx); + + switch(ctx->nat->type) { + case RND_CFN_STRING: + hv.str = val; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wnewval, &hv); + break; + case RND_CFN_BOOLEAN: + case RND_CFN_INTEGER: + hv.lng = atoi(val); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wnewval, &hv); + break; + case RND_CFN_REAL: + hv.dbl = strtod(val, NULL); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wnewval, &hv); + break; + case RND_CFN_COORD: + hv.crd = rnd_get_value(val, NULL, NULL, NULL); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wnewval, &hv); + break; + case RND_CFN_UNIT: + { + const rnd_unit_t *u = rnd_get_unit_struct(val); + if (u != NULL) + hv.lng = u - rnd_units; + else + hv.lng = -1; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wnewval, &hv); + } + break; + case RND_CFN_COLOR: + hv.clr = ctx->nat->val.color[ctx->idx]; + rnd_color_load_str(&hv.clr, val); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wnewval, &hv); + break; + case RND_CFN_LIST: + { + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wnewval]; + rnd_hid_tree_t *tree = attr->wdata; + + rnd_dad_tree_clear(tree); + if (nd->type != LHT_LIST) + return; + for(nl = nd->data.list.first; nl != NULL; nl = nl->next) { + char *cell[2] = {NULL}; + if (nl->type == LHT_TEXT) + cell[0] = rnd_strdup(nl->data.text.value); + rnd_dad_tree_append(attr, NULL, cell); + } + } + break; + case RND_CFN_HLIST: +/* rnd_message(RND_MSG_ERROR, "ERROR: can not import hash lists on GUI\n");*/ + /* Nothing to do, for now it's just a bunch of buttons */ + break; + case RND_CFN_max: + rnd_message(RND_MSG_ERROR, "ERROR: invalid conf node type\n"); + break; + } +} + +static void pref_conf_editval_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *trigger_attr) +{ + confedit_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr; + char buf[128]; + const char *val = buf; + + if (ctx->idx >= ctx->nat->array_size) + return; /* shouldn't ever happen - we have checked this before creating the dialog! */ + + attr = &ctx->dlg[ctx->wnewval]; + + switch(ctx->nat->type) { + case RND_CFN_STRING: val = attr->val.str; break; + case RND_CFN_BOOLEAN: + case RND_CFN_INTEGER: sprintf(buf, "%ld", attr->val.lng); break; + case RND_CFN_REAL: sprintf(buf, "%f", attr->val.dbl); break; + case RND_CFN_COORD: rnd_snprintf(buf, sizeof(buf), "%.08$mH", attr->val.crd); break; + case RND_CFN_UNIT: + if ((attr->val.lng < 0) || (attr->val.lng >= rnd_get_n_units(0))) + return; + val = rnd_units[attr->val.lng].suffix; + break; + case RND_CFN_COLOR: val = attr->val.clr.str; break; + case RND_CFN_LIST: + { + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wnewval]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + lht_node_t *nd = rnd_conf_lht_get_at(ctx->role, ctx->nat->hash_path, 0); + + if (nd == NULL) { + rnd_message(RND_MSG_ERROR, "Internal error: can't copy back to non-existing list!\n"); + return; + } + + if (nd->type != LHT_LIST) { + rnd_message(RND_MSG_ERROR, "Internal error: can't copy back list into non-list!\n"); + return; + } + + /* empty the list so that we insert to an empty list which is overwriting the list */ + while(nd->data.list.first != NULL) + lht_tree_del(nd->data.list.first); + + for(r = gdl_first(&tree->rows); r != NULL; r = gdl_next(&tree->rows, r)) { + lht_node_t *n = lht_dom_node_alloc(LHT_TEXT, NULL); + lht_dom_list_append(nd, n); + n->data.text.value = rnd_strdup(r->cell[0]); + } + rnd_conf_makedirty(ctx->role); + rnd_conf_update(ctx->nat->hash_path, ctx->idx); + } + return; + case RND_CFN_HLIST: + case RND_CFN_max: + return; + } + + if (val == NULL) + val = ""; + rnd_conf_set(ctx->role, ctx->nat->hash_path, ctx->idx, val, RND_POL_OVERWRITE); + + if ((ctx->role == RND_CFR_USER) || (ctx->role == RND_CFR_PROJECT)) + rnd_conf_save_file(&PCB->hidlib, NULL, (PCB == NULL ? NULL : PCB->hidlib.filename), ctx->role, NULL); + else if (ctx->role == RND_CFR_DESIGN) + pcb_board_set_changed_flag(PCB, 1); + + rnd_gui->invalidate_all(rnd_gui); +} + +static void pref_conf_editval_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *trigger_attr) +{ + confedit_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wnewval]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + + if (r != NULL) { + rnd_dad_tree_remove(attr, r); + pref_conf_editval_cb(hid_ctx, caller_data, trigger_attr); + } +} + +static void pref_conf_editval_edit(void *hid_ctx, confedit_ctx_t *ctx, rnd_hid_attribute_t *attr, rnd_hid_row_t *r) +{ + char *nv = rnd_hid_prompt_for(&PCB->hidlib, "list item value:", r->cell[0], "Edit config list item"); + if (nv == NULL) + return; + + if (rnd_dad_tree_modify_cell(attr, r, 0, rnd_strdup(nv)) == 0) + pref_conf_editval_cb(hid_ctx, ctx, attr); +} + +static void pref_conf_editval_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *trigger_attr) +{ + confedit_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wnewval]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + + if (r != NULL) + pref_conf_editval_edit(hid_ctx, ctx, attr, r); +} + +static void pref_conf_editval_ins_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *trigger_attr) +{ + confedit_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wnewval]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + char *cols[] = {NULL, NULL}; + + cols[0] = rnd_strdup(""); + + if (trigger_attr == &ctx->dlg[ctx->winsa]) + r = rnd_dad_tree_append(attr, r, cols); + else + r = rnd_dad_tree_insert(attr, r, cols); + if (r != NULL) + pref_conf_editval_edit(hid_ctx, ctx, attr, r); +} + +static void pref_conf_editval_hlist_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *trigger_attr) +{ + confedit_ctx_t *ctx = caller_data; + rnd_actionva(&PCB->hidlib, ctx->nat->gui_edit_act, + rnd_conf_role_name(ctx->role), ctx->nat->hash_path, trigger_attr->val.str, + NULL); +} + + +static void pref_conf_edit_dlg(rnd_conf_native_t *nat, long idx, rnd_conf_role_t role, rnd_conflist_t *hlist, rnd_bool modal) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + confedit_ctx_t *ctx; + int b[4] = {0}; + + ctx = calloc(sizeof(confedit_ctx_t), 1); + ctx->nat = nat; + ctx->idx = idx; + ctx->role = role; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_LABEL(ctx->dlg, ctx->nat->hash_path); + + switch(ctx->nat->type) { + case RND_CFN_STRING: + RND_DAD_STRING(ctx->dlg); + ctx->wnewval = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_cb); + b[0] = RND_DAD_CURRENT(ctx->dlg); + break; + case RND_CFN_BOOLEAN: + RND_DAD_BOOL(ctx->dlg); + ctx->wnewval = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_cb); + break; + case RND_CFN_INTEGER: + RND_DAD_INTEGER(ctx->dlg); + ctx->wnewval = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -(1<<30), +(1<<30)); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_cb); + b[0] = RND_DAD_CURRENT(ctx->dlg); + break; + case RND_CFN_REAL: + RND_DAD_REAL(ctx->dlg); + ctx->wnewval = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -(1<<30), +(1<<30)); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_cb); + b[0] = RND_DAD_CURRENT(ctx->dlg); + break; + case RND_CFN_COORD: + RND_DAD_COORD(ctx->dlg); + ctx->wnewval = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -RND_MM_TO_COORD(1000), +RND_MM_TO_COORD(1000)); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_cb); + b[0] = RND_DAD_CURRENT(ctx->dlg); + break; + case RND_CFN_UNIT: + RND_DAD_UNIT(ctx->dlg, 0x3fff); + ctx->wnewval = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_cb); + break; + case RND_CFN_COLOR: + RND_DAD_COLOR(ctx->dlg); + ctx->wnewval = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_cb); + break; + case RND_CFN_LIST: + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 1, 0, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wnewval = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_edit_cb); + b[0] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Del"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_del_cb); + b[1] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Insert before"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_ins_cb); + b[2] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Insert after"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_ins_cb); + b[3] = ctx->winsa = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + break; + case RND_CFN_HLIST: + { + gdl_iterator_t it; + rnd_conf_listitem_t *i; + + if (hlist == NULL) { + RND_DAD_LABEL(ctx->dlg, "ERROR: hlist not available"); + break; + } + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + rnd_conflist_foreach(hlist, &it, i) { + lht_node_t *rule = i->prop.src; + RND_DAD_BUTTON(ctx->dlg, rule->name); + RND_DAD_CHANGE_CB(ctx->dlg, pref_conf_editval_hlist_cb); + } + RND_DAD_END(ctx->dlg); + } + break; + case RND_CFN_max: + RND_DAD_LABEL(ctx->dlg, "ERROR: invalid conf node type"); + } + + if (is_read_only(ctx)) { + RND_DAD_LABEL(ctx->dlg, "NOTE: this value is read-only"); + RND_DAD_HELP(ctx->dlg, "Config value with this config role\ncan not be modified.\nPlease pick another config role\nand try to edit or create\nthe value there!\n(If that role has higher priority,\nthat value will override this one)"); + } + else if (confedit_node_is_uninitialized(ctx)) { + RND_DAD_LABEL(ctx->dlg, "NOTE: change the value to create the config node"); + RND_DAD_HELP(ctx->dlg, "This config node does not exist\non the selected role.\nTo create it, change the value.\nSpecial case for boolean values:\nto create an unticked value,\nfirst tick then untick the checkbox."); + } + + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + RND_DAD_NEW("pref_confedit", ctx->dlg, "pcb-rnd conf item", ctx, modal, pref_conf_edit_close_cb); + + if (is_read_only(ctx)) { + int n; + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wnewval, 0); + for(n = 0; n < sizeof(b) / sizeof(b[0]); n++) + if (b[n] != 0) + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, b[n], 0); + } + + + confedit_brd2dlg(ctx); +} + + +static void pref_conf_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *pctx = caller_data; + rnd_hid_row_t *r; + + if (pctx->conf.selected_nat == NULL) { + rnd_message(RND_MSG_ERROR, "You need to select a conf leaf node to edit\nTry the tree on the left.\n"); + return; + } + + r = rnd_dad_tree_get_selected(&pctx->dlg[pctx->conf.wintree]); + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "You need to select a role (upper right list)\n"); + return; + } + + if (pctx->conf.selected_idx >= pctx->conf.selected_nat->array_size) { + rnd_message(RND_MSG_ERROR, "Internal error: array index out of bounds\n"); + return; + } + + if (pctx->conf.selected_nat->type == RND_CFN_HLIST) { + if (pctx->conf.selected_nat->gui_edit_act == NULL) { + rnd_message(RND_MSG_ERROR, "ERROR: can not edit hash lists on GUI\n"); + return; + } + } + + pref_conf_edit_dlg(pctx->conf.selected_nat, pctx->conf.selected_idx, r->user_data2.lng, pctx->conf.selected_nat->val.list, rnd_false); +} + +const char pcb_acts_dlg_confval_edit[] = "dlg_confval_edit(path, idx, role, [modal])\n"; +const char pcb_acth_dlg_confval_edit[] = "Present a dialog box for editing the value of a conf node at path."; +fgw_error_t pcb_act_dlg_confval_edit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *path, *srole, *smodal = NULL; + rnd_bool modal; + long idx; + rnd_conf_native_t *nat; + rnd_conf_role_t role; + + RND_ACT_CONVARG(1, FGW_STR, dlg_confval_edit, path = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_LONG, dlg_confval_edit, idx = argv[2].val.nat_long); + RND_ACT_CONVARG(3, FGW_STR, dlg_confval_edit, srole = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, dlg_confval_edit, smodal = argv[4].val.str); + + nat = rnd_conf_get_field(path); + if (nat == NULL) { + rnd_message(RND_MSG_ERROR, "ERROR: no such config path: '%s'\n", path); + return -1; + } + + + modal = rnd_istrue(smodal); + role = rnd_conf_role_parse(srole); + if (role == RND_CFR_invalid) { + rnd_message(RND_MSG_ERROR, "ERROR: no such config role: '%s'\n", srole); + return -1; + } + + pref_conf_edit_dlg(nat, idx, role, NULL, modal); + RND_ACT_IRES(0); + return 0; +} + + +static void pref_conf_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *pctx = caller_data; + rnd_hid_row_t *r; + + if (pctx->conf.selected_nat == NULL) { + rnd_message(RND_MSG_ERROR, "You need to select a conf leaf node to remove\nTry the tree on the left.\n"); + return; + } + + r = rnd_dad_tree_get_selected(&pctx->dlg[pctx->conf.wintree]); + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "You need to select a role (upper right list)\n"); + return; + } + + if (pctx->conf.selected_idx >= pctx->conf.selected_nat->array_size) { + rnd_message(RND_MSG_ERROR, "Internal error: array index out of bounds\n"); + return; + } + + if (rnd_conf_is_read_only(r->user_data2.lng)) { + rnd_message(RND_MSG_ERROR, "Role is read-only, can not remove item\n"); + return; + } + + rnd_conf_del(r->user_data2.lng, pctx->conf.selected_nat->hash_path, pctx->conf.selected_idx); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_general.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_general.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_general.c (revision 33253) @@ -0,0 +1,93 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, general tab */ + +#include "dlg_pref.h" + +static pref_confitem_t perf_topwin[] = { + {"Alternate window layout to\nallow smaller size", "appearance/compact", 0, NULL}, + {NULL, NULL, 0} +}; + +static pref_confitem_t perf_backup[] = { + {"Save unsaved layout to\nPCB.%i.save at exit", "editor/save_in_tmp", 0, NULL}, + {"Seconds between auto backups\n(set to zero to disable auto backups)", "rc/backup_interval", 0, NULL}, + {NULL, NULL, 0} +}; + +static pref_confitem_t perf_cli[] = { + {"Number of commands to\nremember in the\nhistory list", "plugins/hid_gtk/history_size", 0, NULL}, + {NULL, NULL, 0} +}; + +static void pref_general_dlg2conf(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + + if (pref_dlg2conf_pre(ctx) == NULL) + return; + + pcb_pref_dlg2conf_table(ctx, perf_topwin, attr); + pcb_pref_dlg2conf_table(ctx, perf_backup, attr); + pcb_pref_dlg2conf_table(ctx, perf_cli, attr); + + pref_dlg2conf_post(ctx); +} + +void pcb_dlg_pref_general_close(pref_ctx_t *ctx) +{ + pcb_pref_conflist_remove(ctx, perf_topwin); + pcb_pref_conflist_remove(ctx, perf_backup); + pcb_pref_conflist_remove(ctx, perf_cli); +} + +void pcb_dlg_pref_general_create(pref_ctx_t *ctx) +{ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, "Top window layout"); + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + pcb_pref_create_conftable(ctx, perf_topwin, 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, "Backup"); + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + pcb_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); + pcb_pref_create_conftable(ctx, perf_cli, pref_general_dlg2conf); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_general.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_general.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_general.h (revision 33253) @@ -0,0 +1,12 @@ +#ifndef PCB_DLG_PREF_GENERAL_H +#define PCB_DLG_PREF_GENERAL_H + +typedef struct { + int dummy; +} pref_general_t; + +void pcb_dlg_pref_general_close(pref_ctx_t *ctx); +void pcb_dlg_pref_general_create(pref_ctx_t *ctx); + + +#endif Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_key.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_key.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_key.c (revision 33253) @@ -0,0 +1,259 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, key translation tab */ + +#include "dlg_pref.h" +#include +#include "conf_core.h" +#include +#include + +static void pref_key_brd2dlg(pref_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *row, *r; + rnd_conf_native_t *nat = rnd_conf_get_field("editor/translate_key"); + char *cursor_path = NULL, *cell[3]; + gdl_iterator_t it; + rnd_conf_listitem_t *kt; + + if ((pref_ctx.key.lock) || (!pref_ctx.active)) + return; + + attr = &ctx->dlg[ctx->key.wlist]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if ((r != NULL) && (nat != NULL)) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + if (nat == NULL) + return; + + /* add all items */ + rnd_conflist_foreach(nat->val.list, &it, kt) { + cell[0] = rnd_strdup(kt->name); + cell[1] = rnd_strdup(kt->payload); + row = rnd_dad_tree_append(attr, NULL, cell); + row->user_data = kt; + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->menu.wlist, &hv); + free(cursor_path); + } +} + +static lht_node_t *pref_key_mod_pre(pref_ctx_t *ctx) +{ +/* rnd_hid_attribute_t *attr = &ctx->dlg[ctx->key.wlist]; + rnd_hid_tree_t *tree = attr->wdata;*/ + lht_node_t *lst, *m; + rnd_conf_role_t save; + + save = ctx->role; + ctx->role = RND_CFR_USER; + m = pref_dlg2conf_pre(ctx); + if (m == NULL) { + ctx->role = save; + return NULL; + } + + ctx->key.lock++; + /* get the list and clean it */ + + lst = lht_tree_path_(m->doc, m, "editor/translate_key", 1, 0, NULL); + if (lst == NULL) + rnd_conf_set(RND_CFR_USER, "editor/translate_key", 0, "", RND_POL_OVERWRITE); + lst = lht_tree_path_(m->doc, m, "editor/translate_key", 1, 0, NULL); + ctx->role = save; + + assert(lst != NULL); + return lst; +} + +static void pref_key_mod_post(pref_ctx_t *ctx) +{ +/* rnd_hid_attribute_t *attr = &ctx->dlg[ctx->key.wlist]; + rnd_hid_tree_t *tree = attr->wdata;*/ + rnd_conf_role_t save; + + save = ctx->role; + ctx->role = RND_CFR_USER; + + rnd_conf_update("editor/translate_key", -1); + rnd_conf_makedirty(ctx->role); /* low level lht_dom_node_alloc() wouldn't make user config to be saved! */ + + pref_dlg2conf_post(ctx); + + ctx->role = save; + ctx->key.lock--; +} + + +void pcb_dlg_pref_key_open(pref_ctx_t *ctx) +{ + pref_key_brd2dlg(ctx); +} + +static void pref_key_remove(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *battr) +{ + rnd_hid_attribute_t *attr = &pref_ctx.dlg[pref_ctx.key.wlist]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r, *row = rnd_dad_tree_get_selected(attr); + lht_node_t *nd, *lst = pref_key_mod_pre(&pref_ctx); + + if ((row == NULL) || (lst == NULL)) + return; + + for(nd = lst->data.list.first, r = gdl_first(&tree->rows); r != NULL; r = gdl_next(&tree->rows, r), nd = nd->next) { + if (r == row) { + rnd_dad_tree_remove(attr, r); + lht_tree_del(nd); + break; + } + } + + pref_key_mod_post(&pref_ctx); +} + +/*** key detector GUI ***/ + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int wkdesc, wtdesc; +} kd_ctx_t; + +static kd_ctx_t kd; + +void dummy_expose_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ +} + +rnd_bool key_press_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_bool release, rnd_hid_cfg_mod_t mods, unsigned short int key_raw, unsigned short int key_tr) +{ + rnd_hid_attr_val_t hv; + char *desc; + + if (release) + return 0; + + desc = rnd_hid_cfg_keys_gen_desc(mods, key_raw, 0); + if (desc == NULL) { +/* Can't do this yet because mods are passed on too: + rnd_message(RND_MSG_ERROR, "Failed to recognize that key (%d %d)\n", key_raw, key_tr);*/ + return 0; + } + hv.str = desc; + rnd_gui->attr_dlg_set_value(kd.dlg_hid_ctx, kd.wkdesc, &hv); + + free(desc); + return 0; +} + +static void pref_key_append(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *battr) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"add", 0}, {NULL, 0}}; + rnd_hid_attribute_t *attr = &pref_ctx.dlg[pref_ctx.key.wlist]; + lht_node_t *nd, *lst = pref_key_mod_pre(&pref_ctx); + rnd_box_t vbox = {0, 0, RND_MM_TO_COORD(55), RND_MM_TO_COORD(55)}; + int res; + + if (lst == NULL) + return; + + RND_DAD_BEGIN_VBOX(kd.dlg); + RND_DAD_COMPFLAG(kd.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(kd.dlg); + RND_DAD_LABEL(kd.dlg, "Key pressed:"); + RND_DAD_STRING(kd.dlg); + kd.wkdesc = RND_DAD_CURRENT(kd.dlg); + RND_DAD_HELP(kd.dlg, "Enter a key description here\nTypical examples: t or Altw\nOr use the key detection box on the right"); + RND_DAD_PREVIEW(kd.dlg, dummy_expose_cb, NULL, key_press_cb, NULL, &vbox, 20, 20, NULL); + RND_DAD_COMPFLAG(kd.dlg, RND_HATF_FRAME); + RND_DAD_HELP(kd.dlg, "Click here then press a key and it will be filled in automatically"); + RND_DAD_END(kd.dlg); + RND_DAD_BEGIN_HBOX(kd.dlg); + RND_DAD_LABEL(kd.dlg, "Translated to:"); + RND_DAD_STRING(kd.dlg); + kd.wtdesc = RND_DAD_CURRENT(kd.dlg); + RND_DAD_HELP(kd.dlg, "Enter a key description here\nTypical examples: t or |"); + RND_DAD_END(kd.dlg); + RND_DAD_BUTTON_CLOSES(kd.dlg, clbtn); + RND_DAD_END(kd.dlg); + + RND_DAD_NEW("pref_key_set", kd.dlg, "set key translation", NULL, rnd_true, NULL); + res = RND_DAD_RUN(kd.dlg); + + if (res == 0) { + const char *k1 = kd.dlg[kd.wkdesc].val.str, *k2 = kd.dlg[kd.wtdesc].val.str; + char *cell[3]; + + cell[0] = rnd_strdup(k1); + cell[1] = rnd_strdup(k2); + cell[2] = NULL; + rnd_dad_tree_append(attr, NULL, cell); + + nd = lht_dom_node_alloc(LHT_TEXT, k1); + nd->data.text.value = rnd_strdup(k2); + lht_dom_list_append(lst, nd); + } + + pref_key_mod_post(&pref_ctx); + + RND_DAD_FREE(kd.dlg); +} + + +void pcb_dlg_pref_key_create(pref_ctx_t *ctx) +{ + static const char *hdr[] = {"pressed", "translated to", NULL}; + + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_SCROLL | RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 3, 0, hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + ctx->key.wlist = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Remove"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_key_remove); + RND_DAD_BUTTON(ctx->dlg, "Add new..."); + RND_DAD_CHANGE_CB(ctx->dlg, pref_key_append); + RND_DAD_END(ctx->dlg); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_key.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_key.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_key.h (revision 33253) @@ -0,0 +1,11 @@ +#ifndef PCB_DLG_PREF_KEY_H +#define PCB_DLG_PREF_KEY_H + +typedef struct { + int wlist; + int lock; +} pref_key_t; + +void pcb_dlg_pref_key_create(pref_ctx_t *ctx); + +#endif Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_layer.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_layer.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_layer.c (revision 33253) @@ -0,0 +1,61 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, board tab */ + +#include "dlg_pref.h" +#include +#include "conf_core.h" +#include "stub_draw.h" + +#define RND_EMPTY(a) ((a) ? (a) : "") + + +void layersel_expose_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + pcb_stub_draw_csect(gc, e); +} + +rnd_bool layersel_mouse_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + return pcb_stub_draw_csect_mouse_ev(kind, x, y); +} + +void layersel_free_cb(rnd_hid_attribute_t *attrib, void *user_ctx, void *hid_ctx) +{ +} + +void pcb_dlg_pref_layer_create(pref_ctx_t *ctx) +{ + rnd_box_t vbox = {0, 0, RND_MM_TO_COORD(150), RND_MM_TO_COORD(150)}; + + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_PREVIEW(ctx->dlg, layersel_expose_cb, layersel_mouse_cb, NULL, layersel_free_cb, &vbox, 200, 200, ctx); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_lib.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_lib.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_lib.c (revision 33253) @@ -0,0 +1,481 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, library tab */ + +#include +#include "dlg_pref.h" +#include +#include "conf_core.h" +#include + +static const char *SRC_BRD = ""; + +static void libhelp_btn(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); + +static void pref_lib_update_buttons(void) +{ + rnd_hid_attribute_t *attr = &pref_ctx.dlg[pref_ctx.lib.wlist]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + int en = (r != NULL); + + rnd_gui->attr_dlg_widget_state(pref_ctx.dlg_hid_ctx, pref_ctx.lib.wedit, en); + rnd_gui->attr_dlg_widget_state(pref_ctx.dlg_hid_ctx, pref_ctx.lib.wremove, en); + rnd_gui->attr_dlg_widget_state(pref_ctx.dlg_hid_ctx, pref_ctx.lib.wmoveup, en); + rnd_gui->attr_dlg_widget_state(pref_ctx.dlg_hid_ctx, pref_ctx.lib.wmovedown, en); +} + +static void pref_lib_select_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + pref_lib_update_buttons(); +} + +static void pref_lib_row_free(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + free(row->cell[0]); + free(row->cell[1]); + free(row->cell[2]); + row->cell[0] = row->cell[1] = row->cell[2] = NULL; +} + +/* Current libraries from config to dialog box: remove everything from + the widget first */ +static void pref_lib_conf2dlg_pre(rnd_conf_native_t *cfg, int arr_idx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + + if ((pref_ctx.lib.lock) || (!pref_ctx.active)) + return; + + attr = &pref_ctx.dlg[pref_ctx.lib.wlist]; + tree = attr->wdata; + + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) { + free(pref_ctx.lib.cursor_path); + pref_ctx.lib.cursor_path = rnd_strdup(r->cell[0]); + } + + /* remove all existing entries */ + for(r = gdl_first(&tree->rows); r != NULL; r = gdl_first(&tree->rows)) { + rnd_dad_tree_remove(attr, r); + } +} + +static const char *pref_node_src(lht_node_t *nd) +{ + if (nd->file_name != NULL) + return nd->file_name; + return rnd_conf_role_name(rnd_conf_lookup_role(nd)); +} + +/* Current libraries from config to dialog box: after the change, fill + in all widget rows from the conf */ +static void pref_lib_conf2dlg_post(rnd_conf_native_t *cfg, int arr_idx) +{ + rnd_conf_listitem_t *i; + int idx; + const char *s; + char *cell[4]; + rnd_hid_attribute_t *attr; + rnd_hid_attr_val_t hv; + + if ((pref_ctx.lib.lock) || (!pref_ctx.active)) + return; + + attr = &pref_ctx.dlg[pref_ctx.lib.wlist]; + + /* copy everything from the config tree to the dialog */ + rnd_conf_loop_list_str(&conf_core.rc.library_search_paths, i, s, idx) { + char *tmp; + cell[0] = rnd_strdup(i->payload); + rnd_path_resolve(&PCB->hidlib, cell[0], &tmp, 0, rnd_false); + cell[1] = rnd_strdup(tmp == NULL ? "" : tmp); + cell[2] = rnd_strdup(pref_node_src(i->prop.src)); + cell[3] = NULL; + rnd_dad_tree_append(attr, NULL, cell); + } + + hv.str = pref_ctx.lib.cursor_path; + if (rnd_gui->attr_dlg_set_value(pref_ctx.dlg_hid_ctx, pref_ctx.lib.wlist, &hv) == 0) { + free(pref_ctx.lib.cursor_path); + pref_ctx.lib.cursor_path = NULL; + } + pref_lib_update_buttons(); +} + +/* Dialog box to current libraries in config */ +static void pref_lib_dlg2conf(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + rnd_hid_tree_t *tree = attr->wdata; + lht_node_t *m, *lst, *nd; + rnd_hid_row_t *r; + + + m = pref_dlg2conf_pre(ctx); + if (m == NULL) + return; + + ctx->lib.lock++; + /* get the list and clean it */ + + lst = lht_tree_path_(m->doc, m, "rc/library_search_paths", 1, 0, NULL); + if (lst == NULL) + rnd_conf_set(ctx->role, "rc/library_search_paths", 0, "", RND_POL_OVERWRITE); + lst = lht_tree_path_(m->doc, m, "rc/library_search_paths", 1, 0, NULL); + assert(lst != NULL); + lht_tree_list_clean(lst); + + /* append items from the widget */ + for(r = gdl_first(&tree->rows); r != NULL; r = gdl_next(&tree->rows, r)) { + nd = lht_dom_node_alloc(LHT_TEXT, ""); + nd->data.text.value = rnd_strdup(r->cell[0]); + nd->doc = m->doc; + lht_dom_list_append(lst, nd); + rnd_dad_tree_modify_cell(attr, r, 2, rnd_strdup(pref_node_src(nd))); + } + + rnd_conf_update("rc/library_search_paths", -1); + rnd_conf_makedirty(ctx->role); /* low level lht_dom_node_alloc() wouldn't make user config to be saved! */ + + pref_dlg2conf_post(ctx); + + ctx->lib.lock--; +} + +static void lib_btn_remove(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + rnd_hid_attribute_t *attr = &pref_ctx.dlg[pref_ctx.lib.wlist]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + + if (r == NULL) + return; + + if (rnd_dad_tree_remove(attr, r) == 0) { + pref_lib_dlg2conf(hid_ctx, caller_data, attr); + pref_lib_update_buttons(); + } +} + +static void lib_btn_up(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + rnd_hid_attribute_t *attr = &pref_ctx.dlg[pref_ctx.lib.wlist]; + rnd_hid_row_t *prev, *r = rnd_dad_tree_get_selected(attr); + rnd_hid_tree_t *tree = attr->wdata; + char *cell[4]; + + if (r == NULL) + return; + + prev = gdl_prev(&tree->rows, r); + if (prev == NULL) + return; + + cell[0] = rnd_strdup(r->cell[0]); /* have to copy because this is also the primary key (path for the hash) */ + cell[1] = r->cell[1]; r->cell[1] = NULL; + cell[2] = r->cell[2]; r->cell[2] = NULL; + cell[3] = NULL; + if (rnd_dad_tree_remove(attr, r) == 0) { + rnd_hid_attr_val_t hv; + rnd_dad_tree_insert(attr, prev, cell); + pref_lib_dlg2conf(hid_ctx, caller_data, attr); + hv.str = cell[0]; + rnd_gui->attr_dlg_set_value(pref_ctx.dlg_hid_ctx, pref_ctx.lib.wlist, &hv); + } +} + +static void lib_btn_down(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + rnd_hid_attribute_t *attr = &pref_ctx.dlg[pref_ctx.lib.wlist]; + rnd_hid_row_t *next, *r = rnd_dad_tree_get_selected(attr); + rnd_hid_tree_t *tree = attr->wdata; + char *cell[4]; + + if (r == NULL) + return; + + next = gdl_next(&tree->rows, r); + if (next == NULL) + return; + + cell[0] = rnd_strdup(r->cell[0]); /* have to copy because this is also the primary key (path for the hash) */ + cell[1] = r->cell[1]; r->cell[1] = NULL; + cell[2] = r->cell[2]; r->cell[2] = NULL; + cell[3] = NULL; + if (rnd_dad_tree_remove(attr, r) == 0) { + rnd_hid_attr_val_t hv; + rnd_dad_tree_append(attr, next, cell); + pref_lib_dlg2conf(hid_ctx, caller_data, attr); + hv.str = cell[0]; + rnd_gui->attr_dlg_set_value(pref_ctx.dlg_hid_ctx, pref_ctx.lib.wlist, &hv); + } +} + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int wpath, wexp; + pref_ctx_t *pctx; +} cell_edit_ctx_t; + +static void lib_cell_edit_update(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + cell_edit_ctx_t *ctx = caller_data; + char *tmp; + + rnd_path_resolve(&PCB->hidlib, ctx->dlg[ctx->wpath].val.str, &tmp, 0, rnd_true); + if (tmp != NULL) + RND_DAD_SET_VALUE(hid_ctx, ctx->wexp, str, tmp); +} + +static int lib_cell_edit(pref_ctx_t *pctx, char **cell) +{ + cell_edit_ctx_t ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"ok", 0}, {NULL, 0}}; + + memset(&ctx, 0, sizeof(ctx)); + ctx.pctx = pctx; + + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_BEGIN_TABLE(ctx.dlg, 2); + RND_DAD_LABEL(ctx.dlg, "Path:"); + RND_DAD_STRING(ctx.dlg); + ctx.wpath = RND_DAD_CURRENT(ctx.dlg); + ctx.dlg[ctx.wpath].val.str = rnd_strdup(cell[0]); + RND_DAD_CHANGE_CB(ctx.dlg, lib_cell_edit_update); + + RND_DAD_LABEL(ctx.dlg, "Expanded\nversion:"); + RND_DAD_LABEL(ctx.dlg, rnd_strdup(cell[1])); + ctx.wexp = RND_DAD_CURRENT(ctx.dlg); + ctx.dlg[ctx.wexp].val.str = rnd_strdup(cell[1]); + + RND_DAD_LABEL(ctx.dlg, ""); + RND_DAD_BUTTON(ctx.dlg, "Help..."); + RND_DAD_CHANGE_CB(ctx.dlg, libhelp_btn); + RND_DAD_END(ctx.dlg); + RND_DAD_BUTTON_CLOSES(ctx.dlg, clbtn); + RND_DAD_END(ctx.dlg); + + RND_DAD_NEW("pref_lib_path", ctx.dlg, "Edit library path", &ctx, rnd_true, NULL); + if (RND_DAD_RUN(ctx.dlg) != 0) { + RND_DAD_FREE(ctx.dlg); + return -1; + } + + free(cell[0]); + cell[0] = rnd_strdup(RND_EMPTY(ctx.dlg[ctx.wpath].val.str)); + free(cell[1]); + cell[1] = rnd_strdup(RND_EMPTY(ctx.dlg[ctx.wexp].val.str)); + + RND_DAD_FREE(ctx.dlg); + return 0; +} + +static void lib_btn_insert(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr, int pos) +{ + pref_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr = &pref_ctx.dlg[pref_ctx.lib.wlist]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + char *cell[4]; + + if (r == NULL) { + rnd_hid_tree_t *tree = attr->wdata; + + switch(pos) { + case 0: /* replace */ + rnd_message(RND_MSG_ERROR, "need to select a library path row first\n"); + return; + + case -1: /* before */ + r = gdl_first(&tree->rows); + break; + case +1: /* after */ + r = gdl_last(&tree->rows); + break; + } + } + + if (pos != 0) { + cell[0] = rnd_strdup(""); + cell[1] = rnd_strdup(""); + cell[2] = rnd_strdup(SRC_BRD); + } + else { + cell[0] = rnd_strdup(r->cell[0]); + cell[1] = rnd_strdup(r->cell[1]); + cell[2] = rnd_strdup(r->cell[2]); + } + cell[3] = NULL; + + if (lib_cell_edit(ctx, cell) != 0) { + free(cell[0]); + free(cell[1]); + free(cell[2]); + return; + } + + switch(pos) { + case -1: /* before */ + rnd_dad_tree_insert(attr, r, cell); + break; + case +1: /* after */ + rnd_dad_tree_append(attr, r, cell); + break; + case 0: /* replace */ + rnd_dad_tree_modify_cell(attr, r, 0, cell[0]); + rnd_dad_tree_modify_cell(attr, r, 1, cell[1]); + rnd_dad_tree_modify_cell(attr, r, 2, cell[2]); + break; + } + pref_lib_dlg2conf(hid_ctx, caller_data, attr); +} + +static void lib_btn_insert_before(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + lib_btn_insert(hid_ctx, caller_data, btn_attr, -1); +} + +static void lib_btn_insert_after(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + lib_btn_insert(hid_ctx, caller_data, btn_attr, +1); +} + +static void lib_btn_edit(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *btn_attr) +{ + lib_btn_insert(hid_ctx, caller_data, btn_attr, 0); +} + +void pcb_dlg_pref_lib_close(pref_ctx_t *ctx) +{ + if (ctx->lib.help.active) + RND_DAD_FREE(ctx->lib.help.dlg); +} + +static void pref_libhelp_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ +/* pref_libhelp_ctx_t *ctx = caller_data;*/ +} + +static void pref_libhelp_open(pref_libhelp_ctx_t *ctx) +{ + htsp_entry_t *e; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + if (ctx->active) + return; + + RND_DAD_LABEL(ctx->dlg, "The following $(variables) can be used in the path:"); + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + rnd_conf_fields_foreach(e) { + rnd_conf_native_t *nat = e->value; + char tmp[256]; + + if (strncmp(e->key, "rc/path/", 8) != 0) + continue; + + rnd_snprintf(tmp, sizeof(tmp), "$(rc.path.%s)", e->key + 8); + RND_DAD_LABEL(ctx->dlg, tmp); + RND_DAD_LABEL(ctx->dlg, nat->val.string[0] == NULL ? "" : nat->val.string[0]); + } + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + ctx->active = 1; + RND_DAD_NEW("pref_lib_path_help", ctx->dlg, "pcb-rnd preferences: library help", ctx, rnd_true, pref_libhelp_close_cb); + + RND_DAD_RUN(ctx->dlg); + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(pref_libhelp_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void libhelp_btn(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_libhelp_open(&pref_ctx.lib.help); +} + +void pcb_dlg_pref_lib_create(pref_ctx_t *ctx) +{ + static const char *hdr[] = {"configured path", "actual path on the filesystem", "config source", NULL}; + rnd_hid_tree_t *tree; + + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); /* get the parent vbox, which is the tab's page vbox, to expand and fill */ + + RND_DAD_LABEL(ctx->dlg, "Ordered list of footprint library search directories."); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_SCROLL | RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 3, 0, hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + ctx->lib.wlist = RND_DAD_CURRENT(ctx->dlg); + tree = ctx->dlg[ctx->lib.wlist].wdata; + tree->user_free_cb = pref_lib_row_free; + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, pref_lib_select_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Move up"); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_up); + ctx->lib.wmoveup = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Move down"); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_down); + ctx->lib.wmovedown = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Insert before"); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_insert_before); + RND_DAD_BUTTON(ctx->dlg, "Insert after"); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_insert_after); + RND_DAD_BUTTON(ctx->dlg, "Remove"); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_remove); + ctx->lib.wremove = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Edit..."); + RND_DAD_CHANGE_CB(ctx->dlg, lib_btn_edit); + ctx->lib.wedit = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Help..."); + ctx->lib.whsbutton = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, libhelp_btn); + RND_DAD_END(ctx->dlg); + +} + +void pcb_dlg_pref_lib_open(pref_ctx_t *ctx) +{ + rnd_conf_native_t *cn = rnd_conf_get_field("rc/library_search_paths"); + pref_lib_conf2dlg_post(cn, -1); +} + +void pcb_dlg_pref_lib_init(pref_ctx_t *ctx) +{ + static rnd_conf_hid_callbacks_t cbs_spth; + rnd_conf_native_t *cn = rnd_conf_get_field("rc/library_search_paths"); + + if (cn != NULL) { + memset(&cbs_spth, 0, sizeof(rnd_conf_hid_callbacks_t)); + cbs_spth.val_change_pre = pref_lib_conf2dlg_pre; + cbs_spth.val_change_post = pref_lib_conf2dlg_post; + rnd_conf_hid_set_cb(cn, pref_hid, &cbs_spth); + } +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_lib.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_lib.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_lib.h (revision 33253) @@ -0,0 +1,22 @@ +#ifndef PCB_DLG_PREF_LIB_H +#define PCB_DLG_PREF_LIB_H + +typedef struct pref_libhelp_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ +} pref_libhelp_ctx_t; + +typedef struct { + int wlist, whsbutton, wmoveup, wmovedown, wedit, wremove; + int lock; /* a change in on the dialog box causes a change on the board but this shouldn't in turn casue a changein the dialog */ + char *cursor_path; + pref_libhelp_ctx_t help; +} pref_lib_t; + +void pcb_dlg_pref_lib_close(pref_ctx_t *ctx); +void pcb_dlg_pref_lib_create(pref_ctx_t *ctx); +void pcb_dlg_pref_lib_init(pref_ctx_t *ctx); +void pcb_dlg_pref_lib_open(pref_ctx_t *ctx); + + +#endif Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_menu.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_menu.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_menu.c (revision 33253) @@ -0,0 +1,226 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, menu tab */ + +#include "dlg_pref.h" +#include +#include + +extern conf_dialogs_t dialogs_conf; +extern void pcb_wplc_save_to_role(rnd_conf_role_t role); +extern int pcb_wplc_save_to_file(const char *fn); + +#define GET_ROW(ctx) \ + rnd_hid_attribute_t *lattr= &((pref_ctx_t *)ctx)->dlg[((pref_ctx_t *)ctx)->menu.wlist]; \ + rnd_hid_row_t *r = rnd_dad_tree_get_selected(lattr); \ + +#define GET_ROW_AND_MENU(ctx) \ + GET_ROW(ctx) \ + rnd_menu_patch_t *m; \ + if (r == NULL) {rnd_message(RND_MSG_ERROR, "Select a menu file first\n"); return; } \ + m = r->user_data; \ + if (m == NULL) {rnd_message(RND_MSG_ERROR, "Invalid menu file selection\n"); return; } \ + +/* Update button states: disable or enable them depending on what kind of + menu patch row is selected from the list */ +static void pref_menu_btn_update(pref_ctx_t *ctx) +{ + rnd_menu_patch_t *m; + GET_ROW(ctx); + + if ((r == NULL) || (r->user_data == NULL)) { + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->menu.wunload, 0); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->menu.wreload, 0); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->menu.wexport, 0); + return; + } + + m = r->user_data; + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->menu.wunload, 1); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->menu.wreload, m->has_file); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->menu.wexport, 1); +} + +static void pref_menu_brd2dlg(pref_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cursor_path = NULL, *cell[6]; + long n; + + attr = &ctx->dlg[ctx->menu.wlist]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + for(n = 0; n < rnd_menu_sys.patches.used; n++) { + rnd_menu_patch_t *m = rnd_menu_sys.patches.array[n]; + rnd_hid_row_t *row; + const char *fn = m->cfg.doc->root->file_name; + + cell[0] = rnd_strdup_printf("%ld", m->uid); + cell[1] = rnd_strdup((n == 0 ? "base " : "addon")); + cell[2] = rnd_strdup_printf("%d", m->prio); + cell[3] = rnd_strdup_printf("%s", m->cookie); + cell[4] = rnd_strdup_printf("%s", fn == NULL ? "" : fn); + cell[5] = NULL; + + row = rnd_dad_tree_append(attr, NULL, cell); + row->user_data = m; + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->menu.wlist, &hv); + free(cursor_path); + } + pref_menu_btn_update(ctx); +} + +void pcb_dlg_pref_menu_open(pref_ctx_t *ctx) +{ + pref_menu_brd2dlg(ctx); +} + +void pcb_dlg_pref_menu_close(pref_ctx_t *ctx) +{ +} + +static void menu_select(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_attr_val_t hv; + rnd_hid_tree_t *tree = attrib->wdata; + pref_ctx_t *ctx = tree->user_ctx; + rnd_menu_patch_t *m; + + if ((row == NULL) || (row->user_data == NULL)) { + hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->menu.wdesc, &hv); + return; + } + + m = row->user_data; + hv.str = m->desc == NULL ? "" : m->desc; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->menu.wdesc, &hv); + + pref_menu_btn_update(ctx); +} + + + +static void pref_menu_load(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + char *fn = rnd_gui->fileselect(rnd_gui, "menu patch load", "Load a menu patch to file", "menu_patch.lht", "lht", NULL, "menu_patch_load", RND_HID_FSD_READ, NULL); + if (fn == NULL) + return; + if (rnd_hid_menu_load(rnd_gui, NULL, "preferences", 300, fn, 1, NULL, "User reuqested load through the preferences dialog") == NULL) + rnd_message(RND_MSG_ERROR, "Failed to load/parse menu file '%s' - menu file not loaded\n", fn); + free(fn); +} + +static void pref_menu_unload(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + GET_ROW_AND_MENU(caller_data); + rnd_hid_menu_unload_patch(rnd_gui, m); +} + +static void pref_menu_reload(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + const char *fn; + GET_ROW_AND_MENU(caller_data); + + fn = m->cfg.doc->root->file_name; + rnd_hid_menu_merge_inhibit_inc(); + if (rnd_hid_menu_load(rnd_gui, NULL, m->cookie, m->prio, fn, 1, NULL, m->desc) == NULL) + rnd_message(RND_MSG_ERROR, "Failed to load/parse menu file '%s' - menu file not reloaded\n", fn); + else + rnd_hid_menu_unload_patch(rnd_gui, m); + rnd_hid_menu_merge_inhibit_dec(); +} + +static void pref_menu_export(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + FILE *f; + char *fn; + GET_ROW_AND_MENU(caller_data); + + fn = rnd_gui->fileselect(rnd_gui, "menu patch export", "Export a menu patch to file for debugging", "menu_patch.lht", "lht", NULL, "menu_patch_export", RND_HID_FSD_MAY_NOT_EXIST, NULL); + if (fn == NULL) + return; + + f = rnd_fopen(NULL, fn, "w"); + lht_dom_export(m->cfg.doc->root, f, ""); + fclose(f); + free(fn); +} + +#define NONPERS "\nNon-persistent: the file not will be loaded automatically\nafter pcb-rnd is restarted" + +void pcb_dlg_pref_menu_create(pref_ctx_t *ctx) +{ + static const char *hdr[] = {"uid", "type", "prio", "cookie", "file name", NULL}; + + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 5, 0, hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->menu.wlist = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, menu_select); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Description:"); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->menu.wdesc = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Load..."); + ctx->menu.wload = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, pref_menu_load); + RND_DAD_HELP(ctx->dlg, "Load a new menu (patch) file" NONPERS); + RND_DAD_BUTTON(ctx->dlg, "Unload"); + ctx->menu.wunload = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, pref_menu_unload); + RND_DAD_HELP(ctx->dlg, "Remove the selected menu (patch) from the menu system" NONPERS); + RND_DAD_BUTTON(ctx->dlg, "Reload"); + ctx->menu.wreload = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, pref_menu_reload); + RND_DAD_HELP(ctx->dlg, "Reload the menu file from disk\nand re-merge the menu system"); + RND_DAD_BUTTON(ctx->dlg, "Export..."); + ctx->menu.wexport = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, pref_menu_export); + RND_DAD_HELP(ctx->dlg, "Export menu file to disk\n(useful for debuggin)"); + RND_DAD_END(ctx->dlg); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_menu.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_menu.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_menu.h (revision 33253) @@ -0,0 +1,10 @@ +#ifndef PCB_DLG_PREF_MENU_H +#define PCB_DLG_PREF_MENU_H + +typedef struct { + int wlist, wdesc, wload, wunload, wreload, wexport; +} pref_menu_t; + +void pcb_dlg_pref_menu_create(pref_ctx_t *ctx); + +#endif Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_sizes.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_sizes.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_sizes.c (revision 33253) @@ -0,0 +1,170 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, sizes tab */ + +#include "board.h" +#include "dlg_pref.h" +#include +#include "conf_core.h" +#include "drc.h" + +/* Actual board size to dialog box */ +static void pref_sizes_brd2dlg(pref_ctx_t *ctx) +{ + if (ctx->sizes.lock) + return; + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->sizes.wwidth, crd, PCB->hidlib.size_x); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->sizes.wheight, crd, PCB->hidlib.size_y); +} + +/* Dialog box to actual board size */ +static void pref_sizes_dlg2brd(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + + ctx->sizes.lock++; + if ((PCB->hidlib.size_x != ctx->dlg[ctx->sizes.wwidth].val.crd) || (PCB->hidlib.size_y != ctx->dlg[ctx->sizes.wheight].val.crd)) + pcb_board_resize(ctx->dlg[ctx->sizes.wwidth].val.crd, ctx->dlg[ctx->sizes.wheight].val.crd, 0); + ctx->sizes.lock--; +} + +static void drc_rules_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&PCB->hidlib, attr->user_data, NULL); +} + +static pref_confitem_t limit_sizes[] = { + {"Minimum copper spacing", "design/bloat", 0, NULL}, + {"Minimum copper width", "design/min_wid", 0, NULL}, + {"Minimum silk width", "design/min_slk", 0, NULL}, + {NULL, NULL, 0} +}; + +static void pref_sizes_limit_dlg2conf(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + + if (pref_dlg2conf_pre(ctx) == NULL) + return; + + pcb_pref_dlg2conf_table(ctx, limit_sizes, attr); + + pref_dlg2conf_post(ctx); +} + +static void pref_isle_brd2dlg(rnd_conf_native_t *cfg, int arr_idx) +{ + if ((pref_ctx.sizes.lock) || (!pref_ctx.active)) + return; + RND_DAD_SET_VALUE(pref_ctx.dlg_hid_ctx, pref_ctx.sizes.wisle, dbl, conf_core.design.poly_isle_area / 1000000.0); +} + +static void pref_isle_dlg2brd(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + double v = ctx->dlg[ctx->sizes.wisle].val.dbl * 1000000.0; + + ctx->sizes.lock++; + rnd_conf_setf(ctx->role, "design/poly_isle_area", -1, "%f", v); + ctx->sizes.lock--; +} + +void pcb_dlg_pref_sizes_close(pref_ctx_t *ctx) +{ + pcb_pref_conflist_remove(ctx, limit_sizes); +} + +void pcb_dlg_pref_sizes_create(pref_ctx_t *ctx) +{ + pcb_drc_impl_t *di; + int drcs; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, "Board size"); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Width="); + RND_DAD_COORD(ctx->dlg); + ctx->sizes.wwidth = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, RND_MM_TO_COORD(1), RND_MAX_COORD); + RND_DAD_DEFAULT_NUM(ctx->dlg, PCB->hidlib.size_x); + RND_DAD_CHANGE_CB(ctx->dlg, pref_sizes_dlg2brd); + RND_DAD_LABEL(ctx->dlg, "Height="); + RND_DAD_COORD(ctx->dlg); + ctx->sizes.wheight = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, RND_MM_TO_COORD(1), RND_MAX_COORD); + RND_DAD_DEFAULT_NUM(ctx->dlg, PCB->hidlib.size_y); + RND_DAD_CHANGE_CB(ctx->dlg, pref_sizes_dlg2brd); + 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, "Limiting sizes (not DRC)"); + RND_DAD_LABEL(ctx->dlg, "(Used when the code needs to figure the absolute global smallest value)"); + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + pcb_pref_create_conftable(ctx, limit_sizes, pref_sizes_limit_dlg2conf); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + RND_DAD_LABEL(ctx->dlg, "polygon isle minimum size\n[square um]"); + RND_DAD_REAL(ctx->dlg); + ctx->sizes.wisle = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, 0, RND_MAX_COORD); + ctx->dlg[ctx->sizes.wisle].val.dbl = (conf_core.design.poly_isle_area / 1000000.0); + RND_DAD_CHANGE_CB(ctx->dlg, pref_isle_dlg2brd); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, "Configure DRC rules:"); + for(di = gdl_first(&pcb_drc_impls), drcs = 0; di != NULL; di = di->link.next, drcs++) { + char *ra = rnd_strdup(di->list_rules_action); /* need to strdup it just in case the plugin is unloaded while the preferences dialog is open */ + vtp0_append(&ctx->auto_free, ra); + RND_DAD_BUTTON(ctx->dlg, di->name); + RND_DAD_HELP(ctx->dlg, di->desc); + RND_DAD_SET_ATTR_FIELD(ctx->dlg, user_data, ra); + RND_DAD_CHANGE_CB(ctx->dlg, drc_rules_cb); + } + if (drcs == 0) + RND_DAD_LABEL(ctx->dlg, "ERROR: no DRC plugins available"); + RND_DAD_END(ctx->dlg); +} + +void pcb_dlg_pref_sizes_init(pref_ctx_t *ctx) +{ + static rnd_conf_hid_callbacks_t cbs_isle; + rnd_conf_native_t *cn = rnd_conf_get_field("design/poly_isle_area"); + + if (cn != NULL) { + memset(&cbs_isle, 0, sizeof(rnd_conf_hid_callbacks_t)); + cbs_isle.val_change_post = pref_isle_brd2dlg; + rnd_conf_hid_set_cb(cn, pref_hid, &cbs_isle); + } +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_sizes.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_sizes.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_sizes.h (revision 33253) @@ -0,0 +1,15 @@ +#ifndef PCB_DLG_PREF_SIZES_H +#define PCB_DLG_PREF_SIZES_H + +typedef struct { + int wwidth, wheight; + int wisle; + int lock; /* a change in on the dialog box causes a change on the board but this shouldn't in turn casue a changein the dialog */ +} pref_sizes_t; + +void pcb_dlg_pref_sizes_close(pref_ctx_t *ctx); +void pcb_dlg_pref_sizes_create(pref_ctx_t *ctx); +void pcb_dlg_pref_sizes_init(pref_ctx_t *ctx); + + +#endif Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_win.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_win.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_win.c (revision 33253) @@ -0,0 +1,197 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Preferences dialog, window geometry tab */ + +#include "dlg_pref.h" +#include +#include "conf_core.h" +#include +#include + +extern conf_dialogs_t dialogs_conf; +extern void pcb_wplc_save_to_role(rnd_conf_role_t role); +extern int pcb_wplc_save_to_file(const char *fn); + +static void pref_win_brd2dlg(pref_ctx_t *ctx) +{ + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->win.wmaster, lng, rnd_conf.editor.auto_place); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->win.wboard, lng, dialogs_conf.plugins.dialogs.auto_save_window_geometry.to_design); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->win.wproject, lng, dialogs_conf.plugins.dialogs.auto_save_window_geometry.to_project); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->win.wuser, lng, dialogs_conf.plugins.dialogs.auto_save_window_geometry.to_user); +} + +void pcb_dlg_pref_win_open(pref_ctx_t *ctx) +{ + pref_win_brd2dlg(ctx); +} + +void pcb_dlg_pref_win_close(pref_ctx_t *ctx) +{ +} + +static void pref_win_master_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + rnd_conf_setf(ctx->role, "editor/auto_place", -1, "%d", attr->val.lng); + pref_win_brd2dlg(ctx); +} + +static void pref_win_board_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + rnd_conf_setf(ctx->role, "plugins/dialogs/auto_save_window_geometry/to_design", -1, "%d", attr->val.lng); + pref_win_brd2dlg(ctx); +} + +static void pref_win_project_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + + if (pref_dlg2conf_pre(ctx) == NULL) + return; + + rnd_conf_setf(ctx->role, "plugins/dialogs/auto_save_window_geometry/to_project", -1, "%d", attr->val.lng); + + pref_dlg2conf_post(ctx); + + pref_win_brd2dlg(ctx); +} + +static void pref_win_user_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pref_ctx_t *ctx = caller_data; + rnd_conf_setf(ctx->role, "plugins/dialogs/auto_save_window_geometry/to_user", -1, "%d", attr->val.lng); + pref_win_brd2dlg(ctx); +} + + +static void pref_win_board_now_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_wplc_save_to_role(RND_CFR_USER); +} + +static void pref_win_project_now_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_wplc_save_to_role(RND_CFR_USER); +} + +static void pref_win_user_now_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_wplc_save_to_role(RND_CFR_USER); +} + +static void pref_win_file_now_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + char *fname; + + fname = rnd_gui->fileselect(rnd_gui, "Save window geometry to...", + "Pick a file for saving window geometry to.\n", + "win_geo.lht", ".lht", NULL, "wingeo", RND_HID_FSD_MAY_NOT_EXIST, NULL); + + if (fname == NULL) + return; + + if (pcb_wplc_save_to_file(fname) != 0) + rnd_message(RND_MSG_ERROR, "Error saving window geometry to '%s'\n", fname); +} + + +void pcb_dlg_pref_win_create(pref_ctx_t *ctx) +{ + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, "Load window geometry and enable window placement:"); + RND_DAD_BOOL(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "When enabled, pcb-rnd will load window geometry from config files\nand try to resize and place windows accordingly.\nSizes can be saved once (golden arrangement)\nor at every exit (retrain last setup),\nsee below."); + ctx->win.wmaster = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, pref_win_master_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ctx->dlg, "Save window geometry to..."); + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "... in the design (board) file"); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "now"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_win_board_now_cb); + RND_DAD_LABEL(ctx->dlg, "before close:"); + RND_DAD_BOOL(ctx->dlg); + ctx->win.wboard = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, pref_win_board_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "... in the project file"); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "now"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_win_project_now_cb); + RND_DAD_LABEL(ctx->dlg, "before close:"); + RND_DAD_BOOL(ctx->dlg); + ctx->win.wproject = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, pref_win_project_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "... in the user config"); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "now"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_win_user_now_cb); + RND_DAD_LABEL(ctx->dlg, "before close:"); + RND_DAD_BOOL(ctx->dlg); + ctx->win.wuser = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, pref_win_user_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "... in a custom file"); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "now"); + RND_DAD_CHANGE_CB(ctx->dlg, pref_win_file_now_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_pref_win.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_pref_win.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_pref_win.h (revision 33253) @@ -0,0 +1,10 @@ +#ifndef PCB_DLG_PREF_WIN_H +#define PCB_DLG_PREF_WIN_H + +typedef struct { + int wmaster, wboard, wproject, wuser; +} pref_win_t; + +void pcb_dlg_pref_win_create(pref_ctx_t *ctx); + +#endif Index: tags/2.3.0/src_plugins/dialogs/dlg_printcalib.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_printcalib.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_printcalib.c (revision 33253) @@ -0,0 +1,59 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +static rnd_hid_attribute_t printer_calibrate_attrs[] = { + {"Enter Values here:", "", + RND_HATT_LABEL, 0, 0, {0, 0, 0}, 0, 0}, + {"x-calibration", "X scale for calibrating your printer", + RND_HATT_REAL, 0.5, 25, {0, 0, 1.00}, 0, 0}, + {"y-calibration", "Y scale for calibrating your printer", + RND_HATT_REAL, 0.5, 25, {0, 0, 1.00}, 0, 0} +}; + +const char pcb_acts_PrintCalibrate[] = "PrintCalibrate()"; +const char pcb_acth_PrintCalibrate[] = "Calibrate the printer."; +/* DOC: printcalibrate.html */ +fgw_error_t pcb_act_PrintCalibrate(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_hid_t *printer = rnd_hid_find_printer(); + + if (printer == NULL) { + rnd_message(RND_MSG_ERROR, "No printer available\n"); + RND_ACT_IRES(1); + return 0; + } + printer->calibrate(printer, 0.0, 0.0); + + if (rnd_attribute_dialog("printer_calibrate", printer_calibrate_attrs, 3, "Printer Calibration Values", NULL)) + return 1; + printer->calibrate(printer, printer_calibrate_attrs[1].val.dbl, printer_calibrate_attrs[2].val.dbl); + RND_ACT_IRES(0); + return 0; +} Index: tags/2.3.0/src_plugins/dialogs/dlg_test.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_test.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_test.c (revision 33253) @@ -0,0 +1,542 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "board.h" +#include "obj_text.h" +#include +#include + +static const char dlg_test_syntax[] = "dlg_test()\n"; +static const char dlg_test_help[] = "test the attribute dialog"; + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int wtab, tt, wprog, whpane, wvpane, wtxt, wtxtpos, wtxtro; + int ttctr, wclr, txtro; + int wspin_int, wspout_int, wspin_double, wspout_double, wspin_coord, wspout_coord; +} test_t; + + +static void pcb_act_attr_chg(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void pcb_act_spin_reset(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void pcb_act_spin_upd(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_tab_chg(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_jump(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_color_print(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_color_reset(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_ttbl_insert(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_ttbl_append(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_ttbl_jump(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_ttbl_filt(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_ttbl_select(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_ttbl_row_selected(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row); +static void cb_ttbl_free_row(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row); +static void cb_pane_set(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_text_replace(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_text_insert(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_text_append(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_text_get(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_text_edit(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_text_offs(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); +static void cb_text_ro(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); + +static void prv_expose(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e); +static rnd_bool prv_mouse(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y); + +static const char * test_xpm[] = { +"8 8 4 1", +" c None", +"+ c #550000", +"@ c #ff0000", +"# c #00ff00", +" +##+ ", +" +##+ ", +" ++@@++ ", +" +@ @+ ", +" +@##@+ ", +" +@ @+ ", +" ++@@++ ", +" ++++ " +}; + + +static int attr_idx, attr_idx2; +static fgw_error_t pcb_act_dlg_test(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *vals[] = { "foo", "bar", "baz", NULL }; + const char *tabs[] = { "original test", "new test", "tree-table", "pane", "preview", "text", NULL }; + char *row1[] = {"one", "foo", "FOO", NULL}; + char *row2[] = {"two", "bar", "BAR", NULL}; + char *row2b[] = {"under_two", "ut", "uuut", NULL}; + char *row3[] = {"three", "baz", "BAZ", NULL}; + const char *hdr[] = {"num", "data1", "data2", NULL}; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"ok", 0}, {NULL, 0}}; + rnd_hid_row_t *row; + int failed; + + test_t ctx; + memset(&ctx, 0, sizeof(ctx)); + + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(ctx.dlg, tabs); + RND_DAD_CHANGE_CB(ctx.dlg, cb_tab_chg); + ctx.wtab = RND_DAD_CURRENT(ctx.dlg); + + /* tab 0: "original test" */ + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "text1"); + RND_DAD_BEGIN_TABLE(ctx.dlg, 3); + RND_DAD_LABEL(ctx.dlg, "text2a"); + RND_DAD_LABEL(ctx.dlg, "text2b"); + RND_DAD_LABEL(ctx.dlg, "text2c"); + RND_DAD_LABEL(ctx.dlg, "text2d"); + RND_DAD_END(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "text3"); + + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ctx.dlg, "spin test"); + RND_DAD_BUTTON(ctx.dlg, "reset all to 42"); + RND_DAD_CHANGE_CB(ctx.dlg, pcb_act_spin_reset); + + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "INT:"); + RND_DAD_SPIN_INT(ctx.dlg); + ctx.wspin_int = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_DEFAULT_NUM(ctx.dlg, 42); + RND_DAD_CHANGE_CB(ctx.dlg, pcb_act_spin_upd); + RND_DAD_LABEL(ctx.dlg, "->"); + RND_DAD_LABEL(ctx.dlg, "n/a"); + ctx.wspout_int = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_END(ctx.dlg); + + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "DBL:"); + RND_DAD_SPIN_DOUBLE(ctx.dlg); + ctx.wspin_double = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_DEFAULT_NUM(ctx.dlg, 42); + RND_DAD_CHANGE_CB(ctx.dlg, pcb_act_spin_upd); + RND_DAD_LABEL(ctx.dlg, "->"); + RND_DAD_LABEL(ctx.dlg, "n/a"); + ctx.wspout_double = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_END(ctx.dlg); + + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "CRD:"); + RND_DAD_SPIN_COORD(ctx.dlg); + ctx.wspin_coord = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_DEFAULT_NUM(ctx.dlg, RND_MM_TO_COORD(42)); + RND_DAD_CHANGE_CB(ctx.dlg, pcb_act_spin_upd); + RND_DAD_LABEL(ctx.dlg, "->"); + RND_DAD_LABEL(ctx.dlg, "n/a"); + ctx.wspout_coord = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_END(ctx.dlg); + + RND_DAD_END(ctx.dlg); + + RND_DAD_ENUM(ctx.dlg, vals); + RND_DAD_CHANGE_CB(ctx.dlg, pcb_act_attr_chg); + attr_idx = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_INTEGER(ctx.dlg); + RND_DAD_MINVAL(ctx.dlg, 1); + RND_DAD_MAXVAL(ctx.dlg, 10); + RND_DAD_DEFAULT_NUM(ctx.dlg, 3); + RND_DAD_CHANGE_CB(ctx.dlg, pcb_act_attr_chg); + attr_idx2 = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_BUTTON(ctx.dlg, "update!"); + RND_DAD_CHANGE_CB(ctx.dlg, pcb_act_attr_chg); + RND_DAD_END(ctx.dlg); + + /* tab 1: "new test" */ + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "new test."); + RND_DAD_PICTURE(ctx.dlg, test_xpm); + RND_DAD_BUTTON(ctx.dlg, "jump to the first tab"); + RND_DAD_CHANGE_CB(ctx.dlg, cb_jump); + RND_DAD_PICBUTTON(ctx.dlg, test_xpm); + RND_DAD_CHANGE_CB(ctx.dlg, cb_color_reset); + RND_DAD_COLOR(ctx.dlg); + RND_DAD_CHANGE_CB(ctx.dlg, cb_color_print); + ctx.wclr = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_END(ctx.dlg); + + + /* tab 2: tree table widget */ + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx.dlg, 3, 1, hdr); + ctx.tt = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_SCROLL); + RND_DAD_CHANGE_CB(ctx.dlg, cb_ttbl_select); + RND_DAD_TREE_SET_CB(ctx.dlg, free_cb, cb_ttbl_free_row); + RND_DAD_TREE_SET_CB(ctx.dlg, selected_cb, cb_ttbl_row_selected); + RND_DAD_TREE_APPEND(ctx.dlg, NULL, row1); + row = RND_DAD_TREE_APPEND(ctx.dlg, NULL, row2); + RND_DAD_TREE_APPEND_UNDER(ctx.dlg, row, row2b); + RND_DAD_TREE_APPEND(ctx.dlg, NULL, row3); + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_BUTTON(ctx.dlg, "insert row"); + RND_DAD_CHANGE_CB(ctx.dlg, cb_ttbl_insert); + RND_DAD_BUTTON(ctx.dlg, "append row"); + RND_DAD_CHANGE_CB(ctx.dlg, cb_ttbl_append); + RND_DAD_BUTTON(ctx.dlg, "jump!"); + RND_DAD_CHANGE_CB(ctx.dlg, cb_ttbl_jump); + RND_DAD_BOOL(ctx.dlg); + RND_DAD_CHANGE_CB(ctx.dlg, cb_ttbl_filt); + RND_DAD_END(ctx.dlg); + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_PROGRESS(ctx.dlg); + ctx.wprog = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_END(ctx.dlg); + RND_DAD_END(ctx.dlg); + + /* tab 3: pane */ + RND_DAD_BEGIN_HPANE(ctx.dlg); + ctx.whpane = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "left1"); + RND_DAD_LABEL(ctx.dlg, "left2"); + RND_DAD_END(ctx.dlg); + RND_DAD_BEGIN_VPANE(ctx.dlg); + ctx.wvpane = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "right top1"); + RND_DAD_LABEL(ctx.dlg, "right top2"); + RND_DAD_END(ctx.dlg); + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, "right bottom1"); + RND_DAD_LABEL(ctx.dlg, "right bottom2"); + RND_DAD_BUTTON(ctx.dlg, "set all to 30%"); + RND_DAD_CHANGE_CB(ctx.dlg, cb_pane_set); + RND_DAD_END(ctx.dlg); + RND_DAD_END(ctx.dlg); + RND_DAD_END(ctx.dlg); + + /* tab 4: preview */ + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_PREVIEW(ctx.dlg, prv_expose, prv_mouse, NULL, NULL, NULL, 200, 200, NULL); + RND_DAD_LABEL(ctx.dlg, "This is a cool preview widget."); + RND_DAD_END(ctx.dlg); + + /* tab 5: text */ + RND_DAD_BEGIN_VBOX(ctx.dlg); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_TEXT(ctx.dlg, NULL); + RND_DAD_COMPFLAG(ctx.dlg, RND_HATF_SCROLL | RND_HATF_EXPFILL); + RND_DAD_CHANGE_CB(ctx.dlg, cb_text_edit); + ctx.wtxt = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_LABEL(ctx.dlg, ""); + ctx.wtxtpos = RND_DAD_CURRENT(ctx.dlg); + RND_DAD_BUTTON(ctx.dlg, "half the offset"); + RND_DAD_CHANGE_CB(ctx.dlg, cb_text_offs); + RND_DAD_END(ctx.dlg); + RND_DAD_BEGIN_HBOX(ctx.dlg); + RND_DAD_BUTTON(ctx.dlg, "replace"); + RND_DAD_CHANGE_CB(ctx.dlg, cb_text_replace); + RND_DAD_BUTTON(ctx.dlg, "insert"); + RND_DAD_CHANGE_CB(ctx.dlg, cb_text_insert); + RND_DAD_BUTTON(ctx.dlg, "append"); + RND_DAD_CHANGE_CB(ctx.dlg, cb_text_append); + RND_DAD_BUTTON(ctx.dlg, "get"); + RND_DAD_CHANGE_CB(ctx.dlg, cb_text_get); + RND_DAD_BUTTON(ctx.dlg, "ro"); + ctx.txtro = 0; + RND_DAD_CHANGE_CB(ctx.dlg, cb_text_ro); + RND_DAD_END(ctx.dlg); + RND_DAD_END(ctx.dlg); + + RND_DAD_END(ctx.dlg); + RND_DAD_BUTTON_CLOSES(ctx.dlg, clbtn); + RND_DAD_END(ctx.dlg); + + RND_DAD_AUTORUN("dlg_test", ctx.dlg, "attribute dialog test", &ctx, failed); + + if (failed != 0) + rnd_message(RND_MSG_WARNING, "Test dialog cancelled"); + + RND_DAD_FREE(ctx.dlg); + + RND_ACT_IRES(0); + return 0; +} + +static void pcb_act_attr_chg(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + static rnd_hid_attr_val_t val; + static rnd_bool st; + printf("Chg\n"); + + st = !st; + val.lng = (val.lng + 1) % 3; +/* rnd_gui->attr_dlg_widget_state(hid_ctx, attr_idx, st);*/ + + rnd_gui->attr_dlg_set_value(hid_ctx, attr_idx, &val); +} + +static void pcb_act_spin_reset(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attr_val_t hv; + + hv.lng = 42; + hv.dbl = 42.0; + hv.crd = RND_MM_TO_COORD(42); + + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wspin_int, &hv); + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wspin_double, &hv); + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wspin_coord, &hv); +} + +static void pcb_act_spin_upd(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attr_val_t hv; + char tmp[256]; + + hv.str = tmp; + + sprintf(tmp, "%ld", ctx->dlg[ctx->wspin_int].val.lng); + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wspout_int, &hv); + sprintf(tmp, "%f", ctx->dlg[ctx->wspin_double].val.dbl); + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wspout_double, &hv); + rnd_snprintf(tmp, sizeof(tmp), "%mm\n%ml", ctx->dlg[ctx->wspin_coord].val.crd, ctx->dlg[ctx->wspin_coord].val.crd); + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wspout_coord, &hv); +} + + +static void cb_tab_chg(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + printf("Tab switch to %ld!\n", ctx->dlg[ctx->wtab].val.lng); +} + +static void cb_jump(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_attr_val_t val; + test_t *ctx = caller_data; + + printf("Jumping tabs\n"); + val.lng = 0; + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wtab, &val); +} + +static void cb_ttbl_insert(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attribute_t *treea = &ctx->dlg[ctx->tt]; + char *rowdata[] = {NULL, "ins", "dummy", NULL}; + rnd_hid_row_t *new_row, *row = rnd_dad_tree_get_selected(treea); + rnd_hid_attr_val_t val; + + rowdata[0] = rnd_strdup_printf("dyn_%d", ctx->ttctr++); + new_row = rnd_dad_tree_insert(treea, row, rowdata); + new_row->user_data2.lng = 1; + + val.dbl = (double)ctx->ttctr / 20.0; + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wprog, &val); +} + +static void cb_ttbl_append(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attribute_t *treea = &ctx->dlg[ctx->tt]; + char *rowdata[] = {NULL, "app", "dummy", NULL}; + rnd_hid_row_t *new_row, *row = rnd_dad_tree_get_selected(treea); + rnd_hid_attr_val_t val; + + rowdata[0] = rnd_strdup_printf("dyn_%d", ctx->ttctr++); + new_row = rnd_dad_tree_append(treea, row, rowdata); + new_row->user_data2.lng = 1; + + val.dbl = (double)ctx->ttctr / 20.0; + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wprog, &val); +} + +static void cb_ttbl_jump(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attr_val_t val; + + val.str = "two/under_two"; + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->tt, &val); +} + +static void ttbl_filt(gdl_list_t *list, int hide) +{ + rnd_hid_row_t *r; + for(r = gdl_first(list); r != NULL; r = gdl_next(list, r)) { + if (r->user_data2.lng) + r->hide = hide; + ttbl_filt(&r->children, hide); + } +} + +static void cb_ttbl_filt(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attribute_t *treea = &ctx->dlg[ctx->tt]; + rnd_hid_tree_t *tree = treea->wdata; + + ttbl_filt(&tree->rows, attr->val.lng); + rnd_dad_tree_update_hide(treea); +} + +/* table level selection */ +static void cb_ttbl_select(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hid_row_t *row = rnd_dad_tree_get_selected(attr); + if (attr->val.str != NULL) + rnd_trace("tt tbl selected: path=%s row=%p '%s'\n", attr->val.str, row, row->cell[0]); + else + rnd_trace("tt tbl selected: \n"); +} + +/* row level selection */ +static void cb_ttbl_row_selected(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + if (row != NULL) + rnd_trace("tt row selected: row=%p '%s'\n", row, row->cell[0]); + else + rnd_trace("tt row selected: \n"); +} + +static void cb_ttbl_free_row(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + if (row->user_data2.lng) + free(row->cell[0]); +} + +static void cb_pane_set(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attr_val_t val; + + val.dbl = 0.3; + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->whpane, &val); + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wvpane, &val); +} + +static void cb_text_replace(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + txt->hid_set_text(atxt, hid_ctx, RND_HID_TEXT_REPLACE, "Hello\nworld!\n"); +} + +static void cb_text_insert(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + txt->hid_set_text(atxt, hid_ctx, RND_HID_TEXT_INSERT, "ins"); +} + +static void cb_text_append(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + txt->hid_set_text(atxt, hid_ctx, RND_HID_TEXT_APPEND | RND_HID_TEXT_MARKUP, "appred\n"); +} + +static void cb_text_get(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + char *s; + s = txt->hid_get_text(atxt, hid_ctx); + printf("text: '%s'\n", s); + free(s); +} + +static void cb_text_edit(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_text_t *txt = attr->wdata; + long x, y, o; + char buf[256]; + rnd_hid_attr_val_t val; + + txt->hid_get_xy(attr, hid_ctx, &x, &y); + o = txt->hid_get_offs(attr, hid_ctx); + sprintf(buf, "cursor after edit: line %ld col %ld offs %ld", y, x, o); + val.str = buf; + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wtxtpos, &val); +} + +static void cb_text_offs(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + txt->hid_set_offs(atxt, hid_ctx, txt->hid_get_offs(atxt, hid_ctx) / 2); +} + +static void cb_text_ro(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + ctx->txtro = !ctx->txtro; + txt->hid_set_readonly(atxt, hid_ctx, ctx->txtro); +} + +static void prv_expose(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + rnd_render->set_color(gc, rnd_color_red); + pcb_text_draw_string_simple(NULL, "foo", RND_MM_TO_COORD(1), RND_MM_TO_COORD(20), 5.0, 5.0, 10.0, 0, 0, 0, 0, 0); + + printf("expose in dlg_test!\n"); +} + + +static rnd_bool prv_mouse(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + rnd_printf("Mouse %d %mm %mm\n", kind, x, y); + return (kind == RND_HID_MOUSE_PRESS) || (kind == RND_HID_MOUSE_RELEASE); +} + +static void cb_color_print(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + + printf("currenct color: #%02x%02x%02x\n", + ctx->dlg[ctx->wclr].val.clr.r, ctx->dlg[ctx->wclr].val.clr.g, ctx->dlg[ctx->wclr].val.clr.b); +} + +static void cb_color_reset(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + test_t *ctx = caller_data; + rnd_hid_attr_val_t val; + + rnd_color_load_str(&val.clr, "#005599"); + rnd_gui->attr_dlg_set_value(hid_ctx, ctx->wclr, &val); +} + Index: tags/2.3.0/src_plugins/dialogs/dlg_undo.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_undo.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_undo.c (revision 33253) @@ -0,0 +1,191 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include "event.h" +#include "undo.h" + +const char *dlg_undo_cookie = "undo dialog"; + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int wlist; + long serial; /* last seen undo serial, for updating the dialog on change */ + int active; /* already open - allow only one instance */ +} undo_ctx_t; + +undo_ctx_t undo_ctx; + +extern uundo_list_t pcb_uundo; + +static void undo_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + undo_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(undo_ctx_t)); +} + +static void cb_undo(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_undo(rnd_true); +} + +static void cb_redo(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_redo(rnd_true); +} + +static void cb_clear(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_undo_clear_list(rnd_true); +} + + +static void undo_data2dlg(undo_ctx_t *ctx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[4], *cursor_path = NULL; + uundo_item_t *i; + char *payload, buff[8192], mark[2], ser[64]; + + attr = &ctx->dlg[ctx->wlist]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + mark[1] = '\0'; + cell[3] = NULL; + for(i = pcb_uundo.head; i != NULL; i = i->next) { + payload = ""; + if (i->oper->item_print != NULL) { + i->oper->item_print(i->udata, buff, sizeof(buff)); + payload = buff; + } + mark[0] = '\0'; + if ((i == pcb_uundo.head) && (i == pcb_uundo.tail)) + mark[0] = '*'; + else if (i == pcb_uundo.head) + mark[0] = 'h'; + else if (i == pcb_uundo.tail) + mark[0] = 't'; + sprintf(ser, "%ld", (long)i->serial); + cell[0] = rnd_strdup(ser); + cell[1] = rnd_strdup(mark); + cell[2] = rnd_strdup(payload); + rnd_dad_tree_append(attr, NULL, cell); + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlist, &hv); + free(cursor_path); + } +} + +static void pcb_dlg_undo(void) +{ + static const char *hdr[] = {"serial", "flg", "operation", NULL}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + if (undo_ctx.active) + return; /* do not open another */ + + RND_DAD_BEGIN_VBOX(undo_ctx.dlg); + RND_DAD_COMPFLAG(undo_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(undo_ctx.dlg, 3, 0, hdr); + RND_DAD_COMPFLAG(undo_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + undo_ctx.wlist = RND_DAD_CURRENT(undo_ctx.dlg); + + RND_DAD_BEGIN_HBOX(undo_ctx.dlg); + RND_DAD_BUTTON(undo_ctx.dlg, "Undo"); + RND_DAD_CHANGE_CB(undo_ctx.dlg, cb_undo); + RND_DAD_BUTTON(undo_ctx.dlg, "Redo"); + RND_DAD_CHANGE_CB(undo_ctx.dlg, cb_redo); + RND_DAD_BUTTON(undo_ctx.dlg, "Clear"); + RND_DAD_CHANGE_CB(undo_ctx.dlg, cb_clear); + RND_DAD_END(undo_ctx.dlg); + RND_DAD_BUTTON_CLOSES(undo_ctx.dlg, clbtn); + RND_DAD_END(undo_ctx.dlg); + + /* set up the context */ + undo_ctx.active = 1; + + RND_DAD_DEFSIZE(undo_ctx.dlg, 300, 400); + RND_DAD_NEW("undo", undo_ctx.dlg, "pcb-rnd undo list", &undo_ctx, rnd_false, undo_close_cb); + undo_data2dlg(&undo_ctx); +} + +static const char pcb_acts_UndoDialog[] = "UndoDialog()\n"; +static const char pcb_acth_UndoDialog[] = "Open the undo dialog."; +static fgw_error_t pcb_act_UndoDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_dlg_undo(); + RND_ACT_IRES(0); + return 0; +} + +/* update the dialog after an undo operation */ +static void pcb_dlg_undo_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + undo_ctx_t *ctx = user_data; + if (!ctx->active) + return; + undo_data2dlg(ctx); +} + +/* Check if the serial has changed and update the dialog if so */ +static void pcb_dlg_undo_ev_chk(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + undo_ctx_t *ctx = user_data; + if (!ctx->active) + return; + if (ctx->serial != pcb_uundo.serial) { + undo_data2dlg(ctx); + ctx->serial = pcb_uundo.serial; + } +} + + +static void pcb_dlg_undo_init(void) +{ + rnd_event_bind(PCB_EVENT_UNDO_POST, pcb_dlg_undo_ev, &undo_ctx, dlg_undo_cookie); + rnd_event_bind(RND_EVENT_USER_INPUT_POST, pcb_dlg_undo_ev_chk, &undo_ctx, dlg_undo_cookie); +} + +static void pcb_dlg_undo_uninit(void) +{ + rnd_event_unbind_allcookie(dlg_undo_cookie); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_view.c =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_view.c (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_view.c (revision 33253) @@ -0,0 +1,850 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include +#include "board.h" +#include "conf_core.h" +#include +#include "view.h" +#include "draw.h" +#include "drc.h" +#include "actions_pcb.h" +#include +#include +#include +#include +#include "undo.h" +#include +#include + +static const char *dlg_view_cookie = "dlg_drc"; + +typedef struct view_ctx_s view_ctx_t; +struct view_ctx_s { + RND_DAD_DECL_NOINIT(dlg) + pcb_board_t *pcb; + pcb_view_list_t *lst; + pcb_view_list_t lst_local; + int alloced, active; + + void (*refresh)(view_ctx_t *ctx); + + unsigned long int selected; + + int wpos, wlist, wcount, wprev, wdescription, wmeasure; + int wbtn_cut; + + unsigned list_alloced:1; +}; + +view_ctx_t view_ctx; + +static void view_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + view_ctx_t *ctx = caller_data; + + RND_DAD_FREE(ctx->dlg); + if (ctx->list_alloced) { + pcb_view_list_free(ctx->lst); + ctx->lst = NULL; + } + if (ctx->alloced) + free(ctx); + else + ctx->active = 0; +} + +static void view2dlg_list(view_ctx_t *ctx) +{ + pcb_view_t *v; + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[3], *cursor_path = NULL; + + attr = &ctx->dlg[ctx->wlist]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + cell[2] = NULL; + for(v = pcb_view_list_first(ctx->lst); v != NULL; v = pcb_view_list_next(v)) { + rnd_hid_row_t *r, *rt; + rt = htsp_get(&tree->paths, v->type); + if (rt == NULL) { + cell[0] = rnd_strdup(v->type); + cell[1] = rnd_strdup(""); + rt = rnd_dad_tree_append(attr, NULL, cell); + rt->user_data2.lng = 0; + } + + cell[0] = rnd_strdup_printf("%lu", v->uid); + cell[1] = rnd_strdup(v->title); + r = rnd_dad_tree_append_under(attr, rt, cell); + r->user_data2.lng = v->uid; + rnd_dad_tree_expcoll(attr, rt, 1, 0); + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wlist, &hv); + free(cursor_path); + } +} + +static void view2dlg_pos(view_ctx_t *ctx) +{ + long cnt; + + pcb_view_by_uid_cnt(ctx->lst, ctx->selected, &cnt); + if (cnt >= 0) { + char tmp[32]; + sprintf(tmp, "%ld", cnt+1); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wpos, str, rnd_strdup(tmp)); + } + else + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wpos, str, rnd_strdup("")); +} + +static void view2dlg_count(view_ctx_t *ctx) +{ + char tmp[32]; + + sprintf(tmp, "%ld", (long)pcb_view_list_length(ctx->lst)); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wcount, str, rnd_strdup(tmp)); +} + +static void view2dlg(view_ctx_t *ctx) +{ + view2dlg_count(ctx); + + if (ctx->wlist >= 0) + view2dlg_list(ctx); + + if (ctx->wpos >= 0) + view2dlg_pos(ctx); +} + +void view_simple_show(view_ctx_t *ctx) +{ + pcb_view_t *v = pcb_view_by_uid(ctx->lst, ctx->selected); + if (v != NULL) { + pcb_view_goto(v); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wdescription, str, rnd_text_wrap(rnd_strdup(v->description), 32, '\n', ' ')); + switch(v->data_type) { + case PCB_VIEW_PLAIN: + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wmeasure, str, rnd_strdup("")); + break; + case PCB_VIEW_DRC: + if (v->data.drc.have_measured) + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wmeasure, str, rnd_strdup_printf("DRC: %m+required: %$mw\nmeasured: %$mw\n", rnd_conf.editor.grid_unit->allow, v->data.drc.required_value, v->data.drc.measured_value)); + else + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wmeasure, str, rnd_strdup_printf("DRC: %m+required: %$mw\n", rnd_conf.editor.grid_unit->allow, v->data.drc.required_value)); + break; + } + } + + if (v == NULL) { + ctx->selected = 0; + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wdescription, str, rnd_strdup("")); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wmeasure, str, rnd_strdup("")); + } + else + rnd_dad_preview_zoomto(&ctx->dlg[ctx->wprev], &v->bbox); +} + +static void view_select(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + view_ctx_t *ctx = tree->user_ctx; + + if (row != NULL) + ctx->selected = row->user_data2.lng; + view_simple_show(ctx); +} + +static vtp0_t view_color_save; + +static void view_expose_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + view_ctx_t *ctx = prv->user_ctx; + rnd_xform_t xform; + int old_termlab, g; + static const rnd_color_t *offend_color[2]; + pcb_view_t *v = pcb_view_by_uid(ctx->lst, ctx->selected); + size_t n; + void **p; + + if (v == NULL) + return; + + offend_color[0] = rnd_color_red; + offend_color[1] = rnd_color_blue; + + /* NOTE: zoom box was already set on select */ + + /* save offending object colors */ + vtp0_truncate(&view_color_save, 0); + for(g = 0; g < 2; g++) { + pcb_idpath_t *i; + for(i = pcb_idpath_list_first(&v->objs[g]); i != NULL; i = pcb_idpath_list_next(i)) { + pcb_any_obj_t *obj = pcb_idpath2obj_in(ctx->pcb->Data, i); + if ((obj != NULL) && (obj->type & PCB_OBJ_CLASS_REAL)) { + vtp0_append(&view_color_save, obj); + if (obj->override_color != NULL) + vtp0_append(&view_color_save, (char *)obj->override_color); + else + vtp0_append(&view_color_save, NULL); + obj->override_color = (rnd_color_t *)offend_color[g]; /* we are sure obj is not free'd before we restore this */ + } + } + } + + /* draw the board */ + old_termlab = pcb_draw_force_termlab; + pcb_draw_force_termlab = 1; + memset(&xform, 0, sizeof(xform)); + xform.layer_faded = 1; + rnd_expose_main(rnd_gui, e, &xform); + pcb_draw_force_termlab = old_termlab; + + /* restore object color */ + for(n = 0, p = view_color_save.array; n < view_color_save.used; n+=2,p+=2) { + pcb_any_obj_t *obj = p[0]; + rnd_color_t *s = p[1]; + obj->override_color = s; + } + vtp0_truncate(&view_color_save, 0); +} + + +static rnd_bool view_mouse_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + return rnd_false; /* don't redraw */ +} + +void view_refresh(view_ctx_t *ctx) +{ + if (ctx->refresh != NULL) + ctx->refresh(ctx); + view2dlg(ctx); +} + +static void view_preview_update(view_ctx_t *ctx) +{ + rnd_hid_attr_val_t hv; + + if ((ctx == NULL) || (!ctx->active) || (ctx->selected == 0)) + return; + + hv.str = NULL; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wprev, &hv); +} + + +static void view_refresh_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + view_refresh((view_ctx_t *)caller_data); +} + +static void view_close_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + view_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); +} + +static void view_stepped(view_ctx_t *ctx, pcb_view_t *v) +{ + if (v == NULL) + return; + ctx->selected = v->uid; + view_simple_show(ctx); + view2dlg_pos(ctx); +} + +static void view_del_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + view_ctx_t *ctx = caller_data; + pcb_view_t *v, *newv; + + if (ctx->wlist < 0) { /* simplified dialog, no list */ + v = pcb_view_by_uid(ctx->lst, ctx->selected); + if (v == NULL) + return; + newv = pcb_view_list_next(v); + if (newv == NULL) + newv = pcb_view_list_first(ctx->lst); + pcb_view_free(v); + view_stepped(ctx, newv); + view2dlg_count(ctx); + } + else { /* full dialog, go by the list */ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_row_t *rc, *r = rnd_dad_tree_get_selected(attr); + + if (r == NULL) + return; + + if (r->user_data2.lng == 0) { + /* remove a whole category - assume a single level */ + for(rc = gdl_first(&r->children); rc != NULL; rc = gdl_next(&r->children, rc)) { + v = pcb_view_by_uid(ctx->lst, rc->user_data2.lng); + rnd_dad_tree_remove(attr, rc); + if (v != NULL) + pcb_view_free(v); + } + rnd_dad_tree_remove(attr, r); + } + else { + /* remove a single item */ + v = pcb_view_by_uid(ctx->lst, r->user_data2.lng); + rnd_dad_tree_remove(attr, r); + if (v != NULL) + pcb_view_free(v); + } + } +} + +static void view_copy_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + view_ctx_t *ctx = caller_data; + pcb_view_t *v; + gds_t tmp; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_row_t *rc, *r = rnd_dad_tree_get_selected(attr); + int btn_idx = attr_btn - ctx->dlg; + int cut = (ctx->wbtn_cut == btn_idx); + + if (r == NULL) + return; + + /* only full dialog, go by the list */ + + gds_init(&tmp); + + pcb_view_save_list_begin(&tmp, NULL); + if (r->user_data2.lng == 0) { + /* dump a whole category */ + for(rc = gdl_first(&r->children); rc != NULL; rc = gdl_next(&r->children, rc)) { + v = pcb_view_by_uid(ctx->lst, rc->user_data2.lng); + if (v != NULL) { + pcb_view_save(v, &tmp, " "); + if (cut) + pcb_view_free(v); + } + } + } + else { + /* dump a single item */ + v = pcb_view_by_uid(ctx->lst, r->user_data2.lng); + if (v != NULL) { + pcb_view_save(v, &tmp, " "); + if (cut) + pcb_view_free(v); + } + } + pcb_view_save_list_end(&tmp, NULL); + rnd_gui->clip_set(rnd_gui, RND_HID_CLIPFMT_TEXT, tmp.array, tmp.used+1); + gds_uninit(&tmp); + if (cut) + view2dlg_list(ctx); +} + +static void view_paste_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + view_ctx_t *ctx = caller_data; + rnd_hid_clipfmt_t cformat; + void *cdata, *load_ctx; + size_t clen; + pcb_view_t *v, *vt = NULL; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(attr); + + if (r != NULL) { + /* if cursor is a category */ + if (r->user_data2.lng == 0) { + r = gdl_first(&r->children); + if (r == NULL) + return; + } + vt = pcb_view_by_uid(ctx->lst, r->user_data2.lng); + } + + if (rnd_gui->clip_get(rnd_gui, &cformat, &cdata, &clen) != 0) + return; + + if (cformat != RND_HID_CLIPFMT_TEXT) { + rnd_gui->clip_free(rnd_gui, cformat, cdata, clen); + return; + } + + load_ctx = pcb_view_load_start_str(cdata); + rnd_gui->clip_free(rnd_gui, cformat, cdata, clen); + if (load_ctx == NULL) + return; + + for(;;) { + v = pcb_view_load_next(load_ctx, NULL); + if (v == NULL) + break; + pcb_view_list_insert_before(ctx->lst, vt, v); + vt = v; + } + + pcb_view_load_end(load_ctx); + view2dlg_list(ctx); +} + +static void view_save_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + view_ctx_t *ctx = caller_data; + gds_t tmp; + pcb_view_t *v; + char *fn; + FILE *f; + + fn = rnd_gui->fileselect(rnd_gui, "Save view list", "Save all views from the list", "view.lht", "lht", NULL, "view", 0, NULL); + if (fn == NULL) + return; + + f = rnd_fopen(&PCB->hidlib, fn, "w"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can't open %s for write\n", fn); + return; + } + + gds_init(&tmp); + pcb_view_save_list_begin(&tmp, NULL); + for(v = pcb_view_list_first(ctx->lst); v != NULL; v = pcb_view_list_next(v)) + pcb_view_save(v, &tmp, " "); + pcb_view_save_list_end(&tmp, NULL); + + fprintf(f, "%s", tmp.array); + fclose(f); + gds_uninit(&tmp); +} + +static void view_load_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + view_ctx_t *ctx = caller_data; + pcb_view_t *v; + char *fn; + FILE *f; + void *load_ctx; + + fn = rnd_gui->fileselect(rnd_gui, "Load view list", "Load all views from the list", "view.lht", "lht", NULL, "view", RND_HID_FSD_READ, NULL); + if (fn == NULL) + return; + + f = rnd_fopen(&PCB->hidlib, fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can't open %s for read\n", fn); + return; + } + + load_ctx = pcb_view_load_start_file(f); + if (load_ctx == NULL) { + rnd_message(RND_MSG_ERROR, "Error parsing %s - is it a view list?\n", fn); + fclose(f); + return; + } + fclose(f); + + pcb_view_list_free_fields(ctx->lst); + for(;;) { + v = pcb_view_load_next(load_ctx, NULL); + if (v == NULL) + break; + pcb_view_list_append(ctx->lst, v); + } + + pcb_view_load_end(load_ctx); + view2dlg_list(ctx); +} + +static void view_select_obj(view_ctx_t *ctx, pcb_view_t *v) +{ + pcb_idpath_t *i; + int chg = 0; + + if (v == NULL) + return; + + for(i = pcb_idpath_list_first(&v->objs[0]); i != NULL; i = pcb_idpath_list_next(i)) { + pcb_any_obj_t *obj = pcb_idpath2obj_in(ctx->pcb->Data, i); + if ((obj != NULL) && (obj->type & PCB_OBJ_CLASS_REAL)) { + pcb_undo_add_obj_to_flag((void *)obj); + pcb_draw_obj(obj); + PCB_FLAG_ASSIGN(PCB_FLAG_SELECTED, 1, obj); + chg = 1; + } + } + + if (chg) { + pcb_board_set_changed_flag(PCB, rnd_true); + view_preview_update(ctx); + } +} + +static void view_select_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + view_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wlist]; + rnd_hid_row_t *rc, *r = rnd_dad_tree_get_selected(attr); + + if (r == NULL) + return; + + if (r->user_data2.lng == 0) { + /* select a whole category - assume a single level */ + for(rc = gdl_first(&r->children); rc != NULL; rc = gdl_next(&r->children, rc)) { + view_select_obj(ctx, pcb_view_by_uid(ctx->lst, rc->user_data2.lng)); + } + } + else { + /* select a single item */ + view_select_obj(ctx, pcb_view_by_uid(ctx->lst, r->user_data2.lng)); + } +} + +static void simple_rewind(view_ctx_t *ctx) +{ + pcb_view_t *v = pcb_view_list_first(ctx->lst); + if (v != NULL) { + ctx->selected = v->uid; + view_stepped(ctx, v); + } + else + ctx->selected = 0; +} + +static void view_prev_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + view_ctx_t *ctx = caller_data; + pcb_view_t *v = pcb_view_by_uid(ctx->lst, ctx->selected); + + if (v == NULL) + v = pcb_view_list_first(ctx->lst); + else + v = pcb_view_list_prev(v); + view_stepped(ctx, v); +} + +static void view_next_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + view_ctx_t *ctx = caller_data; + pcb_view_t *v = pcb_view_by_uid(ctx->lst, ctx->selected); + + if (v == NULL) + v = pcb_view_list_first(ctx->lst); + else + v = pcb_view_list_next(v); + view_stepped(ctx, v); +} + + +static void pcb_dlg_view_full(const char *id, view_ctx_t *ctx, const char *title, void (*extra_buttons)(view_ctx_t *), unsigned long preview_flipflags) +{ + const char *hdr[] = { "ID", "title", NULL }; + + ctx->wpos = -1; + + preview_flipflags &= (RND_HATF_PRV_GFLIP | RND_HATF_PRV_LFLIP); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_HPANE(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + /* left */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Number of violations:"); + RND_DAD_LABEL(ctx->dlg, "n/a"); + ctx->wcount = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_TREE(ctx->dlg, 2, 1, hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_SCROLL | RND_HATF_EXPFILL); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, view_select); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + ctx->wlist = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Copy"); + RND_DAD_CHANGE_CB(ctx->dlg, view_copy_btn_cb); + RND_DAD_BUTTON(ctx->dlg, "Cut"); + ctx->wbtn_cut = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, view_copy_btn_cb); + RND_DAD_BUTTON(ctx->dlg, "Paste"); + RND_DAD_CHANGE_CB(ctx->dlg, view_paste_btn_cb); + RND_DAD_BUTTON(ctx->dlg, "Del"); + RND_DAD_CHANGE_CB(ctx->dlg, view_del_btn_cb); + RND_DAD_BUTTON(ctx->dlg, "Select"); + RND_DAD_CHANGE_CB(ctx->dlg, view_select_btn_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* right */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_PREVIEW(ctx->dlg, view_expose_cb, view_mouse_cb, NULL, NULL, NULL, 100, 100, ctx); + ctx->wprev = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_PRV_BOARD | preview_flipflags); + RND_DAD_LABEL(ctx->dlg, "(description)"); + ctx->wdescription = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(measure)"); + ctx->wmeasure = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Save all"); + RND_DAD_CHANGE_CB(ctx->dlg, view_save_btn_cb); + RND_DAD_BUTTON(ctx->dlg, "Load all"); + RND_DAD_CHANGE_CB(ctx->dlg, view_load_btn_cb); + if (ctx->refresh != NULL) { + RND_DAD_BUTTON(ctx->dlg, "Refresh"); + RND_DAD_CHANGE_CB(ctx->dlg, view_refresh_btn_cb); + } + if (extra_buttons != NULL) + extra_buttons(ctx); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Close"); + RND_DAD_CHANGE_CB(ctx->dlg, view_close_btn_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_NEW(id, ctx->dlg, title, ctx, rnd_false, view_close_cb); + + ctx->active = 1; +} + +static void pcb_dlg_view_simplified(const char *id, view_ctx_t *ctx, const char *title, unsigned long preview_flipflags) +{ + pcb_view_t *v; + + preview_flipflags &= (RND_HATF_PRV_GFLIP | RND_HATF_PRV_LFLIP); + + ctx->wlist = -1; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_PREVIEW(ctx->dlg, view_expose_cb, view_mouse_cb, NULL, NULL, NULL, 100, 100, ctx); + ctx->wprev = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_PRV_BOARD | preview_flipflags); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(description)"); + ctx->wdescription = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(measure)"); + ctx->wmeasure = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Previous"); + RND_DAD_CHANGE_CB(ctx->dlg, view_prev_btn_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, "na"); + ctx->wpos = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "/"); + RND_DAD_LABEL(ctx->dlg, "na"); + ctx->wcount = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Del"); + RND_DAD_CHANGE_CB(ctx->dlg, view_del_btn_cb); + RND_DAD_BUTTON(ctx->dlg, "Next"); + RND_DAD_CHANGE_CB(ctx->dlg, view_next_btn_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + if (ctx->refresh != NULL) { + RND_DAD_BUTTON(ctx->dlg, "Refresh"); + RND_DAD_CHANGE_CB(ctx->dlg, view_refresh_btn_cb); + } + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Close"); + RND_DAD_CHANGE_CB(ctx->dlg, view_close_btn_cb); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + + RND_DAD_NEW(id, ctx->dlg, title, ctx, rnd_false, view_close_cb); + + ctx->active = 1; + + v = pcb_view_list_first(ctx->lst); + if (v != NULL) + ctx->selected = v->uid; + else + ctx->selected = 0; + simple_rewind(ctx); +} + +static void drc_refresh(view_ctx_t *ctx) +{ + pcb_drc_all(); + + if (ctx->wlist < 0) + simple_rewind(ctx); +} + +static void drc_config_btn_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&PCB->hidlib, "preferences", "Sizes", NULL); +} + +void drc_extra_buttons(view_ctx_t *ctx) +{ + RND_DAD_BUTTON(ctx->dlg, "Config..."); + RND_DAD_CHANGE_CB(ctx->dlg, drc_config_btn_cb); +} + +static view_ctx_t drc_gui_ctx = {0}; +const char pcb_acts_DrcDialog[] = "DrcDialog([list|simple]\n"; +const char pcb_acth_DrcDialog[] = "Execute drc checks and invoke a view list dialog box for presenting the results"; +fgw_error_t pcb_act_DrcDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *dlg_type = "list"; + unsigned long flip_flags = RND_HATF_PRV_GFLIP; + + RND_ACT_MAY_CONVARG(1, FGW_STR, DrcDialog, dlg_type = argv[1].val.str); + + if (!drc_gui_ctx.active) { + drc_gui_ctx.pcb = PCB; + drc_gui_ctx.lst = &pcb_drc_lst; + drc_gui_ctx.refresh = drc_refresh; + pcb_drc_all(); + if (rnd_strcasecmp(dlg_type, "simple") == 0) + pcb_dlg_view_simplified("drc_simple", &drc_gui_ctx, "DRC violations", flip_flags); + else + pcb_dlg_view_full("drc_full", &drc_gui_ctx, "DRC violations", drc_extra_buttons, flip_flags); + } + + view2dlg(&drc_gui_ctx); + + return 0; +} + +extern pcb_view_list_t pcb_io_incompat_lst; +static view_ctx_t io_gui_ctx = {0}; +const char pcb_acts_IOIncompatListDialog[] = "IOIncompatListDialog([list|simple])\n"; +const char pcb_acth_IOIncompatListDialog[] = "Present the format incompatibilities of the last save to file operation in a GUI dialog."; +fgw_error_t pcb_act_IOIncompatListDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *dlg_type = "list"; + RND_ACT_MAY_CONVARG(1, FGW_STR, IOIncompatListDialog, dlg_type = argv[1].val.str); + + if (!io_gui_ctx.active) { + io_gui_ctx.pcb = PCB; + io_gui_ctx.lst = &pcb_io_incompat_lst; + io_gui_ctx.refresh = NULL; + if (rnd_strcasecmp(dlg_type, "simple") == 0) + pcb_dlg_view_simplified("io_incompat_simple", &io_gui_ctx, "IO incompatibilities in last save", 0); + else + pcb_dlg_view_full("io_incompat_full", &io_gui_ctx, "IO incompatibilities in last save", NULL, 0); + } + + view2dlg(&io_gui_ctx); + + return 0; +} + +const char pcb_acts_ViewList[] = "viewlist([name, [winid, [listptr]]])\n"; +const char pcb_acth_ViewList[] = "Present a new empty view list"; +fgw_error_t pcb_act_ViewList(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + view_ctx_t *ctx; + void *lst = NULL; + const char *name = "view list", *winid = "viewlist"; + RND_ACT_MAY_CONVARG(1, FGW_STR, ViewList, name = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, ViewList, winid = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_PTR, ViewList, lst = argv[3].val.ptr_void); + + if ((lst != NULL) && (!fgw_ptr_in_domain(&rnd_fgw, &argv[3], PCB_PTR_DOMAIN_VIEWLIST))) { + rnd_message(RND_MSG_ERROR, "invalid list pointer"); + RND_ACT_IRES(1); + return 0; + } + + RND_ACT_IRES(0); + ctx = calloc(sizeof(view_ctx_t), 1); + ctx->pcb = PCB; + if (lst != NULL) + ctx->lst = lst; + else + ctx->lst = calloc(sizeof(pcb_view_list_t), 1); + ctx->list_alloced = 1; + ctx->refresh = NULL; + pcb_dlg_view_full(winid, ctx, name, NULL, 0); + view2dlg(ctx); + return 0; +} + +static void view_preview_update_cb(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (drc_gui_ctx.active) + view_preview_update(&drc_gui_ctx); + if (io_gui_ctx.active) + view_preview_update(&io_gui_ctx); +} + +void pcb_view_dlg_uninit(void) +{ + rnd_event_unbind_allcookie(dlg_view_cookie); + vtp0_uninit(&view_color_save); +} + +void pcb_view_dlg_init(void) +{ + rnd_event_bind(RND_EVENT_USER_INPUT_POST, view_preview_update_cb, NULL, dlg_view_cookie); +} Index: tags/2.3.0/src_plugins/dialogs/dlg_view.h =================================================================== --- tags/2.3.0/src_plugins/dialogs/dlg_view.h (nonexistent) +++ tags/2.3.0/src_plugins/dialogs/dlg_view.h (revision 33253) @@ -0,0 +1,15 @@ +extern const char pcb_acts_DrcDialog[]; +extern const char pcb_acth_DrcDialog[]; +fgw_error_t pcb_act_DrcDialog(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv); + +extern const char pcb_acts_IOIncompatListDialog[]; +extern const char pcb_acth_IOIncompatListDialog[]; +fgw_error_t pcb_act_IOIncompatListDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char pcb_acts_ViewList[]; +extern const char pcb_acth_ViewList[]; +fgw_error_t pcb_act_ViewList(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void pcb_view_dlg_uninit(void); +void pcb_view_dlg_init(void); + Index: tags/2.3.0/src_plugins/distalign/Makefile =================================================================== --- tags/2.3.0/src_plugins/distalign/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/distalign/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_distalign + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/distalign/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/distalign/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/distalign/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {distalign} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/distalign/distalign.o @] + +switch /local/pcb/distalign/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/distalign/distalign.c =================================================================== --- tags/2.3.0/src_plugins/distalign/distalign.c (nonexistent) +++ tags/2.3.0/src_plugins/distalign/distalign.c (revision 33253) @@ -0,0 +1,557 @@ +/* Functions to distribute (evenly spread out) and align PCB objects. + * + * Copyright (C) 2007 Ben Jackson + * Copyright (C) 2016,2020 Tibor 'Igor2' Palinkas + * + * Licensed under the terms of the GNU General Public + * License, version 2 or later. + * + * Ported to pcb-rnd by Tibor 'Igor2' Palinkas in 2016. + * Major feature extension by Tibor 'Igor2' Palinkas in 2020: work on any object type. + * + * Original source was: http://ad7gd.net/geda/distalign.c + * + * Ben Jackson AD7GD + * + * http://www.ben.com/ + */ + +#include +#include + +#include "board.h" +#include "config.h" +#include "data.h" +#include "data_it.h" +#include +#include +#include "undo.h" +#include +#include "move.h" +#include "draw.h" +#include +#include +#include + +enum { + K_X, + K_Y, + K_Lefts, + K_Rights, + K_Tops, + K_Bottoms, + K_Centers, + K_Marks, + K_Gaps, + K_First, + K_Last, + K_Average, + K_Crosshair, + K_Gridless, + K_none, + K_align, + K_distribute +}; + +static const char *keywords[] = { + /*[K_X] */ "X", + /*[K_Y] */ "Y", + /*[K_Lefts] */ "Lefts", + /*[K_Rights] */ "Rights", + /*[K_Tops] */ "Tops", + /*[K_Bottoms] */ "Bottoms", + /*[K_Centers] */ "Centers", + /*[K_Marks] */ "Marks", + /*[K_Gaps] */ "Gaps", + /*[K_First] */ "First", + /*[K_Last] */ "Last", + /*[K_Average] */ "Average", + /*[K_Crosshair] */ "pcb_crosshair", + /*[K_Gridless] */ "Gridless", +}; + +static int keyword(const char *s) +{ + int i; + + if (!s) { + return K_none; + } + for (i = 0; i < RND_ENTRIES(keywords); ++i) { + if (keywords[i] && rnd_strcasecmp(s, keywords[i]) == 0) + return i; + } + return -1; +} + + +/* this macro produces a function in X or Y that switches on 'point' */ +#define COORD(DIR) \ +static inline rnd_coord_t \ +coord ## DIR(pcb_any_obj_t *obj, int point) \ +{ \ + rnd_coord_t oX, oY; \ + switch (point) { \ + case K_Marks: \ + oX = oY = 0; \ + if (obj->type == PCB_OBJ_SUBC) \ + pcb_subc_get_origin((pcb_subc_t *)obj, &oX, &oY); \ + else \ + pcb_obj_center(obj, &oX, &oY); \ + return o ## DIR; \ + case K_Lefts: \ + case K_Tops: \ + return obj->BoundingBox.DIR ## 1; \ + case K_Rights: \ + case K_Bottoms: \ + return obj->BoundingBox.DIR ## 2; \ + case K_Centers: \ + case K_Gaps: \ + return (obj->BoundingBox.DIR ## 1 + obj->BoundingBox.DIR ## 2) / 2; \ + } \ + return 0; \ +} + +COORD(X) +COORD(Y) + +/* return the object coordinate associated with the given internal point */ +static rnd_coord_t coord(pcb_any_obj_t *obj, int dir, int point) +{ + if (dir == K_X) + return coordX(obj, point); + else + return coordY(obj, point); +} + +static struct obj_by_pos { + pcb_any_obj_t *obj; + rnd_coord_t pos; + rnd_coord_t width; +} *objs_by_pos; + +static int nobjs_by_pos; + +static int cmp_ebp(const void *a, const void *b) +{ + const struct obj_by_pos *ea = a; + const struct obj_by_pos *eb = b; + + return ea->pos - eb->pos; +} + +/* + * Find all selected objects, then order them in order by coordinate in + * the 'dir' axis. This is used to find the "First" and "Last" object + * and also to choose the distribution order. + * + * For alignment, first and last are in the orthogonal axis (imagine if + * you were lining up letters in a sentence, aligning *vertically* to the + * first letter means selecting the first letter *horizontally*). + * + * For distribution, first and last are in the distribution axis. + */ +static int sort_objs_by_pos(int op, int dir, int point, int reference) +{ + int nsel = 0; + pcb_data_it_t it; + pcb_any_obj_t *obj; + + if (nobjs_by_pos) + return nobjs_by_pos; + + if (op == K_align) { + dir = dir == K_X ? K_Y : K_X; /* see above */ + switch(reference) { + case K_First: point = K_Lefts; break; + case K_Last: point = K_Rights; break; + } + } + + for(obj = pcb_data_first(&it, PCB->Data, PCB_OBJ_CLASS_REAL); obj != NULL; obj = pcb_data_next(&it)) + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, obj)) + continue; + nsel++; + } + + if (!nsel) + return 0; + objs_by_pos = malloc(nsel * sizeof(*objs_by_pos)); + nobjs_by_pos = nsel; + nsel = 0; + + for(obj = pcb_data_first(&it, PCB->Data, PCB_OBJ_CLASS_REAL); obj != NULL; obj = pcb_data_next(&it)) + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, obj)) + continue; + objs_by_pos[nsel].obj = obj; + objs_by_pos[nsel++].pos = coord(obj, dir, point); + } + + qsort(objs_by_pos, nobjs_by_pos, sizeof(*objs_by_pos), cmp_ebp); + return nobjs_by_pos; +} + +static void free_objs_by_pos(void) +{ + if (nobjs_by_pos) { + free(objs_by_pos); + objs_by_pos = NULL; + nobjs_by_pos = 0; + } +} + +/* Find the reference coordinate from the specified points of all selected objects. */ +static rnd_coord_t reference_coord(int op, int x, int y, int dir, int point, int reference) +{ + rnd_coord_t q; + int nsel; + pcb_data_it_t it; + pcb_any_obj_t *obj; + + q = 0; + switch (reference) { + case K_Crosshair: + if (dir == K_X) + q = x; + else + q = y; + break; + case K_Average: /* the average among selected objects */ + nsel = 0; + q = 0; + for(obj = pcb_data_first(&it, PCB->Data, PCB_OBJ_CLASS_REAL); obj != NULL; obj = pcb_data_next(&it)) + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, obj)) + continue; + q += coord(obj, dir, point); + nsel++; + } + + if (nsel) + q /= nsel; + break; + case K_First: /* first or last in the orthogonal direction */ + case K_Last: + if (!sort_objs_by_pos(op, dir, point, reference)) { + q = 0; + break; + } + if (reference == K_First) { + q = coord(objs_by_pos[0].obj, dir, point); + } + else { + q = coord(objs_by_pos[nobjs_by_pos - 1].obj, dir, point); + } + break; + } + return q; +} + +static const char pcb_acts_align[] = "Align(X/Y, [Lefts/Rights/Tops/Bottoms/Centers/Marks, [First/Last/pcb_crosshair/Average[, Gridless]]])"; +/* DOC: align.html */ +static fgw_error_t pcb_act_align(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *a0, *a1 = NULL, *a2 = NULL, *a3 = NULL; + int dir; + int point; + int reference; + int gridless; + rnd_coord_t q; + int changed = 0; + pcb_data_it_t it; + pcb_any_obj_t *obj; + + if (argc < 2 || argc > 5) { + RND_ACT_FAIL(align); + } + + RND_ACT_CONVARG(1, FGW_STR, align, a0 = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, align, a1 = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, align, a2 = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, align, a3 = argv[4].val.str); + + /* parse direction arg */ + switch ((dir = keyword(a0))) { + case K_X: + case K_Y: + break; + default: + RND_ACT_FAIL(align); + } + /* parse point (within each object) which will be aligned */ + switch ((point = keyword(a1))) { + case K_Centers: + case K_Marks: + break; + case K_Lefts: + case K_Rights: + if (dir == K_Y) { + RND_ACT_FAIL(align); + } + break; + case K_Tops: + case K_Bottoms: + if (dir == K_X) { + RND_ACT_FAIL(align); + } + break; + case K_none: + point = K_Marks; /* default value */ + break; + default: + RND_ACT_FAIL(align); + } + /* parse reference which will determine alignment coordinates */ + switch ((reference = keyword(a2))) { + case K_First: + case K_Last: + case K_Average: + case K_Crosshair: + break; + case K_none: + reference = K_First; /* default value */ + break; + default: + RND_ACT_FAIL(align); + } + /* optionally work off the grid (solar cells!) */ + switch (keyword(a3)) { + case K_Gridless: + gridless = 1; + break; + case K_none: + gridless = 0; + break; + default: + RND_ACT_FAIL(align); + } + /* find the final alignment coordinate using the above options */ + q = reference_coord(K_align, pcb_crosshair.X, pcb_crosshair.Y, dir, point, reference); + /* move all selected objects to the new coordinate */ + for(obj = pcb_data_first(&it, PCB->Data, PCB_OBJ_CLASS_REAL); obj != NULL; obj = pcb_data_next(&it)) + { + rnd_coord_t p, dp, dx, dy; + + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, obj)) + continue; + /* find delta from reference point to reference point */ + p = coord(obj, dir, point); + dp = q - p; + /* ...but if we're gridful, keep the mark on the grid */ + if (!gridless) { + dp -= (coord(obj, dir, K_Marks) + dp) % (long) (PCB->hidlib.grid); + } + if (dp) { + /* move from generic to X or Y */ + dx = dy = dp; + if (dir == K_X) + dy = 0; + else + dx = 0; + pcb_move_obj(obj->type, obj->parent.any, obj, obj, dx, dy); + changed = 1; + } + } + + if (changed) { + pcb_undo_inc_serial(); + rnd_hid_redraw(PCB); + pcb_board_set_changed_flag(PCB, 1); + } + free_objs_by_pos(); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_distribute[] = "Distribute(X/Y, [Lefts/Rights/Tops/Bottoms/Centers/Marks/Gaps, [First/Last/pcb_crosshair, First/Last/pcb_crosshair[, Gridless]]])"; +/* DOC: distribute.html */ +static fgw_error_t pcb_act_distribute(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *a0, *a1 = NULL, *a2 = NULL, *a3 = NULL, *a4 = NULL; + int dir; + int point; + int refa, refb; + int gridless; + rnd_coord_t s, e, slack; + int divisor; + int changed = 0; + int i; + + if (argc < 2 || argc == 4 || argc > 6) { + RND_ACT_FAIL(distribute); + } + + RND_ACT_CONVARG(1, FGW_STR, distribute, a0 = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, distribute, a1 = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, distribute, a2 = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, distribute, a3 = argv[4].val.str); + RND_ACT_MAY_CONVARG(5, FGW_STR, distribute, a4 = argv[5].val.str); + + + /* parse direction arg */ + switch ((dir = keyword(a0))) { + case K_X: + case K_Y: + break; + default: + RND_ACT_FAIL(distribute); + } + /* parse point (within each objects) which will be distributed */ + switch ((point = keyword(a1))) { + case K_Centers: + case K_Marks: + case K_Gaps: + break; + case K_Lefts: + case K_Rights: + if (dir == K_Y) { + RND_ACT_FAIL(distribute); + } + break; + case K_Tops: + case K_Bottoms: + if (dir == K_X) { + RND_ACT_FAIL(distribute); + } + break; + case K_none: + point = K_Marks; /* default value */ + break; + default: + RND_ACT_FAIL(distribute); + } + /* parse reference which will determine first distribution coordinate */ + switch ((refa = keyword(a2))) { + case K_First: + case K_Last: + case K_Average: + case K_Crosshair: + break; + case K_none: + refa = K_First; /* default value */ + break; + default: + RND_ACT_FAIL(distribute); + } + /* parse reference which will determine final distribution coordinate */ + switch ((refb = keyword(a3))) { + case K_First: + case K_Last: + case K_Average: + case K_Crosshair: + break; + case K_none: + refb = K_Last; /* default value */ + break; + default: + RND_ACT_FAIL(distribute); + } + if (refa == refb) { + RND_ACT_FAIL(distribute); + } + /* optionally work off the grid (solar cells!) */ + switch (keyword(a4)) { + case K_Gridless: + gridless = 1; + break; + case K_none: + gridless = 0; + break; + default: + RND_ACT_FAIL(distribute); + } + /* build list of objects in orthogonal axis order */ + sort_objs_by_pos(K_distribute, dir, point, refb); + /* find the endpoints given the above options */ + s = reference_coord(K_distribute, pcb_crosshair.X, pcb_crosshair.Y, dir, point, refa); + e = reference_coord(K_distribute, pcb_crosshair.X, pcb_crosshair.Y, dir, point, refb); + slack = e - s; + /* use this divisor to calculate spacing (for 1 elt, avoid 1/0) */ + divisor = (nobjs_by_pos > 1) ? (nobjs_by_pos - 1) : 1; + /* even the gaps instead of the edges or whatnot */ + /* find the "slack" in the row */ + if (point == K_Gaps) { + rnd_coord_t w; + + /* subtract all the "widths" from the slack */ + for (i = 0; i < nobjs_by_pos; ++i) { + pcb_any_obj_t *o = objs_by_pos[i].obj; + /* coord doesn't care if I mix Lefts/Tops */ + w = objs_by_pos[i].width = coord(o, dir, K_Rights) - coord(o, dir, K_Lefts); + /* Gaps distribution is on centers, so half of + * first and last subcircuit don't count */ + if (i == 0 || i == nobjs_by_pos - 1) { + w /= 2; + } + slack -= w; + } + /* slack could be negative */ + } + /* move all selected objects to the new coordinate */ + for (i = 0; i < nobjs_by_pos; ++i) { + pcb_any_obj_t *obj = objs_by_pos[i].obj; + rnd_coord_t p, q, dp, dx, dy; + + /* find reference point for this object */ + q = s + slack * i / divisor; + /* find delta from reference point to reference point */ + p = coord(obj, dir, point); + dp = q - p; + /* ...but if we're gridful, keep the mark on the grid */ + if (!gridless) { + dp -= (coord(obj, dir, K_Marks) + dp) % (long) (PCB->hidlib.grid); + } + if (dp) { + /* move from generic to X or Y */ + dx = dy = dp; + if (dir == K_X) + dy = 0; + else + dx = 0; + pcb_move_obj(obj->type, obj->parent.any, obj, obj, dx, dy); + changed = 1; + } + /* in gaps mode, accumulate part widths */ + if (point == K_Gaps) { + /* move remaining half of our objects */ + s += objs_by_pos[i].width / 2; + /* move half of next objects */ + if (i < nobjs_by_pos - 1) + s += objs_by_pos[i + 1].width / 2; + } + } + if (changed) { + pcb_undo_inc_serial(); + rnd_hid_redraw(PCB); + pcb_board_set_changed_flag(PCB, 1); + } + free_objs_by_pos(); + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t distalign_action_list[] = { + {"distribute", pcb_act_distribute, "Distribute objects", pcb_acts_distribute}, + {"distributetext", pcb_act_distribute, "Distribute objects", pcb_acts_distribute}, + {"align", pcb_act_align, "Align objects", pcb_acts_align}, + {"aligntext", pcb_act_align, "Align objects", pcb_acts_align} +}; + +static char *distalign_cookie = "distalign plugin"; + +int pplg_check_ver_distalign(int ver_needed) { return 0; } + +void pplg_uninit_distalign(void) +{ + rnd_remove_actions_by_cookie(distalign_cookie); +} + +int pplg_init_distalign(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(distalign_action_list, distalign_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/distalign/distalign.pup =================================================================== --- tags/2.3.0/src_plugins/distalign/distalign.pup (nonexistent) +++ tags/2.3.0/src_plugins/distalign/distalign.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short distribute and align objs +$long Introducing Align() and Distribute(), which work much like the similarly named functions in Visio. Given that PCB does not have the concept of "first selected object" to draw on, the reference points can be selected by arguments. +$package extra +$state works +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/djopt/Makefile =================================================================== --- tags/2.3.0/src_plugins/djopt/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/djopt/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_djopt + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/djopt/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/djopt/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/djopt/Plug.tmpasm (revision 33253) @@ -0,0 +1,9 @@ +put /local/pcb/mod {djopt} +append /local/pcb/mod/OBJS [@ $(PLUGDIR)/djopt/djopt.o @] +put /local/pcb/mod/CONF {$(PLUGDIR)/djopt/djopt_conf.h} + +switch /local/pcb/djopt/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/djopt/djopt.c =================================================================== --- tags/2.3.0/src_plugins/djopt/djopt.c (nonexistent) +++ tags/2.3.0/src_plugins/djopt/djopt.c (revision 33253) @@ -0,0 +1,2585 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2003 DJ Delorie + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA + * dj@delorie.com + * + */ + +#include "config.h" +#include "conf_core.h" +#include +#include "board.h" + +#include +#include + + +#include "data.h" +#include "remove.h" +#include "move.h" +#include "draw.h" +#include "undo.h" +#include "flag_str.h" +#include "find.h" +#include "layer.h" +#include +#include +#include +#include +#include "djopt_conf.h" +#include "obj_line.h" +#include +#include "obj_pstk_inlines.h" + +conf_djopt_t conf_djopt; + +static const char *djopt_cookie = "djopt"; + +#define dprintf if(0)rnd_printf + +#define selected(x) PCB_FLAG_TEST(PCB_FLAG_SELECTED, (x)) +#define autorouted(x) PCB_FLAG_TEST(PCB_FLAG_AUTO, (x)) + +#define SB (conf_core.design.bloat+1) + +/* must be 2^N-1 */ +#define INC 7 + +#define O_HORIZ 0x10 +#define O_VERT 0x20 +#define LEFT 0x11 +#define RIGHT 0x12 +#define UP 0x24 +#define DOWN 0x28 +#define DIAGONAL 0xf0 +#define ORIENT(x) ((x) & 0xf0) +#define DIRECT(x) ((x) & 0x0f) + +/* Manhattan length of the longest "freckle" */ +#define LONGEST_FRECKLE 2 + +struct line_s; + +typedef struct corner_s { + int layer; + struct corner_s *next; + int x, y; + int net; + pcb_pstk_t *via, *pad, *pin; + int miter; + int n_lines; + struct line_s **lines; +} corner_s; + +typedef struct line_s { + int layer; + struct line_s *next; + corner_s *s, *e; + pcb_line_t *line; + char is_pad; +} line_s; + +typedef struct rect_s { + int x1, y1, x2, y2; +} rect_s; + +#define DELETE(q) (q)->layer = 0xdeadbeef +#define DELETED(q) ((q)->layer == 0xdeadbeef) + +static corner_s *corners, *next_corner = 0; +static line_s *lines; + +static int layer_groupings[PCB_MAX_LAYERGRP]; +static char layer_type[PCB_MAX_LAYER]; +#define LT_COMPONENT 1 +#define LT_SOLDER 2 + +static const char *element_name_for(corner_s * c) +{ + PCB_SUBC_LOOP(PCB->Data); + { + PCB_PADSTACK_LOOP(subc->data); + { + if ((padstack == c->pin) || (padstack == c->pad)) + return subc->refdes; + } + PCB_END_LOOP; + } + PCB_END_LOOP; + + return "unknown"; +} + +static const char *corner_name(corner_s * c) +{ + static char buf[4][100]; + static int bn = 0; + char *bp; + bn = (bn + 1) % 4; + + if (c->net == 0xf1eef1ee) { + sprintf(buf[bn], "\033[31m[%p freed corner]\033[0m", (void *) c); + return buf[bn]; + } + + sprintf(buf[bn], "\033[%dm[%p ", (c->pin || c->pad || c->via) ? 33 : 34, (void *) c); + bp = buf[bn] + strlen(buf[bn]); + + if (c->pin) + rnd_sprintf(bp, "pin %s:%s at %#mD", element_name_for(c), c->pin->term, c->x, c->y); + else if (c->via) + rnd_sprintf(bp, "via at %#mD", c->x, c->y); + else if (c->pad) { + rnd_sprintf(bp, "pad %s:%s at %#mD %#mD-%#mD", + element_name_for(c), c->pad->term, c->x, c->y, + c->pad->BoundingBox.X1, c->pad->BoundingBox.Y1, c->pad->BoundingBox.X2, c->pad->BoundingBox.Y2); + } + else + rnd_sprintf(bp, "at %#mD", c->x, c->y); + sprintf(bp + strlen(bp), " n%d l%d]\033[0m", c->n_lines, c->layer); + return buf[bn]; +} + +static int solder_layer, component_layer; + +static void dj_abort(const char *msg, ...) +{ + va_list a; + va_start(a, msg); + vprintf(msg, a); + va_end(a); + fflush(stdout); + abort(); +} + +#if 1 +#define check(c,l) +#else +#define check(c,l) check2(__LINE__,c,l) +static void check2(int srcline, corner_s * c, line_s * l) +{ + int saw_c = 0, saw_l = 0; + corner_s *cc; + line_s *ll; + int i; + + for (cc = corners; cc; cc = cc->next) { + if (DELETED(cc)) + continue; + if (cc == c) + saw_c = 1; + for (i = 0; i < cc->n_lines; i++) + if (cc->lines[i]->s != cc && cc->lines[i]->e != cc) + dj_abort("check:%d: cc has line without backref\n", srcline); + if (cc->via && (cc->x != cc->via->X || cc->y != cc->via->Y)) + dj_abort("check:%d: via not at corner\n", srcline); + if (cc->pin && (cc->x != cc->pin->X || cc->y != cc->pin->Y)) + dj_abort("check:%d: pin not at corner\n", srcline); + } + if (c && !saw_c) + dj_abort("check:%d: corner not in corners list\n", srcline); + for (ll = lines; ll; ll = ll->next) { + if (DELETED(ll)) + continue; + if (ll == l) + saw_l = 1; + for (i = 0; i < ll->s->n_lines; i++) + if (ll->s->lines[i] == ll) + break; + if (i == ll->s->n_lines) + dj_abort("check:%d: ll->s has no backref\n", srcline); + for (i = 0; i < ll->e->n_lines; i++) + if (ll->e->lines[i] == ll) + break; + if (i == ll->e->n_lines) + dj_abort("check:%d: ll->e has no backref\n", srcline); + if (!ll->is_pad + && (ll->s->x != ll->line->Point1.X + || ll->s->y != ll->line->Point1.Y || ll->e->x != ll->line->Point2.X || ll->e->y != ll->line->Point2.Y)) { + rnd_printf("line: %#mD to %#mD pcbline: %#mD to %#mD\n", + ll->s->x, ll->s->y, + ll->e->x, ll->e->y, ll->line->Point1.X, ll->line->Point1.Y, ll->line->Point2.X, ll->line->Point2.Y); + dj_abort("check:%d: line doesn't match pcbline\n", srcline); + } + } + if (l && !saw_l) + dj_abort("check:%d: line not in lines list\n", srcline); +} + +#endif + +#define SWAP(a,b) { a^=b; b^=a; a^=b; } + +static int gridsnap(rnd_coord_t n) +{ + if (n <= 0) + return 0; + return n - n % (rnd_conf.editor.grid); +} + +/* Avoid commonly used names. */ + +static int djabs(int x) +{ + return x > 0 ? x : -x; +} + +static int djmax(int x, int y) +{ + return x > y ? x : y; +} + +/* + * Find distance between 2 points. We use floating point math here + * because we can fairly easily overflow a 32 bit integer here. In + * fact it only takes 0.46" to do so. + */ +static int dist(int x1, int y1, int x2, int y2) +{ + double dx1, dy1, dx2, dy2, d; + + dx1 = (double) x1; + dy1 = (double) y1; + dx2 = (double) x2; + dy2 = (double) y2; + + d = sqrt((dx1 - dx2) * (dx1 - dx2) + (dy1 - dy2) * (dy1 - dy2)); + d = rnd_round(d); + + return (int) d; +} + +static int line_length(line_s * l) +{ + if (l->s->x == l->e->x) + return djabs(l->s->y - l->e->y); + if (l->s->y == l->e->y) + return djabs(l->s->x - l->e->x); + return dist(l->s->x, l->s->y, l->e->x, l->e->y); +} + +static int dist_ltp2(int dx, int y, int y1, int y2) +{ + if (y1 > y2) + SWAP(y1, y2); + if (y < y1) + return dist(dx, y, 0, y1); + if (y > y2) + return dist(dx, y, 0, y2); + return djabs(dx); +} + +int sqr(int a) +{ + return a * a; +} + +static int intersecting_layers(int l1, int l2) +{ + if (l1 == -1 || l2 == -1) + return 1; + if (l1 == l2) + return 1; + if (layer_groupings[l1] == layer_groupings[l2]) + return 1; + return 0; +} + +static int dist_line_to_point(line_s * l, corner_s * c) +{ + double len, r, d; + /* We can do this quickly if l is vertical or horizontal. */ + if (l->s->x == l->e->x) + return dist_ltp2(l->s->x - c->x, c->y, l->s->y, l->e->y); + if (l->s->y == l->e->y) + return dist_ltp2(l->s->y - c->y, c->x, l->s->x, l->e->x); + + /* Do it the hard way. See comments for pcb_is_point_on_line() in search.c */ + len = sqrt(sqr(l->s->x - l->e->x) + sqr(l->s->y - l->e->y)); + if (len == 0) + return dist(l->s->x, l->s->y, c->x, c->y); + r = (l->s->y - c->y) * (l->s->y - l->e->y) + (l->s->x - c->x) * (l->s->x - l->e->x); + r /= len * len; + if (r < 0) + return dist(l->s->x, l->s->y, c->x, c->y); + if (r > 1) + return dist(l->e->x, l->e->y, c->x, c->y); + d = (l->e->y - l->s->y) * (c->x * l->s->x) + (l->e->x - l->s->x) * (c->y - l->s->y); + return (int) (d / len); +} + +static int line_orient(line_s * l, corner_s * c) +{ + int x1, y1, x2, y2; + if (c == l->s) { + x1 = l->s->x; + y1 = l->s->y; + x2 = l->e->x; + y2 = l->e->y; + } + else { + x1 = l->e->x; + y1 = l->e->y; + x2 = l->s->x; + y2 = l->s->y; + } + if (x1 == x2) { + if (y1 < y2) + return DOWN; + return UP; + } + else if (y1 == y2) { + if (x1 < x2) + return RIGHT; + return LEFT; + } + return DIAGONAL; +} + +static corner_s *other_corner(line_s * l, corner_s * c) +{ + if (l->s == c) + return l->e; + if (l->e == c) + return l->s; + dj_abort("other_corner: neither corner passed\n"); + return NULL; +} + +static corner_s *find_corner_if(int x, int y, int l) +{ + corner_s *c; + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if (c->x != x || c->y != y) + continue; + if (!(c->layer == -1 || intersecting_layers(c->layer, l))) + continue; + return c; + } + return 0; +} + +static corner_s *find_corner(int x, int y, int l) +{ + corner_s *c; + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if (c->x != x || c->y != y) + continue; + if (!(c->layer == -1 || intersecting_layers(c->layer, l))) + continue; + return c; + } + c = (corner_s *) malloc(sizeof(corner_s)); + c->next = corners; + corners = c; + c->x = x; + c->y = y; + c->net = 0; + c->via = 0; + c->pad = 0; + c->pin = 0; + c->layer = l; + c->n_lines = 0; + c->lines = (line_s **) malloc(INC * sizeof(line_s *)); + return c; +} + +static void add_line_to_corner(line_s * l, corner_s * c) +{ + int n; + n = (c->n_lines + 1 + INC) & ~INC; + c->lines = (line_s **) realloc(c->lines, n * sizeof(line_s *)); + c->lines[c->n_lines] = l; + c->n_lines++; + dprintf("add_line_to_corner %#mD\n", c->x, c->y); +} + +static pcb_line_t *create_pcb_line(int layer, int x1, int y1, int x2, int y2, int thick, int clear, pcb_flag_t flags) +{ + char *from, *to; + pcb_line_t *nl; + pcb_layer_t *lyr = pcb_get_layer(PCB->Data, layer); + + from = (char *) linelist_first(&lyr->Line); + nl = pcb_line_new(PCB->Data->Layer + layer, x1, y1, x2, y2, thick, clear, flags); + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, lyr, nl, nl); + + to = (char *) linelist_first(&lyr->Line); + if (from != to) { + line_s *lp; + for (lp = lines; lp; lp = lp->next) { + if (DELETED(lp)) + continue; + if ((char *) (lp->line) >= from && (char *) (lp->line) <= from + linelist_length(&lyr->Line) * sizeof(pcb_line_t)) + lp->line = (pcb_line_t *) ((char *) (lp->line) + (to - from)); + } + } + return nl; +} + +static void new_line(corner_s * s, corner_s * e, int layer, pcb_line_t * example) +{ + line_s *ls; + + if (!(pcb_layer_flags(PCB, layer) & PCB_LYT_COPPER)) + dj_abort("layer %d\n", layer); + + if (example == NULL) + dj_abort("NULL example passed to new_line()\n", layer); + + if (s->x == e->x && s->y == e->y) + return; + + ls = (line_s *) malloc(sizeof(line_s)); + ls->next = lines; + lines = ls; + ls->is_pad = 0; + ls->s = s; + ls->e = e; + ls->layer = layer; +#if 0 + if ((example->Point1.X == s->x && example->Point1.Y == s->y && example->Point2.X == e->x && example->Point2.Y == e->y) + || (example->Point2.X == s->x && example->Point2.Y == s->y && example->Point1.X == e->x && example->Point1.Y == e->y)) { + ls->line = example; + } + else +#endif + { + pcb_line_t *nl; + dprintf + ("New line \033[35m%#mD to %#mD from l%d t%#mS c%#mS f%s\033[0m\n", + s->x, s->y, e->x, e->y, layer, example->Thickness, example->Clearance, pcb_strflg_f2s(example->Flags, PCB_OBJ_LINE, NULL, 0)); + nl = create_pcb_line(layer, s->x, s->y, e->x, e->y, example->Thickness, example->Clearance, example->Flags); + + if (!nl) + dj_abort("can't create new line!"); + ls->line = nl; + } + add_line_to_corner(ls, s); + add_line_to_corner(ls, e); + check(s, ls); + check(e, ls); +} + +static line_s *other_line(corner_s * c, line_s * l) +{ + int i; + line_s *rv = 0; + if (c->pin || c->pad || c->via) + return 0; + for (i = 0; i < c->n_lines; i++) { + if (c->lines[i] == l) + continue; + if (rv) + return 0; + rv = c->lines[i]; + } + return rv; +} + +static void empty_rect(rect_s * rect) +{ + rect->x1 = rect->y1 = INT_MAX; + rect->x2 = rect->y2 = INT_MIN; +} + +static void add_point_to_rect(rect_s * rect, int x, int y, int w) +{ + if (rect->x1 > x - w) + rect->x1 = x - w; + if (rect->x2 < x + w) + rect->x2 = x + w; + if (rect->y1 > y - w) + rect->y1 = y - w; + if (rect->y2 < y + w) + rect->y2 = y + w; +} + +static void add_line_to_rect(rect_s * rect, line_s * l) +{ + add_point_to_rect(rect, l->s->x, l->s->y, 0); + add_point_to_rect(rect, l->e->x, l->e->y, 0); +} + +static int pin_in_rect(rect_s * r, int x, int y, int w) +{ + if (x < r->x1 && x + w < r->x1) + return 0; + if (x > r->x2 && x - w > r->x2) + return 0; + if (y < r->y1 && y + w < r->y1) + return 0; + if (y > r->y2 && y - w > r->y2) + return 0; + return 1; +} + +static int line_in_rect(rect_s * r, line_s * l) +{ + rect_s lr; + empty_rect(&lr); + add_point_to_rect(&lr, l->s->x, l->s->y, l->line->Thickness / 2); + add_point_to_rect(&lr, l->e->x, l->e->y, l->line->Thickness / 2); + dprintf("line_in_rect %#mD-%#mD vs %#mD-%#mD\n", r->x1, r->y1, r->x2, r->y2, lr.x1, lr.y1, lr.x2, lr.y2); + /* simple intersection of rectangles */ + if (lr.x1 < r->x1) + lr.x1 = r->x1; + if (lr.x2 > r->x2) + lr.x2 = r->x2; + if (lr.y1 < r->y1) + lr.y1 = r->y1; + if (lr.y2 > r->y2) + lr.y2 = r->y2; + if (lr.x1 < lr.x2 && lr.y1 < lr.y2) + return 1; + return 0; +} + +static int corner_radius(corner_s * c) +{ + pcb_pstk_t *p = NULL; + int diam = 0; + int i; + + if (c->pin) p = c->pin; + if (c->via) p = c->via; + if (c->pad) p = c->pad; + if (p != NULL) + diam = djmax(p->BoundingBox.X2 - p->BoundingBox.X1, p->BoundingBox.Y2 - p->BoundingBox.Y1); + + for (i = 0; i < c->n_lines; i++) + if (c->lines[i]->line) + diam = djmax(c->lines[i]->line->Thickness, diam); + diam = (diam + 1) / 2; + return diam; +} + +static void add_corner_to_rect_if(rect_s * rect, corner_s * c, rect_s * e) +{ + int diam = corner_radius(c); + if (!pin_in_rect(e, c->x, c->y, diam)) + return; + if (c->x < e->x1 && c->y < e->y1 && dist(c->x, c->y, e->x1, e->y1) > diam) + return; + if (c->x > e->x2 && c->y < e->y1 && dist(c->x, c->y, e->x2, e->y1) > diam) + return; + if (c->x < e->x1 && c->y > e->y2 && dist(c->x, c->y, e->x1, e->y2) > diam) + return; + if (c->x > e->x2 && c->y > e->y2 && dist(c->x, c->y, e->x2, e->y2) > diam) + return; + + /*rnd_printf("add point %#mD diam %#mS\n", c->x, c->y, diam); */ + add_point_to_rect(rect, c->x, c->y, diam); +} + +static void remove_line(line_s * l) +{ + int i, j; + pcb_layer_t *layer = &(PCB->Data->Layer[l->layer]); + + check(0, 0); + + if (l->line) + pcb_line_destroy(layer, l->line); + + DELETE(l); + + for (i = 0, j = 0; i < l->s->n_lines; i++) + if (l->s->lines[i] != l) + l->s->lines[j++] = l->s->lines[i]; + l->s->n_lines = j; + + for (i = 0, j = 0; i < l->e->n_lines; i++) + if (l->e->lines[i] != l) + l->e->lines[j++] = l->e->lines[i]; + l->e->n_lines = j; + check(0, 0); +} + +static void move_line_to_layer(line_s * l, int layer) +{ + pcb_layer_t *ls, *ld; + + ls = pcb_get_layer(PCB->Data, l->layer); + ld = pcb_get_layer(PCB->Data, layer); + + pcb_move_obj_to_layer(PCB_OBJ_LINE, ls, l->line, 0, ld, 0); + l->layer = layer; +} + +static void remove_via_at(corner_s * c) +{ + pcb_remove_object(PCB_OBJ_PSTK, c->via, 0, 0); + c->via = 0; +} + +static void remove_corner(corner_s * c2) +{ + corner_s *c; + dprintf("remove corner %s\n", corner_name(c2)); + if (corners == c2) + corners = c2->next; + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if (c->next == c2) + c->next = c2->next; + } + if (next_corner == c2) + next_corner = c2->next; + free(c2->lines); + c2->lines = 0; + DELETE(c2); +} + +static void merge_corners(corner_s * c1, corner_s * c2) +{ + int i; + if (c1 == c2) + abort(); + dprintf("merge corners %s %s\n", corner_name(c1), corner_name(c2)); + for (i = 0; i < c2->n_lines; i++) { + add_line_to_corner(c2->lines[i], c1); + if (c2->lines[i]->s == c2) + c2->lines[i]->s = c1; + if (c2->lines[i]->e == c2) + c2->lines[i]->e = c1; + } + if (c1->via && c2->via) + remove_via_at(c2); + else if (c2->via) + c1->via = c2->via; + if (c2->pad) + c1->pad = c2->pad; + if (c2->pin) + c1->pin = c2->pin; + if (c2->layer != c1->layer) + c1->layer = -1; + + remove_corner(c2); +} + +static void move_corner(corner_s * c, int x, int y) +{ + pcb_pstk_t *via; + int i; + corner_s *pad; + + check(c, 0); + if (c->pad || c->pin) + dj_abort("move_corner: has pin or pad\n"); + dprintf("move_corner %p from %#mD to %#mD\n", (void *) c, c->x, c->y, x, y); + pad = find_corner_if(x, y, c->layer); + c->x = x; + c->y = y; + via = c->via; + if (via) { + pcb_move_obj(PCB_OBJ_PSTK, via, via, via, x - via->x, y - via->y); + dprintf("via move %#mD to %#mD\n", via->x, via->y, x, y); + } + for (i = 0; i < c->n_lines; i++) { + pcb_line_t *tl = c->lines[i]->line; + if (tl) { + if (c->lines[i]->s == c) { + pcb_move_obj(PCB_OBJ_LINE_POINT, pcb_get_layer(PCB->Data, c->lines[i]->layer), tl, &tl->Point1, x - (tl->Point1.X), y - (tl->Point1.Y)); + } + else { + pcb_move_obj(PCB_OBJ_LINE_POINT, pcb_get_layer(PCB->Data, c->lines[i]->layer), tl, &tl->Point2, x - (tl->Point2.X), y - (tl->Point2.Y)); + } + dprintf("Line %p moved to %#mD %#mD\n", (void *) tl, tl->Point1.X, tl->Point1.Y, tl->Point2.X, tl->Point2.Y); + } + } + if (pad && pad != c) + merge_corners(c, pad); + else + for (i = 0; i < c->n_lines; i++) { + if (c->lines[i]->s->x == c->lines[i]->e->x && c->lines[i]->s->y == c->lines[i]->e->y) { + corner_s *c2 = other_corner(c->lines[i], c); + dprintf("move_corner: removing line %#mD %#mD %p %p\n", c->x, c->y, c2->x, c2->y, (void *) c, (void *) c2); + + remove_line(c->lines[i]); + if (c != c2) + merge_corners(c, c2); + check(c, 0); + i--; + break; + } + } + rnd_hid_progress(0, 0, 0); + check(c, 0); +} + +static int any_line_selected() +{ + line_s *l; + for (l = lines; l; l = l->next) { + if (DELETED(l)) + continue; + if (l->line && selected(l->line)) + return 1; + } + return 0; +} + +static int trim_step(int s, int l1, int l2) +{ + dprintf("trim %d %d %d\n", s, l1, l2); + if (s > l1) + s = l1; + if (s > l2) + s = l2; + if (s != l1 && s != l2) + s = gridsnap(s); + return s; +} + +static int canonicalize_line(line_s * l); + +static int split_line(line_s * l, corner_s * c) +{ + int i; + pcb_line_t *pcbline; + line_s *ls; + + if (!intersecting_layers(l->layer, c->layer)) + return 0; + if (l->is_pad) + return 0; + if (c->pad) { + dprintf("split on pad!\n"); + if (l->s->pad == c->pad || l->e->pad == c->pad) + return 0; + dprintf("splitting...\n"); + } + + check(c, l); + pcbline = create_pcb_line(l->layer, c->x, c->y, l->e->x, l->e->y, l->line->Thickness, l->line->Clearance, l->line->Flags); + if (pcbline == 0) + return 0; /* already a line there */ + + check(c, l); + + dprintf("split line from %#mD to %#mD at %#mD\n", l->s->x, l->s->y, l->e->x, l->e->y, c->x, c->y); + ls = (line_s *) malloc(sizeof(line_s)); + + ls->next = lines; + lines = ls; + ls->is_pad = 0; + ls->s = c; + ls->e = l->e; + ls->line = pcbline; + ls->layer = l->layer; + for (i = 0; i < l->e->n_lines; i++) + if (l->e->lines[i] == l) + l->e->lines[i] = ls; + l->e = c; + add_line_to_corner(l, c); + add_line_to_corner(ls, c); + + pcb_move_obj(PCB_OBJ_LINE_POINT, pcb_get_layer(PCB->Data, l->layer), l->line, &l->line->Point2, + c->x - (l->line->Point2.X), c->y - (l->line->Point2.Y)); + + return 1; +} + +static int canonicalize_line(line_s * l) +{ + /* This could be faster */ + corner_s *c; + if (l->s->x == l->e->x) { + int y1 = l->s->y; + int y2 = l->e->y; + int x1 = l->s->x - l->line->Thickness / 2; + int x2 = l->s->x + l->line->Thickness / 2; + if (y1 > y2) { + int t = y1; + y1 = y2; + y2 = t; + } + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if ((y1 < c->y && c->y < y2) + && intersecting_layers(l->layer, c->layer)) { + if (c->x != l->s->x && c->x < x2 && c->x > x1 && !(c->pad || c->pin)) { + move_corner(c, l->s->x, c->y); + } + if (c->x == l->s->x) { + /* FIXME: if the line is split, we have to re-canonicalize + both segments. */ + return split_line(l, c); + } + } + } + } + else if (l->s->y == l->e->y) { + int x1 = l->s->x; + int x2 = l->e->x; + int y1 = l->s->y - l->line->Thickness / 2; + int y2 = l->s->y + l->line->Thickness / 2; + if (x1 > x2) { + int t = x1; + x1 = x2; + x2 = t; + } + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if ((x1 < c->x && c->x < x2) + && intersecting_layers(l->layer, c->layer)) { + if (c->y != l->s->y && c->y < y2 && c->y > y1 && !(c->pad || c->pin)) { + move_corner(c, c->x, l->s->y); + } + if (c->y == l->s->y) { + /* FIXME: Likewise. */ + return split_line(l, c); + } + } + } + } + else { + /* diagonal lines. Let's try to split them at pins/vias + anyway. */ + int x1 = l->s->x; + int x2 = l->e->x; + int y1 = l->s->y; + int y2 = l->e->y; + if (x1 > x2) { + int t = x1; + x1 = x2; + x2 = t; + } + if (y1 > y2) { + int t = y1; + y1 = y2; + y2 = t; + } + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if (!c->via && !c->pin) + continue; + if ((x1 < c->x && c->x < x2) + && (y1 < c->y && c->y < y2) + && intersecting_layers(l->layer, c->layer)) { + pcb_pstk_t *p = c->pin ? c->pin : c->via; + int th = djmax(p->BoundingBox.X2 - p->BoundingBox.X1, p->BoundingBox.Y2 - p->BoundingBox.Y1); + th /= 2; + if (dist(l->s->x, l->s->y, c->x, c->y) > th + && dist(l->e->x, l->e->y, c->x, c->y) > th && pcb_isc_pstk_line(pcb_find0, p, l->line, rnd_false)) { + return split_line(l, c); + } + } + } + } + return 0; +} + +/* Make sure all vias are at line end points */ +static int canonicalize_lines() +{ + int changes = 0; + int count; + line_s *l; + while (1) { + count = 0; + for (l = lines; l; l = l->next) { + if (DELETED(l)) + continue; + count += canonicalize_line(l); + } + changes += count; + if (count == 0) + break; + } + return changes; +} + +static int simple_optimize_corner(corner_s * c) +{ + int i; + int rv = 0; + + check(c, 0); + if (c->via) { + /* see if no via is needed */ + if (selected(c->via)) + dprintf("via check: line[0] layer %d at %#mD nl %d\n", c->lines[0]->layer, c->x, c->y, c->n_lines); + /* We can't delete vias that connect to power planes, or vias + have terminal name (assume they're test points). */ + if (!PCB_FLAG_THERM_TEST_ANY(c->via) && (c->via->term == NULL)) { + for (i = 1; i < c->n_lines; i++) { + if (selected(c->via)) + dprintf(" line[%d] layer %d %#mD to %#mD\n", + i, c->lines[i]->layer, c->lines[i]->s->x, c->lines[i]->s->y, c->lines[i]->e->x, c->lines[i]->e->y); + if (c->lines[i]->layer != c->lines[0]->layer) + break; + } + if (i == c->n_lines) { + if (selected(c->via)) + dprintf(" remove it\n"); + remove_via_at(c); + rv++; + } + } + } + + check(c, 0); + if (c->n_lines == 2 && !c->via) { + /* see if it is an unneeded corner */ + int o = line_orient(c->lines[0], c); + corner_s *c2 = other_corner(c->lines[1], c); + corner_s *c0 = other_corner(c->lines[0], c); + if (o == line_orient(c->lines[1], c2) && o != DIAGONAL) { + dprintf("straight %#mD to %#mD to %#mD\n", c0->x, c0->y, c->x, c->y, c2->x, c2->y); + if (selected(c->lines[0]->line)) + PCB_FLAG_SET(PCB_FLAG_SELECTED, c->lines[1]->line); + if (selected(c->lines[1]->line)) + PCB_FLAG_SET(PCB_FLAG_SELECTED, c->lines[0]->line); + move_corner(c, c2->x, c2->y); + } + } + check(c, 0); + if (c->n_lines == 1 && !c->via) { + corner_s *c0 = other_corner(c->lines[0], c); + if (abs(c->x - c0->x) + abs(c->y - c0->y) <= LONGEST_FRECKLE) { + /* + * Remove this line, as it is a "freckle". A freckle is an extremely + * short line (around 0.01 thou) that is unconnected at one end. + * Freckles are almost insignificantly small, but are annoying as + * they prevent the mitering optimiser from working. + * Freckles sometimes arise because of a bug in the autorouter that + * causes it to create small overshoots (typically 0.01 thou) at the + * intersections of vertical and horizontal lines. These overshoots + * are converted to freckles as a side effect of canonicalize_line(). + * Note that canonicalize_line() is not at fault, the bug is in the + * autorouter creating overshoots. + * The autorouter bug arose some time between the 20080202 and 20091103 + * releases. + * This code is probably worth keeping even when the autorouter bug is + * fixed, as "freckles" could conceivably arise in other ways. + */ + dprintf("freckle %#mD to %#mD\n", c->x, c->y, c0->x, c0->y); + move_corner(c, c0->x, c0->y); + } + } + check(c, 0); + return rv; +} + +/* We always run these */ +static int simple_optimizations() +{ + corner_s *c; + int rv = 0; + + /* Look for corners that aren't */ + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if (c->pad || c->pin) + continue; + rv += simple_optimize_corner(c); + } + return rv; +} + +static int is_hole(corner_s * c) +{ + return c->pin || c->pad || c->via; +} + +static int orthopull_1(corner_s * c, int fdir, int rdir, int any_sel) +{ + static corner_s **cs = 0; + static int cm = 0; + static line_s **ls = 0; + static int lm = 0; + int i, li, ln, cn, snap; + line_s *l = 0; + corner_s *c2, *cb; + int adir = 0, sdir = 0, pull; + int saw_sel = 0, saw_auto = 0; + int max, len = 0, r1 = 0, r2; + rect_s rr; + int edir = 0, done; + + if (cs == 0) { + cs = (corner_s **) malloc(10 * sizeof(corner_s)); + cm = 10; + ls = (line_s **) malloc(10 * sizeof(line_s)); + lm = 10; + } + + for (i = 0; i < c->n_lines; i++) { + int o = line_orient(c->lines[i], c); + if (o == rdir) + return 0; + } + + switch (fdir) { + case RIGHT: + adir = DOWN; + sdir = UP; + break; + case DOWN: + adir = RIGHT; + sdir = LEFT; + break; + default: + dj_abort("fdir not right or down\n"); + } + + c2 = c; + cn = 0; + ln = 0; + pull = 0; + while (c2) { + if (c2->pad || c2->pin || c2->n_lines < 2) + return 0; + if (cn >= cm) { + cm = cn + 10; + cs = (corner_s **) realloc(cs, cm * sizeof(corner_s)); + } + cs[cn++] = c2; + r2 = corner_radius(c2); + if (r1 < r2) + r1 = r2; + l = 0; + for (i = 0; i < c2->n_lines; i++) { + int o = line_orient(c2->lines[i], c2); + if (o == DIAGONAL) + return 0; + if (o == fdir) { + if (l) + return 0; /* we don't support overlapping lines yet */ + l = c2->lines[i]; + } + if (o == rdir && c2->lines[i] != ls[ln - 1]) + return 0; /* likewise */ + if (o == adir) + pull++; + if (o == sdir) + pull--; + } + if (!l) + break; + if (selected(l->line)) + saw_sel = 1; + if (autorouted(l->line)) + saw_auto = 1; + if (ln >= lm) { + lm = ln + 10; + ls = (line_s **) realloc(ls, lm * sizeof(line_s)); + } + ls[ln++] = l; + c2 = other_corner(l, c2); + } + if (cn < 2 || pull == 0) + return 0; + if (any_sel && !saw_sel) + return 0; + if (!any_sel && conf_djopt.plugins.djopt.auto_only && !saw_auto) + return 0; + + /* Ok, now look for other blockages. */ + + empty_rect(&rr); + add_point_to_rect(&rr, c->x, c->y, corner_radius(c)); + add_point_to_rect(&rr, c2->x, c2->y, corner_radius(c2)); + + if (fdir == RIGHT && pull < 0) + edir = UP; + else if (fdir == RIGHT && pull > 0) + edir = DOWN; + else if (fdir == DOWN && pull < 0) + edir = LEFT; + else if (fdir == DOWN && pull > 0) + edir = RIGHT; + + max = -1; + for (i = 0; i < cn; i++) + for (li = 0; li < cs[i]->n_lines; li++) { + if (line_orient(cs[i]->lines[li], cs[i]) != edir) + continue; + len = line_length(cs[i]->lines[li]); + if (max > len || max == -1) + max = len; + } + dprintf("c %s %4#mD cn %d pull %3d max %4#mS\n", fdir == RIGHT ? "right" : "down ", c->x, c->y, cn, pull, max); + + switch (edir) { + case UP: + rr.y1 = c->y - r1 - max; + break; + case DOWN: + rr.y2 = c->y + r1 + max; + break; + case LEFT: + rr.x1 = c->x - r1 - max; + break; + case RIGHT: + rr.x2 = c->x + r1 + max; + break; + } + rr.x1 -= SB + 1; + rr.x2 += SB + 1; + rr.y1 -= SB + 1; + rr.y2 += SB + 1; + + snap = 0; + for (cb = corners; cb; cb = cb->next) { + int sep; + if (DELETED(cb)) + continue; + r1 = corner_radius(cb); + if (cb->net == c->net && !cb->pad) + continue; + if (!pin_in_rect(&rr, cb->x, cb->y, r1)) + continue; + switch (edir) { +#define ECHK(X,Y,LT) \ + for (i=0; ilayer, cb->layer)) \ + continue; \ + r2 = corner_radius(cs[i]); \ + if (cb->X + r1 <= cs[i]->X - r2 - SB - 1) \ + continue; \ + if (cb->X - r1 >= cs[i]->X + r2 + SB + 1) \ + continue; \ + if (cb->Y LT cs[i]->Y) \ + continue; \ + sep = djabs(cb->Y - cs[i]->Y) - r1 - r2 - SB - 1; \ + if (max > sep) \ + { max = sep; snap = 1; }\ + } \ + for (i=0; ilayer, cb->layer)) \ + continue; \ + if (cb->X <= cs[i]->X || cb->X >= cs[i+1]->X) \ + continue; \ + sep = (djabs(cb->Y - cs[i]->Y) - ls[i]->line->Thickness/2 \ + - r1 - SB - 1); \ + if (max > sep) \ + { max = sep; snap = 1; }\ + } + case UP: + ECHK(x, y, >=); + break; + case DOWN: + ECHK(x, y, <=); + break; + case LEFT: + ECHK(y, x, >=); + break; + case RIGHT: + ECHK(y, x, <=); + break; + } + } + + /* We must now check every line segment against our corners. */ + for (l = lines; l; l = l->next) { + int o, x1, x2, y1, y2; + if (DELETED(l)) + continue; + dprintf("check line %#mD to %#mD\n", l->s->x, l->s->y, l->e->x, l->e->y); + if (l->s->net == c->net) { + dprintf(" same net\n"); + continue; + } + o = line_orient(l, 0); + /* We don't need to check perpendicular lines, because their + corners already take care of it. */ + if ((fdir == RIGHT && (o == UP || o == DOWN)) + || (fdir == DOWN && (o == RIGHT || o == LEFT))) { + dprintf(" perpendicular\n"); + continue; + } + + /* Choose so that x1,y1 is closest to corner C */ + if ((fdir == RIGHT && l->s->x < l->e->x) + || (fdir == DOWN && l->s->y < l->e->y)) { + x1 = l->s->x; + y1 = l->s->y; + x2 = l->e->x; + y2 = l->e->y; + } + else { + x1 = l->e->x; + y1 = l->e->y; + x2 = l->s->x; + y2 = l->s->y; + } + + /* Eliminate all lines outside our range */ + if ((fdir == RIGHT && (x2 < c->x || x1 > c2->x)) + || (fdir == DOWN && (y2 < c->y || y1 > c2->y))) { + dprintf(" outside our range\n"); + continue; + } + + /* Eliminate all lines on the wrong side of us */ + if ((edir == UP && y1 > c->y && y2 > c->y) + || (edir == DOWN && y1 < c->y && y2 < c->y) + || (edir == LEFT && x1 > c->x && x2 > c->x) + || (edir == RIGHT && x1 < c->x && x2 < c->x)) { + dprintf(" wrong side\n"); + continue; + } + + /* For now, cheat on diagonals */ + switch (edir) { + case RIGHT: + if (x1 > x2) + x1 = x2; + break; + case LEFT: + if (x1 < x2) + x1 = x2; + break; + case DOWN: + if (y1 > y2) + y1 = y2; + break; + case UP: + if (y1 < y2) + y1 = y2; + break; + } + + /* Ok, now see how far we can get for each of our corners. */ + for (i = 0; i < cn; i++) { + int r = l->line->Thickness + SB + corner_radius(cs[i]) + 1; + int len = 0; + if ((fdir == RIGHT && (x2 < cs[i]->x || x1 > cs[i]->x)) + || (fdir == DOWN && (y2 < cs[i]->y || y1 > cs[i]->y))) + continue; + if (!intersecting_layers(cs[i]->layer, l->layer)) + continue; + switch (edir) { + case RIGHT: + len = x1 - c->x; + break; + case LEFT: + len = c->x - x1; + break; + case DOWN: + len = y1 - c->y; + break; + case UP: + len = c->y - y1; + break; + } + len -= r; + dprintf(" len is %#mS vs corner at %#mD\n", len, cs[i]->x, cs[i]->y); + if (len <= 0) + return 0; + if (max > len) + max = len; + } + + } + + /* We must make sure that if a segment isn't being completely + removed, that any vias and/or pads don't overlap. */ + done = 0; + while (!done) { + done = 1; + for (i = 0; i < cn; i++) + for (li = 0; li < cs[i]->n_lines; li++) { + line_s *l = cs[i]->lines[li]; + corner_s *oc = other_corner(l, cs[i]); + if (line_orient(l, cs[i]) != edir) + continue; + len = line_length(l); + if (!oc->pad || !cs[i]->via) { + if (!is_hole(l->s) || !is_hole(l->e)) + continue; + if (len == max) + continue; + } + len -= corner_radius(l->s); + len -= corner_radius(l->e); + len -= SB + 1; + if (max > len) { + max = len; + done = 0; + } + } + } + + if (max <= 0) + return 0; + switch (edir) { + case UP: + len = c->y - max; + break; + case DOWN: + len = c->y + max; + break; + case LEFT: + len = c->x - max; + break; + case RIGHT: + len = c->x + max; + break; + } + if (snap && max > rnd_conf.editor.grid) { + if (pull < 0) + len += rnd_conf.editor.grid - 1; + len = gridsnap(len); + } + if ((fdir == RIGHT && len == cs[0]->y) || (fdir == DOWN && len == cs[0]->x)) + return 0; + for (i = 0; i < cn; i++) { + if (fdir == RIGHT) { + max = len - cs[i]->y; + move_corner(cs[i], cs[i]->x, len); + } + else { + max = len - cs[i]->x; + move_corner(cs[i], len, cs[i]->y); + } + } + return max * pull; +} + +static int orthopull() +{ + /* Look for straight runs which could be moved to reduce total trace + length. */ + int any_sel = any_line_selected(); + corner_s *c; + int rv = 0; + + for (c = corners; c;) { + if (DELETED(c)) + continue; + if (c->pin || c->pad) { + c = c->next; + continue; + } + next_corner = c; + rv += orthopull_1(c, RIGHT, LEFT, any_sel); + if (c != next_corner) { + c = next_corner; + continue; + } + rv += orthopull_1(c, DOWN, UP, any_sel); + if (c != next_corner) { + c = next_corner; + continue; + } + c = c->next; + } + if (rv) + rnd_printf("orthopull: %ml mils saved\n", rv); + return rv; +} + +static int debumpify() +{ + /* Look for "U" shaped traces we can shorten (or eliminate) */ + int rv = 0; + int any_selected = any_line_selected(); + line_s *l, *l1, *l2; + corner_s *c, *c1, *c2; + rect_s rr, rp; + int o, o1, o2, step, w; + for (l = lines; l; l = l->next) { + if (DELETED(l)) + continue; + if (!l->line) + continue; + if (any_selected && !selected(l->line)) + continue; + if (!any_selected && conf_djopt.plugins.djopt.auto_only && !autorouted(l->line)) + continue; + if (l->s->pin || l->s->pad || l->e->pin || l->e->pad) + continue; + o = line_orient(l, 0); + if (o == DIAGONAL) + continue; + l1 = other_line(l->s, l); + if (!l1) + continue; + o1 = line_orient(l1, l->s); + l2 = other_line(l->e, l); + if (!l2) + continue; + o2 = line_orient(l2, l->e); + if (ORIENT(o) == ORIENT(o1) || o1 != o2 || o1 == DIAGONAL) + continue; + + dprintf("\nline: %#mD to %#mD\n", l->s->x, l->s->y, l->e->x, l->e->y); + w = l->line->Thickness / 2 + SB + 1; + empty_rect(&rr); + add_line_to_rect(&rr, l1); + add_line_to_rect(&rr, l2); + if (rr.x1 != l->s->x && rr.x1 != l->e->x) + rr.x1 -= w; + if (rr.x2 != l->s->x && rr.x2 != l->e->x) + rr.x2 += w; + if (rr.y1 != l->s->y && rr.y1 != l->e->y) + rr.y1 -= w; + if (rr.y2 != l->s->y && rr.y2 != l->e->y) + rr.y2 += w; + dprintf("range: x %#mS..%#mS y %#mS..%#mS\n", rr.x1, rr.x2, rr.y1, rr.y2); + + c1 = other_corner(l1, l->s); + c2 = other_corner(l2, l->e); + + empty_rect(&rp); + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if (c->net != l->s->net && intersecting_layers(c->layer, l->s->layer)) + add_corner_to_rect_if(&rp, c, &rr); + } + if (rp.x1 == INT_MAX) { + rp.x1 = rr.x2; + rp.x2 = rr.x1; + rp.y1 = rr.y2; + rp.y2 = rr.y1; + } + dprintf("pin r: x %#mS..%#mS y %#mS..%#mS\n", rp.x1, rp.x2, rp.y1, rp.y2); + + switch (o1) { + case LEFT: + step = l->s->x - rp.x2 - w; + step = gridsnap(step); + if (step > l->s->x - c1->x) + step = l->s->x - c1->x; + if (step > l->s->x - c2->x) + step = l->s->x - c2->x; + if (step > 0) { + dprintf("left step %#mS at %#mD\n", step, l->s->x, l->s->y); + move_corner(l->s, l->s->x - step, l->s->y); + move_corner(l->e, l->e->x - step, l->e->y); + rv += step; + } + break; + case RIGHT: + step = rp.x1 - l->s->x - w; + step = gridsnap(step); + if (step > c1->x - l->s->x) + step = c1->x - l->s->x; + if (step > c2->x - l->s->x) + step = c2->x - l->s->x; + if (step > 0) { + dprintf("right step %#mS at %#mD\n", step, l->s->x, l->s->y); + move_corner(l->s, l->s->x + step, l->s->y); + move_corner(l->e, l->e->x + step, l->e->y); + rv += step; + } + break; + case UP: + if (rp.y2 == INT_MIN) + rp.y2 = rr.y1; + step = trim_step(l->s->y - rp.y2 - w, l->s->y - c1->y, l->s->y - c2->y); + if (step > 0) { + dprintf("up step %#mS at %#mD\n", step, l->s->x, l->s->y); + move_corner(l->s, l->s->x, l->s->y - step); + move_corner(l->e, l->e->x, l->e->y - step); + rv += step; + } + break; + case DOWN: + step = rp.y1 - l->s->y - w; + step = gridsnap(step); + if (step > c1->y - l->s->y) + step = c1->y - l->s->y; + if (step > c2->y - l->s->y) + step = c2->y - l->s->y; + if (step > 0) { + dprintf("down step %#mS at %#mD\n", step, l->s->x, l->s->y); + move_corner(l->s, l->s->x, l->s->y + step); + move_corner(l->e, l->e->x, l->e->y + step); + rv += step; + } + break; + } + check(0, l); + } + + rv += simple_optimizations(); + if (rv) + rnd_printf("debumpify: %ml mils saved\n", rv / 50); + return rv; +} + +static int simple_corner(corner_s * c) +{ + int o1, o2; + if (c->pad || c->pin || c->via) + return 0; + if (c->n_lines != 2) + return 0; + o1 = line_orient(c->lines[0], c); + o2 = line_orient(c->lines[1], c); + if (ORIENT(o1) == ORIENT(o2)) + return 0; + if (ORIENT(o1) == DIAGONAL || ORIENT(o2) == DIAGONAL) + return 0; + return 1; +} + +static int unjaggy_once() +{ + /* Look for sequences of simple corners we can reduce. */ + int rv = 0; + corner_s *c, *c0, *c1, *cc; + int l, w, sel = any_line_selected(); + int o0, o1, s0, s1; + rect_s rr, rp; + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if (!simple_corner(c)) + continue; + if (!c->lines[0]->line || !c->lines[1]->line) + continue; + if (sel && !(selected(c->lines[0]->line) + || selected(c->lines[1]->line))) + continue; + if (!sel && conf_djopt.plugins.djopt.auto_only && !(autorouted(c->lines[0]->line) + || autorouted(c->lines[1]->line))) + continue; + dprintf("simple at %#mD\n", c->x, c->y); + + c0 = other_corner(c->lines[0], c); + o0 = line_orient(c->lines[0], c); + s0 = simple_corner(c0); + + c1 = other_corner(c->lines[1], c); + o1 = line_orient(c->lines[1], c); + s1 = simple_corner(c1); + + if (!s0 && !s1) + continue; + dprintf("simples at %#mD\n", c->x, c->y); + + w = 1; + for (l = 0; l < c0->n_lines; l++) + if (c0->lines[l] != c->lines[0] + && c0->lines[l]->layer == c->lines[0]->layer) { + int o = line_orient(c0->lines[l], c0); + if (o == o1) + w = 0; + } + for (l = 0; l < c1->n_lines; l++) + if (c1->lines[l] != c->lines[0] + && c1->lines[l]->layer == c->lines[0]->layer) { + int o = line_orient(c1->lines[l], c1); + if (o == o0) + w = 0; + } + if (!w) + continue; + dprintf("orient ok\n"); + + w = c->lines[0]->line->Thickness / 2 + SB + 1; + empty_rect(&rr); + add_line_to_rect(&rr, c->lines[0]); + add_line_to_rect(&rr, c->lines[1]); + if (c->x != rr.x1) + rr.x1 -= w; + else + rr.x2 += w; + if (c->y != rr.y1) + rr.y1 -= w; + else + rr.y2 += w; + + empty_rect(&rp); + for (cc = corners; cc; cc = cc->next) { + if (DELETED(cc)) + continue; + if (cc->net != c->net && intersecting_layers(cc->layer, c->layer)) + add_corner_to_rect_if(&rp, cc, &rr); + } + dprintf("rp x %#mS..%#mS y %#mS..%#mS\n", rp.x1, rp.x2, rp.y1, rp.y2); + if (rp.x1 <= rp.x2) /* something triggered */ + continue; + + dprintf("unjaggy at %#mD layer %d\n", c->x, c->y, c->layer); + if (c->x == c0->x) + move_corner(c, c1->x, c0->y); + else + move_corner(c, c0->x, c1->y); + rv++; + check(c, 0); + } + rv += simple_optimizations(); + check(c, 0); + return rv; +} + +static int unjaggy() +{ + int i, r = 0, j; + for (i = 0; i < 100; i++) { + j = unjaggy_once(); + if (j == 0) + break; + r += j; + } + if (r) + printf("%d unjagg%s \n", r, r == 1 ? "y" : "ies"); + return r; +} + +static int vianudge() +{ + /* Look for vias with all lines leaving the same way, try to nudge + via to eliminate one or more of them. */ + int rv = 0; + corner_s *c, *c2, *c3; + line_s *l; + unsigned char directions[PCB_MAX_LAYER]; + unsigned char counts[PCB_MAX_LAYER]; + + memset(directions, 0, sizeof(directions)); + memset(counts, 0, sizeof(counts)); + + for (c = corners; c; c = c->next) { + int o, i, vr, cr, oboth; + int len = 0, saved = 0; + + if (DELETED(c)) + continue; + + if (!c->via) + continue; + + memset(directions, 0, sizeof(directions)); + memset(counts, 0, sizeof(counts)); + + for (i = 0; i < c->n_lines; i++) { + o = line_orient(c->lines[i], c); + counts[c->lines[i]->layer]++; + directions[c->lines[i]->layer] |= o; + } + for (o = 0, i = 0; i < pcb_max_layer(PCB); i++) { + if (!(pcb_layer_flags(PCB, i) & PCB_LYT_COPPER)) + continue; + if (counts[i] == 1) { + o = directions[i]; + break; + } + } + switch (o) { + case LEFT: + case RIGHT: + oboth = LEFT | RIGHT; + break; + case UP: + case DOWN: + oboth = UP | DOWN; + break; + default: + continue; + } + for (i = 0; i < pcb_max_layer(PCB); i++) { + if (!(pcb_layer_flags(PCB, i) & PCB_LYT_COPPER)) + continue; + if (counts[i] && directions[i] != o && directions[i] != oboth) + goto vianudge_continue; + } + c2 = 0; + for (i = 0; i < c->n_lines; i++) { + int ll = line_length(c->lines[i]); + if (line_orient(c->lines[i], c) != o) { + saved--; + continue; + } + saved++; + if (c2 == 0 || len > ll) { + len = ll; + c2 = other_corner(c->lines[i], c); + } + } + if (c2->pad || c2->pin || c2->via) + continue; + + /* Now look for clearance in the new position */ + vr = djmax(c->via->BoundingBox.X2 - c->via->BoundingBox.X1, c->via->BoundingBox.Y2 - c->via->BoundingBox.Y1); + vr = vr / 2 + SB + 1; + for (c3 = corners; c3; c3 = c3->next) { + if (DELETED(c3)) + continue; + if ((c3->net != c->net && (c3->pin || c3->via)) || c3->pad) { + cr = corner_radius(c3); + if (dist(c2->x, c2->y, c3->x, c3->y) < vr + cr) + goto vianudge_continue; + } + } + for (l = lines; l; l = l->next) { + if (DELETED(l)) + continue; + if (l->s->net != c->net) { + int ld = dist_line_to_point(l, c2); + if (ld < l->line->Thickness / 2 + vr) + goto vianudge_continue; + } + } + + /* at this point, we know we can move it */ + + dprintf("vianudge: nudging via at %#mD by %#mS saving %#mS\n", c->x, c->y, len, saved); + rv += len * saved; + move_corner(c, c2->x, c2->y); + + check(c, 0); + + vianudge_continue: + continue; + } + + if (rv) + rnd_printf("vianudge: %ml mils saved\n", rv); + return rv; +} + +static int viatrim() +{ + /* Look for traces that can be moved to the other side of the board, + to reduce the number of vias needed. For now, we look for simple + lines, not multi-segmented lines. */ + line_s *l, *l2; + int i, rv = 0, vrm = 0; + int any_sel = any_line_selected(); + + for (l = lines; l; l = l->next) { + rect_s r; + int my_layer, other_layer; + + if (DELETED(l)) + continue; + if (!l->s->via) + continue; + if (!l->e->via) + continue; + if (any_sel && !selected(l->line)) + continue; + if (!any_sel && conf_djopt.plugins.djopt.auto_only && !autorouted(l->line)) + continue; + + my_layer = l->layer; + other_layer = -1; + dprintf("line %p on layer %d from %#mD to %#mD\n", (void *) l, l->layer, l->s->x, l->s->y, l->e->x, l->e->y); + for (i = 0; i < l->s->n_lines; i++) + if (l->s->lines[i] != l) { + if (other_layer == -1) { + other_layer = l->s->lines[i]->layer; + dprintf("noting other line %p on layer %d\n", (void *) (l->s->lines[i]), my_layer); + } + else if (l->s->lines[i]->layer != other_layer) { + dprintf("saw other line %p on layer %d (not %d)\n", (void *) (l->s->lines[i]), l->s->lines[i]->layer, my_layer); + other_layer = -1; + goto viatrim_other_corner; + } + } + viatrim_other_corner: + if (other_layer == -1) + for (i = 0; i < l->e->n_lines; i++) + if (l->e->lines[i] != l) { + if (other_layer == -1) { + other_layer = l->s->lines[i]->layer; + dprintf("noting other line %p on layer %d\n", (void *) (l->s->lines[i]), my_layer); + } + else if (l->e->lines[i]->layer != other_layer) { + dprintf("saw end line on layer %d (not %d)\n", l->e->lines[i]->layer, other_layer); + goto viatrim_continue; + } + } + + /* Now see if any other line intersects us. We don't need to + check corners, because they'd either be pins/vias and + already conflict, or pads, which we'll check here anyway. */ + empty_rect(&r); + add_point_to_rect(&r, l->s->x, l->s->y, l->line->Thickness); + add_point_to_rect(&r, l->e->x, l->e->y, l->line->Thickness); + + for (l2 = lines; l2; l2 = l2->next) { + if (DELETED(l2)) + continue; + if (l2->s->net != l->s->net && l2->layer == other_layer) { + dprintf("checking other line %#mD to %#mD\n", l2->s->x, l2->s->y, l2->e->x, l2->e->y); + if (line_in_rect(&r, l2)) { + dprintf("line from %#mD to %#mD in the way\n", l2->s->x, l2->s->y, l2->e->x, l2->e->y); + goto viatrim_continue; + } + } + } + + if (l->layer == other_layer) + continue; + move_line_to_layer(l, other_layer); + rv++; + + viatrim_continue: + continue; + } + vrm = simple_optimizations(); + if (rv > 0) + printf("viatrim: %d traces moved, %d vias removed\n", rv, vrm); + return rv + vrm; +} + +static int automagic() +{ + int more = 1, oldmore = 0; + int toomany = 100; + while (more != oldmore && --toomany) { + oldmore = more; + more += debumpify(); + more += unjaggy(); + more += orthopull(); + more += vianudge(); + more += viatrim(); + } + return more - 1; +} + +static int miter() +{ + corner_s *c; + int done, progress; + int sel = any_line_selected(); + int saved = 0; + + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + c->miter = 0; + if (c->n_lines == 2 && !c->via && !c->pin && !c->via) { + int o1 = line_orient(c->lines[0], c); + int o2 = line_orient(c->lines[1], c); + if (ORIENT(o1) != ORIENT(o2) + && o1 != DIAGONAL && o2 != DIAGONAL && c->lines[0]->line->Thickness == c->lines[1]->line->Thickness) + c->miter = -1; + } + } + + done = 0; + progress = 1; + while (!done && progress) { + done = 1; + progress = 0; + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if (c->miter == -1) { + int max = line_length(c->lines[0]); + int len = line_length(c->lines[1]); + int bloat; + int ref, dist; + corner_s *closest_corner = 0, *c2, *oc1, *oc2; + int mx = 0, my = 0, x, y; + int o1 = line_orient(c->lines[0], c); + int o2 = line_orient(c->lines[1], c); + + if (c->pad || c->pin || c->via) { + c->miter = 0; + progress = 1; + continue; + } + + oc1 = other_corner(c->lines[0], c); + oc2 = other_corner(c->lines[1], c); +#if 0 + if (oc1->pad) + oc1 = 0; + if (oc2->pad) + oc2 = 0; +#endif + + if ((sel && !(selected(c->lines[0]->line) + || selected(c->lines[1]->line))) + || (!sel && conf_djopt.plugins.djopt.auto_only && !(autorouted(c->lines[0]->line) + || autorouted(c->lines[1]->line)))) { + c->miter = 0; + progress = 1; + continue; + } + + if (max > len) + max = len; + switch (o1) { + case LEFT: + mx = -1; + break; + case RIGHT: + mx = 1; + break; + case UP: + my = -1; + break; + case DOWN: + my = 1; + break; + } + switch (o2) { + case LEFT: + mx = -1; + break; + case RIGHT: + mx = 1; + break; + case UP: + my = -1; + break; + case DOWN: + my = 1; + break; + } + ref = c->x * mx + c->y * my; + dist = max; + + bloat = (c->lines[0]->line->Thickness / 2 + SB + 1) * 3 / 2; + + for (c2 = corners; c2; c2 = c2->next) { + if (DELETED(c2)) + continue; + if (c2 != c && c2 != oc1 && c2 != oc2 + && c->x * mx <= c2->x * mx + && c->y * my <= c2->y * my && c->net != c2->net && intersecting_layers(c->layer, c2->layer)) { + int cr = corner_radius(c2); + len = c2->x * mx + c2->y * my - ref - cr - bloat; + if (c->x != c2->x && c->y != c2->y) + len -= cr; + if (len < dist || (len == dist && c->miter != -1)) { + dist = len; + closest_corner = c2; + } + } + } + + if (closest_corner && closest_corner->miter == -1) { + done = 0; + continue; + } + +#if 0 + if (dist < rnd_conf.editor.grid) { + c->miter = 0; + progress = 1; + continue; + } + + dist -= dist % rnd_conf.editor.grid; +#endif + if (dist <= 0) { + c->miter = 0; + progress = 1; + continue; + } + + x = c->x; + y = c->y; + switch (o1) { + case LEFT: + x -= dist; + break; + case RIGHT: + x += dist; + break; + case UP: + y -= dist; + break; + case DOWN: + y += dist; + break; + } + c2 = find_corner(x, y, c->layer); + if (c2 != other_corner(c->lines[0], c)) + split_line(c->lines[0], c2); + x = c->x; + y = c->y; + switch (o2) { + case LEFT: + x -= dist; + break; + case RIGHT: + x += dist; + break; + case UP: + y -= dist; + break; + case DOWN: + y += dist; + break; + } + move_corner(c, x, y); + c->miter = 0; + c2->miter = 0; + progress = 1; + saved++; + } + } + } + return saved; +} + +static void classify_corner(corner_s * c, int this_net) +{ + int i; + if (c->net == this_net) + return; + c->net = this_net; + for (i = 0; i < c->n_lines; i++) + classify_corner(other_corner(c->lines[i], c), this_net); +} + +static void classify_nets() +{ + static int this_net = 1; + corner_s *c; + + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if (c->net) + continue; + classify_corner(c, this_net); + this_net++; + } +} + +#if 0 +static void nudge_corner(corner_s * c, int dx, int dy, corner_s * prev_corner) +{ + int ox = c->x; + int oy = c->y; + int l; + if (prev_corner && (c->pin || c->pad)) + return; + move_corner(c, ox + dx, oy + dy); + for (l = 0; l < c->n_lines; l++) { + corner_s *oc = other_corner(c->lines[l], c); + if (oc == prev_corner) + continue; + if (dx && oc->x == ox) + nudge_corner(oc, dx, 0, c); + if (dy && oc->y == oy) + nudge_corner(oc, 0, dy, c); + } +} +#endif + +static line_s *choose_example_line(corner_s * c1, corner_s * c2) +{ + int ci, li; + corner_s *c[2]; + c[0] = c1; + c[1] = c2; + dprintf("choose_example_line\n"); + for (ci = 0; ci < 2; ci++) + for (li = 0; li < c[ci]->n_lines; li++) { + dprintf(" try[%d,%d] \033[36m<%#mD-%#mD t%#mS c%#mS f%s>\033[0m\n", + ci, li, + c[ci]->lines[li]->s->x, c[ci]->lines[li]->s->y, + c[ci]->lines[li]->e->x, c[ci]->lines[li]->e->y, + c[ci]->lines[li]->line->Thickness, + c[ci]->lines[li]->line->Clearance, pcb_strflg_f2s(c[ci]->lines[li]->line->Flags, PCB_OBJ_LINE, NULL, 0)); + /* Pads are disqualified, as we want to mimic a trace line. */ + if (c[ci]->lines[li]->line == (pcb_line_t *) c[ci]->pad) { + dprintf(" bad, pad\n"); + continue; + } + /* Lines on layers that don't connect to the other pad are bad too. */ + if (!intersecting_layers(c[ci]->lines[li]->layer, c[1 - ci]->layer)) { + dprintf(" bad, layers\n"); + continue; + } + dprintf(" good\n"); + return c[ci]->lines[li]; + } + dprintf("choose_example_line: none found!\n"); + return 0; +} + +static int connect_corners(corner_s * c1, corner_s * c2) +{ + int layer; + line_s *ex = choose_example_line(c1, c2); + pcb_line_t *example = ex->line; + + dprintf + ("connect_corners \033[32m%#mD to %#mD, example line %#mD to %#mD l%d\033[0m\n", + c1->x, c1->y, c2->x, c2->y, ex->s->x, ex->s->y, ex->e->x, ex->e->y, ex->layer); + + layer = ex->layer; + + /* Assume c1 is the moveable one. */ + if (!(c1->pin || c1->pad || c1->via) && c1->n_lines == 1) { + int nx, ny; + /* Extend the line */ + if (c1->lines[0]->s->x == c1->lines[0]->e->x) + nx = c1->x, ny = c2->y; + else + nx = c2->x, ny = c1->y; + if (nx != c2->x || ny != c2->y) { + move_corner(c1, nx, ny); + new_line(c1, c2, layer, example); + return 1; + } + else { + move_corner(c1, nx, ny); + return 1; + } + } + else { + corner_s *nc = find_corner(c1->x, c2->y, layer); + new_line(c1, nc, layer, example); + new_line(nc, c2, layer, example); + return 0; + } +} + +static void pinsnap() +{ + corner_s *c; + int best_dist[PCB_MAX_LAYER + 1]; + corner_s *best_c[PCB_MAX_LAYER + 1]; + int l, got_one; + int left = 0, right = 0, top = 0, bottom = 0; + pcb_pstk_t *pin; + int again = 1; + + int close = 0; + corner_s *c2; + + memset(best_c, 0, sizeof(best_c)); + memset(best_dist, 0, sizeof(best_dist)); + + /* Look for pins that have no connections. See if there's a corner + close by that should be connected to it. This usually happens + when the MUCS router needs to route to an off-grid pin. */ + while (again) { + again = 0; + for (c = corners; c; c = c->next) { + if (DELETED(c)) + continue; + if (!(c->pin || c->via || c->pad)) + continue; + + pin = NULL; + + dprintf("\ncorner %s\n", corner_name(c)); + if (c->pin) pin = c->pin; + if (c->via) pin = c->via; + if (c->pad) pin = c->pad; + left = pin->BoundingBox.X1; + right = pin->BoundingBox.X2; + top = pin->BoundingBox.Y1; + bottom = pin->BoundingBox.Y2; + + dprintf("%s x %#mS-%#mS y %#mS-%#mS\n", corner_name(c), left, right, bottom, top); + for (l = 0; l <= pcb_max_layer(PCB); l++) { + if (!(pcb_layer_flags(PCB, l) & PCB_LYT_COPPER)) + continue; + best_dist[l] = close * 2; + best_c[l] = 0; + } + got_one = 0; + for (c2 = corners; c2; c2 = c2->next) { + int lt; + rnd_coord_t thick; + + if (DELETED(c2)) + continue; + thick = djmax(pin->BoundingBox.X2 - pin->BoundingBox.X1, pin->BoundingBox.Y2 - pin->BoundingBox.Y1); + lt = corner_radius(c2); + if (c2->n_lines && c2 != c && !(c2->pin || c2->pad || c2->via) + && intersecting_layers(c->layer, c2->layer) + && c2->x >= left - lt && c2->x <= right + lt && c2->y >= bottom - lt && c2->y <= top + lt) { + int d = dist(c->x, c->y, c2->x, c2->y); + if (pin && d > thick / 2 + lt) + continue; + if (c2->n_lines == 1) { + got_one++; + dprintf("found orphan %s vs %s\n", corner_name(c2), corner_name(c)); + connect_corners(c, c2); + again = 1; + continue; + } + if (best_c[c2->layer] == 0 || c2->n_lines < best_c[c2->layer]->n_lines || (d < best_dist[c2->layer] + && c2->n_lines <= + best_c[c2->layer]->n_lines)) { + best_dist[c2->layer] = d; + best_c[c2->layer] = c2; + dprintf("layer %d best now %s\n", c2->layer, corner_name(c2)); + } + } + if (!got_one && c->n_lines == (c->pad ? 1 : 0)) { + for (l = 0; l <= pcb_max_layer(PCB); l++) + if (best_c[l]) + dprintf("best[%d] = %s\n", l, corner_name(best_c[l])); + for (l = 0; l <= pcb_max_layer(PCB); l++) + if (best_c[l]) { + dprintf("move %s to %s\n", corner_name(best_c[l]), corner_name(c)); + connect_corners(best_c[l], c); + again = 1; + continue; + } + } + } + } + } + + /* Now look for line ends that don't connect, see if they need to be + extended to intersect another line. */ + for (c = corners; c; c = c->next) { + line_s *l, *t; + int lo; + + if (DELETED(c)) + continue; + if (c->pin || c->via || c->pad) + continue; + if (c->n_lines != 1) + continue; + + l = c->lines[0]; + lo = line_orient(l, c); + dprintf("line end %#mD orient %d\n", c->x, c->y, lo); + + for (t = lines; t; t = t->next) { + if (DELETED(t)) + continue; + if (t->layer != c->lines[0]->layer) + continue; + switch (lo) { /* remember, orient is for the line relative to the corner */ + case LEFT: + if (t->s->x == t->e->x + && c->x < t->s->x + && t->s->x < c->x + (l->line->Thickness + t->line->Thickness) / 2 && ((t->s->y < c->y && c->y < t->e->y) + || (t->e->y < c->y && c->y < t->s->y))) { + dprintf("found %#mD - %#mD\n", t->s->x, t->s->y, t->e->x, t->e->y); + move_corner(c, t->s->x, c->y); + } + break; + case RIGHT: + if (t->s->x == t->e->x + && c->x > t->s->x + && t->s->x > c->x - (l->line->Thickness + t->line->Thickness) / 2 && ((t->s->y < c->y && c->y < t->e->y) + || (t->e->y < c->y && c->y < t->s->y))) { + dprintf("found %#mD - %#mD\n", t->s->x, t->s->y, t->e->x, t->e->y); + move_corner(c, t->s->x, c->y); + } + break; + case UP: + if (t->s->y == t->e->y + && c->y < t->s->y + && t->s->y < c->y + (l->line->Thickness + t->line->Thickness) / 2 && ((t->s->x < c->x && c->x < t->e->x) + || (t->e->x < c->x && c->x < t->s->x))) { + dprintf("found %#mD - %#mD\n", t->s->x, t->s->y, t->e->x, t->e->y); + move_corner(c, c->x, t->s->y); + } + break; + case DOWN: + if (t->s->y == t->e->y + && c->y > t->s->y + && t->s->y > c->y - (l->line->Thickness + t->line->Thickness) / 2 && ((t->s->x < c->x && c->x < t->e->x) + || (t->e->x < c->x && c->x < t->s->x))) { + dprintf("found %#mD - %#mD\n", t->s->x, t->s->y, t->e->x, t->e->y); + move_corner(c, c->x, t->s->y); + } + break; + } + } + } +} + +static int pstk_orient(pcb_pstk_t *p) +{ + rnd_coord_t dx = p->BoundingBox.X2 - p->BoundingBox.X1; + rnd_coord_t dy = p->BoundingBox.Y2 - p->BoundingBox.Y1; + if (dx < dy * 3) + return O_VERT; + if (dx > dy * 3) + return O_HORIZ; + return DIAGONAL; +} + +static void padcleaner_(pcb_data_t *data) +{ + line_s *l, *nextl; + rect_s r; + + dprintf("\ndj: padcleaner\n"); + for (l = lines; l; l = nextl) { + nextl = l->next; + + if (l->is_pad) + continue; + + if (DELETED(l)) + continue; + + dprintf("dj: line %p\n", (void *) l); + check(0, l); + + if (l->s->pad && l->s->pad == l->e->pad) + continue; + + PCB_PADSTACK_LOOP(data); + { + pcb_pstk_shape_t *shape = NULL; + + /* check if the padstack has copper on the given side */ + switch(layer_type[l->layer]) { + case LT_SOLDER: shape = pcb_pstk_shape(padstack, PCB_LYT_BOTTOM | PCB_LYT_COPPER, 0); break; + case LT_COMPONENT: shape = pcb_pstk_shape(padstack, PCB_LYT_TOP | PCB_LYT_COPPER, 0); break; + } + if (shape == NULL) + continue; + + empty_rect(&r); + add_point_to_rect(&r, padstack->BoundingBox.X1, padstack->BoundingBox.Y1, 0); + add_point_to_rect(&r, padstack->BoundingBox.X2, padstack->BoundingBox.Y2, 0); + if (pin_in_rect(&r, l->s->x, l->s->y, 0) + && pin_in_rect(&r, l->e->x, l->e->y, 0) + && ORIENT(line_orient(l, 0)) == pstk_orient(padstack)) { + dprintf + ("padcleaner %#mD-%#mD vs line %#mD-%#mD %#mS\n", + padstack->BoundingBox.X1, padstack->BoundingBox.Y1, padstack->BoundingBox.X2, padstack->BoundingBox.Y2, + l->s->x, l->s->y, l->e->x, l->e->y, l->line->Thickness); + remove_line(l); + goto next_line; + } + } + PCB_END_LOOP; + next_line:; + } +} + +static void padcleaner(void) +{ + padcleaner_(PCB->Data); + PCB_SUBC_LOOP(PCB->Data); { + padcleaner_(subc->data); + } PCB_END_LOOP; +} + + +static void grok_layer_groups() +{ + int i, j, f; + pcb_layer_stack_t *l = &(PCB->LayerGroups); + + solder_layer = component_layer = -1; + for (i = 0; i < pcb_max_layer(PCB); i++) { + layer_type[i] = 0; + layer_groupings[i] = 0; + } + for (i = 0; i < pcb_max_group(PCB); i++) { + f = 0; + for (j = 0; j < l->grp[i].len; j++) { + unsigned int lflg = pcb_layer_flags(PCB, l->grp[i].lid[j]); + if (lflg & PCB_LYT_BOTTOM) + f |= LT_SOLDER; + if (lflg & PCB_LYT_TOP) + f |= LT_COMPONENT; + } + for (j = 0; j < l->grp[i].len; j++) { + if (l->grp[i].lid[j] < pcb_max_layer(PCB)) { + layer_type[l->grp[i].lid[j]] |= f; + layer_groupings[l->grp[i].lid[j]] = i; + if (solder_layer == -1 && f == LT_SOLDER) + solder_layer = l->grp[i].lid[j]; + if (component_layer == -1 && f == LT_COMPONENT) + component_layer = l->grp[i].lid[j]; + } + } + } +} + +static const char pcb_acts_DJopt[] = "djopt(debumpify|unjaggy|simple|vianudge|viatrim|orthopull)\n" "djopt(auto) - all of the above\n" "djopt(miter)"; +static const char pcb_acth_DJopt[] = "Perform various optimizations on the current board."; +/* DOC: djopt.html */ +static fgw_error_t pcb_act_DJopt(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *arg = NULL; + int layn, saved = 0; + corner_s *c; + + RND_ACT_MAY_CONVARG(1, FGW_STR, DJopt, arg = argv[1].val.str); + +#ifdef ENDIF + SwitchDrawingWindow(PCB->Zoom, Output.drawing_area->window, conf_core.editor.show_solder_side, rnd_false); +#endif + + rnd_hid_busy(PCB, 1); + + lines = 0; + corners = 0; + + grok_layer_groups(); + + PCB_SUBC_LOOP(PCB->Data); + PCB_PADSTACK_LOOP(subc->data); + { + pcb_pstk_proto_t *proto; + proto = pcb_pstk_get_proto(padstack); + if (proto == NULL) + continue; + + c = find_corner(padstack->x, padstack->y, -1); + if (!PCB_PSTK_PROTO_CUTS(proto)) + c->pad = padstack; + else + c->pin = padstack; + } + PCB_END_LOOP; + PCB_END_LOOP; + + PCB_PADSTACK_LOOP(PCB->Data); + /* hace don't mess with vias that have thermals */ + /* but then again don't bump into them if (!PCB_FLAG_TEST(ALLTHERMFLAGS, via)) */ + { + c = find_corner(padstack->x, padstack->y, -1); + c->via = padstack; + } + PCB_END_LOOP; + + check(0, 0); + + if (RND_NSTRCMP(arg, "splitlines") == 0) { + if (canonicalize_lines()) + pcb_undo_inc_serial(); + rnd_hid_busy(PCB, 0); + return 0; + } + + for (layn = 0; layn < pcb_max_layer(PCB); layn++) { + pcb_layer_t *layer = pcb_get_layer(PCB->Data, layn); + + if (!(pcb_layer_flags(PCB, layn) & PCB_LYT_COPPER)) + continue; + + PCB_LINE_LOOP(layer); + { + line_s *ls; + + if (conf_djopt.plugins.djopt.auto_only && !autorouted(line)) + continue; + + if (line->Point1.X == line->Point2.X && line->Point1.Y == line->Point2.Y) { + pcb_line_destroy(layer, line); + continue; + } + + ls = (line_s *) malloc(sizeof(line_s)); + ls->next = lines; + lines = ls; + ls->is_pad = 0; + ls->s = find_corner(line->Point1.X, line->Point1.Y, layn); + ls->e = find_corner(line->Point2.X, line->Point2.Y, layn); + ls->line = line; + add_line_to_corner(ls, ls->s); + add_line_to_corner(ls, ls->e); + ls->layer = layn; + } + PCB_END_LOOP; + } + + check(0, 0); + pinsnap(); + canonicalize_lines(); + check(0, 0); + classify_nets(); + /*dump_all(); */ + check(0, 0); + + if (RND_NSTRCMP(arg, "debumpify") == 0) + saved += debumpify(); + else if (RND_NSTRCMP(arg, "unjaggy") == 0) + saved += unjaggy(); + else if (RND_NSTRCMP(arg, "simple") == 0) + saved += simple_optimizations(); + else if (RND_NSTRCMP(arg, "vianudge") == 0) + saved += vianudge(); + else if (RND_NSTRCMP(arg, "viatrim") == 0) + saved += viatrim(); + else if (RND_NSTRCMP(arg, "orthopull") == 0) + saved += orthopull(); + else if (RND_NSTRCMP(arg, "auto") == 0) + saved += automagic(); + else if (RND_NSTRCMP(arg, "miter") == 0) + saved += miter(); + else { + printf("unknown command: %s\n", arg); + rnd_hid_busy(PCB, 0); + return 1; + } + + padcleaner(); + + check(0, 0); + if (saved) + pcb_undo_inc_serial(); + + rnd_hid_busy(PCB, 0); + RND_ACT_IRES(0); + return 0; +} + +rnd_action_t djopt_action_list[] = { + {"djopt", pcb_act_DJopt, pcb_acth_DJopt, pcb_acts_DJopt} +}; + +int pplg_check_ver_djopt(int ver_needed) { return 0; } + +void pplg_uninit_djopt(void) +{ + rnd_remove_actions_by_cookie(djopt_cookie); + rnd_conf_unreg_fields("plugins/djopt/"); +} + +int pplg_init_djopt(void) +{ + RND_API_CHK_VER; + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_djopt, field,isarray,type_name,cpath,cname,desc,flags); +#include "djopt_conf_fields.h" + + RND_REGISTER_ACTIONS(djopt_action_list, djopt_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/djopt/djopt.h =================================================================== --- tags/2.3.0/src_plugins/djopt/djopt.h (nonexistent) +++ tags/2.3.0/src_plugins/djopt/djopt.h (revision 33253) @@ -0,0 +1,41 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2003 DJ Delorie + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA + * dj@delorie.com + * + */ + +#ifndef PCB_DJOPT_H +#define PCB_DJOPT_H + +#include "config.h" + +fgw_error_t pcb_act_DJopt(int, char **, rnd_coord_t, rnd_coord_t); +int djopt_set_auto_only(int, char **, rnd_coord_t, rnd_coord_t); +#endif Index: tags/2.3.0/src_plugins/djopt/djopt.pup =================================================================== --- tags/2.3.0/src_plugins/djopt/djopt.pup (nonexistent) +++ tags/2.3.0/src_plugins/djopt/djopt.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short djopt board optimization +$long Various board optimization algorithms. +$package extra +$state works +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/djopt/djopt_conf.h =================================================================== --- tags/2.3.0/src_plugins/djopt/djopt_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/djopt/djopt_conf.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_DJOPT_CONF_H +#define PCB_DJOPT_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN auto_only; /* Operate on autorouted tracks only */ + } djopt; + } plugins; +} conf_djopt_t; + +#endif Index: tags/2.3.0/src_plugins/draw_csect/Makefile =================================================================== --- tags/2.3.0/src_plugins/draw_csect/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/draw_csect/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_draw_csect + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/draw_csect/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/draw_csect/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/draw_csect/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {draw_csect} +append /local/pcb/mod/OBJS [@ + $(PLUGDIR)/draw_csect/draw_csect.o +@] + +switch /local/pcb/draw_csect/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/draw_csect/draw_csect.c =================================================================== --- tags/2.3.0/src_plugins/draw_csect/draw_csect.c (nonexistent) +++ tags/2.3.0/src_plugins/draw_csect/draw_csect.c (revision 33253) @@ -0,0 +1,977 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* draw cross section */ +#include "config.h" + + +#include "board.h" +#include "data.h" +#include "draw.h" +#include +#include "stub_draw.h" +#include +#include +#include +#include "event.h" +#include "undo.h" +#include "layer_vis.h" +#include "conf_core.h" + +#include "obj_text_draw.h" +#include "obj_line_draw.h" + +extern rnd_layergrp_id_t pcb_actd_EditGroup_gid; + +static const char *COLOR_COPPER_ = "#C05020"; +static const char *COLOR_SUBSTRATE_ = "#E0D090"; +static const char *COLOR_SILK_ = "#000000"; +static const char *COLOR_MASK_ = "#30d030"; +static const char *COLOR_PASTE_ = "#60e0e0"; +static const char *COLOR_MISC_ = "#e0e000"; +static const char *COLOR_OUTLINE_ = "#000000"; + +#define COLOR_ANNOT rnd_conf.appearance.color.grid +#define COLOR_BG rnd_conf.appearance.color.background + +static rnd_color_t + COLOR_COPPER, COLOR_SUBSTRATE, COLOR_SILK, COLOR_MASK, + COLOR_PASTE, COLOR_MISC, COLOR_OUTLINE; + +static rnd_layer_id_t drag_lid = -1; +static rnd_layergrp_id_t drag_gid = -1, drag_gid_subst = -1; + +#define GROUP_WIDTH_MM 75 + +static rnd_xform_t def_xform; +static pcb_draw_info_t def_info; + +/* Draw a text at x;y sized scale percentage */ +static pcb_text_t *dtext(int x, int y, int scale, int dir, const char *txt) +{ + static pcb_text_t t; + + memset(&t, 0, sizeof(t)); + + t.X = RND_MM_TO_COORD(x); + t.Y = RND_MM_TO_COORD(y); + t.TextString = (char *)txt; + t.rot = 90.0*dir; + t.Scale = scale; + t.fid = 0; /* use the default font */ + t.Flags = pcb_no_flags(); + pcb_text_draw_(&def_info, &t, 0, 0, PCB_TXT_TINY_ACCURATE); + return &t; +} + +/* Draw a text at x;y sized scale percentage */ +static pcb_text_t *dtext_(rnd_coord_t x, rnd_coord_t y, int scale, int dir, const char *txt, rnd_coord_t th) +{ + static pcb_text_t t; + + memset(&t, 0, sizeof(t)); + + t.X = x; + t.Y = y; + t.TextString = (char *)txt; + t.rot = 90.0*dir; + t.Scale = scale; + t.fid = 0; /* use the default font */ + t.Flags = pcb_no_flags(); + pcb_text_draw_(&def_info, &t, th, 0, PCB_TXT_TINY_ACCURATE); + return &t; +} + +/* Draw a text at x;y with a background */ +static pcb_text_t *dtext_bg(rnd_hid_gc_t gc, int x, int y, int scale, int dir, const char *txt, const rnd_color_t *bgcolor, const rnd_color_t *fgcolor) +{ + static pcb_text_t t; + + memset(&t, 0, sizeof(t)); + + t.X = RND_MM_TO_COORD(x); + t.Y = RND_MM_TO_COORD(y); + t.TextString = (char *)txt; + t.rot = 90.0 * dir; + t.Scale = scale; + t.fid = 0; /* use the default font */ + t.Flags = pcb_no_flags(); + + if (rnd_gui->gui) { /* it is unreadable on black&white and on most exporters */ + rnd_render->set_color(gc, bgcolor); + pcb_text_draw_(&def_info, &t, 1000000, 0, PCB_TXT_TINY_ACCURATE); + } + + rnd_render->set_color(gc, fgcolor); + pcb_text_draw_(&def_info, &t, 0, 0, PCB_TXT_TINY_ACCURATE); + + return &t; +} + +/* draw a line of a specific thickness */ +static void dline(int x1, int y1, int x2, int y2, float thick) +{ + pcb_line_t l; + memset(&l, 0, sizeof(l)); + l.Point1.X = RND_MM_TO_COORD(x1); + l.Point1.Y = RND_MM_TO_COORD(y1); + l.Point2.X = RND_MM_TO_COORD(x2); + l.Point2.Y = RND_MM_TO_COORD(y2); + l.Thickness = RND_MM_TO_COORD(thick); + if (l.Thickness == 0) + l.Thickness = 1; + pcb_line_draw_(&def_info, &l, 0); +} + +/* draw a line of a specific thickness */ +static void dline_(rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, float thick) +{ + pcb_line_t l; + memset(&l, 0, sizeof(l)); + l.Point1.X = x1; + l.Point1.Y = y1; + l.Point2.X = x2; + l.Point2.Y = y2; + l.Thickness = RND_MM_TO_COORD(thick); + if (l.Thickness == 0) + l.Thickness = 1; + pcb_line_draw_(&def_info, &l, 0); +} + + +/* draw a line clipped with two imaginary vertical lines at cx1 and cx2 */ +static void dline_vclip(int x1, int y1, int x2, int y2, float thick, int cx1, int cx2) +{ + if (cx2 < cx1) { /* make sure cx2 > cx1 */ + int tmp; + tmp = cx1; + cx1 = cx2; + cx2 = tmp; + } + + if (x2 == x1) { /* do not clip vertical lines */ + if ((x1 >= cx1) && (x1 <= cx2)) + dline(x1, y1, x2, y2, thick); + return; + } + + if (x2 < x1) { /* make sure x2 > x1 */ + int tmp; + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + } + + /* clip */ + if (x2 > cx2) { + y2 = (double)(cx2 - x1) / (double)(x2 - x1) * (double)(y2 - y1) + y1; + x2 = cx2; + } + if (x1 < cx1) { + y1 = (double)(cx1 - x1) / (double)(x2 - x1) * (double)(y2 - y1) + y1; + x1 = cx1; + } + + dline(x1, y1, x2, y2, thick); +} + + +/* Draw a 45-deg hactched box wihtout the rectangle; + if step > 0 use \ hatching, else use / */ +static void hatch_box(int x1, int y1, int x2, int y2, float thick, int step) +{ + int n, h = y2 - y1; + + if (step > 0) + for(n = x1 - h; n <= x2; n += step) + dline_vclip(n, y1, n+h, y2, thick, x1, x2); + else + for(n = x2; n >= x1-h; n += step) + dline_vclip(n+h, y1, n, y2, thick, x1, x2); +} + +enum { + OMIT_NONE = 0, + OMIT_TOP = 1, + OMIT_BOTTOM = 2, + OMIT_LEFT = 4, + OMIT_RIGHT = 8, + OMIT_ALL = 1|2|4|8 +}; + +/* draw a hatched rectangle; to turn off hatching in a directon set the + corresponding step to 0 */ +static void dhrect(int x1, int y1, int x2, int y2, float thick_rect, float thick_hatch, int step_fwd, int step_back, unsigned omit) +{ + if (!(omit & OMIT_TOP)) + dline(x1, y1, x2, y1, thick_rect); + if (!(omit & OMIT_RIGHT)) + dline(x2, y1, x2, y2, thick_rect); + if (!(omit & OMIT_BOTTOM)) + dline(x1, y2, x2, y2, thick_rect); + if (!(omit & OMIT_LEFT)) + dline(x1, y1, x1, y2, thick_rect); + + if (step_fwd > 0) + hatch_box(x1, y1, x2, y2, thick_hatch, +step_fwd); + + if (step_back > 0) + hatch_box(x1, y1, x2, y2, thick_hatch, -step_back); +} + +static rnd_box_t btn_addgrp, btn_delgrp, btn_addlayer, btn_dellayer, btn_addoutline; +static rnd_box_t layer_crd[PCB_MAX_LAYER]; +static rnd_box_t group_crd[PCB_MAX_LAYERGRP]; +static rnd_box_t outline_crd; +static char layer_valid[PCB_MAX_LAYER]; +static char group_valid[PCB_MAX_LAYERGRP]; +static char outline_valid; + +static void reg_layer_coords(rnd_layer_id_t lid, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + if ((lid < 0) || (lid >= PCB_MAX_LAYER)) + return; + layer_crd[lid].X1 = x1; + layer_crd[lid].Y1 = y1; + layer_crd[lid].X2 = x2; + layer_crd[lid].Y2 = y2; + layer_valid[lid] = 1; +} + +static void reg_group_coords(rnd_layergrp_id_t gid, rnd_coord_t y1, rnd_coord_t y2) +{ + if ((gid < 0) || (gid >= PCB_MAX_LAYER)) + return; + group_crd[gid].Y1 = y1; + group_crd[gid].Y2 = y2; + group_valid[gid] = 1; +} + +static void reg_outline_coords(rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + outline_crd.X1 = x1; + outline_crd.Y1 = y1; + outline_crd.X2 = x2; + outline_crd.Y2 = y2; + outline_valid = 1; +} + +static void reset_layer_coords(void) +{ + memset(layer_valid, 0, sizeof(layer_valid)); + memset(group_valid, 0, sizeof(group_valid)); + outline_valid = 0; +} + +static rnd_layer_id_t get_layer_coords(rnd_coord_t x, rnd_coord_t y) +{ + rnd_layer_id_t n; + + for(n = 0; n < PCB_MAX_LAYER; n++) { + if (!layer_valid[n]) continue; + if ((layer_crd[n].X1 <= x) && (layer_crd[n].Y1 <= y) && + (layer_crd[n].X2 >= x) && (layer_crd[n].Y2 >= y)) + return n; + } + return -1; +} + +static rnd_layergrp_id_t get_group_coords(rnd_coord_t y, rnd_coord_t *y1, rnd_coord_t *y2) +{ + rnd_layergrp_id_t n; + + for(n = 0; n < PCB_MAX_LAYERGRP; n++) { + if (!group_valid[n]) continue; + if ((group_crd[n].Y1 <= y) && (group_crd[n].Y2 >= y)) { + *y1 = group_crd[n].Y1; + *y2 = group_crd[n].Y2; + return n; + } + } + return -1; +} + +static rnd_coord_t create_button(rnd_hid_gc_t gc, int x, int y, const char *label, rnd_box_t *box) +{ + pcb_text_t *t; + t = dtext_bg(gc, x, y, 200, 0, label, &COLOR_BG, &COLOR_ANNOT); + pcb_text_bbox(pcb_font(PCB, 0, 1), t); + dhrect(RND_COORD_TO_MM(t->BoundingBox.X1), y, RND_COORD_TO_MM(t->BoundingBox.X2)+1, y+4, 0.25, 0, 0, 0, OMIT_NONE); + box->X1 = t->BoundingBox.X1; + box->Y1 = RND_MM_TO_COORD(y); + box->X2 = t->BoundingBox.X2+RND_MM_TO_COORD(1); + box->Y2 = RND_MM_TO_COORD(y+4); + return RND_COORD_TO_MM(box->X2); +} + +static int is_button(int x, int y, const rnd_box_t *box) +{ + return (x >= box->X1) && (x <= box->X2) && (y >= box->Y1) && (y <= box->Y2); +} + +static rnd_hid_gc_t csect_gc; + +static rnd_coord_t ox, oy, cx, cy; +static int drag_addgrp, drag_delgrp, drag_addlayer, drag_dellayer, drag_addoutline; +static rnd_layergrp_id_t gactive = -1; +static rnd_layergrp_id_t outline_gactive = -1; +static rnd_layer_id_t lactive = -1; +int lactive_idx = -1; + +/* true if we are dragging somehting */ +#define DRAGGING ((drag_lid >= 0) || (drag_addgrp | drag_delgrp | drag_addlayer | drag_dellayer) || (drag_gid >= 0)) + +typedef enum { + MARK_GRP_FRAME, + MARK_GRP_MIDDLE, + MARK_GRP_TOP +} mark_grp_loc_t; + +static void mark_grp(rnd_coord_t y, unsigned int accept_mask, mark_grp_loc_t loc) +{ + rnd_coord_t y1, y2, x0 = -RND_MM_TO_COORD(5); + rnd_layergrp_id_t g; + + g = get_group_coords(y, &y1, &y2); + + if ((g >= 0) && ((pcb_layergrp_flags(PCB, g) & accept_mask) & accept_mask)) { + gactive = g; + switch(loc) { + case MARK_GRP_FRAME: + dline_(x0, y1, RND_MM_TO_COORD(200), y1, 0.1); + dline_(x0, y2, RND_MM_TO_COORD(200), y2, 0.1); + break; + case MARK_GRP_MIDDLE: + dline_(x0, (y1+y2)/2, RND_MM_TO_COORD(200), (y1+y2)/2, 0.1); + break; + case MARK_GRP_TOP: + dline_(x0, y1, RND_MM_TO_COORD(200), y1, 0.1); + break; + } + } + else + gactive = -1; +} + +static void mark_outline_grp(rnd_coord_t x, rnd_coord_t y, rnd_layergrp_id_t gid) +{ + if (outline_valid && + (outline_crd.X1 <= x) && (outline_crd.Y1 <= y) && + (outline_crd.X2 >= x) && (outline_crd.Y2 >= y)) { + outline_gactive = gid; + } + else + outline_gactive = -1; +} + +static void mark_layer(rnd_coord_t x, rnd_coord_t y) +{ + lactive = get_layer_coords(x, y); + if (lactive >= 0) { + dhrect( + RND_COORD_TO_MM(layer_crd[lactive].X1)-1, RND_COORD_TO_MM(layer_crd[lactive].Y1)-1, + RND_COORD_TO_MM(layer_crd[lactive].X2)+1, RND_COORD_TO_MM(layer_crd[lactive].Y2)+1, + 0.1, 0.1, 3, 3, 0 + ); + } +} + +static void mark_layer_order(rnd_coord_t x) +{ + pcb_layergrp_t *g; + rnd_coord_t tx, ty1, ty2; + lactive_idx = -1; + + if ((gactive < 0) || (PCB->LayerGroups.grp[gactive].len < 1)) + return; + + g = &PCB->LayerGroups.grp[gactive]; + + tx = layer_crd[g->lid[0]].X1 - RND_MM_TO_COORD(1.5); + ty1 = layer_crd[g->lid[0]].Y1; + ty2 = layer_crd[g->lid[0]].Y2; + + for(lactive_idx = g->len-1; lactive_idx >= 0; lactive_idx--) { + rnd_layer_id_t lid = g->lid[lactive_idx]; + if (x > (layer_crd[lid].X1 + layer_crd[lid].X2)/2) { + tx = layer_crd[lid].X2; + break; + } + } + dline_(tx, ty1-RND_MM_TO_COORD(1.5), tx-RND_MM_TO_COORD(0.75), ty2+RND_MM_TO_COORD(1.5), 0.1); + dline_(tx, ty1-RND_MM_TO_COORD(1.5), tx+RND_MM_TO_COORD(0.75), ty2+RND_MM_TO_COORD(1.5), 0.1); + lactive_idx++; +} + +static void draw_hover_label(rnd_hid_gc_t gc, const char *str) +{ + int x0 = RND_MM_TO_COORD(2.5); /* compensate for the mouse cursor (sort of random) */ + rnd_render->set_color(gc, &COLOR_ANNOT); + dtext_(cx+x0, cy, 250, 0, str, RND_MM_TO_COORD(0.01)); +} + +/* Draw the cross-section layer */ +static void draw_csect(rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + rnd_layergrp_id_t gid, outline_gid = -1; + int ystart = 10, x, y, last_copper_step = 5; + const char *thick; + + reset_layer_coords(); + csect_gc = gc; + + rnd_render->set_color(gc, &COLOR_ANNOT); + dtext(0, 0, 500, 0, "Board cross section"); + + /* draw physical layers */ + y = ystart; + for(gid = 0; gid < pcb_max_group(PCB); gid++) { + int i, stepf = 0, stepb = 0, th; + pcb_layergrp_t *g = PCB->LayerGroups.grp + gid; + const rnd_color_t *color; + + if ((!g->valid) || (gid == drag_gid) || (gid == drag_gid_subst)) + continue; + else if (g->ltype & PCB_LYT_COPPER) { + last_copper_step = -last_copper_step; + if (last_copper_step > 0) + stepf = last_copper_step; + else + stepb = -last_copper_step; + th = 5; + color = &COLOR_COPPER; + } + else if (g->ltype & PCB_LYT_SUBSTRATE) { + stepf = stepb = 7; + th = 10; + color = &COLOR_SUBSTRATE; + } + else if (g->ltype & PCB_LYT_SILK) { + th = 5; + color = &COLOR_SILK; + stepb = 3; + } + else if (g->ltype & PCB_LYT_MASK) { + th = 5; + color = &COLOR_MASK; + stepb = 9; + } + else if (g->ltype & PCB_LYT_PASTE) { + th = 5; + color = &COLOR_PASTE; + stepf = 9; + } + else if (g->ltype & PCB_LYT_MISC) { + th = 5; + color = &COLOR_MISC; + stepf = 3; + } + else if (g->ltype & PCB_LYT_BOUNDARY) { +TODO("layer: handle multiple outline layers") + outline_gid = gid; + continue; + } + else + continue; + + rnd_render->set_color(gc, color); + dhrect(0, y, GROUP_WIDTH_MM, y+th, 1, 0.5, stepf, stepb, OMIT_LEFT | OMIT_RIGHT); + dtext_bg(gc, 5, y, 200, 0, g->name, &COLOR_BG, &COLOR_ANNOT); + thick = pcb_attribute_get(&g->Attributes, "thickness"); + if (thick != NULL) + dtext_bg(gc, 45, y, 200, 0, thick, &COLOR_BG, &COLOR_ANNOT); + reg_group_coords(gid, RND_MM_TO_COORD(y), RND_MM_TO_COORD(y+th)); + + + /* draw layer names */ + { + x = GROUP_WIDTH_MM + 3; + for(i = 0; i < g->len; i++) { + pcb_text_t *t; + rnd_layer_id_t lid = g->lid[i]; + pcb_layer_t *l = &PCB->Data->Layer[lid]; + int redraw_text = 0; + + if (lid == drag_lid) + continue; + t = dtext_bg(gc, x, y, 200, 0, l->name, &COLOR_BG, &l->meta.real.color); + pcb_text_bbox(pcb_font(PCB, 0, 1), t); + if (l->comb & PCB_LYC_SUB) { + dhrect(RND_COORD_TO_MM(t->BoundingBox.X1), y, RND_COORD_TO_MM(t->BoundingBox.X2)+1, y+4, 1.2, 0, 0, 0, OMIT_NONE); + redraw_text = 1; + } + + if (redraw_text) { + t = dtext_bg(gc, x, y, 200, 0, l->name, &COLOR_BG, &l->meta.real.color); + pcb_text_bbox(pcb_font(PCB, 0, 1), t); + } + else + dhrect(RND_COORD_TO_MM(t->BoundingBox.X1), y, RND_COORD_TO_MM(t->BoundingBox.X2)+1, y+4, 0.25, 0, 0, 0, OMIT_NONE); + + if (l->comb & PCB_LYC_AUTO) + dhrect(RND_COORD_TO_MM(t->BoundingBox.X1), y, RND_COORD_TO_MM(t->BoundingBox.X2)+1, y+4, 0.0, 0, 3, 0, OMIT_ALL); + + reg_layer_coords(lid, t->BoundingBox.X1, RND_MM_TO_COORD(y), t->BoundingBox.X2+RND_MM_TO_COORD(1), RND_MM_TO_COORD(y+4)); + x += RND_COORD_TO_MM(t->BoundingBox.X2 - t->BoundingBox.X1) + 3; + } + } + + /* increment y */ + y += th + 1; + } + + /* draw global/special layers */ + y+=7; + if (outline_gid >= 0) { + pcb_layergrp_t *g = PCB->LayerGroups.grp + outline_gid; + pcb_text_t *t; + if (g->len > 0) { + pcb_layer_t *l = &PCB->Data->Layer[g->lid[0]]; + rnd_render->set_color(gc, &l->meta.real.color); + t = dtext_bg(gc, 1, y, 200, 0, l->name, &COLOR_BG, &l->meta.real.color); + pcb_text_bbox(pcb_font(PCB, 0, 1), t); + dhrect(RND_COORD_TO_MM(t->BoundingBox.X1), y, RND_COORD_TO_MM(t->BoundingBox.X2)+1, y+4, 1, 0, 0, 0, OMIT_NONE); + dtext_bg(gc, 1, y, 200, 0, l->name, &COLOR_BG, &l->meta.real.color); + reg_layer_coords(g->lid[0], t->BoundingBox.X1, RND_MM_TO_COORD(y), t->BoundingBox.X2+RND_MM_TO_COORD(1), RND_MM_TO_COORD(y+4)); + } + else { + rnd_render->set_color(gc, &COLOR_OUTLINE); + t = dtext_bg(gc, 1, y, 200, 0, "", &COLOR_BG, &COLOR_OUTLINE); + pcb_text_bbox(pcb_font(PCB, 0, 1), t); + dhrect(RND_COORD_TO_MM(t->BoundingBox.X1), y, RND_COORD_TO_MM(t->BoundingBox.X2)+1, y+4, 1, 0, 0, 0, OMIT_NONE); + dtext_bg(gc, 1, y, 200, 0, "", &COLOR_BG, &COLOR_OUTLINE); + } + dline(0, ystart, 0, y+4, 1); + reg_outline_coords(t->BoundingBox.X1, RND_MM_TO_COORD(y), t->BoundingBox.X2, RND_MM_TO_COORD(y+4)); + } + else { + create_button(gc, 2, y, "Create outline", &btn_addoutline); + } + + x=30; + x = 2 + create_button(gc, x, y, "Add copper group", &btn_addgrp); + x = 2 + create_button(gc, x, y, "Del copper group", &btn_delgrp); + + x += 2; + x = 2 + create_button(gc, x, y, "Add logical layer", &btn_addlayer); + x = 2 + create_button(gc, x, y, "Del logical layer", &btn_dellayer); + + + if (DRAGGING) { + rnd_render->set_color(gc, rnd_color_black); + + /* draw the actual operation */ + if (drag_addgrp) { + mark_grp(cy, PCB_LYT_SUBSTRATE, MARK_GRP_MIDDLE); + draw_hover_label(gc, "INSERT GRP"); + } + if (drag_delgrp) { + mark_grp(cy, PCB_LYT_COPPER | PCB_LYT_INTERN, MARK_GRP_FRAME); + draw_hover_label(gc, "DEL GROUP"); + } + if (drag_addlayer) { + mark_grp(cy, PCB_LYT_COPPER | PCB_LYT_MASK | PCB_LYT_PASTE | PCB_LYT_SILK, MARK_GRP_FRAME); + mark_outline_grp(cx, cy, outline_gid); + draw_hover_label(gc, "ADD LAYER"); + } + if (drag_dellayer) { + mark_layer(cx, cy); + draw_hover_label(gc, "DEL LAYER"); + } + else if (drag_lid >= 0) { + pcb_layer_t *l = &PCB->Data->Layer[drag_lid]; + draw_hover_label(gc, l->name); + mark_grp(cy, PCB_LYT_COPPER | PCB_LYT_MASK | PCB_LYT_PASTE | PCB_LYT_SILK, MARK_GRP_FRAME); + mark_outline_grp(cx, cy, outline_gid); + mark_layer_order(cx); + } + else if (drag_gid >= 0) { + pcb_layergrp_t *g = &PCB->LayerGroups.grp[drag_gid]; + const char *name = g->name == NULL ? "" : g->name; + draw_hover_label(gc, name); + mark_grp(cy, PCB_LYT_COPPER | PCB_LYT_INTERN, MARK_GRP_TOP); + if (gactive < 0) + mark_grp(cy, PCB_LYT_COPPER | PCB_LYT_BOTTOM, MARK_GRP_TOP); + if (gactive < 0) + mark_grp(cy, PCB_LYT_SUBSTRATE, MARK_GRP_TOP); + } + } +} + +/* Returns 0 if gactive can be removed from its current group */ +static int check_layer_del(rnd_layer_id_t lid) +{ + pcb_layergrp_t *grp; + unsigned int tflg; + + tflg = pcb_layer_flags(PCB, lid); + grp = pcb_get_layergrp(PCB, pcb_layer_get_group(PCB, lid)); + + if (grp == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid source group.\n"); + return -1; + } + + if ((tflg & PCB_LYT_SILK) && (grp->len == 1)) { + rnd_message(RND_MSG_ERROR, "Can not remove the last layer of this group because this group must have at least one layer.\n"); + return -1; + } + + return 0; +} + +static void do_move_grp() +{ + unsigned int tflg; + + if ((gactive < 0) || (gactive == drag_gid+1)) + return; + + tflg = pcb_layergrp_flags(PCB, gactive); + + pcb_layergrp_move(PCB, drag_gid, gactive); + + if (drag_gid_subst >= 0) { + if ((drag_gid < drag_gid_subst) && (gactive > drag_gid)) + drag_gid_subst--; /* the move shifted this down one slot */ + + if (gactive < drag_gid_subst) + drag_gid_subst++; /* the move shifted this up one slot */ + + if (tflg & PCB_LYT_COPPER) { + if (tflg & PCB_LYT_BOTTOM) + pcb_layergrp_move(PCB, drag_gid_subst, gactive); + else + pcb_layergrp_move(PCB, drag_gid_subst, gactive+1); + } + else if (tflg & PCB_LYT_SUBSTRATE) { + if (gactive < drag_gid) + pcb_layergrp_move(PCB, drag_gid_subst, gactive); + else + pcb_layergrp_move(PCB, drag_gid_subst, gactive-1); + } + } +} + + +static rnd_bool mouse_csect(rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + rnd_bool res = 0; + rnd_layer_id_t lid; + + switch(kind) { + case RND_HID_MOUSE_PRESS: + if (is_button(x, y, &btn_addoutline)) { + drag_addoutline = 1; + res = 1; + break; + } + + if (is_button(x, y, &btn_addgrp)) { + drag_addgrp = 1; + res = 1; + break; + } + + if (is_button(x, y, &btn_delgrp)) { + drag_delgrp = 1; + res = 1; + break; + } + + if (is_button(x, y, &btn_addlayer)) { + drag_addlayer = 1; + res = 1; + break; + } + + if (is_button(x, y, &btn_dellayer)) { + drag_dellayer = 1; + res = 1; + break; + } + + drag_lid = get_layer_coords(x, y); + if (drag_lid >= 0) { + ox = x; + oy = y; + res = 1; + break; + } + + if ((x > 0) && (x < RND_MM_TO_COORD(GROUP_WIDTH_MM))) { + rnd_coord_t tmp; + rnd_layergrp_id_t gid; + gid = get_group_coords(y, &tmp, &tmp); + if ((gid >= 0) && (pcb_layergrp_flags(PCB, gid) & PCB_LYT_COPPER) && (pcb_layergrp_flags(PCB, gid) & PCB_LYT_INTERN)) { + drag_gid = gid; + /* temporary workaround for the restricted setup */ + if (pcb_layergrp_flags(PCB, gid - 1) & PCB_LYT_SUBSTRATE) + drag_gid_subst = gid - 1; + else if ((pcb_layergrp_flags(PCB, gid - 1) & PCB_LYT_BOUNDARY) && (pcb_layergrp_flags(PCB, gid - 2) & PCB_LYT_SUBSTRATE)) + drag_gid_subst = gid - 2; + res = 1; + } + } + break; + case RND_HID_MOUSE_RELEASE: + if (drag_addoutline) { + if (is_button(x, y, &btn_addoutline)) { + pcb_layergrp_t *g = pcb_get_grp_new_misc(PCB); + + pcb_undo_freeze_serial(); + g->name = rnd_strdup("global_outline"); + g->ltype = PCB_LYT_BOUNDARY; + g->purpose = rnd_strdup("uroute"); + g->valid = 1; + g->open = 1; + pcb_layergrp_undoable_created(g); + + outline_gactive = pcb_layergrp_id(PCB, g); + pcb_layer_create(PCB, outline_gactive, "outline", 1); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + } + drag_addoutline = 0; + gactive = -1; + res = 1; + } + else if (drag_addgrp) { + if (gactive >= 0) { + pcb_layergrp_t *g; + pcb_undo_freeze_serial(); + g = pcb_layergrp_insert_after(PCB, gactive); + g->name = NULL; + g->ltype = PCB_LYT_INTERN | PCB_LYT_SUBSTRATE; + g->valid = 1; + pcb_layergrp_undoable_created(g); + g = pcb_layergrp_insert_after(PCB, gactive); + g->name = rnd_strdup("Intern"); + g->ltype = PCB_LYT_INTERN | PCB_LYT_COPPER; + g->valid = 1; + pcb_layergrp_undoable_created(g); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + } + drag_addgrp = 0; + gactive = -1; + res = 1; + } + else if (drag_delgrp) { + if (gactive >= 0) { + pcb_layergrp_del(PCB, gactive, 1, 1); + if (pcb_layergrp_flags(PCB, gactive) & PCB_LYT_SUBSTRATE) + pcb_layergrp_del(PCB, gactive, 1, 1); + else if (pcb_layergrp_flags(PCB, gactive-1) & PCB_LYT_SUBSTRATE) + pcb_layergrp_del(PCB, gactive-1, 1, 1); + } + drag_delgrp = 0; + gactive = -1; + res = 1; + } + else if (drag_addlayer) { + if (gactive >= 0) { + pcb_layer_create(PCB, gactive, "New Layer", 1); + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + } + else if (outline_gactive >= 0 && PCB->LayerGroups.grp[outline_gactive].len == 0) { + pcb_layer_create(PCB, outline_gactive, "outline", 1); + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + } + drag_addlayer = 0; + gactive = -1; + res = 1; + } + else if (drag_dellayer) { + if (lactive >= 0) { + char tmp[32]; + sprintf(tmp, "%ld", lactive); + rnd_actionva(&PCB->hidlib, "MoveLayer", tmp, "-1", NULL); + } + drag_dellayer = 0; + lactive = -1; + res = 1; + } + else if (drag_lid >= 0) { + if (gactive >= 0) { + pcb_layer_t *l = &PCB->Data->Layer[drag_lid]; + pcb_layergrp_t *g; + if (l->meta.real.grp == gactive) { /* move within the group */ + int d, s, at; + g = &PCB->LayerGroups.grp[gactive]; + + /* move drag_lid to the end of the list within the group */ + for(s = d = 0; s < g->len; s++) { + if (g->lid[s] != drag_lid) { + g->lid[d] = g->lid[s]; + d++; + } + else + at = s; + } + g->lid[g->len-1] = drag_lid; + if (lactive_idx >= at) /* because lactive_idx was calculated with this layer in the middle */ + lactive_idx--; + goto move_layer_to_its_place; + } + else if (check_layer_del(drag_lid) == 0) { + g = &PCB->LayerGroups.grp[gactive]; + pcb_layer_move_to_group(PCB, drag_lid, gactive); + rnd_message(RND_MSG_INFO, "moved layer %s to group %d\n", l->name, gactive); + move_layer_to_its_place:; + if (lactive_idx < g->len-1) { + memmove(g->lid + lactive_idx + 1, g->lid + lactive_idx, (g->len - 1 - lactive_idx) * sizeof(rnd_layer_id_t)); + g->lid[lactive_idx] = drag_lid; + } + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + } + } + else if (outline_gactive >= 0 && PCB->LayerGroups.grp[outline_gactive].len == 0) { + pcb_layer_t *l = &PCB->Data->Layer[drag_lid]; + pcb_layer_move_to_group(PCB, drag_lid, outline_gactive); + rnd_message(RND_MSG_INFO, "moved layer %s to group %d\n", l->name, outline_gactive); + } + else + rnd_message(RND_MSG_ERROR, "Can not move layer into that layer group\n"); + res = 1; + drag_lid = -1; + gactive = -1; + } + else if (drag_gid > 0) { + do_move_grp(); + res = 1; + drag_gid = -1; + drag_gid_subst = -1; + } + break; + case RND_HID_MOUSE_MOTION: + cx = x; + cy = y; + res = DRAGGING; + break; + case RND_HID_MOUSE_POPUP: + lid = get_layer_coords(x, y); + if (lid >= 0) { + pcb_layervis_change_group_vis(&PCB->hidlib, lid, 1, 1); + rnd_actionva(&PCB->hidlib, "Popup", "layer", NULL); + } + else if ((x > 0) && (x < RND_MM_TO_COORD(GROUP_WIDTH_MM))) { + rnd_coord_t tmp; + pcb_actd_EditGroup_gid = get_group_coords(y, &tmp, &tmp); + if (pcb_actd_EditGroup_gid >= 0) + rnd_actionva(&PCB->hidlib, "Popup", "group", NULL); + } + break; + + } + return res; +} + + + + +static const char pcb_acts_dump_csect[] = "DumpCsect()"; +static const char pcb_acth_dump_csect[] = "Print the cross-section of the board (layer stack)"; + +static fgw_error_t pcb_act_dump_csect(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_layergrp_id_t gid; + + for(gid = 0; gid < pcb_max_group(PCB); gid++) { + int i; + const char *type_gfx; + pcb_layergrp_t *g = PCB->LayerGroups.grp + gid; + + if (!g->valid) { + if (g->len <= 0) + continue; + type_gfx = "old"; + } + else if (g->ltype & PCB_LYT_VIRTUAL) continue; + else if (g->ltype & PCB_LYT_COPPER) type_gfx = "===="; + else if (g->ltype & PCB_LYT_SUBSTRATE) type_gfx = "xxxx"; + else if (g->ltype & PCB_LYT_SILK) type_gfx = "silk"; + else if (g->ltype & PCB_LYT_MASK) type_gfx = "mask"; + else if (g->ltype & PCB_LYT_PASTE) type_gfx = "pst."; + else if (g->ltype & PCB_LYT_MISC) type_gfx = "misc"; + else if (g->ltype & PCB_LYT_MECH) type_gfx = "mech"; + else if (g->ltype & PCB_LYT_DOC) type_gfx = "doc."; + else if (g->ltype & PCB_LYT_BOUNDARY) type_gfx = "||||"; + else type_gfx = "????"; + + printf("%s {%ld} %s\n", type_gfx, gid, g->name); + for(i = 0; i < g->len; i++) { + rnd_layer_id_t lid = g->lid[i]; + pcb_layer_t *l = &PCB->Data->Layer[lid]; + printf(" [%ld] %s comb=", lid, l->name); + if (l->comb & PCB_LYC_SUB) printf(" sub"); + if (l->comb & PCB_LYC_AUTO) printf(" auto"); + printf("\n"); + if (l->meta.real.grp != gid) + printf(" *** broken layer-to-group cross reference: %ld\n", l->meta.real.grp); + } + } + RND_ACT_IRES(0); + return 0; +} + +static const char *draw_csect_cookie = "draw_csect"; + +rnd_action_t draw_csect_action_list[] = { + {"DumpCsect", pcb_act_dump_csect, pcb_acth_dump_csect, pcb_acts_dump_csect} +}; + +int pplg_check_ver_draw_csect(int ver_needed) { return 0; } + +void pplg_uninit_draw_csect(void) +{ + rnd_remove_actions_by_cookie(draw_csect_cookie); +} + +int pplg_init_draw_csect(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(draw_csect_action_list, draw_csect_cookie) + + def_info.xform = &def_xform; + + rnd_color_load_str(&COLOR_COPPER, COLOR_COPPER_); + rnd_color_load_str(&COLOR_SUBSTRATE, COLOR_SUBSTRATE_); + rnd_color_load_str(&COLOR_SILK, COLOR_SILK_); + rnd_color_load_str(&COLOR_MASK, COLOR_MASK_); + rnd_color_load_str(&COLOR_PASTE, COLOR_PASTE_); + rnd_color_load_str(&COLOR_MISC, COLOR_MISC_); + rnd_color_load_str(&COLOR_OUTLINE, COLOR_OUTLINE_); + + pcb_stub_draw_csect = draw_csect; + pcb_stub_draw_csect_mouse_ev = mouse_csect; + + return 0; +} Index: tags/2.3.0/src_plugins/draw_csect/draw_csect.pup =================================================================== --- tags/2.3.0/src_plugins/draw_csect/draw_csect.pup (nonexistent) +++ tags/2.3.0/src_plugins/draw_csect/draw_csect.pup (revision 33253) @@ -0,0 +1,6 @@ +$class feature +$short draw cross-section (layers) +$long Draw cross section and layer map. +$package (core) +$state works +default disable Index: tags/2.3.0/src_plugins/draw_fab/Makefile =================================================================== --- tags/2.3.0/src_plugins/draw_fab/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/draw_fab/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_draw_fab + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/draw_fab/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/draw_fab/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/draw_fab/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {draw_fab} +append /local/pcb/mod/OBJS [@ + $(PLUGDIR)/draw_fab/draw_fab.o +@] +put /local/pcb/mod/CONF {$(PLUGDIR)/draw_fab/draw_fab_conf.h} + +switch /local/pcb/draw_fab/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/draw_fab/draw_fab.c =================================================================== --- tags/2.3.0/src_plugins/draw_fab/draw_fab.c (nonexistent) +++ tags/2.3.0/src_plugins/draw_fab/draw_fab.c (revision 33253) @@ -0,0 +1,352 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2003 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* printing routines */ +#include "config.h" + +#include + +#include "board.h" +#include "build_run.h" +#include +#include "data.h" +#include "draw.h" +#include "../report/drill.h" +#include +#include "stub_draw.h" +#include "draw_fab_conf.h" +#include "conf_core.h" +#include +#include "obj_pstk_inlines.h" +#include +#include "funchash_core.h" + +#include "obj_text_draw.h" + + +conf_draw_fab_t conf_draw_fab; + +/* --------------------------------------------------------------------------- + * prints a FAB drawing. + */ + +#define TEXT_SIZE RND_MIL_TO_COORD(150) +#define TEXT_LINE RND_MIL_TO_COORD(150) +#define DRILL_MARK_SIZE RND_MIL_TO_COORD(16) +#define FAB_LINE_W RND_MIL_TO_COORD(8) + +static void fab_line(rnd_hid_gc_t gc, int x1, int y1, int x2, int y2) +{ + rnd_render->draw_line(gc, x1, y1, x2, y2); +} + +static void fab_circle(rnd_hid_gc_t gc, int x, int y, int r) +{ + rnd_render->draw_arc(gc, x, y, r, r, 0, 180); + rnd_render->draw_arc(gc, x, y, r, r, 180, 180); +} + +/* align is 0=left, 1=center, 2=right, add 8 for underline */ +static void text_at(pcb_draw_info_t *info, rnd_hid_gc_t gc, int x, int y, int align, const char *fmt, ...) +{ + char tmp[512]; + int w = 0, i; + pcb_text_t t; + va_list a; + pcb_font_t *font = pcb_font(PCB, 0, 1); + va_start(a, fmt); + vsprintf(tmp, fmt, a); + va_end(a); + memset(&t, 0, sizeof(t)); + t.TextString = tmp; + t.Scale = RND_COORD_TO_MIL(TEXT_SIZE); /* pcnt of 100mil base height */ + t.Flags = pcb_no_flags(); + t.fid = 0; /* use the default font */ + t.X = x; + t.Y = y; + for (i = 0; tmp[i]; i++) + w += (font->Symbol[(int) tmp[i]].Width + font->Symbol[(int) tmp[i]].Delta); + w = PCB_SCALE_TEXT(w, t.Scale); + t.X -= w * (align & 3) / 2; + if (t.X < 0) + t.X = 0; + pcb_text_draw_(info, &t, 0,0, PCB_TXT_TINY_ACCURATE); + if (align & 8) + fab_line(gc, t.X, + t.Y + PCB_SCALE_TEXT(font->MaxHeight, t.Scale) + RND_MIL_TO_COORD(10), + t.X + w, t.Y + PCB_SCALE_TEXT(font->MaxHeight, t.Scale) + RND_MIL_TO_COORD(10)); +} + +/* Y, +, X, circle, square */ +static void drill_sym(rnd_hid_gc_t gc, int idx, int x, int y) +{ + int type = idx % 5; + int size = idx / 5; + int s2 = (size + 1) * DRILL_MARK_SIZE; + int i; + switch (type) { + case 0: /* Y */ ; + fab_line(gc, x, y, x, y + s2); + fab_line(gc, x, y, x + s2 * 13 / 15, y - s2 / 2); + fab_line(gc, x, y, x - s2 * 13 / 15, y - s2 / 2); + for (i = 1; i <= size; i++) + fab_circle(gc, x, y, i * DRILL_MARK_SIZE); + break; + case 1: /* + */ + ; + fab_line(gc, x, y - s2, x, y + s2); + fab_line(gc, x - s2, y, x + s2, y); + for (i = 1; i <= size; i++) { + fab_line(gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE); + fab_line(gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); + fab_line(gc, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); + fab_line(gc, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); + } + break; + case 2: /* X */ ; + fab_line(gc, x - s2 * 3 / 4, y - s2 * 3 / 4, x + s2 * 3 / 4, y + s2 * 3 / 4); + fab_line(gc, x - s2 * 3 / 4, y + s2 * 3 / 4, x + s2 * 3 / 4, y - s2 * 3 / 4); + for (i = 1; i <= size; i++) { + fab_line(gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE); + fab_line(gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); + fab_line(gc, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); + fab_line(gc, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); + } + break; + case 3: /* circle */ ; + for (i = 0; i <= size; i++) + fab_circle(gc, x, y, (i + 1) * DRILL_MARK_SIZE - DRILL_MARK_SIZE / 2); + break; + case 4: /* square */ + for (i = 1; i <= size + 1; i++) { + fab_line(gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE); + fab_line(gc, x - i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); + fab_line(gc, x - i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); + fab_line(gc, x + i * DRILL_MARK_SIZE, y - i * DRILL_MARK_SIZE, x + i * DRILL_MARK_SIZE, y + i * DRILL_MARK_SIZE); + } + break; + } +} + +static int count_drill_lines(pcb_drill_info_t *AllDrills) +{ + int n, ds = 0; + for (n = AllDrills->DrillN - 1; n >= 0; n--) { + pcb_drill_t *drill = &(AllDrills->Drill[n]); + if (drill->PinCount + drill->ViaCount > drill->UnplatedCount) + ds++; + if (drill->UnplatedCount) + ds++; + } + return ds; +} + + +static int DrawFab_overhang(void) +{ + pcb_drill_info_t *AllDrills = drill_get_info(PCB->Data); + int ds = count_drill_lines(AllDrills); + if (ds < 4) + ds = 4; + return (ds + 2) * TEXT_LINE; +} + +static void draw_fab_layer(pcb_draw_info_t *info, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e, pcb_layer_t *layer, int found) +{ + rnd_hid_set_line_width(gc, RND_MIL_TO_COORD(10)); + PCB_LINE_LOOP(layer); + { + rnd_render->draw_line(gc, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); + } + PCB_END_LOOP; + PCB_ARC_LOOP(layer); + { + rnd_render->draw_arc(gc, arc->X, arc->Y, arc->Width, arc->Height, arc->StartAngle, arc->Delta); + } + PCB_END_LOOP; + PCB_TEXT_LOOP(layer); + { + pcb_text_draw_(info, text, 0, 0, PCB_TXT_TINY_ACCURATE); + } + PCB_END_LOOP; + if (!found) { + rnd_hid_set_line_width(gc, FAB_LINE_W); + text_at(info, gc, PCB->hidlib.size_x / 2, PCB->hidlib.size_y + RND_MIL_TO_COORD(20), 1, "Board outline is the centerline of this path"); + } +} + +static void DrawFab(pcb_draw_info_t *info, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + pcb_drill_info_t *AllDrills; + int i, n, yoff, total_drills = 0, ds = 0, found; + char utcTime[64]; + + AllDrills = drill_get_info(PCB->Data); + if (rnd_conf.editor.grid_unit->family == RND_UNIT_IMPERIAL) + drill_round_info(AllDrills, RND_MIL_TO_COORD(1)); + else + drill_round_info(AllDrills, RND_MM_TO_COORD(0.01)); + yoff = -TEXT_LINE; + + /* count how many drill description lines will be needed */ + ds = count_drill_lines(AllDrills); + + /* + * When we only have a few drill sizes we need to make sure the + * drill table header doesn't fall on top of the board info + * section. + */ + if (ds < 4) { + yoff -= (4 - ds) * TEXT_LINE; + } + + rnd_hid_set_line_cap(gc, rnd_cap_round); + rnd_hid_set_line_width(gc, FAB_LINE_W); + + for (n = AllDrills->DrillN - 1; n >= 0; n--) { + int plated_sym = -1, unplated_sym = -1; + pcb_drill_t *drill = &(AllDrills->Drill[n]); + if (drill->PinCount + drill->ViaCount > drill->UnplatedCount) + plated_sym = --ds; + if (drill->UnplatedCount) + unplated_sym = --ds; + rnd_render->set_color(gc, &conf_core.appearance.color.pin); + for (i = 0; i < drill->PinN; i++) { + int unplated = 1; + rnd_coord_t x, y; + assert(drill->hole[i]->type == PCB_OBJ_PSTK); + { + pcb_pstk_t *ps = (pcb_pstk_t *)drill->hole[i]; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + unplated = !proto->hplated; + x = ps->x; + y = ps->y; + } + drill_sym(gc, unplated ? unplated_sym : plated_sym, x, y); + } + if (plated_sym != -1) { + drill_sym(gc, plated_sym, TEXT_SIZE, yoff + TEXT_SIZE / 4); + text_at(info, gc, RND_MIL_TO_COORD(1350), yoff, RND_MIL_TO_COORD(2), "YES"); + text_at(info, gc, RND_MIL_TO_COORD(980), yoff, RND_MIL_TO_COORD(2), "%d", drill->PinCount + drill->ViaCount - drill->UnplatedCount); + + if (unplated_sym != -1) + yoff -= TEXT_LINE; + } + if (unplated_sym != -1) { + drill_sym(gc, unplated_sym, TEXT_SIZE, yoff + TEXT_SIZE / 4); + text_at(info, gc, RND_MIL_TO_COORD(1400), yoff, RND_MIL_TO_COORD(2), "NO"); + text_at(info, gc, RND_MIL_TO_COORD(980), yoff, RND_MIL_TO_COORD(2), "%d", drill->UnplatedCount); + } + rnd_render->set_color(gc, &conf_core.appearance.color.element); + if (rnd_conf.editor.grid_unit->family == RND_UNIT_IMPERIAL) + text_at(info, gc, RND_MIL_TO_COORD(450), yoff, RND_MIL_TO_COORD(2), "%0.3f", RND_COORD_TO_INCH(drill->DrillSize)); + else + text_at(info, gc, RND_MIL_TO_COORD(450), yoff, RND_MIL_TO_COORD(2), "%1.2f", RND_COORD_TO_MM(drill->DrillSize)); + if (plated_sym != -1 && unplated_sym != -1) { + if (rnd_conf.editor.grid_unit->family == RND_UNIT_IMPERIAL) + text_at(info, gc, RND_MIL_TO_COORD(450), yoff + TEXT_LINE, RND_MIL_TO_COORD(2), "%0.3f", RND_COORD_TO_INCH(drill->DrillSize)); + else + text_at(info, gc, RND_MIL_TO_COORD(450), yoff + TEXT_LINE, RND_MIL_TO_COORD(2), "%1.2f", RND_COORD_TO_MM(drill->DrillSize)); + } + yoff -= TEXT_LINE; + total_drills += drill->PinCount; + total_drills += drill->ViaCount; + } + + rnd_render->set_color(gc, &conf_core.appearance.color.element); + text_at(info, gc, 0, yoff, RND_MIL_TO_COORD(9), "Symbol"); + if (rnd_conf.editor.grid_unit->family == RND_UNIT_IMPERIAL) + text_at(info, gc, RND_MIL_TO_COORD(410), yoff, RND_MIL_TO_COORD(9), "Diam. (Inch)"); + else + text_at(info, gc, RND_MIL_TO_COORD(410), yoff, RND_MIL_TO_COORD(9), "Diam. (mm)"); + text_at(info, gc, RND_MIL_TO_COORD(950), yoff, RND_MIL_TO_COORD(9), "Count"); + text_at(info, gc, RND_MIL_TO_COORD(1300), yoff, RND_MIL_TO_COORD(9), "Plated?"); + yoff -= TEXT_LINE; + text_at(info, gc, 0, yoff, 0, + "There are %d different drill sizes used in this layout, %d holes total", AllDrills->DrillN, total_drills); + /* Create a portable timestamp. */ + + if (!conf_draw_fab.plugins.draw_fab.omit_date) + rnd_print_utc(utcTime, sizeof(utcTime), 0); + else + strcpy(utcTime, ""); + + yoff = -TEXT_LINE; + for (found = 0, i = 0; i < pcb_max_layer(PCB); i++) { + pcb_layer_t *l = &PCB->Data->Layer[i]; + pcb_layer_type_t flags = pcb_layer_flags(PCB, i); + int purpi = pcb_layer_purpose(PCB, i, NULL); + if (PCB_LAYER_IS_ROUTE(flags, purpi) && (!RND_RTREE_EMPTY(l->line_tree) || !RND_RTREE_EMPTY(l->arc_tree))) { + draw_fab_layer(info, gc, e, l, found); + found = 1; + } + } + if (!found) { + rnd_hid_set_line_width(gc, RND_MIL_TO_COORD(10)); + rnd_render->draw_line(gc, 0, 0, PCB->hidlib.size_x, 0); + rnd_render->draw_line(gc, 0, 0, 0, PCB->hidlib.size_y); + rnd_render->draw_line(gc, PCB->hidlib.size_x, 0, PCB->hidlib.size_x, PCB->hidlib.size_y); + rnd_render->draw_line(gc, 0, PCB->hidlib.size_y, PCB->hidlib.size_x, PCB->hidlib.size_y); + /*FPrintOutline (); */ + rnd_hid_set_line_width(gc, FAB_LINE_W); + text_at(info, gc, RND_MIL_TO_COORD(2000), yoff, 0, + "Maximum Dimensions: %f mils wide, %f mils high", RND_COORD_TO_MIL(PCB->hidlib.size_x), RND_COORD_TO_MIL(PCB->hidlib.size_y)); + text_at(info, gc, PCB->hidlib.size_x / 2, PCB->hidlib.size_y + RND_MIL_TO_COORD(20), 1, + "Board outline is the centerline of this %f mil" + " rectangle - 0,0 to %f,%f mils", + RND_COORD_TO_MIL(FAB_LINE_W), RND_COORD_TO_MIL(PCB->hidlib.size_x), RND_COORD_TO_MIL(PCB->hidlib.size_y)); + } + yoff -= TEXT_LINE; + + text_at(info, gc, RND_MIL_TO_COORD(2000), yoff, 0, "Date: %s", utcTime); + yoff -= TEXT_LINE; + text_at(info, gc, RND_MIL_TO_COORD(2000), yoff, 0, "Author: %s", pcb_author()); + yoff -= TEXT_LINE; + text_at(info, gc, RND_MIL_TO_COORD(2000), yoff, 0, "Title: %s - Fabrication Drawing", RND_UNKNOWN(PCB->hidlib.name)); +} + +int pplg_check_ver_draw_fab(int ver_needed) { return 0; } + +void pplg_uninit_draw_fab(void) +{ + rnd_conf_unreg_fields("plugins/draw_fab/"); +} + +int pplg_init_draw_fab(void) +{ + RND_API_CHK_VER; + pcb_stub_draw_fab = DrawFab; + pcb_stub_draw_fab_overhang = DrawFab_overhang; + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_draw_fab, field,isarray,type_name,cpath,cname,desc,flags); +#include "draw_fab_conf_fields.h" + + + return 0; +} Index: tags/2.3.0/src_plugins/draw_fab/draw_fab.pup =================================================================== --- tags/2.3.0/src_plugins/draw_fab/draw_fab.pup (nonexistent) +++ tags/2.3.0/src_plugins/draw_fab/draw_fab.pup (revision 33253) @@ -0,0 +1,10 @@ +$class feature +$short fab layer in some exports +$long Draw the fab layer (for various exporters). +$package (core) +$state works +default buildin + +# for drill.[ch] +dep report +autoload 1 Index: tags/2.3.0/src_plugins/draw_fab/draw_fab_conf.h =================================================================== --- tags/2.3.0/src_plugins/draw_fab/draw_fab_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/draw_fab/draw_fab_conf.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_DRAW_FAB_CONF_H +#define PCB_DRAW_FAB_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN omit_date; /* do not draw date (useful for testing) */ + } draw_fab; + } plugins; +} conf_draw_fab_t; + +#endif Index: tags/2.3.0/src_plugins/draw_fontsel/Makefile =================================================================== --- tags/2.3.0/src_plugins/draw_fontsel/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/draw_fontsel/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_draw_fontsel + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/draw_fontsel/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/draw_fontsel/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/draw_fontsel/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {draw_fontsel} +append /local/pcb/mod/OBJS [@ + $(PLUGDIR)/draw_fontsel/draw_fontsel.o +@] + +switch /local/pcb/draw_fontsel/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/draw_fontsel/draw_fontsel.c =================================================================== --- tags/2.3.0/src_plugins/draw_fontsel/draw_fontsel.c (nonexistent) +++ tags/2.3.0/src_plugins/draw_fontsel/draw_fontsel.c (revision 33253) @@ -0,0 +1,207 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* printing routines */ +#include "config.h" + +#include + +#include "board.h" +#include "build_run.h" +#include "data.h" +#include "draw.h" +#include "font.h" +#include +#include +#include "stub_draw.h" +#include +#include +#include "conf_core.h" + +#include "obj_text.h" +#include "obj_text_draw.h" +#include "obj_line_draw.h" + +static pcb_draw_info_t dinfo; +static rnd_xform_t dxform; + + +static pcb_text_t *dtext(int x, int y, int scale, pcb_font_id_t fid, const char *txt) +{ + static pcb_text_t t = {0}; + + if (dinfo.xform == NULL) dinfo.xform = &dxform; + + t.X = RND_MM_TO_COORD(x); + t.Y = RND_MM_TO_COORD(y); + t.TextString = (char *)txt; + t.Scale = scale; + t.fid = fid; + t.Flags = pcb_no_flags(); + pcb_text_draw_(&dinfo, &t, 0, 0, PCB_TXT_TINY_ACCURATE); + return &t; +} + +/* draw a line of a specific thickness */ +static void dline(int x1, int y1, int x2, int y2, float thick) +{ + pcb_line_t l; + + if (dinfo.xform == NULL) dinfo.xform = &dxform; + + l.Point1.X = RND_MM_TO_COORD(x1); + l.Point1.Y = RND_MM_TO_COORD(y1); + l.Point2.X = RND_MM_TO_COORD(x2); + l.Point2.Y = RND_MM_TO_COORD(y2); + l.Thickness = RND_MM_TO_COORD(thick); + pcb_line_draw_(&dinfo, &l, 0); +} + +static void dchkbox(rnd_hid_gc_t gc, int x0, int y0, int checked) +{ + int w = 2, h = 2; + float th = 0.1, th2 = 0.4; + + rnd_render->set_color(gc, rnd_color_black); + dline(x0, y0, x0+w, y0, th); + dline(x0+w, y0, x0+w, y0+h, th); + dline(x0+w, y0+h, x0, y0+h, th); + dline(x0, y0+h, x0, y0, th); + if (checked) { + rnd_render->set_color(gc, rnd_color_red); + dline(x0, y0, x0+w, y0+h, th2); + dline(x0, y0+h, x0+w, y0, th2); + } +} + +#define MAX_FONT 128 +typedef struct { + int y1, y2; + pcb_font_id_t fid; +} font_coord_t; + +font_coord_t font_coord[MAX_FONT]; +int font_coords; + +static void pcb_draw_font(rnd_hid_gc_t gc, pcb_font_t *f, int x, int *y, pcb_text_t *txt) +{ + char buf[256]; + pcb_text_t *t; + const char *nm; + int y_old = *y; + pcb_font_id_t target_fid = (txt == NULL) ? conf_core.design.text_font_id : txt->fid; + + nm = (f->name == NULL) ? "" : f->name; + rnd_snprintf(buf, sizeof(buf), "#%d [abc ABC 123] %s", f->id, nm); + + dchkbox(gc, x-4, *y, (f->id == target_fid)); + + rnd_render->set_color(gc, rnd_color_black); + t = dtext(x, *y, 200, f->id, buf); + pcb_text_bbox(pcb_font(PCB, f->id, 1), t); + + *y += rnd_round(RND_COORD_TO_MM(t->BoundingBox.Y2 - t->BoundingBox.Y1) + 0.5); + + if (font_coords < MAX_FONT) { + font_coord[font_coords].y1 = y_old; + font_coord[font_coords].y2 = *y; + font_coord[font_coords].fid = f->id; + font_coords++; + } +} + + +static void pcb_draw_fontsel(rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e, pcb_text_t *txt) +{ + int y = 0; + + font_coords = 0; + pcb_draw_font(gc, &PCB->fontkit.dflt, 0, &y, txt); + + if (PCB->fontkit.hash_inited) { + htip_entry_t *e; + for (e = htip_first(&PCB->fontkit.fonts); e; e = htip_next(&PCB->fontkit.fonts, e)) + pcb_draw_font(gc, e->value, 0, &y, txt); + } +} + +static pcb_font_id_t lookup_fid_for_coord(int ymm) +{ + int n; + + for(n = 0; n < font_coords; n++) + if ((ymm >= font_coord[n].y1) && (ymm <= font_coord[n].y2)) + return font_coord[n].fid; + return -1; +} + +static rnd_bool pcb_mouse_fontsel(rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y, pcb_text_t *txt) +{ + pcb_font_id_t fid; + int ymm; + + switch(kind) { + case RND_HID_MOUSE_PRESS: + ymm = RND_COORD_TO_MM(y); + fid = lookup_fid_for_coord(ymm); + if (fid >= 0) { + if (txt == NULL) { + char sval[128]; + sprintf(sval, "%ld", fid); + rnd_conf_set(RND_CFR_DESIGN, "design/text_font_id", 0, sval, RND_POL_OVERWRITE); + } + else { + switch(txt->type) { + case PCB_OBJ_TEXT: + pcb_text_set_font(txt, fid); + break; + default: + break; + } + rnd_gui->invalidate_all(rnd_gui); + } + return 1; + } + default: + break; + } + return 0; +} + +int pplg_check_ver_draw_fontsel(int ver_needed) { return 0; } + +void pplg_uninit_draw_fontsel(void) +{ +} + +int pplg_init_draw_fontsel(void) +{ + RND_API_CHK_VER; + pcb_stub_draw_fontsel = pcb_draw_fontsel; + pcb_stub_draw_fontsel_mouse_ev = pcb_mouse_fontsel; + return 0; +} Index: tags/2.3.0/src_plugins/draw_fontsel/draw_fontsel.pup =================================================================== --- tags/2.3.0/src_plugins/draw_fontsel/draw_fontsel.pup (nonexistent) +++ tags/2.3.0/src_plugins/draw_fontsel/draw_fontsel.pup (revision 33253) @@ -0,0 +1,6 @@ +$class feature +$short font selection GUI +$long Draw the font selector GUI +$package lib-gui +$state works +default disable Index: tags/2.3.0/src_plugins/drc_query/Makefile =================================================================== --- tags/2.3.0/src_plugins/drc_query/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/drc_query/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_drc_query + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/drc_query/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/drc_query/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/drc_query/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {drc_query} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/drc_query/drc_query.o @] +put /local/pcb/mod/CONF {$(PLUGDIR)/drc_query/drc_query_conf.h} +put /local/pcb/mod/CONFFILE {drc_query.conf} +put /local/pcb/mod/CONFVAR {drc_query_conf_internal} + +switch /local/pcb/drc_query/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/drc_query/dlg.c =================================================================== --- tags/2.3.0/src_plugins/drc_query/dlg.c (nonexistent) +++ tags/2.3.0/src_plugins/drc_query/dlg.c (revision 33253) @@ -0,0 +1,976 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include +#include +#include +#include "actions_pcb.h" + +#define PCB dont_use + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + drc_query_prog_t *prog; + int wname, wtotprog, wcurrprog, wcnt, force_close; +} progbar_t; + +static void drc_query_progress_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + progbar_t *pb = caller_data; + if (!pb->force_close) + pb->prog->cancel = 1; + pb->prog->dialog = NULL; + if (!pb->force_close) { + RND_DAD_FREE(pb->dlg); + free(pb); + } +} + +void drc_query_progress_dlg(progbar_t *pb) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 0}, {NULL, 0}}; + + RND_DAD_BEGIN_VBOX(pb->dlg); + RND_DAD_COMPFLAG(pb->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(pb->dlg); + RND_DAD_LABEL(pb->dlg, "DRC rule script:"); + RND_DAD_LABEL(pb->dlg, "n/a"); + pb->wname = RND_DAD_CURRENT(pb->dlg); + RND_DAD_END(pb->dlg); + + RND_DAD_LABEL(pb->dlg, "Overall progress:"); + RND_DAD_PROGRESS(pb->dlg); + pb->wtotprog = RND_DAD_CURRENT(pb->dlg); + + RND_DAD_LABEL(pb->dlg, "Current execution progress:"); + RND_DAD_PROGRESS(pb->dlg); + pb->wcurrprog = RND_DAD_CURRENT(pb->dlg); + + RND_DAD_BEGIN_HBOX(pb->dlg); + RND_DAD_LABEL(pb->dlg, "Violatons so far:"); + RND_DAD_LABEL(pb->dlg, "0"); + pb->wcnt = RND_DAD_CURRENT(pb->dlg); + RND_DAD_END(pb->dlg); + + RND_DAD_BUTTON_CLOSES(pb->dlg, clbtn); + RND_DAD_END(pb->dlg); + + RND_DAD_DEFSIZE(pb->dlg, 200, 200); + RND_DAD_NEW("drc_query_progress", pb->dlg, "drc_query: DRC progress", pb, rnd_true, drc_query_progress_close_cb); +} + +static int drc_query_progress(pcb_qry_exec_t *ec, long at, long total) +{ + drc_query_prog_t *prog = ec->progress_ctx; + progbar_t *pb = prog->dialog; + rnd_hid_attr_val_t hv; + char tmp[128]; + + if (!RND_HAVE_GUI_ATTR_DLG) { + fprintf(stderr, "DRC: %ld/%ld %s %ld/%ld", prog->script_at, prog->script_total, prog->name, at, total); + if (prog->qctx != NULL) + fprintf(stderr, " Violations: %ld\n", prog->qctx->hit_cnt); + else + fprintf(stderr, "\n"); + return prog->cancel; + } + + if (total < 0) { + if (prog->dialog == NULL) + return 0; + prog->dialog = NULL; + pb->force_close = 1; + RND_DAD_FREE(pb->dlg); + free(pb); + return 0; + } + + if (prog->dialog == NULL) { + pb = calloc(sizeof(progbar_t), 1); + prog->dialog = pb; + pb->prog = prog; + drc_query_progress_dlg(pb); + } + + + hv.str = prog->name; + rnd_gui->attr_dlg_set_value(pb->dlg_hid_ctx, pb->wname, &hv); + + hv.dbl = (double)prog->script_at / (double)prog->script_total; + rnd_gui->attr_dlg_set_value(pb->dlg_hid_ctx, pb->wtotprog, &hv); + + hv.dbl = (double)at / (double)total; + rnd_gui->attr_dlg_set_value(pb->dlg_hid_ctx, pb->wcurrprog, &hv); + + if (prog->qctx != NULL) { + sprintf(tmp, "%ld", prog->qctx->hit_cnt); + hv.str = rnd_strdup(tmp); + rnd_gui->attr_dlg_set_value(pb->dlg_hid_ctx, pb->wcnt, &hv); + } + + rnd_hid_iterate(rnd_gui); + return prog->cancel; +} + + +static void rlist_select(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row); +static void drc_dlist_pcb2dlg(void); + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + rnd_conf_role_t role; + char *rule, *path; + int wtype, wtitle, wsource, wdisable, wdesc, wquery, wsave, wsaveroles; + gdl_elem_t link; +} rule_edit_ctx_t; + +static const char *save_roles[] = {"user", "project", "design", "cli", NULL}; +static rnd_conf_role_t save_rolee[] = { RND_CFR_USER, RND_CFR_PROJECT, RND_CFR_DESIGN, RND_CFR_CLI}; +#define save_role_defaulti 2 + +gdl_list_t rule_edit_dialogs; + +static void rule_edit_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + rule_edit_ctx_t *ctx = caller_data; + + gdl_remove(&rule_edit_dialogs, ctx, link); + + free(ctx->path); + free(ctx->rule); + RND_DAD_FREE(ctx->dlg); + free(ctx); +} + +static void drc_rule_pcb2dlg(rule_edit_ctx_t *ctx) +{ + rnd_dad_retovr_t retovr; + lht_node_t *nd = rnd_conf_lht_get_at_mainplug(ctx->role, ctx->path, 1, 0); + if (nd != NULL) { + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wquery]; + rnd_hid_text_t *txt = atxt->wdata; + int *dis, dis_ = 0; + + dis = drc_get_disable(ctx->rule); + if (dis == NULL) + dis = &dis_; + + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wtype, str, textval_empty(nd, "type")); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wtitle, str, textval_empty(nd, "title")); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wsource, str, textval_empty(nd, "source")); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wdisable, str, *dis ? "yes" : "no"); + RND_DAD_SET_VALUE(ctx->dlg_hid_ctx, ctx->wdesc, str, textval_empty(nd, "desc")); + + txt->hid_set_text(atxt, ctx->dlg_hid_ctx, RND_HID_TEXT_REPLACE, textval_empty(nd, "query")); + } + else { + rnd_message(RND_MSG_ERROR, "Rule %s disappeared from the config tree.\n", ctx->rule); + rnd_hid_dad_close(ctx->dlg_hid_ctx, &retovr, -1); + } +} + +static void drcq_open_view_win(rnd_hidlib_t *hidlib, pcb_view_list_t *view) +{ + fgw_arg_t args[4], ares; + args[1].type = FGW_STR; args[1].val.str = "drc_query: manual run"; + args[2].type = FGW_STR; args[2].val.str = "drc_query_run"; + fgw_ptr_reg(&rnd_fgw, &args[3], PCB_PTR_DOMAIN_VIEWLIST, FGW_PTR | FGW_STRUCT, view); + rnd_actionv_bin(hidlib, "viewlist", &ares, 4, args); + +} + +static void rule_btn_run_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + rule_edit_ctx_t *ctx = caller_data; + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wquery]; + rnd_hid_text_t *txt = atxt->wdata; + char *script = txt->hid_get_text(atxt, hid_ctx); + pcb_view_list_t *view = calloc(sizeof(pcb_view_list_t), 1); + pcb_board_t *pcb = (pcb_board_t *)rnd_gui->get_dad_hidlib(hid_ctx); + pcb_qry_exec_t ec; + + pcb_qry_init(&ec, pcb, NULL, -1); + drc_qry_exec(&ec, pcb, view, ctx->rule, + ctx->dlg[ctx->wtype].val.str, + ctx->dlg[ctx->wtitle].val.str, + ctx->dlg[ctx->wdesc].val.str, + script); + drcq_open_view_win(&pcb->hidlib, view); + pcb_qry_uninit(&ec); + + free(script); + drc_rlist_pcb2dlg(); /* for the run time */ +} + +static void rule_btn_save_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + rule_edit_ctx_t *ctx = caller_data; + int ri = ctx->dlg[ctx->wsaveroles].val.lng; + lht_node_t *nd; + rnd_conf_role_t role; + rnd_hid_attribute_t *atxt = &ctx->dlg[ctx->wquery]; + rnd_hid_text_t *txt = atxt->wdata; + + if ((ri < 0) || (ri >= sizeof(save_rolee)/sizeof(save_rolee[0]))) { + rnd_message(RND_MSG_ERROR, "Internal error: role out of range, rule is NOT saved\n"); + return; + } + + role = save_rolee[ri]; + nd = rnd_conf_lht_get_at_mainplug(role, ctx->path, 1, 0); + if (nd == NULL) { + MKDIR_RULE_ROOT(nd, role, RND_POL_OVERWRITE, return); + MKDIR_RULES(nd, return); + if ((nd->data.list.first == NULL) && (role != RND_CFR_USER)) { + gdl_iterator_t it; + rnd_conf_listitem_t *i; + + /* need to copy all rules! */ + rnd_conflist_foreach(&conf_drc_query.plugins.drc_query.rules, &it, i) { + lht_node_t *nnew = lht_dom_duptree(i->prop.src); + lht_dom_list_append(nd, nnew); + } + rnd_message(RND_MSG_WARNING, "NOTE: Copying ALL drc rule to config role %s\n", ctx->rule, save_roles[ri]); + } + MKDIR_ND(nd, nd, LHT_HASH, ctx->rule, return); + rnd_message(RND_MSG_INFO, "NOTE: Copying drc rule '%s' to config role %s\n", ctx->rule, save_roles[ri]); + } + + MKDIR_ND_SET_TEXT(nd, "type", ctx->dlg[ctx->wtype].val.str, return); + MKDIR_ND_SET_TEXT(nd, "desc", ctx->dlg[ctx->wdesc].val.str, return); + MKDIR_ND_SET_TEXT(nd, "title", ctx->dlg[ctx->wtitle].val.str, return); + MKDIR_ND_SET_TEXT(nd, "source", ctx->dlg[ctx->wsource].val.str, return); + MKDIR_ND_SET_TEXT(nd, "query", txt->hid_get_text(atxt, hid_ctx), return); + + rnd_conf_update(NULL, -1); + drc_rlist_pcb2dlg(); +} + +static int pcb_dlg_rule_edit(rnd_conf_role_t role, const char *rule) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + char *info, *path; + rule_edit_ctx_t *ctx; + lht_node_t *nd; + int n, srolei = save_role_defaulti; + + for(ctx = gdl_first(&rule_edit_dialogs); ctx != NULL; ctx = gdl_next(&rule_edit_dialogs, ctx)) + { + if (strcmp(rule, ctx->rule) == 0) { + rnd_message(RND_MSG_ERROR, "An edit dialog for rule %s is already open.\n", rule); + return 0; + } + } + + path = rnd_concat(DRC_CONF_PATH_RULES, rule, ":0", NULL); + nd = rnd_conf_lht_get_at_mainplug(role, path, 1, 0); + if (nd == NULL) { + rnd_message(RND_MSG_ERROR, "Rule %s not found on this role.\n", rule); + return -1; + } + + ctx = calloc(sizeof(rule_edit_ctx_t), 1); + ctx->role = role; + ctx->rule = rnd_strdup(rule); + ctx->path = path; + + gdl_insert(&rule_edit_dialogs, ctx, link); + + /* attempt to set save role to input role, if input role is not read-only */ + for(n = 0; n < sizeof(save_rolee)/sizeof(save_rolee[0]); n++) { + if (save_rolee[n] == role) { + srolei = n; + break; + } + } + + info = rnd_strdup_printf("DRC rule edit: %s on role %s", rule, rnd_conf_role_name(role)); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, info); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "DRC violation type (group):"); + RND_DAD_STRING(ctx->dlg); + RND_DAD_WIDTH_CHR(ctx->dlg, 24); + ctx->wtype = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "DRC violation title:"); + RND_DAD_STRING(ctx->dlg); + RND_DAD_WIDTH_CHR(ctx->dlg, 32); + ctx->wtitle = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Rule source:"); + RND_DAD_STRING(ctx->dlg); + RND_DAD_WIDTH_CHR(ctx->dlg, 32); + ctx->wsource = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Disable drc rule:"); + RND_DAD_BOOL(ctx->dlg); + ctx->wdisable = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "DRC violation description:"); + RND_DAD_STRING(ctx->dlg); + RND_DAD_WIDTH_CHR(ctx->dlg, 48); + ctx->wdesc = RND_DAD_CURRENT(ctx->dlg); + + RND_DAD_LABEL(ctx->dlg, "DRC rule query script:"); + RND_DAD_TEXT(ctx->dlg, ctx); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wquery = RND_DAD_CURRENT(ctx->dlg); + + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Run"); + RND_DAD_CHANGE_CB(ctx->dlg, rule_btn_run_cb); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_TIGHT); + RND_DAD_BUTTON(ctx->dlg, "Save"); + RND_DAD_CHANGE_CB(ctx->dlg, rule_btn_save_cb); + ctx->wsave = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "Save rule at the selected conf role\nFor roles other than 'user', a full copy of all drc rules are saved!\n"); + RND_DAD_ENUM(ctx->dlg, save_roles); + ctx->wsaveroles = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_DEFAULT_NUM(ctx->dlg, srolei); + RND_DAD_HELP(ctx->dlg, "Save rule at the selected conf role\nFor roles other than 'user', a full copy of all drc rules are saved!\n"); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + free(info); + + RND_DAD_DEFSIZE(ctx->dlg, 200, 400); + RND_DAD_NEW("drc_query_rule_edit", ctx->dlg, "drc_query: rule editor", ctx, rnd_false, rule_edit_close_cb); + + drc_rule_pcb2dlg(ctx); + + return 0; +} + +static const char pcb_acts_DrcQueryEditRule[] = "DrcQueryEditRule(role, path, rule)\nDrcQueryEditRule(role, rule)\n"; +static const char pcb_acth_DrcQueryEditRule[] = "Interactive, GUI based DRC rule editor"; +static fgw_error_t pcb_act_DrcQueryEditRule(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *srole, *spath, *srule = NULL; + rnd_conf_role_t role; + + RND_ACT_CONVARG(1, FGW_STR, DrcQueryEditRule, srole = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, DrcQueryEditRule, spath = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, DrcQueryEditRule, srule = argv[3].val.str); + + if (srule == NULL) + srule = spath; + + role = rnd_conf_role_parse(srole); + if (role == RND_CFR_invalid) + RND_ACT_FAIL(DrcQueryEditRule); + + RND_ACT_IRES(pcb_dlg_rule_edit(role, srule)); + return 0; +} + + + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ + int wrlist, wrule, wtype, wtitle, wdesc, wstat; /* rule */ + int wdlist, wdef, wdtype, wdefault, wddesc, wvalue; /* define */ +} drc_rlist_ctx_t; + +static drc_rlist_ctx_t drc_rlist_ctx; + +static void drc_rlist_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + drc_rlist_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(drc_rlist_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void drc_rlist_pcb2dlg(void) +{ + drc_rlist_ctx_t *ctx = &drc_rlist_ctx; + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[5], *cursor_path = NULL; + gdl_iterator_t it; + rnd_conf_listitem_t *i; + pcb_drcq_stat_t *st; + + if (!ctx->active) + return; + + attr = &ctx->dlg[ctx->wrlist]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + cell[4] = NULL; + + rnd_conflist_foreach(&conf_drc_query.plugins.drc_query.rules, &it, i) { + const char *src; + int *dis, dis_ = 0; + rnd_conf_role_t role; + lht_node_t *rule = i->prop.src; + st = pcb_drcq_stat_get(rule->name); + + if (rule->type != LHT_HASH) + continue; + + dis = drc_get_disable(rule->name); + if (dis == NULL) + dis = &dis_; + + role = rnd_conf_lookup_role(rule); + src = textval_empty(rule, "source"); + cell[0] = rule->name; + cell[1] = rnd_strdup(rnd_conf_role_name(role)); + cell[2] = *dis ? "YES" : "no"; + if (st->run_cnt > 0) + cell[3] = rnd_strdup_printf("%.3fs", st->last_run_time); + else + cell[3] = "-"; + + if (*src != '\0') { + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *parent = htsp_get(&tree->paths, src); + char *pcell[5]; + + if (parent == NULL) { + pcell[0] = (char *)src; + pcell[1] = ""; + pcell[2] = ""; + pcell[3] = ""; + pcell[4] = NULL; + parent = rnd_dad_tree_append(tree->attrib, NULL, pcell); + } + rnd_dad_tree_append_under(tree->attrib, parent, cell); + } + else + rnd_dad_tree_append(attr, NULL, cell); + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wrlist, &hv); + free(cursor_path); + + r = rnd_dad_tree_get_selected(attr); + rlist_select(&ctx->dlg[ctx->wrlist], ctx->dlg_hid_ctx, r); + } +} + +static void rlist_btn_toggle_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + drc_rlist_ctx_t *ctx = caller_data; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&(ctx->dlg[ctx->wrlist])); + int *dis; + + if (row == NULL) { + rnd_message(RND_MSG_ERROR, "Select a rule first!\n"); + return; + } + + dis = drc_get_disable(row->cell[0]); + if (dis == NULL) { + rnd_message(RND_MSG_ERROR, "internal error: no disable conf node for %s\n", row->cell[0]); + return; + } + + *dis = !*dis; + drc_rlist_pcb2dlg(); +} + +#define rlist_fetch() \ +do { \ + if (row == NULL) { \ + rnd_message(RND_MSG_ERROR, "Select a rule first!\n"); \ + return; \ + } \ + if (*row->cell[1] == '\0') \ + return; \ + role = rnd_conf_role_parse(row->cell[1]); \ + if (role == RND_CFR_invalid) { \ + rnd_message(RND_MSG_ERROR, "internal error: invalid role %s\n", row->cell[0]); \ + return; \ + } \ +} while(0) + +#define dlist_fetch rlist_fetch + + +static const char *rule_basename(const char *cell0) +{ + const char *basename = strchr(cell0, '/'); + if (basename == NULL) + return cell0; + return basename+1; +} + +#define rlist_fetch_nd() \ +do { \ + if (*row->cell[1] != '\0') { \ + const char *basename = rule_basename(row->cell[0]); \ + pcb_drc_query_rule_by_name(basename, &nd, 0); \ + if (nd == NULL) { \ + rnd_message(RND_MSG_ERROR, "internal error: rule %s not found\n", basename); \ + return; \ + } \ + } \ + else \ + return; \ +} while(0) + +#define dlist_fetch_nd() \ +do { \ + if (*row->cell[1] != '\0') { \ + const char *basename = rule_basename(row->cell[0]); \ + pcb_drc_query_def_by_name(basename, &nd, 0); \ + if (nd == NULL) { \ + rnd_message(RND_MSG_ERROR, "internal error: definition %s not found\n", basename); \ + return; \ + } \ + } \ + else \ + return; \ +} while(0) + +static void rlist_btn_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + drc_rlist_ctx_t *ctx = caller_data; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&(ctx->dlg[ctx->wrlist])); + rnd_conf_role_t role; + + rlist_fetch(); + + pcb_dlg_rule_edit(role, row->cell[0]); +} + +static void rlist_btn_run_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + drc_rlist_ctx_t *ctx = caller_data; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&(ctx->dlg[ctx->wrlist])); + lht_node_t *nd; + const char *script; + rnd_conf_role_t role; + pcb_view_list_t *view; + pcb_board_t *pcb = (pcb_board_t *)rnd_gui->get_dad_hidlib(hid_ctx); + pcb_qry_exec_t ec; + + rlist_fetch(); + rlist_fetch_nd(); + + script = textval_empty(nd, "query"); + if (script == NULL) { + rnd_message(RND_MSG_ERROR, "Can not run rule %s: no query specified\n", row->cell[0]); + return; + } + + view = calloc(sizeof(pcb_view_list_t), 1); + pcb_qry_init(&ec, pcb, NULL, -1); + drc_qry_exec(&ec, pcb, view, rule_basename(row->cell[0]), textval_empty(nd, "type"), textval_empty(nd, "title"), textval_empty(nd, "desc"), script); + drcq_open_view_win(&pcb->hidlib, view); + pcb_qry_uninit(&ec); + drc_rlist_pcb2dlg(); /* for the run time */ +} + +static void rlist_btn_export_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + drc_rlist_ctx_t *ctx = caller_data; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&(ctx->dlg[ctx->wrlist])); + pcb_board_t *pcb = (pcb_board_t *)rnd_gui->get_dad_hidlib(hid_ctx); + + if (row == NULL) { + rnd_message(RND_MSG_ERROR, "Select a rule first\n"); + return; + } + + rnd_actionva(&pcb->hidlib, "DrcQueryExport", row->cell[0], NULL); +} + +static void rlist_btn_import_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_inp) +{ + pcb_board_t *pcb = (pcb_board_t *)rnd_gui->get_dad_hidlib(hid_ctx); + + rnd_actionva(&pcb->hidlib, "DrcQueryImport", NULL); + drc_rlist_pcb2dlg(); + drc_dlist_pcb2dlg(); +} + + +static void rlist_select(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_attr_val_t hv; + rnd_hid_tree_t *tree = attrib->wdata; + drc_rlist_ctx_t *ctx = tree->user_ctx; + lht_node_t *nd; + gds_t tmp; + rnd_conf_role_t role; + pcb_drcq_stat_t *st; + + rlist_fetch(); + rlist_fetch_nd(); + + hv.str = nd->name; + if (hv.str == NULL) hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wrule, &hv); + + hv.str = textval_empty(nd, "type"); + if (hv.str == NULL) hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtype, &hv); + + hv.str = textval_empty(nd, "title"); + if (hv.str == NULL) hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtitle, &hv); + + hv.str = textval_empty(nd, "desc"); + if (hv.str == NULL) hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wdesc, &hv); + + gds_init(&tmp); + st = pcb_drcq_stat_get(nd->name); + rnd_append_printf(&tmp, "Ran %ld times", st->run_cnt); + if (st->run_cnt > 0) { + rnd_append_printf(&tmp, "\nLast run took: %.6f s", st->last_run_time); + rnd_append_printf(&tmp, "\nTotal run time: %.6f s", st->sum_run_time); + rnd_append_printf(&tmp, "\nAverage run time: %.6f s", st->sum_run_time / (double)st->run_cnt); + rnd_append_printf(&tmp, "\nLast run violations: %ld", st->last_hit_cnt); + rnd_append_printf(&tmp, "\nTotal violations: %ld", st->sum_hit_cnt); + rnd_append_printf(&tmp, "\nAverage violations: %.2f", (double)st->sum_hit_cnt / (double)st->run_cnt); + } + hv.str = tmp.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wstat, &hv); + gds_uninit(&tmp); +} + +static void drc_dlist_pcb2dlg(void) +{ + drc_rlist_ctx_t *ctx = &drc_rlist_ctx; + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[3], *cursor_path = NULL; + gdl_iterator_t it; + rnd_conf_listitem_t *i; + + if (!ctx->active) + return; + + attr = &ctx->dlg[ctx->wdlist]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + cell[2] = NULL; + + rnd_conflist_foreach(&conf_drc_query.plugins.drc_query.definitions, &it, i) { + const char *src; + int *dis, dis_ = 0; + rnd_conf_role_t role; + lht_node_t *rule = i->prop.src; + + if (rule->type != LHT_HASH) + continue; + + dis = drc_get_disable(rule->name); + if (dis == NULL) + dis = &dis_; + + role = rnd_conf_lookup_role(rule); + src = textval_empty(rule, "source"); + cell[0] = rule->name; + cell[1] = rnd_strdup(rnd_conf_role_name(role)); + + if (*src != '\0') { + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *parent = htsp_get(&tree->paths, src); + char *pcell[3]; + + if (parent == NULL) { + pcell[0] = (char *)src; + pcell[1] = ""; + pcell[2] = NULL; + parent = rnd_dad_tree_append(tree->attrib, NULL, pcell); + } + rnd_dad_tree_append_under(tree->attrib, parent, cell); + } + else + rnd_dad_tree_append(attr, NULL, cell); + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wdlist, &hv); + free(cursor_path); + + r = rnd_dad_tree_get_selected(attr); + rlist_select(&ctx->dlg[ctx->wdlist], ctx->dlg_hid_ctx, r); + } +} + +static void dlist_btn_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + drc_rlist_ctx_t *ctx = caller_data; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&(ctx->dlg[ctx->wdlist])); + rnd_hidlib_t *hl = rnd_gui->get_dad_hidlib(hid_ctx); + lht_node_t *nd; + char *path; + + dlist_fetch_nd(); + + if (nd == NULL) + return; + + path = rnd_concat("design/drc/", nd->name, NULL); + rnd_actionva(hl, "dlg_confval_edit", path, "0", "design", NULL); + free(path); +} + +static void dlist_select(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + char *path; + rnd_hid_attr_val_t hv; + rnd_hid_tree_t *tree = attrib->wdata; + drc_rlist_ctx_t *ctx = tree->user_ctx; + lht_node_t *nd; + rnd_conf_role_t role; + gds_t tmp; + rnd_conf_native_t *nat; + + dlist_fetch(); + dlist_fetch_nd(); + + hv.str = nd->name; + if (hv.str == NULL) hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wdef, &hv); + + hv.str = textval_empty(nd, "type"); + if (hv.str == NULL) hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wdtype, &hv); + + hv.str = textval_empty(nd, "desc"); + if (hv.str == NULL) hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wddesc, &hv); + + hv.str = textval_empty(nd, "default"); + if (hv.str == NULL) hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wdefault, &hv); + + path = rnd_concat("design/drc/", nd->name, NULL); + nat = rnd_conf_get_field(path); + free(path); + gds_init(&tmp); + if (nat != NULL) { + rnd_conf_print_native((rnd_conf_pfn)rnd_append_printf, &tmp, "", 0, nat); + hv.str = tmp.array; + } + else + hv.str = ""; + if (hv.str == NULL) hv.str = ""; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wvalue, &hv); + gds_uninit(&tmp); +} + + +static void pcb_dlg_drc_rlist_rules(int *wpane) +{ + static const char *lst_hdr[] = {"rule name", "role", "disabled", "cost", NULL}; + + RND_DAD_BEGIN_HPANE(drc_rlist_ctx.dlg); + *wpane = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + + RND_DAD_BEGIN_VBOX(drc_rlist_ctx.dlg); /* left */ + RND_DAD_COMPFLAG(drc_rlist_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Rules available:"); + RND_DAD_TREE(drc_rlist_ctx.dlg, 4, 1, lst_hdr); + RND_DAD_COMPFLAG(drc_rlist_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + drc_rlist_ctx.wrlist = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_TREE_SET_CB(drc_rlist_ctx.dlg, selected_cb, rlist_select); + RND_DAD_TREE_SET_CB(drc_rlist_ctx.dlg, ctx, &drc_rlist_ctx); + RND_DAD_BEGIN_HBOX(drc_rlist_ctx.dlg); + RND_DAD_BUTTON(drc_rlist_ctx.dlg, "Run"); + RND_DAD_CHANGE_CB(drc_rlist_ctx.dlg, rlist_btn_run_cb); + RND_DAD_BUTTON(drc_rlist_ctx.dlg, "Edit..."); + RND_DAD_CHANGE_CB(drc_rlist_ctx.dlg, rlist_btn_edit_cb); + RND_DAD_BUTTON(drc_rlist_ctx.dlg, "Toggle disable"); + RND_DAD_CHANGE_CB(drc_rlist_ctx.dlg, rlist_btn_toggle_cb); + RND_DAD_BUTTON(drc_rlist_ctx.dlg, "Export..."); + RND_DAD_CHANGE_CB(drc_rlist_ctx.dlg, rlist_btn_export_cb); + RND_DAD_BUTTON(drc_rlist_ctx.dlg, "Import..."); + RND_DAD_CHANGE_CB(drc_rlist_ctx.dlg, rlist_btn_import_cb); + RND_DAD_END(drc_rlist_ctx.dlg); + RND_DAD_END(drc_rlist_ctx.dlg); + + RND_DAD_BEGIN_VBOX(drc_rlist_ctx.dlg); /* right */ + RND_DAD_COMPFLAG(drc_rlist_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(drc_rlist_ctx.dlg); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Rule: "); + RND_DAD_LABEL(drc_rlist_ctx.dlg, ""); + drc_rlist_ctx.wrule = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_END(drc_rlist_ctx.dlg); + + RND_DAD_BEGIN_VBOX(drc_rlist_ctx.dlg); + RND_DAD_COMPFLAG(drc_rlist_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Type/group:"); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "-"); + drc_rlist_ctx.wtype = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_LABEL(drc_rlist_ctx.dlg, ""); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Title:"); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "-"); + drc_rlist_ctx.wtitle = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_LABEL(drc_rlist_ctx.dlg, ""); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Description:"); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "-"); + drc_rlist_ctx.wdesc = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_LABEL(drc_rlist_ctx.dlg, ""); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Statistics:"); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "-"); + drc_rlist_ctx.wstat = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_END(drc_rlist_ctx.dlg); + RND_DAD_END(drc_rlist_ctx.dlg); + + RND_DAD_END(drc_rlist_ctx.dlg); +} + +static void pcb_dlg_drc_rlist_defs(int *wpane) +{ + static const char *lst_hdr[] = {"rule name", "role", NULL}; + + RND_DAD_BEGIN_HPANE(drc_rlist_ctx.dlg); + *wpane = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + + RND_DAD_BEGIN_VBOX(drc_rlist_ctx.dlg); /* left */ + RND_DAD_COMPFLAG(drc_rlist_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Definitions available:"); + RND_DAD_TREE(drc_rlist_ctx.dlg, 2, 1, lst_hdr); + RND_DAD_COMPFLAG(drc_rlist_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + drc_rlist_ctx.wdlist = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_TREE_SET_CB(drc_rlist_ctx.dlg, selected_cb, dlist_select); + RND_DAD_TREE_SET_CB(drc_rlist_ctx.dlg, ctx, &drc_rlist_ctx); + RND_DAD_END(drc_rlist_ctx.dlg); + + RND_DAD_BEGIN_VBOX(drc_rlist_ctx.dlg); /* right */ + RND_DAD_COMPFLAG(drc_rlist_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(drc_rlist_ctx.dlg); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Definition: "); + RND_DAD_LABEL(drc_rlist_ctx.dlg, ""); + drc_rlist_ctx.wdef = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_END(drc_rlist_ctx.dlg); + + RND_DAD_BEGIN_VBOX(drc_rlist_ctx.dlg); + RND_DAD_COMPFLAG(drc_rlist_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Type:"); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "-"); + drc_rlist_ctx.wdtype = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_LABEL(drc_rlist_ctx.dlg, ""); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Description:"); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "-"); + drc_rlist_ctx.wddesc = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_LABEL(drc_rlist_ctx.dlg, ""); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Default:"); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "-"); + drc_rlist_ctx.wdefault = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_LABEL(drc_rlist_ctx.dlg, ""); + RND_DAD_LABEL(drc_rlist_ctx.dlg, "Current value:"); + RND_DAD_BUTTON(drc_rlist_ctx.dlg, "-"); + drc_rlist_ctx.wvalue = RND_DAD_CURRENT(drc_rlist_ctx.dlg); + RND_DAD_CHANGE_CB(drc_rlist_ctx.dlg, dlist_btn_edit_cb); + RND_DAD_END(drc_rlist_ctx.dlg); + RND_DAD_END(drc_rlist_ctx.dlg); + + RND_DAD_END(drc_rlist_ctx.dlg); + +} + +static int pcb_dlg_drc_rlist(void) +{ + static const char *tabs[] = {"Rules", "Definitions", NULL}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + int wpaner, wpaned; + + if (drc_rlist_ctx.active) + return 0; /* do not open another */ + + + RND_DAD_BEGIN_VBOX(drc_rlist_ctx.dlg); + RND_DAD_COMPFLAG(drc_rlist_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(drc_rlist_ctx.dlg, tabs); + RND_DAD_COMPFLAG(drc_rlist_ctx.dlg, RND_HATF_EXPFILL); + pcb_dlg_drc_rlist_rules(&wpaner); + pcb_dlg_drc_rlist_defs(&wpaned); + RND_DAD_END(drc_rlist_ctx.dlg); + RND_DAD_BUTTON_CLOSES(drc_rlist_ctx.dlg, clbtn); + RND_DAD_END(drc_rlist_ctx.dlg); + + /* set up the context */ + drc_rlist_ctx.active = 1; + + RND_DAD_DEFSIZE(drc_rlist_ctx.dlg, 550, 400); + RND_DAD_NEW("drc_query_list", drc_rlist_ctx.dlg, "drc_query: list of rules", &drc_rlist_ctx, rnd_false, drc_rlist_close_cb); + RND_DAD_SET_VALUE(drc_rlist_ctx.dlg_hid_ctx, wpaner, dbl, 0.5); + RND_DAD_SET_VALUE(drc_rlist_ctx.dlg_hid_ctx, wpaned, dbl, 0.5); + drc_rlist_pcb2dlg(); + drc_dlist_pcb2dlg(); + return 0; +} + + +static const char pcb_acts_DrcQueryListRules[] = "DrcQueryListRules()\n"; +static const char pcb_acth_DrcQueryListRules[] = "List all drc rules implemented in drc_query"; +static fgw_error_t pcb_act_DrcQueryListRules(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + RND_ACT_IRES(pcb_dlg_drc_rlist()); + return 0; +} Index: tags/2.3.0/src_plugins/drc_query/drc_lht.c =================================================================== --- tags/2.3.0/src_plugins/drc_query/drc_lht.c (nonexistent) +++ tags/2.3.0/src_plugins/drc_query/drc_lht.c (revision 33253) @@ -0,0 +1,166 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +static int drc_query_lht_save_def(rnd_hidlib_t *hl, lht_node_t *ndefs, const char *def_id) +{ + lht_node_t *norig; + if (pcb_drc_query_def_by_name(def_id, &norig, 0) != 0) + return -1; + lht_dom_list_append(ndefs, lht_dom_duptree(norig)); + return 0; +} + +static int drc_query_lht_save_rule(rnd_hidlib_t *hl, const char *fn, const char *rule_id) +{ + htsi_t defs; + htsi_entry_t *e; + fgw_arg_t tmp; + lht_doc_t *doc; + lht_node_t *ndefs, *nrules, *norig; + int res = 0; + FILE *f; + + if (pcb_drc_query_get(hl, 1, rule_id, "query", &tmp) != 0) + return -1; + + f = rnd_fopen(hl, fn, "w"); + if (f == NULL) + return -1; + + doc = lht_dom_init(); + doc->root = lht_dom_node_alloc(LHT_LIST, "pcb-rnd-drc-query-v1"); + ndefs = lht_dom_node_alloc(LHT_LIST, "definitions"); + nrules = lht_dom_node_alloc(LHT_LIST, "rules"); + lht_dom_list_append(doc->root, ndefs); + lht_dom_list_append(doc->root, nrules); + + htsi_init(&defs, strhash, strkeyeq); + pcb_qry_extract_defs(&defs, tmp.val.str); + for(e = htsi_first(&defs); e != NULL; e = htsi_next(&defs, e)) { + if (drc_query_lht_save_def(hl, ndefs, e->key) != 0) + res = -1; + free(e->key); + } + htsi_uninit(&defs); + + if (pcb_drc_query_rule_by_name(rule_id, &norig, 0) == 0) { + lht_dom_list_append(nrules, lht_dom_duptree(norig)); + res = lht_dom_export(doc->root, f, ""); + } + else + res = -1; + + fclose(f); + lht_dom_uninit(doc); + + return res; +} + +static int reloc_children(lht_node_t *dst, lht_node_t *src) +{ + lht_dom_iterator_t it; + lht_node_t *nd; + int res = 0; + + if ((dst == NULL) || (dst->type != LHT_HASH) || (src == NULL) || (src->type != LHT_HASH)) + return -1; + + /* remove everything from dst */ + for(nd = lht_dom_first(&it, dst); nd != NULL; nd = lht_dom_next(&it)) + if (lht_tree_del(nd) != 0) + res = -1; + + /* move src nodes to dst */ + for(nd = lht_dom_first(&it, src); nd != NULL; nd = lht_dom_next(&it)) { + if (lht_tree_detach(nd) == 0) + lht_dom_hash_put(dst, nd); + else + res = -1; + } + + return res; +} + +static int drc_query_lht_load_rules(rnd_hidlib_t *hl, const char *fn) +{ + FILE *f; + lht_doc_t *doc; + lht_node_t *ndefs, *nrules, *nd, *dst; + int res = 0; + + f = rnd_fopen(hl, fn, "r"); + if (f == NULL) + return -1; + + doc = lht_dom_load_stream(f, fn, NULL); + fclose(f); + if (doc == NULL) + return -1; + + if ((doc->root->type != LHT_LIST) || (strcmp(doc->root->name, "pcb-rnd-drc-query-v1"))) + goto error; + + ndefs = doc->root->data.list.first; + if (ndefs == NULL) + goto error; + nrules = ndefs->next; + if (nrules == NULL) + goto error; + + if ((ndefs->type != LHT_LIST) || (strcmp(ndefs->name, "definitions"))) + goto error; + if ((nrules->type != LHT_LIST) || (strcmp(nrules->name, "rules"))) + goto error; + + for(nd = ndefs->data.list.first; nd != NULL; nd = nd->next) { + if (pcb_drc_query_def_by_name(nd->name, &dst, 1) == 0) { + if (reloc_children(dst, nd) != 0) + res = -1; + } + else + res = -1; + } + + for(nd = nrules->data.list.first; nd != NULL; nd = nd->next) { + if (pcb_drc_query_rule_by_name(nd->name, &dst, 1) == 0) { + if (reloc_children(dst, nd) != 0) + res = -1; + } + else + res = -1; + } + + return res; + + error:; + lht_dom_uninit(doc); + return -1; +} + Index: tags/2.3.0/src_plugins/drc_query/drc_query.c =================================================================== --- tags/2.3.0/src_plugins/drc_query/drc_query.c (nonexistent) +++ tags/2.3.0/src_plugins/drc_query/drc_query.c (revision 33253) @@ -0,0 +1,897 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "board.h" +#include "drc.h" +#include "view.h" +#include "conf_core.h" +#include "find.h" +#include "event.h" + +#include "drc_query_conf.h" +#include "../src_plugins/drc_query/conf_internal.c" +#include "../src_plugins/query/query.h" +#include "../src_plugins/query/query_exec.h" + + +static void drc_rlist_pcb2dlg(void); + +#include "drc_query_stat.c" + +static const char *drc_query_cookie = "drc_query"; + +extern conf_drc_query_t conf_drc_query; +#define DRC_QUERY_CONF_FN "drc_query.conf" + +#define DRC_CONF_PATH_PLUGIN "plugins/drc_query/" +#define DRC_CONF_PATH_DISABLE "design/drc_disable/" +#define DRC_CONF_PATH_CONST "design/drc/" +#define DRC_CONF_PATH_RULES "plugins/drc_query/rules/" +#define DRC_CONF_PATH_DEFS "plugins/drc_query/definitions/" + +typedef struct { + pcb_board_t *pcb; + pcb_view_list_t *lst; + const char *type; + const char *title; + const char *desc; + long hit_cnt; +} drc_qry_ctx_t; + +static fgw_arg_t load_obj_const(pcb_obj_qry_const_t *cnst) +{ + fgw_arg_t a; + + switch(cnst->val.type) { + case PCBQ_VT_COORD: + a.type = FGW_COORD; + fgw_coord(&a) = cnst->val.data.crd; + return a; + case PCBQ_VT_LONG: + a.type = FGW_LONG; + a.val.nat_long = cnst->val.data.lng; + return a; + case PCBQ_VT_DOUBLE: + a.type = FGW_DOUBLE; + a.val.nat_double = cnst->val.data.dbl; + return a; + + case PCBQ_VT_STRING: + a.type = FGW_STR | FGW_DYN; + a.val.str = rnd_strdup(cnst->val.data.str); + return a; + + case PCBQ_VT_VOID: + case PCBQ_VT_OBJ: + case PCBQ_VT_LST: + break; + } + + a.type = FGW_INVALID; + return a; +} + +void drc_qry_exec_cb(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current) +{ + drc_qry_ctx_t *qctx = user_ctx; + pcb_view_t *violation; + int bv; + + if (res->type == PCBQ_VT_COORD) + bv = res->data.crd != 0; + else if (res->type == PCBQ_VT_LONG) + bv = res->data.lng != 0; + else if (res->type == PCBQ_VT_LST) + bv = res->data.lst.used > 0; + else + return; + + if (!bv) + return; + + violation = pcb_view_new(&qctx->pcb->hidlib, qctx->type, qctx->title, qctx->desc); + if (res->type == PCBQ_VT_LST) { + int i; + fgw_arg_t *expv = NULL, expv_, *mesv = NULL, mesv_; + for(i = 0; i < res->data.lst.used-1; i+=2) { + pcb_any_obj_t *cmd = res->data.lst.array[i], *obj = res->data.lst.array[i+1]; + pcb_qry_drc_ctrl_t ctrl = pcb_qry_drc_ctrl_decode(cmd); + pcb_obj_qry_const_t *cnst = res->data.lst.array[i+1]; + + switch(ctrl) { + case PCB_QRY_DRC_GRP1: pcb_view_append_obj(violation, 0, obj); break; + case PCB_QRY_DRC_GRP2: pcb_view_append_obj(violation, 1, obj); break; + case PCB_QRY_DRC_EXPECT: expv = &expv_; expv_ = load_obj_const(cnst); break; + case PCB_QRY_DRC_MEASURE: mesv = &mesv_; mesv_ = load_obj_const(cnst); break; + case PCB_QRY_DRC_TEXT: pcb_view_append_text(violation, (char *)cnst); + case PCB_QRY_DRC_invalid: + break; + } + } + + if (expv != NULL) + pcb_drc_set_data(violation, mesv, *expv); + } + else + pcb_view_append_obj(violation, 0, (pcb_any_obj_t *)current); + pcb_view_set_bbox_by_objs(qctx->pcb->Data, violation); + pcb_view_list_append(qctx->lst, violation); + qctx->hit_cnt++; +} + +typedef struct { + const char *name; + long script_total, script_at; + void *dialog; + drc_qry_ctx_t *qctx; + unsigned cancel:1; +} drc_query_prog_t; + +static long drc_qry_exec(pcb_qry_exec_t *ec, pcb_board_t *pcb, pcb_view_list_t *lst, const char *name, const char *type, const char *title, const char *desc, const char *query) +{ + const char *scope = NULL; + drc_query_prog_t *prog = ec->progress_ctx; + drc_qry_ctx_t qctx; + pcb_drcq_stat_t *st; + double ts, te; + + if ((prog != 0) && (prog->cancel)) + return 0; + + if (query == NULL) { + rnd_message(RND_MSG_ERROR, "drc_query: igoring rule with no query string:%s\n", name); + return 0; + } + if (type == NULL) type = "DRC violation"; + if (title == NULL) title = "Unspecified error"; + if (desc == NULL) desc = "n/a"; + + qctx.pcb = pcb; + qctx.lst = lst; + qctx.type = type; + qctx.title = title; + qctx.desc = desc; + qctx.hit_cnt = 0; + if (prog != NULL) + prog->qctx = &qctx; + + st = pcb_drcq_stat_get(name); + + ts = rnd_dtime(); + pcb_qry_run_script(ec, pcb, query, scope, drc_qry_exec_cb, &qctx); + te = rnd_dtime(); + + st->last_run_time = te - ts; + st->sum_run_time += te - ts; + st->run_cnt++; + st->last_hit_cnt = qctx.hit_cnt; + st->sum_hit_cnt += qctx.hit_cnt; + if (prog != NULL) + prog->qctx = 0; + return 0; +} + +static const char *load_str(lht_node_t *rule, rnd_conf_listitem_t *i, const char *name) +{ + lht_node_t *n = lht_dom_hash_get(rule, name); + if (n == NULL) + return NULL; + if (n->type != LHT_TEXT) { + rnd_message(RND_MSG_ERROR, "drc_query: igoring non-text node %s of rule %s \n", name, i->name); + return NULL; + } + return n->data.text.value; +} + +static int *drc_get_disable(const char *name) +{ + char *path = rnd_concat(DRC_CONF_PATH_DISABLE, name, NULL); + rnd_conf_native_t *nat = rnd_conf_get_field(path); + free(path); + if ((nat == NULL) || (nat->type != RND_CFN_BOOLEAN)) + return NULL; + return nat->val.boolean; +} + + +static int drc_query_progress(pcb_qry_exec_t *ec, long at, long total); + +static void pcb_drc_query(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pcb_board_t *pcb = (pcb_board_t *)hidlib; + gdl_iterator_t it; + rnd_conf_listitem_t *i; + long cnt = 0; + int bufno = -1, *ran; + pcb_qry_exec_t ec; + drc_query_prog_t prog; + + if (conf_drc_query.plugins.drc_query.disable) + return; + + pcb_qry_init(&ec, pcb, NULL, bufno); + ec.progress_cb = drc_query_progress; + ec.progress_ctx = &prog; + + prog.script_total = rnd_conflist_length(&conf_drc_query.plugins.drc_query.rules); + prog.script_at = 0; + prog.dialog = NULL; + prog.cancel = 0; + + rnd_conflist_foreach(&conf_drc_query.plugins.drc_query.rules, &it, i) { + lht_node_t *rule = i->prop.src; + int *dis; + if (rule->type != LHT_HASH) { + rnd_message(RND_MSG_ERROR, "drc_query: rule %s is not a hash\n", i->name); + continue; + } + + dis = drc_get_disable(i->name); + if ((dis != NULL) && (*dis != 0)) + continue; + + assert(argv[1].type == RND_EVARG_PTR); + ran = argv[1].d.p; + (*ran)++; + + prog.name = i->name; + cnt += drc_qry_exec(&ec, pcb, &pcb_drc_lst, i->name, + load_str(rule, i, "type"), load_str(rule, i, "title"), load_str(rule, i, "desc"), + load_str(rule, i, "query") + ); + prog.script_at++; + } + + drc_query_progress(&ec, -1, -1); + + pcb_qry_uninit(&ec); + drc_rlist_pcb2dlg(); /* for the run time */ +} + +static vtp0_t free_drc_conf_nodes; +static rnd_conf_native_t *nat_defs = NULL; +static rnd_conf_native_t *nat_rules = NULL; +static void drc_query_newconf(rnd_conf_native_t *cfg, rnd_conf_listitem_t *i) +{ + if (nat_rules == NULL) { + if (strncmp(cfg->hash_path, DRC_CONF_PATH_RULES, strlen(DRC_CONF_PATH_RULES)-1) == 0) { + nat_rules = cfg; + nat_rules->gui_edit_act = "DrcQueryEditRule"; + } + } + + if (nat_defs == NULL) { + if (strncmp(cfg->hash_path, DRC_CONF_PATH_DEFS, strlen(DRC_CONF_PATH_DEFS)-1) != 0) + return; + nat_defs = cfg; + } + + if (nat_rules == cfg) { + lht_node_t *nd = i->prop.src; + char *path = rnd_concat(DRC_CONF_PATH_DISABLE, nd->name, NULL); + + if (rnd_conf_get_field(path) == NULL) { + const char *sdesc; + rnd_conf_native_t *nat; + rnd_bool_t *b; + lht_node_t *ndesc; + + ndesc = lht_dom_hash_get(nd, "desc"); + if ((ndesc != NULL) && (ndesc->type == LHT_TEXT)) sdesc = ndesc->data.text.value; + + b = calloc(sizeof(rnd_bool_t), 1); + nat = rnd_conf_reg_field_(b, 1, RND_CFN_BOOLEAN, path, rnd_strdup(sdesc), 0); + if (nat == NULL) { + free(b); + rnd_message(RND_MSG_ERROR, "drc_query: failed to register conf node '%s'\n", path); + goto fail; + } + + nat->random_flags.dyn_hash_path = 1; + nat->random_flags.dyn_desc = 1; + nat->random_flags.dyn_val = 1; + vtp0_append(&free_drc_conf_nodes, nat); + rnd_conf_set(RND_CFR_INTERNAL, path, -1, "0", RND_POL_OVERWRITE); + } + else + free(path); + } + else if (nat_defs == cfg) { + lht_node_t *nd = i->prop.src; + char *path = rnd_concat(DRC_CONF_PATH_CONST, nd->name, NULL); + rnd_coord_t *c; + rnd_conf_native_t *nat = rnd_conf_get_field(path); + + if ((nat == NULL) || (nat->used == 0)) { /* create the definition and set default value (but only once) */ + union { + rnd_coord_t c; + double d; + void *ptr; + char *str; + } anyval; + lht_node_t *ndesc = lht_dom_hash_get(nd, "desc"); + lht_node_t *ntype = lht_dom_hash_get(nd, "type"); + lht_node_t *ndefault = lht_dom_hash_get(nd, "default"); + lht_node_t *nlegacy = lht_dom_hash_get(nd, "legacy"); + const char *sdesc = "n/a", *stype = NULL, *sdefault = NULL, *slegacy = NULL; + rnd_conf_native_type_t type; + int pathfree = 1; + + if ((ndesc != NULL) && (ndesc->type == LHT_TEXT)) sdesc = ndesc->data.text.value; + if ((ntype != NULL) && (ntype->type == LHT_TEXT)) stype = ntype->data.text.value; + if ((ndefault != NULL) && (ndefault->type == LHT_TEXT)) sdefault = ndefault->data.text.value; + if ((nlegacy != NULL) && (nlegacy->type == LHT_TEXT)) slegacy = nlegacy->data.text.value; + + if (stype == NULL) { + if ((ndesc != NULL) || (sdefault != NULL)) + rnd_message(RND_MSG_ERROR, "drc_query: missing type field for constant %s\n", nd->name); + goto fail; + } + + type = rnd_conf_native_type_parse(stype); + if (type >= RND_CFN_LIST) { + rnd_message(RND_MSG_ERROR, "drc_query: invalid type '%s' for %s\n", stype, nd->name); + goto fail; + } + + /* create the new conf node for the def if it doesn't already exist */ + if (nat == NULL) { + c = calloc(sizeof(anyval), 1); + pathfree = 0; + nat = rnd_conf_reg_field_(c, 1, type, path, rnd_strdup(sdesc), 0); + if (nat == NULL) { + free(c); + rnd_message(RND_MSG_ERROR, "drc_query: failed to register conf node '%s'\n", path); + goto fail; + } + + nat->random_flags.dyn_hash_path = 1; + nat->random_flags.dyn_desc = 1; + nat->random_flags.dyn_val = 1; + vtp0_append(&free_drc_conf_nodes, nat); + } + + /* set default value */ + if (slegacy != NULL) + pcb_conf_legacy(path, slegacy); + else if (sdefault != NULL) + rnd_conf_set(RND_CFR_INTERNAL, path, -1, sdefault, RND_POL_OVERWRITE); + if (!pathfree) + path = NULL; /* hash key shall not be free'd */ + } + fail:; + free(path); + } +} + +static const char *textval_empty(lht_node_t *nd, const char *fname) +{ + lht_node_t *nt = lht_dom_hash_get(nd, fname); + + if ((nt == NULL) || (nt->type != LHT_TEXT)) + return ""; + + return nt->data.text.value; +} + +static const char *textval_null(lht_node_t *nd, const char *fname) +{ + lht_node_t *nt = lht_dom_hash_get(nd, fname); + + if ((nt == NULL) || (nt->type != LHT_TEXT)) + return NULL; + + return nt->data.text.value; +} + +#define MKDIR_ND(outnode, parent, ntype, nname, errinstr) \ +do { \ + lht_node_t *nnew; \ + lht_err_t err; \ + char *nname0 = (char *)nname; \ + if (parent->type == LHT_LIST) nname0 = rnd_concat(nname, ":0", NULL); \ + nnew = lht_tree_path_(parent->doc, parent, nname0, 1, 1, &err); \ + if (parent->type == LHT_LIST) free(nname0); \ + if ((nnew != NULL) && (nnew->type != ntype)) { \ + rnd_message(RND_MSG_ERROR, "Internal error: invalid existing node type for %s: %d, rule is NOT saved\n", nname, nnew->type); \ + errinstr; \ + } \ + else if (nnew == NULL) { \ + nnew = lht_dom_node_alloc(ntype, nname); \ + switch(parent->type) { \ + case LHT_HASH: err = lht_dom_hash_put(parent, nnew); break; \ + case LHT_LIST: err = lht_dom_list_append(parent, nnew); break; \ + default: \ + rnd_message(RND_MSG_ERROR, "Internal error: invalid parent node type for %s: %d, rule is NOT saved\n", parent->name, parent->type); \ + errinstr; \ + } \ + } \ + outnode = nnew; \ +} while(0) + +#define MKDIR_ND_SET_TEXT(parent, nname, nval, errinstr) \ +do { \ + lht_node_t *ntxt; \ + MKDIR_ND(ntxt, parent, LHT_TEXT, nname, errinstr); \ + if (ntxt == NULL) { \ + rnd_message(RND_MSG_ERROR, "Internal error: new text node for %s is NULL, rule is NOT saved\n", nname); \ + errinstr; \ + } \ + free(ntxt->data.text.value); \ + ntxt->data.text.value = rnd_strdup(nval == NULL ? "" : nval); \ +} while(0) + +#define MKDIR_RULES(nd, errinstr) \ +do { \ + MKDIR_ND(nd, nd, LHT_HASH, "plugins", errinstr); \ + MKDIR_ND(nd, nd, LHT_HASH, "drc_query", errinstr); \ + MKDIR_ND(nd, nd, LHT_LIST, "rules", errinstr); \ +} while(0) + +#define MKDIR_CONSTS(nd, errinstr) \ +do { \ + MKDIR_ND(nd, nd, LHT_HASH, "plugins", errinstr); \ + MKDIR_ND(nd, nd, LHT_HASH, "drc_query", errinstr); \ + MKDIR_ND(nd, nd, LHT_LIST, "definitions", errinstr); \ +} while(0) + +#define MKDIR_RULE_ROOT(nd, role, pol, errinst) \ +do { \ + nd = rnd_conf_lht_get_first_crpol(role, pol, 1); \ + if (nd == NULL) { \ + rnd_message(RND_MSG_ERROR, "Internal error: failed to create role root, rule is NOT saved\n"); \ + errinst; \ + } \ +} while(0) + +#define DRC_QUERY_RULE_OR_DEF(is_rule) \ + ((is_rule) ? &conf_drc_query.plugins.drc_query.rules : &conf_drc_query.plugins.drc_query.definitions) + +static int pcb_drc_query_any_by_name(const char *name, int is_rule, lht_node_t **nd_out, int do_create) +{ + lht_node_t *n = NULL, *nd = NULL; + int ret = -1, needs_update = 0; + const rnd_conflist_t *l = DRC_QUERY_RULE_OR_DEF(is_rule); + gdl_iterator_t it; + rnd_conf_listitem_t *i; + + rnd_conflist_foreach(l, &it, i) { + n = i->prop.src; + if ((n != NULL) && (strcmp(n->name, name) == 0)) { + nd = n; + break; + } + } + + if (!do_create) { + if (nd != NULL) + ret = 0; + } + else { + if (nd == NULL) { /* allocate new node */ + ret = 0; + MKDIR_RULE_ROOT(nd, RND_CFR_DESIGN, RND_POL_APPEND, goto skip); + if (is_rule) + MKDIR_RULES(nd, goto skip); + else + MKDIR_CONSTS(nd, goto skip); + MKDIR_ND(nd, nd, LHT_HASH, name, goto skip); + if (nd == NULL) /* failed to create */ + ret = -1; + else + needs_update = 1; + } + else { /* failed to allocate because it exists: return error, but also set the output */ + ret = -1; + } + } + + if (needs_update) + rnd_conf_update(NULL, -1); + + skip:; + if (nd_out != NULL) + *nd_out = nd; + + return ret; +} + +static int pcb_drc_query_rule_by_name(const char *name, lht_node_t **nd_out, int do_create) +{ + return pcb_drc_query_any_by_name(name, 1, nd_out, do_create); +} + +static int pcb_drc_query_def_by_name(const char *name, lht_node_t **nd_out, int do_create) +{ + return pcb_drc_query_any_by_name(name, 0, nd_out, do_create); +} + + +static int pcb_drc_query_clear(rnd_hidlib_t *hidlib, int is_rule, const char *src) +{ + const rnd_conflist_t *l = DRC_QUERY_RULE_OR_DEF(is_rule); + gdl_iterator_t it; + rnd_conf_listitem_t *i; + int needs_update = 0; + + rnd_conflist_foreach(l, &it, i) { + const char *nsrc; + lht_node_t *n = i->prop.src; + if (n == NULL) + continue; + nsrc = textval_null(n, "src"); + if (nsrc == NULL) + continue; + if (strcmp(nsrc, src) == 0) { + needs_update = 1; + i->prop.src = NULL; + lht_tree_del(n); + } + } + + if (needs_update) + rnd_conf_update(NULL, -1); + + return -1; +} + +static int pcb_drc_query_create(rnd_hidlib_t *hidlib, int is_rule, const char *rule) +{ + lht_node_t *nd; + + if (pcb_drc_query_any_by_name(rule, is_rule, &nd, 1) != 0) + return -1; /* do not re-create existing rule, force creating a new */ + + return 0; +} + +void d2() {} + +static int pcb_drc_query_set(rnd_hidlib_t *hidlib, int is_rule, const char *rule, const char *key, const char *val) +{ + lht_node_t *nd; + + if (pcb_drc_query_any_by_name(rule, is_rule, &nd, 0) != 0) + return -1; + + MKDIR_ND_SET_TEXT(nd, key, val, return -1); + + /* copy default value when set in a separate step, after node creation */ + if (!is_rule && (nat_defs != NULL)) { + char *path = rnd_concat(DRC_CONF_PATH_CONST, nd->name, NULL); + rnd_conf_native_t *nat = rnd_conf_get_field(path); + + /* set value only if it's a new node, so existing value is not overwritten */ + if ((nat == NULL) || (nat->used == 0)) { + rnd_conf_listitem_t i = {0}; + i.prop.src = nd; + drc_query_newconf(nat_defs, &i); + } + free(path); + } + + return 0; +} + +static int pcb_drc_query_get(rnd_hidlib_t *hidlib, int is_rule, const char *rule, const char *key, fgw_arg_t *res) +{ + lht_node_t *nd; + + if (pcb_drc_query_any_by_name(rule, is_rule, &nd, 0) != 0) + return -1; + + res->type = FGW_STR; + res->val.cstr = textval_empty(nd, key); + + return 0; +} + +static int pcb_drc_query_get_rule_defs(rnd_hidlib_t *hidlib, const char *rule, fgw_arg_t *res) +{ + htsi_t defs; + htsi_entry_t *e; + gds_t lst; + fgw_arg_t tmp; + if (pcb_drc_query_get(hidlib, 1, rule, "query", &tmp) != 0) + return -1; + + gds_init(&lst); + htsi_init(&defs, strhash, strkeyeq); + pcb_qry_extract_defs(&defs, tmp.val.str); + for(e = htsi_first(&defs); e != NULL; e = htsi_next(&defs, e)) { + if (lst.used > 0) + gds_append(&lst, '\n'); + gds_append_str(&lst, e->key); + free(e->key); + } + htsi_uninit(&defs); + + if (lst.used == 0) { + gds_uninit(&lst); + res->type = FGW_STR; + res->val.cstr = ""; + return 0; + } + + res->type = FGW_STR | FGW_DYN; + res->val.str = lst.array; + return 0; +} + + +static const char pcb_acts_DrcQueryRuleMod[] = \ + "DrcQueryRuleMod(clear, source)\n" + "DrcQueryRuleMod(create, rule_name)\n" + "DrcQueryRuleMod(get, rule_name, field_name)\n" + "DrcQueryRuleMod(set, rule_name, field_name, value)\n"; +static const char pcb_acth_DrcQueryRuleMod[] = "Automated DRC rule editing (for scripting and import)"; +static fgw_error_t pcb_act_DrcQueryRuleMod(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd, *target, *key = NULL, *val=NULL; + rnd_hidlib_t *hl = RND_ACT_HIDLIB; + int resi = -1; + + RND_ACT_CONVARG(1, FGW_STR, DrcQueryRuleMod, cmd = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, DrcQueryRuleMod, target = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, DrcQueryRuleMod, key = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, DrcQueryRuleMod, val = argv[4].val.str); + + if (strcmp(cmd, "clear") == 0) resi = pcb_drc_query_clear(hl, 1, target); + else if (strcmp(cmd, "create") == 0) resi = pcb_drc_query_create(hl, 1, target); + else if (strcmp(cmd, "set") == 0) resi = pcb_drc_query_set(hl, 1, target, key, val); + else if (strcmp(cmd, "get") == 0) { + if (strcmp(key, "defs") == 0) + return pcb_drc_query_get_rule_defs(hl, target, res); + else + return pcb_drc_query_get(hl, 1, target, key, res); + } + else + RND_ACT_FAIL(DrcQueryRuleMod); + + RND_ACT_IRES(resi); + return 0; +} + +static const char pcb_acts_DrcQueryDefMod[] = \ + "DrcQueryDefMod(clear, source)\n" + "DrcQueryDefMod(create, rule_name)\n" + "DrcQueryDefMod(get, rule_name, field_name)\n" + "DrcQueryDefMod(set, rule_name, field_name, value)\n"; +static const char pcb_acth_DrcQueryDefMod[] = "Automated DRC rule editing (for scripting and import)"; +static fgw_error_t pcb_act_DrcQueryDefMod(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd, *target, *key = NULL, *val=NULL; + rnd_hidlib_t *hl = RND_ACT_HIDLIB; + int resi = -1; + + RND_ACT_CONVARG(1, FGW_STR, DrcQueryDefMod, cmd = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, DrcQueryDefMod, target = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, DrcQueryDefMod, key = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, DrcQueryDefMod, val = argv[4].val.str); + + if (strcmp(cmd, "clear") == 0) resi = pcb_drc_query_clear(hl, 0, target); + else if (strcmp(cmd, "create") == 0) resi = pcb_drc_query_create(hl, 0, target); + else if (strcmp(cmd, "set") == 0) resi = pcb_drc_query_set(hl, 0, target, key, val); + else if (strcmp(cmd, "get") == 0) return pcb_drc_query_get(hl, 0, target, key, res); + else + RND_ACT_FAIL(DrcQueryDefMod); + + RND_ACT_IRES(resi); + return 0; +} + +#include "drc_lht.c" + +static const rnd_hid_fsd_filter_t *init_flt(const char **fmt) +{ + static const char *pat_tdx[] = {"*.tdx", NULL}; + static const char *pat_lht[] = {"*.lht", NULL}; + static const rnd_hid_fsd_filter_t flt[] = { + {"tEDAx", "tEDAx", pat_tdx}, + {"lihata", "lihata", pat_lht}, + {NULL, NULL, NULL} + }; + + *fmt = "tEDAx"; + return flt; +} + +static const char pcb_acts_DrcQueryExport[] = "DrcQueryExport(ruleID, [filename], [format])\n"; +static const char pcb_acth_DrcQueryExport[] = "Export a rule and related definitions to a file."; +static fgw_error_t pcb_act_DrcQueryExport(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int ires = 0; + const char *id, *fn = NULL, *fmt; + char *autofree = NULL; + rnd_hidlib_t *hl = RND_ACT_HIDLIB; + const rnd_hid_fsd_filter_t *flt = init_flt(&fmt); + + RND_ACT_CONVARG(1, FGW_STR, DrcQueryExport, id = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, DrcQueryExport, fn = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, DrcQueryExport, fmt = argv[3].val.str); + + if (fn == NULL) { + const char *ext = ".tdx", *sep; + char *fnid = rnd_concat(id, ext, NULL); +TODO("cleanup: fix format selection: generalize dlg_loadsave.c's subfmt code"); + fn = autofree = rnd_gui->fileselect(rnd_gui, "drc_query_rule", "Export a drc_query rule and related definitions", + fnid, ext, flt, "drc_query", 0, NULL); + free(fnid); + if (fn == NULL) + return -1; + + sep = strrchr(fn, '.'); + if (sep != NULL) { + sep++; + switch(*sep) { + case 't': case 'T': fmt = "tEDAx"; break; + case 'l': case 'L': fmt = "lihata"; break; + } + } + } + + switch(*fmt) { + case 't': case 'T': ires = rnd_actionva(hl, "savetedax", "drc_query", fn, id, NULL); break; + case 'l': case 'L': ires = drc_query_lht_save_rule(hl, fn, id); break; + default: rnd_message(RND_MSG_ERROR, "Can not save in format '%s'\n", fmt); ires = -1; break; + } + + free(autofree); + RND_ACT_IRES(ires); + return 0; +} + +static const char pcb_acts_DrcQueryImport[] = "DrcQueryImport([filename])\n"; +static const char pcb_acth_DrcQueryImport[] = "Import a rule and related definitions from a file."; +static fgw_error_t pcb_act_DrcQueryImport(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int ires = 0; + const char *fn = NULL, *fmt; + char *autofree = NULL; + rnd_hidlib_t *hl = RND_ACT_HIDLIB; + FILE *f; + fgw_arg_t args[2], tpres; + const rnd_hid_fsd_filter_t *flt = init_flt(&fmt); + + RND_ACT_MAY_CONVARG(1, FGW_STR, DrcQueryExport, fn = argv[1].val.str); + + if (fn == NULL) { + const char *ext = ".tdx"; + fn = autofree = rnd_gui->fileselect(rnd_gui, "drc_query_rule", "Import a drc_query rule and related definitions", + NULL, ext, flt, "drc_query", RND_HID_FSD_READ, NULL); + if (fn == NULL) + return -1; + } + + + /* figure the format and load */ + f = rnd_fopen(hl, fn, "r"); + if (f == NULL) + return -1; + + fgw_ptr_reg(&rnd_fgw, &args[1], RND_PTR_DOMAIN_FILE_PTR, FGW_PTR | FGW_STRUCT, f); + + if ((rnd_actionv_bin(hl, "tedaxtestparse", &tpres, 2, args) == 0) && (tpres.type == FGW_INT) && (tpres.val.nat_int == 1)) { + ires = rnd_actionva(hl, "loadtedaxfrom", "drc_query", fn, "", "0", NULL); + goto done; + } + + /* To check another format: rewind(f) and repeat the above if() */ + + /* fallback: io_lihata */ + ires = drc_query_lht_load_rules(hl, fn); + + done:; + fgw_ptr_unreg(&rnd_fgw, &args[1], RND_PTR_DOMAIN_FILE_PTR); + fclose(f); + + if (ires == 0) + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + + free(autofree); + RND_ACT_IRES(ires); + return 0; +} + +#include "dlg.c" + +static pcb_drc_impl_t drc_query_impl = {"drc_query", "query() based DRC", "drcquerylistrules"}; + +static rnd_action_t drc_query_action_list[] = { + {"DrcQueryListRules", pcb_act_DrcQueryListRules, pcb_acth_DrcQueryListRules, pcb_acts_DrcQueryListRules}, + {"DrcQueryEditRule", pcb_act_DrcQueryEditRule, pcb_acth_DrcQueryEditRule, pcb_acts_DrcQueryEditRule}, + {"DrcQueryRuleMod", pcb_act_DrcQueryRuleMod, pcb_acth_DrcQueryRuleMod, pcb_acts_DrcQueryRuleMod}, + {"DrcQueryDefMod", pcb_act_DrcQueryDefMod, pcb_acth_DrcQueryDefMod, pcb_acts_DrcQueryDefMod}, + {"DrcQueryExport", pcb_act_DrcQueryExport, pcb_acth_DrcQueryExport, pcb_acts_DrcQueryExport}, + {"DrcQueryImport", pcb_act_DrcQueryImport, pcb_acth_DrcQueryImport, pcb_acts_DrcQueryImport} +}; + +int pplg_check_ver_drc_query(int ver_needed) { return 0; } + +void pplg_uninit_drc_query(void) +{ + long n; + + pcb_drc_impl_unreg(&drc_query_impl); + rnd_event_unbind_allcookie(drc_query_cookie); + rnd_conf_unreg_file(DRC_QUERY_CONF_FN, drc_query_conf_internal); + rnd_conf_unreg_fields(DRC_CONF_PATH_PLUGIN); + rnd_conf_hid_unreg(drc_query_cookie); + + for(n = 0; n < free_drc_conf_nodes.used; n++) + rnd_conf_unreg_field(free_drc_conf_nodes.array[n]); + vtp0_uninit(&free_drc_conf_nodes); + + rnd_remove_actions_by_cookie(drc_query_cookie); + pcb_drcq_stat_uninit(); +} + +static rnd_conf_hid_callbacks_t cbs; + +int pplg_init_drc_query(void) +{ + RND_API_CHK_VER; + + pcb_drcq_stat_init(); + + rnd_event_bind(PCB_EVENT_DRC_RUN, pcb_drc_query, NULL, drc_query_cookie); + + vtp0_init(&free_drc_conf_nodes); + cbs.new_hlist_item_post = drc_query_newconf; + rnd_conf_hid_reg(drc_query_cookie, &cbs); + + rnd_conf_reg_file(DRC_QUERY_CONF_FN, drc_query_conf_internal); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_drc_query, field,isarray,type_name,cpath,cname,desc,flags); +#include "drc_query_conf_fields.h" + + RND_REGISTER_ACTIONS(drc_query_action_list, drc_query_cookie) + pcb_drc_impl_reg(&drc_query_impl); + + return 0; +} + + +conf_drc_query_t conf_drc_query; Index: tags/2.3.0/src_plugins/drc_query/drc_query.conf =================================================================== --- tags/2.3.0/src_plugins/drc_query/drc_query.conf (nonexistent) +++ tags/2.3.0/src_plugins/drc_query/drc_query.conf (revision 33253) @@ -0,0 +1,149 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:drc_query { + disable=0 + + li:definitions { + ha:min_copper_clearance { + type = coord + legacy = design/bloat + desc = {minimum gap between copper features of different networks} + } + ha:min_copper_overlap { + type = coord + legacy = design/shrink + desc = {minimum overlap between copper features on the same network for reliable connection} + } + ha:min_drill { + type = coord + legacy = design/min_drill + desc = {minimum drill diameter} + } + ha:hole_overlap_factor { + type = real + default = 0.0 + desc = {How much drilled holes may overlap [-1..+1]; 0 means touching holes are reported; positive numbers allow more overlap, negative numbers report non-overlapping but close holes} + } + + ha:min_copper_thickness { + type = coord + default = 0mm + legacy = design/min_wid + desc = {Minimum copper object width; anything thinner than this value is a violation} + } + + ha:min_silk_thickness { + type = coord + default = 0mm + legacy = design/min_slk + desc = {Minimum silk object width; anything thinner than this value is a violation} + } + + + ha:min_ring { + type = coord + default = 0mm + legacy = design/min_ring + desc = {Minimum ring thickness of padstacks } + } + } + + li:rules { + + ha:hole_dia { + type = single hole + title = hole too small + desc = padstack hole diameter is too small + query = {(@.hole > 0) && (@.hole < $min_drill) thus violation(DRCGRP1, @, DRCMEASURE, @.hole, DRCEXPECT, $min_drill)} + } + + ha:hole_overlap { + type = pair hole + title = overlapping holes + desc = padstack holes overlap + query = { +rule overlap +let A @.type==PSTK +let B A +assert (A.IID > B.IID) && (distance(A.x, A.y, B.x, B.y) < (A.hole + B.hole)/(2*(1+$hole_overlap_factor))) thus violation(DRCGRP1, A, DRCGRP2, B, DRCMEASURE, coord(distance(A.x, A.y, B.x, B.y)), DRCEXPECT, coord((A.hole + B.hole)/(2*(1+$hole_overlap_factor)))) + } + } + + ha:net_break { + type = broken net + title = insufficient overlap + desc = the overlap between two objects in the net is insufficient and can lead to broken network during board fabrication + query = { +rule net brk +let N netlist() +let O netsegs(N) +assert netbreak(O, $min_copper_overlap) + } + } + + ha:net_short { + type = shorted nets + title = net too close to other net + desc = insufficient clearance between an object of the network and objects of other networks + query = { +rule net short +let N netlist() +let O netsegs(N) +assert netshort(O, $min_copper_clearance) + } + } + + ha:min_copper_thickness { + type = thin copper + title = copper object too thin + desc = Copper object thickness is below the required value. Copper objects too thin may break or peel off during board fabriaction. + query = {(@.layer.type == COPPER) && (@.thickness != 0) && (@.thickness < $min_copper_thickness) thus violation(DRCGRP1, @, DRCMEASURE, @.thickness, DRCEXPECT, $min_copper_thickness)} + } + + ha:min_silk_thickness { + type = thin silk + title = silk object too thin + desc = Silk object thickness is below the required value. Silk objects too thin may disappear during board fabrication. + query = {(@.layer.type == SILK) && (@.thickness != 0) && (@.thickness < $min_silk_thickness) thus violation(DRCGRP1, @, DRCMEASURE, @.thickness, DRCEXPECT, $min_silk_thickness) } + } + + ha:beyond_drawing_area { + type = object beyond drawing area + title = Objects located outside of the drawing area + desc = Objects may be omitted from exports or may be outside of the board contour. + query = { (@.bbox.x2 < 0) || (@.bbox.y2 < 0) || (@.bbox.x1 > $dwg_area_x) || (@.bbox.y1 > $dwg_area_y) } + } + + ha:min_ring { + type = padstack ring too thin + title = Ring of a padstack object is too thin + desc = The smallest neck of the ring is thinner than the required value - the ring may break during drilling or erode away during etching. + query = { pstkring(@, $min_ring) > 0 } + } + + ha:fullpoly { + type = fullpoly + title = Multi-island polygon with the fullpoly flag + desc = Polygon with the fullpoly flag set is cut into multiple islands; there is no guarantee that the islands are connected while pcb-rnd will always think they are, fooling the drc and rats optimizer. + query = { poly_num_islands(@) > 1 } + } + + ha:ko_named { + type = courtyard + title = Courtyard conflict + desc = Courtyard objects overlap + query = { +rule courtyard +let A (@.layer.purpose ~ "^ko.") thus @ +let B A +assert (A != B) && (A.IID <= B.IID) && (A.layer.position == B.layer.position) && (A.layer.purpose == B.layer.purpose) && (overlap(A, B)) \\ + thus violation(DRCGRP1, A, DRCGRP2, B, DRCTEXT, "On keepout type ", DRCTEXT, A.layer.purpose, DRCTEXT, " ", DRCTEXT, A.layer.a.drc_desc) +} + } + + } + } + } + } +} Index: tags/2.3.0/src_plugins/drc_query/drc_query.pup =================================================================== --- tags/2.3.0/src_plugins/drc_query/drc_query.pup (nonexistent) +++ tags/2.3.0/src_plugins/drc_query/drc_query.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short query() based DRC +$long Scriptable DRC based on query() +$package (core) +default buildin +dep query +autoload 1 Index: tags/2.3.0/src_plugins/drc_query/drc_query_conf.h =================================================================== --- tags/2.3.0/src_plugins/drc_query/drc_query_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/drc_query/drc_query_conf.h (revision 33253) @@ -0,0 +1,16 @@ +#ifndef PCB_DRC_QUERY_CONF_H +#define PCB_DRC_QUERY_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN disable; /* disable the whole engine */ + RND_CFT_HLIST definitions; /* DRC constant definitions */ + RND_CFT_HLIST rules; /* inline rules */ + } drc_query; + } plugins; +} conf_drc_query_t; + +#endif Index: tags/2.3.0/src_plugins/drc_query/drc_query_stat.c =================================================================== --- tags/2.3.0/src_plugins/drc_query/drc_query_stat.c (nonexistent) +++ tags/2.3.0/src_plugins/drc_query/drc_query_stat.c (revision 33253) @@ -0,0 +1,39 @@ +typedef struct { + const char *name; + double last_run_time; + double sum_run_time; + long run_cnt; + long last_hit_cnt; + long sum_hit_cnt; +} pcb_drcq_stat_t; + +static htsp_t pcb_drcq_stat; + +static void pcb_drcq_stat_init(void) +{ + htsp_init(&pcb_drcq_stat, strhash, strkeyeq); +} + +static void pcb_drcq_stat_uninit(void) +{ + htsp_entry_t *e; + for(e = htsp_first(&pcb_drcq_stat); e != NULL; e = htsp_next(&pcb_drcq_stat, e)) { + pcb_drcq_stat_t *st = e->value; + free((char *)st->name); + free(st); + } + htsp_uninit(&pcb_drcq_stat); +} + +static pcb_drcq_stat_t *pcb_drcq_stat_get(const char *name) +{ + pcb_drcq_stat_t *st = htsp_get(&pcb_drcq_stat, name); + + if (st != NULL) + return st; + + st = calloc(sizeof(pcb_drcq_stat_t), 1); + st->name = rnd_strdup(name); + htsp_set(&pcb_drcq_stat, (char *)st->name, st); + return st; +} Index: tags/2.3.0/src_plugins/expfeat/Makefile =================================================================== --- tags/2.3.0/src_plugins/expfeat/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/expfeat/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_expfeat + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/expfeat/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/expfeat/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/expfeat/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {expfeat} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/expfeat/expfeat.o @] + +switch /local/pcb/expfeat/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/expfeat/expfeat.c =================================================================== --- tags/2.3.0/src_plugins/expfeat/expfeat.c (nonexistent) +++ tags/2.3.0/src_plugins/expfeat/expfeat.c (revision 33253) @@ -0,0 +1,68 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include "data.h" +#include "change.h" +#include +#include "undo.h" +#include +#include + + +static const char pcb_acts_ExpFeatTmp[] = "ExpFeatTmp(...)"; +static const char pcb_acth_ExpFeatTmp[] = "Experimental Feature Template."; +/* DOC: foobar.html */ +/* (change the name of the above reference to the lowercase version of + your action name and create the document in + doc/user/09_appendix/action_src/) */ +static fgw_error_t pcb_act_ExpFeatTmp(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_INFO, "Hello world from expfeat!\n"); + RND_ACT_IRES(0); + return 0; +} + +static const rnd_action_t expfeat_action_list[] = { + {"ExpFeatTmp", pcb_act_ExpFeatTmp, pcb_acth_ExpFeatTmp, pcb_acts_ExpFeatTmp} +}; + +static const char *expfeat_cookie = "experimental features plugin"; + +int pplg_check_ver_expfeat(int ver_needed) { return 0; } + +void pplg_uninit_expfeat(void) +{ + rnd_remove_actions_by_cookie(expfeat_cookie); +} + +int pplg_init_expfeat(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(expfeat_action_list, expfeat_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/expfeat/expfeat.pup =================================================================== --- tags/2.3.0/src_plugins/expfeat/expfeat.pup (nonexistent) +++ tags/2.3.0/src_plugins/expfeat/expfeat.pup (revision 33253) @@ -0,0 +1,6 @@ +$class feature +$short experimental features +$long Staging plugin for experimenting with new actions and dialogs before getting them into core or other plugins +$state works +default disable +autoload 1 Index: tags/2.3.0/src_plugins/export_bom/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_bom/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_bom/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_bom + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_bom/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_bom/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_bom/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {export_bom} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_bom/bom.o @] + +switch /local/pcb/export_bom/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_bom/bom.c =================================================================== --- tags/2.3.0/src_plugins/export_bom/bom.c (nonexistent) +++ tags/2.3.0/src_plugins/export_bom/bom.c (revision 33253) @@ -0,0 +1,292 @@ +/* Print bill of materials file is which can be used for checking stock + and purchasing needed materials. */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include + +#include + +#include "build_run.h" +#include "board.h" +#include "data.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include "hid_cam.h" +#include + +const char *bom_cookie = "bom HID"; + +static rnd_export_opt_t bom_options[] = { +/* %start-doc options "8 BOM Creation" +@ftable @code +@item --bomfile +Name of the BOM output file. +@end ftable +%end-doc +*/ + {"bomfile", "Name of the BOM output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_bomfile 0 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 1 + +}; + +#define NUM_OPTIONS (sizeof(bom_options)/sizeof(bom_options[0])) + +static rnd_hid_attr_val_t bom_values[NUM_OPTIONS]; + +static const char *bom_filename; + +typedef struct pcb_bom_list_s { + char *descr; + char *value; + int num; + vts0_t refdes; + struct pcb_bom_list_s *next; +} pcb_bom_list_t; + +static rnd_export_opt_t *bom_get_export_options(rnd_hid_t *hid, int *n) +{ + if ((PCB != NULL) && (bom_options[HA_bomfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &bom_options[HA_bomfile], ".bom"); + + if (n) + *n = NUM_OPTIONS; + return bom_options; +} + +char *pcb_bom_clean_str(const char *in) +{ + char *out; + int i; + + if ((out = malloc((strlen(in) + 1) * sizeof(char))) == NULL) { + fprintf(stderr, "Error: pcb_bom_clean_str() malloc() failed\n"); + exit(1); + } + + /* copy over in to out with some character conversions. + Go all the way to then end to get the terminating \0 */ + for (i = 0; i <= strlen(in); i++) { + switch (in[i]) { + case '"': + out[i] = '\''; + break; + default: + out[i] = in[i]; + } + } + + return out; +} + + +static pcb_bom_list_t *bom_insert(char *refdes, char *descr, char *value, pcb_bom_list_t * bom) +{ + pcb_bom_list_t *newlist, *cur, *prev = NULL; + + if (bom == NULL) { + /* this is the first subcircuit so automatically create an entry */ + if ((newlist = malloc(sizeof(pcb_bom_list_t))) == NULL) { + fprintf(stderr, "malloc() failed in bom_insert()\n"); + exit(1); + } + + newlist->next = NULL; + newlist->descr = rnd_strdup(descr); + newlist->value = rnd_strdup(value); + newlist->num = 1; + vts0_init(&newlist->refdes); + vts0_append(&newlist->refdes, rnd_strdup(refdes)); + return newlist; + } + + /* search and see if we already have used one of these components */ + cur = bom; + while(cur != NULL) { + if ((RND_NSTRCMP(descr, cur->descr) == 0) && (RND_NSTRCMP(value, cur->value) == 0)) { + cur->num++; + vts0_append(&cur->refdes, rnd_strdup(refdes)); + break; + } + prev = cur; + cur = cur->next; + } + + if (cur == NULL) { + if ((newlist = malloc(sizeof(pcb_bom_list_t))) == NULL) { + fprintf(stderr, "malloc() failed in bom_insert()\n"); + exit(1); + } + + prev->next = newlist; + + newlist->next = NULL; + newlist->descr = rnd_strdup(descr); + newlist->value = rnd_strdup(value); + newlist->num = 1; + vts0_init(&newlist->refdes); + vts0_append(&newlist->refdes, rnd_strdup(refdes)); + } + + return bom; +} + +/* If fp is not NULL then print out the bill of materials contained in + bom. Either way, free all memory which has been allocated for bom. */ +static void print_and_free(FILE * fp, pcb_bom_list_t *bom) +{ + pcb_bom_list_t *lastb; + char *descr, *value; + long n; + + while (bom != NULL) { + if (fp) { + descr = pcb_bom_clean_str(bom->descr); + value = pcb_bom_clean_str(bom->value); + fprintf(fp, "%d,\"%s\",\"%s\",", bom->num, descr, value); + free(descr); + free(value); + } + + for(n = 0; n < bom->refdes.used; n++) { + char *refdes = bom->refdes.array[n]; + if (fp) + fprintf(fp, "%s ", refdes); + free(refdes); + } + vts0_uninit(&bom->refdes); + if (fp) + fprintf(fp, "\n"); + lastb = bom; + bom = bom->next; + free(lastb); + } +} + +static int bom_print(void) +{ + char utcTime[64]; + FILE *fp; + pcb_bom_list_t *bom = NULL; + + rnd_print_utc(utcTime, sizeof(utcTime), 0); + + PCB_SUBC_LOOP(PCB->Data); + { + /* insert this component into the bill of materials list */ + bom = bom_insert((char *) RND_UNKNOWN(subc->refdes), + (char *) RND_UNKNOWN(pcb_subc_name(subc, "bom::footprint")), + (char *) RND_UNKNOWN(pcb_attribute_get(&subc->Attributes, "value")), + bom); + } + PCB_END_LOOP; + + fp = rnd_fopen_askovr(&PCB->hidlib, bom_filename, "w", NULL); + if (!fp) { + rnd_message(RND_MSG_ERROR, "Cannot open file %s for writing\n", bom_filename); + print_and_free(NULL, bom); + return 1; + } + + fprintf(fp, "# $Id"); + fprintf(fp, "$\n"); + fprintf(fp, "# PcbBOM Version 1.0\n"); + fprintf(fp, "# Date: %s\n", utcTime); + fprintf(fp, "# Author: %s\n", pcb_author()); + fprintf(fp, "# Title: %s - PCB BOM\n", RND_UNKNOWN(PCB->hidlib.name)); + fprintf(fp, "# Quantity, Description, Value, RefDes\n"); + fprintf(fp, "# --------------------------------------------\n"); + + print_and_free(fp, bom); + + fclose(fp); + + return 0; +} + +static void bom_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + int i; + pcb_cam_t cam; + + if (!options) { + bom_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + bom_values[i] = bom_options[i].default_val; + options = bom_values; + } + + bom_filename = options[HA_bomfile].str; + if (!bom_filename) + bom_filename = "pcb-out.bom"; + + pcb_cam_begin_nolayer(PCB, &cam, NULL, options[HA_cam].str, &bom_filename); + + bom_print(); + pcb_cam_end(&cam); +} + +static int bom_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nbom exporter command line arguments:\n\n"); + rnd_hid_usage(bom_options, sizeof(bom_options) / sizeof(bom_options[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x bom [bom_options] foo.pcb\n\n"); + return 0; +} + + +static int bom_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(bom_options, sizeof(bom_options) / sizeof(bom_options[0]), bom_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +rnd_hid_t bom_hid; + +int pplg_check_ver_export_bom(int ver_needed) { return 0; } + +void pplg_uninit_export_bom(void) +{ + rnd_export_remove_opts_by_cookie(bom_cookie); + rnd_hid_remove_hid(&bom_hid); +} + +int pplg_init_export_bom(void) +{ + RND_API_CHK_VER; + + memset(&bom_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&bom_hid); + + bom_hid.struct_size = sizeof(rnd_hid_t); + bom_hid.name = "bom"; + bom_hid.description = "Exports a Bill of Materials"; + bom_hid.exporter = 1; + + bom_hid.get_export_options = bom_get_export_options; + bom_hid.do_export = bom_do_export; + bom_hid.parse_arguments = bom_parse_arguments; + + bom_hid.usage = bom_usage; + + rnd_hid_register_hid(&bom_hid); + return 0; +} Index: tags/2.3.0/src_plugins/export_bom/export_bom.pup =================================================================== --- tags/2.3.0/src_plugins/export_bom/export_bom.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_bom/export_bom.pup (revision 33253) @@ -0,0 +1,9 @@ +$class export +$short bom pcb_exporter +$long Export bom (Bill of Materials) +$state works +$fmt-native no +$fmt-feature-w bom (Bill of Materials, text) +$package export +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_dsn/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_dsn/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_dsn/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_dsn + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_dsn/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_dsn/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_dsn/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {export_dsn} +put /local/pcb/mod/OBJS_C99 [@ $(PLUGDIR)/export_dsn/dsn.o @] + +switch /local/pcb/export_dsn/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_dsn/dsn.c =================================================================== --- tags/2.3.0/src_plugins/export_dsn/dsn.c (nonexistent) +++ tags/2.3.0/src_plugins/export_dsn/dsn.c (revision 33253) @@ -0,0 +1,630 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * + * Specctra .dsn export HID + * Copyright (C) 2008, 2011 Josh Jordan, Dan McMahill, and Jared Casper + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* +This program exports specctra .dsn files. +By Josh Jordan and Dan McMahill, modified from bom.c + -- Updated to use Coord and other fixes by Jared Casper 16 Sep 2011 +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include +#include "buffer.h" +#include "change.h" +#include "draw.h" +#include "undo.h" +#include +#include "polygon.h" +#include +#include "layer.h" +#include +#include "netlist.h" + +#include +#include +#include +#include +#include +#include "hid_cam.h" +#include +#include "obj_line.h" +#include "obj_pstk_inlines.h" + +static const char *dsn_cookie = "dsn exporter"; + +#define GRP_NAME(grp_) ((grp_) - PCB->LayerGroups.grp), ((grp_)->name) + +static rnd_coord_t trackwidth = 8; /* user options defined in export dialog */ +static rnd_coord_t clearance = 8; +static rnd_coord_t viawidth = 45; +static rnd_coord_t viadrill = 25; + +static rnd_hid_t dsn_hid; + +static rnd_export_opt_t dsn_options[] = { + {"dsnfile", "SPECCTRA output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_dsnfile 0 + {"trackwidth", "track width in mils", + RND_HATT_COORD, RND_MIL_TO_COORD(0), RND_MIL_TO_COORD(100), {0, 0, 0, RND_MIL_TO_COORD(8)}, 0, 0}, +#define HA_trackwidth 1 + {"clearance", "clearance in mils", + RND_HATT_COORD, RND_MIL_TO_COORD(0), RND_MIL_TO_COORD(100), {0, 0, 0, RND_MIL_TO_COORD(8)}, 0, 0}, +#define HA_clearance 2 + {"viawidth", "via width in mils", + RND_HATT_COORD, RND_MIL_TO_COORD(0), RND_MIL_TO_COORD(100), {0, 0, 0, RND_MIL_TO_COORD(27)}, 0, + 0}, +#define HA_viawidth 3 + {"viadrill", "via drill diameter in mils", + RND_HATT_COORD, RND_MIL_TO_COORD(0), RND_MIL_TO_COORD(100), {0, 0, 0, RND_MIL_TO_COORD(15)}, 0, + 0}, +#define HA_viadrill 4 + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 5 + +}; + +#define NUM_OPTIONS (sizeof(dsn_options)/sizeof(dsn_options[0])) + +static rnd_hid_attr_val_t dsn_values[NUM_OPTIONS]; + +static const char *dsn_filename; + +static rnd_export_opt_t *dsn_get_export_options(rnd_hid_t *hid, int *n) +{ + if ((PCB != NULL) && (dsn_options[HA_dsnfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &dsn_options[HA_dsnfile], ".dsn"); + if (n) + *n = NUM_OPTIONS; + return dsn_options; +} + +static void print_structure(FILE * fp) +{ + rnd_layergrp_id_t group, top_group, bot_group; + + pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_COPPER, &top_group, 1); + pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_COPPER, &bot_group, 1); + + fprintf(fp, " (structure\n"); + for (group = 0; group < pcb_max_group(PCB); group++) { + htsp_entry_t *e; + pcb_layergrp_t *g = &PCB->LayerGroups.grp[group]; + char *layeropts = rnd_strdup("(type signal)"); + + if (!(g->ltype & PCB_LYT_COPPER)) + continue; + +TODO("revise this; use attributes instead") + /* see if group has same name as a net and make it a power layer */ + /* loop thru all nets */ + for(e = htsp_first(&PCB->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&PCB->netlist[PCB_NETLIST_EDITED], e)) { + pcb_net_t *net = e->value; + if (!strcmp(g->name, net->name)) { + free(layeropts); + layeropts = rnd_strdup_printf("(type power) (use_net \"%s\")", g->name); + } + } + fprintf(fp, " (layer \"%ld__%s\"\n", (long)GRP_NAME(g)); + fprintf(fp, " %s\n", layeropts); + fprintf(fp, " )\n"); + free(layeropts); + } + + /* PCB outline */ + rnd_fprintf(fp, " (boundary\n"); + rnd_fprintf(fp, " (rect pcb 0.0 0.0 %.6mm %.6mm)\n", PCB->hidlib.size_x, PCB->hidlib.size_y); + rnd_fprintf(fp, " )\n"); + rnd_fprintf(fp, " (via via_%ld_%ld)\n", viawidth, viadrill); + + /* DRC rules */ + rnd_fprintf(fp, " (rule\n"); + rnd_fprintf(fp, " (width %mm)\n", trackwidth); + rnd_fprintf(fp, " (clear %mm)\n", clearance); + rnd_fprintf(fp, " (clear %mm (type wire_area))\n", clearance); + rnd_fprintf(fp, " (clear %mm (type via_smd via_pin))\n", clearance); + rnd_fprintf(fp, " (clear %mm (type smd_smd))\n", clearance); + rnd_fprintf(fp, " (clear %mm (type default_smd))\n", clearance); + rnd_fprintf(fp, " )\n )\n"); +} + +static void print_placement(FILE * fp) +{ + fprintf(fp, " (placement\n"); + + PCB_SUBC_LOOP(PCB->Data); + { + char *ename; + rnd_coord_t ox, oy; + char *side; + int res; + int subc_on_solder = 0; + + pcb_subc_get_side(subc, &subc_on_solder); + side = subc_on_solder ? "back" : "front"; + + res = pcb_subc_get_origin(subc, &ox, &oy); + assert(res == 0); + if (subc->refdes != NULL) + ename = rnd_strdup(subc->refdes); + else + ename = rnd_strdup("null"); + rnd_fprintf(fp, " (component %d\n", subc->ID); + rnd_fprintf(fp, " (place \"%s\" %.6mm %.6mm %s 0 (PN 0))\n", ename, ox, PCB->hidlib.size_y - oy, side); + rnd_fprintf(fp, " )\n"); + free(ename); + } + PCB_END_LOOP; + +TODO("padstack: check if real shapes are exported") + PCB_PADSTACK_LOOP(PCB->Data); + { /* add mounting holes */ + rnd_fprintf(fp, " (component %d\n", padstack->ID); + rnd_fprintf(fp, " (place %d %.6mm %.6mm %s 0 (PN 0))\n", padstack->ID, padstack->x, (PCB->hidlib.size_y - padstack->y), "front"); + rnd_fprintf(fp, " )\n"); + } + PCB_END_LOOP; + + fprintf(fp, " )\n"); +} + +static void print_polyshape(gds_t *term_shapes, pcb_pstk_poly_t *ply, rnd_coord_t ox, rnd_coord_t oy, pcb_layergrp_t *grp, int partsidesign) +{ + char tmp[512]; + int fld; + int n; + + rnd_snprintf(tmp, sizeof(tmp), " (polygon \"%d__%s\" 0", GRP_NAME(grp)); + gds_append_str(term_shapes, tmp); + + fld = 0; + for(n = 0; n < ply->len; n++) { + if ((fld % 3) == 0) + gds_append_str(term_shapes, "\n "); + rnd_snprintf(tmp, sizeof(tmp), " %.6mm %.6mm", (ply->x[n] - ox) * partsidesign, -(ply->y[n] - oy)); + gds_append_str(term_shapes, tmp); + fld++; + } + + gds_append_str(term_shapes, "\n )\n"); +} + +static void print_lineshape(gds_t *term_shapes, pcb_pstk_line_t *lin, rnd_coord_t ox, rnd_coord_t oy, pcb_layergrp_t *grp, int partsidesign) +{ + char tmp[512]; + int fld; + rnd_coord_t x[4], y[4]; + int n; + pcb_line_t ltmp; + + rnd_snprintf(tmp, sizeof(tmp), " (polygon \"%d__%s\" 0", GRP_NAME(grp)); + gds_append_str(term_shapes, tmp); + + memset(<mp, 0, sizeof(ltmp)); + ltmp.Point1.X = lin->x1; + ltmp.Point1.Y = lin->y1; + ltmp.Point2.X = lin->x2; + ltmp.Point2.Y = lin->y2; + ltmp.Thickness = lin->thickness; + pcb_sqline_to_rect(<mp, x, y); + +TODO("padstack: this ignores round cap") + + fld = 0; + for(n = 0; n < 4; n++) { + if ((fld % 3) == 0) + gds_append_str(term_shapes, "\n "); + rnd_snprintf(tmp, sizeof(tmp), " %.6mm %.6mm", (x[n] - ox) * partsidesign, -(y[n] - oy)); + gds_append_str(term_shapes, tmp); + fld++; + } + + gds_append_str(term_shapes, "\n )\n"); +} + +static void print_circshape(gds_t *term_shapes, pcb_pstk_circ_t *circ, rnd_coord_t ox, rnd_coord_t oy, pcb_layergrp_t *grp, int partsidesign) +{ + char tmp[512]; + + rnd_snprintf(tmp, sizeof(tmp), " (circle \"%d__%s\"", GRP_NAME(grp)); + gds_append_str(term_shapes, tmp); + +TODO("padstack: this ignores circle center offset") + + rnd_snprintf(tmp, sizeof(tmp), " %.6mm)\n", circ->dia); + gds_append_str(term_shapes, tmp); +} + +static void print_polyline(gds_t *term_shapes, pcb_poly_it_t *it, rnd_pline_t *pl, rnd_coord_t ox, rnd_coord_t oy, pcb_layergrp_t *grp, int partsidesign) +{ + char tmp[512]; + int fld; + rnd_coord_t x, y; + int go; + + if (pl != NULL) { + rnd_snprintf(tmp, sizeof(tmp), "(polygon \"%d__%s\" 0", GRP_NAME(grp)); + gds_append_str(term_shapes, tmp); + + fld = 0; + for(go = pcb_poly_vect_first(it, &x, &y); go; go = pcb_poly_vect_next(it, &x, &y)) { + if ((fld % 3) == 0) + gds_append_str(term_shapes, "\n "); + rnd_snprintf(tmp, sizeof(tmp), " %.6mm %.6mm", (x - ox) * partsidesign, -(y - oy)); + gds_append_str(term_shapes, tmp); + fld++; + } + + gds_append_str(term_shapes, "\n )\n"); + } +} + +static void print_term_poly(FILE *fp, gds_t *term_shapes, pcb_poly_t *poly, rnd_coord_t ox, rnd_coord_t oy, int term_on_bottom, int partsidesign) +{ + if (poly->term != NULL) { + rnd_layergrp_id_t gid = term_on_bottom ? pcb_layergrp_get_bottom_copper() : pcb_layergrp_get_top_copper(); + pcb_layergrp_t *grp = pcb_get_layergrp(PCB, gid); + char *padstack = rnd_strdup_printf("Term_poly_%ld", poly->ID); + pcb_poly_it_t it; + rnd_polyarea_t *pa; + + + rnd_fprintf(fp, " (pin %s \"%s\" %.6mm %.6mm)\n", padstack, poly->term, 0, 0); + + gds_append_str(term_shapes, " (padstack "); + gds_append_str(term_shapes, padstack); + gds_append_str(term_shapes, "\n"); + + gds_append_str(term_shapes, " (shape "); + + for(pa = pcb_poly_island_first(poly, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_pline_t *pl; + + pl = pcb_poly_contour(&it); + + print_polyline(term_shapes, &it, pl, ox, oy, grp, partsidesign); + } + + gds_append_str(term_shapes, " )\n"); + gds_append_str(term_shapes, " (attach off)\n"); + gds_append_str(term_shapes, " )\n"); + } +} + +void print_pstk_shape(gds_t *term_shapes, pcb_pstk_t *padstack, rnd_layergrp_id_t gid, rnd_coord_t ox, rnd_coord_t oy, int partsidesign) +{ + pcb_pstk_shape_t *shp; + pcb_layergrp_t *grp = pcb_get_layergrp(PCB, gid); + pcb_layer_type_t lyt = grp->ltype; + + shp = pcb_pstk_shape(padstack, lyt, 0); + if (shp == NULL) + return; + + /* if the subc is placed on the other side, need to invert the output layerstack as well */ + if (partsidesign < 0) { + rnd_layergrp_id_t n, offs = 0; + + /* determine copper offset from the top */ + for(n = 0; (n < PCB->LayerGroups.len) && (n != gid); n++) + if (PCB->LayerGroups.grp[n].type & PCB_LYT_COPPER) + offs++; + + /* count it back from the bottom and set grp */ + for(n = PCB->LayerGroups.len-1; (n > 0) && (n != gid); n--) { + if (PCB->LayerGroups.grp[n].type & PCB_LYT_COPPER) { + if (offs == 0) { + grp = &PCB->LayerGroups.grp[n]; + break; + } + offs--; + } + } + } + + switch(shp->shape) { + case PCB_PSSH_POLY: + print_polyshape(term_shapes, &shp->data.poly, ox, oy, grp, partsidesign); + break; + case PCB_PSSH_LINE: + print_lineshape(term_shapes, &shp->data.line, ox, oy, grp, partsidesign); + break; + case PCB_PSSH_CIRC: + print_circshape(term_shapes, &shp->data.circ, ox, oy, grp, partsidesign); + break; + case PCB_PSSH_HSHADOW: + break; + } +} + +static void print_library(FILE * fp) +{ + gds_t term_shapes; + + gds_init(&term_shapes); + + fprintf(fp, " (library\n"); + + PCB_SUBC_LOOP(PCB->Data); + { + rnd_coord_t ox, oy; + int partsidesign, subc_on_solder = 0; + pcb_layer_type_t lyt_side; + + pcb_subc_get_side(subc, &subc_on_solder); + partsidesign = subc_on_solder ? -1 : 1; + lyt_side = subc_on_solder ? PCB_LYT_BOTTOM : PCB_LYT_TOP; + + pcb_subc_get_origin(subc, &ox, &oy); + + fprintf(fp, " (image %ld\n", subc->ID); /* map every subc by ID */ + PCB_POLY_COPPER_LOOP(subc->data); + { + pcb_layer_type_t lyt = pcb_layer_flags_(layer); + if ((lyt & PCB_LYT_COPPER) && ((lyt & PCB_LYT_TOP) || (lyt & PCB_LYT_BOTTOM))) + print_term_poly(fp, &term_shapes, polygon, ox, oy, !(lyt & lyt_side), partsidesign); + } + PCB_ENDALL_LOOP; + + PCB_PADSTACK_LOOP(subc->data); + { + rnd_layergrp_id_t group; + char *pid = rnd_strdup_printf("Pstk_shape_%ld", padstack->ID); + + rnd_fprintf(fp, " (pin %s \"%s\" %.6mm %.6mm)\n", pid, padstack->term, (padstack->x-ox)*partsidesign, -(padstack->y-oy)); + + gds_append_str(&term_shapes, " (padstack "); + gds_append_str(&term_shapes, pid); + gds_append_str(&term_shapes, "\n"); + + gds_append_str(&term_shapes, " (shape\n"); + + for (group = 0; group < pcb_max_group(PCB); group++) { + pcb_layergrp_t *g = &PCB->LayerGroups.grp[group]; + if (g->ltype & PCB_LYT_COPPER) + print_pstk_shape(&term_shapes, padstack, group, 0, 0, partsidesign); + } + + gds_append_str(&term_shapes, " )\n"); + gds_append_str(&term_shapes, " (attach off)\n"); + gds_append_str(&term_shapes, " )\n"); + } + PCB_END_LOOP; + + fprintf(fp, " )\n"); + } + PCB_END_LOOP; + + /* add padstack for terminals */ + rnd_fprintf(fp, "%s", term_shapes.array); + rnd_fprintf(fp, " )\n"); + + + gds_uninit(&term_shapes); +} + +static void print_quoted_pin(FILE *fp, const pcb_net_term_t *t) +{ + fprintf(fp, " \"%s\"-\"%s\"", t->refdes, t->term); +} + +static void print_network(FILE * fp) +{ + htsp_entry_t *e; + + fprintf(fp, " (network\n"); + + for(e = htsp_first(&PCB->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&PCB->netlist[PCB_NETLIST_EDITED], e)) { + pcb_net_term_t *t; + pcb_net_t *net = e->value; + + fprintf(fp, " (net \"%s\"\n", net->name); + fprintf(fp, " (pins"); + + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) + print_quoted_pin(fp, t); + fprintf(fp, ")\n"); + fprintf(fp, " )\n"); + } + + fprintf(fp, " (class pcb_rnd_default"); + for(e = htsp_first(&PCB->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&PCB->netlist[PCB_NETLIST_EDITED], e)) { + pcb_net_t *net = e->value; + fprintf(fp, " \"%s\"", net->name); + } + rnd_fprintf(fp, "\n"); + rnd_fprintf(fp, " (circuit\n"); + rnd_fprintf(fp, " (use_via via_%ld_%ld)\n", viawidth, viadrill); + rnd_fprintf(fp, " )\n"); + rnd_fprintf(fp, " (rule (width %.6mm))\n )\n )\n", trackwidth); +} + +static void print_wires(FILE * fp) +{ + int group; + fprintf(fp, " (wiring\n"); + + for (group = 0; group < pcb_max_group(PCB); group++) { + pcb_layergrp_t *g = &PCB->LayerGroups.grp[group]; + rnd_cardinal_t n; + if (!(g->ltype & PCB_LYT_COPPER)) + continue; + for(n = 0; n < g->len; n++) { + pcb_layer_t *lay = pcb_get_layer(PCB->Data, g->lid[n]); + + PCB_LINE_LOOP(lay); + { + rnd_fprintf(fp, + " (wire (path %d__%s %.6mm %.6mm %.6mm %.6mm %.6mm)\n", GRP_NAME(g), line->Thickness, + line->Point1.X, (PCB->hidlib.size_y - line->Point1.Y), + line->Point2.X, (PCB->hidlib.size_y - line->Point2.Y)); + fprintf(fp, " (type protect))\n"); + } + PCB_END_LOOP; + } + } + fprintf(fp, "\n )\n)\n"); /* close all braces */ +} + +static int PrintSPECCTRA(void) +{ + FILE *fp; + /* Print out the dsn .dsn file. */ + fp = rnd_fopen_askovr(&PCB->hidlib, dsn_filename, "w", NULL); + if (!fp) { + rnd_message(RND_MSG_WARNING, "Cannot open file %s for writing\n", dsn_filename); + return 1; + } + + /* pcb [required] */ + fprintf(fp, "(pcb %s\n", ((PCB->hidlib.name) && *(PCB->hidlib.name) ? (PCB->hidlib.name) : "notnamed")); + + /* parser descriptor [optional] */ + fprintf(fp, " (parser\n"); + fprintf(fp, " (string_quote \")\n"); + fprintf(fp, " (space_in_quoted_tokens on)\n"); + fprintf(fp, " (host_cad \"pcb-rnd\")\n"); + fprintf(fp, " (host_version \"%s\")\n", PCB_VERSION); + fprintf(fp, " )\n"); + + /* capacitance resolution descriptor [optional] */ + + /* conductance resolution descriptor [optional] */ + + /* current resolution descriptor [optional] */ + + /* inductance resolution descriptor [optional] */ + + /* resistance resolution descriptor [optional] */ + + /* resolution descriptor [optional] */ + fprintf(fp, " (resolution mm 1000000)\n"); + + /* time resolution descriptor [optional] */ + + /* voltage resolution descriptor [optional] */ + + /* unit descriptor [optional] */ + + /* structure descriptor [required] */ + print_structure(fp); + + /* placement descriptor [optional] */ + print_placement(fp); + + /* library descriptor [required] */ + print_library(fp); + + /* floor plan descriptor [optional] */ + + /* part library descriptor [optional] */ + + /* network descriptor [required] */ + print_network(fp); + + /* wiring descriptor [optional] */ + print_wires(fp); + + /* color descriptor [optional] */ + + fclose(fp); + + return 0; +} + + +static void dsn_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + int i; + pcb_cam_t cam; + + if (!options) { + dsn_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + dsn_values[i] = dsn_options[i].default_val; + options = dsn_values; + } + dsn_filename = options[HA_dsnfile].str; + if (!dsn_filename) + dsn_filename = "pcb-out.dsn"; + + pcb_cam_begin_nolayer(PCB, &cam, NULL, options[HA_cam].str, &dsn_filename); + + trackwidth = options[HA_trackwidth].crd; + clearance = options[HA_clearance].crd; + viawidth = options[HA_viawidth].crd; + viadrill = options[HA_viadrill].crd; + PrintSPECCTRA(); + pcb_cam_end(&cam); +} + +static int dsn_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + return rnd_hid_parse_command_line(argc, argv); +} + +int pplg_check_ver_export_dsn(int ver_needed) { return 0; } + +void pplg_uninit_export_dsn(void) +{ + rnd_export_remove_opts_by_cookie(dsn_cookie); + rnd_hid_remove_hid(&dsn_hid); +} + +int pplg_init_export_dsn(void) +{ + RND_API_CHK_VER; + memset(&dsn_hid, 0, sizeof(rnd_hid_t)); + rnd_hid_nogui_init(&dsn_hid); + + dsn_hid.struct_size = sizeof(rnd_hid_t); + dsn_hid.name = "dsn"; + dsn_hid.description = "Exports DSN format"; + dsn_hid.exporter = 1; + dsn_hid.get_export_options = dsn_get_export_options; + dsn_hid.do_export = dsn_do_export; + dsn_hid.parse_arguments = dsn_parse_arguments; + rnd_hid_register_hid(&dsn_hid); + + rnd_export_register_opts(dsn_options, sizeof(dsn_options) / sizeof(dsn_options[0]), dsn_cookie, 0); + return 0; +} + Index: tags/2.3.0/src_plugins/export_dsn/export_dsn.pup =================================================================== --- tags/2.3.0/src_plugins/export_dsn/export_dsn.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_dsn/export_dsn.pup (revision 33253) @@ -0,0 +1,9 @@ +$class export +$short specctra .dsn pcb_exporter +$long Export specctra .dsn files +$state works +$fmt-native no +$fmt-feature-w specctra .dsn (padstacks and subcircuits, works with freerouting.net) +$package auto +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_dxf/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_dxf/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_dxf/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_dxf + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_dxf/Makefile.test =================================================================== --- tags/2.3.0/src_plugins/export_dxf/Makefile.test (nonexistent) +++ tags/2.3.0/src_plugins/export_dxf/Makefile.test (revision 33253) @@ -0,0 +1,15 @@ +LHT=../../src_3rd/liblihata +HT=../../src_3rd/genht +CFLAGS = -Wall -g -I../../src_3rd -DTESTER +LDFLAGS = +OBJS = $(LHT)/parser.o $(LHT)/lihata.o $(HT)/htsp.o $(HT)/hash.o \ + $(LHT)/dom.o $(LHT)/dom_list.o $(LHT)/dom_hash.o $(LHT)/dom_table.o \ + $(LHT)/tree_path.o $(LHT)/tree.o $(LHT)/tree_list.o $(LHT)/tree_hash.o \ + $(LHT)/tree_table.o $(LHT)/hash_str.o + +lht_template: lht_template.o $(OBJS) + $(CC) $(LDFLAGS) -o $@ $^ + +lht_template.o: lht_template.c + $(CC) -c -o $@ $(CFLAGS) lht_template.c + Index: tags/2.3.0/src_plugins/export_dxf/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_dxf/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_dxf/Plug.tmpasm (revision 33253) @@ -0,0 +1,21 @@ +put /local/pcb/mod {export_dxf} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/export_dxf/dxf.o + $(PLUGDIR)/export_dxf/lht_template.o + $(PLUGDIR)/export_dxf/dxf_templ_lht.o +@] + +switch /local/pcb/export_dxf/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end + +# always generate the template lht rule so make dep can be run +append /local/pcb/CLEANFILES { $(PLUGDIR)/export_dxf/dxf_templ_lht.c } +append /local/pcb/DEPDEPS { $(PLUGDIR)/export_dxf/dxf_templ_lht.c } +append /local/pcb/RULES [@ +### export_dxf: dxf template embed +$(PLUGDIR)/export_dxf/dxf_templ_lht.c: $(PLUGDIR)/export_dxf/dxf_templ.lht $(CQUOTE) + $(CQUOTE) -n dxf_templ_default <$(PLUGDIR)/export_dxf/dxf_templ.lht >$(PLUGDIR)/export_dxf/dxf_templ_lht.c +@] Index: tags/2.3.0/src_plugins/export_dxf/dxf.c =================================================================== --- tags/2.3.0/src_plugins/export_dxf/dxf.c (nonexistent) +++ tags/2.3.0/src_plugins/export_dxf/dxf.c (revision 33253) @@ -0,0 +1,574 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include +#include + +#include +#include "board.h" +#include "data.h" +#include "draw.h" +#include +#include "layer.h" +#include "layer_vis.h" +#include +#include +#include +#include "lht_template.h" +#include +#include "funchash_core.h" + +#include +#include + +#include +#include +#include "hid_cam.h" + +static const char *layer_names[] = { + "outline", + "bottom_copper", "top_copper", + "bottom_silk", "top_silk", + "drill_plated", "drill_unplated", + NULL +}; + +static rnd_hid_t dxf_hid; + +const char *dxf_cookie = "dxf HID"; + +static pcb_cam_t dxf_cam; + + +typedef struct { + FILE *f; + unsigned long handle; + lht_doc_t *temp; + const char *layer_name; + long drawn_objs; + unsigned force_thin:1; + unsigned enable_force_thin:1; + unsigned poly_fill:1; + unsigned poly_contour:1; + unsigned drill_fill:1; + unsigned drill_contour:1; +} dxf_ctx_t; + +static dxf_ctx_t dxf_ctx; + +typedef struct rnd_hid_gc_s { + rnd_core_gc_t core_gc; + rnd_hid_t *me_pointer; + rnd_cap_style_t cap; + rnd_coord_t width; + char *color; + int drill; + unsigned warned_elliptical:1; + unsigned drawing_hole:1; +} rnd_hid_gc_s; + +static struct rnd_hid_gc_s thin = { + {0}, + NULL, + 0, 1, + NULL, 0, 0 +}; + + +#include "dxf_draw.c" + + +rnd_export_opt_t dxf_attribute_list[] = { + /* other HIDs expect this to be first. */ + +/* %start-doc options "93 DXF Options" +@ftable @code +@item --outfile +Name of the file to be exported to. Can contain a path. +@end ftable +%end-doc +*/ + {"outfile", "Graphics output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_dxffile 0 + +/* %start-doc options "93 DXF Options" +@ftable @code +@item --template +Name of the lihata template file to be used instead of the default dxf template. Can contain a path. +@end ftable +%end-doc +*/ + {"template", "DXF template (lihata file)", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_template 1 + +/* %start-doc options "93 DXF Options" +@ftable @code +@item --thin +Draw outline and drills with thin lines. +@end ftable +%end-doc +*/ + {"thin", "Draw outline and drill with thin lines", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_thin 2 + +/* %start-doc options "93 DXF Options" +@ftable @code +@item --poly-fill +Fill polygons using hatch +@end ftable +%end-doc +*/ + {"poly-fill", "Fill polygons using hatch", + RND_HATT_BOOL, 0, 0, {1, (void *)1, 1}, 0, 0}, +#define HA_poly_fill 3 + +/* %start-doc options "93 DXF Options" +@ftable @code +@item --poly-fill +Draw polygons contour with thin line +@end ftable +%end-doc +*/ + {"poly-contour", "Draw polygons contour with thin line", + RND_HATT_BOOL, 0, 0, {1, (void *)1, 1}, 0, 0}, +#define HA_poly_contour 4 + +/* %start-doc options "93 DXF Options" +@ftable @code +@item --drill-fill +Fill drill (hole) circles using hatch +@end ftable +%end-doc +*/ + {"drill-fill", "Fill drill (hole) circles using hatch", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_drill_fill 5 + +/* %start-doc options "93 DXF Options" +@ftable @code +@item --polyfill +Draw drill contour with thin line +@end ftable +%end-doc +*/ + {"drill-contour", "Draw drill contour with thin line", + RND_HATT_BOOL, 0, 0, {1, (void *)1, 1}, 0, 0}, +#define HA_drill_contour 6 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 7 + +}; + +#define NUM_OPTIONS (sizeof(dxf_attribute_list)/sizeof(dxf_attribute_list[0])) + +static rnd_hid_attr_val_t dxf_values[NUM_OPTIONS]; + +static rnd_export_opt_t *dxf_get_export_options(rnd_hid_t *hid, int *n) +{ + const char *suffix = ".dxf"; + + if ((PCB != NULL) && (dxf_attribute_list[HA_dxffile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &dxf_attribute_list[HA_dxffile], suffix); + + if (n) + *n = NUM_OPTIONS; + return dxf_attribute_list; +} + +void dxf_hid_export_to_file(dxf_ctx_t *ctx, rnd_hid_attr_val_t * options, rnd_xform_t *xform) +{ + static int saved_layer_stack[PCB_MAX_LAYER]; + rnd_hid_expose_ctx_t hectx; + + hectx.view.X1 = 0; + hectx.view.Y1 = 0; + hectx.view.X2 = PCB->hidlib.size_x; + hectx.view.Y2 = PCB->hidlib.size_y; + + memcpy(saved_layer_stack, pcb_layer_stack, sizeof(pcb_layer_stack)); + + rnd_conf_force_set_bool(conf_core.editor.show_solder_side, 0); + + dxf_ctx.enable_force_thin = options[HA_thin].lng; + dxf_ctx.poly_fill = options[HA_poly_fill].lng; + dxf_ctx.poly_contour = options[HA_poly_contour].lng; + dxf_ctx.drill_fill = options[HA_drill_fill].lng; + dxf_ctx.drill_contour = options[HA_drill_contour].lng; + + rnd_expose_main(&dxf_hid, &hectx, xform); + + rnd_conf_update(NULL, -1); /* restore forced sets */ +} + +int insert_hdr(FILE *f, const char *prefix, char *name, lht_err_t *err) +{ + if (strcmp(name, "extmin") == 0) + fprintf(f, "10\n0\n20\n0\n30\n0\n"); + else if (strcmp(name, "extmax") == 0) + rnd_fprintf(f, "10\n%mm\n20\n0\n30\n%mm\n", PCB->hidlib.size_x, PCB->hidlib.size_y); + else if (strcmp(name, "layers") == 0) { + const char **s; + for(s = layer_names; *s != NULL; s++) + dxf_gen_layer(&dxf_ctx, *s); + } + else { + rnd_message(RND_MSG_ERROR, "Invalid header insertion: '%s'\n", name); + return -1; + } + + return 0; +} + +int insert_ftr(FILE *f, const char *prefix, char *name, lht_err_t *err) +{ + rnd_message(RND_MSG_ERROR, "Invalid footer insertion: '%s'\n", name); + return -1; +} + +extern const char dxf_templ_default_arr[]; +static void dxf_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + const char *filename; + int save_ons[PCB_MAX_LAYER]; + int i; + const char *fn; + char *errmsg; + lht_err_t err; + rnd_xform_t xform; + + if (!options) { + dxf_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + dxf_values[i] = dxf_attribute_list[i].default_val; + options = dxf_values; + } + + dxf_ctx.drawn_objs = 0; + pcb_cam_begin(PCB, &dxf_cam, &xform, options[HA_cam].str, dxf_attribute_list, NUM_OPTIONS, options); + + filename = options[HA_dxffile].str; + if (!filename) + filename = "pcb.dxf"; + + if (dxf_cam.fn_template == NULL) { + dxf_ctx.f = rnd_fopen_askovr(&PCB->hidlib, dxf_cam.active ? dxf_cam.fn : filename, "wb", NULL); + if (!dxf_ctx.f) { + perror(filename); + return; + } + } + else + dxf_ctx.f = NULL; + + fn = options[HA_template].str; + if (fn == NULL) { + fn = ""; + dxf_ctx.temp = lht_dom_load_string(dxf_templ_default_arr, fn, &errmsg); + } + else { + char *real_fn; + dxf_ctx.temp = NULL; + real_fn = rnd_fopen_check(&PCB->hidlib, fn, "r"); + if (real_fn != NULL) + dxf_ctx.temp = lht_dom_load(real_fn, &errmsg); + free(real_fn); + } + + if (dxf_ctx.temp == NULL) { + rnd_message(RND_MSG_ERROR, "Can't open dxf template: %s\n", fn); + fclose(dxf_ctx.f); + return; + } + + dxf_ctx.handle = 100; + if (dxf_ctx.f != NULL) { + if (lht_temp_exec(dxf_ctx.f, "", dxf_ctx.temp, "header", insert_hdr, &err) != 0) + rnd_message(RND_MSG_ERROR, "Can't render dxf template header\n"); + } + + if (!dxf_cam.active) + pcb_hid_save_and_show_layer_ons(save_ons); + + dxf_hid_export_to_file(&dxf_ctx, options, &xform); + + if (!dxf_cam.active) + pcb_hid_restore_layer_ons(save_ons); + + if (lht_temp_exec(dxf_ctx.f, "", dxf_ctx.temp, "footer", insert_ftr, &err) != 0) + rnd_message(RND_MSG_ERROR, "Can't render dxf template header\n"); + fclose(dxf_ctx.f); + + if (!dxf_cam.active) dxf_cam.okempty_content = 1; /* never warn in direct export */ + + if (pcb_cam_end(&dxf_cam) == 0) { + if (!dxf_cam.okempty_group) + rnd_message(RND_MSG_ERROR, "dxf cam export for '%s' failed to produce any content (layer group missing)\n", options[HA_cam].str); + } + else if (dxf_ctx.drawn_objs == 0) { + if (!dxf_cam.okempty_content) + rnd_message(RND_MSG_ERROR, "dxf cam export for '%s' failed to produce any content (no objects)\n", options[HA_cam].str); + } +} + +static int dxf_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(dxf_attribute_list, sizeof(dxf_attribute_list) / sizeof(dxf_attribute_list[0]), dxf_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int dxf_set_layer_group(rnd_hid_t *hid, 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 (flags & PCB_LYT_UI) + return 0; + + pcb_cam_set_layer_group(&dxf_cam, group, purpose, purpi, flags, xform); + + if (dxf_cam.fn_changed) { + lht_err_t err; + + if (dxf_ctx.f != NULL) { + if (lht_temp_exec(dxf_ctx.f, "", dxf_ctx.temp, "footer", insert_ftr, &err) != 0) + rnd_message(RND_MSG_ERROR, "Can't render dxf template header\n"); + fclose(dxf_ctx.f); + } + + dxf_ctx.f = rnd_fopen_askovr(&PCB->hidlib, dxf_cam.fn, "wb", NULL); + if (!dxf_ctx.f) { + perror(dxf_cam.fn); + return 0; + } + if (lht_temp_exec(dxf_ctx.f, "", dxf_ctx.temp, "header", insert_hdr, &err) != 0) + rnd_message(RND_MSG_ERROR, "Can't render dxf template header\n"); + } + + if (!dxf_cam.active) { + if (flags & PCB_LYT_INVIS) + return 0; + } + + dxf_ctx.force_thin = 0; + + if (PCB_LAYER_IS_ROUTE(flags, purpi)) { + dxf_ctx.layer_name = "outline"; + dxf_ctx.force_thin = 1; + return 1; + } + + if (dxf_cam.active) { + pcb_layergrp_t *grp = pcb_get_layergrp(PCB, group); + dxf_ctx.layer_name = grp->name; + return 1; + } + + if (PCB_LAYER_IS_PDRILL(flags, purpi)) { + dxf_ctx.layer_name = "drill_plated"; + dxf_ctx.force_thin = 1; + return 1; + } + + if (PCB_LAYER_IS_UDRILL(flags, purpi)) { + dxf_ctx.layer_name = "drill_unplated"; + dxf_ctx.force_thin = 1; + return 1; + } + + if ((flags & PCB_LYT_TOP) && (flags & PCB_LYT_COPPER)) { + dxf_ctx.layer_name = "top_copper"; + return 1; + } + + if ((flags & PCB_LYT_TOP) && (flags & PCB_LYT_SILK)) { + dxf_ctx.layer_name = "top_silk"; + return 1; + } + + if ((flags & PCB_LYT_BOTTOM) && (flags & PCB_LYT_COPPER)) { + dxf_ctx.layer_name = "bottom_copper"; + return 1; + } + + if ((flags & PCB_LYT_BOTTOM) && (flags & PCB_LYT_SILK)) { + dxf_ctx.layer_name = "bottom_silk"; + return 1; + } + + return 0; +} + + +static rnd_hid_gc_t dxf_make_gc(rnd_hid_t *hid) +{ + rnd_hid_gc_t rv = (rnd_hid_gc_t) calloc(sizeof(rnd_hid_gc_s), 1); + rv->me_pointer = &dxf_hid; + return rv; +} + +static void dxf_destroy_gc(rnd_hid_gc_t gc) +{ + free(gc); +} + +static void dxf_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + if (direct) + return; + + switch(op) { + case RND_HID_COMP_RESET: + break; + + case RND_HID_COMP_POSITIVE: + case RND_HID_COMP_POSITIVE_XOR: + case RND_HID_COMP_NEGATIVE: + break; + + case RND_HID_COMP_FLUSH: + break; + } +} + +static void dxf_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + if (rnd_color_is_drill(color) == 0) + gc->drawing_hole = 1; +} + +static void dxf_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + gc->cap = style; +} + +static void dxf_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + gc->width = width; +} + + +static void dxf_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ + ; +} + +#define fix_rect_coords() \ + if (x1 > x2) {\ + rnd_coord_t t = x1; \ + x1 = x2; \ + x2 = t; \ + } \ + if (y1 > y2) { \ + rnd_coord_t t = y1; \ + y1 = y2; \ + y2 = t; \ + } + +static void dxf_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + fix_rect_coords(); +} + +static void dxf_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + fix_rect_coords(); +} + +static void dxf_calibrate(rnd_hid_t *hid, double xval, double yval) +{ + rnd_message(RND_MSG_ERROR, "dxf_calibrate() not implemented"); + return; +} + +static void dxf_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int a) +{ +} + +static int dxf_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\ndxf exporter command line arguments:\n\n"); + rnd_hid_usage(dxf_attribute_list, sizeof(dxf_attribute_list) / sizeof(dxf_attribute_list[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x dxf [dxf options] foo.pcb\n\n"); + return 0; +} + +int pplg_check_ver_export_dxf(int ver_needed) { return 0; } + +void pplg_uninit_export_dxf(void) +{ + rnd_export_remove_opts_by_cookie(dxf_cookie); + rnd_hid_remove_hid(&dxf_hid); +} + +int pplg_init_export_dxf(void) +{ + RND_API_CHK_VER; + + memset(&dxf_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&dxf_hid); + + dxf_hid.struct_size = sizeof(rnd_hid_t); + dxf_hid.name = "dxf"; + dxf_hid.description = "Drawing eXchange Format exporter"; + dxf_hid.exporter = 1; + + dxf_hid.get_export_options = dxf_get_export_options; + dxf_hid.do_export = dxf_do_export; + dxf_hid.parse_arguments = dxf_parse_arguments; + dxf_hid.set_layer_group = dxf_set_layer_group; + dxf_hid.make_gc = dxf_make_gc; + dxf_hid.destroy_gc = dxf_destroy_gc; + dxf_hid.set_drawing_mode = dxf_set_drawing_mode; + dxf_hid.set_color = dxf_set_color; + dxf_hid.set_line_cap = dxf_set_line_cap; + dxf_hid.set_line_width = dxf_set_line_width; + dxf_hid.set_draw_xor = dxf_set_draw_xor; + dxf_hid.draw_line = dxf_draw_line; + dxf_hid.draw_arc = dxf_draw_arc; + dxf_hid.draw_rect = dxf_draw_rect; + dxf_hid.fill_circle = dxf_fill_circle; + dxf_hid.fill_polygon = dxf_fill_polygon; + dxf_hid.fill_polygon_offs = dxf_fill_polygon_offs; + dxf_hid.fill_rect = dxf_fill_rect; + dxf_hid.calibrate = dxf_calibrate; + dxf_hid.set_crosshair = dxf_set_crosshair; + + dxf_hid.usage = dxf_usage; + + rnd_hid_register_hid(&dxf_hid); + + return 0; +} Index: tags/2.3.0/src_plugins/export_dxf/dxf_draw.c =================================================================== --- tags/2.3.0/src_plugins/export_dxf/dxf_draw.c (nonexistent) +++ tags/2.3.0/src_plugins/export_dxf/dxf_draw.c (revision 33253) @@ -0,0 +1,205 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#define TRX(x) (x) +#define TRY(y) (PCB->hidlib.size_y - (y)) + +static void dxf_draw_handle(dxf_ctx_t *ctx) +{ + ctx->drawn_objs++; + ctx->handle++; + fprintf(ctx->f, "5\n%lu\n", ctx->handle); +} + +static void dxf_draw_line_props(dxf_ctx_t *ctx, rnd_hid_gc_t gc) +{ + fprintf(ctx->f, "100\nAcDbEntity\n"); + fprintf(ctx->f, "8\n%s\n", ctx->layer_name); /* layer name */ + fprintf(ctx->f, "6\nByLayer\n"); /* linetype name */ + fprintf(ctx->f, "62\n256\n"); /* color; 256=ByLayer */ + + /* lineweight enum (width in 0.01mm) */ + if (ctx->enable_force_thin && ctx->force_thin) + fprintf(ctx->f, "370\n1\n"); + else + fprintf(ctx->f, "370\n%d\n", (int)rnd_round(RND_COORD_TO_MM(gc->width)*100.0)); +} + +static void dxf_hatch_pre(dxf_ctx_t *ctx, rnd_hid_gc_t gc, int n_coords) +{ + fprintf(ctx->f, "0\nHATCH\n"); + dxf_draw_handle(ctx); + dxf_draw_line_props(ctx, gc); + fprintf(ctx->f, "100\nAcDbHatch\n"); + fprintf(ctx->f, "10\n0\n20\n0\n30\n0\n"); /* elevation */ + fprintf(ctx->f, "210\n0\n220\n0\n230\n1\n"); /* extrusion */ + fprintf(ctx->f, "2\nSOLID\n"); + fprintf(ctx->f, "70\n1\n"); /* solid fill */ + fprintf(ctx->f, "71\n0\n"); /* associativity: non */ + fprintf(ctx->f, "91\n1\n"); /* number of loops (contours) */ + fprintf(ctx->f, "92\n0\n"); /* boundary path type: default */ + fprintf(ctx->f, "93\n%d\n", n_coords); +} + +static void dxf_hatch_post(dxf_ctx_t *ctx) +{ + fprintf(ctx->f, "97\n0\n"); /* number of source boundaries */ + fprintf(ctx->f, "75\n0\n"); /* hatch style: normal, odd parity */ + fprintf(ctx->f, "76\n1\n"); /* pattern type: predefined */ + fprintf(ctx->f, "98\n0\n"); /* number of seed points */ +} + +static void dxf_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + dxf_ctx_t *ctx = &dxf_ctx; + fprintf(ctx->f, "0\nLINE\n"); + dxf_draw_handle(ctx); + dxf_draw_line_props(ctx, gc); + fprintf(ctx->f, "100\nAcDbLine\n"); + rnd_fprintf(ctx->f, "10\n%mm\n20\n%mm\n", TRX(x1), TRY(y1)); + rnd_fprintf(ctx->f, "11\n%mm\n21\n%mm\n", TRX(x2), TRY(y2)); +} + +static void dxf_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t r) +{ + dxf_ctx_t *ctx = &dxf_ctx; + fprintf(ctx->f, "0\nCIRCLE\n"); + dxf_draw_handle(ctx); + dxf_draw_line_props(ctx, &thin); + + /* contour, just in case the hatch fails */ + if (ctx->drill_contour) { + fprintf(ctx->f, "100\nAcDbCircle\n"); + rnd_fprintf(ctx->f, "10\n%mm\n20\n%mm\n", TRX(cx), TRY(cy)); + rnd_fprintf(ctx->f, "40\n%mm\n", r); + } + + /* hatch for fill circle: use it for copper or if explicitly requested */ + if (ctx->drill_fill || !gc->drawing_hole) { + dxf_hatch_pre(ctx, &thin, 1); + rnd_fprintf(ctx->f, "72\n2\n"); /* circular contour */ + rnd_fprintf(ctx->f, "10\n%mm\n20\n%mm\n", TRX(cx), TRY(cy)); + rnd_fprintf(ctx->f, "40\n%mm\n", r); + rnd_fprintf(ctx->f, "50\n0\n"); + rnd_fprintf(ctx->f, "51\n360\n"); + rnd_fprintf(ctx->f, "73\n1\n"); /* is closed */ + dxf_hatch_post(ctx); + } +} + +static void dxf_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_angle_t end_angle, tmp; + dxf_ctx_t *ctx = &dxf_ctx; + + end_angle = start_angle + delta_angle; + + if (delta_angle < 0) { + tmp = start_angle; + start_angle = end_angle; + end_angle = tmp; + } + + start_angle -= 180; + end_angle -= 180; + if (end_angle >= 360) + end_angle -= 360; + if (end_angle < 0) + end_angle += 360; + + fprintf(ctx->f, "0\nARC\n"); + dxf_draw_handle(ctx); + dxf_draw_line_props(ctx, gc); + fprintf(ctx->f, "100\nAcDbCircle\n"); + rnd_fprintf(ctx->f, "10\n%mm\n20\n%mm\n", TRX(cx), TRY(cy)); + rnd_fprintf(ctx->f, "40\n%mm\n", (width + height)/2); + fprintf(ctx->f, "100\nAcDbArc\n"); + fprintf(ctx->f, "50\n%f\n", start_angle); + fprintf(ctx->f, "51\n%f\n", end_angle); +} + +static void dxf_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) +{ + dxf_ctx_t *ctx = &dxf_ctx; + int n, to; + + dxf_ctx.drawn_objs++; + +#if HATCH_NEEDS_BBOX + rnd_coord_t x_min, x_max, y_min, y_max; + x_max = x_min = *x + dx; + y_max = y_min = *y + dy; + for(n = 1; n < n_coords; n++) { + if (x[n] < x_min) x_min = x[n] + dx; + if (x[n] > x_max) x_max = x[n] + dx; + if (y[n] < y_min) y_min = y[n] + dy; + if (y[n] > y_max) y_max = y[n] + dy; + } +#endif + + if (ctx->poly_fill) { + dxf_hatch_pre(ctx, &thin, n_coords); + for(n = 0; n < n_coords; n++) { + to = n+1; + if (to == n_coords) + to = 0; + fprintf(ctx->f, "72\n1\n"); /* edge=line */ + rnd_fprintf(ctx->f, "10\n%mm\n20\n%mm\n", TRX(x[n]+dx), TRY(y[n]+dy)); + rnd_fprintf(ctx->f, "11\n%mm\n21\n%mm\n", TRX(x[to]+dx), TRY(y[to]+dy)); + } + dxf_hatch_post(ctx); + } + + if (ctx->poly_contour) { + for(n = 0; n < n_coords; n++) { + to = n+1; + if (to == n_coords) + to = 0; + dxf_draw_line(&thin, x[n]+dx, y[n]+dy, x[to]+dx, y[to]+dy); + } + } +} + + +static void dxf_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + dxf_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + +static void dxf_gen_layer(dxf_ctx_t *ctx, const char *name) +{ + fprintf(ctx->f, "0\nLAYER\n"); + dxf_draw_handle(ctx); + fprintf(ctx->f, "330\n2\n"); /* BLOCK_RECORD handle */ + fprintf(ctx->f, "100\nAcDbSymbolTableRecord\n"); + fprintf(ctx->f, "100\nAcDbLayerTableRecord\n"); + fprintf(ctx->f, "2\n%s\n", name); + fprintf(ctx->f, "70\n0\n"); /* flags */ + fprintf(ctx->f, "62\n7\n"); /* color */ + fprintf(ctx->f, "6\nCONTINUOUS\n"); /* default line type */ + fprintf(ctx->f, "370\n15\n"); /* default line width in 0.01mm */ + fprintf(ctx->f, "390\nF\n"); /* plot style */ +} Index: tags/2.3.0/src_plugins/export_dxf/dxf_templ.lht =================================================================== --- tags/2.3.0/src_plugins/export_dxf/dxf_templ.lht (nonexistent) +++ tags/2.3.0/src_plugins/export_dxf/dxf_templ.lht (revision 33253) @@ -0,0 +1,1554 @@ +ha:template { + trim_indent=1 + ha:template { + li:header { + verbatim { + 999 + dxfrw 0.5.11 + 0 + SECTION + 2 + HEADER + 9 + $ACADVER + 1 + AC1021 + 9 + $HANDSEED + 5 + 20000 + 9 + $DWGCODEPAGE + 3 + ANSI_1252 + 9 + $INSBASE + 10 + 0 + 20 + 0 + 30 + 0 + 9 + $EXTMIN + } + insert {extmin} + verbatim { + 9 + $EXTMAX + } + insert {extmax} + verbatim { + 9 + $LIMMIN + 10 + 0 + 20 + 0 + 9 + $LIMMAX + 10 + 420 + 20 + 297 + 9 + $ORTHOMODE + 70 + 0 + 9 + $LTSCALE + 40 + 1 + 9 + $TEXTSTYLE + 7 + STANDARD + 9 + $CLAYER + 8 + 0 + 9 + $DIMASZ + 40 + 2.5 + 9 + $DIMLFAC + 40 + 1 + 9 + $DIMSCALE + 40 + 1 + 9 + $DIMEXO + 40 + 0.625 + 9 + $DIMEXE + 40 + 1.25 + 9 + $DIMTXT + 40 + 2.5 + 9 + $DIMTSZ + 40 + 0 + 9 + $DIMAUNIT + 70 + 0 + 9 + $DIMADEC + 70 + 0 + 9 + $DIMLUNIT + 70 + 2 + 9 + $DIMSTYLE + 2 + STANDARD + 9 + $DIMGAP + 40 + 0.625 + 9 + $DIMTIH + 70 + 0 + 9 + $LUNITS + 70 + 2 + 9 + $LUPREC + 70 + 4 + 9 + $AUNITS + 70 + 0 + 9 + $AUPREC + 70 + 2 + 9 + $SPLINESEGS + 70 + 8 + 9 + $SNAPSTYLE + 70 + 0 + 9 + $PINSBASE + 10 + 0 + 20 + 0 + 30 + 0 + 9 + $PLIMMIN + 10 + 0 + 20 + 0 + 9 + $PLIMMAX + 10 + 210 + 20 + 297 + 9 + $INSUNITS + 70 + 4 + 9 + $PSVPSCALE + 40 + 1 + 0 + ENDSEC + 0 + SECTION + 2 + CLASSES + 0 + ENDSEC + 0 + SECTION + 2 + TABLES + 0 + TABLE + 2 + VPORT + 5 + 8 + 330 + 0 + 100 + AcDbSymbolTable + 70 + 1 + 0 + VPORT + 5 + 31 + 330 + 2 + 100 + AcDbSymbolTableRecord + 100 + AcDbViewportTableRecord + 2 + *ACTIVE + 70 + 0 + 10 + 0 + 20 + 0 + 11 + 1 + 21 + 1 + 12 + 73.375 + 22 + 51.875 + 13 + 0 + 23 + 0 + 14 + 10 + 24 + 10 + 15 + 10 + 25 + 10 + 16 + 0 + 26 + 0 + 36 + 1 + 17 + 0 + 27 + 0 + 37 + 0 + 40 + 116.25 + 41 + 1.36989247312 + 42 + 50 + 43 + 0 + 44 + 0 + 50 + 0 + 51 + 0 + 71 + 0 + 72 + 100 + 73 + 1 + 74 + 3 + 75 + 0 + 76 + 1 + 77 + 0 + 78 + 0 + 281 + 0 + 65 + 1 + 110 + 0 + 120 + 0 + 130 + 0 + 111 + 1 + 121 + 0 + 131 + 0 + 112 + 0 + 122 + 1 + 132 + 0 + 79 + 0 + 146 + 0 + 348 + 10020 + 60 + 7 + 61 + 5 + 292 + 1 + 282 + 1 + 141 + 0 + 142 + 0 + 63 + 250 + 421 + 3358443 + 0 + ENDTAB + 0 + TABLE + 2 + LTYPE + 5 + 5 + 330 + 0 + 100 + AcDbSymbolTable + 70 + 4 + 0 + LTYPE + 5 + 14 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + ByBlock + 70 + 0 + 3 + + 72 + 65 + 73 + 0 + 40 + 0 + 0 + LTYPE + 5 + 15 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + ByLayer + 70 + 0 + 3 + + 72 + 65 + 73 + 0 + 40 + 0 + 0 + LTYPE + 5 + 16 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + Continuous + 70 + 0 + 3 + Solid line + 72 + 65 + 73 + 0 + 40 + 0 + 0 + LTYPE + 5 + 32 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DOT + 70 + 0 + 3 + Dot . . . . . . . . . . . . . . . . . . . . . . + 72 + 65 + 73 + 2 + 40 + 6.35 + 49 + 0 + 74 + 0 + 49 + -6.35 + 74 + 0 + 0 + LTYPE + 5 + 33 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DOT2 + 70 + 0 + 3 + Dot (.5x) ..................................... + 72 + 65 + 73 + 2 + 40 + 3.175 + 49 + 0 + 74 + 0 + 49 + -3.175 + 74 + 0 + 0 + LTYPE + 5 + 34 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DOTX2 + 70 + 0 + 3 + Dot (2x) . . . . . . . . . . . . . + 72 + 65 + 73 + 2 + 40 + 12.7 + 49 + 0 + 74 + 0 + 49 + -12.7 + 74 + 0 + 0 + LTYPE + 5 + 35 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DASHED + 70 + 0 + 3 + Dot . . . . . . . . . . . . . . . . . . . . . . + 72 + 65 + 73 + 2 + 40 + 19.05 + 49 + 12.7 + 74 + 0 + 49 + -6.35 + 74 + 0 + 0 + LTYPE + 5 + 36 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DASHED2 + 70 + 0 + 3 + Dashed (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + 72 + 65 + 73 + 2 + 40 + 9.525 + 49 + 6.35 + 74 + 0 + 49 + -3.175 + 74 + 0 + 0 + LTYPE + 5 + 37 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DASHEDX2 + 70 + 0 + 3 + Dashed (2x) ____ ____ ____ ____ ____ ___ + 72 + 65 + 73 + 2 + 40 + 38.1 + 49 + 25.4 + 74 + 0 + 49 + -12.7 + 74 + 0 + 0 + LTYPE + 5 + 38 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DASHDOT + 70 + 0 + 3 + Dash dot __ . __ . __ . __ . __ . __ . __ . __ + 72 + 65 + 73 + 4 + 40 + 25.4 + 49 + 12.7 + 74 + 0 + 49 + -6.35 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -6.35 + 74 + 0 + 0 + LTYPE + 5 + 39 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DASHDOT2 + 70 + 0 + 3 + Dash dot (.5x) _._._._._._._._._._._._._._._. + 72 + 65 + 73 + 4 + 40 + 12.7 + 49 + 6.35 + 74 + 0 + 49 + -3.175 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -3.175 + 74 + 0 + 0 + LTYPE + 5 + 3A + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DASHDOTX2 + 70 + 0 + 3 + Dash dot (2x) ____ . ____ . ____ . ___ + 72 + 65 + 73 + 4 + 40 + 50.8 + 49 + 25.4 + 74 + 0 + 49 + -12.7 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -12.7 + 74 + 0 + 0 + LTYPE + 5 + 3B + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DIVIDE + 70 + 0 + 3 + Divide ____ . . ____ . . ____ . . ____ . . ____ + 72 + 65 + 73 + 6 + 40 + 31.75 + 49 + 12.7 + 74 + 0 + 49 + -6.35 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -6.35 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -6.35 + 74 + 0 + 0 + LTYPE + 5 + 3C + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DIVIDE2 + 70 + 0 + 3 + Divide (.5x) __..__..__..__..__..__..__..__.._ + 72 + 65 + 73 + 6 + 40 + 15.875 + 49 + 6.35 + 74 + 0 + 49 + -3.175 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -3.175 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -3.175 + 74 + 0 + 0 + LTYPE + 5 + 3D + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + DIVIDEX2 + 70 + 0 + 3 + Divide (2x) ________ . . ________ . . _ + 72 + 65 + 73 + 6 + 40 + 63.5 + 49 + 25.4 + 74 + 0 + 49 + -12.7 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -12.7 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -12.7 + 74 + 0 + 0 + LTYPE + 5 + 3E + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + BORDER + 70 + 0 + 3 + Border __ __ . __ __ . __ __ . __ __ . __ __ . + 72 + 65 + 73 + 6 + 40 + 44.45 + 49 + 12.7 + 74 + 0 + 49 + -6.35 + 74 + 0 + 49 + 12.7 + 74 + 0 + 49 + -6.35 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -6.35 + 74 + 0 + 0 + LTYPE + 5 + 3F + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + BORDER2 + 70 + 0 + 3 + Border (.5x) __.__.__.__.__.__.__.__.__.__.__. + 72 + 65 + 73 + 6 + 40 + 22.225 + 49 + 6.35 + 74 + 0 + 49 + -3.175 + 74 + 0 + 49 + 6.35 + 74 + 0 + 49 + -3.175 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -3.175 + 74 + 0 + 0 + LTYPE + 5 + 40 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + BORDERX2 + 70 + 0 + 3 + Border (2x) ____ ____ . ____ ____ . ___ + 72 + 65 + 73 + 6 + 40 + 88.9 + 49 + 25.4 + 74 + 0 + 49 + -12.7 + 74 + 0 + 49 + 25.4 + 74 + 0 + 49 + -12.7 + 74 + 0 + 49 + 0 + 74 + 0 + 49 + -12.7 + 74 + 0 + 0 + LTYPE + 5 + 41 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + CENTER + 70 + 0 + 3 + Center ____ _ ____ _ ____ _ ____ _ ____ _ ____ + 72 + 65 + 73 + 4 + 40 + 50.8 + 49 + 31.75 + 74 + 0 + 49 + -6.35 + 74 + 0 + 49 + 6.35 + 74 + 0 + 49 + -6.35 + 74 + 0 + 0 + LTYPE + 5 + 42 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + CENTER2 + 70 + 0 + 3 + Center (.5x) ___ _ ___ _ ___ _ ___ _ ___ _ ___ + 72 + 65 + 73 + 4 + 40 + 28.575 + 49 + 19.05 + 74 + 0 + 49 + -3.175 + 74 + 0 + 49 + 3.175 + 74 + 0 + 49 + -3.175 + 74 + 0 + 0 + LTYPE + 5 + 43 + 330 + 5 + 100 + AcDbSymbolTableRecord + 100 + AcDbLinetypeTableRecord + 2 + CENTERX2 + 70 + 0 + 3 + Center (2x) ________ __ ________ __ _____ + 72 + 65 + 73 + 4 + 40 + 101.6 + 49 + 63.5 + 74 + 0 + 49 + -12.7 + 74 + 0 + 49 + 12.7 + 74 + 0 + 49 + -12.7 + 74 + 0 + 0 + ENDTAB + 0 + TABLE + 2 + LAYER + 5 + 2 + 330 + 0 + 100 + AcDbSymbolTable + 70 + 1 + 0 + LAYER + 5 + 10 + 330 + 2 + 100 + AcDbSymbolTableRecord + 100 + AcDbLayerTableRecord + 2 + 0 + 70 + 0 + 62 + 7 + 6 + CONTINUOUS + 370 + 0 + 390 + F + } + insert {layers} + verbatim { + 0 + ENDTAB + 0 + TABLE + 2 + STYLE + 5 + 3 + 330 + 0 + 100 + AcDbSymbolTable + 70 + 3 + 0 + STYLE + 5 + 44 + 330 + 2 + 100 + AcDbSymbolTableRecord + 100 + AcDbTextStyleTableRecord + 2 + Standard + 70 + 0 + 40 + 0 + 41 + 1 + 50 + 0 + 71 + 0 + 42 + 1 + 3 + txt + 4 + + 0 + ENDTAB + 0 + TABLE + 2 + VIEW + 5 + 6 + 330 + 0 + 100 + AcDbSymbolTable + 70 + 0 + 0 + ENDTAB + 0 + TABLE + 2 + UCS + 5 + 7 + 330 + 0 + 100 + AcDbSymbolTable + 70 + 0 + 0 + ENDTAB + 0 + TABLE + 2 + APPID + 5 + 9 + 330 + 0 + 100 + AcDbSymbolTable + 70 + 1 + 0 + APPID + 5 + 12 + 330 + 9 + 100 + AcDbSymbolTableRecord + 100 + AcDbRegAppTableRecord + 2 + ACAD + 70 + 0 + 0 + ENDTAB + 0 + TABLE + 2 + DIMSTYLE + 5 + A + 330 + 0 + 100 + AcDbSymbolTable + 70 + 1 + 100 + AcDbDimStyleTable + 71 + 1 + 0 + DIMSTYLE + 105 + 45 + 330 + A + 100 + AcDbSymbolTableRecord + 100 + AcDbDimStyleTableRecord + 2 + Standard + 70 + 0 + 40 + 1 + 41 + 2.5 + 42 + 0.625 + 43 + 0.38 + 44 + 1.25 + 45 + 0 + 46 + 0 + 47 + 0 + 48 + 0 + 140 + 2.5 + 141 + 0.09 + 142 + 0 + 143 + 25.4 + 144 + 1 + 145 + 0 + 146 + 1 + 147 + 0.625 + 148 + 0 + 71 + 0 + 72 + 0 + 73 + 0 + 74 + 1 + 75 + 0 + 76 + 0 + 77 + 0 + 78 + 0 + 79 + 0 + 170 + 0 + 171 + 2 + 172 + 0 + 173 + 0 + 174 + 0 + 175 + 0 + 176 + 0 + 177 + 0 + 178 + 0 + 179 + 0 + 271 + 4 + 272 + 4 + 273 + 2 + 274 + 2 + 275 + 0 + 276 + 0 + 277 + 2 + 278 + 46 + 279 + 0 + 280 + 0 + 281 + 0 + 282 + 0 + 283 + 1 + 284 + 0 + 285 + 0 + 286 + 0 + 288 + 0 + 289 + 3 + 340 + Standard + 341 + + 371 + -2 + 372 + -2 + 0 + ENDTAB + 0 + TABLE + 2 + BLOCK_RECORD + 5 + 1 + 330 + 0 + 100 + AcDbSymbolTable + 70 + 2 + 0 + BLOCK_RECORD + 5 + 1F + 330 + 1 + 100 + AcDbSymbolTableRecord + 100 + AcDbBlockTableRecord + 2 + *Model_Space + 70 + 0 + 280 + 1 + 281 + 0 + 0 + BLOCK_RECORD + 5 + 1E + 330 + 1 + 100 + AcDbSymbolTableRecord + 100 + AcDbBlockTableRecord + 2 + *Paper_Space + 70 + 0 + 280 + 1 + 281 + 0 + 0 + ENDTAB + 0 + ENDSEC + 0 + SECTION + 2 + BLOCKS + 0 + BLOCK + 5 + 20 + 330 + 1F + 100 + AcDbEntity + 8 + 0 + 100 + AcDbBlockBegin + 2 + *Model_Space + 70 + 0 + 10 + 0 + 20 + 0 + 30 + 0 + 3 + *Model_Space + 1 + + 0 + ENDBLK + 5 + 21 + 330 + 1F + 100 + AcDbEntity + 8 + 0 + 100 + AcDbBlockEnd + 0 + BLOCK + 5 + 1C + 330 + 1B + 100 + AcDbEntity + 8 + 0 + 100 + AcDbBlockBegin + 2 + *Paper_Space + 70 + 0 + 10 + 0 + 20 + 0 + 30 + 0 + 3 + *Paper_Space + 1 + + 0 + ENDBLK + 5 + 1D + 330 + 1F + 100 + AcDbEntity + 8 + 0 + 100 + AcDbBlockEnd + 0 + ENDSEC + 0 + SECTION + 2 + ENTITIES + } + } + li:footer { + verbatim { + 0 + ENDSEC + 0 + SECTION + 2 + OBJECTS + 0 + DICTIONARY + 5 + C + 330 + 0 + 100 + AcDbDictionary + 281 + 1 + 3 + ACAD_GROUP + 350 + D + 0 + DICTIONARY + 5 + D + 330 + C + 100 + AcDbDictionary + 281 + 1 + 0 + ENDSEC + 0 + EOF + } + } + } +} Index: tags/2.3.0/src_plugins/export_dxf/export_dxf.pup =================================================================== --- tags/2.3.0/src_plugins/export_dxf/export_dxf.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_dxf/export_dxf.pup (revision 33253) @@ -0,0 +1,9 @@ +$class export +$short DXF pcb_exporter +$long Export dxf +$state works +$fmt-native no +$fmt-feature-w .dxf (2D drawing for mech CADs) +$package export +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_dxf/lht_template.c =================================================================== --- tags/2.3.0/src_plugins/export_dxf/lht_template.c (nonexistent) +++ tags/2.3.0/src_plugins/export_dxf/lht_template.c (revision 33253) @@ -0,0 +1,129 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Generate output using a lihata template */ + +#ifndef TESTER +#include "config.h" +#endif + + +#include +#include +#include +#include +#include +#include +#include "lht_template.h" + +static void verbatim(FILE *f, const char *prefix, const char *value, int trim_indent) +{ + const char *s, *next; + int indent_len = 0; + if (*value == '\n') + value++; + + if (trim_indent) + for(s = value; isspace(*s); s++) + indent_len++; + + for(s = value; *s != '\0'; s = next) { + if (trim_indent) { + int n; + for(n = 0; (n < indent_len) && (isspace(*s)); n++) s++; + } + next = strpbrk(s, "\r\n"); + if (next == NULL) { + fprintf(f, "%s%s", prefix, s); + break; + } + while((*next == '\r') || (*next == '\n')) next++; + fprintf(f, "%s", prefix); + fwrite(s, 1, next-s, f); + } +} + +int lht_temp_exec(FILE *f, const char *prefix, lht_doc_t *doc, const char *name, lht_temp_insert_t ins, lht_err_t *err) +{ + lht_node_t *t, *n, *cfg; + int trim_indent = 0; + + if (prefix == NULL) + prefix = ""; + + t = lht_tree_path(doc, "/template", name, 1, err); + if (t == NULL) + return -1; + + if (t->type != LHT_LIST) { + *err = LHTE_INVALID_TYPE; + return -1; + } + + cfg = lht_tree_path(doc, "/", "trim_indent", 1, NULL); + if ((cfg != NULL) && (cfg->type == LHT_TEXT) && (cfg->data.text.value != NULL)) + trim_indent = ((strcmp(cfg->data.text.value, "1") == 0) || (strcmp(cfg->data.text.value, "yes") == 0) || (strcmp(cfg->data.text.value, "true") == 0)); + + for(n = t->data.list.first; n != NULL; n = n->next) { + if (strcmp(n->name, "verbatim") == 0) + verbatim(f, prefix, n->data.text.value, trim_indent); + if (strcmp(n->name, "insert") == 0) { + int res = ins(f, prefix, n->data.text.value, err); + if (res != 0) + return res; + } + } + + return 0; +} + +#ifdef TESTER +int ins_(FILE *f, const char *prefix, char *name, lht_err_t *err) +{ + printf("INSERT: %s\n", name); + return 0; +} + +int main() +{ + lht_doc_t *doc; + lht_err_t err; + char *errmsg; + const char *fn = "dxf_templ.lht"; + + /* do not do safe_fs here - it's just a test code that never ends up in pcb_rnd */ + doc = lht_dom_load(fn, &errmsg); + if (doc == NULL) { + fprintf(stderr, "Error loading %s: %s\n", fn, errmsg); + exit(1); + } + + lht_temp_exec(stdout, "", doc, "header", ins_, &err); + + lht_dom_uninit(doc); + return 0; +} +#endif Index: tags/2.3.0/src_plugins/export_dxf/lht_template.h =================================================================== --- tags/2.3.0/src_plugins/export_dxf/lht_template.h (nonexistent) +++ tags/2.3.0/src_plugins/export_dxf/lht_template.h (revision 33253) @@ -0,0 +1,10 @@ +#ifndef PCB_LHT_TEMPLATE_H +#define PCB_LHT_TEMPLATE_H +#include +#include + +typedef int (*lht_temp_insert_t)(FILE *f, const char *prefix, char *name, lht_err_t *err); + +int lht_temp_exec(FILE *f, const char *prefix, lht_doc_t *doc, const char *name, lht_temp_insert_t ins, lht_err_t *err); + +#endif Index: tags/2.3.0/src_plugins/export_excellon/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_excellon/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_excellon/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_gerber + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_excellon/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_excellon/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_excellon/Plug.tmpasm (revision 33253) @@ -0,0 +1,13 @@ +put /local/pcb/mod {export_excellon} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/export_excellon/aperture.o + $(PLUGDIR)/export_excellon/excellon.o +@] +put /local/pcb/mod/CONF {$(PLUGDIR)/export_excellon/excellon_conf.h} + + +switch /local/pcb/export_excellon/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_excellon/aperture.c =================================================================== --- tags/2.3.0/src_plugins/export_excellon/aperture.c (nonexistent) +++ tags/2.3.0/src_plugins/export_excellon/aperture.c (revision 33253) @@ -0,0 +1,111 @@ + +#include "config.h" + +#include +#include + +#include + +#define GVT_DONT_UNDEF +#include "aperture.h" +#include + +void init_aperture_list(aperture_list_t *list) +{ + list->data = NULL; + list->aperture_count_default = list->count = 0; + list->aperture_count = &list->aperture_count_default; +} + +void uninit_aperture_list(aperture_list_t *list) +{ + aperture_t *search = list->data; + aperture_t *next; + while (search) { + next = search->next; + free(search); + search = next; + } + init_aperture_list(list); +} + +aperture_t *add_aperture(aperture_list_t *list, rnd_coord_t width, aperture_shape_t shape) +{ + aperture_t *app = (aperture_t *) malloc(sizeof *app); + if (app == NULL) + return NULL; + + app->width = width; + app->shape = shape; + app->dCode = DCODE_BASE + (*list->aperture_count)++; + app->next = list->data; + + list->data = app; + ++list->count; + + return app; +} + +aperture_t *find_aperture(aperture_list_t *list, rnd_coord_t width, aperture_shape_t shape) +{ + aperture_t *search; + + /* we never draw zero-width lines */ + if (width == 0) + return NULL; + + /* Search for an appropriate aperture. */ + for (search = list->data; search; search = search->next) + if (search->width == width && search->shape == shape) + return search; + + /* Failing that, create a new one */ + return add_aperture(list, width, shape); +} + + +/*** drill ***/ + +void pcb_drill_init(pcb_drill_ctx_t *ctx, int *aper_cnt) +{ + vtpdr_init(&ctx->obj); + init_aperture_list(&ctx->apr); + if (aper_cnt != NULL) + ctx->apr.aperture_count = aper_cnt; +} + +void pcb_drill_uninit(pcb_drill_ctx_t *ctx) +{ + vtpdr_uninit(&ctx->obj); + uninit_aperture_list(&ctx->apr); +} + +pcb_pending_drill_t *pcb_drill_new_pending(pcb_drill_ctx_t *ctx, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t diam) +{ + pcb_pending_drill_t *pd = vtpdr_alloc_append(&ctx->obj, 1); + + pd->x = x1; + pd->y = y1; + pd->x2 = x2; + pd->y2 = y2; + pd->diam = diam; + pd->is_slot = (x1 != x2) || (y1 != y2); + find_aperture(&ctx->apr, diam, ROUND); + return pd; +} + +static int drill_sort_cb(const void *va, const void *vb) +{ + pcb_pending_drill_t *a = (pcb_pending_drill_t *)va; + pcb_pending_drill_t *b = (pcb_pending_drill_t *)vb; + if (a->diam != b->diam) + return a->diam - b->diam; + if (a->x != b->x) + return a->x - a->x; + return b->y - b->y; +} + +void pcb_drill_sort(pcb_drill_ctx_t *ctx) +{ + qsort(ctx->obj.array, ctx->obj.used, sizeof(ctx->obj.array[0]), drill_sort_cb); +} Index: tags/2.3.0/src_plugins/export_excellon/aperture.h =================================================================== --- tags/2.3.0/src_plugins/export_excellon/aperture.h (nonexistent) +++ tags/2.3.0/src_plugins/export_excellon/aperture.h (revision 33253) @@ -0,0 +1,76 @@ +#ifndef PCB_APERTURE_H +#define PCB_APERTURE_H + +/*** generic aperture ***/ + +enum aperture_shape_e { + ROUND, /* Shaped like a circle */ + OCTAGON, /* octagonal shape */ + SQUARE /* Shaped like a square */ +}; +typedef enum aperture_shape_e aperture_shape_t; + +/* This is added to the global aperture array indexes to get gerber + dcode and macro numbers. */ +#define DCODE_BASE 11 + +typedef struct aperture { + int dCode; /* The RS-274X D code */ + rnd_coord_t width; /* Size in pcb units */ + aperture_shape_t shape; /* ROUND/SQUARE etc */ + struct aperture *next; +} aperture_t; + +typedef struct { + aperture_t *data; + int count; + int aperture_count_default, *aperture_count; +} aperture_list_t; + +void init_aperture_list(aperture_list_t *list); +void uninit_aperture_list(aperture_list_t *list); + +/* Create and add a new aperture to the list */ +aperture_t *add_aperture(aperture_list_t *list, rnd_coord_t width, aperture_shape_t shape); + +/* Fetch an aperture from the list with the specified + * width/shape, creating a new one if none exists */ +aperture_t *find_aperture(aperture_list_t *list, rnd_coord_t width, aperture_shape_t shape); + +/*** drill ***/ + +typedef struct { + rnd_coord_t diam; + rnd_coord_t x; + rnd_coord_t y; + + /* for slots */ + int is_slot; + rnd_coord_t x2; + rnd_coord_t y2; +} pcb_pending_drill_t; + +#define GVT(x) vtpdr_ ## x +#define GVT_ELEM_TYPE pcb_pending_drill_t +#define GVT_SIZE_TYPE size_t +#define GVT_DOUBLING_THRS 2048 +#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 pcb_drill_ctx_s { + vtpdr_t obj; + aperture_list_t apr; +} pcb_drill_ctx_t; + +void pcb_drill_init(pcb_drill_ctx_t *ctx, int *aper_cnt); +void pcb_drill_uninit(pcb_drill_ctx_t *ctx); +pcb_pending_drill_t *pcb_drill_new_pending(pcb_drill_ctx_t *ctx, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t diam); +void pcb_drill_sort(pcb_drill_ctx_t *ctx); + +#endif Index: tags/2.3.0/src_plugins/export_excellon/excellon.c =================================================================== --- tags/2.3.0/src_plugins/export_excellon/excellon.c (nonexistent) +++ tags/2.3.0/src_plugins/export_excellon/excellon.c (revision 33253) @@ -0,0 +1,537 @@ +#include "config.h" + +#include "board.h" +#include +#include +#include +#include +#include "draw.h" +#include +#include "layer.h" +#include "layer_vis.h" +#include +#include +#include "hid_cam.h" +#include +#include +#include +#include "funchash_core.h" +#include "conf_core.h" +#include +#include "excellon_conf.h" + +#include "excellon.h" + +conf_excellon_t conf_excellon; + +static int exc_aperture_cnt; + +#define excellonDrX(pcb, x) ((rnd_coord_t) (x)) +#define excellonDrY(pcb, y) ((rnd_coord_t) ((pcb)->hidlib.size_y - (y))) + +typedef struct { + const char *hdr1; + const char *cfmt; /* drawing coordinate format */ + const char *afmt; /* aperture description format */ +} coord_format_t; + +static coord_format_t coord_format[] = { + {"INCH", "%06.0mk", "%.3mi"}, /* decimil: inch in 00.0000 format, implicit leading-zero (LZ); max board size: 99 inch (2514mm) */ + {"METRIC,000.000", "%03.3mm", "%.6mm"}, /* micron: mm in 000.0000 format, implicit leading-zero (LZ); max board size: 999mm */ + {"METRIC,0000.00", "%04.2mm", "%.5mm"}, /* micron: mm in 000.0000 format, implicit leading-zero (LZ); max board size: 9999mm */ +}; +#define NUM_COORD_FORMATS (sizeof(coord_format)/sizeof(coord_format[0])) + +static const char *coord_format_names[NUM_COORD_FORMATS+1] = { + "decimil", + "um", + "10um", + NULL +}; + + +static rnd_cardinal_t drill_print_objs(pcb_board_t *pcb, FILE *f, pcb_drill_ctx_t *ctx, int force_g85, int slots, rnd_coord_t *excellon_last_tool_dia) +{ + rnd_cardinal_t i, cnt = 0; + int first = 1; + + for (i = 0; i < ctx->obj.used; i++) { + pcb_pending_drill_t *pd = &ctx->obj.array[i]; + if (slots != (!!pd->is_slot)) + continue; + if (i == 0 || pd->diam != *excellon_last_tool_dia) { + aperture_t *ap = find_aperture(&ctx->apr, pd->diam, ROUND); + if (ap == NULL) { + rnd_message(RND_MSG_ERROR, "excellon: internal error: can't register ROUND aperture of dia %$mm\n", pd->diam); + continue; + } + fprintf(f, "T%02d\r\n", ap->dCode); + *excellon_last_tool_dia = pd->diam; + } + if (pd->is_slot) { + if (first) { + rnd_fprintf(f, "G00"); + first = 0; + } + if (force_g85) + rnd_fprintf(f, "X%[3]Y%[3]G85X%[3]Y%[3]\r\n", excellonDrX(pcb, pd->x), excellonDrY(PCB, pd->y), excellonDrX(pcb, pd->x2), excellonDrY(PCB, pd->y2)); + else + rnd_fprintf(f, "X%[3]Y%[3]\r\nM15\r\nG01X%[3]Y%[3]\r\nM17\r\n", excellonDrX(pcb, pd->x), excellonDrY(PCB, pd->y), excellonDrX(pcb, pd->x2), excellonDrY(PCB, pd->y2)); + first = 1; /* each new slot will need a G00 for some fabs that ignore M17 and M15 */ + } + else { + if (first) { + rnd_fprintf(f, "G05\r\n"); + first = 0; + } + rnd_fprintf(f, "X%[3]Y%[3]\r\n", excellonDrX(pcb, pd->x), excellonDrY(pcb, pd->y)); + } + cnt++; + } + return cnt; +} + +static rnd_cardinal_t drill_print_holes(pcb_board_t *pcb, FILE *f, pcb_drill_ctx_t *ctx, int force_g85, const char *coord_fmt_hdr) +{ + aperture_t *search; + rnd_cardinal_t cnt = 0; + rnd_coord_t excellon_last_tool_dia = 0; + + /* We omit the ,TZ here because we are not omitting trailing zeros. Our format is + always six-digit 0.1 mil resolution (i.e. 001100 = 0.11") */ + fprintf(f, "M48\r\n%s\r\n", coord_fmt_hdr); + for (search = ctx->apr.data; search; search = search->next) + rnd_fprintf(f, "T%02dC%[2]\r\n", search->dCode, search->width); + fprintf(f, "%%\r\n"); + + /* dump pending drills in sequence */ + pcb_drill_sort(ctx); + cnt += drill_print_objs(pcb, f, ctx, force_g85, 0, &excellon_last_tool_dia); + cnt += drill_print_objs(pcb, f, ctx, force_g85, 1, &excellon_last_tool_dia); + return cnt; +} + +void pcb_drill_export_excellon(pcb_board_t *pcb, pcb_drill_ctx_t *ctx, int force_g85, int coord_fmt_idx, const char *fn) +{ + FILE *f = rnd_fopen_askovr(&PCB->hidlib, fn, "wb", NULL); /* Binary needed to force CR-LF */ + coord_format_t *cfmt; + + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Error: Could not open %s for writing the excellon file.\n", fn); + return; + } + + if ((coord_fmt_idx < 0) || (coord_fmt_idx >= NUM_COORD_FORMATS)) { + rnd_message(RND_MSG_ERROR, "Error: Invalid excellon coordinate format idx %d.\n", coord_fmt_idx); + return; + } + + cfmt = &coord_format[coord_fmt_idx]; + rnd_printf_slot[3] = cfmt->cfmt; + rnd_printf_slot[2] = cfmt->afmt; + + if (ctx->obj.used > 0) + drill_print_holes(pcb, f, ctx, force_g85, cfmt->hdr1); + + fprintf(f, "M30\r\n"); + fclose(f); +} + +/*** HID ***/ +static rnd_hid_t excellon_hid; +static const char *excellon_cookie = "excellon drill/cnc exporter"; + +#define SUFF_LEN 32 + +/* global exporter states */ +static int is_plated, finding_apertures, exc_aperture_cnt; +static pcb_drill_ctx_t pdrills, udrills; +static pcb_cam_t excellon_cam; +static rnd_coord_t lastwidth; +static char *filename = NULL; +static struct { + unsigned nonround:1; + unsigned arc:1; + unsigned poly:1; + unsigned comp:1; +} warn; + +typedef struct rnd_hid_gc_s { + rnd_core_gc_t core_gc; + rnd_cap_style_t style; + rnd_coord_t width; +} rnd_hid_gc_s; + +static long exc_drawn_objs; + +static rnd_export_opt_t excellon_options[] = { + +/* %start-doc options "90 excellon Export" +@ftable @code +@item --excellonfile +excellon output file prefix. Can include a path. +@end ftable +%end-doc +*/ + {"filename", "excellon output file base - used to generate default plated and/or unplated file name in case they are not specified", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_excellonfile 0 + + {"filename-plated", "excellon output file name for plated features", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_excellonfile_plated 1 + + {"filename-unplated", "excellon output file name for unplated features", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_excellonfile_unplated 2 + + {"coord-format", "Coordinate format (resolution)", + RND_HATT_ENUM, 0, 0, {0, 0, 0}, coord_format_names, 0}, +#define HA_excellonfile_coordfmt 3 + + {"aperture-per-file", "Restart aperture numbering in each new file", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_apeture_per_file 4 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 5 +}; + +#define NUM_OPTIONS (sizeof(excellon_options)/sizeof(excellon_options[0])) + +static rnd_hid_attr_val_t excellon_values[NUM_OPTIONS]; + +static rnd_export_opt_t *excellon_get_export_options(rnd_hid_t *hid, int *n) +{ + if ((PCB != NULL) && (excellon_options[HA_excellonfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &excellon_options[HA_excellonfile], ""); + + if (n) + *n = NUM_OPTIONS; + return excellon_options; +} + +static void excellon_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + const char *fnbase, *fn; + char *filesuff; + int i; + int save_ons[PCB_MAX_LAYER]; + rnd_hid_expose_ctx_t ctx; + rnd_xform_t xform; + + if (!options) { + excellon_get_export_options(hid, NULL); + for (i = 0; i < NUM_OPTIONS; i++) + excellon_values[i] = excellon_options[i].default_val; + options = excellon_values; + } + pcb_drill_init(&pdrills, options[HA_apeture_per_file].lng ? NULL : &exc_aperture_cnt); + pcb_drill_init(&udrills, options[HA_apeture_per_file].lng ? NULL : &exc_aperture_cnt); + memset(&warn, 0, sizeof(warn)); + + exc_drawn_objs = 0; + pcb_cam_begin(PCB, &excellon_cam, &xform, options[HA_cam].str, excellon_options, NUM_OPTIONS, options); + + fnbase = options[HA_excellonfile].str; + if (!fnbase) + fnbase = "pcb-out"; + + i = strlen(fnbase); + filename = (char *) realloc(filename, i + SUFF_LEN); + strcpy(filename, fnbase); + filesuff = filename + strlen(filename); + + if (!excellon_cam.active) + pcb_hid_save_and_show_layer_ons(save_ons); + + ctx.view.X1 = 0; + ctx.view.Y1 = 0; + ctx.view.X2 = PCB->hidlib.size_x; + ctx.view.Y2 = PCB->hidlib.size_y; + + lastwidth = -1; + finding_apertures = 1; + rnd_expose_main(&excellon_hid, &ctx, &xform); + + lastwidth = -1; + finding_apertures = 0; + rnd_expose_main(&excellon_hid, &ctx, &xform); + rnd_conf_update(NULL, -1); /* resotre forced sets */ + + + if (excellon_cam.active) { + fn = excellon_cam.fn; + pcb_drill_export_excellon(PCB, &pdrills, conf_excellon.plugins.export_excellon.plated_g85_slot, options[HA_excellonfile_coordfmt].lng, fn); + } + else { + if (options[HA_excellonfile_plated].str == NULL) { + strcpy(filesuff, ".plated.cnc"); + fn = filename; + } + else + fn = options[HA_excellonfile_plated].str; + pcb_drill_export_excellon(PCB, &pdrills, conf_excellon.plugins.export_excellon.plated_g85_slot, options[HA_excellonfile_coordfmt].lng, fn); + + if (options[HA_excellonfile_unplated].str == NULL) { + strcpy(filesuff, ".unplated.cnc"); + fn = filename; + } + else + fn = options[HA_excellonfile_unplated].str; + pcb_drill_export_excellon(PCB, &udrills, conf_excellon.plugins.export_excellon.unplated_g85_slot, options[HA_excellonfile_coordfmt].lng, fn); + } + + if (!excellon_cam.active) excellon_cam.okempty_content = 1; /* never warn in direct export */ + + if (pcb_cam_end(&excellon_cam) == 0) { + if (!excellon_cam.okempty_group) + rnd_message(RND_MSG_ERROR, "excellon cam export for '%s' failed to produce any content (layer group missing)\n", options[HA_cam].str); + } + else if (exc_drawn_objs == 0) { + if (!excellon_cam.okempty_content) + rnd_message(RND_MSG_ERROR, "excellon cam export for '%s' failed to produce any content (no objects)\n", options[HA_cam].str); + } + + pcb_drill_uninit(&pdrills); + pcb_drill_uninit(&udrills); +} + + +static int excellon_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(excellon_options, NUM_OPTIONS, excellon_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int excellon_set_layer_group(rnd_hid_t *hid, 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) +{ + int is_drill; + + /* before cam lets this happen... */ + if (PCB_LAYER_IS_ASSY(flags, purpi)) + return 0; + + pcb_cam_set_layer_group(&excellon_cam, group, purpose, purpi, flags, xform); + + if (flags & PCB_LYT_UI) + return 0; + + is_drill = PCB_LAYER_IS_DRILL(flags, purpi) || ((flags & PCB_LYT_MECH) && PCB_LAYER_IS_ROUTE(flags, purpi)); + if (!is_drill) + return 0; + + is_plated = PCB_LAYER_IS_PROUTE(flags, purpi) || PCB_LAYER_IS_PDRILL(flags, purpi); + return 1; +} + +static rnd_hid_gc_t excellon_make_gc(rnd_hid_t *hid) +{ + rnd_hid_gc_t rv = calloc(1, sizeof(*rv)); + return rv; +} + +static void excellon_destroy_gc(rnd_hid_gc_t gc) +{ + free(gc); +} + +static void excellon_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *drw_screen) +{ + switch(op) { + case RND_HID_COMP_RESET: + case RND_HID_COMP_POSITIVE: + case RND_HID_COMP_FLUSH: + break; + + case RND_HID_COMP_POSITIVE_XOR: + case RND_HID_COMP_NEGATIVE: + if (!warn.comp) { + warn.comp = 1; + rnd_message(RND_MSG_ERROR, "Excellon: can not draw composite layers (some features may be missing from the export)\n"); + } + } +} + +static void excellon_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ +} + +static void excellon_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + gc->style = style; +} + +static void excellon_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + gc->width = width; +} + +static void excellon_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ +} + +pcb_drill_ctx_t *get_drill_ctx(void) +{ + if (excellon_cam.active) + return &pdrills; + + return (is_plated ? &pdrills : &udrills); +} + +static void use_gc(rnd_hid_gc_t gc, rnd_coord_t radius) +{ + exc_drawn_objs++; + if ((gc->style != rnd_cap_round) && (!warn.nonround)) { + warn.nonround = 1; + rnd_message(RND_MSG_ERROR, "Excellon: can not set non-round aperture (some features may be missing from the export)\n"); + } + + if (radius == 0) + radius = gc->width; + else + radius *= 2; + + if (radius != lastwidth) { + aperture_t *aptr = find_aperture(&(get_drill_ctx()->apr), radius, ROUND); + if (aptr == NULL) + rnd_fprintf(stderr, "error: aperture for radius %$mS type ROUND is null\n", radius); + lastwidth = radius; + } +} + + +static void excellon_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_coord_t dia = gc->width/2; + + find_aperture(&(get_drill_ctx()->apr), dia*2, ROUND); + + if (!finding_apertures) + pcb_drill_new_pending(get_drill_ctx(), x1, y1, x2, y2, dia*2); +} + +static void excellon_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + excellon_draw_line(gc, x1, y1, x1, y2); + excellon_draw_line(gc, x1, y1, x2, y1); + excellon_draw_line(gc, x1, y2, x2, y2); + excellon_draw_line(gc, x2, y1, x2, y2); +} + +static void excellon_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) +{ + if (!warn.arc) { + warn.arc = 1; + rnd_message(RND_MSG_ERROR, "Excellon: can not export arcs (some features may be missing from the export)\n"); + } +} + +static void excellon_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + if (radius <= 0) + return; + + radius = 50 * rnd_round(radius / 50.0); + use_gc(gc, radius); + if (!finding_apertures) + pcb_drill_new_pending(get_drill_ctx(), cx, cy, cx, cy, radius * 2); +} + +static void excellon_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) +{ + if (!warn.poly) { + warn.poly = 1; + rnd_message(RND_MSG_ERROR, "Excellon: can not export polygons (some features may be missing from the export)\n"); + } +} + +static void excellon_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + excellon_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + + +static void excellon_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + excellon_fill_polygon(gc, 0, NULL, NULL); +} + +static void excellon_calibrate(rnd_hid_t *hid, double xval, double yval) +{ + rnd_message(RND_MSG_ERROR, "Excellon internal error: can not calibrate()\n"); +} + +static int excellon_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nexcellon exporter command line arguments:\n\n"); + rnd_hid_usage(excellon_options, sizeof(excellon_options) / sizeof(excellon_options[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x excellon [excellon options] foo.pcb\n\n"); + return 0; +} + +static void excellon_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int action) +{ +} + +static void exc_session_begin(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + exc_aperture_cnt = 0; +} + +int pplg_check_ver_export_excellon(int ver_needed) { return 0; } + +void pplg_uninit_export_excellon(void) +{ + rnd_export_remove_opts_by_cookie(excellon_cookie); + free(filename); + rnd_conf_unreg_fields("plugins/export_excellon/"); + rnd_event_unbind_allcookie(excellon_cookie); + rnd_hid_remove_hid(&excellon_hid); +} + +int pplg_init_export_excellon(void) +{ + RND_API_CHK_VER; + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_excellon, field,isarray,type_name,cpath,cname,desc,flags); +#include "excellon_conf_fields.h" + + memset(&excellon_hid, 0, sizeof(excellon_hid)); + + rnd_hid_nogui_init(&excellon_hid); + + excellon_hid.struct_size = sizeof(excellon_hid); + excellon_hid.name = "excellon"; + excellon_hid.description = "excellon drill/boundary export"; + excellon_hid.exporter = 1; + + excellon_hid.get_export_options = excellon_get_export_options; + excellon_hid.do_export = excellon_do_export; + excellon_hid.parse_arguments = excellon_parse_arguments; + excellon_hid.set_layer_group = excellon_set_layer_group; + excellon_hid.make_gc = excellon_make_gc; + excellon_hid.destroy_gc = excellon_destroy_gc; + excellon_hid.set_drawing_mode = excellon_set_drawing_mode; + excellon_hid.set_color = excellon_set_color; + excellon_hid.set_line_cap = excellon_set_line_cap; + excellon_hid.set_line_width = excellon_set_line_width; + excellon_hid.set_draw_xor = excellon_set_draw_xor; + excellon_hid.draw_line = excellon_draw_line; + excellon_hid.draw_arc = excellon_draw_arc; + excellon_hid.draw_rect = excellon_draw_rect; + excellon_hid.fill_circle = excellon_fill_circle; + excellon_hid.fill_polygon = excellon_fill_polygon; + excellon_hid.fill_polygon_offs = excellon_fill_polygon_offs; + excellon_hid.fill_rect = excellon_fill_rect; + excellon_hid.calibrate = excellon_calibrate; + excellon_hid.set_crosshair = excellon_set_crosshair; + excellon_hid.usage = excellon_usage; + + rnd_hid_register_hid(&excellon_hid); + + rnd_event_bind(RND_EVENT_EXPORT_SESSION_BEGIN, exc_session_begin, NULL, excellon_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/export_excellon/excellon.h =================================================================== --- tags/2.3.0/src_plugins/export_excellon/excellon.h (nonexistent) +++ tags/2.3.0/src_plugins/export_excellon/excellon.h (revision 33253) @@ -0,0 +1,12 @@ +#ifndef PCB_DRILL_H +#define PCB_DRILL_H + +#include "aperture.h" + +void pcb_drill_export_excellon(pcb_board_t *pcb, pcb_drill_ctx_t *ctx, int force_g85, int coord_fmt_idx, const char *fn); + +int pplg_check_ver_export_excellon(int ver_needed); +void pplg_uninit_export_excellon(void); +int pplg_init_export_excellon(void); + +#endif Index: tags/2.3.0/src_plugins/export_excellon/excellon_conf.h =================================================================== --- tags/2.3.0/src_plugins/export_excellon/excellon_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/export_excellon/excellon_conf.h (revision 33253) @@ -0,0 +1,15 @@ +#ifndef PCB_EXCELLON_CONF_H +#define PCB_EXCELLON_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN plated_g85_slot; /* use G85 (drill cycle instead of route) for plated slots */ + RND_CFT_BOOLEAN unplated_g85_slot; /* use G85 (drill cycle instead of route) for unplated slots */ + } export_excellon; + } plugins; +} conf_excellon_t; + +#endif Index: tags/2.3.0/src_plugins/export_excellon/export_excellon.pup =================================================================== --- tags/2.3.0/src_plugins/export_excellon/export_excellon.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_excellon/export_excellon.pup (revision 33253) @@ -0,0 +1,9 @@ +$class export +$short Excellon drill exporter +$long Export to excellon drill/cnc files +$state works +$fmt-native no +$fmt-feature-w excellon drill/cnc (for PCB fabbing) +$package export +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_fidocadj/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_fidocadj/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_fidocadj/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_fidocadj + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_fidocadj/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_fidocadj/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_fidocadj/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {export_fidocadj} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_fidocadj/fidocadj.o @] + +switch /local/pcb/export_fidocadj/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_fidocadj/export_fidocadj.pup =================================================================== --- tags/2.3.0/src_plugins/export_fidocadj/export_fidocadj.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_fidocadj/export_fidocadj.pup (revision 33253) @@ -0,0 +1,10 @@ +$class export +$short FidoCadJ .fcd pcb_exporter +$long Export to FidoCadJ format (.fcd) +$state WIP +$fmt-native no +$fmt-feature-w fidocad .fcd (partial export) +$package export-extra +dep lib_compat_help +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_fidocadj/fidocadj.c =================================================================== --- tags/2.3.0/src_plugins/export_fidocadj/fidocadj.c (nonexistent) +++ tags/2.3.0/src_plugins/export_fidocadj/fidocadj.c (revision 33253) @@ -0,0 +1,393 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* + * Based on the png exporter by Dan McMahill + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "genht/htsi.h" + +#include +#include "board.h" +#include "data.h" +#include "layer_vis.h" +#include +#include +#include +#include "plug_io.h" +#include + +#include +#include + +#include +#include +#include "hid_cam.h" + +#include "../src_plugins/lib_compat_help/pstk_compat.h" + +static rnd_hid_t fidocadj_hid; + +const char *fidocadj_cookie = "fidocadj HID"; + +rnd_export_opt_t fidocadj_attribute_list[] = { + /* other HIDs expect this to be first. */ + + {"outfile", "Output file name", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_fidocadjfile 0 + + {"libfile", "path to PCB.fcl", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_libfile 1 +}; + +#define NUM_OPTIONS (sizeof(fidocadj_attribute_list)/sizeof(fidocadj_attribute_list[0])) + +static rnd_hid_attr_val_t fidocadj_values[NUM_OPTIONS]; + +static rnd_export_opt_t *fidocadj_get_export_options(rnd_hid_t *hid, int *n) +{ + const char *suffix = ".fcd"; + + if ((PCB != NULL) && (fidocadj_attribute_list[HA_fidocadjfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &fidocadj_attribute_list[HA_fidocadjfile], suffix); + + if (n) + *n = NUM_OPTIONS; + return fidocadj_attribute_list; +} + +/* index PCB.fcl so we have a list of known fidocadj footprints */ +static int load_lib(htsi_t *ht, const char *fn) +{ + FILE *f; + char line[1024]; + f = rnd_fopen(&PCB->hidlib, fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can't open fidocadj PCB library file '%s' for read\n", fn); + return -1; + } + *line = '\0'; + fgets(line, sizeof(line), f); + if (rnd_strncasecmp(line, "[FIDOLIB PCB Footprints]", 24) != 0) { + rnd_message(RND_MSG_ERROR, "'%s' doesn't have the fidocadj lib header\n", fn); + fclose(f); + return -1; + } + while(fgets(line, sizeof(line), f) != NULL) { + char *end, *s = line; + + if (*line != '[') + continue; + + s++; + end = strchr(s, ' '); + if (end != NULL) { + *end = '\0'; + htsi_set(ht, rnd_strdup(s), 1); + } + } + fclose(f); + return 0; +} + +static long int crd(rnd_coord_t c) +{ + return rnd_round((double)RND_COORD_TO_MIL(c) / 5.0); +} + +static int layer_map(unsigned int lflg, int *fidoly_next, const char *lyname) +{ + if (lflg & PCB_LYT_COPPER) { + if (lflg & PCB_LYT_BOTTOM) + return 1; + if (lflg & PCB_LYT_TOP) + return 2; + } + if (lflg & PCB_LYT_SILK) + return 3; + + (*fidoly_next)++; + if (*fidoly_next > 15) { + char *msg = rnd_strdup_printf("FidoCadJ can't handle this many layers - layer %s is not exported\n", lyname); + pcb_io_incompat_save(NULL, NULL, "layer", msg, NULL); + free(msg); + return -1; + } + return *fidoly_next; +} + +static void write_custom_subc(FILE *f, pcb_subc_t *sc) +{ + char *msg = rnd_strdup_printf("Can't export custom footprint for %s yet\n", sc->refdes); + pcb_io_incompat_save(sc->parent.data, (pcb_any_obj_t *)sc, msg, "subc", "subcircuit omitted - add the footprint type on the footprint list!"); + free(msg); +} + +static void fidocadj_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + FILE *f; + const char *filename, *libfile; + int n, fidoly_next, have_lib; + rnd_layer_id_t lid; + htsi_t lib_names; /* hash of names found in the library, if have_lib is 1 */ + + if (!options) { + fidocadj_get_export_options(hid, 0); + for (n = 0; n < NUM_OPTIONS; n++) + fidocadj_values[n] = fidocadj_attribute_list[n].default_val; + options = fidocadj_values; + } + + libfile = options[HA_libfile].str; + if ((libfile != NULL) && (*libfile != '\0')) { + htsi_init(&lib_names, strhash, strkeyeq); + have_lib = 1; + if (load_lib(&lib_names, libfile) != 0) + goto free_lib; + } + else + have_lib = 0; + + filename = options[HA_fidocadjfile].str; + if (!filename) + filename = "pcb-rnd-default.fcd"; + + f = rnd_fopen_askovr(&PCB->hidlib, filename, "w", NULL); + if (!f) { + perror(filename); + return; + } + + fprintf(f, "[FIDOCAD]\n"); + + fidoly_next = 3; + for(lid = 0; lid < pcb_max_layer(PCB); lid++) { + pcb_layer_t *ly = PCB->Data->Layer+lid; + unsigned int lflg = pcb_layer_flags(PCB, lid); + int fidoly = layer_map(lflg, &fidoly_next, ly->name); + + if (fidoly < 0) + continue; + + PCB_LINE_LOOP(ly) { + fprintf(f, "PL %ld %ld %ld %ld %ld %d\n", + crd(line->Point1.X), crd(line->Point1.Y), + crd(line->Point2.X), crd(line->Point2.Y), + crd(line->Thickness), fidoly); + } + PCB_END_LOOP; + + PCB_ARC_LOOP(ly) { +TODO(": fprintf() some curve using arc->*") + ; + } + PCB_END_LOOP; + + PCB_POLY_LOOP(ly) { + rnd_vnode_t *v; + rnd_pline_t *pl = polygon->Clipped->contours; + + if (polygon->HoleIndexN > 0) { + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)polygon, "polygon", "FidoCadJ can't handle holes in polygons, ignoring holes for this export", "(some of the polygons will look different unless you remove the holes or split up the polygons)"); + } + + fprintf(f, "PP %ld %ld", crd(pl->head->point[0]), crd(pl->head->point[1])); + v = pl->head->next; + do { + fprintf(f, " %ld %ld", crd(v->point[0]), crd(v->point[1])); + } while ((v = v->next) != pl->head->next); + fprintf(f, " %d\n", fidoly); + } + PCB_END_LOOP; + + PCB_TEXT_LOOP(ly) { + char *s; + /* default_font 'm' = 4189 wide + * default_font 'l', starts at y = 1000 + * default_font 'p','q', finish at y = 6333 + * default_font stroke thickness = 800 + * giving sx = (4189+800)/(5333+800) ~= 0.813 + */ + int scale, scret = pcb_text_old_scale(text, &scale); + rnd_coord_t x0 = text->X; + /*rnd_coord_t sx = text->BoundingBox.X2 - text->BoundingBox.X1; unused */ + rnd_coord_t y0 = text->Y; + /* rnd_coord_t sy = text->BoundingBox.Y2 - text->BoundingBox.Y1; unused */ + rnd_coord_t glyphy = 5789*(rnd_coord_t)scale; /* (ascent+descent)*Scale */ + rnd_coord_t glyphx = 813*(glyphy/1000); /* based on 'm' glyph dimensions */ + glyphy = 10*glyphy/7; /* empirically determined */ + glyphx = 10*glyphx/7; /* scaling voodoo */ + if (scret != 0) + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)text, "text-scale", "file format does not support different x and y direction text scale - using average scale", "Use the scale field, set scale_x and scale_y to 0"); + if (text->mirror_x) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-mirror-x", "file format does not support different mirroring text in the x direction", "do not mirror, or mirror in the y direction (with the ONSOLDER flag)"); + + /*switch(text->Direction) { + case 0: + x0 += sx; + break; + case 1: + y0 += sy; + break; + case 2: + x0 -= sx; + break; + case 3: + y0 -= sy; + break; + }*/ +TODO("textrot: can we exprot rotation with %f?") + fprintf(f, "TY %ld %ld %ld %ld %d 1 %d * ", /* 1 = bold */ + crd(x0), crd(y0), crd(glyphy), crd(glyphx), + (int)rnd_round(text->rot), fidoly); + for(s = text->TextString; *s != '\0'; s++) { + if (*s == ' ') + fprintf(f, "++"); + else + fputc(*s, f); + } + fputc('\n', f); + } + PCB_END_LOOP; + } + + PCB_PADSTACK_LOOP(PCB->Data) { + int oshape; + rnd_coord_t x, y, drill_dia, pad_dia, clearance, mask; + pcb_pstk_compshape_t cshape; + rnd_bool plated; + if (!pcb_pstk_export_compat_via(padstack, &x, &y, &drill_dia, &pad_dia, &clearance, &mask, &cshape, &plated)) { + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)padstack, "padstack-uniformity", "can't export non-uniform padstacl", "use a simpler padstack - omiting this one from the export"); + continue; + } + switch(cshape) { + case PCB_PSTK_COMPAT_OCTAGON: + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)padstack, "padstack-shape", "can't export octagonal shape", "use round or square instead; (fallback to round for now)"); + /* fall-through */ + case PCB_PSTK_COMPAT_ROUND: oshape = 0; break; + case PCB_PSTK_COMPAT_SQUARE: oshape = 1; break; /* rectangle with sharp corners */ + default: + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)padstack, "padstack-shape", "can't export shaped padstack", "use round or square instead; (fallback to round for now)"); + oshape = 0; + } + fprintf(f, "pa %ld %ld %ld %ld %ld %d\n", crd(x), crd(y), crd(pad_dia), crd(pad_dia), crd(drill_dia), oshape); + } + PCB_END_LOOP; + + PCB_SUBC_LOOP(PCB->Data) { + const char *fp = pcb_attribute_get(&subc->Attributes, "footprint"); + if ((fp != NULL) && have_lib && (htsi_get(&lib_names, fp))) { + rnd_coord_t x, y; + double rot = 0.0; + int on_bottom = 0; + if (pcb_subc_get_origin(subc, &x, &y)) { + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)subc, "subc", "can't figure subcircuit origin", "omitting this part until the proper subc-aux layer objects are added"); + continue; + } + pcb_subc_get_rotation(subc, &rot); + pcb_subc_get_side(subc, &on_bottom); + +TODO(": figure how to store rotation") +TODO(": figure how to store side") + fprintf(f, "MC %ld %ld %d 0 %s\n", crd(x), crd(y), 0, fp); + } + else + write_custom_subc(f, subc); + } + PCB_END_LOOP; + + + fclose(f); + + free_lib:; + if (have_lib) { + htsi_entry_t *e; + for (e = htsi_first(&lib_names); e; e = htsi_next(&lib_names, e)) + free(e->key); + + htsi_uninit(&lib_names); + } +} + +static int fidocadj_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(fidocadj_attribute_list, sizeof(fidocadj_attribute_list) / sizeof(fidocadj_attribute_list[0]), fidocadj_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int fidocadj_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nfidocadj exporter command line arguments:\n\n"); + rnd_hid_usage(fidocadj_attribute_list, sizeof(fidocadj_attribute_list) / sizeof(fidocadj_attribute_list[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x fidocadj [fidocadj options] foo.pcb\n\n"); + return 0; +} + +int pplg_check_ver_export_fidocadj(int ver_needed) { return 0; } + +void pplg_uninit_export_fidocadj(void) +{ + rnd_export_remove_opts_by_cookie(fidocadj_cookie); + rnd_hid_remove_hid(&fidocadj_hid); +} + +int pplg_init_export_fidocadj(void) +{ + RND_API_CHK_VER; + + memset(&fidocadj_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&fidocadj_hid); + + fidocadj_hid.struct_size = sizeof(rnd_hid_t); + fidocadj_hid.name = "fidocadj"; + fidocadj_hid.description = "export board in FidoCadJ .fcd format"; + fidocadj_hid.exporter = 1; + + fidocadj_hid.get_export_options = fidocadj_get_export_options; + fidocadj_hid.do_export = fidocadj_do_export; + fidocadj_hid.parse_arguments = fidocadj_parse_arguments; + + fidocadj_hid.usage = fidocadj_usage; + + rnd_hid_register_hid(&fidocadj_hid); + + return 0; +} Index: tags/2.3.0/src_plugins/export_gcode/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_gcode/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_gcode/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_gcode + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_gcode/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_gcode/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_gcode/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {export_gcode} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/export_gcode/gcode.o +@] + + +switch /local/pcb/export_gcode/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_gcode/export_gcode.pup =================================================================== --- tags/2.3.0/src_plugins/export_gcode/export_gcode.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_gcode/export_gcode.pup (revision 33253) @@ -0,0 +1,10 @@ +$class export +$short gcode pcb_exporter +$long Export to gcode +$state WIP +$fmt-native no +$fmt-feature-w export gcode (for milling) +$package export +default buildin +dep millpath +autoload 1 Index: tags/2.3.0/src_plugins/export_gcode/gcode.c =================================================================== --- tags/2.3.0/src_plugins/export_gcode/gcode.c (nonexistent) +++ tags/2.3.0/src_plugins/export_gcode/gcode.c (revision 33253) @@ -0,0 +1,428 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include "board.h" +#include +#include "funchash_core.h" +#include "layer.h" + +#include +#include + +#include +#include +#include "hid_cam.h" + +#include "../src_plugins/millpath/toolpath.h" + +const char *pcb_export_gcode_cookie = "export_gcode plugin"; + +static rnd_hid_t gcode_hid; + +typedef struct { + pcb_cam_t cam; + pcb_board_t *pcb; + FILE *f; /* output file */ + int passes; /* number of millings for a thru-cut - calculated for the header */ + pcb_layergrp_t *grp; /* layer group being exported */ + long drawn_objs; +} gcode_t; + +static gcode_t gctx; + +static const char def_layer_script[] = "setup_negative; trace_contour; fix_overcuts"; +static const char def_mech_script[] = "setup_positive; trace_contour; fix_overcuts"; + +rnd_export_opt_t gcode_attribute_list[] = { + {"outfile", "file name prefix for non-cam", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_outfile 0 + + {"dias", "tool diameters", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_template 1 + + {"layer-script", "rendering script for layer graphics", + RND_HATT_STRING, 0, 0, {0, def_layer_script, 0}, 0, 0}, +#define HA_layer_script 2 + + {"mech-script", "rendering script for boundary/mech/drill", + RND_HATT_STRING, 0, 0, {0, def_mech_script, 0}, 0, 0}, +#define HA_mech_script 3 + + {"mill-depth", "Milling depth on layers", + RND_HATT_COORD, RND_MM_TO_COORD(-10), RND_MM_TO_COORD(100), {0, 0, 0, RND_MM_TO_COORD(-0.05)}, 0}, +#define HA_layerdepth 4 + + {"total-cut-depth", "Total milling depth when cutting through the board (if 0, use pcb thickness)", + RND_HATT_COORD, RND_MM_TO_COORD(-10), RND_MM_TO_COORD(100), {0, 0, 0, RND_MM_TO_COORD(-1.6)}, 0}, +#define HA_totalcutdepth 5 + + {"cut-depth", "Milling depth increment in each pass", + RND_HATT_COORD, RND_MM_TO_COORD(-10), RND_MM_TO_COORD(100), {0, 0, 0, RND_MM_TO_COORD(0.5)}, 0}, +#define HA_cutdepth 6 + + {"safe-Z", "Safe Z (above the board) for traverse move", + RND_HATT_COORD, RND_MM_TO_COORD(-10), RND_MM_TO_COORD(100), {0, 0, 0, RND_MM_TO_COORD(0.5)}, 0}, +#define HA_safeZ 7 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 8 + +}; + +#define NUM_OPTIONS (sizeof(gcode_attribute_list)/sizeof(gcode_attribute_list[0])) + +static rnd_hid_attr_val_t gcode_values[NUM_OPTIONS]; + +static rnd_export_opt_t *gcode_get_export_options(rnd_hid_t *hid, int *n) +{ + if (n) + *n = NUM_OPTIONS; + return gcode_attribute_list; +} + +#define TX(x) (x) +#define TY_MIRROR(y) (gctx.pcb->hidlib.size_y - (y)) +#define TY_NORMAL(y) (y) +#define TY(y) (gctx.grp->ltype & PCB_LYT_BOTTOM ? TY_MIRROR(y) : TY_NORMAL(y)) + +static void gcode_print_lines_(pcb_line_t *from, pcb_line_t *to, int passes, int depth) +{ + pcb_line_t *l; + + gctx.drawn_objs++; + rnd_fprintf(gctx.f, "G0 Z#100\nG0 X%mm Y%mm\n", TX(from->Point1.X), TY(from->Point1.Y)); + + if (passes > 1) + fprintf(gctx.f, "(new path)\n"); + for(;;) { + /* mill from..to (forward) */ + fprintf(gctx.f, "G0 Z#%d\n", depth++); + for(l = from; l != to; l = l->link.next) + rnd_fprintf(gctx.f, "G1 X%mm Y%mm\n", TX(l->Point2.X), TY(l->Point2.Y)); + rnd_fprintf(gctx.f, "G1 X%mm Y%mm\n", TX(to->Point2.X), TY(to->Point2.Y)); + if (--passes <= 0) + break; + + /* if we are back where we normally start, just go on to the next loop... */ + if ((to->Point2.X == from->Point1.X) && (to->Point2.Y == from->Point1.Y)) { + fprintf(gctx.f, "(continue-loop one step deeper)\n"); + continue; + } + + /* ... else turn back to do it backward */ + fprintf(gctx.f, "(back-loop one step deeper)\n"); + /* mill to..from (backward) */ + fprintf(gctx.f, "G0 Z#%d\n", depth++); + for(l = to; l != from; l = l->link.prev) + rnd_fprintf(gctx.f, "G1 X%mm Y%mm\n", TX(l->Point1.X), TY(l->Point1.Y)); + rnd_fprintf(gctx.f, "G1 X%mm Y%mm\n", TX(from->Point1.X), TY(from->Point1.Y)); + if (--passes <= 0) + break; + } + +} + + +#define thru_start_depth 102 + +static void gcode_print_header(void) +{ + rnd_coord_t step = gcode_values[HA_cutdepth].crd; + rnd_coord_t total = gcode_values[HA_totalcutdepth].crd; + rnd_coord_t at = gcode_values[HA_layerdepth].crd; + + rnd_fprintf(gctx.f, "#100=%mm (safe Z for travels above the board)\n", gcode_values[HA_safeZ].crd); + rnd_fprintf(gctx.f, "#101=%mm (cutting depth for layers)\n", gcode_values[HA_layerdepth].crd); + + + if (step > 0) + step = -step; + else if (step == 0) { + rnd_message(RND_MSG_ERROR, "export_gcode: cut increment not configured - not exporting thru-cut layer\n"); + return; + } + + + if (total == 0) { + total = pcb_board_thickness(gctx.pcb, "gcode", PCB_BRDTHICK_PRINT_ERROR); + if (total == 0) { + rnd_message(RND_MSG_ERROR, "export_gcode: can't determine board thickness - not exporting thru-cut layer\n"); + return; + } + } + + for(gctx.passes = 0, at += step; at > total; gctx.passes++, at += step) + rnd_fprintf(gctx.f, "#%d=%mm (%s cutting depth for thru-cuts)\n", thru_start_depth+gctx.passes, at, gctx.passes == 0 ? "first" : "next"); + rnd_fprintf(gctx.f, "#%d=%mm (last cutting depth for thru-cuts)\n", thru_start_depth+gctx.passes, total); + gctx.passes++; + + rnd_fprintf(gctx.f, + "G17 " /* X-Y plane */ + "G21 " /* mm */ + "G90 " /* absolute coords */ + "G64 " /* best speed path */ + "M03 " /* spindle on, CW */ + "S3000 " /* spindle speed */ + "M07 " /* mist coolant on */ + "F1 " /* feed rate */ + "\n"); +} + +static void gcode_print_footer(void) +{ + rnd_fprintf(gctx.f, + "G0 Z#100\n" /* remove the tool from the board, just in case */ + "M05 " /* stop spindle */ + "M09 " /* coolant off */ + "M02\n" /* end */ + ); +} + + +static void gcode_print_lines(pcb_tlp_session_t *tctx, pcb_layergrp_t *grp, int thru) +{ + pcb_line_t *from = NULL, *to, *last_to = NULL; + gdl_iterator_t it; + rnd_coord_t lastx = RND_MAX_COORD, lasty = RND_MAX_COORD; + int start_depth, passes; + + if (tctx->res_path->Line.lst.length == 0) { + rnd_fprintf(gctx.f, "(empty layer group: %s)\n", grp->name); + return; + } + + if (thru) { + passes = gctx.passes; + start_depth = thru_start_depth; + } + else { + passes = 1; + start_depth = 101; + } + + from = linelist_first(&tctx->res_path->Line); + lastx = TX(from->Point2.X); + lasty = TY(from->Point2.Y); + linelist_foreach(&tctx->res_path->Line, &it, to) { + rnd_coord_t x1 = TX(to->Point1.X), y1 = TY(to->Point1.Y), x2 = TX(to->Point2.X), y2 = TY(to->Point2.Y); + if ((lastx != x1) && (lasty != y1)) { + if (to->link.prev == NULL) + gcode_print_lines_(from, from, passes, start_depth); /* corner case: first line is a stand-alone segment */ + else + gcode_print_lines_(from, to->link.prev, passes, start_depth); + from = to; + } + lastx = x2; + lasty = y2; + last_to = to; + } + gcode_print_lines_(from, last_to, passes, start_depth); + +} + +static int gcode_export_layer_group(rnd_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, rnd_xform_t **xform) +{ + int script_ha, thru; + const char *script; + pcb_layergrp_t *grp = &gctx.pcb->LayerGroups.grp[group]; + static pcb_tlp_session_t tctx; + static rnd_coord_t tool_dias[] = { + RND_MM_TO_COORD(0.2), + RND_MM_TO_COORD(3) + }; + static pcb_tlp_tools_t tools = { sizeof(tool_dias)/sizeof(tool_dias[0]), tool_dias}; + + + if (flags & PCB_LYT_UI) + return 0; + + pcb_cam_set_layer_group(&gctx.cam, group, purpose, purpi, flags, xform); + + if (!gctx.cam.active) { + /* in direct export do only mechanical and copper layer groups */ + if (!(flags & PCB_LYT_COPPER) && !(flags & PCB_LYT_BOUNDARY) && !(flags & PCB_LYT_MECH)) + return 0; + } + + if (!gctx.cam.active) { + const char *base = gcode_values[HA_outfile].str; + gds_t fn; + + if (base == NULL) base = gctx.pcb->hidlib.filename; + if (base == NULL) base = "unknown"; + + gds_init(&fn); + gds_append_str(&fn, base); + gds_append(&fn, '.'); + pcb_layer_to_file_name_append(&fn, layer, flags, purpose, purpi, PCB_FNS_pcb_rnd); + gds_append_str(&fn, ".cnc"); + + gctx.f = rnd_fopen_askovr(&gctx.pcb->hidlib, fn.array, "w", NULL); + if (gctx.f != NULL) + gcode_print_header(); + + gds_uninit(&fn); + } + + if (gctx.f == NULL) + return 0; + + if (PCB_LAYER_IS_ROUTE(flags, purpi) || PCB_LAYER_IS_DRILL(flags, purpi)) { + script_ha = HA_mech_script; + script = def_mech_script; + thru = 1; + } + else { + script_ha = HA_layer_script; + script = def_layer_script; + thru = 0; + } + + if (gcode_values[script_ha].str != NULL) + script = gcode_values[script_ha].str; + + memset(&tctx, 0, sizeof(tctx)); + tctx.edge_clearance = RND_MM_TO_COORD(0.05); + tctx.tools = &tools; + pcb_tlp_mill_script(gctx.pcb, &tctx, grp, script); + + gcode_print_lines(&tctx, grp, thru); + + if (!gctx.cam.active) { + gcode_print_footer(); + fclose(gctx.f); + } + return 0; +} + +static void gcode_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + int i; + rnd_layergrp_id_t gid; + rnd_xform_t xform; + pcb_board_t *pcb = PCB; + + if (!options) { + gcode_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + gcode_values[i] = gcode_attribute_list[i].default_val; + options = gcode_values; + } + + gctx.pcb = pcb; + gctx.f = NULL; + gctx.drawn_objs = 0; + pcb_cam_begin(pcb, &gctx.cam, &xform, options[HA_cam].str, gcode_attribute_list, NUM_OPTIONS, options); + + + if (gctx.cam.active) { + gctx.f = rnd_fopen_askovr(&pcb->hidlib, gctx.cam.fn, "w", NULL); + if (gctx.f != NULL) + gcode_print_header(); + } + + if (!gctx.cam.active || (gctx.f != NULL)) { + for(gid = 0; gid < pcb->LayerGroups.len; gid++) { + pcb_layergrp_t *grp = &pcb->LayerGroups.grp[gid]; + rnd_xform_t *xf = &xform; + gctx.grp = grp; + gcode_export_layer_group(gid, grp->purpose, grp->purpi, grp->lid[0], grp->ltype, &xf); + gctx.grp = NULL; + } + + if (gctx.cam.active) { + gcode_print_footer(); + fclose(gctx.f); + } + } + + if (!gctx.cam.active) gctx.cam.okempty_content = 1; /* never warn in direct export */ + + if (pcb_cam_end(&gctx.cam) == 0) { + if (!gctx.cam.okempty_group) + rnd_message(RND_MSG_ERROR, "gcode cam export for '%s' failed to produce any content (layer group missing)\n", options[HA_cam].str); + } + else if (gctx.drawn_objs == 0) { + if (!gctx.cam.okempty_content) + rnd_message(RND_MSG_ERROR, "gcode cam export for '%s' failed to produce any content (no objects)\n", options[HA_cam].str); + } +} + +static int gcode_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(gcode_attribute_list, sizeof(gcode_attribute_list) / sizeof(gcode_attribute_list[0]), pcb_export_gcode_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + + +static int gcode_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\ngcode exporter command line arguments:\n\n"); + rnd_hid_usage(gcode_attribute_list, sizeof(gcode_attribute_list) / sizeof(gcode_attribute_list[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x gcode [gcode options] foo.pcb\n\n"); + return 0; +} + + + +int pplg_check_ver_export_gcode(int ver_needed) { return 0; } + +void pplg_uninit_export_gcode(void) +{ + rnd_hid_remove_hid(&gcode_hid); +} + + +int pplg_init_export_gcode(void) +{ + RND_API_CHK_VER; + + memset(&gcode_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&gcode_hid); + + gcode_hid.struct_size = sizeof(rnd_hid_t); + gcode_hid.name = "gcode"; + gcode_hid.description = "router g-code for removing copper, drilling and routing board outline"; + gcode_hid.exporter = 1; + + gcode_hid.get_export_options = gcode_get_export_options; + gcode_hid.do_export = gcode_do_export; + gcode_hid.parse_arguments = gcode_parse_arguments; + + gcode_hid.usage = gcode_usage; + + rnd_hid_register_hid(&gcode_hid); + + + return 0; +} Index: tags/2.3.0/src_plugins/export_gerber/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_gerber/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_gerber/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_gerber + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_gerber/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_gerber/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_gerber/Plug.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +put /local/pcb/mod {export_gerber} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/export_gerber/gerber.o +@] +put /local/pcb/mod/CONF {$(PLUGDIR)/export_gerber/gerber_conf.h} + + +switch /local/pcb/export_gerber/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_gerber/export_gerber.pup =================================================================== --- tags/2.3.0/src_plugins/export_gerber/export_gerber.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_gerber/export_gerber.pup (revision 33253) @@ -0,0 +1,10 @@ +$class export +$short Gerber pcb_exporter +$long Export to gerber +$state works +$fmt-native no +$fmt-feature-w gerber for PCB fabbing +$package export +dep export_excellon +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_gerber/gerber.c =================================================================== --- tags/2.3.0/src_plugins/export_gerber/gerber.c (nonexistent) +++ tags/2.3.0/src_plugins/export_gerber/gerber.c (revision 33253) @@ -0,0 +1,1120 @@ +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "board.h" +#include "build_run.h" +#include "config.h" +#include "data.h" +#include +#include "draw.h" +#include "layer.h" +#include "layer_vis.h" +#include +#include +#include "hid_cam.h" +#include +#include +#include "funchash_core.h" +#include "gerber_conf.h" +#include + +#include +#include +#include +#include +#include +#include +#include "conf_core.h" +#include +#include + +#include "../src_plugins/export_excellon/aperture.h" + +#include + + +const char *gerber_cookie = "gerber HID"; + +conf_gerber_t conf_gerber; + +#define CRASH(func) fprintf(stderr, "HID error: pcb called unimplemented Gerber function %s.\n", func); abort() + +#define SUFF_LEN 256 + +#if SUFF_LEN < PCB_DERIVE_FN_SUFF_LEN +# error SUFF_LEN needs at least PCB_DERIVE_FN_SUFF_LEN +#endif + +static pcb_cam_t gerber_cam; + +/* These are for films */ +#define gerberX(pcb, x) ((rnd_coord_t) (x)) +#define gerberY(pcb, y) ((rnd_coord_t) ((pcb)->hidlib.size_y - (y))) +#define gerberXOffset(pcb, x) ((rnd_coord_t) (x)) +#define gerberYOffset(pcb, y) ((rnd_coord_t) (-(y))) + +static int verbose; +static int all_layers; +static int is_mask, was_drill; +static int is_drill, is_plated; +static rnd_composite_op_t gerber_drawing_mode, drawing_mode_issued; +static int flash_drills, line_slots; +static int copy_outline_mode; +static int want_cross_sect; +static int want_per_file_apertures; +static int has_outline; +static int gerber_debug; +static int gerber_ovr; +static int gerber_global_aperture_cnt; +static long gerber_drawn_objs; + +static aperture_list_t *layer_aptr_list; +static aperture_list_t *curr_aptr_list; +static int layer_list_max; +static int layer_list_idx; + +static void reset_apertures(void) +{ + int i; + for (i = 0; i < layer_list_max; ++i) + uninit_aperture_list(&layer_aptr_list[i]); + free(layer_aptr_list); + layer_aptr_list = NULL; + curr_aptr_list = NULL; + layer_list_max = 0; + layer_list_idx = 0; +} + +static void fprint_aperture(FILE *f, aperture_t *aptr) +{ + switch (aptr->shape) { + case ROUND: + rnd_fprintf(f, "%%ADD%dC,%[5]*%%\r\n", aptr->dCode, aptr->width); + break; + case SQUARE: + rnd_fprintf(f, "%%ADD%dR,%[5]X%[5]*%%\r\n", aptr->dCode, aptr->width, aptr->width); + break; + case OCTAGON: + rnd_fprintf(f, "%%AMOCT%d*5,0,8,0,0,%[5],22.5*%%\r\n" + "%%ADD%dOCT%d*%%\r\n", aptr->dCode, (rnd_coord_t) ((double) aptr->width / RND_COS_22_5_DEGREE), aptr->dCode, aptr->dCode); + break; + } +} + +#define AUTO_OUTLINE_WIDTH RND_MIL_TO_COORD(8) /* Auto-geneated outline width of 8 mils */ + +/* Set the aperture list for the current layer, + * expanding the list buffer if needed */ +static aperture_list_t *set_layer_aperture_list(int layer_idx, int aper_per_file) +{ + if (layer_idx >= layer_list_max) { + int i = layer_list_max; + layer_list_max = 2 * (layer_idx + 1); + layer_aptr_list = (aperture_list_t *) + realloc(layer_aptr_list, layer_list_max * sizeof(*layer_aptr_list)); + for (; i < layer_list_max; ++i) + init_aperture_list(&layer_aptr_list[i]); + } + curr_aptr_list = &layer_aptr_list[layer_idx]; + if (aper_per_file) + curr_aptr_list->aperture_count = &curr_aptr_list->aperture_count_default; + else + curr_aptr_list->aperture_count = &gerber_global_aperture_cnt; + return curr_aptr_list; +} + +/* --------------------------------------------------------------------------- */ + +static rnd_hid_t gerber_hid; + +typedef struct rnd_hid_gc_s { + rnd_core_gc_t core_gc; + rnd_cap_style_t cap; + int width; + int color; + int erase; + int drill; +} rnd_hid_gc_s; + +static FILE *f = NULL; +static gds_t fn_gds; +static int fn_baselen = 0; +static char *filename = NULL; +static char *filesuff = NULL; +static char *layername = NULL; +static int lncount = 0; + +static int finding_apertures = 0; +static int pagecount = 0; +static int linewidth = -1; +static rnd_layergrp_id_t lastgroup = -1; +static int lastcap = -1; +static int lastcolor = -1; +static int lastX, lastY; /* the last X and Y coordinate */ + +static const char *copy_outline_names[] = { +#define COPY_OUTLINE_NONE 0 + "none", +#define COPY_OUTLINE_MASK 1 + "mask", +#define COPY_OUTLINE_SILK 2 + "silk", +#define COPY_OUTLINE_ALL 3 + "all", + NULL +}; + +typedef struct { + const char *hdr1; + const char *cfmt; /* drawing coordinate format */ + const char *afmt; /* aperture description format */ +} coord_format_t; + +static coord_format_t coord_format[] = { + {"%MOIN*%\r\n%FSLAX25Y25*%\r\n", "%.0mc", "%.4mi"}, /* centimil: inch, leading zero suppression, Absolute Data, 2.5 format */ + {"%MOMM*%\r\n%FSLAX43Y43*%\r\n", "%.0mu", "%.3mm"}, /* micrometer: mm, leading zero suppression, Absolute Data, 4.3 format */ + {"%MOMM*%\r\n%FSLAX46Y46*%\r\n", "%.0mn", "%.6mm"} /* nanometer: mm, leading zero suppression, Absolute Data, 4.6 format */ +}; +#define NUM_COORD_FORMATS (sizeof(coord_format)/sizeof(coord_format[0])) + +static coord_format_t *gerber_cfmt; + +static const char *coord_format_names[NUM_COORD_FORMATS+1] = { + "centimil", + "micrometer", + "nanometer", + NULL +}; + +static void gerber_warning(rnd_hid_export_opt_func_action_t act, void *call_ctx, rnd_export_opt_t *opt); + +static rnd_export_opt_t gerber_options[] = { + {"", "WARNING", + RND_HATT_BEGIN_VBOX, 0, 0, {0, 0, 0, 0, {0}, gerber_warning}, 0, 0}, +#define HA_warning 0 + +/* %start-doc options "90 Gerber Export" +@ftable @code +@item --gerberfile +Gerber output file prefix. Can include a path. +@end ftable +%end-doc +*/ + {"gerberfile", "Gerber output file base", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_gerberfile 1 + +/* %start-doc options "90 Gerber Export" +@ftable @code +@item --all-layers +Output contains all layers, even empty ones. +@end ftable +%end-doc +*/ + {"all-layers", "Output all layers, even empty ones", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_all_layers 2 + +/* %start-doc options "90 Gerber Export" +@ftable @code +@item --verbose +Print file names and aperture counts on stdout. +@end ftable +%end-doc +*/ + {"verbose", "Print file names and aperture counts on stdout", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_verbose 3 + {"copy-outline", "Copy outline onto other layers", + RND_HATT_ENUM, 0, 0, {0, 0, 0}, copy_outline_names, 0}, +#define HA_copy_outline 4 + {"cross-sect", "Export the cross section layer", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cross_sect 5 + + {"coord-format", "Coordinate format (resolution)", + RND_HATT_ENUM, 0, 0, {0, 0, 0}, coord_format_names, 0}, +#define HA_coord_format 6 + + {"aperture-per-file", "Restart aperture numbering in each new file", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_apeture_per_file 7 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 8 +}; + +#define NUM_OPTIONS (sizeof(gerber_options)/sizeof(gerber_options[0])) + +static rnd_hid_attr_val_t gerber_values[NUM_OPTIONS]; + +static rnd_export_opt_t *gerber_get_export_options(rnd_hid_t *hid, int *n) +{ + if ((PCB != NULL) && (gerber_options[HA_gerberfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &gerber_options[HA_gerberfile], ""); + + if (n) + *n = NUM_OPTIONS; + return gerber_options; +} + +static rnd_layergrp_id_t group_for_layer(int l) +{ + if (l < pcb_max_layer(PCB) && l >= 0) + return pcb_layer_get_group(PCB, l); + /* else something unique */ + return pcb_max_group(PCB) + 3 + l; +} + +static int layer_sort(const void *va, const void *vb) +{ + int a = *(int *) va; + int b = *(int *) vb; + int d = group_for_layer(b) - group_for_layer(a); + if (d) + return d; + return b - a; +} + +static void maybe_close_f(FILE * f) +{ + if (f) { + fprintf(f, "M02*\r\n"); + fclose(f); + } +} + +static rnd_box_t region; + +static void append_file_suffix(gds_t *dst, rnd_layergrp_id_t gid, rnd_layer_id_t lid, unsigned int flags, const char *purpose, int purpi, int drill, int *merge_same) +{ + const char *sext = ".gbr"; + + fn_gds.used = fn_baselen; + if (merge_same != NULL) *merge_same = 0; + + pcb_layer_to_file_name_append(dst, lid, flags, purpose, purpi, PCB_FNS_pcb_rnd); + gds_append_str(dst, sext); + + filename = fn_gds.array; + filesuff = fn_gds.array + fn_baselen; +} + +static void gerber_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + const char *fnbase; + int i; + static int saved_layer_stack[PCB_MAX_LAYER]; + int save_ons[PCB_MAX_LAYER]; + rnd_hid_expose_ctx_t ctx; + rnd_xform_t xform; + + gerber_ovr = 0; + + drawing_mode_issued = RND_HID_COMP_POSITIVE; + + if (!options) { + gerber_get_export_options(hid, NULL); + for (i = 0; i < NUM_OPTIONS; i++) + gerber_values[i] = gerber_options[i].default_val; + options = gerber_values; + } + + /* set up the coord format */ + i = options[HA_coord_format].lng; + if ((i < 0) || (i >= NUM_COORD_FORMATS)) { + rnd_message(RND_MSG_ERROR, "Invalid coordinate format (out of bounds)\n"); + return; + } + gerber_cfmt = &coord_format[i]; + rnd_printf_slot[4] = gerber_cfmt->cfmt; + rnd_printf_slot[5] = gerber_cfmt->afmt; + + gerber_drawn_objs = 0; + pcb_cam_begin(PCB, &gerber_cam, &xform, options[HA_cam].str, gerber_options, NUM_OPTIONS, options); + + fnbase = options[HA_gerberfile].str; + if (!fnbase) + fnbase = "pcb-out"; + + verbose = options[HA_verbose].lng || rnd_conf.rc.verbose; + all_layers = options[HA_all_layers].lng; + + copy_outline_mode = options[HA_copy_outline].lng; + + want_cross_sect = options[HA_cross_sect].lng; + want_per_file_apertures = options[HA_apeture_per_file].lng; + + has_outline = pcb_has_explicit_outline(PCB); + + i = strlen(fnbase); + gds_init(&fn_gds); + gds_append_str(&fn_gds, fnbase); + gds_append(&fn_gds, '.'); + fn_baselen = fn_gds.used; + filename = fn_gds.array; + + if (!gerber_cam.active) + pcb_hid_save_and_show_layer_ons(save_ons); + + memcpy(saved_layer_stack, pcb_layer_stack, sizeof(pcb_layer_stack)); + qsort(pcb_layer_stack, pcb_max_layer(PCB), sizeof(pcb_layer_stack[0]), layer_sort); + linewidth = -1; + lastcap = -1; + lastgroup = -1; + lastcolor = -1; + + ctx.view.X1 = 0; + ctx.view.Y1 = 0; + ctx.view.X2 = PCB->hidlib.size_x; + ctx.view.Y2 = PCB->hidlib.size_y; + + pagecount = 1; + reset_apertures(); + + xform.no_slot_in_nonmech = 1; + + lastgroup = -1; + layer_list_idx = 0; + finding_apertures = 1; + rnd_expose_main(&gerber_hid, &ctx, &xform); + + lastgroup = -2; + layer_list_idx = 0; + finding_apertures = 0; + rnd_expose_main(&gerber_hid, &ctx, &xform); + + memcpy(pcb_layer_stack, saved_layer_stack, sizeof(pcb_layer_stack)); + + maybe_close_f(f); + f = NULL; + if (!gerber_cam.active) + pcb_hid_restore_layer_ons(save_ons); + rnd_conf_update(NULL, -1); /* resotre forced sets */ + + if (!gerber_cam.active) gerber_cam.okempty_content = 1; /* never warn in direct export */ + + if (pcb_cam_end(&gerber_cam) == 0) { + if (!gerber_cam.okempty_group) + rnd_message(RND_MSG_ERROR, "gerber cam export for '%s' failed to produce any content (layer group missing)\n", options[HA_cam].str); + } + else if (gerber_drawn_objs == 0) { + if (!gerber_cam.okempty_content) + rnd_message(RND_MSG_ERROR, "gerber cam export for '%s' failed to produce any content (no objects)\n", options[HA_cam].str); + } + + /* in cam mode we have f still open */ + maybe_close_f(f); + f = NULL; + gds_uninit(&fn_gds); +} + +static int gerber_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(gerber_options, NUM_OPTIONS, gerber_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + + + +static int gerber_set_layer_group(rnd_hid_t *hid, 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) +{ + int want_outline; + char *cp; + const char *group_name; + + pcb_cam_set_layer_group(&gerber_cam, group, purpose, purpi, flags, xform); + + if ((!gerber_cam.active) && (PCB_LAYER_IS_ASSY(flags, purpi))) + return 0; + + if ((!gerber_cam.active) && (flags & PCB_LYT_DOC)) + return 0; + + if (flags & PCB_LYT_UI) + return 0; + +#if 0 + printf(" Layer %s group %lx drill %d mask %d flags=%lx\n", pcb_layer_name(PCB, layer), group, is_drill, is_mask, flags); +#endif + + + if (!all_layers) { + int stay = 0; + if ((group >= 0) && pcb_layergrp_is_empty(PCB, group) && !(flags & PCB_LYT_SILK)) { + /* layer is empty and the user didn't want to have empty layers; however; + if the user wants to copy the outline to specific layers, those + layers will become non-empty: even an empty outline would bring + the implicit outline rectangle at board extents! */ + + if (PCB_LAYER_IS_OUTLINE(flags, purpi)) stay = 1; /* outline layer can never be empty, because of the implicit outline */ + + if (copy_outline_mode == COPY_OUTLINE_MASK && (flags & PCB_LYT_MASK)) stay = 1; + if (copy_outline_mode == COPY_OUTLINE_SILK && (flags & PCB_LYT_SILK)) stay = 1; + if (copy_outline_mode == COPY_OUTLINE_ALL && \ + ((flags & PCB_LYT_SILK) || (flags & PCB_LYT_MASK) || + PCB_LAYER_IS_FAB(flags, purpi) || + PCB_LAYER_IS_ASSY(flags, purpi))) stay = 1; + + if (!stay) return 0; + } + } + + if (flags & PCB_LYT_INVIS) { +/* printf(" nope: invis %d or assy %d\n", (flags & PCB_LYT_INVIS), (flags & PCB_LYT_ASSY));*/ + return 0; + } + + if (PCB_LAYER_IS_CSECT(flags, purpi) && (!want_cross_sect)) + return 0; + + if ((group >= 0) && (group < pcb_max_group(PCB))) { + group_name = PCB->LayerGroups.grp[group].name; + if (group_name == NULL) + group_name = ""; + } + else + group_name = ""; + + flash_drills = 0; + line_slots = 0; + if ((flags & PCB_LYT_MECH) && PCB_LAYER_IS_ROUTE(flags, purpi)) { + flash_drills = 1; + line_slots = 1; + } + + is_drill = PCB_LAYER_IS_DRILL(flags, purpi) || ((flags & PCB_LYT_MECH) && PCB_LAYER_IS_ROUTE(flags, purpi)); + is_plated = PCB_LAYER_IS_PROUTE(flags, purpi) || PCB_LAYER_IS_PDRILL(flags, purpi); + is_mask = !!(flags & PCB_LYT_MASK); + if (group < 0 || group != lastgroup) { + char utcTime[64]; + aperture_list_t *aptr_list; + aperture_t *search; + + lastgroup = group; + lastX = -1; + lastY = -1; + lastcolor = 0; + linewidth = -1; + lastcap = -1; + + aptr_list = set_layer_aperture_list(layer_list_idx++, want_per_file_apertures); + + if (finding_apertures) + goto emit_outline; + + if (aptr_list->count == 0 && !all_layers && !is_drill) + return 0; + + if ((!gerber_cam.active) || (gerber_cam.fn_changed)) { + /* in cam mode we reuse f */ + maybe_close_f(f); + f = NULL; + } + + pagecount++; + append_file_suffix(&fn_gds, group, layer, flags, purpose, purpi, 0, NULL); + if (f == NULL) { /* open a new file if we closed the previous (cam mode: only one file) */ + f = rnd_fopen_askovr(&PCB->hidlib, gerber_cam.active ? gerber_cam.fn : filename, "wb", &gerber_ovr); /* Binary needed to force CR-LF */ + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Error: Could not open %s for writing.\n", filename); + return 1; + } + } + + was_drill = is_drill; + + if (verbose) { + int c = aptr_list->count; + fprintf(stderr, "Gerber: %d aperture%s in %s\n", c, c == 1 ? "" : "s", filename); + } + + fprintf(f, "G04 start of page %d for group %ld layer_idx %ld *\r\n", pagecount, group, layer); + + /* Create a portable timestamp. */ + rnd_print_utc(utcTime, sizeof(utcTime), 0); + + /* Print a cute file header at the beginning of each file. */ + fprintf(f, "G04 Title: %s, %s *\r\n", RND_UNKNOWN(PCB->hidlib.name), RND_UNKNOWN(group_name)); + fprintf(f, "G04 Creator: pcb-rnd " PCB_VERSION " *\r\n"); + fprintf(f, "G04 CreationDate: %s *\r\n", utcTime); + + /* ID the user. */ + fprintf(f, "G04 For: %s *\r\n", pcb_author()); + + fprintf(f, "G04 Format: Gerber/RS-274X *\r\n"); + rnd_fprintf(f, "G04 PCB-Dimensions: %[4] %[4] *\r\n", PCB->hidlib.size_x, PCB->hidlib.size_y); + fprintf(f, "G04 PCB-Coordinate-Origin: lower left *\r\n"); + + /* Unit and coord format */ + fprintf(f, "%s", gerber_cfmt->hdr1); + + /* build a legal identifier. */ + if (layername) + free(layername); + layername = rnd_strdup(filesuff); + if (strrchr(layername, '.')) + *strrchr(layername, '.') = 0; + + for (cp = layername; *cp; cp++) { + if (isalnum((int) *cp)) + *cp = toupper((int) *cp); + else + *cp = '_'; + } + fprintf(f, "%%LN%s*%%\r\n", layername); + lncount = 1; + + for (search = aptr_list->data; search; search = search->next) + fprint_aperture(f, search); + if (aptr_list->count == 0) + /* We need to put *something* in the file to make it be parsed + as RS-274X instead of RS-274D. */ + fprintf(f, "%%ADD11C,0.0100*%%\r\n"); + } + +emit_outline: + /* If we're printing a copper layer other than the outline layer, + and we want to "print outlines", and we have an outline layer, + print the outline layer on this layer also. */ + want_outline = 0; + if (copy_outline_mode == COPY_OUTLINE_MASK && (flags & PCB_LYT_MASK)) + want_outline = 1; + if (copy_outline_mode == COPY_OUTLINE_SILK && (flags & PCB_LYT_SILK)) + want_outline = 1; + + if (copy_outline_mode == COPY_OUTLINE_ALL && ((flags & PCB_LYT_SILK) || (flags & PCB_LYT_MASK) || PCB_LAYER_IS_FAB(flags, purpi) || PCB_LAYER_IS_ASSY(flags, purpi))) + want_outline = 1; + + if (want_outline && !(PCB_LAYER_IS_ROUTE(flags, purpi))) { + if (has_outline) { + pcb_draw_groups(hid, PCB, PCB_LYT_BOUNDARY, F_proute, NULL, ®ion, rnd_color_black, PCB_LYT_MECH, 0, 0); + pcb_draw_groups(hid, PCB, PCB_LYT_BOUNDARY, F_uroute, NULL, ®ion, rnd_color_black, PCB_LYT_MECH, 0, 0); + } + else { + rnd_hid_gc_t gc = rnd_hid_make_gc(); + if (flags & PCB_LYT_SILK) + rnd_hid_set_line_width(gc, conf_core.design.min_slk); + else if (group >= 0) + rnd_hid_set_line_width(gc, conf_core.design.min_wid); + else + rnd_hid_set_line_width(gc, AUTO_OUTLINE_WIDTH); + rnd_render->draw_line(gc, 0, 0, PCB->hidlib.size_x, 0); + rnd_render->draw_line(gc, 0, 0, 0, PCB->hidlib.size_y); + rnd_render->draw_line(gc, PCB->hidlib.size_x, 0, PCB->hidlib.size_x, PCB->hidlib.size_y); + rnd_render->draw_line(gc, 0, PCB->hidlib.size_y, PCB->hidlib.size_x, PCB->hidlib.size_y); + rnd_hid_destroy_gc(gc); + } + } + return 1; +} + +static rnd_hid_gc_t gerber_make_gc(rnd_hid_t *hid) +{ + rnd_hid_gc_t rv = (rnd_hid_gc_t) calloc(1, sizeof(*rv)); + rv->cap = rnd_cap_round; + return rv; +} + +static void gerber_destroy_gc(rnd_hid_gc_t gc) +{ + free(gc); +} + +static void gerber_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *drw_screen) +{ + gerber_drawing_mode = op; + if ((f != NULL) && (gerber_debug)) + fprintf(f, "G04 hid debug composite: %d*\r\n", op); +} + +static void gerber_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + if (rnd_color_is_drill(color)) { + gc->color = 1; + gc->erase = 0; + gc->drill = 1; + } + else { + gc->color = 0; + gc->erase = 0; + gc->drill = 0; + } +} + +static void gerber_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + gc->cap = style; +} + +static void gerber_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + gc->width = width; +} + +static void gerber_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ + ; +} + +static void use_gc(rnd_hid_gc_t gc, int radius) +{ + gerber_drawn_objs++; + if ((f != NULL) && (gerber_drawing_mode != drawing_mode_issued)) { + if ((gerber_drawing_mode == RND_HID_COMP_POSITIVE) || (gerber_drawing_mode == RND_HID_COMP_POSITIVE_XOR)) { + fprintf(f, "%%LPD*%%\r\n"); + drawing_mode_issued = gerber_drawing_mode; + } + else if (gerber_drawing_mode == RND_HID_COMP_NEGATIVE) { + fprintf(f, "%%LPC*%%\r\n"); + drawing_mode_issued = gerber_drawing_mode; + } + } + + if (radius) { + radius *= 2; + if (radius != linewidth || lastcap != rnd_cap_round) { + aperture_t *aptr = find_aperture(curr_aptr_list, radius, ROUND); + if (aptr == NULL) + rnd_fprintf(stderr, "error: aperture for radius %$mS type ROUND is null\n", radius); + else if (f != NULL) + fprintf(f, "G54D%d*", aptr->dCode); + linewidth = radius; + lastcap = rnd_cap_round; + } + } + else if (linewidth != gc->width || lastcap != gc->cap) { + aperture_t *aptr; + aperture_shape_t shape; + + linewidth = gc->width; + lastcap = gc->cap; + switch (gc->cap) { + case rnd_cap_round: + shape = ROUND; + break; + case rnd_cap_square: + shape = SQUARE; + break; + default: + assert(!"unhandled cap"); + shape = ROUND; + } + aptr = find_aperture(curr_aptr_list, linewidth, shape); + if (aptr == NULL) + rnd_fprintf(stderr, "error: aperture for width %$mS type %s is null\n", linewidth, shape == ROUND ? "ROUND" : "SQUARE"); + if (f && aptr) + fprintf(f, "G54D%d*", aptr->dCode); + } +} + +static void gerber_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_bool m = rnd_false; + int i; + int firstTime = 1; + rnd_coord_t startX = 0, startY = 0; + + if (is_mask && (gerber_drawing_mode != RND_HID_COMP_POSITIVE) && (gerber_drawing_mode != RND_HID_COMP_POSITIVE_XOR) && (gerber_drawing_mode != RND_HID_COMP_NEGATIVE)) + return; + + use_gc(gc, 10 * 100); + if (!f) + return; + fprintf(f, "G36*\r\n"); + for (i = 0; i < n_coords; i++) { + if (x[i]+dx != lastX) { + m = rnd_true; + lastX = x[i]+dx; + rnd_fprintf(f, "X%[4]", gerberX(PCB, lastX)); + } + if (y[i]+dy != lastY) { + m = rnd_true; + lastY = y[i]+dy; + rnd_fprintf(f, "Y%[4]", gerberY(PCB, lastY)); + } + if (firstTime) { + firstTime = 0; + startX = x[i]+dx; + startY = y[i]+dy; + if (m) + fprintf(f, "D02*"); + } + else if (m) + fprintf(f, "D01*\r\n"); + m = rnd_false; + } + if (startX != lastX) { + m = rnd_true; + lastX = startX; + rnd_fprintf(f, "X%[4]", gerberX(PCB, startX)); + } + if (startY != lastY) { + m = rnd_true; + lastY = startY; + rnd_fprintf(f, "Y%[4]", gerberY(PCB, lastY)); + } + if (m) + fprintf(f, "D01*\r\n"); + fprintf(f, "G37*\r\n"); +} + +static void gerber_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + gerber_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + +static void gerber_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_bool m = rnd_false; + + if (line_slots) { + rnd_coord_t dia = gc->width/2; + find_aperture(curr_aptr_list, dia*2, ROUND); /* for a real gerber export of the BOUNDARY group: place aperture on the per layer aperture list */ + + if (finding_apertures) + return; + } + + if (x1 != x2 && y1 != y2 && gc->cap == rnd_cap_square) { + rnd_coord_t x[5], y[5]; + double tx, ty, theta; + + theta = atan2(y2 - y1, x2 - x1); + + /* T is a vector half a thickness long, in the direction of + one of the corners. */ + tx = gc->width / 2.0 * cos(theta + M_PI / 4) * sqrt(2.0); + ty = gc->width / 2.0 * sin(theta + M_PI / 4) * sqrt(2.0); + + x[0] = x1 - tx; + y[0] = y1 - ty; + x[1] = x2 + ty; + y[1] = y2 - tx; + x[2] = x2 + tx; + y[2] = y2 + ty; + x[3] = x1 - ty; + y[3] = y1 + tx; + + x[4] = x[0]; + y[4] = y[0]; + gerber_fill_polygon(gc, 5, x, y); + return; + } + + use_gc(gc, 0); + if (!f) + return; + + if (x1 != lastX) { + m = rnd_true; + lastX = x1; + rnd_fprintf(f, "X%[4]", gerberX(PCB, lastX)); + } + if (y1 != lastY) { + m = rnd_true; + lastY = y1; + rnd_fprintf(f, "Y%[4]", gerberY(PCB, lastY)); + } + if ((x1 == x2) && (y1 == y2)) + fprintf(f, "D03*\r\n"); + else { + if (m) + fprintf(f, "D02*"); + if (x2 != lastX) { + lastX = x2; + rnd_fprintf(f, "X%[4]", gerberX(PCB, lastX)); + } + if (y2 != lastY) { + lastY = y2; + rnd_fprintf(f, "Y%[4]", gerberY(PCB, lastY)); + + } + fprintf(f, "D01*\r\n"); + } +} + +static void gerber_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + gerber_draw_line(gc, x1, y1, x1, y2); + gerber_draw_line(gc, x1, y1, x2, y1); + gerber_draw_line(gc, x1, y2, x2, y2); + gerber_draw_line(gc, x2, y1, x2, y2); +} + +static void gerber_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_bool m = rnd_false; + double arcStartX, arcStopX, arcStartY, arcStopY; + + /* we never draw zero-width lines */ + if (gc->width == 0) + return; + + use_gc(gc, 0); + if (!f) + return; + + /* full circle is full.... truncate so that the arc split code never needs to + do more than 180 deg */ + if (delta_angle < -360.0) + delta_angle = -360.0; + if (delta_angle > +360.0) + delta_angle = +360.0; + + + /* some gerber interpreters (gerbv for one) have hard time dealing with + full-circle arcs - split large arcs up into 2 smaller ones */ + if (delta_angle < -180.0) { + gerber_draw_arc(gc, cx, cy, width, height, start_angle, -180.0); + gerber_draw_arc(gc, cx, cy, width, height, start_angle-180, delta_angle+180.0); + return; + } + if (delta_angle > +180.0) { + gerber_draw_arc(gc, cx, cy, width, height, start_angle, 180.0); + gerber_draw_arc(gc, cx, cy, width, height, start_angle+180, delta_angle-180.0); + return; + } + + + arcStartX = cx - width * cos(RND_TO_RADIANS(start_angle)); + arcStartY = cy + height * sin(RND_TO_RADIANS(start_angle)); + + if (fabs(delta_angle) < 0.01) { + gerber_draw_line(gc, arcStartX, arcStartY, arcStartX, arcStartY); + return; + } + + /* I checked three different gerber viewers, and they all disagreed + on how ellipses should be drawn. The spec just calls G74/G75 + "circular interpolation" so there's a chance it just doesn't + support ellipses at all. Thus, we draw them out with line + segments. Note that most arcs in pcb are circles anyway. */ + if (width != height) { + double step, angle; + rnd_coord_t max = width > height ? width : height; + rnd_coord_t minr = max - gc->width / 10; + int nsteps; + rnd_coord_t x0, y0, x1, y1; + + if (minr >= max) + minr = max - 1; + step = acos((double) minr / (double) max) * 180.0 / M_PI; + if (step > 5) + step = 5; + nsteps = fabs(delta_angle) / step + 1; + step = (double) delta_angle / nsteps; + + x0 = arcStartX; + y0 = arcStartY; + angle = start_angle; + while (nsteps > 0) { + nsteps--; + x1 = cx - width * cos(RND_TO_RADIANS(angle + step)); + y1 = cy + height * sin(RND_TO_RADIANS(angle + step)); + gerber_draw_line(gc, x0, y0, x1, y1); + x0 = x1; + y0 = y1; + angle += step; + } + return; + } + + arcStopX = cx - width * cos(RND_TO_RADIANS(start_angle + delta_angle)); + arcStopY = cy + height * sin(RND_TO_RADIANS(start_angle + delta_angle)); + if (arcStartX != lastX) { + m = rnd_true; + lastX = arcStartX; + rnd_fprintf(f, "X%[4]", gerberX(PCB, lastX)); + } + if (arcStartY != lastY) { + m = rnd_true; + lastY = arcStartY; + rnd_fprintf(f, "Y%[4]", gerberY(PCB, lastY)); + } + if (m) + fprintf(f, "D02*"); + rnd_fprintf(f, + "G75*G0%1dX%[4]Y%[4]I%[4]J%[4]D01*G01*\r\n", + (delta_angle < 0) ? 2 : 3, + gerberX(PCB, arcStopX), gerberY(PCB, arcStopY), + gerberXOffset(PCB, cx - arcStartX), gerberYOffset(PCB, cy - arcStartY)); + lastX = arcStopX; + lastY = arcStopY; +} + +static void gerber_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + if (radius <= 0) + return; + if (is_drill) + radius = 50 * rnd_round(radius / 50.0); + use_gc(gc, radius); + if (!f) + return; + if (is_drill) { + if (finding_apertures) + return; + } + else if (gc->drill && !flash_drills) + return; + if (cx != lastX) { + lastX = cx; + rnd_fprintf(f, "X%[4]", gerberX(PCB, lastX)); + } + if (cy != lastY) { + lastY = cy; + rnd_fprintf(f, "Y%[4]", gerberY(PCB, lastY)); + } + fprintf(f, "D03*\r\n"); +} + +static void gerber_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_coord_t x[5]; + rnd_coord_t y[5]; + x[0] = x[4] = x1; + y[0] = y[4] = y1; + x[1] = x1; + y[1] = y2; + x[2] = x2; + y[2] = y2; + x[3] = x2; + y[3] = y1; + gerber_fill_polygon(gc, 5, x, y); +} + +static void gerber_calibrate(rnd_hid_t *hid, double xval, double yval) +{ + CRASH("gerber_calibrate"); +} + +static int gerber_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\ngerber exporter command line arguments:\n\n"); + rnd_hid_usage(gerber_options, sizeof(gerber_options) / sizeof(gerber_options[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x gerber [gerber options] foo.pcb\n\n"); + return 0; +} + +static void gerber_go_to_cam_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_dad_retovr_t retovr; + rnd_hid_dad_close(hid_ctx, &retovr, -1); + rnd_actionva(&PCB->hidlib, "cam", NULL); +} + + +static void gerber_warning(rnd_hid_export_opt_func_action_t act, void *call_ctx, rnd_export_opt_t *opt) +{ + const char warn_txt[] = + "WARNING: direct gerber export is most probably NOT what\n" + "you want, especially if you are exporting to fab the\n" + "board. Please use the cam export instead!\n" + "For more info please read:\n" + "http://repo.hu/cgi-bin/pool.cgi?cmd=show&node=cam_switch\n"; + rnd_hid_export_opt_func_dad_t *dad = call_ctx; + + switch(act) { + case RND_HIDEOF_USAGE: + fprintf((FILE *)call_ctx, "******************************************************************************\n"); + fprintf((FILE *)call_ctx, warn_txt); + fprintf((FILE *)call_ctx, "For the cam export, try --help cam\n"); + fprintf((FILE *)call_ctx, "Command line would look like pcb-rnd -x cam gerber:fixed filename\n"); + fprintf((FILE *)call_ctx, "******************************************************************************\n\n"); + break; + case RND_HIDEOF_DAD: + RND_DAD_BEGIN_VBOX(dad->dlg); + RND_DAD_COMPFLAG(dad->dlg, RND_HATF_EXPFILL | RND_HATF_FRAME); + RND_DAD_BEGIN_HBOX(dad->dlg); + RND_DAD_PICTURE(dad->dlg, pcp_dlg_xpm_by_name("warning")); + RND_DAD_BEGIN_VBOX(dad->dlg); + RND_DAD_LABEL(dad->dlg, warn_txt); + RND_DAD_BUTTON(dad->dlg, "Get me to the cam export dialog"); + RND_DAD_CHANGE_CB(dad->dlg, gerber_go_to_cam_cb); + RND_DAD_LABEL(dad->dlg, ""); + RND_DAD_END(dad->dlg); + RND_DAD_END(dad->dlg); + RND_DAD_END(dad->dlg); + break; + } +} + + +static void gerber_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int action) +{ +} + +static void gerber_session_begin(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + gerber_global_aperture_cnt = 0; +} + +int pplg_check_ver_export_gerber(int ver_needed) { return 0; } + +void pplg_uninit_export_gerber(void) +{ + rnd_export_remove_opts_by_cookie(gerber_cookie); + rnd_conf_unreg_fields("plugins/export_gerber/"); + rnd_event_unbind_allcookie(gerber_cookie); + rnd_hid_remove_hid(&gerber_hid); +} + +int pplg_init_export_gerber(void) +{ + RND_API_CHK_VER; + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_gerber, field,isarray,type_name,cpath,cname,desc,flags); +#include "gerber_conf_fields.h" + + memset(&gerber_hid, 0, sizeof(gerber_hid)); + + rnd_hid_nogui_init(&gerber_hid); + + gerber_hid.struct_size = sizeof(gerber_hid); + gerber_hid.name = "gerber"; + gerber_hid.description = "RS-274X (Gerber) export"; + gerber_hid.exporter = 1; + + gerber_hid.mask_invert = 1; + + gerber_hid.get_export_options = gerber_get_export_options; + gerber_hid.do_export = gerber_do_export; + gerber_hid.parse_arguments = gerber_parse_arguments; + gerber_hid.set_layer_group = gerber_set_layer_group; + gerber_hid.make_gc = gerber_make_gc; + gerber_hid.destroy_gc = gerber_destroy_gc; + gerber_hid.set_drawing_mode = gerber_set_drawing_mode; + gerber_hid.set_color = gerber_set_color; + gerber_hid.set_line_cap = gerber_set_line_cap; + gerber_hid.set_line_width = gerber_set_line_width; + gerber_hid.set_draw_xor = gerber_set_draw_xor; + gerber_hid.draw_line = gerber_draw_line; + gerber_hid.draw_arc = gerber_draw_arc; + gerber_hid.draw_rect = gerber_draw_rect; + gerber_hid.fill_circle = gerber_fill_circle; + gerber_hid.fill_polygon = gerber_fill_polygon; + gerber_hid.fill_polygon_offs = gerber_fill_polygon_offs; + gerber_hid.fill_rect = gerber_fill_rect; + gerber_hid.calibrate = gerber_calibrate; + gerber_hid.set_crosshair = gerber_set_crosshair; + gerber_hid.usage = gerber_usage; + + rnd_hid_register_hid(&gerber_hid); + + rnd_event_bind(RND_EVENT_EXPORT_SESSION_BEGIN, gerber_session_begin, NULL, gerber_cookie); + + return 0; +} + Index: tags/2.3.0/src_plugins/export_gerber/gerber_conf.h =================================================================== --- tags/2.3.0/src_plugins/export_gerber/gerber_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/export_gerber/gerber_conf.h (revision 33253) @@ -0,0 +1,15 @@ +#ifndef PCB_GERBER_CONF_H +#define PCB_GERBER_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN plated_g85_slot; /* use G85 (drill cycle instead of route) for plated slots - only affects direct gerber export, DO NOT USE, check excellon's config instead */ + RND_CFT_BOOLEAN unplated_g85_slot; /* use G85 (drill cycle instead of route) for unplated slots - only affects direct gerber export, DO NOT USE, check excellon's config instead */ + } export_gerber; + } plugins; +} conf_gerber_t; + +#endif Index: tags/2.3.0/src_plugins/export_ipcd356/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_ipcd356/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_ipcd356/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_ipcd356 + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_ipcd356/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_ipcd356/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_ipcd356/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {export_ipcd356} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_ipcd356/ipcd356.o @] + +switch /local/pcb/export_ipcd356/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_ipcd356/export_ipcd356.pup =================================================================== --- tags/2.3.0/src_plugins/export_ipcd356/export_ipcd356.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_ipcd356/export_ipcd356.pup (revision 33253) @@ -0,0 +1,10 @@ +$class export +$short IPC-D-356 Netlist pcb_exporter +$long IPC-D-356 Netlist export. +$state works +$fmt-native no +$fmt-feature-w IPC-D-356 Netlist (for automated testing) +$package export-extra +dep lib_compat_help +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_ipcd356/ipcd356.c =================================================================== --- tags/2.3.0/src_plugins/export_ipcd356/ipcd356.c (nonexistent) +++ tags/2.3.0/src_plugins/export_ipcd356/ipcd356.c (revision 33253) @@ -0,0 +1,504 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * ipc-d-356 export plugin + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include "board.h" +#include "data.h" +#include +#include "conf_core.h" +#include +#include +#include "netlist.h" +#include +#include "layer.h" +#include "obj_arc.h" +#include "obj_line.h" +#include "obj_poly.h" +#include "obj_subc.h" +#include "obj_pstk.h" +#include "obj_pstk_inlines.h" + +#include +#include +#include "hid_cam.h" +#include +#include +#include + +static const char *ipcd356_cookie = "ipcd356 exporter"; + +/*** low level export code ***/ +typedef struct { + pcb_board_t *pcb; + FILE *f; + int is_mil; +} write_ctx_t; + +typedef struct { + pcb_any_obj_t *o; + const char *netname, *refdes, *term; + int is_plated, access_top, access_bottom, rot, masked_top, masked_bottom; + rnd_coord_t hole, width, height, cx, cy; +} test_feature_t; + +static int getattr(pcb_any_obj_t *o, const char *key) +{ + char *val = pcb_attribute_get(&o->Attributes, key); + if (val == NULL) return 0; + if (rnd_strcasecmp(val, "yes") == 0) return 1; + return 0; +} + +static void fill_field(char *dst, int start, int end, const char *data, const char *name) +{ + int n; + const char *d = data; + + if (data == NULL) + d = ""; + + for(n = start; n <= end; n++) { + if (*d != '\0') + dst[n] = *d++; + else + dst[n] = ' '; + } + if (*d != '\0') + rnd_message(RND_MSG_WARNING, "Data '%s' is too long for a(n) %s, truncated\n", data, name); +} + +static void fill_field_coord(write_ctx_t *ctx, char *dst, int start, int end, rnd_coord_t crd, int sign, const char *name) +{ + int len = end-start+1; + char tmp[32], fmt[16]; + if (sign) { + dst[start] = (crd >= 0) ? '+' : '-'; + start++; + len--; + } + if (ctx->is_mil) { + sprintf(fmt, "%%0%d.0ml", len); + crd *= 10; + } + else { + sprintf(fmt, "%%0%d.0mm", len); + crd *= 1000; + } + rnd_snprintf(tmp, sizeof(tmp), fmt, crd); + fill_field(dst, start, end, tmp, name); +} + +static void ipcd356_write_head(write_ctx_t *ctx) +{ + char utc[64]; + + rnd_print_utc(utc, sizeof(utc), 0); + + fprintf(ctx->f, "C IPC-D-356 Netlist generated by pcb-rnd " PCB_VERSION "\n"); + fprintf(ctx->f, "C \n"); + fprintf(ctx->f, "C File created on %s\n", utc); + fprintf(ctx->f, "C \n"); + fprintf(ctx->f, "P JOB %s\n", (PCB->hidlib.name == NULL) ? PCB->hidlib.filename : PCB->hidlib.name); + fprintf(ctx->f, "P CODE 00\n"); + fprintf(ctx->f, "P UNITS CUST %d\n", ctx->is_mil ? 0 : 1); + fprintf(ctx->f, "P DIM N\n"); + fprintf(ctx->f, "P VER IPC-D-356\n"); + fprintf(ctx->f, "P IMAGE PRIMARY\n"); + fprintf(ctx->f, "C \n"); +} + +static void ipcd356_write_foot(write_ctx_t *ctx) +{ + fprintf(ctx->f, "999\n\n"); +} + +static void ipcd356_write_feature(write_ctx_t *ctx, test_feature_t *t) +{ + char line[128]; + int is_tooling, is_mid; + + is_tooling = getattr(t->o, "ipcd356::tooling"); + is_mid = getattr(t->o, "ipcd356::mid"); + + line[0] = '3'; + if (is_tooling) + line[1] = '4'; + else if (t->hole > 0) + line[1] = '1'; + else + line[1] = '2'; + line[2] = '7'; + + fill_field(line, 3, 16, t->netname, "netname"); + fill_field(line, 17, 19, NULL, NULL); + fill_field(line, 20, 25, t->refdes, "refdes"); + line[26] = '-'; + fill_field(line, 27, 30, t->term, "term ID"); + line[31] = is_mid ? 'M' : ' '; + + if (t->hole > 0) { + line[32] = 'D'; + fill_field_coord(ctx, line, 33, 36, t->hole, 0, "hole"); + } + else + fill_field(line, 32, 36, NULL, NULL); + + if (t->hole > 0) + line[37] = t->is_plated ? 'P' : 'U'; + else + line[37] = ' '; + + if ((t->access_top) && (t->access_bottom)) + strcpy(line+38, "A00"); + else if (t->access_top) + strcpy(line+38, "A01"); + else if (t->access_bottom) + strcpy(line+38, "A02"); + else + return; /* do not export something that's not accessible from top or bottom */ + + line[41] = 'X'; + fill_field_coord(ctx, line, 42, 48, t->cx, 1, "X coord"); + line[49] = 'Y'; + fill_field_coord(ctx, line, 50, 56, PCB->hidlib.size_y - t->cy, 1, "Y coord"); + + line[57] = 'X'; + fill_field_coord(ctx, line, 58, 61, t->width, 0, "width"); + line[62] = 'Y'; + fill_field_coord(ctx, line, 63, 66, t->height, 0, "height"); + line[67] = 'R'; + fill_field_coord(ctx, line, 68, 70, t->rot, 0, "rotation"); + + line[71] = ' '; + if ((t->masked_top) && (t->masked_bottom)) + strcpy(line+72, "S3"); + else if (t->masked_top) + strcpy(line+72, "S1"); + else if (t->masked_bottom) + strcpy(line+72, "S2"); + else + strcpy(line+72, "S0"); + fill_field(line, 74, 79, NULL, NULL); + + line[80] = '\n'; + line[81] = '\0'; + fprintf(ctx->f, "%s", line); +} + +/* light terminals */ +static void ipcd356_pstk_shape(test_feature_t *t, pcb_pstk_shape_t *sh) +{ + int n; + rnd_coord_t x1, y1, x2, y2; + switch(sh->shape) { + case PCB_PSSH_HSHADOW: + break; + case PCB_PSSH_CIRC: + t->width = sh->data.circ.dia; + t->height = 0; + t->cx += sh->data.circ.x; + t->cy += sh->data.circ.y; + break; + case PCB_PSSH_LINE: + t->height = t->width = sh->data.line.thickness; + t->cx += (sh->data.line.x1 + sh->data.line.x2)/2; + t->cy += (sh->data.line.y1 + sh->data.line.y2)/2; + break; + case PCB_PSSH_POLY: + t->height = t->width = sh->data.line.thickness; + x1 = x2 = sh->data.poly.x[0]; + y1 = y2 = sh->data.poly.y[0]; + for(n = 1; n < sh->data.poly.len; n++) { + if (sh->data.poly.x[n] < x1) x1 = sh->data.poly.x[n]; + if (sh->data.poly.x[n] > x2) x2 = sh->data.poly.x[n]; + if (sh->data.poly.y[n] < y1) y1 = sh->data.poly.y[n]; + if (sh->data.poly.y[n] > y2) y2 = sh->data.poly.y[n]; + } + + t->cx += (x1 + x2)/2; + t->cy += (y1 + y2)/2; + if (sh->data.poly.pa == NULL) + pcb_pstk_shape_update_pa(&sh->data.poly); + if (pcb_pline_is_rectangle(sh->data.poly.pa->contours)) { + t->width = (x2 - x1); + t->height = (y2 - y1); + } + else { + t->width = (x2 - x1) / 4 + 1; + t->height = (y2 - y1) / 4 + 1; + } + break; + } +} + +static void ipcd356_write_pstk(write_ctx_t *ctx, pcb_subc_t *subc, pcb_pstk_t *pstk) +{ + test_feature_t t; + pcb_pstk_proto_t *proto; + pcb_pstk_shape_t *st, *sb; + pcb_pstk_tshape_t *tshp; + + if (pstk->term == NULL) + return; + + proto = pcb_pstk_get_proto(pstk); + if (proto == NULL) + return; + + { + pcb_net_term_t *term = pcb_net_find_by_obj(&ctx->pcb->netlist[PCB_NETLIST_EDITED], (pcb_any_obj_t *)pstk); + t.netname = (term == NULL) ? "N/C" : term->parent.net->name; + } + + t.o = (pcb_any_obj_t *)pstk; + t.refdes = subc->refdes; + t.term = pstk->term; + t.is_plated = proto->hplated; + t.access_top = ((st = pcb_pstk_shape(pstk, PCB_LYT_TOP | PCB_LYT_COPPER, 0)) != NULL); + t.access_bottom = ((sb = pcb_pstk_shape(pstk, PCB_LYT_BOTTOM | PCB_LYT_COPPER, 0)) != NULL); + /* this assumes the mask shape will expose all copper */ + t.masked_top = (pcb_pstk_shape(pstk, PCB_LYT_TOP | PCB_LYT_MASK, 0) == NULL); + t.masked_bottom = (pcb_pstk_shape(pstk, PCB_LYT_BOTTOM | PCB_LYT_MASK, 0) == NULL); + t.hole = proto->hdia; + t.cx = pstk->x; + t.cy = pstk->y; + + /* this assumes bottom shape is not smaller than top shape */ + if (st != NULL) ipcd356_pstk_shape(&t, st); + else if (sb != NULL) ipcd356_pstk_shape(&t, sb); + + tshp = pcb_pstk_get_tshape(pstk); + t.rot = tshp->rot; + + ipcd356_write_feature(ctx, &t); +} + +/* heavy terminals: lines, arcs, polygons */ +static int ipcd356_heavy(write_ctx_t *ctx, test_feature_t *t, pcb_subc_t *subc, pcb_layer_t *layer, pcb_any_obj_t *o) +{ + pcb_layer_type_t flg; + + if (o->term == NULL) + return -1; + flg = pcb_layer_flags_(layer); + if (!(flg & PCB_LYT_COPPER)) + return -1; + + memset(t, 0, sizeof(test_feature_t)); + + { + pcb_net_term_t *term = pcb_net_find_by_obj(&ctx->pcb->netlist[PCB_NETLIST_EDITED], (pcb_any_obj_t *)o); + t->netname = (term == NULL) ? "N/C" : term->parent.net->name; + } + + t->o = o; + t->refdes = subc->refdes; + t->term = o->term; + t->access_top = (flg & PCB_LYT_TOP); + t->access_bottom = (flg & PCB_LYT_BOTTOM); + return 0; +} + +static void ipcd356_write_line(write_ctx_t *ctx, pcb_subc_t *subc, pcb_layer_t *layer, pcb_line_t *line) +{ + test_feature_t t; + + if (ipcd356_heavy(ctx, &t, subc, layer, (pcb_any_obj_t *)line) != 0) + return; + + t.cx = (line->Point1.X + line->Point2.X) / 2; + t.cy = (line->Point1.Y + line->Point2.Y) / 2; + t.width = t.height = line->Thickness; + t.rot = atan2(line->Point2.Y - line->Point1.Y, line->Point2.X - line->Point1.X) * RND_RAD_TO_DEG; + ipcd356_write_feature(ctx, &t); +} + +static void ipcd356_write_arc(write_ctx_t *ctx, pcb_subc_t *subc, pcb_layer_t *layer, pcb_arc_t *arc) +{ + test_feature_t t; + + if (ipcd356_heavy(ctx, &t, subc, layer, (pcb_any_obj_t *)arc) != 0) + return; + + pcb_arc_middle(arc, &t.cx, &t.cy); + t.width = t.height = arc->Thickness; + t.rot = arc->StartAngle + (arc->Delta / 2); + ipcd356_write_feature(ctx, &t); +} + +static void ipcd356_write_poly(write_ctx_t *ctx, pcb_subc_t *subc, pcb_layer_t *layer, pcb_poly_t *poly) +{ + test_feature_t t; + + if (ipcd356_heavy(ctx, &t, subc, layer, (pcb_any_obj_t *)poly) != 0) + return; + + t.cx = (poly->BoundingBox.X1 + poly->BoundingBox.X2) / 2; + t.cy = (poly->BoundingBox.Y1 + poly->BoundingBox.Y2) / 2; + t.width = (poly->BoundingBox.X2 - poly->BoundingBox.X1) / 8 + 1; + t.height = (poly->BoundingBox.Y2 - poly->BoundingBox.Y1) / 8 + 1; + t.rot = 0; + ipcd356_write_feature(ctx, &t); +} + +static void ipcd356_write(pcb_board_t *pcb, FILE *f) +{ + write_ctx_t ctx; + + ctx.pcb = pcb; + ctx.f = f; + ctx.is_mil = (strcmp(rnd_conf.editor.grid_unit->suffix, "mil") == 0); + + ipcd356_write_head(&ctx); + PCB_SUBC_LOOP(pcb->Data); { +TODO("subc: subc-in-subc") + PCB_PADSTACK_LOOP(subc->data); { + ipcd356_write_pstk(&ctx, subc, padstack); + } PCB_END_LOOP; + PCB_LINE_ALL_LOOP(subc->data); { + ipcd356_write_line(&ctx, subc, layer, line); + } PCB_ENDALL_LOOP; + PCB_ARC_ALL_LOOP(subc->data); { + ipcd356_write_arc(&ctx, subc, layer, arc); + } PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(subc->data); { + ipcd356_write_poly(&ctx, subc, layer, polygon); + } PCB_ENDALL_LOOP; + } PCB_END_LOOP; + ipcd356_write_foot(&ctx); +} + +/*** export hid administration and API/glu ***/ + +static rnd_export_opt_t ipcd356_options[] = { +/* %start-doc options "8 IPC-D-356 Netlist Export" +@ftable @code +@item --netlist-file +Name of the IPC-D-356 Netlist output file. +@end ftable +%end-doc +*/ + { + "netlistfile", + "Name of the IPC-D-356 Netlist output file", + RND_HATT_STRING, + 0, 0, {0, 0, 0}, 0, 0}, +#define HA_ipcd356_filename 0 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 1 + +}; + +#define NUM_OPTIONS (sizeof(ipcd356_options)/sizeof(ipcd356_options[0])) + +static rnd_hid_attr_val_t ipcd356_values[NUM_OPTIONS]; + +static rnd_export_opt_t *ipcd356_get_export_options(rnd_hid_t *hid, int *n) +{ + if ((PCB != NULL) && (ipcd356_options[HA_ipcd356_filename].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &ipcd356_options[HA_ipcd356_filename], ".net"); + + if (n != NULL) + *n = NUM_OPTIONS; + + return ipcd356_options; +} + +static int ipcd356_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + return rnd_hid_parse_command_line(argc, argv); +} + +static void ipcd356_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + int n; + const char *fn; + FILE *f; + pcb_cam_t cam; + + if (!options) { + ipcd356_get_export_options(hid, 0); + + for (n = 0; n < NUM_OPTIONS; n++) + ipcd356_values[n] = ipcd356_options[n].default_val; + + options = ipcd356_values; + } + + fn = options[HA_ipcd356_filename].str; + if (fn == NULL) + fn = "pcb-rnd-out.net"; + + pcb_cam_begin_nolayer(PCB, &cam, NULL, options[HA_cam].str, &fn); + + f = rnd_fopen_askovr(&PCB->hidlib, fn, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can't open %s for write\n", fn); + return; + } + ipcd356_write(PCB, f); + fclose(f); + pcb_cam_end(&cam); +} + +static rnd_hid_t ipcd356_hid; + +int pplg_check_ver_export_ipcd356(int ver_needed) { return 0; } + +void pplg_uninit_export_ipcd356(void) +{ + rnd_export_remove_opts_by_cookie(ipcd356_cookie); + rnd_hid_remove_hid(&ipcd356_hid); +} + +int pplg_init_export_ipcd356(void) +{ + RND_API_CHK_VER; + memset(&ipcd356_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&ipcd356_hid); + + ipcd356_hid.struct_size = sizeof(rnd_hid_t); + ipcd356_hid.name = "IPC-D-356"; + ipcd356_hid.description = "Exports to IPC-D-356 netlist"; + ipcd356_hid.exporter = 1; + + ipcd356_hid.get_export_options = ipcd356_get_export_options; + ipcd356_hid.do_export = ipcd356_do_export; + ipcd356_hid.parse_arguments = ipcd356_parse_arguments; + + rnd_hid_register_hid(&ipcd356_hid); + + rnd_export_register_opts(ipcd356_options, sizeof(ipcd356_options) / sizeof(ipcd356_options[0]), ipcd356_cookie, 0); + return 0; +} Index: tags/2.3.0/src_plugins/export_lpr/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_lpr/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_lpr/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_lpr + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_lpr/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_lpr/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_lpr/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {export_lpr} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_lpr/lpr.o @] + +switch /local/pcb/export_lpr/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_lpr/export_lpr.pup =================================================================== --- tags/2.3.0/src_plugins/export_lpr/export_lpr.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_lpr/export_lpr.pup (revision 33253) @@ -0,0 +1,10 @@ +$class export +$short lpr pcb_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/2.3.0/src_plugins/export_lpr/lpr.c =================================================================== --- tags/2.3.0/src_plugins/export_lpr/lpr.c (nonexistent) +++ tags/2.3.0/src_plugins/export_lpr/lpr.c (revision 33253) @@ -0,0 +1,149 @@ +#include "config.h" + +#include +#include +#include +#include +#include + +#include "data.h" +#include +#include +#include + +#include +#include "../export_ps/ps.h" +#include +#include +#include +#include + +const char *lpr_cookie = "lpr HID"; + +static rnd_export_opt_t base_lpr_options[] = { + +/* %start-doc options "98 lpr Printing Options" +@ftable @code +@item --lprcommand +Command to use for printing. Defaults to @code{lpr}. This can be used to produce +PDF output with a virtual PDF printer. Example: @* +@code{--lprcommand "lp -d CUPS-PDF-Printer"}. +@end ftable +@noindent In addition, all @ref{Postscript Export} options are valid. +%end-doc +*/ + {"lprcommand", "Command to use for printing", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_lprcommand 0 +}; + +#define NUM_OPTIONS (sizeof(lpr_options)/sizeof(lpr_options[0])) + +static rnd_export_opt_t *lpr_options = 0; +static int num_lpr_options = 0; +static rnd_hid_attr_val_t *lpr_values; + +static rnd_export_opt_t *lpr_get_export_options(rnd_hid_t *hid, int *n) +{ + /* + * We initialize the default value in this manner because the GUI + * HID's may want to free() this string value and replace it with a + * new one based on how a user fills out a print dialog. + */ + if (base_lpr_options[HA_lprcommand].default_val.str == NULL) { + base_lpr_options[HA_lprcommand].default_val.str = rnd_strdup("lpr"); + } + + if (lpr_options == 0) { + rnd_export_opt_t *ps_opts = ps_hid.get_export_options(&ps_hid, &num_lpr_options); + lpr_options = calloc(num_lpr_options, sizeof(rnd_hid_attribute_t)); + memcpy(lpr_options, ps_opts, num_lpr_options * sizeof(rnd_hid_attribute_t)); + memcpy(lpr_options, base_lpr_options, sizeof(base_lpr_options)); + lpr_values = (rnd_hid_attr_val_t *) calloc(num_lpr_options, sizeof(rnd_hid_attr_val_t)); + } + if (n) + *n = num_lpr_options; + return lpr_options; +} + +static void lpr_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + FILE *f; + int i; + const char *filename; + + if (!options) { + lpr_get_export_options(hid, 0); + for (i = 0; i < num_lpr_options; i++) + lpr_values[i] = lpr_options[i].default_val; + options = lpr_values; + } + + filename = options[HA_lprcommand].str; + + printf("LPR: open %s\n", filename); + f = rnd_popen(NULL, filename, "w"); + if (!f) { + perror(filename); + return; + } + + ps_hid_export_to_file(f, options, NULL); + + rnd_pclose(f); +} + +static int lpr_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + lpr_get_export_options(hid, 0); + rnd_export_register_opts(lpr_options, num_lpr_options, lpr_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static void lpr_calibrate(rnd_hid_t *hid, double xval, double yval) +{ + ps_calibrate_1(hid, xval, yval, 1); +} + +static rnd_hid_t lpr_hid; + +static int lpr_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nlpr exporter command line arguments:\n\n"); + rnd_hid_usage(base_lpr_options, sizeof(base_lpr_options) / sizeof(base_lpr_options[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x lpr [lpr options] foo.pcb\n\n"); + return 0; +} + +int pplg_check_ver_export_lpr(int ver_needed) { return 0; } + +void pplg_uninit_export_lpr(void) +{ + rnd_remove_actions_by_cookie(lpr_cookie); + rnd_hid_remove_hid(&lpr_hid); +} + +int pplg_init_export_lpr(void) +{ + RND_API_CHK_VER; + memset(&lpr_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&lpr_hid); + ps_ps_init(&lpr_hid); + + lpr_hid.struct_size = sizeof(rnd_hid_t); + lpr_hid.name = "lpr"; + lpr_hid.description = "Postscript print"; + lpr_hid.printer = 1; + + lpr_hid.get_export_options = lpr_get_export_options; + lpr_hid.do_export = lpr_do_export; + lpr_hid.parse_arguments = lpr_parse_arguments; + lpr_hid.calibrate = lpr_calibrate; + + lpr_hid.usage = lpr_usage; + + rnd_hid_register_hid(&lpr_hid); + + return 0; +} Index: tags/2.3.0/src_plugins/export_oldconn/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_oldconn/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_oldconn/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_oldconn + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_oldconn/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_oldconn/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_oldconn/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {export_oldconn} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_oldconn/oldconn.o @] + +switch /local/pcb/export_oldconn/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_oldconn/export_oldconn.pup =================================================================== --- tags/2.3.0/src_plugins/export_oldconn/export_oldconn.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_oldconn/export_oldconn.pup (revision 33253) @@ -0,0 +1,9 @@ +$class export +$short old connection data format +$long Export subc/terminal connection map in an old, custom file format +$state works +$fmt-native no +$fmt-feature-w list of terminal connections (old, custom format) +$package export-extra +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_oldconn/oldconn.c =================================================================== --- tags/2.3.0/src_plugins/export_oldconn/oldconn.c (nonexistent) +++ tags/2.3.0/src_plugins/export_oldconn/oldconn.c (revision 33253) @@ -0,0 +1,324 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include + +#include +#include "board.h" +#include +#include "data.h" +#include "data_it.h" +#include "draw.h" +#include +#include "plug_io.h" +#include +#include "find.h" +#include "obj_subc_parent.h" +#include "undo.h" +#include "funchash_core.h" +#include "search.h" + +#include +#include + +const char *oldconn_cookie = "export_oldconn HID"; + +#define SEPARATE(fp) \ + do { \ + int __i__; \ + FILE *__f__ = (fp); \ + fputc('#', __f__); \ + for (__i__ = conf_core.appearance.messages.char_per_line; __i__ > 0; __i__--) \ + fputc('=', __f__); \ + fputc('\n', __f__); \ + } while(0) + +/* writes the several names of a subcircuit to a file */ +static void print_subc_name(FILE *f, pcb_subc_t *subc) +{ + fputc('(', f); + pcb_print_quoted_string(f, (char *)RND_EMPTY(pcb_attribute_get(&subc->Attributes, "footprint"))); + fputc(' ', f); + pcb_print_quoted_string(f, (char *)RND_EMPTY(subc->refdes)); + fputc(' ', f); + pcb_print_quoted_string(f, (char *)RND_EMPTY(pcb_attribute_get(&subc->Attributes, "value"))); + fputs(")\n", f); +} + +static void pcb_print_conn_subc_name(FILE *f, pcb_subc_t *subc) +{ + fputs("Element", f); + print_subc_name(f, subc); + fputs("{\n", f); +} + +static int count_term_cb(pcb_find_t *fctx, pcb_any_obj_t *o, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + unsigned long *cnt = fctx->user_data; + + if (o->term == NULL) + return 0; + + (*cnt)++; + if ((*cnt) > 1) + return 1; /* stop searching after the second object - no need to know how many terminals are connected, the fact that it's more than 1 is enough */ + return 0; +} + +/* prints all unused pins of a subcircuit to f */ +static void print_select_unused_subc_terms(FILE *f, pcb_subc_t *subc, int do_select) +{ + unsigned long cnt; + pcb_find_t fctx; + pcb_any_obj_t *o; + pcb_data_it_t it; + int subc_announced = 0; + + memset(&fctx, 0, sizeof(fctx)); + fctx.user_data = &cnt; + fctx.found_cb = count_term_cb; + + for(o = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + if (o->term == NULL) /* consider named terminals only */ + continue; + + cnt = 0; + pcb_find_from_obj(&fctx, PCB->Data, o); + pcb_find_free(&fctx); + + if (cnt <= 1) { + if (!subc_announced) { + pcb_print_conn_subc_name(f, subc); + subc_announced = 1; + } + + fputc('\t', f); + pcb_print_quoted_string(f, (char *)RND_EMPTY(o->term)); + fputc('\n', f); + if (do_select) { + PCB_FLAG_SET(PCB_FLAG_SELECTED, o); + pcb_draw_obj(o); + } + } + } + + /* print separator if element has unused pins or pads */ + if (subc_announced) { + fputs("}\n\n", f); + SEPARATE(f); + } +} + +typedef struct { + FILE *f; + pcb_any_obj_t *start; +} term_cb_t; + +static int print_term_conn_cb(pcb_find_t *fctx, pcb_any_obj_t *o, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + term_cb_t *ctx = fctx->user_data; + pcb_subc_t *sc; + + if (ctx->start == o) + return 0; + + sc = pcb_obj_parent_subc(o); + if (sc == NULL) + return 0; + + fputs("\t\t", ctx->f); + pcb_print_quoted_string(ctx->f, RND_EMPTY(o->term)); + fputs(" ", ctx->f); + print_subc_name(ctx->f, sc); + return 0; +} + + +/* Find connected terminals to each terminal of subc and write them to f. */ +static void pcb_print_subc_conns(FILE *f, pcb_subc_t *subc) +{ + pcb_any_obj_t *o; + pcb_data_it_t it; + pcb_find_t fctx; + term_cb_t cbctx; + + pcb_print_conn_subc_name(f, subc); + + cbctx.f = f; + memset(&fctx, 0, sizeof(fctx)); + + for(o = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + if (o->term == NULL) /* consider named terminals only */ + continue; + + fputs("\t", f); + pcb_print_quoted_string(f, RND_EMPTY(o->term)); + fputs("\n\t{\n", f); + + cbctx.start = o; + fctx.user_data = &cbctx; + fctx.found_cb = print_term_conn_cb; + pcb_find_from_obj(&fctx, PCB->Data, o); + pcb_find_free(&fctx); + + fputs("\t}\n", f); + } + fputs("}\n\n", f); +} + +/* Find and print (to f) all unused pins of all subcircuits */ +static void pcb_lookup_unused_pins(FILE *f, int do_select) +{ + PCB_SUBC_LOOP(PCB->Data); + { + print_select_unused_subc_terms(f, subc, do_select); + } + PCB_END_LOOP; + + if (conf_core.editor.beep_when_finished) + rnd_gui->beep(rnd_gui); + + if (do_select) { + pcb_undo_inc_serial(); + pcb_draw(); + } +} + +/* Find and print (to f) all connections from terminals of subc */ +static void pcb_lookup_subc_conns(FILE *f, pcb_subc_t *subc) +{ + pcb_print_subc_conns(f, subc); + if (conf_core.editor.beep_when_finished) + rnd_gui->beep(rnd_gui); +} + +/* Find all connections from all terminals of all subcircuits and print in f. */ +static void pcb_lookup_conns_to_all_subcs(FILE *f) +{ + PCB_SUBC_LOOP(PCB->Data); + { + pcb_print_subc_conns(f, subc); + SEPARATE(f); + } + PCB_END_LOOP; + + if (conf_core.editor.beep_when_finished) + rnd_gui->beep(rnd_gui); + rnd_hid_redraw(PCB); +} + +static FILE *pcb_check_and_open_file(const char *Filename) +{ + FILE *fp = NULL; + + if ((Filename != NULL) && (*Filename != '\0')) { + char message[RND_PATH_MAX + 80]; + int response; + + if (rnd_file_readable(Filename)) { + sprintf(message, "File '%s' exists, use anyway?", Filename); + response = rnd_hid_message_box(&PCB->hidlib, "warning", "Overwrite file", message, "cancel", 0, "ok", 1, NULL); + if (response != 1) + return NULL; + } + if ((fp = rnd_fopen_askovr(&PCB->hidlib, Filename, "w", NULL)) == NULL) + rnd_open_error_message(Filename); + } + return fp; +} + +static const char pcb_acts_ExportOldConn[] = "ExportOldConn(AllConnections|AllUnusedPins|ElementConnections,filename)\n"; +static const char pcb_acth_ExportOldConn[] = "Export galvanic connection data in an old, custom file format."; +/* DOC: exportoldconn.html */ +fgw_error_t pcb_act_ExportOldConn(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op; + const char *name = NULL; + FILE *f; + void *ptrtmp; + rnd_coord_t x, y; + + RND_ACT_CONVARG(1, FGW_KEYWORD, ExportOldConn, op = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, ExportOldConn, name = argv[2].val.str); + RND_ACT_IRES(0); + + switch(op) { + case F_AllConnections: + f = pcb_check_and_open_file(name); + if (f != NULL) { + pcb_lookup_conns_to_all_subcs(f); + fclose(f); + } + return 0; + + case F_AllUnusedPins: + f = pcb_check_and_open_file(name); + if (f != NULL) { + pcb_lookup_unused_pins(f, 1); + fclose(f); + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + } + return 0; + + case F_ElementConnections: + case F_SubcConnections: + rnd_hid_get_coords("Click on a subc", &x, &y, 0); + if (pcb_search_screen(x, y, PCB_OBJ_SUBC, &ptrtmp, &ptrtmp, &ptrtmp) != PCB_OBJ_VOID) { + pcb_subc_t *subc = (pcb_subc_t *) ptrtmp; + f = pcb_check_and_open_file(name); + if (f != NULL) { + pcb_lookup_subc_conns(f, subc); + fclose(f); + } + } + return 0; + } + RND_ACT_FAIL(ExportOldConn); +} + +static rnd_action_t oldconn_action_list[] = { + {"ExportOldConn", pcb_act_ExportOldConn, pcb_acth_ExportOldConn, pcb_acts_ExportOldConn} +}; + +int pplg_check_ver_export_oldconn(int ver_needed) { return 0; } + +void pplg_uninit_export_oldconn(void) +{ + rnd_remove_actions_by_cookie(oldconn_cookie); +} + +int pplg_init_export_oldconn(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(oldconn_action_list, oldconn_cookie) + + return 0; +} Index: tags/2.3.0/src_plugins/export_openems/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_openems/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_openems/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_openems + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_openems/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_openems/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_openems/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {export_openems} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/export_openems/export_openems.o + $(PLUGDIR)/export_openems/mesh.o +@] + +switch /local/pcb/export_openems/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_openems/excitation.c =================================================================== --- tags/2.3.0/src_plugins/export_openems/excitation.c (nonexistent) +++ tags/2.3.0/src_plugins/export_openems/excitation.c (revision 33253) @@ -0,0 +1,573 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include "event.h" + +#define MAX_EXC 16 +#define FREQ_MAX ((double)(100.0*1000.0*1000.0*1000.0)) +#define AEPREFIX "openems::excitation::" + +typedef struct { + int w[8]; +} exc_data_t; + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ + int wselector, wtab; + int selected; + exc_data_t exc_data[MAX_EXC]; +} exc_ctx_t; + +exc_ctx_t exc_ctx; + +typedef struct { + const char *name; + void (*dad)(int idx); + char *(*get)(int idx, int fmt_matlab); + void (*ser)(int idx, int save); /* serialization: if save is 1, set attributes, else load attributes */ + int type_id; +} exc_t; +#define MAX_EXC_TYPES 5 +static const exc_t excitations[MAX_EXC_TYPES]; + + +static void ser_save(const char *data, const char *attrkey) +{ + const char *orig = pcb_attribute_get(&PCB->Attributes, attrkey); + if ((orig == NULL) || (strcmp(orig, data) != 0)) { + pcb_attribute_put(&PCB->Attributes, attrkey, data); + pcb_board_set_changed_flag(PCB, rnd_true); + } +} + +static const char *ser_load(const char *attrkey) +{ + return pcb_attribute_get(&PCB->Attributes, attrkey); +} + +#if 0 +/* unused at the moment */ +static void ser_int(int save, int widx, const char *attrkey) +{ + if (save) { + char tmp[128]; + sprintf(tmp, "%d", exc_ctx.dlg[widx].val.lng); + ser_save(tmp, attrkey); + } + else { + rnd_hid_attr_val_t hv; + char *end; + const char *orig = ser_load(attrkey); + + if (orig != NULL) { + hv.lng = strtol(orig, &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Invalid integer value in board attribute '%s': '%s'\n", attrkey, orig); + hv.lng = 0; + } + } + else + hv.lng = 0; + + rnd_gui->attr_dlg_set_value(exc_ctx.dlg_hid_ctx, widx, &hv); + } +} +#endif + +static void ser_hz(int save, int widx, const char *attrkey) +{ + if (save) { + char tmp[128]; + sprintf(tmp, "%f Hz", exc_ctx.dlg[widx].val.dbl); + ser_save(tmp, attrkey); + } + else { + rnd_hid_attr_val_t hv; + char *end; + const char *orig = ser_load(attrkey); + + if (orig != NULL) { + hv.dbl = strtod(orig, &end); + if (*end != '\0') { + while(isspace(*end)) end++; + if (rnd_strcasecmp(end, "hz") != 0) { + rnd_message(RND_MSG_ERROR, "Invalid real value (Hz) in board attribute '%s': '%s'\n", attrkey, orig); + hv.dbl = 0; + } + } + } + else + hv.dbl = 0; + + rnd_gui->attr_dlg_set_value(exc_ctx.dlg_hid_ctx, widx, &hv); + } +} + +static void ser_str(int save, int widx, const char *attrkey) +{ + if (save) { + ser_save(exc_ctx.dlg[widx].val.str, attrkey); + } + else { + rnd_hid_attr_val_t hv; + hv.str = ser_load(attrkey); + if (hv.str == NULL) + hv.str = ""; + rnd_gui->attr_dlg_set_value(exc_ctx.dlg_hid_ctx, widx, &hv); + } +} + +static void exc_val_chg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr); + +static rnd_bool to_hz(const char *s, double *out) +{ + const rnd_unit_t *u; + double d; + if (!rnd_get_value_unit(s, NULL, 0, &d, &u)) + return rnd_false; + if (u->family != RND_UNIT_FREQ) + return rnd_false; + *out = d; + return rnd_true; +} + +/*** excitation "micro-plugins" ***/ + +#define I_FC 0 +#define I_F0 1 + +/** gaussian **/ +static void exc_gaus_dad(int idx) +{ + RND_DAD_BEGIN_TABLE(exc_ctx.dlg, 2); + RND_DAD_LABEL(exc_ctx.dlg, "fc"); + RND_DAD_SPIN_FREQ(exc_ctx.dlg); + RND_DAD_MINMAX(exc_ctx.dlg, 0, FREQ_MAX); + RND_DAD_HELP(exc_ctx.dlg, "20db Cutoff Frequency\nbandwidth is 2*fc"); + RND_DAD_CHANGE_CB(exc_ctx.dlg, exc_val_chg_cb); + exc_ctx.exc_data[idx].w[I_FC] = RND_DAD_CURRENT(exc_ctx.dlg); + + RND_DAD_LABEL(exc_ctx.dlg, "f0"); + RND_DAD_REAL(exc_ctx.dlg); + RND_DAD_MINMAX(exc_ctx.dlg, 0, FREQ_MAX); + RND_DAD_HELP(exc_ctx.dlg, "Center Frequency [Hz]"); + RND_DAD_CHANGE_CB(exc_ctx.dlg, exc_val_chg_cb); + exc_ctx.exc_data[idx].w[I_F0] = RND_DAD_CURRENT(exc_ctx.dlg); + + RND_DAD_END(exc_ctx.dlg); +} + + +static char *exc_gaus_get(int idx, int fmt_matlab) +{ + double f0 = 0, fc = 0; + + if (!to_hz(pcb_attribute_get(&PCB->Attributes, AEPREFIX "gaussian::f0"), &f0)) + rnd_message(RND_MSG_ERROR, "Gauss excitation: unable to parse frequency gaussian::f0\n"); + + if (!to_hz(pcb_attribute_get(&PCB->Attributes, AEPREFIX "gaussian::fc"), &fc)) + rnd_message(RND_MSG_ERROR, "Gauss excitation: unable to parse frequency gaussian::fc\n"); + + if (fmt_matlab) + return rnd_strdup_printf("FDTD = SetGaussExcite(FDTD, %f, %f);", fc, f0); + + return rnd_strdup_printf("Type='%d' f0='%f' fc='%f'", excitations[idx].type_id, fc, f0); +} + +static void exc_gaus_ser(int idx, int save) +{ + ser_hz(save, exc_ctx.exc_data[idx].w[I_F0], AEPREFIX "gaussian::f0"); + ser_hz(save, exc_ctx.exc_data[idx].w[I_FC], AEPREFIX "gaussian::fc"); +} + +#undef I_FC +#undef I_F0 + +/** sinusoidal **/ + +#define I_F0 0 + +static void exc_sin_dad(int idx) +{ + RND_DAD_BEGIN_TABLE(exc_ctx.dlg, 2); + RND_DAD_LABEL(exc_ctx.dlg, "f0"); + RND_DAD_REAL(exc_ctx.dlg); + RND_DAD_MINMAX(exc_ctx.dlg, 0, FREQ_MAX); + RND_DAD_HELP(exc_ctx.dlg, "Center Frequency [Hz]"); + RND_DAD_CHANGE_CB(exc_ctx.dlg, exc_val_chg_cb); + exc_ctx.exc_data[idx].w[I_F0] = RND_DAD_CURRENT(exc_ctx.dlg); + RND_DAD_END(exc_ctx.dlg); +} + +static char *exc_sin_get(int idx, int fmt_matlab) +{ + double f0; + + if (!to_hz(pcb_attribute_get(&PCB->Attributes, AEPREFIX "sinusoidal::f0"), &f0)) + rnd_message(RND_MSG_ERROR, "Sinus excitation: unable to parse frequency sinusoidal::f0\n"); + + if (fmt_matlab) + return rnd_strdup_printf("FDTD = SetSinusExcite(FDTD, %f);", f0); + return rnd_strdup_printf("Type='%d' f0='%f'", excitations[idx].type_id, f0); +} + +static void exc_sin_ser(int idx, int save) +{ + ser_hz(save, exc_ctx.exc_data[idx].w[I_F0], AEPREFIX "sinusoidal::f0"); +} + +#undef I_F0 + +/** custom **/ + +#define I_F0 0 +#define I_FUNC 1 + +static void exc_cust_dad(int idx) +{ + RND_DAD_BEGIN_TABLE(exc_ctx.dlg, 2); + RND_DAD_LABEL(exc_ctx.dlg, "f0"); + RND_DAD_REAL(exc_ctx.dlg); + RND_DAD_MINMAX(exc_ctx.dlg, 0, FREQ_MAX); + RND_DAD_HELP(exc_ctx.dlg, "Nyquest Rate [Hz]"); + RND_DAD_CHANGE_CB(exc_ctx.dlg, exc_val_chg_cb); + exc_ctx.exc_data[idx].w[I_F0] = RND_DAD_CURRENT(exc_ctx.dlg); + + RND_DAD_LABEL(exc_ctx.dlg, "function"); + RND_DAD_STRING(exc_ctx.dlg); + RND_DAD_HELP(exc_ctx.dlg, "Custom function"); + RND_DAD_CHANGE_CB(exc_ctx.dlg, exc_val_chg_cb); + exc_ctx.exc_data[idx].w[I_FUNC] = RND_DAD_CURRENT(exc_ctx.dlg); + RND_DAD_END(exc_ctx.dlg); +} + +static char *exc_cust_get(int idx, int fmt_matlab) +{ + double f0; + + if (!to_hz(pcb_attribute_get(&PCB->Attributes, AEPREFIX "custom::f0"), &f0)) + rnd_message(RND_MSG_ERROR, "Custom excitation: unable to parse frequency custom::f0\n"); + + if (fmt_matlab) + return rnd_strdup_printf( + "FDTD = SetCustomExcite(FDTD, %f, %s)", + f0, + pcb_attribute_get(&PCB->Attributes, AEPREFIX "custom::func") + ); + + return rnd_strdup_printf("Type='%d' f0='%f' Function='%s'", + excitations[idx].type_id, + f0, + pcb_attribute_get(&PCB->Attributes, AEPREFIX "custom::func") + ); +} + +static void exc_cust_ser(int idx, int save) +{ + ser_hz(save, exc_ctx.exc_data[idx].w[I_F0], AEPREFIX "custom::f0"); + ser_str(save, exc_ctx.exc_data[idx].w[I_FUNC], AEPREFIX "custom::func"); +} + +#undef I_F0 +#undef I_FUNC + + +/** user-specified **/ + +#define I_SCRIPT 0 + +static void exc_user_dad(int idx) +{ + RND_DAD_BEGIN_VBOX(exc_ctx.dlg); + RND_DAD_COMPFLAG(exc_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(exc_ctx.dlg, "Specify the excitation setup script:"); + RND_DAD_TEXT(exc_ctx.dlg, NULL); + RND_DAD_COMPFLAG(exc_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_CHANGE_CB(exc_ctx.dlg, exc_val_chg_cb); + exc_ctx.exc_data[idx].w[I_SCRIPT] = RND_DAD_CURRENT(exc_ctx.dlg); + RND_DAD_END(exc_ctx.dlg); +} + +static char *exc_user_get(int idx, int fmt_matlab) +{ + if (fmt_matlab) + return rnd_strdup(pcb_attribute_get(&PCB->Attributes, AEPREFIX "user-defined::script")); + return NULL; +} + +static void exc_user_ser(int idx, int save) +{ + int wscript; + rnd_hid_attribute_t *attr; + rnd_hid_text_t *txt; + + wscript = exc_ctx.exc_data[idx].w[I_SCRIPT]; + attr = &exc_ctx.dlg[wscript]; + txt = attr->wdata; + + ser_save(txt->hid_get_text(attr, exc_ctx.dlg_hid_ctx), AEPREFIX "user-defined::script"); +} + +#undef I_SCRIPT +/*** generic code ***/ + +static const exc_t excitations[MAX_EXC_TYPES] = { + { "gaussian", exc_gaus_dad, exc_gaus_get, exc_gaus_ser, 0 }, + { "sinusoidal", exc_sin_dad, exc_sin_get, exc_sin_ser, 1 }, + { "custom", exc_cust_dad, exc_cust_get, exc_cust_ser, 10 }, + { "user-defined", exc_user_dad, exc_user_get, exc_user_ser, -1 }, + /* pending IDs: dirac=2, step=3 */ + { NULL, NULL} +}; + +static void exc_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + exc_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(exc_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void exc_load_all(void) +{ + const exc_t *e; + int n; + for(n = 0, e = excitations; e->name != NULL; n++,e++) + e->ser(n, 0); +} + +static int load_selector(void) +{ + const char *type = pcb_attribute_get(&PCB->Attributes, AEPREFIX "type"); + const exc_t *e; + int n; + + if (type == NULL) { + exc_ctx.selected = 0; + return 0; + } + + for(n = 0, e = excitations; e->name != NULL; n++,e++) { + if (strcmp(e->name, type) == 0) { + exc_ctx.selected = n; + return 0; + } + } + + return -1; +} + +static void select_update(int setattr) +{ + rnd_hid_attr_val_t hv; + hv.lng = exc_ctx.selected; + + if ((exc_ctx.selected < 0) || (exc_ctx.selected >= sizeof(excitations)/sizeof(excitations[0]))) { + rnd_message(RND_MSG_ERROR, "Invalid excitation selected\n"); + exc_ctx.selected = 0; + } + + rnd_gui->attr_dlg_set_value(exc_ctx.dlg_hid_ctx, exc_ctx.wtab, &hv); + rnd_gui->attr_dlg_set_value(exc_ctx.dlg_hid_ctx, exc_ctx.wselector, &hv); + if (setattr) { + const char *orig = pcb_attribute_get(&PCB->Attributes, "openems::excitation::type"); + if ((orig == NULL) || (strcmp(orig, excitations[exc_ctx.selected].name) != 0)) { + pcb_attribute_put(&PCB->Attributes, "openems::excitation::type", excitations[exc_ctx.selected].name); + pcb_board_set_changed_flag(PCB, rnd_true); + } + } +} + +static void select_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + exc_ctx.selected = attr->val.lng; + select_update(1); +} + +static void exc_val_chg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + excitations[exc_ctx.selected].ser(exc_ctx.selected, 1); +} + +static void pcb_dlg_exc(void) +{ + static const char *excnames[MAX_EXC+1]; + const exc_t *e; + int n; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + if (exc_ctx.active) + return; /* do not open another */ + + if (excnames[0] == NULL) { + for(n = 0, e = excitations; e->name != NULL; n++,e++) { + if (n >= MAX_EXC) { + rnd_message(RND_MSG_ERROR, "internal error: too many excitations"); + break; + } + excnames[n] = e->name; + } + excnames[n] = NULL; + } + + RND_DAD_BEGIN_VBOX(exc_ctx.dlg); + RND_DAD_COMPFLAG(exc_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(exc_ctx.dlg); + RND_DAD_LABEL(exc_ctx.dlg, "Excitation type:"); + RND_DAD_ENUM(exc_ctx.dlg, excnames); + exc_ctx.wselector = RND_DAD_CURRENT(exc_ctx.dlg); + RND_DAD_CHANGE_CB(exc_ctx.dlg, select_cb); + RND_DAD_END(exc_ctx.dlg); + RND_DAD_BEGIN_TABBED(exc_ctx.dlg, excnames); + RND_DAD_COMPFLAG(exc_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_HIDE_TABLAB); + exc_ctx.wtab = RND_DAD_CURRENT(exc_ctx.dlg); + for(n = 0, e = excitations; e->name != NULL; n++,e++) { + if (e->dad != NULL) + e->dad(n); + else + RND_DAD_LABEL(exc_ctx.dlg, "Not yet available."); + } + RND_DAD_END(exc_ctx.dlg); + RND_DAD_BUTTON_CLOSES(exc_ctx.dlg, clbtn); + RND_DAD_END(exc_ctx.dlg); + + /* set up the context */ + exc_ctx.active = 1; + + RND_DAD_NEW("openems_excitation", exc_ctx.dlg, "openems: excitation", &exc_ctx, rnd_false, exc_close_cb); + + load_selector(); + select_update(1); + exc_load_all(); +} + +static const char pcb_acts_OpenemsExcitation[] = + "OpenemsExcitation([interactive])\n" + "OpenemsExcitation(select, excitationname)\n" + "OpenemsExcitation(set, [excitationnme], paramname, paramval)\n" + "OpenemsExcitation(get, [excitationnme], paramname)\n" + ; +static const char pcb_acth_OpenemsExcitation[] = "Select which openEMS excitation method should be exported and manipulate the associated parameters. When invoked without arguments a dialog box with the same functionality is presented."; +/* DOC: openemsexcication.html */ +static fgw_error_t pcb_act_OpenemsExcitation(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *op = "interactive", *a1 = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, OpenemsExcitation, op = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, OpenemsExcitation, a1 = argv[2].val.str); + + RND_ACT_IRES(0); + + if (strcmp(op, "interactive") == 0) + pcb_dlg_exc(); + else if (strcmp(op, "select") == 0) { + if (a1 == NULL) { + rnd_message(RND_MSG_ERROR, "OpenemsExcitation(select) needs a excitation name"); + goto error; + } + pcb_attribute_put(&PCB->Attributes, AEPREFIX "type", a1); + load_selector(); + select_update(1); + } + else if (strcmp(op, "set") == 0) { + int start; + const char *key, *val; + char *attrkey; + switch(argc) { + case 4: a1 = excitations[exc_ctx.selected].name; start = 2; break; + case 5: start = 3; break; + default: + rnd_message(RND_MSG_ERROR, "OpenemsExcitation(set) needs exactly 2 or 3 more arguments"); + goto error; + } + + RND_ACT_CONVARG(start+0, FGW_STR, OpenemsExcitation, key = argv[start+0].val.str); + RND_ACT_CONVARG(start+1, FGW_STR, OpenemsExcitation, val = argv[start+1].val.str); + + attrkey = rnd_strdup_printf(AEPREFIX "%s::%s", a1, key); + pcb_attribute_put(&PCB->Attributes, attrkey, val); + free(attrkey); + + exc_load_all(); + } + else if (strcmp(op, "get") == 0) { + int start; + const char *key; + char *attrkey; + switch(argc) { + case 3: a1 = excitations[exc_ctx.selected].name; start = 2; break; + case 4: start = 3; break; + default: + rnd_message(RND_MSG_ERROR, "OpenemsExcitation(get) needs exactly 1 or 2 more arguments"); + goto error; + } + + RND_ACT_CONVARG(start+0, FGW_STR, OpenemsExcitation, key = argv[start+0].val.str); + + attrkey = rnd_strdup_printf(AEPREFIX "%s::%s", a1, key); + res->type = FGW_STR; + res->val.cstr = pcb_attribute_get(&PCB->Attributes, attrkey); + free(attrkey); + } + + return 0; + + error:; + RND_ACT_IRES(1); + return 0; +} + +static char *pcb_openems_excitation_get(pcb_board_t *pcb, int fmt_matlab) +{ + if ((exc_ctx.selected < 0) || (exc_ctx.selected >= sizeof(excitations)/sizeof(excitations[0]))) { + rnd_message(RND_MSG_ERROR, "No excitation selected\n"); + if (fmt_matlab) + return rnd_strdup("%% ERROR: no excitation selected\n"); + else + return NULL; + } + return excitations[exc_ctx.selected].get(exc_ctx.selected, fmt_matlab); +} + +static void exc_ev_board_changed(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + load_selector(); + if (exc_ctx.active) + exc_load_all(); +} + +static void pcb_openems_excitation_init(void) +{ + rnd_event_bind(RND_EVENT_BOARD_CHANGED, exc_ev_board_changed, NULL, openems_cookie); +} + +static void pcb_openems_excitation_uninit(void) +{ + rnd_event_unbind_allcookie(openems_cookie); +} Index: tags/2.3.0/src_plugins/export_openems/export_openems.c =================================================================== --- tags/2.3.0/src_plugins/export_openems/export_openems.c (nonexistent) +++ tags/2.3.0/src_plugins/export_openems/export_openems.c (revision 33253) @@ -0,0 +1,969 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "data_it.h" +#include "draw.h" +#include +#include +#include +#include "layer_vis.h" +#include "obj_subc_parent.h" +#include "obj_pstk_inlines.h" + +#include +#include +#include +#include "hid_cam.h" +#include +#include +#include "../src_plugins/lib_polyhelp/topoly.h" +#include "mesh.h" + +static rnd_hid_t openems_hid; + +const char *openems_cookie = "openems HID"; + +#include "excitation.c" + +#define MESH_NAME "openems" + +#define PRIO_SUBSTRATE 1 +#define PRIO_COPPER 2 +#define PRIO_PORT 999 + +typedef struct rnd_hid_gc_s { + rnd_core_gc_t core_gc; + rnd_hid_t *me_pointer; + rnd_cap_style_t cap; + int width; +} rnd_hid_gc_s; + +typedef struct { + /* input/output */ + FILE *f, *fsim; + pcb_board_t *pcb; + rnd_hid_attr_val_t *options; + + /* local cache */ + const char *filename; + int lg_pcb2ems[PCB_MAX_LAYERGRP]; /* indexed by gid, gives 0 or the ems-side layer ID */ + int lg_ems2pcb[PCB_MAX_LAYERGRP]; /* indexed by the ems-side layer ID, gives -1 or a gid */ + int lg_next; + int clayer; /* current layer (lg index really) */ + long oid; /* unique object ID - we need some unique variable names, keep on counting them */ + long port_id; /* unique port ID for similar reasons */ + rnd_coord_t ox, oy; + unsigned warn_subc_term:1; + unsigned warn_port_pstk:1; + unsigned fmt_matlab:1; /* when 1, use matlab syntax; 0 means xml syntax */ + + /* xml */ + unsigned cond_sheet_open:1; + double elevation; /* in mm */ +} wctx_t; + +static FILE *f = NULL; +static wctx_t *ems_ctx; +static int openems_ovr; + + +#define THMAX RND_MM_TO_COORD(100) + +rnd_export_opt_t openems_attribute_list[] = { + {"outfile", "Graphics output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_openemsfile 0 + + {"def-copper-thick", "Default copper thickness", + RND_HATT_COORD, 0, THMAX, {0, 0, 0, RND_MM_TO_COORD(0.035)}, 0, 0}, +#define HA_def_copper_thick 1 + + {"def-substrate-thick", "Default substrate thickness", + RND_HATT_COORD, 0, THMAX, {0, 0, 0, RND_MM_TO_COORD(0.8)}, 0, 0}, +#define HA_def_substrate_thick 2 + + {"def-copper-cond", "Default copper conductivity", + RND_HATT_STRING, 0, 0, {0, "56e6", 0}, 0, 0}, +#define HA_def_copper_cond 3 + + {"def-subst-epsilon", "Default substrate epsilon", + RND_HATT_STRING, 0, 0, {0, "3.66", 0}, 0, 0}, +#define HA_def_subst_epsilon 4 + + {"def-subst-mue", "Default substrate mue", + RND_HATT_STRING, 0, 0, {0, "0", 0}, 0, 0}, +#define HA_def_subst_mue 5 + + {"def-subst-kappa", "Default substrate kappa", + RND_HATT_STRING, 0, 0, {0, "0", 0}, 0, 0}, +#define HA_def_subst_kappa 6 + + {"def-subst-sigma", "Default substrate sigma", + RND_HATT_STRING, 0, 0, {0, "0", 0}, 0, 0}, +#define HA_def_subst_sigma 7 + + {"void-name", "Name of the void (sorrunding material)", + RND_HATT_STRING, 0, 0, {0, "AIR", 0}, 0, 0}, +#define HA_void_name 8 + + {"void-epsilon", "epsilon value for the void (sorrunding material)", + RND_HATT_REAL, 0, 1000, {0, 0, 1}, 0, 0}, +#define HA_void_epsilon 9 + + {"void-mue", "mue value for the void (sorrunding material)", + RND_HATT_REAL, 0, 1000, {0, 0, 1}, 0, 0}, +#define HA_void_mue 10 + + {"segments", "kludge: number of segments used to approximate round cap trace ends", + RND_HATT_INTEGER, 0, 100, {10, 0, 0}, 0, 0}, +#define HA_segments 11 + + {"base-prio", "base priority: if the board displaces the chassis", + RND_HATT_INTEGER, 0, 10, {0, 0, 0}, 0, 0}, +#define HA_base_prio 12 + + {"port-resistance", "default port resistance", + RND_HATT_REAL, 0, 1000, {0, 0, 50}, 0, 0} +#define HA_def_port_res 13 + +}; + +#define NUM_OPTIONS (sizeof(openems_attribute_list)/sizeof(openems_attribute_list[0])) + +static rnd_hid_attr_val_t openems_values[NUM_OPTIONS]; + +static rnd_export_opt_t *openems_get_export_options(rnd_hid_t *hid, int *n) +{ + const char *suffix = ".m"; + pcb_mesh_t *mesh = pcb_mesh_get(MESH_NAME); + + if ((PCB != NULL) && (openems_attribute_list[HA_openemsfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &openems_attribute_list[HA_openemsfile], suffix); + + if (mesh != NULL) { + openems_attribute_list[HA_def_substrate_thick].default_val.crd = mesh->def_subs_thick; + openems_attribute_list[HA_def_copper_thick].default_val.crd = mesh->def_copper_thick; + } + +TODO(": when export dialogs change into DAD, this hack to convert the strings to allocated ones will not be needed anymore") + openems_attribute_list[HA_def_copper_cond].default_val.str = rnd_strdup(openems_attribute_list[HA_def_copper_cond].default_val.str); + openems_attribute_list[HA_def_subst_epsilon].default_val.str = rnd_strdup(openems_attribute_list[HA_def_subst_epsilon].default_val.str); + openems_attribute_list[HA_def_subst_mue].default_val.str = rnd_strdup(openems_attribute_list[HA_def_subst_mue].default_val.str); + openems_attribute_list[HA_def_subst_kappa].default_val.str = rnd_strdup(openems_attribute_list[HA_def_subst_kappa].default_val.str); + openems_attribute_list[HA_def_subst_sigma].default_val.str = rnd_strdup(openems_attribute_list[HA_def_subst_sigma].default_val.str); + openems_attribute_list[HA_void_name].default_val.str = rnd_strdup(openems_attribute_list[HA_void_name].default_val.str); + + if (n) + *n = NUM_OPTIONS; + return openems_attribute_list; +} + +rnd_coord_t ems_layergrp_thickness(pcb_layergrp_t *grp) +{ + return mesh_layergrp_thickness(grp, (grp->ltype & PCB_LYT_COPPER) ? openems_attribute_list[HA_def_copper_thick].default_val.crd : openems_attribute_list[HA_def_substrate_thick].default_val.crd); +} + + +/* Find the openems 0;0 mark, if there is any */ +static void find_origin_bump(void *ctx_, pcb_board_t *pcb, pcb_layer_t *layer, pcb_line_t *line) +{ + wctx_t *ctx = ctx_; + if (pcb_attribute_get(&line->Attributes, "openems-origin") != NULL) { + ctx->ox = (line->BoundingBox.X1 + line->BoundingBox.X2) / 2; + ctx->oy = (line->BoundingBox.Y1 + line->BoundingBox.Y2) / 2; + } +} + +static void find_origin(wctx_t *ctx) +{ + pcb_loop_layers(ctx->pcb, ctx, NULL, find_origin_bump, NULL, NULL, NULL, NULL); +} + +static void openems_wr_m_tunables(wctx_t *ctx) +{ + fprintf(ctx->f, "%%%%%% User tunables\n"); + fprintf(ctx->f, "\n"); + + fprintf(ctx->f, "%%%% base_priority and offset: chassis for the board to sit in.\n"); + fprintf(ctx->f, "%% base priority: if the board displaces the model of the chassis or the other way around.\n"); + fprintf(ctx->f, "base_priority=%ld;\n", ctx->options[HA_base_prio].lng); + fprintf(ctx->f, "\n"); + fprintf(ctx->f, "%% offset on the whole layout to locate it relative to the simulation origin\n"); + rnd_fprintf(ctx->f, "offset.x = %mm;\n", -ctx->ox); + rnd_fprintf(ctx->f, "offset.y = %mm;\n", ctx->oy); + fprintf(ctx->f, "offset.z = 0;\n"); + fprintf(ctx->f, "\n"); + + fprintf(ctx->f, "%% void is the material used for: fill holes, cutouts in substrate, etc\n"); + fprintf(ctx->f, "void.name = '%s';\n", ctx->options[HA_void_name].str); + fprintf(ctx->f, "void.epsilon = %f;\n", ctx->options[HA_void_epsilon].dbl); + fprintf(ctx->f, "void.mue = %f;\n", ctx->options[HA_void_mue].dbl); + fprintf(ctx->f, "%% void.kappa = kappa;\n"); + fprintf(ctx->f, "%% void.sigma = sigma;\n"); + fprintf(ctx->f, "\n"); + + fprintf(ctx->f, "%% how many points should be used to describe the round end of traces.\n"); + fprintf(ctx->f, "kludge.segments = %ld;\n", ctx->options[HA_segments].lng); + fprintf(ctx->f, "\n"); + + fprintf(ctx->f, "\n"); +} + +static void print_lparm(wctx_t *ctx, pcb_layergrp_t *grp, const char *attr, int cop_opt, int subs_opt, const char *cop_fmt, const char *subs_fmt) +{ + const char *fmt; + int opt; + +TODO(": this needs layer group attributes in core (planned for lihata v5)") +#if 0 +TODO(": try openems::attr first - make a new core call for prefixed get, this will be a real common pattern") + const char *val = pcb_attribute_get(&grp->Attributes, attr); + + if (val != NULL) { + /* specified by a layer group attribute: overrides anything else */ + if (is_str) + fprintf(ctx->f, "%s", val); + else + TODO: getvalue, print as coord + return; + } +#endif + + opt = (grp->ltype & PCB_LYT_COPPER) ? cop_opt : subs_opt; + fmt = (grp->ltype & PCB_LYT_COPPER) ? cop_fmt : subs_fmt; + assert(opt >= 0); + if (fmt == NULL) + rnd_fprintf(ctx->f, "%s", ctx->options[opt].str); + else + rnd_fprintf(ctx->f, fmt, ctx->options[opt].crd); +} + +static void openems_wr_m_layers(wctx_t *ctx) +{ + rnd_layergrp_id_t gid; + int next = 1; + + for(gid = 0; gid < PCB_MAX_LAYERGRP; gid++) + ctx->lg_ems2pcb[gid] = -1; + + fprintf(ctx->f, "%%%%%% Layer mapping\n"); + + /* linear map of copper and substrate layers */ + for(gid = 0; gid < ctx->pcb->LayerGroups.len; gid++) { + pcb_layergrp_t *grp = &ctx->pcb->LayerGroups.grp[gid]; + int iscop = (grp->ltype & PCB_LYT_COPPER); + + if (!(iscop) && !(grp->ltype & PCB_LYT_SUBSTRATE)) + continue; + ctx->lg_ems2pcb[next] = gid; + ctx->lg_pcb2ems[gid] = next; + + fprintf(ctx->f, "layers(%d).number = %d;\n", next, next); /* type index really */ + fprintf(ctx->f, "layers(%d).name = '%s';\n", next, (grp->name == NULL ? "anon" : grp->name)); + fprintf(ctx->f, "layers(%d).clearn = 0;\n", next); + fprintf(ctx->f, "layer_types(%d).name = '%s_%d';\n", next, iscop ? "COPPER" : "SUBSTRATE", next); + fprintf(ctx->f, "layer_types(%d).subtype = %d;\n", next, iscop ? 2 : 3); + + fprintf(ctx->f, "layer_types(%d).thickness = ", next); + print_lparm(ctx, grp, "thickness", HA_def_copper_thick, HA_def_substrate_thick, "%.09mm/1000", "%.09mm"); /* the /1000 works around that openems ignores the default mm unit and reads this one value in meter */ + fprintf(ctx->f, ";\n"); + + if (iscop) { + fprintf(ctx->f, "layer_types(%d).conductivity = ", next); + print_lparm(ctx, grp, "conductivity", HA_def_copper_cond, -1, NULL, NULL); + fprintf(ctx->f, ";\n"); + } + else { /* substrate */ + fprintf(ctx->f, "layer_types(%d).epsilon = ", next); + print_lparm(ctx, grp, "epsilon", -1, HA_def_subst_epsilon, NULL, NULL); + fprintf(ctx->f, ";\n"); + + fprintf(ctx->f, "layer_types(%d).mue = ", next); + print_lparm(ctx, grp, "mue", -1, HA_def_subst_mue, NULL, NULL); + fprintf(ctx->f, ";\n"); + + fprintf(ctx->f, "layer_types(%d).kappa = ", next); + print_lparm(ctx, grp, "kappa", -1, HA_def_subst_kappa, NULL, NULL); + fprintf(ctx->f, ";\n"); + + fprintf(ctx->f, "layer_types(%d).sigma = ", next); + print_lparm(ctx, grp, "sigma", -1, HA_def_subst_sigma, NULL, NULL); + fprintf(ctx->f, ";\n"); + + } + + next++; + fprintf(ctx->f, "\n"); + } + fprintf(ctx->f, "\n"); + + ctx->lg_next = next; +} + +static void openems_wr_m_init(wctx_t *ctx) +{ + fprintf(ctx->f, "%%%%%% Initialize pcb2csx\n"); + fprintf(ctx->f, "PCBRND = InitPCBRND(layers, layer_types, void, base_priority, offset, kludge);\n"); + fprintf(ctx->f, "CSX = InitPcbrndLayers(CSX, PCBRND);\n"); + fprintf(ctx->f, "\n"); +} + +static void openems_wr_m_outline(wctx_t *ctx) +{ + int n; + pcb_any_obj_t *out1; + + fprintf(ctx->f, "%%%%%% Board outline\n"); + +TODO("layer: consider multiple outline layers instead") + out1 = pcb_topoly_find_1st_outline(ctx->pcb); + if (out1 != NULL) { + long n; + pcb_poly_t *p = pcb_topoly_conn(ctx->pcb, out1, PCB_TOPOLY_KEEP_ORIG | PCB_TOPOLY_FLOATING); + for(n = 0; n < p->PointN; n++) + rnd_fprintf(ctx->f, "outline_xy(1, %ld) = %mm; outline_xy(2, %ld) = %mm;\n", n+1, p->Points[n].X, n+1, -p->Points[n].Y); + pcb_poly_free(p); + } + else { + /* rectangular board size */ + rnd_fprintf(ctx->f, "outline_xy(1, 1) = 0; outline_xy(2, 1) = 0;\n"); + rnd_fprintf(ctx->f, "outline_xy(1, 2) = %mm; outline_xy(2, 2) = 0;\n", ctx->pcb->hidlib.size_x); + rnd_fprintf(ctx->f, "outline_xy(1, 3) = %mm; outline_xy(2, 3) = %mm;\n", ctx->pcb->hidlib.size_x, -ctx->pcb->hidlib.size_y); + rnd_fprintf(ctx->f, "outline_xy(1, 4) = 0; outline_xy(2, 4) = %mm;\n", -ctx->pcb->hidlib.size_y); + } + + /* create all substrate layers using this polygon*/ + for(n = 1; n < ctx->lg_next; n++) { + pcb_layergrp_t *grp = &ctx->pcb->LayerGroups.grp[ctx->lg_ems2pcb[n]]; + if (grp->ltype & PCB_LYT_SUBSTRATE) + fprintf(ctx->f, "CSX = AddPcbrndPoly(CSX, PCBRND, %d, outline_xy, 1);\n", n); + } + + fprintf(ctx->f, "\n"); +} + +static void openems_wr_m_vport(wctx_t *ctx, pcb_any_obj_t *o, rnd_coord_t x, rnd_coord_t y, rnd_layergrp_id_t gid1, rnd_layergrp_id_t gid2, const char *safe_name, double resistance, int act) +{ + ctx->port_id++; + + rnd_fprintf(ctx->f, "\npoint%s(1, 1) = %mm; point%s(2, 1) = %mm;\n", safe_name, x, safe_name, -y); + fprintf(ctx->f, "[start%s, stop%s] = CalcPcbrnd2PortV(PCBRND, point%s, %d, %d);\n", safe_name, safe_name, safe_name, ctx->lg_pcb2ems[gid1], ctx->lg_pcb2ems[gid2]); + fprintf(ctx->f, "[CSX, port{%ld}] = AddLumpedPort(CSX, 999, %ld, %f, start%s, stop%s, [0 0 -1]%s);\n", ctx->port_id, ctx->port_id, resistance, safe_name, safe_name, act ? ", true" : ""); +} + +static void openems_wr_xml_vport(wctx_t *ctx, pcb_any_obj_t *o, rnd_coord_t x, rnd_coord_t y, rnd_layergrp_id_t gid1, rnd_layergrp_id_t gid2, const char *safe_name, double resistance, int act); + +static void openems_vport_write(wctx_t *ctx, pcb_any_obj_t *o, rnd_coord_t x, rnd_coord_t y, rnd_layergrp_id_t gid1, rnd_layergrp_id_t gid2, const char *port_name) +{ + char *end, *s, *safe_name = rnd_strdup(port_name); + const char *att; + double resistance = ctx->options[HA_def_port_res].dbl; + int act = 1; + + att = pcb_attribute_get(&o->Attributes, "openems::resistance"); + if (att != NULL) { + double tmp = strtod(att, &end); + if (*end == '\0') + resistance = tmp; + else + rnd_message(RND_MSG_WARNING, "Ignoring invalid openems::resistance value for port %s: '%s' (must be a number without suffix)\n", port_name, att); + } + + att = pcb_attribute_get(&o->Attributes, "openems::active"); + if (att != NULL) { + if (rnd_strcasecmp(att, "true") == 0) + act = 1; + else if (rnd_strcasecmp(att, "false") == 0) + act = 0; + else + rnd_message(RND_MSG_WARNING, "Ignoring invalid openems::active value for port %s: '%s' (must be true or false)\n", port_name, att); + } + + for(s = safe_name; *s != '\0'; s++) + if (!isalnum(*s)) + *s = '_'; + + if (ctx->fmt_matlab) + openems_wr_m_vport(ctx, o, x, y, gid1, gid2, safe_name, resistance, act); + else + openems_wr_xml_vport(ctx, o, x, y, gid1, gid2, safe_name, resistance, act); + + free(safe_name); +} + +rnd_layergrp_id_t openems_vport_main_group_pstk(pcb_board_t *pcb, pcb_pstk_t *ps, int *gstep, const char *port_name) +{ + int top, bot, intern; + rnd_layergrp_id_t gid1; + + top = (pcb_pstk_shape(ps, PCB_LYT_COPPER | PCB_LYT_TOP, 0) != NULL); + bot = (pcb_pstk_shape(ps, PCB_LYT_COPPER | PCB_LYT_BOTTOM, 0) != NULL); + intern = (pcb_pstk_shape(ps, PCB_LYT_INTERN | PCB_LYT_BOTTOM, 0) != NULL); + if (intern) { + rnd_message(RND_MSG_ERROR, "Can not export openems vport %s: it has internal copper\n(must be either top or bottom copper)\n", port_name); + return -1; + } + if (top && bot) { + rnd_message(RND_MSG_ERROR, "Can not export openems vport %s: it has both top and bottom copper\n", port_name); + return -1; + } + if (!top && !bot) { + rnd_message(RND_MSG_ERROR, "Can not export openems vport %s: it does not have copper either on top or bottom\n", port_name); + return -1; + } + + /* pick main group */ + if (top) { + gid1 = pcb_layergrp_get_top_copper(); + *gstep = +1; + } + else { + gid1 = pcb_layergrp_get_bottom_copper(); + *gstep = -1; + } + if (gid1 < 0) { + rnd_message(RND_MSG_ERROR, "Can not export openems vport %s: can not find top or bottom layer group ID\n", port_name); + return -1; + } + + return gid1; +} + +rnd_layergrp_id_t openems_vport_aux_group(pcb_board_t *pcb, rnd_layergrp_id_t gid1, int gstep, const char *port_name) +{ + rnd_layergrp_id_t gid2; + + for(gid2 = gid1 + gstep; (gid2 >= 0) && (gid2 <= pcb->LayerGroups.len); gid2 += gstep) + if (pcb->LayerGroups.grp[gid2].ltype & PCB_LYT_COPPER) + return gid2; + + rnd_message(RND_MSG_ERROR, "Can not export openems vport %s: can not find pair layer\n", port_name); + return -1; +} + + +#define TPMASK (PCB_OBJ_LINE | PCB_OBJ_PSTK | PCB_OBJ_SUBC) +static void openems_wr_testpoints(wctx_t *ctx, pcb_data_t *data) +{ + pcb_any_obj_t *o; + pcb_data_it_t it; + + for(o = pcb_data_first(&it, data, TPMASK); o != NULL; o = pcb_data_next(&it)) { + const char *port_name; + if (o->type == PCB_OBJ_SUBC) + openems_wr_testpoints(ctx, ((pcb_subc_t *)o)->data); + + port_name = pcb_attribute_get(&o->Attributes, "openems::vport"); + if (port_name == NULL) + continue; + + if (o->type == PCB_OBJ_SUBC) { + if (!ctx->warn_subc_term) + rnd_message(RND_MSG_ERROR, "Subcircuit being a terminal is not supported.\n"); + ctx->warn_subc_term = 1; + continue; + } + + /* place the vertical port */ + switch(o->type) { + case PCB_OBJ_PSTK: + { + int gstep; + rnd_layergrp_id_t gid1, gid2; + pcb_pstk_t *ps = (pcb_pstk_t *)o; + + if (port_name == NULL) + break; + + gid1 = openems_vport_main_group_pstk(ctx->pcb, ps, &gstep, port_name); + if (gid1 < 0) + break; + + gid2 = openems_vport_aux_group(ctx->pcb, gid1, gstep, port_name); + if (gid2 < 0) + break; + +TODO(": check if there is copper object on hid2 at x;y") + + if (pcb_attribute_get(&o->Attributes, "openems::vport-reverse") == NULL) + openems_vport_write(ctx, (pcb_any_obj_t *)ps, ps->x, ps->y, gid1, gid2, port_name); + else + openems_vport_write(ctx, (pcb_any_obj_t *)ps, ps->x, ps->y, gid2, gid1, port_name); + } + break; + default: + if (!ctx->warn_port_pstk) + rnd_message(RND_MSG_ERROR, "Only padstacks can be openems ports at the moment\n"); + ctx->warn_port_pstk = 1; + break; + } + } +} + +static void openems_wr_m_mesh_lines(wctx_t *ctx, pcb_mesh_lines_t *l) +{ + rnd_cardinal_t n; + for(n = 0; n < vtc0_len(&l->result); n++) + rnd_fprintf(ctx->f, "%s%mm", (n == 0 ? "" : " "), l->result.array[n]); +} + +static void openems_wr_m_mesh1(wctx_t *ctx) +{ + pcb_mesh_t *mesh = pcb_mesh_get(MESH_NAME); + char *exc = pcb_openems_excitation_get(ctx->pcb, 1); + int n; + + fprintf(ctx->fsim, "%%%%%% Board mesh, part 1\n"); + fprintf(ctx->fsim, "unit = 1.0e-3;\n"); + fprintf(ctx->fsim, "FDTD = InitFDTD();\n"); + fprintf(ctx->fsim, "%% Excitation begin\n"); + fprintf(ctx->fsim, "%s\n", exc); + fprintf(ctx->fsim, "%% Excitation end\n"); + free(exc); + + if (mesh != NULL) { + + fprintf(ctx->fsim, "BC = {"); + + for(n = 0; n < 6; n++) + fprintf(ctx->fsim, "%s'%s'", (n == 0 ? "" : " "), mesh->bnd[n]); + fprintf(ctx->fsim, "};\n"); + + fprintf(ctx->fsim, "FDTD = SetBoundaryCond(FDTD, BC);\n"); + } + fprintf(ctx->fsim, "physical_constants;\n"); + fprintf(ctx->fsim, "CSX = InitCSX();\n"); + fprintf(ctx->fsim, "\n"); +} + +static void openems_wr_m_mesh2(wctx_t *ctx) +{ + pcb_mesh_t *mesh = pcb_mesh_get(MESH_NAME); + + if (mesh == NULL) { + fprintf(ctx->f, "%%%%%% Board mesh (NOT defined in pcb-rnd)\n"); + return; + } + fprintf(ctx->f, "%%%%%% Board mesh, part 2\n"); + + rnd_fprintf(ctx->f, "z_bottom_copper=%mm\n", mesh->z_bottom_copper); + + fprintf(ctx->f, "mesh.y=["); + openems_wr_m_mesh_lines(ctx, &mesh->line[PCB_MESH_HORIZONTAL]); + fprintf(ctx->f, "];\n"); + + fprintf(ctx->f, "mesh.x=["); + openems_wr_m_mesh_lines(ctx, &mesh->line[PCB_MESH_VERTICAL]); + fprintf(ctx->f, "];\n"); + + fprintf(ctx->f, "mesh.z=["); + openems_wr_m_mesh_lines(ctx, &mesh->line[PCB_MESH_Z]); + fprintf(ctx->f, "];\n"); + + fprintf(ctx->f, "mesh.x = mesh.x .+ offset.x;\n"); + fprintf(ctx->f, "mesh.y = offset.y .- mesh.y;\n"); + fprintf(ctx->f, "mesh.z = z_bottom_copper .- mesh.z .+ offset.z;\n"); + if (mesh->pml > 0) + fprintf(ctx->f, "mesh = AddPML(mesh, %d);\n", mesh->pml); + fprintf(ctx->f, "CSX = DefineRectGrid(CSX, unit, mesh);\n"); + fprintf(ctx->f, "\n"); +} + +static void openems_wr_m_sim(wctx_t *wctx) +{ + openems_wr_m_mesh1(wctx); + + fprintf(wctx->fsim, "run %s\n\n", wctx->filename); + + fprintf(wctx->fsim, "Sim_Path = '.';\n"); + fprintf(wctx->fsim, "Sim_CSX = 'csxcad.xml';\n"); + fprintf(wctx->fsim, "WriteOpenEMS( [Sim_Path '/' Sim_CSX], FDTD, CSX );\n"); +} + +#include "openems_xml.c" + +static void openems_hid_export_to_file(const char *filename, FILE *the_file, FILE *fsim, rnd_hid_attr_val_t *options, int fmt_matlab) +{ + rnd_hid_expose_ctx_t ctx; + wctx_t wctx; + + memset(&wctx, 0, sizeof(wctx)); + wctx.filename = filename; + wctx.f = the_file; + wctx.fsim = fsim; + wctx.pcb = PCB; + wctx.options = options; + wctx.fmt_matlab = fmt_matlab; + ems_ctx = &wctx; + + ctx.view.X1 = 0; + ctx.view.Y1 = 0; + ctx.view.X2 = PCB->hidlib.size_x; + ctx.view.Y2 = PCB->hidlib.size_y; + + f = the_file; + + rnd_conf_force_set_bool(conf_core.editor.show_solder_side, 0); + + find_origin(&wctx); + + if (fmt_matlab) { + openems_wr_m_sim(&wctx); + openems_wr_m_tunables(&wctx); + openems_wr_m_mesh2(&wctx); + openems_wr_m_layers(&wctx); + openems_wr_m_init(&wctx); + openems_wr_m_outline(&wctx); + + fprintf(wctx.f, "%%%%%% Copper objects\n"); + rnd_expose_main(&openems_hid, &ctx, NULL); + + fprintf(wctx.f, "%%%%%% Port(s) on terminals\n"); + openems_wr_testpoints(&wctx, wctx.pcb->Data); + } + else { /* xml */ + if (openems_wr_xml(&wctx) != 0) + rnd_message(RND_MSG_ERROR, "openEMS: Due to errors, the exported file is invalid.\n"); + } + + rnd_conf_update(NULL, -1); /* restore forced sets */ +} + +static void openems_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + const char *filename; + char *runfn = NULL, *end; + int save_ons[PCB_MAX_LAYER]; + int i, len, fmt_matlab; + FILE *fsim; + + openems_ovr = 0; + + if (!options) { + openems_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + openems_values[i] = openems_attribute_list[i].default_val; + options = openems_values; + } + + filename = options[HA_openemsfile].str; + if (!filename) + filename = "pcb.m"; + + f = rnd_fopen_askovr(&PCB->hidlib, filename, "wb", &openems_ovr); + if (!f) { + perror(filename); + return; + } + + end = strrchr(filename, '.'); + fmt_matlab = !((end != NULL) && (rnd_strcasecmp(end, ".xml") == 0)); + + if (fmt_matlab) { + /* create the run.m file */ + len = strlen(filename); + runfn = malloc(len+16); + memcpy(runfn, filename, len+1); + end = runfn + len - 2; + if (strcmp(end, ".m") != 0) + end = runfn + len; + strcpy(end, ".sim.m"); + + fsim = rnd_fopen_askovr(&PCB->hidlib, runfn, "wb", &openems_ovr); + if (fsim == NULL) { + perror(runfn); + return; + } + } + else { /* xml */ + fsim = NULL; + } + + pcb_hid_save_and_show_layer_ons(save_ons); + + openems_hid_export_to_file(filename, f, fsim, options, fmt_matlab); + + pcb_hid_restore_layer_ons(save_ons); + + fclose(f); + if (fsim != NULL) + fclose(fsim); + f = NULL; + free(runfn); +} + +static int openems_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(openems_attribute_list, sizeof(openems_attribute_list) / sizeof(openems_attribute_list[0]), openems_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int openems_set_layer_group(rnd_hid_t *hid, 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 (flags & PCB_LYT_COPPER) { /* export copper layers only */ + ems_ctx->clayer = ems_ctx->lg_pcb2ems[group]; + if ((!ems_ctx->fmt_matlab) && (!is_empty)) + if (openems_wr_xml_layergrp_begin(ems_ctx, &ems_ctx->pcb->LayerGroups.grp[group]) != 0) + return 0; + return 1; + } + return 0; +} + +static rnd_hid_gc_t openems_make_gc(rnd_hid_t *hid) +{ + rnd_hid_gc_t rv = (rnd_hid_gc_t) calloc(sizeof(rnd_hid_gc_s), 1); + rv->me_pointer = &openems_hid; + return rv; +} + +static void openems_destroy_gc(rnd_hid_gc_t gc) +{ + free(gc); +} + +static void openems_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + switch(op) { + case RND_HID_COMP_RESET: + break; + case RND_HID_COMP_POSITIVE: + case RND_HID_COMP_POSITIVE_XOR: + break; + case RND_HID_COMP_NEGATIVE: + rnd_message(RND_MSG_ERROR, "Can't draw composite layer, especially not on copper\n"); + break; + case RND_HID_COMP_FLUSH: + break; + } +} + +static void openems_set_color(rnd_hid_gc_t gc, const rnd_color_t *name) +{ +} + +static void openems_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + gc->cap = style; +} + +static void openems_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + gc->width = width; +} + + +static void openems_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ + ; +} + +static void openems_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ +} + +static void openems_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ +} + +static void openems_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) +{ +} + +static void openems_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + wctx_t *ctx = ems_ctx; + long oid = ctx->oid++; + + if (ctx->fmt_matlab) { + rnd_fprintf(ctx->f, "points%ld(1, 1) = %mm; points%ld(2, 1) = %mm;\n", oid, cx, oid, -cy); + rnd_fprintf(ctx->f, "points%ld(1, 2) = %mm; points%ld(2, 2) = %mm;\n", oid, cx, oid, -cy); + rnd_fprintf(ctx->f, "CSX = AddPcbrndTrace(CSX, PCBRND, %d, points%ld, %mm, 0);\n", ctx->clayer, oid, radius*2); + } + else { + double a, step, x = RND_COORD_TO_MM(cx), y = -RND_COORD_TO_MM(cy), r = RND_COORD_TO_MM(radius); + step = r*10; + if (step < 8) step = 8; + step = 2*M_PI/step; + + rnd_fprintf(ctx->f, " \n", PRIO_COPPER, ctx->elevation, floor(2*M_PI/step)); + for(a = 0; a < 2*M_PI; a += step) + rnd_fprintf(ctx->f, " \n", x + cos(a)*r, y + sin(a)*r); + rnd_fprintf(ctx->f, " \n"); + } +} + +static void openems_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) +{ + wctx_t *ctx = ems_ctx; + int n; + + if (ctx->fmt_matlab) { + long oid = ctx->oid++; + + for(n = 0; n < n_coords; n++) + rnd_fprintf(ctx->f, "poly%ld_xy(1, %ld) = %mm; poly%ld_xy(2, %ld) = %mm;\n", oid, n+1, x[n]+dx, oid, n+1, -(y[n]+dy)); + + fprintf(ctx->f, "CSX = AddPcbrndPoly(CSX, PCBRND, %d, poly%ld_xy, 1);\n", ctx->clayer, oid); + } + else { + rnd_fprintf(ctx->f, " \n", PRIO_COPPER, ctx->elevation, n_coords); + for(n = 0; n < n_coords; n++) + rnd_fprintf(ctx->f, " \n", RND_COORD_TO_MM(x[n]+dx), RND_COORD_TO_MM(-(y[n]+dy))); + rnd_fprintf(ctx->f, " \n"); + } +} + +static void openems_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + openems_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + +static void openems_draw_line_body(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_coord_t x[4], y[4]; + pcb_line_t tmp = {0}; + tmp.Point1.X = x1; + tmp.Point1.Y = y1; + tmp.Point2.X = x2; + tmp.Point2.Y = y2; + tmp.Thickness = gc->width; + pcb_sqline_to_rect(&tmp, x, y); + openems_fill_polygon_offs(gc, 4, x, y, 0, 0); + +} + +static void openems_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + wctx_t *ctx = ems_ctx; + + if (gc->cap == rnd_cap_square) { + openems_draw_line_body(gc, x1, y1, x2, y2); + return; + } + + if (ctx->fmt_matlab) { + long oid = ctx->oid++; + rnd_fprintf(ctx->f, "points%ld(1, 1) = %mm; points%ld(2, 1) = %mm;\n", oid, x1, oid, -y1); + rnd_fprintf(ctx->f, "points%ld(1, 2) = %mm; points%ld(2, 2) = %mm;\n", oid, x2, oid, -y2); + rnd_fprintf(ctx->f, "CSX = AddPcbrndTrace(CSX, PCBRND, %d, points%ld, %mm, 0);\n", ctx->clayer, oid, gc->width); + } + else { + openems_fill_circle(gc, x1, y1, gc->width/2); + openems_fill_circle(gc, x2, y2, gc->width/2); + openems_draw_line_body(gc, x1, y1, x2, y2); + } +} + + +static void openems_calibrate(rnd_hid_t *hid, double xval, double yval) +{ + rnd_message(RND_MSG_ERROR, "openems_calibrate() not implemented"); + return; +} + +static void openems_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int a) +{ +} + +static int openems_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nopenems exporter command line arguments:\n\n"); + rnd_hid_usage(openems_attribute_list, sizeof(openems_attribute_list) / sizeof(openems_attribute_list[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x openems [openems options] foo.pcb\n\n"); + return 0; +} + +static rnd_action_t openems_action_list[] = { + {"mesh", pcb_act_mesh, pcb_acth_mesh, pcb_acts_mesh}, + {"OpenemsExcitation", pcb_act_OpenemsExcitation, pcb_acth_OpenemsExcitation, pcb_acts_OpenemsExcitation} +}; + +int pplg_check_ver_export_openems(int ver_needed) { return 0; } + +void pplg_uninit_export_openems(void) +{ + pcb_openems_excitation_uninit(); + rnd_remove_actions_by_cookie(openems_cookie); + rnd_export_remove_opts_by_cookie(openems_cookie); + rnd_hid_remove_hid(&openems_hid); +} + +int pplg_init_export_openems(void) +{ + RND_API_CHK_VER; + + memset(&openems_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&openems_hid); + + openems_hid.struct_size = sizeof(rnd_hid_t); + openems_hid.name = "openems"; + openems_hid.description = "OpenEMS exporter"; + openems_hid.exporter = 1; + + openems_hid.get_export_options = openems_get_export_options; + openems_hid.do_export = openems_do_export; + openems_hid.parse_arguments = openems_parse_arguments; + openems_hid.set_layer_group = openems_set_layer_group; + openems_hid.make_gc = openems_make_gc; + openems_hid.destroy_gc = openems_destroy_gc; + openems_hid.set_drawing_mode = openems_set_drawing_mode; + openems_hid.set_color = openems_set_color; + openems_hid.set_line_cap = openems_set_line_cap; + openems_hid.set_line_width = openems_set_line_width; + openems_hid.set_draw_xor = openems_set_draw_xor; + openems_hid.draw_line = openems_draw_line; + openems_hid.draw_arc = openems_draw_arc; + openems_hid.draw_rect = openems_draw_rect; + openems_hid.fill_circle = openems_fill_circle; + openems_hid.fill_polygon = openems_fill_polygon; + openems_hid.fill_polygon_offs = openems_fill_polygon_offs; + openems_hid.fill_rect = openems_fill_rect; + openems_hid.calibrate = openems_calibrate; + openems_hid.set_crosshair = openems_set_crosshair; + + openems_hid.usage = openems_usage; + + rnd_hid_register_hid(&openems_hid); + + RND_REGISTER_ACTIONS(openems_action_list, openems_cookie); + + pcb_openems_excitation_init(); + + return 0; +} Index: tags/2.3.0/src_plugins/export_openems/export_openems.pup =================================================================== --- tags/2.3.0/src_plugins/export_openems/export_openems.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_openems/export_openems.pup (revision 33253) @@ -0,0 +1,10 @@ +$class export +$short openems exporter +$long Export copper to OpenEMS simulation +$state WIP +$fmt-native no +$fmt-feature-w OpenEMS (simulation, matlab files) +$package export-sim +dep lib_polyhelp +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_openems/mesh.c =================================================================== --- tags/2.3.0/src_plugins/export_openems/mesh.c (nonexistent) +++ tags/2.3.0/src_plugins/export_openems/mesh.c (revision 33253) @@ -0,0 +1,1286 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "mesh.h" +#include "layer.h" +#include "layer_ui.h" +#include +#include "board.h" +#include "data.h" +#include +#include "event.h" +#include +#include + +static pcb_mesh_t mesh; +static const char *mesh_ui_cookie = "mesh ui layer cookie"; + +static const char *bnds[] = { "PEC", "PMC", "MUR", "PML_8", NULL }; +static const char *bnd_names[] = { "xmin", "xmax", "ymin", "ymax", "zmin", "zmax" }; +static const char *subslines[] = { "0", "1", "3", "5", NULL }; +static const int num_subslines[] = { 0, 1, 3, 5 }; + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int dens_obj, dens_gap, min_space, smooth, hor, ver, noimpl; + int bnd[6], pml, subslines, air_top, air_bot, dens_air, smoothz, max_air, def_subs_thick, def_copper_thick; + unsigned active:1; +} mesh_dlg_t; +static mesh_dlg_t ia; + +static void mesh2dlg() +{ + int n; + rnd_coord_t subst_thick; + + subst_thick = pcb_board_thickness(PCB, "openems", PCB_BRDTHICK_PRINT_ERROR); + if (subst_thick <= 0) { + rnd_message(RND_MSG_ERROR, "Assuming 1.5mm thick substrate because of the missing thickness attributes.\nFeel free to change it in the mesh dialog or add the attributes to the substrate groups."); + subst_thick = RND_MM_TO_COORD(1.5); + } + + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.pml, lng, mesh.pml); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.dens_obj, crd, RND_MM_TO_COORD(0.15)); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.dens_gap, crd, RND_MM_TO_COORD(0.5)); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.min_space, crd, RND_MM_TO_COORD(0.1)); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.smooth, lng, 1); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.noimpl, lng, 0); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.hor, lng, 1); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.ver, lng, 1); +TODO("enum lookup"); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.subslines, lng, 3); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.def_subs_thick, crd, subst_thick); +/* RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.def_copper_thick, crd, RND_MM_TO_COORD(1.5));*/ + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.air_top, lng, 1); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.air_bot, lng, 1); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.dens_air, crd, RND_MM_TO_COORD(0.7)); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.smoothz, lng, 1); + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.max_air, crd, RND_MM_TO_COORD(4)); + for(n = 0; n < 6; n++) { + const char **a; + int i; + if (mesh.bnd[n] != NULL) + for(i = 0, a = bnds; *a != NULL; a++,i++) + if (strcmp(*a, mesh.bnd[n]) == 0) + RND_DAD_SET_VALUE(ia.dlg_hid_ctx, ia.bnd[n], lng, i); + } +} + +static void dlg2mesh(void) +{ + int n; + mesh.pml = ia.dlg[ia.pml].val.lng; + mesh.dens_obj = ia.dlg[ia.dens_obj].val.crd; + mesh.dens_gap = ia.dlg[ia.dens_gap].val.crd; + mesh.min_space = ia.dlg[ia.min_space].val.crd; + mesh.smooth = ia.dlg[ia.smooth].val.lng; + mesh.noimpl = ia.dlg[ia.noimpl].val.lng; + mesh.hor = ia.dlg[ia.hor].val.lng; + mesh.ver = ia.dlg[ia.ver].val.lng; +TODO("enum lookup"); + mesh.subslines = ia.dlg[ia.subslines].val.lng; + mesh.def_subs_thick = ia.dlg[ia.def_subs_thick].val.crd; + mesh.def_copper_thick = ia.dlg[ia.def_copper_thick].val.crd; + mesh.air_top = ia.dlg[ia.air_top].val.lng; + mesh.air_bot = ia.dlg[ia.air_top].val.lng; + mesh.dens_air = ia.dlg[ia.dens_air].val.crd; + mesh.smoothz = ia.dlg[ia.smoothz].val.lng; + mesh.max_air = ia.dlg[ia.max_air].val.crd; + for(n = 0; n < 6; n++) + mesh.bnd[n] = bnds[ia.dlg[ia.bnd[n]].val.lng]; +} + +#if 1 + static void mesh_trace(const char *fmt, ...) { } +#else +# define mesh_trace pcb_trace +#endif + +TODO("remove this once the function is moved and published in core") +extern const char *pcb_layergrp_thickness_attr(pcb_layergrp_t *grp, const char *namespace); + +rnd_coord_t mesh_layergrp_thickness(pcb_layergrp_t *grp, rnd_coord_t fallback) +{ + rnd_coord_t th = fallback; + const char *s = pcb_layergrp_thickness_attr(grp, "openems"); + if (s != NULL) + th = rnd_get_value(s, NULL, NULL, NULL); + else + rnd_message(RND_MSG_ERROR, "openEMS: thickness of layer group '%s' is not available, using default for type\n(You should fix your layer group attributes!)\n", grp->name); + return th; +} + + +TODO("reorder to avoid fwd decl") +static void mesh_auto_add_smooth(vtc0_t *v, rnd_coord_t c1, rnd_coord_t c2, rnd_coord_t d1, rnd_coord_t d, rnd_coord_t d2); + +#define SAVE_INT(name) \ + rnd_append_printf(dst, "%s " #name" = %d\n", prefix, (int)me->dlg[me->name].val.lng); +#define SAVE_COORD(name) \ + rnd_append_printf(dst, "%s " #name" = %.08$$mm\n", prefix, (rnd_coord_t)me->dlg[me->name].val.crd); +void pcb_mesh_save(const mesh_dlg_t *me, gds_t *dst, const char *prefix) +{ + int n; + + if (prefix == NULL) + prefix = ""; + + rnd_append_printf(dst, "%sha:pcb-rnd-mesh-v1 {\n", prefix); + SAVE_COORD(dens_obj); + SAVE_COORD(dens_gap); + SAVE_COORD(min_space); + SAVE_INT(pml); + SAVE_INT(smooth); + SAVE_INT(hor); + SAVE_INT(ver); + SAVE_INT(noimpl); + SAVE_INT(air_top); + SAVE_INT(air_bot); + SAVE_COORD(dens_air); + SAVE_INT(smoothz); + SAVE_COORD(max_air); + SAVE_COORD(def_subs_thick); + SAVE_COORD(def_copper_thick); + rnd_append_printf(dst, "%s li:boundary = {", prefix); + for(n = 0; n < 6; n++) { + int bidx = me->dlg[me->bnd[n]].val.lng; + const char *bs; + if ((bidx < 0) || (bidx >= sizeof(bnds) / sizeof(bnds[0]))) + bs = "invalid"; + else + bs = bnds[bidx]; + gds_append_str(dst, bs); + gds_append(dst, ';'); + } + gds_append_str(dst, "}\n"); + + { + int sidx = me->dlg[me->subslines].val.lng; + const char *bs; + if ((sidx < 0) || (sidx >= sizeof(subslines) / sizeof(subslines[0]))) + bs = "invalid"; + else + bs = subslines[sidx]; + rnd_append_printf(dst, "%s subslines = %s\n", prefix, bs); + } + + rnd_append_printf(dst, "%s}\n", prefix); +} +#undef SAVE_INT +#undef SAVE_COORD + +#define LOAD_INT(name) \ +do { \ + lht_node_t *n = lht_dom_hash_get(root, #name); \ + if (n != NULL) { \ + int v; \ + char *end; \ + if (n->type != LHT_TEXT) { \ + rnd_message(RND_MSG_ERROR, "Invalid mesh item: " #name " should be text\n"); \ + return -1; \ + } \ + v = strtol(n->data.text.value, &end, 10); \ + if (*end != '\0') { \ + rnd_message(RND_MSG_ERROR, "Invalid mesh integer: " #name "\n"); \ + return -1; \ + } \ + RND_DAD_SET_VALUE(me->dlg_hid_ctx, me->name, lng, v); \ + } \ +} while(0) + +#define LOAD_COORD(name) \ +do { \ + lht_node_t *n = lht_dom_hash_get(root, #name); \ + if (n != NULL) { \ + double v; \ + rnd_bool succ; \ + if (n->type != LHT_TEXT) { \ + rnd_message(RND_MSG_ERROR, "Invalid mesh item: " #name " should be text\n"); \ + return -1; \ + } \ + v = rnd_get_value(n->data.text.value, NULL, NULL, &succ); \ + if (!succ) { \ + rnd_message(RND_MSG_ERROR, "Invalid mesh coord: " #name "\n"); \ + return -1; \ + } \ + RND_DAD_SET_VALUE(me->dlg_hid_ctx, me->name, crd, (rnd_coord_t)v); \ + } \ +} while(0) + +#define LOAD_ENUM_VAL(dst, name, node, arr) \ +do { \ + if (node != NULL) { \ + int __found__ = 0, __n__; \ + const char **__a__; \ + if (node->type != LHT_TEXT) { \ + rnd_message(RND_MSG_ERROR, "Invalid mesh value: " #name " should be text\n"); \ + return -1; \ + } \ + if (strcmp(node->data.text.value, "invalid") == 0) break; \ + for(__n__ = 0, __a__ = arr; *__a__ != NULL; __a__++,__n__++) { \ + if (strcmp(node->data.text.value, *__a__) == 0) { \ + __found__ = 1; \ + break; \ + } \ + } \ + if (!__found__) { \ + rnd_message(RND_MSG_ERROR, "Invalid mesh value '%s' for " #name "\n", node->data.text.value); \ + return -1; \ + } \ + RND_DAD_SET_VALUE(me->dlg_hid_ctx, dst, lng, __n__); \ + } \ +} while(0) + +static int mesh_load_subtree(mesh_dlg_t *me, lht_node_t *root) +{ + lht_node_t *lst, *nd; + + if ((root->type != LHT_HASH) || (strcmp(root->name, "pcb-rnd-mesh-v1") != 0)) { + rnd_message(RND_MSG_ERROR, "Input is not a valid mesh save - should be a ha:pcb-rnd-mesh subtree\n"); + return -1; + } + + LOAD_COORD(dens_obj); + LOAD_COORD(dens_gap); + LOAD_COORD(min_space); + LOAD_INT(pml); + LOAD_INT(smooth); + LOAD_INT(hor); + LOAD_INT(ver); + LOAD_INT(noimpl); + LOAD_INT(air_top); + LOAD_INT(air_bot); + LOAD_COORD(dens_air); + LOAD_INT(smoothz); + LOAD_COORD(max_air); + LOAD_COORD(def_subs_thick); + LOAD_COORD(def_copper_thick); + LOAD_ENUM_VAL(me->subslines, subslines, lht_dom_hash_get(root, "subslines"), subslines); + + lst = lht_dom_hash_get(root, "boundary"); + if (lst != NULL) { + int n; + if (lst->type != LHT_LIST) { + rnd_message(RND_MSG_ERROR, "Boundary shall be a list\n"); + return -1; + } + for(n = 0, nd = lst->data.list.first; (n < 6) && (nd != NULL); n++,nd = nd->next) + LOAD_ENUM_VAL(me->bnd[n], boundary, nd, bnds); + } + + return 0; +} +#undef LOAD_INT +#undef LOAD_COORD + +int mesh_load_file(mesh_dlg_t *me, FILE *f) +{ + int c, res; + lht_doc_t *doc; + + doc = lht_dom_init(); + + while((c = fgetc(f)) != EOF) { + lht_err_t err = lht_dom_parser_char(doc, c); + if ((err != LHTE_SUCCESS) && (err != LHTE_STOP)) { + lht_dom_uninit(doc); + return -1; + } + } + res = mesh_load_subtree(me, doc->root); + lht_dom_uninit(doc); + return res; +} + + +static void mesh_add_edge(pcb_mesh_t *mesh, pcb_mesh_dir_t dir, rnd_coord_t crd) +{ + vtc0_append(&mesh->line[dir].edge, crd); +} + +static void mesh_add_result(pcb_mesh_t *mesh, pcb_mesh_dir_t dir, rnd_coord_t crd) +{ + vtc0_append(&mesh->line[dir].result, crd); +} + +static void mesh_add_range(pcb_mesh_t *mesh, pcb_mesh_dir_t dir, rnd_coord_t c1, rnd_coord_t c2, rnd_coord_t dens) +{ + pcb_range_t *r = vtr0_alloc_append(&mesh->line[dir].dens, 1); + r->begin = c1; + r->end = c2; + r->data[0].c = dens; +} + +static void mesh_add_obj(pcb_mesh_t *mesh, pcb_mesh_dir_t dir, rnd_coord_t c1, rnd_coord_t c2, int aligned) +{ + if (aligned) { + mesh_add_edge(mesh, dir, c1 - mesh->dens_obj * 2 / 3); + mesh_add_edge(mesh, dir, c1 + mesh->dens_obj * 1 / 3); + mesh_add_edge(mesh, dir, c2 - mesh->dens_obj * 1 / 3); + mesh_add_edge(mesh, dir, c2 + mesh->dens_obj * 2 / 3); + } + mesh_add_range(mesh, dir, c1, c2, mesh->dens_obj); +} + +/* generate edges and ranges looking at objects on the given layer */ +static int mesh_gen_obj(pcb_mesh_t *mesh, pcb_layer_t *layer, pcb_mesh_dir_t dir) +{ + pcb_data_t *data = layer->parent.data; + pcb_line_t *line; + pcb_line_t *arc; + pcb_poly_t *poly; + pcb_pstk_t *ps; + gdl_iterator_t it; + + padstacklist_foreach(&data->padstack, &it, ps) { + if (pcb_attribute_get(&ps->Attributes, "openems::vport") != 0) { + switch(dir) { + case PCB_MESH_HORIZONTAL: mesh_add_edge(mesh, dir, ps->y); break; + case PCB_MESH_VERTICAL: mesh_add_edge(mesh, dir, ps->x); break; + default: break; + } + } + } + + linelist_foreach(&layer->Line, &it, line) { + rnd_coord_t x1 = line->Point1.X, y1 = line->Point1.Y, x2 = line->Point2.X, y2 = line->Point2.Y; + int aligned = (x1 == x2) || (y1 == y2); + + switch(dir) { + case PCB_MESH_HORIZONTAL: + if (y1 < y2) + mesh_add_obj(mesh, dir, y1 - line->Thickness/2, y2 + line->Thickness/2, aligned); + else + mesh_add_obj(mesh, dir, y2 - line->Thickness/2, y1 + line->Thickness/2, aligned); + break; + case PCB_MESH_VERTICAL: + if (x1 < x2) + mesh_add_obj(mesh, dir, x1 - line->Thickness/2, x2 + line->Thickness/2, aligned); + else + mesh_add_obj(mesh, dir, x2 - line->Thickness/2, x1 + line->Thickness/2, aligned); + break; + default: break; + } + } + + arclist_foreach(&layer->Arc, &it, arc) { + /* no point in encorcinf 1/3 2/3 rule, just set the range */ + switch(dir) { + case PCB_MESH_HORIZONTAL: mesh_add_range(mesh, dir, arc->BoundingBox.Y1 + arc->Clearance/2, arc->BoundingBox.Y2 - arc->Clearance/2, mesh->dens_obj); break; + case PCB_MESH_VERTICAL: mesh_add_range(mesh, dir, arc->BoundingBox.X1 + arc->Clearance/2, arc->BoundingBox.X2 - arc->Clearance/2, mesh->dens_obj); break; + default: break; + } + } + +TODO("mesh: text") + + polylist_foreach(&layer->Polygon, &it, poly) { + pcb_poly_it_t it; + rnd_polyarea_t *pa; + + for(pa = pcb_poly_island_first(poly, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_coord_t x, y; + rnd_pline_t *pl; + int go; + + pl = pcb_poly_contour(&it); + if (pl != NULL) { + rnd_coord_t lx, ly, minx, miny, maxx, maxy; + + pcb_poly_vect_first(&it, &minx, &miny); + maxx = minx; + maxy = miny; + pcb_poly_vect_peek_prev(&it, &lx, &ly); + /* find axis aligned contour edges for the 2/3 1/3 rule */ + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) { + switch(dir) { + case PCB_MESH_HORIZONTAL: + if (y == ly) { + int sign = (x > lx) ? +1 : -1; + mesh_add_edge(mesh, dir, y - sign * mesh->dens_obj * 2 / 3); + mesh_add_edge(mesh, dir, y + sign * mesh->dens_obj * 1 / 3); + } + break; + case PCB_MESH_VERTICAL: + if (x == lx) { + int sign = (y < ly) ? +1 : -1; + mesh_add_edge(mesh, dir, x - sign * mesh->dens_obj * 2 / 3); + mesh_add_edge(mesh, dir, x + sign * mesh->dens_obj * 1 / 3); + } + break; + default: break; + } + lx = x; + ly = y; + if (x < minx) minx = x; + if (y < miny) miny = y; + if (x > maxx) maxx = x; + if (y > maxy) maxy = y; + } + switch(dir) { + case PCB_MESH_HORIZONTAL: mesh_add_range(mesh, dir, miny, maxy, mesh->dens_obj); break; + case PCB_MESH_VERTICAL: mesh_add_range(mesh, dir, minx, maxx, mesh->dens_obj); break; + default: break; + } + /* Note: holes can be ignored: holes are sorrunded by polygons, the grid is dense over them already */ + } + } + } + return 0; +} + +/* run mesh_gen_obj on all subc layers that match current board mesh layer */ +static int mesh_gen_obj_subc(pcb_mesh_t *mesh, pcb_mesh_dir_t dir) +{ + pcb_data_t *data = mesh->layer->parent.data; + pcb_subc_t *sc; + gdl_iterator_t it; + + subclist_foreach(&data->subc, &it, sc) { + int n; + pcb_layer_t *ly; + for(n = 0, ly = sc->data->Layer; n < sc->data->LayerN; n++,ly++) { + if (pcb_layer_get_real(ly) == mesh->layer) { + if (mesh_gen_obj(mesh, ly, dir) != 0) + return -1; + } + } + } + return 0; +} + +static int cmp_coord(const void *v1, const void *v2) +{ + const rnd_coord_t *c1 = v1, *c2 = v2; + return *c1 < *c2 ? -1 : +1; +} + +static int cmp_range(const void *v1, const void *v2) +{ + const pcb_range_t *c1 = v1, *c2 = v2; + return c1->begin < c2->begin ? -1 : +1; +} + + +typedef struct { + rnd_coord_t min; + rnd_coord_t max; + int found; +} mesh_maybe_t; + +static int cmp_maybe_add(const void *k, const void *v) +{ + const mesh_maybe_t *ctx = k; + const rnd_coord_t *c = v; + + if ((*c >= ctx->min) && (*c <= ctx->max)) + return 0; + if (*c < ctx->min) + return +1; + return -1; +} + +static void mesh_maybe_add_edge(pcb_mesh_t *mesh, pcb_mesh_dir_t dir, rnd_coord_t at, rnd_coord_t dist) +{ + mesh_maybe_t ctx; + rnd_coord_t *c; + ctx.min = at - dist; + ctx.max = at + dist; + ctx.found = 0; + + c = bsearch(&ctx, mesh->line[dir].edge.array, vtc0_len(&mesh->line[dir].edge), sizeof(rnd_coord_t), cmp_maybe_add); + if (c == NULL) { +TODO(": optimization: run a second bsearch and insert instead of this; testing: 45 deg line (won't have axis aligned edge for the 2/3 1/3 rule)") + vtc0_append(&mesh->line[dir].edge, at); + qsort(mesh->line[dir].edge.array, vtc0_len(&mesh->line[dir].edge), sizeof(rnd_coord_t), cmp_coord); + } +} + +static int mesh_sort(pcb_mesh_t *mesh, pcb_mesh_dir_t dir) +{ + size_t n; + pcb_range_t *r; + + if (vtr0_len(&mesh->line[dir].dens) < 1) { + rnd_message(RND_MSG_ERROR, "There are not enough objects to do the meshing\n"); + return -1; + } + + qsort(mesh->line[dir].edge.array, vtc0_len(&mesh->line[dir].edge), sizeof(rnd_coord_t), cmp_coord); + qsort(mesh->line[dir].dens.array, vtr0_len(&mesh->line[dir].dens), sizeof(pcb_range_t), cmp_range); + + /* warn for edges too close */ + for(n = 0; n < vtc0_len(&mesh->line[dir].edge)-1; n++) { + rnd_coord_t c1 = mesh->line[dir].edge.array[n], c2 = mesh->line[dir].edge.array[n+1]; + if (c2 - c1 < mesh->min_space) { + if ((c2 - c1) < RND_MM_TO_COORD(0.1)) { + mesh->line[dir].edge.array[n] = (c1 + c2) / 2; + vtc0_remove(&mesh->line[dir].edge, n+1, 1); + } + else + rnd_message(RND_MSG_ERROR, "meshing error: invalid minimum spacing (%$mm) required: forced %s edges are closer than that around %$mm..%$mm; try decreasing your minimum spacing to below %$mm\n", mesh->min_space, dir == PCB_MESH_VERTICAL ? "vertical" : "horizonal", c1, c2, c2-c1); + } + } + + + /* merge overlapping ranges of the same density */ + for(n = 0; n < vtr0_len(&mesh->line[dir].dens)-1; n++) { + pcb_range_t *r1 = &mesh->line[dir].dens.array[n], *r2 = &mesh->line[dir].dens.array[n+1]; + if (r1->data[0].c != r2->data[0].c) continue; + if (r2->begin < r1->end) { + if (r2->end > r1->end) + r1->end = r2->end; + vtr0_remove(&mesh->line[dir].dens, n+1, 1); + n--; /* make sure to check the next range against the current one, might be overlapping as well */ + } + } + + /* continous ranges: fill in the gaps */ + for(n = 0; n < vtr0_len(&mesh->line[dir].dens)-1; n++) { + pcb_range_t *r1 = &mesh->line[dir].dens.array[n], *r2 = &mesh->line[dir].dens.array[n+1]; + if (r1->end < r2->begin) { + rnd_coord_t my_end = r2->begin; /* the insert will change r2 pointer */ + pcb_range_t *r = vtr0_alloc_insert(&mesh->line[dir].dens, n+1, 1); + r->begin = r1->end; + r->end = my_end; + r->data[0].c = mesh->dens_gap; + n++; /* no need to check the new block */ + } + } + + /* make sure there's a forced mesh line at region transitions */ + for(n = 0; n < vtr0_len(&mesh->line[dir].dens); n++) { + pcb_range_t *r = &mesh->line[dir].dens.array[n]; + if (n == 0) + mesh_maybe_add_edge(mesh, dir, r->begin, mesh->dens_gap); + mesh_maybe_add_edge(mesh, dir, r->end, mesh->dens_gap); + } + + /* continous ranges: start and end */ + r = vtr0_alloc_insert(&mesh->line[dir].dens, 0, 1); + r->begin = 0; + r->end = mesh->line[dir].dens.array[1].begin; + r->data[0].c = mesh->dens_gap; + + r = vtr0_alloc_append(&mesh->line[dir].dens, 1); + r->begin = mesh->line[dir].dens.array[vtr0_len(&mesh->line[dir].dens)-2].end; + r->end = (dir == PCB_MESH_HORIZONTAL) ? PCB->hidlib.size_y : PCB->hidlib.size_x; + r->data[0].c = mesh->dens_gap; + + + return 0; +} + +static int cmp_range_at(const void *key_, const void *v_) +{ + const rnd_coord_t *key = key_; + const pcb_range_t *v = v_; + + if ((*key >= v->begin) && (*key <= v->end)) + return 0; + if (*key < v->begin) return -1; + return +1; +} + +static pcb_range_t *mesh_find_range(const vtr0_t *v, rnd_coord_t at, rnd_coord_t *dens, rnd_coord_t *dens_left, rnd_coord_t *dens_right) +{ + pcb_range_t *r; + r = bsearch(&at, v->array, vtr0_len((vtr0_t *)v), sizeof(pcb_range_t), cmp_range_at); + if (dens != NULL) { + if (r == NULL) + return NULL; + *dens = r->data[0].c; + } + if (dens_left != NULL) { + if (r == v->array) + *dens_left = r->data[0].c; + else + *dens_left = r[-1].data[0].c; + } + if (dens_right != NULL) { + if (r == v->array+v->used-1) + *dens_right = r->data[0].c; + else + *dens_right = r[+1].data[0].c; + } + return r; +} + +static int mesh_auto_z(pcb_mesh_t *mesh) +{ + rnd_layergrp_id_t gid; + rnd_coord_t y = 0, ytop = 0, ybottom, top_dens, bottom_dens; + int n, lns, first = 1; + + vtc0_truncate(&mesh->line[PCB_MESH_Z].result, 0); + + lns = num_subslines[ia.dlg[ia.subslines].val.lng]; + if (lns != 0) lns++; + + for(gid = 0; gid < PCB->LayerGroups.len; gid++) { + pcb_layergrp_t *grp = &PCB->LayerGroups.grp[gid]; + if (grp->ltype & PCB_LYT_COPPER) { + /* For now follow the old behavior and ignore the thickness of copper layers for now: copper sheets are modelled in 2d */ +#if 0 + rnd_coord_t th = mesh_layergrp_thickness(grp, mesh->def_copper_thick); + y += th; + ybottom = y; +#endif + } + else if (grp->ltype & PCB_LYT_SUBSTRATE) { + rnd_coord_t d, t = mesh_layergrp_thickness(grp, mesh->def_subs_thick); + double dens = (double)t/(double)lns; + bottom_dens = rnd_round(dens); + if (lns != 0) { + for(n = 0; n <= lns; n++) { + if (n == 0) { + if (first) { + ytop = y; + top_dens = rnd_round(dens); + first = 0; + } + else + continue; + } + d = rnd_round((double)y+dens*(double)n); + mesh_add_result(mesh, PCB_MESH_Z, d); + } + } + else { + if (first) { + ytop = y; + first = 0; + top_dens = mesh->def_subs_thick; + } + mesh_add_result(mesh, PCB_MESH_Z, y); + } + y += t; + ybottom = y; + } + } + + if (ia.dlg[ia.air_top].val.lng) { + if (ia.dlg[ia.smoothz].val.lng) { + mesh_auto_add_smooth(&mesh->line[PCB_MESH_Z].result, ytop - ia.dlg[ia.max_air].val.crd, ytop, + ia.dlg[ia.dens_air].val.crd, ia.dlg[ia.dens_air].val.crd, top_dens); + } + else { + for(y = ytop; y > ytop - ia.dlg[ia.max_air].val.crd ; y -= ia.dlg[ia.dens_air].val.crd) + mesh_add_result(mesh, PCB_MESH_Z, y); + } + } + + if (ia.dlg[ia.air_bot].val.lng) { + if (ia.dlg[ia.smoothz].val.lng) { + mesh_auto_add_smooth(&mesh->line[PCB_MESH_Z].result, ybottom, ybottom + ia.dlg[ia.max_air].val.crd, + bottom_dens, ia.dlg[ia.dens_air].val.crd, ia.dlg[ia.dens_air].val.crd); + } + else { + for(y = ybottom; y < ybottom + ia.dlg[ia.max_air].val.crd ; y += ia.dlg[ia.dens_air].val.crd) + mesh_add_result(mesh, PCB_MESH_Z, y); + } + } + + mesh->z_bottom_copper = ybottom; + + return 0; +} + +static void mesh_draw_line(pcb_mesh_t *mesh, pcb_mesh_dir_t dir, rnd_coord_t at, rnd_coord_t aux1, rnd_coord_t aux2, rnd_coord_t thick) +{ + if (dir == PCB_MESH_HORIZONTAL) + pcb_line_new(mesh->ui_layer_xy, aux1, at, aux2, at, thick, 0, pcb_no_flags()); + else + pcb_line_new(mesh->ui_layer_xy, at, aux1, at, aux2, thick, 0, pcb_no_flags()); +} + +static void mesh_draw_range(pcb_mesh_t *mesh, pcb_mesh_dir_t dir, rnd_coord_t at1, rnd_coord_t at2, rnd_coord_t aux, rnd_coord_t thick) +{ + if (dir == PCB_MESH_HORIZONTAL) + pcb_line_new(mesh->ui_layer_xy, aux, at1, aux, at2, thick, 0, pcb_no_flags()); + else + pcb_line_new(mesh->ui_layer_xy, at1, aux, at2, aux, thick, 0, pcb_no_flags()); +} + +static void mesh_draw_label(pcb_mesh_t *mesh, pcb_mesh_dir_t dir, rnd_coord_t aux, const char *label) +{ + aux -= RND_MM_TO_COORD(0.6); + if (dir == PCB_MESH_HORIZONTAL) + pcb_text_new(mesh->ui_layer_xy, pcb_font(PCB, 0, 0), aux, 0, 90, 75, 0, label, pcb_no_flags()); + else + pcb_text_new(mesh->ui_layer_xy, pcb_font(PCB, 0, 0), 0, aux, 0, 75, 0, label, pcb_no_flags()); + +} + +static int mesh_vis_xy(pcb_mesh_t *mesh, pcb_mesh_dir_t dir) +{ + size_t n; + rnd_coord_t end; + + mesh_draw_label(mesh, dir, RND_MM_TO_COORD(0.1), "object edge"); + + mesh_trace("%s edges:\n", dir == PCB_MESH_HORIZONTAL ? "horizontal" : "vertical"); + for(n = 0; n < vtc0_len(&mesh->line[dir].edge); n++) { + mesh_trace(" %mm", mesh->line[dir].edge.array[n]); + mesh_draw_line(mesh, dir, mesh->line[dir].edge.array[n], RND_MM_TO_COORD(0.1), RND_MM_TO_COORD(0.5), RND_MM_TO_COORD(0.1)); + } + mesh_trace("\n"); + + mesh_draw_label(mesh, dir, RND_MM_TO_COORD(2), "density ranges"); + + mesh_trace("%s ranges:\n", dir == PCB_MESH_HORIZONTAL ? "horizontal" : "vertical"); + for(n = 0; n < vtr0_len(&mesh->line[dir].dens); n++) { + pcb_range_t *r = &mesh->line[dir].dens.array[n]; + mesh_trace(" [%mm..%mm=%mm]", r->begin, r->end, r->data[0].c); + mesh_draw_range(mesh, dir, r->begin, r->end, RND_MM_TO_COORD(2)+r->data[0].c/2, RND_MM_TO_COORD(0.05)); + } + mesh_trace("\n"); + + mesh_trace("%s result:\n", dir == PCB_MESH_HORIZONTAL ? "horizontal" : "vertical"); + end = (dir == PCB_MESH_HORIZONTAL) ? PCB->hidlib.size_x : PCB->hidlib.size_y; + for(n = 0; n < vtc0_len(&mesh->line[dir].result); n++) { + mesh_trace(" %mm", mesh->line[dir].result.array[n]); + mesh_draw_line(mesh, dir, mesh->line[dir].result.array[n], 0, end, RND_MM_TO_COORD(0.03)); + } + mesh_trace("\n"); + + return 0; +} + +static int mesh_vis_z(pcb_mesh_t *mesh) +{ + int n; + rnd_layergrp_id_t gid; + rnd_coord_t y0 = PCB->hidlib.size_y/3, y = y0, y2; + rnd_coord_t xl = PCB->hidlib.size_x/5; /* board left */ + rnd_coord_t xr = PCB->hidlib.size_x/5*3; /* board right */ + rnd_coord_t spen = RND_MM_TO_COORD(0.3), cpen = RND_MM_TO_COORD(0.2), mpen = RND_MM_TO_COORD(0.03); + int mag = 2; + + for(gid = 0; gid < PCB->LayerGroups.len; gid++) { + pcb_layergrp_t *grp = &PCB->LayerGroups.grp[gid]; + if (grp->ltype & PCB_LYT_COPPER) { + y2 = y + mesh->def_copper_thick * mag / 2; + pcb_line_new(mesh->ui_layer_z, xr, y2, xr+RND_MM_TO_COORD(2), y2, cpen, 0, pcb_no_flags()); + pcb_text_new(mesh->ui_layer_z, pcb_font(PCB, 0, 0), xr+RND_MM_TO_COORD(3), y2 - RND_MM_TO_COORD(1), 0, 100, 0, grp->name, pcb_no_flags()); + y += mesh->def_copper_thick * mag; + } + else if (grp->ltype & PCB_LYT_SUBSTRATE) { + y2 = y + mesh->def_subs_thick * mag; + pcb_line_new(mesh->ui_layer_z, xl, y, xr, y, spen, 0, pcb_no_flags()); + pcb_line_new(mesh->ui_layer_z, xl, y2, xr, y2, spen, 0, pcb_no_flags()); + pcb_line_new(mesh->ui_layer_z, xl, y, xl, y2, spen, 0, pcb_no_flags()); + pcb_line_new(mesh->ui_layer_z, xr, y, xr, y2, spen, 0, pcb_no_flags()); + y = y2; + } + } + + mesh_trace("Z lines:\n"); + for(n = 0; n < vtc0_len(&mesh->line[PCB_MESH_Z].result); n++) { + rnd_coord_t y = y0+mesh->line[PCB_MESH_Z].result.array[n]*mag; + mesh_trace(" %mm", y); + pcb_line_new(mesh->ui_layer_z, 0, y, PCB->hidlib.size_x, y, mpen, 0, pcb_no_flags()); + } + mesh_trace("\n"); + return 0; +} + + +static void mesh_auto_add_even(vtc0_t *v, rnd_coord_t c1, rnd_coord_t c2, rnd_coord_t d) +{ + long num = (c2 - c1) / d; + + if (num < 1) + return; + + d = (c2 - c1)/(num+1); + if (d > 0) { + c2 -= d/4; /* open on the right, minus rounding errors */ + for(; c1 < c2; c1 += d) + vtc0_append(v, c1); + } +} + +static rnd_coord_t mesh_auto_add_interp(vtc0_t *v, rnd_coord_t c, rnd_coord_t d1, rnd_coord_t d2, rnd_coord_t dd) +{ + if (dd > 0) { + for(; d1 <= d2; d1 += dd) { + vtc0_append(v, c); + c += d1; + } + return c; + } + else { + for(; d1 <= d2; d1 -= dd) { + c -= d1; + vtc0_append(v, c); + } + return c; + } + +} + +static void mesh_auto_add_smooth(vtc0_t *v, rnd_coord_t c1, rnd_coord_t c2, rnd_coord_t d1, rnd_coord_t d, rnd_coord_t d2) +{ + rnd_coord_t len = c2 - c1, begin = c1, end = c2, glen; + int lines; + + /* ramp up (if there's room) */ + if (d > d1) { + lines = (d / d1) + 0; + if (lines > 0) { + glen = lines * d; + if (glen < len/4) + begin = mesh_auto_add_interp(v, c1, d1, d, (d-d1)/lines); + } + else + begin = c1; + } + + /* ramp down (if there's room) */ + if (d > d2) { + lines = (d / d2) + 0; + if (lines > 0) { + glen = lines * d; + if (glen < len/4) + end = mesh_auto_add_interp(v, c2, d2, d, -(d-d2)/lines); + } + else + end = c2; + } + + /* middle section: linear */ + mesh_auto_add_even(v, begin, end, d); +} + +static int mesh_auto_build(pcb_mesh_t *mesh, pcb_mesh_dir_t dir) +{ + size_t n; + rnd_coord_t c1, c2; + rnd_coord_t d1, d, d2; + + mesh_trace("build:\n"); + + /* left edge, before the first known line */ + if (!mesh->noimpl) { + c1 = 0; + c2 = mesh->line[dir].edge.array[0]; + mesh_find_range(&mesh->line[dir].dens, (c1+c2)/2, &d, &d1, &d2); + if (mesh->smooth) + mesh_auto_add_smooth(&mesh->line[dir].result, c1, c2, d1, d, d2); + else + mesh_auto_add_even(&mesh->line[dir].result, c1, c2, d); + } + + /* normal, between known lines */ + for(n = 0; n < vtc0_len(&mesh->line[dir].edge); n++) { + c1 = mesh->line[dir].edge.array[n]; + c2 = mesh->line[dir].edge.array[n+1]; + + vtc0_append(&mesh->line[dir].result, c1); + + if (c2 - c1 < mesh->dens_obj / 2) + continue; /* don't attempt to insert lines where it won't fit */ + + mesh_find_range(&mesh->line[dir].dens, (c1+c2)/2, &d, &d1, &d2); + if (c2 - c1 < d * 2) + continue; /* don't attempt to insert lines where it won't fit */ + + mesh_trace(" %mm..%mm %mm,%mm,%mm\n", c1, c2, d1, d, d2); + + if (mesh->noimpl) + continue; + + /* place mesh lines between c1 and c2 */ + if (mesh->smooth) + mesh_auto_add_smooth(&mesh->line[dir].result, c1, c2, d1, d, d2); + else + mesh_auto_add_even(&mesh->line[dir].result, c1, c2, d); + } + + /* right edge, after the last known line */ + if (!mesh->noimpl) { + c1 = mesh->line[dir].edge.array[vtc0_len(&mesh->line[dir].edge)-1]; + c2 = (dir == PCB_MESH_HORIZONTAL) ? PCB->hidlib.size_y : PCB->hidlib.size_x; + mesh_find_range(&mesh->line[dir].dens, (c1+c2)/2, &d, &d1, &d2); + if (mesh->smooth) + mesh_auto_add_smooth(&mesh->line[dir].result, c1, c2, d1, d, d2); + else + mesh_auto_add_even(&mesh->line[dir].result, c1, c2, d); + + vtc0_append(&mesh->line[dir].result, c2); /* ranges are open from the end, need to manually place the last */ + } + + mesh_trace("\n"); + return 0; +} + +int mesh_auto(pcb_mesh_t *mesh, pcb_mesh_dir_t dir) +{ + vtc0_truncate(&mesh->line[dir].edge, 0); + vtr0_truncate(&mesh->line[dir].dens, 0); + vtc0_truncate(&mesh->line[dir].result, 0); + + if (mesh_gen_obj(mesh, mesh->layer, dir) != 0) + return -1; + if (mesh_gen_obj_subc(mesh, dir) != 0) + return -1; + if (mesh_sort(mesh, dir) != 0) + return -1; + if (mesh_auto_build(mesh, dir) != 0) + return -1; + + if (mesh->ui_layer_xy != NULL) + mesh_vis_xy(mesh, dir); + + return 0; +} + +static void mesh_layer_reset() +{ + static rnd_color_t clr; + + if (clr.str[0] != '#') + rnd_color_load_str(&clr, "#007733"); + + if (mesh.ui_layer_xy != NULL) + pcb_uilayer_free(mesh.ui_layer_xy); + if (mesh.ui_layer_z != NULL) + pcb_uilayer_free(mesh.ui_layer_z); + mesh.ui_layer_xy = pcb_uilayer_alloc(mesh_ui_cookie, "mesh xy", &clr); + mesh.ui_layer_z = pcb_uilayer_alloc(mesh_ui_cookie, "mesh z", &clr); +} + +static void ia_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + RND_DAD_FREE(ia.dlg); + memset(&ia, 0, sizeof(ia)); +} + +static char *default_file = NULL; +static void ia_save_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + char *fname = NULL; + FILE *f; + gds_t tmp; + + fname = rnd_gui->fileselect(rnd_gui, "Save mesh settings...", + "Picks file for saving mesh settings.\n", + default_file, ".lht", NULL, "mesh", RND_HID_FSD_MAY_NOT_EXIST, NULL); + if (fname == NULL) + return; /* cancel */ + + if (default_file != NULL) { + free(default_file); + default_file = rnd_strdup(fname); + } + + f = rnd_fopen_askovr(&PCB->hidlib, fname, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can not open '%s' for write\n", fname); + return; + } + + gds_init(&tmp); + pcb_mesh_save(&ia, &tmp, NULL); + fprintf(f, "%s", tmp.array); + gds_uninit(&tmp); + free(fname); + fclose(f); +} + +static int ia_load_file(const char *fname) +{ + FILE *f; + int res; + + f = rnd_fopen(&PCB->hidlib, fname, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can not open '%s' for read\n", fname); + return -1; + } + + res = mesh_load_file(&ia, f); + if (res != 0) + rnd_message(RND_MSG_ERROR, "Loading mesh settings from '%s' failed.\n", fname); + fclose(f); + return res; +} + +static void ia_load_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + char *fname = NULL; + + fname = rnd_gui->fileselect(rnd_gui, "Load mesh settings...", + "Picks file for loading mesh settings from.\n", + default_file, ".lht", NULL, "mesh", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return; /* cancel */ + + if (default_file != NULL) { + free(default_file); + default_file = rnd_strdup(fname); + } + ia_load_file(fname); +} + +static void mesh_sort_uniq(pcb_mesh_lines_t *l) +{ + qsort(l->result.array, vtc0_len(&l->result), sizeof(rnd_coord_t), cmp_coord); +} + +static void mesh_sort_uniq_all(pcb_mesh_t *mesh) +{ + mesh_sort_uniq(&mesh->line[PCB_MESH_HORIZONTAL]); + mesh_sort_uniq(&mesh->line[PCB_MESH_VERTICAL]); + mesh_sort_uniq(&mesh->line[PCB_MESH_Z]); +} + +static void ia_gen(void) +{ + mesh_layer_reset(); + mesh.layer = PCB_CURRLAYER(PCB); + + if (ia.dlg[ia.hor].val.lng) + mesh_auto(&mesh, PCB_MESH_HORIZONTAL); + if (ia.dlg[ia.ver].val.lng) + mesh_auto(&mesh, PCB_MESH_VERTICAL); + + mesh_auto_z(&mesh); + if (mesh.ui_layer_z != NULL) + mesh_vis_z(&mesh); + + mesh_sort_uniq_all(&mesh); + + free(mesh.ui_name_xy); + free((char *)mesh.ui_layer_xy->name); /* we have strdup'd it */ + mesh.ui_name_xy = rnd_strdup_printf("mesh 0: %s", mesh.layer->name); + mesh.ui_layer_xy->name = rnd_strdup(mesh.ui_name_xy); + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + + rnd_gui->invalidate_all(rnd_gui); +} + +static void ia_gen_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + + dlg2mesh(); + ia_gen(); +} + +pcb_mesh_t *pcb_mesh_get(const char *name) +{ + return &mesh; +} + +int pcb_mesh_interactive(void) +{ + int n; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + if (ia.active) + return 0; + + RND_DAD_BEGIN_VBOX(ia.dlg); + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_BEGIN_VBOX(ia.dlg); + RND_DAD_COMPFLAG(ia.dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ia.dlg, "XY-mesh"); + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_COORD(ia.dlg); + ia.dens_obj = RND_DAD_CURRENT(ia.dlg); + RND_DAD_MINMAX(ia.dlg, 0, RND_MM_TO_COORD(5)); + RND_DAD_LABEL(ia.dlg, "copper dens."); + RND_DAD_HELP(ia.dlg, "mesh density over copper"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_COORD(ia.dlg); + ia.dens_gap = RND_DAD_CURRENT(ia.dlg); + RND_DAD_MINMAX(ia.dlg, 0, RND_MM_TO_COORD(5)); + RND_DAD_LABEL(ia.dlg, "gap dens."); + RND_DAD_HELP(ia.dlg, "mesh density over gaps"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_COORD(ia.dlg); + ia.min_space = RND_DAD_CURRENT(ia.dlg); + RND_DAD_MINMAX(ia.dlg, 0, RND_MM_TO_COORD(5)); + RND_DAD_LABEL(ia.dlg, "min. spacing"); + RND_DAD_HELP(ia.dlg, "minimum distance between mesh lines"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_BOOL(ia.dlg); + ia.smooth = RND_DAD_CURRENT(ia.dlg); + RND_DAD_LABEL(ia.dlg, "smooth mesh"); + RND_DAD_HELP(ia.dlg, "avoid jumps between different mesh densities,\nuse smooth (gradual) changes"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_BOOL(ia.dlg); + ia.hor = RND_DAD_CURRENT(ia.dlg); + RND_DAD_LABEL(ia.dlg, "horizontal"); + RND_DAD_HELP(ia.dlg, "enable adding horizontal mesh lines"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_BOOL(ia.dlg); + ia.ver = RND_DAD_CURRENT(ia.dlg); + RND_DAD_LABEL(ia.dlg, "vertical"); + RND_DAD_HELP(ia.dlg, "enable adding vertical mesh lines"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_BOOL(ia.dlg); + ia.noimpl = RND_DAD_CURRENT(ia.dlg); + RND_DAD_LABEL(ia.dlg, "omit implicit"); + RND_DAD_HELP(ia.dlg, "add only the mesh lines for boundaries,\nomit in-material meshing"); + RND_DAD_END(ia.dlg); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_VBOX(ia.dlg); + RND_DAD_COMPFLAG(ia.dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ia.dlg, "Z-mesh"); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_ENUM(ia.dlg, subslines); + ia.subslines = RND_DAD_CURRENT(ia.dlg); + RND_DAD_LABEL(ia.dlg, "num in substrate"); + RND_DAD_HELP(ia.dlg, "number of mesh lines in substrate"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_COORD(ia.dlg); + ia.def_subs_thick = RND_DAD_CURRENT(ia.dlg); + RND_DAD_MINMAX(ia.dlg, 0, RND_MM_TO_COORD(5)); + RND_DAD_LABEL(ia.dlg, "def. subst. thick"); + RND_DAD_HELP(ia.dlg, "default substrate thickness\n(for substrate layer groups without\nthickness specified in attribute)"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_COORD(ia.dlg); + ia.def_copper_thick = RND_DAD_CURRENT(ia.dlg); + RND_DAD_MINMAX(ia.dlg, 0, RND_MM_TO_COORD(5)); + RND_DAD_LABEL(ia.dlg, "def. copper thick"); + RND_DAD_HELP(ia.dlg, "default copper thickness\n(for copper layer groups without\nthickness specified in attribute)"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_BOOL(ia.dlg); + ia.air_top = RND_DAD_CURRENT(ia.dlg); + RND_DAD_LABEL(ia.dlg, "in air top"); + RND_DAD_HELP(ia.dlg, "add mesh lines in air above the top of the board"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_BOOL(ia.dlg); + ia.air_bot = RND_DAD_CURRENT(ia.dlg); + RND_DAD_LABEL(ia.dlg, "in air bottom"); + RND_DAD_HELP(ia.dlg, "add mesh lines in air below the bottom of the board"); + RND_DAD_END(ia.dlg); + + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_COORD(ia.dlg); + ia.dens_air = RND_DAD_CURRENT(ia.dlg); + RND_DAD_MINMAX(ia.dlg, 0, RND_MM_TO_COORD(5)); + RND_DAD_LABEL(ia.dlg, "dens. air"); + RND_DAD_HELP(ia.dlg, "mesh line density (spacing) in air"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_COORD(ia.dlg); + ia.max_air = RND_DAD_CURRENT(ia.dlg); + RND_DAD_MINMAX(ia.dlg, 0, RND_MM_TO_COORD(5)); + RND_DAD_LABEL(ia.dlg, "air thickness"); + RND_DAD_HELP(ia.dlg, "how far out to mesh in air"); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_BOOL(ia.dlg); + ia.smoothz = RND_DAD_CURRENT(ia.dlg); + RND_DAD_LABEL(ia.dlg, "smooth mesh"); + RND_DAD_HELP(ia.dlg, "avoid jumps between different mesh densities,\nuse smooth (gradual) changes"); + RND_DAD_END(ia.dlg); + + RND_DAD_END(ia.dlg); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_BEGIN_VBOX(ia.dlg); + RND_DAD_COMPFLAG(ia.dlg, RND_HATF_FRAME); + RND_DAD_LABEL(ia.dlg, "Boundary"); + for(n = 0; n < 6; n+=2) { + char name[64]; + sprintf(name, "%s %s", bnd_names[n], bnd_names[n+1]); + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_ENUM(ia.dlg, bnds); + ia.bnd[n] = RND_DAD_CURRENT(ia.dlg); + RND_DAD_LABEL(ia.dlg, name); + RND_DAD_ENUM(ia.dlg, bnds); + ia.bnd[n+1] = RND_DAD_CURRENT(ia.dlg); + RND_DAD_END(ia.dlg); + } + + RND_DAD_BEGIN_HBOX(ia.dlg); + RND_DAD_LABEL(ia.dlg, "PML cells:"); + RND_DAD_INTEGER(ia.dlg); + ia.pml = RND_DAD_CURRENT(ia.dlg); + RND_DAD_MINMAX(ia.dlg, 0, 32); + RND_DAD_DEFAULT_NUM(ia.dlg, 8); + RND_DAD_END(ia.dlg); + RND_DAD_END(ia.dlg); + + RND_DAD_BEGIN_VBOX(ia.dlg); + RND_DAD_BUTTON(ia.dlg, "Save to file"); + RND_DAD_CHANGE_CB(ia.dlg, ia_save_cb); + RND_DAD_BUTTON(ia.dlg, "Load from file"); + RND_DAD_CHANGE_CB(ia.dlg, ia_load_cb); + RND_DAD_BUTTON(ia.dlg, "Generate mesh!"); + RND_DAD_CHANGE_CB(ia.dlg, ia_gen_cb); + RND_DAD_END(ia.dlg); + RND_DAD_END(ia.dlg); + RND_DAD_BUTTON_CLOSES(ia.dlg, clbtn); + RND_DAD_END(ia.dlg); + + RND_DAD_NEW("mesh", ia.dlg, "mesher", &ia, 0, ia_close_cb); + ia.active = 1; + + mesh2dlg(); + return 0; +} + +const char pcb_acts_mesh[] = "mesh()"; +const char pcb_acth_mesh[] = "generate a mesh for simulation"; +fgw_error_t pcb_act_mesh(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_mesh_interactive(); + RND_ACT_IRES(0); + return 0; +} Index: tags/2.3.0/src_plugins/export_openems/mesh.h =================================================================== --- tags/2.3.0/src_plugins/export_openems/mesh.h (nonexistent) +++ tags/2.3.0/src_plugins/export_openems/mesh.h (revision 33253) @@ -0,0 +1,54 @@ +#include "layer.h" +#include +#include "vtr0.h" +#include + +typedef struct { + vtc0_t user_line; /* input: lines forced by the user */ + vtr0_t user_dens; /* input: density forced by the user */ + vtc0_t edge; /* input: around object edge - lines that must be in the mesh */ + vtr0_t dens; /* input: density ranges; data[0].c is the target density */ + vtc0_t result; /* resulting line coordinates */ +} pcb_mesh_lines_t; + +typedef enum { + PCB_MESH_HORIZONTAL, /* variable y coord (horizontal lines) */ + PCB_MESH_VERTICAL, /* variable x coord (vertical lines) */ + PCB_MESH_Z, + PCB_MESH_max +} pcb_mesh_dir_t; + +typedef struct { + pcb_layer_t *layer; /* input layer (objects are picked up from this layer) */ + pcb_layer_t *ui_layer_xy, *ui_layer_z; /* optional UI layers to draw the mesh on */ + char *ui_name_xy; /* name of the UI layer */ + rnd_coord_t dens_obj, dens_gap; /* target density: distance between mesh lines above objects and above gaps */ + rnd_coord_t min_space; /* make sure there's always at least this much space between two mesh lines */ + rnd_coord_t def_subs_thick; /* default substrate thickness */ + rnd_coord_t def_copper_thick; /* default copper thickness */ + pcb_mesh_lines_t line[PCB_MESH_max]; /* actual lines of the mesh */ + const char *bnd[6]; /* temporary: boundary conditions */ + rnd_coord_t z_bottom_copper; /* z coordinate of the bottom copper layer, along the z-mesh (0 is the top copper) */ + int pml; /* add pml cells around the exterior of the existing mesh of "perfectly matched" impedance */ + int subslines; /* number of mesh lines in substrate (z) */ + rnd_coord_t dens_air; /* mesh line density (spacing) in air */ + rnd_coord_t max_air; /* how far out to mesh in air */ + unsigned hor:1; /* enable adding horizontal mesh lines */ + unsigned ver:1; /* enable adding vertical mesh lines */ + unsigned smooth:1; /* if set, avoid jumps in the meshing by gradually changing meshing distance: x and y direction */ + unsigned smoothz:1; /* if set, avoid jumps in the meshing by gradually changing meshing distance: z direction */ + unsigned air_top:1; /* add mesh lines in air above the top of the board */ + unsigned air_bot:1; /* add mesh lines in air below the top of the board */ + unsigned noimpl:1; /* when set, do not add extra implicit mesh lines, keep the explicit ones only */ +} pcb_mesh_t; + +extern const char pcb_acts_mesh[]; +extern const char pcb_acth_mesh[]; +fgw_error_t pcb_act_mesh(fgw_arg_t *res, int oargc, fgw_arg_t *oargv); + +/* Get one of the configured meshes */ +pcb_mesh_t *pcb_mesh_get(const char *name); + +/* Return layer group thickness, warn for missing value and use fallback */ +rnd_coord_t mesh_layergrp_thickness(pcb_layergrp_t *grp, rnd_coord_t fallback); + Index: tags/2.3.0/src_plugins/export_openems/openems_xml.c =================================================================== --- tags/2.3.0/src_plugins/export_openems/openems_xml.c (nonexistent) +++ tags/2.3.0/src_plugins/export_openems/openems_xml.c (revision 33253) @@ -0,0 +1,314 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +static long def_num_timesteps = 1000000000; +static double def_end_crit = 1e-05; +static long def_f_max = 2100000000; + +static void openems_wr_xml_layergrp_end(wctx_t *ctx) +{ + if (ctx->cond_sheet_open) { + fprintf(ctx->f, " \n"); + fprintf(ctx->f, " \n"); + ctx->cond_sheet_open = 0; + } +} + +static rnd_coord_t get_grp_elev(wctx_t *ctx, pcb_layergrp_t *g) +{ + rnd_layergrp_id_t from, to; + + if (pcb_layergrp_list(ctx->pcb, PCB_LYT_BOTTOM|PCB_LYT_COPPER, &from, 1) != 1) { + ctx->elevation = 0; + rnd_message(RND_MSG_ERROR, "Missing bottom copper layer group - can not simulate\n"); + return -1; + } + to = g - ctx->pcb->LayerGroups.grp; + if (from == to) + return 0; + return pcb_stack_thickness(ctx->pcb, "openems", PCB_BRDTHICK_PRINT_ERROR, from, 1, to, 0, PCB_LYT_SUBSTRATE|PCB_LYT_COPPER); +} + +static int openems_wr_xml_layergrp_begin(wctx_t *ctx, pcb_layergrp_t *g) +{ + rnd_coord_t elev, th = ems_layergrp_thickness(g); + pcb_layer_t *ly = NULL; + + openems_wr_xml_layergrp_end(ctx); + + if (g->len < 0) { + /* shouldn't happen: we are not called for empty layer groups */ + return -1; + } + ly = pcb_get_layer(ctx->pcb->Data, g->lid[0]); + + fprintf(ctx->f, " \n", th); + + if (ly != NULL) { + fprintf(ctx->f, " \n", ly->meta.real.color.r, ly->meta.real.color.g, ly->meta.real.color.b); + fprintf(ctx->f, " \n", ly->meta.real.color.r, ly->meta.real.color.g, ly->meta.real.color.b); + } + + fprintf(ctx->f, " \n"); + ctx->cond_sheet_open = 1; + elev = get_grp_elev(ctx, g); + if (elev < 0) + return -1; + ctx->elevation = RND_COORD_TO_MM(elev); + return 0; +} + +static int openems_wr_xml_outline(wctx_t *ctx, pcb_layergrp_t *g) +{ + pcb_any_obj_t *out1; + rnd_coord_t th = ems_layergrp_thickness(g); + + if (th <= 0) { + rnd_message(RND_MSG_ERROR, "Substrate thickness is missing or invalid - can't export\n"); + return -1; + } + +TODO("layer: consider multiple outline layers instead") + out1 = pcb_topoly_find_1st_outline(ctx->pcb); + + rnd_fprintf(ctx->f, " \n", PRIO_SUBSTRATE, ctx->elevation, th); + if (out1 != NULL) { + long n; + pcb_poly_t *p = pcb_topoly_conn(ctx->pcb, out1, PCB_TOPOLY_KEEP_ORIG | PCB_TOPOLY_FLOATING); + + for(n = 0; n < p->PointN; n++) + rnd_fprintf(ctx->f, " \n", p->Points[n].X, -p->Points[n].Y); + pcb_poly_free(p); + } + else { + /* rectangular board size */ + rnd_fprintf(ctx->f, " \n", 0, 0); + rnd_fprintf(ctx->f, " \n", ctx->pcb->hidlib.size_x, 0); + rnd_fprintf(ctx->f, " \n", ctx->pcb->hidlib.size_x, -ctx->pcb->hidlib.size_y); + rnd_fprintf(ctx->f, " \n", 0, -ctx->pcb->hidlib.size_y); + } + rnd_fprintf(ctx->f, " \n"); + return 0; +} + + +static int openems_wr_xml_grp_substrate(wctx_t *ctx, pcb_layergrp_t *g) +{ + rnd_coord_t th = get_grp_elev(ctx, g); + + if (th < 0) + return -1; + ctx->elevation = RND_COORD_TO_MM(th); + + fprintf(ctx->f, " \n", g->name); + fprintf(ctx->f, " \n"); + fprintf(ctx->f, " \n"); + fprintf(ctx->f, " \n"); + fprintf(ctx->f, " \n"); + openems_wr_xml_outline(ctx, g); + fprintf(ctx->f, " \n"); + fprintf(ctx->f, " \n"); + return 0; +} + +static int openems_wr_xml_layers(wctx_t *ctx) +{ + rnd_hid_expose_ctx_t ectx = {0}; + rnd_cardinal_t gid; + int err = 0; + + + ectx.view.X1 = 0; + ectx.view.Y1 = 0; + ectx.view.X2 = ctx->pcb->hidlib.size_x; + ectx.view.Y2 = ctx->pcb->hidlib.size_y; + + rnd_expose_main(&openems_hid, &ectx, NULL); + openems_wr_xml_layergrp_end(ctx); + + /* export substrate bricks */ + for(gid = 0; gid < ctx->pcb->LayerGroups.len; gid++) { + pcb_layergrp_t *g = &ctx->pcb->LayerGroups.grp[gid]; + if (g->ltype & PCB_LYT_SUBSTRATE) + err |= openems_wr_xml_grp_substrate(ctx, g); + } + + return err; +} + +static void openems_wr_xml_mesh_lines(wctx_t *ctx, pcb_mesh_t *mesh, char axis, pcb_mesh_lines_t *l, rnd_coord_t scale) +{ + rnd_cardinal_t n, i = 0, len = vtc0_len(&l->result); + rnd_coord_t delta, at; + + fprintf(ctx->f, " <%cLines>", axis); + + if (mesh->pml > 0) { + delta = (l->result.array[1] - l->result.array[0]); + at = l->result.array[0] - delta * (mesh->pml+1); + for(n = 0; n < mesh->pml; n++) { + at += delta; + rnd_fprintf(ctx->f, "%s%mm", (i++ == 0 ? "" : ","), (rnd_coord_t)(at*scale)); + } + } + + for(n = 0; n < len; n++) + rnd_fprintf(ctx->f, "%s%mm", (i++ == 0 ? "" : ","), (rnd_coord_t)(l->result.array[n]*scale)); + + if (mesh->pml > 0) { + delta = (l->result.array[len-1] - l->result.array[len-2]); + at = l->result.array[len-1]; + for(n = 0; n < mesh->pml; n++) { + at += delta; + rnd_fprintf(ctx->f, "%s%mm", (i++ == 0 ? "" : ","), (rnd_coord_t)(at*scale)); + } + } + + fprintf(ctx->f, "\n", axis); +} + + +static void openems_wr_xml_grid(wctx_t *ctx, pcb_mesh_t *mesh) +{ + fprintf(ctx->f, " \n"); + openems_wr_xml_mesh_lines(ctx, mesh, 'Y', &mesh->line[PCB_MESH_HORIZONTAL], -1); + openems_wr_xml_mesh_lines(ctx, mesh, 'X', &mesh->line[PCB_MESH_VERTICAL], 1); + openems_wr_xml_mesh_lines(ctx, mesh, 'Z', &mesh->line[PCB_MESH_Z], 1); + fprintf(ctx->f, " \n"); +} + +static void openems_wr_xml_vport(wctx_t *ctx, pcb_any_obj_t *o, rnd_coord_t x, rnd_coord_t y, rnd_layergrp_id_t gid1, rnd_layergrp_id_t gid2, const char *safe_name, double resistance, int act) +{ + pcb_layergrp_t *g1, *g2; + rnd_coord_t e1, e2, em; + + g1 = pcb_get_layergrp(ctx->pcb, gid1); + g2 = pcb_get_layergrp(ctx->pcb, gid2); + if ((g1 == NULL) || (g2 == NULL)) { + rnd_message(RND_MSG_ERROR, "openems_wr_xml_vport: invalid layer groups"); + return; + } + e1 = get_grp_elev(ctx, g1); + e2 = get_grp_elev(ctx, g2); + if ((e1 < 0) || (e2 < 0)) { + rnd_message(RND_MSG_ERROR, "openems_wr_xml_vport: can not determine layer group elevations"); + return; + } + em = rnd_round((double)(e1+e2)/2.0); + + ctx->port_id++; + + rnd_fprintf(ctx->f, " \n", ctx->port_id, resistance); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n", PRIO_PORT); + rnd_fprintf(ctx->f, " \n", x, -y, e1); + rnd_fprintf(ctx->f, " \n", x, -y, e2); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + + rnd_fprintf(ctx->f, " \n", ctx->port_id); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n", x, -y, e1); + rnd_fprintf(ctx->f, " \n", x, -y, e2); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n", ctx->port_id); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n", x, -y, em); + rnd_fprintf(ctx->f, " \n", x, -y, em); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + + TODO("Check if it is true:"); + /* excitation is always fed in on port 1 */ + if (ctx->port_id == 1) { + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n", x, -y, e1); + rnd_fprintf(ctx->f, " \n", x, -y, e2); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + rnd_fprintf(ctx->f, " \n"); + } + +} + + +static int openems_wr_xml(wctx_t *ctx) +{ + pcb_mesh_t *mesh = pcb_mesh_get(MESH_NAME); + char *exc; + int err = 0; + + fprintf(ctx->f, "\n"); + fprintf(ctx->f, "\n"); + fprintf(ctx->f, " \n", def_num_timesteps, def_end_crit, def_f_max); + + exc = pcb_openems_excitation_get(ctx->pcb, 0); + if (exc != NULL) { + fprintf(ctx->f, " \n", exc); + fprintf(ctx->f, " \n"); + } + else { + fprintf(ctx->f, "\n"); + rnd_message(RND_MSG_ERROR, "openems xml: no excitation selected or invalid excitation\n"); + } + free(exc); + + if ((mesh != NULL) && (mesh->bnd[0] != NULL)) { + fprintf(ctx->f, " \n", mesh->bnd[0], mesh->bnd[1], mesh->bnd[2], mesh->bnd[3], mesh->bnd[4], mesh->bnd[5]); + fprintf(ctx->f, " \n"); + } + fprintf(ctx->f, " \n"); + + fprintf(ctx->f, " \n"); + fprintf(ctx->f, " \n", ctx->options[HA_void_epsilon].dbl, ctx->options[HA_void_mue].dbl); + + fprintf(ctx->f, " \n"); + err |= openems_wr_xml_layers(ctx); + openems_wr_testpoints(ctx, ctx->pcb->Data); + fprintf(ctx->f, " \n"); + + openems_wr_xml_grid(ctx, mesh); + fprintf(ctx->f, " \n"); + + + fprintf(ctx->f, "\n"); + return err; +} + Index: tags/2.3.0/src_plugins/export_openscad/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_openscad/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_openscad/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_openscad + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_openscad/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_openscad/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_openscad/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {export_openscad} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/export_openscad/export_openscad.o +@] + +switch /local/pcb/export_openscad/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_openscad/export_openscad.c =================================================================== --- tags/2.3.0/src_plugins/export_openscad/export_openscad.c (nonexistent) +++ tags/2.3.0/src_plugins/export_openscad/export_openscad.c (revision 33253) @@ -0,0 +1,716 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "board.h" +#include "data.h" +#include "draw.h" +#include +#include "layer.h" +#include "layer_vis.h" +#include +#include +#include +#include +#include "obj_pstk_inlines.h" +#include "funchash_core.h" + +#include +#include + +#include +#include +#include +#include "hid_cam.h" + + +static rnd_hid_t openscad_hid; + +const char *openscad_cookie = "openscad HID"; + + +typedef struct rnd_hid_gc_s { + rnd_core_gc_t core_gc; + rnd_hid_t *me_pointer; + rnd_cap_style_t cap; + int width; +} rnd_hid_gc_s; + +static FILE *f = NULL; +static unsigned layer_open; +static double layer_thickness = 0.01, effective_layer_thickness; +static gds_t layer_group_calls, model_calls; +static const char *scad_group_name; +static int scad_group_level; +static const char *scad_group_color; +static int scad_layer_cnt; +static vti0_t scad_comp; + +static rnd_hid_attr_val_t *openscad_options; + +rnd_export_opt_t openscad_attribute_list[] = { + /* other HIDs expect this to be first. */ + +/* %start-doc options "93 DXF Options" +@ftable @code +@item --outfile +Name of the file to be exported to. Can contain a path. +@end ftable +%end-doc +*/ + {"outfile", "Graphics output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_openscadfile 0 + + {"copper", "enable exporting outer copper layers", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_copper 1 + + {"silk", "enable exporting silk layers", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_silk 2 + + {"mask", "enable exporting mask layers", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_mask 3 + + {"models", "enable searching and inserting model files", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_models 4 + + {"drill", "enable drilling holes", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_drill 5 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 6 + +}; + +#define NUM_OPTIONS (sizeof(openscad_attribute_list)/sizeof(openscad_attribute_list[0])) + +#include "scad_draw.c" +#include "scad_models.c" + +static rnd_hid_attr_val_t openscad_values[NUM_OPTIONS]; + +static rnd_export_opt_t *openscad_get_export_options(rnd_hid_t *hid, int *n) +{ + const char *suffix = ".scad"; + + if ((PCB != NULL) && (openscad_attribute_list[HA_openscadfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &openscad_attribute_list[HA_openscadfile], suffix); + + if (n) + *n = NUM_OPTIONS; + return openscad_attribute_list; +} + +void openscad_hid_export_to_file(FILE * the_file, rnd_hid_attr_val_t * options) +{ + static int saved_layer_stack[PCB_MAX_LAYER]; + rnd_hid_expose_ctx_t ctx; + + ctx.view.X1 = 0; + ctx.view.Y1 = 0; + ctx.view.X2 = PCB->hidlib.size_x; + ctx.view.Y2 = PCB->hidlib.size_y; + + f = the_file; + + memcpy(saved_layer_stack, pcb_layer_stack, sizeof(pcb_layer_stack)); + + rnd_conf_force_set_bool(conf_core.editor.show_solder_side, 0); + + openscad_options = options; + rnd_expose_main(&openscad_hid, &ctx, NULL); + openscad_options = NULL; + + rnd_conf_update(NULL, -1); /* restore forced sets */ +} + +static void scad_close_layer() +{ + if (layer_open) { + fprintf(f, " }\n"); + fprintf(f, "}\n\n"); + layer_open = 0; + } +} + +static void scad_dump_comp(void) +{ + int n, closes = 0; + +/* + a layer list like this: +4 -5 -0 +6 -7 + becomes script like this: + + difference() + { + union() { + difference() { + 4 + 5 + 0 + } + 6 + } + 7 + } + +*/ + + /* add an union or difference on polarity change */ + for(n = vti0_len(&scad_comp)-2; n >= 0; n--) { + int p1 = (scad_comp.array[n]) > 0, p2 = (scad_comp.array[n+1] > 0); + if (p2 && !p1) { + fprintf(f, " union() {\n"); + closes++; + } + if (!p2 && p1) { + fprintf(f, " difference() {\n"); + closes++; + } + } + + /* list layer calls, add a close on polarity change */ + for(n = 0; n < vti0_len(&scad_comp); n++) { + int id = scad_comp.array[n], is_pos = id > 0; + if (id < 0) + id = -id; + fprintf(f, " layer_%s_%s_%d();\n", scad_group_name, is_pos ? "pos" : "neg", id); + if ((n > 0) && (n < vti0_len(&scad_comp)-1)) { + int id2 = scad_comp.array[n+1]; + int p1 = is_pos, p2 = (id2 > 0); + if (p2 != p1) { + fprintf(f, "}\n"); + closes--; + } + } + } + + /* the first open needs to be closed manually */ + if (closes) + fprintf(f, "}\n"); +} + +static void scad_close_layer_group() +{ + if (scad_group_name != NULL) { + fprintf(f, "module layer_group_%s() {\n", scad_group_name); + scad_dump_comp(); + fprintf(f, "}\n\n"); + + rnd_append_printf(&layer_group_calls, " layer_group_%s();\n", scad_group_name); + scad_group_name = NULL; + scad_group_color = NULL; + scad_group_level = 0; + vti0_truncate(&scad_comp, 0); + } +} + +static void scad_new_layer(int is_pos) +{ + double h; + scad_layer_cnt++; + + if (is_pos) + vti0_append(&scad_comp, scad_layer_cnt); + else + vti0_append(&scad_comp, -scad_layer_cnt); + + scad_close_layer(); + + if (is_pos) { + effective_layer_thickness = layer_thickness; + if (scad_group_level > 0) + h = 0.8+((double)scad_group_level*1.1) * effective_layer_thickness; + else + h = -0.8+((double)scad_group_level*1.1) * effective_layer_thickness; + } + else { + double mult = 2.0; + effective_layer_thickness = layer_thickness * mult; + if (scad_group_level > 0) + h = 0.8+((double)scad_group_level*1.1) * layer_thickness; + else + h = -0.8+((double)scad_group_level*1.1) * layer_thickness; + h -= effective_layer_thickness/2.0; + effective_layer_thickness+=1.0; + } + fprintf(f, "module layer_%s_%s_%d() {\n", scad_group_name, is_pos ? "pos" : "neg", scad_layer_cnt); + fprintf(f, " color([%s])\n", scad_group_color); + fprintf(f, " translate([0,0,%f]) {\n", h); + layer_open = 1; + +} + + +static void scad_new_layer_group(const char *group_name, int level, const char *color) +{ + scad_close_layer_group(); + + scad_group_name = group_name; + scad_group_level = level; + scad_group_color = color; + scad_group_level = level; +} + + +static void openscad_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + const char *filename; + int save_ons[PCB_MAX_LAYER]; + int i; + pcb_cam_t cam; + + if (!options) { + openscad_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + openscad_values[i] = openscad_attribute_list[i].default_val; + options = openscad_values; + } + + filename = options[HA_openscadfile].str; + if (!filename) + filename = "pcb.openscad"; + + pcb_cam_begin_nolayer(PCB, &cam, NULL, options[HA_cam].str, &filename); + + f = rnd_fopen_askovr(&PCB->hidlib, filename, "wb", NULL); + if (!f) { + perror(filename); + return; + } + + pcb_hid_save_and_show_layer_ons(save_ons); + + scad_layer_cnt = 0; + scad_draw_primitives(); + + if (scad_draw_outline() < 0) + return; + + gds_init(&layer_group_calls); + gds_init(&model_calls); + vti0_init(&scad_comp); + + if (options[HA_models].lng) + scad_insert_models(); + + openscad_hid_export_to_file(f, options); + scad_close_layer_group(); + + if (options[HA_drill].lng) + scad_draw_drills(); + + scad_draw_finish(options); + + pcb_hid_restore_layer_ons(save_ons); + + gds_uninit(&layer_group_calls); + gds_uninit(&model_calls); + vti0_uninit(&scad_comp); + + fclose(f); + f = NULL; + pcb_cam_end(&cam); +} + +static int openscad_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(openscad_attribute_list, sizeof(openscad_attribute_list) / sizeof(openscad_attribute_list[0]), openscad_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + + + +static int openscad_set_layer_group(rnd_hid_t *hid, 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 (flags & PCB_LYT_UI) + return 0; + + if (flags & PCB_LYT_INVIS) + return 0; + + if (PCB_LAYER_IS_ROUTE(flags, purpi)) { + return 0; + } + + if (PCB_LAYER_IS_DRILL(flags, purpi)) + return 0; + + if (flags & PCB_LYT_MASK) { + if (!openscad_options[HA_mask].lng) + return 0; + if (flags & PCB_LYT_TOP) { + scad_new_layer_group("top_mask", +2, "0,0.7,0,0.5"); + return 1; + } + if (flags & PCB_LYT_BOTTOM) { + scad_new_layer_group("bottom_mask", -2, "0,0.7,0,0.5"); + return 1; + } + } + + if (flags & PCB_LYT_SILK) { + if (!openscad_options[HA_silk].lng) + return 0; + if (flags & PCB_LYT_TOP) { + scad_new_layer_group("top_silk", +3, "0,0,0"); + return 1; + } + if (flags & PCB_LYT_BOTTOM) { + scad_new_layer_group("bottom_silk", -3, "0,0,0"); + return 1; + } + } + + if (flags & PCB_LYT_COPPER) { + if (!openscad_options[HA_copper].lng) { + printf("skip copper\n"); + return 0; + } + if (flags & PCB_LYT_TOP) { + scad_new_layer_group("top_copper", +1, "1,0.4,0.2"); + return 1; + } + if (flags & PCB_LYT_BOTTOM) { + scad_new_layer_group("bottom_copper", -1, "1,0.4,0.2"); + return 1; + } + } + + return 0; +} + + +static rnd_hid_gc_t openscad_make_gc(rnd_hid_t *hid) +{ + rnd_hid_gc_t rv = (rnd_hid_gc_t) calloc(sizeof(rnd_hid_gc_s), 1); + rv->me_pointer = &openscad_hid; + return rv; +} + +static void openscad_destroy_gc(rnd_hid_gc_t gc) +{ + free(gc); +} + +static void openscad_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + switch(op) { + case RND_HID_COMP_RESET: + break; + + case RND_HID_COMP_POSITIVE: + case RND_HID_COMP_POSITIVE_XOR: + scad_new_layer(1); + break; + case RND_HID_COMP_NEGATIVE: + scad_new_layer(0); + break; + + case RND_HID_COMP_FLUSH: + scad_close_layer(); + break; + } +} + +static void openscad_set_color(rnd_hid_gc_t gc, const rnd_color_t *name) +{ +} + +static void openscad_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + gc->cap = style; +} + +static void openscad_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + gc->width = width; +} + + +static void openscad_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ + ; +} + +#define fix_rect_coords() \ + if (x1 > x2) {\ + rnd_coord_t t = x1; \ + x1 = x2; \ + x2 = t; \ + } \ + if (y1 > y2) { \ + rnd_coord_t t = y1; \ + y1 = y2; \ + y2 = t; \ + } + + +static void openscad_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + TRX(x1); TRY(y1); + TRX(x2); TRY(y2); + + fix_rect_coords(); + rnd_fprintf(f, " pcb_fill_rect(%mm, %mm, %mm, %mm, %f, %f);\n", + x1, y1, x2, y2, 0.0, effective_layer_thickness); +} + +static void openscad_draw_line(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + double length, angle; + const char *cap_style; + + TRX(x1); TRY(y1); + TRX(x2); TRY(y2); + + length = rnd_distance(x1, y1, x2, y2); + angle = atan2((double)y2-y1, (double)x2-x1); + + if (gc->cap == rnd_cap_square) + cap_style = "sc"; + else + cap_style = "rc"; + + rnd_fprintf(f, " pcb_line_%s(%mm, %mm, %mm, %f, %mm, %f);\n", cap_style, + x1, y1, (rnd_coord_t)rnd_round(length), angle * RND_RAD_TO_DEG, gc->width, effective_layer_thickness); +} + +static void openscad_draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + TRX(x1); TRY(y1); + TRX(x2); TRY(y2); + + fix_rect_coords(); + openscad_draw_line(gc, x1, y1, x2, y1); + openscad_draw_line(gc, x2, y1, x2, y2); + openscad_draw_line(gc, x2, y2, x1, y2); + openscad_draw_line(gc, x1, y2, x1, y1); +} + +static void openscad_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) +{ + double a, step = delta_angle/10.0, end_angle = start_angle + delta_angle; + int first; + rnd_coord_t lx, ly, x, y; + + if (step >= 0) { + if (step < 1) step = 1; + if (step > 10) step = 10; + } + else { + if (step > -1) step = -1; + if (step < -0) step = -10; + } + + /* only recent versions support angle for rotate_extrude(), so use line approximation for now */ + fprintf(f, " // line-approx arc %f .. %f by %f\n", start_angle, end_angle, step); + + TODO("use the central arc approximation instead"); + for(first = 1, a = start_angle; step > 0 ? (a < end_angle) : (a > end_angle); a += step) { + x = (double)cx + cos((180-a) / RND_RAD_TO_DEG) * (double)width; + y = (double)cy + sin((180-a) / RND_RAD_TO_DEG) * (double)height; + if (!first) { + fprintf(f, "\t"); + openscad_draw_line(gc, lx, ly, x, y); + } + lx = x; + ly = y; + first = 0; + } + if (!first) { + x = (double)cx + cos((180 - end_angle) / RND_RAD_TO_DEG) * (double)width; + y = (double)cy + sin((180 - end_angle) / RND_RAD_TO_DEG) * (double)height; + fprintf(f, "\t"); + openscad_draw_line(gc, lx, ly, x, y); + } +} + +static void openscad_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + TRX(cx); TRY(cy); + + rnd_fprintf(f, " pcb_fcirc(%mm, %mm, %mm, %f);\n", cx, cy, radius, effective_layer_thickness); +} + +static void openscad_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) +{ + int n; + fprintf(f, " pcb_fill_poly(["); + for(n = 0; n < n_coords-1; n++) + rnd_fprintf(f, "[%mm,%mm],", TRX_(x[n]+dx), TRY_(y[n]+dy)); + rnd_fprintf(f, "[%mm,%mm]], %f);\n", TRX_(x[n]+dx), TRY_(y[n]+dy), effective_layer_thickness); +} + +static void openscad_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + openscad_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + +static void openscad_calibrate(rnd_hid_t *hid, double xval, double yval) +{ + rnd_message(RND_MSG_ERROR, "openscad_calibrate() not implemented"); + return; +} + +static void openscad_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int a) +{ +} + +static int openscad_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nopenscad exporter command line arguments:\n\n"); + rnd_hid_usage(openscad_attribute_list, sizeof(openscad_attribute_list) / sizeof(openscad_attribute_list[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x openscad [openscad options] foo.pcb\n\n"); + return 0; +} + + +static const char pcb_acts_scad_export_poly[] = "ScadExportPoly(filename)\n"; +static const char pcb_acth_scad_export_poly[] = "exports all selected polygons to an openscad script; only the outmost contour of each poly is exported"; +static fgw_error_t pcb_act_scad_export_poly(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + FILE *f; + const char *name; + + RND_ACT_CONVARG(1, FGW_STR, scad_export_poly, name = argv[1].val.str); + + f = rnd_fopen_askovr(&PCB->hidlib, name, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to open %s for writing\n", name); + RND_ACT_IRES(-1); + return 0; + } + + + PCB_POLY_ALL_LOOP(PCB->Data); { + pcb_poly_it_t it; + rnd_polyarea_t *pa; + + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, polygon)) + continue; + + /* iterate over all islands of a polygon */ + for(pa = pcb_poly_island_first(polygon, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_coord_t x, y; + rnd_pline_t *pl; + int go; + + /* check if we have a contour for the given island */ + pl = pcb_poly_contour(&it); + if (pl != NULL) { + int cnt; + + fprintf(f, "polygon(["); + /* iterate over the vectors of the contour */ + for(go = pcb_poly_vect_first(&it, &x, &y),cnt = 0; go; go = pcb_poly_vect_next(&it, &x, &y), cnt++) + rnd_fprintf(f, "%s[%mm,%mm]", (cnt > 0 ? "," : ""), x, y); + fprintf(f, "]);\n"); + } + } + } PCB_ENDALL_LOOP; + + fclose(f); + + RND_ACT_IRES(0); + return 0; +} + + +static rnd_action_t scad_action_list[] = { + {"ExportScadPoly", pcb_act_scad_export_poly, pcb_acth_scad_export_poly, pcb_acts_scad_export_poly} +}; + +int pplg_check_ver_export_openscad(int ver_needed) { return 0; } + +void pplg_uninit_export_openscad(void) +{ + rnd_export_remove_opts_by_cookie(openscad_cookie); + rnd_remove_actions_by_cookie(openscad_cookie); + rnd_hid_remove_hid(&openscad_hid); +} + +int pplg_init_export_openscad(void) +{ + RND_API_CHK_VER; + + memset(&openscad_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&openscad_hid); + + openscad_hid.struct_size = sizeof(rnd_hid_t); + openscad_hid.name = "openscad"; + openscad_hid.description = "OpenSCAD exporter"; + openscad_hid.exporter = 1; + + openscad_hid.get_export_options = openscad_get_export_options; + openscad_hid.do_export = openscad_do_export; + openscad_hid.parse_arguments = openscad_parse_arguments; + openscad_hid.set_layer_group = openscad_set_layer_group; + openscad_hid.make_gc = openscad_make_gc; + openscad_hid.destroy_gc = openscad_destroy_gc; + openscad_hid.set_drawing_mode = openscad_set_drawing_mode; + openscad_hid.set_color = openscad_set_color; + openscad_hid.set_line_cap = openscad_set_line_cap; + openscad_hid.set_line_width = openscad_set_line_width; + openscad_hid.set_draw_xor = openscad_set_draw_xor; + openscad_hid.draw_line = openscad_draw_line; + openscad_hid.draw_arc = openscad_draw_arc; + openscad_hid.draw_rect = openscad_draw_rect; + openscad_hid.fill_circle = openscad_fill_circle; + openscad_hid.fill_polygon = openscad_fill_polygon; + openscad_hid.fill_polygon_offs = openscad_fill_polygon_offs; + openscad_hid.fill_rect = openscad_fill_rect; + openscad_hid.calibrate = openscad_calibrate; + openscad_hid.set_crosshair = openscad_set_crosshair; + + openscad_hid.usage = openscad_usage; + + rnd_hid_register_hid(&openscad_hid); + + RND_REGISTER_ACTIONS(scad_action_list, openscad_cookie) + + return 0; +} Index: tags/2.3.0/src_plugins/export_openscad/export_openscad.pup =================================================================== --- tags/2.3.0/src_plugins/export_openscad/export_openscad.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_openscad/export_openscad.pup (revision 33253) @@ -0,0 +1,10 @@ +$class export +$short openscad pcb_exporter +$long Export openscad +$state WIP +$fmt-native no +$fmt-feature-w openscad script (colored 3D model) +$package export +dep lib_polyhelp +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_openscad/scad_draw.c =================================================================== --- tags/2.3.0/src_plugins/export_openscad/scad_draw.c (nonexistent) +++ tags/2.3.0/src_plugins/export_openscad/scad_draw.c (revision 33253) @@ -0,0 +1,159 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "../lib_polyhelp/topoly.h" +#include "plug_io.h" + +#define TRX_(x) (x) +#define TRY_(y) (PCB->hidlib.size_y - (y)) + +#define TRX(x) +#define TRY(y) y = TRY_(y) + +static void scad_draw_primitives(void) +{ + fprintf(f, "// Round cap line\n"); + fprintf(f, "module pcb_line_rc(x1, y1, length, angle, width, thick) {\n"); + fprintf(f, " translate([x1,y1,0]) {\n"); + fprintf(f, " rotate([0,0,angle]) {\n"); + fprintf(f, " translate([length/2, 0, 0])\n"); + fprintf(f, " cube([length, width, thick], center=true);\n"); + fprintf(f, " cylinder(r=width/2, h=thick, center=true, $fn=30);\n"); + fprintf(f, " translate([length, 0, 0])\n"); + fprintf(f, " cylinder(r=width/2, h=thick, center=true, $fn=30);\n"); + fprintf(f, " }\n"); + fprintf(f, " }\n"); + fprintf(f, "}\n"); + + fprintf(f, "// Square cap line\n"); + fprintf(f, "module pcb_line_sc(x1, y1, length, angle, width, thick) {\n"); + fprintf(f, " translate([x1,y1,0]) {\n"); + fprintf(f, " rotate([0,0,angle]) {\n"); + fprintf(f, " translate([length/2, 0, 0])\n"); + fprintf(f, " cube([length + width, width, thick], center=true);\n"); + fprintf(f, " }\n"); + fprintf(f, " }\n"); + fprintf(f, "}\n"); + + fprintf(f, "// filled rectangle\n"); + fprintf(f, "module pcb_fill_rect(x1, y1, x2, y2, angle, thick) {\n"); + fprintf(f, " translate([(x1+x2)/2,(y1+y2)/2,0])\n"); + fprintf(f, " rotate([0,0,angle])\n"); + fprintf(f, " cube([x2-x1, y2-y1, thick], center=true);\n"); + fprintf(f, "}\n"); + + fprintf(f, "// filled polygon\n"); + fprintf(f, "module pcb_fill_poly(coords, thick) {\n"); + fprintf(f, " linear_extrude(height=thick)\n"); + fprintf(f, " polygon(coords);\n"); + fprintf(f, "}\n"); + + fprintf(f, "// filled circle\n"); + fprintf(f, "module pcb_fcirc(x1, y1, radius, thick) {\n"); + fprintf(f, " translate([x1,y1,0])\n"); + fprintf(f, " cylinder(r=radius, h=thick, center=true, $fn=30);\n"); + fprintf(f, "}\n"); +} + +static int scad_draw_outline(void) +{ + pcb_poly_t *poly = pcb_topoly_1st_outline(PCB, PCB_TOPOLY_FLOATING); + int n; + + if (poly == NULL) + return -1; + + fprintf(f, "module pcb_outline() {\n"); + fprintf(f, " polygon([\n\t\t"); + /* we need the as-drawn polygon and we know there are no holes */ + for(n = 0; n < poly->PointN; n++) + rnd_fprintf(f, "[%mm,%mm]%s", TRX_(poly->Points[n].X), TRY_(poly->Points[n].Y), ((n < (poly->PointN-1)) ? "," : "\n")); + fprintf(f, " ]);\n"); + fprintf(f, "}\n"); + + pcb_poly_free(poly); + return 0; +} + +static void scad_draw_pstk(const pcb_pstk_t *ps) +{ + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + + if (proto == NULL) { + pcb_io_incompat_save(ps->parent.data, (pcb_any_obj_t *)ps, "padstack-proto", "failed to retrieve padstack prototype", "internal pcb-rnd error, please file a bugreport"); + return; + } + +TODO("padstack: this ignores bbvias") +TODO("slot: this ignores slots") + if (proto->hdia > 0) { + rnd_fprintf(f, " translate([%mm,%mm,0])\n", TRX_(ps->x), TRY_(ps->y)); + rnd_fprintf(f, " cylinder(r=%mm, h=4, center=true, $fn=30);\n", proto->hdia/2); + } +} + +static void scad_draw_drills(void) +{ + rnd_rtree_it_t it; + rnd_box_t *obj; + + fprintf(f, "module pcb_drill() {\n"); + + for(obj = rnd_r_first(PCB->Data->padstack_tree, &it); obj != NULL; obj = rnd_r_next(&it)) + scad_draw_pstk((pcb_pstk_t *)obj); + + fprintf(f, "}\n"); +} + +static void scad_draw_finish(rnd_hid_attr_val_t *options) +{ + fprintf(f, "module pcb_board_main() {\n"); + fprintf(f, " translate ([0, 0, -0.8])\n"); + fprintf(f, " linear_extrude(height=1.6)\n"); + fprintf(f, " pcb_outline();\n"); + fprintf(f, "%s", layer_group_calls.array); + fprintf(f, "}\n"); + fprintf(f, "\n"); + + fprintf(f, "module pcb_board() {\n"); + fprintf(f, " intersection() {\n"); + fprintf(f, " translate ([0, 0, -4])\n"); + fprintf(f, " linear_extrude(height=8)\n"); + fprintf(f, " pcb_outline();\n"); + fprintf(f, " union() {\n"); + fprintf(f, " difference() {\n"); + fprintf(f, " pcb_board_main();\n"); + if (options[HA_drill].lng) + fprintf(f, " pcb_drill();\n"); + fprintf(f, " }\n"); + fprintf(f, " }\n"); + fprintf(f, " }\n"); + fprintf(f, "%s", model_calls.array); + fprintf(f, "}\n"); + fprintf(f, "\n"); + + fprintf(f, "pcb_board();\n"); +} Index: tags/2.3.0/src_plugins/export_openscad/scad_models.c =================================================================== --- tags/2.3.0/src_plugins/export_openscad/scad_models.c (nonexistent) +++ tags/2.3.0/src_plugins/export_openscad/scad_models.c (revision 33253) @@ -0,0 +1,141 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "conf_core.h" + +static void scad_insert_model(htsp_t *models, const char *name, rnd_coord_t x0, rnd_coord_t y0, double rot, int on_bottom, const char *transf, const char *param) +{ + FILE *fin; + char *ref; + + if (!htsp_has(models, name)) { + char buff[1024], *full_path; + fin = rnd_fopen_first(&PCB->hidlib, &conf_core.rc.library_search_paths, name, "r", &full_path, rnd_true); + + if (fin != NULL) { + char *s, *safe_name = rnd_strdup(name); + for(s = safe_name; *s != '\0'; s++) + if (!isalnum(*s)) + *s = '_'; + + fprintf(f, "// Model loaded from '%s'\n", full_path); + free(full_path); + + /* replace the module line */ + while(fgets(buff, sizeof(buff), fin) != NULL) { + char *mod = strstr(buff, "module"), *par; + if (mod != NULL) { + mod += 6; + *mod = '\0'; + mod++; + fprintf(f, "%s", buff); + while(isspace(*mod)) mod++; + if (!isalpha(*mod) && (*mod != '_')) + rnd_message(RND_MSG_ERROR, "Openscad model '%s': module name must be in the same line as the module keyword\n", full_path); + fprintf(f, " pcb_part_%s", safe_name); + par = strchr(mod, '('); + if (par != NULL) + fprintf(f, "%s", par); + else + fprintf(f, "\n"); + break; + } + fprintf(f, "%s", buff); + } + + /* copy the rest */ + while(fgets(buff, sizeof(buff), fin) != NULL) { + fprintf(f, "%s", buff); + } + fclose(fin); + rnd_snprintf(buff, sizeof(buff), "pcb_part_%s", safe_name); + htsp_set(models, (char *)name, rnd_strdup(buff)); + free(safe_name); + } + else { + htsp_set(models, (char *)name, NULL); + rnd_message(RND_MSG_WARNING, "openscad: can't find model file for %s in the footprint library\n", name); + } + } + ref = htsp_get(models, (char *)name); + if (ref != NULL) { + char tab[] = "\t\t\t\t\t\t\t\t"; + int ind = 0; + rnd_append_printf(&model_calls, " translate([%mm,%mm,%c0.8])\n", x0, y0, on_bottom ? '-' : '+'); + ind++; + tab[ind] = '\0'; + + if ((rot != 0) || on_bottom) { + rnd_append_printf(&model_calls, " %srotate([%d,0,%f])\n", tab, (on_bottom ? 180 : 0), rot); + tab[ind] = '\t'; ind++; tab[ind] = '\0'; + } + + if (transf != NULL) { + rnd_append_printf(&model_calls, " %s%s\n", tab, transf); + tab[ind] = '\t'; ind++; tab[ind] = '\0'; + } + + + if (param != NULL) + rnd_append_printf(&model_calls, " %s%s(%s);\n", tab, ref, param); + else + rnd_append_printf(&model_calls, " %s%s();\n", tab, ref); + } +} + +static void scad_insert_models(void) +{ + htsp_t models; + const char *mod, *transf, *param; + htsp_entry_t *e; + + htsp_init(&models, strhash, strkeyeq); + + PCB_SUBC_LOOP(PCB->Data); { + mod = pcb_attribute_get(&subc->Attributes, "openscad"); + if (mod != NULL) { + rnd_coord_t ox, oy; + double rot = 0; + int on_bottom = 0; + + if (pcb_subc_get_origin(subc, &ox, &oy) != 0) { + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)subc, "subc-place", "Failed to get origin of subcircuit", "fix the missing subc-aux layer"); + continue; + } + pcb_subc_get_rotation(subc, &rot); + pcb_subc_get_side(subc, &on_bottom); + + transf = pcb_attribute_get(&subc->Attributes, "openscad-transformation"); + param = pcb_attribute_get(&subc->Attributes, "openscad-param"); + scad_insert_model(&models, mod, TRX_(ox), TRY_(oy), rot, on_bottom, transf, param); + } + } PCB_END_LOOP; + + for (e = htsp_first(&models); e; e = htsp_next(&models, e)) + free(e->value); + + htsp_uninit(&models); +} Index: tags/2.3.0/src_plugins/export_png/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_png/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_png/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_png + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_png/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_png/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_png/Plug.tmpasm (revision 33253) @@ -0,0 +1,16 @@ +put /local/pcb/mod {export_png} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_png/png.o @] + +switch /local/pcb/export_png/controls + case {disable} end; + default + put /local/pcb/mod/LDFLAGS libs/gui/gd/ldflags + put /local/pcb/mod/CFLAGS libs/gui/gd/cflags + end +end + +switch /local/pcb/export_png/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_png/export_png.pup =================================================================== --- tags/2.3.0/src_plugins/export_png/export_png.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_png/export_png.pup (revision 33253) @@ -0,0 +1,11 @@ +$class export +$short png/gif/jpg pcb_exporter +$long Export to png, gif and jpeg +$state works +$fmt-native no +$fmt-feature-w render in .png +$fmt-feature-w render in .gif +$fmt-feature-w render in .jpeg +$package export +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_png/png.c =================================================================== --- tags/2.3.0/src_plugins/export_png/png.c (nonexistent) +++ tags/2.3.0/src_plugins/export_png/png.c (revision 33253) @@ -0,0 +1,1452 @@ + /* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2006 Dan McMahill + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* + * Heavily based on the ps HID written by DJ Delorie + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "board.h" +#include +#include +#include "data.h" +#include "draw.h" +#include +#include "layer.h" +#include "layer_vis.h" +#include +#include +#include +#include +#include "funchash_core.h" + +#include +#include +#include "png.h" + +/* the gd library which makes this all so easy */ +#include + +#include +#include +#include "hid_cam.h" + +#define PNG_SCALE_HACK1 0 +#include +#define pcb_hack_round(d) rnd_round(d) + +#define CRASH(func) fprintf(stderr, "HID error: pcb called unimplemented PNG function %s.\n", func); abort() + +static rnd_hid_t png_hid; + +const char *png_cookie = "png HID"; + +static pcb_cam_t png_cam; + +static rnd_clrcache_t color_cache; +static int color_cache_inited = 0; +static htpp_t brush_cache; +static int brush_cache_inited = 0; + +static double bloat = 0; +static double scale = 1; +static rnd_coord_t x_shift = 0; +static rnd_coord_t y_shift = 0; +static int show_solder_side; +static long png_drawn_objs = 0; +#define SCALE(w) ((int)rnd_round((w)/scale)) +#define SCALE_X(x) ((int)pcb_hack_round(((x) - x_shift)/scale)) +#define SCALE_Y(y) ((int)pcb_hack_round(((show_solder_side ? (PCB->hidlib.size_y-(y)) : (y)) - y_shift)/scale)) +#define SWAP_IF_SOLDER(a,b) do { int c; if (show_solder_side) { c=a; a=b; b=c; }} while (0) + +/* Used to detect non-trivial outlines */ +#define NOT_EDGE_X(x) ((x) != 0 && (x) != PCB->hidlib.size_x) +#define NOT_EDGE_Y(y) ((y) != 0 && (y) != PCB->hidlib.size_y) +#define NOT_EDGE(x,y) (NOT_EDGE_X(x) || NOT_EDGE_Y(y)) + +static void png_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius); + +/* The result of a failed gdImageColorAllocate() call */ +#define BADC -1 + +typedef struct color_struct { + /* the descriptor used by the gd library */ + int c; + + /* so I can figure out what rgb value c refers to */ + unsigned int r, g, b, a; + +} color_struct; + +typedef struct rnd_hid_gc_s { + rnd_core_gc_t core_gc; + rnd_hid_t *me_pointer; + rnd_cap_style_t cap; + int width, r, g, b; + color_struct *color; + gdImagePtr brush; + int is_erase; +} hid_gc_t; + +static color_struct *black = NULL, *white = NULL; +static gdImagePtr im = NULL, master_im, comp_im = NULL, erase_im = NULL; +static FILE *f = 0; +static int linewidth = -1; +static int lastgroup = -1; +static gdImagePtr lastbrush = (gdImagePtr) ((void *) -1); +static int lastcap = -1; +static int last_color_r, last_color_g, last_color_b, last_cap; + +static int doing_outline, have_outline; + +#define FMT_gif "GIF" +#define FMT_jpg "JPEG" +#define FMT_png "PNG" + +/* If this table has no elements in it, then we have no reason to + register this HID and will refrain from doing so at the end of this + file. */ + +#undef HAVE_SOME_FORMAT + +static const char *filetypes[] = { +#ifdef RND_HAVE_GDIMAGEPNG + FMT_png, +#define HAVE_SOME_FORMAT 1 +#endif + +#ifdef RND_HAVE_GDIMAGEGIF + FMT_gif, +#define HAVE_SOME_FORMAT 1 +#endif + +#ifdef RND_HAVE_GDIMAGEJPEG + FMT_jpg, +#define HAVE_SOME_FORMAT 1 +#endif + + NULL +}; + +#include "png_photo1.c" + +rnd_export_opt_t png_attribute_list[] = { +/* other HIDs expect this to be first. */ + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --outfile +Name of the file to be exported to. Can contain a path. +@end ftable +%end-doc +*/ + {"outfile", "Graphics output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_pngfile 0 + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --dpi +Scale factor in pixels/inch. Set to 0 to scale to size specified in the layout. +@end ftable +%end-doc +*/ + {"dpi", "Scale factor (pixels/inch). 0 to scale to specified size", + RND_HATT_INTEGER, 0, 10000, {100, 0, 0}, 0, 0}, +#define HA_dpi 1 + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --x-max +Width of the png image in pixels. No constraint, when set to 0. +@end ftable +%end-doc +*/ + {"x-max", "Maximum width (pixels). 0 to not constrain", + RND_HATT_INTEGER, 0, 10000, {0, 0, 0}, 0, 0}, +#define HA_xmax 2 + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --y-max +Height of the png output in pixels. No constraint, when set to 0. +@end ftable +%end-doc +*/ + {"y-max", "Maximum height (pixels). 0 to not constrain", + RND_HATT_INTEGER, 0, 10000, {0, 0, 0}, 0, 0}, +#define HA_ymax 3 + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --xy-max +Maximum width and height of the PNG output in pixels. No constraint, when set to 0. +@end ftable +%end-doc +*/ + {"xy-max", "Maximum width and height (pixels). 0 to not constrain", + RND_HATT_INTEGER, 0, 10000, {0, 0, 0}, 0, 0}, +#define HA_xymax 4 + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --as-shown +Export layers as shown on screen. +@end ftable +%end-doc +*/ + {"as-shown", "Export layers as shown on screen", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_as_shown 5 + +/* %start-doc options "93 PNG Options" +@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, 0}, +#define HA_mono 6 + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --only-vivible +Limit the bounds of the exported PNG image to the visible items. +@end ftable +%end-doc +*/ + {"only-visible", "Limit the bounds of the PNG image to the visible items", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_only_visible 7 + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --use-alpha +Make the background and any holes transparent. +@end ftable +%end-doc +*/ + {"use-alpha", "Make the background and any holes transparent", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_use_alpha 8 + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --format +File format to be exported. Parameter @code{} can be @samp{PNG}, +@samp{GIF}, or @samp{JPEG}. +@end ftable +%end-doc +*/ + {"format", "Export file format", + RND_HATT_ENUM, 0, 0, {0, 0, 0}, filetypes, 0}, +#define HA_filetype 9 + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --png-bloat +Amount of extra thickness to add to traces, pads, or pin edges. The parameter +@samp{} is a number, appended by a dimension @samp{mm}, @samp{mil}, or +@samp{pix}. If no dimension is given, the default dimension is 1/100 mil. +OBSOLETE - do not use this feature! +@end ftable +%end-doc +*/ + {"png-bloat", "Amount (in/mm/mil/pix) to add to trace/pad/pin edges (1 = 1/100 mil) (OBSOLETE - do not use this feature!)", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_bloat 10 + +/* %start-doc options "93 PNG Options" +@ftable @code +@cindex photo-mode +@item --photo-mode +Export a photo realistic image of the layout. +@end ftable +%end-doc +*/ + {"photo-mode", "Photo-realistic export mode", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_photo_mode 11 + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --photo-flip-x +In photo-realistic mode, export the reverse side of the layout. Left-right flip. +@end ftable +%end-doc +*/ + {"photo-flip-x", "Show reverse side of the board, left-right flip", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_photo_flip_x 12 + +/* %start-doc options "93 PNG Options" +@ftable @code +@item --photo-flip-y +In photo-realistic mode, export the reverse side of the layout. Up-down flip. +@end ftable +%end-doc +*/ + {"photo-flip-y", "Show reverse side of the board, up-down flip", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_photo_flip_y 13 + +/* %start-doc options "93 PNG Options" +@ftable @code +@cindex photo-mask-colour +@item --photo-mask-colour +In photo-realistic mode, export the solder mask as this colour. Parameter +@code{} can be @samp{green}, @samp{red}, @samp{blue}, or @samp{purple}. +@end ftable +%end-doc +*/ + {"photo-mask-colour", "Colour for the exported colour mask (green, red, blue, purple)", + RND_HATT_ENUM, 0, 0, {0, 0, 0}, mask_colour_names, 0}, +#define HA_photo_mask_colour 14 + +/* %start-doc options "93 PNG Options" +@ftable @code +@cindex photo-plating +@item --photo-plating +In photo-realistic mode, export the exposed copper as though it has this type +of plating. Parameter @code{} can be @samp{tinned}, @samp{gold}, +@samp{silver}, or @samp{copper}. +@end ftable +%end-doc +*/ + {"photo-plating", "Type of plating applied to exposed copper in photo-mode (tinned, gold, silver, copper)", + RND_HATT_ENUM, 0, 0, {0, 0, 0}, plating_type_names, 0}, +#define HA_photo_plating 15 + +/* %start-doc options "93 PNG Options" +@ftable @code +@cindex photo-silk-colour +@item --photo-silk-colour +In photo-realistic mode, export the silk screen as this colour. Parameter +@code{} can be @samp{white}, @samp{black}, or @samp{yellow}. +@end ftable +%end-doc +*/ + {"photo-silk-colour", "Colour for the exported colour silk (white, black, yellow)", + RND_HATT_ENUM, 0, 0, {0, 0, 0}, silk_colour_names, 0}, +#define HA_photo_silk_colour 16 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 17 +}; + +#define NUM_OPTIONS (sizeof(png_attribute_list)/sizeof(png_attribute_list[0])) + +static rnd_hid_attr_val_t png_values[NUM_OPTIONS]; + +static const char *get_file_suffix(void) +{ + const char *result = NULL; + const char *fmt; + + fmt = filetypes[png_attribute_list[HA_filetype].default_val.lng]; + + if (fmt == NULL) { /* Do nothing */ } + else if (strcmp(fmt, FMT_gif) == 0) + result = ".gif"; + else if (strcmp(fmt, FMT_jpg) == 0) + result = ".jpg"; + else if (strcmp(fmt, FMT_png) == 0) + result = ".png"; + + if (result == NULL) { + fprintf(stderr, "Error: Invalid graphic file format\n"); + result = ".???"; + } + return result; +} + +static rnd_export_opt_t *png_get_export_options(rnd_hid_t *hid, int *n) +{ + const char *suffix = get_file_suffix(); + + if ((PCB != NULL) && (png_attribute_list[HA_pngfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &png_attribute_list[HA_pngfile], suffix); + + if (n) + *n = NUM_OPTIONS; + return png_attribute_list; +} + + +static rnd_layergrp_id_t group_for_layer(int l) +{ + if (l < pcb_max_layer(PCB) && l >= 0) + return pcb_layer_get_group(PCB, l); + /* else something unique */ + return pcb_max_group(PCB) + 3 + l; +} + +static int is_solder(rnd_layergrp_id_t grp) { return pcb_layergrp_flags(PCB, grp) & PCB_LYT_BOTTOM; } +static int is_component(rnd_layergrp_id_t grp) { return pcb_layergrp_flags(PCB, grp) & PCB_LYT_TOP; } + +static int layer_sort(const void *va, const void *vb) +{ + int a = *(int *) va; + int b = *(int *) vb; + rnd_layergrp_id_t al = group_for_layer(a); + rnd_layergrp_id_t bl = group_for_layer(b); + int d = bl - al; + + if (a >= 0 && a < pcb_max_layer(PCB)) { + int aside = (is_solder(al) ? 0 : is_component(al) ? 2 : 1); + int bside = (is_solder(bl) ? 0 : is_component(bl) ? 2 : 1); + + if (bside != aside) + return bside - aside; + } + if (d) + return d; + return b - a; +} + +static const char *filename; +static rnd_box_t *bounds; +static int in_mono, as_shown; + +static void parse_bloat(const char *str) +{ + int n; + rnd_unit_list_t extra_units = { + {"pix", 0, 0}, + {"px", 0, 0}, + {"", 0, 0} + }; + for(n = 0; n < (sizeof(extra_units)/sizeof(extra_units[0]))-1; n++) + extra_units[n].scale = scale; + if (str == NULL) + return; + bloat = rnd_get_value_ex(str, NULL, NULL, extra_units, "", NULL); +} + +static void rgb(color_struct *dest, int r, int g, int b) +{ + dest->r = r; + dest->g = g; + dest->b = b; +} + +static rnd_hid_attr_val_t *png_options; + +#include "png_photo2.c" + +static void png_head(void) +{ + linewidth = -1; + lastbrush = (gdImagePtr) ((void *) -1); + lastcap = -1; + lastgroup = -1; + png_photo_head(); + show_solder_side = conf_core.editor.show_solder_side; + last_color_r = last_color_g = last_color_b = last_cap = -1; + + gdImageFilledRectangle(im, 0, 0, gdImageSX(im), gdImageSY(im), white->c); +} + +static void png_foot(void) +{ + const char *fmt; + rnd_bool format_error = rnd_false; + + if (photo_mode) + png_photo_foot(); + + /* actually write out the image */ + fmt = filetypes[png_options[HA_filetype].lng]; + + if (fmt == NULL) + format_error = rnd_true; + else if (strcmp(fmt, FMT_gif) == 0) +#ifdef RND_HAVE_GDIMAGEGIF + gdImageGif(im, f); +#else + format_error = rnd_true; +#endif + else if (strcmp(fmt, FMT_jpg) == 0) +#ifdef RND_HAVE_GDIMAGEJPEG + gdImageJpeg(im, f, -1); +#else + format_error = rnd_true; +#endif + else if (strcmp(fmt, FMT_png) == 0) +#ifdef RND_HAVE_GDIMAGEPNG + gdImagePng(im, f); +#else + format_error = rnd_true; +#endif + else + format_error = rnd_true; + + if (format_error) + fprintf(stderr, "Error: Invalid graphic file format." " This is a bug. Please report it.\n"); +} + +void png_hid_export_to_file(FILE *the_file, rnd_hid_attr_val_t *options, rnd_xform_t *xform) +{ + static int saved_layer_stack[PCB_MAX_LAYER]; + rnd_box_t tmp, region; + rnd_hid_expose_ctx_t ctx; + + f = the_file; + + region.X1 = 0; + region.Y1 = 0; + region.X2 = PCB->hidlib.size_x; + region.Y2 = PCB->hidlib.size_y; + + png_options = options; + if (options[HA_only_visible].lng) + bounds = pcb_data_bbox(&tmp, PCB->Data, rnd_false); + else + bounds = ®ion; + + memcpy(saved_layer_stack, pcb_layer_stack, sizeof(pcb_layer_stack)); + + as_shown = options[HA_as_shown].lng; + if (options[HA_as_shown].lng) + pcb_draw_setup_default_gui_xform(xform); + if (!options[HA_as_shown].lng) { + rnd_conf_force_set_bool(conf_core.editor.show_solder_side, 0); + + qsort(pcb_layer_stack, pcb_max_layer(PCB), sizeof(pcb_layer_stack[0]), layer_sort); + + if (photo_mode) + png_photo_as_shown(); + } + + in_mono = options[HA_mono].lng; + png_head(); + + if (!photo_mode && conf_core.editor.show_solder_side) { + int i, j; + for (i = 0, j = pcb_max_layer(PCB) - 1; i < j; i++, j--) { + int k = pcb_layer_stack[i]; + pcb_layer_stack[i] = pcb_layer_stack[j]; + pcb_layer_stack[j] = k; + } + } + + if (as_shown) { + /* disable (exporter default) hiding overlay in as_shown */ + xform->omit_overlay = 0; + } + + ctx.view = *bounds; + rnd_expose_main(&png_hid, &ctx, xform); + + memcpy(pcb_layer_stack, saved_layer_stack, sizeof(pcb_layer_stack)); + rnd_conf_update(NULL, -1); /* restore forced sets */ +} + + +static void png_free_cache(void) +{ + if (color_cache_inited) { + rnd_clrcache_uninit(&color_cache); + color_cache_inited = 0; + } + if (brush_cache_inited) { + htpp_entry_t *e; + for(e = htpp_first(&brush_cache); e != NULL; e = htpp_next(&brush_cache, e)) + gdImageDestroy(e->value); + htpp_uninit(&brush_cache); + brush_cache_inited = 0; + } +} + +static void png_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + int save_ons[PCB_MAX_LAYER]; + int i; + rnd_box_t tmp, *bbox; + int w, h; + int xmax, ymax, dpi; + rnd_xform_t xform; + + png_free_cache(); + + if (!options) { + png_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + png_values[i] = png_attribute_list[i].default_val; + options = png_values; + } + + png_drawn_objs = 0; + pcb_cam_begin(PCB, &png_cam, &xform, options[HA_cam].str, png_attribute_list, NUM_OPTIONS, options); + + if (options[HA_photo_mode].lng) { + photo_mode = 1; + png_photo_do_export(options); + } + else + photo_mode = 0; + + filename = options[HA_pngfile].str; + if (!filename) + filename = "pcb-out.png"; + + /* figure out width and height of the board */ + if (options[HA_only_visible].lng) { + bbox = pcb_data_bbox(&tmp, PCB->Data, rnd_false); + x_shift = bbox->X1; + y_shift = bbox->Y1; + h = bbox->Y2 - bbox->Y1; + w = bbox->X2 - bbox->X1; + } + else { + x_shift = 0; + y_shift = 0; + h = PCB->hidlib.size_y; + w = PCB->hidlib.size_x; + } + + /* figure out the scale factor to fit in the specified PNG file size */ + xmax = ymax = dpi = 0; + if (options[HA_dpi].lng != 0) { + dpi = options[HA_dpi].lng; + if (dpi < 0) { + fprintf(stderr, "ERROR: dpi may not be < 0\n"); + return; + } + } + + if (options[HA_xmax].lng > 0) { + xmax = options[HA_xmax].lng; + dpi = 0; + } + + if (options[HA_ymax].lng > 0) { + ymax = options[HA_ymax].lng; + dpi = 0; + } + + if (options[HA_xymax].lng > 0) { + dpi = 0; + if (options[HA_xymax].lng < xmax || xmax == 0) + xmax = options[HA_xymax].lng; + if (options[HA_xymax].lng < ymax || ymax == 0) + ymax = options[HA_xymax].lng; + } + + if (xmax < 0 || ymax < 0) { + fprintf(stderr, "ERROR: xmax and ymax may not be < 0\n"); + return; + } + + if (dpi > 0) { + /* a scale of 1 means 1 pixel is 1 inch + a scale of 10 means 1 pixel is 10 inches */ + scale = RND_INCH_TO_COORD(1) / dpi; + w = rnd_round(w / scale) - PNG_SCALE_HACK1; + h = rnd_round(h / scale) - PNG_SCALE_HACK1; + } + else if (xmax == 0 && ymax == 0) { + fprintf(stderr, "ERROR: You may not set both xmax, ymax," "and xy-max to zero\n"); + return; + } + else { + if (ymax == 0 || ((xmax > 0) + && ((w / xmax) > (h / ymax)))) { + h = (h * xmax) / w; + scale = w / xmax; + w = xmax; + } + else { + w = (w * ymax) / h; + scale = h / ymax; + h = ymax; + } + } + + im = gdImageCreate(w, h); + if (im == NULL) { + rnd_message(RND_MSG_ERROR, "png_do_export(): gdImageCreate(%d, %d) returned NULL. Aborting export.\n", w, h); + return; + } + +#ifdef RND_HAVE_GD_RESOLUTION + gdImageSetResolution(im, dpi, dpi); +#endif + + master_im = im; + + parse_bloat(options[HA_bloat].str); + + /* Allocate white and black; the first color allocated becomes the background color */ + white = (color_struct *) malloc(sizeof(color_struct)); + white->r = white->g = white->b = 255; + if (options[HA_use_alpha].lng) + white->a = 127; + else + white->a = 0; + white->c = gdImageColorAllocateAlpha(im, white->r, white->g, white->b, white->a); + if (white->c == BADC) { + rnd_message(RND_MSG_ERROR, "png_do_export(): gdImageColorAllocateAlpha() returned NULL. Aborting export.\n"); + return; + } + + + black = (color_struct *) malloc(sizeof(color_struct)); + black->r = black->g = black->b = black->a = 0; + black->c = gdImageColorAllocate(im, black->r, black->g, black->b); + if (black->c == BADC) { + rnd_message(RND_MSG_ERROR, "png_do_export(): gdImageColorAllocateAlpha() returned NULL. Aborting export.\n"); + return; + } + + if (!png_cam.fn_template) { + f = rnd_fopen_askovr(&PCB->hidlib, png_cam.active ? png_cam.fn : filename, "wb", NULL); + if (!f) { + perror(filename); + return; + } + } + else + f = NULL; + + png_hid.force_compositing = !!photo_mode; + + if ((!png_cam.active) && (!options[HA_as_shown].lng)) + pcb_hid_save_and_show_layer_ons(save_ons); + + png_hid_export_to_file(f, options, &xform); + + if ((!png_cam.active) && (!options[HA_as_shown].lng)) + pcb_hid_restore_layer_ons(save_ons); + + png_foot(); + if (f != NULL) + fclose(f); + + if (master_im != NULL) { + gdImageDestroy(master_im); + master_im = NULL; + } + if (comp_im != NULL) { + gdImageDestroy(comp_im); + comp_im = NULL; + } + if (erase_im != NULL) { + gdImageDestroy(erase_im); + erase_im = NULL; + } + + png_photo_post_export(); + png_free_cache(); + free(white); + free(black); + + if (!png_cam.active) png_cam.okempty_content = 1; /* never warn in direct export */ + + if (pcb_cam_end(&png_cam) == 0) { + if (!png_cam.okempty_group) + rnd_message(RND_MSG_ERROR, "png cam export for '%s' failed to produce any content (layer group missing)\n", options[HA_cam].str); + } + else if (png_drawn_objs == 0) { + if (!png_cam.okempty_content) + rnd_message(RND_MSG_ERROR, "png cam export for '%s' failed to produce any content (no objects)\n", options[HA_cam].str); + } +} + +static int png_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(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 is_mask; + +static int png_set_layer_group(rnd_hid_t *hid, 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 (flags & PCB_LYT_UI) + return 0; + + pcb_cam_set_layer_group(&png_cam, group, purpose, purpi, flags, xform); + if (png_cam.fn_changed) { + if (f != NULL) { + png_foot(); + fclose(f); + } + f = rnd_fopen_askovr(&PCB->hidlib, png_cam.fn, "wb", NULL); + if (!f) { + perror(filename); + return 0; + } + png_head(); + } + + if (!png_cam.active) { + if (flags & PCB_LYT_NOEXPORT) + return 0; + + if (PCB_LAYER_IS_ASSY(flags, purpi) || PCB_LAYER_IS_FAB(flags, purpi) || (flags & PCB_LYT_PASTE) || (flags & PCB_LYT_INVIS) || PCB_LAYER_IS_CSECT(flags, purpi)) + return 0; + } + + is_mask = (flags & PCB_LYT_MASK); + + if (photo_mode) + return png_set_layer_group_photo(group, purpose, purpi, layer, flags, is_empty, xform); + + if (as_shown) { + if ((flags & PCB_LYT_ANYTHING) == PCB_LYT_SILK) { + if (PCB_LAYERFLG_ON_VISIBLE_SIDE(flags)) + return pcb_silk_on(PCB); + return 0; + } + + if ((flags & PCB_LYT_ANYTHING) == PCB_LYT_MASK) + return PCB->LayerGroups.grp[group].vis && PCB_LAYERFLG_ON_VISIBLE_SIDE(flags); + } + else { + if (is_mask) + return 0; + + if ((flags & PCB_LYT_ANYTHING) == PCB_LYT_SILK) + return !!(flags & PCB_LYT_TOP); + } + + return 1; +} + + +static rnd_hid_gc_t png_make_gc(rnd_hid_t *hid) +{ + rnd_hid_gc_t rv = (rnd_hid_gc_t) calloc(sizeof(hid_gc_t), 1); + rv->me_pointer = &png_hid; + rv->cap = rnd_cap_round; + rv->width = 1; + rv->color = (color_struct *) malloc(sizeof(color_struct)); + rv->color->r = rv->color->g = rv->color->b = rv->color->a = 0; + rv->color->c = 0; + rv->is_erase = 0; + return rv; +} + +static void png_destroy_gc(rnd_hid_gc_t gc) +{ + free(gc); +} + +static rnd_composite_op_t drawing_mode; +static void png_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + static gdImagePtr dst_im; + drawing_mode = op; + if ((direct) || (is_photo_drill)) /* photo drill is a special layer, no copositing on that */ + return; + switch(op) { + case RND_HID_COMP_RESET: + + /* the main pixel buffer; drawn with color */ + if (comp_im == NULL) { + comp_im = gdImageCreate(gdImageSX(im), gdImageSY(im)); + if (!comp_im) { + rnd_message(RND_MSG_ERROR, "png_set_drawing_mode(): gdImageCreate(%d, %d) returned NULL on comp_im. Corrupt export!\n", gdImageSY(im), gdImageSY(im)); + return; + } + } + + /* erase mask: for composite layers, tells whether the color pixel + should be combined back to the master image; white means combine back, + anything else means cut-out/forget/ignore that pixel */ + if (erase_im == NULL) { + erase_im = gdImageCreate(gdImageSX(im), gdImageSY(im)); + if (!erase_im) { + rnd_message(RND_MSG_ERROR, "png_set_drawing_mode(): gdImageCreate(%d, %d) returned NULL on erase_im. Corrupt export!\n", gdImageSY(im), gdImageSY(im)); + return; + } + } + gdImagePaletteCopy(comp_im, im); + dst_im = im; + gdImageFilledRectangle(comp_im, 0, 0, gdImageSX(comp_im), gdImageSY(comp_im), white->c); + + gdImagePaletteCopy(erase_im, im); + gdImageFilledRectangle(erase_im, 0, 0, gdImageSX(erase_im), gdImageSY(erase_im), black->c); + break; + + case RND_HID_COMP_POSITIVE: + case RND_HID_COMP_POSITIVE_XOR: + im = comp_im; + break; + case RND_HID_COMP_NEGATIVE: + im = erase_im; + break; + + case RND_HID_COMP_FLUSH: + { + int x, y, c, e; + im = dst_im; + gdImagePaletteCopy(im, comp_im); + for (x = 0; x < gdImageSX(im); x++) { + for (y = 0; y < gdImageSY(im); y++) { + e = gdImageGetPixel(erase_im, x, y); + c = gdImageGetPixel(comp_im, x, y); + if ((e == white->c) && (c)) + gdImageSetPixel(im, x, y, c); + } + } + break; + } + } +} + +static void png_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + color_struct *cc; + + if (im == NULL) + return; + + if (color == NULL) + color = rnd_color_red; + + if (rnd_color_is_drill(color)) { + gc->color = white; + gc->is_erase = 1; + return; + } + gc->is_erase = 0; + + if (in_mono || (color->packed == 0)) { + gc->color = black; + return; + } + + if (!color_cache_inited) { + rnd_clrcache_init(&color_cache, sizeof(color_struct), NULL); + color_cache_inited = 1; + } + + if ((cc = rnd_clrcache_get(&color_cache, color, 0)) != NULL) { + gc->color = cc; + } + else if (color->str[0] == '#') { + cc = rnd_clrcache_get(&color_cache, color, 1); + gc->color = cc; + gc->color->r = color->r; + gc->color->g = color->g; + gc->color->b = color->b; + gc->color->c = gdImageColorAllocate(im, gc->color->r, gc->color->g, gc->color->b); + if (gc->color->c == BADC) { + rnd_message(RND_MSG_ERROR, "png_set_color(): gdImageColorAllocate() returned NULL. Aborting export.\n"); + return; + } + } + else { + fprintf(stderr, "WE SHOULD NOT BE HERE!!!\n"); + gc->color = black; + } +} + +static void png_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + gc->cap = style; +} + +static void png_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + gc->width = width; +} + +static void png_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ + ; +} + +static unsigned brush_hash(const void *kv) +{ + const hid_gc_t *k = kv; + return ((((unsigned)k->r) << 24) | (((unsigned)k->g) << 16) | (((unsigned)k->b) << 8) | k->cap) + (unsigned)k->width; +} + +static int brush_keyeq(const void *av, const void *bv) +{ + const hid_gc_t *a = av, *b = bv; + if (a->cap != b->cap) return 0; + if (a->width != b->width) return 0; + if (a->r != b->r) return 0; + if (a->g != b->g) return 0; + if (a->b != b->b) return 0; + return 1; +} + +static int unerase_override = 0; +static void use_gc(gdImagePtr im, rnd_hid_gc_t gc) +{ + int need_brush = 0; + rnd_hid_gc_t agc; + gdImagePtr brp; + + png_drawn_objs++; + + agc = gc; + if (unerase_override) { + agc->r = -1; + agc->g = -1; + agc->b = -1; + } + else { + agc->r = gc->color->r; + agc->g = gc->color->g; + agc->b = gc->color->b; + } + + if (agc->me_pointer != &png_hid) { + fprintf(stderr, "Fatal: GC from another HID passed to png HID\n"); + abort(); + } + + if (linewidth != agc->width) { + /* Make sure the scaling doesn't erase lines completely */ + if (SCALE(agc->width) == 0 && agc->width > 0) + gdImageSetThickness(im, 1); + else + gdImageSetThickness(im, SCALE(agc->width + 2 * bloat)); + linewidth = agc->width; + need_brush = 1; + } + + need_brush |= (agc->r != last_color_r) || (agc->g != last_color_g) || (agc->b != last_color_b) || (agc->cap != last_cap); + + if (lastbrush != agc->brush || need_brush) { + int r; + + if (agc->width) + r = SCALE(agc->width + 2 * bloat); + else + r = 1; + + /* do not allow a brush size that is zero width. In this case limit to a single pixel. */ + if (r == 0) + r = 1; + + last_color_r = agc->r; + last_color_g = agc->g; + last_color_b = agc->b; + last_cap = agc->cap; + + if (!brush_cache_inited) { + htpp_init(&brush_cache, brush_hash, brush_keyeq); + brush_cache_inited = 1; + } + + if ((brp = htpp_get(&brush_cache, agc)) != NULL) { + agc->brush = brp; + } + else { + int bg, fg; + agc->brush = gdImageCreate(r, r); + if (agc->brush == NULL) { + rnd_message(RND_MSG_ERROR, "use_gc(): gdImageCreate(%d, %d) returned NULL. Aborting export.\n", r, r); + return; + } + + bg = gdImageColorAllocate(agc->brush, 255, 255, 255); + if (bg == BADC) { + rnd_message(RND_MSG_ERROR, "use_gc(): gdImageColorAllocate() returned NULL. Aborting export.\n"); + return; + } + if (unerase_override) + fg = gdImageColorAllocateAlpha(agc->brush, 255, 255, 255, 0); + else + fg = gdImageColorAllocateAlpha(agc->brush, agc->r, agc->g, agc->b, 0); + if (fg == BADC) { + rnd_message(RND_MSG_ERROR, "use_gc(): gdImageColorAllocate() returned NULL. Aborting export.\n"); + return; + } + gdImageColorTransparent(agc->brush, bg); + + /* if we shrunk to a radius/box width of zero, then just use + a single pixel to draw with. */ + if (r <= 1) + gdImageFilledRectangle(agc->brush, 0, 0, 0, 0, fg); + else { + if (agc->cap != rnd_cap_square) { + gdImageFilledEllipse(agc->brush, r / 2, r / 2, r, r, fg); + /* Make sure the ellipse is the right exact size. */ + gdImageSetPixel(agc->brush, 0, r / 2, fg); + gdImageSetPixel(agc->brush, r - 1, r / 2, fg); + gdImageSetPixel(agc->brush, r / 2, 0, fg); + gdImageSetPixel(agc->brush, r / 2, r - 1, fg); + } + else + gdImageFilledRectangle(agc->brush, 0, 0, r - 1, r - 1, fg); + } + brp = agc->brush; + htpp_set(&brush_cache, agc, brp); + } + + gdImageSetBrush(im, agc->brush); + lastbrush = agc->brush; + + } +} + + +static void png_fill_rect_(gdImagePtr im, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + use_gc(im, gc); + gdImageSetThickness(im, 0); + linewidth = 0; + + if (x1 > x2) { + rnd_coord_t t = x1; + x2 = x2; + x2 = t; + } + if (y1 > y2) { + rnd_coord_t t = y1; + y2 = y2; + y2 = t; + } + y1 -= bloat; + y2 += bloat; + SWAP_IF_SOLDER(y1, y2); + + gdImageFilledRectangle(im, SCALE_X(x1 - bloat), SCALE_Y(y1), SCALE_X(x2 + bloat) - 1, SCALE_Y(y2) - 1, unerase_override ? white->c : gc->color->c); + have_outline |= doing_outline; +} + +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) +{ + png_fill_rect_(im, gc, x1, y1, x2, y2); + if ((im != erase_im) && (erase_im != NULL)) { + unerase_override = 1; + png_fill_rect_(erase_im, gc, x1, y1, x2, y2); + unerase_override = 0; + } +} + + +static void png_draw_line_(gdImagePtr im, rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + int x1o = 0, y1o = 0, x2o = 0, y2o = 0; + if (x1 == x2 && y1 == y2 && !photo_mode) { + rnd_coord_t w = gc->width / 2; + if (gc->cap != rnd_cap_square) + png_fill_circle(gc, x1, y1, w); + else + png_fill_rect(gc, x1 - w, y1 - w, x1 + w, y1 + w); + return; + } + use_gc(im, gc); + + if (NOT_EDGE(x1, y1) || NOT_EDGE(x2, y2)) + have_outline |= doing_outline; + + /* libgd clipping bug - lines drawn along the bottom or right edges + need to be brought in by a pixel to make sure they are not clipped + by libgd - even tho they should be visible because of thickness, they + would not be because the center line is off the image */ + if (x1 == PCB->hidlib.size_x && x2 == PCB->hidlib.size_x) { + x1o = -1; + x2o = -1; + } + if (y1 == PCB->hidlib.size_y && y2 == PCB->hidlib.size_y) { + y1o = -1; + y2o = -1; + } + + gdImageSetThickness(im, 0); + linewidth = 0; + if (gc->cap != rnd_cap_square || x1 == x2 || y1 == y2) { + gdImageLine(im, SCALE_X(x1) + x1o, SCALE_Y(y1) + y1o, SCALE_X(x2) + x2o, SCALE_Y(y2) + y2o, gdBrushed); + } + else { + /* if we are drawing a line with a square end cap and it is + not purely horizontal or vertical, then we need to draw + it as a filled polygon. */ + int fg, w = gc->width, dx = x2 - x1, dy = y2 - y1, dwx, dwy; + gdPoint p[4]; + double l = sqrt((double)dx * (double)dx + (double)dy * (double)dy) * 2.0; + + if (unerase_override) + fg = gdImageColorResolve(im, 255, 255, 255); + else + fg = gdImageColorResolve(im, gc->color->r, gc->color->g, gc->color->b); + + w += 2 * bloat; + dwx = -w / l * dy; + dwy = w / l * dx; + p[0].x = SCALE_X(x1 + dwx - dwy); + p[0].y = SCALE_Y(y1 + dwy + dwx); + p[1].x = SCALE_X(x1 - dwx - dwy); + p[1].y = SCALE_Y(y1 - dwy + dwx); + p[2].x = SCALE_X(x2 - dwx + dwy); + p[2].y = SCALE_Y(y2 - dwy - dwx); + p[3].x = SCALE_X(x2 + dwx + dwy); + p[3].y = SCALE_Y(y2 + dwy - dwx); + gdImageFilledPolygon(im, p, 4, fg); + } +} + +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) +{ + png_draw_line_(im, gc, x1, y1, x2, y2); + if ((im != erase_im) && (erase_im != NULL)) { + unerase_override = 1; + png_draw_line_(erase_im, gc, x1, y1, x2, y2); + unerase_override = 0; + } +} + +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_(gdImagePtr im, 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_angle_t sa, ea; + + use_gc(im, gc); + gdImageSetThickness(im, 0); + linewidth = 0; + + /* zero angle arcs need special handling as gd will output either + nothing at all or a full circle when passed delta angle of 0 or 360. */ + if (delta_angle == 0) { + rnd_coord_t x = (width * cos(start_angle * M_PI / 180)); + rnd_coord_t y = (width * sin(start_angle * M_PI / 180)); + x = cx - x; + y = cy + y; + png_fill_circle(gc, x, y, gc->width / 2); + return; + } + + if ((delta_angle >= 360) || (delta_angle <= -360)) { + /* save some expensive calculations if we are going to draw a full circle anyway */ + sa = 0; + ea = 360; + } + else { + /* in gdImageArc, 0 degrees is to the right and +90 degrees is down + in pcb, 0 degrees is to the left and +90 degrees is down */ + start_angle = 180 - start_angle; + delta_angle = -delta_angle; + if (show_solder_side) { + start_angle = -start_angle; + delta_angle = -delta_angle; + } + if (delta_angle > 0) { + sa = start_angle; + ea = start_angle + delta_angle; + } + else { + sa = start_angle + delta_angle; + ea = start_angle; + } + + /* make sure we start between 0 and 360 otherwise gd does + strange things */ + sa = rnd_normalize_angle(sa); + ea = rnd_normalize_angle(ea); + } + + have_outline |= doing_outline; + +#if 0 + printf("draw_arc %d,%d %dx%d %d..%d %d..%d\n", cx, cy, width, height, start_angle, delta_angle, sa, ea); + printf("gdImageArc (%p, %d, %d, %d, %d, %d, %d, %d)\n", + (void *)im, SCALE_X(cx), SCALE_Y(cy), SCALE(width), SCALE(height), sa, ea, gc->color->c); +#endif + gdImageArc(im, SCALE_X(cx), SCALE_Y(cy), SCALE(2 * width), SCALE(2 * height), sa, ea, gdBrushed); +} + +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) +{ + png_draw_arc_(im, gc, cx, cy, width, height, start_angle, delta_angle); + if ((im != erase_im) && (erase_im != NULL)) { + unerase_override = 1; + png_draw_arc_(erase_im, gc, cx, cy, width, height, start_angle, delta_angle); + unerase_override = 0; + } +} + +static void png_fill_circle_(gdImagePtr im, rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + rnd_coord_t my_bloat; + + use_gc(im, gc); + + if (gc->is_erase) + my_bloat = -2 * bloat; + else + my_bloat = 2 * bloat; + + have_outline |= doing_outline; + + gdImageSetThickness(im, 0); + linewidth = 0; + gdImageFilledEllipse(im, SCALE_X(cx), SCALE_Y(cy), SCALE(2 * radius + my_bloat), SCALE(2 * radius + my_bloat), unerase_override ? white->c : gc->color->c); +} + +static void png_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + png_fill_circle_(im, gc, cx, cy, radius); + if ((im != erase_im) && (erase_im != NULL)) { + unerase_override = 1; + png_fill_circle_(erase_im, gc, cx, cy, radius); + unerase_override = 0; + } +} + + +static void png_fill_polygon_offs_(gdImagePtr im, rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t dx, rnd_coord_t dy) +{ + int i; + gdPoint *points; + + points = (gdPoint *) malloc(n_coords * sizeof(gdPoint)); + if (points == NULL) { + fprintf(stderr, "ERROR: png_fill_polygon(): malloc failed\n"); + exit(1); + } + + use_gc(im, gc); + for (i = 0; i < n_coords; i++) { + if (NOT_EDGE(x[i], y[i])) + have_outline |= doing_outline; + points[i].x = SCALE_X(x[i]+dx); + points[i].y = SCALE_Y(y[i]+dy); + } + gdImageSetThickness(im, 0); + linewidth = 0; + gdImageFilledPolygon(im, points, n_coords, unerase_override ? white->c : gc->color->c); + free(points); +} + +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) +{ + png_fill_polygon_offs_(im, gc, n_coords, x, y, dx, dy); + if ((im != erase_im) && (erase_im != NULL)) { + unerase_override = 1; + png_fill_polygon_offs_(erase_im, gc, n_coords, x, y, dx, dy); + unerase_override = 0; + } +} + + +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); +} + + +static void png_calibrate(rnd_hid_t *hid, double xval, double yval) +{ + CRASH("png_calibrate"); +} + +static void png_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int a) +{ +} + +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: pcb-rnd [generic_options] -x png [png options] foo.pcb\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); +#ifdef HAVE_SOME_FORMAT + rnd_hid_remove_hid(&png_hid); +#endif +} + +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 = png_make_gc; + png_hid.destroy_gc = png_destroy_gc; + png_hid.set_drawing_mode = png_set_drawing_mode; + png_hid.set_color = png_set_color; + png_hid.set_line_cap = png_set_line_cap; + png_hid.set_line_width = png_set_line_width; + png_hid.set_draw_xor = png_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.calibrate = png_calibrate; + png_hid.set_crosshair = png_set_crosshair; + + png_hid.usage = png_usage; + +#ifdef HAVE_SOME_FORMAT + rnd_hid_register_hid(&png_hid); +#endif + return 0; +} Index: tags/2.3.0/src_plugins/export_png/png.h =================================================================== --- tags/2.3.0/src_plugins/export_png/png.h (nonexistent) +++ tags/2.3.0/src_plugins/export_png/png.h (revision 33253) @@ -0,0 +1,2 @@ +extern const char *png_cookie; +extern void png_hid_export_to_file(FILE *, rnd_hid_attr_val_t *, rnd_xform_t *); Index: tags/2.3.0/src_plugins/export_png/png_photo1.c =================================================================== --- tags/2.3.0/src_plugins/export_png/png_photo1.c (nonexistent) +++ tags/2.3.0/src_plugins/export_png/png_photo1.c (revision 33253) @@ -0,0 +1,121 @@ + /* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2006 Dan McMahill + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#define PHOTO_FLIP_X 1 +#define PHOTO_FLIP_Y 2 + +static int photo_mode, photo_flip; +static gdImagePtr photo_copper[PCB_MAX_LAYER]; +static gdImagePtr photo_silk, photo_mask, photo_drill, *photo_im; +static gdImagePtr photo_outline; +static int photo_groups[PCB_MAX_LAYERGRP + 2], photo_ngroups; +static int photo_has_inners; +static rnd_layergrp_id_t photo_last_grp; +static int is_photo_drill; + +static const char *mask_colour_names[] = { + "green", + "red", + "blue", + "purple", + "black", + "white", + NULL +}; + +/* These values were arrived at through trial and error. + One potential improvement (especially for white) is + to use separate color_structs for the multiplication + and addition parts of the mask math. + */ +static const color_struct mask_colours[] = { +#define MASK_COLOUR_GREEN 0 + {0x3CA03CFF, 60, 160, 60, 255}, +#define MASK_COLOUR_RED 1 + {0x8C1919FF, 140, 25, 25, 255}, +#define MASK_COLOUR_BLUE 2 + {0x3232A0FF, 50, 50, 160, 255}, +#define MASK_COLOUR_PURPLE 3 + {0x3C1446FF, 60, 20, 70, 255}, +#define MASK_COLOUR_BLACK 4 + {0x141414FF, 20, 20, 20, 255}, +#define MASK_COLOUR_WHITE 5 + {0xA7E6A2FF, 167, 230, 162, 255} /* <-- needs improvement over FR4 */ +}; + +static const char *plating_type_names[] = { +#define PLATING_TIN 0 + "tinned", +#define PLATING_GOLD 1 + "gold", +#define PLATING_SILVER 2 + "silver", +#define PLATING_COPPER 3 + "copper", + NULL +}; + +static const char *silk_colour_names[] = { + "white", + "black", + "yellow", + NULL +}; + +static const color_struct silk_colours[] = { +#define SILK_COLOUR_WHITE 0 + {0xE0E0E0FF, 224, 224, 224, 255}, +#define SILK_COLOUR_BLACK 1 + {0x0E0E0EFF, 14, 14, 14, 255}, +#define SILK_COLOUR_YELLOW 2 + {0xB9B90AFF, 185, 185, 10, 255} +}; + +static const color_struct silk_top_shadow = {0x151515FF, 21, 21, 21, 255}; +static const color_struct silk_bottom_shadow = {0x0E0E0EFF, 14, 14, 14, 255}; + +static int smshadows[3][3] = { + {1, 0, -1}, + {0, 0, -1}, + {-1, -1, -1}, +}; + +static int shadows[5][5] = { + {1, 1, 0, 0, -1}, + {1, 1, 1, -1, 0}, + {0, 1, 0, -1, 0}, + {0, -1, -1, -1, 0}, + {-1, 0, 0, 0, -1}, +}; + +/* black and white are 0 and 1 */ +#define TOP_SHADOW 2 +#define BOTTOM_SHADOW 3 + +static void png_photo_as_shown(); + Index: tags/2.3.0/src_plugins/export_png/png_photo2.c =================================================================== --- tags/2.3.0/src_plugins/export_png/png_photo2.c (nonexistent) +++ tags/2.3.0/src_plugins/export_png/png_photo2.c (revision 33253) @@ -0,0 +1,460 @@ + /* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2006 Dan McMahill + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* + * Heavily based on the ps HID written by DJ Delorie + */ + + +/* For photo-mode we need the following layers as monochrome masks: + + top soldermask + top silk + copper layers + drill +*/ + +static void ts_bs(gdImagePtr im) +{ + int x, y, sx, sy, si; + for (x = 0; x < gdImageSX(im); x++) + for (y = 0; y < gdImageSY(im); y++) { + si = 0; + for (sx = -2; sx < 3; sx++) + for (sy = -2; sy < 3; sy++) + if (!gdImageGetPixel(im, x + sx, y + sy)) + si += shadows[sx + 2][sy + 2]; + if (gdImageGetPixel(im, x, y)) { + if (si > 1) + gdImageSetPixel(im, x, y, TOP_SHADOW); + else if (si < -1) + gdImageSetPixel(im, x, y, BOTTOM_SHADOW); + } + } +} + +static void ts_bs_sm(gdImagePtr im) +{ + int x, y, sx, sy, si; + for (x = 0; x < gdImageSX(im); x++) + for (y = 0; y < gdImageSY(im); y++) { + si = 0; + for (sx = -1; sx < 2; sx++) + for (sy = -1; sy < 2; sy++) + if (!gdImageGetPixel(im, x + sx, y + sy)) + si += smshadows[sx + 1][sy + 1]; + if (gdImageGetPixel(im, x, y)) { + if (si > 1) + gdImageSetPixel(im, x, y, TOP_SHADOW); + else if (si < -1) + gdImageSetPixel(im, x, y, BOTTOM_SHADOW); + } + } +} + +static void clip(color_struct * dest, color_struct * source) +{ +#define CLIP(var) \ + dest->var = source->var; \ + if (dest->var > 255) dest->var = 255; \ + if (dest->var < 0) dest->var = 0; + + CLIP(r); + CLIP(g); + CLIP(b); +#undef CLIP +} + +static void blend(color_struct * dest, float a_amount, color_struct * a, color_struct * b) +{ + dest->r = a->r * a_amount + b->r * (1 - a_amount); + dest->g = a->g * a_amount + b->g * (1 - a_amount); + dest->b = a->b * a_amount + b->b * (1 - a_amount); +} + +static void multiply(color_struct * dest, color_struct * a, color_struct * b) +{ + dest->r = (a->r * b->r) / 255; + dest->g = (a->g * b->g) / 255; + dest->b = (a->b * b->b) / 255; +} + +static void add(color_struct * dest, double a_amount, const color_struct * a, double b_amount, const color_struct * b) +{ + dest->r = a->r * a_amount + b->r * b_amount; + dest->g = a->g * a_amount + b->g * b_amount; + dest->b = a->b * a_amount + b->b * b_amount; + + clip(dest, dest); +} + +static void subtract(color_struct * dest, double a_amount, const color_struct * a, double b_amount, const color_struct * b) +{ + dest->r = a->r * a_amount - b->r * b_amount; + dest->g = a->g * a_amount - b->g * b_amount; + dest->b = a->b * a_amount - b->b * b_amount; + + clip(dest, dest); +} + +static int png_set_layer_group_photo(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) +{ + /* workaround: the outline layer vs. alpha breaks if set twice and the draw + code may set it twice (if there's no mech layer), but always in a row */ + if (group == photo_last_grp) + return 1; + photo_last_grp = group; + + if (PCB_LAYER_IS_OUTLINE(flags, purpi)) { + doing_outline = 1; + have_outline = 0; + } + else + doing_outline = 0; + + is_photo_drill = (PCB_LAYER_IS_DRILL(flags, purpi) || ((flags & PCB_LYT_MECH) && PCB_LAYER_IS_ROUTE(flags, purpi))); + if (((flags & PCB_LYT_ANYTHING) == PCB_LYT_SILK) && (flags & PCB_LYT_TOP)) { + if (photo_flip) + return 0; + photo_im = &photo_silk; + } + else if (((flags & PCB_LYT_ANYTHING) == PCB_LYT_SILK) && (flags & PCB_LYT_BOTTOM)) { + if (!photo_flip) + return 0; + photo_im = &photo_silk; + } + else if ((flags & PCB_LYT_MASK) && (flags & PCB_LYT_TOP)) { + if (photo_flip) + return 0; + photo_im = &photo_mask; + } + else if ((flags & PCB_LYT_MASK) && (flags & PCB_LYT_BOTTOM)) { + if (!photo_flip) + return 0; + photo_im = &photo_mask; + } + else if (is_photo_drill) { + photo_im = &photo_drill; + } + else { + if (PCB_LAYER_IS_OUTLINE(flags, purpi)) { + doing_outline = 1; + have_outline = 0; + photo_im = &photo_outline; + } + else if (flags & PCB_LYT_COPPER) { + photo_im = photo_copper + group; + } + else + return 0; + } + + if (!*photo_im) { + static color_struct *black = NULL, *white = NULL; + *photo_im = gdImageCreate(gdImageSX(im), gdImageSY(im)); + if (photo_im == NULL) { + rnd_message(RND_MSG_ERROR, "png_set_layer(): gdImageCreate(%d, %d) returned NULL. Aborting export.\n", gdImageSX(im), gdImageSY(im)); + return 0; + } + + + white = (color_struct *) malloc(sizeof(color_struct)); + white->r = white->g = white->b = 255; + white->a = 0; + white->c = gdImageColorAllocate(*photo_im, white->r, white->g, white->b); + if (white->c == BADC) { + rnd_message(RND_MSG_ERROR, "png_set_layer(): gdImageColorAllocate() returned NULL. Aborting export.\n"); + return 0; + } + + black = (color_struct *) malloc(sizeof(color_struct)); + black->r = black->g = black->b = black->a = 0; + black->c = gdImageColorAllocate(*photo_im, black->r, black->g, black->b); + if (black->c == BADC) { + rnd_message(RND_MSG_ERROR, "png_set_layer(): gdImageColorAllocate() returned NULL. Aborting export.\n"); + return 0; + } + + if (is_photo_drill) + gdImageFilledRectangle(*photo_im, 0, 0, gdImageSX(im), gdImageSY(im), black->c); + } + im = *photo_im; + return 1; +} + +static void png_photo_head(void) +{ + photo_last_grp = -1; +} + +static void png_photo_foot(void) +{ + int x, y, darken, lg; + color_struct white, black, fr4; + + rgb(&white, 255, 255, 255); + rgb(&black, 0, 0, 0); + rgb(&fr4, 70, 70, 70); + + im = master_im; + + ts_bs(photo_copper[photo_groups[0]]); + if (photo_silk != NULL) + ts_bs(photo_silk); + if (photo_mask != NULL) + ts_bs_sm(photo_mask); + + if (photo_outline && have_outline) { + int black = gdImageColorResolve(photo_outline, 0x00, 0x00, 0x00); + + /* go all the way around the image, trying to fill the outline */ + for (x = 0; x < gdImageSX(im); x++) { + gdImageFillToBorder(photo_outline, x, 0, black, black); + gdImageFillToBorder(photo_outline, x, gdImageSY(im) - 1, black, black); + } + for (y = 1; y < gdImageSY(im) - 1; y++) { + gdImageFillToBorder(photo_outline, 0, y, black, black); + gdImageFillToBorder(photo_outline, gdImageSX(im) - 1, y, black, black); + + } + } + + + for (x = 0; x < gdImageSX(im); x++) { + for (y = 0; y < gdImageSY(im); y++) { + color_struct p, cop; + color_struct mask_colour, silk_colour; + int cc, mask, silk; + int transparent; + + if (photo_outline && have_outline) { + transparent = gdImageGetPixel(photo_outline, x, y); + } + else { + transparent = 0; + } + + mask = photo_mask ? gdImageGetPixel(photo_mask, x, y) : 0; + silk = photo_silk ? gdImageGetPixel(photo_silk, x, y) : 0; + + darken = 0; + for(lg = 1; lg < photo_ngroups; lg++) { + if (photo_copper[photo_groups[lg]] && gdImageGetPixel(photo_copper[photo_groups[lg]], x, y)) { + darken = 1; + break; + } + } + + if (darken) + rgb(&cop, 40, 40, 40); + else + rgb(&cop, 100, 100, 110); + + blend(&cop, 0.3, &cop, &fr4); + + cc = gdImageGetPixel(photo_copper[photo_groups[0]], x, y); + if (cc) { + int r; + + if (mask) + rgb(&cop, 220, 145, 230); + else { + + if (png_options[HA_photo_plating].lng == PLATING_GOLD) { + /* ENIG */ + rgb(&cop, 185, 146, 52); + + /* increase top shadow to increase shininess */ + if (cc == TOP_SHADOW) + blend(&cop, 0.7, &cop, &white); + } + else if (png_options[HA_photo_plating].lng == PLATING_TIN) { + /* tinned */ + rgb(&cop, 140, 150, 160); + + /* add some variation to make it look more matte */ + r = (rand() % 5 - 2) * 2; + cop.r += r; + cop.g += r; + cop.b += r; + } + else if (png_options[HA_photo_plating].lng == PLATING_SILVER) { + /* silver */ + rgb(&cop, 192, 192, 185); + + /* increase top shadow to increase shininess */ + if (cc == TOP_SHADOW) + blend(&cop, 0.7, &cop, &white); + } + else if (png_options[HA_photo_plating].lng == PLATING_COPPER) { + /* copper */ + rgb(&cop, 184, 115, 51); + + /* increase top shadow to increase shininess */ + if (cc == TOP_SHADOW) + blend(&cop, 0.7, &cop, &white); + } + /*FIXME: old code...can be removed after validation. rgb(&cop, 140, 150, 160); + r = (rnd_rand() % 5 - 2) * 2; + cop.r += r; + cop.g += r; + cop.b += r; */ + } + + if (cc == TOP_SHADOW) { + cop.r = 255 - (255 - cop.r) * 0.7; + cop.g = 255 - (255 - cop.g) * 0.7; + cop.b = 255 - (255 - cop.b) * 0.7; + } + if (cc == BOTTOM_SHADOW) { + cop.r *= 0.7; + cop.g *= 0.7; + cop.b *= 0.7; + } + } + + if (photo_drill && !gdImageGetPixel(photo_drill, x, y)) { + rgb(&p, 0, 0, 0); + transparent = 1; + } + else if (silk) { + silk_colour = silk_colours[png_options[HA_photo_silk_colour].lng]; + blend(&p, 1.0, &silk_colour, &silk_colour); + + if (silk == TOP_SHADOW) + add(&p, 1.0, &p, 1.0, &silk_top_shadow); + else if (silk == BOTTOM_SHADOW) + subtract(&p, 1.0, &p, 1.0, &silk_bottom_shadow); + } + else if (mask) { + p = cop; + mask_colour = mask_colours[png_options[HA_photo_mask_colour].lng]; + multiply(&p, &p, &mask_colour); + add(&p, 1, &p, 0.2, &mask_colour); + if (mask == TOP_SHADOW) + blend(&p, 0.7, &p, &white); + if (mask == BOTTOM_SHADOW) + blend(&p, 0.7, &p, &black); + } + else + p = cop; + + if (png_options[HA_use_alpha].lng) + cc = (transparent) ? gdImageColorResolveAlpha(im, 0, 0, 0, 127) : gdImageColorResolveAlpha(im, p.r, p.g, p.b, 0); + else + cc = (transparent) ? gdImageColorResolve(im, 0, 0, 0) : gdImageColorResolve(im, p.r, p.g, p.b); + + if (photo_flip == PHOTO_FLIP_X) + gdImageSetPixel(im, gdImageSX(im) - x - 1, y, cc); + else if (photo_flip == PHOTO_FLIP_Y) + gdImageSetPixel(im, x, gdImageSY(im) - y - 1, cc); + else + gdImageSetPixel(im, x, y, cc); + } + } +} + +static void png_photo_as_shown() +{ + int i, n = 0; + rnd_layergrp_id_t solder_layer = -1, comp_layer = -1; + + pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_COPPER, &solder_layer, 1); + pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_COPPER, &comp_layer, 1); + assert(solder_layer >= 0); + assert(comp_layer >= 0); + + photo_has_inners = 0; + if (comp_layer < solder_layer) + for (i = comp_layer; i <= solder_layer; i++) { + photo_groups[n++] = i; + if (i != comp_layer && i != solder_layer && !pcb_layergrp_is_empty(PCB, i)) + photo_has_inners = 1; + } + else + for (i = comp_layer; i >= solder_layer; i--) { + photo_groups[n++] = i; + if (i != comp_layer && i != solder_layer && !pcb_layergrp_is_empty(PCB, i)) + photo_has_inners = 1; + } + if (!photo_has_inners) { + photo_groups[1] = photo_groups[n - 1]; + n = 2; + } + photo_ngroups = n; + + if (photo_flip) { + for (i = 0, n = photo_ngroups - 1; i < n; i++, n--) { + int tmp = photo_groups[i]; + photo_groups[i] = photo_groups[n]; + photo_groups[n] = tmp; + } + } +} + +static void png_photo_do_export(rnd_hid_attr_val_t *options) +{ + options[HA_mono].lng = 1; + options[HA_as_shown].lng = 0; + memset(photo_copper, 0, sizeof(photo_copper)); + photo_silk = photo_mask = photo_drill = 0; + photo_outline = 0; + if (options[HA_photo_flip_x].lng) + photo_flip = PHOTO_FLIP_X; + else if (options[HA_photo_flip_y].lng) + photo_flip = PHOTO_FLIP_Y; + else + photo_flip = 0; +} + +static void png_photo_post_export() +{ + int i; + if (photo_silk != NULL) { + gdImageDestroy(photo_silk); + photo_silk = NULL; + } + if (photo_mask != NULL) { + gdImageDestroy(photo_mask); + photo_mask = NULL; + } + if (photo_drill != NULL) { + gdImageDestroy(photo_drill); + photo_drill = NULL; + } + if (photo_outline != NULL) { + gdImageDestroy(photo_outline); + photo_outline = NULL; + } + for(i = 0; i < PCB_MAX_LAYER; i++) { + if (photo_copper[i] != NULL) { + gdImageDestroy(photo_copper[i]); + photo_copper[i] = NULL; + } + } +} Index: tags/2.3.0/src_plugins/export_ps/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_ps/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_ps/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_ps + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_ps/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_ps/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_ps/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {export_ps} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_ps/ps.o $(PLUGDIR)/export_ps/eps.o @] + +switch /local/pcb/export_ps/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_ps/eps.c =================================================================== --- tags/2.3.0/src_plugins/export_ps/eps.c (nonexistent) +++ tags/2.3.0/src_plugins/export_ps/eps.c (revision 33253) @@ -0,0 +1,691 @@ +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include + +#include +#include "board.h" +#include +#include "data.h" +#include "draw.h" +#include "layer.h" +#include "layer_vis.h" +#include +#include + +#include +#include +#include "ps.h" +#include +#include +#include "hid_cam.h" +#include "funchash_core.h" + +#define CRASH(func) fprintf(stderr, "HID error: pcb called unimplemented EPS function %s.\n", func); abort() + +static pcb_cam_t eps_cam; + +typedef struct rnd_hid_gc_s { + rnd_core_gc_t core_gc; + rnd_cap_style_t cap; + rnd_coord_t width; + unsigned long color; + int erase; +} rnd_hid_gc_s; + +static rnd_hid_t eps_hid; + +static FILE *f = 0; +static rnd_coord_t linewidth = -1; +static int lastcap = -1; +static int lastcolor = -1; +static int print_group[PCB_MAX_LAYERGRP]; +static int print_layer[PCB_MAX_LAYER]; +static int fast_erase = -1; +static rnd_composite_op_t drawing_mode; +static long eps_drawn_objs; + +static 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, 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, 0}, +#define HA_scale 1 + +/* %start-doc options "92 Encapsulated Postscript Export" +@ftable @code +@cindex as-shown (EPS) +@item --as-shown +Export layers as shown on screen. +@end ftable +%end-doc +*/ + {"as-shown", "Export layers as shown on screen", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_as_shown 2 + +/* %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, 0}, +#define HA_mono 3 + +/* %start-doc options "92 Encapsulated Postscript Export" +@ftable @code +@cindex only-visible +@item --only-visible +Limit the bounds of the EPS file to the visible items. +@end ftable +%end-doc +*/ + {"only-visible", "Limit the bounds of the EPS file to the visible items", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_only_visible 4 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 5 + +}; + +#define NUM_OPTIONS (sizeof(eps_attribute_list)/sizeof(eps_attribute_list[0])) + +static rnd_hid_attr_val_t eps_values[NUM_OPTIONS]; + +static rnd_export_opt_t *eps_get_export_options(rnd_hid_t *hid, int *n) +{ + if ((PCB != NULL) && (eps_attribute_list[HA_psfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &eps_attribute_list[HA_psfile], ".eps"); + + if (n) + *n = NUM_OPTIONS; + return eps_attribute_list; +} + +static rnd_layergrp_id_t group_for_layer(int l) +{ + if (l < pcb_max_layer(PCB) && l >= 0) + return pcb_layer_get_group(PCB, l); + /* else something unique */ + return pcb_max_group(PCB) + 3 + l; +} + +static int is_solder(rnd_layergrp_id_t grp) { return pcb_layergrp_flags(PCB, grp) & PCB_LYT_BOTTOM; } +static int is_component(rnd_layergrp_id_t grp) { return pcb_layergrp_flags(PCB, grp) & PCB_LYT_TOP; } + +static int layer_sort(const void *va, const void *vb) +{ + int a = *(int *) va; + int b = *(int *) vb; + rnd_layergrp_id_t al = group_for_layer(a); + rnd_layergrp_id_t bl = group_for_layer(b); + int d = bl - al; + + if (a >= 0 && a < pcb_max_layer(PCB)) { + int aside = (is_solder(al) ? 0 : is_component(al) ? 2 : 1); + int bside = (is_solder(bl) ? 0 : is_component(bl) ? 2 : 1); + if (bside != aside) + return bside - aside; + } + if (d) + return d; + return b - a; +} + +static const char *filename; +static rnd_box_t *bounds; +static int in_mono, as_shown; + +static rnd_hid_attr_val_t *options_; +static void eps_print_header(FILE *f, const char *outfn) +{ + linewidth = -1; + lastcap = -1; + lastcolor = -1; + + fprintf(f, "%%!PS-Adobe-3.0 EPSF-3.0\n"); + +#define pcb2em(x) 1 + RND_COORD_TO_INCH (x) * 72.0 * options_[HA_scale].dbl + fprintf(f, "%%%%BoundingBox: 0 0 %f %f\n", pcb2em(bounds->X2 - bounds->X1), pcb2em(bounds->Y2 - bounds->Y1)); +#undef pcb2em + fprintf(f, "%%%%Pages: 1\n"); + fprintf(f, "save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def\n"); + fprintf(f, "%%%%EndProlog\n"); + fprintf(f, "%%%%Page: 1 1\n"); + + fprintf(f, "%%%%BeginDocument: %s\n\n", outfn); + + fprintf(f, "72 72 scale\n"); + fprintf(f, "1 dup neg scale\n"); + fprintf(f, "%g dup scale\n", options_[HA_scale].dbl); + rnd_fprintf(f, "%mi %mi translate\n", -bounds->X1, -bounds->Y2); + if (options_[HA_as_shown].lng && conf_core.editor.show_solder_side) + rnd_fprintf(f, "-1 1 scale %mi 0 translate\n", bounds->X1 - bounds->X2); + +#define Q (rnd_coord_t) RND_MIL_TO_COORD(10) + rnd_fprintf(f, + "/nclip { %mi %mi moveto %mi %mi lineto %mi %mi lineto %mi %mi lineto %mi %mi lineto eoclip newpath } def\n", + bounds->X1 - Q, bounds->Y1 - Q, bounds->X1 - Q, bounds->Y2 + Q, + bounds->X2 + Q, bounds->Y2 + Q, bounds->X2 + Q, bounds->Y1 - Q, bounds->X1 - Q, bounds->Y1 - Q); +#undef Q + fprintf(f, "/t { moveto lineto stroke } bind def\n"); + fprintf(f, "/tc { moveto lineto strokepath nclip } bind def\n"); + fprintf(f, "/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def\n"); + fprintf(f, " x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def\n"); + fprintf(f, "/c { 0 360 arc fill } bind def\n"); + fprintf(f, "/cc { 0 360 arc nclip } bind def\n"); + fprintf(f, "/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def\n"); +} + +static void eps_print_footer(FILE *f) +{ + fprintf(f, "showpage\n"); + + fprintf(f, "%%%%EndDocument\n"); + fprintf(f, "%%%%Trailer\n"); + fprintf(f, "cleartomark countdictstack exch sub { end } repeat restore\n"); + fprintf(f, "%%%%EOF\n"); +} + +void eps_hid_export_to_file(FILE * the_file, rnd_hid_attr_val_t *options, rnd_xform_t *xform) +{ + int i; + static int saved_layer_stack[PCB_MAX_LAYER]; + rnd_box_t tmp, region; + rnd_hid_expose_ctx_t ctx; + + options_ = options; + + f = the_file; + + region.X1 = 0; + region.Y1 = 0; + region.X2 = PCB->hidlib.size_x; + region.Y2 = PCB->hidlib.size_y; + + if (options[HA_only_visible].lng) + bounds = pcb_data_bbox(&tmp, PCB->Data, rnd_false); + else + bounds = ®ion; + + memset(print_group, 0, sizeof(print_group)); + memset(print_layer, 0, sizeof(print_layer)); + + /* Figure out which layers actually have stuff on them. */ + for (i = 0; i < pcb_max_layer(PCB); i++) { + pcb_layer_t *layer = PCB->Data->Layer + i; + if (pcb_layer_flags(PCB, i) & PCB_LYT_SILK) + continue; + if (layer->meta.real.vis) + if (!pcb_layer_is_empty_(PCB, layer)) + print_group[pcb_layer_get_group(PCB, i)] = 1; + } + + /* Now, if only one layer has real stuff on it, we can use the fast + erase logic. Otherwise, we have to use the expensive multi-mask + erase. */ + fast_erase = 0; + for (i = 0; i < pcb_max_group(PCB); i++) + if (print_group[i]) + fast_erase++; + + /* If NO layers had anything on them, at least print the component + layer to get the pins. */ + if (fast_erase == 0) { + rnd_layergrp_id_t comp_copp; + if (pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_COPPER, &comp_copp, 1) > 0) { + print_group[pcb_layer_get_group(PCB, comp_copp)] = 1; + fast_erase = 1; + } + } + + /* "fast_erase" is 1 if we can just paint white to erase. */ + fast_erase = fast_erase == 1 ? 1 : 0; + + /* Now, for each group we're printing, mark its layers for + printing. */ + for (i = 0; i < pcb_max_layer(PCB); i++) { + if (pcb_layer_flags(PCB, i) & PCB_LYT_SILK) + continue; + if (print_group[pcb_layer_get_group(PCB, i)]) + print_layer[i] = 1; + } + + memcpy(saved_layer_stack, pcb_layer_stack, sizeof(pcb_layer_stack)); + as_shown = options[HA_as_shown].lng; + if (options[HA_as_shown].lng) + pcb_draw_setup_default_gui_xform(xform); + if (!options[HA_as_shown].lng) { + qsort(pcb_layer_stack, pcb_max_layer(PCB), sizeof(pcb_layer_stack[0]), layer_sort); + } + linewidth = -1; + lastcap = -1; + lastcolor = -1; + + in_mono = options[HA_mono].lng; + + if (f != NULL) + eps_print_header(f, rnd_hid_export_fn(filename)); + + if (as_shown) { + /* disable (exporter default) hiding overlay in as_shown */ + xform->omit_overlay = 0; + } + + ctx.view = *bounds; + rnd_expose_main(&eps_hid, &ctx, xform); + + eps_print_footer(f); + + memcpy(pcb_layer_stack, saved_layer_stack, sizeof(pcb_layer_stack)); + options_ = NULL; +} + +static void eps_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + int i; + int save_ons[PCB_MAX_LAYER]; + rnd_xform_t xform; + + if (!options) { + eps_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + eps_values[i] = eps_attribute_list[i].default_val; + options = eps_values; + } + + eps_drawn_objs = 0; + pcb_cam_begin(PCB, &eps_cam, &xform, options[HA_cam].str, eps_attribute_list, NUM_OPTIONS, options); + + filename = options[HA_psfile].str; + if (!filename) + filename = "pcb-out.eps"; + + if (eps_cam.fn_template == NULL) { + f = rnd_fopen_askovr(&PCB->hidlib, eps_cam.active ? eps_cam.fn : filename, "w", NULL); + if (!f) { + perror(filename); + return; + } + } + else + f = NULL; + + if ((!eps_cam.active) && (!options[HA_as_shown].lng)) + pcb_hid_save_and_show_layer_ons(save_ons); + eps_hid_export_to_file(f, options, &xform); + if ((!eps_cam.active) && (!options[HA_as_shown].lng)) + pcb_hid_restore_layer_ons(save_ons); + + fclose(f); + + if (!eps_cam.active) eps_cam.okempty_content = 1; /* never warn in direct export */ + + if (pcb_cam_end(&eps_cam) == 0) { + if (!eps_cam.okempty_group) + rnd_message(RND_MSG_ERROR, "eps cam export for '%s' failed to produce any content (layer group missing)\n", options[HA_cam].str); + } + else if (eps_drawn_objs == 0) { + if (!eps_cam.okempty_content) + rnd_message(RND_MSG_ERROR, "eps cam export for '%s' failed to produce any content (no objects)\n", options[HA_cam].str); + } +} + +static int eps_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(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 is_mask; +static int is_paste; +static int is_drill; + +static int eps_set_layer_group(rnd_hid_t *hid, 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) +{ + gds_t tmp_ln; + const char *name; + + if (flags & PCB_LYT_UI) + return 0; + + pcb_cam_set_layer_group(&eps_cam, group, purpose, purpi, flags, xform); + + if (eps_cam.fn_changed) { + if (f != NULL) { + eps_print_footer(f); + fclose(f); + } + f = rnd_fopen_askovr(&PCB->hidlib, eps_cam.fn, "w", NULL); + eps_print_header(f, eps_cam.fn); + } + + if (!eps_cam.active) { + if (flags & PCB_LYT_NOEXPORT) + return 0; + + if (PCB_LAYER_IS_ASSY(flags, purpi) || PCB_LAYER_IS_FAB(flags, purpi) || PCB_LAYER_IS_CSECT(flags, purpi) || (flags & PCB_LYT_INVIS)) + return 0; + + if ((group >= 0) && pcb_layergrp_is_empty(PCB, group) && PCB_LAYER_IS_ROUTE(flags, purpi)) + return 0; + } + + is_drill = PCB_LAYER_IS_DRILL(flags, purpi); + is_mask = (flags & PCB_LYT_MASK); + is_paste = !!(flags & PCB_LYT_PASTE); + + if (is_mask || is_paste) + return 0; + + gds_init(&tmp_ln); + name = pcb_layer_to_file_name(&tmp_ln, layer, flags, purpose, purpi, PCB_FNS_fixed); + +#if 0 + printf("Layer %s group %d drill %d mask %d\n", name, group, is_drill, is_mask); +#endif + fprintf(f, "%% Layer %s group %ld drill %d mask %d\n", name, group, is_drill, is_mask); + gds_uninit(&tmp_ln); + + if (as_shown) { + if (PCB_LAYERFLG_ON_VISIBLE_SIDE(flags)) + return pcb_silk_on(PCB); + else + return 0; + } + else { + if (((flags & PCB_LYT_ANYTHING) == PCB_LYT_SILK) && (flags & PCB_LYT_TOP)) + return 1; + if (((flags & PCB_LYT_ANYTHING) == PCB_LYT_SILK) && (flags & PCB_LYT_BOTTOM)) + return 0; + } + + return 1; +} + +static rnd_hid_gc_t eps_make_gc(rnd_hid_t *hid) +{ + rnd_hid_gc_t rv = (rnd_hid_gc_t) malloc(sizeof(rnd_hid_gc_s)); + rv->cap = rnd_cap_round; + rv->width = 0; + rv->color = 0; + return rv; +} + +static void eps_destroy_gc(rnd_hid_gc_t gc) +{ + free(gc); +} + +static void eps_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + if (direct) + return; + drawing_mode = op; + switch(op) { + case RND_HID_COMP_RESET: + fprintf(f, "gsave\n"); + break; + + case RND_HID_COMP_POSITIVE: + case RND_HID_COMP_POSITIVE_XOR: + case RND_HID_COMP_NEGATIVE: + break; + + case RND_HID_COMP_FLUSH: + fprintf(f, "grestore\n"); + lastcolor = -1; + break; + } +} + + +static void eps_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + if (drawing_mode == RND_HID_COMP_NEGATIVE) { + gc->color = 0xffffff; + gc->erase = 1; + return; + } + if (rnd_color_is_drill(color)) { + gc->color = 0xffffff; + gc->erase = 0; + return; + } + gc->erase = 0; + if (in_mono) + gc->color = 0; + else if (color->str[0] == '#') + gc->color = (color->r << 16) + (color->g << 8) + color->b; + else + gc->color = 0; +} + +static void eps_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + gc->cap = style; +} + +static void eps_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + gc->width = width; +} + +static void eps_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ + ; +} + +static void use_gc(rnd_hid_gc_t gc) +{ + eps_drawn_objs++; + if (linewidth != gc->width) { + rnd_fprintf(f, "%mi setlinewidth\n", gc->width); + linewidth = gc->width; + } + if (lastcap != gc->cap) { + int c; + switch (gc->cap) { + case rnd_cap_round: + c = 1; + break; + case rnd_cap_square: + c = 2; + break; + default: + assert(!"unhandled cap"); + c = 1; + } + fprintf(f, "%d setlinecap\n", c); + lastcap = gc->cap; + } + if (lastcolor != gc->color) { + int c = gc->color; +#define CV(x,b) (((x>>b)&0xff)/255.0) + fprintf(f, "%g %g %g setrgbcolor\n", CV(c, 16), CV(c, 8), CV(c, 0)); + lastcolor = gc->color; + } +} + +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); +static void eps_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius); + +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) +{ + use_gc(gc); + rnd_fprintf(f, "%mi %mi %mi %mi r\n", 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_coord_t w = gc->width / 2; + if (x1 == x2 && y1 == y2) { + if (gc->cap == rnd_cap_square) + eps_fill_rect(gc, x1 - w, y1 - w, x1 + w, y1 + w); + else + eps_fill_circle(gc, x1, y1, w); + return; + } + use_gc(gc); + if (gc->erase && gc->cap != rnd_cap_square) { + double ang = atan2(y2 - y1, x2 - x1); + double dx = w * sin(ang); + double dy = -w * cos(ang); + double deg = ang * 180.0 / M_PI; + rnd_coord_t vx1 = x1 + dx; + rnd_coord_t vy1 = y1 + dy; + + rnd_fprintf(f, "%mi %mi moveto ", vx1, vy1); + rnd_fprintf(f, "%mi %mi %mi %g %g arc\n", x2, y2, w, deg - 90, deg + 90); + rnd_fprintf(f, "%mi %mi %mi %g %g arc\n", x1, y1, w, deg + 90, deg + 270); + fprintf(f, "nclip\n"); + + return; + } + rnd_fprintf(f, "%mi %mi %mi %mi %s\n", x1, y1, x2, y2, gc->erase ? "tc" : "t"); +} + +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_angle_t sa, ea; + double w; + + if ((width == 0) && (height == 0)) { + /* degenerate case, draw dot */ + eps_draw_line(gc, cx, cy, cx, cy); + return; + } + + if (delta_angle > 0) { + sa = start_angle; + ea = start_angle + delta_angle; + } + else { + sa = start_angle + delta_angle; + ea = start_angle; + } +#if 0 + printf("draw_arc %d,%d %dx%d %d..%d %d..%d\n", cx, cy, width, height, start_angle, delta_angle, sa, ea); +#endif + use_gc(gc); + w = width; + if (w == 0) /* make sure not to div by zero; this hack will have very similar effect */ + w = 0.0001; + rnd_fprintf(f, "%ma %ma %mi %mi %mi %mi %f a\n", sa, ea, -width, height, cx, cy, (double) linewidth / w); +} + +static void eps_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + use_gc(gc); + rnd_fprintf(f, "%mi %mi %mi %s\n", cx, cy, radius, gc->erase ? "cc" : "c"); +} + +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) +{ + int i; + const char *op = "moveto"; + use_gc(gc); + for (i = 0; i < n_coords; i++) { + rnd_fprintf(f, "%mi %mi %s\n", x[i] + dx, y[i] + dy, op); + op = "lineto"; + } + + fprintf(f, "fill\n"); +} + +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) +{ + use_gc(gc); + rnd_fprintf(f, "%mi %mi %mi %mi r\n", x1, y1, x2, y2); +} + +static void eps_calibrate(rnd_hid_t *hid, double xval, double yval) +{ + CRASH("eps_calibrate"); +} + +static void eps_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int action) +{ +} + +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: pcb-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 = eps_make_gc; + eps_hid.destroy_gc = eps_destroy_gc; + eps_hid.set_drawing_mode = eps_set_drawing_mode; + eps_hid.set_color = eps_set_color; + eps_hid.set_line_cap = eps_set_line_cap; + eps_hid.set_line_width = eps_set_line_width; + eps_hid.set_draw_xor = 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.calibrate = eps_calibrate; + eps_hid.set_crosshair = eps_set_crosshair; + + eps_hid.usage = eps_usage; + + rnd_hid_register_hid(&eps_hid); +} Index: tags/2.3.0/src_plugins/export_ps/export_ps.pup =================================================================== --- tags/2.3.0/src_plugins/export_ps/export_ps.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_ps/export_ps.pup (revision 33253) @@ -0,0 +1,11 @@ +$class export +$short postscript pcb_exporter +$long Export postscript or embedded postscript. +$state works +$fmt-native no +$fmt-feature-w render black&white postscript (single or multiple files) +$fmt-feature-w render black&white or color embedded postscript (single file) +$package export +dep lib_compat_help +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_ps/ps.c =================================================================== --- tags/2.3.0/src_plugins/export_ps/ps.c (nonexistent) +++ tags/2.3.0/src_plugins/export_ps/ps.c (revision 33253) @@ -0,0 +1,1507 @@ +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include "board.h" +#include "data.h" +#include "layer.h" +#include +#include "draw.h" +#include +#include +#include "hid_cam.h" +#include +#include "funchash_core.h" +#include "layer_vis.h" + +#include +#include +#include "ps.h" +#include +#include +#include +#include "conf_core.h" +#include +#include "stub_draw.h" +#include "../src_plugins/lib_compat_help/media.h" + +const char *ps_cookie = "ps HID"; + +static int ps_set_layer_group(rnd_hid_t *hid, 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 void use_gc(rnd_hid_gc_t gc); + +typedef struct rnd_hid_gc_s { + rnd_core_gc_t core_gc; + rnd_hid_t *me_pointer; + rnd_cap_style_t cap; + rnd_coord_t width; + unsigned char r, g, b; + int erase; + int faded; +} rnd_hid_gc_s; + +static pcb_cam_t ps_cam; + +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, 0}, +#define HA_psfile 0 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex drill-helper +@item --drill-helper +Draw small holes to center drill but in copper +@end ftable +%end-doc +*/ + {"drill-helper", "Draw small holes to center drill but in copper", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_drillhelper 1 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex align-marks +@item --align-marks +Print alignment marks on each sheet. This is meant to ease alignment during exposure. +@end ftable +%end-doc +*/ + {"align-marks", "Print alignment marks on each sheet", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_alignmarks 2 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --outline +Print the contents of the outline layer on each sheet. +@end ftable +%end-doc +*/ + {"outline", "Print outline on each sheet", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_outline 3 +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --mirror +Print mirror image. +@end ftable +%end-doc +*/ + {"mirror", "Print mirror image of every page", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_mirror 4 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --fill-page +Scale output to make the board fit the page. +@end ftable +%end-doc +*/ + {"fill-page", "Scale board to fill page", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_fillpage 5 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --auto-mirror +Print mirror image of appropriate layers. +@end ftable +%end-doc +*/ + {"auto-mirror", "Print mirror image of appropriate layers", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_automirror 6 + +/* %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, 0}, +#define HA_color 7 + +/* %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, 0}, +#define HA_psinvert 8 + +/* %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}, pcb_medias, 0}, +#define HA_media 9 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex psfade +@item --psfade +Fade amount for assembly drawings (0.0=missing, 1.0=solid). +@end ftable +%end-doc +*/ + {"psfade", "Fade amount for assembly drawings (0.0=missing, 1.0=solid)", + RND_HATT_REAL, 0, 1, {0, 0, 0.40}, 0, 0}, +#define HA_psfade 10 + +/* %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, 0}, +#define HA_scale 11 + +/* %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, 0}, +#define HA_multifile 12 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --xcalib +Paper width. Used for x-Axis calibration. +@end ftable +%end-doc +*/ + {"xcalib", "Paper width. Used for x-Axis calibration", + RND_HATT_REAL, 0, 2, {0, 0, 1.0}, 0, 0}, +#define HA_xcalib 13 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --ycalib +Paper height. Used for y-Axis calibration. +@end ftable +%end-doc +*/ + {"ycalib", "Paper height. Used for y-Axis calibration", + RND_HATT_REAL, 0, 2, {0, 0, 1.0}, 0, 0}, +#define HA_ycalib 14 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@item --drill-copper +Draw drill holes in pins / vias, instead of leaving solid copper. +@end ftable +%end-doc +*/ + {"drill-copper", "Draw drill holes in pins / vias, instead of leaving solid copper", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_drillcopper 15 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex show-legend +@item --show-legend +Print file name and scale on printout. +@end ftable +%end-doc +*/ + {"show-legend", "Print file name and scale on printout", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_legend 16 + +/* %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", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_toc 17 + + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex single-page +@item --single-page +Merge all drawings on a single page +@end ftable +%end-doc +*/ + {"single-page", "Merge all drawings on a single page", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_single_page 18 + +/* %start-doc options "91 Postscript Export" +@ftable @code +@cindex drill-helper-size +@item --drill-helper-size +Diameter of the small hole when drill-helper is on +@end ftable +%end-doc +*/ + {"drill-helper-size", "Diameter of the small hole when drill-helper is on", + RND_HATT_COORD, 0, RND_MM_TO_COORD(10), {0, 0, 0, PCB_MIN_PINORVIAHOLE}, 0, 0}, +#define HA_drillhelpersize 19 + + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 20 + +}; + +#define NUM_OPTIONS (sizeof(ps_attribute_list)/sizeof(ps_attribute_list[0])) + +/* All file-scope data is in global struct */ +static struct { + double calibration_x, calibration_y; + + FILE *f; + int pagecount; + rnd_coord_t linewidth; + double fade_ratio; + rnd_bool multi_file; + rnd_bool multi_file_cam; + rnd_coord_t media_width, media_height, ps_width, ps_height; + + const char *filename; + rnd_bool drill_helper; + rnd_coord_t drill_helper_size; + rnd_bool align_marks; + rnd_bool outline; + rnd_bool mirror; + rnd_bool fillpage; + rnd_bool automirror; + rnd_bool incolor; + rnd_bool doing_toc; + rnd_bool invert; + int media_idx; + rnd_bool drillcopper; + rnd_bool legend; + rnd_bool single_page; + + int has_outline; + double scale_factor; + + rnd_hid_expose_ctx_t exps; + + rnd_hid_attr_val_t ps_values[NUM_OPTIONS]; + + rnd_bool is_mask; + rnd_bool is_drill; + rnd_bool is_assy; + rnd_bool is_copper; + rnd_bool is_paste; + + rnd_composite_op_t drawing_mode; + int ovr_all; + long drawn_objs; +} global; + +static rnd_export_opt_t *ps_get_export_options(rnd_hid_t *hid, int *n) +{ + if ((PCB != NULL) && (ps_attribute_list[HA_psfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &ps_attribute_list[HA_psfile], ".ps"); + + if (n) + *n = NUM_OPTIONS; + return ps_attribute_list; +} + +static rnd_layergrp_id_t group_for_layer(int l) +{ + if (l < pcb_max_layer(PCB) && l >= 0) + return pcb_layer_get_group(PCB, l); + /* else something unique */ + return pcb_max_group(PCB) + 3 + l; +} + +static int layer_sort(const void *va, const void *vb) +{ + int a = *(int *) va; + int b = *(int *) vb; + int d = group_for_layer(b) - group_for_layer(a); + if (d) + return d; + return b - a; +} + +void ps_start_file(FILE * f) +{ + time_t currenttime = time(NULL); + + fprintf(f, "%%!PS-Adobe-3.0\n"); + + /* Document Structuring Conventions (DCS): */ + + /* Start General Header Comments: */ + + /* + * %%Title DCS provides text title for the document that is useful + * for printing banner pages. + */ + fprintf(f, "%%%%Title: %s\n", rnd_hid_export_fn(PCB->hidlib.filename)); + + /* + * %%CreationDate DCS indicates the date and time the document was + * created. Neither the date nor time need be in any standard + * format. This comment is meant to be used purely for informational + * purposes, such as printing on banner pages. + */ + fprintf(f, "%%%%CreationDate: %s", asctime(localtime(¤ttime))); + + /* + * %%Creator DCS indicates the document creator, usually the name of + * the document composition software. + */ + fprintf(f, "%%%%Creator: PCB release: pcb-rnd " PCB_VERSION "\n"); + + /* + * %%Version DCS comment can be used to note the version and + * revision number of a document or resource. A document manager may + * wish to provide version control services, or allow substitution + * of compatible versions/revisions of a resource or document. + * + * The format should be in the form of 'procname': + * ::= < name> < version> < revision> + * < name> ::= < text> + * < version> ::= < real> + * < revision> ::= < uint> + * + * If a version numbering scheme is not used, these fields should + * still be filled with a dummy value of 0. + * + * There is currently no code in PCB to manage this revision number. + * + */ + fprintf(f, "%%%%Version: (PCB pcb-rnd " PCB_VERSION ") 0.0 0\n"); + + + /* + * %%PageOrder DCS is intended to help document managers determine + * the order of pages in the document file, which in turn enables a + * document manager optionally to reorder the pages. 'Ascend'-The + * pages are in ascending order for example, 1-2-3-4-5-6. + */ + fprintf(f, "%%%%PageOrder: Ascend\n"); + + /* + * %%Pages: < numpages> | (atend) < numpages> ::= < uint> (Total + * %%number of pages) + * + * %%Pages DCS defines the number of virtual pages that a document + * will image. (atend) defers the count until the end of the file, + * which is useful for dynamically generated contents. + */ + fprintf(f, "%%%%Pages: (atend)\n"); + + /* + * %%DocumentMedia: + * + * Substitute 0 or "" for N/A. Width and height are in points + * (1/72"). + * + * Media sizes are in PCB units + */ + rnd_fprintf(f, "%%%%DocumentMedia: %s %f %f 0 \"\" \"\"\n", + pcb_media_data[global.media_idx].name, + 72 * RND_COORD_TO_INCH(pcb_media_data[global.media_idx].width), + 72 * RND_COORD_TO_INCH(pcb_media_data[global.media_idx].height)); + rnd_fprintf(f, "%%%%DocumentPaperSizes: %s\n", pcb_media_data[global.media_idx].name); + + /* End General Header Comments. */ + + /* General Body Comments go here. Currently there are none. */ + + /* + * %%EndComments DCS indicates an explicit end to the header + * comments of the document. All global DCS's must preceded + * this. A blank line gives an implicit end to the comments. + */ + fprintf(f, "%%%%EndComments\n\n"); +} + +static void ps_end_file(FILE * f) +{ + /* + * %%Trailer DCS must only occur once at the end of the document + * script. Any post-processing or cleanup should be contained in + * the trailer of the document, which is anything that follows the + * %%Trailer comment. Any of the document level structure comments + * that were deferred by using the (atend) convention must be + * mentioned in the trailer of the document after the %%Trailer + * comment. + */ + fprintf(f, "%%%%Trailer\n"); + + /* + * %%Pages was deferred until the end of the document via the + * (atend) mentioned, in the General Header section. + */ + fprintf(f, "%%%%Pages: %d\n", global.pagecount); + + /* + * %%EOF DCS signifies the end of the document. When the document + * manager sees this comment, it issues an end-of-file signal to the + * PostScript interpreter. This is done so system-dependent file + * endings, such as Control-D and end-of-file packets, do not + * confuse the PostScript interpreter. + */ + fprintf(f, "%%%%EOF\n"); +} + +static FILE *psopen(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(&PCB->hidlib, 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(&PCB->hidlib, 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(FILE * the_file, rnd_hid_attr_val_t * options, rnd_xform_t *xform) +{ + static int saved_layer_stack[PCB_MAX_LAYER]; + + global.f = the_file; + global.drill_helper = options[HA_drillhelper].lng; + global.drill_helper_size = options[HA_drillhelpersize].crd; + global.align_marks = options[HA_alignmarks].lng; + global.outline = options[HA_outline].lng; + global.mirror = options[HA_mirror].lng; + global.fillpage = options[HA_fillpage].lng; + global.automirror = options[HA_automirror].lng; + global.incolor = options[HA_color].lng; + global.invert = options[HA_psinvert].lng; + global.fade_ratio = RND_CLAMP(options[HA_psfade].dbl, 0, 1); + global.media_idx = options[HA_media].lng; + global.media_width = pcb_media_data[global.media_idx].width; + global.media_height = pcb_media_data[global.media_idx].height; + global.ps_width = global.media_width - 2.0 * pcb_media_data[global.media_idx].margin_x; + global.ps_height = global.media_height - 2.0 * pcb_media_data[global.media_idx].margin_y; + global.scale_factor = options[HA_scale].dbl; + global.calibration_x = options[HA_xcalib].dbl; + global.calibration_y = options[HA_ycalib].dbl; + global.drillcopper = options[HA_drillcopper].lng; + global.legend = options[HA_legend].lng; + global.single_page = options[HA_single_page].lng; + + if (the_file) + ps_start_file(the_file); + + if (global.fillpage) { + double zx, zy; + if (PCB->hidlib.size_x > PCB->hidlib.size_y) { + zx = global.ps_height / PCB->hidlib.size_x; + zy = global.ps_width / PCB->hidlib.size_y; + } + else { + zx = global.ps_height / PCB->hidlib.size_y; + zy = global.ps_width / PCB->hidlib.size_x; + } + global.scale_factor *= MIN(zx, zy); + } + + global.has_outline = pcb_has_explicit_outline(PCB); + memcpy(saved_layer_stack, pcb_layer_stack, sizeof(pcb_layer_stack)); + qsort(pcb_layer_stack, pcb_max_layer(PCB), sizeof(pcb_layer_stack[0]), layer_sort); + + global.linewidth = -1; + /* reset static vars */ + ps_set_layer_group(rnd_render, -1, NULL, -1, -1, 0, -1, NULL); + use_gc(NULL); + + global.exps.view.X1 = 0; + global.exps.view.Y1 = 0; + global.exps.view.X2 = PCB->hidlib.size_x; + global.exps.view.Y2 = PCB->hidlib.size_y; + + if ((!global.multi_file && !global.multi_file_cam) && (options[HA_toc].lng)) { + /* %%Page DSC requires both a label and an ordinal */ + fprintf(the_file, "%%%%Page: TableOfContents 1\n"); + fprintf(the_file, "/Times-Roman findfont 24 scalefont setfont\n"); + fprintf(the_file, "/rightshow { /s exch def s stringwidth pop -1 mul 0 rmoveto s show } def\n"); + fprintf(the_file, "/y 72 9 mul def /toc { 100 y moveto show /y y 24 sub def } bind def\n"); + fprintf(the_file, "/tocp { /y y 12 sub def 90 y moveto rightshow } bind def\n"); + + global.doing_toc = 1; + global.pagecount = 1; /* 'pagecount' is modified by rnd_expose_main() call */ + rnd_expose_main(&ps_hid, &global.exps, xform); + } + + global.pagecount = 1; /* Reset 'pagecount' if single file */ + global.doing_toc = 0; + ps_set_layer_group(rnd_render, -1, NULL, -1, -1, 0, -1, NULL); /* reset static vars */ + rnd_expose_main(&ps_hid, &global.exps, xform); + + if (the_file) + fprintf(the_file, "showpage\n"); + + memcpy(pcb_layer_stack, saved_layer_stack, sizeof(pcb_layer_stack)); +} + +static void ps_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + FILE *fh; + int save_ons[PCB_MAX_LAYER]; + int i; + rnd_xform_t xform; + + global.ovr_all = 0; + + if (!options) { + ps_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + global.ps_values[i] = ps_attribute_list[i].default_val; + options = global.ps_values; + } + + global.drawn_objs = 0; + pcb_cam_begin(PCB, &ps_cam, &xform, options[HA_cam].str, ps_attribute_list, NUM_OPTIONS, options); + + global.filename = options[HA_psfile].str; + if (!global.filename) + global.filename = "pcb-out.ps"; + + /* cam mode shall result in a single file, no matter what other attributes say */ + if (ps_cam.active) { + global.multi_file = options[HA_multifile].lng; + global.multi_file_cam = (ps_cam.fn_template != NULL); /* template means multiple files potentially */ + } + else { + global.multi_file = options[HA_multifile].lng; + global.multi_file_cam = 0; + } + + if (global.multi_file || global.multi_file_cam) + fh = 0; + else { + const char *fn = ps_cam.active ? ps_cam.fn : global.filename; + fh = psopen(fn, "toc"); + if (!fh) { + perror(fn); + return; + } + } + + if (!ps_cam.active) + pcb_hid_save_and_show_layer_ons(save_ons); + ps_hid_export_to_file(fh, options, &xform); + if (!ps_cam.active) + pcb_hid_restore_layer_ons(save_ons); + + global.multi_file = 0; + if (fh) { + ps_end_file(fh); + fclose(fh); + } + + if (!ps_cam.active) ps_cam.okempty_content = 1; /* never warn in direct export */ + + if (pcb_cam_end(&ps_cam) == 0) { + if (!ps_cam.okempty_group) + rnd_message(RND_MSG_ERROR, "ps cam export for '%s' failed to produce any content (layer group missing)\n", options[HA_cam].str); + } + else if (global.drawn_objs == 0) { + if (!ps_cam.okempty_content) + rnd_message(RND_MSG_ERROR, "ps cam export for '%s' failed to produce any content (no objects)\n", options[HA_cam].str); + } + +} + +static int ps_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(ps_attribute_list, NUM_OPTIONS, ps_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static void corner(FILE * fh, rnd_coord_t x, rnd_coord_t y, int dx, int dy) +{ + rnd_coord_t len = RND_MIL_TO_COORD(2000); + rnd_coord_t len2 = RND_MIL_TO_COORD(200); + rnd_coord_t thick = 0; + /* + * Originally 'thick' used thicker lines. Currently is uses + * Postscript's "device thin" line - i.e. zero width means one + * device pixel. The code remains in case you want to make them + * thicker - it needs to offset everything so that the *edge* of the + * thick line lines up with the edge of the board, not the *center* + * of the thick line. + */ + + rnd_fprintf(fh, "gsave %mi setlinewidth %mi %mi translate %d %d scale\n", thick * 2, x, y, dx, dy); + rnd_fprintf(fh, "%mi %mi moveto %mi %mi %mi 0 90 arc %mi %mi lineto\n", len, thick, thick, thick, len2 + thick, thick, len); + if (dx < 0 && dy < 0) + rnd_fprintf(fh, "%mi %mi moveto 0 %mi rlineto\n", len2 * 2 + thick, thick, -len2); + fprintf(fh, "stroke grestore\n"); +} + +static int ps_set_layer_group(rnd_hid_t *hid, 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) +{ + gds_t tmp_ln; + static int lastgroup = -1; + time_t currenttime; + const char *name; + int newpage; + + if (is_empty == -1) { + lastgroup = -1; + return 0; + } + + + if (flags & PCB_LYT_UI) + return 0; + + pcb_cam_set_layer_group(&ps_cam, group, purpose, purpi, flags, xform); + + if (!ps_cam.active) { + if (flags & PCB_LYT_NOEXPORT) + return 0; + + if (!PCB_LAYER_IS_OUTLINE(flags, purpi)) { /* outline layer can never be empty, because of the implicit outline */ + if (is_empty) + return 0; + + if ((group >= 0) && pcb_layergrp_is_empty(PCB, group)) + return 0; + } + + if (flags & PCB_LYT_INVIS) + return 0; + + if (PCB_LAYER_IS_CSECT(flags, purpi)) /* not yet finished */ + return 0; + } + + + gds_init(&tmp_ln); + name = pcb_layer_to_file_name(&tmp_ln, layer, flags, purpose, purpi, PCB_FNS_fixed); + + global.is_drill = PCB_LAYER_IS_DRILL(flags, purpi); + global.is_mask = !!(flags & PCB_LYT_MASK); + global.is_assy = PCB_LAYER_IS_ASSY(flags, purpi); + global.is_copper = !!(flags & PCB_LYT_COPPER); + global.is_paste = !!(flags & PCB_LYT_PASTE); + +#if 0 + printf("Layer %s group %d drill %d mask %d\n", name, group, global.is_drill, global.is_mask); +#endif + + if (global.doing_toc) { + if (group < 0 || group != lastgroup) { + if (global.pagecount == 1) { + currenttime = time(NULL); + fprintf(global.f, "30 30 moveto (%s) show\n", rnd_hid_export_fn(PCB->hidlib.filename)); + + fprintf(global.f, "(%d.) tocp\n", global.pagecount); + fprintf(global.f, "(Table of Contents \\(This Page\\)) toc\n"); + + fprintf(global.f, "(Created on %s) toc\n", asctime(localtime(¤ttime))); + fprintf(global.f, "( ) tocp\n"); + } + + global.pagecount++; + lastgroup = group; + fprintf(global.f, "(%d.) tocp\n", global.single_page ? 2 : global.pagecount); + fprintf(global.f, "(%s) toc\n", name); + } + gds_uninit(&tmp_ln); + return 0; + } + + if (ps_cam.active) + newpage = ps_cam.fn_changed || (global.pagecount == 1); + else + newpage = (group < 0 || group != lastgroup); + if ((global.pagecount > 1) && global.single_page) + newpage = 0; + + if (newpage) { + double boffset; + int mirror_this = 0; + lastgroup = group; + + if ((!ps_cam.active) && (global.pagecount != 0)) { + rnd_fprintf(global.f, "showpage\n"); + } + global.pagecount++; + if ((!ps_cam.active && global.multi_file) || (ps_cam.active && ps_cam.fn_changed)) { + const char *fn; + gds_t tmp; + + gds_init(&tmp); + fn = ps_cam.active ? ps_cam.fn : pcb_layer_to_file_name(&tmp, layer, flags, purpose, purpi, PCB_FNS_fixed); + if (global.f) { + ps_end_file(global.f); + fclose(global.f); + } + global.f = psopen(ps_cam.active ? fn : global.filename, fn); + gds_uninit(&tmp); + + if (!global.f) { + perror(global.filename); + gds_uninit(&tmp_ln); + return 0; + } + + ps_start_file(global.f); + } + + /* + * %%Page DSC comment marks the beginning of the PostScript + * language instructions that describe a particular + * page. %%Page: requires two arguments: a page label and a + * sequential page number. The label may be anything, but the + * ordinal page number must reflect the position of that page in + * the body of the PostScript file and must start with 1, not 0. + */ + { + gds_t tmp; + gds_init(&tmp); + fprintf(global.f, "%%%%Page: %s %d\n", pcb_layer_to_file_name(&tmp, layer, flags, purpose, purpi, PCB_FNS_fixed), global.pagecount); + gds_uninit(&tmp); + } + + if (global.mirror) + mirror_this = !mirror_this; + if (global.automirror && (flags & PCB_LYT_BOTTOM)) + mirror_this = !mirror_this; + + fprintf(global.f, "/Helvetica findfont 10 scalefont setfont\n"); + if (global.legend) { + gds_t tmp; + fprintf(global.f, "30 30 moveto (%s) show\n", rnd_hid_export_fn(PCB->hidlib.filename)); + + gds_init(&tmp); + if (PCB->hidlib.name) + fprintf(global.f, "30 41 moveto (%s, %s) show\n", PCB->hidlib.name, pcb_layer_to_file_name(&tmp, layer, flags, purpose, purpi, PCB_FNS_fixed)); + else + fprintf(global.f, "30 41 moveto (%s) show\n", pcb_layer_to_file_name(&tmp, layer, flags, purpose, purpi, PCB_FNS_fixed)); + gds_uninit(&tmp); + + if (mirror_this) + fprintf(global.f, "( \\(mirrored\\)) show\n"); + + if (global.fillpage) + fprintf(global.f, "(, not to scale) show\n"); + else + fprintf(global.f, "(, scale = 1:%.3f) show\n", global.scale_factor); + } + fprintf(global.f, "newpath\n"); + + rnd_fprintf(global.f, "72 72 scale %mi %mi translate\n", global.media_width / 2, global.media_height / 2); + + boffset = global.media_height / 2; + if (PCB->hidlib.size_x > PCB->hidlib.size_y) { + fprintf(global.f, "90 rotate\n"); + boffset = global.media_width / 2; + fprintf(global.f, "%g %g scale %% calibration\n", global.calibration_y, global.calibration_x); + } + else + fprintf(global.f, "%g %g scale %% calibration\n", global.calibration_x, global.calibration_y); + + if (mirror_this) + fprintf(global.f, "1 -1 scale\n"); + + fprintf(global.f, "%g dup neg scale\n", PCB_LAYER_IS_FAB(flags, purpi) ? 1.0 : global.scale_factor); + rnd_fprintf(global.f, "%mi %mi translate\n", -PCB->hidlib.size_x / 2, -PCB->hidlib.size_y / 2); + + /* Keep the drill list from falling off the left edge of the paper, + * even if it means some of the board falls off the right edge. + * If users don't want to make smaller boards, or use fewer drill + * sizes, they can always ignore this sheet. */ + if (PCB_LAYER_IS_FAB(flags, purpi)) { + rnd_coord_t natural = boffset - RND_MIL_TO_COORD(500) - PCB->hidlib.size_y / 2; + rnd_coord_t needed = pcb_stub_draw_fab_overhang(); + rnd_fprintf(global.f, "%% PrintFab overhang natural %mi, needed %mi\n", natural, needed); + if (needed > natural) + rnd_fprintf(global.f, "0 %mi translate\n", needed - natural); + } + + if (global.invert) { + fprintf(global.f, "/gray { 1 exch sub setgray } bind def\n"); + fprintf(global.f, "/rgb { 1 1 3 { pop 1 exch sub 3 1 roll } for setrgbcolor } bind def\n"); + } + else { + fprintf(global.f, "/gray { setgray } bind def\n"); + fprintf(global.f, "/rgb { setrgbcolor } bind def\n"); + } + + if (!global.has_outline || global.invert) { + if ((PCB_LAYER_IS_ROUTE(flags, purpi)) || (global.outline)) { + rnd_fprintf(global.f, + "0 setgray %mi setlinewidth 0 0 moveto 0 " + "%mi lineto %mi %mi lineto %mi 0 lineto closepath %s\n", + conf_core.design.min_wid, + PCB->hidlib.size_y, PCB->hidlib.size_x, PCB->hidlib.size_y, PCB->hidlib.size_x, global.invert ? "fill" : "stroke"); + } + } + + if (global.align_marks) { + corner(global.f, 0, 0, -1, -1); + corner(global.f, PCB->hidlib.size_x, 0, 1, -1); + corner(global.f, PCB->hidlib.size_x, PCB->hidlib.size_y, 1, 1); + corner(global.f, 0, PCB->hidlib.size_y, -1, 1); + } + + global.linewidth = -1; + use_gc(NULL); /* reset static vars */ + + fprintf(global.f, + "/ts 1 def\n" + "/ty ts neg def /tx 0 def /Helvetica findfont ts scalefont setfont\n" + "/t { moveto lineto stroke } bind def\n" + "/dr { /y2 exch def /x2 exch def /y1 exch def /x1 exch def\n" + " x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath stroke } bind def\n"); + fprintf(global.f,"/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def\n" + " x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def\n" + "/c { 0 360 arc fill } bind def\n" + "/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def\n"); + if (global.drill_helper) + rnd_fprintf(global.f, + "/dh { gsave %mi setlinewidth 0 gray %mi 0 360 arc stroke grestore} bind def\n", + (rnd_coord_t) global.drill_helper_size, (rnd_coord_t) (global.drill_helper_size * 3 / 2)); + } +#if 0 + /* Try to outsmart ps2pdf's heuristics for page rotation, by putting + * text on all pages -- even if that text is blank */ + if (!(PCB_LAYER_IS_FAB(flags, purpi))) + fprintf(global.f, "gsave tx ty translate 1 -1 scale 0 0 moveto (Layer %s) show grestore newpath /ty ty ts sub def\n", name); + else + fprintf(global.f, "gsave tx ty translate 1 -1 scale 0 0 moveto ( ) show grestore newpath /ty ty ts sub def\n"); +#endif + + /* If we're printing a layer other than an outline layer, and + we want to "print outlines", and we have an outline layer, + print the outline layer on this layer also. */ + if (global.outline && + global.has_outline && + !(PCB_LAYER_IS_ROUTE(flags, purpi))) { + int save_drill = global.is_drill; + global.is_drill = 0; + pcb_draw_groups(hid, PCB, PCB_LYT_BOUNDARY, F_proute, NULL, &global.exps.view, rnd_color_black, PCB_LYT_MECH, 0, 0); + pcb_draw_groups(hid, PCB, PCB_LYT_BOUNDARY, F_uroute, NULL, &global.exps.view, rnd_color_black, PCB_LYT_MECH, 0, 0); + global.is_drill = save_drill; + } + + gds_uninit(&tmp_ln); + return 1; +} + +static rnd_hid_gc_t ps_make_gc(rnd_hid_t *hid) +{ + rnd_hid_gc_t rv = (rnd_hid_gc_t) calloc(1, sizeof(rnd_hid_gc_s)); + rv->me_pointer = &ps_hid; + rv->cap = rnd_cap_round; + return rv; +} + +static void ps_destroy_gc(rnd_hid_gc_t gc) +{ + free(gc); +} + +static void ps_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + global.drawing_mode = op; +} + + +static void ps_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + if (global.drawing_mode == RND_HID_COMP_NEGATIVE) { + gc->r = gc->g = gc->b = 255; + gc->erase = 0; + } + else if (rnd_color_is_drill(color)) { + gc->r = gc->g = gc->b = 255; + gc->erase = 1; + } + else if (global.incolor) { + gc->r = color->r; + gc->g = color->g; + gc->b = color->b; + gc->erase = 0; + } + else { + gc->r = gc->g = gc->b = 0; + gc->erase = 0; + } +} + +static void ps_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + gc->cap = style; +} + +static void ps_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + gc->width = width; +} + +static void ps_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ + ; +} + +static void ps_set_draw_faded(rnd_hid_gc_t gc, int faded) +{ + gc->faded = faded; +} + +static void use_gc(rnd_hid_gc_t gc) +{ + static int lastcap = -1; + static int lastcolor = -1; + + global.drawn_objs++; + if (gc == NULL) { + lastcap = lastcolor = -1; + return; + } + if (gc->me_pointer != &ps_hid) { + fprintf(stderr, "Fatal: GC from another HID passed to ps HID\n"); + abort(); + } + if (global.linewidth != gc->width) { + rnd_fprintf(global.f, "%mi setlinewidth\n", gc->width); + global.linewidth = gc->width; + } + if (lastcap != gc->cap) { + int c; + switch (gc->cap) { + case rnd_cap_round: + c = 1; + break; + case rnd_cap_square: + c = 2; + break; + default: + assert(!"unhandled cap"); + c = 1; + } + fprintf(global.f, "%d setlinecap %d setlinejoin\n", c, c); + lastcap = gc->cap; + } +#define CBLEND(gc) (((gc->r)<<24)|((gc->g)<<16)|((gc->b)<<8)|(gc->faded)) + if (lastcolor != CBLEND(gc)) { + if (global.is_drill || global.is_mask) { + fprintf(global.f, "%d gray\n", (gc->erase || global.is_mask) ? 0 : 1); + lastcolor = 0; + } + else { + double r, g, b; + r = gc->r; + g = gc->g; + b = gc->b; + if (gc->faded) { + r = (1 - global.fade_ratio) *255 + global.fade_ratio * r; + g = (1 - global.fade_ratio) *255 + global.fade_ratio * g; + b = (1 - global.fade_ratio) *255 + global.fade_ratio * b; + } + if (gc->r == gc->g && gc->g == gc->b) + fprintf(global.f, "%g gray\n", r / 255.0); + else + fprintf(global.f, "%g %g %g rgb\n", r / 255.0, g / 255.0, b / 255.0); + lastcolor = CBLEND(gc); + } + } +} + +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) +{ + use_gc(gc); + rnd_fprintf(global.f, "%mi %mi %mi %mi dr\n", x1, y1, x2, y2); +} + +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); +static void ps_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius); + +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) +{ +#if 0 + /* If you're etching your own paste mask, this will reduce the + amount of brass you need to etch by drawing outlines for large + pads. See also ps_fill_rect. */ + if (is_paste && gc->width > 2500 && gc->cap == rnd_cap_square && (x1 == x2 || y1 == y2)) { + rnd_coord_t t, w; + if (x1 > x2) { + t = x1; + x1 = x2; + x2 = t; + } + if (y1 > y2) { + t = y1; + y1 = y2; + y2 = t; + } + w = gc->width / 2; + ps_fill_rect(gc, x1 - w, y1 - w, x2 + w, y2 + w); + return; + } +#endif + if (x1 == x2 && y1 == y2) { + rnd_coord_t w = gc->width / 2; + if (gc->cap == rnd_cap_square) + ps_fill_rect(gc, x1 - w, y1 - w, x1 + w, y1 + w); + else + ps_fill_circle(gc, x1, y1, w); + return; + } + use_gc(gc); + rnd_fprintf(global.f, "%mi %mi %mi %mi t\n", 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_angle_t sa, ea; + double w; + + if ((width == 0) && (height == 0)) { + /* degenerate case, draw dot */ + ps_draw_line(gc, cx, cy, cx, cy); + return; + } + + if (delta_angle > 0) { + sa = start_angle; + ea = start_angle + delta_angle; + } + else { + sa = start_angle + delta_angle; + ea = start_angle; + } +#if 0 + printf("draw_arc %d,%d %dx%d %d..%d %d..%d\n", cx, cy, width, height, start_angle, delta_angle, sa, ea); +#endif + use_gc(gc); + w = width; + if (w == 0) /* make sure not to div by zero; this hack will have very similar effect */ + w = 0.0001; + rnd_fprintf(global.f, "%ma %ma %mi %mi %mi %mi %f a\n", + sa, ea, -width, height, cx, cy, (double)(global.linewidth) / w); +} + +static void ps_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + use_gc(gc); + if (!gc->erase || !global.is_copper || global.drillcopper) { + if (gc->erase && global.is_copper && global.drill_helper && radius >= global.drill_helper_size) + radius = global.drill_helper_size; + rnd_fprintf(global.f, "%mi %mi %mi c\n", 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) +{ + int i; + const char *op = "moveto"; + use_gc(gc); + for (i = 0; i < n_coords; i++) { + rnd_fprintf(global.f, "%mi %mi %s\n", x[i]+dx, y[i]+dy, op); + op = "lineto"; + } + fprintf(global.f, "fill\n"); +} + +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); +} + + +typedef struct { + rnd_coord_t x1, y1, x2, y2; +} lseg_t; + +typedef struct { + rnd_coord_t x, y; +} lpoint_t; + +#define minmax(val, min, max) \ +do { \ + if (val < min) min = val; \ + if (val > max) max = val; \ +} while(0) + +#define lsegs_append(x1_, y1_, x2_, y2_) \ +do { \ + if (y1_ < y2_) { \ + lsegs[lsegs_used].x1 = x1_; \ + lsegs[lsegs_used].y1 = y1_; \ + lsegs[lsegs_used].x2 = x2_; \ + lsegs[lsegs_used].y2 = y2_; \ + } \ + else { \ + lsegs[lsegs_used].x2 = x1_; \ + lsegs[lsegs_used].y2 = y1_; \ + lsegs[lsegs_used].x1 = x2_; \ + lsegs[lsegs_used].y1 = y2_; \ + } \ + lsegs_used++; \ + minmax(y1_, lsegs_ymin, lsegs_ymax); \ + minmax(y2_, lsegs_ymin, lsegs_ymax); \ + minmax(x1_, lsegs_xmin, lsegs_xmax); \ + minmax(x2_, lsegs_xmin, lsegs_xmax); \ +} while(0) + +#define lseg_line(x1_, y1_, x2_, y2_) \ + do { \ + fprintf(global.f, "newpath\n"); \ + rnd_fprintf(global.f, "%mi %mi moveto\n", x1_, y1_); \ + rnd_fprintf(global.f, "%mi %mi lineto\n", x2_, y2_); \ + fprintf (global.f, "stroke\n"); \ + } while(0) + +int coord_comp(const void *c1_, const void *c2_) +{ + const rnd_coord_t *c1 = c1_, *c2 = c2_; + return *c1 < *c2; +} + +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) +{ + use_gc(gc); + if (x1 > x2) { + rnd_coord_t t = x1; + x1 = x2; + x2 = t; + } + if (y1 > y2) { + rnd_coord_t t = y1; + y1 = y2; + y2 = t; + } +#if 0 + /* See comment in ps_draw_line. */ + if (is_paste && (x2 - x1) > 2500 && (y2 - y1) > 2500) { + linewidth = 1000; + lastcap = rnd_cap_round; + fprintf(f, "1000 setlinewidth 1 setlinecap 1 setlinejoin\n"); + fprintf(f, "%d %d moveto %d %d lineto %d %d lineto %d %d lineto closepath stroke\n", + x1 + 500 - bloat, y1 + 500 - bloat, + x1 + 500 - bloat, y2 - 500 + bloat, x2 - 500 + bloat, y2 - 500 + bloat, x2 - 500 + bloat, y1 + 500 - bloat); + return; + } +#endif + rnd_fprintf(global.f, "%mi %mi %mi %mi r\n", x1, y1, x2, y2); +} + +rnd_hid_attribute_t ps_calib_attribute_list[] = { + {"lprcommand", "Command to print", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +}; + +static const char *const calib_lines[] = { + "%!PS-Adobe-3.0\n", + "%%Title: Calibration Page\n", + "%%PageOrder: Ascend\n", + "%%Pages: 1\n", + "%%EndComments\n", + "\n", + "%%Page: Calibrate 1\n", + "72 72 scale\n", + "\n", + "0 setlinewidth\n", + "0.375 0.375 moveto\n", + "8.125 0.375 lineto\n", + "8.125 10.625 lineto\n", + "0.375 10.625 lineto\n", + "closepath stroke\n", + "\n", + "0.5 0.5 translate\n", + "0.001 setlinewidth\n", + "\n", + "/Times-Roman findfont 0.2 scalefont setfont\n", + "\n", + "/sign {\n", + " 0 lt { -1 } { 1 } ifelse\n", + "} def\n", + "\n", + "/cbar {\n", + " /units exch def\n", + " /x exch def\n", + " /y exch def \n", + "\n", + " /x x sign 0.5 mul def\n", + "\n", + " 0 setlinewidth\n", + " newpath x y 0.25 0 180 arc gsave 0.85 setgray fill grestore closepath stroke\n", + " newpath x 0 0.25 180 360 arc gsave 0.85 setgray fill grestore closepath stroke\n", + " 0.001 setlinewidth\n", + "\n", + " x 0 moveto\n", + " x y lineto\n", + "% -0.07 -0.2 rlineto 0.14 0 rmoveto -0.07 0.2 rlineto\n", + " x y lineto\n", + " -0.1 0 rlineto 0.2 0 rlineto\n", + " stroke\n", + " x 0 moveto\n", + "% -0.07 0.2 rlineto 0.14 0 rmoveto -0.07 -0.2 rlineto\n", + " x 0 moveto\n", + " -0.1 0 rlineto 0.2 0 rlineto\n", + " stroke\n", + "\n", + " x 0.1 add\n", + " y 0.2 sub moveto\n", + " units show\n", + "} bind def\n", + "\n", + "/y 9 def\n", + "/t {\n", + " /str exch def\n", + " 1.5 y moveto str show\n", + " /y y 0.25 sub def\n", + "} bind def\n", + "\n", + "(Please measure ONE of the horizontal lines, in the units indicated for)t\n", + "(that line, and enter that value as X. Similarly, measure ONE of the)t\n", + "(vertical lines and enter that value as Y. Measurements should be)t\n", + "(between the flat faces of the semicircles.)t\n", + "()t\n", + "(The large box is 10.25 by 7.75 inches)t\n", + "\n", + "/in { } bind def\n", + "/cm { 2.54 div } bind def\n", + "/mm { 25.4 div } bind def\n", + "\n", + 0 +}; + +static int guess(double val, double close_to, double *calib) +{ + if (val >= close_to * 0.9 && val <= close_to * 1.1) { + *calib = close_to / val; + return 0; + } + return 1; +} + +void ps_calibrate_1(rnd_hid_t *hid, double xval, double yval, int use_command) +{ + FILE *ps_cal_file; + int used_popen = 0, c; + + if (xval > 0 && yval > 0) { + if (guess(xval, 4, &global.calibration_x)) + if (guess(xval, 15, &global.calibration_x)) + if (guess(xval, 7.5, &global.calibration_x)) { + if (xval < 2) + ps_attribute_list[HA_xcalib].default_val.dbl = global.calibration_x = xval; + else + rnd_message(RND_MSG_ERROR, "X value of %g is too far off.\n" "Expecting it near: 1.0, 4.0, 15.0, 7.5\n", xval); + } + if (guess(yval, 4, &global.calibration_y)) + if (guess(yval, 20, &global.calibration_y)) + if (guess(yval, 10, &global.calibration_y)) { + if (yval < 2) + ps_attribute_list[HA_ycalib].default_val.dbl = global.calibration_y = yval; + else + rnd_message(RND_MSG_ERROR, "Y value of %g is too far off.\n" "Expecting it near: 1.0, 4.0, 20.0, 10.0\n", yval); + } + return; + } + + if (ps_calib_attribute_list[0].val.str == NULL) { + ps_calib_attribute_list[0].val.str = rnd_strdup("lpr"); + } + + if (rnd_attribute_dialog("ps_calibrate", ps_calib_attribute_list, 1, "Print Calibration Page", NULL)) + return; + + if (ps_calib_attribute_list[0].val.str == NULL) + return; + + if (use_command || strchr(ps_calib_attribute_list[0].val.str, '|')) { + const char *cmd = ps_calib_attribute_list[0].val.str; + while (*cmd == ' ' || *cmd == '|') + cmd++; + ps_cal_file = rnd_popen(&PCB->hidlib, cmd, "w"); + used_popen = 1; + } + else + ps_cal_file = rnd_fopen(&PCB->hidlib, ps_calib_attribute_list[0].val.str, "w"); + + for (c = 0; calib_lines[c]; c++) + fputs(calib_lines[c], ps_cal_file); + + fprintf(ps_cal_file, "4 in 0.5 (Y in) cbar\n"); + fprintf(ps_cal_file, "20 cm 1.5 (Y cm) cbar\n"); + fprintf(ps_cal_file, "10 in 2.5 (Y in) cbar\n"); + fprintf(ps_cal_file, "-90 rotate\n"); + fprintf(ps_cal_file, "4 in -0.5 (X in) cbar\n"); + fprintf(ps_cal_file, "15 cm -1.5 (X cm) cbar\n"); + fprintf(ps_cal_file, "7.5 in -2.5 (X in) cbar\n"); + + fprintf(ps_cal_file, "showpage\n"); + + fprintf(ps_cal_file, "%%%%EOF\n"); + + if (used_popen) + rnd_pclose(ps_cal_file); + else + fclose(ps_cal_file); +} + +static void ps_calibrate(rnd_hid_t *hid, double xval, double yval) +{ + ps_calibrate_1(hid, xval, yval, 0); +} + +static void ps_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int action) +{ +} + +rnd_hid_t ps_hid; + +static fgw_error_t pcb_act_PSCalib(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + ps_calibrate(&ps_hid, 0.0, 0.0); + return 0; +} + +rnd_action_t hidps_action_list[] = { + {"pscalib", pcb_act_PSCalib, NULL, NULL} +}; + +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 = ps_make_gc; + hid->destroy_gc = ps_destroy_gc; + hid->set_drawing_mode = ps_set_drawing_mode; + hid->set_color = ps_set_color; + hid->set_line_cap = ps_set_line_cap; + hid->set_line_width = ps_set_line_width; + hid->set_draw_xor = ps_set_draw_xor; + hid->set_draw_faded = ps_set_draw_faded; + 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->calibrate = ps_calibrate; + hid->set_crosshair = ps_set_crosshair; + + RND_REGISTER_ACTIONS(hidps_action_list, ps_cookie) + + 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: pcb-rnd [generic_options] -x ps [ps options] foo.pcb\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; +} + + +int pplg_check_ver_export_ps(int ver_needed) { return 0; } + +void pplg_uninit_export_ps(void) +{ + plugin_ps_uninit(); + rnd_hid_remove_hid(&ps_hid); + hid_eps_uninit(); +} + +int pplg_init_export_ps(void) +{ + RND_API_CHK_VER; + 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.usage = ps_usage; + + rnd_hid_register_hid(&ps_hid); + + hid_eps_init(); + return 0; +} Index: tags/2.3.0/src_plugins/export_ps/ps.h =================================================================== --- tags/2.3.0/src_plugins/export_ps/ps.h (nonexistent) +++ tags/2.3.0/src_plugins/export_ps/ps.h (revision 33253) @@ -0,0 +1,8 @@ +extern const char *ps_cookie; +extern rnd_hid_t ps_hid; +extern void ps_hid_export_to_file(FILE *, rnd_hid_attr_val_t *, rnd_xform_t *); +extern void ps_start_file(FILE *); +extern void ps_calibrate_1(rnd_hid_t *hid, double, double, int); +extern void hid_eps_init(); +extern void hid_eps_uninit(); +void ps_ps_init(rnd_hid_t * hid); Index: tags/2.3.0/src_plugins/export_stat/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_stat/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_stat/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_stat + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_stat/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_stat/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_stat/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {export_stat} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_stat/stat.o @] + +switch /local/pcb/export_stat/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_stat/export_stat.pup =================================================================== --- tags/2.3.0/src_plugins/export_stat/export_stat.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_stat/export_stat.pup (revision 33253) @@ -0,0 +1,9 @@ +$class export +$short export board statistics +$long Export various board statistics in lihata format +$state works +$fmt-native no +$fmt-feature-w anonimized board statistics in lihata +$package export +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_stat/stat.c =================================================================== --- tags/2.3.0/src_plugins/export_stat/stat.c (nonexistent) +++ tags/2.3.0/src_plugins/export_stat/stat.c (revision 33253) @@ -0,0 +1,425 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2006 Dan McMahill + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* + * Based on the png exporter by Dan McMahill + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "board.h" +#include "data.h" +#include "data_it.h" +#include "netlist.h" +#include +#include +#include +#include "plug_io.h" +#include +#include "obj_pstk_inlines.h" + +#include +#include + +#include +#include +#include "hid_cam.h" + + +static rnd_hid_t stat_hid; + +const char *stat_cookie = "stat HID"; + +rnd_export_opt_t stat_attribute_list[] = { + /* other HIDs expect this to be first. */ + + {"outfile", "Output file name", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_statfile 0 + + {"board_id", "Short name of the board so it can be identified for updates", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_board_id 1 + + {"orig", "This design started its life in pcb-rnd", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_orig 2 + + {"lht_built", "This design was already in lihata when real boards got built", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_lht_built 3 + + + {"built", "how many actual/physical boards got built", + RND_HATT_INTEGER, 0, 1000000, {0, 0, 0}, 0, 0}, +#define HA_built 4 + + {"first_ver", "the version of pcb-rnd you first used on this board", + RND_HATT_STRING, 0, 0, {0, NULL, 0}, 0, 0}, +#define HA_first_ver 5 + + {"license", "license of the design", + RND_HATT_STRING, 0, 0, {0, NULL, 0}, 0, 0}, +#define HA_license 6 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 7 + +}; + +#define NUM_OPTIONS (sizeof(stat_attribute_list)/sizeof(stat_attribute_list[0])) + +static rnd_hid_attr_val_t stat_values[NUM_OPTIONS]; + +static rnd_export_opt_t *stat_get_export_options(rnd_hid_t *hid, int *n) +{ + const char *suffix = ".stat.lht"; + + if ((PCB != NULL) && (stat_attribute_list[HA_statfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &stat_attribute_list[HA_statfile], suffix); + + if (n) + *n = NUM_OPTIONS; + return stat_attribute_list; +} + +typedef struct layer_stat_s { + rnd_coord_t trace_len; + double copper_area; + unsigned long int lines, arcs, polys, elements; +} layer_stat_t; + +static void stat_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + FILE *f; + const char *filename; + int i, lid; + rnd_layergrp_id_t lgid; + char buff[1024]; + layer_stat_t ls, *lgs, lgss[PCB_MAX_LAYERGRP]; + int nl, phg, hp, hup, group_not_empty[PCB_MAX_LAYERGRP]; + rnd_cardinal_t num_etop = 0, num_ebottom = 0, num_esmd = 0, num_epads = 0, num_epins = 0, num_terms = 0, num_slots = 0; + rnd_coord_t width, height; + pcb_cam_t cam; + + memset(lgss, 0, sizeof(lgss)); + memset(group_not_empty, 0, sizeof(group_not_empty)); + + if (!options) { + stat_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + stat_values[i] = stat_attribute_list[i].default_val; + options = stat_values; + } + + filename = options[HA_statfile].str; + if (!filename) + filename = "pcb.stat.lht"; + + pcb_cam_begin_nolayer(PCB, &cam, NULL, options[HA_cam].str, &filename); + + f = rnd_fopen_askovr(&PCB->hidlib, filename, "w", NULL); + if (!f) { + perror(filename); + return; + } + + pcb_board_count_holes(PCB, &hp, &hup, NULL); + rnd_print_utc(buff, sizeof(buff), 0); + + fprintf(f, "ha:pcb-rnd-board-stats-v2 {\n"); + fprintf(f, " ha:meta {\n"); + fprintf(f, " date={%s}\n", buff); + fprintf(f, " built=%ld\n", options[HA_built].lng); + fprintf(f, " lht_built=%s\n", (options[HA_lht_built].lng ? "yes" : "no")); + fprintf(f, " orig_rnd=%s\n", (options[HA_orig].lng ? "yes" : "no")); + fprintf(f, " first_ver=%s\n", options[HA_first_ver].str); + fprintf(f, " curr_ver=%s\n", PCB_VERSION); +#ifdef PCB_REVISION + fprintf(f, " curr_rev=%s\n", PCB_REVISION); +#endif + + fprintf(f, " }\n"); + + fprintf(f, " li:logical_layers {\n"); + for(lid = 0; lid < pcb_max_layer(PCB); lid++) { + pcb_layer_t *l = PCB->Data->Layer+lid; + int empty = pcb_layer_is_empty_(PCB, l); + unsigned int lflg = pcb_layer_flags(PCB, lid); + + lgid = pcb_layer_get_group(PCB, lid); + lgs = lgss + lgid; + + fprintf(f, " ha:layer_%d {\n", lid); + fprintf(f, " name={%s}\n", l->name); + fprintf(f, " empty=%s\n", empty ? "yes" : "no"); + fprintf(f, " flags=%x\n", lflg); + fprintf(f, " grp=%ld\n", lgid); + + if (lflg & PCB_LYT_COPPER) { + memset(&ls, 0, sizeof(ls)); + + PCB_LINE_LOOP(l) { + rnd_coord_t v; + double d; + lgs->lines++; + ls.lines++; + v = pcb_line_length(line); + ls.trace_len += v; + lgs->trace_len += v; + d = pcb_line_area(line); + ls.copper_area += d; + lgs->copper_area += d; + + } + PCB_END_LOOP; + + PCB_ARC_LOOP(l) { + rnd_coord_t v; + double d; + lgs->arcs++; + ls.arcs++; + v = pcb_arc_length(arc); + ls.trace_len += v; + lgs->trace_len += v; + d = pcb_arc_area(arc); + ls.copper_area += d; + lgs->copper_area += d; + } + PCB_END_LOOP; + + PCB_POLY_LOOP(l) { + double v; + lgs->polys++; + ls.polys++; + v = pcb_poly_area(polygon); + ls.copper_area += v; + lgs->copper_area += v; + } + PCB_END_LOOP; + + if (!empty) + group_not_empty[lgid] = 1; + + fprintf(f, " lines=%lu\n", ls.lines); + fprintf(f, " arcs=%lu\n", ls.arcs); + fprintf(f, " polys=%lu\n", ls.polys); + rnd_fprintf(f, " trace_len=%$mm\n", ls.trace_len); + fprintf(f, " copper_area={%f mm^2}\n", (double)ls.copper_area / (double)RND_MM_TO_COORD(1) / (double)RND_MM_TO_COORD(1)); + } + fprintf(f, " }\n"); + } + fprintf(f, " }\n"); + + phg = 0; + fprintf(f, " li:physical_layers {\n"); + for(lgid = 0; lgid < pcb_max_group(PCB); lgid++) { + if (group_not_empty[lgid]) { + phg++; + fprintf(f, " ha:layergroup_%ld {\n", lgid); + fprintf(f, " lines=%lu\n", lgss[lgid].lines); + fprintf(f, " arcs=%lu\n", lgss[lgid].arcs); + fprintf(f, " polys=%lu\n", lgss[lgid].polys); + rnd_fprintf(f, " trace_len=%$mm\n", lgss[lgid].trace_len); + fprintf(f, " copper_area={%f mm^2}\n", (double)lgss[lgid].copper_area / (double)RND_MM_TO_COORD(1) / (double)RND_MM_TO_COORD(1)); + fprintf(f, " }\n"); + } + } + fprintf(f, " }\n"); + + fprintf(f, " li:netlist {\n"); + for(nl = 0; nl < PCB_NUM_NETLISTS; nl++) { + htsp_entry_t *e; + rnd_cardinal_t terms = 0, best_terms = 0; + fprintf(f, " ha:%s {\n", pcb_netlist_names[nl]); + + for(e = htsp_first(&PCB->netlist[nl]); e != NULL; e = htsp_next(&PCB->netlist[nl], e)) { + pcb_net_t *net = e->value; + long numt = pcb_termlist_length(&net->conns); + + terms += numt; + if (numt > best_terms) + best_terms = numt; + } + fprintf(f, " nets=%ld\n", (long int)PCB->netlist[nl].used); + fprintf(f, " terminals=%ld\n", (long int)terms); + fprintf(f, " max_term_per_net=%ld\n", (long int)best_terms); + fprintf(f, " }\n"); + } + fprintf(f, " }\n"); + + PCB_SUBC_LOOP(PCB->Data) { + int bott; + rnd_cardinal_t slot = 0, hole = 0, all = 0; + pcb_any_obj_t *o; + pcb_data_it_t it; + htsi_t t; + htsi_entry_t *e; + + if (pcb_subc_get_side(subc, &bott) == 0) { + if (bott) + num_ebottom++; + else + num_etop++; + } + + /* count each terminal ID only once, because of heavy terminals */ + htsi_init(&t, strhash, strkeyeq); + for(o = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + if (o->term != NULL) { + htsi_set(&t, (char *)o->term, 1); + if (o->type == PCB_OBJ_PSTK) { + pcb_pstk_proto_t *proto = pcb_pstk_get_proto((pcb_pstk_t *)o); + if ((proto != NULL) && (proto->hdia > 0)) + hole++; + if ((proto != NULL) && (proto->mech_idx >= 0)) { + hole++; + slot++; + num_slots++; + } + } + } + } + + for (e = htsi_first(&t); e != NULL; e = htsi_next(&t, e)) { + num_terms++; + all++; + } + + /* a part is considered smd if it has at most half as many holes as terminals total */ + if ((hole*2 + slot*2) < all) + num_esmd++; + + htsi_uninit(&t); + } + PCB_END_LOOP; + + if (pcb_has_explicit_outline(PCB)) { + rnd_box_t bb; + pcb_data_bbox_naked(&bb, PCB->Data, rnd_true); + width = bb.X2 - bb.X1; + height = bb.Y2 - bb.Y1; + } + else { + width = PCB->hidlib.size_x; + height = PCB->hidlib.size_y; + } + + fprintf(f, " ha:board {\n"); + fprintf(f, " id={%s}\n", options[HA_board_id].str == NULL ? "" : options[HA_board_id].str); + fprintf(f, " license={%s}\n", options[HA_license].str); + fprintf(f, " format={%s}\n", PCB->Data->loader == NULL ? "unknown" : PCB->Data->loader->description); + rnd_fprintf(f, " width=%$mm\n", width); + rnd_fprintf(f, " height=%$mm\n", height); + fprintf(f, " gross_area={%.4f mm^2}\n", (double)RND_COORD_TO_MM(width) * (double)RND_COORD_TO_MM(height)); + fprintf(f, " holes_plated=%d\n", hp); + fprintf(f, " holes_unplated=%d\n", hup); + fprintf(f, " physical_copper_layers=%d\n", phg); + fprintf(f, " ha:subcircuits {\n"); + fprintf(f, " total=%ld\n", (long int)num_ebottom + num_etop); + fprintf(f, " top_side=%ld\n", (long int)num_etop); + fprintf(f, " bottom_side=%ld\n", (long int)num_ebottom); + fprintf(f, " smd=%ld\n", (long int)num_esmd); + fprintf(f, " pads=%ld\n", (long int)num_epads); + fprintf(f, " pins=%ld\n", (long int)num_epins); + fprintf(f, " terms=%ld\n", (long int)num_terms); + fprintf(f, " slots=%ld\n", (long int)num_slots); + fprintf(f, " }\n"); + fprintf(f, " }\n"); + + fprintf(f, "}\n"); + fclose(f); + pcb_cam_end(&cam); +} + +static int stat_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(stat_attribute_list, sizeof(stat_attribute_list) / sizeof(stat_attribute_list[0]), stat_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static int stat_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nstat exporter command line arguments:\n\n"); + rnd_hid_usage(stat_attribute_list, sizeof(stat_attribute_list) / sizeof(stat_attribute_list[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x stat [stat options] foo.pcb\n\n"); + return 0; +} + +int pplg_check_ver_export_stat(int ver_needed) { return 0; } + +void pplg_uninit_export_stat(void) +{ + free((char *)stat_attribute_list[HA_first_ver].default_val.str); + free((char *)stat_attribute_list[HA_license].default_val.str); + stat_attribute_list[HA_first_ver].default_val.str = NULL; + stat_attribute_list[HA_license].default_val.str = NULL; + rnd_export_remove_opts_by_cookie(stat_cookie); + rnd_hid_remove_hid(&stat_hid); +} + +int pplg_init_export_stat(void) +{ + RND_API_CHK_VER; + + memset(&stat_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&stat_hid); + + stat_hid.struct_size = sizeof(rnd_hid_t); + stat_hid.name = "stat"; + stat_hid.description = "board statistics"; + stat_hid.exporter = 1; + + stat_hid.get_export_options = stat_get_export_options; + stat_hid.do_export = stat_do_export; + stat_hid.parse_arguments = stat_parse_arguments; + + stat_hid.usage = stat_usage; + + stat_attribute_list[HA_first_ver].default_val.str = rnd_strdup(PCB_VERSION); + stat_attribute_list[HA_license].default_val.str = rnd_strdup("proprietary/private"); + + rnd_hid_register_hid(&stat_hid); + + return 0; +} Index: tags/2.3.0/src_plugins/export_stl/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_stl/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_stl/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_stl + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_stl/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_stl/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_stl/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {export_stl} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_stl/export_stl.o @] + +switch /local/pcb/export_stl/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_stl/export_stl.c =================================================================== --- tags/2.3.0/src_plugins/export_stl/export_stl.c (nonexistent) +++ tags/2.3.0/src_plugins/export_stl/export_stl.c (revision 33253) @@ -0,0 +1,558 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include "hid_cam.h" +#include +#include +#include +#include +#include +#include +#include "data.h" +#include "funchash_core.h" +#include "layer.h" +#include "obj_pstk_inlines.h" +#include "plug_io.h" +#include "conf_core.h" + +#include "../lib_polyhelp/topoly.h" +#include "../lib_polyhelp/triangulate.h" + +static rnd_hid_t stl_hid; +const char *stl_cookie = "export_stl HID"; + +rnd_export_opt_t stl_attribute_list[] = { + {"outfile", "STL output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_stlfile 0 + + {"models", "enable searching and inserting model files", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_models 1 + + {"min-drill", "minimum circular hole diameter to render (smaller ones are not drawn)", + RND_HATT_COORD, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_mindrill 2 + + {"min-slot-line", "minimum thickness of padstakc slots specified as lines (smaller ones are not drawn)", + RND_HATT_COORD, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_minline 3 + + {"slot-poly", "draw cutouts for slots specified as padstack polygons", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_slotpoly 4 + + {"cutouts", "draw cutouts drawn on 'route' layer groups (outline/slot mech layer groups)", + RND_HATT_BOOL, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_cutouts 5 + + {"override-thickness", "override calculated board thickness (when non-zero)", + RND_HATT_COORD, 0, 0, {1, 0, 0}, 0, 0}, +#define HA_ovrthick 6 + + {"z-center", "when true: z=0 is the center of board cross section, instead of being at the bottom side", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_zcent 7 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 8 +}; + +#define NUM_OPTIONS (sizeof(stl_attribute_list)/sizeof(stl_attribute_list[0])) + +static rnd_hid_attr_val_t stl_values[NUM_OPTIONS]; + +static rnd_export_opt_t *stl_get_export_options(rnd_hid_t *hid, int *n) +{ + const char *suffix = ".stl"; + + if ((PCB != NULL) && (stl_attribute_list[HA_stlfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &stl_attribute_list[HA_stlfile], suffix); + + if (n) + *n = NUM_OPTIONS; + return stl_attribute_list; +} + +static void stl_print_horiz_tri(FILE *f, fp2t_triangle_t *t, int up, rnd_coord_t z) +{ + fprintf(f, " facet normal 0 0 %d\n", up ? 1 : -1); + fprintf(f, " outer loop\n"); + + if (up) { + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", (rnd_coord_t)t->Points[0]->X, (rnd_coord_t)t->Points[0]->Y, z); + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", (rnd_coord_t)t->Points[1]->X, (rnd_coord_t)t->Points[1]->Y, z); + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", (rnd_coord_t)t->Points[2]->X, (rnd_coord_t)t->Points[2]->Y, z); + } + else { + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", (rnd_coord_t)t->Points[2]->X, (rnd_coord_t)t->Points[2]->Y, z); + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", (rnd_coord_t)t->Points[1]->X, (rnd_coord_t)t->Points[1]->Y, z); + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", (rnd_coord_t)t->Points[0]->X, (rnd_coord_t)t->Points[0]->Y, z); + } + + fprintf(f, " endloop\n"); + fprintf(f, " endfacet\n"); +} + +static void stl_print_vert_tri(FILE *f, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t z0, rnd_coord_t z1) +{ + double vx, vy, nx, ny, len; + + vx = x2 - x1; vy = y2 - y1; + len = sqrt(vx*vx + vy*vy); + if (len == 0) return; + vx /= len; vy /= len; + nx = -vy; ny = vx; + + fprintf(f, " facet normal %f %f 0\n", nx, ny); + fprintf(f, " outer loop\n"); + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", x2, y2, z1); + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", x1, y1, z1); + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", x1, y1, z0); + fprintf(f, " endloop\n"); + fprintf(f, " endfacet\n"); + + fprintf(f, " facet normal %f %f 0\n", nx, ny); + fprintf(f, " outer loop\n"); + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", x2, y2, z1); + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", x1, y1, z0); + rnd_fprintf(f, " vertex %.09mm %.09mm %.09mm\n", x2, y2, z0); + fprintf(f, " endloop\n"); + fprintf(f, " endfacet\n"); +} + +static long pa_len(const rnd_polyarea_t *pa) +{ + rnd_pline_t *pl; + rnd_vnode_t *n; + long cnt = 0; + + pl = pa->contours; + n = pl->head; + do { + cnt++; + n = n->next; + } while(n != pl->head); + return cnt; +} + +static long poly_len(const pcb_poly_t *poly) +{ + return poly->PointN; /* assume no holes */ +} + +static int pstk_points(pcb_board_t *pcb, pcb_pstk_t *pstk, pcb_layer_t *layer, fp2t_t *tri, rnd_coord_t maxy, vtd0_t *contours, rnd_hid_attr_val_t *options) +{ + pcb_pstk_shape_t *shp, tmp; + rnd_polyarea_t *pa = NULL; + int segs = 0; + + shp = pcb_pstk_shape_mech_or_hole_at(pcb, pstk, layer, &tmp); + if (shp == NULL) + return 0; + + switch(shp->shape) { + case PCB_PSSH_POLY: + if (!options[HA_slotpoly].lng) + return 0; + segs = shp->data.poly.len; + break; + case PCB_PSSH_CIRC: + if (shp->data.circ.dia < options[HA_mindrill].crd) + return 0; + segs = RND_COORD_TO_MM(shp->data.circ.dia)*8+6; + break; + case PCB_PSSH_HSHADOW: return 0; + case PCB_PSSH_LINE: + if (shp->data.line.thickness < options[HA_minline].crd) + return 0; + + { + pcb_line_t l = {0}; + l.Point1.X = pstk->x + shp->data.line.x1; l.Point1.Y = pstk->y + shp->data.line.y1; + l.Point2.X = pstk->x + shp->data.line.x2; l.Point2.Y = pstk->y + shp->data.line.y2; + l.Thickness = shp->data.line.thickness; + if (shp->data.line.square) + PCB_FLAG_SET(PCB_FLAG_SQUARE, &l); + pa = pcb_poly_from_pcb_line(&l, l.Thickness); + segs += pa_len(pa); + } + break; + } + + if (tri != NULL) { + switch(shp->shape) { + case PCB_PSSH_POLY: + { + int n; + for(n = 0; n < shp->data.poly.len; n++) { + fp2t_point_t *pt = fp2t_push_point(tri); + pt->X = pstk->x + shp->data.poly.x[n]; + pt->Y = maxy - (pstk->y + shp->data.poly.y[n]); + vtd0_append(contours, pt->X); + vtd0_append(contours, pt->Y); + } + fp2t_add_hole(tri); + vtd0_append(contours, HUGE_VAL); + vtd0_append(contours, HUGE_VAL); + } + break; + case PCB_PSSH_LINE: + { + rnd_pline_t *pl = pa->contours; + rnd_vnode_t *n = pl->head; + do { + fp2t_point_t *pt = fp2t_push_point(tri); + pt->X = n->point[0]; + pt->Y = maxy - n->point[1]; + vtd0_append(contours, pt->X); + vtd0_append(contours, pt->Y); + n = n->next; + } while(n != pl->head); + fp2t_add_hole(tri); + vtd0_append(contours, HUGE_VAL); + vtd0_append(contours, HUGE_VAL); + } + break; + case PCB_PSSH_CIRC: + { + double a, step = 2*M_PI/segs, r = (double)shp->data.circ.dia / 2.0; + int n; + for(n = 0, a = 0; n < segs; n++, a += step) { + fp2t_point_t *pt = fp2t_push_point(tri); + pt->X = pstk->x + shp->data.circ.x + rnd_round(cos(a) * r); + pt->Y = maxy - (pstk->y + shp->data.circ.y + rnd_round(sin(a) * r)); + vtd0_append(contours, pt->X); + vtd0_append(contours, pt->Y); + } + fp2t_add_hole(tri); + vtd0_append(contours, HUGE_VAL); + vtd0_append(contours, HUGE_VAL); + } + case PCB_PSSH_HSHADOW: return 0; + } + } + + if (pa != NULL) + rnd_polyarea_free(&pa); + + return segs; +} + +static void add_holes_pstk(fp2t_t *tri, pcb_board_t *pcb, pcb_layer_t *toply, rnd_coord_t maxy, vtd0_t *contours, rnd_hid_attr_val_t *options, pcb_dynf_t df) +{ + rnd_rtree_it_t it; + rnd_box_t *n; + + for(n = rnd_r_first(pcb->Data->padstack_tree, &it); n != NULL; n = rnd_r_next(&it)) { + pcb_pstk_t *ps = (pcb_pstk_t *)n; + if (!PCB_DFLAG_TEST(&ps->Flags, df)) /* if a padstack is marked, it is on the contour and it should already be subtracted from the contour poly, skip it */ + pstk_points(pcb, ps, toply, tri, maxy, contours, options); + } +} + +static long estimate_hole_pts_pstk(pcb_board_t *pcb, pcb_layer_t *toply, rnd_hid_attr_val_t *options) +{ + rnd_rtree_it_t it; + rnd_box_t *n; + long cnt = 0; + + for(n = rnd_r_first(pcb->Data->padstack_tree, &it); n != NULL; n = rnd_r_next(&it)) { + pcb_pstk_t *ps = (pcb_pstk_t *)n; + cnt += pstk_points(pcb, ps, toply, NULL, 0, NULL, options); + } + + return cnt; +} + +static long estimate_cutout_pts(pcb_board_t *pcb, vtp0_t *cutouts, pcb_dynf_t df, rnd_hid_attr_val_t *options) +{ + rnd_layer_id_t lid; + long cnt = 0; + + if (!options[HA_cutouts].lng) + return 0; + + for(lid = 0; lid < pcb->Data->LayerN; lid++) { + pcb_layer_type_t lyt = pcb_layer_flags(pcb, lid); + int purpi = pcb_layer_purpose(pcb, lid, NULL); + pcb_layer_t *layer = &pcb->Data->Layer[lid]; + pcb_poly_t *poly; + + if (!PCB_LAYER_IS_ROUTE(lyt, purpi)) continue; +/* rnd_trace("Outline [%ld]\n", lid);*/ + PCB_LINE_LOOP(layer) { + if (PCB_DFLAG_TEST(&line->Flags, df)) continue; /* object already found - either as outline or as a cutout */ + poly = pcb_topoly_conn_with(pcb, (pcb_any_obj_t *)line, PCB_TOPOLY_FLOATING, df); + vtp0_append(cutouts, poly); + cnt += poly_len(poly); +/* rnd_trace(" line: %ld %d -> %p\n", line->ID, PCB_DFLAG_TEST(&line->Flags, df), poly);*/ + } PCB_END_LOOP; + PCB_ARC_LOOP(layer) { + if (PCB_DFLAG_TEST(&arc->Flags, df)) continue; /* object already found - either as outline or as a cutout */ + poly = pcb_topoly_conn_with(pcb, (pcb_any_obj_t *)arc, PCB_TOPOLY_FLOATING, df); + vtp0_append(cutouts, poly); + cnt += poly_len(poly); +/* rnd_trace(" arc: %ld %d -> %p\n", arc->ID, PCB_DFLAG_TEST(&arc->Flags, df), poly);*/ + } PCB_END_LOOP; + } + return cnt; +} + +static void add_holes_cutout(fp2t_t *tri, pcb_board_t *pcb, rnd_coord_t maxy, vtp0_t *cutouts, vtd0_t *contours, rnd_hid_attr_val_t *options) +{ + long np; + + if (!options[HA_cutouts].lng) + return; + + for(np = 0; np < cutouts->used; np++) { + pcb_poly_t *poly = cutouts->array[np]; + int n; + + for(n = 0; n < poly->PointN; n++) { + fp2t_point_t *pt = fp2t_push_point(tri); + pt->X = poly->Points[n].X; + pt->Y = maxy - poly->Points[n].Y; + vtd0_append(contours, pt->X); + vtd0_append(contours, pt->Y); + } + + fp2t_add_hole(tri); + vtd0_append(contours, HUGE_VAL); + vtd0_append(contours, HUGE_VAL); + } +} + +#include "stl_models.c" + +int stl_hid_export_to_file(FILE *f, rnd_hid_attr_val_t *options, rnd_coord_t maxy, rnd_coord_t z0, rnd_coord_t z1) +{ + pcb_dynf_t df; + pcb_poly_t *brdpoly; + size_t mem_req; + void *mem; + fp2t_t tri; + long cn_start, cn, n, pstk_points, cutout_points; + rnd_layer_id_t lid = -1; + pcb_layer_t *toply; + vtd0_t contours = {0}; + vtp0_t cutouts = {0}; + long contlen; + rnd_vnode_t *vn; + rnd_pline_t *pl; + + if ((pcb_layer_list(PCB, PCB_LYT_COPPER | PCB_LYT_TOP, &lid, 1) != 1) && (pcb_layer_list(PCB, PCB_LYT_COPPER | PCB_LYT_BOTTOM, &lid, 1) != 1)) { + rnd_message(RND_MSG_ERROR, "A top or bottom copper layer is required for stl export\n"); + return -1; + } + toply = pcb_get_layer(PCB->Data, lid); + + + df = pcb_dynflag_alloc("export_stl_map_contour"); + pcb_data_dynflag_clear(PCB->Data, df); + brdpoly = pcb_topoly_1st_outline_with(PCB, PCB_TOPOLY_FLOATING, df); + + pstk_points = estimate_hole_pts_pstk(PCB, toply, options); + cutout_points = estimate_cutout_pts(PCB, &cutouts, df, options); + + contlen = pa_len(brdpoly->Clipped); + mem_req = fp2t_memory_required(contlen + pstk_points + cutout_points); + mem = calloc(mem_req, 1); + if (!fp2t_init(&tri, mem, contlen + pstk_points)) { + free(mem); + pcb_poly_free(brdpoly); + pcb_dynflag_free(df); + return -1; + } + + /* there are no holes in the brdpoly so this simple approach for determining + the number of contour points works (cutouts are applied separately on + the triangulation lib level) */ +/* pn = contlen;*/ + pl = brdpoly->Clipped->contours; + vn = pl->head; + n = 0; + do { + fp2t_point_t *pt = fp2t_push_point(&tri); + pt->X = vn->point[0]; + pt->Y = maxy - vn->point[1]; + vtd0_append(&contours, pt->X); + vtd0_append(&contours, pt->Y); + vn = vn->next; + n++; + } while(vn != pl->head); + + fp2t_add_edge(&tri); + vtd0_append(&contours, HUGE_VAL); + vtd0_append(&contours, HUGE_VAL); + + add_holes_pstk(&tri, PCB, toply, maxy, &contours, options, df); + add_holes_cutout(&tri, PCB, maxy, &cutouts, &contours, options); + + fp2t_triangulate(&tri); + + fprintf(f, "solid pcb\n"); + + /* write the top and bottom plane */ + for(n = 0; n < tri.TriangleCount; n++) { + stl_print_horiz_tri(f, tri.Triangles[n], 0, z0); + stl_print_horiz_tri(f, tri.Triangles[n], 1, z1); + } + + /* write the vertical side */ + for(cn_start = 0, cn = 2; cn < contours.used; cn+=2) { + if (contours.array[cn] == HUGE_VAL) { + double cx, cy, px, py; + long n, pn; +/* rnd_trace("contour: %ld..%ld\n", cn_start, cn);*/ + for(n = cn-2; n >= cn_start; n-=2) { + pn = n-2; + if (pn < cn_start) + pn = cn-2; + px = contours.array[pn], py = contours.array[pn+1]; + cx = contours.array[n], cy = contours.array[n+1]; +/* rnd_trace(" [%ld <- %ld] c:%f;%f p:%f;%f\n", n, pn, cx/1000000.0, cy/1000000.0, px/1000000.0, py/1000000.0);*/ + stl_print_vert_tri(f, cx, cy, px, py, z0, z1); + } + cn += 2; + cn_start = cn; + } + } + + if (options[HA_models].lng) + stl_models_print(PCB, f, maxy, z0, z1); + + fprintf(f, "endsolid\n"); + + vtp0_uninit(&cutouts); + for(n = 0; n < cutouts.used; n++) + pcb_poly_free((pcb_poly_t *)cutouts.array[n]); + vtd0_uninit(&contours); + free(mem); + pcb_poly_free(brdpoly); + pcb_dynflag_free(df); + return 0; +} + +static void stl_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + const char *filename; + int i; + pcb_cam_t cam; + FILE *f; + rnd_coord_t thick; + + if (!options) { + stl_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + stl_values[i] = stl_attribute_list[i].default_val; + options = stl_values; + } + + filename = options[HA_stlfile].str; + if (!filename) + filename = "pcb.stl"; + + pcb_cam_begin_nolayer(PCB, &cam, NULL, options[HA_cam].str, &filename); + + f = rnd_fopen_askovr(&PCB->hidlib, filename, "wb", NULL); + if (!f) { + perror(filename); + return; + } + + /* determine sheet thickness */ + if (options[HA_ovrthick].crd > 0) thick = options[HA_ovrthick].crd; + else thick = pcb_board_thickness(PCB, "stl", PCB_BRDTHICK_PRINT_ERROR); + if (thick <= 0) { + rnd_message(RND_MSG_WARNING, "STL: can not determine board thickness - falling back to hardwired 1.6mm\n"); + thick = RND_MM_TO_COORD(1.6); + } + + if (options[HA_zcent].lng) + stl_hid_export_to_file(f, options, PCB->hidlib.size_y, -thick/2, +thick/2); + else + stl_hid_export_to_file(f, options, PCB->hidlib.size_y, 0, thick); + + fclose(f); + pcb_cam_end(&cam); +} + +static int stl_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(stl_attribute_list, sizeof(stl_attribute_list) / sizeof(stl_attribute_list[0]), stl_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + + +static int stl_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nstl exporter command line arguments:\n\n"); + rnd_hid_usage(stl_attribute_list, sizeof(stl_attribute_list) / sizeof(stl_attribute_list[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x stl [stl options] foo.pcb\n\n"); + return 0; +} + + +int pplg_check_ver_export_stl(int ver_needed) { return 0; } + +void pplg_uninit_export_stl(void) +{ + rnd_remove_actions_by_cookie(stl_cookie); + rnd_hid_remove_hid(&stl_hid); +} + +int pplg_init_export_stl(void) +{ + RND_API_CHK_VER; + + memset(&stl_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&stl_hid); + + stl_hid.struct_size = sizeof(rnd_hid_t); + stl_hid.name = "stl"; + stl_hid.description = "export board outline in 3-dimensional STL"; + stl_hid.exporter = 1; + + stl_hid.get_export_options = stl_get_export_options; + stl_hid.do_export = stl_do_export; + stl_hid.parse_arguments = stl_parse_arguments; + + stl_hid.usage = stl_usage; + + rnd_hid_register_hid(&stl_hid); + + return 0; +} Index: tags/2.3.0/src_plugins/export_stl/export_stl.pup =================================================================== --- tags/2.3.0/src_plugins/export_stl/export_stl.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_stl/export_stl.pup (revision 33253) @@ -0,0 +1,9 @@ +$class export +$short 3d export: STL +$long Export stl (triangulated surface) +$state WIP +$fmt-native no +$fmt-feature-w stl (3d triangulated surface model) +$package export-extra +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_stl/stl_models.c =================================================================== --- tags/2.3.0/src_plugins/export_stl/stl_models.c (nonexistent) +++ tags/2.3.0/src_plugins/export_stl/stl_models.c (revision 33253) @@ -0,0 +1,344 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include +#include +#include + +typedef struct stl_facet_s stl_facet_t; + +struct stl_facet_s { + double n[3]; + double vx[3], vy[3], vz[3]; + stl_facet_t *next; +}; + +static char *stl_getline(char *line, int linelen, FILE *f) +{ + char *cmd; + while((cmd = fgets(line, linelen, f)) != NULL) { + while(isspace(*cmd)) cmd++; + if (*cmd == '\0') continue; + return cmd; + } + return NULL; +} + +void stl_solid_free(stl_facet_t *head) +{ + stl_facet_t *next; + for(; head != NULL; head = next) { + next = head->next; + free(head); + } +} + +stl_facet_t *stl_solid_fload(rnd_hidlib_t *hl, FILE *f) +{ + stl_facet_t *head = NULL, *tail = NULL, *t; + char *cmd, line[512]; + + /* find the 'solid' header */ + cmd = stl_getline(line, sizeof(line), f); + if ((cmd == NULL) || (strncmp(cmd, "solid", 5) != 0)) { + rnd_message(RND_MSG_ERROR, "Invalid stl file: first line is not a 'solid'\n"); + return NULL; + } + + for(;;) { + int n; + + cmd = stl_getline(line, sizeof(line), f); + if (cmd == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid stl file: premature end of file in solid\n"); + goto error; + } + if (strncmp(cmd, "endsolid", 8) == 0) + break; /* normal end of file */ + + if (strncmp(cmd, "facet normal", 12) != 0) { + rnd_message(RND_MSG_ERROR, "Invalid stl file: expected facet, got %s\n", cmd); + goto error; + } + + t = malloc(sizeof(stl_facet_t)); + t->next = NULL; + if (tail != NULL) { + tail->next = t; + tail = t; + } + else + head = tail = t; + + cmd += 12; + if (sscanf(cmd, "%lf %lf %lf", &t->n[0], &t->n[1], &t->n[2]) != 3) { + rnd_message(RND_MSG_ERROR, "Invalid stl file: wrong facet normals '%s'\n", cmd); + goto error; + } + + cmd = stl_getline(line, sizeof(line), f); + if (strncmp(cmd, "outer loop", 10) != 0) { + rnd_message(RND_MSG_ERROR, "Invalid stl file: expected outer loop, got %s\n", cmd); + goto error; + } + + for(n = 0; n < 3; n++) { + cmd = stl_getline(line, sizeof(line), f); + if (strncmp(cmd, "vertex", 6) != 0) { + rnd_message(RND_MSG_ERROR, "Invalid stl file: expected vertex, got %s\n", cmd); + goto error; + } + cmd+=6; + if (sscanf(cmd, "%lf %lf %lf", &t->vx[n], &t->vy[n], &t->vz[n]) != 3) { + rnd_message(RND_MSG_ERROR, "Invalid stl file: wrong facet vertex '%s'\n", cmd); + goto error; + } + } + + cmd = stl_getline(line, sizeof(line), f); + if (strncmp(cmd, "endloop", 7) != 0) { + rnd_message(RND_MSG_ERROR, "Invalid stl file: expected endloop, got %s\n", cmd); + goto error; + } + + cmd = stl_getline(line, sizeof(line), f); + if (strncmp(cmd, "endfacet", 8) != 0) { + rnd_message(RND_MSG_ERROR, "Invalid stl file: expected endfacet, got %s\n", cmd); + goto error; + } + } + + + return head; + + error:; + stl_solid_free(head); + fclose(f); + return NULL; +} + +RND_INLINE void v_transform(double dst[3], double src[3], double mx[16]) +{ + dst[0] = src[0]*mx[0] + src[1]*mx[4] + src[2]*mx[8] + mx[12]; + dst[1] = src[0]*mx[1] + src[1]*mx[5] + src[2]*mx[9] + mx[13]; + dst[2] = src[0]*mx[2] + src[1]*mx[6] + src[2]*mx[10] + mx[14]; +} + +static const double mx_ident[16] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 }; + +RND_INLINE void mx_rot_x(double mx_dst[16], double a) +{ + double s = sin(a), c = cos(a); + mx_dst[ 0] = 1; mx_dst[ 1] = 0; mx_dst[ 2] = 0; mx_dst[ 3] = 0; + mx_dst[ 4] = 0; mx_dst[ 5] = c; mx_dst[ 6] = s; mx_dst[ 7] = 0; + mx_dst[ 8] = 0; mx_dst[ 9] = -s; mx_dst[10] = c; mx_dst[11] = 0; + mx_dst[12] = 0; mx_dst[13] = 0; mx_dst[14] = 0; mx_dst[15] = 1; +} + + +RND_INLINE void mx_rot_y(double mx_dst[16], double a) +{ + double s = sin(a), c = cos(a); + + mx_dst[ 0] = c; mx_dst[ 1] = 0; mx_dst[ 2] = -s; mx_dst[ 3] = 0; + mx_dst[ 4] = 0; mx_dst[ 5] = 1; mx_dst[ 6] = 0; mx_dst[ 7] = 0; + mx_dst[ 8] = s; mx_dst[ 9] = 0; mx_dst[10] = c; mx_dst[11] = 0; + mx_dst[12] = 0; mx_dst[13] = 0; mx_dst[14] = 0; mx_dst[15] = 1; +} + +RND_INLINE void mx_rot_z(double mx_dst[16], double a) +{ + double s = sin(a), c = cos(a); + mx_dst[ 0] = c; mx_dst[ 1] = s; mx_dst[ 2] = 0; mx_dst[ 3] = 0; + mx_dst[ 4] = -s; mx_dst[ 5] = c; mx_dst[ 6] = 0; mx_dst[ 7] = 0; + mx_dst[ 8] = 0; mx_dst[ 9] = 0; mx_dst[10] = 1; mx_dst[11] = 0; + mx_dst[12] = 0; mx_dst[13] = 0; mx_dst[14] = 0; mx_dst[15] = 1; +} + +RND_INLINE void mx_xlate(double mx_dst[16], double x, double y, double z) +{ + mx_dst[ 0] = 1; mx_dst[ 1] = 0; mx_dst[ 2] = 0; mx_dst[ 3] = 0; + mx_dst[ 4] = 0; mx_dst[ 5] = 1; mx_dst[ 6] = 0; mx_dst[ 7] = 0; + mx_dst[ 8] = 0; mx_dst[ 9] = 0; mx_dst[10] = 1; mx_dst[11] = 0; + mx_dst[12] = x; mx_dst[13] = y; mx_dst[14] = z; mx_dst[15] = 1; +} + +RND_INLINE void mx_mult(double dst[16], double a[16], double b[16]) +{ + int n, m, k, l; + for(n = 0; n<16; n++) { + dst[n] = 0; + for(m = 0, k = n & 3, l = n & 12; m < 4; m++, k += 4, l++) + dst[n] = dst[n] + b[k] * a[l]; + } +} + +void stl_solid_print_facets(FILE *f, stl_facet_t *head, double rotx, double roty, double rotz, double xlatex, double xlatey, double xlatez) +{ + double mxn[16], mx[16], tmp[16], tmp2[16]; + + memcpy(mx, mx_ident, sizeof(mx_ident)); + if (rotx != 0) { mx_rot_x(tmp, rotx); mx_mult(tmp2, mx, tmp); memcpy(mx, tmp2, sizeof(tmp2)); } + if (roty != 0) { mx_rot_y(tmp, roty); mx_mult(tmp2, mx, tmp); memcpy(mx, tmp2, sizeof(tmp2)); } + if (rotz != 0) { mx_rot_z(tmp, rotz); mx_mult(tmp2, mx, tmp); memcpy(mx, tmp2, sizeof(tmp2)); } + memcpy(mxn, mx, sizeof(mx)); + if ((xlatex != 0) || (xlatey != 0) || (xlatez != 0)) { + mx_xlate(tmp, xlatex, xlatey, xlatez); + mx_mult(tmp2, mx, tmp); + memcpy(mx, tmp2, sizeof(tmp2)); + } + + for(; head != NULL; head = head->next) { + double v[3], p[3]; + int n; + v_transform(v, head->n, mxn); + fprintf(f, " facet normal %f %f %f\n", v[0], -v[1], v[2]); + fprintf(f, " outer loop\n"); + for(n = 0; n < 3; n++) { + p[0] = head->vx[n]; p[1] = head->vy[n]; p[2] = head->vz[n]; + v_transform(v, p, mx); + fprintf(f, " vertex %f %f %f\n", v[0], v[1], v[2]); + } + fprintf(f, " endloop\n"); + fprintf(f, " endfacet\n"); + } +} + +#ifndef STL_TESTER + +static void parse_utrans(double dst[3], const char *src) +{ + double tmp[3]; + int n; + const char *s = src; + char *end; + + if (src == NULL) + return; + + for(n = 0; n < 3; n++) { + if (s == NULL) + break; + tmp[n] = strtod(s, &end); + if ((!isspace(*end)) && (*end != ',') && (*end != ';') && (*end != '\0')) { + rnd_message(RND_MSG_ERROR, "stl: Invalis user coords in footprint transformation attribute: %s\n", src); + return; + } + s = end+1; + } + memcpy(dst, tmp, sizeof(tmp)); +} + +static void stl_model_place(rnd_hidlib_t *hl, FILE *outf, htsp_t *models, const char *name, rnd_coord_t ox, rnd_coord_t oy, double rotdeg, int on_bottom, const char *user_xlate, const char *user_rot, double maxy, rnd_coord_t z0, rnd_coord_t z1) +{ + stl_facet_t *head = NULL; + double uxlate[3] = {0,0,0}, xlate[3], urot[3] = {0,0,0}, rot[3]; + + if (!htsp_has(models, name)) { + char *full_path; + FILE *f = rnd_fopen_first(&PCB->hidlib, &conf_core.rc.library_search_paths, name, "r", &full_path, rnd_true); + if (f != NULL) { + head = stl_solid_fload(hl, f); + if (head == NULL) + rnd_message(RND_MSG_ERROR, "STL model failed to load: %s\n", full_path); + } + else + rnd_message(RND_MSG_ERROR, "STL model not found: %s\n", name); + free(full_path); + fclose(f); + htsp_set(models, rnd_strdup(name), head); + } + else + head = htsp_get(models, name); + + if (head == NULL) + return; + + parse_utrans(uxlate, user_xlate); + xlate[0] = RND_COORD_TO_MM(ox) + uxlate[0]; + xlate[1] = RND_COORD_TO_MM(maxy - (oy)) + uxlate[1]; + xlate[2] = RND_COORD_TO_MM((on_bottom ? z0 : z1)) + uxlate[3]; + + parse_utrans(urot, user_rot); + rot[0] = 0 + urot[0] / RND_RAD_TO_DEG; + rot[1] = (on_bottom ? M_PI : 0) + urot[1] / RND_RAD_TO_DEG; + rot[2] = rotdeg / RND_RAD_TO_DEG + urot[2] / RND_RAD_TO_DEG; + + stl_solid_print_facets(outf, head, rot[0], rot[1], rot[2], xlate[0], xlate[1], xlate[2]); +} + + +void stl_models_print(pcb_board_t *pcb, FILE *outf, double maxy, rnd_coord_t z0, rnd_coord_t z1) +{ + htsp_t models; + const char *mod; + htsp_entry_t *e; + + htsp_init(&models, strhash, strkeyeq); + + PCB_SUBC_LOOP(PCB->Data); { + mod = pcb_attribute_get(&subc->Attributes, "stl"); + if (mod != NULL) { + rnd_coord_t ox, oy; + double rot = 0; + int on_bottom = 0; + const char *srot, *sxlate; + + if (pcb_subc_get_origin(subc, &ox, &oy) != 0) { + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)subc, "subc-place", "Failed to get origin of subcircuit", "fix the missing subc-aux layer"); + continue; + } + pcb_subc_get_rotation(subc, &rot); + pcb_subc_get_side(subc, &on_bottom); + + sxlate = pcb_attribute_get(&subc->Attributes, "stl::translate"); + if (sxlate == NULL) + sxlate = pcb_attribute_get(&subc->Attributes, "stl-translate"); + srot = pcb_attribute_get(&subc->Attributes, "stl::rotate"); + if (srot == NULL) + srot = pcb_attribute_get(&subc->Attributes, "stl-rotate"); + + stl_model_place(&pcb->hidlib, outf, &models, mod, ox, oy, rot, on_bottom, sxlate, srot, maxy, z0, z1); + } + } PCB_END_LOOP; + + for (e = htsp_first(&models); e; e = htsp_next(&models, e)) { + free(e->key); + stl_solid_free((stl_facet_t *)e->value); + } + + htsp_uninit(&models); + +} + +#endif Index: tags/2.3.0/src_plugins/export_stl/test_load/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_stl/test_load/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_stl/test_load/Makefile (revision 33253) @@ -0,0 +1,5 @@ +CFLAGS = -g -Wall -I. +LDFLAGS = -lm + +main: main.c ../stl_models.c + $(CC) $(CFLAGS) $(LDFLAGS) -o main main.c \ No newline at end of file Index: tags/2.3.0/src_plugins/export_stl/test_load/config.h =================================================================== --- tags/2.3.0/src_plugins/export_stl/test_load/config.h (nonexistent) +++ tags/2.3.0/src_plugins/export_stl/test_load/config.h (revision 33253) @@ -0,0 +1,2 @@ +typedef int rnd_hidlib_t; +#define RND_INLINE static Index: tags/2.3.0/src_plugins/export_stl/test_load/error.h =================================================================== --- tags/2.3.0/src_plugins/export_stl/test_load/error.h (nonexistent) +++ tags/2.3.0/src_plugins/export_stl/test_load/error.h (revision 33253) @@ -0,0 +1 @@ +#define rnd_message(RND_MSG_ERROR, x...) fprintf(stderr, x) Index: tags/2.3.0/src_plugins/export_stl/test_load/main.c =================================================================== --- tags/2.3.0/src_plugins/export_stl/test_load/main.c (nonexistent) +++ tags/2.3.0/src_plugins/export_stl/test_load/main.c (revision 33253) @@ -0,0 +1,34 @@ +#include "safe_fs.h" +#include "error.h" +#define STL_TESTER +#include "../stl_models.c" + +stl_facet_t *stl_solid_load(rnd_hidlib_t *hl, const char *fn) +{ + FILE *f; + stl_facet_t *res; + + f = rnd_fopen(hl, fn, "r"); + if (f == NULL) + return NULL; + + res = stl_solid_fload(hl, f); + + fclose(f); + + return res; +} + +int main() +{ + FILE *f; + stl_facet_t *solid = stl_solid_load(NULL, "1206.stl"); + + f = fopen("A.stl", "w"); + fprintf(f, "solid t1\n"); + stl_solid_print_facets(f, solid, 0, 0, M_PI/6, 12, 0, 0); + fprintf(f, "endsolid\n"); + fclose(f); + + stl_solid_free(solid); +} Index: tags/2.3.0/src_plugins/export_stl/test_load/safe_fs.h =================================================================== --- tags/2.3.0/src_plugins/export_stl/test_load/safe_fs.h (nonexistent) +++ tags/2.3.0/src_plugins/export_stl/test_load/safe_fs.h (revision 33253) @@ -0,0 +1,2 @@ + +#define rnd_fopen(hl, fn, mode) fopen(fn, mode) Index: tags/2.3.0/src_plugins/export_svg/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_svg/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_svg/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_svg + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_svg/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_svg/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_svg/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {export_svg} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_svg/svg.o @] + +switch /local/pcb/export_svg/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_svg/export_svg.pup =================================================================== --- tags/2.3.0/src_plugins/export_svg/export_svg.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_svg/export_svg.pup (revision 33253) @@ -0,0 +1,9 @@ +$class export +$short SVG pcb_exporter +$long Scalable Vector Graphics (SVG) exporter +$fmt-native no +$fmt-feature-w svg (Scalable Vector Graphics) +$state works +$package export +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/export_svg/svg.c =================================================================== --- tags/2.3.0/src_plugins/export_svg/svg.c (nonexistent) +++ tags/2.3.0/src_plugins/export_svg/svg.c (revision 33253) @@ -0,0 +1,942 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2006 Dan McMahill + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* + * Based on the png exporter by Dan McMahill + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "board.h" +#include "data.h" +#include "draw.h" +#include +#include "layer.h" +#include "layer_vis.h" +#include +#include +#include +#include +#include "funchash_core.h" + +#include +#include + +#include +#include +#include "hid_cam.h" + + +static rnd_hid_t svg_hid; + +const char *svg_cookie = "svg HID"; + +static pcb_cam_t svg_cam; + +typedef struct rnd_hid_gc_s { + rnd_core_gc_t core_gc; + rnd_hid_t *me_pointer; + rnd_cap_style_t cap; + int width; + char *color; + int drill; + unsigned warned_elliptical:1; +} rnd_hid_gc_s; + +static const char *CAPS(rnd_cap_style_t cap) +{ + switch (cap) { + case rnd_cap_round: + return "round"; + case rnd_cap_square: + return "square"; + default: + assert(!"unhandled cap"); + return "round"; + } + return ""; +} + +static FILE *f = NULL; +static int group_open = 0; +static int opacity = 100, drawing_mask, drawing_hole, photo_mode, flip; + +static gds_t sbright, sdark, snormal, sclip; +static rnd_composite_op_t drawing_mode; +static int comp_cnt, svg_true_size = 0; +static long svg_drawn_objs; + +/* Photo mode colors and hacks */ +static const char *board_color = "#464646"; +static const char *mask_color = "#00ff00"; +static float mask_opacity_factor = 0.5; + +static enum { + PHOTO_MASK, + PHOTO_SILK, + PHOTO_COPPER, + PHOTO_INNER +} photo_color; + +static struct { + const char *bright; + const char *normal; + const char *dark; + rnd_coord_t offs; +} photo_palette[] = { + /* MASK */ { "#00ff00", "#00ff00", "#00ff00", RND_MM_TO_COORD(0) }, + /* SILK */ { "#ffffff", "#eeeeee", "#aaaaaa", RND_MM_TO_COORD(0) }, + /* COPPER */ { "#bbbbbb", "#707090", "#555555", RND_MM_TO_COORD(0.05) }, + /* INNER */ { "#222222", "#111111", "#000000", RND_MM_TO_COORD(0) } +}; + +rnd_export_opt_t svg_attribute_list[] = { + /* other HIDs expect this to be first. */ + +/* %start-doc options "93 SVG Options" +@ftable @code +@item --outfile +Name of the file to be exported to. Can contain a path. +@end ftable +%end-doc +*/ + {"outfile", "Graphics output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_svgfile 0 + +/* %start-doc options "93 SVG Options" +@ftable @code +@cindex photo-mode +@item --photo-mode +Export a photo realistic image of the layout. +@end ftable +%end-doc +*/ + {"photo-mode", "Photo-realistic export mode", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_photo_mode 1 + +/* %start-doc options "93 SVG Options" +@ftable @code +@cindex opacity +@item --opacity +Layer opacity +@end ftable +%end-doc +*/ + {"opacity", "Layer opacity", + RND_HATT_INTEGER, 0, 100, {100, 0, 0}, 0, 0}, +#define HA_opacity 2 + +/* %start-doc options "93 SVG Options" +@ftable @code +@cindex flip +@item --flip +Flip board, look at it from the bottom side +@end ftable +%end-doc +*/ + {"flip", "Flip board", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_flip 3 + + {"as-shown", "Render similar to as shown on screen (display overlays)", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_as_shown 4 + + {"true-size", "Attempt to preserve true size for printing", + RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_true_size 5 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0} +#define HA_cam 6 +}; + +#define NUM_OPTIONS (sizeof(svg_attribute_list)/sizeof(svg_attribute_list[0])) + +#define TRX(x) +#define TRY(y) \ +do { \ + if (flip) \ + y = PCB->hidlib.size_y - y; \ +} while(0) + +static rnd_hid_attr_val_t svg_values[NUM_OPTIONS]; + +static rnd_export_opt_t *svg_get_export_options(rnd_hid_t *hid, int *n) +{ + const char *suffix = ".svg"; + + if ((PCB != NULL) && (svg_attribute_list[HA_svgfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &svg_attribute_list[HA_svgfile], suffix); + + if (n) + *n = NUM_OPTIONS; + return svg_attribute_list; +} + +void svg_hid_export_to_file(FILE * the_file, rnd_hid_attr_val_t * options, rnd_xform_t *xform) +{ + static int saved_layer_stack[PCB_MAX_LAYER]; + rnd_hid_expose_ctx_t ctx; + + ctx.view.X1 = 0; + ctx.view.Y1 = 0; + ctx.view.X2 = PCB->hidlib.size_x; + ctx.view.Y2 = PCB->hidlib.size_y; + + f = the_file; + + memcpy(saved_layer_stack, pcb_layer_stack, sizeof(pcb_layer_stack)); + + { + rnd_conf_force_set_bool(conf_core.editor.show_solder_side, 0); + + if (options[HA_photo_mode].lng) { + photo_mode = 1; + } + else + photo_mode = 0; + + if (options[HA_flip].lng) { + flip = 1; + rnd_conf_force_set_bool(conf_core.editor.show_solder_side, 1); + } + else + flip = 0; + } + + if (photo_mode) { + rnd_fprintf(f, "\n", + 0, 0, PCB->hidlib.size_x, PCB->hidlib.size_y, board_color); + } + + opacity = options[HA_opacity].lng; + + gds_init(&sbright); + gds_init(&sdark); + gds_init(&snormal); + + if (options[HA_as_shown].lng) { + pcb_draw_setup_default_gui_xform(xform); + + /* disable (exporter default) hiding overlay in as_shown */ + xform->omit_overlay = 0; + } + + rnd_expose_main(&svg_hid, &ctx, xform); + + rnd_conf_update(NULL, -1); /* restore forced sets */ +} + +static void group_close() +{ + if (group_open == 1) { + if (gds_len(&sdark) > 0) { + fprintf(f, "\n"); + fprintf(f, "%s", sdark.array); + gds_truncate(&sdark, 0); + } + + if (gds_len(&sbright) > 0) { + fprintf(f, "\n"); + fprintf(f, "%s", sbright.array); + gds_truncate(&sbright, 0); + } + + if (gds_len(&snormal) > 0) { + fprintf(f, "\n"); + fprintf(f, "%s", snormal.array); + gds_truncate(&snormal, 0); + } + + } + fprintf(f, "\n"); +} + +static void svg_header() +{ + rnd_coord_t w, h, x1, y1, x2, y2; + + fprintf(f, "\n"); + w = PCB->hidlib.size_x; + h = PCB->hidlib.size_y; + while((w < RND_MM_TO_COORD(1024)) && (h < RND_MM_TO_COORD(1024))) { + w *= 2; + h *= 2; + } + + x2 = PCB->hidlib.size_x; + y2 = PCB->hidlib.size_y; + if (svg_true_size) { + rnd_fprintf(f, "\n", x2, y2, x2, y2); + } + else { + x1 = RND_MM_TO_COORD(2); + y1 = RND_MM_TO_COORD(2); + x2 += RND_MM_TO_COORD(5); + y2 += RND_MM_TO_COORD(5); + rnd_fprintf(f, "\n", w, h, x1, y1, x2, y2); + } +} + +static void svg_footer(void) +{ + while(group_open) { + group_close(); + group_open--; + } + + fprintf(f, "\n"); +} + +static void svg_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + const char *filename; + int save_ons[PCB_MAX_LAYER]; + int i; + rnd_xform_t xform; + + comp_cnt = 0; + + if (!options) { + svg_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + svg_values[i] = svg_attribute_list[i].default_val; + options = svg_values; + } + + svg_true_size = options[HA_true_size].lng; + svg_drawn_objs = 0; + pcb_cam_begin(PCB, &svg_cam, &xform, options[HA_cam].str, svg_attribute_list, NUM_OPTIONS, options); + + if (svg_cam.fn_template == NULL) { + filename = options[HA_svgfile].str; + if (!filename) + filename = "pcb.svg"; + + f = rnd_fopen_askovr(&PCB->hidlib, svg_cam.active ? svg_cam.fn : filename, "wb", NULL); + if (!f) { + perror(filename); + return; + } + svg_header(); + } + else + f = NULL; + + if (!svg_cam.active) + pcb_hid_save_and_show_layer_ons(save_ons); + + svg_hid_export_to_file(f, options, &xform); + + if (!svg_cam.active) + pcb_hid_restore_layer_ons(save_ons); + + if (f != NULL) { + svg_footer(); + fclose(f); + } + f = NULL; + + if (!svg_cam.active) svg_cam.okempty_content = 1; /* never warn in direct export */ + + if (pcb_cam_end(&svg_cam) == 0) { + if (!svg_cam.okempty_group) + rnd_message(RND_MSG_ERROR, "svg cam export for '%s' failed to produce any content (layer group missing)\n", options[HA_cam].str); + } + else if (svg_drawn_objs == 0) { + if (!svg_cam.okempty_content) + rnd_message(RND_MSG_ERROR, "svg cam export for '%s' failed to produce any content (no objects)\n", options[HA_cam].str); + } +} + +static int svg_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(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_layergrp_id_t group, const char *purpose, int purpi, rnd_layer_id_t layer, unsigned int flags, int is_empty, rnd_xform_t **xform) +{ + int opa, is_our_mask = 0, is_our_silk = 0; + + if (is_empty) + return 0; + + if (flags & PCB_LYT_UI) + return 0; + + pcb_cam_set_layer_group(&svg_cam, group, purpose, purpi, flags, xform); + + if (svg_cam.fn_changed || (f == NULL)) { + if (f != NULL) { + svg_footer(); + fclose(f); + } + + f = rnd_fopen_askovr(&PCB->hidlib, svg_cam.fn, "wb", NULL); + if (f == NULL) { + perror(svg_cam.fn); + return 0; + } + svg_header(); + } + + if (!svg_cam.active) { + if (flags & PCB_LYT_INVIS) + return 0; + + if (flags & PCB_LYT_MASK) { + if ((!photo_mode) && (!PCB->LayerGroups.grp[group].vis)) + return 0; /* not in photo mode or not visible */ + } + } + + switch(flags & PCB_LYT_ANYTHING) { + case PCB_LYT_MASK: is_our_mask = PCB_LAYERFLG_ON_VISIBLE_SIDE(flags); break; + case PCB_LYT_SILK: is_our_silk = PCB_LAYERFLG_ON_VISIBLE_SIDE(flags); break; + default:; + } + + if (!svg_cam.active) { + if (!(flags & PCB_LYT_COPPER) && (!is_our_silk) && (!is_our_mask) && !(PCB_LAYER_IS_DRILL(flags, purpi)) && !(PCB_LAYER_IS_ROUTE(flags, purpi))) + return 0; + } + + while(group_open) { + group_close(); + group_open--; + } + + { + gds_t tmp_ln; + const char *name; + gds_init(&tmp_ln); + name = pcb_layer_to_file_name(&tmp_ln, layer, flags, purpose, purpi, PCB_FNS_fixed); + fprintf(f, "\n"); + group_open = 1; + + if (photo_mode) { + if (is_our_silk) + photo_color = PHOTO_SILK; + else if (is_our_mask) + photo_color = PHOTO_MASK; + else if (group >= 0) { + if (PCB_LAYERFLG_ON_VISIBLE_SIDE(flags)) + photo_color = PHOTO_COPPER; + else + photo_color = PHOTO_INNER; + } + } + + drawing_hole = PCB_LAYER_IS_DRILL(flags, purpi); + + return 1; +} + + +static rnd_hid_gc_t svg_make_gc(rnd_hid_t *hid) +{ + rnd_hid_gc_t rv = (rnd_hid_gc_t) calloc(sizeof(rnd_hid_gc_s), 1); + rv->me_pointer = &svg_hid; + rv->cap = rnd_cap_round; + rv->width = 1; + rv->color = NULL; + return rv; +} + +static void svg_destroy_gc(rnd_hid_gc_t gc) +{ + free(gc); +} + +static void svg_set_drawing_mode(rnd_hid_t *hid, rnd_composite_op_t op, rnd_bool direct, const rnd_box_t *screen) +{ + drawing_mode = op; + + if (direct) + return; + + switch(op) { + case RND_HID_COMP_RESET: + comp_cnt++; + gds_init(&sclip); + rnd_append_printf(&snormal, "\n"); + rnd_append_printf(&snormal, "\n"); + rnd_append_printf(&snormal, "\n", comp_cnt); + rnd_append_printf(&sclip, "\n", comp_cnt, PCB->hidlib.size_x, PCB->hidlib.size_y); + break; + + case RND_HID_COMP_POSITIVE: + case RND_HID_COMP_POSITIVE_XOR: + case RND_HID_COMP_NEGATIVE: + break; + + case RND_HID_COMP_FLUSH: + rnd_append_printf(&snormal, "\n"); + rnd_append_printf(&sclip, "\n"); + gds_append_str(&snormal, sclip.array); + rnd_append_printf(&snormal, "\n"); + rnd_append_printf(&snormal, "\n", comp_cnt, comp_cnt); + rnd_append_printf(&snormal, "\n"); + gds_uninit(&sclip); + break; + } +} + +static const char *svg_color(rnd_hid_gc_t gc) +{ + return gc->color; +} + +static const char *svg_clip_color(rnd_hid_gc_t gc) +{ + if ((drawing_mode == RND_HID_COMP_POSITIVE) || (drawing_mode == RND_HID_COMP_POSITIVE_XOR)) + return "#FFFFFF"; + if (drawing_mode == RND_HID_COMP_NEGATIVE) + return "#000000"; + return NULL; +} + +static void svg_set_color(rnd_hid_gc_t gc, const rnd_color_t *color) +{ + const char *name; + gc->drill = 0; + + if (color == NULL) + name = "#ff0000"; + else + name = color->str; + + if (rnd_color_is_drill(color)) { + name = "#ffffff"; + gc->drill = 1; + } + if (drawing_mask) + name = mask_color; + if ((gc->color != NULL) && (strcmp(gc->color, name) == 0)) + return; + free(gc->color); + gc->color = rnd_strdup(name); +} + +static void svg_set_line_cap(rnd_hid_gc_t gc, rnd_cap_style_t style) +{ + gc->cap = style; +} + +static void svg_set_line_width(rnd_hid_gc_t gc, rnd_coord_t width) +{ + gc->width = width < RND_MM_TO_COORD(0.01) ? RND_MM_TO_COORD(0.01) : width; +} + +static void indent(gds_t *s) +{ + static char ind[] = " "; + if (group_open < sizeof(ind)-1) { + ind[group_open] = '\0'; + if (s == NULL) + rnd_fprintf(f, ind); + else + rnd_append_printf(s, ind); + ind[group_open] = ' '; + return; + } + + if (s == NULL) + rnd_fprintf(f, ind); + else + rnd_append_printf(s, ind); +} + +static void svg_set_draw_xor(rnd_hid_gc_t gc, int xor_) +{ + ; +} + +#define fix_rect_coords() \ + if (x1 > x2) {\ + rnd_coord_t t = x1; \ + x1 = x2; \ + x2 = t; \ + } \ + if (y1 > y2) { \ + rnd_coord_t t = y1; \ + y1 = y2; \ + y2 = t; \ + } + +static void draw_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t w, rnd_coord_t h, rnd_coord_t stroke) +{ + const char *clip_color = svg_clip_color(gc); + + indent(&snormal); + rnd_append_printf(&snormal, "\n", + x1, y1, w, h, stroke, svg_color(gc), CAPS(gc->cap)); + if (clip_color != NULL) { + indent(&sclip); + rnd_append_printf(&sclip, "\n", + x1, y1, w, h, stroke, clip_color, CAPS(gc->cap)); + } +} + +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) +{ + svg_drawn_objs++; + fix_rect_coords(); + draw_rect(gc, x1, y1, x2-x1, y2-y1, gc->width); +} + +static void draw_fill_rect(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t w, rnd_coord_t h) +{ + const char *clip_color = svg_clip_color(gc); + if ((photo_mode) && (clip_color == NULL)) { + rnd_coord_t photo_offs = photo_palette[photo_color].offs; + if (photo_offs != 0) { + indent(&sdark); + rnd_append_printf(&sdark, "\n", + x1+photo_offs, y1+photo_offs, w, h, photo_palette[photo_color].dark); + indent(&sbright); + rnd_append_printf(&sbright, "\n", + x1-photo_offs, y1-photo_offs, w, h, photo_palette[photo_color].bright); + } + indent(&snormal); + rnd_append_printf(&snormal, "\n", + x1, y1, w, h, photo_palette[photo_color].normal); + } + else { + indent(&snormal); + rnd_append_printf(&snormal, "\n", + x1, y1, w, h, svg_color(gc)); + if (clip_color != NULL) + rnd_append_printf(&sclip, "\n", + x1, y1, w, h, clip_color); + } +} + +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) +{ + svg_drawn_objs++; + TRX(x1); TRY(y1); TRX(x2); TRY(y2); + fix_rect_coords(); + draw_fill_rect(gc, x1, y1, x2-x1, y2-y1); +} + +static void pcb_line_draw(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + const char *clip_color = svg_clip_color(gc); + if ((photo_mode) && (clip_color == NULL)) { + rnd_coord_t photo_offs = photo_palette[photo_color].offs; + if (photo_offs != 0) { + indent(&sbright); + rnd_append_printf(&sbright, "\n", + x1-photo_offs, y1-photo_offs, x2-photo_offs, y2-photo_offs, gc->width, photo_palette[photo_color].bright, CAPS(gc->cap)); + indent(&sdark); + rnd_append_printf(&sdark, "\n", + x1+photo_offs, y1+photo_offs, x2+photo_offs, y2+photo_offs, gc->width, photo_palette[photo_color].dark, CAPS(gc->cap)); + } + indent(&snormal); + rnd_append_printf(&snormal, "\n", + x1, y1, x2, y2, gc->width, photo_palette[photo_color].normal, CAPS(gc->cap)); + } + else { + indent(&snormal); + rnd_append_printf(&snormal, "\n", + x1, y1, x2, y2, gc->width, svg_color(gc), CAPS(gc->cap)); + if (clip_color != NULL) { + rnd_append_printf(&sclip, "\n", + x1, y1, x2, y2, gc->width, clip_color, CAPS(gc->cap)); + } + } +} + +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) +{ + svg_drawn_objs++; + TRX(x1); TRY(y1); TRX(x2); TRY(y2); + pcb_line_draw(gc, x1, y1, x2, y2); +} + +static void pcb_arc_draw(rnd_hid_gc_t gc, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t r, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t stroke, int large, int sweep) +{ + const char *clip_color = svg_clip_color(gc); + if ((photo_mode) && (clip_color == NULL)) { + rnd_coord_t photo_offs = photo_palette[photo_color].offs; + if (photo_offs != 0) { + indent(&sbright); + rnd_append_printf(&sbright, "\n", + x1-photo_offs, y1-photo_offs, r, r, large, sweep, x2-photo_offs, y2-photo_offs, gc->width, photo_palette[photo_color].bright, CAPS(gc->cap)); + indent(&sdark); + rnd_append_printf(&sdark, "\n", + x1+photo_offs, y1+photo_offs, r, r, large, sweep, x2+photo_offs, y2+photo_offs, gc->width, photo_palette[photo_color].dark, CAPS(gc->cap)); + } + indent(&snormal); + rnd_append_printf(&snormal, "\n", + x1, y1, r, r, large, sweep, x2, y2, gc->width, photo_palette[photo_color].normal, CAPS(gc->cap)); + } + else { + indent(&snormal); + rnd_append_printf(&snormal, "\n", + x1, y1, r, r, large, sweep, x2, y2, gc->width, svg_color(gc), CAPS(gc->cap)); + if (clip_color != NULL) + rnd_append_printf(&sclip, "\n", + x1, y1, r, r, large, sweep, x2, y2, gc->width, clip_color, CAPS(gc->cap)); + } +} + +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_coord_t x1, y1, x2, y2, diff = 0, diff2, maxdiff; + rnd_angle_t sa, ea; + + svg_drawn_objs++; + + /* degenerate case: r=0 means a single dot */ + if ((width == 0) && (height == 0)) { + pcb_line_draw(gc, cx, cy, cx, cy); + return; + } + + /* detect elliptical arcs: if diff between radii is above 0.1% */ + diff2 = width - height; + if (diff2 < 0) + diff2 = -diff2; + maxdiff = width; + if (height > maxdiff) + maxdiff = height; + if (diff2 > maxdiff / 1000) { + if (!gc->warned_elliptical) { + rnd_message(RND_MSG_ERROR, "Can't draw elliptical arc on svg; object omitted; expect BROKEN TRACE\n"); + gc->warned_elliptical = 1; + } + return; + } + + TRX(cx); TRY(cy); + + /* calculate start and end angles considering flip */ + start_angle = 180 - start_angle; + delta_angle = -delta_angle; + if (flip) { + start_angle = -start_angle; + delta_angle = -delta_angle; + } + + /* workaround for near-360 deg rendering bugs */ + if ((delta_angle >= +360.0) || (delta_angle <= -360.0)) { + svg_draw_arc(gc, cx, cy, width, height, 0, 180); + svg_draw_arc(gc, cx, cy, width, height, 180, 180); + return; + } + + if (fabs(delta_angle) <= 0.001) { delta_angle = 0.001; diff=1; } + + sa = start_angle; + ea = start_angle + delta_angle; + + /* calculate the endpoints */ + x2 = rnd_round((double)cx + ((double)width * cos(sa * M_PI / 180))); + y2 = rnd_round((double)cy + ((double)width * sin(sa * M_PI / 180))); + x1 = rnd_round((double)cx + ((double)width * cos(ea * M_PI / 180))+diff); + y1 = rnd_round((double)cy + ((double)width * sin(ea * M_PI / 180))+diff); + + pcb_arc_draw(gc, x1, y1, width, x2, y2, gc->width, (fabs(delta_angle) > 180), (delta_angle < 0.0)); +} + +static void draw_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t r, rnd_coord_t stroke) +{ + const char *clip_color = svg_clip_color(gc); + + svg_drawn_objs++; + + if ((photo_mode) && (clip_color == NULL)) { + if (!drawing_hole) { + rnd_coord_t photo_offs = photo_palette[photo_color].offs; + if ((!gc->drill) && (photo_offs != 0)) { + indent(&sbright); + rnd_append_printf(&sbright, "\n", + cx-photo_offs, cy-photo_offs, r, stroke, photo_palette[photo_color].bright); + + indent(&sdark); + rnd_append_printf(&sdark, "\n", + cx+photo_offs, cy+photo_offs, r, stroke, photo_palette[photo_color].dark); + } + indent(&snormal); + rnd_append_printf(&snormal, "\n", + cx, cy, r, stroke, photo_palette[photo_color].normal); + } + else { + indent(&snormal); + rnd_append_printf(&snormal, "\n", + cx, cy, r, stroke, "#000000"); + } + } + else{ + indent(&snormal); + rnd_append_printf(&snormal, "\n", + cx, cy, r, stroke, svg_color(gc)); + if (clip_color != NULL) + rnd_append_printf(&sclip, "\n", + cx, cy, r, stroke, clip_color); + } +} + +static void svg_fill_circle(rnd_hid_gc_t gc, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t radius) +{ + svg_drawn_objs++; + TRX(cx); TRY(cy); + draw_fill_circle(gc, cx, cy, radius, 0); +} + +static void draw_poly(gds_t *s, rnd_hid_gc_t gc, int n_coords, rnd_coord_t * x, rnd_coord_t * y, rnd_coord_t dx, rnd_coord_t dy, const char *clr) +{ + int i; + float poly_bloat = 0.01; + + indent(s); + gds_append_str(s, "\n", poly_bloat, clr, clr); +} + +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) +{ + const char *clip_color = svg_clip_color(gc); + svg_drawn_objs++; + if ((photo_mode) && (clip_color == NULL)) { + rnd_coord_t photo_offs = photo_palette[photo_color].offs; + if (photo_offs != 0) { + draw_poly(&sbright, gc, n_coords, x, y, dx-photo_offs, dy-photo_offs, photo_palette[photo_color].bright); + draw_poly(&sdark, gc, n_coords, x, y, dx+photo_offs, dy+photo_offs, photo_palette[photo_color].dark); + } + draw_poly(&snormal, gc, n_coords, x, y, dx, dy, photo_palette[photo_color].normal); + } + else { + draw_poly(&snormal, gc, n_coords, x, y, dx, dy, svg_color(gc)); + if (clip_color != NULL) + draw_poly(&sclip, gc, n_coords, x, y, dx, dy, clip_color); + } +} + +static void svg_fill_polygon(rnd_hid_gc_t gc, int n_coords, rnd_coord_t *x, rnd_coord_t *y) +{ + svg_fill_polygon_offs(gc, n_coords, x, y, 0, 0); +} + + +static void svg_calibrate(rnd_hid_t *hid, double xval, double yval) +{ + rnd_message(RND_MSG_ERROR, "svg_calibrate() not implemented"); + return; +} + +static void svg_set_crosshair(rnd_hid_t *hid, rnd_coord_t x, rnd_coord_t y, int a) +{ +} + +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: pcb-rnd [generic_options] -x svg [svg options] foo.pcb\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 = svg_make_gc; + svg_hid.destroy_gc = svg_destroy_gc; + svg_hid.set_drawing_mode = svg_set_drawing_mode; + svg_hid.set_color = svg_set_color; + svg_hid.set_line_cap = svg_set_line_cap; + svg_hid.set_line_width = svg_set_line_width; + svg_hid.set_draw_xor = 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.calibrate = svg_calibrate; + svg_hid.set_crosshair = svg_set_crosshair; + + svg_hid.usage = svg_usage; + + rnd_hid_register_hid(&svg_hid); + + return 0; +} Index: tags/2.3.0/src_plugins/export_vfs_fuse/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_vfs_fuse/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_fuse/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_export_vfs_fuse + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_vfs_fuse/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_vfs_fuse/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_fuse/Plug.tmpasm (revision 33253) @@ -0,0 +1,17 @@ +put /local/pcb/mod {export_vfs_fuse} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_vfs_fuse/export_vfs_fuse.o @] + +switch /local/pcb/export_vfs_fuse/controls + case {disable} end; + default + put /local/pcb/mod/CFLAGS [@@/target/libs/sul/fuse/cflags@@] + put /local/pcb/mod/LDFLAGS [@@/target/libs/sul/fuse/ldflags@@] + append /local/pcb/mod/DISTCLEANFILES { $(PLUGDIR)/export_vfs_fuse/fuse_includes.h } + end +end + +switch /local/pcb/export_vfs_fuse/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_vfs_fuse/README =================================================================== --- tags/2.3.0/src_plugins/export_vfs_fuse/README (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_fuse/README (revision 33253) @@ -0,0 +1,20 @@ +1. Mounting a board + + mkdir /tmp/mntpt + pcb-rnd -x vfs_fuse board.lht /tmp/mntpt + +This will start a pcb-rnd process in the background. The proces will load +board.lht, just like if it was a normal GUI or CLI user session, until the +unmount. + +Make sure /dev/fuse has the right permissions and your user has write access +to it. A typical setup is: + - /dev/fuse having group +rw with group owner set to 'fuse' + - the user added in the 'fuse' group + +2. Unmounting a board + + fusermount -u /tmp/mntpt + +This is when the board is saved if there was any change (write) while it +was mounted. Index: tags/2.3.0/src_plugins/export_vfs_fuse/export_vfs_fuse.c =================================================================== --- tags/2.3.0/src_plugins/export_vfs_fuse/export_vfs_fuse.c (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_fuse/export_vfs_fuse.c (revision 33253) @@ -0,0 +1,389 @@ +#define _XOPEN_SOURCE 500 + +/* Required because FUSE uses readdir as struct field name */ +#define RND_SAFE_FS + +#include "fuse_includes.h" + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "build_run.h" +#include "board.h" +#include "data.h" +#include +#include +#include +#include "plug_io.h" +#include +#include + +#include +#include +#include +#include + +#include "../src_plugins/lib_vfs/lib_vfs.h" + +static const char *export_vfs_fuse_cookie = "export_vfs_fuse HID"; +static int pcb_fuse_changed; +static char fuse_cwd[RND_PATH_MAX]; + +static rnd_export_opt_t *export_vfs_fuse_get_export_options(rnd_hid_t *hid, int *n) +{ + return 0; +} + +typedef struct { + const char *path; + void *buf; + fuse_fill_dir_t filler; + int pathlen; +} pcb_fuse_list_t; + +static void pcb_fuse_list_cb(void *ctx_, const char *path, int isdir) +{ + pcb_fuse_list_t *ctx = ctx_; + int child, direct, pl; + + pl = strlen(path); + if (pl <= ctx->pathlen) + return; + + if (ctx->pathlen > 0) { + child = memcmp(path, ctx->path, ctx->pathlen) == 0; + path += ctx->pathlen; + if (*path == '/') + path++; + else if (*path != '\0') + child = 0; + } + else + child = 1; + + if ((child) && (*path != '\0')) { + direct = (strchr(path, '/') == NULL); + if (direct) { + struct stat st; + memset(&st, 0, sizeof(struct stat)); + st.st_mode = (isdir ? (S_IFDIR | 0755) : (S_IFREG | 0644)); + st.st_nlink = 1 + !!isdir; + ctx->filler(ctx->buf, path, &st, 0); + } + } +} + +static int pcb_fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) +{ + pcb_fuse_list_t ctx; + + if (*path == '/') + path++; + + ctx.path = path; + ctx.buf = buf; + ctx.filler = filler; + ctx.pathlen = strlen(path); + + filler(buf, ".", NULL, 0); + filler(buf, "..", NULL, 0); + pcb_vfs_list(PCB, pcb_fuse_list_cb, &ctx); + + return 0; +} + +static int pcb_fuse_getattr(const char *path, struct stat *stbuf) +{ + int isdir; + gds_t data; + + gds_init(&data); + if (strcmp(path, "/") != 0) { + if (*path == '/') + path++; + if (pcb_vfs_access(PCB, path, &data, 0, &isdir) != 0) { + gds_uninit(&data); + return -ENOENT; + } + } + else + isdir = 1; + + memset(stbuf, 0, sizeof(struct stat)); + stbuf->st_mode = (isdir ? (S_IFDIR | 0755) : (S_IFREG | 0644)); + stbuf->st_nlink = 1 + !!isdir; + stbuf->st_size = data.used; + + gds_uninit(&data); + return 0; +} + +static int pcb_fuse_access(const char *path, int mask) +{ + return 0; +} + +static int pcb_fuse_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) +{ + gds_t data; + int len; + + if (*path == '/') + path++; + gds_init(&data); + if (pcb_vfs_access(PCB, path, &data, 0, NULL) != 0) { + gds_uninit(&data); + return -ENOENT; + } + + len = data.used; + len -= offset; + if (len > 0) + memcpy(buf, data.array + offset, len); + else + len = 0; + gds_uninit(&data); + + return len; +} + +static int pcb_fuse_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) +{ + gds_t data, src; + + if (*path == '/') + path++; + + gds_init(&data); + + if (offset > 0) { + if (pcb_vfs_access(PCB, path, &data, 0, NULL) != 0) { + gds_uninit(&data); + return -ENOENT; + } + src.array = (char *)buf; + src.used = src.alloced = size; + src.no_realloc = 1; + gds_copy(&data, offset, &src, 0, size); + } + else + gds_append_len(&data, buf, size); + + if ((data.used > 0) && (data.array[data.used-1] == '\n')) + data.array[data.used-1] = '\0'; + + if (pcb_vfs_access(PCB, path, &data, 1, NULL) != 0) { + gds_uninit(&data); + return -EIO; + } + + gds_uninit(&data); + pcb_fuse_changed = 1; + return size; +} + +static int pcb_fuse_truncate(const char *path, off_t size) +{ + gds_t data; + + if (*path == '/') + path++; + gds_init(&data); + if (pcb_vfs_access(PCB, path, &data, 0, NULL) != 0) { + gds_uninit(&data); + return -ENOENT; + } + + if ((size == data.used) || (size < 0)) + return 0; + + if (size < data.used) { + data.used = size; + data.array[size] = '\0'; + } + else { + size_t old = data.used; + gds_enlarge(&data, size); + if ((old > 0)&& (data.array[old-1] == '\n')) + data.array[old-1] = ' '; + memset(&data.array[old-1], ' ', size-old-1); + data.array[size] = '\0'; + } + + if (pcb_vfs_access(PCB, path, &data, 1, NULL) != 0) { + gds_uninit(&data); + return -EIO; + } + + gds_uninit(&data); + pcb_fuse_changed = 1; + return 0; +} + + +static int pcb_fuse_open(const char *path, struct fuse_file_info *fi) +{ + return 0; +} + +static void pcb_fuse_destroy(void *private_data) +{ + char *fn = PCB->hidlib.filename; + + if (!pcb_fuse_changed) + return; + + /* pwd is lost during daemonisation */ + if (!rnd_is_path_abs(PCB->hidlib.filename)) + fn = rnd_strdup_printf("%s%c%s", fuse_cwd, RND_DIR_SEPARATOR_C, PCB->hidlib.filename); + + if (pcb_save_pcb(fn, NULL) != 0) { + fprintf(stderr, "Failed to save the modified board file\n"); + exit(1); + } +} + + +static char **fuse_argv; +static int fuse_argc = 0; +static void export_vfs_fuse_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + static struct fuse_operations oper; + + rnd_get_wd(fuse_cwd); + + oper.readdir = pcb_fuse_readdir; + oper.open = pcb_fuse_open; + oper.read = pcb_fuse_read; + oper.write = pcb_fuse_write; + oper.truncate = pcb_fuse_truncate; + oper.getattr = pcb_fuse_getattr; + oper.access = pcb_fuse_access; + oper.destroy = pcb_fuse_destroy; + + pcb_fuse_changed = 0; + if (fuse_main(fuse_argc, fuse_argv, &oper, NULL) != 0) + fprintf(stderr, "fuse_main() returned error.\n"); +} + +static int export_vfs_fuse_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nexport_vfs_fuse exporter command line arguments are plain fuse aguments.\n\n"); + fprintf(stderr, "\nUsage: pcb-rnd [pcb-rnd-options] [-o fuse-options] foo.pcb mountpoint\n\n"); + return 0; +} + +#define arg_append(dst_argc, dst_argv, str) dst_argv[dst_argc++] = str + +#define arg_copy_to_fuse(cnt) \ +do { \ + int __i__; \ + for(__i__ = 0; __i__ < (cnt); __i__++,n++) \ + arg_append(fuse_argc, fuse_argv, in_argv[n]); \ + n--; \ +} while(0) + +#define arg_copy_to_pcb(cnt) \ +do { \ + int __i__; \ + for(__i__ = 0; __i__ < (cnt); __i__++,n++) \ + arg_append(fuse_ret_argc, fuse_ret_argv, in_argv[n]); \ + n--; \ +} while(0) + +static char **fuse_ret_argv; +static int fuse_ret_argc = 0; +static int export_vfs_fuse_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + int n, in_argc = *argc; + char **in_argv = *argv; + char *board = NULL, *dir = NULL; + + fuse_argv = malloc(sizeof(char *) * (*argc+1)); + fuse_argc = 0; + fuse_ret_argv = malloc(sizeof(char *) * (*argc+1)); + fuse_ret_argc = 0; + + arg_append(fuse_argc, fuse_argv, "pcb-rnd"); /* program name */ + arg_append(fuse_argc, fuse_argv, "?"); /* make room for the mount point */ + + for(n = 0; n < in_argc; n++) { + if (strcmp(in_argv[n], "-o") == 0) arg_copy_to_fuse(2); + else if (*in_argv[n] == '-') arg_copy_to_pcb(2); + else { + if (board == NULL) board = in_argv[n]; + else if (dir == NULL) dir = in_argv[n]; + else { + fprintf(stderr, "export_vfs_fuse: excess unrecognized argument: '%s'\n", in_argv[n]); + exit(1); + } + } + } + + if (board == NULL) { + fprintf(stderr, "export_vfs_fuse: board name is required\n"); + exit(1); + } + + if (dir == NULL) { + fprintf(stderr, "export_vfs_fuse: mount point is required\n"); + exit(1); + } + + arg_append(fuse_ret_argc, fuse_ret_argv, board); + fuse_argv[1] = dir; + + fuse_argv[fuse_argc] = NULL; + fuse_ret_argv[fuse_ret_argc] = NULL; + + argc = &fuse_ret_argc; + *argv = fuse_ret_argv; + return 0; +} + +rnd_hid_t export_vfs_fuse_hid; + +int pplg_check_ver_export_vfs_fuse(int ver_needed) { return 0; } + +void pplg_uninit_export_vfs_fuse(void) +{ + rnd_export_remove_opts_by_cookie(export_vfs_fuse_cookie); + free(fuse_argv); + fuse_argv = NULL; + free(fuse_ret_argv); + fuse_ret_argv = NULL; + rnd_hid_remove_hid(&export_vfs_fuse_hid); +} + +int pplg_init_export_vfs_fuse(void) +{ + RND_API_CHK_VER; + + memset(&export_vfs_fuse_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&export_vfs_fuse_hid); + + export_vfs_fuse_hid.struct_size = sizeof(rnd_hid_t); + export_vfs_fuse_hid.name = "vfs_fuse"; + export_vfs_fuse_hid.description = "Handler of FUSE calls, serving board data"; + export_vfs_fuse_hid.exporter = 1; + export_vfs_fuse_hid.hide_from_gui = 1; + + export_vfs_fuse_hid.get_export_options = export_vfs_fuse_get_export_options; + export_vfs_fuse_hid.do_export = export_vfs_fuse_do_export; + export_vfs_fuse_hid.parse_arguments = export_vfs_fuse_parse_arguments; + + export_vfs_fuse_hid.usage = export_vfs_fuse_usage; + + rnd_hid_register_hid(&export_vfs_fuse_hid); + return 0; +} Index: tags/2.3.0/src_plugins/export_vfs_fuse/export_vfs_fuse.pup =================================================================== --- tags/2.3.0/src_plugins/export_vfs_fuse/export_vfs_fuse.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_fuse/export_vfs_fuse.pup (revision 33253) @@ -0,0 +1,7 @@ +$class export +$short FUSE VFS server +$long Export all data and config of a board to a FUSE mountable filesystem +$state WIP +dep lib_vfs +default disable +autoload 1 Index: tags/2.3.0/src_plugins/export_vfs_fuse/fuse_includes.h.in =================================================================== --- tags/2.3.0/src_plugins/export_vfs_fuse/fuse_includes.h.in (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_fuse/fuse_includes.h.in (revision 33253) @@ -0,0 +1,12 @@ +if ?libs/sul/fuse/presents +then +put /local/tmp ?libs/sul/fuse/includes +gsub /local/tmp {\\\\n *} {\n} +print [@ +@/local/tmp@ +@] +else +print [@ +#error Fuse is not configured, can not compile export_vfs_fuse +@] +end Index: tags/2.3.0/src_plugins/export_vfs_mc/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_vfs_mc/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_mc/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_export_vfs_mc + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_vfs_mc/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_vfs_mc/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_mc/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {export_vfs_mc} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_vfs_mc/export_vfs_mc.o @] + +switch /local/pcb/export_vfs_mc/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_vfs_mc/README =================================================================== --- tags/2.3.0/src_plugins/export_vfs_mc/README (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_mc/README (revision 33253) @@ -0,0 +1 @@ +For instructions, see the top comments in upcb. Index: tags/2.3.0/src_plugins/export_vfs_mc/export_vfs_mc.c =================================================================== --- tags/2.3.0/src_plugins/export_vfs_mc/export_vfs_mc.c (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_mc/export_vfs_mc.c (revision 33253) @@ -0,0 +1,174 @@ +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include + +#include "build_run.h" +#include "board.h" +#include "data.h" +#include +#include +#include +#include "plug_io.h" + +#include +#include +#include +#include + +#include "../src_plugins/lib_vfs/lib_vfs.h" + +const char *export_vfs_mc_cookie = "export_vfs_mc HID"; + +static rnd_export_opt_t export_vfs_mc_options[] = { + {"cmd", "mc command", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_export_vfs_mc_cmd 0 + + {"qpath", "query path", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_export_vfs_mc_qpath 1 +}; + +#define NUM_OPTIONS (sizeof(export_vfs_mc_options)/sizeof(export_vfs_mc_options[0])) + +static rnd_hid_attr_val_t export_vfs_mc_values[NUM_OPTIONS]; + +static rnd_export_opt_t *export_vfs_mc_get_export_options(rnd_hid_t *hid, int *n) +{ + if (n) + *n = NUM_OPTIONS; + return export_vfs_mc_options; +} + +static void mc_list_cb(void *ctx, const char *path, int isdir) +{ + const char *attrs = isdir ? "drwxr-xr-x" : "-rw-r--r--"; + printf("%s 1 pcb-rnd pcb-rnd 0 01/01/01 01:01 %s\n", attrs, path); +} + +static void mc_list(void) +{ + pcb_vfs_list(PCB, mc_list_cb, NULL); +} + +static void mc_copyout(const char *path) +{ + gds_t res; + + gds_init(&res); + if (pcb_vfs_access(PCB, path, &res, 0, NULL) == 0) { + printf("%s", res.array); + } + else { + fprintf(stderr, "Can not access that field for read\n"); + exit(1); + } + gds_uninit(&res); +} + +static void mc_copyin(const char *path) +{ + gds_t inp; + char buf[256]; + int len; + + gds_init(&inp); + while((len = read(0, buf, 256)) > 0) { + gds_append_len(&inp, buf, len); + if (inp.used > 1024*1024) { + fprintf(stderr, "Data too large\n"); + exit(1); + } + } + + if ((inp.used > 0) && (inp.array[inp.used-1] == '\n')) { + inp.used--; /* remove exactly one trailing newline */ + inp.array[inp.used] = '\0'; + } + + if (pcb_vfs_access(PCB, path, &inp, 1, NULL) != 0) { + fprintf(stderr, "Can not access that field for write\n"); + exit(1); + } + gds_uninit(&inp); + if (pcb_save_pcb(PCB->hidlib.filename, NULL) != 0) { + fprintf(stderr, "Failed to save the modified board file\n"); + exit(1); + } +} + +static void export_vfs_mc_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + const char *cmd; + int i; + + if (!options) { + export_vfs_mc_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + export_vfs_mc_values[i] = export_vfs_mc_options[i].default_val; + options = export_vfs_mc_values; + } + + cmd = options[HA_export_vfs_mc_cmd].str; + if (strcmp(cmd, "list") == 0) mc_list(); + else if (strcmp(cmd, "copyout") == 0) mc_copyout(options[HA_export_vfs_mc_qpath].str); + else if (strcmp(cmd, "copyin") == 0) mc_copyin(options[HA_export_vfs_mc_qpath].str); + else { + fprintf(stderr, "Unknown vfs_mc command: '%s'\n", cmd); + exit(1); + } +} + +static int export_vfs_mc_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nexport_vfs_mc exporter command line arguments:\n\n"); + rnd_hid_usage(export_vfs_mc_options, sizeof(export_vfs_mc_options) / sizeof(export_vfs_mc_options[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x export_vfs_mc [export_vfs_mc_options] foo.pcb\n\n"); + return 0; +} + + +static int export_vfs_mc_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(export_vfs_mc_options, sizeof(export_vfs_mc_options) / sizeof(export_vfs_mc_options[0]), export_vfs_mc_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +rnd_hid_t export_vfs_mc_hid; + +int pplg_check_ver_export_vfs_mc(int ver_needed) { return 0; } + +void pplg_uninit_export_vfs_mc(void) +{ + rnd_export_remove_opts_by_cookie(export_vfs_mc_cookie); + rnd_hid_remove_hid(&export_vfs_mc_hid); +} + +int pplg_init_export_vfs_mc(void) +{ + RND_API_CHK_VER; + + memset(&export_vfs_mc_hid, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&export_vfs_mc_hid); + + export_vfs_mc_hid.struct_size = sizeof(rnd_hid_t); + export_vfs_mc_hid.name = "vfs_mc"; + export_vfs_mc_hid.description = "Handler of mc VFS calls, serving board data"; + export_vfs_mc_hid.exporter = 1; + export_vfs_mc_hid.hide_from_gui = 1; + + export_vfs_mc_hid.get_export_options = export_vfs_mc_get_export_options; + export_vfs_mc_hid.do_export = export_vfs_mc_do_export; + export_vfs_mc_hid.parse_arguments = export_vfs_mc_parse_arguments; + + export_vfs_mc_hid.usage = export_vfs_mc_usage; + + rnd_hid_register_hid(&export_vfs_mc_hid); + return 0; +} Index: tags/2.3.0/src_plugins/export_vfs_mc/export_vfs_mc.pup =================================================================== --- tags/2.3.0/src_plugins/export_vfs_mc/export_vfs_mc.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_mc/export_vfs_mc.pup (revision 33253) @@ -0,0 +1,7 @@ +$class export +$short GNU mc VFS server +$long Export all data and config of a board to GNU mc +$state WIP +dep lib_vfs +default disable +autoload 1 Index: tags/2.3.0/src_plugins/export_vfs_mc/upcb =================================================================== --- tags/2.3.0/src_plugins/export_vfs_mc/upcb (nonexistent) +++ tags/2.3.0/src_plugins/export_vfs_mc/upcb (revision 33253) @@ -0,0 +1,29 @@ +#!/bin/sh + +# GNU mc VFS glue for printed circuit boards using pcb-rnd +# This file is placed in the public domain by the author, +# Tibor 'Igor2' Palinkas, in 2019. +# +# Install this file in /usr/lib/mc/extfs.d +# +# Then add this in mc.ext (e.g. in /etc/mc/mc.ext): +# +# # PCB files +# shell/.pcb +# Open=%cd %p/upcb:// +# + +PCBRND="pcb-rnd -x vfs_mc" + +cmd=$1 +shift 1 +case "$cmd" in + list) $PCBRND --cmd list "$1" ;; + copyout) $PCBRND --cmd copyout "$1" --qpath "$2" > $3;; + copyin) $PCBRND --cmd copyin "$1" --qpath "$2" < $3;; +# rm) +# rmdir) +# mkdir) + *) exit 1 ;; +esac +exit 0 Property changes on: tags/2.3.0/src_plugins/export_vfs_mc/upcb ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/src_plugins/export_xy/Makefile =================================================================== --- tags/2.3.0/src_plugins/export_xy/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/export_xy/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_export_xy + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/export_xy/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/export_xy/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/export_xy/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {export_xy} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/export_xy/xy.o @] +put /local/pcb/mod/CONF {$(PLUGDIR)/export_xy/xy_conf.h} +put /local/pcb/mod/CONFFILE {export_xy.conf} +put /local/pcb/mod/CONFVAR {export_xy_conf_internal} + +switch /local/pcb/export_xy/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/export_xy/export_xy.conf =================================================================== --- tags/2.3.0/src_plugins/export_xy/export_xy.conf (nonexistent) +++ tags/2.3.0/src_plugins/export_xy/export_xy.conf (revision 33253) @@ -0,0 +1,97 @@ +### conf file header (compacted) +li:pcb-rnd-conf-v1 { ha:overwrite { ha:plugins { ha:export_xy { li:templates { + +### tempalates + +# classis gEDA/PCB xy ######################################################### +xy.name = pcb xy +xy.hdr = {# $Id$ +# PcbXY Version 1.0 +# Date: %UTC% +# Author: %author% +# Title: %title% - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in %suffix%. rotation in degrees. +# -------------------------------------------- +} +xy.subc = {%subc.refdes%,"%subc.footprint%","%subc.value%",%subc.x%,%subc.y%,%subc.rot%,%subc.side% +} + +# gxyrs ####################################################################### +gxyrs.name = gxyrs +gxyrs.hdr = {#gxyrs version 1.0 +#Date: %UTC% +#Author: %author% +#Title: %title% - pcb-rnd gxyrs +#Placement data: +#Designator X-Loc Y-Loc Rotation Side Type X-Size Y-Size Value Footprint +# -------------------------------------------- +} + +gxyrs.subc = {%subc.refdes_% %subc.x% %subc.y% %subc.rot% %subc.side% %subc.pad_width% %subc.pad_height% %subc.value_% %subc.footprint_% +} + + +# macrofab #################################################################### +macrofab.name = Macrofab +macrofab.hdr = {#pcb-rnd Macrofab export version 1.0 +#Date: %UTC% +#Author: %author% +#Title: %title% - pcb-rnd Macrofab export +#Placement data: +#Designator X-Loc Y-Loc Rotation Side Type X-Size Y-Size Value Footprint +# -------------------------------------------- +} +macrofab.subc = {%subc.refdes_% %subc.padcx% %subc.padcy% %subc.negrot% %subc.num-side% %subc.smdvsthrunum% %subc.pad_width_prerot% %subc.pad_height_prerot% %subc.value_% %subc.footprint_% %subc.a.macrofab::DNP?0:1% %subc.a.macrofab::MPN|% +} + +# TM220/TM240 ################################################################# +tm220.name = TM220/TM240 +tm220.hdr = {#pcb-rnd TM220A/TM240A xyrs version 1.0 +#Date: %UTC% +#Author: %author% +#Title: %title% - pcb-rnd gxyrs +#Placement data: +#RefDes, top/bottom, X, Y, rotation +# X,Y in %suffix%. rotation in degrees. +# -------------------------------------------- +} + +tm220.subc = {%subc.refdes%,%subc.side%,%subc.x%,%subc.y%,%subc.rot% +} + +# KiCad .pos file ############################################################# +kicad_pos.name = {KiCad .pos} +kicad_pos.hdr = {###pcb-rnd KiCad .pos compatible xyrs version 1.0 +###Date: %UTC%, Author: %author%, Title: %title% - pcb-rnd gxyrs +## Unit = %suffix%., Angle = degrees. +#, Ref, Val, Package, PosX, PosY, Rot, Side +} +kicad_pos.subc = {,"%subc.refdes%","%subc.value%","%subc.footprint%",%subc.x%,%subc.y%,%subc.rot%,%subc.side% +} + +# ncap (work in progress) ##################################################### +ncap.name = {ncap export (WIP)} +ncap.hdr = {ncapture 0 +4 +%boardw% +%boardh% +80hmmm +-30hmmm; +} + +ncap.subc = {%subc.count% +0 +%subc.pincount% +1 +%subc.refdes% +%subc.90rot% +%subc.x% +%subc.y% +0 +} +ncap.term = {%term.netname% +} + +### conf file footer (compacted) +} } } } } Index: tags/2.3.0/src_plugins/export_xy/export_xy.pup =================================================================== --- tags/2.3.0/src_plugins/export_xy/export_xy.pup (nonexistent) +++ tags/2.3.0/src_plugins/export_xy/export_xy.pup (revision 33253) @@ -0,0 +1,14 @@ +$class export +$short xy (centroid) pcb_exporter +$long Template based export of XY centroid subcircuit data e.g. for pick & place. +$state works +$fmt-native no +$fmt-feature-w geda/PCB xy +$fmt-feature-w gxyrs +$fmt-feature-w Macrofab's pick&place +$fmt-feature-w pick&place file for the TM220/TM240 device +$fmt-feature-w KiCad .pos file +$package export +default buildin +dep export_bom +autoload 1 Index: tags/2.3.0/src_plugins/export_xy/xy.c =================================================================== --- tags/2.3.0/src_plugins/export_xy/xy.c (nonexistent) +++ tags/2.3.0/src_plugins/export_xy/xy.c (revision 33253) @@ -0,0 +1,893 @@ +#include "config.h" +#include "conf_core.h" +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "build_run.h" +#include "board.h" +#include "data.h" +#include "data_it.h" +#include +#include +#include +#include +#include "obj_pstk_inlines.h" +#include "obj_subc_op.h" +#include "layer.h" +#include "netlist.h" +#include +#include "operation.h" +#include "xy_conf.h" + +#include +#include +#include +#include "hid_cam.h" +#include + +#include "../src_plugins/lib_compat_help/elem_rot.h" +#include "../src_plugins/export_xy/conf_internal.c" + +#define CONF_FN "export_xy.conf" + +conf_xy_t conf_xy; + +extern char *pcb_bom_clean_str(const char *in); + +const char *xy_cookie = "XY HID"; + +/* Maximum length of a template name (in the config file, in the enum) */ +#define MAX_TEMP_NAME_LEN 128 + + +static rnd_export_opt_t xy_options[] = { +/* %start-doc options "8 XY Creation" +@ftable @code +@item --xyfile +Name of the XY output file. +@end ftable +%end-doc +*/ + {"xyfile", "Name of the XY output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_xyfile 0 + +/* %start-doc options "8 XY Creation" +@ftable @code +@item --xy-unit +Unit of XY dimensions. Defaults to mil. +@end ftable +%end-doc +*/ + {"xy-unit", "XY units", + RND_HATT_UNIT, 0, 0, {-1, 0, 0}, NULL, 0}, +#define HA_unit 1 + {"format", "file format (template)", + RND_HATT_ENUM, 0, 0, {0, 0, 0}, NULL, 0}, +#define HA_format 2 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 3 + +}; + +#define NUM_OPTIONS (sizeof(xy_options)/sizeof(xy_options[0])) + +static rnd_hid_attr_val_t xy_values[NUM_OPTIONS]; + +static const char *xy_filename; +static const rnd_unit_t *xy_unit; +vts0_t fmt_names; /* array of const char * long name of each format, pointing into the conf database */ +vts0_t fmt_ids; /* array of strdup'd short name (ID) of each format */ + +static void free_fmts(void) +{ + int n; + for(n = 0; n < fmt_ids.used; n++) { + free(fmt_ids.array[n]); + fmt_ids.array[n] = NULL; + } +} + +static rnd_export_opt_t *xy_get_export_options(rnd_hid_t *hid, int *n) +{ + static int last_unit_value = -1; + rnd_conf_listitem_t *li; + int idx; + + /* load all formats from the config */ + fmt_names.used = 0; + fmt_ids.used = 0; + + free_fmts(); + rnd_conf_loop_list(&conf_xy.plugins.export_xy.templates, li, idx) { + char id[MAX_TEMP_NAME_LEN]; + const char *sep = strchr(li->name, '.'); + int len; + + if (sep == NULL) { + rnd_message(RND_MSG_ERROR, "export_xy: ignoring invalid template name (missing period): '%s'\n", li->name); + continue; + } + if (strcmp(sep+1, "name") != 0) + continue; + len = sep - li->name; + if (len > sizeof(id)-1) { + rnd_message(RND_MSG_ERROR, "export_xy: ignoring invalid template name (too long): '%s'\n", li->name); + continue; + } + memcpy(id, li->name, len); + id[len] = '\0'; + vts0_append(&fmt_names, (char *)li->payload); + vts0_append(&fmt_ids, rnd_strdup(id)); + } + + if (fmt_names.used == 0) { + rnd_message(RND_MSG_ERROR, "export_xy: can not set up export options: no template available\n"); + return NULL; + } + + xy_options[HA_format].enumerations = (const char **)fmt_names.array; + + /* set default unit and filename */ + if (xy_options[HA_unit].default_val.lng == last_unit_value) { + if (rnd_conf.editor.grid_unit) + xy_options[HA_unit].default_val.lng = rnd_conf.editor.grid_unit->index; + else + xy_options[HA_unit].default_val.lng = rnd_get_unit_struct("mil")->index; + last_unit_value = xy_options[HA_unit].default_val.lng; + } + if ((PCB != NULL) && (xy_options[HA_xyfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &xy_options[HA_xyfile], ".xy"); + + if (n) + *n = NUM_OPTIONS; + return xy_options; +} + +/* --------------------------------------------------------------------------- + * prints a centroid file in a format which includes data needed by a + * pick and place machine. Further formatting for a particular factory setup + * can easily be generated with awk or perl. + * returns != zero on error + */ + +typedef struct { + char utcTime[64]; + char *name, *descr, *value; + const char *pad_netname; + rnd_coord_t x, y; + double theta, xray_theta; + pcb_subc_t *subc; + rnd_coord_t pad_cx, pad_cy; + rnd_coord_t pad_w, pad_h; + rnd_coord_t prpad_cx, prpad_cy; + rnd_coord_t prpad_w, prpad_h; + rnd_cardinal_t count; + rnd_coord_t ox, oy; + int origin_score; + char *origin_tmp; + rnd_bool front; +} subst_ctx_t; + +/* Find the pick and place 0;0 mark, if there is any */ +static void find_origin(subst_ctx_t *ctx, const char *format_name) +{ + char tmp[128]; + pcb_data_it_t it; + pcb_any_obj_t *obj; + + rnd_snprintf(tmp, sizeof(tmp), "pnp-origin-%s", format_name); + + ctx->origin_score = 0; + ctx->ox = ctx->oy = 0; + ctx->origin_tmp = tmp; + + for(obj = pcb_data_first(&it, PCB->Data, PCB_OBJ_CLASS_REAL); obj != NULL; obj = pcb_data_next(&it)) { + int score; + + if (pcb_attribute_get(&obj->Attributes, ctx->origin_tmp) != NULL) + score = 2; /* first look for the format-specific attribute */ + else if (pcb_attribute_get(&obj->Attributes, "pnp-origin") != NULL) + score = 1; /* then for the generic pnp-specific attribute */ + else + continue; + + if (score > ctx->origin_score) { + ctx->origin_score = score; + pcb_obj_center(obj, &ctx->ox, &ctx->oy); + } + } +} + +static void calc_pad_bbox_(subst_ctx_t *ctx, rnd_coord_t *pw, rnd_coord_t *ph, rnd_coord_t *pcx, rnd_coord_t *pcy) +{ + rnd_box_t box; + box.X1 = box.Y1 = RND_MAX_COORD; + box.X2 = box.Y2 = -RND_MAX_COORD; + + if (ctx->subc != NULL) { + pcb_any_obj_t *o; + pcb_data_it_t it; + + for(o = pcb_data_first(&it, ctx->subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + if (o->term != NULL) { + if ((o->type != PCB_OBJ_PSTK) && (o->type != PCB_OBJ_SUBC)) { /* layer objects */ + pcb_layer_t *ly = o->parent.layer; + assert(o->parent_type == PCB_PARENT_LAYER); + if (!(pcb_layer_flags_(ly) & PCB_LYT_COPPER)) + continue; + } + rnd_box_bump_box(&box, &o->bbox_naked); + } + } + } + + *pw = box.X2 - box.X1; + *ph = box.Y2 - box.Y1; + *pcx = (box.X2 + box.X1)/2; + *pcy = (box.Y2 + box.Y1)/2; +} + +static void count_pins_pads(subst_ctx_t *ctx, int *pins, int *pads) +{ + *pins = *pads = 0; + + if (ctx->subc != NULL) { + pcb_any_obj_t *o; + pcb_data_it_t it; + for(o = pcb_data_first(&it, ctx->subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + pcb_layer_type_t lyt; + + if (o->term == NULL) + continue; + + /* light terminals */ + if (o->type == PCB_OBJ_PSTK) { + pcb_pstk_t *ps = (pcb_pstk_t *)o; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + + if (proto->hdia > 0) { /* through-hole */ + (*pins)++; + continue; + } + + /* smd */ + if (pcb_pstk_shape(ps, PCB_LYT_TOP | PCB_LYT_COPPER, 0)) + (*pads)++; + if (pcb_pstk_shape(ps, PCB_LYT_BOTTOM | PCB_LYT_COPPER, 0)) + (*pads)++; + continue; + } + + /* heavy terminal */ + if (o->type == PCB_OBJ_SUBC) { +TODO("subc: subc-in-subc") + assert(!"no subc-in-subc support yet"); + continue; + } + assert(o->parent_type == PCB_PARENT_LAYER); + lyt = pcb_layer_flags_(o->parent.layer); + if ((lyt & PCB_LYT_COPPER) && (lyt & (PCB_LYT_TOP || PCB_LYT_TOP))) + (*pads)++; + } + } +} + +static void calc_pad_bbox(subst_ctx_t *ctx, int prerot, rnd_coord_t *pw, rnd_coord_t *ph, rnd_coord_t *pcx, rnd_coord_t *pcy) +{ + if (prerot) { + pcb_subc_t *save, *sc_rot0; + pcb_data_t *tmp = pcb_buffers[PCB_MAX_BUFFER-1].Data; + double ang; + pcb_opctx_t op; + + /* this is what we would do if we wanted to return the pre-rotation state */ + if ((ctx->theta == 0) || (ctx->theta == 180) || (ctx->theta == -180)) { + calc_pad_bbox_(ctx, pw, ph, pcx, pcy); + return; + } + if ((ctx->theta == 90) || (ctx->theta == 270) || (ctx->theta == -90) || (ctx->theta == -270)) { + calc_pad_bbox_(ctx, ph, pw, pcx, pcy); + return; + } + + sc_rot0 = pcb_subc_dup_at(NULL, tmp, ctx->subc, 0, 0, 0, rnd_false); + ang = ctx->theta / RND_RAD_TO_DEG; + pcb_subc_rotate(sc_rot0, 0, 0, cos(ang), sin(ang), ctx->theta); + + save = ctx->subc; + ctx->subc = sc_rot0; + calc_pad_bbox_(ctx, pw, ph, pcx, pcy); + ctx->subc = save; + + op.remove.pcb = PCB; + op.remove.destroy_target = tmp; + pcb_subcop_destroy(&op, sc_rot0); + return; + } + + calc_pad_bbox_(ctx, pw, ph, pcx, pcy); +} + +static void append_clean(gds_t *dst, const char *text) +{ + const char *s; + for(s = text; *s != '\0'; s++) + if (isalnum(*s) || (*s == '.') || (*s == '-') || (*s == '+')) + gds_append(dst, *s); + else + gds_append(dst, '_'); +} + +static int is_val_true(const char *val) +{ + if (val == NULL) return 0; + if (strcmp(val, "yes") == 0) return 1; + if (strcmp(val, "on") == 0) return 1; + if (strcmp(val, "true") == 0) return 1; + if (strcmp(val, "1") == 0) return 1; + return 0; +} + +static int subst_cb(void *ctx_, gds_t *s, const char **input) +{ + int pin_cnt = 0; + int pad_cnt = 0; + subst_ctx_t *ctx = ctx_; + if (strncmp(*input, "UTC%", 4) == 0) { + *input += 4; + gds_append_str(s, ctx->utcTime); + return 0; + } + if (strncmp(*input, "author%", 7) == 0) { + *input += 7; + gds_append_str(s, pcb_author()); + return 0; + } + if (strncmp(*input, "title%", 6) == 0) { + *input += 6; + gds_append_str(s, RND_UNKNOWN(PCB->hidlib.name)); + return 0; + } + if (strncmp(*input, "suffix%", 7) == 0) { + *input += 7; + gds_append_str(s, xy_unit->suffix); + return 0; + } + if (strncmp(*input, "boardw%", 7) == 0) { + *input += 7; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, PCB->hidlib.size_x); + return 0; + } + if (strncmp(*input, "boardh%", 7) == 0) { + *input += 7; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, PCB->hidlib.size_y); + return 0; + } + if (strncmp(*input, "subc.", 5) == 0) { + *input += 5; + + /* elem attribute print: + subc.a.attribute - print the attribute if exists, "n/a" if not + subc.a.attribute|unk - print the attribute if exists, unk if not + subc.a.attribute?yes - print yes if attribute is true, "n/a" if not + subc.a.attribute?yes:nope - print yes if attribute is true, nope if not + */ + if (strncmp(*input, "a.", 2) == 0) { + char aname[256], unk_buf[256], *nope; + const char *val, *end, *unk = "n/a"; + long len; + + *input += 2; + end = strpbrk(*input, "?|%"); + len = end - *input; + if (len >= sizeof(aname) - 1) { + rnd_message(RND_MSG_ERROR, "xy tempalte error: attribute name '%s' too long\n", *input); + return 1; + } + memcpy(aname, *input, len); + aname[len] = '\0'; + if (*end == '|') { /* "or unknown" */ + *input = end+1; + end = strchr(*input, '%'); + len = end - *input; + if (len >= sizeof(unk_buf) - 1) { + rnd_message(RND_MSG_ERROR, "xy tempalte error: elem atribute '|unknown' field '%s' too long\n", *input); + return 1; + } + memcpy(unk_buf, *input, len); + unk_buf[len] = '\0'; + unk = unk_buf; + *input = end; + } + else if (*end == '?') { /* trenary */ + *input = end+1; + end = strchr(*input, '%'); + len = end - *input; + if (len >= sizeof(unk_buf) - 1) { + rnd_message(RND_MSG_ERROR, "xy tempalte error: elem atribute trenary field '%s' too long\n", *input); + return 1; + } + + memcpy(unk_buf, *input, len); + unk_buf[len] = '\0'; + *input = end+1; + + nope = strchr(unk_buf, ':'); + if (nope != NULL) { + *nope = '\0'; + nope++; + } + else /* only '?' is given, no ':' */ + nope = "n/a"; + + val = pcb_attribute_get(&ctx->subc->Attributes, aname); + if (is_val_true(val)) + gds_append_str(s, unk_buf); + else + gds_append_str(s, nope); + + return 0; + } + else + *input = end; + (*input)++; + + val = pcb_attribute_get(&ctx->subc->Attributes, aname); + if (val == NULL) + val = unk; + gds_append_str(s, val); + return 0; + } + if (strncmp(*input, "refdes%", 7) == 0) { + *input += 7; + gds_append_str(s, ctx->name); + return 0; + } + if (strncmp(*input, "refdes_%", 8) == 0) { + *input += 8; + append_clean(s, ctx->name); + return 0; + } + if (strncmp(*input, "footprint%", 10) == 0) { + *input += 10; + gds_append_str(s, ctx->descr); + return 0; + } + if (strncmp(*input, "footprint_%", 11) == 0) { + *input += 11; + append_clean(s, ctx->descr); + return 0; + } + if (strncmp(*input, "value%", 6) == 0) { + *input += 6; + gds_append_str(s, ctx->value); + return 0; + } + if (strncmp(*input, "value_%", 7) == 0) { + *input += 7; + append_clean(s, ctx->value); + return 0; + } + if (strncmp(*input, "x%", 2) == 0) { + *input += 2; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, ctx->x); + return 0; + } + if (strncmp(*input, "y%", 2) == 0) { + *input += 2; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, ctx->y); + return 0; + } + if (strncmp(*input, "padcx%", 6) == 0) { + *input += 6; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, ctx->pad_cx); + return 0; + } + if (strncmp(*input, "padcy%", 6) == 0) { + *input += 6; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, ctx->pad_cy); + return 0; + } + if (strncmp(*input, "padcx_prerot%", 13) == 0) { + *input += 13; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, ctx->prpad_cx); + return 0; + } + if (strncmp(*input, "padcy_prerot%", 13) == 0) { + *input += 13; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, ctx->prpad_cy); + return 0; + } + if (strncmp(*input, "rot%", 4) == 0) { + *input += 4; + rnd_append_printf(s, "%g", ctx->theta); + return 0; + } + if (strncmp(*input, "negrot%", 7) == 0) { + *input += 7; + rnd_append_printf(s, "%g", -ctx->theta); + return 0; + } + if (strncmp(*input, "siderot%", 8) == 0) { + *input += 8; + rnd_append_printf(s, "%g", ctx->xray_theta); + return 0; + } + if (strncmp(*input, "270-rot%", 8) == 0) { + *input += 8; + rnd_append_printf(s, "%g", (270-ctx->theta)); + return 0; + } + if (strncmp(*input, "side270-rot%", 12) == 0) { + *input += 12; + rnd_append_printf(s, "%g", (270-ctx->theta)); + return 0; + } + if (strncmp(*input, "90rot%", 6) == 0) { + *input += 6; + if (ctx->theta == 0) { + rnd_append_printf(s, "0"); + } else if (ctx->theta == 90) { + rnd_append_printf(s, "1"); + } else if (ctx->theta == 180) { + rnd_append_printf(s, "2"); + } else { + rnd_append_printf(s, "3"); + } + return 0; + } + if (strncmp(*input, "ncapbbox%", 9) == 0) { + *input += 9; + /* need to calculate element bounding box */ + return 0; + } + if (strncmp(*input, "side%", 5) == 0) { + *input += 5; + gds_append_str(s, ctx->front ? "top" : "bottom"); + return 0; + } + if (strncmp(*input, "count%", 6) == 0) { + *input += 6; + rnd_append_printf(s, "%d", ctx->count); + return 0; + } + if (strncmp(*input, "num-side%", 9) == 0) { + *input += 9; + gds_append_str(s, ctx->front ? "1" : "2"); + return 0; + } + if (strncmp(*input, "pad_width%", 10) == 0) { + *input += 10; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, ctx->pad_w); + return 0; + } + if (strncmp(*input, "pad_height%", 11) == 0) { + *input += 11; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, ctx->pad_h); + return 0; + } + if (strncmp(*input, "pad_width_prerot%", 17) == 0) { + *input += 17; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, ctx->prpad_w); + return 0; + } + if (strncmp(*input, "pad_height_prerot%", 18) == 0) { + *input += 18; + rnd_append_printf(s, "%m+%mN", xy_unit->allow, ctx->prpad_h); + return 0; + } + if (strncmp(*input, "smdvsthru%", 10) == 0) { + *input += 10; + count_pins_pads(ctx, &pin_cnt, &pad_cnt); + if (pin_cnt > 0) { + rnd_append_printf(s, "PTH"); + } else if (pad_cnt > 0) { + rnd_append_printf(s, "SMD"); + } else { + rnd_append_printf(s, "0"); + } + return 0; + } + if (strncmp(*input, "smdvsthrunum%", 13) == 0) { + *input += 13; + count_pins_pads(ctx, &pin_cnt, &pad_cnt); + if (pin_cnt > 0) { + rnd_append_printf(s, "2"); + } else if (pad_cnt > 0) { + rnd_append_printf(s, "1"); + } else { + rnd_append_printf(s, "0"); + } + return 0; + } + if (strncmp(*input, "pincount%", 9) == 0) { + *input += 9; + count_pins_pads(ctx, &pin_cnt, &pad_cnt); + if (pin_cnt > 0) { + rnd_append_printf(s, "%d", pin_cnt); + } else if (pad_cnt > 0) { + rnd_append_printf(s, "%d", pad_cnt); + } else { + rnd_append_printf(s, "0"); + } + return 0; + } + } + if (strncmp(*input, "term.", 5) == 0) { + *input += 5; + if (strncmp(*input, "netname%", 8) == 0) { + *input += 8; + if (*ctx->pad_netname != '\0') + rnd_append_printf(s, "%s", ctx->pad_netname); + else + rnd_append_printf(s, "NC"); + return 0; + } + } + return -1; +} + +static void fprintf_templ(FILE *f, subst_ctx_t *ctx, const char *templ) +{ + if (templ != NULL) { + char *tmp = rnd_strdup_subst(templ, subst_cb, ctx, RND_SUBST_PERCENT); + fprintf(f, "%s", tmp); + free(tmp); + } +} + +static void xy_translate(subst_ctx_t *ctx, rnd_coord_t *x, rnd_coord_t *y) +{ + /* translate the xy coords using explicit or implicit origin; implicit origin + is lower left corner (looking from top) of board extents */ + if (ctx->origin_score > 0) { + *y = ctx->oy - *y; + *x = *x - ctx->ox; + } + else + *y = PCB->hidlib.size_y - *y; +} + +typedef struct { + const char *hdr, *subc, *term, *foot; +} template_t; + + +static int PrintXY(const template_t *templ, const char *format_name) +{ + FILE *fp; + subst_ctx_t ctx; + + fp = rnd_fopen_askovr(&PCB->hidlib, xy_filename, "w", NULL); + if (!fp) { + rnd_message(RND_MSG_ERROR, "Cannot open file %s for writing\n", xy_filename); + return 1; + } + + ctx.count = 0; + + rnd_print_utc(ctx.utcTime, sizeof(ctx.utcTime), 0); + + find_origin(&ctx, format_name); + + fprintf_templ(fp, &ctx, templ->hdr); + + /* For each subcircuit we calculate the centroid of the footprint. */ + PCB_SUBC_LOOP(PCB->Data); + { + pcb_any_obj_t *o; + pcb_data_it_t it; + int bott; + ctx.count++; + + ctx.pad_w = ctx.pad_h = 0; + ctx.theta = ctx.xray_theta = 0.0; + + ctx.name = pcb_bom_clean_str((char *) RND_UNKNOWN(pcb_attribute_get(&subc->Attributes, "refdes"))); + ctx.descr = pcb_bom_clean_str((char *) RND_UNKNOWN(pcb_subc_name(subc, "export_xy::footprint"))); + ctx.value = pcb_bom_clean_str((char *) RND_UNKNOWN(pcb_attribute_get(&subc->Attributes, "value"))); + + /* prefer the pnp-origin but if that doesn't exist, pick the subc origin */ + if (!pcb_subc_find_aux_point(subc, "pnp-origin", &ctx.x, &ctx.y)) + if (pcb_subc_get_origin(subc, &ctx.x, &ctx.y) != 0) + rnd_message(RND_MSG_ERROR, "xy: can't get subc origin for %s\n", ctx.name); + + if (pcb_subc_get_rotation(subc, &ctx.theta) != 0) rnd_message(RND_MSG_ERROR, "xy: can't get subc rotation for %s\n", ctx.name); + if (pcb_subc_get_side(subc, &bott) != 0) rnd_message(RND_MSG_ERROR, "xy: can't get subc side for %s\n", ctx.name); + + ctx.theta = -ctx.theta; + if (ctx.theta == -0) + ctx.theta = 0; + + xy_translate(&ctx, &ctx.x, &ctx.y); + + ctx.subc = subc; + ctx.front = !bott; + +TODO("padstack: do not depend on this, just use the normal bbox and rotate that back") + calc_pad_bbox(&ctx, 0, &ctx.pad_w, &ctx.pad_h, &ctx.pad_cx, &ctx.pad_cy); + calc_pad_bbox(&ctx, 1, &ctx.prpad_w, &ctx.prpad_h, &ctx.prpad_cx, &ctx.prpad_cy); + xy_translate(&ctx, &ctx.pad_cx, &ctx.pad_cy); + + fprintf_templ(fp, &ctx, templ->subc); + + for(o = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + if (o->term != NULL) { + ctx.pad_netname = NULL; + { + pcb_net_term_t *t = pcb_net_find_by_obj(&PCB->netlist[PCB_NETLIST_EDITED], o); + if (t != NULL) + ctx.pad_netname = t->parent.net->name; + } + if (ctx.pad_netname == NULL) + ctx.pad_netname = ""; + fprintf_templ(fp, &ctx, templ->term); + } + } + + ctx.pad_netname = NULL; + + free(ctx.name); + free(ctx.descr); + free(ctx.value); + } + PCB_END_LOOP; + + fprintf_templ(fp, &ctx, templ->foot); + + fclose(fp); + + return 0; +} + +static void gather_templates(void) +{ + rnd_conf_listitem_t *i; + int n; + + rnd_conf_loop_list(&conf_xy.plugins.export_xy.templates, i, n) { + char buff[256], *id, *sect; + int nl = strlen(i->name); + if (nl > sizeof(buff)-1) { + rnd_message(RND_MSG_ERROR, "export_xy: ignoring template '%s': name too long\n", i->name); + continue; + } + memcpy(buff, i->name, nl+1); + id = buff; + sect = strchr(id, '.'); + if (sect == NULL) { + rnd_message(RND_MSG_ERROR, "export_xy: ignoring template '%s': does not have a .section suffix\n", i->name); + continue; + } + *sect = '\0'; + sect++; + } +} + +static const char *get_templ(const char *tid, const char *type) +{ + char path[MAX_TEMP_NAME_LEN + 16]; + rnd_conf_listitem_t *li; + int idx; + + sprintf(path, "%s.%s", tid, type); /* safe: tid's length is checked before it was put in the vector, type is hardwired in code and is never longer than a few chars */ + rnd_conf_loop_list(&conf_xy.plugins.export_xy.templates, li, idx) + if (strcmp(li->name, path) == 0) + return li->payload; + return NULL; +} + +static void xy_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + int i; + template_t templ; + char **tid; + pcb_cam_t cam; + + memset(&templ, 0, sizeof(templ)); + + + gather_templates(); + + if (!options) { + xy_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + xy_values[i] = xy_options[i].default_val; + options = xy_values; + } + + xy_filename = options[HA_xyfile].str; + if (!xy_filename) + xy_filename = "pcb-out.xy"; + + pcb_cam_begin_nolayer(PCB, &cam, NULL, options[HA_cam].str, &xy_filename); + + if (options[HA_unit].lng == -1) + xy_unit = rnd_get_unit_struct("mil"); + else + xy_unit = &rnd_units[options[HA_unit].lng]; + + tid = vts0_get(&fmt_ids, options[HA_format].lng, 0); + if ((tid == NULL) || (*tid == NULL)) { + rnd_message(RND_MSG_ERROR, "export_xy: invalid template selected\n"); + return; + } + templ.hdr = get_templ(*tid, "hdr"); + templ.subc = get_templ(*tid, "subc"); + templ.term = get_templ(*tid, "term"); + + PrintXY(&templ, options[HA_format].str); + pcb_cam_end(&cam); +} + +static int xy_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\nXY exporter command line arguments:\n\n"); + rnd_hid_usage(xy_options, sizeof(xy_options) / sizeof(xy_options[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x xy [xy_options] foo.pcb\n\n"); + return 0; +} + +static int xy_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(xy_options, sizeof(xy_options) / sizeof(xy_options[0]), xy_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +rnd_hid_t xy_hid; + +int pplg_check_ver_export_xy(int ver_needed) { return 0; } + +void pplg_uninit_export_xy(void) +{ + rnd_export_remove_opts_by_cookie(xy_cookie); + rnd_conf_unreg_file(CONF_FN, export_xy_conf_internal); + rnd_conf_unreg_fields("plugins/export_xy/"); + free_fmts(); + vts0_uninit(&fmt_names); + vts0_uninit(&fmt_ids); + rnd_hid_remove_hid(&xy_hid); +} + + +int pplg_init_export_xy(void) +{ + RND_API_CHK_VER; + + rnd_conf_reg_file(CONF_FN, export_xy_conf_internal); + + memset(&xy_hid, 0, sizeof(rnd_hid_t)); + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_xy, field,isarray,type_name,cpath,cname,desc,flags); +#include "xy_conf_fields.h" + + rnd_hid_nogui_init(&xy_hid); + + xy_hid.struct_size = sizeof(rnd_hid_t); + xy_hid.name = "XY"; + xy_hid.description = "Exports a XY (centroid)"; + xy_hid.exporter = 1; + + xy_hid.get_export_options = xy_get_export_options; + xy_hid.do_export = xy_do_export; + xy_hid.parse_arguments = xy_parse_arguments; + + xy_hid.usage = xy_usage; + + rnd_hid_register_hid(&xy_hid); + + vts0_init(&fmt_names); + vts0_init(&fmt_ids); + return 0; +} Index: tags/2.3.0/src_plugins/export_xy/xy_conf.h =================================================================== --- tags/2.3.0/src_plugins/export_xy/xy_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/export_xy/xy_conf.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_VENDOR_CONF_H +#define PCB_VENDOR_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_LIST templates; + } export_xy; + } plugins; +} conf_xy_t; + +#endif Index: tags/2.3.0/src_plugins/extedit/Makefile =================================================================== --- tags/2.3.0/src_plugins/extedit/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/extedit/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_extedit + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/extedit/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/extedit/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/extedit/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {extedit} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/extedit/extedit.o +@] + +switch /local/pcb/extedit/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/extedit/extedit.c =================================================================== --- tags/2.3.0/src_plugins/extedit/extedit.c (nonexistent) +++ tags/2.3.0/src_plugins/extedit/extedit.c (revision 33253) @@ -0,0 +1,357 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "board.h" +#include +#include +#include "conf_core.h" +#include "data.h" +#include "buffer.h" +#include +#include "remove.h" +#include +#include "search.h" +#include "undo.h" +#include "../src_plugins/io_lihata/io_lihata.h" +#include "../src_plugins/io_lihata/write.h" +#include "../src_plugins/io_lihata/read.h" + +/* List of all available external edit methods */ +typedef enum { + EEF_LIHATA, + EEF_max +} extedit_fmt_t; + +const char *extedit_fmt_names[EEF_max+1] = { + "lihata", + NULL +}; + +typedef struct extedit_method_s { + char *name; + long types; + extedit_fmt_t fmt; + char *command; +} extedit_method_t; + +static extedit_method_t methods[] = { + {"pcb-rnd", PCB_OBJ_SUBC, EEF_LIHATA, "pcb-rnd -C \"design;%c\" \"%f\""}, + {"pcb-rnd (no cfg)", PCB_OBJ_SUBC, EEF_LIHATA, "pcb-rnd \"%f\""}, + {"editor", PCB_OBJ_SUBC, EEF_LIHATA, "xterm -e editor \"%f\""}, + {NULL, 0, 0, NULL} +}; + +/* accept these objects for external editing */ +#define EXTEDIT_TYPES (PCB_OBJ_SUBC) + +#include "extedit_dad.c" + +/* HID-dependent, portable watch of child process */ +typedef struct { + FILE *fc; + int stay; + rnd_hidval_t wid; +} extedit_wait_t; + +rnd_bool extedit_fd_watch(rnd_hidval_t watch, int fd, unsigned int condition, rnd_hidval_t user_data) +{ + char tmp[128]; + int res; + extedit_wait_t *ctx = user_data.ptr; + + /* excess callbacks */ + if (!ctx->stay) + return rnd_true; + + res = fread(tmp, 1, sizeof(tmp), ctx->fc); + if (res <= 0) { + ctx->stay = 0; + return rnd_false; /* also disables/removes the watch */ + } + return rnd_true; +} + +/* Invoke the child process, display a "progress bar" or some other indication + while it's running and wait for it to exit (preferrably keeping the gui + refreshed, even if the process is blocking) */ +static void invoke(extedit_method_t *mth, const char *fn, const char *fn_cfg) +{ + rnd_build_argfn_t subs; + char *cmd; + FILE *fc; + + memset(&subs, 0, sizeof(subs)); + subs.params['f' - 'a'] = fn; + subs.params['c' - 'a'] = fn_cfg; + subs.hidlib = &PCB->hidlib; + cmd = rnd_build_argfn(mth->command, &subs); + + /* Don't use rnd_system() because that blocks the current process and the + GUI toolkit won't have a chance to handle expose events */ + fc = rnd_popen(&PCB->hidlib, cmd, "r"); + + if (rnd_gui != NULL) { + int fd = rnd_fileno(fc); + if (fd > 0) { + int n = 0; + rnd_hidval_t hd; + extedit_wait_t ctx; + + ctx.stay = 1; + ctx.fc = fc; + hd.ptr = &ctx; + ctx.wid = rnd_gui->watch_file(rnd_gui, fd, RND_WATCH_READABLE | RND_WATCH_HANGUP, extedit_fd_watch, hd); + while(ctx.stay) { + if (rnd_gui != NULL) { + n++; + rnd_hid_progress(50+sin((double)n/10.0)*40, 100, "Invoked external editor. Please edit, save and close there to finish this operation"); + } + rnd_ms_sleep(50); + } + } + else + goto old_wait; + } + else { + old_wait:; + + if (rnd_gui != NULL) { + rnd_hid_progress(50, 100, "Invoked external editor. Please edit, save and close there to finish this operation"); + rnd_ms_sleep(1000); /* ugly hack: give the GUI some time to flush */ + } + while(!(feof(fc))) { + char tmp[128]; + fread(tmp, 1, sizeof(tmp), fc); + } + } + pclose(fc); + + if (rnd_gui != NULL) + rnd_hid_progress(0, 0, NULL); + free(cmd); +} + + + +static const char pcb_acts_extedit[] = "extedit(object|selected|buffer, [interactive|method])\n"; +static const char pcb_acth_extedit[] = "Invoke an external program to edit a specific part of the current board."; +static fgw_error_t pcb_act_extedit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd = NULL, *method = NULL; + long type; + void *ptr1, *ptr2, *ptr3; + extedit_method_t *mth = NULL; + char *tmp_fn, *tmp_cfg_fn; + int ret = 1; + FILE *f; + int bn = PCB_MAX_BUFFER - 1, load_bn = PCB_MAX_BUFFER - 1; + int obn = conf_core.editor.buffer_number; + int paste = 0, del_selected = 0; + rnd_coord_t pastex = 0, pastey = 0; + + RND_ACT_MAY_CONVARG(1, FGW_STR, extedit, cmd = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, extedit, method = argv[2].val.str); + + /* pick up the object to edit */ + if ((cmd == NULL) || (rnd_strcasecmp(cmd, "object") == 0)) { + rnd_coord_t x, y; + rnd_hid_get_coords("Click on object to edit", &x, &y, 0); + type = pcb_search_screen(x, y, EXTEDIT_TYPES, &ptr1, &ptr2, &ptr3); + + pcb_buffer_set_number(bn); + pcb_buffer_clear(PCB, PCB_PASTEBUFFER); + if (pcb_copy_obj_to_buffer(PCB, pcb_buffers[bn].Data, PCB->Data, type, ptr1, ptr2, ptr3) == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to copy target objects to temporary paste buffer\n"); + goto quit0; + } + paste = 1; + } + else if ((argc > 1) && (rnd_strcasecmp(cmd, "selected") == 0)) { + pcb_buffer_set_number(bn); + pcb_buffer_clear(PCB, PCB_PASTEBUFFER); + pcb_buffer_add_selected(PCB, PCB_PASTEBUFFER, pcb_crosshair.X, pcb_crosshair.Y, rnd_false, rnd_false); + pastex = pcb_crosshair.X; + pastey = pcb_crosshair.Y; + del_selected = 1; + paste = 1; + if (pcb_data_is_empty(PCB_PASTEBUFFER->Data)) { + rnd_message(RND_MSG_WARNING, "Nothing is selected, can't ext-edit selection\n"); + goto quit0; + } + } + else if ((argc > 1) && (rnd_strcasecmp(cmd, "buffer") == 0)) { + load_bn = bn = conf_core.editor.buffer_number; + if (pcb_data_is_empty(PCB_PASTEBUFFER->Data)) { + rnd_message(RND_MSG_WARNING, "Nothing in current buffer, can't ext-edit selection\n"); + goto quit0; + } + } + else { + rnd_message(RND_MSG_ERROR, "Wrong 1st argument '%s'\n", cmd); + ret = 1; + goto quit0; + } + + /* determine the method */ + if (argc > 2) { + for(mth = methods; mth->name != NULL; mth++) { + if (rnd_strcasecmp(mth->name, method) == 0) + break; + } + if (mth->name == NULL) { + rnd_message(RND_MSG_ERROR, "unknown method '%s'; available methods:\n", method); + for(mth = methods; mth->name != NULL; mth++) { + if (mth != methods) + rnd_message(RND_MSG_ERROR, ", ", mth->name); + rnd_message(RND_MSG_ERROR, "%s", mth->name); + } + rnd_message(RND_MSG_ERROR, "\n"); + ret = 1; + goto quit0; + } + } + if (mth == NULL) { + mth = extedit_interactive(); + if (mth == NULL) { /* no method selected */ + ret = 1; + goto quit0; + } + } + + tmp_fn = rnd_tempfile_name_new("extedit"); + tmp_cfg_fn = rnd_tempfile_name_new("extedit_cfg"); + if ((tmp_fn == NULL) || (tmp_cfg_fn == NULL)) { + rnd_message(RND_MSG_ERROR, "Failed to create temporary file\n"); + ret = 1; + goto quit1; + } + + /* export */ + switch(mth->fmt) { + case EEF_LIHATA: + { + int res; + void *udata; + + rnd_conf_save_file(&PCB->hidlib, NULL, NULL, RND_CFR_DESIGN, tmp_cfg_fn); + + f = rnd_fopen(&PCB->hidlib, tmp_fn, "w"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to open temporary file\n"); + goto quit1; + } + + res = io_lihata_write_subcs_head(plug_io_lihata_default, &udata, f, 0, 1); + if (res == 0) { + res |= io_lihata_write_subcs_subc(plug_io_lihata_default, &udata, f, pcb_subclist_first(&pcb_buffers[bn].Data->subc)); + res |= io_lihata_write_subcs_tail(plug_io_lihata_default, &udata, f); + } + + if (res != 0) { + fclose(f); + rnd_message(RND_MSG_ERROR, "Failed to export target objects to lihata footprint.\n"); + goto quit1; + } + fclose(f); + } + break; + case EEF_max: + break; + } + + /* invoke external program */ + invoke(mth, tmp_fn, tmp_cfg_fn); + + /* load the result */ + switch(mth->fmt) { + case EEF_LIHATA: + { + int bn = load_bn; + + pcb_buffer_set_number(bn); + pcb_buffer_clear(PCB, PCB_PASTEBUFFER); + + if (io_lihata_parse_subc(plug_io_lihata_default, pcb_buffers[bn].Data, tmp_fn, NULL) != 0) { + rnd_message(RND_MSG_ERROR, "Failed to load the edited footprint. File left at '%s'.\n", tmp_fn); + ret = 1; + goto quit1; + } + + if (del_selected) + pcb_remove_selected(rnd_true); + if (paste) { + pcb_undo_save_serial(); + pcb_buffer_copy_to_layout(PCB, pastex, pastey, rnd_false); + pcb_undo_restore_serial(); + pcb_remove_object(type, ptr1, ptr2, ptr3); + pcb_undo_inc_serial(); + } + ret = 0; + } + case EEF_max: + break; + } + if (rnd_gui != NULL) + rnd_gui->invalidate_all(rnd_gui); + + quit1:; + if (tmp_fn != NULL) + rnd_tempfile_unlink(tmp_fn); + if (tmp_cfg_fn != NULL) + rnd_tempfile_unlink(tmp_cfg_fn); + quit0:; + pcb_buffer_set_number(obn); + RND_ACT_IRES(ret); + return 0; +} + +static rnd_action_t extedit_action_list[] = { + {"extedit", pcb_act_extedit, pcb_acts_extedit, pcb_acth_extedit} +}; + +static const char *extedit_cookie = "extedit plugin"; + +int pplg_check_ver_extedit(int ver_needed) { return 0; } + +void pplg_uninit_extedit(void) +{ + rnd_remove_actions_by_cookie(extedit_cookie); +} + +int pplg_init_extedit(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(extedit_action_list, extedit_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/extedit/extedit.pup =================================================================== --- tags/2.3.0/src_plugins/extedit/extedit.pup (nonexistent) +++ tags/2.3.0/src_plugins/extedit/extedit.pup (revision 33253) @@ -0,0 +1,8 @@ +$class feature +$short edit with external program +$long invoke external program to edit parts of the current board +$state works +$package (core) +dep io_lihata +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/extedit/extedit_dad.c =================================================================== --- tags/2.3.0/src_plugins/extedit/extedit_dad.c (nonexistent) +++ tags/2.3.0/src_plugins/extedit/extedit_dad.c (revision 33253) @@ -0,0 +1,129 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int mthi; + + int wmethod, wfmt, wcmd; +} ee_t; + +#define NUM_METHODS (sizeof(methods) / sizeof(methods[0])) + +static void ee_data2dialog(ee_t *ee) +{ + RND_DAD_SET_VALUE(ee->dlg_hid_ctx, ee->wmethod, lng, ee->mthi); + RND_DAD_SET_VALUE(ee->dlg_hid_ctx, ee->wfmt, lng, methods[ee->mthi].fmt); + RND_DAD_SET_VALUE(ee->dlg_hid_ctx, ee->wcmd, str, rnd_strdup(methods[ee->mthi].command)); + + /* we have only one format, so disable the combo box for selecting it */ + rnd_gui->attr_dlg_widget_state(ee->dlg_hid_ctx, ee->wfmt, rnd_false); +} + +static void ee_chg_method(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + static int lock = 0; + ee_t *ee = caller_data; + + if (lock) + return; + + ee->mthi = ee->dlg[ee->wmethod].val.lng; + + lock = 1; + ee_data2dialog(ee); + lock = 0; +} + +static void ee_chg_cmd(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + static int lock = 0; + ee_t *ee = caller_data; + + if (lock) + return; + + methods[ee->mthi].command = rnd_strdup(ee->dlg[ee->wcmd].val.str); + + lock = 1; + ee_data2dialog(ee); + lock = 0; +} + + +/* DAD-based interactive method editor */ +static extedit_method_t *extedit_interactive(void) +{ + ee_t ee; + char tmp[256]; + const char *names[NUM_METHODS+1]; + int n, res; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"Edit!", 0}, {NULL, 0}}; + + for(n = 0; n < NUM_METHODS; n++) + names[n] = methods[n].name; + names[n] = NULL; + + memset(&ee, 0, sizeof(ee)); + + RND_DAD_BEGIN_VBOX(ee.dlg); + sprintf(tmp, "Select external editor..."); + RND_DAD_LABEL(ee.dlg, tmp); + + RND_DAD_BEGIN_HBOX(ee.dlg); + RND_DAD_LABEL(ee.dlg, "Method name:"); + RND_DAD_ENUM(ee.dlg, names); + ee.wmethod = RND_DAD_CURRENT(ee.dlg); + RND_DAD_CHANGE_CB(ee.dlg, ee_chg_method); + RND_DAD_END(ee.dlg); + + RND_DAD_BEGIN_HBOX(ee.dlg); + RND_DAD_LABEL(ee.dlg, "File format:"); + RND_DAD_ENUM(ee.dlg, extedit_fmt_names); + ee.wfmt = RND_DAD_CURRENT(ee.dlg); + RND_DAD_END(ee.dlg); + + RND_DAD_BEGIN_HBOX(ee.dlg); + RND_DAD_LABEL(ee.dlg, "Command template:"); + RND_DAD_STRING(ee.dlg); + ee.wcmd = RND_DAD_CURRENT(ee.dlg); + RND_DAD_CHANGE_CB(ee.dlg, ee_chg_cmd); + RND_DAD_END(ee.dlg); + RND_DAD_BUTTON_CLOSES(ee.dlg, clbtn); + RND_DAD_END(ee.dlg); + + RND_DAD_NEW("extedit", ee.dlg, "External editor", &ee, rnd_true, NULL); + + ee_data2dialog(&ee); + res = RND_DAD_RUN(ee.dlg); + + RND_DAD_FREE(ee.dlg); + if (res != 0) + return NULL; + return &methods[ee.mthi]; +} Index: tags/2.3.0/src_plugins/exto_std/Makefile =================================================================== --- tags/2.3.0/src_plugins/exto_std/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/exto_std/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_exto_std + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/exto_std/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/exto_std/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/exto_std/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {exto_std} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/exto_std/exto_std.o +@] + + +switch /local/pcb/exto_std/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/exto_std/bus.c =================================================================== --- tags/2.3.0/src_plugins/exto_std/bus.c (nonexistent) +++ tags/2.3.0/src_plugins/exto_std/bus.c (revision 33253) @@ -0,0 +1,412 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * Extended object for a bus; edit: thick line; places parallel thin lines + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#define LID_EDIT 0 +#define LID_TARGET 1 + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int gui_active; + int width; + rnd_coord_t pitch; + rnd_coord_t thickness; + rnd_coord_t clearance; + + /* cache: */ + rnd_coord_t vthickness; /* virtual thickness (edit object's) */ +} bus_t; + +static void pcb_bus_del_pre(pcb_subc_t *subc) +{ + bus_t *bus = subc->extobj_data; + rnd_trace("bus del_pre\n"); + + if ((bus != NULL) && (bus->gui_active)) + RND_DAD_FREE(bus->dlg); + + free(bus); + subc->extobj_data = NULL; +} + +static void bus_unpack(pcb_subc_t *obj) +{ + bus_t *bus; + + if (obj->extobj_data == NULL) + obj->extobj_data = calloc(sizeof(bus_t), 1); + bus = obj->extobj_data; + + pcb_extobj_unpack_int(obj, &bus->width, "extobj::width"); + pcb_extobj_unpack_coord(obj, &bus->thickness, "extobj::thickness"); + pcb_extobj_unpack_coord(obj, &bus->clearance, "extobj::clearance"); + pcb_extobj_unpack_coord(obj, &bus->pitch, "extobj::pitch"); + bus->vthickness = (bus->width - 1) * bus->pitch + bus->thickness; +} + +/* remove all bus traces from the subc */ +static void bus_clear(pcb_subc_t *subc) +{ + pcb_line_t *l, *next; + pcb_layer_t *ely = &subc->data->Layer[LID_TARGET]; + + for(l = linelist_first(&ely->Line); l != NULL; l = next) { + next = linelist_next(l); + if (PCB_FLAG_TEST(PCB_FLAG_FLOATER, l)) continue; /* do not free the floater */ + pcb_poly_restore_to_poly(ely->parent.data, PCB_OBJ_LINE, ely, l); + pcb_line_free(l); + } +} + +#define bus_seg_def \ + double vx, vy, nx, ny, len + +#define bus_seg_calc(l) \ + do { \ + vx = l->Point2.X - l->Point1.X; \ + vy = l->Point2.Y - l->Point1.Y; \ + len = sqrt(vx*vx + vy *vy); \ + vx /= len; \ + vy /= len; \ + nx = -vy; \ + ny = vx; \ + } while(0) + +static int close_enough(rnd_point_t a, rnd_point_t b) +{ + rnd_coord_t dx = a.X - b.X, dy = a.Y - b.Y; + + if (dx < -1) return 0; + if (dx > +1) return 0; + if (dy < -1) return 0; + if (dy > +1) return 0; + return 1; +} + +/* create all new padstacks */ +static int bus_gen(pcb_subc_t *subc, pcb_any_obj_t *edit_obj) +{ + bus_t *bus; + pcb_line_t *l1 = NULL, *l, *ltmp; + pcb_layer_t *ely = &subc->data->Layer[LID_EDIT]; + pcb_layer_t *tly = &subc->data->Layer[LID_TARGET]; + double o0; + + if (subc->extobj_data == NULL) + bus_unpack(subc); + bus = subc->extobj_data; + + pcb_exto_regen_begin(subc); + + o0 = ((bus->width - 1) * bus->pitch)/2; + for(l = linelist_first(&ely->Line); l != NULL; l = linelist_next(l)) { + rnd_rtree_box_t sb; + rnd_rtree_it_t it; + bus_seg_def; + double o = o0, a1 = 0, a2 = 0, tune1, tune2; + int n, c1 = 0, c2 = 0; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, l)) continue; /* gen only for floater */ + + l->Thickness = bus->vthickness; + if (l1 == NULL) l1 = l; + +/* rnd_trace("line\n");*/ + sb.x1 = l->Point1.X-1; sb.y1 = l->Point1.Y-1; + sb.x2 = l->Point1.X+1; sb.y2 = l->Point1.Y+1; + for(ltmp = rnd_rtree_first(&it, ely->line_tree, &sb); ltmp != NULL; ltmp = rnd_rtree_next(&it)) + { + if ((ltmp == l) || (ltmp->parent.any != l->parent.any)) continue; + if (close_enough(l->Point1, ltmp->Point1)) { + a1 = atan2(ltmp->Point2.Y - ltmp->Point1.Y, ltmp->Point2.X - ltmp->Point1.X); + c1 = 1; +/* rnd_trace(" conn1 2-1 %f\n", a1);*/ + break; + } + else if (close_enough(l->Point1, ltmp->Point2)) { + a1 = atan2(ltmp->Point1.Y - ltmp->Point2.Y, ltmp->Point1.X - ltmp->Point2.X); + c1 = 1; +/* rnd_trace(" conn1 1-2 %f\n", a1);*/ + break; + } + } + sb.x1 = l->Point2.X-1; sb.y1 = l->Point2.Y-1; + sb.x2 = l->Point2.X+1; sb.y2 = l->Point2.Y+1; + for(ltmp = rnd_rtree_first(&it, ely->line_tree, &sb); ltmp != NULL; ltmp = rnd_rtree_next(&it)) + { + if ((ltmp == l) || (ltmp->parent.any != l->parent.any)) continue; + if (close_enough(l->Point2, ltmp->Point1)) { + a2 = atan2(ltmp->Point2.Y - ltmp->Point1.Y, ltmp->Point2.X - ltmp->Point1.X); + c2 = 1; +/* rnd_trace(" conn2 2-1 %f\n", a1);*/ + break; + } + if (close_enough(l->Point2, ltmp->Point2)) { + a2 = atan2(ltmp->Point1.Y - ltmp->Point2.Y, ltmp->Point1.X - ltmp->Point2.X); + c2 = 1; +/* rnd_trace(" conn2 2-1 %f\n", a1);*/ + break; + } + } + + bus_seg_calc(l); + + if (c1) { + double a0 = atan2(l->Point1.Y - l->Point2.Y, l->Point1.X - l->Point2.X); +/*rnd_trace("c1 a0=%f a1=%f\n", a0 * RND_RAD_TO_DEG, a1 * RND_RAD_TO_DEG);*/ + a1 = a1 - a0; + tune1 = tan(a1/2.0); + } + else + tune1 = 0; + + if (c2) { + double a0 = atan2(l->Point2.Y - l->Point1.Y, l->Point2.X - l->Point1.X); +/*rnd_trace("c1 a0=%f a2=%f\n", a0 * RND_RAD_TO_DEG, a2 * RND_RAD_TO_DEG);*/ + a2 = a2 - a0; + tune2 = tan(a2/2.0); + } + else + tune2 = 0; + +/* rnd_trace("tune: %f:%f %f:%f\n", a1 * RND_RAD_TO_DEG, tune1, a2 * RND_RAD_TO_DEG, tune2);*/ + + for(n = 0; n < bus->width; n++,o-=bus->pitch) { + double o2 = -o; + pcb_line_t *new_line; +/* rnd_trace(" off1: %f %f %ml = %ml\n", vx, tune1, (rnd_coord_t)o, (rnd_coord_t)(vx * tune1 * o)); + rnd_trace(" off2: %f %f %ml = %ml\n", vx, tune2, (rnd_coord_t)o, (rnd_coord_t)(vx * tune2 * o));*/ + new_line = pcb_line_new(tly, + l->Point1.X + nx * o + vx * tune1 * o2, l->Point1.Y + ny * o + vy * tune1 * o2, + l->Point2.X + nx * o + vx * tune2 * o2, l->Point2.Y + ny * o + vy * tune2 * o2, + bus->thickness, bus->clearance*2, pcb_flag_make(PCB_FLAG_CLEARLINE)); + if (new_line != NULL) + pcb_poly_clear_from_poly(tly->parent.data, PCB_OBJ_LINE, tly, new_line); + } + + } + + if (l1 != NULL) { +rnd_trace("bus origin at %mm %mm\n", l1->Point1.X, l1->Point1.Y); + pcb_subc_move_origin_to(subc, l1->Point1.X, l1->Point1.Y, 0); + } + return pcb_exto_regen_end(subc); +} + +static void pcb_bus_draw_mark(pcb_draw_info_t *info, pcb_subc_t *subc) +{ + bus_t *bus; + pcb_line_t *l; + pcb_layer_t *ly = &subc->data->Layer[LID_EDIT]; + + if (subc->extobj_data == NULL) + bus_unpack(subc); + bus = subc->extobj_data; + + rnd_render->set_color(pcb_draw_out.fgGC, &conf_core.appearance.color.extobj); + rnd_hid_set_line_width(pcb_draw_out.fgGC, -1); + + for(l = linelist_first(&ly->Line); l != NULL; l = linelist_next(l)) { + rnd_coord_t x, y; + double o; + bus_seg_def; + + if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, l)) continue; + + bus_seg_calc(l); + + x = l->Point1.X; y = l->Point1.Y; + for(o = 0; o < len; o += RND_MM_TO_COORD(5), x += vx*RND_MM_TO_COORD(5), y += vy*RND_MM_TO_COORD(5)) + rnd_render->draw_line(pcb_draw_out.fgGC, + x + nx * bus->vthickness/2, y + ny * bus->vthickness/2, + x - nx * bus->vthickness/2, y - ny * bus->vthickness/2); + } + + pcb_exto_draw_mark(info, subc); +} + + +static void pcb_bus_float_pre(pcb_subc_t *subc, pcb_any_obj_t *edit_obj) +{ + rnd_trace("bus: edit pre %ld %ld\n", subc->ID, edit_obj->ID); + bus_clear(subc); +} + +static void pcb_bus_float_geo(pcb_subc_t *subc, pcb_any_obj_t *edit_obj) +{ + rnd_trace("bus: edit geo %ld %ld\n", subc->ID, edit_obj == NULL ? -1 : edit_obj->ID); + bus_gen(subc, edit_obj); +} + +static pcb_extobj_new_t pcb_bus_float_new(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + rnd_trace("bus: float new %ld %ld\n", subc->ID, floater->ID); + bus_clear(subc); /* a new floater may affect existing rendered line lengths at junctions, it's better to recalc the whole bus */ + return PCB_EXTONEW_FLOATER; +} + +static pcb_extobj_del_t pcb_bus_float_del(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + pcb_layer_t *ly = &subc->data->Layer[LID_EDIT]; + long len = linelist_length(&ly->Line); + + rnd_trace("bus: float del %ld %ld edit-objs=%ld\n", subc->ID, floater->ID, len); + + return len == 1 ? PCB_EXTODEL_SUBC : PCB_EXTODEL_FLOATER; /* removing the last floater should remove the subc */ +} + + +static void pcb_bus_chg_attr(pcb_subc_t *subc, const char *key, const char *value) +{ + rnd_trace("bus chg_attr\n"); + if (strncmp(key, "extobj::", 8) == 0) { + bus_clear(subc); + bus_unpack(subc); + bus_gen(subc, NULL); + } +} + + +static pcb_subc_t *pcb_bus_conv_objs(pcb_data_t *dst, vtp0_t *objs, pcb_subc_t *copy_from) +{ + long n; + pcb_subc_t *subc; + pcb_line_t *l; + pcb_layer_t *ly; + pcb_dflgmap_t layers[] = { + {"edit", PCB_LYT_DOC, "extobj", 0, 0}, + {"target", PCB_LYT_COPPER, NULL, 0, 0}, + {NULL, 0, NULL, 0, 0} + }; + + rnd_trace("bus: conv_objs\n"); + + /* refuse anything that's not a line */ + for(n = 0; n < objs->used; n++) { + l = objs->array[n]; + if (l->type != PCB_OBJ_LINE) + return NULL; + } + + /* use the layer of the first object for edit */ + l = objs->array[0]; + layers[0].lyt = pcb_layer_flags_(l->parent.layer); + pcb_layer_purpose_(l->parent.layer, &layers[0].purpose); + + /* use current layer for target */ + ly = PCB_CURRLAYER(PCB); + layers[1].lyt = pcb_layer_flags_(ly); + pcb_layer_purpose_(ly, &layers[1].purpose); + + + subc = pcb_exto_create(dst, "bus", layers, l->Point1.X, l->Point1.Y, 0, copy_from); + if (copy_from == NULL) { + char tmp[32]; + pcb_attribute_put(&subc->Attributes, "extobj::width", "2"); + rnd_sprintf(tmp, "%$$mH", conf_core.design.line_thickness + conf_core.design.clearance/2); + pcb_attribute_put(&subc->Attributes, "extobj::pitch", tmp); + rnd_sprintf(tmp, "%$$mH", conf_core.design.line_thickness); + pcb_attribute_put(&subc->Attributes, "extobj::thickness", tmp); + rnd_sprintf(tmp, "%$$mH", conf_core.design.clearance); + pcb_attribute_put(&subc->Attributes, "extobj::clearance", tmp); + } + + if (layers[1].lyt & PCB_LYT_INTERN) { + TODO("Set offset and update binding"); + } + + bus_unpack(subc); + +TODO("set vthickness"); + /* create edit-objects */ + ly = &subc->data->Layer[LID_EDIT]; + for(n = 0; n < objs->used; n++) { + l = pcb_line_dup(ly, objs->array[n]); + PCB_FLAG_SET(PCB_FLAG_FLOATER, l); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, l); + pcb_attribute_put(&l->Attributes, "extobj::role", "edit"); +rnd_trace(" subc=%p l=%p\n", subc, ly); + } + + bus_gen(subc, NULL); + return subc; +} + + +static void pcb_bus_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + pcb_subc_t *subc = caller_data; + bus_t *bus = subc->extobj_data; + + RND_DAD_FREE(bus->dlg); + bus->gui_active = 0; +} + +static void pcb_bus_gui_propedit(pcb_subc_t *subc) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + bus_t *bus; + + rnd_trace("bus: gui propedit\n"); + + if (subc->extobj_data == NULL) + bus_unpack(subc); + bus = subc->extobj_data; + + rnd_trace("bus: active=%d\n", bus->gui_active); + if (bus->gui_active) + return; /* do not open another */ + + RND_DAD_BEGIN_VBOX(bus->dlg); + RND_DAD_COMPFLAG(bus->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABLE(bus->dlg, 2); + pcb_exto_dlg_int(bus->dlg, subc, "width", "extobj::width", "number of traces in the bus"); + pcb_exto_dlg_coord(bus->dlg, subc, "thickness", "extobj::thickness", "thickness of each trace"); + pcb_exto_dlg_coord(bus->dlg, subc, "clearance", "extobj::clearance", "clearance on each trace"); + pcb_exto_dlg_coord(bus->dlg, subc, "pitch", "extobj::pitch", "distance between trace centerlines"); + RND_DAD_END(bus->dlg); + RND_DAD_BUTTON_CLOSES(bus->dlg, clbtn); + RND_DAD_END(bus->dlg); + + /* set up the context */ + bus->gui_active = 1; + + RND_DAD_NEW("bus", bus->dlg, "Bus", subc, rnd_false, pcb_bus_close_cb); +} + +static pcb_extobj_t pcb_bus = { + "bus", + pcb_bus_draw_mark, + pcb_bus_float_pre, + pcb_bus_float_geo, + pcb_bus_float_new, + pcb_bus_float_del, + pcb_bus_chg_attr, + pcb_bus_del_pre, + pcb_bus_conv_objs, + pcb_bus_gui_propedit +}; Index: tags/2.3.0/src_plugins/exto_std/cord.c =================================================================== --- tags/2.3.0/src_plugins/exto_std/cord.c (nonexistent) +++ tags/2.3.0/src_plugins/exto_std/cord.c (revision 33253) @@ -0,0 +1,460 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * Extended object for a cords: insulated wires with 1 or 2 conductive end(s) + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "search.h" +#include "data_parent.h" + +#define LID_EDIT 0 +#define LID_TARGET 1 +#define COPPER_END 0 +#define SILK_END 1 +#define CTRL_END 2 + +#define BEZIER + +static char cord_footprint[] = "fp"; + +static const char *group_of(pcb_any_obj_t *floater) +{ + const char *grp = pcb_attribute_get(&floater->Attributes, "cord::group"); + if ((grp == NULL) || (*grp == '\0')) return NULL; + return grp; +} + +static void set_grp(pcb_any_obj_t *obj, const char *grp) +{ + pcb_attribute_put(&obj->Attributes, "cord::group", grp); +} + +static void cord_clear_ly(pcb_subc_t *subc, pcb_layer_t *ly, const char *group) +{ + pcb_line_t *l, *next; + + for(l = linelist_first(&ly->Line); l != NULL; l = next) { + next = linelist_next(l); + if (group != NULL) { + const char *lg = group_of((pcb_any_obj_t *)l); + if ((lg == NULL) || (strcmp(lg, group) != 0)) continue; + } + pcb_line_free(l); + } +} + +/* remove all existing graphics from the subc */ +static void cord_clear(pcb_subc_t *subc, const char *group) +{ + cord_clear_ly(subc, &subc->data->Layer[LID_TARGET], group); + cord_clear_ly(subc, &subc->data->Layer[LID_EDIT], group); + +} + + +/* find the two endpoint padstacks of a group */ +static void cord_get_ends(pcb_subc_t *subc, const char *group, pcb_pstk_t **end1, pcb_arc_t **ctrl1, pcb_pstk_t **end2, pcb_arc_t **ctrl2) +{ + pcb_pstk_t *p; + pcb_arc_t *a; + pcb_layer_t *ely = &subc->data->Layer[LID_EDIT]; + + *end1 = *end2 = NULL; + *ctrl1 = *ctrl2 = NULL; + + for(p = padstacklist_first(&subc->data->padstack); p != NULL; p = padstacklist_next(p)) { + const char *lg = group_of((pcb_any_obj_t *)p), *idxs = pcb_attribute_get(&p->Attributes, "extobj::idx"); + if ((lg == NULL) || (strcmp(lg, group) != 0) || (idxs == NULL)) continue; + if (idxs[0] == '0') *end1 = p; + else if (idxs[0] == '1') *end2 = p; + } + + for(a = arclist_first(&ely->Arc); a != NULL; a = arclist_next(a)) { + const char *lg = group_of((pcb_any_obj_t *)a), *idxs = pcb_attribute_get(&a->Attributes, "extobj::idx"); + if ((lg == NULL) || (strcmp(lg, group) != 0) || (idxs == NULL)) continue; + if (idxs[0] == '0') *ctrl1 = a; + else if (idxs[0] == '1') *ctrl2 = a; + } +} + +/* create the graphics */ +static int cord_gen(pcb_subc_t *subc, const char *group) +{ + pcb_layer_t *lyr = &subc->data->Layer[LID_TARGET]; + pcb_layer_t *elyr = &subc->data->Layer[LID_EDIT]; + pcb_line_t *l; + pcb_pstk_t *e1, *e2; + pcb_arc_t *a1, *a2; + + cord_get_ends(subc, group, &e1, &a1, &e2, &a2); + if ((e1 == NULL) || (e2 == NULL)) { + rnd_message(RND_MSG_ERROR, "extended object cord: failed to generate cord for #%ld group %s: missing endpoint\n", subc->ID, group); + return -1; + } + + pcb_exto_regen_begin(subc); + + + if (a1 != NULL) { + l = pcb_line_new(elyr, e1->x, e1->y, a1->X, a1->Y, + 1, 0, pcb_flag_make(0)); + pcb_attribute_put(&l->Attributes, "extobj::role", "gfx"); + set_grp((pcb_any_obj_t *)l, group); + } + + if (a2 != NULL) { + l = pcb_line_new(elyr, e2->x, e2->y, a2->X, a2->Y, + 1, 0, pcb_flag_make(0)); + pcb_attribute_put(&l->Attributes, "extobj::role", "gfx"); + set_grp((pcb_any_obj_t *)l, group); + } + + if ((a1 != NULL) && (a2 != NULL)) { + double t, it, t2, t3, it2, it3, step = 1.0/25.0; + rnd_coord_t lx, ly, x, y; + + lx = e1->x; ly = e1->y; + for(t = step; t <= 1.0+step/2.0; t += step) { + if (t > 1.0) + t = 1.0; + it = 1-t; + it2 = it*it; + it3 = it2 * it; + t2 = t*t; + t3 = t2*t; + + /* B(t)=(1-t)^3 * P0 + 3*(1-t)^2 * t * P1 + 3 * (1-t)*t^2 * P2 + t^3*P3 */ + + x = rnd_round(it3*e1->x + 3*it2*t*a1->X + 3*it*t2*a2->X + t3*e2->x); + y = rnd_round(it3*e1->y + 3*it2*t*a1->Y + 3*it*t2*a2->Y + t3*e2->y); + + l = pcb_line_new(lyr, lx, ly, x, y, + RND_MM_TO_COORD(0.25), 0, pcb_flag_make(0)); + pcb_attribute_put(&l->Attributes, "extobj::role", "gfx"); + set_grp((pcb_any_obj_t *)l, group); + + lx = x; ly = y; + } + + } + else { + l = pcb_line_new(lyr, e1->x, e1->y, e2->x, e2->y, + RND_MM_TO_COORD(0.25), 0, pcb_flag_make(0)); + pcb_attribute_put(&l->Attributes, "extobj::role", "gfx"); + set_grp((pcb_any_obj_t *)l, group); + } + + return pcb_exto_regen_end(subc); +} + + +static void pcb_cord_draw_mark(pcb_draw_info_t *info, pcb_subc_t *subc) +{ + pcb_exto_draw_mark(info, subc); + if (subc->extobj_data == cord_footprint) + pcb_draw_subc_mark((const rnd_box_t *)subc, info); +} + +static void pcb_cord_float_pre(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + rnd_trace("cord: float pre %ld %ld role=%s\n", subc->ID, floater->ID, floater->extobj_role); + + if (floater->extobj_role == NULL) + return; + + cord_clear(subc, group_of(floater)); +} + +static void pcb_cord_float_geo(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + const char *grp; + + if (floater == NULL) { + /* post-floater-del update: noop */ + return; + } + + rnd_trace("cord: float geo %ld %ld role=%s\n", subc->ID, floater->ID, floater->extobj_role); + + if (floater->extobj_role == NULL) + return; + + grp = group_of(floater); + if (grp == NULL) + return; + + cord_gen(subc, grp); + + if ((floater->type == PCB_OBJ_LINE) && (pcb_attribute_get(&subc->Attributes, "extobj::fixed_origin") == NULL)) { + pcb_pstk_t *ps = (pcb_pstk_t *)floater; + pcb_subc_move_origin_to(subc, ps->x + RND_MM_TO_COORD(0.3), ps->y + RND_MM_TO_COORD(0.3), 0); + } +} + +static pcb_extobj_del_t pcb_cord_float_del(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + pcb_pstk_t *p, *next; + const char *group = group_of(floater); + int has_other_grp = 0; + + rnd_trace("cord: float del %ld %ld\n", subc->ID, floater->ID); + + if ((floater->type != PCB_OBJ_LINE) || (group == NULL)) + return PCB_EXTODEL_FLOATER; /* e.g. refdes text - none of our business */ + + for(p = padstacklist_first(&subc->data->padstack); p != NULL; p = next) { + const char *lg; + next = padstacklist_next(p); + if ((pcb_any_obj_t *)p == floater) continue; /* do not remove the input floater, the caller may need it */ + lg = group_of((pcb_any_obj_t *)p); + if ((lg == NULL) || (strcmp(lg, group) != 0)) { + has_other_grp = 1; + continue; + } + pcb_pstk_free(p); + } + + return has_other_grp ? PCB_EXTODEL_FLOATER : PCB_EXTODEL_SUBC; +} + +static void pcb_cord_chg_attr(pcb_subc_t *subc, const char *key, const char *value) +{ + rnd_trace("cord chg_attr\n"); +} + +static rnd_cardinal_t endpt_pstk_proto(pcb_data_t *data, pcb_layer_type_t lyt) +{ + pcb_pstk_proto_t proto; + pcb_pstk_shape_t shape; + pcb_pstk_tshape_t tshp; + + memset(&proto, 0, sizeof(proto)); + memset(&tshp, 0, sizeof(tshp)); + memset(&shape, 0, sizeof(shape)); + + tshp.shape = &shape; + proto.tr.alloced = proto.tr.used = 1; /* has the canonical form only */ + proto.tr.array = &tshp; + + shape.shape = PCB_PSSH_CIRC; + shape.data.circ.dia = RND_MM_TO_COORD(0.5); + shape.data.circ.x = shape.data.circ.y = 0; + + shape.layer_mask = lyt; + shape.comb = 0; + tshp.len = 1; + + proto.hdia = 0; + proto.hplated = 0; + + pcb_pstk_proto_update(&proto); + return pcb_pstk_proto_insert_dup(data, &proto, 1, 0); +} + +static pcb_pstk_t *endpt_pstk(pcb_subc_t *subc, const char *ptidx, rnd_cardinal_t pid, rnd_coord_t x, rnd_coord_t y, rnd_coord_t ox, rnd_coord_t oy, const char *term, const char *grp, int floater) +{ + pcb_pstk_t *ps; + rnd_coord_t dx = ox-x, dy = oy-y, cpx = x+dx/4, cpy = y+dy/4, cpr = RND_MM_TO_COORD(0.5); + pcb_layer_t *ely = &subc->data->Layer[LID_EDIT]; + + + ps = pcb_pstk_new(subc->data, -1, pid, x, y, 0, pcb_flag_make(0)); + set_grp((pcb_any_obj_t *)ps, grp); + pcb_attribute_put(&ps->Attributes, "extobj::role", "endpt"); + pcb_attribute_put(&ps->Attributes, "extobj::idx", ptidx); + pcb_attribute_put(&ps->Attributes, "intconn", grp); + if (term != NULL) + pcb_attribute_put(&ps->Attributes, "term", term); + + +#ifdef BEZIER + { + pcb_arc_t *a; + a = pcb_arc_new(ely, cpx, cpy, 0, 0, 0, 360, cpr, cpr*2, pcb_flag_make(0), 0); + set_grp((pcb_any_obj_t *)a, grp); + pcb_attribute_put(&a->Attributes, "extobj::role", "control"); + pcb_attribute_put(&a->Attributes, "extobj::idx", ptidx); + PCB_FLAG_SET(PCB_FLAG_FLOATER, a); + } +#endif + + if (floater) + PCB_FLAG_SET(PCB_FLAG_FLOATER, ps); + + return ps; +} + + +static void conv_pstk(pcb_subc_t *subc, pcb_pstk_t *ps, long *grp, long *term, int *has_origin) +{ + char sgrp[16], sterm[16]; + rnd_coord_t d = RND_MM_TO_COORD(0.75); + + sprintf(sgrp, "%ld", (*grp)++); + + endpt_pstk(subc, "0", COPPER_END, ps->x+d, ps->y+d, ps->x, ps->y, ps->term, sgrp, 1); + + sprintf(sterm, "cord%ld", (*term)++); + endpt_pstk(subc, "1", SILK_END, ps->x, ps->y, ps->x+d, ps->x+d, ps->term, sgrp, 0); + + if (!*has_origin) { + pcb_subc_move_origin_to(subc, ps->x + RND_MM_TO_COORD(0.3), ps->y + RND_MM_TO_COORD(0.3), 0); + *has_origin = 1; + } + + cord_gen(subc, sgrp); +} + +static pcb_subc_t *pcb_cord_conv_objs(pcb_data_t *dst, vtp0_t *objs, pcb_subc_t *copy_from) +{ + pcb_subc_t *subc; + long n, grp = 1, term = 0; /* for intconn grp needs to start from 1 */ + rnd_coord_t ox = 0, oy = 0, has_origin = 0, has_subc = 0; + pcb_dflgmap_t layers[] = { + {"edit", PCB_LYT_DOC, "extobj", 0, 0}, + {"target", PCB_LYT_SILK | PCB_LYT_TOP, NULL, 0, 0}, + {NULL, 0, NULL, 0, 0} + }; + + rnd_trace("cord: conv_objs\n"); + + /* origin override: if converting subcircuits, keep the first subcircuits origin */ + for(n = 0; n < objs->used; n++) { + pcb_subc_t *s = objs->array[n]; + if (s->type != PCB_OBJ_SUBC) continue; + has_subc = 1; + + if (pcb_subc_get_origin(s, &ox, &oy) == 0) { + has_origin = 1; + break; + } + } + + /* set target layer from the first line object's layer */ + for(n = 0; n < objs->used; n++) { + pcb_line_t *l = objs->array[n]; + if (l->type != PCB_OBJ_LINE) continue; + + layers[1].lyt = pcb_layer_flags_(l->parent.layer); + pcb_layer_purpose_(l->parent.layer, &layers[1].purpose); + if (!has_origin) { + ox = l->Point1.X + RND_MM_TO_COORD(0.3); + oy = l->Point1.Y + RND_MM_TO_COORD(0.3); + has_origin = 1; + } + break; + } + + subc = pcb_exto_create(dst, "cord", layers, ox, oy, 0, copy_from); + + /* create padstack prototypes */ + if (endpt_pstk_proto(subc->data, PCB_LYT_COPPER | PCB_LYT_TOP) != COPPER_END) + rnd_message(RND_MSG_WARNING, "extended object cord: wrong pstk proto ID for copper end\n"); + if (endpt_pstk_proto(subc->data, PCB_LYT_SILK | PCB_LYT_TOP) != SILK_END) + rnd_message(RND_MSG_WARNING, "extended object cord: wrong pstk proto ID for silk end\n"); + + /* convert lines into 2-ended cords */ + for(n = 0; n < objs->used; n++) { + char sgrp[16], sterm[16]; + pcb_line_t *l = objs->array[n]; + + if (l->type != PCB_OBJ_LINE) continue; + + sprintf(sgrp, "%ld", grp++); + + sprintf(sterm, "cord%ld", term++); + endpt_pstk(subc, "0", COPPER_END, l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y, sterm, sgrp, 1); + + sprintf(sterm, "cord%ld", term++); + endpt_pstk(subc, "1", COPPER_END, l->Point2.X, l->Point2.Y, l->Point1.X, l->Point1.Y, sterm, sgrp, 1); + + cord_gen(subc, sgrp); + } + + /* convert padstacks into single-ended cords, one end anchored at the original position */ + for(n = 0; n < objs->used; n++) { + pcb_pstk_t *ps = objs->array[n]; + if (ps->type == PCB_OBJ_PSTK) + conv_pstk(subc, ps, &grp, &term, &has_origin); + } + + /* convert subcircuits (footprints) */ + /* step 1: convert padstacks */ + for(n = 0; n < objs->used; n++) { + pcb_pstk_t *ps; + pcb_subc_t *s = objs->array[n]; + if (s->type != PCB_OBJ_SUBC) continue; + + for(ps = padstacklist_first(&s->data->padstack); ps != NULL; ps = padstacklist_next(ps)) + conv_pstk(subc, ps, &grp, &term, &has_origin); + } + + /* step 2: copy layer objects */ + for(n = 0; n < objs->used; n++) { + int lid; + pcb_subc_t *s = objs->array[n]; + if (s->type != PCB_OBJ_SUBC) continue; + + pcb_attribute_copy_all(&subc->Attributes, &s->Attributes); + + for(lid = 0; lid < s->data->LayerN; lid++) { + pcb_layer_t *sl = &s->data->Layer[lid], *dl; + + if (strcmp(sl->name, "subc-aux") == 0) continue; + + dl = pcb_subc_alloc_layer_like(subc, sl); + pcb_subc_dup_layer_objs(subc, dl, sl, 0, 0, 0); + } + } + + + if (has_subc) { + pcb_attribute_put(&subc->Attributes, "extobj::fixed_origin", "(yes)"); + + pcb_subc_unreg(subc); + pcb_subc_bbox(subc); + pcb_subc_reg(dst, subc); + + subc->extobj_data = cord_footprint; + } + else + subc->extobj_data = NULL; + + + return subc; +} + +static pcb_extobj_t pcb_cord = { + "cord", + pcb_cord_draw_mark, + pcb_cord_float_pre, + pcb_cord_float_geo, + NULL, + pcb_cord_float_del, + pcb_cord_chg_attr, + NULL, + pcb_cord_conv_objs, + NULL, +}; Index: tags/2.3.0/src_plugins/exto_std/dimension.c =================================================================== --- tags/2.3.0/src_plugins/exto_std/dimension.c (nonexistent) +++ tags/2.3.0/src_plugins/exto_std/dimension.c (revision 33253) @@ -0,0 +1,443 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * Extended object for a dimension; draws a dimension line over the size of the edit-object + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "search.h" + +#define LID_EDIT 0 +#define LID_TARGET 1 + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int gui_active; + + int style; + rnd_coord_t displace; + const char *fmt; + + unsigned int valid:1; + double x1, y1, x2, y2, len, dx, dy; +} dimension; + +static pcb_any_obj_t *dimension_edit_obj(pcb_subc_t *subc) +{ + pcb_layer_t *ly = &subc->data->Layer[LID_EDIT]; + return (pcb_any_obj_t *)linelist_first(&ly->Line); +} + +static void pcb_dimension_del_pre(pcb_subc_t *subc) +{ + rnd_trace("dim del_pre\n"); + free(subc->extobj_data); + subc->extobj_data = NULL; +} + +static int dimension_update_src(dimension *dim, pcb_any_obj_t *edit) +{ + dim->valid = 0; + + if (edit == NULL) + return 0; + + switch(edit->type) { + case PCB_OBJ_LINE: + { + pcb_line_t *line = (pcb_line_t *)edit; + dim->x1 = line->Point1.X; dim->y1 = line->Point1.Y; + dim->x2 = line->Point2.X; dim->y2 = line->Point2.Y; + dim->valid = 1; + } + break; + default: + /* can not dimension the given object type */ + break; + } + + + if (dim->valid) { + dim->dx = dim->x2 - dim->x1; + dim->dy = dim->y2 - dim->y1; + dim->len = sqrt(dim->dx*dim->dx + dim->dy*dim->dy); + if (dim->len != 0) { + dim->dx /= dim->len; + dim->dy /= dim->len; + } + } + + return !dim->valid; +} + + +static void dimension_unpack(pcb_subc_t *obj) +{ + dimension *dim; + pcb_any_obj_t *edit; + + if (obj->extobj_data == NULL) + obj->extobj_data = calloc(sizeof(dimension), 1); + dim = obj->extobj_data; + + pcb_extobj_unpack_coord(obj, &dim->displace, "extobj::displace"); + dim->fmt = pcb_attribute_get(&obj->Attributes, "extobj::format"); + if (dim->fmt == NULL) + dim->fmt = "%.03$mm"; + + edit = dimension_edit_obj(obj); + dimension_update_src(dim, edit); +} + +/* remove all existing graphics from the subc */ +static void dimension_clear(pcb_subc_t *subc) +{ + pcb_layer_t *ly = &subc->data->Layer[LID_TARGET]; + pcb_line_t *l, *next; + pcb_poly_t *p; + pcb_text_t *t; + + for(l = linelist_first(&ly->Line); l != NULL; l = next) { + next = linelist_next(l); + if (PCB_FLAG_TEST(PCB_FLAG_FLOATER, l)) continue; /* do not free the floater */ + pcb_line_free(l); + } + + for(p = polylist_first(&ly->Polygon); p != NULL; p = polylist_first(&ly->Polygon)) { + pcb_poly_free(p); + } + + for(t = textlist_first(&ly->Text); t != NULL; t = textlist_first(&ly->Text)) { + pcb_text_free(t); + } +} + +static void draw_arrow(dimension *dim, pcb_data_t *data, pcb_layer_t *ly, rnd_coord_t x1, rnd_coord_t y1, double arrx, double arry) +{ + pcb_poly_t *p = pcb_poly_new(ly, 0, pcb_flag_make(0)); + pcb_poly_point_new(p, x1, y1); + pcb_poly_point_new(p, x1 + dim->dx * arrx - dim->dy * arry, y1 + dim->dy * arrx + dim->dx * arry); + pcb_poly_point_new(p, x1 + dim->dx * arrx + dim->dy * arry, y1 + dim->dy * arrx - dim->dx * arry); + pcb_add_poly_on_layer(ly, p); + pcb_poly_init_clip(data, ly, p); +} + +/* create the graphics */ +static int dimension_gen(pcb_subc_t *subc) +{ + dimension *dim; + pcb_layer_t *ly; + pcb_line_t *flt; + double ang, deg, dispe, rotsign; + double arrx = RND_MM_TO_COORD(2), arry = RND_MM_TO_COORD(0.5); + rnd_coord_t x1, y1, x2, y2, x1e, y1e, x2e, y2e, tx, ty, x, y, ex, ey; + pcb_text_t *t; + char ttmp[128]; + pcb_any_obj_t *edit_obj; + + if (subc->extobj_data == NULL) + dimension_unpack(subc); + dim = subc->extobj_data; + edit_obj = dimension_edit_obj(subc); + if (dimension_update_src(dim, edit_obj) != 0) + return -1; + + pcb_exto_regen_begin(subc); + + ly = &subc->data->Layer[LID_TARGET]; + + /* endpoints of the displaced baseline */ + x1 = rnd_round(dim->x1 + dim->displace * -dim->dy); + y1 = rnd_round(dim->y1 + dim->displace * +dim->dx); + x2 = rnd_round(dim->x2 + dim->displace * -dim->dy); + y2 = rnd_round(dim->y2 + dim->displace * +dim->dx); + + /* endpoints of the extended-displaced baseline */ + dispe = RND_MM_TO_COORD(0.5); + if (dim->displace < 0) + dispe = -dispe; + dispe = dim->displace + dispe; + + x1e = rnd_round(dim->x1 + dispe * -dim->dy); + y1e = rnd_round(dim->y1 + dispe * +dim->dx); + x2e = rnd_round(dim->x2 + dispe * -dim->dy); + y2e = rnd_round(dim->y2 + dispe * +dim->dx); + + /* main dim line */ + flt = linelist_first(&subc->data->Layer[LID_TARGET].Line); + if (flt == NULL) { /* create the floater if it doesn't exist */ + flt = pcb_line_new(ly, + x1 + arrx * dim->dx, y1 + arrx * dim->dy, + x2 - arrx * dim->dx, y2 - arrx * dim->dy, + RND_MM_TO_COORD(0.25), 0, pcb_flag_make(PCB_FLAG_FLOATER)); + pcb_attribute_put(&flt->Attributes, "extobj::role", "dimline"); + } + else { /* modify the floater if it exists */ + if (ly->line_tree != NULL) + rnd_r_delete_entry(ly->line_tree, (rnd_box_t *)flt); + + flt->Point1.X = x1 + arrx * dim->dx; flt->Point1.Y = y1 + arrx * dim->dy; + flt->Point2.X = x2 - arrx * dim->dx; flt->Point2.Y = y2 - arrx * dim->dy; + + pcb_line_bbox(flt); + if (ly->line_tree != NULL) + rnd_r_insert_entry(ly->line_tree, (rnd_box_t *)flt); + } + + /* guide lines */ + pcb_line_new(ly, dim->x1, dim->y1, x1e, y1e, RND_MM_TO_COORD(0.25), 0, pcb_flag_make(0)); + pcb_line_new(ly, dim->x2, dim->y2, x2e, y2e, RND_MM_TO_COORD(0.25), 0, pcb_flag_make(0)); + + /* arrows */ + draw_arrow(dim, subc->data, ly, x1, y1, arrx, arry); + draw_arrow(dim, subc->data, ly, x2, y2, -arrx, arry); + + /* text */ + if (rnd_safe_snprintf(ttmp, sizeof(ttmp), RND_SAFEPRINT_COORD_ONLY | 1, dim->fmt, (rnd_coord_t)dim->len) < 0) + strcpy(ttmp, ""); + t = pcb_text_new(ly, pcb_font(PCB, 0, 0), 0, 0, 0, 100, 0, ttmp, pcb_flag_make(0)); + tx = t->BoundingBox.X2 - t->BoundingBox.X1; + ty = t->BoundingBox.Y2 - t->BoundingBox.Y1; + + ang = atan2(-dim->dy, dim->dx) + M_PI; + deg = ang * RND_RAD_TO_DEG; + if ((deg > 135) && (deg < 315)) { + ang = ang-M_PI; + deg = ang * RND_RAD_TO_DEG; + rotsign = -1; + } + else + rotsign = +1; + + x = ex = (x1+x2)/2; y = ey = (y1+y2)/2; + x += rotsign * tx/2 * dim->dx; y += rotsign * tx/2 * dim->dy; + x += rotsign * ty * -dim->dy; y += rotsign * ty * dim->dx; + if ((ang > 0.001) || (ang < -0.001)) + pcb_text_rotate(t, 0, 0, cos(ang), sin(ang), deg); + pcb_text_move(t, x, y); + + x = ex + dim->dy * PCB_SUBC_AUX_UNIT * 0.5 * rotsign; + y = ey - dim->dx * PCB_SUBC_AUX_UNIT * 0.5 * rotsign; + pcb_subc_move_origin_to(subc, x, y, 0); + + return pcb_exto_regen_end(subc); +} + + +static void pcb_dimension_draw_mark(pcb_draw_info_t *info, pcb_subc_t *subc) +{ + pcb_exto_draw_mark(info, subc); +} + +static void pcb_dimension_float_pre(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + rnd_trace("dim: float pre %ld %ld role=%s\n", subc->ID, floater->ID, floater->extobj_role); + + dimension_clear(subc); +} + + +static void pcb_dimension_dimline_geo(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + dimension *dim; + pcb_line_t *fline = (pcb_line_t *)floater, bline; + rnd_coord_t fx, fy; + double d; + char tmp[128]; + + + if (floater->type != PCB_OBJ_LINE) + return; + + if (subc->extobj_data == NULL) + dimension_unpack(subc); + dim = subc->extobj_data; + + fx = rnd_round((double)(fline->Point1.X + fline->Point2.X)/2.0); + fy = rnd_round((double)(fline->Point1.Y + fline->Point2.Y)/2.0); + + memset(&bline, 0, sizeof(bline)); + bline.Point1.X = dim->x1; bline.Point1.Y = dim->y1; + bline.Point2.X = dim->x2; bline.Point2.Y = dim->y2; + d = pcb_point_line_dist2(fx, fy, &bline); + if (d != 0) { + double side = ((dim->x2 - dim->x1)*(fy - dim->y1) - (dim->y2 - dim->y1)*(fx - dim->x1)); /* which side fx;fy is on */ + d = sqrt(d); + if (side < 0) + d = -d; + } + +rnd_trace("new disp: %mm f=%mm;%mm\n", (rnd_coord_t)d, fx, fy); + + if ((d > -RND_MM_TO_COORD(0.1)) && (d < RND_MM_TO_COORD(0.1))) + return; + +rnd_trace("let's do it!\n"); + + dimension_clear(subc); + dim->displace = d; + rnd_snprintf(tmp, sizeof(tmp), "%.08$mH", (rnd_coord_t)d); + pcb_attribute_put(&subc->Attributes, "extobj::displace", tmp); + dimension_gen(subc); +} + +static void pcb_dimension_float_geo(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + rnd_trace("dim: float geo %ld %ld role=%s\n", subc->ID, floater->ID, floater->extobj_role); + + if (floater->extobj_role == NULL) + return; + + if (strcmp(floater->extobj_role, "edit") == 0) + dimension_gen(subc); + else if (strcmp(floater->extobj_role, "dimline") == 0) + pcb_dimension_dimline_geo(subc, floater); + +} + +static pcb_extobj_new_t pcb_dimension_float_new(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + rnd_trace("dim: float new %ld %ld\n", subc->ID, floater->ID); + return PCB_EXTONEW_SPAWN; +} + +static pcb_extobj_del_t pcb_dimension_float_del(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + rnd_trace("dim: float del %ld %ld\n", subc->ID, floater->ID); + return PCB_EXTODEL_SUBC; +} + +static void pcb_dimension_chg_attr(pcb_subc_t *subc, const char *key, const char *value) +{ + rnd_trace("dim chg_attr\n"); + if (strncmp(key, "extobj::", 8) == 0) { + dimension_clear(subc); + dimension_unpack(subc); + dimension_gen(subc); + } +} + +static pcb_subc_t *pcb_dimension_conv_objs(pcb_data_t *dst, vtp0_t *objs, pcb_subc_t *copy_from) +{ + pcb_subc_t *subc; + pcb_line_t *l; + pcb_layer_t *ly, *targetly = NULL; + pcb_dflgmap_t layers[] = { + {"edit", PCB_LYT_DOC, "extobj", 0, 0}, + {"target", PCB_LYT_DOC, "fab", 0, 0}, + {NULL, 0, NULL, 0, 0} + }; + + rnd_trace("dim: conv_objs\n"); + + if (objs->used != 1) + return NULL; /* there must be a single line */ + + /* use the layer of the first object */ + l = objs->array[0]; + if (l->type != PCB_OBJ_LINE) + return NULL; + + layers[0].lyt = pcb_layer_flags_(l->parent.layer); + pcb_layer_purpose_(l->parent.layer, &layers[0].purpose); + if ((copy_from != NULL) && (copy_from->data->LayerN > LID_TARGET) && (copy_from->data->Layer[LID_TARGET].meta.bound.real != NULL)) { + targetly = copy_from->data->Layer[LID_TARGET].meta.bound.real; + } + else if (dst->parent_type == PCB_PARENT_BOARD) { + pcb_board_t *pcb = dst->parent.board; + targetly = PCB_CURRLAYER(pcb); + } + + if (targetly != NULL) { + layers[1].lyt = pcb_layer_flags_(targetly); + pcb_layer_purpose_(targetly, &layers[1].purpose); + } + + subc = pcb_exto_create(dst, "dimension", layers, l->Point1.X, l->Point1.Y, 0, copy_from); + if (copy_from == NULL) + pcb_attribute_put(&subc->Attributes, "extobj::displace", "4mm"); + + /* create edit-objects */ + ly = &subc->data->Layer[LID_EDIT]; + l = pcb_line_dup(ly, objs->array[0]); + PCB_FLAG_SET(PCB_FLAG_FLOATER, l); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, l); + pcb_attribute_put(&l->Attributes, "extobj::role", "edit"); + + dimension_unpack(subc); + dimension_gen(subc); + return subc; +} + +static void pcb_dimension_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + pcb_subc_t *subc = caller_data; + dimension *dim = subc->extobj_data; + + RND_DAD_FREE(dim->dlg); + dim->gui_active = 0; +} + +static void pcb_dimension_gui_propedit(pcb_subc_t *subc) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + dimension *dim; + + rnd_trace("dim: gui propedit\n"); + + if (subc->extobj_data == NULL) + dimension_unpack(subc); + dim = subc->extobj_data; + + rnd_trace("dim: active=%d\n", dim->gui_active); + if (dim->gui_active) + return; /* do not open another */ + + RND_DAD_BEGIN_VBOX(dim->dlg); + RND_DAD_COMPFLAG(dim->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABLE(dim->dlg, 2); + pcb_exto_dlg_coord(dim->dlg, subc, "displacement", "extobj::displace", "distance between base line and dimension line"); + pcb_exto_dlg_str(dim->dlg, subc, "format", "extobj::format", "printf coord format string of the dimension value"); + RND_DAD_END(dim->dlg); + RND_DAD_BUTTON_CLOSES(dim->dlg, clbtn); + RND_DAD_END(dim->dlg); + + /* set up the context */ + dim->gui_active = 1; + + RND_DAD_NEW("dimension", dim->dlg, "Dimension line", subc, rnd_false, pcb_dimension_close_cb); +} + +static pcb_extobj_t pcb_dimension = { + "dimension", + pcb_dimension_draw_mark, + pcb_dimension_float_pre, + pcb_dimension_float_geo, + pcb_dimension_float_new, + pcb_dimension_float_del, + pcb_dimension_chg_attr, + pcb_dimension_del_pre, + pcb_dimension_conv_objs, + pcb_dimension_gui_propedit +}; Index: tags/2.3.0/src_plugins/exto_std/exto_std.c =================================================================== --- tags/2.3.0/src_plugins/exto_std/exto_std.c (nonexistent) +++ tags/2.3.0/src_plugins/exto_std/exto_std.c (revision 33253) @@ -0,0 +1,72 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * Basic, standard extended objects + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include "board.h" +#include "data.h" +#include +#include +#include "obj_subc.h" +#include +#include "extobj.h" +#include "extobj_helper.h" +#include "conf_core.h" +#include +#include + +#include "line_of_vias.c" +#include "dimension.c" +#include "cord.c" +#include "bus.c" +/*#include "wholepoly.c"*/ + +int pplg_check_ver_exto_std(int ver_needed) { return 0; } + +void pplg_uninit_exto_std(void) +{ + pcb_extobj_unreg(&pcb_line_of_vias); + pcb_extobj_unreg(&pcb_dimension); + pcb_extobj_unreg(&pcb_cord); + pcb_extobj_unreg(&pcb_bus); +/* pcb_extobj_unreg(&pcb_wholepoly);*/ +} + +int pplg_init_exto_std(void) +{ + RND_API_CHK_VER; + + pcb_extobj_reg(&pcb_line_of_vias); + pcb_extobj_reg(&pcb_dimension); + pcb_extobj_reg(&pcb_cord); + pcb_extobj_reg(&pcb_bus); +/* pcb_extobj_reg(&pcb_wholepoly);*/ + return 0; +} Index: tags/2.3.0/src_plugins/exto_std/exto_std.pup =================================================================== --- tags/2.3.0/src_plugins/exto_std/exto_std.pup (nonexistent) +++ tags/2.3.0/src_plugins/exto_std/exto_std.pup (revision 33253) @@ -0,0 +1,8 @@ +$class feature +$short standard extended objects +$long Extended objects for: line-of-vias, dimension +$state WIP +$package core +dep lib_compat_help +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/exto_std/line_of_vias.c =================================================================== --- tags/2.3.0/src_plugins/exto_std/line_of_vias.c (nonexistent) +++ tags/2.3.0/src_plugins/exto_std/line_of_vias.c (revision 33253) @@ -0,0 +1,343 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * Extended object for a line-of-vias; edit: line; places a row of vias over the line + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#define LID_EDIT 0 + +#include "../src_plugins/lib_compat_help/pstk_compat.h" + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int gui_active; + rnd_coord_t pitch; + rnd_coord_t clearance; +} line_of_vias; + +static void pcb_line_of_vias_del_pre(pcb_subc_t *subc) +{ + line_of_vias *lov = subc->extobj_data; + rnd_trace("LoV del_pre\n"); + + if ((lov != NULL) && (lov->gui_active)) + RND_DAD_FREE(lov->dlg); + + free(lov); + subc->extobj_data = NULL; +} + +static void line_of_vias_unpack(pcb_subc_t *obj) +{ + line_of_vias *lov; + + if (obj->extobj_data == NULL) + obj->extobj_data = calloc(sizeof(line_of_vias), 1); + lov = obj->extobj_data; + + pcb_extobj_unpack_coord(obj, &lov->pitch, "extobj::pitch"); + pcb_extobj_unpack_coord(obj, &lov->clearance, "extobj::clearance"); +} + +/* remove all existing padstacks from the subc */ +static void line_of_vias_clear(pcb_subc_t *subc) +{ + pcb_pstk_t *ps; + for(ps = padstacklist_first(&subc->data->padstack); ps != NULL; ps = padstacklist_first(&subc->data->padstack)) { + pcb_poly_restore_to_poly(ps->parent.data, PCB_OBJ_PSTK, NULL, ps); + pcb_pstk_free(ps); + } +} + +#define line_geo_def \ + double len, dx, dy \ + +#define line_geo_calc(line) \ + do { \ + len = rnd_distance(line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); \ + dx = (double)(line->Point2.X - line->Point1.X) / len; \ + dy = (double)(line->Point2.Y - line->Point1.Y) / len; \ + } while(0) + + +/* create all new padstacks */ +static void line_of_vias_gen_line(pcb_board_t *pcb, pcb_subc_t *subc, pcb_line_t *line) +{ + line_geo_def; + double offs, x, y, pitch, too_close, qbox_bloat; + line_of_vias *lov = subc->extobj_data; + + line_geo_calc(line); + x = line->Point1.X; + y = line->Point1.Y; + pitch = lov->pitch; + too_close = pitch/2.0; + qbox_bloat = pitch/4.0; + for(offs = 0; offs <= len; offs += pitch) { + rnd_rtree_it_t it; + rnd_rtree_box_t qbox; + pcb_pstk_t *cl; + int skip = 0; + rnd_coord_t rx = rnd_round(x), ry = rnd_round(y); + + /* skip if there's a via too close */ + qbox.x1 = rnd_round(rx - qbox_bloat); qbox.y1 = rnd_round(ry - qbox_bloat); + qbox.x2 = rnd_round(rx + qbox_bloat); qbox.y2 = rnd_round(ry + qbox_bloat); + + if ((pcb != NULL) && (pcb->Data->padstack_tree != NULL)) { + for(cl = rnd_rtree_first(&it, pcb->Data->padstack_tree, &qbox); cl != NULL; cl = rnd_rtree_next(&it)) { + if (rnd_distance(rx, ry, cl->x, cl->y) < too_close) { + skip = 1; + break; + } + } + } + + if (!skip) + pcb_pstk_new(subc->data, -1, 0, rx, ry, lov->clearance, pcb_flag_make(PCB_FLAG_CLEARLINE)); + + x += dx * pitch; + y += dy * pitch; + } +} + +static int line_of_vias_gen(pcb_subc_t *subc, pcb_any_obj_t *edit_obj) +{ + pcb_line_t *line; + pcb_board_t *pcb = pcb_data_get_top(subc->data); + pcb_layer_t *ly = &subc->data->Layer[LID_EDIT]; + line_of_vias *lov; + + if (subc->extobj_data == NULL) + line_of_vias_unpack(subc); + + lov = subc->extobj_data; + if (lov->pitch < RND_MM_TO_COORD(0.001)) { + rnd_message(RND_MSG_ERROR, "line_of_vias_gen(): can not generate line-of-vias, pitch value is too small\n"); + return -1; + } + + + pcb_exto_regen_begin(subc); + for(line = linelist_first(&ly->Line); line != NULL; line = linelist_next(line)) + line_of_vias_gen_line(pcb, subc, line); + + + { + line_geo_def; + line = linelist_first(&ly->Line); + line_geo_calc(line); + pcb_subc_move_origin_to(subc, line->Point1.X - dy * PCB_SUBC_AUX_UNIT, line->Point1.Y + dx * PCB_SUBC_AUX_UNIT, 0); + } + + return pcb_exto_regen_end(subc); +} + +static void draw_mark_line(pcb_draw_info_t *info, pcb_subc_t *subc, pcb_line_t *line) +{ + int selected; + double disp = RND_MM_TO_COORD(0.05); + double arrow = RND_MM_TO_COORD(0.2); + double ax, ay, ax1, ay1, ax2, ay2; + line_geo_def; + rnd_coord_t x1 = line->Point1.X, y1 = line->Point1.Y, x2 = line->Point2.X, y2 = line->Point2.Y; +/* line_of_vias *lov = subc->extobj_data;*/ + + line_geo_calc(line); + + selected = PCB_FLAG_TEST(PCB_FLAG_SELECTED, line); + rnd_render->set_color(pcb_draw_out.fgGC, selected ? &conf_core.appearance.color.selected : &conf_core.appearance.color.extobj); + rnd_hid_set_line_width(pcb_draw_out.fgGC, -1); + rnd_render->draw_line(pcb_draw_out.fgGC, x1 - dy * +disp, y1 + dx * +disp, x2 - dy * +disp, y2 + dx * +disp); + rnd_render->draw_line(pcb_draw_out.fgGC, x1 - dy * -disp, y1 + dx * -disp, x2 - dy * -disp, y2 + dx * -disp); + + rnd_hid_set_line_width(pcb_draw_out.fgGC, -2); + ax = x1 + dx * arrow; + ay = y1 + dy * arrow; + ax1 = x1 - dy * +arrow; + ay1 = y1 + dx * +arrow; + ax2 = x1 - dy * -arrow; + ay2 = y1 + dx * -arrow; + rnd_render->draw_line(pcb_draw_out.fgGC, ax1, ay1, ax2, ay2); + rnd_render->draw_line(pcb_draw_out.fgGC, ax1, ay1, ax, ay); + rnd_render->draw_line(pcb_draw_out.fgGC, ax2, ay2, ax, ay); +} + +static void pcb_line_of_vias_draw_mark(pcb_draw_info_t *info, pcb_subc_t *subc) +{ + pcb_line_t *line; + pcb_layer_t *ly = &subc->data->Layer[LID_EDIT]; + + if (subc->extobj_data == NULL) + line_of_vias_unpack(subc); + + for(line = linelist_first(&ly->Line); line != NULL; line = linelist_next(line)) + draw_mark_line(info, subc, line); + + pcb_exto_draw_mark(info, subc); +} + + +static void pcb_line_of_vias_float_pre(pcb_subc_t *subc, pcb_any_obj_t *edit_obj) +{ + rnd_trace("LoV: edit pre %ld %ld\n", subc->ID, edit_obj->ID); + line_of_vias_clear(subc); +} + +static void pcb_line_of_vias_float_geo(pcb_subc_t *subc, pcb_any_obj_t *edit_obj) +{ + rnd_trace("LoV: edit geo %ld %ld\n", subc->ID, edit_obj == NULL ? -1 : edit_obj->ID); + line_of_vias_gen(subc, edit_obj); +} + +static pcb_extobj_new_t pcb_line_of_vias_float_new(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + rnd_trace("LoV: float new %ld %ld\n", subc->ID, floater->ID); + return PCB_EXTONEW_FLOATER; +} + +static pcb_extobj_del_t pcb_line_of_vias_float_del(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + pcb_layer_t *ly = &subc->data->Layer[LID_EDIT]; + long len = linelist_length(&ly->Line); + + rnd_trace("LoV: float del %ld %ld edit-objs=%ld\n", subc->ID, floater->ID, len); + + return len == 1 ? PCB_EXTODEL_SUBC : PCB_EXTODEL_FLOATER; /* removing the last floater should remove the subc */ +} + + +static void pcb_line_of_vias_chg_attr(pcb_subc_t *subc, const char *key, const char *value) +{ + rnd_trace("LoV chg_attr\n"); + if (strncmp(key, "extobj::", 8) == 0) { + line_of_vias_clear(subc); + line_of_vias_unpack(subc); + line_of_vias_gen(subc, NULL); + } +} + + +static pcb_subc_t *pcb_line_of_vias_conv_objs(pcb_data_t *dst, vtp0_t *objs, pcb_subc_t *copy_from) +{ + long n; + pcb_subc_t *subc; + pcb_line_t *l; + pcb_layer_t *ly; + pcb_dflgmap_t layers[] = { + {"edit", PCB_LYT_DOC, "extobj", 0, 0}, + {NULL, 0, NULL, 0, 0} + }; + + rnd_trace("LoV: conv_objs\n"); + + /* refuse anything that's not a line */ + for(n = 0; n < objs->used; n++) { + l = objs->array[n]; + if (l->type != PCB_OBJ_LINE) + return NULL; + } + + /* use the layer of the first object */ + l = objs->array[0]; + layers[0].lyt = pcb_layer_flags_(l->parent.layer); + pcb_layer_purpose_(l->parent.layer, &layers[0].purpose); + + subc = pcb_exto_create(dst, "line-of-vias", layers, l->Point1.X, l->Point1.Y, 0, copy_from); + if (copy_from == NULL) + pcb_attribute_put(&subc->Attributes, "extobj::pitch", "4mm"); + + /* create edit-objects */ + ly = &subc->data->Layer[LID_EDIT]; + for(n = 0; n < objs->used; n++) { + l = pcb_line_dup(ly, objs->array[n]); + PCB_FLAG_SET(PCB_FLAG_FLOATER, l); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, l); + pcb_attribute_put(&l->Attributes, "extobj::role", "edit"); + } + + /* create the padstack prototype */ +TODO("pstk #21: do not work in comp mode, use a pstk proto + remove the plugin dependency when done") + pcb_pstk_new_compat_via(subc->data, -1, l->Point1.X, l->Point1.Y, + conf_core.design.via_drilling_hole, conf_core.design.via_thickness, conf_core.design.clearance, + 0, PCB_PSTK_COMPAT_ROUND, rnd_true); + + line_of_vias_unpack(subc); + line_of_vias_gen(subc, NULL); + return subc; +} + + +static void pcb_line_of_vias_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + pcb_subc_t *subc = caller_data; + line_of_vias *lov = subc->extobj_data; + + RND_DAD_FREE(lov->dlg); + lov->gui_active = 0; +} + +static void pcb_line_of_vias_gui_propedit(pcb_subc_t *subc) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + line_of_vias *lov; + + rnd_trace("LoV: gui propedit\n"); + + if (subc->extobj_data == NULL) + line_of_vias_unpack(subc); + lov = subc->extobj_data; + + rnd_trace("LoV: active=%d\n", lov->gui_active); + if (lov->gui_active) + return; /* do not open another */ + + RND_DAD_BEGIN_VBOX(lov->dlg); + RND_DAD_COMPFLAG(lov->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABLE(lov->dlg, 2); + pcb_exto_dlg_coord(lov->dlg, subc, "pitch", "extobj::pitch", "target distance between center of vias"); + pcb_exto_dlg_coord(lov->dlg, subc, "clearance", "extobj::clearance", "global clarance value on vias"); + RND_DAD_END(lov->dlg); + RND_DAD_BUTTON_CLOSES(lov->dlg, clbtn); + RND_DAD_END(lov->dlg); + + /* set up the context */ + lov->gui_active = 1; + + RND_DAD_NEW("line_of_vias", lov->dlg, "Line of vias", subc, rnd_false, pcb_line_of_vias_close_cb); +} + +static pcb_extobj_t pcb_line_of_vias = { + "line-of-vias", + pcb_line_of_vias_draw_mark, + pcb_line_of_vias_float_pre, + pcb_line_of_vias_float_geo, + pcb_line_of_vias_float_new, + pcb_line_of_vias_float_del, + pcb_line_of_vias_chg_attr, + pcb_line_of_vias_del_pre, + pcb_line_of_vias_conv_objs, + pcb_line_of_vias_gui_propedit +}; Index: tags/2.3.0/src_plugins/exto_std/wholepoly.c =================================================================== --- tags/2.3.0/src_plugins/exto_std/wholepoly.c (nonexistent) +++ tags/2.3.0/src_plugins/exto_std/wholepoly.c (revision 33253) @@ -0,0 +1,292 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * Extended object for a wholepoly; edit: first polygon; explicit polygon object for each island + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#define LID_WHP 0 + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int gui_active; +} wholepoly; + +static void pcb_wholepoly_del_pre(pcb_subc_t *subc) +{ + wholepoly *whp = subc->extobj_data; + rnd_trace("WhP del_pre\n"); + + if ((whp != NULL) && (whp->gui_active)) + RND_DAD_FREE(whp->dlg); + + free(whp); + subc->extobj_data = NULL; +} + +static void wholepoly_unpack(pcb_subc_t *obj) +{ +#if 0 +/* no settings yet */ + wholepoly *whp; + + if (obj->extobj_data == NULL) + obj->extobj_data = calloc(sizeof(wholepoly), 1); + whp = obj->extobj_data; +#endif +} + +/* remove all existing padstacks from the subc */ +static void wholepoly_clear(pcb_subc_t *subc) +{ + pcb_poly_t *p, *back = NULL; + pcb_layer_t *ly = &subc->data->Layer[LID_WHP]; + + for(p = polylist_first(&ly->Polygon); p != NULL; p = polylist_next(p)) { + if (PCB_FLAG_TEST(PCB_FLAG_FLOATER, p)) { + /* do not free the floater, but remember as the last kept floater */ + back = p; + } + else { + pcb_poly_free(p); + p = back; + if (p == NULL) + p = polylist_first(&ly->Polygon); + } + } +} + +static void wholepoly_gen_poly(pcb_board_t *pcb, pcb_subc_t *subc, pcb_poly_t *poly) +{ + pcb_poly_it_t it; + rnd_polyarea_t *pa; + double best = 0; + rnd_pline_t *best_pl; + + /* figure the biggest area island - that one shouldn't be traced */ + for(pa = pcb_poly_island_first(poly, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_pline_t *pl = pcb_poly_contour(&it); + if (pl != NULL) { + if (pl->area > best) { + best = pl->area; + best_pl = pl; + } + } + } + + /* trace each missing island with a new poly */ + for(pa = pcb_poly_island_first(poly, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + int go; + rnd_coord_t x, y; + rnd_pline_t *pl = pcb_poly_contour(&it); + pcb_poly_t *np; + + if ((pl == NULL) || (pl == best_pl)) + continue; + + np = pcb_poly_new(poly->parent.layer, poly->Clearance, poly->Flags); + PCB_FLAG_CLEAR(PCB_FLAG_FLOATER, np); + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) + pcb_poly_point_new(np, x, y); + pcb_add_poly_on_layer(poly->parent.layer, np); + } +} + +static int wholepoly_gen(pcb_subc_t *subc, pcb_any_obj_t *edit_obj) +{ + pcb_poly_t *poly; + pcb_board_t *pcb = pcb_data_get_top(subc->data); + pcb_layer_t *ly = &subc->data->Layer[LID_WHP]; + wholepoly *whp; + + if (subc->extobj_data == NULL) + wholepoly_unpack(subc); + + whp = subc->extobj_data; + + pcb_exto_regen_begin(subc); + for(poly = polylist_first(&ly->Polygon); poly != NULL; poly = polylist_next(poly)) + wholepoly_gen_poly(pcb, subc, poly); + + return pcb_exto_regen_end(subc); +} + +static void pcb_wholepoly_draw_mark(pcb_draw_info_t *info, pcb_subc_t *subc) +{ + pcb_poly_t *poly; + pcb_layer_t *ly = &subc->data->Layer[LID_WHP]; + + if (subc->extobj_data == NULL) + wholepoly_unpack(subc); + + printf("mark!!!\n"); + + pcb_exto_draw_mark(info, subc); +} + + +static void pcb_wholepoly_float_pre(pcb_subc_t *subc, pcb_any_obj_t *edit_obj) +{ + rnd_trace("WhP: edit pre %ld %ld\n", subc->ID, edit_obj->ID); + wholepoly_clear(subc); +} + +static void pcb_wholepoly_float_geo(pcb_subc_t *subc, pcb_any_obj_t *edit_obj) +{ + rnd_trace("WhP: edit geo %ld %ld\n", subc->ID, edit_obj == NULL ? -1 : edit_obj->ID); + wholepoly_gen(subc, edit_obj); +} + +static pcb_extobj_new_t pcb_wholepoly_float_new(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + rnd_trace("WhP: float new %ld %ld\n", subc->ID, floater->ID); + return PCB_EXTONEW_FLOATER; +} + +static pcb_extobj_del_t pcb_wholepoly_float_del(pcb_subc_t *subc, pcb_any_obj_t *floater) +{ + pcb_layer_t *ly = &subc->data->Layer[LID_WHP]; + long len = polylist_length(&ly->Polygon); + + rnd_trace("WhP: float del %ld %ld edit-objs=%ld\n", subc->ID, floater->ID, len); + + return len == 1 ? PCB_EXTODEL_SUBC : PCB_EXTODEL_FLOATER; /* removing the last floater should remove the subc */ +} + + +static void pcb_wholepoly_chg_attr(pcb_subc_t *subc, const char *key, const char *value) +{ + rnd_trace("WhP chg_attr\n"); + if (strncmp(key, "extobj::", 8) == 0) { + wholepoly_clear(subc); + wholepoly_unpack(subc); + wholepoly_gen(subc, NULL); + } +} + + +static pcb_subc_t *pcb_wholepoly_conv_objs(pcb_data_t *dst, vtp0_t *objs, pcb_subc_t *copy_from) +{ + long n; + rnd_coord_t cx, cy; + pcb_subc_t *subc; + pcb_poly_t *p; + pcb_layer_t *ly; + pcb_dflgmap_t layers[] = { + {"edit", PCB_LYT_DOC, "extobj", 0, 0}, + {NULL, 0, NULL, 0, 0} + }; + + rnd_trace("WhP: conv_objs\n"); + + /* refuse anything that's not a polygon */ + for(n = 0; n < objs->used; n++) { + p = objs->array[n]; + if (p->type != PCB_OBJ_POLY) + return NULL; + } + + /* use the layer of the first object */ + p = objs->array[0]; + layers[0].lyt = pcb_layer_flags_(p->parent.layer); + pcb_layer_purpose_(p->parent.layer, &layers[0].purpose); + + cx = cy = 0; + for(n = 0; n < p->PointN; n++) { + cx += p->Points[n].X; + cy += p->Points[n].Y; + } + cx /= (double)p->PointN; + cy /= (double)p->PointN; +rnd_printf("Center: %mm;%mm\n", cx, cy); + subc = pcb_exto_create(dst, "wholepoly", layers, cx, cy, 0, copy_from); + +#if 0 + if (copy_from == NULL) + pcb_attribute_put(&subc->Attributes, "extobj::pitch", "4mm"); +#endif + + /* create edit-objects */ + ly = &subc->data->Layer[LID_WHP]; + for(n = 0; n < objs->used; n++) { + p = pcb_poly_dup(ly, objs->array[n]); + PCB_FLAG_SET(PCB_FLAG_FLOATER, p); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, p); + pcb_attribute_put(&p->Attributes, "extobj::role", "edit"); + } + + wholepoly_unpack(subc); + wholepoly_gen(subc, NULL); + return subc; +} + + +static void pcb_wholepoly_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + pcb_subc_t *subc = caller_data; + wholepoly *whp = subc->extobj_data; + + RND_DAD_FREE(whp->dlg); + whp->gui_active = 0; +} + +static void pcb_wholepoly_gui_propedit(pcb_subc_t *subc) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + wholepoly *whp; + + rnd_trace("WhP: gui propedit\n"); + + if (subc->extobj_data == NULL) + wholepoly_unpack(subc); + whp = subc->extobj_data; + + rnd_trace("WhP: active=%d\n", whp->gui_active); + if (whp->gui_active) + return; /* do not open another */ + + RND_DAD_BEGIN_VBOX(whp->dlg); + RND_DAD_COMPFLAG(whp->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(whp->dlg, "The whole poly extended object\ndoes not have settings"); + RND_DAD_BUTTON_CLOSES(whp->dlg, clbtn); + RND_DAD_END(whp->dlg); + + /* set up the context */ + whp->gui_active = 1; + + RND_DAD_NEW("wholepoly", whp->dlg, "Whole polygons", subc, rnd_false, pcb_wholepoly_close_cb); +} + +static pcb_extobj_t pcb_wholepoly = { + "wholepoly", + pcb_wholepoly_draw_mark, + pcb_wholepoly_float_pre, + pcb_wholepoly_float_geo, + pcb_wholepoly_float_new, + pcb_wholepoly_float_del, + pcb_wholepoly_chg_attr, + pcb_wholepoly_del_pre, + pcb_wholepoly_conv_objs, + pcb_wholepoly_gui_propedit +}; Index: tags/2.3.0/src_plugins/fontmode/Makefile =================================================================== --- tags/2.3.0/src_plugins/fontmode/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/fontmode/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_fontmode + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/fontmode/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/fontmode/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/fontmode/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {fontmode} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/fontmode/fontmode.o @] + +switch /local/pcb/fontmode/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/fontmode/fontmode.c =================================================================== --- tags/2.3.0/src_plugins/fontmode/fontmode.c (nonexistent) +++ tags/2.3.0/src_plugins/fontmode/fontmode.c (revision 33253) @@ -0,0 +1,366 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2006 DJ Delorie + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA + * dj@delorie.com + * + */ + +#include "config.h" +#include "conf_core.h" + +#include "board.h" + +#include +#include +#include +#include + +#include "data.h" +#include "draw.h" +#include "flag.h" +#include "layer.h" +#include "move.h" +#include "remove.h" +#include +#include "flag_str.h" +#include "undo.h" +#include +#include +#include +#include +#include "event.h" +#include "polygon.h" +#include "obj_poly_draw.h" + +/* FIXME - we currently hardcode the grid and PCB size. What we + should do in the future is scan the font for its extents, and size + the grid appropriately. Also, when we convert back to a font, we + should search the grid for the gridlines and use them to figure out + where the symbols are. */ + +#define CELL_SIZE ((rnd_coord_t)(RND_MIL_TO_COORD (100))) + +#define XYtoSym(x,y) (((x) / CELL_SIZE - 1) + (16 * ((y) / CELL_SIZE - 1))) + +static const char pcb_acts_fontedit[] = "FontEdit()"; +static const char pcb_acth_fontedit[] = "Convert the current font to a PCB for editing."; +static pcb_layer_t *make_layer(rnd_layergrp_id_t grp, const char *lname) +{ + rnd_layer_id_t lid; + + assert(grp >= 0); + lid = pcb_layer_create(PCB, grp, lname, 0); + assert(lid >= 0); + PCB->Data->Layer[lid].meta.real.vis = 1; + PCB->Data->Layer[lid].meta.real.color = *pcb_layer_default_color(lid, 0); + return &PCB->Data->Layer[lid]; +} + +static void add_poly(pcb_layer_t *layer, pcb_poly_t *poly, rnd_coord_t ox, rnd_coord_t oy) +{ + pcb_poly_t *np; + + /* alloc */ + np = pcb_poly_new(layer, 0, pcb_no_flags()); + pcb_poly_copy(np, poly, ox, oy); + + /* add */ + pcb_add_poly_on_layer(layer, np); + pcb_poly_init_clip(PCB->Data, layer, np); + pcb_poly_invalidate_draw(layer, np); +} + +static fgw_error_t pcb_act_FontEdit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_font_t *font; + pcb_symbol_t *symbol; + pcb_layer_t *lfont, *lorig, *lwidth, *lgrid, *lsilk; + rnd_layergrp_id_t grp[4]; + pcb_poly_t *poly; + pcb_arc_t *arc, *newarc; + int s, l; + + font = pcb_font_unlink(PCB, conf_core.design.text_font_id); + if (font == NULL) { + rnd_message(RND_MSG_ERROR, "Can't fetch font id %d\n", conf_core.design.text_font_id); + return 1; + } + + if (rnd_actionva(RND_ACT_HIDLIB, "New", "Font", 0)) + return 1; + + rnd_conf_set(RND_CFR_DESIGN, "editor/grid_unit", -1, "mil", RND_POL_OVERWRITE); + rnd_conf_set_design("design/min_wid", "%s", "1"); + rnd_conf_set_design("design/min_slk", "%s", "1"); + rnd_conf_set_design("design/text_font_id", "%s", "0"); + + + PCB->hidlib.size_x = CELL_SIZE * 18; + PCB->hidlib.size_y = CELL_SIZE * ((PCB_MAX_FONTPOSITION + 15) / 16 + 2); + PCB->hidlib.grid = RND_MIL_TO_COORD(5); + + /* create the layer stack and logical layers */ + pcb_layergrp_inhibit_inc(); + pcb_layers_reset(PCB); + pcb_layer_group_setup_default(PCB); + pcb_get_grp_new_intern(PCB, 1); + pcb_get_grp_new_intern(PCB, 2); + + assert(pcb_layergrp_list(PCB, PCB_LYT_COPPER, grp, 4) == 4); + lfont = make_layer(grp[0], "Font"); + lorig = make_layer(grp[1], "OrigFont"); + lwidth = make_layer(grp[2], "Width"); + lgrid = make_layer(grp[3], "Grid"); + + assert(pcb_layergrp_list(PCB, PCB_LYT_SILK, grp, 2) == 2); + make_layer(grp[0], "Silk"); + lsilk = make_layer(grp[1], "Silk"); + + pcb_layergrp_inhibit_dec(); + + /* Inform the rest about the board change (layer stack, size) */ + rnd_event(&PCB->hidlib, RND_EVENT_BOARD_CHANGED, NULL); + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + + for (s = 0; s <= PCB_MAX_FONTPOSITION; s++) { + char txt[32]; + rnd_coord_t ox = (s % 16 + 1) * CELL_SIZE; + rnd_coord_t oy = (s / 16 + 1) * CELL_SIZE; + rnd_coord_t w, miny, maxy, maxx = 0; + + symbol = &font->Symbol[s]; + + miny = RND_MIL_TO_COORD(5); + maxy = font->MaxHeight; + + if ((s > 32) && (s < 127)) { + sprintf(txt, "%c", s); + pcb_text_new(lsilk, pcb_font(PCB, 0, 0), ox+CELL_SIZE-CELL_SIZE/3, oy+CELL_SIZE-CELL_SIZE/3, 0, 50, 0, txt, pcb_no_flags()); + } + sprintf(txt, "%d", s); + pcb_text_new(lsilk, pcb_font(PCB, 0, 0), ox+CELL_SIZE/20, oy+CELL_SIZE-CELL_SIZE/3, 0, 50, 0, txt, pcb_no_flags()); + + for (l = 0; l < symbol->LineN; l++) { + pcb_line_new_merge(lfont, + symbol->Line[l].Point1.X + ox, + symbol->Line[l].Point1.Y + oy, + symbol->Line[l].Point2.X + ox, + symbol->Line[l].Point2.Y + oy, symbol->Line[l].Thickness, symbol->Line[l].Thickness, pcb_no_flags()); + pcb_line_new_merge(lorig, symbol->Line[l].Point1.X + ox, + symbol->Line[l].Point1.Y + oy, + symbol->Line[l].Point2.X + ox, + symbol->Line[l].Point2.Y + oy, symbol->Line[l].Thickness, symbol->Line[l].Thickness, pcb_no_flags()); + if (maxx < symbol->Line[l].Point1.X) + maxx = symbol->Line[l].Point1.X; + if (maxx < symbol->Line[l].Point2.X) + maxx = symbol->Line[l].Point2.X; + } + + + for(arc = arclist_first(&symbol->arcs); arc != NULL; arc = arclist_next(arc)) { + pcb_arc_new(lfont, arc->X + ox, arc->Y + oy, arc->Width, arc->Height, arc->StartAngle, arc->Delta, arc->Thickness, 0, pcb_no_flags(), rnd_true); + newarc = pcb_arc_new(lorig, arc->X + ox, arc->Y + oy, arc->Width, arc->Height, arc->StartAngle, arc->Delta, arc->Thickness, 0, pcb_no_flags(), rnd_true); + if (newarc != NULL) { + if (maxx < newarc->BoundingBox.X2 - ox) + maxx = newarc->BoundingBox.X2 - ox; + if (maxy < newarc->BoundingBox.Y2 - oy) + maxy = newarc->BoundingBox.Y2 - oy; + } + } + + for(poly = polylist_first(&symbol->polys); poly != NULL; poly = polylist_next(poly)) { + int n; + rnd_point_t *pnt; + + add_poly(lfont, poly, ox, oy); + add_poly(lorig, poly, ox, oy); + + for(n = 0, pnt = poly->Points; n < poly->PointN; n++,pnt++) { + if (maxx < pnt->X) + maxx = pnt->X; + if (maxy < pnt->Y) + maxy = pnt->Y; + } + } + + w = maxx + symbol->Delta + ox; + pcb_line_new_merge(lwidth, w, miny + oy, w, maxy + oy, RND_MIL_TO_COORD(1), RND_MIL_TO_COORD(1), pcb_no_flags()); + } + + for (l = 0; l < 16; l++) { + int x = (l + 1) * CELL_SIZE; + pcb_line_new_merge(lgrid, x, 0, x, PCB->hidlib.size_y, RND_MIL_TO_COORD(1), RND_MIL_TO_COORD(1), pcb_no_flags()); + } + for (l = 0; l <= PCB_MAX_FONTPOSITION / 16 + 1; l++) { + int y = (l + 1) * CELL_SIZE; + pcb_line_new_merge(lgrid, 0, y, PCB->hidlib.size_x, y, RND_MIL_TO_COORD(1), RND_MIL_TO_COORD(1), pcb_no_flags()); + } + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_fontsave[] = "FontSave()"; +static const char pcb_acth_fontsave[] = "Convert the current PCB back to a font."; +static fgw_error_t pcb_act_FontSave(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_font_t *font; + pcb_symbol_t *symbol; + int i; + pcb_line_t *l; + pcb_arc_t *a; + pcb_poly_t *p, *np; + gdl_iterator_t it; + pcb_layer_t *lfont, *lwidth; + + font = pcb_font(PCB, 0, 1); + lfont = PCB->Data->Layer + 0; + lwidth = PCB->Data->Layer + 2; + + for (i = 0; i <= PCB_MAX_FONTPOSITION; i++) { + font->Symbol[i].LineN = 0; + font->Symbol[i].Valid = 0; + font->Symbol[i].Width = 0; + } + + /* pack lines */ + linelist_foreach(&lfont->Line, &it, l) { + int x1 = l->Point1.X; + int y1 = l->Point1.Y; + int x2 = l->Point2.X; + int y2 = l->Point2.Y; + int ox, oy, s; + + s = XYtoSym(x1, y1); + ox = (s % 16 + 1) * CELL_SIZE; + oy = (s / 16 + 1) * CELL_SIZE; + symbol = &font->Symbol[s]; + + x1 -= ox; + y1 -= oy; + x2 -= ox; + y2 -= oy; + + if (symbol->Width < x1) + symbol->Width = x1; + if (symbol->Width < x2) + symbol->Width = x2; + symbol->Valid = 1; + + pcb_font_new_line_in_sym(symbol, x1, y1, x2, y2, l->Thickness); + } + + /* pack arcs */ + arclist_foreach(&lfont->Arc, &it, a) { + int cx = a->X; + int cy = a->Y; + int ox, oy, s; + + s = XYtoSym(cx, cy); + ox = (s % 16 + 1) * CELL_SIZE; + oy = (s / 16 + 1) * CELL_SIZE; + symbol = &font->Symbol[s]; + + cx -= ox; + cy -= oy; + + pcb_arc_bbox(a); + if (symbol->Width < a->BoundingBox.X2 - ox) + symbol->Width = a->BoundingBox.X2 - ox; + + if (symbol->Width < cx) + symbol->Width = cx; + symbol->Valid = 1; + + pcb_font_new_arc_in_sym(symbol, cx, cy, a->Width, a->StartAngle, a->Delta, a->Thickness); + } + + /* pack polygons */ + polylist_foreach(&lfont->Polygon, &it, p) { + rnd_coord_t x1 = p->Points[0].X; + rnd_coord_t y1 = p->Points[0].Y; + rnd_coord_t s, ox, oy; + int n; + + s = XYtoSym(x1, y1); + ox = (s % 16 + 1) * CELL_SIZE; + oy = (s / 16 + 1) * CELL_SIZE; + symbol = &font->Symbol[s]; + + np = pcb_font_new_poly_in_sym(symbol, p->PointN); + + for(n = 0; n < p->PointN; n++) { + np->Points[n].X = p->Points[n].X - ox; + np->Points[n].Y = p->Points[n].Y - oy; + if (symbol->Width < np->Points[n].X) + symbol->Width = np->Points[n].X; + } + } + + /* recalc delta */ + linelist_foreach(&lwidth->Line, &it, l) { + rnd_coord_t x1 = l->Point1.X; + rnd_coord_t y1 = l->Point1.Y; + rnd_coord_t ox, s; + + s = XYtoSym(x1, y1); + ox = (s % 16 + 1) * CELL_SIZE; + symbol = &font->Symbol[s]; + + x1 -= ox; + + symbol->Delta = x1 - symbol->Width; + } + + pcb_font_set_info(font); + rnd_actionva(RND_ACT_HIDLIB, "SaveFontTo", NULL); + + RND_ACT_IRES(0); + return 0; +} + +rnd_action_t fontmode_action_list[] = { + {"FontEdit", pcb_act_FontEdit, pcb_acth_fontedit, pcb_acts_fontedit}, + {"FontSave", pcb_act_FontSave, pcb_acth_fontsave, pcb_acts_fontsave} +}; + +static const char *fontmode_cookie = "fontmode plugin"; + +int pplg_check_ver_fontmode(int ver_needed) { return 0; } + +void pplg_uninit_fontmode(void) +{ + rnd_remove_actions_by_cookie(fontmode_cookie); +} + +int pplg_init_fontmode(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(fontmode_action_list, fontmode_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/fontmode/fontmode.pup =================================================================== --- tags/2.3.0/src_plugins/fontmode/fontmode.pup (nonexistent) +++ tags/2.3.0/src_plugins/fontmode/fontmode.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short font editor +$long Font editing actions. +$state works +$package extra +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/fp_board/Makefile =================================================================== --- tags/2.3.0/src_plugins/fp_board/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/fp_board/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_fp_board + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/fp_board/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/fp_board/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/fp_board/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {fp_board} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/fp_board/fp_board.o @] + +switch /local/pcb/fp_board/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/fp_board/fp_board.c =================================================================== --- tags/2.3.0/src_plugins/fp_board/fp_board.c (nonexistent) +++ tags/2.3.0/src_plugins/fp_board/fp_board.c (revision 33253) @@ -0,0 +1,163 @@ + +#include "config.h" + +#include +#include "plug_footprint.h" +#include "board.h" +#include "buffer.h" +#include "data.h" +#include +#include "obj_subc.h" +#include "obj_subc_list.h" +#include "obj_subc_op.h" +#include +#include +#include "operation.h" +#include "plug_io.h" +#include + +#define REQUIRE_PATH_PREFIX "board@" + +static int fp_board_load_dir(pcb_plug_fp_t *ctx, const char *path, int force) +{ + const char *fpath; + pcb_fplibrary_t *l; + pcb_buffer_t buff; + unsigned long int id; + int old_dedup; + pcb_subclist_dedup_initializer(dedup); + + if (strncmp(path, REQUIRE_PATH_PREFIX, strlen(REQUIRE_PATH_PREFIX)) != 0) + return -1; + + fpath = path + strlen(REQUIRE_PATH_PREFIX); + + /* load file */ + memset(&buff, 0, sizeof(buff)); + if (pcb_buffer_load_layout(PCB, &buff, fpath, NULL) != rnd_true) { + rnd_message(RND_MSG_ERROR, "Warning: failed to load %s\n", fpath); + return -1; + } + + /* make sure lib dir is ready */ + l = pcb_fp_lib_search(&pcb_library, path); + if (l == NULL) + l = pcb_fp_mkdir_len(&pcb_library, path, -1); + + /* add unique elements */ + old_dedup = pcb_subc_hash_ignore_uid; + pcb_subc_hash_ignore_uid = 1; + id = 0; + PCB_SUBC_LOOP(buff.Data) { + const char *ename; + pcb_fplibrary_t *e; + + id++; + pcb_subclist_dedup_skip(dedup, subc); + + ename = pcb_attribute_get(&subc->Attributes, "footprint"); + if (ename == NULL) + ename = subc->refdes; + if (ename == NULL) + ename = "anonymous"; + e = pcb_fp_append_entry(l, ename, PCB_FP_FILE, NULL, 0); + + /* remember location by ID - because of the dedup search by name is unsafe */ + if (e != NULL) + e->data.fp.loc_info = rnd_strdup_printf("%s@%lu", path, id); + + } PCB_END_LOOP; + + pcb_subc_hash_ignore_uid = old_dedup; + pcb_subclist_dedup_free(dedup); + + /* clean up buffer */ + pcb_buffer_clear(PCB, &buff); + free(buff.Data); + + return 0; +} + +static FILE *fp_board_fopen(pcb_plug_fp_t *ctx, const char *path, const char *name, pcb_fp_fopen_ctx_t *fctx, pcb_data_t *dst) +{ + char *fpath, *ids, *end; + unsigned long int id, req_id; + pcb_buffer_t buff; + pcb_opctx_t op; + + if (dst == NULL) + return NULL; + + if (strncmp(name, REQUIRE_PATH_PREFIX, strlen(REQUIRE_PATH_PREFIX)) != 0) + return NULL; + + /* split file name and ID */ + fpath = rnd_strdup(name + strlen(REQUIRE_PATH_PREFIX)); + ids = strchr(fpath, '@'); + if (ids == NULL) + goto err; + + *ids = '\0'; + ids++; + + req_id = strtoul(ids, &end, 10); + if (*end != '\0') + goto err; + + /* load file */ + memset(&buff, 0, sizeof(buff)); + if (pcb_buffer_load_layout(PCB, &buff, fpath, NULL) != rnd_true) { + rnd_message(RND_MSG_ERROR, "Warning: failed to load %s\n", fpath); + goto err; + } + + /* find the reuqested footprint in the file */ + id = 0; + PCB_SUBC_LOOP(buff.Data) { + id++; + if (id == req_id) { + memset(&op, 0, sizeof(op)); + op.buffer.dst = dst; + pcb_data_set_layer_parents(op.buffer.dst); + pcb_subcop_add_to_buffer(&op, subc); + + return PCB_FP_FOPEN_IN_DST; + } + } PCB_END_LOOP; + + /* clean up buffer */ + + pcb_buffer_clear(PCB, &buff); + free(buff.Data); + return NULL; + +err:; + free(fpath); + return NULL; +} + +static void fp_board_fclose(pcb_plug_fp_t *ctx, FILE * f, pcb_fp_fopen_ctx_t *fctx) +{ + rnd_message(RND_MSG_ERROR, "Internal error: fp_board_fclose() shouldn't have been called. Please report this bug.\n"); +} + + +static pcb_plug_fp_t fp_board; + +int pplg_check_ver_fp_board(int ver_needed) { return 0; } + +void pplg_uninit_fp_board(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_fp_t, pcb_plug_fp_chain, &fp_board); +} + +int pplg_init_fp_board(void) +{ + RND_API_CHK_VER; + fp_board.plugin_data = NULL; + fp_board.load_dir = fp_board_load_dir; + fp_board.fp_fopen = fp_board_fopen; + fp_board.fp_fclose = fp_board_fclose; + RND_HOOK_REGISTER(pcb_plug_fp_t, pcb_plug_fp_chain, &fp_board); + return 0; +} Index: tags/2.3.0/src_plugins/fp_board/fp_board.pup =================================================================== --- tags/2.3.0/src_plugins/fp_board/fp_board.pup (nonexistent) +++ tags/2.3.0/src_plugins/fp_board/fp_board.pup (revision 33253) @@ -0,0 +1,7 @@ +$class fp +$short footprint library from boards +$long Footprint: load a board and expose all the unique subcircuits on that board as a footprint library +$state WIP +$package (core) +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/fp_fs/Makefile =================================================================== --- tags/2.3.0/src_plugins/fp_fs/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/fp_fs/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_fp_fs + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/fp_fs/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/fp_fs/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/fp_fs/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {fp_fs} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/fp_fs/fp_fs.o @] +put /local/pcb/mod/CONF {$(PLUGDIR)/fp_fs/fp_fs_conf.h} +put /local/pcb/mod/CONFFILE {fp_fs.conf} +put /local/pcb/mod/CONFVAR {fp_fs_conf_internal} + +switch /local/pcb/fp_fs/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/fp_fs/fp_fs.c =================================================================== --- tags/2.3.0/src_plugins/fp_fs/fp_fs.c (nonexistent) +++ tags/2.3.0/src_plugins/fp_fs/fp_fs.c (revision 33253) @@ -0,0 +1,602 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Footprint libraries hosted in file system directories */ + +#include "config.h" + +#include +#include +#include +#include + +#include + +#include "board.h" +#include "data.h" +#include +#include +#include +#include "plug_footprint.h" +#include "plug_io.h" +#include +#include +#include +#include +#include +#include "conf_core.h" +#include +#include +#include + +#include "fp_fs_conf.h" + +#define FP_FS_CONF_FN "ar_extern.conf" +static conf_fp_fs_t conf_fp_fs; +static const char fp_fs_cookie[] = "fp_fs plugin"; + +static vtp0_t remove_regex; + +#include "conf_internal.c" + +/*** low level map cache ***/ + +typedef struct { + char *path; /* also the key */ + pcb_plug_fp_map_t map; + time_t mtime; +} pcb_fp_map_cache_t; + +htsp_t fp_fs_cache; + +pcb_plug_fp_map_t *pcb_io_map_footprint_file_cached(rnd_hidlib_t *hl, htsp_t *cache, struct stat *st, const char *path) +{ + pcb_fp_map_cache_t *c; + c = htsp_get(cache, path); + if ((c != NULL) && (c->mtime >= st->st_mtime)) + return &c->map; + + if (c == NULL) { + c = calloc(sizeof(pcb_fp_map_cache_t), 1); + c->path = rnd_strdup(path); + htsp_set(cache, c->path, c); + } + else + pcb_io_fp_map_free_fields(&c->map); + + pcb_io_map_footprint_file(hl, path, &c->map, 1); + c->mtime = st->st_mtime; + return &c->map; +} + +void fp_fs_cache_uninit(htsp_t *cache) +{ + htsp_entry_t *e; + for(e = htsp_first(cache); e != NULL; e = htsp_next(cache, e)) { + pcb_fp_map_cache_t *c = e->value; + free(c->path); + pcb_io_fp_map_free(&c->map); + free(c); + } + htsp_uninit(cache); +} + + +/*** list and search ***/ + + +typedef struct list_dir_s list_dir_t; + +struct list_dir_s { + char *parent; + char *subdir; + pcb_plug_fp_map_t *children; + list_dir_t *next; +}; + +typedef struct { + pcb_fplibrary_t *menu; + list_dir_t *subdirs; + int children; + int is_virtual_dir; +} list_st_t; + +static int list_cb(void *cookie, const char *subdir, const char *name, pcb_fptype_t type, void *tags[], pcb_plug_fp_map_t *children) +{ + list_st_t *l = (list_st_t *) cookie; + pcb_fplibrary_t *e; + + if ((type == PCB_FP_DIR) || (type == PCB_FP_FILEDIR)) { + list_dir_t *d; + /* can not recurse directly from here because that would ruin the menu + pointer: pcb_lib_menu_new(&Library) calls realloc()! + Build a list of directories to be visited later, instead. */ + d = malloc(sizeof(list_dir_t)); + d->subdir = rnd_strdup(name); + d->parent = rnd_strdup(subdir); + d->next = l->subdirs; + d->children = children; + l->subdirs = d; + return 0; + } + + l->children++; + e = pcb_fp_append_entry(l->menu, name, type, tags, 1); + +/* Avoid using rnd_concat() - would be a new dependency for gsch2pcb-rnd */ + { + int sl = strlen(subdir); + int nl = strlen(name); + char *end; + + end = e->data.fp.loc_info = malloc(sl+nl+4); + memcpy(end, subdir, sl); end += sl; + if (l->is_virtual_dir) { + *end = ':'; end++; + *end = ':'; end++; + } + else { + *end = RND_DIR_SEPARATOR_C; end++; + } + memcpy(end, name, nl+1); end += nl; + } + + return 0; +} + +/* returns whether file should be ignored by file name */ +static int fp_fs_ignore_fn(const char *fn, int len) +{ + int n; + rnd_conf_listitem_t *ci; + const char *p; + + if (fn == NULL) return 1; + + if (fn[0] == '.') { /* do not depend on config in avoiding infinite recursion on . and .. */ + if (fn[1] == '\0') return 1; + if ((fn[1] == '.') && (fn[2] == '\0')) return 1; + } + + rnd_conf_loop_list_str(&conf_fp_fs.plugins.fp_fs.ignore_prefix, ci, p, n) { + const char *s1, *s2; + for(s1 = fn, s2 = p; *s1 == *s2; s1++, s2++) { + if (*s2 == '\0') return 1; + if (*s1 == '\0') break; + } + } + + rnd_conf_loop_list_str(&conf_fp_fs.plugins.fp_fs.ignore_suffix, ci, p, n) { + long slen = strlen(p); + if ((len >= slen) && (strcmp(fn + (len - slen), p) == 0)) return 1; + } + + return 0; +} + +static int fp_fs_list(pcb_fplibrary_t *pl, const char *subdir, int recurse, + int (*cb) (void *cookie, const char *subdir, const char *name, pcb_fptype_t type, void *tags[], pcb_plug_fp_map_t *children), + void *cookie, int subdir_may_not_exist, int need_tags) +{ + char olddir[RND_PATH_MAX + 1]; /* The directory we start out in (cwd) */ + char new_subdir[RND_PATH_MAX + 1]; + char fn[RND_PATH_MAX + 1], *fn_end; + DIR *subdirobj; /* Interable object holding all subdir entries */ + struct dirent *subdirentry; /* Individual subdir entry */ + struct stat buffer; /* Buffer used in stat */ + size_t l; + int n_footprints = 0; /* Running count of footprints found in this subdir */ + + /* Cache old dir, then cd into subdir because stat is given relative file names. */ + memset(olddir, 0, sizeof olddir); + if (rnd_get_wd(olddir) == NULL) { + rnd_message(RND_MSG_ERROR, "fp_fs_list(): Could not determine initial working directory\n"); + return 0; + } + + if (strcmp(subdir, ".svn") == 0) + return 0; + + if (chdir(subdir)) { + if (!subdir_may_not_exist) + rnd_chdir_error_message(subdir); + return 0; + } + + + /* Determine subdir's abs path */ + if (rnd_get_wd(new_subdir) == NULL) { + rnd_message(RND_MSG_ERROR, "fp_fs_list(): Could not determine new working directory\n"); + if (chdir(olddir)) + rnd_chdir_error_message(olddir); + return 0; + } + + l = strlen(new_subdir); + memcpy(fn, new_subdir, l); + fn[l] = RND_DIR_SEPARATOR_C; + fn[l+1] = '\0'; + fn_end = fn + l + 1; + + /* First try opening the directory specified by path */ + if ((subdirobj = rnd_opendir(&PCB->hidlib, new_subdir)) == NULL) { + rnd_opendir_error_message(new_subdir); + if (chdir(olddir)) + rnd_chdir_error_message(olddir); + return 0; + } + + /* Now loop over files in this directory looking for files. + We ignore certain files which are not footprints. */ + while ((subdirentry = rnd_readdir(subdirobj)) != NULL) { +#ifdef FP_FS_TRACE + rnd_trace("readdir: '%s'\n", subdirentry->d_name); +#endif + + /* Ignore non-footprint files found in this directory + We're skipping .png and .html because those + may exist in a library tree to provide an html browsable + index of the library. */ + l = strlen(subdirentry->d_name); + if (fp_fs_ignore_fn(subdirentry->d_name, l)) + continue; + if (stat(subdirentry->d_name, &buffer) == 0) { + strcpy(fn_end, subdirentry->d_name); + if ((S_ISREG(buffer.st_mode)) || (RND_WRAP_S_ISLNK(buffer.st_mode))) { + pcb_plug_fp_map_t *res; + res = pcb_io_map_footprint_file_cached(&PCB->hidlib, &fp_fs_cache, &buffer, fn); + if (res->libtype == PCB_LIB_DIR) { + cb(cookie, new_subdir, subdirentry->d_name, PCB_FP_FILEDIR, NULL, res->next); + } + else if ((res->libtype == PCB_LIB_FOOTPRINT) && ((res->type == PCB_FP_FILE) || (res->type == PCB_FP_PARAMETRIC))) { + n_footprints++; + if (cb(cookie, new_subdir, subdirentry->d_name, res->type, (void **)res->tags.array, NULL)) + break; + continue; + } + } + + if ((S_ISDIR(buffer.st_mode)) || (RND_WRAP_S_ISLNK(buffer.st_mode))) { + cb(cookie, new_subdir, subdirentry->d_name, PCB_FP_DIR, NULL, NULL); + if (recurse) { + n_footprints += fp_fs_list(pl, fn, recurse, cb, cookie, 0, need_tags); + } + continue; + } + + } + } + /* Done. Clean up, cd back into old dir, and return */ + rnd_closedir(subdirobj); + if (chdir(olddir)) + rnd_chdir_error_message(olddir); + return n_footprints; +} + +static int fp_fs_load_dir_(pcb_fplibrary_t *pl, const char *subdir, const char *toppath, int is_root, pcb_plug_fp_map_t *children) +{ + list_st_t l; + list_dir_t *d, *nextd; + char working_[RND_PATH_MAX + 1]; + const char *visible_subdir; + char *working; /* String holding abs path to working dir */ + + sprintf(working_, "%s%c%s", toppath, RND_DIR_SEPARATOR_C, subdir); + rnd_path_resolve(&PCB->hidlib, working_, &working, 0, rnd_false); + + /* Return error if the root is not a directory, to give other fp_ plugins a chance */ + if ((is_root) && (!rnd_is_dir(&PCB->hidlib, working))) { + free(working); + return -1; + } + + if (strcmp(subdir, ".") == 0) + visible_subdir = toppath; + else + visible_subdir = subdir; + + l.menu = pcb_fp_lib_search(pl, visible_subdir); + if (l.menu == NULL) + l.menu = pcb_fp_mkdir_len(pl, visible_subdir, -1); + l.subdirs = NULL; + l.children = 0; + l.is_virtual_dir = 0; + + if (children != NULL) { + pcb_plug_fp_map_t *n; + l.is_virtual_dir = 1; + for(n = children; n != NULL; n = n->next) { + list_cb(&l, working, n->name, n->type, (void **)n->tags.array, NULL); + l.children++; + } + free(working); + return l.children; + } + + fp_fs_list(l.menu, working, 0, list_cb, &l, is_root, 1); + + /* now recurse to each subdirectory mapped in the previous call; + by now we don't care if menu is ruined by the realloc() in pcb_lib_menu_new() */ + for (d = l.subdirs; d != NULL; d = nextd) { + l.children += fp_fs_load_dir_(l.menu, d->subdir, d->parent, 0, d->children); + nextd = d->next; + free(d->subdir); + free(d->parent); + free(d); + } + if ((l.children == 0) && (l.menu->data.dir.children.used == 0)) + pcb_fp_rmdir(l.menu); + free(working); + return l.children; +} + + +static int fp_fs_load_dir(pcb_plug_fp_t *ctx, const char *path, int force) +{ + int res; + + res = fp_fs_load_dir_(&pcb_library, ".", path, 1, NULL); + if (res >= 0) { + pcb_fplibrary_t *l = pcb_fp_lib_search(&pcb_library, path); + if ((l != NULL) && (l->type == PCB_LIB_DIR)) + l->data.dir.backend = ctx; + } + return res; +} + +typedef struct { + const char *target; + int target_len; + int parametric; + char *path; + char *real_name; +} fp_search_t; + +static int fp_search_cb(void *cookie, const char *subdir, const char *name, pcb_fptype_t type, void *tags[], pcb_plug_fp_map_t *children) +{ + fp_search_t *ctx = (fp_search_t *) cookie; + if ((strncmp(ctx->target, name, ctx->target_len) == 0) && ((! !ctx->parametric) == (type == PCB_FP_PARAMETRIC))) { + const char *suffix = name + ctx->target_len; + int n, found = 0; + if (*suffix != '\0') { /* footprint names may end in .fp or .ele or .subc.lht or .lht */ + for(n = 0; n < remove_regex.used; n++) { + if (re_sei_exec(remove_regex.array[n], name)) { + char *dst; + /* remove by the regex, the remaining part must match the original request */ + re_sei_subst(remove_regex.array[n], &dst, name, "", 0); + found = (strcmp(dst, ctx->target) == 0); + if (found) + break; + } + } + } + else + found = 1; + + if (found) { + ctx->path = rnd_strdup(subdir); + ctx->real_name = rnd_strdup(name); + return 1; + } + } + return 0; +} + +/* walk the search_path for finding the first footprint for basename (shall not contain "(") */ +static char *fp_fs_search(const char *search_path, const char *basename, int parametric) +{ + const char *p, *end; + char path[RND_PATH_MAX + 1]; + fp_search_t ctx; + + if (rnd_is_path_abs(basename)) + return rnd_strdup(basename); + + ctx.target = basename; + ctx.target_len = strlen(ctx.target); + ctx.parametric = parametric; + ctx.path = NULL; + +/* fprintf("Looking for %s\n", ctx.target);*/ + + for (p = search_path; *p != '\0'; p = end + 1) { + char *fpath; + end = strchr(p, ':'); + if (end != NULL) { + memcpy(path, p, end - p); + path[end - p] = '\0'; + } + else + strcpy(path, p); + + rnd_path_resolve(&PCB->hidlib, path, &fpath, 0, rnd_false); +/* fprintf(stderr, " in '%s'\n", fpath);*/ + + fp_fs_list(&pcb_library, fpath, 1, fp_search_cb, &ctx, 1, 0); + if (ctx.path != NULL) { + sprintf(path, "%s%c%s", ctx.path, RND_DIR_SEPARATOR_C, ctx.real_name); + free(ctx.path); + free(ctx.real_name); +/* fprintf(" found '%s'\n", path);*/ + free(fpath); + return rnd_strdup(path); + } + free(fpath); + if (end == NULL) + break; + } + return NULL; +} + +#define F_IS_PARAMETRIC 0 +#define F_TMPNAME 1 +static FILE *fp_fs_fopen(pcb_plug_fp_t *ctx, const char *path, const char *name, pcb_fp_fopen_ctx_t *fctx, pcb_data_t *dst) +{ + char *basename, *params, *fullname; + FILE *fp, *f = NULL; + const char *libshell; + + fctx->field[F_TMPNAME].p = NULL; + fctx->field[F_IS_PARAMETRIC].i = pcb_fp_dupname(name, &basename, ¶ms); + if (basename == NULL) + return NULL; + + fctx->backend = ctx; + + fullname = fp_fs_search(path, basename, fctx->field[F_IS_PARAMETRIC].i); +/* fprintf(stderr, "basename=%s fullname=%s\n", basename, fullname);*/ +/* printf("pcb_fp_fopen: %d '%s' '%s' fullname='%s'\n", fctx->field[F_IS_PARAMETRIC].i, basename, params, fullname);*/ + + + if (fullname != NULL) { +/*fprintf(stderr, "fullname=%s param=%d\n", fullname, fctx->field[F_IS_PARAMETRIC].i);*/ + if (fctx->field[F_IS_PARAMETRIC].i) { + char *cmd; + const char *sep = " "; + libshell = conf_core.rc.library_shell; + if (libshell == NULL) { + libshell = ""; + sep = ""; + } +#ifdef __WIN32__ + { + char *s; + cmd = malloc(strlen(rnd_w32_bindir) + strlen(libshell) + strlen(fullname) + strlen(params) + 32); + sprintf(cmd, "%s/sh -c \"%s%s%s %s\"", rnd_w32_bindir, libshell, sep, fullname, params); + for(s = cmd; *s != '\0'; s++) + if (*s == '\\') + *s = '/'; + } +#else + cmd = malloc(strlen(libshell) + strlen(fullname) + strlen(params) + 16); + sprintf(cmd, "%s%s%s %s", libshell, sep, fullname, params); +#endif +/*fprintf(stderr, " cmd=%s\n", cmd);*/ + /* Make a copy of the output of the parametric so rewind() can be called on it */ + fctx->field[F_TMPNAME].p = rnd_tempfile_name_new("pcb-rnd-pfp"); + f = rnd_fopen(&PCB->hidlib, (char *)fctx->field[F_TMPNAME].p, "wb+"); + if (f != NULL) { + char buff[4096]; + int len; + fp = rnd_popen(&PCB->hidlib, cmd, "r"); + if (fp != NULL) { + while((len = fread(buff, 1, sizeof(buff), fp)) > 0) + fwrite(buff, 1, len, f); + rnd_pclose(fp); + } + else + rnd_message(RND_MSG_ERROR, "Parametric footprint: failed to execute %s\n", cmd); + rewind(f); + } + free(cmd); + } + else + f = rnd_fopen(&PCB->hidlib, fullname, "rb"); + free(fullname); + } + + free(basename); + return f; +} + +static void fp_fs_fclose(pcb_plug_fp_t *ctx, FILE * f, pcb_fp_fopen_ctx_t *fctx) +{ + fclose(f); + if (fctx->field[F_TMPNAME].p != NULL) + rnd_tempfile_unlink((char *)fctx->field[F_TMPNAME].p); +} + +static void fp_fs_free_remove_regex(void) +{ + long n; + for(n = 0; n < remove_regex.used; n++) + re_sei_free(remove_regex.array[n]); + vtp0_uninit(&remove_regex); +} + +static void fp_fs_cfg_cb(rnd_conf_native_t *cfg, int arr_idx) +{ + int n; + rnd_conf_listitem_t *ci; + const char *p; + + fp_fs_free_remove_regex(); + vtp0_init(&remove_regex); + rnd_conf_loop_list_str(&conf_fp_fs.plugins.fp_fs.remove_regex, ci, p, n) { + re_sei_t *regex = re_sei_comp(p); + if (regex != NULL) + vtp0_append(&remove_regex, regex); + else + rnd_message(RND_MSG_ERROR, "fp_fs: failed to compile remove_regex: '%s'\n", p); + } +} + + +static pcb_plug_fp_t fp_fs; +static rnd_conf_hid_id_t cfgid; + +int pplg_check_ver_fp_fs(int ver_needed) { return 0; } + +void pplg_uninit_fp_fs(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_fp_t, pcb_plug_fp_chain, &fp_fs); + + rnd_conf_hid_unreg(fp_fs_cookie); + + rnd_conf_unreg_file(FP_FS_CONF_FN, fp_fs_conf_internal); + + fp_fs_cache_uninit(&fp_fs_cache); + rnd_conf_unreg_fields("plugins/fp_fs/"); + fp_fs_free_remove_regex(); +} + +int pplg_init_fp_fs(void) +{ + static rnd_conf_hid_callbacks_t cbs; + + RND_API_CHK_VER; + fp_fs.plugin_data = NULL; + fp_fs.load_dir = fp_fs_load_dir; + fp_fs.fp_fopen = fp_fs_fopen; + fp_fs.fp_fclose = fp_fs_fclose; + RND_HOOK_REGISTER(pcb_plug_fp_t, pcb_plug_fp_chain, &fp_fs); + htsp_init(&fp_fs_cache, strhash, strkeyeq); + + rnd_conf_reg_file(FP_FS_CONF_FN, fp_fs_conf_internal); + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_fp_fs, field,isarray,type_name,cpath,cname,desc,flags); +#include "fp_fs_conf_fields.h" + + cfgid = rnd_conf_hid_reg(fp_fs_cookie, NULL); + cbs.val_change_post = fp_fs_cfg_cb; + rnd_conf_hid_set_cb(rnd_conf_get_field("plugins/fp_fs/remove_regex"), cfgid, &cbs); + + return 0; +} Index: tags/2.3.0/src_plugins/fp_fs/fp_fs.conf =================================================================== --- tags/2.3.0/src_plugins/fp_fs/fp_fs.conf (nonexistent) +++ tags/2.3.0/src_plugins/fp_fs/fp_fs.conf (revision 33253) @@ -0,0 +1,27 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:fp_fs { + li:ignore_prefix { + . + Makefile + } + li:ignore_suffix { + .png + .html + .pcb + } + li:remove_regex = { + {.tdx$} + {.fp$} + {.ele$} + {.subc_lht$} + {.lht$} + {.bxl$} + {.kicad_mod$} + } + } + } + } +} + Index: tags/2.3.0/src_plugins/fp_fs/fp_fs.pup =================================================================== --- tags/2.3.0/src_plugins/fp_fs/fp_fs.pup (nonexistent) +++ tags/2.3.0/src_plugins/fp_fs/fp_fs.pup (revision 33253) @@ -0,0 +1,7 @@ +$class fp +$short filesystem footprints +$long Footprint: file system based implementation. Used to be called Newlib: load footprints from directories. Run external processes for the parametric footprints. +$state works +$package (core) +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/fp_fs/fp_fs_conf.h =================================================================== --- tags/2.3.0/src_plugins/fp_fs/fp_fs_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/fp_fs/fp_fs_conf.h (revision 33253) @@ -0,0 +1,16 @@ +#ifndef PCB_FP_FS_CONF_H +#define PCB_FP_FS_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_LIST ignore_prefix; /* ignore file names starting with these prefixes */ + RND_CFT_LIST ignore_suffix; /* ignore file names ending with these suffixes */ + RND_CFT_LIST remove_regex; /* regex's used to remove 'file extension', e.g. .fp or .lht to match footprint file name to footprint sch name */ + } fp_fs; + } plugins; +} conf_fp_fs_t; + +#endif Index: tags/2.3.0/src_plugins/fp_wget/Makefile =================================================================== --- tags/2.3.0/src_plugins/fp_wget/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/Makefile (revision 33253) @@ -0,0 +1,12 @@ +all: + cd ../../src && $(MAKE) mod_fp_wget + +CFLAGS = -Wall -g -I../../src -I../.. -I../../src_3rd -I../../src_3rd/liblihata + +test: tester + +tester: tester.o gedasymbols.o wget_common.o ../../src_3rd/genvector/gds_char.o + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/fp_wget/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/fp_wget/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/Plug.tmpasm (revision 33253) @@ -0,0 +1,16 @@ +put /local/pcb/mod {fp_wget} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/fp_wget/fp_wget.o + $(PLUGDIR)/fp_wget/wget_common.o + $(PLUGDIR)/fp_wget/gedasymbols.o + $(PLUGDIR)/fp_wget/edakrill.o +@] +put /local/pcb/mod/CONF {$(PLUGDIR)/fp_wget/fp_wget_conf.h} +put /local/pcb/mod/CONFFILE {fp_wget.conf} +put /local/pcb/mod/CONFVAR {fp_wget_conf_internal} + +switch /local/pcb/fp_wget/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/fp_wget/edakrill.c =================================================================== --- tags/2.3.0/src_plugins/fp_wget/edakrill.c (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/edakrill.c (revision 33253) @@ -0,0 +1,345 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017, 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include "wget_common.h" +#include "edakrill.h" +#include +#include "plug_footprint.h" +#include +#include +#include "fp_wget_conf.h" +#include "globalconst.h" + +#define REQUIRE_PATH_PREFIX "wget@edakrill" + +#define ROOT_URL "http://www.repo.hu/projects/edakrill/" +#define FP_URL ROOT_URL "user/" + +static const char *url_idx_md5 = ROOT_URL "tags.idx.md5"; +static const char *url_idx_list = ROOT_URL "tags.idx"; + +struct { + char *name; + char *fname; + int fp; + long date; + void **tags; + int tags_used, tags_alloced; +} krill; + +static void tag_add_(const char *kv) +{ + if (krill.tags_used >= krill.tags_alloced) { + krill.tags_alloced += 16; + krill.tags = realloc(krill.tags, sizeof(void *) * krill.tags_alloced); + } + krill.tags[krill.tags_used] = (void *)(kv == NULL ? NULL : pcb_fp_tag(kv, 1)); + krill.tags_used++; +} + +static void tag_add(const char *key, const char *val) +{ + char *next, *tmp; + for(; val != NULL; val = next) { + next = strchr(val, ','); + if (next != NULL) { + *next = '\0'; + next++; + } + while(*val == ' ') val++; + if (*val == '\0') + break; + tmp = rnd_strdup_printf("%s:%s", key, val); + tag_add_(tmp); + free(tmp); + } +} + +static void krill_flush(pcb_plug_fp_t *ctx, gds_t *vpath, int base_len) +{ + if ((krill.fp) && (krill.fname != NULL)) { + char *end, *fn; + pcb_fplibrary_t *l; + +/* printf("Krill %s: %s [%ld]\n", krill.name, krill.fname, krill.date);*/ + + /* split path and fn; path stays in vpath.array, fn is a ptr to the file name */ + gds_truncate(vpath, base_len); + gds_append_str(vpath, krill.fname); + end = vpath->array + vpath->used - 1; + while((end > vpath->array) && (*end != '/')) { end--; vpath->used--; } + *end = '\0'; + vpath->used--; + end++; + fn = end; + + /* add to the database */ + l = pcb_fp_mkdir_p(vpath->array); + if (krill.tags != NULL) + tag_add_(NULL); + l = pcb_fp_append_entry(l, fn, PCB_FP_FILE, krill.tags, 0); + fn[-1] = '/'; + l->data.fp.loc_info = rnd_strdup(vpath->array); + + krill.tags = NULL; + krill.tags_used = 0; + } + + krill.tags_used = 0; + + free(krill.name); + free(krill.fname); + free(krill.tags); + krill.name = NULL; + krill.fname = NULL; + krill.fp = 0; + krill.date = 0; + krill.tags = NULL; + krill.tags_alloced = 0; +} + +int fp_edakrill_load_dir(pcb_plug_fp_t *ctx, const char *path, int force) +{ + FILE *f; + int fctx; + char *md5_last, *md5_new; + char line[1024]; + fp_get_mode mode; + gds_t vpath; + int vpath_base_len; + fp_get_mode wmode = FP_WGET_OFFLINE; + pcb_fplibrary_t *l; + char last_sum_fn[RND_PATH_MAX]; + + if (strncmp(path, REQUIRE_PATH_PREFIX, strlen(REQUIRE_PATH_PREFIX)) != 0) + return -1; + + rnd_snprintf(last_sum_fn, sizeof(last_sum_fn), "%s" RND_DIR_SEPARATOR_S "edakrill.last", conf_fp_wget.plugins.fp_wget.cache_dir); + + gds_init(&vpath); + gds_append_str(&vpath, REQUIRE_PATH_PREFIX); + + l = pcb_fp_mkdir_p(vpath.array); + if (l != NULL) + l->data.dir.backend = ctx; + + if (force || (conf_fp_wget.plugins.fp_wget.auto_update_edakrill)) + wmode &= ~FP_WGET_OFFLINE; + + if (fp_wget_open(url_idx_md5, conf_fp_wget.plugins.fp_wget.cache_dir, &f, &fctx, wmode) != 0) { + if (wmode & FP_WGET_OFFLINE) /* accept that we don't have the index in offline mode */ + goto quit; + goto err; + } + + md5_new = load_md5_sum(f); + fp_wget_close(&f, &fctx); + + if (md5_new == NULL) + goto err; + + f = rnd_fopen(NULL, last_sum_fn, "r"); + md5_last = load_md5_sum(f); + if (f != NULL) + fclose(f); + +/* printf("old='%s' new='%s'\n", md5_last, md5_new);*/ + + if (!md5_cmp_free(last_sum_fn, md5_last, md5_new)) { +/* printf("no chg.\n");*/ + mode = FP_WGET_OFFLINE; /* use the cache */ + } + else + mode = 0; + + if (fp_wget_open(url_idx_list, conf_fp_wget.plugins.fp_wget.cache_dir, &f, &fctx, mode) != 0) { + rnd_message(RND_MSG_ERROR, "edakrill: failed to download the new list\n"); + rnd_remove(NULL, last_sum_fn); /* make sure it is downloaded next time */ + goto err; + } + + gds_append(&vpath, '/'); + vpath_base_len = vpath.used; + + while(fgets(line, sizeof(line), f) != NULL) { + char *end; + if ((*line == '#') || (line[1] != ' ')) + continue; + + end = line + strlen(line) - 1; + *end = '\0'; + if (*line == 'f') { + krill_flush(ctx, &vpath, vpath_base_len); + krill.name = rnd_strdup(line+2); + } + if (strncmp(line, "t type=", 7) == 0) { + if (strcmp(line+7, "footprint") == 0) + krill.fp = 1; + } + if (*line == 't') { + char *val, *key = line+2; + val = strchr(key, '='); + if (val != NULL) { + *val = '\0'; + val++; + if ((strcmp(key, "auto/file") != 0) && (strcmp(key, "type") != 0)) { + tag_add(key, val); + } + } + } + if (*line == 'm') { + end = strstr(line, ".cnv.fp "); + if (end != NULL) { + end += 7; + *end = '\0'; + end++; + krill.fname = rnd_strdup(line+2); + krill.date = strtol(end, NULL, 10); + } + } + + } + krill_flush(ctx, &vpath, vpath_base_len); + fp_wget_close(&f, &fctx); + + quit:; + gds_uninit(&vpath); + return 0; + + err:; + gds_uninit(&vpath); + return -1; +} + +#define FIELD_WGET_CTX 0 + +static int search_edakrill(char *out, int out_len, FILE *f, const char *fn) +{ + char *line, line_[8192], *end; + + *out = '\0'; + + if (f == NULL) + return -1; + + while((line = fgets(line_, sizeof(line_), f)) != NULL) { + size_t len; + if (*line != 'f') + continue; + next:; + line += 2; + len = strlen(line); + if ((strstr(line, fn) != NULL) && (len < out_len)) { + while((line = fgets(line_, sizeof(line_), f)) != NULL) { + if (*line == 'f') + goto next; /* no suitable 'm' line but bumped into the next 'f' line -> process the next fp */ + if (*line == 'm') { + line += 2; + + end = strstr(line, ".cnv.fp "); /* accept only converted pcb footprints for now */ + if (end != NULL) { + end += 7; + *end = '\0'; + end++; + strcpy(out, line); + return 0; + } + } + } + } + } + return -1; +} + + +FILE *fp_edakrill_fopen(pcb_plug_fp_t *ctx, const char *path, const char *name, pcb_fp_fopen_ctx_t *fctx, pcb_data_t *dst) +{ + gds_t s; + char tmp[1024]; + FILE *f; + int from_path = (path != NULL) && (strcmp(path, REQUIRE_PATH_PREFIX) == 0); + + if (!from_path) { + if (strncmp(name, REQUIRE_PATH_PREFIX, strlen(REQUIRE_PATH_PREFIX)) == 0) + name+=strlen(REQUIRE_PATH_PREFIX); + else + return NULL; + } + + if (*name == '/') + name++; + + if (from_path) { + if (fp_wget_search(tmp, sizeof(tmp), name, !conf_fp_wget.plugins.fp_wget.auto_update_edakrill, url_idx_list, conf_fp_wget.plugins.fp_wget.cache_dir, search_edakrill) != 0) + goto bad; + name = tmp; + } + + gds_init(&s); + gds_append_str(&s, FP_URL); + gds_append_str(&s, name); + + fp_wget_open(s.array, conf_fp_wget.plugins.fp_wget.cache_dir, &f, &(fctx->field[FIELD_WGET_CTX].i), FP_WGET_UPDATE); + + gds_uninit(&s); + + bad:; + fctx->backend = ctx; + + return f; +} + +void fp_edakrill_fclose(pcb_plug_fp_t *ctx, FILE * f, pcb_fp_fopen_ctx_t *fctx) +{ + fp_wget_close(&f, &(fctx->field[FIELD_WGET_CTX].i)); +} + + +static pcb_plug_fp_t fp_edakrill; + +void fp_edakrill_uninit(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_fp_t, pcb_plug_fp_chain, &fp_edakrill); +} + +void fp_edakrill_init(void) +{ + fp_edakrill.plugin_data = NULL; + fp_edakrill.load_dir = fp_edakrill_load_dir; + fp_edakrill.fp_fopen = fp_edakrill_fopen; + fp_edakrill.fp_fclose = fp_edakrill_fclose; + + RND_HOOK_REGISTER(pcb_plug_fp_t, pcb_plug_fp_chain, &fp_edakrill); +} Index: tags/2.3.0/src_plugins/fp_wget/edakrill.h =================================================================== --- tags/2.3.0/src_plugins/fp_wget/edakrill.h (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/edakrill.h (revision 33253) @@ -0,0 +1,8 @@ +#include "plug_footprint.h" +#include "fp_wget_conf.h" +int fp_edakrill_load_dir(pcb_plug_fp_t *ctx, const char *path, int force); +FILE *fp_edakrill_fopen(pcb_plug_fp_t *ctx, const char *path, const char *name, pcb_fp_fopen_ctx_t *fctx, pcb_data_t *dst); +void fp_edakrill_fclose(pcb_plug_fp_t *ctx, FILE * f, pcb_fp_fopen_ctx_t *fctx); +void fp_edakrill_init(void); +void fp_edakrill_uninit(void); + Index: tags/2.3.0/src_plugins/fp_wget/fp_wget.c =================================================================== --- tags/2.3.0/src_plugins/fp_wget/fp_wget.c (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/fp_wget.c (revision 33253) @@ -0,0 +1,36 @@ +#include "config.h" +#include "gedasymbols.h" +#include "edakrill.h" +#include +#include "fp_wget_conf.h" +#include "../src_plugins/fp_wget/conf_internal.c" + + +conf_fp_wget_t conf_fp_wget; + +#define FP_WGET_CONF_FN "fp_wget.conf" + +int pplg_check_ver_fp_wget(int ver_needed) { return 0; } + +void pplg_uninit_fp_wget(void) +{ + rnd_conf_unreg_file(FP_WGET_CONF_FN, fp_wget_conf_internal); + fp_gedasymbols_uninit(); + fp_edakrill_uninit(); + rnd_conf_unreg_fields("plugins/fp_wget/"); +} + +int pplg_init_fp_wget(void) +{ + RND_API_CHK_VER; + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_fp_wget, field,isarray,type_name,cpath,cname,desc,flags); +#include "fp_wget_conf_fields.h" + + rnd_conf_reg_file(FP_WGET_CONF_FN, fp_wget_conf_internal); + + fp_gedasymbols_init(); + fp_edakrill_init(); + return 0; +} Index: tags/2.3.0/src_plugins/fp_wget/fp_wget.conf =================================================================== --- tags/2.3.0/src_plugins/fp_wget/fp_wget.conf (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/fp_wget.conf (revision 33253) @@ -0,0 +1,9 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:fp_wget { + cache_dir=fp_wget_cache + } + } + } +} Index: tags/2.3.0/src_plugins/fp_wget/fp_wget.pup =================================================================== --- tags/2.3.0/src_plugins/fp_wget/fp_wget.pup (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/fp_wget.pup (revision 33253) @@ -0,0 +1,9 @@ +$class fp +$short web footprints +$long Footprint: get static (file) footprints from the web, e.g. from http://gedasymbols.org +$state works +$package cloud +default buildin +dep fp_fs +dep lib_wget +autoload 1 Index: tags/2.3.0/src_plugins/fp_wget/fp_wget_conf.h =================================================================== --- tags/2.3.0/src_plugins/fp_wget/fp_wget_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/fp_wget_conf.h (revision 33253) @@ -0,0 +1,18 @@ +#ifndef PCB_FP_WGET_CONF_H +#define PCB_FP_WGET_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN auto_update_gedasymbols; /* update the index of gedasymbols on startup automatically */ + RND_CFT_BOOLEAN auto_update_edakrill; /* update the index of edakrill on startup automatically */ + RND_CFT_STRING cache_dir; /* where to build the cache */ + } fp_wget; + } plugins; +} conf_fp_wget_t; + +extern conf_fp_wget_t conf_fp_wget; + +#endif Index: tags/2.3.0/src_plugins/fp_wget/gedasymbols.c =================================================================== --- tags/2.3.0/src_plugins/fp_wget/gedasymbols.c (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/gedasymbols.c (revision 33253) @@ -0,0 +1,239 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016, 2017, 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include "wget_common.h" +#include "gedasymbols.h" +#include +#include "plug_footprint.h" +#include +#include +#include "fp_wget_conf.h" +#include "globalconst.h" + +#define REQUIRE_PATH_PREFIX "wget@gedasymbols" + +#define CGI_URL "http://www.gedasymbols.org/scripts/global_list.cgi" +#define FP_URL "http://www.gedasymbols.org/" +#define FP_DL "?dl" +static const char *url_idx_md5 = CGI_URL "?md5"; +static const char *url_idx_list = CGI_URL; + + +int fp_gedasymbols_load_dir(pcb_plug_fp_t *ctx, const char *path, int force) +{ + FILE *f; + int fctx; + char *md5_last, *md5_new; + char line[1024]; + fp_get_mode mode; + gds_t vpath; + int vpath_base_len; + fp_get_mode wmode = FP_WGET_OFFLINE; + pcb_fplibrary_t *l; + char last_sum_fn[RND_PATH_MAX]; + + if (strncmp(path, REQUIRE_PATH_PREFIX, strlen(REQUIRE_PATH_PREFIX)) != 0) + return -1; + + rnd_snprintf(last_sum_fn, sizeof(last_sum_fn), "%s" RND_DIR_SEPARATOR_S "gedasymbols.last", conf_fp_wget.plugins.fp_wget.cache_dir); + + gds_init(&vpath); + gds_append_str(&vpath, REQUIRE_PATH_PREFIX); + + l = pcb_fp_mkdir_p(vpath.array); + if (l != NULL) + l->data.dir.backend = ctx; + + if (force || (conf_fp_wget.plugins.fp_wget.auto_update_gedasymbols)) + wmode &= ~FP_WGET_OFFLINE; + + if (fp_wget_open(url_idx_md5, conf_fp_wget.plugins.fp_wget.cache_dir, &f, &fctx, wmode) != 0) { + if (wmode & FP_WGET_OFFLINE) /* accept that we don't have the index in offline mode */ + goto quit; + goto err; + } + + md5_new = load_md5_sum(f); + fp_wget_close(&f, &fctx); + + if (md5_new == NULL) + goto err; + + f = rnd_fopen(NULL, last_sum_fn, "r"); + md5_last = load_md5_sum(f); + if (f != NULL) + fclose(f); + +/* printf("old='%s' new='%s'\n", md5_last, md5_new);*/ + + if (!md5_cmp_free(last_sum_fn, md5_last, md5_new)) { +/* printf("no chg.\n");*/ + mode = FP_WGET_OFFLINE; /* use the cache */ + } + else + mode = 0; + + if (fp_wget_open(url_idx_list, conf_fp_wget.plugins.fp_wget.cache_dir, &f, &fctx, mode) != 0) { + rnd_message(RND_MSG_ERROR, "gedasymbols: failed to download the new list\n"); + rnd_remove(NULL, last_sum_fn); /* make sure it is downloaded next time */ + goto err; + } + + gds_append(&vpath, '/'); + vpath_base_len = vpath.used; + + while(fgets(line, sizeof(line), f) != NULL) { + char *end, *fn; + + if (*line == '#') + continue; + end = strchr(line, '|'); + if (end == NULL) + continue; + *end = '\0'; + + /* split path and fn; path stays in vpath.array, fn is a ptr to the file name */ + gds_truncate(&vpath, vpath_base_len); + gds_append_str(&vpath, line); + end = vpath.array + vpath.used - 1; + while((end > vpath.array) && (*end != '/')) { end--; vpath.used--; } + *end = '\0'; + vpath.used--; + end++; + fn = end; + + /* add to the database */ + l = pcb_fp_mkdir_p(vpath.array); + l = pcb_fp_append_entry(l, fn, PCB_FP_FILE, NULL, 0); + fn[-1] = '/'; + l->data.fp.loc_info = rnd_strdup(vpath.array); + } + fp_wget_close(&f, &fctx); + + quit:; + gds_uninit(&vpath); + return 0; + + err:; + gds_uninit(&vpath); + return -1; +} + +#define FIELD_WGET_CTX 0 + +static int search_gedasyms(char *out, int out_len, FILE *f, const char *fn) +{ + char *line, line_[8192]; + + *out = '\0'; + + if (f == NULL) + return -1; + + while((line = fgets(line_, sizeof(line_), f)) != NULL) { + char *sep; + sep = strchr(line, '|'); + if (sep == NULL) + continue; + *sep = '\0'; + if ((strstr(line, fn) != NULL) && (strlen(line) < out_len)) { + strcpy(out, line); + return 0; + } + } + return -1; +} + + +FILE *fp_gedasymbols_fopen(pcb_plug_fp_t *ctx, const char *path, const char *name, pcb_fp_fopen_ctx_t *fctx, pcb_data_t *dst) +{ + gds_t s; + char tmp[1024]; + FILE *f = NULL; + int from_path = (path != NULL) && (strcmp(path, REQUIRE_PATH_PREFIX) == 0); + + if (!from_path) { + if (strncmp(name, REQUIRE_PATH_PREFIX, strlen(REQUIRE_PATH_PREFIX)) == 0) + name+=strlen(REQUIRE_PATH_PREFIX); + else + return NULL; + } + + if (*name == '/') + name++; + + if (from_path) { + if (fp_wget_search(tmp, sizeof(tmp), name, !conf_fp_wget.plugins.fp_wget.auto_update_gedasymbols, url_idx_list, conf_fp_wget.plugins.fp_wget.cache_dir, search_gedasyms) != 0) + goto bad; + name = tmp; + } + + gds_init(&s); + gds_append_str(&s, FP_URL); + gds_append_str(&s, name); + gds_append_str(&s, FP_DL); + + fp_wget_open(s.array, conf_fp_wget.plugins.fp_wget.cache_dir, &f, &(fctx->field[FIELD_WGET_CTX].i), FP_WGET_UPDATE); + + gds_uninit(&s); + + bad:; + fctx->backend = ctx; + + return f; +} + +void fp_gedasymbols_fclose(pcb_plug_fp_t *ctx, FILE * f, pcb_fp_fopen_ctx_t *fctx) +{ + fp_wget_close(&f, &(fctx->field[FIELD_WGET_CTX].i)); +} + + +static pcb_plug_fp_t fp_gedasymbols; + +void fp_gedasymbols_uninit(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_fp_t, pcb_plug_fp_chain, &fp_gedasymbols); +} + +void fp_gedasymbols_init(void) +{ + fp_gedasymbols.plugin_data = NULL; + fp_gedasymbols.load_dir = fp_gedasymbols_load_dir; + fp_gedasymbols.fp_fopen = fp_gedasymbols_fopen; + fp_gedasymbols.fp_fclose = fp_gedasymbols_fclose; + + RND_HOOK_REGISTER(pcb_plug_fp_t, pcb_plug_fp_chain, &fp_gedasymbols); +} Index: tags/2.3.0/src_plugins/fp_wget/gedasymbols.h =================================================================== --- tags/2.3.0/src_plugins/fp_wget/gedasymbols.h (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/gedasymbols.h (revision 33253) @@ -0,0 +1,8 @@ +#include "plug_footprint.h" +#include "fp_wget_conf.h" +int fp_gedasymbols_load_dir(pcb_plug_fp_t *ctx, const char *path, int force); +FILE *fp_gedasymbols_fopen(pcb_plug_fp_t *ctx, const char *path, const char *name, pcb_fp_fopen_ctx_t *fctx, pcb_data_t *dst); +void fp_gedasymbols_fclose(pcb_plug_fp_t *ctx, FILE * f, pcb_fp_fopen_ctx_t *fctx); +void fp_gedasymbols_init(void); +void fp_gedasymbols_uninit(void); + Index: tags/2.3.0/src_plugins/fp_wget/tester.c =================================================================== --- tags/2.3.0/src_plugins/fp_wget/tester.c (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/tester.c (revision 33253) @@ -0,0 +1,39 @@ +#include +#include +#include "config.h" +#include "gedasymbols.h" + +#undef strdup +char *rnd_strdup(const char *s) { return strdup(s); } + +pcb_plug_fp_t *pcb_plug_fp_chain = NULL; + +pcb_library_t ltmp; +pcb_library_t *pcb_fp_mkdir_p(const char *path) +{ + printf("lib mkdir: '%s'\n", path); + return (library_t *)<mp; +} + +pcb_library_t *pcb_fp_append_entry(library_t *parent, const char *name, pcb_fp_type_t type, void *tags[], rnd_bool dup_tags) +{ + printf("lib entry: '%s'\n", name); + return (library_t *)<mp; +} + +int main() +{ + pcb_fp_fopen_ctx_t fctx; + FILE *f; + char line[1024]; + +/* fp_gedasymbols_load_dir(NULL, "gedasymbols://", 1); */ + f = fp_gedasymbols_fopen(NULL, NULL, "wget@gedasymbols/user/sean_depagnier/footprints/HDMI_CONN.fp", &fctx); + + while(fgets(line, sizeof(line), f) != NULL) + printf("|%s", line); + + fp_gedasymbols_fclose(NULL, f, &fctx); + +} + Index: tags/2.3.0/src_plugins/fp_wget/wget_common.c =================================================================== --- tags/2.3.0/src_plugins/fp_wget/wget_common.c (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/wget_common.c (revision 33253) @@ -0,0 +1,202 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016, 2017, 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include +#include "config.h" +#include "wget_common.h" +#include +#include +#include "globalconst.h" + +#include + +int fp_wget_offline = 0; + +enum { + FCTX_INVALID = 0, + FCTX_POPEN, + FCTX_FOPEN, + FCTX_NOP +}; + +static int mkdirp(const char *dir) +{ + int len; + char buff[RND_PATH_MAX+32]; + len = rnd_snprintf(buff, sizeof(buff), "mkdir -p '%s'", dir); + if (len >= sizeof(buff)-1) + return -1; + return rnd_system(NULL, buff); +} + +int fp_wget_open(const char *url, const char *cache_path, FILE **f, int *fctx, fp_get_mode mode) +{ + char *cmd; + int ul = strlen(url), cl = strlen(cache_path); + int update = (mode & FP_WGET_UPDATE); + + cmd = malloc(ul*2+cl+32); + *fctx = FCTX_INVALID; + + if (cache_path == NULL) { + if (f == NULL) + goto error; + if (!fp_wget_offline) + *f = pcb_wget_popen(url, update, NULL); + if (*f == NULL) + goto error; + *fctx = FCTX_POPEN; + } + else { + char *cdir; + cdir = strstr(url, "://"); + if (cdir == NULL) + goto error; + cdir += 3; + + { + char *end; + sprintf(cmd, "%s/%s", cache_path, cdir); + end = strrchr(cmd, '/'); + if (end != NULL) { + *end = '\0'; + if (mkdirp(cmd) != 0) + goto error; + *end = '/'; + } + } + + if ((!fp_wget_offline) && !(mode & FP_WGET_OFFLINE)) { + int res; + sprintf(cmd, "%s/%s", cache_path, cdir); + res = pcb_wget_disk(url, cmd, update, NULL); +/* rnd_trace("------res=%d\n", res); */ + if ((res != 0) && (res != 768)) { /* some versions of wget will return error on -c if the file doesn't need update; try to guess whether it's really an error */ + /* when wget fails, a 0-long file might be left there - remove it so it won't block new downloads */ + rnd_remove(NULL, cmd); + } + } + if (f != NULL) { + sprintf(cmd, "%s/%s", cache_path, cdir); + *f = rnd_fopen(NULL, cmd, "rb"); + if (*f == NULL) + goto error; + *fctx = FCTX_FOPEN; + } + else + *fctx = FCTX_NOP; + } + free(cmd); + return 0; + + error:; + free(cmd); + return -1; +} + +int fp_wget_close(FILE **f, int *fctx) +{ + if (*fctx == FCTX_NOP) + return 0; + + if (*f == NULL) + return -1; + + switch(*fctx) { + case FCTX_POPEN: rnd_pclose(*f); *f = NULL; return 0; + case FCTX_FOPEN: fclose(*f); *f = NULL; return 0; + } + + return -1; +} + + +char *load_md5_sum(FILE *f) +{ + char *s, sum[64]; + + if (f == NULL) + return NULL; + + *sum = '\0'; + fgets(sum, sizeof(sum), f); + sum[sizeof(sum)-1] = '\0'; + + for(s = sum;; s++) { + if ((*s == '\0') || (isspace(*s))) { + if ((s - sum) == 32) { + *s = '\0'; + return rnd_strdup(sum); + } + else + return NULL; + } + if (isdigit(*s)) + continue; + if ((*s >= 'a') && (*s <= 'f')) + continue; + if ((*s >= 'A') && (*s <= 'F')) + continue; + return NULL; + } +} + +int md5_cmp_free(const char *last_fn, char *md5_last, char *md5_new) +{ + int changed = 0; + + if ((md5_last == NULL) || (strcmp(md5_last, md5_new) != 0)) { + FILE *f; + f = rnd_fopen(NULL, last_fn, "w"); + fputs(md5_new, f); + fclose(f); + changed = 1; + } + if (md5_last != NULL) + free(md5_last); + free(md5_new); + return changed; +} + +int fp_wget_search(char *out, int out_len, const char *name, int offline, const char *url, const char *cache, int (*fp_wget_search_)(char *out, int out_len, FILE *f, const char *fn)) +{ + FILE *f_idx; + int fctx; + fp_get_mode mode = offline ? FP_WGET_OFFLINE : 0; + + if (fp_wget_open(url, cache, &f_idx, &fctx, mode) == 0) { + if (fp_wget_search_(out, out_len, f_idx, name) != 0) { + fp_wget_close(&f_idx, &fctx); + return -1; + } + } + else + return -1; + fp_wget_close(&f_idx, &fctx); + return 0; +} Index: tags/2.3.0/src_plugins/fp_wget/wget_common.h =================================================================== --- tags/2.3.0/src_plugins/fp_wget/wget_common.h (nonexistent) +++ tags/2.3.0/src_plugins/fp_wget/wget_common.h (revision 33253) @@ -0,0 +1,18 @@ +#include + +typedef enum { + FP_WGET_UPDATE = 1, /* wget -c: update existing file, don't replace (a.k.a. cache) */ + FP_WGET_OFFLINE = 2 /* do not wget, open cached file or fail */ +} fp_get_mode; + +int fp_wget_open(const char *url, const char *cache_path, FILE **f, int *fctx, fp_get_mode mode); +int fp_wget_close(FILE **f, int *fctx); + +char *load_md5_sum(FILE *f); +int md5_cmp_free(const char *last_fn, char *md5_last, char *md5_new); + +/* search fn in an auto updated index file; return 0 on success and + fill in out with the full path from the index. Search_cb: + search fn in an index file; return 0 on success and fill in out with the + full path from the index. */ +int fp_wget_search(char *out, int out_len, const char *fn, int offline, const char *idx_url, const char *idx_cache, int (*search_cb)(char *out, int out_len, FILE *f, const char *fn)); Index: tags/2.3.0/src_plugins/import_accel_net/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_accel_net/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_accel_net/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_accel_net + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_accel_net/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_accel_net/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_accel_net/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {import_accel_net} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_accel_net/accel_net.o @] +put /local/pcb/mod/MENUFILE {accel_net-menu.lht} +put /local/pcb/mod/MENUVAR {accel_net_menu} + +switch /local/pcb/import_accel_net/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_accel_net/accel_net-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_accel_net/accel_net-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_accel_net/accel_net-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Load Accel netlist file = { action=LoadAccelNetFrom() } + } + } + } +} Index: tags/2.3.0/src_plugins/import_accel_net/accel_net.c =================================================================== --- tags/2.3.0/src_plugins/import_accel_net/accel_net.c (nonexistent) +++ tags/2.3.0/src_plugins/import_accel_net/accel_net.c (revision 33253) @@ -0,0 +1,271 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * sch import: ACCEL netlist + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "plug_import.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "undo.h" + +#include "menu_internal.c" + +static const char *accel_net_cookie = "accel_net importer"; + +static int accel_net_parse_net(FILE *fn) +{ + gsxl_dom_t dom; + gsxl_node_t *netlist, *n, *m; + int res, c; + gds_t tmp; + char line[1024]; + + gds_init(&tmp); + gsxl_init(&dom, gsxl_node_t); + + fgets(line, sizeof(line), fn); /* eat up the header line, not part of the s-expr */ + + dom.parse.line_comment_char = '#'; + dom.parse.brace_quote = 1; + + /* need to fake a root because there are multiple roots in the file */ + gsxl_parse_char(&dom, '('); + gsxl_parse_char(&dom, 'R'); + gsxl_parse_char(&dom, ' '); + + do { + c = fgetc(fn); + if (c == EOF) + gsxl_parse_char(&dom, ')'); /* close fake root first */ + } while((res = gsxl_parse_char(&dom, c)) == GSX_RES_NEXT); + + if (res != GSX_RES_EOE) { + rnd_message(RND_MSG_ERROR, "accel: s-expression parse error\n"); + return -1; + } + + /* compact and simplify the tree */ + gsxl_compact_tree(&dom); + + if ((dom.root->children == NULL) || (dom.root->children->next == NULL)) { + rnd_message(RND_MSG_ERROR, "accel: missing root node or netlist\n"); + return -1; + } + + if (strcmp(dom.root->children->str, "asciiHeader") != 0) { + rnd_message(RND_MSG_ERROR, "accel: invalid root node; espected 'asciiHeader', got '%s'\n", dom.root->str); + return -1; + } + + netlist = dom.root->children->next; + if (strcmp(netlist->str, "netlist") != 0) { + rnd_message(RND_MSG_ERROR, "accel: invalid root node; espected 'asciiHeader', got '%s'\n", dom.root->str); + return -1; + } + + rnd_actionva(&PCB->hidlib, "ElementList", "start", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + + + netlist = netlist->children->next; /* first item was the netlist name */ + for(n = netlist; n != NULL; n = n->next) { + if (strcmp(n->str, "compInst") == 0) { + char *refdes = n->children->str, *footprint = NULL, *value = ""; + for(m = n->children; m != NULL; m = m->next) { + if (strcmp(m->str, "originalName") == 0) footprint = m->children->str; + if (strcmp(m->str, "compValue") == 0) value = m->children->str; + } + if (footprint != NULL) + rnd_actionva(&PCB->hidlib, "ElementList", "Need", refdes, footprint, value, NULL); + else + rnd_message(RND_MSG_ERROR, "accel: can't import %s: no footprint\n", refdes); + } + else if (strcmp(n->str, "net") == 0) { + char *netname = n->children->str; + for(m = n->children; m != NULL; m = m->next) { + char *refdes = NULL, *pin = NULL; + if (strcmp(m->str, "node") == 0) { + refdes = m->children->str; + pin = m->children->next->str; + tmp.used = 0; + gds_append_str(&tmp, refdes); + gds_append(&tmp, '-'); + gds_append_str(&tmp, pin); + rnd_actionva(&PCB->hidlib, "Netlist", "Add", netname, tmp.array, NULL); + } + } + } + } + + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + rnd_actionva(&PCB->hidlib, "ElementList", "Done", NULL); + + gsxl_uninit(&dom); + gds_uninit(&tmp); + return 0; +} + + +static int accel_net_load(const char *fname_net) +{ + FILE *fn; + int ret = 0; + + fn = rnd_fopen(&PCB->hidlib, fname_net, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname_net); + return -1; + } + + pcb_undo_freeze_serial(); + ret = accel_net_parse_net(fn); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + fclose(fn); + return ret; +} + +static const char pcb_acts_LoadAccelNetFrom[] = "LoadAccelNetFrom(filename)"; +static const char pcb_acth_LoadAccelNetFrom[] = "Loads the specified Accel EDA netlist file."; +fgw_error_t pcb_act_LoadAccelNetFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + static char *default_file = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadAccelNetFrom, fname = argv[1].val.str); + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Load pads ascii netlist file...", + "Picks a pads ascii netlist file to load.\n", + default_file, ".net", NULL, "accel_net", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 1; + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + RND_ACT_IRES(0); + return accel_net_load(fname); +} + +static int accel_net_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + FILE *f; + unsigned int limit; + + if ((aspects != IMPORT_ASPECT_NETLIST) || (numargs != 1)) + return 0; /* only pure netlist import is supported from a single file*/ + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + for(limit = 0; limit < 4; limit++) { + char *s, line[1024]; + s = fgets(line, sizeof(line), f); + if (s == NULL) + break; + while(isspace(*s)) s++; + if (strncmp(s, "ACCEL_ASCII", 11) == 0) { + fclose(f); + return 100; + } + } + + fclose(f); + + return 0; +} + + +static int accel_net_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_accel_net: requires exactly 1 input file name\n"); + return -1; + } + return accel_net_load(fns[0]); +} + +static pcb_plug_import_t import_accel_net; + +rnd_action_t accel_net_action_list[] = { + {"LoadAccelNetFrom", pcb_act_LoadAccelNetFrom, pcb_acth_LoadAccelNetFrom, pcb_acts_LoadAccelNetFrom} +}; + +int pplg_check_ver_import_accel_net(int ver_needed) { return 0; } + +void pplg_uninit_import_accel_net(void) +{ + rnd_remove_actions_by_cookie(accel_net_cookie); + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_accel_net); + rnd_hid_menu_unload(rnd_gui, accel_net_cookie); +} + +int pplg_init_import_accel_net(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_accel_net.plugin_data = NULL; + + import_accel_net.fmt_support_prio = accel_net_support_prio; + import_accel_net.import = accel_net_import; + import_accel_net.name = "accel_net"; + import_accel_net.desc = "schamtics from accel EDA netlist"; + import_accel_net.ui_prio = 50; + import_accel_net.single_arg = 1; + import_accel_net.all_filenames = 1; + import_accel_net.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_accel_net); + + RND_REGISTER_ACTIONS(accel_net_action_list, accel_net_cookie) + rnd_hid_menu_load(rnd_gui, NULL, accel_net_cookie, 175, NULL, 0, accel_net_menu, "plugin: import accel_net"); + return 0; +} Index: tags/2.3.0/src_plugins/import_accel_net/import_accel_net.pup =================================================================== --- tags/2.3.0/src_plugins/import_accel_net/import_accel_net.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_accel_net/import_accel_net.pup (revision 33253) @@ -0,0 +1,10 @@ +$class import +$short import Accel netlist +$long Import the netlist and footprints from a Accel netlist. +$state works +$fmt-native no +$fmt-feature-r Accel ASCII netlists + footprint info +$package import-net +default buildin +dep lib_gensexpr +autoload 1 Index: tags/2.3.0/src_plugins/import_calay/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_calay/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_calay/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_calay + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_calay/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_calay/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_calay/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {import_calay} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_calay/calay.o @] +put /local/pcb/mod/MENUFILE {calay-menu.lht} +put /local/pcb/mod/MENUVAR {calay_menu} + +switch /local/pcb/import_calay/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_calay/calay-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_calay/calay-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_calay/calay-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Load Calay .net+.cmp files = { action=LoadCalayFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/import_calay/calay.c =================================================================== --- tags/2.3.0/src_plugins/import_calay/calay.c (nonexistent) +++ tags/2.3.0/src_plugins/import_calay/calay.c (revision 33253) @@ -0,0 +1,303 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * calay import HID + * pcb-rnd Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "plug_import.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#define NETEXT ".net" +#define CMPEXT ".cmp" + +#include "menu_internal.c" + +static const char *calay_cookie = "calay importer"; + +/* remove leading whitespace */ +#define ltrim(s) while(isspace(*s)) s++ + +/* remove trailing newline */ +#define rtrim(s) \ + do { \ + char *end; \ + for(end = s + strlen(s) - 1; (end >= s) && ((*end == '\r') || (*end == '\n') || (*end == ' ')); end--) \ + *end = '\0'; \ + } while(0) + + +static int calay_parse_net(FILE *fn) +{ + char line[512]; + char *curr = NULL; + + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + + while(fgets(line, sizeof(line), fn) != NULL) { + char *s, *next, *num; + + s = line; + ltrim(s); + if (*s == '/') { + s++; + next = strpbrk(s, " \t\r\n"); + if (next != NULL) { + *next = '\0'; + next++; + } + free(curr); + curr = rnd_strdup(s); + s = next; + } + + for(;;) { + ltrim(s); + if (*s == '\0') + break; + next = strchr(s, ')'); + if (next != NULL) { + *next = '\0'; + next++; + } + num = strchr(s, '('); + if (num != NULL) { + *num = '-'; + if (curr != NULL) + rnd_actionva(&PCB->hidlib, "Netlist", "Add", curr, s, NULL); + else + rnd_message(RND_MSG_ERROR, "Calay syntax error: %s is after a ;, not in any net\n", s); + } + else + rnd_message(RND_MSG_ERROR, "Calay syntax error: %s should have been refdes(pin)\n", s); + + if ((next == NULL) || (*next == '\0')) + break; + switch(*next) { + case ' ': + case '\t': + case ',': next++; break; + case ';': next++; free(curr); curr = NULL; next++; break; + default: + rnd_message(RND_MSG_ERROR, "Calay syntax error: invalid separator: %s %d (expected , or ;)\n", next, *next); + } + s = next; + } + } + + free(curr); + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + + return 0; +} + +static int calay_parse_comp(FILE *f) +{ + char line[512]; + char *val, *refdes, *footprint, *end; + int len; + rnd_actionva(&PCB->hidlib, "ElementList", "start", NULL); + + while(fgets(line, sizeof(line), f) != NULL) { + len = strlen(line); + if ((len > 2) && (len < 54)) { + rnd_message(RND_MSG_ERROR, "Calay component syntax error: short line: '%s'\n", line); + continue; + } + val = line; + + refdes = strpbrk(val, " \t\r\n"); + if (refdes == NULL) + continue; + *refdes = 0; + refdes++; + ltrim(refdes); + + footprint = strpbrk(refdes, " \t\r\n"); + if (footprint == NULL) + continue; + *footprint = 0; + footprint++; + ltrim(footprint); + + end = strpbrk(footprint, " \t\r\n"); + if (end != NULL) + *end = '\0'; + + rnd_actionva(&PCB->hidlib, "ElementList", "Need", refdes, footprint, val, NULL); + } + rnd_actionva(&PCB->hidlib, "ElementList", "Done", NULL); + return 0; +} + + +static int calay_load(const char *fname_net, const char *fname_cmp) +{ + FILE *f; + int ret = 0; + + f = rnd_fopen(&PCB->hidlib, fname_net, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "can't open calay netlist file '%s' for read\n", fname_net); + return -1; + } + ret = calay_parse_net(f); + fclose(f); + + f = rnd_fopen(&PCB->hidlib, fname_cmp, "r"); + if (f == NULL) + rnd_message(RND_MSG_ERROR, "can't open calay component file '%s' for read\n(non-fatal, but footprints will not be placed)\n", fname_cmp); + + pcb_undo_freeze_serial(); + ret = calay_parse_comp(f); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + fclose(f); + return ret; +} + +static const char pcb_acts_LoadCalayFrom[] = "LoadCalayFrom(filename)"; +static const char pcb_acth_LoadCalayFrom[] = "Loads the specified calay netlist/component file pair."; +fgw_error_t pcb_act_LoadCalayFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname_net = NULL; + char *fname_cmp, *end; + static char *default_file = NULL; + + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadCalayFrom, fname_net = argv[1].val.str); + + if (!fname_net || !*fname_net) { + fname_net = rnd_gui->fileselect(rnd_gui, + "Load calay netlist file...", "Picks a calay netlist file to load.\n", + default_file, NETEXT, NULL, "calay", RND_HID_FSD_READ, NULL); + if (fname_net == NULL) + return 1; + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + fname_cmp = malloc(strlen(fname_net) + strlen(CMPEXT) + 4); + strcpy(fname_cmp, fname_net); + end = strrchr(fname_cmp, '.'); + if (end == NULL) + end = fname_cmp + strlen(fname_cmp); + strcpy(end, CMPEXT); + + RND_ACT_IRES(calay_load(fname_net, fname_cmp)); + free(fname_cmp); + return 0; +} + +static int calay_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + FILE *f; + + if (aspects != IMPORT_ASPECT_NETLIST) + return 0; /* only pure netlist import is supported */ + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + { + char *s, line[16]; + + s = fgets(line, sizeof(line), f); + fclose(f); + if ((s != NULL) && (s[0] == '/') && (s[7] == ' ')) + return 100; + } + return 0; +} + + +static int calay_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_calay: requires exactly 1 input file name\n"); + return -1; + } + return rnd_actionva(&PCB->hidlib, "LoadCalayFrom", fns[0], NULL); +} + +static pcb_plug_import_t import_calay; + +rnd_action_t calay_action_list[] = { + {"LoadCalayFrom", pcb_act_LoadCalayFrom, pcb_acth_LoadCalayFrom, pcb_acts_LoadCalayFrom} +}; + +int pplg_check_ver_import_calay(int ver_needed) { return 0; } + +void pplg_uninit_import_calay(void) +{ + rnd_remove_actions_by_cookie(calay_cookie); + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_calay); + rnd_hid_menu_unload(rnd_gui, calay_cookie); +} + +int pplg_init_import_calay(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_calay.plugin_data = NULL; + + import_calay.fmt_support_prio = calay_support_prio; + import_calay.import = calay_import; + import_calay.name = "calay"; + import_calay.desc = "schamtics from calay"; + import_calay.ui_prio = 20; + import_calay.single_arg = 1; + import_calay.all_filenames = 1; + import_calay.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_calay); + + + RND_REGISTER_ACTIONS(calay_action_list, calay_cookie) + rnd_hid_menu_load(rnd_gui, NULL, calay_cookie, 170, NULL, 0, calay_menu, "plugin: import calay"); + return 0; +} Index: tags/2.3.0/src_plugins/import_calay/import_calay.pup =================================================================== --- tags/2.3.0/src_plugins/import_calay/import_calay.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_calay/import_calay.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import calay .net +$long Import the netlist and footprints from a calay netlist. +$state works +$fmt-native no +$fmt-feature-r calay (netlists + footprint info) +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_dsn/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_dsn/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_dsn/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_dsn + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_dsn/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_dsn/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_dsn/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {import_dsn} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_dsn/dsn.o @] +put /local/pcb/mod/MENUFILE {dsn-menu.lht} +put /local/pcb/mod/MENUVAR {dsn_menu} + +switch /local/pcb/import_dsn/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_dsn/dsn-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_dsn/dsn-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_dsn/dsn-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_geo { + li:submenu { + ha:Load routed dsn or ses file = { action=LoadDsnFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/import_dsn/dsn.c =================================================================== --- tags/2.3.0/src_plugins/import_dsn/dsn.c (nonexistent) +++ tags/2.3.0/src_plugins/import_dsn/dsn.c (revision 33253) @@ -0,0 +1,361 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * Specctra .dsn import HID + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "polygon.h" +#include + +#include +#include +#include +#include + +#include "src_plugins/lib_compat_help/pstk_compat.h" + +#include "menu_internal.c" + + +static const char *dsn_cookie = "dsn importer"; + +typedef enum { + TYPE_PCB, + TYPE_SESSION +} dsn_type_t; + +static rnd_layer_id_t ses_layer_by_name(pcb_board_t *pcb, const char *name) +{ + char *end; + long gid; + pcb_layergrp_t *grp; + + gid = strtol(name, &end, 10); + if ((end[0] != '_') || (end[1] != '_')) + return -1; + + grp = pcb_get_layergrp(pcb, gid); + if (grp == NULL) + return -1; + + if (strcmp(end+2, grp->name) != 0) { + rnd_message(RND_MSG_ERROR, "layer (group) name mismatch: group %ld should be '%s' but is '%s'\nses file not for this board?\n", gid, grp->name, end+2); + return -1; + } + + if (grp->len <= 0) { + rnd_message(RND_MSG_ERROR, "layer (group) '%s' has no layers\nses file not for this board?\n", name); + return -1; + } + + if (!(grp->ltype & PCB_LYT_COPPER)) { + rnd_message(RND_MSG_ERROR, "layer (group) type %s should a copper layer group\nses file not for this board?\n", name); + return -1; + } + + return grp->lid[0]; +} + +static void parse_polyline(long int *nlines, rnd_coord_t clear, const gsxl_node_t *n, const char *unit, int workaround0) +{ + const gsxl_node_t *c; + rnd_coord_t x, y, lx, ly, thick; + long pn; + const char *slayer = n->children->str; + const char *sthick = n->children->next->str; + rnd_bool succ; + rnd_layer_id_t lid; + pcb_layer_t *layer; + + thick = rnd_get_value(sthick, unit, NULL, &succ); + if (!succ) { + rnd_message(RND_MSG_ERROR, "import_dsn: skipping polyline because thickness is invalid: %s\n", sthick); + return; + } + + lid = ses_layer_by_name(PCB, slayer); + if (lid < 0) { + rnd_message(RND_MSG_ERROR, "import_dsn: skipping polyline because layer name is invalid: %s\n", slayer); + return; + } + layer = PCB->Data->Layer+lid; + + /*printf("- %s\n", slayer);*/ + for(pn = 0, c = n->children->next->next; c != NULL; pn++, c = c->next->next) { + const char *sx = c->str; + const char *sy = c->next->str; + x = rnd_get_value(sx, unit, NULL, &succ); + if (!succ) { + rnd_message(RND_MSG_ERROR, "import_dsn: skipping polyline segment because x coord is invalid: %s\n", sx); + return; + } + y = rnd_get_value(sy, unit, NULL, &succ); + if (!succ) { + rnd_message(RND_MSG_ERROR, "import_dsn: skipping polyline segment because x coord is invalid: %s\n", sy); + return; + } + if (workaround0 && ((y < RND_MM_TO_COORD(0.01)) || (x < RND_MM_TO_COORD(0.01)))) /* workaround for broken polyline coords */ + return; + (*nlines)++; + if (pn > 0) { + /*pcb_line_t *line = */pcb_line_new_merge(layer, lx, PCB->hidlib.size_y - ly, + x, PCB->hidlib.size_y - y, thick, clear, pcb_flag_make(PCB_FLAG_AUTO | PCB_FLAG_CLEARLINE)); +/* pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_LINE, layer, line);*/ +/* rnd_printf("LINE: %$mm %$mm .. %$mm %$mm\n", lx, ly, x, y);*/ + } + lx = x; + ly = y; + } +} + +static void parse_wire(long int *nlines, rnd_coord_t clear, const gsxl_node_t *wire, dsn_type_t type) +{ + const gsxl_node_t *n; + for(n = wire->children; n != NULL; n = n->next) { + if ((type == TYPE_PCB) && (strcmp(n->str, "polyline_path") == 0)) + parse_polyline(nlines, clear, n, "mm", 1); + else if ((type == TYPE_SESSION) && (strcmp(n->str, "path") == 0)) + parse_polyline(nlines, clear, n, "nm", 0); + else if (strcmp(n->str, "net") == 0) { + /* ignore */ + } + else if (strcmp(n->str, "type") == 0) { + /* ignore */ + } + else if (strcmp(n->str, "clearance_class") == 0) { + /* ignore */ + } + else + rnd_message(RND_MSG_WARNING, "import_dsn: ignoring unknown wire directive %s\n", n->str); + } +} + +static void parse_via(rnd_coord_t clear, const gsxl_node_t *via, dsn_type_t type) +{ + const gsxl_node_t *c = via->children->next; + const char *name = via->children->str; + const char *sx = c->str; + const char *sy = c->next->str; + rnd_bool succ; + rnd_coord_t x, y, dia, drill; + long l1, l2; + const char *unit = (type == TYPE_PCB) ? "mm" : "nm"; + + if (strncmp(name, "via_", 4) != 0) { + rnd_message(RND_MSG_ERROR, "import_dsn: skipping via with invalid name (prefix): %s\n", name); + return; + } + + name += 4; + if (sscanf(name, "%ld_%ld", &l1, &l2) != 2) { + rnd_message(RND_MSG_ERROR, "import_dsn: skipping via with invalid name (diameters): %s\n", name); + return; + } + + dia = l1; + drill = l2; + + x = rnd_get_value(sx, unit, NULL, &succ); + if (!succ) { + rnd_message(RND_MSG_ERROR, "import_dsn: skipping via segment because x coord is invalid: %s\n", sx); + return; + } + y = rnd_get_value(sy, unit, NULL, &succ); + if (!succ) { + rnd_message(RND_MSG_ERROR, "import_dsn: skipping via segment because x coord is invalid: %s\n", sy); + return; + } + + { + pcb_pstk_t *ps = pcb_pstk_new_compat_via(PCB->Data, -1, x, PCB->hidlib.size_y - y, drill, dia, clear, 0, PCB_PSTK_COMPAT_ROUND, 1); + PCB_FLAG_SET(PCB_FLAG_AUTO, ps); + } +} + +static const char pcb_acts_LoadDsnFrom[] = "LoadDsnFrom(filename)"; +static const char pcb_acth_LoadDsnFrom[] = "Loads the specified routed dsn file."; + +fgw_error_t pcb_act_LoadDsnFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + rnd_coord_t clear; + FILE *f; + gsxl_dom_t dom; + int c, seek_quote = 1; + long int nlines = 0, nvias = 0; + gsx_parse_res_t rs; + gsxl_node_t *wiring, *w, *routes, *nout, *n; + dsn_type_t type; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadDsnFrom, fname = argv[1].val.str); + + if ((fname == NULL) || (*fname == '\0')) { + fname = rnd_gui->fileselect(rnd_gui, + "Load a routed dsn or ses file...", + "Select dsn or ses file to load.\nThe file could be generated using the tool downloaded from freeroute.net\n", + NULL, /* default file name */ + ".dsn", NULL, "dsn", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 1; + } + + /* load and parse the file into a dom tree */ + f = rnd_fopen(&PCB->hidlib, fname, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "import_dsn: can't open %s for read\n", fname); + return 1; + } + gsxl_init(&dom, gsxl_node_t); + dom.parse.line_comment_char = '#'; + do { + c = fgetc(f); + rs = gsxl_parse_char(&dom, c); + + /* Workaround: skip the unbalanced '"' in string_quote */ + if (seek_quote && (dom.parse.used == 12) && (strncmp(dom.parse.atom, "string_quote", dom.parse.used) == 0)) { + do { + c = fgetc(f); + } while((c != ')') && (c != EOF)); + rs = gsxl_parse_char(&dom, ')'); + seek_quote = 0; + } + } while(rs == GSX_RES_NEXT); + fclose(f); + + if (rs != GSX_RES_EOE) { + rnd_message(RND_MSG_ERROR, "import_dsn: parse error in %s at %d:%d\n", fname, dom.parse.line, dom.parse.col); + goto error; + } + gsxl_compact_tree(&dom); + + + /* parse the tree: find wiring */ + clear = PCB->RouteStyle.array[0].Clearance * 2; + if (strcmp(dom.root->str, "PCB") == 0) + type = TYPE_PCB; + else if (strcmp(dom.root->str, "session") == 0) + type = TYPE_SESSION; + else { + rnd_message(RND_MSG_ERROR, "import_dsn: s-expr is not a PCB or session\n"); + goto error; + } + + switch(type) { + case TYPE_PCB: + for(wiring = dom.root->children; wiring != NULL; wiring = wiring->next) + if (strcmp(wiring->str, "wiring") == 0) + break; + + if (wiring == NULL) { + rnd_message(RND_MSG_ERROR, "import_dsn: s-expr does not have a wiring section\n"); + goto error; + } + + /* parse wiring */ + for(w = wiring->children; w != NULL; w = w->next) { + if (strcmp(w->str, "wire") == 0) + parse_wire(&nlines, clear, w, type); + if (strcmp(w->str, "via") == 0) { + parse_via(clear, w, type); + nvias++; + } + } + break; + case TYPE_SESSION: + for(routes = dom.root->children; routes != NULL; routes = routes->next) + if (strcmp(routes->str, "routes") == 0) + break; + + if (routes == NULL) { + rnd_message(RND_MSG_ERROR, "import_dsn: s-expr does not have a routes section\n"); + goto error; + } + + for(nout = routes->children; nout != NULL; nout = nout->next) + if (strcmp(nout->str, "network_out") == 0) + break; + + if (nout == NULL) { + rnd_message(RND_MSG_ERROR, "import_dsn: s-expr does not have a network_out section\n"); + goto error; + } + + for(n = nout->children; n != NULL; n = n->next) { + for(w = n->children; w != NULL; w = w->next) { + if (strcmp(w->str, "wire") == 0) + parse_wire(&nlines, clear, w, type); + if (strcmp(w->str, "via") == 0) { + parse_via(clear, w, type); + nvias++; + } + } + } + break; + } + + rnd_message(RND_MSG_INFO, "import_dsn: loaded %ld wires and %ld vias\n", nlines, nvias); + + gsxl_uninit(&dom); + RND_ACT_IRES(0); + return 0; + + error:; + gsxl_uninit(&dom); + + RND_ACT_IRES(-1); + return 0; +} + +rnd_action_t dsn_action_list[] = { + {"LoadDsnFrom", pcb_act_LoadDsnFrom, pcb_acth_LoadDsnFrom, pcb_acts_LoadDsnFrom} +}; + +int pplg_check_ver_import_dsn(int ver_needed) { return 0; } + +void pplg_uninit_import_dsn(void) +{ + rnd_remove_actions_by_cookie(dsn_cookie); + rnd_hid_menu_unload(rnd_gui, dsn_cookie); +} + +int pplg_init_import_dsn(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(dsn_action_list, dsn_cookie) + rnd_hid_menu_load(rnd_gui, NULL, dsn_cookie, 190, NULL, 0, dsn_menu, "plugin: import_dsn"); + return 0; +} + Index: tags/2.3.0/src_plugins/import_dsn/import_dsn.pup =================================================================== --- tags/2.3.0/src_plugins/import_dsn/import_dsn.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_dsn/import_dsn.pup (revision 33253) @@ -0,0 +1,11 @@ +$class import +$short specctra .dsn importer +$long Import specctra .dsn files +$state works +$fmt-native no +$fmt-feature-r specctra .dsn (wires and vias) +$package auto +default buildin +dep lib_compat_help +dep lib_gensexpr +autoload 1 Index: tags/2.3.0/src_plugins/import_edif/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_edif/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_edif/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_import_edif + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/import_edif/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_edif/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_edif/Plug.tmpasm (revision 33253) @@ -0,0 +1,9 @@ +put /local/pcb/mod {import_edif} +append /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_edif/edif.o $(PLUGDIR)/import_edif/import_edif.o @] +append /local/pcb/mod/YACC {$(PLUGDIR)/import_edif/edif} + +switch /local/pcb/import_edif/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_edif/edif.c =================================================================== --- tags/2.3.0/src_plugins/import_edif/edif.c (nonexistent) +++ tags/2.3.0/src_plugins/import_edif/edif.c (revision 33253) @@ -0,0 +1,6251 @@ +/* A Bison parser, made by GNU Bison 3.3.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. + + 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 3 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, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.3.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse edifparse +#define yylex ediflex +#define yyerror ediferror +#define yydebug edifdebug +#define yynerrs edifnerrs + +#define yylval ediflval +#define yychar edifchar + +/* First part of user prologue. */ +#line 1 "edif.y" /* yacc.c:337 */ + +/* + * PCB Edif parser based heavily on: + * + * Header: edif.y,v 1.18 87/12/07 19:59:49 roger Locked + */ +/************************************************************************ + * * + * edif.y * + * * + * EDIF 2.0.0 parser, Level 0 * + * * + * You are free to copy, distribute, use it, abuse it, make it * + * write bad tracks all over the disk ... or anything else. * + * * + * Your friendly neighborhood Rogue Monster - roger@mips.com * + * * + ************************************************************************/ +#include + +/* for malloc, free, atoi */ +#include + +/* for strcpy */ +#include + +#include + +#include +#include "board.h" +#include "data.h" +#include +#include "netlist.h" +#include +#include +#include + +/* + * Local definitions. + */ +#define IDENT_LENGTH 255 +#define Malloc(s) malloc(s) +#define Free(p) free(p) +#define Getc(s) getc(s) +#define Ungetc(c) ungetc(c,Input) + + typedef struct _str_pair + { + char* str1; + char* str2; + struct _str_pair* next; + } str_pair; + + typedef struct _pair_list + { + char* name; + str_pair* list; + } pair_list; + + str_pair* new_str_pair(char* s1, char* s2) + { + str_pair* ps = (str_pair *)malloc(sizeof(str_pair)); + ps->str1 = s1; + ps->str2 = s2; + ps->next = NULL; + return ps; + } + + pair_list* new_pair_list(str_pair* ps) + { + pair_list* pl = (pair_list *)malloc(sizeof(pair_list)); + pl->list = ps; + pl->name = NULL; + return pl; + } + + void str_pair_free(str_pair* ps) + { + str_pair* node; + while ( ps ) + { + free(ps->str1); + free(ps->str2); + node = ps; + ps = ps->next; + free(node); + } + } + + void pair_list_free(pair_list* pl) + { + str_pair_free(pl->list); + free(pl->name); + free(pl); + } + + void define_pcb_net(str_pair* name, pair_list* nodes) + { + int tl; + str_pair* done_node; + str_pair* node; + char* buf; + char* p; + pcb_net_t *net; + + if ( !name->str1 ) + { + /* no net name given, stop now */ + /* if renamed str2 also exists and must be freed */ + if ( name->str2 ) free(name->str2); + free(name); + pair_list_free(nodes); + return; + } + net = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_INPUT], name->str1, PCB_NETA_ALLOC); + free(name->str1); + /* if renamed str2 also exists and must be freed */ + if ( name->str2 ) free(name->str2); + free(name); + buf = (char *)malloc(256); + if ( !buf ) + { + /* no memory */ + pair_list_free(nodes); + return; + } + + node = nodes->list; + free(nodes->name); + free(nodes); + while ( node ) + { + /* check for node with no instance */ + if ( !node->str1 ) + { + /* toss it and move on */ + free(node->str2); + done_node = node; + node = node->next; + free(done_node); + continue; + } + tl = strlen(node->str1) + strlen(node->str2); + if ( tl + 3 > 256 ) + { + free(buf); + buf = (char *)malloc(tl+3); + if ( !buf ) + { + /* no memory */ + str_pair_free(node); + return; + } + } + strcpy(buf,node->str1); + /* make all upper case, because of PCB funky behaviour */ + p=buf; + while ( *p ) + { + *p = toupper( (int) *p); + p++; + } + /* add dash separating designator from node */ + *(buf+strlen(node->str1)) = '-'; + /* check for the edif number prefix */ + if ( node->str2[0] == '&' ) + { + /* skip number prefix */ + strcpy(buf+strlen(node->str1)+1,node->str2 +1); + } + else + { + strcpy(buf+strlen(node->str1)+1,node->str2); + } + /* free the strings */ + free(node->str1); + free(node->str2); + + pcb_net_term_get_by_pinname(net, buf, PCB_NETA_ALLOC); + + done_node = node; + node = node->next; + free(done_node); + } + } + + +/* forward function declarations */ + static int yylex(void); + static void yyerror(const char *); + static void PopC(void); + +#line 271 "edif.c" /* yacc.c:337 */ +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "edif.h". */ +#ifndef YY_EDIF_EDIF_H_INCLUDED +# define YY_EDIF_EDIF_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int edifdebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + EDIF_TOK_IDENT = 258, + EDIF_TOK_INT = 259, + EDIF_TOK_KEYWORD = 260, + EDIF_TOK_STR = 261, + EDIF_TOK_ANGLE = 262, + EDIF_TOK_BEHAVIOR = 263, + EDIF_TOK_CALCULATED = 264, + EDIF_TOK_CAPACITANCE = 265, + EDIF_TOK_CENTERCENTER = 266, + EDIF_TOK_CENTERLEFT = 267, + EDIF_TOK_CENTERRIGHT = 268, + EDIF_TOK_CHARGE = 269, + EDIF_TOK_CONDUCTANCE = 270, + EDIF_TOK_CURRENT = 271, + EDIF_TOK_DISTANCE = 272, + EDIF_TOK_DOCUMENT = 273, + EDIF_TOK_ENERGY = 274, + EDIF_TOK_EXTEND = 275, + EDIF_TOK_FLUX = 276, + EDIF_TOK_FREQUENCY = 277, + EDIF_TOK_GENERIC = 278, + EDIF_TOK_GRAPHIC = 279, + EDIF_TOK_INDUCTANCE = 280, + EDIF_TOK_INOUT = 281, + EDIF_TOK_INPUT = 282, + EDIF_TOK_LOGICMODEL = 283, + EDIF_TOK_LOWERCENTER = 284, + EDIF_TOK_LOWERLEFT = 285, + EDIF_TOK_LOWERRIGHT = 286, + EDIF_TOK_MASKLAYOUT = 287, + EDIF_TOK_MASS = 288, + EDIF_TOK_MEASURED = 289, + EDIF_TOK_MX = 290, + EDIF_TOK_MXR90 = 291, + EDIF_TOK_MY = 292, + EDIF_TOK_MYR90 = 293, + EDIF_TOK_NETLIST = 294, + EDIF_TOK_OUTPUT = 295, + EDIF_TOK_PCBLAYOUT = 296, + EDIF_TOK_POWER = 297, + EDIF_TOK_R0 = 298, + EDIF_TOK_R180 = 299, + EDIF_TOK_R270 = 300, + EDIF_TOK_R90 = 301, + EDIF_TOK_REQUIRED = 302, + EDIF_TOK_RESISTANCE = 303, + EDIF_TOK_RIPPER = 304, + EDIF_TOK_ROUND = 305, + EDIF_TOK_SCHEMATIC = 306, + EDIF_TOK_STRANGER = 307, + EDIF_TOK_SYMBOLIC = 308, + EDIF_TOK_TEMPERATURE = 309, + EDIF_TOK_TIE = 310, + EDIF_TOK_TIME = 311, + EDIF_TOK_TRUNCATE = 312, + EDIF_TOK_UPPERCENTER = 313, + EDIF_TOK_UPPERLEFT = 314, + EDIF_TOK_UPPERRIGHT = 315, + EDIF_TOK_VOLTAGE = 316, + EDIF_TOK_ACLOAD = 317, + EDIF_TOK_AFTER = 318, + EDIF_TOK_ANNOTATE = 319, + EDIF_TOK_APPLY = 320, + EDIF_TOK_ARC = 321, + EDIF_TOK_ARRAY = 322, + EDIF_TOK_ARRAYMACRO = 323, + EDIF_TOK_ARRAYRELATEDINFO = 324, + EDIF_TOK_ARRAYSITE = 325, + EDIF_TOK_ATLEAST = 326, + EDIF_TOK_ATMOST = 327, + EDIF_TOK_AUTHOR = 328, + EDIF_TOK_BASEARRAY = 329, + EDIF_TOK_BECOMES = 330, + EDIF_TOK_BETWEEN = 331, + EDIF_TOK_BOOLEAN = 332, + EDIF_TOK_BOOLEANDISPLAY = 333, + EDIF_TOK_BOOLEANMAP = 334, + EDIF_TOK_BORDERPATTERN = 335, + EDIF_TOK_BORDERWIDTH = 336, + EDIF_TOK_BOUNDINGBOX = 337, + EDIF_TOK_CELL = 338, + EDIF_TOK_CELLREF = 339, + EDIF_TOK_CELLTYPE = 340, + EDIF_TOK_CHANGE = 341, + EDIF_TOK_CIRCLE = 342, + EDIF_TOK_COLOR = 343, + EDIF_TOK_COMMENT = 344, + EDIF_TOK_COMMENTGRAPHICS = 345, + EDIF_TOK_COMPOUND = 346, + EDIF_TOK_CONNECTLOCATION = 347, + EDIF_TOK_CONTENTS = 348, + EDIF_TOK_CORNERTYPE = 349, + EDIF_TOK_CRITICALITY = 350, + EDIF_TOK_CURRENTMAP = 351, + EDIF_TOK_CURVE = 352, + EDIF_TOK_CYCLE = 353, + EDIF_TOK_DATAORIGIN = 354, + EDIF_TOK_DCFANINLOAD = 355, + EDIF_TOK_DCFANOUTLOAD = 356, + EDIF_TOK_DCMAXFANIN = 357, + EDIF_TOK_DCMAXFANOUT = 358, + EDIF_TOK_DELAY = 359, + EDIF_TOK_DELTA = 360, + EDIF_TOK_DERIVATION = 361, + EDIF_TOK_DESIGN = 362, + EDIF_TOK_DESIGNATOR = 363, + EDIF_TOK_DIFFERENCE = 364, + EDIF_TOK_DIRECTION = 365, + EDIF_TOK_DISPLAY = 366, + EDIF_TOK_DOMINATES = 367, + EDIF_TOK_DOT = 368, + EDIF_TOK_DURATION = 369, + EDIF_TOK_E = 370, + EDIF_TOK_EDIF = 371, + EDIF_TOK_EDIFLEVEL = 372, + EDIF_TOK_EDIFVERSION = 373, + EDIF_TOK_ENCLOSUREDISTANCE = 374, + EDIF_TOK_ENDTYPE = 375, + EDIF_TOK_ENTRY = 376, + EDIF_TOK_EVENT = 377, + EDIF_TOK_EXACTLY = 378, + EDIF_TOK_EXTERNAL = 379, + EDIF_TOK_FABRICATE = 380, + EDIF_TOK_FALSE = 381, + EDIF_TOK_FIGURE = 382, + EDIF_TOK_FIGUREAREA = 383, + EDIF_TOK_FIGUREGROUP = 384, + EDIF_TOK_FIGUREGROUPOBJECT = 385, + EDIF_TOK_FIGUREGROUPOVERRIDE = 386, + EDIF_TOK_FIGUREGROUPREF = 387, + EDIF_TOK_FIGUREPERIMETER = 388, + EDIF_TOK_FIGUREWIDTH = 389, + EDIF_TOK_FILLPATTERN = 390, + EDIF_TOK_FOLLOW = 391, + EDIF_TOK_FORBIDDENEVENT = 392, + EDIF_TOK_GLOBALPORTREF = 393, + EDIF_TOK_GREATERTHAN = 394, + EDIF_TOK_GRIDMAP = 395, + EDIF_TOK_IGNORE = 396, + EDIF_TOK_INCLUDEFIGUREGROUP = 397, + EDIF_TOK_INITIAL = 398, + EDIF_TOK_INSTANCE = 399, + EDIF_TOK_INSTANCEBACKANNOTATE = 400, + EDIF_TOK_INSTANCEGROUP = 401, + EDIF_TOK_INSTANCEMAP = 402, + EDIF_TOK_INSTANCEREF = 403, + EDIF_TOK_INTEGER = 404, + EDIF_TOK_INTEGERDISPLAY = 405, + EDIF_TOK_INTERFACE = 406, + EDIF_TOK_INTERFIGUREGROUPSPACING = 407, + EDIF_TOK_INTERSECTION = 408, + EDIF_TOK_INTRAFIGUREGROUPSPACING = 409, + EDIF_TOK_INVERSE = 410, + EDIF_TOK_ISOLATED = 411, + EDIF_TOK_JOINED = 412, + EDIF_TOK_JUSTIFY = 413, + EDIF_TOK_KEYWORDDISPLAY = 414, + EDIF_TOK_KEYWORDLEVEL = 415, + EDIF_TOK_KEYWORDMAP = 416, + EDIF_TOK_LESSTHAN = 417, + EDIF_TOK_LIBRARY = 418, + EDIF_TOK_LIBRARYREF = 419, + EDIF_TOK_LISTOFNETS = 420, + EDIF_TOK_LISTOFPORTS = 421, + EDIF_TOK_LOADDELAY = 422, + EDIF_TOK_LOGICASSIGN = 423, + EDIF_TOK_LOGICINPUT = 424, + EDIF_TOK_LOGICLIST = 425, + EDIF_TOK_LOGICMAPINPUT = 426, + EDIF_TOK_LOGICMAPOUTPUT = 427, + EDIF_TOK_LOGICONEOF = 428, + EDIF_TOK_LOGICOUTPUT = 429, + EDIF_TOK_LOGICPORT = 430, + EDIF_TOK_LOGICREF = 431, + EDIF_TOK_LOGICVALUE = 432, + EDIF_TOK_LOGICWAVEFORM = 433, + EDIF_TOK_MAINTAIN = 434, + EDIF_TOK_MATCH = 435, + EDIF_TOK_MEMBER = 436, + EDIF_TOK_MINOMAX = 437, + EDIF_TOK_MINOMAXDISPLAY = 438, + EDIF_TOK_MNM = 439, + EDIF_TOK_MULTIPLEVALUESET = 440, + EDIF_TOK_MUSTJOIN = 441, + EDIF_TOK_NAME = 442, + EDIF_TOK_NET = 443, + EDIF_TOK_NETBACKANNOTATE = 444, + EDIF_TOK_NETBUNDLE = 445, + EDIF_TOK_NETDELAY = 446, + EDIF_TOK_NETGROUP = 447, + EDIF_TOK_NETMAP = 448, + EDIF_TOK_NETREF = 449, + EDIF_TOK_NOCHANGE = 450, + EDIF_TOK_NONPERMUTABLE = 451, + EDIF_TOK_NOTALLOWED = 452, + EDIF_TOK_NOTCHSPACING = 453, + EDIF_TOK_NUMBER = 454, + EDIF_TOK_NUMBERDEFINITION = 455, + EDIF_TOK_NUMBERDISPLAY = 456, + EDIF_TOK_OFFPAGECONNECTOR = 457, + EDIF_TOK_OFFSETEVENT = 458, + EDIF_TOK_OPENSHAPE = 459, + EDIF_TOK_ORIENTATION = 460, + EDIF_TOK_ORIGIN = 461, + EDIF_TOK_OVERHANGDISTANCE = 462, + EDIF_TOK_OVERLAPDISTANCE = 463, + EDIF_TOK_OVERSIZE = 464, + EDIF_TOK_OWNER = 465, + EDIF_TOK_PAGE = 466, + EDIF_TOK_PAGESIZE = 467, + EDIF_TOK_PARAMETER = 468, + EDIF_TOK_PARAMETERASSIGN = 469, + EDIF_TOK_PARAMETERDISPLAY = 470, + EDIF_TOK_PATH = 471, + EDIF_TOK_PATHDELAY = 472, + EDIF_TOK_PATHWIDTH = 473, + EDIF_TOK_PERMUTABLE = 474, + EDIF_TOK_PHYSICALDESIGNRULE = 475, + EDIF_TOK_PLUG = 476, + EDIF_TOK_POINT = 477, + EDIF_TOK_POINTDISPLAY = 478, + EDIF_TOK_POINTLIST = 479, + EDIF_TOK_POLYGON = 480, + EDIF_TOK_PORT = 481, + EDIF_TOK_PORTBACKANNOTATE = 482, + EDIF_TOK_PORTBUNDLE = 483, + EDIF_TOK_PORTDELAY = 484, + EDIF_TOK_PORTGROUP = 485, + EDIF_TOK_PORTIMPLEMENTATION = 486, + EDIF_TOK_PORTINSTANCE = 487, + EDIF_TOK_PORTLIST = 488, + EDIF_TOK_PORTLISTALIAS = 489, + EDIF_TOK_PORTMAP = 490, + EDIF_TOK_PORTREF = 491, + EDIF_TOK_PROGRAM = 492, + EDIF_TOK_PROPERTY = 493, + EDIF_TOK_PROPERTYDISPLAY = 494, + EDIF_TOK_PROTECTIONFRAME = 495, + EDIF_TOK_PT = 496, + EDIF_TOK_RANGEVECTOR = 497, + EDIF_TOK_RECTANGLE = 498, + EDIF_TOK_RECTANGLESIZE = 499, + EDIF_TOK_RENAME = 500, + EDIF_TOK_RESOLVES = 501, + EDIF_TOK_SCALE = 502, + EDIF_TOK_SCALEX = 503, + EDIF_TOK_SCALEY = 504, + EDIF_TOK_SECTION = 505, + EDIF_TOK_SHAPE = 506, + EDIF_TOK_SIMULATE = 507, + EDIF_TOK_SIMULATIONINFO = 508, + EDIF_TOK_SINGLEVALUESET = 509, + EDIF_TOK_SITE = 510, + EDIF_TOK_SOCKET = 511, + EDIF_TOK_SOCKETSET = 512, + EDIF_TOK_STATUS = 513, + EDIF_TOK_STEADY = 514, + EDIF_TOK_STRING = 515, + EDIF_TOK_STRINGDISPLAY = 516, + EDIF_TOK_STRONG = 517, + EDIF_TOK_SYMBOL = 518, + EDIF_TOK_SYMMETRY = 519, + EDIF_TOK_TABLE = 520, + EDIF_TOK_TABLEDEFAULT = 521, + EDIF_TOK_TECHNOLOGY = 522, + EDIF_TOK_TEXTHEIGHT = 523, + EDIF_TOK_TIMEINTERVAL = 524, + EDIF_TOK_TIMESTAMP = 525, + EDIF_TOK_TIMING = 526, + EDIF_TOK_TRANSFORM = 527, + EDIF_TOK_TRANSITION = 528, + EDIF_TOK_TRIGGER = 529, + EDIF_TOK_TRUE = 530, + EDIF_TOK_UNCONSTRAINED = 531, + EDIF_TOK_UNDEFINED = 532, + EDIF_TOK_UNION = 533, + EDIF_TOK_UNIT = 534, + EDIF_TOK_UNUSED = 535, + EDIF_TOK_USERDATA = 536, + EDIF_TOK_VERSION = 537, + EDIF_TOK_VIEW = 538, + EDIF_TOK_VIEWLIST = 539, + EDIF_TOK_VIEWMAP = 540, + EDIF_TOK_VIEWREF = 541, + EDIF_TOK_VIEWTYPE = 542, + EDIF_TOK_VISIBLE = 543, + EDIF_TOK_VOLTAGEMAP = 544, + EDIF_TOK_WAVEVALUE = 545, + EDIF_TOK_WEAK = 546, + EDIF_TOK_WEAKJOINED = 547, + EDIF_TOK_WHEN = 548, + EDIF_TOK_WRITTEN = 549 + }; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 196 "edif.y" /* yacc.c:352 */ + + char* s; + pair_list* pl; + str_pair* ps; + +#line 615 "edif.c" /* yacc.c:352 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE ediflval; + +int edifparse (void); + +#endif /* !YY_EDIF_EDIF_H_INCLUDED */ + + + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 11 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 2619 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 296 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 472 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 1129 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 1626 + +#define YYUNDEFTOK 2 +#define YYMAXUTOK 549 + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_uint16 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 295, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294 +}; + +#if YYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 508, 508, 511, 514, 515, 516, 517, 518, 519, + 520, 523, 526, 529, 533, 536, 537, 540, 543, 544, + 545, 546, 547, 548, 551, 554, 555, 558, 561, 562, + 563, 564, 565, 568, 571, 574, 575, 578, 581, 584, + 585, 586, 587, 588, 591, 594, 597, 600, 603, 606, + 609, 610, 611, 614, 617, 618, 621, 622, 625, 628, + 629, 630, 631, 634, 637, 638, 641, 644, 645, 648, + 651, 654, 657, 660, 661, 662, 663, 664, 665, 666, + 669, 672, 675, 676, 679, 682, 685, 686, 687, 690, + 693, 694, 695, 698, 699, 700, 703, 706, 707, 710, + 713, 716, 717, 720, 723, 724, 725, 726, 727, 728, + 729, 730, 733, 736, 739, 740, 741, 742, 743, 744, + 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, + 755, 756, 759, 762, 763, 766, 769, 770, 771, 774, + 777, 778, 781, 784, 787, 788, 789, 792, 795, 796, + 799, 802, 803, 806, 809, 810, 813, 816, 817, 820, + 823, 824, 827, 830, 831, 834, 837, 838, 841, 844, + 845, 848, 851, 852, 853, 856, 859, 860, 861, 862, + 863, 866, 869, 870, 873, 876, 879, 880, 881, 882, + 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, + 893, 896, 899, 900, 901, 902, 905, 908, 909, 910, + 913, 916, 917, 920, 921, 924, 925, 928, 929, 932, + 935, 936, 939, 942, 943, 946, 949, 953, 954, 955, + 956, 959, 962, 963, 964, 967, 971, 972, 973, 976, + 977, 978, 979, 982, 983, 984, 987, 990, 991, 992, + 993, 994, 995, 996, 999, 1002, 1005, 1006, 1007, 1008, + 1009, 1012, 1015, 1018, 1021, 1022, 1023, 1024, 1025, 1026, + 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1037, 1040, + 1043, 1046, 1047, 1048, 1051, 1054, 1055, 1056, 1057, 1058, + 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1069, 1072, + 1073, 1076, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, + 1087, 1088, 1089, 1092, 1095, 1096, 1097, 1098, 1101, 1102, + 1103, 1104, 1105, 1108, 1111, 1112, 1113, 1114, 1117, 1120, + 1121, 1122, 1123, 1126, 1129, 1132, 1133, 1136, 1137, 1138, + 1139, 1142, 1145, 1146, 1149, 1152, 1153, 1154, 1155, 1156, + 1159, 1162, 1165, 1168, 1171, 1174, 1175, 1178, 1181, 1184, + 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1196, + 1199, 1200, 1201, 1204, 1207, 1208, 1209, 1210, 1211, 1214, + 1217, 1218, 1221, 1224, 1225, 1226, 1227, 1228, 1231, 1232, + 1235, 1236, 1239, 1242, 1243, 1246, 1249, 1250, 1251, 1252, + 1255, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, + 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1277, 1281, + 1282, 1283, 1284, 1287, 1290, 1291, 1292, 1293, 1296, 1299, + 1300, 1301, 1302, 1305, 1308, 1309, 1312, 1315, 1318, 1319, + 1320, 1321, 1324, 1327, 1328, 1329, 1330, 1331, 1332, 1333, + 1334, 1335, 1338, 1341, 1342, 1345, 1348, 1351, 1352, 1355, + 1358, 1361, 1364, 1367, 1370, 1373, 1374, 1375, 1376, 1377, + 1380, 1383, 1386, 1387, 1390, 1393, 1394, 1395, 1398, 1401, + 1402, 1405, 1408, 1409, 1412, 1413, 1414, 1417, 1418, 1419, + 1422, 1425, 1426, 1427, 1428, 1431, 1434, 1435, 1436, 1437, + 1440, 1443, 1444, 1447, 1450, 1451, 1454, 1457, 1460, 1463, + 1464, 1465, 1468, 1471, 1472, 1473, 1474, 1477, 1480, 1481, + 1482, 1483, 1486, 1489, 1490, 1493, 1496, 1497, 1498, 1499, + 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, + 1510, 1513, 1516, 1517, 1518, 1519, 1520, 1523, 1526, 1527, + 1530, 1531, 1532, 1535, 1538, 1539, 1540, 1543, 1544, 1545, + 1548, 1551, 1552, 1555, 1558, 1559, 1560, 1561, 1564, 1567, + 1568, 1571, 1572, 1575, 1578, 1579, 1580, 1583, 1586, 1587, + 1590, 1593, 1594, 1595, 1596, 1597, 1600, 1603, 1604, 1607, + 1608, 1609, 1612, 1613, 1616, 1619, 1620, 1621, 1622, 1623, + 1624, 1625, 1626, 1627, 1628, 1631, 1634, 1635, 1636, 1637, + 1638, 1641, 1644, 1645, 1646, 1647, 1648, 1649, 1652, 1655, + 1656, 1657, 1660, 1663, 1664, 1665, 1668, 1671, 1672, 1673, + 1674, 1675, 1678, 1679, 1683, 1684, 1687, 1690, 1691, 1692, + 1693, 1696, 1699, 1702, 1703, 1704, 1707, 1710, 1711, 1712, + 1715, 1718, 1719, 1720, 1721, 1724, 1727, 1728, 1729, 1730, + 1733, 1736, 1737, 1740, 1743, 1744, 1745, 1746, 1749, 1752, + 1753, 1754, 1755, 1756, 1759, 1762, 1765, 1766, 1769, 1772, + 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1782, 1785, 1789, + 1790, 1791, 1792, 1795, 1799, 1800, 1801, 1802, 1805, 1808, + 1809, 1812, 1815, 1818, 1819, 1820, 1821, 1822, 1823, 1824, + 1825, 1826, 1827, 1830, 1833, 1836, 1837, 1840, 1843, 1844, + 1847, 1850, 1853, 1854, 1857, 1860, 1861, 1864, 1867, 1870, + 1871, 1872, 1873, 1876, 1879, 1880, 1883, 1886, 1887, 1888, + 1889, 1892, 1895, 1896, 1899, 1902, 1903, 1906, 1909, 1912, + 1913, 1916, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, + 1927, 1928, 1929, 1930, 1931, 1934, 1937, 1938, 1939, 1940, + 1941, 1942, 1943, 1944, 1945, 1946, 1949, 1952, 1953, 1954, + 1955, 1958, 1961, 1962, 1963, 1964, 1967, 1970, 1971, 1972, + 1975, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, + 1987, 1988, 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2012, 2013, 2014, + 2017, 2020, 2023, 2024, 2025, 2026, 2027, 2030, 2031, 2034, + 2035, 2038, 2053, 2054, 2055, 2056, 2059, 2062, 2063, 2066, + 2069, 2070, 2073, 2076, 2077, 2078, 2079, 2080, 2083, 2086, + 2089, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, + 2101, 2102, 2103, 2106, 2107, 2108, 2109, 2110, 2111, 2114, + 2117, 2118, 2119, 2122, 2125, 2126, 2129, 2132, 2133, 2134, + 2135, 2138, 2142, 2143, 2146, 2147, 2150, 2153, 2154, 2157, + 2160, 2163, 2164, 2167, 2170, 2173, 2176, 2177, 2178, 2179, + 2182, 2185, 2186, 2189, 2192, 2195, 2196, 2197, 2198, 2199, + 2200, 2203, 2206, 2207, 2208, 2209, 2212, 2215, 2216, 2219, + 2222, 2223, 2226, 2229, 2230, 2233, 2236, 2237, 2240, 2243, + 2244, 2245, 2246, 2249, 2252, 2253, 2254, 2257, 2258, 2259, + 2262, 2265, 2268, 2269, 2270, 2271, 2274, 2275, 2278, 2281, + 2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, + 2294, 2295, 2296, 2297, 2300, 2303, 2304, 2307, 2310, 2311, + 2312, 2315, 2318, 2319, 2320, 2321, 2324, 2325, 2326, 2329, + 2332, 2333, 2334, 2335, 2336, 2337, 2338, 2341, 2344, 2347, + 2348, 2351, 2352, 2353, 2356, 2360, 2363, 2364, 2365, 2366, + 2367, 2370, 2374, 2375, 2378, 2379, 2382, 2383, 2386, 2387, + 2390, 2391, 2394, 2397, 2398, 2399, 2402, 2405, 2406, 2407, + 2408, 2411, 2414, 2415, 2416, 2417, 2418, 2419, 2422, 2425, + 2428, 2431, 2432, 2433, 2434, 2437, 2440, 2441, 2442, 2443, + 2444, 2445, 2446, 2447, 2448, 2449, 2450, 2451, 2452, 2453, + 2454, 2455, 2458, 2461, 2464, 2465, 2466, 2467, 2468, 2471, + 2472, 2475, 2476, 2479, 2482, 2485, 2486, 2487, 2488, 2489, + 2490, 2493, 2496, 2497, 2498, 2501, 2504, 2505, 2506, 2507, + 2508, 2509, 2510, 2511, 2512, 2515, 2518, 2521, 2524, 2525, + 2528, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539, + 2540, 2543, 2546, 2549, 2552, 2555, 2558, 2559, 2560, 2561, + 2564, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2576, 2579, + 2580, 2581, 2582, 2583, 2584, 2585, 2588, 2591, 2594, 2597 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "EDIF_TOK_IDENT", "EDIF_TOK_INT", + "EDIF_TOK_KEYWORD", "EDIF_TOK_STR", "EDIF_TOK_ANGLE", + "EDIF_TOK_BEHAVIOR", "EDIF_TOK_CALCULATED", "EDIF_TOK_CAPACITANCE", + "EDIF_TOK_CENTERCENTER", "EDIF_TOK_CENTERLEFT", "EDIF_TOK_CENTERRIGHT", + "EDIF_TOK_CHARGE", "EDIF_TOK_CONDUCTANCE", "EDIF_TOK_CURRENT", + "EDIF_TOK_DISTANCE", "EDIF_TOK_DOCUMENT", "EDIF_TOK_ENERGY", + "EDIF_TOK_EXTEND", "EDIF_TOK_FLUX", "EDIF_TOK_FREQUENCY", + "EDIF_TOK_GENERIC", "EDIF_TOK_GRAPHIC", "EDIF_TOK_INDUCTANCE", + "EDIF_TOK_INOUT", "EDIF_TOK_INPUT", "EDIF_TOK_LOGICMODEL", + "EDIF_TOK_LOWERCENTER", "EDIF_TOK_LOWERLEFT", "EDIF_TOK_LOWERRIGHT", + "EDIF_TOK_MASKLAYOUT", "EDIF_TOK_MASS", "EDIF_TOK_MEASURED", + "EDIF_TOK_MX", "EDIF_TOK_MXR90", "EDIF_TOK_MY", "EDIF_TOK_MYR90", + "EDIF_TOK_NETLIST", "EDIF_TOK_OUTPUT", "EDIF_TOK_PCBLAYOUT", + "EDIF_TOK_POWER", "EDIF_TOK_R0", "EDIF_TOK_R180", "EDIF_TOK_R270", + "EDIF_TOK_R90", "EDIF_TOK_REQUIRED", "EDIF_TOK_RESISTANCE", + "EDIF_TOK_RIPPER", "EDIF_TOK_ROUND", "EDIF_TOK_SCHEMATIC", + "EDIF_TOK_STRANGER", "EDIF_TOK_SYMBOLIC", "EDIF_TOK_TEMPERATURE", + "EDIF_TOK_TIE", "EDIF_TOK_TIME", "EDIF_TOK_TRUNCATE", + "EDIF_TOK_UPPERCENTER", "EDIF_TOK_UPPERLEFT", "EDIF_TOK_UPPERRIGHT", + "EDIF_TOK_VOLTAGE", "EDIF_TOK_ACLOAD", "EDIF_TOK_AFTER", + "EDIF_TOK_ANNOTATE", "EDIF_TOK_APPLY", "EDIF_TOK_ARC", "EDIF_TOK_ARRAY", + "EDIF_TOK_ARRAYMACRO", "EDIF_TOK_ARRAYRELATEDINFO", "EDIF_TOK_ARRAYSITE", + "EDIF_TOK_ATLEAST", "EDIF_TOK_ATMOST", "EDIF_TOK_AUTHOR", + "EDIF_TOK_BASEARRAY", "EDIF_TOK_BECOMES", "EDIF_TOK_BETWEEN", + "EDIF_TOK_BOOLEAN", "EDIF_TOK_BOOLEANDISPLAY", "EDIF_TOK_BOOLEANMAP", + "EDIF_TOK_BORDERPATTERN", "EDIF_TOK_BORDERWIDTH", "EDIF_TOK_BOUNDINGBOX", + "EDIF_TOK_CELL", "EDIF_TOK_CELLREF", "EDIF_TOK_CELLTYPE", + "EDIF_TOK_CHANGE", "EDIF_TOK_CIRCLE", "EDIF_TOK_COLOR", + "EDIF_TOK_COMMENT", "EDIF_TOK_COMMENTGRAPHICS", "EDIF_TOK_COMPOUND", + "EDIF_TOK_CONNECTLOCATION", "EDIF_TOK_CONTENTS", "EDIF_TOK_CORNERTYPE", + "EDIF_TOK_CRITICALITY", "EDIF_TOK_CURRENTMAP", "EDIF_TOK_CURVE", + "EDIF_TOK_CYCLE", "EDIF_TOK_DATAORIGIN", "EDIF_TOK_DCFANINLOAD", + "EDIF_TOK_DCFANOUTLOAD", "EDIF_TOK_DCMAXFANIN", "EDIF_TOK_DCMAXFANOUT", + "EDIF_TOK_DELAY", "EDIF_TOK_DELTA", "EDIF_TOK_DERIVATION", + "EDIF_TOK_DESIGN", "EDIF_TOK_DESIGNATOR", "EDIF_TOK_DIFFERENCE", + "EDIF_TOK_DIRECTION", "EDIF_TOK_DISPLAY", "EDIF_TOK_DOMINATES", + "EDIF_TOK_DOT", "EDIF_TOK_DURATION", "EDIF_TOK_E", "EDIF_TOK_EDIF", + "EDIF_TOK_EDIFLEVEL", "EDIF_TOK_EDIFVERSION", + "EDIF_TOK_ENCLOSUREDISTANCE", "EDIF_TOK_ENDTYPE", "EDIF_TOK_ENTRY", + "EDIF_TOK_EVENT", "EDIF_TOK_EXACTLY", "EDIF_TOK_EXTERNAL", + "EDIF_TOK_FABRICATE", "EDIF_TOK_FALSE", "EDIF_TOK_FIGURE", + "EDIF_TOK_FIGUREAREA", "EDIF_TOK_FIGUREGROUP", + "EDIF_TOK_FIGUREGROUPOBJECT", "EDIF_TOK_FIGUREGROUPOVERRIDE", + "EDIF_TOK_FIGUREGROUPREF", "EDIF_TOK_FIGUREPERIMETER", + "EDIF_TOK_FIGUREWIDTH", "EDIF_TOK_FILLPATTERN", "EDIF_TOK_FOLLOW", + "EDIF_TOK_FORBIDDENEVENT", "EDIF_TOK_GLOBALPORTREF", + "EDIF_TOK_GREATERTHAN", "EDIF_TOK_GRIDMAP", "EDIF_TOK_IGNORE", + "EDIF_TOK_INCLUDEFIGUREGROUP", "EDIF_TOK_INITIAL", "EDIF_TOK_INSTANCE", + "EDIF_TOK_INSTANCEBACKANNOTATE", "EDIF_TOK_INSTANCEGROUP", + "EDIF_TOK_INSTANCEMAP", "EDIF_TOK_INSTANCEREF", "EDIF_TOK_INTEGER", + "EDIF_TOK_INTEGERDISPLAY", "EDIF_TOK_INTERFACE", + "EDIF_TOK_INTERFIGUREGROUPSPACING", "EDIF_TOK_INTERSECTION", + "EDIF_TOK_INTRAFIGUREGROUPSPACING", "EDIF_TOK_INVERSE", + "EDIF_TOK_ISOLATED", "EDIF_TOK_JOINED", "EDIF_TOK_JUSTIFY", + "EDIF_TOK_KEYWORDDISPLAY", "EDIF_TOK_KEYWORDLEVEL", + "EDIF_TOK_KEYWORDMAP", "EDIF_TOK_LESSTHAN", "EDIF_TOK_LIBRARY", + "EDIF_TOK_LIBRARYREF", "EDIF_TOK_LISTOFNETS", "EDIF_TOK_LISTOFPORTS", + "EDIF_TOK_LOADDELAY", "EDIF_TOK_LOGICASSIGN", "EDIF_TOK_LOGICINPUT", + "EDIF_TOK_LOGICLIST", "EDIF_TOK_LOGICMAPINPUT", + "EDIF_TOK_LOGICMAPOUTPUT", "EDIF_TOK_LOGICONEOF", "EDIF_TOK_LOGICOUTPUT", + "EDIF_TOK_LOGICPORT", "EDIF_TOK_LOGICREF", "EDIF_TOK_LOGICVALUE", + "EDIF_TOK_LOGICWAVEFORM", "EDIF_TOK_MAINTAIN", "EDIF_TOK_MATCH", + "EDIF_TOK_MEMBER", "EDIF_TOK_MINOMAX", "EDIF_TOK_MINOMAXDISPLAY", + "EDIF_TOK_MNM", "EDIF_TOK_MULTIPLEVALUESET", "EDIF_TOK_MUSTJOIN", + "EDIF_TOK_NAME", "EDIF_TOK_NET", "EDIF_TOK_NETBACKANNOTATE", + "EDIF_TOK_NETBUNDLE", "EDIF_TOK_NETDELAY", "EDIF_TOK_NETGROUP", + "EDIF_TOK_NETMAP", "EDIF_TOK_NETREF", "EDIF_TOK_NOCHANGE", + "EDIF_TOK_NONPERMUTABLE", "EDIF_TOK_NOTALLOWED", "EDIF_TOK_NOTCHSPACING", + "EDIF_TOK_NUMBER", "EDIF_TOK_NUMBERDEFINITION", "EDIF_TOK_NUMBERDISPLAY", + "EDIF_TOK_OFFPAGECONNECTOR", "EDIF_TOK_OFFSETEVENT", + "EDIF_TOK_OPENSHAPE", "EDIF_TOK_ORIENTATION", "EDIF_TOK_ORIGIN", + "EDIF_TOK_OVERHANGDISTANCE", "EDIF_TOK_OVERLAPDISTANCE", + "EDIF_TOK_OVERSIZE", "EDIF_TOK_OWNER", "EDIF_TOK_PAGE", + "EDIF_TOK_PAGESIZE", "EDIF_TOK_PARAMETER", "EDIF_TOK_PARAMETERASSIGN", + "EDIF_TOK_PARAMETERDISPLAY", "EDIF_TOK_PATH", "EDIF_TOK_PATHDELAY", + "EDIF_TOK_PATHWIDTH", "EDIF_TOK_PERMUTABLE", + "EDIF_TOK_PHYSICALDESIGNRULE", "EDIF_TOK_PLUG", "EDIF_TOK_POINT", + "EDIF_TOK_POINTDISPLAY", "EDIF_TOK_POINTLIST", "EDIF_TOK_POLYGON", + "EDIF_TOK_PORT", "EDIF_TOK_PORTBACKANNOTATE", "EDIF_TOK_PORTBUNDLE", + "EDIF_TOK_PORTDELAY", "EDIF_TOK_PORTGROUP", + "EDIF_TOK_PORTIMPLEMENTATION", "EDIF_TOK_PORTINSTANCE", + "EDIF_TOK_PORTLIST", "EDIF_TOK_PORTLISTALIAS", "EDIF_TOK_PORTMAP", + "EDIF_TOK_PORTREF", "EDIF_TOK_PROGRAM", "EDIF_TOK_PROPERTY", + "EDIF_TOK_PROPERTYDISPLAY", "EDIF_TOK_PROTECTIONFRAME", "EDIF_TOK_PT", + "EDIF_TOK_RANGEVECTOR", "EDIF_TOK_RECTANGLE", "EDIF_TOK_RECTANGLESIZE", + "EDIF_TOK_RENAME", "EDIF_TOK_RESOLVES", "EDIF_TOK_SCALE", + "EDIF_TOK_SCALEX", "EDIF_TOK_SCALEY", "EDIF_TOK_SECTION", + "EDIF_TOK_SHAPE", "EDIF_TOK_SIMULATE", "EDIF_TOK_SIMULATIONINFO", + "EDIF_TOK_SINGLEVALUESET", "EDIF_TOK_SITE", "EDIF_TOK_SOCKET", + "EDIF_TOK_SOCKETSET", "EDIF_TOK_STATUS", "EDIF_TOK_STEADY", + "EDIF_TOK_STRING", "EDIF_TOK_STRINGDISPLAY", "EDIF_TOK_STRONG", + "EDIF_TOK_SYMBOL", "EDIF_TOK_SYMMETRY", "EDIF_TOK_TABLE", + "EDIF_TOK_TABLEDEFAULT", "EDIF_TOK_TECHNOLOGY", "EDIF_TOK_TEXTHEIGHT", + "EDIF_TOK_TIMEINTERVAL", "EDIF_TOK_TIMESTAMP", "EDIF_TOK_TIMING", + "EDIF_TOK_TRANSFORM", "EDIF_TOK_TRANSITION", "EDIF_TOK_TRIGGER", + "EDIF_TOK_TRUE", "EDIF_TOK_UNCONSTRAINED", "EDIF_TOK_UNDEFINED", + "EDIF_TOK_UNION", "EDIF_TOK_UNIT", "EDIF_TOK_UNUSED", + "EDIF_TOK_USERDATA", "EDIF_TOK_VERSION", "EDIF_TOK_VIEW", + "EDIF_TOK_VIEWLIST", "EDIF_TOK_VIEWMAP", "EDIF_TOK_VIEWREF", + "EDIF_TOK_VIEWTYPE", "EDIF_TOK_VISIBLE", "EDIF_TOK_VOLTAGEMAP", + "EDIF_TOK_WAVEVALUE", "EDIF_TOK_WEAK", "EDIF_TOK_WEAKJOINED", + "EDIF_TOK_WHEN", "EDIF_TOK_WRITTEN", "')'", "$accept", "PopC", "Edif", + "_Edif", "EdifFileName", "EdifLevel", "EdifVersion", "AcLoad", "_AcLoad", + "After", "_After", "Annotate", "_Annotate", "Apply", "_Apply", "Arc", + "Array", "_Array", "ArrayMacro", "ArrayRelInfo", "_ArrayRelInfo", + "ArraySite", "AtLeast", "AtMost", "Author", "BaseArray", "Becomes", + "_Becomes", "Between", "__Between", "_Between", "Boolean", "_Boolean", + "BooleanDisp", "_BooleanDisp", "BooleanMap", "BooleanValue", "BorderPat", + "BorderWidth", "BoundBox", "Cell", "_Cell", "CellNameDef", "CellRef", + "_CellRef", "CellNameRef", "CellType", "_CellType", "Change", "__Change", + "_Change", "Circle", "_Circle", "Color", "Comment", "_Comment", + "CommGraph", "_CommGraph", "Compound", "Contents", "_Contents", + "ConnectLoc", "_ConnectLoc", "CornerType", "_CornerType", "Criticality", + "_Criticality", "CurrentMap", "Curve", "_Curve", "Cycle", "_Cycle", + "DataOrigin", "_DataOrigin", "DcFanInLoad", "_DcFanInLoad", + "DcFanOutLoad", "_DcFanOutLoad", "DcMaxFanIn", "_DcMaxFanIn", + "DcMaxFanOut", "_DcMaxFanOut", "Delay", "_Delay", "Delta", "_Delta", + "Derivation", "_Derivation", "Design", "_Design", "Designator", + "_Designator", "DesignNameDef", "DesignRule", "_DesignRule", + "Difference", "_Difference", "Direction", "_Direction", "Display", + "_Display", "_DisplayJust", "_DisplayOrien", "_DisplayOrg", "Dominates", + "_Dominates", "Dot", "_Dot", "Duration", "EncloseDist", "_EncloseDist", + "EndType", "_EndType", "Entry", "___Entry", "__Entry", "_Entry", "Event", + "_Event", "Exactly", "External", "_External", "Fabricate", "False", + "FigGrp", "_FigGrp", "FigGrpNameDef", "FigGrpNameRef", "FigGrpObj", + "_FigGrpObj", "FigGrpOver", "_FigGrpOver", "FigGrpRef", "_FigGrpRef", + "Figure", "_Figure", "FigureArea", "_FigureArea", "FigureOp", + "FigurePerim", "_FigurePerim", "FigureWidth", "_FigureWidth", + "FillPattern", "Follow", "__Follow", "_Follow", "Forbidden", + "_Forbidden", "Form", "_Form", "GlobPortRef", "GreaterThan", "GridMap", + "Ignore", "IncFigGrp", "_IncFigGrp", "Initial", "Instance", "_Instance", + "InstanceRef", "_InstanceRef", "InstBackAn", "_InstBackAn", "InstGroup", + "_InstGroup", "InstMap", "_InstMap", "InstNameDef", "InstNameRef", + "IntDisplay", "_IntDisplay", "Integer", "_Integer", "Interface", + "_Interface", "InterFigGrp", "_InterFigGrp", "Intersection", + "_Intersection", "IntraFigGrp", "_IntraFigGrp", "Inverse", "_Inverse", + "Isolated", "Joined", "_Joined", "Justify", "_Justify", "KeywordDisp", + "_KeywordDisp", "KeywordLevel", "KeywordMap", "_KeywordMap", + "KeywordName", "LayerNameDef", "LessThan", "LibNameDef", "LibNameRef", + "Library", "_Library", "LibraryRef", "ListOfNets", "_ListOfNets", + "ListOfPorts", "_ListOfPorts", "LoadDelay", "_LoadDelay", "LogicAssn", + "___LogicAssn", "__LogicAssn", "_LogicAssn", "LogicIn", "_LogicIn", + "LogicList", "_LogicList", "LogicMapIn", "_LogicMapIn", "LogicMapOut", + "_LogicMapOut", "LogicNameDef", "LogicNameRef", "LogicOneOf", + "_LogicOneOf", "LogicOut", "_LogicOut", "LogicPort", "_LogicPort", + "LogicRef", "_LogicRef", "LogicValue", "_LogicValue", "LogicWave", + "_LogicWave", "Maintain", "__Maintain", "_Maintain", "Match", "__Match", + "_Match", "Member", "_Member", "MiNoMa", "_MiNoMa", "MiNoMaDisp", + "_MiNoMaDisp", "MiNoMaValue", "Mnm", "_Mnm", "MultValSet", "_MultValSet", + "MustJoin", "_MustJoin", "Name", "_Name", "NameDef", "NameRef", "Net", + "_Net", "NetBackAn", "_NetBackAn", "NetBundle", "_NetBundle", "NetDelay", + "_NetDelay", "NetGroup", "_NetGroup", "NetMap", "_NetMap", "NetNameDef", + "NetNameRef", "NetRef", "_NetRef", "NoChange", "NonPermut", "_NonPermut", + "NotAllowed", "_NotAllowed", "NotchSpace", "_NotchSpace", "Number", + "_Number", "NumbDisplay", "_NumbDisplay", "NumberDefn", "_NumberDefn", + "OffPageConn", "_OffPageConn", "OffsetEvent", "OpenShape", "_OpenShape", + "Orientation", "_Orientation", "Origin", "OverhngDist", "_OverhngDist", + "OverlapDist", "_OverlapDist", "Oversize", "_Oversize", "Owner", "Page", + "_Page", "PageSize", "ParamDisp", "_ParamDisp", "Parameter", + "_Parameter", "ParamAssign", "Path", "_Path", "PathDelay", "_PathDelay", + "PathWidth", "Permutable", "_Permutable", "Plug", "_Plug", "Point", + "_Point", "PointDisp", "_PointDisp", "PointList", "_PointList", + "PointValue", "Polygon", "_Polygon", "Port", "_Port", "PortBackAn", + "_PortBackAn", "PortBundle", "_PortBundle", "PortDelay", "_PortDelay", + "PortGroup", "_PortGroup", "PortImpl", "_PortImpl", "PortInst", + "_PortInst", "PortList", "_PortList", "PortListAls", "PortMap", + "_PortMap", "PortNameDef", "PortNameRef", "PortRef", "_PortRef", + "Program", "_Program", "PropDisplay", "_PropDisplay", "Property", + "_Property", "PropNameDef", "PropNameRef", "ProtectFrame", + "_ProtectFrame", "Range", "RangeVector", "_RangeVector", "Rectangle", + "_Rectangle", "RectSize", "_RectSize", "Rename", "__Rename", "_Rename", + "Resolves", "_Resolves", "RuleNameDef", "Scale", "ScaledInt", "ScaleX", + "ScaleY", "Section", "_Section", "Shape", "_Shape", "SimNameDef", + "Simulate", "_Simulate", "SimulInfo", "_SimulInfo", "SingleValSet", + "_SingleValSet", "Site", "_Site", "Socket", "_Socket", "SocketSet", + "_SocketSet", "Status", "_Status", "Steady", "__Steady", "_Steady", + "StrDisplay", "String", "_String", "_StrDisplay", "Strong", "Symbol", + "_Symbol", "Symmetry", "_Symmetry", "Table", "_Table", "TableDeflt", + "__TableDeflt", "_TableDeflt", "Technology", "_Technology", "TextHeight", + "TimeIntval", "__TimeIntval", "_TimeIntval", "TimeStamp", "Timing", + "_Timing", "Transform", "_TransX", "_TransY", "_TransDelta", + "_TransOrien", "_TransOrg", "Transition", "_Transition", "Trigger", + "_Trigger", "True", "TypedValue", "Unconstrained", "Undefined", "Union", + "_Union", "Unit", "_Unit", "Unused", "UserData", "_UserData", + "ValueNameDef", "ValueNameRef", "Version", "View", "_View", "ViewList", + "_ViewList", "ViewMap", "_ViewMap", "ViewNameDef", "ViewNameRef", + "ViewRef", "_ViewRef", "ViewType", "_ViewType", "Visible", "VoltageMap", + "WaveValue", "Weak", "WeakJoined", "_WeakJoined", "When", "_When", + "Written", "_Written", "Ident", "Str", "Int", "Keyword", YY_NULLPTR +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, + 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, + 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, + 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, + 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, + 545, 546, 547, 548, 549, 41 +}; +# endif + +#define YYPACT_NINF -1333 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-1333))) + +#define YYTABLE_NINF -1 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + 41, 152, 149, -1333, 176, 81, 305, -1333, -1333, -1333, + -1333, -1333, 33, -1333, -1333, 59, -1333, 148, 317, 101, + -1333, -1333, -1333, -1333, 437, 150, -1333, -1333, -1333, 148, + 148, 304, 81, 312, -1333, -1333, -1333, -1333, -1333, 33, + -1333, -1333, 148, 150, 316, -1333, -1333, 1508, 1780, 272, + -1333, -1333, -1333, 150, -1333, 148, -1333, 122, 715, 148, + 148, 111, -1333, 997, 1020, 148, 148, 152, 148, 176, + 300, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, 150, 1588, 280, -1333, -1333, 150, -1333, + -1333, 152, 152, 152, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, 148, 150, 148, 111, -1333, 36, -1333, -1333, + -1333, 150, -1333, -1333, -1333, 150, 148, 150, -1333, 1023, + 150, 66, -1333, 150, 150, 150, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, 260, 150, + -1333, -1333, 424, -1333, 317, -1333, 317, 273, 439, -1333, + 148, 111, -1333, -1333, -1333, -1333, 439, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 310, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, 148, 150, -1333, 81, -1333, 441, + 254, 254, 266, -1333, -1333, -1333, -1333, 150, 150, 150, + 150, 416, 49, 115, 91, 801, 77, 437, 2006, -1333, + -1333, -1333, -1333, -1333, 71, 148, -1333, 376, -1333, -1333, + -1333, -1333, -1333, -1333, 343, 445, -1333, 445, -1333, 148, + -1333, 158, -1333, -1333, -1333, -1333, 300, -1333, -1333, -1333, + -1333, 148, -1333, -1333, -1333, -1333, 276, 144, -1333, -1333, + -1333, -1333, -1333, -1333, 111, -1333, -1333, -1333, -1333, 260, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, + -1333, 150, 81, 150, -1333, -1333, -1333, 546, 152, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 148, + 437, 437, 437, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + 33, -1333, 33, -1333, 33, -1333, 150, 150, 144, -1333, + -1333, -1333, 33, -1333, 33, -1333, -1333, -1333, -1333, 150, + -1333, -1333, 132, 152, 152, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, 468, -1333, 148, 150, 306, 306, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 144, -1333, + -1333, -1333, -1333, -1333, 111, 111, -1333, -1333, -1333, -1333, + 81, -1333, 1442, -1333, -1333, 1794, 519, 832, 940, -1333, + 148, -1333, 437, 150, -1333, 150, -1333, 150, 111, 111, + 150, 1196, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, 152, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + 150, 152, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + 148, 150, -1333, -1333, -1333, 150, 321, -1333, 1196, 81, + 1196, 1196, 148, 1196, -1333, -1333, -1333, 150, -1333, -1333, + -1333, -1333, -1333, 461, 461, 461, 461, 461, 461, 461, + 461, 461, 461, 461, -1333, 1198, -1333, -1333, -1333, 322, + 867, 148, -1333, -1333, 150, 1263, -1333, -1333, 376, -1333, + -1333, 1263, -1333, -1333, 150, 1196, -1333, -1333, 1263, -1333, + 342, 461, 1545, 1545, 1545, 461, 1545, -1333, 130, 1545, + 461, 461, -29, 300, 81, 276, -1333, 150, -1333, -1333, + -1333, 81, 276, 81, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 1879, + 444, 466, -1333, 425, -1333, 382, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, + -1333, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 540, + -1333, -1333, -1333, -1333, 150, -1333, -1333, 1545, 111, 111, + 42, 111, 111, 111, 1276, -1333, -1333, -1333, -1333, 130, + -1333, -1333, -1333, -1333, 130, -1333, -1333, 130, -1333, -1333, + 1545, 130, -1333, -1333, -1333, -1333, -1333, 130, -1333, -1333, + 1545, 1545, -1333, -1333, -1333, -1333, 130, 150, 150, -1333, + 150, 63, -1333, 63, 63, 63, 150, 150, 150, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, + -1333, -1333, 186, 529, -1333, 653, 833, 529, 605, -1333, + 171, 529, 581, -1333, 783, -1333, -1333, 150, -1333, 130, + -1333, -1333, 150, 150, -1333, 53, -1333, 150, 150, 150, + -1333, 150, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, 130, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + 130, -1333, -1333, 130, -1333, -1333, -75, 361, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, 990, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, 81, -34, -1333, -1333, 59, 548, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, 442, 460, 548, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 539, + 523, 93, 93, 93, 93, 548, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 543, + -1333, -1333, 108, -1333, 108, 108, -1333, 152, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, 1584, 148, 81, + -1333, 150, -1333, 150, -1333, -1333, 894, -1333, 708, 252, + -1333, -1333, 150, -1333, 150, -1333, -1333, 561, 46, -1333, + -1333, 150, -1333, 150, -1333, -1333, 150, -1333, -1333, 150, + -1333, -1333, 150, -1333, -1333, 150, -1333, -1333, 26, 86, + -1333, 431, 421, 150, -1333, 130, -1333, -1333, 531, 281, + 152, -1333, -1333, 1023, -73, -1333, -1333, 631, -1333, 512, + 762, -1333, -1333, 481, 365, 588, 454, -1333, 76, 104, + 108, 108, 108, 108, 108, 108, 104, 437, 418, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, 51, -1333, -1333, + 424, -1333, -1333, -1333, -1333, -1333, 150, 436, 561, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 523, -1333, + -31, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + 523, -1333, -1333, -31, -1333, -1333, -1333, -1333, 150, 453, + 150, -1333, -1333, -1333, -1333, 529, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, 148, 321, -1333, -1333, + -1333, -1333, -1333, 711, 150, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + 726, 176, 529, 81, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, 620, 108, 152, -1333, + -1333, -1333, -1333, -1333, -1333, 59, 454, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, 260, 150, 691, -1333, -1333, + 751, -85, -1333, -1333, -1333, -115, -1333, 726, -1333, -1333, + -1333, 568, 562, 635, -1333, -1333, 449, 1253, -1333, -1333, + 97, -1333, -1333, -1333, 448, -1333, -1333, -1333, 150, -1333, + 384, -24, -1333, -1333, -24, 150, -1333, -1333, 950, 950, + -1333, -1333, -1333, 523, -1333, -1333, -1333, -1333, -1333, -122, + -1333, -1333, 150, -1333, -1333, 150, 86, 148, 150, -1333, + -77, -1333, -1333, -1333, 150, -1333, -90, -1333, -1333, -1333, + -1333, 33, -1333, -1333, -1333, -1333, 33, -1333, -1333, 33, + -1333, 148, 409, -1333, 530, 111, 150, -1333, -1333, 150, + 260, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + 260, 260, 675, 553, 553, 675, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, 99, -1333, -1333, + -1333, 812, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 679, + -1333, -1333, 946, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 651, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, 34, 276, 104, 104, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, 1014, 671, -1333, -1333, 634, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, + -1333, -1333, -1333, -1333, 950, 150, 453, -1333, -1333, -119, + -1333, -1333, -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, 684, 255, 255, -1333, -1333, -1333, -1333, -1333, 150, + 624, -1333, -1333, -1333, -117, 260, -117, -1333, -1333, -1333, + -117, -1333, -117, -1333, -1333, -117, -1333, -117, 269, -1333, + -1333, -1333, 428, 529, 104, 560, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -98, -1333, -1333, -1333, -1333, + -1333, -1333, 150, -1333, 255, 150, 255, -1333, -1333, -1333, + -1333, 739, -1333, -64, -1333, -1333, 26, -1333, -1333, -31, + -1333, -1333, -1333, -1333, -1333, 111, 111, -1333, -1333, -1333, + 150, 114, 64, -1333, 150, -1333, -127, -1333, -1333, -1333, + -1333, 150, -1333, -52, -1333, -1333, -1333, -52, -1333, -1333, + -1333, -1333, -1333, 150, -1333, -1333, -1333, -1333, -1333, 28, + -1333, -1333, -46, -1333, -1333, -1333, -1333, -1333, -1333, 383, + 890, -1333, -1333, -1333, -1333, -1333, -1333, 1023, 657, -1333, + -1333, 148, -1333, 564, -1333, -1333, -1333, 11, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, 684, -1333, -1333, -1333, -1333, + -1333, -1333, 81, 26, -1333, -1333, -1333, -1333, -1333, 150, + -1333, -1333, -1333, 150, 150, -1333, 150, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, 534, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, 113, -1333, -117, 260, -1333, -1333, -1333, + -1333, -1333, 255, -1333, 890, -1333, -1333, 150, -1333, -1333, + -1333, -1333, 26, 150, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -1333, 148, 148, -1333, 725, + -1333, 150, -1333, -1333, -31, 376, -1333, -1333, 150, -1333, + -1333, -1333, -1333, 577, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, 260, 950, -1333, -1333, -1333, 26, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, 150, -1333, 150, 148, -1333, -1333, + 272, -1333, -1333, -1333, -1333, -1333, 150, -1333, 150, -1333, + 260, -1333, -1333, -1333, 150, -1333, 150, -1333, -1333, -1333, + 150, -46, -1333, 280, -1333, -1333, 150, -1333, -1333, -1333, + -1333, -1333, -1333, 150, -1333, -1333 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint16 yydefact[] = +{ + 0, 0, 0, 1126, 0, 0, 0, 590, 11, 591, + 589, 1, 0, 587, 883, 0, 882, 0, 0, 0, + 2, 586, 588, 1127, 0, 0, 885, 884, 1128, 0, + 0, 0, 0, 213, 211, 212, 593, 279, 592, 0, + 946, 881, 0, 0, 0, 4, 285, 0, 0, 215, + 214, 940, 947, 0, 12, 0, 457, 0, 0, 0, + 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, + 0, 284, 292, 289, 290, 295, 286, 287, 291, 288, + 296, 293, 297, 294, 443, 444, 445, 446, 447, 448, + 449, 450, 451, 0, 0, 217, 216, 13, 0, 456, + 458, 0, 0, 0, 929, 3, 9, 8, 6, 7, + 5, 10, 0, 0, 0, 0, 891, 0, 136, 137, + 138, 0, 232, 233, 234, 0, 0, 0, 848, 0, + 0, 0, 1054, 0, 0, 0, 68, 67, 442, 683, + 686, 684, 685, 679, 681, 682, 680, 0, 0, 0, + 218, 455, 0, 184, 0, 462, 0, 0, 0, 70, + 0, 0, 100, 102, 135, 231, 0, 727, 59, 396, + 564, 656, 737, 942, 1022, 1023, 1024, 1025, 1026, 0, + 1027, 843, 987, 1129, 1053, 1058, 1057, 1056, 1055, 345, + 262, 1021, 1101, 678, 0, 0, 210, 0, 176, 0, + 0, 0, 0, 928, 931, 932, 930, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 842, + 847, 844, 846, 845, 0, 0, 687, 82, 84, 175, + 178, 179, 177, 180, 0, 0, 256, 0, 465, 0, + 1119, 0, 69, 892, 99, 333, 0, 58, 62, 61, + 60, 0, 395, 398, 399, 397, 0, 0, 563, 567, + 566, 565, 571, 572, 0, 655, 659, 658, 657, 0, + 736, 740, 739, 738, 941, 944, 945, 943, 0, 1051, + 1037, 1048, 1049, 1038, 1036, 1046, 1050, 1044, 1045, 1043, + 1047, 1039, 1040, 1041, 1042, 0, 344, 349, 348, 347, + 346, 0, 0, 0, 83, 664, 980, 0, 0, 255, + 258, 259, 257, 260, 464, 467, 468, 466, 469, 0, + 0, 0, 0, 1118, 1120, 1124, 1122, 1121, 1123, 1125, + 0, 64, 0, 393, 0, 569, 0, 0, 0, 574, + 576, 575, 0, 661, 0, 742, 701, 1035, 747, 0, + 463, 81, 0, 0, 0, 186, 912, 979, 985, 984, + 982, 981, 983, 986, 0, 80, 0, 0, 151, 837, + 63, 65, 392, 394, 568, 570, 1028, 1029, 0, 660, + 662, 741, 743, 470, 0, 0, 663, 667, 666, 665, + 0, 460, 0, 264, 278, 0, 0, 0, 0, 73, + 0, 47, 0, 0, 152, 0, 838, 0, 0, 0, + 0, 0, 263, 271, 268, 269, 274, 265, 266, 270, + 277, 267, 275, 272, 276, 273, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 185, 199, 193, + 198, 188, 190, 187, 194, 195, 197, 196, 192, 191, + 189, 200, 0, 911, 914, 913, 915, 88, 87, 86, + 0, 0, 1076, 72, 77, 79, 74, 78, 76, 75, + 0, 0, 150, 836, 573, 0, 0, 261, 0, 0, + 0, 0, 0, 0, 320, 355, 356, 0, 318, 321, + 322, 319, 889, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 526, 0, 506, 85, 1085, 0, + 0, 0, 1063, 352, 0, 0, 202, 203, 299, 424, + 425, 0, 434, 435, 0, 0, 1031, 1032, 0, 354, + 0, 0, 0, 0, 0, 0, 0, 647, 0, 0, + 0, 0, 0, 0, 0, 0, 220, 0, 501, 504, + 887, 0, 0, 0, 525, 529, 539, 530, 528, 533, + 536, 535, 534, 538, 537, 532, 540, 527, 531, 0, + 0, 0, 383, 0, 627, 0, 822, 1075, 1083, 1080, + 1079, 1082, 1081, 1078, 1077, 1084, 0, 890, 201, 204, + 205, 0, 300, 423, 426, 427, 433, 699, 700, 0, + 1030, 1033, 1034, 281, 0, 282, 283, 0, 0, 0, + 0, 0, 0, 0, 917, 866, 865, 868, 867, 0, + 864, 863, 314, 315, 0, 324, 325, 0, 329, 330, + 0, 0, 429, 430, 646, 648, 649, 0, 651, 652, + 0, 0, 578, 870, 878, 877, 0, 0, 0, 507, + 0, 0, 436, 0, 0, 0, 0, 0, 0, 1096, + 1098, 1099, 1097, 1091, 1093, 1092, 1094, 1100, 1095, 0, + 401, 1065, 0, 0, 374, 0, 0, 0, 0, 606, + 0, 0, 0, 766, 0, 994, 298, 0, 280, 0, + 227, 228, 0, 0, 54, 0, 55, 0, 0, 0, + 918, 0, 313, 316, 317, 323, 326, 327, 328, 331, + 332, 0, 419, 420, 428, 431, 432, 650, 653, 654, + 0, 689, 690, 0, 694, 695, 0, 0, 876, 879, + 880, 66, 112, 142, 219, 221, 500, 502, 503, 505, + 886, 888, 948, 1102, 1104, 1090, 0, 114, 1064, 1068, + 1067, 1069, 1066, 1070, 0, 370, 391, 390, 0, 0, + 373, 378, 375, 377, 376, 380, 382, 386, 384, 385, + 387, 635, 634, 637, 0, 0, 605, 610, 608, 607, + 609, 623, 626, 630, 629, 628, 631, 830, 829, 832, + 0, 0, 0, 0, 0, 0, 765, 773, 775, 769, + 770, 771, 772, 767, 768, 774, 787, 821, 825, 824, + 823, 826, 698, 226, 229, 230, 45, 46, 56, 0, + 57, 254, 351, 461, 916, 418, 421, 422, 688, 691, + 692, 693, 696, 697, 577, 579, 869, 871, 872, 0, + 438, 581, 0, 729, 0, 0, 851, 0, 950, 1106, + 400, 406, 416, 414, 408, 409, 407, 411, 402, 403, + 415, 405, 413, 404, 412, 417, 410, 0, 0, 0, + 371, 0, 372, 0, 183, 182, 0, 996, 0, 0, + 639, 638, 0, 640, 0, 141, 140, 0, 0, 834, + 833, 0, 835, 0, 16, 15, 0, 155, 154, 0, + 158, 157, 0, 161, 160, 0, 164, 163, 0, 0, + 53, 0, 0, 0, 41, 0, 40, 39, 0, 0, + 0, 1060, 1059, 0, 0, 828, 827, 0, 752, 0, + 0, 903, 905, 0, 0, 0, 0, 104, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, + 129, 130, 122, 117, 127, 115, 128, 119, 120, 116, + 121, 123, 118, 125, 124, 131, 126, 0, 561, 1086, + 1088, 369, 181, 172, 173, 174, 0, 0, 0, 995, + 999, 998, 997, 1000, 379, 381, 636, 139, 0, 619, + 0, 622, 624, 625, 831, 14, 153, 156, 159, 162, + 0, 782, 783, 0, 786, 788, 789, 734, 0, 923, + 0, 48, 38, 42, 43, 0, 817, 437, 441, 440, + 439, 580, 585, 583, 582, 584, 0, 718, 643, 728, + 732, 731, 730, 0, 0, 751, 761, 763, 757, 758, + 759, 760, 756, 753, 755, 762, 754, 764, 475, 777, + 0, 0, 0, 0, 850, 856, 861, 855, 853, 854, + 858, 859, 852, 857, 860, 862, 0, 0, 0, 904, + 908, 909, 906, 910, 907, 0, 0, 949, 955, 957, + 962, 954, 952, 953, 959, 956, 960, 951, 958, 961, + 963, 1105, 1109, 1108, 1107, 0, 0, 0, 302, 303, + 0, 0, 335, 336, 389, 0, 388, 0, 518, 633, + 632, 0, 0, 0, 669, 703, 0, 0, 792, 791, + 0, 896, 1017, 1111, 0, 560, 562, 1089, 0, 171, + 0, 0, 342, 725, 0, 0, 167, 166, 0, 0, + 618, 621, 620, 0, 480, 479, 781, 785, 784, 0, + 37, 965, 0, 924, 44, 0, 0, 35, 0, 719, + 0, 207, 208, 209, 0, 1052, 0, 776, 779, 778, + 780, 0, 453, 459, 1062, 1061, 0, 715, 849, 0, + 840, 0, 0, 28, 0, 0, 0, 26, 25, 0, + 0, 71, 103, 105, 108, 110, 106, 107, 109, 111, + 0, 0, 0, 0, 0, 0, 301, 304, 311, 305, + 306, 307, 308, 309, 310, 312, 968, 0, 337, 338, + 1072, 0, 360, 359, 517, 520, 519, 521, 595, 0, + 472, 612, 0, 668, 672, 671, 670, 673, 702, 710, + 711, 707, 704, 705, 706, 709, 708, 712, 133, 790, + 801, 796, 793, 794, 795, 798, 797, 799, 800, 895, + 899, 897, 898, 0, 0, 0, 0, 1110, 1112, 1116, + 1113, 1115, 1114, 1117, 1087, 0, 0, 989, 990, 0, + 341, 343, 724, 726, 165, 496, 509, 0, 51, 50, + 52, 1014, 1013, 1015, 0, 0, 0, 733, 735, 0, + 922, 350, 816, 819, 818, 0, 36, 717, 642, 645, + 644, 206, 474, 476, 477, 452, 454, 714, 716, 839, + 841, 148, 0, 0, 27, 31, 29, 30, 32, 0, + 0, 24, 713, 874, 0, 0, 0, 223, 144, 676, + 0, 745, 0, 722, 749, 0, 901, 0, 0, 334, + 339, 340, 0, 0, 0, 1002, 358, 367, 365, 362, + 363, 366, 364, 361, 368, 594, 603, 601, 596, 598, + 600, 599, 597, 602, 604, 0, 611, 616, 614, 613, + 615, 617, 0, 134, 0, 0, 0, 1016, 1018, 1020, + 1019, 0, 18, 0, 482, 483, 550, 548, 549, 0, + 251, 250, 249, 248, 247, 0, 0, 993, 991, 992, + 0, 0, 0, 49, 0, 478, 0, 926, 964, 966, + 34, 0, 149, 0, 491, 493, 492, 0, 513, 515, + 514, 820, 542, 0, 873, 875, 97, 222, 224, 0, + 675, 677, 0, 721, 723, 748, 750, 900, 902, 0, + 0, 967, 969, 970, 1071, 1074, 1073, 0, 0, 804, + 803, 0, 1003, 1004, 471, 473, 132, 93, 92, 90, + 91, 357, 936, 934, 935, 0, 17, 22, 19, 21, + 20, 23, 0, 487, 485, 484, 486, 551, 552, 0, + 246, 253, 252, 0, 0, 988, 0, 495, 499, 497, + 498, 508, 511, 510, 1012, 0, 925, 927, 147, 490, + 494, 512, 516, 0, 1103, 0, 0, 143, 145, 146, + 744, 746, 0, 237, 0, 236, 238, 0, 972, 974, + 973, 975, 976, 0, 802, 812, 814, 808, 809, 810, + 811, 807, 806, 813, 805, 815, 0, 0, 1005, 1006, + 94, 0, 95, 937, 0, 523, 488, 489, 0, 547, + 674, 225, 353, 920, 541, 546, 544, 543, 545, 96, + 98, 0, 0, 556, 554, 555, 243, 239, 241, 240, + 242, 641, 977, 978, 0, 720, 0, 0, 169, 1007, + 1008, 89, 933, 939, 938, 524, 0, 481, 0, 921, + 0, 558, 557, 559, 0, 244, 0, 245, 971, 893, + 0, 0, 1009, 1010, 522, 919, 0, 553, 235, 894, + 168, 170, 1011, 0, 33, 1001 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -1333, -25, -1333, -1333, -1333, 8, -1333, -906, -1333, -1333, + -1333, -265, -1333, -1333, -1333, -1333, 173, -1333, -1333, -1333, + -1333, -1333, 223, 139, -1333, -1333, -996, -1333, -1333, -1333, + -1333, 645, -1333, -1333, -1333, -1333, -168, 470, 473, -285, + 599, -1333, -1333, -91, -1333, -1333, -1333, -1333, -557, -1333, + -1333, -1333, -1333, 504, 1011, -1333, -878, -1333, -1333, -1333, + -1333, -1333, -1333, -310, -1333, -316, -1333, -1333, -291, -1333, + -1333, -1333, -1333, -1333, -902, -1333, -901, -1333, -896, -1333, + -893, -1333, -891, -1333, -1333, -1333, -630, -1333, -1333, -1333, + -666, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -26, + -1333, -1333, -1333, -1333, -1333, -1333, -1333, -1333, -890, -1333, + -1333, 527, -1333, -1333, -1333, -1333, -1333, -284, -1333, -1333, + -1333, -1333, -1333, -1333, 528, -1333, -11, 3, 1663, -1333, + -7, -1333, 1085, -1333, -880, -1333, -1333, -1333, 1301, -1333, + -1333, -1333, -1333, 544, -1043, -1333, -1333, -1333, -1333, 716, + -1333, -1333, 329, -1333, -570, -1333, -1333, -1333, -872, -1333, + 308, -1333, -1333, -1333, -1333, -1333, -1333, -1333, 4, -1333, + 180, -1333, 745, -1333, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -1333, -834, -1333, -1333, -1333, -871, + -1333, -1333, -1333, -1333, -1333, -1333, 263, 858, -1333, -1333, + -1333, -517, -1333, -1333, -1333, -1333, -1202, -181, -428, -1333, + -1333, -1333, -1333, -1333, -1109, -1333, -1333, -1333, -1333, -1333, + -99, -514, -1097, -1333, -1333, -1333, -1333, -1333, -1332, -1333, + -1333, -1333, -1227, -1333, -420, -1333, -1333, -1333, -1333, -1333, + -665, -1333, 769, -1333, -193, -1333, -209, -1333, 90, -1333, + -1333, -1333, -1333, 355, -1333, 903, 128, -1025, -1333, -1333, + -1333, -141, -1333, -242, -1333, -287, -1333, -1333, -1333, 55, + 123, -674, -1333, -502, -1333, -1333, -1333, -1333, -1333, -1333, + 813, -1333, 472, -1333, -1333, -1333, -1333, -1333, -251, -1333, + -1333, -560, -1333, -582, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, -83, 105, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, -1333, 656, -864, -1333, -1333, -1333, 830, -1333, + -1333, -1333, -155, -1333, -210, -1333, -1333, -113, -1333, -1333, + -1333, -105, -1333, -889, -1333, -213, -1333, -803, -1333, -1333, + -1333, -874, -1333, -1333, -1333, -1333, -679, -882, 502, -1333, + -1333, -1333, -699, -1333, 767, -1333, -1333, -1333, -1333, -1333, + 845, 339, -1333, -942, -1333, -1333, -1333, -1333, -1333, -1333, + -1333, -1333, 902, -1333, 141, -1333, -1333, -44, -1333, -1333, + -1333, -1333, 213, -1333, -1333, -1333, 411, -1333, -1333, -1333, + -1333, -1333, -1333, -1333, -189, -1333, -363, -1333, -1333, -214, + 873, -1333, -1333, -1333, -1333, -1333, -195, -1333, -1300, -1333, + -1333, -1333, -1333, 904, -1333, 712, -1333, -1333, -1333, -1333, + -706, -1333, -1248, -1333, -1333, -1333, -1333, -1333, -980, -186, + -1333, -1333, -1333, -912, -1333, -1333, -1333, -1333, -467, -1333, + -1089, 1032, -1333, -1333, -241, 742, -1333, -1333, -235, -1333, + -1333, -1333, -1333, -1333, -770, -1333, -1333, -1333, 727, -1333, + -1333, -1333, 203, -1333, -1333, -1333, -1333, -1333, 1551, 12, + 347, -1333 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 21, 2, 58, 6, 31, 18, 797, 893, 1268, + 1391, 1078, 1186, 1070, 1182, 1518, 925, 1305, 914, 851, + 915, 916, 615, 616, 324, 917, 1141, 1287, 617, 695, + 819, 174, 211, 249, 330, 555, 135, 72, 73, 950, + 310, 398, 364, 198, 303, 227, 399, 460, 1388, 1467, + 1551, 1207, 1515, 74, 75, 117, 952, 1097, 557, 750, + 867, 1252, 1382, 76, 121, 778, 884, 558, 1339, 1439, + 1183, 1421, 326, 403, 799, 896, 800, 899, 801, 902, + 802, 905, 989, 1135, 1589, 1611, 877, 976, 107, 199, + 762, 873, 152, 359, 395, 484, 515, 1043, 1164, 22, + 33, 49, 95, 149, 559, 651, 1209, 1336, 1407, 439, + 689, 77, 125, 1452, 1524, 1576, 1606, 1277, 1399, 618, + 108, 235, 360, 136, 361, 392, 393, 34, 531, 604, + 35, 47, 485, 591, 953, 1100, 441, 619, 486, 442, + 624, 443, 627, 78, 954, 1101, 1217, 981, 1131, 185, + 224, 1018, 620, 388, 1498, 420, 487, 1389, 955, 1221, + 674, 871, 579, 675, 769, 879, 580, 676, 1105, 755, + 253, 332, 175, 212, 671, 746, 444, 711, 488, 521, + 445, 631, 489, 524, 560, 854, 918, 50, 93, 1060, + 1171, 56, 45, 57, 1172, 390, 621, 154, 349, 109, + 237, 304, 1231, 1375, 1049, 1166, 1002, 1143, 1271, 1393, + 1483, 1558, 1326, 1423, 1291, 1411, 561, 653, 562, 654, + 504, 1292, 1293, 1412, 1327, 1427, 956, 1107, 1484, 1596, + 455, 505, 1433, 1513, 1272, 1396, 1489, 1525, 1572, 1604, + 787, 967, 176, 213, 1144, 334, 1145, 262, 338, 644, + 726, 855, 919, 36, 12, 492, 649, 957, 1229, 581, + 678, 958, 1232, 779, 990, 784, 888, 582, 680, 1111, + 773, 679, 882, 1529, 1030, 1160, 446, 538, 447, 637, + 177, 214, 267, 342, 306, 352, 959, 1113, 1278, 1210, + 1340, 96, 147, 150, 448, 720, 449, 723, 490, 599, + 221, 960, 1116, 1085, 1061, 1176, 856, 1158, 1359, 1211, + 1342, 982, 1134, 79, 857, 924, 1008, 1149, 178, 215, + 272, 344, 1343, 1442, 195, 1212, 1345, 858, 927, 583, + 682, 859, 1050, 804, 1003, 809, 909, 961, 1117, 1360, + 1458, 1019, 1156, 1072, 584, 684, 928, 789, 683, 891, + 327, 405, 1063, 1179, 80, 179, 129, 1180, 861, 930, + 622, 645, 727, 1096, 1334, 450, 646, 9, 15, 25, + 564, 655, 493, 389, 263, 1462, 1548, 962, 1120, 1214, + 1347, 932, 862, 933, 362, 396, 623, 701, 1507, 1598, + 1010, 1152, 1298, 1416, 110, 157, 1390, 1475, 1554, 26, + 180, 216, 39, 565, 863, 934, 1153, 1299, 1219, 1348, + 1453, 1532, 1584, 236, 307, 81, 1132, 1279, 1410, 240, + 764, 878, 1363, 1463, 1549, 1590, 1613, 1623, 1142, 1294, + 1123, 1263, 137, 181, 340, 341, 491, 528, 223, 295, + 1046, 82, 131, 923, 1177, 404, 468, 672, 1222, 1352, + 469, 510, 509, 970, 872, 1128, 570, 669, 83, 567, + 1074, 568, 866, 935, 966, 1124, 206, 241, 38, 27, + 116, 189 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_uint16 yytable[] = +{ + 41, 592, 275, 883, 261, 273, 785, 1147, 756, 514, + 232, 1027, 771, 52, 51, 1351, 803, 1001, 54, 892, + 260, 1036, 71, 1148, 1236, 1038, 1039, 1005, 97, 1288, + 648, 1040, 99, 105, 1041, 46, 40, 656, 1044, 658, + 864, 1290, 23, 250, 1138, 1023, 312, 335, 317, 3, + 1058, 1419, 1057, 28, 1082, 28, 1081, 1102, 1059, 345, + 1031, 1093, 1083, 1084, 1118, 23, 3, 3, 138, 3, + 28, 183, 23, 151, 3, 28, 183, 23, 331, 3, + 853, 1270, 417, 23, 3, 1022, 1138, 1133, 159, 3, + 942, 1243, 162, 1486, 1516, 28, 164, 28, 1275, 881, + 165, 1092, 167, 23, 3, 182, 184, 3, 190, 191, + 192, 3, 1482, 608, 673, 28, 3, 3, 1528, 28, + 1384, 67, 193, 1028, 196, 609, 1432, 1062, 1505, 163, + 988, 1087, 203, 1155, 1189, 1296, 844, 735, 845, 737, + 739, 741, 843, 187, 19, 887, 843, 37, 28, 11, + 1531, 681, 28, 1355, 219, 3, 642, 1, 1213, 681, + 37, 964, 200, 681, 201, 908, 929, 643, 20, 1220, + 226, 869, 681, 20, 229, 920, 20, 1385, 20, 3, + 1216, 612, 242, 243, 244, 245, 247, 252, 258, 265, + 270, 274, 1577, 1000, 1488, 194, 1510, 20, 169, 251, + 1512, 1216, 115, 988, 1371, 20, 114, 32, 114, 466, + 309, 62, 314, 643, 993, 613, 323, 1196, 20, 62, + 20, 62, 20, 771, 1580, 1197, 114, 754, 277, 278, + 114, 320, 32, 4, 1285, 1088, 299, 1253, 1241, 1251, + 677, 940, 1139, 20, 1242, 1254, 1255, 62, 1260, 20, + 4, 4, 869, 346, 1496, 1496, 161, 321, 3, 114, + 62, 1042, 1108, 4, 20, 1114, 1000, 754, 4, 194, + 347, 20, 384, 4, 1303, 62, 348, 1228, 351, 747, + 28, 1557, 357, 1285, 1139, 754, 1286, 1286, 4, 687, + 171, 4, 264, 1386, 264, 4, 1309, 170, 256, 257, + 4, 4, 209, 1502, 371, 370, 373, 372, 375, 374, + 1329, 376, 377, 1246, 1500, 1599, 380, 379, 382, 381, + 24, 5, 681, 20, 383, 228, 1350, 386, 20, 20, + 1583, 20, 367, 368, 369, 1223, 650, 173, 24, 4, + 681, 20, 401, 657, 20, 3, 20, 947, 1478, 1369, + 1465, 1367, 1379, 5, 1378, 268, 7, 1370, 20, 20, + 14, 20, 62, 781, 29, 677, 296, 412, 1383, 1544, + 437, 453, 20, 463, 1607, 647, 42, 43, 472, 385, + 473, 20, 474, 1394, 1397, 477, 20, 1174, 1184, 53, + 1449, 114, 20, 410, 20, 322, 67, 5, 339, 62, + 673, 1403, 98, 1491, 1566, 343, 112, 113, 20, 20, + 20, 69, 126, 127, 471, 130, 1568, 20, 1256, 1492, + 336, 337, 7, 17, 67, 20, 133, 20, 378, 1075, + 350, 1422, 608, 609, 30, 507, 754, 610, 840, 69, + 1425, 1429, 4, 23, 104, 20, 512, 936, 1424, 1428, + 513, 478, 69, 20, 62, 937, 7, 7, 7, 158, + 257, 160, 529, 1601, 28, 44, 20, 69, 407, 1384, + 48, 1550, 1459, 166, 479, 1603, 55, 94, 188, 339, + 554, 20, 518, 752, 611, 577, 148, 1552, 1016, 587, + 588, 681, 938, 168, 246, 480, 593, 481, 62, 596, + 612, 194, 1469, 600, 1473, 1487, 1275, 208, 197, 940, + 1468, 1264, 1472, 634, 1016, 1362, 168, 681, 37, 339, + 217, 234, 652, 613, 1051, 408, 409, 28, 308, 4, + 62, 936, 3, 603, 62, 1450, 239, 62, 62, 937, + 302, 225, 133, 305, 874, 1533, 1066, 20, 67, 475, + 476, 482, 1535, 397, 69, 1358, 1537, 1538, 1593, 255, + 1159, 685, 1539, 1522, 20, 1540, 686, 202, 20, 1542, + 62, 300, 301, 849, 1594, 134, 20, 1076, 1322, 688, + 1052, 895, 1456, 1323, 939, 1553, 319, 1276, 402, 218, + 673, 530, 1556, 940, 702, 670, 946, 894, 333, 705, + 218, 1401, 708, 67, 1053, 20, 714, 37, 62, 569, + 251, 911, 717, 912, 673, 614, 1265, 913, 681, 677, + 483, 728, 731, 732, 1289, 733, 734, 1266, 736, 738, + 740, 742, 743, 744, 63, 62, 677, 942, 114, 943, + 1574, 1582, 1386, 790, 745, 1055, 69, 748, 1573, 1079, + 760, 766, 1007, 776, 876, 782, 20, 796, 37, 807, + 20, 1076, 812, 7, 813, 988, 366, 816, 817, 1015, + 62, 353, 821, 822, 823, 354, 824, 1009, 1048, 67, + 946, 791, 792, 793, 794, 1605, 825, 673, 1174, 758, + 69, 134, 1122, 790, 62, 828, 452, 1095, 831, 104, + 774, 834, 836, 104, 20, 1130, 256, 257, 7, 7, + 754, 20, 1220, 400, 869, 1067, 4, 1151, 1181, 790, + 62, 850, 69, 20, 62, 840, 69, 1230, 869, 69, + 69, 791, 792, 793, 794, 1563, 20, 1161, 1162, 758, + 20, 1033, 62, 20, 20, 840, 62, 470, 1406, 692, + 693, 1163, 697, 698, 699, 1075, 1275, 791, 792, 793, + 794, 758, 69, 1016, 1016, 758, 355, 681, 62, 937, + 875, 1068, 1338, 936, 774, 681, 20, 1341, 938, 1137, + 62, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 1541, 1275, 910, 1136, 775, 62, 1406, 356, + 69, 757, 1432, 207, 62, 772, 938, 7, 1461, 788, + 795, 210, 1194, 1547, 20, 62, 7, 511, 938, 67, + 869, 1016, 101, 940, 681, 869, 20, 69, 62, 525, + 1588, 1239, 1193, 694, 818, 940, 315, 1276, 1200, 102, + 62, 20, 949, 67, 936, 977, 971, 1281, 972, 1355, + 1283, 62, 937, 979, 984, 457, 248, 986, 586, 987, + 795, 1187, 413, 991, 1201, 414, 994, 942, 995, 67, + 775, 996, 62, 67, 997, 939, 20, 998, 103, 1127, + 999, 458, 868, 20, 1004, 1190, 795, 459, 1011, 938, + 1012, 67, 1523, 1017, 1021, 67, 415, 1499, 1503, 1029, + 20, 62, 1035, 973, 8, 1054, 940, 1265, 1069, 1077, + 1091, 1034, 69, 1368, 1346, 1034, 69, 67, 1266, 418, + 758, 1051, 62, 440, 759, 978, 20, 1098, 974, 67, + 20, 1099, 898, 901, 904, 907, 419, 1034, 69, 696, + 297, 975, 1125, 1565, 626, 629, 222, 633, 20, 1115, + 639, 1129, 20, 3, 885, 1202, 62, 254, 820, 1121, + 69, 156, 1295, 1479, 67, 1140, 231, 1203, 1555, 1185, + 128, 1480, 69, 104, 20, 1244, 1204, 1052, 1146, 765, + 1333, 673, 259, 1150, 768, 1154, 20, 1372, 1400, 69, + 1335, 1337, 1405, 946, 1095, 1408, 69, 969, 1112, 1567, + 67, 1053, 1205, 20, 153, 155, 155, 69, 328, 1165, + 20, 992, 571, 806, 572, 921, 772, 118, 691, 681, + 69, 20, 1578, 172, 269, 1167, 1353, 266, 1409, 62, + 1612, 1622, 69, 1245, 20, 62, 937, 788, 1595, 1086, + 122, 713, 194, 69, 1354, 271, 20, 119, 421, 1344, + 67, 722, 725, 1313, 120, 1392, 573, 20, 1602, 839, + 574, 1314, 1402, 870, 69, 835, 1482, 788, 100, 106, + 123, 1191, 1192, 938, 788, 1206, 1261, 124, 20, 62, + 963, 880, 1224, 759, 1355, 1527, 1526, 1188, 1233, 276, + 111, 1238, 1249, 69, 575, 1259, 20, 889, 758, 1267, + 168, 1417, 576, 1274, 423, 238, 1280, 20, 1414, 1282, + 1284, 406, 1457, 1104, 69, 1109, 1109, 1455, 1104, 425, + 1285, 886, 1025, 1286, 1297, 1436, 681, 1300, 20, 0, + 1301, 1302, 1262, 1307, 0, 1308, 0, 4, 838, 1311, + 0, 1312, 0, 788, 0, 1316, 1315, 840, 69, 0, + 1318, 1317, 0, 1320, 1319, 1216, 0, 1324, 0, 422, + 0, 1331, 20, 0, 1332, 465, 0, 0, 204, 0, + 0, 0, 169, 0, 0, 0, 841, 0, 67, 0, + 1175, 1178, 0, 0, 67, 0, 810, 985, 0, 205, + 220, 0, 1349, 0, 0, 0, 1356, 7, 104, 7, + 7, 0, 7, 842, 1365, 170, 781, 1376, 677, 843, + 230, 365, 0, 0, 0, 968, 844, 0, 845, 0, + 0, 69, 171, 461, 0, 462, 0, 69, 67, 1519, + 846, 233, 1521, 0, 0, 20, 0, 0, 1387, 0, + 0, 20, 847, 0, 806, 172, 311, 1016, 316, 0, + 681, 0, 325, 848, 0, 0, 391, 394, 0, 0, + 0, 759, 1413, 897, 900, 903, 906, 313, 0, 318, + 1415, 69, 563, 329, 1418, 7, 0, 543, 0, 0, + 1420, 0, 849, 173, 788, 20, 0, 62, 0, 544, + 0, 890, 0, 7, 545, 7, 7, 7, 7, 7, + 7, 0, 0, 0, 1431, 478, 1571, 0, 0, 1434, + 546, 1437, 0, 0, 1126, 1440, 0, 1443, 358, 0, + 1445, 0, 1447, 1451, 0, 0, 1330, 1454, 479, 494, + 495, 496, 497, 498, 499, 500, 501, 502, 503, 363, + 0, 0, 62, 937, 0, 1248, 0, 608, 609, 480, + 1464, 481, 610, 0, 547, 506, 0, 1466, 0, 0, + 1471, 1600, 0, 387, 508, 0, 1476, 0, 0, 548, + 549, 0, 478, 1157, 1490, 0, 0, 0, 625, 628, + 938, 632, 0, 0, 638, 1495, 1497, 1501, 0, 1504, + 1616, 1506, 0, 788, 788, 479, 1508, 940, 1509, 611, + 0, 1621, 1511, 416, 0, 482, 438, 454, 1514, 464, + 0, 1006, 1051, 0, 1517, 612, 480, 1520, 481, 0, + 1020, 1024, 7, 7, 424, 0, 1032, 451, 456, 0, + 467, 0, 0, 1534, 0, 0, 67, 1094, 613, 751, + 0, 1103, 763, 0, 550, 780, 0, 0, 1119, 805, + 788, 788, 690, 0, 0, 0, 0, 0, 0, 700, + 551, 0, 0, 0, 1559, 0, 0, 0, 1560, 1561, + 0, 1562, 482, 0, 483, 712, 0, 0, 0, 69, + 0, 1175, 788, 0, 0, 721, 724, 552, 1564, 553, + 1569, 67, 1053, 20, 0, 0, 0, 0, 0, 0, + 0, 0, 1581, 0, 1306, 0, 0, 0, 1585, 0, + 0, 0, 788, 860, 788, 0, 556, 0, 0, 0, + 0, 578, 59, 60, 0, 0, 1591, 0, 1321, 1592, + 61, 62, 0, 1597, 69, 0, 63, 566, 0, 0, + 0, 483, 585, 0, 0, 0, 1493, 1494, 20, 635, + 0, 0, 10, 0, 0, 13, 16, 0, 20, 1608, + 0, 1609, 64, 516, 0, 519, 522, 0, 526, 0, + 636, 1614, 837, 1615, 0, 0, 0, 65, 0, 1617, + 0, 1618, 0, 0, 411, 1619, 1620, 0, 59, 60, + 0, 1624, 0, 0, 0, 0, 61, 62, 1625, 0, + 589, 0, 63, 1218, 0, 0, 594, 0, 0, 0, + 597, 0, 0, 601, 0, 605, 608, 609, 10, 0, + 132, 610, 0, 139, 140, 141, 142, 0, 64, 0, + 703, 143, 144, 145, 146, 706, 0, 0, 709, 0, + 0, 0, 715, 65, 0, 0, 0, 0, 718, 0, + 788, 704, 10, 10, 10, 0, 707, 729, 1304, 710, + 66, 0, 1310, 716, 0, 0, 936, 0, 611, 719, + 0, 0, 0, 62, 937, 0, 0, 0, 730, 0, + 67, 0, 186, 749, 612, 0, 761, 767, 0, 777, + 0, 783, 0, 798, 1045, 808, 0, 1064, 0, 0, + 814, 1089, 0, 0, 753, 0, 0, 613, 770, 0, + 68, 938, 786, 0, 0, 0, 811, 0, 0, 0, + 939, 815, 826, 69, 0, 0, 66, 0, 940, 0, + 70, 829, 0, 0, 832, 0, 0, 20, 0, 0, + 0, 0, 0, 827, 0, 922, 67, 926, 926, 0, + 931, 0, 830, 0, 0, 833, 0, 852, 0, 941, + 0, 0, 0, 0, 0, 0, 0, 1395, 1398, 0, + 0, 0, 942, 0, 943, 298, 68, 1404, 865, 517, + 0, 520, 523, 0, 527, 0, 944, 0, 0, 69, + 0, 84, 85, 86, 0, 945, 70, 0, 0, 614, + 0, 0, 0, 20, 0, 0, 0, 0, 1546, 87, + 88, 89, 0, 0, 0, 946, 590, 1169, 0, 0, + 0, 0, 595, 1026, 1426, 1430, 598, 0, 0, 602, + 0, 606, 0, 0, 947, 0, 847, 0, 90, 91, + 92, 394, 0, 1106, 926, 1110, 1110, 926, 1106, 0, + 0, 0, 0, 0, 0, 759, 1460, 0, 0, 10, + 0, 0, 0, 0, 1198, 69, 0, 0, 0, 0, + 0, 0, 0, 0, 1226, 0, 0, 948, 951, 20, + 1235, 0, 0, 62, 1257, 0, 1470, 659, 1474, 980, + 0, 0, 0, 1586, 1587, 1485, 0, 660, 0, 965, + 0, 0, 0, 661, 10, 10, 0, 662, 0, 0, + 983, 663, 0, 426, 0, 0, 0, 0, 664, 0, + 665, 0, 427, 354, 0, 0, 1013, 428, 429, 0, + 666, 667, 668, 0, 1610, 0, 0, 0, 1037, 0, + 0, 1056, 0, 0, 1071, 1080, 430, 1014, 431, 0, + 0, 0, 1530, 0, 0, 0, 0, 0, 0, 1047, + 0, 0, 1065, 0, 0, 1073, 1090, 0, 0, 0, + 926, 506, 0, 0, 0, 0, 0, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 1361, 0, + 0, 432, 433, 0, 0, 0, 1373, 0, 0, 1380, + 0, 434, 435, 10, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 279, 0, 0, 280, 0, 0, 0, + 281, 282, 283, 284, 1575, 285, 1579, 286, 287, 0, + 0, 288, 0, 0, 0, 0, 0, 0, 436, 289, + 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, + 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, + 292, 1168, 293, 0, 0, 0, 0, 294, 0, 0, + 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, + 0, 0, 1170, 0, 0, 0, 0, 0, 0, 20, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1435, 0, 1438, 0, 0, 0, 1441, 1195, 1444, + 0, 1208, 1446, 0, 1448, 0, 0, 0, 1225, 0, + 0, 0, 0, 0, 1234, 0, 0, 1240, 1250, 1199, + 0, 0, 1215, 0, 0, 1269, 0, 0, 0, 1227, + 0, 0, 0, 0, 0, 1237, 0, 0, 1247, 1258, + 0, 0, 0, 0, 0, 0, 1273, 532, 533, 534, + 535, 536, 537, 539, 540, 541, 542, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1325, 607, 0, 0, 0, 630, 0, + 0, 0, 0, 640, 641, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1328, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1543, 0, 0, 0, 0, + 0, 0, 1357, 0, 0, 0, 0, 0, 0, 0, + 1366, 0, 0, 1377, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1364, 0, 0, 0, 0, 0, 0, + 0, 1374, 0, 0, 1381, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1570, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 0, 10, 10, 0, 10, 0, + 0, 0, 1477, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1481, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1536, + 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, + 1545, 10, 10, 10, 10, 10, 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, 1173, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 10 +}; + +static const yytype_int16 yycheck[] = +{ + 25, 518, 216, 773, 213, 215, 680, 1003, 673, 476, + 199, 923, 677, 39, 39, 1217, 682, 908, 43, 789, + 213, 927, 47, 1003, 1113, 927, 927, 909, 53, 1138, + 544, 927, 57, 58, 927, 32, 24, 551, 927, 553, + 746, 1138, 6, 211, 75, 919, 235, 256, 237, 3, + 930, 1299, 930, 4, 934, 4, 934, 939, 930, 269, + 924, 935, 934, 934, 946, 6, 3, 3, 93, 3, + 4, 5, 6, 98, 3, 4, 5, 6, 246, 3, + 746, 1124, 392, 6, 3, 919, 75, 978, 113, 3, + 188, 1116, 117, 1393, 66, 4, 121, 4, 122, 773, + 125, 935, 127, 6, 3, 130, 131, 3, 133, 134, + 135, 3, 176, 71, 148, 4, 3, 3, 1450, 4, + 86, 238, 147, 196, 149, 72, 178, 930, 255, 117, + 104, 934, 157, 1015, 1076, 257, 226, 651, 228, 653, + 654, 655, 219, 131, 111, 775, 219, 19, 4, 0, + 1450, 236, 4, 272, 179, 3, 185, 116, 1100, 236, + 32, 867, 154, 236, 156, 795, 845, 242, 295, 284, + 195, 286, 236, 295, 199, 67, 295, 143, 295, 3, + 265, 139, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 1524, 167, 1396, 241, 1423, 295, 149, 150, + 1427, 265, 61, 104, 1229, 295, 115, 131, 115, 398, + 235, 89, 237, 242, 888, 162, 241, 1097, 295, 89, + 295, 89, 295, 888, 1524, 1097, 115, 181, 216, 217, + 115, 73, 131, 187, 170, 934, 224, 1117, 1116, 1117, + 194, 144, 273, 295, 1116, 1117, 1117, 89, 1120, 295, + 187, 187, 286, 278, 141, 141, 115, 99, 3, 115, + 89, 927, 941, 187, 295, 944, 167, 181, 187, 241, + 295, 295, 140, 187, 1156, 89, 301, 1111, 303, 93, + 4, 1483, 307, 170, 273, 181, 173, 173, 187, 599, + 199, 187, 201, 259, 201, 187, 1160, 182, 183, 184, + 187, 187, 161, 1412, 330, 330, 332, 332, 334, 334, + 1184, 336, 337, 1116, 1411, 1563, 342, 342, 344, 344, + 261, 245, 236, 295, 349, 197, 1217, 352, 295, 295, + 1532, 295, 320, 321, 322, 1105, 545, 260, 261, 187, + 236, 295, 367, 552, 295, 3, 295, 250, 1391, 1229, + 1375, 1229, 1232, 245, 1232, 214, 1, 1229, 295, 295, + 5, 295, 89, 192, 17, 194, 295, 392, 1248, 1458, + 395, 396, 295, 398, 1576, 543, 29, 30, 403, 247, + 405, 295, 407, 1265, 1266, 410, 295, 1052, 1067, 42, + 121, 115, 295, 390, 295, 237, 238, 245, 257, 89, + 148, 1275, 55, 1399, 1513, 264, 59, 60, 295, 295, + 295, 281, 65, 66, 402, 68, 1513, 295, 1117, 1399, + 276, 277, 67, 118, 238, 295, 126, 295, 338, 64, + 302, 1321, 71, 72, 117, 460, 181, 76, 157, 281, + 1322, 1323, 187, 6, 258, 295, 471, 82, 1322, 1323, + 475, 109, 281, 295, 89, 90, 101, 102, 103, 112, + 184, 114, 487, 1572, 4, 161, 295, 281, 378, 86, + 158, 1467, 1354, 126, 132, 1572, 160, 205, 131, 338, + 505, 295, 479, 672, 123, 510, 206, 1467, 233, 514, + 515, 236, 127, 77, 78, 153, 521, 155, 89, 524, + 139, 241, 1384, 528, 1386, 1396, 122, 160, 84, 144, + 1384, 63, 1386, 538, 233, 1221, 77, 236, 390, 378, + 210, 267, 547, 162, 159, 384, 385, 4, 83, 187, + 89, 82, 3, 530, 89, 266, 270, 89, 89, 90, + 164, 194, 126, 200, 758, 1457, 65, 295, 238, 408, + 409, 209, 1458, 85, 281, 1221, 1458, 1458, 1554, 212, + 1027, 586, 1458, 180, 295, 1458, 591, 294, 295, 1458, + 89, 224, 225, 292, 1554, 275, 295, 212, 169, 604, + 215, 790, 1352, 174, 136, 1475, 239, 203, 282, 279, + 148, 130, 1483, 144, 619, 151, 231, 790, 251, 624, + 279, 1275, 627, 238, 239, 295, 631, 479, 89, 287, + 150, 68, 637, 70, 148, 254, 168, 74, 236, 194, + 278, 646, 647, 648, 1138, 650, 651, 179, 653, 654, + 655, 656, 657, 658, 94, 89, 194, 188, 115, 190, + 1522, 1532, 259, 62, 669, 930, 281, 672, 1522, 934, + 675, 676, 221, 678, 106, 680, 295, 682, 530, 684, + 295, 212, 687, 308, 689, 104, 319, 692, 693, 138, + 89, 125, 697, 698, 699, 129, 701, 256, 166, 238, + 231, 100, 101, 102, 103, 1576, 711, 148, 1353, 108, + 281, 275, 274, 62, 89, 720, 177, 243, 723, 258, + 95, 726, 727, 258, 295, 269, 183, 184, 353, 354, + 181, 295, 284, 366, 286, 234, 187, 264, 98, 62, + 89, 746, 281, 295, 89, 157, 281, 165, 286, 281, + 281, 100, 101, 102, 103, 1505, 295, 26, 27, 108, + 295, 110, 89, 295, 295, 157, 89, 400, 114, 608, + 609, 40, 611, 612, 613, 64, 122, 100, 101, 102, + 103, 108, 281, 233, 233, 108, 220, 236, 89, 90, + 758, 290, 97, 82, 95, 236, 295, 224, 127, 988, + 89, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 1458, 122, 819, 988, 191, 89, 114, 253, + 281, 673, 178, 158, 89, 677, 127, 452, 248, 681, + 229, 166, 1097, 249, 295, 89, 461, 470, 127, 238, + 286, 233, 107, 144, 236, 286, 295, 281, 89, 482, + 105, 1116, 1097, 610, 695, 144, 237, 203, 87, 124, + 89, 295, 867, 238, 82, 137, 871, 1131, 873, 272, + 1134, 89, 90, 878, 879, 23, 211, 882, 511, 884, + 229, 1075, 392, 888, 113, 392, 891, 188, 893, 238, + 191, 896, 89, 238, 899, 136, 295, 902, 163, 970, + 905, 49, 754, 295, 909, 1095, 229, 55, 913, 127, + 915, 238, 1449, 918, 919, 238, 392, 1411, 1412, 924, + 295, 89, 927, 9, 1, 930, 144, 168, 933, 934, + 935, 280, 281, 1229, 1205, 280, 281, 238, 179, 392, + 108, 159, 89, 395, 271, 217, 295, 938, 34, 238, + 295, 938, 791, 792, 793, 794, 392, 280, 281, 610, + 224, 47, 967, 1513, 533, 534, 179, 536, 295, 945, + 539, 976, 295, 3, 774, 204, 89, 212, 695, 947, + 281, 103, 1143, 1391, 238, 990, 199, 216, 1482, 1068, + 67, 1391, 281, 258, 295, 1116, 225, 215, 1003, 146, + 1190, 148, 213, 1008, 676, 1010, 295, 1229, 1275, 281, + 1200, 1201, 1276, 231, 243, 1279, 281, 869, 943, 1513, + 238, 239, 251, 295, 101, 102, 103, 281, 241, 1034, + 295, 888, 145, 230, 147, 842, 888, 20, 607, 236, + 281, 295, 1524, 222, 223, 1050, 214, 214, 1279, 89, + 1590, 1613, 281, 1116, 295, 89, 90, 909, 1555, 934, + 20, 630, 241, 281, 232, 215, 295, 50, 392, 1204, + 238, 640, 641, 1166, 57, 1264, 189, 295, 1572, 69, + 193, 1166, 1275, 755, 281, 726, 176, 939, 57, 58, + 50, 1096, 1097, 127, 946, 1100, 1120, 57, 295, 89, + 867, 773, 1107, 271, 272, 195, 1449, 1075, 1113, 216, + 58, 1116, 1117, 281, 227, 1120, 295, 789, 108, 1124, + 77, 1296, 235, 1128, 392, 201, 1131, 295, 1294, 1134, + 1135, 369, 1353, 940, 281, 942, 943, 1352, 945, 392, + 170, 774, 919, 173, 1149, 1335, 236, 1152, 295, -1, + 1155, 1156, 1120, 1158, -1, 1160, -1, 187, 727, 1164, + -1, 1166, -1, 1015, -1, 1171, 1171, 157, 281, -1, + 1176, 1176, -1, 1179, 1179, 265, -1, 1182, -1, 392, + -1, 1186, 295, -1, 1189, 398, -1, -1, 157, -1, + -1, -1, 149, -1, -1, -1, 186, -1, 238, -1, + 1052, 1053, -1, -1, 238, -1, 684, 879, -1, 157, + 179, -1, 1217, -1, -1, -1, 1221, 842, 258, 844, + 845, -1, 847, 213, 1229, 182, 192, 1232, 194, 219, + 199, 308, -1, -1, -1, 868, 226, -1, 228, -1, + -1, 281, 199, 283, -1, 285, -1, 281, 238, 1439, + 240, 199, 1442, -1, -1, 295, -1, -1, 1263, -1, + -1, 295, 252, -1, 230, 222, 235, 233, 237, -1, + 236, -1, 241, 263, -1, -1, 353, 354, -1, -1, + -1, 271, 1287, 791, 792, 793, 794, 235, -1, 237, + 1295, 281, 505, 241, 1299, 920, -1, 79, -1, -1, + 1305, -1, 292, 260, 1156, 295, -1, 89, -1, 91, + -1, 789, -1, 938, 96, 940, 941, 942, 943, 944, + 945, -1, -1, -1, 1329, 109, 1516, -1, -1, 1334, + 112, 1336, -1, -1, 967, 1340, -1, 1342, 307, -1, + 1345, -1, 1347, 1348, -1, -1, 1185, 1352, 132, 427, + 428, 429, 430, 431, 432, 433, 434, 435, 436, 307, + -1, -1, 89, 90, -1, 92, -1, 71, 72, 153, + 1375, 155, 76, -1, 156, 452, -1, 1382, -1, -1, + 1385, 1571, -1, 352, 461, -1, 1391, -1, -1, 171, + 172, -1, 109, 1026, 1399, -1, -1, -1, 533, 534, + 127, 536, -1, -1, 539, 1410, 1411, 1412, -1, 1414, + 1600, 1416, -1, 1265, 1266, 132, 1421, 144, 1423, 123, + -1, 1611, 1427, 392, -1, 209, 395, 396, 1433, 398, + -1, 909, 159, -1, 1439, 139, 153, 1442, 155, -1, + 918, 919, 1067, 1068, 392, -1, 924, 395, 396, -1, + 398, -1, -1, 1458, -1, -1, 238, 935, 162, 672, + -1, 939, 675, -1, 246, 678, -1, -1, 946, 682, + 1322, 1323, 607, -1, -1, -1, -1, -1, -1, 614, + 262, -1, -1, -1, 1489, -1, -1, -1, 1493, 1494, + -1, 1496, 209, -1, 278, 630, -1, -1, -1, 281, + -1, 1353, 1354, -1, -1, 640, 641, 289, 1513, 291, + 1515, 238, 239, 295, -1, -1, -1, -1, -1, -1, + -1, -1, 1527, -1, 1157, -1, -1, -1, 1533, -1, + -1, -1, 1384, 746, 1386, -1, 505, -1, -1, -1, + -1, 510, 80, 81, -1, -1, 1551, -1, 1181, 1554, + 88, 89, -1, 1558, 281, -1, 94, 505, -1, -1, + -1, 278, 510, -1, -1, -1, 1405, 1406, 295, 538, + -1, -1, 1, -1, -1, 4, 5, -1, 295, 1584, + -1, 1586, 120, 478, -1, 480, 481, -1, 483, -1, + 538, 1596, 727, 1598, -1, -1, -1, 135, -1, 1604, + -1, 1606, -1, -1, 142, 1610, 1611, -1, 80, 81, + -1, 1616, -1, -1, -1, -1, 88, 89, 1623, -1, + 515, -1, 94, 1101, -1, -1, 521, -1, -1, -1, + 525, -1, -1, 528, -1, 530, 71, 72, 67, -1, + 69, 76, -1, 35, 36, 37, 38, -1, 120, -1, + 619, 43, 44, 45, 46, 624, -1, -1, 627, -1, + -1, -1, 631, 135, -1, -1, -1, -1, 637, -1, + 1522, 619, 101, 102, 103, -1, 624, 646, 1156, 627, + 218, -1, 1160, 631, -1, -1, 82, -1, 123, 637, + -1, -1, -1, 89, 90, -1, -1, -1, 646, -1, + 238, -1, 131, 672, 139, -1, 675, 676, -1, 678, + -1, 680, -1, 682, 927, 684, -1, 930, -1, -1, + 689, 934, -1, -1, 672, -1, -1, 162, 676, -1, + 268, 127, 680, -1, -1, -1, 684, -1, -1, -1, + 136, 689, 711, 281, -1, -1, 218, -1, 144, -1, + 288, 720, -1, -1, 723, -1, -1, 295, -1, -1, + -1, -1, -1, 711, -1, 842, 238, 844, 845, -1, + 847, -1, 720, -1, -1, 723, -1, 746, -1, 175, + -1, -1, -1, -1, -1, -1, -1, 1265, 1266, -1, + -1, -1, 188, -1, 190, 224, 268, 1275, 746, 478, + -1, 480, 481, -1, 483, -1, 202, -1, -1, 281, + -1, 11, 12, 13, -1, 211, 288, -1, -1, 254, + -1, -1, -1, 295, -1, -1, -1, -1, 1461, 29, + 30, 31, -1, -1, -1, 231, 515, 1050, -1, -1, + -1, -1, 521, 920, 1322, 1323, 525, -1, -1, 528, + -1, 530, -1, -1, 250, -1, 252, -1, 58, 59, + 60, 938, -1, 940, 941, 942, 943, 944, 945, -1, + -1, -1, -1, -1, -1, 271, 1354, -1, -1, 308, + -1, -1, -1, -1, 1097, 281, -1, -1, -1, -1, + -1, -1, -1, -1, 1107, -1, -1, 293, 867, 295, + 1113, -1, -1, 89, 1117, -1, 1384, 8, 1386, 878, + -1, -1, -1, 1546, 1547, 1393, -1, 18, -1, 867, + -1, -1, -1, 24, 353, 354, -1, 28, -1, -1, + 878, 32, -1, 119, -1, -1, -1, -1, 39, -1, + 41, -1, 128, 129, -1, -1, 915, 133, 134, -1, + 51, 52, 53, -1, 1587, -1, -1, -1, 927, -1, + -1, 930, -1, -1, 933, 934, 152, 915, 154, -1, + -1, -1, 1450, -1, -1, -1, -1, -1, -1, 927, + -1, -1, 930, -1, -1, 933, 934, -1, -1, -1, + 1067, 1068, -1, -1, -1, -1, -1, 426, 427, 428, + 429, 430, 431, 432, 433, 434, 435, 436, 1221, -1, + -1, 197, 198, -1, -1, -1, 1229, -1, -1, 1232, + -1, 207, 208, 452, -1, -1, -1, -1, -1, -1, + -1, -1, 461, 7, -1, -1, 10, -1, -1, -1, + 14, 15, 16, 17, 1522, 19, 1524, 21, 22, -1, + -1, 25, -1, -1, -1, -1, -1, -1, 244, 33, + -1, -1, -1, -1, -1, -1, -1, -1, 42, -1, + -1, -1, -1, -1, 48, -1, -1, -1, -1, -1, + 54, 1050, 56, -1, -1, -1, -1, 61, -1, -1, + -1, -1, -1, -1, -1, 281, -1, -1, -1, -1, + -1, -1, 1050, -1, -1, -1, -1, -1, -1, 295, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1334, -1, 1336, -1, -1, -1, 1340, 1097, 1342, + -1, 1100, 1345, -1, 1347, -1, -1, -1, 1107, -1, + -1, -1, -1, -1, 1113, -1, -1, 1116, 1117, 1097, + -1, -1, 1100, -1, -1, 1124, -1, -1, -1, 1107, + -1, -1, -1, -1, -1, 1113, -1, -1, 1116, 1117, + -1, -1, -1, -1, -1, -1, 1124, 494, 495, 496, + 497, 498, 499, 500, 501, 502, 503, -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, 1182, 531, -1, -1, -1, 535, -1, + -1, -1, -1, 540, 541, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 1182, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1458, -1, -1, -1, -1, + -1, -1, 1221, -1, -1, -1, -1, -1, -1, -1, + 1229, -1, -1, 1232, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1221, -1, -1, -1, -1, -1, -1, + -1, 1229, -1, -1, 1232, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 1515, -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, 842, -1, 844, 845, -1, 847, -1, + -1, -1, 1391, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1391, -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, 1458, + -1, 920, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 938, + 1458, 940, 941, 942, 943, 944, 945, -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, 1051, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 1067, 1068 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint16 yystos[] = +{ + 0, 116, 298, 3, 187, 245, 300, 549, 551, 663, + 764, 0, 550, 764, 549, 664, 764, 118, 302, 111, + 295, 297, 395, 6, 261, 665, 695, 765, 4, 766, + 117, 301, 131, 396, 423, 426, 549, 552, 764, 698, + 765, 297, 766, 766, 161, 488, 423, 427, 158, 397, + 483, 297, 395, 766, 297, 160, 487, 489, 299, 80, + 81, 88, 89, 94, 120, 135, 218, 238, 268, 281, + 288, 297, 333, 334, 349, 350, 359, 407, 439, 609, + 650, 711, 737, 754, 11, 12, 13, 29, 30, 31, + 58, 59, 60, 484, 205, 398, 587, 297, 766, 297, + 350, 107, 124, 163, 258, 297, 350, 384, 416, 495, + 690, 737, 766, 766, 115, 670, 766, 351, 20, 50, + 57, 360, 20, 50, 57, 408, 766, 766, 551, 652, + 766, 738, 764, 126, 275, 332, 419, 728, 297, 35, + 36, 37, 38, 43, 44, 45, 46, 588, 206, 399, + 589, 297, 388, 551, 493, 551, 493, 691, 766, 297, + 766, 670, 297, 765, 297, 297, 766, 297, 77, 149, + 182, 199, 222, 260, 327, 468, 538, 576, 614, 651, + 696, 729, 297, 5, 297, 445, 764, 765, 766, 767, + 297, 297, 297, 297, 241, 620, 297, 84, 339, 385, + 301, 301, 294, 297, 350, 737, 762, 327, 766, 670, + 327, 328, 469, 539, 577, 615, 697, 210, 279, 297, + 350, 596, 650, 734, 446, 766, 297, 341, 552, 297, + 350, 650, 690, 737, 267, 417, 709, 496, 709, 270, + 715, 763, 297, 297, 297, 297, 78, 297, 327, 329, + 332, 150, 297, 466, 468, 766, 183, 184, 297, 538, + 540, 542, 543, 670, 201, 297, 576, 578, 670, 223, + 297, 614, 616, 620, 297, 695, 696, 765, 765, 7, + 10, 14, 15, 16, 17, 19, 21, 22, 25, 33, + 42, 48, 54, 56, 61, 735, 295, 445, 764, 765, + 766, 766, 164, 340, 497, 200, 580, 710, 83, 297, + 336, 350, 690, 737, 297, 336, 350, 690, 737, 766, + 73, 99, 237, 297, 320, 350, 368, 646, 650, 737, + 330, 332, 467, 766, 541, 542, 276, 277, 544, 670, + 730, 731, 579, 670, 617, 620, 297, 297, 297, 494, + 552, 297, 581, 125, 129, 220, 253, 297, 350, 389, + 418, 420, 680, 737, 338, 551, 766, 765, 765, 765, + 297, 395, 297, 395, 297, 395, 297, 297, 544, 297, + 395, 297, 395, 297, 140, 247, 297, 350, 449, 669, + 491, 551, 421, 422, 551, 390, 681, 85, 337, 342, + 766, 297, 282, 369, 741, 647, 741, 544, 670, 670, + 423, 142, 297, 333, 334, 349, 350, 359, 407, 439, + 451, 609, 650, 711, 737, 754, 119, 128, 133, 134, + 152, 154, 197, 198, 207, 208, 244, 297, 350, 405, + 420, 432, 435, 437, 472, 476, 572, 574, 590, 592, + 661, 737, 177, 297, 350, 526, 737, 23, 49, 55, + 343, 283, 285, 297, 350, 650, 690, 737, 742, 746, + 766, 765, 297, 297, 297, 670, 670, 297, 109, 132, + 153, 155, 209, 278, 391, 428, 434, 452, 474, 478, + 594, 732, 551, 668, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 516, 527, 551, 297, 551, 748, + 747, 766, 297, 297, 734, 392, 428, 434, 423, 428, + 434, 475, 428, 434, 479, 766, 428, 434, 733, 297, + 130, 424, 424, 424, 424, 424, 424, 424, 573, 424, + 424, 424, 424, 79, 91, 96, 112, 156, 171, 172, + 246, 262, 289, 291, 297, 331, 350, 354, 363, 400, + 480, 512, 514, 650, 666, 699, 737, 755, 757, 287, + 752, 145, 147, 189, 193, 227, 235, 297, 350, 458, + 462, 555, 563, 625, 640, 737, 766, 297, 297, 428, + 434, 429, 497, 297, 428, 434, 297, 428, 434, 595, + 297, 428, 434, 423, 425, 428, 434, 424, 71, 72, + 76, 123, 139, 162, 254, 318, 319, 324, 415, 433, + 448, 492, 656, 682, 436, 656, 682, 438, 656, 682, + 424, 477, 656, 682, 297, 350, 737, 575, 656, 682, + 424, 424, 185, 242, 545, 657, 662, 332, 517, 552, + 542, 401, 297, 513, 515, 667, 517, 542, 517, 8, + 18, 24, 28, 32, 39, 41, 51, 52, 53, 753, + 151, 470, 743, 148, 456, 459, 463, 194, 556, 567, + 564, 236, 626, 644, 641, 297, 297, 359, 297, 406, + 656, 682, 670, 670, 318, 325, 448, 670, 670, 670, + 656, 683, 297, 350, 737, 297, 350, 737, 297, 350, + 737, 473, 656, 682, 297, 350, 737, 297, 350, 737, + 591, 656, 682, 593, 656, 682, 546, 658, 297, 350, + 737, 297, 297, 297, 297, 517, 297, 517, 297, 517, + 297, 517, 297, 297, 297, 297, 471, 93, 297, 350, + 355, 650, 690, 737, 181, 465, 536, 552, 108, 271, + 297, 350, 386, 650, 716, 146, 297, 350, 456, 460, + 737, 536, 552, 566, 95, 191, 297, 350, 361, 559, + 650, 192, 297, 350, 561, 567, 737, 536, 552, 643, + 62, 100, 101, 102, 103, 229, 297, 303, 350, 370, + 372, 374, 376, 386, 629, 650, 230, 297, 350, 631, + 644, 737, 297, 297, 350, 737, 297, 297, 319, 326, + 492, 297, 297, 297, 297, 297, 350, 737, 297, 350, + 737, 297, 350, 737, 297, 657, 297, 656, 682, 69, + 157, 186, 213, 219, 226, 228, 240, 252, 263, 292, + 297, 315, 350, 386, 481, 547, 602, 610, 623, 627, + 650, 654, 678, 700, 716, 737, 758, 356, 552, 286, + 456, 457, 750, 387, 695, 765, 106, 382, 717, 461, + 456, 567, 568, 750, 362, 466, 766, 382, 562, 456, + 644, 645, 750, 304, 540, 542, 371, 578, 670, 373, + 578, 670, 375, 578, 670, 377, 578, 670, 382, 632, + 297, 68, 70, 74, 314, 316, 317, 321, 482, 548, + 67, 312, 551, 739, 611, 312, 551, 624, 642, 642, + 655, 551, 677, 679, 701, 759, 82, 90, 127, 136, + 144, 175, 188, 190, 202, 211, 231, 250, 293, 297, + 335, 350, 352, 430, 440, 454, 522, 553, 557, 582, + 597, 633, 673, 678, 716, 737, 760, 537, 766, 552, + 749, 297, 297, 9, 34, 47, 383, 137, 217, 297, + 350, 443, 607, 737, 297, 456, 297, 297, 104, 378, + 560, 297, 566, 567, 297, 297, 297, 297, 297, 297, + 167, 378, 502, 630, 297, 643, 644, 221, 612, 256, + 686, 297, 297, 350, 737, 138, 233, 297, 447, 637, + 644, 297, 481, 637, 644, 758, 551, 729, 196, 297, + 570, 610, 644, 110, 280, 297, 303, 350, 370, 372, + 374, 376, 386, 393, 629, 650, 736, 737, 166, 500, + 628, 159, 215, 239, 297, 335, 350, 352, 430, 454, + 485, 600, 633, 648, 650, 737, 65, 234, 290, 297, + 309, 350, 639, 737, 756, 64, 212, 297, 307, 335, + 350, 352, 430, 454, 485, 599, 600, 633, 648, 650, + 737, 297, 481, 637, 644, 243, 659, 353, 422, 426, + 431, 441, 643, 644, 312, 464, 551, 523, 642, 312, + 551, 565, 565, 583, 642, 464, 598, 634, 643, 644, + 674, 765, 274, 726, 761, 297, 766, 339, 751, 297, + 269, 444, 712, 378, 608, 379, 540, 542, 75, 273, + 297, 322, 724, 503, 540, 542, 297, 322, 724, 613, + 297, 264, 687, 702, 297, 643, 638, 766, 603, 734, + 571, 26, 27, 40, 394, 297, 501, 297, 350, 650, + 737, 486, 490, 764, 536, 552, 601, 740, 552, 649, + 653, 98, 310, 366, 642, 516, 308, 695, 765, 659, + 620, 297, 297, 307, 335, 350, 430, 454, 650, 737, + 87, 113, 204, 216, 225, 251, 297, 347, 350, 402, + 585, 605, 621, 659, 675, 737, 265, 442, 644, 704, + 284, 455, 744, 750, 297, 350, 650, 737, 481, 554, + 165, 498, 558, 297, 350, 650, 736, 737, 297, 335, + 350, 352, 454, 553, 557, 599, 633, 737, 92, 297, + 350, 352, 357, 430, 454, 485, 648, 650, 737, 297, + 454, 673, 765, 727, 63, 168, 179, 297, 305, 350, + 440, 504, 530, 737, 297, 122, 203, 413, 584, 713, + 297, 413, 297, 413, 297, 170, 173, 323, 510, 517, + 518, 510, 517, 518, 725, 503, 257, 297, 688, 703, + 297, 297, 297, 643, 644, 313, 766, 297, 297, 610, + 644, 297, 297, 623, 627, 297, 395, 297, 395, 297, + 395, 766, 169, 174, 297, 350, 508, 520, 737, 637, + 670, 297, 297, 620, 660, 620, 403, 620, 97, 364, + 586, 224, 606, 618, 618, 622, 364, 676, 705, 297, + 378, 502, 745, 214, 232, 272, 297, 350, 386, 604, + 635, 650, 716, 718, 737, 297, 350, 352, 361, 430, + 454, 553, 559, 650, 737, 499, 297, 350, 352, 430, + 650, 737, 358, 430, 86, 143, 259, 297, 344, 453, + 692, 306, 542, 505, 643, 644, 531, 643, 644, 414, + 561, 567, 631, 637, 644, 413, 114, 404, 413, 584, + 714, 511, 519, 297, 725, 297, 689, 702, 297, 718, + 297, 367, 404, 509, 637, 643, 644, 521, 637, 643, + 644, 297, 178, 528, 297, 650, 620, 297, 650, 365, + 297, 650, 619, 297, 650, 297, 650, 297, 650, 121, + 266, 297, 409, 706, 297, 744, 750, 740, 636, 643, + 644, 248, 671, 719, 297, 553, 297, 345, 637, 643, + 644, 297, 637, 643, 644, 693, 297, 350, 440, 504, + 530, 737, 176, 506, 524, 644, 704, 378, 502, 532, + 297, 322, 724, 670, 670, 297, 141, 297, 450, 517, + 518, 297, 510, 517, 297, 255, 297, 684, 297, 297, + 528, 297, 528, 529, 297, 348, 66, 297, 311, 620, + 297, 620, 180, 344, 410, 533, 692, 195, 524, 569, + 644, 704, 707, 729, 297, 303, 350, 370, 372, 374, + 376, 386, 629, 650, 736, 737, 766, 249, 672, 720, + 322, 346, 724, 404, 694, 517, 378, 502, 507, 297, + 297, 297, 297, 750, 297, 450, 510, 517, 518, 297, + 650, 620, 534, 637, 643, 644, 411, 524, 569, 644, + 704, 297, 378, 502, 708, 297, 766, 766, 105, 380, + 721, 297, 297, 322, 724, 497, 525, 297, 685, 718, + 620, 510, 517, 518, 535, 378, 412, 502, 297, 297, + 766, 381, 587, 722, 297, 297, 620, 297, 297, 297, + 297, 620, 589, 723, 297, 297 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint16 yyr1[] = +{ + 0, 296, 297, 298, 299, 299, 299, 299, 299, 299, + 299, 300, 301, 302, 303, 304, 304, 305, 306, 306, + 306, 306, 306, 306, 307, 308, 308, 309, 310, 310, + 310, 310, 310, 311, 312, 313, 313, 314, 315, 316, + 316, 316, 316, 316, 317, 318, 319, 320, 321, 322, + 323, 323, 323, 324, 325, 325, 326, 326, 327, 328, + 328, 328, 328, 329, 330, 330, 331, 332, 332, 333, + 334, 335, 336, 337, 337, 337, 337, 337, 337, 337, + 338, 339, 340, 340, 341, 342, 343, 343, 343, 344, + 345, 345, 345, 346, 346, 346, 347, 348, 348, 349, + 350, 351, 351, 352, 353, 353, 353, 353, 353, 353, + 353, 353, 354, 355, 356, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, + 356, 356, 357, 358, 358, 359, 360, 360, 360, 361, + 362, 362, 363, 364, 365, 365, 365, 366, 367, 367, + 368, 369, 369, 370, 371, 371, 372, 373, 373, 374, + 375, 375, 376, 377, 377, 378, 379, 379, 380, 381, + 381, 382, 383, 383, 383, 384, 385, 385, 385, 385, + 385, 386, 387, 387, 388, 389, 390, 390, 390, 390, + 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, + 390, 391, 392, 392, 392, 392, 393, 394, 394, 394, + 395, 396, 396, 397, 397, 398, 398, 399, 399, 400, + 401, 401, 402, 403, 403, 404, 405, 406, 406, 406, + 406, 407, 408, 408, 408, 409, 410, 410, 410, 411, + 411, 411, 411, 412, 412, 412, 413, 414, 414, 414, + 414, 414, 414, 414, 415, 416, 417, 417, 417, 417, + 417, 418, 419, 420, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, 422, 423, + 424, 425, 425, 425, 426, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 428, 429, + 429, 430, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 432, 433, 433, 433, 433, 434, 434, + 434, 434, 434, 435, 436, 436, 436, 436, 437, 438, + 438, 438, 438, 439, 440, 441, 441, 442, 442, 442, + 442, 443, 444, 444, 445, 446, 446, 446, 446, 446, + 447, 448, 449, 450, 451, 452, 452, 453, 454, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 456, + 457, 457, 457, 458, 459, 459, 459, 459, 459, 460, + 461, 461, 462, 463, 463, 463, 463, 463, 464, 464, + 465, 465, 466, 467, 467, 468, 469, 469, 469, 469, + 470, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 472, 473, + 473, 473, 473, 474, 475, 475, 475, 475, 476, 477, + 477, 477, 477, 478, 479, 479, 480, 481, 482, 482, + 482, 482, 483, 484, 484, 484, 484, 484, 484, 484, + 484, 484, 485, 486, 486, 487, 488, 489, 489, 490, + 491, 492, 493, 494, 495, 496, 496, 496, 496, 496, + 497, 498, 499, 499, 500, 501, 501, 501, 502, 503, + 503, 504, 505, 505, 506, 506, 506, 507, 507, 507, + 508, 509, 509, 509, 509, 510, 511, 511, 511, 511, + 512, 513, 513, 514, 515, 515, 516, 517, 518, 519, + 519, 519, 520, 521, 521, 521, 521, 522, 523, 523, + 523, 523, 524, 525, 525, 526, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 528, 529, 529, 529, 529, 529, 530, 531, 531, + 532, 532, 532, 533, 534, 534, 534, 535, 535, 535, + 536, 537, 537, 538, 539, 539, 539, 539, 540, 541, + 541, 542, 542, 543, 544, 544, 544, 545, 546, 546, + 547, 548, 548, 548, 548, 548, 549, 550, 550, 551, + 551, 551, 552, 552, 553, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 555, 556, 556, 556, 556, + 556, 557, 558, 558, 558, 558, 558, 558, 559, 560, + 560, 560, 561, 562, 562, 562, 563, 564, 564, 564, + 564, 564, 565, 565, 566, 566, 567, 568, 568, 568, + 568, 569, 570, 571, 571, 571, 572, 573, 573, 573, + 574, 575, 575, 575, 575, 576, 577, 577, 577, 577, + 578, 579, 579, 580, 581, 581, 581, 581, 582, 583, + 583, 583, 583, 583, 584, 585, 586, 586, 587, 588, + 588, 588, 588, 588, 588, 588, 588, 589, 590, 591, + 591, 591, 591, 592, 593, 593, 593, 593, 594, 595, + 595, 596, 597, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 600, 601, 601, 602, 603, 603, + 604, 605, 606, 606, 607, 608, 608, 609, 610, 611, + 611, 611, 611, 612, 613, 613, 614, 615, 615, 615, + 615, 616, 617, 617, 618, 619, 619, 620, 621, 622, + 622, 623, 624, 624, 624, 624, 624, 624, 624, 624, + 624, 624, 624, 624, 624, 625, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 627, 628, 628, 628, + 628, 629, 630, 630, 630, 630, 631, 632, 632, 632, + 633, 634, 634, 634, 634, 634, 634, 634, 634, 634, + 634, 634, 635, 636, 636, 636, 636, 636, 636, 636, + 636, 636, 636, 636, 636, 636, 637, 638, 638, 638, + 639, 640, 641, 641, 641, 641, 641, 642, 642, 643, + 643, 644, 645, 645, 645, 645, 646, 647, 647, 648, + 649, 649, 650, 651, 651, 651, 651, 651, 652, 653, + 654, 655, 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 656, 656, 656, 656, 656, 656, 657, + 658, 658, 658, 659, 660, 660, 661, 662, 662, 662, + 662, 663, 664, 664, 665, 665, 666, 667, 667, 668, + 669, 670, 670, 671, 672, 673, 674, 674, 674, 674, + 675, 676, 676, 677, 678, 679, 679, 679, 679, 679, + 679, 680, 681, 681, 681, 681, 682, 683, 683, 684, + 685, 685, 686, 687, 687, 688, 689, 689, 690, 691, + 691, 691, 691, 692, 693, 693, 693, 694, 694, 694, + 695, 696, 697, 697, 697, 697, 698, 698, 699, 700, + 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, + 701, 701, 701, 701, 702, 703, 703, 704, 705, 705, + 705, 706, 707, 707, 707, 707, 708, 708, 708, 709, + 710, 710, 710, 710, 710, 710, 710, 711, 712, 713, + 713, 714, 714, 714, 715, 716, 717, 717, 717, 717, + 717, 718, 719, 719, 720, 720, 721, 721, 722, 722, + 723, 723, 724, 725, 725, 725, 726, 727, 727, 727, + 727, 728, 729, 729, 729, 729, 729, 729, 730, 731, + 732, 733, 733, 733, 733, 734, 735, 735, 735, 735, + 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, + 735, 735, 736, 737, 738, 738, 738, 738, 738, 739, + 739, 740, 740, 741, 742, 743, 743, 743, 743, 743, + 743, 744, 745, 745, 745, 746, 747, 747, 747, 747, + 747, 747, 747, 747, 747, 748, 749, 750, 751, 751, + 752, 753, 753, 753, 753, 753, 753, 753, 753, 753, + 753, 754, 755, 756, 757, 758, 759, 759, 759, 759, + 760, 761, 761, 761, 761, 761, 761, 761, 762, 763, + 763, 763, 763, 763, 763, 763, 764, 765, 766, 767 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 7, 0, 2, 2, 2, 2, 2, + 2, 1, 3, 5, 3, 1, 1, 3, 1, 2, + 2, 2, 2, 2, 3, 1, 1, 3, 1, 2, + 2, 2, 2, 5, 5, 0, 1, 3, 3, 1, + 1, 1, 2, 2, 3, 3, 3, 3, 2, 3, + 1, 1, 1, 4, 1, 1, 1, 1, 3, 0, + 2, 2, 2, 3, 1, 2, 3, 1, 1, 5, + 3, 3, 4, 1, 2, 2, 2, 2, 2, 2, + 1, 4, 0, 1, 1, 3, 1, 1, 1, 4, + 1, 1, 1, 0, 1, 1, 5, 0, 2, 5, + 3, 0, 2, 3, 0, 2, 2, 2, 2, 2, + 2, 2, 3, 3, 0, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 3, 0, 1, 3, 1, 1, 1, 3, + 1, 1, 3, 3, 0, 2, 2, 4, 0, 1, + 4, 0, 1, 3, 1, 1, 3, 1, 1, 3, + 1, 1, 3, 1, 1, 3, 1, 1, 3, 0, + 2, 3, 1, 1, 1, 4, 1, 2, 2, 2, + 2, 3, 1, 1, 1, 3, 0, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 1, 1, 2, 2, 3, 1, 1, 1, + 6, 1, 1, 0, 1, 0, 1, 0, 1, 3, + 0, 2, 3, 1, 2, 3, 6, 1, 1, 2, + 2, 3, 1, 1, 1, 5, 1, 1, 1, 1, + 1, 1, 1, 0, 1, 1, 3, 1, 1, 1, + 1, 1, 2, 2, 3, 5, 1, 2, 2, 2, + 2, 4, 2, 3, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, + 3, 1, 1, 1, 3, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 4, 0, + 1, 3, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 5, 1, 1, 2, 2, 1, 1, + 1, 1, 1, 5, 1, 1, 2, 2, 5, 1, + 1, 2, 2, 5, 4, 1, 1, 1, 1, 2, + 2, 3, 1, 2, 3, 0, 2, 2, 2, 2, + 3, 3, 4, 2, 3, 1, 1, 2, 4, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 4, + 0, 1, 1, 3, 1, 2, 2, 2, 2, 3, + 0, 2, 3, 0, 2, 2, 2, 2, 1, 1, + 1, 1, 3, 1, 2, 3, 0, 2, 2, 2, + 3, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 6, 1, + 1, 2, 2, 3, 1, 1, 2, 2, 5, 1, + 1, 2, 2, 3, 1, 1, 2, 3, 0, 2, + 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 1, 2, 3, 3, 1, 2, 1, + 1, 3, 1, 1, 5, 1, 2, 2, 2, 2, + 3, 3, 0, 2, 3, 0, 2, 2, 4, 1, + 1, 5, 1, 1, 1, 1, 1, 0, 1, 1, + 3, 1, 1, 1, 2, 3, 0, 2, 2, 2, + 3, 0, 2, 3, 0, 2, 1, 1, 3, 0, + 2, 2, 3, 1, 1, 1, 2, 3, 1, 2, + 2, 2, 4, 0, 1, 3, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 0, 2, 2, 2, 2, 4, 1, 1, + 0, 1, 1, 4, 1, 1, 1, 1, 1, 1, + 4, 1, 2, 3, 0, 2, 2, 2, 3, 1, + 2, 1, 1, 5, 1, 1, 1, 3, 0, 2, + 3, 0, 2, 2, 2, 2, 3, 1, 2, 1, + 1, 1, 1, 1, 4, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 1, 2, 2, 2, + 2, 4, 1, 2, 2, 2, 2, 2, 4, 1, + 2, 2, 3, 0, 2, 2, 3, 0, 2, 2, + 2, 2, 1, 1, 1, 1, 4, 0, 1, 1, + 1, 2, 3, 0, 2, 2, 4, 1, 2, 2, + 5, 1, 1, 2, 2, 3, 0, 2, 2, 2, + 3, 1, 2, 3, 0, 2, 2, 2, 3, 1, + 2, 2, 2, 2, 4, 3, 1, 2, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 6, 1, + 1, 2, 2, 6, 1, 1, 2, 2, 5, 1, + 1, 3, 3, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 3, 3, 1, 2, 5, 0, 1, + 4, 3, 1, 2, 3, 1, 2, 3, 3, 0, + 2, 2, 2, 3, 0, 2, 3, 0, 2, 2, + 2, 3, 1, 2, 3, 0, 2, 4, 3, 1, + 2, 3, 1, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 4, 1, 2, 2, + 2, 4, 1, 1, 2, 2, 3, 0, 2, 2, + 3, 1, 1, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 3, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 0, 2, 2, + 4, 3, 0, 2, 2, 2, 2, 1, 1, 1, + 1, 4, 0, 1, 1, 1, 4, 0, 1, 3, + 1, 2, 4, 1, 2, 2, 2, 2, 1, 1, + 3, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 1, 1, 1, 1, 1, 1, 3, + 0, 2, 2, 4, 1, 2, 5, 1, 1, 2, + 2, 4, 1, 1, 1, 1, 3, 0, 2, 1, + 5, 1, 4, 4, 4, 3, 1, 2, 2, 2, + 3, 1, 2, 1, 3, 1, 2, 2, 2, 2, + 2, 3, 0, 2, 2, 2, 3, 0, 1, 4, + 0, 1, 3, 0, 1, 3, 1, 2, 3, 0, + 2, 2, 2, 4, 1, 1, 1, 1, 2, 2, + 3, 3, 0, 2, 2, 2, 1, 2, 3, 3, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 3, 0, 2, 3, 0, 2, + 2, 4, 1, 1, 1, 1, 0, 1, 1, 3, + 1, 2, 2, 2, 2, 2, 2, 3, 4, 1, + 1, 1, 1, 1, 8, 3, 1, 2, 2, 2, + 2, 7, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 4, 1, 1, 1, 3, 0, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, + 3, 1, 1, 2, 2, 3, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 3, 1, 2, 2, 2, 2, 1, + 1, 1, 1, 3, 5, 1, 2, 2, 2, 2, + 2, 3, 0, 2, 2, 3, 0, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 1, 4, 0, 1, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 3, 5, 3, 3, 0, 2, 2, 2, + 3, 1, 2, 2, 2, 2, 2, 2, 3, 1, + 2, 2, 2, 2, 2, 2, 1, 1, 1, 1 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +{ + FILE *yyoutput = yyo; + YYUSE (yyoutput); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); +# endif + YYUSE (yytype); +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyo, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyo, yytype, yyvaluep); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +{ + unsigned long yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &yyvsp[(yyi + 1) - (yynrhs)] + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +yystrlen (const char *yystr) +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +{ + YYUSE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + *yyssp = (yytype_int16) yystate; + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 508 "edif.y" /* yacc.c:1652 */ + { PopC(); } +#line 3378 "edif.c" /* yacc.c:1652 */ + break; + + case 11: +#line 523 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3384 "edif.c" /* yacc.c:1652 */ + break; + + case 12: +#line 526 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-1].s)); } +#line 3390 "edif.c" /* yacc.c:1652 */ + break; + + case 13: +#line 530 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-3].s)); free((yyvsp[-2].s)); free((yyvsp[-1].s)); } +#line 3396 "edif.c" /* yacc.c:1652 */ + break; + + case 25: +#line 554 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3402 "edif.c" /* yacc.c:1652 */ + break; + + case 34: +#line 571 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[-3].ps)); free((yyvsp[-2].s)); } +#line 3408 "edif.c" /* yacc.c:1652 */ + break; + + case 36: +#line 575 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3414 "edif.c" /* yacc.c:1652 */ + break; + + case 47: +#line 600 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-1].s)); } +#line 3420 "edif.c" /* yacc.c:1652 */ + break; + + case 69: +#line 648 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-3].s)); free((yyvsp[-2].s)); } +#line 3426 "edif.c" /* yacc.c:1652 */ + break; + + case 70: +#line 651 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-1].s)); } +#line 3432 "edif.c" /* yacc.c:1652 */ + break; + + case 80: +#line 669 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3438 "edif.c" /* yacc.c:1652 */ + break; + + case 84: +#line 679 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3444 "edif.c" /* yacc.c:1652 */ + break; + + case 91: +#line 694 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3450 "edif.c" /* yacc.c:1652 */ + break; + + case 102: +#line 717 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3456 "edif.c" /* yacc.c:1652 */ + break; + + case 140: +#line 777 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3462 "edif.c" /* yacc.c:1652 */ + break; + + case 147: +#line 792 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-2].s)); } +#line 3468 "edif.c" /* yacc.c:1652 */ + break; + + case 150: +#line 799 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-2].s)); } +#line 3474 "edif.c" /* yacc.c:1652 */ + break; + + case 182: +#line 869 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3480 "edif.c" /* yacc.c:1652 */ + break; + + case 184: +#line 873 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3486 "edif.c" /* yacc.c:1652 */ + break; + + case 240: +#line 977 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3492 "edif.c" /* yacc.c:1652 */ + break; + + case 247: +#line 990 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3498 "edif.c" /* yacc.c:1652 */ + break; + + case 278: +#line 1037 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3504 "edif.c" /* yacc.c:1652 */ + break; + + case 279: +#line 1040 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3510 "edif.c" /* yacc.c:1652 */ + break; + + case 333: +#line 1126 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-3].s)); free((yyvsp[-2].s)); } +#line 3516 "edif.c" /* yacc.c:1652 */ + break; + + case 336: +#line 1133 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3522 "edif.c" /* yacc.c:1652 */ + break; + + case 337: +#line 1136 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3528 "edif.c" /* yacc.c:1652 */ + break; + + case 344: +#line 1149 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-2].s)); } +#line 3534 "edif.c" /* yacc.c:1652 */ + break; + + case 346: +#line 1153 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3540 "edif.c" /* yacc.c:1652 */ + break; + + case 347: +#line 1154 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3546 "edif.c" /* yacc.c:1652 */ + break; + + case 348: +#line 1155 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3552 "edif.c" /* yacc.c:1652 */ + break; + + case 369: +#line 1196 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[-2].s); } +#line 3558 "edif.c" /* yacc.c:1652 */ + break; + + case 371: +#line 1200 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3564 "edif.c" /* yacc.c:1652 */ + break; + + case 374: +#line 1207 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3570 "edif.c" /* yacc.c:1652 */ + break; + + case 381: +#line 1218 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3576 "edif.c" /* yacc.c:1652 */ + break; + + case 384: +#line 1225 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3582 "edif.c" /* yacc.c:1652 */ + break; + + case 388: +#line 1231 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3588 "edif.c" /* yacc.c:1652 */ + break; + + case 390: +#line 1235 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 3594 "edif.c" /* yacc.c:1652 */ + break; + + case 393: +#line 1242 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3600 "edif.c" /* yacc.c:1652 */ + break; + + case 397: +#line 1250 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3606 "edif.c" /* yacc.c:1652 */ + break; + + case 408: +#line 1265 "edif.y" /* yacc.c:1652 */ + { pair_list_free((yyvsp[0].pl)); } +#line 3612 "edif.c" /* yacc.c:1652 */ + break; + + case 437: +#line 1315 "edif.y" /* yacc.c:1652 */ + { (yyval.pl) = new_pair_list((yyvsp[-1].ps)); } +#line 3618 "edif.c" /* yacc.c:1652 */ + break; + + case 438: +#line 1318 "edif.y" /* yacc.c:1652 */ + { (yyval.ps)=NULL; } +#line 3624 "edif.c" /* yacc.c:1652 */ + break; + + case 439: +#line 1319 "edif.y" /* yacc.c:1652 */ + { (yyvsp[0].ps)->next = (yyvsp[-1].ps); (yyval.ps) = (yyvsp[0].ps); } +#line 3630 "edif.c" /* yacc.c:1652 */ + break; + + case 455: +#line 1345 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-1].s)); } +#line 3636 "edif.c" /* yacc.c:1652 */ + break; + + case 459: +#line 1355 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3642 "edif.c" /* yacc.c:1652 */ + break; + + case 460: +#line 1358 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3648 "edif.c" /* yacc.c:1652 */ + break; + + case 462: +#line 1364 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3654 "edif.c" /* yacc.c:1652 */ + break; + + case 463: +#line 1367 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3660 "edif.c" /* yacc.c:1652 */ + break; + + case 483: +#line 1409 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3666 "edif.c" /* yacc.c:1652 */ + break; + + case 484: +#line 1412 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3672 "edif.c" /* yacc.c:1652 */ + break; + + case 492: +#line 1426 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3678 "edif.c" /* yacc.c:1652 */ + break; + + case 506: +#line 1454 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3684 "edif.c" /* yacc.c:1652 */ + break; + + case 507: +#line 1457 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3690 "edif.c" /* yacc.c:1652 */ + break; + + case 514: +#line 1472 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3696 "edif.c" /* yacc.c:1652 */ + break; + + case 549: +#line 1527 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3702 "edif.c" /* yacc.c:1652 */ + break; + + case 555: +#line 1539 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3708 "edif.c" /* yacc.c:1652 */ + break; + + case 560: +#line 1548 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-2].s)); } +#line 3714 "edif.c" /* yacc.c:1652 */ + break; + + case 561: +#line 1551 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3720 "edif.c" /* yacc.c:1652 */ + break; + + case 562: +#line 1552 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3726 "edif.c" /* yacc.c:1652 */ + break; + + case 582: +#line 1594 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3732 "edif.c" /* yacc.c:1652 */ + break; + + case 585: +#line 1597 "edif.y" /* yacc.c:1652 */ + { pair_list_free((yyvsp[0].pl)); } +#line 3738 "edif.c" /* yacc.c:1652 */ + break; + + case 586: +#line 1600 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[-1].s); } +#line 3744 "edif.c" /* yacc.c:1652 */ + break; + + case 587: +#line 1603 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 3750 "edif.c" /* yacc.c:1652 */ + break; + + case 589: +#line 1607 "edif.y" /* yacc.c:1652 */ + { (yyval.ps) = new_str_pair((yyvsp[0].s),NULL); } +#line 3756 "edif.c" /* yacc.c:1652 */ + break; + + case 590: +#line 1608 "edif.y" /* yacc.c:1652 */ + { (yyval.ps) = new_str_pair((yyvsp[0].s),NULL); } +#line 3762 "edif.c" /* yacc.c:1652 */ + break; + + case 591: +#line 1609 "edif.y" /* yacc.c:1652 */ + { (yyval.ps)=(yyvsp[0].ps); } +#line 3768 "edif.c" /* yacc.c:1652 */ + break; + + case 592: +#line 1612 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 3774 "edif.c" /* yacc.c:1652 */ + break; + + case 593: +#line 1613 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 3780 "edif.c" /* yacc.c:1652 */ + break; + + case 594: +#line 1616 "edif.y" /* yacc.c:1652 */ + { define_pcb_net((yyvsp[-2].ps), (yyvsp[-1].pl)); } +#line 3786 "edif.c" /* yacc.c:1652 */ + break; + + case 595: +#line 1619 "edif.y" /* yacc.c:1652 */ + { (yyval.pl)=(yyvsp[0].pl); } +#line 3792 "edif.c" /* yacc.c:1652 */ + break; + + case 611: +#line 1641 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[-2].ps)); } +#line 3798 "edif.c" /* yacc.c:1652 */ + break; + + case 632: +#line 1678 "edif.y" /* yacc.c:1652 */ + { (yyval.ps)=(yyvsp[0].ps); } +#line 3804 "edif.c" /* yacc.c:1652 */ + break; + + case 633: +#line 1679 "edif.y" /* yacc.c:1652 */ + { (yyval.ps)=NULL; } +#line 3810 "edif.c" /* yacc.c:1652 */ + break; + + case 634: +#line 1683 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3816 "edif.c" /* yacc.c:1652 */ + break; + + case 639: +#line 1692 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3822 "edif.c" /* yacc.c:1652 */ + break; + + case 644: +#line 1703 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3828 "edif.c" /* yacc.c:1652 */ + break; + + case 698: +#line 1805 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-3].s)); } +#line 3834 "edif.c" /* yacc.c:1652 */ + break; + + case 701: +#line 1812 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-1].s)); } +#line 3840 "edif.c" /* yacc.c:1652 */ + break; + + case 727: +#line 1864 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-1].s)); } +#line 3846 "edif.c" /* yacc.c:1652 */ + break; + + case 730: +#line 1871 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3852 "edif.c" /* yacc.c:1652 */ + break; + + case 747: +#line 1906 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-2].s)); free((yyvsp[-1].s)); } +#line 3858 "edif.c" /* yacc.c:1652 */ + break; + + case 766: +#line 1937 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3864 "edif.c" /* yacc.c:1652 */ + break; + + case 789: +#line 1972 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3870 "edif.c" /* yacc.c:1652 */ + break; + + case 791: +#line 1978 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3876 "edif.c" /* yacc.c:1652 */ + break; + + case 803: +#line 1994 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3882 "edif.c" /* yacc.c:1652 */ + break; + + case 818: +#line 2013 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3888 "edif.c" /* yacc.c:1652 */ + break; + + case 823: +#line 2024 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3894 "edif.c" /* yacc.c:1652 */ + break; + + case 827: +#line 2030 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3900 "edif.c" /* yacc.c:1652 */ + break; + + case 829: +#line 2034 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 3906 "edif.c" /* yacc.c:1652 */ + break; + + case 831: +#line 2039 "edif.y" /* yacc.c:1652 */ + { + if ((yyvsp[-1].ps)) + { + (yyval.ps) = new_str_pair((yyvsp[-1].ps)->str1,(yyvsp[-2].s)); + free((yyvsp[-1].ps)); + } + else + { + /* handle port with no instance by passing up the chain */ + (yyval.ps) = new_str_pair(NULL,(yyvsp[-2].s)); + } +} +#line 3923 "edif.c" /* yacc.c:1652 */ + break; + + case 832: +#line 2053 "edif.y" /* yacc.c:1652 */ + { (yyval.ps)=NULL; } +#line 3929 "edif.c" /* yacc.c:1652 */ + break; + + case 833: +#line 2054 "edif.y" /* yacc.c:1652 */ + { (yyval.ps)=(yyvsp[0].ps); } +#line 3935 "edif.c" /* yacc.c:1652 */ + break; + + case 834: +#line 2055 "edif.y" /* yacc.c:1652 */ + { (yyval.ps) = new_str_pair((yyvsp[0].s),NULL); } +#line 3941 "edif.c" /* yacc.c:1652 */ + break; + + case 835: +#line 2056 "edif.y" /* yacc.c:1652 */ + { (yyval.ps)=NULL; } +#line 3947 "edif.c" /* yacc.c:1652 */ + break; + + case 848: +#line 2083 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3953 "edif.c" /* yacc.c:1652 */ + break; + + case 849: +#line 2086 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 3959 "edif.c" /* yacc.c:1652 */ + break; + + case 881: +#line 2139 "edif.y" /* yacc.c:1652 */ + { (yyval.ps) = new_str_pair((yyvsp[-2].s),(yyvsp[-1].s)); } +#line 3965 "edif.c" /* yacc.c:1652 */ + break; + + case 882: +#line 2142 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 3971 "edif.c" /* yacc.c:1652 */ + break; + + case 883: +#line 2143 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 3977 "edif.c" /* yacc.c:1652 */ + break; + + case 884: +#line 2146 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 3983 "edif.c" /* yacc.c:1652 */ + break; + + case 885: +#line 2147 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=NULL; } +#line 3989 "edif.c" /* yacc.c:1652 */ + break; + + case 889: +#line 2157 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 3995 "edif.c" /* yacc.c:1652 */ + break; + + case 891: +#line 2163 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 4001 "edif.c" /* yacc.c:1652 */ + break; + + case 892: +#line 2164 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-2].s)); free((yyvsp[-1].s)); } +#line 4007 "edif.c" /* yacc.c:1652 */ + break; + + case 893: +#line 2167 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-2].s)); free((yyvsp[-1].s)); } +#line 4013 "edif.c" /* yacc.c:1652 */ + break; + + case 894: +#line 2170 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-2].s)); free((yyvsp[-1].s)); } +#line 4019 "edif.c" /* yacc.c:1652 */ + break; + + case 896: +#line 2176 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 4025 "edif.c" /* yacc.c:1652 */ + break; + + case 898: +#line 2178 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 4031 "edif.c" /* yacc.c:1652 */ + break; + + case 903: +#line 2189 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 4037 "edif.c" /* yacc.c:1652 */ + break; + + case 935: +#line 2253 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 4043 "edif.c" /* yacc.c:1652 */ + break; + + case 943: +#line 2269 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 4049 "edif.c" /* yacc.c:1652 */ + break; + + case 946: +#line 2274 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 4055 "edif.c" /* yacc.c:1652 */ + break; + + case 973: +#line 2319 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 4061 "edif.c" /* yacc.c:1652 */ + break; + + case 987: +#line 2341 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-1].s)); } +#line 4067 "edif.c" /* yacc.c:1652 */ + break; + + case 994: +#line 2357 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-6].s)); free((yyvsp[-5].s)); free((yyvsp[-4].s)); free((yyvsp[-3].s)); free((yyvsp[-2].s)); free((yyvsp[-1].s)); } +#line 4073 "edif.c" /* yacc.c:1652 */ + break; + + case 1054: +#line 2464 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 4079 "edif.c" /* yacc.c:1652 */ + break; + + case 1055: +#line 2465 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 4085 "edif.c" /* yacc.c:1652 */ + break; + + case 1056: +#line 2466 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 4091 "edif.c" /* yacc.c:1652 */ + break; + + case 1057: +#line 2467 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 4097 "edif.c" /* yacc.c:1652 */ + break; + + case 1059: +#line 2471 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 4103 "edif.c" /* yacc.c:1652 */ + break; + + case 1061: +#line 2475 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 4109 "edif.c" /* yacc.c:1652 */ + break; + + case 1063: +#line 2479 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[-1].s)); } +#line 4115 "edif.c" /* yacc.c:1652 */ + break; + + case 1085: +#line 2515 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 4121 "edif.c" /* yacc.c:1652 */ + break; + + case 1086: +#line 2518 "edif.y" /* yacc.c:1652 */ + { free((yyvsp[0].s)); } +#line 4127 "edif.c" /* yacc.c:1652 */ + break; + + case 1107: +#line 2559 "edif.y" /* yacc.c:1652 */ + { str_pair_free((yyvsp[0].ps)); } +#line 4133 "edif.c" /* yacc.c:1652 */ + break; + + case 1109: +#line 2561 "edif.y" /* yacc.c:1652 */ + { pair_list_free((yyvsp[0].pl)); } +#line 4139 "edif.c" /* yacc.c:1652 */ + break; + + case 1126: +#line 2588 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 4145 "edif.c" /* yacc.c:1652 */ + break; + + case 1127: +#line 2591 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 4151 "edif.c" /* yacc.c:1652 */ + break; + + case 1128: +#line 2594 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 4157 "edif.c" /* yacc.c:1652 */ + break; + + case 1129: +#line 2597 "edif.y" /* yacc.c:1652 */ + { (yyval.s)=(yyvsp[0].s); } +#line 4163 "edif.c" /* yacc.c:1652 */ + break; + + +#line 4167 "edif.c" /* yacc.c:1652 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} +#line 2600 "edif.y" /* yacc.c:1918 */ + +/* + * xmalloc: + * + * Garbage function for 'alloca()'. + */ +char *xmalloc(int siz) +{ + return ((char *)Malloc(siz)); +} +/* + * Token & context carriers: + * + * These are the linkage pointers for threading this context garbage + * for converting identifiers into parser tokens. + */ +typedef struct TokenCar { + struct TokenCar *Next; /* pointer to next carrier */ + struct Token *Token; /* associated token */ +} TokenCar; +typedef struct UsedCar { + struct UsedCar *Next; /* pointer to next carrier */ + short Code; /* used '%token' value */ +} UsedCar; +typedef struct ContextCar { + struct ContextCar *Next; /* pointer to next carrier */ + struct Context *Context; /* associated context */ + union { + int Single; /* single usage flag (context tree) */ + struct UsedCar *Used; /* single used list (context stack) */ + } u; +} ContextCar; +/* + * Token definitions: + * + * This associates the '%token' codings with strings which are to + * be free standing tokens. Doesn't have to be in sorted order but the + * strings must be in lower case. + */ +typedef struct Token { + const char *Name; /* token name */ + int Code; /* '%token' value */ + struct Token *Next; /* hash table linkage */ +} Token; +static Token TokenDef[] = { + {"angle", EDIF_TOK_ANGLE}, + {"behavior", EDIF_TOK_BEHAVIOR}, + {"calculated", EDIF_TOK_CALCULATED}, + {"capacitance", EDIF_TOK_CAPACITANCE}, + {"centercenter", EDIF_TOK_CENTERCENTER}, + {"centerleft", EDIF_TOK_CENTERLEFT}, + {"centerright", EDIF_TOK_CENTERRIGHT}, + {"charge", EDIF_TOK_CHARGE}, + {"conductance", EDIF_TOK_CONDUCTANCE}, + {"current", EDIF_TOK_CURRENT}, + {"distance", EDIF_TOK_DISTANCE}, + {"document", EDIF_TOK_DOCUMENT}, + {"energy", EDIF_TOK_ENERGY}, + {"extend", EDIF_TOK_EXTEND}, + {"flux", EDIF_TOK_FLUX}, + {"frequency", EDIF_TOK_FREQUENCY}, + {"generic", EDIF_TOK_GENERIC}, + {"graphic", EDIF_TOK_GRAPHIC}, + {"inductance", EDIF_TOK_INDUCTANCE}, + {"inout", EDIF_TOK_INOUT}, + {"input", EDIF_TOK_INPUT}, + {"logicmodel", EDIF_TOK_LOGICMODEL}, + {"lowercenter", EDIF_TOK_LOWERCENTER}, + {"lowerleft", EDIF_TOK_LOWERLEFT}, + {"lowerright", EDIF_TOK_LOWERRIGHT}, + {"masklayout", EDIF_TOK_MASKLAYOUT}, + {"mass", EDIF_TOK_MASS}, + {"measured", EDIF_TOK_MEASURED}, + {"mx", EDIF_TOK_MX}, + {"mxr90", EDIF_TOK_MXR90}, + {"my", EDIF_TOK_MY}, + {"myr90", EDIF_TOK_MYR90}, + {"netlist", EDIF_TOK_NETLIST}, + {"output", EDIF_TOK_OUTPUT}, + {"pcblayout", EDIF_TOK_PCBLAYOUT}, + {"power", EDIF_TOK_POWER}, + {"r0", EDIF_TOK_R0}, + {"r180", EDIF_TOK_R180}, + {"r270", EDIF_TOK_R270}, + {"r90", EDIF_TOK_R90}, + {"required", EDIF_TOK_REQUIRED}, + {"resistance", EDIF_TOK_RESISTANCE}, + {"ripper", EDIF_TOK_RIPPER}, + {"round", EDIF_TOK_ROUND}, + {"schematic", EDIF_TOK_SCHEMATIC}, + {"stranger", EDIF_TOK_STRANGER}, + {"symbolic", EDIF_TOK_SYMBOLIC}, + {"temperature", EDIF_TOK_TEMPERATURE}, + {"tie", EDIF_TOK_TIE}, + {"time", EDIF_TOK_TIME}, + {"truncate", EDIF_TOK_TRUNCATE}, + {"uppercenter", EDIF_TOK_UPPERCENTER}, + {"upperleft", EDIF_TOK_UPPERLEFT}, + {"upperright", EDIF_TOK_UPPERRIGHT}, + {"voltage", EDIF_TOK_VOLTAGE} +}; +static int TokenDefSize = sizeof(TokenDef) / sizeof(Token); +/* + * Token enable definitions: + * + * There is one array for each set of tokens enabled by a + * particular context (barf). Another array is used to bind + * these arrays to a context. + */ +static short e_CellType[] = {EDIF_TOK_TIE, EDIF_TOK_RIPPER, EDIF_TOK_GENERIC}; +static short e_CornerType[] = {EDIF_TOK_EXTEND, EDIF_TOK_TRUNCATE, + EDIF_TOK_ROUND}; +static short e_Derivation[] = {EDIF_TOK_CALCULATED, EDIF_TOK_MEASURED, + EDIF_TOK_REQUIRED}; +static short e_Direction[] = {EDIF_TOK_INPUT, EDIF_TOK_OUTPUT, + EDIF_TOK_INOUT}; +static short e_EndType[] = {EDIF_TOK_EXTEND, EDIF_TOK_TRUNCATE, + EDIF_TOK_ROUND}; +static short e_Justify[] = {EDIF_TOK_CENTERCENTER, EDIF_TOK_CENTERLEFT, + EDIF_TOK_CENTERRIGHT, EDIF_TOK_LOWERCENTER, + EDIF_TOK_LOWERLEFT, EDIF_TOK_LOWERRIGHT, + EDIF_TOK_UPPERCENTER, EDIF_TOK_UPPERLEFT, + EDIF_TOK_UPPERRIGHT}; +static short e_Orientation[] = {EDIF_TOK_R0, EDIF_TOK_R90, EDIF_TOK_R180, + EDIF_TOK_R270, EDIF_TOK_MX, EDIF_TOK_MY, + EDIF_TOK_MXR90, EDIF_TOK_MYR90}; +static short e_Unit[] = {EDIF_TOK_DISTANCE, EDIF_TOK_CAPACITANCE, + EDIF_TOK_CURRENT, EDIF_TOK_RESISTANCE, + EDIF_TOK_TEMPERATURE, EDIF_TOK_TIME, + EDIF_TOK_VOLTAGE, EDIF_TOK_MASS, EDIF_TOK_FREQUENCY, + EDIF_TOK_INDUCTANCE, EDIF_TOK_ENERGY, + EDIF_TOK_POWER, EDIF_TOK_CHARGE, + EDIF_TOK_CONDUCTANCE, EDIF_TOK_FLUX, EDIF_TOK_ANGLE}; +static short e_ViewType[] = {EDIF_TOK_MASKLAYOUT, EDIF_TOK_PCBLAYOUT, + EDIF_TOK_NETLIST, EDIF_TOK_SCHEMATIC, + EDIF_TOK_SYMBOLIC, EDIF_TOK_BEHAVIOR, + EDIF_TOK_LOGICMODEL, EDIF_TOK_DOCUMENT, + EDIF_TOK_GRAPHIC, EDIF_TOK_STRANGER}; +/* + * Token tying table: + * + * This binds enabled tokens to a context. + */ +typedef struct Tie { + short *Enable; /* pointer to enable array */ + short Origin; /* '%token' value of context */ + short EnableSize; /* size of enabled array */ +} Tie; +#define TE(e,o) {e,o,sizeof(e)/sizeof(short)} +static Tie TieDef[] = { + TE(e_CellType, EDIF_TOK_CELLTYPE), + TE(e_CornerType, EDIF_TOK_CORNERTYPE), + TE(e_Derivation, EDIF_TOK_DERIVATION), + TE(e_Direction, EDIF_TOK_DIRECTION), + TE(e_EndType, EDIF_TOK_ENDTYPE), + TE(e_Justify, EDIF_TOK_JUSTIFY), + TE(e_Orientation, EDIF_TOK_ORIENTATION), + TE(e_Unit, EDIF_TOK_UNIT), + TE(e_ViewType, EDIF_TOK_VIEWTYPE) +}; +static int TieDefSize = sizeof(TieDef) / sizeof(Tie); +/* + * Context definitions: + * + * This associates keyword strings with '%token' values. It + * also creates a pretty much empty header for later building of + * the context tree. Again they needn't be sorted, but strings + * must be lower case. + */ +typedef struct Context { + const char *Name; /* keyword name */ + short Code; /* '%token' value */ + short Flags; /* special operation flags */ + struct ContextCar *Context; /* contexts which can be moved to */ + struct TokenCar *Token; /* active tokens */ + struct Context *Next; /* hash table linkage */ +} Context; +static Context ContextDef[] = { + {"", 0}, /* start context */ + {"acload", EDIF_TOK_ACLOAD}, + {"after", EDIF_TOK_AFTER}, + {"annotate", EDIF_TOK_ANNOTATE}, + {"apply", EDIF_TOK_APPLY}, + {"arc", EDIF_TOK_ARC}, + {"array", EDIF_TOK_ARRAY}, + {"arraymacro", EDIF_TOK_ARRAYMACRO}, + {"arrayrelatedinfo", EDIF_TOK_ARRAYRELATEDINFO}, + {"arraysite", EDIF_TOK_ARRAYSITE}, + {"atleast", EDIF_TOK_ATLEAST}, + {"atmost", EDIF_TOK_ATMOST}, + {"author", EDIF_TOK_AUTHOR}, + {"basearray", EDIF_TOK_BASEARRAY}, + {"becomes", EDIF_TOK_BECOMES}, + {"between", EDIF_TOK_BETWEEN}, + {"boolean", EDIF_TOK_BOOLEAN}, + {"booleandisplay", EDIF_TOK_BOOLEANDISPLAY}, + {"booleanmap", EDIF_TOK_BOOLEANMAP}, + {"borderpattern", EDIF_TOK_BORDERPATTERN}, + {"borderwidth", EDIF_TOK_BORDERWIDTH}, + {"boundingbox", EDIF_TOK_BOUNDINGBOX}, + {"cell", EDIF_TOK_CELL}, + {"cellref", EDIF_TOK_CELLREF}, + {"celltype", EDIF_TOK_CELLTYPE}, + {"change", EDIF_TOK_CHANGE}, + {"circle", EDIF_TOK_CIRCLE}, + {"color", EDIF_TOK_COLOR}, + {"comment", EDIF_TOK_COMMENT}, + {"commentgraphics", EDIF_TOK_COMMENTGRAPHICS}, + {"compound", EDIF_TOK_COMPOUND}, + {"connectlocation", EDIF_TOK_CONNECTLOCATION}, + {"contents", EDIF_TOK_CONTENTS}, + {"cornertype", EDIF_TOK_CORNERTYPE}, + {"criticality", EDIF_TOK_CRITICALITY}, + {"currentmap", EDIF_TOK_CURRENTMAP}, + {"curve", EDIF_TOK_CURVE}, + {"cycle", EDIF_TOK_CYCLE}, + {"dataorigin", EDIF_TOK_DATAORIGIN}, + {"dcfaninload", EDIF_TOK_DCFANINLOAD}, + {"dcfanoutload", EDIF_TOK_DCFANOUTLOAD}, + {"dcmaxfanin", EDIF_TOK_DCMAXFANIN}, + {"dcmaxfanout", EDIF_TOK_DCMAXFANOUT}, + {"delay", EDIF_TOK_DELAY}, + {"delta", EDIF_TOK_DELTA}, + {"derivation", EDIF_TOK_DERIVATION}, + {"design", EDIF_TOK_DESIGN}, + {"designator", EDIF_TOK_DESIGNATOR}, + {"difference", EDIF_TOK_DIFFERENCE}, + {"direction", EDIF_TOK_DIRECTION}, + {"display", EDIF_TOK_DISPLAY}, + {"dominates", EDIF_TOK_DOMINATES}, + {"dot", EDIF_TOK_DOT}, + {"duration", EDIF_TOK_DURATION}, + {"e", EDIF_TOK_E}, + {"edif", EDIF_TOK_EDIF}, + {"ediflevel", EDIF_TOK_EDIFLEVEL}, + {"edifversion", EDIF_TOK_EDIFVERSION}, + {"enclosuredistance", EDIF_TOK_ENCLOSUREDISTANCE}, + {"endtype", EDIF_TOK_ENDTYPE}, + {"entry", EDIF_TOK_ENTRY}, + {"exactly", EDIF_TOK_EXACTLY}, + {"external", EDIF_TOK_EXTERNAL}, + {"fabricate", EDIF_TOK_FABRICATE}, + {"false", EDIF_TOK_FALSE}, + {"figure", EDIF_TOK_FIGURE}, + {"figurearea", EDIF_TOK_FIGUREAREA}, + {"figuregroup", EDIF_TOK_FIGUREGROUP}, + {"figuregroupobject", EDIF_TOK_FIGUREGROUPOBJECT}, + {"figuregroupoverride", EDIF_TOK_FIGUREGROUPOVERRIDE}, + {"figuregroupref", EDIF_TOK_FIGUREGROUPREF}, + {"figureperimeter", EDIF_TOK_FIGUREPERIMETER}, + {"figurewidth", EDIF_TOK_FIGUREWIDTH}, + {"fillpattern", EDIF_TOK_FILLPATTERN}, + {"follow", EDIF_TOK_FOLLOW}, + {"forbiddenevent", EDIF_TOK_FORBIDDENEVENT}, + {"globalportref", EDIF_TOK_GLOBALPORTREF}, + {"greaterthan", EDIF_TOK_GREATERTHAN}, + {"gridmap", EDIF_TOK_GRIDMAP}, + {"ignore", EDIF_TOK_IGNORE}, + {"includefiguregroup", EDIF_TOK_INCLUDEFIGUREGROUP}, + {"initial", EDIF_TOK_INITIAL}, + {"instance", EDIF_TOK_INSTANCE}, + {"instancebackannotate", EDIF_TOK_INSTANCEBACKANNOTATE}, + {"instancegroup", EDIF_TOK_INSTANCEGROUP}, + {"instancemap", EDIF_TOK_INSTANCEMAP}, + {"instanceref", EDIF_TOK_INSTANCEREF}, + {"integer", EDIF_TOK_INTEGER}, + {"integerdisplay", EDIF_TOK_INTEGERDISPLAY}, + {"interface", EDIF_TOK_INTERFACE}, + {"interfiguregroupspacing", EDIF_TOK_INTERFIGUREGROUPSPACING}, + {"intersection", EDIF_TOK_INTERSECTION}, + {"intrafiguregroupspacing", EDIF_TOK_INTRAFIGUREGROUPSPACING}, + {"inverse", EDIF_TOK_INVERSE}, + {"isolated", EDIF_TOK_ISOLATED}, + {"joined", EDIF_TOK_JOINED}, + {"justify", EDIF_TOK_JUSTIFY}, + {"keyworddisplay", EDIF_TOK_KEYWORDDISPLAY}, + {"keywordlevel", EDIF_TOK_KEYWORDLEVEL}, + {"keywordmap", EDIF_TOK_KEYWORDMAP}, + {"lessthan", EDIF_TOK_LESSTHAN}, + {"library", EDIF_TOK_LIBRARY}, + {"libraryref", EDIF_TOK_LIBRARYREF}, + {"listofnets", EDIF_TOK_LISTOFNETS}, + {"listofports", EDIF_TOK_LISTOFPORTS}, + {"loaddelay", EDIF_TOK_LOADDELAY}, + {"logicassign", EDIF_TOK_LOGICASSIGN}, + {"logicinput", EDIF_TOK_LOGICINPUT}, + {"logiclist", EDIF_TOK_LOGICLIST}, + {"logicmapinput", EDIF_TOK_LOGICMAPINPUT}, + {"logicmapoutput", EDIF_TOK_LOGICMAPOUTPUT}, + {"logiconeof", EDIF_TOK_LOGICONEOF}, + {"logicoutput", EDIF_TOK_LOGICOUTPUT}, + {"logicport", EDIF_TOK_LOGICPORT}, + {"logicref", EDIF_TOK_LOGICREF}, + {"logicvalue", EDIF_TOK_LOGICVALUE}, + {"logicwaveform", EDIF_TOK_LOGICWAVEFORM}, + {"maintain", EDIF_TOK_MAINTAIN}, + {"match", EDIF_TOK_MATCH}, + {"member", EDIF_TOK_MEMBER}, + {"minomax", EDIF_TOK_MINOMAX}, + {"minomaxdisplay", EDIF_TOK_MINOMAXDISPLAY}, + {"mnm", EDIF_TOK_MNM}, + {"multiplevalueset", EDIF_TOK_MULTIPLEVALUESET}, + {"mustjoin", EDIF_TOK_MUSTJOIN}, + {"name", EDIF_TOK_NAME}, + {"net", EDIF_TOK_NET}, + {"netbackannotate", EDIF_TOK_NETBACKANNOTATE}, + {"netbundle", EDIF_TOK_NETBUNDLE}, + {"netdelay", EDIF_TOK_NETDELAY}, + {"netgroup", EDIF_TOK_NETGROUP}, + {"netmap", EDIF_TOK_NETMAP}, + {"netref", EDIF_TOK_NETREF}, + {"nochange", EDIF_TOK_NOCHANGE}, + {"nonpermutable", EDIF_TOK_NONPERMUTABLE}, + {"notallowed", EDIF_TOK_NOTALLOWED}, + {"notchspacing", EDIF_TOK_NOTCHSPACING}, + {"number", EDIF_TOK_NUMBER}, + {"numberdefinition", EDIF_TOK_NUMBERDEFINITION}, + {"numberdisplay", EDIF_TOK_NUMBERDISPLAY}, + {"offpageconnector", EDIF_TOK_OFFPAGECONNECTOR}, + {"offsetevent", EDIF_TOK_OFFSETEVENT}, + {"openshape", EDIF_TOK_OPENSHAPE}, + {"orientation", EDIF_TOK_ORIENTATION}, + {"origin", EDIF_TOK_ORIGIN}, + {"overhangdistance", EDIF_TOK_OVERHANGDISTANCE}, + {"overlapdistance", EDIF_TOK_OVERLAPDISTANCE}, + {"oversize", EDIF_TOK_OVERSIZE}, + {"owner", EDIF_TOK_OWNER}, + {"page", EDIF_TOK_PAGE}, + {"pagesize", EDIF_TOK_PAGESIZE}, + {"parameter", EDIF_TOK_PARAMETER}, + {"parameterassign", EDIF_TOK_PARAMETERASSIGN}, + {"parameterdisplay", EDIF_TOK_PARAMETERDISPLAY}, + {"path", EDIF_TOK_PATH}, + {"pathdelay", EDIF_TOK_PATHDELAY}, + {"pathwidth", EDIF_TOK_PATHWIDTH}, + {"permutable", EDIF_TOK_PERMUTABLE}, + {"physicaldesignrule", EDIF_TOK_PHYSICALDESIGNRULE}, + {"plug", EDIF_TOK_PLUG}, + {"point", EDIF_TOK_POINT}, + {"pointdisplay", EDIF_TOK_POINTDISPLAY}, + {"pointlist", EDIF_TOK_POINTLIST}, + {"polygon", EDIF_TOK_POLYGON}, + {"port", EDIF_TOK_PORT}, + {"portbackannotate", EDIF_TOK_PORTBACKANNOTATE}, + {"portbundle", EDIF_TOK_PORTBUNDLE}, + {"portdelay", EDIF_TOK_PORTDELAY}, + {"portgroup", EDIF_TOK_PORTGROUP}, + {"portimplementation", EDIF_TOK_PORTIMPLEMENTATION}, + {"portinstance", EDIF_TOK_PORTINSTANCE}, + {"portlist", EDIF_TOK_PORTLIST}, + {"portlistalias", EDIF_TOK_PORTLISTALIAS}, + {"portmap", EDIF_TOK_PORTMAP}, + {"portref", EDIF_TOK_PORTREF}, + {"program", EDIF_TOK_PROGRAM}, + {"property", EDIF_TOK_PROPERTY}, + {"propertydisplay", EDIF_TOK_PROPERTYDISPLAY}, + {"protectionframe", EDIF_TOK_PROTECTIONFRAME}, + {"pt", EDIF_TOK_PT}, + {"rangevector", EDIF_TOK_RANGEVECTOR}, + {"rectangle", EDIF_TOK_RECTANGLE}, + {"rectanglesize", EDIF_TOK_RECTANGLESIZE}, + {"rename", EDIF_TOK_RENAME}, + {"resolves", EDIF_TOK_RESOLVES}, + {"scale", EDIF_TOK_SCALE}, + {"scalex", EDIF_TOK_SCALEX}, + {"scaley", EDIF_TOK_SCALEY}, + {"section", EDIF_TOK_SECTION}, + {"shape", EDIF_TOK_SHAPE}, + {"simulate", EDIF_TOK_SIMULATE}, + {"simulationinfo", EDIF_TOK_SIMULATIONINFO}, + {"singlevalueset", EDIF_TOK_SINGLEVALUESET}, + {"site", EDIF_TOK_SITE}, + {"socket", EDIF_TOK_SOCKET}, + {"socketset", EDIF_TOK_SOCKETSET}, + {"status", EDIF_TOK_STATUS}, + {"steady", EDIF_TOK_STEADY}, + {"string", EDIF_TOK_STRING}, + {"stringdisplay", EDIF_TOK_STRINGDISPLAY}, + {"strong", EDIF_TOK_STRONG}, + {"symbol", EDIF_TOK_SYMBOL}, + {"symmetry", EDIF_TOK_SYMMETRY}, + {"table", EDIF_TOK_TABLE}, + {"tabledefault", EDIF_TOK_TABLEDEFAULT}, + {"technology", EDIF_TOK_TECHNOLOGY}, + {"textheight", EDIF_TOK_TEXTHEIGHT}, + {"timeinterval", EDIF_TOK_TIMEINTERVAL}, + {"timestamp", EDIF_TOK_TIMESTAMP}, + {"timing", EDIF_TOK_TIMING}, + {"transform", EDIF_TOK_TRANSFORM}, + {"transition", EDIF_TOK_TRANSITION}, + {"trigger", EDIF_TOK_TRIGGER}, + {"true", EDIF_TOK_TRUE}, + {"unconstrained", EDIF_TOK_UNCONSTRAINED}, + {"undefined", EDIF_TOK_UNDEFINED}, + {"union", EDIF_TOK_UNION}, + {"unit", EDIF_TOK_UNIT}, + {"unused", EDIF_TOK_UNUSED}, + {"userdata", EDIF_TOK_USERDATA}, + {"version", EDIF_TOK_VERSION}, + {"view", EDIF_TOK_VIEW}, + {"viewlist", EDIF_TOK_VIEWLIST}, + {"viewmap", EDIF_TOK_VIEWMAP}, + {"viewref", EDIF_TOK_VIEWREF}, + {"viewtype", EDIF_TOK_VIEWTYPE}, + {"visible", EDIF_TOK_VISIBLE}, + {"voltagemap", EDIF_TOK_VOLTAGEMAP}, + {"wavevalue", EDIF_TOK_WAVEVALUE}, + {"weak", EDIF_TOK_WEAK}, + {"weakjoined", EDIF_TOK_WEAKJOINED}, + {"when", EDIF_TOK_WHEN}, + {"written", EDIF_TOK_WRITTEN} +}; +static int ContextDefSize = sizeof(ContextDef) / sizeof(Context); +/* + * Context follower tables: + * + * This is pretty ugly, an array is defined for each context + * which has following context levels. Yet another table is used + * to bind these arrays to the originating contexts. + * Arrays are declared as: + * + * static short f_[] = { ... }; + * + * The array entries are the '%token' values for all keywords which + * can be reached from the context. Like I said, ugly, + * but it works. + * A negative entry means that the follow can only occur once within + * the specified context. + */ +static short f_NULL[] = {EDIF_TOK_EDIF}; +static short f_Edif[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_EDIFVERSION, + EDIF_TOK_EDIFLEVEL, EDIF_TOK_KEYWORDMAP, + -EDIF_TOK_STATUS, EDIF_TOK_EXTERNAL, + EDIF_TOK_LIBRARY, EDIF_TOK_DESIGN, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_AcLoad[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY}; +static short f_After[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_FOLLOW, + EDIF_TOK_MAINTAIN, EDIF_TOK_LOGICASSIGN, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_Annotate[] = {EDIF_TOK_STRINGDISPLAY}; +static short f_Apply[] = {EDIF_TOK_CYCLE, EDIF_TOK_LOGICINPUT, + EDIF_TOK_LOGICOUTPUT, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Arc[] = {EDIF_TOK_PT}; +static short f_Array[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME}; +static short f_ArrayMacro[] = {EDIF_TOK_PLUG}; +static short f_ArrayRelatedInfo[] = {EDIF_TOK_BASEARRAY, EDIF_TOK_ARRAYSITE, + EDIF_TOK_ARRAYMACRO, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_ArraySite[] = {EDIF_TOK_SOCKET}; +static short f_AtLeast[] = {EDIF_TOK_E}; +static short f_AtMost[] = {EDIF_TOK_E}; +static short f_Becomes[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, + EDIF_TOK_LOGICONEOF}; +/* +static short f_Between[] = {EDIF_TOK_ATLEAST, EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_LESSTHAN}; +*/ +static short f_Boolean[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE, + EDIF_TOK_BOOLEANDISPLAY, EDIF_TOK_BOOLEAN}; +static short f_BooleanDisplay[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE, + EDIF_TOK_DISPLAY}; +static short f_BooleanMap[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE}; +static short f_BorderPattern[] = {EDIF_TOK_BOOLEAN}; +static short f_BoundingBox[] = {EDIF_TOK_RECTANGLE}; +static short f_Cell[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_CELLTYPE, + -EDIF_TOK_STATUS, -EDIF_TOK_VIEWMAP, EDIF_TOK_VIEW, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA, + EDIF_TOK_PROPERTY}; +static short f_CellRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; +static short f_Change[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, + EDIF_TOK_BECOMES, EDIF_TOK_TRANSITION}; +static short f_Circle[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; +static short f_Color[] = {EDIF_TOK_E}; +static short f_CommentGraphics[] = {EDIF_TOK_ANNOTATE, EDIF_TOK_FIGURE, + EDIF_TOK_INSTANCE, -EDIF_TOK_BOUNDINGBOX, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Compound[] = {EDIF_TOK_NAME}; +static short f_ConnectLocation[] = {EDIF_TOK_FIGURE}; +static short f_Contents[] = {EDIF_TOK_INSTANCE, EDIF_TOK_OFFPAGECONNECTOR, + EDIF_TOK_FIGURE, EDIF_TOK_SECTION, EDIF_TOK_NET, + EDIF_TOK_NETBUNDLE, EDIF_TOK_PAGE, + EDIF_TOK_COMMENTGRAPHICS, + EDIF_TOK_PORTIMPLEMENTATION, + EDIF_TOK_TIMING, EDIF_TOK_SIMULATE, + EDIF_TOK_WHEN, EDIF_TOK_FOLLOW, + EDIF_TOK_LOGICPORT, -EDIF_TOK_BOUNDINGBOX, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_Criticality[] = {EDIF_TOK_INTEGERDISPLAY}; +static short f_CurrentMap[] = {EDIF_TOK_MNM, EDIF_TOK_E}; +static short f_Curve[] = {EDIF_TOK_ARC, EDIF_TOK_PT}; +static short f_Cycle[] = {EDIF_TOK_DURATION}; +static short f_DataOrigin[] = {EDIF_TOK_VERSION}; +static short f_DcFanInLoad[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; +static short f_DcFanOutLoad[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; +static short f_DcMaxFanIn[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; +static short f_DcMaxFanOut[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; +static short f_Delay[] = {EDIF_TOK_MNM, EDIF_TOK_E}; +static short f_Delta[] = {EDIF_TOK_PT}; +static short f_Design[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_CELLREF, + EDIF_TOK_STATUS, EDIF_TOK_COMMENT, + EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; +static short f_Designator[] = {EDIF_TOK_STRINGDISPLAY}; +static short f_Difference[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, + EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, + EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; +static short f_Display[] = {EDIF_TOK_NAME, EDIF_TOK_FIGUREGROUPOVERRIDE, + EDIF_TOK_JUSTIFY, EDIF_TOK_ORIENTATION, + EDIF_TOK_ORIGIN}; +static short f_Dominates[] = {EDIF_TOK_NAME}; +static short f_Dot[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; +static short f_Duration[] = {EDIF_TOK_E}; +static short f_EnclosureDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, + EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, + EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_Entry[] = {EDIF_TOK_MATCH, EDIF_TOK_CHANGE, EDIF_TOK_STEADY, + EDIF_TOK_LOGICREF, EDIF_TOK_PORTREF, + EDIF_TOK_NOCHANGE, EDIF_TOK_TABLE, + EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; +static short f_Exactly[] = {EDIF_TOK_E}; +static short f_External[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_EDIFLEVEL, EDIF_TOK_TECHNOLOGY, + -EDIF_TOK_STATUS, EDIF_TOK_CELL, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Fabricate[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME}; +static short f_Figure[] = {EDIF_TOK_NAME, EDIF_TOK_FIGUREGROUPOVERRIDE, + EDIF_TOK_CIRCLE, EDIF_TOK_DOT, EDIF_TOK_OPENSHAPE, + EDIF_TOK_PATH, EDIF_TOK_POLYGON, + EDIF_TOK_RECTANGLE, EDIF_TOK_SHAPE, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_FigureArea[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_FigureGroup[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + -EDIF_TOK_CORNERTYPE, -EDIF_TOK_ENDTYPE, + -EDIF_TOK_PATHWIDTH, -EDIF_TOK_BORDERWIDTH, + -EDIF_TOK_COLOR, -EDIF_TOK_FILLPATTERN, + -EDIF_TOK_BORDERPATTERN, -EDIF_TOK_TEXTHEIGHT, + -EDIF_TOK_VISIBLE, EDIF_TOK_INCLUDEFIGUREGROUP, + EDIF_TOK_COMMENT, EDIF_TOK_PROPERTY, + EDIF_TOK_USERDATA}; +static short f_FigureGroupObject[] = {EDIF_TOK_NAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, + EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, + EDIF_TOK_OVERSIZE}; +static short f_FigureGroupOverride[] = {EDIF_TOK_NAME, -EDIF_TOK_CORNERTYPE, + -EDIF_TOK_ENDTYPE, -EDIF_TOK_PATHWIDTH, + -EDIF_TOK_BORDERWIDTH, -EDIF_TOK_COLOR, + -EDIF_TOK_FILLPATTERN, + -EDIF_TOK_TEXTHEIGHT, + -EDIF_TOK_BORDERPATTERN, + EDIF_TOK_VISIBLE, EDIF_TOK_COMMENT, + EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; +static short f_FigureGroupRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; +static short f_FigurePerimeter[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, + EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, + EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_FigureWidth[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_FillPattern[] = {EDIF_TOK_BOOLEAN}; +static short f_Follow[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_TABLE, + EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; +static short f_ForbiddenEvent[] = {EDIF_TOK_TIMEINTERVAL, EDIF_TOK_EVENT}; +static short f_GlobalPortRef[] = {EDIF_TOK_NAME}; +static short f_GreaterThan[] = {EDIF_TOK_E}; +static short f_GridMap[] = {EDIF_TOK_E}; +static short f_IncludeFigureGroup[] = {EDIF_TOK_FIGUREGROUPREF, + EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, + EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, + EDIF_TOK_OVERSIZE}; +static short f_Instance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + EDIF_TOK_VIEWREF, EDIF_TOK_VIEWLIST, + -EDIF_TOK_TRANSFORM, EDIF_TOK_PARAMETERASSIGN, + EDIF_TOK_PORTINSTANCE, EDIF_TOK_TIMING, + -EDIF_TOK_DESIGNATOR, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_InstanceBackAnnotate[] = {EDIF_TOK_INSTANCEREF, + -EDIF_TOK_DESIGNATOR, EDIF_TOK_TIMING, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; +static short f_InstanceGroup[] = {EDIF_TOK_INSTANCEREF}; +static short f_InstanceMap[] = {EDIF_TOK_INSTANCEREF, EDIF_TOK_INSTANCEGROUP, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_InstanceRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, + EDIF_TOK_INSTANCEREF, EDIF_TOK_VIEWREF}; +static short f_Integer[] = {EDIF_TOK_INTEGERDISPLAY, EDIF_TOK_INTEGER}; +static short f_IntegerDisplay[] = {EDIF_TOK_DISPLAY}; +static short f_Interface[] = {EDIF_TOK_PORT, EDIF_TOK_PORTBUNDLE, + -EDIF_TOK_SYMBOL, -EDIF_TOK_PROTECTIONFRAME, + -EDIF_TOK_ARRAYRELATEDINFO, EDIF_TOK_PARAMETER, + EDIF_TOK_JOINED, EDIF_TOK_MUSTJOIN, + EDIF_TOK_WEAKJOINED, EDIF_TOK_PERMUTABLE, + EDIF_TOK_TIMING, EDIF_TOK_SIMULATE, + -EDIF_TOK_DESIGNATOR, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_InterFigureGroupSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, + EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Intersection[] = {EDIF_TOK_FIGUREGROUPREF, + EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, + EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, + EDIF_TOK_OVERSIZE}; +static short f_IntraFigureGroupSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, + EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, + EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Inverse[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, + EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, + EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; +static short f_Joined[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, + EDIF_TOK_GLOBALPORTREF}; +static short f_KeywordDisplay[] = {EDIF_TOK_DISPLAY}; +static short f_KeywordMap[] = {EDIF_TOK_KEYWORDLEVEL, EDIF_TOK_COMMENT}; +static short f_LessThan[] = {EDIF_TOK_E}; +static short f_Library[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_EDIFLEVEL, + EDIF_TOK_TECHNOLOGY, -EDIF_TOK_STATUS, + EDIF_TOK_CELL, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_LibraryRef[] = {EDIF_TOK_NAME}; +static short f_ListOfNets[] = {EDIF_TOK_NET}; +static short f_ListOfPorts[] = {EDIF_TOK_PORT, EDIF_TOK_PORTBUNDLE}; +static short f_LoadDelay[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY}; +static short f_LogicAssign[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, + EDIF_TOK_LOGICREF, EDIF_TOK_TABLE, + EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; +static short f_LogicInput[] = {EDIF_TOK_PORTLIST, EDIF_TOK_PORTREF, + EDIF_TOK_NAME, EDIF_TOK_LOGICWAVEFORM}; +static short f_LogicList[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICONEOF, + EDIF_TOK_IGNORE}; +static short f_LogicMapInput[] = {EDIF_TOK_LOGICREF}; +static short f_LogicMapOutput[] = {EDIF_TOK_LOGICREF}; +static short f_LogicOneOf[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST}; +static short f_LogicOutput[] = {EDIF_TOK_PORTLIST, EDIF_TOK_PORTREF, + EDIF_TOK_NAME, EDIF_TOK_LOGICWAVEFORM}; +static short f_LogicPort[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_LogicRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; +static short f_LogicValue[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + -EDIF_TOK_VOLTAGEMAP, -EDIF_TOK_CURRENTMAP, + -EDIF_TOK_BOOLEANMAP, -EDIF_TOK_COMPOUND, + -EDIF_TOK_WEAK ,-EDIF_TOK_STRONG, + -EDIF_TOK_DOMINATES, -EDIF_TOK_LOGICMAPOUTPUT, + -EDIF_TOK_LOGICMAPINPUT, + -EDIF_TOK_ISOLATED, EDIF_TOK_RESOLVES, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_LogicWaveform[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, + EDIF_TOK_LOGICONEOF, EDIF_TOK_IGNORE}; +static short f_Maintain[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_DELAY, + EDIF_TOK_LOADDELAY}; +static short f_Match[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, + EDIF_TOK_LOGICLIST, EDIF_TOK_LOGICONEOF}; +static short f_Member[] = {EDIF_TOK_NAME}; +static short f_MiNoMax[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY, + EDIF_TOK_MINOMAX}; +static short f_MiNoMaxDisplay[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_DISPLAY}; +static short f_Mnm[] = {EDIF_TOK_E, EDIF_TOK_UNDEFINED, + EDIF_TOK_UNCONSTRAINED}; +static short f_MultipleValueSet[] = {EDIF_TOK_RANGEVECTOR}; +static short f_MustJoin[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, + EDIF_TOK_WEAKJOINED, EDIF_TOK_JOINED}; +static short f_Name[] = {EDIF_TOK_DISPLAY}; +static short f_Net[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, -EDIF_TOK_CRITICALITY, + EDIF_TOK_NETDELAY, EDIF_TOK_FIGURE, EDIF_TOK_NET, + EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA, EDIF_TOK_JOINED, EDIF_TOK_ARRAY}; +static short f_NetBackAnnotate[] = {EDIF_TOK_NETREF, EDIF_TOK_NETDELAY, + -EDIF_TOK_CRITICALITY, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT}; +static short f_NetBundle[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + EDIF_TOK_LISTOFNETS, EDIF_TOK_FIGURE, + EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_NetDelay[] = {EDIF_TOK_DERIVATION, EDIF_TOK_DELAY, + EDIF_TOK_TRANSITION, EDIF_TOK_BECOMES}; +static short f_NetGroup[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_NETREF}; +static short f_NetMap[] = {EDIF_TOK_NETREF, EDIF_TOK_NETGROUP, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_NetRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_NETREF, + EDIF_TOK_INSTANCEREF, EDIF_TOK_VIEWREF}; +static short f_NonPermutable[] = {EDIF_TOK_PORTREF, EDIF_TOK_PERMUTABLE}; +static short f_NotAllowed[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_NotchSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_Number[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY, EDIF_TOK_NUMBER}; +static short f_NumberDefinition[] = {EDIF_TOK_SCALE, -EDIF_TOK_GRIDMAP, + EDIF_TOK_COMMENT}; +static short f_NumberDisplay[] = {EDIF_TOK_E, EDIF_TOK_DISPLAY}; +static short f_OffPageConnector[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + -EDIF_TOK_UNUSED, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_OffsetEvent[] = {EDIF_TOK_EVENT, EDIF_TOK_E}; +static short f_OpenShape[] = {EDIF_TOK_CURVE, EDIF_TOK_PROPERTY}; +static short f_Origin[] = {EDIF_TOK_PT}; +static short f_OverhangDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_OverlapDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_Oversize[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, + EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, + EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE, + EDIF_TOK_CORNERTYPE}; +static short f_Page[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + EDIF_TOK_INSTANCE, EDIF_TOK_NET, EDIF_TOK_NETBUNDLE, + EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PORTIMPLEMENTATION, + -EDIF_TOK_PAGESIZE, -EDIF_TOK_BOUNDINGBOX, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_PageSize[] = {EDIF_TOK_RECTANGLE}; +static short f_Parameter[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + EDIF_TOK_BOOLEAN, EDIF_TOK_INTEGER, + EDIF_TOK_MINOMAX, EDIF_TOK_NUMBER, + EDIF_TOK_POINT, EDIF_TOK_STRING}; +static short f_ParameterAssign[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, + EDIF_TOK_BOOLEAN, EDIF_TOK_INTEGER, + EDIF_TOK_MINOMAX, EDIF_TOK_NUMBER, EDIF_TOK_POINT, + EDIF_TOK_STRING}; +static short f_ParameterDisplay[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, + EDIF_TOK_DISPLAY}; +static short f_Path[] = {EDIF_TOK_POINTLIST, EDIF_TOK_PROPERTY}; +static short f_PathDelay[] = {EDIF_TOK_DELAY, EDIF_TOK_EVENT}; +static short f_Permutable[] = {EDIF_TOK_PORTREF, EDIF_TOK_PERMUTABLE, + EDIF_TOK_NONPERMUTABLE}; +static short f_PhysicalDesignRule[] = {EDIF_TOK_FIGUREWIDTH, + EDIF_TOK_FIGUREAREA, + EDIF_TOK_RECTANGLESIZE, + EDIF_TOK_FIGUREPERIMETER, + EDIF_TOK_OVERLAPDISTANCE, + EDIF_TOK_OVERHANGDISTANCE, + EDIF_TOK_ENCLOSUREDISTANCE, + EDIF_TOK_INTERFIGUREGROUPSPACING, + EDIF_TOK_NOTCHSPACING, + EDIF_TOK_INTRAFIGUREGROUPSPACING, + EDIF_TOK_NOTALLOWED, + EDIF_TOK_FIGUREGROUP, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Plug[] = {EDIF_TOK_SOCKETSET}; +static short f_Point[] = {EDIF_TOK_PT, EDIF_TOK_POINTDISPLAY, + EDIF_TOK_POINT}; +static short f_PointDisplay[] = {EDIF_TOK_PT, EDIF_TOK_DISPLAY}; +static short f_PointList[] = {EDIF_TOK_PT}; +static short f_Polygon[] = {EDIF_TOK_POINTLIST, EDIF_TOK_PROPERTY}; +static short f_Port[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + -EDIF_TOK_DIRECTION, -EDIF_TOK_UNUSED, + EDIF_TOK_PORTDELAY, -EDIF_TOK_DESIGNATOR, + -EDIF_TOK_DCFANINLOAD, -EDIF_TOK_DCFANOUTLOAD, + -EDIF_TOK_DCMAXFANIN, -EDIF_TOK_DCMAXFANOUT, + -EDIF_TOK_ACLOAD, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_PortBackAnnotate[] = {EDIF_TOK_PORTREF, -EDIF_TOK_DESIGNATOR, + EDIF_TOK_PORTDELAY, -EDIF_TOK_DCFANINLOAD, + -EDIF_TOK_DCFANOUTLOAD, + -EDIF_TOK_DCMAXFANIN, + -EDIF_TOK_DCMAXFANOUT, -EDIF_TOK_ACLOAD, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; +static short f_PortBundle[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + EDIF_TOK_LISTOFPORTS, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_PortDelay[] = {EDIF_TOK_DERIVATION, EDIF_TOK_DELAY, + EDIF_TOK_LOADDELAY, EDIF_TOK_TRANSITION, + EDIF_TOK_BECOMES}; +static short f_PortGroup[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, + EDIF_TOK_PORTREF}; +static short f_PortImplementation[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_MEMBER, + -EDIF_TOK_CONNECTLOCATION, + EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, + EDIF_TOK_COMMENTGRAPHICS, + EDIF_TOK_PROPERTYDISPLAY, + EDIF_TOK_KEYWORDDISPLAY, + EDIF_TOK_PROPERTY, + EDIF_TOK_USERDATA, EDIF_TOK_COMMENT}; +static short f_PortInstance[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, + EDIF_TOK_MEMBER, -EDIF_TOK_UNUSED, + EDIF_TOK_PORTDELAY, -EDIF_TOK_DESIGNATOR, + -EDIF_TOK_DCFANINLOAD, + -EDIF_TOK_DCFANOUTLOAD, -EDIF_TOK_DCMAXFANIN, + -EDIF_TOK_DCMAXFANOUT, -EDIF_TOK_ACLOAD, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_PortList[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, + EDIF_TOK_MEMBER}; +static short f_PortListAlias[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_ARRAY, EDIF_TOK_PORTLIST}; +static short f_PortMap[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTGROUP, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_PortRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, + EDIF_TOK_PORTREF, EDIF_TOK_INSTANCEREF, + EDIF_TOK_VIEWREF}; +static short f_Program[] = {EDIF_TOK_VERSION}; +static short f_Property[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_BOOLEAN, + EDIF_TOK_INTEGER, EDIF_TOK_MINOMAX, + EDIF_TOK_NUMBER, EDIF_TOK_POINT, EDIF_TOK_STRING, + -EDIF_TOK_OWNER, -EDIF_TOK_UNIT, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; +static short f_PropertyDisplay[] = {EDIF_TOK_NAME, EDIF_TOK_DISPLAY}; +static short f_ProtectionFrame[] = {EDIF_TOK_PORTIMPLEMENTATION, + EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, + EDIF_TOK_COMMENTGRAPHICS, + -EDIF_TOK_BOUNDINGBOX, + EDIF_TOK_PROPERTYDISPLAY, + EDIF_TOK_KEYWORDDISPLAY, + EDIF_TOK_PARAMETERDISPLAY, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_RangeVector[] = {EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, + EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, + EDIF_TOK_SINGLEVALUESET}; +static short f_Rectangle[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; +static short f_RectangleSize[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_RANGEVECTOR, + EDIF_TOK_MULTIPLEVALUESET,EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Rename[] = {EDIF_TOK_NAME, EDIF_TOK_STRINGDISPLAY}; +static short f_Resolves[] = {EDIF_TOK_NAME}; +static short f_Scale[] = {EDIF_TOK_E, EDIF_TOK_UNIT}; +static short f_Section[] = {EDIF_TOK_SECTION, EDIF_TOK_INSTANCE}; +static short f_Shape[] = {EDIF_TOK_CURVE, EDIF_TOK_PROPERTY}; +static short f_Simulate[] = {EDIF_TOK_NAME, EDIF_TOK_PORTLISTALIAS, + EDIF_TOK_WAVEVALUE, EDIF_TOK_APPLY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_SimulationInfo[] = {EDIF_TOK_LOGICVALUE, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_SingleValueSet[] = {EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, + EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN}; +static short f_Site[] = {EDIF_TOK_VIEWREF, EDIF_TOK_TRANSFORM}; +static short f_Socket[] = {EDIF_TOK_SYMMETRY}; +static short f_SocketSet[] = {EDIF_TOK_SYMMETRY, EDIF_TOK_SITE}; +static short f_Status[] = {EDIF_TOK_WRITTEN, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Steady[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_PORTREF, + EDIF_TOK_PORTLIST, EDIF_TOK_DURATION, + EDIF_TOK_TRANSITION, EDIF_TOK_BECOMES}; +static short f_String[] = {EDIF_TOK_STRINGDISPLAY, EDIF_TOK_STRING}; +static short f_StringDisplay[] = {EDIF_TOK_DISPLAY}; +static short f_Strong[] = {EDIF_TOK_NAME}; +static short f_Symbol[] = {EDIF_TOK_PORTIMPLEMENTATION, EDIF_TOK_FIGURE, + EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, + EDIF_TOK_ANNOTATE, -EDIF_TOK_PAGESIZE, + -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_PROPERTYDISPLAY, + EDIF_TOK_KEYWORDDISPLAY, EDIF_TOK_PARAMETERDISPLAY, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Symmetry[] = {EDIF_TOK_TRANSFORM}; +static short f_Table[] = {EDIF_TOK_ENTRY, EDIF_TOK_TABLEDEFAULT}; +static short f_TableDefault[] = {EDIF_TOK_LOGICREF, EDIF_TOK_PORTREF, + EDIF_TOK_NOCHANGE, EDIF_TOK_TABLE, + EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; +static short f_Technology[] = {EDIF_TOK_NUMBERDEFINITION, EDIF_TOK_FIGUREGROUP, + EDIF_TOK_FABRICATE, -EDIF_TOK_SIMULATIONINFO, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA, + -EDIF_TOK_PHYSICALDESIGNRULE}; +static short f_TimeInterval[] = {EDIF_TOK_EVENT, EDIF_TOK_OFFSETEVENT, + EDIF_TOK_DURATION}; +static short f_Timing[] = {EDIF_TOK_DERIVATION, EDIF_TOK_PATHDELAY, + EDIF_TOK_FORBIDDENEVENT, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Transform[] = {EDIF_TOK_SCALEX, EDIF_TOK_SCALEY, EDIF_TOK_DELTA, + EDIF_TOK_ORIENTATION, EDIF_TOK_ORIGIN}; +static short f_Transition[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, + EDIF_TOK_LOGICONEOF}; +static short f_Trigger[] = {EDIF_TOK_CHANGE, EDIF_TOK_STEADY, + EDIF_TOK_INITIAL}; +static short f_Union[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, + EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, + EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; +static short f_View[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_VIEWTYPE, + EDIF_TOK_INTERFACE, -EDIF_TOK_STATUS, + -EDIF_TOK_CONTENTS, EDIF_TOK_COMMENT, + EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; +static short f_ViewList[] = {EDIF_TOK_VIEWREF, EDIF_TOK_VIEWLIST}; +static short f_ViewMap[] = {EDIF_TOK_PORTMAP, EDIF_TOK_PORTBACKANNOTATE, + EDIF_TOK_INSTANCEMAP, + EDIF_TOK_INSTANCEBACKANNOTATE, EDIF_TOK_NETMAP, + EDIF_TOK_NETBACKANNOTATE, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_ViewRef[] = {EDIF_TOK_NAME, EDIF_TOK_CELLREF}; +static short f_Visible[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE}; +static short f_VoltageMap[] = {EDIF_TOK_MNM, EDIF_TOK_E}; +static short f_WaveValue[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_E, + EDIF_TOK_LOGICWAVEFORM}; +static short f_Weak[] = {EDIF_TOK_NAME}; +static short f_WeakJoined[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, + EDIF_TOK_JOINED}; +static short f_When[] = {EDIF_TOK_TRIGGER, EDIF_TOK_AFTER, + EDIF_TOK_FOLLOW, EDIF_TOK_MAINTAIN, + EDIF_TOK_LOGICASSIGN, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Written[] = {EDIF_TOK_TIMESTAMP, EDIF_TOK_AUTHOR, + EDIF_TOK_PROGRAM, EDIF_TOK_DATAORIGIN, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +/* + * Context binding table: + * + * This binds context follower arrays to their originating context. + */ +typedef struct Binder { + short *Follower; /* pointer to follower array */ + short Origin; /* '%token' value of origin */ + short FollowerSize; /* size of follower array */ +} Binder; +#define BE(f,o) {f,o,sizeof(f)/sizeof(short)} +static Binder BinderDef[] = { + BE(f_NULL, 0), + BE(f_Edif, EDIF_TOK_EDIF), + BE(f_AcLoad, EDIF_TOK_ACLOAD), + BE(f_After, EDIF_TOK_AFTER), + BE(f_Annotate, EDIF_TOK_ANNOTATE), + BE(f_Apply, EDIF_TOK_APPLY), + BE(f_Arc, EDIF_TOK_ARC), + BE(f_Array, EDIF_TOK_ARRAY), + BE(f_ArrayMacro, EDIF_TOK_ARRAYMACRO), + BE(f_ArrayRelatedInfo, EDIF_TOK_ARRAYRELATEDINFO), + BE(f_ArraySite, EDIF_TOK_ARRAYSITE), + BE(f_AtLeast, EDIF_TOK_ATLEAST), + BE(f_AtMost, EDIF_TOK_ATMOST), + BE(f_Becomes, EDIF_TOK_BECOMES), + BE(f_Boolean, EDIF_TOK_BOOLEAN), + BE(f_BooleanDisplay, EDIF_TOK_BOOLEANDISPLAY), + BE(f_BooleanMap, EDIF_TOK_BOOLEANMAP), + BE(f_BorderPattern, EDIF_TOK_BORDERPATTERN), + BE(f_BoundingBox, EDIF_TOK_BOUNDINGBOX), + BE(f_Cell, EDIF_TOK_CELL), + BE(f_CellRef, EDIF_TOK_CELLREF), + BE(f_Change, EDIF_TOK_CHANGE), + BE(f_Circle, EDIF_TOK_CIRCLE), + BE(f_Color, EDIF_TOK_COLOR), + BE(f_CommentGraphics, EDIF_TOK_COMMENTGRAPHICS), + BE(f_Compound, EDIF_TOK_COMPOUND), + BE(f_ConnectLocation, EDIF_TOK_CONNECTLOCATION), + BE(f_Contents, EDIF_TOK_CONTENTS), + BE(f_Criticality, EDIF_TOK_CRITICALITY), + BE(f_CurrentMap, EDIF_TOK_CURRENTMAP), + BE(f_Curve, EDIF_TOK_CURVE), + BE(f_Cycle, EDIF_TOK_CYCLE), + BE(f_DataOrigin, EDIF_TOK_DATAORIGIN), + BE(f_DcFanInLoad, EDIF_TOK_DCFANINLOAD), + BE(f_DcFanOutLoad, EDIF_TOK_DCFANOUTLOAD), + BE(f_DcMaxFanIn, EDIF_TOK_DCMAXFANIN), + BE(f_DcMaxFanOut, EDIF_TOK_DCMAXFANOUT), + BE(f_Delay, EDIF_TOK_DELAY), + BE(f_Delta, EDIF_TOK_DELTA), + BE(f_Design, EDIF_TOK_DESIGN), + BE(f_Designator, EDIF_TOK_DESIGNATOR), + BE(f_Difference, EDIF_TOK_DIFFERENCE), + BE(f_Display, EDIF_TOK_DISPLAY), + BE(f_Dominates, EDIF_TOK_DOMINATES), + BE(f_Dot, EDIF_TOK_DOT), + BE(f_Duration, EDIF_TOK_DURATION), + BE(f_EnclosureDistance, EDIF_TOK_ENCLOSUREDISTANCE), + BE(f_Entry, EDIF_TOK_ENTRY), + BE(f_Exactly, EDIF_TOK_EXACTLY), + BE(f_External, EDIF_TOK_EXTERNAL), + BE(f_Fabricate, EDIF_TOK_FABRICATE), + BE(f_Figure, EDIF_TOK_FIGURE), + BE(f_FigureArea, EDIF_TOK_FIGUREAREA), + BE(f_FigureGroup, EDIF_TOK_FIGUREGROUP), + BE(f_FigureGroupObject, EDIF_TOK_FIGUREGROUPOBJECT), + BE(f_FigureGroupOverride, EDIF_TOK_FIGUREGROUPOVERRIDE), + BE(f_FigureGroupRef, EDIF_TOK_FIGUREGROUPREF), + BE(f_FigurePerimeter, EDIF_TOK_FIGUREPERIMETER), + BE(f_FigureWidth, EDIF_TOK_FIGUREWIDTH), + BE(f_FillPattern, EDIF_TOK_FILLPATTERN), + BE(f_Follow, EDIF_TOK_FOLLOW), + BE(f_ForbiddenEvent, EDIF_TOK_FORBIDDENEVENT), + BE(f_GlobalPortRef, EDIF_TOK_GLOBALPORTREF), + BE(f_GreaterThan, EDIF_TOK_GREATERTHAN), + BE(f_GridMap, EDIF_TOK_GRIDMAP), + BE(f_IncludeFigureGroup, EDIF_TOK_INCLUDEFIGUREGROUP), + BE(f_Instance, EDIF_TOK_INSTANCE), + BE(f_InstanceBackAnnotate, EDIF_TOK_INSTANCEBACKANNOTATE), + BE(f_InstanceGroup, EDIF_TOK_INSTANCEGROUP), + BE(f_InstanceMap, EDIF_TOK_INSTANCEMAP), + BE(f_InstanceRef, EDIF_TOK_INSTANCEREF), + BE(f_Integer, EDIF_TOK_INTEGER), + BE(f_IntegerDisplay, EDIF_TOK_INTEGERDISPLAY), + BE(f_InterFigureGroupSpacing, EDIF_TOK_INTERFIGUREGROUPSPACING), + BE(f_Interface, EDIF_TOK_INTERFACE), + BE(f_Intersection, EDIF_TOK_INTERSECTION), + BE(f_IntraFigureGroupSpacing, EDIF_TOK_INTRAFIGUREGROUPSPACING), + BE(f_Inverse, EDIF_TOK_INVERSE), + BE(f_Joined, EDIF_TOK_JOINED), + BE(f_KeywordDisplay, EDIF_TOK_KEYWORDDISPLAY), + BE(f_KeywordMap, EDIF_TOK_KEYWORDMAP), + BE(f_LessThan, EDIF_TOK_LESSTHAN), + BE(f_Library, EDIF_TOK_LIBRARY), + BE(f_LibraryRef, EDIF_TOK_LIBRARYREF), + BE(f_ListOfNets, EDIF_TOK_LISTOFNETS), + BE(f_ListOfPorts, EDIF_TOK_LISTOFPORTS), + BE(f_LoadDelay, EDIF_TOK_LOADDELAY), + BE(f_LogicAssign, EDIF_TOK_LOGICASSIGN), + BE(f_LogicInput, EDIF_TOK_LOGICINPUT), + BE(f_LogicList, EDIF_TOK_LOGICLIST), + BE(f_LogicMapInput, EDIF_TOK_LOGICMAPINPUT), + BE(f_LogicMapOutput, EDIF_TOK_LOGICMAPOUTPUT), + BE(f_LogicOneOf, EDIF_TOK_LOGICONEOF), + BE(f_LogicOutput, EDIF_TOK_LOGICOUTPUT), + BE(f_LogicPort, EDIF_TOK_LOGICPORT), + BE(f_LogicRef, EDIF_TOK_LOGICREF), + BE(f_LogicValue, EDIF_TOK_LOGICVALUE), + BE(f_LogicWaveform, EDIF_TOK_LOGICWAVEFORM), + BE(f_Maintain, EDIF_TOK_MAINTAIN), + BE(f_Match, EDIF_TOK_MATCH), + BE(f_Member, EDIF_TOK_MEMBER), + BE(f_MiNoMax, EDIF_TOK_MINOMAX), + BE(f_MiNoMaxDisplay, EDIF_TOK_MINOMAXDISPLAY), + BE(f_Mnm, EDIF_TOK_MNM), + BE(f_MultipleValueSet, EDIF_TOK_MULTIPLEVALUESET), + BE(f_MustJoin, EDIF_TOK_MUSTJOIN), + BE(f_Name, EDIF_TOK_NAME), + BE(f_Net, EDIF_TOK_NET), + BE(f_NetBackAnnotate, EDIF_TOK_NETBACKANNOTATE), + BE(f_NetBundle, EDIF_TOK_NETBUNDLE), + BE(f_NetDelay, EDIF_TOK_NETDELAY), + BE(f_NetGroup, EDIF_TOK_NETGROUP), + BE(f_NetMap, EDIF_TOK_NETMAP), + BE(f_NetRef, EDIF_TOK_NETREF), + BE(f_NonPermutable, EDIF_TOK_NONPERMUTABLE), + BE(f_NotAllowed, EDIF_TOK_NOTALLOWED), + BE(f_NotchSpacing, EDIF_TOK_NOTCHSPACING), + BE(f_Number, EDIF_TOK_NUMBER), + BE(f_NumberDefinition, EDIF_TOK_NUMBERDEFINITION), + BE(f_NumberDisplay, EDIF_TOK_NUMBERDISPLAY), + BE(f_OffPageConnector, EDIF_TOK_OFFPAGECONNECTOR), + BE(f_OffsetEvent, EDIF_TOK_OFFSETEVENT), + BE(f_OpenShape, EDIF_TOK_OPENSHAPE), + BE(f_Origin, EDIF_TOK_ORIGIN), + BE(f_OverhangDistance, EDIF_TOK_OVERHANGDISTANCE), + BE(f_OverlapDistance, EDIF_TOK_OVERLAPDISTANCE), + BE(f_Oversize, EDIF_TOK_OVERSIZE), + BE(f_Page, EDIF_TOK_PAGE), + BE(f_PageSize, EDIF_TOK_PAGESIZE), + BE(f_Parameter, EDIF_TOK_PARAMETER), + BE(f_ParameterAssign, EDIF_TOK_PARAMETERASSIGN), + BE(f_ParameterDisplay, EDIF_TOK_PARAMETERDISPLAY), + BE(f_Path, EDIF_TOK_PATH), + BE(f_PathDelay, EDIF_TOK_PATHDELAY), + BE(f_Permutable, EDIF_TOK_PERMUTABLE), + BE(f_PhysicalDesignRule, EDIF_TOK_PHYSICALDESIGNRULE), + BE(f_Plug, EDIF_TOK_PLUG), + BE(f_Point, EDIF_TOK_POINT), + BE(f_PointDisplay, EDIF_TOK_POINTDISPLAY), + BE(f_PointList, EDIF_TOK_POINTLIST), + BE(f_Polygon, EDIF_TOK_POLYGON), + BE(f_Port, EDIF_TOK_PORT), + BE(f_PortBackAnnotate, EDIF_TOK_PORTBACKANNOTATE), + BE(f_PortBundle, EDIF_TOK_PORTBUNDLE), + BE(f_PortDelay, EDIF_TOK_PORTDELAY), + BE(f_PortGroup, EDIF_TOK_PORTGROUP), + BE(f_PortImplementation, EDIF_TOK_PORTIMPLEMENTATION), + BE(f_PortInstance, EDIF_TOK_PORTINSTANCE), + BE(f_PortList, EDIF_TOK_PORTLIST), + BE(f_PortListAlias, EDIF_TOK_PORTLISTALIAS), + BE(f_PortMap, EDIF_TOK_PORTMAP), + BE(f_PortRef, EDIF_TOK_PORTREF), + BE(f_Program, EDIF_TOK_PROGRAM), + BE(f_Property, EDIF_TOK_PROPERTY), + BE(f_PropertyDisplay, EDIF_TOK_PROPERTYDISPLAY), + BE(f_ProtectionFrame, EDIF_TOK_PROTECTIONFRAME), + BE(f_RangeVector, EDIF_TOK_RANGEVECTOR), + BE(f_Rectangle, EDIF_TOK_RECTANGLE), + BE(f_RectangleSize, EDIF_TOK_RECTANGLESIZE), + BE(f_Rename, EDIF_TOK_RENAME), + BE(f_Resolves, EDIF_TOK_RESOLVES), + BE(f_Scale, EDIF_TOK_SCALE), + BE(f_Section, EDIF_TOK_SECTION), + BE(f_Shape, EDIF_TOK_SHAPE), + BE(f_Simulate, EDIF_TOK_SIMULATE), + BE(f_SimulationInfo, EDIF_TOK_SIMULATIONINFO), + BE(f_SingleValueSet, EDIF_TOK_SINGLEVALUESET), + BE(f_Site, EDIF_TOK_SITE), + BE(f_Socket, EDIF_TOK_SOCKET), + BE(f_SocketSet, EDIF_TOK_SOCKETSET), + BE(f_Status, EDIF_TOK_STATUS), + BE(f_Steady, EDIF_TOK_STEADY), + BE(f_String, EDIF_TOK_STRING), + BE(f_StringDisplay, EDIF_TOK_STRINGDISPLAY), + BE(f_Strong, EDIF_TOK_STRONG), + BE(f_Symbol, EDIF_TOK_SYMBOL), + BE(f_Symmetry, EDIF_TOK_SYMMETRY), + BE(f_Table, EDIF_TOK_TABLE), + BE(f_TableDefault, EDIF_TOK_TABLEDEFAULT), + BE(f_Technology, EDIF_TOK_TECHNOLOGY), + BE(f_TimeInterval, EDIF_TOK_TIMEINTERVAL), + BE(f_Timing, EDIF_TOK_TIMING), + BE(f_Transform, EDIF_TOK_TRANSFORM), + BE(f_Transition, EDIF_TOK_TRANSITION), + BE(f_Trigger, EDIF_TOK_TRIGGER), + BE(f_Union, EDIF_TOK_UNION), + BE(f_View, EDIF_TOK_VIEW), + BE(f_ViewList, EDIF_TOK_VIEWLIST), + BE(f_ViewMap, EDIF_TOK_VIEWMAP), + BE(f_ViewRef, EDIF_TOK_VIEWREF), + BE(f_Visible, EDIF_TOK_VISIBLE), + BE(f_VoltageMap, EDIF_TOK_VOLTAGEMAP), + BE(f_WaveValue, EDIF_TOK_WAVEVALUE), + BE(f_Weak, EDIF_TOK_WEAK), + BE(f_WeakJoined, EDIF_TOK_WEAKJOINED), + BE(f_When, EDIF_TOK_WHEN), + BE(f_Written, EDIF_TOK_WRITTEN) +}; +static int BinderDefSize = sizeof(BinderDef) / sizeof(Binder); +/* + * Keyword table: + * + * This hash table holds all strings which may have to be matched + * to. WARNING: it is assumed that there is no overlap of the 'token' + * and 'context' strings. + */ +typedef struct Keyword { + struct Keyword *Next; /* pointer to next entry */ + const char *String; /* pointer to associated string */ +} Keyword; +#define KEYWORD_HASH 127 /* hash table size */ +static Keyword *KeywordTable[KEYWORD_HASH]; +/* + * Enter keyword: + * + * The passed string is entered into the keyword hash table. + */ +static void EnterKeyword(const char * str) +{ + /* + * Locals. + */ + register Keyword *key; + register unsigned int hsh; + register const char *cp; + /* + * Create the hash code, and add an entry to the table. + */ + for (hsh = 0, cp = str; *cp; hsh += hsh + *cp++); + hsh %= KEYWORD_HASH; + key = (Keyword *) Malloc(sizeof(Keyword)); + key->Next = KeywordTable[hsh]; + (KeywordTable[hsh] = key)->String = str; +} +/* + * Find keyword: + * + * The passed string is located within the keyword table. If an + * entry exists, then the value of the keyword string is returned. This + * is real useful for doing string comparisons by pointer value later. + * If there is no match, a NULL is returned. + */ +static const char *FindKeyword(const char * str) +{ + /* + * Locals. + */ + register Keyword *wlk,*owk; + register unsigned int hsh; + register char *cp; + char lower[IDENT_LENGTH + 1]; + /* + * Create a lower case copy of the string. + */ + for (cp = lower; *str;) + if (isupper( (int) *str)) + *cp++ = tolower( (int) *str++); + else + *cp++ = *str++; + *cp = '\0'; + /* + * Search the hash table for a match. + */ + for (hsh = 0, cp = lower; *cp; hsh += hsh + *cp++); + hsh %= KEYWORD_HASH; + for (owk = NULL, wlk = KeywordTable[hsh]; wlk; wlk = (owk = wlk)->Next) + if (!strcmp(wlk->String,lower)){ + /* + * Readjust the LRU. + */ + if (owk){ + owk->Next = wlk->Next; + wlk->Next = KeywordTable[hsh]; + KeywordTable[hsh] = wlk; + } + return (wlk->String); + } + return NULL; +} +/* + * Token hash table. + */ +#define TOKEN_HASH 51 +static Token *TokenHash[TOKEN_HASH]; +/* + * Find token: + * + * A pointer to the token of the passed code is returned. If + * no such beastie is present a NULL is returned instead. + */ +static Token *FindToken(register int cod) +{ + /* + * Locals. + */ + register Token *wlk,*owk; + register unsigned int hsh; + /* + * Search the hash table for a matching token. + */ + hsh = cod % TOKEN_HASH; + for (owk = NULL, wlk = TokenHash[hsh]; wlk; wlk = (owk = wlk)->Next) + if (cod == wlk->Code){ + if (owk){ + owk->Next = wlk->Next; + wlk->Next = TokenHash[hsh]; + TokenHash[hsh] = wlk; + } + break; + } + return wlk; +} +/* + * Context hash table. + */ +#define CONTEXT_HASH 127 +static Context *ContextHash[CONTEXT_HASH]; +/* + * Find context: + * + * A pointer to the context of the passed code is returned. If + * no such beastie is present a NULL is returned instead. + */ +static Context *FindContext(register int cod) +{ + /* + * Locals. + */ + register Context *wlk,*owk; + register unsigned int hsh; + /* + * Search the hash table for a matching context. + */ + hsh = cod % CONTEXT_HASH; + for (owk = NULL, wlk = ContextHash[hsh]; wlk; wlk = (owk = wlk)->Next) + if (cod == wlk->Code){ + if (owk){ + owk->Next = wlk->Next; + wlk->Next = ContextHash[hsh]; + ContextHash[hsh] = wlk; + } + break; + } + return wlk; +} +/* + * Token stacking variables. + */ +#ifdef DEBUG +#define TS_DEPTH 8 +#define TS_MASK (TS_DEPTH - 1) +static unsigned int TSP = 0; /* token stack pointer */ +static char *TokenStack[TS_DEPTH]; /* token name strings */ +static short TokenType[TS_DEPTH]; /* token types */ +/* + * Stack: + * + * Add a token to the debug stack. The passed string and type are + * what is to be pushed. + */ +static void Stack(char * str, int typ) +{ + /* + * Free any previous string, then push. + */ + if (TokenStack[TSP & TS_MASK]) + Free(TokenStack[TSP & TS_MASK]); + TokenStack[TSP & TS_MASK] = strcpy((char *)Malloc(strlen(str) + 1),str); + TokenType[TSP & TS_MASK] = typ; + TSP += 1; +} +/* + * Dump stack: + * + * This displays the last set of accumulated tokens. + */ +static void DumpStack() +{ + /* + * Locals. + */ + register int i; + register Context *cxt; + register Token *tok; + register char *nam; + FILE *Error = stderr; + /* + * Run through the list displaying the oldest first. + */ + fprintf(Error,"\n\n"); + for (i = 0; i < TS_DEPTH; i += 1) + if (TokenStack[(TSP + i) & TS_MASK]){ + /* + * Get the type name string. + */ + if ((cxt = FindContext(TokenType[(TSP + i) & TS_MASK])) != NULL) + nam = cxt->Name; + else if ((tok = FindToken(TokenType[(TSP + i) & TS_MASK])) != NULL) + nam = tok->Name; + else switch (TokenType[(TSP + i) & TS_MASK]){ + case EDIF_TOK_IDENT: nam = "IDENT"; break; + case EDIF_TOK_INT: nam = "INT"; break; + case EDIF_TOK_KEYWORD: nam = "KEYWORD"; break; + case EDIF_TOK_STR: nam = "STR"; break; + default: nam = "?"; break; + } + /* + * Now print the token state. + */ + fprintf(Error,"%2d %-16.16s '%s'\n",TS_DEPTH - i,nam, + TokenStack[(TSP + i) & TS_MASK]); + } + fprintf(Error,"\n"); +} +#else +#define Stack(s,t) +#endif /* DEBUG */ +/* + * Parser state variables. + */ +static FILE *Input = NULL; /* input stream */ +static FILE *Error = NULL; /* error stream */ +static char *InFile; /* file name on the input stream */ +static long LineNumber; /* current input line number */ +static ContextCar *CSP = NULL; /* top of context stack */ +static char yytext[IDENT_LENGTH + 1]; /* token buffer */ +static char CharBuf[IDENT_LENGTH + 1]; /* garbage buffer */ +/* + * yyerror: + * + * Standard error reporter, it prints out the passed string + * preceeded by the current filename and line number. + */ +static void yyerror(const char *ers) +{ +#ifdef DEBUG + DumpStack(); +#endif /* DEBUG */ + rnd_message(RND_MSG_ERROR, "EDIF import error: %s, line %ld: %s\n",InFile,LineNumber,ers); +} +/* + * String bucket definitions. + */ +#define BUCKET_SIZE 64 +typedef struct Bucket { + struct Bucket *Next; /* pointer to next bucket */ + int Index; /* pointer to next free slot */ + char Data[BUCKET_SIZE]; /* string data */ +} Bucket; +static Bucket *CurrentBucket = NULL; /* string bucket list */ +static int StringSize = 0; /* current string length */ +/* + * Push string: + * + * This adds the passed charater to the current string bucket. + */ +static void PushString(char chr) +{ + /* + * Locals. + */ + register Bucket *bck; + /* + * Make sure there is room for the push. + */ + if ((bck = CurrentBucket)->Index >= BUCKET_SIZE){ + bck = (Bucket *) Malloc(sizeof(Bucket)); + bck->Next = CurrentBucket; + (CurrentBucket = bck)->Index = 0; + } + /* + * Push the character. + */ + bck->Data[bck->Index++] = chr; + StringSize += 1; +} +/* + * Form string: + * + * This converts the current string bucket into a real live string, + * whose pointer is returned. + */ +static char *FormString() +{ + /* + * Locals. + */ + register Bucket *bck; + register char *cp; + /* + * Allocate space for the string, set the pointer at the end. + */ + cp = (char *) Malloc(StringSize + 1); + + cp += StringSize; + *cp-- = '\0'; + /* + * Yank characters out of the bucket. + */ + for (bck = CurrentBucket; bck->Index || bck->Next;){ + if (!bck->Index){ + CurrentBucket = bck->Next; + Free(bck); + bck = CurrentBucket; + } + *cp-- = bck->Data[--bck->Index]; + } + /* reset buffer size to zero */ + StringSize =0; + return (cp + 1); +} +/* + * Parse EDIF: + * + * This builds the context tree and then calls the real parser. + * It is passed two file streams, the first is where the input comes + * from; the second is where error messages get printed. + */ +void ParseEDIF(char* filename,FILE* err) +{ + /* + * Locals. + */ + register int i; + static int ContextDefined = 1; + /* + * Set up the file state to something useful. + */ + InFile = filename; + Input = rnd_fopen(&PCB->hidlib, filename, "r"); + Error = err; + LineNumber = 1; + /* + * Define both the enabled token and context strings. + */ + if (ContextDefined){ + for (i = TokenDefSize; i--; EnterKeyword(TokenDef[i].Name)){ + register unsigned int hsh; + hsh = TokenDef[i].Code % TOKEN_HASH; + TokenDef[i].Next = TokenHash[hsh]; + TokenHash[hsh] = &TokenDef[i]; + } + for (i = ContextDefSize; i--; EnterKeyword(ContextDef[i].Name)){ + register unsigned int hsh; + hsh = ContextDef[i].Code % CONTEXT_HASH; + ContextDef[i].Next = ContextHash[hsh]; + ContextHash[hsh] = &ContextDef[i]; + } + /* + * Build the context tree. + */ + for (i = BinderDefSize; i--;){ + register Context *cxt; + register int j; + /* + * Define the current context to have carriers bound to it. + */ + cxt = FindContext(BinderDef[i].Origin); + for (j = BinderDef[i].FollowerSize; j--;){ + register ContextCar *cc; + /* + * Add carriers to the current context. + */ + cc = (ContextCar *) Malloc(sizeof(ContextCar)); + cc->Next = cxt->Context; + (cxt->Context = cc)->Context = + FindContext(RND_ABS(BinderDef[i].Follower[j])); + cc->u.Single = BinderDef[i].Follower[j] < 0; + } + } + /* + * Build the token tree. + */ + for (i = TieDefSize; i--;){ + register Context *cxt; + register int j; + /* + * Define the current context to have carriers bound to it. + */ + cxt = FindContext(TieDef[i].Origin); + for (j = TieDef[i].EnableSize; j--;){ + register TokenCar *tc; + /* + * Add carriers to the current context. + */ + tc = (TokenCar *) Malloc(sizeof(TokenCar)); + tc->Next = cxt->Token; + (cxt->Token = tc)->Token = FindToken(TieDef[i].Enable[j]); + } + } + /* + * Put a bogus context on the stack which has 'EDIF' as its + * follower. + */ + CSP = (ContextCar *) Malloc(sizeof(ContextCar)); + CSP->Next = NULL; + CSP->Context = FindContext(0); + CSP->u.Used = NULL; + ContextDefined = 0; + } + /* + * Create an initial, empty string bucket. + */ + CurrentBucket = (Bucket *) Malloc(sizeof(Bucket)); + CurrentBucket->Next = 0; + CurrentBucket->Index = 0; + /* + * Fill the token stack with NULLs if debugging is enabled. + */ +#ifdef DEBUG + for (i = TS_DEPTH; i--; TokenStack[i] = NULL) + if (TokenStack[i]) + Free(TokenStack[i]); + TSP = 0; +#endif /* DEBUG */ + /* + * Go parse things! + */ + edifparse(); +} +/* + * Match token: + * + * The passed string is looked up in the current context's token + * list to see if it is enabled. If so the token value is returned, + * if not then zero. + */ +static int MatchToken(register const char * str) +{ + /* + * Locals. + */ + register TokenCar *wlk,*owk; + /* + * Convert the string to the proper form, then search the token + * carrier list for a match. + */ + str = FindKeyword(str); + for (owk = NULL, wlk = CSP->Context->Token; wlk; wlk = (owk = wlk)->Next) + if (str == wlk->Token->Name){ + if (owk){ + owk->Next = wlk->Next; + wlk->Next = CSP->Context->Token; + CSP->Context->Token = wlk; + } + return (wlk->Token->Code); + } + return 0; +} +/* + * Match context: + * + * If the passed keyword string is within the current context, the + * new context is pushed and token value is returned. A zero otherwise. + */ +static int MatchContext(register const char * str) +{ + /* + * Locals. + */ + register ContextCar *wlk,*owk; + /* + * See if the context is present. + */ + str = FindKeyword(str); + for (owk = NULL, wlk = CSP->Context->Context; wlk; wlk = (owk = wlk)->Next) + if (str == wlk->Context->Name){ + if (owk){ + owk->Next = wlk->Next; + wlk->Next = CSP->Context->Context; + CSP->Context->Context = wlk; + } + /* + * If a single context, make sure it isn't already used. + */ + if (wlk->u.Single){ + register UsedCar *usc; + for (usc = CSP->u.Used; usc; usc = usc->Next) + if (usc->Code == wlk->Context->Code) + break; + if (usc){ + sprintf(CharBuf,"'%s' is used more than once within '%s'", + str,CSP->Context->Name); + yyerror(CharBuf); + } else { + usc = (UsedCar *) Malloc(sizeof(UsedCar)); + usc->Next = CSP->u.Used; + (CSP->u.Used = usc)->Code = wlk->Context->Code; + } + } + /* + * Push the new context. + */ + owk = (ContextCar *) Malloc(sizeof(ContextCar)); + owk->Next = CSP; + (CSP = owk)->Context = wlk->Context; + owk->u.Used = NULL; + return (wlk->Context->Code); + } + return 0; +} +/* + * PopC: + * + * This pops the current context. + */ +static void PopC() +{ + /* + * Locals. + */ + register UsedCar *usc; + register ContextCar *csp; + /* + * Release single markers and pop context. + */ + while ( (usc = CSP->u.Used) ){ + CSP->u.Used = usc->Next; + Free(usc); + } + csp = CSP->Next; + Free(CSP); + CSP = csp; +} +/* + * Lexical analyzer states. + */ +#define L_START 0 +#define L_INT 1 +#define L_IDENT 2 +#define L_KEYWORD 3 +#define L_STRING 4 +#define L_KEYWORD2 5 +#define L_ASCIICHAR 6 +#define L_ASCIICHAR2 7 +/* + * yylex: + * + * This is the lexical analyzer called by the YACC/BISON parser. + * It returns a pretty restricted set of token types and does the + * context movement when acceptable keywords are found. The token + * value returned is a NULL terminated string to allocated storage + * (ie - it should get released some time) with some restrictions. + * The token value for integers is strips a leading '+' if present. + * String token values have the leading and trailing '"'-s stripped. + * '%' conversion characters in string values are passed converted. + * The '(' and ')' characters do not have a token value. + */ +static int yylex() +{ + /* + * Locals. + */ + register int c,s,l; + /* + * Keep on sucking up characters until we find something which + * explicitly forces us out of this function. + */ + for (s = L_START, l = 0; 1;){ + yytext[l++] = c = Getc(Input); + switch (s){ + /* + * Starting state, look for something resembling a token. + */ + case L_START: + if (isdigit(c) || c == '-') + s = L_INT; + else if (isalpha(c) || c == '&') + s = L_IDENT; + else if (isspace(c)){ + if (c == '\n') + LineNumber += 1; + l = 0; + } else if (c == '('){ + l = 0; + s = L_KEYWORD; + } else if (c == '"') + s = L_STRING; + else if (c == '+'){ + l = 0; /* strip '+' */ + s = L_INT; + } else if (c == EOF) + return ('\0'); + else { + yytext[1] = '\0'; + Stack(yytext,c); + return c; + } + break; + /* + * Suck up the integer digits. + */ + case L_INT: + if (isdigit(c)) + break; + Ungetc(c); + yytext[--l] = '\0'; + yylval.s = strcpy((char *)Malloc(l + 1),yytext); + Stack(yytext,EDIF_TOK_INT); + return EDIF_TOK_INT; + /* + * Grab an identifier, see if the current context enables + * it with a specific token value. + */ + case L_IDENT: + if (isalpha(c) || isdigit(c) || c == '_') + break; + Ungetc(c); + yytext[--l] = '\0'; + if (CSP->Context->Token && (c = MatchToken(yytext))){ + Stack(yytext,c); + return c; + } + yylval.s = strcpy((char *)Malloc(l + 1),yytext); + Stack(yytext, EDIF_TOK_IDENT); + return EDIF_TOK_IDENT; + /* + * Scan until you find the start of an identifier, discard + * any whitespace found. On no identifier, return a '('. + */ + case L_KEYWORD: + if (isalpha(c) || c == '&'){ + s = L_KEYWORD2; + break; + } else if (isspace(c)){ + l = 0; + break; + } + Ungetc(c); + Stack("(",'('); + return ('('); + /* + * Suck up the keyword identifier, if it matches the set of + * allowable contexts then return its token value and push + * the context, otherwise just return the identifier string. + */ + case L_KEYWORD2: + if (isalpha(c) || isdigit(c) || c == '_') + break; + Ungetc(c); + yytext[--l] = '\0'; + if ( (c = MatchContext(yytext)) ){ + Stack(yytext,c); + return c; + } + yylval.s = strcpy((char *)Malloc(l + 1),yytext); + Stack(yytext, EDIF_TOK_KEYWORD); + return EDIF_TOK_KEYWORD; + /* + * Suck up string characters but once resolved they should + * be deposited in the string bucket because they can be + * arbitrarily long. + */ + case L_STRING: + if (c == '\n') + LineNumber += 1; + else if (c == '\r') + ; + else if (c == '"' || c == EOF){ + yylval.s = FormString(); + Stack(yylval.s, EDIF_TOK_STR); + return EDIF_TOK_STR; + } else if (c == '%') + s = L_ASCIICHAR; + else + PushString(c); + l = 0; + break; + /* + * Skip white space and look for integers to be pushed + * as characters. + */ + case L_ASCIICHAR: + if (isdigit(c)){ + s = L_ASCIICHAR2; + break; + } else if (c == '%' || c == EOF) + s = L_STRING; + else if (c == '\n') + LineNumber += 1; + l = 0; + break; + /* + * Convert the accumulated integer into a char and push. + */ + case L_ASCIICHAR2: + if (isdigit(c)) + break; + Ungetc(c); + yytext[--l] = '\0'; + PushString(atoi(yytext)); + s = L_ASCIICHAR; + l = 0; + break; + } + } +} + +int ReadEdifNetlist(char *filename) +{ + rnd_message(RND_MSG_INFO,"Importing edif netlist %s\n", filename); + ParseEDIF(filename, NULL); + + return 0; +} Index: tags/2.3.0/src_plugins/import_edif/edif.h =================================================================== --- tags/2.3.0/src_plugins/import_edif/edif.h (nonexistent) +++ tags/2.3.0/src_plugins/import_edif/edif.h (revision 33253) @@ -0,0 +1,371 @@ +/* A Bison parser, made by GNU Bison 3.3.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. + + 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 3 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, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +#ifndef YY_EDIF_EDIF_H_INCLUDED +# define YY_EDIF_EDIF_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int edifdebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + EDIF_TOK_IDENT = 258, + EDIF_TOK_INT = 259, + EDIF_TOK_KEYWORD = 260, + EDIF_TOK_STR = 261, + EDIF_TOK_ANGLE = 262, + EDIF_TOK_BEHAVIOR = 263, + EDIF_TOK_CALCULATED = 264, + EDIF_TOK_CAPACITANCE = 265, + EDIF_TOK_CENTERCENTER = 266, + EDIF_TOK_CENTERLEFT = 267, + EDIF_TOK_CENTERRIGHT = 268, + EDIF_TOK_CHARGE = 269, + EDIF_TOK_CONDUCTANCE = 270, + EDIF_TOK_CURRENT = 271, + EDIF_TOK_DISTANCE = 272, + EDIF_TOK_DOCUMENT = 273, + EDIF_TOK_ENERGY = 274, + EDIF_TOK_EXTEND = 275, + EDIF_TOK_FLUX = 276, + EDIF_TOK_FREQUENCY = 277, + EDIF_TOK_GENERIC = 278, + EDIF_TOK_GRAPHIC = 279, + EDIF_TOK_INDUCTANCE = 280, + EDIF_TOK_INOUT = 281, + EDIF_TOK_INPUT = 282, + EDIF_TOK_LOGICMODEL = 283, + EDIF_TOK_LOWERCENTER = 284, + EDIF_TOK_LOWERLEFT = 285, + EDIF_TOK_LOWERRIGHT = 286, + EDIF_TOK_MASKLAYOUT = 287, + EDIF_TOK_MASS = 288, + EDIF_TOK_MEASURED = 289, + EDIF_TOK_MX = 290, + EDIF_TOK_MXR90 = 291, + EDIF_TOK_MY = 292, + EDIF_TOK_MYR90 = 293, + EDIF_TOK_NETLIST = 294, + EDIF_TOK_OUTPUT = 295, + EDIF_TOK_PCBLAYOUT = 296, + EDIF_TOK_POWER = 297, + EDIF_TOK_R0 = 298, + EDIF_TOK_R180 = 299, + EDIF_TOK_R270 = 300, + EDIF_TOK_R90 = 301, + EDIF_TOK_REQUIRED = 302, + EDIF_TOK_RESISTANCE = 303, + EDIF_TOK_RIPPER = 304, + EDIF_TOK_ROUND = 305, + EDIF_TOK_SCHEMATIC = 306, + EDIF_TOK_STRANGER = 307, + EDIF_TOK_SYMBOLIC = 308, + EDIF_TOK_TEMPERATURE = 309, + EDIF_TOK_TIE = 310, + EDIF_TOK_TIME = 311, + EDIF_TOK_TRUNCATE = 312, + EDIF_TOK_UPPERCENTER = 313, + EDIF_TOK_UPPERLEFT = 314, + EDIF_TOK_UPPERRIGHT = 315, + EDIF_TOK_VOLTAGE = 316, + EDIF_TOK_ACLOAD = 317, + EDIF_TOK_AFTER = 318, + EDIF_TOK_ANNOTATE = 319, + EDIF_TOK_APPLY = 320, + EDIF_TOK_ARC = 321, + EDIF_TOK_ARRAY = 322, + EDIF_TOK_ARRAYMACRO = 323, + EDIF_TOK_ARRAYRELATEDINFO = 324, + EDIF_TOK_ARRAYSITE = 325, + EDIF_TOK_ATLEAST = 326, + EDIF_TOK_ATMOST = 327, + EDIF_TOK_AUTHOR = 328, + EDIF_TOK_BASEARRAY = 329, + EDIF_TOK_BECOMES = 330, + EDIF_TOK_BETWEEN = 331, + EDIF_TOK_BOOLEAN = 332, + EDIF_TOK_BOOLEANDISPLAY = 333, + EDIF_TOK_BOOLEANMAP = 334, + EDIF_TOK_BORDERPATTERN = 335, + EDIF_TOK_BORDERWIDTH = 336, + EDIF_TOK_BOUNDINGBOX = 337, + EDIF_TOK_CELL = 338, + EDIF_TOK_CELLREF = 339, + EDIF_TOK_CELLTYPE = 340, + EDIF_TOK_CHANGE = 341, + EDIF_TOK_CIRCLE = 342, + EDIF_TOK_COLOR = 343, + EDIF_TOK_COMMENT = 344, + EDIF_TOK_COMMENTGRAPHICS = 345, + EDIF_TOK_COMPOUND = 346, + EDIF_TOK_CONNECTLOCATION = 347, + EDIF_TOK_CONTENTS = 348, + EDIF_TOK_CORNERTYPE = 349, + EDIF_TOK_CRITICALITY = 350, + EDIF_TOK_CURRENTMAP = 351, + EDIF_TOK_CURVE = 352, + EDIF_TOK_CYCLE = 353, + EDIF_TOK_DATAORIGIN = 354, + EDIF_TOK_DCFANINLOAD = 355, + EDIF_TOK_DCFANOUTLOAD = 356, + EDIF_TOK_DCMAXFANIN = 357, + EDIF_TOK_DCMAXFANOUT = 358, + EDIF_TOK_DELAY = 359, + EDIF_TOK_DELTA = 360, + EDIF_TOK_DERIVATION = 361, + EDIF_TOK_DESIGN = 362, + EDIF_TOK_DESIGNATOR = 363, + EDIF_TOK_DIFFERENCE = 364, + EDIF_TOK_DIRECTION = 365, + EDIF_TOK_DISPLAY = 366, + EDIF_TOK_DOMINATES = 367, + EDIF_TOK_DOT = 368, + EDIF_TOK_DURATION = 369, + EDIF_TOK_E = 370, + EDIF_TOK_EDIF = 371, + EDIF_TOK_EDIFLEVEL = 372, + EDIF_TOK_EDIFVERSION = 373, + EDIF_TOK_ENCLOSUREDISTANCE = 374, + EDIF_TOK_ENDTYPE = 375, + EDIF_TOK_ENTRY = 376, + EDIF_TOK_EVENT = 377, + EDIF_TOK_EXACTLY = 378, + EDIF_TOK_EXTERNAL = 379, + EDIF_TOK_FABRICATE = 380, + EDIF_TOK_FALSE = 381, + EDIF_TOK_FIGURE = 382, + EDIF_TOK_FIGUREAREA = 383, + EDIF_TOK_FIGUREGROUP = 384, + EDIF_TOK_FIGUREGROUPOBJECT = 385, + EDIF_TOK_FIGUREGROUPOVERRIDE = 386, + EDIF_TOK_FIGUREGROUPREF = 387, + EDIF_TOK_FIGUREPERIMETER = 388, + EDIF_TOK_FIGUREWIDTH = 389, + EDIF_TOK_FILLPATTERN = 390, + EDIF_TOK_FOLLOW = 391, + EDIF_TOK_FORBIDDENEVENT = 392, + EDIF_TOK_GLOBALPORTREF = 393, + EDIF_TOK_GREATERTHAN = 394, + EDIF_TOK_GRIDMAP = 395, + EDIF_TOK_IGNORE = 396, + EDIF_TOK_INCLUDEFIGUREGROUP = 397, + EDIF_TOK_INITIAL = 398, + EDIF_TOK_INSTANCE = 399, + EDIF_TOK_INSTANCEBACKANNOTATE = 400, + EDIF_TOK_INSTANCEGROUP = 401, + EDIF_TOK_INSTANCEMAP = 402, + EDIF_TOK_INSTANCEREF = 403, + EDIF_TOK_INTEGER = 404, + EDIF_TOK_INTEGERDISPLAY = 405, + EDIF_TOK_INTERFACE = 406, + EDIF_TOK_INTERFIGUREGROUPSPACING = 407, + EDIF_TOK_INTERSECTION = 408, + EDIF_TOK_INTRAFIGUREGROUPSPACING = 409, + EDIF_TOK_INVERSE = 410, + EDIF_TOK_ISOLATED = 411, + EDIF_TOK_JOINED = 412, + EDIF_TOK_JUSTIFY = 413, + EDIF_TOK_KEYWORDDISPLAY = 414, + EDIF_TOK_KEYWORDLEVEL = 415, + EDIF_TOK_KEYWORDMAP = 416, + EDIF_TOK_LESSTHAN = 417, + EDIF_TOK_LIBRARY = 418, + EDIF_TOK_LIBRARYREF = 419, + EDIF_TOK_LISTOFNETS = 420, + EDIF_TOK_LISTOFPORTS = 421, + EDIF_TOK_LOADDELAY = 422, + EDIF_TOK_LOGICASSIGN = 423, + EDIF_TOK_LOGICINPUT = 424, + EDIF_TOK_LOGICLIST = 425, + EDIF_TOK_LOGICMAPINPUT = 426, + EDIF_TOK_LOGICMAPOUTPUT = 427, + EDIF_TOK_LOGICONEOF = 428, + EDIF_TOK_LOGICOUTPUT = 429, + EDIF_TOK_LOGICPORT = 430, + EDIF_TOK_LOGICREF = 431, + EDIF_TOK_LOGICVALUE = 432, + EDIF_TOK_LOGICWAVEFORM = 433, + EDIF_TOK_MAINTAIN = 434, + EDIF_TOK_MATCH = 435, + EDIF_TOK_MEMBER = 436, + EDIF_TOK_MINOMAX = 437, + EDIF_TOK_MINOMAXDISPLAY = 438, + EDIF_TOK_MNM = 439, + EDIF_TOK_MULTIPLEVALUESET = 440, + EDIF_TOK_MUSTJOIN = 441, + EDIF_TOK_NAME = 442, + EDIF_TOK_NET = 443, + EDIF_TOK_NETBACKANNOTATE = 444, + EDIF_TOK_NETBUNDLE = 445, + EDIF_TOK_NETDELAY = 446, + EDIF_TOK_NETGROUP = 447, + EDIF_TOK_NETMAP = 448, + EDIF_TOK_NETREF = 449, + EDIF_TOK_NOCHANGE = 450, + EDIF_TOK_NONPERMUTABLE = 451, + EDIF_TOK_NOTALLOWED = 452, + EDIF_TOK_NOTCHSPACING = 453, + EDIF_TOK_NUMBER = 454, + EDIF_TOK_NUMBERDEFINITION = 455, + EDIF_TOK_NUMBERDISPLAY = 456, + EDIF_TOK_OFFPAGECONNECTOR = 457, + EDIF_TOK_OFFSETEVENT = 458, + EDIF_TOK_OPENSHAPE = 459, + EDIF_TOK_ORIENTATION = 460, + EDIF_TOK_ORIGIN = 461, + EDIF_TOK_OVERHANGDISTANCE = 462, + EDIF_TOK_OVERLAPDISTANCE = 463, + EDIF_TOK_OVERSIZE = 464, + EDIF_TOK_OWNER = 465, + EDIF_TOK_PAGE = 466, + EDIF_TOK_PAGESIZE = 467, + EDIF_TOK_PARAMETER = 468, + EDIF_TOK_PARAMETERASSIGN = 469, + EDIF_TOK_PARAMETERDISPLAY = 470, + EDIF_TOK_PATH = 471, + EDIF_TOK_PATHDELAY = 472, + EDIF_TOK_PATHWIDTH = 473, + EDIF_TOK_PERMUTABLE = 474, + EDIF_TOK_PHYSICALDESIGNRULE = 475, + EDIF_TOK_PLUG = 476, + EDIF_TOK_POINT = 477, + EDIF_TOK_POINTDISPLAY = 478, + EDIF_TOK_POINTLIST = 479, + EDIF_TOK_POLYGON = 480, + EDIF_TOK_PORT = 481, + EDIF_TOK_PORTBACKANNOTATE = 482, + EDIF_TOK_PORTBUNDLE = 483, + EDIF_TOK_PORTDELAY = 484, + EDIF_TOK_PORTGROUP = 485, + EDIF_TOK_PORTIMPLEMENTATION = 486, + EDIF_TOK_PORTINSTANCE = 487, + EDIF_TOK_PORTLIST = 488, + EDIF_TOK_PORTLISTALIAS = 489, + EDIF_TOK_PORTMAP = 490, + EDIF_TOK_PORTREF = 491, + EDIF_TOK_PROGRAM = 492, + EDIF_TOK_PROPERTY = 493, + EDIF_TOK_PROPERTYDISPLAY = 494, + EDIF_TOK_PROTECTIONFRAME = 495, + EDIF_TOK_PT = 496, + EDIF_TOK_RANGEVECTOR = 497, + EDIF_TOK_RECTANGLE = 498, + EDIF_TOK_RECTANGLESIZE = 499, + EDIF_TOK_RENAME = 500, + EDIF_TOK_RESOLVES = 501, + EDIF_TOK_SCALE = 502, + EDIF_TOK_SCALEX = 503, + EDIF_TOK_SCALEY = 504, + EDIF_TOK_SECTION = 505, + EDIF_TOK_SHAPE = 506, + EDIF_TOK_SIMULATE = 507, + EDIF_TOK_SIMULATIONINFO = 508, + EDIF_TOK_SINGLEVALUESET = 509, + EDIF_TOK_SITE = 510, + EDIF_TOK_SOCKET = 511, + EDIF_TOK_SOCKETSET = 512, + EDIF_TOK_STATUS = 513, + EDIF_TOK_STEADY = 514, + EDIF_TOK_STRING = 515, + EDIF_TOK_STRINGDISPLAY = 516, + EDIF_TOK_STRONG = 517, + EDIF_TOK_SYMBOL = 518, + EDIF_TOK_SYMMETRY = 519, + EDIF_TOK_TABLE = 520, + EDIF_TOK_TABLEDEFAULT = 521, + EDIF_TOK_TECHNOLOGY = 522, + EDIF_TOK_TEXTHEIGHT = 523, + EDIF_TOK_TIMEINTERVAL = 524, + EDIF_TOK_TIMESTAMP = 525, + EDIF_TOK_TIMING = 526, + EDIF_TOK_TRANSFORM = 527, + EDIF_TOK_TRANSITION = 528, + EDIF_TOK_TRIGGER = 529, + EDIF_TOK_TRUE = 530, + EDIF_TOK_UNCONSTRAINED = 531, + EDIF_TOK_UNDEFINED = 532, + EDIF_TOK_UNION = 533, + EDIF_TOK_UNIT = 534, + EDIF_TOK_UNUSED = 535, + EDIF_TOK_USERDATA = 536, + EDIF_TOK_VERSION = 537, + EDIF_TOK_VIEW = 538, + EDIF_TOK_VIEWLIST = 539, + EDIF_TOK_VIEWMAP = 540, + EDIF_TOK_VIEWREF = 541, + EDIF_TOK_VIEWTYPE = 542, + EDIF_TOK_VISIBLE = 543, + EDIF_TOK_VOLTAGEMAP = 544, + EDIF_TOK_WAVEVALUE = 545, + EDIF_TOK_WEAK = 546, + EDIF_TOK_WEAKJOINED = 547, + EDIF_TOK_WHEN = 548, + EDIF_TOK_WRITTEN = 549 + }; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 196 "edif.y" /* yacc.c:1921 */ + + char* s; + pair_list* pl; + str_pair* ps; + +#line 359 "edif.h" /* yacc.c:1921 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE ediflval; + +int edifparse (void); + +#endif /* !YY_EDIF_EDIF_H_INCLUDED */ Index: tags/2.3.0/src_plugins/import_edif/edif.y =================================================================== --- tags/2.3.0/src_plugins/import_edif/edif.y (nonexistent) +++ tags/2.3.0/src_plugins/import_edif/edif.y (revision 33253) @@ -0,0 +1,4453 @@ +%{ +/* + * PCB Edif parser based heavily on: + * + * Header: edif.y,v 1.18 87/12/07 19:59:49 roger Locked + */ +/************************************************************************ + * * + * edif.y * + * * + * EDIF 2.0.0 parser, Level 0 * + * * + * You are free to copy, distribute, use it, abuse it, make it * + * write bad tracks all over the disk ... or anything else. * + * * + * Your friendly neighborhood Rogue Monster - roger@mips.com * + * * + ************************************************************************/ +#include + +/* for malloc, free, atoi */ +#include + +/* for strcpy */ +#include + +#include + +#include +#include "board.h" +#include "data.h" +#include +#include "netlist.h" +#include +#include +#include + +/* + * Local definitions. + */ +#define IDENT_LENGTH 255 +#define Malloc(s) malloc(s) +#define Free(p) free(p) +#define Getc(s) getc(s) +#define Ungetc(c) ungetc(c,Input) + + typedef struct _str_pair + { + char* str1; + char* str2; + struct _str_pair* next; + } str_pair; + + typedef struct _pair_list + { + char* name; + str_pair* list; + } pair_list; + + str_pair* new_str_pair(char* s1, char* s2) + { + str_pair* ps = (str_pair *)malloc(sizeof(str_pair)); + ps->str1 = s1; + ps->str2 = s2; + ps->next = NULL; + return ps; + } + + pair_list* new_pair_list(str_pair* ps) + { + pair_list* pl = (pair_list *)malloc(sizeof(pair_list)); + pl->list = ps; + pl->name = NULL; + return pl; + } + + void str_pair_free(str_pair* ps) + { + str_pair* node; + while ( ps ) + { + free(ps->str1); + free(ps->str2); + node = ps; + ps = ps->next; + free(node); + } + } + + void pair_list_free(pair_list* pl) + { + str_pair_free(pl->list); + free(pl->name); + free(pl); + } + + void define_pcb_net(str_pair* name, pair_list* nodes) + { + int tl; + str_pair* done_node; + str_pair* node; + char* buf; + char* p; + pcb_net_t *net; + + if ( !name->str1 ) + { + /* no net name given, stop now */ + /* if renamed str2 also exists and must be freed */ + if ( name->str2 ) free(name->str2); + free(name); + pair_list_free(nodes); + return; + } + net = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_INPUT], name->str1, PCB_NETA_ALLOC); + free(name->str1); + /* if renamed str2 also exists and must be freed */ + if ( name->str2 ) free(name->str2); + free(name); + buf = (char *)malloc(256); + if ( !buf ) + { + /* no memory */ + pair_list_free(nodes); + return; + } + + node = nodes->list; + free(nodes->name); + free(nodes); + while ( node ) + { + /* check for node with no instance */ + if ( !node->str1 ) + { + /* toss it and move on */ + free(node->str2); + done_node = node; + node = node->next; + free(done_node); + continue; + } + tl = strlen(node->str1) + strlen(node->str2); + if ( tl + 3 > 256 ) + { + free(buf); + buf = (char *)malloc(tl+3); + if ( !buf ) + { + /* no memory */ + str_pair_free(node); + return; + } + } + strcpy(buf,node->str1); + /* make all upper case, because of PCB funky behaviour */ + p=buf; + while ( *p ) + { + *p = toupper( (int) *p); + p++; + } + /* add dash separating designator from node */ + *(buf+strlen(node->str1)) = '-'; + /* check for the edif number prefix */ + if ( node->str2[0] == '&' ) + { + /* skip number prefix */ + strcpy(buf+strlen(node->str1)+1,node->str2 +1); + } + else + { + strcpy(buf+strlen(node->str1)+1,node->str2); + } + /* free the strings */ + free(node->str1); + free(node->str2); + + pcb_net_term_get_by_pinname(net, buf, PCB_NETA_ALLOC); + + done_node = node; + node = node->next; + free(done_node); + } + } + + +/* forward function declarations */ + static int yylex(void); + static void yyerror(const char *); + static void PopC(void); +%} + +%name-prefix "edif" + +%union { + char* s; + pair_list* pl; + str_pair* ps; +} + +%type Int Ident Str Keyword Name _Name +%type PortRef _PortRef NetNameDef NameDef +%type Rename _Joined +%type __Rename _Rename NameRef +%type InstanceRef InstNameRef Member PortNameRef +%type Net _Net Joined + +%token EDIF_TOK_IDENT +%token EDIF_TOK_INT +%token EDIF_TOK_KEYWORD +%token EDIF_TOK_STR + +%token EDIF_TOK_ANGLE +%token EDIF_TOK_BEHAVIOR +%token EDIF_TOK_CALCULATED +%token EDIF_TOK_CAPACITANCE +%token EDIF_TOK_CENTERCENTER +%token EDIF_TOK_CENTERLEFT +%token EDIF_TOK_CENTERRIGHT +%token EDIF_TOK_CHARGE +%token EDIF_TOK_CONDUCTANCE +%token EDIF_TOK_CURRENT +%token EDIF_TOK_DISTANCE +%token EDIF_TOK_DOCUMENT +%token EDIF_TOK_ENERGY +%token EDIF_TOK_EXTEND +%token EDIF_TOK_FLUX +%token EDIF_TOK_FREQUENCY +%token EDIF_TOK_GENERIC +%token EDIF_TOK_GRAPHIC +%token EDIF_TOK_INDUCTANCE +%token EDIF_TOK_INOUT +%token EDIF_TOK_INPUT +%token EDIF_TOK_LOGICMODEL +%token EDIF_TOK_LOWERCENTER +%token EDIF_TOK_LOWERLEFT +%token EDIF_TOK_LOWERRIGHT +%token EDIF_TOK_MASKLAYOUT +%token EDIF_TOK_MASS +%token EDIF_TOK_MEASURED +%token EDIF_TOK_MX +%token EDIF_TOK_MXR90 +%token EDIF_TOK_MY +%token EDIF_TOK_MYR90 +%token EDIF_TOK_NETLIST +%token EDIF_TOK_OUTPUT +%token EDIF_TOK_PCBLAYOUT +%token EDIF_TOK_POWER +%token EDIF_TOK_R0 +%token EDIF_TOK_R180 +%token EDIF_TOK_R270 +%token EDIF_TOK_R90 +%token EDIF_TOK_REQUIRED +%token EDIF_TOK_RESISTANCE +%token EDIF_TOK_RIPPER +%token EDIF_TOK_ROUND +%token EDIF_TOK_SCHEMATIC +%token EDIF_TOK_STRANGER +%token EDIF_TOK_SYMBOLIC +%token EDIF_TOK_TEMPERATURE +%token EDIF_TOK_TIE +%token EDIF_TOK_TIME +%token EDIF_TOK_TRUNCATE +%token EDIF_TOK_UPPERCENTER +%token EDIF_TOK_UPPERLEFT +%token EDIF_TOK_UPPERRIGHT +%token EDIF_TOK_VOLTAGE + +%token EDIF_TOK_ACLOAD +%token EDIF_TOK_AFTER +%token EDIF_TOK_ANNOTATE +%token EDIF_TOK_APPLY +%token EDIF_TOK_ARC +%token EDIF_TOK_ARRAY +%token EDIF_TOK_ARRAYMACRO +%token EDIF_TOK_ARRAYRELATEDINFO +%token EDIF_TOK_ARRAYSITE +%token EDIF_TOK_ATLEAST +%token EDIF_TOK_ATMOST +%token EDIF_TOK_AUTHOR +%token EDIF_TOK_BASEARRAY +%token EDIF_TOK_BECOMES +%token EDIF_TOK_BETWEEN +%token EDIF_TOK_BOOLEAN +%token EDIF_TOK_BOOLEANDISPLAY +%token EDIF_TOK_BOOLEANMAP +%token EDIF_TOK_BORDERPATTERN +%token EDIF_TOK_BORDERWIDTH +%token EDIF_TOK_BOUNDINGBOX +%token EDIF_TOK_CELL +%token EDIF_TOK_CELLREF +%token EDIF_TOK_CELLTYPE +%token EDIF_TOK_CHANGE +%token EDIF_TOK_CIRCLE +%token EDIF_TOK_COLOR +%token EDIF_TOK_COMMENT +%token EDIF_TOK_COMMENTGRAPHICS +%token EDIF_TOK_COMPOUND +%token EDIF_TOK_CONNECTLOCATION +%token EDIF_TOK_CONTENTS +%token EDIF_TOK_CORNERTYPE +%token EDIF_TOK_CRITICALITY +%token EDIF_TOK_CURRENTMAP +%token EDIF_TOK_CURVE +%token EDIF_TOK_CYCLE +%token EDIF_TOK_DATAORIGIN +%token EDIF_TOK_DCFANINLOAD +%token EDIF_TOK_DCFANOUTLOAD +%token EDIF_TOK_DCMAXFANIN +%token EDIF_TOK_DCMAXFANOUT +%token EDIF_TOK_DELAY +%token EDIF_TOK_DELTA +%token EDIF_TOK_DERIVATION +%token EDIF_TOK_DESIGN +%token EDIF_TOK_DESIGNATOR +%token EDIF_TOK_DIFFERENCE +%token EDIF_TOK_DIRECTION +%token EDIF_TOK_DISPLAY +%token EDIF_TOK_DOMINATES +%token EDIF_TOK_DOT +%token EDIF_TOK_DURATION +%token EDIF_TOK_E +%token EDIF_TOK_EDIF +%token EDIF_TOK_EDIFLEVEL +%token EDIF_TOK_EDIFVERSION +%token EDIF_TOK_ENCLOSUREDISTANCE +%token EDIF_TOK_ENDTYPE +%token EDIF_TOK_ENTRY +%token EDIF_TOK_EVENT +%token EDIF_TOK_EXACTLY +%token EDIF_TOK_EXTERNAL +%token EDIF_TOK_FABRICATE +%token EDIF_TOK_FALSE +%token EDIF_TOK_FIGURE +%token EDIF_TOK_FIGUREAREA +%token EDIF_TOK_FIGUREGROUP +%token EDIF_TOK_FIGUREGROUPOBJECT +%token EDIF_TOK_FIGUREGROUPOVERRIDE +%token EDIF_TOK_FIGUREGROUPREF +%token EDIF_TOK_FIGUREPERIMETER +%token EDIF_TOK_FIGUREWIDTH +%token EDIF_TOK_FILLPATTERN +%token EDIF_TOK_FOLLOW +%token EDIF_TOK_FORBIDDENEVENT +%token EDIF_TOK_GLOBALPORTREF +%token EDIF_TOK_GREATERTHAN +%token EDIF_TOK_GRIDMAP +%token EDIF_TOK_IGNORE +%token EDIF_TOK_INCLUDEFIGUREGROUP +%token EDIF_TOK_INITIAL +%token EDIF_TOK_INSTANCE +%token EDIF_TOK_INSTANCEBACKANNOTATE +%token EDIF_TOK_INSTANCEGROUP +%token EDIF_TOK_INSTANCEMAP +%token EDIF_TOK_INSTANCEREF +%token EDIF_TOK_INTEGER +%token EDIF_TOK_INTEGERDISPLAY +%token EDIF_TOK_INTERFACE +%token EDIF_TOK_INTERFIGUREGROUPSPACING +%token EDIF_TOK_INTERSECTION +%token EDIF_TOK_INTRAFIGUREGROUPSPACING +%token EDIF_TOK_INVERSE +%token EDIF_TOK_ISOLATED +%token EDIF_TOK_JOINED +%token EDIF_TOK_JUSTIFY +%token EDIF_TOK_KEYWORDDISPLAY +%token EDIF_TOK_KEYWORDLEVEL +%token EDIF_TOK_KEYWORDMAP +%token EDIF_TOK_LESSTHAN +%token EDIF_TOK_LIBRARY +%token EDIF_TOK_LIBRARYREF +%token EDIF_TOK_LISTOFNETS +%token EDIF_TOK_LISTOFPORTS +%token EDIF_TOK_LOADDELAY +%token EDIF_TOK_LOGICASSIGN +%token EDIF_TOK_LOGICINPUT +%token EDIF_TOK_LOGICLIST +%token EDIF_TOK_LOGICMAPINPUT +%token EDIF_TOK_LOGICMAPOUTPUT +%token EDIF_TOK_LOGICONEOF +%token EDIF_TOK_LOGICOUTPUT +%token EDIF_TOK_LOGICPORT +%token EDIF_TOK_LOGICREF +%token EDIF_TOK_LOGICVALUE +%token EDIF_TOK_LOGICWAVEFORM +%token EDIF_TOK_MAINTAIN +%token EDIF_TOK_MATCH +%token EDIF_TOK_MEMBER +%token EDIF_TOK_MINOMAX +%token EDIF_TOK_MINOMAXDISPLAY +%token EDIF_TOK_MNM +%token EDIF_TOK_MULTIPLEVALUESET +%token EDIF_TOK_MUSTJOIN +%token EDIF_TOK_NAME +%token EDIF_TOK_NET +%token EDIF_TOK_NETBACKANNOTATE +%token EDIF_TOK_NETBUNDLE +%token EDIF_TOK_NETDELAY +%token EDIF_TOK_NETGROUP +%token EDIF_TOK_NETMAP +%token EDIF_TOK_NETREF +%token EDIF_TOK_NOCHANGE +%token EDIF_TOK_NONPERMUTABLE +%token EDIF_TOK_NOTALLOWED +%token EDIF_TOK_NOTCHSPACING +%token EDIF_TOK_NUMBER +%token EDIF_TOK_NUMBERDEFINITION +%token EDIF_TOK_NUMBERDISPLAY +%token EDIF_TOK_OFFPAGECONNECTOR +%token EDIF_TOK_OFFSETEVENT +%token EDIF_TOK_OPENSHAPE +%token EDIF_TOK_ORIENTATION +%token EDIF_TOK_ORIGIN +%token EDIF_TOK_OVERHANGDISTANCE +%token EDIF_TOK_OVERLAPDISTANCE +%token EDIF_TOK_OVERSIZE +%token EDIF_TOK_OWNER +%token EDIF_TOK_PAGE +%token EDIF_TOK_PAGESIZE +%token EDIF_TOK_PARAMETER +%token EDIF_TOK_PARAMETERASSIGN +%token EDIF_TOK_PARAMETERDISPLAY +%token EDIF_TOK_PATH +%token EDIF_TOK_PATHDELAY +%token EDIF_TOK_PATHWIDTH +%token EDIF_TOK_PERMUTABLE +%token EDIF_TOK_PHYSICALDESIGNRULE +%token EDIF_TOK_PLUG +%token EDIF_TOK_POINT +%token EDIF_TOK_POINTDISPLAY +%token EDIF_TOK_POINTLIST +%token EDIF_TOK_POLYGON +%token EDIF_TOK_PORT +%token EDIF_TOK_PORTBACKANNOTATE +%token EDIF_TOK_PORTBUNDLE +%token EDIF_TOK_PORTDELAY +%token EDIF_TOK_PORTGROUP +%token EDIF_TOK_PORTIMPLEMENTATION +%token EDIF_TOK_PORTINSTANCE +%token EDIF_TOK_PORTLIST +%token EDIF_TOK_PORTLISTALIAS +%token EDIF_TOK_PORTMAP +%token EDIF_TOK_PORTREF +%token EDIF_TOK_PROGRAM +%token EDIF_TOK_PROPERTY +%token EDIF_TOK_PROPERTYDISPLAY +%token EDIF_TOK_PROTECTIONFRAME +%token EDIF_TOK_PT +%token EDIF_TOK_RANGEVECTOR +%token EDIF_TOK_RECTANGLE +%token EDIF_TOK_RECTANGLESIZE +%token EDIF_TOK_RENAME +%token EDIF_TOK_RESOLVES +%token EDIF_TOK_SCALE +%token EDIF_TOK_SCALEX +%token EDIF_TOK_SCALEY +%token EDIF_TOK_SECTION +%token EDIF_TOK_SHAPE +%token EDIF_TOK_SIMULATE +%token EDIF_TOK_SIMULATIONINFO +%token EDIF_TOK_SINGLEVALUESET +%token EDIF_TOK_SITE +%token EDIF_TOK_SOCKET +%token EDIF_TOK_SOCKETSET +%token EDIF_TOK_STATUS +%token EDIF_TOK_STEADY +%token EDIF_TOK_STRING +%token EDIF_TOK_STRINGDISPLAY +%token EDIF_TOK_STRONG +%token EDIF_TOK_SYMBOL +%token EDIF_TOK_SYMMETRY +%token EDIF_TOK_TABLE +%token EDIF_TOK_TABLEDEFAULT +%token EDIF_TOK_TECHNOLOGY +%token EDIF_TOK_TEXTHEIGHT +%token EDIF_TOK_TIMEINTERVAL +%token EDIF_TOK_TIMESTAMP +%token EDIF_TOK_TIMING +%token EDIF_TOK_TRANSFORM +%token EDIF_TOK_TRANSITION +%token EDIF_TOK_TRIGGER +%token EDIF_TOK_TRUE +%token EDIF_TOK_UNCONSTRAINED +%token EDIF_TOK_UNDEFINED +%token EDIF_TOK_UNION +%token EDIF_TOK_UNIT +%token EDIF_TOK_UNUSED +%token EDIF_TOK_USERDATA +%token EDIF_TOK_VERSION +%token EDIF_TOK_VIEW +%token EDIF_TOK_VIEWLIST +%token EDIF_TOK_VIEWMAP +%token EDIF_TOK_VIEWREF +%token EDIF_TOK_VIEWTYPE +%token EDIF_TOK_VISIBLE +%token EDIF_TOK_VOLTAGEMAP +%token EDIF_TOK_WAVEVALUE +%token EDIF_TOK_WEAK +%token EDIF_TOK_WEAKJOINED +%token EDIF_TOK_WHEN +%token EDIF_TOK_WRITTEN + +%start Edif + +%% + +PopC : ')' { PopC(); } + ; + +Edif : EDIF_TOK_EDIF EdifFileName EdifVersion EdifLevel KeywordMap _Edif PopC + ; + +_Edif : + | _Edif Status + | _Edif External + | _Edif Library + | _Edif Design + | _Edif Comment + | _Edif UserData + ; + +EdifFileName : NameDef { str_pair_free($1); } + ; + +EdifLevel : EDIF_TOK_EDIFLEVEL Int PopC { free($2); } + ; + +EdifVersion : EDIF_TOK_EDIFVERSION Int Int Int PopC +{ free($2); free($3); free($4); } + ; + +AcLoad : EDIF_TOK_ACLOAD _AcLoad PopC + ; + +_AcLoad : MiNoMaValue + | MiNoMaDisp + ; + +After : EDIF_TOK_AFTER _After PopC + ; + +_After : MiNoMaValue + | _After Follow + | _After Maintain + | _After LogicAssn + | _After Comment + | _After UserData + ; + +Annotate : EDIF_TOK_ANNOTATE _Annotate PopC + ; + +_Annotate : Str { free($1); } + | StrDisplay + ; + +Apply : EDIF_TOK_APPLY _Apply PopC + ; + +_Apply : Cycle + | _Apply LogicIn + | _Apply LogicOut + | _Apply Comment + | _Apply UserData + ; + +Arc : EDIF_TOK_ARC PointValue PointValue PointValue PopC + ; + +Array : EDIF_TOK_ARRAY NameDef Int _Array PopC { str_pair_free($2); free($3); } + ; + +_Array : + | Int { free($1); } + ; + +ArrayMacro : EDIF_TOK_ARRAYMACRO Plug PopC + ; + +ArrayRelInfo : EDIF_TOK_ARRAYRELATEDINFO _ArrayRelInfo PopC + ; + +_ArrayRelInfo : BaseArray + | ArraySite + | ArrayMacro + | _ArrayRelInfo Comment + | _ArrayRelInfo UserData + ; + +ArraySite : EDIF_TOK_ARRAYSITE Socket PopC + ; + +AtLeast : EDIF_TOK_ATLEAST ScaledInt PopC + ; + +AtMost : EDIF_TOK_ATMOST ScaledInt PopC + ; + +Author : EDIF_TOK_AUTHOR Str PopC { free($2); } + ; + +BaseArray : EDIF_TOK_BASEARRAY PopC + ; + +Becomes : EDIF_TOK_BECOMES _Becomes PopC + ; + +_Becomes : LogicNameRef + | LogicList + | LogicOneOf + ; + +Between : EDIF_TOK_BETWEEN __Between _Between PopC + ; + +__Between : AtLeast + | GreaterThan + ; + +_Between : AtMost + | LessThan + ; + +Boolean : EDIF_TOK_BOOLEAN _Boolean PopC + ; + +_Boolean : + | _Boolean BooleanValue + | _Boolean BooleanDisp + | _Boolean Boolean + ; + +BooleanDisp : EDIF_TOK_BOOLEANDISPLAY _BooleanDisp PopC + ; + +_BooleanDisp : BooleanValue + | _BooleanDisp Display + ; + +BooleanMap : EDIF_TOK_BOOLEANMAP BooleanValue PopC + ; + +BooleanValue : True + | False + ; + +BorderPat : EDIF_TOK_BORDERPATTERN Int Int Boolean PopC { free($2); free($3); } + ; + +BorderWidth : EDIF_TOK_BORDERWIDTH Int PopC { free($2); } + ; + +BoundBox : EDIF_TOK_BOUNDINGBOX Rectangle PopC + ; + +Cell : EDIF_TOK_CELL CellNameDef _Cell PopC + ; + +_Cell : CellType + | _Cell Status + | _Cell ViewMap + | _Cell View + | _Cell Comment + | _Cell UserData + | _Cell Property + ; + +CellNameDef : NameDef { str_pair_free($1); } + ; + +CellRef : EDIF_TOK_CELLREF CellNameRef _CellRef PopC + ; + +_CellRef : + | LibraryRef + ; + +CellNameRef : NameRef { free($1); } + ; + +CellType : EDIF_TOK_CELLTYPE _CellType PopC + ; + +_CellType : EDIF_TOK_TIE + | EDIF_TOK_RIPPER + | EDIF_TOK_GENERIC + ; + +Change : EDIF_TOK_CHANGE __Change _Change PopC + ; + +__Change : PortNameRef + | PortRef { str_pair_free($1); } + | PortList + ; + +_Change : + | Becomes + | Transition + ; + +Circle : EDIF_TOK_CIRCLE PointValue PointValue _Circle PopC + ; + +_Circle : + | _Circle Property + ; + +Color : EDIF_TOK_COLOR ScaledInt ScaledInt ScaledInt PopC + ; + +Comment : EDIF_TOK_COMMENT _Comment PopC + ; + +_Comment : + | _Comment Str { free($2); } + ; + +CommGraph : EDIF_TOK_COMMENTGRAPHICS _CommGraph PopC + ; + +_CommGraph : + | _CommGraph Annotate + | _CommGraph Figure + | _CommGraph Instance + | _CommGraph BoundBox + | _CommGraph Property + | _CommGraph Comment + | _CommGraph UserData + ; + +Compound : EDIF_TOK_COMPOUND LogicNameRef PopC + ; + +Contents : EDIF_TOK_CONTENTS _Contents PopC + ; + +_Contents : + | _Contents Instance + | _Contents OffPageConn + | _Contents Figure + | _Contents Section + | _Contents Net + | _Contents NetBundle + | _Contents Page + | _Contents CommGraph + | _Contents PortImpl + | _Contents Timing + | _Contents Simulate + | _Contents When + | _Contents Follow + | _Contents LogicPort + | _Contents BoundBox + | _Contents Comment + | _Contents UserData + ; + +ConnectLoc : EDIF_TOK_CONNECTLOCATION _ConnectLoc PopC + ; + +_ConnectLoc : + | Figure + ; + +CornerType : EDIF_TOK_CORNERTYPE _CornerType PopC + ; + +_CornerType : EDIF_TOK_EXTEND + | EDIF_TOK_ROUND + | EDIF_TOK_TRUNCATE + ; + +Criticality : EDIF_TOK_CRITICALITY _Criticality PopC + ; + +_Criticality : Int { free($1); } + | IntDisplay + ; + +CurrentMap : EDIF_TOK_CURRENTMAP MiNoMaValue PopC + ; + +Curve : EDIF_TOK_CURVE _Curve PopC + ; + +_Curve : + | _Curve Arc + | _Curve PointValue + ; + +Cycle : EDIF_TOK_CYCLE Int _Cycle PopC { free($2); } + ; + +_Cycle : + | Duration + ; + +DataOrigin : EDIF_TOK_DATAORIGIN Str _DataOrigin PopC { free($2); } + ; + +_DataOrigin : + | Version + ; + +DcFanInLoad : EDIF_TOK_DCFANINLOAD _DcFanInLoad PopC + ; + +_DcFanInLoad : ScaledInt + | NumbDisplay + ; + +DcFanOutLoad : EDIF_TOK_DCFANOUTLOAD _DcFanOutLoad PopC + ; + +_DcFanOutLoad : ScaledInt + | NumbDisplay + ; + +DcMaxFanIn : EDIF_TOK_DCMAXFANIN _DcMaxFanIn PopC + ; + +_DcMaxFanIn : ScaledInt + | NumbDisplay + ; + +DcMaxFanOut : EDIF_TOK_DCMAXFANOUT _DcMaxFanOut PopC + ; + +_DcMaxFanOut : ScaledInt + | NumbDisplay + ; + +Delay : EDIF_TOK_DELAY _Delay PopC + ; + +_Delay : MiNoMaValue + | MiNoMaDisp + ; + +Delta : EDIF_TOK_DELTA _Delta PopC + ; + +_Delta : + | _Delta PointValue + ; + +Derivation : EDIF_TOK_DERIVATION _Derivation PopC + ; + +_Derivation : EDIF_TOK_CALCULATED + | EDIF_TOK_MEASURED + | EDIF_TOK_REQUIRED + ; + +Design : EDIF_TOK_DESIGN DesignNameDef _Design PopC + ; + +_Design : CellRef + | _Design Status + | _Design Comment + | _Design Property + | _Design UserData + ; + +Designator : EDIF_TOK_DESIGNATOR _Designator PopC + ; + +_Designator : Str { free($1); } + | StrDisplay + ; + +DesignNameDef : NameDef { str_pair_free($1); } + ; + +DesignRule : EDIF_TOK_PHYSICALDESIGNRULE _DesignRule PopC + ; + +_DesignRule : + | _DesignRule FigureWidth + | _DesignRule FigureArea + | _DesignRule RectSize + | _DesignRule FigurePerim + | _DesignRule OverlapDist + | _DesignRule OverhngDist + | _DesignRule EncloseDist + | _DesignRule InterFigGrp + | _DesignRule IntraFigGrp + | _DesignRule NotchSpace + | _DesignRule NotAllowed + | _DesignRule FigGrp + | _DesignRule Comment + | _DesignRule UserData + ; + +Difference : EDIF_TOK_DIFFERENCE _Difference PopC + ; + +_Difference : FigGrpRef + | FigureOp + | _Difference FigGrpRef + | _Difference FigureOp + ; + +Direction : EDIF_TOK_DIRECTION _Direction PopC + ; + +_Direction : EDIF_TOK_INOUT + | EDIF_TOK_INPUT + | EDIF_TOK_OUTPUT + ; + +Display : EDIF_TOK_DISPLAY _Display _DisplayJust _DisplayOrien _DisplayOrg PopC + ; + +_Display : FigGrpNameRef + | FigGrpOver + ; + +_DisplayJust : + | Justify + ; + +_DisplayOrien : + | Orientation + ; + +_DisplayOrg : + | Origin + ; + +Dominates : EDIF_TOK_DOMINATES _Dominates PopC + ; + +_Dominates : + | _Dominates LogicNameRef + ; + +Dot : EDIF_TOK_DOT _Dot PopC + ; + +_Dot : PointValue + | _Dot Property + ; + +Duration : EDIF_TOK_DURATION ScaledInt PopC + ; + +EncloseDist : EDIF_TOK_ENCLOSUREDISTANCE RuleNameDef FigGrpObj FigGrpObj _EncloseDist + PopC + ; + +_EncloseDist : Range + | SingleValSet + | _EncloseDist Comment + | _EncloseDist UserData + ; + +EndType : EDIF_TOK_ENDTYPE _EndType PopC + ; + +_EndType : EDIF_TOK_EXTEND + | EDIF_TOK_ROUND + | EDIF_TOK_TRUNCATE + ; + +Entry : EDIF_TOK_ENTRY ___Entry __Entry _Entry + PopC + ; + +___Entry : Match + | Change + | Steady + ; + +__Entry : LogicRef + | PortRef { str_pair_free($1); } + | NoChange + | Table + ; + +_Entry : + | Delay + | LoadDelay + ; + +Event : EDIF_TOK_EVENT _Event PopC + ; + +_Event : PortRef { str_pair_free($1); } + | PortList + | PortGroup + | NetRef + | NetGroup + | _Event Transition + | _Event Becomes + ; + +Exactly : EDIF_TOK_EXACTLY ScaledInt PopC + ; + +External : EDIF_TOK_EXTERNAL LibNameDef EdifLevel _External PopC + ; + +_External : Technology + | _External Status + | _External Cell + | _External Comment + | _External UserData + ; + +Fabricate : EDIF_TOK_FABRICATE LayerNameDef FigGrpNameRef PopC + ; + +False : EDIF_TOK_FALSE PopC + ; + +FigGrp : EDIF_TOK_FIGUREGROUP _FigGrp PopC + ; + +_FigGrp : FigGrpNameDef + | _FigGrp CornerType + | _FigGrp EndType + | _FigGrp PathWidth + | _FigGrp BorderWidth + | _FigGrp Color + | _FigGrp FillPattern + | _FigGrp BorderPat + | _FigGrp TextHeight + | _FigGrp Visible + | _FigGrp Comment + | _FigGrp Property + | _FigGrp UserData + | _FigGrp IncFigGrp + ; + +FigGrpNameDef : NameDef { str_pair_free($1); } + ; + +FigGrpNameRef : NameRef { free($1); } + ; + +FigGrpObj : EDIF_TOK_FIGUREGROUPOBJECT _FigGrpObj PopC + ; + +_FigGrpObj : FigGrpNameRef + | FigGrpRef + | FigureOp + ; + +FigGrpOver : EDIF_TOK_FIGUREGROUPOVERRIDE _FigGrpOver PopC + ; + +_FigGrpOver : FigGrpNameRef + | _FigGrpOver CornerType + | _FigGrpOver EndType + | _FigGrpOver PathWidth + | _FigGrpOver BorderWidth + | _FigGrpOver Color + | _FigGrpOver FillPattern + | _FigGrpOver BorderPat + | _FigGrpOver TextHeight + | _FigGrpOver Visible + | _FigGrpOver Comment + | _FigGrpOver Property + | _FigGrpOver UserData + ; + +FigGrpRef : EDIF_TOK_FIGUREGROUPREF FigGrpNameRef _FigGrpRef PopC + ; + +_FigGrpRef : + | LibraryRef + ; + +Figure : EDIF_TOK_FIGURE _Figure PopC + ; + +_Figure : FigGrpNameDef + | FigGrpOver + | _Figure Circle + | _Figure Dot + | _Figure OpenShape + | _Figure Path + | _Figure Polygon + | _Figure Rectangle + | _Figure Shape + | _Figure Comment + | _Figure UserData + ; + +FigureArea : EDIF_TOK_FIGUREAREA RuleNameDef FigGrpObj _FigureArea PopC + ; + +_FigureArea : Range + | SingleValSet + | _FigureArea Comment + | _FigureArea UserData + ; + +FigureOp : Intersection + | Union + | Difference + | Inverse + | Oversize + ; + +FigurePerim : EDIF_TOK_FIGUREPERIMETER RuleNameDef FigGrpObj _FigurePerim PopC + ; + +_FigurePerim : Range + | SingleValSet + | _FigurePerim Comment + | _FigurePerim UserData + ; + +FigureWidth : EDIF_TOK_FIGUREWIDTH RuleNameDef FigGrpObj _FigureWidth PopC + ; + +_FigureWidth : Range + | SingleValSet + | _FigureWidth Comment + | _FigureWidth UserData + ; + +FillPattern : EDIF_TOK_FILLPATTERN Int Int Boolean PopC { free($2); free($3); } + ; + +Follow : EDIF_TOK_FOLLOW __Follow _Follow PopC + ; + +__Follow : PortNameRef + | PortRef { str_pair_free($1); } + ; + +_Follow : PortRef { str_pair_free($1); } + | Table + | _Follow Delay + | _Follow LoadDelay + ; + +Forbidden : EDIF_TOK_FORBIDDENEVENT _Forbidden PopC + ; + +_Forbidden : TimeIntval + | _Forbidden Event + ; + +Form : Keyword _Form ')' { free($1); } + ; + +_Form : + | _Form Int { free($2); } + | _Form Str { free($2); } + | _Form Ident { free($2); } + | _Form Form + ; + +GlobPortRef : EDIF_TOK_GLOBALPORTREF PortNameRef PopC + ; + +GreaterThan : EDIF_TOK_GREATERTHAN ScaledInt PopC + ; + +GridMap : EDIF_TOK_GRIDMAP ScaledInt ScaledInt PopC + ; + +Ignore : EDIF_TOK_IGNORE PopC + ; + +IncFigGrp : EDIF_TOK_INCLUDEFIGUREGROUP _IncFigGrp PopC + ; + +_IncFigGrp : FigGrpRef + | FigureOp + ; + +Initial : EDIF_TOK_INITIAL PopC + ; + +Instance : EDIF_TOK_INSTANCE InstNameDef _Instance PopC + ; + +_Instance : ViewRef + | ViewList + | _Instance Transform + | _Instance ParamAssign + | _Instance PortInst + | _Instance Timing + | _Instance Designator + | _Instance Property + | _Instance Comment + | _Instance UserData + ; + +InstanceRef : EDIF_TOK_INSTANCEREF InstNameRef _InstanceRef PopC { $$=$2; } + ; + +_InstanceRef : +| InstanceRef { free($1); } + | ViewRef + ; + +InstBackAn : EDIF_TOK_INSTANCEBACKANNOTATE _InstBackAn PopC + ; + +_InstBackAn : InstanceRef { free($1); } + | _InstBackAn Designator + | _InstBackAn Timing + | _InstBackAn Property + | _InstBackAn Comment + ; + +InstGroup : EDIF_TOK_INSTANCEGROUP _InstGroup PopC + ; + +_InstGroup : + | _InstGroup InstanceRef { free($2); } + ; + +InstMap : EDIF_TOK_INSTANCEMAP _InstMap PopC + ; + +_InstMap : + | _InstMap InstanceRef { free($2); } + | _InstMap InstGroup + | _InstMap Comment + | _InstMap UserData + ; + +InstNameDef : NameDef { str_pair_free($1); } + | Array + ; + +InstNameRef : NameRef { $$=$1; } + | Member + ; + +IntDisplay : EDIF_TOK_INTEGERDISPLAY _IntDisplay PopC + ; + +_IntDisplay : Int { free($1); } + | _IntDisplay Display + ; + +Integer : EDIF_TOK_INTEGER _Integer PopC + ; + +_Integer : + | _Integer Int { free($2); } + | _Integer IntDisplay + | _Integer Integer + ; + +Interface : EDIF_TOK_INTERFACE _Interface PopC + ; + +_Interface : + | _Interface Port + | _Interface PortBundle + | _Interface Symbol + | _Interface ProtectFrame + | _Interface ArrayRelInfo + | _Interface Parameter + | _Interface Joined { pair_list_free($2); } + | _Interface MustJoin + | _Interface WeakJoined + | _Interface Permutable + | _Interface Timing + | _Interface Simulate + | _Interface Designator + | _Interface Property + | _Interface Comment + | _Interface UserData + ; + +InterFigGrp : EDIF_TOK_INTERFIGUREGROUPSPACING RuleNameDef FigGrpObj FigGrpObj + _InterFigGrp PopC + ; + +_InterFigGrp : Range + | SingleValSet + | _InterFigGrp Comment + | _InterFigGrp UserData + ; + +Intersection : EDIF_TOK_INTERSECTION _Intersection PopC + ; + +_Intersection : FigGrpRef + | FigureOp + | _Intersection FigGrpRef + | _Intersection FigureOp + ; + +IntraFigGrp : EDIF_TOK_INTRAFIGUREGROUPSPACING RuleNameDef FigGrpObj _IntraFigGrp PopC + ; + +_IntraFigGrp : Range + | SingleValSet + | _IntraFigGrp Comment + | _IntraFigGrp UserData + ; + +Inverse : EDIF_TOK_INVERSE _Inverse PopC + ; + +_Inverse : FigGrpRef + | FigureOp + ; + +Isolated : EDIF_TOK_ISOLATED PopC + ; + +Joined : EDIF_TOK_JOINED _Joined PopC { $$ = new_pair_list($2); } + ; + +_Joined : { $$=NULL; } +| _Joined PortRef { $2->next = $1; $$ = $2; } + | _Joined PortList + | _Joined GlobPortRef + ; + +Justify : EDIF_TOK_JUSTIFY _Justify PopC + ; + +_Justify : EDIF_TOK_CENTERCENTER + | EDIF_TOK_CENTERLEFT + | EDIF_TOK_CENTERRIGHT + | EDIF_TOK_LOWERCENTER + | EDIF_TOK_LOWERLEFT + | EDIF_TOK_LOWERRIGHT + | EDIF_TOK_UPPERCENTER + | EDIF_TOK_UPPERLEFT + | EDIF_TOK_UPPERRIGHT + ; + +KeywordDisp : EDIF_TOK_KEYWORDDISPLAY _KeywordDisp PopC + ; + +_KeywordDisp : KeywordName + | _KeywordDisp Display + ; + +KeywordLevel : EDIF_TOK_KEYWORDLEVEL Int PopC { free($2); } + ; + +KeywordMap : EDIF_TOK_KEYWORDMAP _KeywordMap PopC + ; + +_KeywordMap : KeywordLevel + | _KeywordMap Comment + ; + +KeywordName : Ident { free($1); } + ; + +LayerNameDef : NameDef { str_pair_free($1); } + ; + +LessThan : EDIF_TOK_LESSTHAN ScaledInt PopC + ; + +LibNameDef : NameDef { str_pair_free($1); } + ; + +LibNameRef : NameRef { free($1); } + ; + +Library : EDIF_TOK_LIBRARY LibNameDef EdifLevel _Library PopC + ; + +_Library : Technology + | _Library Status + | _Library Cell + | _Library Comment + | _Library UserData + ; + +LibraryRef : EDIF_TOK_LIBRARYREF LibNameRef PopC + ; + +ListOfNets : EDIF_TOK_LISTOFNETS _ListOfNets PopC + ; + +_ListOfNets : + | _ListOfNets Net + ; + +ListOfPorts : EDIF_TOK_LISTOFPORTS _ListOfPorts PopC + ; + +_ListOfPorts : + | _ListOfPorts Port + | _ListOfPorts PortBundle + ; + +LoadDelay : EDIF_TOK_LOADDELAY _LoadDelay _LoadDelay PopC + ; + +_LoadDelay : MiNoMaValue + | MiNoMaDisp + ; + +LogicAssn : EDIF_TOK_LOGICASSIGN ___LogicAssn __LogicAssn _LogicAssn PopC + ; + +___LogicAssn : PortNameRef + | PortRef { str_pair_free($1); } + ; + +__LogicAssn : PortRef { str_pair_free($1); } + | LogicRef + | Table + ; + +_LogicAssn : + | Delay + | LoadDelay + ; + +LogicIn : EDIF_TOK_LOGICINPUT _LogicIn PopC + ; + +_LogicIn : PortList + | PortRef { str_pair_free($1); } + | PortNameRef + | _LogicIn LogicWave + ; + +LogicList : EDIF_TOK_LOGICLIST _LogicList PopC + ; + +_LogicList : + | _LogicList LogicNameRef + | _LogicList LogicOneOf + | _LogicList Ignore + ; + +LogicMapIn : EDIF_TOK_LOGICMAPINPUT _LogicMapIn PopC + ; + +_LogicMapIn : + | _LogicMapIn LogicNameRef + ; + +LogicMapOut : EDIF_TOK_LOGICMAPOUTPUT _LogicMapOut PopC + ; + +_LogicMapOut : + | _LogicMapOut LogicNameRef + ; + +LogicNameDef : NameDef { str_pair_free($1); } + ; + +LogicNameRef : NameRef { free($1); } + ; + +LogicOneOf : EDIF_TOK_LOGICONEOF _LogicOneOf PopC + ; + +_LogicOneOf : + | _LogicOneOf LogicNameRef + | _LogicOneOf LogicList + ; + +LogicOut : EDIF_TOK_LOGICOUTPUT _LogicOut PopC + ; + +_LogicOut : PortList + | PortRef { str_pair_free($1); } + | PortNameRef + | _LogicOut LogicWave + ; + +LogicPort : EDIF_TOK_LOGICPORT _LogicPort PopC + ; + +_LogicPort : PortNameDef + | _LogicPort Property + | _LogicPort Comment + | _LogicPort UserData + ; + +LogicRef : EDIF_TOK_LOGICREF LogicNameRef _LogicRef PopC + ; + +_LogicRef : + | LibraryRef + ; + +LogicValue : EDIF_TOK_LOGICVALUE _LogicValue PopC + ; + +_LogicValue : LogicNameDef + | _LogicValue VoltageMap + | _LogicValue CurrentMap + | _LogicValue BooleanMap + | _LogicValue Compound + | _LogicValue Weak + | _LogicValue Strong + | _LogicValue Dominates + | _LogicValue LogicMapOut + | _LogicValue LogicMapIn + | _LogicValue Isolated + | _LogicValue Resolves + | _LogicValue Property + | _LogicValue Comment + | _LogicValue UserData + ; + +LogicWave : EDIF_TOK_LOGICWAVEFORM _LogicWave PopC + ; + +_LogicWave : + | _LogicWave LogicNameRef + | _LogicWave LogicList + | _LogicWave LogicOneOf + | _LogicWave Ignore + ; + +Maintain : EDIF_TOK_MAINTAIN __Maintain _Maintain PopC + ; + +__Maintain : PortNameRef + | PortRef { str_pair_free($1); } + ; + +_Maintain : + | Delay + | LoadDelay + ; + +Match : EDIF_TOK_MATCH __Match _Match PopC + ; + +__Match : PortNameRef + | PortRef { str_pair_free($1); } + | PortList + ; + +_Match : LogicNameRef + | LogicList + | LogicOneOf + ; + +Member : EDIF_TOK_MEMBER NameRef _Member PopC { free($2); } + ; + +_Member : Int { free($1); } + | _Member Int { free($2); } + ; + +MiNoMa : EDIF_TOK_MINOMAX _MiNoMa PopC + ; + +_MiNoMa : + | _MiNoMa MiNoMaValue + | _MiNoMa MiNoMaDisp + | _MiNoMa MiNoMa + ; + +MiNoMaDisp : EDIF_TOK_MINOMAXDISPLAY _MiNoMaDisp PopC + ; + +_MiNoMaDisp : MiNoMaValue + | _MiNoMaDisp Display + ; + +MiNoMaValue : Mnm + | ScaledInt + ; + +Mnm : EDIF_TOK_MNM _Mnm _Mnm _Mnm PopC + ; + +_Mnm : ScaledInt + | Undefined + | Unconstrained + ; + +MultValSet : EDIF_TOK_MULTIPLEVALUESET _MultValSet PopC + ; + +_MultValSet : + | _MultValSet RangeVector + ; + +MustJoin : EDIF_TOK_MUSTJOIN _MustJoin PopC + ; + +_MustJoin : + | _MustJoin PortRef { str_pair_free($2); } + | _MustJoin PortList + | _MustJoin WeakJoined + | _MustJoin Joined { pair_list_free($2); } + ; + +Name : EDIF_TOK_NAME _Name PopC { $$=$2; } + ; + +_Name : Ident { $$=$1; } + | _Name Display + ; + +NameDef : Ident { $$ = new_str_pair($1,NULL); } + | Name { $$ = new_str_pair($1,NULL); } +| Rename { $$=$1; } + ; + +NameRef : Ident { $$=$1; } + | Name { $$=$1; } + ; + +Net : EDIF_TOK_NET NetNameDef _Net PopC { define_pcb_net($2, $3); } + ; + +_Net : Joined { $$=$1; } + | _Net Criticality + | _Net NetDelay + | _Net Figure + | _Net Net + | _Net Instance + | _Net CommGraph + | _Net Property + | _Net Comment + | _Net UserData + ; + +NetBackAn : EDIF_TOK_NETBACKANNOTATE _NetBackAn PopC + ; + +_NetBackAn : NetRef + | _NetBackAn NetDelay + | _NetBackAn Criticality + | _NetBackAn Property + | _NetBackAn Comment + ; + +NetBundle : EDIF_TOK_NETBUNDLE NetNameDef _NetBundle PopC { str_pair_free($2); } + ; + +_NetBundle : ListOfNets + | _NetBundle Figure + | _NetBundle CommGraph + | _NetBundle Property + | _NetBundle Comment + | _NetBundle UserData + ; + +NetDelay : EDIF_TOK_NETDELAY Derivation _NetDelay PopC + ; + +_NetDelay : Delay + | _NetDelay Transition + | _NetDelay Becomes + ; + +NetGroup : EDIF_TOK_NETGROUP _NetGroup PopC + ; + +_NetGroup : + | _NetGroup NetNameRef + | _NetGroup NetRef + ; + +NetMap : EDIF_TOK_NETMAP _NetMap PopC + ; + +_NetMap : + | _NetMap NetRef + | _NetMap NetGroup + | _NetMap Comment + | _NetMap UserData + ; + +NetNameDef : NameDef { $$=$1; } +| Array { $$=NULL; } + + ; + +NetNameRef : NameRef { free($1); } + | Member + ; + +NetRef : EDIF_TOK_NETREF NetNameRef _NetRef PopC + ; + +_NetRef : + | NetRef + | InstanceRef { free($1); } + | ViewRef + ; + +NoChange : EDIF_TOK_NOCHANGE PopC + ; + +NonPermut : EDIF_TOK_NONPERMUTABLE _NonPermut PopC + ; + +_NonPermut : + | _NonPermut PortRef { str_pair_free($2); } + | _NonPermut Permutable + ; + +NotAllowed : EDIF_TOK_NOTALLOWED RuleNameDef _NotAllowed PopC + ; + +_NotAllowed : FigGrpObj + | _NotAllowed Comment + | _NotAllowed UserData + ; + +NotchSpace : EDIF_TOK_NOTCHSPACING RuleNameDef FigGrpObj _NotchSpace PopC + ; + +_NotchSpace : Range + | SingleValSet + | _NotchSpace Comment + | _NotchSpace UserData + ; + +Number : EDIF_TOK_NUMBER _Number PopC + ; + +_Number : + | _Number ScaledInt + | _Number NumbDisplay + | _Number Number + ; + +NumbDisplay : EDIF_TOK_NUMBERDISPLAY _NumbDisplay PopC + ; + +_NumbDisplay : ScaledInt + | _NumbDisplay Display + ; + +NumberDefn : EDIF_TOK_NUMBERDEFINITION _NumberDefn PopC + ; + +_NumberDefn : + | _NumberDefn Scale + | _NumberDefn GridMap + | _NumberDefn Comment + ; + +OffPageConn : EDIF_TOK_OFFPAGECONNECTOR _OffPageConn PopC + ; + +_OffPageConn : PortNameDef + | _OffPageConn Unused + | _OffPageConn Property + | _OffPageConn Comment + | _OffPageConn UserData + ; + +OffsetEvent : EDIF_TOK_OFFSETEVENT Event ScaledInt PopC + ; + +OpenShape : EDIF_TOK_OPENSHAPE _OpenShape PopC + ; + +_OpenShape : Curve + | _OpenShape Property + ; + +Orientation : EDIF_TOK_ORIENTATION _Orientation PopC + ; + +_Orientation : EDIF_TOK_R0 + | EDIF_TOK_R90 + | EDIF_TOK_R180 + | EDIF_TOK_R270 + | EDIF_TOK_MX + | EDIF_TOK_MY + | EDIF_TOK_MYR90 + | EDIF_TOK_MXR90 + ; + +Origin : EDIF_TOK_ORIGIN PointValue PopC + ; + +OverhngDist : EDIF_TOK_OVERHANGDISTANCE RuleNameDef FigGrpObj FigGrpObj _OverhngDist + PopC + ; + +_OverhngDist : Range + | SingleValSet + | _OverhngDist Comment + | _OverhngDist UserData + ; + +OverlapDist : EDIF_TOK_OVERLAPDISTANCE RuleNameDef FigGrpObj FigGrpObj _OverlapDist + PopC + ; + +_OverlapDist : Range + | SingleValSet + | _OverlapDist Comment + | _OverlapDist UserData + ; + +Oversize : EDIF_TOK_OVERSIZE Int _Oversize CornerType PopC { free($2); } + ; + +_Oversize : FigGrpRef + | FigureOp + ; + +Owner : EDIF_TOK_OWNER Str PopC { free($2); } + ; + +Page : EDIF_TOK_PAGE _Page PopC + ; + +_Page : InstNameDef + | _Page Instance + | _Page Net + | _Page NetBundle + | _Page CommGraph + | _Page PortImpl + | _Page PageSize + | _Page BoundBox + | _Page Comment + | _Page UserData + ; + +PageSize : EDIF_TOK_PAGESIZE Rectangle PopC + ; + +ParamDisp : EDIF_TOK_PARAMETERDISPLAY _ParamDisp PopC + ; + +_ParamDisp : ValueNameRef + | _ParamDisp Display + ; + +Parameter : EDIF_TOK_PARAMETER ValueNameDef TypedValue _Parameter PopC + ; + +_Parameter : + | Unit + ; + +ParamAssign : EDIF_TOK_PARAMETERASSIGN ValueNameRef TypedValue PopC + ; + +Path : EDIF_TOK_PATH _Path PopC + ; + +_Path : PointList + | _Path Property + ; + +PathDelay : EDIF_TOK_PATHDELAY _PathDelay PopC + ; + +_PathDelay : Delay + | _PathDelay Event + ; + +PathWidth : EDIF_TOK_PATHWIDTH Int PopC { free($2); } + ; + +Permutable : EDIF_TOK_PERMUTABLE _Permutable PopC + ; + +_Permutable : + | _Permutable PortRef { str_pair_free($2); } + | _Permutable Permutable + | _Permutable NonPermut + ; + +Plug : EDIF_TOK_PLUG _Plug PopC + ; + +_Plug : + | _Plug SocketSet + ; + +Point : EDIF_TOK_POINT _Point PopC + ; + +_Point : + | _Point PointValue + | _Point PointDisp + | _Point Point + ; + +PointDisp : EDIF_TOK_POINTDISPLAY _PointDisp PopC + ; + +_PointDisp : PointValue + | _PointDisp Display + ; + +PointList : EDIF_TOK_POINTLIST _PointList PopC + ; + +_PointList : + | _PointList PointValue + ; + +PointValue : EDIF_TOK_PT Int Int PopC { free($2); free($3); } + ; + +Polygon : EDIF_TOK_POLYGON _Polygon PopC + ; + +_Polygon : PointList + | _Polygon Property + ; + +Port : EDIF_TOK_PORT _Port PopC + ; + +_Port : PortNameDef + | _Port Direction + | _Port Unused + | _Port PortDelay + | _Port Designator + | _Port DcFanInLoad + | _Port DcFanOutLoad + | _Port DcMaxFanIn + | _Port DcMaxFanOut + | _Port AcLoad + | _Port Property + | _Port Comment + | _Port UserData + ; + +PortBackAn : EDIF_TOK_PORTBACKANNOTATE _PortBackAn PopC + ; + +_PortBackAn : PortRef { str_pair_free($1); } + | _PortBackAn Designator + | _PortBackAn PortDelay + | _PortBackAn DcFanInLoad + | _PortBackAn DcFanOutLoad + | _PortBackAn DcMaxFanIn + | _PortBackAn DcMaxFanOut + | _PortBackAn AcLoad + | _PortBackAn Property + | _PortBackAn Comment + ; + +PortBundle : EDIF_TOK_PORTBUNDLE PortNameDef _PortBundle PopC + ; + +_PortBundle : ListOfPorts + | _PortBundle Property + | _PortBundle Comment + | _PortBundle UserData + ; + +PortDelay : EDIF_TOK_PORTDELAY Derivation _PortDelay PopC + ; + +_PortDelay : Delay + | LoadDelay + | _PortDelay Transition + | _PortDelay Becomes + ; + +PortGroup : EDIF_TOK_PORTGROUP _PortGroup PopC + ; + +_PortGroup : + | _PortGroup PortNameRef + | _PortGroup PortRef { str_pair_free($2); } + ; + +PortImpl : EDIF_TOK_PORTIMPLEMENTATION _PortImpl PopC + ; + +_PortImpl : PortRef { str_pair_free($1); } + | PortNameRef + | _PortImpl ConnectLoc + | _PortImpl Figure + | _PortImpl Instance + | _PortImpl CommGraph + | _PortImpl PropDisplay + | _PortImpl KeywordDisp + | _PortImpl Property + | _PortImpl UserData + | _PortImpl Comment + ; + +PortInst : EDIF_TOK_PORTINSTANCE _PortInst PopC + ; + +_PortInst : PortRef { str_pair_free($1); } + | PortNameRef + | _PortInst Unused + | _PortInst PortDelay + | _PortInst Designator + | _PortInst DcFanInLoad + | _PortInst DcFanOutLoad + | _PortInst DcMaxFanIn + | _PortInst DcMaxFanOut + | _PortInst AcLoad + | _PortInst Property + | _PortInst Comment + | _PortInst UserData + ; + +PortList : EDIF_TOK_PORTLIST _PortList PopC + ; + +_PortList : + | _PortList PortRef { str_pair_free($2); } + | _PortList PortNameRef + ; + +PortListAls : EDIF_TOK_PORTLISTALIAS PortNameDef PortList PopC + ; + +PortMap : EDIF_TOK_PORTMAP _PortMap PopC + ; + +_PortMap : + | _PortMap PortRef { str_pair_free($2); } + | _PortMap PortGroup + | _PortMap Comment + | _PortMap UserData + ; + +PortNameDef : NameDef { str_pair_free($1); } + | Array + ; + +PortNameRef : NameRef { $$=$1; } + | Member + ; + +PortRef : EDIF_TOK_PORTREF PortNameRef _PortRef PopC +{ + if ($3) + { + $$ = new_str_pair($3->str1,$2); + free($3); + } + else + { + /* handle port with no instance by passing up the chain */ + $$ = new_str_pair(NULL,$2); + } +} + ; + +_PortRef : { $$=NULL; } + | PortRef { $$=$1; } + | InstanceRef { $$ = new_str_pair($1,NULL); } + | ViewRef { $$=NULL; } + ; + +Program : EDIF_TOK_PROGRAM Str _Program PopC + ; + +_Program : + | Version + ; + +PropDisplay : EDIF_TOK_PROPERTYDISPLAY _PropDisplay PopC + ; + +_PropDisplay : PropNameRef + | _PropDisplay Display + ; + +Property : EDIF_TOK_PROPERTY PropNameDef _Property PopC + ; + +_Property : TypedValue + | _Property Owner + | _Property Unit + | _Property Property + | _Property Comment + ; + +PropNameDef : NameDef { str_pair_free($1); } + ; + +PropNameRef : NameRef { free($1); } + ; + +ProtectFrame : EDIF_TOK_PROTECTIONFRAME _ProtectFrame PopC + ; + +_ProtectFrame : + | _ProtectFrame PortImpl + | _ProtectFrame Figure + | _ProtectFrame Instance + | _ProtectFrame CommGraph + | _ProtectFrame BoundBox + | _ProtectFrame PropDisplay + | _ProtectFrame KeywordDisp + | _ProtectFrame ParamDisp + | _ProtectFrame Property + | _ProtectFrame Comment + | _ProtectFrame UserData + ; + +Range : LessThan + | GreaterThan + | AtMost + | AtLeast + | Exactly + | Between + ; + +RangeVector : EDIF_TOK_RANGEVECTOR _RangeVector PopC + ; + +_RangeVector : + | _RangeVector Range + | _RangeVector SingleValSet + ; + +Rectangle : EDIF_TOK_RECTANGLE PointValue _Rectangle PopC + ; + +_Rectangle : PointValue + | _Rectangle Property + ; + +RectSize : EDIF_TOK_RECTANGLESIZE RuleNameDef FigGrpObj _RectSize PopC + ; + +_RectSize : RangeVector + | MultValSet + | _RectSize Comment + | _RectSize UserData + ; + +Rename : EDIF_TOK_RENAME __Rename _Rename PopC +{ $$ = new_str_pair($2,$3); } + ; + +__Rename : Ident { $$=$1; } + | Name { $$=$1; } + ; + +_Rename : Str { $$=$1; } + | StrDisplay { $$=NULL; } + ; + +Resolves : EDIF_TOK_RESOLVES _Resolves PopC + ; + +_Resolves : + | _Resolves LogicNameRef + ; + +RuleNameDef : NameDef { str_pair_free($1); } + ; + +Scale : EDIF_TOK_SCALE ScaledInt ScaledInt Unit PopC + ; + +ScaledInt : Int { free($1); } + | EDIF_TOK_E Int Int PopC { free($2); free($3); } + ; + +ScaleX : EDIF_TOK_SCALEX Int Int PopC { free($2); free($3); } + ; + +ScaleY : EDIF_TOK_SCALEY Int Int PopC { free($2); free($3); } + ; + +Section : EDIF_TOK_SECTION _Section PopC + ; + +_Section : Str { free($1); } + | _Section Section + | _Section Str { free($2); } + | _Section Instance + ; + +Shape : EDIF_TOK_SHAPE _Shape PopC + ; + +_Shape : Curve + | _Shape Property + ; + +SimNameDef : NameDef { str_pair_free($1); } + ; + +Simulate : EDIF_TOK_SIMULATE _Simulate PopC + ; + +_Simulate : SimNameDef + | _Simulate PortListAls + | _Simulate WaveValue + | _Simulate Apply + | _Simulate Comment + | _Simulate UserData + ; + +SimulInfo : EDIF_TOK_SIMULATIONINFO _SimulInfo PopC + ; + +_SimulInfo : + | _SimulInfo LogicValue + | _SimulInfo Comment + | _SimulInfo UserData + ; + +SingleValSet : EDIF_TOK_SINGLEVALUESET _SingleValSet PopC + ; + +_SingleValSet : + | Range + ; + +Site : EDIF_TOK_SITE ViewRef _Site PopC + ; + +_Site : + | Transform + ; + +Socket : EDIF_TOK_SOCKET _Socket PopC + ; + +_Socket : + | Symmetry + ; + +SocketSet : EDIF_TOK_SOCKETSET _SocketSet PopC + ; + +_SocketSet : Symmetry + | _SocketSet Site + ; + +Status : EDIF_TOK_STATUS _Status PopC + ; + +_Status : + | _Status Written + | _Status Comment + | _Status UserData + ; + +Steady : EDIF_TOK_STEADY __Steady _Steady PopC + ; + +__Steady : PortNameRef + | PortRef { str_pair_free($1); } + | PortList + ; + +_Steady : Duration + | _Steady Transition + | _Steady Becomes + ; + +StrDisplay : EDIF_TOK_STRINGDISPLAY _StrDisplay PopC + ; + +String : EDIF_TOK_STRING _String PopC + ; + +_String : + | _String Str { free($2); } + | _String StrDisplay + | _String String + ; + +_StrDisplay : Str { free($1); } + | _StrDisplay Display + ; + +Strong : EDIF_TOK_STRONG LogicNameRef PopC + ; + +Symbol : EDIF_TOK_SYMBOL _Symbol PopC + ; + +_Symbol : + | _Symbol PortImpl + | _Symbol Figure + | _Symbol Instance + | _Symbol CommGraph + | _Symbol Annotate + | _Symbol PageSize + | _Symbol BoundBox + | _Symbol PropDisplay + | _Symbol KeywordDisp + | _Symbol ParamDisp + | _Symbol Property + | _Symbol Comment + | _Symbol UserData + ; + +Symmetry : EDIF_TOK_SYMMETRY _Symmetry PopC + ; + +_Symmetry : + | _Symmetry Transform + ; + +Table : EDIF_TOK_TABLE _Table PopC + ; + +_Table : + | _Table Entry + | _Table TableDeflt + ; + +TableDeflt : EDIF_TOK_TABLEDEFAULT __TableDeflt _TableDeflt PopC + ; + +__TableDeflt : LogicRef + | PortRef { str_pair_free($1); } + | NoChange + | Table + ; + +_TableDeflt : + | Delay + | LoadDelay + ; + +Technology : EDIF_TOK_TECHNOLOGY _Technology PopC + ; + +_Technology : NumberDefn + | _Technology FigGrp + | _Technology Fabricate + | _Technology SimulInfo + | _Technology DesignRule + | _Technology Comment + | _Technology UserData + ; + +TextHeight : EDIF_TOK_TEXTHEIGHT Int PopC { free($2); } + ; + +TimeIntval : EDIF_TOK_TIMEINTERVAL __TimeIntval _TimeIntval PopC + ; + +__TimeIntval : Event + | OffsetEvent + ; + +_TimeIntval : Event + | OffsetEvent + | Duration + ; + +TimeStamp : EDIF_TOK_TIMESTAMP Int Int Int Int Int Int PopC +{ free($2); free($3); free($4); free($5); free($6); free($7); } + ; + +Timing : EDIF_TOK_TIMING _Timing PopC + ; + +_Timing : Derivation + | _Timing PathDelay + | _Timing Forbidden + | _Timing Comment + | _Timing UserData + ; + +Transform : EDIF_TOK_TRANSFORM _TransX _TransY _TransDelta _TransOrien _TransOrg + PopC + ; + +_TransX : + | ScaleX + ; + +_TransY : + | ScaleY + ; + +_TransDelta : + | Delta + ; + +_TransOrien : + | Orientation + ; + +_TransOrg : + | Origin + ; + +Transition : EDIF_TOK_TRANSITION _Transition _Transition PopC + ; + +_Transition : LogicNameRef + | LogicList + | LogicOneOf + ; + +Trigger : EDIF_TOK_TRIGGER _Trigger PopC + ; + +_Trigger : + | _Trigger Change + | _Trigger Steady + | _Trigger Initial + ; + +True : EDIF_TOK_TRUE PopC + ; + +TypedValue : Boolean + | Integer + | MiNoMa + | Number + | Point + | String + ; + +Unconstrained : EDIF_TOK_UNCONSTRAINED PopC + ; + +Undefined : EDIF_TOK_UNDEFINED PopC + ; + +Union : EDIF_TOK_UNION _Union PopC + ; + +_Union : FigGrpRef + | FigureOp + | _Union FigGrpRef + | _Union FigureOp + ; + +Unit : EDIF_TOK_UNIT _Unit PopC + ; + +_Unit : EDIF_TOK_DISTANCE + | EDIF_TOK_CAPACITANCE + | EDIF_TOK_CURRENT + | EDIF_TOK_RESISTANCE + | EDIF_TOK_TEMPERATURE + | EDIF_TOK_TIME + | EDIF_TOK_VOLTAGE + | EDIF_TOK_MASS + | EDIF_TOK_FREQUENCY + | EDIF_TOK_INDUCTANCE + | EDIF_TOK_ENERGY + | EDIF_TOK_POWER + | EDIF_TOK_CHARGE + | EDIF_TOK_CONDUCTANCE + | EDIF_TOK_FLUX + | EDIF_TOK_ANGLE + ; + +Unused : EDIF_TOK_UNUSED PopC + ; + +UserData : EDIF_TOK_USERDATA _UserData PopC + ; + +_UserData : Ident { free($1); } + | _UserData Int { free($2); } + | _UserData Str { free($2); } + | _UserData Ident { free($2); } + | _UserData Form + ; + +ValueNameDef : NameDef { str_pair_free($1); } + | Array + ; + +ValueNameRef : NameRef { free($1); } + | Member + ; + +Version : EDIF_TOK_VERSION Str PopC { free($2); } + ; + +View : EDIF_TOK_VIEW ViewNameDef ViewType _View PopC + ; + +_View : Interface + | _View Status + | _View Contents + | _View Comment + | _View Property + | _View UserData + ; + +ViewList : EDIF_TOK_VIEWLIST _ViewList PopC + ; + +_ViewList : + | _ViewList ViewRef + | _ViewList ViewList + ; + +ViewMap : EDIF_TOK_VIEWMAP _ViewMap PopC + ; + +_ViewMap : + | _ViewMap PortMap + | _ViewMap PortBackAn + | _ViewMap InstMap + | _ViewMap InstBackAn + | _ViewMap NetMap + | _ViewMap NetBackAn + | _ViewMap Comment + | _ViewMap UserData + ; + +ViewNameDef : NameDef { str_pair_free($1); } + ; + +ViewNameRef : NameRef { free($1); } + ; + +ViewRef : EDIF_TOK_VIEWREF ViewNameRef _ViewRef PopC + ; + +_ViewRef : + | CellRef + ; + +ViewType : EDIF_TOK_VIEWTYPE _ViewType PopC + ; + +_ViewType : EDIF_TOK_MASKLAYOUT + | EDIF_TOK_PCBLAYOUT + | EDIF_TOK_NETLIST + | EDIF_TOK_SCHEMATIC + | EDIF_TOK_SYMBOLIC + | EDIF_TOK_BEHAVIOR + | EDIF_TOK_LOGICMODEL + | EDIF_TOK_DOCUMENT + | EDIF_TOK_GRAPHIC + | EDIF_TOK_STRANGER + ; + +Visible : EDIF_TOK_VISIBLE BooleanValue PopC + ; + +VoltageMap : EDIF_TOK_VOLTAGEMAP MiNoMaValue PopC + ; + +WaveValue : EDIF_TOK_WAVEVALUE LogicNameDef ScaledInt LogicWave PopC + ; + +Weak : EDIF_TOK_WEAK LogicNameRef PopC + ; + +WeakJoined : EDIF_TOK_WEAKJOINED _WeakJoined PopC + ; + +_WeakJoined : + | _WeakJoined PortRef { str_pair_free($2); } + | _WeakJoined PortList + | _WeakJoined Joined { pair_list_free($2); } + ; + +When : EDIF_TOK_WHEN _When PopC + ; + +_When : Trigger + | _When After + | _When Follow + | _When Maintain + | _When LogicAssn + | _When Comment + | _When UserData + ; + +Written : EDIF_TOK_WRITTEN _Written PopC + ; + +_Written : TimeStamp + | _Written Author + | _Written Program + | _Written DataOrigin + | _Written Property + | _Written Comment + | _Written UserData + ; + +Ident : EDIF_TOK_IDENT { $$=$1; } + ; + +Str : EDIF_TOK_STR { $$=$1; } + ; + +Int : EDIF_TOK_INT { $$=$1; } + ; + +Keyword : EDIF_TOK_KEYWORD { $$=$1; } + ; + +%% +/* + * xmalloc: + * + * Garbage function for 'alloca()'. + */ +char *xmalloc(int siz) +{ + return ((char *)Malloc(siz)); +} +/* + * Token & context carriers: + * + * These are the linkage pointers for threading this context garbage + * for converting identifiers into parser tokens. + */ +typedef struct TokenCar { + struct TokenCar *Next; /* pointer to next carrier */ + struct Token *Token; /* associated token */ +} TokenCar; +typedef struct UsedCar { + struct UsedCar *Next; /* pointer to next carrier */ + short Code; /* used '%token' value */ +} UsedCar; +typedef struct ContextCar { + struct ContextCar *Next; /* pointer to next carrier */ + struct Context *Context; /* associated context */ + union { + int Single; /* single usage flag (context tree) */ + struct UsedCar *Used; /* single used list (context stack) */ + } u; +} ContextCar; +/* + * Token definitions: + * + * This associates the '%token' codings with strings which are to + * be free standing tokens. Doesn't have to be in sorted order but the + * strings must be in lower case. + */ +typedef struct Token { + const char *Name; /* token name */ + int Code; /* '%token' value */ + struct Token *Next; /* hash table linkage */ +} Token; +static Token TokenDef[] = { + {"angle", EDIF_TOK_ANGLE}, + {"behavior", EDIF_TOK_BEHAVIOR}, + {"calculated", EDIF_TOK_CALCULATED}, + {"capacitance", EDIF_TOK_CAPACITANCE}, + {"centercenter", EDIF_TOK_CENTERCENTER}, + {"centerleft", EDIF_TOK_CENTERLEFT}, + {"centerright", EDIF_TOK_CENTERRIGHT}, + {"charge", EDIF_TOK_CHARGE}, + {"conductance", EDIF_TOK_CONDUCTANCE}, + {"current", EDIF_TOK_CURRENT}, + {"distance", EDIF_TOK_DISTANCE}, + {"document", EDIF_TOK_DOCUMENT}, + {"energy", EDIF_TOK_ENERGY}, + {"extend", EDIF_TOK_EXTEND}, + {"flux", EDIF_TOK_FLUX}, + {"frequency", EDIF_TOK_FREQUENCY}, + {"generic", EDIF_TOK_GENERIC}, + {"graphic", EDIF_TOK_GRAPHIC}, + {"inductance", EDIF_TOK_INDUCTANCE}, + {"inout", EDIF_TOK_INOUT}, + {"input", EDIF_TOK_INPUT}, + {"logicmodel", EDIF_TOK_LOGICMODEL}, + {"lowercenter", EDIF_TOK_LOWERCENTER}, + {"lowerleft", EDIF_TOK_LOWERLEFT}, + {"lowerright", EDIF_TOK_LOWERRIGHT}, + {"masklayout", EDIF_TOK_MASKLAYOUT}, + {"mass", EDIF_TOK_MASS}, + {"measured", EDIF_TOK_MEASURED}, + {"mx", EDIF_TOK_MX}, + {"mxr90", EDIF_TOK_MXR90}, + {"my", EDIF_TOK_MY}, + {"myr90", EDIF_TOK_MYR90}, + {"netlist", EDIF_TOK_NETLIST}, + {"output", EDIF_TOK_OUTPUT}, + {"pcblayout", EDIF_TOK_PCBLAYOUT}, + {"power", EDIF_TOK_POWER}, + {"r0", EDIF_TOK_R0}, + {"r180", EDIF_TOK_R180}, + {"r270", EDIF_TOK_R270}, + {"r90", EDIF_TOK_R90}, + {"required", EDIF_TOK_REQUIRED}, + {"resistance", EDIF_TOK_RESISTANCE}, + {"ripper", EDIF_TOK_RIPPER}, + {"round", EDIF_TOK_ROUND}, + {"schematic", EDIF_TOK_SCHEMATIC}, + {"stranger", EDIF_TOK_STRANGER}, + {"symbolic", EDIF_TOK_SYMBOLIC}, + {"temperature", EDIF_TOK_TEMPERATURE}, + {"tie", EDIF_TOK_TIE}, + {"time", EDIF_TOK_TIME}, + {"truncate", EDIF_TOK_TRUNCATE}, + {"uppercenter", EDIF_TOK_UPPERCENTER}, + {"upperleft", EDIF_TOK_UPPERLEFT}, + {"upperright", EDIF_TOK_UPPERRIGHT}, + {"voltage", EDIF_TOK_VOLTAGE} +}; +static int TokenDefSize = sizeof(TokenDef) / sizeof(Token); +/* + * Token enable definitions: + * + * There is one array for each set of tokens enabled by a + * particular context (barf). Another array is used to bind + * these arrays to a context. + */ +static short e_CellType[] = {EDIF_TOK_TIE, EDIF_TOK_RIPPER, EDIF_TOK_GENERIC}; +static short e_CornerType[] = {EDIF_TOK_EXTEND, EDIF_TOK_TRUNCATE, + EDIF_TOK_ROUND}; +static short e_Derivation[] = {EDIF_TOK_CALCULATED, EDIF_TOK_MEASURED, + EDIF_TOK_REQUIRED}; +static short e_Direction[] = {EDIF_TOK_INPUT, EDIF_TOK_OUTPUT, + EDIF_TOK_INOUT}; +static short e_EndType[] = {EDIF_TOK_EXTEND, EDIF_TOK_TRUNCATE, + EDIF_TOK_ROUND}; +static short e_Justify[] = {EDIF_TOK_CENTERCENTER, EDIF_TOK_CENTERLEFT, + EDIF_TOK_CENTERRIGHT, EDIF_TOK_LOWERCENTER, + EDIF_TOK_LOWERLEFT, EDIF_TOK_LOWERRIGHT, + EDIF_TOK_UPPERCENTER, EDIF_TOK_UPPERLEFT, + EDIF_TOK_UPPERRIGHT}; +static short e_Orientation[] = {EDIF_TOK_R0, EDIF_TOK_R90, EDIF_TOK_R180, + EDIF_TOK_R270, EDIF_TOK_MX, EDIF_TOK_MY, + EDIF_TOK_MXR90, EDIF_TOK_MYR90}; +static short e_Unit[] = {EDIF_TOK_DISTANCE, EDIF_TOK_CAPACITANCE, + EDIF_TOK_CURRENT, EDIF_TOK_RESISTANCE, + EDIF_TOK_TEMPERATURE, EDIF_TOK_TIME, + EDIF_TOK_VOLTAGE, EDIF_TOK_MASS, EDIF_TOK_FREQUENCY, + EDIF_TOK_INDUCTANCE, EDIF_TOK_ENERGY, + EDIF_TOK_POWER, EDIF_TOK_CHARGE, + EDIF_TOK_CONDUCTANCE, EDIF_TOK_FLUX, EDIF_TOK_ANGLE}; +static short e_ViewType[] = {EDIF_TOK_MASKLAYOUT, EDIF_TOK_PCBLAYOUT, + EDIF_TOK_NETLIST, EDIF_TOK_SCHEMATIC, + EDIF_TOK_SYMBOLIC, EDIF_TOK_BEHAVIOR, + EDIF_TOK_LOGICMODEL, EDIF_TOK_DOCUMENT, + EDIF_TOK_GRAPHIC, EDIF_TOK_STRANGER}; +/* + * Token tying table: + * + * This binds enabled tokens to a context. + */ +typedef struct Tie { + short *Enable; /* pointer to enable array */ + short Origin; /* '%token' value of context */ + short EnableSize; /* size of enabled array */ +} Tie; +#define TE(e,o) {e,o,sizeof(e)/sizeof(short)} +static Tie TieDef[] = { + TE(e_CellType, EDIF_TOK_CELLTYPE), + TE(e_CornerType, EDIF_TOK_CORNERTYPE), + TE(e_Derivation, EDIF_TOK_DERIVATION), + TE(e_Direction, EDIF_TOK_DIRECTION), + TE(e_EndType, EDIF_TOK_ENDTYPE), + TE(e_Justify, EDIF_TOK_JUSTIFY), + TE(e_Orientation, EDIF_TOK_ORIENTATION), + TE(e_Unit, EDIF_TOK_UNIT), + TE(e_ViewType, EDIF_TOK_VIEWTYPE) +}; +static int TieDefSize = sizeof(TieDef) / sizeof(Tie); +/* + * Context definitions: + * + * This associates keyword strings with '%token' values. It + * also creates a pretty much empty header for later building of + * the context tree. Again they needn't be sorted, but strings + * must be lower case. + */ +typedef struct Context { + const char *Name; /* keyword name */ + short Code; /* '%token' value */ + short Flags; /* special operation flags */ + struct ContextCar *Context; /* contexts which can be moved to */ + struct TokenCar *Token; /* active tokens */ + struct Context *Next; /* hash table linkage */ +} Context; +static Context ContextDef[] = { + {"", 0}, /* start context */ + {"acload", EDIF_TOK_ACLOAD}, + {"after", EDIF_TOK_AFTER}, + {"annotate", EDIF_TOK_ANNOTATE}, + {"apply", EDIF_TOK_APPLY}, + {"arc", EDIF_TOK_ARC}, + {"array", EDIF_TOK_ARRAY}, + {"arraymacro", EDIF_TOK_ARRAYMACRO}, + {"arrayrelatedinfo", EDIF_TOK_ARRAYRELATEDINFO}, + {"arraysite", EDIF_TOK_ARRAYSITE}, + {"atleast", EDIF_TOK_ATLEAST}, + {"atmost", EDIF_TOK_ATMOST}, + {"author", EDIF_TOK_AUTHOR}, + {"basearray", EDIF_TOK_BASEARRAY}, + {"becomes", EDIF_TOK_BECOMES}, + {"between", EDIF_TOK_BETWEEN}, + {"boolean", EDIF_TOK_BOOLEAN}, + {"booleandisplay", EDIF_TOK_BOOLEANDISPLAY}, + {"booleanmap", EDIF_TOK_BOOLEANMAP}, + {"borderpattern", EDIF_TOK_BORDERPATTERN}, + {"borderwidth", EDIF_TOK_BORDERWIDTH}, + {"boundingbox", EDIF_TOK_BOUNDINGBOX}, + {"cell", EDIF_TOK_CELL}, + {"cellref", EDIF_TOK_CELLREF}, + {"celltype", EDIF_TOK_CELLTYPE}, + {"change", EDIF_TOK_CHANGE}, + {"circle", EDIF_TOK_CIRCLE}, + {"color", EDIF_TOK_COLOR}, + {"comment", EDIF_TOK_COMMENT}, + {"commentgraphics", EDIF_TOK_COMMENTGRAPHICS}, + {"compound", EDIF_TOK_COMPOUND}, + {"connectlocation", EDIF_TOK_CONNECTLOCATION}, + {"contents", EDIF_TOK_CONTENTS}, + {"cornertype", EDIF_TOK_CORNERTYPE}, + {"criticality", EDIF_TOK_CRITICALITY}, + {"currentmap", EDIF_TOK_CURRENTMAP}, + {"curve", EDIF_TOK_CURVE}, + {"cycle", EDIF_TOK_CYCLE}, + {"dataorigin", EDIF_TOK_DATAORIGIN}, + {"dcfaninload", EDIF_TOK_DCFANINLOAD}, + {"dcfanoutload", EDIF_TOK_DCFANOUTLOAD}, + {"dcmaxfanin", EDIF_TOK_DCMAXFANIN}, + {"dcmaxfanout", EDIF_TOK_DCMAXFANOUT}, + {"delay", EDIF_TOK_DELAY}, + {"delta", EDIF_TOK_DELTA}, + {"derivation", EDIF_TOK_DERIVATION}, + {"design", EDIF_TOK_DESIGN}, + {"designator", EDIF_TOK_DESIGNATOR}, + {"difference", EDIF_TOK_DIFFERENCE}, + {"direction", EDIF_TOK_DIRECTION}, + {"display", EDIF_TOK_DISPLAY}, + {"dominates", EDIF_TOK_DOMINATES}, + {"dot", EDIF_TOK_DOT}, + {"duration", EDIF_TOK_DURATION}, + {"e", EDIF_TOK_E}, + {"edif", EDIF_TOK_EDIF}, + {"ediflevel", EDIF_TOK_EDIFLEVEL}, + {"edifversion", EDIF_TOK_EDIFVERSION}, + {"enclosuredistance", EDIF_TOK_ENCLOSUREDISTANCE}, + {"endtype", EDIF_TOK_ENDTYPE}, + {"entry", EDIF_TOK_ENTRY}, + {"exactly", EDIF_TOK_EXACTLY}, + {"external", EDIF_TOK_EXTERNAL}, + {"fabricate", EDIF_TOK_FABRICATE}, + {"false", EDIF_TOK_FALSE}, + {"figure", EDIF_TOK_FIGURE}, + {"figurearea", EDIF_TOK_FIGUREAREA}, + {"figuregroup", EDIF_TOK_FIGUREGROUP}, + {"figuregroupobject", EDIF_TOK_FIGUREGROUPOBJECT}, + {"figuregroupoverride", EDIF_TOK_FIGUREGROUPOVERRIDE}, + {"figuregroupref", EDIF_TOK_FIGUREGROUPREF}, + {"figureperimeter", EDIF_TOK_FIGUREPERIMETER}, + {"figurewidth", EDIF_TOK_FIGUREWIDTH}, + {"fillpattern", EDIF_TOK_FILLPATTERN}, + {"follow", EDIF_TOK_FOLLOW}, + {"forbiddenevent", EDIF_TOK_FORBIDDENEVENT}, + {"globalportref", EDIF_TOK_GLOBALPORTREF}, + {"greaterthan", EDIF_TOK_GREATERTHAN}, + {"gridmap", EDIF_TOK_GRIDMAP}, + {"ignore", EDIF_TOK_IGNORE}, + {"includefiguregroup", EDIF_TOK_INCLUDEFIGUREGROUP}, + {"initial", EDIF_TOK_INITIAL}, + {"instance", EDIF_TOK_INSTANCE}, + {"instancebackannotate", EDIF_TOK_INSTANCEBACKANNOTATE}, + {"instancegroup", EDIF_TOK_INSTANCEGROUP}, + {"instancemap", EDIF_TOK_INSTANCEMAP}, + {"instanceref", EDIF_TOK_INSTANCEREF}, + {"integer", EDIF_TOK_INTEGER}, + {"integerdisplay", EDIF_TOK_INTEGERDISPLAY}, + {"interface", EDIF_TOK_INTERFACE}, + {"interfiguregroupspacing", EDIF_TOK_INTERFIGUREGROUPSPACING}, + {"intersection", EDIF_TOK_INTERSECTION}, + {"intrafiguregroupspacing", EDIF_TOK_INTRAFIGUREGROUPSPACING}, + {"inverse", EDIF_TOK_INVERSE}, + {"isolated", EDIF_TOK_ISOLATED}, + {"joined", EDIF_TOK_JOINED}, + {"justify", EDIF_TOK_JUSTIFY}, + {"keyworddisplay", EDIF_TOK_KEYWORDDISPLAY}, + {"keywordlevel", EDIF_TOK_KEYWORDLEVEL}, + {"keywordmap", EDIF_TOK_KEYWORDMAP}, + {"lessthan", EDIF_TOK_LESSTHAN}, + {"library", EDIF_TOK_LIBRARY}, + {"libraryref", EDIF_TOK_LIBRARYREF}, + {"listofnets", EDIF_TOK_LISTOFNETS}, + {"listofports", EDIF_TOK_LISTOFPORTS}, + {"loaddelay", EDIF_TOK_LOADDELAY}, + {"logicassign", EDIF_TOK_LOGICASSIGN}, + {"logicinput", EDIF_TOK_LOGICINPUT}, + {"logiclist", EDIF_TOK_LOGICLIST}, + {"logicmapinput", EDIF_TOK_LOGICMAPINPUT}, + {"logicmapoutput", EDIF_TOK_LOGICMAPOUTPUT}, + {"logiconeof", EDIF_TOK_LOGICONEOF}, + {"logicoutput", EDIF_TOK_LOGICOUTPUT}, + {"logicport", EDIF_TOK_LOGICPORT}, + {"logicref", EDIF_TOK_LOGICREF}, + {"logicvalue", EDIF_TOK_LOGICVALUE}, + {"logicwaveform", EDIF_TOK_LOGICWAVEFORM}, + {"maintain", EDIF_TOK_MAINTAIN}, + {"match", EDIF_TOK_MATCH}, + {"member", EDIF_TOK_MEMBER}, + {"minomax", EDIF_TOK_MINOMAX}, + {"minomaxdisplay", EDIF_TOK_MINOMAXDISPLAY}, + {"mnm", EDIF_TOK_MNM}, + {"multiplevalueset", EDIF_TOK_MULTIPLEVALUESET}, + {"mustjoin", EDIF_TOK_MUSTJOIN}, + {"name", EDIF_TOK_NAME}, + {"net", EDIF_TOK_NET}, + {"netbackannotate", EDIF_TOK_NETBACKANNOTATE}, + {"netbundle", EDIF_TOK_NETBUNDLE}, + {"netdelay", EDIF_TOK_NETDELAY}, + {"netgroup", EDIF_TOK_NETGROUP}, + {"netmap", EDIF_TOK_NETMAP}, + {"netref", EDIF_TOK_NETREF}, + {"nochange", EDIF_TOK_NOCHANGE}, + {"nonpermutable", EDIF_TOK_NONPERMUTABLE}, + {"notallowed", EDIF_TOK_NOTALLOWED}, + {"notchspacing", EDIF_TOK_NOTCHSPACING}, + {"number", EDIF_TOK_NUMBER}, + {"numberdefinition", EDIF_TOK_NUMBERDEFINITION}, + {"numberdisplay", EDIF_TOK_NUMBERDISPLAY}, + {"offpageconnector", EDIF_TOK_OFFPAGECONNECTOR}, + {"offsetevent", EDIF_TOK_OFFSETEVENT}, + {"openshape", EDIF_TOK_OPENSHAPE}, + {"orientation", EDIF_TOK_ORIENTATION}, + {"origin", EDIF_TOK_ORIGIN}, + {"overhangdistance", EDIF_TOK_OVERHANGDISTANCE}, + {"overlapdistance", EDIF_TOK_OVERLAPDISTANCE}, + {"oversize", EDIF_TOK_OVERSIZE}, + {"owner", EDIF_TOK_OWNER}, + {"page", EDIF_TOK_PAGE}, + {"pagesize", EDIF_TOK_PAGESIZE}, + {"parameter", EDIF_TOK_PARAMETER}, + {"parameterassign", EDIF_TOK_PARAMETERASSIGN}, + {"parameterdisplay", EDIF_TOK_PARAMETERDISPLAY}, + {"path", EDIF_TOK_PATH}, + {"pathdelay", EDIF_TOK_PATHDELAY}, + {"pathwidth", EDIF_TOK_PATHWIDTH}, + {"permutable", EDIF_TOK_PERMUTABLE}, + {"physicaldesignrule", EDIF_TOK_PHYSICALDESIGNRULE}, + {"plug", EDIF_TOK_PLUG}, + {"point", EDIF_TOK_POINT}, + {"pointdisplay", EDIF_TOK_POINTDISPLAY}, + {"pointlist", EDIF_TOK_POINTLIST}, + {"polygon", EDIF_TOK_POLYGON}, + {"port", EDIF_TOK_PORT}, + {"portbackannotate", EDIF_TOK_PORTBACKANNOTATE}, + {"portbundle", EDIF_TOK_PORTBUNDLE}, + {"portdelay", EDIF_TOK_PORTDELAY}, + {"portgroup", EDIF_TOK_PORTGROUP}, + {"portimplementation", EDIF_TOK_PORTIMPLEMENTATION}, + {"portinstance", EDIF_TOK_PORTINSTANCE}, + {"portlist", EDIF_TOK_PORTLIST}, + {"portlistalias", EDIF_TOK_PORTLISTALIAS}, + {"portmap", EDIF_TOK_PORTMAP}, + {"portref", EDIF_TOK_PORTREF}, + {"program", EDIF_TOK_PROGRAM}, + {"property", EDIF_TOK_PROPERTY}, + {"propertydisplay", EDIF_TOK_PROPERTYDISPLAY}, + {"protectionframe", EDIF_TOK_PROTECTIONFRAME}, + {"pt", EDIF_TOK_PT}, + {"rangevector", EDIF_TOK_RANGEVECTOR}, + {"rectangle", EDIF_TOK_RECTANGLE}, + {"rectanglesize", EDIF_TOK_RECTANGLESIZE}, + {"rename", EDIF_TOK_RENAME}, + {"resolves", EDIF_TOK_RESOLVES}, + {"scale", EDIF_TOK_SCALE}, + {"scalex", EDIF_TOK_SCALEX}, + {"scaley", EDIF_TOK_SCALEY}, + {"section", EDIF_TOK_SECTION}, + {"shape", EDIF_TOK_SHAPE}, + {"simulate", EDIF_TOK_SIMULATE}, + {"simulationinfo", EDIF_TOK_SIMULATIONINFO}, + {"singlevalueset", EDIF_TOK_SINGLEVALUESET}, + {"site", EDIF_TOK_SITE}, + {"socket", EDIF_TOK_SOCKET}, + {"socketset", EDIF_TOK_SOCKETSET}, + {"status", EDIF_TOK_STATUS}, + {"steady", EDIF_TOK_STEADY}, + {"string", EDIF_TOK_STRING}, + {"stringdisplay", EDIF_TOK_STRINGDISPLAY}, + {"strong", EDIF_TOK_STRONG}, + {"symbol", EDIF_TOK_SYMBOL}, + {"symmetry", EDIF_TOK_SYMMETRY}, + {"table", EDIF_TOK_TABLE}, + {"tabledefault", EDIF_TOK_TABLEDEFAULT}, + {"technology", EDIF_TOK_TECHNOLOGY}, + {"textheight", EDIF_TOK_TEXTHEIGHT}, + {"timeinterval", EDIF_TOK_TIMEINTERVAL}, + {"timestamp", EDIF_TOK_TIMESTAMP}, + {"timing", EDIF_TOK_TIMING}, + {"transform", EDIF_TOK_TRANSFORM}, + {"transition", EDIF_TOK_TRANSITION}, + {"trigger", EDIF_TOK_TRIGGER}, + {"true", EDIF_TOK_TRUE}, + {"unconstrained", EDIF_TOK_UNCONSTRAINED}, + {"undefined", EDIF_TOK_UNDEFINED}, + {"union", EDIF_TOK_UNION}, + {"unit", EDIF_TOK_UNIT}, + {"unused", EDIF_TOK_UNUSED}, + {"userdata", EDIF_TOK_USERDATA}, + {"version", EDIF_TOK_VERSION}, + {"view", EDIF_TOK_VIEW}, + {"viewlist", EDIF_TOK_VIEWLIST}, + {"viewmap", EDIF_TOK_VIEWMAP}, + {"viewref", EDIF_TOK_VIEWREF}, + {"viewtype", EDIF_TOK_VIEWTYPE}, + {"visible", EDIF_TOK_VISIBLE}, + {"voltagemap", EDIF_TOK_VOLTAGEMAP}, + {"wavevalue", EDIF_TOK_WAVEVALUE}, + {"weak", EDIF_TOK_WEAK}, + {"weakjoined", EDIF_TOK_WEAKJOINED}, + {"when", EDIF_TOK_WHEN}, + {"written", EDIF_TOK_WRITTEN} +}; +static int ContextDefSize = sizeof(ContextDef) / sizeof(Context); +/* + * Context follower tables: + * + * This is pretty ugly, an array is defined for each context + * which has following context levels. Yet another table is used + * to bind these arrays to the originating contexts. + * Arrays are declared as: + * + * static short f_[] = { ... }; + * + * The array entries are the '%token' values for all keywords which + * can be reached from the context. Like I said, ugly, + * but it works. + * A negative entry means that the follow can only occur once within + * the specified context. + */ +static short f_NULL[] = {EDIF_TOK_EDIF}; +static short f_Edif[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_EDIFVERSION, + EDIF_TOK_EDIFLEVEL, EDIF_TOK_KEYWORDMAP, + -EDIF_TOK_STATUS, EDIF_TOK_EXTERNAL, + EDIF_TOK_LIBRARY, EDIF_TOK_DESIGN, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_AcLoad[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY}; +static short f_After[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_FOLLOW, + EDIF_TOK_MAINTAIN, EDIF_TOK_LOGICASSIGN, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_Annotate[] = {EDIF_TOK_STRINGDISPLAY}; +static short f_Apply[] = {EDIF_TOK_CYCLE, EDIF_TOK_LOGICINPUT, + EDIF_TOK_LOGICOUTPUT, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Arc[] = {EDIF_TOK_PT}; +static short f_Array[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME}; +static short f_ArrayMacro[] = {EDIF_TOK_PLUG}; +static short f_ArrayRelatedInfo[] = {EDIF_TOK_BASEARRAY, EDIF_TOK_ARRAYSITE, + EDIF_TOK_ARRAYMACRO, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_ArraySite[] = {EDIF_TOK_SOCKET}; +static short f_AtLeast[] = {EDIF_TOK_E}; +static short f_AtMost[] = {EDIF_TOK_E}; +static short f_Becomes[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, + EDIF_TOK_LOGICONEOF}; +/* +static short f_Between[] = {EDIF_TOK_ATLEAST, EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_LESSTHAN}; +*/ +static short f_Boolean[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE, + EDIF_TOK_BOOLEANDISPLAY, EDIF_TOK_BOOLEAN}; +static short f_BooleanDisplay[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE, + EDIF_TOK_DISPLAY}; +static short f_BooleanMap[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE}; +static short f_BorderPattern[] = {EDIF_TOK_BOOLEAN}; +static short f_BoundingBox[] = {EDIF_TOK_RECTANGLE}; +static short f_Cell[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_CELLTYPE, + -EDIF_TOK_STATUS, -EDIF_TOK_VIEWMAP, EDIF_TOK_VIEW, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA, + EDIF_TOK_PROPERTY}; +static short f_CellRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; +static short f_Change[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, + EDIF_TOK_BECOMES, EDIF_TOK_TRANSITION}; +static short f_Circle[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; +static short f_Color[] = {EDIF_TOK_E}; +static short f_CommentGraphics[] = {EDIF_TOK_ANNOTATE, EDIF_TOK_FIGURE, + EDIF_TOK_INSTANCE, -EDIF_TOK_BOUNDINGBOX, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Compound[] = {EDIF_TOK_NAME}; +static short f_ConnectLocation[] = {EDIF_TOK_FIGURE}; +static short f_Contents[] = {EDIF_TOK_INSTANCE, EDIF_TOK_OFFPAGECONNECTOR, + EDIF_TOK_FIGURE, EDIF_TOK_SECTION, EDIF_TOK_NET, + EDIF_TOK_NETBUNDLE, EDIF_TOK_PAGE, + EDIF_TOK_COMMENTGRAPHICS, + EDIF_TOK_PORTIMPLEMENTATION, + EDIF_TOK_TIMING, EDIF_TOK_SIMULATE, + EDIF_TOK_WHEN, EDIF_TOK_FOLLOW, + EDIF_TOK_LOGICPORT, -EDIF_TOK_BOUNDINGBOX, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_Criticality[] = {EDIF_TOK_INTEGERDISPLAY}; +static short f_CurrentMap[] = {EDIF_TOK_MNM, EDIF_TOK_E}; +static short f_Curve[] = {EDIF_TOK_ARC, EDIF_TOK_PT}; +static short f_Cycle[] = {EDIF_TOK_DURATION}; +static short f_DataOrigin[] = {EDIF_TOK_VERSION}; +static short f_DcFanInLoad[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; +static short f_DcFanOutLoad[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; +static short f_DcMaxFanIn[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; +static short f_DcMaxFanOut[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY}; +static short f_Delay[] = {EDIF_TOK_MNM, EDIF_TOK_E}; +static short f_Delta[] = {EDIF_TOK_PT}; +static short f_Design[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_CELLREF, + EDIF_TOK_STATUS, EDIF_TOK_COMMENT, + EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; +static short f_Designator[] = {EDIF_TOK_STRINGDISPLAY}; +static short f_Difference[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, + EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, + EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; +static short f_Display[] = {EDIF_TOK_NAME, EDIF_TOK_FIGUREGROUPOVERRIDE, + EDIF_TOK_JUSTIFY, EDIF_TOK_ORIENTATION, + EDIF_TOK_ORIGIN}; +static short f_Dominates[] = {EDIF_TOK_NAME}; +static short f_Dot[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; +static short f_Duration[] = {EDIF_TOK_E}; +static short f_EnclosureDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, + EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, + EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_Entry[] = {EDIF_TOK_MATCH, EDIF_TOK_CHANGE, EDIF_TOK_STEADY, + EDIF_TOK_LOGICREF, EDIF_TOK_PORTREF, + EDIF_TOK_NOCHANGE, EDIF_TOK_TABLE, + EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; +static short f_Exactly[] = {EDIF_TOK_E}; +static short f_External[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_EDIFLEVEL, EDIF_TOK_TECHNOLOGY, + -EDIF_TOK_STATUS, EDIF_TOK_CELL, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Fabricate[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME}; +static short f_Figure[] = {EDIF_TOK_NAME, EDIF_TOK_FIGUREGROUPOVERRIDE, + EDIF_TOK_CIRCLE, EDIF_TOK_DOT, EDIF_TOK_OPENSHAPE, + EDIF_TOK_PATH, EDIF_TOK_POLYGON, + EDIF_TOK_RECTANGLE, EDIF_TOK_SHAPE, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_FigureArea[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_FigureGroup[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + -EDIF_TOK_CORNERTYPE, -EDIF_TOK_ENDTYPE, + -EDIF_TOK_PATHWIDTH, -EDIF_TOK_BORDERWIDTH, + -EDIF_TOK_COLOR, -EDIF_TOK_FILLPATTERN, + -EDIF_TOK_BORDERPATTERN, -EDIF_TOK_TEXTHEIGHT, + -EDIF_TOK_VISIBLE, EDIF_TOK_INCLUDEFIGUREGROUP, + EDIF_TOK_COMMENT, EDIF_TOK_PROPERTY, + EDIF_TOK_USERDATA}; +static short f_FigureGroupObject[] = {EDIF_TOK_NAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, + EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, + EDIF_TOK_OVERSIZE}; +static short f_FigureGroupOverride[] = {EDIF_TOK_NAME, -EDIF_TOK_CORNERTYPE, + -EDIF_TOK_ENDTYPE, -EDIF_TOK_PATHWIDTH, + -EDIF_TOK_BORDERWIDTH, -EDIF_TOK_COLOR, + -EDIF_TOK_FILLPATTERN, + -EDIF_TOK_TEXTHEIGHT, + -EDIF_TOK_BORDERPATTERN, + EDIF_TOK_VISIBLE, EDIF_TOK_COMMENT, + EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; +static short f_FigureGroupRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; +static short f_FigurePerimeter[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, + EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, + EDIF_TOK_SINGLEVALUESET, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_FigureWidth[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_FillPattern[] = {EDIF_TOK_BOOLEAN}; +static short f_Follow[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_TABLE, + EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; +static short f_ForbiddenEvent[] = {EDIF_TOK_TIMEINTERVAL, EDIF_TOK_EVENT}; +static short f_GlobalPortRef[] = {EDIF_TOK_NAME}; +static short f_GreaterThan[] = {EDIF_TOK_E}; +static short f_GridMap[] = {EDIF_TOK_E}; +static short f_IncludeFigureGroup[] = {EDIF_TOK_FIGUREGROUPREF, + EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, + EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, + EDIF_TOK_OVERSIZE}; +static short f_Instance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + EDIF_TOK_VIEWREF, EDIF_TOK_VIEWLIST, + -EDIF_TOK_TRANSFORM, EDIF_TOK_PARAMETERASSIGN, + EDIF_TOK_PORTINSTANCE, EDIF_TOK_TIMING, + -EDIF_TOK_DESIGNATOR, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_InstanceBackAnnotate[] = {EDIF_TOK_INSTANCEREF, + -EDIF_TOK_DESIGNATOR, EDIF_TOK_TIMING, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; +static short f_InstanceGroup[] = {EDIF_TOK_INSTANCEREF}; +static short f_InstanceMap[] = {EDIF_TOK_INSTANCEREF, EDIF_TOK_INSTANCEGROUP, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_InstanceRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, + EDIF_TOK_INSTANCEREF, EDIF_TOK_VIEWREF}; +static short f_Integer[] = {EDIF_TOK_INTEGERDISPLAY, EDIF_TOK_INTEGER}; +static short f_IntegerDisplay[] = {EDIF_TOK_DISPLAY}; +static short f_Interface[] = {EDIF_TOK_PORT, EDIF_TOK_PORTBUNDLE, + -EDIF_TOK_SYMBOL, -EDIF_TOK_PROTECTIONFRAME, + -EDIF_TOK_ARRAYRELATEDINFO, EDIF_TOK_PARAMETER, + EDIF_TOK_JOINED, EDIF_TOK_MUSTJOIN, + EDIF_TOK_WEAKJOINED, EDIF_TOK_PERMUTABLE, + EDIF_TOK_TIMING, EDIF_TOK_SIMULATE, + -EDIF_TOK_DESIGNATOR, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_InterFigureGroupSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, + EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Intersection[] = {EDIF_TOK_FIGUREGROUPREF, + EDIF_TOK_INTERSECTION, EDIF_TOK_UNION, + EDIF_TOK_DIFFERENCE, EDIF_TOK_INVERSE, + EDIF_TOK_OVERSIZE}; +static short f_IntraFigureGroupSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, + EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, + EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Inverse[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, + EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, + EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; +static short f_Joined[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, + EDIF_TOK_GLOBALPORTREF}; +static short f_KeywordDisplay[] = {EDIF_TOK_DISPLAY}; +static short f_KeywordMap[] = {EDIF_TOK_KEYWORDLEVEL, EDIF_TOK_COMMENT}; +static short f_LessThan[] = {EDIF_TOK_E}; +static short f_Library[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_EDIFLEVEL, + EDIF_TOK_TECHNOLOGY, -EDIF_TOK_STATUS, + EDIF_TOK_CELL, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_LibraryRef[] = {EDIF_TOK_NAME}; +static short f_ListOfNets[] = {EDIF_TOK_NET}; +static short f_ListOfPorts[] = {EDIF_TOK_PORT, EDIF_TOK_PORTBUNDLE}; +static short f_LoadDelay[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY}; +static short f_LogicAssign[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, + EDIF_TOK_LOGICREF, EDIF_TOK_TABLE, + EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; +static short f_LogicInput[] = {EDIF_TOK_PORTLIST, EDIF_TOK_PORTREF, + EDIF_TOK_NAME, EDIF_TOK_LOGICWAVEFORM}; +static short f_LogicList[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICONEOF, + EDIF_TOK_IGNORE}; +static short f_LogicMapInput[] = {EDIF_TOK_LOGICREF}; +static short f_LogicMapOutput[] = {EDIF_TOK_LOGICREF}; +static short f_LogicOneOf[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST}; +static short f_LogicOutput[] = {EDIF_TOK_PORTLIST, EDIF_TOK_PORTREF, + EDIF_TOK_NAME, EDIF_TOK_LOGICWAVEFORM}; +static short f_LogicPort[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_LogicRef[] = {EDIF_TOK_NAME, EDIF_TOK_LIBRARYREF}; +static short f_LogicValue[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + -EDIF_TOK_VOLTAGEMAP, -EDIF_TOK_CURRENTMAP, + -EDIF_TOK_BOOLEANMAP, -EDIF_TOK_COMPOUND, + -EDIF_TOK_WEAK ,-EDIF_TOK_STRONG, + -EDIF_TOK_DOMINATES, -EDIF_TOK_LOGICMAPOUTPUT, + -EDIF_TOK_LOGICMAPINPUT, + -EDIF_TOK_ISOLATED, EDIF_TOK_RESOLVES, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_LogicWaveform[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, + EDIF_TOK_LOGICONEOF, EDIF_TOK_IGNORE}; +static short f_Maintain[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_DELAY, + EDIF_TOK_LOADDELAY}; +static short f_Match[] = {EDIF_TOK_NAME, EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, + EDIF_TOK_LOGICLIST, EDIF_TOK_LOGICONEOF}; +static short f_Member[] = {EDIF_TOK_NAME}; +static short f_MiNoMax[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_MINOMAXDISPLAY, + EDIF_TOK_MINOMAX}; +static short f_MiNoMaxDisplay[] = {EDIF_TOK_MNM, EDIF_TOK_E, EDIF_TOK_DISPLAY}; +static short f_Mnm[] = {EDIF_TOK_E, EDIF_TOK_UNDEFINED, + EDIF_TOK_UNCONSTRAINED}; +static short f_MultipleValueSet[] = {EDIF_TOK_RANGEVECTOR}; +static short f_MustJoin[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, + EDIF_TOK_WEAKJOINED, EDIF_TOK_JOINED}; +static short f_Name[] = {EDIF_TOK_DISPLAY}; +static short f_Net[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, -EDIF_TOK_CRITICALITY, + EDIF_TOK_NETDELAY, EDIF_TOK_FIGURE, EDIF_TOK_NET, + EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA, EDIF_TOK_JOINED, EDIF_TOK_ARRAY}; +static short f_NetBackAnnotate[] = {EDIF_TOK_NETREF, EDIF_TOK_NETDELAY, + -EDIF_TOK_CRITICALITY, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT}; +static short f_NetBundle[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + EDIF_TOK_LISTOFNETS, EDIF_TOK_FIGURE, + EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_NetDelay[] = {EDIF_TOK_DERIVATION, EDIF_TOK_DELAY, + EDIF_TOK_TRANSITION, EDIF_TOK_BECOMES}; +static short f_NetGroup[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_NETREF}; +static short f_NetMap[] = {EDIF_TOK_NETREF, EDIF_TOK_NETGROUP, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_NetRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_NETREF, + EDIF_TOK_INSTANCEREF, EDIF_TOK_VIEWREF}; +static short f_NonPermutable[] = {EDIF_TOK_PORTREF, EDIF_TOK_PERMUTABLE}; +static short f_NotAllowed[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_NotchSpacing[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_Number[] = {EDIF_TOK_E, EDIF_TOK_NUMBERDISPLAY, EDIF_TOK_NUMBER}; +static short f_NumberDefinition[] = {EDIF_TOK_SCALE, -EDIF_TOK_GRIDMAP, + EDIF_TOK_COMMENT}; +static short f_NumberDisplay[] = {EDIF_TOK_E, EDIF_TOK_DISPLAY}; +static short f_OffPageConnector[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + -EDIF_TOK_UNUSED, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_OffsetEvent[] = {EDIF_TOK_EVENT, EDIF_TOK_E}; +static short f_OpenShape[] = {EDIF_TOK_CURVE, EDIF_TOK_PROPERTY}; +static short f_Origin[] = {EDIF_TOK_PT}; +static short f_OverhangDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_OverlapDistance[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, EDIF_TOK_LESSTHAN, + EDIF_TOK_GREATERTHAN, EDIF_TOK_ATMOST, + EDIF_TOK_ATLEAST, EDIF_TOK_EXACTLY, + EDIF_TOK_BETWEEN, EDIF_TOK_SINGLEVALUESET, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_Oversize[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, + EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, + EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE, + EDIF_TOK_CORNERTYPE}; +static short f_Page[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + EDIF_TOK_INSTANCE, EDIF_TOK_NET, EDIF_TOK_NETBUNDLE, + EDIF_TOK_COMMENTGRAPHICS, EDIF_TOK_PORTIMPLEMENTATION, + -EDIF_TOK_PAGESIZE, -EDIF_TOK_BOUNDINGBOX, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_PageSize[] = {EDIF_TOK_RECTANGLE}; +static short f_Parameter[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + EDIF_TOK_BOOLEAN, EDIF_TOK_INTEGER, + EDIF_TOK_MINOMAX, EDIF_TOK_NUMBER, + EDIF_TOK_POINT, EDIF_TOK_STRING}; +static short f_ParameterAssign[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, + EDIF_TOK_BOOLEAN, EDIF_TOK_INTEGER, + EDIF_TOK_MINOMAX, EDIF_TOK_NUMBER, EDIF_TOK_POINT, + EDIF_TOK_STRING}; +static short f_ParameterDisplay[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, + EDIF_TOK_DISPLAY}; +static short f_Path[] = {EDIF_TOK_POINTLIST, EDIF_TOK_PROPERTY}; +static short f_PathDelay[] = {EDIF_TOK_DELAY, EDIF_TOK_EVENT}; +static short f_Permutable[] = {EDIF_TOK_PORTREF, EDIF_TOK_PERMUTABLE, + EDIF_TOK_NONPERMUTABLE}; +static short f_PhysicalDesignRule[] = {EDIF_TOK_FIGUREWIDTH, + EDIF_TOK_FIGUREAREA, + EDIF_TOK_RECTANGLESIZE, + EDIF_TOK_FIGUREPERIMETER, + EDIF_TOK_OVERLAPDISTANCE, + EDIF_TOK_OVERHANGDISTANCE, + EDIF_TOK_ENCLOSUREDISTANCE, + EDIF_TOK_INTERFIGUREGROUPSPACING, + EDIF_TOK_NOTCHSPACING, + EDIF_TOK_INTRAFIGUREGROUPSPACING, + EDIF_TOK_NOTALLOWED, + EDIF_TOK_FIGUREGROUP, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Plug[] = {EDIF_TOK_SOCKETSET}; +static short f_Point[] = {EDIF_TOK_PT, EDIF_TOK_POINTDISPLAY, + EDIF_TOK_POINT}; +static short f_PointDisplay[] = {EDIF_TOK_PT, EDIF_TOK_DISPLAY}; +static short f_PointList[] = {EDIF_TOK_PT}; +static short f_Polygon[] = {EDIF_TOK_POINTLIST, EDIF_TOK_PROPERTY}; +static short f_Port[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + -EDIF_TOK_DIRECTION, -EDIF_TOK_UNUSED, + EDIF_TOK_PORTDELAY, -EDIF_TOK_DESIGNATOR, + -EDIF_TOK_DCFANINLOAD, -EDIF_TOK_DCFANOUTLOAD, + -EDIF_TOK_DCMAXFANIN, -EDIF_TOK_DCMAXFANOUT, + -EDIF_TOK_ACLOAD, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_PortBackAnnotate[] = {EDIF_TOK_PORTREF, -EDIF_TOK_DESIGNATOR, + EDIF_TOK_PORTDELAY, -EDIF_TOK_DCFANINLOAD, + -EDIF_TOK_DCFANOUTLOAD, + -EDIF_TOK_DCMAXFANIN, + -EDIF_TOK_DCMAXFANOUT, -EDIF_TOK_ACLOAD, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; +static short f_PortBundle[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_ARRAY, + EDIF_TOK_LISTOFPORTS, EDIF_TOK_PROPERTY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_PortDelay[] = {EDIF_TOK_DERIVATION, EDIF_TOK_DELAY, + EDIF_TOK_LOADDELAY, EDIF_TOK_TRANSITION, + EDIF_TOK_BECOMES}; +static short f_PortGroup[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, + EDIF_TOK_PORTREF}; +static short f_PortImplementation[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, EDIF_TOK_MEMBER, + -EDIF_TOK_CONNECTLOCATION, + EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, + EDIF_TOK_COMMENTGRAPHICS, + EDIF_TOK_PROPERTYDISPLAY, + EDIF_TOK_KEYWORDDISPLAY, + EDIF_TOK_PROPERTY, + EDIF_TOK_USERDATA, EDIF_TOK_COMMENT}; +static short f_PortInstance[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, + EDIF_TOK_MEMBER, -EDIF_TOK_UNUSED, + EDIF_TOK_PORTDELAY, -EDIF_TOK_DESIGNATOR, + -EDIF_TOK_DCFANINLOAD, + -EDIF_TOK_DCFANOUTLOAD, -EDIF_TOK_DCMAXFANIN, + -EDIF_TOK_DCMAXFANOUT, -EDIF_TOK_ACLOAD, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_PortList[] = {EDIF_TOK_PORTREF, EDIF_TOK_NAME, + EDIF_TOK_MEMBER}; +static short f_PortListAlias[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_ARRAY, EDIF_TOK_PORTLIST}; +static short f_PortMap[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTGROUP, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_PortRef[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, + EDIF_TOK_PORTREF, EDIF_TOK_INSTANCEREF, + EDIF_TOK_VIEWREF}; +static short f_Program[] = {EDIF_TOK_VERSION}; +static short f_Property[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_BOOLEAN, + EDIF_TOK_INTEGER, EDIF_TOK_MINOMAX, + EDIF_TOK_NUMBER, EDIF_TOK_POINT, EDIF_TOK_STRING, + -EDIF_TOK_OWNER, -EDIF_TOK_UNIT, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT}; +static short f_PropertyDisplay[] = {EDIF_TOK_NAME, EDIF_TOK_DISPLAY}; +static short f_ProtectionFrame[] = {EDIF_TOK_PORTIMPLEMENTATION, + EDIF_TOK_FIGURE, EDIF_TOK_INSTANCE, + EDIF_TOK_COMMENTGRAPHICS, + -EDIF_TOK_BOUNDINGBOX, + EDIF_TOK_PROPERTYDISPLAY, + EDIF_TOK_KEYWORDDISPLAY, + EDIF_TOK_PARAMETERDISPLAY, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_RangeVector[] = {EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, + EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN, + EDIF_TOK_SINGLEVALUESET}; +static short f_Rectangle[] = {EDIF_TOK_PT, EDIF_TOK_PROPERTY}; +static short f_RectangleSize[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, + EDIF_TOK_FIGUREGROUPOBJECT, + EDIF_TOK_RANGEVECTOR, + EDIF_TOK_MULTIPLEVALUESET,EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Rename[] = {EDIF_TOK_NAME, EDIF_TOK_STRINGDISPLAY}; +static short f_Resolves[] = {EDIF_TOK_NAME}; +static short f_Scale[] = {EDIF_TOK_E, EDIF_TOK_UNIT}; +static short f_Section[] = {EDIF_TOK_SECTION, EDIF_TOK_INSTANCE}; +static short f_Shape[] = {EDIF_TOK_CURVE, EDIF_TOK_PROPERTY}; +static short f_Simulate[] = {EDIF_TOK_NAME, EDIF_TOK_PORTLISTALIAS, + EDIF_TOK_WAVEVALUE, EDIF_TOK_APPLY, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA}; +static short f_SimulationInfo[] = {EDIF_TOK_LOGICVALUE, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_SingleValueSet[] = {EDIF_TOK_LESSTHAN, EDIF_TOK_GREATERTHAN, + EDIF_TOK_ATMOST, EDIF_TOK_ATLEAST, + EDIF_TOK_EXACTLY, EDIF_TOK_BETWEEN}; +static short f_Site[] = {EDIF_TOK_VIEWREF, EDIF_TOK_TRANSFORM}; +static short f_Socket[] = {EDIF_TOK_SYMMETRY}; +static short f_SocketSet[] = {EDIF_TOK_SYMMETRY, EDIF_TOK_SITE}; +static short f_Status[] = {EDIF_TOK_WRITTEN, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Steady[] = {EDIF_TOK_NAME, EDIF_TOK_MEMBER, EDIF_TOK_PORTREF, + EDIF_TOK_PORTLIST, EDIF_TOK_DURATION, + EDIF_TOK_TRANSITION, EDIF_TOK_BECOMES}; +static short f_String[] = {EDIF_TOK_STRINGDISPLAY, EDIF_TOK_STRING}; +static short f_StringDisplay[] = {EDIF_TOK_DISPLAY}; +static short f_Strong[] = {EDIF_TOK_NAME}; +static short f_Symbol[] = {EDIF_TOK_PORTIMPLEMENTATION, EDIF_TOK_FIGURE, + EDIF_TOK_INSTANCE, EDIF_TOK_COMMENTGRAPHICS, + EDIF_TOK_ANNOTATE, -EDIF_TOK_PAGESIZE, + -EDIF_TOK_BOUNDINGBOX, EDIF_TOK_PROPERTYDISPLAY, + EDIF_TOK_KEYWORDDISPLAY, EDIF_TOK_PARAMETERDISPLAY, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Symmetry[] = {EDIF_TOK_TRANSFORM}; +static short f_Table[] = {EDIF_TOK_ENTRY, EDIF_TOK_TABLEDEFAULT}; +static short f_TableDefault[] = {EDIF_TOK_LOGICREF, EDIF_TOK_PORTREF, + EDIF_TOK_NOCHANGE, EDIF_TOK_TABLE, + EDIF_TOK_DELAY, EDIF_TOK_LOADDELAY}; +static short f_Technology[] = {EDIF_TOK_NUMBERDEFINITION, EDIF_TOK_FIGUREGROUP, + EDIF_TOK_FABRICATE, -EDIF_TOK_SIMULATIONINFO, + EDIF_TOK_COMMENT, EDIF_TOK_USERDATA, + -EDIF_TOK_PHYSICALDESIGNRULE}; +static short f_TimeInterval[] = {EDIF_TOK_EVENT, EDIF_TOK_OFFSETEVENT, + EDIF_TOK_DURATION}; +static short f_Timing[] = {EDIF_TOK_DERIVATION, EDIF_TOK_PATHDELAY, + EDIF_TOK_FORBIDDENEVENT, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Transform[] = {EDIF_TOK_SCALEX, EDIF_TOK_SCALEY, EDIF_TOK_DELTA, + EDIF_TOK_ORIENTATION, EDIF_TOK_ORIGIN}; +static short f_Transition[] = {EDIF_TOK_NAME, EDIF_TOK_LOGICLIST, + EDIF_TOK_LOGICONEOF}; +static short f_Trigger[] = {EDIF_TOK_CHANGE, EDIF_TOK_STEADY, + EDIF_TOK_INITIAL}; +static short f_Union[] = {EDIF_TOK_FIGUREGROUPREF, EDIF_TOK_INTERSECTION, + EDIF_TOK_UNION, EDIF_TOK_DIFFERENCE, + EDIF_TOK_INVERSE, EDIF_TOK_OVERSIZE}; +static short f_View[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_VIEWTYPE, + EDIF_TOK_INTERFACE, -EDIF_TOK_STATUS, + -EDIF_TOK_CONTENTS, EDIF_TOK_COMMENT, + EDIF_TOK_PROPERTY, EDIF_TOK_USERDATA}; +static short f_ViewList[] = {EDIF_TOK_VIEWREF, EDIF_TOK_VIEWLIST}; +static short f_ViewMap[] = {EDIF_TOK_PORTMAP, EDIF_TOK_PORTBACKANNOTATE, + EDIF_TOK_INSTANCEMAP, + EDIF_TOK_INSTANCEBACKANNOTATE, EDIF_TOK_NETMAP, + EDIF_TOK_NETBACKANNOTATE, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_ViewRef[] = {EDIF_TOK_NAME, EDIF_TOK_CELLREF}; +static short f_Visible[] = {EDIF_TOK_FALSE, EDIF_TOK_TRUE}; +static short f_VoltageMap[] = {EDIF_TOK_MNM, EDIF_TOK_E}; +static short f_WaveValue[] = {EDIF_TOK_NAME, EDIF_TOK_RENAME, EDIF_TOK_E, + EDIF_TOK_LOGICWAVEFORM}; +static short f_Weak[] = {EDIF_TOK_NAME}; +static short f_WeakJoined[] = {EDIF_TOK_PORTREF, EDIF_TOK_PORTLIST, + EDIF_TOK_JOINED}; +static short f_When[] = {EDIF_TOK_TRIGGER, EDIF_TOK_AFTER, + EDIF_TOK_FOLLOW, EDIF_TOK_MAINTAIN, + EDIF_TOK_LOGICASSIGN, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +static short f_Written[] = {EDIF_TOK_TIMESTAMP, EDIF_TOK_AUTHOR, + EDIF_TOK_PROGRAM, EDIF_TOK_DATAORIGIN, + EDIF_TOK_PROPERTY, EDIF_TOK_COMMENT, + EDIF_TOK_USERDATA}; +/* + * Context binding table: + * + * This binds context follower arrays to their originating context. + */ +typedef struct Binder { + short *Follower; /* pointer to follower array */ + short Origin; /* '%token' value of origin */ + short FollowerSize; /* size of follower array */ +} Binder; +#define BE(f,o) {f,o,sizeof(f)/sizeof(short)} +static Binder BinderDef[] = { + BE(f_NULL, 0), + BE(f_Edif, EDIF_TOK_EDIF), + BE(f_AcLoad, EDIF_TOK_ACLOAD), + BE(f_After, EDIF_TOK_AFTER), + BE(f_Annotate, EDIF_TOK_ANNOTATE), + BE(f_Apply, EDIF_TOK_APPLY), + BE(f_Arc, EDIF_TOK_ARC), + BE(f_Array, EDIF_TOK_ARRAY), + BE(f_ArrayMacro, EDIF_TOK_ARRAYMACRO), + BE(f_ArrayRelatedInfo, EDIF_TOK_ARRAYRELATEDINFO), + BE(f_ArraySite, EDIF_TOK_ARRAYSITE), + BE(f_AtLeast, EDIF_TOK_ATLEAST), + BE(f_AtMost, EDIF_TOK_ATMOST), + BE(f_Becomes, EDIF_TOK_BECOMES), + BE(f_Boolean, EDIF_TOK_BOOLEAN), + BE(f_BooleanDisplay, EDIF_TOK_BOOLEANDISPLAY), + BE(f_BooleanMap, EDIF_TOK_BOOLEANMAP), + BE(f_BorderPattern, EDIF_TOK_BORDERPATTERN), + BE(f_BoundingBox, EDIF_TOK_BOUNDINGBOX), + BE(f_Cell, EDIF_TOK_CELL), + BE(f_CellRef, EDIF_TOK_CELLREF), + BE(f_Change, EDIF_TOK_CHANGE), + BE(f_Circle, EDIF_TOK_CIRCLE), + BE(f_Color, EDIF_TOK_COLOR), + BE(f_CommentGraphics, EDIF_TOK_COMMENTGRAPHICS), + BE(f_Compound, EDIF_TOK_COMPOUND), + BE(f_ConnectLocation, EDIF_TOK_CONNECTLOCATION), + BE(f_Contents, EDIF_TOK_CONTENTS), + BE(f_Criticality, EDIF_TOK_CRITICALITY), + BE(f_CurrentMap, EDIF_TOK_CURRENTMAP), + BE(f_Curve, EDIF_TOK_CURVE), + BE(f_Cycle, EDIF_TOK_CYCLE), + BE(f_DataOrigin, EDIF_TOK_DATAORIGIN), + BE(f_DcFanInLoad, EDIF_TOK_DCFANINLOAD), + BE(f_DcFanOutLoad, EDIF_TOK_DCFANOUTLOAD), + BE(f_DcMaxFanIn, EDIF_TOK_DCMAXFANIN), + BE(f_DcMaxFanOut, EDIF_TOK_DCMAXFANOUT), + BE(f_Delay, EDIF_TOK_DELAY), + BE(f_Delta, EDIF_TOK_DELTA), + BE(f_Design, EDIF_TOK_DESIGN), + BE(f_Designator, EDIF_TOK_DESIGNATOR), + BE(f_Difference, EDIF_TOK_DIFFERENCE), + BE(f_Display, EDIF_TOK_DISPLAY), + BE(f_Dominates, EDIF_TOK_DOMINATES), + BE(f_Dot, EDIF_TOK_DOT), + BE(f_Duration, EDIF_TOK_DURATION), + BE(f_EnclosureDistance, EDIF_TOK_ENCLOSUREDISTANCE), + BE(f_Entry, EDIF_TOK_ENTRY), + BE(f_Exactly, EDIF_TOK_EXACTLY), + BE(f_External, EDIF_TOK_EXTERNAL), + BE(f_Fabricate, EDIF_TOK_FABRICATE), + BE(f_Figure, EDIF_TOK_FIGURE), + BE(f_FigureArea, EDIF_TOK_FIGUREAREA), + BE(f_FigureGroup, EDIF_TOK_FIGUREGROUP), + BE(f_FigureGroupObject, EDIF_TOK_FIGUREGROUPOBJECT), + BE(f_FigureGroupOverride, EDIF_TOK_FIGUREGROUPOVERRIDE), + BE(f_FigureGroupRef, EDIF_TOK_FIGUREGROUPREF), + BE(f_FigurePerimeter, EDIF_TOK_FIGUREPERIMETER), + BE(f_FigureWidth, EDIF_TOK_FIGUREWIDTH), + BE(f_FillPattern, EDIF_TOK_FILLPATTERN), + BE(f_Follow, EDIF_TOK_FOLLOW), + BE(f_ForbiddenEvent, EDIF_TOK_FORBIDDENEVENT), + BE(f_GlobalPortRef, EDIF_TOK_GLOBALPORTREF), + BE(f_GreaterThan, EDIF_TOK_GREATERTHAN), + BE(f_GridMap, EDIF_TOK_GRIDMAP), + BE(f_IncludeFigureGroup, EDIF_TOK_INCLUDEFIGUREGROUP), + BE(f_Instance, EDIF_TOK_INSTANCE), + BE(f_InstanceBackAnnotate, EDIF_TOK_INSTANCEBACKANNOTATE), + BE(f_InstanceGroup, EDIF_TOK_INSTANCEGROUP), + BE(f_InstanceMap, EDIF_TOK_INSTANCEMAP), + BE(f_InstanceRef, EDIF_TOK_INSTANCEREF), + BE(f_Integer, EDIF_TOK_INTEGER), + BE(f_IntegerDisplay, EDIF_TOK_INTEGERDISPLAY), + BE(f_InterFigureGroupSpacing, EDIF_TOK_INTERFIGUREGROUPSPACING), + BE(f_Interface, EDIF_TOK_INTERFACE), + BE(f_Intersection, EDIF_TOK_INTERSECTION), + BE(f_IntraFigureGroupSpacing, EDIF_TOK_INTRAFIGUREGROUPSPACING), + BE(f_Inverse, EDIF_TOK_INVERSE), + BE(f_Joined, EDIF_TOK_JOINED), + BE(f_KeywordDisplay, EDIF_TOK_KEYWORDDISPLAY), + BE(f_KeywordMap, EDIF_TOK_KEYWORDMAP), + BE(f_LessThan, EDIF_TOK_LESSTHAN), + BE(f_Library, EDIF_TOK_LIBRARY), + BE(f_LibraryRef, EDIF_TOK_LIBRARYREF), + BE(f_ListOfNets, EDIF_TOK_LISTOFNETS), + BE(f_ListOfPorts, EDIF_TOK_LISTOFPORTS), + BE(f_LoadDelay, EDIF_TOK_LOADDELAY), + BE(f_LogicAssign, EDIF_TOK_LOGICASSIGN), + BE(f_LogicInput, EDIF_TOK_LOGICINPUT), + BE(f_LogicList, EDIF_TOK_LOGICLIST), + BE(f_LogicMapInput, EDIF_TOK_LOGICMAPINPUT), + BE(f_LogicMapOutput, EDIF_TOK_LOGICMAPOUTPUT), + BE(f_LogicOneOf, EDIF_TOK_LOGICONEOF), + BE(f_LogicOutput, EDIF_TOK_LOGICOUTPUT), + BE(f_LogicPort, EDIF_TOK_LOGICPORT), + BE(f_LogicRef, EDIF_TOK_LOGICREF), + BE(f_LogicValue, EDIF_TOK_LOGICVALUE), + BE(f_LogicWaveform, EDIF_TOK_LOGICWAVEFORM), + BE(f_Maintain, EDIF_TOK_MAINTAIN), + BE(f_Match, EDIF_TOK_MATCH), + BE(f_Member, EDIF_TOK_MEMBER), + BE(f_MiNoMax, EDIF_TOK_MINOMAX), + BE(f_MiNoMaxDisplay, EDIF_TOK_MINOMAXDISPLAY), + BE(f_Mnm, EDIF_TOK_MNM), + BE(f_MultipleValueSet, EDIF_TOK_MULTIPLEVALUESET), + BE(f_MustJoin, EDIF_TOK_MUSTJOIN), + BE(f_Name, EDIF_TOK_NAME), + BE(f_Net, EDIF_TOK_NET), + BE(f_NetBackAnnotate, EDIF_TOK_NETBACKANNOTATE), + BE(f_NetBundle, EDIF_TOK_NETBUNDLE), + BE(f_NetDelay, EDIF_TOK_NETDELAY), + BE(f_NetGroup, EDIF_TOK_NETGROUP), + BE(f_NetMap, EDIF_TOK_NETMAP), + BE(f_NetRef, EDIF_TOK_NETREF), + BE(f_NonPermutable, EDIF_TOK_NONPERMUTABLE), + BE(f_NotAllowed, EDIF_TOK_NOTALLOWED), + BE(f_NotchSpacing, EDIF_TOK_NOTCHSPACING), + BE(f_Number, EDIF_TOK_NUMBER), + BE(f_NumberDefinition, EDIF_TOK_NUMBERDEFINITION), + BE(f_NumberDisplay, EDIF_TOK_NUMBERDISPLAY), + BE(f_OffPageConnector, EDIF_TOK_OFFPAGECONNECTOR), + BE(f_OffsetEvent, EDIF_TOK_OFFSETEVENT), + BE(f_OpenShape, EDIF_TOK_OPENSHAPE), + BE(f_Origin, EDIF_TOK_ORIGIN), + BE(f_OverhangDistance, EDIF_TOK_OVERHANGDISTANCE), + BE(f_OverlapDistance, EDIF_TOK_OVERLAPDISTANCE), + BE(f_Oversize, EDIF_TOK_OVERSIZE), + BE(f_Page, EDIF_TOK_PAGE), + BE(f_PageSize, EDIF_TOK_PAGESIZE), + BE(f_Parameter, EDIF_TOK_PARAMETER), + BE(f_ParameterAssign, EDIF_TOK_PARAMETERASSIGN), + BE(f_ParameterDisplay, EDIF_TOK_PARAMETERDISPLAY), + BE(f_Path, EDIF_TOK_PATH), + BE(f_PathDelay, EDIF_TOK_PATHDELAY), + BE(f_Permutable, EDIF_TOK_PERMUTABLE), + BE(f_PhysicalDesignRule, EDIF_TOK_PHYSICALDESIGNRULE), + BE(f_Plug, EDIF_TOK_PLUG), + BE(f_Point, EDIF_TOK_POINT), + BE(f_PointDisplay, EDIF_TOK_POINTDISPLAY), + BE(f_PointList, EDIF_TOK_POINTLIST), + BE(f_Polygon, EDIF_TOK_POLYGON), + BE(f_Port, EDIF_TOK_PORT), + BE(f_PortBackAnnotate, EDIF_TOK_PORTBACKANNOTATE), + BE(f_PortBundle, EDIF_TOK_PORTBUNDLE), + BE(f_PortDelay, EDIF_TOK_PORTDELAY), + BE(f_PortGroup, EDIF_TOK_PORTGROUP), + BE(f_PortImplementation, EDIF_TOK_PORTIMPLEMENTATION), + BE(f_PortInstance, EDIF_TOK_PORTINSTANCE), + BE(f_PortList, EDIF_TOK_PORTLIST), + BE(f_PortListAlias, EDIF_TOK_PORTLISTALIAS), + BE(f_PortMap, EDIF_TOK_PORTMAP), + BE(f_PortRef, EDIF_TOK_PORTREF), + BE(f_Program, EDIF_TOK_PROGRAM), + BE(f_Property, EDIF_TOK_PROPERTY), + BE(f_PropertyDisplay, EDIF_TOK_PROPERTYDISPLAY), + BE(f_ProtectionFrame, EDIF_TOK_PROTECTIONFRAME), + BE(f_RangeVector, EDIF_TOK_RANGEVECTOR), + BE(f_Rectangle, EDIF_TOK_RECTANGLE), + BE(f_RectangleSize, EDIF_TOK_RECTANGLESIZE), + BE(f_Rename, EDIF_TOK_RENAME), + BE(f_Resolves, EDIF_TOK_RESOLVES), + BE(f_Scale, EDIF_TOK_SCALE), + BE(f_Section, EDIF_TOK_SECTION), + BE(f_Shape, EDIF_TOK_SHAPE), + BE(f_Simulate, EDIF_TOK_SIMULATE), + BE(f_SimulationInfo, EDIF_TOK_SIMULATIONINFO), + BE(f_SingleValueSet, EDIF_TOK_SINGLEVALUESET), + BE(f_Site, EDIF_TOK_SITE), + BE(f_Socket, EDIF_TOK_SOCKET), + BE(f_SocketSet, EDIF_TOK_SOCKETSET), + BE(f_Status, EDIF_TOK_STATUS), + BE(f_Steady, EDIF_TOK_STEADY), + BE(f_String, EDIF_TOK_STRING), + BE(f_StringDisplay, EDIF_TOK_STRINGDISPLAY), + BE(f_Strong, EDIF_TOK_STRONG), + BE(f_Symbol, EDIF_TOK_SYMBOL), + BE(f_Symmetry, EDIF_TOK_SYMMETRY), + BE(f_Table, EDIF_TOK_TABLE), + BE(f_TableDefault, EDIF_TOK_TABLEDEFAULT), + BE(f_Technology, EDIF_TOK_TECHNOLOGY), + BE(f_TimeInterval, EDIF_TOK_TIMEINTERVAL), + BE(f_Timing, EDIF_TOK_TIMING), + BE(f_Transform, EDIF_TOK_TRANSFORM), + BE(f_Transition, EDIF_TOK_TRANSITION), + BE(f_Trigger, EDIF_TOK_TRIGGER), + BE(f_Union, EDIF_TOK_UNION), + BE(f_View, EDIF_TOK_VIEW), + BE(f_ViewList, EDIF_TOK_VIEWLIST), + BE(f_ViewMap, EDIF_TOK_VIEWMAP), + BE(f_ViewRef, EDIF_TOK_VIEWREF), + BE(f_Visible, EDIF_TOK_VISIBLE), + BE(f_VoltageMap, EDIF_TOK_VOLTAGEMAP), + BE(f_WaveValue, EDIF_TOK_WAVEVALUE), + BE(f_Weak, EDIF_TOK_WEAK), + BE(f_WeakJoined, EDIF_TOK_WEAKJOINED), + BE(f_When, EDIF_TOK_WHEN), + BE(f_Written, EDIF_TOK_WRITTEN) +}; +static int BinderDefSize = sizeof(BinderDef) / sizeof(Binder); +/* + * Keyword table: + * + * This hash table holds all strings which may have to be matched + * to. WARNING: it is assumed that there is no overlap of the 'token' + * and 'context' strings. + */ +typedef struct Keyword { + struct Keyword *Next; /* pointer to next entry */ + const char *String; /* pointer to associated string */ +} Keyword; +#define KEYWORD_HASH 127 /* hash table size */ +static Keyword *KeywordTable[KEYWORD_HASH]; +/* + * Enter keyword: + * + * The passed string is entered into the keyword hash table. + */ +static void EnterKeyword(const char * str) +{ + /* + * Locals. + */ + register Keyword *key; + register unsigned int hsh; + register const char *cp; + /* + * Create the hash code, and add an entry to the table. + */ + for (hsh = 0, cp = str; *cp; hsh += hsh + *cp++); + hsh %= KEYWORD_HASH; + key = (Keyword *) Malloc(sizeof(Keyword)); + key->Next = KeywordTable[hsh]; + (KeywordTable[hsh] = key)->String = str; +} +/* + * Find keyword: + * + * The passed string is located within the keyword table. If an + * entry exists, then the value of the keyword string is returned. This + * is real useful for doing string comparisons by pointer value later. + * If there is no match, a NULL is returned. + */ +static const char *FindKeyword(const char * str) +{ + /* + * Locals. + */ + register Keyword *wlk,*owk; + register unsigned int hsh; + register char *cp; + char lower[IDENT_LENGTH + 1]; + /* + * Create a lower case copy of the string. + */ + for (cp = lower; *str;) + if (isupper( (int) *str)) + *cp++ = tolower( (int) *str++); + else + *cp++ = *str++; + *cp = '\0'; + /* + * Search the hash table for a match. + */ + for (hsh = 0, cp = lower; *cp; hsh += hsh + *cp++); + hsh %= KEYWORD_HASH; + for (owk = NULL, wlk = KeywordTable[hsh]; wlk; wlk = (owk = wlk)->Next) + if (!strcmp(wlk->String,lower)){ + /* + * Readjust the LRU. + */ + if (owk){ + owk->Next = wlk->Next; + wlk->Next = KeywordTable[hsh]; + KeywordTable[hsh] = wlk; + } + return (wlk->String); + } + return NULL; +} +/* + * Token hash table. + */ +#define TOKEN_HASH 51 +static Token *TokenHash[TOKEN_HASH]; +/* + * Find token: + * + * A pointer to the token of the passed code is returned. If + * no such beastie is present a NULL is returned instead. + */ +static Token *FindToken(register int cod) +{ + /* + * Locals. + */ + register Token *wlk,*owk; + register unsigned int hsh; + /* + * Search the hash table for a matching token. + */ + hsh = cod % TOKEN_HASH; + for (owk = NULL, wlk = TokenHash[hsh]; wlk; wlk = (owk = wlk)->Next) + if (cod == wlk->Code){ + if (owk){ + owk->Next = wlk->Next; + wlk->Next = TokenHash[hsh]; + TokenHash[hsh] = wlk; + } + break; + } + return wlk; +} +/* + * Context hash table. + */ +#define CONTEXT_HASH 127 +static Context *ContextHash[CONTEXT_HASH]; +/* + * Find context: + * + * A pointer to the context of the passed code is returned. If + * no such beastie is present a NULL is returned instead. + */ +static Context *FindContext(register int cod) +{ + /* + * Locals. + */ + register Context *wlk,*owk; + register unsigned int hsh; + /* + * Search the hash table for a matching context. + */ + hsh = cod % CONTEXT_HASH; + for (owk = NULL, wlk = ContextHash[hsh]; wlk; wlk = (owk = wlk)->Next) + if (cod == wlk->Code){ + if (owk){ + owk->Next = wlk->Next; + wlk->Next = ContextHash[hsh]; + ContextHash[hsh] = wlk; + } + break; + } + return wlk; +} +/* + * Token stacking variables. + */ +#ifdef DEBUG +#define TS_DEPTH 8 +#define TS_MASK (TS_DEPTH - 1) +static unsigned int TSP = 0; /* token stack pointer */ +static char *TokenStack[TS_DEPTH]; /* token name strings */ +static short TokenType[TS_DEPTH]; /* token types */ +/* + * Stack: + * + * Add a token to the debug stack. The passed string and type are + * what is to be pushed. + */ +static void Stack(char * str, int typ) +{ + /* + * Free any previous string, then push. + */ + if (TokenStack[TSP & TS_MASK]) + Free(TokenStack[TSP & TS_MASK]); + TokenStack[TSP & TS_MASK] = strcpy((char *)Malloc(strlen(str) + 1),str); + TokenType[TSP & TS_MASK] = typ; + TSP += 1; +} +/* + * Dump stack: + * + * This displays the last set of accumulated tokens. + */ +static void DumpStack() +{ + /* + * Locals. + */ + register int i; + register Context *cxt; + register Token *tok; + register char *nam; + FILE *Error = stderr; + /* + * Run through the list displaying the oldest first. + */ + fprintf(Error,"\n\n"); + for (i = 0; i < TS_DEPTH; i += 1) + if (TokenStack[(TSP + i) & TS_MASK]){ + /* + * Get the type name string. + */ + if ((cxt = FindContext(TokenType[(TSP + i) & TS_MASK])) != NULL) + nam = cxt->Name; + else if ((tok = FindToken(TokenType[(TSP + i) & TS_MASK])) != NULL) + nam = tok->Name; + else switch (TokenType[(TSP + i) & TS_MASK]){ + case EDIF_TOK_IDENT: nam = "IDENT"; break; + case EDIF_TOK_INT: nam = "INT"; break; + case EDIF_TOK_KEYWORD: nam = "KEYWORD"; break; + case EDIF_TOK_STR: nam = "STR"; break; + default: nam = "?"; break; + } + /* + * Now print the token state. + */ + fprintf(Error,"%2d %-16.16s '%s'\n",TS_DEPTH - i,nam, + TokenStack[(TSP + i) & TS_MASK]); + } + fprintf(Error,"\n"); +} +#else +#define Stack(s,t) +#endif /* DEBUG */ +/* + * Parser state variables. + */ +static FILE *Input = NULL; /* input stream */ +static FILE *Error = NULL; /* error stream */ +static char *InFile; /* file name on the input stream */ +static long LineNumber; /* current input line number */ +static ContextCar *CSP = NULL; /* top of context stack */ +static char yytext[IDENT_LENGTH + 1]; /* token buffer */ +static char CharBuf[IDENT_LENGTH + 1]; /* garbage buffer */ +/* + * yyerror: + * + * Standard error reporter, it prints out the passed string + * preceeded by the current filename and line number. + */ +static void yyerror(const char *ers) +{ +#ifdef DEBUG + DumpStack(); +#endif /* DEBUG */ + rnd_message(RND_MSG_ERROR, "EDIF import error: %s, line %ld: %s\n",InFile,LineNumber,ers); +} +/* + * String bucket definitions. + */ +#define BUCKET_SIZE 64 +typedef struct Bucket { + struct Bucket *Next; /* pointer to next bucket */ + int Index; /* pointer to next free slot */ + char Data[BUCKET_SIZE]; /* string data */ +} Bucket; +static Bucket *CurrentBucket = NULL; /* string bucket list */ +static int StringSize = 0; /* current string length */ +/* + * Push string: + * + * This adds the passed charater to the current string bucket. + */ +static void PushString(char chr) +{ + /* + * Locals. + */ + register Bucket *bck; + /* + * Make sure there is room for the push. + */ + if ((bck = CurrentBucket)->Index >= BUCKET_SIZE){ + bck = (Bucket *) Malloc(sizeof(Bucket)); + bck->Next = CurrentBucket; + (CurrentBucket = bck)->Index = 0; + } + /* + * Push the character. + */ + bck->Data[bck->Index++] = chr; + StringSize += 1; +} +/* + * Form string: + * + * This converts the current string bucket into a real live string, + * whose pointer is returned. + */ +static char *FormString() +{ + /* + * Locals. + */ + register Bucket *bck; + register char *cp; + /* + * Allocate space for the string, set the pointer at the end. + */ + cp = (char *) Malloc(StringSize + 1); + + cp += StringSize; + *cp-- = '\0'; + /* + * Yank characters out of the bucket. + */ + for (bck = CurrentBucket; bck->Index || bck->Next;){ + if (!bck->Index){ + CurrentBucket = bck->Next; + Free(bck); + bck = CurrentBucket; + } + *cp-- = bck->Data[--bck->Index]; + } + /* reset buffer size to zero */ + StringSize =0; + return (cp + 1); +} +/* + * Parse EDIF: + * + * This builds the context tree and then calls the real parser. + * It is passed two file streams, the first is where the input comes + * from; the second is where error messages get printed. + */ +void ParseEDIF(char* filename,FILE* err) +{ + /* + * Locals. + */ + register int i; + static int ContextDefined = 1; + /* + * Set up the file state to something useful. + */ + InFile = filename; + Input = rnd_fopen(&PCB->hidlib, filename, "r"); + Error = err; + LineNumber = 1; + /* + * Define both the enabled token and context strings. + */ + if (ContextDefined){ + for (i = TokenDefSize; i--; EnterKeyword(TokenDef[i].Name)){ + register unsigned int hsh; + hsh = TokenDef[i].Code % TOKEN_HASH; + TokenDef[i].Next = TokenHash[hsh]; + TokenHash[hsh] = &TokenDef[i]; + } + for (i = ContextDefSize; i--; EnterKeyword(ContextDef[i].Name)){ + register unsigned int hsh; + hsh = ContextDef[i].Code % CONTEXT_HASH; + ContextDef[i].Next = ContextHash[hsh]; + ContextHash[hsh] = &ContextDef[i]; + } + /* + * Build the context tree. + */ + for (i = BinderDefSize; i--;){ + register Context *cxt; + register int j; + /* + * Define the current context to have carriers bound to it. + */ + cxt = FindContext(BinderDef[i].Origin); + for (j = BinderDef[i].FollowerSize; j--;){ + register ContextCar *cc; + /* + * Add carriers to the current context. + */ + cc = (ContextCar *) Malloc(sizeof(ContextCar)); + cc->Next = cxt->Context; + (cxt->Context = cc)->Context = + FindContext(RND_ABS(BinderDef[i].Follower[j])); + cc->u.Single = BinderDef[i].Follower[j] < 0; + } + } + /* + * Build the token tree. + */ + for (i = TieDefSize; i--;){ + register Context *cxt; + register int j; + /* + * Define the current context to have carriers bound to it. + */ + cxt = FindContext(TieDef[i].Origin); + for (j = TieDef[i].EnableSize; j--;){ + register TokenCar *tc; + /* + * Add carriers to the current context. + */ + tc = (TokenCar *) Malloc(sizeof(TokenCar)); + tc->Next = cxt->Token; + (cxt->Token = tc)->Token = FindToken(TieDef[i].Enable[j]); + } + } + /* + * Put a bogus context on the stack which has 'EDIF' as its + * follower. + */ + CSP = (ContextCar *) Malloc(sizeof(ContextCar)); + CSP->Next = NULL; + CSP->Context = FindContext(0); + CSP->u.Used = NULL; + ContextDefined = 0; + } + /* + * Create an initial, empty string bucket. + */ + CurrentBucket = (Bucket *) Malloc(sizeof(Bucket)); + CurrentBucket->Next = 0; + CurrentBucket->Index = 0; + /* + * Fill the token stack with NULLs if debugging is enabled. + */ +#ifdef DEBUG + for (i = TS_DEPTH; i--; TokenStack[i] = NULL) + if (TokenStack[i]) + Free(TokenStack[i]); + TSP = 0; +#endif /* DEBUG */ + /* + * Go parse things! + */ + edifparse(); +} +/* + * Match token: + * + * The passed string is looked up in the current context's token + * list to see if it is enabled. If so the token value is returned, + * if not then zero. + */ +static int MatchToken(register const char * str) +{ + /* + * Locals. + */ + register TokenCar *wlk,*owk; + /* + * Convert the string to the proper form, then search the token + * carrier list for a match. + */ + str = FindKeyword(str); + for (owk = NULL, wlk = CSP->Context->Token; wlk; wlk = (owk = wlk)->Next) + if (str == wlk->Token->Name){ + if (owk){ + owk->Next = wlk->Next; + wlk->Next = CSP->Context->Token; + CSP->Context->Token = wlk; + } + return (wlk->Token->Code); + } + return 0; +} +/* + * Match context: + * + * If the passed keyword string is within the current context, the + * new context is pushed and token value is returned. A zero otherwise. + */ +static int MatchContext(register const char * str) +{ + /* + * Locals. + */ + register ContextCar *wlk,*owk; + /* + * See if the context is present. + */ + str = FindKeyword(str); + for (owk = NULL, wlk = CSP->Context->Context; wlk; wlk = (owk = wlk)->Next) + if (str == wlk->Context->Name){ + if (owk){ + owk->Next = wlk->Next; + wlk->Next = CSP->Context->Context; + CSP->Context->Context = wlk; + } + /* + * If a single context, make sure it isn't already used. + */ + if (wlk->u.Single){ + register UsedCar *usc; + for (usc = CSP->u.Used; usc; usc = usc->Next) + if (usc->Code == wlk->Context->Code) + break; + if (usc){ + sprintf(CharBuf,"'%s' is used more than once within '%s'", + str,CSP->Context->Name); + yyerror(CharBuf); + } else { + usc = (UsedCar *) Malloc(sizeof(UsedCar)); + usc->Next = CSP->u.Used; + (CSP->u.Used = usc)->Code = wlk->Context->Code; + } + } + /* + * Push the new context. + */ + owk = (ContextCar *) Malloc(sizeof(ContextCar)); + owk->Next = CSP; + (CSP = owk)->Context = wlk->Context; + owk->u.Used = NULL; + return (wlk->Context->Code); + } + return 0; +} +/* + * PopC: + * + * This pops the current context. + */ +static void PopC() +{ + /* + * Locals. + */ + register UsedCar *usc; + register ContextCar *csp; + /* + * Release single markers and pop context. + */ + while ( (usc = CSP->u.Used) ){ + CSP->u.Used = usc->Next; + Free(usc); + } + csp = CSP->Next; + Free(CSP); + CSP = csp; +} +/* + * Lexical analyzer states. + */ +#define L_START 0 +#define L_INT 1 +#define L_IDENT 2 +#define L_KEYWORD 3 +#define L_STRING 4 +#define L_KEYWORD2 5 +#define L_ASCIICHAR 6 +#define L_ASCIICHAR2 7 +/* + * yylex: + * + * This is the lexical analyzer called by the YACC/BISON parser. + * It returns a pretty restricted set of token types and does the + * context movement when acceptable keywords are found. The token + * value returned is a NULL terminated string to allocated storage + * (ie - it should get released some time) with some restrictions. + * The token value for integers is strips a leading '+' if present. + * String token values have the leading and trailing '"'-s stripped. + * '%' conversion characters in string values are passed converted. + * The '(' and ')' characters do not have a token value. + */ +static int yylex() +{ + /* + * Locals. + */ + register int c,s,l; + /* + * Keep on sucking up characters until we find something which + * explicitly forces us out of this function. + */ + for (s = L_START, l = 0; 1;){ + yytext[l++] = c = Getc(Input); + switch (s){ + /* + * Starting state, look for something resembling a token. + */ + case L_START: + if (isdigit(c) || c == '-') + s = L_INT; + else if (isalpha(c) || c == '&') + s = L_IDENT; + else if (isspace(c)){ + if (c == '\n') + LineNumber += 1; + l = 0; + } else if (c == '('){ + l = 0; + s = L_KEYWORD; + } else if (c == '"') + s = L_STRING; + else if (c == '+'){ + l = 0; /* strip '+' */ + s = L_INT; + } else if (c == EOF) + return ('\0'); + else { + yytext[1] = '\0'; + Stack(yytext,c); + return c; + } + break; + /* + * Suck up the integer digits. + */ + case L_INT: + if (isdigit(c)) + break; + Ungetc(c); + yytext[--l] = '\0'; + yylval.s = strcpy((char *)Malloc(l + 1),yytext); + Stack(yytext,EDIF_TOK_INT); + return EDIF_TOK_INT; + /* + * Grab an identifier, see if the current context enables + * it with a specific token value. + */ + case L_IDENT: + if (isalpha(c) || isdigit(c) || c == '_') + break; + Ungetc(c); + yytext[--l] = '\0'; + if (CSP->Context->Token && (c = MatchToken(yytext))){ + Stack(yytext,c); + return c; + } + yylval.s = strcpy((char *)Malloc(l + 1),yytext); + Stack(yytext, EDIF_TOK_IDENT); + return EDIF_TOK_IDENT; + /* + * Scan until you find the start of an identifier, discard + * any whitespace found. On no identifier, return a '('. + */ + case L_KEYWORD: + if (isalpha(c) || c == '&'){ + s = L_KEYWORD2; + break; + } else if (isspace(c)){ + l = 0; + break; + } + Ungetc(c); + Stack("(",'('); + return ('('); + /* + * Suck up the keyword identifier, if it matches the set of + * allowable contexts then return its token value and push + * the context, otherwise just return the identifier string. + */ + case L_KEYWORD2: + if (isalpha(c) || isdigit(c) || c == '_') + break; + Ungetc(c); + yytext[--l] = '\0'; + if ( (c = MatchContext(yytext)) ){ + Stack(yytext,c); + return c; + } + yylval.s = strcpy((char *)Malloc(l + 1),yytext); + Stack(yytext, EDIF_TOK_KEYWORD); + return EDIF_TOK_KEYWORD; + /* + * Suck up string characters but once resolved they should + * be deposited in the string bucket because they can be + * arbitrarily long. + */ + case L_STRING: + if (c == '\n') + LineNumber += 1; + else if (c == '\r') + ; + else if (c == '"' || c == EOF){ + yylval.s = FormString(); + Stack(yylval.s, EDIF_TOK_STR); + return EDIF_TOK_STR; + } else if (c == '%') + s = L_ASCIICHAR; + else + PushString(c); + l = 0; + break; + /* + * Skip white space and look for integers to be pushed + * as characters. + */ + case L_ASCIICHAR: + if (isdigit(c)){ + s = L_ASCIICHAR2; + break; + } else if (c == '%' || c == EOF) + s = L_STRING; + else if (c == '\n') + LineNumber += 1; + l = 0; + break; + /* + * Convert the accumulated integer into a char and push. + */ + case L_ASCIICHAR2: + if (isdigit(c)) + break; + Ungetc(c); + yytext[--l] = '\0'; + PushString(atoi(yytext)); + s = L_ASCIICHAR; + l = 0; + break; + } + } +} + +int ReadEdifNetlist(char *filename) +{ + rnd_message(RND_MSG_INFO,"Importing edif netlist %s\n", filename); + ParseEDIF(filename, NULL); + + return 0; +} Index: tags/2.3.0/src_plugins/import_edif/edif_parse.h =================================================================== --- tags/2.3.0/src_plugins/import_edif/edif_parse.h (nonexistent) +++ tags/2.3.0/src_plugins/import_edif/edif_parse.h (revision 33253) @@ -0,0 +1,33 @@ +/* + * COPYRIGHT + * + * Copyright (C) 2006 Jeffry C Bailey + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + + +#ifndef PCB_EDIF_PARSE_H +#define PCB_EDIF_PARSE_H + +void ParseEDIF(char *filename, FILE * err); + + +#endif /* PCB_EDIF_PARSE_H */ Index: tags/2.3.0/src_plugins/import_edif/import_edif.c =================================================================== --- tags/2.3.0/src_plugins/import_edif/import_edif.c (nonexistent) +++ tags/2.3.0/src_plugins/import_edif/import_edif.c (revision 33253) @@ -0,0 +1,117 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2020 Tibor 'Igor2' Palinkas + * + * This module, io_kicad_legacy, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "board.h" +#include "data.h" +#include +#include +#include "plug_import.h" +#include "rats_patch.h" + +/* for pcb_sort_library only */ +#include "plug_io.h" + + +static pcb_plug_import_t import_edif; + +int edif_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + char buf[65]; + int len; + char *p; + FILE *fp; + + if (aspects != IMPORT_ASPECT_NETLIST) + return 0; /* only pure netlist import is supported */ + + fp = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (fp == NULL) + return 0; /* only importing from a file is supported */ + + /* If the header contains "edif", it is supported */ + len = fread(buf, 1, sizeof(buf) - 1, fp); + buf[len] = '\0'; + for(p = buf; *p != '\0'; p++) + *p = tolower((int) *p); + if (strstr(buf, "edif") != NULL) { + fclose(fp); + return 100; + } + + fclose(fp); + /* Else don't even attempt to load it */ + return 0; +} + + +extern int ReadEdifNetlist(char *filename); +static int edif_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + int ret; + + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_edif: requires exactly 1 input file name\n"); + return -1; + } + + ret = ReadEdifNetlist((char *)fns[0]); + if (ret == 0) + pcb_ratspatch_make_edited(PCB); + return ret; +} + +int pplg_check_ver_import_edif(int ver_needed) { return 0; } + +void pplg_uninit_import_edif(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_edif); +} + +int pplg_init_import_edif(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_edif.plugin_data = NULL; + + import_edif.fmt_support_prio = edif_support_prio; + import_edif.import = edif_import; + import_edif.name = "edif"; + import_edif.desc = "EDIF netlist (flat)"; + import_edif.ui_prio = 50; + import_edif.single_arg = 1; + import_edif.all_filenames = 1; + import_edif.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_edif); + + return 0; +} + Index: tags/2.3.0/src_plugins/import_edif/import_edif.pup =================================================================== --- tags/2.3.0/src_plugins/import_edif/import_edif.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_edif/import_edif.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import edif +$long Import plugin for netlists in the EDIF format. +$state works +$fmt-native no +$fmt-feature-r flat netlist from EDIF +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_fpcb_nl/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_fpcb_nl/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_fpcb_nl/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_fpcb_nl + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_fpcb_nl/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_fpcb_nl/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_fpcb_nl/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {import_fpcb_nl} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_fpcb_nl/fpcb_nl.o @] +put /local/pcb/mod/MENUFILE {fpcb_nl-menu.lht} +put /local/pcb/mod/MENUVAR {fpcb_nl_menu} + +switch /local/pcb/import_fpcb_nl/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_fpcb_nl/fpcb_nl-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_fpcb_nl/fpcb_nl-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_fpcb_nl/fpcb_nl-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Load FreePCB netlist (EasyEDA) = { action=LoadFpcbnlFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/import_fpcb_nl/fpcb_nl.c =================================================================== --- tags/2.3.0/src_plugins/import_fpcb_nl/fpcb_nl.c (nonexistent) +++ tags/2.3.0/src_plugins/import_fpcb_nl/fpcb_nl.c (revision 33253) @@ -0,0 +1,274 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * Freepcb netlist import + * pcb-rnd Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "plug_import.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "menu_internal.c" + +static const char *fpcb_nl_cookie = "fpcb_nl importer"; + +/* remove leading whitespace */ +#define ltrim(s) while(isspace(*s)) s++ + +/* remove trailing newline */ +#define rtrim(s) \ + do { \ + char *end; \ + for(end = s + strlen(s) - 1; (end >= s) && ((*end == '\r') || (*end == '\n')); end--) \ + *end = '\0'; \ + } while(0) + +static int fpcb_nl_load(const char *fn) +{ + FILE *f; + char *line, *curr, *next, *fp, *tn, buff[8192], signame[512]; + enum { MODE_NONE, MODE_PART, MODE_NET, MODE_SIGNAL } mode = MODE_NONE; + int anon = 0; + + f = rnd_fopen(&PCB->hidlib, fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can't open %s for read\n", fn); + return -1; + } + + rnd_actionva(&PCB->hidlib, "ElementList", "start", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + + while((line = fgets(buff, sizeof(buff), f)) != NULL) { + rtrim(line); + + /* parse directive */ + if (*line == '*') { + if (rnd_strcasecmp(line, "*END*") == 0) + break; + else if (rnd_strcasecmp(line, "*PART*") == 0) + mode = MODE_PART; + else if (rnd_strcasecmp(line, "*NET*") == 0) + mode = MODE_NET; + else if (rnd_strncasecmp(line, "*SIGNAL*", 8) == 0) { + *signame = '\0'; + if ((mode == MODE_NET) || (mode == MODE_SIGNAL)) { + int len; + mode = MODE_SIGNAL; + line += 9; + ltrim(line); + len = strlen(line); + if (len == 0) { + rnd_message(RND_MSG_ERROR, "Empty/missing net name in *SINGAL*\n"); + sprintf(signame, "pcbrndanonymous%d", anon++); + } + else { + if (len > sizeof(signame)-1) { + len = sizeof(signame)-1; + rnd_message(RND_MSG_ERROR, "Net name %s is too long, truncating.\nThis may result in broken netlist, please use shorter names \n", line); + } + memcpy(signame, line, len); + signame[len] = '\0'; + } + } + else + mode = MODE_NONE; + } + continue; + } + + switch(mode) { + case MODE_PART: + if (*line == '\0') + continue; + fp = strpbrk(line, " \t"); + if (fp != NULL) { + *fp = '\0'; + fp++; + ltrim(fp); + } + if ((fp != NULL) && (*fp != '\0')) { + rnd_actionva(&PCB->hidlib, "ElementList", "Need", line, fp, "", NULL); + } + else + rnd_message(RND_MSG_ERROR, "No footprint specified for %s\n", line); + break; + case MODE_SIGNAL: + ltrim(line); + for(curr = line; curr != NULL; curr = next) { + next = strpbrk(curr, " \t"); + if (next != NULL) { + *next = '\0'; + next++; + ltrim(next); + } + if (*curr == '\0') + continue; + tn = strchr(curr, '.'); + if (tn == NULL) { + rnd_message(RND_MSG_ERROR, "Syntax error in netlist: '%s' in net '%s' should be refdes.termid\n", curr, signame); + continue; + } + *tn = '-'; + rnd_actionva(&PCB->hidlib, "Netlist", "Add", signame, curr, NULL); + } + break; + default: break; /* ignore line */ + } + } + + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + rnd_actionva(&PCB->hidlib, "ElementList", "Done", NULL); + + fclose(f); + return 0; +} + +static const char pcb_acts_LoadFpcbnlFrom[] = "LoadFpcbnlFrom(filename)"; +static const char pcb_acth_LoadFpcbnlFrom[] = "Loads the specified freepcb netlist."; +fgw_error_t pcb_act_LoadFpcbnlFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + static char *default_file = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadFpcbnlFrom, fname = argv[1].val.str); + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, + "Load freepcb netlist...", "Picks a freepcb netlist file to load.\n", + default_file, ".net", NULL, "freepcb", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 1; + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + pcb_undo_freeze_serial(); + RND_ACT_IRES(fpcb_nl_load(fname)); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + return 0; +} + +static int fpcb_nl_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + FILE *f; + int n; + + if ((aspects != IMPORT_ASPECT_NETLIST) || (numargs != 1)) + return 0; /* only pure netlist import is supported */ + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + for(n = 0; n < 32; n++) { + char line[1024]; + fgets(line, sizeof(line), f); + if (strncmp(line, "*PADS-PCB*", 10) == 0) { + fclose(f); + return 100; + } + } + + fclose(f); + return 0; +} + + +static int fpcb_nl_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + int ret; + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_fpcb_nl: requires exactly 1 input file name\n"); + return -1; + } + + pcb_undo_freeze_serial(); + ret = fpcb_nl_load(fns[0]); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + return ret; +} + +static pcb_plug_import_t import_fpcb_nl; + +rnd_action_t fpcb_nl_action_list[] = { + {"LoadFpcbnlFrom", pcb_act_LoadFpcbnlFrom, pcb_acth_LoadFpcbnlFrom, pcb_acts_LoadFpcbnlFrom} +}; + +int pplg_check_ver_import_fpcb_nl(int ver_needed) { return 0; } + +void pplg_uninit_import_fpcb_nl(void) +{ + rnd_remove_actions_by_cookie(fpcb_nl_cookie); + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_fpcb_nl); + rnd_hid_menu_unload(rnd_gui, fpcb_nl_cookie); +} + +int pplg_init_import_fpcb_nl(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_fpcb_nl.plugin_data = NULL; + + import_fpcb_nl.fmt_support_prio = fpcb_nl_support_prio; + import_fpcb_nl.import = fpcb_nl_import; + import_fpcb_nl.name = "FreePCB"; + import_fpcb_nl.desc = "FreePCB/EasyEDA schematics"; + import_fpcb_nl.ui_prio = 50; + import_fpcb_nl.single_arg = 1; + import_fpcb_nl.all_filenames = 1; + import_fpcb_nl.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_fpcb_nl); + + + RND_REGISTER_ACTIONS(fpcb_nl_action_list, fpcb_nl_cookie) + rnd_hid_menu_load(rnd_gui, NULL, fpcb_nl_cookie, 165, NULL, 0, fpcb_nl_menu, "plugin: fpcb_nl import"); + return 0; +} Index: tags/2.3.0/src_plugins/import_fpcb_nl/import_fpcb_nl.pup =================================================================== --- tags/2.3.0/src_plugins/import_fpcb_nl/import_fpcb_nl.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_fpcb_nl/import_fpcb_nl.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import freepcb netlist +$long Import the netlist and footprints from freepcb format (exported by e.g. easyeda) +$state works +$fmt-native no +$fmt-feature-r freepcb netlist + footprint info +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_gnetlist/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_gnetlist/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_gnetlist/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_import_gnetlist + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/import_gnetlist/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_gnetlist/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_gnetlist/Plug.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +put /local/pcb/mod {import_gnetlist} +append /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_gnetlist/import_gnetlist.o @] +put /local/pcb/mod/CONF {$(PLUGDIR)/import_gnetlist/import_gnetlist_conf.h} +put /local/pcb/mod/CONFFILE {import_gnetlist.conf} +put /local/pcb/mod/CONFVAR {import_gnetlist_conf_internal} + + +switch /local/pcb/import_gnetlist/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist.c =================================================================== --- tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist.c (nonexistent) +++ tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist.c (revision 33253) @@ -0,0 +1,173 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +/* for win32 paths: */ +#include + +#include "board.h" +#include "undo.h" +#include "plug_import.h" + +#include "import_gnetlist_conf.h" +#include "../src_plugins/import_gnetlist/conf_internal.c" + +#define IMPORT_GNETLIST_CONF_FN "import_gnetlist.conf" + +conf_import_gnetlist_t conf_import_gnetlist; + +static pcb_plug_import_t import_gnetlist; + + +int gnetlist_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + FILE *f; + char line[128], *s; + int spc = 0; + + if ((aspects != IMPORT_ASPECT_NETLIST) || (numargs < 1)) + return 0; /* only pure netlist import is supported, only if there are files */ + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + line[0] = '\0'; + fgets(line, sizeof(line), f); + fclose(f); + + /* must start with "v ", followed by digits and one space */ + if ((line[0] != 'v') || (line[1] != ' ')) + return 0; + for(s = line+2; *s != '\0'; s++) { + if ((*s == '\r') || (*s == '\n')) break; + else if (*s == ' ') spc++; + else if (!isdigit(*s)) + return 0; + } + if (spc != 1) + return 0; + + return 100; +} + +static int gnetlist_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + char **cmd; + int n, res, verbose; + fgw_arg_t rs; + char *tmpfn = rnd_tempfile_name_new("gnetlist_output"); + + PCB_IMPORT_SCH_VERBOSE(verbose); + + if (tmpfn == NULL) { + rnd_message(RND_MSG_ERROR, "Could not create temp file for gnetlist output"); + return -1; + } + + + cmd = malloc((numfns+9) * sizeof(char *)); + cmd[0] = (char *)conf_import_gnetlist.plugins.import_gnetlist.gnetlist_program; /* won't be free'd */ + cmd[1] = "-L"; + cmd[2] = PCBLIBDIR; + cmd[3] = "-g"; + cmd[4] = "pcbrndfwd"; + cmd[5] = "-o"; + cmd[6] = tmpfn; + cmd[7] = "--"; + for(n = 0; n < numfns; n++) + cmd[n+8] = rnd_build_fn(&PCB->hidlib, fns[n]); + cmd[numfns+8] = NULL; + + if (verbose) { + rnd_message(RND_MSG_DEBUG, "import_gnetlist: running gnetlist:\n"); + for(n = 0; n < numfns+8; n++) + rnd_message(RND_MSG_DEBUG, " %s", cmd[n]); + rnd_message(RND_MSG_DEBUG, "\n"); + } + + res = rnd_spawnvp((const char **)cmd); + if (res == 0) { + if (verbose) + rnd_message(RND_MSG_DEBUG, "pcb_gnetlist: about to run pcb_act_ExecuteFile, file = %s\n", tmpfn); + pcb_undo_freeze_serial(); + fgw_uvcall(&rnd_fgw, &PCB->hidlib, &rs, "executefile", FGW_STR, tmpfn, 0); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + } + for(n = 0; n < numfns; n++) + free(cmd[n+8]); + rnd_unlink(&PCB->hidlib, tmpfn); + free(cmd); + return res; +} + +int pplg_check_ver_import_gnetlist(int ver_needed) { return 0; } + +void pplg_uninit_import_gnetlist(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_gnetlist); + rnd_conf_unreg_file(IMPORT_GNETLIST_CONF_FN, import_gnetlist_conf_internal); + rnd_conf_unreg_fields("plugins/import_gnetlist/"); +} + +int pplg_init_import_gnetlist(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_gnetlist.plugin_data = NULL; + + import_gnetlist.fmt_support_prio = gnetlist_support_prio; + import_gnetlist.import = gnetlist_import; + import_gnetlist.name = "gnetlist"; + import_gnetlist.desc = "gEDA sch using gnetlist"; + import_gnetlist.ui_prio = 50; + import_gnetlist.single_arg = 0; + import_gnetlist.all_filenames = 1; + import_gnetlist.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_gnetlist); + + rnd_conf_reg_file(IMPORT_GNETLIST_CONF_FN, import_gnetlist_conf_internal); + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_import_gnetlist, field,isarray,type_name,cpath,cname,desc,flags); +#include "import_gnetlist_conf_fields.h" + + return 0; +} + Index: tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist.conf =================================================================== --- tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist.conf (nonexistent) +++ tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist.conf (revision 33253) @@ -0,0 +1,9 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:import_gnetlist { + gnetlist_program=gnetlist + } + } + } +} Index: tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist.pup =================================================================== --- tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short sch import: run gnetlist +$long Import gEDA/gschem schematics running gnetlist +$state works +$fmt-native no +$fmt-feature-r gEDA/gschem (netlist + footpritn info, running gnetlist) +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist_conf.h =================================================================== --- tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/import_gnetlist/import_gnetlist_conf.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_IMPORT_GNETLIST_CONF_H +#define PCB_IMPORT_GNETLIST_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_STRING gnetlist_program; /* gnetlist program name */ + } import_gnetlist; + } plugins; +} conf_import_gnetlist_t; + +#endif Index: tags/2.3.0/src_plugins/import_hpgl/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_hpgl/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_hpgl/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_hpgl + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_hpgl/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_hpgl/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_hpgl/Plug.tmpasm (revision 33253) @@ -0,0 +1,13 @@ +put /local/pcb/mod {import_hpgl} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/import_hpgl/hpgl.o + $(SRC_3RD_DIR)/libuhpgl/parse.o +@] +put /local/pcb/mod/MENUFILE {hpgl-menu.lht} +put /local/pcb/mod/MENUVAR {hpgl_menu} + +switch /local/pcb/import_hpgl/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_hpgl/hpgl-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_hpgl/hpgl-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_hpgl/hpgl-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_geo { + li:submenu { + ha:Load HP-GL plot to paste-buffer = { action=LoadHPGLFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/import_hpgl/hpgl.c =================================================================== --- tags/2.3.0/src_plugins/import_hpgl/hpgl.c (nonexistent) +++ tags/2.3.0/src_plugins/import_hpgl/hpgl.c (revision 33253) @@ -0,0 +1,194 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * HP-GL import HID + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "board.h" +#include "conf_core.h" +#include "data.h" +#include "buffer.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "menu_internal.c" + +static const char *hpgl_cookie = "hpgl importer"; + +#define HPGL2CRD_D(crd) (RND_MM_TO_COORD((double)crd*0.025)) +#define HPGL2CRD_X(crd) (RND_MM_TO_COORD((double)crd*0.025)) +#define HPGL2CRD_Y(crd) (RND_MM_TO_COORD((double)crd*(-0.025))) + +static pcb_layer_t *get_pen_layer(pcb_data_t *data, int pen) +{ + int n, old_len; + pen = pen % PCB_MAX_LAYER; + + if (pen >= data->LayerN) { + old_len = data->LayerN; + data->LayerN = pen+1; +/* data->Layer = realloc(data->Layer, sizeof(pcb_layer_t) * data->LayerN);*/ + for(n = old_len; n < data->LayerN; n++) { + memset(&data->Layer[n], 0, sizeof(pcb_layer_t)); + pcb_layer_real2bound(&data->Layer[n], &PCB->Data->Layer[n], 0); + free((char *)data->Layer[n].name); + data->Layer[n].name = rnd_strdup_printf("hpgl_pen_%d", n); + data->Layer[n].parent.data = data; + data->Layer[n].parent_type = PCB_PARENT_DATA; + data->Layer[n].type = PCB_OBJ_LAYER; + } + } + + return &data->Layer[pen]; +} + +static int load_line(uhpgl_ctx_t *ctx, uhpgl_line_t *line) +{ + pcb_data_t *data = (pcb_data_t *)ctx->user_data; + pcb_layer_t *layer = get_pen_layer(data, line->pen); + pcb_line_new(layer, + HPGL2CRD_X(line->p1.x), HPGL2CRD_Y(line->p1.y), HPGL2CRD_X(line->p2.x), HPGL2CRD_Y(line->p2.y), + conf_core.design.line_thickness, 2 * conf_core.design.clearance, + pcb_flag_make((conf_core.editor.clear_line ? PCB_FLAG_CLEARLINE : 0))); + return 0; +} + +static int load_arc(uhpgl_ctx_t *ctx, uhpgl_arc_t *arc) +{ + pcb_data_t *data = (pcb_data_t *)ctx->user_data; + pcb_layer_t *layer = get_pen_layer(data, arc->pen); + + pcb_arc_new(layer, + HPGL2CRD_X(arc->center.x), HPGL2CRD_Y(arc->center.y), + HPGL2CRD_D(arc->r), HPGL2CRD_D(arc->r), + arc->starta+180, arc->deltaa, + conf_core.design.line_thickness, 2 * conf_core.design.clearance, + pcb_flag_make((conf_core.editor.clear_line ? PCB_FLAG_CLEARLINE : 0)), rnd_true); + + return 0; +} + +static int load_poly(uhpgl_ctx_t *ctx, uhpgl_poly_t *poly) +{ +/* pcb_data_t *data = (pcb_data_t *)ctx->user_data;*/ + rnd_message(RND_MSG_ERROR, "HPGL: polygons are not yet supported\n"); + return 0; +} + +static int hpgl_load(const char *fname) +{ + FILE *f; + uhpgl_ctx_t ctx; + + memset(&ctx, 0, sizeof(ctx)); + + ctx.conf.line = load_line; + ctx.conf.arc = load_arc; + ctx.conf.poly = load_poly; + + f = rnd_fopen(&PCB->hidlib, fname, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Error opening HP-GL %s for read\n", fname); + return 1; + } + + pcb_buffer_clear(PCB, PCB_PASTEBUFFER); + ctx.user_data = PCB_PASTEBUFFER->Data; + PCB_PASTEBUFFER->Data->LayerN = 0; + + if ((uhpgl_parse_open(&ctx) == 0) && (uhpgl_parse_file(&ctx, f) == 0) && (uhpgl_parse_close(&ctx) == 0)) { + fclose(f); + if (PCB_PASTEBUFFER->Data->LayerN == 0) { + rnd_message(RND_MSG_ERROR, "Error loading HP-GL: could not load any object from %s\n", fname); + return 0; + } + rnd_actionva(&PCB->hidlib, "mode", "buffer", NULL); + return 0; + } + + fclose(f); + rnd_message(RND_MSG_ERROR, "Error loading HP-GL at %s:%d.%d: %s\n", fname, ctx.error.line, ctx.error.col, ctx.error.msg); + + return 1; +} + +static const char pcb_acts_LoadHpglFrom[] = "LoadHpglFrom(filename)"; +static const char pcb_acth_LoadHpglFrom[] = "Loads the specified hpgl plot file to the current buffer"; +fgw_error_t pcb_act_LoadHpglFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + static char *default_file = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadHpglFrom, fname = argv[1].val.str); + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Load HP-GL file...", + "Picks a HP-GL plot file to load.\n", + default_file, ".hpgl", NULL, "hpgl", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 0; /* cancel */ + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + RND_ACT_IRES(0); + return hpgl_load(fname); +} + +rnd_action_t hpgl_action_list[] = { + {"LoadHpglFrom", pcb_act_LoadHpglFrom, pcb_acth_LoadHpglFrom, pcb_acts_LoadHpglFrom} +}; + +int pplg_check_ver_import_hpgl(int ver_needed) { return 0; } + +void pplg_uninit_import_hpgl(void) +{ + rnd_remove_actions_by_cookie(hpgl_cookie); + rnd_hid_menu_unload(rnd_gui, hpgl_cookie); +} + +int pplg_init_import_hpgl(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(hpgl_action_list, hpgl_cookie) + rnd_hid_menu_load(rnd_gui, NULL, hpgl_cookie, 135, NULL, 0, hpgl_menu, "plugin: import_hpgl"); + return 0; +} Index: tags/2.3.0/src_plugins/import_hpgl/import_hpgl.pup =================================================================== --- tags/2.3.0/src_plugins/import_hpgl/import_hpgl.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_hpgl/import_hpgl.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import HP-GL plot files +$long Emulate a plotter and import the plot as lines, arcs and polygons. +$state works +$fmt-native no +$fmt-feature-r HPGL plot (lines, arcs, polygons) +$package import-geo +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_ipcd356/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_ipcd356/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_ipcd356/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_ipcd356 + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_ipcd356/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_ipcd356/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_ipcd356/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {import_ipcd356} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_ipcd356/ipcd356.o @] +put /local/pcb/mod/MENUFILE {ipcd356-menu.lht} +put /local/pcb/mod/MENUVAR {ipcd356_menu} + +switch /local/pcb/import_ipcd356/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_ipcd356/import_ipcd356.pup =================================================================== --- tags/2.3.0/src_plugins/import_ipcd356/import_ipcd356.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_ipcd356/import_ipcd356.pup (revision 33253) @@ -0,0 +1,10 @@ +$class import +$short import IPC-D-356 Netlist +$long IPC-D-356 Netlist and pad centroid import +$state works +$fmt-native no +$fmt-feature-w IPC-D-356 Netlist (from automated testing) +$package import-net +dep lib_compat_help +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_ipcd356/ipcd356-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_ipcd356/ipcd356-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_ipcd356/ipcd356-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Load IPC-D-356 netlist = { action=LoadIpc356From() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/import_ipcd356/ipcd356.c =================================================================== --- tags/2.3.0/src_plugins/import_ipcd356/ipcd356.c (nonexistent) +++ tags/2.3.0/src_plugins/import_ipcd356/ipcd356.c (revision 33253) @@ -0,0 +1,528 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * ipc-d-356 import plugin + * pcb-rnd Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include "board.h" +#include "data.h" +#include "undo.h" +#include + +#include "conf_core.h" +#include +#include +#include +#include +#include +#include + +#include "../src_plugins/lib_compat_help/pstk_help.h" + +#include "plug_import.h" + +#include "menu_internal.c" + +static const char *ipcd356_cookie = "ipcd356 importer"; + +static void set_src(pcb_attribute_list_t *a, const char *fn, long lineno) +{ + char src[8192]; + rnd_snprintf(src, sizeof(src), "ipcd356::%s:%ld", fn, lineno); + pcb_attribute_put(a, "source", src); +} + +static int netname_valid(const char *netname) +{ + if (*netname == '\0') return 0; + if (strcmp(netname, "N/C") == 0) return 0; + return 1; +} + +static void extract_field(char *dst, const char *line, int start, int end) +{ + int n; + line += start; + for(n = end-start; n >= 0; n--) { + if (*line == ' ') + break; + *dst++ = *line++; + } + *dst = '\0'; +} + +static int extract_dim(rnd_coord_t *dst, const char *line, int start, int end, int has_sign, int is_mil) +{ + char tmp[16]; + const char *sign = line + start; + double d; + rnd_bool succ; + + if (has_sign) { + if ((*sign != '+') && (*sign != '-') && (*sign != ' ')) { + rnd_message(RND_MSG_WARNING, "Invalid coordinate sign: '%c':\n", *line); + return -1; + } + } + extract_field(tmp, line, start, end); + d = rnd_get_value(tmp, is_mil ? "mil" : "mm", NULL, &succ); + if (!succ) + return -1; + if (is_mil) + d = d / 10.0; + else + d = d / 1000.0; + *dst = rnd_round(d); + return 0; +} + +static int extract_int(int *dst, const char *line, int start, int end) +{ + char tmp[16], *ends; + + extract_field(tmp, line, start, end); + *dst = strtol(tmp, &ends, 10); + if (*ends != '\0') + return -1; + return 0; +} + +typedef struct { + int is_via, is_middle, is_plated, side, rot, is_tooling, mask; + rnd_coord_t hole, width, height, cx, cy; +} test_feature_t; + +static int parse_feature(char *line, test_feature_t *tf, const char *fn, long lineno, int is_mil, int is_rad, char *netname, char *refdes, char *term) +{ + if (line[2] != '7') { + rnd_message(RND_MSG_WARNING, "Ignoring unknown test feautre '3%c%c' in %s:%ld' - does not end in 7\n", line[1], line[2], fn, lineno); + return -1; + } + if (line[26] != '-') { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - missing dash between refdes and pin number\n", fn, lineno); + return -1; + } + extract_field(netname, line, 3, 16); + extract_field(refdes, line, 20, 25); + extract_field(term, line, 27, 30); + tf->is_via = (strcmp(refdes, "VIA") == 0); + tf->is_middle = (line[31] == 'M'); + if (line[32] == 'D') { + if (extract_dim(&tf->hole, line, 33, 36, 0, is_mil)) { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - invalid hole dimension\n", fn, lineno); + return -1; + } + if (line[37] == 'P') + tf->is_plated = 1; + else if (line[37] == 'U') + tf->is_plated = 0; + else { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - hole is neither plated nor unplated\n", fn, lineno); + return -1; + } + } + else { + tf->hole = 0; + tf->is_plated = 0; + } + if (line[38] != 'A') { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - missing 'A' for access\n", fn, lineno); + return -1; + } + if (extract_int(&tf->side, line, 39, 40)) { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - invalid access side\n", fn, lineno); + return -1; + } + if (line[41] != 'X') { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - missing 'X'\n", fn, lineno); + return -1; + } + if (extract_dim(&tf->cx, line, 42, 48, 1, is_mil)) { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - invalid X dimension\n", fn, lineno); + return -1; + } + if (line[49] != 'Y') { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - missing 'Y'\n", fn, lineno); + return -1; + } + if (extract_dim(&tf->cy, line, 50, 56, 1, is_mil)) { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - invalid Y dimension\n", fn, lineno); + return -1; + } + if (line[57] != 'X') { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - missing width 'X'\n", fn, lineno); + return -1; + } + if (extract_dim(&tf->width, line, 58, 61, 0, is_mil)) { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - invalid width dimension\n", fn, lineno); + return -1; + } + if (line[62] != 'Y') { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - missing height 'Y'\n", fn, lineno); + return -1; + } + if (extract_dim(&tf->height, line, 63, 66, 0, is_mil)) { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - invalid height 'Y' dimension\n", fn, lineno); + return -1; + } + if (line[67] != 'R') { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - missing rotation 'R'\n", fn, lineno); + return -1; + } + if (extract_int(&tf->rot, line, 68, 70)) { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - invalid height 'Y' dimension\n", fn, lineno); + return -1; + } + if (line[72] != 'S') { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - solder mask marker 'S'\n", fn, lineno); + return -1; + } + if (extract_int(&tf->mask, line, 73, 73)) { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - invalid height 'Y' dimension\n", fn, lineno); + return -1; + } + tf->is_tooling = 0; + + switch(line[1]) { + case '3': /* tooling feature/hole */ + case '4': /* tooling hole only */ + tf->is_tooling = 1; + case '1': /* through hole */ + if (tf->hole == 0) { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - thru-hole feature without hole dia\n", fn, lineno); + return -1; + } + break; + case '2': /* SMT feature */ + if (tf->hole > 0) { + rnd_message(RND_MSG_WARNING, "Ignoring invalid test feautre in %s:%ld' - SMD feature with hole dia\n", fn, lineno); + break; + } + break; + default: + rnd_message(RND_MSG_WARNING, "Ignoring unknown test feautre '3%c%c' in %s:%ld - unknown second digit'\n", line[1], line[2], fn, lineno); + } + return 0; +} + +static void create_feature(pcb_board_t *pcb, pcb_data_t *data, test_feature_t *tf, const char *fn, long lineno, const char *term) +{ + pcb_pstk_t *ps; + pcb_pstk_shape_t sh[6]; + rnd_coord_t msk = RND_MIL_TO_COORD(4), y; + int i = 0, thru = (tf->hole > 0) && (tf->is_plated); + + memset(sh, 0, sizeof(sh)); + if (tf->height == 0) { + if ((tf->side == 0) || (tf->side == 1) || thru) { + sh[i].layer_mask = PCB_LYT_TOP | PCB_LYT_COPPER; pcb_shape_oval(&sh[i], tf->width, tf->width); i++; + } + if ((tf->side == 0) || (tf->side == 2) || thru) { + sh[i].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_COPPER; pcb_shape_oval(&sh[i], tf->width, tf->width); i++; + } + if (thru) { + sh[i].layer_mask = PCB_LYT_INTERN | PCB_LYT_COPPER; pcb_shape_oval(&sh[i], tf->width, tf->width); i++; + } + if ((tf->mask == 0) || (tf->mask == 1)) { + sh[i].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_MASK; sh[i].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_oval(&sh[i], tf->width + msk, tf->width + msk); i++; + } + if ((tf->mask == 0) || (tf->mask == 2)) { + sh[i].layer_mask = PCB_LYT_TOP | PCB_LYT_MASK; sh[i].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_oval(&sh[i], tf->width + msk, tf->width + msk); i++; + } + } + else { + if ((tf->side == 0) || (tf->side == 1) || thru) { + sh[i].layer_mask = PCB_LYT_TOP | PCB_LYT_COPPER; pcb_shape_rect(&sh[i], tf->width, tf->height); i++; + } + if ((tf->side == 0) || (tf->side == 2) || thru) { + sh[i].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_COPPER; pcb_shape_rect(&sh[i], tf->width, tf->height); i++; + } + if (thru) { + sh[i].layer_mask = PCB_LYT_INTERN | PCB_LYT_COPPER; pcb_shape_rect(&sh[i], tf->width, tf->height); i++; + } + if ((tf->mask == 0) || (tf->mask == 1)) { + sh[i].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_MASK; sh[i].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_rect(&sh[i], tf->width + msk, tf->height + msk); i++; + } + if ((tf->mask == 0) || (tf->mask == 2)) { + sh[i].layer_mask = PCB_LYT_TOP | PCB_LYT_MASK; sh[i].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_rect(&sh[i], tf->width + msk, tf->height + msk); i++; + } + } + + y = pcb->hidlib.size_y - tf->cy; + if ((y < 0) || (y > pcb->hidlib.size_y) || (tf->cx < 0) || (tf->cx > pcb->hidlib.size_x)) + rnd_message(RND_MSG_WARNING, "Test feature ended up out of the board extents in %s:%ld - board too small please use autocrop()\n", fn, lineno); + ps = pcb_pstk_new_from_shape(data, tf->cx, y, tf->hole, tf->is_plated, conf_core.design.bloat, sh); + + if (tf->is_middle) + pcb_attribute_put(&ps->Attributes, "ipcd356::mid", "yes"); + if (tf->is_tooling) + pcb_attribute_put(&ps->Attributes, "ipcd356::tooling", "yes"); + if (term) + pcb_attribute_put(&ps->Attributes, "term", term); +} + +static int ipc356_parse(pcb_board_t *pcb, FILE *f, const char *fn, htsp_t *subcs, int want_net, int want_pads) +{ + char line_[128], *line, netname[16], refdes[8], term[8]; + long lineno = 0; + int is_mil = 1, is_rad = 0; + test_feature_t tf; + pcb_subc_t *sc; + pcb_data_t *data = pcb->Data; + + while((line = fgets(line_, sizeof(line_), f)) != NULL) { + lineno++; + switch(*line) { + case '\r': + case '\n': + case 'C': /* comment */ + break; + case 'P': /* parameter */ + if (strncmp(line+3, "UNITS CUST", 10) == 0) { + switch(line[14]) { + case '0': is_mil = 1; is_rad = 0; break; + case '1': is_mil = 0; is_rad = 0; break; + case '2': is_mil = 1; is_rad = 1; break; + } + if (is_rad) { + rnd_message(RND_MSG_ERROR, "Unimplemented unit in %s:%ld - requested radians in rotation, the code doesn't handle that\n", fn, lineno); + return 1; + } + } + break; + case '3': /* test feature */ + if (parse_feature(line, &tf, fn, lineno, is_mil, is_rad, netname, refdes, term) != 0) + return 1; + + if (subcs != NULL) { + sc = htsp_get(subcs, refdes); + + if (sc == NULL) { + const char *nr; + sc = pcb_subc_alloc(); + pcb_attribute_put(&sc->Attributes, "refdes", refdes); + set_src(&sc->Attributes, fn, lineno); + nr = pcb_attribute_get(&sc->Attributes, "refdes"); + htsp_set(subcs, (char *)nr, sc); + pcb_subc_reg(pcb->Data, sc); + pcb_subc_bind_globals(pcb, sc); + } + data = sc->data; + } + + if (want_pads) + create_feature(pcb, data, &tf, fn, lineno, term); + + if (want_net && (netname_valid(netname))) { + char tn[36]; + sprintf(tn, "%s-%s", refdes, term); + rnd_actionva(&pcb->hidlib, "Netlist", "Add", netname, tn, NULL); + } + break; + case '9': /* EOF */ + if ((line[1] == '9') && (line[2] == '9')) + return 0; + rnd_message(RND_MSG_ERROR, "Invalid end-of-file marker in %s:%ld - expected '999'\n", fn, lineno); + return 1; + } + } + + rnd_message(RND_MSG_ERROR, "Unexpected end of file - expected '999'\n"); + return 1; +} + +static const char pcb_acts_LoadIpc356From[] = "LoadIpc356From(filename, [nonet], [nopad], [nosubc])"; +static const char pcb_acth_LoadIpc356From[] = "Loads the specified IPC356-D netlist"; +fgw_error_t pcb_act_LoadIpc356From(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + FILE *f; + static char *default_file = NULL; + const char *fname = NULL; + int rs, n, want_subc = 1, want_net = 1, want_pads = 1; + htsp_t subcs, *scs = NULL; + htsp_entry_t *e; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadIpc356From, fname = argv[1].val.str); + + if ((fname == NULL) || (*fname == '\0')) { + fname = rnd_gui->fileselect(rnd_gui, "Load IPC-D-356 netlist...", + "Pick an IPC-D-356 netlist file.\n", + default_file, ".net", NULL, "ipcd356", RND_HID_FSD_READ, NULL); + if (fname == NULL) { + RND_ACT_IRES(1); + return 0; + } + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + f = rnd_fopen(&PCB->hidlib, fname, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Can't open %s for read\n", fname); + RND_ACT_IRES(1); + return 0; + } + + for(n = 2; n < argc; n++) { + const char *s; + RND_ACT_MAY_CONVARG(n, FGW_STR, LoadIpc356From, s = argv[n].val.str); + if (strcmp(s, "nonet") == 0) want_net = 0; + if (strcmp(s, "nopad") == 0) want_pads = 0; + if (strcmp(s, "nosubc") == 0) want_subc = 0; + } + + if (!want_pads) + want_subc = 0; /* can't load subcircuits if there are no padstacks - they would be all empty */ + + if (want_subc) { + htsp_init(&subcs, strhash, strkeyeq); + scs = &subcs; + } + + pcb_undo_freeze_serial(); + + if (want_net) { + rnd_actionva(RND_ACT_HIDLIB, "Netlist", "Freeze", NULL); + rnd_actionva(RND_ACT_HIDLIB, "Netlist", "Clear", NULL); + } + + rs = ipc356_parse(PCB, f, fname, scs, want_net, want_pads); + + if (want_net) { + rnd_actionva(RND_ACT_HIDLIB, "Netlist", "Sort", NULL); + rnd_actionva(RND_ACT_HIDLIB, "Netlist", "Thaw", NULL); + } + + fclose(f); + + if (want_subc) { + for (e = htsp_first(&subcs); e; e = htsp_next(&subcs, e)) { + pcb_subc_t *sc = (pcb_subc_t *)e->value; + pcb_subc_reg(PCB->Data, sc); + pcb_subc_bbox(sc); + if (PCB->Data->subc_tree == NULL) + PCB->Data->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(PCB->Data->subc_tree, (rnd_box_t *)sc); + pcb_subc_rebind(PCB, sc); + } + htsp_uninit(&subcs); + } + + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + RND_ACT_IRES(rs); + return 0; +} + +rnd_action_t import_ipcd356_action_list[] = { + {"LoadIpc356From", pcb_act_LoadIpc356From, pcb_acth_LoadIpc356From, pcb_acts_LoadIpc356From} +}; + +static int ipcd356_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + FILE *f; + + if ((aspects != IMPORT_ASPECT_NETLIST) || (numargs != 1)) + return 0; /* only pure netlist import is supported */ + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + for(;;) { + char *s, line[1024]; + line[19] = '!'; /* make sure we have a space there because of fgets */ + s = fgets(line, sizeof(line), f); + if (s == NULL) + break; + if ((strncmp(s, "999", 3) == 0) && (isspace(s[3]))) { + fclose(f); + return 100; + } + if ((strncmp(s, "327", 3) != 0) && (strncmp(s, "317", 3) != 0)) + continue; + if (s[19] == ' ') { + fclose(f); + return 100; + } + } + + fclose(f); + return 0; +} + + +static int ipcd356_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_ipcd356: requires exactly 1 input file name\n"); + return -1; + } + return rnd_actionva(&PCB->hidlib, "LoadIpc356From", fns[0], NULL); +} + +static pcb_plug_import_t import_ipcd356; + + +int pplg_check_ver_import_ipcd356(int ver_needed) { return 0; } + +void pplg_uninit_import_ipcd356(void) +{ + rnd_remove_actions_by_cookie(ipcd356_cookie); + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_ipcd356); + rnd_hid_menu_unload(rnd_gui, ipcd356_cookie); +} + +int pplg_init_import_ipcd356(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_ipcd356.plugin_data = NULL; + + import_ipcd356.fmt_support_prio = ipcd356_support_prio; + import_ipcd356.import = ipcd356_import; + import_ipcd356.name = "IPC-D-356"; + import_ipcd356.desc = "nets and pads from an IPC-D-356 test file"; + import_ipcd356.ui_prio = 30; + import_ipcd356.single_arg = 1; + import_ipcd356.all_filenames = 1; + import_ipcd356.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_ipcd356); + + + RND_REGISTER_ACTIONS(import_ipcd356_action_list, ipcd356_cookie); + rnd_hid_menu_load(rnd_gui, NULL, ipcd356_cookie, 180, NULL, 0, ipcd356_menu, "ipcd356 import"); + return 0; +} Index: tags/2.3.0/src_plugins/import_ltspice/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_ltspice/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_ltspice/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_ltspice + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_ltspice/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_ltspice/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_ltspice/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {import_ltspice} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_ltspice/ltspice.o @] +put /local/pcb/mod/MENUFILE {ltspice-menu.lht} +put /local/pcb/mod/MENUVAR {ltspice_menu} + +switch /local/pcb/import_ltspice/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_ltspice/import_ltspice.pup =================================================================== --- tags/2.3.0/src_plugins/import_ltspice/import_ltspice.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_ltspice/import_ltspice.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import ltspice .net+.asc +$long Import the netlist and footprints from an ltspice .asc and .net pair of files +$state works +$fmt-native no +$fmt-feature-r import ltspice .net and .asc (netlist and footprint info) +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_ltspice/ltspice-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_ltspice/ltspice-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_ltspice/ltspice-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Load LTSpice .net and .asc files = { action=LoadLTSpiceFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/import_ltspice/ltspice.c =================================================================== --- tags/2.3.0/src_plugins/import_ltspice/ltspice.c (nonexistent) +++ tags/2.3.0/src_plugins/import_ltspice/ltspice.c (revision 33253) @@ -0,0 +1,417 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * LTSpice import HID + * pcb-rnd Copyright (C) 2017,2020 Tibor 'Igor2' Palinkas + * Copyright (C) 2017 Erich Heinzle (non passive footprint parsing) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "plug_import.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "menu_internal.c" + +static const char *ltspice_cookie = "ltspice importer"; + +static int ltspice_hdr_asc(FILE *f) +{ + char s[1024]; + while(fgets(s, sizeof(s), f) != NULL) + if (strncmp(s, "Version 4", 9) == 0) + return 0; + return -1; +} + +/* remove leading whitespace */ +#define ltrim(s) while(isspace(*s)) s++ + +/* remove trailing newline */ +#define rtrim(s) \ + do { \ + char *end; \ + for(end = s + strlen(s) - 1; (end >= s) && ((*end == '\r') || (*end == '\n')); end--) \ + *end = '\0'; \ + } while(0) + +typedef struct { + char *refdes; + char *value; + char *footprint; +} symattr_t; + + +#define null_empty(s) ((s) == NULL ? "" : (s)) + +static void sym_flush(symattr_t *sattr) +{ +/* rnd_trace("ltspice sym: refdes=%s val=%s fp=%s\n", sattr->refdes, sattr->value, sattr->footprint);*/ + + if (sattr->refdes != NULL) { + if (sattr->footprint == NULL) + rnd_message(RND_MSG_ERROR, "ltspice: not importing refdes=%s: no footprint specified\n", sattr->refdes); + else + rnd_actionva(&PCB->hidlib, "ElementList", "Need", null_empty(sattr->refdes), null_empty(sattr->footprint), null_empty(sattr->value), NULL); + } + free(sattr->refdes); sattr->refdes = NULL; + free(sattr->value); sattr->value = NULL; + free(sattr->footprint); sattr->footprint = NULL; +} + +static int ltspice_parse_asc(FILE *fa) +{ + symattr_t sattr; + char line[1024]; + + memset(&sattr, 0, sizeof(sattr)); + + rnd_actionva(&PCB->hidlib, "ElementList", "start", NULL); + + while(fgets(line, sizeof(line), fa) != NULL) { + char *s; + int isPassive = 0; + s = line; + rtrim(s); + + if (strncmp(s, "SYMBOL", 6) == 0) + sym_flush(&sattr); + else if (strncmp(s, "SYMATTR", 7) == 0) { + s+=8; + ltrim(s); + if (strncmp(s, "InstName", 8) == 0) { + s+=9; + ltrim(s); + free(sattr.refdes); + sattr.refdes = rnd_strdup(s); + /* figure out if device is passive or not, as this affects + subsequent parsing of the "SYMATTR VALUE .... " line */ + if (strncmp(s, "R", 1) != 0 && strncmp(s, "L", 1) != 0 && + strncmp(s, "C", 1) != 0) { + isPassive = 0; + } + else { + isPassive = 1; + } + } + else { + if (strncmp(s, "Value", 5) == 0) { + /* we get around non passives having a device quoted with no + mfg= field in the .net file by parsing the device name for + an appended .pcb-rnd-TO92 etc... + i.e. parse the following: SYMATTR Value 2N2222.pcb-rnd-TO92 */ + s+=6; + ltrim(s); + free(sattr.value); + if (isPassive) { + sattr.value = rnd_strdup(s); + } + else { + char *fp; + /*s+=6;*/ + fp = strstr(s, ".pcb-rnd-"); + if (fp != NULL) { + sattr.value = rnd_strdup(fp); + s = fp; + fp += 9; + if (*fp == '"') { + char *end; + fp++; + end = strchr(fp, '"'); + if (end != NULL) + *end = '\0'; + } + free(sattr.footprint); + sattr.footprint = rnd_strdup(fp); + } + } + } + if (strncmp(s, "SpiceLine", 9) == 0) { + /* for passives, the SpiceLine include the "mfg=" field */ + char *fp; + s+=6; + fp = strstr(s, "mfg="); + if (fp != NULL) { + fp += 4; + if (*fp == '"') { + char *end; + fp++; + end = strchr(fp, '"'); + if (end != NULL) + *end = '\0'; + } + if (strncmp(fp, ".pcb-rnd-", 9) == 0) + fp += 9; + if (strncmp(fp, "pcb-rnd-", 8) == 0) + fp += 8; + free(sattr.footprint); + sattr.footprint = rnd_strdup(fp); + } + } + /* nothing stops a user inserting + "SYMATTR Footprint TO92" if keen in the .asc file */ + if (strncmp(s, "Footprint", 9) == 0) { + s+=10; + ltrim(s); + free(sattr.footprint); + sattr.footprint = rnd_strdup(s); + } + } + } + } + sym_flush(&sattr); + rnd_actionva(&PCB->hidlib, "ElementList", "Done", NULL); + return 0; +} + +static int ltspice_parse_net(FILE *fn) +{ + char line[1024]; + + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + + while(fgets(line, sizeof(line), fn) != NULL) { + int argc; + char **argv, *s; + + s = line; + ltrim(s); + rtrim(s); + argc = qparse2(s, &argv, QPARSE_DOUBLE_QUOTE | QPARSE_SINGLE_QUOTE); + if ((argc > 1) && (strcmp(argv[0], "NET") == 0)) { + int n; + for(n = 2; n < argc; n++) { +/* rnd_trace("net-add '%s' '%s'\n", argv[1], argv[n]);*/ + rnd_actionva(&PCB->hidlib, "Netlist", "Add", argv[1], argv[n], NULL); + } + } + } + + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + + return 0; +} + + +static int ltspice_load(const char *fname_net, const char *fname_asc) +{ + FILE *fn, *fa; + int ret = 0; + + fn = rnd_fopen(&PCB->hidlib, fname_net, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname_net); + return -1; + } + fa = rnd_fopen(&PCB->hidlib, fname_asc, "r"); + if (fa == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname_asc); + fclose(fn); + return -1; + } + + if (ltspice_hdr_asc(fa)) { + rnd_message(RND_MSG_ERROR, "file '%s' doesn't look like a verison 4 asc file\n", fname_asc); + goto error; + } + + + if (ltspice_parse_asc(fa) != 0) goto error; + if (ltspice_parse_net(fn) != 0) goto error; + + quit:; + fclose(fa); + fclose(fn); + return ret; + + error: + ret = -1; + goto quit; +} + +static void gen_filenames(const char *fname, char **fname_net, char **fname_asc) +{ + const char *end; + char *fname_base = NULL; + + end = strrchr(fname, '.'); + if (end != NULL) { + if (strcmp(end, ".net") == 0) + fname_base = rnd_strndup(fname, end - fname); + else if (strcmp(end, ".asc") == 0) + fname_base = rnd_strndup(fname, end - fname); + } + if (fname_base == NULL) + fname_base = rnd_strdup(fname); + + *fname_net = rnd_strdup_printf("%s.net", fname_base); + *fname_asc = rnd_strdup_printf("%s.asc", fname_base); + free(fname_base); +} + +static const char pcb_acts_LoadLtspiceFrom[] = "LoadLtspiceFrom(filename)"; +static const char pcb_acth_LoadLtspiceFrom[] = "Loads the specified ltspice .net and .asc file - the netlist must be mentor netlist."; +fgw_error_t pcb_act_LoadLtspiceFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + char *fname_asc, *fname_net; + static char *default_file = NULL; + int rs; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadLtspiceFrom, fname = argv[1].val.str); + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Load ltspice net+asc file pair...", + "Picks a ltspice mentor net or asc file to load.\n", + default_file, ".asc", NULL, "ltspice", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 1; + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + gen_filenames(fname, &fname_net, &fname_asc); + + pcb_undo_freeze_serial(); + rs = ltspice_load(fname_net, fname_asc); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + free(fname_asc); + free(fname_net); + + RND_ACT_IRES(rs); + return 0; +} + +static int ltspice_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + int res = 0; + FILE *f = NULL; + unsigned int good = 0; + char *fname_asc, *fname_net; + + if ((aspects != IMPORT_ASPECT_NETLIST) || (numargs != 1)) + return 0; /* only pure netlist import is supported */ + + gen_filenames(args[0], &fname_net, &fname_asc); + if (!rnd_file_readable(fname_net)) + goto quit; + + f = rnd_fopen(&PCB->hidlib, fname_asc, "r"); + if (f == NULL) + goto quit; + + for(;;) { + char *s, line[1024]; + s = fgets(line, sizeof(line), f); + if (s == NULL) + break; + while(isspace(*s)) s++; + if (strncmp(s, "SHEET", 5) == 0) + good |= 1; + else if (strncmp(s, "WIRE", 4) == 0) + good |= 2; + if (good == (1|2)) { + res = 100; + goto quit; + } + } + + + quit:; + if (f != NULL) + fclose(f); + free(fname_asc); + free(fname_net); + return res; +} + + +static int ltspice_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_ltspice: requires exactly 1 input file name\n"); + return -1; + } + return rnd_actionva(&PCB->hidlib, "LoadLtspiceFrom", fns[0], NULL); +} + +static pcb_plug_import_t import_ltspice; + +rnd_action_t ltspice_action_list[] = { + {"LoadLtspiceFrom", pcb_act_LoadLtspiceFrom, pcb_acth_LoadLtspiceFrom, pcb_acts_LoadLtspiceFrom} +}; + +int pplg_check_ver_import_ltspice(int ver_needed) { return 0; } + +void pplg_uninit_import_ltspice(void) +{ + rnd_remove_actions_by_cookie(ltspice_cookie); + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_ltspice); + rnd_hid_menu_unload(rnd_gui, ltspice_cookie); +} + +int pplg_init_import_ltspice(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_ltspice.plugin_data = NULL; + + import_ltspice.fmt_support_prio = ltspice_support_prio; + import_ltspice.import = ltspice_import; + import_ltspice.name = "LTSpice"; + import_ltspice.desc = "schamtics from LTSpice"; + import_ltspice.ui_prio = 50; + import_ltspice.single_arg = 1; + import_ltspice.all_filenames = 1; + import_ltspice.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_ltspice); + + RND_REGISTER_ACTIONS(ltspice_action_list, ltspice_cookie) + rnd_hid_menu_load(rnd_gui, NULL, ltspice_cookie, 165, NULL, 0, ltspice_menu, "plugin: ltspice netlist import"); + return 0; +} Index: tags/2.3.0/src_plugins/import_mentor_sch/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_mentor_sch/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_mentor_sch/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_mentor_sch + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_mentor_sch/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_mentor_sch/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_mentor_sch/Plug.tmpasm (revision 33253) @@ -0,0 +1,15 @@ +put /local/pcb/mod {import_mentor_sch} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/import_mentor_sch/netlist_helper.o + $(PLUGDIR)/import_mentor_sch/mentor_sch.o +@] +put /local/pcb/mod/CONF {$(PLUGDIR)/import_mentor_sch/mentor_sch_conf.h} +put /local/pcb/mod/MENUFILE {mentor-menu.lht} +put /local/pcb/mod/MENUVAR {mentor_menu} + + +switch /local/pcb/import_mentor_sch/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_mentor_sch/import_mentor_sch.pup =================================================================== --- tags/2.3.0/src_plugins/import_mentor_sch/import_mentor_sch.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_mentor_sch/import_mentor_sch.pup (revision 33253) @@ -0,0 +1,10 @@ +$class import +$short import mentor graphics sch +$long Import Mentor Graphics Design Capture from flattened .edf netlist, using a parts conversion table. +$state works +$fmt-native no +$fmt-feature-r flat .edf (netlist+footprint, produced by Mentor Graphics Design Capture) +$package import-net +default buildin +dep lib_gensexpr +autoload 1 Index: tags/2.3.0/src_plugins/import_mentor_sch/mentor-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_mentor_sch/mentor-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_mentor_sch/mentor-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Import mentor graphics schematics = { action=LoadMentorFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/import_mentor_sch/mentor_parts.map =================================================================== --- tags/2.3.0/src_plugins/import_mentor_sch/mentor_parts.map (nonexistent) +++ tags/2.3.0/src_plugins/import_mentor_sch/mentor_parts.map (revision 33253) @@ -0,0 +1,19 @@ +# Format: +# - one rulr per line +# - field separator is | +# - fields: +# 1: priority: if multiple rules match for a givem part attrib, pick the highest prio only +# * means "ignore priority, always execute" +# 2: part attribute name regex - consider the rule only if the part has a matching attribute name +# 3: part attribute value regex - consider the rule only if value matches; back referenced from add-value +# 4: add attribute name: add or overwrite attribute on rule match +# 5: add attribute value: use value for the new attribute; built with back references to part attribute regex + +# plain headers +100|Part Name|Dummy_HDR \([0-9]+\)x\([0-9]+\) P:\([0-9.]+mm\)|footprint|connector(\1, \2, \3) + +# last hope... +10|Part Name|_0402$|footprint|0402 +10|Part Name|_0603$|footprint|0603 +10|Part Name|_1206$|footprint|1206 +10|Part Name|_1210$|footprint|1210 Index: tags/2.3.0/src_plugins/import_mentor_sch/mentor_sch.c =================================================================== --- tags/2.3.0/src_plugins/import_mentor_sch/mentor_sch.c (nonexistent) +++ tags/2.3.0/src_plugins/import_mentor_sch/mentor_sch.c (revision 33253) @@ -0,0 +1,350 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * mentor graphics schematics import plugin + * pcb-rnd Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "plug_import.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "mentor_sch_conf.h" +#include +#include + +#include "netlist_helper.h" + +#include "menu_internal.c" + +conf_mentor_sch_t conf_mentor; + + +static const char *mentor_sch_cookie = "mentor_sch importer"; + +/* Return the nth child's string of the subtree called subtree_name under node */ +static const char *get_by_name(gsxl_node_t *node, const char *subtree_name, int child_idx) +{ + gsxl_node_t *n; + for(n = node->children; n != NULL; n = n->next) { + if (strcmp(n->str, subtree_name) == 0) { + for(n = n->children; (n != NULL) && (child_idx > 0); n = n->next, child_idx--) ; + if (n == NULL) + return NULL; + return n->str; + } + } + return NULL; +} + +static int parse_netlist_instance(nethlp_ctx_t *nhctx, gsxl_node_t *inst) +{ + gsxl_node_t *n; + const char *refdes = NULL; + nethlp_elem_ctx_t ectx; + +/* printf("inst %s\n", inst->children->str); */ + + nethlp_elem_new(nhctx, &ectx, inst->children->str); + + for(n = inst->children; n != NULL; n = n->next) { + if (strcmp(n->str, "designator") == 0) { + refdes = n->children->str; +/* printf(" refdes=%s\n", refdes); */ + nethlp_elem_refdes(&ectx, refdes); + } + else if (strcmp(n->str, "property") == 0) { + const char *key, *val; + key = get_by_name(n, "rename", 1); + val = get_by_name(n, "string", 0); +/* printf(" property '%s'='%s'\n", key, val); */ + if ((key != NULL) && (val != NULL)) + nethlp_elem_attr(&ectx, key, val); + } + } + + nethlp_elem_done(&PCB->hidlib, &ectx); +/* rnd_actionva(&PCB->hidlib, "ElementList", "Need", null_empty(sattr->refdes), null_empty(sattr->footprint), null_empty(sattr->value), NULL);*/ + return 0; +} + +static int parse_netlist_net(nethlp_ctx_t *nhctx, gsxl_node_t *net) +{ + gsxl_node_t *n, *p; + const char *netname = get_by_name(net, "rename", 1); + nethlp_net_ctx_t nctx; + + nethlp_net_new(nhctx, &nctx, netname); + + for(n = net->children; n != NULL; n = n->next) { + if (strcmp(n->str, "joined") == 0) { + for(p = n->children; p != NULL; p = p->next) { + if (strcmp(p->str, "portRef") == 0) { + const char *part, *pin; + pin = p->children->str; + part = get_by_name(p, "instanceRef", 0); + if ((part != NULL) && (pin != NULL)) { + if (*pin == '&') + pin++; + nethlp_net_add_term(&PCB->hidlib, &nctx, part, pin); + } + } + } + } + } + + nethlp_net_destroy(&nctx); + return 0; +} + + +static int parse_netlist_view(gsxl_node_t *view) +{ + gsxl_node_t *contents, *n; + nethlp_ctx_t nhctx; + int idx, res = 0, cnt = 0; + rnd_conf_listitem_t *item; + const char *item_str; + + nethlp_new(&nhctx); + + rnd_conf_loop_list_str(&conf_mentor.plugins.import_mentor_sch.map_search_paths, item, item_str, idx) { + char *p; + rnd_path_resolve(&PCB->hidlib, item_str, &p, 0, rnd_false); + if (p != NULL) { + cnt += nethlp_load_part_map(&nhctx, p); + free(p); + } + } + if (cnt == 0) + rnd_message(RND_MSG_WARNING, "Couldn't find any part map rules - check your map_search_paths and rule files\n"); + + for(contents = view->children; contents != NULL; contents = contents->next) { + if (strcmp(contents->str, "contents") == 0) { + printf("--- view\n"); + for(n = contents->children; n != NULL; n = n->next) { + if (strcmp(n->str, "instance") == 0) + res |= parse_netlist_instance(&nhctx, n); + if (strcmp(n->str, "net") == 0) + res |= parse_netlist_net(&nhctx, n); + } + } + } + + nethlp_destroy(&nhctx); + return res; +} + +static int mentor_parse_tree(gsxl_dom_t *dom) +{ + gsxl_node_t *view, *cell, *library, *vtype; + + /* check the header */ + if (strcmp(dom->root->str, "edif") != 0) { + rnd_message(RND_MSG_ERROR, "Invalid mentor edf header: not an EDIF file\n"); + return -1; + } + + pcb_undo_freeze_serial(); + + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + rnd_actionva(&PCB->hidlib, "ElementList", "start", NULL); + + for(library = dom->root->children; library != NULL; library = library->next) { + if (strcmp(library->str, "library") == 0) { + if (strcmp(library->children->str, "hierarchical") == 0) { + for(cell = library->children; cell != NULL; cell = cell->next) { + if (strcmp(cell->str, "cell") == 0) { + for(view = cell->children; view != NULL; view = view->next) { + if (strcmp(view->children->str, "v1") == 0) { + vtype = view->children->next; + if ((strcmp(vtype->str, "viewType") == 0) && (strcmp(vtype->children->str, "netlist") == 0)) + parse_netlist_view(view); + } + } + } + } + } + } + } + + rnd_actionva(&PCB->hidlib, "ElementList", "Done", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + +/* for(n = library->children; n != NULL; n = n->next) { + printf("n=%s\n", n->str); + if (strcmp(n->str, "cell") == 0) { + printf("cell\n"); + } + }*/ + + + return -1; +} + + +static int mentor_sch_load(const char *fname_net) +{ + FILE *fn; + gsxl_dom_t dom; + int c, ret = 0; + gsx_parse_res_t res; + + fn = rnd_fopen(NULL, fname_net, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname_net); + return -1; + } + + gsxl_init(&dom, gsxl_node_t); + + dom.parse.line_comment_char = '#'; + do { + c = fgetc(fn); + } while((res = gsxl_parse_char(&dom, c)) == GSX_RES_NEXT); + fclose(fn); + + if (res == GSX_RES_EOE) { + /* compact and simplify the tree */ + gsxl_compact_tree(&dom); + + /* recursively parse the dom */ + ret = mentor_parse_tree(&dom); + } + else { + rnd_message(RND_MSG_ERROR, "Invalid mentor edf: not a valid s-expression file near %d:%d\n", dom.parse.line, dom.parse.col); + ret = -1; + } + + /* clean up */ + gsxl_uninit(&dom); + + return ret; + +} + +static const char pcb_acts_Loadmentor_schFrom[] = "LoadMentorFrom(filename)"; +static const char pcb_acth_Loadmentor_schFrom[] = "Loads the specified Mentor Graphics Design Capture schematics flat .edf file."; +fgw_error_t pcb_act_LoadMentorFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + static char *default_file = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, Loadmentor_schFrom, fname = argv[1].val.str); + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Load mentor edf netlist file...", + "Picks a mentor edf file to load.\n", + default_file, ".edf", NULL, "mentor_sch", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 1; + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + RND_ACT_IRES(0); + return mentor_sch_load(fname); +} + +static int mentor_sch_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + if (aspects != IMPORT_ASPECT_NETLIST) + return 0; /* only pure netlist import is supported */ + return 0; /* can't tell apart from normal edif; best if the user selects format explicitly */ +} + + +static int mentor_sch_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_mentor_sch: requires exactly 1 input file name\n"); + return -1; + } + return mentor_sch_load(fns[0]); +} + +static pcb_plug_import_t import_mentor_sch; + + +rnd_action_t mentor_sch_action_list[] = { + {"LoadMentorFrom", pcb_act_LoadMentorFrom, pcb_acth_Loadmentor_schFrom, pcb_acts_Loadmentor_schFrom} +}; + +int pplg_check_ver_import_mentor_sch(int ver_needed) { return 0; } + +void pplg_uninit_import_mentor_sch(void) +{ + rnd_remove_actions_by_cookie(mentor_sch_cookie); + rnd_conf_unreg_fields("plugins/import_mentor_sch/"); + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_mentor_sch); + rnd_hid_menu_unload(rnd_gui, mentor_sch_cookie); +} + +int pplg_init_import_mentor_sch(void) +{ + RND_API_CHK_VER; + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_mentor, field,isarray,type_name,cpath,cname,desc,flags); +#include "mentor_sch_conf_fields.h" + + /* register the IO hook */ + import_mentor_sch.plugin_data = NULL; + + import_mentor_sch.fmt_support_prio = mentor_sch_support_prio; + import_mentor_sch.import = mentor_sch_import; + import_mentor_sch.name = "mentor_sch"; + import_mentor_sch.desc = "schamtics: Mentor Graphics Design Design Caputre"; + import_mentor_sch.ui_prio = 40; + import_mentor_sch.single_arg = 1; + import_mentor_sch.all_filenames = 1; + import_mentor_sch.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_mentor_sch); + + RND_REGISTER_ACTIONS(mentor_sch_action_list, mentor_sch_cookie) + rnd_hid_menu_load(rnd_gui, NULL, mentor_sch_cookie, 185, NULL, 0, mentor_menu, "plugin: mentor_sch"); + return 0; +} Index: tags/2.3.0/src_plugins/import_mentor_sch/mentor_sch_conf.h =================================================================== --- tags/2.3.0/src_plugins/import_mentor_sch/mentor_sch_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/import_mentor_sch/mentor_sch_conf.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_MENTOR_SCH_CONF_H +#define PCB_MENTOR_SCH_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_LIST map_search_paths; /* parts map file search paths */ + } import_mentor_sch; + } plugins; +} conf_mentor_sch_t; + +#endif Index: tags/2.3.0/src_plugins/import_mentor_sch/netlist_helper.c =================================================================== --- tags/2.3.0/src_plugins/import_mentor_sch/netlist_helper.c (nonexistent) +++ tags/2.3.0/src_plugins/import_mentor_sch/netlist_helper.c (revision 33253) @@ -0,0 +1,308 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * netlist build helper + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "netlist_helper.h" +#include +#include +#include +#include +#include + + +nethlp_ctx_t *nethlp_new(nethlp_ctx_t *prealloc) +{ + if (prealloc == NULL) { + prealloc = malloc(sizeof(nethlp_ctx_t)); + prealloc->alloced = 1; + } + else + prealloc->alloced = 0; + + prealloc->part_rules = NULL; + htsp_init(&prealloc->id2refdes, strhash, strkeyeq); + return prealloc; +} + +void nethlp_destroy(nethlp_ctx_t *nhctx) +{ + htsp_entry_t *e; + nethlp_rule_t *r, *next; + + for(r = nhctx->part_rules; r != NULL; r = next) { + next = r->next; + re_se_free(r->key); + re_se_free(r->val); + free(r->new_key); + free(r->new_val); + free(r); + } + + for (e = htsp_first(&nhctx->id2refdes); e; e = htsp_next(&nhctx->id2refdes, e)) { + free(e->key); + free(e->value); + } + htsp_uninit(&nhctx->id2refdes); + if (nhctx->alloced) + free(nhctx); +} + +#define ltrim(str) while(isspace(*str)) str++; +#define rtrim(str) \ +do { \ + char *__s__; \ + for(__s__ = str + strlen(str) - 1; __s__ >= str; __s__--) { \ + if ((*__s__ != '\r') && (*__s__ != '\n')) \ + break; \ + *__s__ = '\0'; \ + } \ +} while(0) + +static int part_map_split(char *s, char *argv[], int maxargs) +{ + int argc; + int n; + + ltrim(s); + if ((*s == '#') || (*s == '\0')) + return 0; + rtrim(s); + + for(argc = n = 0; n < maxargs; n++) { + argv[argc] = s; + if (s != NULL) { + argc++; + s = strchr(s, '|'); + if (s != NULL) { + *s = '\0'; + s++; + } + } + } + return argc; +} + +static int part_map_parse(nethlp_ctx_t *nhctx, int argc, char *argv[], const char *fn, int lineno) +{ + char *end; + nethlp_rule_t *r; + re_se_t *kr, *vr; + int prio; + + if (argc != 5) { + rnd_message(RND_MSG_ERROR, "Loading part map: wrong number of fields %d in %s:%d - expected 5 - ignoring this rule\n", argc, fn, lineno); + return -1; + } + if (*argv[0] != '*') { + prio = strtol(argv[0], &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Loading part map: invaid priority '%s' in %s:%d - ignoring this rule\n", argv[0], fn, lineno); + return -1; + } + } + else + prio = nethlp_prio_always; + kr = re_se_comp(argv[1]); + if (kr == NULL) { + rnd_message(RND_MSG_ERROR, "Loading part map: can't compile attribute name regex in %s:%d - ignoring this rule\n", fn, lineno); + return -1; + } + vr = re_se_comp(argv[2]); + if (vr == NULL) { + re_se_free(kr); + rnd_message(RND_MSG_ERROR, "Loading part map: can't compile attribute value regex in %s:%d - ignoring this rule\n", fn, lineno); + return -1; + } + + r = malloc(sizeof(nethlp_rule_t)); + r->prio = prio; + r->key = kr; + r->val = vr; + r->new_key = rnd_strdup(argv[3]); + r->new_val = rnd_strdup(argv[4]); + r->next = nhctx->part_rules; + nhctx->part_rules = r; + + return 0; +} + +int nethlp_load_part_map(nethlp_ctx_t *nhctx, const char *fn) +{ + FILE *f; + int cnt, argc, lineno; + char line[1024], *argv[8]; + + f = rnd_fopen(NULL, fn, "r"); + if (f == NULL) + return -1; + + lineno = 0; + while(fgets(line, sizeof(line), f) != NULL) { + lineno++; + argc = part_map_split(line, argv, 6); + if ((argc > 0) && (part_map_parse(nhctx, argc, argv, fn, lineno) == 0)) { +/* printf("MAP %d '%s' '%s' '%s' '%s' '%s'\n", argc, argv[0], argv[1], argv[2], argv[3], argv[4]);*/ + cnt++; + } + } + + fclose(f); + return cnt; +} + + +nethlp_elem_ctx_t *nethlp_elem_new(nethlp_ctx_t *nhctx, nethlp_elem_ctx_t *prealloc, const char *id) +{ + if (prealloc == NULL) { + prealloc = malloc(sizeof(nethlp_elem_ctx_t)); + prealloc->alloced = 1; + } + else + prealloc->alloced = 0; + prealloc->nhctx = nhctx; + prealloc->id = rnd_strdup(id); + htsp_init(&prealloc->attr, strhash, strkeyeq); + return prealloc; +} + +void nethlp_elem_refdes(nethlp_elem_ctx_t *ectx, const char *refdes) +{ + htsp_set(&ectx->nhctx->id2refdes, rnd_strdup(ectx->id), rnd_strdup(refdes)); +} + +void nethlp_elem_attr(nethlp_elem_ctx_t *ectx, const char *key, const char *val) +{ + htsp_set(&ectx->attr, rnd_strdup(key), rnd_strdup(val)); +} + +static void elem_map_apply(nethlp_elem_ctx_t *ectx, nethlp_rule_t *r) +{ + char *dst; + re_se_backref(r->val, &dst, r->new_val); +/* printf("Map add: '%s' -> '%s'\n", r->new_key, dst);*/ + htsp_set(&ectx->attr, rnd_strdup(r->new_key), rnd_strdup(dst)); +} + +void nethlp_elem_done(rnd_hidlib_t *hl, nethlp_elem_ctx_t *ectx) +{ + htsp_entry_t *e; + char *refdes, *footprint, *value; + + /* apply part map */ + for (e = htsp_first(&ectx->attr); e; e = htsp_next(&ectx->attr, e)) { + nethlp_rule_t *r, *best_rule = NULL; + int best_prio = 0; + + for(r = ectx->nhctx->part_rules; r != NULL; r = r->next) { + if (r->prio == nethlp_prio_always) { + if (re_se_exec(r->key, e->key) && re_se_exec(r->val, e->value)) { + /* always apply - backref is already set up for val */ + elem_map_apply(ectx, r); + } + } + else if ((r->prio >= best_prio) && re_se_exec(r->key, e->key) && re_se_exec(r->val, e->value)) { + best_prio = r->prio; + best_rule = r; + } + } + if (best_rule != NULL) { + re_se_exec(best_rule->val, e->value); /* acquire the back refs again */ + elem_map_apply(ectx, best_rule); + } + } + + refdes = htsp_get(&ectx->nhctx->id2refdes, ectx->id); + if (refdes != NULL) { + /* look up hardwired attributes */ + footprint = htsp_get(&ectx->attr, "pcb-rnd-footprint"); + if (footprint == NULL) footprint = htsp_get(&ectx->attr, "footprint"); + if (footprint == NULL) footprint = htsp_get(&ectx->attr, "Footprint"); + if (footprint == NULL) footprint = ""; + + value = htsp_get(&ectx->attr, "pcb-rnd-value"); + if (value == NULL) value = htsp_get(&ectx->attr, "value"); + if (value == NULL) value = htsp_get(&ectx->attr, "Value"); + if (value == NULL) value = ""; + + /* create elemet */ + rnd_actionva(hl, "ElementList", "Need", refdes, footprint, value, NULL); +/* printf("Elem '%s' -> %s:%s:%s\n", ectx->id, refdes, footprint, value);*/ + } + else + rnd_message(RND_MSG_ERROR, "Ignoring part %s: no refdes\n", ectx->id); + + /* free */ + for (e = htsp_first(&ectx->attr); e; e = htsp_next(&ectx->attr, e)) { + free(e->key); + free(e->value); + } + htsp_uninit(&ectx->attr); + free(ectx->id); + if (ectx->alloced) + free(ectx); +} + + +nethlp_net_ctx_t *nethlp_net_new(nethlp_ctx_t *nhctx, nethlp_net_ctx_t *prealloc, const char *netname) +{ + if (prealloc == NULL) { + prealloc = malloc(sizeof(nethlp_net_ctx_t)); + prealloc->alloced = 1; + } + else + prealloc->alloced = 0; + prealloc->nhctx = nhctx; + + prealloc->netname = rnd_strdup(netname); + return prealloc; +} + +void nethlp_net_add_term(rnd_hidlib_t *hl, nethlp_net_ctx_t *nctx, const char *part, const char *pin) +{ + char *refdes = htsp_get(&nctx->nhctx->id2refdes, part); + char term[256]; + if (refdes == NULL) { + rnd_message(RND_MSG_ERROR, "nethelper: can't resolve refdes of part %s\n", part); + } + rnd_snprintf(term, sizeof(term), "%s-%s", refdes, pin); + rnd_actionva(hl, "Netlist", "Add", nctx->netname, term, NULL); +} + +void nethlp_net_destroy(nethlp_net_ctx_t *nctx) +{ + free(nctx->netname); + if (nctx->alloced) + free(nctx); +} + Index: tags/2.3.0/src_plugins/import_mentor_sch/netlist_helper.h =================================================================== --- tags/2.3.0/src_plugins/import_mentor_sch/netlist_helper.h (nonexistent) +++ tags/2.3.0/src_plugins/import_mentor_sch/netlist_helper.h (revision 33253) @@ -0,0 +1,51 @@ +#include +#include +#include + +typedef struct nethlp_rule_s nethlp_rule_t; + +#define nethlp_prio_always -1 + +struct nethlp_rule_s { + int prio; + re_se_t *key; + re_se_t *val; + char *new_key; + char *new_val; + nethlp_rule_t *next; +}; + +typedef struct { + htsp_t id2refdes; /* element ID -> refdes */ + nethlp_rule_t *part_rules; + int alloced; +} nethlp_ctx_t; + +typedef struct { + htsp_t attr; + char *id; + nethlp_ctx_t *nhctx; + int alloced; +} nethlp_elem_ctx_t; + +typedef struct { + char *netname; + nethlp_ctx_t *nhctx; + int alloced; +} nethlp_net_ctx_t; + + +nethlp_ctx_t *nethlp_new(nethlp_ctx_t *prealloc); +void nethlp_destroy(nethlp_ctx_t *nhctx); + +int nethlp_load_part_map(nethlp_ctx_t *nhctx, const char *fn); + +nethlp_elem_ctx_t *nethlp_elem_new(nethlp_ctx_t *nhctx, nethlp_elem_ctx_t *prealloc, const char *id); +void nethlp_elem_refdes(nethlp_elem_ctx_t *ectx, const char *refdes); +void nethlp_elem_attr(nethlp_elem_ctx_t *ectx, const char *key, const char *val); +void nethlp_elem_done(rnd_hidlib_t *hl, nethlp_elem_ctx_t *ectx); + + +nethlp_net_ctx_t *nethlp_net_new(nethlp_ctx_t *nhctx, nethlp_net_ctx_t *prealloc, const char *netname); +void nethlp_net_add_term(rnd_hidlib_t *hl, nethlp_net_ctx_t *nctx, const char *part, const char *pin); +void nethlp_net_destroy(nethlp_net_ctx_t *nctx); Index: tags/2.3.0/src_plugins/import_mucs/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_mucs/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_mucs/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_mucs + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_mucs/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_mucs/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_mucs/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {import_mucs} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_mucs/mucs.o @] +put /local/pcb/mod/MENUFILE {mucs-menu.lht} +put /local/pcb/mod/MENUVAR {mucs_menu} + +switch /local/pcb/import_mucs/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_mucs/import_mucs.pup =================================================================== --- tags/2.3.0/src_plugins/import_mucs/import_mucs.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_mucs/import_mucs.pup (revision 33253) @@ -0,0 +1,10 @@ +$class import +$short import mucs routing +$long Import lines and vias from MUCS unixplot .pl files +$state works +$fmt-native no +$fmt-feature-r MUCS unixplot .pl (lines and vias) +$package auto +default buildin +dep lib_compat_help +autoload 1 Index: tags/2.3.0/src_plugins/import_mucs/mucs-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_mucs/mucs-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_mucs/mucs-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_geo { + li:submenu { + ha:Load MUCS pl file = { action=LoadMucsFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/import_mucs/mucs.c =================================================================== --- tags/2.3.0/src_plugins/import_mucs/mucs.c (nonexistent) +++ tags/2.3.0/src_plugins/import_mucs/mucs.c (revision 33253) @@ -0,0 +1,177 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * MUCS unixplot import HID + * pcb-rnd Copyright (C) 2017 Erich Heinzle + * Based on up2pcb.cc, a simple unixplot file to pcb syntax converter + * Copyright (C) 2001 Luis Claudio Gamboa Lopes + * And loosely based on dsn.c + * Copyright (C) 2008, 2011 Josh Jordan, Dan McMahill, and Jared Casper + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* This plugin imports unixplot format line and via data into pcb-rnd */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "data.h" +#include +#include +#include +#include +#include +#include +#include +#include "layer.h" +#include "conf_core.h" +#include "src_plugins/lib_compat_help/pstk_compat.h" + +#include "menu_internal.c" + +static const char *mucs_cookie = "mucs importer"; + +static const char pcb_acts_LoadMucsFrom[] = "LoadMucsFrom(filename)"; +static const char pcb_acth_LoadMucsFrom[] = "Loads the specified mucs routing file."; +fgw_error_t pcb_act_LoadMucsFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + static char *default_file = NULL; + FILE *fi; + int c, c2; + rnd_coord_t x1, y1, x2, y2, r; + pcb_pstk_t *ps; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadMucsFrom, fname = argv[1].val.str); + + if (!(pcb_layer_flags(PCB, PCB_CURRLID(PCB)) & PCB_LYT_COPPER)) { + rnd_message(RND_MSG_ERROR, "The currently active layer is not a copper layer.\n"); + RND_ACT_IRES(1); + return 0; + } + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Load mucs routing session Resource File...", + "Picks a mucs session resource file to load.\n" + "This file could be generated by mucs-pcb\n", + default_file, ".l1", NULL, "unixplot", RND_HID_FSD_READ, NULL); + if (fname == NULL) { + RND_ACT_IRES(1); + return 0; + } + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + + if (fname && *fname) + default_file = rnd_strdup(fname); + } + + fi = rnd_fopen(&PCB->hidlib, fname, "r"); + if (!fi) { + rnd_message(RND_MSG_ERROR, "Can't load mucs unixplot file %s for read\n", fname); + RND_ACT_IRES(1); + return 0; + } + + while ((c = getc(fi)) != EOF) { +/* rnd_trace("Char: %d \n", c); */ + switch (c) { + case 's': + x1 = 100 * (getc(fi) + (getc(fi) * 256)); + y1 = 100 * (getc(fi) + (getc(fi) * 256)); + x2 = 100 * (getc(fi) + (getc(fi) * 256)); + y2 = 100 * (getc(fi) + (getc(fi) * 256)); + rnd_trace("s--%i %i %i %i ???\n", x1, y1, x2, y2); + break; + case 'l': + x1 = (getc(fi) + (getc(fi) * 256)); + y1 = (getc(fi) + (getc(fi) * 256)); + x2 = (getc(fi) + (getc(fi) * 256)); + y2 = (getc(fi) + (getc(fi) * 256)); + rnd_trace("Line(%d %d %d %d 20 \" \")\n", x1, y1, x2, y2); + /* consider a bounds checking function to censor absurd coord sizes */ + pcb_line_new(PCB_CURRLAYER(PCB), RND_MIL_TO_COORD(x1), RND_MIL_TO_COORD(y1), RND_MIL_TO_COORD(x2), RND_MIL_TO_COORD(y2), RND_MIL_TO_COORD(10), RND_MIL_TO_COORD(10), pcb_flag_make(PCB_FLAG_AUTO)); + break; + case 'c': + x1 = (getc(fi) + (getc(fi) * 256)); + y1 = (getc(fi) + (getc(fi) * 256)); + r = (getc(fi) + (getc(fi) * 256)); + rnd_trace("Via(%d %d 60 25 \"\" \" \")\n", x1, y1); + ps = pcb_pstk_new_compat_via(PCB->Data, -1, RND_MIL_TO_COORD(x1), RND_MIL_TO_COORD(y1), conf_core.design.via_drilling_hole, conf_core.design.via_thickness, conf_core.design.clearance, 0, PCB_PSTK_COMPAT_ROUND, 1); + PCB_FLAG_SET(PCB_FLAG_AUTO, ps); + break; + case 'n': + x1 = (getc(fi) + (getc(fi) * 256)); + y1 = (getc(fi) + (getc(fi) * 256)); + rnd_trace("Line(%d %d %d %d 20 \" \")\n", x1, y1, x2, y2); + pcb_line_new(PCB_CURRLAYER(PCB), RND_MIL_TO_COORD(x1), RND_MIL_TO_COORD(y1), RND_MIL_TO_COORD(x2), RND_MIL_TO_COORD(y2), RND_MIL_TO_COORD(10), RND_MIL_TO_COORD(10), pcb_flag_make(PCB_FLAG_AUTO)); + x2 = x1; + y2 = y1; + break; + case 'a': + x1 = 100 * ((getc(fi) * 256) + getc(fi)); + y1 = 100 * ((getc(fi) * 256) + getc(fi)); + x2 = 100 * ((getc(fi) * 256) + getc(fi)); + y2 = 100 * ((getc(fi) * 256) + getc(fi)); + r = 100 * ((getc(fi) * 256) + getc(fi)); + rnd_trace("a--stroke newpath\n%d %d %d %d %d arc\n", x1, y1, x2, y2, r); + break; + case 'e': + break; + case 't': + do { + c2 = getc(fi); + } while (c2 != '\0' && c2 != EOF); + break; + } + } + fclose(fi); + RND_ACT_IRES(0); + return 0; +} + +rnd_action_t mucs_action_list[] = { + {"LoadMucsFrom", pcb_act_LoadMucsFrom, pcb_acth_LoadMucsFrom, pcb_acts_LoadMucsFrom} +}; + +int pplg_check_ver_import_mucs(int ver_needed) { return 0; } + +void pplg_uninit_import_mucs(void) +{ + rnd_remove_actions_by_cookie(mucs_cookie); + rnd_hid_menu_unload(rnd_gui, mucs_cookie); +} + +int pplg_init_import_mucs(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(mucs_action_list, mucs_cookie) + rnd_hid_menu_load(rnd_gui, NULL, mucs_cookie, 125, NULL, 0, mucs_menu, "plugin: import_mucs"); + return 0; +} Index: tags/2.3.0/src_plugins/import_net_action/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_net_action/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_net_action/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_net_action + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_net_action/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_net_action/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_net_action/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {import_net_action} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_net_action/import_net_action.o @] + +switch /local/pcb/import_net_action/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_net_action/import_net_action.c =================================================================== --- tags/2.3.0/src_plugins/import_net_action/import_net_action.c (nonexistent) +++ tags/2.3.0/src_plugins/import_net_action/import_net_action.c (revision 33253) @@ -0,0 +1,129 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * netlist action import HID + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "undo.h" +#include "actions_pcb.h" +#include "plug_import.h" + +#include +#include +#include +#include + +#include +#include +#include + +static int net_action_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + FILE *f; + unsigned int good = 0, l; + + if ((aspects != IMPORT_ASPECT_NETLIST) || (numargs != 1)) + return 0; /* only pure netlist import is supported from a single file*/ + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + for(l = 0; l < 32; l++) { + char *s, *n, line[1024]; + s = fgets(line, sizeof(line), f); + if (s == NULL) + break; + for(n = s; *n != '\0'; n++) + *n = tolower(*n); + if (strstr(s, "netlist") != NULL) { + if (strstr(s, "freeze") != NULL) good |= 1; + if (strstr(s, "clear") != NULL) good |= 2; + if (strstr(s, "thaw") != NULL) good |= 2; + } + if (strstr(s, "elementlist") != NULL) { + if (strstr(s, "start") != NULL) good |= 1; + if (strstr(s, "need") != NULL) good |= 2; + } + if (good == (1|2)) { + fclose(f); + return 100; + } + } + + fclose(f); + return 0; +} + + +static int net_action_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + if (numargs != 1) { + rnd_message(RND_MSG_ERROR, "import_net_action: requires exactly 1 input file name\n"); + return -1; + } + pcb_undo_freeze_serial(); + pcb_act_execute_file(&PCB->hidlib, args[0]); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + return 0; /* some parts of the script may fail (e.g. footprint not found) - that doesn't mean a real error */ +} + +static pcb_plug_import_t import_net_action; + +int pplg_check_ver_import_net_action(int ver_needed) { return 0; } + +void pplg_uninit_import_net_action(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_net_action); +} + +int pplg_init_import_net_action(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_net_action.plugin_data = NULL; + + import_net_action.fmt_support_prio = net_action_support_prio; + import_net_action.import = net_action_import; + import_net_action.name = "action"; + import_net_action.desc = "schamtics from pcb-rnd action script"; + import_net_action.ui_prio = 95; + import_net_action.single_arg = 1; + import_net_action.all_filenames = 1; + import_net_action.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_net_action); + + return 0; +} Index: tags/2.3.0/src_plugins/import_net_action/import_net_action.pup =================================================================== --- tags/2.3.0/src_plugins/import_net_action/import_net_action.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_net_action/import_net_action.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import net: action script +$long Import the netlist and footprints from an action script. +$state works +$fmt-native no +$fmt-feature-r pcb-rnd action script (netlist + footprint info) +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_net_cmd/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_net_cmd/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_net_cmd/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_import_net_cmd + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/import_net_cmd/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_net_cmd/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_net_cmd/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {import_net_cmd} +append /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_net_cmd/import_net_cmd.o @] + +switch /local/pcb/import_net_cmd/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_net_cmd/import_net_cmd.c =================================================================== --- tags/2.3.0/src_plugins/import_net_cmd/import_net_cmd.c (nonexistent) +++ tags/2.3.0/src_plugins/import_net_cmd/import_net_cmd.c (revision 33253) @@ -0,0 +1,122 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "board.h" +#include "undo.h" +#include "plug_import.h" + +static pcb_plug_import_t import_net_cmd; + + +int net_cmd_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + return 0; /* autodetect should always fail to avoid accidental command execution - the import shall work only directly */ +} + + +static int net_cmd_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + int res, verbose; + const char *cmdline, *outfn; + char *tmpfn = NULL; + + PCB_IMPORT_SCH_VERBOSE(verbose); + + if (numfns != 2) { + rnd_message(RND_MSG_ERROR, "net_cmd_import: requires exactly two arguments:\nfirst argument must be the output file name or -\nsecond argument must be a full command line\n"); + return -1; + } + + outfn = fns[0]; + cmdline = fns[1]; + + if ((outfn == NULL) || (*outfn == '\0')) { + rnd_message(RND_MSG_ERROR, "net_cmd_import: Could not create temp file for the netlist output"); + return -1; + } + if ((outfn[0] == '-') && (outfn[1] == '\0')) { + tmpfn = rnd_tempfile_name_new("net_cmd_output"); + outfn = tmpfn; + } + + if (verbose) + rnd_message(RND_MSG_DEBUG, "import_net_cmd: running cmd: '%s' outfn='%s'\n", cmdline, outfn); + + if (PCB->hidlib.filename != NULL) + rnd_setenv("IMPORT_NET_CMD_PCB", PCB->hidlib.filename, 1); + rnd_setenv("IMPORT_NET_CMD_OUT", outfn, 1); + res = rnd_system(&PCB->hidlib, cmdline); + if (res == 0) { + if (verbose) + rnd_message(RND_MSG_DEBUG, "pcb_net_cmd: about to run pcb_act_ExecuteFile, outfn='%s'\n", outfn); + pcb_undo_freeze_serial(); + pcb_import_netlist(&PCB->hidlib, outfn); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + } + if (tmpfn != NULL) + rnd_tempfile_unlink(tmpfn); + return res; +} + +int pplg_check_ver_import_net_cmd(int ver_needed) { return 0; } + +void pplg_uninit_import_net_cmd(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_net_cmd); +} + +int pplg_init_import_net_cmd(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_net_cmd.plugin_data = NULL; + + import_net_cmd.fmt_support_prio = net_cmd_support_prio; + import_net_cmd.import = net_cmd_import; + import_net_cmd.name = "cmd"; + import_net_cmd.desc = "sch/netlist by command line"; + import_net_cmd.ui_prio = 90; + import_net_cmd.single_arg = 0; + import_net_cmd.all_filenames = 0; + import_net_cmd.ext_exec = 1; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_net_cmd); + + return 0; +} + Index: tags/2.3.0/src_plugins/import_net_cmd/import_net_cmd.pup =================================================================== --- tags/2.3.0/src_plugins/import_net_cmd/import_net_cmd.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_net_cmd/import_net_cmd.pup (revision 33253) @@ -0,0 +1,10 @@ +$class import +$short sch/net import: run custom cmd +$long Import schematics/netlist by running a commandline +$state works +$fmt-native no +$fmt-feature-r schematics import by running a commandline +$fmt-feature-r netlist import by running a commandline +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_netlist/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_netlist/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_netlist/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_import_netlist + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/import_netlist/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_netlist/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_netlist/Plug.tmpasm (revision 33253) @@ -0,0 +1,9 @@ +put /local/pcb/mod {import_netlist} +append /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_netlist/import_netlist.o @] +append /local/pcb/mod/YACC {$(PLUGDIR)/import_netlist/netlist} + +switch /local/pcb/import_netlist/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_netlist/import_netlist.c =================================================================== --- tags/2.3.0/src_plugins/import_netlist/import_netlist.c (nonexistent) +++ tags/2.3.0/src_plugins/import_netlist/import_netlist.c (revision 33253) @@ -0,0 +1,214 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,1997,1998,2005,2006 Thomas Nau + * Copyright (C) 2015,2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include "board.h" +#include +#include "plug_io.h" +#include "plug_import.h" +#include "conf_core.h" +#include +#include "data.h" +#include "undo.h" +#include "rats_patch.h" +#include +#include +#include +#include "netlist.h" + +static pcb_plug_import_t import_netlist; + + +#define BLANK(x) ((x) == ' ' || (x) == '\t' || (x) == '\n' \ + || (x) == '\0') + +/* --------------------------------------------------------------------------- + * Read in a netlist and store it in the netlist menu + */ +static int ReadNetlist(const char *filename) +{ + char *command = NULL; + char inputline[RND_MAX_NETLIST_LINE_LENGTH + 1]; + char temp[RND_MAX_NETLIST_LINE_LENGTH + 1]; + FILE *fp; + pcb_net_t *net = NULL; + int i, j, lines, kind; + rnd_bool continued; + int used_popen = 0; + const char *ratcmd; + + if (!filename) + return 1; /* nothing to do */ + + rnd_message(RND_MSG_INFO, "Importing PCB netlist %s\n", filename); + + ratcmd = conf_core.rc.rat_command; + if (RND_EMPTY_STRING_P(ratcmd)) { + fp = rnd_fopen(&PCB->hidlib, filename, "r"); + if (!fp) { + rnd_message(RND_MSG_ERROR, "Cannot open %s for reading", filename); + return 1; + } + } + else { + rnd_build_argfn_t p; + used_popen = 1; + memset(&p, 0, sizeof(p)); + p.params['p'-'a'] = conf_core.rc.rat_path; + p.params['f'-'a'] = filename; + p.hidlib = &PCB->hidlib; + command = rnd_build_argfn(conf_core.rc.rat_command, &p); + + /* open pipe to stdout of command */ + if (*command == '\0' || (fp = rnd_popen(&PCB->hidlib, command, "r")) == NULL) { + rnd_popen_error_message(command); + free(command); + return 1; + } + free(command); + } + lines = 0; + /* kind = 0 is net name + * kind = 1 is route style name + * kind = 2 is connection + */ + kind = 0; + while (fgets(inputline, RND_MAX_NETLIST_LINE_LENGTH, fp)) { + size_t len = strlen(inputline); + /* check for maximum length line */ + if (len) { + if (inputline[--len] != '\n') + rnd_message(RND_MSG_ERROR, "Line length (%i) exceeded in netlist file.\n" + "additional characters will be ignored.\n", RND_MAX_NETLIST_LINE_LENGTH); + else + inputline[len] = '\0'; + } + continued = (inputline[len - 1] == '\\') ? rnd_true : rnd_false; + if (continued) + inputline[len - 1] = '\0'; + lines++; + i = 0; + while (inputline[i] != '\0') { + j = 0; + /* skip leading blanks */ + while (inputline[i] != '\0' && BLANK(inputline[i])) + i++; + while (!BLANK(inputline[i])) + temp[j++] = inputline[i++]; + temp[j] = '\0'; + while (inputline[i] != '\0' && BLANK(inputline[i])) + i++; + if (kind == 0) { + if (!pcb_net_name_valid(temp)) + rnd_message(RND_MSG_ERROR, "gEDA/PCB netlist: invalid net name: '%s'\n", temp); + net = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_INPUT], temp, PCB_NETA_ALLOC); + kind++; + } + else { + if (kind == 1 && strchr(temp, '-') == NULL) { + kind++; + pcb_attribute_put(&net->Attributes, "style", temp); + } + else { + pcb_net_term_get_by_pinname(net, temp, PCB_NETA_ALLOC); + } + } + } + if (!continued) + kind = 0; + } + if (!lines) { + rnd_message(RND_MSG_ERROR, "Empty netlist file!\n"); + rnd_pclose(fp); + return 1; + } + if (used_popen) + rnd_pclose(fp); + else + fclose(fp); + pcb_ratspatch_make_edited(PCB); + return 0; +} + +static int netlist_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + if (aspects != IMPORT_ASPECT_NETLIST) + return 0; /* only pure netlist import is supported */ + + /* we are sort of a low prio fallback without any chance to check the file format in advance */ + return 11; +} + + +static int netlist_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + int res; + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_netlist: requires exactly 1 input file name\n"); + return -1; + } + + pcb_undo_freeze_serial(); + res = ReadNetlist(fns[0]); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + return res; +} + +int pplg_check_ver_import_netlist(int ver_needed) { return 0; } + +void pplg_uninit_import_netlist(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_netlist); +} + +int pplg_init_import_netlist(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_netlist.plugin_data = NULL; + + import_netlist.fmt_support_prio = netlist_support_prio; + import_netlist.import = netlist_import; + import_netlist.name = "gEDA"; + import_netlist.desc = "gEDA/PCB netlist file"; + import_netlist.ui_prio = 20; + import_netlist.single_arg = 1; + import_netlist.all_filenames = 1; + import_netlist.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_netlist); + + return 0; +} + Index: tags/2.3.0/src_plugins/import_netlist/import_netlist.pup =================================================================== --- tags/2.3.0/src_plugins/import_netlist/import_netlist.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_netlist/import_netlist.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import netlist +$long Import plugin for netlists in the classic pcb netlist format. +$state works +$fmt-native no +$fmt-feature-r gEDA netlist (plain text, no footprint info) +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_orcad_net/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_orcad_net/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_orcad_net/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_orcad_net + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_orcad_net/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_orcad_net/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_orcad_net/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {import_orcad_net} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_orcad_net/orcad_net.o @] +put /local/pcb/mod/MENUFILE {orcad_net-menu.lht} +put /local/pcb/mod/MENUVAR {orcad_net_menu} + +switch /local/pcb/import_orcad_net/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_orcad_net/import_orcad_net.pup =================================================================== --- tags/2.3.0/src_plugins/import_orcad_net/import_orcad_net.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_orcad_net/import_orcad_net.pup (revision 33253) @@ -0,0 +1,10 @@ +$class import +$short import Orcad netlist +$long Import the netlist and footprints from a Orcad netlist. +$state works +$fmt-native no +$fmt-feature-r Orcad PCB II (netlist + footprint info) +$package import-net +default buildin +dep lib_gensexpr +autoload 1 Index: tags/2.3.0/src_plugins/import_orcad_net/orcad_net-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_orcad_net/orcad_net-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_orcad_net/orcad_net-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Load Orcad PCB II netlist file = { action=LoadOrcadNetFrom() } + } + } + } +} Index: tags/2.3.0/src_plugins/import_orcad_net/orcad_net.c =================================================================== --- tags/2.3.0/src_plugins/import_orcad_net/orcad_net.c (nonexistent) +++ tags/2.3.0/src_plugins/import_orcad_net/orcad_net.c (revision 33253) @@ -0,0 +1,244 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * sch import: orcad netlist + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "plug_import.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "menu_internal.c" + +static const char *orcad_net_cookie = "orcad_net importer"; + +static int orcad_net_parse_net(FILE *fn) +{ + gsxl_dom_t dom; + gsxl_node_t *n, *footprint, *refdes, *noise, *net; + int res, c, restore; + gds_t tmp; + + gds_init(&tmp); + gsxl_init(&dom, gsxl_node_t); + + dom.parse.line_comment_char = '#'; + dom.parse.brace_quote = 1; + do { + c = fgetc(fn); + } while((res = gsxl_parse_char(&dom, c)) == GSX_RES_NEXT); + + if (res != GSX_RES_EOE) { + rnd_message(RND_MSG_ERROR, "orcad: s-expression parse error\n"); + return -1; + } + + /* compact and simplify the tree */ + gsxl_compact_tree(&dom); + + + rnd_actionva(&PCB->hidlib, "ElementList", "start", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + + for(n = dom.root->children; n != NULL; n = n->next) { + footprint = n->children; + if ((footprint == NULL) || (footprint->next == NULL) || (footprint->next->next == NULL)) { + rnd_message(RND_MSG_ERROR, "orcad: missing footprint or refdes in %d:%d\n", n->line, n->col); + continue; + } + refdes = footprint->next; + noise = refdes->next; + +/*pcb_trace("@ '%s' '%s'\n", footprint->str, refdes->str);*/ + rnd_actionva(&PCB->hidlib, "ElementList", "Need", refdes->str, footprint->str, "", NULL); + + tmp.used = 0; + gds_append_str(&tmp, refdes->str); + gds_append(&tmp, '-'); + restore = tmp.used; + + for(net = noise->next; net != NULL; net = net->next) { + if (net->children == NULL) { + rnd_message(RND_MSG_ERROR, "orcad: missing terminal ID in %d:%d\n", n->line, n->col); + continue; + } + + tmp.used = restore; + gds_append_str(&tmp, net->str); + rnd_actionva(&PCB->hidlib, "Netlist", "Add", net->children->str, tmp.array, NULL); +/*pcb_trace(" net %s %s\n", tmp.array, net->children->str);*/ + } + } + + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + rnd_actionva(&PCB->hidlib, "ElementList", "Done", NULL); + + gsxl_uninit(&dom); + gds_uninit(&tmp); + return 0; +} + + +static int orcad_net_load(const char *fname_net) +{ + FILE *fn; + int ret = 0; + + fn = rnd_fopen(&PCB->hidlib, fname_net, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname_net); + return -1; + } + + pcb_undo_freeze_serial(); + ret = orcad_net_parse_net(fn); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + fclose(fn); + return ret; +} + +static const char pcb_acts_LoadOrcadNetFrom[] = "LoadOrcadNetFrom(filename)"; +static const char pcb_acth_LoadOrcadNetFrom[] = "Loads the specified Orcad netlist file."; +fgw_error_t pcb_act_LoadOrcadNetFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + static char *default_file = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadOrcadNetFrom, fname = argv[1].val.str); + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Load pads ascii netlist file...", + "Picks a pads ascii netlist file to load.\n", + default_file, ".net", NULL, "orcad_net", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 1; + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + RND_ACT_IRES(0); + return orcad_net_load(fname); +} + +static int orcad_net_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + FILE *f; + unsigned int limit; + + if ((aspects != IMPORT_ASPECT_NETLIST) || (numargs != 1)) + return 0; /* only pure netlist import is supported from a single file*/ + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + for(limit = 0; limit < 8; limit++) { + char *s, line[1024]; + s = fgets(line, sizeof(line), f); + if (s == NULL) + break; + while(isspace(*s)) s++; + if (strstr(s, "OrCAD/PCB II Netlist") != NULL) { + fclose(f); + return 100; + } + } + + fclose(f); + + return 0; +} + + +static int orcad_net_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_orcad_net: requires exactly 1 input file name\n"); + return -1; + } + return orcad_net_load(fns[0]); +} + +static pcb_plug_import_t import_orcad_net; + +rnd_action_t orcad_net_action_list[] = { + {"LoadOrcadNetFrom", pcb_act_LoadOrcadNetFrom, pcb_acth_LoadOrcadNetFrom, pcb_acts_LoadOrcadNetFrom} +}; + +int pplg_check_ver_import_orcad_net(int ver_needed) { return 0; } + +void pplg_uninit_import_orcad_net(void) +{ + rnd_remove_actions_by_cookie(orcad_net_cookie); + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_orcad_net); + rnd_hid_menu_unload(rnd_gui, orcad_net_cookie); +} + +int pplg_init_import_orcad_net(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_orcad_net.plugin_data = NULL; + + import_orcad_net.fmt_support_prio = orcad_net_support_prio; + import_orcad_net.import = orcad_net_import; + import_orcad_net.name = "orcad_net"; + import_orcad_net.desc = "schamtics from orcad netlist"; + import_orcad_net.ui_prio = 50; + import_orcad_net.single_arg = 1; + import_orcad_net.all_filenames = 1; + import_orcad_net.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_orcad_net); + + RND_REGISTER_ACTIONS(orcad_net_action_list, orcad_net_cookie) + rnd_hid_menu_load(rnd_gui, NULL, orcad_net_cookie, 175, NULL, 0, orcad_net_menu, "plugin: import orcad_net"); + return 0; +} Index: tags/2.3.0/src_plugins/import_pads_net/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_pads_net/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_pads_net/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_pads_net + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_pads_net/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_pads_net/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_pads_net/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {import_pads_net} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_pads_net/pads_net.o @] +put /local/pcb/mod/MENUFILE {pads_net-menu.lht} +put /local/pcb/mod/MENUVAR {pads_net_menu} + +switch /local/pcb/import_pads_net/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_pads_net/import_pads_net.pup =================================================================== --- tags/2.3.0/src_plugins/import_pads_net/import_pads_net.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_pads_net/import_pads_net.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import PADS ascii netlist .asc +$long Import the netlist and footprints from a PADS netlist. +$state works +$fmt-native no +$fmt-feature-r PADS ascii (.asc, netlists + footprint info) +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_pads_net/pads_net-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_pads_net/pads_net-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_pads_net/pads_net-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Load PADS ASCII .asc file = { action=LoadPadsNetFrom() } + } + } + } +} Index: tags/2.3.0/src_plugins/import_pads_net/pads_net.c =================================================================== --- tags/2.3.0/src_plugins/import_pads_net/pads_net.c (nonexistent) +++ tags/2.3.0/src_plugins/import_pads_net/pads_net.c (revision 33253) @@ -0,0 +1,263 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * sch import: PADS netlist ASCII (powerpcb?) + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "plug_import.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "menu_internal.c" + +static const char *pads_net_cookie = "pads_net importer"; + +/* remove leading whitespace */ +#define ltrim(s) while(isspace(*s)) s++ + +/* remove trailing newline */ +#define rtrim(s) \ + do { \ + char *end; \ + for(end = s + strlen(s) - 1; (end >= s) && ((*end == '\r') || (*end == '\n')); end--) \ + *end = '\0'; \ + } while(0) +static int pads_net_parse_net(FILE *fn) +{ + char line[1024], signal[1024]; + enum { NONE, NET, PART } mode = NONE; + + rnd_actionva(&PCB->hidlib, "ElementList", "start", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + + *signal = '\0'; + + while(fgets(line, sizeof(line), fn) != NULL) { + char *s, *next, *pin; + + s = line; + ltrim(s); + rtrim(s); + + if (strcmp(s, "*NET*") == 0) { mode = NET; continue; } + if (strncmp(s, "*PART*", 6) == 0) { mode = PART; continue; } + if (strcmp(s, "*END*") == 0) { break; } + + if (strncmp(s, "*SIGNAL*", 8) == 0) { + s = line + 8; + ltrim(s); + strncpy(signal, s, sizeof(signal)); + continue; + } + + switch(mode) { + case NONE: break; + case PART: + next = strchr(s, ' '); + if (next == NULL) { + rnd_message(RND_MSG_ERROR, "pads_net: not importing part=%s: no footprint specified\n", s); + break; + } + *next = '\0'; + next++; + ltrim(next); + rnd_actionva(&PCB->hidlib, "ElementList", "Need", s, next, "", NULL); + break; + case NET: + if (*signal == '\0') { + rnd_message(RND_MSG_ERROR, "pads_net: not importing net=%s: no signal specified\n", line); + continue; + } + for(s = line; (s != NULL) && (*s != '\0'); s = next) { + next = strpbrk(s, " \t"); + if (next != NULL) { + *next = '\0'; + next++; + ltrim(next); + } + pin = strchr(s, '.'); + if (pin == NULL) { + rnd_message(RND_MSG_ERROR, "pads_net: not importing pin='%s' for net %s: no terminal ID\n", s, signal); + continue; + } + *pin = '-'; + rnd_actionva(&PCB->hidlib, "Netlist", "Add", signal, s, NULL); + } + break; + } + } + + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + rnd_actionva(&PCB->hidlib, "ElementList", "Done", NULL); + + return 0; +} + + +static int pads_net_load(const char *fname_net) +{ + FILE *fn; + int ret = 0; + + fn = rnd_fopen(&PCB->hidlib, fname_net, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname_net); + return -1; + } + + pcb_undo_freeze_serial(); + ret = pads_net_parse_net(fn); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + fclose(fn); + return ret; +} + +static const char pcb_acts_LoadPadsNetFrom[] = "LoadPadsNetFrom(filename)"; +static const char pcb_acth_LoadPadsNetFrom[] = "Loads the specified pads ascii netlist .asc file."; +fgw_error_t pcb_act_LoadPadsNetFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + static char *default_file = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadPadsNetFrom, fname = argv[1].val.str); + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Load pads ascii netlist file...", + "Picks a pads ascii netlist file to load.\n", + default_file, ".asc", NULL, "pads_net", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 1; + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + RND_ACT_IRES(0); + return pads_net_load(fname); +} + +static int pads_net_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + FILE *f; + unsigned int good = 0; + + if ((aspects != IMPORT_ASPECT_NETLIST) || (numargs != 1)) + return 0; /* only pure netlist import is supported from a single file*/ + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + for(;;) { + char *s, line[1024]; + s = fgets(line, sizeof(line), f); + if (s == NULL) + break; + while(isspace(*s)) s++; + if (strncmp(s, "!PADS-", 6) == 0) + good |= 1; + else if (strncmp(s, "*PART*", 6) == 0) + good |= 2; + else if (strncmp(s, "*NET*", 5) == 0) + good |= 4; + if (good == (1|2|4)) { + fclose(f); + return 100; + } + } + + fclose(f); + + return 0; +} + + +static int pads_net_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_pads_net: requires exactly 1 input file name\n"); + return -1; + } + return pads_net_load(fns[0]); +} + +static pcb_plug_import_t import_pads_net; + +rnd_action_t pads_net_action_list[] = { + {"LoadPadsNetFrom", pcb_act_LoadPadsNetFrom, pcb_acth_LoadPadsNetFrom, pcb_acts_LoadPadsNetFrom} +}; + +int pplg_check_ver_import_pads_net(int ver_needed) { return 0; } + +void pplg_uninit_import_pads_net(void) +{ + rnd_remove_actions_by_cookie(pads_net_cookie); + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_pads_net); + rnd_hid_menu_unload(rnd_gui, pads_net_cookie); +} + +int pplg_init_import_pads_net(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_pads_net.plugin_data = NULL; + + import_pads_net.fmt_support_prio = pads_net_support_prio; + import_pads_net.import = pads_net_import; + import_pads_net.name = "pads_net"; + import_pads_net.desc = "schamtics from pads ascii netlist"; + import_pads_net.ui_prio = 50; + import_pads_net.single_arg = 1; + import_pads_net.all_filenames = 1; + import_pads_net.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_pads_net); + + RND_REGISTER_ACTIONS(pads_net_action_list, pads_net_cookie) + rnd_hid_menu_load(rnd_gui, NULL, pads_net_cookie, 175, NULL, 0, pads_net_menu, "plugin: import pads_net"); + return 0; +} Index: tags/2.3.0/src_plugins/import_protel_net/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_protel_net/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_protel_net/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_protel_net + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_protel_net/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_protel_net/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_protel_net/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {import_protel_net} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_protel_net/protel_net.o @] +put /local/pcb/mod/MENUFILE {protel_net-menu.lht} +put /local/pcb/mod/MENUVAR {protel_net_menu} + +switch /local/pcb/import_protel_net/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_protel_net/import_protel_net.pup =================================================================== --- tags/2.3.0/src_plugins/import_protel_net/import_protel_net.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_protel_net/import_protel_net.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import Protel netlist 2.0 +$long Import the netlist and footprints from a Protel netlist. +$state works +$fmt-native no +$fmt-feature-r Protel netlists 2.0 + footprint info +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_protel_net/protel_net-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_protel_net/protel_net-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_protel_net/protel_net-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Load Protel netlist 2.0 file = { action=LoadProtelNetFrom() } + } + } + } +} Index: tags/2.3.0/src_plugins/import_protel_net/protel_net.c =================================================================== --- tags/2.3.0/src_plugins/import_protel_net/protel_net.c (nonexistent) +++ tags/2.3.0/src_plugins/import_protel_net/protel_net.c (revision 33253) @@ -0,0 +1,282 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * sch import: Protel netlist 2.0 + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "plug_import.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "menu_internal.c" + +static const char *protel_net_cookie = "protel_net importer"; + +/* remove leading whitespace */ +#define ltrim(s) while(isspace(*s)) s++ + +/* remove trailing newline */ +#define rtrim(s) \ + do { \ + char *end; \ + for(end = s + strlen(s) - 1; (end >= s) && ((*end == '\r') || (*end == '\n')); end--) \ + *end = '\0'; \ + } while(0) + +#define LOAD(dst) \ +do { \ + dst.used = 0; \ + *line = '\0'; \ + fgets(line, sizeof(line), fn); \ + s = line; \ + ltrim(s); \ + rtrim(s); \ + gds_append_str(&dst, s); \ +} while(0) + +#define FREE(dst) gds_truncate(&dst, 0) + +static int protel_net_parse_net(FILE *fn) +{ + char line[1024]; + enum { NONE, NET, PART, CFG } mode = NONE; + gds_t refdes, footprint, value, netname; + + gds_init(&refdes); + gds_init(&footprint); + gds_init(&value); + gds_init(&netname); + + rnd_actionva(&PCB->hidlib, "ElementList", "start", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + + while(fgets(line, sizeof(line), fn) != NULL) { + char *s, *end; + + s = line; + ltrim(s); + rtrim(s); + + switch(mode) { + case NONE: + if (*s == '[') + mode = PART; + else if (*s == '(') { + LOAD(netname); + mode = NET; + } + else if (*s == '{') + mode = CFG; + break; + + case PART: + if (*s == ']') { + rnd_actionva(&PCB->hidlib, "ElementList", "Need", refdes.array, footprint.array, value.array, NULL); + FREE(refdes); + FREE(footprint); + FREE(value); + mode = NONE; + } + else if (strcmp(s, "DESIGNATOR") == 0) + LOAD(refdes); + else if (strcmp(s, "FOOTPRINT") == 0) + LOAD(footprint); + else if (strcmp(s, "PARTTYPE") == 0) + LOAD(value); + break; + + case NET: + if (*s == ')') { + FREE(netname); + mode = NONE; + } + else { + end = strchr(s, ' '); + if (end != NULL) + *end = '\0'; + rnd_actionva(&PCB->hidlib, "Netlist", "Add", netname.array, s, NULL); + } + break; + + case CFG: + if (*s == '}') + mode = NONE; + break; + } + } + + if (mode != NONE) + rnd_message(RND_MSG_ERROR, "protel: last block is not closed\n"); + + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + rnd_actionva(&PCB->hidlib, "ElementList", "Done", NULL); + + gds_uninit(&refdes); + gds_uninit(&footprint); + gds_uninit(&value); + gds_uninit(&netname); + + return 0; +} + + +static int protel_net_load(const char *fname_net) +{ + FILE *fn; + int ret = 0; + + fn = rnd_fopen(&PCB->hidlib, fname_net, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname_net); + return -1; + } + + pcb_undo_freeze_serial(); + ret = protel_net_parse_net(fn); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + fclose(fn); + return ret; +} + +static const char pcb_acts_LoadProtelNetFrom[] = "LoadProtelNetFrom(filename)"; +static const char pcb_acth_LoadProtelNetFrom[] = "Loads the specified protel netlist 2.0 file."; +fgw_error_t pcb_act_LoadProtelNetFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + static char *default_file = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadProtelNetFrom, fname = argv[1].val.str); + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Load pads ascii netlist file...", + "Picks a pads ascii netlist file to load.\n", + default_file, ".net", NULL, "protel_net", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 1; + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + RND_ACT_IRES(0); + return protel_net_load(fname); +} + +static int protel_net_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + FILE *f; + + if ((aspects != IMPORT_ASPECT_NETLIST) || (numargs != 1)) + return 0; /* only pure netlist import is supported from a single file*/ + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + for(;;) { + char *s, line[1024]; + s = fgets(line, sizeof(line), f); + if (s == NULL) + break; + while(isspace(*s)) s++; + if (strncmp(s, "PROTEL NETLIST 2.0", 18) == 0) { + fclose(f); + return 100; + } + } + + fclose(f); + + return 0; +} + + +static int protel_net_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_protel_net: requires exactly 1 input file name\n"); + return -1; + } + return protel_net_load(fns[0]); +} + +static pcb_plug_import_t import_protel_net; + +rnd_action_t protel_net_action_list[] = { + {"LoadProtelNetFrom", pcb_act_LoadProtelNetFrom, pcb_acth_LoadProtelNetFrom, pcb_acts_LoadProtelNetFrom} +}; + +int pplg_check_ver_import_protel_net(int ver_needed) { return 0; } + +void pplg_uninit_import_protel_net(void) +{ + rnd_remove_actions_by_cookie(protel_net_cookie); + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_protel_net); + rnd_hid_menu_unload(rnd_gui, protel_net_cookie); +} + +int pplg_init_import_protel_net(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_protel_net.plugin_data = NULL; + + import_protel_net.fmt_support_prio = protel_net_support_prio; + import_protel_net.import = protel_net_import; + import_protel_net.name = "protel_net"; + import_protel_net.desc = "schamtics from protel netlist 2.0"; + import_protel_net.ui_prio = 50; + import_protel_net.single_arg = 1; + import_protel_net.all_filenames = 1; + import_protel_net.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_protel_net); + + RND_REGISTER_ACTIONS(protel_net_action_list, protel_net_cookie) + rnd_hid_menu_load(rnd_gui, NULL, protel_net_cookie, 175, NULL, 0, protel_net_menu, "plugin: import protel_net"); + return 0; +} Index: tags/2.3.0/src_plugins/import_pxm_gd/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_pxm_gd/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_pxm_gd/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_import_pxm_gd + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/import_pxm_gd/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_pxm_gd/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_pxm_gd/Plug.tmpasm (revision 33253) @@ -0,0 +1,16 @@ +put /local/pcb/mod {import_pxm_gd} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_pxm_gd/import_pxm_gd.o @] + +switch /local/pcb/import_pxm_gd/controls + case {disable} end; + default + put /local/pcb/mod/LDFLAGS libs/gui/gd/ldflags + put /local/pcb/mod/CFLAGS libs/gui/gd/cflags + end +end + +switch /local/pcb/import_pxm_gd/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_pxm_gd/import_pxm_gd.c =================================================================== --- tags/2.3.0/src_plugins/import_pxm_gd/import_pxm_gd.c (nonexistent) +++ tags/2.3.0/src_plugins/import_pxm_gd/import_pxm_gd.c (revision 33253) @@ -0,0 +1,147 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * pixmap loader for pnm + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include + +static const char *import_pxm_gd_cookie = "import_pxm_gd"; + +static int gd_load(rnd_hidlib_t *hidlib, rnd_pixmap_t *pxm, const char *fn, gdImagePtr (*loader)(FILE *f)) +{ + int x, y; + gdImagePtr gdi; + FILE *f; + + f = rnd_fopen(hidlib, fn, "rb"); + if (f == NULL) + return -1; + gdi = loader(f); + if (gdi != NULL) { + unsigned char *p; + int r, g, b, a; + pxm->sx = gdi->sx; + pxm->sy = gdi->sy; + pxm->tr = pxm->tg = 127; + pxm->tb = 128; + pxm->size = pxm->sx * pxm->sy * 3; + pxm->has_transp = 0; + p = pxm->p = malloc(pxm->size); + for(y = 0; y < pxm->sy; y++) { + for(x = 0; x < pxm->sx; x++) { + int pix = gdImageGetPixel(gdi, x, y); + r = gdImageRed(gdi, pix); + g = gdImageGreen(gdi, pix); + b = gdImageBlue(gdi, pix); + a = gdImageAlpha(gdi, pix); + + if (a == 0) { + if ((r == pxm->tr) && (g == pxm->tg) && (b == pxm->tb)) + b--; + *p++ = r; + *p++ = g; + *p++ = b; + } + else { + *p++ = pxm->tr; + *p++ = pxm->tg; + *p++ = pxm->tb; + pxm->has_transp = 1; + } + } + } + } + fclose(f); + return (gdi == NULL); +} + +#ifdef RND_HAVE_GDIMAGEPNG +static int gd_png_load(rnd_hidlib_t *hidlib, rnd_pixmap_t *pxm, const char *fn) +{ + return gd_load(hidlib, pxm, fn, gdImageCreateFromPng); +} + +static const rnd_pixmap_import_t pxm_gd_png_imp = { + "png (gd)", + gd_png_load +}; +#endif + +#ifdef RND_HAVE_GDIMAGEJPEG +static int gd_jpg_load(rnd_hidlib_t *hidlib, rnd_pixmap_t *pxm, const char *fn) +{ + return gd_load(hidlib, pxm, fn, gdImageCreateFromJpeg); +} + +static const rnd_pixmap_import_t pxm_gd_jpg_imp = { + "jpg (gd)", + gd_jpg_load +}; +#endif + +#ifdef RND_HAVE_GDIMAGEGIF +static int gd_gif_load(rnd_hidlib_t *hidlib, rnd_pixmap_t *pxm, const char *fn) +{ + return gd_load(hidlib, pxm, fn, gdImageCreateFromGif); +} + +static const rnd_pixmap_import_t pxm_gd_gif_imp = { + "gif (gd)", + gd_gif_load +}; +#endif + +int pplg_check_ver_import_pxm_gd(int ver_needed) { return 0; } + +void pplg_uninit_import_pxm_gd(void) +{ + rnd_pixmap_unreg_import_all(import_pxm_gd_cookie); +} + +int pplg_init_import_pxm_gd(void) +{ + RND_API_CHK_VER; + +#ifdef RND_HAVE_GDIMAGEPNG + rnd_pixmap_reg_import(&pxm_gd_png_imp, import_pxm_gd_cookie); +#endif +#ifdef RND_HAVE_GDIMAGEJPEG + rnd_pixmap_reg_import(&pxm_gd_jpg_imp, import_pxm_gd_cookie); +#endif +#ifdef RND_HAVE_GDIMAGEGIF + rnd_pixmap_reg_import(&pxm_gd_gif_imp, import_pxm_gd_cookie); +#endif + return 0; +} Index: tags/2.3.0/src_plugins/import_pxm_gd/import_pxm_gd.pup =================================================================== --- tags/2.3.0/src_plugins/import_pxm_gd/import_pxm_gd.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_pxm_gd/import_pxm_gd.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import pixmaps from png/gif/jpg +$long Import png, gif and jpeg using libgd +$state works +$fmt-native no +$fmt-feature-r pixmap (e.g. png) +$package import-geo +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_pxm_pnm/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_pxm_pnm/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_pxm_pnm/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_import_pxm_pnm + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/import_pxm_pnm/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_pxm_pnm/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_pxm_pnm/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {import_pxm_pnm} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_pxm_pnm/import_pxm_pnm.o @] + +switch /local/pcb/import_pxm_pnm/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_pxm_pnm/import_pxm_pnm.c =================================================================== --- tags/2.3.0/src_plugins/import_pxm_pnm/import_pxm_pnm.c (nonexistent) +++ tags/2.3.0/src_plugins/import_pxm_pnm/import_pxm_pnm.c (revision 33253) @@ -0,0 +1,183 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * pixmap loader for pnm + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static const char *import_pxm_pnm_cookie = "import_pxm_pnm"; + +#define ADDPX(pxm, r_, g_, b_, not_transparent) \ +do { \ + int r = r_, g = g_, b = b_; \ + if ((r < 0) || (g < 0) || (b < 0)) \ + goto error; \ + if (not_transparent && (r == pxm->tr) && (g == pxm->tg) && (b == pxm->tb)) \ + b--; \ + *o++ = r; \ + *o++ = g; \ + *o++ = b; \ +} while(0) + +static void decode_comment(rnd_pixmap_t *pxm, char *comment) +{ + while(isspace(*comment)) comment++; + if (rnd_strncasecmp(comment, "transparent pixel:", 18) == 0) { + int r, g, b; + if (sscanf(comment+18, "%d %d %d", &r, &g, &b) == 3) { + if ((r >= 0) && (r <= 255) && (g >= 0) && (g <= 255) && (b >= 0) && (b <= 255)) { + pxm->tr = r; + pxm->tg = g; + pxm->tb = b; + pxm->has_transp = 1; + } + else + rnd_message(RND_MSG_ERROR, "pnm_load(): ignoring invalid transparent pixel: value out of range (%d %d %d)\n", r, g, b); + } + else + rnd_message(RND_MSG_ERROR, "pnm_load(): ignoring invalid transparent pixel: need 3 integers (got: %s)\n", comment+18); + } +} + +#define GETLINE \ +while(fgets(line, sizeof(line) - 1, f) != NULL) { \ + if (*line == '#') {\ + decode_comment(pxm, line+1); \ + continue; \ + } \ + break; \ +} + +static int pnm_load(rnd_hidlib_t *hidlib, rnd_pixmap_t *pxm, const char *fn) +{ + FILE *f; + char *s, line[1024]; + unsigned char *o; + int n, type; + + f = rnd_fopen(hidlib, fn, "rb"); + if (f == NULL) + return -1; + + pxm->tr = pxm->tg = 127; + pxm->tb = 128; + pxm->has_transp = 0; + + GETLINE; + if ((line[0] != 'P') || ((line[1] != '4') && (line[1] != '5') && (line[1] != '6')) || (line[2] != '\n')) { + fclose(f); + return -1; + } + type = line[1]; + + + GETLINE; + s = strchr(line, ' '); + if (s == NULL) { + fclose(f); + return -1; + } + *s = '\0'; + s++; + pxm->sx = atoi(line); + pxm->sy = atoi(s); + + if ((pxm->sx <= 0) || (pxm->sy <= 0) || (pxm->sx > 100000) || (pxm->sy > 100000)) { + fclose(f); + return -1; + } + + n = pxm->sx * pxm->sy; + pxm->size = n * 3; + o = pxm->p = malloc(pxm->size); + + switch(type) { + case '6': + GETLINE; + if (atoi(line) != 255) + goto error; + for(; n>0; n--) + ADDPX(pxm, fgetc(f), fgetc(f), fgetc(f), 0); + break; + case '5': + fgets(line, sizeof(line) - 1, f); + for(; n>0; n--) { + int px = fgetc(f); + ADDPX(pxm, px, px, px, 0); + } + break; + case '4': + for(;n>0;) { + int m, c, px; + c = fgetc(f); + for(m = 0; m < 8; m++) { + px = (c & 128) ? 0 : 255; + ADDPX(pxm, px, px, px, 0); + c <<= 1; + n--; + } + } + break; + } + fclose(f); + return 0; + + error:; + free(pxm->p); + pxm->p = NULL; + fclose(f); + return 0; +} + +static const rnd_pixmap_import_t pxm_pnm_imp = { + "pnm", + pnm_load +}; + +int pplg_check_ver_import_pxm_pnm(int ver_needed) { return 0; } + +void pplg_uninit_import_pxm_pnm(void) +{ + rnd_pixmap_unreg_import_all(import_pxm_pnm_cookie); +} + +int pplg_init_import_pxm_pnm(void) +{ + RND_API_CHK_VER; + rnd_pixmap_reg_import(&pxm_pnm_imp, import_pxm_pnm_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/import_pxm_pnm/import_pxm_pnm.pup =================================================================== --- tags/2.3.0/src_plugins/import_pxm_pnm/import_pxm_pnm.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_pxm_pnm/import_pxm_pnm.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import pixmaps from pnm +$long Import pnm P4, P5 and P6 into pcb-rnd pixmaps +$state works +$fmt-native no +$fmt-feature-r pnm (pixmap) +$package import-geo +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_sch2/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_sch2/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_sch2/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_sch2 + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_sch2/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_sch2/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_sch2/Plug.tmpasm (revision 33253) @@ -0,0 +1,9 @@ +put /local/pcb/mod {import_sch2} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_sch2/import_sch.o @] +put /local/pcb/mod/CONF {$(PLUGDIR)/import_sch2/import_sch_conf.h} + +switch /local/pcb/import_sch2/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_sch2/import_sch.c =================================================================== --- tags/2.3.0/src_plugins/import_sch2/import_sch.c (nonexistent) +++ tags/2.3.0/src_plugins/import_sch2/import_sch.c (revision 33253) @@ -0,0 +1,248 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include "globalconst.h" + +#include "board.h" +#include "undo.h" +#include "plug_import.h" +#include "import_sch_conf.h" + +#define MAX_ARGS 16 + +static conf_import_sch_t conf_import_sch; + +static int do_import(void); +static const char *import_sch_cookie = "import_sch2 plugin"; + +#include "import_sch_dlg.c" + +static int convert_attribs(void) +{ + const char *mode = pcb_attrib_get(PCB, "import::mode"); + const char *src0 = pcb_attrib_get(PCB, "import::src0"); + char tmp[32]; + int n, idx; + + if ((mode == NULL) && (src0 == NULL)) + return 0; + + for(n = 0, idx = 0; n < MAX_ARGS; n++) { + const char *src; + + sprintf(tmp, "import::src%d", n); + src = pcb_attrib_get(PCB, tmp); + if (src != NULL) { + rnd_conf_grow("plugins/import_sch/args", idx+1); + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/args", idx, src, RND_POL_OVERWRITE); + idx++; + } + } + + if (mode == NULL) + mode = "gnetlist"; + else if (strcmp(mode, "make") == 0) + mode = "cmd"; + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/import_fmt", 0, mode, RND_POL_OVERWRITE); + + + if (strcmp(mode, "cmd") == 0) { + const char *outfile = pcb_attrib_get(PCB, "import::outfile"); + const char *makefile = pcb_attrib_get(PCB, "import::makefile"); + const char *target = pcb_attrib_get(PCB, "import::target"); + gds_t cmdline; + + if (outfile == NULL) outfile = "-"; + if (target == NULL) target = "pcb_import"; + + gds_init(&cmdline); + gds_append_str(&cmdline, "make"); + if (makefile != NULL) { + gds_append_str(&cmdline, " -f \""); + gds_append_str(&cmdline, makefile); + gds_append(&cmdline, '"'); + } + gds_append(&cmdline, ' '); + gds_append_str(&cmdline, target); + + rnd_conf_grow("plugins/import_sch/args", 2); + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/args", 0, outfile, RND_POL_OVERWRITE); + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/args", 1, cmdline.array, RND_POL_OVERWRITE); + + gds_uninit(&cmdline); + } + + return 1; +} + +static int do_import(void) +{ + const char **a = NULL; + int len, n, res; + rnd_conf_listitem_t *ci; + const char *imp_name = conf_import_sch.plugins.import_sch.import_fmt; + pcb_plug_import_t *p; + + if ((imp_name == NULL) || (*imp_name == '\0')) { + if (convert_attribs()) { + rnd_message(RND_MSG_ERROR, "Had to convert import:: attributes to import_sch config\nNOTE: changes done to import settings will not change the old attribute values.\nFor details see: http://repo.hu/projects/pcb-rnd/help/err0001.html\n"); + imp_name = conf_import_sch.plugins.import_sch.import_fmt; + } + else { + if (!RND_HAVE_GUI_ATTR_DLG) { + rnd_message(RND_MSG_ERROR, "import_sch not configured; please use ImportSch(setup, ...)\n"); + return 1; + } + else + return do_dialog(); + } + } + + p = pcb_lookup_importer(imp_name); + if (p == NULL) { + rnd_message(RND_MSG_ERROR, "import_sch2: can not find importer called '%s'\nIs the corresponding plugin compiled?\n", imp_name); + return 1; + } + + len = rnd_conflist_length((rnd_conflist_t *)&conf_import_sch.plugins.import_sch.args); + if ((p->single_arg) && (len > 1)) + len = 1; + a = malloc((len+1) * sizeof(char *)); + for(n = 0, ci = rnd_conflist_first((rnd_conflist_t *)&conf_import_sch.plugins.import_sch.args); ci != NULL; ci = rnd_conflist_next(ci), n++) + a[n] = ci->val.string[0]; + rnd_message(RND_MSG_DEBUG, "import_sch2: reimport with %s -> %p\n", imp_name, p); + pcb_undo_freeze_serial(); + res = p->import(p, IMPORT_ASPECT_NETLIST, a, len); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + free(a); + return res; +} + +static int do_setup(int argc, fgw_arg_t *argv) +{ + int n; + pcb_plug_import_t *p; + + if (argc < 1) { + rnd_message(RND_MSG_ERROR, "ImportSch: setup needs importer name\n"); + return -1; + } + + for(n = 0; n < argc; n++) { + if (fgw_arg_conv(&rnd_fgw, &argv[n], FGW_STR) != 0) { + rnd_message(RND_MSG_ERROR, "ImportSch: failed to convert argument %d to string\n", n+1); + return -1; + } + } + + p = pcb_lookup_importer(argv[0].val.str); + if (p == NULL) { + rnd_message(RND_MSG_ERROR, "ImportSch: importer not found: '%s'\n", argv[0].val.str); + return -1; + } + + if (p->single_arg && (argc != 2)) { + rnd_message(RND_MSG_ERROR, "ImportSch: importer '%s' requires exactly one file name argument\n", argv[0].val.str); + return -1; + } + else if (p->all_filenames && (argc < 2)) { + rnd_message(RND_MSG_ERROR, "ImportSch: importer '%s' requires at least one file name argument\n", argv[0].val.str); + return -1; + } + + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/import_fmt", 0, argv[0].val.str, RND_POL_OVERWRITE); + rnd_conf_grow("plugins/import_sch/args", argc-1); + for(n = 1; n < argc; n++) + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/args", n-1, argv[n].val.str, RND_POL_OVERWRITE); + + return 0; +} + +static const char pcb_acts_ImportSch[] = + "ImportSch()\n" + "ImportSch(reimport)\n" + "ImportSch(setup, importer, [args...])\n"; +static const char pcb_acth_ImportSch[] = "Import schematics/netlist."; +/* DOC: importsch.html */ +static fgw_error_t pcb_act_ImportSch(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd = "reimport"; + + RND_ACT_MAY_CONVARG(1, FGW_STR, ImportSch, cmd = argv[1].val.str); + + if (strcmp(cmd, "reimport") == 0) { + RND_ACT_IRES(do_import()); + return 0; + } + if (strcmp(cmd, "setup") == 0) { + RND_ACT_IRES(do_setup(argc-2, argv+2)); + return 0; + } + if (strcmp(cmd, "dialog") == 0) { + RND_ACT_IRES(do_dialog()); + return 0; + } + + RND_ACT_FAIL(ImportSch); + RND_ACT_IRES(1); + return 0; +} + + +static rnd_action_t import_sch_action_list[] = { + {"ImportSch", pcb_act_ImportSch, pcb_acth_ImportSch, pcb_acts_ImportSch} +}; + +int pplg_check_ver_import_sch2(int ver_needed) { return 0; } + +void pplg_uninit_import_sch2(void) +{ + rnd_remove_actions_by_cookie(import_sch_cookie); + rnd_conf_unreg_fields("plugins/import_sch/"); + isch_dlg_uninit(); +} + +int pplg_init_import_sch2(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(import_sch_action_list, import_sch_cookie) +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_import_sch, field,isarray,type_name,cpath,cname,desc,flags); +#include "import_sch_conf_fields.h" + isch_dlg_init(); + + return 0; +} Index: tags/2.3.0/src_plugins/import_sch2/import_sch2.pup =================================================================== --- tags/2.3.0/src_plugins/import_sch2/import_sch2.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_sch2/import_sch2.pup (revision 33253) @@ -0,0 +1,8 @@ +$class import +$short import sch v2 +$long Imports footprints and netlist data from the schematics (or some other source). +$state WIP +$fmt-native no +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_sch2/import_sch_conf.h =================================================================== --- tags/2.3.0/src_plugins/import_sch2/import_sch_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/import_sch2/import_sch_conf.h (revision 33253) @@ -0,0 +1,20 @@ +#ifndef PCB_IMPORT_SCH_CONF_H +#define PCB_IMPORT_SCH_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_STRING import_fmt; /* name of the input format */ + RND_CFT_LIST args; /* import_fmt arguments, typically file names */ + RND_CFT_BOOLEAN verbose; /* verbose logging of the import code */ + + /* obsolete: temporary compatibility with import_sch for the transition period */ + RND_CFT_STRING gnetlist_program; /* DEPRECATED: gnetlist program name */ + RND_CFT_STRING make_program; /* DEPRECATED: make program name */ + } import_sch; + } plugins; +} conf_import_sch_t; + +#endif Index: tags/2.3.0/src_plugins/import_sch2/import_sch_dlg.c =================================================================== --- tags/2.3.0/src_plugins/import_sch2/import_sch_dlg.c (nonexistent) +++ tags/2.3.0/src_plugins/import_sch2/import_sch_dlg.c (revision 33253) @@ -0,0 +1,387 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* #included from import_sch.c to share global static variables */ + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + char **inames; + int len; + int wfmt, wtab, warg_ctrl, wverbose; + int warg[MAX_ARGS], warg_box[MAX_ARGS], warg_button[MAX_ARGS]; + rnd_hidval_t timer; + int arg_dirty; + int active; /* already open - allow only one instance */ +} isch_ctx_t; + +static isch_ctx_t isch_ctx; +static int isch_conf_lock = 0; + +static void isch_arg2pcb(void) +{ + int n; + rnd_conf_listitem_t *ci; + + isch_conf_lock++; + restart:; + for(n = 0, ci = rnd_conflist_first((rnd_conflist_t *)&conf_import_sch.plugins.import_sch.args); ci != NULL; ci = rnd_conflist_next(ci), n++) { + const char *newval = isch_ctx.dlg[isch_ctx.warg[n]].val.str; + if (newval == NULL) + newval = ""; + if (strcmp(ci->val.string[0], newval) != 0) { + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/args", n, newval, RND_POL_OVERWRITE); + goto restart; /* elements may be deleted and added with different pointers... */ + } + } + isch_conf_lock--; + + isch_ctx.arg_dirty = 0; +} + +static void isch_timed_update_cb(rnd_hidval_t user_data) +{ + isch_arg2pcb(); +} + +static void isch_flush_timer(void) +{ + if (isch_ctx.arg_dirty) { + rnd_gui->stop_timer(rnd_gui, isch_ctx.timer); + isch_arg2pcb(); + } +} + +static void isch_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + int n; + isch_ctx_t *ctx = caller_data; + + isch_flush_timer(); + RND_DAD_FREE(ctx->dlg); + for(n = 0; n < isch_ctx.len; n++) + free(isch_ctx.inames[n]); + free(isch_ctx.inames); + memset(ctx, 0, sizeof(isch_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static int isch_cmp(const void *a_, const void *b_) +{ + pcb_plug_import_t * const *a = a_, * const *b = b_; + + if ((*a)->ui_prio < (*b)->ui_prio) + return 1; + if ((*a)->ui_prio > (*b)->ui_prio) + return -1; + return strcmp((*a)->name, (*b)->name) > 0 ? 1 : -1; +} + +static void isch_switch_fmt(int target, int setconf) +{ + const pcb_plug_import_t *p = pcb_lookup_importer(isch_ctx.inames[target]); + int len, n, controllable; + + isch_conf_lock++; + RND_DAD_SET_VALUE(isch_ctx.dlg_hid_ctx, isch_ctx.wtab, lng, target); + if (setconf && (p != NULL)) + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/import_fmt", 0, p->name, RND_POL_OVERWRITE); + + if (p == NULL) { + len = 0; + controllable = 0; + } + else if (p->single_arg) { + len = rnd_conflist_length((rnd_conflist_t *)&conf_import_sch.plugins.import_sch.args); + if (len < 1) { + rnd_conf_grow("plugins/import_sch/args", 1); + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/args", 0, "", RND_POL_OVERWRITE); + } + len = 1; + controllable = 0; + } + else { + len = rnd_conflist_length((rnd_conflist_t *)&conf_import_sch.plugins.import_sch.args); + controllable = 1; + } + + + for(n = 0; n < MAX_ARGS; n++) { + rnd_gui->attr_dlg_widget_hide(isch_ctx.dlg_hid_ctx, isch_ctx.warg_box[n], n >= len); + rnd_gui->attr_dlg_widget_hide(isch_ctx.dlg_hid_ctx, isch_ctx.warg_button[n], !((p != NULL) && (p->all_filenames))); + } + + rnd_gui->attr_dlg_widget_hide(isch_ctx.dlg_hid_ctx, isch_ctx.warg_ctrl, !controllable); + isch_conf_lock--; +} + + +static void isch_pcb2dlg(void) +{ + int n, tab = 0; + rnd_conf_listitem_t *ci; + const char *tname = conf_import_sch.plugins.import_sch.import_fmt; + + isch_flush_timer(); + + if (tname != NULL) { + for(n = 0; n < isch_ctx.len; n++) { + if (rnd_strcasecmp(isch_ctx.inames[n], tname) == 0) { + tab = n; + break; + } + } + } + + for(n = 0, ci = rnd_conflist_first((rnd_conflist_t *)&conf_import_sch.plugins.import_sch.args); ci != NULL; ci = rnd_conflist_next(ci), n++) + RND_DAD_SET_VALUE(isch_ctx.dlg_hid_ctx, isch_ctx.warg[n], str, ci->val.string[0]); + + RND_DAD_SET_VALUE(isch_ctx.dlg_hid_ctx, isch_ctx.wfmt, lng, tab); + RND_DAD_SET_VALUE(isch_ctx.dlg_hid_ctx, isch_ctx.wverbose, lng, conf_import_sch.plugins.import_sch.verbose); + isch_switch_fmt(tab, 0); +} + +static void isch_fmt_chg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + isch_switch_fmt(isch_ctx.dlg[isch_ctx.wfmt].val.lng, 1); +} + +static void isch_arg_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int len = rnd_conflist_length((rnd_conflist_t *)&conf_import_sch.plugins.import_sch.args); + if (len > 0) { + rnd_conf_del(RND_CFR_DESIGN, "plugins/import_sch/args", len-1); + isch_pcb2dlg(); + } +} + +static void isch_arg_add_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int len = rnd_conflist_length((rnd_conflist_t *)&conf_import_sch.plugins.import_sch.args); + if (len < MAX_ARGS+1) { + isch_conf_lock++; + rnd_conf_grow("plugins/import_sch/args", len+1); + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/args", len, "", RND_POL_OVERWRITE); + isch_pcb2dlg(); + isch_conf_lock--; + } +} + +static void isch_browse_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int n, idx = -1, wid = attr - isch_ctx.dlg; + char *name; + static char cwd[RND_PATH_MAX + 1]; + + for(n = 0; n < MAX_ARGS; n++) { + if (isch_ctx.warg_button[n] == wid) { + idx = n; + break; + } + } + if (idx < 0) + return; + + if (*cwd == '\0') + rnd_get_wd(cwd); + + name = rnd_gui->fileselect(rnd_gui, "Import schematics", "Import netlist and footprints from schematics", cwd, NULL, NULL, "schematics", RND_HID_FSD_MAY_NOT_EXIST, NULL); + if (name == NULL) + return; + + isch_conf_lock++; + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/args", idx, name, RND_POL_OVERWRITE); + isch_pcb2dlg(); + free(name); + isch_conf_lock--; +} + + +static void isch_import_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + isch_flush_timer(); + do_import(); +} + +static void isch_arg_chg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_hidval_t user_data; + + if (isch_ctx.arg_dirty) + rnd_gui->stop_timer(rnd_gui, isch_ctx.timer); + + user_data.ptr = NULL; + isch_ctx.timer = rnd_gui->add_timer(rnd_gui, isch_timed_update_cb, 1000, user_data); + isch_ctx.arg_dirty = 1; +} + +static void isch_generic_chg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + const char *nv = isch_ctx.dlg[isch_ctx.wverbose].val.lng ? "1" : "0"; + isch_conf_lock++; + rnd_conf_set(RND_CFR_DESIGN, "plugins/import_sch/verbose", 0, nv, RND_POL_OVERWRITE); + isch_conf_lock--; +} + +static void isch_plc_cfg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&PCB->hidlib, "preferences", "config", "footprint_", NULL); +} + + +static void isch_add_tab(const pcb_plug_import_t *p) +{ + RND_DAD_BEGIN_VBOX(isch_ctx.dlg); + RND_DAD_LABEL(isch_ctx.dlg, p->desc); + RND_DAD_END(isch_ctx.dlg); +} + +static int do_dialog(void) +{ + int len, n; + const pcb_plug_import_t *p, **pa; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + if (isch_ctx.active) + return 0; /* do not open another */ + + len = 0; + for(p = pcb_plug_import_chain; p != NULL; p = p->next) len++; + + isch_ctx.arg_dirty = 0; + isch_ctx.inames = malloc((len+1) * sizeof(char *)); + pa = malloc(len * sizeof(pcb_plug_import_t *)); + + for(n = 0, p = pcb_plug_import_chain; p != NULL; p = p->next, n++) + pa[n] = p; + + qsort(pa, len, sizeof(pcb_plug_import_t *), isch_cmp); + + for(n = 0; n < len; n++) + isch_ctx.inames[n] = rnd_strdup(pa[n]->name); + isch_ctx.inames[n] = NULL; + isch_ctx.len = len; + + RND_DAD_BEGIN_VBOX(isch_ctx.dlg); + RND_DAD_COMPFLAG(isch_ctx.dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_VBOX(isch_ctx.dlg); /* format box */ + RND_DAD_COMPFLAG(isch_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HBOX(isch_ctx.dlg); + RND_DAD_LABEL(isch_ctx.dlg, "Format:"); + RND_DAD_ENUM(isch_ctx.dlg, isch_ctx.inames); + isch_ctx.wfmt = RND_DAD_CURRENT(isch_ctx.dlg); + RND_DAD_CHANGE_CB(isch_ctx.dlg, isch_fmt_chg_cb); + RND_DAD_HELP(isch_ctx.dlg, "Import file format (or plugin)"); + RND_DAD_END(isch_ctx.dlg); + RND_DAD_BEGIN_TABBED(isch_ctx.dlg, isch_ctx.inames); + RND_DAD_COMPFLAG(isch_ctx.dlg, RND_HATF_HIDE_TABLAB); + isch_ctx.wtab = RND_DAD_CURRENT(isch_ctx.dlg); + for(n = 0; n < len; n++) + isch_add_tab(pa[n]); + RND_DAD_END(isch_ctx.dlg); + RND_DAD_BEGIN_VBOX(isch_ctx.dlg); /* scrollable arg list */ + RND_DAD_COMPFLAG(isch_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + for(n = 0; n < MAX_ARGS; n++) { + RND_DAD_BEGIN_HBOX(isch_ctx.dlg); + isch_ctx.warg_box[n] = RND_DAD_CURRENT(isch_ctx.dlg); + RND_DAD_STRING(isch_ctx.dlg); + isch_ctx.warg[n] = RND_DAD_CURRENT(isch_ctx.dlg); + RND_DAD_WIDTH_CHR(isch_ctx.dlg, 32); + RND_DAD_CHANGE_CB(isch_ctx.dlg, isch_arg_chg_cb); + RND_DAD_BUTTON(isch_ctx.dlg, "browse"); + RND_DAD_CHANGE_CB(isch_ctx.dlg, isch_browse_cb); + isch_ctx.warg_button[n] = RND_DAD_CURRENT(isch_ctx.dlg); + RND_DAD_END(isch_ctx.dlg); + } + RND_DAD_BEGIN_HBOX(isch_ctx.dlg); + isch_ctx.warg_ctrl = RND_DAD_CURRENT(isch_ctx.dlg); + RND_DAD_BUTTON(isch_ctx.dlg, "Del last"); + RND_DAD_CHANGE_CB(isch_ctx.dlg, isch_arg_del_cb); + RND_DAD_HELP(isch_ctx.dlg, "Remove the last option from the end of the list"); + RND_DAD_BUTTON(isch_ctx.dlg, "One more"); + RND_DAD_CHANGE_CB(isch_ctx.dlg, isch_arg_add_cb); + RND_DAD_HELP(isch_ctx.dlg, "Append one more option to the end of the list"); + RND_DAD_END(isch_ctx.dlg); + RND_DAD_END(isch_ctx.dlg); + RND_DAD_END(isch_ctx.dlg); + + RND_DAD_BEGIN_VBOX(isch_ctx.dlg); /* generic settings */ + RND_DAD_BEGIN_HBOX(isch_ctx.dlg); + RND_DAD_LABEL(isch_ctx.dlg, "Verbose import:"); + RND_DAD_BOOL(isch_ctx.dlg); + isch_ctx.wverbose = RND_DAD_CURRENT(isch_ctx.dlg); + RND_DAD_CHANGE_CB(isch_ctx.dlg, isch_generic_chg_cb); + RND_DAD_END(isch_ctx.dlg); + RND_DAD_BUTTON(isch_ctx.dlg, "Placement config..."); + RND_DAD_CHANGE_CB(isch_ctx.dlg, isch_plc_cfg_cb); + RND_DAD_HELP(isch_ctx.dlg, "Configure how/where newly imported subcircuits\nare placed on the board"); + RND_DAD_END(isch_ctx.dlg); + + RND_DAD_BEGIN_HBOX(isch_ctx.dlg); /* bottom buttons */ + RND_DAD_BUTTON(isch_ctx.dlg, "Import!"); + RND_DAD_CHANGE_CB(isch_ctx.dlg, isch_import_cb); + RND_DAD_BEGIN_HBOX(isch_ctx.dlg); + RND_DAD_COMPFLAG(isch_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_END(isch_ctx.dlg); + RND_DAD_BUTTON_CLOSES(isch_ctx.dlg, clbtn); + RND_DAD_END(isch_ctx.dlg); + RND_DAD_END(isch_ctx.dlg); + + free(pa); + + /* set up the context */ + isch_ctx.active = 1; + + RND_DAD_DEFSIZE(isch_ctx.dlg, 360, 400); + RND_DAD_NEW("import_sch", isch_ctx.dlg, "Import schematics/netlist", &isch_ctx, rnd_false, isch_close_cb); + isch_pcb2dlg(); + isch_switch_fmt(isch_ctx.dlg[isch_ctx.wfmt].val.lng, 1); + + return 0; +} + +static void isch_cfg_chg(rnd_conf_native_t *cfg, int arr_idx) +{ + if ((isch_conf_lock == 0) && isch_ctx.active) + isch_pcb2dlg(); +} + +static rnd_conf_hid_id_t cfgid; + +static void isch_dlg_uninit(void) +{ + rnd_conf_hid_unreg(import_sch_cookie); +} + +static void isch_dlg_init(void) +{ + static rnd_conf_hid_callbacks_t cbs; + cfgid = rnd_conf_hid_reg(import_sch_cookie, NULL); + + cbs.val_change_post = isch_cfg_chg; + + rnd_conf_hid_set_cb(rnd_conf_get_field("plugins/import_sch/args"), cfgid, &cbs); + rnd_conf_hid_set_cb(rnd_conf_get_field("plugins/import_sch/import_fmt"), cfgid, &cbs); + rnd_conf_hid_set_cb(rnd_conf_get_field("plugins/import_sch/verbose"), cfgid, &cbs); +} Index: tags/2.3.0/src_plugins/import_tinycad/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_tinycad/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_tinycad/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_tinycad + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_tinycad/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_tinycad/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_tinycad/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {import_tinycad} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/import_tinycad/tinycad.o @] +put /local/pcb/mod/MENUFILE {tinycad-menu.lht} +put /local/pcb/mod/MENUVAR {tinycad_menu} + +switch /local/pcb/import_tinycad/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_tinycad/import_tinycad.pup =================================================================== --- tags/2.3.0/src_plugins/import_tinycad/import_tinycad.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_tinycad/import_tinycad.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import tinycad .net +$long Import the netlist and footprints from a tinycad netlist. +$state works +$fmt-native no +$fmt-feature-r tinycad .net (netlists + footprint info) +$package import-net +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_tinycad/tinycad-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_tinycad/tinycad-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_tinycad/tinycad-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Load TinyCAD .net file = { action=LoadTinyCADFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/import_tinycad/tinycad.c =================================================================== --- tags/2.3.0/src_plugins/import_tinycad/tinycad.c (nonexistent) +++ tags/2.3.0/src_plugins/import_tinycad/tinycad.c (revision 33253) @@ -0,0 +1,286 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tinycad import HID + * pcb-rnd Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "plug_import.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "menu_internal.c" + +static const char *tinycad_cookie = "tinycad importer"; + +/* remove leading whitespace */ +#define ltrim(s) while(isspace(*s)) s++ + +/* remove trailing newline */ +#define rtrim(s) \ + do { \ + char *end; \ + for(end = s + strlen(s) - 1; (end >= s) && ((*end == '\r') || (*end == '\n')); end--) \ + *end = '\0'; \ + } while(0) + +typedef struct { + char *refdes; + char *value; + char *footprint; +} symattr_t; + +#define null_empty(s) ((s) == NULL ? "" : (s)) + +static void sym_flush(symattr_t *sattr) +{ + if (sattr->refdes != NULL) { +/* rnd_trace("tinycad sym: refdes=%s val=%s fp=%s\n", sattr->refdes, sattr->value, sattr->footprint);*/ + if (sattr->footprint == NULL) + rnd_message(RND_MSG_ERROR, "tinycad: not importing refdes=%s: no footprint specified\n", sattr->refdes); + else + rnd_actionva(&PCB->hidlib, "ElementList", "Need", null_empty(sattr->refdes), null_empty(sattr->footprint), null_empty(sattr->value), NULL); + } + free(sattr->refdes); sattr->refdes = NULL; + free(sattr->value); sattr->value = NULL; + free(sattr->footprint); sattr->footprint = NULL; +} + + +static int tinycad_parse_net(FILE *fn) +{ + char line[1024]; + symattr_t sattr; + + memset(&sattr, 0, sizeof(sattr)); + + rnd_actionva(&PCB->hidlib, "ElementList", "start", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + + while(fgets(line, sizeof(line), fn) != NULL) { + int argc; + char **argv, *s; + + s = line; + ltrim(s); + if (*s == ';') /* comment */ + continue; + rtrim(s); + argc = qparse2(s, &argv, QPARSE_DOUBLE_QUOTE | QPARSE_SINGLE_QUOTE); + if ((argc > 1) && (strcmp(argv[0], "NET") == 0)) { + char *curr, *next, *sep; + + for(curr = argv[5]; (curr != NULL) && (*curr != '\0'); curr = next) { + next = strchr(curr, ')'); + if (next != NULL) { + *next = '\0'; + next++; + if (*next == ',') + next++; + } + if (*curr == '(') + curr++; + sep = strchr(curr, ','); + if (sep != NULL) { + *sep = '-'; +/* rnd_trace("net-add '%s' '%s'\n", argv[2], curr);*/ + rnd_actionva(&PCB->hidlib, "Netlist", "Add", argv[2], curr, NULL); + } + } + } + else if ((argc > 1) && (strcmp(argv[0], "COMPONENT") == 0)) { + sym_flush(&sattr); + free(sattr.refdes); + sattr.refdes = rnd_strdup(argv[1]); + } + else if ((argc > 3) && (strcmp(argv[0], "OPTION") == 0)) { + if (strcmp(argv[3], "..") != 0) { + if (strcmp(argv[1], "Package") == 0) { + free(sattr.footprint); + sattr.footprint = rnd_strdup(argv[3]); + } + else if (strcmp(argv[1], "Value") == 0) { + free(sattr.value); + sattr.value = rnd_strdup(argv[3]); + } + } + } + qparse_free(argc, &argv); + } + + sym_flush(&sattr); + + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + rnd_actionva(&PCB->hidlib, "ElementList", "Done", NULL); + + return 0; +} + + +static int tinycad_load(const char *fname_net) +{ + FILE *fn; + int ret = 0; + + fn = rnd_fopen(&PCB->hidlib, fname_net, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname_net); + return -1; + } + + pcb_undo_freeze_serial(); + ret = tinycad_parse_net(fn); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + fclose(fn); + return ret; +} + +static const char pcb_acts_LoadtinycadFrom[] = "LoadTinycadFrom(filename)"; +static const char pcb_acth_LoadtinycadFrom[] = "Loads the specified tinycad .net file - the netlist must be tinycad netlist output."; +fgw_error_t pcb_act_LoadtinycadFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + static char *default_file = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadtinycadFrom, fname = argv[1].val.str); + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Load tinycad netlist file...", + "Picks a tinycad netlist file to load.\n", + default_file, ".net", NULL, "tinycad", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 1; + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + RND_ACT_IRES(0); + return tinycad_load(fname); +} + +static int tinycad_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + FILE *f; + unsigned int good = 0; + + if ((aspects != IMPORT_ASPECT_NETLIST) || (numargs != 1)) + return 0; /* only pure netlist import is supported from a single file*/ + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + for(;;) { + char *s, line[1024]; + s = fgets(line, sizeof(line), f); + if (s == NULL) + break; + while(isspace(*s)) s++; + if (strncmp(s, "COMPONENT", 9) == 0) + good |= 1; + else if (strncmp(s, "OPTION", 6) == 0) + good |= 2; + else if (strncmp(s, "NET", 3) == 0) + good |= 4; + if (good == (1|2|4)) { + fclose(f); + return 100; + } + } + + fclose(f); + + return 0; +} + + +static int tinycad_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_tinycad: requires exactly 1 input file name\n"); + return -1; + } + return tinycad_load(fns[0]); +} + +static pcb_plug_import_t import_tinycad; + +rnd_action_t tinycad_action_list[] = { + {"LoadTinycadFrom", pcb_act_LoadtinycadFrom, pcb_acth_LoadtinycadFrom, pcb_acts_LoadtinycadFrom} +}; + +int pplg_check_ver_import_tinycad(int ver_needed) { return 0; } + +void pplg_uninit_import_tinycad(void) +{ + rnd_remove_actions_by_cookie(tinycad_cookie); + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_tinycad); + rnd_hid_menu_unload(rnd_gui, tinycad_cookie); +} + +int pplg_init_import_tinycad(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + import_tinycad.plugin_data = NULL; + + import_tinycad.fmt_support_prio = tinycad_support_prio; + import_tinycad.import = tinycad_import; + import_tinycad.name = "tinycad"; + import_tinycad.desc = "schamtics from tinycad"; + import_tinycad.ui_prio = 50; + import_tinycad.single_arg = 1; + import_tinycad.all_filenames = 1; + import_tinycad.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_tinycad); + + RND_REGISTER_ACTIONS(tinycad_action_list, tinycad_cookie) + rnd_hid_menu_load(rnd_gui, NULL, tinycad_cookie, 175, NULL, 0, tinycad_menu, "plugin: import tinycad"); + return 0; +} Index: tags/2.3.0/src_plugins/import_ttf/Makefile =================================================================== --- tags/2.3.0/src_plugins/import_ttf/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/import_ttf/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_import_ttf + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/import_ttf/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/import_ttf/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/import_ttf/Plug.tmpasm (revision 33253) @@ -0,0 +1,22 @@ +put /local/pcb/mod {import_ttf} +put /local/pcb/mod/MENUFILE {import_ttf-menu.lht} +put /local/pcb/mod/MENUVAR {import_ttf_menu} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/import_ttf/ttf.o + $(PLUGDIR)/import_ttf/ttf_load.o + $(PLUGDIR)/import_ttf/str_approx.o +@] + +switch /local/pcb/import_ttf/controls + case {disable} end; + default + put /local/pcb/mod/LDFLAGS libs/sul/freetype2/ldflags + put /local/pcb/mod/CFLAGS libs/sul/freetype2/cflags + end +end + +switch /local/pcb/import_ttf/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/import_ttf/import_ttf-menu.lht =================================================================== --- tags/2.3.0/src_plugins/import_ttf/import_ttf-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/import_ttf/import_ttf-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_geo { + li:submenu { + ha:Import ttf glyphs = { action=LoadTtf() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/import_ttf/import_ttf.pup =================================================================== --- tags/2.3.0/src_plugins/import_ttf/import_ttf.pup (nonexistent) +++ tags/2.3.0/src_plugins/import_ttf/import_ttf.pup (revision 33253) @@ -0,0 +1,9 @@ +$class import +$short import ttf glyphs +$long Import outline ttf glyphs into the current font, either as polygons or lines +$state WIP +$fmt-native no +$fmt-feature-r ttf font +$package import-geo +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/import_ttf/str_approx.c =================================================================== --- tags/2.3.0/src_plugins/import_ttf/str_approx.c (nonexistent) +++ tags/2.3.0/src_plugins/import_ttf/str_approx.c (revision 33253) @@ -0,0 +1,82 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * ttf stroker + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Dummy stroker that approximates curves with line segments */ + +#include "ttf_load.h" +#include "str_approx.h" +#include + +char *str_approx_comment = "!!"; + +static double sqr(double a) +{ + return a*a; +} + +static double cub(double a) +{ + return a*a*a; +} + +int stroke_approx_conic_to(const FT_Vector *control, const FT_Vector *to, void *s_) +{ + pcb_ttf_stroke_t *s = (pcb_ttf_stroke_t *)s_; + double t; + double nodes = 10, td = 1.0 / nodes; + FT_Vector v; + + if (str_approx_comment != NULL) rnd_trace("%s conic to {\n", str_approx_comment); + for(t = 0.0; t <= 1.0; t += td) { + v.x = sqr(1.0-t) * s->x + 2.0*t*(1.0-t)*(double)control->x + t*t*(double)to->x; + v.y = sqr(1.0-t) * s->y + 2.0*t*(1.0-t)*(double)control->y + t*t*(double)to->y; + s->funcs.line_to(&v, s); + } + if (str_approx_comment != NULL) rnd_trace("%s }\n", str_approx_comment); + + s->funcs.line_to(to, s); + return 0; +} + +int stroke_approx_cubic_to(const FT_Vector *control1, const FT_Vector *control2, const FT_Vector *to, void *s_) +{ + pcb_ttf_stroke_t *s = (pcb_ttf_stroke_t *)s_; + double t; + double nodes = 10, td = 1.0 / nodes; + FT_Vector v; + + if (str_approx_comment != NULL) rnd_trace("%s cubic to {\n", str_approx_comment); + for(t = 0.0; t <= 1.0; t += td) { + v.x = cub(1.0-t)*s->x + 3.0*t*sqr(1.0-t)*(double)control1->x + 3.0*sqr(t)*(1.0-t)*(double)control2->x + cub(t)*(double)to->x; + v.y = cub(1.0-t)*s->y + 3.0*t*sqr(1.0-t)*(double)control1->y + 3.0*sqr(t)*(1.0-t)*(double)control2->y + cub(t)*(double)to->y; + s->funcs.line_to(&v, s); + } + if (str_approx_comment != NULL) rnd_trace("%s }\n", str_approx_comment); + s->funcs.line_to(to, s); + return 0; +} Index: tags/2.3.0/src_plugins/import_ttf/str_approx.h =================================================================== --- tags/2.3.0/src_plugins/import_ttf/str_approx.h (nonexistent) +++ tags/2.3.0/src_plugins/import_ttf/str_approx.h (revision 33253) @@ -0,0 +1,4 @@ +extern char *str_approx_comment; + +int stroke_approx_conic_to(const FT_Vector *control, const FT_Vector *to, void *s_); +int stroke_approx_cubic_to(const FT_Vector *control1, const FT_Vector *control2, const FT_Vector *to, void *s_); Index: tags/2.3.0/src_plugins/import_ttf/ttf.c =================================================================== --- tags/2.3.0/src_plugins/import_ttf/ttf.c (nonexistent) +++ tags/2.3.0/src_plugins/import_ttf/ttf.c (revision 33253) @@ -0,0 +1,685 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * ttf glyph import + * pcb-rnd Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include "board.h" +#include "data.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include + +#include "ttf_load.h" +#include "str_approx.h" + +#include +#include + +static const char *ttf_cookie = "ttf importer"; + +#include "menu_internal.c" + +static void str_init(pcb_ttf_stroke_t *s) +{ + rnd_trace("stroke init\n"); +} + +static void str_start(pcb_ttf_stroke_t *s, int chr) +{ + rnd_trace("stroke start\n"); +} + +static void str_finish(pcb_ttf_stroke_t *s) +{ + rnd_trace("stroke finish\n"); +} + +static void str_uninit(pcb_ttf_stroke_t *s) +{ + rnd_trace("stroke uninit\n"); +} + +#define TRX(x) RND_MM_TO_COORD((x) * str->scale_x + str->dx) +#define TRY(y) RND_MM_TO_COORD((str->ttf->face->height - (y) - str->ttf->face->ascender - str->ttf->face->descender) * str->scale_y + str->dy) + +#define TRX_(x) RND_MM_TO_COORD((x) * stroke->scale_x) +#define TRY_(y) RND_MM_TO_COORD((y) * stroke->scale_y) + +static void poly_create(pcb_ttf_stroke_t *str, rnd_pline_t *pl, int is_neg) +{ + rnd_polyarea_t *pa; + + if (pl->Count < 3) + return; + + pa = rnd_polyarea_create(); + rnd_polyarea_contour_include(pa, pl); + vtp0_append((is_neg ? &str->poly_neg : &str->poly_pos), pa); +rnd_trace("poly append: %d [%f] on %s\n", pl->Count, pl->area/1000000000.0, is_neg ? "neg" : "pos"); +} + +static void poly_flush(pcb_ttf_stroke_t *str) +{ + int is_neg = 0; + + if (!str->want_poly || (str->contour == NULL)) + return; + + rnd_poly_contour_pre(str->contour, rnd_true); + if (str->contour->Flags.orient != RND_PLF_DIR) { + rnd_poly_contour_inv(str->contour); + is_neg = 1; + } + + if (rnd_pline_is_selfint(str->contour)) { + int n; + vtp0_t pls; + vtp0_init(&pls); + rnd_pline_split_selfint(str->contour, &pls); + for(n = 0; n < pls.used; n++) { + rnd_pline_t *pln = (rnd_pline_t *)pls.array[n]; + poly_create(str, pln, is_neg); + } + vtp0_uninit(&pls); + rnd_poly_contour_del(&str->contour); + } + else + poly_create(str, str->contour, is_neg); + + str->contour = NULL; +} + +static void ttf_poly_emit(rnd_pline_t *pl, void *ctx) +{ + long n; + rnd_vnode_t *v; + pcb_ttf_stroke_t *str = ctx; + pcb_poly_t *p = pcb_font_new_poly_in_sym(str->sym, pl->Count); + +rnd_trace(" emit: %d\n", pl->Count); + for(n = 0, v = pl->head; n < pl->Count; n++, v = v->next) { + p->Points[n].X = v->point[0]; + p->Points[n].Y = v->point[1]; + } +} + +static void poly_apply(pcb_ttf_stroke_t *str) +{ + int p, n; + rnd_trace("poly apply:\n"); + for(p = 0; p < str->poly_pos.used; p++) { + rnd_polyarea_t *pap = str->poly_pos.array[p]; + for(n = 0; n < str->poly_neg.used; n++) { + rnd_polyarea_t *res, *pan = str->poly_neg.array[n]; + if (pan == NULL) continue; + if (rnd_poly_contour_in_contour(pap->contours, pan->contours)) { + str->poly_neg.array[n] = NULL; + rnd_polyarea_boolean_free(pap, pan, &res, RND_PBO_SUB); + if (res != NULL) { + str->poly_pos.array[p] = pap = res; + str->poly_neg.array[n] = NULL; /* already freed, do not reuse */ + } + } + } + } + + /* dice and free positive poly areas */ + for(p = 0; p < str->poly_pos.used; p++) + rnd_polyarea_no_holes_dicer(str->poly_pos.array[p], -RND_MAX_COORD, -RND_MAX_COORD, +RND_MAX_COORD, +RND_MAX_COORD, ttf_poly_emit, str); + + /* free remaining (unused) negative areas */ + for(n = 0; n < str->poly_neg.used; n++) { + rnd_polyarea_t *pan = str->poly_neg.array[n]; + if (pan != NULL) + rnd_polyarea_free(&pan); + } + + vtp0_uninit(&str->poly_pos); + vtp0_uninit(&str->poly_neg); + rnd_trace("(end)\n"); +} + +static int str_move_to(const FT_Vector *to, void *s_) +{ + pcb_ttf_stroke_t *str = s_; + rnd_trace(" move %f;%f %ld;%ld\n", str->x, str->y, to->x, to->y); + poly_flush(str); + str->x = to->x; + str->y = to->y; + return 0; +} + +static int str_line_to(const FT_Vector *to, void *s_) +{ + pcb_ttf_stroke_t *str = s_; + rnd_trace(" line %f;%f %ld;%ld\n", str->x, str->y, to->x, to->y); + if (str->want_poly) { + rnd_vector_t v; + + + if (str->contour == NULL) { + v[0] = TRX(str->x); v[1] = TRY(str->y); + str->contour = rnd_poly_contour_new(v); + } + v[0] = TRX(to->x); v[1] = TRY(to->y); + rnd_poly_vertex_include(str->contour->head->prev, rnd_poly_node_create(v)); + } + else { + pcb_font_new_line_in_sym(str->sym, + TRX(str->x), TRY(str->y), + TRX(to->x), TRY(to->y), + 1); + } + str->x = to->x; + str->y = to->y; + return 0; +} + +static int conv_char_desc(const char *s, const char **end) +{ + /* explicit '' */ + if (s[0] == '\'') { + if (s[2] == '\'') { + *end = s+3; + return s[1]; + } + *end = s+2; + return -1; + } + + /* unicode &# code point, hex or dec */ + if ((s[0] == '&') && (s[1] == '#')) { + if (s[2] == 'x') + return strtol(s+3, (char **)end, 16); + return strtol(s+2, (char **)end, 10); + } + + /* unicode U+ code point, hex */ + if ((s[0] == 'U') && (s[1] == '+')) + return strtol(s+2, (char **)end, 16); + + /* assume plain character */ + *end = s+1; + return s[0]; +} + +static int conv_coord_pair(const char *s, double *x, double *y) +{ + char *end; + *x = strtod(s, &end); + if (*end == '\0') { + *y = *x; + return 0; + } + if ((*end != ',') && (*end != ';') && (*end != 'x') && (*end != '*') && (*end != '/')) + return -1; + *y = strtod(end+1, &end); + if (*end == '\0') + return 0; + return -1; +} + +static int ttf_import(pcb_board_t *pcb, pcb_ttf_t *ctx, pcb_ttf_stroke_t *stroke, int src_from, int src_to, int dst) +{ + int r, src, ret = 0; + pcb_font_t *f = pcb_font(pcb, conf_core.design.text_font_id, 1); + + + stroke->funcs.move_to = str_move_to; + stroke->funcs.line_to = str_line_to; + stroke->funcs.conic_to = stroke_approx_conic_to; + stroke->funcs.cubic_to = stroke_approx_cubic_to; + + stroke->init = str_init; + stroke->start = str_start; + stroke->finish = str_finish; + stroke->uninit = str_uninit; + + stroke->ttf = ctx; + + for(src = src_from; (src <= src_to) && (dst < (PCB_MAX_FONTPOSITION+1)); src++,dst++) { + rnd_trace("face: %d -> %d\n", src, dst); + stroke->sym = &f->Symbol[dst]; + + pcb_font_free_symbol(stroke->sym); + + r = pcb_ttf_trace(ctx, src, src, stroke, 1); + if (r != 0) + ret = -1; + + if (stroke->want_poly) { + poly_flush(stroke); + poly_apply(stroke); + } + + stroke->sym->Valid = 1; + stroke->sym->Width = TRX_(ctx->face->glyph->advance.x); + stroke->sym->Height = TRY_(ctx->face->ascender + ctx->face->descender); + stroke->sym->Delta = RND_MIL_TO_COORD(12); + } + + return ret; +} + +static const char pcb_acts_LoadTtfGlyphs[] = "LoadTtfGlyphs(filename, srcglyps, [dstchars], [outline|polygon], [scale], [offset])"; +static const char pcb_acth_LoadTtfGlyphs[] = "Loads glyphs from an outline ttf in the specified source range, optionally remapping them to dstchars range in the pcb-rnd font"; +/* DOC: loadttfglyphs.html */ +fgw_error_t pcb_act_LoadTtfGlyphs(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *fn, *ssrc, *smode = "polygon", *sdst = NULL, *sscale = "0.001", *soffs = "0", *end = NULL; + pcb_ttf_t ctx = {0}; + pcb_ttf_stroke_t stroke = {0}; + int r, ret = 0, dst, src_from, src_to; + + RND_ACT_CONVARG(1, FGW_STR, LoadTtfGlyphs, fn = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, LoadTtfGlyphs, ssrc = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, LoadTtfGlyphs, smode = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, LoadTtfGlyphs, sdst = argv[4].val.str); + RND_ACT_MAY_CONVARG(5, FGW_STR, LoadTtfGlyphs, sscale = argv[5].val.str); + RND_ACT_MAY_CONVARG(6, FGW_STR, LoadTtfGlyphs, soffs = argv[6].val.str); + + r = pcb_ttf_load(&ctx, fn); + if (r != 0) { + RND_ACT_IRES(-1); + return 0; + } + rnd_trace("ttf load; %d\n", r); + + src_from = conv_char_desc(ssrc, &end); + if ((end[0] == '.') && (end[1] == '.')) + src_to = conv_char_desc(end+2, &end); + else + src_to = src_from; + + if ((end[0] != '\0') || (src_from < 0) || (src_to < 0)) { + rnd_message(RND_MSG_ERROR, "LoadTtfGlyphs(): invalid source character: %s\n", ssrc); + RND_ACT_IRES(-1); + return 0; + } + + if (sdst != NULL) { + dst = conv_char_desc(sdst, &end); + if ((end[0] != '\0') || (dst < 0) || (dst > 255)) { + rnd_message(RND_MSG_ERROR, "LoadTtfGlyphs(): invalid destination character: %s\n", sdst); + RND_ACT_IRES(-1); + return 0; + } + } + else + dst = src_from; + + if (strncmp(smode, "poly", 4) == 0) + stroke.want_poly = 1; + else if (strcmp(smode, "outline") == 0) + stroke.want_poly = 0; + else { + rnd_message(RND_MSG_ERROR, "LoadTtfGlyphs(): invalid mode: %s\n", smode); + RND_ACT_IRES(-1); + return 0; + } + + if (conv_coord_pair(sscale, &stroke.scale_x, &stroke.scale_y) != 0) { + rnd_message(RND_MSG_ERROR, "LoadTtfGlyphs(): invalid scale: %s\n", sscale); + RND_ACT_IRES(-1); + return 0; + } + + if (conv_coord_pair(soffs, &stroke.dx, &stroke.dy) != 0) { + rnd_message(RND_MSG_ERROR, "LoadTtfGlyphs(): invalid offs: %s\n", sscale); + RND_ACT_IRES(-1); + return 0; + } + + ret = ttf_import(pcb, &ctx, &stroke, src_from, src_to, dst); + +rnd_trace(" xform: %f;%f %f;%f\n", stroke.scale_x, stroke.scale_y, stroke.dx, stroke.dy); + + pcb_ttf_unload(&ctx); + RND_ACT_IRES(ret); + return 0; +} + +/*** dialog ***/ +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int active; + pcb_ttf_t ttf; + int loaded; /* ttf loaded */ + int wmsg, wfont, wsrc, wdst, wrend, wscale, wox, woy, wimport, wprv; + int timer_active; + rnd_hidval_t timer; +} ttfgui_ctx_t; + +ttfgui_ctx_t ttfgui_ctx; + +static void ttfgui_unload(ttfgui_ctx_t *ctx) +{ + if (!ctx->loaded) return; + + pcb_ttf_unload(&ctx->ttf); + ctx->loaded = 0; +} + +static void ttfgui_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + ttfgui_ctx_t *ctx = caller_data; + + ttfgui_unload(ctx); + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(ttfgui_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void ttf_expose(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ +/* ttfgui_ctx_t *ctx = prv->user_ctx;*/ + char s[17]; + int x, y, v; + + rnd_render->set_color(gc, rnd_color_black); + + s[16] = '\0'; + v = 0; + for(y = 0; y < 16; y++) { + for(x = 0; x < 16; x++) + s[x] = v++; + pcb_text_draw_string_simple(NULL, s, RND_MM_TO_COORD(0), RND_MM_TO_COORD(y*2), 1.0, 1.0, 0.0, 0, 0, 0, 0, 0); + } +} + +static void load_src_dst(ttfgui_ctx_t *ctx, const char *ssrc, const char *sdst) +{ + rnd_hid_attr_val_t hv; + + hv.str = ssrc; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wsrc, &hv); + + hv.str = sdst; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wdst, &hv); +} + +static void load_all_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + load_src_dst(caller_data, " ..~", " "); +} + +static void load_low_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + load_src_dst(caller_data, "a..z", "a"); +} + +static void load_up_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + load_src_dst(caller_data, "A..Z", "A"); +} + +static void load_num_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + load_src_dst(caller_data, "0..9", "0"); +} + +static void font_change_timer_cb(rnd_hidval_t user_data) +{ + ttfgui_ctx_t *ctx = user_data.ptr; + if (ctx->active) { + int r; + const char *fn = ctx->dlg[ctx->wfont].val.str; + char *tmp; + rnd_hid_attr_val_t hv; + + ttfgui_unload(ctx); + r = pcb_ttf_load(&ctx->ttf, fn); + if (r == 0) { + ctx->loaded = 1; + tmp = rnd_strdup_printf("Loaded %s", fn); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wimport, 1); + } + else { + tmp = rnd_strdup_printf("ERROR: failed to load %s", fn); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wimport, 0); + } + + hv.str = tmp; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wmsg, &hv); + + free(tmp); + } + ctx->timer_active = 0; +} + +static void font_change_timer(ttfgui_ctx_t *ctx, int period) +{ + rnd_hidval_t hv; + + if (ctx->timer_active && (rnd_gui->stop_timer != NULL)) + rnd_gui->stop_timer(rnd_gui, ctx->timer); + + hv.ptr = ctx; + ctx->timer = rnd_gui->add_timer(rnd_gui, font_change_timer_cb, period, hv); + ctx->timer_active = 1; +} + +static void font_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + font_change_timer(caller_data, 750); +} + +static void font_browse_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + char *fn; + ttfgui_ctx_t *ctx = caller_data; + rnd_hid_attr_val_t hv; + + fn = rnd_gui->fileselect(rnd_gui, "Import ttf file", "Select a ttf file (or other font file that libfreetype can load) for importing glyphs from", + NULL, "ttf", NULL, "import_ttf", RND_HID_FSD_READ, NULL); + + if (fn == NULL) + return; + + hv.str = fn; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wfont, &hv); + free(fn); + font_change_timer(caller_data, 100); +} + +static void rezoom(ttfgui_ctx_t *ctx) +{ + rnd_box_t bbox; + bbox.X1 = 0; + bbox.Y1 = 0; + bbox.X2 = RND_MM_TO_COORD(32); + bbox.Y2 = RND_MM_TO_COORD(32); + rnd_dad_preview_zoomto(&ctx->dlg[ctx->wprv], &bbox); +} + +static void import_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int src_from, src_to, dst, ret; + pcb_ttf_stroke_t stroke = {0}; + const char *end; + ttfgui_ctx_t *ctx = caller_data; + + if ((ctx->dlg[ctx->wsrc].val.str == NULL) || (ctx->dlg[ctx->wdst].val.str == NULL)) { + rnd_message(RND_MSG_ERROR, "missing from/to ranges for the character mapping\n"); + return; + } + + src_from = conv_char_desc(ctx->dlg[ctx->wsrc].val.str, &end); + if ((end[0] == '.') && (end[1] == '.')) + src_to = conv_char_desc(end+2, &end); + else + src_to = src_from; + if ((end[0] != '\0') || (src_from < 0) || (src_to < 0)) { + rnd_message(RND_MSG_ERROR, "invalid source character\n"); + return; + } + + dst = conv_char_desc(ctx->dlg[ctx->wdst].val.str, &end); + if ((end[0] != '\0') || (dst < 0) || (dst > 255)) { + rnd_message(RND_MSG_ERROR, "invalid destination character\n"); + return; + } + + stroke.want_poly = (ctx->dlg[ctx->wrend].val.lng == 0); + + stroke.scale_x = stroke.scale_y = ctx->dlg[ctx->wscale].val.dbl; + stroke.dx = ctx->dlg[ctx->wox].val.dbl; + stroke.dy = ctx->dlg[ctx->woy].val.dbl; + + ret = ttf_import(PCB, &ctx->ttf, &stroke, src_from, src_to, dst); + if (ret != 0) + rnd_message(RND_MSG_ERROR, "ttf import failed - make sure your character range settings are good\n"); + + /* redraw */ + rnd_gui->invalidate_all(rnd_gui); + rezoom(ctx); +} + + +static const char pcb_acts_LoadTtf[] = "LoadTtf()"; +static const char pcb_acth_LoadTtf[] = "Presents a GUI dialog for interactively loading glyphs from from a ttf file"; +fgw_error_t pcb_act_LoadTtf(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + static const char *rend_names[] = {"polygon", "outline", NULL}; + ttfgui_ctx_t *ctx = &ttfgui_ctx; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + RND_ACT_IRES(0); + if (ctx->active) + return 0; /* do not open another */ + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_HPANE(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + /* left */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Font:"); + RND_DAD_STRING(ctx->dlg); + ctx->wfont = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_WIDTH_CHR(ctx->dlg, 32); + RND_DAD_CHANGE_CB(ctx->dlg, font_change_cb); + RND_DAD_BUTTON(ctx->dlg, "Browse"); + RND_DAD_CHANGE_CB(ctx->dlg, font_browse_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->wmsg = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_TABLE(ctx->dlg, 2); + RND_DAD_LABEL(ctx->dlg, "Source character(s):"); + RND_DAD_STRING(ctx->dlg); + ctx->wsrc = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Destination start:"); + RND_DAD_STRING(ctx->dlg); + ctx->wdst = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Rendering:"); + RND_DAD_ENUM(ctx->dlg, rend_names); + ctx->wrend = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Scale:"); + RND_DAD_REAL(ctx->dlg); + ctx->wscale = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_DEFAULT_NUM(ctx->dlg, 0.001); + RND_DAD_LABEL(ctx->dlg, "X offset:"); + RND_DAD_REAL(ctx->dlg); + ctx->wox = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_DEFAULT_NUM(ctx->dlg, 0); + RND_DAD_LABEL(ctx->dlg, "Y offset:"); + RND_DAD_REAL(ctx->dlg); + ctx->woy = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_DEFAULT_NUM(ctx->dlg, 0); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BUTTON(ctx->dlg, "All"); + RND_DAD_CHANGE_CB(ctx->dlg, load_all_cb); + RND_DAD_BUTTON(ctx->dlg, "Lowercase"); + RND_DAD_CHANGE_CB(ctx->dlg, load_low_cb); + RND_DAD_BUTTON(ctx->dlg, "Uppercase"); + RND_DAD_CHANGE_CB(ctx->dlg, load_up_cb); + RND_DAD_BUTTON(ctx->dlg, "Number"); + RND_DAD_CHANGE_CB(ctx->dlg, load_num_cb); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Import!"); + ctx->wimport = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, import_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* right */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_PREVIEW(ctx->dlg, ttf_expose, NULL, NULL, NULL, NULL, 300, 300, ctx); + ctx->wprv = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + /* set up the context */ + ctx->active = 1; + + RND_DAD_NEW("load_ttf", ctx->dlg, "Load glyphs from ttf font", ctx, rnd_false, ttfgui_close_cb); + + rezoom(ctx); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wimport, 0); /* disable import button before a file name is specified */ + + return 0; +} + +rnd_action_t ttf_action_list[] = { + {"LoadTtfGlyphs", pcb_act_LoadTtfGlyphs, pcb_acth_LoadTtfGlyphs, pcb_acts_LoadTtfGlyphs}, + {"LoadTtf", pcb_act_LoadTtf, pcb_acth_LoadTtf, pcb_acts_LoadTtf} +}; + +int pplg_check_ver_import_ttf(int ver_needed) { return 0; } + +void pplg_uninit_import_ttf(void) +{ + rnd_hid_menu_unload(rnd_gui, ttf_cookie); + rnd_remove_actions_by_cookie(ttf_cookie); +} + +int pplg_init_import_ttf(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(ttf_action_list, ttf_cookie) + rnd_hid_menu_load(rnd_gui, NULL, ttf_cookie, 50, NULL, 0, import_ttf_menu, "plugin: import_ttf"); + return 0; +} Index: tags/2.3.0/src_plugins/import_ttf/ttf_load.c =================================================================== --- tags/2.3.0/src_plugins/import_ttf/ttf_load.c (nonexistent) +++ tags/2.3.0/src_plugins/import_ttf/ttf_load.c (revision 33253) @@ -0,0 +1,119 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * ttf low level loader + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include +#include +#include +#include "ttf_load.h" + +# undef __FTERRORS_H__ +# define FT_ERRORDEF( e, v, s ) { e, s }, +# define FT_ERROR_START_LIST { +# define FT_ERROR_END_LIST { 0, 0 } }; + static const struct { + FT_Error errnum; + const char *errstr; + } ft_errtab[] = +# include FT_ERRORS_H + +static const char *int_errtab[] = { + "success", + "Need an outline font" +}; + +int pcb_ttf_load(pcb_ttf_t *ctx, const char *fn) +{ + FT_Error errnum; + + errnum = FT_Init_FreeType(&ctx->library); + if (errnum == 0) + errnum = FT_New_Face(ctx->library, fn, 0, &ctx->face); + return errnum; +} + +int pcb_ttf_unload(pcb_ttf_t *ctx) +{ + FT_Done_Face(ctx->face); + FT_Done_Library(ctx->library); + memset(ctx, 0, sizeof(pcb_ttf_t)); + return 0; +} + + +FT_Error pcb_ttf_trace(pcb_ttf_t *ctx, FT_ULong ttf_chr, FT_ULong out_chr, pcb_ttf_stroke_t *str, unsigned short int scale) +{ + FT_Error err; + FT_Glyph gly; + FT_OutlineGlyph ol; + FT_Matrix mx; + + if (scale > 1) { + mx.xx = scale << 16; + mx.xy = 0; + mx.yy = scale << 16; + mx.yx = 0; + FT_Set_Transform(ctx->face, &mx, NULL); + } + else + FT_Set_Transform(ctx->face, NULL, NULL); + + err = FT_Load_Glyph(ctx->face, FT_Get_Char_Index(ctx->face, ttf_chr), FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE); + if (err != 0) + return err; + + FT_Get_Glyph(ctx->face->glyph, &gly); + ol = (FT_OutlineGlyph)gly; + if (ctx->face->glyph->format != ft_glyph_format_outline) + return -1; /* this method supports only outline font */ + + str->start(str, out_chr); + err = FT_Outline_Decompose(&(ol->outline), &str->funcs, str); + str->finish(str); + + if (err != 0) + return err; + + return 0; +} + +const char *pcb_ttf_errmsg(FT_Error errnum) +{ + if (errnum > 0) { + if (errnum < sizeof(ft_errtab) / sizeof(ft_errtab[0])) + return ft_errtab[errnum].errstr; + return "Invalid freetype2 error code."; + } + + errnum = -errnum; + if (errnum < sizeof(int_errtab) / sizeof(int_errtab[0])) + return int_errtab[errnum]; + + return "Invalid internal error code."; +} Index: tags/2.3.0/src_plugins/import_ttf/ttf_load.h =================================================================== --- tags/2.3.0/src_plugins/import_ttf/ttf_load.h (nonexistent) +++ tags/2.3.0/src_plugins/import_ttf/ttf_load.h (revision 33253) @@ -0,0 +1,83 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * ttf low level loader + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_TTF_LOAD_H +#define PCB_TTF_LOAD_H + +#include "config.h" + +#include +#include +#include + +#include +#include +#include + +#include "font.h" + +typedef struct pcb_ttf_s { + FT_Library library; + FT_Face face; +} pcb_ttf_t; + +/* Stroker backend; this low level lib does not know how to draw anything but + calls back the stroker for outline objects */ +typedef struct pcb_ttf_stroke_s pcb_ttf_stroke_t; +struct pcb_ttf_stroke_s { + FT_Outline_Funcs funcs; + void (*init)(pcb_ttf_stroke_t *s); + void (*start)(pcb_ttf_stroke_t *s, int chr); + void (*finish)(pcb_ttf_stroke_t *s); + void (*uninit)(pcb_ttf_stroke_t *s); + + double x, y; /* in freeftype's coords */ + double dx, dy, scale_x, scale_y; + pcb_symbol_t *sym; + pcb_ttf_t *ttf; + + + unsigned want_poly:1; + + vtp0_t poly_pos, poly_neg; /* of (rnd_polyarea_t *) */ + rnd_pline_t *contour; +}; + +/* Load the ttf font from fn; return 0 on success */ +FT_Error pcb_ttf_load(pcb_ttf_t *ttf, const char *fn); + +int pcb_ttf_unload(pcb_ttf_t *ctx); + +/* Use str to trace the outline of a glyph; returns 0 on success */ +FT_Error pcb_ttf_trace(pcb_ttf_t *ctx, FT_ULong ttf_chr, FT_ULong out_chr, pcb_ttf_stroke_t *str, unsigned short int scale); + +/* Convert an error code into a human readable error message */ +const char *pcb_ttf_errmsg(FT_Error errnum); + + +#endif Index: tags/2.3.0/src_plugins/io_autotrax/Makefile =================================================================== --- tags/2.3.0/src_plugins/io_autotrax/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/io_autotrax/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_io_autotrax + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/io_autotrax/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/io_autotrax/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/io_autotrax/Plug.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +put /local/pcb/mod {io_autotrax} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/io_autotrax/io_autotrax.o + $(PLUGDIR)/io_autotrax/write.o + $(PLUGDIR)/io_autotrax/read.o +@] + +switch /local/pcb/io_autotrax/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/io_autotrax/io_autotrax.c =================================================================== --- tags/2.3.0/src_plugins/io_autotrax/io_autotrax.c (nonexistent) +++ tags/2.3.0/src_plugins/io_autotrax/io_autotrax.c (revision 33253) @@ -0,0 +1,98 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * autotrax IO plugin - plugin coordination + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include +#include "plug_io.h" +#include "write.h" +#include "read.h" +#include + +#include "board.h" +#include "conf_core.h" +#include "buffer.h" +#include +#include + +static pcb_plug_io_t io_autotrax; +static const char *autotrax_cookie = "autotrax IO"; + + +int io_autotrax_fmt(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, int wr, const char *fmt) +{ + if (wr && (typ & PCB_IOT_FOOTPRINT)) /* no footprint write */ + return 0; + + if (strcmp(ctx->description, fmt) == 0) + return 200; + + if ((strcmp(fmt, "Protel autotrax") != 0) || + ((typ & (~(PCB_IOT_FOOTPRINT | PCB_IOT_BUFFER | PCB_IOT_PCB))) != 0)) + return 0; + + return 100; +} + +int pplg_check_ver_io_autotrax(int ver_needed) { return 0; } + +void pplg_uninit_io_autotrax(void) +{ + rnd_remove_actions_by_cookie(autotrax_cookie); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_autotrax); +} + +int pplg_init_io_autotrax(void) +{ + RND_API_CHK_VER; + + io_autotrax.plugin_data = NULL; + io_autotrax.fmt_support_prio = io_autotrax_fmt; + io_autotrax.test_parse = io_autotrax_test_parse; + io_autotrax.parse_pcb = io_autotrax_read_pcb; + io_autotrax.parse_footprint = NULL; + io_autotrax.map_footprint = NULL; + io_autotrax.parse_font = NULL; + io_autotrax.write_buffer = NULL; + io_autotrax.write_pcb = io_autotrax_write_pcb; + io_autotrax.default_fmt = "Protel autotrax"; + io_autotrax.description = "Protel autotrax and easytrax"; + io_autotrax.save_preference_prio = 80; + io_autotrax.default_extension = ".PCB"; + io_autotrax.fp_extension = ".PCB"; + io_autotrax.mime_type = "application/x-autotrax-pcb"; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_autotrax); + + return 0; +} + Index: tags/2.3.0/src_plugins/io_autotrax/io_autotrax.pup =================================================================== --- tags/2.3.0/src_plugins/io_autotrax/io_autotrax.pup (nonexistent) +++ tags/2.3.0/src_plugins/io_autotrax/io_autotrax.pup (revision 33253) @@ -0,0 +1,12 @@ +$class io +$short autotrax (freeware PCB CAD) +$long Import and export autotrax layouts and footprints. +$state works +$fmt-native no +$fmt-feature-r autotrax PCB board, version 4 +$fmt-feature-r autotrax PCB board, version 5 +$fmt-feature-w autotrax PCB board, version 4 +$package io-alien +default buildin +dep lib_polyhelp +autoload 1 Index: tags/2.3.0/src_plugins/io_autotrax/read.c =================================================================== --- tags/2.3.0/src_plugins/io_autotrax/read.c (nonexistent) +++ tags/2.3.0/src_plugins/io_autotrax/read.c (revision 33253) @@ -0,0 +1,1206 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016, 2017, 2018 Tibor 'Igor2' Palinkas + * Copyright (C) 2016, 2017 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include "board.h" +#include "plug_io.h" +#include +#include "data.h" +#include "read.h" +#include "layer.h" +#include "polygon.h" +#include /* for distance calculations */ +#include "conf_core.h" +#include "move.h" +#include +#include "rotate.h" +#include +#include "undo.h" + +#include "../src_plugins/lib_compat_help/pstk_compat.h" +#include "../src_plugins/lib_compat_help/pstk_help.h" +#include "../src_plugins/lib_compat_help/subc_help.h" + +#define PCB REPLACE_THIS + +#define MAXREAD 255 + +/* remove leading whitespace */ +#define ltrim(s) while(isspace(*s)) s++ + +/* remove trailing newline */ +#define rtrim(s) \ + do { \ + char *end; \ + for(end = s + strlen(s) - 1; (end >= s) && ((*end == '\r') || (*end == '\n')); end--) \ + *end = '\0'; \ + } while(0) + +/* read the next line, increasing the line number lineno */ +#define fgetline(s, size, stream, lineno) \ + ((lineno)++,fgets((s), (size), (stream))) + +/* the following sym_attr_t struct, #define... and sym_flush() routine could go in a shared lib */ + +typedef struct { + char *refdes; + char *value; + char *footprint; +} symattr_t; + +#define null_empty(s) ((s) == NULL ? "" : (s)) + +static void sym_flush(rnd_hidlib_t *hl, symattr_t *sattr) +{ + if (sattr->refdes != NULL) { + if (sattr->footprint == NULL) + rnd_message(RND_MSG_ERROR, "protel autotrax: not importing refdes=%s: no footprint specified\n", sattr->refdes); + else + rnd_actionva(hl, "ElementList", "Need", null_empty(sattr->refdes), null_empty(sattr->footprint), null_empty(sattr->value), NULL); + } + free(sattr->refdes); + sattr->refdes = NULL; + free(sattr->value); + sattr->value = NULL; + free(sattr->footprint); + sattr->footprint = NULL; +} + + +/* the followinf read_state_t struct could go in a shared lib for parsers doing layer mapping */ + +typedef struct { + pcb_board_t *pcb; + const char *Filename; + rnd_conf_role_t settings_dest; + rnd_layer_id_t protel_to_stackup[14]; + int lineno; + rnd_coord_t mask_clearance; + rnd_coord_t copper_clearance; + rnd_coord_t minimum_comp_pin_drill; + int trax_version; + int ignored_keepout_element; + int ignored_layer_zero_element; +} read_state_t; + +static int rdax_net(read_state_t *st, FILE *FP); /* describes netlists for the layout */ + +/* Look up (or even alloc) a layer on the board or in a subc, by autotrax layer number */ +static pcb_layer_t *autotrax_get_layer(read_state_t *st, pcb_subc_t *subc, int autotrax_layer, const char *otyp) +{ + int lid, comb; + pcb_layer_type_t lyt; + + if (autotrax_layer == 12) { + st->ignored_keepout_element++; + return NULL; + } + if (autotrax_layer == 0) { + rnd_message(RND_MSG_ERROR, "Ignored '%s' on easy/autotrax layer zero, %s:%d\n", otyp, st->Filename, st->lineno); + st->ignored_layer_zero_element++; + return NULL; + } + + lid = st->protel_to_stackup[autotrax_layer]; + if (lid < 0) { + rnd_message(RND_MSG_ERROR, "Ignored '%s' on easy/autotrax unknown layer %d, %s:%d\n", otyp, autotrax_layer, st->Filename, st->lineno); + return NULL; + } + + if (subc == NULL) + return &st->pcb->Data->Layer[lid]; + + lyt = pcb_layer_flags(st->pcb, lid); + comb = 0; + return pcb_subc_get_layer(subc, lyt, comb, 1, st->pcb->Data->Layer[lid].name, rnd_true); +} + +/* autotrax_free_text/component_text */ +static int rdax_text(read_state_t *st, FILE *FP, pcb_subc_t *subc) +{ + int height_mil; + int autotrax_layer = 0; + char line[MAXREAD], *t; + int success; + int valid = 1; + rnd_coord_t X, Y, linewidth; + int scaling = 100; + unsigned direction = 0; /* default is horizontal */ + pcb_flag_t Flags; + pcb_layer_t *ly; + pcb_layer_type_t lyt; + + if (fgetline(line, sizeof(line), FP, st->lineno) != NULL) { + int argc; + char **argv, *s; + + s = line; + ltrim(s); + rtrim(s); + argc = qparse2(s, &argv, 0); + if (argc > 5) { + X = rnd_get_value_ex(argv[0], NULL, NULL, NULL, "mil", &success); + valid &= success; + Y = rnd_get_value_ex(argv[1], NULL, NULL, NULL, "mil", &success); + valid &= success; + height_mil = rnd_get_value_ex(argv[2], NULL, NULL, NULL, NULL, &success); + valid &= success; + scaling = (100 * height_mil) / 60; + direction = rnd_get_value_ex(argv[3], NULL, NULL, NULL, NULL, &success); + direction = direction % 4; /* ignore mirroring */ + valid &= success; + linewidth = rnd_get_value_ex(argv[4], NULL, NULL, NULL, "mil", &success); + valid &= success; + autotrax_layer = rnd_get_value_ex(argv[5], NULL, NULL, NULL, NULL, &success); + valid &= (success && (autotrax_layer > 0) && (autotrax_layer < 14)); + /* we ignore the user routed flag */ + qparse_free(argc, &argv); + } + else { + rnd_message(RND_MSG_ERROR, "Insufficient free string attribute fields, %s:%d\n", st->Filename, st->lineno); + qparse_free(argc, &argv); + return -1; + } + } + + if (!valid) { + rnd_message(RND_MSG_ERROR, "Failed to parse text attribute fields, %s:%d\n", st->Filename, st->lineno); + return -1; + } + + if (fgetline(line, sizeof(line), FP, st->lineno) == NULL) { + rnd_message(RND_MSG_ERROR, "Empty free string text field, %s:%d\n", st->Filename, st->lineno); + strcpy(line, "(empty text field)"); + } /* this helps the parser fail more gracefully if excessive newlines, or empty text field */ + + t = line; + ltrim(t); + rtrim(t); /*need to remove trailing '\r' to avoid rendering oddities */ + + /* # TODO - ABOUT HERE, CAN DO ROTATION/DIRECTION CONVERSION */ + + ly = autotrax_get_layer(st, subc, autotrax_layer, "text"); + if (ly == NULL) + return 0; + + lyt = pcb_layer_flags_(ly); + if (lyt & PCB_LYT_BOTTOM) Flags = pcb_flag_make(PCB_FLAG_ONSOLDER); + else Flags = pcb_flag_make(0); + +TODO("textrot: is there a real rotation angle available?") + if (pcb_text_new(ly, pcb_font(st->pcb, 0, 1), X, Y, 90.0*direction, scaling, 0, t, Flags) != 0) + return 1; + return -1; + +TODO("do not use strlen() for this, decide where to move this code") +/* + if (strlen(t) == 0) { + rnd_message(RND_MSG_ERROR, "Empty free string not placed on layout, %s:%d\n", st->Filename, st->lineno); + return 0; + } +*/ +} + +/* autotrax_pcb free_track/component_track */ +static int rdax_track(read_state_t *st, FILE *FP, pcb_subc_t *subc) +{ + char line[MAXREAD]; + rnd_coord_t X1, Y1, X2, Y2, Thickness, Clearance; + pcb_flag_t Flags = pcb_flag_make(0); + int autotrax_layer = 0; + int success; + int valid = 1; + pcb_layer_t *ly; + + Thickness = 0; + Clearance = st->copper_clearance; /* start with sane default */ + + if (fgetline(line, sizeof(line), FP, st->lineno) != NULL) { + int argc; + char **argv, *s; + + s = line; + ltrim(s); + rtrim(s); + argc = qparse2(s, &argv, 0); + if (argc > 5) { + X1 = rnd_get_value_ex(argv[0], NULL, NULL, NULL, "mil", &success); + valid &= success; + Y1 = rnd_get_value_ex(argv[1], NULL, NULL, NULL, "mil", &success); + valid &= success; + X2 = rnd_get_value_ex(argv[2], NULL, NULL, NULL, "mil", &success); + valid &= success; + Y2 = rnd_get_value_ex(argv[3], NULL, NULL, NULL, "mil", &success); + valid &= success; + Thickness = rnd_get_value_ex(argv[4], NULL, NULL, NULL, "mil", &success); + valid &= success; + autotrax_layer = rnd_get_value_ex(argv[5], NULL, NULL, NULL, NULL, &success); + valid &= (success && (autotrax_layer > 0) && (autotrax_layer < 14)); + /* we ignore the user routed flag */ + qparse_free(argc, &argv); + } + else { + rnd_message(RND_MSG_ERROR, "Insufficient track attribute fields, %s:%d\n", st->Filename, st->lineno); + qparse_free(argc, &argv); + return -1; + } + } + + ly = autotrax_get_layer(st, subc, autotrax_layer, "line"); + if (ly == NULL) + return 0; + + if (pcb_line_new(ly, X1, Y1, X2, Y2, Thickness, Clearance, Flags) != NULL) + return 1; + return -1; +} + +/* autotrax_pcb free arc and component arc parser */ +static int rdax_arc(read_state_t *st, FILE *FP, pcb_subc_t *subc) +{ + char line[MAXREAD]; + int segments = 15; /* full circle by default */ + int success; + int valid = 1; + int autotrax_layer = 0; + pcb_layer_t *ly; + + rnd_coord_t centreX, centreY, width, height, Thickness, Clearance, radius; + rnd_angle_t start_angle = 0.0; + rnd_angle_t delta = 360.0; + + pcb_flag_t Flags = pcb_flag_make(0); /* start with something bland here */ + rnd_layer_id_t PCB_layer; + + Thickness = 0; + Clearance = st->copper_clearance; /* start with sane default */ + + if (fgetline(line, sizeof(line), FP, st->lineno) != NULL) { + int argc; + char **argv, *s; + s = line; + ltrim(s); + rtrim(s); + argc = qparse2(s, &argv, 0); + if (argc > 5) { + centreX = rnd_get_value_ex(argv[0], NULL, NULL, NULL, "mil", &success); + valid &= success; + centreY = rnd_get_value_ex(argv[1], NULL, NULL, NULL, "mil", &success); + valid &= success; + radius = rnd_get_value_ex(argv[2], NULL, NULL, NULL, "mil", &success); + valid &= success; + segments = rnd_get_value_ex(argv[3], NULL, NULL, NULL, NULL, &success); + valid &= success; + Thickness = rnd_get_value_ex(argv[4], NULL, NULL, NULL, "mil", &success); + valid &= success; + autotrax_layer = rnd_get_value_ex(argv[5], NULL, NULL, NULL, NULL, &success); + PCB_layer = st->protel_to_stackup[(int)autotrax_layer]; + valid &= (success && (autotrax_layer > 0) && (autotrax_layer < 14)); + /* we ignore the user routed flag */ + qparse_free(argc, &argv); + } + else { + qparse_free(argc, &argv); + rnd_message(RND_MSG_ERROR, "Insufficient arc attribute fields, %s:%d\n", st->Filename, st->lineno); + return -1; + } + } + + if (!valid) { + rnd_message(RND_MSG_ERROR, "Unable to parse arc attribute fields, %s:%d\n", st->Filename, st->lineno); + return -1; + } + + + width = height = radius; + +/* we now need to decrypt the segments value. Some definitions will represent two arcs. +Bit 0 : RU quadrant +Bit 1 : LU quadrant +Bit 2 : LL quadrant +Bit 3 : LR quadrant + +Since the board will be flipped, we should swap upper and lower quadrants + +TODO: This needs further testing to ensure the refererence +document used reflects actual outputs from protel autotrax +*/ + if (segments == 10) { /* LU + RL quadrants */ + start_angle = 180.0; + delta = 90.0; + pcb_arc_new(&st->pcb->Data->Layer[PCB_layer], centreX, centreY, width, height, start_angle, delta, Thickness, Clearance, Flags, rnd_true); + start_angle = 0.0; + } + else if (segments == 5) { /* RU + LL quadrants */ + start_angle = 270.0; + delta = 90.0; + pcb_arc_new(&st->pcb->Data->Layer[PCB_layer], centreX, centreY, width, height, start_angle, delta, Thickness, Clearance, Flags, rnd_true); + start_angle = 90.0; + } + else if (segments >= 15) { /* whole circle */ + start_angle = 0.0; + delta = 360.0; + } + else if (segments == 1) { /* RU quadrant */ + start_angle = 90.0; + delta = 90.0; + } + else if (segments == 2) { /* LU quadrant */ + start_angle = 0.0; + delta = 90.0; + } + else if (segments == 4) { /* LL quadrant */ + start_angle = 270.0; + delta = 90.0; + } + else if (segments == 8) { /* RL quadrant */ + start_angle = 180.0; + delta = 90.0; + } + else if (segments == 3) { /* Upper half */ + start_angle = 0.0; + delta = 180.0; + } + else if (segments == 6) { /* Left half */ + start_angle = 270.0; + delta = 180.0; + } + else if (segments == 12) { /* Lower half */ + start_angle = 180.0; + delta = 180.0; + } + else if (segments == 9) { /* Right half */ + start_angle = 90.0; + delta = 180.0; + } + else if (segments == 14) { /* not RUQ */ + start_angle = 180.0; + delta = 270.0; + } + else if (segments == 13) { /* not LUQ */ + start_angle = 90.0; + delta = 270.0; + } + else if (segments == 11) { /* not LLQ */ + start_angle = 0.0; + delta = 270.0; + } + else if (segments == 7) { /* not RLQ */ + start_angle = 270.0; + delta = 270.0; + } + + ly = autotrax_get_layer(st, subc, autotrax_layer, "arc"); + if (ly == NULL) + return 0; + + if (pcb_arc_new(ly, centreX, centreY, width, height, start_angle, delta, Thickness, Clearance, Flags, rnd_true) != 0) + return 1; + return -1; +} + +/* autotrax_pcb via parser */ +static int rdax_via(read_state_t *st, FILE *FP, pcb_subc_t *subc) +{ + char line[MAXREAD]; + char *name; + int success; + int valid = 1; + pcb_data_t *data = (subc == NULL) ? st->pcb->Data : subc->data; + pcb_pstk_t *ps; + rnd_coord_t X, Y, Thickness, Clearance, Mask, Drill; /* not sure what to do with mask */ + + Thickness = 0; + Clearance = st->copper_clearance; /* start with sane default */ + + Drill = RND_MM_TO_COORD(0.300); /* start with something sane */ + + name = rnd_strdup("unnamed"); + + if (fgetline(line, sizeof(line), FP, st->lineno) != NULL) { + int argc; + char **argv, *s; + s = line; + ltrim(s); + rtrim(s); + argc = qparse2(s, &argv, 0); + if (argc >= 4) { + X = rnd_get_value_ex(argv[0], NULL, NULL, NULL, "mil", &success); + valid &= success; + Y = rnd_get_value_ex(argv[1], NULL, NULL, NULL, "mil", &success); + valid &= success; + Thickness = rnd_get_value_ex(argv[2], NULL, NULL, NULL, "mil", &success); + valid &= success; + Drill = rnd_get_value_ex(argv[3], NULL, NULL, NULL, "mil", &success); + valid &= success; + qparse_free(argc, &argv); + } + else { + qparse_free(argc, &argv); + rnd_message(RND_MSG_ERROR, "Insufficient via attribute fields, %s:%d\n", st->Filename, st->lineno); + return -1; + } + } + + if (!valid) { + rnd_message(RND_MSG_ERROR, "Unable to parse via attribute fields, %s:%d\n", st->Filename, st->lineno); + return -1; + } + + Mask = Thickness + st->mask_clearance; + + ps = pcb_pstk_new_compat_via(data, -1, X, Y, Drill, Thickness, Clearance, Mask, PCB_PSTK_COMPAT_ROUND, 1); + return ps != NULL; +} + +/* autotrax_pcb free or component pad +x y X_size Y_size shape holesize pwr/gnd layer +padname +may need to think about hybrid outputs, like pad + hole, to match possible features in protel autotrax +*/ +static int rdax_pad(read_state_t *st, FILE *FP, pcb_subc_t *subc, int component) +{ + char line[MAXREAD], *s; + int Connects = 0; + int Shape = 0; + int autotrax_layer = 0; + int valid = 1; + int success; + rnd_coord_t X, Y, X_size, Y_size, Thickness, Clearance, Mask, Drill; + pcb_data_t *data = (subc == NULL) ? st->pcb->Data : subc->data; + pcb_pstk_t *ps; + + Thickness = 0; + Clearance = st->copper_clearance; /* start with sane default */ + + Drill = RND_MM_TO_COORD(0.300); /* start with something sane */ + + if (fgetline(line, sizeof(line), FP, st->lineno) != NULL) { + int argc; + char **argv, *end; + s = line; + ltrim(s); + rtrim(s); + argc = qparse2(s, &argv, 0); + if (argc <= 6) { + qparse_free(argc, &argv); + rnd_message(RND_MSG_ERROR, "Insufficient pad attribute fields, %s:%d\n", st->Filename, st->lineno); + return -1; + } + X = rnd_get_value_ex(argv[0], NULL, NULL, NULL, "mil", &success); + valid &= success; + Y = rnd_get_value_ex(argv[1], NULL, NULL, NULL, "mil", &success); + valid &= success; + X_size = rnd_get_value_ex(argv[2], NULL, NULL, NULL, "mil", &success); + valid &= success; + Y_size = rnd_get_value_ex(argv[3], NULL, NULL, NULL, "mil", &success); + valid &= success; + Shape = strtol(argv[4], &end, 10); + if (*end != '\0') valid = 0; + Drill = rnd_get_value_ex(argv[5], NULL, NULL, NULL, "mil", &success); + valid &= success; + Connects = strtol(argv[6], &end, 10); + if (*end != '\0') valid = 0; + /* which specifies GND or Power connection for pin/pad/via */ + autotrax_layer = strtol(argv[7], &end, 10); + if (*end != '\0') valid = 0; + valid &= (success && (autotrax_layer > 0) && (autotrax_layer < 14)); + qparse_free(argc, &argv); + } + + if (!valid) { + rnd_message(RND_MSG_ERROR, "Insufficient pad attribute fields, %s:%d\n", st->Filename, st->lineno); + return -1; + } + +/* now find name as string on next line and copy it */ +TODO("can not exit above if we need to read this line") + if (fgetline(line, sizeof(line), FP, st->lineno) == NULL) { + rnd_message(RND_MSG_ERROR, "Error parsing pad text field line, %s:%d\n", st->Filename, st->lineno); + return -1; + } + s = line; + rtrim(s); /* avoid rendering oddities on layout, and netlist matching confusion */ + + if (autotrax_layer == 11) return 1; /* layer 11: "board" layer - looks like an ignore */ + + /* these features can have connections to GND and PWR + planes specified in protel autotrax (seems rare though) + so we warn the user is this is the case */ + switch (Connects) { + case 1: + rnd_message(RND_MSG_ERROR, "pin clears PWR/GND, %s:%d.\n", st->Filename, st->lineno); + break; + case 2: + rnd_message(RND_MSG_ERROR, "pin requires relief to GND plane, %s:%d.\n", st->Filename, st->lineno); + break; + case 4: + rnd_message(RND_MSG_ERROR, "pin requires relief to PWR plane, %s:%d.\n", st->Filename, st->lineno); + break; + case 3: + rnd_message(RND_MSG_ERROR, "pin should connect to PWR plane, %s:%d.\n", st->Filename, st->lineno); + break; + case 5: + rnd_message(RND_MSG_ERROR, "pin should connect to GND plane, %s:%d.\n", st->Filename, st->lineno); + break; + } + + Thickness = MIN(X_size, Y_size); + Mask = Thickness + st->mask_clearance; + + if (autotrax_layer == 0) { + rnd_message(RND_MSG_ERROR, "Ignored pad on easy/autotrax layer zero, %s:%d\n", st->Filename, st->lineno); + st->ignored_layer_zero_element++; + return 0; + } + + /* Easytrax seems to specify zero drill for some component pins, and round free pins/pads */ + if (((st->trax_version == 5) && (X_size == Y_size) && component && (Drill == 0)) + || ((st->trax_version == 5) && (X_size == Y_size) && (Shape == 1) && (Drill == 0))) { + Drill = st->minimum_comp_pin_drill; /* ?may be better off using half the thickness for drill */ + } + +/* currently ignore: + shape: + 5 Cross Hair Target + 6 Moiro Target */ + if ((Shape == 5) || (Shape == 6)) { + rnd_message(RND_MSG_ERROR, "Unsupported FP target shape %d, %s:%d.\n", Shape, st->Filename, st->lineno); + return 0; + } + + { /* pad not within element, i.e. a free pad/pin/via */ + pcb_pstk_shape_t sh[8]; + int n; + + memset(sh, 0, sizeof(sh)); + sh[0].layer_mask = PCB_LYT_PASTE; sh[0].comb = PCB_LYC_AUTO; + sh[1].layer_mask = PCB_LYT_MASK; sh[1].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + sh[2].layer_mask = PCB_LYT_COPPER; + sh[3].layer_mask = PCB_LYT_COPPER; + sh[4].layer_mask = PCB_LYT_COPPER; + sh[5].layer_mask = PCB_LYT_MASK; sh[5].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + sh[6].layer_mask = PCB_LYT_PASTE; sh[6].comb = PCB_LYC_AUTO; + + switch(autotrax_layer) { + case 1: + for(n = 0; n < 3; n++) + sh[n].layer_mask |= PCB_LYT_TOP; + sh[3].layer_mask = 0; + break; + case 6: + for(n = 0; n < 3; n++) + sh[n].layer_mask |= PCB_LYT_BOTTOM; + sh[3].layer_mask = 0; + break; + case 13: + for(n = 0; n < 3; n++) + sh[n].layer_mask |= PCB_LYT_TOP; + sh[3].layer_mask |= PCB_LYT_INTERN; + for(n = 4; n < 7; n++) + sh[n].layer_mask |= PCB_LYT_BOTTOM; + break; + default: + rnd_message(RND_MSG_ERROR, "Unsupported FP layer: %d, %s:%d.\n", autotrax_layer, st->Filename, st->lineno); + return 0; + } + + switch(Shape) { + case 1: /* round */ + for(n = 0; n < 7; n++) { + rnd_coord_t clr = (sh[n].layer_mask & PCB_LYT_MASK) ? Clearance : 0; + if (sh[n].layer_mask == 0) break; + pcb_shape_oval(&sh[n], X_size+clr, Y_size+clr); + } + break; + case 2: /* rect */ + case 4: /* round-rect - for now */ +TODO("generate round-rect") + for(n = 0; n < 7; n++) { + rnd_coord_t clr = (sh[n].layer_mask & PCB_LYT_MASK) ? Clearance : 0; + if (sh[n].layer_mask == 0) break; + pcb_shape_rect(&sh[n], X_size+clr, Y_size+clr); + } + break; + case 3: /* octa */ +TODO("generate octa") + default: + rnd_message(RND_MSG_ERROR, "Unsupported FP shape: %d, %s:%d.\n", Shape, st->Filename, st->lineno); + return 0; + } + ps = pcb_pstk_new_from_shape(data, X, Y, Drill, 1, Clearance, sh); + if (ps == NULL) + rnd_message(RND_MSG_ERROR, "Failed to convert FP to padstack, %s:%d.\n", st->Filename, st->lineno); + + return (ps != NULL); + } +} + +/* protel autorax free fill (rectangular pour) parser - the closest thing protel autotrax has to a polygon */ +static int rdax_fill(read_state_t *st, FILE *FP, pcb_subc_t *subc) +{ + int success; + int valid = 1; + int autotrax_layer = 0; + char line[MAXREAD]; + pcb_poly_t *polygon = NULL; + pcb_flag_t flags = pcb_flag_make(PCB_FLAG_CLEARPOLY); + rnd_coord_t X1, Y1, X2, Y2, Clearance; + pcb_layer_t *ly; + + Clearance = st->copper_clearance; /* start with sane default */ + + if (fgetline(line, sizeof(line), FP, st->lineno) != NULL) { + int argc; + char **argv, *s; + s = line; + ltrim(s); + rtrim(s); + argc = qparse2(s, &argv, 0); + if (argc >= 5) { + X1 = rnd_get_value_ex(argv[0], NULL, NULL, NULL, "mil", &success); + valid &= success; + Y1 = rnd_get_value_ex(argv[1], NULL, NULL, NULL, "mil", &success); + valid &= success; + X2 = rnd_get_value_ex(argv[2], NULL, NULL, NULL, "mil", &success); + valid &= success; + Y2 = rnd_get_value_ex(argv[3], NULL, NULL, NULL, "mil", &success); + valid &= success; +TODO("do not use get_value_ex for plain integers (revise the whole file for this)") + autotrax_layer = rnd_get_value_ex(argv[4], NULL, NULL, NULL, NULL, &success); + valid &= (success && (autotrax_layer > 0) && (autotrax_layer < 14)); + qparse_free(argc, &argv); + } + else { + qparse_free(argc, &argv); + rnd_message(RND_MSG_ERROR, "Insufficient fill attribute fields, %s:%d\n", st->Filename, st->lineno); + return -1; + } + } + + if (!valid) { + rnd_message(RND_MSG_ERROR, "Fill attribute fields unable to be parsed, %s:%d\n", st->Filename, st->lineno); + return -1; + } + +TODO("figure if autotrax really converts layer 1 and 6 polygons to pads") + if ((subc == NULL) || ((autotrax_layer != 1) && (autotrax_layer != 6))) { + ly = autotrax_get_layer(st, subc, autotrax_layer, "polygon"); + if (ly == NULL) + return 0; + + polygon = pcb_poly_new(ly, 0, flags); + if (polygon == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to allocate polygon, %s:%d\n", st->Filename, st->lineno); + return -1; + } + + pcb_poly_point_new(polygon, X1, Y1); + pcb_poly_point_new(polygon, X2, Y1); + pcb_poly_point_new(polygon, X2, Y2); + pcb_poly_point_new(polygon, X1, Y2); + pcb_add_poly_on_layer(ly, polygon); + if (subc == NULL) + pcb_poly_init_clip(st->pcb->Data, ly, polygon); + return 1; + } + else { + rnd_coord_t w = X2-X1, h = Y2-Y1; + pcb_pstk_shape_t sh[4]; + pcb_layer_type_t side; + int n; + + switch(autotrax_layer) { + case 1: side = PCB_LYT_TOP; break; + case 6: side = PCB_LYT_BOTTOM; break; + } + + memset(sh, 0, sizeof(sh)); + sh[0].layer_mask = side | PCB_LYT_PASTE; sh[0].comb = PCB_LYC_AUTO; + sh[1].layer_mask = side | PCB_LYT_MASK; sh[1].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + sh[2].layer_mask = side | PCB_LYT_COPPER; + pcb_shape_rect(&sh[0], w, h); + pcb_shape_rect(&sh[1], w+Clearance, h+Clearance); + pcb_shape_rect(&sh[2], w, h); + if (pcb_pstk_new_from_shape(subc->data, (X1+X2)/2, (Y1+Y2)/2, 0, 0, Clearance, sh) != NULL) + return 1; + rnd_message(RND_MSG_ERROR, "SMD pad: filed to convert from polygon, %s:%d\n", st->Filename, st->lineno); + } + + return -1; +} + +static rnd_layer_id_t autotrax_reg_layer(read_state_t *st, const char *autotrax_layer, unsigned int mask) +{ + rnd_layer_id_t id; + if (pcb_layer_list(st->pcb, mask, &id, 1) != 1) { + rnd_layergrp_id_t gid; + pcb_layergrp_list(st->pcb, mask, &gid, 1); + id = pcb_layer_create(st->pcb, gid, autotrax_layer, 0); + } + return id; +} + +/* create a set of default layers, since protel has a static stackup */ +static int autotrax_create_layers(read_state_t *st) +{ + + pcb_layergrp_t *g; + rnd_layer_id_t id; + + pcb_layer_group_setup_default(st->pcb); + + st->protel_to_stackup[7] = autotrax_reg_layer(st, "top silk", PCB_LYT_SILK | PCB_LYT_TOP); + st->protel_to_stackup[8] = autotrax_reg_layer(st, "bottom silk", PCB_LYT_SILK | PCB_LYT_BOTTOM); + + st->protel_to_stackup[1] = autotrax_reg_layer(st, "top copper", PCB_LYT_COPPER | PCB_LYT_TOP); + st->protel_to_stackup[6] = autotrax_reg_layer(st, "bottom copper", PCB_LYT_COPPER | PCB_LYT_BOTTOM); + + if (pcb_layer_list(st->pcb, PCB_LYT_SILK | PCB_LYT_TOP, &id, 1) == 1) { + rnd_layergrp_id_t gid; + pcb_layergrp_list(st->pcb, PCB_LYT_SILK | PCB_LYT_TOP, &gid, 1); + st->protel_to_stackup[11] = pcb_layer_create(st->pcb, gid, "Board", 0); /* != outline, cutouts */ + pcb_layergrp_list(st->pcb, PCB_LYT_SILK | PCB_LYT_TOP, &gid, 1); + st->protel_to_stackup[13] = pcb_layer_create(st->pcb, gid, "Multi", 0); + } + else { + rnd_message(RND_MSG_ERROR, "Unable to create Keepout, Multi layers in default top silk group\n"); + } + + g = pcb_get_grp_new_intern(st->pcb, -1); + st->protel_to_stackup[2] = pcb_layer_create(st->pcb, g - st->pcb->LayerGroups.grp, "Mid1", 0); + + g = pcb_get_grp_new_intern(st->pcb, -1); + st->protel_to_stackup[3] = pcb_layer_create(st->pcb, g - st->pcb->LayerGroups.grp, "Mid2", 0); + + g = pcb_get_grp_new_intern(st->pcb, -1); + st->protel_to_stackup[4] = pcb_layer_create(st->pcb, g - st->pcb->LayerGroups.grp, "Mid3", 0); + + g = pcb_get_grp_new_intern(st->pcb, -1); + st->protel_to_stackup[5] = pcb_layer_create(st->pcb, g - st->pcb->LayerGroups.grp, "Mid4", 0); + + g = pcb_get_grp_new_intern(st->pcb, -1); + st->protel_to_stackup[9] = pcb_layer_create(st->pcb, g - st->pcb->LayerGroups.grp, "GND", 0); + + g = pcb_get_grp_new_intern(st->pcb, -1); + st->protel_to_stackup[10] = pcb_layer_create(st->pcb, g - st->pcb->LayerGroups.grp, "Power", 0); + + g = pcb_get_grp_new_intern(st->pcb, -1); + g->name = rnd_strdup("outline"); /* equivalent to keepout = layer 12 in autotrax */ + g->ltype = PCB_LYT_BOUNDARY; /* and includes cutouts */ + pcb_layergrp_set_purpose__(g, rnd_strdup("uroute"), 0); + st->protel_to_stackup[12] = autotrax_reg_layer(st, "outline", PCB_LYT_BOUNDARY); + + pcb_layergrp_inhibit_dec(); + + return 0; +} + +/* autotrax_pcb rdax_net ; used to read net descriptions for the entire layout */ +static int rdax_net(read_state_t *st, FILE *FP) +{ + symattr_t sattr; + + char line[MAXREAD]; + char *netname, *s; + int length = 0; + int in_comp = 0; + int in_net = 1; + int in_node_table = 0; + int endpcb = 0; + + netname = NULL; + + memset(&sattr, 0, sizeof(sattr)); + + /* next line is the netlist name */ + + if (fgetline(line, sizeof(line), FP, st->lineno) != NULL) { + s = line; + rtrim(s); + netname = rnd_strdup(line); + } + else { + rnd_message(RND_MSG_ERROR, "Empty netlist name found, %s:%d\n", st->Filename, st->lineno); + return -1; + } + fgetline(line, sizeof(line), FP, st->lineno); + s = line; + rtrim(s); + while(!feof(FP) && !endpcb && in_net) { + fgetline(line, sizeof(line), FP, st->lineno); + if (strncmp(line, "[", 1) == 0) { + in_comp = 1; + while(in_comp) { + if (fgetline(line, sizeof(line), FP, st->lineno) == NULL) { + rnd_message(RND_MSG_ERROR, "Empty line in netlist COMP, %s:%d\n", st->Filename, st->lineno); + } + else { + if (fgetline(line, sizeof(line), FP, st->lineno) == NULL) { + rnd_message(RND_MSG_ERROR, "Empty netlist REFDES, %s:%d\n", st->Filename, st->lineno); + } + else { + s = line; + rtrim(s); + sym_flush(&st->pcb->hidlib, &sattr); + free(sattr.refdes); + sattr.refdes = rnd_strdup(line); + } + if (fgetline(line, sizeof(line), FP, st->lineno) == NULL) { + rnd_message(RND_MSG_ERROR, "Empty NETDEF package, %s:%d\n", st->Filename, st->lineno); + free(sattr.footprint); + sattr.footprint = rnd_strdup("unknown"); + } + else { + s = line; + rtrim(s); + free(sattr.footprint); + sattr.footprint = rnd_strdup(line); + } + if (fgetline(line, sizeof(line), FP, st->lineno) == NULL) { + free(sattr.value); + sattr.value = rnd_strdup("value"); + } + else { + s = line; + rtrim(s); + free(sattr.value); + sattr.value = rnd_strdup(line); + } + } + while(fgetline(line, sizeof(line), FP, st->lineno) == NULL) { + /* clear empty lines in COMP definition */ + } + if (strncmp(line, "]", 1) == 0) { + in_comp = 0; + } + } + } + else if (strncmp(line, "(", 1) == 0) { + in_net = 1; + while(in_net || in_node_table) { + while(fgetline(line, sizeof(line), FP, st->lineno) == NULL) { + /* skip empty lines */ + } + if (strncmp(line, ")", 1) == 0) { + in_net = 0; + } + else if (strncmp(line, "{", 1) == 0) { + in_node_table = 1; + in_net = 0; + } + else if (strncmp(line, "}", 1) == 0) { + in_node_table = 0; + } + else if (!in_node_table) { + s = line; + rtrim(s); + if ((*line != '\0') && (netname != NULL)) { + rnd_actionva(&st->pcb->hidlib, "Netlist", "Add", netname, line, NULL); + } + } + } + } + else if (length >= 6 && strncmp(line, "ENDPCB", 6) == 0) { + rnd_message(RND_MSG_ERROR, "End of protel Autotrax file found in netlist section?!, %s:%d\n", st->Filename, st->lineno); + endpcb = 1; /* if we get here, something went wrong */ + } + } + sym_flush(&st->pcb->hidlib, &sattr); + + return 0; +} + +/* protel autotrax component definition parser */ +/* no mark() or location as such it seems */ +static int rdax_component(read_state_t *st, FILE *FP) +{ + int success; + int valid = 1; + int refdes_scaling = 100; + rnd_coord_t module_X, module_Y; + unsigned direction = 0; /* default is horizontal */ + char module_name[MAXREAD], module_refdes[MAXREAD], module_value[MAXREAD]; + pcb_subc_t *new_module; + + pcb_flag_t Flags = pcb_flag_make(0); /* start with something bland here */ + pcb_flag_t text_flags = pcb_flag_make(0); /* start with something bland here */ + + char *s, line[MAXREAD]; + int nonempty = 0; + int length = 0; + + if (fgetline(module_refdes, sizeof(module_refdes), FP, st->lineno) == NULL) { + strcpy(module_refdes, "unknown"); + } + s = module_refdes; + rtrim(s); /* avoid rendering oddities on layout */ + if (fgetline(module_name, sizeof(module_name), FP, st->lineno) == NULL) { + strcpy(module_name, "unknown"); + } + s = module_name; + rtrim(s); /* avoid rendering oddities on layout */ + if (fgetline(module_value, sizeof(module_value), FP, st->lineno) == NULL) { + strcpy(module_value, "unknown"); + } + s = module_value; + rtrim(s); /* avoid rendering oddities on layout */ + +/* with the header read, we now ignore the locations for the text fields in the next two lines... */ +/* we also allow up to two empty lines in case of extra newlines */ + if (fgetline(line, sizeof(line), FP, st->lineno) == NULL) { + fgetline(line, sizeof(line), FP, st->lineno); + } + if (fgetline(line, sizeof(line), FP, st->lineno) == NULL) { + fgetline(line, sizeof(line), FP, st->lineno); + } + + if (fgetline(line, sizeof(line), FP, st->lineno) != NULL) { + int argc; + char **argv, *s; + s = line; + ltrim(s); + rtrim(s); + argc = qparse2(s, &argv, 0); + if (argc >= 2) { + module_X = rnd_get_value_ex(argv[0], NULL, NULL, NULL, "mil", &success); + valid &= success; + module_Y = rnd_get_value_ex(argv[1], NULL, NULL, NULL, "mil", &success); + valid &= success; +TODO("load placement status and apply PCB_FLAG_LOCK if needed") + qparse_free(argc, &argv); + } + else { + qparse_free(argc, &argv); + rnd_message(RND_MSG_ERROR, "Insufficient COMP attribute fields, %s:%d\n", st->Filename, st->lineno); + return -1; + } + } + + if (!valid) { + rnd_message(RND_MSG_ERROR, "Unable to parse COMP attributes, %s:%d\n", st->Filename, st->lineno); + return -1; + } + + new_module = pcb_subc_alloc(); + pcb_subc_create_aux(new_module, module_X, module_Y, 0.0, 0); + pcb_attribute_put(&new_module->Attributes, "refdes", "A1"); + pcb_subc_reg(st->pcb->Data, new_module); + pcb_subc_bind_globals(st->pcb, new_module); + + nonempty = 0; + while(!feof(FP)) { + if (fgetline(line, sizeof(line), FP, st->lineno) == NULL) { + fgetline(line, sizeof(line), FP, st->lineno); + } + s = line; + length = strlen(line); + if (length >= 7) { + if (strncmp(line, "ENDCOMP", 7) == 0) { + if (nonempty) { /* could try and use module empty function here */ + pcb_subc_bbox(new_module); + break; + } + else { + rnd_message(RND_MSG_ERROR, "Empty module/COMP found, not added to layout, %s:%d\n", st->Filename, st->lineno); +TODO("TODO safely free new_module") + return 0; + } + } + } + else if (length >= 2) { +TODO("this does not handle return -1") + if (strncmp(s, "CT", 2) == 0) { + nonempty |= rdax_track(st, FP, new_module); + } + else if (strncmp(s, "CA", 2) == 0) { + nonempty |= rdax_arc(st, FP, new_module); + } + else if (strncmp(s, "CV", 2) == 0) { + nonempty |= rdax_via(st, FP, new_module); + } + else if (strncmp(s, "CF", 2) == 0) { + nonempty |= rdax_fill(st, FP, new_module); + } + else if (strncmp(s, "CP", 2) == 0) { + nonempty |= rdax_pad(st, FP, new_module, 1); /* flag in COMP */ + } + else if (strncmp(s, "CS", 2) == 0) { + nonempty |= rdax_text(st, FP, new_module); + } + } + } + pcb_subc_bbox(new_module); + if (st->pcb->Data->subc_tree == NULL) + st->pcb->Data->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(st->pcb->Data->subc_tree, (rnd_box_t *)new_module); + pcb_subc_rebind(st->pcb, new_module); + + return 0; +} + + +int io_autotrax_read_pcb(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest) +{ + int readres = 0; + rnd_box_t board_size, *box; + read_state_t st; + FILE *FP; + pcb_subc_t *subc = NULL; + int length = 0; + int finished = 0; + int netdefs = 0; + char line[1024]; + char *s; + + FP = rnd_fopen(&Ptr->hidlib, Filename, "r"); + if (FP == NULL) + return -1; + + /* set up the parse context */ + memset(&st, 0, sizeof(st)); + st.pcb = Ptr; + st.Filename = Filename; + st.settings_dest = settings_dest; + st.lineno = 0; + st.mask_clearance = st.copper_clearance = RND_MIL_TO_COORD(10); /* sensible default values */ + st.minimum_comp_pin_drill = RND_MIL_TO_COORD(30); /* Easytrax PCB FILE 5 uses zero in COMP pins */ + st.trax_version = 4; /* assume autotrax, not easytrax */ + st.ignored_keepout_element = 0; + st.ignored_layer_zero_element = 0; + + while(!feof(FP) && !finished) { + if (fgetline(line, sizeof(line), FP, st.lineno) == NULL) { + fgetline(line, sizeof(line), FP, st.lineno); + } + s = line; + rtrim(s); + length = strlen(line); + if (length >= 10) { + if (strncmp(line, "PCB FILE 4", 10) == 0) { + st.trax_version = 4; + autotrax_create_layers(&st); + } + else if (strncmp(line, "PCB FILE 5", 10) == 0) { + st.trax_version = 5; + autotrax_create_layers(&st); + } + } + else if (length >= 6) { + if (strncmp(s, "ENDPCB", 6) == 0) { + finished = 1; + } + else if (strncmp(s, "NETDEF", 6) == 0) { + if (netdefs == 0) { + rnd_actionva(&Ptr->hidlib, "ElementList", "start", NULL); + rnd_actionva(&Ptr->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&Ptr->hidlib, "Netlist", "Clear", NULL); + } + netdefs |= 1; + rdax_net(&st, FP); + } + } + else if (length >= 4) { + if (strncmp(line, "COMP", 4) == 0) { + rdax_component(&st, FP); + } + } + else if (length >= 2) { + if (strncmp(s, "FT", 2) == 0) rdax_track(&st, FP, subc); + else if (strncmp(s, "FA", 2) == 0) rdax_arc(&st, FP, subc); + else if (strncmp(s, "FV", 2) == 0) rdax_via(&st, FP, subc); + else if (strncmp(s, "FF", 2) == 0) rdax_fill(&st, FP, subc); + else if (strncmp(s, "FP", 2) == 0) rdax_pad(&st, FP, subc, 0); /* flag not in a component */ + else if (strncmp(s, "FS", 2) == 0) rdax_text(&st, FP, subc); + } + } + if (netdefs) { + rnd_actionva(&Ptr->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&Ptr->hidlib, "Netlist", "Thaw", NULL); + rnd_actionva(&Ptr->hidlib, "ElementList", "Done", NULL); + } + fclose(FP); + box = pcb_data_bbox(&board_size, Ptr->Data, rnd_false); + if (st.ignored_keepout_element) { + rnd_message(RND_MSG_ERROR, "Ignored %d keepout track(s) on auto/easytrax layer 12\n", st.ignored_keepout_element); + } + if (st.ignored_layer_zero_element) { + rnd_message(RND_MSG_ERROR, "Ignored %d auto/easytrax layer zero feature(s)\n", st.ignored_layer_zero_element); + } + + if (box != NULL) { + Ptr->hidlib.size_x = box->X2; + Ptr->hidlib.size_y = box->Y2; + } + else + rnd_message(RND_MSG_ERROR, "Can not determine board extents - empty board?\n"); + + /* we now flip the board about the X-axis, to invert the Y coords used by autotrax */ + pcb_undo_freeze_add(); + pcb_data_mirror(Ptr->Data, 0, PCB_TXM_COORD, 0, 0); + pcb_undo_unfreeze_add(); + + /* still not sure if this is required: */ + pcb_layer_auto_fixup(Ptr); + + pcb_board_normalize(Ptr); + pcb_layer_colors_from_conf(Ptr, 1); + + return readres; +} + +int io_autotrax_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f) +{ + char line[1024], *s; + + if (typ != PCB_IOT_PCB) + return 0; /* support only boards for now */ + + while(!(feof(f))) { + if (fgets(line, sizeof(line), f) != NULL) { + s = line; + while(isspace(*s)) + s++; /* strip leading whitespace */ + if (strncmp(s, "PCB FILE 4", 10) == 0 || strncmp(s, "PCB FILE 5", 10) == 0) + return 1; + if ((*s == '\r') || (*s == '\n') || (*s == '#') || (*s == '\0')) + /* ignore empty lines and comments */ + continue; + return 0; + } + } + + return 0; +} Index: tags/2.3.0/src_plugins/io_autotrax/read.h =================================================================== --- tags/2.3.0/src_plugins/io_autotrax/read.h (nonexistent) +++ tags/2.3.0/src_plugins/io_autotrax/read.h (revision 33253) @@ -0,0 +1,34 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * Copyright (C) 2016 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include +#include "data.h" + +int io_autotrax_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); +int io_autotrax_read_pcb(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest); Index: tags/2.3.0/src_plugins/io_autotrax/write.c =================================================================== --- tags/2.3.0/src_plugins/io_autotrax/write.c (nonexistent) +++ tags/2.3.0/src_plugins/io_autotrax/write.c (revision 33253) @@ -0,0 +1,709 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * Copyright (C) 2016, 2017 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include +#include "config.h" +#include +#include "board.h" +#include "plug_io.h" +#include +#include "netlist.h" +#include "data.h" +#include "write.h" +#include "layer.h" +#include +#include "../lib_polyhelp/polyhelp.h" + +#include "../src_plugins/lib_compat_help/pstk_compat.h" + + +typedef struct { + pcb_layer_type_t lyt; + rnd_bool plane; +} layer_map_t; + +/* The hardwired layer map of autotrax */ +#define LAYER_MAP_LEN 14 +static layer_map_t layer_map[LAYER_MAP_LEN] = { + /* 0 */ { 0, 0}, /* unused */ + /* 1 */ { PCB_LYT_TOP | PCB_LYT_COPPER, 0}, /* "top" */ + /* 2 */ { PCB_LYT_INTERN | PCB_LYT_COPPER, 0}, + /* 3 */ { PCB_LYT_INTERN | PCB_LYT_COPPER, 0}, + /* 4 */ { PCB_LYT_INTERN | PCB_LYT_COPPER, 0}, + /* 5 */ { PCB_LYT_INTERN | PCB_LYT_COPPER, 0}, + /* 6 */ { PCB_LYT_BOTTOM | PCB_LYT_COPPER, 0}, /* "bottom" */ + /* 7 */ { PCB_LYT_TOP | PCB_LYT_SILK, 0}, /* "top overlay" */ + /* 8 */ { PCB_LYT_BOTTOM | PCB_LYT_SILK, 0}, /* "bottom overlay" */ + /* 9 */ { PCB_LYT_INTERN | PCB_LYT_COPPER, 1}, /* "ground plane" */ + /* 10 */ { PCB_LYT_INTERN | PCB_LYT_COPPER, 1}, /* "power plane" */ + /* 11 */ { PCB_LYT_BOUNDARY, 0}, /* "board layer" */ + /* 12 */ { 0, 0}, /* "keepout" */ + /* 13 */ { 0, 0}, /* "multi layer" - used to indicate padstacks are on all layers */ +}; + +typedef struct { + FILE *f; + pcb_board_t *pcb; + pcb_layergrp_t *id2grp[LAYER_MAP_LEN]; + int grp2id[PCB_MAX_LAYERGRP]; +} wctx_t; + +static int wrax_layer2id(wctx_t *ctx, pcb_layer_t *ly) +{ + rnd_layergrp_id_t gid = pcb_layer_get_group_(ly); + if ((gid >= 0) && (gid < PCB_MAX_LAYERGRP)) + return ctx->grp2id[gid]; + return 0; +} + +static pcb_layergrp_t *wrax_id2grp(wctx_t *ctx, int alayer_id) +{ + if ((alayer_id <= 0) || (alayer_id >= LAYER_MAP_LEN)) + return NULL; + return ctx->id2grp[alayer_id]; +} + +static int wrax_lyt2id(wctx_t *ctx, pcb_layer_type_t lyt) +{ + int n; + for(n = 1; n < LAYER_MAP_LEN; n++) + if (layer_map[n].lyt == lyt) + return n; + return 0; +} + +static void wrax_map_layer_error(wctx_t *ctx, pcb_layergrp_t *grp, const char *msg, const char *hint) +{ + char tmp[256]; + rnd_snprintf(tmp, sizeof(tmp), "%s (omitting layer group): %s", msg, grp->name); + pcb_io_incompat_save(ctx->pcb->Data, NULL, "layer", tmp, hint); +} + +static int wrax_map_layers(wctx_t *ctx) +{ + int n, intcnt = 0; + + for(n = 0; n < ctx->pcb->LayerGroups.len; n++) { + pcb_layergrp_t *grp = &ctx->pcb->LayerGroups.grp[n]; + int al; + + if ((grp->ltype & PCB_LYT_SUBSTRATE) || (grp->ltype & PCB_LYT_VIRTUAL) || (grp->ltype & PCB_LYT_PASTE) || (grp->ltype & PCB_LYT_MASK)) + continue; + + al = wrax_lyt2id(ctx, grp->ltype); + if (al == 0) { + wrax_map_layer_error(ctx, grp, "Unable to map pcb-rnd layer group to autotrax layer", "change layer type"); + continue; + } + + if (grp->ltype & PCB_LYT_INTERN) { + /* intern copper: find the first free slot */ + while((layer_map[al+intcnt].lyt & PCB_LYT_INTERN) && (ctx->id2grp[al+intcnt] != NULL)) intcnt++; + al += intcnt; + if (!(layer_map[al+intcnt].lyt & PCB_LYT_INTERN)) { + wrax_map_layer_error(ctx, grp, "Ran out of internal layer groups while mapping pcb-rnd layer group to autotrax layer", "autotrax supports only 4 internal signal layers - use less internal layers"); + continue; + } + } + + if (ctx->id2grp[al] != NULL) { + wrax_map_layer_error(ctx, grp, "Attempt to map multiple layer groups to the same autotrax layer", "use only one layer group per layer group type"); + continue; + } + + ctx->id2grp[al] = grp; + ctx->grp2id[grp - ctx->pcb->LayerGroups.grp] = al; + } + return 0; +} + + +#define PCB_PSTK_COMPAT_RRECT 250 +static int wrax_padstack(wctx_t *ctx, pcb_pstk_t *ps, rnd_coord_t dx, rnd_coord_t dy, rnd_bool in_subc) +{ + const char *name; + rnd_coord_t x, y, drill_dia, pad_dia, clearance, mask, x1, y1, x2, y2, thickness, w, h; + pcb_pstk_compshape_t cshape; + rnd_bool plated, square, nopaste; + int ashape, alayer; + + if (ps->term != NULL) { + const char *s; + int len; + + name = ps->term; + for(s = name, len = 0; *s != '\0'; s++,len++) { + if (!isalnum(*s)) { + pcb_io_incompat_save(ps->parent.data, (pcb_any_obj_t *)ps, "padname", "autotrax pad name (terminal name) must consists of alphanumeric characters only - omitting padstack", "rename the terminal to something simpler"); + return 0; + } + if (len >= 4) { + pcb_io_incompat_save(ps->parent.data, (pcb_any_obj_t *)ps, "padname", "autotrax pad name (terminal name) must consists of alphanumeric characters only - omitting padstack", "rename the terminal to something simpler"); + return 0; + } + } + } + else + name = "none"; + + if (pcb_pstk_export_compat_via(ps, &x, &y, &drill_dia, &pad_dia, &clearance, &mask, &cshape, &plated)) { + w = h = pad_dia; + alayer = 13; + } + else if (pcb_pstk_export_compat_pad(ps, &x1, &y1, &x2, &y2, &thickness, &clearance, &mask, &square, &nopaste)) { + if ((x1 != x2) && (y1 != y2)) { + pcb_io_incompat_save(ps->parent.data, (pcb_any_obj_t *)ps, "padstack-rot", "can not export rotated rectangular/line pin/pad/via", "shape must be axis-aligned"); + return 0; + } + /* convert to the same format as via */ + cshape = square ? PCB_PSTK_COMPAT_SQUARE : PCB_PSTK_COMPAT_RRECT; + + /* calculate center and disable hole */ + x = (x1+x2)/2; + y = (y1+y2)/2; + w = x2 - x1; + h = y2 - y1; + drill_dia = 0; + +TODO("need to figure which side the padstack is on!") + alayer = 1; + } + else { + pcb_io_incompat_save(ps->parent.data, (pcb_any_obj_t *)ps, "padstack-shape", "can not export complex pin/pad/via", "use uniform shaped pins/vias and simpler pads, with simple shapes (no generic polygons)"); + return 0; + } + + if ((cshape != PCB_PSTK_COMPAT_ROUND) && (ps->rot != 0)) { + pcb_io_incompat_save(ps->parent.data, (pcb_any_obj_t *)ps, "padstack-rot", "can not export rotated pin/pad/via", "remove rotation, shapes must be axis-aligned"); + return 0; + } + + switch((int)cshape) { + case PCB_PSTK_COMPAT_ROUND: ashape = 1; break; + case PCB_PSTK_COMPAT_SQUARE: ashape = 2; break; + case PCB_PSTK_COMPAT_OCTAGON: ashape = 3; break; + case PCB_PSTK_COMPAT_RRECT: ashape = 4; break; + default: + pcb_io_incompat_save(ps->parent.data, (pcb_any_obj_t *)ps, "padstack-shape", "can not export: invalid pad shape", "use circle, octagon, rectangle or round rectangle"); + return 0; + } + + if (in_subc) + fputs("CP ", ctx->f); + else + fputs("FP ", ctx->f); + +TODO("figure which is the gnd and which is the power plane") +TODO("add checks for thermals: only gnd/pwr can have them, warn for others") + + rnd_fprintf(ctx->f, "%.0ml %.0ml %.0ml %.0ml %d %.0ml 1 %d\r\n", + x+dx, PCB->hidlib.size_y - (y+dy), w, h, + ashape, drill_dia, alayer); + + fputs(name, ctx->f); + fputs("\r\n", ctx->f); + return 0; +} + +int wrax_data(wctx_t *ctx, pcb_data_t *data, rnd_coord_t dx, rnd_coord_t dy); + +static int wrax_vias(wctx_t *ctx, pcb_data_t *Data, rnd_coord_t dx, rnd_coord_t dy, rnd_bool in_subc) +{ + gdl_iterator_t it; + pcb_pstk_t *ps; + int res = 0; + + padstacklist_foreach(&Data->padstack, &it, ps) + res |= wrax_padstack(ctx, ps, dx, dy, in_subc); + + return res; +} + +/* writes generic autotrax track descriptor line for components and layouts */ +static int wrax_line(wctx_t *ctx, pcb_line_t *line, rnd_cardinal_t layer, rnd_coord_t dx, rnd_coord_t dy) +{ + int user_routed = 1; + rnd_fprintf(ctx->f, "%.0ml %.0ml %.0ml %.0ml %.0ml %d %d\r\n", line->Point1.X+dx, PCB->hidlib.size_y - (line->Point1.Y+dy), line->Point2.X+dx, PCB->hidlib.size_y - (line->Point2.Y+dy), line->Thickness, layer, user_routed); + return 0; +} + +/* writes autotrax track descriptor for a pair of polyline vertices */ +static int wrax_pline_segment(wctx_t *ctx, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t Thickness, rnd_cardinal_t layer) +{ + int user_routed = 1; + rnd_fprintf(ctx->f, "FT\r\n%.0ml %.0ml %.0ml %.0ml %.0ml %d %d\r\n", x1, PCB->hidlib.size_y - y1, x2, PCB->hidlib.size_y - y2, Thickness, layer, user_routed); + return 0; +} + +typedef struct { + wctx_t *wctx; + rnd_cardinal_t layer; + rnd_coord_t dx, dy; + rnd_coord_t thickness; +} autotrax_hatch_ctx_t; + + +static void autotrax_hatch_cb(void *ctx_, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + autotrax_hatch_ctx_t *hctx = (autotrax_hatch_ctx_t *) ctx_; + wrax_pline_segment( + hctx->wctx, + x1+hctx->dx, y1+hctx->dy, x2+hctx->dx, y2+hctx->dy, + hctx->thickness, hctx->layer); +} + +/* generates autotrax tracks to cross hatch a complex polygon being exported */ +static void autotrax_cpoly_hatch_lines(wctx_t *ctx, const pcb_poly_t *src, pcb_cpoly_hatchdir_t dir, rnd_coord_t period, rnd_coord_t thickness, rnd_cardinal_t layer, rnd_coord_t dx, rnd_coord_t dy) +{ + autotrax_hatch_ctx_t hctx; + + hctx.wctx = ctx; + hctx.layer = layer; + hctx.thickness = thickness; + hctx.dx = dx; + hctx.dy = dy; + pcb_cpoly_hatch(src, dir, (thickness / 2) + 1, period, &hctx, autotrax_hatch_cb); +} + +/* generates an autotrax arc "segments" value to approximate an arc being exported */ +static int pcb_rnd_arc_to_autotrax_segments(rnd_angle_t arc_start, rnd_angle_t arc_delta) +{ + int arc_segments = 0; /* start with no arc segments */ + /* 15 = circle, bit 1 = LUQ, bit 2 = LLQ, bit 3 = LRQ, bit 4 = URQ */ + if (arc_delta == -360) /* it's a circle */ + arc_delta = 360; + if (arc_delta < 0) { + arc_delta = -arc_delta; + arc_start -= arc_delta; + } + +TODO("TODO arc segments less than 90 degrees do not convert well.") + + while(arc_start < 0) + arc_start += 360; + while(arc_start > 360) + arc_start -= 360; + + if (arc_delta >= 360) { /* it's a circle */ + arc_segments |= 0x0F; + } + else { + if (arc_start <= 0.0 && (arc_start + arc_delta) >= 90.0) + arc_segments |= 0x04; /* LLQ */ + if (arc_start <= 90.0 && (arc_start + arc_delta) >= 180.0) + arc_segments |= 0x08; /* LRQ */ + if (arc_start <= 180.0 && (arc_start + arc_delta) >= 270.0) + arc_segments |= 0x01; /* URQ */ + if (arc_start <= 270.0 && (arc_start + arc_delta) >= 360.0) + arc_segments |= 0x02; /* ULQ */ + if (arc_start <= 360.0 && (arc_start + arc_delta) >= 450.0) + arc_segments |= 0x04; /* LLQ */ + if (arc_start <= 360.0 && (arc_start + arc_delta) >= 540.0) + arc_segments |= 0x08; /* LRQ */ + if (arc_start <= 360.0 && (arc_start + arc_delta) >= 630.0) + arc_segments |= 0x01; /* URQ */ + } + return arc_segments; +} + +/* writes generic autotrax arc descriptor line for components and layouts */ +static int wrax_arc(wctx_t *ctx, pcb_arc_t *arc, int current_layer, rnd_coord_t dx, rnd_coord_t dy) +{ + rnd_coord_t radius; + if (arc->Width > arc->Height) { + radius = arc->Height; + } + else { + radius = arc->Width; + } + rnd_fprintf(ctx->f, "%.0ml %.0ml %.0ml %d %.0ml %d\r\n", arc->X+dx, PCB->hidlib.size_y - (arc->Y+dy), radius, pcb_rnd_arc_to_autotrax_segments(arc->StartAngle, arc->Delta), arc->Thickness, current_layer); + return 0; +} + +/* writes netlist data in autotrax format */ +static int wrax_equipotential_netlists(wctx_t *ctx) +{ + int show_status = 0; + /* show status can be 0 or 1 for a net: + 0 hide rats nest + 1 show rats nest */ + /* now we step through any available netlists and generate descriptors */ + + if (PCB->netlist[PCB_NETLIST_EDITED].used > 0) { + htsp_entry_t *e; + + for(e = htsp_first(&PCB->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&PCB->netlist[PCB_NETLIST_EDITED], e)) { + pcb_net_term_t *t; + pcb_net_t *net = e->value; + + fprintf(ctx->f, "NETDEF\r\n"); + rnd_fprintf(ctx->f, "%s\r\n", net->name); + rnd_fprintf(ctx->f, "%d\r\n", show_status); + fprintf(ctx->f, "(\r\n"); + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) + rnd_fprintf(ctx->f, "%s-%s\r\n", t->refdes, t->term); + fprintf(ctx->f, ")\r\n"); + } + } + return 0; +} + + +static int wrax_lines(wctx_t *ctx, rnd_cardinal_t number, pcb_layer_t *layer, rnd_coord_t dx, rnd_coord_t dy, rnd_bool in_subc) +{ + gdl_iterator_t it; + pcb_line_t *line; + rnd_cardinal_t current_layer = number; + + /* write information about non empty layers */ + if (!pcb_layer_is_empty_(PCB, layer) || (layer->name && *layer->name)) { + int local_flag = 0; + linelist_foreach(&layer->Line, &it, line) { + if (in_subc) + rnd_fprintf(ctx->f, "CT\r\n"); + else + rnd_fprintf(ctx->f, "FT\r\n"); + wrax_line(ctx, line, current_layer, dx, dy); + local_flag |= 1; + } + return local_flag; + } + + return 0; +} + +/* writes autotrax arcs for layouts */ +static int wrax_arcs(wctx_t *ctx, rnd_cardinal_t number, pcb_layer_t *layer, rnd_coord_t dx, rnd_coord_t dy, rnd_bool in_subc) +{ + gdl_iterator_t it; + pcb_arc_t *arc; + rnd_cardinal_t current_layer = number; + + /* write information about non empty layers */ + if (!pcb_layer_is_empty_(PCB, layer)) { /*|| (layer->name && *layer->name)) { */ + int local_flag = 0; + arclist_foreach(&layer->Arc, &it, arc) { + if (in_subc) + rnd_fprintf(ctx->f, "CA\r\n"); + else + rnd_fprintf(ctx->f, "FA\r\n"); + wrax_arc(ctx, arc, current_layer, dx, dy); + local_flag |= 1; + } + return local_flag; + } + + return 0; +} + +/* writes generic autotrax text descriptor line layouts onl, since no text in .fp */ +static int wrax_text(wctx_t *ctx, rnd_cardinal_t number, pcb_layer_t *layer, rnd_coord_t dx, rnd_coord_t dy, rnd_bool in_subc) +{ + pcb_font_t *myfont = pcb_font(PCB, 0, 1); + rnd_coord_t mHeight = myfont->MaxHeight; /* autotrax needs the width of the widest letter */ + int autotrax_mirrored = 0; /* 0 is not mirrored, +16 is mirrored */ + + rnd_coord_t default_stroke_thickness, strokeThickness, textHeight; + int rotation; + int local_flag; + + gdl_iterator_t it; + pcb_text_t *text; + rnd_cardinal_t current_layer = number; + + int index = 0; + + int scale; + +TODO("why do we hardwire this here?") + default_stroke_thickness = 200000; + + /* write information about non empty layers */ + if (!pcb_layer_is_empty_(PCB, layer)) { /*|| (layer->name && *layer->name)) { */ + local_flag = 0; + textlist_foreach(&layer->Text, &it, text) { + int direction; + + if (pcb_text_old_direction(&direction, text->rot) != 0) { +TODO("indicate save incompatibility") + } + + if (pcb_text_old_scale(text, &scale) != 0) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-scale", "file format does not support different x and y direction text scale - using average scale", "Use the scale field, set scale_x and scale_y to 0"); + + if (text->mirror_x) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-mirror-x", "file format does not support different mirroring text in the x direction", "do not mirror, or mirror in the y direction (with the ONSOLDER flag)"); + + if (current_layer < 9) { /* copper or silk layer text */ + if (in_subc) + fputs("CS\r\n", ctx->f); + else + fputs("FS\r\n", ctx->f); + strokeThickness = PCB_SCALE_TEXT(default_stroke_thickness, scale / 2); + textHeight = PCB_SCALE_TEXT(mHeight, scale); + rotation = 0; + if (current_layer == 6 || current_layer == 8) /* back copper or silk */ + autotrax_mirrored = 16; /* mirrored */ + if (direction == 3) /*vertical down */ + rotation = 3; + else if (direction == 2) /*upside down */ + rotation = 2; + else if (direction == 1) /*vertical up */ + rotation = 1; + else if (direction == 0) /*normal text */ + rotation = 0; + + rnd_fprintf(ctx->f, "%.0ml %.0ml %.0ml %d %.0ml %d\r\n", text->X+dx, PCB->hidlib.size_y - (text->Y+dy), textHeight, rotation + autotrax_mirrored, strokeThickness, current_layer); + for(index = 0; index < 32; index++) { + if (text->TextString[index] == '\0') + index = 32; + else if (text->TextString[index] < 32 || text->TextString[index] > 126) + fputc(' ', ctx->f); /* replace non alphanum with space */ + else /* need to truncate to 32 alphanumeric chars */ + fputc(text->TextString[index], ctx->f); + } + rnd_fprintf(ctx->f, "\r\n"); + } + local_flag |= 1; + } + return local_flag; + } + + return 0; +} + +static const char *or_empty(const char *s) +{ + if (s == NULL) return ""; + return s; +} + +static int wrax_subc(wctx_t *ctx, pcb_subc_t *subc) +{ + int res, on_bottom = 0, silk_layer; + rnd_box_t *box = &subc->BoundingBox; + rnd_coord_t xPos, yPos, yPos2, yPos3; + +TODO("do not hardcode things like this, especially when actual data is available") + rnd_coord_t text_offset = RND_MIL_TO_COORD(400); /* this gives good placement of refdes relative to element */ + +TODO("rename these variables to something more expressive") +TODO("instead of hardwiring coords, just read existing dyntex coords") + xPos = (box->X1 + box->X2) / 2; + yPos = PCB->hidlib.size_y - (box->Y1 - text_offset); + yPos2 = yPos - RND_MIL_TO_COORD(200); + yPos3 = yPos2 - RND_MIL_TO_COORD(200); + + pcb_subc_get_side(subc, &on_bottom); + +TODO("do not hardwire these layers, even if the autotrax format hardwires them - look them up from the static table, let the hardwiring happen only at one place") + if (on_bottom) + silk_layer = 8; + else + silk_layer = 7; + + fprintf(ctx->f, "COMP\r\n%s\r\n", or_empty(subc->refdes)); + fprintf(ctx->f, "%s\r\n", or_empty(pcb_attribute_get(&subc->Attributes, "footprint"))); + fprintf(ctx->f, "%s\r\n", or_empty(pcb_attribute_get(&subc->Attributes, "value"))); + rnd_fprintf(ctx->f, "%.0ml %.0ml 100 0 10 %d\r\n", xPos, yPos, silk_layer); /* designator */ + rnd_fprintf(ctx->f, "%.0ml %.0ml 100 0 10 %d\r\n", xPos, yPos2, silk_layer); /* pattern */ + rnd_fprintf(ctx->f, "%.0ml %.0ml 100 0 10 %d\r\n", xPos, yPos3, silk_layer); /* comment field */ + + res = wrax_data(ctx, subc->data, 0, 0); + + fprintf(ctx->f, "ENDCOMP\r\n"); + return res; +} + +static int wrax_subcs(wctx_t *ctx, pcb_data_t *data) +{ + gdl_iterator_t sit; + pcb_subc_t *subc; + int res = 0; + + subclist_foreach(&data->subc, &sit, subc) + res |= wrax_subc(ctx, subc); + + return res; +} + +/* writes polygon data in autotrax fill (rectangle) format for use in a layout .PCB file */ +static int wrax_polygons(wctx_t *ctx, rnd_cardinal_t number, pcb_layer_t *layer, rnd_coord_t dx, rnd_coord_t dy, rnd_bool in_subc) +{ + int i; + gdl_iterator_t it; + pcb_poly_t *polygon; + rnd_cardinal_t current_layer = number; + + pcb_poly_it_t poly_it; + rnd_polyarea_t *pa; + + rnd_coord_t minx, miny, maxx, maxy; + + /* write information about non empty layers */ + if (!pcb_layer_is_empty_(PCB, layer)) { /*|| (layer->name && *layer->name)) { */ + int local_flag = 0; + + polylist_foreach(&layer->Polygon, &it, polygon) { + if (pcb_cpoly_is_simple_rect(polygon)) { + rnd_trace(" simple rectangular polyogon\n"); + +TODO("why do we recalculate the bounding box here?") + minx = maxx = polygon->Points[0].X; + miny = maxy = polygon->Points[0].Y; + + /* now the fill zone outline is defined by a rectangle enclosing the poly */ + /* hmm. or, could use a bounding box... */ + for(i = 0; i < polygon->PointN; i++) { + if (minx > polygon->Points[i].X) + minx = polygon->Points[i].X; + if (maxx < polygon->Points[i].X) + maxx = polygon->Points[i].X; + if (miny > polygon->Points[i].Y) + miny = polygon->Points[i].Y; + if (maxy < polygon->Points[i].Y) + maxy = polygon->Points[i].Y; + } + rnd_fprintf(ctx->f, "%cF\r\n%.0ml %.0ml %.0ml %.0ml %d\r\n", (in_subc ? 'C' : 'F'), minx+dx, PCB->hidlib.size_y - (miny+dy), maxx+dx, PCB->hidlib.size_y - (maxy+dy), current_layer); + + local_flag |= 1; +/* here we need to test for non rectangular polygons to flag imperfect export to easy/autotrax + + if (helper_clipped_polygon_type_function(clipped_thing)) { + rnd_message(RND_MSG_ERROR, "Polygon exported as a bounding box only.\n"); + }*/ + } + else { + rnd_coord_t Thickness; + Thickness = RND_MIL_TO_COORD(10); + autotrax_cpoly_hatch_lines(ctx, polygon, PCB_CPOLY_HATCH_HORIZONTAL | PCB_CPOLY_HATCH_VERTICAL, Thickness * 3, Thickness, current_layer, dx, dy); +TODO("do we really need to reimplement this, can not cpoly_hatch_lines handle it?") + for(pa = pcb_poly_island_first(polygon, &poly_it); pa != NULL; pa = pcb_poly_island_next(&poly_it)) { + /* now generate cross hatch lines for polygon island export */ + rnd_pline_t *pl, *track; + /* check if we have a contour for the given island */ + pl = pcb_poly_contour(&poly_it); + if (pl != NULL) { + const rnd_vnode_t *v, *n; + track = rnd_pline_dup_offset(pl, -((Thickness / 2) + 1)); + v = track->head; + do { + n = v->next; + wrax_pline_segment(ctx, v->point[0]+dx, v->point[1]+dy, n->point[0]+dx, n->point[1]+dy, Thickness, current_layer); + } while((v = v->next) != track->head); + rnd_poly_contour_del(&track); + + /* iterate over all holes within this island */ + for(pl = pcb_poly_hole_first(&poly_it); pl != NULL; pl = pcb_poly_hole_next(&poly_it)) { + const rnd_vnode_t *v, *n; + track = rnd_pline_dup_offset(pl, -((Thickness / 2) + 1)); + v = track->head; + do { + n = v->next; + wrax_pline_segment(ctx, v->point[0]+dx, v->point[1]+dy, n->point[0]+dx, n->point[1]+dy, Thickness, current_layer); + } while((v = v->next) != track->head); + rnd_poly_contour_del(&track); + } + } + } + } + } + return local_flag; + } + + return 0; +} + +int wrax_data(wctx_t *ctx, pcb_data_t *data, rnd_coord_t dx, rnd_coord_t dy) +{ + int n; + rnd_bool in_subc = (data->parent_type == PCB_PARENT_SUBC); + + for(n = 0; n < data->LayerN; n++) { + pcb_layer_t *ly = &data->Layer[n]; + int alid = wrax_layer2id(ctx, ly); /* autotrax layer ID */ + if (alid == 0) { + char tmp[256]; + rnd_snprintf(tmp, sizeof(tmp), "Ignoring unmapped layer: %s", ly->name); + pcb_io_incompat_save(data, NULL, "layer", tmp, NULL); + continue; + } + { + pcb_gfx_t *gfx; + for(gfx = gfxlist_first(&ly->Gfx); gfx != NULL; gfx = gfxlist_next(gfx)) + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)gfx, "gfx", "gfx can not be exported", "please use the lihata board format"); + } + wrax_lines(ctx, alid, ly, dx, dy, in_subc); + wrax_arcs(ctx, alid, ly, dx, dy, in_subc); + wrax_text(ctx, alid, ly, dx, dy, in_subc); + wrax_polygons(ctx, alid, ly, dx, dy, in_subc); + } + + wrax_subcs(ctx, data); + wrax_vias(ctx, data, dx, dy, in_subc); + return 0; +} + +/* writes autotrax PCB to file */ +int io_autotrax_write_pcb(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + wctx_t wctx; + + /* autotrax expects layout dimensions to be specified in mils */ + int max_width_mil = 32000; + int max_height_mil = 32000; + + memset(&wctx, 0, sizeof(wctx)); + wctx.f = FP; + wctx.pcb = PCB; + +TODO("this is a bug - exporting to a file shall not change the content we are exporting") + if (pcb_board_normalize(PCB) < 0) { + rnd_message(RND_MSG_ERROR, "Unable to normalise layout prior to attempting export.\n"); + return -1; + } + + if (wrax_map_layers(&wctx) != 0) + return -1; + + fputs("PCB FILE 4\r\n", FP); /*autotrax header */ + + /* we sort out if the layout dimensions exceed the autotrax maxima */ + if (RND_COORD_TO_MIL(PCB->hidlib.size_x) > max_width_mil || RND_COORD_TO_MIL(PCB->hidlib.size_y) > max_height_mil) { + rnd_message(RND_MSG_ERROR, "Layout size exceeds protel autotrax 32000 mil x 32000 mil maximum."); + return -1; + } + + wrax_data(&wctx, PCB->Data, 0, 0); + + /* last are the autotrax netlist descriptors */ + wrax_equipotential_netlists(&wctx); + + fputs("ENDPCB\r\n", FP); /*autotrax footer */ + + return 0; +} Index: tags/2.3.0/src_plugins/io_autotrax/write.h =================================================================== --- tags/2.3.0/src_plugins/io_autotrax/write.h (nonexistent) +++ tags/2.3.0/src_plugins/io_autotrax/write.h (revision 33253) @@ -0,0 +1,35 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * Copyright (C) 2016 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include +#include "data.h" + +int io_autotrax_write_element(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data); +int io_autotrax_write_buffer(pcb_plug_io_t *ctx, FILE *FP, pcb_buffer_t *buff); +int io_autotrax_write_pcb(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency); Index: tags/2.3.0/src_plugins/io_bxl/Makefile =================================================================== --- tags/2.3.0/src_plugins/io_bxl/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_io_bxl + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/io_bxl/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/io_bxl/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/Plug.tmpasm (revision 33253) @@ -0,0 +1,17 @@ +put /local/pcb/mod {io_bxl} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/io_bxl/io_bxl.o + $(PLUGDIR)/io_bxl/bxl_decode.o + $(PLUGDIR)/io_bxl/bxl_gram.o + $(PLUGDIR)/io_bxl/bxl_lex.o + $(PLUGDIR)/io_bxl/read.o +@] + +put /local/pcb/mod/BYACCIC {$(PLUGDIR)/io_bxl/bxl_gram} +put /local/pcb/mod/UREGLEX {$(PLUGDIR)/io_bxl/bxl_lex} + +switch /local/pcb/io_bxl/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/io_bxl/bxl.h =================================================================== --- tags/2.3.0/src_plugins/io_bxl/bxl.h (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/bxl.h (revision 33253) @@ -0,0 +1,109 @@ +#ifndef PCB_BXL_H +#define PCB_BXL_H + +#include "data.h" +#include "layer.h" +#include "obj_subc.h" +#include "obj_poly.h" +#include "obj_pstk.h" +#include +#include + +typedef enum { + PCB_BXL_JUST_TOP = 1, + PCB_BXL_JUST_LEFT = 1, + PCB_BXL_JUST_CENTER = 2, + PCB_BXL_JUST_BOTTOM = 4, + PCB_BXL_JUST_RIGHT = 4 +} pcb_bxl_just_t; + +typedef struct { + double width, height, char_width; +} pcb_bxl_test_style_t; + +typedef struct pcb_bxl_ctx_s { + pcb_board_t *pcb; + pcb_subc_t *subc; + char in_target_fp; /* 1 if we are parsing the target footprint; else skip */ + const char *subfpname; /* target footprint name to load */ + + int in_error; + + /* cache */ + htsp_t layer_name2ly; + htsp_t text_name2style; + htsi_t proto_name2id; + int proto_id; + + struct { + rnd_coord_t origin_x, origin_y, pick_x, pick_y, glue_x, glue_y; + } pat_state; + + struct { + pcb_layer_t *layer; + rnd_coord_t origin_x, origin_y, endp_x, endp_y, width, height, radius; + rnd_coord_t hole; + pcb_poly_t *poly; + double arc_start, arc_delta; + double rot; + int num_shapes, pad_type, shape_type, pin_number; + long pstk_proto_id; + char *pin_name; + pcb_bxl_just_t hjust, vjust; + pcb_bxl_test_style_t *text_style; + char *text_str, *attr_key, *attr_val; + pcb_pstk_proto_t proto; + unsigned flipped:1; + unsigned is_visible:1; + unsigned plated:1; + unsigned nopaste:1; + unsigned surface:1; + + unsigned delayed_poly:1; + unsigned is_text:1; + unsigned has_mask_shape:1; + int copper_shape_idx; + } state; + + struct { + long poly_broken; + long property_null_obj; + long property_nosep; + } warn; +} pcb_bxl_ctx_t; + +rnd_coord_t pcb_bxl_coord_x(rnd_coord_t c); +rnd_coord_t pcb_bxl_coord_y(rnd_coord_t c); + +void pcb_bxl_pattern_begin(pcb_bxl_ctx_t *ctx, const char *name); +void pcb_bxl_pattern_end(pcb_bxl_ctx_t *ctx); +void pcb_bxl_reset(pcb_bxl_ctx_t *ctx); +void pcb_bxl_reset_pattern(pcb_bxl_ctx_t *ctx); +void pcb_bxl_set_layer(pcb_bxl_ctx_t *ctx, const char *layer_name); +void pcb_bxl_set_justify(pcb_bxl_ctx_t *ctx, const char *str); +void pcb_bxl_set_text_str(pcb_bxl_ctx_t *ctx, char *str); +void pcb_bxl_set_text_style(pcb_bxl_ctx_t *ctx, const char *name); +void pcb_bxl_set_attr_val(pcb_bxl_ctx_t *ctx, char *key, char *val); + +void pcb_bxl_add_property(pcb_bxl_ctx_t *ctx, pcb_any_obj_t *obj, const char *keyval); + +void pcb_bxl_add_line(pcb_bxl_ctx_t *ctx); +void pcb_bxl_add_arc(pcb_bxl_ctx_t *ctx); +void pcb_bxl_add_text(pcb_bxl_ctx_t *ctx); + +void pcb_bxl_poly_begin(pcb_bxl_ctx_t *ctx); +void pcb_bxl_poly_end(pcb_bxl_ctx_t *ctx); +void pcb_bxl_poly_add_vertex(pcb_bxl_ctx_t *ctx, rnd_coord_t x, rnd_coord_t y); + +void pcb_bxl_text_style_begin(pcb_bxl_ctx_t *ctx, char *name); +void pcb_bxl_text_style_end(pcb_bxl_ctx_t *ctx); + +void pcb_bxl_padstack_begin(pcb_bxl_ctx_t *ctx, char *name); +void pcb_bxl_padstack_end(pcb_bxl_ctx_t *ctx); +void pcb_bxl_padstack_begin_shape(pcb_bxl_ctx_t *ctx, const char *name); +void pcb_bxl_padstack_end_shape(pcb_bxl_ctx_t *ctx); + +void pcb_bxl_pad_begin(pcb_bxl_ctx_t *ctx); +void pcb_bxl_pad_end(pcb_bxl_ctx_t *ctx); +void pcb_bxl_pad_set_style(pcb_bxl_ctx_t *ctx, const char *pstkname); +#endif Index: tags/2.3.0/src_plugins/io_bxl/bxl_decode.c =================================================================== --- tags/2.3.0/src_plugins/io_bxl/bxl_decode.c (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/bxl_decode.c (revision 33253) @@ -0,0 +1,332 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * BXL IO plugin - file format read, binary decoder + * pcb-rnd Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * Algorithm based on BXL2text/SourceBuffer.cc by Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include "bxl_decode.h" + +/* Allocates a new node under parent (parent is NULL for root) */ +static hnode_t *hnode_alloc(htree_t *tree, hnode_t *parent, int symbol) +{ + hnode_t *n; + + assert(tree->pool_used < sizeof(tree->pool) / sizeof(tree->pool[0])); + + n = &tree->pool[tree->pool_used++]; + + n->weight = 0; + + if (parent != NULL) { + n->parent = parent; + n->level = parent->level+1; + } + else { + n->parent = NULL; + n->level = 0; + } + + if (n->level > 7) + n->symbol = symbol; + else + n->symbol = -1; + return n; +} + +static hnode_t *hnode_add_child(htree_t *tree, hnode_t *n, int symbol) +{ + hnode_t *ret; + + if (n->level < 7) { + if (n->right != NULL) { + ret = hnode_add_child(tree, n->right, symbol); + if (ret != NULL) + return ret; + } + if (n->left != NULL) { + ret = hnode_add_child(tree, n->left, symbol); + if (ret != NULL) + return ret; + } + if (n->right == NULL) { /* fill from the right side */ + n->right = hnode_alloc(tree, n, -1); + return n->right; + } + if (n->left == NULL) { + n->left = hnode_alloc(tree, n, -1); + return n->left; + } + return NULL; + } + + if (n->right == NULL) { + n->right = hnode_alloc(tree, n, symbol); + return n->right; + } + if (n->left == NULL) { + n->left = hnode_alloc(tree, n, symbol); + return n->left; + } + + return NULL; /* leaves are filled */ +} + +#define is_leaf(n) ((n)->level > 7) + +#define sibling(parent, n) (((n) == (parent)->right) ? (parent)->left : (parent)->right) + +#define inc_weight(n) (n)->weight++ + +#define need_swapping(n) \ + ((n)->parent != NULL && (n)->parent->parent != NULL && (n)->weight > (n)->parent->weight) + +static void hnode_swap(hnode_t *n1, hnode_t *n2, hnode_t *n3) +{ + if (n3 != NULL) + n3->parent = n1; + + if (n1->right == n2) + n1->right = n3; + else if (n1->left == n2) + n1->left = n3; +} + +static htree_t *htree_init(htree_t *t) +{ + int leaf_count = 0; + hnode_t *node; + + t->pool_used = 0; + node = t->root = hnode_alloc(t, NULL, 0); + + /* fill levels */ + while(node != NULL) { + node = hnode_add_child(t, t->root, leaf_count); + if ((node != NULL) && (is_leaf(node))) { + t->node_linear[leaf_count] = node; + leaf_count++; + } + } + return t; +} + +static void htree_update(hnode_t *current) +{ + hnode_t *parent, *grand_parent, *parent_sibling; + if ((current == NULL) || (!need_swapping(current))) + return; + + parent = current->parent; + grand_parent = parent->parent; + parent_sibling = sibling(grand_parent, parent); + + hnode_swap(grand_parent, parent, current); + hnode_swap(grand_parent, parent_sibling, parent); + hnode_swap(parent, current, parent_sibling); + + parent->weight = parent->right->weight + parent->left->weight; + grand_parent->weight = current->weight + parent->weight; + + htree_update(parent); + htree_update(grand_parent); + htree_update(current); +} + +static int next_bit(hdecode_t *ctx) +{ + if (ctx->bitpos < 0) { + ctx->bitpos = 7; + return -1; /* read the next */ + } + return ctx->chr & (1 << (ctx->bitpos--)); +} + +static void decode_run(hdecode_t *ctx) +{ + for(;;) { + while(!is_leaf(ctx->node)) { + int bit = next_bit(ctx); + if (bit < 0) + return; /* wait for the next byte */ + if (bit) + ctx->node = ctx->node->left; + else + ctx->node = ctx->node->right; + } + + /* produce the next output byte */ + if (ctx->opos < ctx->plain_len) + ctx->out[ctx->out_len++] = ctx->node->symbol; + ctx->opos++; + inc_weight(ctx->node); + htree_update(ctx->node); + ctx->node = ctx->tree.root; + } +} + +/* Swap the bits in a byte */ +static unsigned long int bitswap(unsigned int i) +{ + int n; + unsigned long int o = 0; + + for(n = 0; n < 8; n++) { + o <<= 1; + o |= (i & 1); + i >>= 1; + } + + return o; +} + +int pcb_bxl_decode_char(hdecode_t *ctx, int inchr) +{ + if (ctx->hdr_pos < 4) { + /* Read the header; the header is A B C D, where A is the LSB and + D is the MSB of uncompressed file length in bytes; each header + byte is binary mirrored for some very good but unfortunately + undocumented reason. + + Yet another twist: the input binary file often (always?) ends in + \r\n. Thus the plain text output must be truncated at the length + extracted from the header, else there would be noise causing syntax + error at the end of the decoded file. + */ + ctx->hdr[ctx->hdr_pos] = inchr; + ctx->hdr_pos++; + if (ctx->hdr_pos == 4) + ctx->plain_len = bitswap(ctx->hdr[3]) << 24 | bitswap(ctx->hdr[2]) << 16 | bitswap(ctx->hdr[1]) << 8 | bitswap(ctx->hdr[0]); + return 0; + } + + if (ctx->opos >= ctx->plain_len) + return 0; + + ctx->out_len = 0; + ctx->chr = inchr; + decode_run(ctx); + return ctx->out_len; +} + +void pcb_bxl_decode_init(hdecode_t *ctx) +{ + memset(ctx, 0, sizeof(hdecode_t)); + htree_init(&ctx->tree); + ctx->node = ctx->tree.root; + decode_run(ctx); +} + +static void append(hdecode_t *ctx, int bitval) +{ + ctx->chr <<= 1; + ctx->chr |= bitval; + ctx->bitpos++; + if (ctx->bitpos == 8) { + ctx->out[ctx->out_len++] = ctx->chr; + ctx->chr = ctx->bitpos = 0; + } +} + +int pcb_bxl_encode_char(hdecode_t *ctx, int inchr) +{ + int depth = 0; + int encoded[257]; /* we need to account for very asymmetric tree topologies */ + hnode_t *node = ctx->tree.node_linear[inchr]; + + ctx->plain_len++; + ctx->out_len = 0; + + /* output 4 dummy bytes that will be the length "header" */ + if (!ctx->after_first_bit) + ctx->out_len = 4; + + inc_weight(node); + + while (node->level != 0) { + if (node == node->parent->left) + encoded[256-depth] = 1; /* left of parent */ + else + encoded[256-depth] = 0; /* right of parent */ + depth++; + node = node->parent; + } + + for(; depth > 0; depth--) { + if (ctx->after_first_bit) { + if (encoded[257-depth]) + append(ctx, 1); + else + append(ctx, 0); + } + else + ctx->after_first_bit = 1; + } + + htree_update(ctx->tree.node_linear[inchr]); + return ctx->out_len; +} + +int pcb_bxl_encode_eof(hdecode_t *ctx) +{ + ctx->out_len = 0; + if (ctx->bitpos != 0) { + /* pad the last byte */ + while(ctx->out_len == 0) + append(ctx, 0); + } + ctx->out[ctx->out_len++] = '\r'; + ctx->out[ctx->out_len++] = '\n'; + return ctx->out_len; +} + +int pcb_bxl_encode_len(hdecode_t *ctx) +{ + unsigned long int len = ctx->plain_len; + int n; + + ctx->bitpos = ctx->out_len = 0; + + for(n = 0; n < 32; n++) { + append(ctx, len & 1); + len >>= 1; + } + return ctx->out_len; +} + + +void pcb_bxl_encode_init(hdecode_t *ctx) +{ + pcb_bxl_decode_init(ctx); + ctx->bitpos = 0; +} + Index: tags/2.3.0/src_plugins/io_bxl/bxl_decode.h =================================================================== --- tags/2.3.0/src_plugins/io_bxl/bxl_decode.h (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/bxl_decode.h (revision 33253) @@ -0,0 +1,82 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * BXL IO plugin - file format read, binary decoder + * pcb-rnd Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +typedef struct hnode_s hnode_t; + +struct hnode_s { + int level, symbol, weight; + hnode_t *parent, *left, *right; +}; + +typedef struct htree_s { + hnode_t *root; + hnode_t pool[512]; + hnode_t *node_linear[256]; + int pool_used; +} htree_t; + +typedef struct hdecode_s { + int chr, bitpos; + htree_t tree; + hnode_t *node; + int out[10]; + int out_len; + int hdr_pos; + int hdr[4]; + unsigned long int plain_len, opos; + unsigned after_first_bit:1; +} hdecode_t; + +/* Initialize a decode context, before the first input byte is pushed. + No dynamic allocation is done during decoding so no uninit required. */ +void pcb_bxl_decode_init(hdecode_t *ctx); + +/* Feed the state machine with an input character. Returns the number of + output characters available in ctx->out[]; these must be saved before + the next call. */ +int pcb_bxl_decode_char(hdecode_t *ctx, int inchr); + + +/* Initialize an encode context, before the first output byte is pushed. + No dynamic allocation is done during encoding so no uninit required. */ +void pcb_bxl_encode_init(hdecode_t *ctx); + +/* Feed the state machine with an output character. Returns the number of + encoded characters available in ctx->out[]; these must be saved before + the next call. */ +int pcb_bxl_encode_char(hdecode_t *ctx, int inchr); + +/* Call this at the end of the output stream to flush the last incomplete + output byte. Same return as pcb_bxl_encode_char. */ +int pcb_bxl_encode_eof(hdecode_t *ctx); + +/* Call this after pcb_bxl_encode_eof() to generate the "length header" that + shall be written at the beginning of the stream. */ +int pcb_bxl_encode_len(hdecode_t *ctx); + Index: tags/2.3.0/src_plugins/io_bxl/bxl_gram.c =================================================================== --- tags/2.3.0/src_plugins/io_bxl/bxl_gram.c (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/bxl_gram.c (revision 33253) @@ -0,0 +1,907 @@ + +#ifdef YY_QUERY_API_VER +#define YY_BYACCIC +#define YY_API_MAJOR 1 +#define YY_API_MINOR 0 +#endif /*YY_QUERY_API_VER*/ + +#define pcb_bxl_EMPTY (-1) +#define pcb_bxl_clearin (pcb_bxl_chr = pcb_bxl_EMPTY) +#define pcb_bxl_errok (pcb_bxl_errflag = 0) +#define pcb_bxl_RECOVERING() (pcb_bxl_errflag != 0) +#define pcb_bxl_ENOMEM (-2) +#define pcb_bxl_EOF 0 +#line 16 "bxl_gram.c" +#include "bxl_gram.h" +static const pcb_bxl_int_t pcb_bxl_lhs[] = { -1, + 0, 5, 5, 6, 6, 6, 6, 3, 3, 7, + 7, 4, 4, 1, 1, 2, 12, 12, 12, 13, + 14, 15, 17, 8, 16, 16, 18, 18, 18, 20, + 22, 9, 19, 19, 23, 23, 23, 23, 21, 21, + 26, 24, 25, 25, 27, 27, 27, 27, 29, 10, + 28, 28, 30, 30, 30, 30, 31, 32, 32, 33, + 33, 33, 33, 33, 33, 33, 33, 43, 34, 42, + 42, 44, 44, 44, 44, 44, 44, 44, 46, 35, + 45, 45, 47, 47, 47, 47, 47, 49, 36, 48, + 48, 50, 50, 50, 50, 52, 37, 51, 51, 53, + 53, 53, 53, 55, 39, 54, 54, 56, 56, 56, + 56, 56, 56, 58, 40, 57, 57, 59, 59, 59, + 59, 59, 59, 41, 38, 60, 60, 61, 61, 61, + 62, 11, 63, 11, +}; +static const pcb_bxl_int_t pcb_bxl_len[] = { 2, + 2, 0, 3, 1, 1, 1, 1, 1, 1, 1, + 2, 0, 1, 1, 1, 1, 2, 2, 2, 4, + 2, 2, 0, 4, 0, 4, 2, 2, 2, 0, + 0, 12, 0, 4, 2, 2, 2, 2, 0, 2, + 0, 5, 0, 4, 2, 2, 1, 1, 0, 6, + 0, 3, 1, 6, 6, 6, 6, 0, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 3, 0, + 4, 2, 2, 2, 2, 2, 2, 1, 0, 3, + 0, 4, 2, 3, 1, 1, 1, 0, 3, 0, + 4, 4, 1, 1, 1, 0, 3, 0, 4, 3, + 1, 1, 1, 0, 3, 0, 4, 2, 2, 2, + 1, 1, 1, 0, 3, 0, 4, 2, 2, 2, + 1, 1, 1, 2, 2, 0, 4, 2, 2, 1, + 0, 4, 0, 4, +}; +static const pcb_bxl_int_t pcb_bxl_defred[] = { 0, + 0, 0, 0, 13, 11, 0, 0, 0, 1, 0, + 4, 5, 6, 7, 0, 0, 23, 30, 0, 0, + 0, 0, 0, 0, 49, 3, 0, 0, 0, 24, + 0, 0, 0, 132, 134, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 53, 14, 15, 27, 28, 29, 0, 16, 35, + 8, 9, 36, 37, 38, 0, 0, 0, 0, 0, + 0, 50, 0, 26, 34, 0, 0, 0, 0, 0, + 52, 0, 0, 0, 0, 0, 31, 68, 79, 88, + 96, 104, 114, 0, 0, 0, 0, 60, 61, 62, + 63, 64, 65, 66, 67, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 124, 125, 57, 0, + 54, 55, 56, 0, 0, 0, 0, 69, 0, 80, + 0, 89, 0, 97, 0, 105, 0, 115, 0, 0, + 0, 130, 0, 59, 41, 32, 40, 0, 0, 0, + 0, 0, 0, 78, 0, 0, 0, 0, 0, 85, + 86, 87, 0, 0, 93, 94, 95, 0, 0, 0, + 0, 0, 101, 102, 103, 0, 0, 0, 0, 111, + 112, 113, 0, 0, 0, 0, 121, 122, 123, 0, + 0, 128, 129, 0, 0, 72, 73, 74, 75, 76, + 77, 0, 22, 21, 83, 0, 0, 0, 0, 18, + 0, 17, 19, 0, 108, 109, 110, 0, 120, 118, + 119, 0, 0, 127, 0, 0, 71, 84, 82, 0, + 91, 100, 99, 107, 117, 20, 0, 0, 47, 48, + 0, 42, 92, 45, 46, 0, 44, +}; +static const pcb_bxl_int_t pcb_bxl_dgoto[] = { 2, + 59, 60, 63, 3, 9, 10, 4, 11, 12, 13, + 14, 173, 142, 161, 162, 30, 23, 39, 32, 24, + 125, 109, 44, 126, 226, 195, 241, 50, 33, 51, + 52, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 128, 110, 155, 130, 111, 163, 132, 112, 168, + 134, 113, 176, 136, 114, 183, 138, 115, 190, 117, + 143, 15, 16, +}; +static const pcb_bxl_int_t pcb_bxl_sindex[] = { -7, + -7, 0, -181, 0, 0, -255, -250, -226, 0, -7, + 0, 0, 0, 0, -285, -278, 0, 0, -7, -181, + -216, -213, 6, 12, 0, 0, -249, -259, -119, 0, + -234, -7, -140, 0, 0, -210, -210, -210, 25, -210, + -201, -201, -201, 27, -198, 15, 36, 39, 41, -176, + -7, 0, 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 12, 34, -160, -210, -210, + -210, 0, -140, 0, 0, -153, -7, 69, 73, 75, + 0, -7, -178, -210, -210, -210, 0, 0, 0, 0, + 0, 0, 0, 80, 80, -157, -7, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 86, 88, -131, 90, + 110, 112, 113, 116, 117, -257, 0, 0, 0, -178, + 0, 0, 0, -102, -109, -131, -154, 0, -233, 0, + -199, 0, -235, 0, -207, 0, -245, 0, -210, -100, + -99, 0, 121, 0, 0, 0, 0, -94, -97, -93, + -91, -92, -210, 0, 124, -210, -87, -89, 128, 0, + 0, 0, 132, -210, 0, 0, 0, 133, -84, -83, + -79, -201, 0, 0, 0, 138, -210, -210, -210, 0, + 0, 0, 139, -210, -77, -201, 0, 0, 0, 140, + 141, 0, 0, 80, 144, 0, 0, 0, 0, 0, + 0, 90, 0, 0, 0, -210, 110, 142, 112, 0, + -73, 0, 0, 113, 0, 0, 0, 116, 0, 0, + 0, 117, -210, 0, -187, -7, 0, 0, 0, -210, + 0, 0, 0, 0, 0, 0, -210, -70, 0, 0, + 148, 0, 0, 0, 0, 144, 0, +}; +static const pcb_bxl_int_t pcb_bxl_rindex[] = { 9, + 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 180, 181, 0, 0, 0, 0, 0, 0, + 0, 0, -86, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, + 0, 0, 0, 0, 0, 181, 0, 0, 0, 0, + 0, 0, -86, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -85, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 182, 182, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -74, 185, + 187, 188, 189, 190, 191, 0, 0, 0, 0, -85, + 0, 0, 0, 0, 0, -74, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 182, 192, 0, 0, 0, 0, 0, + 0, 185, 0, 0, 0, 0, 187, 0, 188, 0, + 0, 0, 0, 189, 0, 0, 0, 190, 0, 0, + 0, 191, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 192, 0, +}; +static const pcb_bxl_int_t pcb_bxl_gindex[] = { 0, + -30, -55, -31, 0, 183, 0, 3, 0, 0, 0, + 0, 67, -25, -114, -111, 147, 0, 0, 143, 0, + 81, 0, 0, 0, -40, 0, 0, 135, 0, 0, + 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8, 0, 0, 5, 0, 0, 4, 0, 0, + 7, 0, 0, -4, 0, 0, -6, 0, 0, -95, + 0, 0, 0, +}; +#define pcb_bxl_TABLESIZE 323 +static const pcb_bxl_int_t pcb_bxl_table[] = { 118, + 10, 2, 1, 5, 17, 55, 56, 57, 12, 18, + 64, 65, 20, 78, 79, 80, 166, 169, 175, 167, + 181, 25, 189, 182, 53, 54, 21, 169, 106, 107, + 108, 157, 139, 19, 45, 22, 40, 41, 42, 27, + 156, 157, 28, 157, 139, 29, 184, 53, 54, 140, + 141, 31, 171, 73, 139, 35, 139, 185, 172, 61, + 62, 170, 171, 34, 186, 58, 156, 66, 172, 157, + 67, 158, 68, 159, 156, 69, 43, 157, 70, 83, + 71, 6, 139, 191, 87, 7, 156, 237, 238, 157, + 139, 76, 177, 178, 179, 164, 8, 77, 224, 120, + 203, 154, 72, 160, 82, 165, 88, 174, 208, 180, + 239, 188, 84, 240, 89, 90, 85, 91, 86, 116, + 92, 215, 201, 119, 93, 121, 122, 94, 123, 127, + 95, 148, 149, 150, 151, 139, 152, 153, 124, 46, + 213, 47, 48, 49, 36, 37, 38, 216, 217, 129, + 228, 131, 133, 219, 221, 135, 137, 145, 146, 192, + 193, 194, 197, 196, 202, 200, 198, 236, 199, 204, + 205, 206, 207, 209, 243, 210, 211, 212, 214, 218, + 222, 244, 220, 225, 223, 230, 232, 245, 246, 25, + 33, 126, 51, 39, 70, 58, 81, 90, 98, 106, + 116, 43, 26, 187, 74, 247, 147, 81, 75, 227, + 144, 229, 231, 234, 0, 235, 0, 0, 0, 0, + 233, 0, 0, 0, 0, 0, 0, 0, 242, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 10, 10, 10, + 10, 12, 0, 0, 0, 12, 0, 0, 10, 10, + 10, 10, 10, 10, 10, 10, 12, 0, 0, 0, + 0, 0, 0, 10, 10, 0, 10, 0, 0, 10, + 0, 0, 0, 10, 0, 0, 10, 0, 0, 10, + 0, 0, 10, 131, 10, 133, 0, 0, 0, 0, + 12, 0, 12, +}; +static const pcb_bxl_int_t pcb_bxl_check[] = { 95, + 0, 0, 10, 1, 260, 36, 37, 38, 0, 260, + 42, 43, 10, 69, 70, 71, 131, 263, 133, 131, + 135, 19, 137, 135, 258, 259, 312, 263, 84, 85, + 86, 277, 290, 260, 32, 314, 271, 272, 273, 256, + 274, 277, 256, 277, 290, 40, 292, 258, 259, 307, + 308, 40, 298, 51, 290, 315, 290, 303, 304, 261, + 262, 297, 298, 313, 310, 41, 274, 41, 304, 277, + 269, 305, 58, 129, 274, 40, 311, 277, 40, 77, + 40, 263, 290, 139, 82, 267, 274, 275, 276, 277, + 290, 58, 300, 301, 302, 295, 278, 258, 194, 97, + 156, 127, 279, 129, 258, 131, 285, 133, 164, 135, + 225, 137, 44, 225, 293, 294, 44, 296, 44, 40, + 299, 177, 153, 281, 303, 41, 41, 306, 41, 40, + 309, 286, 287, 288, 289, 290, 291, 292, 270, 280, + 172, 282, 283, 284, 264, 265, 266, 178, 179, 40, + 206, 40, 40, 184, 186, 40, 40, 260, 268, 260, + 260, 41, 260, 258, 41, 258, 260, 223, 260, 257, + 260, 44, 41, 41, 230, 260, 260, 257, 41, 41, + 41, 237, 260, 40, 44, 44, 260, 258, 41, 10, + 10, 10, 279, 268, 10, 281, 10, 10, 10, 10, + 10, 10, 20, 137, 58, 246, 126, 73, 66, 202, + 120, 207, 209, 218, -1, 222, -1, -1, -1, -1, + 214, -1, -1, -1, -1, -1, -1, -1, 226, -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, 263, -1, -1, -1, 267, 268, 269, + 270, 263, -1, -1, -1, 267, -1, -1, 278, 279, + 280, 281, 282, 283, 284, 285, 278, -1, -1, -1, + -1, -1, -1, 293, 294, -1, 296, -1, -1, 299, + -1, -1, -1, 303, -1, -1, 306, -1, -1, 309, + -1, -1, 312, 312, 314, 314, -1, -1, -1, -1, + 312, -1, 314, +}; +#define pcb_bxl_FINAL 2 +#define pcb_bxl_MAXTOKEN 315 +#define pcb_bxl_UNDFTOKEN 381 +#define pcb_bxl_TRANSLATE(a) ((a) > pcb_bxl_MAXTOKEN ? pcb_bxl_UNDFTOKEN : (a)) +#if pcb_bxl_DEBUG +static const char *const pcb_bxl_name[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,"'('","')'",0,0,"','",0,0,0,0,0,0,0,0,0,0,0,0,0,"':'",0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,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_ID", +"T_INTEGER","T_REAL_ONLY","T_QSTR","T_TRUE","T_FALSE","T_TEXTSTYLE", +"T_FONTWIDTH","T_FONTCHARWIDTH","T_FONTHEIGHT","T_PADSTACK","T_ENDPADSTACK", +"T_SHAPES","T_PADSHAPE","T_HOLEDIAM","T_SURFACE","T_PLATED","T_WIDTH", +"T_HEIGHT","T_PADTYPE","T_LAYER","T_PATTERN","T_ENDPATTERN","T_DATA", +"T_ENDDATA","T_ORIGINPOINT","T_PICKPOINT","T_GLUEPOINT","T_PAD","T_NUMBER", +"T_PINNAME","T_PADSTYLE","T_ORIGINALPADSTYLE","T_ORIGIN","T_ORIGINALPINNUMBER", +"T_ROTATE","T_POLY","T_LINE","T_ENDPOINT","T_ATTRIBUTE","T_ATTR","T_JUSTIFY", +"T_ARC","T_RADIUS","T_STARTANGLE","T_SWEEPANGLE","T_TEXT","T_ISVISIBLE", +"T_PROPERTY","T_WIZARD","T_VARNAME","T_VARDATA","T_TEMPLATEDATA","T_ISFLIPPED", +"T_NOPASTE","T_SYMBOL","T_ENDSYMBOL","T_COMPONENT","T_ENDCOMPONENT",0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"illegal-symbol", +}; +static const char *const pcb_bxl_rule[] = { +"$accept : full_file", +"full_file : maybe_nl file", +"file :", +"file : statement nl file", +"statement : text_style", +"statement : pad_stack", +"statement : pattern", +"statement : boring_section", +"boolean : T_TRUE", +"boolean : T_FALSE", +"nl : '\\n'", +"nl : '\\n' nl", +"maybe_nl :", +"maybe_nl : nl", +"real : T_INTEGER", +"real : T_REAL_ONLY", +"coord : real", +"common_attr_text : T_JUSTIFY T_ID", +"common_attr_text : T_TEXTSTYLE T_QSTR", +"common_attr_text : T_ISVISIBLE boolean", +"common_origin : T_ORIGIN coord ',' coord", +"common_layer : T_LAYER T_ID", +"common_width : T_WIDTH coord", +"$$1 :", +"text_style : T_TEXTSTYLE T_QSTR $$1 text_style_attrs", +"text_style_attrs :", +"text_style_attrs : '(' text_style_attr ')' text_style_attrs", +"text_style_attr : T_FONTWIDTH real", +"text_style_attr : T_FONTCHARWIDTH real", +"text_style_attr : T_FONTHEIGHT real", +"$$2 :", +"$$3 :", +"pad_stack : T_PADSTACK T_QSTR $$2 pstk_attrs nl T_SHAPES ':' T_INTEGER nl $$3 pad_shapes T_ENDPADSTACK", +"pstk_attrs :", +"pstk_attrs : '(' pstk_attr ')' pstk_attrs", +"pstk_attr : T_HOLEDIAM coord", +"pstk_attr : T_SURFACE boolean", +"pstk_attr : T_PLATED boolean", +"pstk_attr : T_NOPASTE boolean", +"pad_shapes :", +"pad_shapes : pad_shape pad_shapes", +"$$4 :", +"pad_shape : T_PADSHAPE T_QSTR $$4 padshape_attrs nl", +"padshape_attrs :", +"padshape_attrs : '(' padshape_attr ')' padshape_attrs", +"padshape_attr : T_HEIGHT coord", +"padshape_attr : T_PADTYPE T_INTEGER", +"padshape_attr : common_layer", +"padshape_attr : common_width", +"$$5 :", +"pattern : T_PATTERN T_QSTR nl $$5 pattern_chldrn T_ENDPATTERN", +"pattern_chldrn :", +"pattern_chldrn : pattern_chld nl pattern_chldrn", +"pattern_chld : data", +"pattern_chld : T_ORIGINPOINT '(' coord ',' coord ')'", +"pattern_chld : T_PICKPOINT '(' coord ',' coord ')'", +"pattern_chld : T_GLUEPOINT '(' coord ',' coord ')'", +"data : T_DATA ':' T_INTEGER nl data_chldrn T_ENDDATA", +"data_chldrn :", +"data_chldrn : data_chld nl data_chldrn", +"data_chld : pad", +"data_chld : poly", +"data_chld : line", +"data_chld : attribute", +"data_chld : templatedata", +"data_chld : arc", +"data_chld : text", +"data_chld : wizard", +"$$6 :", +"pad : T_PAD $$6 pad_attrs", +"pad_attrs :", +"pad_attrs : '(' pad_attr ')' pad_attrs", +"pad_attr : T_NUMBER T_INTEGER", +"pad_attr : T_PINNAME T_QSTR", +"pad_attr : T_PADSTYLE T_QSTR", +"pad_attr : T_ORIGINALPADSTYLE T_QSTR", +"pad_attr : T_ORIGINALPINNUMBER T_INTEGER", +"pad_attr : T_ROTATE real", +"pad_attr : common_origin", +"$$7 :", +"poly : T_POLY $$7 poly_attrs", +"poly_attrs :", +"poly_attrs : '(' poly_attr ')' poly_attrs", +"poly_attr : T_PROPERTY T_QSTR", +"poly_attr : coord ',' coord", +"poly_attr : common_origin", +"poly_attr : common_layer", +"poly_attr : common_width", +"$$8 :", +"line : T_LINE $$8 line_attrs", +"line_attrs :", +"line_attrs : '(' line_attr ')' line_attrs", +"line_attr : T_ENDPOINT coord ',' coord", +"line_attr : common_origin", +"line_attr : common_layer", +"line_attr : common_width", +"$$9 :", +"attribute : T_ATTRIBUTE $$9 attribute_attrs", +"attribute_attrs :", +"attribute_attrs : '(' attribute_attr ')' attribute_attrs", +"attribute_attr : T_ATTR T_QSTR T_QSTR", +"attribute_attr : common_attr_text", +"attribute_attr : common_origin", +"attribute_attr : common_layer", +"$$10 :", +"arc : T_ARC $$10 arc_attrs", +"arc_attrs :", +"arc_attrs : '(' arc_attr ')' arc_attrs", +"arc_attr : T_RADIUS coord", +"arc_attr : T_STARTANGLE real", +"arc_attr : T_SWEEPANGLE real", +"arc_attr : common_origin", +"arc_attr : common_layer", +"arc_attr : common_width", +"$$11 :", +"text : T_TEXT $$11 text_attrs", +"text_attrs :", +"text_attrs : '(' text_attr ')' text_attrs", +"text_attr : T_TEXT T_QSTR", +"text_attr : T_ISFLIPPED boolean", +"text_attr : T_ROTATE real", +"text_attr : common_attr_text", +"text_attr : common_origin", +"text_attr : common_layer", +"wizard : T_WIZARD wizard_attrs", +"templatedata : T_TEMPLATEDATA wizard_attrs", +"wizard_attrs :", +"wizard_attrs : '(' wizard_attr ')' wizard_attrs", +"wizard_attr : T_VARNAME T_QSTR", +"wizard_attr : T_VARDATA T_QSTR", +"wizard_attr : common_origin", +"$$12 :", +"boring_section : $$12 T_SYMBOL error T_ENDSYMBOL", +"$$13 :", +"boring_section : $$13 T_COMPONENT error T_ENDCOMPONENT", + +}; +#endif + + +#if pcb_bxl_DEBUG +#include /* needed for printf */ +#endif + +#include /* needed for malloc, etc */ +#include /* needed for memset */ + +/* allocate initial stack or double stack size, up to yyctx->stack_max_depth */ +static int pcb_bxl_growstack(pcb_bxl_yyctx_t *yyctx, pcb_bxl_STACKDATA *data) +{ + int i; + unsigned newsize; + pcb_bxl_int_t *newss; + pcb_bxl_STYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = pcb_bxl_INITSTACKSIZE; + else if (newsize >= yyctx->stack_max_depth) + return pcb_bxl_ENOMEM; + else if ((newsize *= 2) > yyctx->stack_max_depth) + newsize = yyctx->stack_max_depth; + + i = (int)(data->s_mark - data->s_base); + newss = (pcb_bxl_int_t *) realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return pcb_bxl_ENOMEM; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (pcb_bxl_STYPE *) realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return pcb_bxl_ENOMEM; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +static void pcb_bxl_freestack(pcb_bxl_STACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} + +#define pcb_bxl_ABORT goto yyabort +#define pcb_bxl_REJECT goto yyabort +#define pcb_bxl_ACCEPT goto yyaccept +#define pcb_bxl_ERROR goto yyerrlab + +int pcb_bxl_parse_init(pcb_bxl_yyctx_t *yyctx) +{ +#if pcb_bxl_DEBUG + const char *yys; + + if ((yys = getenv("pcb_bxl_DEBUG")) != 0) { + yyctx->yyn = *yys; + if (yyctx->yyn >= '0' && yyctx->yyn <= '9') + yyctx->debug = yyctx->yyn - '0'; + } +#endif + + memset(&yyctx->val, 0, sizeof(yyctx->val)); + memset(&yyctx->lval, 0, sizeof(yyctx->lval)); + + yyctx->yym = 0; + yyctx->yyn = 0; + yyctx->nerrs = 0; + yyctx->errflag = 0; + yyctx->chr = pcb_bxl_EMPTY; + yyctx->state = 0; + + memset(&yyctx->stack, 0, sizeof(yyctx->stack)); + + yyctx->stack_max_depth = pcb_bxl_INITSTACKSIZE > 10000 ? pcb_bxl_INITSTACKSIZE : 10000; + if (yyctx->stack.s_base == NULL && pcb_bxl_growstack(yyctx, &yyctx->stack) == pcb_bxl_ENOMEM) + return -1; + yyctx->stack.s_mark = yyctx->stack.s_base; + yyctx->stack.l_mark = yyctx->stack.l_base; + yyctx->state = 0; + *yyctx->stack.s_mark = 0; + yyctx->jump = 0; + return 0; +} + + +#define pcb_bxl_GETCHAR(labidx) \ +do { \ + if (used) { yyctx->jump = labidx; return pcb_bxl_RES_NEXT; } \ + getchar_ ## labidx:; yyctx->chr = tok; yyctx->lval = *lval; used = 1; \ +} while(0) + +pcb_bxl_res_t pcb_bxl_parse(pcb_bxl_yyctx_t *yyctx, pcb_bxl_ctx_t *ctx, int tok, pcb_bxl_STYPE *lval) +{ + int used = 0; +#if pcb_bxl_DEBUG + const char *yys; +#endif + +yyloop:; + if (yyctx->jump == 1) { yyctx->jump = 0; goto getchar_1; } + if (yyctx->jump == 2) { yyctx->jump = 0; goto getchar_2; } + + if ((yyctx->yyn = pcb_bxl_defred[yyctx->state]) != 0) + goto yyreduce; + if (yyctx->chr < 0) { + pcb_bxl_GETCHAR(1); + if (yyctx->chr < 0) + yyctx->chr = pcb_bxl_EOF; +#if pcb_bxl_DEBUG + if (yyctx->debug) { + if ((yys = pcb_bxl_name[pcb_bxl_TRANSLATE(yyctx->chr)]) == NULL) + yys = pcb_bxl_name[pcb_bxl_UNDFTOKEN]; + printf("yyctx->debug: state %d, reading %d (%s)\n", yyctx->state, yyctx->chr, yys); + } +#endif + } + if (((yyctx->yyn = pcb_bxl_sindex[yyctx->state]) != 0) && (yyctx->yyn += yyctx->chr) >= 0 && yyctx->yyn <= pcb_bxl_TABLESIZE && pcb_bxl_check[yyctx->yyn] == (pcb_bxl_int_t) yyctx->chr) { +#if pcb_bxl_DEBUG + if (yyctx->debug) + printf("yyctx->debug: state %d, shifting to state %d\n", yyctx->state, pcb_bxl_table[yyctx->yyn]); +#endif + if (yyctx->stack.s_mark >= yyctx->stack.s_last && pcb_bxl_growstack(yyctx, &yyctx->stack) == pcb_bxl_ENOMEM) + goto yyoverflow; + yyctx->state = pcb_bxl_table[yyctx->yyn]; + *++yyctx->stack.s_mark = pcb_bxl_table[yyctx->yyn]; + *++yyctx->stack.l_mark = yyctx->lval; + yyctx->chr = pcb_bxl_EMPTY; + if (yyctx->errflag > 0) + --yyctx->errflag; + goto yyloop; + } + if (((yyctx->yyn = pcb_bxl_rindex[yyctx->state]) != 0) && (yyctx->yyn += yyctx->chr) >= 0 && yyctx->yyn <= pcb_bxl_TABLESIZE && pcb_bxl_check[yyctx->yyn] == (pcb_bxl_int_t) yyctx->chr) { + yyctx->yyn = pcb_bxl_table[yyctx->yyn]; + goto yyreduce; + } + if (yyctx->errflag != 0) + goto yyinrecovery; + + pcb_bxl_error(ctx, yyctx->lval, "syntax error"); + + goto yyerrlab; /* redundant goto avoids 'unused label' warning */ +yyerrlab: + ++yyctx->nerrs; + +yyinrecovery: + if (yyctx->errflag < 3) { + yyctx->errflag = 3; + for(;;) { + if (((yyctx->yyn = pcb_bxl_sindex[*yyctx->stack.s_mark]) != 0) && (yyctx->yyn += pcb_bxl_ERRCODE) >= 0 && yyctx->yyn <= pcb_bxl_TABLESIZE && pcb_bxl_check[yyctx->yyn] == (pcb_bxl_int_t) pcb_bxl_ERRCODE) { +#if pcb_bxl_DEBUG + if (yyctx->debug) + printf("yyctx->debug: state %d, error recovery shifting to state %d\n", *yyctx->stack.s_mark, pcb_bxl_table[yyctx->yyn]); +#endif + if (yyctx->stack.s_mark >= yyctx->stack.s_last && pcb_bxl_growstack(yyctx, &yyctx->stack) == pcb_bxl_ENOMEM) + goto yyoverflow; + yyctx->state = pcb_bxl_table[yyctx->yyn]; + *++yyctx->stack.s_mark = pcb_bxl_table[yyctx->yyn]; + *++yyctx->stack.l_mark = yyctx->lval; + goto yyloop; + } + else { +#if pcb_bxl_DEBUG + if (yyctx->debug) + printf("yyctx->debug: error recovery discarding state %d\n", *yyctx->stack.s_mark); +#endif + if (yyctx->stack.s_mark <= yyctx->stack.s_base) + goto yyabort; + --yyctx->stack.s_mark; + --yyctx->stack.l_mark; + } + } + } + else { + if (yyctx->chr == pcb_bxl_EOF) + goto yyabort; +#if pcb_bxl_DEBUG + if (yyctx->debug) { + if ((yys = pcb_bxl_name[pcb_bxl_TRANSLATE(yyctx->chr)]) == NULL) + yys = pcb_bxl_name[pcb_bxl_UNDFTOKEN]; + printf("yyctx->debug: state %d, error recovery discards token %d (%s)\n", yyctx->state, yyctx->chr, yys); + } +#endif + yyctx->chr = pcb_bxl_EMPTY; + goto yyloop; + } + +yyreduce: +#if pcb_bxl_DEBUG + if (yyctx->debug) + printf("yyctx->debug: state %d, reducing by rule %d (%s)\n", yyctx->state, yyctx->yyn, pcb_bxl_rule[yyctx->yyn]); +#endif + yyctx->yym = pcb_bxl_len[yyctx->yyn]; + if (yyctx->yym > 0) + yyctx->val = yyctx->stack.l_mark[1 - yyctx->yym]; + else + memset(&yyctx->val, 0, sizeof yyctx->val); + + switch (yyctx->yyn) { +case 8: +#line 104 "bxl_gram.y" + { yyctx->val.un.i = 1; } +break; +case 9: +#line 105 "bxl_gram.y" + { yyctx->val.un.i = 0; } +break; +case 14: +#line 119 "bxl_gram.y" + { yyctx->val.un.d = yyctx->stack.l_mark[0].un.i; } +break; +case 15: +#line 120 "bxl_gram.y" + { yyctx->val.un.d = yyctx->stack.l_mark[0].un.d; } +break; +case 16: +#line 124 "bxl_gram.y" + { yyctx->val.un.c = RND_MIL_TO_COORD(yyctx->stack.l_mark[0].un.d); } +break; +case 17: +#line 128 "bxl_gram.y" + { pcb_bxl_set_justify(ctx, yyctx->stack.l_mark[0].un.s); free(yyctx->stack.l_mark[0].un.s); } +break; +case 18: +#line 129 "bxl_gram.y" + { pcb_bxl_set_text_style(ctx, yyctx->stack.l_mark[0].un.s); free(yyctx->stack.l_mark[0].un.s); } +break; +case 19: +#line 130 "bxl_gram.y" + { ctx->state.is_visible = yyctx->stack.l_mark[0].un.i; } +break; +case 20: +#line 134 "bxl_gram.y" + { ctx->state.origin_x = XCRD(yyctx->stack.l_mark[-2].un.c); ctx->state.origin_y = YCRD(yyctx->stack.l_mark[0].un.c); } +break; +case 21: +#line 138 "bxl_gram.y" + { pcb_bxl_set_layer(ctx, yyctx->stack.l_mark[0].un.s); free(yyctx->stack.l_mark[0].un.s); } +break; +case 22: +#line 142 "bxl_gram.y" + { ctx->state.width = yyctx->stack.l_mark[0].un.c; } +break; +case 23: +#line 148 "bxl_gram.y" + { pcb_bxl_text_style_begin(ctx, yyctx->stack.l_mark[0].un.s); /* $2 is taken over */ } +break; +case 24: +#line 149 "bxl_gram.y" + { pcb_bxl_text_style_end(ctx); } +break; +case 27: +#line 158 "bxl_gram.y" + { ctx->state.text_style->width = yyctx->stack.l_mark[0].un.d; } +break; +case 28: +#line 159 "bxl_gram.y" + { ctx->state.text_style->char_width = yyctx->stack.l_mark[0].un.d; } +break; +case 29: +#line 160 "bxl_gram.y" + { ctx->state.text_style->height = yyctx->stack.l_mark[0].un.d; } +break; +case 30: +#line 167 "bxl_gram.y" + { pcb_bxl_reset(ctx); pcb_bxl_padstack_begin(ctx, yyctx->stack.l_mark[0].un.s); /* $2 is taken over */ } +break; +case 31: +#line 169 "bxl_gram.y" + { ctx->state.num_shapes = yyctx->stack.l_mark[-1].un.i; } +break; +case 32: +#line 171 "bxl_gram.y" + { pcb_bxl_padstack_end(ctx); } +break; +case 35: +#line 180 "bxl_gram.y" + { ctx->state.hole = yyctx->stack.l_mark[0].un.c; } +break; +case 36: +#line 181 "bxl_gram.y" + { ctx->state.surface = yyctx->stack.l_mark[0].un.i; } +break; +case 37: +#line 182 "bxl_gram.y" + { ctx->state.plated = yyctx->stack.l_mark[0].un.i; } +break; +case 38: +#line 183 "bxl_gram.y" + { ctx->state.nopaste = yyctx->stack.l_mark[0].un.i; } +break; +case 41: +#line 192 "bxl_gram.y" + { pcb_bxl_padstack_begin_shape(ctx, yyctx->stack.l_mark[0].un.s); free(yyctx->stack.l_mark[0].un.s); } +break; +case 42: +#line 193 "bxl_gram.y" + { pcb_bxl_padstack_end_shape(ctx); } +break; +case 45: +#line 202 "bxl_gram.y" + { ctx->state.height = yyctx->stack.l_mark[0].un.c; } +break; +case 46: +#line 203 "bxl_gram.y" + { ctx->state.pad_type = yyctx->stack.l_mark[0].un.i; } +break; +case 49: +#line 210 "bxl_gram.y" + { pcb_bxl_reset_pattern(ctx); pcb_bxl_pattern_begin(ctx, yyctx->stack.l_mark[-1].un.s); free(yyctx->stack.l_mark[-1].un.s); } +break; +case 50: +#line 212 "bxl_gram.y" + { pcb_bxl_pattern_end(ctx); pcb_bxl_reset_pattern(ctx); } +break; +case 54: +#line 222 "bxl_gram.y" + { ctx->pat_state.origin_x = XCRD(yyctx->stack.l_mark[-3].un.c); ctx->pat_state.origin_y = YCRD(yyctx->stack.l_mark[-1].un.c); } +break; +case 55: +#line 223 "bxl_gram.y" + { ctx->pat_state.pick_x = XCRD(yyctx->stack.l_mark[-3].un.c); ctx->pat_state.pick_y = YCRD(yyctx->stack.l_mark[-1].un.c); } +break; +case 56: +#line 224 "bxl_gram.y" + { ctx->pat_state.glue_x = XCRD(yyctx->stack.l_mark[-3].un.c); ctx->pat_state.glue_y = YCRD(yyctx->stack.l_mark[-1].un.c); } +break; +case 68: +#line 252 "bxl_gram.y" + { pcb_bxl_pad_begin(ctx); } +break; +case 69: +#line 253 "bxl_gram.y" + { pcb_bxl_pad_end(ctx); } +break; +case 72: +#line 262 "bxl_gram.y" + { ctx->state.pin_number = yyctx->stack.l_mark[0].un.i; } +break; +case 73: +#line 263 "bxl_gram.y" + { ctx->state.pin_name = yyctx->stack.l_mark[0].un.s; /* takes over $2 */ } +break; +case 74: +#line 264 "bxl_gram.y" + { pcb_bxl_pad_set_style(ctx, yyctx->stack.l_mark[0].un.s); free(yyctx->stack.l_mark[0].un.s); } +break; +case 75: +#line 265 "bxl_gram.y" + { /* what's this?! */ free(yyctx->stack.l_mark[0].un.s); } +break; +case 76: +#line 266 "bxl_gram.y" + { /* what's this?! */ } +break; +case 77: +#line 267 "bxl_gram.y" + { ctx->state.rot = yyctx->stack.l_mark[0].un.d; } +break; +case 79: +#line 273 "bxl_gram.y" + { pcb_bxl_poly_begin(ctx); } +break; +case 80: +#line 274 "bxl_gram.y" + { pcb_bxl_poly_end(ctx); } +break; +case 83: +#line 284 "bxl_gram.y" + { pcb_bxl_add_property(ctx, (pcb_any_obj_t *)ctx->state.poly, yyctx->stack.l_mark[0].un.s); free(yyctx->stack.l_mark[0].un.s); } +break; +case 84: +#line 285 "bxl_gram.y" + { pcb_bxl_poly_add_vertex(ctx, XCRD(yyctx->stack.l_mark[-2].un.c), YCRD(yyctx->stack.l_mark[0].un.c)); } +break; +case 88: +#line 293 "bxl_gram.y" + { pcb_bxl_reset(ctx); } +break; +case 89: +#line 294 "bxl_gram.y" + { pcb_bxl_add_line(ctx); pcb_bxl_reset(ctx); } +break; +case 92: +#line 303 "bxl_gram.y" + { ctx->state.endp_x = XCRD(yyctx->stack.l_mark[-2].un.c); ctx->state.endp_y = YCRD(yyctx->stack.l_mark[0].un.c); } +break; +case 96: +#line 311 "bxl_gram.y" + { pcb_bxl_reset(ctx); ctx->state.is_text = 0; } +break; +case 97: +#line 312 "bxl_gram.y" + { pcb_bxl_add_text(ctx); pcb_bxl_reset(ctx); } +break; +case 100: +#line 321 "bxl_gram.y" + { pcb_bxl_set_attr_val(ctx, yyctx->stack.l_mark[-1].un.s, yyctx->stack.l_mark[0].un.s); /* $2 and $3 are taken over */ } +break; +case 104: +#line 330 "bxl_gram.y" + { pcb_bxl_reset(ctx); } +break; +case 105: +#line 331 "bxl_gram.y" + { pcb_bxl_add_arc(ctx); pcb_bxl_reset(ctx); } +break; +case 108: +#line 340 "bxl_gram.y" + { ctx->state.radius = yyctx->stack.l_mark[0].un.c; } +break; +case 109: +#line 341 "bxl_gram.y" + { ctx->state.arc_start = yyctx->stack.l_mark[0].un.d; } +break; +case 110: +#line 342 "bxl_gram.y" + { ctx->state.arc_delta = yyctx->stack.l_mark[0].un.d; } +break; +case 114: +#line 350 "bxl_gram.y" + { pcb_bxl_reset(ctx); ctx->state.is_text = 1; } +break; +case 115: +#line 351 "bxl_gram.y" + { pcb_bxl_add_text(ctx); pcb_bxl_reset(ctx); } +break; +case 118: +#line 360 "bxl_gram.y" + { pcb_bxl_set_text_str(ctx, yyctx->stack.l_mark[0].un.s); /* $2 is taken over */ } +break; +case 119: +#line 361 "bxl_gram.y" + { ctx->state.flipped = yyctx->stack.l_mark[0].un.i; } +break; +case 120: +#line 362 "bxl_gram.y" + { ctx->state.rot = yyctx->stack.l_mark[0].un.d; } +break; +case 128: +#line 383 "bxl_gram.y" + { free(yyctx->stack.l_mark[0].un.s); } +break; +case 129: +#line 384 "bxl_gram.y" + { free(yyctx->stack.l_mark[0].un.s); } +break; +case 131: +#line 390 "bxl_gram.y" + { ctx->in_error = 1; } +break; +case 132: +#line 390 "bxl_gram.y" + { ctx->in_error = 0; } +break; +case 133: +#line 391 "bxl_gram.y" + { ctx->in_error = 1; } +break; +case 134: +#line 391 "bxl_gram.y" + { ctx->in_error = 0; } +break; +#line 866 "bxl_gram.c" + } + yyctx->stack.s_mark -= yyctx->yym; + yyctx->state = *yyctx->stack.s_mark; + yyctx->stack.l_mark -= yyctx->yym; + yyctx->yym = pcb_bxl_lhs[yyctx->yyn]; + if (yyctx->state == 0 && yyctx->yym == 0) { +#if pcb_bxl_DEBUG + if (yyctx->debug) + printf("yyctx->debug: after reduction, shifting from state 0 to state %d\n", pcb_bxl_FINAL); +#endif + yyctx->state = pcb_bxl_FINAL; + *++yyctx->stack.s_mark = pcb_bxl_FINAL; + *++yyctx->stack.l_mark = yyctx->val; + if (yyctx->chr < 0) { + pcb_bxl_GETCHAR(2); + if (yyctx->chr < 0) + yyctx->chr = pcb_bxl_EOF; +#if pcb_bxl_DEBUG + if (yyctx->debug) { + if ((yys = pcb_bxl_name[pcb_bxl_TRANSLATE(yyctx->chr)]) == NULL) + yys = pcb_bxl_name[pcb_bxl_UNDFTOKEN]; + printf("yyctx->debug: state %d, reading %d (%s)\n", pcb_bxl_FINAL, yyctx->chr, yys); + } +#endif + } + if (yyctx->chr == pcb_bxl_EOF) + goto yyaccept; + goto yyloop; + } + if (((yyctx->yyn = pcb_bxl_gindex[yyctx->yym]) != 0) && (yyctx->yyn += yyctx->state) >= 0 && yyctx->yyn <= pcb_bxl_TABLESIZE && pcb_bxl_check[yyctx->yyn] == (pcb_bxl_int_t) yyctx->state) + yyctx->state = pcb_bxl_table[yyctx->yyn]; + else + yyctx->state = pcb_bxl_dgoto[yyctx->yym]; +#if pcb_bxl_DEBUG + if (yyctx->debug) + printf("yyctx->debug: after reduction, shifting from state %d to state %d\n", *yyctx->stack.s_mark, yyctx->state); +#endif + if (yyctx->stack.s_mark >= yyctx->stack.s_last && pcb_bxl_growstack(yyctx, &yyctx->stack) == pcb_bxl_ENOMEM) + goto yyoverflow; + *++yyctx->stack.s_mark = (pcb_bxl_int_t) yyctx->state; + *++yyctx->stack.l_mark = yyctx->val; + goto yyloop; + +yyoverflow: + pcb_bxl_error(ctx, yyctx->lval, "yacc stack overflow"); + +yyabort: + pcb_bxl_freestack(&yyctx->stack); + return pcb_bxl_RES_ABORT; + +yyaccept: + pcb_bxl_freestack(&yyctx->stack); + return pcb_bxl_RES_DONE; +} Index: tags/2.3.0/src_plugins/io_bxl/bxl_gram.h =================================================================== --- tags/2.3.0/src_plugins/io_bxl/bxl_gram.h (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/bxl_gram.h (revision 33253) @@ -0,0 +1,171 @@ +#ifndef _pcb_bxl__defines_h_ +#define _pcb_bxl__defines_h_ + +typedef short pcb_bxl_int_t; +#define pcb_bxl_chr yyctx->chr +#define pcb_bxl_val yyctx->val +#define pcb_bxl_lval yyctx->lval +#define pcb_bxl_stack yyctx->stack +#define pcb_bxl_debug yyctx->debug +#define pcb_bxl_nerrs yyctx->nerrs +#define pcb_bxl_errflag yyctx->errflag +#define pcb_bxl_state yyctx->state +#define pcb_bxl_yyn yyctx->yyn +#define pcb_bxl_yym yyctx->yym +#define pcb_bxl_jump yyctx->jump +#line 18 "bxl_gram.y" +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * BXL IO plugin - BXL grammar + * pcb-rnd Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ +#include +#include "bxl_gram.h" +#include "bxl.h" + +TODO("Can remove this once the coord unit is converted with getvalue") +#include + +#define XCRD(c) pcb_bxl_coord_x(c) +#define YCRD(c) pcb_bxl_coord_y(c) + +#line 8 "bxl_gram.y" +typedef union +{ + double d; + int i; + char *s; + rnd_coord_t c; +} pcb_bxl_tokunion_t; +#line 3 "bxl_gram.y" +typedef struct +{ + pcb_bxl_tokunion_t un; + long line, first_col, last_col; +} pcb_bxl_tokstruct_t; +typedef pcb_bxl_tokstruct_t pcb_bxl_STYPE; + + +#define T_ID 257 +#define T_INTEGER 258 +#define T_REAL_ONLY 259 +#define T_QSTR 260 +#define T_TRUE 261 +#define T_FALSE 262 +#define T_TEXTSTYLE 263 +#define T_FONTWIDTH 264 +#define T_FONTCHARWIDTH 265 +#define T_FONTHEIGHT 266 +#define T_PADSTACK 267 +#define T_ENDPADSTACK 268 +#define T_SHAPES 269 +#define T_PADSHAPE 270 +#define T_HOLEDIAM 271 +#define T_SURFACE 272 +#define T_PLATED 273 +#define T_WIDTH 274 +#define T_HEIGHT 275 +#define T_PADTYPE 276 +#define T_LAYER 277 +#define T_PATTERN 278 +#define T_ENDPATTERN 279 +#define T_DATA 280 +#define T_ENDDATA 281 +#define T_ORIGINPOINT 282 +#define T_PICKPOINT 283 +#define T_GLUEPOINT 284 +#define T_PAD 285 +#define T_NUMBER 286 +#define T_PINNAME 287 +#define T_PADSTYLE 288 +#define T_ORIGINALPADSTYLE 289 +#define T_ORIGIN 290 +#define T_ORIGINALPINNUMBER 291 +#define T_ROTATE 292 +#define T_POLY 293 +#define T_LINE 294 +#define T_ENDPOINT 295 +#define T_ATTRIBUTE 296 +#define T_ATTR 297 +#define T_JUSTIFY 298 +#define T_ARC 299 +#define T_RADIUS 300 +#define T_STARTANGLE 301 +#define T_SWEEPANGLE 302 +#define T_TEXT 303 +#define T_ISVISIBLE 304 +#define T_PROPERTY 305 +#define T_WIZARD 306 +#define T_VARNAME 307 +#define T_VARDATA 308 +#define T_TEMPLATEDATA 309 +#define T_ISFLIPPED 310 +#define T_NOPASTE 311 +#define T_SYMBOL 312 +#define T_ENDSYMBOL 313 +#define T_COMPONENT 314 +#define T_ENDCOMPONENT 315 +#define pcb_bxl_ERRCODE 256 + +#ifndef pcb_bxl_INITSTACKSIZE +#define pcb_bxl_INITSTACKSIZE 200 +#endif + +typedef struct { + unsigned stacksize; + pcb_bxl_int_t *s_base; + pcb_bxl_int_t *s_mark; + pcb_bxl_int_t *s_last; + pcb_bxl_STYPE *l_base; + pcb_bxl_STYPE *l_mark; +#if pcb_bxl_DEBUG + int debug; +#endif +} pcb_bxl_STACKDATA; + +typedef struct { + int errflag; + int chr; + pcb_bxl_STYPE val; + pcb_bxl_STYPE lval; + int nerrs; + int yym, yyn, state; + int jump; + int stack_max_depth; + int debug; + + /* variables for the parser stack */ + pcb_bxl_STACKDATA stack; +} pcb_bxl_yyctx_t; + +typedef enum { pcb_bxl_RES_NEXT, pcb_bxl_RES_DONE, pcb_bxl_RES_ABORT } pcb_bxl_res_t; + +extern int pcb_bxl_parse_init(pcb_bxl_yyctx_t *yyctx); +extern pcb_bxl_res_t pcb_bxl_parse(pcb_bxl_yyctx_t *yyctx, pcb_bxl_ctx_t *ctx, int tok, pcb_bxl_STYPE *lval); +extern void pcb_bxl_error(pcb_bxl_ctx_t *ctx, pcb_bxl_STYPE tok, const char *msg); + + +#endif /* _pcb_bxl__defines_h_ */ Index: tags/2.3.0/src_plugins/io_bxl/bxl_gram.y =================================================================== --- tags/2.3.0/src_plugins/io_bxl/bxl_gram.y (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/bxl_gram.y (revision 33253) @@ -0,0 +1,392 @@ +%prefix pcb_bxl_% + +%struct +{ + long line, first_col, last_col; +} + +%union +{ + double d; + int i; + char *s; + rnd_coord_t c; +} + + +%{ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * BXL IO plugin - BXL grammar + * pcb-rnd Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ +#include +#include "bxl_gram.h" +#include "bxl.h" + +TODO("Can remove this once the coord unit is converted with getvalue") +#include + +#define XCRD(c) pcb_bxl_coord_x(c) +#define YCRD(c) pcb_bxl_coord_y(c) + +%} + +/* Generic */ +%token T_ID T_INTEGER T_REAL_ONLY T_QSTR + +/* Keywords for footprints */ +%token T_TRUE T_FALSE T_TEXTSTYLE T_FONTWIDTH T_FONTCHARWIDTH T_FONTHEIGHT +%token T_PADSTACK T_ENDPADSTACK T_SHAPES T_PADSHAPE T_HOLEDIAM T_SURFACE +%token T_PLATED T_WIDTH T_HEIGHT T_PADTYPE T_LAYER T_PATTERN T_ENDPATTERN +%token T_DATA T_ENDDATA T_ORIGINPOINT T_PICKPOINT T_GLUEPOINT T_PAD T_NUMBER +%token T_PINNAME T_PADSTYLE T_ORIGINALPADSTYLE T_ORIGIN T_ORIGINALPINNUMBER +%token T_ROTATE T_POLY T_LINE T_ENDPOINT T_ATTRIBUTE T_ATTR T_JUSTIFY +%token T_ARC T_RADIUS T_STARTANGLE T_SWEEPANGLE T_TEXT T_ISVISIBLE T_PROPERTY +%token T_WIZARD T_VARNAME T_VARDATA T_TEMPLATEDATA T_ISFLIPPED T_NOPASTE + +/* Sections that are to be ignored (non-footprint data) */ +%token T_SYMBOL T_ENDSYMBOL T_COMPONENT T_ENDCOMPONENT + +%type T_QSTR +%type T_ID +%type T_INTEGER +%type T_REAL_ONLY +%type real +%type coord +%type boolean + +%% + +full_file: + maybe_nl + file + ; + +file: + /* empty */ + |statement nl file + ; + +statement: + text_style + | pad_stack + | pattern + | boring_section + ; + +/*** common and misc ***/ + +boolean: + T_TRUE { $$ = 1; } + | T_FALSE { $$ = 0; } + ; + +nl: + '\n' + | '\n' nl + ; + +maybe_nl: + /* empty */ + | nl + ; + +real: + T_INTEGER { $$ = $1; } + | T_REAL_ONLY { $$ = $1; } + ; + +coord: + real { $$ = RND_MIL_TO_COORD($1); } + ; + +common_attr_text: + T_JUSTIFY T_ID { pcb_bxl_set_justify(ctx, $2); free($2); } + | T_TEXTSTYLE T_QSTR { pcb_bxl_set_text_style(ctx, $2); free($2); } + | T_ISVISIBLE boolean { ctx->state.is_visible = $2; } + ; + +common_origin: + T_ORIGIN coord ',' coord { ctx->state.origin_x = XCRD($2); ctx->state.origin_y = YCRD($4); } + ; + +common_layer: + T_LAYER T_ID { pcb_bxl_set_layer(ctx, $2); free($2); } + ; + +common_width: + T_WIDTH coord { ctx->state.width = $2; } + ; + +/*** TextStyle ***/ + +text_style: + T_TEXTSTYLE T_QSTR { pcb_bxl_text_style_begin(ctx, $2); /* $2 is taken over */ } + text_style_attrs { pcb_bxl_text_style_end(ctx); } + ; + +text_style_attrs: + /* empty */ + | '(' text_style_attr ')' text_style_attrs + ; + +text_style_attr: + T_FONTWIDTH real { ctx->state.text_style->width = $2; } + | T_FONTCHARWIDTH real { ctx->state.text_style->char_width = $2; } + | T_FONTHEIGHT real { ctx->state.text_style->height = $2; } + ; + + +/*** PadStack ***/ + +pad_stack: + T_PADSTACK T_QSTR { pcb_bxl_reset(ctx); pcb_bxl_padstack_begin(ctx, $2); /* $2 is taken over */ } + pstk_attrs nl + T_SHAPES ':' T_INTEGER nl { ctx->state.num_shapes = $8; } + pad_shapes + T_ENDPADSTACK { pcb_bxl_padstack_end(ctx); } + ; + +pstk_attrs: + /* empty */ + | '(' pstk_attr ')' pstk_attrs + ; + +pstk_attr: + T_HOLEDIAM coord { ctx->state.hole = $2; } + | T_SURFACE boolean { ctx->state.surface = $2; } + | T_PLATED boolean { ctx->state.plated = $2; } + | T_NOPASTE boolean { ctx->state.nopaste = $2; } + ; + +pad_shapes: + /* empty */ + | pad_shape pad_shapes + ; + +pad_shape: + T_PADSHAPE T_QSTR { pcb_bxl_padstack_begin_shape(ctx, $2); free($2); } + padshape_attrs nl { pcb_bxl_padstack_end_shape(ctx); } + ; + +padshape_attrs: + /* empty */ + | '(' padshape_attr ')' padshape_attrs + ; + +padshape_attr: + T_HEIGHT coord { ctx->state.height = $2; } + | T_PADTYPE T_INTEGER { ctx->state.pad_type = $2; } + | common_layer + | common_width + ; + +/*** Pattern ***/ +pattern: + T_PATTERN T_QSTR nl { pcb_bxl_reset_pattern(ctx); pcb_bxl_pattern_begin(ctx, $2); free($2); } + pattern_chldrn + T_ENDPATTERN { pcb_bxl_pattern_end(ctx); pcb_bxl_reset_pattern(ctx); } + ; + +pattern_chldrn: + /* empty */ + | pattern_chld nl pattern_chldrn + ; + +pattern_chld: + data + | T_ORIGINPOINT '(' coord ',' coord ')' { ctx->pat_state.origin_x = XCRD($3); ctx->pat_state.origin_y = YCRD($5); } + | T_PICKPOINT '(' coord ',' coord ')' { ctx->pat_state.pick_x = XCRD($3); ctx->pat_state.pick_y = YCRD($5); } + | T_GLUEPOINT '(' coord ',' coord ')' { ctx->pat_state.glue_x = XCRD($3); ctx->pat_state.glue_y = YCRD($5); } + ; + +data: + T_DATA ':' T_INTEGER nl + data_chldrn + T_ENDDATA + ; + +data_chldrn: + /* empty */ + | data_chld nl data_chldrn + ; + +data_chld: + pad + | poly + | line + | attribute + | templatedata + | arc + | text + | wizard + + ; + +/*** Pad ***/ +pad: + T_PAD { pcb_bxl_pad_begin(ctx); } + pad_attrs { pcb_bxl_pad_end(ctx); } + ; + +pad_attrs: + /* empty */ + | '(' pad_attr ')' pad_attrs + ; + +pad_attr: + T_NUMBER T_INTEGER { ctx->state.pin_number = $2; } + | T_PINNAME T_QSTR { ctx->state.pin_name = $2; /* takes over $2 */ } + | T_PADSTYLE T_QSTR { pcb_bxl_pad_set_style(ctx, $2); free($2); } + | T_ORIGINALPADSTYLE T_QSTR { /* what's this?! */ free($2); } + | T_ORIGINALPINNUMBER T_INTEGER { /* what's this?! */ } + | T_ROTATE real { ctx->state.rot = $2; } + | common_origin + ; + +/*** Poly ***/ +poly: + T_POLY { pcb_bxl_poly_begin(ctx); } + poly_attrs { pcb_bxl_poly_end(ctx); } + ; + +poly_attrs: + /* empty */ + | '(' poly_attr ')' poly_attrs + ; + +poly_attr: + + T_PROPERTY T_QSTR { pcb_bxl_add_property(ctx, (pcb_any_obj_t *)ctx->state.poly, $2); free($2); } + | coord ',' coord { pcb_bxl_poly_add_vertex(ctx, XCRD($1), YCRD($3)); } + | common_origin + | common_layer + | common_width + ; + +/*** Line ***/ +line: + T_LINE { pcb_bxl_reset(ctx); } + line_attrs { pcb_bxl_add_line(ctx); pcb_bxl_reset(ctx); } + ; + +line_attrs: + /* empty */ + | '(' line_attr ')' line_attrs + ; + +line_attr: + T_ENDPOINT coord ',' coord { ctx->state.endp_x = XCRD($2); ctx->state.endp_y = YCRD($4); } + | common_origin + | common_layer + | common_width + ; + +/*** Attribute ***/ +attribute: + T_ATTRIBUTE { pcb_bxl_reset(ctx); ctx->state.is_text = 0; } + attribute_attrs { pcb_bxl_add_text(ctx); pcb_bxl_reset(ctx); } + ; + +attribute_attrs: + /* empty */ + | '(' attribute_attr ')' attribute_attrs + ; + +attribute_attr: + T_ATTR T_QSTR T_QSTR { pcb_bxl_set_attr_val(ctx, $2, $3); /* $2 and $3 are taken over */ } + | common_attr_text + | common_origin + | common_layer + ; + + +/*** Arc ***/ +arc: + T_ARC { pcb_bxl_reset(ctx); } + arc_attrs { pcb_bxl_add_arc(ctx); pcb_bxl_reset(ctx); } + ; + +arc_attrs: + /* empty */ + | '(' arc_attr ')' arc_attrs + ; + +arc_attr: + T_RADIUS coord { ctx->state.radius = $2; } + | T_STARTANGLE real { ctx->state.arc_start = $2; } + | T_SWEEPANGLE real { ctx->state.arc_delta = $2; } + | common_origin + | common_layer + | common_width + ; + +/*** Text ***/ +text: + T_TEXT { pcb_bxl_reset(ctx); ctx->state.is_text = 1; } + text_attrs { pcb_bxl_add_text(ctx); pcb_bxl_reset(ctx); } + ; + +text_attrs: + /* empty */ + | '(' text_attr ')' text_attrs + ; + +text_attr: + T_TEXT T_QSTR { pcb_bxl_set_text_str(ctx, $2); /* $2 is taken over */ } + | T_ISFLIPPED boolean { ctx->state.flipped = $2; } + | T_ROTATE real { ctx->state.rot = $2; } + | common_attr_text + | common_origin + | common_layer + ; + +/*** Wizard & template ***/ +wizard: + T_WIZARD wizard_attrs + ; + +templatedata: + T_TEMPLATEDATA wizard_attrs + ; + +wizard_attrs: + /* empty */ + | '(' wizard_attr ')' wizard_attrs + ; + +wizard_attr: + T_VARNAME T_QSTR { free($2); } + | T_VARDATA T_QSTR { free($2); } + | common_origin + ; + +/*** Sections not interesting for pcb-rnd ***/ +boring_section: + { ctx->in_error = 1; } T_SYMBOL error T_ENDSYMBOL { ctx->in_error = 0; } + | { ctx->in_error = 1; } T_COMPONENT error T_ENDCOMPONENT { ctx->in_error = 0; } + ; Index: tags/2.3.0/src_plugins/io_bxl/bxl_lex.c =================================================================== --- tags/2.3.0/src_plugins/io_bxl/bxl_lex.c (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/bxl_lex.c (revision 33253) @@ -0,0 +1,887 @@ +static const unsigned char pcb_bxl_nfa_0[] = {4,3,0,0,0,0,0,32,255,131,0,0,0,40,0,0,0,0,11,3,0,0,0,0,0,32,255,131,0,0,0,40,0,0,0,0,0,0,0}; +static const unsigned char pcb_bxl_bittab_0[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +static const unsigned char pcb_bxl_chrtyp_0[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,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,0,0,0,0,1,0,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,0,0,0,0,0}; +static const unsigned char pcb_bxl_nfa_1[] = {4,11,3,0,0,0,0,0,32,255,131,0,0,0,40,0,0,0,0,0,3,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,11,3,0,0,0,0,0,40,255,3,32,0,0,0,32,0,0,0,0,0,0,0}; +static const unsigned char pcb_bxl_nfa_2[] = {4,3,0,0,0,0,0,0,0,0,254,255,255,7,254,255,255,7,11,3,0,0,0,0,0,32,255,3,254,255,255,135,254,255,255,7,0,0,0}; +static const unsigned char pcb_bxl_nfa_3[] = {4,1,34,6,1,11,3,255,255,255,255,251,255,255,255,255,255,255,255,255,255,255,255,0,7,1,1,34,0,0}; +static const unsigned char pcb_bxl_nfa_4[] = {4,3,0,4,0,0,0,19,0,4,0,0,0,0,0,0,0,0,0}; +static const unsigned char pcb_bxl_nfa_5[] = {4,3,0,34,0,0,1,0,0,0,0,0,0,0,0,0,0,0,11,3,0,34,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +/* strtree.h BEGIN { */ +#ifndef UREGLEX_STRTREE_H +#define UREGLEX_STRTREE_H +typedef enum {ULX_REQ = 1, ULX_BRA, ULX_FIN, ULX_BAD} ureglex_stree_op_t; +typedef struct ureglex_strtree_s { int *code, *ip; } ureglex_strtree_t; +int ureglex_strtree_exec(ureglex_strtree_t *ctx, int chr); +#define UREGLEX_STRTREE_MORE -5 +#endif +/* strtree.h END } */ + +/* strtree_exec.c BEGIN { */ +int ureglex_strtree_exec(ureglex_strtree_t *ctx, int chr) +{ + int expected, dst; + for(;;) { + switch(*ctx->ip) { + case ULX_REQ: + expected = ctx->ip[1]; + ctx->ip += 2; + if (chr == expected) + return UREGLEX_STRTREE_MORE; + return -1; + case ULX_BRA: + expected = ctx->ip[1]; + dst = ctx->ip[2]; + ctx->ip += 3; + if (chr == expected) { + ctx->ip = ctx->code + dst; + return UREGLEX_STRTREE_MORE; + } + break; + case ULX_FIN: return ctx->ip[1]; + case ULX_BAD: return -2; + } + } + return -1; +} +/* strtree_exec.c END } */ + +/* exec.h BEGIN { */ +#ifndef UREGLEX_EXEC_COMMON_H +#define UREGLEX_EXEC_COMMON_H +#define MAXTAG 10 +typedef struct ureglex_precomp_s { + const unsigned char *nfa; + const unsigned char *bittab; + const unsigned char *chrtyp; + double weight; +} ureglex_precomp_t; +typedef struct ureglex_s { + ureglex_precomp_t *pc; + const char *bol; + const char *bopat[MAXTAG]; + const char *eopat[MAXTAG]; + int score; + const char *endp; + union { const void *ptr; int i; } pmstk[30]; + int pmsp; + const unsigned char *pm_ap; + const char *pm_lp; + int pm_c; + const char *pm_bp; + const char *pm_ep; + const char *pm_are; + const char *ex_lp; + unsigned char ex_c; + int ex_loop, pm_loop, pm_loop2, pm_loop2_later; + int exec_state; +} ureglex_t; +typedef enum { + UREGLEX_MORE = -1, + UREGLEX_TOO_LONG = -2, + UREGLEX_NO_MATCH = -3, + UREGLEX_NOP = -4 +} ureglex_error_t; +extern const unsigned char ureglex_nfa_str[]; +#define ULX_BUF ctx->buff +#define ULX_TAGP(n) (ctx->state[ruleid].bopat[(n)]) +#define ULX_TAGL(n) (ctx->state[ruleid].eopat[(n)] - ctx->state[ruleid].bopat[(n)]) +#define ULX_IGNORE goto ureglex_ignore; +#endif +/* exec.h END } */ + +/* common.h, exec.c BEGIN { */ +#define MAXCHR 128 +#define CHRBIT 8 +#define BITBLK MAXCHR/CHRBIT +#define BLKIND 0170 +#define BITIND 07 +void ureglex_exec_init(ureglex_t *re, const char *str, int buff_used); +extern int ureglex_exec(ureglex_t *re); +extern int ureglex_tag(ureglex_t *re, int tagid, char **begin, char **end); +enum ureglex_opcode_e { + NOP = 0, + END = 0, + CHR = 1, + ANY = 2, + CCL = 3, + BOL = 4, + EOL = 5, + BOT = 6, + EOT = 7, + BOW = 8, + EOW = 9, + REF = 10, + CLO = 11 +}; +#include +#include +#define re_tolower(c) c +#define iswordc(r,x) r->pc->chrtyp[inascii(x)] +#define end(s) (*(s) == '\0') +static unsigned char ureglex_bitarr[] = {1,2,4,8,16,32,64,128}; +#define inascii(x) (0177&(x)) +#define isinset(x,y) ((x)[((y)&BLKIND)>>3] & ureglex_bitarr[(y)&BITIND]) +const unsigned char ureglex_nfa_str[] = {0}; +#define ANYSKIP 2 +#define CHRSKIP 3 +#define CCLSKIP 18 +static const char MORE[] = "more!"; +#define want_more(loopid) \ +do { \ + if (r->pm_lp < r->endp) \ + goto loop ## loopid; \ + r->pm_loop = loopid; \ + return MORE; \ +} while(0) +#define PUSH(r,ty,val) if (r->pmsp >= sizeof(r->pmstk) / sizeof(r->pmstk[0])) return 0; r->pmstk[r->pmsp++].ty = val +#define POP(r,ty,dst) dst = r->pmstk[--r->pmsp].ty +static const char *pmatch(ureglex_t *r) +{ + register int op, c, n; + register const char *e = NULL; + switch(r->pm_loop) { + case 1: r->pm_loop = 0; goto loop1; + case 2: r->pm_loop = 0; goto loop2; + case 3: r->pm_loop = 0; goto loop3; + case 4: r->pm_loop = 0; goto loop4; + case 6: r->pm_loop = 0; goto loop6; + case 7: r->pm_loop = 0; goto loop7; + case 8: r->pm_loop = 0; goto loop8; + } + switch(r->pm_loop2) { + case 1: r->pm_loop2 = 0; goto loop2_1; + } + while ((op = *r->pm_ap++) != END) + switch(op) { + case CHR: + want_more(6); + loop6:; + if (re_tolower(*r->pm_lp++) != *r->pm_ap++) + return 0; + r->score += 100; + break; + case ANY: + want_more(7); + loop7:; + if (end(r->pm_lp++)) + return 0; + r->score++; + break; + case CCL: + if (end(r->pm_lp)) + return 0; + want_more(8); + loop8:; + c = re_tolower(*r->pm_lp++); + if (!isinset(r->pm_ap,c)) + return 0; + r->pm_ap += BITBLK; + r->score += 2; + break; + case BOL: + if (r->pm_lp != r->bol) + return 0; + r->score += 10; + break; + case EOL: + if (!end(r->pm_lp)) + return 0; + r->score += 10; + break; + case BOT: + r->bopat[*r->pm_ap++] = r->pm_lp; + break; + case EOT: + r->eopat[*r->pm_ap++] = r->pm_lp; + break; + case BOW: + if ((r->pm_lp!=r->bol && iswordc(r, r->pm_lp[-1])) || !iswordc(r, *r->pm_lp)) + return 0; + r->score += 5; + break; + case EOW: + if (r->pm_lp==r->bol || !iswordc(r, r->pm_lp[-1]) || (!end(r->pm_lp) && iswordc(r, *r->pm_lp))) + return 0; + r->score += 5; + break; + case REF: + n = *r->pm_ap++; + r->pm_bp = r->bopat[n]; + r->pm_ep = r->eopat[n]; + while (r->pm_bp < r->pm_ep) { + want_more(1); + loop1:; + if (*r->pm_bp++ != *r->pm_lp++) + return 0; + r->score += 2; + } + break; + case CLO: + r->pm_are = r->pm_lp; + switch(*r->pm_ap) { + case ANY: + do { + want_more(2); + loop2:; + } while(!end(r->pm_lp++)); + n = ANYSKIP; + r->score++; + break; + case CHR: + r->pm_c = *(r->pm_ap+1); + do { + want_more(3); + loop3:; + } while (!end(r->pm_lp) && r->pm_c == re_tolower(*r->pm_lp) && (r->pm_lp++)); + n = CHRSKIP; + r->score += 100; + break; + case CCL: + do { + want_more(4); + loop4:; + } while ((c = re_tolower(*r->pm_lp)) && isinset(r->pm_ap+1,c) && (r->pm_lp++)); + n = CCLSKIP; + r->score += 2; + break; + default: + return 0; + } + r->pm_ap += n; + while (r->pm_lp >= r->pm_are) { + PUSH(r, ptr, r->pm_ap); + PUSH(r, ptr, r->pm_lp); + PUSH(r, i, r->pm_loop); + r->pm_loop2_later = 1; + e = pmatch(r); + if (e == MORE) + return MORE; + loop2_1:; + POP(r, i, r->pm_loop); + POP(r, ptr, r->pm_lp); + POP(r, ptr, r->pm_ap); + if (e) + return e; + --r->pm_lp; + } + return 0; + default: + return 0; + } + r->pm_loop2 = r->pm_loop2_later; + return r->pm_lp; +} +void ureglex_exec_init(ureglex_t *r, const char *lp, int buff_used) +{ + r->bol = lp; + r->score = 1; + memset(r->bopat, 0, (char *)&r->eopat[MAXTAG] - (char *)&r->bopat[0]); + r->pmsp = 0; + r->ex_lp = lp; + r->endp = lp + buff_used; + r->ex_loop = r->pm_loop = r->pm_loop2 = 0; + r->exec_state = -1; +} +#undef want_more +#define want_more(loopid) \ +do { \ + if (r->ex_lp < r->endp) \ + goto loop ## loopid; \ + r->ex_loop = loopid; \ + return -1; \ +} while(0) +#define want_more2(loopid) \ +do { \ + if (r->pm_lp < r->endp) \ + goto loop ## loopid; \ + r->ex_loop = loopid; \ + return -1; \ +} while(0) +int ureglex_exec(ureglex_t *r) +{ + register const char *ep = 0; + const unsigned char *ap = r->pc->nfa; + r->endp++; + switch(r->ex_loop) { + case 1: r->ex_loop = 0; goto loop1; + case 2: r->ex_loop = 0; goto loop2; + case 3: r->ex_loop = 0; goto loop3; + case 4: r->ex_loop = 0; goto loop4; + } + switch(*ap) { + case BOL: + r->pm_ap = ap; + r->pm_lp = r->ex_lp; + loop1:; + ep = pmatch(r); + if (ep == MORE) + want_more2(1); + break; + case CHR: + r->ex_c = *(ap+1); + while (!end(r->ex_lp) && re_tolower(*r->ex_lp) != r->ex_c) { + r->ex_lp++; + want_more(2); + loop2:; + } + if (end(r->ex_lp)) + return 0; + default: + for(;;) { + r->pm_ap = ap; + r->pm_lp = r->ex_lp; + loop3:; + ep = pmatch(r); + if (ep == MORE) { + want_more2(3); + } + if (ep != NULL) + break; + r->ex_lp++; + want_more(4); + loop4:; + if (end(r->ex_lp)) + break; + } + break; + case END: + return 0; + } + if (!ep) + return 0; + r->bopat[0] = r->ex_lp; + r->eopat[0] = ep; + return r->score; +} +#define setout(dest,val) \ + if ((dest) != NULL) \ + *(dest) = val; +int ureglex_tag(ureglex_t *re, int tagid, char **begin, char **end) +{ + if ((tagid < 0) || (tagid > MAXTAG)) { + setout(begin, NULL); + setout(end, NULL); + return -1; + } + setout(begin, (char *)re->bopat[tagid]); + setout(end, (char *)re->eopat[tagid]); + return 0; +} +/* common.h, exec.c END } */ + +int pcb_bxl_strings[] = {2,51,266,2,65,169,2,67,75,2,68,243,2,69,58,2,70,259,2,71,224,2,72,252,2,73,153,2,74,176,2,76,191,2,78,217,2,79,198,2,80,137,2,82,162,2,83,94,2,84,121,2,86,110,2,87,128,4,1,110,1,100,2,67,305,2,68,344,2,80,337,2,83,324,4,1,111,1,109,1,112,1,111,1,110,1,101,1,110,1,116,3,61,4,2,104,832,2,116,800,2,117,819,2,119,781,2,121,770,4,1,97,1,114,2,68,897,2,78,906,4,2,101,843,2,114,850,4,1,105,2,100,924,2,122,915,4,2,97,631,2,105,638,2,108,645,2,111,624,2,114,609,4,1,115,2,70,485,2,86 +,500,4,2,97,748,2,111,759,4,2,114,279,2,116,284,4,1,117,1,115,1,116,1,105,1,102,1,121,3,46,4,2,97,522,2,105,515,4,1,114,1,105,1,103,1,105,1,110,2,80,566,2,97,555,3,37,4,2,111,542,2,117,531,4,1,108,1,117,1,101,1,80,1,111,1,105,1,110,1,116,3,31,4,1,97,1,116,1,97,3,27,4,2,101,459,2,111,470,4,2,97,407,2,111,393,4,1,68,1,95,1,68,1,88,1,70,3,6,4,1,99,3,47,4,1,116,1,114,2,105,294,3,45,4,1,98,1,117,1,116,1,101,3,44,4,1,111,1,109,1,112,1,111,1,110,1,101,1,110,1,116,3,62,4,1,121,1,109,1,98,1,111,1,108,3,60 +,4,2,97,362,2,111,353,4,1,97,1,116,1,97,3,28,4,1,105,1,110,1,116,3,42,4,2,100,380,2,116,369,4,1,116,1,101,1,114,1,110,3,26,4,1,83,1,116,1,97,1,99,1,107,3,14,4,1,110,1,116,2,67,429,2,72,416,2,87,448,4,1,108,1,115,1,101,3,8,4,1,101,1,105,1,103,1,104,1,116,3,12,4,1,104,1,97,1,114,1,87,1,105,1,100,1,116,1,104,3,11,4,1,105,1,100,1,116,1,104,3,10,4,1,105,1,103,1,104,1,116,3,22,4,1,108,1,101,1,68,1,105,1,97,1,109,3,17,4,1,108,1,105,1,112,1,112,1,101,1,100,3,53,4,1,105,1,115,1,105,1,98,1,108,1,101,3,52,4 +,1,110,1,101,3,41,4,1,121,1,101,1,114,3,24,4,1,109,1,98,1,101,1,114,3,33,4,1,80,1,97,1,115,1,116,1,101,3,20,4,1,108,1,80,2,97,594,2,105,577,4,1,111,1,105,1,110,1,116,3,29,4,1,110,1,78,1,117,1,109,1,98,1,101,1,114,3,38,4,1,100,1,83,1,116,1,121,1,108,1,101,3,36,4,1,111,1,112,1,101,1,114,1,116,1,121,3,54,4,1,108,1,121,3,40,4,2,100,656,2,116,665,4,2,99,733,2,110,722,4,1,97,1,116,1,101,1,100,3,19,4,2,83,676,2,84,683,3,32,4,1,116,1,101,1,114,1,110,3,25,4,2,104,699,2,116,692,4,1,121,1,112,1,101,3,23,4,2 +,97,715,2,121,708,4,1,97,1,112,1,101,3,16,4,1,108,1,101,3,35,4,1,99,1,107,3,13,4,1,78,1,97,1,109,1,101,3,34,4,1,107,1,80,1,111,1,105,1,110,1,116,3,30,4,1,100,1,105,1,117,1,115,3,48,4,1,116,1,97,1,116,1,101,3,39,4,1,109,1,98,1,111,1,108,3,59,4,1,101,1,101,1,112,1,65,1,110,1,103,1,108,1,101,3,50,4,1,97,1,114,1,116,1,65,1,110,1,103,1,108,1,101,3,49,4,1,114,1,102,1,97,1,99,1,101,3,18,4,1,97,1,112,1,101,1,115,3,15,4,2,109,857,2,120,878,4,1,117,1,101,3,7,4,1,112,1,108,1,97,1,116,1,101,1,100,1,97,1,116,1 +,97,3,56,4,1,116,2,83,886,3,51,4,1,116,1,121,1,108,1,101,3,9,4,1,97,1,116,1,97,3,58,4,1,97,1,109,1,101,3,57,4,1,97,1,114,1,100,3,55,4,1,116,1,104,3,21,4}; +ureglex_precomp_t pcb_bxl_rules[] = { + {pcb_bxl_nfa_0, pcb_bxl_bittab_0, pcb_bxl_chrtyp_0, 1.000000}, + {pcb_bxl_nfa_1, pcb_bxl_bittab_0, pcb_bxl_chrtyp_0, 1.000000}, + {pcb_bxl_nfa_2, pcb_bxl_bittab_0, pcb_bxl_chrtyp_0, 1.000000}, + {pcb_bxl_nfa_3, pcb_bxl_bittab_0, pcb_bxl_chrtyp_0, 1.000000}, + {pcb_bxl_nfa_4, pcb_bxl_bittab_0, pcb_bxl_chrtyp_0, 1.000000}, + {pcb_bxl_nfa_5, pcb_bxl_bittab_0, pcb_bxl_chrtyp_0, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {ureglex_nfa_str, NULL, NULL, 1.000000}, + {NULL, NULL, NULL, 0.0} +}; +#define pcb_bxl_num_rules 63 +typedef struct pcb_bxl_ureglex_s { + ureglex_precomp_t *rules; + char buff[256]; + int num_rules, buff_used, step_back_to, buff_save_term, by_len; + long loc_offs[2], loc_line[2], loc_col[2]; + ureglex_t state[pcb_bxl_num_rules]; + const char *sp; + int strtree_state, strtree_len, strtree_score; + ureglex_strtree_t strtree; +} pcb_bxl_ureglex_t; + +/* TOP CODE BEGIN { */ +#line 5 "bxl_lex.ul" + /* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * BXL IO plugin - bxl lexer + * pcb-rnd Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + #include + #include + #include "bxl_gram.h" + #define lval ((pcb_bxl_STYPE *)(user_ctx)) +/* TOP CODE END } */ + +/* exec_spec.h BEGIN { */ +void pcb_bxl_lex_reset(pcb_bxl_ureglex_t *ctx); +void pcb_bxl_lex_init(pcb_bxl_ureglex_t *ctx, ureglex_precomp_t *rules); +int pcb_bxl_lex_char(pcb_bxl_ureglex_t *ctx, void *user_ctx, int chr); +/* exec_spec.h END } */ + +static int pcb_bxl_user_code(pcb_bxl_ureglex_t *ctx, void * user_ctx, int ruleid) { + ureglex_t *rule = &ctx->state[ruleid]; + (void)rule; + switch(ruleid) { + case 0:{ +#line 41 "bxl_lex.ul" + lval->un.i = atoi(ULX_BUF); + return T_INTEGER; + + } + return UREGLEX_NOP; + case 1:{ +#line 47 "bxl_lex.ul" + lval->un.d = strtod(ULX_BUF, NULL); + return T_REAL_ONLY; + + } + return UREGLEX_NOP; + case 2:{ +#line 53 "bxl_lex.ul" + lval->un.s = rnd_strdup(ULX_BUF); + return T_ID; + + } + return UREGLEX_NOP; + case 3:{ +#line 59 "bxl_lex.ul" + lval->un.s = rnd_strndup(ULX_TAGP(1), ULX_TAGL(1)); + return T_QSTR; + + } + return UREGLEX_NOP; + case 4:{ +#line 65 "bxl_lex.ul" + return *ULX_BUF; + + } + return UREGLEX_NOP; + case 5:{ +#line 70 "bxl_lex.ul" + ULX_IGNORE; + + } + return UREGLEX_NOP; + case 6:{ + lval->un.s = rnd_strdup(ULX_BUF); return T_ID; + } + return UREGLEX_NOP; + case 7:{ + return T_TRUE; + } + return UREGLEX_NOP; + case 8:{ + return T_FALSE; + } + return UREGLEX_NOP; + case 9:{ + return T_TEXTSTYLE; + } + return UREGLEX_NOP; + case 10:{ + return T_FONTWIDTH; + } + return UREGLEX_NOP; + case 11:{ + return T_FONTCHARWIDTH; + } + return UREGLEX_NOP; + case 12:{ + return T_FONTHEIGHT; + } + return UREGLEX_NOP; + case 13:{ + return T_PADSTACK; + } + return UREGLEX_NOP; + case 14:{ + return T_ENDPADSTACK; + } + return UREGLEX_NOP; + case 15:{ + return T_SHAPES; + } + return UREGLEX_NOP; + case 16:{ + return T_PADSHAPE; + } + return UREGLEX_NOP; + case 17:{ + return T_HOLEDIAM; + } + return UREGLEX_NOP; + case 18:{ + return T_SURFACE; + } + return UREGLEX_NOP; + case 19:{ + return T_PLATED; + } + return UREGLEX_NOP; + case 20:{ + return T_NOPASTE; + } + return UREGLEX_NOP; + case 21:{ + return T_WIDTH; + } + return UREGLEX_NOP; + case 22:{ + return T_HEIGHT; + } + return UREGLEX_NOP; + case 23:{ + return T_PADTYPE; + } + return UREGLEX_NOP; + case 24:{ + return T_LAYER; + } + return UREGLEX_NOP; + case 25:{ + return T_PATTERN; + } + return UREGLEX_NOP; + case 26:{ + return T_ENDPATTERN; + } + return UREGLEX_NOP; + case 27:{ + return T_DATA; + } + return UREGLEX_NOP; + case 28:{ + return T_ENDDATA; + } + return UREGLEX_NOP; + case 29:{ + return T_ORIGINPOINT; + } + return UREGLEX_NOP; + case 30:{ + return T_PICKPOINT; + } + return UREGLEX_NOP; + case 31:{ + return T_GLUEPOINT; + } + return UREGLEX_NOP; + case 32:{ + return T_PAD; + } + return UREGLEX_NOP; + case 33:{ + return T_NUMBER; + } + return UREGLEX_NOP; + case 34:{ + return T_PINNAME; + } + return UREGLEX_NOP; + case 35:{ + return T_PADSTYLE; + } + return UREGLEX_NOP; + case 36:{ + return T_ORIGINALPADSTYLE; + } + return UREGLEX_NOP; + case 37:{ + return T_ORIGIN; + } + return UREGLEX_NOP; + case 38:{ +return T_ORIGINALPINNUMBER; + } + return UREGLEX_NOP; + case 39:{ + return T_ROTATE; + } + return UREGLEX_NOP; + case 40:{ + return T_POLY; + } + return UREGLEX_NOP; + case 41:{ + return T_LINE; + } + return UREGLEX_NOP; + case 42:{ + return T_ENDPOINT; + } + return UREGLEX_NOP; + case 43:{ + return T_WIDTH; + } + return UREGLEX_NOP; + case 44:{ + return T_ATTRIBUTE; + } + return UREGLEX_NOP; + case 45:{ + return T_ATTR; + } + return UREGLEX_NOP; + case 46:{ + return T_JUSTIFY; + } + return UREGLEX_NOP; + case 47:{ + return T_ARC; + } + return UREGLEX_NOP; + case 48:{ + return T_RADIUS; + } + return UREGLEX_NOP; + case 49:{ + return T_STARTANGLE; + } + return UREGLEX_NOP; + case 50:{ + return T_SWEEPANGLE; + } + return UREGLEX_NOP; + case 51:{ + return T_TEXT; + } + return UREGLEX_NOP; + case 52:{ + return T_ISVISIBLE; + } + return UREGLEX_NOP; + case 53:{ + return T_ISFLIPPED; + } + return UREGLEX_NOP; + case 54:{ + return T_PROPERTY; + } + return UREGLEX_NOP; + case 55:{ + return T_WIZARD; + } + return UREGLEX_NOP; + case 56:{ + return T_TEMPLATEDATA; + } + return UREGLEX_NOP; + case 57:{ + return T_VARNAME; + } + return UREGLEX_NOP; + case 58:{ + return T_VARDATA; + } + return UREGLEX_NOP; + case 59:{ + return T_SYMBOL; + } + return UREGLEX_NOP; + case 60:{ + return T_ENDSYMBOL; + } + return UREGLEX_NOP; + case 61:{ + return T_COMPONENT; + } + return UREGLEX_NOP; + case 62:{ + return T_ENDCOMPONENT; + } + return UREGLEX_NOP; + } + return UREGLEX_NO_MATCH; + goto ureglex_ignore; + ureglex_ignore:; + pcb_bxl_lex_reset(ctx); + return UREGLEX_MORE; +} + +/* exec_spec.c BEGIN { */ +void pcb_bxl_lex_reset(pcb_bxl_ureglex_t *ctx) +{ + int n = 0; + if ((ctx->step_back_to >= 0) && (ctx->step_back_to < ctx->buff_used)) { + if (ctx->buff_save_term > 0) + ctx->buff[ctx->step_back_to] = ctx->buff_save_term; + n = ctx->buff_used - ctx->step_back_to; + memmove(ctx->buff, ctx->buff + ctx->step_back_to, n+1); + } + ctx->buff_used = n; + for(n = 0; n < ctx->num_rules; n++) + ureglex_exec_init(&ctx->state[n], ctx->buff, ctx->buff_used); + ctx->buff_save_term = ctx->step_back_to = -1; + ctx->loc_offs[0] = ctx->loc_offs[1]; + ctx->loc_line[0] = ctx->loc_line[1]; + ctx->loc_col[0] = ctx->loc_col[1]; +#if 1 + ctx->strtree_state = UREGLEX_STRTREE_MORE; + ctx->strtree_len = ctx->strtree_score = 0; + ctx->strtree.ip = ctx->strtree.code = pcb_bxl_strings; + ctx->sp = ctx->buff; +#endif +} +void pcb_bxl_lex_init(pcb_bxl_ureglex_t *ctx, ureglex_precomp_t *rules) +{ + ureglex_precomp_t *p; + ctx->rules = rules; + ctx->num_rules = 0; + ctx->buff_save_term = ctx->step_back_to = -1; + for(p = pcb_bxl_rules; p->nfa != NULL; p++) + ctx->state[ctx->num_rules++].pc = p; + ctx->by_len = (p->weight > 0.0); + ctx->loc_offs[1] = ctx->loc_line[1] = ctx->loc_col[1] = 1; + pcb_bxl_lex_reset(ctx); + ctx->loc_offs[1] = ctx->loc_col[1] = 0; +} +int pcb_bxl_lex_char(pcb_bxl_ureglex_t *ctx, void *user_ctx, int chr) +{ + ureglex_t *best = NULL; + int n, working = 0; + if (ctx->buff_used >= (sizeof(ctx->buff)-1)) + return UREGLEX_TOO_LONG; + ctx->buff[ctx->buff_used++] = chr; + ctx->buff[ctx->buff_used] = '\0'; + ctx->loc_offs[1]++; + if (chr == '\n') { + ctx->loc_line[1]++; + ctx->loc_col[1] = 0; + } + else + ctx->loc_col[1]++; +#if 1 + while((ctx->strtree_state == UREGLEX_STRTREE_MORE) && (ctx->sp < (&ctx->buff[ctx->buff_used]))) { + ctx->strtree_state = ureglex_strtree_exec(&ctx->strtree, *ctx->sp++); + if (ctx->strtree_state == UREGLEX_STRTREE_MORE) + working++; + if (ctx->strtree_state > 0) { + ureglex_t *s = &ctx->state[ctx->strtree_state]; + ctx->strtree_len = ctx->buff_used; + s->exec_state = s->score = ctx->strtree_score = (int)((double)(ctx->strtree_len-1) * s->pc->weight * 100); + s->bopat[0] = ctx->buff; + s->eopat[0] = ctx->buff + ctx->strtree_len - 1; + } + } +#endif + for(n = 0; n < ctx->num_rules; n++) { + ureglex_t *s = &ctx->state[n]; + if ((s->pc->bittab != NULL) && (s->exec_state < 0)) { + s->exec_state = ureglex_exec(s); + if (s->exec_state < 0) + working++; + else if ((s->exec_state > 0) && (s->pc->weight != 1.0)) + s->exec_state = s->score = (int)((double)s->exec_state * s->pc->weight); + } + } + if (working != 0) + return UREGLEX_MORE; + for(n = 0; n < ctx->num_rules; n++) { + ureglex_t *s = &ctx->state[n]; + if ((s->pc->bittab != NULL) && (s->exec_state > 0)) { + if (best == NULL) + best = s; + else if ((!ctx->by_len) && (s->score > best->score)) + best = s; + else if ((ctx->by_len) && (s->eopat[0] - s->eopat[1] > best->eopat[0] - best->eopat[1])) + best = s; + } + } +#if 1 + if (ctx->strtree_state > 0) { + if (best == NULL) + best = &ctx->state[ctx->strtree_state]; + else if ((!ctx->by_len) && (ctx->strtree_score > best->score)) + best = &ctx->state[ctx->strtree_state]; + else if ((ctx->by_len) && (ctx->strtree_len > best->eopat[0] - best->eopat[1])) + best = &ctx->state[ctx->strtree_state]; + } +#endif + if (best == NULL) { + ctx->step_back_to = ctx->buff_used-1; + return UREGLEX_NO_MATCH; + } + ctx->step_back_to = best->eopat[0] - ctx->buff; + ctx->buff_save_term = ctx->buff[ctx->step_back_to]; + ctx->buff[ctx->step_back_to] = '\0'; + return pcb_bxl_user_code(ctx, user_ctx, best - ctx->state); +} +/* exec_spec.c END } */ + Index: tags/2.3.0/src_plugins/io_bxl/bxl_lex.h =================================================================== --- tags/2.3.0/src_plugins/io_bxl/bxl_lex.h (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/bxl_lex.h (revision 33253) @@ -0,0 +1,77 @@ +/* strtree.h BEGIN { */ +#ifndef UREGLEX_STRTREE_H +#define UREGLEX_STRTREE_H +typedef enum {ULX_REQ = 1, ULX_BRA, ULX_FIN, ULX_BAD} ureglex_stree_op_t; +typedef struct ureglex_strtree_s { int *code, *ip; } ureglex_strtree_t; +int ureglex_strtree_exec(ureglex_strtree_t *ctx, int chr); +#define UREGLEX_STRTREE_MORE -5 +#endif +/* strtree.h END } */ + +/* exec.h BEGIN { */ +#ifndef UREGLEX_EXEC_COMMON_H +#define UREGLEX_EXEC_COMMON_H +#define MAXTAG 10 +typedef struct ureglex_precomp_s { + const unsigned char *nfa; + const unsigned char *bittab; + const unsigned char *chrtyp; + double weight; +} ureglex_precomp_t; +typedef struct ureglex_s { + ureglex_precomp_t *pc; + const char *bol; + const char *bopat[MAXTAG]; + const char *eopat[MAXTAG]; + int score; + const char *endp; + union { const void *ptr; int i; } pmstk[30]; + int pmsp; + const unsigned char *pm_ap; + const char *pm_lp; + int pm_c; + const char *pm_bp; + const char *pm_ep; + const char *pm_are; + const char *ex_lp; + unsigned char ex_c; + int ex_loop, pm_loop, pm_loop2, pm_loop2_later; + int exec_state; +} ureglex_t; +typedef enum { + UREGLEX_MORE = -1, + UREGLEX_TOO_LONG = -2, + UREGLEX_NO_MATCH = -3, + UREGLEX_NOP = -4 +} ureglex_error_t; +extern const unsigned char ureglex_nfa_str[]; +#define ULX_BUF ctx->buff +#define ULX_TAGP(n) (ctx->state[ruleid].bopat[(n)]) +#define ULX_TAGL(n) (ctx->state[ruleid].eopat[(n)] - ctx->state[ruleid].bopat[(n)]) +#define ULX_IGNORE goto ureglex_ignore; +#endif +/* exec.h END } */ + +#define pcb_bxl_num_rules 63 +typedef struct pcb_bxl_ureglex_s { + ureglex_precomp_t *rules; + char buff[256]; + int num_rules, buff_used, step_back_to, buff_save_term, by_len; + long loc_offs[2], loc_line[2], loc_col[2]; + ureglex_t state[pcb_bxl_num_rules]; + const char *sp; + int strtree_state, strtree_len, strtree_score; + ureglex_strtree_t strtree; +} pcb_bxl_ureglex_t; + +/* exec_spec.h BEGIN { */ +void pcb_bxl_lex_reset(pcb_bxl_ureglex_t *ctx); +void pcb_bxl_lex_init(pcb_bxl_ureglex_t *ctx, ureglex_precomp_t *rules); +int pcb_bxl_lex_char(pcb_bxl_ureglex_t *ctx, void *user_ctx, int chr); +/* exec_spec.h END } */ + +#ifndef URELGLEX_EXEC_pcb_bxl_H +#define URELGLEX_EXEC_pcb_bxl_H +extern ureglex_precomp_t pcb_bxl_rules[]; +#define URELGLEX_EXEC_pcb_bxl_HAS_COMMON 1 +#endif Index: tags/2.3.0/src_plugins/io_bxl/bxl_lex.ul =================================================================== --- tags/2.3.0/src_plugins/io_bxl/bxl_lex.ul (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/bxl_lex.ul (revision 33253) @@ -0,0 +1,129 @@ +prefix pcb_bxl +by_score + +top_code + /* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * BXL IO plugin - bxl lexer + * pcb-rnd Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + #include + #include + #include "bxl_gram.h" + #define lval ((pcb_bxl_STYPE *)(user_ctx)) + +rule integer +regex [-]?[0-9]+ +code + lval->un.i = atoi(ULX_BUF); + return T_INTEGER; + +rule real +regex [-]?[0-9]*[.][0-9Ee+-]* +code + lval->un.d = strtod(ULX_BUF, NULL); + return T_REAL_ONLY; + +rule id +regex [a-zA-Z][a-zA-Z0-9_-]* +code + lval->un.s = pcb_strdup(ULX_BUF); + return T_ID; + +rule quoted string +regex "\([^"]*\)" +code + lval->un.s = pcb_strndup(ULX_TAGP(1), ULX_TAGL(1)); + return T_QSTR; + +rule chars +regex [():,\n] +code + return *ULX_BUF; + +rule blank +regex [ \t\r]+ +code + ULX_IGNORE; + +rulestring 3D_DXF lval->un.s = pcb_strdup(ULX_BUF); return T_ID; + +rulestring True return T_TRUE; +rulestring False return T_FALSE; +rulestring TextStyle return T_TEXTSTYLE; +rulestring FontWidth return T_FONTWIDTH; +rulestring FontCharWidth return T_FONTCHARWIDTH; +rulestring FontHeight return T_FONTHEIGHT; +rulestring PadStack return T_PADSTACK; +rulestring EndPadStack return T_ENDPADSTACK; +rulestring Shapes return T_SHAPES; +rulestring PadShape return T_PADSHAPE; +rulestring HoleDiam return T_HOLEDIAM; +rulestring Surface return T_SURFACE; +rulestring Plated return T_PLATED; +rulestring NoPaste return T_NOPASTE; +rulestring Width return T_WIDTH; +rulestring Height return T_HEIGHT; +rulestring PadType return T_PADTYPE; +rulestring Layer return T_LAYER; +rulestring Pattern return T_PATTERN; +rulestring EndPattern return T_ENDPATTERN; +rulestring Data return T_DATA; +rulestring EndData return T_ENDDATA; +rulestring OriginPoint return T_ORIGINPOINT; +rulestring PickPoint return T_PICKPOINT; +rulestring GluePoint return T_GLUEPOINT; +rulestring Pad return T_PAD; +rulestring Number return T_NUMBER; +rulestring PinName return T_PINNAME; +rulestring PadStyle return T_PADSTYLE; +rulestring OriginalPadStyle return T_ORIGINALPADSTYLE; +rulestring Origin return T_ORIGIN; +rulestring OriginalPinNumber return T_ORIGINALPINNUMBER; +rulestring Rotate return T_ROTATE; +rulestring Poly return T_POLY; +rulestring Line return T_LINE; +rulestring EndPoint return T_ENDPOINT; +rulestring Width return T_WIDTH; +rulestring Attribute return T_ATTRIBUTE; +rulestring Attr return T_ATTR; +rulestring Justify return T_JUSTIFY; +rulestring Arc return T_ARC; +rulestring Radius return T_RADIUS; +rulestring StartAngle return T_STARTANGLE; +rulestring SweepAngle return T_SWEEPANGLE; +rulestring Text return T_TEXT; +rulestring IsVisible return T_ISVISIBLE; +rulestring IsFlipped return T_ISFLIPPED; +rulestring Property return T_PROPERTY; +rulestring Wizard return T_WIZARD; +rulestring Templatedata return T_TEMPLATEDATA; +rulestring VarName return T_VARNAME; +rulestring VarData return T_VARDATA; +rulestring Symbol return T_SYMBOL; +rulestring EndSymbol return T_ENDSYMBOL; +rulestring Component return T_COMPONENT; +rulestring EndComponent return T_ENDCOMPONENT; Index: tags/2.3.0/src_plugins/io_bxl/io_bxl.c =================================================================== --- tags/2.3.0/src_plugins/io_bxl/io_bxl.c (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/io_bxl.c (revision 33253) @@ -0,0 +1,91 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * BXL IO plugin - plugin coordination + * pcb-rnd Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include "plug_io.h" + +#include "read.h" + +static pcb_plug_io_t io_bxl; +static const char *bxl_cookie = "bxl IO"; + + +int io_bxl_fmt(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, int wr, const char *fmt) +{ + if ((strcmp(ctx->description, fmt) != 0) && (rnd_strcasecmp(fmt, "bxl") != 0)) /* format name mismatch */ + return 0; + + if (((typ & (~(PCB_IOT_FOOTPRINT))) != 0) && ((typ & (~(PCB_IOT_PCB))) != 0)) /* support only footprints */ + return 0; + + if (wr) /* no footprint write yet */ + return 0; + + return 100; +} + +int pplg_check_ver_io_bxl(int ver_needed) { return 0; } + +void pplg_uninit_io_bxl(void) +{ + rnd_remove_actions_by_cookie(bxl_cookie); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_bxl); +} + +int pplg_init_io_bxl(void) +{ + RND_API_CHK_VER; + + io_bxl.plugin_data = NULL; + io_bxl.fmt_support_prio = io_bxl_fmt; + io_bxl.test_parse = io_bxl_test_parse; + io_bxl.parse_pcb = io_bxl_parse_pcb; + io_bxl.parse_footprint = io_bxl_parse_footprint; + io_bxl.map_footprint = io_bxl_map_footprint; + io_bxl.parse_font = NULL; + io_bxl.write_buffer = NULL; + io_bxl.write_pcb = NULL; + io_bxl.default_fmt = "bxl"; + io_bxl.description = "bxl footprint"; + io_bxl.save_preference_prio = 90; + io_bxl.default_extension = ".bxl"; + io_bxl.fp_extension = ".bxl"; + io_bxl.mime_type = "application/x-bxl"; + io_bxl.multi_footprint = 1; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_bxl); + + return 0; +} + Index: tags/2.3.0/src_plugins/io_bxl/io_bxl.pup =================================================================== --- tags/2.3.0/src_plugins/io_bxl/io_bxl.pup (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/io_bxl.pup (revision 33253) @@ -0,0 +1,9 @@ +$class io +$short BXL footprint +$long load footprints from the BXL format. +$state WIP +$fmt-native no +$fmt-feature-r BXL footprints +$package io-alien +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/io_bxl/read.c =================================================================== --- tags/2.3.0/src_plugins/io_bxl/read.c (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/read.c (revision 33253) @@ -0,0 +1,877 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * BXL IO plugin - read: decode, parse, interpret + * pcb-rnd Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include "board.h" + +#include "read.h" +#include "plug_footprint.h" +#include "bxl_decode.h" +#include "bxl_lex.h" +#include "bxl_gram.h" + +#define SKIP if (!ctx->in_target_fp) return +#define SKIP_FREE(ptr) if (!ctx->in_target_fp) { free(ptr); return; } + +static const pcb_dflgmap_t bxl_layer_names[] = { + /* name layer type purpose comb flags */ + {"TOP", PCB_LYT_TOP | PCB_LYT_COPPER, NULL, 0, 0}, + {"BOTTOM", PCB_LYT_BOTTOM | PCB_LYT_COPPER, NULL, 0, 0}, + {"TOP_SILKSCREEN", PCB_LYT_TOP | PCB_LYT_SILK, NULL, 0, 0}, + {"BOTTOM_SILKSCREEN", PCB_LYT_BOTTOM | PCB_LYT_SILK, NULL, 0, 0}, + {"TOP_ASSEMBLY", PCB_LYT_TOP | PCB_LYT_DOC, "assy", 0, 0}, + {"BOTTOM_ASSEMBLY", PCB_LYT_BOTTOM | PCB_LYT_DOC, "assy", 0, 0}, + {"TOP_SOLDER_MASK", PCB_LYT_TOP | PCB_LYT_MASK, NULL, PCB_LYC_SUB|PCB_LYC_AUTO, 0}, + {"BOTTOM_SOLDER_MASK", PCB_LYT_BOTTOM | PCB_LYT_MASK, NULL, PCB_LYC_SUB|PCB_LYC_AUTO, 0}, + {"TOP_SOLDER_PASTE", PCB_LYT_TOP | PCB_LYT_PASTE, NULL, PCB_LYC_AUTO,0}, + {"BOTTOM_SOLDER_PASTE", PCB_LYT_BOTTOM | PCB_LYT_PASTE, NULL, PCB_LYC_AUTO,0}, + + /* these are better not drawn by default */ + {"3D_DXF", PCB_LYT_VIRTUAL, NULL, 0, 0}, + {"PIN_DETAIL", PCB_LYT_VIRTUAL, NULL, 0, 0}, + {"TOP_NO-PROBE", PCB_LYT_VIRTUAL, NULL, 0, 0}, + {"BOTTOM_NO-PROBE", PCB_LYT_VIRTUAL, NULL, 0, 0}, + {"TOP_VALOR", PCB_LYT_VIRTUAL, NULL, 0, 0}, + {"BOTTOM_VALOR", PCB_LYT_VIRTUAL, NULL, 0, 0}, + {"TOP_PLACE_BOUND", PCB_LYT_VIRTUAL, NULL, 0, 0}, + {"BOTTOM_PLACE_BOUND", PCB_LYT_VIRTUAL, NULL, 0, 0}, + {"TOP_PLACEBOUND_3", PCB_LYT_VIRTUAL, NULL, 0, 0}, + {"BOTTOM_PLACEBOUND_3", PCB_LYT_VIRTUAL, NULL, 0, 0}, + {"PLACEMENT_BODY", PCB_LYT_VIRTUAL, NULL, 0, 0}, + {NULL, 0, 0, 0, 0} +}; + +static const pcb_dflgmap_t bxl_layer_fragments[] = { + {"TOP_", PCB_LYT_TOP, NULL, 0, 0}, + {"BOTTOM_", PCB_LYT_BOTTOM, NULL, 0, 0}, + {NULL, 0, 0, 0, 0} +}; + + +static const pcb_dflgmap_t *bcl_layer_resolve_name(const char *name) +{ + static pcb_dflgmap_t tmp; + const pcb_dflgmap_t *n; + + for(n = bxl_layer_names; n->name != NULL; n++) + if (strcmp(name, n->name) == 0) + return n; + + memset(&tmp, 0, sizeof(tmp)); + for(n = bxl_layer_fragments; n->name != NULL; n++) { + if (strstr(name, n->name) != NULL) { + tmp.lyt |= n->lyt; + tmp.comb |= n->comb; + if (n->purpose != NULL) + tmp.purpose = n->purpose; + } + } + tmp.name = name; + + if ((tmp.lyt & PCB_LYT_ANYTHING) == 0) + tmp.lyt |= PCB_LYT_DOC; + + return &tmp; +} + +rnd_coord_t pcb_bxl_coord_x(rnd_coord_t c) { return c; } +rnd_coord_t pcb_bxl_coord_y(rnd_coord_t c) { return -c; } + +void pcb_bxl_pattern_begin(pcb_bxl_ctx_t *bctx, const char *name) +{ + if (bctx->subfpname != NULL) + bctx->in_target_fp = (strcmp(name, bctx->subfpname) == 0); + /* if it is NULL, we are reading the first and bctx->in_target_fp is already set to 1 by the init call */ +} + +void pcb_bxl_pattern_end(pcb_bxl_ctx_t *ctx) +{ + pcb_subc_create_aux(ctx->subc, ctx->pat_state.origin_x, ctx->pat_state.origin_y, 0, 0); + pcb_subc_create_aux_point(ctx->subc, ctx->pat_state.pick_x, ctx->pat_state.pick_y, "pnp-origin"); + pcb_subc_create_aux_point(ctx->subc, ctx->pat_state.glue_x, ctx->pat_state.glue_y, "glue-origin"); + + ctx->in_target_fp = 0; +} + +void pcb_bxl_reset(pcb_bxl_ctx_t *ctx) +{ + free(ctx->state.attr_key); + free(ctx->state.attr_val); + memset(&ctx->state, 0, sizeof(ctx->state)); +} + +void pcb_bxl_reset_pattern(pcb_bxl_ctx_t *ctx) +{ + SKIP; + memset(&ctx->pat_state, 0, sizeof(ctx->pat_state)); +} + +void pcb_bxl_set_layer(pcb_bxl_ctx_t *ctx, const char *layer_name) +{ + htsp_entry_t *e; + + e = htsp_getentry(&ctx->layer_name2ly, layer_name); + if (e == NULL) { + const pcb_dflgmap_t *lm = bcl_layer_resolve_name(layer_name); + pcb_layer_t *ly; + + ly = pcb_subc_get_layer(ctx->subc, lm->lyt, lm->comb, 1, layer_name, rnd_true); + htsp_set(&ctx->layer_name2ly, rnd_strdup(layer_name), ly); + ctx->state.layer = ly; + } + else + ctx->state.layer = e->value; + + if (ctx->state.delayed_poly) { + ctx->state.poly = pcb_poly_new(ctx->state.layer, 0, pcb_flag_make(PCB_FLAG_CLEARPOLY)); + ctx->state.delayed_poly = 0; + } +} + +void pcb_bxl_set_justify(pcb_bxl_ctx_t *ctx, const char *str) +{ + /* special case for single center */ + if (rnd_strcasecmp(str, "center") == 0) { ctx->state.hjust = ctx->state.vjust = PCB_BXL_JUST_CENTER; return; } + + if (rnd_strncasecmp(str, "lower", 5) == 0) { ctx->state.vjust = PCB_BXL_JUST_BOTTOM; str+=5; } + else if (rnd_strncasecmp(str, "upper", 5) == 0) { ctx->state.vjust = PCB_BXL_JUST_TOP; str+=5; } + else if (rnd_strncasecmp(str, "center", 6) == 0) { ctx->state.vjust = PCB_BXL_JUST_CENTER; str+=6; } + + if (rnd_strncasecmp(str, "left", 4) == 0) ctx->state.hjust = PCB_BXL_JUST_LEFT; + else if (rnd_strncasecmp(str, "right", 5) == 0) ctx->state.hjust = PCB_BXL_JUST_RIGHT; + else if (rnd_strncasecmp(str, "center", 6) == 0) ctx->state.hjust = PCB_BXL_JUST_CENTER; +} + +void pcb_bxl_add_property(pcb_bxl_ctx_t *ctx, pcb_any_obj_t *obj, const char *keyval) +{ + char *tmp, *val; + const char *sep; + + SKIP; + + if (obj == NULL) { + ctx->warn.property_null_obj++; + return; + } + + sep = strchr(keyval, '='); + if (sep == NULL) { + ctx->warn.property_nosep++; + return; + } + + tmp = rnd_strdup(keyval); + tmp[sep-keyval] = '\0'; + val = tmp+(sep-keyval)+1; + pcb_attribute_put(&obj->Attributes, tmp, val); + free(tmp); +} + +void pcb_bxl_set_attr_val(pcb_bxl_ctx_t *ctx, char *key, char *val) +{ + free(ctx->state.attr_key); + free(ctx->state.attr_val); + + ctx->state.attr_key = key; + ctx->state.attr_val = val; +} + + +void pcb_bxl_padstack_begin(pcb_bxl_ctx_t *ctx, char *name) +{ + htsi_entry_t *e = htsi_getentry(&ctx->proto_name2id, name); + if (e != NULL) + rnd_message(RND_MSG_WARNING, "bxl footprint error: padstack '%s' redefined\n", name); + + ctx->state.proto.name = name; + ctx->state.proto.in_use = 1; + ctx->state.copper_shape_idx = -1; + if (e == NULL) + htsi_set(&ctx->proto_name2id, name, ctx->proto_id++); +} + + + /* create mask shapes for thru-hole */ +static void pcb_bxl_padstack_end_automask(pcb_bxl_ctx_t *ctx) +{ + const pcb_proto_layer_t *n; + int i, dst; + + if (ctx->state.surface) + return; + + if (ctx->state.proto.hdia <= 0) + rnd_message(RND_MSG_WARNING, "bxl footprint error: padstack '%s' marked as non-surface-mounted yet there is no hole in it\n", ctx->state.proto.name); + if (ctx->state.has_mask_shape) + return; /* do not override user's mask */ + + if (ctx->state.copper_shape_idx < 0) { + rnd_message(RND_MSG_WARNING, "bxl footprint error: padstack '%s' is thru-hole, does not have mask or copper\n", ctx->state.proto.name); + return; + } + + for(n = pcb_proto_layers, i = 0; i < pcb_proto_num_layers; i++,n++) { + pcb_pstk_tshape_t *ts; + + if ((n->mask & PCB_LYT_MASK) == 0) + continue; + + ts = &ctx->state.proto.tr.array[0]; + pcb_pstk_alloc_append_shape(ts); + dst = ts->len-1; + pcb_pstk_shape_derive(&ctx->state.proto, dst, ctx->state.copper_shape_idx, n->auto_bloat, n->mask, n->comb); + } +} + +void pcb_bxl_padstack_end(pcb_bxl_ctx_t *ctx) +{ + rnd_cardinal_t i; + + ctx->state.proto.hdia = ctx->state.hole; + ctx->state.proto.hplated = ctx->state.plated; + + pcb_bxl_padstack_end_automask(ctx); + + i = pcb_pstk_proto_insert_forcedup(ctx->subc->data, &ctx->state.proto, 0, 0); + if (ctx->proto_id-1 != i) + rnd_message(RND_MSG_WARNING, "bxl footprint error: failed to insert padstack '%s'\n", ctx->state.proto.name); + ctx->state.proto.name = NULL; /* do not free it as it is the hash key */ + + pcb_pstk_proto_free_fields(&ctx->state.proto); +} + +void pcb_bxl_padstack_begin_shape(pcb_bxl_ctx_t *ctx, const char *name) +{ + if (rnd_strcasecmp(name, "rectangle") == 0) ctx->state.shape_type = 1; + else if (rnd_strcasecmp(name, "square") == 0) ctx->state.shape_type = 1; + else if (rnd_strcasecmp(name, "round") == 0) ctx->state.shape_type = 2; + else { + rnd_message(RND_MSG_WARNING, "bxl footprint error: unknown padstack shape '%s' in '%s' - omitting shape\n", name, ctx->state.proto.name); + return; + } +} + +void pcb_bxl_padstack_end_shape(pcb_bxl_ctx_t *ctx) +{ + pcb_pstk_tshape_t *ts; + pcb_pstk_shape_t *sh; + + if ((ctx->state.width == 0) || (ctx->state.height == 0)) { + /* 0 sizes shape should not appear on the output */ + if (ctx->state.layer->meta.bound.type & PCB_LYT_COPPER) + rnd_message(RND_MSG_WARNING, "bxl footprint error: 0 sized copper shape in padstack '%s'\n", ctx->state.proto.name); + return; + } + + if (ctx->state.proto.tr.used == 0) + ts = pcb_vtpadstack_tshape_alloc_append(&ctx->state.proto.tr, 1); + else + ts = &ctx->state.proto.tr.array[0]; + sh = pcb_pstk_alloc_append_shape(ts); + + if (ctx->state.layer->meta.bound.type & PCB_LYT_MASK) + ctx->state.has_mask_shape = 1; + + if (ctx->state.layer->meta.bound.type & PCB_LYT_COPPER) + ctx->state.copper_shape_idx = ts->len-1; + + sh->layer_mask = ctx->state.layer->meta.bound.type; + sh->comb = ctx->state.layer->comb; + sh->clearance = 0; + switch(ctx->state.shape_type) { + case 1: /* rectangle, square */ + { + rnd_coord_t w2 = (ctx->state.width/2)+1, h2 = (ctx->state.height/2)+1; + sh->shape = PCB_PSSH_POLY; + pcb_pstk_shape_alloc_poly(&sh->data.poly, 4); + sh->data.poly.x[0] = -w2; sh->data.poly.y[0] = -h2; + sh->data.poly.x[1] = +w2; sh->data.poly.y[1] = -h2; + sh->data.poly.x[2] = +w2; sh->data.poly.y[2] = +h2; + sh->data.poly.x[3] = -w2; sh->data.poly.y[3] = +h2; + } + break; + + case 2: /* round */ + sh->shape = PCB_PSSH_CIRC; + sh->data.circ.x = sh->data.circ.y = 0; + sh->data.circ.dia = (ctx->state.width + ctx->state.height)/2; + if (ctx->state.width != ctx->state.height) + rnd_message(RND_MSG_WARNING, "bxl footprint error: padstack: asymmetric round shape - probably a typo, using real round shape in '%s'\n", ctx->state.proto.name); + break; + } + +} + +void pcb_bxl_pad_begin(pcb_bxl_ctx_t *ctx) +{ + SKIP; + ctx->state.pstk_proto_id = -1; + ctx->state.pin_number = -1; +} + +void pcb_bxl_pad_end(pcb_bxl_ctx_t *ctx) +{ + int xmirror = 0, smirror = 0; + pcb_pstk_t *ps; + + SKIP_FREE(ctx->state.pin_name); + + if (ctx->state.pstk_proto_id < 0) { + free(ctx->state.pin_name); + return; + } + + ps = pcb_pstk_new_tr(ctx->subc->data, -1, ctx->state.pstk_proto_id, + ctx->state.origin_x, ctx->state.origin_y, + RND_MM_TO_COORD(0.2), pcb_flag_make(PCB_FLAG_CLEARLINE), + ctx->state.rot, xmirror, smirror); + + if (ps != NULL) { + if (ctx->state.pin_name != NULL) + pcb_attribute_put(&ps->Attributes, "name", ctx->state.pin_name); + + if (ctx->state.pin_number >= 0) { + char tmp[32]; + sprintf(tmp, "%d", ctx->state.pin_number); + pcb_attribute_put(&ps->Attributes, "term", tmp); + } + } + else + rnd_message(RND_MSG_ERROR, "bxl footprint: internal error: failed to create padstack - expect missing padstacks\n"); + + free(ctx->state.pin_name); + ctx->state.pin_name = NULL; +} + +void pcb_bxl_pad_set_style(pcb_bxl_ctx_t *ctx, const char *pstkname) +{ + htsi_entry_t *e; + + SKIP; + + e = htsi_getentry(&ctx->proto_name2id, pstkname); + if (e == NULL) { + ctx->state.pstk_proto_id = -1; + rnd_message(RND_MSG_WARNING, "bxl footprint error: invalid padstack reference '%s' - pad will not be created\n", pstkname); + return; + } + ctx->state.pstk_proto_id = e->value; +} + + + +void pcb_bxl_add_line(pcb_bxl_ctx_t *ctx) +{ + rnd_coord_t width; + SKIP; + width = ctx->state.width; + if (width == 0) + width = 1; + pcb_line_new(ctx->state.layer, + ctx->state.origin_x, ctx->state.origin_y, + ctx->state.endp_x, ctx->state.endp_y, + width, 0, pcb_flag_make(PCB_FLAG_CLEARLINE)); +} + +void pcb_bxl_add_arc(pcb_bxl_ctx_t *ctx) +{ + rnd_coord_t width; + SKIP; + width = ctx->state.width; + if (width == 0) + width = 1; + pcb_arc_new(ctx->state.layer, + ctx->state.origin_x, ctx->state.origin_y, + ctx->state.radius, ctx->state.radius, + ctx->state.arc_start, ctx->state.arc_delta, + width, 0, pcb_flag_make(PCB_FLAG_CLEARLINE), 0); +} + +void pcb_bxl_add_text(pcb_bxl_ctx_t *ctx) +{ + pcb_flag_values_t flg = 0; + int tlen; + rnd_coord_t bbw, bbh, anchx, anchy; + rnd_coord_t thickness; + double scxy; + pcb_text_mirror_t mirror; + SKIP; + + if (!ctx->state.is_text && (ctx->state.attr_key != NULL)) { + int is_refdes = (rnd_strcasecmp(ctx->state.attr_key, "refdes") == 0); + + if (is_refdes) { + strcpy(ctx->state.attr_key, "refdes"); + + /* make sure the text object is created properly */ + flg = PCB_FLAG_FLOATER | PCB_FLAG_DYNTEXT; + free(ctx->state.text_str); + ctx->state.text_str = rnd_strdup("%a.parent.refdes%"); + ctx->state.is_visible = 1; + } + pcb_attribute_put(&ctx->subc->Attributes, ctx->state.attr_key, ctx->state.attr_val); + } + + if (ctx->state.text_style->char_width == 0) + ctx->state.text_style->char_width = ctx->state.text_style->height; + + /* determine desired bounding box size */ + tlen = ctx->state.text_str == NULL ? 0 : strlen(ctx->state.text_str); + bbw = RND_MIL_TO_COORD(ctx->state.text_style->char_width * tlen); + bbh = RND_MIL_TO_COORD(ctx->state.text_style->height * (double)(1.3333333333)); /* +1/3 for the parts under the baseline */ + + /* determine anchor point on this bounding box; the anchor is the point placed + at origin */ + switch(ctx->state.hjust) { + case PCB_BXL_JUST_LEFT: anchx = 0; break; + case PCB_BXL_JUST_RIGHT: anchx = bbw; break; + default:; + case PCB_BXL_JUST_CENTER: anchx = bbw/2; break; + } + + switch(ctx->state.vjust) { + case PCB_BXL_JUST_TOP: anchy = 0; break; + case PCB_BXL_JUST_BOTTOM: anchy = RND_MIL_TO_COORD(ctx->state.text_style->height); break; + default:; + case PCB_BXL_JUST_CENTER: anchy = RND_MIL_TO_COORD(ctx->state.text_style->height)/2; break; + } + +/*rnd_trace("bxl text '%s' w=%ml h=%ml anchx=%ml anchy=%ml (%d %d)\n", ctx->state.text_str, bbw, bbh, anchx, anchy, ctx->state.hjust, ctx->state.vjust);*/ + + if ((ctx->state.text_str != NULL) && (ctx->state.is_visible)) { + if (ctx->state.text_style != NULL) { +/* rnd_trace(" wh: %ml %ml\n", RND_MIL_TO_COORD(ctx->state.text_style->char_width), RND_MIL_TO_COORD(ctx->state.text_style->height));*/ + scxy = (double)ctx->state.text_style->char_width / (double)ctx->state.text_style->height; + thickness = RND_MIL_TO_COORD(ctx->state.text_style->width); + } + else { + scxy = 1; + thickness = 0; + } + + mirror = ctx->state.flipped ? PCB_TXT_MIRROR_X : 0; + pcb_text_new_by_bbox(ctx->state.layer, pcb_font(ctx->pcb, 0, 1), + ctx->state.origin_x, ctx->state.origin_y, + bbw, bbh, anchx, anchy, scxy, mirror, + ctx->state.rot, thickness, ctx->state.text_str, + pcb_flag_make(PCB_FLAG_CLEARLINE | flg)); + } + free(ctx->state.text_str); + ctx->state.text_str = NULL; +} + +void pcb_bxl_set_text_str(pcb_bxl_ctx_t *ctx, char *str) +{ + SKIP_FREE(str); + free(ctx->state.text_str); + ctx->state.text_str = str; +} + + +void pcb_bxl_poly_begin(pcb_bxl_ctx_t *ctx) +{ + SKIP; + ctx->state.delayed_poly = 1; +} + +void pcb_bxl_poly_add_vertex(pcb_bxl_ctx_t *ctx, rnd_coord_t x, rnd_coord_t y) +{ + SKIP; + assert(ctx->state.poly != NULL); + pcb_poly_point_new(ctx->state.poly, x + ctx->state.origin_x, y + ctx->state.origin_y); +} + +void pcb_bxl_poly_end(pcb_bxl_ctx_t *ctx) +{ + SKIP; + assert(ctx->state.poly != NULL); + + if (pcb_poly_is_valid(ctx->state.poly)) { + pcb_add_poly_on_layer(ctx->state.layer, ctx->state.poly); +/* pcb_poly_init_clip(ctx->subc->data, ctx->state.layer, ctx->state.poly);*/ + } + else { + ctx->warn.poly_broken++; + pcb_poly_free(ctx->state.poly); + } + ctx->state.poly = NULL; + ctx->state.delayed_poly = 0; +} + +void pcb_bxl_text_style_begin(pcb_bxl_ctx_t *ctx, char *name) +{ + pcb_bxl_test_style_t *ts = htsp_get(&ctx->text_name2style, name); + if (ts == NULL) { + ts = calloc(sizeof(pcb_bxl_test_style_t), 1); + htsp_set(&ctx->text_name2style, name, ts); /* name is not free'd at the caller */ + } + else + rnd_message(RND_MSG_WARNING, "bxl footprint error: text style '%s' is redefined; second definition will override first\n", name); + ctx->state.text_style = ts; +} + +void pcb_bxl_text_style_end(pcb_bxl_ctx_t *ctx) +{ + ctx->state.text_style = NULL; +} + +void pcb_bxl_set_text_style(pcb_bxl_ctx_t *ctx, const char *name) +{ + ctx->state.text_style = htsp_get(&ctx->text_name2style, name); + if (ctx->state.text_style == NULL) + rnd_message(RND_MSG_WARNING, "bxl footprint error: text style '%s' not defined (using default style)\n", name); +} + + +#define WARN_CNT(_count_, args) \ +do { \ + long cnt = (bctx->warn._count_); \ + if (cnt > 0) rnd_message args; \ +} while(0) + + +static void pcb_bxl_init(pcb_bxl_ctx_t *bctx, pcb_board_t *pcb, pcb_data_t *data, const char *subfpname) +{ + memset(bctx, 0, sizeof(pcb_bxl_ctx_t)); + bctx->pcb = pcb; + bctx->subc = pcb_subc_new(); + + if (data != NULL) { + if (!data->padstack_tree) + data->padstack_tree = rnd_r_create_tree(); + bctx->subc->data->padstack_tree = data->padstack_tree; + } + + if (subfpname == NULL) + bctx->in_target_fp = 1; /* read the first one if the user didn't name any */ + bctx->subfpname = subfpname; + htsp_init(&bctx->layer_name2ly, strhash, strkeyeq); + htsp_init(&bctx->text_name2style, strhash_case, strkeyeq_case); + htsi_init(&bctx->proto_name2id, strhash, strkeyeq); +} + +static void pcb_bxl_uninit(pcb_bxl_ctx_t *bctx) +{ + htsp_entry_t *e; + htsi_entry_t *ei; + + /* emit all accumulated warnings */ + WARN_CNT(poly_broken, (RND_MSG_WARNING, "footprint contains %ld invalid polygons (polygons ignored)\n", cnt)); + WARN_CNT(property_null_obj, (RND_MSG_WARNING, "footprint contains %ld properties that could not be attached to any object\n", cnt)); + WARN_CNT(property_nosep, (RND_MSG_WARNING, "footprint contains %ld properties without separator between key and value\n", cnt)); + + + for(e = htsp_first(&bctx->layer_name2ly); e != NULL; e = htsp_next(&bctx->layer_name2ly, e)) + free(e->key); + htsp_uninit(&bctx->layer_name2ly); + + for(e = htsp_first(&bctx->text_name2style); e != NULL; e = htsp_next(&bctx->text_name2style, e)) { + free(e->key); + free(e->value); + } + htsp_uninit(&bctx->text_name2style); + + for(ei = htsi_first(&bctx->proto_name2id); ei != NULL; ei = htsi_next(&bctx->proto_name2id, ei)) + free(ei->key); + htsi_uninit(&bctx->proto_name2id); +} + +#undef WARN_CNT + +/* Error is handled on the push side */ +void pcb_bxl_error(pcb_bxl_ctx_t *ctx, pcb_bxl_STYPE tok, const char *s) { } + +int io_bxl_parse_footprint(pcb_plug_io_t *ctx, pcb_data_t *data, const char *filename, const char *subfpname) +{ + rnd_hidlib_t *hl = &PCB->hidlib; + FILE *f; + int chr, tok, yres, ret = 0; + hdecode_t hctx; + pcb_bxl_ureglex_t lctx; + pcb_bxl_yyctx_t yyctx; + pcb_bxl_ctx_t bctx; + pcb_bxl_STYPE lval; + + f = rnd_fopen(hl, filename, "rb"); + if (f == NULL) + return -1; + + pcb_bxl_init(&bctx, (pcb_board_t *)hl, data, subfpname); + + pcb_bxl_decode_init(&hctx); + pcb_bxl_lex_init(&lctx, pcb_bxl_rules); + pcb_bxl_parse_init(&yyctx); + + /* read all bytes of the binary file */ + while((chr = fgetc(f)) != EOF) { + int n, ilen; + + /* feed the binary decoding */ + ilen = pcb_bxl_decode_char(&hctx, chr); + assert(ilen >= 0); + if (ilen == 0) + continue; + + /* feed the lexer */ + for(n = 0; n < ilen; n++) { + tok = pcb_bxl_lex_char(&lctx, &lval, hctx.out[n]); + if (tok == UREGLEX_MORE) + continue; + + /* feed the grammar */ + lval.line = lctx.loc_line[0]; + lval.first_col = lctx.loc_col[0]; + yres = pcb_bxl_parse(&yyctx, &bctx, tok, &lval); + + if ((bctx.in_error) && ((tok == T_ID) || (tok == T_QSTR))) + free(lval.un.s); + + if (yres != 0) { + fprintf(stderr, "BXL syntax error at %ld:%ld\n", lval.line, lval.first_col); + ret = -1; + if (bctx.subc != NULL) + pcb_subc_free(bctx.subc); + goto error; + } + pcb_bxl_lex_reset(&lctx); /* prepare for the next token */ + } + } + + pcb_subc_reg(data, bctx.subc); + + error:; + pcb_bxl_parse(&yyctx, &bctx, 0, &lval); + pcb_bxl_uninit(&bctx); + fclose(f); + return ret; +} + +int io_bxl_test_parse2(rnd_hidlib_t *hl, pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *filename, FILE *f_ignore, void *cbctx, void (*pat_cb)(void *cbctx, const char *name)) +{ + FILE *f; + int chr, tok, found_tok = 0, ret = 0; + hdecode_t hctx; + pcb_bxl_ureglex_t lctx; + + f = rnd_fopen(hl, filename, "rb"); /* need to open it again, for binary access */ + if (f == NULL) + return 0; + + pcb_bxl_decode_init(&hctx); + pcb_bxl_lex_init(&lctx, pcb_bxl_rules); + + /* read all bytes of the binary file */ + while((chr = fgetc(f)) != EOF) { + int n, ilen; + + /* feed the binary decoding */ + ilen = pcb_bxl_decode_char(&hctx, chr); + assert(ilen >= 0); + if (ilen == 0) + continue; + + /* feed the lexer */ + for(n = 0; n < ilen; n++) { + pcb_bxl_STYPE lval; + tok = pcb_bxl_lex_char(&lctx, &lval, hctx.out[n]); + if (tok == UREGLEX_MORE) + continue; + + if ((tok == UREGLEX_NO_MATCH) || (tok == UREGLEX_TOO_LONG)) { + fclose(f); + return -1; /* error - stop fast, don't read through the whole file */ + } + + /* simplified "grammar": find opening tokens, save the next token + as ID and don't do anything until finding the closing token */ + + switch(found_tok) { + + /* found an opening token, tok is the ID */ + case T_PADSTACK: + rnd_trace("BXL testparse; padstack '%s'\n", lval.un.s); + found_tok = T_ENDPADSTACK; + break; + case T_PATTERN: + rnd_trace("BXL testparse; footprint '%s'\n", lval.un.s); + if (pat_cb != NULL) + pat_cb(cbctx, lval.un.s); + if ((typ & PCB_IOT_FOOTPRINT) || (typ & PCB_IOT_PCB)) + ret++; + found_tok = T_ENDPATTERN; + break; + case T_SYMBOL: found_tok = T_ENDSYMBOL; break; + case T_COMPONENT: found_tok = T_ENDCOMPONENT; break; + + default:; + switch(tok) { + /* closing token: watch for an open again */ + case T_ENDPADSTACK: + case T_ENDPATTERN: + case T_ENDSYMBOL: + case T_ENDCOMPONENT: + found_tok = 0; + break; + + /* outside of known context */ + case T_PADSTACK: + case T_PATTERN: + case T_COMPONENT: + case T_SYMBOL: + if (found_tok == 0) /* do not allow nested opens */ + found_tok = tok; + break; + default:; + /* ignore anything else */ + break; + } + break; + } + + /* fix memory leak */ + if ((tok == T_ID) || (tok == T_QSTR)) + free(lval.un.s); + + pcb_bxl_lex_reset(&lctx); /* prepare for the next token */ + } + } + + fclose(f); + return ret; +} + +int io_bxl_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *filename, FILE *f) +{ + return io_bxl_test_parse2(NULL, ctx, typ, filename, f, NULL, NULL); +} + +typedef struct { + int has_fp; + const char *fn; + pcb_plug_fp_map_t *curr, *head; +} bxl_fp_map_ctx_t; + +static void pat_cb(void *cbctx_, const char *name) +{ + bxl_fp_map_ctx_t *cbctx = cbctx_; + pcb_io_fp_map_append(&cbctx->curr, cbctx->head, cbctx->fn, name); +} + +pcb_plug_fp_map_t *io_bxl_map_footprint(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags) +{ + int res; + bxl_fp_map_ctx_t cbctx; + + cbctx.has_fp = 0; + cbctx.curr = cbctx.head = head; + cbctx.fn = fn; + + res = io_bxl_test_parse2(NULL, ctx, PCB_IOT_FOOTPRINT, fn, f, &cbctx, pat_cb); + if (res <= 0) + return NULL; + + return head; +} + +int io_bxl_parse_pcb(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest) +{ + char *sep, *autofree = NULL; + const char *subfpname = NULL; + pcb_plug_fp_map_t *m, *map = NULL, *best, head = {0}; + int res = -1; + + sep = strstr(Filename, "::"); + if (sep == NULL) { + + int numfp; + FILE *f = rnd_fopen(&PCB->hidlib, Filename, "r"); + + if (f == NULL) + return -1; + map = io_bxl_map_footprint(ctx, f, Filename, &head, 0); + for(numfp = 0, m = map; m != NULL; m = m->next) { + if (m->type == PCB_FP_FILE) { + numfp++; + best = m; + } + } + + if (numfp == 0) { + fclose(f); + goto end; + } + if (numfp == 1) { + fclose(f); + subfpname = best->name; + goto single; + } + fclose(f); + + subfpname = pcb_fp_map_choose(&PCB->hidlib, map); + if (subfpname == NULL) + goto end; + } + else { + size_t offs = sep - Filename; + autofree = rnd_strdup(Filename); + Filename = autofree; + sep = autofree + offs; + *sep = '\0'; + subfpname = sep+2; + } + + + + single:; + Ptr->is_footprint = 1; + res = io_bxl_parse_footprint(ctx, Ptr->Data, Filename, subfpname); + + if (res == 0) { + pcb_subc_t *sc = pcb_subclist_first(&Ptr->Data->subc); + pcb_layergrp_upgrade_to_pstk(Ptr); + + pcb_layer_create_all_for_recipe(Ptr, sc->data->Layer, sc->data->LayerN); + pcb_subc_rebind(Ptr, sc); + pcb_data_clip_polys(sc->data); + } + + end:; + if (map != NULL) + pcb_io_fp_map_free(map); + free(autofree); + return res; +} + Index: tags/2.3.0/src_plugins/io_bxl/read.h =================================================================== --- tags/2.3.0/src_plugins/io_bxl/read.h (nonexistent) +++ tags/2.3.0/src_plugins/io_bxl/read.h (revision 33253) @@ -0,0 +1,9 @@ +#include +#include "plug_io.h" + +int io_bxl_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); +int io_bxl_parse_footprint(pcb_plug_io_t *ctx, pcb_data_t *Ptr, const char *fn, const char *subfpname); +pcb_plug_fp_map_t *io_bxl_map_footprint(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags); +int io_bxl_parse_pcb(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest); + + Index: tags/2.3.0/src_plugins/io_dsn/Makefile =================================================================== --- tags/2.3.0/src_plugins/io_dsn/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/io_dsn/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_io_dsn + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/io_dsn/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/io_dsn/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/io_dsn/Plug.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +put /local/pcb/mod {io_dsn} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/io_dsn/io_dsn.o + $(PLUGDIR)/io_dsn/read.o + $(PLUGDIR)/io_dsn/write.o +@] + +switch /local/pcb/io_dsn/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/io_dsn/io_dsn.c =================================================================== --- tags/2.3.0/src_plugins/io_dsn/io_dsn.c (nonexistent) +++ tags/2.3.0/src_plugins/io_dsn/io_dsn.c (revision 33253) @@ -0,0 +1,93 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * dsn IO plugin - plugin coordination + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "read.h" +#include "write.h" + +#include +#include +#include "plug_io.h" +#include + + +static const char *dsn_cookie = "dsn IO"; +static pcb_plug_io_t io_dsn; + +int io_dsn_fmt(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, int wr, const char *fmt) +{ + if (wr && (typ & PCB_IOT_FOOTPRINT)) /* no footprint write */ + return 0; + + if (strcmp(ctx->description, fmt) == 0) + return 200; + + if ((rnd_strcasecmp(fmt, "dsn") != 0) || + ((typ & (~(PCB_IOT_PCB))) != 0)) + return 0; + + return 100; +} + +int pplg_check_ver_io_dsn(int ver_needed) { return 0; } + +void pplg_uninit_io_dsn(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_dsn); +} + +int pplg_init_io_dsn(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + io_dsn.plugin_data = NULL; + io_dsn.fmt_support_prio = io_dsn_fmt; + io_dsn.test_parse = io_dsn_test_parse; + io_dsn.parse_pcb = io_dsn_parse_pcb; + io_dsn.parse_footprint = NULL; + io_dsn.map_footprint = NULL; + io_dsn.parse_font = NULL; + io_dsn.write_buffer = NULL; + io_dsn.write_pcb = io_dsn_write_pcb; + io_dsn.default_fmt = "dsn"; + io_dsn.description = "specctra dsn"; + io_dsn.save_preference_prio = 20; + io_dsn.default_extension = ".dsn"; + io_dsn.fp_extension = NULL; + io_dsn.mime_type = "application/dsn"; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_dsn); + + return 0; +} Index: tags/2.3.0/src_plugins/io_dsn/io_dsn.pup =================================================================== --- tags/2.3.0/src_plugins/io_dsn/io_dsn.pup (nonexistent) +++ tags/2.3.0/src_plugins/io_dsn/io_dsn.pup (revision 33253) @@ -0,0 +1,12 @@ +$class io +$short specctra .dsn +$long Load and save specctra DSN files +$state works +$fmt-native no +$fmt-feature-r dsn board +$fmt-feature-w dsn board +$package io-alien +dep lib_gensexpr +dep lib_netmap +default disable +autoload 1 Index: tags/2.3.0/src_plugins/io_dsn/read.c =================================================================== --- tags/2.3.0/src_plugins/io_dsn/read.c (nonexistent) +++ tags/2.3.0/src_plugins/io_dsn/read.c (revision 33253) @@ -0,0 +1,1876 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * dsn IO plugin - file format read, parser + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "plug_io.h" +#include +#include +#include +#include +#include "layer_grp.h" +#include "conf_core.h" +#include +#include +#include "netlist.h" +#include + +#include "read.h" + +typedef struct { + gsxl_dom_t dom; + pcb_board_t *pcb; + const rnd_unit_t *unit; + rnd_box_t bbox; /* board's bbox from the boundary subtrees, in the file's coordinate system */ + htsp_t name2layer; + htsp_t protos; /* padstack prototypes - allocated for the hash, copied on placement */ + htsp_t subcs; /* subc images - allocated for the hash, copied on placement */ + rnd_cardinal_t testpoint; + unsigned has_pcb_boundary:1; + unsigned has_testpoint:1; +} dsn_read_t; + +static char *STR(gsxl_node_t *node) +{ + if (node == NULL) + return NULL; + return node->str; +} + +static char *STRE(gsxl_node_t *node) +{ + if (node == NULL) + return ""; + if (node->str == NULL) + return ""; + return node->str; +} + +/* check if node is named name and if so, save the node in nname for + later reference; assumes node->str is not NULL */ +#define if_save_uniq(node, name) \ + if (rnd_strcasecmp(node->str, #name) == 0) { \ + if (n ## name != NULL) { \ + rnd_message(RND_MSG_ERROR, "Multiple " #name " nodes where only one is expected (at %ld:%ld)\n", (long)node->line, (long)node->col); \ + return -1; \ + } \ + n ## name = node; \ + } + +static rnd_coord_t COORD(dsn_read_t *ctx, gsxl_node_t *n) +{ + char *end, *s = STRE(n); + double v = strtod(s, &end); + + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Invalid coord: '%s' (at %ld:%ld)\n", s, (long)n->line, (long)n->col); + return 0; + } + v /= ctx->unit->scale_factor; + if (ctx->unit->family == RND_UNIT_METRIC) + return RND_MM_TO_COORD(v); + return RND_MIL_TO_COORD(v); +} + +#define COORDX(ctx, n) COORD(ctx, n) +#define COORDY(ctx, n) (ctx->bbox.Y2 - COORD(ctx, n)) + +/* load coordinates from nodes starting from src, hoppin on ->next, into + rnd_coord_t dst[]. Each coord is converted according to the next char + in const char *fmt[]; 'c' is raw coord, 'x' and 'y' are board coords, + 'X' and 'Y' are relative coords */ +#define DSN_LOAD_COORDS_FMT(dst, src, fmt, err_statement) \ + do { \ + int __i__; \ + gsxl_node_t *__n__ = (src); \ + const char *__fmt__ = (fmt); \ + for(__i__ = 0; __fmt__[__i__] != '\0'; __i__++) { \ + if (__n__ == NULL) { err_statement; } \ + switch(__fmt__[__i__]) { \ + case 'c': dst[__i__] = COORD(ctx, __n__); break; \ + case 'x': dst[__i__] = COORDX(ctx, __n__); break; \ + case 'y': dst[__i__] = COORDY(ctx, __n__); break; \ + case 'X': dst[__i__] = COORD(ctx, __n__); break; \ + case 'Y': dst[__i__] = COORD(ctx, __n__); if (dst[__i__] != 0) dst[__i__] = -dst[__i__]; break; \ + } \ + __n__ = __n__->next; \ + } \ + } while(0) + +static const rnd_unit_t *push_unit(dsn_read_t *ctx, gsxl_node_t *nu) +{ + const rnd_unit_t *old = ctx->unit; + char *su, *s; + + if ((nu == NULL) || (nu->children == NULL)) + return ctx->unit; + + for(su = s = STRE(gsxl_children(nu)); *s != '\0'; s++) + *s = tolower(*s); + + ctx->unit = rnd_get_unit_struct(su); + if (ctx->unit == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid unit: '%s' (at %ld:%ld)\n", su, (long)nu->line, (long)nu->col); + return NULL; + } + + return old; +} + +static void pop_unit(dsn_read_t *ctx, const rnd_unit_t *saved) +{ + ctx->unit = saved; +} + +/* Search a subtree for a unit descriptor and push it and return the old. + Returns NULL if nothing found/pushed */ +static const rnd_unit_t *dsn_set_old_unit(dsn_read_t *ctx, gsxl_node_t *nd) +{ + const rnd_unit_t *old_unit = NULL; + gsxl_node_t *n; + + for(n = nd; n != NULL; n = n->next) { + if ((n->str != NULL) && ((rnd_strcasecmp(n->str, "unit") == 0) || (rnd_strcasecmp(n->str, "resolution") == 0))) { + old_unit = push_unit(ctx, n); + break; + } + } + + return old_unit; +} + +/*** tree parse ***/ + +static int dsn_parse_wire(dsn_read_t *ctx, gsxl_node_t *wrr, pcb_subc_t *subc, pcb_layer_t *force_ly); + +static rnd_coord_t dsn_load_aper(dsn_read_t *ctx, gsxl_node_t *c) +{ + rnd_coord_t res = COORD(ctx, c); + if (res == 0) + res = 1; + return res; +} + +static void parse_attribute(dsn_read_t *ctx, pcb_attribute_list_t *attr, gsxl_node_t *kv) +{ + for(;kv != NULL; kv = kv->next) + pcb_attribute_put(attr, STRE(kv), STRE(kv->children)); +} + +static int dsn_parse_rect(dsn_read_t *ctx, rnd_box_t *dst, gsxl_node_t *src, int no_y_flip) +{ + rnd_coord_t x, y; + + if (src == NULL) { + rnd_message(RND_MSG_ERROR, "Missing coord in rect\n"); + return -1; + } + + /* set all corners to first x;y */ + dst->X1 = dst->X2 = COORDX(ctx, src); + if (src->next == NULL) goto err; + src = src->next; + if (no_y_flip) + dst->Y1 = dst->Y2 = COORD(ctx, src); + else + dst->Y1 = dst->Y2 = COORDY(ctx, src); + if (src->next == NULL) goto err; + src = src->next; + + /* bump with second x;y */ + x = COORDX(ctx, src); + if (src->next == NULL) goto err; + src = src->next; + if (no_y_flip) + y = COORD(ctx, src); + else + y = COORDY(ctx, src); + rnd_box_bump_point(dst, x, y); + return 0; + + err:; + rnd_message(RND_MSG_ERROR, "Missing coord in rect (at %ld:%ld)\n", (long)src->line, (long)src->col); + return -1; +} + + +static int dsn_parse_rule(dsn_read_t *ctx, gsxl_node_t *rule) +{ + if ((rule == NULL) || (rule->str == NULL)) + return 0; + if (rnd_strcasecmp(rule->str, "width") == 0) + rnd_conf_set_design("design/min_wid", "%$mS", COORD(ctx, rule->children)); + /* the rest of the rules do not have a direct mapping in the current DRC code */ + return 0; +} + +static void boundary_line(pcb_layer_t *oly, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t aper) +{ + if (aper <= 0) + aper = 1; + pcb_line_new(oly, x1, y1, x2, y2, aper, 0, pcb_no_flags()); +} + +static int dsn_parse_boundary_(dsn_read_t *ctx, gsxl_node_t *bnd, int do_bbox, pcb_layer_t *oly) +{ + gsxl_node_t *b, *n; + for(bnd = bnd->children; bnd != NULL; bnd = bnd->next) { + if (bnd->str == NULL) + continue; + if (rnd_strcasecmp(bnd->str, "path") == 0) { + rnd_coord_t x, y, lx, ly, fx, fy, aper; + int len; + + b = gsxl_children(bnd); + if (!do_bbox && (rnd_strcasecmp(STRE(b), "pcb") == 0)) { + rnd_message(RND_MSG_ERROR, "PCB boundary shall be a rect, not a path;\naccepting the path, but other software may choke on this file\n"); + ctx->has_pcb_boundary = 1; + } + if ((b->next == NULL) || (b->next->next == NULL)) { + rnd_message(RND_MSG_ERROR, "not enough arguments for boundary poly (at %ld:%ld)\n", (long)b->line, (long)b->col); + return -1; + } + + aper = COORD(ctx, b->next); + + for(len = 0, n = b->next->next; n != NULL; len++) { + x = COORDX(ctx, n); + if (n->next == NULL) { + rnd_message(RND_MSG_ERROR, "Not enough coordinate values (missing y)\n"); + break; + } + n = n->next; + if (do_bbox) + y = COORD(ctx, n); + else + y = COORDY(ctx, n); + n = n->next; + if (!do_bbox) { + if (len == 0) { + fx = x; + fy = y; + } + else + boundary_line(oly, lx, ly, x, y, aper); + lx = x; + ly = y; + } + else + rnd_box_bump_point(&ctx->bbox, x, y); + } + if (!do_bbox && (x != fx) && (y != fy)) /* close the boundary */ + boundary_line(oly, lx, ly, x, y, aper); + } + else if (rnd_strcasecmp(bnd->str, "rect") == 0) { + rnd_box_t box; + + b = gsxl_children(bnd); + if ((b->next == NULL) || (b->next->next == NULL)) { + rnd_message(RND_MSG_ERROR, "not enough arguments for boundary rect (at %ld:%ld)\n", (long)b->line, (long)b->col); + return -1; + } + if (rnd_strcasecmp(STRE(b), "pcb") == 0) + ctx->has_pcb_boundary = 1; + if (dsn_parse_rect(ctx, &box, b->next, do_bbox) != 0) + return -1; + if (!do_bbox) { + boundary_line(oly, box.X1, box.Y1, box.X1, box.Y2, 0); + boundary_line(oly, box.X1, box.Y2, box.X2, box.Y2, 0); + boundary_line(oly, box.X2, box.Y2, box.X1, box.Y2, 0); + boundary_line(oly, box.X1, box.Y2, box.X1, box.Y1, 0); + } + else + rnd_box_bump_box(&ctx->bbox, &box); + } + } + return 0; +} + +static int dsn_parse_boundary(dsn_read_t *ctx, gsxl_node_t *bnd) +{ + int res; + rnd_layer_id_t olid; + pcb_layer_t *oly; + + if (bnd == NULL) + return 0; + + if (pcb_layer_list(ctx->pcb, PCB_LYT_BOUNDARY, &olid, 1) < 1) { + rnd_message(RND_MSG_ERROR, "Intenal error: no boundary layer found\n"); + return -1; + } + oly = pcb_get_layer(ctx->pcb->Data, olid); + + + res = dsn_parse_boundary_(ctx, bnd, 1, oly); + res |= dsn_parse_boundary_(ctx, bnd, 0, oly); + if (res != 0) + return -1; + + + return 0; +} + +static int parse_layer_type(dsn_read_t *ctx, pcb_layergrp_t *grp, const char *ty) +{ + if ((rnd_strcasecmp(ty, "signal") == 0) || (rnd_strcasecmp(ty, "jumper") == 0)) + return 0; /* nothig special to do */ + if ((rnd_strcasecmp(ty, "power") == 0) || (rnd_strcasecmp(ty, "mixed") == 0)) { + pcb_attribute_put(&grp->Attributes, "plane", ty); + return 0; + } + + rnd_message(RND_MSG_WARNING, "Ignoring unknown layer type '%s' for %s\n", ty, grp->name); + return 0; +} + +#define CHECK_TOO_MANY_LAYERS(node, num) \ +do { \ + if (num >= PCB_MAX_LAYERGRP) { \ + rnd_message(RND_MSG_ERROR, "Too many layer groups in the layer stack (at %ld:%ld)\n", (long)node->line, (long)node->col); \ + return -1; \ + } \ +} while(0) + +static int dsn_parse_structure(dsn_read_t *ctx, gsxl_node_t *str) +{ + const pcb_dflgmap_t *m; + gsxl_node_t *n, *i; + pcb_layergrp_t *topcop = NULL, *botcop = NULL, *grp; + rnd_layergrp_id_t gid; + const rnd_unit_t *old_unit; + const pcb_dflgmap_t doclayers[] = { + {"top_outline", PCB_LYT_TOP | PCB_LYT_DOC, "outline", PCB_LYC_AUTO, 0}, + {"bot_outline", PCB_LYT_BOTTOM | PCB_LYT_DOC, "outline", PCB_LYC_AUTO, 0}, + {"top_all_keepout", PCB_LYT_TOP | PCB_LYT_DOC, "all_keepout", PCB_LYC_AUTO, 0}, + {"bot_all_keepout", PCB_LYT_BOTTOM | PCB_LYT_DOC, "all_keepout", PCB_LYC_AUTO, 0}, + {"top_copper_keepout", PCB_LYT_TOP | PCB_LYT_DOC, "copper_keepout", PCB_LYC_AUTO, 0}, + {"bot_copper_keepout", PCB_LYT_BOTTOM | PCB_LYT_DOC, "copper_keepout", PCB_LYC_AUTO, 0}, + {"top_subc_keepout", PCB_LYT_TOP | PCB_LYT_DOC, "subc_keepout", PCB_LYC_AUTO, 0}, + {"bot_subc_keepout", PCB_LYT_BOTTOM | PCB_LYT_DOC, "subc_keepout", PCB_LYC_AUTO, 0}, + {"top_via_keepout", PCB_LYT_TOP | PCB_LYT_DOC, "via_keepout", PCB_LYC_AUTO, 0}, + {"bot_via_keepout", PCB_LYT_BOTTOM | PCB_LYT_DOC, "via_keepout", PCB_LYC_AUTO, 0}, + {NULL, 0} + }; + + if (str == NULL) { + rnd_message(RND_MSG_ERROR, "Can not parse board without a structure subtree\n"); + return -1; + } + + old_unit = dsn_set_old_unit(ctx, str->children); + + pcb_layergrp_inhibit_inc(); + for(m = pcb_dflgmap; m <= pcb_dflgmap_last_top_noncopper; m++) { + CHECK_TOO_MANY_LAYERS(str, ctx->pcb->LayerGroups.len); + pcb_layergrp_set_dflgly(ctx->pcb, &ctx->pcb->LayerGroups.grp[ctx->pcb->LayerGroups.len++], m, NULL, NULL); + } + + for(n = str->children; n != NULL; n = n->next) { + if (n->str == NULL) + continue; + else if (rnd_strcasecmp(n->str, "layer") == 0) { + pcb_layer_t *ly; + + if (botcop != NULL) { + CHECK_TOO_MANY_LAYERS(n, ctx->pcb->LayerGroups.len); + pcb_layergrp_set_dflgly(ctx->pcb, &ctx->pcb->LayerGroups.grp[ctx->pcb->LayerGroups.len++], &pcb_dflg_substrate, NULL, NULL); + } + CHECK_TOO_MANY_LAYERS(n, ctx->pcb->LayerGroups.len); + botcop = &ctx->pcb->LayerGroups.grp[ctx->pcb->LayerGroups.len++]; + if (topcop == NULL) + topcop = botcop; + pcb_layergrp_set_dflgly(ctx->pcb, botcop, &pcb_dflg_int_copper, STR(gsxl_children(n)), STR(gsxl_children(n))); + + ly = pcb_get_layer(ctx->pcb->Data, botcop->lid[0]); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "io_dsn internal error: no layer in group\n"); + return -1; + } + htsp_set(&ctx->name2layer, (char *)ly->name, ly); + + if (n->children != NULL) { + for(i = n->children->next; i != NULL; i = i->next) { + if (rnd_strcasecmp(i->str, "type") == 0) { + if (parse_layer_type(ctx, botcop, STRE(i->children)) != 0) + return -1; + } + else if (rnd_strcasecmp(i->str, "property") == 0) { + parse_attribute(ctx, &botcop->Attributes, i->children); + } + } + } + } + } + + if (topcop == NULL) { + rnd_message(RND_MSG_ERROR, "Can not parse board without a copper layers\n"); + return -1; + } + + topcop->ltype = PCB_LYT_TOP | PCB_LYT_COPPER; + botcop->ltype = PCB_LYT_BOTTOM | PCB_LYT_COPPER; + + CHECK_TOO_MANY_LAYERS(str, ctx->pcb->LayerGroups.len); + pcb_layergrp_set_dflgly(ctx->pcb, &ctx->pcb->LayerGroups.grp[ctx->pcb->LayerGroups.len++], &pcb_dflg_outline, NULL, NULL); + + for(m = pcb_dflgmap_first_bottom_noncopper; m->name != NULL; m++) { + CHECK_TOO_MANY_LAYERS(str, ctx->pcb->LayerGroups.len); + pcb_layergrp_set_dflgly(ctx->pcb, &ctx->pcb->LayerGroups.grp[ctx->pcb->LayerGroups.len++], m, NULL, NULL); + } + + /* create documentation layers */ + for(m = doclayers; m->name != NULL; m++) { + pcb_layergrp_t *grp; +/* pcb_layer_t *ly;*/ + + CHECK_TOO_MANY_LAYERS(str, ctx->pcb->LayerGroups.len); + grp = &ctx->pcb->LayerGroups.grp[ctx->pcb->LayerGroups.len++]; + pcb_layergrp_set_dflgly(ctx->pcb, grp, m, NULL, NULL); + +/* overridden by the GUI logic: + grp->vis = 0; + ly = pcb_get_layer(ctx->pcb->Data, grp->lid[0]); + ly->meta.real.vis = 0;*/ + } + + + pcb_layergrp_inhibit_dec(); + + ctx->has_pcb_boundary = 0; + for(n = str->children; n != NULL; n = n->next) { + if (n->str == NULL) + continue; + else if (rnd_strcasecmp(n->str, "boundary") == 0) { + if (dsn_parse_boundary(ctx, n) != 0) + return -1; + } + else if (rnd_strcasecmp(n->str, "rule") == 0) { + if (dsn_parse_rule(ctx, n->children) != 0) + return -1; + } + } + + if ((ctx->bbox.X1 < 0) || (ctx->bbox.Y1 < 0)) + rnd_message(RND_MSG_WARNING, "Negative coordinates on input - you may want to execute autocrop()\n"); + + ctx->pcb->hidlib.size_x = ctx->bbox.X2 - ctx->bbox.X1; + ctx->pcb->hidlib.size_y = ctx->bbox.Y2 - ctx->bbox.Y1; + + if (!ctx->has_pcb_boundary) { + ctx->bbox.X1 = ctx->bbox.Y1 = ctx->bbox.X2 = ctx->bbox.Y2 = 0; + rnd_message(RND_MSG_ERROR, "Missing pcb boundary; every dsn design must have a pcb boundary.\ntrying to make up one using the bounding box.\nYou may want to execute autocrop()\n"); + } + + /* place polygons on planes */ + for(gid = 0, grp = ctx->pcb->LayerGroups.grp; gid < ctx->pcb->LayerGroups.len; gid++,grp++) { + if (pcb_attribute_get(&grp->Attributes, "plane") != NULL) { + pcb_layer_t *ly; + if (!ctx->has_pcb_boundary) { + rnd_message(RND_MSG_ERROR, "Because of the missing pcb boundary power planes are not filled with polygons.\n"); + return 0; + } + ly = pcb_get_layer(ctx->pcb->Data, grp->lid[0]); + pcb_poly_new_from_rectangle(ly, ctx->bbox.X1, ctx->bbox.Y2 - ctx->bbox.Y1, ctx->bbox.X2, 0, conf_core.design.clearance, pcb_flag_make(PCB_FLAG_CLEARPOLY)); + } + } + + if (old_unit != NULL) + pop_unit(ctx, old_unit); + + return 0; +} + +int dsn_parse_pstk_shape_circle(dsn_read_t *ctx, gsxl_node_t *nd, pcb_pstk_shape_t *shp) +{ + gsxl_node_t *args = nd->children->next; + + if ((args == NULL) || (args->str == NULL)) { + rnd_message(RND_MSG_ERROR, "Padstack circle: not enough arguments (at %ld:%ld)\n", (long)nd->line, (long)nd->col); + return -1; + } + + shp->shape = PCB_PSSH_CIRC; + shp->data.circ.dia = COORD(ctx, args); + if (args->next != NULL) { + shp->data.circ.x = COORD(ctx, args->next); + shp->data.circ.y = COORD(ctx, args->next->next); + if (shp->data.circ.y != 0) + shp->data.circ.y = -shp->data.circ.y; + } + else + shp->data.circ.x = shp->data.circ.y = 0; + + return 0; +} + +int dsn_parse_pstk_shape_rect(dsn_read_t *ctx, gsxl_node_t *nd, pcb_pstk_shape_t *shp) +{ + rnd_box_t box; + gsxl_node_t *args = nd->children->next; + + if (dsn_parse_rect(ctx, &box, args, 1) != 0) + return -1; + + shp->shape = PCB_PSSH_POLY; + pcb_pstk_shape_alloc_poly(&shp->data.poly, 4); + + if (box.Y1 != 0) box.Y1 = -box.Y1; + if (box.Y2 != 0) box.Y2 = -box.Y2; + + shp->data.poly.x[0] = box.X1; shp->data.poly.y[0] = box.Y1; + shp->data.poly.x[1] = box.X2; shp->data.poly.y[1] = box.Y1; + shp->data.poly.x[2] = box.X2; shp->data.poly.y[2] = box.Y2; + shp->data.poly.x[3] = box.X1; shp->data.poly.y[3] = box.Y2; + + pcb_pstk_shape_update_pa(&shp->data.poly); + + return 0; +} + +int dsn_parse_pstk_shape_path(dsn_read_t *ctx, gsxl_node_t *nd, pcb_pstk_shape_t *shp) +{ + gsxl_node_t *extra; + gsxl_node_t *th = nd->children->next, *args = th->next; + + if ((args == NULL) || (args->next == NULL) || (args->next->next == NULL) || (args->next->next->next == NULL)) { + rnd_message(RND_MSG_ERROR, "Padstack path: not enough arguments (at %ld:%ld)\n", (long)nd->line, (long)nd->col); + return -1; + } + + extra = args->next->next->next->next; + if ((extra != NULL) && (!isalpha(*extra->str))) { + rnd_message(RND_MSG_ERROR, "Padstack path: too many arguments - only a single line supported (at %ld:%ld)\n", (long)nd->line, (long)nd->col); + return -1; + } + + shp->shape = PCB_PSSH_LINE; + shp->data.line.x1 = COORD(ctx, args); + shp->data.line.y1 = COORD(ctx, args->next); + shp->data.line.x2 = COORD(ctx, args->next->next); + shp->data.line.y2 = COORD(ctx, args->next->next->next); + shp->data.line.thickness = COORD(ctx, th); + + if (shp->data.line.y1 != 0) shp->data.line.y1 = -shp->data.line.y1; + if (shp->data.line.y2 != 0) shp->data.line.y2 = -shp->data.line.y2; + + return 0; +} + +int dsn_parse_pstk_shape_poly(dsn_read_t *ctx, gsxl_node_t *nd, pcb_pstk_shape_t *shp) +{ + gsxl_node_t *n, *ap = nd->children->next, *args = ap->next; + rnd_coord_t aper; + long len, i; + + for(len = 0, n = args; (n != NULL) && !(isalpha(*n->str)); n = n->next, len++) ; + + if (len < 3) { + rnd_message(RND_MSG_ERROR, "Padstack poly: too few points (at %ld:%ld)\n", (long)nd->line, (long)nd->col); + return -1; + } + + if ((len % 2) != 0) { + rnd_message(RND_MSG_ERROR, "Padstack poly: wrong (odd) number of arguments (at %ld:%ld)\n", (long)nd->line, (long)nd->col); + return -1; + } + + shp->shape = PCB_PSSH_POLY; + pcb_pstk_shape_alloc_poly(&shp->data.poly, len/2); + for(n = args, i = 0; n != NULL; n = n->next, i++) { + shp->data.poly.x[i] = COORD(ctx, n); + n = n->next; + shp->data.poly.y[i] = COORD(ctx, n); + if (shp->data.poly.y[i] != 0) + shp->data.poly.y[i] = -shp->data.poly.y[i]; + } + + aper = COORD(ctx, ap); + if (aper > 0) + pcb_pstk_shape_grow_(shp, 0, aper); + + pcb_pstk_shape_update_pa(&shp->data.poly); + + return 0; +} + +int dsn_parse_pstk_shape_plating(dsn_read_t *ctx, gsxl_node_t *plt, pcb_pstk_proto_t *prt) +{ + if ((plt->children == NULL) || (plt->children->str == NULL)) + return 0; + if (rnd_strcasecmp(plt->children->str, "plated") == 0) + prt->hplated = 1; + return 0; +} + +static int dsn_parse_lib_padstack_shp(dsn_read_t *ctx, gsxl_node_t *sn, pcb_pstk_shape_t *shp) +{ + memset(shp, 0, sizeof(pcb_pstk_shape_t)); + if ((sn == NULL) || (sn->str == NULL)) { + rnd_message(RND_MSG_ERROR, "Invalid padstack shape (at %ld:%ld)\n", (long)sn->line, (long)sn->col); + return -1; + } + if (rnd_strcasecmp(sn->str, "circle") == 0) { + if (dsn_parse_pstk_shape_circle(ctx, sn, shp) != 0) + return -1; + } + else if (rnd_strcasecmp(sn->str, "rect") == 0) { + if (dsn_parse_pstk_shape_rect(ctx, sn, shp) != 0) + return -1; + } + else if ((rnd_strcasecmp(sn->str, "polygon") == 0) || (rnd_strcasecmp(sn->str, "poly") == 0)) { + if (dsn_parse_pstk_shape_poly(ctx, sn, shp) != 0) + return -1; + } + else if (rnd_strcasecmp(sn->str, "path") == 0) { + if (dsn_parse_pstk_shape_path(ctx, sn, shp) != 0) + return -1; + } + else if (rnd_strcasecmp(sn->str, "qarc") == 0) { + rnd_message(RND_MSG_ERROR, "Unsupported padstack shape %s (at %ld:%ld)\n", sn->str, (long)sn->line, (long)sn->col); + return -1; + } + else { + rnd_message(RND_MSG_ERROR, "Invalid/unknown padstack shape %s (at %ld:%ld)\n", sn->str, (long)sn->line, (long)sn->col); + return -1; + } + return 0; +} + +/* Return a PCB_LYT_TOP, PCB_LYT_BOTTOM, PCB_LYT_INTERN or 0 for global; + return -1 for invalid layer name */ +static pcb_layer_type_t dsn_pstk_shape_layer(dsn_read_t *ctx, gsxl_node_t *net) +{ + const char *nname= STRE(net); + pcb_layer_t *ly; + + if ((rnd_strcasecmp(nname, "signal") == 0) || (rnd_strcasecmp(nname, "power") == 0)) + return 0; + + ly = htsp_get(&ctx->name2layer, nname); \ + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid/unknown net '%s' (at %ld:%ld)\n", nname, (long)net->line, (long)net->col); + return -1; + } + + return pcb_layer_flags_(ly) & PCB_LYT_ANYWHERE; +} + + +static void dsn_pstk_set_shape_(pcb_pstk_proto_t *prt, pcb_layer_type_t lyt, pcb_pstk_shape_t *shp, gsxl_node_t *nd) +{ + pcb_pstk_shape_t *existing = NULL; + int n; + + shp->layer_mask = lyt; + + for(n = 0; n < prt->tr.array[0].len; n++) { + if (lyt == prt->tr.array[0].shape[n].layer_mask) { + existing = &prt->tr.array[0].shape[n]; + break; + } + } + + if (existing == NULL) { + pcb_pstk_shape_t *newshp = pcb_pstk_alloc_append_shape(&prt->tr.array[0]); + pcb_pstk_shape_copy(newshp, shp); + return; + } + + if (pcb_pstk_shape_eq(existing, shp)) + return; + + rnd_message(RND_MSG_WARNING, "Incompatible padstack: some shape details are lost (at %ld:%ld)\n", (long)nd->line, (long)nd->col); +} + +static void dsn_pstk_set_shape(pcb_pstk_proto_t *prt, pcb_layer_type_t lyt, pcb_pstk_shape_t *shp, gsxl_node_t *nd) +{ + if (lyt == 0) { + dsn_pstk_set_shape_(prt, PCB_LYT_TOP | PCB_LYT_COPPER, shp, nd); + dsn_pstk_set_shape_(prt, PCB_LYT_INTERN | PCB_LYT_COPPER, shp, nd); + dsn_pstk_set_shape_(prt, PCB_LYT_BOTTOM | PCB_LYT_COPPER, shp, nd); + } + else + dsn_pstk_set_shape_(prt, lyt | PCB_LYT_COPPER, shp, nd); + pcb_pstk_shape_free(shp); +} + +static int dsn_parse_lib_padstack(dsn_read_t *ctx, gsxl_node_t *wrr) +{ + const rnd_unit_t *old_unit; + gsxl_node_t *n; + pcb_pstk_proto_t *prt; + pcb_pstk_shape_t hole; + int has_hole = 0; + + if ((wrr->children == NULL) || (wrr->children->str == NULL)) { + rnd_message(RND_MSG_WARNING, "Empty padstack (at %ld:%ld)\n", (long)wrr->line, (long)wrr->col); + return -1; + } + + prt = calloc(sizeof(pcb_pstk_proto_t), 1); + pcb_vtpadstack_tshape_alloc_append(&prt->tr, 1); + + prt->name = rnd_strdup(wrr->children->str); + + old_unit = dsn_set_old_unit(ctx, wrr->children->next); + + for(n = wrr->children; n != NULL; n = n->next) { + if (n->str == NULL) + continue; + if (rnd_strcasecmp(n->str, "shape") == 0) { + pcb_pstk_shape_t shp; + pcb_layer_type_t lyt; + + lyt = dsn_pstk_shape_layer(ctx, n->children->children); + if (lyt < 0) + goto err; + + if (dsn_parse_lib_padstack_shp(ctx, n->children, &shp) != 0) + goto err; + + dsn_pstk_set_shape(prt, lyt, &shp, n); + } + else if (rnd_strcasecmp(n->str, "hole") == 0) { + pcb_pstk_shape_t shp; + + if (has_hole) { + if (dsn_parse_lib_padstack_shp(ctx, n->children, &shp) != 0) + goto err; + + if (!pcb_pstk_shape_eq(&hole, &shp)) + rnd_message(RND_MSG_WARNING, "Incompatible padstack: non-uniform hole geometry; keeping one hole shape randomly (at %ld:%ld)\n", (long)n->line, (long)n->col); + + pcb_pstk_shape_free(&shp); + } + else { + if (dsn_parse_lib_padstack_shp(ctx, n->children, &hole) != 0) + goto err; + has_hole = 1; + } + } + else if (rnd_strcasecmp(n->str, "antipad") == 0) { + /* silently not supported */ + } + else if (rnd_strcasecmp(n->str, "plating") == 0) { + if (dsn_parse_pstk_shape_plating(ctx, n, prt) != 0) + goto err; + } + else if ((rnd_strcasecmp(n->str, "rotate") == 0) || (rnd_strcasecmp(n->str, "absolute") == 0)) { + if (rnd_strcasecmp(STRE(n->children), "off") == 0) { + rnd_message(RND_MSG_WARNING, "unhandled padstack flag %s (at %ld:%ld) - this property will be ignored\n", n->str, (long)n->line, (long)n->col); + } + } + } + + if (has_hole) { + if ((hole.shape == PCB_PSSH_CIRC) && (hole.data.circ.x == 0) && (hole.data.circ.y == 0)) { + /* simple, concentric hole: convert to a single-dia hole */ + prt->hdia = hole.data.circ.dia; + } + else { + /* non-circular or non-concentric hole: slot on the mech layer */ + pcb_pstk_shape_t *newshp = pcb_pstk_alloc_append_shape(&prt->tr.array[0]); + hole.layer_mask = PCB_LYT_MECH; + hole.comb = PCB_LYC_AUTO; + pcb_pstk_shape_copy(newshp, &hole); + pcb_pstk_shape_free(&hole); + } + } + + pcb_pstk_proto_update(prt); + htsp_set(&ctx->protos, prt->name, prt); + + if (old_unit != NULL) + pop_unit(ctx, old_unit); + + return 0; + err:; + pcb_pstk_proto_free_fields(prt); + free(prt); + return -1; +} + + +static int dsn_parse_img_via(dsn_read_t *ctx, gsxl_node_t *pn, pcb_subc_t *subc) +{ + const char *psname = STRE(pn->children); + gsxl_node_t *ncoord; + pcb_pstk_proto_t *proto; + + if ((psname == NULL) || (*psname == '\0')) { + rnd_message(RND_MSG_ERROR, "Invalid anonymous via (at %ld:%ld)\n", (long)pn->line, (long)pn->col); + return -1; + } + + proto = htsp_get(&ctx->protos, psname); + if (proto == NULL) { + rnd_message(RND_MSG_ERROR, "Unknown via '%s' (at %ld:%ld)\n", psname, (long)pn->line, (long)pn->col); + return -1; + } + + for(ncoord = pn->children->next; ncoord != NULL; ncoord = ncoord->next->next) { + rnd_coord_t crd[2]; + rnd_cardinal_t pid; + + DSN_LOAD_COORDS_FMT(crd, ncoord, "XY", goto err_coord); + pid = pcb_pstk_proto_insert_dup(subc->data, proto, 1, 0); + pcb_pstk_new(subc->data, -1, pid, crd[0], crd[1], conf_core.design.clearance/2, pcb_flag_make(PCB_FLAG_CLEARLINE)); + } + + return 0; + err_coord:; + rnd_message(RND_MSG_ERROR, "Invalid via coordinates (at %ld:%ld)\n", (long)pn->line, (long)pn->col); + return -1; +} + +static int dsn_parse_img_pin(dsn_read_t *ctx, gsxl_node_t *pn, pcb_subc_t *subc) +{ + gsxl_node_t *ncoord, *nrot; + const char *term, *psname = STRE(pn->children); + pcb_pstk_proto_t *proto; + pcb_pstk_t *ps; + rnd_cardinal_t pid; + rnd_coord_t crd[2] = {0, 0}; + double rotang = 0.0; + + if ((psname == NULL) || (*psname == '\0')) { + rnd_message(RND_MSG_ERROR, "Invalid anonymous pin (at %ld:%ld)\n", (long)pn->line, (long)pn->col); + return -1; + } + + proto = htsp_get(&ctx->protos, psname); + if (proto == NULL) { + rnd_message(RND_MSG_ERROR, "Unknown pin '%s' (at %ld:%ld)\n", psname, (long)pn->line, (long)pn->col); + return -1; + } + + if (pn->children->next == NULL) { + rnd_message(RND_MSG_ERROR, "Missing pin terminal ID (at %ld:%ld)\n", (long)pn->line, (long)pn->col); + return -1; + } + + term = STRE(pn->children->next); + ncoord = pn->children->next->next; + DSN_LOAD_COORDS_FMT(crd, ncoord, "XY", goto err_coord); + + nrot = ncoord->next->next; + if ((nrot != NULL) && (nrot->str != NULL) && (rnd_strcasecmp(nrot->str, "rotate") == 0)) { + char *end; + rotang = strtod(STRE(nrot->children), &end); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Invalid pin rotation angle (at %ld:%ld)\n", (long)pn->line, (long)pn->col); + return -1; + } + } + + pid = pcb_pstk_proto_insert_dup(subc->data, proto, 1, 0); + ps = pcb_pstk_new(subc->data, -1, pid, crd[0], crd[1], conf_core.design.clearance/2, pcb_flag_make(PCB_FLAG_CLEARLINE)); + if (ps != NULL) { + if (rotang != 0.0) { + ps->rot = rotang; + pcb_pstk_bbox(ps); + } + pcb_attribute_put(&ps->Attributes, "term", term); + } + else + rnd_message(RND_MSG_ERROR, "Failed to create via - expect missing vias (at %ld:%ld)\n", (long)pn->line, (long)pn->col); + + return 0; + err_coord:; + rnd_message(RND_MSG_ERROR, "Invalid pin coordinates (at %ld:%ld)\n", (long)pn->line, (long)pn->col); + return -1; +} + +static int dsn_parse_img_conductor(dsn_read_t *ctx, gsxl_node_t *imr, pcb_subc_t *subc) +{ + return dsn_parse_wire(ctx, imr, subc, NULL); +} + +static int dsn_parse_img_hardwired(dsn_read_t *ctx, gsxl_node_t *nd, pcb_subc_t *subc, pcb_layer_type_t lyt, const char *purpose) +{ + pcb_layer_t *ly; + int n, found; + for(n = 0, found = 0, ly = subc->data->Layer; n < subc->data->LayerN; n++,ly++) { + if ((ly->meta.bound.type & lyt) && (strcmp(ly->meta.bound.purpose, purpose) == 0)) { + found = 1; + break; + } + } + if (!found) { + rnd_message(RND_MSG_ERROR, "Internal error: subc doc outline layer (at %ld:%ld)\n", (long)nd->line, (long)nd->col); + return -1; + } + return dsn_parse_wire(ctx, nd, subc, ly); +} + +static int dsn_parse_img_outline(dsn_read_t *ctx, gsxl_node_t *nd, pcb_subc_t *subc) +{ + return dsn_parse_img_hardwired(ctx, nd, subc, PCB_LYT_DOC, "outline"); +} + +static int dsn_parse_img_keepout(dsn_read_t *ctx, gsxl_node_t *nd, const char *type, pcb_subc_t *subc) +{ + return dsn_parse_img_hardwired(ctx, nd, subc, PCB_LYT_DOC, type); +} + +static int dsn_parse_img_property(dsn_read_t *ctx, gsxl_node_t *nd, pcb_subc_t *subc) +{ + parse_attribute(ctx, &subc->Attributes, nd->children); + return 0; +} + +static int dsn_parse_lib_image(dsn_read_t *ctx, gsxl_node_t *imr) +{ + const rnd_unit_t *old_unit; + pcb_subc_t *subc; + char *id; + int n; + pcb_layer_t *ly, *nly; + + id = STRE(imr->children); + if ((id == NULL) || (*id == '\0')) { + rnd_message(RND_MSG_WARNING, "invalid empty image name (at %ld:%ld) - this property will be ignored\n", (long)imr->line, (long)imr->col); + return -1; + } + + old_unit = dsn_set_old_unit(ctx, imr->children); + + subc = pcb_subc_new(); + + /* create format-special bound layers first so lookup is fast */ + pcb_layer_new_bound(subc->data, PCB_LYT_DOC | PCB_LYT_TOP, "dsn outline", "outline"); + + /* create a bound layer for all board layers, just in case */ + for(n = 0, ly = ctx->pcb->Data->Layer; n < ctx->pcb->Data->LayerN; n++,ly++) { + const char *purp = NULL; + pcb_layer_type_t lyt = pcb_layer_flags_(ly); + + if (lyt & PCB_LYT_SUBSTRATE) + continue; + + pcb_layer_purpose_(ly, &purp); + nly = pcb_layer_new_bound(subc->data, lyt, ly->name, purp); + + if ((lyt & PCB_LYT_MASK) || (lyt & PCB_LYT_PASTE)) + nly->comb |= PCB_LYC_AUTO; + if (lyt & PCB_LYT_MASK) + nly->comb |= PCB_LYC_SUB; + } + + /* create less popular format-special bound layers at the end */ + pcb_layer_new_bound(subc->data, PCB_LYT_DOC | PCB_LYT_TOP, "all_keepout", "all_keepout"); + pcb_layer_new_bound(subc->data, PCB_LYT_DOC | PCB_LYT_TOP, "copper_keepout", "copper_keepout"); + pcb_layer_new_bound(subc->data, PCB_LYT_DOC | PCB_LYT_TOP, "subc_keepout", "subc_keepout"); + pcb_layer_new_bound(subc->data, PCB_LYT_DOC | PCB_LYT_TOP, "via_keepout", "via_keepout"); + + + for(imr = imr->children->next; imr != NULL; imr = imr->next) { + if (imr->str == NULL) + continue; + if (rnd_strcasecmp(imr->str, "outline") == 0) { + if (dsn_parse_img_outline(ctx, imr, subc) != 0) + return -1; + } + else if (rnd_strcasecmp(imr->str, "pin") == 0) { + if (dsn_parse_img_pin(ctx, imr, subc) != 0) + return -1; + } + else if (rnd_strcasecmp(imr->str, "conductor") == 0) { + if (dsn_parse_img_conductor(ctx, imr, subc) != 0) + return -1; + } + else if (rnd_strcasecmp(imr->str, "via") == 0) { + if (dsn_parse_img_via(ctx, imr, subc) != 0) + return -1; + } + else if (rnd_strcasecmp(imr->str, "keepout") == 0) { + if (dsn_parse_img_keepout(ctx, imr, "all", subc) != 0) + return -1; + } + else if (rnd_strcasecmp(imr->str, "wire_keepout") == 0) { + if (dsn_parse_img_keepout(ctx, imr, "copper", subc) != 0) + return -1; + } + else if (rnd_strcasecmp(imr->str, "place_keepout") == 0) { + if (dsn_parse_img_keepout(ctx, imr, "subc", subc) != 0) + return -1; + } + else if (rnd_strcasecmp(imr->str, "via_keepout") == 0) { + if (dsn_parse_img_keepout(ctx, imr, "via", subc) != 0) + return -1; + } + else if (rnd_strcasecmp(imr->str, "property") == 0) { + if (dsn_parse_img_property(ctx, imr, subc) != 0) + return -1; + } + } + + pcb_attribute_put(&subc->Attributes, "footprint", id); + id = pcb_attribute_get(&subc->Attributes, "footprint"); + htsp_set(&ctx->subcs, id, subc); + + if (old_unit != NULL) + pop_unit(ctx, old_unit); + return 0; +} + +static int dsn_parse_library(dsn_read_t *ctx, gsxl_node_t *wrr) +{ + const rnd_unit_t *old_unit; + gsxl_node_t *n; + + old_unit = dsn_set_old_unit(ctx, wrr->children); + + for(n = wrr->children; n != NULL; n = n->next) { + if ((n->str != NULL) && (rnd_strcasecmp(n->str, "padstack") == 0)) { + if (dsn_parse_lib_padstack(ctx, n) != 0) + return -1; + } + } + + for(n = wrr->children; n != NULL; n = n->next) { + if (n->str == NULL) + continue; + if (rnd_strcasecmp(n->str, "image") == 0) { + if (dsn_parse_lib_image(ctx, n) != 0) + return -1; + } + else if ((rnd_strcasecmp(n->str, "jumper") == 0) || (rnd_strcasecmp(n->str, "via_array_template") == 0) || (rnd_strcasecmp(n->str, "directory") == 0)) { + rnd_message(RND_MSG_WARNING, "unhandled library item %s (at %ld:%ld) - please send the dsn file as a bugreport\n", n->str, (long)n->line, (long)n->col); + } + } + + if (old_unit != NULL) + pop_unit(ctx, old_unit); + + return 0; +} + + +#define DSN_PARSE_NET(ly, net, fail, subc, force_ly) \ +do { \ + if (force_ly == NULL) { \ + gsxl_node_t *__net__ = (net); \ + const char *__nname__ = STRE(__net__); \ + if (subc != NULL) { \ + int __n__; \ + ly = NULL; \ + for(__n__ = 0; __n__ < subc->data->LayerN; __n__++) { \ + if (strcmp(subc->data->Layer[__n__].name, __nname__) == 0) { \ + ly = &subc->data->Layer[__n__]; \ + } \ + } \ + } \ + else \ + ly = htsp_get(&ctx->name2layer, __nname__); \ + if (ly == NULL) { \ + rnd_message(RND_MSG_ERROR, "Invalid/unknown net '%s' (at %ld:%ld)\n", __nname__, (long)__net__->line, (long)__net__->col); \ + { fail; } \ + } \ + } \ + else \ + ly = force_ly; \ +} while(0) + +static int dsn_parse_wire_poly(dsn_read_t *ctx, gsxl_node_t *wrr, pcb_subc_t *subc, pcb_layer_t *force_ly) +{ + gsxl_node_t *n, *net = wrr->children; + pcb_layer_t *ly; + rnd_coord_t aper; + rnd_coord_t x, y, fx, fy; + long len = 0; + pcb_poly_t *poly; + + DSN_PARSE_NET(ly, net, return -1, subc, force_ly); + + if ((net->next == NULL) || (net->next->next == NULL)) { + rnd_message(RND_MSG_ERROR, "Not enough wire polygon attributes (at %ld:%ld)\n", (long)wrr->line, (long)wrr->col); + return -1; + } + + aper = dsn_load_aper(ctx, net->next); + poly = pcb_poly_new(ly, conf_core.design.clearance, pcb_flag_make(PCB_FLAG_CLEARPOLYPOLY)); + for(n = net->next->next; n != NULL;) { + if (isalpha(*n->str)) + break; + x = COORDX(ctx, n); + if (n->next == NULL) { + rnd_message(RND_MSG_ERROR, "Not enough coordinate values (missing y)\n"); + break; + } + n = n->next; + if (subc != 0) { + y = COORD(ctx, n); + if (y != 0) y = -y; + } + else + y = COORDY(ctx, n); + n = n->next; + if (len == 0) { + fx = x; + fy = y; + } + else { + if ((fx == x) && (fy == y)) + break; + } + pcb_poly_point_new(poly, x, y); + len++; + } + + if (len < 3) { + rnd_message(RND_MSG_ERROR, "Not enough coordinate pairs for a polygon (at %ld:%ld)\n", (long)wrr->line, (long)wrr->col); + return -1; + } + + if (aper != 0) { + double dv; + long n; + rnd_polo_t *p; + + /* this assumes there's no hole in the poly - but DSN doesn't support holes anyway */ + p = malloc(sizeof(rnd_polo_t) * len); + for(n = 0; n < len; n++) { + p[n].x = poly->Points[n].X; + p[n].y = poly->Points[n].Y; + } + rnd_polo_norms(p, len); + if (rnd_polo_2area(p, len) < 0) + dv = -2.0; + else + dv = 2.0; + rnd_polo_offs((double)aper / dv, p, len); + + for(n = 0; n < len; n++) { + poly->Points[n].X = rnd_round(p[n].x); + poly->Points[n].Y = rnd_round(p[n].y); + } + free(p); + } + pcb_add_poly_on_layer(ly, poly); + return 0; +} + +static int dsn_parse_wire_rect(dsn_read_t *ctx, gsxl_node_t *wrr, pcb_subc_t *subc, pcb_layer_t *force_ly) +{ + rnd_box_t box; + gsxl_node_t *net = wrr->children; + pcb_layer_t *ly; + + DSN_PARSE_NET(ly, net, return -1, subc, force_ly); + + if (dsn_parse_rect(ctx, &box, net->next, (subc != NULL)) != 0) + return -1; + + if (subc) { + if (box.Y1 != 0) box.Y1 = -box.Y1; + if (box.Y2 != 0) box.Y2 = -box.Y2; + } + + pcb_poly_new_from_rectangle(ly, box.X1, box.Y1, box.X2, box.Y2, conf_core.design.clearance, pcb_flag_make(PCB_FLAG_CLEARPOLYPOLY)); + + return 0; +} + +static int dsn_parse_wire_circle(dsn_read_t *ctx, gsxl_node_t *wrr, pcb_subc_t *subc, pcb_layer_t *force_ly) +{ + gsxl_node_t *n, *net = wrr->children; + pcb_layer_t *ly; + rnd_coord_t r, cent[2] = {0, 0}; + pcb_poly_t *poly; + double a, astep; + + DSN_PARSE_NET(ly, net, return -1, subc, force_ly); + + if ((net->next == NULL) || (net->next->next == NULL)) { + rnd_message(RND_MSG_ERROR, "Not enough wire circle attributes (at %ld:%ld)\n", (long)wrr->line, (long)wrr->col); + return -1; + } + + n = net->next; + r = rnd_round((double)COORD(ctx, n) / 2.0); + n = n->next; + if (n != NULL) + DSN_LOAD_COORDS_FMT(cent, n, (subc == NULL) ? "xy" : "XY", goto err_cent); + + poly = pcb_poly_new(ly, conf_core.design.clearance, pcb_flag_make(PCB_FLAG_CLEARPOLYPOLY)); + astep = 2*M_PI / (8 + r / RND_MM_TO_COORD(0.1)); + + for(a = 0; a < 2*M_PI; a += astep) { + rnd_coord_t x, y; + x = rnd_round(cos(a) * (double)r + (double)cent[0]); + y = rnd_round(sin(a) * (double)r + (double)cent[1]); + pcb_poly_point_new(poly, x, y); + } + pcb_add_poly_on_layer(ly, poly); + return 0; + + err_cent:; + rnd_message(RND_MSG_ERROR, "Not enough circle center attributes (at %ld:%ld)\n", (long)wrr->line, (long)wrr->col); + return -1; +} + +static int dsn_parse_wire_path(dsn_read_t *ctx, gsxl_node_t *wrr, pcb_subc_t *subc, pcb_layer_t *force_ly) +{ + gsxl_node_t *n, *net = wrr->children; + pcb_layer_t *ly; + rnd_coord_t aper; + rnd_coord_t x, y, px, py; + int len = 0; + + DSN_PARSE_NET(ly, net, return -1, subc, force_ly); + + if ((net->next == NULL) || (net->next->next == NULL)) { + rnd_message(RND_MSG_ERROR, "Not enough wire path attributes (at %ld:%ld)\n", (long)wrr->line, (long)wrr->col); + return -1; + } + + aper = dsn_load_aper(ctx, net->next); + + for(n = net->next->next; n != NULL;) { + x = COORDX(ctx, n); + if (n->next == NULL) { + rnd_message(RND_MSG_ERROR, "Not enough coordinate values (missing y)\n"); + break; + } + n = n->next; + if (subc != NULL) { + y = COORD(ctx, n); + if (y != 0) y = -y; + } + else + y = COORDY(ctx, n); + n = n->next; + if (len > 0) + pcb_line_new(ly, px, py, x, y, aper, conf_core.design.clearance, pcb_flag_make(PCB_FLAG_CLEARLINE)); + len++; + px = x; + py = y; + } + + return 0; +} + +static int qarc_angle(rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t x, rnd_coord_t y, rnd_coord_t *r) +{ + rnd_coord_t dx = x - cx; + rnd_coord_t dy = y - cy; + + if ((dx != 0) && (dy != 0)) + return -1; + + if (dx < 0) { + *r = -dx; + return 0; + } + if (dx > 0) { + *r = dx; + return 180; + } + + if (dy < 0) { + *r = -dy; + return 270; + } + if (dy > 0) { + *r = dy; + return 90; + } + + return -1; /* all were zero */ +} + +static int dsn_parse_wire_qarc(dsn_read_t *ctx, gsxl_node_t *wrr, pcb_subc_t *subc, pcb_layer_t *force_ly) +{ + gsxl_node_t *coords, *net = wrr->children; + pcb_layer_t *ly; + rnd_coord_t r1, r2, aper; + rnd_coord_t crd[6]; /* sx, sy, ex, ey, cx, cy */ + int sa, ea; + + DSN_PARSE_NET(ly, net, return -1, subc, force_ly); + + if ((net->next == NULL) || ((coords = net->next->next) == NULL)) { + not_enough:; + rnd_message(RND_MSG_ERROR, "Not enough wire qarc attributes (at %ld:%ld)\n", (long)wrr->line, (long)wrr->col); + return -1; + } + + aper = dsn_load_aper(ctx, net->next); + + DSN_LOAD_COORDS_FMT(crd, coords, (subc == NULL) ? "xyxyxy" : "XYXYXY", goto not_enough); + + sa = qarc_angle(crd[4], crd[5], crd[0], crd[1], &r1); + ea = qarc_angle(crd[4], crd[5], crd[2], crd[3], &r2); + if ((sa == -1) || (ea == -1) || (r1 != r2)) { + rnd_message(RND_MSG_ERROR, "invalid qarcs coords (at %ld:%ld)\n", (long)wrr->line, (long)wrr->col); + return -1; + } + + pcb_arc_new(ly, crd[4], crd[5], r1, r1, sa, ea-sa, aper, conf_core.design.clearance, pcb_flag_make(PCB_FLAG_CLEARLINE), 0); + + return 0; +} + +static int dsn_parse_wire(dsn_read_t *ctx, gsxl_node_t *wrr, pcb_subc_t *subc, pcb_layer_t *force_ly) +{ + /* pick up properties */ +/* These are specified but not handled by pcb-rnd: / + for(wrr = wrr->children; wrr != NULL; wrr = wrr->next) { + if (wrr->str == NULL) + continue; + if (rnd_strcasecmp(wrr->str, "type")) { } + else if (rnd_strcasecmp(wrr->str, "attr") == 0) { } + else if (rnd_strcasecmp(wrr->str, "net") == 0) { } + else if (rnd_strcasecmp(wrr->str, "turret") == 0) { } + else if (rnd_strcasecmp(wrr->str, "shield") == 0) { } + else if (rnd_strcasecmp(wrr->str, "connect") == 0) { } + else if (rnd_strcasecmp(wrr->str, "supply") == 0) { } + } +*/ + + /* draw the actual objects */ + for(wrr = wrr->children; wrr != NULL; wrr = wrr->next) { + if (wrr->str == NULL) + continue; + if ((rnd_strcasecmp(wrr->str, "polygon") == 0) || (rnd_strcasecmp(wrr->str, "poly") == 0)) { + if (dsn_parse_wire_poly(ctx, wrr, subc, force_ly) != 0) + return -1; + } + else if (rnd_strcasecmp(wrr->str, "path") == 0) { + if (dsn_parse_wire_path(ctx, wrr, subc, force_ly) != 0) + return -1; + } + else if (rnd_strcasecmp(wrr->str, "qarc") == 0) { + if (dsn_parse_wire_qarc(ctx, wrr, subc, force_ly) != 0) + return -1; + } + else if (rnd_strcasecmp(wrr->str, "rect") == 0) { + if (dsn_parse_wire_rect(ctx, wrr, subc, force_ly) != 0) + return -1; + } + else if (rnd_strcasecmp(wrr->str, "circle") == 0) { + if (dsn_parse_wire_circle(ctx, wrr, subc, force_ly) != 0) + return -1; + } + } + return 0; +} + +static int dsn_parse_via(dsn_read_t *ctx, gsxl_node_t *vnd) +{ + pcb_pstk_proto_t *proto; + const char *pname; + rnd_cardinal_t pid; + rnd_coord_t crd[2] = {0, 0}; + + if ((vnd->children == NULL) || (vnd->children->str == NULL)) { + rnd_message(RND_MSG_ERROR, "Not enough via arguments (at %ld:%ld)\n", (long)vnd->line, (long)vnd->col); + return -1; + } + + pname = vnd->children->str; + proto = htsp_get(&ctx->protos, pname); + if (proto == NULL) { + rnd_message(RND_MSG_ERROR, "Unknown via '%s' (at %ld:%ld)\n", pname, (long)vnd->line, (long)vnd->col); + return -1; + } + + DSN_LOAD_COORDS_FMT(crd, vnd->children->next, "xy", goto err_coord); + + pid = pcb_pstk_proto_insert_dup(ctx->pcb->Data, proto, 1, 0); + if (pcb_pstk_new(ctx->pcb->Data, -1, pid, crd[0], crd[1], conf_core.design.clearance/2, pcb_flag_make(PCB_FLAG_CLEARLINE)) == NULL) + rnd_message(RND_MSG_ERROR, "Failed to create via - expect missing vias (at %ld:%ld)\n", (long)vnd->line, (long)vnd->col); + + return 0; + err_coord:; + rnd_message(RND_MSG_ERROR, "Invalid via coordinates (at %ld:%ld)\n", (long)vnd->line, (long)vnd->col); + return -1; +} + +static int dsn_parse_point(dsn_read_t *ctx, gsxl_node_t *tnd) +{ + rnd_coord_t crd[2] = {0, 0}; + gsxl_node_t *side; + pcb_pstk_t *ps; + int back; + + DSN_LOAD_COORDS_FMT(crd, tnd->children, "xy", goto not_enough); + + side = tnd->children->next->next; + if ((side == NULL) || (side->str == NULL)) { + rnd_message(RND_MSG_ERROR, "Testpoint without side (at %ld:%ld)\n", (long)tnd->line, (long)tnd->col); + return -1; + } + if (rnd_strcasecmp(side->str, "front") == 0) { + back = 0; + } + else if (rnd_strcasecmp(side->str, "back") == 0) { + back = 1; + } + else { + rnd_message(RND_MSG_ERROR, "Invalid testpoint side '%s' (at %ld:%ld)\n", side->str, (long)tnd->line, (long)tnd->col); + return -1; + } + + /* create a padstack for the testpoint if we don't have one already */ + if (!ctx->has_testpoint) { + pcb_pstk_proto_t tpp; + pcb_pstk_shape_t *shp; + + memset(&tpp, 0, sizeof(tpp)); + pcb_vtpadstack_tshape_alloc_append(&tpp.tr, 1); + + /* copper pad */ + shp = pcb_pstk_alloc_append_shape(&tpp.tr.array[0]); + memset(shp, 0, sizeof(pcb_pstk_shape_t)); + shp->layer_mask = PCB_LYT_TOP | PCB_LYT_COPPER; + shp->shape = PCB_PSSH_CIRC; + shp->data.circ.dia = conf_core.design.min_wid; + + /* solder mask cutout - 5% larger */ + shp = pcb_pstk_alloc_append_shape(&tpp.tr.array[0]); + memset(shp, 0, sizeof(pcb_pstk_shape_t)); + shp->layer_mask = PCB_LYT_TOP | PCB_LYT_MASK; + shp->comb = PCB_LYC_SUB | PCB_LYC_AUTO; + shp->shape = PCB_PSSH_CIRC; + shp->data.circ.dia = rnd_round((double)conf_core.design.min_wid * 1.05); + + ctx->testpoint = pcb_pstk_proto_insert_dup(ctx->pcb->Data, &tpp, 1, 0); + ctx->has_testpoint = 1; + pcb_pstk_proto_free_fields(&tpp); + } + + ps = pcb_pstk_new(ctx->pcb->Data, -1, ctx->testpoint, crd[0], crd[1], 0, pcb_no_flags()); + if (ps == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to create testpoint (at %ld:%ld)\n", (long)tnd->line, (long)tnd->col); + return 0; + } + + if (back) + pcb_pstk_mirror(ps, PCB_PSTK_DONT_MIRROR_COORDS, 1, 1, 0); + + + return 0; + not_enough:; + rnd_message(RND_MSG_ERROR, "Not enough coordinates for a testpoint (at %ld:%ld)\n", (long)tnd->line, (long)tnd->col); + return -1; +} + +static int dsn_parse_wiring(dsn_read_t *ctx, gsxl_node_t *wrr) +{ + const rnd_unit_t *old_unit; + + old_unit = dsn_set_old_unit(ctx, wrr->children); + + for(wrr = wrr->children; wrr != NULL; wrr = wrr->next) { + if (wrr->str == NULL) + continue; + if (rnd_strcasecmp(wrr->str, "wire") == 0) { + if (dsn_parse_wire(ctx, wrr, NULL, NULL) != 0) + return -1; + } + else if (rnd_strcasecmp(wrr->str, "via") == 0) { + if (dsn_parse_via(ctx, wrr) != 0) + return -1; + } + else if (rnd_strcasecmp(wrr->str, "point") == 0) { + if (dsn_parse_point(ctx, wrr) != 0) + return -1; + } + else if ((rnd_strcasecmp(wrr->str, "bond") == 0) || (rnd_strcasecmp(wrr->str, "supply_pin") == 0)) { + rnd_message(RND_MSG_WARNING, "unhandled wiring: '%s' (at %ld:%ld) - please send the dsn file as a bugreport\n", wrr->str, (long)wrr->line, (long)wrr->col); + } + } + + if (old_unit != NULL) + pop_unit(ctx, old_unit); + + return 0; +} + +static int dsn_parse_place_component(dsn_read_t *ctx, gsxl_node_t *plr, int mirror_first) +{ + const char *id = STRE(plr->children); + pcb_subc_t *subc, *nsc; + gsxl_node_t *n; + + subc = htsp_get(&ctx->subcs, id); + if (subc == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid image name '%s' in placement (at %ld:%ld) - please send the dsn file as a bugreport\n", id, (long)plr->line, (long)plr->col); + return -1; + } + + for(n = plr->children->next; n != NULL; n = n->next) { + rnd_coord_t crd[2] = {0, 0}; + const char *refdes = STRE(n->children); + gsxl_node_t *side; + int need_mirror; + double rot; + char *end; + + DSN_LOAD_COORDS_FMT(crd, n->children->next, "xy", goto bad_coord); + + side = n->children->next->next->next; + if ((side == NULL) || (side->str == NULL)) { + rnd_message(RND_MSG_ERROR, "Invalid placement side (at %ld:%ld)\n", (long)n->line, (long)n->col); + return -1; + } + if (rnd_strcasecmp(side->str, "front") == 0) + need_mirror = 0; + else if (rnd_strcasecmp(side->str, "back") == 0) + need_mirror = 1; + else { + rnd_message(RND_MSG_ERROR, "Invalid placement side '%s' (at %ld:%ld)\n", side->str, (long)n->line, (long)n->col); + return -1; + } + + rot = strtod(STRE(side->next), &end); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Invalid placement rotation '%s' - must be a number (at %ld:%ld)\n", side->next->str, (long)n->line, (long)n->col); + return -1; + } + + nsc = pcb_subc_dup_at(ctx->pcb, ctx->pcb->Data, subc, crd[0], crd[1], 0, rnd_false); + pcb_attribute_put(&nsc->Attributes, "refdes", refdes); + + if (mirror_first) { + if (need_mirror) + pcb_subc_change_side(nsc, crd[1] * 2 - PCB->hidlib.size_y); + if (rot != 0.0) + pcb_subc_rotate(nsc, crd[0], crd[1], cos(rot / RND_RAD_TO_DEG), sin(rot / RND_RAD_TO_DEG), rot); + } + else { + if (rot != 0.0) + pcb_subc_rotate(nsc, crd[0], crd[1], cos(rot / RND_RAD_TO_DEG), sin(rot / RND_RAD_TO_DEG), rot); + if (need_mirror) + pcb_subc_change_side(nsc, crd[1] * 2 - PCB->hidlib.size_y); + } + } + + return 0; + bad_coord:; + rnd_message(RND_MSG_ERROR, "Invalid placement coords (at %ld:%ld) - please send the dsn file as a bugreport\n", (long)n->line, (long)n->col); + return -1; +} + +static int dsn_parse_placement(dsn_read_t *ctx, gsxl_node_t *plr) +{ + const rnd_unit_t *old_unit; + int mirror_first = 1; + + old_unit = dsn_set_old_unit(ctx, plr->children); + + for(plr = plr->children; plr != NULL; plr = plr->next) { + if (plr->str == NULL) + continue; + if (rnd_strcasecmp(plr->str, "place_control") == 0) { + if (rnd_strcasecmp(STRE(plr->children), "flip_style") == 0) { + if (rnd_strcasecmp(STRE(plr->children->children), "mirror_first") == 0) + mirror_first = 1; + else if (rnd_strcasecmp(STRE(plr->children->children), "mirror_first") == 0) + mirror_first = 0; + else + rnd_message(RND_MSG_WARNING, "invalid flip_style: '%s' (at %ld:%ld) - subcircuits may be misplaced - please send the dsn file as a bugreport\n", STRE(plr->children->children), (long)plr->line, (long)plr->col); + } + } + else if (rnd_strcasecmp(plr->str, "component") == 0) { + if (dsn_parse_place_component(ctx, plr, mirror_first) != 0) + return -1; + } + } + + if (old_unit != NULL) + pop_unit(ctx, old_unit); + + return 0; +} + +static int dsn_parse_net(dsn_read_t *ctx, gsxl_node_t *nwr) +{ + char *s, *netname = nwr->children->str; + pcb_net_t *net; + + for(s = netname; *s != '\0'; s++) + if (!isalnum(*s) && (*s != '+') && (*s != '-')) + *s = '_'; + + net = pcb_net_get(ctx->pcb, &ctx->pcb->netlist[PCB_NETLIST_INPUT], netname, 1); + if (net == NULL) { + rnd_message(RND_MSG_ERROR, "can not create net: '%s' (at %ld:%ld) - subcircuits may be misplaced - please send the dsn file as a bugreport\n", netname, (long)nwr->children->line, (long)nwr->children->col); + return -1; + } + for(nwr = nwr->children->next; nwr != NULL; nwr = nwr->next) { + if (nwr->str == NULL) + continue; + if (rnd_strcasecmp(nwr->str, "pins") == 0) { + gsxl_node_t *n; + for(n = nwr->children; n != NULL; n = n->next) + rnd_actionva(&ctx->pcb->hidlib, "Netlist", "Add", netname, n->str, NULL); + } + else if (rnd_strcasecmp(nwr->str, "property") == 0) { + parse_attribute(ctx, &net->Attributes, nwr->children); + } + } + + return 0; +} + +static int dsn_parse_network(dsn_read_t *ctx, gsxl_node_t *nwr) +{ + rnd_actionva(&ctx->pcb->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&ctx->pcb->hidlib, "Netlist", "Clear", NULL); + + for(nwr = nwr->children; nwr != NULL; nwr = nwr->next) { + if (nwr->str == NULL) + continue; + if (rnd_strcasecmp(nwr->str, "net") == 0) { + if (dsn_parse_net(ctx, nwr) != 0) + return -1; + } + } + + rnd_actionva(&ctx->pcb->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&ctx->pcb->hidlib, "Netlist", "Thaw", NULL); + + return 0; +} + + + +static int dsn_parse_pcb(dsn_read_t *ctx, gsxl_node_t *root) +{ + gsxl_node_t *n, *nunit = NULL, *nstructure = NULL, *nplacement = NULL, *nlibrary = NULL, *nnetwork = NULL, *nwiring = NULL, *ncolors = NULL, *nresolution = NULL; + + /* default unit in case the file does not specify one */ + ctx->unit = rnd_get_unit_struct("inch"); + + free(ctx->pcb->hidlib.name); + ctx->pcb->hidlib.name = rnd_strdup(STRE(root->children)); + + for(n = root->children->next; n != NULL; n = n->next) { + if (n->str == NULL) + continue; + else if_save_uniq(n, unit) + else if_save_uniq(n, resolution) + else if_save_uniq(n, structure) + else if_save_uniq(n, placement) + else if_save_uniq(n, library) + else if_save_uniq(n, network) + else if_save_uniq(n, wiring) + else if_save_uniq(n, colors) + } + + if ((nresolution != NULL) && (nresolution->children != NULL)) { + char *s, *su; + + for(su = s = STRE(gsxl_children(nresolution)); *s != '\0'; s++) + *s = tolower(*s); + + ctx->unit = rnd_get_unit_struct(su); + if (ctx->unit == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid resolution unit: '%s'\n", su); + return -1; + } + } + + if (push_unit(ctx, nunit) == NULL) + return -1; + + if (dsn_parse_structure(ctx, nstructure) != 0) + return -1; + + if ((nlibrary != NULL) && (nlibrary->children != NULL)) { + if (dsn_parse_library(ctx, nlibrary) != 0) + return -1; + } + + if ((nplacement != NULL) && (nplacement->children != NULL)) { + if (dsn_parse_placement(ctx, nplacement) != 0) + return -1; + } + + if ((nnetwork != NULL) && (nnetwork->children != NULL)) { + if (dsn_parse_network(ctx, nnetwork) != 0) + return -1; + } + + if ((nwiring != NULL) && (nwiring->children != NULL)) + if (dsn_parse_wiring(ctx, nwiring) != 0) + return -1; + + + return 0; +} + +/*** glue and low level ***/ + + +int io_dsn_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f) +{ + char line[1024], *s; + int phc = 0, in_pcb = 0, lineno = 0; + + if (typ != PCB_IOT_PCB) + return 0; + + while(!(feof(f)) && (lineno < 512)) { + if (fgets(line, sizeof(line), f) != NULL) { + lineno++; + for(s = line; *s != '\0'; s++) + if (*s == '(') + phc++; + s = line; + if ((phc > 0) && (strstr(s, "pcb") != 0)) + in_pcb = 1; + if ((phc > 0) && (strstr(s, "PCB") != 0)) + in_pcb = 1; + if ((phc > 2) && in_pcb && (strstr(s, "space_in_quoted_tokens") != 0)) + return 1; + if ((phc > 2) && in_pcb && (strstr(s, "host_cad") != 0)) + return 1; + if ((phc > 2) && in_pcb && (strstr(s, "host_version") != 0)) + return 1; + } + } + + /* hit eof before seeing a valid root -> bad */ + return 0; +} + +static int dsn_parse_file(dsn_read_t *rdctx, const char *fn) +{ + int c, blen = -1; + gsx_parse_res_t res; + FILE *f; + char buff[12]; + long q_offs = -1, offs; + + + f = rnd_fopen(&PCB->hidlib, fn, "r"); + if (f == NULL) + return -1; + + /* find the offset of the quote char so it can be ignored during the s-expression parse */ + offs = 0; + while(!(feof(f))) { + c = fgetc(f); + if (c == 's') + blen = 0; + if (blen >= 0) { + buff[blen] = c; + if (blen == 12) { + if (memcmp(buff, "string_quote", 12) == 0) { + for(c = fgetc(f),offs++; isspace(c); c = fgetc(f),offs++) ; + q_offs = offs; + printf("quote is %c at %ld\n", c, q_offs); + break; + } + blen = -1; + } + blen++; + } + offs++; + } + rewind(f); + + + gsxl_init(&rdctx->dom, gsxl_node_t); + rdctx->dom.parse.line_comment_char = '#'; + offs = 0; + do { + c = fgetc(f); + if (offs == q_offs) /* need to ignore the quote char else it's an unbalanced quote */ + c = '.'; + offs++; + } while((res = gsxl_parse_char(&rdctx->dom, c)) == GSX_RES_NEXT); + + fclose(f); + if (res != GSX_RES_EOE) { + rnd_message(RND_MSG_ERROR, "s-expression parse error at offset %ld\n", offs); + return -1; + } + + return 0; +} + +int io_dsn_parse_pcb(pcb_plug_io_t *ctx, pcb_board_t *pcb, const char *Filename, rnd_conf_role_t settings_dest) +{ + dsn_read_t rdctx; + gsxl_node_t *rn; + htsp_entry_t *e; + int ret; + + memset(&rdctx, 0, sizeof(rdctx)); + if (dsn_parse_file(&rdctx, Filename) != 0) + goto error; + + gsxl_compact_tree(&rdctx.dom); + rn = rdctx.dom.root; + if ((rn == NULL) || (rn->str == NULL) || (rnd_strcasecmp(rn->str, "pcb") != 0)) { + rnd_message(RND_MSG_ERROR, "Root node should be pcb, got %s instead\n", rn->str); + goto error; + } + if (gsxl_next(rn) != NULL) { + rnd_message(RND_MSG_ERROR, "Multiple root nodes?!\n"); + goto error; + } + + rdctx.pcb = pcb; + htsp_init(&rdctx.name2layer, strhash, strkeyeq); + htsp_init(&rdctx.protos, strhash, strkeyeq); + htsp_init(&rdctx.subcs, strhash, strkeyeq); + + pcb_data_clip_inhibit_inc(rdctx.pcb->Data); + ret = dsn_parse_pcb(&rdctx, rn); + pcb_data_clip_inhibit_dec(rdctx.pcb->Data, 1); + + for (e = htsp_first(&rdctx.protos); e; e = htsp_next(&rdctx.protos, e)) { + pcb_pstk_proto_free_fields(e->value); + free(e->value); + } + for (e = htsp_first(&rdctx.subcs); e; e = htsp_next(&rdctx.subcs, e)) + pcb_subc_free(e->value); + htsp_uninit(&rdctx.name2layer); + htsp_uninit(&rdctx.protos); + gsxl_uninit(&rdctx.dom); + return ret; + + error:; + gsxl_uninit(&rdctx.dom); + return -1; +} + Index: tags/2.3.0/src_plugins/io_dsn/read.h =================================================================== --- tags/2.3.0/src_plugins/io_dsn/read.h (nonexistent) +++ tags/2.3.0/src_plugins/io_dsn/read.h (revision 33253) @@ -0,0 +1,4 @@ +#include "plug_io.h" + +int io_dsn_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); +int io_dsn_parse_pcb(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest); Index: tags/2.3.0/src_plugins/io_dsn/write.c =================================================================== --- tags/2.3.0/src_plugins/io_dsn/write.c (nonexistent) +++ tags/2.3.0/src_plugins/io_dsn/write.c (revision 33253) @@ -0,0 +1,183 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * dsn IO plugin - file format write + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "plug_io.h" +#include +#include +#include "board.h" +#include "data.h" +#include "layer.h" +#include "layer_grp.h" + +#include "write.h" + +#include "../src_plugins/lib_netmap/netmap.h" + +typedef struct { + FILE *f; + pcb_board_t *pcb; + pcb_netmap_t nmap; +} dsn_write_t; + +#define GNAME_MAX 64 + +static void group_name(char *dst, const char *src, rnd_layergrp_id_t gid) +{ + int n; + char *d; + const char*s; + + n = sprintf(dst, "%d__", (int)gid); + + for(d = dst+n, s = src; (*s != '\0') && (n < GNAME_MAX - 1); s++,d++,n++) { + if ((*s == '"') || (*s < 32) || (*s > 126)) + *d = '_'; + else + *d = *s; + } + *d = '\0'; +} + +#define COORDX(x) (x) +#define COORDY(y) (PCB->hidlib.size_y - (y)) + +static int dsn_write_structure(dsn_write_t *wctx) +{ + rnd_layergrp_id_t gid; + pcb_layergrp_t *lg; + + fprintf(wctx->f, " (structure\n"); + for(gid = 0, lg = wctx->pcb->LayerGroups.grp; gid < wctx->pcb->LayerGroups.len; gid++,lg++) { + char gname[GNAME_MAX]; + if (!(lg->ltype & PCB_LYT_COPPER)) + continue; + group_name(gname, lg->name, gid); + fprintf(wctx->f, " (layer \"%s\" (type signal))\n", gname); + } + fprintf(wctx->f, " )\n"); + + return 0; +} + +static int dsn_write_wiring(dsn_write_t *wctx) +{ + rnd_layer_id_t lid; + pcb_layer_t *ly; + + fprintf(wctx->f, " (wiring\n"); + for(ly = wctx->pcb->Data->Layer, lid = 0; lid < wctx->pcb->Data->LayerN; lid++,ly++) { + char gname[GNAME_MAX]; + rnd_layergrp_id_t gid = pcb_layer_get_group_(ly); + pcb_layergrp_t *lg = pcb_get_layergrp(wctx->pcb, gid); + pcb_net_t *net; + + if ((lg == NULL) || !(lg->ltype & PCB_LYT_COPPER)) + continue; + + group_name(gname, lg->name, gid); + + { + pcb_gfx_t *gfx; + for(gfx = gfxlist_first(&ly->Gfx); gfx != NULL; gfx = gfxlist_next(gfx)) + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)gfx, "gfx", "gfx can not be exported", "please use the lihata board format"); + } + + PCB_LINE_LOOP(ly); + { + net = htpp_get(&wctx->nmap.o2n, (pcb_any_obj_t *)line); + rnd_fprintf(wctx->f," (wire (path \"%s\" %[4] %[4] %[4] %[4] %[4])", gname, line->Thickness, + COORDX(line->Point1.X), COORDY(line->Point1.Y), + COORDX(line->Point2.X), COORDY(line->Point2.Y)); + if (net != NULL) + fprintf(wctx->f, "(net \"%s\")", net->name); + fprintf(wctx->f, "(type protect))\n"); + } + PCB_END_LOOP; + + } + fprintf(wctx->f, " )\n"); + return 0; +} + + +static int dsn_write_board(dsn_write_t *wctx) +{ + const char *s; + int res = 0; + + if (pcb_netmap_init(&wctx->nmap, wctx->pcb, 0) != 0) { + rnd_message(RND_MSG_ERROR, "Can not set up net map\n"); + return -1; + } + + fprintf(wctx->f, "(pcb "); + if ((wctx->pcb->hidlib.name != NULL) && (*wctx->pcb->hidlib.name != '\0')) { + for(s = wctx->pcb->hidlib.name; *s != '\0'; s++) { + if (isalnum(*s)) + fputc(*s, wctx->f); + else + fputc('_', wctx->f); + } + fputc('\n', wctx->f); + } + else + fprintf(wctx->f, "anon\n"); + + fprintf(wctx->f, " (parser\n"); + fprintf(wctx->f, " (string_quote \")\n"); + fprintf(wctx->f, " (space_in_quoted_tokens on)\n"); + fprintf(wctx->f, " (host_cad \"pcb-rnd/io_dsn\")\n"); + fprintf(wctx->f, " (host_version \"%s\")\n", PCB_VERSION); + fprintf(wctx->f, " )\n"); + + /* set units to mm with nm resolution */ + fprintf(wctx->f, " (resolution mm 1000000)\n"); + fprintf(wctx->f, " (unit mm)\n"); + rnd_printf_slot[4] = "%.07mm"; + + res |= dsn_write_structure(wctx); + res |= dsn_write_wiring(wctx); + + fprintf(wctx->f, ")\n"); + + pcb_netmap_uninit(&wctx->nmap); + return res; +} + + +int io_dsn_write_pcb(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + dsn_write_t wctx; + + wctx.f = FP; + wctx.pcb = PCB; + + return dsn_write_board(&wctx); +} Index: tags/2.3.0/src_plugins/io_dsn/write.h =================================================================== --- tags/2.3.0/src_plugins/io_dsn/write.h (nonexistent) +++ tags/2.3.0/src_plugins/io_dsn/write.h (revision 33253) @@ -0,0 +1 @@ +int io_dsn_write_pcb(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency); Index: tags/2.3.0/src_plugins/io_eagle/Makefile =================================================================== --- tags/2.3.0/src_plugins/io_eagle/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_io_eagle + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/io_eagle/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/io_eagle/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/Plug.tmpasm (revision 33253) @@ -0,0 +1,26 @@ +put /local/pcb/mod {io_eagle} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/io_eagle/io_eagle.o + $(PLUGDIR)/io_eagle/read.o + $(PLUGDIR)/io_eagle/read_dru.o + $(PLUGDIR)/io_eagle/egb_tree.o + $(PLUGDIR)/io_eagle/eagle_bin.o + $(PLUGDIR)/io_eagle/trparse_xml.o + $(PLUGDIR)/io_eagle/trparse_bin.o +@] + +switch /local/pcb/io_eagle/controls + case {disable} end; + default + put /local/pcb/mod/CFLAGS /target/libs/sul/libxml2/cflags + put /local/pcb/mod/LDFLAGS /target/libs/sul/libxml2/ldflags + end +end + + +switch /local/pcb/io_eagle/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end + Index: tags/2.3.0/src_plugins/io_eagle/dru-contents-summary.txt =================================================================== --- tags/2.3.0/src_plugins/io_eagle/dru-contents-summary.txt (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/dru-contents-summary.txt (revision 33253) @@ -0,0 +1,67 @@ +layerSetup = (1*16) -> defines a layer stackup composed of layer 1 and layer 16, and the '*' denotes a core between them, whereas '+' would denote "prepreg" , i.e. a commercial 4 layer given by: layerSetup = (1+2*15+16), and a commercial 6 layer given by layerSetup = (1+2*3+14*15+16)" +mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm ->minimum thickness of each copper layer, quoted in order of layers +mtIsolate = 1.6mm 1.2mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm -> minimum thickness of dielectric between copper layers, quoted in order of layers +mdWireWire = 6mil -> minimum distance between signal layer wires +mdWirePad = 6mil -> minimum distance between signal layer wire and pad +mdWireVia = 6mil -> minimum distance between signal layer wire and via +mdPadPad = 6mil -> minimum distance between signal layer pads +mdPadVia = 6mil -> minimum distance between signal layer pads and vias +mdViaVia = 8mil -> minimum distance between signal layer vias +mdSmdPad = 0mil -> minimum distance for same signal SMD-Pad, zero disables checks +mdSmdVia = 0mil -> minimum distance for same signal SMD-Via, zero disables checks +mdSmdSmd = 0mil -> minimum distance for same signal SMD-SMD, zero disables checks +mdViaViaSameLayer = 8mil ->minimum distance between vias in same layer +mnLayersViaInSmd = 2 +mdCopperDimension = 20mil -> minimum distance between any copper object in signal layers and the board dimensions or holes , setting to zero disables check +mdDrill = 10mil -> minimum distance between drill holes, setting to zero disables check +mdSmdStop = 0mil -> minimum distance between SMD slder mask apertures +msWidth = 6mil -> minimum feature size +msDrill = 12mil -> minimum drill size +msMicroVia = 12mil -> minimum micro via size, applies to blind vias one layer deep. If set to value greater than minimum drill, there are no micro vias +msBlindViaRatio = 0.500000 -> aspect ratio required for drill diameter d given layer thickness t +rvPadTop = 0.250000 -> percent of drill diameter that gives the width of the annulus ring for a top layer pad +rvPadInner = 0.250000 -> percent of drill diameter that gives the width of the annulus ring for an inner layer pad +rvPadBottom = 0.250000 -> percent of drill diameter that gives the width of the annulus ring for a bottom layer pad +rvViaOuter = 0.250000 -> percent of drill diameter that gives the width of the annulus ring for an outer layer via +rvViaInner = 0.250000 -> percent of drill diameter that gives the width of the annulus ring for an inner layer via +rvMicroViaOuter = 0.250000 -> percent of drill diameter that gives the width of the annulus ring an outer layer microvia +rvMicroViaInner = 0.250000 -> percent of drill diameter that gives the width of the annulus ring an inner layer microvia +rlMinPadTop = 6mil -> gives minimum restring size for top layer pad +rlMaxPadTop = 20mil - > as above, but max +rlMinPadInner = 6mil -> gives minimum restring size for inner layer pad +rlMaxPadInner = 20mil - > as above, but max +rlMinPadBottom = 6mil -> gives minimum restring size for bottom layer +rlMaxPadBottom = 20mil - > as above, but max +rlMinViaOuter = 6mil -> gives minimum restring size for outer layer via +rlMaxViaOuter = 20mil - > as above, but max +rlMinViaInner = 6mil -> gives minimum restring size for inner layer via +rlMaxViaInner = 20mil - > as above, but max +rlMinMicroViaOuter = 4mil -> gives minimum restring size for outer layer microvia +rlMaxMicroViaOuter = 20mil - > as above, but max +rlMinMicroViaInner = 4mil -> gives minimum restring size for inner layer microvia +rlMaxMicroViaInner = 20mil - > as above, but max +psTop = -1 -> pad shape on the top, -1 == as defined by library, 1 == round, 0 == square +psBottom = -1 -> pad shape on the top, as defined by library +psFirst = 0 -> pad shape on the top, not special, i.e. square +psElongationLong = 100 -> pad elongation, in percent +psElongationOffset = 100 -> offset pad, percentage of diameter, "right side" +mvStopFrame = 1.000000 -> percent of minimum size of smds, pad, vias, limited by min and max +mvCreamFrame = 0.000000 -> percent of minimum size of smds or paste aperture, limited by min and max +mlMinStopFrame = 0mil -> solder mask aperture clearance from copper min +mlMaxStopFrame = 0mil -> solder mask aperture clearance from copper max +mlMinCreamFrame = 0mil -> SMD paste aperture clearance from copper min +mlMaxCreamFrame = 0mil -> SMD paste aperture clearance from copper max +mlViaStopLimit = 100mil -> via size above which aperture is made in solder mask for vias +srRoundness = 0.000000 -> SMD corner roundness as percent +srMinRoundness = 0mil -> SMD minimum corner roundness +srMaxRoundness = 0mil -> SMD maximum corner roundness +slThermalIsolate = 10mil -> defines width of copper bridges between non copper annular zones around an SMD/pad +slThermalsForVias = 0 -> if not zero, vias are connected to surrounding polygons with thermals, +dpMaxLengthDifference = 10mm -> max differenc in length for differential pairs +dpGapFactor = 2.500000 -> gap factor for meandering differential pairs +checkGrid = 0 -> check all features are on grid +checkAngle = 0 -> check if al angles multiple of 45 degrees +checkFont = 1 +checkRestrict = 0 +useDiameter = 13 +maxErrors = 50 Index: tags/2.3.0/src_plugins/io_eagle/eagle_bin.c =================================================================== --- tags/2.3.0/src_plugins/io_eagle/eagle_bin.c (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/eagle_bin.c (revision 33253) @@ -0,0 +1,2373 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017 Tibor 'Igor2' Palinkas + * Copyright (C) 2017 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Eagle binary tree parser */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "eagle_bin.h" +#include "egb_tree.h" +#include +#include +#include +#include + +/* Describe a bitfield: width of the field that hosts the bitfield, first +and last bit offsets, inclusive. Bit offsets are starting from 0 at LSB. */ +#define BITFIELD(field_width_bytes, first_bit, last_bit) \ + (((unsigned long)(field_width_bytes)) << 16 | ((unsigned long)(first_bit)) << 8 | ((unsigned long)(last_bit))) + +typedef enum { + T_BMB, /* bit-mask-bool: apply the bitmask in 'len' to the the byte at offs and use the result as a boolean */ + T_UBF, /* unsigned bitfield; offset is the first byte in block[], len is a BITFIELD() */ + T_INT, + T_DBL, + T_STR +} pcb_eagle_type_t; + +typedef enum { + SS_DIRECT, /* it specifies the number of direct children */ + SS_RECURSIVE, /* it specifies the number of all children, recursively */ + SS_RECURSIVE_MINUS_1 /* same as SS_RECURSIVE, but decrease the children count first */ +} pcb_eagle_ss_type_t; + + +typedef struct { + int offs; /* 0 is the terminator (no more offsets) */ + unsigned long len; + int val; +} fmatch_t; + +typedef struct { + int offs; /* 0 is the terminator (no more offsets) */ + int len; + pcb_eagle_ss_type_t ss_type; + char *tree_name; /* if not NULL, create a subtree using this name and no attributes */ +} subsect_t; + +typedef struct { + char *name; /* NULL is the terminator (no more attributes) */ + pcb_eagle_type_t type; + int offs; + unsigned len; +} attrs_t; + +typedef struct { + unsigned int cmd, cmd_mask;/* rule matches only if block[0] == cmd */ + char *name; + fmatch_t fmatch[4]; /* rule matches only if all fmatch integer fields match their val */ + subsect_t subs[8];/* how to extract number of subsections (direct children) */ + attrs_t attrs[32];/* how to extract node attributes */ +} pcb_eagle_script_t; + +typedef struct +{ + egb_node_t *root, *layers, *drawing, *libraries, *elements, *firstel, *signals, *board, *drc; + long mdWireWire, wire2pad, wire2via, pad2pad, pad2via, via2via, pad2smd, via2smd, + smd2smd, copper2dimension, drill2hole, msWidth, minDrill, psTop, psBottom, psFirst; + /* DRC values for spacing and width */ + double rvPadTop, rvPadInner, rvPadBottom; /* DRC values for via sizes */ + double rvViaOuter, rvViaInner, rvMicroViaOuter, rvMicroViaInner; + /* the following design rule values don't map obviously to XML parameters */ + long restring_limit1_mil, restring_limit2_mil, restring_limit3_mil, + restring_limit4_mil, restring_limit5_mil, restring_limit6_mil, + restring_limit7_mil, restring_limit8_mil, restring_limit9_mil, + restring_limit10_mil, restring_limit11_mil, restring_limit12_mil, + restring_limit13_mil, restring_limit14_mil, mask_limit1_mil, + mask_limit2_mil, mask_limit3_mil, mask_limit4_mil; + double mask_percentages1_ratio, mask_percentages2_ratio; + char *free_text; + char *free_text_cursor; + size_t free_text_len; +} egb_ctx_t; + +#define TERM {0} + +static const pcb_eagle_script_t pcb_eagle_script[] = { + { PCB_EGKW_SECT_START, 0xFF7F, "drawing", + { /* field match */ + TERM + }, + { /* subsection sizes */ +/* {2, 2, SS_DIRECT, NULL},*/ + {4, 4, SS_RECURSIVE_MINUS_1, NULL}, + TERM + }, + { /* attributes */ + {"subsecs", T_INT, 2, 2}, + {"numsecs", T_INT, 4, 4}, + {"subsecsMSB", T_INT, 3, 1}, + {"subsecsLSB", T_INT, 2, 1}, + {"numsecsMSB2", T_INT, 7, 1}, + {"numsecsMSB1", T_INT, 6, 1}, + {"numsecsMSB0", T_INT, 5, 1}, + {"numsecsLSB", T_INT, 4, 1}, + {"v1", T_INT, 8, 1}, + {"v2", T_INT, 9, 1}, + TERM + }, + }, + { PCB_EGKW_SECT_UNKNOWN11, 0xFFFF, "unknown11" }, + { PCB_EGKW_SECT_GRID, 0xFFFF, "grid", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"display", T_BMB, 2, 0x01}, + {"visible", T_BMB, 2, 0x02}, + {"unit", T_UBF, 3, BITFIELD(1, 0, 3)}, + {"altunit", T_UBF, 3, BITFIELD(1, 4, 7)}, + {"multiple",T_INT, 4, 3}, + {"size", T_DBL, 8, 8}, + {"altsize", T_DBL, 16, 8}, + TERM + }, + }, + { PCB_EGKW_SECT_LAYER, 0xFF7F, "layer", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"side", T_BMB, 2, 0x10}, + {"visible", T_UBF, 2, BITFIELD(1, 2, 3)}, + {"active", T_BMB, 2, 0x02}, + {"number",T_UBF, 3, BITFIELD(1, 0, 7)}, + {"other",T_INT, 4, 1}, + {"fill", T_UBF, 5, BITFIELD(1, 0, 3)}, + {"color",T_UBF, 6, BITFIELD(1, 0, 5)}, + {"name", T_STR, 15, 9}, + TERM + }, + }, + { PCB_EGKW_SECT_SCHEMA, 0xFFFF, "schema", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {4, 4, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"shtsubsecs", T_INT, 8, 4}, + {"atrsubsecs", T_INT, 12, 4}, /* 0 if v4 */ + {"xref_format", T_STR, 19, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_LIBRARY, 0xFF7F, "library", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {4, 4, SS_RECURSIVE, NULL}, + {8, 4, SS_RECURSIVE, NULL}, + {12, 4, SS_RECURSIVE, NULL}, + /*{4, 4, SS_DIRECT, NULL},*/ + TERM + }, + { /* attributes */ + {"devsubsecs", T_INT, 4, 4}, + {"symsubsecs", T_INT, 8, 4}, + {"pacsubsecs", T_INT, 12, 4}, + {"children", T_INT, 8, 4}, + {"name", T_STR, 16, 8}, + TERM + }, + }, + { PCB_EGKW_SECT_DEVICES, 0xFF7F, "devices", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {4, 4, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"children", T_INT, 8, 4}, + {"library", T_STR, 16, 8}, + TERM + }, + }, + { PCB_EGKW_SECT_SYMBOLS, 0xFF7F, "symbols", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {4, 4, SS_RECURSIVE, NULL}, + TERM + }, + { /* attributes */ + {"children", T_INT, 8, 4}, + {"library", T_STR, 16, 8}, + TERM + }, + }, + { PCB_EGKW_SECT_PACKAGES, 0xFF5F, "packages", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {4, 4, SS_RECURSIVE, NULL}, + TERM + }, + { /* attributes */ + {"subsects", T_INT, 4, 4}, + {"children", T_INT, 8, 2}, + {"desc", T_STR, 10, 6}, + {"library", T_STR, 16, 8}, + TERM + }, + }, + { PCB_EGKW_SECT_SCHEMASHEET, 0xFFFF, "schemasheet", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"minx", T_INT, 4, 2}, + {"miny", T_INT, 6, 2}, + {"maxx", T_INT, 8, 2}, + {"maxy", T_INT, 10, 2}, + {"partsubsecs", T_INT, 12, 4}, + {"bussubsecs", T_INT, 16, 4}, + {"netsubsecs", T_INT, 20, 4}, + TERM + }, + }, + { PCB_EGKW_SECT_BOARD, 0xFF37, "board", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {12, 4, SS_RECURSIVE, "libraries"}, /* lib */ + {2, 2, SS_DIRECT, "plain"}, /* globals */ + {16, 4, SS_RECURSIVE, "elements"}, /* package refs */ + {20, 4, SS_RECURSIVE, "signals"}, /* nets */ + TERM + }, + { /* attributes */ + {"minx", T_INT, 4, 2}, + {"miny", T_INT, 6, 2}, + {"maxx", T_INT, 8, 2}, + {"maxy", T_INT, 10, 2}, + {"defsubsecs", T_INT, 12, 4}, + {"pacsubsecs", T_INT, 16, 4}, + {"netsubsecs", T_INT, 20, 4}, + TERM + }, + }, + { PCB_EGKW_SECT_SIGNAL, 0xFFB3, "signal", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"minx", T_INT, 4, 2}, + {"miny", T_INT, 6, 2}, + {"maxx", T_INT, 8, 2}, + {"maxy", T_INT, 10, 2}, + {"airwires", T_BMB, 12, 0x02}, + {"netclass", T_UBF, 13, BITFIELD(1, 0, 3)}, + {"name", T_STR, 16, 8}, + TERM + }, + }, + { PCB_EGKW_SECT_SYMBOL, 0xFFFF, "symbol", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"minx", T_INT, 4, 2}, + {"miny", T_INT, 6, 2}, + {"maxx", T_INT, 8, 2}, + {"maxy", T_INT, 10, 2}, + {"name", T_STR, 16, 8}, + TERM + }, + }, + { PCB_EGKW_SECT_PACKAGE, 0xFFDF, "package", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_RECURSIVE, NULL}, + TERM + }, + { /* attributes */ + {"minx", T_INT, 4, 2}, + {"miny", T_INT, 6, 2}, + {"maxx", T_INT, 8, 2}, + {"maxy", T_INT, 10, 2}, + {"desc", T_STR, 13, 5}, + {"name", T_STR, 18, 6}, + TERM + }, + }, + { PCB_EGKW_SECT_SCHEMANET, 0xFFFF, "schemanet", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"minx", T_INT, 4, 2}, + {"miny", T_INT, 6, 2}, + {"maxx", T_INT, 8, 2}, + {"maxy", T_INT, 10, 2}, + {"netclass", T_UBF, 13, BITFIELD(1, 0, 3)}, + {"name", T_STR, 18, 6}, + TERM + }, + }, + { PCB_EGKW_SECT_PATH, 0xFFFF, "path", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"minx", T_INT, 4, 2}, + {"miny", T_INT, 6, 2}, + {"maxx", T_INT, 8, 2}, + {"maxy", T_INT, 10, 2}, + TERM + }, + }, + { PCB_EGKW_SECT_POLYGON, 0xFFF7, "polygon", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"minx", T_INT, 4, 2}, + {"miny", T_INT, 6, 2}, + {"maxx", T_INT, 8, 2}, + {"maxy", T_INT, 10, 2}, + {"width", T_INT, 12, 2}, + {"spacing", T_INT, 14, 2}, + {"isolate", T_INT, 16, 2}, + {"layer", T_UBF, 18, BITFIELD(1,0,7)}, + {"pour", T_BMB, 19, 0x01}, + {"rank", T_BMB, 19, BITFIELD(1, 1, 3)}, + {"thermals", T_BMB, 19, 0x80}, + {"orphans", T_BMB, 19, 0x40}, + TERM + }, + }, + { PCB_EGKW_SECT_LINE, 0xFF43, "wire", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"half_width", T_INT, 20, 2}, + {"stflags", T_BMB, 22, 0x33}, + /*{"bin_style", T_BMB, 22, 0x03},*/ + /*{"bin_cap", T_BMB, 22, 0x10},*/ + {"clockwise", T_BMB, 22, 0x20}, + {"linetype", T_UBF, 23, BITFIELD(1, 0, 7)}, + {"linetype_0_x1", T_INT, 4, 4}, + /*{"x", T_INT, 4, 4}, only needed if wire used for polygon vertex coord */ + {"linetype_0_y1", T_INT, 8, 4}, + /*{"y", T_INT, 8, 4}, only needed if wire used for polygon vertex coord */ + {"linetype_0_x2", T_INT, 12, 4}, + {"linetype_0_y2", T_INT, 16, 4}, + {"arc_negflags", T_UBF, 19, BITFIELD(1, 0, 4)}, + /*{"c_negflag", T_BMB, 19, 0x01},*/ + {"arc_c1", T_INT, 7, 1}, + {"arc_c2", T_INT, 11, 1}, + {"arc_c3", T_INT, 15, 1}, + {"arc_x1", T_INT, 4, 3}, + {"arc_y1", T_INT, 8, 3}, + {"arc_x2", T_INT, 12, 3}, + {"arc_y2", T_INT, 16, 3}, + TERM + }, + }, + { PCB_EGKW_SECT_ARC, 0xFFFF, "arc", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"half_width", T_INT, 20, 2}, + {"clockwise", T_BMB, 22, 0x20}, + {"arctype", T_UBF, 23, BITFIELD(1, 0, 7)}, + {"arc_negflags", T_UBF, 19, BITFIELD(1, 0, 7)}, + /*{"c_negflag", T_BMB, 19, 0x01},*/ + {"arc_c1", T_INT, 7, 1}, + {"arc_c2", T_INT, 11, 1}, + {"arc_c3", T_INT, 15, 1}, + {"arc_x1", T_INT, 4, 3}, + {"arc_y1", T_INT, 8, 3}, + {"arc_x2", T_INT, 12, 3}, + {"arc_y2", T_INT, 16, 3}, + {"arctype_other_x1", T_INT, 4, 4}, + {"arctype_other_y1", T_INT, 8, 4}, + {"arctype_other_x2", T_INT, 12, 4}, + {"arctype_other_y2", T_INT, 16, 4}, + TERM + }, + }, + { PCB_EGKW_SECT_CIRCLE, 0xFF53, "circle", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"radius", T_INT, 12, 4}, + {"half_width", T_INT, 20, 4}, + TERM + }, + }, + { PCB_EGKW_SECT_RECTANGLE, 0xFF5F, "rectangle", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x1", T_INT, 4, 4}, + {"y1", T_INT, 8, 4}, + {"x2", T_INT, 12, 4}, + {"y2", T_INT, 16, 4}, + {"bin_rot", T_INT, 20, 2}, /* ? should it be T_UBF, 16, BITFIELD(2, 0, 11)},*/ + TERM + }, + }, + { PCB_EGKW_SECT_JUNCTION, 0xFFFF, "junction", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"width_2", T_INT, 12, 2}, + TERM + }, + }, + { PCB_EGKW_SECT_HOLE, 0xFF53, "hole", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"half_diameter", T_UBF, 12, BITFIELD(2, 0, 15)}, + {"half_drill", T_UBF, 12, BITFIELD(2, 0, 15)}, /* try duplicating field */ + TERM + }, + }, + { PCB_EGKW_SECT_VIA, 0xFF7F, "via", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"shape", T_INT, 2, 1}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"half_drill", T_UBF, 12, BITFIELD(2, 0, 15)}, + {"half_diameter", T_UBF, 14, BITFIELD(2, 0, 15)}, + {"layers", T_UBF, 16, BITFIELD(1,0,7)}, /*not 1:1 mapping */ + {"stop", T_BMB, 17, 0x01}, + TERM + }, + }, + { PCB_EGKW_SECT_PAD, 0xFF5F, "pad", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"shape", T_INT, 2, 1}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"half_drill", T_UBF, 12, BITFIELD(2, 0, 15)}, + {"half_diameter", T_UBF, 14, BITFIELD(2, 0, 15)}, + {"bin_rot" , T_INT, 16, 2}, /* ? maybe T_UBF, 16, BITFIELD(2, 0, 11)}, */ + {"stop", T_BMB, 18, 0x01}, + {"thermals", T_BMB, 18, 0x04}, + {"first", T_BMB, 18, 0x08}, + {"name", T_STR, 19, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_SMD, 0xFF7F, "smd", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"roundness", T_INT, 2, 1}, + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"half_dx", T_UBF, 12, BITFIELD(2, 0, 15)}, + {"half_dy", T_UBF, 14, BITFIELD(2, 0, 15)}, + {"bin_rot", T_UBF, 16, BITFIELD(2, 0, 11)}, + {"stop", T_BMB, 18, 0x01}, + {"cream", T_BMB, 18, 0x02}, + {"thermals", T_BMB, 18, 0x04}, + {"first", T_BMB, 18, 0x08}, + {"name", T_STR, 19, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_PIN, 0xFF7F, "pin", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"function", T_UBF, 2, BITFIELD(1, 0, 1)}, + {"visible", T_UBF, 2, BITFIELD(1, 6, 7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"direction", T_UBF, 12, BITFIELD(1, 0, 3)}, + {"length", T_UBF, 12, BITFIELD(1, 4, 5)}, + {"bin_rot", T_UBF, 12, BITFIELD(1, 6, 7)}, + {"direction", T_UBF, 12, BITFIELD(1, 0, 3)}, + {"swaplevel", T_INT, 13, 1}, + {"name", T_STR, 14, 10}, + TERM + }, + }, + { PCB_EGKW_SECT_GATE, 0xFF7F, "gate", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"addlevel", T_INT, 12, 1}, + {"swap", T_INT, 13, 1}, + {"symno", T_INT, 14, 2}, + {"name", T_STR, 16, 8}, + TERM + }, + }, + { PCB_EGKW_SECT_ELEMENT, 0xFF53, "element", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"library", T_INT, 12, 2}, + {"package", T_INT, 14, 2}, + {"bin_rot", T_UBF, 16, BITFIELD(2, 0, 11)}, /* result is n*1024 */ + {"mirrored", T_BMB, 17, 0x10}, + {"spin", T_BMB, 17, 0x40}, + TERM + }, + }, + { PCB_EGKW_SECT_ELEMENT2, 0xFF5F, "element2", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"name", T_STR, 2, 8}, + {"value", T_STR, 10, 14}, + TERM + }, + }, + { PCB_EGKW_SECT_INSTANCE, 0xFFFF, "instance", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"placed", T_INT, 12, 2}, /* == True for v4 */ + {"gateno", T_INT, 14, 2}, + {"bin_rot", T_UBF, 16, BITFIELD(2, 10, 11)}, /* was 0, 11}, */ + /* _get_uint16_mask(16, 0x0c00) */ + {"mirrored", T_UBF, 16, BITFIELD(2, 12, 12)}, + /* _get_uint16_mask(16, 0x1000) */ + {"smashed", T_BMB, 18, 0x01}, + TERM + }, + }, + { PCB_EGKW_SECT_TEXT, 0xFF53, "text", /* basic text block */ + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"half_size", T_INT, 12, 2}, + {"ratio", T_UBF, 14, BITFIELD(2, 2, 6)}, + /*self._get_uint8_mask(14, 0x7c) >> 2 },*/ + {"bin_rot" , T_UBF, 16, BITFIELD(2, 0, 11)}, + /*self._get_uint16_mask(16, 0x0fff)*/ + {"mirrored" , T_UBF, 16, BITFIELD(2, 12, 12)}, + /*bool(self._get_uint16_mask(16, 0x1000))*/ + {"spin" , T_UBF, 16, BITFIELD(2, 14, 14)}, + /*bool(self._get_uint16_mask(16, 0x4000))*/ + {"textfield", T_STR, 18, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_NETBUSLABEL, 0xFFFF, "netbuslabel", /* text base section equiv. */ + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"size", T_INT, 12, 2}, + {"ratio", T_UBF, 14, BITFIELD(2, 2, 6)}, + /*self._get_uint8_mask(14, 0x7c) >> 2 },*/ + {"bin_rot" , T_UBF, 16, BITFIELD(2, 0, 11)}, + /*self._get_uint16_mask(16, 0x0fff)*/ + {"mirrored" , T_UBF, 16, BITFIELD(2, 12, 12)}, + /*bool(self._get_uint16_mask(16, 0x1000))*/ + {"spin" , T_UBF, 16, BITFIELD(2, 14, 14)}, + /*bool(self._get_uint16_mask(16, 0x4000))*/ + {"textfield", T_STR, 18, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_SMASHEDNAME, 0xFF73, "name", /* text base section equiv. */ + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"size", T_INT, 12, 2}, + {"ratio", T_UBF, 14, BITFIELD(2, 2, 6)}, + /*self._get_uint8_mask(14, 0x7c) >> 2 },*/ + {"bin_rot" , T_UBF, 16, BITFIELD(2, 0, 11)}, + /*self._get_uint16_mask(16, 0x0fff)*/ + {"mirrored" , T_UBF, 16, BITFIELD(2, 12, 12)}, + /*bool(self._get_uint16_mask(16, 0x1000))*/ + {"spin" , T_UBF, 16, BITFIELD(2, 14, 14)}, + /*bool(self._get_uint16_mask(16, 0x4000))*/ + {"textfield", T_STR, 18, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_SMASHEDVALUE, 0xFF73, "value", /* text base section equiv. */ + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"size", T_INT, 12, 2}, + {"ratio", T_UBF, 14, BITFIELD(2, 2, 6)}, + /*self._get_uint8_mask(14, 0x7c) >> 2 },*/ + {"bin_rot" , T_UBF, 16, BITFIELD(2, 0, 11)}, + /*self._get_uint16_mask(16, 0x0fff)*/ + {"mirrored" , T_UBF, 16, BITFIELD(2, 12, 12)}, + /*bool(self._get_uint16_mask(16, 0x1000))*/ + {"spin" , T_UBF, 16, BITFIELD(2, 14, 14)}, + /*bool(self._get_uint16_mask(16, 0x4000))*/ + {"textfield", T_STR, 18, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_PACKAGEVARIANT, 0xFF7F, "packagevariant", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"package", T_INT, 4, 2}, + {"table", T_STR, 6, 13}, + {"name", T_STR, 19, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_DEVICE, 0xFF7F, "device", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_RECURSIVE, "gates"}, /* gates */ + {4, 2, SS_RECURSIVE, "variants"}, /* variants */ + /* ? {2, 2, SS_DIRECT, NULL},*/ + TERM + }, + { /* attributes */ + {"gates", T_INT, 2, 2}, + {"variants", T_INT, 4, 2}, + {"prefix", T_STR, 8, 5}, + {"desc", T_STR, 13, 5}, + {"name", T_STR, 18, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_PART, 0xFFFF, "part", + { /* field match */ + TERM + }, + { /* subsection sizes */ + {2, 2, SS_DIRECT, NULL}, + TERM + }, + { /* attributes */ + {"lib", T_INT, 4, 2}, + {"device", T_INT, 6, 2}, + {"variant", T_INT, 8, 1}, + {"technology", T_INT, 9, 2}, + {"name", T_STR, 11, 5}, + {"value", T_STR, 16, 8}, + TERM + }, + }, + { PCB_EGKW_SECT_SCHEMABUS, 0xFFFF }, + { PCB_EGKW_SECT_VARIANTCONNECTIONS, 0xFF7F, "variantconnections", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + /* a sequence of 22 bytes or 11 H?, in format (x1,y1), (x2,y2), ... */ + TERM + }, + }, + { PCB_EGKW_SECT_SCHEMACONNECTION, 0xFFFF }, + { PCB_EGKW_SECT_CONTACTREF, 0xFFF57, "contactref", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"partnumber", T_INT, 4, 2}, + {"pin", T_INT, 6, 2}, + TERM + }, + }, + { PCB_EGKW_SECT_SMASHEDPART, 0xFFFF, "smashedpart", /* same as text basesection */ + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"size", T_INT, 12, 2}, + {"ratio", T_UBF, 14, BITFIELD(2, 2, 6)}, + /*self._get_uint8_mask(14, 0x7c) >> 2 },*/ + {"bin_rot" , T_UBF, 16, BITFIELD(2, 0, 11)}, + /*self._get_uint16_mask(16, 0x0fff)*/ + {"mirrored" , T_UBF, 16, BITFIELD(2, 12, 12)}, + /*bool(self._get_uint16_mask(16, 0x1000))*/ + {"spin" , T_UBF, 16, BITFIELD(2, 14, 14)}, + /*bool(self._get_uint16_mask(16, 0x4000))*/ + {"textfield", T_STR, 18, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_SMASHEDGATE, 0xFFFF, "smashedgate", /* same as text basesection */ + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"size", T_INT, 12, 2}, + {"ratio", T_UBF, 14, BITFIELD(2, 2, 6)}, + /*self._get_uint8_mask(14, 0x7c) >> 2 },*/ + {"bin_rot" , T_UBF, 16, BITFIELD(2, 0, 11)}, + /*self._get_uint16_mask(16, 0x0fff)*/ + {"mirrored" , T_UBF, 16, BITFIELD(2, 12, 12)}, + /*bool(self._get_uint16_mask(16, 0x1000))*/ + {"spin" , T_UBF, 16, BITFIELD(2, 14, 14)}, + /*bool(self._get_uint16_mask(16, 0x4000))*/ + {"textfield", T_STR, 18, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_ATTRIBUTE, 0xFF7F, "attribute", /* same as text basesection */ + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"size", T_INT, 12, 2}, + {"ratio", T_UBF, 14, BITFIELD(2, 2, 6)}, + /*self._get_uint8_mask(14, 0x7c) >> 2 },*/ + {"bin_rot" , T_UBF, 16, BITFIELD(2, 0, 11)}, + /*self._get_uint16_mask(16, 0x0fff)*/ + {"mirrored" , T_UBF, 16, BITFIELD(2, 12, 12)}, + /*bool(self._get_uint16_mask(16, 0x1000))*/ + {"spin" , T_UBF, 16, BITFIELD(2, 14, 14)}, + /*bool(self._get_uint16_mask(16, 0x4000))*/ + {"textfield", T_STR, 18, 5}, + TERM + }, + }, + { PCB_EGKW_SECT_ATTRIBUTEVALUE, 0xFFFF, "attribute-value", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"symbol", T_STR, 2, 5}, + {"attribute", T_STR, 7, 17}, + TERM + }, + }, + { PCB_EGKW_SECT_FRAME, 0xFFFF, "frame", + { /* field match */ + TERM + }, + { /* subsection sizes */ + /*{"drawables-subsec", T_INT, 2, 2},*/ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x1", T_INT, 4, 4}, + {"y1", T_INT, 8, 4}, + {"x2", T_INT, 12, 4}, + {"y2", T_INT, 16, 4}, + {"cols", T_INT, 20, 1}, + {"rows", T_INT, 21, 1}, + {"borders", T_INT, 22, 1}, + TERM + }, + }, + { PCB_EGKW_SECT_SMASHEDXREF, 0xFFFF, "smashedxref", + { /* field match */ + TERM + }, + { /* subsection sizes */ + TERM + }, + { /* attributes */ + {"layer", T_UBF, 3, BITFIELD(1,0,7)}, + {"x", T_INT, 4, 4}, + {"y", T_INT, 8, 4}, + {"size", T_INT, 12, 2}, + {"ratio", T_UBF, 14, BITFIELD(2, 2, 6)}, + /*self._get_uint8_mask(14, 0x7c) >> 2 },*/ + {"bin_rot" , T_UBF, 16, BITFIELD(2, 0, 11)}, + /*self._get_uint16_mask(16, 0x0fff)*/ + {"mirrored" , T_UBF, 16, BITFIELD(2, 12, 12)}, + /*bool(self._get_uint16_mask(16, 0x1000))*/ + {"spin" , T_UBF, 16, BITFIELD(2, 14, 14)}, + /*bool(self._get_uint16_mask(16, 0x4000))*/ + {"textfield", T_STR, 18, 5}, + TERM + }, + }, + + /* unknown leaves */ + { 0x5300, 0xFFFF }, + { 0x2d84, 0xFFFF }, + /* end of table */ + { 0 } +}; + +static unsigned long load_ulong_se(unsigned char *src, int offs, unsigned long len, int sign_extend) +{ + int n; + unsigned long l = 0; + + if ((sign_extend) && (src[offs+len-1] & 0x80)) + l = -1; + + for(n = 0; n < len; n++) { + l <<= 8; + l |= src[offs+len-n-1]; + } + return l; +} + +static unsigned long load_ulong(unsigned char *src, int offs, unsigned long len) +{ + return load_ulong_se(src, offs, len, 0); +} + +static long load_long(unsigned char *src, int offs, unsigned long len) +{ + return (long)load_ulong_se(src, offs, len, 1); +} + +static int load_bmb(unsigned char *src, int offs, unsigned long len) +{ + return !!(src[offs] & len); +} + +static unsigned long load_ubf(unsigned char *src, int offs, unsigned long field) +{ + unsigned long val; + int len, first, last, mask; + + len = (field >> 16) & 0xff; + first = (field >> 8) & 0xff; + last = field & 0xff; + mask = (1 << (last - first + 1)) - 1; + + val = load_ulong(src, offs, len); + val >>= first; + return val & mask; +} + +static char *load_str(unsigned char *src, char *dst, int offs, unsigned long len) +{ + memcpy(dst, src+offs, len); + dst[len] = '\0'; + return dst; +} + +static double load_double(unsigned char *src, int offs, unsigned long len) +{ + double d; + assert(len == sizeof(double)); + memcpy(&d, src+offs, sizeof(double)); + return d; +} + +/* a function to convert binary format rotations into XML compatible SMRXXX format */ +int bin_rot2degrees(const char *rot, char *tmp, int mirrored, int spin) +{ + long deg; + char *end, *cend; + if (rot == NULL) { + return -1; + } else { + end = tmp; + if (spin) *end++ = 'S'; + if (mirrored) *end++ = 'M'; + *end++ = 'R'; + end[0] = '0'; + end[1] = '\0'; /* default "R0" for v3,4,5 where bin_rot == 0*/ + + deg = strtol(rot, &cend, 10); + /*printf("Calculated deg == %ld pre bin_rot2degree conversion\n", deg);*/ + if (*cend != '\0') { +TODO(": convert this to proper error reporting") + printf("unexpected binary field 'rot' value suffix\n"); + return -1; + } + if (deg >= 1024) { + deg = (360*deg)/4096; /* v4, v5 do n*1024 */ + sprintf(end, "%ld", deg); + /*printf("Did deg == %ld bin_rot2degree conversion\n", deg);*/ + return 0; + } else if (deg > 0) { /* v3 */ + deg = deg & 0x00f0; /* only need bottom 4 bits for v3, it seems*/ + deg = deg*90; + /*printf("About to do deg < 1024 bin_rot2degree conversion\n");*/ + sprintf(end, "%ld", deg); + return 0; + } else { + /*printf("Default deg == 0 bin_rot2degree conversion\n");*/ + return 0; + } + } + return -1; /* should not get here */ +} + +static const char *egb_next_long_text(egb_ctx_t *egb_ctx) +{ + const char *res = egb_ctx->free_text_cursor; + + if (res == NULL) { + rnd_message(RND_MSG_ERROR, "Invalid free-text reference (out of strings)\n"); + return ""; + } + + /* seek the next string */ + while(*egb_ctx->free_text_cursor != '\0') egb_ctx->free_text_cursor++; + egb_ctx->free_text_cursor++; + + /* detect end of list by the terminating empty string */ + if (*egb_ctx->free_text_cursor == '\0') + egb_ctx->free_text_cursor = NULL; + + return res; +} + +int read_notes(void *ctx, FILE *f, const char *fn, egb_ctx_t *egb_ctx) +{ + unsigned char block[8]; + int text_remaining = 0; + egb_ctx->free_text_len = 0; + egb_ctx->free_text = NULL; + egb_ctx->free_text_cursor = NULL; + + if (fread(block, 1, 8, f) != 8) { + rnd_message(RND_MSG_ERROR, "Short read in free text section preamble. Text section not found.\n"); + return -1; + } + + if (load_long(block, 0, 1) == 0x13 && load_long(block, 1, 1) == 0x12) { + } + else { + rnd_message(RND_MSG_ERROR, "Failed to find 0x1312 start of pre-DRC free text section.\n"); + return -1; + } + + text_remaining = egb_ctx->free_text_len = (int)load_long(block, 4, 2); + text_remaining += 4; /* there seems to be a 4 byte checksum or something at the end */ + +TODO("TODO instead of skipping the text, we need to load it completely with drc_ctx->free_text pointing to it") + egb_ctx->free_text = malloc(text_remaining); + if (fread(egb_ctx->free_text, 1, text_remaining, f) != text_remaining) { + rnd_message(RND_MSG_ERROR, "Short read: free text block content. Truncated file?\n"); + return -1; + } + egb_ctx->free_text_cursor = egb_ctx->free_text; + + return 0; +} + +int read_drc(void *ctx, FILE *f, const char *fn, egb_ctx_t *drc_ctx) +{ + unsigned char block[4]; + int DRC_length_used = 244; + unsigned char DRC_block[244]; + unsigned char c; + int DRC_preamble_end_found = 0; + + /* these are sane, default values for DRC in case not present, i.e. in v3 no DRC section */ + drc_ctx->mdWireWire = 12; + drc_ctx->msWidth = 10; + drc_ctx->rvPadTop = 0.25; + drc_ctx->rvPadInner = 0.25; + drc_ctx->rvPadBottom = 0.25; + + if (fread(block, 1, 4, f) != 4) { +TODO(": convert this to proper error reporting") + rnd_trace("E: short attempted DRC preamble read; preamble not found. Truncated file?\n"); + return -1; + } + + /* look for DRC start sentinel */ + if (!(load_long(block, 0, 1) == 0x10 + && load_long(block, 1, 1) == 0x04 + && load_long(block, 2, 1) == 0x00 + && load_long(block, 3, 1) == 0x20)) { +TODO(": convert this to proper error reporting") + rnd_trace("E: start of DRC preamble not found where it was expected.\n"); + rnd_trace("E: drc byte 0 : %d\n", (int)load_long(block, 0, 1) ); + rnd_trace("E: drc byte 1 : %d\n", (int)load_long(block, 1, 1) ); + rnd_trace("E: drc byte 2 : %d\n", (int)load_long(block, 2, 1) ); + rnd_trace("E: drc byte 3 : %d\n", (int)load_long(block, 3, 1) ); + return -1; + } + + while (!DRC_preamble_end_found) { + if (fread(&c, 1, 1, f) != 1) { /* the text preamble is not necessarily n * 4 bytes */ +TODO(": convert this to proper error reporting") + rnd_trace("E: short attempted DRC preamble read. Truncated file?\n"); + return -1; + } else { + if (c == '\0') { /* so we step through, looking for each 0x00 */ + if (fread(block, 1, 4, f) != 4) { /* the text preamble seems to n * 24 bytes */ +TODO(": convert this to proper error reporting") + rnd_trace("E: short attempted DRC preamble read. Truncated file?\n"); + return -1; + } + if (load_long(block, 0, 1) == 0x78 + && load_long(block, 1, 1) == 0x56 + && load_long(block, 2, 1) == 0x34 + && load_long(block, 3, 1) == 0x12) { + DRC_preamble_end_found = 1; + } + } + } + } + + if (fread(DRC_block, 1, DRC_length_used, f) != DRC_length_used) { +TODO(": convert this to proper error reporting") + rnd_trace("E: short DRC value block read. DRC section incomplete. Truncated file?\n"); + return -1; + } + + /* first ~134 bytes contain the most useful DRC stuff, such as + wire2wire wire2pad wire2via pad2pad pad2via via2via pad2smd via2smd smd2smd + also, restring order: padtop padinner padbottom viaouter viainner + (microviaouter microviainner) */ + + drc_ctx->mdWireWire = (long)(load_long(DRC_block, 0, 4)/2.54/100); + drc_ctx->wire2pad = (long)(load_long(DRC_block, 4, 4)/2.54/100); + drc_ctx->wire2via = (long)(load_long(DRC_block, 8, 4)/2.54/100); + drc_ctx->pad2pad = (long)(load_long(DRC_block, 12, 4)/2.54/100); + drc_ctx->pad2via = (long)(load_long(DRC_block, 16, 4)/2.54/100); + drc_ctx->via2via = (long)(load_long(DRC_block, 20, 4)/2.54/100); + drc_ctx->pad2smd = (long)(load_long(DRC_block, 24, 4)/2.54/100); + drc_ctx->via2smd = (long)(load_long(DRC_block, 28, 4)/2.54/100); + drc_ctx->smd2smd = (long)(load_long(DRC_block, 32, 4)/2.54/100); + drc_ctx->copper2dimension = (long)(load_long(DRC_block, 44, 4)/2.54/100); + drc_ctx->drill2hole = (long)(load_long(DRC_block, 52, 4)/2.54/100); + + drc_ctx->msWidth = (long)(load_long(DRC_block, 64, 4)/2.54/100); + drc_ctx->minDrill = (long)(load_long(DRC_block, 68, 4)/2.54/100); + + /*in version 5, this is wedged inbetween drill and pad ratios: + min_micro_via, blind_via_ratio, int, float, 12 bytes*/ + + drc_ctx->rvPadTop = load_double(DRC_block, 84, 8); + drc_ctx->rvPadInner = load_double(DRC_block, 92, 8); + drc_ctx->rvPadBottom = load_double(DRC_block, 100, 8); + + drc_ctx->rvViaOuter = load_double(DRC_block, 108, 8); + drc_ctx->rvViaInner = load_double(DRC_block, 116, 8); + drc_ctx->rvMicroViaOuter = load_double(DRC_block, 124, 8); + drc_ctx->rvMicroViaInner = load_double(DRC_block, 132, 8); + + /* not entirely sure what these do as they don't map obviously to XML */ + drc_ctx->restring_limit1_mil = (long)load_long(DRC_block, 140, 4)/2.54/100; + drc_ctx->restring_limit2_mil = (long)load_long(DRC_block, 144, 4)/2.54/100; + drc_ctx->restring_limit3_mil = (long)load_long(DRC_block, 148, 4)/2.54/100; + drc_ctx->restring_limit4_mil = (long)load_long(DRC_block, 152, 4)/2.54/100; + drc_ctx->restring_limit5_mil = (long)load_long(DRC_block, 156, 4)/2.54/100; + drc_ctx->restring_limit6_mil = (long)load_long(DRC_block, 160, 4)/2.54/100; + drc_ctx->restring_limit7_mil = (long)load_long(DRC_block, 164, 4)/2.54/100; + drc_ctx->restring_limit8_mil = (long)load_long(DRC_block, 168, 4)/2.54/100; + drc_ctx->restring_limit9_mil = (long)load_long(DRC_block, 172, 4)/2.54/100; + drc_ctx->restring_limit10_mil = (long)load_long(DRC_block, 176, 4)/2.54/100; + drc_ctx->restring_limit11_mil = (long)load_long(DRC_block, 180, 4)/2.54/100; + drc_ctx->restring_limit12_mil = (long)load_long(DRC_block, 184, 4)/2.54/100; + drc_ctx->restring_limit13_mil = (long)load_long(DRC_block, 188, 4)/2.54/100; + drc_ctx->restring_limit14_mil = (long)load_long(DRC_block, 192, 4)/2.54/100; + + /* pad shapes */ + drc_ctx->psTop = load_long(DRC_block, 196, 4); + drc_ctx->psBottom = load_long(DRC_block, 200, 4); + drc_ctx->psFirst = load_long(DRC_block, 204, 4); + + /* not sure how these map to XML design rules parameters*/ + drc_ctx->mask_percentages1_ratio = load_double(DRC_block, 208, 8); + drc_ctx->mask_percentages2_ratio = load_double(DRC_block, 216, 8); + drc_ctx->mask_limit1_mil = (long)load_long(DRC_block, 224, 4)/2.54/100; + drc_ctx->mask_limit2_mil = (long)load_long(DRC_block, 228, 4)/2.54/100; + drc_ctx->mask_limit3_mil = (long)load_long(DRC_block, 232, 4)/2.54/100; + drc_ctx->mask_limit4_mil = (long)load_long(DRC_block, 236, 4)/2.54/100; + + /* populate the drc_ctx struct to return the result of the DRC block read attempt */ + + return 0; +} + + +int read_block(long *numblocks, int level, void *ctx, FILE *f, const char *fn, egb_node_t *parent) +{ + unsigned char block[24]; + const pcb_eagle_script_t *sc; + const subsect_t *ss; + const attrs_t *at; + const fmatch_t *fm; + char ind[256]; + int processed = 0; + egb_node_t *lpar; + + memset(ind, ' ', level); + ind[level] = '\0'; + + /* load the current block */ + if (fread(block, 1, 24, f) != 24) { +TODO(": convert this to proper error reporting") + rnd_trace("E: short read\n"); + return -1; + } + processed++; + + if (*numblocks < 0 && load_long(block, 0, 1) == 0x10) { + *numblocks = load_long(block, 4, 4); + } + + for(sc = pcb_eagle_script; sc->cmd != 0; sc++) { + int match = 1; + unsigned int cmdh = (sc->cmd >> 8) & 0xFF, cmdl = sc->cmd & 0xFF; + unsigned int mskh = (sc->cmd_mask >> 8) & 0xFF, mskl = sc->cmd_mask & 0xFF; + + assert((cmdh & mskh) == cmdh); + assert((cmdl & mskl) == cmdl); + + if ((cmdh != (block[0] & mskh)) || (cmdl != (block[1] & mskl))) + continue; + + for(fm = sc->fmatch; fm->offs != 0; fm++) { + if (load_long(block, fm->offs, fm->len) != fm->val) { + match = 0; + break; + } + } + if (match) + goto found; + } + +TODO(": convert this to proper error reporting") + rnd_trace("E: unknown block ID 0x%02x%02x at offset %ld\n", block[0], block[1], ftell(f)); + return -1; + + found:; + + if (sc->name != NULL) + parent = egb_node_append(parent, egb_node_alloc(sc->cmd, sc->name)); + else + parent = egb_node_append(parent, egb_node_alloc(sc->cmd, "UNKNOWN")); + + for(at = sc->attrs; at->name != NULL; at++) { + char buff[128]; + *buff = '\0'; + switch(at->type) { + case T_BMB: + sprintf(buff, "%d", load_bmb(block, at->offs, at->len)); + break; + case T_UBF: + sprintf(buff, "%ld", load_ubf(block, at->offs, at->len)); + break; + case T_INT: + sprintf(buff, "%ld", load_long(block, at->offs, at->len)); + break; + case T_DBL: + sprintf(buff, "%f", load_double(block, at->offs, at->len)); + break; + case T_STR: + load_str(block, buff, at->offs, at->len); + break; + } + egb_node_prop_set(parent, at->name, buff); + } + + *numblocks = *numblocks - 1; + + for(ss = sc->subs; ss->offs != 0; ss++) { + unsigned long int n, numch = load_ulong(block, ss->offs, ss->len); + + if (ss->ss_type == SS_DIRECT) { + long lp = 0; + if (ss->tree_name != NULL) + lpar = egb_node_append(parent, egb_node_alloc(0, ss->tree_name)); + else + lpar = parent; + for(n = 0; n < numch && *numblocks > 0; n++) { + int res = read_block(numblocks, level+1, ctx, f, fn, lpar); + if (res < 0) + return res; + processed += res; + lp += res; + } + } + else { + long rem, lp = 0; + if (ss->tree_name != NULL) + lpar = egb_node_append(parent, egb_node_alloc(0, ss->tree_name)); + else + lpar = parent; + if (ss->ss_type == SS_RECURSIVE_MINUS_1) + numch--; + rem = numch; + for(n = 0; n < numch && rem > 0; n++) { + int res = read_block(&rem, level+1, ctx, f, fn, lpar); + if (res < 0) + return res; + *numblocks -= res; + processed += res; + lp += res; + } + } + } + + return processed; +} + +static egb_node_t *find_node(egb_node_t *first, int id) +{ + egb_node_t *n; + + for(n = first; n != NULL; n = n->next) + if (n->id == id) + return n; + + return NULL; +} + +static egb_node_t *find_node_name(egb_node_t *first, const char *id_name) +{ + egb_node_t *n; + + for(n = first; n != NULL; n = n->next) + if (strcmp(n->id_name, id_name) == 0) + return n; + + return NULL; +} + +static long fix_three_byte_read(long num, int negflag) { /* used to turn three byte T_INT read into 3 byte uint value */ + if (num < 0 && negflag) { + return num; + } else if (num > 0 && negflag) { /* this should only happen with 'c' built from three distinct bytes */ + return num - 0x800000; + } else if (num < 0 && !negflag) { + return num + 0x800000; + } + return num; /* i.e. if (num > 0 && !negflag) */ +} + +static long fix_one_byte_read(long num) { /* used to turn one byte T_INT read into 1 byte uint value */ + if (num < 0) { + return (num + 0x80); + } + return num; +} + +static int arc_decode(void *ctx, egb_node_t *elem, int arctype, int linetype) +{ + htss_entry_t *e; + + char itoa_buffer[64]; + long c, cx, cy, x1, x2, y1, y2, x3, y3, radius; + double theta_1, theta_2, delta_theta; + double delta_x, delta_y; + int arc_flags = 0; + int clockwise = 0; + c = 0; + if (linetype == 129 || arctype == 0) { + arc_flags = atoi(egb_node_prop_get(elem, "arc_negflags")); + for (e = htss_first(&elem->props); e; e = htss_next(&elem->props, e)) { + if (strcmp(e->key, "arc_x1") == 0) { + x1 = fix_three_byte_read(atoi(e->value), arc_flags & 0x02); + sprintf(itoa_buffer, "%ld", x1); + egb_node_prop_set(elem, "x1", itoa_buffer); + } else if (strcmp(e->key, "arc_y1") == 0) { + y1 = fix_three_byte_read(atoi(e->value), arc_flags & 0x04); + sprintf(itoa_buffer, "%ld", y1); + egb_node_prop_set(elem, "y1", itoa_buffer); + } else if (strcmp(e->key, "arc_x2") == 0) { + x2 = fix_three_byte_read(atoi(e->value), arc_flags & 0x08); + sprintf(itoa_buffer, "%ld", x2); + egb_node_prop_set(elem, "x2", itoa_buffer); + } else if (strcmp(e->key, "arc_y2") == 0) { + y2 = fix_three_byte_read(atoi(e->value), arc_flags & 0x10); + sprintf(itoa_buffer, "%ld", y2); + egb_node_prop_set(elem, "y2", itoa_buffer); + } else if (strcmp(e->key, "arc_c1") == 0) { + c += fix_one_byte_read(atoi(e->value)); + } else if (strcmp(e->key, "arc_c2") == 0) { + c += 256*fix_one_byte_read(atoi(e->value)); + } else if (strcmp(e->key, "arc_c3") == 0) { + c += 256*256*fix_one_byte_read(atoi(e->value)); + } else if (strcmp(e->key, "clockwise") == 0) { + clockwise = atoi(e->value); + } + } + c = fix_three_byte_read(c, arc_flags & 0x01); + x3 = (x1+x2)/2; + y3 = (y1+y2)/2; + + if (RND_ABS(x2-x1) < RND_ABS(y2-y1)) { + cx = c; + cy = (long)((x3-cx)*(x2-x1)/(double)((y2-y1)) + y3); + } else { + cy = c; + cx = (long)((y3-cy)*(y2-y1)/(double)((x2-x1)) + x3); + } + radius = (long)rnd_distance((double)cx, (double)cy, (double)x2, (double)y2); + sprintf(itoa_buffer, "%ld", radius); + egb_node_prop_set(elem, "radius", itoa_buffer); + sprintf(itoa_buffer, "%ld", cx); + egb_node_prop_set(elem, "x", itoa_buffer); + sprintf(itoa_buffer, "%ld", cy); + egb_node_prop_set(elem, "y", itoa_buffer); + + if (cx == x2 && cy == y1 && x2 < x1 && y2 > y1) { /* RUQ */ + egb_node_prop_set(elem, "StartAngle", "90"); + egb_node_prop_set(elem, "Delta", "90"); + } else if (cx == x1 && cy == y2 && x2 < x1 && y1 > y2) { /* LUQ */ + egb_node_prop_set(elem, "StartAngle", "0"); + egb_node_prop_set(elem, "Delta", "90"); + } else if (cx == x2 && cy == y1 && x2 > x1 && y1 > y2) { /* LLQ */ + egb_node_prop_set(elem, "StartAngle", "270"); + egb_node_prop_set(elem, "Delta", "90"); + } else if (cx == x1 && cy == y2 && x2 > x1 && y2 > y1) { /* RLQ */ + egb_node_prop_set(elem, "StartAngle", "180"); + egb_node_prop_set(elem, "Delta", "90"); + } else { + delta_x = (double)(x1 - cx); + delta_y = (double)(y1 - cy); + theta_1 = RND_RAD_TO_DEG*atan2(-delta_y, delta_x); + theta_2 = RND_RAD_TO_DEG*atan2(-(y2 - cy), (x2 - cx)); + + theta_1 = 180 - theta_1; /* eagle coord system */ + theta_2 = 180 - theta_2; /* eagle coord system */ + + delta_theta = (theta_2 - theta_1); + + while (theta_1 > 360) { + theta_1 -= 360; + } + + while (delta_theta < -180) { /* this seems to fix pathological cases */ + delta_theta += 360; + } + while (delta_theta > 180) { + delta_theta -= 360; + } + + sprintf(itoa_buffer, "%ld", (long)(theta_1)); + egb_node_prop_set(elem, "StartAngle", itoa_buffer); + sprintf(itoa_buffer, "%ld", (long)(delta_theta)); + egb_node_prop_set(elem, "Delta", itoa_buffer); + } +TODO("TODO still need to fine tune non-trivial non 90 degree arcs start and delta for 0x81, 0x00") + } else if ((linetype > 0 && linetype < 129) || arctype > 0) { + int x1_ok, x2_ok, y1_ok, y2_ok, cxy_ok; + x1_ok = x2_ok = y1_ok = y2_ok = cxy_ok = 0; + for (e = htss_first(&elem->props); e; e = htss_next(&elem->props, e)) { + if (strcmp(e->key, "arctype_other_x1") == 0) { + x1 = atoi(e->value); + x1_ok = 1; + } else if (strcmp(e->key, "arctype_other_y1") == 0) { + y1 = atoi(e->value); + y1_ok = 1; + } else if (strcmp(e->key, "arctype_other_x2") == 0) { + x2 = atoi(e->value); + x2_ok = 1; + } else if (strcmp(e->key, "arctype_other_y2") == 0) { + y2 = atoi(e->value); + y2_ok = 1; + } else if (strcmp(e->key, "linetype_0_x1") == 0) { + x1 = atoi(e->value); + x1_ok = 1; + } else if (strcmp(e->key, "linetype_0_y1") == 0) { + y1 = atoi(e->value); + y1_ok = 1; + } else if (strcmp(e->key, "linetype_0_x2") == 0) { + x2 = atoi(e->value); + x2_ok = 1; + } else if (strcmp(e->key, "linetype_0_y2") == 0) { + y2 = atoi(e->value); + y2_ok = 1; + } + + } + if (linetype == 0x78 || arctype == 0x01) { + cx = MIN(x1, x2); + cy = MIN(y1, y2); + cxy_ok = 1; + egb_node_prop_set(elem, "StartAngle", "180"); + egb_node_prop_set(elem, "Delta", "90"); + } else if (linetype == 0x79 || arctype == 0x02) { + cx = MAX(x1, x2); + cy = MIN(y1, y2); + cxy_ok = 1; + egb_node_prop_set(elem, "StartAngle", "270"); + egb_node_prop_set(elem, "Delta", "90"); + } else if (linetype == 0x7a || arctype == 0x03) { + cx = MAX(x1, x2); + cy = MAX(y1, y2); + cxy_ok = 1; + egb_node_prop_set(elem, "StartAngle", "0"); + egb_node_prop_set(elem, "Delta", "90"); + } else if (linetype == 0x7b || arctype == 0x04) { + cx = MIN(x1, x2); + cy = MAX(y1, y2); + cxy_ok = 1; + egb_node_prop_set(elem, "StartAngle", "90"); + egb_node_prop_set(elem, "Delta", "90"); + } else if (linetype == 0x7c || arctype == 0x05) { /* 124 */ + cx = (x1 + x2)/2; + cy = (y1 + y2)/2; + cxy_ok = 1; + egb_node_prop_set(elem, "StartAngle", "90"); + egb_node_prop_set(elem, "Delta", "180"); + } else if (linetype == 0x7d || arctype == 0x06) { /* 125 */ + cx = (x1 + x2)/2; + cy = (y1 + y2)/2; + cxy_ok = 1; + egb_node_prop_set(elem, "StartAngle", "270"); + egb_node_prop_set(elem, "Delta", "180"); + } else if (linetype == 0x7e || arctype == 0x07) { + cx = (x1 + x2)/2; + cy = (y1 + y2)/2; + cxy_ok = 1; + egb_node_prop_set(elem, "StartAngle", "180"); + egb_node_prop_set(elem, "Delta", "180"); + } else if (linetype == 0x7f || arctype == 0x08) { + cx = (x1 + x2)/2; + cy = (y1 + y2)/2; + cxy_ok = 1; + egb_node_prop_set(elem, "StartAngle", "0"); + egb_node_prop_set(elem, "Delta", "180"); + } + + if (!cxy_ok) { + rnd_message(RND_MSG_ERROR, "cx and cy not set in arc/linetype: %d/%d\n", linetype, arctype); + cx = cy = 0; + } else if (!(x1_ok && x2_ok && y1_ok && y2_ok)) { + rnd_message(RND_MSG_ERROR, "x1/2 or y1/2 not set in binary arc\n"); + } + radius = (long)(rnd_distance((double)cx, (double)cy, (double)x2, (double)y2)); + sprintf(itoa_buffer, "%ld", radius); + egb_node_prop_set(elem, "radius", itoa_buffer); + + sprintf(itoa_buffer, "%ld", cx); + egb_node_prop_set(elem, "x", itoa_buffer); + sprintf(itoa_buffer, "%ld", cy); + egb_node_prop_set(elem, "y", itoa_buffer); + + } + return 0; +} + +/* Return the idxth library from the libraries subtree, or NULL if not found */ +static egb_node_t *library_ref_by_idx(egb_node_t *libraries, long idx) +{ + egb_node_t *n; + + /* count children of libraries */ + for(n = libraries->first_child; (n != NULL) && (idx > 1); n = n->next, idx--) ; + if (n == NULL) + rnd_message(RND_MSG_ERROR, "io_eagle bin: eagle_library_ref_by_idx() can't find library index %ld\n", idx); + return n; +} + +/* Return the idxth package from the library subtree, or NULL if not found */ +static egb_node_t *package_ref_by_idx(egb_node_t *library, long idx) +{ + egb_node_t *n, *pkgs; + + /* find library/0x1500->packages/0x1900 node */ + for(pkgs = library->first_child; (pkgs != NULL) && ((pkgs->id & 0xFF00) != 0x1900); pkgs = pkgs->next); + if (pkgs == NULL) + rnd_message(RND_MSG_ERROR, "io_eagle bin: eagle_pkg_ref_by_idx() can't find packages node in library tree\n", idx); + /* count children of library */ + for(n = pkgs->first_child; (n != NULL) && (idx > 1); n = n->next, idx--); + if (n == NULL) + rnd_message(RND_MSG_ERROR, "io_eagle bin: eagle_pkg_ref_by_idx() can't find package index %ld\n", idx); + return n; +} + +/* Return the idxth element instance from the elements subtree, or NULL if not found */ +static egb_node_t *elem_ref_by_idx(egb_node_t *elements, long idx) +{ + egb_node_t *n; + + /* count children of elelements */ + for(n = elements->first_child; (n != NULL) && (idx > 1); n = n->next, idx--) ; + if (n == NULL) + rnd_message(RND_MSG_ERROR, "io_eagle bin: eagle_elem_ref_by_idx() can't find element placement index %ld\n", idx); + return n; +} + +/* allocate the pin name of the j-th pin of a given element in the elements subtree to contactref node cr; allocate default of pin_number if name text not found for pin */ +static int cr_pin_name_by_elem_idx(egb_node_t *cr, egb_ctx_t *egb_ctx, long elem_idx) +{ + int pin_idx = (int)(atoi(egb_node_prop_get(cr, "pin"))); + int pin_num; + egb_node_t *p, *lib, *pkg; + egb_node_t *elements = egb_ctx->elements; + egb_node_t *libraries = egb_ctx->libraries; + egb_node_t *e = elem_ref_by_idx(elements, elem_idx); + + pin_num = pin_idx; + if (e == NULL) + return 1; + + lib = library_ref_by_idx(libraries, atoi(egb_node_prop_get(e, "library"))); + if (lib == NULL) + return 1; + + pkg = package_ref_by_idx(lib, atoi(egb_node_prop_get(e, "package"))); + if (pkg == NULL) + return 1; + + for (p = pkg->first_child; (p != NULL) && (pin_num > 1) ; p = p->next) { + if ((p->id & 0xFF00) == 0x2a00 || (p->id & 0xFF00) == 0x2b00 || (p->id & 0xFF00) == 0x2c00 ) { /* we found a pad _or_ pin _or_ SMD */ + pin_num--; + } + } + + if (p == NULL || pin_num > 1) { + egb_node_prop_set(cr, "pad", "PIN_NOT_FOUND"); + return 0; + } + + if (egb_node_prop_get(p, "name")) { + egb_node_prop_set(cr, "pad", egb_node_prop_get(p, "name")); + return 0; + } else { + egb_node_prop_set(cr, "pad", egb_node_prop_get(cr, "pin")); + return 0; + } +} + + +/* Return the refdes of the idxth element instance from the elements subtree, or NULL if not found */ +static const char *elem_refdes_by_idx(egb_node_t *elements, long idx) +{ + egb_node_t *e = elem_ref_by_idx(elements, idx); + if (e == NULL) + return NULL; + return egb_node_prop_get(e, "name"); +} + +/* bin path walk; the ... is a 0 terminated list of pcb_eagle_binkw_t IDs */ +static egb_node_t *tree_id_path(egb_node_t *subtree, ...) +{ + egb_node_t *nd = subtree; + pcb_eagle_binkw_t target; + va_list ap; + + va_start(ap, subtree); + + /* get next path element */ + while((target = va_arg(ap, pcb_eagle_binkw_t)) != 0) { + /* look for target on this level */ + for(nd = nd->first_child;;nd = nd->next) { + if (nd == NULL) {/* target not found on this level */ + va_end(ap); + return NULL; + } + if (nd->id == target) /* found, skip to next level */ + break; + } + } + + va_end(ap); + return nd; +} + + +static int postprocess_wires(void *ctx, egb_node_t *root) +{ + htss_entry_t *e; + egb_node_t *n; + int line_type = -1; + long half_width = 0; + char tmp[32]; + + if (root->id == PCB_EGKW_SECT_LINE) { + for (e = htss_first(&root->props); e; e = htss_next(&root->props, e)) + if (strcmp(e->key, "linetype") == 0 && strcmp(e->value, "0") == 0) { + line_type = 0; + } else if (strcmp(e->key, "linetype") == 0) { + line_type = atoi(e->value); + } + } + if(line_type == 0) { + for (e = htss_first(&root->props); e; e = htss_next(&root->props, e)) { + if (strcmp(e->key, "linetype_0_x1") == 0) { + egb_node_prop_set(root, "x1", e->value); + } else if (strcmp(e->key, "linetype_0_y1") == 0) { + egb_node_prop_set(root, "y1", e->value); + } else if (strcmp(e->key, "linetype_0_x2") == 0) { + egb_node_prop_set(root, "x2", e->value); + } else if (strcmp(e->key, "linetype_0_y2") == 0) { + egb_node_prop_set(root, "y2", e->value); + } else if (strcmp(e->key, "half_width") == 0) { + half_width = atoi(e->value); + sprintf(tmp, "%ld", half_width*2); + egb_node_prop_set(root, "width", tmp); + } /* <- added width doubling routine here */ + } + } else if (line_type > 0) { /* avoid parsing non wire and non arc elements */ + for (e = htss_first(&root->props); e; e = htss_next(&root->props, e)) { + if (strcmp(e->key, "half_width") == 0) { + half_width = atoi(e->value); + sprintf(tmp, "%ld", half_width*2); + egb_node_prop_set(root, "width", tmp); + } + } + arc_decode(ctx, root, -1, line_type); + } + + for(n = root->first_child; n != NULL; n = n->next) + postprocess_wires(ctx, n); + return 0; +} + +static int postprocess_arcs(void *ctx, egb_node_t *root) +{ + htss_entry_t *e; + egb_node_t *n; + int arc_type = -1; + long half_width= 0; + char tmp[32]; + + if (root->id == PCB_EGKW_SECT_ARC) { + for (e = htss_first(&root->props); e; e = htss_next(&root->props, e)) + if (strcmp(e->key, "arctype") == 0 && strcmp(e->value, "0") == 0) { + arc_type = 0; + } else if (strcmp(e->key, "arctype") == 0) { /* found types 5, 3, 2 so far */ + arc_type = atoi(e->value); + } + } + + if (arc_type == 0) { + for (e = htss_first(&root->props); e; e = htss_next(&root->props, e)) { + if (strcmp(e->key, "arc_x1") == 0) { + egb_node_prop_set(root, "x1", e->value); + } else if (strcmp(e->key, "arc_y1") == 0) { + egb_node_prop_set(root, "y1", e->value); + } else if (strcmp(e->key, "arc_x2") == 0) { + egb_node_prop_set(root, "x2", e->value); + } else if (strcmp(e->key, "arc_y2") == 0) { + egb_node_prop_set(root, "y2", e->value); + } else if (strcmp(e->key, "half_width") == 0) { + half_width = atoi(e->value); + sprintf(tmp, "%ld", half_width*2); + egb_node_prop_set(root, "width", tmp); + } /* <- added width doubling routine here */ + } + } else if (arc_type > 0) { /* avoid further parsing of non arc elements */ + for (e = htss_first(&root->props); e; e = htss_next(&root->props, e)) { + if (strcmp(e->key, "arctype_other_x1") == 0) { + egb_node_prop_set(root, "x1", e->value); + } else if (strcmp(e->key, "arctype_other_y1") == 0) { + egb_node_prop_set(root, "y1", e->value); + } else if (strcmp(e->key, "arctype_other_x2") == 0) { + egb_node_prop_set(root, "x2", e->value); + } else if (strcmp(e->key, "arctype_other_y2") == 0) { + egb_node_prop_set(root, "y2", e->value); + } else if (strcmp(e->key, "half_width") == 0) { + half_width = atoi(e->value); + sprintf(tmp, "%ld", half_width*2); + egb_node_prop_set(root, "width", tmp); + } /* <- added width doubling routine here */ + } + } + + arc_decode(ctx, root, arc_type, -1); + for(n = root->first_child; n != NULL; n = n->next) + postprocess_arcs(ctx, n); + return 0; +} + +/* post process circles to double their width */ +static int postprocess_circles(void *ctx, egb_node_t *root) +{ + htss_entry_t *e; + egb_node_t *n; + long half_width= 0; + char tmp[32]; + + if (root->id == PCB_EGKW_SECT_CIRCLE) { + for (e = htss_first(&root->props); e; e = htss_next(&root->props, e)) { + if (strcmp(e->key, "half_width") == 0) { + half_width = atoi(e->value); + sprintf(tmp, "%ld", half_width*2); + egb_node_prop_set(root, "width", tmp); + break; + } /* <- added width doubling routine here */ + } + } + + for(n = root->first_child; n != NULL; n = n->next) + postprocess_circles(ctx, n); + return 0; +} + +/* post process rotation to make the rotation values xml format 'RXXX' compliant */ +static int postprocess_rotation(void *ctx, egb_node_t *root, int node_type) +{ + egb_node_t *n; + char *v, tmp[32]; + int spin = 0, mirrored = 0; /* default not mirrored, not spinning */ + + if (root != NULL && root->id == node_type) { + v = htss_get(&root->props, "mirrored"); + if (v != NULL) + mirrored = (*v != '0'); + + v = htss_get(&root->props, "spin"); + if (v != NULL) + spin = (*v != '0'); + + v = htss_get(&root->props, "bin_rot"); + if (v != NULL) { + bin_rot2degrees(v, tmp, mirrored, spin); + egb_node_prop_set(root, "rot", tmp); + } + } + for(n = root->first_child; n != NULL; n = n->next) + postprocess_rotation(ctx, n, node_type); + return 0; +} + +/* we post process the PCB_EGKW_SECT_SMD nodes to double the dx and dy dimensions pre XML parsing */ +static int postprocess_smd(void *ctx, egb_node_t *root) +{ + htss_entry_t *e; + egb_node_t *n; + long half_dx = 0; + long half_dy = 0; + char tmp[32]; + + if (root != NULL && root->id == PCB_EGKW_SECT_SMD) { + for (e = htss_first(&root->props); e; e = htss_next(&root->props, e)) { + if (strcmp(e->key, "half_dx") == 0) { + half_dx = atoi(e->value); + sprintf(tmp, "%ld", half_dx*2); + egb_node_prop_set(root, "dx", tmp); + } else if (strcmp(e->key, "half_dy") == 0) { + half_dy = atoi(e->value); + sprintf(tmp, "%ld", half_dy*2); + egb_node_prop_set(root, "dy", tmp); + } + } + } + + for(n = root->first_child; n != NULL; n = n->next) + postprocess_smd(ctx, n); + return 0; +} + +/* we post process the +PCB_EGKW_SECT_PAD and PCB_EGKW_SECT_HOLE and PCB_EGKW_SECT_VIA and PCB_EGKW_SECT_TEXT +nodes to double the drill, diameter, text height dimensions pre XML parsing */ +static int postprocess_dimensions(void *ctx, egb_node_t *root) +{ + htss_entry_t *e; + egb_node_t *n; + long half_drill = 0; + long half_diameter = 0; + long half_size = 0; + char tmp[32]; +TODO("TODO padstacks - need to convert obround pins to appropriate padstack types") + if (root != NULL && (root->id == PCB_EGKW_SECT_PAD + || root->id == PCB_EGKW_SECT_HOLE || root->id == PCB_EGKW_SECT_VIA + || root->id == PCB_EGKW_SECT_TEXT)) { + for (e = htss_first(&root->props); e; e = htss_next(&root->props, e)) { + if (strcmp(e->key, "half_drill") == 0) { + half_drill = atoi(e->value); + sprintf(tmp, "%ld", half_drill*2); + egb_node_prop_set(root, "drill", tmp); + } else if (strcmp(e->key, "half_diameter") == 0) { + half_diameter = atoi(e->value); + sprintf(tmp, "%ld", half_diameter*2); + egb_node_prop_set(root, "diameter", tmp); + } else if (strcmp(e->key, "half_size") == 0) { + half_size = atoi(e->value); + sprintf(tmp, "%ld", half_size*2); + egb_node_prop_set(root, "size", tmp); + } + } + } + + for(n = root->first_child; n != NULL; n = n->next) + postprocess_dimensions(ctx, n); + return 0; +} + +static void fix_long_text(egb_ctx_t *egb_ctx, egb_node_t *root, const char *field_name) +{ + htss_entry_t *e; + + if (root->props.table == NULL) return; + e = htss_getentry(&root->props, field_name); + if (e == NULL) return; + if (*e->value == 127) { + free(e->value); + e->value = rnd_strdup(egb_next_long_text(egb_ctx)); + } +} + +/* we post process the PCB_EGKW_SECT_TEXT for 'free text' (long text) substitution */ +static int postprocess_free_text(egb_ctx_t *egb_ctx, egb_node_t *root) +{ + egb_node_t *n; + + switch(root->id) { + case PCB_EGKW_SECT_TEXT: + case PCB_EGKW_SECT_NETBUSLABEL: + case PCB_EGKW_SECT_SMASHEDNAME: + case PCB_EGKW_SECT_SMASHEDVALUE: + case PCB_EGKW_SECT_SMASHEDPART: + case PCB_EGKW_SECT_SMASHEDGATE: + case PCB_EGKW_SECT_ATTRIBUTE: + case PCB_EGKW_SECT_SMASHEDXREF: + fix_long_text(egb_ctx, root, "textfield"); + break; + case PCB_EGKW_SECT_LAYER: + case PCB_EGKW_SECT_LIBRARY: + case PCB_EGKW_SECT_SIGNAL: + case PCB_EGKW_SECT_SYMBOL: + case PCB_EGKW_SECT_SCHEMANET: + case PCB_EGKW_SECT_PAD: + case PCB_EGKW_SECT_SMD: + case PCB_EGKW_SECT_PIN: + case PCB_EGKW_SECT_GATE: + fix_long_text(egb_ctx, root, "name"); + break; + case PCB_EGKW_SECT_ELEMENT2: + case PCB_EGKW_SECT_PART: + fix_long_text(egb_ctx, root, "name"); + fix_long_text(egb_ctx, root, "value"); + break; + case PCB_EGKW_SECT_DEVICES: + case PCB_EGKW_SECT_SYMBOLS: + fix_long_text(egb_ctx, root, "library"); + break; + case PCB_EGKW_SECT_PACKAGEVARIANT: + fix_long_text(egb_ctx, root, "table"); + fix_long_text(egb_ctx, root, "name"); + break; + case PCB_EGKW_SECT_PACKAGE: + fix_long_text(egb_ctx, root, "desc"); + fix_long_text(egb_ctx, root, "name"); + break; + case PCB_EGKW_SECT_PACKAGES: + fix_long_text(egb_ctx, root, "desc"); + fix_long_text(egb_ctx, root, "library"); + break; + case PCB_EGKW_SECT_SCHEMA: + fix_long_text(egb_ctx, root, "xref_format"); + break; + case PCB_EGKW_SECT_ATTRIBUTEVALUE: + fix_long_text(egb_ctx, root, "symbol"); + fix_long_text(egb_ctx, root, "attribute"); + break; + case PCB_EGKW_SECT_DEVICE: + fix_long_text(egb_ctx, root, "prefix"); + fix_long_text(egb_ctx, root, "desc"); + fix_long_text(egb_ctx, root, "name"); + break; + default:; + } + + for(n = root->first_child; n != NULL; n = n->next) + postprocess_free_text(egb_ctx, n); + return 0; +} + +/* look for contactrefs, and 1) append "name"="refdes" fields to contactref nodes as "element" "refdes" and 2) append "pad" = (pin_name(if present) or default pin_num) for netlist loading */ +static int postproc_contactrefs(void *ctx, egb_ctx_t *egb_ctx) +{ + htss_entry_t *e; + egb_node_t *cr, *n, *next, *next2; + + if (egb_ctx->signals == NULL) + return 0; /* probably a library file */ + + for(n = egb_ctx->signals->first_child; n != NULL; n = next) { + next = n->next; + if (n->first_child != NULL && n->first_child->id == PCB_EGKW_SECT_CONTACTREF) { + for (cr = n->first_child; cr != NULL; cr = next2) { + next2 = cr->next; + for (e = htss_first(&cr->props); e; e = htss_next(&cr->props, e)) { + if (strcmp(e->key, "partnumber") == 0) { + int element_num = atoi(e->value); + egb_node_prop_set(cr, "element", elem_refdes_by_idx(egb_ctx->elements, (long) element_num)); + cr_pin_name_by_elem_idx(cr, egb_ctx, (long) element_num); + } + } + } + } + } + return 0; +} + + +/* look for elements, and subsequent element2 blocks, and copy name/value fields to element */ +static int postproc_elements(void *ctx, egb_ctx_t *egb_ctx) +{ + htss_entry_t *e; + egb_node_t *el2, *n, *q, *next, *next2; + + if (egb_ctx->elements == NULL) + return 0; /* probably a library file */ + + for(n = egb_ctx->firstel; n != NULL; n = next) { + next = n->next; + if (n->first_child && n->first_child->id == PCB_EGKW_SECT_ELEMENT2) { + el2 = n; + for(q = el2->first_child; q != NULL; q = next2) { + next2 = q->next; + for (e = htss_first(&q->props); e; e = htss_next(&q->props, e)) { + if (strcmp(e->key, "name") == 0) { + if (e->value != NULL && e->value[0] == '-' && e->value[1] == '\0') { + egb_node_prop_set(n, "name", "HYPHEN"); + rnd_message(RND_MSG_WARNING, "Substituted invalid name %s in PCB_EKGW_SECT_ELEMENT with 'HYPHEN'\n", e->value); + } else { + egb_node_prop_set(n, "name", e->value); + } + } + else if (strcmp(e->key, "value") == 0) { + egb_node_prop_set(n, "value", e->value); + } + } + } + } + /* we now add element x,y fields to refdes/value element2 node */ +TODO("What this code is supposed to do? element2 doesn't have x;y, when this is enabled it overwrites perfectly good subc x;y with 0"); +#if 0 + for (e = htss_first(&n->props); e; e = htss_next(&n->props, e)) { + if (strcmp(e->key, "x") == 0) { + egb_node_prop_set(el2, "x", e->value); + } + else if (strcmp(e->key, "y") == 0) { + egb_node_prop_set(el2, "y", e->value); + } + } +#endif + /* could potentially add default size, rot to text somewhere around here + or look harder for other optional nodes defining these parameters here */ + } + return 0; +} + +TODO("TODO netlist - this code flattens the signals so the XML parser finds everything, but connectivity info for nested nets is not preserved in the process #") +TODO("TODO netlist labels - eagle bin often has invalid net labels, i.e.'-', '+' so may need to filter#") +/* take any sub level signal /signals/signal1/signal2 and move it up a level to /signals/signal2 */ +static int postproc_signal(void *ctx, egb_ctx_t *egb_ctx) +{ + egb_node_t *n, *p, *prev2, *next, *next2; + + egb_node_t *signal; + + if (egb_ctx->signals == NULL) + return 0; /* probably a library */ + + signal = egb_ctx->signals->first_child; + + for(n = signal; n != NULL; n = next) { + next = n->next; + if (n->id == PCB_EGKW_SECT_SIGNAL) { + for(p = n->first_child, prev2 = NULL; p != NULL; p = next2) { + next2 = p->next; + if (p->id == PCB_EGKW_SECT_SIGNAL) { + egb_node_unlink(n, prev2, p); + egb_node_append(egb_ctx->signals, p); + } + else + prev2 = p; + } + } + } + return 0; +} + +/* populate the newly created drc node in the binary tree before XML parsing, if board present */ +static int postproc_drc(void *ctx, egb_ctx_t *egb_ctx) +{ + char tmp[32]; + egb_node_t *current; + + if (egb_ctx->drc == NULL) + return 0; /* probably a library with no board node */ + + current = egb_node_append(egb_ctx->drc, egb_node_alloc(PCB_EGKW_SECT_DRC, "param")); + sprintf(tmp, "%ldmil", egb_ctx->mdWireWire); + egb_node_prop_set(current, "name", "mdWireWire"); + egb_node_prop_set(current, "value", tmp); + + current = egb_node_append(egb_ctx->drc, egb_node_alloc(PCB_EGKW_SECT_DRC, "param")); + sprintf(tmp, "%ldmil", egb_ctx->msWidth); + egb_node_prop_set(current, "name", "msWidth"); + egb_node_prop_set(current, "value", tmp); + + current = egb_node_append(egb_ctx->drc, egb_node_alloc(PCB_EGKW_SECT_DRC, "param")); + sprintf(tmp, "%f", egb_ctx->rvPadTop); + egb_node_prop_set(current, "name", "rvPadTop"); + egb_node_prop_set(current, "value", tmp); + + current = egb_node_append(egb_ctx->drc, egb_node_alloc(PCB_EGKW_SECT_DRC, "param")); + sprintf(tmp, "%f", egb_ctx->rvPadInner); + egb_node_prop_set(current, "name", "rvPadInner"); + egb_node_prop_set(current, "value", tmp); + + current = egb_node_append(egb_ctx->drc, egb_node_alloc(PCB_EGKW_SECT_DRC, "param")); + sprintf(tmp, "%f", egb_ctx->rvPadBottom); + egb_node_prop_set(current, "name", "rvPadBottom"); + egb_node_prop_set(current, "value", tmp); + + return 0; +} + +/* take each /drawing/layer and move them into a newly created /drawing/layers/ */ +static int postproc_layers(void *ctx, egb_ctx_t *egb_ctx) +{ + egb_node_t *n, *prev, *next; + + for(n = egb_ctx->drawing->first_child, prev = NULL; n != NULL; n = next) { + next = n->next; /* need to save this because unlink() will ruin it */ + if (n->id == PCB_EGKW_SECT_LAYER) { + egb_node_unlink(egb_ctx->drawing, prev, n); + egb_node_append(egb_ctx->layers, n); + } + else + prev = n; + } + + return 0; +} + +/* insert a library node above each packages node to match the xml */ +static int postproc_libs(void *ctx, egb_ctx_t *egb_ctx) +{ + egb_node_t *n, *lib; + + if (egb_ctx->libraries == NULL) /* a library .lbr has a sole library in it, unlike a board */ + return 0; + + for(n = egb_ctx->libraries->first_child; n != NULL; n = egb_ctx->libraries->first_child) { + if (n->id == PCB_EGKW_SECT_LIBRARY) + break; + + if (n->id != PCB_EGKW_SECT_PACKAGES) { + rnd_message(RND_MSG_ERROR, "postproc_libs(): unexpected node under libraries (must be packages)\n"); + return -1; + } + + egb_node_unlink(egb_ctx->libraries, NULL, n); + lib = egb_node_append(egb_ctx->libraries, egb_node_alloc(PCB_EGKW_SECT_LIBRARY, "library")); + egb_node_append(lib, n); + } + + return 0; +} + +static int postproc(void *ctx, egb_node_t *root, egb_ctx_t *drc_ctx) +{ + + egb_node_t *n, *signal; + egb_ctx_t eagle_bin_ctx; + egb_ctx_t *egb_ctx_p; + egb_ctx_p = &eagle_bin_ctx; + + /* this preliminary code does not assume a board node is present, i.e. could be library .lbr */ + eagle_bin_ctx.root = root; + eagle_bin_ctx.drawing = root->first_child; + eagle_bin_ctx.layers = egb_node_append(root, egb_node_alloc(PCB_EGKW_SECT_LAYERS, "layers")); + eagle_bin_ctx.drc = NULL; /* this will be looked for if board node present */ + eagle_bin_ctx.signals = NULL; /* this will be looked for if board node present */ + eagle_bin_ctx.elements = NULL; /* this will be looked for if board node present */ + eagle_bin_ctx.libraries = NULL;/* this will be looked for if board node present */ + + /* populate context with default DRC settings, since DRC is not present in binary v3 */ + eagle_bin_ctx.mdWireWire = drc_ctx->mdWireWire; + eagle_bin_ctx.msWidth = drc_ctx->msWidth; + eagle_bin_ctx.rvPadTop = drc_ctx->rvPadTop; + eagle_bin_ctx.rvPadInner = drc_ctx->rvPadInner; + eagle_bin_ctx.rvPadBottom = drc_ctx->rvPadBottom; + + eagle_bin_ctx.board = find_node(eagle_bin_ctx.drawing->first_child, PCB_EGKW_SECT_BOARD); + if (eagle_bin_ctx.board == NULL) { +TODO(": convert this to proper error reporting") + rnd_trace("No board node found, this may be a library file.\n"); + } else { + /* the following code relies on the board node being present, i.e. a layout */ + /* create a drc node, since DRC block if present in binary file comes after the tree */ + eagle_bin_ctx.drc = egb_node_append(eagle_bin_ctx.board, egb_node_alloc(PCB_EGKW_SECT_DRC, "designrules")); + eagle_bin_ctx.libraries = find_node_name(eagle_bin_ctx.board->first_child, "libraries"); + if (eagle_bin_ctx.libraries == NULL) { /* layouts have a libraries node it seems */ +TODO(": convert this to proper error reporting") + rnd_trace("Eagle binary layout is missing a board/libraries node.\n"); + return -1; + } + + for(n = eagle_bin_ctx.board->first_child, signal = NULL; signal == NULL && n != NULL; n = n->next) { + if (n->first_child && n->first_child->id == PCB_EGKW_SECT_SIGNAL) { + signal = n->first_child; + eagle_bin_ctx.signals = signal->parent; + } + } + + for(n = eagle_bin_ctx.board->first_child, eagle_bin_ctx.firstel = NULL; + eagle_bin_ctx.firstel == NULL && n != NULL; n = n->next) { + if (n->first_child && n->first_child->id == PCB_EGKW_SECT_ELEMENT) { + eagle_bin_ctx.firstel = n->first_child; + eagle_bin_ctx.elements = eagle_bin_ctx.firstel->parent; + } + } + } + + /* after post processing layers, we populate the DRC node first, if present... */ + + return postproc_layers(ctx, egb_ctx_p) || postproc_drc(ctx, egb_ctx_p) + || postproc_libs(ctx, egb_ctx_p) || postproc_elements(ctx, egb_ctx_p) + || postproc_signal(ctx, egb_ctx_p) || postproc_contactrefs(ctx, egb_ctx_p) + || postprocess_wires(ctx, root) || postprocess_arcs(ctx, root) + || postprocess_circles(ctx, root) || postprocess_smd(ctx, root) + || postprocess_dimensions(ctx, root) + || postprocess_free_text(drc_ctx, root) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_SMD) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_PIN) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_RECTANGLE) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_PAD) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_TEXT) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_SMASHEDVALUE) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_SMASHEDNAME) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_NETBUSLABEL) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_SMASHEDXREF) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_ATTRIBUTE) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_SMASHEDGATE) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_SMASHEDPART) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_INSTANCE) + || postprocess_rotation(ctx, root, PCB_EGKW_SECT_ELEMENT); +} + +static void egb_free_ctx(egb_ctx_t *egb_ctx) +{ + free(egb_ctx->free_text); + egb_ctx->free_text = egb_ctx->free_text_cursor = NULL; +} + +int pcb_egle_bin_load(void *ctx, FILE *f, const char *fn, egb_node_t **root) +{ + long test = -1; + long *numblocks = &test; + int res = 0; + + egb_ctx_t eagle_bin_ctx; + +/* rnd_trace("blocks remaining prior to function call = %ld\n", *numblocks);*/ + + *root = egb_node_alloc(0, "eagle"); + + res = read_block(numblocks, 1, ctx, f, fn, *root); + if (res < 0) { +TODO(": convert this to proper error reporting") + rnd_trace("Problem with remaining blocks... is this a library file?\n"); + return res; + } +/* rnd_trace("blocks remaining after outer function call = %ld (after reading %d blocks)\n\n", *numblocks, res);*/ + + /* could test if < v4 as v3.xx seems to have no DRC or Netclass or Free Text end blocks */ + read_notes(ctx, f, fn, &eagle_bin_ctx); + /* read_drc will determine sane defaults if no DRC block found */ + if (read_drc(ctx, f, fn, &eagle_bin_ctx) != 0) { +TODO(": convert this to proper error reporting") + rnd_trace("No DRC section found, either a v3 binary file or a binary library file.\n"); + } /* we now use the eagle_bin_ctx results for post_proc */ + + res = postproc(ctx, *root, &eagle_bin_ctx); + egb_free_ctx(&eagle_bin_ctx); + return res; +} + Index: tags/2.3.0/src_plugins/io_eagle/eagle_bin.h =================================================================== --- tags/2.3.0/src_plugins/io_eagle/eagle_bin.h (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/eagle_bin.h (revision 33253) @@ -0,0 +1,91 @@ +/* COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017 Tibor 'Igor2' Palinkas + * Copyright (C) 2017 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Eagle binary tree parser */ + +#include +#include "egb_tree.h" + +typedef enum pcb_eagle_binkw_s { + PCB_EGKW_SECT_START = 0x1000, /*0x1080*/ + PCB_EGKW_SECT_UNKNOWN11 = 0x1100, + PCB_EGKW_SECT_GRID = 0x1200, + PCB_EGKW_SECT_LAYER = 0x1300, /*0x1380 */ + PCB_EGKW_SECT_SCHEMA = 0x1400, + PCB_EGKW_SECT_LIBRARY = 0x1500, /*0x1580 */ + PCB_EGKW_SECT_DEVICES = 0x1700, /*0x1780 */ + PCB_EGKW_SECT_SYMBOLS = 0x1800, /*0x1880 */ + PCB_EGKW_SECT_PACKAGES = 0x1900, /*0x1980, 0x19a0 */ + PCB_EGKW_SECT_SCHEMASHEET = 0x1a00, + PCB_EGKW_SECT_BOARD = 0x1b00, /*0x1b40, 0x1b80, 0x1b08 */ + PCB_EGKW_SECT_SIGNAL = 0x1c00, /*0x1c04, 0x1c40,0x1c48,0x1c08 */ + PCB_EGKW_SECT_SYMBOL = 0x1d00, + PCB_EGKW_SECT_PACKAGE = 0x1e00, /*0x1e20*/ + PCB_EGKW_SECT_SCHEMANET = 0x1f00, + PCB_EGKW_SECT_PATH = 0x2000, + PCB_EGKW_SECT_POLYGON = 0x2100, /*0x2108 */ + PCB_EGKW_SECT_LINE = 0x2200, /*0x2280,0x228c,0x2288,0x2290,0x229c,0x22a0,0x22a8 */ + PCB_EGKW_SECT_ARC = 0x2400, + PCB_EGKW_SECT_CIRCLE = 0x2500, /*0x2580, 0x25a0, 0x258c */ + PCB_EGKW_SECT_RECTANGLE = 0x2600,/*0x2680,0x26a0 */ + PCB_EGKW_SECT_JUNCTION = 0x2700, + PCB_EGKW_SECT_HOLE = 0x2800, /*0x2880,0x28a0,0x288c */ + PCB_EGKW_SECT_VIA = 0x2900, /*0x2980 */ + PCB_EGKW_SECT_PAD = 0x2a00, /*0x2a80,0x2aa0 */ + PCB_EGKW_SECT_SMD = 0x2b00, /*0x2b80 */ + PCB_EGKW_SECT_PIN = 0x2c00, /*0x2c80 */ + PCB_EGKW_SECT_GATE = 0x2d00, /*0x2d80 */ + PCB_EGKW_SECT_ELEMENT = 0x2e00,/*0x2e20,0x2e80,0x2e0c,0x2e28 */ + PCB_EGKW_SECT_ELEMENT2 = 0x2f00,/*0x2f80,0x2fa0 */ + PCB_EGKW_SECT_INSTANCE = 0x3000, + PCB_EGKW_SECT_TEXT = 0x3100,/*0x3180,0x31a0,0x318c */ + PCB_EGKW_SECT_NETBUSLABEL = 0x3300, + PCB_EGKW_SECT_SMASHEDNAME = 0x3400, /*0x3480,0x348c,0x3488 */ + PCB_EGKW_SECT_SMASHEDVALUE = 0x3500,/*0x3580,0x3588,0x358c */ + PCB_EGKW_SECT_PACKAGEVARIANT = 0x3600, /*0x3680 */ + PCB_EGKW_SECT_DEVICE = 0x3700, /*0x3780 */ + PCB_EGKW_SECT_PART = 0x3800, + PCB_EGKW_SECT_SCHEMABUS = 0x3a00, + PCB_EGKW_SECT_VARIANTCONNECTIONS = 0x3c00, /*0x3c80 */ + PCB_EGKW_SECT_SCHEMACONNECTION = 0x3d00, + PCB_EGKW_SECT_CONTACTREF = 0x3e00, /*0x3e80,0x3ea8,0x3ea0,0x3e20 */ + PCB_EGKW_SECT_SMASHEDPART = 0x3f00, + PCB_EGKW_SECT_SMASHEDGATE = 0x4000, + PCB_EGKW_SECT_ATTRIBUTE = 0x4100, /*0x4180 */ + PCB_EGKW_SECT_ATTRIBUTEVALUE = 0x4200, + PCB_EGKW_SECT_FRAME = 0x4300, + PCB_EGKW_SECT_SMASHEDXREF = 0x4400, + PCB_EGKW_SECT_FREETEXT = 0x1312, + + /* virtual nodes added in postprocessing */ + PCB_EGKW_SECT_LAYERS = 0x11300, + PCB_EGKW_SECT_DRC = 0x11100 +} pcb_eagle_binkw_t; + +int pcb_egle_bin_load(void *ctx, FILE *f, const char *fn, egb_node_t **root); + + Index: tags/2.3.0/src_plugins/io_eagle/egb_tree.c =================================================================== --- tags/2.3.0/src_plugins/io_eagle/egb_tree.c (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/egb_tree.c (revision 33253) @@ -0,0 +1,151 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Eagle binary tree store */ + +#include "config.h" +#include +#include +#include +#include "egb_tree.h" +#include + +egb_node_t *egb_node_alloc(int id, const char *id_name) +{ + egb_node_t *nd = calloc(sizeof(egb_node_t), 1); + nd->id = id; + nd->id_name = id_name; + return nd; +} + +egb_node_t *egb_node_append(egb_node_t *parent, egb_node_t *node) +{ + node->parent = parent; + node->next = NULL; + + if (parent->last_child == NULL) { + parent->last_child = node; + parent->first_child = node; + } + else { + parent->last_child->next = node; + parent->last_child = node; + } + return node; +} + + +void egb_node_prop_set(egb_node_t *node, const char *key, const char *val) +{ + htss_entry_t *e; + if (node->props.table == NULL) + htss_init(&node->props, strhash, strkeyeq); + e = htss_getentry(&node->props, key); + if (e != NULL) { + free(e->value); + e->value = rnd_strdup(val); + } + else + htss_set(&node->props, rnd_strdup(key), rnd_strdup(val)); +} + +char *egb_node_prop_get(egb_node_t *node, const char *key) +{ + if (node->props.table == NULL) + return NULL; + return htss_get(&node->props, key); +} + +void egb_node_free(egb_node_t *node) +{ + egb_node_t *n, *next; + + for(n = node->first_child; n != NULL; n = next) { + next = n->next; + egb_node_free(n); + } + + if (node->props.table != NULL) { + htss_entry_t *e; + for (e = htss_first(&node->props); e; e = htss_next(&node->props, e)) { + free(e->key); + free(e->value); + } + htss_uninit(&node->props); + } + free(node); +} + +egb_node_t *egb_node_unlink(egb_node_t *parent, egb_node_t *prev, egb_node_t *node) +{ + if (parent->first_child == node) { + assert(prev == NULL); + parent->first_child = node->next; + } + else { + assert(prev != NULL); + assert(prev->next == node); + } + + if (parent->last_child == node) + parent->last_child = prev; + + if (prev != NULL) + prev->next = node->next; + + node->parent = NULL; + node->next = NULL; + return node; +} + + +static char inds[] = " "; +static void egb_dump_(FILE *f, int ind, egb_node_t *node) +{ + htss_entry_t *e; + int i; + egb_node_t *n; + + if (ind >= sizeof(inds)-1) + ind = sizeof(inds)-1; + inds[ind] = '\0'; + fprintf(f, "%s%s/%04x [", inds, node->id_name, node->id); + inds[ind] = ' '; + + for (e = htss_first(&node->props), i = 0; e; e = htss_next(&node->props, e), i++) + fprintf(f, "%s%s=\"%s\"", (i > 0 ? " " : ""), e->key, e->value); + fprintf(f, "]\n"); + + for(n = node->first_child; n != NULL; n = n->next) + egb_dump_(f, ind+1, n); +} + +void egb_dump(FILE *f, egb_node_t *node) +{ + egb_dump_(f, 0, node); +} + Index: tags/2.3.0/src_plugins/io_eagle/egb_tree.h =================================================================== --- tags/2.3.0/src_plugins/io_eagle/egb_tree.h (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/egb_tree.h (revision 33253) @@ -0,0 +1,71 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Eagle binary tree store */ + +#ifndef PCB_EGB_TREE_H +#define PCB_EGB_TREE_H +#include +#include + +typedef struct egb_node_s egb_node_t; + +struct egb_node_s { + int id; + const char *id_name; + htss_t props; + egb_node_t *parent; + egb_node_t *next; + egb_node_t *first_child, *last_child; + void *user_data; +}; + + +/* Allocate a new floating node */ +egb_node_t *egb_node_alloc(int id, const char *id_name); + +/* Link a floating node into the tree, appending it as the last + child of parent. Returns the node. */ +egb_node_t *egb_node_append(egb_node_t *parent, egb_node_t *node); + +/* Unlink a node from its parent, making the node a floating node. + Returns the node */ +egb_node_t *egb_node_unlink(egb_node_t *parent, egb_node_t *prev, egb_node_t *node); + +/* Free a subtree (without unlinking) */ +void egb_node_free(egb_node_t *node); + +/* Set a named property of a node to val */ +void egb_node_prop_set(egb_node_t *node, const char *key, const char *val); + +/* Return the value of a named property of a node */ +char *egb_node_prop_get(egb_node_t *node, const char *key); + +/* Print the indented tree in text to f */ +void egb_dump(FILE *f, egb_node_t *node); + +#endif Index: tags/2.3.0/src_plugins/io_eagle/format_tree.txt =================================================================== --- tags/2.3.0/src_plugins/io_eagle/format_tree.txt (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/format_tree.txt (revision 33253) @@ -0,0 +1,77 @@ +XML: + +eagle + drawing + settings + grid + layers + layer [name, color, fill, visible, active, number] + board + plain + libraries + library + description + packages + package [name] + description + wire [x1, y1, x2, y2, width, layer] + hole [name, x, y, drill, diameter, shape] + pad [name, x, y, drill, diameter, shape]x + circle [x, y, radius, width, layer] + smd [x, y, dx, dy, rot, layer] (smd pad) + text [x, y, size, rot, layer] + rectangle [x1, y1, x2, y2, layer] + attributes + variantdefs + classes + description + designrules + autorouter + elements + element [name, library, package, value, x, y, rot] + signals + signal [name] + contactref [element, pad] + wire [x1, y1, x2, y2, width, layer] + polygon [layer] + vertex [x, y] + via [name, x, y, drill, diameter, shape] + compatibility + @text + + +bin: + +0x1000/start (->drawing?) + 0x1100/settings? + 0x1200/grid + 0x1300/layer !!! + 0x1b00/board + + 0x2200/line + 0x2600/rectangle + + 0x1900/packages (->library?) + 0x1e00/package + 0x2100/polygon + 0x2200/line (->vertex?) + 0x2600/rectangle + 0x2200/line (->wire?) + 0x2d00/smd + 0x2a00/pad + 0x2500/circle + 0x3100/text? + 0x2800/hole + + 0x2e00/boardpackage? + 0x2f00/boarkpackage2??? + 0x3400/smashedname?? -> description? + 0x3500/smashedvalue?? -> description? + + 0x1c00/boardnet -> signal + 0x3e00/boardconnection -> contactref + 0x2100/polygon + 0x2200/line (->vertex?) + 0x2200/line + 0x2900/via + Index: tags/2.3.0/src_plugins/io_eagle/io_eagle.c =================================================================== --- tags/2.3.0/src_plugins/io_eagle/io_eagle.c (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/io_eagle.c (revision 33253) @@ -0,0 +1,130 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This module, io_eagle, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include "plug_io.h" +#include "read.h" +#include "read_dru.h" +#include + +static pcb_plug_io_t io_eagle_xml, io_eagle_bin, io_eagle_dru; +static const char *eagle_cookie = "eagle plugin"; + +int io_eagle_fmt(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, int wr, const char *fmt) +{ + if (wr && (typ & PCB_IOT_FOOTPRINT)) /* no footprint write */ + return 0; + + if (strcmp(ctx->description, fmt) == 0) + return 200; + + if ((strcmp(fmt, "eagle") != 0) || + ((typ & (~(PCB_IOT_FOOTPRINT | PCB_IOT_BUFFER | PCB_IOT_PCB))) != 0)) + return 0; + + return 100; +} + +int pplg_check_ver_io_eagle(int ver_needed) { return 0; } + +void pplg_uninit_io_eagle(void) +{ + /* Runs once when the plugin is unloaded. TODO: free plugin-globals here. */ + rnd_remove_actions_by_cookie(eagle_cookie); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_eagle_xml); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_eagle_bin); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_eagle_dru); +} + +int pplg_init_io_eagle(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + io_eagle_xml.plugin_data = NULL; + io_eagle_xml.fmt_support_prio = io_eagle_fmt; + io_eagle_xml.test_parse = io_eagle_test_parse_xml; + io_eagle_xml.parse_pcb = io_eagle_read_pcb_xml; +/* io_eagle_xml.parse_footprint = NULL; + io_eagle_xml.map_footprint = NULL; + io_eagle_xml.parse_font = NULL; + io_eagle_xml.write_buffer = io_eagle_write_buffer; + io_eagle_xml.write_pcb = io_eagle_write_pcb;*/ + io_eagle_xml.default_fmt = "eagle"; + io_eagle_xml.description = "eagle xml"; + io_eagle_xml.save_preference_prio = 40; + io_eagle_xml.default_extension = ".eagle_pcb"; + io_eagle_xml.fp_extension = ".eagle_mod"; + io_eagle_xml.mime_type = "application/x-eagle-pcb"; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_eagle_xml); + + /* register the IO hook */ + io_eagle_bin.plugin_data = NULL; + io_eagle_bin.fmt_support_prio = io_eagle_fmt; + io_eagle_bin.test_parse = io_eagle_test_parse_bin; + io_eagle_bin.parse_pcb = io_eagle_read_pcb_bin; +/* io_eagle_bin.parse_footprint = NULL; + io_eagle_bin.map_footprint = NULL; + io_eagle_bin.parse_font = NULL; + io_eagle_bin.write_buffer = io_eagle_write_buffer; + io_eagle_bin.write_pcb = io_eagle_write_pcb;*/ + io_eagle_bin.default_fmt = "eagle"; + io_eagle_bin.description = "eagle bin"; + io_eagle_bin.save_preference_prio = 30; + io_eagle_bin.default_extension = ".brd"; + io_eagle_bin.fp_extension = ".???"; + io_eagle_bin.mime_type = "application/x-eagle-pcb"; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_eagle_bin); + + /* register the IO hook */ + io_eagle_dru.plugin_data = NULL; + io_eagle_dru.fmt_support_prio = io_eagle_fmt; + io_eagle_dru.test_parse = io_eagle_test_parse_dru; + io_eagle_dru.parse_pcb = io_eagle_read_pcb_dru; + io_eagle_dru.parse_footprint = NULL; + io_eagle_dru.map_footprint = NULL; + io_eagle_dru.parse_font = NULL; + io_eagle_dru.write_buffer = NULL; + io_eagle_dru.write_pcb = /*io_eagle_write_pcb_dru*/ NULL; + io_eagle_dru.default_fmt = "eagle"; + io_eagle_dru.description = "eagle dru"; + io_eagle_dru.save_preference_prio = 0; + io_eagle_dru.default_extension = ".dru"; + io_eagle_dru.fp_extension = ".dru"; + io_eagle_dru.mime_type = "application/x-eagle-dru"; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_eagle_dru); + + return 0; +} + Index: tags/2.3.0/src_plugins/io_eagle/io_eagle.pup =================================================================== --- tags/2.3.0/src_plugins/io_eagle/io_eagle.pup (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/io_eagle.pup (revision 33253) @@ -0,0 +1,15 @@ +$class io +$short Eagle's xml and binary formats +$long Load the design from eagle's xml and binary formats. +$state works +$fmt-native no +$fmt-feature-r eagle xml board version 6, 7, 8 +$fmt-feature-r eagle xml footprint lib +$fmt-feature-r eagle binary board version 3, 4, 5 +$fmt-feature-r eagle binary footprint lib +$fmt-feature-r eagle DRU (design rules) +$package io-alien +dep shape +dep lib_compat_help +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/io_eagle/read.c =================================================================== --- tags/2.3.0/src_plugins/io_eagle/read.c (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/read.c (revision 33253) @@ -0,0 +1,1899 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,2019,2020 Tibor 'Igor2' Palinkas + * Copyright (C) 2017 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "read.h" +#include +#include "conf_core.h" +#include +#include "polygon.h" +#include +#include +#include "undo.h" +#include +#include "trparse.h" +#include "trparse_xml.h" +#include "trparse_bin.h" +#include "obj_subc.h" +#include "obj_poly_op.h" + +#include "../src_plugins/lib_compat_help/pstk_compat.h" +#include "../src_plugins/lib_compat_help/subc_help.h" +#include "../src_plugins/lib_compat_help/pstk_help.h" +#include "../src_plugins/shape/shape.h" + +/* coordinates that corresponds to pcb-rnd 100% text size in height */ +#define EAGLE_TEXT_SIZE_100 RND_MIL_TO_COORD(50) + +#define PARENT(node) st->parser.calls->parent(&st->parser, node) +#define CHILDREN(node) st->parser.calls->children(&st->parser, node) +#define NEXT(node) st->parser.calls->next(&st->parser, node) +#define NODENAME(node) st->parser.calls->nodename(node) + +#define GET_PROP(node, key) st->parser.calls->prop(&st->parser, node, key) +#define GET_PROP_(st, node, key) (st)->parser.calls->prop(&((st)->parser), node, key) +#define GET_TEXT(node) st->parser.calls->text(&st->parser, node) + +#define STRCMP(s1, s2) st->parser.calls->str_cmp(s1,s2) +#define IS_TEXT(node) st->parser.calls->is_text(&st->parser, node) + +typedef struct eagle_layer_s { + const char *name; + int color; + int fill; + int visible; + int active; + + rnd_layer_id_t lid; +} eagle_layer_t; + +typedef struct eagle_library_s { + const char *desc; + htsp_t elems; /* -> pcb_elemement_t */ +} eagle_library_t; + + +typedef struct read_state_s { + trparse_t parser; + pcb_board_t *pcb; + + htip_t layers; + htsp_t libs; + + /* design rules */ + rnd_coord_t md_wire_wire; /* minimal distance between wire and wire (clearance) */ + rnd_coord_t ms_width; /* minimal trace width */ + double rv_pad_top, rv_pad_inner, rv_pad_bottom; /* pad size-to-drill ration on different layers */ + + const char *default_unit; /* assumed unit for unitless coord values */ + unsigned elem_by_name:1; /* whether elements are addressed by name (or by index in the lib) */ +} read_state_t; + +typedef struct { + const char *node_name; + int (*parser)(read_state_t *st, trnode_t *subtree, void *obj, int type); +} dispatch_t; + +typedef enum { + IN_SUBC = 1, + ON_BOARD +} eagle_loc_t; + +typedef int eagle_layerid_t; + +/* Xml path walk that's much simpler than xpath; the ... is a NULL + terminated list of node names */ +static trnode_t *eagle_trpath(read_state_t *st, trnode_t *subtree, ...) +{ + trnode_t *nd = subtree; + const char *target; + va_list ap; + + va_start(ap, subtree); + + /* get next path element */ + while((target = va_arg(ap, const char *)) != NULL) { + /* look for target on this level */ + for(nd = CHILDREN(nd);;nd = NEXT(nd)) { + if (nd == NULL) {/* target not found on this level */ + va_end(ap); + return NULL; + } + if (STRCMP(NODENAME(nd), target) == 0) /* found, skip to next level */ + break; + } + } + + va_end(ap); + return nd; +} + +/* Search the dispatcher table for subtree->str, execute the parser on match + with the children ("parameters") of the subtree */ +static int eagle_dispatch(read_state_t *st, trnode_t *subtree, const dispatch_t *disp_table, void *obj, int type) +{ + const dispatch_t *d; + const char *name; + + /* do not tolerate empty/NIL node */ + if (NODENAME(subtree) == NULL) + return -1; + + if (IS_TEXT(subtree)) + name = "@text"; + else + name = NODENAME(subtree); + + for(d = disp_table; d->node_name != NULL; d++) + if (STRCMP(d->node_name, name) == 0) + return d->parser(st, subtree, obj, type); + + rnd_message(RND_MSG_ERROR, "eagle: unknown node: '%s'\n", name); + /* node name not found in the dispatcher table */ + return -1; +} + +/* Take each children of tree and execute them using eagle_dispatch + Useful for procssing nodes that may host various subtrees of different + nodes ina flexible way. Return non-zero if any subtree processor failed. */ +static int eagle_foreach_dispatch(read_state_t *st, trnode_t *tree, const dispatch_t *disp_table, void *obj, int type) +{ + trnode_t *n; + + for(n = tree; n != NULL; n = NEXT(n)) + if (eagle_dispatch(st, n, disp_table, obj, type) != 0) + return -1; + + return 0; /* success */ +} + +/* No-op: ignore the subtree */ +static int eagle_read_nop(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + return 0; +} + + + +int io_eagle_test_parse_xml(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f) +{ + char line[1024]; + int found = 0, lineno = 0; + + /* look for 32) + break; + } + return 0; +} + +int io_eagle_test_parse_bin(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f) +{ + unsigned char buff[2]; + int read_length = fread(buff, 1, 2, f); + if ((read_length == 2) && (buff[0] == 0x10) && (buff[1] == 0x00)) { + return 1; /* Eagle v4, v5 */ + } else if ((read_length == 2) && (buff[0] == 0x10) && (buff[1] == 0x80)) { + return 1; /* Eagle v3 */ + } + return 0; +} + +/* Return a node attribute value converted to long, or return invalid_val + for synatx error or if the attribute doesn't exist */ +static long eagle_get_attrl(read_state_t *st, trnode_t *nd, const char *name, long invalid_val) +{ + const char *p = GET_PROP(nd, name); + char *end; + long res; + + if (p == NULL) + return invalid_val; + res = strtol(p, &end, 10); + if (*end != '\0') + return invalid_val; + return res; +} + +/* Return a node attribute value converted to double, or return invalid_val + for synatx error or if the attribute doesn't exist */ +static double eagle_get_attrd(read_state_t *st, trnode_t *nd, const char *name, double invalid_val) +{ + const char *p = GET_PROP(nd, name); + char *end; + double res; + + if (p == NULL) + return invalid_val; + res = strtod(p, &end); + if (*end != '\0') + return invalid_val; + return res; +} + +/* Return a node attribute value converted to char *, or return invalid_val + if the attribute doesn't exist */ +static const char *eagle_get_attrs(read_state_t *st, trnode_t *nd, const char *name, const char *invalid_val) +{ + const char *p = GET_PROP(nd, name); + if (p == NULL) + return invalid_val; + return p; +} + +/* Return a node attribute value converted to coord, or return invalid_val + if the attribute doesn't exist */ +static rnd_coord_t eagle_get_attrc(read_state_t *st, trnode_t *nd, const char *name, rnd_coord_t invalid_val) +{ + const char *p = GET_PROP(nd, name); + rnd_coord_t c; + rnd_bool succ; + + if (p == NULL) + return invalid_val; + + c = rnd_get_value(p, st->default_unit, NULL, &succ); + if (!succ) + return invalid_val; + return c; +} + +/* same as eagle_get_attrc() but assume the input has units */ +static rnd_coord_t eagle_get_attrcu(read_state_t *st, trnode_t *nd, const char *name, rnd_coord_t invalid_val) +{ + const char *p = GET_PROP(nd, name); + rnd_coord_t c; + rnd_bool succ; + + if (p == NULL) + return invalid_val; + + c = rnd_get_value(p, NULL, NULL, &succ); + if (!succ) + return invalid_val; + return c; +} + +static int eagle_read_layers(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + trnode_t *n; + + pcb_layergrp_inhibit_inc(); + + for(n = CHILDREN(subtree); n != NULL; n = NEXT(n)) { + if (STRCMP(NODENAME(n), "layer") == 0) { + eagle_layer_t *ly = calloc(sizeof(eagle_layer_t), 1); + int reuse = 0; + long tmp_id; + eagle_layerid_t id; + unsigned long typ; + rnd_layergrp_id_t gid; + pcb_layergrp_t *grp; + + ly->name = eagle_get_attrs(st, n, "name", NULL); + ly->color = eagle_get_attrl(st, n, "color", -1); + ly->fill = eagle_get_attrl(st, n, "fill", -1); + ly->visible = eagle_get_attrl(st, n, "visible", -1); + ly->active = eagle_get_attrl(st, n, "active", -1); + ly->lid = -1; + tmp_id = eagle_get_attrl(st, n, "number", -1); + if (tmp_id < 1 || tmp_id > 254) { + rnd_message(RND_MSG_ERROR, "invalid layer definition layer number found: '%d', skipping\n", tmp_id); + return -1; + } + id = tmp_id; + htip_set(&st->layers, id, ly); /* all valid layers get a hash */ + typ = 0; + switch(id) { + case 1: typ = PCB_LYT_COPPER | PCB_LYT_TOP; break; + case 16: typ = PCB_LYT_COPPER | PCB_LYT_BOTTOM; break; + case 121: + case 21: /* tplace element silk */ + /*case 51: tDocu, second layer in top silk group */ + case 25: /* names */ + case 27: /* values */ + case 39: /* keepout */ + reuse = 1; + typ = PCB_LYT_SILK | PCB_LYT_TOP; + break; + case 122: + case 22: /* bplace element silk */ + /* case 52: bDocu, second layer in bottom silk group */ + case 26: /* names */ + case 28: /* values */ + case 40: /* keepout */ + reuse = 1; + typ = PCB_LYT_SILK | PCB_LYT_BOTTOM; + break; + case 20: /*199: 20 is dimension, 199 is contour */ + grp = pcb_get_grp_new_intern(st->pcb, -1); + ly->lid = pcb_layer_create(st->pcb, grp - st->pcb->LayerGroups.grp, ly->name, 0); + pcb_layergrp_fix_turn_to_outline(grp); + break; + + default: + if ((id > 1) && (id < 16)) { + /* new internal layer */ + grp = pcb_get_grp_new_intern(st->pcb, -1); + ly->lid = pcb_layer_create(st->pcb, grp - st->pcb->LayerGroups.grp, ly->name, 0); + } + } + if (typ != 0) { + if (reuse) + pcb_layer_list(st->pcb, typ, &ly->lid, 1); + if ((ly->lid < 0) && (pcb_layergrp_list(st->pcb, typ, &gid, 1) > 0)) + ly->lid = pcb_layer_create(st->pcb, gid, ly->name, 0); + } + } + } + pcb_layer_group_setup_silks(st->pcb); + pcb_layer_auto_fixup(st->pcb); + pcb_layergrp_inhibit_dec(); + return 0; +} + +static pcb_layer_t *eagle_layer_get(read_state_t *st, eagle_layerid_t id, eagle_loc_t loc, void *obj) +{ + /* tDocu & bDocu are used for info used when designing, but not necessarily for + exporting to Gerber i.e. package outlines that cross pads, or instructions. + These layers within the silk groups will be needed when subc replaces elements + since most Eagle packages use tDocu, bDocu for some of their artwork */ + + eagle_layer_t *ly = htip_get(&st->layers, id); + rnd_layer_id_t lid; + pcb_subc_t *subc = obj; + pcb_layer_type_t lyt; + pcb_layer_combining_t comb; + + /* if more than 51 or 52 are considered useful, we could relax the test here: */ + if ((ly == NULL) || (ly->lid < 0)) { + TODO("move this out to a separate function") + if (id == 51 || id == 52) { + /* create docu on the first reference */ + pcb_layer_type_t typ; + rnd_layergrp_id_t gid; + switch (id) { + case 51: /* = tDocu */ + typ = PCB_LYT_SILK | PCB_LYT_TOP; + ly->name = "tDocu"; + ly->color = 14; + break; + default: /* i.e. 52 = bDocu: */ + typ = PCB_LYT_SILK | PCB_LYT_BOTTOM; + ly->name = "bDocu"; + ly->color = 7; + break; + } + + ly->fill = 1; + ly->visible = 0; + ly->active = 1; + pcb_layergrp_list(st->pcb, typ, &gid, 1); + ly->lid = pcb_layer_create(st->pcb, gid, ly->name, 0); + } + else + return NULL; /* not found and not supported */ + } + + switch(loc) { + case ON_BOARD: + return &st->pcb->Data->Layer[ly->lid]; + case IN_SUBC: + /* check if the layer already exists (by name) */ + lid = pcb_layer_by_name(subc->data, ly->name); + if (lid >= 0) + return &subc->data->Layer[lid]; + + if (ly->lid < 0) { + rnd_message(RND_MSG_ERROR, "\tfp_* layer '%s' not found for module object, using unbound subc layer instead.\n", ly->name); + lyt = PCB_LYT_VIRTUAL; + comb = 0; + return pcb_subc_get_layer(subc, lyt, comb, 1, ly->name, rnd_true); + } + lyt = pcb_layer_flags(st->pcb, ly->lid); + comb = 0; + return pcb_subc_get_layer(subc, lyt, comb, 1, ly->name, rnd_true); + } + return NULL; +} + +static pcb_subc_t *eagle_libelem_by_name(read_state_t *st, const char *lib, const char *elem) +{ + eagle_library_t *l; + l = htsp_get(&st->libs, lib); + if (l == NULL) + return NULL; + return htsp_get(&l->elems, elem); +} + +static pcb_subc_t *eagle_libelem_by_idx(read_state_t *st, trnode_t *libs, long libi, long pkgi) +{ + trnode_t *n; + pcb_subc_t *res; + + /* count children of libs so n ends up at the libith library */ + for(n = CHILDREN(libs); (n != NULL) && (libi > 1); n = NEXT(n), libi--) ; + if (n == NULL) { + rnd_message(RND_MSG_ERROR, "io_eagle bin: eagle_libelem_by_idx() can't find lib by idx:\n"); + return NULL; + } + + if (STRCMP(NODENAME(n), "library") != 0) { + rnd_message(RND_MSG_ERROR, "io_eagle bin: eagle_libelem_by_idx() expected library node:\n"); + return NULL; + } + n = CHILDREN(n); + + if (STRCMP(NODENAME(n), "packages") != 0) { + rnd_message(RND_MSG_ERROR, "io_eagle bin: eagle_libelem_by_idx() expected packages node:\n"); + return NULL; + } + + /* count children of that library so n ends up at the pkgth package */ + for(n = CHILDREN(n); (n != NULL) && (pkgi > 1); n = NEXT(n), pkgi--) ; + if (n == NULL) { + rnd_message(RND_MSG_ERROR, "io_eagle bin: eagle_libelem_by_idx() can't find pkg by idx:\n"); + return NULL; + } + + res = st->parser.calls->get_user_data(n); + if (res == NULL) + rnd_message(RND_MSG_ERROR, "io_eagle bin: eagle_libelem_by_idx() found the element node in the tree but there's no element instance associated with it:\n"); + return res; +} + +static void size_bump(read_state_t *st, rnd_coord_t x, rnd_coord_t y) +{ + if (x > st->pcb->hidlib.size_x) + st->pcb->hidlib.size_x = x; + if (y > st->pcb->hidlib.size_y) + st->pcb->hidlib.size_y = y; +} + +/* Convert eagle Rxxx to degrees. Binary n*1024 string converted to Rxxx in eagle_bin.c */ +static int eagle_rot2degrees(const char *rot) +{ + long deg; + char *end; + + if (rot == NULL) { + return -1; + } else { + deg = strtol(rot+1, &end, 10); + if (*end != '\0') + return -1; + } + while (deg >= 360) { + deg -= 360; + } + return (int) deg; +} + +/* Convert eagle Rxxx string to pcb-rnd 90-deg rotation steps */ +static int eagle_rot2steps(const char *rot) +{ + int deg = eagle_rot2degrees(rot); + + switch(deg) { + case 0: return 0; + case 90: return 3; + case 180: return 2; + case 270: return 1; + } + rnd_message(RND_MSG_WARNING, "Unexpected non n*90 degree rotation value '%s' ignored\n", rot); + return -1; +} + +/****************** drawing primitives ******************/ + +/* Return the length of a string in drawing character units considering + which characters are half-wide in eagle's default font. Returns + size*2. */ +static int eagle_strlen2(const char *str) +{ + static int inited = 0; + static char half[256] = {0}; + const char *s; + int size; + + if (!inited) { /* create the half[] table from a static list */ + static const char *halves = "fijkltI[]||:;'.()`!"; + for(s = halves; *s != '\0'; s++) + half[(int)*s] = 1; + inited = 1; + } + + for(size = 0, s = str; *s != '\0'; s++) { + if (half[(int)*s]) size++; + else size += 2; + } + + return size; +} + +static int eagle_read_text(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + eagle_layerid_t ln = eagle_get_attrl(st, subtree, "layer", -1); + rnd_coord_t X, Y, size, bbw, bbh, anchx, anchy, basel; + const char *rot, *text_val, *align; + unsigned int rotdeg = 0, spin = 0; + enum { ALEFT=-1, ATOP=-1, CENTER=0, ARIGHT=+1, ABOTTOM=+1 } ax = ALEFT, ay = ABOTTOM; /* anchor position (text alignment) */ + pcb_flag_t text_flags = pcb_flag_make(0); + pcb_layer_t *ly; + pcb_text_mirror_t mirror = 0; + + + ly = eagle_layer_get(st, ln, type, obj); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to allocate text layer 'ly' to 'ln:%d' in eagle_read_text()\n", ln); + return 0; + } + if (!(text_val = eagle_get_attrs(st, subtree, "textfield", NULL)) && CHILDREN(subtree) == NULL) { + rnd_message(RND_MSG_WARNING, "Ignoring empty text field\n"); + return 0; + } + if (text_val == NULL && !IS_TEXT(CHILDREN(subtree))) { + rnd_message(RND_MSG_WARNING, "Ignoring text field (invalid child node)\n"); + return 0; + } + +TODO("need to convert multiline text (\n) into multiple text objects; example: work/alien_formats/85 veegashield") + if (text_val == NULL) { + text_val = (const char *)GET_TEXT(CHILDREN(subtree)); + } + X = eagle_get_attrc(st, subtree, "x", -1); + Y = eagle_get_attrc(st, subtree, "y", -1); + + /* bounding box and anchor calculation */ + size = eagle_get_attrc(st, subtree, "size", -1); + bbw = (double)size * 0.905 * (double)eagle_strlen2(text_val) / 2.0; + bbh = (double)size * 1.45; + align = eagle_get_attrs(st, subtree, "align", NULL); + if (align != 0) { + if (rnd_strncasecmp(align, "bottom", 6) == 0) { align+=6; ay = ABOTTOM; } + else if (rnd_strncasecmp(align, "top", 3) == 0) { align+=3; ay = ATOP; } + else if (rnd_strncasecmp(align, "center", 6) == 0) { align+=6; ax = ay = 0; } /* plain "center" means "center-center" */ + else + rnd_message(RND_MSG_WARNING, "Ignoring invalid vertical text alignment '%s'\n", align); + if (*align == '-') { + align++; + if (rnd_strcasecmp(align, "left") == 0) ax = ALEFT; + else if (rnd_strcasecmp(align, "right") == 0) ax = ARIGHT; + else if (rnd_strcasecmp(align, "center") == 0) ax = 0; + else + rnd_message(RND_MSG_WARNING, "Ignoring invalid horizontal text alignment '%s'\n", align); + } + } + + + + rot = eagle_get_attrs(st, subtree, "rot", NULL); +/*rnd_trace("text=%s %mm;%mm bbw=%mm bbh=%mm align: %d %d anchor: %mm %mm rot=%s\n", text_val, X, Y, bbw, bbh, ax, ay, anchx, anchy, rot);*/ + + if (rot != NULL) { /* strict order seems to be: SMR */ + if (*rot == 'S') { + spin = 1; + rot++; + } + if (*rot == 'M') { + mirror = PCB_TXT_MIRROR_X; + rot++; + } + if (*rot == 'R') { + char *end; + rotdeg = strtol(rot+1, &end, 10); + if (*end != '\0') + rnd_message(RND_MSG_WARNING, "Ignoring invalid text rotation '%s' (requires integer)\n", rot); + + if (!spin && (rotdeg > 90) && (rotdeg <= 270)) { /* when spin is not enabled, eagle rotates the text so it's readable from bottom and right */ + rotdeg -= 180; + ax = -ax; + } + rotdeg = 360-rotdeg; /* compensate for the y mirror at the end */ + } + else + rnd_message(RND_MSG_WARNING, "Ignoring invalid text rotation '%s' (missing R prefix)\n", rot); + } + + switch(ax) { + case ALEFT: anchx = 0; break; + case ARIGHT: anchx = bbw; break; + default: anchx = bbw/2; + } + basel = 4*bbh/5; + switch(ay) { + case ATOP: anchy = 0; break; + case ABOTTOM: anchy = -basel; break; + default: anchy = -basel/2; + } + + pcb_text_new_by_bbox(ly, pcb_font(st->pcb, 0, 1), X, Y, bbw, bbh, anchx, anchy, 1, mirror, rotdeg, 0, text_val, text_flags); + + return 0; +} + +static long eagle_degrees_to_pcb_degrees(long const eagle_degrees) { + long e_degrees = eagle_degrees; + while (e_degrees < 0) { + e_degrees += 360; + } + while (e_degrees > 360) { + e_degrees -= 360; + } + return (360 - e_degrees); +} + +static int eagle_read_circle(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + eagle_loc_t loc = type; + pcb_arc_t *circ; + eagle_layerid_t ln = eagle_get_attrl(st, subtree, "layer", -1); + pcb_layer_t *ly; + + ly = eagle_layer_get(st, ln, loc, obj); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to allocate circle layer 'ly' to 'ln:%d' in eagle_read_circle()\n", ln); + return 0; + } + + circ = pcb_arc_alloc(ly); + circ->X = eagle_get_attrc(st, subtree, "x", -1); + circ->Y = eagle_get_attrc(st, subtree, "y", -1); + circ->Width = eagle_get_attrc(st, subtree, "radius", -1); + circ->Height = circ->Width; /* no ellipse support */ + circ->StartAngle = eagle_degrees_to_pcb_degrees(eagle_get_attrl(st, subtree, "StartAngle", 0)); + circ->Delta = -eagle_get_attrl(st, subtree, "Delta", -360); + circ->Thickness = eagle_get_attrc(st, subtree, "width", -1); + circ->Clearance = st->md_wire_wire*2; + circ->Flags = pcb_flag_make(PCB_FLAG_CLEARLINE); + + + switch(loc) { + case IN_SUBC: break; + case ON_BOARD: + size_bump(st, circ->X + circ->Width + circ->Thickness, circ->Y + circ->Width + circ->Thickness); + pcb_add_arc_on_layer(ly, circ); + break; + } + + return 0; +} + +static int eagle_read_rect(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + eagle_loc_t loc = type; + eagle_layerid_t ln = eagle_get_attrl(st, subtree, "layer", -1); + pcb_layer_t *ly; + rnd_coord_t x1, y1, x2, y2; + + ly = eagle_layer_get(st, ln, loc, obj); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to allocate rect layer 'ly' to 'ln:%d' in eagle_read_rect()\n", ln); + return 0; + } + + x1 = eagle_get_attrc(st, subtree, "x1", -1); + y1 = eagle_get_attrc(st, subtree, "y1", -1); + x2 = eagle_get_attrc(st, subtree, "x2", -1); + y2 = eagle_get_attrc(st, subtree, "y2", -1); + + pcb_poly_new_from_rectangle(ly, x1, y1, x2, y2, 0, pcb_no_flags()); + + switch(loc) { + case IN_SUBC: + break; + + case ON_BOARD: + size_bump(st, x1, y1); + size_bump(st, x2, y2); + break; + } + + return 0; +} + +static int eagle_read_wire_curve(read_state_t *st, trnode_t *subtree, void *obj, eagle_loc_t loc, pcb_layer_t *ly, double curvang) +{ + pcb_arc_t *arc; + rnd_coord_t x1, y1, x2, y2, th, cx, cy; + double sidex, sidey, sidelen, nx, ny, midx, midy, r, sa, da, dx, dy, sa2, curve; + + x1 = eagle_get_attrc(st, subtree, "x1", -1); + y1 = eagle_get_attrc(st, subtree, "y1", -1); + x2 = eagle_get_attrc(st, subtree, "x2", -1); + y2 = eagle_get_attrc(st, subtree, "y2", -1); + th = eagle_get_attrc(st, subtree, "width", -1); + curve = eagle_get_attrd(st, subtree, "curve", -1); + + midx = (x2 + x1) / 2.0; + midy = (y2 + y1) / 2.0; + sidex = x2 - x1; + sidey = y2 - y1; + sidelen = sqrt(sidex * sidex + sidey * sidey); + nx = -sidey / sidelen; + ny = sidex / sidelen; + r = (sidelen / 2) / tan(curvang / RND_RAD_TO_DEG / 2.0); + cx = rnd_round(midx + nx * r); + cy = rnd_round(midy + ny * r); +/* rnd_trace("curve mid: %mm;%mm center: %mm;%mm\n", midx, midy, cx, cy);*/ + + dx = x1 - cx; + dy = y1 - cy; + r = sqrt(dx * dx + dy * dy); + sa = 180.0 - atan2(y1 - cy, x1 - cx) * RND_RAD_TO_DEG; +/* ea = 180.0 - atan2(y2 - cy, x2 - cx) * RND_RAD_TO_DEG;*/ + + da = -curve; + +/* rnd_trace(" r=%mm %f %f -> %f\n", (rnd_coord_t)r, sa, ea, da);*/ + arc = pcb_arc_new(ly, cx, cy, r, r, sa, da, th, st->md_wire_wire*2, pcb_flag_make(PCB_FLAG_CLEARLINE), 0); + + switch (loc) { + case IN_SUBC: + break; + case ON_BOARD: + size_bump(st, arc->BoundingBox.X1, arc->BoundingBox.Y1); + size_bump(st, arc->BoundingBox.X2, arc->BoundingBox.Y2); + break; + } + + return 0; +} + +static int eagle_read_wire_line(read_state_t *st, trnode_t *subtree, void *obj, eagle_loc_t loc, pcb_layer_t *ly) +{ + pcb_line_t *lin; + + lin = pcb_line_alloc(ly); + lin->Point1.X = eagle_get_attrc(st, subtree, "x1", -1); + lin->Point1.Y = eagle_get_attrc(st, subtree, "y1", -1); + lin->Point2.X = eagle_get_attrc(st, subtree, "x2", -1); + lin->Point2.Y = eagle_get_attrc(st, subtree, "y2", -1); + lin->Thickness = eagle_get_attrc(st, subtree, "width", -1); + lin->Clearance = st->md_wire_wire*2; + lin->Flags = pcb_flag_make(PCB_FLAG_CLEARLINE); + lin->ID = pcb_create_ID_get(); + + switch (loc) { + case IN_SUBC: + break; + case ON_BOARD: + size_bump(st, lin->Point1.X + lin->Thickness, lin->Point1.Y + lin->Thickness); + size_bump(st, lin->Point2.X + lin->Thickness, lin->Point2.Y + lin->Thickness); + pcb_add_line_on_layer(ly, lin); + break; + } + + return 0; +} + + +static int eagle_read_wire(read_state_t * st, trnode_t * subtree, void *obj, int type) +{ + eagle_loc_t loc = type; + pcb_layer_t *ly; + eagle_layerid_t ln = eagle_get_attrl(st, subtree, "layer", -1); + long linetype = eagle_get_attrl(st, subtree, "linetype", -1);/* only present if bin file */ + double curve = eagle_get_attrd(st, subtree, "curve", 0); /*present if a wire "arc" */ + + ly = eagle_layer_get(st, ln, loc, obj); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to allocate wire layer 'ly' to ln:%d in eagle_read_wire()\n"); + return 0; + } + + if (curve) + return eagle_read_wire_curve(st, subtree, obj, loc, ly, curve); + + if (linetype > 0) /* only occurs if loading eagle binary wire type != 0 */ + return eagle_read_circle(st, subtree, obj, loc); + + return eagle_read_wire_line(st, subtree, obj, loc, ly); +} + +typedef enum { + EAGLE_PSH_SQUARE, + EAGLE_PSH_ROUND, + EAGLE_PSH_OCTAGON, + EAGLE_PSH_LONG, + EAGLE_PSH_OFFSET, /* need example of this */ + EAGLE_PSH_SMD /* special round rect */ +} eagle_pstk_shape_t; + +/* Create a padstack at x;y; roundness and onbottom, applies only to + EAGLE_PSH_SMD. dx and dy are the size; for some shapes they have to + be equal. Returns NULL on error. */ +static pcb_pstk_t *eagle_create_pstk(read_state_t *st, pcb_data_t *data, rnd_coord_t x, rnd_coord_t y, eagle_pstk_shape_t shape, rnd_coord_t dx, rnd_coord_t dy, rnd_coord_t clr, rnd_coord_t drill_dia, int roundness, int rot, int onbottom, rnd_bool plated) +{ + pcb_pstk_shape_t shapes[8]; +TODO("{clearance} need to establish how mask clearance is defined and done in eagle") + rnd_coord_t mask_gap = clr; +TODO("{clearance} need to establish how paste clearance, if any, is defined and done in eagle") + rnd_coord_t paste_gap = 0; + + switch (shape) { + case EAGLE_PSH_SQUARE: + shapes[0].layer_mask = PCB_LYT_TOP | PCB_LYT_MASK; + shapes[0].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_rect(&shapes[0], dx + mask_gap, dy + mask_gap); + shapes[1].layer_mask = PCB_LYT_TOP | PCB_LYT_PASTE; + shapes[1].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_rect(&shapes[1], dx + paste_gap, dy + paste_gap); + shapes[2].layer_mask = PCB_LYT_TOP | PCB_LYT_COPPER; + shapes[2].comb = 0; + pcb_shape_rect(&shapes[2], dx, dy); + shapes[3].layer_mask = PCB_LYT_INTERN | PCB_LYT_COPPER; + shapes[3].comb = 0; + pcb_shape_rect(&shapes[3], dx, dy); + shapes[4].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_COPPER; + shapes[4].comb = 0; + pcb_shape_rect(&shapes[4], dx, dy); + shapes[5].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_PASTE; + shapes[5].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_rect(&shapes[5], dx + paste_gap, dy + paste_gap); + shapes[6].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_MASK; + shapes[6].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_rect(&shapes[6], dx + mask_gap, dy + mask_gap); + shapes[7].layer_mask = 0; + break; + case EAGLE_PSH_OCTAGON: + { + rnd_coord_t dx2 = dx/2, dy2 = dy/2; + shapes[0].layer_mask = PCB_LYT_TOP | PCB_LYT_MASK; + shapes[0].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_octagon(&shapes[0], dx2 + mask_gap, dy2 + mask_gap); + shapes[1].layer_mask = PCB_LYT_TOP | PCB_LYT_PASTE; + shapes[1].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_octagon(&shapes[1], dx2 + paste_gap, dy2 + paste_gap); + shapes[2].layer_mask = PCB_LYT_TOP | PCB_LYT_COPPER; + shapes[2].comb = 0; + pcb_shape_octagon(&shapes[2], dx2, dy2); + shapes[3].layer_mask = PCB_LYT_INTERN | PCB_LYT_COPPER; + shapes[3].comb = 0; + pcb_shape_octagon(&shapes[3], dx2, dy2); + shapes[4].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_COPPER; + shapes[4].comb = 0; + pcb_shape_octagon(&shapes[4], dx2, dy2); + shapes[5].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_PASTE; + shapes[5].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_octagon(&shapes[5], dx2 + paste_gap, dy2 + paste_gap); + shapes[6].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_MASK; + shapes[6].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_octagon(&shapes[6], dx2 + mask_gap, dy2 + mask_gap); + shapes[7].layer_mask = 0; + } + break; + case EAGLE_PSH_ROUND: + assert(dx == dy); + case EAGLE_PSH_OFFSET: +TODO("{pstk_shape} TODO need OFFSET shape generation function, once OFFSET object understood") + case EAGLE_PSH_LONG: + shapes[0].layer_mask = PCB_LYT_TOP | PCB_LYT_MASK; + shapes[0].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_oval(&shapes[0], dx + mask_gap, dy + mask_gap); + shapes[1].layer_mask = PCB_LYT_TOP | PCB_LYT_PASTE; + shapes[1].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_oval(&shapes[1], dx + paste_gap, dy + paste_gap); + shapes[2].layer_mask = PCB_LYT_TOP | PCB_LYT_COPPER; + shapes[2].comb = 0; + pcb_shape_oval(&shapes[2], dx, dy); + shapes[3].layer_mask = PCB_LYT_INTERN | PCB_LYT_COPPER; + shapes[3].comb = 0; + pcb_shape_oval(&shapes[3], dx, dy); + shapes[4].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_COPPER; + shapes[4].comb = 0; + pcb_shape_oval(&shapes[4], dx, dy); + shapes[5].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_PASTE; + shapes[5].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_oval(&shapes[5], dx + paste_gap, dy + paste_gap); + shapes[6].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_MASK; + shapes[6].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + pcb_shape_oval(&shapes[6], dx + mask_gap, dy + mask_gap); + shapes[7].layer_mask = 0; + break; + case EAGLE_PSH_SMD: + { + double rnd = (double)roundness / 200.0; + pcb_layer_type_t side = onbottom ? PCB_LYT_BOTTOM : PCB_LYT_TOP; + shapes[0].layer_mask = side | PCB_LYT_MASK; + shapes[0].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + if (rnd == 0) + pcb_shape_rect(&shapes[0], dx + mask_gap, dy + mask_gap); + else + pcb_shape_roundrect(&shapes[0], dx + mask_gap, dy + mask_gap, rnd); + shapes[1].layer_mask = side | PCB_LYT_PASTE; + shapes[1].comb = PCB_LYC_SUB | PCB_LYC_AUTO; + if (rnd == 0) + pcb_shape_rect(&shapes[1], dx + paste_gap, dy + paste_gap); + else + pcb_shape_roundrect(&shapes[1], dx + paste_gap, dy + paste_gap, rnd); + shapes[2].layer_mask = side | PCB_LYT_COPPER; + shapes[2].comb = 0; + if (rnd == 0) + pcb_shape_rect(&shapes[2], dx, dy); + else + pcb_shape_roundrect(&shapes[2], dx, dy, rnd); + shapes[3].layer_mask = 0; + } + break; + } + + if (rot != 0) { + int n; + double sina = sin(-(double)rot / RND_RAD_TO_DEG), cosa = cos(-(double)rot / RND_RAD_TO_DEG); + + for(n = 0; n < sizeof(shapes)/sizeof(shapes[0]); n++) { + if (shapes[n].layer_mask == 0) break; + pcb_pstk_shape_rot(&shapes[n], sina, cosa, rot); + } + } + + return pcb_pstk_new_from_shape(data, x, y, drill_dia, plated, clr, shapes); +} + +static int eagle_read_smd(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + rnd_coord_t x, y, dx, dy; + pcb_pstk_t *ps; + pcb_subc_t *subc = obj; + const char *name, *srot; +TODO("{smdsides} rot example too, on the bottom side to check if rotation inverts") + eagle_layerid_t ln; + eagle_layer_t *ly; + long roundness = 0; + rnd_coord_t clr; + int rot = 0, onbottom = 0; + + assert(type == IN_SUBC); + + ln = eagle_get_attrl(st, subtree, "layer", -1); + if (ln != -1) { /* can't go by layer type because there's no layer stack yet (we are in lib) */ + if (ln == 16) onbottom = 1; + else if (ln== 1) onbottom = 0; + else rnd_message(RND_MSG_ERROR, "Failed to determine smd pad side, assuming top (invalid layer %d)\n", ln); + } + else + rnd_message(RND_MSG_ERROR, "Failed to determine smd pad side, assuming top (missing layer)\n"); + + name = eagle_get_attrs(st, subtree, "name", NULL); + x = eagle_get_attrc(st, subtree, "x", 0); + y = eagle_get_attrc(st, subtree, "y", 0); + dx = eagle_get_attrc(st, subtree, "dx", 0); + dy = eagle_get_attrc(st, subtree, "dy", 0); + srot = eagle_get_attrs(st, subtree, "rot", NULL); + if (srot != NULL) + rot = eagle_rot2degrees(srot); + roundness = eagle_get_attrl(st, subtree, "roundness", 0); + +TODO("{thermal} need to load thermals flags to set clearance; may in fact be more contactref related.") + +TODO("{clearance} this should be coming from the eagle file") + clr = conf_core.design.clearance; + + ps = eagle_create_pstk(st, subc->data, x, y, EAGLE_PSH_SMD, dx, dy, clr, 0, roundness, rot, onbottom, 0); + if (ps == NULL) + rnd_message(RND_MSG_ERROR, "Failed to load smd pad\n"); + + if (name != NULL) + pcb_attribute_put(&ps->Attributes, "term", name); + + return 0; +} + +static int eagle_read_pad_or_hole(read_state_t *st, trnode_t *subtree, void *obj, int type, int hole) +{ + eagle_loc_t loc = type; + rnd_coord_t x, y, drill, diax, diay, clr, mask; + pcb_pstk_t *ps; + const char *name, *shape; + pcb_data_t *data; + eagle_pstk_shape_t sh = EAGLE_PSH_ROUND; /* if nothing is said, round is used by eagle */ + int roundness = 0; + int rot = 0, onbottom = 0, plated = 1; + + switch(loc) { + case IN_SUBC: + data = ((pcb_subc_t *)obj)->data; + break; + case ON_BOARD: + data = st->pcb->Data; + break; + } + + name = eagle_get_attrs(st, subtree, "name", NULL); + x = eagle_get_attrc(st, subtree, "x", 0); + y = eagle_get_attrc(st, subtree, "y", 0); + drill = eagle_get_attrc(st, subtree, "drill", 0); + diax = eagle_get_attrc(st, subtree, "diameter", drill * (1.0+st->rv_pad_top*2.0)); + shape = eagle_get_attrs(st, subtree, "shape", 0); + + clr = conf_core.design.clearance; /* eagle doesn't seem to support per via clearance */ + mask = (loc == IN_SUBC) ? conf_core.design.clearance : 0; /* board vias don't have mask */ + + if ((diax - drill) / 2.0 < st->ms_width) + diax = drill + 2*st->ms_width; + + TODO("{bbvia} padstack: process the extent attribute for bbvia") + TODO("{plating} check how to determine plated"); + TODO("bin: test the binary numbers for offset and long: shape = {square, round, octagon, long, offset} binary"); + diay = diax; + if (shape != NULL) { + if ((strcmp(shape, "octagon") == 0) || (strcmp(shape, "2") == 0)) + sh = EAGLE_PSH_OCTAGON; + else if ((strcmp(shape, "square") == 0) || (strcmp(shape, "0") == 0)) + sh = EAGLE_PSH_SQUARE; + else if ((strcmp(shape, "round") == 0) || (strcmp(shape, "1") == 0)) + sh = EAGLE_PSH_ROUND; + else if ((strcmp(shape, "offset") == 0) || (strcmp(shape, "4") == 0)) { + sh = EAGLE_PSH_OFFSET; + diay *= 2; + } + else if ((strcmp(shape, "long") == 0) || (strcmp(shape, "3") == 0)) { + sh = EAGLE_PSH_LONG; + diay *= 2; + } + else { + rnd_message(RND_MSG_ERROR, "Invalid padstack shape: '%s' - omitting padstack\n", shape); + return -1; + } + } +TODO("variable mask is ignored"); + ps = eagle_create_pstk(st, data, x, y, sh, diax, diay, clr, drill, roundness, rot, onbottom, plated); + + if (name != NULL) + pcb_attribute_put(&ps->Attributes, "term", name); + + switch(loc) { + case IN_SUBC: break; + case ON_BOARD: + size_bump(st, x + diax, y + diay); + break; + } + + return 0; +} + +static int eagle_read_hole(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + return eagle_read_pad_or_hole(st, subtree, obj, type, 1); +} + +static int eagle_read_pad(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + return eagle_read_pad_or_hole(st, subtree, obj, type, 0); +} + +static int eagle_read_via(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + return eagle_read_pad_or_hole(st, subtree, obj, ON_BOARD, 0); +} + + +/****************** composite objects ******************/ + +/* Save the relative coords and size of the each relevant text fields */ +static int eagle_read_pkg_txt(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + rnd_coord_t size; + trnode_t *n; + const char *cont; + rnd_coord_t x, y; + int dir = 0, scale; + eagle_layerid_t layer; + const char *pattern; + + for(n = CHILDREN(subtree); n != NULL; n = NEXT(n)) + if (IS_TEXT(n)) + break; + + if ((n == NULL) || ((cont = GET_TEXT(n)) == NULL)) + return 0; + + /* create dyntext for name and value only (the core could handle any attribute, but we can't pick them up on the element ref) */ + if (STRCMP(cont, ">NAME") == 0) + pattern = "%a.parent.refdes%"; + else if (STRCMP(cont, ">VALUE") == 0) + pattern = "%a.parent.value%"; + else + return 0; + + layer = eagle_get_attrl(st, subtree, "layer", 0); + size = eagle_get_attrc(st, subtree, "size", EAGLE_TEXT_SIZE_100); + x = eagle_get_attrc(st, subtree, "x", 0); + y = eagle_get_attrc(st, subtree, "y", 0); + y += size; /* different text object origin in eagle */ + scale = (int)(((double)size/(double)EAGLE_TEXT_SIZE_100) * 100.0); + + pcb_subc_add_dyntex((pcb_subc_t *)obj, x, y, dir, scale, (layer == 27), pattern); + + return 0; +} + +static void eagle_read_poly_corner(read_state_t *st, trnode_t *n, pcb_poly_t *poly, const char *xname, const char *yname, eagle_loc_t loc) +{ + rnd_coord_t x, y; + x = eagle_get_attrc(st, n, xname, 0); + y = eagle_get_attrc(st, n, yname, 0); + pcb_poly_point_new(poly, x, y); + switch (loc) { + case IN_SUBC: + break; + case ON_BOARD: + size_bump(st, x, y); + break; + } +} + +static int eagle_read_poly(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + eagle_loc_t loc = type; + pcb_layer_t *ly; + eagle_layerid_t ln = eagle_get_attrl(st, subtree, "layer", -1); + const char *pour = GET_PROP(subtree, "pour"); + pcb_poly_t *poly; + trnode_t *n; + int is_cutout; + + ly = eagle_layer_get(st, ln, loc, obj); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to allocate polygon layer 'ly' to 'ln:%d' in eagle_read_poly()\n", ln); + return 0; + } + + is_cutout = ((pour != NULL) && (strcmp(pour, "cutout") == 0)); + + poly = pcb_poly_new(ly, 0, pcb_flag_make(is_cutout ? PCB_FLAG_FOUND : PCB_FLAG_CLEARPOLY)); +TODO("{polyarc} need to check XML never defines a polygon outline with arcs or curves") + for(n = CHILDREN(subtree); n != NULL; n = NEXT(n)) { + if (STRCMP(NODENAME(n), "vertex") == 0) { + rnd_coord_t x, y; + x = eagle_get_attrc(st, n, "x", 0); + y = eagle_get_attrc(st, n, "y", 0); + pcb_poly_point_new(poly, x, y); + switch (loc) { + case IN_SUBC: + break; + case ON_BOARD: + size_bump(st, x, y); + break; + } +TODO("bin: need to check if binary format is sometimes using arcs or curves for polygn outlines") +TODO("bin: can remove the following if dealt with in post processor for binary tree") + } else if (STRCMP(NODENAME(n), "wire") == 0) { /* binary format vertices it seems */ + eagle_read_poly_corner(st, n, poly, "linetype_0_x1", "linetype_0_y1", loc); + eagle_read_poly_corner(st, n, poly, "linetype_0_x2", "linetype_0_y2", loc); + } + } + + pcb_add_poly_on_layer(ly, poly); + pcb_poly_init_clip(st->pcb->Data, ly, poly); + + return 0; +} + +static int eagle_read_pkg(read_state_t *st, trnode_t *subtree, pcb_subc_t *subc) +{ + static const dispatch_t disp[] = { /* possible children of package */ + {"description", eagle_read_nop}, + {"wire", eagle_read_wire}, + {"hole", eagle_read_hole}, + {"circle", eagle_read_circle}, + {"arc", eagle_read_circle}, + {"smd", eagle_read_smd}, + {"pad", eagle_read_pad}, + {"text", eagle_read_pkg_txt}, + {"polygon", eagle_read_poly}, /* TODO: check this to handle subc */ + {"rectangle", eagle_read_rect}, + {"@text", eagle_read_nop}, + {NULL, NULL} + }; + + TODO("^^^ can polygon be in footprints?"); + + return eagle_foreach_dispatch(st, CHILDREN(subtree), disp, subc, IN_SUBC); +} + +static int eagle_read_library_file_pkgs(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + trnode_t *n; + + for(n = CHILDREN(subtree); n != NULL; n = NEXT(n)) { + rnd_trace("looking at child %s of packages node\n", NODENAME(n)); + if (STRCMP(NODENAME(n), "package") == 0) { + pcb_subc_t *subc; + + subc = pcb_subc_alloc(); + pcb_attribute_put(&subc->Attributes, "refdes", "K1"); + pcb_subc_reg(st->pcb->Data, subc); + pcb_subc_bind_globals(st->pcb, subc); + eagle_read_pkg(st, n, subc); + if (pcb_data_is_empty(subc->data)) { + pcb_subc_free(subc); + rnd_message(RND_MSG_WARNING, "Ignoring empty package in library\n"); + continue; + } + + pcb_attribute_put(&subc->Attributes, "refdes", eagle_get_attrs(st, n, "name", NULL)); + pcb_attribute_put(&subc->Attributes, "value", eagle_get_attrs(st, n, "value", NULL)); + pcb_attribute_put(&subc->Attributes, "footprint", eagle_get_attrs(st, n, "package", NULL)); + + pcb_subc_bbox(subc); +TODO("subc: revise this: are we loading an instance here? do we need to place it? do not even bump if not!") + if (st->pcb->Data->subc_tree == NULL) + st->pcb->Data->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(st->pcb->Data->subc_tree, (rnd_box_t *)subc); + pcb_subc_rebind(st->pcb, subc); + +TODO("revise rotation and flip") +#if 0 + if ((moduleRotation == 90) || (moduleRotation == 180) || (moduleRotation == 270)) { + /* lossles module rotation for round steps */ + moduleRotation = moduleRotation / 90; + pcb_subc_rotate90(subc, moduleX, moduleY, moduleRotation); + } + else if (moduleRotation != 0) { + double rot = moduleRotation; + pcb_subc_rotate(subc, moduleX, moduleY, cos(rot/RND_RAD_TO_DEG), sin(rot/RND_RAD_TO_DEG), rot); + } +#endif + + size_bump(st, subc->BoundingBox.X2, subc->BoundingBox.Y2); + } + } + return 0; +} + +static int eagle_read_lib_pkgs(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + trnode_t *n; + eagle_library_t *lib = obj; + + for(n = CHILDREN(subtree); n != NULL; n = NEXT(n)) { + if (STRCMP(NODENAME(n), "package") == 0) { + pcb_subc_t *subc; + const char *name = eagle_get_attrs(st, n, "name", NULL); + + if ((st->elem_by_name) && (name == NULL)) { + rnd_message(RND_MSG_WARNING, "Ignoring package with no name\n"); + continue; + } + + subc = pcb_subc_alloc(); + eagle_read_pkg(st, n, subc); + if (pcb_subc_is_empty(subc)) { + rnd_message(RND_MSG_WARNING, "Ignoring empty package %s\n", name); + free(subc); + continue; + } + + if (st->elem_by_name) + htsp_set(&lib->elems, (char *)name, subc); + st->parser.calls->set_user_data(n, subc); + } + } + return 0; +} + +static int eagle_read_library(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + static const dispatch_t disp[] = { /* possible children of */ + {"description", eagle_read_nop}, + {"devices", eagle_read_nop}, + {"symbols", eagle_read_nop}, + {"devicesets", eagle_read_nop}, + {"packages", eagle_read_library_file_pkgs},/* read & place element(s) in library */ + {"@text", eagle_read_nop}, + {NULL, NULL} + }; + return eagle_foreach_dispatch(st, CHILDREN(subtree), disp, subtree, 0); +} + +static int eagle_read_libs(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + trnode_t *n; + static const dispatch_t disp[] = { /* possible children of */ + {"description", eagle_read_nop}, + {"packages", eagle_read_lib_pkgs}, + {"@text", eagle_read_nop}, + {NULL, NULL} + }; + + for(n = CHILDREN(subtree); n != NULL; n = NEXT(n)) { + if (STRCMP(NODENAME(n), "library") == 0) { + const char *name = eagle_get_attrs(st, n, "name", NULL); + eagle_library_t *lib; + if ((st->elem_by_name) && (name == NULL)) { + rnd_message(RND_MSG_WARNING, "Ignoring library with no name\n"); + continue; + } + lib = calloc(sizeof(eagle_library_t), 1); + + if (st->elem_by_name) + htsp_init(&lib->elems, strhash, strkeyeq); + + eagle_foreach_dispatch(st, CHILDREN(n), disp, lib, 0); + + if (st->elem_by_name) + htsp_set(&st->libs, (char *)name, lib); + } + } + return 0; +} + +static int eagle_read_contactref(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + const char *elem, *pad, *net; + char conn[256]; + + elem = eagle_get_attrs(st, subtree, "element", NULL); + pad = eagle_get_attrs(st, subtree, "pad", NULL); + + + if ((elem == NULL) || (pad == NULL)) { + rnd_message(RND_MSG_WARNING, "Failed to parse contactref node: missing \"element\" or \"pad\" netlist attributes\n"); + return -1; + } + + if (elem != NULL && elem[0] == '-' && elem[1] == '\0') { + rnd_snprintf(conn, sizeof(conn), "%s-%s", "HYPHEN", pad); + rnd_message(RND_MSG_WARNING, "Substituted invalid element name '-' with 'HYPHEN'\n"); + } else { + rnd_snprintf(conn, sizeof(conn), "%s-%s", elem, pad); + } + + net = eagle_get_attrs(st, PARENT(subtree), "name", NULL); + + if (net != NULL && net[0] == '-' && net[1] == '\0') { /* pcb-rnd doesn't like it when Eagle uses '-' for GND*/ + rnd_actionva(&st->pcb->hidlib, "Netlist", "Add", "GND", conn, NULL); + rnd_message(RND_MSG_WARNING, "Substituted contactref net \"GND\" instead of original invalid '-'\n"); + } else { + rnd_actionva(&st->pcb->hidlib, "Netlist", "Add", net, conn, NULL); + } + return 0; +} + +static int eagle_read_signals(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + trnode_t *n; + static const dispatch_t disp[] = { /* possible children of */ + {"contactref", eagle_read_contactref}, /* if this fails, rest of disp acts up */ + {"wire", eagle_read_wire}, + {"arc", eagle_read_circle}, /*binary format */ + {"polygon", eagle_read_poly}, + {"via", eagle_read_via}, + {"text", eagle_read_text}, + {"@text", eagle_read_nop}, + {NULL, NULL} + }; + + rnd_actionva(&st->pcb->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&st->pcb->hidlib, "Netlist", "Clear", NULL); + + for(n = CHILDREN(subtree); n != NULL; n = NEXT(n)) { + if (STRCMP(NODENAME(n), "signal") == 0) { + const char *name = eagle_get_attrs(st, n, "name", NULL); + if (name == NULL) { + rnd_message(RND_MSG_WARNING, "Ignoring signal with no name\n"); + continue; + } + eagle_foreach_dispatch(st, CHILDREN(n), disp, (char *)name, ON_BOARD); + } + } + + rnd_actionva(&st->pcb->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&st->pcb->hidlib, "Netlist", "Thaw", NULL); + + return 0; +} + +static void eagle_read_subc_attrs(read_state_t *st, trnode_t *nd, pcb_subc_t *subc, rnd_coord_t x, rnd_coord_t y, const char *attname, const char *subc_attr, const char *str, rnd_bool add_text) +{ + pcb_attribute_put(&subc->Attributes, subc_attr, str); + if (!add_text) + return; + +TODO("{libtext} some text objects should be already created in the library; we should iterate over existing %DYNTEXT% attributes, add the new ones, change the coords of existing ones CUCP#45") +#if 0 + y += EAGLE_TEXT_SIZE_100; + + for(nd = CHILDREN(nd); nd != NULL; nd = NEXT(nd)) { + const char *this_attr = eagle_get_attrs(st, nd, "name", ""); + if (((STRCMP(NODENAME(nd), "attribute") == 0) || + (STRCMP(NODENAME(nd), "element2") == 0) ) + && (strcmp(attname, this_attr) == 0)) { + direction = eagle_rot2steps(eagle_get_attrs(st, nd, "rot", NULL)); + if (direction < 0) + direction = 0; + size = eagle_get_attrc(st, nd, "size", EAGLE_TEXT_SIZE_100); + break; + } + } +#endif +} + +static int eagle_read_elements(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + trnode_t *n, *nlib; + double ang; + + if (st->elem_by_name) + nlib = NULL; + else + nlib = eagle_trpath(st, st->parser.root, "drawing", "board", "libraries", NULL); + + for(n = CHILDREN(subtree); n != NULL; n = NEXT(n)) { + if (STRCMP(NODENAME(n), "element") == 0) { + rnd_coord_t x, y; + const char *name, *val, *lib, *pkg, *rot, *mirrored; + pcb_subc_t *subc, *new_subc; + int back = 0; + + name = eagle_get_attrs(st, n, "name", NULL); + val = eagle_get_attrs(st, n, "value", NULL); + + if (name == NULL) { + rnd_message(RND_MSG_ERROR, "Element name not found in tree\n"); + name = "refdes_not_found"; + val = "parse_error"; + } + + /* need to get these as string because error messages will use them */ + lib = eagle_get_attrs(st, n, "library", NULL); + pkg = eagle_get_attrs(st, n, "package", NULL); + + if (st->elem_by_name) { /* xml: library and package are named */ + if ((lib == NULL) || (pkg == NULL)) { + rnd_message(RND_MSG_WARNING, "Ignoring element with incomplete library reference\n"); + continue; + } + subc = eagle_libelem_by_name(st, lib, pkg); + } + else { + long libi = eagle_get_attrl(st, n, "library", -1); + long pkgi = eagle_get_attrl(st, n, "package", -1); + if ((libi < 0) || (pkgi < 0)) { + rnd_message(RND_MSG_WARNING, "Ignoring element with broken library reference: %s/%s\n", lib, pkg); + continue; + } + subc = eagle_libelem_by_idx(st, nlib, libi, pkgi); + } + + /* sanity checks: the element exists and is non-empty */ + if (subc == NULL) { + rnd_message(RND_MSG_ERROR, "Library element not found: %s/%s\n", lib, pkg); + continue; + } + if (pcb_subc_is_empty(subc)) { + rnd_message(RND_MSG_ERROR, "Not placing empty element: %s/%s\n", lib, pkg); + continue; + } + + x = eagle_get_attrc(st, n, "x", -1); + y = eagle_get_attrc(st, n, "y", -1); + rot = eagle_get_attrs(st, n, "rot", NULL); + mirrored = eagle_get_attrs(st, n, "mirrored", NULL); + if ((rot != NULL) && (*rot == 'M')) { + rot++; + back = 1; + } else if ((mirrored != NULL) && (*mirrored == '1')) { + back = 1; + } + + new_subc = pcb_subc_dup_at(st->pcb, st->pcb->Data, subc, x, y, rnd_false, rnd_false); + new_subc->Flags = pcb_no_flags(); + new_subc->ID = pcb_create_ID_get(); + + eagle_read_subc_attrs(st, n, new_subc, x, y, "PROD_ID", "footprint", pkg, 0); + eagle_read_subc_attrs(st, n, new_subc, x, y, "NAME", "refdes", name, 1); + eagle_read_subc_attrs(st, n, new_subc, x, y, "VALUE", "value", val, 0); + + pcb_subc_bbox(new_subc); + pcb_subc_rebind(st->pcb, new_subc); + + if (rot != NULL) { + char *end; + ang = strtod(rot+1, &end); + if (*end == '\0') { + if (fmod(ang, 90) == 0) { /* use lossles rotation without any sin() */ + int steps = eagle_rot2steps(rot); + if (back) + steps = (steps + 2)%4; + if (steps > 0) + pcb_subc_rotate90(new_subc, x, y, steps); + else + rnd_message(RND_MSG_WARNING, "0 degree element rotation/steps used for '%s'/'%d': %s/%s/%s\n", rot, steps, name, pkg, lib); + } + else { + double sina, cosa; + ang = -ang; + sina = sin(ang / RND_RAD_TO_DEG); + cosa = cos(ang / RND_RAD_TO_DEG); + pcb_subc_rotate(new_subc, x, y, cosa, sina, ang); + } + } + else + rnd_message(RND_MSG_ERROR, "syntax error in element rotation '%s': %s/%s/%s\n", rot, name, pkg, lib); + } + else + ang = 0; + + if (back) + pcb_subc_change_side(new_subc, 2 * y - st->pcb->hidlib.size_y); + + pcb_subc_create_aux(new_subc, x, y, ang, back); + + size_bump(st, new_subc->BoundingBox.X2, new_subc->BoundingBox.Y2); + } + } + return 0; +} + +static int eagle_read_plain(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + static const dispatch_t disp[] = { /* possible children of */ + {"contactref", eagle_read_contactref}, + {"wire", eagle_read_wire}, + {"arc", eagle_read_circle}, /* binary format */ + {"polygon", eagle_read_poly}, + {"rectangle", eagle_read_rect}, + {"via", eagle_read_via}, + {"circle", eagle_read_circle}, + {"text", eagle_read_text}, + {"hole", eagle_read_hole}, + {"dimension", eagle_read_nop}, + {"@text", eagle_read_nop}, + {NULL, NULL} + }; + +TODO("test (should process these probably no-net-no-signal objects)") + return eagle_foreach_dispatch(st, CHILDREN(subtree), disp, NULL, ON_BOARD); +} + +static int eagle_read_board(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + static const dispatch_t disp[] = { /* possible children of */ + {"plain", eagle_read_plain}, + {"libraries", eagle_read_libs}, + {"attributes", eagle_read_nop}, + {"variantdefs", eagle_read_nop}, + {"classes", eagle_read_nop}, + {"description", eagle_read_nop}, + {"designrules", eagle_read_nop}, + {"autorouter", eagle_read_nop}, + {"elements", eagle_read_elements}, + {"signals", eagle_read_signals}, + {"errors", eagle_read_nop}, + {"@text", eagle_read_nop}, + {NULL, NULL} + }; + return eagle_foreach_dispatch(st, CHILDREN(subtree), disp, NULL, 0); +} + + +static int eagle_read_drawing(read_state_t *st, trnode_t *subtree, void *obj, int type) +{ + int res; + + static const dispatch_t disp_1[] = { /* possible children of */ + {"settings", eagle_read_nop}, + {"layers", eagle_read_layers}, + {"grid", eagle_read_nop}, + {"board", eagle_read_nop}, + {"library", eagle_read_nop}, + {"unknown11", eagle_read_nop}, /* TODO: temporary; from the binary tree */ + {"@text", eagle_read_nop}, + {NULL, NULL} + }; + + static const dispatch_t disp_2[] = { /* possible children of */ + {"settings", eagle_read_nop}, + {"layers", eagle_read_nop}, + {"grid", eagle_read_nop}, + {"board", eagle_read_board}, + {"library", eagle_read_library}, + {"unknown11", eagle_read_nop}, /* TODO: temporary; from the binary tree */ + {"@text", eagle_read_nop}, + {NULL, NULL} + }; + + res = eagle_foreach_dispatch(st, CHILDREN(subtree), disp_1, NULL, 0); + res |= eagle_foreach_dispatch(st, CHILDREN(subtree), disp_2, NULL, 0); + return res; +} + +static int eagle_read_design_rules(read_state_t *st) +{ + trnode_t *dr, *n; + const char *name; + + /* st->ms_width the default minimum feature width, already defined */ + st->rv_pad_top = 0.25; + st->rv_pad_inner = 0.25; + st->rv_pad_bottom = 0.25; + st->md_wire_wire = RND_MIL_TO_COORD(10); /* default minimum wire to wire spacing */ + + dr = eagle_trpath(st, st->parser.root, "drawing", "board", "designrules", NULL); + if (dr == NULL) { + rnd_message(RND_MSG_WARNING, "can't find design rules, using sane defaults\n"); + } else { + for(n = CHILDREN(dr); n != NULL; n = NEXT(n)) { + if (STRCMP(NODENAME(n), "param") != 0) + continue; + name = eagle_get_attrs(st, n, "name", NULL); + if (strcmp(name, "mdWireWire") == 0) st->md_wire_wire = eagle_get_attrcu(st, n, "value", 0); + else if (strcmp(name, "msWidth") == 0) st->ms_width = eagle_get_attrcu(st, n, "value", 0); + else if (strcmp(name, "rvPadTop") == 0) st->rv_pad_top = eagle_get_attrd(st, n, "value", 0); + else if (strcmp(name, "rvPadInner") == 0) st->rv_pad_inner = eagle_get_attrd(st, n, "value", 0); + else if (strcmp(name, "rvPadBottom") == 0) st->rv_pad_bottom = eagle_get_attrd(st, n, "value", 0); + } + if ((st->rv_pad_top != st->rv_pad_inner) || (st->rv_pad_top != st->rv_pad_inner)) + rnd_message(RND_MSG_WARNING, "top/inner/bottom default pad sizes differ - using top size only\n"); + } + return 0; +} + +static int eagle_read_ver(const char *ver) +{ + int v1, v2, v3; + char *end; + + v3 = 0; + + if (ver == NULL) { + rnd_message(RND_MSG_ERROR, "no version attribute in \n"); + return -1; + } + v1 = strtol(ver, &end, 10); + if (*end != '.') { + rnd_message(RND_MSG_ERROR, "malformed version string [1] in \n"); + return -1; + } + v2 = strtol(end+1, &end, 10); + if (*end != '.' && *end != '\0') { + rnd_message(RND_MSG_ERROR, "malformed version string [2] in \n"); + return -1; + } else if (*end == '.') { + v3 = strtol(end+1, &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "malformed version string [3] in \n"); + return -1; + } + } + + /* version check */ + if (v1 < 6) { + rnd_message(RND_MSG_ERROR, "file version too old\n"); + return -1; + } + if (v1 > 8) { + rnd_message(RND_MSG_ERROR, "file version too new\n"); + return -1; + } + rnd_message(RND_MSG_DEBUG, "Loading eagle board version %d.%d.%d\n", v1, v2, v3); + return 0; +} + +static void st_init(read_state_t *st) +{ + htip_init(&st->layers, longhash, longkeyeq); + htsp_init(&st->libs, strhash, strkeyeq); + pcb_layer_group_setup_default(st->pcb); +} + +static void st_uninit(read_state_t *st) +{ + htip_entry_t *ei; + htsp_entry_t *es; + + pcb_layergrp_fix_old_outline(st->pcb); + + for (ei = htip_first(&st->layers); ei; ei = htip_next(&st->layers, ei)) + free(ei->value); + htip_uninit(&st->layers); + + for (es = htsp_first(&st->libs); es; es = htsp_next(&st->libs, es)) { + htsp_entry_t *e; + eagle_library_t *l = es->value; + for (e = htsp_first(&l->elems); e; e = htsp_next(&l->elems, e)) + free(e->value); + htsp_uninit(&l->elems); + free(l); + } + htsp_uninit(&st->libs); + st->parser.calls->unload(&st->parser); +} + +static int post_process_thermals(read_state_t *st) +{ +TODO("{thermal} process thermals") + PCB_PADSTACK_LOOP(st->pcb->Data); + { + } + PCB_END_LOOP; + return 0; +} + +static int post_process_polyholes(read_state_t *st) +{ + rnd_layer_id_t lid; + for(lid = 0; lid < st->pcb->Data->LayerN; lid++) { + pcb_poly_t *hole, *poly; + gdl_iterator_t ith, itp; + pcb_layer_t *ly = &st->pcb->Data->Layer[lid]; + if (!(pcb_layer_flags(PCB, lid) & PCB_LYT_COPPER)) continue; + linelist_foreach(&(ly)->Polygon, &ith, hole) { + if (!PCB_FLAG_TEST(PCB_FLAG_FOUND, hole)) continue; + linelist_foreach(&(ly)->Polygon, &itp, poly) { + if (PCB_FLAG_TEST(PCB_FLAG_FOUND, poly)) continue; + if (rnd_polyarea_touching(hole->Clipped, poly->Clipped)) { + rnd_cardinal_t n; + poly->clip_dirty = 1; + /* add hole points to the permanent list */ + pcb_poly_hole_new(poly); + for(n = 0; n < hole->PointN; n++) + pcb_poly_point_new(poly, hole->Points[n].X, hole->Points[n].Y); + } + } + pcb_polyop_destroy(NULL, ly, hole); + } + } + return 0; +} + + +int io_eagle_read_pcb_xml(pcb_plug_io_t *ctx, pcb_board_t *pcb, const char *Filename, rnd_conf_role_t settings_dest) +{ + int pp_res, res, old_leni; + read_state_t st = {0}; + + static const dispatch_t disp[] = { /* possible children of root */ + {"drawing", eagle_read_drawing}, + {"compatibility", eagle_read_nop}, + {"@text", eagle_read_nop}, + {NULL, NULL} + }; + + /* have not read design rules section yet but need this for rectangle parsing */ + st.ms_width = RND_MIL_TO_COORD(10); /* default minimum feature width */ + + st.parser.calls = &trparse_xml_calls; + + if (st.parser.calls->load(&st.parser, Filename) != 0) + return -1; + + pcb->suppress_warn_missing_font = 1; + + st.pcb = pcb; + st.elem_by_name = 1; + st.default_unit = "mm"; + st_init(&st); + + if (eagle_read_ver(GET_PROP_(&st, st.parser.root, "version")) < 0) { + rnd_message(RND_MSG_ERROR, "Eagle XML version parse error\n"); + goto err; + } + + pcb_data_clip_inhibit_inc(pcb->Data); + eagle_read_design_rules(&st); + old_leni = pcb_create_being_lenient; + pcb_create_being_lenient = 1; + res = eagle_foreach_dispatch(&st, st.parser.calls->children(&st.parser, st.parser.root), disp, NULL, 0); + if (res == 0) { + pcb_undo_freeze_add(); + pcb_data_mirror(pcb->Data, 0, PCB_TXM_COORD | PCB_TXM_ROT, 0, 0); + pcb_undo_unfreeze_add(); + } + pcb_create_being_lenient = old_leni; + pcb_board_normalize(pcb); + pcb_layer_colors_from_conf(pcb, 1); + + pp_res = post_process_thermals(&st); + pcb_data_clip_inhibit_dec(pcb->Data, 1); + + + /* need to do the poly hole calculations in a new clip session because + each polygon needs to be clipped already to see if holes affect them */ + pcb_data_clip_inhibit_inc(pcb->Data); + pp_res |= post_process_polyholes(&st); + pcb_data_clip_inhibit_dec(pcb->Data, 1); + + st_uninit(&st); + return pp_res; + +err:; + st_uninit(&st); + rnd_message(RND_MSG_ERROR, "Eagle XML parsing error.\n"); + return -1; +} + +int io_eagle_read_pcb_bin(pcb_plug_io_t *ctx, pcb_board_t *pcb, const char *Filename, rnd_conf_role_t settings_dest) +{ + int pp_res, res, old_leni; + read_state_t st = {0}; + + static const dispatch_t disp_1[] = { /* possible children of root */ + {"drawing", eagle_read_nop}, + {"layers", eagle_read_layers}, /* trying this */ + {NULL, NULL} + }; + + + static const dispatch_t disp_2[] = { /* possible children of root */ + {"drawing", eagle_read_drawing}, + {"layers", eagle_read_nop}, + {NULL, NULL} + }; + + st.parser.calls = &trparse_bin_calls; + + if (st.parser.calls->load(&st.parser, Filename) != 0) { + printf("parser error\n"); + return -1; + } + + pcb->suppress_warn_missing_font = 1; + + st.pcb = pcb; + st.elem_by_name = 0; + st.default_unit = "du"; /* du = decimicron = 0.1 micron unit for eagle bin format */ + st_init(&st); + + pcb_data_clip_inhibit_inc(st.pcb->Data); + eagle_read_design_rules(&st); + + old_leni = pcb_create_being_lenient; + pcb_create_being_lenient = 1; + res = eagle_foreach_dispatch(&st, st.parser.calls->children(&st.parser, st.parser.root), disp_1, NULL, 0); + res |= eagle_foreach_dispatch(&st, st.parser.calls->children(&st.parser, st.parser.root), disp_2, NULL, 0); + if (res == 0) { + pcb_undo_freeze_add(); + pcb_data_mirror(pcb->Data, 0, PCB_TXM_COORD | PCB_TXM_ROT, 0, 0); + pcb_undo_unfreeze_add(); + } + pcb_create_being_lenient = old_leni; + pcb_board_normalize(pcb); + pcb_layer_colors_from_conf(pcb, 1); + + pp_res = post_process_thermals(&st); + pcb_data_clip_inhibit_dec(st.pcb->Data, 1); + st_uninit(&st); + return pp_res; +} + Index: tags/2.3.0/src_plugins/io_eagle/read.h =================================================================== --- tags/2.3.0/src_plugins/io_eagle/read.h (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/read.h (revision 33253) @@ -0,0 +1,10 @@ +#include "board.h" +#include +#include "plug_io.h" + +int io_eagle_test_parse_xml(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); +int io_eagle_read_pcb_xml(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest); + +int io_eagle_test_parse_bin(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); +int io_eagle_read_pcb_bin(pcb_plug_io_t *ctx, pcb_board_t *pcb, const char *Filename, rnd_conf_role_t settings_dest); + Index: tags/2.3.0/src_plugins/io_eagle/read_dru.c =================================================================== --- tags/2.3.0/src_plugins/io_eagle/read_dru.c (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/read_dru.c (revision 33253) @@ -0,0 +1,235 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include +#include +#include +#include +#include + +#include "read_dru.h" +#include "conf_core.h" + +int pcb_eagle_dru_test_parse(FILE *f) +{ + char buff[256], *s; + rewind(f); + s = fgets(buff, sizeof(buff)-1, f); + rewind(f); + buff[sizeof(buff)-1] = '\0'; + + if (s == NULL) + return 0; + + /* first line is a description */ + if (strncmp(s, "description", 11) != 0) + return 0; + s += 11; + + /* it may contain a [lang] suffix */ + if (*s == '[') { + s = strchr(s, ']'); + if (s == NULL) + return 0; + s++; + } + + /* there may be whitespace */ + while(isspace(*s)) s++; + + /* and the key/value separator is an '=' */ + if (*s != '=') + return 0; + + return 1; +} + +/* eat up whitespace after the '=' */ +static void eat_up_ws(FILE *f) +{ + for(;;) { + int c = fgetc(f); + if (c == EOF) + return; + if (!isspace(c)) { + ungetc(c, f); + return; + } + } +} + +void pcb_eagle_dru_parse_line(FILE *f, gds_t *buff, char **key, char **value) +{ + long n, keyo = -1, valo = -1; + gds_truncate(buff, 0); + *key = NULL; + *value = NULL; + for(;;) { + int c = fgetc(f); + if (c == EOF) + break; + if ((c == '\r') || (c == '\n')) { + if (buff->used == 0) /* ignore leading newlines */ + continue; + break; + } + if (isspace(c) && (keyo < 0)) /* ignore leading spaces */ + continue; + + /* have key, don't have val, found sep */ + if ((keyo >= 0) && (valo < 0) && (c == '=')) { + for(n = buff->used-1; n >= 0; n--) { + if (!isspace(buff->array[n])) + break; + buff->array[n] = '\0'; + } + gds_append(buff, '\0'); + valo = buff->used; + eat_up_ws(f); + } + else + gds_append(buff, c); + + /* set key offset */ + if (keyo < 0) + keyo = 0; + } + + gds_append(buff, '\0'); + + if (keyo >= 0) + *key = buff->array + keyo; + if (valo >= 0) + *value = buff->array + valo; +} + + +#ifndef PCB_EAGLE_DRU_PARSER_TEST + +#include +#include "board.h" +#include "layer_grp.h" +#include + +int io_eagle_test_parse_dru(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f) +{ + if (typ != PCB_IOT_PCB) + return 0; /* support only boards because DRU can be loaded onto a board only */ + return pcb_eagle_dru_test_parse(f); +} + +static void bump_up_str(const char *key, const char *val, const char *cpath, rnd_coord_t curr_val) +{ + rnd_bool succ; + double d; + + d = rnd_get_value(val, NULL, NULL, &succ); + if (!succ) { + rnd_message(RND_MSG_ERROR, "Invalid coord value for key %s: '%s'\n", key, val); + return; + } + if (d > curr_val) + rnd_conf_set(RND_CFR_DESIGN, "design/min_drill", -1, val, RND_POL_OVERWRITE); +} + +int io_eagle_read_pcb_dru(pcb_plug_io_t *ctx, pcb_board_t *pcb, const char *Filename, rnd_conf_role_t settings_dest) +{ + FILE *f; + char *efn; + gds_t buff; + rnd_layergrp_id_t gid; + int n, num_layers = 0; + static const char prefix[] = "io_eagle::dru::"; + char tmp[256]; + + f = rnd_fopen_fn(&PCB->hidlib, Filename, "r", &efn); + if (f == NULL) + return -1; + + rnd_conf_set(RND_CFR_DESIGN, "design/bloat", -1, "0", RND_POL_OVERWRITE); + rnd_conf_set(RND_CFR_DESIGN, "design/min_wid", -1, "0", RND_POL_OVERWRITE); + rnd_conf_set(RND_CFR_DESIGN, "design/min_drill", -1, "0", RND_POL_OVERWRITE); + + memcpy(tmp, prefix, sizeof(prefix)); + + gds_init(&buff); + while(!(feof(f))) { + char *k, *v; + pcb_eagle_dru_parse_line(f, &buff, &k, &v); + if (k == NULL) + continue; + if (strcmp(k, "layerSetup") == 0) { + v = strchr(v, '*'); + if (v != NULL) { + v++; + num_layers = atoi(v); + } + } + else if (strcmp(k, "mdWireWire") == 0) + bump_up_str(k, v, "design/bloat", conf_core.design.bloat); + else if (strcmp(k, "mdWirePad") == 0) + bump_up_str(k, v, "design/bloat", conf_core.design.bloat); + else if (strcmp(k, "mdWireVia") == 0) + bump_up_str(k, v, "design/bloat", conf_core.design.bloat); + else if (strcmp(k, "mdPadPad") == 0) + bump_up_str(k, v, "design/bloat", conf_core.design.bloat); + else if (strcmp(k, "mdPadVia") == 0) + bump_up_str(k, v, "design/bloat", conf_core.design.bloat); + else if (strcmp(k, "msWidth") == 0) + bump_up_str(k, v, "design/min_wid", conf_core.design.min_wid); + else if (strcmp(k, "msDrill") == 0) + bump_up_str(k, v, "design/min_drill", conf_core.design.min_drill); + else { + int len = strlen(k); + if (len < sizeof(tmp) - sizeof(prefix)) { + memcpy(tmp + sizeof(prefix) - 1, k, len+1); + pcb_attribute_put(&pcb->Attributes, tmp, v); + } + } + } + + /* set up layers */ + pcb_layer_group_setup_default(pcb); + if (pcb_layergrp_list(pcb, PCB_LYT_COPPER | PCB_LYT_TOP, &gid, 1)) + pcb_layer_create(pcb, gid, "top_copper", 0); + if (pcb_layergrp_list(pcb, PCB_LYT_COPPER | PCB_LYT_BOTTOM, &gid, 1)) + pcb_layer_create(pcb, gid, "bottom_copper", 0); + num_layers--; + for(n = 0; n < num_layers; n++) { + pcb_layergrp_t *grp = pcb_get_grp_new_intern(pcb, -1); + sprintf(tmp, "signal_%d", n); + pcb_layer_create(pcb, grp - pcb->LayerGroups.grp, tmp, 0); + } + pcb_layer_group_setup_silks(pcb); + + fclose(f); + return 0; +} + + +#endif Index: tags/2.3.0/src_plugins/io_eagle/read_dru.h =================================================================== --- tags/2.3.0/src_plugins/io_eagle/read_dru.h (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/read_dru.h (revision 33253) @@ -0,0 +1,23 @@ +#ifndef PCB_IO_EAGLE_READ_DRU_H +#define PCB_IO_EAGLE_READ_DRU_H + +#include +#include + +#ifndef PCB_EAGLE_DRU_PARSER_TEST +#include "plug_io.h" +int io_eagle_test_parse_dru(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); +int io_eagle_read_pcb_dru(pcb_plug_io_t *ctx, pcb_board_t *pcb, const char *Filename, rnd_conf_role_t settings_dest); +#endif + +/*** low level ***/ + +/* Read the first bytes of a file (and rewind) to determine if the file is + an eagle dru file; returns 1 if it is, 0 if not. */ +int pcb_eagle_dru_test_parse(FILE *f); + +/* Load the next item from the dru and set key and value to point to the + corresponding fields within the buff (or NULL if not present). */ +void pcb_eagle_dru_parse_line(FILE *f, gds_t *buff, char **key, char **value); + +#endif Index: tags/2.3.0/src_plugins/io_eagle/trparse.h =================================================================== --- tags/2.3.0/src_plugins/io_eagle/trparse.h (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/trparse.h (revision 33253) @@ -0,0 +1,33 @@ +#ifndef PCB_TRPARSE_H +#define PCB_TRPARSE_H + +typedef void trnode_t; +typedef struct trparse_s trparse_t; + +typedef struct trparse_calls_s { + int (*load)(trparse_t *pst, const char *fn); + int (*unload)(trparse_t *pst); + + trnode_t *(*parent)(trparse_t *pst, trnode_t *node); + trnode_t *(*children)(trparse_t *pst, trnode_t *node); + trnode_t *(*next)(trparse_t *pst, trnode_t *node); + + const char *(*nodename)(trnode_t *node); + const char *(*prop)(trparse_t *pst, trnode_t *node, const char *key); + const char *(*text)(trparse_t *pst, trnode_t *node); + + int (*str_cmp)(const char *s1, const char *s2); + int (*is_text)(trparse_t *pst, trnode_t *node); + + void *(*get_user_data)(trnode_t *node); + void (*set_user_data)(trnode_t *node, void *data); +} trparse_calls_t; + + +struct trparse_s { + void *doc; + trnode_t *root; + const trparse_calls_t *calls; +}; + +#endif Index: tags/2.3.0/src_plugins/io_eagle/trparse_bin.c =================================================================== --- tags/2.3.0/src_plugins/io_eagle/trparse_bin.c (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/trparse_bin.c (revision 33253) @@ -0,0 +1,148 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include "egb_tree.h" +#include "eagle_bin.h" + +#include "trparse.h" +#include "trparse_bin.h" + +static int eagle_bin_load(trparse_t *pst, const char *fn) +{ + egb_node_t *root; + FILE *f; + int res; + + f = rnd_fopen(NULL, fn, "rb"); + if (f == NULL) + return -1; + + res = pcb_egle_bin_load(NULL, f, fn, &root); + + fclose(f); + +/* + printf("@@@ eagle_bin_tree @@@\n"); + egb_dump(stdout, root); +*/ + + if (res != 0) { + printf("FAILED TO LOAD: %d\n", res); + return -1; + } + + pst->doc = NULL; + pst->root = root; + + return 0; +} + +static int eagle_bin_unload(trparse_t *pst) +{ + egb_node_free(pst->root); + pst->root = NULL; + return 0; +} + +static trnode_t *eagle_bin_parent(trparse_t *pst, trnode_t *node) +{ + egb_node_t *nd = (egb_node_t *)node; + return (trnode_t *)nd->parent; +} + +static trnode_t *eagle_bin_children(trparse_t *pst, trnode_t *node) +{ + egb_node_t *nd = (egb_node_t *)node; + return (trnode_t *)nd->first_child; +} + +static trnode_t *eagle_bin_next(trparse_t *pst, trnode_t *node) +{ + egb_node_t *nd = (egb_node_t *)node; + return (trnode_t *)nd->next; +} + +const char *eagle_bin_nodename(trnode_t *node) +{ + egb_node_t *nd = (egb_node_t *)node; + return (const char *)nd->id_name; +} + +static const char *eagle_bin_prop(trparse_t *pst, trnode_t *node, const char *key) +{ + egb_node_t *nd = (egb_node_t *)node; + return egb_node_prop_get(nd, key); +} + +static const char *eagle_bin_text(trparse_t *pst, trnode_t *node) +{ + /*egb_node_t *nd = (egb_node_t *)node;*/ +TODO("TODO") + return NULL; +} + +static int eagle_bin_is_text(trparse_t *pst, trnode_t *node) +{ +TODO("TODO") + return 0; +} + +static void *eagle_bin_get_user_data(trnode_t *node) +{ + egb_node_t *nd = (egb_node_t *)node; + return nd->user_data; +} + +static void eagle_bin_set_user_data(trnode_t *node, void *data) +{ + egb_node_t *nd = (egb_node_t *)node; + nd->user_data = data; +} + + +trparse_calls_t trparse_bin_calls = { + eagle_bin_load, + eagle_bin_unload, + eagle_bin_parent, + eagle_bin_children, + eagle_bin_next, + eagle_bin_nodename, + eagle_bin_prop, + eagle_bin_text, + strcmp, + eagle_bin_is_text, + eagle_bin_get_user_data, + eagle_bin_set_user_data +}; Index: tags/2.3.0/src_plugins/io_eagle/trparse_bin.h =================================================================== --- tags/2.3.0/src_plugins/io_eagle/trparse_bin.h (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/trparse_bin.h (revision 33253) @@ -0,0 +1,7 @@ +#ifndef PCB_TRPARSE_BIN_H +#define PCB_TRPARSE_BIN_H + +#include "trparse.h" +extern trparse_calls_t trparse_bin_calls; + +#endif Index: tags/2.3.0/src_plugins/io_eagle/trparse_xml.c =================================================================== --- tags/2.3.0/src_plugins/io_eagle/trparse_xml.c (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/trparse_xml.c (revision 33253) @@ -0,0 +1,154 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include + +#include "trparse.h" +#include "trparse_xml.h" + +static int eagle_xml_load(trparse_t *pst, const char *fn) +{ + xmlDoc *doc; + xmlNode *root; + FILE *f; + char *efn; + + f = rnd_fopen_fn(NULL, fn, "r", &efn); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "can't open '%s'\n", fn); + return -1; + } + fclose(f); + + doc = xmlReadFile(efn, NULL, 0); + if (doc == NULL) { + rnd_message(RND_MSG_ERROR, "xml parsing error on file %s (%s)\n", fn, efn); + free(efn); + return -1; + } + free(efn); + + root = xmlDocGetRootElement(doc); + if (xmlStrcmp(root->name, (xmlChar *)"eagle") != 0) { + rnd_message(RND_MSG_ERROR, "xml error: root is not \n"); + xmlFreeDoc(doc); + return -1; + } + + pst->doc = doc; + pst->root = root; + + return 0; +} + +static int eagle_xml_unload(trparse_t *pst) +{ + xmlFreeDoc((xmlDoc *)pst->doc); + return 0; +} + +static trnode_t *eagle_xml_children(trparse_t *pst, trnode_t *node) +{ + xmlNode *nd = (xmlNode *)node; + return (trnode_t *)nd->children; +} + +static trnode_t *eagle_xml_parent(trparse_t *pst, trnode_t *node) +{ + xmlNode *nd = (xmlNode *)node; + return (trnode_t *)nd->parent; +} + +static trnode_t *eagle_xml_next(trparse_t *pst, trnode_t *node) +{ + xmlNode *nd = (xmlNode *)node; + return (trnode_t *)nd->next; +} + +const char *eagle_xml_nodename(trnode_t *node) +{ + xmlNode *nd = (xmlNode *)node; + return (const char *)nd->name; +} + +static const char *eagle_xml_prop(trparse_t *pst, trnode_t *node, const char *key) +{ + xmlNode *nd = (xmlNode *)node; + return (const char *)xmlGetProp(nd, (const xmlChar *)key); +} + +static const char *eagle_xml_text(trparse_t *pst, trnode_t *node) +{ + xmlNode *nd = (xmlNode *)node; + return (const char *)nd->content; +} + +static int eagle_xml_strcmp(const char *s1, const char *s2) +{ + return xmlStrcmp((const xmlChar *)s1, (const xmlChar *)s2); +} + +static int eagle_xml_is_text(trparse_t *pst, trnode_t *node) +{ + return ((xmlNode *)node)->type == XML_TEXT_NODE; +} + +static void *eagle_xml_get_user_data(trnode_t *node) +{ + xmlNode *nd = (xmlNode *)node; + return nd->_private; +} + +static void eagle_xml_set_user_data(trnode_t *node, void *data) +{ + xmlNode *nd = (xmlNode *)node; + nd->_private = data; +} + + +trparse_calls_t trparse_xml_calls = { + eagle_xml_load, + eagle_xml_unload, + eagle_xml_parent, + eagle_xml_children, + eagle_xml_next, + eagle_xml_nodename, + eagle_xml_prop, + eagle_xml_text, + eagle_xml_strcmp, + eagle_xml_is_text, + eagle_xml_get_user_data, + eagle_xml_set_user_data +}; Index: tags/2.3.0/src_plugins/io_eagle/trparse_xml.h =================================================================== --- tags/2.3.0/src_plugins/io_eagle/trparse_xml.h (nonexistent) +++ tags/2.3.0/src_plugins/io_eagle/trparse_xml.h (revision 33253) @@ -0,0 +1,7 @@ +#ifndef PCB_TRPARSE_XML_H +#define PCB_TRPARSE_XML_H + +#include "trparse.h" +extern trparse_calls_t trparse_xml_calls; + +#endif Index: tags/2.3.0/src_plugins/io_hyp/Makefile =================================================================== --- tags/2.3.0/src_plugins/io_hyp/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/Makefile (revision 33253) @@ -0,0 +1,10 @@ +all: + cd ../../src && $(MAKE) mod_io_hyp + +hyp_l.o: hyp_y.h + +parser.o: hyp_l.h hyp_y.h + +clean: + rm *.o *.so hyp_l.c hyp_l.h hyp_y.c hyp_y.h 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/io_hyp/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/io_hyp/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/Plug.tmpasm (revision 33253) @@ -0,0 +1,21 @@ +put /local/pcb/mod {io_hyp} +put /local/pcb/mod/MENUFILE {hyp-menu.lht} +put /local/pcb/mod/MENUVAR {hyp_menu} + +append /local/pcb/mod/OBJS [@ + $(PLUGDIR)/io_hyp/io_hyp.o + $(PLUGDIR)/io_hyp/hyp_l.o + $(PLUGDIR)/io_hyp/hyp_y.o + $(PLUGDIR)/io_hyp/parser.o + $(PLUGDIR)/io_hyp/write.o +@] + +put /local/pcb/mod/YACC {$(PLUGDIR)/io_hyp/hyp_y} +put /local/pcb/mod/LEX {$(PLUGDIR)/io_hyp/hyp_l} + + +switch /local/pcb/io_hyp/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/io_hyp/hacking.txt =================================================================== --- tags/2.3.0/src_plugins/io_hyp/hacking.txt (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/hacking.txt (revision 33253) @@ -0,0 +1,21 @@ +The hyperlynx file is read using a bison/flex scanner. The flex scanner +is in hyp_l, the bison parser in hyp_y.y. For each hyperlynx construct +the parser calls the corresponding exec_* routine in parser.c. Example: +if the parser encounters an arc segment, the symbol in the scanner/parser +is H_ARC, and the routine in parser.c is called exec_arc(). + +If you need a rough description of the hyperlynx format, download +"bird33" from http://www.ibis.org/birds/bird33.txt . Substitute ".IBP +file format" with ".HYP file format" and "SUBSTRATE_OUTLINE" with "BOARD" +and you have an (old) description of the hyperlynx format. + +Not all CAD programs create compliant .hyp files. The most common +omission is not putting quotes around a string. This causes problems if +the string contains blank space or commas. + +If you change scanner or parser you need to revalidate. Try loading a +collection of hyperlynx files generated by diverse CAD programs. + +The python script "gensamp" creates a sample hyperlynx file which +contains line, arc and unrouted segments, polygons with and without +holes, polylines, etc. Index: tags/2.3.0/src_plugins/io_hyp/hyp-menu.lht =================================================================== --- tags/2.3.0/src_plugins/io_hyp/hyp-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/hyp-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_geo { + li:submenu { + ha:Load Hyperlynx .hyp file = { action=LoadHypFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/io_hyp/hyp_l.c =================================================================== --- tags/2.3.0/src_plugins/io_hyp/hyp_l.c (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/hyp_l.c (revision 33253) @@ -0,0 +1,4768 @@ +#line 2 "hyp_l.c" + +#line 4 "hyp_l.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +/* %not-for-header */ +/* %if-c-only */ +/* %if-not-reentrant */ +#define yy_create_buffer hyy_create_buffer +#define yy_delete_buffer hyy_delete_buffer +#define yy_scan_buffer hyy_scan_buffer +#define yy_scan_string hyy_scan_string +#define yy_scan_bytes hyy_scan_bytes +#define yy_init_buffer hyy_init_buffer +#define yy_flush_buffer hyy_flush_buffer +#define yy_load_buffer_state hyy_load_buffer_state +#define yy_switch_to_buffer hyy_switch_to_buffer +#define yypush_buffer_state hyypush_buffer_state +#define yypop_buffer_state hyypop_buffer_state +#define yyensure_buffer_stack hyyensure_buffer_stack +#define yy_flex_debug hyy_flex_debug +#define yyin hyyin +#define yyleng hyyleng +#define yylex hyylex +#define yylineno hyylineno +#define yyout hyyout +#define yyrestart hyyrestart +#define yytext hyytext +#define yywrap hyywrap +#define yyalloc hyyalloc +#define yyrealloc hyyrealloc +#define yyfree hyyfree + +/* %endif */ +/* %endif */ +/* %ok-for-header */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* %if-c++-only */ +/* %endif */ + +/* %if-c-only */ +#ifdef yy_create_buffer +#define hyy_create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer hyy_create_buffer +#endif + +#ifdef yy_delete_buffer +#define hyy_delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer hyy_delete_buffer +#endif + +#ifdef yy_scan_buffer +#define hyy_scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer hyy_scan_buffer +#endif + +#ifdef yy_scan_string +#define hyy_scan_string_ALREADY_DEFINED +#else +#define yy_scan_string hyy_scan_string +#endif + +#ifdef yy_scan_bytes +#define hyy_scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes hyy_scan_bytes +#endif + +#ifdef yy_init_buffer +#define hyy_init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer hyy_init_buffer +#endif + +#ifdef yy_flush_buffer +#define hyy_flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer hyy_flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define hyy_load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state hyy_load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define hyy_switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer hyy_switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define hyypush_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state hyypush_buffer_state +#endif + +#ifdef yypop_buffer_state +#define hyypop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state hyypop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define hyyensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack hyyensure_buffer_stack +#endif + +#ifdef yylex +#define hyylex_ALREADY_DEFINED +#else +#define yylex hyylex +#endif + +#ifdef yyrestart +#define hyyrestart_ALREADY_DEFINED +#else +#define yyrestart hyyrestart +#endif + +#ifdef yylex_init +#define hyylex_init_ALREADY_DEFINED +#else +#define yylex_init hyylex_init +#endif + +#ifdef yylex_init_extra +#define hyylex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra hyylex_init_extra +#endif + +#ifdef yylex_destroy +#define hyylex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy hyylex_destroy +#endif + +#ifdef yyget_debug +#define hyyget_debug_ALREADY_DEFINED +#else +#define yyget_debug hyyget_debug +#endif + +#ifdef yyset_debug +#define hyyset_debug_ALREADY_DEFINED +#else +#define yyset_debug hyyset_debug +#endif + +#ifdef yyget_extra +#define hyyget_extra_ALREADY_DEFINED +#else +#define yyget_extra hyyget_extra +#endif + +#ifdef yyset_extra +#define hyyset_extra_ALREADY_DEFINED +#else +#define yyset_extra hyyset_extra +#endif + +#ifdef yyget_in +#define hyyget_in_ALREADY_DEFINED +#else +#define yyget_in hyyget_in +#endif + +#ifdef yyset_in +#define hyyset_in_ALREADY_DEFINED +#else +#define yyset_in hyyset_in +#endif + +#ifdef yyget_out +#define hyyget_out_ALREADY_DEFINED +#else +#define yyget_out hyyget_out +#endif + +#ifdef yyset_out +#define hyyset_out_ALREADY_DEFINED +#else +#define yyset_out hyyset_out +#endif + +#ifdef yyget_leng +#define hyyget_leng_ALREADY_DEFINED +#else +#define yyget_leng hyyget_leng +#endif + +#ifdef yyget_text +#define hyyget_text_ALREADY_DEFINED +#else +#define yyget_text hyyget_text +#endif + +#ifdef yyget_lineno +#define hyyget_lineno_ALREADY_DEFINED +#else +#define yyget_lineno hyyget_lineno +#endif + +#ifdef yyset_lineno +#define hyyset_lineno_ALREADY_DEFINED +#else +#define yyset_lineno hyyset_lineno +#endif + +#ifdef yywrap +#define hyywrap_ALREADY_DEFINED +#else +#define yywrap hyywrap +#endif + +/* %endif */ + +#ifdef yyalloc +#define hyyalloc_ALREADY_DEFINED +#else +#define yyalloc hyyalloc +#endif + +#ifdef yyrealloc +#define hyyrealloc_ALREADY_DEFINED +#else +#define yyrealloc hyyrealloc +#endif + +#ifdef yyfree +#define hyyfree_ALREADY_DEFINED +#else +#define yyfree hyyfree +#endif + +/* %if-c-only */ + +#ifdef yytext +#define hyytext_ALREADY_DEFINED +#else +#define yytext hyytext +#endif + +#ifdef yyleng +#define hyyleng_ALREADY_DEFINED +#else +#define yyleng hyyleng +#endif + +#ifdef yyin +#define hyyin_ALREADY_DEFINED +#else +#define yyin hyyin +#endif + +#ifdef yyout +#define hyyout_ALREADY_DEFINED +#else +#define yyout hyyout +#endif + +#ifdef yy_flex_debug +#define hyy_flex_debug_ALREADY_DEFINED +#else +#define yy_flex_debug hyy_flex_debug +#endif + +#ifdef yylineno +#define hyylineno_ALREADY_DEFINED +#else +#define yylineno hyylineno +#endif + +/* %endif */ + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +/* %if-c-only */ +#include +#include +#include +#include +/* %endif */ + +/* %if-tables-serialization */ +/* %endif */ +/* end standard C headers. */ + +/* %if-c-or-c++ */ +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* %endif */ + +/* begin standard C++ headers. */ +/* %if-c++-only */ +/* %endif */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* %not-for-header */ +/* Returned upon end-of-file. */ +#define YY_NULL 0 +/* %ok-for-header */ + +/* %not-for-header */ +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) +/* %ok-for-header */ + +/* %if-reentrant */ +/* %endif */ + +/* %if-not-reentrant */ + +/* %endif */ + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +/* %if-not-reentrant */ +extern int yyleng; +/* %endif */ + +/* %if-c-only */ +/* %if-not-reentrant */ +extern FILE *yyin, *yyout; +/* %endif */ +/* %endif */ + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + #define YY_LINENO_REWIND_TO(dst) \ + do {\ + const char *p;\ + for ( p = yy_cp-1; p >= (dst); --p)\ + if ( *p == '\n' )\ + --yylineno;\ + }while(0) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { +/* %if-c-only */ + FILE *yy_input_file; +/* %endif */ + +/* %if-c++-only */ +/* %endif */ + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* %if-c-only Standard (non-C++) definition */ +/* %not-for-header */ +/* %if-not-reentrant */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ +/* %endif */ +/* %ok-for-header */ + +/* %endif */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* %if-c-only Standard (non-C++) definition */ + +/* %if-not-reentrant */ +/* %not-for-header */ +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; +/* %ok-for-header */ + +/* %endif */ + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +/* %endif */ + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */ +/* Begin user sect3 */ + +#define hyywrap() (/*CONSTCOND*/1) +#define YY_SKIP_YYWRAP + +#define FLEX_DEBUG +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +/* %% [1.5] DFA */ + +/* %if-c-only Standard (non-C++) definition */ + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* %endif */ + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ +/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ +/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\ + (yy_c_buf_p) = yy_cp; +/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */ +#define YY_NUM_RULES 138 +#define YY_END_OF_BUFFER 139 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_acclist[861] = + { 0, + 1, 1, 139, 135, 137, 138, 4, 137, 138, 5, + 138, 5, 137, 138, 137, 138, 131, 137, 138, 132, + 137, 138, 135, 137, 138, 133, 135, 137, 138, 135, + 137, 138, 108, 135, 137, 138, 134, 137, 138, 20, + 135, 137, 138, 135, 137, 138, 135, 137, 138, 135, + 137, 138, 135, 137, 138, 135, 137, 138, 135, 137, + 138, 135, 137, 138, 135, 137, 138, 30, 135, 137, + 138, 31, 135, 137, 138, 135, 137, 138, 135, 137, + 138, 135, 137, 138, 42, 135, 137, 138, 43, 135, + 137, 138, 135, 137, 138, 135, 137, 138, 135, 137, + + 138, 135, 137, 138, 135, 137, 138, 135, 137, 138, + 135, 137, 138, 135, 137, 138, 129, 137, 138, 130, + 137, 138, 135, 137, 138, 128, 135, 137, 138, 4, + 137, 138, 4, 128, 137, 138, 127, 132, 137, 138, + 128, 133, 135, 137, 138, 127, 130, 137, 138, 128, + 135, 137, 138, 126, 135, 137, 138, 135, 137, 138, + 135, 137, 138, 125, 135, 137, 138, 1, 135, 137, + 138, 1, 4, 137, 138, 1, 5, 138, 1, 5, + 137, 138, 1, 137, 138, 1, 131, 137, 138, 1, + 132, 137, 138, 1, 133, 135, 137, 138, 1, 134, + + 137, 138, 1, 129, 137, 138, 1, 135, 137, 138, + 135, 137, 138, 4, 137, 138, 2, 5, 138, 2, + 5, 137, 138, 137, 138, 131, 137, 138, 132, 137, + 138, 133, 135, 137, 138, 134, 137, 138, 129, 137, + 138, 130, 137, 138, 135, 137, 138, 135, 4, 5, + 136, 135, 108, 135, 108, 135, 108, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 53, 135, 135, + 135, 57, 135, 135, 135, 60, 135, 135, 135, 135, + 135, 62, 135, 135, 135, 135, 64, 135, 135, 135, + + 135, 69, 135, 70, 135, 135, 107, 135, 135, 72, + 135, 135, 135, 135, 135, 135, 135, 135, 76, 135, + 135, 135, 78, 135, 135, 135, 135, 135, 135, 87, + 135, 135, 135, 90, 135, 135, 135, 135, 93, 135, + 135, 135, 94, 135, 135, 135, 98, 135, 135, 102, + 135, 135, 135, 135, 3, 128, 135, 128, 128, 4, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 135, + 128, 126, 135, 135, 125, 135, 125, 135, 125, 135, + 135, 1, 135, 1, 1, 4, 1, 5, 1, 1, + + 136, 1, 1, 135, 1, 1, 3, 135, 2, 4, + 2, 5, 2, 136, 135, 2, 3, 135, 108, 135, + 111, 135, 108, 135, 135, 121, 135, 114, 135, 116, + 135, 115, 135, 119, 135, 112, 120, 135, 113, 135, + 118, 135, 109, 135, 110, 135, 122, 135, 117, 135, + 120, 135, 124, 135, 123, 135, 54, 55, 21, 135, + 135, 56, 58, 135, 135, 135, 135, 135, 135, 135, + 18, 135, 135, 61, 63, 19, 135, 65, 66, 135, + 135, 135, 68, 135, 135, 16, 135, 135, 33, 135, + 135, 36, 135, 135, 135, 135, 135, 135, 75, 135, + + 81, 135, 135, 84, 135, 135, 44, 135, 135, 135, + 135, 135, 79, 80, 88, 135, 135, 91, 135, 135, + 51, 135, 135, 95, 96, 97, 99, 100, 101, 106, + 135, 103, 135, 105, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 127, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 125, 135, 135, 125, 135, 1, 135, 135, 135, + 135, 59, 135, 135, 135, 135, 135, 135, 135, 135, + + 28, 135, 67, 135, 135, 135, 135, 135, 135, 73, + 135, 135, 41, 135, 74, 77, 82, 83, 85, 86, + 135, 135, 135, 135, 135, 135, 50, 135, 135, 92, + 135, 135, 135, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 11, 135, 135, 23, 135, 135, 135, 135, 135, 135, + 135, 135, 71, 135, 135, 135, 135, 37, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 9, + 135, 135, 135, 135, 104, 128, 128, 128, 128, 128, + + 128, 128, 135, 22, 135, 135, 135, 135, 135, 135, + 27, 135, 29, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 45, 135, 135, 135, 48, 135, 135, 135, + 135, 135, 135, 52, 135, 128, 128, 128, 135, 135, + 135, 13, 135, 135, 26, 135, 135, 32, 135, 135, + 135, 135, 38, 135, 135, 135, 135, 135, 49, 135, + 12, 135, 135, 135, 7, 135, 128, 128, 128, 135, + 135, 24, 135, 135, 135, 15, 135, 135, 135, 39, + 135, 40, 135, 135, 47, 135, 14, 135, 135, 128, + 128, 128, 135, 8, 135, 135, 17, 135, 135, 10, + + 135, 135, 135, 128, 128, 128, 6, 135, 25, 135, + 135, 46, 135, 135, 128, 128, 128, 135, 135, 135, + 128, 128, 128, 135, 135, 135, 128, 128, 128, 34, + 135, 135, 135, 128, 128, 128, 135, 135, 128, 128, + 128, 135, 135, 128, 128, 128, 135, 135, 128, 128, + 128, 35, 135, 135, 128, 128, 128, 89, 128, 128 + } ; + +static const flex_int16_t yy_accept[771] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 3, 3, 3, 4, 7, 10, 12, 15, 17, 20, + 23, 26, 30, 33, 37, 40, 44, 47, 50, 53, + 56, 59, 62, 65, 68, 72, 76, 79, 82, 85, + 89, 93, 96, 99, 102, 105, 108, 111, 114, 117, + 120, 123, 126, 130, 133, 137, 141, 146, 150, 154, + 158, 161, 164, 168, 172, 176, 179, 183, 186, 190, + 194, 199, 203, 207, 211, 214, 217, 220, 224, 226, + 229, 232, 236, 239, 242, 245, 248, 249, 250, 251, + 251, 252, 252, 253, 255, 257, 257, 259, 260, 261, + + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 276, 277, 278, 279, 280, + 281, 282, 282, 283, 284, 285, 286, 286, 287, 288, + 289, 290, 291, 292, 292, 293, 294, 295, 295, 296, + 297, 298, 299, 300, 301, 302, 302, 303, 304, 304, + 305, 306, 307, 309, 310, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 319, 320, 321, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 330, 331, + 332, 333, 334, 334, 335, 336, 337, 338, 339, 339, + 340, 341, 341, 342, 343, 344, 345, 345, 346, 347, + + 348, 349, 350, 350, 351, 352, 353, 354, 355, 355, + 356, 358, 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, + 360, 362, 363, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 379, 381, + 382, 384, 385, 387, 389, 391, 392, 394, 395, 397, + 399, 400, 402, 403, 405, 406, 408, 409, 409, 410, + 411, 413, 413, 414, 415, 415, 416, 416, 418, 419, + 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, + 419, 419, 419, 419, 419, 419, 421, 422, 423, 425, + + 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, + 436, 438, 439, 440, 441, 442, 443, 444, 445, 446, + 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, + 457, 457, 458, 458, 459, 461, 462, 462, 463, 463, + 464, 465, 466, 467, 468, 469, 470, 471, 473, 474, + 474, 475, 475, 476, 478, 478, 479, 479, 480, 481, + 482, 483, 483, 484, 485, 486, 488, 489, 491, 492, + 494, 495, 496, 497, 498, 499, 499, 500, 501, 501, + 502, 503, 504, 504, 505, 506, 507, 509, 510, 511, + 512, 513, 513, 514, 514, 515, 515, 516, 517, 518, + + 518, 519, 520, 521, 523, 524, 524, 525, 525, 526, + 526, 527, 527, 528, 528, 529, 529, 530, 532, 532, + 533, 534, 534, 535, 536, 537, 538, 539, 540, 541, + 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, + 552, 553, 553, 553, 553, 553, 553, 553, 553, 553, + 553, 553, 553, 554, 555, 556, 557, 558, 559, 560, + 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, + 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, + 581, 582, 584, 585, 587, 589, 590, 590, 590, 590, + 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, + + 590, 590, 590, 591, 592, 592, 593, 594, 595, 596, + 597, 598, 599, 600, 601, 603, 603, 604, 605, 606, + 607, 608, 609, 610, 610, 611, 612, 613, 615, 615, + 616, 616, 617, 617, 618, 618, 619, 619, 620, 620, + 621, 622, 623, 624, 625, 626, 627, 629, 630, 630, + 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, + 641, 642, 643, 644, 645, 646, 646, 646, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, + 658, 659, 660, 661, 663, 664, 666, 667, 668, 669, + 670, 671, 672, 673, 673, 674, 675, 676, 677, 678, + + 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, + 690, 692, 693, 694, 695, 695, 696, 697, 698, 699, + 699, 700, 701, 702, 703, 704, 706, 707, 708, 709, + 710, 711, 713, 715, 716, 717, 718, 719, 720, 721, + 722, 723, 725, 726, 727, 729, 730, 731, 732, 733, + 734, 736, 737, 737, 738, 739, 740, 741, 742, 744, + 745, 747, 748, 750, 751, 752, 753, 755, 756, 757, + 758, 759, 761, 763, 764, 765, 767, 768, 768, 769, + 770, 771, 772, 774, 775, 776, 778, 779, 780, 782, + 784, 785, 787, 789, 790, 791, 791, 792, 793, 794, + + 796, 797, 799, 800, 802, 803, 804, 805, 805, 806, + 807, 809, 811, 812, 814, 815, 816, 816, 817, 818, + 819, 820, 821, 822, 822, 823, 824, 825, 826, 827, + 828, 828, 829, 830, 832, 833, 834, 835, 835, 836, + 837, 838, 839, 840, 840, 841, 842, 843, 844, 845, + 845, 846, 847, 848, 849, 850, 850, 851, 852, 854, + 855, 856, 856, 857, 858, 858, 859, 860, 861, 861 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 5, 1, 6, 1, 1, 1, 1, 1, 7, + 8, 9, 10, 11, 10, 12, 1, 13, 14, 15, + 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, + 16, 1, 17, 1, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 27, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 1, 1, 1, 1, 43, 1, 44, 27, 27, 27, + + 45, 46, 27, 27, 27, 27, 47, 27, 48, 49, + 50, 51, 27, 27, 52, 27, 53, 27, 27, 27, + 54, 55, 56, 1, 57, 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 + } ; + +static const YY_CHAR yy_meta[58] = + { 0, + 1, 2, 3, 4, 5, 4, 4, 4, 1, 1, + 1, 1, 6, 6, 6, 7, 1, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 4, 9 + } ; + +static const flex_int16_t yy_base[876] = + { 0, + 0, 1927, 56, 112, 168, 224, 56, 63, 280, 336, + 392, 448, 1935, 0, 77, 77, 80, 1928, 0, 4391, + 73, 0, 76, 505, 4391, 90, 62, 120, 124, 66, + 125, 1912, 1910, 559, 129, 175, 1898, 594, 133, 628, + 142, 67, 183, 190, 239, 246, 218, 1880, 1884, 4391, + 4391, 668, 1923, 724, 766, 4391, 1922, 4391, 820, 94, + 151, 146, 257, 876, 151, 107, 129, 207, 932, 0, + 987, 0, 0, 1042, 1098, 212, 183, 186, 215, 1155, + 199, 1211, 239, 242, 246, 1267, 0, 206, 270, 1920, + 1919, 1916, 262, 0, 280, 1323, 285, 1378, 1421, 1464, + + 1507, 1550, 1593, 1636, 1679, 1722, 1765, 1808, 1851, 291, + 1894, 1937, 1980, 2023, 305, 306, 307, 4391, 1903, 1904, + 311, 312, 4391, 313, 161, 1887, 330, 4391, 1884, 63, + 1897, 309, 346, 348, 4391, 352, 1877, 353, 354, 358, + 4391, 1886, 1885, 1880, 370, 371, 4391, 1878, 375, 4391, + 1883, 1876, 0, 1874, 399, 4391, 1881, 1867, 1869, 1874, + 1879, 167, 1876, 400, 404, 4391, 1869, 405, 420, 422, + 4391, 1867, 124, 1872, 1856, 412, 421, 427, 4391, 428, + 1862, 1865, 429, 4391, 463, 1857, 1851, 1866, 464, 4391, + 1857, 465, 469, 470, 4391, 471, 486, 487, 492, 4391, + + 493, 1847, 560, 4391, 561, 566, 1829, 2065, 286, 316, + 1875, 2122, 310, 1845, 349, 1862, 1843, 1855, 564, 240, + 355, 345, 573, 123, 1840, 395, 426, 587, 461, 2160, + 329, 468, 1840, 574, 1857, 1838, 1850, 603, 247, 570, + 362, 637, 419, 1835, 495, 641, 665, 592, 2201, 2258, + 632, 645, 674, 677, 687, 693, 2314, 0, 377, 415, + 660, 1863, 2370, 2425, 637, 566, 2481, 590, 621, 708, + 631, 712, 717, 724, 2538, 2594, 634, 645, 4391, 383, + 491, 693, 729, 731, 733, 735, 746, 747, 767, 768, + 827, 828, 829, 833, 835, 2651, 837, 830, 840, 2706, + + 844, 2749, 845, 2792, 846, 2835, 854, 2878, 855, 2921, + 856, 2964, 861, 3007, 862, 3050, 863, 3093, 867, 3136, + 868, 3179, 869, 3222, 884, 3265, 885, 3308, 886, 3351, + 891, 4391, 892, 4391, 0, 1833, 893, 4391, 897, 4391, + 898, 1826, 1820, 1839, 1837, 1828, 1821, 0, 1820, 899, + 4391, 914, 4391, 0, 915, 4391, 945, 4391, 1824, 1825, + 949, 950, 4391, 1812, 1823, 1801, 1817, 1807, 1815, 0, + 951, 1809, 1798, 1804, 955, 957, 4391, 967, 980, 4391, + 982, 995, 997, 4391, 999, 1003, 0, 1806, 60, 1816, + 1802, 1004, 4391, 1005, 4391, 1012, 4391, 1798, 881, 1020, + + 4391, 1021, 1798, 0, 1808, 1022, 4391, 1037, 4391, 1049, + 4391, 1050, 4391, 1054, 4391, 1055, 4391, 0, 1059, 4391, + 1800, 1067, 4391, 907, 1057, 1062, 262, 1058, 958, 1102, + 1013, 1092, 1071, 1107, 677, 1080, 1072, 1114, 1126, 1163, + 4391, 1813, 1794, 1798, 1803, 1809, 1801, 1000, 1070, 1794, + 1786, 593, 1108, 1134, 1079, 1127, 1128, 1165, 1168, 1180, + 1171, 1170, 1173, 3393, 3449, 911, 1190, 690, 1209, 1214, + 944, 1176, 1217, 896, 1219, 1186, 1222, 1232, 1794, 1792, + 1225, 1263, 1019, 1067, 0, 925, 976, 1147, 1172, 1178, + 1239, 1251, 1253, 1260, 1261, 1277, 1279, 1284, 1285, 1286, + + 1290, 1291, 3506, 1790, 1295, 4391, 1785, 1784, 1762, 1778, + 1783, 1780, 1775, 1763, 0, 1296, 4391, 1772, 1297, 1777, + 1764, 1759, 1764, 1301, 4391, 1771, 1280, 0, 1305, 4391, + 1314, 4391, 1324, 4391, 1332, 4391, 1333, 4391, 1334, 4391, + 1774, 1762, 1301, 1762, 1760, 1753, 0, 1762, 1339, 4391, + 1755, 1748, 1380, 4391, 1326, 1368, 1370, 1389, 1392, 1394, + 1399, 1402, 1432, 1352, 1436, 1742, 1720, 1731, 1439, 1289, + 1396, 1133, 1468, 1435, 1472, 1475, 1478, 1482, 1405, 1486, + 1514, 1517, 1300, 1716, 1718, 0, 1696, 1689, 1681, 1682, + 1665, 1660, 1658, 1409, 4391, 1644, 1641, 1652, 1646, 1609, + + 1610, 1614, 1603, 1605, 1607, 1595, 1594, 1582, 1581, 1575, + 0, 1570, 1560, 1530, 1451, 4391, 1518, 1498, 1537, 1526, + 1533, 1555, 1529, 1542, 1516, 0, 1503, 1491, 1476, 1474, + 1481, 0, 0, 1462, 1437, 1448, 1427, 1427, 1428, 1416, + 1403, 0, 1405, 1388, 0, 1380, 1373, 1380, 1376, 1335, + 0, 1569, 1337, 1499, 1565, 1336, 1340, 1337, 0, 1318, + 0, 1245, 0, 1233, 1226, 1220, 0, 1204, 1189, 1177, + 1172, 0, 0, 1147, 1110, 0, 1571, 1046, 1595, 1598, + 1006, 1008, 0, 986, 951, 0, 942, 937, 0, 0, + 946, 0, 0, 941, 1604, 915, 1532, 1607, 924, 0, + + 886, 0, 832, 0, 831, 809, 1573, 759, 1638, 1616, + 0, 0, 549, 0, 740, 1639, 724, 1583, 1568, 707, + 717, 671, 1651, 649, 1623, 1650, 647, 638, 602, 1653, + 584, 1655, 1661, 0, 581, 550, 1658, 491, 1681, 1698, + 479, 463, 1699, 327, 1694, 1691, 272, 234, 1703, 200, + 442, 1728, 186, 169, 1704, 149, 1712, 1732, 0, 1455, + 1733, 45, 1740, 1739, 1756, 4391, 1755, 1771, 4391, 3549, + 3558, 3567, 3576, 3585, 3593, 3597, 3605, 3614, 3622, 3631, + 3639, 3647, 3656, 3664, 3673, 3682, 3691, 3700, 3709, 3718, + 3726, 3734, 3742, 3750, 3758, 3766, 3774, 3782, 3790, 3798, + + 3806, 3814, 3822, 3830, 3838, 3846, 3855, 3864, 3873, 3881, + 3889, 3898, 3906, 3915, 3924, 3933, 3942, 3951, 3960, 3969, + 3978, 3986, 3993, 4000, 4007, 4014, 4021, 4028, 4035, 4042, + 4049, 4056, 4063, 4070, 4077, 4084, 4091, 4099, 4107, 4115, + 4123, 4131, 4139, 4147, 4155, 4163, 4171, 4179, 4187, 4195, + 4203, 4211, 4219, 4227, 4235, 4244, 4252, 4260, 4267, 4274, + 4281, 4288, 4295, 4302, 4309, 4316, 4323, 4330, 4337, 4344, + 4351, 4358, 4365, 4373, 4381 + } ; + +static const flex_int16_t yy_def[876] = + { 0, + 769, 1, 770, 770, 771, 771, 6, 6, 772, 772, + 773, 773, 769, 774, 769, 769, 769, 775, 776, 769, + 774, 774, 774, 769, 769, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, 774, 769, + 769, 777, 778, 769, 769, 769, 778, 769, 779, 774, + 774, 774, 774, 780, 781, 781, 781, 782, 783, 781, + 780, 781, 781, 784, 785, 786, 769, 769, 787, 788, + 786, 785, 786, 786, 786, 789, 774, 769, 769, 775, + 769, 776, 774, 24, 24, 769, 24, 790, 791, 792, + + 793, 794, 795, 796, 797, 798, 799, 800, 801, 774, + 802, 803, 804, 805, 769, 774, 774, 769, 774, 774, + 774, 769, 769, 774, 774, 774, 769, 769, 774, 774, + 774, 774, 774, 769, 769, 774, 774, 769, 774, 774, + 769, 774, 774, 774, 774, 769, 769, 774, 769, 769, + 774, 774, 774, 774, 769, 769, 774, 774, 774, 774, + 774, 774, 774, 774, 769, 769, 774, 769, 774, 774, + 769, 774, 774, 774, 774, 774, 774, 769, 769, 774, + 774, 774, 769, 769, 774, 774, 774, 774, 769, 769, + 774, 769, 774, 774, 769, 774, 769, 774, 774, 769, + + 774, 774, 769, 769, 774, 774, 774, 806, 807, 769, + 778, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 212, + 212, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 808, 769, + 774, 774, 774, 774, 774, 774, 809, 810, 810, 810, + 811, 810, 812, 813, 814, 810, 815, 816, 769, 816, + 769, 817, 818, 816, 819, 820, 821, 769, 769, 822, + 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, + 833, 834, 835, 836, 837, 769, 769, 774, 296, 838, + + 769, 839, 769, 840, 769, 841, 769, 842, 769, 843, + 769, 844, 769, 845, 769, 846, 769, 847, 769, 848, + 769, 849, 769, 850, 769, 851, 769, 852, 769, 853, + 769, 769, 769, 769, 774, 774, 769, 769, 769, 769, + 774, 774, 774, 774, 774, 774, 774, 774, 774, 769, + 769, 769, 769, 774, 769, 769, 769, 769, 774, 774, + 774, 769, 769, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 769, 769, 774, 769, 769, + 774, 774, 769, 769, 774, 774, 774, 774, 774, 774, + 774, 769, 769, 769, 769, 769, 769, 774, 774, 769, + + 769, 774, 774, 774, 774, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 774, 769, 769, + 774, 769, 769, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 855, 855, 465, 465, 465, 465, 465, + 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, + 465, 774, 774, 774, 856, 857, 858, 859, 860, 861, + 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, + + 872, 873, 874, 774, 769, 769, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 769, 769, 774, 774, 774, + 774, 774, 774, 769, 769, 774, 774, 774, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 774, 774, 774, 774, 774, 774, 774, 774, 769, 769, + 774, 774, 774, 769, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 769, 769, 769, 854, 854, + 854, 875, 465, 465, 465, 465, 465, 465, 465, 465, + 465, 465, 465, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 769, 769, 774, 774, 774, 774, 774, + + 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 769, 769, 854, 854, 854, 769, + 854, 465, 465, 465, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, + 774, 854, 769, 854, 465, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 774, 774, 854, 769, 854, 465, + 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, + 774, 774, 774, 774, 854, 769, 854, 465, 774, 774, + + 774, 774, 774, 774, 774, 774, 854, 769, 854, 465, + 774, 774, 774, 774, 774, 854, 769, 854, 465, 774, + 774, 774, 854, 769, 854, 465, 774, 774, 774, 854, + 769, 854, 465, 774, 774, 774, 854, 769, 854, 465, + 774, 774, 854, 769, 854, 465, 774, 774, 854, 769, + 854, 465, 774, 774, 854, 769, 854, 465, 774, 774, + 854, 769, 854, 465, 769, 769, 854, 465, 0, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769 + } ; + +static const flex_int16_t yy_nxt[4449] = + { 0, + 14, 15, 16, 17, 15, 18, 19, 20, 14, 21, + 22, 23, 24, 24, 24, 25, 14, 26, 27, 28, + 29, 30, 31, 14, 14, 32, 14, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 14, 14, 14, 14, 14, 14, 48, 14, + 14, 14, 14, 49, 14, 50, 51, 54, 16, 17, + 55, 18, 19, 56, 14, 61, 57, 62, 63, 63, + 63, 25, 61, 216, 62, 63, 63, 63, 88, 89, + 89, 88, 89, 89, 93, 94, 94, 94, 95, 95, + 95, 115, 542, 120, 115, 121, 132, 181, 345, 133, + + 346, 182, 543, 116, 117, 118, 251, 251, 251, 260, + 260, 50, 58, 54, 16, 17, 55, 18, 19, 56, + 59, 122, 57, 119, 122, 127, 134, 25, 127, 134, + 146, 260, 260, 146, 165, 123, 124, 165, 441, 128, + 135, 129, 216, 178, 147, 130, 178, 388, 166, 131, + 148, 125, 259, 389, 167, 259, 126, 179, 254, 254, + 254, 180, 252, 253, 253, 253, 762, 50, 58, 15, + 16, 17, 15, 18, 19, 20, 149, 341, 22, 149, + 60, 60, 60, 25, 183, 271, 271, 183, 271, 271, + 150, 189, 151, 342, 189, 373, 152, 760, 184, 185, + + 186, 269, 269, 374, 187, 190, 153, 88, 188, 258, + 88, 191, 262, 270, 269, 269, 270, 269, 273, 203, + 274, 759, 203, 50, 51, 15, 16, 17, 15, 18, + 19, 20, 52, 204, 22, 756, 60, 60, 60, 25, + 192, 269, 269, 192, 269, 269, 205, 197, 269, 269, + 197, 754, 193, 194, 195, 441, 206, 444, 196, 198, + 199, 200, 441, 90, 455, 201, 212, 202, 255, 253, + 253, 253, 89, 89, 95, 95, 95, 554, 256, 50, + 51, 65, 66, 67, 65, 68, 69, 70, 210, 210, + 71, 87, 95, 95, 95, 72, 87, 296, 296, 296, + + 298, 256, 753, 299, 299, 299, 115, 331, 333, 115, + 331, 333, 337, 122, 339, 337, 122, 339, 210, 210, + 118, 332, 334, 216, 216, 441, 338, 123, 340, 348, + 88, 127, 349, 231, 127, 73, 51, 65, 66, 67, + 65, 68, 69, 70, 74, 128, 71, 350, 750, 134, + 350, 72, 134, 352, 138, 355, 352, 138, 355, 357, + 441, 351, 357, 135, 441, 216, 447, 353, 141, 356, + 441, 362, 146, 358, 362, 146, 149, 441, 259, 149, + 442, 259, 445, 458, 297, 363, 147, 297, 446, 216, + 150, 73, 51, 76, 77, 78, 76, 79, 80, 81, + + 155, 376, 82, 155, 376, 165, 168, 83, 165, 168, + 441, 216, 451, 392, 156, 377, 392, 260, 260, 166, + 171, 379, 394, 383, 379, 394, 383, 393, 178, 396, + 183, 178, 396, 183, 441, 380, 395, 384, 235, 216, + 216, 441, 179, 397, 184, 216, 212, 84, 85, 76, + 77, 78, 76, 79, 80, 81, 86, 769, 82, 381, + 382, 385, 386, 83, 400, 189, 192, 400, 189, 192, + 406, 408, 410, 406, 408, 410, 441, 757, 401, 190, + 195, 235, 235, 441, 407, 409, 411, 197, 412, 452, + 197, 412, 301, 414, 416, 301, 414, 416, 748, 216, + + 747, 200, 413, 84, 85, 87, 96, 415, 417, 96, + 441, 235, 462, 87, 87, 87, 97, 94, 94, 94, + 744, 87, 87, 87, 87, 87, 98, 99, 100, 87, + 87, 87, 101, 87, 102, 103, 87, 104, 87, 87, + 105, 106, 87, 87, 87, 107, 108, 87, 109, 110, + 99, 101, 111, 103, 87, 112, 87, 106, 113, 114, + 138, 203, 419, 138, 203, 419, 720, 422, 266, 266, + 422, 742, 139, 140, 141, 204, 420, 216, 216, 441, + 142, 423, 421, 721, 143, 441, 448, 449, 441, 441, + 235, 144, 269, 269, 145, 155, 443, 456, 155, 216, + + 216, 216, 441, 457, 235, 453, 216, 441, 441, 156, + 741, 157, 216, 216, 568, 158, 235, 235, 441, 159, + 463, 160, 161, 269, 269, 162, 738, 163, 164, 168, + 235, 736, 168, 271, 271, 454, 278, 278, 235, 266, + 266, 169, 170, 171, 251, 251, 251, 278, 278, 172, + 459, 460, 441, 173, 235, 235, 441, 254, 254, 254, + 235, 735, 258, 174, 175, 262, 734, 176, 177, 209, + 210, 210, 209, 209, 209, 209, 235, 235, 235, 235, + 441, 212, 731, 209, 235, 255, 253, 253, 253, 254, + 254, 254, 554, 209, 303, 256, 427, 303, 256, 482, + + 482, 482, 483, 464, 464, 484, 484, 484, 256, 270, + 269, 269, 270, 729, 269, 273, 90, 274, 256, 269, + 273, 256, 91, 209, 209, 88, 269, 269, 88, 272, + 305, 256, 307, 305, 309, 307, 311, 309, 728, 311, + 727, 213, 214, 215, 216, 217, 216, 313, 315, 218, + 313, 315, 219, 216, 220, 724, 221, 222, 223, 224, + 225, 226, 216, 227, 228, 229, 230, 88, 317, 319, + 231, 317, 319, 722, 230, 230, 230, 230, 230, 230, + 230, 717, 230, 232, 233, 234, 235, 236, 235, 230, + 230, 237, 230, 230, 238, 235, 239, 230, 240, 241, + + 242, 243, 244, 245, 235, 246, 247, 248, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 209, 210, 210, 250, 209, 209, 209, 321, 323, + 325, 321, 323, 325, 327, 209, 329, 327, 297, 329, + 715, 297, 299, 299, 299, 301, 303, 305, 301, 303, + 305, 714, 299, 299, 299, 307, 309, 311, 307, 309, + 311, 503, 313, 315, 317, 313, 315, 317, 319, 321, + 323, 319, 321, 323, 713, 209, 209, 258, 258, 258, + 258, 258, 258, 258, 87, 325, 327, 329, 325, 327, + 329, 258, 331, 333, 337, 331, 333, 337, 339, 505, + + 350, 339, 505, 350, 547, 712, 332, 334, 338, 464, + 464, 212, 340, 506, 351, 352, 355, 578, 352, 355, + 427, 427, 554, 548, 464, 464, 209, 269, 269, 353, + 356, 258, 258, 258, 258, 258, 258, 258, 258, 258, + 258, 258, 258, 258, 468, 711, 357, 258, 258, 357, + 516, 362, 524, 516, 362, 524, 529, 708, 376, 529, + 358, 376, 212, 706, 517, 363, 525, 705, 531, 704, + 530, 531, 377, 769, 258, 703, 574, 297, 427, 468, + 297, 379, 532, 533, 379, 702, 533, 258, 258, 258, + 258, 258, 258, 258, 258, 380, 535, 534, 383, 535, + + 537, 383, 258, 537, 539, 392, 394, 539, 392, 394, + 536, 701, 384, 396, 538, 441, 396, 212, 540, 393, + 395, 400, 549, 406, 400, 549, 406, 397, 554, 700, + 557, 484, 484, 484, 699, 401, 550, 407, 408, 216, + 216, 408, 258, 265, 266, 266, 265, 265, 265, 265, + 410, 412, 409, 410, 412, 414, 416, 265, 414, 416, + 419, 212, 212, 419, 411, 413, 212, 696, 422, 415, + 417, 422, 769, 769, 420, 212, 212, 554, 427, 484, + 484, 484, 423, 212, 212, 441, 554, 554, 427, 564, + 427, 427, 560, 555, 769, 769, 212, 265, 209, 268, + + 269, 269, 268, 268, 268, 268, 212, 554, 569, 216, + 216, 212, 212, 268, 563, 427, 427, 554, 212, 558, + 561, 562, 554, 769, 235, 559, 427, 427, 427, 554, + 212, 212, 212, 427, 556, 210, 210, 427, 212, 427, + 427, 554, 769, 769, 235, 427, 427, 427, 301, 769, + 235, 301, 694, 268, 268, 268, 268, 269, 269, 268, + 268, 268, 268, 268, 268, 268, 268, 212, 235, 212, + 268, 268, 212, 303, 212, 212, 303, 212, 554, 305, + 769, 693, 305, 441, 212, 769, 769, 235, 441, 464, + 464, 565, 570, 575, 571, 441, 692, 268, 235, 464, + + 464, 427, 691, 464, 464, 468, 468, 235, 235, 690, + 268, 268, 268, 269, 269, 268, 268, 268, 268, 235, + 235, 573, 464, 464, 209, 689, 268, 464, 464, 209, + 464, 464, 579, 580, 468, 464, 464, 209, 464, 464, + 307, 688, 468, 307, 576, 464, 464, 687, 468, 582, + 577, 468, 309, 583, 311, 309, 581, 311, 468, 468, + 686, 313, 315, 468, 313, 315, 268, 268, 277, 278, + 278, 277, 277, 277, 277, 482, 482, 482, 317, 685, + 319, 317, 277, 319, 256, 321, 323, 325, 321, 323, + 325, 327, 329, 212, 327, 329, 505, 516, 594, 505, + + 516, 594, 524, 601, 769, 524, 529, 256, 602, 529, + 506, 517, 595, 464, 464, 531, 525, 603, 531, 606, + 530, 624, 277, 277, 96, 533, 607, 96, 533, 532, + 212, 621, 608, 535, 537, 539, 535, 537, 539, 534, + 549, 769, 427, 549, 280, 281, 282, 536, 538, 540, + 283, 684, 284, 285, 550, 286, 212, 683, 287, 288, + 682, 681, 678, 289, 290, 676, 291, 769, 281, 283, + 292, 285, 212, 293, 212, 288, 294, 295, 87, 297, + 427, 615, 297, 769, 615, 769, 87, 298, 87, 87, + 299, 299, 299, 212, 87, 616, 212, 675, 212, 617, + + 212, 674, 427, 212, 769, 673, 212, 769, 427, 769, + 594, 769, 427, 594, 554, 672, 427, 554, 464, 464, + 87, 87, 301, 671, 595, 301, 235, 670, 669, 87, + 87, 87, 87, 87, 87, 87, 212, 87, 427, 427, + 212, 427, 427, 212, 468, 468, 668, 769, 464, 464, + 209, 554, 615, 618, 769, 615, 765, 619, 667, 765, + 235, 666, 665, 87, 87, 303, 616, 664, 303, 468, + 766, 663, 87, 87, 87, 87, 87, 87, 87, 662, + 87, 464, 464, 209, 468, 464, 464, 209, 464, 464, + 209, 464, 464, 209, 468, 464, 464, 209, 468, 464, + + 464, 622, 212, 212, 468, 661, 87, 87, 305, 660, + 659, 305, 658, 769, 769, 87, 87, 87, 87, 87, + 87, 87, 212, 87, 679, 468, 468, 464, 464, 209, + 464, 464, 209, 769, 657, 623, 212, 212, 656, 427, + 652, 212, 464, 464, 209, 468, 653, 769, 769, 87, + 87, 307, 769, 654, 307, 464, 464, 209, 87, 87, + 87, 87, 87, 87, 87, 651, 87, 427, 464, 464, + 209, 655, 468, 212, 709, 212, 468, 212, 464, 464, + 209, 464, 464, 209, 769, 680, 769, 212, 769, 677, + 726, 650, 87, 87, 309, 649, 695, 309, 769, 212, + + 648, 87, 87, 87, 87, 87, 87, 87, 212, 87, + 769, 464, 464, 209, 725, 716, 697, 647, 646, 769, + 464, 464, 209, 698, 645, 707, 644, 212, 710, 464, + 464, 209, 643, 642, 641, 87, 87, 311, 769, 640, + 311, 639, 212, 212, 87, 87, 87, 87, 87, 87, + 87, 638, 87, 769, 769, 212, 732, 212, 719, 212, + 718, 723, 212, 464, 464, 209, 769, 637, 769, 636, + 769, 635, 634, 769, 464, 464, 209, 633, 87, 87, + 313, 733, 730, 313, 632, 212, 737, 87, 87, 87, + 87, 87, 87, 87, 740, 87, 769, 739, 212, 631, + + 743, 630, 629, 212, 464, 464, 209, 212, 212, 769, + 745, 464, 464, 209, 769, 751, 212, 628, 769, 769, + 752, 87, 87, 315, 755, 627, 315, 769, 749, 763, + 87, 87, 87, 87, 87, 87, 87, 212, 87, 761, + 746, 464, 464, 209, 212, 464, 464, 209, 769, 758, + 767, 626, 464, 464, 209, 769, 768, 765, 625, 212, + 765, 216, 620, 216, 87, 87, 317, 764, 235, 317, + 769, 766, 614, 87, 87, 87, 87, 87, 87, 87, + 613, 87, 612, 427, 464, 464, 209, 611, 610, 609, + 605, 604, 600, 599, 598, 597, 596, 593, 592, 468, + + 591, 590, 589, 588, 587, 586, 585, 87, 87, 319, + 584, 468, 319, 468, 216, 567, 87, 87, 87, 87, + 87, 87, 87, 216, 87, 216, 216, 566, 216, 216, + 553, 552, 551, 546, 545, 544, 541, 528, 527, 526, + 523, 522, 521, 520, 519, 518, 515, 514, 513, 512, + 87, 87, 321, 511, 510, 321, 509, 508, 507, 87, + 87, 87, 87, 87, 87, 87, 504, 87, 261, 461, + 235, 235, 441, 235, 450, 216, 216, 441, 216, 212, + 418, 418, 405, 404, 403, 402, 399, 398, 391, 390, + 387, 378, 375, 87, 87, 323, 372, 371, 323, 370, + + 369, 368, 87, 87, 87, 87, 87, 87, 87, 367, + 87, 366, 365, 364, 361, 360, 359, 354, 347, 344, + 343, 336, 335, 279, 90, 91, 212, 212, 207, 153, + 154, 137, 136, 91, 769, 52, 87, 87, 325, 769, + 769, 325, 769, 769, 769, 87, 87, 87, 87, 87, + 87, 87, 769, 87, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 87, + 87, 327, 769, 769, 327, 769, 769, 769, 87, 87, + 87, 87, 87, 87, 87, 769, 87, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 87, 87, 329, 769, 769, 329, 769, 769, + 769, 87, 87, 87, 87, 87, 87, 87, 769, 87, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 87, 209, 210, 210, 209, + 209, 209, 209, 769, 769, 769, 769, 769, 769, 769, + 209, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 209, 209, 230, 769, 769, 769, 212, 769, 769, 769, + 230, 230, 230, 230, 230, 230, 230, 769, 230, 424, + 425, 426, 427, 428, 427, 230, 230, 429, 230, 230, + 430, 427, 431, 230, 432, 433, 434, 435, 436, 437, + 427, 438, 439, 440, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 769, 769, 230, 769, 769, 230, 230, + 230, 769, 230, 230, 230, 230, 230, 230, 230, 230, + + 230, 230, 209, 210, 210, 250, 209, 209, 209, 769, + 769, 769, 769, 769, 769, 769, 209, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 209, 209, 464, 209, + 210, 210, 250, 209, 209, 209, 464, 464, 464, 464, + 464, 464, 464, 209, 464, 465, 466, 467, 468, 469, + 468, 464, 464, 470, 464, 464, 471, 468, 472, 464, + 473, 474, 475, 476, 477, 478, 468, 479, 480, 481, + + 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, + 464, 464, 464, 209, 209, 258, 258, 258, 258, 258, + 258, 258, 769, 769, 769, 769, 769, 769, 769, 258, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 258, + 258, 258, 258, 258, 258, 258, 258, 485, 258, 258, + 258, 258, 769, 769, 769, 258, 258, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 258, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 258, 265, 266, 266, 265, + 265, 265, 265, 769, 769, 769, 769, 769, 769, 769, + 265, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 265, 209, 268, 269, 269, 268, 268, 268, 268, 769, + 769, 769, 769, 769, 769, 769, 268, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 268, 268, 268, 268, + 269, 269, 268, 268, 268, 486, 268, 268, 268, 268, + 769, 769, 769, 268, 268, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 268, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 268, 268, 277, 278, 278, 277, 277, + + 277, 277, 769, 769, 769, 769, 769, 769, 769, 277, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 277, + 277, 87, 96, 769, 769, 96, 769, 769, 769, 87, + 87, 87, 87, 296, 296, 296, 769, 87, 87, 87, + 87, 87, 98, 99, 100, 87, 87, 87, 101, 87, + 102, 103, 87, 104, 87, 87, 105, 106, 87, 87, + 87, 107, 108, 87, 109, 110, 99, 101, 111, 103, + + 87, 112, 87, 106, 113, 114, 87, 297, 769, 769, + 297, 769, 769, 769, 87, 87, 87, 87, 87, 87, + 87, 769, 87, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 87, 87, + 301, 769, 769, 301, 769, 769, 769, 87, 87, 87, + 87, 87, 87, 87, 769, 87, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 87, 87, 303, 769, 769, 303, 769, 769, 769, + + 87, 87, 87, 87, 87, 87, 87, 769, 87, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 87, 87, 305, 769, 769, 305, + 769, 769, 769, 87, 87, 87, 87, 87, 87, 87, + 769, 87, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 87, 87, 307, + 769, 769, 307, 769, 769, 769, 87, 87, 87, 87, + 87, 87, 87, 769, 87, 769, 769, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 87, 87, 309, 769, 769, 309, 769, 769, 769, 87, + 87, 87, 87, 87, 87, 87, 769, 87, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 87, 87, 311, 769, 769, 311, 769, + 769, 769, 87, 87, 87, 87, 87, 87, 87, 769, + 87, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 87, 87, 313, 769, + 769, 313, 769, 769, 769, 87, 87, 87, 87, 87, + 87, 87, 769, 87, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 87, + 87, 315, 769, 769, 315, 769, 769, 769, 87, 87, + 87, 87, 87, 87, 87, 769, 87, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 87, 87, 317, 769, 769, 317, 769, 769, + + 769, 87, 87, 87, 87, 87, 87, 87, 769, 87, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 87, 87, 319, 769, 769, + 319, 769, 769, 769, 87, 87, 87, 87, 87, 87, + 87, 769, 87, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 87, 87, + 321, 769, 769, 321, 769, 769, 769, 87, 87, 87, + 87, 87, 87, 87, 769, 87, 769, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 87, 87, 323, 769, 769, 323, 769, 769, 769, + 87, 87, 87, 87, 87, 87, 87, 769, 87, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 87, 87, 325, 769, 769, 325, + 769, 769, 769, 87, 87, 87, 87, 87, 87, 87, + 769, 87, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 769, 87, 87, 327, + 769, 769, 327, 769, 769, 769, 87, 87, 87, 87, + 87, 87, 87, 769, 87, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 87, 87, 329, 769, 769, 329, 769, 769, 769, 87, + 87, 87, 87, 87, 87, 87, 769, 87, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 87, 209, 210, 210, 250, 209, 209, + + 209, 769, 769, 769, 769, 769, 769, 769, 209, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 209, 209, + 209, 210, 210, 250, 209, 209, 209, 769, 769, 769, + 769, 769, 468, 468, 572, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + + 769, 769, 769, 769, 209, 209, 87, 297, 769, 769, + 297, 769, 769, 769, 87, 87, 87, 87, 87, 87, + 87, 769, 87, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 87, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 87, 769, 769, 769, 769, + 87, 769, 87, 90, 90, 769, 90, 90, 90, 90, + + 90, 90, 92, 769, 92, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 211, 769, 769, 769, 211, 211, + 769, 211, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 257, 257, 257, 257, 257, 257, 257, 257, 258, + 258, 258, 258, 258, 258, 258, 258, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 263, 263, 263, 263, + 263, 263, 263, 263, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 267, 267, 267, 267, 267, 267, 267, + 267, 267, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 272, 272, 272, 272, 272, 272, 272, 272, 272, + + 275, 275, 275, 275, 275, 275, 275, 275, 275, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 300, 300, + 769, 769, 300, 300, 769, 300, 302, 302, 769, 769, + 302, 302, 769, 302, 304, 304, 769, 769, 304, 304, + 769, 304, 306, 306, 769, 769, 306, 306, 769, 306, + 308, 308, 769, 769, 308, 308, 769, 308, 310, 310, + 769, 769, 310, 310, 769, 310, 312, 312, 769, 769, + 312, 312, 769, 312, 314, 314, 769, 769, 314, 314, + 769, 314, 316, 316, 769, 769, 316, 316, 769, 316, + 318, 318, 769, 769, 318, 318, 769, 318, 320, 320, + + 769, 769, 320, 320, 769, 320, 322, 322, 769, 769, + 322, 322, 769, 322, 324, 324, 769, 769, 324, 324, + 769, 324, 326, 326, 769, 769, 326, 326, 769, 326, + 328, 328, 769, 769, 328, 328, 769, 328, 330, 330, + 769, 769, 330, 330, 769, 330, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 209, 209, 209, 209, 209, + 209, 209, 209, 209, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 257, 257, 257, 257, 257, 257, 257, + 257, 258, 258, 258, 258, 258, 258, 258, 258, 261, + 261, 261, 261, 261, 261, 261, 261, 261, 263, 263, + + 263, 263, 263, 263, 263, 263, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 487, 769, 769, + 487, 769, 769, 487, 488, 769, 769, 488, 769, 769, + + 488, 489, 769, 769, 489, 769, 769, 489, 490, 769, + 769, 490, 769, 769, 490, 491, 769, 769, 491, 769, + 769, 491, 492, 769, 769, 492, 769, 769, 492, 493, + 769, 769, 493, 769, 769, 493, 494, 769, 769, 494, + 769, 769, 494, 495, 769, 769, 495, 769, 769, 495, + 496, 769, 769, 496, 769, 769, 496, 497, 769, 769, + 497, 769, 769, 497, 498, 769, 769, 498, 769, 769, + 498, 499, 769, 769, 499, 769, 769, 499, 500, 769, + 769, 500, 769, 769, 500, 501, 769, 769, 501, 769, + 769, 501, 502, 769, 769, 502, 769, 769, 502, 300, + + 300, 769, 769, 300, 300, 769, 300, 302, 302, 769, + 769, 302, 302, 769, 302, 304, 304, 769, 769, 304, + 304, 769, 304, 306, 306, 769, 769, 306, 306, 769, + 306, 308, 308, 769, 769, 308, 308, 769, 308, 310, + 310, 769, 769, 310, 310, 769, 310, 312, 312, 769, + 769, 312, 312, 769, 312, 314, 314, 769, 769, 314, + 314, 769, 314, 316, 316, 769, 769, 316, 316, 769, + 316, 318, 318, 769, 769, 318, 318, 769, 318, 320, + 320, 769, 769, 320, 320, 769, 320, 322, 322, 769, + 769, 322, 322, 769, 322, 324, 324, 769, 769, 324, + + 324, 769, 324, 326, 326, 769, 769, 326, 326, 769, + 326, 328, 328, 769, 769, 328, 328, 769, 328, 330, + 330, 769, 769, 330, 330, 769, 330, 230, 769, 769, + 769, 230, 230, 230, 230, 464, 464, 464, 464, 464, + 464, 464, 464, 464, 258, 258, 258, 258, 258, 258, + 258, 258, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 487, 769, 769, 487, 769, 769, 487, 488, 769, + 769, 488, 769, 769, 488, 489, 769, 769, 489, 769, + 769, 489, 490, 769, 769, 490, 769, 769, 490, 491, + 769, 769, 491, 769, 769, 491, 492, 769, 769, 492, + + 769, 769, 492, 493, 769, 769, 493, 769, 769, 493, + 494, 769, 769, 494, 769, 769, 494, 495, 769, 769, + 495, 769, 769, 495, 496, 769, 769, 496, 769, 769, + 496, 497, 769, 769, 497, 769, 769, 497, 498, 769, + 769, 498, 769, 769, 498, 499, 769, 769, 499, 769, + 769, 499, 500, 769, 769, 500, 769, 769, 500, 501, + 769, 769, 501, 769, 769, 501, 502, 769, 769, 502, + 769, 769, 502, 300, 300, 769, 769, 300, 300, 769, + 300, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 13, 769, 769, 769, 769, 769, 769, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769 + } ; + +static const flex_int16_t yy_chk[4449] = + { 0, + 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, 3, 3, 3, + 3, 3, 3, 3, 7, 7, 3, 7, 7, 7, + 7, 3, 8, 762, 8, 8, 8, 8, 15, 16, + 16, 15, 17, 17, 21, 21, 21, 21, 23, 23, + 23, 26, 389, 27, 26, 27, 30, 42, 130, 30, + + 130, 42, 389, 26, 26, 26, 60, 60, 60, 66, + 66, 3, 3, 4, 4, 4, 4, 4, 4, 4, + 4, 28, 4, 26, 28, 29, 31, 4, 29, 31, + 35, 67, 67, 35, 39, 28, 28, 39, 224, 29, + 31, 29, 224, 41, 35, 29, 41, 173, 39, 29, + 35, 28, 65, 173, 39, 65, 28, 41, 62, 62, + 62, 41, 61, 61, 61, 61, 756, 4, 4, 5, + 5, 5, 5, 5, 5, 5, 36, 125, 5, 36, + 5, 5, 5, 5, 43, 77, 77, 43, 78, 78, + 36, 44, 36, 125, 44, 162, 36, 754, 43, 43, + + 43, 81, 81, 162, 43, 44, 36, 88, 43, 68, + 88, 44, 68, 76, 76, 76, 76, 79, 79, 47, + 79, 753, 47, 5, 5, 6, 6, 6, 6, 6, + 6, 6, 6, 47, 6, 750, 6, 6, 6, 6, + 45, 83, 83, 45, 84, 84, 47, 46, 85, 85, + 46, 748, 45, 45, 45, 220, 47, 220, 45, 46, + 46, 46, 239, 68, 239, 46, 427, 46, 63, 63, + 63, 63, 89, 89, 93, 93, 93, 427, 63, 6, + 6, 9, 9, 9, 9, 9, 9, 9, 209, 209, + 9, 95, 95, 95, 95, 9, 97, 97, 97, 97, + + 110, 63, 747, 110, 110, 110, 115, 116, 117, 115, + 116, 117, 121, 122, 124, 121, 122, 124, 210, 210, + 115, 116, 117, 213, 213, 213, 121, 122, 124, 132, + 231, 127, 132, 231, 127, 9, 9, 10, 10, 10, + 10, 10, 10, 10, 10, 127, 10, 133, 744, 134, + 133, 10, 134, 136, 138, 139, 136, 138, 139, 140, + 222, 133, 140, 134, 215, 215, 222, 136, 138, 139, + 221, 145, 146, 140, 145, 146, 149, 241, 259, 149, + 215, 259, 221, 241, 280, 145, 146, 280, 221, 221, + 149, 10, 10, 11, 11, 11, 11, 11, 11, 11, + + 155, 164, 11, 155, 164, 165, 168, 11, 165, 168, + 226, 226, 226, 176, 155, 164, 176, 260, 260, 165, + 168, 169, 177, 170, 169, 177, 170, 176, 178, 180, + 183, 178, 180, 183, 243, 169, 177, 170, 243, 227, + 227, 227, 178, 180, 183, 227, 751, 11, 11, 12, + 12, 12, 12, 12, 12, 12, 12, 751, 12, 169, + 169, 170, 170, 12, 185, 189, 192, 185, 189, 192, + 193, 194, 196, 193, 194, 196, 229, 751, 185, 189, + 192, 232, 232, 232, 193, 194, 196, 197, 198, 229, + 197, 198, 281, 199, 201, 281, 199, 201, 742, 229, + + 741, 197, 198, 12, 12, 24, 24, 199, 201, 24, + 245, 245, 245, 24, 24, 24, 24, 24, 24, 24, + 738, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 34, 203, 205, 34, 203, 205, 713, 206, 266, 266, + 206, 736, 34, 34, 34, 203, 205, 219, 219, 219, + 34, 206, 205, 713, 34, 240, 223, 223, 223, 234, + 234, 34, 268, 268, 34, 38, 219, 240, 38, 219, + + 228, 228, 228, 240, 240, 234, 228, 248, 452, 38, + 735, 38, 223, 223, 452, 38, 238, 238, 238, 38, + 248, 38, 38, 269, 269, 38, 731, 38, 38, 40, + 248, 729, 40, 271, 271, 238, 277, 277, 238, 265, + 265, 40, 40, 40, 251, 251, 251, 278, 278, 40, + 242, 242, 242, 40, 246, 246, 246, 252, 252, 252, + 246, 728, 261, 40, 40, 261, 727, 40, 40, 52, + 52, 52, 52, 52, 52, 52, 242, 242, 247, 247, + 247, 435, 724, 52, 247, 253, 253, 253, 253, 254, + 254, 254, 435, 265, 282, 253, 435, 282, 254, 255, + + 255, 255, 256, 468, 468, 256, 256, 256, 255, 270, + 270, 270, 270, 722, 272, 272, 261, 272, 253, 273, + 273, 254, 273, 52, 52, 54, 274, 274, 54, 274, + 283, 255, 284, 283, 285, 284, 286, 285, 721, 286, + 720, 54, 54, 54, 54, 54, 54, 287, 288, 54, + 287, 288, 54, 54, 54, 717, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 55, 55, 289, 290, + 55, 289, 290, 715, 55, 55, 55, 55, 55, 55, + 55, 708, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 59, 59, 59, 59, 59, 59, 59, 291, 292, + 293, 291, 292, 293, 294, 59, 295, 294, 297, 295, + 706, 297, 298, 298, 298, 301, 303, 305, 301, 303, + 305, 705, 299, 299, 299, 307, 309, 311, 307, 309, + 311, 299, 313, 315, 317, 313, 315, 317, 319, 321, + 323, 319, 321, 323, 703, 59, 59, 64, 64, 64, + 64, 64, 64, 64, 299, 325, 327, 329, 325, 327, + 329, 64, 331, 333, 337, 331, 333, 337, 339, 341, + + 350, 339, 341, 350, 399, 701, 331, 333, 337, 474, + 474, 424, 339, 341, 350, 352, 355, 474, 352, 355, + 424, 424, 424, 399, 466, 466, 466, 486, 486, 352, + 355, 64, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 466, 699, 357, 69, 69, 357, + 361, 362, 371, 361, 362, 371, 375, 696, 376, 375, + 357, 376, 429, 694, 361, 362, 371, 691, 378, 688, + 375, 378, 376, 429, 69, 687, 471, 487, 429, 471, + 487, 379, 378, 381, 379, 685, 381, 69, 71, 71, + 71, 71, 71, 71, 71, 379, 382, 381, 383, 382, + + 385, 383, 71, 385, 386, 392, 394, 386, 392, 394, + 382, 684, 383, 396, 385, 448, 396, 431, 386, 392, + 394, 400, 402, 406, 400, 402, 406, 396, 431, 682, + 431, 483, 483, 483, 681, 400, 402, 406, 408, 448, + 448, 408, 71, 74, 74, 74, 74, 74, 74, 74, + 410, 412, 408, 410, 412, 414, 416, 74, 414, 416, + 419, 425, 428, 419, 410, 412, 426, 678, 422, 414, + 416, 422, 425, 428, 419, 433, 437, 426, 426, 484, + 484, 484, 422, 455, 436, 449, 433, 437, 437, 437, + 425, 428, 433, 426, 455, 436, 432, 74, 74, 75, + + 75, 75, 75, 75, 75, 75, 430, 432, 455, 449, + 449, 434, 453, 75, 436, 430, 430, 430, 438, 432, + 434, 434, 434, 453, 453, 432, 432, 438, 438, 438, + 439, 456, 457, 438, 430, 572, 572, 430, 454, 439, + 439, 439, 456, 457, 457, 439, 434, 434, 488, 454, + 456, 488, 675, 75, 75, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 440, 454, 458, + 80, 80, 459, 489, 462, 461, 489, 463, 440, 490, + 458, 674, 490, 459, 460, 462, 461, 458, 463, 472, + 472, 440, 461, 472, 463, 460, 671, 80, 462, 476, + + 476, 440, 670, 467, 467, 476, 467, 459, 459, 669, + 80, 80, 82, 82, 82, 82, 82, 82, 82, 460, + 460, 467, 469, 469, 469, 668, 82, 470, 470, 470, + 473, 473, 475, 475, 470, 477, 477, 477, 481, 481, + 491, 666, 469, 491, 473, 478, 478, 665, 478, 478, + 473, 473, 492, 481, 493, 492, 477, 493, 475, 475, + 664, 494, 495, 481, 494, 495, 82, 82, 86, 86, + 86, 86, 86, 86, 86, 482, 482, 482, 496, 662, + 497, 496, 86, 497, 482, 498, 499, 500, 498, 499, + 500, 501, 502, 570, 501, 502, 505, 516, 519, 505, + + 516, 519, 524, 527, 570, 524, 529, 482, 527, 529, + 505, 516, 519, 583, 583, 531, 524, 527, 531, 543, + 529, 583, 86, 86, 96, 533, 543, 96, 533, 531, + 555, 570, 543, 535, 537, 539, 535, 537, 539, 533, + 549, 555, 555, 549, 96, 96, 96, 535, 537, 539, + 96, 660, 96, 96, 549, 96, 564, 658, 96, 96, + 657, 656, 653, 96, 96, 650, 96, 564, 96, 96, + 96, 96, 556, 96, 557, 96, 96, 96, 98, 98, + 564, 553, 98, 556, 553, 557, 98, 98, 98, 98, + 98, 98, 98, 558, 98, 553, 559, 649, 560, 557, + + 571, 648, 556, 561, 558, 647, 562, 559, 559, 560, + 594, 571, 558, 594, 561, 646, 560, 562, 579, 579, + 98, 99, 99, 644, 594, 99, 571, 643, 641, 99, + 99, 99, 99, 99, 99, 99, 563, 99, 561, 561, + 565, 562, 562, 569, 579, 579, 640, 563, 574, 574, + 574, 565, 615, 563, 569, 615, 760, 565, 639, 760, + 569, 638, 637, 99, 100, 100, 615, 636, 100, 574, + 760, 635, 100, 100, 100, 100, 100, 100, 100, 634, + 100, 573, 573, 573, 573, 575, 575, 575, 576, 576, + 576, 577, 577, 577, 577, 578, 578, 578, 576, 580, + + 580, 575, 618, 654, 578, 631, 100, 101, 101, 630, + 629, 101, 628, 618, 654, 101, 101, 101, 101, 101, + 101, 101, 617, 101, 654, 580, 580, 581, 581, 581, + 582, 582, 582, 617, 627, 581, 697, 621, 625, 617, + 618, 619, 623, 623, 623, 582, 620, 697, 621, 101, + 102, 102, 619, 621, 102, 624, 624, 624, 102, 102, + 102, 102, 102, 102, 102, 614, 102, 619, 622, 622, + 622, 623, 624, 652, 697, 677, 622, 707, 655, 655, + 655, 719, 719, 719, 652, 655, 677, 718, 707, 652, + 719, 613, 102, 103, 103, 612, 677, 103, 718, 679, + + 610, 103, 103, 103, 103, 103, 103, 103, 695, 103, + 679, 680, 680, 680, 718, 707, 679, 609, 608, 695, + 698, 698, 698, 680, 607, 695, 606, 725, 698, 710, + 710, 710, 605, 604, 603, 103, 104, 104, 725, 602, + 104, 601, 709, 716, 104, 104, 104, 104, 104, 104, + 104, 600, 104, 709, 716, 723, 725, 730, 710, 732, + 709, 716, 737, 726, 726, 726, 723, 599, 730, 598, + 732, 597, 596, 737, 733, 733, 733, 593, 104, 105, + 105, 726, 723, 105, 592, 739, 730, 105, 105, 105, + 105, 105, 105, 105, 733, 105, 739, 732, 745, 591, + + 737, 590, 589, 743, 746, 746, 746, 749, 755, 745, + 739, 740, 740, 740, 743, 745, 757, 588, 749, 755, + 746, 105, 106, 106, 749, 587, 106, 757, 743, 757, + 106, 106, 106, 106, 106, 106, 106, 761, 106, 755, + 740, 752, 752, 752, 763, 758, 758, 758, 761, 752, + 761, 585, 764, 764, 764, 763, 764, 765, 584, 767, + 765, 568, 567, 566, 106, 107, 107, 758, 763, 107, + 767, 765, 552, 107, 107, 107, 107, 107, 107, 107, + 551, 107, 548, 767, 768, 768, 768, 546, 545, 544, + 542, 541, 526, 523, 522, 521, 520, 518, 514, 768, + + 513, 512, 511, 510, 509, 508, 507, 107, 108, 108, + 504, 480, 108, 479, 451, 450, 108, 108, 108, 108, + 108, 108, 108, 447, 108, 446, 445, 444, 443, 442, + 421, 405, 403, 398, 391, 390, 388, 374, 373, 372, + 369, 368, 367, 366, 365, 364, 360, 359, 349, 347, + 108, 109, 109, 346, 345, 109, 344, 343, 342, 109, + 109, 109, 109, 109, 109, 109, 336, 109, 262, 244, + 237, 236, 235, 233, 225, 218, 217, 216, 214, 211, + 207, 202, 191, 188, 187, 186, 182, 181, 175, 174, + 172, 167, 163, 109, 111, 111, 161, 160, 111, 159, + + 158, 157, 111, 111, 111, 111, 111, 111, 111, 154, + 111, 152, 151, 148, 144, 143, 142, 137, 131, 129, + 126, 120, 119, 92, 91, 90, 57, 53, 49, 48, + 37, 33, 32, 18, 13, 2, 111, 112, 112, 0, + 0, 112, 0, 0, 0, 112, 112, 112, 112, 112, + 112, 112, 0, 112, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, + 113, 113, 0, 0, 113, 0, 0, 0, 113, 113, + 113, 113, 113, 113, 113, 0, 113, 0, 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, 114, 114, 0, 0, 114, 0, 0, + 0, 114, 114, 114, 114, 114, 114, 114, 0, 114, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 114, 208, 208, 208, 208, + 208, 208, 208, 0, 0, 0, 0, 0, 0, 0, + 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 208, 208, 212, 0, 0, 0, 212, 0, 0, 0, + 212, 212, 212, 212, 212, 212, 212, 0, 212, 212, + 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, + 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, + 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, + 212, 212, 212, 212, 212, 212, 212, 230, 230, 230, + 230, 230, 230, 0, 0, 230, 0, 0, 230, 230, + 230, 0, 230, 230, 230, 230, 230, 230, 230, 230, + + 230, 230, 249, 249, 249, 249, 249, 249, 249, 0, + 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 249, 249, 250, 250, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, + + 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, + 250, 250, 250, 250, 250, 257, 257, 257, 257, 257, + 257, 257, 0, 0, 0, 0, 0, 0, 0, 257, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 257, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 0, 0, 0, 263, 263, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 263, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 263, 264, 264, 264, 264, + 264, 264, 264, 0, 0, 0, 0, 0, 0, 0, + 264, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 264, 264, 267, 267, 267, 267, 267, 267, 267, 0, + 0, 0, 0, 0, 0, 0, 267, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 267, 267, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 0, 0, 0, 275, 275, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 275, 275, 276, 276, 276, 276, 276, + + 276, 276, 0, 0, 0, 0, 0, 0, 0, 276, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, + 276, 296, 296, 0, 0, 296, 0, 0, 0, 296, + 296, 296, 296, 296, 296, 296, 0, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + + 296, 296, 296, 296, 296, 296, 300, 300, 0, 0, + 300, 0, 0, 0, 300, 300, 300, 300, 300, 300, + 300, 0, 300, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 300, 302, + 302, 0, 0, 302, 0, 0, 0, 302, 302, 302, + 302, 302, 302, 302, 0, 302, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 302, 304, 304, 0, 0, 304, 0, 0, 0, + + 304, 304, 304, 304, 304, 304, 304, 0, 304, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 304, 306, 306, 0, 0, 306, + 0, 0, 0, 306, 306, 306, 306, 306, 306, 306, + 0, 306, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 306, 308, 308, + 0, 0, 308, 0, 0, 0, 308, 308, 308, 308, + 308, 308, 308, 0, 308, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 308, 310, 310, 0, 0, 310, 0, 0, 0, 310, + 310, 310, 310, 310, 310, 310, 0, 310, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 310, 312, 312, 0, 0, 312, 0, + 0, 0, 312, 312, 312, 312, 312, 312, 312, 0, + 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 312, 314, 314, 0, + 0, 314, 0, 0, 0, 314, 314, 314, 314, 314, + 314, 314, 0, 314, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 314, + 316, 316, 0, 0, 316, 0, 0, 0, 316, 316, + 316, 316, 316, 316, 316, 0, 316, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 316, 318, 318, 0, 0, 318, 0, 0, + + 0, 318, 318, 318, 318, 318, 318, 318, 0, 318, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 318, 320, 320, 0, 0, + 320, 0, 0, 0, 320, 320, 320, 320, 320, 320, + 320, 0, 320, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 320, 322, + 322, 0, 0, 322, 0, 0, 0, 322, 322, 322, + 322, 322, 322, 322, 0, 322, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 322, 324, 324, 0, 0, 324, 0, 0, 0, + 324, 324, 324, 324, 324, 324, 324, 0, 324, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 324, 326, 326, 0, 0, 326, + 0, 0, 0, 326, 326, 326, 326, 326, 326, 326, + 0, 326, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 326, 328, 328, + 0, 0, 328, 0, 0, 0, 328, 328, 328, 328, + 328, 328, 328, 0, 328, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 328, 330, 330, 0, 0, 330, 0, 0, 0, 330, + 330, 330, 330, 330, 330, 330, 0, 330, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 330, 464, 464, 464, 464, 464, 464, + + 464, 0, 0, 0, 0, 0, 0, 0, 464, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 464, 464, + 465, 465, 465, 465, 465, 465, 465, 0, 0, 0, + 0, 0, 465, 465, 465, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 465, 465, 503, 503, 0, 0, + 503, 0, 0, 0, 503, 503, 503, 503, 503, 503, + 503, 0, 503, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 503, 770, + 770, 770, 770, 770, 770, 770, 770, 770, 771, 771, + 771, 771, 771, 771, 771, 771, 771, 772, 772, 772, + 772, 772, 772, 772, 772, 772, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 774, 0, 0, 0, 0, + 774, 0, 774, 775, 775, 0, 775, 775, 775, 775, + + 775, 775, 776, 0, 776, 777, 777, 777, 777, 777, + 777, 777, 777, 777, 778, 0, 0, 0, 778, 778, + 0, 778, 779, 779, 779, 779, 779, 779, 779, 779, + 779, 780, 780, 780, 780, 780, 780, 780, 780, 781, + 781, 781, 781, 781, 781, 781, 781, 782, 782, 782, + 782, 782, 782, 782, 782, 782, 783, 783, 783, 783, + 783, 783, 783, 783, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 786, 786, 786, 786, 786, 786, 786, 786, + 786, 787, 787, 787, 787, 787, 787, 787, 787, 787, + + 788, 788, 788, 788, 788, 788, 788, 788, 788, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 790, 790, + 0, 0, 790, 790, 0, 790, 791, 791, 0, 0, + 791, 791, 0, 791, 792, 792, 0, 0, 792, 792, + 0, 792, 793, 793, 0, 0, 793, 793, 0, 793, + 794, 794, 0, 0, 794, 794, 0, 794, 795, 795, + 0, 0, 795, 795, 0, 795, 796, 796, 0, 0, + 796, 796, 0, 796, 797, 797, 0, 0, 797, 797, + 0, 797, 798, 798, 0, 0, 798, 798, 0, 798, + 799, 799, 0, 0, 799, 799, 0, 799, 800, 800, + + 0, 0, 800, 800, 0, 800, 801, 801, 0, 0, + 801, 801, 0, 801, 802, 802, 0, 0, 802, 802, + 0, 802, 803, 803, 0, 0, 803, 803, 0, 803, + 804, 804, 0, 0, 804, 804, 0, 804, 805, 805, + 0, 0, 805, 805, 0, 805, 806, 806, 806, 806, + 806, 806, 806, 806, 806, 807, 807, 807, 807, 807, + 807, 807, 807, 807, 808, 808, 808, 808, 808, 808, + 808, 808, 808, 809, 809, 809, 809, 809, 809, 809, + 809, 810, 810, 810, 810, 810, 810, 810, 810, 811, + 811, 811, 811, 811, 811, 811, 811, 811, 812, 812, + + 812, 812, 812, 812, 812, 812, 813, 813, 813, 813, + 813, 813, 813, 813, 813, 814, 814, 814, 814, 814, + 814, 814, 814, 814, 815, 815, 815, 815, 815, 815, + 815, 815, 815, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 817, 817, 817, 817, 817, 817, 817, 817, + 817, 818, 818, 818, 818, 818, 818, 818, 818, 818, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 821, 821, + 821, 821, 821, 821, 821, 821, 821, 822, 0, 0, + 822, 0, 0, 822, 823, 0, 0, 823, 0, 0, + + 823, 824, 0, 0, 824, 0, 0, 824, 825, 0, + 0, 825, 0, 0, 825, 826, 0, 0, 826, 0, + 0, 826, 827, 0, 0, 827, 0, 0, 827, 828, + 0, 0, 828, 0, 0, 828, 829, 0, 0, 829, + 0, 0, 829, 830, 0, 0, 830, 0, 0, 830, + 831, 0, 0, 831, 0, 0, 831, 832, 0, 0, + 832, 0, 0, 832, 833, 0, 0, 833, 0, 0, + 833, 834, 0, 0, 834, 0, 0, 834, 835, 0, + 0, 835, 0, 0, 835, 836, 0, 0, 836, 0, + 0, 836, 837, 0, 0, 837, 0, 0, 837, 838, + + 838, 0, 0, 838, 838, 0, 838, 839, 839, 0, + 0, 839, 839, 0, 839, 840, 840, 0, 0, 840, + 840, 0, 840, 841, 841, 0, 0, 841, 841, 0, + 841, 842, 842, 0, 0, 842, 842, 0, 842, 843, + 843, 0, 0, 843, 843, 0, 843, 844, 844, 0, + 0, 844, 844, 0, 844, 845, 845, 0, 0, 845, + 845, 0, 845, 846, 846, 0, 0, 846, 846, 0, + 846, 847, 847, 0, 0, 847, 847, 0, 847, 848, + 848, 0, 0, 848, 848, 0, 848, 849, 849, 0, + 0, 849, 849, 0, 849, 850, 850, 0, 0, 850, + + 850, 0, 850, 851, 851, 0, 0, 851, 851, 0, + 851, 852, 852, 0, 0, 852, 852, 0, 852, 853, + 853, 0, 0, 853, 853, 0, 853, 854, 0, 0, + 0, 854, 854, 854, 854, 855, 855, 855, 855, 855, + 855, 855, 855, 855, 856, 856, 856, 856, 856, 856, + 856, 856, 857, 857, 857, 857, 857, 857, 857, 857, + 857, 858, 0, 0, 858, 0, 0, 858, 859, 0, + 0, 859, 0, 0, 859, 860, 0, 0, 860, 0, + 0, 860, 861, 0, 0, 861, 0, 0, 861, 862, + 0, 0, 862, 0, 0, 862, 863, 0, 0, 863, + + 0, 0, 863, 864, 0, 0, 864, 0, 0, 864, + 865, 0, 0, 865, 0, 0, 865, 866, 0, 0, + 866, 0, 0, 866, 867, 0, 0, 867, 0, 0, + 867, 868, 0, 0, 868, 0, 0, 868, 869, 0, + 0, 869, 0, 0, 869, 870, 0, 0, 870, 0, + 0, 870, 871, 0, 0, 871, 0, 0, 871, 872, + 0, 0, 872, 0, 0, 872, 873, 0, 0, 873, + 0, 0, 873, 874, 874, 0, 0, 874, 874, 0, + 874, 875, 875, 875, 875, 875, 875, 875, 875, 875, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769 + } ; + +/* Table of booleans, true if rule could match eol. */ +static const flex_int32_t yy_rule_can_match_eol[139] = + { 0, +1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; + +extern int yy_flex_debug; +int yy_flex_debug = 1; + +static const flex_int16_t yy_rule_linenum[138] = + { 0, + 144, 149, 156, 158, 160, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + + 272, 273, 274, 275, 276, 280, 281, 286, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 308, 313, 328, 330, 362, 364, + 366, 369, 371, 373, 376, 392, 397 + } ; + +static yy_state_type *yy_state_buf=0, *yy_state_ptr=0; +static char *yy_full_match; +static int yy_lp; +#define REJECT \ +{ \ +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ \ +yy_cp = (yy_full_match); /* restore poss. backed-over text */ \ +++(yy_lp); \ +goto find_rule; \ +} + +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "hyp_l.l" +/* + * read hyperlynx files + * Copyright 2012, 2016 Koen De Vleeschauwer. + * + * This file is part of pcb-rnd. + * + * 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, see . + */ +/* avoid collision with other scanners */ +#line 28 "hyp_l.l" +#include + +char *rnd_strdup(const char *s); /* from #include */ + +#include "hyp_y.h" + +/* copy a string between quotes */ +char *strunquote(const char *); + +/* print error message */ +void hyyerror(const char *); + +/* remember hyperlynx file section we're in */ +int section = -1; + +#line 2222 "hyp_l.c" +#line 46 "hyp_l.l" + /* + * The scanner knows five states: INITIAL, STATE_STRING, STATE_POSINT, STATE_FLOAT and STATE_COMMENT + * + * In state INITIAL the scanner recognizes: + * - punctuation (such as {}()=, ) + * - keywords (such as VERSION, BOARD, NET), + * - strings (both between double quotes " and unquoted), + * - and floating point numbers (with optional suffix, eg. 10 uF), + * + * In STATE_STRING the scanner recognizes punctuation and strings only. + * This avoids unquoted strings being interpreted as numbers, or keywords. + * + * In STATE_POSINT the scanner recognizes a positive integer. + * + * In STATE_FLOAT the scanner recognizes a floating point number (without suffix). + * + * In STATE_COMMENT the scanner discards all text up to the next + * right brace } , and then continues in state INITIAL. + * + */ + + /* whitespace: space, tab, vertical tab, form feed */ + /* accept windows and unix newlines */ + /* + * lines with an asterisk in the first column are comments + */ + /* Left-hand side of an assignment: check whether next token is equals sign */ + /* + * Positive integer + */ + /* + * Floating point numbers + */ + /* ordinary floating point numbers */ + /* floating point numbers with suffix, e,g. pF, nH */ + /* + * Strings + */ + /* an unquoted string */ + /* a sequence of characters, excluding whitespace and reserved characters. + * also allow strings such as "(Net0)" . + */ + /* a string enclosed in double quotes " */ +/* an unquoted string with spaces */ +/* all variables used in assignments */ +/* an unquoted string with spaces is terminated by the next assignment or the end of line */ +/* an empty string is terminated by the next assignment, a ')' or a '}' */ +#line 2271 "hyp_l.c" + +#define INITIAL 0 +#define STATE_STRING 1 +#define STATE_POSINT 2 +#define STATE_FLOAT 3 +#define STATE_COMMENT 4 +#define STATE_COMMENT_EOL 5 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +/* %if-c-only */ +#include +/* %endif */ +/* %if-c++-only */ +/* %endif */ +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* %if-c-only Reentrant structure and macros (non-C++). */ +/* %if-reentrant */ +/* %if-c-only */ + +static int yy_init_globals ( void ); + +/* %endif */ +/* %if-reentrant */ +/* %endif */ +/* %endif End reentrant structures and macros. */ + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* %if-bison-bridge */ +/* %endif */ + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +/* %not-for-header */ +#ifndef YY_NO_UNPUT + + static void yyunput ( int c, char *buf_ptr ); + +#endif +/* %ok-for-header */ + +/* %endif */ + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +/* %if-c-only Standard (non-C++) definition */ +/* %not-for-header */ +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif +/* %ok-for-header */ + +/* %endif */ +#endif + +/* %if-c-only */ + +/* %endif */ + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* %if-c-only Standard (non-C++) definition */ +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +/* %endif */ +/* %if-c++-only C++ definition */ +/* %endif */ +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ +/* %if-c++-only C++ definition \ */\ +/* %endif */ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +/* %if-c-only */ +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +#endif + +/* %if-tables-serialization structures and prototypes */ +/* %not-for-header */ +/* %ok-for-header */ + +/* %not-for-header */ +/* %tables-yydmap generated elements */ +/* %endif */ +/* end tables serialization structures and prototypes */ + +/* %ok-for-header */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 +/* %if-c-only Standard (non-C++) definition */ + +extern int yylex (void); + +#define YY_DECL int yylex (void) +/* %endif */ +/* %if-c++-only C++ definition */ +/* %endif */ +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +/* %% [6.0] YY_RULE_SETUP definition goes here */ +#define YY_RULE_SETUP \ + if ( yyleng > 0 ) \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ + (yytext[yyleng - 1] == '\n'); \ + YY_USER_ACTION + +/* %not-for-header */ +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + /* Create the reject buffer large enough to save one state per allowed character. */ + if ( ! (yy_state_buf) ) + (yy_state_buf) = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE ); + if ( ! (yy_state_buf) ) + YY_FATAL_ERROR( "out of dynamic memory in yylex()" ); + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) +/* %if-c-only */ + yyin = stdin; +/* %endif */ +/* %if-c++-only */ +/* %endif */ + + if ( ! yyout ) +/* %if-c-only */ + yyout = stdout; +/* %endif */ +/* %if-c++-only */ +/* %endif */ + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +/* %% [7.0] user's declarations go here */ +#line 140 "hyp_l.l" + + + /* When in STATE_COMMENT skip all comment until next right brace */ +#line 2569 "hyp_l.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { +/* %% [8.0] yymore()-related code goes here */ + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + +/* %% [9.0] code to set up and find next match goes here */ + yy_current_state = (yy_start); + yy_current_state += YY_AT_BOL(); + + (yy_state_ptr) = (yy_state_buf); + *(yy_state_ptr)++ = yy_current_state; + +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 770 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + *(yy_state_ptr)++ = yy_current_state; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 4391 ); + +yy_find_action: +/* %% [10.0] code to find the action number goes here */ + yy_current_state = *--(yy_state_ptr); + (yy_lp) = yy_accept[yy_current_state]; + +find_rule: /* we branch to this label when backing up */ + + for ( ; ; ) /* until we find what rule we matched */ + { + if ( (yy_lp) && (yy_lp) < yy_accept[yy_current_state + 1] ) + { + yy_act = yy_acclist[(yy_lp)]; + { + (yy_full_match) = yy_cp; + break; + } + } + --yy_cp; + yy_current_state = *--(yy_state_ptr); + (yy_lp) = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +/* %% [11.0] code for yylineno update goes here */ + + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + yylineno++; +; + } + +do_action: /* This label is used only to access EOF actions. */ + +/* %% [12.0] debug code goes here */ + if ( yy_flex_debug ) + { + if ( yy_act == 0 ) + fprintf( stderr, "--scanner backing up\n" ); + else if ( yy_act < 138 ) + fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n", + (long)yy_rule_linenum[yy_act], yytext ); + else if ( yy_act == 138 ) + fprintf( stderr, "--accepting default rule (\"%s\")\n", + yytext ); + else if ( yy_act == 139 ) + fprintf( stderr, "--(end of buffer or a NUL)\n" ); + else + fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); + } + + switch ( yy_act ) + { /* beginning of action switch */ +/* %% [13.0] actions go here */ + +case 1: +/* rule 1 can match eol */ +YY_RULE_SETUP +#line 144 "hyp_l.l" +{ BEGIN INITIAL; /* skip all comment until next right brace */ } + YY_BREAK + +/* When in STATE_COMMENT_EOL skip all comment until end-of-line */ + +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 149 "hyp_l.l" +{ BEGIN INITIAL; /* skip all comment until next end-of-line */ } + YY_BREAK + +/* skip comments and whitespace */ + +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 156 "hyp_l.l" +{ /* skip comments */ } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 158 "hyp_l.l" +{ /* skip whitespace */ } + YY_BREAK +case 5: +/* rule 5 can match eol */ +YY_RULE_SETUP +#line 160 "hyp_l.l" +{ /* skip newlines */ } + YY_BREAK + +/* + * Hyperlynx keywords + */ +/* Sections */ +case 6: +YY_RULE_SETUP +#line 170 "hyp_l.l" +{section = H_BOARD_FILE; return H_BOARD_FILE;} + YY_BREAK +case 7: +YY_RULE_SETUP +#line 171 "hyp_l.l" +{section = H_VERSION; return H_VERSION;} + YY_BREAK +case 8: +YY_RULE_SETUP +#line 172 "hyp_l.l" +{section = H_DATA_MODE; return H_DATA_MODE;} + YY_BREAK +case 9: +YY_RULE_SETUP +#line 173 "hyp_l.l" +{section = H_UNITS; return H_UNITS;} + YY_BREAK +case 10: +YY_RULE_SETUP +#line 174 "hyp_l.l" +{section = H_PLANE_SEP; return H_PLANE_SEP;} + YY_BREAK +case 11: +YY_RULE_SETUP +#line 175 "hyp_l.l" +{section = H_BOARD; BEGIN STATE_COMMENT_EOL; return H_BOARD;} + YY_BREAK +case 12: +YY_RULE_SETUP +#line 176 "hyp_l.l" +{section = H_STACKUP; BEGIN STATE_COMMENT_EOL; return H_STACKUP;} + YY_BREAK +case 13: +YY_RULE_SETUP +#line 177 "hyp_l.l" +{section = H_DEVICES; BEGIN STATE_COMMENT_EOL; return H_DEVICES;} + YY_BREAK +case 14: +YY_RULE_SETUP +#line 178 "hyp_l.l" +{section = H_SUPPLIES; BEGIN STATE_COMMENT_EOL; return H_SUPPLIES;} + YY_BREAK +case 15: +YY_RULE_SETUP +#line 179 "hyp_l.l" +{section = H_PADSTACK; BEGIN STATE_STRING; return H_PADSTACK;} + YY_BREAK +case 16: +YY_RULE_SETUP +#line 180 "hyp_l.l" +{section = H_NET; BEGIN STATE_STRING; return H_NET;} + YY_BREAK +case 17: +YY_RULE_SETUP +#line 181 "hyp_l.l" +{section = H_NET_CLASS; return H_NET_CLASS;} + YY_BREAK +case 18: +YY_RULE_SETUP +#line 182 "hyp_l.l" +{section = H_END; return H_END;} + YY_BREAK +case 19: +YY_RULE_SETUP +#line 183 "hyp_l.l" +{section = H_KEY; return H_KEY;} + YY_BREAK +/* Keywords */ +case 20: +YY_RULE_SETUP +#line 187 "hyp_l.l" +{return H_A;} + YY_BREAK +case 21: +YY_RULE_SETUP +#line 188 "hyp_l.l" +{return H_ARC;} + YY_BREAK +case 22: +YY_RULE_SETUP +#line 189 "hyp_l.l" +{return H_COPPER;} + YY_BREAK +case 23: +YY_RULE_SETUP +#line 190 "hyp_l.l" +{return H_CURVE;} + YY_BREAK +case 24: +YY_RULE_SETUP +#line 191 "hyp_l.l" +{if (section == H_DATA_MODE) BEGIN STATE_COMMENT; return H_DETAILED;} + YY_BREAK +case 25: +YY_RULE_SETUP +#line 192 "hyp_l.l" +{return H_DIELECTRIC;} + YY_BREAK +case 26: +YY_RULE_SETUP +#line 193 "hyp_l.l" +{return H_ENGLISH;} + YY_BREAK +case 27: +YY_RULE_SETUP +#line 194 "hyp_l.l" +{if (section == H_UNITS) BEGIN STATE_COMMENT; return H_LENGTH;} + YY_BREAK +case 28: +YY_RULE_SETUP +#line 195 "hyp_l.l" +{return H_LINE;} + YY_BREAK +case 29: +YY_RULE_SETUP +#line 196 "hyp_l.l" +{return H_METRIC;} + YY_BREAK +case 30: +YY_RULE_SETUP +#line 197 "hyp_l.l" +{return H_M;} + YY_BREAK +case 31: +YY_RULE_SETUP +#line 198 "hyp_l.l" +{return H_N;} + YY_BREAK +case 32: +YY_RULE_SETUP +#line 199 "hyp_l.l" +{return H_OPTIONS;} + YY_BREAK +case 33: +YY_RULE_SETUP +#line 200 "hyp_l.l" +{return H_PAD;} + YY_BREAK +case 34: +YY_RULE_SETUP +#line 201 "hyp_l.l" +{return H_PERIMETER_ARC;} + YY_BREAK +case 35: +YY_RULE_SETUP +#line 202 "hyp_l.l" +{return H_PERIMETER_SEGMENT;} + YY_BREAK +case 36: +YY_RULE_SETUP +#line 203 "hyp_l.l" +{return H_PIN;} + YY_BREAK +case 37: +YY_RULE_SETUP +#line 204 "hyp_l.l" +{return H_PLANE;} + YY_BREAK +case 38: +YY_RULE_SETUP +#line 205 "hyp_l.l" +{return H_POLYGON;} + YY_BREAK +case 39: +YY_RULE_SETUP +#line 206 "hyp_l.l" +{return H_POLYLINE;} + YY_BREAK +case 40: +YY_RULE_SETUP +#line 207 "hyp_l.l" +{return H_POLYVOID;} + YY_BREAK +case 41: +YY_RULE_SETUP +#line 208 "hyp_l.l" +{return H_POUR;} + YY_BREAK +case 42: +YY_RULE_SETUP +#line 209 "hyp_l.l" +{return H_S;} + YY_BREAK +case 43: +YY_RULE_SETUP +#line 210 "hyp_l.l" +{return H_T;} + YY_BREAK +case 44: +YY_RULE_SETUP +#line 211 "hyp_l.l" +{return H_SEG;} + YY_BREAK +case 45: +YY_RULE_SETUP +#line 212 "hyp_l.l" +{return H_SIGNAL;} + YY_BREAK +case 46: +YY_RULE_SETUP +#line 213 "hyp_l.l" +{if (section == H_DATA_MODE) BEGIN STATE_COMMENT; return H_SIMPLIFIED; } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 214 "hyp_l.l" +{return H_SIM_BOTH;} + YY_BREAK +case 48: +YY_RULE_SETUP +#line 215 "hyp_l.l" +{return H_SIM_IN;} + YY_BREAK +case 49: +YY_RULE_SETUP +#line 216 "hyp_l.l" +{return H_SIM_OUT;} + YY_BREAK +case 50: +YY_RULE_SETUP +#line 217 "hyp_l.l" +{return H_USEG;} + YY_BREAK +case 51: +YY_RULE_SETUP +#line 218 "hyp_l.l" +{return H_VIA;} + YY_BREAK +case 52: +YY_RULE_SETUP +#line 219 "hyp_l.l" +{if (section == H_UNITS) BEGIN STATE_COMMENT; return H_WEIGHT;} + YY_BREAK +/* Assignments */ +case 53: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 223 "hyp_l.l" +{return H_A;} + YY_BREAK +case 54: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 224 "hyp_l.l" +{return H_A1;} + YY_BREAK +case 55: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 225 "hyp_l.l" +{return H_A2;} + YY_BREAK +case 56: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 226 "hyp_l.l" +{return H_BR;} + YY_BREAK +case 57: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 227 "hyp_l.l" +{return H_C;} + YY_BREAK +case 58: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 228 "hyp_l.l" +{return H_C_QM;} + YY_BREAK +case 59: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 3; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 229 "hyp_l.l" +{return H_CO_QM;} + YY_BREAK +case 60: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 230 "hyp_l.l" +{return H_D;} + YY_BREAK +case 61: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 231 "hyp_l.l" +{return H_ER;} + YY_BREAK +case 62: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 232 "hyp_l.l" +{return H_F;} + YY_BREAK +case 63: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 233 "hyp_l.l" +{BEGIN STATE_POSINT; return H_ID;} + YY_BREAK +case 64: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 234 "hyp_l.l" +{BEGIN STATE_STRING; return H_L;} + YY_BREAK +case 65: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 235 "hyp_l.l" +{BEGIN STATE_STRING; return H_L1;} + YY_BREAK +case 66: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 236 "hyp_l.l" +{BEGIN STATE_STRING; return H_L2;} + YY_BREAK +case 67: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 3; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 237 "hyp_l.l" +{return H_LPS;} + YY_BREAK +case 68: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 238 "hyp_l.l" +{return H_LT;} + YY_BREAK +case 69: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 239 "hyp_l.l" +{BEGIN STATE_STRING; return H_M;} + YY_BREAK +case 70: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 240 "hyp_l.l" +{BEGIN STATE_STRING; return H_N;} + YY_BREAK +case 71: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 4; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 241 "hyp_l.l" +{BEGIN STATE_STRING; return H_NAME;} + YY_BREAK +/* P is used as "plating thickness" in "stackup/signal" and as "padstack" in "net/via" */ +case 72: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 243 "hyp_l.l" +{if (section == H_NET) BEGIN STATE_STRING; return H_P;} + YY_BREAK +case 73: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 3; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 244 "hyp_l.l" +{BEGIN STATE_STRING; return H_PKG;} + YY_BREAK +case 74: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 3; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 245 "hyp_l.l" +{return H_PR_QM;} + YY_BREAK +case 75: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 246 "hyp_l.l" +{return H_PS;} + YY_BREAK +case 76: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 247 "hyp_l.l" +{return H_R;} + YY_BREAK +case 77: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 3; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 248 "hyp_l.l" +{BEGIN STATE_STRING; return H_REF;} + YY_BREAK +case 78: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 249 "hyp_l.l" +{BEGIN STATE_STRING; return H_S;} + YY_BREAK +case 79: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 250 "hyp_l.l" +{return H_SX;} + YY_BREAK +case 80: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 251 "hyp_l.l" +{return H_SY;} + YY_BREAK +case 81: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 252 "hyp_l.l" +{BEGIN STATE_STRING; return H_S1;} + YY_BREAK +case 82: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 3; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 253 "hyp_l.l" +{return H_S1X;} + YY_BREAK +case 83: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 3; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 254 "hyp_l.l" +{return H_S1Y;} + YY_BREAK +case 84: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 255 "hyp_l.l" +{BEGIN STATE_STRING; return H_S2;} + YY_BREAK +case 85: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 3; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 256 "hyp_l.l" +{return H_S2X;} + YY_BREAK +case 86: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 3; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 257 "hyp_l.l" +{return H_S2Y;} + YY_BREAK +case 87: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 258 "hyp_l.l" +{return H_T;} + YY_BREAK +case 88: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 259 "hyp_l.l" +{return H_TC;} + YY_BREAK +case 89: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 17; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 260 "hyp_l.l" +{return H_USE_DIE_FOR_METAL;} + YY_BREAK +case 90: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 261 "hyp_l.l" +{BEGIN STATE_STRING; return H_V;} + YY_BREAK +case 91: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 262 "hyp_l.l" +{return H_V_QM;} + YY_BREAK +case 92: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 3; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 263 "hyp_l.l" +{if (section == H_DEVICES) BEGIN STATE_STRING; return H_VAL;} + YY_BREAK +case 93: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 264 "hyp_l.l" +{return H_W;} + YY_BREAK +case 94: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 265 "hyp_l.l" +{return H_X;} + YY_BREAK +case 95: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 266 "hyp_l.l" +{return H_X1;} + YY_BREAK +case 96: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 267 "hyp_l.l" +{return H_X2;} + YY_BREAK +case 97: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 268 "hyp_l.l" +{return H_XC;} + YY_BREAK +case 98: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 269 "hyp_l.l" +{return H_Y;} + YY_BREAK +case 99: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 270 "hyp_l.l" +{return H_Y1;} + YY_BREAK +case 100: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 271 "hyp_l.l" +{return H_Y2;} + YY_BREAK +case 101: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 272 "hyp_l.l" +{return H_YC;} + YY_BREAK +case 102: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 273 "hyp_l.l" +{return H_Z;} + YY_BREAK +case 103: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 274 "hyp_l.l" +{BEGIN STATE_STRING; return H_ZL;} + YY_BREAK +case 104: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 4; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 275 "hyp_l.l" +{return H_ZLEN;} + YY_BREAK +case 105: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 276 "hyp_l.l" +{return H_ZW;} + YY_BREAK +/* Booleans */ +case 106: +YY_RULE_SETUP +#line 280 "hyp_l.l" +{hyylval.boolval = 1; return H_BOOL; } + YY_BREAK +case 107: +YY_RULE_SETUP +#line 281 "hyp_l.l" +{hyylval.boolval = 0; return H_BOOL; } + YY_BREAK +/* Floats */ +/* ordinary floating point numbers */ +case 108: +YY_RULE_SETUP +#line 286 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL); return H_FLOAT;} + YY_BREAK +/* floating point numbers with suffix, e,g. pF, nH */ +case 109: +YY_RULE_SETUP +#line 289 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e24; return H_FLOAT;} + YY_BREAK +case 110: +YY_RULE_SETUP +#line 290 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e21; return H_FLOAT;} + YY_BREAK +case 111: +YY_RULE_SETUP +#line 291 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e18; return H_FLOAT;} + YY_BREAK +case 112: +YY_RULE_SETUP +#line 292 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e15; return H_FLOAT;} + YY_BREAK +case 113: +YY_RULE_SETUP +#line 293 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e12; return H_FLOAT;} + YY_BREAK +case 114: +YY_RULE_SETUP +#line 294 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e9; return H_FLOAT;} + YY_BREAK +case 115: +YY_RULE_SETUP +#line 295 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e6; return H_FLOAT;} + YY_BREAK +case 116: +YY_RULE_SETUP +#line 296 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e3; return H_FLOAT;} + YY_BREAK +case 117: +YY_RULE_SETUP +#line 297 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e-3; return H_FLOAT;} + YY_BREAK +case 118: +YY_RULE_SETUP +#line 298 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e-6; return H_FLOAT;} + YY_BREAK +case 119: +YY_RULE_SETUP +#line 299 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e-9; return H_FLOAT;} + YY_BREAK +case 120: +YY_RULE_SETUP +#line 300 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e-12; return H_FLOAT;} + YY_BREAK +case 121: +YY_RULE_SETUP +#line 301 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e-15; return H_FLOAT;} + YY_BREAK +case 122: +YY_RULE_SETUP +#line 302 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e-18; return H_FLOAT;} + YY_BREAK +case 123: +YY_RULE_SETUP +#line 303 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e-21; return H_FLOAT;} + YY_BREAK +case 124: +YY_RULE_SETUP +#line 304 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL) * 1e-24; return H_FLOAT;} + YY_BREAK +/* floating point numbers in VERSION and PLANE_SEP have no suffix and are followed by optional comments */ + +case 125: +YY_RULE_SETUP +#line 308 "hyp_l.l" +{hyylval.floatval = strtod(hyytext, NULL); BEGIN STATE_COMMENT; return H_FLOAT;} + YY_BREAK + +/* A positive integer is used only in polygon/polyline/polyvoid "ID = posint" */ + +case 126: +YY_RULE_SETUP +#line 313 "hyp_l.l" +{ BEGIN INITIAL; hyylval.intval = atoi(hyytext); return H_POSINT; } + YY_BREAK + +/* + * This is a workaround for syntactically incorrect .hyp files. + * We accept the following constructs as representing an empty string: + * NAME= L1=somelayer + * NAME= ) + * NAME= } + * and we accept the following constructs as representing "a string with spaces" + * NAME=a string with spaces L1=somelayer + */ + +case 127: +YY_RULE_SETUP +#line 328 "hyp_l.l" +{ yyless(0); BEGIN INITIAL; hyylval.strval = rnd_strdup(""); return H_STRING; } /* emit empty string and reprocess */ + YY_BREAK +case 128: +YY_RULE_SETUP +#line 330 "hyp_l.l" +{ + /* + * Commas are not allowed in strings in the padstack section unless the string is enclosed in double quotes ("). + */ + + if ((section == H_PADSTACK) && strchr(hyytext, ',')) + REJECT + else + { + char *s = rnd_strdup(hyytext); + + BEGIN INITIAL; + + /* strip final ' VAR=' */ + if ((strlen(s) != 0) && (s[strlen(s)-1] == '=')) { + char* space = strrchr(s, ' '); + /* strip trailing spaces */ + if (space != NULL) + while ((space >= s) && (*space == ' ')) *space-- = '\0'; + yyless(strlen(s)); + if (strchr(s, ' ') != NULL) hyyerror("warning: unquoted string contains space"); + } + + hyylval.strval = s; + + return H_STRING; + } + } + YY_BREAK + + +case 129: +YY_RULE_SETUP +#line 362 "hyp_l.l" +{return '{';} + YY_BREAK +case 130: +YY_RULE_SETUP +#line 364 "hyp_l.l" +{BEGIN STATE_COMMENT_EOL; return '}';} + YY_BREAK +case 131: +YY_RULE_SETUP +#line 366 "hyp_l.l" +{if (section == H_PADSTACK) BEGIN STATE_STRING; return '(';} + YY_BREAK +/* allow for comment after the closing bracket ) */ +case 132: +YY_RULE_SETUP +#line 369 "hyp_l.l" +{BEGIN STATE_COMMENT_EOL; return ')';} + YY_BREAK +case 133: +YY_RULE_SETUP +#line 371 "hyp_l.l" +{return ',';} + YY_BREAK +case 134: +YY_RULE_SETUP +#line 373 "hyp_l.l" +{if ((section == H_VERSION) || (section == H_PLANE_SEP)) BEGIN STATE_FLOAT; return '=';} + YY_BREAK +/* string */ +case 135: +YY_RULE_SETUP +#line 376 "hyp_l.l" +{ + /* + * Commas are not allowed in strings in the padstack section unless the string is enclosed in double quotes ("). + */ + + if ((section == H_PADSTACK) && strchr(hyytext, ',')) + REJECT + else + { + BEGIN INITIAL; + hyylval.strval = rnd_strdup(hyytext); + return H_STRING; + } + } + YY_BREAK +/* string in double quotes */ +case 136: +YY_RULE_SETUP +#line 392 "hyp_l.l" +{BEGIN INITIAL; hyylval.strval = strunquote(hyytext); return H_STRING;} + YY_BREAK +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(STATE_STRING): +case YY_STATE_EOF(STATE_POSINT): +case YY_STATE_EOF(STATE_FLOAT): +case YY_STATE_EOF(STATE_COMMENT): +case YY_STATE_EOF(STATE_COMMENT_EOL): +#line 394 "hyp_l.l" +{yyterminate();} + YY_BREAK +/* have bison catch all unrecognized characters with parse errors */ +case 137: +YY_RULE_SETUP +#line 397 "hyp_l.l" +{return hyytext[0];} + YY_BREAK + +case 138: +YY_RULE_SETUP +#line 401 "hyp_l.l" +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK +#line 3609 "hyp_l.c" + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; +/* %if-c-only */ + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; +/* %endif */ +/* %if-c++-only */ +/* %endif */ + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { +/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */ + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ +/* %ok-for-header */ + +/* %if-c++-only */ +/* %not-for-header */ +/* %ok-for-header */ + +/* %endif */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +/* %if-c-only */ +static int yy_get_next_buffer (void) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +/* %if-c-only */ +/* %not-for-header */ + static yy_state_type yy_get_previous_state (void) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + yy_state_type yy_current_state; + char *yy_cp; + +/* %% [15.0] code to get the start state into yy_current_state goes here */ + yy_current_state = (yy_start); + yy_current_state += YY_AT_BOL(); + + (yy_state_ptr) = (yy_state_buf); + *(yy_state_ptr)++ = yy_current_state; + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { +/* %% [16.0] code to find the next state goes here */ + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 770 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + *(yy_state_ptr)++ = yy_current_state; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ +/* %if-c-only */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + int yy_is_jam; + /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */ + + YY_CHAR yy_c = 1; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 770 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 769); + if ( ! yy_is_jam ) + *(yy_state_ptr)++ = yy_current_state; + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT +/* %if-c-only */ + + static void yyunput (int c, char * yy_bp ) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + int number_to_move = (yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + +/* %% [18.0] update yylineno here */ + + if ( c == '\n' ){ + --yylineno; + } + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} +/* %if-c-only */ + +/* %endif */ +#endif + +/* %if-c-only */ +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + +/* %% [19.0] update BOL and yylineno */ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); + if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol ) + + yylineno++; +; + + return c; +} +/* %if-c-only */ +#endif /* ifndef YY_NO_INPUT */ +/* %endif */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ +/* %if-c-only */ + void yyrestart (FILE * input_file ) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/* %if-c++-only */ +/* %endif */ + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ +/* %if-c-only */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +/* %if-c-only */ +static void yy_load_buffer_state (void) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; +/* %if-c-only */ + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; +/* %endif */ +/* %if-c++-only */ +/* %endif */ + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ +/* %if-c-only */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/* %if-c++-only */ +/* %endif */ + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ +/* %if-c-only */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ +/* %if-c-only */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) +/* %endif */ +/* %if-c++-only */ +/* %endif */ + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + +/* %if-c-only */ + b->yy_input_file = file; +/* %endif */ +/* %if-c++-only */ +/* %endif */ + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + +/* %if-c-only */ + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + +/* %endif */ +/* %if-c++-only */ +/* %endif */ + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ +/* %if-c-only */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/* %if-c-or-c++ */ +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +/* %if-c-only */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} +/* %endif */ + +/* %if-c-or-c++ */ +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +/* %if-c-only */ +void yypop_buffer_state (void) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} +/* %endif */ + +/* %if-c-or-c++ */ +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +/* %if-c-only */ +static void yyensure_buffer_stack (void) +/* %endif */ +/* %if-c++-only */ +/* %endif */ +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} +/* %endif */ + +/* %if-c-only */ +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} +/* %endif */ + +/* %if-c-only */ +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} +/* %endif */ + +/* %if-c-only */ +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} +/* %endif */ + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +/* %if-c-only */ +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} +/* %endif */ +/* %if-c++-only */ +/* %endif */ + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/* %if-c-only */ +/* %if-reentrant */ +/* %endif */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/* %if-reentrant */ +/* %endif */ + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +/* %endif */ + +/* %if-reentrant */ +/* %if-bison-bridge */ +/* %endif */ +/* %endif if-c-only */ + +/* %if-c-only */ +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + /* We do not touch yylineno unless the option is enabled. */ + yylineno = 1; + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + + (yy_state_buf) = 0; + (yy_state_ptr) = 0; + (yy_full_match) = 0; + (yy_lp) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} +/* %endif */ + +/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */ +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + yyfree ( (yy_state_buf) ); + (yy_state_buf) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + +/* %if-reentrant */ +/* %endif */ + return 0; +} +/* %endif */ + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +/* %if-tables-serialization definitions */ +/* %define-yytables The name for this specific scanner's tables. */ +#define YYTABLES_NAME "yytables" +/* %endif */ + +/* %ok-for-header */ + +#line 401 "hyp_l.l" + + + /* + * copy a quoted string. + * e.g. "data 0" -> data 0 + * a double quote inside the string can be escaped by writing two consecutive double quotes + * e.g. "net ""hi""" -> net "hi" + */ + + char *strunquote(const char *src) + { + char* dst; + size_t len = strlen(src) + 1; + dst = (char *)malloc(len); + if (dst != NULL) + { + char* p = (char *)src + 1; /* first char after initial quote */ + char* q = dst; + do + if (*p == '"') p++; + while ((*q++ = *p++) != '\0'); + } + return dst; + } + + /* not truncated */ + Index: tags/2.3.0/src_plugins/io_hyp/hyp_l.h =================================================================== --- tags/2.3.0/src_plugins/io_hyp/hyp_l.h (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/hyp_l.h (revision 33253) @@ -0,0 +1,826 @@ +#ifndef hyyHEADER_H +#define hyyHEADER_H 1 +#define hyyIN_HEADER 1 + +#line 6 "hyp_l.h" + +#line 8 "hyp_l.h" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +/* %not-for-header */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* %if-c++-only */ +/* %endif */ + +/* %if-c-only */ +#ifdef yy_create_buffer +#define hyy_create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer hyy_create_buffer +#endif + +#ifdef yy_delete_buffer +#define hyy_delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer hyy_delete_buffer +#endif + +#ifdef yy_scan_buffer +#define hyy_scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer hyy_scan_buffer +#endif + +#ifdef yy_scan_string +#define hyy_scan_string_ALREADY_DEFINED +#else +#define yy_scan_string hyy_scan_string +#endif + +#ifdef yy_scan_bytes +#define hyy_scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes hyy_scan_bytes +#endif + +#ifdef yy_init_buffer +#define hyy_init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer hyy_init_buffer +#endif + +#ifdef yy_flush_buffer +#define hyy_flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer hyy_flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define hyy_load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state hyy_load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define hyy_switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer hyy_switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define hyypush_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state hyypush_buffer_state +#endif + +#ifdef yypop_buffer_state +#define hyypop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state hyypop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define hyyensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack hyyensure_buffer_stack +#endif + +#ifdef yylex +#define hyylex_ALREADY_DEFINED +#else +#define yylex hyylex +#endif + +#ifdef yyrestart +#define hyyrestart_ALREADY_DEFINED +#else +#define yyrestart hyyrestart +#endif + +#ifdef yylex_init +#define hyylex_init_ALREADY_DEFINED +#else +#define yylex_init hyylex_init +#endif + +#ifdef yylex_init_extra +#define hyylex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra hyylex_init_extra +#endif + +#ifdef yylex_destroy +#define hyylex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy hyylex_destroy +#endif + +#ifdef yyget_debug +#define hyyget_debug_ALREADY_DEFINED +#else +#define yyget_debug hyyget_debug +#endif + +#ifdef yyset_debug +#define hyyset_debug_ALREADY_DEFINED +#else +#define yyset_debug hyyset_debug +#endif + +#ifdef yyget_extra +#define hyyget_extra_ALREADY_DEFINED +#else +#define yyget_extra hyyget_extra +#endif + +#ifdef yyset_extra +#define hyyset_extra_ALREADY_DEFINED +#else +#define yyset_extra hyyset_extra +#endif + +#ifdef yyget_in +#define hyyget_in_ALREADY_DEFINED +#else +#define yyget_in hyyget_in +#endif + +#ifdef yyset_in +#define hyyset_in_ALREADY_DEFINED +#else +#define yyset_in hyyset_in +#endif + +#ifdef yyget_out +#define hyyget_out_ALREADY_DEFINED +#else +#define yyget_out hyyget_out +#endif + +#ifdef yyset_out +#define hyyset_out_ALREADY_DEFINED +#else +#define yyset_out hyyset_out +#endif + +#ifdef yyget_leng +#define hyyget_leng_ALREADY_DEFINED +#else +#define yyget_leng hyyget_leng +#endif + +#ifdef yyget_text +#define hyyget_text_ALREADY_DEFINED +#else +#define yyget_text hyyget_text +#endif + +#ifdef yyget_lineno +#define hyyget_lineno_ALREADY_DEFINED +#else +#define yyget_lineno hyyget_lineno +#endif + +#ifdef yyset_lineno +#define hyyset_lineno_ALREADY_DEFINED +#else +#define yyset_lineno hyyset_lineno +#endif + +#ifdef yywrap +#define hyywrap_ALREADY_DEFINED +#else +#define yywrap hyywrap +#endif + +/* %endif */ + +#ifdef yyalloc +#define hyyalloc_ALREADY_DEFINED +#else +#define yyalloc hyyalloc +#endif + +#ifdef yyrealloc +#define hyyrealloc_ALREADY_DEFINED +#else +#define yyrealloc hyyrealloc +#endif + +#ifdef yyfree +#define hyyfree_ALREADY_DEFINED +#else +#define yyfree hyyfree +#endif + +/* %if-c-only */ + +#ifdef yytext +#define hyytext_ALREADY_DEFINED +#else +#define yytext hyytext +#endif + +#ifdef yyleng +#define hyyleng_ALREADY_DEFINED +#else +#define yyleng hyyleng +#endif + +#ifdef yyin +#define hyyin_ALREADY_DEFINED +#else +#define yyin hyyin +#endif + +#ifdef yyout +#define hyyout_ALREADY_DEFINED +#else +#define yyout hyyout +#endif + +#ifdef yy_flex_debug +#define hyy_flex_debug_ALREADY_DEFINED +#else +#define yy_flex_debug hyy_flex_debug +#endif + +#ifdef yylineno +#define hyylineno_ALREADY_DEFINED +#else +#define yylineno hyylineno +#endif + +/* %endif */ + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +/* %if-c-only */ +#include +#include +#include +#include +/* %endif */ + +/* %if-tables-serialization */ +/* %endif */ +/* end standard C headers. */ + +/* %if-c-or-c++ */ +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* %endif */ + +/* begin standard C++ headers. */ +/* %if-c++-only */ +/* %endif */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* %not-for-header */ + +/* %not-for-header */ + +/* %if-reentrant */ +/* %endif */ + +/* %if-not-reentrant */ + +/* %endif */ + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +/* %if-not-reentrant */ +extern int yyleng; +/* %endif */ + +/* %if-c-only */ +/* %if-not-reentrant */ +extern FILE *yyin, *yyout; +/* %endif */ +/* %endif */ + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { +/* %if-c-only */ + FILE *yy_input_file; +/* %endif */ + +/* %if-c++-only */ +/* %endif */ + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* %if-c-only Standard (non-C++) definition */ +/* %not-for-header */ + +/* %endif */ + +/* %if-c-only Standard (non-C++) definition */ + +/* %if-not-reentrant */ +/* %not-for-header */ + +/* %endif */ + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +/* %endif */ + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */ +/* Begin user sect3 */ + +#define hyywrap() (/*CONSTCOND*/1) +#define YY_SKIP_YYWRAP + +#define FLEX_DEBUG + +extern int yylineno; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +/* %if-c-only Standard (non-C++) definition */ + +/* %endif */ + +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define INITIAL 0 +#define STATE_STRING 1 +#define STATE_POSINT 2 +#define STATE_FLOAT 3 +#define STATE_COMMENT 4 +#define STATE_COMMENT_EOL 5 + +#endif + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +/* %if-c-only */ +#include +/* %endif */ +/* %if-c++-only */ +/* %endif */ +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* %if-c-only Reentrant structure and macros (non-C++). */ +/* %if-reentrant */ +/* %if-c-only */ + +/* %endif */ +/* %if-reentrant */ +/* %endif */ +/* %endif End reentrant structures and macros. */ + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* %if-bison-bridge */ +/* %endif */ + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +/* %not-for-header */ + +/* %endif */ + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +/* %if-c-only Standard (non-C++) definition */ +/* %not-for-header */ + +/* %endif */ +#endif + +/* %if-c-only */ + +/* %endif */ + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* %if-tables-serialization structures and prototypes */ +/* %not-for-header */ + +/* %not-for-header */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 +/* %if-c-only Standard (non-C++) definition */ + +extern int yylex (void); + +#define YY_DECL int yylex (void) +/* %endif */ +/* %if-c++-only C++ definition */ +/* %endif */ +#endif /* !YY_DECL */ + +/* %not-for-header */ + +/* %if-c++-only */ +/* %not-for-header */ + +/* %endif */ + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +/* %if-c-only */ +/* %not-for-header */ + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +#ifndef hyy_create_buffer_ALREADY_DEFINED +#undef yy_create_buffer +#endif +#ifndef hyy_delete_buffer_ALREADY_DEFINED +#undef yy_delete_buffer +#endif +#ifndef hyy_scan_buffer_ALREADY_DEFINED +#undef yy_scan_buffer +#endif +#ifndef hyy_scan_string_ALREADY_DEFINED +#undef yy_scan_string +#endif +#ifndef hyy_scan_bytes_ALREADY_DEFINED +#undef yy_scan_bytes +#endif +#ifndef hyy_init_buffer_ALREADY_DEFINED +#undef yy_init_buffer +#endif +#ifndef hyy_flush_buffer_ALREADY_DEFINED +#undef yy_flush_buffer +#endif +#ifndef hyy_load_buffer_state_ALREADY_DEFINED +#undef yy_load_buffer_state +#endif +#ifndef hyy_switch_to_buffer_ALREADY_DEFINED +#undef yy_switch_to_buffer +#endif +#ifndef hyypush_buffer_state_ALREADY_DEFINED +#undef yypush_buffer_state +#endif +#ifndef hyypop_buffer_state_ALREADY_DEFINED +#undef yypop_buffer_state +#endif +#ifndef hyyensure_buffer_stack_ALREADY_DEFINED +#undef yyensure_buffer_stack +#endif +#ifndef hyylex_ALREADY_DEFINED +#undef yylex +#endif +#ifndef hyyrestart_ALREADY_DEFINED +#undef yyrestart +#endif +#ifndef hyylex_init_ALREADY_DEFINED +#undef yylex_init +#endif +#ifndef hyylex_init_extra_ALREADY_DEFINED +#undef yylex_init_extra +#endif +#ifndef hyylex_destroy_ALREADY_DEFINED +#undef yylex_destroy +#endif +#ifndef hyyget_debug_ALREADY_DEFINED +#undef yyget_debug +#endif +#ifndef hyyset_debug_ALREADY_DEFINED +#undef yyset_debug +#endif +#ifndef hyyget_extra_ALREADY_DEFINED +#undef yyget_extra +#endif +#ifndef hyyset_extra_ALREADY_DEFINED +#undef yyset_extra +#endif +#ifndef hyyget_in_ALREADY_DEFINED +#undef yyget_in +#endif +#ifndef hyyset_in_ALREADY_DEFINED +#undef yyset_in +#endif +#ifndef hyyget_out_ALREADY_DEFINED +#undef yyget_out +#endif +#ifndef hyyset_out_ALREADY_DEFINED +#undef yyset_out +#endif +#ifndef hyyget_leng_ALREADY_DEFINED +#undef yyget_leng +#endif +#ifndef hyyget_text_ALREADY_DEFINED +#undef yyget_text +#endif +#ifndef hyyget_lineno_ALREADY_DEFINED +#undef yyget_lineno +#endif +#ifndef hyyset_lineno_ALREADY_DEFINED +#undef yyset_lineno +#endif +#ifndef hyyget_column_ALREADY_DEFINED +#undef yyget_column +#endif +#ifndef hyyset_column_ALREADY_DEFINED +#undef yyset_column +#endif +#ifndef hyywrap_ALREADY_DEFINED +#undef yywrap +#endif +#ifndef hyyget_lval_ALREADY_DEFINED +#undef yyget_lval +#endif +#ifndef hyyset_lval_ALREADY_DEFINED +#undef yyset_lval +#endif +#ifndef hyyget_lloc_ALREADY_DEFINED +#undef yyget_lloc +#endif +#ifndef hyyset_lloc_ALREADY_DEFINED +#undef yyset_lloc +#endif +#ifndef hyyalloc_ALREADY_DEFINED +#undef yyalloc +#endif +#ifndef hyyrealloc_ALREADY_DEFINED +#undef yyrealloc +#endif +#ifndef hyyfree_ALREADY_DEFINED +#undef yyfree +#endif +#ifndef hyytext_ALREADY_DEFINED +#undef yytext +#endif +#ifndef hyyleng_ALREADY_DEFINED +#undef yyleng +#endif +#ifndef hyyin_ALREADY_DEFINED +#undef yyin +#endif +#ifndef hyyout_ALREADY_DEFINED +#undef yyout +#endif +#ifndef hyy_flex_debug_ALREADY_DEFINED +#undef yy_flex_debug +#endif +#ifndef hyylineno_ALREADY_DEFINED +#undef yylineno +#endif +#ifndef hyytables_fload_ALREADY_DEFINED +#undef yytables_fload +#endif +#ifndef hyytables_destroy_ALREADY_DEFINED +#undef yytables_destroy +#endif +#ifndef hyyTABLES_NAME_ALREADY_DEFINED +#undef yyTABLES_NAME +#endif + +#line 401 "hyp_l.l" + + +#line 825 "hyp_l.h" +#undef hyyIN_HEADER +#endif /* hyyHEADER_H */ Index: tags/2.3.0/src_plugins/io_hyp/hyp_l.l =================================================================== --- tags/2.3.0/src_plugins/io_hyp/hyp_l.l (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/hyp_l.l (revision 33253) @@ -0,0 +1,425 @@ + +/* + * read hyperlynx files + * Copyright 2012, 2016 Koen De Vleeschauwer. + * + * This file is part of pcb-rnd. + * + * 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, see . + */ + +%option noyywrap nodefault yylineno debug + +/* avoid collision with other scanners */ +%option prefix="hyy" + +%{ +#include + +char *rnd_strdup(const char *s); /* from #include */ + +#include "hyp_y.h" + +/* copy a string between quotes */ +char *strunquote(const char *); + +/* print error message */ +void hyyerror(const char *); + +/* remember hyperlynx file section we're in */ +int section = -1; + +%} + + /* + * The scanner knows five states: INITIAL, STATE_STRING, STATE_POSINT, STATE_FLOAT and STATE_COMMENT + * + * In state INITIAL the scanner recognizes: + * - punctuation (such as {}()=, ) + * - keywords (such as VERSION, BOARD, NET), + * - strings (both between double quotes " and unquoted), + * - and floating point numbers (with optional suffix, eg. 10 uF), + * + * In STATE_STRING the scanner recognizes punctuation and strings only. + * This avoids unquoted strings being interpreted as numbers, or keywords. + * + * In STATE_POSINT the scanner recognizes a positive integer. + * + * In STATE_FLOAT the scanner recognizes a floating point number (without suffix). + * + * In STATE_COMMENT the scanner discards all text up to the next + * right brace } , and then continues in state INITIAL. + * + */ + +%x STATE_STRING STATE_POSINT STATE_FLOAT STATE_COMMENT STATE_COMMENT_EOL + + /* whitespace: space, tab, vertical tab, form feed */ +WS [ \t\v\f] + + /* accept windows and unix newlines */ +NEWLINE [\r\n]+ + + /* + * lines with an asterisk in the first column are comments + */ +COMMENT ^\*[^\n\r]*[\n\r]+ + + /* Left-hand side of an assignment: check whether next token is equals sign */ +LHS [ \t\v\f]*"=" + + /* + * Positive integer + */ + +POSINT [0-9]+ + + /* + * Floating point numbers + */ + + /* ordinary floating point numbers */ +SIMPLE_FLOAT [-+]?([0-9]+"."[0-9]*|"."?[0-9]+)([Ee][-+]?[0-9]+)? + + /* floating point numbers with suffix, e,g. pF, nH */ +FLOAT_SUFFIX [A-Za-z]*{WS}+ +FLOAT_YOTTA {SIMPLE_FLOAT}{WS}*"Y"{FLOAT_SUFFIX} +FLOAT_ZETA {SIMPLE_FLOAT}{WS}*"Z"{FLOAT_SUFFIX} +FLOAT_EXA {SIMPLE_FLOAT}{WS}*"E"{FLOAT_SUFFIX} +FLOAT_PETA {SIMPLE_FLOAT}{WS}*"P"{FLOAT_SUFFIX} +FLOAT_TERA {SIMPLE_FLOAT}{WS}*"T"{FLOAT_SUFFIX} +FLOAT_GIGA {SIMPLE_FLOAT}{WS}*"G"{FLOAT_SUFFIX} +FLOAT_MEGA {SIMPLE_FLOAT}{WS}*"M"{FLOAT_SUFFIX} +FLOAT_KILO {SIMPLE_FLOAT}{WS}*[Kk]{FLOAT_SUFFIX} +FLOAT_MILLI {SIMPLE_FLOAT}{WS}*"m"{FLOAT_SUFFIX} +FLOAT_MICRO {SIMPLE_FLOAT}{WS}*[uU]{FLOAT_SUFFIX} +FLOAT_NANO {SIMPLE_FLOAT}{WS}*[nN]{FLOAT_SUFFIX} +FLOAT_PICO {SIMPLE_FLOAT}{WS}*[pP]{FLOAT_SUFFIX} +FLOAT_FEMTO {SIMPLE_FLOAT}{WS}*[fF]{FLOAT_SUFFIX} +FLOAT_ATTO {SIMPLE_FLOAT}{WS}*"a"{FLOAT_SUFFIX} +FLOAT_ZEPTO {SIMPLE_FLOAT}{WS}*"z"{FLOAT_SUFFIX} +FLOAT_YOCTO {SIMPLE_FLOAT}{WS}*"y"{FLOAT_SUFFIX} + + /* + * Strings + */ + + /* an unquoted string */ + /* a sequence of characters, excluding whitespace and reserved characters. + * also allow strings such as "(Net0)" . + */ +STRING [^ \t\v\f\r\n\{\}\(\)=\"]+|"("[[:alnum:]]+")" + + /* a string enclosed in double quotes " */ +QUOTED_STRING \"([^\"\n]|\"\")*\" + +/* an unquoted string with spaces */ +CHARS_AND_SPACES [^\t\v\f\r\n\{\}\(\)=\"]+ + +/* all variables used in assignments */ +VARIABLE ("A"|"A1"|"A2"|"BR"|"C"|"C\?"|"CO\?"|"D"|"ER"|"F"|"ID"|"L"|"L1"|"L2"|"LPS"|"LT"|"M"|"N"|"NAME"|"P"|"PKG"|"PR\?"|"PS"|"R"|"REF"|"S"|"SX"|"SY"|"S1"|"S1X"|"S1Y"|"S2"|"S2X"|"S2Y"|"T"|"TC"|"USE_DIE_FOR_METAL"|"V"|"V\?"|"VAL"|"W"|"X"|"X1"|"X2"|"XC"|"Y"|"Y1"|"Y2"|"YC"|"Z"|"ZL"|"ZLEN"|"ZW") + +/* an unquoted string with spaces is terminated by the next assignment or the end of line */ +STRING_W_SPACES {CHARS_AND_SPACES}(" "{VARIABLE}"=")? + +/* an empty string is terminated by the next assignment, a ')' or a '}' */ +EMPTY_STRING ({WS}{VARIABLE}"="|")"|"}") + +%% + + /* When in STATE_COMMENT skip all comment until next right brace */ +{ +[^\}]* { BEGIN INITIAL; /* skip all comment until next right brace */ } +} + + /* When in STATE_COMMENT_EOL skip all comment until end-of-line */ +{ +[^\r\n]*{NEWLINE}+ { BEGIN INITIAL; /* skip all comment until next end-of-line */ } +} + + + /* skip comments and whitespace */ +<*>{ + + {COMMENT} { /* skip comments */ } + + {WS}+ { /* skip whitespace */ } + + {NEWLINE}+ { /* skip newlines */ } + +} + + /* + * Hyperlynx keywords + */ + + /* Sections */ + +"BOARD_FILE" {section = H_BOARD_FILE; return H_BOARD_FILE;} +"VERSION" {section = H_VERSION; return H_VERSION;} +"DATA_MODE" {section = H_DATA_MODE; return H_DATA_MODE;} +"UNITS" {section = H_UNITS; return H_UNITS;} +"PLANE_SEP" {section = H_PLANE_SEP; return H_PLANE_SEP;} +"BOARD" {section = H_BOARD; BEGIN STATE_COMMENT_EOL; return H_BOARD;} +"STACKUP" {section = H_STACKUP; BEGIN STATE_COMMENT_EOL; return H_STACKUP;} +"DEVICES" {section = H_DEVICES; BEGIN STATE_COMMENT_EOL; return H_DEVICES;} +"SUPPLIES" {section = H_SUPPLIES; BEGIN STATE_COMMENT_EOL; return H_SUPPLIES;} +"PADSTACK" {section = H_PADSTACK; BEGIN STATE_STRING; return H_PADSTACK;} +"NET" {section = H_NET; BEGIN STATE_STRING; return H_NET;} +"NET_CLASS" {section = H_NET_CLASS; return H_NET_CLASS;} +"END" {section = H_END; return H_END;} +"KEY" {section = H_KEY; return H_KEY;} + + /* Keywords */ + +"A" {return H_A;} +"ARC" {return H_ARC;} +"COPPER" {return H_COPPER;} +"CURVE" {return H_CURVE;} +"DETAILED" {if (section == H_DATA_MODE) BEGIN STATE_COMMENT; return H_DETAILED;} +"DIELECTRIC" {return H_DIELECTRIC;} +"ENGLISH" {return H_ENGLISH;} +"LENGTH" {if (section == H_UNITS) BEGIN STATE_COMMENT; return H_LENGTH;} +"LINE" {return H_LINE;} +"METRIC" {return H_METRIC;} +"M" {return H_M;} +"N" {return H_N;} +"OPTIONS" {return H_OPTIONS;} +"PAD" {return H_PAD;} +"PERIMETER_ARC" {return H_PERIMETER_ARC;} +"PERIMETER_SEGMENT" {return H_PERIMETER_SEGMENT;} +"PIN" {return H_PIN;} +"PLANE" {return H_PLANE;} +"POLYGON" {return H_POLYGON;} +"POLYLINE" {return H_POLYLINE;} +"POLYVOID" {return H_POLYVOID;} +"POUR" {return H_POUR;} +"S" {return H_S;} +"T" {return H_T;} +"SEG" {return H_SEG;} +"SIGNAL" {return H_SIGNAL;} +"SIMPLIFIED" {if (section == H_DATA_MODE) BEGIN STATE_COMMENT; return H_SIMPLIFIED; } +"SIM_BOTH" {return H_SIM_BOTH;} +"SIM_IN" {return H_SIM_IN;} +"SIM_OUT" {return H_SIM_OUT;} +"USEG" {return H_USEG;} +"VIA" {return H_VIA;} +"WEIGHT" {if (section == H_UNITS) BEGIN STATE_COMMENT; return H_WEIGHT;} + + /* Assignments */ + +"A"/{LHS} {return H_A;} +"A1"/{LHS} {return H_A1;} +"A2"/{LHS} {return H_A2;} +"BR"/{LHS} {return H_BR;} +"C"/{LHS} {return H_C;} +"C?"/{LHS} {return H_C_QM;} +"CO?"/{LHS} {return H_CO_QM;} +"D"/{LHS} {return H_D;} +"ER"/{LHS} {return H_ER;} +"F"/{LHS} {return H_F;} +"ID"/{LHS} {BEGIN STATE_POSINT; return H_ID;} +"L"/{LHS} {BEGIN STATE_STRING; return H_L;} +"L1"/{LHS} {BEGIN STATE_STRING; return H_L1;} +"L2"/{LHS} {BEGIN STATE_STRING; return H_L2;} +"LPS"/{LHS} {return H_LPS;} +"LT"/{LHS} {return H_LT;} +"M"/{LHS} {BEGIN STATE_STRING; return H_M;} +"N"/{LHS} {BEGIN STATE_STRING; return H_N;} +"NAME"/{LHS} {BEGIN STATE_STRING; return H_NAME;} + /* P is used as "plating thickness" in "stackup/signal" and as "padstack" in "net/via" */ +"P"/{LHS} {if (section == H_NET) BEGIN STATE_STRING; return H_P;} +"PKG"/{LHS} {BEGIN STATE_STRING; return H_PKG;} +"PR?"/{LHS} {return H_PR_QM;} +"PS"/{LHS} {return H_PS;} +"R"/{LHS} {return H_R;} +"REF"/{LHS} {BEGIN STATE_STRING; return H_REF;} +"S"/{LHS} {BEGIN STATE_STRING; return H_S;} +"SX"/{LHS} {return H_SX;} +"SY"/{LHS} {return H_SY;} +"S1"/{LHS} {BEGIN STATE_STRING; return H_S1;} +"S1X"/{LHS} {return H_S1X;} +"S1Y"/{LHS} {return H_S1Y;} +"S2"/{LHS} {BEGIN STATE_STRING; return H_S2;} +"S2X"/{LHS} {return H_S2X;} +"S2Y"/{LHS} {return H_S2Y;} +"T"/{LHS} {return H_T;} +"TC"/{LHS} {return H_TC;} +"USE_DIE_FOR_METAL"/{LHS} {return H_USE_DIE_FOR_METAL;} +"V"/{LHS} {BEGIN STATE_STRING; return H_V;} +"V?"/{LHS} {return H_V_QM;} +"VAL"/{LHS} {if (section == H_DEVICES) BEGIN STATE_STRING; return H_VAL;} +"W"/{LHS} {return H_W;} +"X"/{LHS} {return H_X;} +"X1"/{LHS} {return H_X1;} +"X2"/{LHS} {return H_X2;} +"XC"/{LHS} {return H_XC;} +"Y"/{LHS} {return H_Y;} +"Y1"/{LHS} {return H_Y1;} +"Y2"/{LHS} {return H_Y2;} +"YC"/{LHS} {return H_YC;} +"Z"/{LHS} {return H_Z;} +"ZL"/{LHS} {BEGIN STATE_STRING; return H_ZL;} +"ZLEN"/{LHS} {return H_ZLEN;} +"ZW"/{LHS} {return H_ZW;} + + /* Booleans */ + +"YES"|"yes" {hyylval.boolval = 1; return H_BOOL; } +"NO"|"no" {hyylval.boolval = 0; return H_BOOL; } + + /* Floats */ + + /* ordinary floating point numbers */ +{SIMPLE_FLOAT} {hyylval.floatval = strtod(hyytext, NULL); return H_FLOAT;} + + /* floating point numbers with suffix, e,g. pF, nH */ +{FLOAT_YOTTA} {hyylval.floatval = strtod(hyytext, NULL) * 1e24; return H_FLOAT;} +{FLOAT_ZETA} {hyylval.floatval = strtod(hyytext, NULL) * 1e21; return H_FLOAT;} +{FLOAT_EXA} {hyylval.floatval = strtod(hyytext, NULL) * 1e18; return H_FLOAT;} +{FLOAT_PETA} {hyylval.floatval = strtod(hyytext, NULL) * 1e15; return H_FLOAT;} +{FLOAT_TERA} {hyylval.floatval = strtod(hyytext, NULL) * 1e12; return H_FLOAT;} +{FLOAT_GIGA} {hyylval.floatval = strtod(hyytext, NULL) * 1e9; return H_FLOAT;} +{FLOAT_MEGA} {hyylval.floatval = strtod(hyytext, NULL) * 1e6; return H_FLOAT;} +{FLOAT_KILO} {hyylval.floatval = strtod(hyytext, NULL) * 1e3; return H_FLOAT;} +{FLOAT_MILLI} {hyylval.floatval = strtod(hyytext, NULL) * 1e-3; return H_FLOAT;} +{FLOAT_MICRO} {hyylval.floatval = strtod(hyytext, NULL) * 1e-6; return H_FLOAT;} +{FLOAT_NANO} {hyylval.floatval = strtod(hyytext, NULL) * 1e-9; return H_FLOAT;} +{FLOAT_PICO} {hyylval.floatval = strtod(hyytext, NULL) * 1e-12; return H_FLOAT;} +{FLOAT_FEMTO} {hyylval.floatval = strtod(hyytext, NULL) * 1e-15; return H_FLOAT;} +{FLOAT_ATTO} {hyylval.floatval = strtod(hyytext, NULL) * 1e-18; return H_FLOAT;} +{FLOAT_ZEPTO} {hyylval.floatval = strtod(hyytext, NULL) * 1e-21; return H_FLOAT;} +{FLOAT_YOCTO} {hyylval.floatval = strtod(hyytext, NULL) * 1e-24; return H_FLOAT;} + + /* floating point numbers in VERSION and PLANE_SEP have no suffix and are followed by optional comments */ +{ +{SIMPLE_FLOAT} {hyylval.floatval = strtod(hyytext, NULL); BEGIN STATE_COMMENT; return H_FLOAT;} +} + + /* A positive integer is used only in polygon/polyline/polyvoid "ID = posint" */ +{ +{POSINT} { BEGIN INITIAL; hyylval.intval = atoi(hyytext); return H_POSINT; } +} + + + /* + * This is a workaround for syntactically incorrect .hyp files. + * We accept the following constructs as representing an empty string: + * NAME= L1=somelayer + * NAME= ) + * NAME= } + * and we accept the following constructs as representing "a string with spaces" + * NAME=a string with spaces L1=somelayer + */ +{ + +{EMPTY_STRING} { yyless(0); BEGIN INITIAL; hyylval.strval = rnd_strdup(""); return H_STRING; } /* emit empty string and reprocess */ + +{STRING_W_SPACES} { + /* + * Commas are not allowed in strings in the padstack section unless the string is enclosed in double quotes ("). + */ + + if ((section == H_PADSTACK) && strchr(hyytext, ',')) + REJECT + else + { + char *s = rnd_strdup(hyytext); + + BEGIN INITIAL; + + /* strip final ' VAR=' */ + if ((strlen(s) != 0) && (s[strlen(s)-1] == '=')) { + char* space = strrchr(s, ' '); + /* strip trailing spaces */ + if (space != NULL) + while ((space >= s) && (*space == ' ')) *space-- = '\0'; + yyless(strlen(s)); + if (strchr(s, ' ') != NULL) hyyerror("warning: unquoted string contains space"); + } + + hyylval.strval = s; + + return H_STRING; + } + } +} + +<*>{ + + "{" {return '{';} + + "}" {BEGIN STATE_COMMENT_EOL; return '}';} + + "(" {if (section == H_PADSTACK) BEGIN STATE_STRING; return '(';} + + /* allow for comment after the closing bracket ) */ + ")" {BEGIN STATE_COMMENT_EOL; return ')';} + + "," {return ',';} + + "=" {if ((section == H_VERSION) || (section == H_PLANE_SEP)) BEGIN STATE_FLOAT; return '=';} + + /* string */ + {STRING} { + /* + * Commas are not allowed in strings in the padstack section unless the string is enclosed in double quotes ("). + */ + + if ((section == H_PADSTACK) && strchr(hyytext, ',')) + REJECT + else + { + BEGIN INITIAL; + hyylval.strval = rnd_strdup(hyytext); + return H_STRING; + } + } + + /* string in double quotes */ + {QUOTED_STRING} {BEGIN INITIAL; hyylval.strval = strunquote(hyytext); return H_STRING;} + + <> {yyterminate();} + + /* have bison catch all unrecognized characters with parse errors */ + . {return hyytext[0];} + +} + +%% + + /* + * copy a quoted string. + * e.g. "data 0" -> data 0 + * a double quote inside the string can be escaped by writing two consecutive double quotes + * e.g. "net ""hi""" -> net "hi" + */ + + char *strunquote(const char *src) + { + char* dst; + size_t len = strlen(src) + 1; + dst = (char *)malloc(len); + if (dst != NULL) + { + char* p = (char *)src + 1; /* first char after initial quote */ + char* q = dst; + do + if (*p == '"') p++; + while ((*q++ = *p++) != '\0'); + } + return dst; + } + + /* not truncated */ Index: tags/2.3.0/src_plugins/io_hyp/hyp_y.c =================================================================== --- tags/2.3.0/src_plugins/io_hyp/hyp_y.c (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/hyp_y.c (revision 33253) @@ -0,0 +1,3197 @@ +/* A Bison parser, made by GNU Bison 3.3.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. + + 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 3 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, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.3.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Substitute the type names. */ +#define YYSTYPE HYYSTYPE +/* Substitute the variable and function names. */ +#define yyparse hyyparse +#define yylex hyylex +#define yyerror hyyerror +#define yydebug hyydebug +#define yynerrs hyynerrs + +#define yylval hyylval +#define yychar hyychar + + +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "hyp_y.h". */ +#ifndef YY_HYY_HYP_Y_H_INCLUDED +# define YY_HYY_HYP_Y_H_INCLUDED +/* Debug traces. */ +#ifndef HYYDEBUG +# if defined YYDEBUG +#if YYDEBUG +# define HYYDEBUG 1 +# else +# define HYYDEBUG 0 +# endif +# else /* ! defined YYDEBUG */ +# define HYYDEBUG 1 +# endif /* ! defined YYDEBUG */ +#endif /* ! defined HYYDEBUG */ +#if HYYDEBUG +extern int hyydebug; +#endif +/* "%code requires" blocks. */ +#line 21 "hyp_y.y" /* yacc.c:352 */ + +#include "parser.h" + +#line 123 "hyp_y.c" /* yacc.c:352 */ + +/* Token type. */ +#ifndef HYYTOKENTYPE +# define HYYTOKENTYPE + enum hyytokentype + { + H_BOARD_FILE = 258, + H_VERSION = 259, + H_DATA_MODE = 260, + H_UNITS = 261, + H_PLANE_SEP = 262, + H_BOARD = 263, + H_STACKUP = 264, + H_DEVICES = 265, + H_SUPPLIES = 266, + H_PAD = 267, + H_PADSTACK = 268, + H_NET = 269, + H_NET_CLASS = 270, + H_END = 271, + H_KEY = 272, + H_A = 273, + H_ARC = 274, + H_COPPER = 275, + H_CURVE = 276, + H_DETAILED = 277, + H_DIELECTRIC = 278, + H_ENGLISH = 279, + H_LENGTH = 280, + H_LINE = 281, + H_METRIC = 282, + H_N = 283, + H_OPTIONS = 284, + H_PERIMETER_ARC = 285, + H_PERIMETER_SEGMENT = 286, + H_PIN = 287, + H_PLANE = 288, + H_POLYGON = 289, + H_POLYLINE = 290, + H_POLYVOID = 291, + H_POUR = 292, + H_S = 293, + H_SEG = 294, + H_SIGNAL = 295, + H_SIMPLIFIED = 296, + H_SIM_BOTH = 297, + H_SIM_IN = 298, + H_SIM_OUT = 299, + H_USEG = 300, + H_VIA = 301, + H_WEIGHT = 302, + H_A1 = 303, + H_A2 = 304, + H_BR = 305, + H_C = 306, + H_C_QM = 307, + H_CO_QM = 308, + H_D = 309, + H_ER = 310, + H_F = 311, + H_ID = 312, + H_L = 313, + H_L1 = 314, + H_L2 = 315, + H_LPS = 316, + H_LT = 317, + H_M = 318, + H_NAME = 319, + H_P = 320, + H_PKG = 321, + H_PR_QM = 322, + H_PS = 323, + H_R = 324, + H_REF = 325, + H_SX = 326, + H_SY = 327, + H_S1 = 328, + H_S1X = 329, + H_S1Y = 330, + H_S2 = 331, + H_S2X = 332, + H_S2Y = 333, + H_T = 334, + H_TC = 335, + H_USE_DIE_FOR_METAL = 336, + H_V = 337, + H_V_QM = 338, + H_VAL = 339, + H_W = 340, + H_X = 341, + H_X1 = 342, + H_X2 = 343, + H_XC = 344, + H_Y = 345, + H_Y1 = 346, + H_Y2 = 347, + H_YC = 348, + H_Z = 349, + H_ZL = 350, + H_ZLEN = 351, + H_ZW = 352, + H_YES = 353, + H_NO = 354, + H_BOOL = 355, + H_POSINT = 356, + H_FLOAT = 357, + H_STRING = 358 + }; +#endif + +/* Value type. */ +#if ! defined HYYSTYPE && ! defined HYYSTYPE_IS_DECLARED + +union HYYSTYPE +{ +#line 30 "hyp_y.y" /* yacc.c:352 */ + + int boolval; + int intval; + double floatval; + char* strval; + +#line 246 "hyp_y.c" /* yacc.c:352 */ +}; + +typedef union HYYSTYPE HYYSTYPE; +# define HYYSTYPE_IS_TRIVIAL 1 +# define HYYSTYPE_IS_DECLARED 1 +#endif + + +extern HYYSTYPE hyylval; + +int hyyparse (void); + +#endif /* !YY_HYY_HYP_Y_H_INCLUDED */ + +/* Second part of user prologue. */ +#line 37 "hyp_y.y" /* yacc.c:354 */ + +#include +#include +#include +#include +#include "hyp_l.h" + +void hyyerror(const char *); + +/* HYYPRINT and hyyprint print values of the tokens when debugging is switched on */ +void hyyprint(FILE *, int, HYYSTYPE); +#define HYYPRINT(file, type, value) hyyprint (file, type, value) + +/* clear parse_param struct at beginning of new record */ +static void new_record(); + +/* struct to pass to calling class */ +static parse_param h; + + +#line 283 "hyp_y.c" /* yacc.c:354 */ + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined HYYSTYPE_IS_TRIVIAL && HYYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 34 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 769 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 110 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 179 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 311 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 620 + +#define YYUNDEFTOK 2 +#define YYMAXUTOK 358 + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 107, 108, 2, 2, 109, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 106, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 105, 2, 104, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103 +}; + +#if HYYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 128, 128, 129, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 151, + 151, 156, 156, 161, 164, 165, 170, 173, 174, 177, + 178, 182, 182, 187, 188, 191, 192, 195, 196, 197, + 201, 202, 203, 206, 209, 212, 212, 212, 217, 220, + 221, 224, 225, 226, 227, 228, 231, 234, 234, 235, + 239, 239, 242, 243, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 258, 258, 261, 262, 265, 266, + 267, 268, 269, 270, 271, 272, 276, 276, 279, 280, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 294, + 297, 300, 303, 306, 309, 312, 315, 318, 321, 324, + 329, 330, 333, 334, 337, 337, 337, 337, 338, 341, + 342, 346, 347, 351, 352, 356, 359, 360, 364, 367, + 370, 375, 378, 379, 382, 383, 386, 389, 394, 394, + 394, 397, 397, 398, 399, 402, 403, 406, 406, 407, + 410, 410, 411, 415, 415, 415, 418, 419, 420, 421, + 422, 423, 424, 421, 431, 431, 434, 434, 435, 439, + 440, 440, 444, 445, 448, 449, 450, 451, 452, 453, + 454, 455, 456, 457, 458, 459, 463, 463, 466, 466, + 469, 470, 474, 475, 479, 482, 485, 485, 489, 490, + 494, 496, 497, 498, 499, 500, 501, 502, 503, 504, + 505, 506, 507, 508, 509, 510, 514, 517, 520, 523, + 523, 526, 527, 531, 532, 536, 539, 540, 541, 542, + 546, 546, 549, 550, 554, 555, 556, 557, 558, 562, + 562, 565, 566, 570, 571, 572, 570, 577, 578, 577, + 582, 582, 584, 588, 588, 588, 592, 593, 597, 598, + 599, 600, 604, 608, 609, 610, 614, 614, 614, 618, + 618, 618, 622, 623, 627, 628, 629, 630, 634, 634, + 637, 637, 640, 640, 640, 645, 645, 648, 649, 653, + 654, 658, 659, 660, 664, 664, 667, 667, 667, 672, + 677, 677, 682, 682, 685, 685, 688, 688, 691, 694, + 694, 694 +}; +#endif + +#if HYYDEBUG || YYERROR_VERBOSE || 1 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "H_BOARD_FILE", "H_VERSION", + "H_DATA_MODE", "H_UNITS", "H_PLANE_SEP", "H_BOARD", "H_STACKUP", + "H_DEVICES", "H_SUPPLIES", "H_PAD", "H_PADSTACK", "H_NET", "H_NET_CLASS", + "H_END", "H_KEY", "H_A", "H_ARC", "H_COPPER", "H_CURVE", "H_DETAILED", + "H_DIELECTRIC", "H_ENGLISH", "H_LENGTH", "H_LINE", "H_METRIC", "H_N", + "H_OPTIONS", "H_PERIMETER_ARC", "H_PERIMETER_SEGMENT", "H_PIN", + "H_PLANE", "H_POLYGON", "H_POLYLINE", "H_POLYVOID", "H_POUR", "H_S", + "H_SEG", "H_SIGNAL", "H_SIMPLIFIED", "H_SIM_BOTH", "H_SIM_IN", + "H_SIM_OUT", "H_USEG", "H_VIA", "H_WEIGHT", "H_A1", "H_A2", "H_BR", + "H_C", "H_C_QM", "H_CO_QM", "H_D", "H_ER", "H_F", "H_ID", "H_L", "H_L1", + "H_L2", "H_LPS", "H_LT", "H_M", "H_NAME", "H_P", "H_PKG", "H_PR_QM", + "H_PS", "H_R", "H_REF", "H_SX", "H_SY", "H_S1", "H_S1X", "H_S1Y", "H_S2", + "H_S2X", "H_S2Y", "H_T", "H_TC", "H_USE_DIE_FOR_METAL", "H_V", "H_V_QM", + "H_VAL", "H_W", "H_X", "H_X1", "H_X2", "H_XC", "H_Y", "H_Y1", "H_Y2", + "H_YC", "H_Z", "H_ZL", "H_ZLEN", "H_ZW", "H_YES", "H_NO", "H_BOOL", + "H_POSINT", "H_FLOAT", "H_STRING", "'}'", "'{'", "'='", "'('", "')'", + "','", "$accept", "hyp_file", "hyp_section", "board_file", "$@1", + "version", "$@2", "data_mode", "mode", "units", "unit_system", + "metal_thickness_unit", "plane_sep", "$@3", "board", "board_param_list", + "board_param_list_item", "board_param", "perimeter_segment", + "perimeter_arc", "board_attribute", "$@4", "$@5", "stackup", + "stackup_paramlist", "stackup_param", "options", "options_params", "$@6", + "signal", "$@7", "signal_paramlist", "signal_param", "dielectric", "$@8", + "dielectric_paramlist", "dielectric_param", "plane", "$@9", + "plane_paramlist", "plane_param", "thickness", "plating_thickness", + "bulk_resistivity", "temperature_coefficient", "epsilon_r", + "loss_tangent", "layer_name", "material_name", "plane_separation", + "conformal", "prepreg", "devices", "device_list", "device", "$@10", + "$@11", "$@12", "device_paramlist", "device_value", "device_layer", + "name", "value", "value_float", "value_string", "package", "supplies", + "supply_list", "supply", "voltage_spec", "conversion", "padstack", + "$@13", "$@14", "drill_size", "$@15", "padstack_list", "padstack_def", + "$@16", "pad_shape", "$@17", "pad_coord", "$@18", "$@19", "pad_type", + "$@20", "$@21", "$@22", "$@23", "net", "$@24", "net_separation", "$@25", + "net_copper", "$@26", "net_subrecord_list", "net_subrecord", "seg", + "$@27", "arc", "$@28", "ps_lps_param", "lps_param", "width", + "left_plane_separation", "via", "$@29", "via_param_list", "via_param", + "padstack_name", "layer1_name", "layer2_name", "pin", "$@30", + "pin_param", "pin_function_param", "pin_reference", "pin_function", + "pad", "$@31", "pad_param_list", "pad_param", "useg", "$@32", + "useg_param", "useg_stackup", "$@33", "$@34", "$@35", "useg_impedance", + "$@36", "$@37", "useg_resistance", "$@38", "polygon", "$@39", "$@40", + "polygon_param_list", "polygon_param", "polygon_id", "polygon_type", + "polyvoid", "$@41", "$@42", "polyline", "$@43", "$@44", + "lines_and_curves", "line_or_curve", "line", "$@45", "curve", "$@46", + "net_attribute", "$@47", "$@48", "netclass", "$@49", + "netclass_subrecords", "netclass_paramlist", "netclass_param", + "net_name", "$@50", "netclass_attribute", "$@51", "$@52", "end", "key", + "$@53", "coord_point", "$@54", "coord_point1", "$@55", "coord_point2", + "$@56", "coord_line", "coord_arc", "$@57", "$@58", YY_NULLPTR +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 125, 123, 61, 40, 41, 44 +}; +# endif + +#define YYPACT_NINF -454 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-454))) + +#define YYTABLE_NINF -115 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + 9, -75, 295, 15, -454, -454, -454, -454, -454, -454, + -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, + -454, -65, -31, -20, 5, 8, 30, 120, 74, -454, + 97, 113, -2, 117, -454, -454, 22, 127, 161, 207, + 144, 152, -454, 179, 12, -454, 167, 140, -454, -454, + -454, -454, -454, -454, 18, 181, -454, 47, 188, -454, + 158, 168, 204, -454, 225, -454, -454, -454, -454, 182, + -454, -454, 115, -454, -454, 286, 242, 242, 208, -454, + -454, -454, -454, -454, 222, -454, 28, -454, -454, -454, + -454, 223, 230, -454, -454, 224, 270, -454, -454, 232, + -454, -454, -454, 233, -454, -454, -454, 234, 235, 236, + 237, 248, 251, -454, -454, -454, -454, 210, 238, -454, + -454, 190, 170, -454, -454, -454, 239, 257, -454, -41, + 213, 243, -454, -454, -454, 245, 244, 246, -454, 247, + 249, 250, 252, 253, 254, 255, 256, 258, 122, -454, + -454, -454, -454, -454, -454, -454, -454, 263, 259, 260, + 261, 262, 108, -454, -454, -454, -454, -454, -454, -454, + -454, -454, 264, 265, 26, -454, -454, -454, -454, -454, + -454, -454, -454, -454, -454, 279, 266, 267, 268, 58, + 89, 160, -454, -454, -454, 271, 174, -454, -454, -454, + -454, -454, -454, -454, -454, -454, -454, -454, -454, 146, + -454, 218, -454, -454, -454, -454, -454, -454, 272, 274, + 275, 278, 277, 269, 280, 281, 283, 284, -454, -454, + -454, 285, 287, 288, 289, -454, -454, 290, 291, -454, + -454, 282, -454, 292, 293, 298, 19, 110, 276, 294, + -454, 296, -454, -454, -454, 273, -454, 326, -454, -454, + -454, -454, -454, 88, -454, -454, -454, 297, 329, 357, + -454, -454, 313, 305, -454, -454, -454, -454, -454, -454, + -454, -454, -454, -454, 299, -454, -454, -454, -454, -454, + -454, 300, -454, 302, 303, 304, 306, -454, -454, 294, + -454, -454, -454, 197, 197, 340, -454, 312, 307, 242, + 312, 242, 242, 312, -454, -454, 309, 310, 311, 314, + 316, 317, -454, -454, -454, 318, -454, -454, 315, 294, + 319, 320, 321, -454, -454, 157, -454, -454, -454, 157, + 312, 322, 60, 301, 334, 337, 334, 352, 79, 327, + 328, 330, 332, 323, 331, 85, -454, -62, 294, 335, + 171, 333, -454, -454, -454, -454, 336, 338, 339, 341, + 342, -454, 21, -454, -454, 363, 343, -5, 363, 344, + 248, 345, 346, 347, 348, 349, 350, 351, 353, 354, + 355, 356, 358, 359, 360, 361, -4, -454, -454, -454, + -454, -454, -454, -454, -454, 366, 367, 364, 373, 324, + -454, -454, -22, 363, -454, -454, -454, -454, 369, -454, + -454, -454, -454, -454, 159, 159, 159, -454, 370, 371, + 374, 375, -454, -454, 376, -43, 372, 377, -454, -28, + -454, -454, 365, -43, 378, 362, 380, 381, 383, 384, + 385, 386, 387, 389, 390, 391, 393, 394, 395, 397, + 398, -454, -454, 396, 399, -454, -454, -454, 172, 382, + -454, -454, -454, -454, 388, -454, 185, 109, -454, 176, + -454, -454, -454, 183, 211, 403, -454, -454, -454, -454, + 400, 402, -454, -8, -454, -454, 401, -454, -21, -454, + -454, -454, -454, 229, -454, -454, -454, -454, -454, -454, + -454, -454, -454, -454, -454, -454, -454, -454, -454, 404, + -454, 410, -454, 408, -454, 392, -454, -6, -454, 405, + -454, -454, -454, -454, -454, -454, 406, 411, 413, -454, + -454, -454, -454, -454, -454, 412, 414, -454, -454, -454, + 416, 415, -454, 420, 409, 417, -454, -454, 242, 312, + 421, -454, -454, 422, 423, -454, 425, -454, -454, -454, + 407, 424, 426, -454, 427, -454, -454, 428, -454, 419, + 429, -454, -454, -454, 448, 432, -454, 431, -454, 433, + 434, -454, 435, 436, 439, 440, -454, -454, -454, -45, + 441, 437, 442, -454, -454, 443, 445, 449, 450, -454, + -454, -454, 444, 446, 447, 451, -454, -454, 452, -454 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint16 yydefact[] = +{ + 0, 0, 0, 0, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 0, 0, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, + 0, 0, 34, 0, 0, 36, 0, 0, 50, 51, + 52, 53, 54, 111, 0, 0, 113, 0, 0, 133, + 0, 0, 0, 299, 0, 20, 21, 25, 24, 0, + 27, 28, 0, 31, 39, 0, 0, 0, 38, 40, + 41, 42, 33, 35, 0, 74, 0, 86, 60, 48, + 49, 0, 0, 110, 112, 0, 0, 131, 132, 0, + 164, 285, 300, 0, 23, 30, 29, 0, 0, 0, + 0, 0, 0, 44, 43, 37, 55, 0, 0, 59, + 56, 0, 0, 118, 115, 135, 0, 0, 139, 170, + 0, 0, 22, 26, 32, 0, 0, 0, 308, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, + 78, 80, 81, 84, 85, 82, 83, 0, 0, 0, + 0, 0, 0, 89, 90, 92, 93, 94, 95, 96, + 97, 98, 0, 0, 0, 63, 64, 65, 67, 68, + 69, 70, 71, 72, 73, 0, 0, 0, 0, 0, + 0, 0, 166, 165, 168, 0, 0, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 288, 0, + 286, 0, 290, 292, 291, 301, 45, 304, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 75, 76, + 57, 0, 0, 0, 0, 87, 88, 0, 0, 61, + 62, 0, 125, 0, 0, 0, 0, 0, 0, 144, + 146, 0, 253, 269, 266, 0, 230, 0, 188, 219, + 186, 239, 196, 170, 171, 169, 172, 0, 0, 0, + 287, 289, 0, 0, 306, 309, 79, 108, 103, 105, + 104, 106, 109, 99, 0, 101, 91, 107, 102, 66, + 100, 0, 128, 0, 0, 0, 0, 147, 141, 143, + 140, 145, 185, 0, 0, 0, 184, 0, 0, 0, + 0, 0, 0, 0, 167, 293, 0, 0, 0, 0, + 0, 0, 58, 116, 136, 0, 134, 149, 0, 0, + 0, 0, 0, 258, 259, 0, 257, 261, 260, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 137, 0, 142, 0, + 0, 0, 256, 254, 270, 267, 0, 0, 0, 0, + 0, 234, 0, 233, 282, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 199, 200, 202, + 203, 296, 294, 46, 305, 0, 0, 0, 124, 0, + 120, 122, 0, 0, 126, 127, 150, 152, 0, 262, + 265, 264, 263, 194, 0, 0, 0, 302, 0, 0, + 0, 0, 231, 232, 0, 0, 0, 0, 224, 0, + 220, 222, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 197, 198, 0, 0, 47, 307, 310, 0, 0, + 123, 117, 119, 121, 0, 153, 0, 0, 276, 0, + 273, 274, 275, 0, 0, 0, 238, 235, 236, 237, + 0, 0, 193, 0, 189, 191, 0, 225, 0, 221, + 223, 187, 217, 0, 207, 204, 211, 215, 201, 218, + 216, 205, 206, 208, 209, 210, 212, 213, 214, 0, + 295, 0, 129, 0, 151, 0, 156, 0, 148, 0, + 280, 278, 255, 272, 271, 268, 0, 0, 0, 190, + 192, 228, 227, 226, 229, 0, 0, 240, 241, 242, + 0, 0, 130, 0, 0, 0, 159, 277, 0, 0, + 0, 283, 195, 0, 0, 297, 0, 154, 158, 157, + 0, 0, 0, 303, 0, 247, 243, 0, 311, 0, + 0, 281, 279, 284, 0, 0, 298, 0, 160, 0, + 0, 155, 0, 0, 0, 0, 248, 244, 161, 0, + 0, 0, 0, 252, 249, 0, 0, 0, 0, 162, + 250, 245, 0, 0, 0, 0, 251, 246, 0, 163 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -454, -454, 438, -454, -454, -454, -454, -454, -454, -454, + -454, -454, -454, -454, -454, -454, 379, -454, -454, -454, + -454, -454, -454, -454, -454, 456, -454, -454, -454, -454, + -454, -454, 418, -454, -454, -454, 430, -454, -454, -454, + 453, -79, -454, -87, -73, -14, 20, -116, 24, -122, + -454, -454, -454, -454, 488, -454, -454, -454, -454, 31, + 27, 87, -454, 454, -454, -454, -454, -454, 487, -454, + -454, -454, -454, -454, -454, -454, -230, -245, -454, -454, + -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, + -454, -454, -454, 200, -454, -454, 308, -454, -454, -454, + -454, 3, -13, -133, -454, -454, -454, -454, 154, 128, + 209, 112, -454, -454, -454, 119, -454, -454, -454, -454, + -454, 187, -454, -454, -454, -454, -454, -454, -454, -454, + -454, -454, -454, -454, -454, -454, -454, 325, -117, 368, + -454, -454, -454, -454, -454, -454, -454, -99, -453, -454, + -454, -454, -454, -454, -454, -454, -454, -454, -454, -454, + 455, -454, -454, -454, -454, -454, -454, -454, -454, -302, + -454, 457, -454, 184, -454, -74, -307, -454, -454 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 3, 4, 5, 36, 6, 103, 7, 69, 8, + 72, 107, 9, 108, 10, 44, 45, 78, 79, 80, + 81, 272, 465, 11, 47, 48, 49, 120, 284, 50, + 122, 174, 175, 51, 117, 148, 149, 52, 121, 162, + 163, 150, 177, 165, 166, 151, 152, 333, 154, 171, + 155, 156, 12, 55, 56, 92, 185, 355, 409, 410, + 411, 127, 413, 414, 415, 470, 13, 58, 59, 245, + 295, 14, 60, 189, 248, 329, 249, 250, 328, 418, + 474, 476, 525, 579, 528, 570, 592, 601, 612, 15, + 129, 193, 263, 194, 195, 196, 197, 198, 311, 199, + 309, 494, 495, 334, 496, 200, 313, 396, 397, 398, + 399, 400, 201, 310, 440, 441, 377, 442, 202, 307, + 372, 373, 203, 312, 547, 548, 585, 600, 614, 549, + 584, 599, 604, 613, 204, 303, 424, 335, 336, 337, + 338, 205, 305, 426, 206, 304, 425, 479, 480, 481, + 559, 482, 558, 207, 434, 574, 16, 130, 210, 211, + 212, 213, 464, 214, 463, 577, 17, 18, 131, 342, + 485, 111, 273, 138, 320, 112, 113, 321, 521 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = +{ + 184, 153, 344, 114, 301, 169, 182, 192, 345, 41, + 1, 348, 554, 41, 381, 34, 1, 299, 491, 91, + 296, 541, 542, 543, 602, 160, 533, 160, 437, 19, + 533, 533, 153, 363, 382, 178, 143, 364, 365, 367, + 416, 37, 164, 176, 383, 384, 169, 417, 95, 179, + 385, 437, 184, 491, 301, 379, 386, 555, 182, 368, + 387, 387, 407, 603, 190, 492, 191, 388, 389, 390, + 391, 392, 393, 394, 395, 38, 158, 172, 367, 143, + 438, 142, 544, 164, 143, 96, 39, 178, 144, 145, + 251, 173, 369, 370, 160, 176, 556, 381, 368, 358, + 492, 179, 63, 438, 461, 147, 161, 167, 180, 118, + 529, 40, 42, 301, 2, 43, 82, 382, 143, 43, + 2, -114, 297, 252, 253, 254, 65, 383, 384, 432, + 530, 369, 370, 385, 239, 531, 119, 46, 379, 386, + 105, 168, 181, 143, 387, 170, 183, 267, 167, 126, + 388, 389, 390, 391, 392, 393, 394, 395, 158, 159, + 180, 255, 106, 142, 268, 246, 143, 247, 84, 407, + 144, 145, 256, 140, 269, 141, 160, 142, 257, 258, + 143, 57, 168, 67, 144, 145, 170, 147, 161, 146, + 85, 420, 259, 190, 181, 191, 86, 75, 183, 260, + 87, 147, 68, 61, 421, 261, 262, 88, 422, 76, + 77, 375, 298, 378, 330, 143, 235, 246, 362, 62, + 158, 172, 362, 64, 53, 142, 371, 54, 143, 66, + 228, 70, 144, 145, 71, 173, 331, 346, 160, 408, + 158, 159, 332, 341, 89, 142, 73, 46, 143, 147, + 161, 571, 144, 145, 330, 143, 371, 572, 160, 435, + 74, 140, 443, 141, 99, 142, 477, 478, 143, 147, + 161, 100, 144, 145, 292, 522, 331, 146, 265, 190, + 532, 191, 332, 477, 478, 93, 104, 534, 54, 147, + 477, 478, 97, 526, 527, 57, 408, 408, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 101, 29, 30, + 31, 32, 33, 493, 109, 535, 115, 208, 477, 478, + 209, 493, 270, 545, 546, 209, 483, 484, 102, 110, + 116, 123, 125, 124, 126, 128, 137, 132, 133, 134, + 139, 187, 135, 136, 157, 186, 217, 215, 216, 241, + 294, 244, 218, 219, 308, 220, 221, 316, 222, 223, + 224, 225, 226, 230, 227, 231, 232, 233, 234, 242, + 237, 238, 279, 243, 274, 264, 275, 276, 277, 278, + 300, 306, 280, 282, 281, 317, 283, 285, 291, 286, + 287, 288, 289, 290, 292, 318, 319, 330, 341, 293, + 302, 246, 324, 323, 374, 315, 376, 322, 353, 325, + 354, 379, 326, 343, 327, 349, 350, 351, 356, 332, + 352, 143, 386, 83, 357, 359, 360, 361, 366, 405, + 401, 402, 471, 403, 404, 423, 419, 406, 427, 469, + 473, 35, 412, 472, 428, 429, 501, 430, 431, 436, + 444, 446, 447, 448, 449, 450, 451, 452, 490, 453, + 454, 455, 456, 314, 457, 458, 459, 460, 466, 467, + 468, 475, 486, 500, 487, 497, 488, 489, 519, 551, + 539, 502, 504, 498, 505, 506, 507, 508, 523, 509, + 510, 511, 512, 536, 513, 514, 515, 524, 516, 517, + 518, 553, 589, 90, 266, 439, 537, 520, 538, 540, + 550, 552, 560, 557, 561, 562, 580, 568, 563, 565, + 564, 566, 567, 573, 575, 569, 576, 578, 587, 590, + 618, 588, 581, 591, 582, 583, 586, 605, 596, 593, + 594, 597, 598, 94, 595, 98, 606, 609, 607, 608, + 462, 610, 611, 615, 616, 617, 380, 503, 499, 433, + 619, 0, 0, 0, 445, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 229, 0, + 0, 188, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 339, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 271, 0, 0, 0, + 0, 0, 0, 340, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 347 +}; + +static const yytype_int16 yycheck[] = +{ + 122, 117, 309, 77, 249, 121, 122, 129, 310, 1, + 1, 313, 18, 1, 18, 0, 1, 247, 61, 1, + 1, 42, 43, 44, 69, 68, 479, 68, 56, 104, + 483, 484, 148, 335, 38, 122, 58, 339, 340, 18, + 102, 106, 121, 122, 48, 49, 162, 109, 1, 122, + 54, 56, 174, 61, 299, 59, 60, 63, 174, 38, + 65, 65, 84, 108, 105, 108, 107, 71, 72, 73, + 74, 75, 76, 77, 78, 106, 50, 51, 18, 58, + 108, 55, 103, 162, 58, 38, 106, 174, 62, 63, + 1, 65, 71, 72, 68, 174, 102, 18, 38, 329, + 108, 174, 104, 108, 108, 79, 80, 121, 122, 81, + 1, 106, 104, 358, 105, 107, 104, 38, 58, 107, + 105, 103, 103, 34, 35, 36, 104, 48, 49, 108, + 21, 71, 72, 54, 108, 26, 108, 107, 59, 60, + 25, 121, 122, 58, 65, 121, 122, 1, 162, 64, + 71, 72, 73, 74, 75, 76, 77, 78, 50, 51, + 174, 1, 47, 55, 18, 107, 58, 109, 1, 84, + 62, 63, 12, 51, 28, 53, 68, 55, 18, 19, + 58, 107, 162, 22, 62, 63, 162, 79, 80, 67, + 23, 20, 32, 105, 174, 107, 29, 18, 174, 39, + 33, 79, 41, 106, 33, 45, 46, 40, 37, 30, + 31, 344, 102, 346, 57, 58, 108, 107, 335, 106, + 50, 51, 339, 106, 104, 55, 342, 107, 58, 102, + 108, 24, 62, 63, 27, 65, 79, 311, 68, 355, + 50, 51, 85, 86, 104, 55, 102, 107, 58, 79, + 80, 558, 62, 63, 57, 58, 372, 559, 68, 375, + 108, 51, 378, 53, 106, 55, 107, 108, 58, 79, + 80, 103, 62, 63, 102, 103, 79, 67, 104, 105, + 104, 107, 85, 107, 108, 104, 104, 104, 107, 79, + 107, 108, 104, 108, 109, 107, 412, 413, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 103, 13, 14, + 15, 16, 17, 435, 28, 104, 108, 104, 107, 108, + 107, 443, 104, 94, 95, 107, 425, 426, 103, 87, + 108, 108, 108, 103, 64, 103, 88, 104, 104, 104, + 89, 84, 106, 106, 106, 106, 102, 104, 103, 70, + 52, 83, 106, 106, 28, 106, 106, 28, 106, 106, + 106, 106, 106, 100, 106, 106, 106, 106, 106, 103, + 106, 106, 103, 106, 102, 104, 102, 102, 100, 102, + 104, 108, 102, 100, 103, 28, 102, 102, 106, 102, + 102, 102, 102, 102, 102, 82, 91, 57, 86, 106, + 104, 107, 100, 103, 103, 108, 69, 108, 92, 106, + 93, 59, 108, 106, 108, 106, 106, 106, 100, 85, + 106, 58, 60, 44, 109, 106, 106, 106, 106, 106, + 103, 103, 108, 103, 102, 102, 101, 106, 102, 66, + 413, 3, 355, 412, 106, 106, 443, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 82, 106, + 106, 106, 106, 263, 106, 106, 106, 106, 102, 102, + 106, 102, 102, 108, 103, 103, 102, 102, 82, 69, + 493, 103, 102, 106, 103, 102, 102, 102, 106, 103, + 103, 102, 102, 90, 103, 102, 102, 109, 103, 102, + 102, 109, 54, 47, 196, 377, 106, 108, 106, 108, + 106, 103, 106, 108, 103, 102, 109, 108, 106, 103, + 106, 106, 102, 102, 102, 108, 103, 102, 109, 97, + 79, 102, 108, 102, 108, 108, 108, 96, 102, 106, + 106, 102, 102, 55, 109, 58, 109, 102, 106, 106, + 396, 102, 102, 109, 108, 108, 347, 445, 439, 372, + 108, -1, -1, -1, 380, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 148, -1, + -1, 127, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 174, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 162, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 304, + -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, 211, -1, -1, -1, + -1, -1, -1, 305, -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, 312 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint16 yystos[] = +{ + 0, 1, 105, 111, 112, 113, 115, 117, 119, 122, + 124, 133, 162, 176, 181, 199, 266, 276, 277, 104, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, + 14, 15, 16, 17, 0, 112, 114, 106, 106, 106, + 106, 1, 104, 107, 125, 126, 107, 134, 135, 136, + 139, 143, 147, 104, 107, 163, 164, 107, 177, 178, + 182, 106, 106, 104, 106, 104, 102, 22, 41, 118, + 24, 27, 120, 102, 108, 18, 30, 31, 127, 128, + 129, 130, 104, 126, 1, 23, 29, 33, 40, 104, + 135, 1, 165, 104, 164, 1, 38, 104, 178, 106, + 103, 103, 103, 116, 104, 25, 47, 121, 123, 28, + 87, 281, 285, 286, 285, 108, 108, 144, 81, 108, + 137, 148, 140, 108, 103, 108, 64, 171, 103, 200, + 267, 278, 104, 104, 104, 106, 106, 88, 283, 89, + 51, 53, 55, 58, 62, 63, 67, 79, 145, 146, + 151, 155, 156, 157, 158, 160, 161, 106, 50, 51, + 68, 80, 149, 150, 151, 153, 154, 155, 156, 157, + 158, 159, 51, 65, 141, 142, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 166, 106, 84, 173, 183, + 105, 107, 159, 201, 203, 204, 205, 206, 207, 209, + 215, 222, 228, 232, 244, 251, 254, 263, 104, 107, + 268, 269, 270, 271, 273, 104, 103, 102, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 108, 146, + 100, 106, 106, 106, 106, 108, 150, 106, 106, 108, + 142, 70, 103, 106, 83, 179, 107, 109, 184, 186, + 187, 1, 34, 35, 36, 1, 12, 18, 19, 32, + 39, 45, 46, 202, 104, 104, 206, 1, 18, 28, + 104, 270, 131, 282, 102, 102, 102, 100, 102, 103, + 102, 103, 100, 102, 138, 102, 102, 102, 102, 102, + 102, 106, 102, 106, 52, 180, 1, 103, 102, 186, + 104, 187, 104, 245, 255, 252, 108, 229, 28, 210, + 223, 208, 233, 216, 203, 108, 28, 28, 82, 91, + 284, 287, 108, 103, 100, 106, 108, 108, 188, 185, + 57, 79, 85, 157, 213, 247, 248, 249, 250, 247, + 249, 86, 279, 106, 286, 279, 285, 281, 279, 106, + 106, 106, 106, 92, 93, 167, 100, 109, 186, 106, + 106, 106, 248, 279, 279, 279, 106, 18, 38, 71, + 72, 157, 230, 231, 103, 213, 69, 226, 213, 59, + 220, 18, 38, 48, 49, 54, 60, 65, 71, 72, + 73, 74, 75, 76, 77, 78, 217, 218, 219, 220, + 221, 103, 103, 103, 102, 106, 106, 84, 157, 168, + 169, 170, 171, 172, 173, 174, 102, 109, 189, 101, + 20, 33, 37, 102, 246, 256, 253, 102, 106, 106, + 106, 106, 108, 231, 264, 157, 106, 56, 108, 219, + 224, 225, 227, 157, 106, 283, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 108, 218, 274, 272, 132, 102, 102, 106, 66, + 175, 108, 169, 170, 190, 102, 191, 107, 108, 257, + 258, 259, 261, 257, 257, 280, 102, 103, 102, 102, + 82, 61, 108, 159, 211, 212, 214, 103, 106, 225, + 108, 211, 103, 221, 102, 103, 102, 102, 102, 103, + 103, 102, 102, 103, 102, 102, 103, 102, 102, 82, + 108, 288, 103, 106, 109, 192, 108, 109, 194, 1, + 21, 26, 104, 258, 104, 104, 90, 106, 106, 212, + 108, 42, 43, 44, 103, 94, 95, 234, 235, 239, + 106, 69, 103, 109, 18, 63, 102, 108, 262, 260, + 106, 103, 102, 106, 106, 103, 106, 102, 108, 108, + 195, 286, 279, 102, 265, 102, 103, 275, 102, 193, + 109, 108, 108, 108, 240, 236, 108, 109, 102, 54, + 97, 102, 196, 106, 106, 109, 102, 102, 102, 241, + 237, 197, 69, 108, 242, 96, 109, 106, 106, 102, + 102, 102, 198, 243, 238, 109, 108, 108, 79, 108 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint16 yyr1[] = +{ + 0, 110, 111, 111, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 114, + 113, 116, 115, 117, 118, 118, 119, 120, 120, 121, + 121, 123, 122, 124, 124, 125, 125, 126, 126, 126, + 127, 127, 127, 128, 129, 131, 132, 130, 133, 134, + 134, 135, 135, 135, 135, 135, 136, 138, 137, 137, + 140, 139, 141, 141, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 144, 143, 145, 145, 146, 146, + 146, 146, 146, 146, 146, 146, 148, 147, 149, 149, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 162, 163, 163, 165, 166, 167, 164, 164, 168, + 168, 169, 169, 170, 170, 171, 172, 172, 173, 174, + 175, 176, 177, 177, 178, 178, 179, 180, 182, 183, + 181, 185, 184, 184, 184, 186, 186, 188, 187, 187, + 190, 189, 189, 192, 193, 191, 194, 194, 194, 195, + 196, 197, 198, 194, 200, 199, 202, 201, 201, 203, + 204, 203, 205, 205, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 208, 207, 210, 209, + 211, 211, 212, 212, 213, 214, 216, 215, 217, 217, + 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + 218, 218, 218, 218, 218, 218, 219, 220, 221, 223, + 222, 224, 224, 225, 225, 226, 227, 227, 227, 227, + 229, 228, 230, 230, 231, 231, 231, 231, 231, 233, + 232, 234, 234, 236, 237, 238, 235, 240, 241, 239, + 243, 242, 242, 245, 246, 244, 247, 247, 248, 248, + 248, 248, 249, 250, 250, 250, 252, 253, 251, 255, + 256, 254, 257, 257, 258, 258, 258, 258, 260, 259, + 262, 261, 264, 265, 263, 267, 266, 268, 268, 269, + 269, 270, 270, 270, 272, 271, 274, 275, 273, 276, + 278, 277, 280, 279, 282, 281, 284, 283, 285, 287, + 288, 286 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, + 4, 0, 6, 5, 1, 1, 6, 1, 1, 1, + 1, 0, 6, 4, 3, 2, 1, 3, 2, 2, + 1, 1, 1, 2, 2, 0, 0, 9, 4, 2, + 1, 1, 1, 1, 1, 3, 3, 0, 5, 1, + 0, 5, 2, 1, 1, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 0, 5, 2, 1, 1, 3, + 1, 1, 1, 1, 1, 1, 0, 5, 2, 1, + 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 3, 2, 1, 0, 0, 0, 10, 3, 2, + 1, 2, 1, 2, 1, 3, 1, 1, 3, 3, + 3, 4, 2, 1, 7, 3, 3, 3, 0, 0, + 8, 0, 4, 2, 1, 2, 1, 0, 7, 3, + 0, 3, 1, 0, 0, 7, 1, 3, 3, 0, + 0, 0, 0, 15, 0, 6, 0, 3, 1, 2, + 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 0, 7, 0, 7, + 2, 1, 2, 1, 3, 3, 0, 6, 2, 1, + 1, 3, 1, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, + 6, 2, 1, 2, 1, 3, 3, 3, 3, 3, + 0, 6, 2, 1, 1, 3, 3, 3, 3, 0, + 8, 1, 1, 0, 0, 0, 13, 0, 0, 9, + 0, 5, 1, 0, 0, 8, 2, 1, 1, 1, + 1, 1, 3, 3, 3, 3, 0, 0, 8, 0, + 0, 8, 2, 1, 1, 1, 1, 3, 0, 5, + 0, 5, 0, 0, 11, 0, 6, 2, 1, 2, + 1, 1, 1, 3, 0, 7, 0, 0, 11, 3, + 0, 6, 0, 7, 0, 7, 0, 7, 2, 0, + 0, 12 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if HYYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +{ + FILE *yyoutput = yyo; + YYUSE (yyoutput); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); +# endif + YYUSE (yytype); +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyo, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyo, yytype, yyvaluep); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +{ + unsigned long yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &yyvsp[(yyi + 1) - (yynrhs)] + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !HYYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !HYYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +yystrlen (const char *yystr) +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +{ + YYUSE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + *yyssp = (yytype_int16) yystate; + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 19: +#line 151 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_board_file(&h)) YYERROR; } +#line 1878 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 21: +#line 156 "hyp_y.y" /* yacc.c:1652 */ + { h.vers = yylval.floatval; } +#line 1884 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 22: +#line 156 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_version(&h)) YYERROR; } +#line 1890 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 23: +#line 161 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_data_mode(&h)) YYERROR; } +#line 1896 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 24: +#line 164 "hyp_y.y" /* yacc.c:1652 */ + { h.detailed = rnd_false; } +#line 1902 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 25: +#line 165 "hyp_y.y" /* yacc.c:1652 */ + { h.detailed = rnd_true; } +#line 1908 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 26: +#line 170 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_units(&h)) YYERROR; } +#line 1914 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 27: +#line 173 "hyp_y.y" /* yacc.c:1652 */ + { h.unit_system_english = rnd_true; } +#line 1920 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 28: +#line 174 "hyp_y.y" /* yacc.c:1652 */ + { h.unit_system_english = rnd_false; } +#line 1926 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 29: +#line 177 "hyp_y.y" /* yacc.c:1652 */ + { h.metal_thickness_weight = rnd_true; } +#line 1932 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 30: +#line 178 "hyp_y.y" /* yacc.c:1652 */ + { h.metal_thickness_weight = rnd_false; } +#line 1938 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 31: +#line 182 "hyp_y.y" /* yacc.c:1652 */ + { h.default_plane_separation = yylval.floatval; } +#line 1944 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 32: +#line 182 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_plane_sep(&h)) YYERROR; } +#line 1950 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 38: +#line 196 "hyp_y.y" /* yacc.c:1652 */ + { hyyerror("warning: missing ')'"); } +#line 1956 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 43: +#line 206 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_perimeter_segment(&h)) YYERROR; } +#line 1962 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 44: +#line 209 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_perimeter_arc(&h)) YYERROR; } +#line 1968 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 45: +#line 212 "hyp_y.y" /* yacc.c:1652 */ + { h.name = yylval.strval; } +#line 1974 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 46: +#line 212 "hyp_y.y" /* yacc.c:1652 */ + { h.value = yylval.strval; } +#line 1980 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 47: +#line 212 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_board_attribute(&h)) YYERROR; } +#line 1986 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 56: +#line 231 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_options(&h)) YYERROR; } +#line 1992 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 57: +#line 234 "hyp_y.y" /* yacc.c:1652 */ + { h.use_die_for_metal = yylval.boolval; } +#line 1998 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 60: +#line 239 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2004 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 61: +#line 239 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_signal(&h)) YYERROR; } +#line 2010 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 66: +#line 248 "hyp_y.y" /* yacc.c:1652 */ + { h.bulk_resistivity = yylval.floatval; h.bulk_resistivity_set = rnd_true; } +#line 2016 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 74: +#line 258 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2022 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 75: +#line 258 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_dielectric(&h)) YYERROR; } +#line 2028 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 79: +#line 266 "hyp_y.y" /* yacc.c:1652 */ + { h.epsilon_r = yylval.floatval; h.epsilon_r_set = rnd_true; } +#line 2034 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 86: +#line 276 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2040 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 87: +#line 276 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_plane(&h)) YYERROR; } +#line 2046 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 91: +#line 284 "hyp_y.y" /* yacc.c:1652 */ + { h.bulk_resistivity = yylval.floatval; h.bulk_resistivity_set = rnd_true; } +#line 2052 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 99: +#line 294 "hyp_y.y" /* yacc.c:1652 */ + { h.thickness = yylval.floatval; h.thickness_set = rnd_true; } +#line 2058 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 100: +#line 297 "hyp_y.y" /* yacc.c:1652 */ + { h.plating_thickness = yylval.floatval; h.plating_thickness_set = rnd_true; } +#line 2064 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 101: +#line 300 "hyp_y.y" /* yacc.c:1652 */ + { h.bulk_resistivity = yylval.floatval; h.bulk_resistivity_set = rnd_true; } +#line 2070 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 102: +#line 303 "hyp_y.y" /* yacc.c:1652 */ + { h.temperature_coefficient = yylval.floatval; h.temperature_coefficient_set = rnd_true; } +#line 2076 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 103: +#line 306 "hyp_y.y" /* yacc.c:1652 */ + { h.epsilon_r = yylval.floatval; h.epsilon_r_set = rnd_true; } +#line 2082 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 104: +#line 309 "hyp_y.y" /* yacc.c:1652 */ + { h.loss_tangent = yylval.floatval; h.loss_tangent_set = rnd_true; } +#line 2088 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 105: +#line 312 "hyp_y.y" /* yacc.c:1652 */ + { h.layer_name = yylval.strval; h.layer_name_set = rnd_true; } +#line 2094 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 106: +#line 315 "hyp_y.y" /* yacc.c:1652 */ + { h.material_name = yylval.strval; h.material_name_set = rnd_true; } +#line 2100 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 107: +#line 318 "hyp_y.y" /* yacc.c:1652 */ + { h.plane_separation = yylval.floatval; h.plane_separation_set = rnd_true; } +#line 2106 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 108: +#line 321 "hyp_y.y" /* yacc.c:1652 */ + { h.conformal = yylval.boolval; h.conformal_set = rnd_true; } +#line 2112 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 109: +#line 324 "hyp_y.y" /* yacc.c:1652 */ + { h.prepreg = yylval.boolval; h.prepreg_set = rnd_true; } +#line 2118 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 114: +#line 337 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2124 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 115: +#line 337 "hyp_y.y" /* yacc.c:1652 */ + { h.device_type = yylval.strval; } +#line 2130 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 116: +#line 337 "hyp_y.y" /* yacc.c:1652 */ + { h.ref = yylval.strval; } +#line 2136 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 117: +#line 337 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_devices(&h)) YYERROR; } +#line 2142 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 125: +#line 356 "hyp_y.y" /* yacc.c:1652 */ + { h.name = yylval.strval; h.name_set = rnd_true; } +#line 2148 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 128: +#line 364 "hyp_y.y" /* yacc.c:1652 */ + { h.value_float = yylval.floatval; h.value_float_set = rnd_true; } +#line 2154 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 129: +#line 367 "hyp_y.y" /* yacc.c:1652 */ + { h.value_string = yylval.strval; h.value_string_set = rnd_true; } +#line 2160 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 130: +#line 370 "hyp_y.y" /* yacc.c:1652 */ + { h.package = yylval.strval; h.package_set = rnd_true; } +#line 2166 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 134: +#line 382 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_supplies(&h)) YYERROR; } +#line 2172 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 136: +#line 386 "hyp_y.y" /* yacc.c:1652 */ + { h.voltage_specified = yylval.boolval; } +#line 2178 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 137: +#line 389 "hyp_y.y" /* yacc.c:1652 */ + { h.conversion = yylval.boolval; } +#line 2184 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 138: +#line 394 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2190 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 139: +#line 394 "hyp_y.y" /* yacc.c:1652 */ + { h.padstack_name = yylval.strval; h.padstack_name_set = rnd_true; } +#line 2196 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 140: +#line 394 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_pstk_end(&h)) YYERROR; } +#line 2202 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 141: +#line 397 "hyp_y.y" /* yacc.c:1652 */ + { h.drill_size = yylval.floatval; h.drill_size_set = rnd_true; } +#line 2208 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 147: +#line 406 "hyp_y.y" /* yacc.c:1652 */ + { h.layer_name = yylval.strval; h.layer_name_set = rnd_true; } +#line 2214 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 148: +#line 406 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_pstk_element(&h)) YYERROR; new_record(); } +#line 2220 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 150: +#line 410 "hyp_y.y" /* yacc.c:1652 */ + { h.pad_shape = yylval.floatval; } +#line 2226 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 152: +#line 411 "hyp_y.y" /* yacc.c:1652 */ + { h.pad_shape = -1; } +#line 2232 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 153: +#line 415 "hyp_y.y" /* yacc.c:1652 */ + { h.pad_sx = yylval.floatval; } +#line 2238 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 154: +#line 415 "hyp_y.y" /* yacc.c:1652 */ + { h.pad_sy = yylval.floatval; } +#line 2244 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 155: +#line 415 "hyp_y.y" /* yacc.c:1652 */ + { h.pad_angle = yylval.floatval; } +#line 2250 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 157: +#line 419 "hyp_y.y" /* yacc.c:1652 */ + { h.pad_type = PAD_TYPE_METAL; h.pad_type_set = rnd_true; } +#line 2256 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 158: +#line 420 "hyp_y.y" /* yacc.c:1652 */ + { h.pad_type = PAD_TYPE_ANTIPAD; h.pad_type_set = rnd_true; } +#line 2262 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 159: +#line 421 "hyp_y.y" /* yacc.c:1652 */ + { h.thermal_clear_shape = yylval.floatval; } +#line 2268 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 160: +#line 422 "hyp_y.y" /* yacc.c:1652 */ + { h.thermal_clear_sx = yylval.floatval; } +#line 2274 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 161: +#line 423 "hyp_y.y" /* yacc.c:1652 */ + { h.thermal_clear_sy = yylval.floatval; } +#line 2280 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 162: +#line 424 "hyp_y.y" /* yacc.c:1652 */ + { h.thermal_clear_angle = yylval.floatval; } +#line 2286 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 163: +#line 425 "hyp_y.y" /* yacc.c:1652 */ + { h.pad_type = PAD_TYPE_THERMAL_RELIEF; h.pad_type_set = rnd_true; } +#line 2292 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 164: +#line 431 "hyp_y.y" /* yacc.c:1652 */ + { h.net_name = yylval.strval; if (exec_net(&h)) YYERROR; } +#line 2298 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 166: +#line 434 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_net_plane_separation(&h)) YYERROR; } +#line 2304 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 170: +#line 440 "hyp_y.y" /* yacc.c:1652 */ + { hyyerror("warning: empty net"); } +#line 2310 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 186: +#line 463 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2316 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 187: +#line 463 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_seg(&h)) YYERROR; } +#line 2322 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 188: +#line 466 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2328 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 189: +#line 466 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_arc(&h)) YYERROR; } +#line 2334 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 194: +#line 479 "hyp_y.y" /* yacc.c:1652 */ + { h.width = yylval.floatval; h.width_set = rnd_true; } +#line 2340 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 195: +#line 482 "hyp_y.y" /* yacc.c:1652 */ + { h.left_plane_separation = yylval.floatval; h.left_plane_separation_set = rnd_true; } +#line 2346 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 196: +#line 485 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2352 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 197: +#line 485 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_via(&h)) YYERROR; } +#line 2358 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 201: +#line 496 "hyp_y.y" /* yacc.c:1652 */ + { h.drill_size = yylval.floatval; h.drill_size_set = rnd_true; } +#line 2364 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 204: +#line 499 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad_shape = yylval.strval; h.via_pad_shape_set = rnd_true; } +#line 2370 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 205: +#line 500 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad_sx = yylval.floatval; h.via_pad_sx_set = rnd_true; } +#line 2376 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 206: +#line 501 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad_sy = yylval.floatval; h.via_pad_sy_set = rnd_true; } +#line 2382 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 207: +#line 502 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad_angle = yylval.floatval; h.via_pad_angle_set = rnd_true; } +#line 2388 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 208: +#line 503 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad1_shape = yylval.strval; h.via_pad1_shape_set = rnd_true; } +#line 2394 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 209: +#line 504 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad1_sx = yylval.floatval; h.via_pad1_sx_set = rnd_true; } +#line 2400 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 210: +#line 505 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad1_sy = yylval.floatval; h.via_pad1_sy_set = rnd_true; } +#line 2406 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 211: +#line 506 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad1_angle = yylval.floatval; h.via_pad1_angle_set = rnd_true; } +#line 2412 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 212: +#line 507 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad2_shape = yylval.strval; h.via_pad2_shape_set = rnd_true; } +#line 2418 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 213: +#line 508 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad2_sx = yylval.floatval; h.via_pad2_sx_set = rnd_true; } +#line 2424 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 214: +#line 509 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad2_sy = yylval.floatval; h.via_pad2_sy_set = rnd_true; } +#line 2430 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 215: +#line 510 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad2_angle = yylval.floatval; h.via_pad2_angle_set = rnd_true; } +#line 2436 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 216: +#line 514 "hyp_y.y" /* yacc.c:1652 */ + { h.padstack_name = yylval.strval; h.padstack_name_set = rnd_true; } +#line 2442 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 217: +#line 517 "hyp_y.y" /* yacc.c:1652 */ + { h.layer1_name = yylval.strval; h.layer1_name_set = rnd_true; } +#line 2448 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 218: +#line 520 "hyp_y.y" /* yacc.c:1652 */ + { h.layer2_name = yylval.strval; h.layer2_name_set = rnd_true; } +#line 2454 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 219: +#line 523 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2460 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 220: +#line 523 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_pin(&h)) YYERROR; } +#line 2466 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 225: +#line 536 "hyp_y.y" /* yacc.c:1652 */ + { h.pin_reference = yylval.strval; h.pin_reference_set = rnd_true; } +#line 2472 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 226: +#line 539 "hyp_y.y" /* yacc.c:1652 */ + { h.pin_function = PIN_SIM_OUT; h.pin_function_set = rnd_true; } +#line 2478 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 227: +#line 540 "hyp_y.y" /* yacc.c:1652 */ + { h.pin_function = PIN_SIM_IN; h.pin_function_set = rnd_true; } +#line 2484 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 228: +#line 541 "hyp_y.y" /* yacc.c:1652 */ + { h.pin_function = PIN_SIM_BOTH; h.pin_function_set = rnd_true; } +#line 2490 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 229: +#line 542 "hyp_y.y" /* yacc.c:1652 */ + { h.pin_function = PIN_SIM_BOTH; h.pin_function_set = rnd_true; hyyerror("warning: SIM_BOTH assumed"); } +#line 2496 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 230: +#line 546 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2502 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 231: +#line 546 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_pad(&h)) YYERROR; } +#line 2508 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 235: +#line 555 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad_shape = yylval.strval; h.via_pad_shape_set = rnd_true; } +#line 2514 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 236: +#line 556 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad_sx = yylval.floatval; h.via_pad_sx_set = rnd_true; } +#line 2520 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 237: +#line 557 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad_sy = yylval.floatval; h.via_pad_sy_set = rnd_true; } +#line 2526 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 238: +#line 558 "hyp_y.y" /* yacc.c:1652 */ + { h.via_pad_angle = yylval.floatval; h.via_pad_angle_set = rnd_true; } +#line 2532 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 239: +#line 562 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2538 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 240: +#line 562 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_useg(&h)) YYERROR; } +#line 2544 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 243: +#line 570 "hyp_y.y" /* yacc.c:1652 */ + { h.zlayer_name = yylval.strval; h.zlayer_name_set = rnd_true; } +#line 2550 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 244: +#line 571 "hyp_y.y" /* yacc.c:1652 */ + { h.width = yylval.floatval; } +#line 2556 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 245: +#line 572 "hyp_y.y" /* yacc.c:1652 */ + { h.length = yylval.floatval; } +#line 2562 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 247: +#line 577 "hyp_y.y" /* yacc.c:1652 */ + { h.impedance = yylval.floatval; h.impedance_set = rnd_true; } +#line 2568 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 248: +#line 578 "hyp_y.y" /* yacc.c:1652 */ + { h.delay = yylval.floatval; } +#line 2574 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 250: +#line 582 "hyp_y.y" /* yacc.c:1652 */ + { h.resistance = yylval.floatval; h.resistance_set = rnd_true;} +#line 2580 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 253: +#line 588 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2586 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 254: +#line 588 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_polygon_begin(&h)) YYERROR; } +#line 2592 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 255: +#line 589 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_polygon_end(&h)) YYERROR; } +#line 2598 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 262: +#line 604 "hyp_y.y" /* yacc.c:1652 */ + { h.id = yylval.intval; h.id_set = rnd_true; } +#line 2604 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 263: +#line 608 "hyp_y.y" /* yacc.c:1652 */ + { h.polygon_type = POLYGON_TYPE_POUR; h.polygon_type_set = rnd_true; } +#line 2610 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 264: +#line 609 "hyp_y.y" /* yacc.c:1652 */ + { h.polygon_type = POLYGON_TYPE_PLANE; h.polygon_type_set = rnd_true; } +#line 2616 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 265: +#line 610 "hyp_y.y" /* yacc.c:1652 */ + { h.polygon_type = POLYGON_TYPE_COPPER; h.polygon_type_set = rnd_true; } +#line 2622 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 266: +#line 614 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2628 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 267: +#line 614 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_polyvoid_begin(&h)) YYERROR; } +#line 2634 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 268: +#line 615 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_polyvoid_end(&h)) YYERROR; } +#line 2640 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 269: +#line 618 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2646 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 270: +#line 618 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_polyline_begin(&h)) YYERROR; } +#line 2652 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 271: +#line 619 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_polyline_end(&h)) YYERROR; } +#line 2658 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 276: +#line 629 "hyp_y.y" /* yacc.c:1652 */ + { hyyerror("warning: unexpected ')'"); } +#line 2664 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 278: +#line 634 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2670 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 279: +#line 634 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_line(&h)) YYERROR; } +#line 2676 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 280: +#line 637 "hyp_y.y" /* yacc.c:1652 */ + { new_record(); } +#line 2682 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 281: +#line 637 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_curve(&h)) YYERROR; } +#line 2688 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 282: +#line 640 "hyp_y.y" /* yacc.c:1652 */ + { h.name = yylval.strval; } +#line 2694 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 283: +#line 640 "hyp_y.y" /* yacc.c:1652 */ + { h.value = yylval.strval; } +#line 2700 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 284: +#line 640 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_net_attribute(&h)) YYERROR; } +#line 2706 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 285: +#line 645 "hyp_y.y" /* yacc.c:1652 */ + { h.net_class_name = yylval.strval; if (exec_net_class(&h)) YYERROR; } +#line 2712 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 294: +#line 664 "hyp_y.y" /* yacc.c:1652 */ + { h.net_name = yylval.strval; } +#line 2718 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 295: +#line 664 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_net_class_element(&h)) YYERROR; } +#line 2724 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 296: +#line 667 "hyp_y.y" /* yacc.c:1652 */ + { h.name = yylval.strval; } +#line 2730 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 297: +#line 667 "hyp_y.y" /* yacc.c:1652 */ + { h.value = yylval.strval; } +#line 2736 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 298: +#line 667 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_net_class_attribute(&h)) YYERROR; } +#line 2742 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 299: +#line 672 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_end(&h)) YYERROR; } +#line 2748 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 300: +#line 677 "hyp_y.y" /* yacc.c:1652 */ + { h.key = yylval.strval; } +#line 2754 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 301: +#line 677 "hyp_y.y" /* yacc.c:1652 */ + { if (exec_key(&h)) YYERROR; } +#line 2760 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 302: +#line 682 "hyp_y.y" /* yacc.c:1652 */ + { h.x = yylval.floatval; } +#line 2766 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 303: +#line 682 "hyp_y.y" /* yacc.c:1652 */ + { h.y = yylval.floatval; } +#line 2772 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 304: +#line 685 "hyp_y.y" /* yacc.c:1652 */ + { h.x1 = yylval.floatval; } +#line 2778 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 305: +#line 685 "hyp_y.y" /* yacc.c:1652 */ + { h.y1 = yylval.floatval; } +#line 2784 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 306: +#line 688 "hyp_y.y" /* yacc.c:1652 */ + { h.x2 = yylval.floatval; } +#line 2790 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 307: +#line 688 "hyp_y.y" /* yacc.c:1652 */ + { h.y2 = yylval.floatval; } +#line 2796 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 309: +#line 694 "hyp_y.y" /* yacc.c:1652 */ + { h.xc = yylval.floatval; } +#line 2802 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 310: +#line 694 "hyp_y.y" /* yacc.c:1652 */ + { h.yc = yylval.floatval; } +#line 2808 "hyp_y.c" /* yacc.c:1652 */ + break; + + case 311: +#line 694 "hyp_y.y" /* yacc.c:1652 */ + { h.r = yylval.floatval; } +#line 2814 "hyp_y.c" /* yacc.c:1652 */ + break; + + +#line 2818 "hyp_y.c" /* yacc.c:1652 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} +#line 696 "hyp_y.y" /* yacc.c:1918 */ + + +/* + * Supporting C routines + */ + +void hyyerror(const char *msg) +{ + /* log pcb-rnd message */ + hyp_error(msg); +} + +void hyyprint(FILE *file, int type, YYSTYPE value) +{ + if (type == H_STRING) + fprintf (file, "%s", value.strval); + else if (type == H_FLOAT) + fprintf (file, "%g", value.floatval); + else if (type == H_BOOL) + fprintf (file, "%i", value.boolval); + return; +} + +/* + * reset parse_param struct at beginning of record + */ + +static void new_record() +{ + h.vers = 0; + h.detailed = rnd_false; + h.unit_system_english = rnd_false; + h.metal_thickness_weight = rnd_false; + h.default_plane_separation = 0; + h.use_die_for_metal = rnd_false; + h.bulk_resistivity = 0; + h.conformal = rnd_false; + h.epsilon_r = 0; + h.layer_name = NULL; + h.loss_tangent = 0; + h.material_name = NULL; + h.plane_separation = 0; + h.plating_thickness = 0; + h.prepreg = rnd_false; + h.temperature_coefficient = 0; + h.thickness = 0; + h.bulk_resistivity_set = rnd_false; + h.conformal_set = rnd_false; + h.epsilon_r_set = rnd_false; + h.layer_name_set = rnd_false; + h.loss_tangent_set = rnd_false; + h.material_name_set = rnd_false; + h.plane_separation_set = rnd_false; + h.plating_thickness_set = rnd_false; + h.prepreg_set = rnd_false; + h.temperature_coefficient_set = rnd_false; + h.thickness_set = rnd_false; + h.device_type = NULL; + h.ref = NULL; + h.value_float = 0; + h.value_string = NULL; + h.package = NULL; + h.name_set = rnd_false; + h.value_float_set = rnd_false; + h.value_string_set = rnd_false; + h.package_set = rnd_false; + h.voltage_specified = rnd_false; + h.conversion = rnd_false; + h.padstack_name = NULL; + h.drill_size = 0; + h.pad_shape = 0; + h.pad_sx = 0; + h.pad_sy = 0; + h.pad_angle = 0; + h.thermal_clear_shape = 0; + h.thermal_clear_sx = 0; + h.thermal_clear_sy = 0; + h.thermal_clear_angle = 0; + h.pad_type = PAD_TYPE_METAL; + h.padstack_name_set = rnd_false; + h.drill_size_set = rnd_false; + h.pad_type_set = rnd_false; + h.width = 0; + h.left_plane_separation = 0; + h.width_set = rnd_false; + h.left_plane_separation_set = rnd_false; + h.layer1_name = NULL; + h.layer1_name_set = rnd_false; + h.layer2_name = NULL; + h.layer2_name_set = rnd_false; + h.via_pad_shape = NULL; + h.via_pad_shape_set = rnd_false; + h.via_pad_sx = 0; + h.via_pad_sx_set = rnd_false; + h.via_pad_sy = 0; + h.via_pad_sy_set = rnd_false; + h.via_pad_angle = 0; + h.via_pad_angle_set = rnd_false; + h.via_pad1_shape = NULL; + h.via_pad1_shape_set = rnd_false; + h.via_pad1_sx = 0; + h.via_pad1_sx_set = rnd_false; + h.via_pad1_sy = 0; + h.via_pad1_sy_set = rnd_false; + h.via_pad1_angle = 0; + h.via_pad1_angle_set = rnd_false; + h.via_pad2_shape = NULL; + h.via_pad2_shape_set = rnd_false; + h.via_pad2_sx = 0; + h.via_pad2_sx_set = rnd_false; + h.via_pad2_sy = 0; + h.via_pad2_sy_set = rnd_false; + h.via_pad2_angle = 0; + h.via_pad2_angle_set = rnd_false; + h.pin_reference = NULL; + h.pin_reference_set = rnd_false; + h.pin_function = PIN_SIM_BOTH; + h.pin_function_set = rnd_false; + h.zlayer_name = NULL; + h.zlayer_name_set = rnd_false; + h.length = 0; + h.impedance = 0; + h.impedance_set = rnd_false; + h.delay = 0; + h.resistance = 0; + h.resistance_set = rnd_false; + h.id = -1; + h.id_set = rnd_false; + h.polygon_type = POLYGON_TYPE_PLANE; + h.polygon_type_set = rnd_false; + h.net_class_name = NULL; + h.net_name = NULL; + h.key = NULL; + h.name = NULL; + h.value = NULL; + h.x = 0; + h.y = 0; + h.x1 = 0; + h.y1 = 0; + h.x2 = 0; + h.y2 = 0; + h.xc = 0; + h.yc = 0; + h.r = 0; + + return; +} + +/* not truncated */ Index: tags/2.3.0/src_plugins/io_hyp/hyp_y.h =================================================================== --- tags/2.3.0/src_plugins/io_hyp/hyp_y.h (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/hyp_y.h (revision 33253) @@ -0,0 +1,195 @@ +/* A Bison parser, made by GNU Bison 3.3.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. + + 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 3 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, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +#ifndef YY_HYY_HYP_Y_H_INCLUDED +# define YY_HYY_HYP_Y_H_INCLUDED +/* Debug traces. */ +#ifndef HYYDEBUG +# if defined YYDEBUG +#if YYDEBUG +# define HYYDEBUG 1 +# else +# define HYYDEBUG 0 +# endif +# else /* ! defined YYDEBUG */ +# define HYYDEBUG 1 +# endif /* ! defined YYDEBUG */ +#endif /* ! defined HYYDEBUG */ +#if HYYDEBUG +extern int hyydebug; +#endif +/* "%code requires" blocks. */ +#line 21 "hyp_y.y" /* yacc.c:1921 */ + +#include "parser.h" + +#line 60 "hyp_y.h" /* yacc.c:1921 */ + +/* Token type. */ +#ifndef HYYTOKENTYPE +# define HYYTOKENTYPE + enum hyytokentype + { + H_BOARD_FILE = 258, + H_VERSION = 259, + H_DATA_MODE = 260, + H_UNITS = 261, + H_PLANE_SEP = 262, + H_BOARD = 263, + H_STACKUP = 264, + H_DEVICES = 265, + H_SUPPLIES = 266, + H_PAD = 267, + H_PADSTACK = 268, + H_NET = 269, + H_NET_CLASS = 270, + H_END = 271, + H_KEY = 272, + H_A = 273, + H_ARC = 274, + H_COPPER = 275, + H_CURVE = 276, + H_DETAILED = 277, + H_DIELECTRIC = 278, + H_ENGLISH = 279, + H_LENGTH = 280, + H_LINE = 281, + H_METRIC = 282, + H_N = 283, + H_OPTIONS = 284, + H_PERIMETER_ARC = 285, + H_PERIMETER_SEGMENT = 286, + H_PIN = 287, + H_PLANE = 288, + H_POLYGON = 289, + H_POLYLINE = 290, + H_POLYVOID = 291, + H_POUR = 292, + H_S = 293, + H_SEG = 294, + H_SIGNAL = 295, + H_SIMPLIFIED = 296, + H_SIM_BOTH = 297, + H_SIM_IN = 298, + H_SIM_OUT = 299, + H_USEG = 300, + H_VIA = 301, + H_WEIGHT = 302, + H_A1 = 303, + H_A2 = 304, + H_BR = 305, + H_C = 306, + H_C_QM = 307, + H_CO_QM = 308, + H_D = 309, + H_ER = 310, + H_F = 311, + H_ID = 312, + H_L = 313, + H_L1 = 314, + H_L2 = 315, + H_LPS = 316, + H_LT = 317, + H_M = 318, + H_NAME = 319, + H_P = 320, + H_PKG = 321, + H_PR_QM = 322, + H_PS = 323, + H_R = 324, + H_REF = 325, + H_SX = 326, + H_SY = 327, + H_S1 = 328, + H_S1X = 329, + H_S1Y = 330, + H_S2 = 331, + H_S2X = 332, + H_S2Y = 333, + H_T = 334, + H_TC = 335, + H_USE_DIE_FOR_METAL = 336, + H_V = 337, + H_V_QM = 338, + H_VAL = 339, + H_W = 340, + H_X = 341, + H_X1 = 342, + H_X2 = 343, + H_XC = 344, + H_Y = 345, + H_Y1 = 346, + H_Y2 = 347, + H_YC = 348, + H_Z = 349, + H_ZL = 350, + H_ZLEN = 351, + H_ZW = 352, + H_YES = 353, + H_NO = 354, + H_BOOL = 355, + H_POSINT = 356, + H_FLOAT = 357, + H_STRING = 358 + }; +#endif + +/* Value type. */ +#if ! defined HYYSTYPE && ! defined HYYSTYPE_IS_DECLARED + +union HYYSTYPE +{ +#line 30 "hyp_y.y" /* yacc.c:1921 */ + + int boolval; + int intval; + double floatval; + char* strval; + +#line 183 "hyp_y.h" /* yacc.c:1921 */ +}; + +typedef union HYYSTYPE HYYSTYPE; +# define HYYSTYPE_IS_TRIVIAL 1 +# define HYYSTYPE_IS_DECLARED 1 +#endif + + +extern HYYSTYPE hyylval; + +int hyyparse (void); + +#endif /* !YY_HYY_HYP_Y_H_INCLUDED */ Index: tags/2.3.0/src_plugins/io_hyp/hyp_y.y =================================================================== --- tags/2.3.0/src_plugins/io_hyp/hyp_y.y (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/hyp_y.y (revision 33253) @@ -0,0 +1,844 @@ +/* + * read hyperlynx files + * Copyright 2012-2017 Koen De Vleeschauwer. + * + * This file is part of pcb-rnd. + * + * 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, see . + */ + +%code requires { +#include "parser.h" +} + +%error-verbose +%debug +%defines "hyp_y.h" +%define api.prefix {hyy} + +%union { + int boolval; + int intval; + double floatval; + char* strval; +} + +%{ +#include +#include +#include +#include +#include "hyp_l.h" + +void hyyerror(const char *); + +/* HYYPRINT and hyyprint print values of the tokens when debugging is switched on */ +void hyyprint(FILE *, int, HYYSTYPE); +#define HYYPRINT(file, type, value) hyyprint (file, type, value) + +/* clear parse_param struct at beginning of new record */ +static void new_record(); + +/* struct to pass to calling class */ +static parse_param h; + +%} + +/* + * Hyperlynx keywords + */ + + /* Punctuation: { } ( ) = , */ + + /* Sections */ + +%token H_BOARD_FILE H_VERSION H_DATA_MODE H_UNITS H_PLANE_SEP +%token H_BOARD H_STACKUP H_DEVICES H_SUPPLIES +%token H_PAD H_PADSTACK H_NET H_NET_CLASS H_END H_KEY + + /* Keywords */ + +%token H_A H_ARC H_COPPER H_CURVE H_DETAILED H_DIELECTRIC H_ENGLISH H_LENGTH +%token H_LINE H_METRIC H_N H_OPTIONS H_PERIMETER_ARC H_PERIMETER_SEGMENT H_PIN +%token H_PLANE H_POLYGON H_POLYLINE H_POLYVOID H_POUR H_S H_SEG H_SIGNAL +%token H_SIMPLIFIED H_SIM_BOTH H_SIM_IN H_SIM_OUT H_USEG H_VIA H_WEIGHT + + /* Assignments */ + +%token H_A1 H_A2 H_BR H_C H_C_QM H_CO_QM H_D H_ER H_F H_ID +%token H_L H_L1 H_L2 H_LPS H_LT H_M H_NAME +%token H_P H_PKG H_PR_QM H_PS H_R H_REF H_SX H_SY H_S1 H_S1X H_S1Y H_S2 H_S2X H_S2Y H_T H_TC +%token H_USE_DIE_FOR_METAL H_V H_V_QM H_VAL H_W H_X H_X1 H_X2 +%token H_XC H_Y H_Y1 H_Y2 H_YC H_Z H_ZL H_ZLEN H_ZW + + /* Booleans */ + +%token H_YES H_NO + +%token H_BOOL +%token H_POSINT +%token H_FLOAT +%token H_STRING + +%start hyp_file + +%% + +/* + * Note: + * Use left recursion when parsing board perimeter and nets. + * When using left recursion cpu time is linear with board size. + * When using right recursion we run out of memory on large boards. + * (Typical error message: line xxx: memory exhausted at 'yyy' ) + */ + + /* + hyperlynx file sections: + + board_file + version + data_mode* + units + plane_sep* + board* + stackup* + devices + supplies* + padstack* + net + net_class* + end + + * = optional section + + */ + +hyp_file + : hyp_file hyp_section + | hyp_section ; + +hyp_section + : board_file + | version + | data_mode + | units + | plane_sep + | board + | stackup + | devices + | supplies + | padstack + | net + | netclass + | end + | key + | error '}' ; + + /* board_file */ + +board_file + : '{' H_BOARD_FILE { if (exec_board_file(&h)) YYERROR; } '}' ; + + /* version */ + +version + : '{' H_VERSION '=' H_FLOAT { h.vers = yylval.floatval; } '}' { if (exec_version(&h)) YYERROR; } ; + + /* data_mode */ + +data_mode + : '{' H_DATA_MODE '=' mode '}' { if (exec_data_mode(&h)) YYERROR; }; + +mode + : H_SIMPLIFIED { h.detailed = rnd_false; } + | H_DETAILED { h.detailed = rnd_true; } ; + + /* units */ + +units + : '{' H_UNITS '=' unit_system metal_thickness_unit '}' { if (exec_units(&h)) YYERROR; } ; + +unit_system + : H_ENGLISH { h.unit_system_english = rnd_true; } + | H_METRIC { h.unit_system_english = rnd_false; }; + +metal_thickness_unit + : H_WEIGHT { h.metal_thickness_weight = rnd_true; } + | H_LENGTH { h.metal_thickness_weight = rnd_false; } ; + + /* plane_sep */ +plane_sep + : '{' H_PLANE_SEP '=' H_FLOAT { h.default_plane_separation = yylval.floatval; } '}' { if (exec_plane_sep(&h)) YYERROR; } ; + + /* board */ + +board + : '{' H_BOARD board_param_list '}' + | '{' H_BOARD '}' ; + +board_param_list + : board_param_list board_param_list_item + | board_param_list_item ; + +board_param_list_item + : '(' board_param ')' + | '(' board_param { hyyerror("warning: missing ')'"); } + | error ')' ; + ; + +board_param + : perimeter_segment + | perimeter_arc + | board_attribute ; + +perimeter_segment + : H_PERIMETER_SEGMENT coord_line { if (exec_perimeter_segment(&h)) YYERROR; } ; + +perimeter_arc + : H_PERIMETER_ARC coord_arc { if (exec_perimeter_arc(&h)) YYERROR; } ; + +board_attribute + : H_A H_N '=' H_STRING { h.name = yylval.strval; } H_V '=' H_STRING { h.value = yylval.strval; } { if (exec_board_attribute(&h)) YYERROR; } ; + + /* stackup */ + +stackup + : '{' H_STACKUP stackup_paramlist '}' ; + +stackup_paramlist + : stackup_paramlist stackup_param + | stackup_param ; + +stackup_param + : options + | signal + | dielectric + | plane + | '(' error ')' ; + +options + : '(' H_OPTIONS options_params { if (exec_options(&h)) YYERROR; } ; + +options_params + : H_USE_DIE_FOR_METAL '=' H_BOOL { h.use_die_for_metal = yylval.boolval; } ')' + | ')' + ; + +signal + : '(' H_SIGNAL { new_record(); } signal_paramlist ')' { if (exec_signal(&h)) YYERROR; } ; + +signal_paramlist + : signal_paramlist signal_param + | signal_param ; + +signal_param + : thickness + | plating_thickness + | H_C '=' H_FLOAT { h.bulk_resistivity = yylval.floatval; h.bulk_resistivity_set = rnd_true; } + | bulk_resistivity + | temperature_coefficient + | epsilon_r + | loss_tangent + | layer_name + | material_name + | plane_separation ; + +dielectric + : '(' H_DIELECTRIC { new_record(); } dielectric_paramlist ')' { if (exec_dielectric(&h)) YYERROR; } ; + +dielectric_paramlist + : dielectric_paramlist dielectric_param + | dielectric_param ; + +dielectric_param + : thickness + | H_C '=' H_FLOAT { h.epsilon_r = yylval.floatval; h.epsilon_r_set = rnd_true; } + | epsilon_r + | loss_tangent + | conformal + | prepreg + | layer_name + | material_name + ; + +plane + : '(' H_PLANE { new_record(); } plane_paramlist ')' { if (exec_plane(&h)) YYERROR; } ; + +plane_paramlist + : plane_paramlist plane_param + | plane_param ; + +plane_param + : thickness + | H_C '=' H_FLOAT { h.bulk_resistivity = yylval.floatval; h.bulk_resistivity_set = rnd_true; } + | bulk_resistivity + | temperature_coefficient + | epsilon_r + | loss_tangent + | layer_name + | material_name + | plane_separation ; + +thickness + : H_T '=' H_FLOAT { h.thickness = yylval.floatval; h.thickness_set = rnd_true; } + +plating_thickness + : H_P '=' H_FLOAT { h.plating_thickness = yylval.floatval; h.plating_thickness_set = rnd_true; } + +bulk_resistivity + : H_BR '=' H_FLOAT { h.bulk_resistivity = yylval.floatval; h.bulk_resistivity_set = rnd_true; } + +temperature_coefficient + : H_TC '=' H_FLOAT { h.temperature_coefficient = yylval.floatval; h.temperature_coefficient_set = rnd_true; } + +epsilon_r + : H_ER '=' H_FLOAT { h.epsilon_r = yylval.floatval; h.epsilon_r_set = rnd_true; } + +loss_tangent + : H_LT '=' H_FLOAT { h.loss_tangent = yylval.floatval; h.loss_tangent_set = rnd_true; } + +layer_name + : H_L '=' H_STRING { h.layer_name = yylval.strval; h.layer_name_set = rnd_true; } + +material_name + : H_M '=' H_STRING { h.material_name = yylval.strval; h.material_name_set = rnd_true; } + +plane_separation + : H_PS '=' H_FLOAT { h.plane_separation = yylval.floatval; h.plane_separation_set = rnd_true; } + +conformal + : H_CO_QM '=' H_BOOL { h.conformal = yylval.boolval; h.conformal_set = rnd_true; } + +prepreg + : H_PR_QM '=' H_BOOL { h.prepreg = yylval.boolval; h.prepreg_set = rnd_true; } + + /* devices */ + +devices + : '{' H_DEVICES device_list '}' + | '{' H_DEVICES '}' ; + +device_list + : device_list device + | device ; + +device + : '(' { new_record(); } H_STRING { h.device_type = yylval.strval; } H_REF '=' H_STRING { h.ref = yylval.strval; } device_paramlist ')' { if (exec_devices(&h)) YYERROR; } + | '(' error ')' ; + +device_paramlist + : name device_value + | device_value + ; + +device_value + : value device_layer + | device_layer + ; + +device_layer + : layer_name package + | layer_name + ; + +name + : H_NAME '=' H_STRING { h.name = yylval.strval; h.name_set = rnd_true; } ; + +value + : value_float + | value_string + ; + +value_float + : H_VAL '=' H_FLOAT { h.value_float = yylval.floatval; h.value_float_set = rnd_true; } ; + +value_string + : H_VAL '=' H_STRING { h.value_string = yylval.strval; h.value_string_set = rnd_true; } ; + +package + : H_PKG '=' H_STRING { h.package = yylval.strval; h.package_set = rnd_true; } ; + + /* supplies */ + +supplies + : '{' H_SUPPLIES supply_list '}' ; + +supply_list + : supply_list supply + | supply ; + +supply + : '(' H_S name value_float voltage_spec conversion ')' { if (exec_supplies(&h)) YYERROR; } + | '(' error ')' ; + +voltage_spec + : H_V_QM '=' H_BOOL { h.voltage_specified = yylval.boolval; } ; + +conversion + : H_C_QM '=' H_BOOL { h.conversion = yylval.boolval; } + + /* padstack */ + +padstack + : '{' H_PADSTACK { new_record(); } '=' H_STRING { h.padstack_name = yylval.strval; h.padstack_name_set = rnd_true; } drill_size '}' { if (exec_pstk_end(&h)) YYERROR; } ; + +drill_size + : ',' H_FLOAT { h.drill_size = yylval.floatval; h.drill_size_set = rnd_true; } padstack_list + | ',' padstack_list ; + | padstack_list ; + +padstack_list + : padstack_list padstack_def + | padstack_def ; + +padstack_def + : '(' H_STRING { h.layer_name = yylval.strval; h.layer_name_set = rnd_true; } ',' pad_shape pad_coord pad_type { if (exec_pstk_element(&h)) YYERROR; new_record(); } + | '(' error ')' ; + +pad_shape + : H_FLOAT { h.pad_shape = yylval.floatval; } ',' + | ',' { h.pad_shape = -1; } /* Workaround: Altium sometimes prints an empty pad shape */ + ; + +pad_coord + : H_FLOAT { h.pad_sx = yylval.floatval; } ',' H_FLOAT { h.pad_sy = yylval.floatval; } ',' H_FLOAT { h.pad_angle = yylval.floatval; } + +pad_type + : ')' + | ',' H_M ')' { h.pad_type = PAD_TYPE_METAL; h.pad_type_set = rnd_true; } + | ',' H_A ')' { h.pad_type = PAD_TYPE_ANTIPAD; h.pad_type_set = rnd_true; } + | ',' H_FLOAT { h.thermal_clear_shape = yylval.floatval; } + ',' H_FLOAT { h.thermal_clear_sx = yylval.floatval; } + ',' H_FLOAT { h.thermal_clear_sy = yylval.floatval; } + ',' H_FLOAT { h.thermal_clear_angle = yylval.floatval; } + ',' H_T ')' { h.pad_type = PAD_TYPE_THERMAL_RELIEF; h.pad_type_set = rnd_true; } + ; + + /* net */ + +net + : '{' H_NET '=' H_STRING { h.net_name = yylval.strval; if (exec_net(&h)) YYERROR; } net_separation ; + +net_separation + : plane_separation { if (exec_net_plane_separation(&h)) YYERROR; } net_copper + | net_copper + ; + +net_copper + : net_subrecord_list '}' + | { hyyerror("warning: empty net"); } '}' + ; + +net_subrecord_list + : net_subrecord_list net_subrecord + | net_subrecord ; + +net_subrecord + : seg + | arc + | via + | pin + | pad + | useg + | polygon + | polyvoid + | polyline + | net_attribute + | '(' error ')' + | '{' error '}' + ; + +seg + : '(' H_SEG { new_record(); } coord_line width layer_name ps_lps_param { if (exec_seg(&h)) YYERROR; } ; + +arc + : '(' H_ARC { new_record(); } coord_arc width layer_name ps_lps_param { if (exec_arc(&h)) YYERROR; } ; + +ps_lps_param + : plane_separation lps_param + | lps_param + ; + +lps_param + : left_plane_separation ')' + | ')' + ; + +width + : H_W '=' H_FLOAT { h.width = yylval.floatval; h.width_set = rnd_true; } ; + +left_plane_separation + : H_LPS '=' H_FLOAT { h.left_plane_separation = yylval.floatval; h.left_plane_separation_set = rnd_true; } ; + +via + : '(' H_VIA { new_record(); } coord_point via_param_list ')' { if (exec_via(&h)) YYERROR; } ; + ; + +via_param_list + : via_param_list via_param + | via_param + ; + +via_param + : padstack_name + /* parameters below are for deprecated v1.0 via format */ + | H_D '=' H_FLOAT { h.drill_size = yylval.floatval; h.drill_size_set = rnd_true; } + | layer1_name + | layer2_name + | H_S '=' H_STRING { h.via_pad_shape = yylval.strval; h.via_pad_shape_set = rnd_true; } + | H_SX '=' H_FLOAT { h.via_pad_sx = yylval.floatval; h.via_pad_sx_set = rnd_true; } + | H_SY '=' H_FLOAT { h.via_pad_sy = yylval.floatval; h.via_pad_sy_set = rnd_true; } + | H_A '=' H_FLOAT { h.via_pad_angle = yylval.floatval; h.via_pad_angle_set = rnd_true; } + | H_S1 '=' H_STRING { h.via_pad1_shape = yylval.strval; h.via_pad1_shape_set = rnd_true; } + | H_S1X '=' H_FLOAT { h.via_pad1_sx = yylval.floatval; h.via_pad1_sx_set = rnd_true; } + | H_S1Y '=' H_FLOAT { h.via_pad1_sy = yylval.floatval; h.via_pad1_sy_set = rnd_true; } + | H_A1 '=' H_FLOAT { h.via_pad1_angle = yylval.floatval; h.via_pad1_angle_set = rnd_true; } + | H_S2 '=' H_STRING { h.via_pad2_shape = yylval.strval; h.via_pad2_shape_set = rnd_true; } + | H_S2X '=' H_FLOAT { h.via_pad2_sx = yylval.floatval; h.via_pad2_sx_set = rnd_true; } + | H_S2Y '=' H_FLOAT { h.via_pad2_sy = yylval.floatval; h.via_pad2_sy_set = rnd_true; } + | H_A2 '=' H_FLOAT { h.via_pad2_angle = yylval.floatval; h.via_pad2_angle_set = rnd_true; } + ; + +padstack_name + : H_P '=' H_STRING { h.padstack_name = yylval.strval; h.padstack_name_set = rnd_true; } ; + +layer1_name + : H_L1 '=' H_STRING { h.layer1_name = yylval.strval; h.layer1_name_set = rnd_true; } ; + +layer2_name + : H_L2 '=' H_STRING { h.layer2_name = yylval.strval; h.layer2_name_set = rnd_true; } ; + +pin + : '(' H_PIN { new_record(); } coord_point pin_reference pin_param { if (exec_pin(&h)) YYERROR; } ; + +pin_param + : padstack_name pin_function_param + | pin_function_param + ; + +pin_function_param + : pin_function ')' + | ')' + ; + +pin_reference + : H_R '=' H_STRING { h.pin_reference = yylval.strval; h.pin_reference_set = rnd_true; } ; + +pin_function + : H_F '=' H_SIM_OUT { h.pin_function = PIN_SIM_OUT; h.pin_function_set = rnd_true; } + | H_F '=' H_SIM_IN { h.pin_function = PIN_SIM_IN; h.pin_function_set = rnd_true; } + | H_F '=' H_SIM_BOTH { h.pin_function = PIN_SIM_BOTH; h.pin_function_set = rnd_true; } + | H_F '=' H_STRING { h.pin_function = PIN_SIM_BOTH; h.pin_function_set = rnd_true; hyyerror("warning: SIM_BOTH assumed"); } + ; + +pad /* deprecated hyperlynx v1.x only */ + : '(' H_PAD { new_record(); } coord_point pad_param_list ')' { if (exec_pad(&h)) YYERROR; } ; + +pad_param_list + : pad_param_list pad_param + | pad_param + ; + +pad_param + : layer_name + | H_S '=' H_STRING { h.via_pad_shape = yylval.strval; h.via_pad_shape_set = rnd_true; } + | H_SX '=' H_FLOAT { h.via_pad_sx = yylval.floatval; h.via_pad_sx_set = rnd_true; } + | H_SY '=' H_FLOAT { h.via_pad_sy = yylval.floatval; h.via_pad_sy_set = rnd_true; } + | H_A '=' H_FLOAT { h.via_pad_angle = yylval.floatval; h.via_pad_angle_set = rnd_true; } + ; + +useg + : '(' H_USEG { new_record(); } coord_point1 layer1_name coord_point2 layer2_name useg_param { if (exec_useg(&h)) YYERROR; } ; + +useg_param + : useg_stackup + | useg_impedance + ; + +useg_stackup + : H_ZL '=' H_STRING { h.zlayer_name = yylval.strval; h.zlayer_name_set = rnd_true; } + H_ZW '=' H_FLOAT { h.width = yylval.floatval; } + H_ZLEN '=' H_FLOAT { h.length = yylval.floatval; } + ')' + ; + +useg_impedance + : H_Z '=' H_FLOAT { h.impedance = yylval.floatval; h.impedance_set = rnd_true; } + H_D '=' H_FLOAT { h.delay = yylval.floatval; } + useg_resistance; + +useg_resistance + : H_R '=' H_FLOAT { h.resistance = yylval.floatval; h.resistance_set = rnd_true;} + ')' + | ')' + ; + +polygon + : '{' H_POLYGON { new_record(); } polygon_param_list coord_point { if (exec_polygon_begin(&h)) YYERROR; } + lines_and_curves '}' { if (exec_polygon_end(&h)) YYERROR; } ; + +polygon_param_list + : polygon_param_list polygon_param + | polygon_param + ; + +polygon_param + : layer_name + | width + | polygon_type + | polygon_id + ; + +polygon_id + : H_ID '=' H_POSINT { h.id = yylval.intval; h.id_set = rnd_true; } /* polygon id is a non-negative integer */ + ; + +polygon_type + : H_T '=' H_POUR { h.polygon_type = POLYGON_TYPE_POUR; h.polygon_type_set = rnd_true; } + | H_T '=' H_PLANE { h.polygon_type = POLYGON_TYPE_PLANE; h.polygon_type_set = rnd_true; } + | H_T '=' H_COPPER { h.polygon_type = POLYGON_TYPE_COPPER; h.polygon_type_set = rnd_true; } + ; + +polyvoid + : '{' H_POLYVOID { new_record(); } polygon_id coord_point { if (exec_polyvoid_begin(&h)) YYERROR; } + lines_and_curves '}' { if (exec_polyvoid_end(&h)) YYERROR; } ; + +polyline + : '{' H_POLYLINE { new_record(); } polygon_param_list coord_point { if (exec_polyline_begin(&h)) YYERROR; } + lines_and_curves '}' { if (exec_polyline_end(&h)) YYERROR; } ; + +lines_and_curves + : lines_and_curves line_or_curve + | line_or_curve + ; + +line_or_curve + : line + | curve + | ')' { hyyerror("warning: unexpected ')'"); } + | '(' error ')' + ; + +line + : '(' H_LINE { new_record(); } coord_point ')' { if (exec_line(&h)) YYERROR; } ; + +curve + : '(' H_CURVE { new_record(); } coord_arc ')' { if (exec_curve(&h)) YYERROR; } ; + +net_attribute + : '(' H_A H_N '=' H_STRING { h.name = yylval.strval; } H_V '=' H_STRING { h.value = yylval.strval; } ')' { if (exec_net_attribute(&h)) YYERROR; } ; + + /* net class */ + +netclass + : '{' H_NET_CLASS '=' H_STRING { h.net_class_name = yylval.strval; if (exec_net_class(&h)) YYERROR; } netclass_subrecords ; + +netclass_subrecords + : netclass_paramlist '}' + | '}' + ; + +netclass_paramlist + : netclass_paramlist netclass_param + | netclass_param + ; + +netclass_param + : netclass_attribute + | net_name + | '(' error ')' + ; + +net_name + : '(' H_N H_N '=' H_STRING { h.net_name = yylval.strval; } ')' { if (exec_net_class_element(&h)) YYERROR; } ; + +netclass_attribute + : '(' H_A H_N '=' H_STRING { h.name = yylval.strval; } H_V '=' H_STRING { h.value = yylval.strval; } ')' { if (exec_net_class_attribute(&h)) YYERROR; } ; + + /* end */ + +end + : '{' H_END '}' { if (exec_end(&h)) YYERROR; } ; + + /* key */ + +key + : '{' H_KEY '=' H_STRING { h.key = yylval.strval; } '}' { if (exec_key(&h)) YYERROR; } ; + + /* coordinates */ + +coord_point + : H_X '=' H_FLOAT { h.x = yylval.floatval; } H_Y '=' H_FLOAT { h.y = yylval.floatval; } ; + +coord_point1 + : H_X1 '=' H_FLOAT { h.x1 = yylval.floatval; } H_Y1 '=' H_FLOAT { h.y1 = yylval.floatval; } ; + +coord_point2 + : H_X2 '=' H_FLOAT { h.x2 = yylval.floatval; } H_Y2 '=' H_FLOAT { h.y2 = yylval.floatval; } ; + +coord_line + : coord_point1 coord_point2 ; + +coord_arc + : coord_line H_XC '=' H_FLOAT { h.xc = yylval.floatval; } H_YC '=' H_FLOAT { h.yc = yylval.floatval; } H_R '=' H_FLOAT { h.r = yylval.floatval; } ; + +%% + +/* + * Supporting C routines + */ + +void hyyerror(const char *msg) +{ + /* log pcb-rnd message */ + hyp_error(msg); +} + +void hyyprint(FILE *file, int type, YYSTYPE value) +{ + if (type == H_STRING) + fprintf (file, "%s", value.strval); + else if (type == H_FLOAT) + fprintf (file, "%g", value.floatval); + else if (type == H_BOOL) + fprintf (file, "%i", value.boolval); + return; +} + +/* + * reset parse_param struct at beginning of record + */ + +static void new_record() +{ + h.vers = 0; + h.detailed = rnd_false; + h.unit_system_english = rnd_false; + h.metal_thickness_weight = rnd_false; + h.default_plane_separation = 0; + h.use_die_for_metal = rnd_false; + h.bulk_resistivity = 0; + h.conformal = rnd_false; + h.epsilon_r = 0; + h.layer_name = NULL; + h.loss_tangent = 0; + h.material_name = NULL; + h.plane_separation = 0; + h.plating_thickness = 0; + h.prepreg = rnd_false; + h.temperature_coefficient = 0; + h.thickness = 0; + h.bulk_resistivity_set = rnd_false; + h.conformal_set = rnd_false; + h.epsilon_r_set = rnd_false; + h.layer_name_set = rnd_false; + h.loss_tangent_set = rnd_false; + h.material_name_set = rnd_false; + h.plane_separation_set = rnd_false; + h.plating_thickness_set = rnd_false; + h.prepreg_set = rnd_false; + h.temperature_coefficient_set = rnd_false; + h.thickness_set = rnd_false; + h.device_type = NULL; + h.ref = NULL; + h.value_float = 0; + h.value_string = NULL; + h.package = NULL; + h.name_set = rnd_false; + h.value_float_set = rnd_false; + h.value_string_set = rnd_false; + h.package_set = rnd_false; + h.voltage_specified = rnd_false; + h.conversion = rnd_false; + h.padstack_name = NULL; + h.drill_size = 0; + h.pad_shape = 0; + h.pad_sx = 0; + h.pad_sy = 0; + h.pad_angle = 0; + h.thermal_clear_shape = 0; + h.thermal_clear_sx = 0; + h.thermal_clear_sy = 0; + h.thermal_clear_angle = 0; + h.pad_type = PAD_TYPE_METAL; + h.padstack_name_set = rnd_false; + h.drill_size_set = rnd_false; + h.pad_type_set = rnd_false; + h.width = 0; + h.left_plane_separation = 0; + h.width_set = rnd_false; + h.left_plane_separation_set = rnd_false; + h.layer1_name = NULL; + h.layer1_name_set = rnd_false; + h.layer2_name = NULL; + h.layer2_name_set = rnd_false; + h.via_pad_shape = NULL; + h.via_pad_shape_set = rnd_false; + h.via_pad_sx = 0; + h.via_pad_sx_set = rnd_false; + h.via_pad_sy = 0; + h.via_pad_sy_set = rnd_false; + h.via_pad_angle = 0; + h.via_pad_angle_set = rnd_false; + h.via_pad1_shape = NULL; + h.via_pad1_shape_set = rnd_false; + h.via_pad1_sx = 0; + h.via_pad1_sx_set = rnd_false; + h.via_pad1_sy = 0; + h.via_pad1_sy_set = rnd_false; + h.via_pad1_angle = 0; + h.via_pad1_angle_set = rnd_false; + h.via_pad2_shape = NULL; + h.via_pad2_shape_set = rnd_false; + h.via_pad2_sx = 0; + h.via_pad2_sx_set = rnd_false; + h.via_pad2_sy = 0; + h.via_pad2_sy_set = rnd_false; + h.via_pad2_angle = 0; + h.via_pad2_angle_set = rnd_false; + h.pin_reference = NULL; + h.pin_reference_set = rnd_false; + h.pin_function = PIN_SIM_BOTH; + h.pin_function_set = rnd_false; + h.zlayer_name = NULL; + h.zlayer_name_set = rnd_false; + h.length = 0; + h.impedance = 0; + h.impedance_set = rnd_false; + h.delay = 0; + h.resistance = 0; + h.resistance_set = rnd_false; + h.id = -1; + h.id_set = rnd_false; + h.polygon_type = POLYGON_TYPE_PLANE; + h.polygon_type_set = rnd_false; + h.net_class_name = NULL; + h.net_name = NULL; + h.key = NULL; + h.name = NULL; + h.value = NULL; + h.x = 0; + h.y = 0; + h.x1 = 0; + h.y1 = 0; + h.x2 = 0; + h.y2 = 0; + h.xc = 0; + h.yc = 0; + h.r = 0; + + return; +} + +/* not truncated */ Index: tags/2.3.0/src_plugins/io_hyp/io_hyp.c =================================================================== --- tags/2.3.0/src_plugins/io_hyp/io_hyp.c (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/io_hyp.c (revision 33253) @@ -0,0 +1,203 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * + * hyperlynx .hyp importer, plugin entry + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "event.h" +#include "plug_io.h" +#include "parser.h" +#include "board.h" +#include "write.h" +#include "obj_rat.h" + +#include "menu_internal.c" + +static const char *hyp_cookie = "hyp importer"; + + +static pcb_plug_io_t io_hyp; + +int io_hyp_fmt(pcb_plug_io_t * ctx, pcb_plug_iot_t typ, int wr, const char *fmt) +{ + if (wr && (typ & PCB_IOT_FOOTPRINT)) /* no footprint write */ + return 0; + + if (strcmp(ctx->description, fmt) == 0) + return 200; + + if ((strcmp(fmt, "hyp") != 0) || ((typ & (~(PCB_IOT_PCB))) != 0)) + return 0; + + return 70; +} + + + +static const char pcb_acts_LoadhypFrom[] = "LoadhypFrom(filename[, \"debug\"]...)"; + +static const char pcb_acth_LoadhypFrom[] = "Loads the specified Hyperlynx file."; + +fgw_error_t pcb_act_LoadhypFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + int debug = 0; + rnd_bool_t retval; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadhypFrom, fname = argv[1].val.str); + + if ((fname == NULL) || (*fname == '\0')) { + fname = rnd_gui->fileselect(rnd_gui, + "Load .hyp file...", "Picks a hyperlynx file to load.\n", "default.hyp", + ".hyp", NULL, "hyp", RND_HID_FSD_READ, NULL); + } + + if (fname == NULL) { + RND_ACT_IRES(1); + return 0; + } + +TODO(": rewrite this - this is very unpcb-rnd") +#if 0 + int i = 0; + /* + * debug level. + * one "debug" argument: hyperlynx logging. + * two "debug" arguments: hyperlynx and bison logging. + * three "debug" arguments: hyperlynx, bison and flex logging. + */ + + for (i = 0; i < argc; i++) + debug += (strcmp(argv[i], "debug") == 0); +#endif + + if (debug > 0) + rnd_message(RND_MSG_INFO, "Importing Hyperlynx file '%s', debug level %d\n", fname, debug); + + rnd_hid_busy(PCB, 1); + retval = hyp_parse(PCB->Data, fname, debug); + rnd_hid_busy(PCB, 0); + + /* notify GUI */ + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + rnd_event(&PCB->hidlib, RND_EVENT_BOARD_CHANGED, NULL); + + RND_ACT_IRES(retval); + return 0; +} + +rnd_action_t hyp_action_list[] = { + {"LoadhypFrom", pcb_act_LoadhypFrom, pcb_acth_LoadhypFrom, pcb_acts_LoadhypFrom} +}; + +/* cheap, partial read of the file to determine if it is worth running the real parser */ +int io_hyp_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE * f) +{ + char line[1024]; + int found = 0, lineno = 0; + + if (typ != PCB_IOT_PCB) + return 0; /* support only boards for now */ + + /* look for {VERSION and {BOARD in the first 32 lines, not assuming indentation */ + while (fgets(line, sizeof(line), f) != NULL) { + if ((found == 0) && (strstr(line, "{VERSION="))) + found = 1; + if ((found == 1) && (strstr(line, "{BOARD"))) + return 1; + lineno++; + if (lineno > 32) + break; + } + return 0; +} + +int io_hyp_read_pcb(pcb_plug_io_t * ctx, pcb_board_t * pcb, const char *Filename, rnd_conf_role_t settings_dest) +{ + int res = hyp_parse(pcb->Data, Filename, 0); + pcb_layer_auto_fixup(pcb); + pcb_layer_colors_from_conf(pcb, 1); + pcb_rat_all_anchor_guess(pcb->Data); + return res; +} + +int pplg_check_ver_io_hyp(int ver_needed) +{ + return 0; +} + +void pplg_uninit_io_hyp(void) +{ + rnd_remove_actions_by_cookie(hyp_cookie); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_hyp); + rnd_hid_menu_unload(rnd_gui, hyp_cookie); +} + +int pplg_init_io_hyp(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + io_hyp.plugin_data = NULL; + io_hyp.fmt_support_prio = io_hyp_fmt; + io_hyp.test_parse = io_hyp_test_parse; + io_hyp.parse_pcb = io_hyp_read_pcb; +/* io_hyp.parse_footprint = NULL; + io_hyp.map_footprint = NULL; + io_hyp.parse_font = NULL; + io_hyp.write_buffer = io_hyp_write_buffer;*/ + io_hyp.write_pcb = io_hyp_write_pcb; + io_hyp.default_fmt = "hyp"; + io_hyp.description = "hyperlynx"; + io_hyp.save_preference_prio = 30; + io_hyp.default_extension = ".hyp"; +TODO(": look these up") + io_hyp.fp_extension = ".hyp_mod"; + io_hyp.mime_type = "application/x-hyp-pcb"; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_hyp); + + + RND_REGISTER_ACTIONS(hyp_action_list, hyp_cookie) + + rnd_hid_menu_load(rnd_gui, NULL, hyp_cookie, 130, NULL, 0, hyp_menu, "plugin: io_hyp"); + + return 0; +} + +/* not truncated */ Index: tags/2.3.0/src_plugins/io_hyp/io_hyp.pup =================================================================== --- tags/2.3.0/src_plugins/io_hyp/io_hyp.pup (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/io_hyp.pup (revision 33253) @@ -0,0 +1,12 @@ +$class io +$short hyperlynx .hyp loader +$long Import plugin for hyperlynx geometry (no polygons yet). +$state works +$fmt-native no +$fmt-feature-r hyperlynx board, version 2 and above +$fmt-feature-w hyperlynx board, version 2.0 +$package io-alien +default buildin +autoload 1 +dep lib_netmap + Index: tags/2.3.0/src_plugins/io_hyp/parser.c =================================================================== --- tags/2.3.0/src_plugins/io_hyp/parser.c (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/parser.c (revision 33253) @@ -0,0 +1,2726 @@ +/* + * read hyperlynx files + * Copyright 2016 Koen De Vleeschauwer. + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This file is part of pcb-rnd. + * + * 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, see . + */ + +#define MAX_STRING 256 + +#include "parser.h" +#include "hyp_l.h" +#include "hyp_y.h" +#include +#include +#include "flag_str.h" +#include "polygon.h" +#include "board.h" +#include "layer.h" +#include "data.h" +#include "search.h" +#include "rotate.h" +#include +#include "plug_io.h" +#include +#include +#include "../src_plugins/lib_compat_help/pstk_help.h" +#include "../src_plugins/lib_compat_help/subc_help.h" +#include + +#define MASK_OFFS +RND_MIL_TO_COORD(10) +#define PASTE_OFFS -RND_MIL_TO_COORD(10) + + +#undef min +#undef max +#define min(x, y) ((x) < (y) ? (x) : (y)) +#define max(x, y) ((x) > (y) ? (x) : (y)) + +/* + * the board is shared between all routines. + */ + +pcb_data_t *hyp_dest; + +/* + * board outline is a linked list of arcs and line segments. + */ + +typedef struct outline_s { + rnd_coord_t x1; + rnd_coord_t y1; + rnd_coord_t x2; + rnd_coord_t y2; + rnd_coord_t xc; + rnd_coord_t yc; + rnd_coord_t r; + rnd_bool_t is_arc; /* arc or line */ + rnd_bool_t used; /* already included in outline */ + struct outline_s *next; +} outline_t; + +outline_t *outline_head; +outline_t *outline_tail; + +void hyp_set_origin(); /* set origin so all coordinates are positive */ +void hyp_perimeter(); /* add board outline to pcb */ +void hyp_draw_polygons(); /* add all hyperlynx polygons to pcb */ +static void hyp_subcs_fin(void); +void hyp_resize_board(); /* resize board to fit outline */ +rnd_bool_t hyp_is_bottom_layer(char *); /* true if bottom layer */ + +/* layer creation */ +int layer_count; +rnd_layer_id_t top_layer_id, bottom_layer_id; +void hyp_reset_layers(); /* reset layer stack to minimun */ +rnd_layer_id_t hyp_create_layer(char *lname); /* create new copper layer at bottom of stack */ + +int hyp_debug; /* logging on/off switch */ + +/* Physical constants */ +double inches; /* inches to m */ +double copper_imperial_weight; /* metal thickness in ounces/ft2 */ +double copper_metric_weight; /* metal thickness in grams/cm2 */ +double copper_bulk_resistivity; /* metal resistivity in ohm meter */ +double copper_temperature_coefficient; /* temperature coefficient of bulk resistivity */ +double fr4_epsilon_r; /* dielectric constant of substrate */ +double fr4_loss_tangent; /* loss tangent of substrate */ +double conformal_epsilon_r; /* dielectric constant of conformal coating */ + +/* Hyperlynx UNIT and OPTIONS */ +double unit; /* conversion factor: pcb length units to meters */ +double metal_thickness_unit; /* conversion factor: metal thickness to meters */ + +rnd_bool use_die_for_metal; /* use dielectric constant and loss tangent of dielectric for metal layers */ + +rnd_coord_t board_clearance; /* distance between PLANE polygon and copper of different nets; -1 if not set */ + +/* stackup */ +rnd_bool layer_is_plane[PCB_MAX_LAYER]; /* whether layer is signal or plane layer */ +rnd_coord_t layer_clearance[PCB_MAX_LAYER]; /* separation between fill copper and signals on layer */ + +/* net */ +char *net_name; /* name of current copper */ +rnd_coord_t net_clearance; /* distance between PLANE polygon and net copper */ + +/* netlist */ +void hyp_netlist_begin(); +void hyp_netlist_add(char *device_name, char *pin_name); +void hyp_netlist_end(); + +/* devices */ + +typedef struct device_s { + char *ref; + char *name; /* optional */ + char *value; /* optional */ + char *layer_name; + pcb_subc_t *subc; + struct device_s *next; +} device_t; + +device_t *device_head; +int unknown_device_number; +int unknown_pin_number; + +/* padstack */ + +typedef struct padstack_element_s { + char *layer_name; + int pad_shape; + rnd_coord_t pad_sx; + rnd_coord_t pad_sy; + double pad_angle; + rnd_coord_t thermal_clear_sx; + rnd_coord_t thermal_clear_sy; + double thermal_clear_angle; + pad_type_enum pad_type; + struct padstack_element_s *next; +} padstack_element_t; + +padstack_element_t *current_pstk_element; + +typedef struct padstack_s { + char *name; + rnd_coord_t drill_size; + struct padstack_element_s *padstack; + struct padstack_s *next; +} padstack_t; + +padstack_t *padstack_head; +padstack_t *current_pstk; + +/* polygons */ + +/* + * a hyperlynx polygon is a sequence of line and arc segments. + * + * if is_arc is false, draw a line to (x1, y1). + * if is_arc is true, draw an arc from (x1, y1) to (x2, y2) with center (xc, yc). + * + * is_first marks the first vertex of a contour. + * The first contour is the outer edge of the polygon; the following contours are holes. + */ + +typedef struct hyp_vertex_s { + rnd_coord_t x1; + rnd_coord_t y1; + rnd_coord_t x2; + rnd_coord_t y2; + rnd_coord_t xc; + rnd_coord_t yc; + rnd_coord_t r; + rnd_bool_t is_first; /* true if first vertex of contour */ + rnd_bool_t is_arc; /* true if arc */ + struct hyp_vertex_s *next; +} hyp_vertex_t; + + /* linked list to store correspondence between hyperlynx polygon id's and pcb polygons. */ +typedef struct hyp_polygon_s { + int hyp_poly_id; /* hyperlynx polygon/polyline id */ + polygon_type_enum hyp_poly_type; /* pour, copper, ... */ + rnd_bool_t is_polygon; /* true if polygon, false if polyline */ + char *layer_name; /* layer of polygon */ + rnd_coord_t line_width; /* line width of edge */ + rnd_coord_t clearance; /* clearance with other copper */ + hyp_vertex_t *vertex; /* polygon contours as linked list of vertices */ + struct hyp_polygon_s *next; +} hyp_polygon_t; + +hyp_polygon_t *polygon_head = NULL; /* linked list of all polygons */ +hyp_vertex_t *current_vertex = NULL; /* keeps track where to add next polygon segment when parsing polygons */ + +/* origin. Chosen so all coordinates are positive. */ +rnd_coord_t origin_x; +rnd_coord_t origin_y; + +/* + * Conversion from hyperlynx to rnd_coord_t + */ + +/* meter to rnd_coord_t */ + +static rnd_coord_t m2coord(double m) +{ + return ((rnd_coord_t) RND_MM_TO_COORD(1000.0 * m)); +} + +/* xy coordinates to rnd_coord_t, without offset */ + +static rnd_coord_t xy2coord(double f) +{ + return (m2coord(unit * f)); +} + + +/* x coordinates to rnd_coord_t, with offset */ + +static rnd_coord_t x2coord(double f) +{ + return (m2coord(unit * f) - origin_x); +} + +/* y coordinates to rnd_coord_t, with offset */ + +static rnd_coord_t y2coord(double f) +{ + return (origin_y - m2coord(unit * f)); +} + +/* z coordinates to rnd_coord_t. No offset needed. */ + +static rnd_coord_t z2coord(double f) +{ + return (m2coord(metal_thickness_unit * f)); +} + +/* + * initialize physical constants + */ + +void hyp_init(void) +{ + int n; + + unit = 1; + metal_thickness_unit = 1; + use_die_for_metal = rnd_false; + + inches = 0.0254; /* inches to m */ + copper_imperial_weight = 1.341; /* metal thickness in ounces/ft2. 1 oz/ft2 copper = 1.341 mil */ + copper_metric_weight = 0.1116; /* metal thickness in grams/cm2. 1 gr/cm2 copper = 0.1116 cm */ + copper_bulk_resistivity = 1.724e-8; + copper_temperature_coefficient = 0.00393; + fr4_epsilon_r = 4.3; + fr4_loss_tangent = 0.020; + conformal_epsilon_r = 3.3; /* dielectric constant of conformal layer */ + board_clearance = -1; /* distance between PLANE polygon and copper of different nets; -1 if not set */ + + /* empty board outline */ + outline_head = NULL; + outline_tail = NULL; + + /* clear layer info */ + for (n = 1; n < PCB_MAX_LAYER; n++) { + layer_is_plane[n] = rnd_false; /* signal layer */ + layer_clearance[n] = -1; /* no separation between fill copper and signals on layer */ + } + layer_count = 0; + top_layer_id = -1; + bottom_layer_id = -1; + + /* clear padstack */ + padstack_head = NULL; + current_pstk = NULL; + current_pstk_element = NULL; + + /* clear devices */ + device_head = NULL; + unknown_device_number = 0; + unknown_pin_number = 0; + + /* clear polygon data */ + polygon_head = NULL; + current_vertex = NULL; + + /* set origin */ + origin_x = 0; + origin_y = 0; + + return; +} + +/* + * called by pcb-rnd to load hyperlynx file + */ + +int hyp_parse(pcb_data_t * dest, const char *fname, int debug) +{ + int retval; + + /* set debug levels */ + hyyset_debug(debug > 2); /* switch flex logging on */ + hyydebug = (debug > 1); /* switch bison logging on */ + hyp_debug = (debug > 0); /* switch hyperlynx logging on */ + + hyp_init(); + + hyp_netlist_begin(); + + hyp_reset_layers(); + + /* set shared board */ + hyp_dest = dest; + + /* reset line number to first line */ + hyyset_lineno(1); + + /* parse hyperlynx file */ + hyyin = rnd_fopen(&PCB->hidlib, fname, "r"); + if (hyyin == NULL) + return 1; + retval = hyyparse(); + fclose(hyyin); + + /* set up polygons */ + hyp_draw_polygons(); + + /* postprocess/finalize subcircuits */ + hyp_subcs_fin(); + + /* add board outline last */ + hyp_perimeter(); + + /* clear */ + hyp_dest = NULL; + + hyp_netlist_end(); + + return retval; +} + +/* print error message */ +void hyp_error(const char *msg) +{ + rnd_message_level_t level; + + if (strstr(msg, "warning")) + level = RND_MSG_WARNING; + else + level = RND_MSG_ERROR; + + rnd_message(level, "line %d: %s at '%s'\n", hyylineno, msg, hyytext); +} + +/* + * find padstack by name + */ +TODO(": use a hash instead") +padstack_t *hyp_pstk_by_name(char *padstack_name) +{ + padstack_t *i; + for (i = padstack_head; i != NULL; i = i->next) + if (strcmp(i->name, padstack_name) == 0) + return i; + return NULL; +} + +/* + * netlist - assign pin or pad to net + */ + +void hyp_netlist_begin() +{ + /* clear netlist */ + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + return; +} + +/* add pin to net */ +void hyp_netlist_add(char *device_name, char *pin_name) +{ + char conn[MAX_STRING]; + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "netlist net: '%s' device: '%s' pin: '%s'\n", net_name, device_name, pin_name); + + if ((net_name != NULL) && (device_name != NULL) && (pin_name != NULL)) { + rnd_snprintf(conn, sizeof(conn), "%s-%s", device_name, pin_name); + rnd_actionva(&PCB->hidlib, "Netlist", "Add", net_name, conn, NULL); + } + return; +} + +void hyp_netlist_end() +{ + /* sort netlist */ + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + return; +} + +/* + * find hyperlynx device by name + */ +TODO(": convert this into a hash") +device_t *hyp_device_by_name(char *device_name) +{ + device_t *i; + for (i = device_head; i != NULL; i = i->next) + if (strcmp(i->ref, device_name) == 0) + return i; + return NULL; +} + +pcb_subc_t *hyp_create_subc_by_name(char *refdes, rnd_coord_t x, rnd_coord_t y) +{ + pcb_subc_t *subc; + unsigned int text_direction = 0; + int text_scale = 100; + device_t *dev; + int on_bottom; + + /* does the device already exist? */ + subc = pcb_subc_by_refdes(hyp_dest, refdes); + if (subc != NULL) + return subc; + + /* device needs to be created. Search in DEVICE records. */ + dev = hyp_device_by_name(refdes); + if (dev == NULL) { + /* no device with this name exists, and no such device has been listed in a DEVICE record. Let's create the device anyhow so we can continue. Assume device is on component side. */ + rnd_message(RND_MSG_WARNING, "device \"%s\" not specified in DEVICE record. Assuming device is on component side.\n", refdes); + + dev = calloc(sizeof(device_t), 1); + dev->next = device_head; + device_head = dev; + } + + /* device on component or solder side? */ + if (dev->layer_name != NULL) + on_bottom = hyp_is_bottom_layer(dev->layer_name); + if (on_bottom) + text_direction = 2; + + /* create */ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "creating device \"%s\".\n", dev->ref); + + subc = pcb_subc_alloc(); + pcb_subc_create_aux(subc, x, y, 0.0, on_bottom); + pcb_attribute_put(&subc->Attributes, "refdes", refdes); + pcb_subc_add_refdes_text(subc, x, y, text_direction, text_scale, on_bottom); + pcb_subc_reg(hyp_dest, subc); + pcb_subc_bind_globals(hyp_dest->parent.board, subc); + + dev->subc = subc; + + return subc; +} + +static void hyp_subc_fin(pcb_subc_t *subc) +{ + pcb_subc_bbox(subc); + if (hyp_dest->subc_tree == NULL) + hyp_dest->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(hyp_dest->subc_tree, (rnd_box_t *)subc); + pcb_subc_rebind(hyp_dest->parent.board, subc); +} + +static void hyp_subcs_fin(void) +{ + device_t *d; + for(d = device_head; d != NULL; d = d->next) + if (d->subc != NULL) + hyp_subc_fin(d->subc); +} + +/* + * add segment to board outline + */ + +void hyp_perimeter_segment_add(outline_t * s, rnd_bool_t forward) +{ + rnd_layer_id_t outline_id; + pcb_layer_t *outline_layer; + + /* get outline layer */ + outline_id = pcb_layer_by_name(PCB->Data, "outline"); + if (outline_id < 0) { + rnd_message(RND_MSG_ERROR, "no outline layer.\n"); + return; + } + outline_layer = pcb_get_layer(PCB->Data, outline_id); + if (outline_layer == NULL) { + rnd_message(RND_MSG_ERROR, "get outline layer failed.\n"); + return; + } + + /* mark segment as used, so we don't use it twice */ + s->used = rnd_true; + + /* debugging */ + if (hyp_debug) { + if (forward) + rnd_message(RND_MSG_DEBUG, "outline: fwd %s from (%ml, %ml) to (%ml, %ml)\n", s->is_arc ? "arc" : "line", s->x1, s->y1, + s->x2, s->y2); + else + rnd_message(RND_MSG_DEBUG, "outline: bwd %s from (%ml, %ml) to (%ml, %ml)\n", s->is_arc ? "arc" : "line", s->x2, s->y2, s->x1, s->y1); /* add segment back to front */ + } + + if (s->is_arc) { + /* counterclockwise arc from (x1, y1) to (x2, y2) */ + hyp_arc_new(outline_layer, s->x1, s->y1, s->x2, s->y2, s->xc, s->yc, s->r, s->r, rnd_false, 1, 0, pcb_no_flags()); + } + else + /* line from (x1, y1) to (x2, y2) */ + pcb_line_new(outline_layer, s->x1, s->y1, s->x2, s->y2, 1, 0, pcb_no_flags()); + + return; +} + +/* + * Check whether point (end_x, end_y) is connected to point (begin_x, begin_y) via un-used segment s and other un-used segments. + */ + +rnd_bool_t hyp_segment_connected(rnd_coord_t begin_x, rnd_coord_t begin_y, rnd_coord_t end_x, rnd_coord_t end_y, outline_t * s) +{ + outline_t *i; + rnd_bool_t connected; + + connected = (begin_x == end_x) && (begin_y == end_y); /* trivial case */ + + if (!connected) { + /* recursive descent */ + s->used = rnd_true; + + for (i = outline_head; i != NULL; i = i->next) { + if (i->used) + continue; + if ((i->x1 == begin_x) && (i->y1 == begin_y)) { + connected = ((i->x2 == end_x) && (i->y2 == end_y)) || hyp_segment_connected(i->x2, i->y2, end_x, end_y, i); + if (connected) + break; + } + /* try back-to-front */ + if ((i->x2 == begin_x) && (i->y2 == begin_y)) { + connected = ((i->x1 == end_x) && (i->y1 == end_y)) || hyp_segment_connected(i->x1, i->y1, end_x, end_y, i); + if (connected) + break; + } + } + + s->used = rnd_false; + } + + return connected; +} + +/* + * Sets (origin_x, origin_y) + * Choose origin so that all coordinates are posive. + */ + +void hyp_set_origin() +{ + outline_t *i; + + /* safe initial value */ + if (outline_head != NULL) { + origin_x = outline_head->x1; + origin_y = outline_head->y1; + } + else { + origin_x = 0; + origin_y = 0; + } + + /* choose upper left corner of outline */ + for (i = outline_head; i != NULL; i = i->next) { + /* set origin so all coordinates are positive */ + if (i->x1 < origin_x) + origin_x = i->x1; + if (i->x2 < origin_x) + origin_x = i->x2; + if (i->y1 > origin_y) + origin_y = i->y1; + if (i->y2 > origin_y) + origin_y = i->y2; + if (i->is_arc) { + if (i->xc - i->r < origin_x) + origin_x = i->xc - i->r; + if (i->yc + i->r > origin_y) + origin_y = i->yc + i->r; + } + } +} + +/* + * resize board to fit pcb outline. + */ + +void hyp_resize_board() +{ + rnd_coord_t x_max, x_min, y_max, y_min; + rnd_coord_t width, height; + rnd_coord_t slack = RND_MM_TO_COORD(1); + outline_t *i; + + if (PCB == NULL) + return; + if (outline_head == NULL) + return; + + x_min = x_max = outline_head->x1; + y_min = y_max = outline_head->y1; + + for (i = outline_head; i != NULL; i = i->next) { + + x_max = max(x_max, i->x1); + x_max = max(x_max, i->x2); + y_max = max(y_max, i->y1); + y_max = max(y_max, i->y2); + + x_min = min(x_min, i->x1); + x_min = min(x_min, i->x2); + y_min = min(y_min, i->y1); + y_min = min(y_min, i->y2); + + if (i->is_arc) { + x_max = max(x_max, i->xc + i->r); + y_max = max(y_max, i->yc + i->r); + + x_min = min(x_min, i->xc - i->r); + y_min = min(y_min, i->yc - i->r); + } + } + + width = max(PCB->hidlib.size_x, x_max - x_min + slack); + height = max(PCB->hidlib.size_y, y_max - y_min + slack); + + /* resize if board too small */ + if ((width > PCB->hidlib.size_x) || (height > PCB->hidlib.size_y)) + pcb_board_resize(width, height, 0); + + return; + +} + +/* + * Draw board perimeter. + * The first segment is part of the first polygon. + * The first polygon of the board perimeter is positive, the rest are holes. + * Segments do not necessarily occur in order. + */ + +void hyp_perimeter() +{ + rnd_bool_t warn_not_closed; + rnd_bool_t segment_found; + rnd_bool_t polygon_closed; + rnd_coord_t begin_x, begin_y, last_x, last_y; + outline_t *i; + outline_t *j; + + warn_not_closed = rnd_false; + + /* iterate over perimeter segments and adjust origin */ + for (i = outline_head; i != NULL; i = i->next) { + /* set origin so all coordinates are positive */ + i->x1 = i->x1 - origin_x; + i->y1 = origin_y - i->y1; + i->x2 = i->x2 - origin_x; + i->y2 = origin_y - i->y2; + if (i->is_arc) { + i->xc = i->xc - origin_x; + i->yc = origin_y - i->yc; + } + } + + /* iterate over perimeter polygons */ + while (rnd_true) { + + /* find first free segment */ + for (i = outline_head; i != NULL; i = i->next) + if (i->used == rnd_false) + break; + + /* exit if no segments found */ + if (i == NULL) + break; + + /* first point of polygon (begin_x, begin_y) */ + begin_x = i->x1; + begin_y = i->y1; + + /* last point of polygon (last_x, last_y) */ + last_x = i->x2; + last_y = i->y2; + + /* add segment */ + hyp_perimeter_segment_add(i, rnd_true); + + /* add polygon segments until the polygon is closed */ + polygon_closed = rnd_false; + while (!polygon_closed) { + +#undef XXX +#ifdef XXX + rnd_message(RND_MSG_DEBUG, "perimeter: last_x = %ml last_y = %ml\n", last_x, last_y); + for (i = outline_head; i != NULL; i = i->next) + if (!i->used) + rnd_message(RND_MSG_DEBUG, "perimeter segments available: %s from (%ml, %ml) to (%ml, %ml)\n", + i->is_arc ? "arc " : "line", i->x1, i->y1, i->x2, i->y2); +#endif + + /* find segment to add to current polygon */ + segment_found = rnd_false; + + /* XXX prefer closed polygon over open polyline */ + + for (i = outline_head; i != NULL; i = i->next) { + if (i->used) + continue; + + if ((last_x == i->x1) && (last_y == i->y1)) { + if (!hyp_segment_connected(i->x2, i->y2, begin_x, begin_y, i)) + continue; + /* first point of segment is last point of current edge: add segment to edge */ + segment_found = rnd_true; + hyp_perimeter_segment_add(i, rnd_true); + last_x = i->x2; + last_y = i->y2; + } + else if ((last_x == i->x2) && (last_y == i->y2)) { + if (!hyp_segment_connected(i->x1, i->y1, begin_x, begin_y, i)) + continue; + /* last point of segment is last point of current edge: add segment to edge back to front */ + segment_found = rnd_true; + /* add segment back to front */ + hyp_perimeter_segment_add(i, rnd_false); + last_x = i->x1; + last_y = i->y1; + } + if (segment_found) + break; + } + polygon_closed = (begin_x == last_x) && (begin_y == last_y); + if (!polygon_closed && !segment_found) + break; /* can't find anything suitable */ + } + if (polygon_closed) { + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "outline: closed\n"); + } + else { + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "outline: open\n"); + warn_not_closed = rnd_true; + } + } + + /* free segment memory */ + for (i = outline_head; i != NULL; i = j) { + j = i->next; + free(i); + } + outline_head = outline_tail = NULL; + + if (warn_not_closed) + rnd_message(RND_MSG_WARNING, "warning: board outline not closed\n"); + + return; +} + +/* + * reset pcb layer stack + */ +void hyp_reset_layers() +{ + + rnd_layer_id_t id = -1; + rnd_layergrp_id_t gid = -1; + pcb_layergrp_t *grp = NULL; + + pcb_layergrp_inhibit_inc(); + + pcb_layers_reset(PCB); + + pcb_layer_group_setup_default(PCB); + + /* set up dual layer board: top and bottom copper and silk */ + + id = -1; + if (pcb_layergrp_list(PCB, PCB_LYT_SILK | PCB_LYT_TOP, &gid, 1) == 1) + id = pcb_layer_create(PCB, gid, "top silk", 0); + if (id < 0) + rnd_message(RND_MSG_ERROR, "failed to create top silk\n"); + + id = -1; + if (pcb_layergrp_list(PCB, PCB_LYT_SILK | PCB_LYT_BOTTOM, &gid, 1) == 1) + id = pcb_layer_create(PCB, gid, "bottom silk", 0); + if (id < 0) + rnd_message(RND_MSG_ERROR, "failed to create bottom silk\n"); + + top_layer_id = -1; + if (pcb_layergrp_list(PCB, PCB_LYT_COPPER | PCB_LYT_TOP, &gid, 1) == 1) + top_layer_id = pcb_layer_create(PCB, gid, "", 0); + if (top_layer_id < 0) + rnd_message(RND_MSG_ERROR, "failed to create top copper\n"); + + bottom_layer_id = -1; + if (pcb_layergrp_list(PCB, PCB_LYT_COPPER | PCB_LYT_BOTTOM, &gid, 1) == 1) + bottom_layer_id = pcb_layer_create(PCB, gid, "", 0); + if (bottom_layer_id < 0) + rnd_message(RND_MSG_ERROR, "failed to create bottom copper\n"); + + /* create outline layer */ + + id = -1; + grp = pcb_get_grp_new_intern(PCB, -1); + if (grp != NULL) { + id = pcb_layer_create(PCB, grp - PCB->LayerGroups.grp, "outline", 0); + pcb_layergrp_fix_turn_to_outline(grp); + } + if (id < 0) + rnd_message(RND_MSG_ERROR, "failed to create outline\n"); + + pcb_layergrp_inhibit_dec(); + + return; +} + +/* + * Returns the pcb_layer_id of layer "lname". + * If layer lname does not exist, a new copper layer with name "lname" is created. + * If the layer name is NULL, a new copper layer with a new, unused layer name is created. + */ + +rnd_layer_id_t hyp_create_layer(char *lname) +{ + rnd_layer_id_t layer_id; + rnd_layergrp_id_t gid; + pcb_layergrp_t *grp; + char new_layer_name[MAX_STRING]; + int n; + + layer_id = -1; + if (lname != NULL) { + /* we have a layer name. check whether layer already exists */ + layer_id = pcb_layer_by_name(PCB->Data, lname); + if (layer_id >= 0) + return layer_id; /* found. return existing layer. */ + } + else { + /* no layer name given. find unused layer name in range 1..PCB_MAX_LAYER */ + for (n = 1; n < PCB_MAX_LAYER; n++) { + rnd_sprintf(new_layer_name, "%i", n); + if (pcb_layer_by_name(PCB->Data, new_layer_name) < 0) { + lname = new_layer_name; + break; + } + } + if (lname == NULL) + return bottom_layer_id; /* no unused layer name available */ + } + + /* new layer */ + + layer_count++; + switch (layer_count) { + case 1: + /* rename top copper and return */ + pcb_layer_rename(PCB->Data, top_layer_id, lname, 0); + return top_layer_id; + break; + + case 2: + /* rename bottom copper and return */ + pcb_layer_rename(PCB->Data, bottom_layer_id, lname, 0); + return bottom_layer_id; + break; + + default: + + /* create new bottom layer */ + pcb_layergrp_list(PCB, PCB_LYT_COPPER | PCB_LYT_BOTTOM, &gid, 1); + layer_id = pcb_layer_create(PCB, gid, lname, 0); + + /* check if new bottom layer valid */ + if (layer_id < 0) { + /* layer creation failed. return old bottom layer. */ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "running out of layers\n"); + return bottom_layer_id; + } + + /* move old bottom layer to internal */ + grp = pcb_get_grp_new_intern(PCB, -1); + pcb_layer_move_to_group(PCB, bottom_layer_id, grp - PCB->LayerGroups.grp); + + /* created layer becomes new bottom layer */ + bottom_layer_id = layer_id; + return bottom_layer_id; + } + + return bottom_layer_id; +} + +/* + * convert hyperlynx layer name to pcb layer + */ + +pcb_layer_t *hyp_get_layer(parse_param * h) +{ + return pcb_get_layer(PCB->Data, hyp_create_layer(h->layer_name)); +} + +/* + * True if solder side + */ + +rnd_bool_t hyp_is_bottom_layer(char *layer_name) +{ + return ((layer_name != NULL) && (pcb_layer_flags(PCB, pcb_layer_by_name(PCB->Data, layer_name)) & PCB_LYT_BOTTOM)); +} + +/* + * Draw arc from (x1, y1) to (x2, y2) with center (xc, yc) and radius r. + * Direction of arc is clockwise or counter-clockwise, depending upon value of rnd_bool_t Clockwise. + */ + +pcb_arc_t *hyp_arc_new(pcb_layer_t * Layer, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t XC, + rnd_coord_t YC, rnd_coord_t Width, rnd_coord_t Height, rnd_bool_t Clockwise, rnd_coord_t Thickness, + rnd_coord_t Clearance, pcb_flag_t Flags) +{ + rnd_angle_t start_angle; + rnd_angle_t end_angle; + rnd_angle_t delta; + pcb_arc_t *new_arc; + + if (Width < 1) { + start_angle = 0.0; + end_angle = 360.0; + } + else { + /* note: y-axis points down */ + start_angle = 180 + 180 * atan2(YC - Y1, X1 - XC) / M_PI; + end_angle = 180 + 180 * atan2(YC - Y2, X2 - XC) / M_PI; + } + start_angle = rnd_normalize_angle(start_angle); + end_angle = rnd_normalize_angle(end_angle); + + if (Clockwise) + while (start_angle < end_angle) + start_angle += 360; + else + while (end_angle <= start_angle) + end_angle += 360; + + delta = end_angle - start_angle; + + new_arc = pcb_arc_new(Layer, XC, YC, Width, Height, start_angle, delta, Thickness, Clearance, Flags, rnd_true); + + return new_arc; +} + +/* + * Draw an arc from (x1, y1) to (x2, y2) with center (xc, yc) and radius r using a polygonal approximation. + * Arc may be clockwise or counterclockwise. Note pcb-rnd y-axis points downward. + */ +void hyp_arc2contour(rnd_pline_t * contour, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t xc, + rnd_coord_t yc, rnd_coord_t r, rnd_bool_t clockwise) +{ + rnd_coord_t arc_precision = RND_MM_TO_COORD(0.254); /* mm */ + int min_circle_segments = 8; /* 8 seems minimal, 16 seems more than sufficient. */ + int segments; + int poly_points = 0; + int i; + rnd_vector_t v; + + double alpha = atan2(y1 - yc, x1 - xc); + double beta = atan2(y2 - yc, x2 - xc); + + if (contour == NULL) + return; + + if (clockwise) { + /* draw arc clockwise from (x1,y1) to (x2,y2) */ + if (beta < alpha) + beta = beta + 2 * M_PI; + } + else { + /* draw arc counterclockwise from (x1,y1) to (x2,y2) */ + if (alpha < beta) + alpha = alpha + 2 * M_PI; + /* draw a circle if starting and end points are the same */ + if ((x1 == x2) && (y1 == y2)) + beta = alpha + 2 * M_PI; + } + + /* Calculate number of segments needed for a full circle. */ + segments = min_circle_segments; + if (arc_precision > 0) { + /* Increase number of segments until difference between circular arc and polygonal approximation is less than max_arc_error */ + double arc_error; + do { + arc_error = r * (1 - cos(M_PI / segments)); + if (arc_error > arc_precision) + segments += 4; + } + while (arc_error > arc_precision); + } + else if (arc_precision < 0) + rnd_message(RND_MSG_ERROR, "error: negative arc precision\n"); + + /* A full circle is drawn using 'segments' segments; a 90 degree arc using segments/4. */ + poly_points = rnd_round(segments * fabs(beta - alpha) / (2 * M_PI)); + + /* Sanity checks */ + if (poly_points < 1) + poly_points = 1; + + /* add first point to contour */ + v[0] = x1; + v[1] = y1; + rnd_poly_vertex_include(contour->head->prev, rnd_poly_node_create(v)); + + /* intermediate points */ + for (i = 1; i < poly_points; i++) { + double angle = alpha + (beta - alpha) * i / poly_points; + v[0] = xc + r * cos(angle); + v[1] = yc + r * sin(angle); + rnd_poly_vertex_include(contour->head->prev, rnd_poly_node_create(v)); + } + + /* last point */ + v[0] = x2; + v[1] = y2; + rnd_poly_vertex_include(contour->head->prev, rnd_poly_node_create(v)); + + return; +} + +/* + * dump polygon structure for debugging. + */ +void hyp_dump_polygons() +{ + hyp_polygon_t *i; + hyp_vertex_t *v; + + /* loop over all created polygons and draw them */ + for (i = polygon_head; i != NULL; i = i->next) { + rnd_message(RND_MSG_DEBUG, "%s id=%i.\n", (i->is_polygon ? "polygon" : "polyline"), i->hyp_poly_id); + for (v = i->vertex; v != NULL; v = v->next) { + if (v->is_first) + rnd_message(RND_MSG_DEBUG, " contour\n"); + if (v->is_arc) + rnd_message(RND_MSG_DEBUG, " arc x1 = %ml y1 = %ml x2 = %ml y2 = %ml xc = %ml yc = %ml r = %ml\n", v->x1, v->y1, + v->x2, v->y2, v->xc, v->yc, v->r); + else + rnd_message(RND_MSG_DEBUG, " line x1 = %ml y1 = %ml\n", v->x1, v->y1); + } + } +} + +/* + * draw a single polyline + */ + +void hyp_draw_polyline(hyp_polygon_t * polyline) +{ + pcb_layer_t *layer; + rnd_coord_t xpos; + rnd_coord_t ypos; + hyp_vertex_t *vrtx; + + if ((polyline == NULL) || (polyline->vertex == NULL)) + return; + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "draw polyline: drawing poly id=%i.\n", polyline->hyp_poly_id); + + layer = pcb_get_layer(PCB->Data, hyp_create_layer(polyline->layer_name)); + + xpos = polyline->vertex->x1; + ypos = polyline->vertex->y1; + + for (vrtx = polyline->vertex->next; vrtx != NULL; vrtx = vrtx->next) { + if (vrtx->is_first) + break; /* polyvoids in polyline not implemented */ + if (!vrtx->is_arc) { + /* draw line */ + pcb_line_new(layer, xpos, ypos, vrtx->x1, vrtx->y1, polyline->line_width, polyline->clearance, pcb_no_flags()); + /* move on */ + xpos = vrtx->x1; + ypos = vrtx->y1; + } + else { + /* draw clockwise arc from (x1, y2) to (x2, y2) */ + hyp_arc_new(layer, vrtx->x1, vrtx->y1, vrtx->x2, vrtx->y2, vrtx->xc, vrtx->yc, vrtx->r, vrtx->r, rnd_false, + polyline->line_width, polyline->clearance, pcb_no_flags()); + /* move on */ + if ((xpos == vrtx->x1) && (ypos == vrtx->y1)) { + xpos = vrtx->x2; + ypos = vrtx->y2; + } + else if ((xpos == vrtx->x2) && (ypos == vrtx->y2)) { + xpos = vrtx->x1; + ypos = vrtx->y1; + } + } + } + return; +} + +/* + * draw a single polygon + */ + +void hyp_draw_polygon(hyp_polygon_t * polygon) +{ + pcb_layer_t *layer; + rnd_bool_t outer_contour; + hyp_vertex_t *vrtx; + + rnd_polyarea_t *polyarea = NULL; + rnd_pline_t *contour = NULL; + + polyarea = rnd_polyarea_create(); + if (polyarea == NULL) + return; + + if ((polygon == NULL) || (polygon->vertex == NULL)) + return; + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "draw polygon: drawing poly id=%i.\n", polygon->hyp_poly_id); + + layer = pcb_get_layer(PCB->Data, hyp_create_layer(polygon->layer_name)); + + outer_contour = rnd_true; + + for (vrtx = polygon->vertex; vrtx != NULL; vrtx = vrtx->next) { + rnd_vector_t v; + v[0] = vrtx->x1; + v[1] = vrtx->y1; + if ((vrtx->is_first) || (vrtx->next == NULL)) { + if (contour != NULL) { + /* add contour to polyarea */ + rnd_poly_contour_pre(contour, rnd_false); + + /* check contour valid */ + if (rnd_polyarea_contour_check(contour) && hyp_debug) + rnd_message(RND_MSG_WARNING, "draw polygon: bad contour? continuing.\n"); + + /* set orientation for outer contour, negative for holes */ + if (contour->Flags.orient != (outer_contour ? RND_PLF_DIR : RND_PLF_INV)) + rnd_poly_contour_inv(contour); + + /* add contour to polyarea */ + rnd_polyarea_contour_include(polyarea, contour); + + /* first contour is outer contour, remainder are holes */ + outer_contour = rnd_false; + } + /* create new contour */ + contour = rnd_poly_contour_new(v); + if (contour == NULL) + return; + } + else { + if (!vrtx->is_arc) + /* line. add vertex to contour */ + rnd_poly_vertex_include(contour->head->prev, rnd_poly_node_create(v)); + else + /* arc. pcb polyarea contains line segments, not arc segments. convert arc segment to line segments. */ + hyp_arc2contour(contour, vrtx->x1, vrtx->y1, vrtx->x2, vrtx->y2, vrtx->xc, vrtx->yc, vrtx->r, rnd_false); + } + } + + /* add polyarea to pcb */ + if (rnd_poly_valid(polyarea)) + pcb_poly_to_polygons_on_layer(hyp_dest, layer, polyarea, pcb_no_flags()); + else if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "draw polygon: self-intersecting polygon id=%i dropped.\n", polygon->hyp_poly_id); + + return; +} + +/* + * create all polygons + */ + +void hyp_draw_polygons() +{ + hyp_polygon_t *i; + int l, layer_count = 0; + rnd_layer_id_t *layer_array = NULL; + +#ifdef XXX + hyp_dump_polygons(); /* more debugging */ +#endif + + /* get list of copper layer id's */ + layer_count = pcb_layer_list(PCB, PCB_LYT_COPPER, NULL, 0); + if (layer_count <= 0) + return; + layer_array = malloc(sizeof(rnd_layer_id_t) * layer_count); + if (layer_array == NULL) + return; + layer_count = pcb_layer_list(PCB, PCB_LYT_COPPER, layer_array, layer_count); + + /* loop over all layers */ + for (l = 0; l < layer_count; l++) { + rnd_layer_id_t layer_id = layer_array[l]; + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "draw polygons: layer %lx \"%s\"\n", layer_id, pcb_layer_name(PCB->Data, layer_id)); + + /* loop over all polygons of the layer and draw them */ + for (i = polygon_head; i != NULL; i = i->next) { + /* check polygon is on layer */ + if (layer_id != hyp_create_layer(i->layer_name)) + continue; + /* polygon or polyline? */ + if (i->is_polygon) + hyp_draw_polygon(i); + else + hyp_draw_polyline(i); + } + } + + return; +} + +/* + * calculate hyperlynx-style clearance + * + * use plane_separation of, in order: + * - this copper + * - the net this copper belongs to + * - the layer this copper is on + * - the board + * if neither copper, net, layer nor board have plane_separation set, do not set clearance. + */ + +rnd_coord_t hyp_clearance(parse_param * h) +{ + rnd_coord_t clearance; + rnd_layer_id_t layr_id; + + if (h->layer_name_set) + layr_id = hyp_create_layer(h->layer_name); + clearance = -1; + + if (h->plane_separation_set) + clearance = xy2coord(h->plane_separation); + else if (net_clearance >= 0) + clearance = net_clearance; + else if (h->layer_name_set && (layer_clearance[layr_id] >= 0)) + clearance = layer_clearance[layr_id]; + else if (board_clearance >= 0) + clearance = board_clearance; + else + clearance = 0; + + return clearance; +} + +/* exec_* routines are called by parser to interpret hyperlynx file */ + +/* + * 'BOARD_FILE' record. + */ + +rnd_bool exec_board_file(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "board:\n"); + + return 0; +} + +/* + * 'VERSION' record. + * Specifies version number. + */ + +rnd_bool exec_version(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "version: vers = %f\n", h->vers); + + if (h->vers < 1.0) + rnd_message(RND_MSG_DEBUG, "info: version 1.x deprecated\n"); + + return 0; +} + +/* + * 'DATA_MODE' record. + * If DATA_MODE is DETAILED, model can be used for power and signal simulation. + * If DATA_MODE is SIMPLIFIED, model can be used for signal simulation only. + */ + +rnd_bool exec_data_mode(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "data_mode: detailed = %i\n", h->detailed); + + return 0; +} + +/* + * 'UNITS' record. + * Specifies measurement system (english/metric) for the rest of the file. + */ + +rnd_bool exec_units(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "units: unit_system_english = %d metal_thickness_weight = %d\n", h->unit_system_english, + h->metal_thickness_weight); + + /* convert everything to meter */ + + if (h->unit_system_english) { + unit = inches; /* lengths in inches. 1 in = 2.54 cm = 0.0254 m */ + if (h->metal_thickness_weight) + metal_thickness_unit = copper_imperial_weight * unit; /* metal thickness in ounces/ft2. 1 oz/ft2 copper = 1.341 mil */ + else + metal_thickness_unit = unit; /* metal thickness in inches */ + } + else { + unit = 0.01; /* lengths in centimeters. 1 cm = 0.01 m */ + if (h->metal_thickness_weight) + metal_thickness_unit = copper_metric_weight * unit; /* metal thickness in grams/cm2. 1 gr/cm2 copper = 0.1116 cm */ + else + metal_thickness_unit = unit; /* metal thickness in centimeters */ + } + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "units: unit = %f metal_thickness_unit = %f\n", unit, metal_thickness_unit); + + return 0; +} + +/* + * 'PLANE_SEP' record. + * Defines default trace to plane clearance. + */ + +rnd_bool exec_plane_sep(parse_param * h) +{ + board_clearance = xy2coord(h->default_plane_separation); + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "plane_sep: default_plane_separation = %ml\n", board_clearance); + + return 0; +} + +/* + * 'PERIMETER_SEGMENT' subrecord of 'BOARD' record. + * Draws linear board outline segment from (x1, y1) to (x2, y2). + */ + +rnd_bool exec_perimeter_segment(parse_param * h) +{ + outline_t *peri_seg; + + peri_seg = malloc(sizeof(outline_t)); + + /* convert coordinates */ + peri_seg->x1 = xy2coord(h->x1); + peri_seg->y1 = xy2coord(h->y1); + peri_seg->x2 = xy2coord(h->x2); + peri_seg->y2 = xy2coord(h->y2); + peri_seg->xc = 0; + peri_seg->yc = 0; + peri_seg->r = 0; + peri_seg->is_arc = rnd_false; + peri_seg->used = rnd_false; + peri_seg->next = NULL; + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "perimeter_segment: x1 = %ml y1 = %ml x2 = %ml y2 = %ml\n", peri_seg->x1, peri_seg->y1, + peri_seg->x2, peri_seg->y2); + + /* append at end of doubly linked list */ + if (outline_tail == NULL) { + outline_head = peri_seg; + outline_tail = peri_seg; + } + else { + outline_tail->next = peri_seg; + outline_tail = peri_seg; + } + + /* set origin so all coordinates are positive */ + hyp_set_origin(); + + /* resize board if too small to draw outline */ + hyp_resize_board(); + + return 0; +} + +/* + * 'PERIMETER_ARC' subrecord of 'BOARD' record. + * Draws arc segment of board outline. + * Arc drawn counterclockwise from (x1, y1) to (x2, y2) with center (xc, yc) and radius r. + */ + +rnd_bool exec_perimeter_arc(parse_param * h) +{ + outline_t *peri_arc; + + peri_arc = malloc(sizeof(outline_t)); + + peri_arc->x1 = xy2coord(h->x1); + peri_arc->y1 = xy2coord(h->y1); + peri_arc->x2 = xy2coord(h->x2); + peri_arc->y2 = xy2coord(h->y2); + peri_arc->xc = xy2coord(h->xc); + peri_arc->yc = xy2coord(h->yc); + peri_arc->r = xy2coord(h->r); + peri_arc->is_arc = rnd_true; + peri_arc->used = rnd_false; + peri_arc->next = NULL; + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "perimeter_arc: x1 = %ml y1 = %ml x2 = %ml y2 = %ml xc = %ml yc = %ml r = %ml\n", peri_arc->x1, + peri_arc->y1, peri_arc->x2, peri_arc->y2, peri_arc->xc, peri_arc->yc, peri_arc->r); + + /* append at end of doubly linked list */ + if (outline_tail == NULL) { + outline_head = peri_arc; + outline_tail = peri_arc; + } + else { + outline_tail->next = peri_arc; + outline_tail = peri_arc; + } + + /* set origin so all coordinates are positive */ + hyp_set_origin(); + + return 0; +} + +/* + * 'A' attribute subrecord of 'BOARD' record. + * Defines board attributes as name/value pairs. + */ + +rnd_bool exec_board_attribute(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "board_attribute: name = \"%s\" value = \"%s\"\n", h->name, h->value); + + return 0; +} + +/* + * STACKUP section + */ + +/* + * Debug output for layers + */ + +void hyp_debug_layer(parse_param * h) +{ + if (hyp_debug) { + if (h->thickness_set) + rnd_message(RND_MSG_DEBUG, " thickness = %ml", z2coord(h->thickness)); + if (h->plating_thickness_set) + rnd_message(RND_MSG_DEBUG, " plating_thickness = %ml", z2coord(h->plating_thickness)); + if (h->bulk_resistivity_set) + rnd_message(RND_MSG_DEBUG, " bulk_resistivity = %f", h->bulk_resistivity); + if (h->temperature_coefficient_set) + rnd_message(RND_MSG_DEBUG, " temperature_coefficient = %f", h->temperature_coefficient); + if (h->epsilon_r_set) + rnd_message(RND_MSG_DEBUG, " epsilon_r = %f", h->epsilon_r); + if (h->loss_tangent_set) + rnd_message(RND_MSG_DEBUG, " loss_tangent = %f", h->loss_tangent); + if (h->conformal_set) + rnd_message(RND_MSG_DEBUG, " conformal = %i", h->conformal); + if (h->prepreg_set) + rnd_message(RND_MSG_DEBUG, " prepreg = %i", h->prepreg); + if (h->layer_name_set) + rnd_message(RND_MSG_DEBUG, " layer_name = \"%s\"", h->layer_name); + if (h->material_name_set) + rnd_message(RND_MSG_DEBUG, " material_name = \"%s\"", h->material_name); + if (h->plane_separation_set) + rnd_message(RND_MSG_DEBUG, " plane_separation = %ml", xy2coord(h->plane_separation)); + rnd_message(RND_MSG_DEBUG, "\n"); + } + + return; +} + +/* + * 'OPTIONS' subrecord of 'STACKUP' record. + * Defines dielectric constant and loss tangent of metal layers. + */ + +rnd_bool exec_options(parse_param * h) +{ + /* Use dielectric for metal? */ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "options: use_die_for_metal = %f\n", h->use_die_for_metal); + if (h->use_die_for_metal) + use_die_for_metal = rnd_true; + return 0; +} + +/* + * SIGNAL subrecord of STACKUP record. + * signal layer. + */ + +rnd_bool exec_signal(parse_param * h) +{ + rnd_layer_id_t signal_layer_id; + + if ((h->layer_name != NULL) && (pcb_layer_by_name(PCB->Data, h->layer_name) >= 0)) + rnd_message(RND_MSG_WARNING, "duplicate SIGNAL layer name \"%s\"\n", h->layer_name); + + signal_layer_id = hyp_create_layer(h->layer_name); + + layer_is_plane[signal_layer_id] = rnd_false; + if (h->plane_separation_set) + layer_clearance[signal_layer_id] = xy2coord(h->plane_separation); + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "signal layer: \"%s\"", pcb_layer_name(PCB->Data, signal_layer_id)); + hyp_debug_layer(h); + + return 0; +} + +/* + * DIELECTRIC subrecord of STACKUP record. + * dielectric layer + */ + +rnd_bool exec_dielectric(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "dielectric layer: "); + hyp_debug_layer(h); + + return 0; +} + +/* + * PLANE subrecord of STACKUP record. + * plane layer - a layer which is flooded with copper. + */ + +rnd_bool exec_plane(parse_param * h) +{ + rnd_layer_id_t plane_layer_id; + + if ((h->layer_name != NULL) && (pcb_layer_by_name(PCB->Data, h->layer_name) >= 0)) + rnd_message(RND_MSG_WARNING, "duplicate PLANE layer name \"%s\"\n", h->layer_name); + + plane_layer_id = hyp_create_layer(h->layer_name); + + layer_is_plane[plane_layer_id] = rnd_true; + if (h->plane_separation_set) + layer_clearance[plane_layer_id] = xy2coord(h->plane_separation); + + /* XXX need to flood layer with copper */ + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "plane layer: \"%s\"", pcb_layer_name(PCB->Data, plane_layer_id)); + hyp_debug_layer(h); + + return 0; +} + +/* DEVICE record. */ +rnd_bool exec_devices(parse_param * h) +{ + device_t *new_device; + char value[128]; + + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "device: device_type = \"%s\" ref = \"%s\"", h->device_type, h->ref); + if (h->name_set) + rnd_message(RND_MSG_DEBUG, " name = \"%s\"", h->name); + if (h->value_float_set) + rnd_message(RND_MSG_DEBUG, " value_float = %f", h->value_float); + if (h->value_string_set) + rnd_message(RND_MSG_DEBUG, " value_string = \"%s\"", h->value_string); + if (h->layer_name_set) + rnd_message(RND_MSG_DEBUG, " layer_name = \"%s\"", h->layer_name); + if (h->package_set) + rnd_message(RND_MSG_DEBUG, " package = \"%s\"", h->package); + rnd_message(RND_MSG_DEBUG, "\n"); + } + + /* add device to list */ + new_device = calloc(sizeof(device_t), 1); + + new_device->ref = rnd_strdup(h->ref); + + new_device->name = NULL; + if (h->name_set) + new_device->name = rnd_strdup(h->name); + + + new_device->value = NULL; + if (h->value_string_set) + new_device->value = rnd_strdup(h->value_string); + else if (h->value_float_set) { + /* convert double to string */ + rnd_snprintf(value, sizeof(value), "%f", h->value_float); + new_device->value = rnd_strdup(value); + } + + new_device->layer_name = NULL; + if (h->layer_name_set) + new_device->layer_name = rnd_strdup(h->layer_name); + + new_device->next = device_head; + device_head = new_device; + + return 0; +} + +/* + * SUPPLY record. + * marks nets as power supply. + */ + +rnd_bool exec_supplies(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "supplies: name = \"%s\" value_float = %f voltage_specified = %i conversion = %i\n", h->name, + h->value_float, h->voltage_specified, h->conversion); + + return 0; +} + +/* + * PADSTACK record + */ + +rnd_bool exec_pstk_element(parse_param * h) +{ + /* + * Layer names with special meaning, used in padstack definition: + * MDEF: defines copper pad on all metal layers + * ADEF: defines anti-pad (clearance) on all power planes. + */ + + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "padstack_element:"); + if (h->padstack_name_set) + rnd_message(RND_MSG_DEBUG, " padstack_name = \"%s\"", h->padstack_name); + if (h->drill_size_set) + rnd_message(RND_MSG_DEBUG, " drill_size = %ml", xy2coord(h->drill_size)); + rnd_message(RND_MSG_DEBUG, " layer_name = \"%s\"", h->layer_name); + rnd_message(RND_MSG_DEBUG, " pad_shape = %f", h->pad_shape); + if (h->pad_shape == 0) + rnd_message(RND_MSG_DEBUG, " oval"); + else if (h->pad_shape == 1) + rnd_message(RND_MSG_DEBUG, " rectangular"); + else if (h->pad_shape == 2) + rnd_message(RND_MSG_DEBUG, " oblong"); + else + rnd_message(RND_MSG_DEBUG, " ?"); + rnd_message(RND_MSG_DEBUG, " pad_sx = %ml", xy2coord(h->pad_sx)); + rnd_message(RND_MSG_DEBUG, " pad_sy = %ml", xy2coord(h->pad_sy)); + rnd_message(RND_MSG_DEBUG, " pad_angle = %f", h->pad_angle); + if (h->pad_type_set & (h->pad_type == PAD_TYPE_THERMAL_RELIEF)) { + rnd_message(RND_MSG_DEBUG, " thermal_clear_shape = %f", h->thermal_clear_shape); + if (h->thermal_clear_shape == 0) + rnd_message(RND_MSG_DEBUG, " oval"); + else if (h->thermal_clear_shape == 1) + rnd_message(RND_MSG_DEBUG, " rectangular"); + else if (h->thermal_clear_shape == 2) + rnd_message(RND_MSG_DEBUG, " oblong"); + else + rnd_message(RND_MSG_DEBUG, " ?"); + rnd_message(RND_MSG_DEBUG, " thermal_clear_sx = %ml", xy2coord(h->thermal_clear_sx)); + rnd_message(RND_MSG_DEBUG, " thermal_clear_sy = %ml", xy2coord(h->thermal_clear_sy)); + rnd_message(RND_MSG_DEBUG, " thermal_clear_angle = %f", h->thermal_clear_angle); + } + if (h->pad_type_set) { + rnd_message(RND_MSG_DEBUG, " pad_type = "); + switch (h->pad_type) { + case PAD_TYPE_METAL: + rnd_message(RND_MSG_DEBUG, "metal"); + break; + case PAD_TYPE_ANTIPAD: + rnd_message(RND_MSG_DEBUG, "antipad"); + break; + case PAD_TYPE_THERMAL_RELIEF: + rnd_message(RND_MSG_DEBUG, "thermal_relief"); + break; + default: + rnd_message(RND_MSG_DEBUG, "error"); + } + } + rnd_message(RND_MSG_DEBUG, "\n"); + } + + if (h->padstack_name_set) { + /* add new padstack */ + current_pstk = malloc(sizeof(padstack_t)); + if (current_pstk == NULL) + return 1; /*malloc failed */ + current_pstk->name = rnd_strdup(h->padstack_name); + current_pstk->drill_size = xy2coord(h->drill_size); + current_pstk_element = malloc(sizeof(padstack_element_t)); + current_pstk->padstack = current_pstk_element; + } + else { + /* add new padstack element */ + current_pstk_element->next = malloc(sizeof(padstack_element_t)); + current_pstk_element = current_pstk_element->next; + if (current_pstk_element == NULL) + return 1; /*malloc failed */ + } + + /* fill in values */ + + current_pstk_element->layer_name = rnd_strdup(h->layer_name); + current_pstk_element->pad_shape = h->pad_shape; + current_pstk_element->pad_sx = xy2coord(h->pad_sx); + current_pstk_element->pad_sy = xy2coord(h->pad_sy); + current_pstk_element->pad_angle = h->pad_angle; + current_pstk_element->thermal_clear_sx = xy2coord(h->thermal_clear_sx); + current_pstk_element->thermal_clear_sy = xy2coord(h->thermal_clear_sy); + current_pstk_element->thermal_clear_angle = h->thermal_clear_angle; + if (h->pad_type_set) + current_pstk_element->pad_type = h->pad_type; + else + current_pstk_element->pad_type = PAD_TYPE_METAL; + current_pstk_element->next = NULL; + + return 0; +} + + +rnd_bool exec_pstk_end(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "padstack_end\n"); + + /* add current padstack to list of padstacks */ + if (current_pstk != NULL) { + current_pstk->next = padstack_head; + padstack_head = current_pstk; + current_pstk = NULL; + } + + current_pstk_element = NULL; + + return 0; +} + +static int hyp_pstk_add_shp(pcb_pstk_shape_t *sh, int *used, int max, padstack_element_t *i, pcb_layer_type_t lyt, pcb_layer_combining_t comb, rnd_coord_t offs) +{ + if (*used >= max) + return -1; + sh[*used].layer_mask = lyt; + sh[*used].comb = comb; + switch(i->pad_shape) { + case 0: /* round */ + case 2: /* oblong, rounded rectangle - emulate by line */ + pcb_shape_oval(&sh[*used], i->pad_sx+offs, i->pad_sy+offs); + break; + case 1: /* rectangle */ + pcb_shape_rect(&sh[*used], i->pad_sx+offs, i->pad_sy+offs); + break; + default: + return -1; + } + (*used)++; + return 0; +} + +static pcb_pstk_t *hyp_new_pstk(padstack_t *padstk, pcb_data_t *data, rnd_coord_t x, rnd_coord_t y, rnd_bool with_paste, rnd_bool with_mask) +{ + pcb_pstk_t *ps; + padstack_element_t *i; + pcb_pstk_shape_t sh[8]; + int sh_max = sizeof(sh) / sizeof(sh[0]) - 1; /* leave one entry for terminating */ + int sh_used = 0, have_top = 0, have_bottom = 0, have_inner = 0; + const char *ln_top, *ln_bot; + + memset(sh, 0, sizeof(sh)); + + ln_top = pcb_layer_name(PCB->Data, top_layer_id); + ln_bot = pcb_layer_name(PCB->Data, bottom_layer_id); + + /* loop over all layers of the padstack and create shapes in sh[] */ + for (i = padstk->padstack; i != NULL; i = i->next) { + int mdef, top_or_bottom; + if (i->layer_name == NULL) + continue; + if (i->pad_type != PAD_TYPE_METAL) + continue; + + if (i->pad_angle != 0) + rnd_message(RND_MSG_ERROR, "ignoring pad rotation of padstack at %$mm;%$mm.\n", x, y); + + mdef = strcmp(i->layer_name, "MDEF") == 0; + top_or_bottom = 0; +TODO(": check if mask/paste layers can be acquired explicitly as non-metal layers") + if (mdef || (strcmp(i->layer_name, ln_top) == 0)) { + if (!have_top) { + hyp_pstk_add_shp(sh, &sh_used, sh_max, i, PCB_LYT_TOP | PCB_LYT_COPPER, 0, 0); + if (with_mask) hyp_pstk_add_shp(sh, &sh_used, sh_max, i, PCB_LYT_TOP | PCB_LYT_MASK, PCB_LYC_SUB | PCB_LYC_AUTO, MASK_OFFS); + if (with_paste) hyp_pstk_add_shp(sh, &sh_used, sh_max, i, PCB_LYT_TOP | PCB_LYT_PASTE, PCB_LYC_AUTO, PASTE_OFFS); + } + top_or_bottom = 1; + have_top = 1; + } + if (mdef || (strcmp(i->layer_name, ln_bot) == 0)) { + if (!have_bottom) { + hyp_pstk_add_shp(sh, &sh_used, sh_max, i, PCB_LYT_BOTTOM | PCB_LYT_COPPER, 0, 0); + if (with_mask) hyp_pstk_add_shp(sh, &sh_used, sh_max, i, PCB_LYT_BOTTOM | PCB_LYT_MASK, PCB_LYC_SUB | PCB_LYC_AUTO, MASK_OFFS); + if (with_paste) hyp_pstk_add_shp(sh, &sh_used, sh_max, i, PCB_LYT_BOTTOM | PCB_LYT_PASTE, PCB_LYC_AUTO, PASTE_OFFS); + } + top_or_bottom = 1; + have_bottom = 0; + } + if (!have_inner && (mdef || !top_or_bottom)) { + hyp_pstk_add_shp(sh, &sh_used, sh_max, i, PCB_LYT_INTERN | PCB_LYT_COPPER, 0, 0); + have_inner = 1; + } + } + + ps = pcb_pstk_new_from_shape(data, x, y, padstk->drill_size, 1, 0, sh); + if (ps == NULL) + rnd_message(RND_MSG_ERROR, "Failed to convert padstack at %$mm;%$mm.\n", x, y); + return ps; +} + +/* draw padstack. Used when drawing vias, pins and pads. + * ref is an optional string which gives pin reference as device.pin, eg. U1.VCC */ +void hyp_draw_pstk(padstack_t *padstk, rnd_coord_t x, rnd_coord_t y, char *ref) +{ +/* + * We try to map a hyperlynx padstack to its closest pcb-rnd primitive. + * Choose between pcb_via_new(), pcb_element_pin_new(), pcb_element_pad_new() to draw a padstack. + * if there is a drill hole but no pin reference, it's a via. Use pcb_via_new(). + * if there is a drill hole and a pin reference, it's a pin. Use pcb_element_pin_new(). + * if there is no drill hole, it's a pad. Use pcb_element_pad_new(). + */ + pcb_subc_t *subc = NULL; + char *name = NULL; + char *number = NULL; + char *device_name = NULL; + char *pin_name = NULL; + pcb_pstk_t *pstk; + pcb_data_t *data; + + if (padstk == NULL) { + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "draw padstack: padstack not found.\n"); + return; + } + + + /* device and pin name, if any */ + device_name = NULL; + pin_name = NULL; + data = hyp_dest; + + if (ref != NULL) { + char *dot; + /* reference has format 'device_name.pin_name' */ + device_name = rnd_strdup(ref); + dot = strrchr(device_name, '.'); + if (dot != NULL) { + *dot = '\0'; + pin_name = rnd_strdup(dot + 1); + } + + /* make sure device and pin name have valid values, even if reference has wrong format */ + if ((device_name == NULL) || (strcmp(device_name, "") == 0)) { + device_name = malloc(MAX_STRING); + rnd_sprintf(device_name, "NONAME%0d", unknown_device_number++); + } + + if ((pin_name == NULL) || (strcmp(pin_name, "") == 0)) { + pin_name = malloc(MAX_STRING); + rnd_sprintf(pin_name, "NONUMBER%0d", unknown_pin_number++); + } + + /* find device by name */ + subc = hyp_create_subc_by_name(device_name, x, y); + data = subc->data; + } + + /* name and number NULL if no reference given */ + name = device_name; + number = pin_name; + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "draw padstack: device_name = \"%s\" pin_name = \"%s\"\n", name, number); + + pstk = hyp_new_pstk(padstk, data, x, y, (subc != NULL), (subc != NULL)); + if (pin_name != NULL) + pcb_attribute_put(&pstk->Attributes, "term", pin_name); + + if (subc != NULL) /* add pin to current net */ + hyp_netlist_add(name, number); + + return; +} + + +/* + * NET record. + */ + +rnd_bool exec_net(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "net: net_name = \"%s\"\n", h->net_name); + + net_name = rnd_strdup(h->net_name); + net_clearance = -1; + + return 0; +} + +/* + * PS subrecord of NET record. Plane separation. + */ + +rnd_bool exec_net_plane_separation(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "net_plane_separation: plane_separation = %ml\n", xy2coord(h->plane_separation)); + + net_clearance = xy2coord(h->plane_separation); + + return 0; +} + +/* + * A subrecord of NET record. Attribute. + */ + +rnd_bool exec_net_attribute(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "net_attribute: name = \"%s\" value = \"%s\"\n", h->name, h->value); + + return 0; +} + +/* + * SEG subrecord of NET record. line segment. + */ + +rnd_bool exec_seg(parse_param * h) +{ + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "seg: x1 = %ml y1 = %ml x2 = %ml y2 = %ml ", x2coord(h->x1), y2coord(h->y1), x2coord(h->x2), + y2coord(h->y2)); + rnd_message(RND_MSG_DEBUG, " width = %ml layer_name = \"%s\"", xy2coord(h->width), h->layer_name); + if (h->plane_separation_set) + rnd_message(RND_MSG_DEBUG, " plane_separation = %ml ", xy2coord(h->plane_separation)); + if (h->left_plane_separation_set) + rnd_message(RND_MSG_DEBUG, " left_plane_separation = %ml ", xy2coord(h->left_plane_separation)); + rnd_message(RND_MSG_DEBUG, "\n"); + } + + pcb_line_new(hyp_get_layer(h), x2coord(h->x1), y2coord(h->y1), x2coord(h->x2), y2coord(h->y2), xy2coord(h->width), + hyp_clearance(h), pcb_no_flags()); + + return 0; +} + +/* + * ARC subrecord of NET record. arc segment, drawn clockwise. + */ + +rnd_bool exec_arc(parse_param * h) +{ + + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "arc: x1 = %ml y1 = %ml x2 = %ml y2 = %ml", x2coord(h->x1), y2coord(h->y1), x2coord(h->x2), + y2coord(h->y2)); + rnd_message(RND_MSG_DEBUG, " xc = %ml yc = %ml r = %ml", x2coord(h->xc), y2coord(h->yc), xy2coord(h->r)); + rnd_message(RND_MSG_DEBUG, " width = %ml layer_name = \"%s\"", xy2coord(h->width), h->layer_name); + if (h->plane_separation_set) + rnd_message(RND_MSG_DEBUG, " plane_separation = %ml", xy2coord(h->plane_separation)); + if (h->left_plane_separation_set) + rnd_message(RND_MSG_DEBUG, " left_plane_separation = %ml", xy2coord(h->left_plane_separation)); + rnd_message(RND_MSG_DEBUG, "\n"); + } + + hyp_arc_new(hyp_get_layer(h), x2coord(h->x1), y2coord(h->y1), x2coord(h->x2), y2coord(h->y2), x2coord(h->xc), + y2coord(h->yc), xy2coord(h->r), xy2coord(h->r), rnd_true, xy2coord(h->width), hyp_clearance(h), pcb_no_flags()); + + return 0; +} + +/* + * Convert string-type pad shapes to numeric ones. + */ + +int str2pad_shape(char *pad_shape) +{ + if (pad_shape == NULL) + return 0; + else if (strcmp(pad_shape, "OVAL") == 0) + return 0; + else if (strcmp(pad_shape, "RECT") == 0) + return 1; + else if (strcmp(pad_shape, "OBLONG") == 0) + return 2; + else + return 0; +} + +/* + * VIA subrecord of NET record. + * Draws via using padstack definition. + */ + +rnd_bool exec_via(parse_param * h) +{ + /* detect old-style v1.0 via */ + if (!h->padstack_name_set) + return exec_via_v1(h); + + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "via: x = %ml y = %ml", x2coord(h->x), y2coord(h->y)); + if (h->padstack_name_set) + rnd_message(RND_MSG_DEBUG, " padstack_name = \"%s\"", h->padstack_name); + rnd_message(RND_MSG_DEBUG, "\n"); + } + + if (!h->padstack_name_set) { + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "pin: padstack not set. skipping pin \"%s\"\n", h->pin_reference); + return 0; + } + + hyp_draw_pstk(hyp_pstk_by_name(h->padstack_name), x2coord(h->x), y2coord(h->y), NULL); + + return 0; +} + +/* + * VIA subrecord of NET record. + * Draws deprecated v1.x via. + */ + +rnd_bool exec_via_v1(parse_param * h) +{ + padstack_t *padstk; + padstack_element_t *pad1; + padstack_element_t *pad2; + + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "old_via: x = %ml y = %ml", x2coord(h->x), y2coord(h->y)); + if (h->drill_size_set) + rnd_message(RND_MSG_DEBUG, " drill_size = %ml", xy2coord(h->drill_size)); + if (h->layer1_name_set) + rnd_message(RND_MSG_DEBUG, " layer1_name = \"%s\"", h->layer1_name); + if (h->layer2_name_set) + rnd_message(RND_MSG_DEBUG, " layer2_name = \"%s\"", h->layer2_name); + if (h->via_pad_shape_set) + rnd_message(RND_MSG_DEBUG, " via_pad_shape = \"%s\"", h->via_pad_shape); + if (h->via_pad_sx_set) + rnd_message(RND_MSG_DEBUG, " via_pad_sx = \"%ml\"", xy2coord(h->via_pad_sx)); + if (h->via_pad_sy_set) + rnd_message(RND_MSG_DEBUG, " via_pad_sy = \"%ml\"", xy2coord(h->via_pad_sy)); + if (h->via_pad_angle_set) + rnd_message(RND_MSG_DEBUG, " via_pad_angle = \"%f\"", h->via_pad_angle); + if (h->via_pad1_shape_set) + rnd_message(RND_MSG_DEBUG, " via_pad1_shape = \"%s\"", h->via_pad1_shape); + if (h->via_pad1_sx_set) + rnd_message(RND_MSG_DEBUG, " via_pad1_sx = \"%ml\"", xy2coord(h->via_pad1_sx)); + if (h->via_pad1_sy_set) + rnd_message(RND_MSG_DEBUG, " via_pad1_sy = \"%ml\"", xy2coord(h->via_pad1_sy)); + if (h->via_pad1_angle_set) + rnd_message(RND_MSG_DEBUG, " via_pad1_angle = \"%f\"", h->via_pad1_angle); + if (h->via_pad2_shape_set) + rnd_message(RND_MSG_DEBUG, " via_pad2_shape = \"%s\"", h->via_pad2_shape); + if (h->via_pad2_sx_set) + rnd_message(RND_MSG_DEBUG, " via_pad2_sx = \"%ml\"", xy2coord(h->via_pad2_sx)); + if (h->via_pad2_sy_set) + rnd_message(RND_MSG_DEBUG, " via_pad2_sy = \"%ml\"", xy2coord(h->via_pad2_sy)); + if (h->via_pad2_angle_set) + rnd_message(RND_MSG_DEBUG, " via_pad2_angle = \"%f\"", h->via_pad2_angle); + rnd_message(RND_MSG_DEBUG, "\n"); + } + + /* create padstack for this via */ + padstk = malloc(sizeof(padstack_t)); + if (padstk == NULL) + return 1; + pad1 = malloc(sizeof(padstack_element_t)); + if (pad1 == NULL) + return 1; + pad2 = malloc(sizeof(padstack_element_t)); + if (pad2 == NULL) + return 1; + + padstk->name = "*** VIA ***"; + padstk->drill_size = xy2coord(h->drill_size); + padstk->padstack = pad1; + padstk->next = NULL; + + pad1->layer_name = h->layer1_name; + pad1->pad_shape = str2pad_shape(h->via_pad1_shape); + pad1->pad_sx = xy2coord(h->via_pad1_sx); + pad1->pad_sy = xy2coord(h->via_pad1_sy); + pad1->pad_angle = h->via_pad1_angle; + pad1->thermal_clear_sx = 0; + pad1->thermal_clear_sy = 0; + pad1->thermal_clear_angle = 0.0; + pad1->pad_type = PAD_TYPE_METAL; + + if (h->layer2_name_set && h->via_pad2_sx_set && h->via_pad2_sy_set) { + pad1->next = pad2; + pad2->layer_name = h->layer2_name; + pad2->pad_shape = str2pad_shape(h->via_pad2_shape); + pad2->pad_sx = xy2coord(h->via_pad2_sx); + pad2->pad_sy = xy2coord(h->via_pad2_sy); + pad2->pad_angle = h->via_pad2_angle; + pad2->thermal_clear_sx = 0; + pad2->thermal_clear_sy = 0; + pad2->thermal_clear_angle = 0.0; + pad2->pad_type = PAD_TYPE_METAL; + pad2->next = NULL; + } + else + pad1->next = NULL; + + /* draw padstack */ + hyp_draw_pstk(padstk, x2coord(h->x), y2coord(h->y), NULL); + + /* free padstack for this via */ + free(pad2); + free(pad1); + free(padstk); + + return 0; +} + +/* + * PIN subrecord of NET record. + * Draws PIN using padstack definiton. + */ + +rnd_bool exec_pin(parse_param * h) +{ + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "pin: x = %ml y = %ml", x2coord(h->x), y2coord(h->y)); + rnd_message(RND_MSG_DEBUG, " pin_reference = \"%s\"", h->pin_reference); + if (h->padstack_name_set) + rnd_message(RND_MSG_DEBUG, " padstack_name = \"%s\"", h->padstack_name); + if (h->pin_function_set) + rnd_message(RND_MSG_DEBUG, " pin_function = %i", h->pin_function); + rnd_message(RND_MSG_DEBUG, "\n"); + } + + if (!h->padstack_name_set) { + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "pin: padstack not set. skipping pin \"%s\"\n", h->pin_reference); + return 0; + } + + hyp_draw_pstk(hyp_pstk_by_name(h->padstack_name), x2coord(h->x), y2coord(h->y), h->pin_reference); + + return 0; +} + +/* + * PAD subrecord of NET record. + * Draws deprecated v1.x pad. + */ + +rnd_bool exec_pad(parse_param * h) +{ + padstack_t *padstk; + padstack_element_t *pad; + + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "pad: x = %ml y = %ml", x2coord(h->x), y2coord(h->y)); + if (h->layer_name_set) + rnd_message(RND_MSG_DEBUG, " layer_name = \"%s\"", h->layer_name); + if (h->via_pad_shape_set) + rnd_message(RND_MSG_DEBUG, " via_pad_shape = \"%s\"", h->via_pad_shape); + if (h->via_pad_sx_set) + rnd_message(RND_MSG_DEBUG, " via_pad_sx = \"%ml\"", xy2coord(h->via_pad_sx)); + if (h->via_pad_sy_set) + rnd_message(RND_MSG_DEBUG, " via_pad_sy = \"%ml\"", xy2coord(h->via_pad_sy)); + if (h->via_pad_angle_set) + rnd_message(RND_MSG_DEBUG, " via_pad_angle = \"%f\"", h->via_pad_angle); + rnd_message(RND_MSG_DEBUG, "\n"); + } + + if (!h->layer_name_set) { + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "pad: layer name not set. skipping pad\n."); + return 0; + } + + /* create padstack for this pad */ + padstk = malloc(sizeof(padstack_t)); + if (padstk == NULL) + return 1; + pad = malloc(sizeof(padstack_element_t)); + if (pad == NULL) + return 1; + + padstk->name = "*** PAD ***"; + padstk->drill_size = 0.0; + padstk->padstack = pad; + padstk->next = NULL; + + pad->layer_name = h->layer_name; + pad->pad_shape = str2pad_shape(h->via_pad_shape); + pad->pad_sx = xy2coord(h->via_pad_sx); + pad->pad_sy = xy2coord(h->via_pad_sy); + pad->pad_angle = h->via_pad_angle; + pad->thermal_clear_sx = 0; + pad->thermal_clear_sy = 0; + pad->thermal_clear_angle = 0; + pad->pad_type = PAD_TYPE_METAL; + pad->next = NULL; + + /* draw padstack */ + hyp_draw_pstk(padstk, x2coord(h->x), y2coord(h->y), NULL); + + /* free padstack for this pad */ + free(pad); + free(padstk); + + return 0; +} + +/* + * USEG subrecord of NET record. + * unrouted segment. + */ + +rnd_bool exec_useg(parse_param * h) +{ + rnd_layergrp_id_t layer1_grp_id, layer2_grp_id; + + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "useg: x1 = %ml y1 = %ml layer1_name = \"%s\"", x2coord(h->x1), y2coord(h->y1), h->layer1_name); + rnd_message(RND_MSG_DEBUG, " x2 = %ml y2 = %ml layer2_name = \"%s\"", x2coord(h->x2), y2coord(h->y2), h->layer2_name); + if (h->zlayer_name_set) + rnd_message(RND_MSG_DEBUG, " zlayer_name = \"%s\" width = %ml length = %ml", h->zlayer_name, xy2coord(h->width), + xy2coord(h->length)); + if (h->impedance_set) + rnd_message(RND_MSG_DEBUG, " impedance = %f delay = %f ", h->impedance, h->delay); + if (h->resistance_set) + rnd_message(RND_MSG_DEBUG, " resistance = %f ", h->resistance); + rnd_message(RND_MSG_DEBUG, "\n"); + } + + /* lookup layer group begin and end layer are on */ + layer1_grp_id = pcb_layer_get_group(PCB, hyp_create_layer(h->layer1_name)); + layer2_grp_id = pcb_layer_get_group(PCB, hyp_create_layer(h->layer2_name)); + + if ((layer1_grp_id == -1) || (layer2_grp_id == -1)) { + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "useg: skipping unrouted segment\n"); + return 0; + } + + pcb_rat_new(hyp_dest, -1, x2coord(h->x1), y2coord(h->y1), x2coord(h->x2), y2coord(h->y2), layer1_grp_id, layer2_grp_id, + xy2coord(h->width), pcb_no_flags(), NULL, NULL); + + return 0; +} + +/* + * POLYGON subrecord of NET record. + * draws copper polygon. + */ + +rnd_bool exec_polygon_begin(parse_param * h) +{ + hyp_polygon_t *new_poly; + hyp_vertex_t *new_vertex; + hyp_polygon_t *i; + + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "polygon begin:"); + if (h->layer_name_set) + rnd_message(RND_MSG_DEBUG, " layer_name = \"%s\"", h->layer_name); + if (h->width_set) + rnd_message(RND_MSG_DEBUG, " width = %ml", xy2coord(h->width)); + if (h->polygon_type_set) { + rnd_message(RND_MSG_DEBUG, " polygon_type = ", h->polygon_type, " "); + switch (h->polygon_type) { + case POLYGON_TYPE_PLANE: + rnd_message(RND_MSG_DEBUG, "POLYGON_TYPE_PLANE"); + break; + case POLYGON_TYPE_POUR: + rnd_message(RND_MSG_DEBUG, "POLYGON_TYPE_POUR"); + break; + case POLYGON_TYPE_COPPER: + rnd_message(RND_MSG_DEBUG, "POLYGON_TYPE_COPPER"); + break; + default: + rnd_message(RND_MSG_DEBUG, "Error"); + break; + } + } + if (h->id_set) + rnd_message(RND_MSG_DEBUG, " id = %i", h->id); + rnd_message(RND_MSG_DEBUG, " x = %ml y = %ml\n", x2coord(h->x), y2coord(h->y)); + } + + if (!h->layer_name_set) { + hyp_error("expected polygon layer L = "); + return rnd_true; + } + + if (!h->id_set) { + hyp_error("expected polygon id ID = "); + return rnd_true; + } + + /* make sure layer exists */ + hyp_create_layer(h->layer_name); + + /* check for other polygons with this id */ + if (hyp_debug) + for (i = polygon_head; i != NULL; i = i->next) + if (h->id == i->hyp_poly_id) { + rnd_message(RND_MSG_INFO, "info: duplicate polygon id %i.\n", h->id); + break; + } + + /* create first vertex */ + new_vertex = malloc(sizeof(hyp_vertex_t)); + new_vertex->x1 = x2coord(h->x); + new_vertex->y1 = y2coord(h->y); + new_vertex->x2 = 0; + new_vertex->y2 = 0; + new_vertex->xc = 0; + new_vertex->yc = 0; + new_vertex->r = 0; + new_vertex->is_arc = rnd_false; + new_vertex->is_first = rnd_true; + new_vertex->next = NULL; + + /* create new polygon */ + new_poly = malloc(sizeof(hyp_polygon_t)); + new_poly->hyp_poly_id = h->id; /* hyperlynx polygon/polyline id */ + new_poly->hyp_poly_type = h->polygon_type; + new_poly->is_polygon = rnd_true; + new_poly->layer_name = h->layer_name; + new_poly->line_width = xy2coord(h->width); + new_poly->clearance = hyp_clearance(h); + new_poly->vertex = new_vertex; + + new_poly->next = polygon_head; + polygon_head = new_poly; + + /* bookkeeping */ + current_vertex = new_vertex; + + return 0; +} + +rnd_bool exec_polygon_end(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "polygon end:\n"); + + /* bookkeeping */ + if ((current_vertex == NULL) && hyp_debug) + rnd_message(RND_MSG_WARNING, "polygon: unexpected polygon end. continuing.\n"); + current_vertex = NULL; + + return 0; +} + +/* + * POLYVOID subrecord of NET record. + * same as POLYGON, but instead of creating copper, creates a hole in copper. + */ + +rnd_bool exec_polyvoid_begin(parse_param * h) +{ + hyp_polygon_t *i; + hyp_vertex_t *new_vertex; + + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "polyvoid begin:"); + if (h->id_set) + rnd_message(RND_MSG_DEBUG, " id = %i", h->id); + rnd_message(RND_MSG_DEBUG, " x = %ml y = %ml\n", x2coord(h->x), y2coord(h->y)); + } + + if (!h->id_set) { + hyp_error("expected polygon id ID = "); + return rnd_true; + } + + /* look up polygon with this id */ + for (i = polygon_head; i != NULL; i = i->next) + if (h->id == i->hyp_poly_id) + break; + + if (i == NULL) { + current_vertex = NULL; + rnd_message(RND_MSG_WARNING, "polyvoid: polygon id %i not found\n", h->id); + return 0; + } + + /* find last vertex of polygon */ + for (current_vertex = i->vertex; current_vertex != NULL; current_vertex = current_vertex->next) + if (current_vertex->next == NULL) + break; + + assert(current_vertex != NULL); /* at least one vertex in polygon */ + + /* add new vertex at end of list of vertices */ + new_vertex = malloc(sizeof(hyp_vertex_t)); + new_vertex->x1 = x2coord(h->x); + new_vertex->y1 = y2coord(h->y); + new_vertex->x2 = 0; + new_vertex->y2 = 0; + new_vertex->xc = 0; + new_vertex->yc = 0; + new_vertex->r = 0; + new_vertex->is_arc = rnd_false; + new_vertex->is_first = rnd_true; + new_vertex->next = NULL; + + /* bookkeeping */ + if (current_vertex != NULL) { + current_vertex->next = new_vertex; + current_vertex = new_vertex; + } + + return 0; +} + +rnd_bool exec_polyvoid_end(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "polyvoid end:\n"); + + /* bookkeeping */ + if ((current_vertex == NULL) && hyp_debug) + rnd_message(RND_MSG_WARNING, "polyvoid: unexpected polyvoid end. continuing.\n"); + current_vertex = NULL; + + return 0; +} + +/* + * POLYLINE subrecord of NET record. + */ + +rnd_bool exec_polyline_begin(parse_param * h) +{ + hyp_polygon_t *new_poly; + hyp_vertex_t *new_vertex; + hyp_polygon_t *i; + + if (hyp_debug) { + rnd_message(RND_MSG_DEBUG, "polyline begin:"); + if (h->layer_name_set) + rnd_message(RND_MSG_DEBUG, " layer_name = \"%s\"", h->layer_name); + if (h->width_set) + rnd_message(RND_MSG_DEBUG, " width = %ml", xy2coord(h->width)); + if (h->polygon_type_set) { + rnd_message(RND_MSG_DEBUG, " polygon_type = ", h->polygon_type, " "); + switch (h->polygon_type) { + case POLYGON_TYPE_PLANE: + rnd_message(RND_MSG_DEBUG, "POLYGON_TYPE_PLANE"); + break; + case POLYGON_TYPE_POUR: + rnd_message(RND_MSG_DEBUG, "POLYGON_TYPE_POUR"); + break; + case POLYGON_TYPE_COPPER: + rnd_message(RND_MSG_DEBUG, "POLYGON_TYPE_COPPER"); + break; + default: + rnd_message(RND_MSG_DEBUG, "Error"); + break; + } + } + if (h->id_set) + rnd_message(RND_MSG_DEBUG, " id = %i", h->id); + rnd_message(RND_MSG_DEBUG, " x = %ml y = %ml\n", x2coord(h->x), y2coord(h->y)); + } + + if (!h->layer_name_set) { + hyp_error("expected polygon layer L = "); + return rnd_true; + } + + if (!h->width_set) { + hyp_error("expected polygon width W = "); + return rnd_true; + } + + if (!h->id_set) { + hyp_error("expected polygon id ID = "); + return rnd_true; + } + + /* make sure layer exists */ + hyp_create_layer(h->layer_name); + + /* check for other polygons with this id */ + if (hyp_debug) + for (i = polygon_head; i != NULL; i = i->next) + if (h->id == i->hyp_poly_id) { + rnd_message(RND_MSG_DEBUG, "info: duplicate polygon id %i.\n", h->id); + break; + } + + /* create first vertex */ + new_vertex = malloc(sizeof(hyp_vertex_t)); + new_vertex->x1 = x2coord(h->x); + new_vertex->y1 = y2coord(h->y); + new_vertex->x2 = 0; + new_vertex->y2 = 0; + new_vertex->xc = 0; + new_vertex->yc = 0; + new_vertex->r = 0; + new_vertex->is_arc = rnd_false; + new_vertex->is_first = rnd_true; + new_vertex->next = NULL; + + /* create new polyline */ + new_poly = malloc(sizeof(hyp_polygon_t)); + new_poly->hyp_poly_id = h->id; /* hyperlynx polygon/polyline id */ + new_poly->hyp_poly_type = h->polygon_type; + new_poly->is_polygon = rnd_false; + new_poly->layer_name = h->layer_name; + new_poly->line_width = xy2coord(h->width); + new_poly->clearance = hyp_clearance(h); + new_poly->vertex = new_vertex; + + new_poly->next = polygon_head; + polygon_head = new_poly; + + /* bookkeeping */ + current_vertex = new_vertex; + + return 0; +} + +rnd_bool exec_polyline_end(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "polyline end:\n"); + + /* bookkeeping */ + if ((current_vertex == NULL) && hyp_debug) + rnd_message(RND_MSG_WARNING, "polyline: unexpected polyline end. continuing.\n"); + current_vertex = NULL; + + return 0; +} + +/* + * LINE subrecord of NET record. + */ + +rnd_bool exec_line(parse_param * h) +{ + hyp_vertex_t *new_vertex; + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "line: x = %ml y = %ml\n", x2coord(h->x), y2coord(h->y)); + + if (current_vertex == NULL) { + rnd_message(RND_MSG_DEBUG, "line: skipping."); + return 0; + } + + /* add new vertex at end of list of vertices */ + new_vertex = malloc(sizeof(hyp_vertex_t)); + new_vertex->x1 = x2coord(h->x); + new_vertex->y1 = y2coord(h->y); + new_vertex->x2 = 0; + new_vertex->y2 = 0; + new_vertex->xc = 0; + new_vertex->yc = 0; + new_vertex->r = 0; + new_vertex->is_arc = rnd_false; + new_vertex->is_first = rnd_false; + new_vertex->next = NULL; + + /* bookkeeping */ + current_vertex->next = new_vertex; + current_vertex = new_vertex; + + return 0; +} + +/* + * CURVE subrecord of NET record. + * Clockwise from (x1, y1) to (x2, y2). + */ + +rnd_bool exec_curve(parse_param * h) +{ + hyp_vertex_t *new_vertex; + + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "curve: x1 = %ml y1 = %ml x2 = %ml y2 = %ml xc = %ml yc = %ml r = %ml\n", x2coord(h->x1), + y2coord(h->y1), x2coord(h->x2), y2coord(h->y2), x2coord(h->xc), y2coord(h->yc), xy2coord(h->r)); + + if (current_vertex == NULL) { + rnd_message(RND_MSG_DEBUG, "curve: skipping."); + return 0; + } + + /* add new vertex at end of list of vertices */ + new_vertex = malloc(sizeof(hyp_vertex_t)); + new_vertex->x1 = x2coord(h->x1); + new_vertex->y1 = y2coord(h->y1); + new_vertex->x2 = x2coord(h->x2); + new_vertex->y2 = y2coord(h->y2); + new_vertex->xc = x2coord(h->xc); + new_vertex->yc = y2coord(h->yc); + new_vertex->r = xy2coord(h->r); + new_vertex->is_arc = rnd_true; + new_vertex->is_first = rnd_false; + new_vertex->next = NULL; + + /* bookkeeping */ + current_vertex->next = new_vertex; + current_vertex = new_vertex; + + return 0; +} + +/* + * NET_CLASS record + */ + +rnd_bool exec_net_class(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "net_class: net_class_name = \"%s\"\n", h->net_class_name); + + return 0; +} + +/* + * N net membership subrecord of NET_CLASS record + */ + +rnd_bool exec_net_class_element(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "net_class_element: net_name = \"%s\"\n", h->net_name); + + return 0; +} + +/* + * A attribute subrecord of NET_CLASS record + */ + + +rnd_bool exec_net_class_attribute(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "netclass_attribute: name = \"%s\" value = \"%s\"\n", h->name, h->value); + + return 0; +} + +/* + * KEY record + */ + +rnd_bool exec_key(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "key: key = \"%s\"\n", h->key); + + return 0; +} + +/* + * END record + */ + +rnd_bool exec_end(parse_param * h) +{ + if (hyp_debug) + rnd_message(RND_MSG_DEBUG, "end:\n"); + return 0; +} + +/* not truncated */ Index: tags/2.3.0/src_plugins/io_hyp/parser.h =================================================================== --- tags/2.3.0/src_plugins/io_hyp/parser.h (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/parser.h (revision 33253) @@ -0,0 +1,251 @@ +/* + * read hyperlynx files + * Copyright 2012 Koen De Vleeschauwer. + * + * This file is part of pcb-rnd. + * + * 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, see . + */ + +#ifndef PCB_IO_HYP_PARSER_H +#define PCB_IO_HYP_PARSER_H + +#include +#include +#include "board.h" + + /* + * Parameters passed on by the parser. + * All variables added here are initialized in new_record(). + */ + +typedef enum { PAD_TYPE_METAL, PAD_TYPE_ANTIPAD, PAD_TYPE_THERMAL_RELIEF } pad_type_enum; + +typedef enum { PIN_SIM_IN, PIN_SIM_OUT, PIN_SIM_BOTH } pin_function_enum; + +typedef enum { POLYGON_TYPE_POUR, POLYGON_TYPE_PLANE, POLYGON_TYPE_COPPER, POLYGON_TYPE_PAD, + POLYGON_TYPE_ANTIPAD +} polygon_type_enum; + +typedef struct { + double vers; /* version of the hyp file format */ + rnd_bool detailed; /* data detailed enough for power integrity */ + rnd_bool unit_system_english; /* english or metric units */ + rnd_bool metal_thickness_weight; /* copper by weight or by length */ + double default_plane_separation; /* trace to plane separation */ + + /* stackup record */ + rnd_bool use_die_for_metal; /* dielectric constant and loss tangent of dielectric for metal layers */ + double bulk_resistivity; + rnd_bool conformal; + double epsilon_r; + char *layer_name; + double loss_tangent; + char *material_name; + double plane_separation; + double plating_thickness; + rnd_bool prepreg; + double temperature_coefficient; /* temperature coefficient of resistivity */ + double thickness; /* layer thickness */ + + /* stackup record flags */ + rnd_bool bulk_resistivity_set; + rnd_bool conformal_set; + rnd_bool epsilon_r_set; + rnd_bool layer_name_set; + rnd_bool loss_tangent_set; + rnd_bool material_name_set; + rnd_bool plane_separation_set; + rnd_bool plating_thickness_set; + rnd_bool prepreg_set; + rnd_bool temperature_coefficient_set; + rnd_bool thickness_set; + + /* device record */ + char *device_type; + char *ref; + double value_float; + char *value_string; + char *package; + + /* device record flags */ + rnd_bool name_set; + rnd_bool value_float_set; + rnd_bool value_string_set; + rnd_bool package_set; + + /* supplies record */ + rnd_bool voltage_specified; + rnd_bool conversion; + + /* padstack record */ + char *padstack_name; + double drill_size; + double pad_shape; + double pad_sx; + double pad_sy; + double pad_angle; + double thermal_clear_shape; + double thermal_clear_sx; + double thermal_clear_sy; + double thermal_clear_angle; + pad_type_enum pad_type; + + /* padstack record flags */ + rnd_bool padstack_name_set; + rnd_bool drill_size_set; + rnd_bool pad_type_set; + + /* net record */ + double width; + double left_plane_separation; + rnd_bool width_set; + rnd_bool left_plane_separation_set; + + /* via subrecord of net */ + char *layer1_name; + rnd_bool layer1_name_set; + char *layer2_name; + rnd_bool layer2_name_set; + char *via_pad_shape; + rnd_bool via_pad_shape_set; + double via_pad_sx; + rnd_bool via_pad_sx_set; + double via_pad_sy; + rnd_bool via_pad_sy_set; + double via_pad_angle; + rnd_bool via_pad_angle_set; + char *via_pad1_shape; + rnd_bool via_pad1_shape_set; + double via_pad1_sx; + rnd_bool via_pad1_sx_set; + double via_pad1_sy; + rnd_bool via_pad1_sy_set; + double via_pad1_angle; + rnd_bool via_pad1_angle_set; + char *via_pad2_shape; + rnd_bool via_pad2_shape_set; + double via_pad2_sx; + rnd_bool via_pad2_sx_set; + double via_pad2_sy; + rnd_bool via_pad2_sy_set; + double via_pad2_angle; + rnd_bool via_pad2_angle_set; + + /* pin subrecord of net */ + char *pin_reference; + rnd_bool pin_reference_set; + pin_function_enum pin_function; + rnd_bool pin_function_set; + + /* useg subrecord of net */ + char *zlayer_name; + rnd_bool zlayer_name_set; + double length; + double impedance; + rnd_bool impedance_set; + double delay; + double resistance; + rnd_bool resistance_set; + + /* polygon subrecord of net */ + int id; + rnd_bool id_set; + polygon_type_enum polygon_type; + rnd_bool polygon_type_set; + + /* net class record */ + char *net_class_name; + char *net_name; + + /* key record */ + char *key; + + /* Attributes */ + char *name; /* attribute name */ + char *value; /* attribute value */ + + /* point, line and arc coordinates */ + double x; /* coordinates point */ + double y; /* coordinates point */ + double x1; /* coordinates point 1 */ + double y1; /* coordinates point 1 */ + double x2; /* coordinates point 2 */ + double y2; /* coordinates point 2 */ + double xc; /* coordinates arc */ + double yc; /* coordinates arc */ + double r; /* coordinates arc */ +} parse_param; + + /* exec_* routines are called by parser to interpret hyperlynx file */ +rnd_bool exec_board_file(parse_param * h); +rnd_bool exec_version(parse_param * h); +rnd_bool exec_data_mode(parse_param * h); +rnd_bool exec_units(parse_param * h); +rnd_bool exec_plane_sep(parse_param * h); +rnd_bool exec_perimeter_segment(parse_param * h); +rnd_bool exec_perimeter_arc(parse_param * h); +rnd_bool exec_board_attribute(parse_param * h); + +rnd_bool exec_options(parse_param * h); +rnd_bool exec_signal(parse_param * h); +rnd_bool exec_dielectric(parse_param * h); +rnd_bool exec_plane(parse_param * h); + +rnd_bool exec_devices(parse_param * h); + +rnd_bool exec_supplies(parse_param * h); + +rnd_bool exec_pstk_element(parse_param * h); +rnd_bool exec_pstk_end(parse_param * h); + +rnd_bool exec_net(parse_param * h); +rnd_bool exec_net_plane_separation(parse_param * h); +rnd_bool exec_net_attribute(parse_param * h); +rnd_bool exec_seg(parse_param * h); +rnd_bool exec_arc(parse_param * h); +rnd_bool exec_via(parse_param * h); +rnd_bool exec_via_v1(parse_param * h); /* Old style via format */ +rnd_bool exec_pin(parse_param * h); +rnd_bool exec_pad(parse_param * h); +rnd_bool exec_useg(parse_param * h); + +rnd_bool exec_polygon_begin(parse_param * h); +rnd_bool exec_polygon_end(parse_param * h); +rnd_bool exec_polyvoid_begin(parse_param * h); +rnd_bool exec_polyvoid_end(parse_param * h); +rnd_bool exec_polyline_begin(parse_param * h); +rnd_bool exec_polyline_end(parse_param * h); +rnd_bool exec_line(parse_param * h); +rnd_bool exec_curve(parse_param * h); + +rnd_bool exec_net_class(parse_param * h); +rnd_bool exec_net_class_element(parse_param * h); +rnd_bool exec_net_class_attribute(parse_param * h); + +rnd_bool exec_end(parse_param * h); +rnd_bool exec_key(parse_param * h); + + /* called by pcb-rnd to load hyperlynx file */ +rnd_bool hyp_parse(pcb_data_t * dest, const char *fname, int debug); +void hyp_error(const char *msg); + + /* create arc, hyperlynx-style */ +pcb_arc_t *hyp_arc_new(pcb_layer_t * Layer, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t XC, + rnd_coord_t YC, rnd_coord_t Width, rnd_coord_t Height, rnd_bool_t Clockwise, rnd_coord_t Thickness, + rnd_coord_t Clearance, pcb_flag_t Flags); + +#endif + + /* not truncated */ Index: tags/2.3.0/src_plugins/io_hyp/tests/test00/README.txt =================================================================== --- tags/2.3.0/src_plugins/io_hyp/tests/test00/README.txt (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/tests/test00/README.txt (revision 33253) @@ -0,0 +1,3 @@ +Source: handwritten +GPL: Yes +Remark: contains every imported feature Index: tags/2.3.0/src_plugins/io_hyp/tests/test00/gen_test00.py =================================================================== --- tags/2.3.0/src_plugins/io_hyp/tests/test00/gen_test00.py (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/tests/test00/gen_test00.py (revision 33253) @@ -0,0 +1,328 @@ +#!/usr/bin/python +""" + Generate sample hyperlynx file + Copyright 2017 Koen De Vleeschauwer. + + This file is part of pcb-rnd. + + 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, see . +""" + +from math import pi, sin, cos + +print "{VERSION=2.0}" +print "{UNITS=METRIC LENGTH}" +print "{BOARD" +print " (PERIMETER_SEGMENT X1=1.0 Y1=0.0 X2=19.0 Y2=0.0)" +print " (PERIMETER_SEGMENT X1=20.0 Y1=1.0 X2=20.0 Y2=9.0)" +print " (PERIMETER_SEGMENT X1=19.0 Y1=10.0 X2=1.0 Y2=10.0)" +print " (PERIMETER_SEGMENT X1=0.0 Y1=9.0 X2=0.0 Y2=1.0)" +print " (PERIMETER_ARC X1=0.0 Y1=1.0 X2=1.0 Y2=0.0 XC=1.0 YC=1.0 R=1.0)" +print " (PERIMETER_ARC X1=1.0 Y1=10.0 X2=0.0 Y2=9.0 XC=1.0 YC=9.0 R=1.0)" +print " (PERIMETER_ARC X1=20.0 Y1=9.0 X2=19.0 Y2=10.0 XC=19.0 YC=9.0 R=1.0)" +print " (PERIMETER_ARC X1=19.0 Y1=0.0 X2=20.0 Y2=1.0 XC=19.0 YC=1.0 R=1.0)" +print "" +print " (PERIMETER_SEGMENT X1=2.0 Y1=1.0 X2=3.0 Y2=1.0)" +print " (PERIMETER_SEGMENT X1=3.0 Y1=9.0 X2=2.0 Y2=9.0)" +print " (PERIMETER_ARC X1=2.0 Y1=9.0 X2=1.0 Y2=8.0 XC=2.0 YC=8.0 R=1.0)" +print " (PERIMETER_SEGMENT X1=1.0 Y1=8.0 X2=1.0 Y2=2.0)" +print " (PERIMETER_ARC X1=1.0 Y1=2.0 X2=2.0 Y2=1.0 XC=2.0 YC=2.0 R=1.0)" +print " (PERIMETER_SEGMENT X1=4.0 Y1=2.0 X2=4.0 Y2=8.0)" +print " (PERIMETER_ARC X1=3.0 Y1=1.0 X2=4.0 Y2=2.0 XC=3.0 YC=2.0 R=1.0)" +print " (PERIMETER_ARC X1=4.0 Y1=8.0 X2=3.0 Y2=9.0 XC=3.0 YC=8.0 R=1.0)" + +print " (PERIMETER_ARC X1=5.5 Y1=5.0 X2=5.5 Y2=5.0 XC=5.0 YC=5.0 R=0.5)" + +print " (PERIMETER_ARC X1=5.5 Y1=6.0 X2=4.5 Y2=6.0 XC=5.0 YC=6.0 R=0.5)" +print " (PERIMETER_SEGMENT X1=4.5 Y1=6.0 X2=5.5 Y2=6.0)" + +print " (PERIMETER_ARC X1=4.5 Y1=7.5 X2=5.5 Y2=7.5 XC=5.0 YC=7.5 R=0.5)" +print " (PERIMETER_SEGMENT X1=4.5 Y1=7.5 X2=5.5 Y2=7.5)" + +print " (PERIMETER_ARC X1=5.5 Y1=8.5 X2=5.0 Y2=8.0 XC=5.0 YC=8.5 R=0.5)" +print " (PERIMETER_SEGMENT X1=5.0 Y1=8.0 X2=5.5 Y2=8.5)" + +print "}" + +print "{PLANE_SEP=0.05}" + +print "{STACKUP" +print " (SIGNAL T=0.000700 L=component)" +print " (DIELECTRIC T=0.002000 C=4.000000)" +print " (PLANE T=0.000700 L=solder PS=0.508)" +print "}" +print "{DEVICES" +print " (? REF=U1 NAME=BC548 L=component)" +print "}" + +# +# PADSTACK. MDEF is shorthand for "all copper layers" +# + +print "{PADSTACK=roundpad, 0.2" +print " (MDEF, 0, 0.5, 0.5, 0)" +print "}" +print "{PADSTACK=squarepad, 0.2" +print " (MDEF, 1, 0.5, 0.5, 0)" +print "}" +print "{PADSTACK=oblongpad, 0.2" +print " (MDEF, 2, 0.75, 0.5, 0)" +print "}" +print "{PADSTACK=nodrill," +print " (MDEF, 0, 0.5, 0.5, 0)" +print "}" +print "{PADSTACK=0802pad," +print " (component, 1, 0.2, 0.12, 0)" +print "}" + +# +# SEG line segments +# + +x0 = 6 +y0 = 3 +r1 = 0.5 +r2 = 2 +max = 12 + +print "{NET=segtst" + +for x in range (0, max): + alpha = x * 2 * pi / max + x1 = x0 + r1 * cos (alpha) + y1 = y0 + r1 * sin (alpha) + r = r1 + (r2 - r1) * (x + 1) / max + x2 = x0 + r * cos (alpha) + y2 = y0 + r * sin (alpha) + w = (x + 1) * 0.1 / max + print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=%f L=component)" % ( x1, y1, x2, y2, w) + +print "}" + +# +# ARC arc segments +# + +max = 8 +x0 = 9 +y0 = 1 +r = 0.1 +w = r / 4 + +print "{NET=arctst" + +for a in range (0, max): + for b in range (0, max): + alpha = 2 * pi * a / max + beta = 2 * pi * b / max + xc = x0 + 4 * r * a + yc = y0 + 4 * r * b + x1 = xc + r * cos (alpha) + y1 = yc + r * sin (alpha) + x2 = xc + r * cos (beta) + y2 = yc + r * sin (beta) + print " (ARC X1=%f Y1=%f X2=%f Y2=%f XC=%f YC=%f R=%f W=%f L=component)" % ( x1, y1, x2, y2, xc, yc, r, w) + +print "}" + +# +# VIA +# + +print "{NET=viatst" +print " (VIA X=13 Y=1 P=roundpad)" +print " (VIA X=13 Y=2 P=squarepad)" +print " (VIA X=13 Y=3 P=oblongpad)" +print " (VIA X=13 Y=4 P=nodrill)" +print " (SEG X1=13 Y1=1 X2=13 Y2=2 W=0.1 L=component)" +print " (SEG X1=13 Y1=2 X2=13 Y2=3 W=0.1 L=component)" +print " (SEG X1=13 Y1=3 X2=13 Y2=4 W=0.1 L=component)" +print "}" + +# +# old-style VIA, compatibility only. +# + +print "{NET=oldviatst" +print " (VIA X=14 Y=1 D=0.2 L1=component S1=ROUND S1X=0.5 S1Y=0.5)" +print " (VIA X=14 Y=2 D=0.2 L1=component L2=solder S1=RECT S1X=0.5 S1Y=0.5)" +print " (VIA X=14 Y=3 D=0.2 L1=component L2=solder S1=OBLONG S1X=0.75 S1Y=0.5)" +print " (VIA X=14 Y=4 D=0.0 L1=component L2=solder S1=ROUND S1X=0.5 S1Y=0.5)" +print " (SEG X1=14 Y1=1 X2=14 Y2=2 W=0.1 L=component)" +print " (SEG X1=14 Y1=2 X2=14 Y2=3 W=0.1 L=component)" +print " (SEG X1=14 Y1=3 X2=14 Y2=4 W=0.1 L=component)" +print "}" + +print "{NET=pintst" +# a through-hole transistor +print " (PIN X=15 Y=1 R=U1.1 P=roundpad)" +print " (PIN X=15 Y=2 R=U1.2 P=squarepad)" +print " (PIN X=15 Y=3 R=U1.3 P=oblongpad)" +print "}" + +print "{NET=padtst" +print " (PAD X=16 Y=1 L=component S=ROUND SX=0.5 SY=0.5)" +print " (PAD X=16 Y=2 L=component S=RECT SX=0.5 SY=0.5)" +print " (PAD X=16 Y=3 L=component S=OBLONG SX=0.75 SY=0.5)" +print " (PAD X=17 Y=1 L=solder S=ROUND SX=0.5 SY=0.5)" +print " (PAD X=17 Y=2 L=solder S=RECT SX=0.5 SY=0.5)" +print " (PAD X=17 Y=3 L=solder S=OBLONG SX=0.75 SY=0.5)" +print "}" + +print "{NET=usegtst" +print " (USEG X1=18 Y1=1 L1=component X2=19 Y2=1 L2=component ZL=component ZW=0.1 ZLEN=2 )" +print " (USEG X1=18 Y1=2 L1=component X2=19 Y2=2 L2=component Z=50 D=1e-12 R=5 )" +print " (USEG X1=18 Y1=3 L1=component X2=19 Y2=3 L2=solder ZL=component ZW=0.1 ZLEN=2 )" +print " (USEG X1=18 Y1=4 L1=component X2=19 Y2=4 L2=solder Z=50 D=1e-12 R=5 )" +print "}" + +x0 = 6.0 +y0 = 5.0 +l = 2.0 +h = 0.5 +r = h/2.0 +w = h/4.0 + +print "{NET=polylinetst" +print " {POLYGON L=component W=0.05 ID=1 X=%f Y=%f" % (x0-w, y0-w) +print " (LINE X=%f Y=%f)" % (x0+w, y0-w) +print " (LINE X=%f Y=%f)" % (x0+w, y0+w) +print " (LINE X=%f Y=%f)" % (x0-w, y0+w) +print " (LINE X=%f Y=%f)" % (x0-w, y0-w) +print " }" +print " {POLYLINE L=component W=0.1 ID=1 X=%f Y=%f" % (x0, y0) +for a in range (0, 8, 2): + print " (LINE X=%f Y=%f)" % ( x0+l, y0+a*h) + print " (CURVE X1=%f Y1=%f X2=%f Y2=%f XC=%f YC=%f R=%f)" % ( x0+l, y0+a*h, x0+l, y0+(a+1)*h, x0+l, y0+(a+0.5)*h, r) + print " (LINE X=%f Y=%f)" % ( x0, y0+(a+1)*h) + print " (CURVE X1=%f Y1=%f X2=%f Y2=%f XC=%f YC=%f R=%f)" % ( x0, y0+(a+2)*h, x0, y0+(a+1)*h, x0, y0+(a+1.5)*h, r) + +print " }" +print "}" + +x0 = 9.5 +y0 = 5.5 +r = 0.5 + +print "{NET=curvetst" +print " {POLYGON L=component W=0.05 ID=2 X=%f Y=%f" % (x0+r, y0) +print " (CURVE X1=%f Y1=%f X2=%f Y2=%f XC=%f YC=%f R=%f )" % (x0+r, y0, x0+r, y0, x0, y0, r) +print " }" +print " {POLYVOID ID=2 X=%f Y=%f" % (x0-r/2, y0) +print " (CURVE X1=%f Y1=%f X2=%f Y2=%f XC=%f YC=%f R=%f )" % (x0-r/2, y0, x0+r/2, y0, x0, y0, r/2) +print " (LINE X=%f Y=%f)" % (x0-r/2, y0) +print " }" +print "}" + +x0 = 9.0 +y0 = 6.5 +w = 0.5 + +print "{NET=linetst" +print " {POLYGON L=component W=0.05 ID=3 X=%f Y=%f" % (x0, y0) +print " (LINE X=%f Y=%f)" % (x0+2*w, y0) +print " (LINE X=%f Y=%f)" % (x0+2*w, y0+w) +print " (LINE X=%f Y=%f)" % (x0+w, y0+w) +print " (LINE X=%f Y=%f)" % (x0+w, y0+2*w) +print " (LINE X=%f Y=%f)" % (x0, y0+2*w) +print " (LINE X=%f Y=%f)" % (x0, y0) +print " }" + +x0 = 9.125 +y0 = 6.625 +w = 0.25 + +print " {POLYVOID ID=3 X=%f Y=%f" % (x0, y0) +print " (LINE X=%f Y=%f)" % (x0+2*w, y0) +print " (LINE X=%f Y=%f)" % (x0+2*w, y0+w) +print " (LINE X=%f Y=%f)" % (x0+w, y0+w) +print " (LINE X=%f Y=%f)" % (x0+w, y0+2*w) +print " (LINE X=%f Y=%f)" % (x0, y0+2*w) +print " (LINE X=%f Y=%f)" % (x0, y0) +print " }" + +print "}" + +x0 = 11.5 +y0 = 5.0 +w = 1.0 +h = 0.5 +s = 1.0 + +def mkpolygon (typ, linewdth, id, x0, y0, w, h): + print " {POLYGON L=component T=%s W=%f ID=%i X=%f Y=%f" % (typ, linewdth, id, x0, y0) + print " (LINE X=%f Y=%f)" % (x0+w, y0) + print " (LINE X=%f Y=%f)" % (x0+w, y0+h) + print " (LINE X=%f Y=%f)" % (x0, y0+h) + print " (LINE X=%f Y=%f)" % (x0, y0) + print " }" + return + +def mkpolyvoid (id, x0, y0, w, h): + print " {POLYVOID ID=%i X=%f Y=%f" % (id, x0, y0) + print " (LINE X=%f Y=%f)" % (x0+w, y0) + print " (LINE X=%f Y=%f)" % (x0+w, y0+h) + print " (LINE X=%f Y=%f)" % (x0, y0+h) + print " (LINE X=%f Y=%f)" % (x0, y0) + print " }" + return + +x1 = 11.0 +x2 = x0 + w / 4.0 +print "{NET=poly_clearance_tst PS=0.05" +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0) +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0+s) +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0+2*s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=component)" % (x1, y0+h/2.0, x2, y0+h/2.0) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=component)" % (x1, y0+h/2.0+s, x2, y0+h/2.0+s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=component)" % (x1, y0+h/2.0+2*s, x2, y0+h/2.0+2*s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=component)" % (x1, y0+h/2.0, x1, y0+h/2.0+s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=component)" % (x1, y0+h/2.0+s, x1, y0+h/2.0+2*s) + +mkpolygon("POUR", 0.1, 4, x0, y0, w, h) +mkpolygon("COPPER", 0.1, 5, x0, y0 + s, w, h) +mkpolygon("PLANE", 0.1, 6, x0, y0 + 2 * s, w, h) + +print "}" + +x1 = 13.0 +x2 = x0 + w * 3.0 / 4.0 +print "{NET=poly_clearance_tst2 PS=0.05" +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0) +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0+s) +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0+2*s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=component)" % (x1, y0+h/2.0, x2, y0+h/2.0) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=component)" % (x1, y0+h/2.0+s, x2, y0+h/2.0+s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=component)" % (x1, y0+h/2.0+2*s, x2, y0+h/2.0+2*s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=component)" % (x1, y0+h/2.0, x1, y0+h/2.0+s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=component)" % (x1, y0+h/2.0+s, x1, y0+h/2.0+2*s) +print "}" + +# test nesting of polygons + +x0 = 14.0 +y0 = 5.0 +s = 0.25 +print "{NET=nesting_poly_1 PS=0" +mkpolygon("POUR", 0, 7, x0, y0, 8*s, 8*s) +mkpolyvoid(7, x0+1*s, y0+1*s, 6*s, 6*s) +print "}" +print "{NET=nesting_poly_2 PS=0" +mkpolygon("POUR", 0, 8, x0+2*s, y0+2*s, 4*s, 4*s) +mkpolyvoid(8, x0+3*s, y0+3*s, 2*s, 2*s) +print "}" + +print "{END}" + +# not truncated Property changes on: tags/2.3.0/src_plugins/io_hyp/tests/test00/gen_test00.py ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/src_plugins/io_hyp/tests/test00/test00.hyp =================================================================== --- tags/2.3.0/src_plugins/io_hyp/tests/test00/test00.hyp (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/tests/test00/test00.hyp (revision 33253) @@ -0,0 +1,289 @@ +{VERSION=2.0} +{UNITS=METRIC LENGTH} +{BOARD + (PERIMETER_SEGMENT X1=1.0 Y1=0.0 X2=19.0 Y2=0.0) + (PERIMETER_SEGMENT X1=20.0 Y1=1.0 X2=20.0 Y2=9.0) + (PERIMETER_SEGMENT X1=19.0 Y1=10.0 X2=1.0 Y2=10.0) + (PERIMETER_SEGMENT X1=0.0 Y1=9.0 X2=0.0 Y2=1.0) + (PERIMETER_ARC X1=0.0 Y1=1.0 X2=1.0 Y2=0.0 XC=1.0 YC=1.0 R=1.0) + (PERIMETER_ARC X1=1.0 Y1=10.0 X2=0.0 Y2=9.0 XC=1.0 YC=9.0 R=1.0) + (PERIMETER_ARC X1=20.0 Y1=9.0 X2=19.0 Y2=10.0 XC=19.0 YC=9.0 R=1.0) + (PERIMETER_ARC X1=19.0 Y1=0.0 X2=20.0 Y2=1.0 XC=19.0 YC=1.0 R=1.0) + + (PERIMETER_SEGMENT X1=2.0 Y1=1.0 X2=3.0 Y2=1.0) + (PERIMETER_SEGMENT X1=3.0 Y1=9.0 X2=2.0 Y2=9.0) + (PERIMETER_ARC X1=2.0 Y1=9.0 X2=1.0 Y2=8.0 XC=2.0 YC=8.0 R=1.0) + (PERIMETER_SEGMENT X1=1.0 Y1=8.0 X2=1.0 Y2=2.0) + (PERIMETER_ARC X1=1.0 Y1=2.0 X2=2.0 Y2=1.0 XC=2.0 YC=2.0 R=1.0) + (PERIMETER_SEGMENT X1=4.0 Y1=2.0 X2=4.0 Y2=8.0) + (PERIMETER_ARC X1=3.0 Y1=1.0 X2=4.0 Y2=2.0 XC=3.0 YC=2.0 R=1.0) + (PERIMETER_ARC X1=4.0 Y1=8.0 X2=3.0 Y2=9.0 XC=3.0 YC=8.0 R=1.0) + (PERIMETER_ARC X1=5.5 Y1=5.0 X2=5.5 Y2=5.0 XC=5.0 YC=5.0 R=0.5) + (PERIMETER_ARC X1=5.5 Y1=6.0 X2=4.5 Y2=6.0 XC=5.0 YC=6.0 R=0.5) + (PERIMETER_SEGMENT X1=4.5 Y1=6.0 X2=5.5 Y2=6.0) + (PERIMETER_ARC X1=4.5 Y1=7.5 X2=5.5 Y2=7.5 XC=5.0 YC=7.5 R=0.5) + (PERIMETER_SEGMENT X1=4.5 Y1=7.5 X2=5.5 Y2=7.5) + (PERIMETER_ARC X1=5.5 Y1=8.5 X2=5.0 Y2=8.0 XC=5.0 YC=8.5 R=0.5) + (PERIMETER_SEGMENT X1=5.0 Y1=8.0 X2=5.5 Y2=8.5) +} +{PLANE_SEP=0.05} +{STACKUP + (SIGNAL T=0.000700 L=component) + (DIELECTRIC T=0.002000 C=4.000000) + (PLANE T=0.000700 L=solder PS=0.508) +} +{DEVICES + (? REF=U1 NAME=BC548 L=component) +} +{PADSTACK=roundpad, 0.2 + (MDEF, 0, 0.5, 0.5, 0) +} +{PADSTACK=squarepad, 0.2 + (MDEF, 1, 0.5, 0.5, 0) +} +{PADSTACK=oblongpad, 0.2 + (MDEF, 2, 0.75, 0.5, 0) +} +{PADSTACK=nodrill, + (MDEF, 0, 0.5, 0.5, 0) +} +{PADSTACK=0802pad, + (component, 1, 0.2, 0.12, 0) +} +{NET=segtst + (SEG X1=6.500000 Y1=3.000000 X2=6.625000 Y2=3.000000 W=0.008333 L=component) + (SEG X1=6.433013 Y1=3.250000 X2=6.649519 Y2=3.375000 W=0.016667 L=component) + (SEG X1=6.250000 Y1=3.433013 X2=6.437500 Y2=3.757772 W=0.025000 L=component) + (SEG X1=6.000000 Y1=3.500000 X2=6.000000 Y2=4.000000 W=0.033333 L=component) + (SEG X1=5.750000 Y1=3.433013 X2=5.437500 Y2=3.974279 W=0.041667 L=component) + (SEG X1=5.566987 Y1=3.250000 X2=4.917468 Y2=3.625000 W=0.050000 L=component) + (SEG X1=5.500000 Y1=3.000000 X2=4.625000 Y2=3.000000 W=0.058333 L=component) + (SEG X1=5.566987 Y1=2.750000 X2=4.700962 Y2=2.250000 W=0.066667 L=component) + (SEG X1=5.750000 Y1=2.566987 X2=5.187500 Y2=1.592709 W=0.075000 L=component) + (SEG X1=6.000000 Y1=2.500000 X2=6.000000 Y2=1.250000 W=0.083333 L=component) + (SEG X1=6.250000 Y1=2.566987 X2=6.937500 Y2=1.376202 W=0.091667 L=component) + (SEG X1=6.433013 Y1=2.750000 X2=7.732051 Y2=2.000000 W=0.100000 L=component) +} +{NET=arctst + (ARC X1=9.100000 Y1=1.000000 X2=9.100000 Y2=1.000000 XC=9.000000 YC=1.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.100000 Y1=1.400000 X2=9.070711 Y2=1.470711 XC=9.000000 YC=1.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.100000 Y1=1.800000 X2=9.000000 Y2=1.900000 XC=9.000000 YC=1.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.100000 Y1=2.200000 X2=8.929289 Y2=2.270711 XC=9.000000 YC=2.200000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.100000 Y1=2.600000 X2=8.900000 Y2=2.600000 XC=9.000000 YC=2.600000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.100000 Y1=3.000000 X2=8.929289 Y2=2.929289 XC=9.000000 YC=3.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.100000 Y1=3.400000 X2=9.000000 Y2=3.300000 XC=9.000000 YC=3.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.100000 Y1=3.800000 X2=9.070711 Y2=3.729289 XC=9.000000 YC=3.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.470711 Y1=1.070711 X2=9.500000 Y2=1.000000 XC=9.400000 YC=1.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.470711 Y1=1.470711 X2=9.470711 Y2=1.470711 XC=9.400000 YC=1.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.470711 Y1=1.870711 X2=9.400000 Y2=1.900000 XC=9.400000 YC=1.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.470711 Y1=2.270711 X2=9.329289 Y2=2.270711 XC=9.400000 YC=2.200000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.470711 Y1=2.670711 X2=9.300000 Y2=2.600000 XC=9.400000 YC=2.600000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.470711 Y1=3.070711 X2=9.329289 Y2=2.929289 XC=9.400000 YC=3.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.470711 Y1=3.470711 X2=9.400000 Y2=3.300000 XC=9.400000 YC=3.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.470711 Y1=3.870711 X2=9.470711 Y2=3.729289 XC=9.400000 YC=3.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.800000 Y1=1.100000 X2=9.900000 Y2=1.000000 XC=9.800000 YC=1.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.800000 Y1=1.500000 X2=9.870711 Y2=1.470711 XC=9.800000 YC=1.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.800000 Y1=1.900000 X2=9.800000 Y2=1.900000 XC=9.800000 YC=1.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.800000 Y1=2.300000 X2=9.729289 Y2=2.270711 XC=9.800000 YC=2.200000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.800000 Y1=2.700000 X2=9.700000 Y2=2.600000 XC=9.800000 YC=2.600000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.800000 Y1=3.100000 X2=9.729289 Y2=2.929289 XC=9.800000 YC=3.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.800000 Y1=3.500000 X2=9.800000 Y2=3.300000 XC=9.800000 YC=3.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=9.800000 Y1=3.900000 X2=9.870711 Y2=3.729289 XC=9.800000 YC=3.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.129289 Y1=1.070711 X2=10.300000 Y2=1.000000 XC=10.200000 YC=1.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.129289 Y1=1.470711 X2=10.270711 Y2=1.470711 XC=10.200000 YC=1.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.129289 Y1=1.870711 X2=10.200000 Y2=1.900000 XC=10.200000 YC=1.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.129289 Y1=2.270711 X2=10.129289 Y2=2.270711 XC=10.200000 YC=2.200000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.129289 Y1=2.670711 X2=10.100000 Y2=2.600000 XC=10.200000 YC=2.600000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.129289 Y1=3.070711 X2=10.129289 Y2=2.929289 XC=10.200000 YC=3.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.129289 Y1=3.470711 X2=10.200000 Y2=3.300000 XC=10.200000 YC=3.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.129289 Y1=3.870711 X2=10.270711 Y2=3.729289 XC=10.200000 YC=3.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.500000 Y1=1.000000 X2=10.700000 Y2=1.000000 XC=10.600000 YC=1.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.500000 Y1=1.400000 X2=10.670711 Y2=1.470711 XC=10.600000 YC=1.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.500000 Y1=1.800000 X2=10.600000 Y2=1.900000 XC=10.600000 YC=1.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.500000 Y1=2.200000 X2=10.529289 Y2=2.270711 XC=10.600000 YC=2.200000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.500000 Y1=2.600000 X2=10.500000 Y2=2.600000 XC=10.600000 YC=2.600000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.500000 Y1=3.000000 X2=10.529289 Y2=2.929289 XC=10.600000 YC=3.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.500000 Y1=3.400000 X2=10.600000 Y2=3.300000 XC=10.600000 YC=3.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.500000 Y1=3.800000 X2=10.670711 Y2=3.729289 XC=10.600000 YC=3.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.929289 Y1=0.929289 X2=11.100000 Y2=1.000000 XC=11.000000 YC=1.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.929289 Y1=1.329289 X2=11.070711 Y2=1.470711 XC=11.000000 YC=1.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.929289 Y1=1.729289 X2=11.000000 Y2=1.900000 XC=11.000000 YC=1.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.929289 Y1=2.129289 X2=10.929289 Y2=2.270711 XC=11.000000 YC=2.200000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.929289 Y1=2.529289 X2=10.900000 Y2=2.600000 XC=11.000000 YC=2.600000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.929289 Y1=2.929289 X2=10.929289 Y2=2.929289 XC=11.000000 YC=3.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.929289 Y1=3.329289 X2=11.000000 Y2=3.300000 XC=11.000000 YC=3.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=10.929289 Y1=3.729289 X2=11.070711 Y2=3.729289 XC=11.000000 YC=3.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.400000 Y1=0.900000 X2=11.500000 Y2=1.000000 XC=11.400000 YC=1.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.400000 Y1=1.300000 X2=11.470711 Y2=1.470711 XC=11.400000 YC=1.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.400000 Y1=1.700000 X2=11.400000 Y2=1.900000 XC=11.400000 YC=1.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.400000 Y1=2.100000 X2=11.329289 Y2=2.270711 XC=11.400000 YC=2.200000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.400000 Y1=2.500000 X2=11.300000 Y2=2.600000 XC=11.400000 YC=2.600000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.400000 Y1=2.900000 X2=11.329289 Y2=2.929289 XC=11.400000 YC=3.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.400000 Y1=3.300000 X2=11.400000 Y2=3.300000 XC=11.400000 YC=3.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.400000 Y1=3.700000 X2=11.470711 Y2=3.729289 XC=11.400000 YC=3.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.870711 Y1=0.929289 X2=11.900000 Y2=1.000000 XC=11.800000 YC=1.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.870711 Y1=1.329289 X2=11.870711 Y2=1.470711 XC=11.800000 YC=1.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.870711 Y1=1.729289 X2=11.800000 Y2=1.900000 XC=11.800000 YC=1.800000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.870711 Y1=2.129289 X2=11.729289 Y2=2.270711 XC=11.800000 YC=2.200000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.870711 Y1=2.529289 X2=11.700000 Y2=2.600000 XC=11.800000 YC=2.600000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.870711 Y1=2.929289 X2=11.729289 Y2=2.929289 XC=11.800000 YC=3.000000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.870711 Y1=3.329289 X2=11.800000 Y2=3.300000 XC=11.800000 YC=3.400000 R=0.100000 W=0.025000 L=component) + (ARC X1=11.870711 Y1=3.729289 X2=11.870711 Y2=3.729289 XC=11.800000 YC=3.800000 R=0.100000 W=0.025000 L=component) +} +{NET=viatst + (VIA X=13 Y=1 P=roundpad) + (VIA X=13 Y=2 P=squarepad) + (VIA X=13 Y=3 P=oblongpad) + (VIA X=13 Y=4 P=nodrill) + (SEG X1=13 Y1=1 X2=13 Y2=2 W=0.1 L=component) + (SEG X1=13 Y1=2 X2=13 Y2=3 W=0.1 L=component) + (SEG X1=13 Y1=3 X2=13 Y2=4 W=0.1 L=component) +} +{NET=oldviatst + (VIA X=14 Y=1 D=0.2 L1=component S1=ROUND S1X=0.5 S1Y=0.5) + (VIA X=14 Y=2 D=0.2 L1=component L2=solder S1=RECT S1X=0.5 S1Y=0.5) + (VIA X=14 Y=3 D=0.2 L1=component L2=solder S1=OBLONG S1X=0.75 S1Y=0.5) + (VIA X=14 Y=4 D=0.0 L1=component L2=solder S1=ROUND S1X=0.5 S1Y=0.5) + (SEG X1=14 Y1=1 X2=14 Y2=2 W=0.1 L=component) + (SEG X1=14 Y1=2 X2=14 Y2=3 W=0.1 L=component) + (SEG X1=14 Y1=3 X2=14 Y2=4 W=0.1 L=component) +} +{NET=pintst + (PIN X=15 Y=1 R=U1.1 P=roundpad) + (PIN X=15 Y=2 R=U1.2 P=squarepad) + (PIN X=15 Y=3 R=U1.3 P=oblongpad) +} +{NET=padtst + (PAD X=16 Y=1 L=component S=ROUND SX=0.5 SY=0.5) + (PAD X=16 Y=2 L=component S=RECT SX=0.5 SY=0.5) + (PAD X=16 Y=3 L=component S=OBLONG SX=0.75 SY=0.5) + (PAD X=17 Y=1 L=solder S=ROUND SX=0.5 SY=0.5) + (PAD X=17 Y=2 L=solder S=RECT SX=0.5 SY=0.5) + (PAD X=17 Y=3 L=solder S=OBLONG SX=0.75 SY=0.5) +} +{NET=usegtst + (USEG X1=18 Y1=1 L1=component X2=19 Y2=1 L2=component ZL=component ZW=0.1 ZLEN=2 ) + (USEG X1=18 Y1=2 L1=component X2=19 Y2=2 L2=component Z=50 D=1e-12 R=5 ) + (USEG X1=18 Y1=3 L1=component X2=19 Y2=3 L2=solder ZL=component ZW=0.1 ZLEN=2 ) + (USEG X1=18 Y1=4 L1=component X2=19 Y2=4 L2=solder Z=50 D=1e-12 R=5 ) +} +{NET=polylinetst + {POLYGON L=component W=0.05 ID=1 X=5.875000 Y=4.875000 + (LINE X=6.125000 Y=4.875000) + (LINE X=6.125000 Y=5.125000) + (LINE X=5.875000 Y=5.125000) + (LINE X=5.875000 Y=4.875000) + } + {POLYLINE L=component W=0.1 ID=1 X=6.000000 Y=5.000000 + (LINE X=8.000000 Y=5.000000) + (CURVE X1=8.000000 Y1=5.000000 X2=8.000000 Y2=5.500000 XC=8.000000 YC=5.250000 R=0.250000) + (LINE X=6.000000 Y=5.500000) + (CURVE X1=6.000000 Y1=6.000000 X2=6.000000 Y2=5.500000 XC=6.000000 YC=5.750000 R=0.250000) + (LINE X=8.000000 Y=6.000000) + (CURVE X1=8.000000 Y1=6.000000 X2=8.000000 Y2=6.500000 XC=8.000000 YC=6.250000 R=0.250000) + (LINE X=6.000000 Y=6.500000) + (CURVE X1=6.000000 Y1=7.000000 X2=6.000000 Y2=6.500000 XC=6.000000 YC=6.750000 R=0.250000) + (LINE X=8.000000 Y=7.000000) + (CURVE X1=8.000000 Y1=7.000000 X2=8.000000 Y2=7.500000 XC=8.000000 YC=7.250000 R=0.250000) + (LINE X=6.000000 Y=7.500000) + (CURVE X1=6.000000 Y1=8.000000 X2=6.000000 Y2=7.500000 XC=6.000000 YC=7.750000 R=0.250000) + (LINE X=8.000000 Y=8.000000) + (CURVE X1=8.000000 Y1=8.000000 X2=8.000000 Y2=8.500000 XC=8.000000 YC=8.250000 R=0.250000) + (LINE X=6.000000 Y=8.500000) + (CURVE X1=6.000000 Y1=9.000000 X2=6.000000 Y2=8.500000 XC=6.000000 YC=8.750000 R=0.250000) + } +} +{NET=curvetst + {POLYGON L=component W=0.05 ID=2 X=10.000000 Y=5.500000 + (CURVE X1=10.000000 Y1=5.500000 X2=10.000000 Y2=5.500000 XC=9.500000 YC=5.500000 R=0.500000 ) + } + {POLYVOID ID=2 X=9.250000 Y=5.500000 + (CURVE X1=9.250000 Y1=5.500000 X2=9.750000 Y2=5.500000 XC=9.500000 YC=5.500000 R=0.250000 ) + (LINE X=9.250000 Y=5.500000) + } +} +{NET=linetst + {POLYGON L=component W=0.05 ID=3 X=9.000000 Y=6.500000 + (LINE X=10.000000 Y=6.500000) + (LINE X=10.000000 Y=7.000000) + (LINE X=9.500000 Y=7.000000) + (LINE X=9.500000 Y=7.500000) + (LINE X=9.000000 Y=7.500000) + (LINE X=9.000000 Y=6.500000) + } + {POLYVOID ID=3 X=9.125000 Y=6.625000 + (LINE X=9.625000 Y=6.625000) + (LINE X=9.625000 Y=6.875000) + (LINE X=9.375000 Y=6.875000) + (LINE X=9.375000 Y=7.125000) + (LINE X=9.125000 Y=7.125000) + (LINE X=9.125000 Y=6.625000) + } +} +{NET=poly_clearance_tst PS=0.05 + (VIA X=11.750000 Y=5.250000 P=0802pad) + (VIA X=11.750000 Y=6.250000 P=0802pad) + (VIA X=11.750000 Y=7.250000 P=0802pad) + (SEG X1=11.000000 Y1=5.250000 X2=11.750000 Y2=5.250000 W=0.04 L=component) + (SEG X1=11.000000 Y1=6.250000 X2=11.750000 Y2=6.250000 W=0.04 L=component) + (SEG X1=11.000000 Y1=7.250000 X2=11.750000 Y2=7.250000 W=0.04 L=component) + (SEG X1=11.000000 Y1=5.250000 X2=11.000000 Y2=6.250000 W=0.04 L=component) + (SEG X1=11.000000 Y1=6.250000 X2=11.000000 Y2=7.250000 W=0.04 L=component) + {POLYGON L=component T=POUR W=0.100000 ID=4 X=11.500000 Y=5.000000 + (LINE X=12.500000 Y=5.000000) + (LINE X=12.500000 Y=5.500000) + (LINE X=11.500000 Y=5.500000) + (LINE X=11.500000 Y=5.000000) + } + {POLYGON L=component T=COPPER W=0.100000 ID=5 X=11.500000 Y=6.000000 + (LINE X=12.500000 Y=6.000000) + (LINE X=12.500000 Y=6.500000) + (LINE X=11.500000 Y=6.500000) + (LINE X=11.500000 Y=6.000000) + } + {POLYGON L=component T=PLANE W=0.100000 ID=6 X=11.500000 Y=7.000000 + (LINE X=12.500000 Y=7.000000) + (LINE X=12.500000 Y=7.500000) + (LINE X=11.500000 Y=7.500000) + (LINE X=11.500000 Y=7.000000) + } +} +{NET=poly_clearance_tst2 PS=0.05 + (VIA X=12.250000 Y=5.250000 P=0802pad) + (VIA X=12.250000 Y=6.250000 P=0802pad) + (VIA X=12.250000 Y=7.250000 P=0802pad) + (SEG X1=13.000000 Y1=5.250000 X2=12.250000 Y2=5.250000 W=0.04 L=component) + (SEG X1=13.000000 Y1=6.250000 X2=12.250000 Y2=6.250000 W=0.04 L=component) + (SEG X1=13.000000 Y1=7.250000 X2=12.250000 Y2=7.250000 W=0.04 L=component) + (SEG X1=13.000000 Y1=5.250000 X2=13.000000 Y2=6.250000 W=0.04 L=component) + (SEG X1=13.000000 Y1=6.250000 X2=13.000000 Y2=7.250000 W=0.04 L=component) +} +{NET=nesting_poly_1 PS=0 + {POLYGON L=component T=POUR W=0.000000 ID=7 X=14.000000 Y=5.000000 + (LINE X=16.000000 Y=5.000000) + (LINE X=16.000000 Y=7.000000) + (LINE X=14.000000 Y=7.000000) + (LINE X=14.000000 Y=5.000000) + } + {POLYVOID ID=7 X=14.250000 Y=5.250000 + (LINE X=15.750000 Y=5.250000) + (LINE X=15.750000 Y=6.750000) + (LINE X=14.250000 Y=6.750000) + (LINE X=14.250000 Y=5.250000) + } +} +{NET=nesting_poly_2 PS=0 + {POLYGON L=component T=POUR W=0.000000 ID=8 X=14.500000 Y=5.500000 + (LINE X=15.500000 Y=5.500000) + (LINE X=15.500000 Y=6.500000) + (LINE X=14.500000 Y=6.500000) + (LINE X=14.500000 Y=5.500000) + } + {POLYVOID ID=8 X=14.750000 Y=5.750000 + (LINE X=15.250000 Y=5.750000) + (LINE X=15.250000 Y=6.250000) + (LINE X=14.750000 Y=6.250000) + (LINE X=14.750000 Y=5.750000) + } +} +{END} Index: tags/2.3.0/src_plugins/io_hyp/tests/test01/README.txt =================================================================== --- tags/2.3.0/src_plugins/io_hyp/tests/test01/README.txt (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/tests/test01/README.txt (revision 33253) @@ -0,0 +1,3 @@ +Source: handwritten +GPL: Yes +Remark: contains common syntax errors Index: tags/2.3.0/src_plugins/io_hyp/tests/test01/gen_test01.py =================================================================== --- tags/2.3.0/src_plugins/io_hyp/tests/test01/gen_test01.py (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/tests/test01/gen_test01.py (revision 33253) @@ -0,0 +1,329 @@ +#!/usr/bin/python +""" + Generate sample hyperlynx file + Copyright 2017 Koen De Vleeschauwer. + + This file is part of pcb-rnd. + + 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, see . +""" + +from math import pi, sin, cos +print "* Job: Comment" +print "" +print "{VERSION=2.01}" +print "{UNITS=METRIC LENGTH}" +print "{BOARD" +print " (PERIMETER_SEGMENT X1=1.0 Y1=0.0 X2=19.0 Y2=0.0" +print " (PERIMETER_SEGMENT X1=20.0 Y1=1.0 X2=20.0 Y2=9.0" +print " (PERIMETER_SEGMENT X1=19.0 Y1=10.0 X2=1.0 Y2=10.0" +print " (PERIMETER_SEGMENT X1=0.0 Y1=9.0 X2=0.0 Y2=1.0" +print " (PERIMETER_ARC X1=0.0 Y1=1.0 X2=1.0 Y2=0.0 XC=1.0 YC=1.0 R=1.0" +print " (PERIMETER_ARC X1=1.0 Y1=10.0 X2=0.0 Y2=9.0 XC=1.0 YC=9.0 R=1.0" +print " (PERIMETER_ARC X1=20.0 Y1=9.0 X2=19.0 Y2=10.0 XC=19.0 YC=9.0 R=1.0" +print " (PERIMETER_ARC X1=19.0 Y1=0.0 X2=20.0 Y2=1.0 XC=19.0 YC=1.0 R=1.0" +print "" +print " (PERIMETER_SEGMENT X1=2.0 Y1=1.0 X2=3.0 Y2=1.0" +print " (PERIMETER_SEGMENT X1=3.0 Y1=9.0 X2=2.0 Y2=9.0" +print " (PERIMETER_ARC X1=2.0 Y1=9.0 X2=1.0 Y2=8.0 XC=2.0 YC=8.0 R=1.0" +print " (PERIMETER_SEGMENT X1=1.0 Y1=8.0 X2=1.0 Y2=2.0" +print " (PERIMETER_ARC X1=1.0 Y1=2.0 X2=2.0 Y2=1.0 XC=2.0 YC=2.0 R=1.0" +print " (PERIMETER_SEGMENT X1=4.0 Y1=2.0 X2=4.0 Y2=8.0" +print " (PERIMETER_ARC X1=3.0 Y1=1.0 X2=4.0 Y2=2.0 XC=3.0 YC=2.0 R=1.0" +print " (PERIMETER_ARC X1=4.0 Y1=8.0 X2=3.0 Y2=9.0 XC=3.0 YC=8.0 R=1.0" + +print " (PERIMETER_ARC X1=5.5 Y1=5.0 X2=5.5 Y2=5.0 XC=5.0 YC=5.0 R=0.5" + +print " (PERIMETER_ARC X1=5.5 Y1=6.0 X2=4.5 Y2=6.0 XC=5.0 YC=6.0 R=0.5" +print " (PERIMETER_SEGMENT X1=4.5 Y1=6.0 X2=5.5 Y2=6.0" + +print " (PERIMETER_ARC X1=4.5 Y1=7.5 X2=5.5 Y2=7.5 XC=5.0 YC=7.5 R=0.5" +print " (PERIMETER_SEGMENT X1=4.5 Y1=7.5 X2=5.5 Y2=7.5" + +print " (PERIMETER_ARC X1=5.5 Y1=8.5 X2=5.0 Y2=8.0 XC=5.0 YC=8.5 R=0.5" +print " (PERIMETER_SEGMENT X1=5.0 Y1=8.0 X2=5.5 Y2=8.5" + +print "}" + +print "{PLANE_SEP=0.05}" + +print "{STACKUP" +print " (SIGNAL T=0.001778 L=1 C=1.67e-008)" +print " (DIELECTRIC T=0.149900 C=4.700000)" +print " (PLANE T=0.001778 L=2 C=1.67e-008)" +print "}" +print "{DEVICES" +print " (? REF=U1 NAME=BC848 NPN 1x1 L=1)" +print "}" + +# +# PADSTACK. MDEF is shorthand for "all copper layers" +# + +print "{PADSTACK=roundpad, 0.2" +print " (MDEF, 0, 0.5, 0.5, 0)" +print "}" +print "{PADSTACK=squarepad, 0.2" +print " (MDEF, 1, 0.5, 0.5, 0)" +print "}" +print "{PADSTACK=oblongpad, 0.2" +print " (MDEF, 2, 0.5, 0.5, 0)" +print "}" +print "{PADSTACK=nodrill," +print " (MDEF, 0, 0.5, 0.5, 0)" +print "}" +print "{PADSTACK=0802pad," +print " (1, 1, 0.2, 0.12, 0)" +print "}" + +# +# SEG line segments +# + +x0 = 6 +y0 = 3 +r1 = 0.5 +r2 = 2 +max = 12 + +print "{NET=segtst" + +for x in range (0, max): + alpha = x * 2 * pi / max + x1 = x0 + r1 * cos (alpha) + y1 = y0 + r1 * sin (alpha) + r = r1 + (r2 - r1) * (x + 1) / max + x2 = x0 + r * cos (alpha) + y2 = y0 + r * sin (alpha) + w = (x + 1) * 0.1 / max + print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=%f L=1)" % ( x1, y1, x2, y2, w) + +print "}" + +# +# ARC arc segments +# + +max = 8 +x0 = 9 +y0 = 1 +r = 0.1 +w = r / 4 + +print "{NET=arctst" + +for a in range (0, max): + for b in range (0, max): + alpha = 2 * pi * a / max + beta = 2 * pi * b / max + xc = x0 + 4 * r * a + yc = y0 + 4 * r * b + x1 = xc + r * cos (alpha) + y1 = yc + r * sin (alpha) + x2 = xc + r * cos (beta) + y2 = yc + r * sin (beta) + print " (ARC X1=%f Y1=%f X2=%f Y2=%f XC=%f YC=%f R=%f W=%f L=1)" % ( x1, y1, x2, y2, xc, yc, r, w) + +print "}" + +# +# VIA +# + +print "{NET=viatst" +print " (VIA X=13 Y=1 P=roundpad)" +print " (VIA X=13 Y=2 P=squarepad)" +print " (VIA X=13 Y=3 P=oblongpad)" +print " (VIA X=13 Y=4 P=nodrill)" +print " (SEG X1=13 Y1=1 X2=13 Y2=2 W=0.1 L=1)" +print " (SEG X1=13 Y1=2 X2=13 Y2=3 W=0.1 L=1)" +print " (SEG X1=13 Y1=3 X2=13 Y2=4 W=0.1 L=1)" +print "}" + +# +# old-style VIA, compatibility only. +# + +print "{NET=oldviatst" +print " (VIA X=14 Y=1 D=0.2 L1=1 S1=ROUND S1X=0.5 S1Y=0.5)" +print " (VIA X=14 Y=2 D=0.2 L1=1 L2=2 S1=RECT S1X=0.5 S1Y=0.5)" +print " (VIA X=14 Y=3 D=0.2 L1=1 L2=2 S1=OBLONG S1X=0.5 S1Y=0.5)" +print " (VIA X=14 Y=4 D=0.0 L1=1 L2=2 S1=ROUND S1X=0.5 S1Y=0.5)" +print " (SEG X1=14 Y1=1 X2=14 Y2=2 W=0.1 L=1)" +print " (SEG X1=14 Y1=2 X2=14 Y2=3 W=0.1 L=1)" +print " (SEG X1=14 Y1=3 X2=14 Y2=4 W=0.1 L=1)" +print "}" + +print "{NET=(pintst)" +# a through-hole transistor +print " (PIN X=15 Y=1 R=U1.1 P=roundpad)" +print " (PIN X=15 Y=2 R=U1.2 P=squarepad)" +print " (PIN X=15 Y=3 R=U1.3 P=oblongpad)" +print "}" + +print "{NET=(padtst)" +print " (PAD X=16 Y=1 L=1 S=ROUND SX=0.5 SY=0.5)" +print " (PAD X=16 Y=2 L=1 S=RECT SX=0.5 SY=0.5)" +print " (PAD X=16 Y=3 L=1 S=OBLONG SX=0.5 SY=0.5)" +print " (PAD X=17 Y=1 L=2 S=ROUND SX=0.5 SY=0.5)" +print " (PAD X=17 Y=2 L=2 S=RECT SX=0.5 SY=0.5)" +print " (PAD X=17 Y=3 L=2 S=OBLONG SX=0.5 SY=0.5)" +print "}" + +print "{NET=(usegtst)" +print " (USEG X1=18 Y1=1 L1=1 X2=19 Y2=1 L2=1 ZL=1 ZW=0.1 ZLEN=2 )" +print " (USEG X1=18 Y1=2 L1=1 X2=19 Y2=2 L2=1 Z=50 D=1e-12 R=5 )" +print " (USEG X1=18 Y1=3 L1=1 X2=19 Y2=3 L2=2 ZL=1 ZW=0.1 ZLEN=2 )" +print " (USEG X1=18 Y1=4 L1=1 X2=19 Y2=4 L2=2 Z=50 D=1e-12 R=5 )" +print "}" + +x0 = 6.0 +y0 = 5.0 +l = 2.0 +h = 0.5 +r = h/2.0 +w = h/4.0 + +print "{NET=polylinetst" +print " {POLYGON L=1 W=0.05 ID=1 X=%f Y=%f)" % (x0-w, y0-w) +print " (LINE X=%f Y=%f)" % (x0+w, y0-w) +print " (LINE X=%f Y=%f)" % (x0+w, y0+w) +print " (LINE X=%f Y=%f)" % (x0-w, y0+w) +print " (LINE X=%f Y=%f)" % (x0-w, y0-w) +print " }" +print " {POLYLINE L=1 W=0.1 ID=1 X=%f Y=%f" % (x0, y0) +for a in range (0, 8, 2): + print " (LINE X=%f Y=%f)" % ( x0+l, y0+a*h) + print " (CURVE X1=%f Y1=%f X2=%f Y2=%f XC=%f YC=%f R=%f)" % ( x0+l, y0+a*h, x0+l, y0+(a+1)*h, x0+l, y0+(a+0.5)*h, r) + print " (LINE X=%f Y=%f)" % ( x0, y0+(a+1)*h) + print " (CURVE X1=%f Y1=%f X2=%f Y2=%f XC=%f YC=%f R=%f)" % ( x0, y0+(a+2)*h, x0, y0+(a+1)*h, x0, y0+(a+1.5)*h, r) + +print " }" +print "}" + +x0 = 9.5 +y0 = 5.5 +r = 0.5 + +print "{NET=curvetst" +print " {POLYGON L=1 W=0.05 ID=2 X=%f Y=%f)" % (x0+r, y0) +print " (CURVE X1=%f Y1=%f X2=%f Y2=%f XC=%f YC=%f R=%f )" % (x0+r, y0, x0+r, y0, x0, y0, r) +print " }" +print " {POLYVOID ID=2 X=%f Y=%f" % (x0-r/2, y0) +print " (CURVE X1=%f Y1=%f X2=%f Y2=%f XC=%f YC=%f R=%f )" % (x0-r/2, y0, x0+r/2, y0, x0, y0, r/2) +print " (LINE X=%f Y=%f)" % (x0-r/2, y0) +print " }" +print "}" + +x0 = 9.0 +y0 = 6.5 +w = 0.5 + +print "{NET=linetst" +print " {POLYGON L=1 W=0.05 ID=3 X=%f Y=%f)" % (x0, y0) +print " (LINE X=%f Y=%f)" % (x0+2*w, y0) +print " (LINE X=%f Y=%f)" % (x0+2*w, y0+w) +print " (LINE X=%f Y=%f)" % (x0+w, y0+w) +print " (LINE X=%f Y=%f)" % (x0+w, y0+2*w) +print " (LINE X=%f Y=%f)" % (x0, y0+2*w) +print " (LINE X=%f Y=%f)" % (x0, y0) +print " }" + +x0 = 9.125 +y0 = 6.625 +w = 0.25 + +print " {POLYVOID ID=3 X=%f Y=%f" % (x0, y0) +print " (LINE X=%f Y=%f)" % (x0+2*w, y0) +print " (LINE X=%f Y=%f)" % (x0+2*w, y0+w) +print " (LINE X=%f Y=%f)" % (x0+w, y0+w) +print " (LINE X=%f Y=%f)" % (x0+w, y0+2*w) +print " (LINE X=%f Y=%f)" % (x0, y0+2*w) +print " (LINE X=%f Y=%f)" % (x0, y0) +print " }" + +print "}" + +x0 = 11.5 +y0 = 5.0 +w = 1.0 +h = 0.5 +s = 1.0 + +def mkpolygon (typ, linewdth, id, x0, y0, w, h): + print " {POLYGON L=1 T=%s W=%f ID=%i X=%f Y=%f)" % (typ, linewdth, id, x0, y0) + print " (LINE X=%f Y=%f)" % (x0+w, y0) + print " (LINE X=%f Y=%f)" % (x0+w, y0+h) + print " (LINE X=%f Y=%f)" % (x0, y0+h) + print " (LINE X=%f Y=%f)" % (x0, y0) + print " }" + return + +def mkpolyvoid (id, x0, y0, w, h): + print " {POLYVOID ID=%i X=%f Y=%f" % (id, x0, y0) + print " (LINE X=%f Y=%f)" % (x0+w, y0) + print " (LINE X=%f Y=%f)" % (x0+w, y0+h) + print " (LINE X=%f Y=%f)" % (x0, y0+h) + print " (LINE X=%f Y=%f)" % (x0, y0) + print " }" + return + +x1 = 11.0 +x2 = x0 + w / 4.0 +print "{NET=poly_clearance_tst PS=0.05" +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0) +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0+s) +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0+2*s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=1)" % (x1, y0+h/2.0, x2, y0+h/2.0) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=1)" % (x1, y0+h/2.0+s, x2, y0+h/2.0+s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=1)" % (x1, y0+h/2.0+2*s, x2, y0+h/2.0+2*s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=1)" % (x1, y0+h/2.0, x1, y0+h/2.0+s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=1)" % (x1, y0+h/2.0+s, x1, y0+h/2.0+2*s) + +mkpolygon("POUR", 0.1, 4, x0, y0, w, h) +mkpolygon("COPPER", 0.1, 5, x0, y0 + s, w, h) +mkpolygon("PLANE", 0.1, 6, x0, y0 + 2 * s, w, h) + +print "}" + +x1 = 13.0 +x2 = x0 + w * 3.0 / 4.0 +print "{NET=poly_clearance_tst2 PS=0.05" +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0) +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0+s) +print " (VIA X=%f Y=%f P=0802pad)" % (x2, y0+h/2.0+2*s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=1)" % (x1, y0+h/2.0, x2, y0+h/2.0) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=1)" % (x1, y0+h/2.0+s, x2, y0+h/2.0+s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=1)" % (x1, y0+h/2.0+2*s, x2, y0+h/2.0+2*s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=1)" % (x1, y0+h/2.0, x1, y0+h/2.0+s) +print " (SEG X1=%f Y1=%f X2=%f Y2=%f W=0.04 L=1)" % (x1, y0+h/2.0+s, x1, y0+h/2.0+2*s) +print "}" + +# test nesting of polygons + +x0 = 14.0 +y0 = 5.0 +s = 0.25 +print "{NET=nesting_poly_1 PS=0" +mkpolygon("POUR", 0, 7, x0, y0, 8*s, 8*s) +mkpolyvoid(7, x0+1*s, y0+1*s, 6*s, 6*s) +print "}" +print "{NET=nesting_poly_2 PS=0" +mkpolygon("POUR", 0, 8, x0+2*s, y0+2*s, 4*s, 4*s) +mkpolyvoid(8, x0+3*s, y0+3*s, 2*s, 2*s) +print "}" + +print "{END}" + +# not truncated \ No newline at end of file Index: tags/2.3.0/src_plugins/io_hyp/tests/test01/test01.hyp =================================================================== --- tags/2.3.0/src_plugins/io_hyp/tests/test01/test01.hyp (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/tests/test01/test01.hyp (revision 33253) @@ -0,0 +1,291 @@ +* Job: Comment + +{VERSION=2.01} +{UNITS=METRIC LENGTH} +{BOARD + (PERIMETER_SEGMENT X1=1.0 Y1=0.0 X2=19.0 Y2=0.0 + (PERIMETER_SEGMENT X1=20.0 Y1=1.0 X2=20.0 Y2=9.0 + (PERIMETER_SEGMENT X1=19.0 Y1=10.0 X2=1.0 Y2=10.0 + (PERIMETER_SEGMENT X1=0.0 Y1=9.0 X2=0.0 Y2=1.0 + (PERIMETER_ARC X1=0.0 Y1=1.0 X2=1.0 Y2=0.0 XC=1.0 YC=1.0 R=1.0 + (PERIMETER_ARC X1=1.0 Y1=10.0 X2=0.0 Y2=9.0 XC=1.0 YC=9.0 R=1.0 + (PERIMETER_ARC X1=20.0 Y1=9.0 X2=19.0 Y2=10.0 XC=19.0 YC=9.0 R=1.0 + (PERIMETER_ARC X1=19.0 Y1=0.0 X2=20.0 Y2=1.0 XC=19.0 YC=1.0 R=1.0 + + (PERIMETER_SEGMENT X1=2.0 Y1=1.0 X2=3.0 Y2=1.0 + (PERIMETER_SEGMENT X1=3.0 Y1=9.0 X2=2.0 Y2=9.0 + (PERIMETER_ARC X1=2.0 Y1=9.0 X2=1.0 Y2=8.0 XC=2.0 YC=8.0 R=1.0 + (PERIMETER_SEGMENT X1=1.0 Y1=8.0 X2=1.0 Y2=2.0 + (PERIMETER_ARC X1=1.0 Y1=2.0 X2=2.0 Y2=1.0 XC=2.0 YC=2.0 R=1.0 + (PERIMETER_SEGMENT X1=4.0 Y1=2.0 X2=4.0 Y2=8.0 + (PERIMETER_ARC X1=3.0 Y1=1.0 X2=4.0 Y2=2.0 XC=3.0 YC=2.0 R=1.0 + (PERIMETER_ARC X1=4.0 Y1=8.0 X2=3.0 Y2=9.0 XC=3.0 YC=8.0 R=1.0 + (PERIMETER_ARC X1=5.5 Y1=5.0 X2=5.5 Y2=5.0 XC=5.0 YC=5.0 R=0.5 + (PERIMETER_ARC X1=5.5 Y1=6.0 X2=4.5 Y2=6.0 XC=5.0 YC=6.0 R=0.5 + (PERIMETER_SEGMENT X1=4.5 Y1=6.0 X2=5.5 Y2=6.0 + (PERIMETER_ARC X1=4.5 Y1=7.5 X2=5.5 Y2=7.5 XC=5.0 YC=7.5 R=0.5 + (PERIMETER_SEGMENT X1=4.5 Y1=7.5 X2=5.5 Y2=7.5 + (PERIMETER_ARC X1=5.5 Y1=8.5 X2=5.0 Y2=8.0 XC=5.0 YC=8.5 R=0.5 + (PERIMETER_SEGMENT X1=5.0 Y1=8.0 X2=5.5 Y2=8.5 +} +{PLANE_SEP=0.05} +{STACKUP + (SIGNAL T=0.001778 L=1 C=1.67e-008) + (DIELECTRIC T=0.149900 C=4.700000) + (PLANE T=0.001778 L=2 C=1.67e-008) +} +{DEVICES + (? REF=U1 NAME=BC848 NPN 1x1 L=1) +} +{PADSTACK=roundpad, 0.2 + (MDEF, 0, 0.5, 0.5, 0) +} +{PADSTACK=squarepad, 0.2 + (MDEF, 1, 0.5, 0.5, 0) +} +{PADSTACK=oblongpad, 0.2 + (MDEF, 2, 0.5, 0.5, 0) +} +{PADSTACK=nodrill, + (MDEF, 0, 0.5, 0.5, 0) +} +{PADSTACK=0802pad, + (1, 1, 0.2, 0.12, 0) +} +{NET=segtst + (SEG X1=6.500000 Y1=3.000000 X2=6.625000 Y2=3.000000 W=0.008333 L=1) + (SEG X1=6.433013 Y1=3.250000 X2=6.649519 Y2=3.375000 W=0.016667 L=1) + (SEG X1=6.250000 Y1=3.433013 X2=6.437500 Y2=3.757772 W=0.025000 L=1) + (SEG X1=6.000000 Y1=3.500000 X2=6.000000 Y2=4.000000 W=0.033333 L=1) + (SEG X1=5.750000 Y1=3.433013 X2=5.437500 Y2=3.974279 W=0.041667 L=1) + (SEG X1=5.566987 Y1=3.250000 X2=4.917468 Y2=3.625000 W=0.050000 L=1) + (SEG X1=5.500000 Y1=3.000000 X2=4.625000 Y2=3.000000 W=0.058333 L=1) + (SEG X1=5.566987 Y1=2.750000 X2=4.700962 Y2=2.250000 W=0.066667 L=1) + (SEG X1=5.750000 Y1=2.566987 X2=5.187500 Y2=1.592709 W=0.075000 L=1) + (SEG X1=6.000000 Y1=2.500000 X2=6.000000 Y2=1.250000 W=0.083333 L=1) + (SEG X1=6.250000 Y1=2.566987 X2=6.937500 Y2=1.376202 W=0.091667 L=1) + (SEG X1=6.433013 Y1=2.750000 X2=7.732051 Y2=2.000000 W=0.100000 L=1) +} +{NET=arctst + (ARC X1=9.100000 Y1=1.000000 X2=9.100000 Y2=1.000000 XC=9.000000 YC=1.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.100000 Y1=1.400000 X2=9.070711 Y2=1.470711 XC=9.000000 YC=1.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.100000 Y1=1.800000 X2=9.000000 Y2=1.900000 XC=9.000000 YC=1.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.100000 Y1=2.200000 X2=8.929289 Y2=2.270711 XC=9.000000 YC=2.200000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.100000 Y1=2.600000 X2=8.900000 Y2=2.600000 XC=9.000000 YC=2.600000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.100000 Y1=3.000000 X2=8.929289 Y2=2.929289 XC=9.000000 YC=3.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.100000 Y1=3.400000 X2=9.000000 Y2=3.300000 XC=9.000000 YC=3.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.100000 Y1=3.800000 X2=9.070711 Y2=3.729289 XC=9.000000 YC=3.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.470711 Y1=1.070711 X2=9.500000 Y2=1.000000 XC=9.400000 YC=1.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.470711 Y1=1.470711 X2=9.470711 Y2=1.470711 XC=9.400000 YC=1.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.470711 Y1=1.870711 X2=9.400000 Y2=1.900000 XC=9.400000 YC=1.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.470711 Y1=2.270711 X2=9.329289 Y2=2.270711 XC=9.400000 YC=2.200000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.470711 Y1=2.670711 X2=9.300000 Y2=2.600000 XC=9.400000 YC=2.600000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.470711 Y1=3.070711 X2=9.329289 Y2=2.929289 XC=9.400000 YC=3.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.470711 Y1=3.470711 X2=9.400000 Y2=3.300000 XC=9.400000 YC=3.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.470711 Y1=3.870711 X2=9.470711 Y2=3.729289 XC=9.400000 YC=3.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.800000 Y1=1.100000 X2=9.900000 Y2=1.000000 XC=9.800000 YC=1.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.800000 Y1=1.500000 X2=9.870711 Y2=1.470711 XC=9.800000 YC=1.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.800000 Y1=1.900000 X2=9.800000 Y2=1.900000 XC=9.800000 YC=1.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.800000 Y1=2.300000 X2=9.729289 Y2=2.270711 XC=9.800000 YC=2.200000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.800000 Y1=2.700000 X2=9.700000 Y2=2.600000 XC=9.800000 YC=2.600000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.800000 Y1=3.100000 X2=9.729289 Y2=2.929289 XC=9.800000 YC=3.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.800000 Y1=3.500000 X2=9.800000 Y2=3.300000 XC=9.800000 YC=3.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=9.800000 Y1=3.900000 X2=9.870711 Y2=3.729289 XC=9.800000 YC=3.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.129289 Y1=1.070711 X2=10.300000 Y2=1.000000 XC=10.200000 YC=1.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.129289 Y1=1.470711 X2=10.270711 Y2=1.470711 XC=10.200000 YC=1.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.129289 Y1=1.870711 X2=10.200000 Y2=1.900000 XC=10.200000 YC=1.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.129289 Y1=2.270711 X2=10.129289 Y2=2.270711 XC=10.200000 YC=2.200000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.129289 Y1=2.670711 X2=10.100000 Y2=2.600000 XC=10.200000 YC=2.600000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.129289 Y1=3.070711 X2=10.129289 Y2=2.929289 XC=10.200000 YC=3.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.129289 Y1=3.470711 X2=10.200000 Y2=3.300000 XC=10.200000 YC=3.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.129289 Y1=3.870711 X2=10.270711 Y2=3.729289 XC=10.200000 YC=3.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.500000 Y1=1.000000 X2=10.700000 Y2=1.000000 XC=10.600000 YC=1.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.500000 Y1=1.400000 X2=10.670711 Y2=1.470711 XC=10.600000 YC=1.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.500000 Y1=1.800000 X2=10.600000 Y2=1.900000 XC=10.600000 YC=1.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.500000 Y1=2.200000 X2=10.529289 Y2=2.270711 XC=10.600000 YC=2.200000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.500000 Y1=2.600000 X2=10.500000 Y2=2.600000 XC=10.600000 YC=2.600000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.500000 Y1=3.000000 X2=10.529289 Y2=2.929289 XC=10.600000 YC=3.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.500000 Y1=3.400000 X2=10.600000 Y2=3.300000 XC=10.600000 YC=3.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.500000 Y1=3.800000 X2=10.670711 Y2=3.729289 XC=10.600000 YC=3.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.929289 Y1=0.929289 X2=11.100000 Y2=1.000000 XC=11.000000 YC=1.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.929289 Y1=1.329289 X2=11.070711 Y2=1.470711 XC=11.000000 YC=1.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.929289 Y1=1.729289 X2=11.000000 Y2=1.900000 XC=11.000000 YC=1.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.929289 Y1=2.129289 X2=10.929289 Y2=2.270711 XC=11.000000 YC=2.200000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.929289 Y1=2.529289 X2=10.900000 Y2=2.600000 XC=11.000000 YC=2.600000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.929289 Y1=2.929289 X2=10.929289 Y2=2.929289 XC=11.000000 YC=3.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.929289 Y1=3.329289 X2=11.000000 Y2=3.300000 XC=11.000000 YC=3.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=10.929289 Y1=3.729289 X2=11.070711 Y2=3.729289 XC=11.000000 YC=3.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.400000 Y1=0.900000 X2=11.500000 Y2=1.000000 XC=11.400000 YC=1.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.400000 Y1=1.300000 X2=11.470711 Y2=1.470711 XC=11.400000 YC=1.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.400000 Y1=1.700000 X2=11.400000 Y2=1.900000 XC=11.400000 YC=1.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.400000 Y1=2.100000 X2=11.329289 Y2=2.270711 XC=11.400000 YC=2.200000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.400000 Y1=2.500000 X2=11.300000 Y2=2.600000 XC=11.400000 YC=2.600000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.400000 Y1=2.900000 X2=11.329289 Y2=2.929289 XC=11.400000 YC=3.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.400000 Y1=3.300000 X2=11.400000 Y2=3.300000 XC=11.400000 YC=3.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.400000 Y1=3.700000 X2=11.470711 Y2=3.729289 XC=11.400000 YC=3.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.870711 Y1=0.929289 X2=11.900000 Y2=1.000000 XC=11.800000 YC=1.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.870711 Y1=1.329289 X2=11.870711 Y2=1.470711 XC=11.800000 YC=1.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.870711 Y1=1.729289 X2=11.800000 Y2=1.900000 XC=11.800000 YC=1.800000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.870711 Y1=2.129289 X2=11.729289 Y2=2.270711 XC=11.800000 YC=2.200000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.870711 Y1=2.529289 X2=11.700000 Y2=2.600000 XC=11.800000 YC=2.600000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.870711 Y1=2.929289 X2=11.729289 Y2=2.929289 XC=11.800000 YC=3.000000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.870711 Y1=3.329289 X2=11.800000 Y2=3.300000 XC=11.800000 YC=3.400000 R=0.100000 W=0.025000 L=1) + (ARC X1=11.870711 Y1=3.729289 X2=11.870711 Y2=3.729289 XC=11.800000 YC=3.800000 R=0.100000 W=0.025000 L=1) +} +{NET=viatst + (VIA X=13 Y=1 P=roundpad) + (VIA X=13 Y=2 P=squarepad) + (VIA X=13 Y=3 P=oblongpad) + (VIA X=13 Y=4 P=nodrill) + (SEG X1=13 Y1=1 X2=13 Y2=2 W=0.1 L=1) + (SEG X1=13 Y1=2 X2=13 Y2=3 W=0.1 L=1) + (SEG X1=13 Y1=3 X2=13 Y2=4 W=0.1 L=1) +} +{NET=oldviatst + (VIA X=14 Y=1 D=0.2 L1=1 S1=ROUND S1X=0.5 S1Y=0.5) + (VIA X=14 Y=2 D=0.2 L1=1 L2=2 S1=RECT S1X=0.5 S1Y=0.5) + (VIA X=14 Y=3 D=0.2 L1=1 L2=2 S1=OBLONG S1X=0.5 S1Y=0.5) + (VIA X=14 Y=4 D=0.0 L1=1 L2=2 S1=ROUND S1X=0.5 S1Y=0.5) + (SEG X1=14 Y1=1 X2=14 Y2=2 W=0.1 L=1) + (SEG X1=14 Y1=2 X2=14 Y2=3 W=0.1 L=1) + (SEG X1=14 Y1=3 X2=14 Y2=4 W=0.1 L=1) +} +{NET=(pintst) + (PIN X=15 Y=1 R=U1.1 P=roundpad) + (PIN X=15 Y=2 R=U1.2 P=squarepad) + (PIN X=15 Y=3 R=U1.3 P=oblongpad) +} +{NET=(padtst) + (PAD X=16 Y=1 L=1 S=ROUND SX=0.5 SY=0.5) + (PAD X=16 Y=2 L=1 S=RECT SX=0.5 SY=0.5) + (PAD X=16 Y=3 L=1 S=OBLONG SX=0.5 SY=0.5) + (PAD X=17 Y=1 L=2 S=ROUND SX=0.5 SY=0.5) + (PAD X=17 Y=2 L=2 S=RECT SX=0.5 SY=0.5) + (PAD X=17 Y=3 L=2 S=OBLONG SX=0.5 SY=0.5) +} +{NET=(usegtst) + (USEG X1=18 Y1=1 L1=1 X2=19 Y2=1 L2=1 ZL=1 ZW=0.1 ZLEN=2 ) + (USEG X1=18 Y1=2 L1=1 X2=19 Y2=2 L2=1 Z=50 D=1e-12 R=5 ) + (USEG X1=18 Y1=3 L1=1 X2=19 Y2=3 L2=2 ZL=1 ZW=0.1 ZLEN=2 ) + (USEG X1=18 Y1=4 L1=1 X2=19 Y2=4 L2=2 Z=50 D=1e-12 R=5 ) +} +{NET=polylinetst + {POLYGON L=1 W=0.05 ID=1 X=5.875000 Y=4.875000) + (LINE X=6.125000 Y=4.875000) + (LINE X=6.125000 Y=5.125000) + (LINE X=5.875000 Y=5.125000) + (LINE X=5.875000 Y=4.875000) + } + {POLYLINE L=1 W=0.1 ID=1 X=6.000000 Y=5.000000 + (LINE X=8.000000 Y=5.000000) + (CURVE X1=8.000000 Y1=5.000000 X2=8.000000 Y2=5.500000 XC=8.000000 YC=5.250000 R=0.250000) + (LINE X=6.000000 Y=5.500000) + (CURVE X1=6.000000 Y1=6.000000 X2=6.000000 Y2=5.500000 XC=6.000000 YC=5.750000 R=0.250000) + (LINE X=8.000000 Y=6.000000) + (CURVE X1=8.000000 Y1=6.000000 X2=8.000000 Y2=6.500000 XC=8.000000 YC=6.250000 R=0.250000) + (LINE X=6.000000 Y=6.500000) + (CURVE X1=6.000000 Y1=7.000000 X2=6.000000 Y2=6.500000 XC=6.000000 YC=6.750000 R=0.250000) + (LINE X=8.000000 Y=7.000000) + (CURVE X1=8.000000 Y1=7.000000 X2=8.000000 Y2=7.500000 XC=8.000000 YC=7.250000 R=0.250000) + (LINE X=6.000000 Y=7.500000) + (CURVE X1=6.000000 Y1=8.000000 X2=6.000000 Y2=7.500000 XC=6.000000 YC=7.750000 R=0.250000) + (LINE X=8.000000 Y=8.000000) + (CURVE X1=8.000000 Y1=8.000000 X2=8.000000 Y2=8.500000 XC=8.000000 YC=8.250000 R=0.250000) + (LINE X=6.000000 Y=8.500000) + (CURVE X1=6.000000 Y1=9.000000 X2=6.000000 Y2=8.500000 XC=6.000000 YC=8.750000 R=0.250000) + } +} +{NET=curvetst + {POLYGON L=1 W=0.05 ID=2 X=10.000000 Y=5.500000) + (CURVE X1=10.000000 Y1=5.500000 X2=10.000000 Y2=5.500000 XC=9.500000 YC=5.500000 R=0.500000 ) + } + {POLYVOID ID=2 X=9.250000 Y=5.500000 + (CURVE X1=9.250000 Y1=5.500000 X2=9.750000 Y2=5.500000 XC=9.500000 YC=5.500000 R=0.250000 ) + (LINE X=9.250000 Y=5.500000) + } +} +{NET=linetst + {POLYGON L=1 W=0.05 ID=3 X=9.000000 Y=6.500000) + (LINE X=10.000000 Y=6.500000) + (LINE X=10.000000 Y=7.000000) + (LINE X=9.500000 Y=7.000000) + (LINE X=9.500000 Y=7.500000) + (LINE X=9.000000 Y=7.500000) + (LINE X=9.000000 Y=6.500000) + } + {POLYVOID ID=3 X=9.125000 Y=6.625000 + (LINE X=9.625000 Y=6.625000) + (LINE X=9.625000 Y=6.875000) + (LINE X=9.375000 Y=6.875000) + (LINE X=9.375000 Y=7.125000) + (LINE X=9.125000 Y=7.125000) + (LINE X=9.125000 Y=6.625000) + } +} +{NET=poly_clearance_tst PS=0.05 + (VIA X=11.750000 Y=5.250000 P=0802pad) + (VIA X=11.750000 Y=6.250000 P=0802pad) + (VIA X=11.750000 Y=7.250000 P=0802pad) + (SEG X1=11.000000 Y1=5.250000 X2=11.750000 Y2=5.250000 W=0.04 L=1) + (SEG X1=11.000000 Y1=6.250000 X2=11.750000 Y2=6.250000 W=0.04 L=1) + (SEG X1=11.000000 Y1=7.250000 X2=11.750000 Y2=7.250000 W=0.04 L=1) + (SEG X1=11.000000 Y1=5.250000 X2=11.000000 Y2=6.250000 W=0.04 L=1) + (SEG X1=11.000000 Y1=6.250000 X2=11.000000 Y2=7.250000 W=0.04 L=1) + {POLYGON L=1 T=POUR W=0.100000 ID=4 X=11.500000 Y=5.000000) + (LINE X=12.500000 Y=5.000000) + (LINE X=12.500000 Y=5.500000) + (LINE X=11.500000 Y=5.500000) + (LINE X=11.500000 Y=5.000000) + } + {POLYGON L=1 T=COPPER W=0.100000 ID=5 X=11.500000 Y=6.000000) + (LINE X=12.500000 Y=6.000000) + (LINE X=12.500000 Y=6.500000) + (LINE X=11.500000 Y=6.500000) + (LINE X=11.500000 Y=6.000000) + } + {POLYGON L=1 T=PLANE W=0.100000 ID=6 X=11.500000 Y=7.000000) + (LINE X=12.500000 Y=7.000000) + (LINE X=12.500000 Y=7.500000) + (LINE X=11.500000 Y=7.500000) + (LINE X=11.500000 Y=7.000000) + } +} +{NET=poly_clearance_tst2 PS=0.05 + (VIA X=12.250000 Y=5.250000 P=0802pad) + (VIA X=12.250000 Y=6.250000 P=0802pad) + (VIA X=12.250000 Y=7.250000 P=0802pad) + (SEG X1=13.000000 Y1=5.250000 X2=12.250000 Y2=5.250000 W=0.04 L=1) + (SEG X1=13.000000 Y1=6.250000 X2=12.250000 Y2=6.250000 W=0.04 L=1) + (SEG X1=13.000000 Y1=7.250000 X2=12.250000 Y2=7.250000 W=0.04 L=1) + (SEG X1=13.000000 Y1=5.250000 X2=13.000000 Y2=6.250000 W=0.04 L=1) + (SEG X1=13.000000 Y1=6.250000 X2=13.000000 Y2=7.250000 W=0.04 L=1) +} +{NET=nesting_poly_1 PS=0 + {POLYGON L=1 T=POUR W=0.000000 ID=7 X=14.000000 Y=5.000000) + (LINE X=16.000000 Y=5.000000) + (LINE X=16.000000 Y=7.000000) + (LINE X=14.000000 Y=7.000000) + (LINE X=14.000000 Y=5.000000) + } + {POLYVOID ID=7 X=14.250000 Y=5.250000 + (LINE X=15.750000 Y=5.250000) + (LINE X=15.750000 Y=6.750000) + (LINE X=14.250000 Y=6.750000) + (LINE X=14.250000 Y=5.250000) + } +} +{NET=nesting_poly_2 PS=0 + {POLYGON L=1 T=POUR W=0.000000 ID=8 X=14.500000 Y=5.500000) + (LINE X=15.500000 Y=5.500000) + (LINE X=15.500000 Y=6.500000) + (LINE X=14.500000 Y=6.500000) + (LINE X=14.500000 Y=5.500000) + } + {POLYVOID ID=8 X=14.750000 Y=5.750000 + (LINE X=15.250000 Y=5.750000) + (LINE X=15.250000 Y=6.250000) + (LINE X=14.750000 Y=6.250000) + (LINE X=14.750000 Y=5.750000) + } +} +{END} Index: tags/2.3.0/src_plugins/io_hyp/tests/test_read =================================================================== --- tags/2.3.0/src_plugins/io_hyp/tests/test_read (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/tests/test_read (revision 33253) @@ -0,0 +1,19 @@ +#!/bin/bash +# +# Read all hyperlynx test files and export as png. +# Run from this directory. +# ./test_read +# +OUTDIR=/tmp +for INFILE in test*/*.hyp +do + LOGFILE=${OUTDIR}/`basename ${INFILE} .hyp`.log + PNGFILE=${OUTDIR}/`basename ${INFILE} .hyp`.png + + ../../../src/pcb-rnd --gui batch <<[EOD] > ${LOGFILE} 2>&1 +LoadhypFrom(${INFILE}, debug) +Export(png, --outfile, ${PNGFILE}, --dpi, 300) +[EOD] + ls -l ${LOGFILE} ${PNGFILE} +done +#not truncated Property changes on: tags/2.3.0/src_plugins/io_hyp/tests/test_read ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/src_plugins/io_hyp/tests/test_write =================================================================== --- tags/2.3.0/src_plugins/io_hyp/tests/test_write (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/tests/test_write (revision 33253) @@ -0,0 +1,23 @@ +#!/bin/bash +# +# Read, write and readback hyperlynx file. +# Run from io_hyp/tests directory. +# ./test_write +# +OUTDIR=/tmp +INFILE=test00/test00.hyp +OUTFILE=${OUTDIR}/`basename ${INFILE} .hyp`_2.hyp +PNG1FILE=${OUTDIR}/`basename ${INFILE} .hyp`_1.png +PNG2FILE=${OUTDIR}/`basename ${INFILE} .hyp`_2.png + +../../../src/pcb-rnd --gui batch <<[EOD] >/dev/null 2>&1 +LoadhypFrom(${INFILE}) +Export(png, --outfile, ${PNG1FILE}, --dpi, 300) +SaveTo(LayoutAs, ${OUTFILE}, hyperlynx) +[EOD] +../../../src/pcb-rnd --gui batch <<[EOD] >/dev/null 2>&1 +LoadhypFrom(${OUTFILE}) +Export(png, --outfile, ${PNG2FILE}, --dpi, 300) +[EOD] +ls -l ${PNG1FILE} ${PNG2FILE} +#not truncated Property changes on: tags/2.3.0/src_plugins/io_hyp/tests/test_write ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/src_plugins/io_hyp/write.c =================================================================== --- tags/2.3.0/src_plugins/io_hyp/write.c (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/write.c (revision 33253) @@ -0,0 +1,585 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017, 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "write.h" + +#include "board.h" +#include "data.h" +#include +#include "polygon.h" +#include "obj_subc_parent.h" +#include "obj_pstk_inlines.h" +#include "src_plugins/lib_netmap/netmap.h" +#include "funchash_core.h" +#include +#include + +typedef struct hyp_wr_s { + pcb_board_t *pcb; + FILE *f; + const char *fn; + + const char *ln_top, *ln_bottom; /* "layer name" for top and bottom groups */ + char *elem_name; + size_t elem_name_len; + rnd_cardinal_t poly_id; + htpi_t pstk_cache; + htpp_t grp_names; + long pstk_cache_next; + struct { + unsigned elliptic:1; + } warn; +} hyp_wr_t; + +/* pcb-rnd y-axis points down; hyperlynx y-axis points up */ +static rnd_coord_t flip(rnd_coord_t y) +{ + return (PCB->hidlib.size_y - y); +} + +static void hyp_grp_init(hyp_wr_t *wr) +{ + htpp_init(&wr->grp_names, ptrhash, ptrkeyeq); +} + +static void hyp_grp_uninit(hyp_wr_t *wr) +{ + htpp_entry_t *e; + for (e = htpp_first(&wr->grp_names); e; e = htpp_next(&wr->grp_names, e)) + free(e->value); + htpp_uninit(&wr->grp_names); +} + +static const char *hyp_grp_name(hyp_wr_t *wr, pcb_layergrp_t *grp, const char *sugg_name) +{ + const char *name; + name = htpp_get(&wr->grp_names, grp); + if (name == NULL) { + int n, dup = 0; + name = sugg_name; + if (name == NULL) + name = grp->name; + for(n = 0; n < wr->pcb->LayerGroups.len; n++) { + pcb_layergrp_t *g = &wr->pcb->LayerGroups.grp[n]; + if ((g != grp) && (g->name != NULL) && (strcmp(g->name, name) == 0)) { + dup = 1; + break; + } + } + if (dup) + name = rnd_strdup_printf("%s___%d", name, n); + else + name = rnd_strdup(name); + htpp_set(&wr->grp_names, grp, (char *)name); + } + return name; +} + +static const char *safe_subc_name(hyp_wr_t *wr, pcb_subc_t *subc) +{ + const char *orig = subc->refdes; + char *s; + int len; + + if (orig == NULL) + return orig; + + if (strchr(orig, '.') == NULL) + return orig; + + len = strlen(orig); + if (wr->elem_name_len < len) { + wr->elem_name = realloc(wr->elem_name, len + 1); + wr->elem_name_len = len; + } + memcpy(wr->elem_name, orig, len + 1); + for (s = wr->elem_name; *s != '\0'; s++) + if (*s == '.') + *s = '_'; + + return wr->elem_name; +} + +static int write_hdr(hyp_wr_t * wr) +{ + char dt[128]; + + rnd_print_utc(dt, sizeof(dt), 0); + + fprintf(wr->f, "* %s exported by pcb-rnd " PCB_VERSION " (" PCB_REVISION ") on %s\n", wr->pcb->hidlib.filename, dt); + fprintf(wr->f, "* Board: %s\n", wr->pcb->hidlib.name); + fprintf(wr->f, "{VERSION=2.0}\n"); + fprintf(wr->f, "{DATA_MODE=DETAILED}\n"); + fprintf(wr->f, "{UNITS=METRIC LENGTH}\n"); + return 0; +} + +static int write_foot(hyp_wr_t * wr) +{ + fprintf(wr->f, "{END}\n"); + return 0; +} + +static const char *get_layer_name(hyp_wr_t * wr, pcb_parenttype_t pt, pcb_layer_t * l) +{ + rnd_layergrp_id_t gid; + pcb_layergrp_t *g; + + if (pt != PCB_PARENT_LAYER) + return NULL; + + gid = pcb_layer_get_group_(l); + if (gid < 0) + return NULL; + + g = pcb_get_layergrp(wr->pcb, gid); + return g->name; +} + +static void write_pr_line(hyp_wr_t * wr, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + rnd_fprintf(wr->f, " (PERIMETER_SEGMENT X1=%me Y1=%me X2=%me Y2=%me)\n", x1, flip(y1), x2, flip(y2)); +} + +static void hyp_pstk_init(hyp_wr_t *wr) +{ + htpi_init(&wr->pstk_cache, ptrhash, ptrkeyeq); + wr->pstk_cache_next = 1; +} + +static void hyp_pstk_uninit(hyp_wr_t *wr) +{ + htpi_uninit(&wr->pstk_cache); +} + +void hyp_pstk_shape(hyp_wr_t *wr, const char *lynam, const pcb_pstk_shape_t *shp) +{ + rnd_coord_t sx, sy, minx, miny, maxx, maxy; + int shnum = 0, n; +TODO(": this ignores rotation") + switch(shp->shape) { + case PCB_PSSH_HSHADOW: +TODO("hshadow TODO") + break; + case PCB_PSSH_CIRC: + sx = sy = shp->data.circ.dia; + shnum = 0; + break; + case PCB_PSSH_POLY: +TODO(": check if it is a rectangle") + minx = maxx = shp->data.poly.x[0]; + miny = maxy = shp->data.poly.y[0]; + for(n = 1; n < shp->data.poly.len; n++) { + if (shp->data.poly.x[n] < minx) minx = shp->data.poly.x[n]; + if (shp->data.poly.y[n] < miny) miny = shp->data.poly.y[n]; + if (shp->data.poly.x[n] > maxx) maxx = shp->data.poly.x[n]; + if (shp->data.poly.y[n] > maxy) maxy = shp->data.poly.y[n]; + } + sx = maxx - minx; + sy = maxy - miny; + shnum = 1; + break; + case PCB_PSSH_LINE: + sx = shp->data.line.x2 - shp->data.line.x1; + sy = shp->data.line.y2 - shp->data.line.y1; + if (sx < 0) sx = -sx; + if (sy < 0) sy = -sy; + if (shp->data.line.square) + shnum = 1; + else + shnum = 2; + break; + } + rnd_fprintf(wr->f, " (%s, %d, %me, %me, 0)\n", lynam, shnum, sx, sy); +} + +/* WARNING: not reentrant! */ +static const char *hyp_pstk_cache(hyp_wr_t *wr, pcb_pstk_proto_t *proto, int print) +{ + static char name[16]; + long id; + + id = htpi_get(&wr->pstk_cache, proto); + if (id == 0) { /* not found */ + if (print) { /* auto-allocate */ + id = wr->pstk_cache_next++; + htpi_set(&wr->pstk_cache, proto, id); + } + else + rnd_message(RND_MSG_ERROR, "Internal error: unknown padstack prototype\n"); + } + + sprintf(name, "proto_%ld", id); + if (print) { + pcb_pstk_tshape_t *tshp = &proto->tr.array[0]; + int n; + + if (proto->hdia > 0) + rnd_fprintf(wr->f, "{PADSTACK=%s,%me\n", name, proto->hdia); + else + fprintf(wr->f, "{PADSTACK=%s\n", name); + + for(n = 0; n < tshp->len; n++) { + pcb_pstk_shape_t *shp = &tshp->shape[n]; + pcb_layer_type_t loc; + rnd_layer_id_t l; + + if (!(shp->layer_mask & PCB_LYT_COPPER)) + continue; /* hyp suppports copper only */ + + loc = (shp->layer_mask & PCB_LYT_ANYWHERE); + for(l = 0; l < wr->pcb->LayerGroups.len; l++) { + pcb_layergrp_t *lg = &wr->pcb->LayerGroups.grp[l]; + pcb_layer_type_t lyt = lg->ltype; + if ((lyt & PCB_LYT_COPPER) && (lyt & loc)) + hyp_pstk_shape(wr, hyp_grp_name(wr, lg, NULL), shp); + } + } + + fprintf(wr->f, "}\n"); + } + return name; +} + +static void write_pstk(hyp_wr_t *wr, pcb_pstk_t *ps) +{ + pcb_subc_t *subc = pcb_gobj_parent_subc(ps->parent_type, &ps->parent); + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + + if ((subc != NULL) && (ps->term != NULL)) + rnd_fprintf(wr->f, " (PIN X=%me Y=%me R=\"%s.%s\" P=%[4])\n", ps->x, flip(ps->y), safe_subc_name(wr, subc), ps->term, hyp_pstk_cache(wr, proto, 0)); + else + rnd_fprintf(wr->f, " (VIA X=%me Y=%me P=%[4])\n", ps->x, flip(ps->y), hyp_pstk_cache(wr, proto, 0)); +} + +static void write_poly(hyp_wr_t * wr, pcb_poly_t * poly) +{ + rnd_pline_t *pl; + rnd_vnode_t *v; + + if (poly->Clipped == NULL) { + pcb_layer_t *l = poly->parent.layer; + pcb_poly_init_clip(l->parent.data, l, poly); + } + + if (poly->Clipped == NULL) + return; + + pl = poly->Clipped->contours; + do { + v = pl->head->next; + + if (pl == poly->Clipped->contours) + rnd_fprintf(wr->f, " {POLYGON L=%[4] T=POUR W=0.0 ID=%d X=%me Y=%me\n", + get_layer_name(wr, poly->parent_type, poly->parent.layer), ++wr->poly_id, v->point[0], flip(v->point[1])); + else + /* hole. Use same ID as polygon. */ + rnd_fprintf(wr->f, " {POLYVOID ID=%d X=%me Y=%me\n", wr->poly_id, v->point[0], flip(v->point[1])); + + for (v = v->next; v != pl->head->next; v = v->next) + rnd_fprintf(wr->f, " (LINE X=%me Y=%me)\n", v->point[0], flip(v->point[1])); + + v = pl->head->next; /* repeat first point */ + rnd_fprintf(wr->f, " (LINE X=%me Y=%me)\n", v->point[0], flip(v->point[1])); + + fprintf(wr->f, " }\n"); + } while ((pl = pl->next) != NULL); +} + + +static void write_line(hyp_wr_t * wr, pcb_line_t * line) +{ + rnd_fprintf(wr->f, " (SEG X1=%me Y1=%me X2=%me Y2=%me W=%me L=%[4])\n", + line->Point1.X, flip(line->Point1.Y), line->Point2.X, flip(line->Point2.Y), + line->Thickness, get_layer_name(wr, line->parent_type, line->parent.layer)); +} + +static void write_arc_(hyp_wr_t * wr, const char *cmd, pcb_arc_t * arc, const char *layer) +{ + rnd_coord_t x1, y1, x2, y2; + + if (arc->Width != arc->Height) { + if (!wr->warn.elliptic) { + rnd_message(RND_MSG_WARNING, "Elliptic arcs are not supported - omitting all elliptic arcs\n"); + wr->warn.elliptic = 1; + } + return; + } + + if ((arc->Delta >= 0) == (layer == NULL)) { + pcb_arc_get_end(arc, 0, &x1, &y1); + pcb_arc_get_end(arc, 1, &x2, &y2); + } + else { + pcb_arc_get_end(arc, 1, &x1, &y1); + pcb_arc_get_end(arc, 0, &x2, &y2); + } + + rnd_fprintf(wr->f, "(%s X1=%me Y1=%me X2=%me Y2=%me XC=%me YC=%me R=%me", cmd, x1, flip(y1), x2, flip(y2), arc->X, + flip(arc->Y), arc->Width); + if (layer != NULL) + rnd_fprintf(wr->f, " W=%me L=%[4]", arc->Thickness, layer); + fprintf(wr->f, ")\n"); +} + +static void write_pr_arc(hyp_wr_t * wr, pcb_arc_t * arc) +{ + fprintf(wr->f, " "); + write_arc_(wr, "PERIMETER_ARC", arc, NULL); +} + +static void write_arc(hyp_wr_t * wr, pcb_arc_t * arc) +{ + fprintf(wr->f, " "); + write_arc_(wr, "ARC", arc, get_layer_name(wr, arc->parent_type, arc->parent.layer)); +} + +static int write_board(hyp_wr_t * wr) +{ + int has_outline; + rnd_layergrp_id_t i; + pcb_layergrp_t *g; + + fprintf(wr->f, "{BOARD\n"); + + has_outline = pcb_has_explicit_outline(PCB); + if (!has_outline) { + /* implicit outline */ + fprintf(wr->f, "* implicit outline derived from board width and height\n"); + write_pr_line(wr, 0, 0, PCB->hidlib.size_x, 0); + write_pr_line(wr, 0, 0, 0, PCB->hidlib.size_y); + write_pr_line(wr, PCB->hidlib.size_x, 0, PCB->hidlib.size_x, PCB->hidlib.size_y); + write_pr_line(wr, 0, PCB->hidlib.size_y, PCB->hidlib.size_x, PCB->hidlib.size_y); + } + else { /* explicit outline */ + for(i = 0, g = PCB->LayerGroups.grp; i < PCB->LayerGroups.len; i++,g++) { + int n; + + if (!PCB_LAYER_IS_OUTLINE(g->ltype, g->purpi)) + continue; + + for(n = 0; n < g->len; n++) { + pcb_layer_t *l = pcb_get_layer(PCB->Data, g->lid[n]); + gdl_iterator_t it; + pcb_line_t *line; + pcb_arc_t *arc; + + if (l == NULL) + continue; + +TODO("layer: refuse negative layers and warn for objects other than line/arc") + + linelist_foreach(&l->Line, &it, line) { + write_pr_line(wr, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); + } + arclist_foreach(&l->Arc, &it, arc) { + write_pr_arc(wr, arc); + } + } + } + } + fprintf(wr->f, "}\n"); + return 0; +} + +static int write_lstack(hyp_wr_t * wr) +{ + int n; + + fprintf(wr->f, "{STACKUP\n"); + for (n = 0; n < wr->pcb->LayerGroups.len; n++) { + pcb_layergrp_t *grp = &wr->pcb->LayerGroups.grp[n]; + const char *name = grp->name; + + if (grp->ltype & PCB_LYT_COPPER) { + rnd_fprintf(wr->f, " (SIGNAL T=0.003500 L=%[4])\n", hyp_grp_name(wr, grp, name)); + if (grp->ltype & PCB_LYT_TOP) + wr->ln_top = name; + else if (grp->ltype & PCB_LYT_BOTTOM) + wr->ln_bottom = name; + } + else if (grp->ltype & PCB_LYT_SUBSTRATE) { + char tmp[128]; + if (name == NULL) { + sprintf(tmp, "dielectric layer %d", n); + name = tmp; + } + rnd_fprintf(wr->f, " (DIELECTRIC T=0.160000 L=%[4])\n", hyp_grp_name(wr, grp, name)); + } + } + + fprintf(wr->f, "}\n"); + return 0; +} + +static int write_devices(hyp_wr_t * wr) +{ + gdl_iterator_t it; + pcb_subc_t *subc; + int cnt; + + fprintf(wr->f, "{DEVICES\n"); + + cnt = 0; + subclist_foreach(&wr->pcb->Data->subc, &it, subc) { + const char *layer, *descr; + int on_bottom = 0; + + pcb_subc_get_side(subc, &on_bottom); + + if (on_bottom) + layer = wr->ln_bottom; + else + layer = wr->ln_top; + descr = subc->refdes; + if (descr == NULL) + descr = "?"; + + rnd_fprintf(wr->f, " (? REF=%[4] NAME=%[4] L=%[4])\n", safe_subc_name(wr, subc), descr, layer); + cnt++; + } + + if (cnt == 0) + rnd_message(RND_MSG_WARNING, + "There is no element on the board - this limites the use of the resulting .hyp file, as it won't be able to connect to a simulation\n"); + + fprintf(wr->f, "}\n"); + return 0; +} + +static int write_pstk_protos(hyp_wr_t *wr, pcb_data_t *data) +{ + gdl_iterator_t it; + pcb_subc_t *subc; + rnd_cardinal_t n, end; + + /* print the protos */ + end = pcb_vtpadstack_proto_len(&data->ps_protos); + for(n = 0; n < end; n++) + hyp_pstk_cache(wr, &data->ps_protos.array[n], 1); + + /* recurse on subcircuits */ + subclist_foreach(&data->subc, &it, subc) + write_pstk_protos(wr, subc->data); + + return 0; +} + +static int write_nets(hyp_wr_t * wr) +{ + htpp_entry_t *e; + pcb_netmap_t map; + + pcb_netmap_init(&map, wr->pcb, 0); + for (e = htpp_first(&map.n2o); e != NULL; e = htpp_next(&map.n2o, e)) { + dyn_obj_t *o; + pcb_net_t *net = e->key; + rnd_fprintf(wr->f, "{NET=%[4]\n", net->name); + for (o = e->value; o != NULL; o = o->next) { + switch (o->obj->type) { + case PCB_OBJ_LINE: + write_line(wr, (pcb_line_t *) o->obj); + break; + case PCB_OBJ_ARC: + write_arc(wr, (pcb_arc_t *) o->obj); + break; + case PCB_OBJ_PSTK: + write_pstk(wr, (pcb_pstk_t *) o->obj); + break; + + case PCB_OBJ_POLY: + write_poly(wr, (pcb_poly_t *) o->obj); + break; + + case PCB_OBJ_RAT: + break; /* not yet done */ + + case PCB_OBJ_TEXT: + case PCB_OBJ_SUBC: + case PCB_OBJ_NET: + case PCB_OBJ_NET_TERM: + case PCB_OBJ_LAYER: + case PCB_OBJ_LAYERGRP: + case PCB_OBJ_VOID: + case PCB_OBJ_GFX: + break; /* silently ignore these */ + } + } + fprintf(wr->f, "}\n"); + } + + pcb_netmap_uninit(&map); + return 0; +} + +int io_hyp_write_pcb(pcb_plug_io_t * ctx, FILE * f, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + hyp_wr_t wr; + + memset(&wr, 0, sizeof(wr)); + wr.pcb = PCB; + wr.f = f; + wr.fn = new_filename; + + hyp_pstk_init(&wr); + hyp_grp_init(&wr); + + rnd_printf_slot[4] = "%{{\\}\\()\t\r\n \"=}mq"; + + if (write_hdr(&wr) != 0) + goto err; + + if (write_board(&wr) != 0) + goto err; + + if (write_lstack(&wr) != 0) + goto err; + + if (write_devices(&wr) != 0) + goto err; + + if (write_pstk_protos(&wr, wr.pcb->Data) != 0) + goto err; + + if (write_nets(&wr) != 0) + goto err; + + if (write_foot(&wr) != 0) + goto err; + + hyp_pstk_uninit(&wr); + hyp_grp_uninit(&wr); + free(wr.elem_name); + return 0; + +err:; + hyp_pstk_uninit(&wr); + hyp_grp_uninit(&wr); + free(wr.elem_name); + return -1; +} Index: tags/2.3.0/src_plugins/io_hyp/write.h =================================================================== --- tags/2.3.0/src_plugins/io_hyp/write.h (nonexistent) +++ tags/2.3.0/src_plugins/io_hyp/write.h (revision 33253) @@ -0,0 +1,5 @@ +#include +#include +#include "plug_io.h" + +int io_hyp_write_pcb(pcb_plug_io_t * ctx, FILE * f, const char *old_filename, const char *new_filename, rnd_bool emergency); Index: tags/2.3.0/src_plugins/io_kicad/Makefile =================================================================== --- tags/2.3.0/src_plugins/io_kicad/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_io_kicad + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/io_kicad/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/io_kicad/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/Plug.tmpasm (revision 33253) @@ -0,0 +1,19 @@ +put /local/pcb/mod {io_kicad} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/io_kicad/io_kicad.o + $(PLUGDIR)/io_kicad/layertab.o + $(PLUGDIR)/io_kicad/write.o + $(PLUGDIR)/io_kicad/read.o + $(PLUGDIR)/io_kicad/read_net.o + $(PLUGDIR)/io_kicad/uniq_name.o +@] +#put /local/pcb/mod/YACC {$(PLUGDIR)/io_kicad/parse_y} +#put /local/pcb/mod/LEX {$(PLUGDIR)/io_kicad/parse_l} +put /local/pcb/mod/MENUFILE {kicad-menu.lht} +put /local/pcb/mod/MENUVAR {kicad_menu} + +switch /local/pcb/io_kicad/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/io_kicad/TODO =================================================================== --- tags/2.3.0/src_plugins/io_kicad/TODO (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/TODO (revision 33253) @@ -0,0 +1,5 @@ +Must fix: +- do not silenlty accept input that could not be handled; the goal is not to open huge complex boards and load only 30% of them but to open boards that we can load almost 100% of + +Features: + parse the netlist Index: tags/2.3.0/src_plugins/io_kicad/hacking.txt =================================================================== --- tags/2.3.0/src_plugins/io_kicad/hacking.txt (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/hacking.txt (revision 33253) @@ -0,0 +1,87 @@ +Parser +~~~~~~ +io_kicad_read_pcb() is the main entry point for parsing a board. It loads +the s-expression from the file and using gensexpr it parses it into a +DOM (Document Object Model). Each node of the DOM is a gsxl_node_t, which +has an ->str field for the text data of the node, a ->parent field pointing +to the parent node, a ->children field pointing to the first child node and +a ->next field pointing to the next sibling node (with the same parent). + +An expression like this: + (general + (links 0) + (no_connects 0) + (area 1 2 3 4) + ... + ) + +becomes a subtree like this (levels of the tree is represented by +indentation): + + general + links + 0 + no_connects + 0 + area + 1 + 2 + 3 + 4 + ... + +So that general's ->children is links; links' ->next is no_connects; +no_connects' ->next is area; area's ->next is NULL. In the kicad +parser the terminology is that the root of a subtree is the _command_ +and its children are its _arguments_. E.g. when processing the +area node, the command is "area" it's arguments are "1", "2", "3" and "4"; +when processing the "general" subtree, "area" is the 2nd argument (arguments +are counted from 0). + +Once the tree is built in memory, a recursive tree walk is started by +calling kicad_parse_pcb() on the root of the tree. This function should +evaluate the children of the root node and call the corresponding subtree +processor on each. All parser function should be passed the context: +read_state_t *st. The context holds all relevant information about the +session so we can avoid global variables (or static local variables) and +can keep the code reentrant. + +Subtree processors have unified prototype: they get the context and the +node pointer to the 0th argument of the command: + +static int kicad_parse_something(read_state_t *st, gsxl_node_t *args) + +If a subtree processor returns non-zero, the parsing shall stop and the +caller function shall return non-zero immediately. This way we can undo +the recursion and cancel parsing. + +There are two kind of subtree processors: static and dynamic. A static +subtree processor expects a specific subtree of arguments. This means both +the number and the exact order(!) of the subtrees are fixed. The processor +for the "links" node in the above example has a static subtree processor +because "links" will always have only one argument. Since there is a +fixed amount of arguments, a static subtree processor uses the args->next +or args->next->next or args->next->next->next, etc for accessing the 0th, +1st or 2nd, etc arguments, respectively. + +A dynamic subtree processor has an unknown amount of arguments but the +set of possible arguments are known - just their order and number are +not. For example a "module" is a dynamic subtree because it may have 0 or +more fp_line, pad, etc. children. A dynamic subtree processor needs to +iterate through all its arguments using a loop; for each argument it needs +to look at the ->str field of the argument to decide how to process +that subtree (e.g. if it's an "fp_line" or a "pad"). + +To ease this, function kicad_foreach_dispatch() is provided. It iterates +over all the ->next fields of its "tree" argument and calls a function +for them according to a dispatcher table passed. The dispatcher table has +2 columns, node-name and function-to-call. kicad_parse_pcb() demonstrates +how to set up a table. If the node "general" in the above example +is to be processed this way, general's ->children is passed as tree to +the kicad_foreach_dispatch, with a table that has a function for at least +links, no_connects and area. Those functions will get links' ->children, +no_connects' ->children and area's ->children as args respectively. + + +How to batch-test the loader: +echo 'LoadFrom(Layout, foo.kicad_pcb, kicad)' | ./pcb-rnd --gui batch Index: tags/2.3.0/src_plugins/io_kicad/io_kicad.c =================================================================== --- tags/2.3.0/src_plugins/io_kicad/io_kicad.c (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/io_kicad.c (revision 33253) @@ -0,0 +1,108 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This module, io_kicad, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include "plug_io.h" +#include "write.h" +#include "read.h" +#include "read_net.h" +#include + +#include "menu_internal.c" + +static pcb_plug_io_t io_kicad; +static const char *kicad_cookie = "kicad plugin"; + +int io_kicad_fmt(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, int wr, const char *fmt) +{ + if (strcmp(ctx->description, fmt) == 0) + return 200; + + if ((strcmp(fmt, "kicad") != 0) || + ((typ & (~(PCB_IOT_FOOTPRINT | PCB_IOT_BUFFER | PCB_IOT_PCB))) != 0)) + return 0; + + return 100; +} + +rnd_action_t eeschema_action_list[] = { + {"LoadEeschemaFrom", pcb_act_LoadeeschemaFrom, pcb_acth_LoadeeschemaFrom, pcb_acts_LoadeeschemaFrom} +}; + +int pplg_check_ver_io_kicad(int ver_needed) { return 0; } + +void pplg_uninit_io_kicad(void) +{ + /* Runs once when the plugin is unloaded. TODO: free plugin-globals here. */ + rnd_remove_actions_by_cookie(kicad_cookie); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_kicad); + pcb_eeschema_uninit(); + rnd_hid_menu_unload(rnd_gui, kicad_cookie); +} + +int pplg_init_io_kicad(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + io_kicad.plugin_data = NULL; + io_kicad.fmt_support_prio = io_kicad_fmt; + io_kicad.test_parse = io_kicad_test_parse; + io_kicad.parse_pcb = io_kicad_read_pcb; + io_kicad.parse_footprint = io_kicad_parse_module; + io_kicad.map_footprint = io_kicad_map_footprint; + io_kicad.parse_font = NULL; + io_kicad.write_buffer = NULL; + io_kicad.write_subcs_head = io_kicad_write_subcs_head; + io_kicad.write_subcs_subc = io_kicad_write_subcs_subc; + io_kicad.write_subcs_tail = io_kicad_write_subcs_tail; + io_kicad.write_pcb = io_kicad_write_pcb; + io_kicad.default_fmt = "kicad"; + io_kicad.description = "Kicad, s-expression"; + io_kicad.save_preference_prio = 80; + io_kicad.default_extension = ".kicad_pcb"; + io_kicad.fp_extension = ".kicad_mod"; + io_kicad.mime_type = "application/x-kicad-pcb"; + + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_kicad); + + RND_REGISTER_ACTIONS(eeschema_action_list, kicad_cookie); + + pcb_eeschema_init(); + + rnd_hid_menu_load(rnd_gui, NULL, kicad_cookie, 190, NULL, 0, kicad_menu, "plugin: io_kicad"); + + /* TODO: Alloc plugin-globals here. */ + + return 0; +} + Index: tags/2.3.0/src_plugins/io_kicad/io_kicad.pup =================================================================== --- tags/2.3.0/src_plugins/io_kicad/io_kicad.pup (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/io_kicad.pup (revision 33253) @@ -0,0 +1,17 @@ +$class io +$short Kicad's s-expr format +$long Load and save the design and footprints in Kicad's s-expression format - this is the new, currently preferred format in Kicad. +$state works +$fmt-native no +$fmt-feature-r kicad board, version 3, 4 and 5 (s-expr) +$fmt-feature-w kicad board, version 3 (s-expr) +$fmt-feature-w kicad module (s-expr, according to version 3) +$fmt-feature-r eeschema netlist and footprint info +$package io-alien +default buildin + +dep lib_gensexpr +dep lib_compat_help +dep shape + +autoload 1 Index: tags/2.3.0/src_plugins/io_kicad/kicad-menu.lht =================================================================== --- tags/2.3.0/src_plugins/io_kicad/kicad-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/kicad-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_sch { + li:submenu { + ha:Import KiCad/eeschema schematics = { action=LoadEeschemaFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/io_kicad/layertab.c =================================================================== --- tags/2.3.0/src_plugins/io_kicad/layertab.c (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/layertab.c (revision 33253) @@ -0,0 +1,117 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * kicad IO plugin - load/save in KiCad format + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "layertab.h" + +/* shorthand lyc for silk, mask and paste (pcb-rnd side feature) */ +#define LYS (PCB_LYC_AUTO) +#define LYM (PCB_LYC_AUTO | PCB_LYC_SUB) +#define LYP (PCB_LYC_AUTO) + +const kicad_layertab_t kicad_layertab[] = { + /*id prefix plen score | action lyc purp layer-type */ + { 1, "B.Adhes", 0, 3, LYACT_NEW_MISC, 0, "adhes", PCB_LYT_MECH | PCB_LYT_BOTTOM, 1}, + { 0, "B.Adhes", 0, 2, LYACT_NEW_MISC, 0, "adhes", PCB_LYT_MECH | PCB_LYT_BOTTOM, 0}, + { 1, NULL, 0, 1, LYACT_NEW_MISC, 0, "adhes", PCB_LYT_MECH | PCB_LYT_BOTTOM, 0}, + + { 2, "F.Adhes", 0, 3, LYACT_NEW_MISC, 0, "adhes", PCB_LYT_MECH | PCB_LYT_TOP, 1}, + { 0, "F.Adhes", 0, 2, LYACT_NEW_MISC, 0, "adhes", PCB_LYT_MECH | PCB_LYT_TOP, 0}, + { 2, NULL, 0, 1, LYACT_NEW_MISC, 0, "adhes", PCB_LYT_MECH | PCB_LYT_TOP, 0}, + + { 3, "B.Paste", 0, 3, LYACT_EXISTING, LYP, NULL, PCB_LYT_PASTE | PCB_LYT_BOTTOM, 1}, + { 0, "B.Paste", 0, 2, LYACT_EXISTING, LYP, NULL, PCB_LYT_PASTE | PCB_LYT_BOTTOM, 0}, + { 3, NULL, 0, 1, LYACT_EXISTING, LYP, NULL, PCB_LYT_PASTE | PCB_LYT_BOTTOM, 0}, + + { 4, "F.Paste", 0, 3, LYACT_EXISTING, LYP, NULL, PCB_LYT_PASTE | PCB_LYT_TOP, 1}, + { 0, "F.Paste", 0, 2, LYACT_EXISTING, LYP, NULL, PCB_LYT_PASTE | PCB_LYT_TOP, 0}, + { 4, NULL, 0, 1, LYACT_EXISTING, LYP, NULL, PCB_LYT_PASTE | PCB_LYT_TOP, 0}, + + { 5, "B.SilkS", 0, 3, LYACT_EXISTING, LYS, NULL, PCB_LYT_SILK | PCB_LYT_BOTTOM, 1}, + { 0, "B.SilkS", 0, 2, LYACT_EXISTING, LYS, NULL, PCB_LYT_SILK | PCB_LYT_BOTTOM, 0}, + { 5, NULL, 0, 1, LYACT_EXISTING, LYS, NULL, PCB_LYT_SILK | PCB_LYT_BOTTOM, 0}, + + { 6, "F.SilkS", 0, 3, LYACT_EXISTING, LYS, NULL, PCB_LYT_SILK | PCB_LYT_TOP, 1}, + { 0, "F.SilkS", 0, 2, LYACT_EXISTING, LYS, NULL, PCB_LYT_SILK | PCB_LYT_TOP, 0}, + { 6, NULL, 0, 1, LYACT_EXISTING, LYS, NULL, PCB_LYT_SILK | PCB_LYT_TOP, 0}, + + { 7, "B.Mask", 0, 3, LYACT_EXISTING, LYM, NULL, PCB_LYT_MASK | PCB_LYT_BOTTOM, 1}, + { 0, "B.Mask", 0, 2, LYACT_EXISTING, LYM, NULL, PCB_LYT_MASK | PCB_LYT_BOTTOM, 0}, + { 7, NULL, 0, 1, LYACT_EXISTING, LYM, NULL, PCB_LYT_MASK | PCB_LYT_BOTTOM, 0}, + + { 8, "F.Mask", 0, 3, LYACT_EXISTING, LYM, NULL, PCB_LYT_MASK | PCB_LYT_TOP, 1}, + { 0, "F.Mask", 0, 2, LYACT_EXISTING, LYM, NULL, PCB_LYT_MASK | PCB_LYT_TOP, 0}, + { 8, NULL, 0, 1, LYACT_EXISTING, LYM, NULL, PCB_LYT_MASK | PCB_LYT_TOP, 0}, + + { 9, "Dwgs.", 5, 3, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 1}, + { 0, "Dwgs.", 5, 2, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 0}, + { 9, NULL, 0, 1, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 0}, + + {10, "Cmts.", 5, 3, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 1}, + {00, "Cmts.", 5, 2, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 0}, + {10, NULL, 0, 1, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 0}, + + {11, "Eco", 3, 3, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 1}, + {12, "Eco", 3, 3, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 0}, + {00, "Eco", 3, 2, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 0}, + {11, NULL, 0, 1, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 0}, + {12, NULL, 0, 1, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 0}, + + {13, "Edge.Cuts", 0, 5, LYACT_NEW_OUTLINE, 0, "uroute", 0, 1}, + {00, "Edge.Cuts", 0, 4, LYACT_NEW_OUTLINE, 0, "uroute", 0, 0}, + {13, "Edge.", 5, 3, LYACT_NEW_OUTLINE, 0, "uroute", 0, 0}, + {00, "Edge.", 5, 2, LYACT_NEW_OUTLINE, 0, "uroute", 0, 0}, + {13, NULL, 0, 1, LYACT_NEW_OUTLINE, 0, "uroute", 0, 0}, + + {14, "Margin", 0, 3, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 1}, + {00, "Margin", 0, 2, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 0}, + {14, NULL, 0, 1, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC, 0}, + + {15, "B.CrtYd", 0, 3, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_BOTTOM, 1}, + {00, "B.CrtYd", 0, 2, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_BOTTOM, 0}, + {15, NULL, 0, 1, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_BOTTOM, 0}, + + {16, "F.CrtYd", 0, 3, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_TOP, 1}, + {00, "F.CrtYd", 0, 2, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_TOP, 0}, + {16, NULL, 0, 1, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_TOP, 0}, + + {17, "B.Fab", 0, 3, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_BOTTOM, 1}, + {00, "B.Fab", 0, 2, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_BOTTOM, 0}, + {17, NULL, 0, 1, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_BOTTOM, 0}, + + {18, "F.Fab", 0, 3, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_TOP, 1}, + {00, "F.Fab", 0, 2, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_TOP, 0}, + {18, NULL, 0, 1, LYACT_NEW_MISC, 0, NULL, PCB_LYT_DOC | PCB_LYT_TOP, 0}, + + {0, NULL, 0, 0, 0, 0, NULL, 0, 0} /* terminator: score = 0 */ +}; + +#undef LYM +#undef LYS +#undef LYP Index: tags/2.3.0/src_plugins/io_kicad/layertab.h =================================================================== --- tags/2.3.0/src_plugins/io_kicad/layertab.h (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/layertab.h (revision 33253) @@ -0,0 +1,56 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * kicad IO plugin - load/save in KiCad format + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* A pattern matching/scoring table for pairing up rather fixed KiCad layers + with dynamic pcb-rnd layer types */ + +#include "layer.h" + +typedef struct { + /* match */ + int id; /* if not 0, layer last_copper+lnum must match this value */ + char *prefix; /* when non-NULL: layer name prefix must match on prefix_len length */ + int prefix_len; /* 0 means full string match */ + int score; /* match score - the higher the more chance this rule is used */ + + /* action */ + enum { + LYACT_EXISTING, /* create a new layer in an existing group */ + LYACT_NEW_MISC, /* create a new misc group */ + LYACT_NEW_OUTLINE /* create a new outline group */ + } action; + + pcb_layer_combining_t lyc; /* layer combination (compositing) flags */ + const char *purpose; /* may be NULL */ + pcb_layer_type_t type; /* for selecting/creating the group */ + + int auto_create; /* if automatic layer creation is necessary, use this line for a layer; when 1, prefix must be a full name */ +} kicad_layertab_t; + +extern const kicad_layertab_t kicad_layertab[]; + Index: tags/2.3.0/src_plugins/io_kicad/read.c =================================================================== --- tags/2.3.0/src_plugins/io_kicad/read.c (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/read.c (revision 33253) @@ -0,0 +1,2880 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016..2019 Tibor 'Igor2' Palinkas + * Copyright (C) 2016, 2017 Erich S. Heinzle + * Copyright (C) 2017 Miloh + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "board.h" +#include "plug_io.h" +#include +#include "data.h" +#include "read.h" +#include "layer.h" +#include "polygon.h" +#include "plug_footprint.h" +#include /* for distance calculations */ +#include "conf_core.h" +#include "move.h" +#include "rotate.h" +#include +#include "attrib.h" +#include "netlist.h" +#include +#include "obj_pstk_inlines.h" + +#include "../src_plugins/lib_compat_help/pstk_compat.h" +#include "../src_plugins/lib_compat_help/pstk_help.h" +#include "../src_plugins/lib_compat_help/subc_help.h" +#include "../src_plugins/lib_compat_help/media.h" +#include "../src_plugins/shape/shape.h" + +#include "layertab.h" + +/* a reasonable approximation of pcb glyph width, ~= 5000 centimils; in mm */ +#define GLYPH_WIDTH (1.27) + +/* If we are reading a pcb, use st->pcb, else we are reading a footprint and + use global PCB */ +#define PCB_FOR_FP (st->pcb == NULL ? PCB : st->pcb) + +/* when a coord value is not specified in the file */ +#define UNSPECIFIED RND_MAX_COORD + +typedef enum { + DIM_PAGE, + DIM_AREA, + DIM_FALLBACK, + DIM_max +} kicad_dim_prio_t; + +/* delayed zone connect */ +typedef struct zone_connect_s zone_connect_t; +struct zone_connect_s { + pcb_pstk_t *ps; + const char *netname; + int style; + zone_connect_t *next; +}; + +typedef struct { + pcb_board_t *pcb; + pcb_data_t *fp_data; + const char *Filename; + rnd_conf_role_t settings_dest; + gsxl_dom_t dom; + unsigned auto_layers:1; + unsigned module_pre_create:1; + htsi_t layer_k2i; /* layer name-to-index hash; name is the kicad name, index is the pcb-rnd layer index */ + long ver; + vtp0_t intern_copper; /* temporary storage of internal copper layers */ + double subc_rot; /* for padstacks know the final parent subc rotation in advance to compensate (this depends on the fact that the rotation appears earlier in the file than any pad) */ + pcb_subc_t *last_sc; + const char *primitive_term; /* for gr_ objects: if not NULL, set the term attribute */ + pcb_layer_t *primitive_ly; /* for gr_ objects: if not NULL, use this layer and expect no layer specified in the file */ + pcb_subc_t *primitive_subc; /* for gr_ objects: if not NULL, object is being added under this subc (apply offs) */ + + rnd_coord_t width[DIM_max]; + rnd_coord_t height[DIM_max]; + rnd_coord_t dim_valid[DIM_max]; + + /* setup */ + rnd_coord_t pad_to_mask_clearance; + rnd_coord_t zone_clearance; + + /* delayed actions */ + zone_connect_t *zc_head; + htpp_t poly2net; + unsigned poly2net_inited:1; +} read_state_t; + +typedef struct { + const char *node_name; + int (*parser) (read_state_t *st, gsxl_node_t *subtree); +} dispatch_t; + +typedef struct { + const char *node_name; + int offset; + enum { + KICAD_COORD, + KICAD_DOUBLE + } type; +} autoload_t; + +static int kicad_error(gsxl_node_t *subtree, char *fmt, ...) +{ + gds_t str; + va_list ap; + + gds_init(&str); + rnd_append_printf(&str, "io_kicad parse error at %d.%d: ", subtree->line, subtree->col); + + va_start(ap, fmt); + rnd_safe_append_vprintf(&str, 0, fmt, ap); + va_end(ap); + + gds_append(&str, '\n'); + + rnd_message(RND_MSG_ERROR, "%s", str.array); + + gds_uninit(&str); + return -1; +} + +static int kicad_warning(gsxl_node_t *subtree, char *fmt, ...) +{ + gds_t str; + va_list ap; + + gds_init(&str); + rnd_append_printf(&str, "io_kicad warning at %d.%d: ", subtree->line, subtree->col); + + va_start(ap, fmt); + rnd_safe_append_vprintf(&str, 0, fmt, ap); + va_end(ap); + + gds_append(&str, '\n'); + + rnd_message(RND_MSG_WARNING, "%s", str.array); + + gds_uninit(&str); + return 0; +} + + + +/* Search the dispatcher table for subtree->str, execute the parser on match + with the children ("parameters") of the subtree */ +static int kicad_dispatch(read_state_t *st, gsxl_node_t *subtree, const dispatch_t *disp_table) +{ + const dispatch_t *d; + + /* do not tolerate empty/NIL node */ + if (subtree->str == NULL) + return kicad_error(subtree, "unexpected empty/NIL subtree"); + + for(d = disp_table; d->node_name != NULL; d++) + if (strcmp(d->node_name, subtree->str) == 0) + return d->parser(st, subtree->children); + + /* node name not found in the dispatcher table */ + return kicad_error(subtree, "Unknown node: '%s'", subtree->str); +} + +/* Take each children of tree and execute them using kicad_dispatch + Useful for procssing nodes that may host various subtrees of different + nodes ina flexible way. Return non-zero if any subtree processor failed. */ +static int kicad_foreach_dispatch(read_state_t *st, gsxl_node_t *tree, const dispatch_t *disp_table) +{ + gsxl_node_t *n; + + for(n = tree; n != NULL; n = n->next) + if (kicad_dispatch(st, n, disp_table) != 0) + return -1; + + return 0; /* success */ +} + +/* No-op: ignore the subtree */ +static int kicad_parse_nop(read_state_t *st, gsxl_node_t *subtree) +{ + return 0; +} + +/* kicad_pcb/version */ +static int kicad_parse_version(read_state_t *st, gsxl_node_t *subtree) +{ + if (subtree->str != NULL) { + char *end; + st->ver = strtol(subtree->str, &end, 10); + if (*end != '\0') + return kicad_error(subtree, "unexpected layout version syntax (perhaps too new, please file a feature request!)"); + if ((st->ver == 3) || (st->ver == 4)) + return 0; + if ((st->ver > 20170000L) && (st->ver < 20180000L)) /* kicad 5 */ + return 0; + } + return kicad_error(subtree, "unexpected layout version number (perhaps too new, please file a feature request!)"); +} + + +static int kicad_create_copper_layer_(read_state_t *st, rnd_layergrp_id_t gid, const char *lname, const char *ltype, gsxl_node_t *subtree) +{ + rnd_layer_id_t id; + id = pcb_layer_create(st->pcb, gid, lname, 0); + htsi_set(&st->layer_k2i, rnd_strdup(lname), id); + if (ltype != NULL) { + pcb_layer_t *ly = pcb_get_layer(st->pcb->Data, id); + pcb_attribute_put(&ly->Attributes, "kicad::type", ltype); + } + return 0; +} + +static int kicad_create_copper_layer(read_state_t *st, int lnum, const char *lname, const char *ltype, gsxl_node_t *subtree, int last_copper) +{ + rnd_layergrp_id_t gid = -1; + const char *cu; + + pcb_layer_type_t loc = PCB_LYT_INTERN; + + cu = lname + strlen(lname) - 3; + if (strcmp(cu, ".Cu") != 0) { + if (st->ver < 4) { + if ((strcmp(lname, "Front") != 0) && (strcmp(lname, "Back") != 0)) + kicad_warning(subtree, "layer %d: unusual name for front/back copper (recoverable error)\n", lnum); + } + else + kicad_warning(subtree, "layer %d name should end in .Cu because it is a copper layer (recoverable error)\n", lnum); + } + + if ((lnum == 0) || (lnum == last_copper)) { /* top or bottom - order depends on file version */ + if (st->ver > 3) { + if ((lnum == 0) && (lname[0] != 'F')) + kicad_warning(subtree, "layer 0 should be named F.Cu (recoverable error; new stack)\n"); + if ((lnum == last_copper) && (lname[0] != 'B')) + kicad_warning(subtree, "layer %d should be named B.Cu (recoverable error; new stack)\n", last_copper); + } + else { + if ((lnum == 0) && (lname[0] != 'B')) + kicad_warning(subtree, "layer 0 should be named B.Cu (recoverable error; old stack)\n"); + if ((lnum == last_copper) && (lname[0] != 'F')) + kicad_warning(subtree, "layer %d should be named F.Cu (recoverable error; old stack)\n", last_copper); + } + } + + if (st->ver > 3) { + if (lnum == 0) loc = PCB_LYT_TOP; + else if (lnum == last_copper) loc = PCB_LYT_BOTTOM; + } + else { + if (lnum == 0) loc = PCB_LYT_BOTTOM; + else if (lnum == last_copper) loc = PCB_LYT_TOP; + } + + if (loc & PCB_LYT_INTERN) { + /* for intern copper layers we need to have an array and delay + creation to order them correctly by layer number even if + their are listed in a different order in the file */ + vtp0_set(&st->intern_copper, lnum, subtree); + return 0; + } + + pcb_layergrp_list(st->pcb, PCB_LYT_COPPER | loc, &gid, 1); + return kicad_create_copper_layer_(st, gid, lname, ltype, subtree); +} + + +static int kicad_create_misc_layer(read_state_t *st, int lnum, const char *lname, const char *ltype, gsxl_node_t *subtree, int last_copper) +{ + rnd_layergrp_id_t gid; + rnd_layer_id_t lid = -1; + pcb_layergrp_t *grp, *new_grp = NULL; + pcb_layer_t *ly; + const kicad_layertab_t *lt, *best = NULL; + int adj_lnum = lnum - last_copper; + + /* find the best match */ + for(lt = kicad_layertab; lt->score != 0; lt++) { + /* optimization: if we already have a match, ignore weaker candidates */ + if ((best != NULL) && (lt->score <= best->score)) + continue; + + if ((lt->id != 0) && (lt->id != adj_lnum)) + continue; + + if (lt->prefix != NULL) { + if (lt->prefix_len == 0) { /* full length name match */ + if (strcmp(lt->prefix, lname) != 0) + continue; + } + else { /* prefix name match */ + if (strncmp(lt->prefix, lname, lt->prefix_len) != 0) + continue; + } + } + + /* match; because of the first check, lt is guaranteed to have higher + score than best */ + best = lt; + } + + if (best == NULL) { + kicad_warning(subtree, "unknown layer: %d %s %s\n", lnum, lname, ltype); + remember_bad:; /* HACK/WORKAROUND: remember kicad layers for those that are unsupported */ + htsi_set(&st->layer_k2i, rnd_strdup(lname), -lnum); + return 0; + } + + /* create the best layer by executing its actions */ + switch(best->action) { + case LYACT_EXISTING: + gid = -1; + pcb_layergrp_list(st->pcb, best->type, &gid, 1); + lid = pcb_layer_create(st->pcb, gid, lname, 0); + new_grp = NULL; + break; + + case LYACT_NEW_MISC: + grp = pcb_get_grp_new_misc(st->pcb); + grp->name = rnd_strdup(lname); + grp->ltype = best->type; + lid = pcb_layer_create(st->pcb, grp - st->pcb->LayerGroups.grp, lname, 0); + new_grp = grp; + break; + + case LYACT_NEW_OUTLINE: + grp = pcb_get_grp_new_intern(PCB, -1); + pcb_layergrp_fix_turn_to_outline(grp); + lid = pcb_layer_create(st->pcb, grp - st->pcb->LayerGroups.grp, lname, 0); + new_grp = grp; + break; + } + + if (lid == -1) { + kicad_warning(subtree, "internal error creating layer: %d %s %s\n", lnum, lname, ltype); + goto remember_bad; + } + + ly = pcb_get_layer(st->pcb->Data, lid); + ly->comb |= best->lyc; + + if ((new_grp != NULL) && (best->purpose != NULL)) + new_grp->purpose = rnd_strdup(best->purpose); + + htsi_set(&st->layer_k2i, rnd_strdup(lname), lid); + return 0; +} + + +/* Parse a layer definition and do all the administration needed for the layer */ +static int kicad_create_layer(read_state_t *st, int lnum, const char *lname, const char *ltype, gsxl_node_t *subtree, int last_copper) +{ + if (lnum <= last_copper) + return kicad_create_copper_layer(st, lnum, lname, ltype, subtree, last_copper); + return kicad_create_misc_layer(st, lnum, lname, ltype, subtree, last_copper); +} + +/* Register a kicad layer in the layer hash after looking up the pcb-rnd equivalent */ +static unsigned int kicad_reg_layer(read_state_t *st, const char *kicad_name, unsigned int mask, const char *purpose) +{ + rnd_layer_id_t id; + if (st->pcb != NULL) { + if (pcb_layer_listp(st->pcb, mask, &id, 1, -1, purpose) != 1) { + rnd_layergrp_id_t gid; + pcb_layergrp_listp(PCB, mask, &gid, 1, -1, purpose); + id = pcb_layer_create(st->pcb, gid, kicad_name, 0); + } + } + else { + /* registering a new layer in buffer */ + pcb_layer_t *ly = pcb_layer_new_bound(st->fp_data, mask, kicad_name, purpose); + id = ly - st->fp_data->Layer; + if (mask & PCB_LYT_MASK) + ly->comb |= PCB_LYC_SUB; + } + htsi_set(&st->layer_k2i, rnd_strdup(kicad_name), id); + return 0; +} + +static int kicad_get_layeridx_auto(read_state_t *st, const char *kicad_name); + +/* Returns the pcb-rnd layer index for a kicad_name, or -1 if not found */ +static int kicad_get_layeridx(read_state_t *st, const char *kicad_name) +{ + htsi_entry_t *e; + e = htsi_getentry(&st->layer_k2i, kicad_name); + if (e == NULL) { + if ((kicad_name[0] == 'I') && (kicad_name[1] == 'n')) { + /* Workaround: specal case InX.Cu, where X is an integer */ + char *end; + long id = strtol(kicad_name + 2, &end, 10); + if ((rnd_strcasecmp(end, ".Cu") == 0) && (id >= 1) && (id <= 30)) { + if (kicad_reg_layer(st, kicad_name, PCB_LYT_COPPER | PCB_LYT_INTERN, NULL) == 0) + return kicad_get_layeridx(st, kicad_name); + } + } + if (st->auto_layers) + return kicad_get_layeridx_auto(st, kicad_name); + return -1; + } + return e->value; +} + +static int kicad_get_layeridx_auto(read_state_t *st, const char *kicad_name) +{ + pcb_layer_type_t lyt = 0; + const char *purpose = NULL; + + if ((kicad_name[0] == 'F') && (kicad_name[1] == '.')) lyt |= PCB_LYT_TOP; + else if ((kicad_name[0] == 'B') && (kicad_name[1] == '.')) lyt |= PCB_LYT_BOTTOM; + else if ((kicad_name[0] == 'I') && (kicad_name[1] == 'n')) lyt |= PCB_LYT_INTERN; + + TODO("for In, also remember the offset"); + + TODO("this should use the layertab instead"); + if (rnd_strcasecmp(kicad_name, "Edge.Cuts") == 0) { lyt |= PCB_LYT_BOUNDARY; purpose = "uroute"; } + else if (kicad_name[1] == '.') { + const char *ln = kicad_name + 2; + if (rnd_strcasecmp(ln, "SilkS") == 0) lyt |= PCB_LYT_SILK; + else if (rnd_strcasecmp(ln, "Mask") == 0) lyt |= PCB_LYT_MASK; + else if (rnd_strcasecmp(ln, "Paste") == 0) lyt |= PCB_LYT_PASTE; + else if (rnd_strcasecmp(ln, "Cu") == 0) lyt |= PCB_LYT_COPPER; + else lyt |= PCB_LYT_VIRTUAL; + } + else lyt |= PCB_LYT_VIRTUAL; + + if (kicad_reg_layer(st, kicad_name, lyt, purpose) == 0) + return kicad_get_layeridx(st, kicad_name); + return -1; +} + +static void kicad_create_fp_layers(read_state_t *st, gsxl_node_t *subtree) +{ + const kicad_layertab_t *l; + pcb_layergrp_t *g; + int last_copper = 15; + + pcb_layergrp_inhibit_inc(); + pcb_layer_group_setup_default(st->pcb); + + /* one intern copper */ + g = pcb_get_grp_new_intern(st->pcb, -1); + pcb_layer_create(st->pcb, g - st->pcb->LayerGroups.grp, "Inner1.Cu", 0); + + kicad_create_layer(st, 0, "F.Cu", "signal", subtree, last_copper); + kicad_create_layer(st, 1, "Inner1.Cu", "signal", subtree, last_copper); + kicad_create_layer(st, last_copper, "B.Cu", "signal", subtree, last_copper); + + for(l = kicad_layertab; l->score != 0; l++) { + if (l->auto_create) { + kicad_create_layer(st, last_copper+l->id, l->prefix, NULL, subtree, last_copper); + } + } + pcb_layergrp_inhibit_dec(); +} + +static pcb_layer_t *kicad_get_subc_layer(read_state_t *st, pcb_subc_t *subc, const char *layer_name, const char *default_layer_name) +{ + int pcb_idx = -1; + rnd_layer_id_t lid; + pcb_layer_type_t lyt; + pcb_layer_combining_t comb; + const char *lnm; + + if (layer_name != NULL) { + /* check if the layer already exists (by name) */ + lid = pcb_layer_by_name(subc->data, layer_name); + if (lid >= 0) + return &subc->data->Layer[lid]; + + pcb_idx = kicad_get_layeridx(st, layer_name); + lnm = layer_name; + if (pcb_idx < 0) { + rnd_message(RND_MSG_ERROR, "\tfp_* layer '%s' not found for module object, using unbound subc layer instead.\n", layer_name); + lyt = PCB_LYT_VIRTUAL; + comb = 0; + return pcb_subc_get_layer(subc, lyt, comb, 1, lnm, rnd_true); + } + } + else { + /* check if the layer already exists (by name) */ + lid = pcb_layer_by_name(subc->data, default_layer_name); + if (lid >= 0) + return &subc->data->Layer[lid]; + + rnd_message(RND_MSG_ERROR, "\tfp_* layer '%s' not found for module object, using module layer '%s' instead.\n", layer_name, default_layer_name); + pcb_idx = kicad_get_layeridx(st, default_layer_name); + if (pcb_idx < 0) + return NULL; + lnm = default_layer_name; + } + + if (st->pcb == NULL) + lyt = st->fp_data->Layer[pcb_idx].meta.bound.type; + else + lyt = pcb_layer_flags(st->pcb, pcb_idx); + comb = 0; + if (lyt & PCB_LYT_MASK) + comb |= PCB_LYC_SUB; + return pcb_subc_get_layer(subc, lyt, comb, 1, lnm, rnd_true); +} + +#define SEEN_NO_DUP(bucket, bit) \ +do { \ + int __mask__ = (1<<(bit)); \ + if ((bucket) & __mask__) \ + return -1; \ + bucket |= __mask__; \ +} while(0) + +#define SEEN(bucket, bit) \ +do { \ + int __mask__ = (1<<(bit)); \ + bucket |= __mask__; \ +} while(0) + +#define BV(bit) (1<<(bit)) + +#define ignore_value(n, err) \ +do { \ + if ((n)->children != NULL && (n)->children->str != NULL) { } \ + else \ + return kicad_error(n, err); \ +} while(0) + +#define ignore_value_nodup(n, tally, bitval, err) \ +do { \ + SEEN_NO_DUP(tally, bitval); \ + ignore_value(n, err); \ +} while(0) + +static int kicad_update_size(read_state_t *st) +{ + int n; + for(n = 0; n < DIM_max; n++) { + if (st->dim_valid[n]) { + st->pcb->hidlib.size_x = st->width[n]; + st->pcb->hidlib.size_y = st->height[n]; + return 0; + } + } + + return 0; +} + +/* kicad_pcb/parse_page */ +static int kicad_parse_page_size(read_state_t *st, gsxl_node_t *subtree) +{ + pcb_media_t *m; + + if ((subtree == NULL) || (subtree->str == NULL)) + return kicad_error(subtree, "error parsing KiCad layout size."); + + for(m = pcb_media_data; m->name != NULL; m++) { + if (strcmp(m->name, subtree->str) == 0) { + /* pivot: KiCad assumes portrait */ + st->width[DIM_PAGE] = m->height; + st->height[DIM_PAGE] = m->width; + st->dim_valid[DIM_PAGE] = 1; + return kicad_update_size(st); + } + } + + kicad_error(subtree, "Unknown layout size '%s', using fallback.\n", subtree->str); + return kicad_update_size(st); +} + + +/* kicad_pcb/parse_title_block */ +static int kicad_parse_title_block(read_state_t *st, gsxl_node_t *subtree) +{ + gsxl_node_t *n; + const char *prefix = "kicad_titleblock_"; + char *name; + + if (subtree->str == NULL) + return kicad_error(subtree, "error parsing KiCad titleblock: empty"); + + name = rnd_concat(prefix, subtree->str, NULL); + pcb_attrib_put(st->pcb, name, subtree->children->str); + free(name); + for(n = subtree->next; n != NULL; n = n->next) { + if (n->str != NULL && strcmp("comment", n->str) != 0) { + name = rnd_concat(prefix, n->str, NULL); + pcb_attrib_put(st->pcb, name, n->children->str); + free(name); + } + else { /* if comment field has extra children args */ + name = rnd_concat(prefix, n->str, "_", n->children->str, NULL); + pcb_attrib_put(st->pcb, name, n->children->next->str); + free(name); + } + } + return 0; +} + +/* Convert the string value of node to double and store it in res. On conversion + error report error on node using errmsg. If node == NULL: report error + on missnode, or ignore the problem if missnode is NULL. */ +#define PARSE_DOUBLE(res, missnode, node, errmsg) \ +do { \ + gsxl_node_t *__node__ = (node); \ + if ((__node__ != NULL) && (__node__->str != NULL)) { \ + char *__end__; \ + double __val__ = strtod(__node__->str, &__end__); \ + if (*__end__ != 0) \ + return kicad_error(node, "Invalid numeric (double) " errmsg); \ + else \ + (res) = __val__; \ + } \ + else if (missnode != NULL) \ + return kicad_error(missnode, "Missing child node for " errmsg); \ +} while(0) \ + +/* Convert the string value of node to int and store it in res. On conversion + error report error on node using errmsg. If node == NULL: report error + on missnode, or ignore the problem if missnode is NULL. */ +#define PARSE_INT(res, missnode, node, errmsg) \ +do { \ + gsxl_node_t *__node__ = (node); \ + if ((__node__ != NULL) && (__node__->str != NULL)) { \ + char *__end__; \ + double __val__ = strtol(__node__->str, &__end__, 10); \ + if (*__end__ != 0) \ + return kicad_error(node, "Invalid numeric (integer) " errmsg); \ + else \ + (res) = __val__; \ + } \ + else if (missnode != NULL) \ + return kicad_error(missnode, "Missing child node for " errmsg); \ +} while(0) \ + +/* same as PARSE_DOUBLE() but res is a rnd_coord_t, input string is in mm */ +#define PARSE_COORD(res, missnode, node, errmsg) \ +do { \ + double __dtmp__; \ + PARSE_DOUBLE(__dtmp__, missnode, node, errmsg); \ + (res) = rnd_round(RND_MM_TO_COORD(__dtmp__)); \ +} while(0) \ + +/* parse nd->str into a pcb_layer_t in ly, either as a subc layer or if subc + is NULL, as an st->pcb board layer. loc is a string literal, parent context + of the text, used in the error message. + NOTE: subc case: for text there is no subc default layer (assumes KiCad has text on silk only) */ +#define PARSE_LAYER(ly, nd, subc, loc) \ + do { \ + if ((nd == NULL) || (nd->str == NULL)) \ + return kicad_error(n, "unexpected empty/NULL " loc " layer node"); \ + if (subc == NULL) { \ + rnd_layer_id_t lid = kicad_get_layeridx(st, nd->str); \ + if (lid < 0) \ + return kicad_error(nd, "unhandled " loc " layer: (%s)", nd->str); \ + ly = &st->pcb->Data->Layer[lid]; \ + } \ + else \ + ly = kicad_get_subc_layer(st, subc, nd->str, NULL); \ + } while(0) + +/* Search the autoload table for subtree->str, convert data to a struct field + on match with the children ("parameters") of the subtree */ +static int kicad_autoload(read_state_t *st, gsxl_node_t *subtree, void *dst_struct, const autoload_t *auto_table, int allow_unknown) +{ + const autoload_t *a; + + /* do not tolerate empty/NIL node */ + if (subtree->str == NULL) + return kicad_error(subtree, "unexpected empty/NIL subtree"); + + for(a = auto_table; a->node_name != NULL; a++) { + if (strcmp(a->node_name, subtree->str) == 0) { + char *dst = ((char *)dst_struct) + a->offset; + switch(a->type) { + case KICAD_DOUBLE: + { + double *d = (double *)dst; + PARSE_DOUBLE(*d, NULL, subtree->children, ""); + } + break; + case KICAD_COORD: + { + rnd_coord_t *d = (rnd_coord_t *)dst; + PARSE_COORD(*d, NULL, subtree->children, ""); + } + break; + } + } + } + + if (allow_unknown) + return 0; + + /* node name not found in the dispatcher table */ + return kicad_error(subtree, "Unknown node: '%s'", subtree->str); +} + +/* Take each children of tree and execute them using kicad_autoload + Useful for procssing nodes that may host various subtrees of different + nodes in a flexible way. Return non-zero if any subtree processor failed. */ +static int kicad_foreach_autoload(read_state_t *st, gsxl_node_t *tree, void *dst, const autoload_t *auto_table, int allow_unknown) +{ + gsxl_node_t *n; + + for(n = tree; n != NULL; n = n->next) + if (kicad_autoload(st, n, dst, auto_table, allow_unknown) != 0) + return -1; + + return 0; /* success */ +} + + +static int kicad_parse_general_area(read_state_t *st, gsxl_node_t *subtree) +{ + if ((subtree->str == NULL) || (subtree->next->str == NULL) || (subtree->next->next->str == NULL) || (subtree->next->next->next->str == NULL)) + return kicad_error(subtree, "area requires 4 arguments.\n"); + + PARSE_COORD(st->width[DIM_AREA], NULL, subtree->next->next, "area x2"); + PARSE_COORD(st->height[DIM_AREA], NULL, subtree->next->next->next, "area y2"); + st->dim_valid[DIM_AREA] = 1; + return kicad_update_size(st); +} + +static int kicad_parse_general(read_state_t *st, gsxl_node_t *subtree) +{ + static const dispatch_t disp[] = { /* possible children of root */ + {"links", kicad_parse_nop}, + {"no_connects", kicad_parse_nop}, + {"area", kicad_parse_general_area}, + {"thickness", kicad_parse_nop}, + {"drawings", kicad_parse_nop}, + {"tracks", kicad_parse_nop}, + {"zones", kicad_parse_nop}, + {"modules", kicad_parse_nop}, + {"nets", kicad_parse_nop}, + {NULL, NULL} + }; + + /* Call the corresponding subtree parser for each child node of the root + node; if any of them fail, parse fails */ + return kicad_foreach_dispatch(st, subtree, disp); +} + +static int kicad_parse_setup(read_state_t *st, gsxl_node_t *subtree) +{ + static const autoload_t atbl[] = { + {"pad_to_mask_clearance", offsetof(read_state_t, pad_to_mask_clearance), KICAD_COORD}, + {"zone_clearance", offsetof(read_state_t, zone_clearance), KICAD_COORD}, + {NULL, 0, 0} + }; + return kicad_foreach_autoload(st, subtree, st, atbl, 1); +} + + +static char *fp_text_subst(char *text, pcb_flag_t *flg, int is_refdes) +{ + if (is_refdes || (strcmp(text, "%R") == 0)) { + flg->f |= PCB_FLAG_DYNTEXT | PCB_FLAG_FLOATER; + return "%a.parent.refdes%"; + } + if (strcmp(text, "%V") == 0) { + flg->f |= PCB_FLAG_DYNTEXT | PCB_FLAG_FLOATER; + return "%a.parent.value%"; + } + return text; +} + +/* kicad_pcb/gr_text and fp_text */ +static int kicad_parse_any_text(read_state_t *st, gsxl_node_t *subtree, char *text, pcb_subc_t *subc, double mod_rot, int mod_mirror, int is_refdes) +{ + gsxl_node_t *l, *n, *m; + int i, mirrored = 0; + unsigned long tally = 0, required; + double sx, sy, rotdeg = 0.0; + rnd_coord_t X, Y, thickness = 0, bbw, bbh, xanch, yanch; + int align = 0; /* -1 for left, 0 for center and +1 for right */ + pcb_flag_t flg = pcb_flag_make(0); /* start with something bland here */ + pcb_layer_t *ly; + + /* fix up text for kicad's %R and %V */ + if (subc != NULL) + text = fp_text_subst(text, &flg, is_refdes); + + for(n = subtree, i = 0; n != NULL; n = n->next, i++) { + if (n->str == NULL) + return kicad_error(n, "empty text node"); + if (strcmp("at", n->str) == 0) { + SEEN_NO_DUP(tally, 0); + PARSE_COORD(X, n, n->children, "text X1"); + PARSE_COORD(Y, n, n->children->next, "text Y1"); + PARSE_DOUBLE(rotdeg, NULL, n->children->next->next, "text rotation"); + if (subc != NULL) { + rnd_coord_t sx, sy; + if (pcb_subc_get_origin(subc, &sx, &sy) == 0) { + X += sx; + Y += sy; + } + } + } + else if (strcmp("layer", n->str) == 0) { + SEEN_NO_DUP(tally, 1); + PARSE_LAYER(ly, n->children, subc, "text"); + if (subc == NULL) { + if (pcb_layer_flags_(ly) & PCB_LYT_BOTTOM) + flg.f |= PCB_FLAG_ONSOLDER; + } + } + else if (strcmp("hide", n->str) == 0) { + if (subc != NULL) + return 0; /* simply don't create the object */ + else + kicad_warning(n, "'hide' is invalid for gr_text (ignored)"); + } + else if (strcmp("effects", n->str) == 0) { + for(m = n->children; m != NULL; m = m->next) { + if (m->str == NULL) + return kicad_error(m, "empty text effect"); + if (strcmp("font", m->str) == 0) { + for(l = m->children; l != NULL; l = l->next) { + if (m->str != NULL && strcmp("size", l->str) == 0) { + SEEN_NO_DUP(tally, 2); + /* accrding to gerber exports from v5, it seems the sizes are mixed up! */ + PARSE_DOUBLE(sx, l, l->children->next, "text size X"); + PARSE_DOUBLE(sy, l, l->children, "text size Y"); + } + else if (strcmp("thickness", l->str) == 0) { + SEEN_NO_DUP(tally, 3); + PARSE_COORD(thickness, l, l->children, "text thickness"); + } + } + } + else if (strcmp("justify", m->str) == 0) { + gsxl_node_t *j; + + for(j = m->children; (j != NULL) && (j->str != NULL); j = j->next) { + if (strcmp("mirror", j->str) == 0) { + mirrored = 1; + SEEN_NO_DUP(tally, 4); + } + else if (strcmp("left", j->str) == 0) { + align = -1; + SEEN_NO_DUP(tally, 5); + } + else if (strcmp("center", j->str) == 0) { + align = 0; + SEEN_NO_DUP(tally, 5); + } + else if (strcmp("right", j->str) == 0) { + align = 1; + SEEN_NO_DUP(tally, 5); + } + else + return kicad_error(j, "unknown text justification: %s\n", j->str); + } + } + else + kicad_warning(m, "Unknown text effects argument %s:", m->str); + } + } + } + + /* has location, layer, size and stroke thickness at a minimum */ + required = BV(0) | BV(1) | BV(2) | BV(3); + if ((tally & required) != required) + return kicad_error(subtree, "failed to create text due to missing fields"); + + /* calculate input bounding box */ + bbw = RND_MM_TO_COORD(2.0 * (sx+RND_COORD_TO_MM(thickness)) / 3.0 * strlen(text)); + bbh = RND_MM_TO_COORD(1.25 * (sy+RND_COORD_TO_MM(thickness))); + + switch(align) { + case -1: xanch = 0; break; + case 0: xanch = bbw/2; break; + case +1: xanch = bbw; break; + } + yanch = RND_MM_TO_COORD(0.66*sy+RND_COORD_TO_MM(thickness)); + + rotdeg -= mod_rot; + if (mirrored) + rotdeg = -rotdeg; + + if (mod_mirror) { + rotdeg += 180; + if (rotdeg > 360) + rotdeg -= 360; + } + + pcb_text_new_by_bbox(ly, pcb_font(PCB_FOR_FP, 0, 1), X, Y, bbw, bbh, + xanch, yanch, sx/sy, mirrored ? PCB_TXT_MIRROR_X : 0, rotdeg, thickness, + text, flg); + + return 0; /* create new font */ +} + +/* kicad_pcb/gr_text */ +static int kicad_parse_gr_text(read_state_t *st, gsxl_node_t *subtree) +{ + if (subtree->str != NULL) + return kicad_parse_any_text(st, subtree, subtree->str, NULL, 0.0, 0, 0); + return kicad_error(subtree, "failed to create text: missing text string"); +} + +/* kicad_pcb/target */ +static int kicad_parse_target(read_state_t *st, gsxl_node_t *subtree) +{ + unsigned long tally = 0, required; + rnd_coord_t x, y, thick = RND_MM_TO_COORD(0.15); + double size = 5.0; + pcb_layer_t *ly = NULL; + pcb_subc_t *subc; + gsxl_node_t *n, *lyn; + pcb_flag_t flg = pcb_flag_make(0); + int is_plus = 1; + + + for(n = subtree; n != NULL; n = n->next) { + if (strcmp("plus", n->str) == 0) { + SEEN_NO_DUP(tally, 0); + } + else if (strcmp("x", n->str) == 0) { + SEEN_NO_DUP(tally, 0); + is_plus = 0; + } + else if (strcmp("at", n->str) == 0) { + SEEN_NO_DUP(tally, 1); + PARSE_COORD(x, n, n->children, "target X"); + PARSE_COORD(y, n, n->children->next, "target Y"); + } + else if (strcmp("size", n->str) == 0) { + SEEN_NO_DUP(tally, 2); + PARSE_DOUBLE(size, n, n->children, "target size"); + } + else if (strcmp("width", n->str) == 0) { + SEEN_NO_DUP(tally, 3); + PARSE_COORD(thick, n, n->children, "target width"); + } + else if (strcmp("layer", n->str) == 0) { + SEEN_NO_DUP(tally, 4); + lyn = n->children; + } + } + + required = BV(1) | BV(4); + if ((tally & required) != required) + return kicad_error(subtree, "failed to create target: missing fields"); + + if (!(required & BV(0))) + kicad_warning(subtree, "missing \"plus\" or \"x\" in target - assuming plus target graphics may not look like expected"); + + /* create a subc at the given coords */ + subc = pcb_subc_new(); + pcb_subc_create_aux(subc, x, y, 0.0, 0); + if (st->pcb != NULL) { + pcb_subc_reg(st->pcb->Data, subc); + pcb_subc_bind_globals(st->pcb, subc); + } + + PARSE_LAYER(ly, lyn, subc, "target"); + + /* draw the target within the subc */ + if (is_plus) { + pcb_line_new(ly, x-RND_MM_TO_COORD(size/2), y, x+RND_MM_TO_COORD(size/2), y, thick, 0, flg); + pcb_line_new(ly, x, y-RND_MM_TO_COORD(size/2), x, y+RND_MM_TO_COORD(size/2), thick, 0, flg); + } + else { + pcb_line_new(ly, x-RND_MM_TO_COORD(size/2), y-RND_MM_TO_COORD(size/2), x+RND_MM_TO_COORD(size/2), y+RND_MM_TO_COORD(size/2), thick, 0, flg); + pcb_line_new(ly, x+RND_MM_TO_COORD(size/2), y-RND_MM_TO_COORD(size/2), x-RND_MM_TO_COORD(size/2), y+RND_MM_TO_COORD(size/2), thick, 0, flg); + } + pcb_arc_new(ly, x, y, RND_MM_TO_COORD(size*0.325), RND_MM_TO_COORD(size*0.325), 0,360, thick, 0, flg, 0); + + /* finish registration of the subc */ + pcb_subc_bbox(subc); + if (st->pcb != NULL) { + if (st->pcb->Data->subc_tree == NULL) + st->pcb->Data->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(st->pcb->Data->subc_tree, (rnd_box_t *)subc); + pcb_subc_rebind(st->pcb, subc); + } + else + pcb_subc_reg(st->fp_data, subc); + + return 0; +} + +/* kicad_pcb/gr_line or fp_line */ +static int kicad_parse_any_line(read_state_t *st, gsxl_node_t *subtree, pcb_subc_t *subc, pcb_flag_values_t flag, int is_seg) +{ + gsxl_node_t *n; + unsigned long tally = 0, required; + rnd_coord_t x1, y1, x2, y2, thickness, clearance; + pcb_flag_t flg = pcb_flag_make(flag); + pcb_layer_t *ly = NULL; + pcb_line_t *line; + + TODO("apply poly clearance as in pool/io_kicad (CUCP#39)"); + clearance = thickness = 1; /* start with sane default of one nanometre */ + if (subc != NULL) + clearance = 0; + + TODO("this workaround is for segment - remove it when clearance is figured CUCP#39"); + if (flag & PCB_FLAG_CLEARLINE) + clearance = RND_MM_TO_COORD(0.250); + + for(n = subtree; n != NULL; n = n->next) { + if (n->str == NULL) + return kicad_error(n, "empty line parameter"); + if (strcmp("start", n->str) == 0) { + SEEN_NO_DUP(tally, 0); + PARSE_COORD(x1, n, n->children, "line x1 coord"); + PARSE_COORD(y1, n, n->children->next, "line y1 coord"); + } + else if (strcmp("end", n->str) == 0) { + SEEN_NO_DUP(tally, 1); + PARSE_COORD(x2, n, n->children, "line x2 coord"); + PARSE_COORD(y2, n, n->children->next, "line y2 coord"); + } + else if (strcmp("layer", n->str) == 0) { + SEEN_NO_DUP(tally, 2); + PARSE_LAYER(ly, n->children, subc, "line"); + if (st->primitive_ly != NULL) + return kicad_error(n, "line in this context shall not have layer specified"); + } + else if (strcmp("width", n->str) == 0) { + SEEN_NO_DUP(tally, 3); + PARSE_COORD(thickness, n, n->children, "line thickness"); + } + else if (strcmp("angle", n->str) == 0) { /* unlikely to be used or seen */ + ignore_value_nodup(n, tally, 4, "unexpected empty/NULL line angle"); + } + else if (strcmp("net", n->str) == 0) { /* unlikely to be used or seen */ + ignore_value_nodup(n, tally, 5, "unexpected empty/NULL line net."); + } + else if (strcmp("status", n->str) == 0) { + if (is_seg) { + /* doc: trunk/doc/developer/alien_formats/segment_status.txt */ + /* Conclusion: ignore anything but LOCKED (pcb-rnd doesn't need star/end on pad) */ + if ((n->children != NULL) && (n->children->str != NULL)) { + unsigned long int kf; + char *end; + kf = strtoul(n->children->str, &end, 16); + if (*end != '\0') + return kicad_error(n->children, "invalid hex integer in status"); + if (kf & 0x40000UL) + flg.f |= PCB_FLAG_LOCK; + } + else + kicad_warning(n, "missing status hex integer"); + } + else + return kicad_error(n, "unexpected status in line object (only segment should have a status)"); + } + else if (strcmp("tstamp", n->str) == 0) { + /* ignore */ + } + else + kicad_warning(n, "unexpected line node: %s", n->str); + } + + /* need start, end, layer, thickness at a minimum */ + required = BV(0) | BV(1); /* | BV(3); now have 1nm default width, i.e. for edge cut */ + if (st->primitive_ly == NULL) + required |= BV(2); + else + ly = st->primitive_ly; + + if ((tally & required) != required) + return kicad_error(subtree, "failed to create line: missing fields"); + + if (st->primitive_subc != NULL) + subc = st->primitive_subc; + + if (subc != NULL) { + rnd_coord_t sx, sy; + if (pcb_subc_get_origin(subc, &sx, &sy) == 0) { + x1 += sx; + y1 += sy; + x2 += sx; + y2 += sy; + } + } + line = pcb_line_new(ly, x1, y1, x2, y2, thickness, clearance, flg); + if (st->primitive_term != NULL) + pcb_attribute_put(&line->Attributes, "term", st->primitive_term); + return 0; +} + +/* kicad_pcb/gr_line */ +static int kicad_parse_gr_line(read_state_t *st, gsxl_node_t *subtree) +{ + return kicad_parse_any_line(st, subtree, NULL, 0, 0); +} + +/* kicad_pcb/gr_arc, gr_cicle, fp_arc, fp_circle */ +static int kicad_parse_any_arc(read_state_t *st, gsxl_node_t *subtree, pcb_subc_t *subc) +{ + gsxl_node_t *n; + unsigned long tally = 0, required; + rnd_coord_t cx, cy, endx, endy, thickness, clearance, deltax, deltay; + rnd_angle_t end_angle = 0.0, delta = 360.0; /* these defaults allow a gr_circle to be parsed, which does not specify (angle XXX) */ + pcb_flag_t flg = pcb_flag_make(0); /* start with something bland here */ + pcb_layer_t *ly = NULL; + pcb_arc_t *arc; + + TODO("apply poly clearance as in pool/io_kicad (CUCP#39)"); + if (subc == NULL) + clearance = thickness = RND_MM_TO_COORD(0.250); /* start with sane defaults */ + else + clearance = thickness = RND_MM_TO_COORD(0); + + for(n = subtree; n != NULL; n = n->next) { + if (n->str == NULL) + return kicad_error(n, "empty arc argument"); + if (strcmp("start", n->str) == 0) { + SEEN_NO_DUP(tally, 0); + PARSE_COORD(cx, n, n->children, "arc start X coord"); + PARSE_COORD(cy, n, n->children->next, "arc start Y coord"); + } + else if (strcmp("center", n->str) == 0) { /* this lets us parse a circle too */ + SEEN_NO_DUP(tally, 0); + PARSE_COORD(cx, n, n->children, "arc start X coord"); + PARSE_COORD(cy, n, n->children->next, "arc start Y coord"); + } + else if (strcmp("end", n->str) == 0) { + SEEN_NO_DUP(tally, 1); + PARSE_COORD(endx, n, n->children, "arc end X coord"); + PARSE_COORD(endy, n, n->children->next, "arc end Y coord"); + } + else if (strcmp("layer", n->str) == 0) { + SEEN_NO_DUP(tally, 2); + PARSE_LAYER(ly, n->children, subc, "arc"); + if (st->primitive_ly != NULL) + return kicad_error(n, "arc in this context shall not have layer specified"); + } + else if (strcmp("width", n->str) == 0) { + SEEN_NO_DUP(tally, 3); + PARSE_COORD(thickness, n, n->children, "arc width"); + } + else if (strcmp("angle", n->str) == 0) { + PARSE_DOUBLE(delta, n, n->children, "arc angle"); + } + else if (strcmp("net", n->str) == 0) { /* unlikely to be used or seen */ + ignore_value(n, "unexpected empty/NULL arc net."); + } + else if (strcmp("tstamp", n->str) == 0) { + /* ignore */ + } + else + kicad_warning(n, "Unknown arc argument %s:", n->str); + } + + /* need start, end, layer, thickness at a minimum */ + required = BV(0) | BV(1) | BV(3); /* | BV(4); not needed for circles */ + if (st->primitive_ly == NULL) + required |= BV(2); + else + ly = st->primitive_ly; + + if ((tally & required) != required) + return kicad_error(subtree, "unexpected empty/NULL node in arc."); + + { + rnd_angle_t start_angle; + rnd_coord_t width, height; + + width = height = rnd_distance(cx, cy, endx, endy); /* calculate radius of arc */ + deltax = endx - cx; + deltay = endy - cy; + if (width < 1) { /* degenerate case */ + start_angle = 0; + } + else { + end_angle = 180 + 180 * atan2(-deltay, deltax) / M_PI; + /* avoid using atan2 with zero parameters */ + + if (end_angle < 0.0) + end_angle += 360.0; /* make it 0...360 */ + start_angle = (end_angle - delta); /* pcb-rnd is 180 degrees out of phase with kicad, and opposite direction rotation */ + if (start_angle > 360.0) + start_angle -= 360.0; + if (start_angle < 0.0) + start_angle += 360.0; + } + + if (st->primitive_subc != NULL) + subc = st->primitive_subc; + + if (subc != NULL) { + rnd_coord_t sx, sy; + if (pcb_subc_get_origin(subc, &sx, &sy) == 0) { + cx += sx; + cy += sy; + } + } + /* note: do not remove duplicate arcs, because term may need to be set on the result */ + arc = pcb_arc_new(ly, cx, cy, width, height, start_angle, delta, thickness, clearance, flg, rnd_false); + if (st->primitive_term != NULL) + pcb_attribute_put(&arc->Attributes, "term", st->primitive_term); + } + + return 0; +} + +static int kicad_parse_gr_arc(read_state_t *st, gsxl_node_t *subtree) +{ + return kicad_parse_any_arc(st, subtree, NULL); +} + + +/* kicad_pcb/via */ +static int kicad_parse_via(read_state_t *st, gsxl_node_t *subtree) +{ + gsxl_node_t *n, *nly1, *nly2; + unsigned long tally = 0, required; + int blind_cnt = 0; + rnd_coord_t x, y, thickness, clearance, mask, drill; /* not sure what to do with mask */ + pcb_layer_t *ly1, *ly2; /* blind/buried: from-to layers */ + pcb_pstk_t *ps; + + TODO("apply poly clearance as in pool/io_kicad (CUCP#39)"); + clearance = mask = RND_MM_TO_COORD(0.250); /* start with something bland here */ + drill = RND_MM_TO_COORD(0.300); /* start with something sane */ + + for(n = subtree; n != NULL; n = n->next) { + if (n->str == NULL) + return kicad_error(n, "empty via argument node"); + if (strcmp("at", n->str) == 0) { + SEEN_NO_DUP(tally, 0); + PARSE_COORD(x, n, n->children, "via X coord"); + PARSE_COORD(y, n, n->children->next, "via Y coord"); + } + else if (strcmp("size", n->str) == 0) { + SEEN_NO_DUP(tally, 1); + PARSE_COORD(thickness, n, n->children, "via size coord"); + } + else if (strcmp("layers", n->str) == 0) { + int top=0, bottom=0; + pcb_layer_type_t lyt1, lyt2; + + SEEN_NO_DUP(tally, 2); + nly1 = n->children; + if ((nly1 == NULL) || (nly1->next == NULL) || (nly1->str == NULL) || (nly1->next->str == NULL)) + return kicad_error(n, "too few layers: \"layers\" must have exactly 2 parameters (start and end layer)"); + nly2 = nly1->next; + if (nly2->next != NULL) + return kicad_error(nly2->next, "too few many: \"layers\" must have exactly 2 parameters (start and end layer)"); + + PARSE_LAYER(ly1, nly1, NULL, "via layer1"); + PARSE_LAYER(ly2, nly2, NULL, "via layer2"); + lyt1 = pcb_layer_flags_(ly1); + lyt2 = pcb_layer_flags_(ly2); + if (lyt1 & PCB_LYT_TOP) top++; + if (lyt2 & PCB_LYT_TOP) top++; + if (lyt1 & PCB_LYT_BOTTOM) bottom++; + if (lyt2 & PCB_LYT_BOTTOM) bottom++; + if ((top != 1) || (bottom != 1)) + blind_cnt++; /* a top-to-bottom via is not blind */ + } + else if (strcmp("net", n->str) == 0) { + ignore_value_nodup(n, tally, 3, "unexpected empty/NULL via net node"); + } + else if (strcmp("tstamp", n->str) == 0) { + ignore_value_nodup(n, tally, 4, "unexpected empty/NULL via tstamp node"); + } + else if (strcmp("drill", n->str) == 0) { + SEEN_NO_DUP(tally, 5); + PARSE_COORD(drill, n, n->children, "via drill size"); + } + else if (strcmp("blind", n->str) == 0) { + SEEN_NO_DUP(tally, 6); + blind_cnt++; + } + else + kicad_warning(n, "Unknown via argument %s:", n->str); + } + + /* need start, end, layer, thickness at a minimum */ + required = BV(0) | BV(1); + if ((tally & required) != required) + return kicad_error(subtree, "insufficient via arguments"); + + if ((blind_cnt != 0) && (blind_cnt != 2)) + return kicad_error(subtree, "Contradiction in blind via parameters: the \"blind\" node must present and the via needs to end on an inner layer"); + + ps = pcb_pstk_new_compat_via(st->pcb->Data, -1, x, y, drill, thickness, clearance, mask, PCB_PSTK_COMPAT_ROUND, rnd_true); + if (ps == NULL) + return kicad_error(subtree, "failed to create via-padstack"); + + if (blind_cnt == 2) { /* change the prototype of the padstack to be blind or buried */ + const pcb_pstk_proto_t *orig_proto; + pcb_pstk_proto_t *new_proto; + rnd_cardinal_t new_pid; + int ot1, ot2, ob1, ob2, err; + rnd_layergrp_id_t gtop = pcb_layergrp_get_top_copper(); + rnd_layergrp_id_t gbot = pcb_layergrp_get_bottom_copper(); + + orig_proto = pcb_pstk_get_proto(ps); + assert(orig_proto != NULL); + + err = pcb_layergrp_dist(st->pcb, ly1->meta.real.grp, gtop, PCB_LYT_COPPER, &ot1); + err |= pcb_layergrp_dist(st->pcb, ly2->meta.real.grp, gtop, PCB_LYT_COPPER, &ot2); + err |= pcb_layergrp_dist(st->pcb, ly1->meta.real.grp, gbot, PCB_LYT_COPPER, &ob1); + err |= pcb_layergrp_dist(st->pcb, ly2->meta.real.grp, gbot, PCB_LYT_COPPER, &ob2); + + if (err != 0) + return kicad_error(subtree, "failed to calculate blind/buried via span: invalid layer(s) specified"); + if ((ot1 == ot2) || (ob1 == ob2)) + return kicad_error(subtree, "failed to calculate blind/buried via span: start layer group matches end layer group"); + + pcb_pstk_pre(ps); + new_proto = calloc(sizeof(pcb_pstk_proto_t), 1); + pcb_pstk_proto_copy(new_proto, orig_proto); /* to get all the original shapes and attributes and flags */ + + new_proto->htop = MIN(ot1, ot2); + new_proto->hbottom = MIN(ob1, ob2); + new_pid = pcb_pstk_proto_insert_or_free(st->pcb->Data, new_proto, 0, 0); + ps->proto = new_pid; + pcb_pstk_post(ps); + } + + return 0; +} + +/* kicad_pcb/segment */ +static int kicad_parse_segment(read_state_t *st, gsxl_node_t *subtree) +{ + return kicad_parse_any_line(st, subtree, NULL, PCB_FLAG_CLEARLINE, 1); +} + +/* kicad_pcb parse (layers ) - either board layer defintions, or module pad/via layer defs */ +static int kicad_parse_layer_definitions(read_state_t *st, gsxl_node_t *subtree) +{ + gsxl_node_t *n; + int last_copper; + + if (strcmp(subtree->parent->parent->str, "kicad_pcb") != 0) /* test if deeper in tree than layer definitions for entire board */ + return kicad_error(subtree, "layer definition found in unexpected location in KiCad layout"); + + /* we are just below the top level or root of the tree, so this must be a layer definitions section */ + pcb_layergrp_inhibit_inc(); + pcb_layer_group_setup_default(st->pcb); + + +TODO("check if we really need these excess layers"); +#if 0 + /* set up the hash for implicit layers for modules */ + res = 0; + res |= kicad_reg_layer(st, "Top", PCB_LYT_COPPER | PCB_LYT_TOP, NULL); + res |= kicad_reg_layer(st, "Bottom", PCB_LYT_COPPER | PCB_LYT_BOTTOM, NULL); + + if (res != 0) { + kicad_error(subtree, "Internal error: can't find a silk or mask layer while parsing KiCad layout"); + goto error; + } +#endif + + vtp0_init(&st->intern_copper); + + /* find the first non-signal layer */ + last_copper = -1; + for(n = subtree; n != NULL; n = n->next) { + int lnum, is_copper; + if ((n->str == NULL) || (n->children->str == NULL) || (n->children->next == NULL) || (n->children->next->str == NULL)) { + kicad_error(n, "unexpected board layer definition encountered\n"); + goto error; + } + lnum = atoi(n->str); + is_copper = (strcmp(n->children->next->str, "signal") == 0) || (strcmp(n->children->next->str, "power") == 0) || (strcmp(n->children->next->str, "mixed") == 0); + if ((lnum == 0) && (!is_copper)) { + kicad_error(n, "unexpected board layer definition: layer 0 must be signal\n"); + goto error; + } + if (is_copper && (lnum > last_copper)) + last_copper = lnum; + } + + if (last_copper < 2) { + kicad_error(subtree, "broken layer stack: need at least 2 signal layers (copper layers)\n"); + goto error; + } + if ((last_copper != 15) && (last_copper != 31)) + kicad_error(subtree, "unusual KiCad layer stack: there should be 16 or 32 copper layers, you seem to have %d instead\n", last_copper+1); + + for(n = subtree; n != NULL; n = n->next) { + int lnum; + char *end; + const char *lname = n->children->str, *ltype = n->children->next->str; + + lnum = strtol(n->str, &end, 10); + if (*end != '\0') { + kicad_error(n, "Invalid numeric in layer number (must be a small integer)\n"); + goto error; + } + if (kicad_create_layer(st, lnum, lname, ltype, n, last_copper) < 0) { + kicad_error(n, "Unrecognized layer: %d, %s, %s\n", lnum, lname, ltype); + goto error; + } + } + + /* create internal copper layers, in the right order, regardless of in + what order they are present in the file */ + { + int n, from, dir, reverse_order = (st->ver <= 3); + + if (reverse_order) { + from = last_copper; + dir = -1; + } + else { + from = 0; + dir = 1; + } + + for(n = from; (n <= last_copper) && (n >= 0); n += dir) { + void **ndp = vtp0_get(&st->intern_copper, n, 0); + gsxl_node_t *nd; + if ((ndp != NULL) && (*ndp != NULL)) { + pcb_layergrp_t *g = pcb_get_grp_new_intern(st->pcb, -1); + rnd_layergrp_id_t gid = g - st->pcb->LayerGroups.grp; + const char *lname, *ltype; + + nd = *ndp; + lname = nd->children->str; + ltype = nd->children->next->str; + + if (kicad_create_copper_layer_(st, gid, lname, ltype, nd) != 0) { + kicad_error(nd, "Failed to create internal copper layer: %d, %s, %s\n", n, lname, ltype); + goto error; + } + } + } + } + + vtp0_uninit(&st->intern_copper); + + pcb_layergrp_fix_old_outline(PCB); + pcb_layergrp_inhibit_dec(); + return 0; + + error:; + pcb_layergrp_inhibit_dec(); + return -1; +} + +/* kicad_pcb parse global (board level) net */ +static int kicad_parse_net(read_state_t *st, gsxl_node_t *subtree) +{ + const char *netname; + + if ((subtree == NULL) || (subtree->str == NULL)) + return kicad_error(subtree, "missing net number in net descriptors."); + + if ((subtree->next == NULL) || (subtree->next->str == NULL)) + return kicad_error(subtree->next, "missing net label in net descriptors."); + + netname = subtree->next->str; + if (*netname == '\0') + return 0; /* do not create the anonymous net (is it the no-connect net in kicad?) */ + + if (pcb_net_get(st->pcb, &st->pcb->netlist[PCB_NETLIST_INPUT], netname, PCB_NETA_ALLOC) == NULL) + return kicad_error(subtree->next, "Failed to create net %s", netname); + + return 0; +} + +/* Make a list of zone connects - these connections can not be made immediately + because the polygons may not exist yet */ +static void save_zone_connect(read_state_t *st, pcb_pstk_t *ps, int zone_connect, const char *netname) +{ + zone_connect_t *zc = malloc(sizeof(zone_connect_t)); + zc->ps = ps; + zc->style = zone_connect; + zc->netname = netname; /* it is safe to remember without strdup since it is a tree allocation */ + zc->next = st->zc_head; + st->zc_head = zc; +} + +static void exec_zone_connect(read_state_t *st) +{ + zone_connect_t *zc, *next; + htpp_t poly_upd; + htpp_entry_t *e; + + htpp_init(&poly_upd, ptrhash, ptrkeyeq); + + for(zc = st->zc_head; zc != NULL; zc = next) { + rnd_layer_id_t lid; + pcb_layer_t *ly; + + /* search all layers for polygons */ + for(lid = 0, ly = st->pcb->Data->Layer; lid < st->pcb->Data->LayerN; lid++,ly++) { + rnd_rtree_it_t it; + pcb_poly_t *p; + + if (ly->polygon_tree == NULL) continue; + + /* use rtree to search for polys that are near the padstack */ + for(p = rnd_rtree_first(&it, ly->polygon_tree, (const rnd_rtree_box_t *)&zc->ps->BoundingBox); p != NULL; p = rnd_rtree_next(&it)) { + const char *pnet; + pnet = htpp_get(&st->poly2net, p); + if ((zc != NULL) && (zc->netname != NULL) && (pnet != NULL) && (strcmp(pnet, zc->netname) == 0)) { + unsigned char *th = pcb_pstk_get_thermal(zc->ps, lid, 1); + + switch(zc->style) { + case 1: (*th) |= PCB_THERMAL_ON | PCB_THERMAL_ROUND; break; + case 2: (*th) |= PCB_THERMAL_ON | PCB_THERMAL_SOLID; break; + case 3: (*th) |= PCB_THERMAL_ON | PCB_THERMAL_ROUND | PCB_THERMAL_DIAGONAL; break; + } + htpp_set(&poly_upd, p, p); + rnd_trace("CONN lid=%ld p=%p in %s style=%d\n", lid, p, pnet, zc->style); + } + } + } + + next = zc->next; + free(zc); + } + + /* assume many pins in a poly: it is cheaper to reclip affected polys once, + at the end, than to reclip on each padstack thermal installation in + the above loop */ + for(e = htpp_first(&poly_upd); e != NULL; e = htpp_next(&poly_upd, e)) { + pcb_poly_t *p = e->key; + pcb_poly_init_clip(p->parent.layer->parent.data, p->parent.layer, p); + } + htpp_uninit(&poly_upd); +} + +typedef struct { + pcb_layer_type_t want[PCB_LYT_INTERN+1]; /* indexed by location, contains OR'd bitmask of PCB_LYT_COPPER, PCB_LYT_MASK, PCB_LYT_PASTE */ +} kicad_padly_t; + + + +static void kicad_slot_shape(pcb_pstk_shape_t *shape, rnd_coord_t sx, rnd_coord_t sy) +{ + shape->shape = PCB_PSSH_LINE; + if (sx > sy) { /* horizontal */ + shape->data.line.thickness = sy; + shape->data.line.x1 = (-sx + sy)/2; + shape->data.line.x2 = (+sx - sy)/2; + shape->data.line.y1 = shape->data.line.y2 = 0; + } + else { /* vertical */ + shape->data.line.thickness = sx; + shape->data.line.y1 = (-sy + sx)/2; + shape->data.line.y2 = (+sy - sx)/2; + shape->data.line.x1 = shape->data.line.x2 = 0; + } + shape->layer_mask = PCB_LYT_MECH; + shape->comb = PCB_LYC_AUTO; +} + + +/* check if shape is wanted on a given layer - thru-hole version */ +#define LYSHT(loc, typ) ((layers->want[PCB_LYT_ ## loc] & (PCB_LYT_ ## typ))) + +/* check if shape is wanted on a given layer - SMD version */ +#define LYSHS(loc, typ) ((layers->want[loc] & (PCB_LYT_ ## typ))) + +static pcb_pstk_t *kicad_make_pad_thr(read_state_t *st, gsxl_node_t *subtree, pcb_subc_t *subc, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t padXsize, rnd_coord_t padYsize, rnd_coord_t clearance, rnd_coord_t mask, rnd_coord_t paste, double paste_ratio, rnd_coord_t drillx, rnd_coord_t drilly, const char *pad_shape, int plated, kicad_padly_t *layers, double shape_arg, double shape_arg2) +{ + int len = 0, slot = (drillx != drilly); + rnd_coord_t drill = 0; + + if (pad_shape == NULL) { + kicad_error(subtree, "pin with no shape"); + return NULL; + } + + paste_ratio = 1.0 + (2.0 * paste_ratio); + + if (!slot) + drill = drillx; + + if ((strcmp(pad_shape, "rect") == 0) || (strcmp(pad_shape, "trapezoid") == 0) || (strcmp(pad_shape, "custom") == 0)) { + /* "custom" pads always have a rectangular shape too; keep the rectangle as + padstack and add the custom shapes as heavy terminal together with the + padstack */ + pcb_pstk_shape_t sh[9]; + rnd_coord_t dy = RND_MM_TO_COORD(shape_arg), dx = RND_MM_TO_COORD(shape_arg2); /* x;y and 1;2 swapped intentionally - kicad does it like that */ + memset(sh, 0, sizeof(sh)); + if (LYSHT(TOP, MASK)) {sh[len].layer_mask = PCB_LYT_TOP | PCB_LYT_MASK; sh[len].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_rect_trdelta(&sh[len++], padXsize+mask*2, padYsize+mask*2, dx, dy);} + if (LYSHT(BOTTOM, MASK)) {sh[len].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_MASK; sh[len].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_rect_trdelta(&sh[len++], padXsize+mask*2, padYsize+mask*2, dx, dy);} + if (LYSHT(TOP, PASTE)) {sh[len].layer_mask = PCB_LYT_TOP | PCB_LYT_PASTE; sh[len].comb = PCB_LYC_AUTO; pcb_shape_rect_trdelta(&sh[len++], padXsize * paste_ratio + paste*2, padYsize * paste_ratio + paste*2, dx, dy);} + if (LYSHT(BOTTOM, PASTE)) {sh[len].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_PASTE; sh[len].comb = PCB_LYC_AUTO; pcb_shape_rect_trdelta(&sh[len++], padXsize * paste_ratio + paste*2, padYsize * paste_ratio + paste*2, dx, dy);} + if (LYSHT(TOP, COPPER)) {sh[len].layer_mask = PCB_LYT_TOP | PCB_LYT_COPPER; pcb_shape_rect_trdelta(&sh[len++], padXsize, padYsize, dx, dy);} + if (LYSHT(BOTTOM, COPPER)) {sh[len].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_COPPER; pcb_shape_rect_trdelta(&sh[len++], padXsize, padYsize, dx, dy);} + if (LYSHT(INTERN, COPPER)) {sh[len].layer_mask = PCB_LYT_INTERN | PCB_LYT_COPPER; pcb_shape_rect_trdelta(&sh[len++], padXsize, padYsize, dx, dy);} + if (slot) {kicad_slot_shape(&sh[len++], drillx, drilly);} + if (len == 0) goto no_layer; + sh[len++].layer_mask = 0; + return pcb_pstk_new_from_shape(subc->data, X, Y, drill, plated, clearance, sh); + } + else if ((strcmp(pad_shape, "oval") == 0) || (strcmp(pad_shape, "circle") == 0)) { + pcb_pstk_shape_t sh[9]; + memset(sh, 0, sizeof(sh)); + if (LYSHT(TOP, MASK)) {sh[len].layer_mask = PCB_LYT_TOP | PCB_LYT_MASK; sh[len].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_oval(&sh[len++], padXsize + mask * 2, padYsize + mask * 2);} + if (LYSHT(BOTTOM, MASK)) {sh[len].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_MASK; sh[len].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_oval(&sh[len++], padXsize + mask * 2, padYsize + mask * 2);} + if (LYSHT(TOP, PASTE)) {sh[len].layer_mask = PCB_LYT_TOP | PCB_LYT_PASTE; sh[len].comb = PCB_LYC_AUTO; pcb_shape_oval(&sh[len++], padXsize * paste_ratio + paste*2, padYsize * paste_ratio + paste*2);} + if (LYSHT(BOTTOM, PASTE)) {sh[len].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_PASTE; sh[len].comb = PCB_LYC_AUTO; pcb_shape_oval(&sh[len++], padXsize * paste_ratio + paste*2, padYsize * paste_ratio + paste*2);} + if (LYSHT(TOP, COPPER)) {sh[len].layer_mask = PCB_LYT_TOP | PCB_LYT_COPPER; pcb_shape_oval(&sh[len++], padXsize, padYsize);} + if (LYSHT(BOTTOM, COPPER)) {sh[len].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_COPPER; pcb_shape_oval(&sh[len++], padXsize, padYsize);} + if (LYSHT(INTERN, COPPER)) {sh[len].layer_mask = PCB_LYT_INTERN | PCB_LYT_COPPER; pcb_shape_oval(&sh[len++], padXsize, padYsize);} + if (slot) {kicad_slot_shape(&sh[len++], drillx, drilly);} + if (len == 0) goto no_layer; + sh[len++].layer_mask = 0; + return pcb_pstk_new_from_shape(subc->data, X, Y, drill, plated, clearance, sh); + } + else if (strcmp(pad_shape, "roundrect") == 0) { + pcb_pstk_shape_t sh[9]; + + if ((shape_arg <= 0.0) || (shape_arg > 0.5)) { + kicad_error(subtree, "Round rectangle ratio %f out of range: must be >0 and <=0.5", shape_arg); + return NULL; + } + + memset(sh, 0, sizeof(sh)); + if (LYSHT(TOP, MASK)) {sh[len].layer_mask = PCB_LYT_TOP | PCB_LYT_MASK; sh[len].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_roundrect(&sh[len++], padXsize+mask*2, padYsize+mask*2, shape_arg);} + if (LYSHT(BOTTOM, MASK)) {sh[len].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_MASK; sh[len].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_roundrect(&sh[len++], padXsize+mask*2, padYsize+mask*2, shape_arg);} + if (LYSHT(TOP, PASTE)) {sh[len].layer_mask = PCB_LYT_TOP | PCB_LYT_PASTE; sh[len].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_roundrect(&sh[len++], padXsize * paste_ratio + paste*2, padYsize * paste_ratio + paste*2, shape_arg);} + if (LYSHT(BOTTOM, PASTE)) {sh[len].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_PASTE; sh[len].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_roundrect(&sh[len++], padXsize * paste_ratio + paste*2, padYsize * paste_ratio + paste*2, shape_arg);} + if (LYSHT(TOP, COPPER)) {sh[len].layer_mask = PCB_LYT_TOP | PCB_LYT_COPPER; pcb_shape_roundrect(&sh[len++], padXsize, padYsize, shape_arg);} + if (LYSHT(BOTTOM, COPPER)) {sh[len].layer_mask = PCB_LYT_BOTTOM | PCB_LYT_COPPER; pcb_shape_roundrect(&sh[len++], padXsize, padYsize, shape_arg);} + if (LYSHT(INTERN, COPPER)) {sh[len].layer_mask = PCB_LYT_INTERN | PCB_LYT_COPPER; pcb_shape_roundrect(&sh[len++], padXsize, padYsize, shape_arg);} + if (slot) {kicad_slot_shape(&sh[len++], drillx, drilly);} + if (len == 0) goto no_layer; + sh[len++].layer_mask = 0; + return pcb_pstk_new_from_shape(subc->data, X, Y, drill, plated, clearance, sh); + } + + kicad_error(subtree, "unsupported pad shape '%s'.", pad_shape); + return NULL; + + no_layer:; + kicad_error(subtree, "thru-hole padstack ended up with no shape on any layer"); + return NULL; +} + +static pcb_pstk_t *kicad_make_pad_smd(read_state_t *st, gsxl_node_t *subtree, pcb_subc_t *subc, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t padXsize, rnd_coord_t padYsize, rnd_coord_t clearance, rnd_coord_t mask, rnd_coord_t paste, double paste_ratio, const char *pad_shape, pcb_layer_type_t side, kicad_padly_t *layers, double shape_arg, double shape_arg2) +{ + int len = 0; + + if ((side & PCB_LYT_TOP) && (side & PCB_LYT_BOTTOM)) { + kicad_error(subtree, "can't place the same smd pad on both sides"); + return NULL; + } + + if (!(side & PCB_LYT_TOP) && !(side & PCB_LYT_BOTTOM)) { + kicad_error(subtree, "can't place smd pad on no side"); + return NULL; + } + + paste_ratio = 1.0 + (2.0 * paste_ratio); + + if ((strcmp(pad_shape, "rect") == 0) || (strcmp(pad_shape, "trapezoid") == 0) || (strcmp(pad_shape, "custom") == 0)) { + /* "custom" pads: see comment in kicad_make_pad_thr() */ + pcb_pstk_shape_t sh[4]; + rnd_coord_t dy = RND_MM_TO_COORD(shape_arg), dx = RND_MM_TO_COORD(shape_arg2); /* x;y and 1;2 swapped intentionally - kicad does it like that */ + memset(sh, 0, sizeof(sh)); + if (LYSHS(side, MASK)) {sh[len].layer_mask = side | PCB_LYT_MASK; sh[len].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_rect_trdelta(&sh[len++], padXsize+mask*2, padYsize+mask*2, dx, dy);} + if (LYSHS(side, PASTE)) {sh[len].layer_mask = side | PCB_LYT_PASTE; sh[len].comb = PCB_LYC_AUTO; pcb_shape_rect_trdelta(&sh[len++], padXsize * paste_ratio + paste*2, padYsize * paste_ratio + paste*2, dx, dy);} + if (LYSHS(side, COPPER)) {sh[len].layer_mask = side | PCB_LYT_COPPER; pcb_shape_rect_trdelta(&sh[len++], padXsize, padYsize, dx, dy);} + if (len == 0) goto no_layer; + sh[len++].layer_mask = 0; + return pcb_pstk_new_from_shape(subc->data, X, Y, 0, rnd_false, clearance, sh); + } + else if ((strcmp(pad_shape, "oval") == 0) || (strcmp(pad_shape, "circle") == 0)) { + pcb_pstk_shape_t sh[4]; + memset(sh, 0, sizeof(sh)); + if (LYSHS(side, MASK)) {sh[len].layer_mask = side | PCB_LYT_MASK; sh[len].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_oval(&sh[len++], padXsize+mask*2, padYsize+mask*2);} + if (LYSHS(side, PASTE)) {sh[len].layer_mask = side | PCB_LYT_PASTE; sh[len].comb = PCB_LYC_AUTO; pcb_shape_oval(&sh[len++], padXsize * paste_ratio + paste*2, padYsize * paste_ratio + paste*2);} + if (LYSHS(side, COPPER)) {sh[len].layer_mask = side | PCB_LYT_COPPER; pcb_shape_oval(&sh[len++], padXsize, padYsize);} + if (len == 0) goto no_layer; + sh[len++].layer_mask = 0; + return pcb_pstk_new_from_shape(subc->data, X, Y, 0, rnd_false, clearance, sh); + } + else if (strcmp(pad_shape, "roundrect") == 0) { + pcb_pstk_shape_t sh[4]; + + if ((shape_arg <= 0.0) || (shape_arg > 0.5)) { + kicad_error(subtree, "Round rectangle ratio %f out of range: must be >0 and <=0.5", shape_arg); + return NULL; + } + + memset(sh, 0, sizeof(sh)); + if (LYSHS(side, MASK)) {sh[len].layer_mask = side | PCB_LYT_MASK; sh[len].comb = PCB_LYC_SUB | PCB_LYC_AUTO; pcb_shape_roundrect(&sh[len++], padXsize+mask*2, padYsize+mask*2, shape_arg);} + if (LYSHS(side, PASTE)) {sh[len].layer_mask = side | PCB_LYT_PASTE; sh[len].comb = PCB_LYC_AUTO; pcb_shape_roundrect(&sh[len++], padXsize * paste_ratio + paste*2, padYsize * paste_ratio + paste*2, shape_arg);} + if (LYSHS(side, COPPER)) {sh[len].layer_mask = side | PCB_LYT_COPPER; pcb_shape_roundrect(&sh[len++], padXsize, padYsize, shape_arg);} + if (len == 0) goto no_layer; + sh[len++].layer_mask = 0; + return pcb_pstk_new_from_shape(subc->data, X, Y, 0, rnd_false, clearance, sh); + } + + kicad_error(subtree, "unsupported pad shape '%s'.", pad_shape); + return NULL; + + no_layer:; + kicad_error(subtree, "SMD padstack ended up with no shape on any layer"); + return NULL; +} + +#undef LYSHT +#undef LYSHS + +static int kicad_make_pad(read_state_t *st, gsxl_node_t *subtree, pcb_subc_t *subc, const char *netname, int throughHole, int plated, rnd_coord_t moduleX, rnd_coord_t moduleY, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t padXsize, rnd_coord_t padYsize, double pad_rot, unsigned int moduleRotation, rnd_coord_t clearance, rnd_coord_t mask, rnd_coord_t paste, double paste_ratio, int zone_connect, rnd_coord_t drillx, rnd_coord_t drilly, const char *pin_name, const char *pad_shape, unsigned long *featureTally, int *moduleEmpty, pcb_layer_type_t smd_side, kicad_padly_t *layers, double shape_arg, double shape_arg2) +{ + pcb_pstk_t *ps; + unsigned long required; + + if (subc == NULL) + return kicad_error(subtree, "error - unable to create incomplete module definition."); + + X += moduleX; + Y += moduleY; + + if (throughHole) { + required = BV(0) | BV(1); + if ((*featureTally & required) != required) + return kicad_error(subtree, "malformed module pad/pin definition."); + if ((*featureTally & BV(3)) == 0) + drillx = drilly = RND_MIL_TO_COORD(30); /* CUCP#63: default size is hardwired in pcbnew/class_pad.cpp */ + ps = kicad_make_pad_thr(st, subtree, subc, X, Y, padXsize, padYsize, clearance, mask, paste, paste_ratio, drillx, drilly, pad_shape, plated, layers, shape_arg, shape_arg2); + } + else { + required = BV(0) | BV(1) | BV(2) | BV(5); + if ((*featureTally & required) != required) + return kicad_error(subtree, "error parsing incomplete module definition."); + ps = kicad_make_pad_smd(st, subtree, subc, X, Y, padXsize, padYsize, clearance, mask, paste, paste_ratio, pad_shape, smd_side, layers, shape_arg, shape_arg2); + } + + if (ps == NULL) + return kicad_error(subtree, "failed to created padstack"); + + if (zone_connect != 0) + save_zone_connect(st, ps, zone_connect, netname); + + *moduleEmpty = 0; + + pad_rot -= st->subc_rot; + if (pad_rot != 0.0) { + pcb_pstk_pre(ps); + + if (ps->xmirror) + ps->rot -= (double)pad_rot; + else + ps->rot += (double)pad_rot; + + if ((ps->rot > 360.0) || (ps->rot < -360.0)) + ps->rot = fmod(ps->rot, 360.0); + + if ((ps->rot == 360.0) || (ps->rot == -360.0)) + ps->rot = 0; + + /* force re-render the prototype */ + ps->protoi = -1; + pcb_pstk_get_tshape(ps); + pcb_pstk_bbox(ps); + + pcb_pstk_post(ps); + } + + if (pin_name != NULL) + pcb_attribute_put(&ps->Attributes, "term", pin_name); + + if (netname != NULL) { + pcb_net_term_t *term; + pcb_net_t *net; + + if (subc->refdes == NULL) + return kicad_error(subtree, "Can not connect pad to net '%s': no parent module refdes", netname); + + if (pin_name == NULL) + return kicad_error(subtree, "Can not connect pad to net '%s': no pad name", netname); + + net = pcb_net_get(st->pcb, &st->pcb->netlist[PCB_NETLIST_INPUT], netname, 0); + if (net == NULL) + return kicad_error(subtree, "Can not connect pad %s-%s to net '%s': no such net", subc->refdes, pin_name, netname); + + term = pcb_net_term_get(net, subc->refdes, pin_name, PCB_NETA_ALLOC); + if (term == NULL) + return kicad_error(subtree, "Failed to connect pad to net '%s'", netname); + } + + return 0; +} + +static int kicad_parse_fp_text(read_state_t *st, gsxl_node_t *n, pcb_subc_t *subc, unsigned long *tally, int *foundRefdes, double mod_rot, int mod_mirror) +{ + char *text; + int hidden = 0, refdes = 0; + + if (n->children != NULL && n->children->str != NULL) { + char *key = n->children->str; + if (n->children->next != NULL && n->children->next->str != NULL) { + text = n->children->next->str; + if (strcmp("reference", key) == 0) { + SEEN_NO_DUP(*tally, 7); + pcb_obj_id_fix(text); + pcb_attribute_put(&subc->Attributes, "refdes", text); + *foundRefdes = 1; + } + else if (strcmp("value", key) == 0) { + SEEN_NO_DUP(*tally, 8); + pcb_attribute_put(&subc->Attributes, "value", text); + } + else if (strcmp("descr", key) == 0) { + SEEN_NO_DUP(*tally, 12); + pcb_attribute_put(&subc->Attributes, "footprint", text); + } + else if (strcmp("hide", key) == 0) { + hidden = 1; + } + } + else /* only key, no value */ + text = key; + } + + if (hidden) + return 0; /* pcb-rnd policy: there are no hidden objects; if an object is not needed, it is not created */ + + if (strcmp("reference", n->children->str) == 0) + refdes = 1; + + if (kicad_parse_any_text(st, n->children->next->next, text, subc, mod_rot, mod_mirror, refdes) != 0) + return -1; + return 0; +} + +/* Parse the (layers) subtree, set layer bits in "layers" and return smd_side + (PCB_LYT_ANYWHERE indicating on which side a pad is supposed to be)*/ +pcb_layer_type_t kicad_parse_pad_layers(read_state_t *st, gsxl_node_t *subtree, gsxl_node_t *parent, kicad_padly_t *layers) +{ + gsxl_node_t *l; + pcb_layer_type_t smd_side = 0; + rnd_layer_id_t lid; + int numly = 0, side_from_lyt = 0; + + for(l = subtree; l != NULL; l = l->next) { + if (l->str != NULL) { + int any = 0; + pcb_layer_type_t lyt, lytor; + + if ((l->str[0] == 'F') || (l->str[0] == '*')) + smd_side |= PCB_LYT_TOP; + if ((l->str[0] == 'B') || (l->str[0] == '*')) + smd_side |= PCB_LYT_BOTTOM; + + if (l->str[0] == '*') { + any = 1; + l->str[0] = 'F'; + lid = kicad_get_layeridx(st, l->str); + if (lid < 0) { + l->str[0] = 'B'; + lid = kicad_get_layeridx(st, l->str); + } + l->str[0] = '*'; + } + else { + lid = kicad_get_layeridx(st, l->str); + side_from_lyt = 1; + } + + if (lid < 0) { + /* foreign language files have mismatched layer names in the stackup + and in the module layer reference. Work it around for a few known + cases */ + if (strcmp(l->str, "F.Cu")) { pcb_layer_list(st->pcb, PCB_LYT_COPPER | PCB_LYT_TOP, &lid, 1); smd_side |= PCB_LYT_TOP; } + else if (strcmp(l->str, "B.Cu")) { pcb_layer_list(st->pcb, PCB_LYT_COPPER | PCB_LYT_BOTTOM, &lid, 1); smd_side |= PCB_LYT_BOTTOM; } + else if (strcmp(l->str, "*.Cu")) pcb_layer_list(st->pcb, PCB_LYT_COPPER | PCB_LYT_TOP, &lid, 1); + } + + if (lid < 0) + return kicad_error(l, "Unknown pad layer %s\n", l->str); + + if (st->pcb == NULL) + lyt = st->fp_data->Layer[lid].meta.bound.type; + else + lyt = pcb_layer_flags(st->pcb, lid); + lytor = lyt & PCB_LYT_ANYTHING; + + if ((side_from_lyt) && (smd_side == 0) && (lyt & PCB_LYT_COPPER)) { + if (lyt & PCB_LYT_TOP) smd_side |= PCB_LYT_TOP; + if (lyt & PCB_LYT_BOTTOM) smd_side |= PCB_LYT_BOTTOM; + } + + if (any) { + layers->want[PCB_LYT_TOP] |= lytor; + layers->want[PCB_LYT_BOTTOM] |= lytor; + if (lytor & PCB_LYT_COPPER) + layers->want[PCB_LYT_INTERN] |= lytor; + } + else + layers->want[(lyt & PCB_LYT_ANYWHERE) & 7] |= lytor; + numly++; + } + else + return kicad_error(l, "unexpected empty/NULL module layer node"); + } + + if (numly == 0) { + kicad_warning(parent, "empty (layers) subtree in pad; assuming *.Cu"); + layers->want[PCB_LYT_TOP] |= PCB_LYT_COPPER; + layers->want[PCB_LYT_BOTTOM] |= PCB_LYT_COPPER; + layers->want[PCB_LYT_INTERN] |= PCB_LYT_COPPER; + } + + return smd_side; +} + +static int kicad_parse_pad_options(read_state_t *st, gsxl_node_t *subtree) +{ + gsxl_node_t *n; + for(n = subtree; n != NULL; n = n->next) { + if (strcmp(n->str, "clearance") == 0) { + if ((n->children == NULL) || (n->children->str == NULL)) + return kicad_error(n, "missing clearance option argument"); + if (strcmp(n->children->str, "outline")) + continue; /* normal */ + else if (strcmp(n->children->str, "convexhull")) + kicad_warning(n, "convexhull clearance not supported - going to render a normam clearance around the pad"); + else + return kicad_error(n, "unknwon clearance option argument %s", n->children->str); + } + else if (strcmp(n->str, "anchor") == 0) { + /* Ignore: CUCP#60: used only as a geometry placeholder for + connection calculations, which is not required in pcb-rnd. + Should never be located outside of the main pad shape */ + } + else + return kicad_error(n, "unknwon pad option %s", n->str); + } + return 0; +} + +TODO("eliminate this forward declaration by reordering the code") +static int kicad_parse_any_poly(read_state_t *st, gsxl_node_t *subtree, pcb_subc_t *subc, rnd_coord_t modx, rnd_coord_t mody); + +static int kicad_parse_gr_poly(read_state_t *st, gsxl_node_t *subtree) +{ + rnd_coord_t sx = 0, sy = 0; + pcb_subc_get_origin(st->primitive_subc, &sx, &sy); + return kicad_parse_any_poly(st, subtree, st->primitive_subc, sx, sy); +} + + +/* Parse a primitives subtree found in custom pads - create heavy terminal on each target layer */ +static int kicad_parse_primitives_(read_state_t *st, gsxl_node_t *primitives) +{ + static const dispatch_t disp[] = { + {"gr_line", kicad_parse_gr_line}, + {"gr_arc", kicad_parse_gr_arc}, + {"gr_circle", kicad_parse_gr_arc}, + {"gr_text", kicad_parse_gr_text}, + {"gr_poly", kicad_parse_gr_poly}, + {NULL, NULL} + }; + return kicad_foreach_dispatch(st, primitives, disp); +} + +static int kicad_parse_primitives(read_state_t *st, gsxl_node_t *primitives, pcb_subc_t *subc, const char *term, const kicad_padly_t *layers) +{ + int res, warned = 0; + const char *old_term; + pcb_subc_t *old_subc; + pcb_layer_t *old_ly; + rnd_layer_id_t loc, *typ; + rnd_layer_id_t ltypes[] = { PCB_LYT_COPPER, PCB_LYT_SILK, PCB_LYT_MASK, PCB_LYT_PASTE, 0}; + + old_subc = st->primitive_subc; + old_ly = st->primitive_ly; + old_term = st->primitive_term; + st->primitive_term = term; + st->primitive_subc = subc; + + for(loc = PCB_LYT_TOP; loc <= PCB_LYT_INTERN; loc++) { + for(typ = ltypes; *typ != 0; typ++) { + if (layers->want[loc] & (*typ)) { + pcb_layer_combining_t comb = 0; + if ((*typ) & (PCB_LYT_PASTE | PCB_LYT_MASK | PCB_LYT_SILK)) comb |= PCB_LYC_AUTO; + if ((*typ) & (PCB_LYT_MASK)) comb |= PCB_LYC_SUB; + st->primitive_ly = pcb_subc_get_layer(subc, loc | *typ, comb, 1, "pad", rnd_false); + if (st->primitive_ly != NULL) { + res = kicad_parse_primitives_(st, primitives); + if (!warned && ((*typ) & PCB_LYT_INTERN)) { + warned = 1; + kicad_warning(primitives, "custom pad shape on internal copper layer: creating it only on one layer\n"); + } + } + } + } + } + + st->primitive_term = old_term; + st->primitive_ly = old_ly; + st->primitive_subc = old_subc; + return res; +} + + +static int kicad_parse_pad(read_state_t *st, gsxl_node_t *n, pcb_subc_t *subc, unsigned long *tally, rnd_coord_t moduleX, rnd_coord_t moduleY, unsigned int moduleRotation, rnd_coord_t mod_clr, rnd_coord_t mod_mask, rnd_coord_t mod_paste, double mod_paste_ratio, int mod_zone_connect, int *moduleEmpty) +{ + gsxl_node_t *m; + rnd_coord_t x, y, drillx, drilly, sx, sy, clearance, mask = st->pad_to_mask_clearance*2, paste = 0; + const char *netname = NULL; + char *pin_name = NULL, *pad_shape = NULL; + unsigned long feature_tally = 0; + int through_hole = 0, plated = 0, definite_clearance = 0, zone_connect = mod_zone_connect; + pcb_layer_type_t smd_side; + double paste_ratio = mod_paste_ratio; + kicad_padly_t layers = {0}; + double shape_arg = 0.0, shape_arg2 = 0.0; + double rot = 0.0; + + sx = sy = RND_MIL_TO_COORD(60); /* CUCP#63: default size matching pcbnew/class_pad.cpp */ + + /* Kicad clearance hierarchy (top overrides bottom): + - pad clearance + - module clearance + - zone_clearance (from (setup)) + */ + clearance = 0; + mask = 0; + paste = 0; + + /* overwrite with module clearance if present */ + if (mod_clr != UNSPECIFIED) { + clearance = mod_clr; + definite_clearance = 1; + } + + if (mod_mask != UNSPECIFIED) + mask = mod_mask; + + if (mod_paste != UNSPECIFIED) + paste = mod_paste; + + if (n->children != 0 && n->children->str != NULL) { + pin_name = n->children->str; + pcb_obj_id_fix(pin_name); + SEEN_NO_DUP(feature_tally, 0); + if ((n->children->next == NULL) || (n->children->next->str == NULL)) + return kicad_error(n->children->next, "unexpected empty/NULL module pad type node"); + + through_hole = (strcmp("thru_hole", n->children->next->str) == 0) || (strcmp("np_thru_hole", n->children->next->str) == 0); + plated = through_hole && (n->children->next->str[0] != 'n'); + if (n->children->next->next != NULL && n->children->next->next->str != NULL) + pad_shape = n->children->next->next->str; + else + return kicad_error(n->children->next, "unexpected empty/NULL module pad shape node"); + } + else + return kicad_error(n->children, "unexpected empty/NULL module pad name node"); + + if (n->children->next->next->next == NULL || n->children->next->next->next->str == NULL) + return kicad_error(n->children->next->next, "unexpected empty/NULL module node"); + + for(m = n->children->next->next->next; m != NULL; m = m->next) { + if (m->str == NULL) + return kicad_error(m, "empty parameter in pad description"); + if (strcmp("at", m->str) == 0) { + + SEEN_NO_DUP(feature_tally, 1); + PARSE_COORD(x, m, m->children, "module pad X"); + PARSE_COORD(y, m, m->children->next, "module pad Y"); + PARSE_DOUBLE(rot, NULL, m->children->next->next, "module pad rotation"); + } + else if (strcmp("layers", m->str) == 0) { + SEEN_NO_DUP(feature_tally, 2); + smd_side = kicad_parse_pad_layers(st, m->children, m, &layers); + if (smd_side == -1) + return -1; + } + else if (strcmp("drill", m->str) == 0) { + gsxl_node_t *nd; + SEEN_NO_DUP(feature_tally, 3); + nd = m->children; + if (strcmp(nd->str, "offset") == 0) { + kicad_warning(nd, "Ignoring drill offset"); + nd = nd->next; + } + + if (nd == NULL) { + /* do nothing; may happen if there's only an offset */ + } + else if (strcmp(nd->str, "oval") == 0) { + PARSE_COORD(drillx, m, nd->next, "module pad oval drill X"); + PARSE_COORD(drilly, m, nd->next->next, "module pad oval drill Y"); + } + else { + PARSE_COORD(drillx, m, nd, "module pad round drill"); + drilly = drillx; + } + } + else if (strcmp("net", m->str) == 0) { + SEEN_NO_DUP(feature_tally, 4); + if ((m->children == NULL) || (m->children->str == NULL)) + return kicad_error(m, "unexpected empty/NULL module pad net node"); + if ((m->children->next == NULL) || (m->children->next->str == NULL)) + return kicad_error(m->children, "unexpected empty/NULL module pad net name node"); + netname = m->children->next->str; + } + else if (strcmp("size", m->str) == 0) { + SEEN_NO_DUP(feature_tally, 5); + PARSE_COORD(sx, m, m->children, "module pad size X"); + PARSE_COORD(sy, m, m->children->next, "module pad size Y"); + } + else if (strcmp("solder_mask_margin", m->str) == 0) { + SEEN_NO_DUP(feature_tally, 10); + PARSE_COORD(mask, m, m->children, "module pad mask margin"); + } + else if (strcmp("solder_mask_margin_ratio", m->str) == 0) { + /* This feature doesn't seem to exist in kicad 4 or 5 sources, ignore it */ + } + else if (strcmp("solder_paste_margin", m->str) == 0) { + SEEN_NO_DUP(feature_tally, 6); + PARSE_COORD(paste, m, m->children, "module pad paste margin"); + } + else if (strcmp("solder_paste_ratio", m->str) == 0) { + SEEN_NO_DUP(feature_tally, 6); + PARSE_DOUBLE(paste_ratio, m, m->children, "module pad solder mask ratio"); + } + else if (strcmp("clearance", m->str) == 0) { + SEEN_NO_DUP(feature_tally, 7); + PARSE_COORD(clearance, m, m->children, "module pad clearance"); + definite_clearance = 1; + } + else if (strcmp("primitives", m->str) == 0) { + if (kicad_parse_primitives(st, m->children, subc, pin_name, &layers) != 0) + return -1; + } + else if (strcmp("roundrect_rratio", m->str) == 0) { + SEEN_NO_DUP(feature_tally, 8); + PARSE_DOUBLE(shape_arg, m, m->children, "module pad roundrect_rratio"); + } + else if (strcmp("rect_delta", m->str) == 0) { + SEEN_NO_DUP(feature_tally, 8); + PARSE_DOUBLE(shape_arg, m, m->children, "module pad rect_delta"); + PARSE_DOUBLE(shape_arg2, m, m->children->next, "module pad rect_delta"); + } + else if (strcmp("options", m->str) == 0) { + SEEN_NO_DUP(feature_tally, 9); + if (kicad_parse_pad_options(st, m->children) != 0) + return -1; + } + else if (strcmp("zone_connect", m->str) == 0) { + SEEN_NO_DUP(feature_tally, 10); + PARSE_DOUBLE(zone_connect, m, m->children, "module pad zone_connect"); + } + else + return kicad_error(m, "Unknown pad argument: %s", m->str); + } + + if (subc != NULL) { + if (!definite_clearance) { + kicad_warning(n, "Couldn't determine pad clearance, using 0.25mm"); + clearance = st->zone_clearance; + } + if (kicad_make_pad(st, n, subc, netname, through_hole, plated, moduleX, moduleY, x, y, sx, sy, rot, moduleRotation, clearance, mask, paste, paste_ratio, zone_connect, drillx, drilly, pin_name, pad_shape, &feature_tally, moduleEmpty, smd_side, &layers, shape_arg, shape_arg2) != 0) + return -1; + } + + return 0; +} + +static int kicad_parse_poly_pts(read_state_t *st, gsxl_node_t *subtree, pcb_poly_t *polygon, rnd_coord_t xo, rnd_coord_t yo) +{ + gsxl_node_t *m; + rnd_coord_t x, y; + + if ((subtree == NULL) || (subtree->str == NULL)) + return kicad_error(subtree, "error parsing empty polygon."); + + if (strcmp("pts", subtree->str) != 0) + return kicad_error(subtree, "pts section vertices not found in polygon."); + + for(m = subtree->children; m != NULL; m = m->next) { + if ((m->str == NULL) || (strcmp("xy", m->str) != 0)) + return kicad_error(m, "empty pts element"); + + PARSE_COORD(x, m, m->children, "polygon vertex X"); + PARSE_COORD(y, m, m->children->next, "polygon vertex Y"); + pcb_poly_point_new(polygon, x + xo, y + yo); + } + return 0; +} + +static int kicad_parse_any_poly(read_state_t *st, gsxl_node_t *subtree, pcb_subc_t *subc, rnd_coord_t modx, rnd_coord_t mody) +{ + gsxl_node_t *n, *npts = NULL; + pcb_layer_t *ly = NULL; + rnd_coord_t width = 0; + unsigned long tally = 0; + pcb_poly_t *poly; + pcb_flag_t flags = pcb_flag_make(PCB_FLAG_CLEARPOLY); + + for(n = subtree; n != NULL; n = n->next) { + if (strcmp(n->str, "pts") == 0) { + SEEN_NO_DUP(tally, 1); + npts = n; + } + else if (strcmp(n->str, "layer") == 0) { + SEEN_NO_DUP(tally, 2); + PARSE_LAYER(ly, n->children, subc, "line"); + if (st->primitive_ly != NULL) + return kicad_error(n, "poly in this context shall not have layer specified"); + } + else if (strcmp(n->str, "status") == 0) { + SEEN_NO_DUP(tally, 3); + TODO("do the same as for other object's status"); + } + else if (strcmp(n->str, "tstamp") == 0) { + SEEN_NO_DUP(tally, 4); + /* ignore */ + } + else if (strcmp(n->str, "width") == 0) { + SEEN_NO_DUP(tally, 5); + PARSE_COORD(width, n, n->children, "fp_poly width"); + if (width != 0) { + TODO("need a core function for bloating the poly up but remember the original size?"); + kicad_warning(n, "Ignoring non-zero fp_poly width"); + } + } + else + return kicad_error(subtree, "Invalid fp_poly child: %s", n->str); + } + + if (npts == NULL) + return kicad_error(subtree, "missing pts subtree in fp_poly or gr_poly"); + + if (st->primitive_ly != NULL) + ly = st->primitive_ly; + if (ly == NULL) + return kicad_error(subtree, "missing layer subtree in fp_poly or gr_poly"); + + poly = pcb_poly_new(ly, 0, flags); + if (kicad_parse_poly_pts(st, npts, poly, modx, mody) < 0) + return -1; + + pcb_add_poly_on_layer(ly, poly); + pcb_poly_init_clip(subc->data, ly, poly); + + if (st->primitive_term != NULL) + pcb_attribute_put(&poly->Attributes, "term", st->primitive_term); + + return 0; +} + +static int kicad_parse_fp_poly(read_state_t *st, gsxl_node_t *subtree, pcb_subc_t *subc, rnd_coord_t modx, rnd_coord_t mody) +{ + return kicad_parse_any_poly(st, subtree, subc, modx, mody); +} + + +static int kicad_parse_module(read_state_t *st, gsxl_node_t *subtree) +{ + gsxl_node_t *n, *p; + rnd_layer_id_t lid = 0; + int on_bottom = 0, found_refdes = 0, module_empty = 1, module_defined = 0, i; + int mod_zone_connect = 1; /* default seems to be connect; see CUCP#57, case labeled "-1" */ + double mod_rot = 0, mod_paste_ratio = 0; + unsigned long tally = 0; + rnd_coord_t mod_x = 0, mod_y = 0, mod_clr = UNSPECIFIED, mod_mask = UNSPECIFIED, mod_paste = UNSPECIFIED; + char *mod_name; + pcb_subc_t *subc = NULL; + + if (st->module_pre_create) { + /* loading a module as a footprint - always create the subc in advance */ + subc = pcb_subc_new(); + pcb_subc_create_aux(subc, 0, 0, 0.0, 0); + pcb_attribute_put(&subc->Attributes, "refdes", "K1"); + if (st->pcb != NULL) { + pcb_subc_reg(st->pcb->Data, subc); + pcb_subc_bind_globals(st->pcb, subc); + } + } + + if (subtree->str == NULL) + return kicad_error(subtree, "module parsing failure: empty"); + + mod_name = subtree->str; + p = subtree->next; + if ((p != NULL) && (p->str != NULL) && (strcmp("locked", p->str) == 0)) { + p = p->next; + TODO("The module is locked, which is being ignored.\n"); + } + + SEEN_NO_DUP(tally, 0); + for(n = p, i = 0; n != NULL; n = n->next, i++) { + if (n->str == NULL) + return kicad_error(n, "empty module parameter"); + if (strcmp("layer", n->str) == 0) { /* need this to sort out ONSOLDER flags etc... */ + SEEN_NO_DUP(tally, 1); + if (n->children != NULL && n->children->str != NULL) { + pcb_layer_type_t lyt; + + lid = kicad_get_layeridx(st, n->children->str); + if (lid < 0) + return kicad_error(n->children, "module layer error - unhandled layer %s", n->children->str); + + if (st->pcb == NULL) + lyt = st->fp_data->Layer[lid].meta.bound.type; + else + lyt = pcb_layer_flags(st->pcb, lid); + + if (lyt & PCB_LYT_BOTTOM) + on_bottom = 1; + } + else + return kicad_error(n, "unexpected empty/NULL module layer node"); + } + else if (strcmp("tedit", n->str) == 0) { + SEEN_NO_DUP(tally, 2); + if (n->children != NULL && n->children->str != NULL) { + /* ingore time stamp */ + } + else + return kicad_error(n, "unexpected empty/NULL module tedit node"); + } + else if (strcmp("tstamp", n->str) == 0) { + ignore_value_nodup(n, tally, 3, "unexpected empty/NULL module tstamp node"); + } + else if (strcmp("attr", n->str) == 0) { + char *key; + + if ((n->children == NULL) || (n->children->str == NULL)) + return kicad_error(n, "unexpected empty/NULL module attr node"); + + key = rnd_concat("kicad_attr_", n->children->str, NULL); + pcb_attribute_put(&subc->Attributes, key, "1"); + free(key); + } + else if (strcmp("at", n->str) == 0) { + SEEN_NO_DUP(tally, 4); + PARSE_COORD(mod_x, n, n->children, "module X"); + PARSE_COORD(mod_y, n, n->children->next, "module Y"); + PARSE_DOUBLE(mod_rot, NULL, n->children->next->next, "module rotation"); + st->subc_rot = mod_rot; + + /* if we have been provided with a Module Name and location, create a new subc with default "" and "" for refdes and value fields */ + if (mod_name != NULL && module_defined == 0) { + module_defined = 1; /* but might be empty, wait and see */ + if (subc == NULL) { + subc = pcb_subc_new(); + /* modules are specified in rot=0; build time like that and rotate + the whole subc at the end. Text is special case because kicad + has no 'floater' - rotation is encoded both in text and subc + and it has to be subtracted from text later on */ + pcb_subc_create_aux(subc, mod_x, mod_y, 0.0, on_bottom); + pcb_attribute_put(&subc->Attributes, "refdes", "K1"); + } + if (st->pcb != NULL) { + pcb_subc_reg(st->pcb->Data, subc); + pcb_subc_bind_globals(st->pcb, subc); + } + } + } + else if (strcmp("clearance", n->str) == 0) { + PARSE_COORD(mod_clr, n, n->children, "module pad clearance"); + SEEN_NO_DUP(tally, 9); + } + else if (strcmp("solder_mask_margin", n->str) == 0) { + PARSE_COORD(mod_mask, n, n->children, "module pad solder_mask_margin"); + SEEN_NO_DUP(tally, 10); + } + else if (strcmp("model", n->str) == 0) { + TODO("save this as attribute"); + } + else if (strcmp("fp_text", n->str) == 0) { + kicad_parse_fp_text(st, n, subc, &tally, &found_refdes, mod_rot, on_bottom); + } + else if (strcmp("descr", n->str) == 0) { + SEEN_NO_DUP(tally, 11); + if ((n->children == NULL) || (n->children->str == NULL)) + return kicad_error(n, "unexpected empty/NULL module descr node"); + pcb_attribute_put(&subc->Attributes, "kicad_descr", n->children->str); + } + else if (strcmp("tags", n->str) == 0) { + SEEN_NO_DUP(tally, 12); + if ((n->children == NULL) || (n->children->str == NULL)) + return kicad_error(n, "unexpected empty/NULL module tags node"); + pcb_attribute_put(&subc->Attributes, "kicad_tags", n->children->str); + } + else if (strcmp("solder_paste_margin", n->str) == 0) { + PARSE_COORD(mod_paste, n, n->children, "module pad solder_paste_margin"); + SEEN_NO_DUP(tally, 13); + } + else if (strcmp("solder_paste_ratio", n->str) == 0) { + PARSE_DOUBLE(mod_paste_ratio, n, n->children, "module pad solder_paste_ratio"); + SEEN_NO_DUP(tally, 14); + } + else if (strcmp("zone_connect", n->str) == 0) { + PARSE_INT(mod_zone_connect, n, n->children, "module pad zone_connect"); + SEEN_NO_DUP(tally, 15); + } + else if (strcmp("path", n->str) == 0) { + ignore_value_nodup(n, tally, 16, "unexpected empty/NULL module model node"); + } + else if (strcmp("pad", n->str) == 0) { + if (kicad_parse_pad(st, n, subc, &tally, mod_x, mod_y, mod_rot, mod_clr, mod_mask, mod_paste, mod_paste_ratio, mod_zone_connect, &module_empty) != 0) + return -1; + } + else if (strcmp("fp_line", n->str) == 0) { + if (kicad_parse_any_line(st, n->children, subc, 0, 0) != 0) + return -1; + } + else if (strcmp("fp_poly", n->str) == 0) { + if (kicad_parse_fp_poly(st, n->children, subc, mod_x, mod_y) != 0) + return -1; + } + else if ((strcmp("fp_arc", n->str) == 0) || (strcmp("fp_circle", n->str) == 0)) { + if (kicad_parse_any_arc(st, n->children, subc) != 0) + return -1; + } + else if (strncmp("autoplace", n->str, 9) == 0) { + /* ignore */ + } + else + return kicad_error(n, "Unknown module argument: %s\n", n->str); + } + + if (subc == NULL) + return kicad_error(subtree, "unable to create incomplete subc."); + + if ((mod_name != NULL) && (*mod_name != '\0') && (pcb_attribute_get(&subc->Attributes, "footprint") == NULL)) + pcb_attribute_put(&subc->Attributes, "footprint", mod_name); + + pcb_subc_bbox(subc); + if (st->pcb != NULL) { + if (st->pcb->Data->subc_tree == NULL) + st->pcb->Data->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(st->pcb->Data->subc_tree, (rnd_box_t *)subc); + pcb_subc_rebind(st->pcb, subc); + } + else + pcb_subc_reg(st->fp_data, subc); + + if ((mod_rot == 90) || (mod_rot == 180) || (mod_rot == 270)) { + /* lossles module rotation for round steps */ + mod_rot = rnd_round(mod_rot / 90); + pcb_subc_rotate90(subc, mod_x, mod_y, mod_rot); + } + else if (mod_rot != 0) + pcb_subc_rotate(subc, mod_x, mod_y, cos(mod_rot/RND_RAD_TO_DEG), sin(mod_rot/RND_RAD_TO_DEG), mod_rot); + + st->subc_rot = 0.0; + st->last_sc = subc; + return 0; +} + +static int kicad_parse_zone(read_state_t *st, gsxl_node_t *subtree) +{ + gsxl_node_t *n, *m; + unsigned long tally = 0, required; + pcb_poly_t *polygon = NULL; + pcb_flag_t flags = pcb_flag_make(PCB_FLAG_CLEARPOLY); + pcb_layer_t *ly = NULL; + char *net_name = NULL; + + for(n = subtree; n != NULL; n = n->next) { + if (n->str == NULL) + return kicad_error(n, "empty zone parameter"); + if (strcmp("net", n->str) == 0) { + ignore_value_nodup(n, tally, 0, "unexpected zone net null node."); + } + else if (strcmp("net_name", n->str) == 0) { + SEEN_NO_DUP(tally, 1); + net_name = n->children->str; + } + else if (strcmp("tstamp", n->str) == 0) { + ignore_value_nodup(n, tally, 2, "unexpected zone tstamp null node."); + } + else if (strcmp("hatch", n->str) == 0) { + SEEN_NO_DUP(tally, 3); + if ((n->children == NULL) || (n->children->str == NULL)) + return kicad_error(n, "unexpected zone hatch null node."); + SEEN_NO_DUP(tally, 4); /* same as ^= 1 was */ + if ((n->children->next == NULL) || (n->children->next->str == NULL)) + return kicad_error(n, "unexpected zone hatching null node."); + SEEN_NO_DUP(tally, 5); + } + else if (strcmp("connect_pads", n->str) == 0) { + SEEN_NO_DUP(tally, 6); + if (n->children != NULL && n->children->str != NULL && (strcmp("clearance", n->children->str) == 0) && (n->children->children->str != NULL)) { + SEEN_NO_DUP(tally, 7); /* same as ^= 1 was */ + } + else if (n->children != NULL && n->children->str != NULL && n->children->next->str != NULL) { + SEEN_NO_DUP(tally, 8); /* same as ^= 1 was */ + if (n->children->next != NULL && n->children->next->str != NULL && n->children->next->children != NULL && n->children->next->children->str != NULL) { + if (strcmp("clearance", n->children->next->str) == 0) { + SEEN_NO_DUP(tally, 9); + } + else + kicad_warning(n->children->next, "Unrecognised zone connect_pads option %s\n", n->children->next->str); + } + } + } + else if (strcmp("layers", n->str) == 0) { + TODO("CUCP#49"); + kicad_warning(n->children, "multi-layer zones (e.g. keepouts affecting many layers) are not yet supported - polygon omitted"); + return 0; + } + else if (strcmp("layer", n->str) == 0) { + SEEN_NO_DUP(tally, 10); + PARSE_LAYER(ly, n->children, NULL, "zone polygon"); + if (ly != NULL) { + polygon = pcb_poly_new(ly, 0, flags); + if (polygon == NULL) + return kicad_error(n->children, "Failed to create polygon"); + } + kicad_warning(n->children, "no polygon layer - polygon omitted (only single layer polygons are supported)"); + } + else if (strcmp("polygon", n->str) == 0) { + if (polygon == NULL) + return kicad_error(n->children, "Failed to create polygon, can not add points"); + if (kicad_parse_poly_pts(st, n->children, polygon, 0, 0) < 0) + return -1; + } + else if (strcmp("fill", n->str) == 0) { + SEEN_NO_DUP(tally, 11); + for(m = n->children; m != NULL; m = m->next) { + if (m->str == NULL) + return kicad_error(m, "empty fill parameter"); + if (strcmp("arc_segments", m->str) == 0) { + ignore_value(m, "unexpected zone arc_segment null node."); + } + else if (strcmp("thermal_gap", m->str) == 0) { + ignore_value(m, "unexpected zone thermal_gap null node."); + } + else if (strcmp("thermal_bridge_width", m->str) == 0) { + ignore_value(m, "unexpected zone thermal_bridge_width null node."); + } + else if (strcmp("yes", m->str) == 0) { + /* ignored */ + } + else + kicad_warning(m, "Unknown zone fill argument:\t%s\n", m->str); + } + } + else if (strcmp("min_thickness", n->str) == 0) { + ignore_value_nodup(n, tally, 12, "unexpected zone min_thickness null node"); + } + else if (strcmp("priority", n->str) == 0) { + ignore_value_nodup(n, tally, 13, "unexpected zone min_thickness null node."); + } + else if (strcmp("filled_polygon", n->str) == 0) { + /* Ignore fill type: it's purely on-screen visual, doesn't affect data */ + /* doc: trunk/doc/alien_formats/io_kicad/hatch.txt */ + } + else + kicad_warning(n, "Unknown polygon argument:\t%s\n", n->str); + } + + required = BV(10); /* layer at a minimum */ + if ((tally & required) != required) + return kicad_error(subtree, "can not create zone because required fields are missing"); + + if (polygon != NULL) { + pcb_add_poly_on_layer(ly, polygon); + pcb_poly_init_clip(st->pcb->Data, ly, polygon); + + if (st->poly2net_inited) + htpp_set(&st->poly2net, polygon, net_name); + } + return 0; +} + + +/* Parse a board from &st->dom into st->pcb */ +static int kicad_parse_pcb(read_state_t *st) +{ + int ret; + + static const dispatch_t disp[] = { /* possible children of root */ + {"version", kicad_parse_version}, + {"host", kicad_parse_nop}, + {"general", kicad_parse_general}, + {"page", kicad_parse_page_size}, + {"title_block", kicad_parse_title_block}, + {"layers", kicad_parse_layer_definitions}, /* board layer defs */ + {"setup", kicad_parse_setup}, + {"net", kicad_parse_net}, /* net labels if child of root, otherwise net attribute of element */ + {"net_class", kicad_parse_nop}, + {"module", kicad_parse_module}, /* for footprints */ + {"dimension", kicad_parse_nop}, /* for dimensioning features */ + {"gr_line", kicad_parse_gr_line}, + {"gr_arc", kicad_parse_gr_arc}, + {"gr_circle", kicad_parse_gr_arc}, + {"gr_text", kicad_parse_gr_text}, + {"target", kicad_parse_target}, + {"via", kicad_parse_via}, + {"segment", kicad_parse_segment}, + {"zone", kicad_parse_zone}, /* polygonal zones */ + {NULL, NULL} + }; + + /* require the root node to be kicad_pcb */ + if ((st->dom.root->str == NULL) || (strcmp(st->dom.root->str, "kicad_pcb") != 0)) + return -1; + + /* Call the corresponding subtree parser for each child node of the root + node; if any of them fail, parse fails */ + ret = kicad_foreach_dispatch(st, st->dom.root->children, disp); + + /* create an extra layer for plated slots so they show up properly */ + { + pcb_layergrp_t *g = pcb_get_grp_new_misc(st->pcb); + rnd_layer_id_t lid = pcb_layer_create(st->pcb, g - st->pcb->LayerGroups.grp, "plated_slots", 0); + pcb_layer_t *ly = pcb_get_layer(st->pcb->Data, lid); + g->ltype = PCB_LYT_MECH; + pcb_layergrp_set_purpose(g, "proute", 0); + if (ly != NULL) + ly->comb = PCB_LYC_AUTO; + } + + return ret; +} + +static gsx_parse_res_t kicad_parse_file(FILE *FP, gsxl_dom_t *dom) +{ + int c; + gsx_parse_res_t res; + + gsxl_init(dom, gsxl_node_t); + dom->parse.line_comment_char = '#'; + do { + c = fgetc(FP); + } while((res = gsxl_parse_char(dom, c)) == GSX_RES_NEXT); + + if (res == GSX_RES_EOE) { + /* compact and simplify the tree */ + gsxl_compact_tree(dom); + } + + return res; +} + +int io_kicad_read_pcb(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest) +{ + int readres = 0, clipi = 0; + read_state_t st; + gsx_parse_res_t res; + FILE *FP; + + FP = rnd_fopen(&PCB->hidlib, Filename, "r"); + if (FP == NULL) + return -1; + + /* set up the parse context */ + memset(&st, 0, sizeof(st)); + + st.pcb = Ptr; + st.Filename = Filename; + st.settings_dest = settings_dest; + htsi_init(&st.layer_k2i, strhash, strkeyeq); + htpp_init(&st.poly2net, ptrhash, ptrkeyeq); + st.poly2net_inited = 1; + + /* A0 */ + st.width[DIM_FALLBACK] = RND_MM_TO_COORD(1189.0); + st.height[DIM_FALLBACK] = RND_MM_TO_COORD(841.0); + st.dim_valid[DIM_FALLBACK] = 1; + + /* load the file into the dom */ + res = kicad_parse_file(FP, &st.dom); + fclose(FP); + + if (res == GSX_RES_EOE) { + /* recursively parse the dom */ + if ((st.dom.root->str != NULL) && (strcmp(st.dom.root->str, "module") == 0)) { + Ptr->is_footprint = 1; + st.ver = 4; + kicad_create_fp_layers(&st, st.dom.root); + st.module_pre_create = 1; + readres = kicad_parse_module(&st, st.dom.root->children); + +/* if (readres == 0) { + pcb_layergrp_upgrade_to_pstk(Ptr); + }*/ + } + else { + pcb_data_clip_inhibit_inc(st.pcb->Data); + readres = kicad_parse_pcb(&st); + clipi = 1; + } + } + else + readres = -1; + + exec_zone_connect(&st); + htpp_uninit(&st.poly2net); + + /* clean up */ + gsxl_uninit(&st.dom); + + pcb_layer_auto_fixup(Ptr); + + if (pcb_board_normalize(Ptr) > 0) + rnd_message(RND_MSG_WARNING, "Had to make changes to the coords so that the design fits the board.\n"); + pcb_layer_colors_from_conf(Ptr, 1); + + { /* free layer hack */ + htsi_entry_t *e; + for(e = htsi_first(&st.layer_k2i); e != NULL; e = htsi_next(&st.layer_k2i, e)) + free(e->key); + htsi_uninit(&st.layer_k2i); + } + + /* enable fallback to the default font picked up when creating the based + PCB (loading the default PCB), because we won't get a font from KiCad. */ + st.pcb->fontkit.valid = rnd_true; + + if (clipi) + pcb_data_clip_inhibit_dec(st.pcb->Data, rnd_true); + + + return readres; +} + +int io_kicad_parse_module(pcb_plug_io_t *ctx, pcb_data_t *Ptr, const char *name, const char *subfpname) +{ + int mres; + pcb_fp_fopen_ctx_t fpst; + FILE *f; + read_state_t st; + gsx_parse_res_t res; + + f = pcb_fp_fopen(&conf_core.rc.library_search_paths, name, &fpst, NULL); + + if (f == NULL) { + pcb_fp_fclose(f, &fpst); + return -1; + } + + /* set up the parse context */ + memset(&st, 0, sizeof(st)); + st.pcb = NULL; + st.fp_data = Ptr; + st.Filename = fpst.filename; + st.settings_dest = RND_CFR_invalid; + st.auto_layers = 1; + + res = kicad_parse_file(f, &st.dom); + pcb_fp_fclose(f, &fpst); + + if (res != GSX_RES_EOE) { + if (!pcb_io_err_inhibit) + rnd_message(RND_MSG_ERROR, "Error parsing s-expression '%s'\n", name); + gsxl_uninit(&st.dom); + return -1; + } + + if ((st.dom.root->str == NULL) || (strcmp(st.dom.root->str, "module") != 0)) { + rnd_message(RND_MSG_ERROR, "Wrong root node '%s', expected 'module'\n", st.dom.root->str); + gsxl_uninit(&st.dom); + return -1; + } + + htsi_init(&st.layer_k2i, strhash, strkeyeq); + + st.module_pre_create = 1; + mres = kicad_parse_module(&st, st.dom.root->children); +/* if (mres == 0) + pcb_data_clip_polys(sc->data);*/ + + gsxl_uninit(&st.dom); + return mres; +} + +int io_kicad_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f) +{ + char line[1024], *s; + + if ((typ != PCB_IOT_PCB) && (typ != PCB_IOT_FOOTPRINT)) + return 0; /* support only boards for now - kicad footprints are in the legacy format */ + + while(!(feof(f))) { + if (fgets(line, sizeof(line), f) != NULL) { + s = line; + while(isspace(*s)) + s++; /* strip leading whitespace */ + if ((strncmp(s, "(kicad_pcb", 10) == 0) && (typ == PCB_IOT_PCB)) /* valid root */ + return 1; + if (strncmp(s, "(module", 7) == 0) /* valid root */ + return 1; + if ((*s == '\r') || (*s == '\n') || (*s == '#') || (*s == '\0')) /* ignore empty lines and comments */ + continue; + /* non-comment, non-empty line - and we don't have our root -> it's not an s-expression */ + return 0; + } + } + + /* hit eof before seeing a valid root -> bad */ + return 0; +} + +/* Decide about the type of a footprint file: + it is a kicad mdoule if the first non-comment is "(module" + No tags are saved. +*/ +pcb_plug_fp_map_t *io_kicad_map_footprint(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags) +{ + int c, comment_len; + int first_module = 1; + long pos = 0; + enum { + ST_WS, + ST_COMMENT, + ST_MODULE + } state = ST_WS; + + while ((c = fgetc(f)) != EOF) { + if (pos++ > 1024) break; /* header must be in the first kilobyte */ + switch (state) { + case ST_MODULE: + if (isspace(c)) + break; + if (c == '(') { + head->type = PCB_FP_FILE; + goto out; + } + case ST_WS: + if (isspace(c)) + break; + if (c == '#') { + comment_len = 0; + state = ST_COMMENT; + break; + } + else if ((first_module) && (c == '(')) { + char s[8]; + fgets(s, 7, f); + s[6] = '\0'; + if (strcmp(s, "module") == 0) { + state = ST_MODULE; + break; + } + } + first_module = 0; + /* fall-thru for detecting @ */ + case ST_COMMENT: + comment_len++; + if ((c == '\r') || (c == '\n')) + state = ST_WS; + break; + } + } + +out:; + return head; +} Index: tags/2.3.0/src_plugins/io_kicad/read.h =================================================================== --- tags/2.3.0/src_plugins/io_kicad/read.h (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/read.h (revision 33253) @@ -0,0 +1,37 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * Copyright (C) 2016 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include +#include "data.h" + +int io_kicad_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); +int io_kicad_read_pcb(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest); +int io_kicad_parse_module(pcb_plug_io_t *ctx, pcb_data_t *Ptr, const char *name, const char *subfpname); +pcb_plug_fp_map_t *io_kicad_map_footprint(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags); + Index: tags/2.3.0/src_plugins/io_kicad/read_net.c =================================================================== --- tags/2.3.0/src_plugins/io_kicad/read_net.c (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/read_net.c (revision 33253) @@ -0,0 +1,307 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Schematics/netlist import action for KiCad's eeschema */ + +#include "config.h" + +#include +#include + +#include "read_net.h" + +#include "board.h" +#include "data.h" +#include "plug_import.h" +#include +#include +#include +#include + +#include +#include +#include + +#define if_strval(node, name) \ + if (strcmp(node->str, #name) == 0) { \ + if (name != NULL) { \ + rnd_message(RND_MSG_ERROR, "Invalid eeschema: multiple %s subtrees\n", #name); \ + return -1; \ + } \ + if (node->children != NULL) \ + name = node->children->str; \ + } + +#define if_subtree(node, name) \ + if (strcmp(node->str, #name) == 0) { \ + if (name != NULL) { \ + rnd_message(RND_MSG_ERROR, "Invalid eeschema: multiple %s subtrees\n", #name); \ + return -1; \ + } \ + name = node; \ + } + +#define req_subtree(name) \ + if (name == NULL) { \ + rnd_message(RND_MSG_ERROR, "Invalid eeschema: missing %s subtree\n", #name); \ + return -1; \ + } \ + + +static int eeschema_parse_net(gsxl_dom_t *dom) +{ + gsxl_node_t *i, *net, *c, *n, *version = NULL, *components = NULL, *nets = NULL; + + /* check the header */ + if (strcmp(dom->root->str, "export") != 0) { + rnd_message(RND_MSG_ERROR, "Invalid eeschema netlist header: not an export\n"); + return -1; + } + + for(n = dom->root->children; n != NULL; n = n->next) { + if_subtree(n, version) + else if_subtree(n, components) + else if_subtree(n, nets) + } + + req_subtree(version); + req_subtree(components); + req_subtree(nets); + + if ((version->children == NULL) || (strcmp(version->children->str, "D") != 0)) { + rnd_message(RND_MSG_ERROR, "Invalid eeschema version: expected 'D', got '%s'\n", version->children->str); + return -1; + } + + /* Load the elements */ + rnd_actionva(&PCB->hidlib, "ElementList", "start", NULL); + + for(c = components->children; c != NULL; c = c->next) { + const char *ref = NULL, *value = NULL, *footprint = NULL; + if (strcmp(c->str, "comp") != 0) + continue; + for(n = c->children; n != NULL; n = n->next) { + if_strval(n, ref) + else if_strval(n, value) + else if_strval(n, footprint) + } + if (ref == NULL) { + rnd_message(RND_MSG_WARNING, "eeschema: ignoring component with no refdes\n"); + continue; + } + if (footprint == NULL) { + rnd_message(RND_MSG_WARNING, "eeschema: ignoring component %s with no footprint\n", ref); + continue; + } + rnd_actionva(&PCB->hidlib, "ElementList", "Need", ref, footprint, value == NULL ? "" : value, NULL); + } + + rnd_actionva(&PCB->hidlib, "ElementList", "Done", NULL); + + /* Load the netlist */ + + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + + for(net = nets->children; net != NULL; net = net->next) { + const char *netname = NULL, *code = NULL, *name = NULL; + char refpin[256]; + + if (strcmp(net->str, "net") != 0) + continue; + + for(n = net->children; n != NULL; n = n->next) { + if_strval(n, code) + else if_strval(n, name) + else if (strcmp(n->str, "node") == 0) { + const char *ref = NULL, *pin = NULL; + + /* load node params */ + for(i = n->children; i != NULL; i = i->next) { + if_strval(i, ref) + else if_strval(i, pin) + } + + /* find out the net name */ + if (netname == NULL) { + if ((name != NULL) && (*name != '\0')) + netname = name; + else + netname = code; + } + if (netname == NULL) { + rnd_message(RND_MSG_WARNING, "eeschema: ignoring pins of incomplete net\n"); + continue; + } + + /* do the binding */ + if ((ref == NULL) || (pin == NULL)) { + rnd_message(RND_MSG_WARNING, "eeschema: ignoring incomplete connection to net %s: refdes=%s pin=%s \n", netname, ref, pin); + continue; + } + rnd_snprintf(refpin, sizeof(refpin), "%s-%s", ref, pin); + rnd_actionva(&PCB->hidlib, "Netlist", "Add", netname, refpin, NULL); + } + } + } + + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + + return 0; +} + + + +static int eeschema_load(const char *fname_net) +{ + FILE *fn; + gsxl_dom_t dom; + int c, ret = 0; + gsx_parse_res_t res; + + fn = rnd_fopen(&PCB->hidlib, fname_net, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname_net); + return -1; + } + + gsxl_init(&dom, gsxl_node_t); + + dom.parse.line_comment_char = '#'; + do { + c = fgetc(fn); + } while((res = gsxl_parse_char(&dom, c)) == GSX_RES_NEXT); + fclose(fn); + + if (res == GSX_RES_EOE) { + /* compact and simplify the tree */ + gsxl_compact_tree(&dom); + + /* recursively parse the dom */ + ret = eeschema_parse_net(&dom); + } + else + ret = -1; + + /* clean up */ + gsxl_uninit(&dom); + + return ret; +} + +const char pcb_acts_LoadeeschemaFrom[] = "LoadEeschemaFrom(filename)"; +const char pcb_acth_LoadeeschemaFrom[] = "Loads the specified eeschema .net file - the netlist must be an s-expression."; +fgw_error_t pcb_act_LoadeeschemaFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + static char *default_file = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadeeschemaFrom, fname = argv[1].val.str); + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Load eeschema netlist file...", + "Picks a eeschema netlist file to load.\n", + default_file, ".net", NULL, "eeschema", RND_HID_FSD_READ, NULL); + if (fname == NULL) + return 1; + if (default_file != NULL) { + free(default_file); + default_file = NULL; + } + } + + RND_ACT_IRES(eeschema_load(fname)); + return 0; +} + + +static int eeschema_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + unsigned int n, good = 0; + FILE *f; + + if ((aspects != IMPORT_ASPECT_NETLIST) && (numargs == 1)) + return 0; /* only pure netlist import is supported with a single input file */ + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + for(n = 0; n < 32; n++) { + char *s, line[1024]; + s = fgets(line, sizeof(line), f); + if (s == NULL) + break; + while(isspace(*s)) s++; + if (strstr(s, "(design") != NULL) + good |= 1; + else if (strstr(s, "(export") != NULL) + good |= 2; + if (good == (1|2)) { + fclose(f); + return 100; + } + } + + fclose(f); + return 0; +} + + +static int eeschema_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **fns, int numfns) +{ + if (numfns != 1) { + rnd_message(RND_MSG_ERROR, "import_eeschema: requires exactly 1 input file name\n"); + return -1; + } + return eeschema_load(fns[0]); +} + +static pcb_plug_import_t import_eeschema; + +void pcb_eeschema_uninit(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_eeschema); +} + +void pcb_eeschema_init(void) +{ + /* register the IO hook */ + import_eeschema.plugin_data = NULL; + + import_eeschema.fmt_support_prio = eeschema_support_prio; + import_eeschema.import = eeschema_import; + import_eeschema.name = "eeschema"; + import_eeschema.desc = "schamtics from KiCad's eeschema"; + import_eeschema.ui_prio = 50; + import_eeschema.single_arg = 1; + import_eeschema.all_filenames = 1; + import_eeschema.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_eeschema); +} Index: tags/2.3.0/src_plugins/io_kicad/read_net.h =================================================================== --- tags/2.3.0/src_plugins/io_kicad/read_net.h (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/read_net.h (revision 33253) @@ -0,0 +1,11 @@ +#include +#include + +extern const char pcb_acts_LoadeeschemaFrom[]; +extern const char pcb_acth_LoadeeschemaFrom[]; +fgw_error_t pcb_act_LoadeeschemaFrom(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv); + + +void pcb_eeschema_init(void); +void pcb_eeschema_uninit(void); + Index: tags/2.3.0/src_plugins/io_kicad/uniq_name.c =================================================================== --- tags/2.3.0/src_plugins/io_kicad/uniq_name.c (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/uniq_name.c (revision 33253) @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include "config.h" +#include "uniq_name.h" +#include + +static const char *unm_default_unnamed = "unnamed"; +static const char *unm_default_suffix_sep = "_dup"; + +void unm_init(unm_t *state) +{ + state->unnamed = unm_default_unnamed; + state->suffix_sep = unm_default_suffix_sep; + htsp_init(&state->seen, strhash, strkeyeq); + state->ctr = 0; +} + + +void unm_uninit(unm_t *state) +{ + htsp_entry_t *e; + for (e = htsp_first(&state->seen); e; e = htsp_next(&state->seen, e)) { + free(e->key); + htsp_delentry(&state->seen, e); + } + htsp_uninit(&state->seen); +} + +const char *unm_name(unm_t *state, const char *orig_name, void *user_data) +{ + int l1, l2; + char *name, *end; + const char *head; + + if ((orig_name == NULL) || (*orig_name == '\0')) { + if (!htsp_has(&state->seen, (char *)state->unnamed)) { + name = rnd_strdup(state->unnamed); + htsp_set(&state->seen, name, user_data); + return name; + } + head = state->unnamed; + l1 = strlen(state->unnamed); + l2 = strlen(state->suffix_sep); + } + else { + if (!htsp_has(&state->seen, (char *)orig_name)) { + name = rnd_strdup(orig_name); + htsp_set(&state->seen, name, user_data); + return name; + } + else { + head = orig_name; + l1 = strlen(orig_name); + l2 = strlen(state->suffix_sep); + } + } + + /* have to generate a new name, allocate memory and print the static part + leave end to point where the integer part goes + 21 is large enough to store the widest 64 bit integer decimal, and a \0 */ + end = name = malloc(l1+l2+21); + memcpy(end, head, l1); end += l1; + memcpy(end, state->suffix_sep, l2); end += l2; + + /* look for the first unused entry with this suffix. Note: the entries + this function creates won't collide as ctr is a state of the group, but + it is possible that a new name collides with a past unsuffixed orig_name; + all in all, this loop should exit in the first iteration */ + do { + sprintf(end, "%lu", state->ctr++); + } while(htsp_has(&state->seen, name)); + + htsp_set(&state->seen, name, user_data); + return name; +} Index: tags/2.3.0/src_plugins/io_kicad/uniq_name.h =================================================================== --- tags/2.3.0/src_plugins/io_kicad/uniq_name.h (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/uniq_name.h (revision 33253) @@ -0,0 +1,32 @@ +#ifndef PCB_UNIQ_NAME_H +#define PCB_UNIQ_NAME_H + +#include + +typedef struct unm_s { + const char *unnamed; /* name to use when orig_name is NULL */ + const char *suffix_sep; /* separator for the suffix appended to generate unique names */ + htsp_t seen; /* hash for storing names already handed out */ + unsigned long int ctr; /* duplication counter - this will become the suffix for duplicated items */ +} unm_t; + +/* Initialize a new group of unique names */ +void unm_init(unm_t *state); + +/* Free all memory claimed by the group */ +void unm_uninit(unm_t *state); + +/* Generate and return a unique name: + - if orig_name is NULL, generate an unnamed item + - if orig_name is not-NULL and is unseen so far, return a copy of orig_name + - if orig_name is not-NULL and has been already seen, return a modified version + + Corners: + - an empty, non-NULL orig_name handled as if it was NULL + - the first "unnamed" entry is returned without suffix + + Strings returned are newly allocated and can be used until unm_uninit() + is called on state. */ +const char *unm_name(unm_t *state, const char *orig_name, void *user_data); + +#endif Index: tags/2.3.0/src_plugins/io_kicad/write.c =================================================================== --- tags/2.3.0/src_plugins/io_kicad/write.c (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/write.c (revision 33253) @@ -0,0 +1,1060 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2018..2020 Tibor 'Igor2' Palinkas + * Copyright (C) 2016 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include +#include "config.h" +#include +#include "board.h" +#include "plug_io.h" +#include +#include "uniq_name.h" +#include "data.h" +#include "write.h" +#include "layer.h" +#include "netlist.h" +#include "obj_pstk_inlines.h" +#include "funchash_core.h" + +#include "../src_plugins/lib_compat_help/pstk_compat.h" + +/* When non-zero, introduce an offset to move the whole board to the center of the page */ +static int force_center = 0; + +/* if implicit outline needs to be drawn, use lines of this thickness */ +#define KICAD_OUTLINE_THICK (RND_MIL_TO_COORD(10)) + +#define KICAD_MAX_LAYERS 64 +typedef struct { + FILE *f; /* output file */ + pcb_board_t *pcb; /* board being exported */ + rnd_coord_t ox, oy; /* move every object by this origin */ + struct { + pcb_layergrp_t *grp; + char name[32]; /* kicad layer name */ + const char *param; + int is_sig; + } layer[KICAD_MAX_LAYERS]; /* pcb-rnd layer groups indexed by kicad's stackup */ + int num_layers; /* number of groups in use */ +} wctx_t; + +TODO("remove these few structs and the table below in favor of layertab.[ch]") +typedef enum { + FLP_COP_FIRST, + FLP_COP_INT, + FLP_COP_LAST, + FLP_FIXED, /* fixed, static, hand-assigned number - AVOID USING THIS */ + FLP_MISC /* auto-number from the last known layer */ +} fixed_layer_place_t; + +typedef struct { + int fixed_layernum; + char *name; + char *param; + int is_sig; + pcb_layer_type_t type; + fixed_layer_place_t place; +} fixed_layer_t; + +static fixed_layer_t fixed_layers[] = { + {0, "F.Cu", "signal", 1, PCB_LYT_COPPER | PCB_LYT_TOP, FLP_COP_FIRST }, + {0, "Inner%d.Cu", "signal", 1, PCB_LYT_COPPER | PCB_LYT_INTERN, FLP_COP_INT }, + {0, "B.Cu", "signal", 1, PCB_LYT_COPPER | PCB_LYT_BOTTOM, FLP_COP_LAST }, +/* {16, "B.Adhes", "user", 0, PCB_LYT_ADHES | PCB_LYT_BOTTOM, FLP_FIXED }, + {17, "F.Adhes", "user", 0, PCB_LYT_ADHES | PCB_LYT_TOP, FLP_FIXED },*/ + {18, "B.Paste", "user", 0, PCB_LYT_PASTE | PCB_LYT_BOTTOM, FLP_FIXED }, + {19, "F.Paste", "user", 0, PCB_LYT_PASTE | PCB_LYT_TOP, FLP_FIXED }, + {20, "B.SilkS", "user", 0, PCB_LYT_SILK | PCB_LYT_BOTTOM, FLP_FIXED }, + {21, "F.SilkS", "user", 0, PCB_LYT_SILK | PCB_LYT_TOP, FLP_FIXED }, + {22, "B.Mask", "user", 0, PCB_LYT_MASK | PCB_LYT_BOTTOM, FLP_FIXED }, + {23, "F.Mask", "user", 0, PCB_LYT_MASK | PCB_LYT_TOP, FLP_FIXED }, + {28, "Edge.Cuts", "user", 0, PCB_LYT_BOUNDARY, FLP_FIXED }, + {0, NULL, NULL, 0} +}; + +/* number of copper layers, where to start inners, how to increment iners */ +#define KICAD_COPPERS 16 +#define KICAD_FIRST_INNER 1 +#define KICAD_NEXT_INNER +1 +#define KICAD_FIRST_MISC KICAD_COPPERS + +#define grp_idx(grp) ((grp) - ctx->pcb->LayerGroups->grp) + +/* Make the mapping between pcb-rnd layer groups and kicad layer stackup + Assumption: the first KICAD_COPPERS layers are the copper layers */ +static int kicad_map_layers(wctx_t *ctx) +{ + fixed_layer_t *fl; + int n; + int inner = KICAD_FIRST_INNER; + int misc = KICAD_FIRST_MISC; + char *mapped; + + mapped = calloc(ctx->pcb->LayerGroups.len, 1); + ctx->num_layers = -1; + + for(fl = fixed_layers; fl->name != NULL; fl++) { + rnd_layergrp_id_t gid[KICAD_COPPERS]; + int idx, ngrp; + + gid[0] = -1; + ngrp = pcb_layergrp_list(ctx->pcb, fl->type, gid, KICAD_COPPERS); + if ((fl->place != FLP_COP_INT) && (ngrp > 1)) + pcb_io_incompat_save(ctx->pcb->Data, NULL, "group", "Multiple layer groups of the same type - exporting only the first", "Merge the groups"); + + switch(fl->place) { + case FLP_COP_FIRST: + idx = 0; + break; + case FLP_COP_INT: + /* iterate over all internal groups */ + for(n = 0; n < ngrp; n++) { + idx = inner; + if (inner >= KICAD_COPPERS-1) { + pcb_io_incompat_save(ctx->pcb->Data, NULL, "layer", "Too many internal layer groups, omitting some", "Use fewer groups"); + continue; + } + sprintf(ctx->layer[idx].name, fl->name, idx); + if (gid[n] >= 0) { + inner += KICAD_NEXT_INNER; + ctx->layer[idx].grp = &ctx->pcb->LayerGroups.grp[gid[n]]; + ctx->layer[idx].param = fl->param; + ctx->layer[idx].is_sig = fl->is_sig; + mapped[gid[n]]++; + if (idx > ctx->num_layers) + ctx->num_layers = idx; + } + } + continue; /* the normal layer insertion does only a single group, skip it */ + case FLP_COP_LAST: + idx = KICAD_COPPERS - 1; + break; + + case FLP_FIXED: + idx = fl->fixed_layernum; + break; + + case FLP_MISC: + idx = misc; + if (gid[0] >= 0) + misc++; + if (misc >= KICAD_MAX_LAYERS-1) { + pcb_io_incompat_save(ctx->pcb->Data, NULL, "layer", "Too many internal layer groups, omitting some", "Use fewer groups"); + continue; + } + break; + } + + /* normal, single group mapping */ + if (gid[0] >= 0) { + strcpy(ctx->layer[idx].name, fl->name); + ctx->layer[idx].grp = &ctx->pcb->LayerGroups.grp[gid[0]]; + ctx->layer[idx].param = fl->param; + ctx->layer[idx].is_sig = fl->is_sig; + mapped[gid[0]]++; + if (idx > ctx->num_layers) + ctx->num_layers = idx; + } + } + + for(n = 0; n < ctx->pcb->LayerGroups.len; n++) { + pcb_layergrp_t *grp = &ctx->pcb->LayerGroups.grp[n]; + if ((mapped[n] == 0) && !(grp->ltype & PCB_LYT_SUBSTRATE)) + pcb_io_incompat_save(ctx->pcb->Data, NULL, "layer", "Failed to map layer for export - layer omitted", grp->name); + else if (mapped[n] > 1) + pcb_io_incompat_save(ctx->pcb->Data, NULL, "layer", "Mapped layer for export multiple times", grp->name); + } + + free(mapped); + ctx->num_layers++; + + if (ctx->num_layers < 3) + pcb_io_incompat_save(ctx->pcb->Data, NULL, "layer", "Warning: low output layer count", NULL); + return 0; +} + +static const char *kicad_sexpr_layer_to_text(wctx_t *ctx, int layer) +{ + if ((layer < 0) || (layer >= ctx->num_layers)) { + assert(!"invalid layer"); + return ""; + } + return ctx->layer[layer].name; +} + +static void kicad_print_layers(wctx_t *ctx, int ind) +{ + int n; + + fprintf(ctx->f, "\n%*s(layers\n", ind, ""); + for(n = 0; n < ctx->num_layers; n++) + if (ctx->layer[n].param != NULL) + fprintf(ctx->f, "%*s(%d %s %s)\n", ind+2, "", n, ctx->layer[n].name, ctx->layer[n].param); + fprintf(ctx->f, "%*s)\n", ind, ""); +} + +typedef struct { + int klayer; /* kicad layer ID, index of wctx->layer */ + const char *name; /* kicad layer name (cached from wctx) */ + pcb_layer_t *ly; + pcb_layer_type_t lyt; + enum { + KLYT_COPPER, /* board: copper/signal/trace objects */ + KLYT_GR, /* board: "grpahical" objects: silk and misc */ + KLYT_FP /* module: any */ + } type; + int skip_term; /* do not print terminals on this layer */ +} klayer_t; + +static void kicad_print_line(const wctx_t *ctx, const klayer_t *kly, pcb_line_t *line, int ind, rnd_coord_t dx, rnd_coord_t dy) +{ + const char *cmd[] = {"segment", "gr_line", "fp_line"}; + + fprintf(ctx->f, "%*s", ind, ""); + rnd_fprintf(ctx->f, + "(%s (start %.3mm %.3mm) (end %.3mm %.3mm) (layer %s) (width %.3mm))\n", + cmd[kly->type], + line->Point1.X + dx, line->Point1.Y + dy, + line->Point2.X + dx, line->Point2.Y + dy, + kly->name, line->Thickness); + /* neglect (net ___ ) for now */ +} + +static void kicad_print_arc(const wctx_t *ctx, const klayer_t *kly, pcb_arc_t *arc, int ind, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_arc_t localArc = *arc; /* for converting ellipses to circular arcs */ +/* int kicadArcShape; 3 = circle, and 2 = arc, 1= rectangle used in eeschema only */ + rnd_coord_t copperStartX, copperStartY; /* used for mapping geda copper arcs onto kicad copper lines */ + rnd_coord_t radius, xStart, yStart, xEnd, yEnd; + + if (arc->Width > arc->Height) { + radius = arc->Height; + localArc.Width = radius; + } + else { + radius = arc->Width; + localArc.Height = radius; + } + +TODO(": what do we need this for?") +#if 0 + /* Return the x;y coordinate of the endpoint of an arc; if which is 0, return + the endpoint that corresponds to StartAngle, else return the end angle's. */ + if ((arc->Delta == 360.0) || (arc->Delta == -360.0)) + kicadArcShape = 3; /* it's a circle */ + else + kicadArcShape = 2; /* it's an arc */ +#endif + + xStart = localArc.X + dx; + yStart = localArc.Y + dy; + pcb_arc_get_end(&localArc, 1, &xEnd, &yEnd); + xEnd += dx; + yEnd += dy; + pcb_arc_get_end(&localArc, 0, &copperStartX, &copperStartY); + copperStartX += dx; + copperStartY += dy; + + fprintf(ctx->f, "%*s", ind, ""); + + switch(kly->type) { + case KLYT_COPPER: +TODO(": this should be a proper line approximation using a helper (to be written)") + rnd_fprintf(ctx->f, "(segment (start %.3mm %.3mm) (end %.3mm %.3mm) (layer %s) (width %.3mm))\n", copperStartX, copperStartY, xEnd, yEnd, kly->name, arc->Thickness); /* neglect (net ___ ) for now */ + pcb_io_incompat_save(ctx->pcb->Data, (pcb_any_obj_t *)arc, "copper-arc", "Kicad does not support copper arcs; using line approximation", NULL); + break; + case KLYT_GR: + rnd_fprintf(ctx->f, "(gr_arc (start %.3mm %.3mm) (end %.3mm %.3mm) (angle %ma) (layer %s) (width %.3mm))\n", xStart, yStart, xEnd, yEnd, arc->Delta, kly->name, arc->Thickness); + break; + case KLYT_FP: + rnd_fprintf(ctx->f, "(fp_arc (start %.3mm %.3mm) (end %.3mm %.3mm) (angle %ma) (layer %s) (width %.3mm))\n", xStart, yStart, xEnd, yEnd, arc->Delta, kly->name, arc->Thickness); + break; + } +} + +static void kicad_print_text(const wctx_t *ctx, const klayer_t *kly, pcb_text_t *text, int ind, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_font_t *myfont = pcb_font(PCB, 0, 1); + rnd_coord_t mWidth = myfont->MaxWidth; /* kicad needs the width of the widest letter */ + rnd_coord_t defaultStrokeThickness = 100 * 2540; /* use 100 mil as default 100% stroked font line thickness */ + int kicadMirrored = 1; /* 1 is not mirrored, 0 is mirrored */ + rnd_coord_t defaultXSize; + rnd_coord_t defaultYSize; + rnd_coord_t strokeThickness; + int rotation, direction; + rnd_coord_t textOffsetX; + rnd_coord_t textOffsetY; + rnd_coord_t halfStringWidth; + rnd_coord_t halfStringHeight; + int scale; + + if (!(kly->lyt & PCB_LYT_COPPER) && !(kly->lyt & PCB_LYT_SILK)) { + pcb_io_incompat_save(ctx->pcb->Data, (pcb_any_obj_t *)text, "text-layer", "Kicad supports text only on copper or silk - omitting text object on misc layer", NULL); + return; + } + + if (pcb_text_old_scale(text, &scale) != 0) + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)text, "text-scale", "file format does not support different x and y direction text scale - using average scale", "Use the scale field, set scale_x and scale_y to 0"); + if (text->mirror_x) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-mirror-x", "file format does not support different mirroring text in the x direction", "do not mirror, or mirror in the y direction (with the ONSOLDER flag)"); + + fprintf(ctx->f, "%*s", ind, ""); + rnd_fprintf(ctx->f, "(gr_text %[4] ", text->TextString); + defaultXSize = 5 * PCB_SCALE_TEXT(mWidth, scale) / 6; /* IIRC kicad treats this as kerned width of upper case m */ + defaultYSize = defaultXSize; + strokeThickness = PCB_SCALE_TEXT(defaultStrokeThickness, scale / 2); + rotation = 0; + textOffsetX = 0; + textOffsetY = 0; + halfStringWidth = (text->BoundingBox.X2 - text->BoundingBox.X1) / 2; + if (halfStringWidth < 0) { + halfStringWidth = -halfStringWidth; + } + halfStringHeight = (text->BoundingBox.Y2 - text->BoundingBox.Y1) / 2; + if (halfStringHeight < 0) { + halfStringHeight = -halfStringHeight; + } + +TODO("textrot: use the degrees instead of 90 deg steps") + pcb_text_old_direction(&direction, text->rot); + if (direction == 3) { /*vertical down */ + if (kly->lyt & PCB_LYT_BOTTOM) { /* back copper or silk */ + rotation = 2700; + kicadMirrored = 0; /* mirrored */ + textOffsetY -= halfStringHeight; + textOffsetX -= 2 * halfStringWidth; /* was 1*hsw */ + } + else { /* front copper or silk */ + rotation = 2700; + kicadMirrored = 1; /* not mirrored */ + textOffsetY = halfStringHeight; + textOffsetX -= halfStringWidth; + } + } + else if (direction == 2) { /*upside down */ + if (kly->lyt & PCB_LYT_BOTTOM) { /* back copper or silk */ + rotation = 0; + kicadMirrored = 0; /* mirrored */ + textOffsetY += halfStringHeight; + } + else { /* front copper or silk */ + rotation = 1800; + kicadMirrored = 1; /* not mirrored */ + textOffsetY -= halfStringHeight; + } + textOffsetX = -halfStringWidth; + } + else if (direction == 1) { /*vertical up */ + if (kly->lyt & PCB_LYT_BOTTOM) { /* back copper or silk */ + rotation = 900; + kicadMirrored = 0; /* mirrored */ + textOffsetY = halfStringHeight; + textOffsetX += halfStringWidth; + } + else { /* front copper or silk */ + rotation = 900; + kicadMirrored = 1; /* not mirrored */ + textOffsetY = -halfStringHeight; + textOffsetX = 0; /* += halfStringWidth; */ + } + } + else if (direction == 0) { /*normal text */ + if (kly->lyt & PCB_LYT_BOTTOM) { /* back copper or silk */ + rotation = 1800; + kicadMirrored = 0; /* mirrored */ + textOffsetY -= halfStringHeight; + } + else { /* front copper or silk */ + rotation = 0; + kicadMirrored = 1; /* not mirrored */ + textOffsetY += halfStringHeight; + } + textOffsetX = halfStringWidth; + } + rnd_fprintf(ctx->f, "(at %.3mm %.3mm", text->X + dx + textOffsetX, text->Y + dy + textOffsetY); + if (text->rot != 0.0) + fprintf(ctx->f, " %f", text->rot); + rnd_fprintf(ctx->f, ") (layer %s)\n", kly->name); + fprintf(ctx->f, "%*s", ind + 2, ""); + rnd_fprintf(ctx->f, "(effects (font (size %.3mm %.3mm) (thickness %.3mm))", defaultXSize, defaultYSize, strokeThickness); /* , rotation */ + if (kicadMirrored == 0) { + fprintf(ctx->f, " (justify mirror)"); + } + fprintf(ctx->f, ")\n%*s)\n", ind, ""); +} + +static void kicad_print_poly_zone(const wctx_t *ctx, const klayer_t *kly, pcb_poly_t *polygon, int ind, rnd_coord_t dx, rnd_coord_t dy) +{ + int i, j; + + if (polygon->HoleIndexN != 0) { +TODO(": does kicad suppor holes? of so, use them; else (and only else) there is a polygon.h call that can split up a holed poly into a set of hole-free polygons") + pcb_io_incompat_save(ctx->pcb->Data, (pcb_any_obj_t *)polygon, "poly-hole", "can't export polygon with holes", NULL); + return; + } + + /* preliminaries for zone settings */ +TODO(": never hardwire tstamp") +TODO(": do not hardwire thicknesses and gaps and hatch values!") + fprintf(ctx->f, "%*s(zone (net 0) (net_name \"\") (layer %s) (tstamp 478E3FC8) (hatch edge 0.508)\n", ind, "", kly->name); + fprintf(ctx->f, "%*s(connect_pads no (clearance 0.508))\n", ind + 2, ""); + fprintf(ctx->f, "%*s(min_thickness 0.4826)\n", ind + 2, ""); + fprintf(ctx->f, "%*s(fill (arc_segments 32) (thermal_gap 0.508) (thermal_bridge_width 0.508))\n", ind + 2, ""); + fprintf(ctx->f, "%*s(polygon\n", ind + 2, ""); + fprintf(ctx->f, "%*s(pts\n", ind + 4, ""); + + /* now the zone outline is defined */ + for(i = 0; i < polygon->PointN; i = i + 5) { /* kicad exports five coords per line in s-expr files */ + fprintf(ctx->f, "%*s", ind + 6, ""); /* rnd_fprintf does not support %*s */ + for(j = 0; (j < polygon->PointN) && (j < 5); j++) { + rnd_fprintf(ctx->f, "(xy %.3mm %.3mm)", polygon->Points[i + j].X + dx, polygon->Points[i + j].Y + dy); + if ((j < 4) && ((i + j) < (polygon->PointN - 1))) { + fputs(" ", ctx->f); + } + } + fputs("\n", ctx->f); + } + fprintf(ctx->f, "%*s)\n", ind + 4, ""); + fprintf(ctx->f, "%*s)\n", ind + 2, ""); + fprintf(ctx->f, "%*s)\n", ind, ""); +} + +static void kicad_print_poly_fp_poly(const wctx_t *ctx, const klayer_t *kly, pcb_poly_t *polygon, int ind, rnd_coord_t dx, rnd_coord_t dy) +{ + int i, j; + + if (polygon->HoleIndexN != 0) { +TODO(": does kicad suppor holes? of so, use them; else (and only else) there is a polygon.h call that can split up a holed poly into a set of hole-free polygons") + pcb_io_incompat_save(ctx->pcb->Data, (pcb_any_obj_t *)polygon, "poly-hole", "can't export polygon with holes", NULL); + return; + } + + /* preliminaries for zone settings */ +TODO(": never hardwire tstamp") +TODO(": do not hardwire thicknesses and gaps and hatch values!") + fprintf(ctx->f, "%*s(fp_poly\n%*s(pts\n", ind, "", ind+2, ""); + + /* now the zone outline is defined */ + for(i = 0; i < polygon->PointN; i = i + 5) { /* kicad exports five coords per line in s-expr files */ + fprintf(ctx->f, "%*s", ind + 4, ""); /* rnd_fprintf does not support %*s */ + for(j = 0; (j < polygon->PointN) && (j < 5); j++) { + rnd_fprintf(ctx->f, "(xy %.3mm %.3mm)", polygon->Points[i + j].X + dx, polygon->Points[i + j].Y + dy); + if ((j < 4) && ((i + j) < (polygon->PointN - 1))) { + fputs(" ", ctx->f); + } + } + fputs("\n", ctx->f); + } + fprintf(ctx->f, "%*s) (layer %s) (width 0))\n", ind + 2, "", kly->name); +} + + + +static void kicad_print_poly(const wctx_t *ctx, const klayer_t *kly, pcb_poly_t *polygon, int ind, rnd_coord_t dx, rnd_coord_t dy, int in_module) +{ + if (in_module) + kicad_print_poly_fp_poly(ctx, kly, polygon, ind, dx, dy); + else + kicad_print_poly_zone(ctx, kly, polygon, ind, dx, dy); +} + + +/* Print all objects of a kicad layer; if skip_term is true, ignore the objects + with term ID set */ +static void kicad_print_layer(wctx_t *ctx, pcb_layer_t *ly, const klayer_t *kly, int ind, rnd_coord_t dx, rnd_coord_t dy) +{ + gdl_iterator_t it; + pcb_line_t *line; + pcb_text_t *text; + pcb_poly_t *poly; + pcb_arc_t *arc; + int in_subc = (ly->parent.data->parent_type == PCB_PARENT_SUBC); + + { + pcb_gfx_t *gfx; + for(gfx = gfxlist_first(&ly->Gfx); gfx != NULL; gfx = gfxlist_next(gfx)) + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)gfx, "gfx", "gfx can not be exported", "please use the lihata board format"); + } + + linelist_foreach(&ly->Line, &it, line) + if ((line->term == NULL) || !kly->skip_term) + kicad_print_line(ctx, kly, line, ind, dx, dy); + + arclist_foreach(&ly->Arc, &it, arc) + if ((arc->term == NULL) || !kly->skip_term) + kicad_print_arc(ctx, kly, arc, ind, dx, dy); + + textlist_foreach(&ly->Text, &it, text) { + if (kly->type == KLYT_FP) { + if (!PCB_FLAG_TEST(PCB_FLAG_DYNTEXT, text)) { + pcb_io_incompat_save(ctx->pcb->Data, (pcb_any_obj_t *)text, "subc-text", "can't export custom text in footprint", NULL); + break; + } + else + continue; + } + if ((text->term == NULL) || !kly->skip_term) + kicad_print_text(ctx, kly, text, ind, dx, dy); + } + + polylist_foreach(&ly->Polygon, &it, poly) + if ((poly->term == NULL) || !kly->skip_term) + kicad_print_poly(ctx, kly, poly, ind, dx, dy, in_subc); +} + +/* writes kicad format via data + For a track segment: Position shape Xstart Ystart Xend Yend width + Description layer 0 netcode timestamp status; Shape parameter is set to 0 (reserved for future) */ +static void kicad_print_pstks(wctx_t *ctx, pcb_data_t *Data, int ind, rnd_coord_t dx, rnd_coord_t dy) +{ + gdl_iterator_t it; + pcb_pstk_t *ps; + int is_subc = Data->parent_type == PCB_PARENT_SUBC; + + padstacklist_foreach(&Data->padstack, &it, ps) { + int klayer_from = 0, klayer_to = 15; + rnd_coord_t x, y, drill_dia, pad_dia, clearance, mask, x1, y1, x2, y2, thickness; + pcb_pstk_compshape_t cshape; + rnd_bool plated, square, nopaste; + double psrot; + + if (is_subc && (ps->term == NULL)) { + pcb_io_incompat_save(Data, (pcb_any_obj_t *)ps, "padstack-nonterm", "can't export non-terminal padstack in subcircuit, omitting the object", NULL); + continue; + } + if (!is_subc && (ps->term != NULL)) { + pcb_io_incompat_save(Data, (pcb_any_obj_t *)ps, "padstack-nonsubc", "can't export terminal info for a padstack outside of a subcircuit (omitting terminal info)", NULL); + continue; + } + + psrot = ps->rot; + if (ps->smirror) + psrot = -psrot; + + if (is_subc) { + pcb_net_t *net = NULL; + if (ps->term != NULL) { + pcb_net_term_t *t = pcb_net_find_by_obj(&ctx->pcb->netlist[PCB_NETLIST_EDITED], (const pcb_any_obj_t *)ps); + if (t != NULL) + net = t->parent.net; + } + if (pcb_pstk_export_compat_via(ps, &x, &y, &drill_dia, &pad_dia, &clearance, &mask, &cshape, &plated)) { + fprintf(ctx->f, "%*s", ind, ""); +TODO(": handle all cshapes (throw warnings)") + rnd_fprintf(ctx->f, "(pad %s thru_hole %s (at %.3mm %.3mm %f) (size %.3mm %.3mm) (drill %.3mm) (layers %s %s)", + ps->term, ((cshape == PCB_PSTK_COMPAT_SQUARE) ? "rect" : "oval"), + x + dx, y + dy, psrot, + pad_dia, pad_dia, + drill_dia, + kicad_sexpr_layer_to_text(ctx, 0), kicad_sexpr_layer_to_text(ctx, 15)); + if (net != NULL) + fprintf(ctx->f, " (net %ld %s)", (long)net->export_tmp, net->name); + fprintf(ctx->f, ")\n"); + } + else if (pcb_pstk_export_compat_pad(ps, &x1, &y1, &x2, &y2, &thickness, &clearance, &mask, &square, &nopaste)) { + /* the above check only makes sure this is a plain padstack, get the geometry from the copper layer shape */ + const char *shape_str, *side_str; + int n, has_mask = 0, on_bottom; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto_(Data, ps->proto); + pcb_pstk_tshape_t *tshp = &proto->tr.array[0]; + rnd_coord_t w, h; + + for(n = 0; n < tshp->len; n++) { + if (tshp->shape[n].layer_mask & PCB_LYT_COPPER) { + int i; + pcb_line_t line; + rnd_box_t bx; + pcb_pstk_shape_t *shape = &tshp->shape[n]; + + on_bottom = tshp->shape[n].layer_mask & PCB_LYT_BOTTOM; + if (ps->smirror) on_bottom = !on_bottom; + side_str = (on_bottom ? "B." : "F."); + + switch(shape->shape) { + case PCB_PSSH_POLY: + bx.X1 = bx.X2 = shape->data.poly.x[0]; + bx.Y1 = bx.Y2 = shape->data.poly.y[0]; + for(i = 1; i < shape->data.poly.len; i++) + rnd_box_bump_point(&bx, shape->data.poly.x[i], shape->data.poly.y[i]); + w = (bx.X2 - bx.X1); + h = (bx.Y2 - bx.Y1); + shape_str = "rect"; + break; + case PCB_PSSH_LINE: + line.Point1.X = shape->data.line.x1; + line.Point1.Y = shape->data.line.y1; + line.Point2.X = shape->data.line.x2; + line.Point2.Y = shape->data.line.y2; + line.Thickness = shape->data.line.thickness; + line.Clearance = 0; + line.Flags = pcb_flag_make(shape->data.line.square ? PCB_FLAG_SQUARE : 0); + pcb_line_bbox(&line); + w = (line.BoundingBox.X2 - line.BoundingBox.X1); + h = (line.BoundingBox.Y2 - line.BoundingBox.Y1); + shape_str = shape->data.line.square ? "rect" : "oval"; + break; + case PCB_PSSH_CIRC: + w = h = shape->data.circ.dia; + shape_str = "oval"; + break; + case PCB_PSSH_HSHADOW: +TODO("hshadow TODO") + break; + } + } + if (tshp->shape[n].layer_mask & PCB_LYT_MASK) + has_mask = 1; + } + + fprintf(ctx->f, "%*s", ind, ""); + rnd_fprintf(ctx->f, "(pad %s smd %s (at %.3mm %.3mm %f) (size %.3mm %.3mm) (layers", + ps->term, shape_str, + ps->x + dx, ps->y + dy, psrot, + w, h, + kicad_sexpr_layer_to_text(ctx, 0), kicad_sexpr_layer_to_text(ctx, 15)); + + fprintf(ctx->f, " %sCu", side_str); /* always has copper */ + if (has_mask) + fprintf(ctx->f, " %sMask", side_str); + if (!nopaste) + fprintf(ctx->f, " %sPaste", side_str); + fprintf(ctx->f, ")"); + if (net != NULL) + fprintf(ctx->f, " (net %ld %s)", (long)net->export_tmp, net->name); + fprintf(ctx->f, ")\n"); + } + else + pcb_io_incompat_save(Data, (pcb_any_obj_t *)ps, "padstack-shape", "Can't convert padstack to pin or pad", "use a simpler, uniform shape"); + } + else { /* global via */ + if (!pcb_pstk_export_compat_via(ps, &x, &y, &drill_dia, &pad_dia, &clearance, &mask, &cshape, &plated)) { + pcb_io_incompat_save(Data, (pcb_any_obj_t *)ps, "padstack-shape", "Can not convert padstack to old-style via", "Use round, uniform-shaped vias only"); + continue; + } + + if (cshape != PCB_PSTK_COMPAT_ROUND) { + pcb_io_incompat_save(Data, (pcb_any_obj_t *)ps, "padstack-shape", "Can not convert padstack to via", "only round vias are supported"); + continue; + } +TODO(": set klayer_from and klayer_to using bb span of ps") + + fprintf(ctx->f, "%*s", ind, ""); + rnd_fprintf(ctx->f, "(via (at %.3mm %.3mm) (size %.3mm) (layers %s %s))\n", + x + dx, y + dy, pad_dia, + kicad_sexpr_layer_to_text(ctx, klayer_from), kicad_sexpr_layer_to_text(ctx, klayer_to) + ); /* skip (net 0) for now */ + } + } +} + +void kicad_print_data(wctx_t *ctx, pcb_data_t *data, int ind, rnd_coord_t dx, rnd_coord_t dy) +{ + int n, klayer; + + for(n = 0; n < data->LayerN; n++) { + pcb_layer_t *ly = &data->Layer[n]; + rnd_layergrp_id_t gid = pcb_layer_get_group_(ly); + pcb_layergrp_t *grp; + int found = 0; + klayer_t kly; + + + if (gid < 0) + continue; /* unbound, should not be exported */ + + grp = &ctx->pcb->LayerGroups.grp[gid]; + + for(klayer = 0; klayer < ctx->num_layers; klayer++) { + if (ctx->layer[klayer].grp == grp) { + found = 1; + break; + } + } + + if (!found) { + pcb_io_incompat_save(data, NULL, "layer", "unmapped layer on data export", NULL); + continue; + } + +TODO(": this should be a safe lookup, merged with kicad_sexpr_layer_to_text()") + kly.name = kicad_sexpr_layer_to_text(ctx, klayer); + kly.ly = ly; + kly.lyt = pcb_layer_flags_(ly); + if (data->parent_type != PCB_PARENT_SUBC) { + kly.type = ctx->layer[klayer].is_sig ? KLYT_COPPER : KLYT_GR; + kly.skip_term = rnd_false; + } + else { + kly.type = KLYT_FP; + kly.skip_term = rnd_true; + } + + kicad_print_layer(ctx, ly, &kly, ind, dx, dy); + } + + kicad_print_pstks(ctx, data, ind, dx, dy); +} + +static int kicad_print_subc(wctx_t *ctx, pcb_subc_t *subc, rnd_cardinal_t ind, rnd_coord_t dx, rnd_coord_t dy, unm_t *group1) +{ + rnd_coord_t xPos, yPos, sox, soy; + int on_bottom; + const char *currentElementName; + const char *currentElementRef; + const char *currentElementVal; + +TODO(": get this from data table (see also #1)") + int silkLayer = 21; /* hard coded default, 20 is bottom silk */ + int copperLayer; + + if (pcb_subc_get_origin(subc, &sox, &soy) != 0) { + pcb_io_incompat_save(subc->data, (pcb_any_obj_t *)subc, "subc-place", "Failed to get origin of subcircuit", "fix the missing subc-aux layer"); + return -1; + } + if (pcb_subc_get_side(subc, &on_bottom) != 0) { + pcb_io_incompat_save(subc->data, (pcb_any_obj_t *)subc, "subc-place", "Failed to get placement side of subcircuit", "fix the missing subc-aux layer"); + return -1; + } + + xPos = sox + dx; + yPos = soy + dy; + + if (on_bottom) { + silkLayer = 20; + copperLayer = 15; + } + else { + silkLayer = 21; + copperLayer = 0; + } + + if (group1 != NULL) { +TODO(": we should probably do unm_name() on the refdes, not on footprint-name?") +TODO(": the unique name makes no sense if we override it with unknown - if the unique name is NULL, it is more likely a save-incompatibility error") + currentElementName = unm_name(group1, pcb_attribute_get(&subc->Attributes, "footprint"), subc); + if (currentElementName == NULL) + currentElementName = "unknown"; + } + else { + currentElementName = pcb_attribute_get(&subc->Attributes, "footprint"); + if (currentElementName == NULL) + currentElementName = "unknown"; + } + + currentElementRef = pcb_attribute_get(&subc->Attributes, "refdes"); + if (currentElementRef == NULL) { + currentElementRef = "unknown"; + } + currentElementVal = pcb_attribute_get(&subc->Attributes, "value"); + if (currentElementVal == NULL) { + currentElementVal = "unknown"; + } + +TODO(": why the heck do we hardwire timestamps?!!?!?!") + fprintf(ctx->f, "%*s", ind, ""); +rnd_trace("copper layer=\n", copperLayer); + rnd_fprintf(ctx->f, "(module %[4] (layer %s) (tedit 4E4C0E65) (tstamp 5127A136)\n", currentElementName, kicad_sexpr_layer_to_text(ctx, copperLayer)); + fprintf(ctx->f, "%*s", ind + 2, ""); + rnd_fprintf(ctx->f, "(at %.3mm %.3mm)\n", xPos, yPos); + + fprintf(ctx->f, "%*s", ind + 2, ""); + rnd_fprintf(ctx->f, "(descr %[4])\n", currentElementName); + + fprintf(ctx->f, "%*s", ind + 2, ""); + +TODO(": do not hardwire these coords, look up the first silk dyntext coords instead") + rnd_fprintf(ctx->f, "(fp_text reference %[4] (at 0.0 -2.56) ", currentElementRef); + rnd_fprintf(ctx->f, "(layer %s)\n", kicad_sexpr_layer_to_text(ctx, silkLayer)); + +TODO(": do not hardwire font sizes here, look up the first silk dyntext sizes instead") + fprintf(ctx->f, "%*s", ind + 4, ""); + fprintf(ctx->f, "(effects (font (size 1.397 1.27) (thickness 0.2032)))\n"); + fprintf(ctx->f, "%*s)\n", ind + 2, ""); + +TODO(": do not hardwire these coords, look up the first silk dyntext coords instead") + fprintf(ctx->f, "%*s", ind + 2, ""); + rnd_fprintf(ctx->f, "(fp_text value %[4] (at 0.0 -1.27) ", currentElementVal); + rnd_fprintf(ctx->f, "(layer %s)\n", kicad_sexpr_layer_to_text(ctx, silkLayer)); + +TODO(": do not hardwire font sizes here, look up the first silk dyntext sizes instead") + fprintf(ctx->f, "%*s", ind + 4, ""); + fprintf(ctx->f, "(effects (font (size 1.397 1.27) (thickness 0.2032)))\n"); + fprintf(ctx->f, "%*s)\n", ind + 2, ""); + + kicad_print_data(ctx, subc->data, ind+2, -sox, -soy); + +TODO(": export padstacks") +TODO(": warn for vias") +TODO(": warn for heavy terminals") + + fprintf(ctx->f, "%*s)\n\n", ind, ""); /* finish off module */ + + return 0; +} + + +static int kicad_print_subcs(wctx_t *ctx, pcb_data_t *Data, rnd_cardinal_t ind, rnd_coord_t dx, rnd_coord_t dy, long subc_idx) +{ + gdl_iterator_t sit; + pcb_subc_t *subc; + unm_t group1; /* group used to deal with missing names and provide unique ones if needed */ + +TODO(": revise this for subc") +/* elementlist_dedup_initializer(ededup);*/ + + /* Now initialize the group with defaults */ + unm_init(&group1); + + subclist_foreach(&Data->subc, &sit, subc) { + + if ((subc_idx >= 0) && (subc_idx != sit.count)) + continue; + + /* elementlist_dedup_skip(ededup, element); */ +TODO(": why?") + /* let's not skip duplicate elements for layout export */ + + kicad_print_subc(ctx, subc, ind, dx, dy, &group1); + } + /* Release unique name utility memory */ + unm_uninit(&group1); + +TODO(": revise this for subc") + /* free the state used for deduplication */ +/* elementlist_dedup_free(ededup);*/ + + return 0; +} + +static int write_kicad_layout_via_drill_size(FILE *FP, rnd_cardinal_t indentation) +{ +TODO(": do not hardwire the drill size here - does kicad support only one size, or what?") + fprintf(FP, "%*s", indentation, ""); + rnd_fprintf(FP, "(via_drill 0.635)\n"); /* mm format, default for now, ~= 0.635mm */ + return 0; +} + +int io_kicad_write_subcs_head(pcb_plug_io_t *ctx, void **udata, FILE *f, int lib, long num_subcs) +{ + if ((lib) || (num_subcs > 1)) { + rnd_message(RND_MSG_ERROR, "Can't save a library and/or multiple modules (footprints) in a single s-experssion mod file\n"); + return -1; + } + return 0; +} + +int io_kicad_write_subcs_subc(pcb_plug_io_t *ctx, void **udata, FILE *f, pcb_subc_t *subc) +{ + wctx_t wctx; + +TODO(": make this initialization a common function with write_kicad_layout()") + rnd_printf_slot[4] = "%{\\()\t\r\n \"}mq"; + + wctx.f = f; + wctx.pcb = PCB; + wctx.ox = 0; + wctx.oy = 0; + + if (kicad_map_layers(&wctx) != 0) + return -1; + + return kicad_print_subc(&wctx, subc, 0, 0, 0, NULL); +} + +int io_kicad_write_subcs_tail(pcb_plug_io_t *ctx, void **udata, FILE *f) +{ + return 0; +} + + +static int write_kicad_equipotential_netlists(FILE *FP, pcb_board_t *Layout, rnd_cardinal_t indentation) +{ + rnd_cardinal_t netNumber = 0; + htsp_entry_t *e; + + /* first we write a default netlist for the 0 net, which is for unconnected pads in pcbnew */ + fprintf(FP, "\n%*s(net 0 \"\")\n", indentation, ""); + + /* now we step through any available netlists and generate descriptors */ + for(e = htsp_first(&Layout->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&Layout->netlist[PCB_NETLIST_EDITED], e)) { + pcb_net_t *net = e->value; + + netNumber++; + fprintf(FP, "%*s(net %d ", indentation, "", netNumber); /* netlist 0 was used for unconnected pads */ + rnd_fprintf(FP, "%[4])\n", net->name); + net->export_tmp = netNumber; + } + return 0; +} + +static void kicad_paper(wctx_t *ctx, int ind) +{ + + /* Kicad expects a layout "sheet" size to be specified in mils, and A4, A3 etc... */ + int A4HeightMil = 8267; + int A4WidthMil = 11700; + int sheetHeight = A4HeightMil; + int sheetWidth = A4WidthMil; + int paperSize = 4; /* default paper size is A4 */ + +TODO(": rewrite this: rather have a table and a loop that hardwired calculations in code") + /* we sort out the needed kicad sheet size here, using A4, A3, A2, A1 or A0 size as needed */ + if (RND_COORD_TO_MIL(PCB->hidlib.size_x) > A4WidthMil || RND_COORD_TO_MIL(PCB->hidlib.size_y) > A4HeightMil) { + sheetHeight = A4WidthMil; /* 11.7" */ + sheetWidth = 2 * A4HeightMil; /* 16.5" */ + paperSize = 3; /* this is A3 size */ + } + if (RND_COORD_TO_MIL(PCB->hidlib.size_x) > sheetWidth || RND_COORD_TO_MIL(PCB->hidlib.size_y) > sheetHeight) { + sheetHeight = 2 * A4HeightMil; /* 16.5" */ + sheetWidth = 2 * A4WidthMil; /* 23.4" */ + paperSize = 2; /* this is A2 size */ + } + if (RND_COORD_TO_MIL(PCB->hidlib.size_x) > sheetWidth || RND_COORD_TO_MIL(PCB->hidlib.size_y) > sheetHeight) { + sheetHeight = 2 * A4WidthMil; /* 23.4" */ + sheetWidth = 4 * A4HeightMil; /* 33.1" */ + paperSize = 1; /* this is A1 size */ + } + if (RND_COORD_TO_MIL(PCB->hidlib.size_x) > sheetWidth || RND_COORD_TO_MIL(PCB->hidlib.size_y) > sheetHeight) { + sheetHeight = 4 * A4HeightMil; /* 33.1" */ + sheetWidth = 4 * A4WidthMil; /* 46.8" */ + paperSize = 0; /* this is A0 size; where would you get it made ?!?! */ + } + fprintf(ctx->f, "\n%*s(page A%d)\n", ind, "", paperSize); + + if (force_center) { + rnd_coord_t LayoutXOffset; + rnd_coord_t LayoutYOffset; + + /* we now sort out the offsets for centring the layout in the chosen sheet size here */ + if (sheetWidth > RND_COORD_TO_MIL(PCB->hidlib.size_x)) { /* usually A4, bigger if needed */ + /* fprintf(ctx->f, "%d ", sheetWidth); legacy kicad: elements decimils, sheet size mils */ + LayoutXOffset = RND_MIL_TO_COORD(sheetWidth) / 2 - PCB->hidlib.size_x / 2; + } + else { /* the layout is bigger than A0; most unlikely, but... */ + /* rnd_fprintf(ctx->f, "%.0ml ", PCB->hidlib.size_x); */ + LayoutXOffset = 0; + } + if (sheetHeight > RND_COORD_TO_MIL(PCB->hidlib.size_y)) { + /* fprintf(ctx->f, "%d", sheetHeight); */ + LayoutYOffset = RND_MIL_TO_COORD(sheetHeight) / 2 - PCB->hidlib.size_y / 2; + } + else { /* the layout is bigger than A0; most unlikely, but... */ + /* rnd_fprintf(ctx->f, "%.0ml", PCB->hidlib.size_y); */ + LayoutYOffset = 0; + } + + ctx->ox = LayoutXOffset; + ctx->oy = LayoutYOffset; + } + else + ctx->ox = ctx->oy = 0; +} + +static void kicad_print_implicit_outline(wctx_t *ctx, const char *lynam, rnd_coord_t thick, int ind) +{ + fprintf(ctx->f, "%*s", ind, ""); + rnd_fprintf(ctx->f, "(gr_line (start %.3mm %.3mm) (end %.3mm %.3mm) (layer %s) (width %.3mm))\n", + ctx->ox, ctx->oy, + ctx->pcb->hidlib.size_x + ctx->ox, ctx->oy, + lynam, thick); + fprintf(ctx->f, "%*s", ind, ""); + rnd_fprintf(ctx->f, "(gr_line (start %.3mm %.3mm) (end %.3mm %.3mm) (layer %s) (width %.3mm))\n", + ctx->pcb->hidlib.size_x + ctx->ox, ctx->oy, + ctx->pcb->hidlib.size_x + ctx->ox, ctx->pcb->hidlib.size_y + ctx->oy, + lynam, thick); + fprintf(ctx->f, "%*s", ind, ""); + rnd_fprintf(ctx->f, "(gr_line (start %.3mm %.3mm) (end %.3mm %.3mm) (layer %s) (width %.3mm))\n", + ctx->pcb->hidlib.size_x + ctx->ox, ctx->pcb->hidlib.size_y + ctx->oy, + ctx->ox, ctx->pcb->hidlib.size_y + ctx->oy, + lynam, thick); + fprintf(ctx->f, "%*s", ind, ""); + rnd_fprintf(ctx->f, "(gr_line (start %.3mm %.3mm) (end %.3mm %.3mm) (layer %s) (width %.3mm))\n", + ctx->ox, ctx->pcb->hidlib.size_y + ctx->oy, + ctx->ox, ctx->oy, + lynam, thick); +} + +static void kicad_fixup_outline(wctx_t *ctx, int ind) +{ + fixed_layer_t *l; + + if (pcb_has_explicit_outline(ctx->pcb)) + return; + + /* find the first kicad outline layer */ + for(l = fixed_layers; l->name != NULL; l++) { + if (l->type & PCB_LYT_BOUNDARY) { + kicad_print_implicit_outline(ctx, l->name, KICAD_OUTLINE_THICK, ind); + return; + } + } + + rnd_message(RND_MSG_ERROR, "io_kicad: internal error: can not find output outline layer for drawing the implicit outline\n"); +} + +/* writes PCB to file in s-expression format */ +int io_kicad_write_pcb(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + wctx_t wctx; + int baseSExprIndent = 2; + + memset(&wctx, 0, sizeof(wctx)); + wctx.pcb = PCB; + wctx.f = FP; + + /* Kicad string quoting pattern: protect parenthesis, whitespace, quote and backslash */ + rnd_printf_slot[4] = "%{\\()\t\r\n \"}mq"; + + fprintf(FP, "(kicad_pcb (version 3) (host pcb-rnd \"(%s %s)\")", PCB_VERSION, PCB_REVISION); + + fprintf(FP, "\n%*s(general\n", baseSExprIndent, ""); + fprintf(FP, "%*s)\n", baseSExprIndent, ""); + + kicad_paper(&wctx, baseSExprIndent); + kicad_map_layers(&wctx); + kicad_print_layers(&wctx, baseSExprIndent); + + /* setup section */ + fprintf(FP, "\n%*s(setup\n", baseSExprIndent, ""); + write_kicad_layout_via_drill_size(FP, baseSExprIndent + 2); + fprintf(FP, "%*s)\n", baseSExprIndent, ""); + + /* now come the netlist "equipotential" descriptors */ + + write_kicad_equipotential_netlists(FP, PCB, baseSExprIndent); + + /* module descriptions come next */ + fputs("\n", FP); + + kicad_print_subcs(&wctx, PCB->Data, baseSExprIndent, wctx.ox, wctx.oy, -1); + kicad_print_data(&wctx, PCB->Data, baseSExprIndent, wctx.ox, wctx.oy); + + kicad_fixup_outline(&wctx, baseSExprIndent); + + fputs(")\n", FP); /* finish off the board */ + + return 0; +} Index: tags/2.3.0/src_plugins/io_kicad/write.h =================================================================== --- tags/2.3.0/src_plugins/io_kicad/write.h (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad/write.h (revision 33253) @@ -0,0 +1,37 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * Copyright (C) 2016 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include +#include "data.h" + +int io_kicad_write_pcb(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency); + +int io_kicad_write_subcs_head(pcb_plug_io_t *ctx, void **udata, FILE *f, int lib, long num_subcs); +int io_kicad_write_subcs_subc(pcb_plug_io_t *ctx, void **udata, FILE *f, pcb_subc_t *subc); +int io_kicad_write_subcs_tail(pcb_plug_io_t *ctx, void **udata, FILE *f); Index: tags/2.3.0/src_plugins/io_kicad_legacy/HACKING =================================================================== --- tags/2.3.0/src_plugins/io_kicad_legacy/HACKING (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad_legacy/HACKING (revision 33253) @@ -0,0 +1,36 @@ +The plugin is disabled by default for now. This lets you work on it without +having to worry whether you break other people's compilation. You need to +enable it in your compilation, tho, when running configure: + +./configure --buildin-io_kicad_legacy + +Then run make (maybe only in src/) + +After making modifications to the plugin code, it's enough to run make in +the plugin dir - as the module is a buildin, it will recompile pcb-rnd. + +Run pcb-rnd from the src/ directory (cd there, it won't find its +files otherwise). + +How to run the plugin (GUI version): +1. run pcb-rnd (from src/) +2. load a pcb +3. open the command prompt (press ':') +4. type: SaveTo(PasteBuffer, foobar.mod, kicadl) + +Now, the gtk dialog "Buffer: save buffer elements to file" allows kicad legacy format to be selected. + +Arc and Circle support has been implemented but not fully tested. + +This will save the current PasteBuffer contents to foobar.mod using io_kicad_legacy format. + +Once layout export has been implemented, the following will be possible: + +How to run the plugin (CLI version): + +echo "SaveTo(LayoutAs, foobar.brd, kicadl)" | ./pcb-rnd --gui batch my.pcb + +(This loads my.pcb and saves it to foobar.brd and then exits) + +SVN: when commiting, please prefix all your commit message lines with string +[io_kicad_legacy] to make my job easier when generating Changelog. Index: tags/2.3.0/src_plugins/io_kicad_legacy/Makefile =================================================================== --- tags/2.3.0/src_plugins/io_kicad_legacy/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad_legacy/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_io_kicad_legacy + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/io_kicad_legacy/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/io_kicad_legacy/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad_legacy/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {io_kicad_legacy} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/io_kicad_legacy/io_kicad_legacy.o + $(PLUGDIR)/io_kicad_legacy/write.o +@] + +switch /local/pcb/io_kicad_legacy/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/io_kicad_legacy/io_kicad_legacy.c =================================================================== --- tags/2.3.0/src_plugins/io_kicad_legacy/io_kicad_legacy.c (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad_legacy/io_kicad_legacy.c (revision 33253) @@ -0,0 +1,88 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This module, io_kicad_legacy, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include "plug_io.h" +#include "write.h" + +static pcb_plug_io_t io_kicad_legacy; + +int io_kicad_legacy_fmt(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, int wr, const char *fmt) +{ + if (strcmp(ctx->description, fmt) == 0) + return 200; + + if ((strcmp(fmt, "kicadl") != 0) || + ((typ & (~(PCB_IOT_FOOTPRINT | PCB_IOT_BUFFER | PCB_IOT_PCB))) != 0)) + return 0; + if (wr) + return 100; + return 0; /* no read support yet */ +} + +int pplg_check_ver_io_kicad_legacy(int ver_needed) { return 0; } + +void pplg_uninit_io_kicad_legacy(void) +{ + /* Runs once when the plugin is unloaded. TODO: free plugin-globals here. */ + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_kicad_legacy); +} + +int pplg_init_io_kicad_legacy(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + io_kicad_legacy.plugin_data = NULL; + io_kicad_legacy.fmt_support_prio = io_kicad_legacy_fmt; + io_kicad_legacy.parse_pcb = NULL; + io_kicad_legacy.parse_footprint = NULL; + io_kicad_legacy.map_footprint = NULL; + io_kicad_legacy.parse_font = NULL; + io_kicad_legacy.write_buffer = NULL; + io_kicad_legacy.write_subcs_head = io_kicad_legacy_write_subcs_head; + io_kicad_legacy.write_subcs_subc = io_kicad_legacy_write_subcs_subc; + io_kicad_legacy.write_subcs_tail = io_kicad_legacy_write_subcs_tail; + io_kicad_legacy.write_pcb = io_kicad_legacy_write_pcb; + io_kicad_legacy.default_fmt = "kicadl"; + io_kicad_legacy.description = "Kicad, legacy format"; + io_kicad_legacy.save_preference_prio = 70; + io_kicad_legacy.default_extension = ".brd"; + io_kicad_legacy.fp_extension = ".mod"; + io_kicad_legacy.mime_type = "application/x-kicad-pcbnew"; + + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_kicad_legacy); + + /* TODO: Alloc plugin-globals here. */ + + return 0; +} + Index: tags/2.3.0/src_plugins/io_kicad_legacy/io_kicad_legacy.pup =================================================================== --- tags/2.3.0/src_plugins/io_kicad_legacy/io_kicad_legacy.pup (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad_legacy/io_kicad_legacy.pup (revision 33253) @@ -0,0 +1,11 @@ +$class io +$short Kicad's legacy format +$long Export the design and footprints in Kicad's legacy format. +$state works +$fmt-native no +$fmt-feature-w kicad pcbnew-board, version 1 (legacy plain text format) +$fmt-feature-w kicad pcbnew-module (legacy plain text format) +$package io-alien +default buildin +dep io_kicad +autoload 1 Index: tags/2.3.0/src_plugins/io_kicad_legacy/write.c =================================================================== --- tags/2.3.0/src_plugins/io_kicad_legacy/write.c (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad_legacy/write.c (revision 33253) @@ -0,0 +1,1071 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2018,2019 Tibor 'Igor2' Palinkas + * Copyright (C) 2016 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include +#include "config.h" +#include +#include "board.h" +#include "plug_io.h" +#include +#include "data.h" +#include "write.h" +#include "layer.h" +#include "netlist.h" +#include "obj_pstk_inlines.h" + +#include "../io_kicad/uniq_name.h" +#include "src_plugins/lib_compat_help/pstk_compat.h" + +/* layer "0" is first copper layer = "0. Back - Solder" + * and layer "15" is "15. Front - Component" + * and layer "20" SilkScreen Back + * and layer "21" SilkScreen Front + */ + +static const char *or_empty(const char *s) +{ + if (s == NULL) return ""; + return s; +} + +/* writes (eventually) de-duplicated list of element names in kicad legacy format module $INDEX */ +static int io_kicad_legacy_write_subc_index(FILE *FP, vtp0_t *subcs) +{ + unm_t group1; + long n; + + unm_init(&group1); + + for(n = 0; n < subcs->used; n++) { + pcb_subc_t *subc = subcs->array[n]; + if (pcb_data_is_empty(subc->data)) + continue; + +TODO(": need a subc dedup") +/* elementlist_dedup_skip(ededup, element);*/ + + fprintf(FP, "%s\n", unm_name(&group1, or_empty(pcb_attribute_get(&subc->Attributes, "footprint")), subc)); + } + + unm_uninit(&group1); + return 0; +} + +/* via is: Position shape Xstart Ystart Xend Yend width + Description layer 0 netcode timestamp status + Shape parameter is set to 0 (reserved for future) */ +static int write_kicad_legacy_layout_vias(FILE *FP, pcb_data_t *Data, rnd_coord_t xOffset, rnd_coord_t yOffset) +{ + gdl_iterator_t it; + pcb_pstk_t *ps; + rnd_coord_t x, y, drill_dia, pad_dia, clearance, mask; + pcb_pstk_compshape_t cshape; + rnd_bool plated; + + padstacklist_foreach(&Data->padstack, &it, ps) { + if (pcb_pstk_export_compat_via(ps, &x, &y, &drill_dia, &pad_dia, &clearance, &mask, &cshape, &plated)) { + if (cshape != PCB_PSTK_COMPAT_ROUND) { + pcb_io_incompat_save(Data, (pcb_any_obj_t *)ps, "via", "Failed to export via: only round shaped vias, with copper ring, are supported", NULL); + continue; + } + + rnd_fprintf(FP, "Po 3 %.0mk %.0mk %.0mk %.0mk %.0mk\n", /* testing kicad printf */ + x + xOffset, y + yOffset, x + xOffset, y + yOffset, pad_dia); +TODO(": check if drill_dia can be applied") +TODO(": bbvia") + rnd_fprintf(FP, "De 15 1 0 0 0\n"); /* this is equivalent to 0F, via from 15 -> 0 */ + } + } + return 0; +} + +/* generates a default via drill size for the layout */ +static int write_kicad_legacy_layout_via_drill_size(FILE *FP) +{ +TODO(": do not hardwire this") + rnd_fprintf(FP, "ViaDrill 250\n"); /* decimil format, default for now, ~= 0.635mm */ + return 0; +} + +static int write_kicad_legacy_layout_tracks(FILE *FP, rnd_cardinal_t number, pcb_layer_t *layer, rnd_coord_t xOffset, rnd_coord_t yOffset) +{ + gdl_iterator_t it; + pcb_line_t *line; + rnd_cardinal_t currentLayer = number; + + { + pcb_gfx_t *gfx; + for(gfx = gfxlist_first(&layer->Gfx); gfx != NULL; gfx = gfxlist_next(gfx)) + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)gfx, "gfx", "gfx can not be exported", "please use the lihata board format"); + } + + /* write information about non empty layers */ + if (!pcb_layer_is_empty_(PCB, layer) || (layer->name && *layer->name)) { + int localFlag = 0; + linelist_foreach(&layer->Line, &it, line) { + if (currentLayer < 16) { /* a copper line i.e. track */ + rnd_fprintf(FP, "Po 0 %.0mk %.0mk %.0mk %.0mk %.0mk\n", line->Point1.X + xOffset, line->Point1.Y + yOffset, line->Point2.X + xOffset, line->Point2.Y + yOffset, line->Thickness); + rnd_fprintf(FP, "De %d 0 0 0 0\n", currentLayer); /* omitting net info */ + } + else if ((currentLayer == 20) || (currentLayer == 21) || (currentLayer == 28)) { /* a silk line or outline */ + fputs("$DRAWSEGMENT\n", FP); + rnd_fprintf(FP, "Po 0 %.0mk %.0mk %.0mk %.0mk %.0mk\n", line->Point1.X + xOffset, line->Point1.Y + yOffset, line->Point2.X + xOffset, line->Point2.Y + yOffset, line->Thickness); + rnd_fprintf(FP, "De %d 0 0 0 0\n", currentLayer); /* omitting net info */ + fputs("$EndDRAWSEGMENT\n", FP); + } + localFlag |= 1; + } + return localFlag; + } + else { + return 0; + } +} + +static int write_kicad_legacy_layout_arcs(FILE *FP, rnd_cardinal_t number, pcb_layer_t *layer, rnd_coord_t xOffset, rnd_coord_t yOffset) +{ + gdl_iterator_t it; + pcb_arc_t *arc; + pcb_arc_t localArc; /* for converting ellipses to circular arcs */ + rnd_cardinal_t currentLayer = number; + rnd_coord_t radius, xStart, yStart, xEnd, yEnd; + int copperStartX; /* used for mapping geda copper arcs onto kicad copper lines */ + int copperStartY; /* used for mapping geda copper arcs onto kicad copper lines */ + + /* write information about non empty layers */ + if (!pcb_layer_is_empty_(PCB, layer) || (layer->name && *layer->name)) { + int localFlag = 0; + int kicadArcShape = 2; /* 3 = circle, and 2 = arc, 1= rectangle used in eeschema only */ + arclist_foreach(&layer->Arc, &it, arc) { + localArc = *arc; + if (arc->Width > arc->Height) { + radius = arc->Height; + localArc.Width = radius; + } + else { + radius = arc->Width; + localArc.Height = radius; + } + if (arc->Delta == 360.0 || arc->Delta == -360.0) { /* it's a circle */ + kicadArcShape = 3; + } + else { /* it's an arc */ + kicadArcShape = 2; + } + + xStart = localArc.X + xOffset; + yStart = localArc.Y + yOffset; + pcb_arc_get_end(&localArc, 1, &xEnd, &yEnd); + xEnd += xOffset; + yEnd += yOffset; + pcb_arc_get_end(&localArc, 0, &copperStartX, &copperStartY); + copperStartX += xOffset; + copperStartY += yOffset; + + if (currentLayer < 16) { /* a copper arc, i.e. track, is unsupported by kicad, and will be exported as a line */ + kicadArcShape = 0; /* make it a line for copper layers - kicad doesn't do arcs on copper */ + rnd_fprintf(FP, "Po %d %.0mk %.0mk %.0mk %.0mk %.0mk\n", kicadArcShape, copperStartX, copperStartY, xEnd, yEnd, arc->Thickness); + rnd_fprintf(FP, "De %d 0 0 0 0\n", currentLayer); /* in theory, copper arcs unsupported by kicad, make angle = 0 */ + } + else if ((currentLayer == 20) || (currentLayer == 21) || (currentLayer == 28)) { /* a silk arc or outline */ + fputs("$DRAWSEGMENT\n", FP); + rnd_fprintf(FP, "Po %d %.0mk %.0mk %.0mk %.0mk %.0mk\n", kicadArcShape, xStart, yStart, xEnd, yEnd, arc->Thickness); + rnd_fprintf(FP, "De %d 0 %mA 0 0\n", currentLayer, arc->Delta); /* in theory, decidegrees != 900 unsupported by older kicad */ + fputs("$EndDRAWSEGMENT\n", FP); + } + localFlag |= 1; + } + return localFlag; + } + else { + return 0; + } +} + +static int write_kicad_legacy_layout_text(FILE *FP, rnd_cardinal_t number, pcb_layer_t *layer, rnd_coord_t xOffset, rnd_coord_t yOffset) +{ + pcb_font_t *myfont = pcb_font(PCB, 0, 1); + rnd_coord_t mWidth = myfont->MaxWidth; /* kicad needs the width of the widest letter */ + rnd_coord_t defaultStrokeThickness = 100 * 2540; /* use 100 mil as default 100% stroked font line thickness */ + int kicadMirrored = 1; /* 1 is not mirrored, 0 is mirrored */ + int direction; + + rnd_coord_t defaultXSize; + rnd_coord_t defaultYSize; + rnd_coord_t strokeThickness; + int rotation; + rnd_coord_t textOffsetX; + rnd_coord_t textOffsetY; + rnd_coord_t halfStringWidth; + rnd_coord_t halfStringHeight; + int localFlag; + + gdl_iterator_t it; + pcb_text_t *text; + rnd_cardinal_t currentLayer = number; + + /* write information about non empty layers */ + if (!pcb_layer_is_empty_(PCB, layer) || (layer->name && *layer->name)) { + localFlag = 0; + textlist_foreach(&layer->Text, &it, text) { + if ((currentLayer < 16) || (currentLayer == 20) || (currentLayer == 21)) { /* copper or silk layer text */ + int scale; + if (pcb_text_old_scale(text, &scale) != 0) + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)text, "text-scale", "file format does not support different x and y direction text scale - using average scale", "Use the scale field, set scale_x and scale_y to 0"); + if (text->mirror_x) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-mirror-x", "file format does not support different mirroring text in the x direction", "do not mirror, or mirror in the y direction (with the ONSOLDER flag)"); + + fputs("$TEXTPCB\nTe \"", FP); + fputs(text->TextString, FP); + fputs("\"\n", FP); + defaultXSize = 5 * PCB_SCALE_TEXT(mWidth, scale) / 6; /* IIRC kicad treats this as kerned width of upper case m */ + defaultYSize = defaultXSize; + strokeThickness = PCB_SCALE_TEXT(defaultStrokeThickness, scale / 2); + rotation = 0; + textOffsetX = 0; + textOffsetY = 0; + halfStringWidth = (text->BoundingBox.X2 - text->BoundingBox.X1) / 2; + if (halfStringWidth < 0) { + halfStringWidth = -halfStringWidth; + } + halfStringHeight = (text->BoundingBox.Y2 - text->BoundingBox.Y1) / 2; + if (halfStringHeight < 0) { + halfStringHeight = -halfStringHeight; + } + +TODO("code duplication with io_kicad - clean that up after fixing textrot!") +TODO("textrot: use the angle, not n*90 deg") + pcb_text_old_direction(&direction, text->rot); + if (direction == 3) { /*vertical down */ + if (currentLayer == 0 || currentLayer == 20) { /* back copper or silk */ + rotation = 2700; + kicadMirrored = 0; /* mirrored */ + textOffsetY -= halfStringHeight; + textOffsetX -= 2 * halfStringWidth; /* was 1*hsw */ + } + else { /* front copper or silk */ + rotation = 2700; + kicadMirrored = 1; /* not mirrored */ + textOffsetY = halfStringHeight; + textOffsetX -= halfStringWidth; + } + } + else if (direction == 2) { /*upside down */ + if (currentLayer == 0 || currentLayer == 20) { /* back copper or silk */ + rotation = 0; + kicadMirrored = 0; /* mirrored */ + textOffsetY += halfStringHeight; + } + else { /* front copper or silk */ + rotation = 1800; + kicadMirrored = 1; /* not mirrored */ + textOffsetY -= halfStringHeight; + } + textOffsetX = -halfStringWidth; + } + else if (direction == 1) { /*vertical up */ + if (currentLayer == 0 || currentLayer == 20) { /* back copper or silk */ + rotation = 900; + kicadMirrored = 0; /* mirrored */ + textOffsetY = halfStringHeight; + textOffsetX += halfStringWidth; + } + else { /* front copper or silk */ + rotation = 900; + kicadMirrored = 1; /* not mirrored */ + textOffsetY = -halfStringHeight; + textOffsetX = 0; /* += halfStringWidth; */ + } + } + else if (direction == 0) { /*normal text */ + if (currentLayer == 0 || currentLayer == 20) { /* back copper or silk */ + rotation = 1800; + kicadMirrored = 0; /* mirrored */ + textOffsetY -= halfStringHeight; + } + else { /* front copper or silk */ + rotation = 0; + kicadMirrored = 1; /* not mirrored */ + textOffsetY += halfStringHeight; + } + textOffsetX = halfStringWidth; + } + rnd_fprintf(FP, "Po %.0mk %.0mk %.0mk %.0mk %.0mk %d\n", text->X + xOffset + textOffsetX, text->Y + yOffset + textOffsetY, defaultXSize, defaultYSize, strokeThickness, rotation); + rnd_fprintf(FP, "De %d %d B98C Normal\n", currentLayer, kicadMirrored); /* timestamp made up B98C */ + fputs("$EndTEXTPCB\n", FP); + } + localFlag |= 1; + } + return localFlag; + } + else { + return 0; + } +} + +static int write_kicad_legacy_equipotential_netlists(FILE *FP, pcb_board_t *Layout) +{ + htsp_entry_t *e; + rnd_cardinal_t netNumber = 0; + + /* first we write a default netlist for the 0 net, which is for unconnected pads in pcbnew */ + fputs("$EQUIPOT\n", FP); + fputs("Na 0 \"\"\n", FP); + fputs("St ~\n", FP); + fputs("$EndEQUIPOT\n", FP); + + /* now we step through any available netlists and generate descriptors */ + for(e = htsp_first(&Layout->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&Layout->netlist[PCB_NETLIST_EDITED], e)) { + pcb_net_t *net = e->value; + pcb_net_term_t *t = pcb_termlist_first(&net->conns); + if (t != NULL) { + netNumber++; + fputs("$EQUIPOT\n", FP); + fprintf(FP, "Na %d \"%s\"\n", netNumber, net->name); /* netlist 0 was used for unconnected pads */ + fputs("St ~\n", FP); + fputs("$EndEQUIPOT\n", FP); + net->export_tmp = netNumber; + } + else + net->export_tmp = 0; + } + return 0; +} + +static void print_pstk_net(FILE *FP, pcb_board_t *Layout, pcb_pstk_t *ps) +{ + pcb_net_term_t *term; + pcb_net_t *net = NULL; + + if (Layout != NULL) { + term = pcb_net_find_by_obj(&Layout->netlist[PCB_NETLIST_EDITED], (const pcb_any_obj_t *)ps); + if (term != NULL) + net = term->parent.net; + } + if ((net != NULL) && (net->export_tmp != 0)) + fprintf(FP, "Ne %d \"%s\"\n", net->export_tmp, net->name); /* library parts have empty net descriptors, in a .brd they don't */ + else + fprintf(FP, "Ne 0 \"\"\n"); /* unconnected pads have zero for net */ +} + +static int io_kicad_legacy_write_subc(FILE *FP, pcb_board_t *pcb, pcb_subc_t *subc, rnd_coord_t xOffset, rnd_coord_t yOffset, const char *uname) +{ + pcb_pstk_t *ps; + rnd_coord_t ox, oy, sox, soy; + int on_bottom; + int copperLayer; /* hard coded default, 0 is bottom copper */ + gdl_iterator_t it; + int n, silkLayer; + + if (pcb_subc_get_origin(subc, &sox, &soy) != 0) { + pcb_io_incompat_save(subc->parent.data, (pcb_any_obj_t *)subc, "subc-place", "Failed to get origin of subcircuit", "fix the missing subc-aux layer"); + return -1; + } + if (pcb_subc_get_side(subc, &on_bottom) != 0) { + pcb_io_incompat_save(subc->parent.data, (pcb_any_obj_t *)subc, "subc-place", "Failed to get placement side of subcircuit", "fix the missing subc-aux layer"); + return -1; + } + + ox = sox + xOffset; + oy = soy + yOffset; + + if (on_bottom) { + copperLayer = 0; + silkLayer = 20; + } + else { + copperLayer = 15; + silkLayer = 21; + } + + fprintf(FP, "$MODULE %s\n", uname); +TODO(": do not hardwire time stamps") + rnd_fprintf(FP, "Po %.0mk %.0mk 0 %d 51534DFF 00000000 ~~\n", ox, oy, copperLayer); + fprintf(FP, "Li %s\n", uname); /* This needs to be unique */ + fprintf(FP, "Cd %s\n", uname); + fputs("Sc 0\n", FP); + fputs("AR\n", FP); +TODO(": is this the origin point? if so, it should be sox and soy") + fputs("Op 0 0 0\n", FP); + +TODO(": do not hardwire coords") +TODO(": figure how to turn off displaying these") + fprintf(FP, "T0 0 -4000 600 600 0 120 N V %d N \"%s\"\n", silkLayer, or_empty(pcb_attribute_get(&subc->Attributes, "refdes"))); + fprintf(FP, "T1 0 -5000 600 600 0 120 N V %d N \"%s\"\n", silkLayer, or_empty(pcb_attribute_get(&subc->Attributes, "value"))); + fprintf(FP, "T2 0 -6000 600 600 0 120 N V %d N \"%s\"\n", silkLayer, or_empty(pcb_attribute_get(&subc->Attributes, "footprint"))); + + /* export padstacks */ + padstacklist_foreach(&subc->data->padstack, &it, ps) { + rnd_coord_t x, y, drill_dia, pad_dia, clearance, mask, x1, y1, x2, y2, thickness; + pcb_pstk_compshape_t cshape; + rnd_bool plated, square, nopaste; + double psrot; + + if (ps->term == NULL) { + pcb_io_incompat_save(subc->data, (pcb_any_obj_t *)ps, "padstack-nonterm", "can't export non-terminal padstack in subcircuit, omitting the object", NULL); + continue; + } + + psrot = ps->rot; + if (ps->smirror) + psrot = -psrot; + + if (pcb_pstk_export_compat_via(ps, &x, &y, &drill_dia, &pad_dia, &clearance, &mask, &cshape, &plated)) { + fputs("$PAD\n", FP); + rnd_fprintf(FP, "Po %.0mk %.0mk\n", x - sox, y - soy); /* positions of pad */ + fputs("Sh ", FP); /* pin shape descriptor */ + pcb_print_quoted_string(FP, (char *)RND_EMPTY(ps->term)); + + if (cshape == PCB_PSTK_COMPAT_SQUARE) fputs(" R ", FP); + else if (cshape == PCB_PSTK_COMPAT_ROUND) fputs(" C ", FP); + else { + pcb_io_incompat_save(subc->data, (pcb_any_obj_t *)ps, "padstack-shape", "can't export shaped pin; needs to be square or circular - using circular instead", NULL); + fputs(" C ", FP); + } + rnd_fprintf(FP, "%.0mk %.0mk ", pad_dia, pad_dia); /* height = width */ + fprintf(FP, "0 0 %d\n", (int)(psrot * 10)); /* deltaX deltaY Orientation as float in decidegrees */ + + /* drill details; size and x,y pos relative to pad location */ + rnd_fprintf(FP, "Dr %.0mk 0 0\n", drill_dia); + + fputs("At STD N 00E0FFFF\n", FP); /* through hole STD pin, all copper layers */ + + print_pstk_net(FP, pcb, ps); + fputs("$EndPAD\n", FP); + } + else if (pcb_pstk_export_compat_pad(ps, &x1, &y1, &x2, &y2, &thickness, &clearance, &mask, &square, &nopaste)) { + /* the above check only makes sure this is a plain padstack, get the geometry from the copper layer shape */ + char shape_chr; + int n, has_mask = 0, on_bottom; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto_(subc->data, ps->proto); + pcb_pstk_tshape_t *tshp = &proto->tr.array[0]; + rnd_coord_t w, h, cx, cy; + int found = 0; + + fputs("$PAD\n", FP); /* start pad descriptor for an smd pad */ + +TODO(": remove this code dup with io_kicad") + for(n = 0; n < tshp->len; n++) { + if (tshp->shape[n].layer_mask & PCB_LYT_COPPER) { + int i; + pcb_line_t line; + rnd_box_t bx; + pcb_pstk_shape_t *shape = &tshp->shape[n]; + + if (found) + continue; + found = 1; + + on_bottom = tshp->shape[n].layer_mask & PCB_LYT_BOTTOM; + if (ps->smirror) on_bottom = !on_bottom; + + switch(shape->shape) { + case PCB_PSSH_POLY: + bx.X1 = bx.X2 = shape->data.poly.x[0]; + bx.Y1 = bx.Y2 = shape->data.poly.y[0]; + for(i = 1; i < shape->data.poly.len; i++) + rnd_box_bump_point(&bx, shape->data.poly.x[i], shape->data.poly.y[i]); + w = (bx.X2 - bx.X1); + h = (bx.Y2 - bx.Y1); + cx = (bx.X1 + bx.X2)/2; + cy = (bx.Y1 + bx.Y2)/2; + shape_chr = 'R'; + break; + case PCB_PSSH_LINE: + line.Point1.X = shape->data.line.x1; + line.Point1.Y = shape->data.line.y1; + line.Point2.X = shape->data.line.x2; + line.Point2.Y = shape->data.line.y2; + line.Thickness = shape->data.line.thickness; + line.Clearance = 0; + line.Flags = pcb_flag_make(shape->data.line.square ? PCB_FLAG_SQUARE : 0); + pcb_line_bbox(&line); + w = (line.BoundingBox.X2 - line.BoundingBox.X1); + h = (line.BoundingBox.Y2 - line.BoundingBox.Y1); + cx = (shape->data.line.x1 + shape->data.line.x2)/2; + cy = (shape->data.line.y1 + shape->data.line.y2)/2; + shape_chr = shape->data.line.square ? 'R' : 'C'; + break; + case PCB_PSSH_CIRC: + w = h = shape->data.circ.dia; + cx = shape->data.circ.x; + cy = shape->data.circ.y; + shape_chr = 'C'; + break; + case PCB_PSSH_HSHADOW: +TODO("hshadow TODO") + shape_chr = 'C'; + cx = 0; + cy = 0; + break; + } + } + if (tshp->shape[n].layer_mask & PCB_LYT_MASK) + has_mask = 1; + } + rnd_fprintf(FP, "Po %.0mk %.0mk\n", ps->x + cx - sox, ps->y + cy - soy); /* positions of pad */ + + fputs("Sh ", FP); /* pin shape descriptor */ + pcb_print_quoted_string(FP, (char *)RND_EMPTY(ps->term)); + rnd_fprintf(FP, " %c %.0mk %.0mk ", shape_chr, w, h); + + rnd_fprintf(FP, "0 0 %d\n", (int)(psrot*10.0)); /* deltaX deltaY Orientation as float in decidegrees */ + + fputs("Dr 0 0 0\n", FP); /* drill details; zero size; x,y pos vs pad location */ + + /* SMD pin, need to use right layer mask */ + if (on_bottom) + fputs("At SMD N 00440001\n", FP); + else + fputs("At SMD N 00888000\n", FP); + + print_pstk_net(FP, pcb, ps); + fputs("$EndPAD\n", FP); + } + else + pcb_io_incompat_save(subc->data, (pcb_any_obj_t *)ps, "padstack-shape", "Can't convert padstack to pin or pad", "use a simpler, uniform shape"); + + } + + /* export layer objects */ + for(n = 0; n < subc->data->LayerN; n++) { + pcb_layer_t *ly = &subc->data->Layer[n]; + pcb_layer_type_t lyt = pcb_layer_flags_(ly); + pcb_line_t *line; + pcb_arc_t *arc; + pcb_poly_t *poly; + pcb_text_t *text; + rnd_coord_t arcStartX, arcStartY, arcEndX, arcEndY; + int silkLayer; + + if (!(lyt & PCB_LYT_SILK)) { + linelist_foreach(&ly->Line, &it, line) + pcb_io_incompat_save(subc->data, (pcb_any_obj_t *)line, "subc-obj", "can't save non-silk lines in subcircuits", "convert terminals to padstacks, remove the rest"); + arclist_foreach(&ly->Arc, &it, arc) + pcb_io_incompat_save(subc->data, (pcb_any_obj_t *)arc, "subc-obj", "can't save non-silk arc in subcircuits", "remove this arc"); + } + + polylist_foreach(&ly->Polygon, &it, poly) + pcb_io_incompat_save(subc->data, (pcb_any_obj_t *)poly, "subc-obj", "can't save polygons in subcircuits", "convert square terminals to padstacks, remove the rest"); + + textlist_foreach(&ly->Text, &it, text) + if (!PCB_FLAG_TEST(PCB_FLAG_DYNTEXT, text)) + pcb_io_incompat_save(subc->data, (pcb_any_obj_t *)text, "subc-obj", "can't save text in subcircuits", "remove the text object"); + + silkLayer = (lyt & PCB_LYT_BOTTOM) ? 20 : 21; + + linelist_foreach(&ly->Line, &it, line) { + rnd_fprintf(FP, "DS %.0mk %.0mk %.0mk %.0mk %.0mk ", + line->Point1.X - sox, line->Point1.Y - soy, + line->Point2.X - sox, line->Point2.Y - soy, + line->Thickness); + fprintf(FP, "%d\n", silkLayer); + } + + arclist_foreach(&ly->Arc, &it, arc) { + pcb_arc_get_end(arc, 0, &arcStartX, &arcStartY); + pcb_arc_get_end(arc, 1, &arcEndX, &arcEndY); + + if ((arc->Delta == 360.0) || (arc->Delta == -360.0)) { /* it's a circle */ + rnd_fprintf(FP, "DC %.0mk %.0mk %.0mk %.0mk %.0mk ", + arc->X - sox, arc->Y - soy, /* centre */ + arcStartX - sox, arcStartY - soy, /* on circle */ + arc->Thickness); + } + else { + rnd_fprintf(FP, "DA %.0mk %.0mk %.0mk %.0mk %mA %.0mk ", + arc->X - sox, arc->Y - soy, /* centre */ + arcEndX - sox, arcEndY - soy, + arc->Delta, /* CW delta angle in decidegrees */ + arc->Thickness); + } + fprintf(FP, "%d\n", silkLayer); /* and now append a suitable Kicad layer, front silk = 21, back silk 20 */ + } + } + + fprintf(FP, "$EndMODULE %s\n", uname); + + return 0; +} + +static int write_kicad_legacy_layout_subcs(FILE *FP, pcb_board_t *Layout, pcb_data_t *Data, rnd_coord_t xOffset, rnd_coord_t yOffset) +{ + gdl_iterator_t sit; + pcb_subc_t *subc; + unm_t group1; + + unm_init(&group1); + + subclist_foreach(&Data->subc, &sit, subc) { + const char *uname = unm_name(&group1, or_empty(pcb_attribute_get(&subc->Attributes, "footprint")), subc); +TODO(": what did we need this for?") +/* elementlist_dedup_skip(ededup, element); skip duplicate elements */ + io_kicad_legacy_write_subc(FP, PCB, subc, xOffset, yOffset, uname); + } + + unm_uninit(&group1); + return 0; +} + +static int write_kicad_legacy_layout_polygons(FILE *FP, rnd_cardinal_t number, pcb_layer_t *layer, rnd_coord_t xOffset, rnd_coord_t yOffset) +{ + int i, j; + gdl_iterator_t it; + pcb_poly_t *polygon; + rnd_cardinal_t currentLayer = number; + + /* write information about non empty layers */ + if (!pcb_layer_is_empty_(PCB, layer) || (layer->name && *layer->name)) { + int localFlag = 0; + polylist_foreach(&layer->Polygon, &it, polygon) { + if (polygon->HoleIndexN == 0) { /* no holes defined within polygon, which we implement support for first */ + + /* preliminaries for zone settings */ + fputs("$CZONE_OUTLINE\n", FP); + fputs("ZInfo 478E3FC8 0 \"\"\n", FP); /* use default empty netname, net 0, not connected */ + fprintf(FP, "ZLayer %d\n", currentLayer); + fprintf(FP, "ZAux %d E\n", polygon->PointN); /* corner count, use edge hatching for displaying the zone in pcbnew */ + fputs("ZClearance 200 X\n", FP); /* set pads/pins to not be connected to pours in the zone by default */ + fputs("ZMinThickness 190\n", FP); /* minimum copper thickness in zone, default setting */ + fputs("ZOptions 0 32 F 200 200\n", FP); /* solid fill, 32 segments per arc, antipad thickness, thermal stubs width(s) */ + + /* now the zone outline is defined */ + + for(i = 0, j = 0; i < polygon->PointN; i++) { + if (i == (polygon->PointN - 1)) { + j = 1; /* flags that this is the last vertex of the outline */ + } + rnd_fprintf(FP, "ZCorner %.0mk %.0mk %d\n", polygon->Points[i].X + xOffset, polygon->Points[i].Y + yOffset, j); + } + + /* in here could go additional plolygon descriptors for holes removed from the previously defined outer polygon */ + fputs("$endCZONE_OUTLINE\n", FP); + } + localFlag |= 1; + } + return localFlag; + } + else { + return 0; + } +} + +int io_kicad_legacy_write_subcs_head(pcb_plug_io_t *ctx, void **udata, FILE *f, int lib, long num_subcs) +{ + vtp0_t *subcs = malloc(sizeof(vtp0_t)); + vtp0_init(subcs); + + *udata = subcs; + return 0; +} + +int io_kicad_legacy_write_subcs_subc(pcb_plug_io_t *ctx, void **udata, FILE *f, pcb_subc_t *subc) +{ + vtp0_t *subcs = *udata; + vtp0_append(subcs, subc); + return 0; +} + +int io_kicad_legacy_write_subcs_tail(pcb_plug_io_t *ctx, void **udata, FILE *f) +{ + unm_t group1; + vtp0_t *subcs = *udata; + long n; + +TODO("no hardwiring of dates") + fputs("PCBNEW-LibModule-V1 jan 01 jan 2016 00:00:01 CET\n", f); + fputs("$INDEX\n", f); + io_kicad_legacy_write_subc_index(f, subcs); + fputs("$EndINDEX\n", f); + + unm_init(&group1); + for(n = 0; n < subcs->used; n++) { + pcb_subc_t *subc = subcs->array[n]; + const char *uname = unm_name(&group1, or_empty(pcb_attribute_get(&subc->Attributes, "footprint")), subc); + io_kicad_legacy_write_subc(f, PCB, subc, 0, 0, uname); + } + unm_uninit(&group1); + + vtp0_uninit(subcs); + free(subcs); + return 0; +} + +int io_kicad_legacy_write_pcb(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + rnd_cardinal_t i; + int kicadLayerCount = 0; + int physicalLayerCount = 0; + int layer = 0; + int currentKicadLayer = 0; + int currentGroup = 0; + rnd_coord_t outlineThickness = RND_MIL_TO_COORD(10); + + int bottomCount; + rnd_layer_id_t *bottomLayers; + int innerCount; + rnd_layer_id_t *innerLayers; + int topCount; + rnd_layer_id_t *topLayers; + int bottomSilkCount; + rnd_layer_id_t *bottomSilk; + int topSilkCount; + rnd_layer_id_t *topSilk; + int outlineCount; + rnd_layer_id_t *outlineLayers; + + rnd_coord_t LayoutXOffset; + rnd_coord_t LayoutYOffset; + + /* Kicad expects a layout "sheet" size to be specified in mils, and A4, A3 etc... */ + int A4HeightMil = 8267; + int A4WidthMil = 11700; + int sheetHeight = A4HeightMil; + int sheetWidth = A4WidthMil; + int paperSize = 4; /* default paper size is A4 */ + + fputs("PCBNEW-BOARD Version 1 jan 01 jan 2016 00:00:01 CET\n", FP); + + fputs("$GENERAL\n", FP); + fputs("Ly 1FFF8001\n", FP); /* obsolete, needed for old pcbnew */ + /*puts("Units mm\n",FP); *//*decimils most universal legacy format */ + fputs("$EndGENERAL\n", FP); + + fputs("$SHEETDESCR\n", FP); + +TODO(": se this from io_kicad, do not duplicate the code here") + /* we sort out the needed kicad sheet size here, using A4, A3, A2, A1 or A0 size as needed */ + if (RND_COORD_TO_MIL(PCB->hidlib.size_x) > A4WidthMil || RND_COORD_TO_MIL(PCB->hidlib.size_y) > A4HeightMil) { + sheetHeight = A4WidthMil; /* 11.7" */ + sheetWidth = 2 * A4HeightMil; /* 16.5" */ + paperSize = 3; /* this is A3 size */ + } + if (RND_COORD_TO_MIL(PCB->hidlib.size_x) > sheetWidth || RND_COORD_TO_MIL(PCB->hidlib.size_y) > sheetHeight) { + sheetHeight = 2 * A4HeightMil; /* 16.5" */ + sheetWidth = 2 * A4WidthMil; /* 23.4" */ + paperSize = 2; /* this is A2 size */ + } + if (RND_COORD_TO_MIL(PCB->hidlib.size_x) > sheetWidth || RND_COORD_TO_MIL(PCB->hidlib.size_y) > sheetHeight) { + sheetHeight = 2 * A4WidthMil; /* 23.4" */ + sheetWidth = 4 * A4HeightMil; /* 33.1" */ + paperSize = 1; /* this is A1 size */ + } + if (RND_COORD_TO_MIL(PCB->hidlib.size_x) > sheetWidth || RND_COORD_TO_MIL(PCB->hidlib.size_y) > sheetHeight) { + sheetHeight = 4 * A4HeightMil; /* 33.1" */ + sheetWidth = 4 * A4WidthMil; /* 46.8" */ + paperSize = 0; /* this is A0 size; where would you get it made ?!?! */ + } + + fprintf(FP, "Sheet A%d ", paperSize); + /* we now sort out the offsets for centring the layout in the chosen sheet size here */ + if (sheetWidth > RND_COORD_TO_MIL(PCB->hidlib.size_x)) { /* usually A4, bigger if needed */ + fprintf(FP, "%d ", sheetWidth); /* legacy kicad: elements decimils, sheet size mils */ + LayoutXOffset = RND_MIL_TO_COORD(sheetWidth) / 2 - PCB->hidlib.size_x / 2; + } + else { /* the layout is bigger than A0; most unlikely, but... */ + rnd_fprintf(FP, "%.0ml ", PCB->hidlib.size_x); + LayoutXOffset = 0; + } + if (sheetHeight > RND_COORD_TO_MIL(PCB->hidlib.size_y)) { + fprintf(FP, "%d", sheetHeight); + LayoutYOffset = RND_MIL_TO_COORD(sheetHeight) / 2 - PCB->hidlib.size_y / 2; + } + else { /* the layout is bigger than A0; most unlikely, but... */ + rnd_fprintf(FP, "%.0ml", PCB->hidlib.size_y); + LayoutYOffset = 0; + } + fputs("\n", FP); + fputs("$EndSHEETDESCR\n", FP); + + fputs("$SETUP\n", FP); + fputs("InternalUnit 0.000100 INCH\n", FP); /* decimil is the default v1 kicad legacy unit */ + + /* here we define the copper layers in the exported kicad file */ + physicalLayerCount = pcb_layergrp_list(PCB, PCB_LYT_COPPER, NULL, 0); + + fputs("Layers ", FP); + kicadLayerCount = physicalLayerCount; + if (kicadLayerCount % 2 == 1) { + kicadLayerCount++; /* kicad doesn't like odd numbers of layers, has been deprecated for some time apparently */ + } + + fprintf(FP, "%d\n", kicadLayerCount); + layer = 0; + if (physicalLayerCount >= 1) { + fprintf(FP, "Layer[%d] COPPER_LAYER_0 signal\n", layer); + } + if (physicalLayerCount > 1) { /* seems we need to ignore layers > 16 due to kicad limitation */ + for(layer = 1; (layer < (kicadLayerCount - 1)) && (layer < 15); layer++) { + fprintf(FP, "Layer[%d] Inner%d.Cu signal\n", layer, layer); + } + fputs("Layer[15] COPPER_LAYER_15 signal\n", FP); + } + + write_kicad_legacy_layout_via_drill_size(FP); + + fputs("$EndSETUP\n", FP); + + write_kicad_legacy_equipotential_netlists(FP, PCB); + write_kicad_legacy_layout_subcs(FP, PCB, PCB->Data, LayoutXOffset, LayoutYOffset); + + /* we now need to map pcb's layer groups onto the kicad layer numbers */ + currentKicadLayer = 0; + currentGroup = 0; + + /* figure out which pcb layers are bottom copper and make a list */ + bottomCount = pcb_layer_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_COPPER, NULL, 0); + if (bottomCount > 0) { + bottomLayers = malloc(sizeof(rnd_layer_id_t) * bottomCount); + pcb_layer_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_COPPER, bottomLayers, bottomCount); + } + else { + bottomLayers = NULL; + } + + /* figure out which pcb layers are internal copper layers and make a list */ + innerCount = pcb_layer_list(PCB, PCB_LYT_INTERN | PCB_LYT_COPPER, NULL, 0); + if (innerCount > 0) { + innerLayers = malloc(sizeof(rnd_layer_id_t) * innerCount); + pcb_layer_list(PCB, PCB_LYT_INTERN | PCB_LYT_COPPER, innerLayers, innerCount); + } + else { + innerLayers = NULL; + } + + /* figure out which pcb layers are top copper and make a list */ + topCount = pcb_layer_list(PCB, PCB_LYT_TOP | PCB_LYT_COPPER, NULL, 0); + if (topCount > 0) { + topLayers = malloc(sizeof(rnd_layer_id_t) * topCount); + pcb_layer_list(PCB, PCB_LYT_TOP | PCB_LYT_COPPER, topLayers, topCount); + } + else { + topLayers = NULL; + } + + /* figure out which pcb layers are bottom silk and make a list */ + bottomSilkCount = pcb_layer_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_SILK, NULL, 0); + if (bottomSilkCount > 0) { + bottomSilk = malloc(sizeof(rnd_layer_id_t) * bottomSilkCount); + pcb_layer_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_SILK, bottomSilk, bottomSilkCount); + } + else { + bottomSilk = NULL; + } + + /* figure out which pcb layers are top silk and make a list */ + topSilkCount = pcb_layer_list(PCB, PCB_LYT_TOP | PCB_LYT_SILK, NULL, 0); + if (topSilkCount > 0) { + topSilk = malloc(sizeof(rnd_layer_id_t) * topSilkCount); + pcb_layer_list(PCB, PCB_LYT_TOP | PCB_LYT_SILK, topSilk, topSilkCount); + } + else { + topSilk = NULL; + } + + /* figure out which pcb layers are outlines and make a list */ + outlineCount = pcb_layer_list(PCB, PCB_LYT_BOUNDARY, NULL, 0); + if (outlineCount > 0) { + outlineLayers = malloc(sizeof(rnd_layer_id_t) * outlineCount); + pcb_layer_list(PCB, PCB_LYT_BOUNDARY, outlineLayers, outlineCount); + } + else { + outlineLayers = NULL; + } + + /* we now proceed to write the outline tracks to the kicad file, layer by layer */ + currentKicadLayer = 28; /* 28 is the edge cuts layer in kicad */ + if (outlineCount > 0) { + for(i = 0; i < outlineCount; i++) { /* write top copper tracks, if any */ + write_kicad_legacy_layout_tracks(FP, currentKicadLayer, &(PCB->Data->Layer[outlineLayers[i]]), LayoutXOffset, LayoutYOffset); + write_kicad_legacy_layout_arcs(FP, currentKicadLayer, &(PCB->Data->Layer[outlineLayers[i]]), LayoutXOffset, LayoutYOffset); + } + } + else { /* no outline layer per se, export the board margins instead - obviously some scope to reduce redundant code... */ + fputs("$DRAWSEGMENT\n", FP); + rnd_fprintf(FP, "Po 0 %.0mk %.0mk %.0mk %.0mk %.0mk\n", PCB->hidlib.size_x / 2 - LayoutXOffset, PCB->hidlib.size_y / 2 - LayoutYOffset, PCB->hidlib.size_x / 2 + LayoutXOffset, PCB->hidlib.size_y / 2 - LayoutYOffset, outlineThickness); + rnd_fprintf(FP, "De %d 0 0 0 0\n", currentKicadLayer); + fputs("$EndDRAWSEGMENT\n", FP); + fputs("$DRAWSEGMENT\n", FP); + rnd_fprintf(FP, "Po 0 %.0mk %.0mk %.0mk %.0mk %.0mk\n", PCB->hidlib.size_x / 2 + LayoutXOffset, PCB->hidlib.size_y / 2 - LayoutYOffset, PCB->hidlib.size_x / 2 + LayoutXOffset, PCB->hidlib.size_y / 2 + LayoutYOffset, outlineThickness); + rnd_fprintf(FP, "De %d 0 0 0 0\n", currentKicadLayer); + fputs("$EndDRAWSEGMENT\n", FP); + fputs("$DRAWSEGMENT\n", FP); + rnd_fprintf(FP, "Po 0 %.0mk %.0mk %.0mk %.0mk %.0mk\n", PCB->hidlib.size_x / 2 + LayoutXOffset, PCB->hidlib.size_y / 2 + LayoutYOffset, PCB->hidlib.size_x / 2 - LayoutXOffset, PCB->hidlib.size_y / 2 + LayoutYOffset, outlineThickness); + rnd_fprintf(FP, "De %d 0 0 0 0\n", currentKicadLayer); + fputs("$EndDRAWSEGMENT\n", FP); + fputs("$DRAWSEGMENT\n", FP); + rnd_fprintf(FP, "Po 0 %.0mk %.0mk %.0mk %.0mk %.0mk\n", PCB->hidlib.size_x / 2 - LayoutXOffset, PCB->hidlib.size_y / 2 + LayoutYOffset, PCB->hidlib.size_x / 2 - LayoutXOffset, PCB->hidlib.size_y / 2 - LayoutYOffset, outlineThickness); + rnd_fprintf(FP, "De %d 0 0 0 0\n", currentKicadLayer); + fputs("$EndDRAWSEGMENT\n", FP); + } + + + /* we now proceed to write the bottom silk lines, arcs, text to the kicad legacy file, using layer 20 */ + currentKicadLayer = 20; /* 20 is the bottom silk layer in kicad */ + for(i = 0; i < bottomSilkCount; i++) { /* write bottom silk lines, if any */ + write_kicad_legacy_layout_tracks(FP, currentKicadLayer, &(PCB->Data->Layer[bottomSilk[i]]), LayoutXOffset, LayoutYOffset); + write_kicad_legacy_layout_arcs(FP, currentKicadLayer, &(PCB->Data->Layer[bottomSilk[i]]), LayoutXOffset, LayoutYOffset); + write_kicad_legacy_layout_text(FP, currentKicadLayer, &(PCB->Data->Layer[bottomSilk[i]]), LayoutXOffset, LayoutYOffset); + } + + /* we now proceed to write the bottom copper text to the kicad legacy file, layer by layer */ + currentKicadLayer = 0; /* 0 is the bottom copper layer in kicad */ + for(i = 0; i < bottomCount; i++) { /* write bottom copper tracks, if any */ + write_kicad_legacy_layout_text(FP, currentKicadLayer, &(PCB->Data->Layer[bottomLayers[i]]), LayoutXOffset, LayoutYOffset); + } /* 0 is the bottom most track in kicad */ + + /* we now proceed to write the internal copper text to the kicad file, layer by layer */ + if (innerCount > 0) { + currentGroup = pcb_layer_get_group(PCB, innerLayers[0]); + } + for(i = 0, currentKicadLayer = 1; i < innerCount; i++) { /* write inner copper text, group by group */ + if (currentGroup != pcb_layer_get_group(PCB, innerLayers[i])) { + currentGroup = pcb_layer_get_group(PCB, innerLayers[i]); + currentKicadLayer++; + if (currentKicadLayer > 14) { + currentKicadLayer = 14; /* kicad 16 layers in total, 0...15 */ + } + } + write_kicad_legacy_layout_text(FP, currentKicadLayer, &(PCB->Data->Layer[innerLayers[i]]), LayoutXOffset, LayoutYOffset); + } + + /* we now proceed to write the top copper text to the kicad legacy file, layer by layer */ + currentKicadLayer = 15; /* 15 is the top most copper layer in kicad */ + for(i = 0; i < topCount; i++) { /* write top copper tracks, if any */ + write_kicad_legacy_layout_text(FP, currentKicadLayer, &(PCB->Data->Layer[topLayers[i]]), LayoutXOffset, LayoutYOffset); + } + + /* we now proceed to write the top silk lines, arcs, text to the kicad legacy file, using layer 21 */ + currentKicadLayer = 21; /* 21 is the top silk layer in kicad */ + for(i = 0; i < topSilkCount; i++) { /* write top silk lines, if any */ + write_kicad_legacy_layout_tracks(FP, currentKicadLayer, &(PCB->Data->Layer[topSilk[i]]), LayoutXOffset, LayoutYOffset); + write_kicad_legacy_layout_arcs(FP, currentKicadLayer, &(PCB->Data->Layer[topSilk[i]]), LayoutXOffset, LayoutYOffset); + write_kicad_legacy_layout_text(FP, currentKicadLayer, &(PCB->Data->Layer[topSilk[i]]), LayoutXOffset, LayoutYOffset); + } + + /* having done the graphical elements, we move onto tracks and vias */ + fputs("$TRACK\n", FP); + write_kicad_legacy_layout_vias(FP, PCB->Data, LayoutXOffset, LayoutYOffset); + + /* we now proceed to write the bottom copper tracks to the kicad legacy file, layer by layer */ + currentKicadLayer = 0; /* 0 is the bottom copper layer in kicad */ + for(i = 0; i < bottomCount; i++) { /* write bottom copper tracks, if any */ + write_kicad_legacy_layout_tracks(FP, currentKicadLayer, &(PCB->Data->Layer[bottomLayers[i]]), LayoutXOffset, LayoutYOffset); + write_kicad_legacy_layout_arcs(FP, currentKicadLayer, &(PCB->Data->Layer[bottomLayers[i]]), LayoutXOffset, LayoutYOffset); + } /* 0 is the bottom most track in kicad */ + + /* we now proceed to write the internal copper tracks to the kicad file, layer by layer */ + if (innerCount > 0) { + currentGroup = pcb_layer_get_group(PCB, innerLayers[0]); + } + for(i = 0, currentKicadLayer = 1; i < innerCount; i++) { /* write inner copper tracks, group by group */ + if (currentGroup != pcb_layer_get_group(PCB, innerLayers[i])) { + currentGroup = pcb_layer_get_group(PCB, innerLayers[i]); + currentKicadLayer++; + if (currentKicadLayer > 14) { + currentKicadLayer = 14; /* kicad 16 layers in total, 0...15 */ + } + } + write_kicad_legacy_layout_tracks(FP, currentKicadLayer, &(PCB->Data->Layer[innerLayers[i]]), LayoutXOffset, LayoutYOffset); + write_kicad_legacy_layout_arcs(FP, currentKicadLayer, &(PCB->Data->Layer[innerLayers[i]]), LayoutXOffset, LayoutYOffset); + } + + /* we now proceed to write the top copper tracks to the kicad legacy file, layer by layer */ + currentKicadLayer = 15; /* 15 is the top most copper layer in kicad */ + for(i = 0; i < topCount; i++) { /* write top copper tracks, if any */ + write_kicad_legacy_layout_tracks(FP, currentKicadLayer, &(PCB->Data->Layer[topLayers[i]]), LayoutXOffset, LayoutYOffset); + write_kicad_legacy_layout_arcs(FP, currentKicadLayer, &(PCB->Data->Layer[topLayers[i]]), LayoutXOffset, LayoutYOffset); + } + fputs("$EndTRACK\n", FP); + + /* + * now we proceed to write polygons for each layer, and iterate much like we did for tracks + */ + + /* we now proceed to write the bottom silk polygons to the kicad legacy file, using layer 20 */ + currentKicadLayer = 20; /* 20 is the bottom silk layer in kicad */ + for(i = 0; i < bottomSilkCount; i++) { /* write bottom silk polygons, if any */ + write_kicad_legacy_layout_polygons(FP, currentKicadLayer, &(PCB->Data->Layer[bottomSilk[i]]), LayoutXOffset, LayoutYOffset); + } + + /* we now proceed to write the bottom copper polygons to the kicad legacy file, layer by layer */ + currentKicadLayer = 0; /* 0 is the bottom copper layer in kicad */ + for(i = 0; i < bottomCount; i++) { /* write bottom copper polygons, if any */ + write_kicad_legacy_layout_polygons(FP, currentKicadLayer, &(PCB->Data->Layer[bottomLayers[i]]), LayoutXOffset, LayoutYOffset); + } /* 0 is the bottom most track in kicad */ + + /* we now proceed to write the internal copper polygons to the kicad file, layer by layer */ + if (innerCount > 0) { + currentGroup = pcb_layer_get_group(PCB, innerLayers[0]); + } + for(i = 0, currentKicadLayer = 1; i < innerCount; i++) { /* write inner copper polygons, group by group */ + if (currentGroup != pcb_layer_get_group(PCB, innerLayers[i])) { + currentGroup = pcb_layer_get_group(PCB, innerLayers[i]); + currentKicadLayer++; + if (currentKicadLayer > 14) { + currentKicadLayer = 14; /* kicad 16 layers in total, 0...15 */ + } + } + write_kicad_legacy_layout_polygons(FP, currentKicadLayer, &(PCB->Data->Layer[innerLayers[i]]), LayoutXOffset, LayoutYOffset); + } + + /* we now proceed to write the top copper polygons to the kicad legacy file, layer by layer */ + currentKicadLayer = 15; /* 15 is the top most copper layer in kicad */ + for(i = 0; i < topCount; i++) { /* write top copper polygons, if any */ + write_kicad_legacy_layout_polygons(FP, currentKicadLayer, &(PCB->Data->Layer[topLayers[i]]), LayoutXOffset, LayoutYOffset); + } + + /* we now proceed to write the top silk polygons to the kicad legacy file, using layer 21 */ + currentKicadLayer = 21; /* 21 is the top silk layer in kicad */ + for(i = 0; i < topSilkCount; i++) { /* write top silk polygons, if any */ + write_kicad_legacy_layout_polygons(FP, currentKicadLayer, &(PCB->Data->Layer[topSilk[i]]), LayoutXOffset, LayoutYOffset); + } + + + fputs("$EndBOARD\n", FP); + + /* now free memory from arrays that were used */ + if (bottomCount > 0) { + free(bottomLayers); + } + if (innerCount > 0) { + free(innerLayers); + } + if (topCount > 0) { + free(topLayers); + } + if (topSilkCount > 0) { + free(topSilk); + } + if (bottomSilkCount > 0) { + free(bottomSilk); + } + if (outlineCount > 0) { + free(outlineLayers); + } + return 0; +} Index: tags/2.3.0/src_plugins/io_kicad_legacy/write.h =================================================================== --- tags/2.3.0/src_plugins/io_kicad_legacy/write.h (nonexistent) +++ tags/2.3.0/src_plugins/io_kicad_legacy/write.h (revision 33253) @@ -0,0 +1,36 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * Copyright (C) 2016 Erich S. Heinzle + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include +#include "data.h" + +int io_kicad_legacy_write_pcb(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency); +int io_kicad_legacy_write_subcs_head(pcb_plug_io_t *ctx, void **udata, FILE *f, int lib, long num_subcs); +int io_kicad_legacy_write_subcs_subc(pcb_plug_io_t *ctx, void **udata, FILE *f, pcb_subc_t *subc); +int io_kicad_legacy_write_subcs_tail(pcb_plug_io_t *ctx, void **udata, FILE *f); Index: tags/2.3.0/src_plugins/io_lihata/Makefile =================================================================== --- tags/2.3.0/src_plugins/io_lihata/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_io_lihata + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/io_lihata/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/io_lihata/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/Plug.tmpasm (revision 33253) @@ -0,0 +1,16 @@ +put /local/pcb/mod {io_lihata} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/io_lihata/io_lihata.o + $(PLUGDIR)/io_lihata/write.o + $(PLUGDIR)/io_lihata/write_style.o + $(PLUGDIR)/io_lihata/read.o + $(PLUGDIR)/io_lihata/common.o +@] +put /local/pcb/mod/CONF {$(PLUGDIR)/io_lihata/lht_conf.h} + + +switch /local/pcb/io_lihata/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/io_lihata/TODO.check =================================================================== --- tags/2.3.0/src_plugins/io_lihata/TODO.check (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/TODO.check (revision 33253) @@ -0,0 +1,4 @@ +- poly/pin shapes +- flags on any object type +- name on any object type +- line ->Number? \ No newline at end of file Index: tags/2.3.0/src_plugins/io_lihata/common.c =================================================================== --- tags/2.3.0/src_plugins/io_lihata/common.c (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/common.c (revision 33253) @@ -0,0 +1,85 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Build an in-memory lihata document that represents the board then save it. + A document is built for the merge-save. */ + +#include +#include "config.h" +#include "data.h" +#include "common.h" +#include "thermal.h" + +static const char *thermal_style[] = { + NULL, + "diagonal-sharp", + "horver-sharp", + "solid", + "diagonal-round", + "horver-round" + "noshape" +}; + +static const int thermal_style_bits[] = { + 0, + PCB_THERMAL_ON | PCB_THERMAL_DIAGONAL | PCB_THERMAL_SHARP, + PCB_THERMAL_ON | PCB_THERMAL_SHARP, + PCB_THERMAL_ON | PCB_THERMAL_SOLID, + PCB_THERMAL_ON | PCB_THERMAL_DIAGONAL | PCB_THERMAL_ROUND, + PCB_THERMAL_ON | PCB_THERMAL_ROUND, + PCB_THERMAL_ON +}; + +int io_lihata_resolve_thermal_style_old(const char *name, int ver) +{ + int n, omit = 0; + char *end; + + if (name == NULL) + return 0; + + if (ver < 6) /* old file versions did not have explicit no-shape */ + omit = 1; + + for(n = 1; n < RND_ENTRIES(thermal_style) - omit; n++) + if (strcmp(name, thermal_style[n]) == 0) + return thermal_style_bits[n]; + + n = strtol(name, &end, 10); + if (*end == '\0') { + if ((n >= 0) && (n < sizeof(thermal_style_bits) / sizeof(thermal_style_bits[0]))) + return thermal_style_bits[n]; + } + + return 0; +} + +const char *io_lihata_thermal_style_old(int idx) +{ + if ((idx > 0) && (idx < RND_ENTRIES(thermal_style))) + return thermal_style[idx]; + return NULL; +} Index: tags/2.3.0/src_plugins/io_lihata/common.h =================================================================== --- tags/2.3.0/src_plugins/io_lihata/common.h (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/common.h (revision 33253) @@ -0,0 +1,8 @@ +/* Because all the macros expect it, that's why. */ +typedef struct { + pcb_flag_t Flags; +} io_lihata_flag_holder; + +/* Convert between thermal style index and flag's textual representation */ +const char *io_lihata_thermal_style_old(int idx); +int io_lihata_resolve_thermal_style_old(const char *name, int ver); Index: tags/2.3.0/src_plugins/io_lihata/io_lihata.c =================================================================== --- tags/2.3.0/src_plugins/io_lihata/io_lihata.c (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/io_lihata.c (revision 33253) @@ -0,0 +1,271 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016..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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include "plug_io.h" +#include "read.h" +#include "write.h" +#include "io_lihata.h" + +pcb_plug_io_t plug_io_lihata_v1, plug_io_lihata_v2, plug_io_lihata_v3, + plug_io_lihata_v4, plug_io_lihata_v5, plug_io_lihata_v6, + plug_io_lihata_v7; +conf_io_lihata_t conf_io_lihata; + +pcb_plug_io_t *plug_io_lihata_default = &plug_io_lihata_v7; + +int io_lihata_fmt(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, int wr, const char *fmt) +{ + int lih = (strcmp(fmt, "lihata") == 0); + + if (strcmp(ctx->description, fmt) == 0) + return 200; + + if ((lih) && (typ & PCB_IOT_BUFFER)) { + if (wr && (ctx->write_buffer != NULL)) + return 40; + if (!wr && (ctx->parse_buffer != NULL)) + return 40; + } + + if ((lih) && (typ & PCB_IOT_PADSTACK)) { + if (wr && (ctx->write_padstack != NULL)) + return 100; + if (!wr && (ctx->parse_padstack != NULL)) + return 100; + } + + if (!lih || ((typ & (~(PCB_IOT_PCB | PCB_IOT_FONT | PCB_IOT_FOOTPRINT))) != 0)) + return 0; + + if (wr) + return ctx->save_preference_prio; + return 100; +} + +int pplg_check_ver_io_lihata(int ver_needed) { return 0; } + +void pplg_uninit_io_lihata(void) +{ + rnd_conf_unreg_fields("plugins/io_lihata/"); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v7); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v6); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v5); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v4); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v3); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v2); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v1); +} + +int pplg_init_io_lihata(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + + + plug_io_lihata_v7.plugin_data = NULL; + plug_io_lihata_v7.fmt_support_prio = io_lihata_fmt; + plug_io_lihata_v7.test_parse = io_lihata_test_parse; + plug_io_lihata_v7.parse_pcb = io_lihata_parse_pcb; + plug_io_lihata_v7.parse_footprint = io_lihata_parse_subc; + plug_io_lihata_v7.parse_font = io_lihata_parse_font; + plug_io_lihata_v7.parse_buffer = io_lihata_parse_buffer; + plug_io_lihata_v7.parse_padstack = io_lihata_parse_padstack; + plug_io_lihata_v7.write_font = io_lihata_write_font; + plug_io_lihata_v7.write_buffer = io_lihata_write_buffer; + plug_io_lihata_v7.write_padstack = io_lihata_write_padstack; + plug_io_lihata_v7.write_subcs_head = io_lihata_write_subcs_head; + plug_io_lihata_v7.write_subcs_subc = io_lihata_write_subcs_subc; + plug_io_lihata_v7.write_subcs_tail = io_lihata_write_subcs_tail; + plug_io_lihata_v7.write_pcb = io_lihata_write_pcb_v7; + plug_io_lihata_v7.default_fmt = "lihata"; + plug_io_lihata_v7.description = "lihata board v7"; + plug_io_lihata_v7.save_preference_prio = 199; + plug_io_lihata_v7.default_extension = ".lht"; + plug_io_lihata_v7.fp_extension = ".lht"; + plug_io_lihata_v7.mime_type = "application/x-pcbrnd-board"; + plug_io_lihata_v7.save_as_subd_init = io_lihata_save_as_subd_init; + plug_io_lihata_v7.save_as_subd_uninit = io_lihata_save_as_subd_uninit; + plug_io_lihata_v7.save_as_fmt_changed = io_lihata_save_as_fmt_changed; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v7); + + plug_io_lihata_v6.plugin_data = NULL; + plug_io_lihata_v6.fmt_support_prio = io_lihata_fmt; + plug_io_lihata_v6.test_parse = io_lihata_test_parse; + plug_io_lihata_v6.parse_pcb = io_lihata_parse_pcb; + plug_io_lihata_v6.parse_footprint = io_lihata_parse_subc; + plug_io_lihata_v6.parse_font = io_lihata_parse_font; + plug_io_lihata_v6.parse_buffer = io_lihata_parse_buffer; + plug_io_lihata_v6.write_font = io_lihata_write_font; + plug_io_lihata_v6.write_buffer = io_lihata_write_buffer; + plug_io_lihata_v6.write_subcs_head = io_lihata_write_subcs_head; + plug_io_lihata_v6.write_subcs_subc = io_lihata_write_subcs_subc; + plug_io_lihata_v6.write_subcs_tail = io_lihata_write_subcs_tail; + plug_io_lihata_v6.write_pcb = io_lihata_write_pcb_v6; + plug_io_lihata_v6.default_fmt = "lihata"; + plug_io_lihata_v6.description = "lihata board v6"; + plug_io_lihata_v6.save_preference_prio = 100; + plug_io_lihata_v6.default_extension = ".lht"; + plug_io_lihata_v6.fp_extension = ".lht"; + plug_io_lihata_v6.mime_type = "application/x-pcbrnd-board"; + plug_io_lihata_v6.save_as_subd_init = io_lihata_save_as_subd_init; + plug_io_lihata_v6.save_as_subd_uninit = io_lihata_save_as_subd_uninit; + plug_io_lihata_v6.save_as_fmt_changed = io_lihata_save_as_fmt_changed; + + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v6); + + + plug_io_lihata_v5.plugin_data = NULL; + plug_io_lihata_v5.fmt_support_prio = io_lihata_fmt; + plug_io_lihata_v5.test_parse = io_lihata_test_parse; + plug_io_lihata_v5.parse_pcb = io_lihata_parse_pcb; + plug_io_lihata_v5.parse_footprint = io_lihata_parse_subc; + plug_io_lihata_v5.parse_font = io_lihata_parse_font; + plug_io_lihata_v5.parse_buffer = NULL; + plug_io_lihata_v5.write_font = io_lihata_write_font; + plug_io_lihata_v5.write_buffer = NULL; + plug_io_lihata_v5.write_subcs_head = io_lihata_write_subcs_head; + plug_io_lihata_v5.write_subcs_subc = io_lihata_write_subcs_subc; + plug_io_lihata_v5.write_subcs_tail = io_lihata_write_subcs_tail; + plug_io_lihata_v5.write_pcb = io_lihata_write_pcb_v5; + plug_io_lihata_v5.default_fmt = "lihata"; + plug_io_lihata_v5.description = "lihata board v5"; + plug_io_lihata_v5.save_preference_prio = 100; + plug_io_lihata_v5.default_extension = ".lht"; + plug_io_lihata_v5.fp_extension = ".lht"; + plug_io_lihata_v5.mime_type = "application/x-pcbrnd-board"; + plug_io_lihata_v5.save_as_subd_init = io_lihata_save_as_subd_init; + plug_io_lihata_v5.save_as_subd_uninit = io_lihata_save_as_subd_uninit; + plug_io_lihata_v5.save_as_fmt_changed = io_lihata_save_as_fmt_changed; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v5); + + plug_io_lihata_v4.plugin_data = NULL; + plug_io_lihata_v4.fmt_support_prio = io_lihata_fmt; + plug_io_lihata_v4.test_parse = io_lihata_test_parse; + plug_io_lihata_v4.parse_pcb = io_lihata_parse_pcb; + plug_io_lihata_v4.parse_footprint = io_lihata_parse_subc; + plug_io_lihata_v4.parse_font = io_lihata_parse_font; + plug_io_lihata_v4.parse_buffer = NULL; + plug_io_lihata_v4.write_font = io_lihata_write_font; + plug_io_lihata_v4.write_buffer = NULL; + plug_io_lihata_v4.write_subcs_head = io_lihata_write_subcs_head; + plug_io_lihata_v4.write_subcs_subc = io_lihata_write_subcs_subc; + plug_io_lihata_v4.write_subcs_tail = io_lihata_write_subcs_tail; + plug_io_lihata_v4.write_pcb = io_lihata_write_pcb_v4; + plug_io_lihata_v4.default_fmt = "lihata"; + plug_io_lihata_v4.description = "lihata board v4"; + plug_io_lihata_v4.save_preference_prio = 100; + plug_io_lihata_v4.default_extension = ".lht"; + plug_io_lihata_v4.fp_extension = ".lht"; + plug_io_lihata_v4.mime_type = "application/x-pcbrnd-board"; + plug_io_lihata_v4.save_as_subd_init = io_lihata_save_as_subd_init; + plug_io_lihata_v4.save_as_subd_uninit = io_lihata_save_as_subd_uninit; + plug_io_lihata_v4.save_as_fmt_changed = io_lihata_save_as_fmt_changed; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v4); + + plug_io_lihata_v3.plugin_data = NULL; + plug_io_lihata_v3.fmt_support_prio = io_lihata_fmt; + plug_io_lihata_v3.test_parse = io_lihata_test_parse; + plug_io_lihata_v3.parse_pcb = io_lihata_parse_pcb; + plug_io_lihata_v3.parse_footprint = io_lihata_parse_subc; + plug_io_lihata_v3.parse_font = io_lihata_parse_font; + plug_io_lihata_v3.parse_buffer = NULL; + plug_io_lihata_v3.write_font = io_lihata_write_font; + plug_io_lihata_v3.write_buffer = NULL; + plug_io_lihata_v3.write_subcs_head = io_lihata_write_subcs_head; + plug_io_lihata_v3.write_subcs_subc = io_lihata_write_subcs_subc; + plug_io_lihata_v3.write_subcs_tail = io_lihata_write_subcs_tail; + plug_io_lihata_v3.write_pcb = io_lihata_write_pcb_v3; + plug_io_lihata_v3.default_fmt = "lihata"; + plug_io_lihata_v3.description = "lihata board v3"; + plug_io_lihata_v3.save_preference_prio = 100; + plug_io_lihata_v3.default_extension = ".lht"; + plug_io_lihata_v3.fp_extension = ".lht"; + plug_io_lihata_v3.mime_type = "application/x-pcbrnd-board"; + plug_io_lihata_v3.save_as_subd_init = io_lihata_save_as_subd_init; + plug_io_lihata_v3.save_as_subd_uninit = io_lihata_save_as_subd_uninit; + plug_io_lihata_v3.save_as_fmt_changed = io_lihata_save_as_fmt_changed; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v3); + + plug_io_lihata_v2.plugin_data = NULL; + plug_io_lihata_v2.fmt_support_prio = io_lihata_fmt; + plug_io_lihata_v2.test_parse = io_lihata_test_parse; + plug_io_lihata_v2.parse_pcb = io_lihata_parse_pcb; + plug_io_lihata_v2.parse_footprint = NULL; + plug_io_lihata_v2.parse_font = io_lihata_parse_font; + plug_io_lihata_v2.parse_buffer = NULL; + plug_io_lihata_v2.write_font = io_lihata_write_font; + plug_io_lihata_v2.write_buffer = NULL; + plug_io_lihata_v2.write_pcb = io_lihata_write_pcb_v2; + plug_io_lihata_v2.default_fmt = "lihata"; + plug_io_lihata_v2.description = "lihata board v2"; + plug_io_lihata_v2.save_preference_prio = 100; + plug_io_lihata_v2.default_extension = ".lht"; + plug_io_lihata_v2.fp_extension = ".lht"; + plug_io_lihata_v2.mime_type = "application/x-pcbrnd-board"; + plug_io_lihata_v2.save_as_subd_init = io_lihata_save_as_subd_init; + plug_io_lihata_v2.save_as_subd_uninit = io_lihata_save_as_subd_uninit; + plug_io_lihata_v2.save_as_fmt_changed = io_lihata_save_as_fmt_changed; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v2); + + plug_io_lihata_v1.plugin_data = NULL; + plug_io_lihata_v1.fmt_support_prio = io_lihata_fmt; + plug_io_lihata_v1.test_parse = io_lihata_test_parse; + plug_io_lihata_v1.parse_pcb = io_lihata_parse_pcb; + plug_io_lihata_v1.parse_footprint = NULL; + plug_io_lihata_v1.map_footprint = io_lihata_map_footprint; /* it is enough to have this for one version so the check is done only once */ + plug_io_lihata_v1.parse_font = io_lihata_parse_font; + plug_io_lihata_v1.parse_font = NULL; + plug_io_lihata_v1.write_font = io_lihata_write_font; + plug_io_lihata_v1.write_buffer = NULL; + plug_io_lihata_v1.write_pcb = io_lihata_write_pcb_v1; + plug_io_lihata_v1.default_fmt = "lihata"; + plug_io_lihata_v1.description = "lihata board v1"; + plug_io_lihata_v1.save_preference_prio = 100; + plug_io_lihata_v1.default_extension = ".lht"; + plug_io_lihata_v1.fp_extension = ".lht"; + plug_io_lihata_v1.mime_type = "application/x-pcbrnd-board"; + plug_io_lihata_v1.save_as_subd_init = io_lihata_save_as_subd_init; + plug_io_lihata_v1.save_as_subd_uninit = io_lihata_save_as_subd_uninit; + plug_io_lihata_v1.save_as_fmt_changed = io_lihata_save_as_fmt_changed; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &plug_io_lihata_v1); + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_io_lihata, field,isarray,type_name,cpath,cname,desc,flags); +#include "lht_conf_fields.h" + + return 0; +} + Index: tags/2.3.0/src_plugins/io_lihata/io_lihata.h =================================================================== --- tags/2.3.0/src_plugins/io_lihata/io_lihata.h (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/io_lihata.h (revision 33253) @@ -0,0 +1,36 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include "lht_conf.h" + +extern conf_io_lihata_t conf_io_lihata; +extern pcb_plug_io_t plug_io_lihata_v1, plug_io_lihata_v2, plug_io_lihata_v3, + plug_io_lihata_v4, plug_io_lihata_v5, plug_io_lihata_v6, + plug_io_lihata_v7; + +/* The one extedit and other code should cross-call */ +extern pcb_plug_io_t *plug_io_lihata_default; Index: tags/2.3.0/src_plugins/io_lihata/io_lihata.pup =================================================================== --- tags/2.3.0/src_plugins/io_lihata/io_lihata.pup (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/io_lihata.pup (revision 33253) @@ -0,0 +1,15 @@ +$class io +$short lihata board format +$long Load and save the design and footprints in the lihata board format. +$state works +$fmt-native yes +$fmt-feature-r lihata pcb-rnd board (any version) +$fmt-feature-w lihata pcb-rnd board (any version) +$fmt-feature-r lihata pcb-rnd footprint (any version) +$fmt-feature-w lihata pcb-rnd footprint (any version) +$fmt-feature-r lihata pcb-rnd font (any version) +$fmt-feature-w lihata pcb-rnd font (any version) +$package (core) +dep lib_compat_help +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/io_lihata/lht_conf.h =================================================================== --- tags/2.3.0/src_plugins/io_lihata/lht_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/lht_conf.h (revision 33253) @@ -0,0 +1,17 @@ +#ifndef PCB_IO_LIHATA_CONF_H +#define PCB_IO_LIHATA_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_STRING aux_pcb_pattern; /* [obsolete] file name pattern to use when generating the .pcb backup */ + RND_CFT_BOOLEAN omit_font; /* [dangerous] do not save the font subtree in board files */ + RND_CFT_BOOLEAN omit_config; /* [dangerous] do not save the config subtree in board files */ + RND_CFT_BOOLEAN omit_styles; /* do not save the routing styles subtree in board files */ + } io_lihata; + } plugins; +} conf_io_lihata_t; + +#endif Index: tags/2.3.0/src_plugins/io_lihata/read.c =================================================================== --- tags/2.3.0/src_plugins/io_lihata/read.c (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/read.c (revision 33253) @@ -0,0 +1,2967 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016..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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Load a lihata document in-memory and walk the tree and build pcb native + structs. A full dom load is used instead of the event parser so that + symlinks and tree merges can be supported later. */ + +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "board.h" +#include "data.h" +#include +#include "plug_io.h" +#include "flag_str.h" +#include +#include +#include +#include +#include +#include +#include "layer.h" +#include +#include "common.h" +#include "polygon.h" +#include "conf_core.h" +#include "obj_subc.h" +#include "pcb_minuid.h" +#include "thermal.h" +#include "io_lihata.h" +#include +#include "plug_footprint.h" +#include "vtpadstack.h" +#include "obj_pstk_inlines.h" +#include "netlist.h" + +#include "../src_plugins/lib_compat_help/subc_help.h" +#include "../src_plugins/lib_compat_help/pstk_compat.h" +#include "../src_plugins/lib_compat_help/elem_rot.h" + +typedef struct { + vtp0_t post_ids, post_thermal_old, post_thermal_heavy; + int rdver; + unsigned long warned, old_model_warned; + rnd_conf_role_t cfg_dest; +} lht_read_t; + +static pcb_data_t DUMMY_BUFFER_SUBC; + +/* Note: this works because of using str_flag compat_types */ +#define PCB_OBJ_VIA PCB_OBJ_PSTK +#define PCB_OBJ_PIN PCB_OBJ_PSTK +#define PCB_OBJ_PAD PCB_OBJ_PSTK +#define PCB_OBJ_ELEMENT PCB_OBJ_SUBC + +static pcb_data_t *parse_data(lht_read_t *rctx, pcb_board_t *pcb, pcb_data_t *dst, lht_node_t *nd, pcb_data_t *subc_parent); + +static int iolht_error(lht_node_t *nd, char *fmt, ...) +{ + gds_t str; + va_list ap; + + gds_init(&str); + gds_append_str(&str, "io_lihata parse error"); + if (nd != NULL) + rnd_append_printf(&str, " at %s:%d.%d: ", nd->file_name, nd->line, nd->col); + else + gds_append_str(&str, ": "); + + va_start(ap, fmt); + rnd_safe_append_vprintf(&str, 0, fmt, ap); + va_end(ap); + + rnd_message(RND_MSG_ERROR, "%s", str.array); + + gds_uninit(&str); + return -1; +} + +static void iolht_warn(lht_read_t *rctx, lht_node_t *nd, int wbit, char *fmt, ...) +{ + gds_t str; + va_list ap; + + if (wbit >= 0) { + unsigned long bv = 1ul << wbit; + if (rctx->warned & bv) + return; + rctx->warned |= bv; + } + + gds_init(&str); + gds_append_str(&str, "io_lihata parse warning"); + if (nd != NULL) + rnd_append_printf(&str, "at %s:%d.%d: ", nd->file_name, nd->line, nd->col); + else + gds_append_str(&str, ": "); + + va_start(ap, fmt); + rnd_safe_append_vprintf(&str, 0, fmt, ap); + va_end(ap); + + rnd_message(RND_MSG_WARNING, "%s", str.array); + + gds_uninit(&str); +} + +/* Collect objects that has unknown ID on a list. Once all objects with + known-IDs are allocated, the unknonw-ID objects are allocated a fresh + ID. This makes sure they don't occupy IDs that would be used by known-ID + objects during the load. */ +#define post_id_req(obj) vtp0_append(&rctx->post_ids, &((obj)->ID)) + +static lht_node_t missing_ok; + +static int parse_attributes(pcb_attribute_list_t *list, lht_node_t *nd) +{ + lht_node_t *n; + lht_dom_iterator_t it; + + if (nd == &missing_ok) + return 0; + + if (nd == NULL) + return 0; + + if (nd->type != LHT_HASH) + return -1; + + for(n = lht_dom_first(&it, nd); n != NULL; n = lht_dom_next(&it)) { + if (n->type == LHT_TEXT) + pcb_attribute_put(list, n->name, n->data.text.value); + } + + return 0; +} + +/* Load the (duplicated) string value of a text node into res. Return 0 on success */ +static int parse_text(char **res, lht_node_t *nd) +{ + if (nd == &missing_ok) + return 0; + if (nd == NULL) + return -1; + if (nd->type != LHT_TEXT) + return iolht_error(nd, "expected a text node\n"); + *res = rnd_strdup(nd->data.text.value); + return 0; +} + +/* Load a minuid from a text node into res. Return 0 on success */ +static int parse_minuid(minuid_bin_t res, lht_node_t *nd) +{ + if (nd == &missing_ok) + return 0; + if ((nd == NULL) || (nd->type != LHT_TEXT)) + return iolht_error(nd, "expected a text node for minuid\n"); + if (strlen(nd->data.text.value) != sizeof(minuid_str_t)-1) + return iolht_error(nd, "invalid minuid: '%s'\n", nd->data.text.value); + minuid_str2bin(res, (char *)nd->data.text.value); + return 0; +} + +/* Load the rnd_coord_t value of a text node into res. Return 0 on success */ +static int parse_coord(rnd_coord_t *res, lht_node_t *nd) +{ + double tmp; + rnd_bool success; + + if (nd == &missing_ok) + return 0; + + if (nd == NULL) + return iolht_error(nd, "Missing coord value\n"); + + if (nd->type != LHT_TEXT) + return iolht_error(nd, "Invalid coord type: '%d'\n", nd->type); + + tmp = rnd_get_value_ex(nd->data.text.value, NULL, NULL, NULL, NULL, &success); + if (!success) + return iolht_error(nd, "Invalid coord value: '%s'\n", nd->data.text.value); + + *res = tmp; + return 0; +} + +/* Load the Angle value of a text node into res. Return 0 on success */ +static int parse_angle(rnd_angle_t *res, lht_node_t *nd) +{ + double tmp; + rnd_bool success; + + if (nd == &missing_ok) + return 0; + + if (nd == NULL) + return iolht_error(nd, "Missing angle\n"); + + if (nd->type != LHT_TEXT) + return iolht_error(nd, "Invalid angle type: '%d'\n", nd->type); + + tmp = rnd_get_value_ex(nd->data.text.value, NULL, NULL, NULL, NULL, &success); + if (!success) + return iolht_error(nd, "Invalid angle value: '%s'\n", nd->data.text.value); + + *res = tmp; + return 0; +} + +static int valid_int_tail(const char *end) +{ + while(isspace(*end)) end++; + return *end == '\0'; +} + +/* Load the integer value of a text node into res. Return 0 on success */ +static int parse_int(int *res, lht_node_t *nd) +{ + long int tmp; + int base = 10; + char *end; + + if (nd == &missing_ok) + return 0; + + if (nd == NULL) + return -1; + + if (nd->type != LHT_TEXT) + return iolht_error(nd, "Invalid integer node type (int): '%d'\n", nd->type); + + if ((nd->data.text.value[0] == '0') && (nd->data.text.value[1] == 'x')) + base = 16; + tmp = strtol(nd->data.text.value, &end, base); + if (!valid_int_tail(end)) + return iolht_error(nd, "Invalid integer value (not an integer number): '%s'\n", nd->data.text.value); + + *res = tmp; + return 0; +} + + +/* Load the unsigned long value of a text node into res. Return 0 on success */ +static int parse_ulong(unsigned long *res, lht_node_t *nd) +{ + unsigned long int tmp; + int base = 10; + char *end; + + if (nd == &missing_ok) + return 0; + + if (nd == NULL) + return iolht_error(nd, "Missing unsigned long field\n"); + + if (nd->type != LHT_TEXT) + return iolht_error(nd, "Invalid integer node type (ulong): '%d'\n", nd->type); + + if ((nd->data.text.value[0] == '0') && (nd->data.text.value[1] == 'x')) + base = 16; + tmp = strtoul(nd->data.text.value, &end, base); + if (!valid_int_tail(end)) + return iolht_error(nd, "Invalid integer value (not an unsigned long integer): '%s'\n", nd->data.text.value); + + *res = tmp; + return 0; +} + +/* Load the duble value of a text node into res. Return 0 on success */ +static int parse_double(double *res, lht_node_t *nd) +{ + double tmp; + char *end; + + if (nd == &missing_ok) + return 0; + + if (nd == NULL) + return iolht_error(nd, "Missing floating point number\n"); + + if (nd->type != LHT_TEXT) + return iolht_error(nd, "Invalid floating point number type: '%d'\n", nd->type); + + tmp = strtod(nd->data.text.value, &end); + + if (*end != '\0') + return iolht_error(nd, "Invalid floating point value: '%s'\n", nd->data.text.value); + + *res = tmp; + return 0; +} + +/* Load the id name of a text node (with a prefixed name) into res. + Return 0 on success */ +static int parse_id(long int *res, lht_node_t *nd, int prefix_len) +{ + long int tmp; + char *end; + + if (nd == &missing_ok) + return 0; + + if (nd == NULL) + return iolht_error(nd, "Missing ID node\n"); + + tmp = strtol(nd->name + prefix_len, &end, 10); + if (*end != '\0') + return iolht_error(nd, "Invalid id value (must be a positive integer): '%s'\n", nd->data.text.value); + + pcb_create_ID_bump(tmp+1); + + *res = tmp; + return 0; +} + +/* Load the integer value of a text node into res. Return 0 on success */ +static int parse_idpath(pcb_board_t *pcb, pcb_idpath_t **res, lht_node_t *nd) +{ + if (nd == &missing_ok) + return -1; + + if (nd == NULL) + return -1; + + if (nd->type != LHT_TEXT) + return iolht_error(nd, "Invalid idpath node type: '%d'\n", nd->type); + + *res = pcb_str2idpath(pcb, nd->data.text.value); + return 0; +} + +/* Load the boolean value of a text node into res. + Return 0 on success */ +static int parse_bool(rnd_bool *res, lht_node_t *nd) +{ + char val[8], *end; + + if (nd == &missing_ok) + return 0; + + if (nd == NULL) + return iolht_error(nd, "Missing bool\n"); + + if (nd->type != LHT_TEXT) + return iolht_error(nd, "Invalid bool type: '%d'\n", nd->type); + + strncpy(val, nd->data.text.value, sizeof(val)-1); + val[sizeof(val)-1] = '\0'; + end = strpbrk(val, " \t\r\n"); + if (end != NULL) + *end = '\0'; + + + if ((strcmp(val, "1") == 0) || (rnd_strcasecmp(val, "on") == 0) || + (rnd_strcasecmp(val, "true") == 0) || (rnd_strcasecmp(val, "yes") == 0)) { + *res = 1; + return 0; + } + + if ((strcmp(val, "0") == 0) || (rnd_strcasecmp(val, "off") == 0) || + (rnd_strcasecmp(val, "false") == 0) || (rnd_strcasecmp(val, "no") == 0)) { + *res = 0; + return 0; + } + + return iolht_error(nd, "Invalid bool value: '%s'\n", nd->data.text.value); +} + +static int parse_coord_conf(lht_read_t *rctx, const char *path, lht_node_t *nd) +{ + rnd_coord_t tmp; + + if (nd == &missing_ok) + return 0; + if (nd == NULL) + return 0; + if (parse_coord(&tmp, nd) != 0) + return -1; + + if (rctx->cfg_dest != RND_CFR_invalid) + rnd_conf_set(rctx->cfg_dest, path, -1, nd->data.text.value, RND_POL_OVERWRITE); + return 0; +} + +static lht_node_t *hash_get(lht_node_t *hash, const char *name, int optional) +{ + lht_node_t *nd = lht_dom_hash_get(hash, name); + if (nd != NULL) + return nd; + if (optional) + return &missing_ok; + iolht_error(hash, "Missing hash field: '%s'\n", name); + return NULL; +} + +static int parse_meta(lht_read_t *rctx, pcb_board_t *pcb, lht_node_t *nd) +{ + lht_node_t *grp; + int err = 0; + + if (nd->type != LHT_HASH) + return iolht_error(nd, "board meta must be a hash\n"); + + parse_text(&pcb->hidlib.name, lht_dom_hash_get(nd, "meta")); + + parse_text(&pcb->hidlib.name, lht_dom_hash_get(nd, "board_name")); + + grp = lht_dom_hash_get(nd, "grid"); + if ((grp != NULL) && (grp->type == LHT_HASH)) { + err |= parse_coord(&pcb->hidlib.grid_ox, hash_get(grp, "offs_x", 1)); + err |= parse_coord(&pcb->hidlib.grid_oy, hash_get(grp, "offs_y", 1)); + err |= parse_coord(&pcb->hidlib.grid, hash_get(grp, "spacing", 1)); + if (err != 0) + return -1; + } + + grp = lht_dom_hash_get(nd, "size"); + if ((grp != NULL) && (grp->type == LHT_HASH)) { + err |= parse_coord(&pcb->hidlib.size_x, hash_get(grp, "x", 0)); + err |= parse_coord(&pcb->hidlib.size_y, hash_get(grp, "y", 0)); + err |= parse_coord_conf(rctx, "design/poly_isle_area", hash_get(grp, "isle_area_nm2", 1)); + err |= parse_double(&pcb->ThermScale, hash_get(grp, "thermal_scale", 1)); + if (err != 0) + return -1; + } + + grp = lht_dom_hash_get(nd, "drc"); + if ((grp != NULL) && (grp->type == LHT_HASH)) { + if (rctx->rdver >= 5) + iolht_warn(rctx, grp, 5, "Lihata board v5+ should not have drc metadata saved in board header (use the config)\n"); + err |= parse_coord_conf(rctx, "design/bloat", hash_get(grp, "bloat", 1)); + err |= parse_coord_conf(rctx, "design/shrink", hash_get(grp, "shrink", 1)); + err |= parse_coord_conf(rctx, "design/min_wid", hash_get(grp, "min_width", 1)); + err |= parse_coord_conf(rctx, "design/min_slk", hash_get(grp, "min_silk", 1)); + err |= parse_coord_conf(rctx, "design/min_drill", hash_get(grp, "min_drill", 1)); + err |= parse_coord_conf(rctx, "design/min_ring", hash_get(grp, "min_ring", 1)); + if (err != 0) + return 1; + } + + grp = lht_dom_hash_get(nd, "cursor"); + if ((grp != NULL) && (grp->type == LHT_HASH)) { + if (rctx->rdver >= 5) + iolht_warn(rctx, grp, 0, "Lihata board v5+ should not have cursor metadata saved\n"); + } + + return 0; +} + +static int parse_thermal(unsigned char *dst, lht_node_t *src) +{ + if (src == NULL) + return 0; + + if (src->type != LHT_LIST) + return iolht_error(src, "thermals must be a list\n"); + + *dst = 0; + for(src = src->data.list.first; src != NULL; src = src->next) + if (src->type == LHT_TEXT) + *dst |= pcb_thermal_str2bits(src->data.text.value); + + return 0; +} + +/* pt is a list of lihata node pointers to thermal nodes; each has user + data set to the object. Look up layer info and build the thermal. This + needs to be done in a separate pass at the end of parsing because + vias may precede layers in the lihata input file. */ +static int post_thermal_assign(lht_read_t *rctx, pcb_board_t *pcb, vtp0_t *old, vtp0_t *heavy) +{ + int i; + lht_node_t *n; + lht_dom_iterator_t it; + + /* pin/via before lihata v4: thermal is part of the object flag*/ + for(i = 0; i < vtp0_len(old); i++) { + lht_node_t *thr = old->array[i]; + pcb_pstk_t *ps = thr->user_data; + + assert(ps->type == PCB_OBJ_PSTK); + + ps->thermals.used = 0; + + for(n = lht_dom_first(&it, thr); n != NULL; n = lht_dom_next(&it)) { + if (n->type == LHT_TEXT) { + int layer = pcb_layer_by_name(pcb->Data, n->name) + 1; + if (layer > ps->thermals.used) + ps->thermals.used = layer; + } + } + + if (ps->thermals.used > 0) { + ps->thermals.shape = calloc(sizeof(ps->thermals.shape[0]), ps->thermals.used); + for(n = lht_dom_first(&it, thr); n != NULL; n = lht_dom_next(&it)) { + if (n->type == LHT_TEXT) { + int layer = pcb_layer_by_name(pcb->Data, n->name); + if (layer < 0) + return iolht_error(n, "Invalid layer name in thermal: '%s'\n", n->name); + ps->thermals.shape[layer] = io_lihata_resolve_thermal_style_old(n->data.text.value, rctx->rdver); + } + } + } + else + ps->thermals.shape = NULL; + } + vtp0_uninit(old); + + /* from lihata v4 up: thermal is an object property (on heavy terminal layer objects) */ + for(i = 0; i < vtp0_len(heavy); i++) { + lht_node_t *thr = heavy->array[i]; + pcb_any_obj_t *obj = thr->user_data; + + /* single character thermal: only on the layer the object is on */ + parse_thermal(&obj->thermal, thr); + } + vtp0_uninit(heavy); + + return 0; +} + +static int parse_flags(lht_read_t *rctx, pcb_flag_t *f, lht_node_t *fn, int object_type, unsigned char *intconn, int can_have_thermal) +{ + io_lihata_flag_holder fh; + + memset(&fh, 0, sizeof(fh)); + + if (fn != NULL) { + int n; + for (n = 0; n < pcb_object_flagbits_len; n++) { + long my_types = pcb_object_flagbits[n].object_types | ((rctx->rdver <= 4) ? pcb_object_flagbits[n].compat_types : 0); + if (my_types & object_type) { + rnd_bool b = 0; + if ((parse_bool(&b, hash_get(fn, pcb_object_flagbits[n].name, 1)) == 0) && b) + PCB_FLAG_SET(pcb_object_flagbits[n].mask, &fh); + } + } + + if ((!can_have_thermal) && (lht_dom_hash_get(fn, "thermal") != NULL)) + iolht_error(fn, "Invalid flag thermal: object type can not have a thermal (ignored)\n"); + + + if (parse_int(&n, lht_dom_hash_get(fn, "shape")) == 0) + fh.Flags.q = n; + + if ((intconn != NULL) && (rctx->rdver < 3)) + if (parse_int(&n, lht_dom_hash_get(fn, "intconn")) == 0) + *intconn = n; + } + + *f = fh.Flags; + return 0; +} + +static void parse_thermal_old(lht_read_t *rctx, pcb_any_obj_t *obj, lht_node_t *fn) +{ + lht_node_t *thr; + + if (fn == NULL) + return; + + thr = lht_dom_hash_get(fn, "thermal"); + if (thr == NULL) + return; + + thr->user_data = obj; + vtp0_append(&rctx->post_thermal_old, thr); +} + +/* heavy terminal thermal: save for later processing */ +static int parse_thermal_heavy(lht_read_t *rctx, pcb_any_obj_t *obj, lht_node_t *src) +{ + if (src == NULL) + return 0; + + if (src->type != LHT_LIST) + return iolht_error(src, "heavy thermal must be a list\n"); + + src->user_data = obj; + vtp0_append(&rctx->post_thermal_heavy, src); + + return 0; +} + +static int parse_line(lht_read_t *rctx, pcb_layer_t *ly, lht_node_t *obj, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_line_t *line; + unsigned char intconn = 0; + int err = 0; + long int id; + + if (obj->type != LHT_HASH) + return iolht_error(obj, "line.ID must be a hash\n"); + + if (ly == NULL) + return iolht_error(obj, "can't allocate line on invalid layer\n"); + + if (parse_id(&id, obj, 5) != 0) + return -1; + + line = pcb_line_alloc_id(ly, id); + parse_flags(rctx, &line->Flags, lht_dom_hash_get(obj, "flags"), PCB_OBJ_LINE, &intconn, 0); + pcb_attrib_compat_set_intconn(&line->Attributes, intconn); + parse_attributes(&line->Attributes, lht_dom_hash_get(obj, "attributes")); + + if (rctx->rdver >= 4) + parse_thermal_heavy(rctx, (pcb_any_obj_t *)line, lht_dom_hash_get(obj, "thermal")); + + err |= parse_coord(&line->Thickness, hash_get(obj, "thickness", 0)); + err |= parse_coord(&line->Clearance, hash_get(obj, "clearance", 0)); + err |= parse_coord(&line->Point1.X, hash_get(obj, "x1", 0)); + err |= parse_coord(&line->Point1.Y, hash_get(obj, "y1", 0)); + err |= parse_coord(&line->Point2.X, hash_get(obj, "x2", 0)); + err |= parse_coord(&line->Point2.Y, hash_get(obj, "y2", 0)); + + line->Point1.X += dx; + line->Point2.X += dx; + line->Point1.Y += dy; + line->Point2.Y += dy; + + post_id_req(&line->Point1); + post_id_req(&line->Point2); + + if (ly != NULL) + pcb_add_line_on_layer(ly, line); + + return err; +} + +static int parse_rat(lht_read_t *rctx, pcb_board_t *pcb, pcb_data_t *dt, lht_node_t *obj) +{ + pcb_rat_t rat, *new_rat; + int tmp, err = 0; + + if (parse_id(&rat.ID, obj, 4) != 0) + return -1; + parse_flags(rctx, &rat.Flags, lht_dom_hash_get(obj, "flags"), PCB_OBJ_LINE, NULL, 0); + + err |= parse_coord(&rat.Point1.X, hash_get(obj, "x1", 0)); + err |= parse_coord(&rat.Point1.Y, hash_get(obj, "y1", 0)); + err |= parse_coord(&rat.Point2.X, hash_get(obj, "x2", 0)); + err |= parse_coord(&rat.Point2.Y, hash_get(obj, "y2", 0)); + + err |= parse_int(&tmp, hash_get(obj, "lgrp1", 0)); + rat.group1 = tmp; + err |= parse_int(&tmp, hash_get(obj, "lgrp2", 0)); + rat.group2 = tmp; + + rat.anchor[0] = rat.anchor[1] = NULL; + err |= parse_idpath(pcb, &rat.anchor[0], hash_get(obj, "anchor1", 1)); + err |= parse_idpath(pcb, &rat.anchor[1], hash_get(obj, "anchor2", 1)); + + new_rat = pcb_rat_new(dt, rat.ID, rat.Point1.X, rat.Point1.Y, rat.Point2.X, rat.Point2.Y, rat.group1, rat.group2, + conf_core.appearance.rat_thickness, rat.Flags, NULL, NULL); + + new_rat->anchor[0] = rat.anchor[0]; + new_rat->anchor[1] = rat.anchor[1]; + + parse_attributes(&new_rat->Attributes, lht_dom_hash_get(obj, "attributes")); + + post_id_req(&new_rat->Point1); + post_id_req(&new_rat->Point2); + + return err; +} + +static int parse_arc(lht_read_t *rctx, pcb_layer_t *ly, lht_node_t *obj, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_arc_t *arc; + unsigned char intconn = 0; + int err = 0; + long int id; + + if (obj->type != LHT_HASH) + return iolht_error(obj, "arc.ID must be a hash\n"); + + if (ly == NULL) + return iolht_error(obj, "can't allocate arc on invaid layer\n"); + + if (parse_id(&id, obj, 4) != 0) + return -1; + + arc = pcb_arc_alloc_id(ly, id); + parse_flags(rctx, &arc->Flags, lht_dom_hash_get(obj, "flags"), PCB_OBJ_ARC, &intconn, 0); + pcb_attrib_compat_set_intconn(&arc->Attributes, intconn); + parse_attributes(&arc->Attributes, lht_dom_hash_get(obj, "attributes")); + + if (rctx->rdver >= 4) + parse_thermal_heavy(rctx, (pcb_any_obj_t *)arc, lht_dom_hash_get(obj, "thermal")); + + err |= parse_coord(&arc->Thickness, hash_get(obj, "thickness", 0)); + err |= parse_coord(&arc->Clearance, hash_get(obj, "clearance", 0)); + err |= parse_coord(&arc->X, hash_get(obj, "x", 0)); + err |= parse_coord(&arc->Y, hash_get(obj, "y", 0)); + err |= parse_coord(&arc->Width, hash_get(obj, "width", 0)); + err |= parse_coord(&arc->Height, hash_get(obj, "height", 0)); + err |= parse_angle(&arc->StartAngle, hash_get(obj, "astart", 0)); + err |= parse_angle(&arc->Delta, hash_get(obj, "adelta", 0)); + + if (arc->Width < 0) { + arc->Width = 0; + iolht_error(obj, "negative radius in arc - replaced it with 0\n"); + } + + if (arc->Height < 0) { + arc->Height = 0; + iolht_error(obj, "negative radius in arc - replaced it with 0\n"); + } + + arc->X += dx; + arc->Y += dy; + + if (ly != NULL) + pcb_add_arc_on_layer(ly, arc); + + return err; +} + +typedef struct { + gds_t buff; + unsigned char *iptr, *ibuff; + size_t ibs; +} ucomp_t; + +static void ucomp_dst(void *ctx_, int d) +{ + ucomp_t *ctx = ctx_; + gds_append(&ctx->buff, d); +} + +static int ucomp_src(void *ctx_) +{ + ucomp_t *ctx = ctx_; + if (ctx->ibs == 0) + return EOF; + ctx->ibs--; + return *ctx->iptr++; +} + +static htip_t id2pxm; +static lht_node_t *pxm_root; + +static rnd_pixmap_t *parse_pxm_(lht_node_t *obj) +{ + int err = 0, res, has_transp = 0; + size_t b64s; + unsigned long psx, psy; + ucomp_t uctx; + rnd_pixmap_t *pxm; + lht_node_t *pmn, *trn; + rnd_color_t transp; + + err |= parse_ulong(&psx, hash_get(obj, "sx", 0)); + err |= parse_ulong(&psy, hash_get(obj, "sy", 0)); + trn = hash_get(obj, "transparent", 0); + + if ((trn != NULL) && (trn->type == LHT_TEXT)) { + rnd_color_load_str(&transp, trn->data.text.value); + has_transp = 1; + } + + pmn = hash_get(obj, "pixmap", 0); + if ((pmn == NULL) || (pmn->type != LHT_TEXT)) { + iolht_error(obj, "Failed to find a valid gfx pixmap node\n"); + return NULL; + } + + memset(&uctx, 0, sizeof(uctx)); + b64s = strlen(pmn->data.text.value); + uctx.iptr = uctx.ibuff = malloc(b64s); + uctx.ibs = rnd_base64_str2bin(uctx.ibuff, b64s, pmn->data.text.value, b64s); + + if (uctx.ibs == -1) { + free(uctx.ibuff); + iolht_error(obj, "Failed to base64 decode pixmap gfx\n"); + return NULL; + } + + res = ulzw_decompress(&uctx, ucomp_dst, ucomp_src); + free(uctx.ibuff); + if (res != 0) { + gds_uninit(&uctx.buff); + iolht_error(obj, "Failed to decompress gfx pixmap data\n"); + return NULL; + } + + if (psx * psy * 3 != uctx.buff.used) { + gds_uninit(&uctx.buff); + iolht_error(obj, "Wrong size of pixmap\n"); + return NULL; + } + + pxm = rnd_pixmap_alloc(&PCB->hidlib, psx, psy); + pxm->p = (unsigned char *)uctx.buff.array; + if (has_transp) { + pxm->has_transp = 1; + pxm->tr = transp.r; + pxm->tg = transp.g; + pxm->tb = transp.b; + } + return pxm; +} + +static rnd_pixmap_t *parse_pxm(long int ID) +{ + lht_node_t *nd; + char buff[128]; + rnd_pixmap_t *pxm; + + if (pxm_root == NULL) + return NULL; + + pxm = htip_get(&id2pxm, ID); + if (pxm != NULL) + return pxm; + + sprintf(buff, "ulzw.%ld", ID); + nd = hash_get(pxm_root, buff, 0); + if (nd == NULL) + return NULL; + + pxm = parse_pxm_(nd); + if (pxm == NULL) + return NULL; + + htip_set(&id2pxm, ID, pxm); + return pxm; +} + + +static int pxm_inited = 0; +static void pxm_init(lht_read_t *rctx, lht_node_t *pixmaps) +{ + pxm_root = NULL; + if (rctx->rdver >= 7) + pxm_root = pixmaps; + htip_init(&id2pxm, longhash, longkeyeq); + pxm_inited = 1; +} + +static void pxm_uninit(void) +{ + htip_entry_t *e; + if (!pxm_inited) + return; + for(e = htip_first(&id2pxm); e != NULL; e = htip_next(&id2pxm, e)) + rnd_pixmap_free(e->value); + htip_uninit(&id2pxm); + pxm_root = NULL; + pxm_inited = 0; +} + + +static int parse_gfx(lht_read_t *rctx, pcb_board_t *pcb, pcb_layer_t *ly, lht_node_t *obj, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_gfx_t *gfx; + unsigned char intconn = 0; + int err = 0, itmp; + long int id; + unsigned long int refid; + rnd_pixmap_t *pxm; + + + if (obj->type != LHT_HASH) + return iolht_error(obj, "gfx.ID must be a hash\n"); + + if (ly == NULL) + return iolht_error(obj, "can't allocate gfx on invalid layer\n"); + + if (parse_id(&id, obj, 4) != 0) + return -1; + + gfx = pcb_gfx_alloc_id(ly, id); + parse_flags(rctx, &gfx->Flags, lht_dom_hash_get(obj, "flags"), PCB_OBJ_ARC, &intconn, 0); + pcb_attrib_compat_set_intconn(&gfx->Attributes, intconn); + parse_attributes(&gfx->Attributes, lht_dom_hash_get(obj, "attributes")); + + if (rctx->rdver >= 4) + parse_thermal_heavy(rctx, (pcb_any_obj_t *)gfx, lht_dom_hash_get(obj, "thermal")); + + err |= parse_coord(&gfx->cx, hash_get(obj, "cx", 0)); + err |= parse_coord(&gfx->cy, hash_get(obj, "cy", 0)); + err |= parse_coord(&gfx->sx, hash_get(obj, "sx", 0)); + err |= parse_coord(&gfx->sy, hash_get(obj, "sy", 0)); + err |= parse_angle(&gfx->rot, hash_get(obj, "rot", 0)); + err |= parse_int(&itmp, hash_get(obj, "xmirror", 0)); gfx->xmirror = itmp; + err |= parse_int(&itmp, hash_get(obj, "ymirror", 0)); gfx->ymirror = itmp; + err |= parse_ulong(&refid, hash_get(obj, "pixmap_ref", 0)); + + if (err != 0) { + pcb_gfx_free(gfx); + return err; + } + + gfx->cx += dx; + gfx->cy += dy; + + pxm = parse_pxm(refid); + if (pxm == NULL) { + pcb_gfx_free(gfx); + return iolht_error(obj, "Failed to load referenced pixmap\n"); + } + + pcb_gfx_set_pixmap_dup(gfx, pxm, 0); + gfx->pxm_id = refid; + + pcb_gfx_update(gfx); + if (ly != NULL) + pcb_add_gfx_on_layer(ly, gfx); + + return err; +} + + +static int parse_polygon(lht_read_t *rctx, pcb_layer_t *ly, lht_node_t *obj) +{ + pcb_poly_t *poly; + lht_node_t *geo; + rnd_cardinal_t n = 0, c; + unsigned char intconn = 0; + int err = 0; + long int id; + + if (obj->type != LHT_HASH) + return iolht_error(obj, "polygon.ID must be a hash\n"); + + if (parse_id(&id, obj, 8) != 0) + return -1; + poly = pcb_poly_alloc_id(ly, id); + parse_flags(rctx, &poly->Flags, lht_dom_hash_get(obj, "flags"), PCB_OBJ_POLY, &intconn, 0); + pcb_attrib_compat_set_intconn(&poly->Attributes, intconn); + parse_attributes(&poly->Attributes, lht_dom_hash_get(obj, "attributes")); + + if (rctx->rdver >= 3) + err |= parse_coord(&poly->Clearance, hash_get(obj, "clearance", 1)); + + if (rctx->rdver >= 7) + err |= parse_coord(&poly->enforce_clearance, hash_get(obj, "enforce_clearance", 1)); + + if (rctx->rdver >= 4) + parse_thermal_heavy(rctx, (pcb_any_obj_t *)poly, lht_dom_hash_get(obj, "thermal")); + + geo = lht_dom_hash_get(obj, "geometry"); + if ((geo != NULL) && (geo->type == LHT_LIST)) { + lht_node_t *cnt; + lht_dom_iterator_t it; + + /* count points and holes */ + poly->PointN = 0; + for(c = 0, cnt = lht_dom_first(&it, geo); cnt != NULL; c++, cnt = lht_dom_next(&it)) { + if (cnt->type != LHT_TABLE) + continue; + poly->PointN += cnt->data.table.rows; + } + poly->PointMax = poly->PointN; + poly->Points = malloc(sizeof(rnd_point_t) * poly->PointMax); + poly->HoleIndexMax = poly->HoleIndexN = c-1; + if (poly->HoleIndexN > 0) + poly->HoleIndex = malloc(sizeof(rnd_cardinal_t) * poly->HoleIndexMax); + else + poly->HoleIndex = NULL; + + /* convert points and build hole index */ + for(c = 0, cnt = lht_dom_first(&it, geo); cnt != NULL; c++, cnt = lht_dom_next(&it)) { + rnd_cardinal_t r; + if (cnt->type != LHT_TABLE) + continue; + if (c > 0) + poly->HoleIndex[c-1] = n; + for(r = 0; r < cnt->data.table.rows; r++) { + err |= parse_coord(&poly->Points[n].X, cnt->data.table.r[r][0]); + err |= parse_coord(&poly->Points[n].Y, cnt->data.table.r[r][1]); + /* a point also needs to be a box on paper, but the poly code sets X2 and Y2 to 0 in reality... */ + poly->Points[n].X2 = poly->Points[n].Y2 = 0; + post_id_req(&poly->Points[n]); + n++; + } + } + } + else { + pcb_poly_free(poly); + return iolht_error(obj, "invalid polygon: empty geometry\n"); + } + + if (poly->PointN < 3) { + pcb_poly_free(poly); + return iolht_error(obj, "invalid polygon: less than 3 contour vertices\n"); + } + + if (err != 0) { + pcb_poly_free(poly); + return -1; + } + + pcb_add_poly_on_layer(ly, poly); + pcb_poly_init_clip(ly->parent.data, ly, poly); + + return 0; +} + +static int parse_pcb_text(lht_read_t *rctx, pcb_layer_t *ly, lht_node_t *obj) +{ + pcb_text_t *text; + lht_node_t *role, *nthickness, *nrot, *ndir; + int tmp, err = 0, dir; + unsigned char intconn = 0; + long int id; + + if (obj->type != LHT_HASH) + return iolht_error(obj, "text.ID must be a hash\n"); + + role = lht_dom_hash_get(obj, "role"); + + if (ly == NULL) + return iolht_error(obj, "failed to allocate text object (layer == NULL)\n"); + + if (parse_id(&id, obj, 5) != 0) + return -1; + + if (role != NULL) + return iolht_error(obj, "invalid role: text on layer shall not have a role\n"); + + text = pcb_text_alloc_id(ly, id); + if (text == NULL) + return iolht_error(obj, "failed to allocate text object\n"); + + parse_flags(rctx, &text->Flags, lht_dom_hash_get(obj, "flags"), PCB_OBJ_TEXT, &intconn, 0); + pcb_attrib_compat_set_intconn(&text->Attributes, intconn); + parse_attributes(&text->Attributes, lht_dom_hash_get(obj, "attributes")); + err |= parse_int(&text->Scale, hash_get(obj, "scale", 0)); + err |= parse_double(&text->scale_x, hash_get(obj, "scale_x", 1)); + err |= parse_double(&text->scale_y, hash_get(obj, "scale_y", 1)); + tmp = 0; + err |= parse_int(&tmp, hash_get(obj, "fid", 0)); + text->fid = tmp; + tmp = 0; + err |= parse_coord(&text->X, hash_get(obj, "x", 0)); + err |= parse_coord(&text->Y, hash_get(obj, "y", 0)); + err |= parse_text(&text->TextString, hash_get(obj, "string", 0)); + + nthickness = lht_dom_hash_get(obj, "thickness"); + nrot = lht_dom_hash_get(obj, "rot"); + ndir = lht_dom_hash_get(obj, "direction"); + + + if (nthickness != NULL) { + if (rctx->rdver < 6) + iolht_warn(rctx, nthickness, -1, "Text thickness should not be present in a file with version lower than v6\n"); + err |= parse_coord(&text->thickness, nthickness); + } + else + text->thickness = 0; + + if ((ndir != NULL) && (rctx->rdver >= 6)) + iolht_warn(rctx, nthickness, -1, "Text direction should not be present in a file with version higher than v5 - use text rot instead\n"); + + if (nrot != 0) { + if (rctx->rdver < 6) + iolht_warn(rctx, nthickness, -1, "Text rot should not be present in a file with version lower than v6\n"); + err |= parse_double(&text->rot, nrot); + } + else { + if (ndir != NULL) { + err |= parse_int(&dir, ndir); + dir %= 4; + if (dir < 0) + dir += 4; + text->rot = 90.0 * dir; + } + else + text->rot = 0; + } + + if (ly != NULL) + pcb_add_text_on_layer(ly, text, pcb_font(PCB, text->fid, 1)); + + return err; +} + +static int parse_layer_type(lht_read_t *rctx, pcb_layer_type_t *dst, const char **dst_purpose, lht_node_t *nd, const char *loc) +{ + lht_node_t *flg; + lht_dom_iterator_t itt; + + if (nd == NULL) + return -1; + + *dst_purpose = NULL; + + for(flg = lht_dom_first(&itt, nd); flg != NULL; flg = lht_dom_next(&itt)) { + pcb_layer_type_t val; + if (rctx->rdver < 6) { + if (strcmp(flg->name, "outline") == 0) { + *dst |= PCB_LYT_BOUNDARY; + *dst_purpose = "uroute"; + continue; + } + } + + val = pcb_layer_type_str2bit(flg->name); + if (val == 0) + iolht_error(flg, "Invalid type name: '%s' in %s (ignoring the type flag)\n", flg->name, loc); + *dst |= val; + if (rctx->rdver < 6) { + if (val & (PCB_LYT_MECH | PCB_LYT_DOC | PCB_LYT_BOUNDARY)) + iolht_warn(rctx, flg, -1, "Potentially invalid type name: '%s' in %s - lihata board before v6 did not support it\n(accepting it for now, but expect broken layer stack)\n", flg->name, loc); + } + } + + return 0; +} + +static pcb_layer_combining_t parse_comb(pcb_board_t *pcb, lht_node_t *ncmb) +{ + lht_node_t *n; + pcb_layer_combining_t comb = 0; + lht_dom_iterator_t it; + + for(n = lht_dom_first(&it, ncmb); n != NULL; n = lht_dom_next(&it)) { + pcb_layer_combining_t cval; + if (n->type != LHT_TEXT) { + iolht_error(n, "Ignoring non-text combining flag\n"); + continue; + } + cval = pcb_layer_comb_str2bit(n->name); + if (cval == 0) + iolht_error(n, "Ignoring unknown combining flag: '%s'\n", n->name); + comb |= cval; + } + + return comb; +} + +static int parse_data_layer(lht_read_t *rctx, pcb_board_t *pcb, pcb_data_t *dt, lht_node_t *grp, int layer_id, int bound, pcb_data_t *subc_parent) +{ + lht_node_t *n, *lst, *ncmb, *nvis, *npurp; + lht_dom_iterator_t it; + pcb_layer_t *ly = &dt->Layer[layer_id]; + + if (layer_id >= PCB_MAX_LAYER) + return iolht_error(grp, "Board has more layers than supported by this compilation of pcb-rnd (%d)\nIf this is a valid board, please increase PCB_MAX_LAYER and recompile.\n", PCB_MAX_LAYER); + if (layer_id >= dt->LayerN) + dt->LayerN = layer_id+1; + + ly->parent.data = dt; + ly->parent_type = PCB_PARENT_DATA; + ly->type = PCB_OBJ_LAYER; + + parse_attributes(&ly->Attributes, lht_dom_hash_get(grp, "attributes")); + + ncmb = lht_dom_hash_get(grp, "combining"); + if (ncmb != NULL) { + if (rctx->rdver < 2) + iolht_warn(rctx, ncmb, 1, "Version 1 lihata board should not have combining subtree for layers\n"); + ly->comb = parse_comb(pcb, ncmb); + } + + npurp = lht_dom_hash_get(grp, "purpose"); + if ((rctx->rdver < 6) && (npurp != NULL)) + iolht_warn(rctx, npurp, -1, "Lihata board below v6 should not have layer purpose (the file may not load correctly in older versions of pcb-rnd)\n"); + + if (!bound && (npurp != NULL)) + iolht_warn(rctx, npurp, -1, "Only bound layers should have purpose - ignoring this field\n"); + + if (bound) { + const char *prp; + ly->is_bound = 1; + ly->name = rnd_strdup(grp->name); + parse_int(&dt->Layer[layer_id].meta.bound.stack_offs, lht_dom_hash_get(grp, "stack_offs")); + parse_layer_type(rctx, &dt->Layer[layer_id].meta.bound.type, &prp, lht_dom_hash_get(grp, "type"), "bound layer"); + if (npurp != NULL) { /* use the explicit purpose if it is set */ + if (npurp->type == LHT_TEXT) + dt->Layer[layer_id].meta.bound.purpose = rnd_strdup(npurp->data.text.value); + else + iolht_warn(rctx, npurp, -1, "Layers purpose shall be text - ignoring this field\n"); + } + else if (prp != NULL) /* or the implicit one from parse_layer_type(rctx, ), for old versions */ + dt->Layer[layer_id].meta.bound.purpose = rnd_strdup(prp); + + if (pcb != NULL) { + dt->Layer[layer_id].meta.bound.real = pcb_layer_resolve_binding(pcb, &dt->Layer[layer_id]); + if (dt->Layer[layer_id].meta.bound.real != NULL) + pcb_layer_link_trees(&dt->Layer[layer_id], dt->Layer[layer_id].meta.bound.real); + else if (!(dt->Layer[layer_id].meta.bound.type & PCB_LYT_VIRTUAL)) + iolht_warn(rctx, ncmb, 2, "Can't bind subcircuit layer %s: can't find anything similar on the current board\n", dt->Layer[layer_id].name); + if (subc_parent != NULL) + dt->padstack_tree = subc_parent->padstack_tree; + } + } + else { + /* real */ + lht_node_t *nclr; + ly->name = rnd_strdup(grp->name); + nclr = hash_get(grp, "color", 1); + if ((nclr != NULL) && (nclr->type != LHT_INVALID_TYPE)) { + if (rctx->rdver < 5) + iolht_warn(rctx, nclr, 1, "layer color was not supprted before lihata board v5 (reading from v%d)\n", rctx->rdver); + if (nclr->type == LHT_TEXT) { + if (rnd_color_load_str(&ly->meta.real.color, nclr->data.text.value) != 0) + return iolht_error(nclr, "Invalid color: '%s'\n", nclr->data.text.value); + } + else + iolht_warn(rctx, nclr, 1, "Ignoring color: text node required\n"); + } + + nvis = hash_get(grp, "visible", 1); + if ((nvis != &missing_ok) && rctx->rdver >= 6) + iolht_warn(rctx, nvis, -1, "saving layer visibility was supported only before lihata board v6 (reading from v%d)\n", rctx->rdver); + parse_bool(&ly->meta.real.vis, nvis); + if (pcb != NULL) { + int grp_id; + parse_int(&grp_id, hash_get(grp, "group", 0)); + dt->Layer[layer_id].meta.real.grp = grp_id; + /* rnd_trace("parse_data_layer name: %d,%d '%s' grp=%d\n", layer_id, dt->LayerN-1, ly->name, grp_id);*/ + } + } + + lst = lht_dom_hash_get(grp, "objects"); + if (lst != NULL) { + if (lst->type != LHT_LIST) + return iolht_error(lst, "objects must be in a list\n"); + + for(n = lht_dom_first(&it, lst); n != NULL; n = lht_dom_next(&it)) { + if (strncmp(n->name, "line.", 5) == 0) + parse_line(rctx, ly, n, 0, 0); + if (strncmp(n->name, "arc.", 4) == 0) + parse_arc(rctx, ly, n, 0, 0); + if (strncmp(n->name, "gfx.", 4) == 0) + parse_gfx(rctx, pcb, ly, n, 0, 0); + if (strncmp(n->name, "polygon.", 8) == 0) + parse_polygon(rctx, ly, n); + if (strncmp(n->name, "text.", 5) == 0) + parse_pcb_text(rctx, ly, n); + } + } + + return 0; +} + +static int parse_data_layers(lht_read_t *rctx, pcb_board_t *pcb, pcb_data_t *dt, lht_node_t *grp, int bound, pcb_data_t *subc_parent) +{ + int id; + lht_node_t *n; + lht_dom_iterator_t it; + + for(id = 0, n = lht_dom_first(&it, grp); n != NULL; id++, n = lht_dom_next(&it)) + if (n->type == LHT_HASH) + if (parse_data_layer(rctx, pcb, dt, n, id, bound, subc_parent) < 0) + return -1; + + return 0; +} + +static int parse_pstk(lht_read_t *rctx, pcb_data_t *dt, lht_node_t *obj) +{ + pcb_pstk_t *ps; + lht_node_t *thl, *t; + unsigned char intconn = 0; + unsigned long int pid; + int tmp, err = 0; + long int id; + + if (obj->type != LHT_HASH) + return iolht_error(obj, "pstk.ID must be a hash\n"); + + parse_ulong(&pid, lht_dom_hash_get(obj, "proto")); + if (pcb_pstk_get_proto_(dt, pid) == NULL) + return iolht_error(obj, "Padstack references to non-existent prototype\n"); + + if (parse_id(&id, obj, 13) != 0) + return -1; + + ps = pcb_pstk_alloc_id(dt, id); + + parse_flags(rctx, &ps->Flags, lht_dom_hash_get(obj, "flags"), PCB_OBJ_PSTK, &intconn, 0); + pcb_attrib_compat_set_intconn(&ps->Attributes, intconn); + parse_attributes(&ps->Attributes, lht_dom_hash_get(obj, "attributes")); + + err |= parse_coord(&ps->x, hash_get(obj, "x", 0)); + err |= parse_coord(&ps->y, hash_get(obj, "y", 0)); + err |= parse_double(&ps->rot, hash_get(obj, "rot", 0)); + tmp = 0; + err |= parse_int(&tmp, hash_get(obj, "xmirror", 1)); + ps->xmirror = tmp; + tmp = 0; + err |= parse_int(&tmp, hash_get(obj, "smirror", 1)); + ps->smirror = tmp; + ps->Clearance = 0; + parse_coord(&ps->Clearance, hash_get(obj, "clearance", 1)); + ps->proto = pid; + if (err != 0) + return -1; + + thl = lht_dom_hash_get(obj, "thermal"); + if ((thl != NULL) && (thl->type == LHT_LIST)) { + int max, n; + max = 0; + for(t = thl->data.list.first, n = 0; t != NULL; t = t->next,n++) + { + if (t->type == LHT_LIST) { + char *end; + int ly = strtol(t->name, &end, 10); + if ((*end == '\0') && (ly > max)) + max = ly; + } + } + if (n > max) + max = n; + + ps->thermals.used = max+1; + ps->thermals.shape = calloc(sizeof(ps->thermals.shape[0]), ps->thermals.used); + for(t = thl->data.list.first, n = 0; t != NULL; t = t->next, n++) { + int i; + if (t->type == LHT_TEXT) { + parse_int(&i, t); + ps->thermals.shape[n] = i; + } + else if (t->type == LHT_LIST) { + unsigned char dst; + char *end; + int ly = strtol(t->name, &end, 10); + if ((*end == '\0') && (ly < ps->thermals.used)) { + parse_thermal(&dst, t); + ps->thermals.shape[ly] = dst; + } + } + } + } + + pcb_pstk_add(dt, ps); + + return 0; +} + +static void warn_old_model(lht_read_t *rctx, lht_node_t *obj, char *type, int warnid) +{ + unsigned long warnbit = 1ul << warnid; + if ((rctx->rdver < 5) || (rctx->old_model_warned & warnbit)) + return; + + rctx->old_model_warned |= warnbit; + iolht_warn(rctx, obj, -1, "Lihata from v5 does not support the old data model (elements, pins, pads and vias);\nyour file contains %s that will be converted to the new model\n", type); +} + +static int parse_via(lht_read_t *rctx, pcb_data_t *dt, lht_node_t *obj, rnd_coord_t dx, rnd_coord_t dy, int subc_on_bottom) +{ + pcb_pstk_t *ps; + unsigned char intconn = 0; + rnd_coord_t Thickness, Clearance, Mask = 0, DrillingHole, X, Y; + char *Name = NULL, *Number = NULL; + pcb_flag_t flg; + lht_node_t *fln; + int err = 0; + long int id; + + if (dt == NULL) + return -1; + + warn_old_model(rctx, obj, "via", 1); + + parse_flags(rctx, &flg, fln=lht_dom_hash_get(obj, "flags"), PCB_OBJ_VIA, &intconn, 1); + err |= parse_coord(&Thickness, hash_get(obj, "thickness", 0)); + err |= parse_coord(&Clearance, hash_get(obj, "clearance", 0)); + err |= parse_coord(&Mask, hash_get(obj, "mask", 1)); + err |= parse_coord(&DrillingHole, hash_get(obj, "hole", 0)); + err |= parse_coord(&X, hash_get(obj, "x", 0)); + err |= parse_coord(&Y, hash_get(obj, "y", 0)); + err |= parse_text(&Name, hash_get(obj, "name", 1)); + err |= parse_text(&Number, hash_get(obj, "number", 1)); + if (err != 0) + return -1; + + if (parse_id(&id, obj, 4) != 0) + return -1; + + ps = pcb_old_via_new(dt, id, X+dx, Y+dy, Thickness, Clearance, Mask, DrillingHole, Name, flg); + if (ps == NULL) { + iolht_error(obj, "Failed to convert old via to padstack (this via is LOST)\n"); + return 0; + } + + pcb_attrib_compat_set_intconn(&ps->Attributes, intconn); + parse_attributes(&ps->Attributes, lht_dom_hash_get(obj, "attributes")); + + parse_thermal_old(rctx, (pcb_any_obj_t *)ps, fln); + + if (Number != NULL) + pcb_attribute_put(&ps->Attributes, "term", Number); + if (Name != NULL) + pcb_attribute_put(&ps->Attributes, "name", Name); + + if (subc_on_bottom) + pcb_pstk_mirror(ps, PCB_PSTK_DONT_MIRROR_COORDS, 1, 0, 0); + + return err; +} + +static int parse_pad(lht_read_t *rctx, pcb_subc_t *subc, lht_node_t *obj, rnd_coord_t dx, rnd_coord_t dy, int subc_on_bottom) +{ + pcb_pstk_t *p; + unsigned char intconn = 0; + pcb_flag_t flg; + rnd_coord_t X1, Y1, X2, Y2, Thickness, Clearance, Mask = 0; + char *Name = NULL, *Number = NULL; + int err = 0; + long int id; + + warn_old_model(rctx, obj, "pad", 2); + + parse_flags(rctx, &flg, lht_dom_hash_get(obj, "flags"), PCB_OBJ_PAD, &intconn, 0); + + err |= parse_coord(&Thickness, hash_get(obj, "thickness", 0)); + err |= parse_coord(&Clearance, hash_get(obj, "clearance", 0)); + err |= parse_coord(&Mask, hash_get(obj, "mask", 1)); + err |= parse_coord(&X1, hash_get(obj, "x1", 0)); + err |= parse_coord(&Y1, hash_get(obj, "y1", 0)); + err |= parse_coord(&X2, hash_get(obj, "x2", 0)); + err |= parse_coord(&Y2, hash_get(obj, "y2", 0)); + err |= parse_text(&Name, hash_get(obj, "name", 1)); + err |= parse_text(&Number, hash_get(obj, "number", 1)); + + if (err != 0) + return -1; + + if (parse_id(&id, obj, 4) != 0) + return -1; + + p = pcb_pstk_new_compat_pad(subc->data, id, X1+dx, Y1+dy, X2+dx, Y2+dy, Thickness, Clearance, Mask, flg.f & PCB_FLAG_SQUARE, flg.f & PCB_FLAG_NOPASTE, (!!(flg.f & PCB_FLAG_ONSOLDER))); + if (Number != NULL) + pcb_attribute_put(&p->Attributes, "term", Number); + if (Name != NULL) + pcb_attribute_put(&p->Attributes, "name", Name); + + if (subc_on_bottom) + pcb_pstk_mirror(p, PCB_PSTK_DONT_MIRROR_COORDS, 1, 0, 0); + + pcb_attrib_compat_set_intconn(&p->Attributes, intconn); + parse_attributes(&p->Attributes, lht_dom_hash_get(obj, "attributes")); + + return 0; +} + + +static int parse_element(lht_read_t *rctx, pcb_board_t *pcb, pcb_data_t *dt, lht_node_t *obj) +{ + pcb_subc_t *subc = pcb_subc_alloc(); + pcb_layer_t *silk = NULL; + lht_node_t *lst, *n; + lht_dom_iterator_t it; + int onsld, tdir = 0, tscale = 100; + rnd_coord_t ox = 0, oy = 0, tx, ty; + pcb_text_t *txt; + int err = 0; + + warn_old_model(rctx, obj, "element", 3); + + if (parse_id(&subc->ID, obj, 8) != 0) + return -1; + + pcb_subc_reg(dt, subc); + pcb_obj_id_reg(dt, subc); + + parse_flags(rctx, &subc->Flags, lht_dom_hash_get(obj, "flags"), PCB_OBJ_ELEMENT, NULL, 0); + parse_attributes(&subc->Attributes, lht_dom_hash_get(obj, "attributes")); + err |= parse_coord(&ox, hash_get(obj, "x", 0)); + err |= parse_coord(&oy, hash_get(obj, "y", 0)); + tx = ox; + ty = oy; + + onsld = PCB_FLAG_TEST(PCB_FLAG_ONSOLDER, subc); + subc->Flags.f &= ~PCB_FLAG_ONSOLDER; + + /* bind the via rtree so that vias added in this subc show up on the board */ + if (pcb != NULL) + pcb_subc_bind_globals(pcb, subc); + + /* the only layer objects are put on from and old element is the primary silk layer */ + { + pcb_layer_type_t silk_side = onsld ? PCB_LYT_BOTTOM : PCB_LYT_TOP; + const char *name = onsld ? "bottom-silk" : "top-silk"; + silk = pcb_subc_get_layer(subc, PCB_LYT_SILK | silk_side, /*PCB_LYC_AUTO*/0, rnd_true, name, rnd_false); + } + + lst = lht_dom_hash_get(obj, "objects"); + if (lst == NULL) + return iolht_error(obj, "Invalid element: no objects\n"); + if (lst->type == LHT_LIST) { + for(n = lht_dom_first(&it, lst); n != NULL; n = lht_dom_next(&it)) { + if (strncmp(n->name, "line.", 5) == 0) + parse_line(rctx, silk, n, ox, oy); + if (strncmp(n->name, "arc.", 4) == 0) + parse_arc(rctx, silk, n, ox, oy); + if (strncmp(n->name, "text.", 5) == 0) { + lht_node_t *role = lht_dom_hash_get(n, "role"); + lht_node_t *string = lht_dom_hash_get(n, "string"); + if ((role != NULL) && (role->type == LHT_TEXT) && (string != NULL) && (string->type == LHT_TEXT)) { + const char *key = role->data.text.value; + const char *val = string->data.text.value; + if (strcmp(key, "desc") == 0) pcb_attribute_put(&subc->Attributes, "footprint", val); + if (strcmp(key, "value") == 0) pcb_attribute_put(&subc->Attributes, "value", val); + if (strcmp(key, "name") == 0) pcb_attribute_put(&subc->Attributes, "refdes", val); + err |= parse_coord(&tx, hash_get(n, "x", 0)); + err |= parse_coord(&ty, hash_get(n, "y", 0)); + err |= parse_coord(&tdir, hash_get(n, "direction", 1)); + err |= parse_coord(&tscale, hash_get(n, "scale", 1)); + } + } + if (strncmp(n->name, "pin.", 4) == 0) + parse_via(rctx, subc->data, n, ox, oy, onsld); + if (strncmp(n->name, "pad.", 4) == 0) + parse_pad(rctx, subc, n, ox, oy, onsld); + } + } + else + return iolht_error(obj, "invalid element: objects is not a list\n"); + +TODO("subc: TextFlags") + txt = pcb_subc_add_refdes_text(subc, tx, ty, tdir, tscale, onsld); + + pcb_subc_xy_rot_pnp(subc, ox, oy, onsld); + + pcb_subc_bbox(subc); + + if (dt->subc_tree == NULL) + dt->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(dt->subc_tree, (rnd_box_t *)subc); + + pcb_subc_rebind(pcb, subc); + + return err; +} + +static int parse_subc(lht_read_t *rctx, pcb_board_t *pcb, pcb_data_t *dt, lht_node_t *obj, pcb_subc_t **subc_out) +{ + pcb_subc_t *sc = pcb_subc_alloc(); + unsigned char intconn = 0; + int n; + + if (obj->type != LHT_HASH) + return iolht_error(obj, "subc.ID must be a hash\n"); + + parse_id(&sc->ID, obj, 5); + parse_flags(rctx, &sc->Flags, lht_dom_hash_get(obj, "flags"), PCB_OBJ_ELEMENT, &intconn, 0); + pcb_attrib_compat_set_intconn(&sc->Attributes, intconn); + parse_attributes(&sc->Attributes, lht_dom_hash_get(obj, "attributes")); + parse_minuid(sc->uid, lht_dom_hash_get(obj, "uid")); + + if (!dt->padstack_tree) + dt->padstack_tree = rnd_r_create_tree(); + sc->data->padstack_tree = dt->padstack_tree; + + pcb_subc_reg(dt, sc); + pcb_obj_id_reg(dt, sc); + + if (parse_data(rctx, pcb, sc->data, lht_dom_hash_get(obj, "data"), dt) == 0) + return iolht_error(obj, "Invalid subc: no data\n"); + + for(n = 0; n < sc->data->LayerN; n++) + sc->data->Layer[n].is_bound = 1; + + pcb_data_bbox(&sc->BoundingBox, sc->data, rnd_true); + pcb_data_bbox_naked(&sc->bbox_naked, sc->data, rnd_true); + + if (!dt->subc_tree) + dt->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(dt->subc_tree, (rnd_box_t *)sc); + + if (subc_out != NULL) + *subc_out = sc; + + return 0; +} + + +static int parse_data_objects(lht_read_t *rctx, pcb_board_t *pcb_for_font, pcb_data_t *dt, lht_node_t *grp) +{ + lht_node_t *n; + lht_dom_iterator_t it; + + if (grp->type != LHT_LIST) + return iolht_error(grp, "groups must be a list\n"); + + for(n = lht_dom_first(&it, grp); n != NULL; n = lht_dom_next(&it)) { + if (strncmp(n->name, "padstack_ref.", 13) == 0) + parse_pstk(rctx, dt, n); + if (strncmp(n->name, "via.", 4) == 0) + parse_via(rctx, dt, n, 0, 0, 0); + if (strncmp(n->name, "rat.", 4) == 0) + parse_rat(rctx, pcb_for_font, dt, n); + else if (strncmp(n->name, "element.", 8) == 0) + parse_element(rctx, pcb_for_font, dt, n); + else if (strncmp(n->name, "subc.", 5) == 0) + if (parse_subc(rctx, pcb_for_font, dt, n, NULL) != 0) + return iolht_error(n, "failed to parse subcircuit\n"); + } + + return 0; +} + +static void layer_fixup(pcb_board_t *pcb) +{ + int n; + rnd_layergrp_id_t top_silk, bottom_silk; + pcb_layergrp_t *g; + + pcb_layergrp_inhibit_inc(); + + pcb_layer_group_setup_default(pcb); + + /* old silk assumption: last two layers are silk, bottom and top */ + bottom_silk = pcb->Data->Layer[pcb->Data->LayerN-2].meta.real.grp; + top_silk = pcb->Data->Layer[pcb->Data->LayerN-1].meta.real.grp; + pcb->Data->Layer[pcb->Data->LayerN-2].meta.real.grp = -1; + pcb->Data->Layer[pcb->Data->LayerN-1].meta.real.grp = -1; + +/* rnd_trace("NAME: '%s' '%s'\n", pcb->Data->Layer[pcb->Data->LayerN-1].Name,pcb->Data->Layer[pcb->Data->LayerN-2].Name);*/ + + for(n = 0; n < pcb->Data->LayerN - 2; n++) { + pcb_layer_t *l = &pcb->Data->Layer[n]; + rnd_layergrp_id_t grp = l->meta.real.grp; + /*rnd_trace("********* l=%d %s g=%ld (top=%ld bottom=%ld)\n", n, l->name, grp, top_silk, bottom_silk);*/ + l->meta.real.grp = -1; + + if (grp == bottom_silk) + g = pcb_get_grp(&pcb->LayerGroups, PCB_LYT_BOTTOM, PCB_LYT_COPPER); + else if (grp == top_silk) + g = pcb_get_grp(&pcb->LayerGroups, PCB_LYT_TOP, PCB_LYT_COPPER); + else + g = pcb_get_grp_new_intern(pcb, grp); +/* rnd_trace(" add %ld\n", g - pcb->LayerGroups.meta.real.grp);*/ + if (g != NULL) { + pcb_layer_add_in_group_(pcb, g, g - pcb->LayerGroups.grp, n); + if (strcmp(l->name, "outline") == 0) + pcb_layergrp_fix_turn_to_outline(g); + } + else + rnd_message(RND_MSG_ERROR, "failed to create layer %s\n", l->name); + } + + pcb_layergrp_fix_old_outline(pcb); + + /* link in the 2 hardwired silks and mark them auto */ + g = pcb_get_grp(&pcb->LayerGroups, PCB_LYT_BOTTOM, PCB_LYT_SILK); + pcb_layer_add_in_group_(pcb, g, g - pcb->LayerGroups.grp, pcb->Data->LayerN-2); + pcb->Data->Layer[pcb->Data->LayerN-2].comb |= PCB_LYC_AUTO; + + g = pcb_get_grp(&pcb->LayerGroups, PCB_LYT_TOP, PCB_LYT_SILK); + pcb_layer_add_in_group_(pcb, g, g - pcb->LayerGroups.grp, pcb->Data->LayerN-1); + pcb->Data->Layer[pcb->Data->LayerN-1].comb |= PCB_LYC_AUTO; + + pcb_layergrp_inhibit_dec(); +} + + +/* outline layers did not have auto flkag back then but we need that now for padstack slots */ +static void outline_fixup(pcb_board_t *pcb) +{ + rnd_layer_id_t n; + pcb_layergrp_inhibit_inc(); + + for(n = 0; n < pcb->Data->LayerN; n++) { + pcb_layer_t *l = &pcb->Data->Layer[n]; + pcb_layergrp_t *g = &pcb->LayerGroups.grp[l->meta.real.grp]; + + if (g->ltype & PCB_LYT_BOUNDARY) + l->comb |= PCB_LYC_AUTO; + } + + pcb_layergrp_inhibit_dec(); +} + +static int validate_layer_stack_lyr(lht_read_t *rctx, pcb_board_t *pcb, lht_node_t *loc) +{ + rnd_layer_id_t tmp[2], lid; + rnd_layergrp_id_t gid; + int n, found; + + /* check layer->group cross-links */ + for(lid = 0; lid < pcb->Data->LayerN; lid++) { + pcb_layergrp_t *grp; + gid = pcb->Data->Layer[lid].meta.real.grp; + grp = pcb_get_layergrp(pcb, gid); + if (grp == NULL) + return iolht_error(loc, "Broken layer stackup: missing valid group for layer %ld\n", lid); + + for(found = n = 0; n < grp->len; n++) { + if (grp->lid[n] == lid) { + found = 1; + break; + } + } + + if (!found) + return iolht_error(loc, "Broken layer stackup: group->layer backlink for layer %ld\n", lid); + } + + /* check group->layer cross-links */ + for(gid = 0; gid < pcb->LayerGroups.len; gid++) { + pcb_layergrp_t *grp = &pcb->LayerGroups.grp[gid]; + for(n = 0; n < grp->len; n++) { + pcb_layer_t *ly; + lid = grp->lid[n]; + ly = pcb_get_layer(pcb->Data, lid); + if (ly == NULL) + return iolht_error(loc, "Broken layer stackup: group %ld links to non-existent layer %ld\n", gid, lid); + if (ly->meta.real.grp != gid) + return iolht_error(loc, "Broken layer stackup: group %ld links to layer %ld which then links back to group %ld instead\n", gid, lid, ly->meta.real.grp); + } + } + + if (rctx->rdver == 1) { /* v1 used to require top and bottom silk */ + if (pcb_layer_list(pcb, PCB_LYT_TOP | PCB_LYT_SILK, tmp, 2) < 1) + iolht_warn(rctx, loc, -1, "Strange layer stackup for v1: top silk layer missing\n"); + if (pcb_layer_list(pcb, PCB_LYT_BOTTOM | PCB_LYT_SILK, tmp, 2) < 1) + iolht_warn(rctx, loc, -1, "Strange layer stackup for v1: bottom silk layer missing\n"); + } + + if (rctx->rdver < 6) { + if (pcb_layer_list(pcb, PCB_LYT_BOUNDARY, tmp, 2) > 1) + return iolht_error(loc, "Unsupported layer stackup: multiple outline layers was not possible before lihata board v6\n"); + } + return 0; +} + +static int validate_layer_stack_grp(lht_read_t *rctx, pcb_board_t *pcb, lht_node_t *loc) +{ + rnd_layergrp_id_t tmp[2]; + + if (rctx->rdver == 1) { /*v1 required top and bottom silk */ + if (pcb_layergrp_list(pcb, PCB_LYT_TOP | PCB_LYT_SILK, tmp, 2) < 1) + iolht_warn(rctx, loc, -1, "Strange layer stackup in v1: top silk layer group missing\n"); + if (pcb_layergrp_list(pcb, PCB_LYT_BOTTOM | PCB_LYT_SILK, tmp, 2) < 1) + iolht_warn(rctx, loc, -1, "Strange layer stackup in v1: bottom silk layer group missing\n"); + } + if ((pcb_layergrp_list(pcb, PCB_LYT_BOUNDARY, tmp, 2) > 1) && (rctx->rdver < 6)) + return iolht_error(loc, "Unsupported layer stackup: multiple outline layer groups was not possible before lihata board v6\n"); + return 0; +} + +static int parse_layer_stack(lht_read_t *rctx, pcb_board_t *pcb, lht_node_t *nd) +{ + lht_node_t *grps, *grp, *name, *layers, *lyr, *nattr, *npurp; + lht_dom_iterator_t it, itt; + long int n; + + for(n = 0; n < PCB_MAX_LAYERGRP; n++) + pcb_layergrp_free(pcb, n); + pcb->LayerGroups.len = 0; + + grps = lht_dom_hash_get(nd, "groups"); + for(grp = lht_dom_first(&it, grps); grp != NULL; grp = lht_dom_next(&it)) { + rnd_layergrp_id_t gid; + pcb_layergrp_t *g; + char *end; + const char *prp; + + if (grp->type != LHT_HASH) { + iolht_error(grp, "Invalid group in layer stack: '%s' (not a hash; ignoring the group)\n", grp->name); + continue; + } + + gid = strtol(grp->name, &end, 10); + if ((*end != '\0') || (gid < 0)) { + iolht_error(grp, "Invalid group id in layer stack: '%s' (not an int or negative; ignoring the group)\n", grp->name); + continue; + } + if (gid >= PCB_MAX_LAYERGRP) { + iolht_error(grp, "Invalid group id in layer stack: '%s' (too many layers; ignoring the group)\n", grp->name); + continue; + } + + pcb_layergrp_free(pcb, n); /* just in case of double initialization of the same layer id */ + + g = &pcb->LayerGroups.grp[gid]; + if (pcb->LayerGroups.len <= gid) + pcb->LayerGroups.len = gid+1; + pcb_layergrp_setup(g, pcb); + g->purpose = NULL; + g->purpi = -1; + + /* set name and type*/ + name = lht_dom_hash_get(grp, "name"); + if ((name == NULL) || (name->type != LHT_TEXT) || (name->data.text.value == NULL)) { + g->name = malloc(32); + sprintf(g->name, "grp_%ld", gid); + } + else + g->name = rnd_strdup(name->data.text.value); + parse_layer_type(rctx, &g->ltype, &prp, lht_dom_hash_get(grp, "type"), g->name); + + if (rctx->rdver < 6) { + if ((g->ltype & PCB_LYT_DOC) || (g->ltype & PCB_LYT_MECH)) + iolht_warn(rctx, grp, -1, "Layer groups could not have type DOC or MECH before lihata v6 - still loading these types,\nbut they will be ignored by older versions of pcb-rnd.\n"); + } + + npurp = lht_dom_hash_get(grp, "purpose"); + if (npurp != NULL) { /* use the explicit purpose field if found */ + if (rctx->rdver < 6) + iolht_warn(rctx, grp, -1, "Layer groups could not have a purpose field before lihata v6 - still loading the purpose,\nbut it will be ignored by older versions of pcb-rnd.\n"); + if (npurp->type == LHT_TEXT) + pcb_layergrp_set_purpose__(g, rnd_strdup(npurp->data.text.value), 0); + else + iolht_warn(rctx, npurp, -1, "Group purpose shall be text - ignoring this field\n"); + } + else if (prp != NULL) /* or the implicit one returned by parse_layer_type(rctx, ) */ + pcb_layergrp_set_purpose__(g, rnd_strdup(prp), 0); + + /* load attributes */ + nattr = lht_dom_hash_get(grp, "attributes"); + if (nattr != NULL) { + if (rctx->rdver < 5) + iolht_warn(rctx, nattr, 3, "Layer groups could not have attributes before lihata v5 - still loading these attributes,\nbut they will be ignored by older versions of pcb-rnd.\n"); + if (parse_attributes(&g->Attributes, nattr) < 0) + return iolht_error(nattr, "failed to load attributes\n"); + } + + /* load layers */ + layers = lht_dom_hash_get(grp, "layers"); + if (layers != NULL) { + for(lyr = lht_dom_first(&itt, layers); lyr != NULL; lyr = lht_dom_next(&itt)) { + rnd_layer_id_t lid; + if (lyr->type != LHT_TEXT) { + iolht_error(lyr, "Invalid layer node type in group '%s' (ignoring the layer)\n", g->name); + continue; + } + lid = strtol(lyr->data.text.value, &end, 10); + if ((*end != '\0') || (lid < 0)) { + iolht_error(lyr, "Invalid layer id '%s' in group '%s' (not an int or negative; ignoring the layer)\n", lyr->data.text.value, g->name); + continue; + } + if (g->len >= PCB_MAX_LAYER) { + iolht_error(lyr, "Too many layers in group '%s' (ignoring the layer)\n", g->name); + continue; + } + g->lid[g->len] = lid; + g->len++; + } + } + } + return validate_layer_stack_grp(rctx, pcb, nd); +} + +static int parse_data_pstk_shape_poly(lht_read_t *rctx, pcb_board_t *pcb, pcb_pstk_shape_t *dst, lht_node_t *nshape, pcb_data_t *subc_parent) +{ + lht_node_t *n; + rnd_cardinal_t i; + + dst->shape = PCB_PSSH_POLY; + dst->data.poly.x = NULL; /* if we return before the allocation... */ + dst->data.poly.len = 0; + for(n = nshape->data.list.first; n != NULL; n = n->next) + dst->data.poly.len++; + + if ((dst->data.poly.len % 2) != 0) + return iolht_error(n, "odd number of padstack shape polygon points\n"); + + dst->data.poly.len /= 2; + + pcb_pstk_shape_alloc_poly(&dst->data.poly, dst->data.poly.len); + for(n = nshape->data.list.first, i = 0; n != NULL; i++) { + if (parse_coord(&dst->data.poly.x[i], n) != 0) return -1; + n = n->next; + if (parse_coord(&dst->data.poly.y[i], n) != 0) return -1; + n = n->next; + } + return 0; +} + +static int parse_data_pstk_shape_line(lht_read_t *rctx, pcb_board_t *pcb, pcb_pstk_shape_t *dst, lht_node_t *nshape, pcb_data_t *subc_parent) +{ + int sq; + int err = 0; + + dst->shape = PCB_PSSH_LINE; + + err |= parse_coord(&dst->data.line.x1, hash_get(nshape, "x1", 0)); + err |= parse_coord(&dst->data.line.y1, hash_get(nshape, "y1", 0)); + err |= parse_coord(&dst->data.line.x2, hash_get(nshape, "x2", 0)); + err |= parse_coord(&dst->data.line.y2, hash_get(nshape, "y2", 0)); + err |= parse_coord(&dst->data.line.thickness, hash_get(nshape, "thickness", 0)); + err |= parse_int(&sq, hash_get(nshape, "square", 0)); + dst->data.line.square = sq; + return err; +} + +static int parse_data_pstk_shape_circ(lht_read_t *rctx, pcb_board_t *pcb, pcb_pstk_shape_t *dst, lht_node_t *nshape, pcb_data_t *subc_parent) +{ + int err = 0; + dst->shape = PCB_PSSH_CIRC; + + err |= parse_coord(&dst->data.circ.x, hash_get(nshape, "x", 0)); + err |= parse_coord(&dst->data.circ.y, hash_get(nshape, "y", 0)); + err |= parse_coord(&dst->data.circ.dia, hash_get(nshape, "dia", 0)); + return err; +} + +static int parse_data_pstk_shape_hshadow(lht_read_t *rctx, pcb_board_t *pcb, pcb_pstk_shape_t *dst, lht_node_t *nshape, pcb_data_t *subc_parent) +{ + dst->shape = PCB_PSSH_HSHADOW; + if (rctx->rdver < 6) + iolht_warn(rctx, nshape, 7, "lihata board before v6 did not support padstack shape hshadow\n"); + return 0; +} + +static int parse_data_pstk_shape_v4(lht_read_t *rctx, pcb_board_t *pcb, pcb_pstk_shape_t *dst, lht_node_t *nshape, pcb_data_t *subc_parent) +{ + lht_node_t *ncmb, *nlyt, *ns; + int res = -1; + const char *prp; + + nlyt = lht_dom_hash_get(nshape, "layer_mask"); + if ((nlyt != NULL) && (nlyt->type == LHT_HASH)) + res = parse_layer_type(rctx, &dst->layer_mask, &prp, nlyt, "padstack shape"); + +TODO("layer: shape v6 and support for prp") + + if (res != 0) + return iolht_error(nlyt != NULL ? nlyt : nshape, "Failed to parse pad stack shape (layer mask)\n"); + + if (dst->layer_mask == 0) + iolht_warn(rctx, nlyt, -1, "Failed to parse pad stack shape (empty layer mask)\nThe padstack may have shapes that will behave strangely - please fix it manually\n"); + + ncmb = lht_dom_hash_get(nshape, "combining"); + if ((ncmb != NULL) && (ncmb->type == LHT_HASH)) + dst->comb = parse_comb(pcb, ncmb); + + if (parse_coord(&dst->clearance, lht_dom_hash_get(nshape, "clearance")) != 0) return -1; + + ns = lht_dom_hash_get(nshape, "ps_poly"); + if ((ns != NULL) && (ns->type == LHT_LIST)) return parse_data_pstk_shape_poly(rctx, pcb, dst, ns, subc_parent); + + ns = lht_dom_hash_get(nshape, "ps_line"); + if ((ns != NULL) && (ns->type == LHT_HASH)) return parse_data_pstk_shape_line(rctx, pcb, dst, ns, subc_parent); + + ns = lht_dom_hash_get(nshape, "ps_circ"); + if ((ns != NULL) && (ns->type == LHT_HASH)) return parse_data_pstk_shape_circ(rctx, pcb, dst, ns, subc_parent); + + ns = lht_dom_hash_get(nshape, "ps_hshadow"); + if ((ns != NULL) && (ns->type == LHT_TEXT)) return parse_data_pstk_shape_hshadow(rctx, pcb, dst, ns, subc_parent); + + return iolht_error(nshape, "Failed to parse pad stack: missing shape\n"); +} + + +static int parse_data_pstk_proto(lht_read_t *rctx, pcb_board_t *pcb, pcb_pstk_proto_t *dst, lht_node_t *nproto, pcb_data_t *subc_parent, int prver) +{ + int itmp, i; + lht_node_t *nshape, *n; + pcb_pstk_tshape_t *ts; + + switch(prver) { + case 4: + if (rctx->rdver >= 6) + iolht_warn(rctx, nproto, 6, "lihata board from v6 should use padstack prototype v6\n"); + break; + case 6: + if (rctx->rdver < 6) + iolht_warn(rctx, nproto, 6, "lihata board nefore v6 did not have padstack prototype v6\n"); + break; + default: + return iolht_error(nproto, "invalid padstack prototype version\n"); + } + + n = lht_dom_hash_get(nproto, "name"); + if (n != NULL) { + dst->name = rnd_strdup(n->data.text.value); + if (rctx->rdver < 5) + iolht_warn(rctx, n, 6, "lihata board before v5 did not support padstack prototype names\n"); + } + else + dst->name = NULL; + + /* read the hole */ + if (parse_coord(&dst->hdia, lht_dom_hash_get(nproto, "hdia")) != 0) return -1; + if (parse_int(&dst->htop, lht_dom_hash_get(nproto, "htop")) != 0) return -1; + if (parse_int(&dst->hbottom, lht_dom_hash_get(nproto, "hbottom")) != 0) return -1; + if (parse_int(&itmp, lht_dom_hash_get(nproto, "hplated")) != 0) return -1; + dst->hplated = itmp; + dst->in_use = 1; + if (subc_parent != NULL) + dst->parent = subc_parent; + else if (pcb != NULL) + dst->parent = pcb->Data; + else + dst->parent = NULL; + + /* read shapes */ + nshape = lht_dom_hash_get(nproto, "shape"); + if ((nshape == NULL) || (nshape->type != LHT_LIST)) + return iolht_error(nshape, "shape must be an existing list\n"); + + ts = pcb_vtpadstack_tshape_get(&dst->tr, 0, 1); + + for(n = nshape->data.list.first, ts->len = 0; n != NULL; n = n->next) ts->len++; + ts->shape = calloc(sizeof(pcb_pstk_shape_t), ts->len); + + for(n = nshape->data.list.first, i = 0; n != NULL; n = n->next, i++) + if ((n->type == LHT_HASH) && (strcmp(n->name, "ps_shape_v4") == 0)) + if (parse_data_pstk_shape_v4(rctx, pcb, ts->shape+i, n, subc_parent) != 0) + goto error; + + pcb_pstk_proto_update(dst); + + return 0; + error:; + free(ts->shape); + ts->shape = NULL; + ts->len = 0; + return iolht_error(n, "failed to parse padstack due to bad shape\n"); +} + +static int parse_data_pstk_protos(lht_read_t *rctx, pcb_board_t *pcb, pcb_data_t *dst, lht_node_t *pp, pcb_data_t *subc_parent) +{ + rnd_cardinal_t pid, len; + lht_node_t *pr; + int res = 0; + + for(len = 0, pr = pp->data.list.first; pr != NULL; pr = pr->next) len++; + + if (len == 0) + return 0; /* there are no prototypes to load */ + + pcb_vtpadstack_proto_enlarge(&dst->ps_protos, len-1); + for(pid = 0, pr = pp->data.list.first; ((pr != NULL) && (res == 0)); pr = pr->next, pid++) { + if ((pr->type == LHT_TEXT) && (strcmp(pr->name, "unused") == 0)) + continue; + else if ((pr->type == LHT_HASH) && (strncmp(pr->name, "ps_proto_v", 10) == 0)) { + char *sid = pr->name+11, *end; + long int pid_in_file; + int prver = strtol(pr->name+10, &end, 10); + + if ((*end != '\0') && (*end != '.')) + return iolht_error(pr, "Invalid padstack proto version '%s' (not an integer)\n", pr->name+10); + + if (*sid == '.') { + sid++; + pid_in_file = strtol(sid, &end, 0); + if (*end != '\0') + return iolht_error(pr, "Invalid padstack proto ID '%s' (not an integer)\n", sid); + else if (pid_in_file < pid) + return iolht_error(pr, "Invalid padstack proto ID '%s' (can't rewind)\n", sid); + pid = pid_in_file; + } + else if (*sid != '\0') + return iolht_error(pr, "Invalid padstack proto ID '%s' (syntax)\n", sid); + if (pid >= dst->ps_protos.used) + pcb_vtpadstack_proto_enlarge(&dst->ps_protos, pid); + res = parse_data_pstk_proto(rctx, pcb, dst->ps_protos.array + pid, pr, dst, prver); + if (res != 0) + return iolht_error(pr, "Invalid padstack proto definition\n"); + } + else + return iolht_error(pr, "Invalid padstack proto definition\n", pp->name); + } + + return res; +} + +static pcb_data_t *parse_data(lht_read_t *rctx, pcb_board_t *pcb, pcb_data_t *dst, lht_node_t *nd, pcb_data_t *subc_parent) +{ + pcb_data_t *dt; + lht_node_t *grp; + int bound_layers = (subc_parent != NULL); + + if (subc_parent == &DUMMY_BUFFER_SUBC) + subc_parent = NULL; + + if ((nd == NULL) || (nd->type != LHT_HASH)) + return NULL; + + if (dst == NULL) + dt = pcb_buffer_new(pcb); + else + dt = dst; + + if (!bound_layers) + pcb->Data = dt; + + grp = lht_dom_hash_get(nd, "layers"); + if ((grp != NULL) && (grp->type == LHT_LIST)) + parse_data_layers(rctx, pcb, dt, grp, bound_layers, subc_parent); + + if (rctx->rdver == 1) + layer_fixup(pcb); + + if ((rctx->rdver < 6) && (pcb != NULL)) + outline_fixup(pcb); + + if (rctx->rdver >= 4) { + grp = lht_dom_hash_get(nd, "padstack_prototypes"); + if ((grp != NULL) && (grp->type == LHT_LIST)) + parse_data_pstk_protos(rctx, pcb, dt, grp, subc_parent); + } + + grp = lht_dom_hash_get(nd, "objects"); + if (grp != NULL) + if (parse_data_objects(rctx, pcb, dt, grp) != 0) + return NULL; + + return dt; +} + +static int parse_symbol(pcb_symbol_t *sym, lht_node_t *nd) +{ + lht_node_t *grp, *obj, *n; + lht_dom_iterator_t it; + int err = 0; + + err |= parse_coord(&sym->Width, hash_get(nd, "width", 0)); + err |= parse_coord(&sym->Height, hash_get(nd, "height", 0)); + err |= parse_coord(&sym->Delta, hash_get(nd, "delta", 0)); + + grp = lht_dom_hash_get(nd, "objects"); + for(obj = lht_dom_first(&it, grp); obj != NULL; obj = lht_dom_next(&it)) { + rnd_coord_t x1, y1, x2, y2, th, r; + double sa, da; + + if (strncmp(obj->name, "line.", 5) == 0) { + err |= parse_coord(&x1, hash_get(obj, "x1", 0)); + err |= parse_coord(&y1, hash_get(obj, "y1", 0)); + err |= parse_coord(&x2, hash_get(obj, "x2", 0)); + err |= parse_coord(&y2, hash_get(obj, "y2", 0)); + err |= parse_coord(&th, hash_get(obj, "thickness", 0)); + if (err != 0) + return -1; + pcb_font_new_line_in_sym(sym, x1, y1, x2, y2, th); + } + else if (strncmp(obj->name, "simplearc.", 10) == 0) { + err |= parse_coord(&x1, hash_get(obj, "x", 0)); + err |= parse_coord(&y1, hash_get(obj, "y", 0)); + err |= parse_coord(&r, hash_get(obj, "r", 0)); + err |= parse_coord(&th, hash_get(obj, "thickness", 0)); + err |= parse_double(&sa, hash_get(obj, "astart", 0)); + err |= parse_double(&da, hash_get(obj, "adelta", 0)); + if (err != 0) + return -1; + pcb_font_new_arc_in_sym(sym, x1, y1, r, sa, da, th); + } + else if (strncmp(obj->name, "simplepoly.", 11) == 0) { + int len; + pcb_poly_t *sp; + if (obj->type != LHT_LIST) { + iolht_error(obj, "Symbol error: simplepoly is not a list! (ignoring this poly)\n"); + continue; + } + for(len = 0, n = obj->data.list.first; n != NULL; len++, n = n->next) ; + if ((len % 2 != 0) || (len < 6)) { + iolht_error(obj, "Symbol error: sumplepoly has wrong number of points (%d, expected an even integer >= 6)! (ignoring this poly)\n", len); + continue; + } + sp = pcb_font_new_poly_in_sym(sym, len/2); + for(len = 0, n = obj->data.list.first; n != NULL; len++, n = n->next) { + parse_coord(&x1, n); + n = n->next; + parse_coord(&y1, n); + sp->Points[len].X = x1; + sp->Points[len].Y = y1; + } + } + } + + sym->Valid = 1; + return 0; +} + +static int parse_font(pcb_font_t *font, lht_node_t *nd) +{ + lht_node_t *grp, *sym; + lht_dom_iterator_t it; + int err = 0; + + if (nd->type != LHT_HASH) + return iolht_error(nd, "font must be a hash\n"); + + err |= parse_coord(&font->MaxHeight, hash_get(nd, "cell_height", 0)); + err |= parse_coord(&font->MaxWidth, hash_get(nd, "cell_width", 0)); + + grp = lht_dom_hash_get(nd, "symbols"); + + for(sym = lht_dom_first(&it, grp); sym != NULL; sym = lht_dom_next(&it)) { + int chr; + if (sym->type != LHT_HASH) + continue; + if (*sym->name == '&') { + char *end; + chr = strtol(sym->name+1, &end, 16); + if (*end != '\0') { + iolht_error(sym, "Ignoring symbol with invalid symbol name '%s'.\n", sym->name); + continue; + } + } + else + chr = *sym->name; + if ((chr >= 0) && (chr < sizeof(font->Symbol) / sizeof(font->Symbol[0]))) { + parse_symbol(font->Symbol+chr, sym); + } + } + + return err; +} + +static int parse_fontkit(pcb_fontkit_t *fk, lht_node_t *nd) +{ + lht_node_t *n; + lht_dom_iterator_t it; + + if (nd->type != LHT_HASH) + return iolht_error(nd, "fontkit must be a hash\n"); + + pcb_fontkit_reset (fk); + + for(n = lht_dom_first(&it, nd); n != NULL; n = lht_dom_next(&it)) { + pcb_font_t *f; + + if (strcmp(n->name, "geda_pcb") != 0) { + char *end; + int id = strtol(n->name, &end, 10); + if (*end != '\0') + continue; /* ingore fonts with invalid name for now - maybe it'd be safer to read the ID field */ + f = pcb_new_font(fk, id, NULL); + if (f == NULL) + return iolht_error(nd, "Failed to allocate font id %d (name '%s').\n", id, n->name); + } + else { + pcb_font_free (&fk->dflt); + fk->dflt.id = 0; /* restore default font's ID */ + f = &fk->dflt; + } + + if (parse_font(f, n) != 0) + return -1; + } + + return 0; +} + + +static void post_ids_assign(vtp0_t *ids) +{ + int n; + for(n = 0; n < vtp0_len(ids); n++) { + long int *id = ids->array[n]; + *id = pcb_create_ID_get(); + } + vtp0_uninit(ids); +} + +static int parse_styles(lht_read_t *rctx, pcb_data_t *dt, vtroutestyle_t *styles, lht_node_t *nd) +{ + lht_node_t *stn; + lht_dom_iterator_t it; + int err = 0; + + if (nd->type != LHT_LIST) + return iolht_error(nd, "route styles must be a list\n"); + + for(stn = lht_dom_first(&it, nd); stn != NULL; stn = lht_dom_next(&it)) { + pcb_route_style_t *s = vtroutestyle_alloc_append(styles, 1); + int name_len = strlen(stn->name); + + if (stn->type != LHT_HASH) + return iolht_error(stn, "route style entry must be a hash\n"); + + /* safe copy the name */ + if (name_len > sizeof(s->name)-1) { + iolht_warn(rctx, stn, -1, "Route style name too long: '%s' (should be less than %d characters); name will be truncated\n", stn->name, sizeof(s->name)-1); + memcpy(s->name, stn->name, sizeof(s->name)-2); + s->name[sizeof(s->name)-1] = '\0'; + } + else + memcpy(s->name, stn->name, name_len+1); + + s->via_proto = 0; + s->via_proto_set = 0; + s->Hole = 0; + s->Diameter = 0; + err |= parse_coord(&s->Thick, hash_get(stn, "thickness", 0)); + err |= parse_coord(&s->Diameter, hash_get(stn, "diameter", 1)); + err |= parse_coord(&s->Hole, hash_get(stn, "hole", 1)); + err |= parse_coord(&s->Clearance, hash_get(stn, "clearance", 0)); + parse_attributes(&s->attr, lht_dom_hash_get(stn, "attributes")); + + /* read text thickness */ + { + lht_node_t *tt = lht_dom_hash_get(stn, "text_thick"); + + s->textt = 0; + if (tt != NULL) { + err |= parse_coord(&s->textt, tt); + if (rctx->rdver < 6) + iolht_warn(rctx, stn, -1, "text_thick in route style before v6 was not supported\n(accepting it for now, but older versions of pcb-rnd won't)\n"); + } + } + + /* read text scale */ + { + lht_node_t *ts = lht_dom_hash_get(stn, "text_scale"); + + s->texts = 0; + if (ts != NULL) { + err |= parse_int(&s->texts, ts); + if (rctx->rdver < 6) + iolht_warn(rctx, stn, -1, "text_scale in route style before v6 was not supported\n(accepting it for now, but older versions of pcb-rnd won't)\n"); + } + } + + if (rctx->rdver >= 5) { + lht_node_t *vp = lht_dom_hash_get(stn, "via_proto"); + if (vp != NULL) { + unsigned long pid; + if (parse_ulong(&pid, vp) != 0) + return iolht_error(stn, "Invalid route style prototype ID\n"); + s->via_proto = pid; + s->via_proto_set = 1; + if (pcb_pstk_get_proto_(dt, pid) == NULL) + iolht_warn(rctx, vp, -1, "Route style %s references to non-existent prototype %ld\n", s->via_proto); + } + } + } + return 0; +} + +static int parse_netlist_input(lht_read_t *rctx, pcb_board_t *pcb, pcb_netlist_t *nl, lht_node_t *netlist) +{ + lht_node_t *nnet; + if (netlist->type != LHT_LIST) + return iolht_error(netlist, "netlist (parent) must be a list\n"); + + for(nnet = netlist->data.list.first; nnet != NULL; nnet = nnet->next) { + lht_node_t *nconn, *nstyle, *nt, *nattr; + pcb_net_t *net; + const char *style = NULL; + + if (nnet->type != LHT_HASH) + return iolht_error(nnet, "netlist must be a hash\n"); + nconn = lht_dom_hash_get(nnet, "conn"); + nstyle = lht_dom_hash_get(nnet, "style"); + nattr = lht_dom_hash_get(nnet, "attributes"); + + if ((nconn != NULL) && (nconn->type != LHT_LIST)) + return iolht_error(nconn, "conn must be a list\n"); + + if (nstyle != NULL) { + if (nstyle->type != LHT_TEXT) + return iolht_error(nstyle, "style must be text\n"); + style = nstyle->data.text.value; + } + + net = pcb_net_get(pcb, nl, nnet->name, PCB_NETA_ALLOC); + if (net == NULL) + return iolht_error(nnet, "failed to add network\n"); + if (nconn != NULL) { + for(nt = nconn->data.list.first; nt != NULL; nt = nt->next) { + if ((nt->type != LHT_TEXT) || (*nt->data.text.value == '\0')) + return iolht_error(nt, "terminal id must be a non-empty text\n"); + if (pcb_net_term_get_by_pinname(net, nt->data.text.value, PCB_NETA_ALLOC) == NULL) + return iolht_error(nt, "failed to add terminal id to network\n"); + } + } + + if (nattr != NULL) { + if (rctx->rdver < 5) + iolht_warn(rctx, nattr, 4, "Netlist could not have attributes before lihata v5 - still loading these attributes,\nbut they will be ignored by older versions of pcb-rnd.\n"); + if (parse_attributes(&net->Attributes, nattr) < 0) + return iolht_error(nattr, "failed to load attributes\n"); + } + if (style != NULL) + pcb_attribute_put(&net->Attributes, "style", style); + } + return 0; +} + +static int parse_netlist_patch(pcb_board_t *pcb, lht_node_t *patches) +{ + lht_node_t *np; + + if (patches->type != LHT_LIST) + return iolht_error(patches, "netlist patches must be a list\n"); + + for(np = patches->data.list.first; np != NULL; np = np->next) { + lht_node_t *nnet, *nkey, *nval; + if (np->type != LHT_HASH) + return iolht_error(np, "each netlist patch must be a hash\n"); + nnet = lht_dom_hash_get(np, "net"); + if ((nnet == NULL) || (nnet->type != LHT_TEXT) || (*nnet->data.text.value == '\0')) + return iolht_error(nnet, "netlist patch net name must be a non-empty text\n"); + + if (strcmp(np->name, "del_conn") == 0) { + nval = lht_dom_hash_get(np, "term"); + if ((nval == NULL) || (nval->type != LHT_TEXT) || (*nval->data.text.value == '\0')) + return iolht_error(nval, "netlist patch terminal ID must be a non-empty string (del_conn)\n"); + pcb_ratspatch_append(pcb, RATP_DEL_CONN, nval->data.text.value, nnet->data.text.value, NULL, 0); + } + else if (strcmp(np->name, "add_conn") == 0) { + nval = lht_dom_hash_get(np, "term"); + if ((nval == NULL) || (nval->type != LHT_TEXT) || (*nval->data.text.value == '\0')) + return iolht_error(nval, "netlist patch terminal ID must be a non-empty string (add_conn)\n"); + pcb_ratspatch_append(pcb, RATP_ADD_CONN, nval->data.text.value, nnet->data.text.value, NULL, 0); + } + else if (strcmp(np->name, "change_attrib") == 0) { + nkey = lht_dom_hash_get(np, "key"); + if ((nkey == NULL) || (nkey->type != LHT_TEXT) || (*nkey->data.text.value == '\0')) + return iolht_error(nval, "netlist patch attrib key must be a non-empty string (change_attrib)\n"); + nval = lht_dom_hash_get(np, "val"); + if ((nval == NULL) || (nval->type != LHT_TEXT)) + return iolht_error(nval, "netlist patch attrib value must be a non-empty string (change_attrib)\n"); + pcb_ratspatch_append(pcb, RATP_CHANGE_ATTRIB, nnet->data.text.value, nkey->data.text.value, nval->data.text.value, 0); + } + } + return 0; +} + +static int parse_netlists(lht_read_t *rctx, pcb_board_t *pcb, lht_node_t *netlists) +{ + lht_node_t *sub; + + if (netlists->type != LHT_HASH) + return iolht_error(netlists, "netlists must be a hash\n"); + + sub = lht_dom_hash_get(netlists, "input"); + if ((sub != NULL) && (parse_netlist_input(rctx, pcb, pcb->netlist+PCB_NETLIST_INPUT, sub) != 0)) + return iolht_error(sub, "failed to parse the input netlist\n"); + + sub = lht_dom_hash_get(netlists, "netlist_patch"); + if ((sub != NULL) && (parse_netlist_patch(pcb, sub) != 0)) + return iolht_error(sub, "failed to parse the netlist patch\n"); + + return 0; +} + +static void parse_conf(lht_read_t *rctx, pcb_board_t *pcb, lht_node_t *sub) +{ + if (rctx->cfg_dest == RND_CFR_invalid) + return; + if (rnd_conf_insert_tree_as(rctx->cfg_dest, sub) != 0) + rnd_message(RND_MSG_ERROR, "Failed to insert the config subtree '%s' found in %s\n", sub->name, pcb->hidlib.filename); + else + rnd_conf_update(NULL, -1); +} + + +static int parse_board(lht_read_t *rctx, pcb_board_t *pcb, lht_node_t *nd) +{ + lht_node_t *sub; + pcb_plug_io_t *loader; + + rctx->warned = 0; + rctx->old_model_warned = 0; + rctx->rdver = atoi(nd->name+15); + switch(rctx->rdver) { + case 1: loader = &plug_io_lihata_v1; break; + case 2: loader = &plug_io_lihata_v2; break; + case 3: loader = &plug_io_lihata_v3; break; + case 4: loader = &plug_io_lihata_v4; break; + case 5: loader = &plug_io_lihata_v5; break; + case 6: loader = &plug_io_lihata_v6; break; + case 7: loader = &plug_io_lihata_v7; break; + default: + return iolht_error(nd, "Lihata board version %d not supported;\n" + "must be 1, 2, 3, 4, 5, 6 or 7.\n", rctx->rdver); + } + + vtp0_init(&rctx->post_ids); + vtp0_init(&rctx->post_thermal_old); + vtp0_init(&rctx->post_thermal_heavy); + pxm_init(rctx, lht_dom_hash_get(nd, "pixmaps")); + + pcb_rat_all_anchor_guess(pcb->Data); + + memset(&pcb->LayerGroups, 0, sizeof(pcb->LayerGroups)); + + if (parse_attributes(&pcb->Attributes, lht_dom_hash_get(nd, "attributes")) != 0) + goto error; + + sub = lht_dom_hash_get(nd, "meta"); + if ((sub != NULL) && (parse_meta(rctx, pcb, sub) != 0)) + goto error; + + sub = lht_dom_hash_get(nd, "font"); + if ((sub != NULL) && (parse_fontkit(&PCB->fontkit, sub) != 0)) + goto error; + PCB->fontkit.valid = 1; + + if (rctx->rdver >= 2) { + sub = lht_dom_hash_get(nd, "layer_stack"); + if (sub != NULL) { + if (parse_layer_stack(rctx, pcb, sub) != 0) + goto error; + } + else if (validate_layer_stack_grp(rctx, pcb, nd) != 0) + goto error; + } + + pcb_data_clip_inhibit_inc(pcb->Data); + + sub = lht_dom_hash_get(nd, "data"); + if (sub == NULL) { + pcb_data_clip_inhibit_dec(pcb->Data, rnd_true); + return iolht_error(nd, "Lihata board without data\n"); + } + if (parse_data(rctx, pcb, pcb->Data, sub, NULL) == NULL) { + pcb_data_clip_inhibit_dec(pcb->Data, rnd_true); + goto error; + } + + if (validate_layer_stack_lyr(rctx, pcb, sub) != 0) + goto error; + + sub = lht_dom_hash_get(nd, "styles"); + if ((sub != NULL) && (parse_styles(rctx, pcb->Data, &pcb->RouteStyle, sub) != 0)) { + pcb_data_clip_inhibit_dec(pcb->Data, rnd_true); + goto error; + } + + sub = lht_dom_hash_get(nd, "netlists"); + if ((sub != NULL) && (parse_netlists(rctx, pcb, sub) != 0)) { + pcb_data_clip_inhibit_dec(pcb->Data, rnd_true); + goto error; + } + + post_ids_assign(&rctx->post_ids); + if (post_thermal_assign(rctx, pcb, &rctx->post_thermal_old, &rctx->post_thermal_heavy) != 0) { + pcb_data_clip_inhibit_dec(pcb->Data, rnd_true); + goto error; + } + + /* Run poly clipping at the end so we have all IDs and we can + announce the clipping (it's slow, we may need a progress bar) */ + { + rnd_rtree_it_t it; + rnd_box_t *b; + int l; + for(l = 0; l < pcb->Data->LayerN; l++) { + pcb_layer_t *layer = pcb->Data->Layer + l; + for(b = rnd_r_first(layer->polygon_tree, &it); b != NULL; b = rnd_r_next(&it)) { + pcb_poly_t *p = (pcb_poly_t *)b; + pcb_poly_init_clip(pcb->Data, layer, p); + } + } + } + + sub = lht_dom_hash_get(nd, "pcb-rnd-conf-v1"); + if (sub != NULL) + parse_conf(rctx, pcb, sub); + + if (rctx->rdver < 5) { + /* have to parse meta again to get config values overwritten */ + sub = lht_dom_hash_get(nd, "meta"); + if (sub != NULL) + parse_meta(rctx, pcb, sub); + } + + pcb_data_clip_inhibit_dec(pcb->Data, rnd_true); + + pcb->Data->loader = loader; /* set this manually so the version is remembered */ + pxm_uninit(); + return 0; + + error: + pxm_uninit(); + return -1; +} + +int io_lihata_parse_pcb(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest) +{ + int res; + char *errmsg = NULL, *realfn; + lht_doc_t *doc = NULL; + lht_read_t rctx = {0}; + + rctx.cfg_dest = settings_dest; + + realfn = rnd_fopen_check(NULL, Filename, "r"); + if (realfn != NULL) + doc = lht_dom_load(realfn, &errmsg); + free(realfn); + + if (doc == NULL) { + rnd_message(RND_MSG_ERROR, "Error loading '%s': %s\n", Filename, errmsg); + free(errmsg); + return -1; + } + + if ((doc->root->type == LHT_HASH) && (strncmp(doc->root->name, "pcb-rnd-board-v", 15) == 0)) { + res = parse_board(&rctx, Ptr, doc->root); + } + else if ((doc->root->type == LHT_LIST) && (strncmp(doc->root->name, "pcb-rnd-subcircuit-v", 20) == 0)) { + pcb_subc_t *sc; + + rctx.warned = 0; + rctx.old_model_warned = 0; + rctx.rdver = atoi(doc->root->name+20); + Ptr->is_footprint = 1; + res = parse_subc(&rctx, NULL, Ptr->Data, doc->root->data.list.first, &sc); + + if (res == 0) { + pcb_layergrp_upgrade_to_pstk(Ptr); + pcb_layer_create_all_for_recipe(Ptr, sc->data->Layer, sc->data->LayerN); + pcb_subc_rebind(Ptr, sc); + pcb_data_clip_polys(sc->data); + } + } + else { + iolht_error(doc->root, "Error loading '%s': neither a board nor a subcircuit\n", Filename); + res = -1; + } + + lht_dom_uninit(doc); + free(errmsg); + return res; +} + +int io_lihata_parse_buffer(pcb_plug_io_t *ctx, pcb_buffer_t *buff, const char *filename) +{ + int res; + char *errmsg = NULL, *realfn; + lht_doc_t *doc = NULL; + lht_read_t rctx = {0}; + + rctx.cfg_dest = RND_CFR_invalid; + + realfn = rnd_fopen_check(NULL, filename, "r"); + if (realfn != NULL) + doc = lht_dom_load(realfn, &errmsg); + free(realfn); + + if (doc == NULL) { + rnd_message(RND_MSG_ERROR, "Error loading '%s': %s\n", filename, errmsg); + free(errmsg); + return -1; + } + + if ((doc->root->type == LHT_HASH) && (strncmp(doc->root->name, "pcb-rnd-buffer-v", 16) == 0)) { + lht_node_t *datand = lht_dom_hash_get(doc->root, "data"); + rctx.rdver = atoi(doc->root->name+16); + if (datand == NULL) { + iolht_error(doc->root, "Error loading '%s': buffer has no data\n", filename); + res = -1; + } + else + res = (parse_data(&rctx, NULL, buff->Data, datand, &DUMMY_BUFFER_SUBC) == NULL); + + if (res == 0) { + lht_node_t *ndx = lht_dom_hash_get(doc->root, "x"), *ndy = lht_dom_hash_get(doc->root, "y"); + parse_coord(&buff->X, ndx); + parse_coord(&buff->Y, ndy); + } + } + else { + iolht_error(doc->root, "Error loading '%s': not a pcb-rnd paste buffer\n", filename); + res = -1; + } + + lht_dom_uninit(doc); + free(errmsg); + return res; +} + +int io_lihata_parse_padstack(pcb_plug_io_t *ctx, pcb_pstk_proto_t *proto, const char *filename) +{ + int res; + char *errmsg = NULL, *realfn; + lht_doc_t *doc = NULL; + lht_read_t rctx = {0}; + + rctx.cfg_dest = RND_CFR_invalid; + + realfn = rnd_fopen_check(NULL, filename, "r"); + if (realfn != NULL) + doc = lht_dom_load(realfn, &errmsg); + free(realfn); + + if (doc == NULL) { + rnd_message(RND_MSG_ERROR, "Error loading '%s': %s\n", filename, errmsg); + free(errmsg); + return -1; + } + + if ((doc->root->type == LHT_HASH) && (strncmp(doc->root->name, "pcb-rnd-padstack-v", 18) == 0)) { + lht_node_t *datand = lht_dom_hash_get(doc->root, "ps_proto_v6.0"); + if (datand == NULL) { + iolht_error(doc->root, "Error loading '%s': padstack has no ps_proto_v6\n", filename); + res = -1; + } + else + res = parse_data_pstk_proto(&rctx, NULL, proto, datand, NULL, 6); + } + else { + iolht_error(doc->root, "Error loading '%s': not a pcb-rnd paste buffer\n", filename); + res = -1; + } + + lht_dom_uninit(doc); + free(errmsg); + return res; +} + + +typedef enum { + TPS_UNDECIDED, + TPS_GOOD, + TPS_BAD +} test_parse_t; + +/* expect root to be a ha:pcb-rnd-board-v* */ +void test_parse_ev(lht_parse_t *ctx, lht_event_t ev, lht_node_type_t nt, const char *name, const char *value) +{ + test_parse_t *state = ctx->user_data; + if (ev == LHT_OPEN) { + if ((nt == LHT_HASH) && (strncmp(name, "pcb-rnd-board-v", 15) == 0)) + *state = TPS_GOOD; + else if ((nt == LHT_HASH) && (strncmp(name, "pcb-rnd-buffer-v", 16) == 0)) + *state = TPS_GOOD; + else if ((nt == LHT_LIST) && (strncmp(name, "pcb-rnd-subcircuit-v", 20) == 0)) + *state = TPS_GOOD; + else if ((nt == LHT_HASH) && (strncmp(name, "pcb-rnd-padstack-v", 18) == 0)) + *state = TPS_GOOD; + else + *state = TPS_BAD; + } +} + + +/* run an event parser for the first 32k of the file; accept the file if it + has a valid looking root; refuse if: + - no root in the first 32k (or till eof) + - not a valid lihata doc (parser error) + - lihata, but the wrong root +*/ +int io_lihata_test_parse(pcb_plug_io_t *plug_ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f) +{ + lht_parse_t ctx; + int count; + test_parse_t state = TPS_UNDECIDED; + + lht_parser_init(&ctx); + ctx.event = test_parse_ev; + ctx.user_data = &state; + + for(count = 0; count < 32768; count++) { + int c = fgetc(f); + if (lht_parser_char(&ctx, c) != LHTE_SUCCESS) { + /* parse error or end */ + state = TPS_BAD; + break; + } + if (state != TPS_UNDECIDED) + break; + } + lht_parser_uninit(&ctx); + return (state == TPS_GOOD); +} + +int io_lihata_parse_font(pcb_plug_io_t *ctx, pcb_font_t *Ptr, const char *Filename) +{ + int res; + char *errmsg = NULL, *realfn; + lht_doc_t *doc = NULL; + + realfn = rnd_fopen_check(&PCB->hidlib, Filename, "r"); + if (realfn != NULL) + doc = lht_dom_load(realfn, &errmsg); + free(realfn); + + if (doc == NULL) { + if (!pcb_io_err_inhibit) + rnd_message(RND_MSG_ERROR, "Error loading '%s': %s\n", Filename, errmsg); + free(errmsg); + return -1; + } + + if ((doc->root->type != LHT_LIST) || (strcmp(doc->root->name, "pcb-rnd-font-v1"))) { + if (!pcb_io_err_inhibit) + rnd_message(RND_MSG_ERROR, "Not a font lihata.\n"); + res = -1; + } + else + res = parse_font(Ptr, doc->root->data.list.first); + + free(errmsg); + lht_dom_uninit(doc); + return res; +} + + +int io_lihata_parse_subc(pcb_plug_io_t *ctx, pcb_data_t *Ptr, const char *name, const char *subfpname) +{ + int res; + char *errmsg = NULL; + lht_doc_t *doc = NULL; + lht_node_t *n; + pcb_fp_fopen_ctx_t st; + FILE *f; + pcb_subc_t *sc; + lht_read_t rctx = {0}; + + rctx.cfg_dest = RND_CFR_invalid; + + f = pcb_fp_fopen(&conf_core.rc.library_search_paths, name, &st, NULL); + + if (f != NULL) + doc = lht_dom_load_stream(f, st.filename, &errmsg); + pcb_fp_fclose(f, &st); + + if (doc == NULL) { + if (!pcb_io_err_inhibit) + rnd_message(RND_MSG_ERROR, "Error loading '%s': %s\n", name, errmsg); + free(errmsg); + return -1; + } + + if ((doc->root->type != LHT_LIST) || (strncmp(doc->root->name, "pcb-rnd-subcircuit-v", 20))) { + if (!pcb_io_err_inhibit) + rnd_message(RND_MSG_ERROR, "Not a subcircuit lihata.\n"); + free(errmsg); + lht_dom_uninit(doc); + return -1; + } + + rctx.warned = 0; + rctx.old_model_warned = 0; + rctx.rdver = atoi(doc->root->name+20); + if (rctx.rdver < 3) { + if (!pcb_io_err_inhibit) + rnd_message(RND_MSG_ERROR, "io_lihata: invalid subc file version: %s (expected 3 or higher)\n", doc->root->name+20); + free(errmsg); + lht_dom_uninit(doc); + return -1; + } + + for(n = doc->root->data.list.first; n != NULL; n = n->next) { + if (strcmp(n->name, "pixmaps") == 0) { + if (n->type == LHT_HASH) { + pxm_init(&rctx, n); + break; + } + else + rnd_message(RND_MSG_ERROR, "io_lihata: invalid pixmaps subtree: needs to be a hash\n"); + } + } + + res = parse_subc(&rctx, NULL, Ptr, doc->root->data.list.first, &sc); + pxm_uninit(); + if (res == 0) + pcb_data_clip_polys(sc->data); + + lht_dom_uninit(doc); + free(errmsg); + return res; +} + +/* Decide about the type of a footprint file: + - if root is li:pcb-rnd-subcircuit, it is a static footprint file + - else it is a parametric element (footprint generator) if it contains + "@@" "purpose" + - if a line of a file element starts with ## and doesn't contain @, it's a tag + - if need_tags is set, tags are saved +*/ +pcb_plug_fp_map_t *io_lihata_map_footprint(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags) +{ + int c, comment_len; + int first_subc = 1; + long pos = 0; + enum { + ST_WS, + ST_COMMENT, + ST_TAG + } state = ST_WS; + gds_t tag; + + gds_init(&tag); + while ((c = fgetc(f)) != EOF) { + pos++; + if (pos > 1024) break; /* header must be in the first kilobyte */ + switch (state) { + case ST_WS: + if (isspace(c)) + break; + if (c == '#') { + comment_len = 0; + state = ST_COMMENT; + break; + } + else if ((first_subc) && (c == 'l')) { + char s[23]; + /* li:pcb-rnd-subcircuit */ + fgets(s, 21, f); + s[20] = '\0'; + if (strcmp(s, "i:pcb-rnd-subcircuit") == 0) { + head->type = PCB_FP_FILE; + goto out; + } + } + first_subc = 0; + /* fall-thru for detecting @ */ + case ST_COMMENT: + comment_len++; + if ((c == '!') && (pos == 2)) { + /* must be a shebang -> parametric footprint */ + head->type = PCB_FP_PARAMETRIC; + goto out; + } + + if ((c == '#') && (comment_len == 1)) { + state = ST_TAG; + break; + } + if ((c == '\r') || (c == '\n')) + state = ST_WS; + if (c == '@') { + char s[10]; + maybe_purpose:; + /* "@@" "purpose" */ + fgets(s, 9, f); + s[8] = '\0'; + if (strcmp(s, "@purpose") == 0) { + head->type = PCB_FP_PARAMETRIC; + goto out; + } + } + break; + case ST_TAG: + if ((c == '\r') || (c == '\n')) { /* end of a tag */ + if (need_tags && (tag.used != 0)) + vts0_append(&head->tags, (char *)pcb_fp_tag(tag.array, 1)); + + tag.used = 0; + state = ST_WS; + break; + } + if (c == '@') + goto maybe_purpose; + gds_append(&tag, c); + } + } + +out:; + gds_uninit(&tag); + return head; +} Index: tags/2.3.0/src_plugins/io_lihata/read.h =================================================================== --- tags/2.3.0/src_plugins/io_lihata/read.h (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/read.h (revision 33253) @@ -0,0 +1,37 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "plug_io.h" + +int io_lihata_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); +int io_lihata_parse_pcb(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest); +int io_lihata_parse_font(pcb_plug_io_t *ctx, pcb_font_t *Ptr, const char *Filename); +int io_lihata_parse_subc(pcb_plug_io_t *ctx, pcb_data_t *Ptr, const char *name, const char *subfpname); +int io_lihata_parse_padstack(pcb_plug_io_t *ctx, pcb_pstk_proto_t *proto, const char *filename); +int io_lihata_parse_buffer(pcb_plug_io_t *ctx, pcb_buffer_t *buff, const char *filename); +pcb_plug_fp_map_t *io_lihata_map_footprint(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags); + + Index: tags/2.3.0/src_plugins/io_lihata/write.c =================================================================== --- tags/2.3.0/src_plugins/io_lihata/write.c (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/write.c (revision 33253) @@ -0,0 +1,2107 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016..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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Build an in-memory lihata document that represents the board then save it. + A document is built for the merge-save. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "board.h" +#include "conf_core.h" +#include "data.h" +#include +#include "plug_io.h" +#include "flag_str.h" +#include +#include "rats_patch.h" +#include +#include +#include +#include +#include "layer.h" +#include "common.h" +#include "write_style.h" +#include "io_lihata.h" +#include "idpath.h" +#include +#include "obj_subc_list.h" +#include "pcb_minuid.h" +#include +#include "thermal.h" +#include "funchash_core.h" +#include "netlist.h" +#include + +#include "src_plugins/lib_compat_help/pstk_compat.h" + +/*#define CFMT "%[9]"*/ +#define CFMT "%.08$$mH" +/*#define CFMT "%$$mn"*/ + +/* Note: this works because of using str_flag compat_types */ +#define PCB_OBJ_VIA PCB_OBJ_PSTK +#define PCB_OBJ_PIN PCB_OBJ_PSTK +#define PCB_OBJ_PAD PCB_OBJ_PSTK +#define PCB_OBJ_ELEMENT PCB_OBJ_SUBC + +static int io_lihata_full_tree = 0; +static int wrver; +static htip_t id2pxm; +static htpi_t pxm2id; + +static lht_node_t *build_data(pcb_data_t *data); + +#define lht_dom_list_append_safe(lst, item) \ +do { \ + lht_node_t *__append_safe__ = item; \ + if (__append_safe__ != NULL) \ + lht_dom_list_append(lst, __append_safe__); \ +} while(0) + +/* An invalid node will kill any existing node on an overwrite-save-merge */ +static lht_node_t *dummy_node(const char *name) +{ + lht_node_t *n; + n = lht_dom_node_alloc(LHT_TEXT, name); + n->type = LHT_INVALID_TYPE; + return n; +} + +static lht_node_t *dummy_text_node(const char *name) +{ + if (io_lihata_full_tree) { + lht_node_t *n = lht_dom_node_alloc(LHT_TEXT, name); + n->data.text.value = rnd_strdup(""); + return n; + } + return dummy_node(name); +} + +static lht_node_t *build_text(const char *key, const char *value) +{ + lht_node_t *field; + + if (value == NULL) + return dummy_text_node(key); + + field = lht_dom_node_alloc(LHT_TEXT, key); + field->data.text.value = rnd_strdup(value); + return field; +} + +static lht_node_t *build_text_nodup(const char *key, char *value) +{ + lht_node_t *field; + + if (value == NULL) + return dummy_text_node(key); + + field = lht_dom_node_alloc(LHT_TEXT, key); + field->data.text.value = value; + return field; +} + +static lht_node_t *build_textf(const char *key, const char *fmt, ...) +{ + lht_node_t *field; + va_list ap; + + field = lht_dom_node_alloc(LHT_TEXT, key); + va_start(ap, fmt); + field->data.text.value = rnd_strdup_vprintf(fmt, ap); + va_end(ap); + return field; +} + +static lht_node_t *build_idpath(const char *key, const pcb_idpath_t *idpath) +{ + char *idps = NULL; + if ((idpath != NULL) && (idpath->len > 0)) + idps = pcb_idpath2str(idpath, 0); + return build_text(key, idps); +} + +static lht_node_t *build_minuid(const char *key, minuid_bin_t val) +{ + minuid_str_t tmp; + minuid_bin2str(tmp, val); + return build_text(key, tmp); +} + +static lht_node_t *build_board_meta(pcb_board_t *pcb) +{ + lht_node_t *meta, *grp; + + meta = lht_dom_node_alloc(LHT_HASH, "meta"); + lht_dom_hash_put(meta, build_text("board_name", pcb->hidlib.name)); + + grp = lht_dom_node_alloc(LHT_HASH, "grid"); + lht_dom_hash_put(meta, grp); + lht_dom_hash_put(grp, build_textf("offs_x", CFMT, pcb->hidlib.grid_ox)); + lht_dom_hash_put(grp, build_textf("offs_y", CFMT, pcb->hidlib.grid_oy)); + lht_dom_hash_put(grp, build_textf("spacing", CFMT, pcb->hidlib.grid)); + + grp = lht_dom_node_alloc(LHT_HASH, "size"); + lht_dom_hash_put(meta, grp); + lht_dom_hash_put(grp, build_textf("x", CFMT, pcb->hidlib.size_x)); + lht_dom_hash_put(grp, build_textf("y", CFMT, pcb->hidlib.size_y)); + if (wrver < 5) { + lht_dom_hash_put(grp, build_textf("isle_area_nm2", "%f", conf_core.design.poly_isle_area)); + } + lht_dom_hash_put(grp, build_textf("thermal_scale", "%f", pcb->ThermScale)); + + if (wrver < 5) { + grp = lht_dom_node_alloc(LHT_HASH, "drc"); + lht_dom_hash_put(meta, grp); + lht_dom_hash_put(grp, build_textf("bloat", CFMT, conf_core.design.bloat)); + lht_dom_hash_put(grp, build_textf("shrink", CFMT, conf_core.design.shrink)); + lht_dom_hash_put(grp, build_textf("min_width", CFMT, conf_core.design.min_wid)); + lht_dom_hash_put(grp, build_textf("min_silk", CFMT, conf_core.design.min_slk)); + lht_dom_hash_put(grp, build_textf("min_drill", CFMT, conf_core.design.min_drill)); + lht_dom_hash_put(grp, build_textf("min_ring", CFMT, conf_core.design.min_ring)); + } + + if (wrver < 5) { + grp = lht_dom_node_alloc(LHT_HASH, "cursor"); + lht_dom_hash_put(meta, grp); + lht_dom_hash_put(grp, build_textf("x", CFMT, 0)); + lht_dom_hash_put(grp, build_textf("y", CFMT, 0)); + lht_dom_hash_put(grp, build_textf("zoom", "%.6f", 1000)); + } + + return meta; +} + +static lht_node_t *build_attributes(pcb_attribute_list_t *lst) +{ + int n; + lht_node_t *ln; + + if ((lst->Number == 0) && (!io_lihata_full_tree)) + return dummy_node("attributes"); + ln = lht_dom_node_alloc(LHT_HASH, "attributes"); + + for (n = 0; n < lst->Number; n++) { + if ((wrver < 3) && (strcmp(lst->List[n].name, "intconn") == 0)) + continue; /* do not write intconn as attribute for v1 and v2, we used a flag for those */ + lht_dom_hash_put(ln, build_text(lst->List[n].name, lst->List[n].value)); + } + + return ln; +} + +static lht_node_t *build_flags(pcb_flag_t *f, int object_type, int intconn) +{ + int n, layer, added = 0, thrm = 0; + lht_node_t *hsh, *txt, *lst; + io_lihata_flag_holder fh; + + + fh.Flags = *f; + + hsh = lht_dom_node_alloc(LHT_HASH, "flags"); + + /* create normal flag nodes */ + for (n = 0; n < pcb_object_flagbits_len; n++) { + long my_types = pcb_object_flagbits[n].object_types | ((wrver <= 4) ? pcb_object_flagbits[n].compat_types : 0); + if ((my_types & object_type) && (PCB_FLAG_TEST(pcb_object_flagbits[n].mask, &fh))) { + lht_dom_hash_put(hsh, build_text(pcb_object_flagbits[n].name, "1")); + PCB_FLAG_CLEAR(pcb_object_flagbits[n].mask, &fh); + added++; + } + } + + /* thermal flags per layer */ + lst = lht_dom_node_alloc(LHT_HASH, "thermal"); + + for(layer = 0; layer < pcb_max_layer(PCB); layer++) { + if (PCB_FLAG_THERM_TEST_ANY(&fh)) { + int t = PCB_FLAG_THERM_GET(layer, &fh); + if (t != 0) { + const char *name; + txt = lht_dom_node_alloc(LHT_TEXT, PCB->Data->Layer[layer].name); + name = io_lihata_thermal_style_old(t); + if (name != NULL) + txt->data.text.value = rnd_strdup(name); + else + txt->data.text.value = rnd_strdup_printf("%d", t); + lht_dom_hash_put(lst, txt); + added++; + thrm++; + } + } + } + + if (thrm > 0) + lht_dom_hash_put(hsh, lst); + else + lht_dom_node_free(lst); + + if (f->q > 0) { + lht_dom_hash_put(hsh, build_textf("shape", "%d", f->q)); + added++; + } + + if ((intconn > 0) && (wrver < 3)) { + lht_dom_hash_put(hsh, build_textf("intconn", "%d", intconn)); + added++; + } + + if ((added == 0) && (!io_lihata_full_tree)) { + lht_dom_node_free(hsh); + return dummy_node("flags"); + } + + return hsh; +} + +static void obj_attr_flag_warn(pcb_any_obj_t *obj) +{ + int warned = 0; + + if (wrver < 5) { + if (pcb_attribute_get(&obj->Attributes, "intnoconn") != NULL) { + warned = 1; + rnd_message(RND_MSG_WARNING, "pcb-rnd versions only reading file older than lihata v5 may ignore the intnoconn flag\n"); + } + } + if (wrver < 3) { + if (pcb_attribute_get(&obj->Attributes, "intconn") != NULL) { + warned = 1; + rnd_message(RND_MSG_WARNING, "pcb-rnd versions only reading file older than lihata v3 may ignore the intconn flag\n"); + } + } + + if (warned) + rnd_message(RND_MSG_WARNING, "^^^ in %s #%ld\n", pcb_obj_type_name(obj->type), obj->ID); +} + +/* Write the thermal list of heavy terminals; put the resulting "thermal" + node in ha:dst */ +void build_thermal_heavy(lht_node_t *dst, pcb_any_obj_t *o) +{ + lht_node_t *th; + pcb_thermal_t tin = o->thermal; + const char *bit; + + assert(dst->type == LHT_HASH); + + if (o->thermal == 0) { + lht_dom_hash_put(dst, dummy_node("thermal")); + return; + } + + if (wrver < 4) + pcb_io_incompat_save(NULL, o, "thermal", "lihata boards before version v4 did not support heavy terminal vias\n", "Either save in lihata v4+ or do not use heavy terminal thermals"); + + th = lht_dom_node_alloc(LHT_LIST, "thermal"); + lht_dom_hash_put(dst, th); + while((bit = pcb_thermal_bits2str(&tin)) != NULL) + lht_dom_list_append(th, build_textf(NULL, bit)); +} + + +static lht_node_t *build_line(pcb_line_t *line, int local_id, rnd_coord_t dx, rnd_coord_t dy, int simple) +{ + char buff[128]; + lht_node_t *obj; + + sprintf(buff, "line.%ld", (local_id >= 0 ? local_id : line->ID)); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + if (!simple) { + obj_attr_flag_warn((pcb_any_obj_t *)line); + lht_dom_hash_put(obj, build_attributes(&line->Attributes)); + lht_dom_hash_put(obj, build_flags(&line->Flags, PCB_OBJ_LINE, line->intconn)); + lht_dom_hash_put(obj, build_textf("clearance", CFMT, line->Clearance)); + } + + lht_dom_hash_put(obj, build_textf("thickness", CFMT, line->Thickness)); + lht_dom_hash_put(obj, build_textf("x1", CFMT, line->Point1.X+dx)); + lht_dom_hash_put(obj, build_textf("y1", CFMT, line->Point1.Y+dy)); + lht_dom_hash_put(obj, build_textf("x2", CFMT, line->Point2.X+dx)); + lht_dom_hash_put(obj, build_textf("y2", CFMT, line->Point2.Y+dy)); + + build_thermal_heavy(obj, (pcb_any_obj_t*)line); + + return obj; +} + +static lht_node_t *build_simplearc(pcb_arc_t *arc, int local_id) +{ + char buff[128]; + lht_node_t *obj; + + sprintf(buff, "simplearc.%ld", (local_id >= 0 ? local_id : arc->ID)); + obj = lht_dom_node_alloc(LHT_HASH, buff); + lht_dom_hash_put(obj, build_textf("x", CFMT, arc->X)); + lht_dom_hash_put(obj, build_textf("y", CFMT, arc->Y)); + lht_dom_hash_put(obj, build_textf("r", CFMT, arc->Height)); + lht_dom_hash_put(obj, build_textf("astart", "%f", arc->StartAngle)); + lht_dom_hash_put(obj, build_textf("adelta", "%f", arc->Delta)); + lht_dom_hash_put(obj, build_textf("thickness", CFMT, arc->Thickness)); + + return obj; +} + + +static lht_node_t *build_simplepoly(pcb_poly_t *poly, int local_id) +{ + char buff[128]; + lht_node_t *obj; + rnd_point_t *pnt; + int n; + + sprintf(buff, "simplepoly.%ld", (local_id >= 0 ? local_id : poly->ID)); + obj = lht_dom_node_alloc(LHT_LIST, buff); + + for(n = 0, pnt = poly->Points; n < poly->PointN; n++,pnt++) { + lht_dom_list_append(obj, build_textf(NULL, CFMT, pnt->X)); + lht_dom_list_append(obj, build_textf(NULL, CFMT, pnt->Y)); + } + return obj; +} + + +static lht_node_t *build_rat(pcb_rat_t *rat) +{ + char buff[128]; + lht_node_t *obj; + sprintf(buff, "rat.%ld", rat->ID); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + obj_attr_flag_warn((pcb_any_obj_t *)rat); + + lht_dom_hash_put(obj, build_attributes(&rat->Attributes)); + lht_dom_hash_put(obj, build_flags(&rat->Flags, PCB_OBJ_LINE, rat->intconn)); + lht_dom_hash_put(obj, build_textf("x1", CFMT, rat->Point1.X)); + lht_dom_hash_put(obj, build_textf("y1", CFMT, rat->Point1.Y)); + lht_dom_hash_put(obj, build_textf("x2", CFMT, rat->Point2.X)); + lht_dom_hash_put(obj, build_textf("y2", CFMT, rat->Point2.Y)); + lht_dom_hash_put(obj, build_textf("lgrp1", "%d", rat->group1)); + lht_dom_hash_put(obj, build_textf("lgrp2", "%d", rat->group2)); + + if (wrver >= 7) { + lht_dom_hash_put(obj, build_idpath("anchor1", rat->anchor[0])); + lht_dom_hash_put(obj, build_idpath("anchor2", rat->anchor[1])); + } + + return obj; +} + +static lht_node_t *build_arc(pcb_arc_t *arc, rnd_coord_t dx, rnd_coord_t dy) +{ + char buff[128]; + lht_node_t *obj; + + sprintf(buff, "arc.%ld", arc->ID); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + obj_attr_flag_warn((pcb_any_obj_t *)arc); + + lht_dom_hash_put(obj, build_attributes(&arc->Attributes)); + lht_dom_hash_put(obj, build_flags(&arc->Flags, PCB_OBJ_ARC, arc->intconn)); + lht_dom_hash_put(obj, build_textf("thickness", CFMT, arc->Thickness)); + lht_dom_hash_put(obj, build_textf("clearance", CFMT, arc->Clearance)); + lht_dom_hash_put(obj, build_textf("x", CFMT, arc->X+dx)); + lht_dom_hash_put(obj, build_textf("y", CFMT, arc->Y+dy)); + lht_dom_hash_put(obj, build_textf("width", CFMT, arc->Width)); + lht_dom_hash_put(obj, build_textf("height", CFMT, arc->Height)); + lht_dom_hash_put(obj, build_textf("astart", "%ma", arc->StartAngle)); + lht_dom_hash_put(obj, build_textf("adelta", "%ma", arc->Delta)); + + build_thermal_heavy(obj, (pcb_any_obj_t*)arc); + + return obj; +} + +typedef struct { + unsigned char *buff, *optr, *iptr; + size_t cbs, ibs, cmax; +} ucomp_t; + +static void ucomp_dst(void *ctx_, int d) +{ + ucomp_t *ctx = ctx_; + if (ctx->cmax <= 0) { + rnd_message(RND_MSG_ERROR, "Ran out of buffer space while compressing gfx pixmap\n"); + return; + } + *ctx->optr++ = d; + ctx->cmax--; + ctx->cbs++; +} + +static int ucomp_src(void *ctx_) +{ + ucomp_t *ctx = ctx_; + if (ctx->ibs == 0) + return EOF; + ctx->ibs--; + return *ctx->iptr++; +} + +static lht_node_t *build_pxm(rnd_pixmap_t *pxm, long int ID) +{ + char buff[128], *tbuff; + size_t tbs, obs; + lht_node_t *obj; + ucomp_t uctx; + + sprintf(buff, "ulzw.%ld", ID); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + lht_dom_hash_put(obj, build_textf("sx", "%ld", pxm->sx)); + lht_dom_hash_put(obj, build_textf("sy", "%ld", pxm->sy)); + lht_dom_hash_put(obj, build_textf("transparent", "#%02x%02x%02x", pxm->tr, pxm->tg, pxm->tb)); + + uctx.iptr = pxm->p; + uctx.ibs = pxm->size; + uctx.cmax = pxm->size * 2 + 256; + uctx.cbs = 0; + uctx.optr = uctx.buff = malloc(uctx.cmax); + ulzw_compress(&uctx, ucomp_dst, ucomp_src, 12); + + tbs = uctx.cbs + uctx.cbs/2 + 4; + tbuff = malloc(tbs+1); + obs = rnd_base64_bin2str(tbuff, tbs, uctx.buff, uctx.cbs); + if (obs != -1) { + tbuff[obs] = '\0'; + lht_dom_hash_put(obj, build_text_nodup("pixmap", tbuff)); + } + else { + free(tbuff); + pcb_io_incompat_save(NULL, NULL, "gfx_internal", "Internal error saving gfx: base64\n", "Please report this bug to the developer!"); + } + free(uctx.buff); + return obj; +} + +static lht_node_t *build_pxms(void) +{ + htip_entry_t *e; + lht_node_t *root = lht_dom_node_alloc(LHT_HASH, "pixmaps"); + + for(e = htip_first(&id2pxm); e != NULL; e = htip_next(&id2pxm, e)) + lht_dom_hash_put(root, build_pxm(e->value, e->key)); + + return root; +} + +static long gfx_invent_pxm_id(pcb_gfx_t *gfx) +{ + rnd_pixmap_t *existing; + long int id; + + id = htpi_get(&pxm2id, gfx->pxm_neutral); + if (id > 0) /* already have this pixmap stored with an id, reuse that to avoid redundant storage */ + return gfx->pxm_id = id; + + if (gfx->pxm_id == 0) + gfx->pxm_id = pcb_create_ID_get(); + existing = htip_get(&id2pxm, gfx->pxm_id); + if (existing == gfx->pxm_neutral) + return gfx->pxm_id; + + if (existing != NULL) + gfx->pxm_id = pcb_create_ID_get(); /* need to find a new ID because the one in gfx is already in use for a different pixmap */ + htip_set(&id2pxm, gfx->pxm_id, gfx->pxm_neutral); + htpi_set(&pxm2id, gfx->pxm_neutral, gfx->pxm_id); + return gfx->pxm_id; +} + +/* assign all pixmap IDs for data, trying to preserve the ones from load */ +static void gfx_invent_pxm_ids(pcb_data_t *data) +{ + long int n; + for(n = 0; n < data->LayerN; n++) { + pcb_layer_t *layer = data->Layer+n; + pcb_gfx_t *gfx; + + /* first remember IDs to preserve */ + for(gfx = gfxlist_first(&layer->Gfx); gfx != NULL; gfx = gfxlist_next(gfx)) + if (gfx->pxm_id > 0) + gfx_invent_pxm_id(gfx); + + /* then assign yet-unassigned IDs */ + for(gfx = gfxlist_first(&layer->Gfx); gfx != NULL; gfx = gfxlist_next(gfx)) + if (gfx->pxm_id <= 0) + gfx_invent_pxm_id(gfx); + } +} + +static void pxm_init(void) +{ + htip_init(&id2pxm, longhash, longkeyeq); + htpi_init(&pxm2id, ptrhash, ptrkeyeq); +} + +static void pxm_uninit(void) +{ + htip_uninit(&id2pxm); + htpi_uninit(&pxm2id); +} + + +static lht_node_t *build_gfx(pcb_gfx_t *gfx, rnd_coord_t dx, rnd_coord_t dy) +{ + char buff[128]; + lht_node_t *obj; + + sprintf(buff, "gfx.%ld", gfx->ID); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + obj_attr_flag_warn((pcb_any_obj_t *)gfx); + + lht_dom_hash_put(obj, build_attributes(&gfx->Attributes)); + lht_dom_hash_put(obj, build_flags(&gfx->Flags, PCB_OBJ_GFX, gfx->intconn)); + lht_dom_hash_put(obj, build_textf("cx", CFMT, gfx->cx+dx)); + lht_dom_hash_put(obj, build_textf("cy", CFMT, gfx->cy+dy)); + lht_dom_hash_put(obj, build_textf("sx", CFMT, gfx->sx)); + lht_dom_hash_put(obj, build_textf("sy", CFMT, gfx->sy)); + lht_dom_hash_put(obj, build_textf("rot", "%f", gfx->rot)); + lht_dom_hash_put(obj, build_textf("xmirror", "%d", gfx->xmirror)); + lht_dom_hash_put(obj, build_textf("ymirror", "%d", gfx->ymirror)); + lht_dom_hash_put(obj, build_textf("pixmap_ref", "%ld", gfx->pxm_id)); + + build_thermal_heavy(obj, (pcb_any_obj_t*)gfx); + + return obj; +} + + +/* attempt to convert a padstack to an old-style via for v1, v2 and v3 */ +static lht_node_t *build_pstk_pinvia(pcb_data_t *data, pcb_pstk_t *ps, rnd_bool is_via, rnd_coord_t dx, rnd_coord_t dy) +{ + char buff[128]; + lht_node_t *obj; + rnd_coord_t x, y, drill_dia, pad_dia, clearance, mask; + pcb_pstk_compshape_t cshape; + rnd_bool plated; + pcb_flag_t flg; + char *name = pcb_attribute_get(&ps->Attributes, "name"); + + + if (!pcb_pstk_export_compat_via(ps, &x, &y, &drill_dia, &pad_dia, &clearance, &mask, &cshape, &plated)) { + pcb_io_incompat_save(data, (pcb_any_obj_t *)ps, "padstack-old", "Failed to convert to old-style via", "Old via format is very much restricted; try to use a simpler, uniform shape padstack"); + return NULL; + } + + sprintf(buff, "%s.%ld", is_via ? "via" : "pin", ps->ID); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + flg = pcb_pstk_compat_pinvia_flag(ps, cshape, 0); + + obj_attr_flag_warn((pcb_any_obj_t *)ps); + + lht_dom_hash_put(obj, build_attributes(&ps->Attributes)); + lht_dom_hash_put(obj, build_flags(&flg, PCB_OBJ_VIA, ps->intconn)); + lht_dom_hash_put(obj, build_textf("thickness", CFMT, pad_dia)); + lht_dom_hash_put(obj, build_textf("clearance", CFMT, clearance)); + lht_dom_hash_put(obj, build_textf("mask", CFMT, mask)); + lht_dom_hash_put(obj, build_textf("hole", CFMT, drill_dia)); + lht_dom_hash_put(obj, build_textf("x", CFMT, x + dx)); + lht_dom_hash_put(obj, build_textf("y", CFMT, y + dy)); + lht_dom_hash_put(obj, build_text("name", name)); + lht_dom_hash_put(obj, build_text("number", ps->term)); + return obj; +} + +/* attempt to convert a padstack to an old-style pad for v1, v2 and v3 */ +static lht_node_t *build_pstk_pad(pcb_data_t *data, pcb_pstk_t *ps, rnd_coord_t dx, rnd_coord_t dy) +{ + char buff[128]; + lht_node_t *obj; + rnd_coord_t x1, y1, x2, y2, thickness, clearance, mask; + rnd_bool square, nopaste; + char *name = pcb_attribute_get(&ps->Attributes, "name"); + pcb_flag_t flg; + + if (!pcb_pstk_export_compat_pad(ps, &x1, &y1, &x2, &y2, &thickness, &clearance, &mask, &square, &nopaste)) { + pcb_io_incompat_save(data, (pcb_any_obj_t *)ps, "padstack-old", "Failed to convert to old-style pad", "Old pad format is very much restricted; try to use a simpler, uniform shape padstack, square or round-cap line based"); + return NULL; + } + + sprintf(buff, "pad.%ld", ps->ID); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + flg = ps->Flags; + if (square) + flg.f |= PCB_FLAG_SQUARE; + if (nopaste) + flg.f |= PCB_FLAG_NOPASTE; + + obj_attr_flag_warn((pcb_any_obj_t *)ps); + + lht_dom_hash_put(obj, build_attributes(&ps->Attributes)); + lht_dom_hash_put(obj, build_flags(&flg, PCB_OBJ_PAD, ps->intconn)); + lht_dom_hash_put(obj, build_textf("thickness", CFMT, thickness)); + lht_dom_hash_put(obj, build_textf("clearance", CFMT, clearance)); + lht_dom_hash_put(obj, build_textf("mask", CFMT, mask)); + lht_dom_hash_put(obj, build_textf("x1", CFMT, x1+dx)); + lht_dom_hash_put(obj, build_textf("y1", CFMT, y1+dy)); + lht_dom_hash_put(obj, build_textf("x2", CFMT, x2+dx)); + lht_dom_hash_put(obj, build_textf("y2", CFMT, y2+dy)); + lht_dom_hash_put(obj, build_text("name", name)); + lht_dom_hash_put(obj, build_text("number", ps->term)); + return obj; +} + +static lht_node_t *build_polygon(pcb_poly_t *poly) +{ + char buff[128]; + lht_node_t *obj, *tbl, *geo; + rnd_cardinal_t n, hole = 0; + + sprintf(buff, "polygon.%ld", poly->ID); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + obj_attr_flag_warn((pcb_any_obj_t *)poly); + + lht_dom_hash_put(obj, build_attributes(&poly->Attributes)); + lht_dom_hash_put(obj, build_flags(&poly->Flags, PCB_OBJ_POLY, poly->intconn)); + + if ((wrver >= 3) && (poly->Clearance > 0)) + lht_dom_hash_put(obj, build_textf("clearance", CFMT, poly->Clearance)); + else + lht_dom_hash_put(obj, dummy_node("clearance")); + + if ((wrver >= 7) && (poly->enforce_clearance > 0)) + lht_dom_hash_put(obj, build_textf("enforce_clearance", CFMT, poly->enforce_clearance)); + else + lht_dom_hash_put(obj, dummy_node("enforce_clearance")); + + if ((wrver < 7) && (poly->enforce_clearance > 0)) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)poly, "enforce_clearance", "lihata boards before version v7 did not support polygon side enforce_clearance\n", "Either save in lihata v7+ or set polygon enforce_clearance to 0"); + + geo = lht_dom_node_alloc(LHT_LIST, "geometry"); + lht_dom_hash_put(obj, geo); + + tbl = lht_dom_node_alloc(LHT_TABLE, "contour"); + tbl->data.table.cols = 2; + lht_dom_list_append(geo, tbl); + + for(n = 0; n < poly->PointN; n++) { + int row; + if ((hole < poly->HoleIndexN) && (n == poly->HoleIndex[hole])) { + tbl = lht_dom_node_alloc(LHT_TABLE, "hole"); + tbl->data.table.cols = 2; + lht_dom_list_append(geo, tbl); + hole++; + } + + row = tbl->data.table.rows; + lht_tree_table_ins_row(tbl, row); + + lht_dom_node_free(tbl->data.table.r[row][0]); + lht_dom_node_free(tbl->data.table.r[row][1]); + tbl->data.table.r[row][0] = build_textf(NULL, CFMT, poly->Points[n].X); + tbl->data.table.r[row][1] = build_textf(NULL, CFMT, poly->Points[n].Y); + } + + build_thermal_heavy(obj, (pcb_any_obj_t*)poly); + + return obj; +} + +static lht_node_t *build_pcb_text(const char *role, pcb_text_t *text) +{ + char buff[128], *av; + lht_node_t *obj; + + sprintf(buff, "text.%ld", text->ID); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + obj_attr_flag_warn((pcb_any_obj_t *)text); + + lht_dom_hash_put(obj, build_attributes(&text->Attributes)); + lht_dom_hash_put(obj, build_flags(&text->Flags, PCB_OBJ_TEXT, text->intconn)); + lht_dom_hash_put(obj, build_text("string", text->TextString)); + lht_dom_hash_put(obj, build_textf("fid", "%ld", text->fid)); + lht_dom_hash_put(obj, build_textf("x", CFMT, text->X)); + lht_dom_hash_put(obj, build_textf("y", CFMT, text->Y)); + + if (wrver >= 7) { + if (text->Scale != 0) + lht_dom_hash_put(obj, build_textf("scale", "%d", text->Scale)); + else + lht_dom_hash_put(obj, dummy_text_node("scale")); + if (text->scale_x != 0) + lht_dom_hash_put(obj, build_textf("scale_x", "%f", text->scale_x)); + else + lht_dom_hash_put(obj, dummy_text_node("scale")); + if (text->scale_y != 0) + lht_dom_hash_put(obj, build_textf("scale_y", "%f", text->scale_y)); + else + lht_dom_hash_put(obj, dummy_text_node("scale")); + } + else { + int scale; + if (pcb_text_old_scale(text, &scale) != 0) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-scale", "versions below lihata board v7 do not support different x and y direction text scale - using average scale", "Use the scale field, set scale_x and scale_y to 0"); + lht_dom_hash_put(obj, build_textf("scale", "%d", scale)); + if (text->mirror_x) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-mirror-x", "file format does not support different mirroring text in the x direction", "do not mirror, or mirror in the y direction (with the ONSOLDER flag)"); + } + + if (wrver >= 6) { + lht_dom_hash_put(obj, build_textf("rot", "%f", text->rot)); + if (text->thickness > 0) + lht_dom_hash_put(obj, build_textf("thickness", CFMT, text->thickness)); + else + lht_dom_hash_put(obj, dummy_node("thickness")); + } + else { + int dir; + if (!pcb_text_old_direction(&dir, text->rot)) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-rot", "versions below lihata board v6 do not support arbitrary text rotation - rounding to 90 degree rotation", "Use only 90 degree rotations through the direction field"); + + lht_dom_hash_put(obj, build_textf("direction", "%d", dir)); + + if (text->thickness > 0) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-width", "versions below lihata board v6 do not support arbitrary text width - will render with default width", "Leave the thickness field empty (zero) and depend on the automatism"); + } + + if (role != NULL) + lht_dom_hash_put(obj, build_text("role", role)); + + if ((wrver < 7) && ((av = pcb_attribute_get(&text->Attributes, "tight_clearance")) != NULL)) + if (rnd_istrue(av)) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text_tight_clearance", "lihata boards before version v7 did not support text tight_clearance\n", "Either save in lihata v7+ or remove the tight_clearance attribute"); + + if ((wrver < 7) && ((av = pcb_attribute_get(&text->Attributes, "mirror_x")) != NULL)) + if (rnd_istrue(av)) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text_mirror_x", "lihata boards before version v7 did not support text mirror_x\n", "Either save in lihata v7+ or remove the mirror_x attribute"); + + return obj; +} + +static lht_node_t *build_subc_element(pcb_subc_t *subc) +{ + char buff[128]; + lht_node_t *obj, *lst; + rnd_coord_t ox, oy; + gdl_iterator_t it; + int l, seen_refdes = 0; + pcb_pstk_t *ps; + + if (pcb_subc_get_origin(subc, &ox, &oy) != 0) { + assert(subc->parent_type == PCB_PARENT_DATA); + pcb_io_incompat_save(subc->parent.data, (pcb_any_obj_t *)subc, "subc-elem", "Failed to convert subc to old-style element: missing origin", "make sure the subcircuit has the vectors on its subc-aux layer"); + return NULL; + } + + sprintf(buff, "element.%ld", subc->ID); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + obj_attr_flag_warn((pcb_any_obj_t *)subc); + + lht_dom_hash_put(obj, build_attributes(&subc->Attributes)); + lht_dom_hash_put(obj, build_flags(&subc->Flags, PCB_OBJ_ELEMENT, 0)); + + /* build drawing primitives */ + lst = lht_dom_node_alloc(LHT_LIST, "objects"); + lht_dom_hash_put(obj, lst); + + + lht_dom_hash_put(obj, build_textf("x", CFMT, ox)); + lht_dom_hash_put(obj, build_textf("y", CFMT, oy)); + + /* export layer objects: silk lines and arcs */ + for(l = 0; l < subc->data->LayerN; l++) { + pcb_layer_t *ly = &subc->data->Layer[l]; + pcb_line_t *line; + pcb_arc_t *arc; + pcb_text_t *text; + + if ((ly->meta.bound.type & PCB_LYT_SILK) && (ly->meta.bound.type & PCB_LYT_TOP)) { + { + pcb_gfx_t *gfx; + for(gfx = gfxlist_first(&ly->Gfx); gfx != NULL; gfx = gfxlist_next(gfx)) + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)gfx, "gfx", "gfx can not be exported in element", "please use a more recent lihata format with subc support"); + } + linelist_foreach(&ly->Line, &it, line) + lht_dom_list_append(lst, build_line(line, -1, -ox, -oy, 0)); + arclist_foreach(&ly->Arc, &it, arc) + lht_dom_list_append(lst, build_arc(arc, -ox, -oy)); + textlist_foreach(&ly->Text, &it, text) { + if (PCB_FLAG_TEST(PCB_FLAG_DYNTEXT, text)) { + if (!seen_refdes) { + pcb_text_t tmp; + memcpy(&tmp, text, sizeof(tmp)); + tmp.TextString = pcb_attribute_get(&subc->Attributes, "footprint"); + lht_dom_list_append(lst, build_pcb_text("desc", &tmp)); + tmp.TextString = pcb_attribute_get(&subc->Attributes, "refdes"); + lht_dom_list_append(lst, build_pcb_text("name", &tmp)); + tmp.TextString = pcb_attribute_get(&subc->Attributes, "value"); + lht_dom_list_append(lst, build_pcb_text("value", &tmp)); + seen_refdes = 1; + } + } + else { + pcb_io_incompat_save(subc->parent.data, (pcb_any_obj_t *)text, "subc-text", "can't export custom silk text object", "the only text old pcb elements support is the refdes/value/description text"); + } + } + if (polylist_length(&ly->Polygon) > 0) { + char *desc = rnd_strdup_printf("Polygons on layer %s can not be exported in an element", ly->name); + pcb_io_incompat_save(subc->data, NULL, desc, "subc-objs", "only lines and arcs are exported"); + free(desc); + } + if (textlist_length(&ly->Text) > 1) { + char *desc = rnd_strdup_printf("Text on layer %s can not be exported in an element", ly->name); + pcb_io_incompat_save(subc->data, NULL, desc, "subc-objs", "only lines and arcs are exported"); + free(desc); + } + continue; + } + + if (!(ly->meta.bound.type & PCB_LYT_VIRTUAL) && (!pcb_layer_is_pure_empty(ly))) { + char *desc = rnd_strdup_printf("Objects on layer %s can not be exported in an element", ly->name); + pcb_io_incompat_save(subc->data, NULL, desc, "subc-layer", "only top silk lines and arcs are exported; heavy terminals are not supported, use padstacks only"); + free(desc); + } + } + + for(ps = padstacklist_first(&subc->data->padstack); ps != NULL; ps = padstacklist_next(ps)) { + lht_node_t *nps; + + nps = build_pstk_pinvia(subc->data, ps, rnd_false, -ox, -oy); + if (nps == NULL) + nps = build_pstk_pad(subc->data, ps, -ox, -oy); + if (nps != NULL) + lht_dom_list_append(lst, nps); + else + pcb_io_incompat_save(subc->data, (pcb_any_obj_t *)ps, "padstack-old", "Padstack can not be exported as pin or pad", "use simpler padstack; for pins, all copper layers must have the same shape and there must be no paste; for pads, use a line or a rectangle; paste and mask must match the copper shape"); + } + + if (!seen_refdes) + pcb_io_incompat_save(subc->parent.data, (pcb_any_obj_t *)subc, "subc-refdes", "can't export subcircuit without refdes text on silk", "old pcb elements require refdes text on silk"); + + return obj; +} + +static lht_node_t *build_subc(pcb_subc_t *sc) +{ + char buff[128]; + lht_node_t *obj; + + if (wrver < 3) + return build_subc_element(sc); + + sprintf(buff, "subc.%ld", sc->ID); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + obj_attr_flag_warn((pcb_any_obj_t *)sc); + + lht_dom_hash_put(obj, build_attributes(&sc->Attributes)); + lht_dom_hash_put(obj, build_flags(&sc->Flags, PCB_OBJ_SUBC, 0)); + lht_dom_hash_put(obj, build_data(sc->data)); + lht_dom_hash_put(obj, build_minuid("uid", sc->uid)); + + return obj; +} + +static void build_layer_stack_flag(void *ctx, pcb_layer_type_t bit, const char *name, int class, const char *class_name) +{ + lht_node_t *dst = ctx; + lht_dom_hash_put(dst, build_text(name, "1")); +} + +static void build_data_layer_comb(void *ctx, pcb_layer_combining_t bit, const char *name) +{ + lht_node_t *comb = ctx; + lht_dom_hash_put(comb, build_text(name, "1")); +} + + +static lht_node_t *build_pstk_proto(pcb_data_t *data, pcb_pstk_proto_t *proto, long pid) +{ + lht_node_t *nproto, *nmask, *nshape, *nshapelst, *ncomb, *nshapeo; + rnd_cardinal_t sn, pn; + pcb_pstk_tshape_t *ts; + char tmp[64]; + pcb_layer_type_t lyt_permit = PCB_LYT_ANYWHERE | PCB_LYT_COPPER | PCB_LYT_SILK | PCB_LYT_MASK | PCB_LYT_PASTE; + + if (wrver >= 6) + lyt_permit |= PCB_LYT_MECH; + + if (wrver < 6) + sprintf(tmp, "ps_proto_v4.%ld", pid); + else + sprintf(tmp, "ps_proto_v6.%ld", pid); + + nproto = lht_dom_node_alloc(LHT_HASH, tmp); + + lht_dom_hash_put(nproto, build_textf("hdia", CFMT, proto->hdia)); + lht_dom_hash_put(nproto, build_textf("htop", "%d", proto->htop)); + lht_dom_hash_put(nproto, build_textf("hbottom", "%d", proto->hbottom)); + lht_dom_hash_put(nproto, build_textf("hplated", "%d", proto->hplated)); + if (proto->name != NULL) { + if (wrver >= 5) + lht_dom_hash_put(nproto, build_text("name", proto->name)); + else + pcb_io_incompat_save(NULL, NULL, "padstack-name", "versions below lihata board v5 do not support padstack prototype names\n", "Be aware that padstack proto names are lost in save or use lihata board v5 or higher"); + } + else + lht_dom_hash_put(nproto, dummy_node("name")); + + /* save each shape */ + lht_dom_hash_put(nproto, nshapelst = lht_dom_node_alloc(LHT_LIST, "shape")); + ts = &proto->tr.array[0]; /* save the canonical shape only, the transformation cache is generated runtime */ + if (ts != NULL) + for(sn = 0; sn < ts->len; sn++) { + pcb_pstk_shape_t *shape = ts->shape + sn; + pcb_layer_type_t save_mask; + + save_mask = shape->layer_mask & lyt_permit; + if (save_mask != shape->layer_mask) { + pcb_io_incompat_save(data, NULL, "padstack-layer", "Can not save padstack prototype properly because it uses a layer type not supported by this version of lihata padstack.", "Either save in the latest lihata - or accept that some shapes are omitted"); + continue; + } + + lht_dom_list_append(nshapelst, nshape = lht_dom_node_alloc(LHT_HASH, "ps_shape_v4")); + + lht_dom_hash_put(nshape, nmask = lht_dom_node_alloc(LHT_HASH, "layer_mask")); + pcb_layer_type_map(save_mask, nmask, build_layer_stack_flag); + + lht_dom_hash_put(nshape, ncomb = lht_dom_node_alloc(LHT_HASH, "combining")); + pcb_layer_comb_map(shape->comb, ncomb, build_data_layer_comb); + + lht_dom_hash_put(nshape, build_textf("clearance", CFMT, shape->clearance)); + + switch(shape->shape) { + case PCB_PSSH_POLY: + nshapeo = lht_dom_node_alloc(LHT_LIST, "ps_poly"); + for(pn = 0; pn < shape->data.poly.len; pn++) { + lht_dom_list_append(nshapeo, build_textf(NULL, CFMT, shape->data.poly.x[pn])); + lht_dom_list_append(nshapeo, build_textf(NULL, CFMT, shape->data.poly.y[pn])); + } + break; + case PCB_PSSH_LINE: + nshapeo = lht_dom_node_alloc(LHT_HASH, "ps_line"); + lht_dom_hash_put(nshapeo, build_textf("x1", CFMT, shape->data.line.x1)); + lht_dom_hash_put(nshapeo, build_textf("y1", CFMT, shape->data.line.y1)); + lht_dom_hash_put(nshapeo, build_textf("x2", CFMT, shape->data.line.x2)); + lht_dom_hash_put(nshapeo, build_textf("y2", CFMT, shape->data.line.y2)); + lht_dom_hash_put(nshapeo, build_textf("thickness", CFMT, shape->data.line.thickness)); + lht_dom_hash_put(nshapeo, build_textf("square", "%d", shape->data.line.square)); + break; + case PCB_PSSH_CIRC: + nshapeo = lht_dom_node_alloc(LHT_HASH, "ps_circ"); + lht_dom_hash_put(nshapeo, build_textf("x", CFMT, shape->data.circ.x)); + lht_dom_hash_put(nshapeo, build_textf("y", CFMT, shape->data.circ.y)); + lht_dom_hash_put(nshapeo, build_textf("dia", CFMT, shape->data.circ.dia)); + break; + case PCB_PSSH_HSHADOW: + if (wrver < 6) { + pcb_io_incompat_save(data, NULL, "padstack-shape", "Can not save padstack prototype shape \"hshadow\" in lihata formats below version 6.", "Either save in lihata v6 - or accept that the padstack will connect more layers than it should."); + nshapeo = lht_dom_node_alloc(LHT_HASH, "ps_circ"); + lht_dom_hash_put(nshapeo, build_textf("dia", CFMT, 1)); + } + else + nshapeo = build_text("ps_hshadow", ""); + break; + default: + rnd_message(RND_MSG_ERROR, "Internal error: unimplemented pad stack shape %d\n", shape->shape); + abort(); + } + lht_dom_hash_put(nshape, nshapeo); + } + + return nproto; +} + +static lht_node_t *build_pstk_protos(pcb_data_t *data, pcb_vtpadstack_proto_t *pp) +{ + lht_node_t *lst; + rnd_cardinal_t n; + + lst = lht_dom_node_alloc(LHT_LIST, "padstack_prototypes"); + for(n = 0; n < pcb_vtpadstack_proto_len(pp); n++) { + pcb_pstk_proto_t *proto = pp->array+n; + + if (proto->in_use) + lht_dom_list_append(lst, build_pstk_proto(data, proto, n)); + else + lht_dom_list_append(lst, build_text("unused", "1")); + } + + return lst; +} + +static lht_node_t *build_pstk(pcb_pstk_t *ps) +{ + char buff[128]; + lht_node_t *obj, *thr, *thr_lst; + unsigned long n; + + sprintf(buff, "padstack_ref.%ld", ps->ID); + obj = lht_dom_node_alloc(LHT_HASH, buff); + + lht_dom_hash_put(obj, build_attributes(&ps->Attributes)); + lht_dom_hash_put(obj, build_flags(&ps->Flags, PCB_OBJ_PSTK, ps->intconn)); + + lht_dom_hash_put(obj, build_textf("proto", "%ld", (long int)ps->proto)); + lht_dom_hash_put(obj, build_textf("x", CFMT, ps->x)); + lht_dom_hash_put(obj, build_textf("y", CFMT, ps->y)); + lht_dom_hash_put(obj, build_textf("clearance", CFMT, ps->Clearance)); + lht_dom_hash_put(obj, build_textf("rot", "%f", ps->rot)); + lht_dom_hash_put(obj, build_textf("xmirror", "%d", ps->xmirror)); + lht_dom_hash_put(obj, build_textf("smirror", "%d", ps->smirror)); + + lht_dom_hash_put(obj, thr = lht_dom_node_alloc(LHT_LIST, "thermal")); + for(n = 0; n < ps->thermals.used; n++) { + pcb_thermal_t ts = ps->thermals.shape[n]; + if (ts != 0) { + char tmp[64]; + const char *b; + sprintf(tmp, "%ld", n); + thr_lst = lht_dom_node_alloc(LHT_LIST, tmp); + while((b = pcb_thermal_bits2str(&ts)) != NULL) + lht_dom_list_append(thr_lst, build_text(NULL, b)); + if ((wrver >= 6) && ((ts & 3) == PCB_THERMAL_NOSHAPE)) + lht_dom_list_append(thr_lst, build_text(NULL, "noshape")); + lht_dom_list_append(thr, thr_lst); + } + + } + + return obj; +} + +static lht_node_t *build_layer_stack(pcb_board_t *pcb) +{ + lht_node_t *lstk, *grps, *grp, *layers, *flags; + int n, i, outlines = 0; + + lstk = lht_dom_node_alloc(LHT_HASH, "layer_stack"); + lht_dom_hash_put(lstk, grps = lht_dom_node_alloc(LHT_LIST, "groups")); + + for(n = 0; n < pcb->LayerGroups.len; n++) { + pcb_layergrp_t *g = &pcb->LayerGroups.grp[n]; + pcb_layer_type_t lyt; + char tmp[32]; + sprintf(tmp, "%d", n); + lht_dom_list_append(grps, grp = lht_dom_node_alloc(LHT_HASH, tmp)); + + if (wrver >= 5) + lht_dom_hash_put(grp, build_attributes(&g->Attributes)); + else if (g->Attributes.Number > 0) + pcb_io_incompat_save(pcb->Data, (pcb_any_obj_t *)g, "group-meta", "Can not save layer group attributes in lihata formats below version 5.", "Either save in lihata v5 - or accept that attributes are not saved"); + + lht_dom_hash_put(grp, build_text("name", g->name)); + lht_dom_hash_put(grp, layers = lht_dom_node_alloc(LHT_LIST, "layers")); + for(i = 0; i < g->len; i++) + lht_dom_list_append(layers, build_textf("", "%ld", g->lid[i])); + + lyt = g->ltype; + if (wrver < 6) { + int is_outline = (PCB_LAYER_IS_OUTLINE(g->ltype, g->purpi)); + + if ((!is_outline) && (g->purpose != NULL)) + pcb_io_incompat_save(pcb->Data, (pcb_any_obj_t *)g, "group-meta", "Can not save layer group purpose in lihata formats below version 6.", "Either save in lihata v6 - or accept that these layers will change type in the file"); + + if (is_outline) { + lht_dom_hash_put(grp, flags = lht_dom_node_alloc(LHT_HASH, "type")); + pcb_layer_type_map(lyt & (~PCB_LYT_ANYTHING), flags, build_layer_stack_flag); + lht_dom_hash_put(flags, build_text("outline", "1")); + outlines++; + if (outlines > 1) { + pcb_io_incompat_save(pcb->Data, (pcb_any_obj_t *)g, "group", "Can not save multiple outline layer groups in lihata board version below v6", "Save in lihata board v6"); + return NULL; + } + } + else if ((lyt & PCB_LYT_DOC) || (lyt & PCB_LYT_MECH) || (lyt & PCB_LYT_BOUNDARY)) { + lyt &= ~(PCB_LYT_DOC | PCB_LYT_MECH | PCB_LYT_BOUNDARY); + pcb_io_incompat_save(pcb->Data, (pcb_any_obj_t *)g, "group", "Can not save layer group type DOC or MECH in lihata formats below version 6, saving as MISC.", "Either save in lihata v6 - or accept that these layers will change type in the file"); + } + } + else { + if (g->purpose != NULL) + lht_dom_hash_put(grp, build_text("purpose", g->purpose)); + else + lht_dom_hash_put(grp, dummy_node("purpose")); + } + lht_dom_hash_put(grp, flags = lht_dom_node_alloc(LHT_HASH, "type")); + pcb_layer_type_map(lyt, flags, build_layer_stack_flag); + } + + return lstk; +} + + +static lht_node_t *build_data_layer(pcb_data_t *data, pcb_layer_t *layer, rnd_layergrp_id_t layer_group, rnd_layer_id_t lid) +{ + lht_node_t *obj, *grp, *comb; + pcb_line_t *li; + pcb_arc_t *ar; + pcb_poly_t *po; + pcb_text_t *tx; + pcb_gfx_t *gfx; + int added = 0; + + obj = lht_dom_node_alloc(LHT_HASH, layer->name); + + if (!layer->is_bound) { + if (wrver < 6) + lht_dom_hash_put(obj, build_text("visible", layer->meta.real.vis ? "1" : "0")); + lht_dom_hash_put(obj, build_textf("group", "%ld", layer_group)); + if (wrver >= 5) + lht_dom_hash_put(obj, build_text("color", layer->meta.real.color.str)); + } + else { + if (wrver >= 3) { + lht_node_t *type; + + if (layer->meta.bound.stack_offs != 0) + lht_dom_hash_put(obj, build_textf("stack_offs", "%d", layer->meta.bound.stack_offs)); + + lht_dom_hash_put(obj, type = lht_dom_node_alloc(LHT_HASH, "type")); + pcb_layer_type_map(layer->meta.bound.type, type, build_layer_stack_flag); + if (wrver >= 6) { + if (layer->meta.bound.purpose != NULL) + lht_dom_hash_put(obj, build_text("purpose", layer->meta.bound.purpose)); + else + lht_dom_hash_put(obj, dummy_node("purpose")); + } + else if (layer->meta.bound.purpose != NULL) + rnd_message(RND_MSG_WARNING, "io_lihata: attempting to save bound layer with a purpose string - not supported in lihata board below v6. Layer binding might be broken after load.\n"); + } + else + rnd_message(RND_MSG_WARNING, "io_lihata: attempting to save bound layers in lihata version lower than 3; feature not supported by the format.\n"); + } + + if (!layer->is_bound) + lht_dom_hash_put(obj, build_attributes(&layer->Attributes)); + + if (wrver >= 2) { + lht_dom_hash_put(obj, build_textf("lid", "%ld", lid)); + lht_dom_hash_put(obj, comb = lht_dom_node_alloc(LHT_HASH, "combining")); + pcb_layer_comb_map(layer->comb, comb, build_data_layer_comb); + } + + grp = lht_dom_node_alloc(LHT_LIST, "objects"); + + for(li = linelist_first(&layer->Line); li != NULL; li = linelist_next(li)) { + lht_dom_list_append(grp, build_line(li, -1, 0, 0, 0)); + added++; + } + + for(ar = arclist_first(&layer->Arc); ar != NULL; ar = arclist_next(ar)) { + lht_dom_list_append(grp, build_arc(ar, 0, 0)); + added++; + } + + for(po = polylist_first(&layer->Polygon); po != NULL; po = polylist_next(po)) { + lht_dom_list_append(grp, build_polygon(po)); + added++; + } + + for(tx = textlist_first(&layer->Text); tx != NULL; tx = textlist_next(tx)) { + lht_dom_list_append(grp, build_pcb_text(NULL, tx)); + added++; + } + + gfx = gfxlist_first(&layer->Gfx); + if (wrver >= 7) { + for(; gfx != NULL; gfx = gfxlist_next(gfx)) { + lht_dom_list_append(grp, build_gfx(gfx, 0, 0)); + added++; + } + } + else + for(; gfx != NULL; gfx = gfxlist_next(gfx)) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)gfx, "gfx", "lihata boards before version v7 did not support the gfx object\n", "Either save in lihata v7+ or remove the gfx object"); + + + lht_dom_hash_put(obj, grp); + + return obj; +} + +#define LAYER_GID_FIX_V1() \ + do { \ + if (wrver == 1) { \ + if (gid >= 0) { \ + if (gid < sizeof(grp) / sizeof(grp[0])) \ + gid = grp[gid]; \ + else \ + gid = -1; \ + } \ + } \ + } while(0) + + +static lht_node_t *build_data_layers(pcb_data_t *data) +{ + long int n; + lht_node_t *layers; + pcb_layergrp_t *g; + + layers = lht_dom_node_alloc(LHT_LIST, "layers"); + + if (wrver >= 7) + gfx_invent_pxm_ids(data); + + if (wrver == 1) { /* produce an old layer group assignment from top to bottom (needed for v1, good for other versions too) */ + rnd_layergrp_id_t gm, grp[PCB_MAX_LAYERGRP], gtop = -1, gbottom = -1; + + gm = 0; + for(n = 0; n < pcb_max_group(PCB); n++) { + unsigned int gflg = pcb_layergrp_flags(PCB, n); + if (gflg & PCB_LYT_COPPER) { + if (gflg & PCB_LYT_TOP) + gtop = gm; + if (gflg & PCB_LYT_BOTTOM) + gbottom = gm; + grp[n] = gm; +/* rnd_trace("build data layers: %d -> %ld {%ld %ld}\n", n, gm, gtop, gbottom); */ + gm++; + } + else + grp[n] = -1; + } + + g = pcb_get_grp(&PCB->LayerGroups, PCB_LYT_BOTTOM, PCB_LYT_SILK); + if (g == NULL) { + pcb_io_incompat_save(NULL, NULL, "layer", "lihata board v1 did not support a layer stackup without bottom silk\n", "Either create the top silk layer or save in at least v2\nNote: only pcb-rnd above 2.1.0 will load boards without silk; best use v6 or higher."); + return NULL; + } + grp[g - PCB->LayerGroups.grp] = gbottom; + + g = pcb_get_grp(&PCB->LayerGroups, PCB_LYT_TOP, PCB_LYT_SILK); + if (g == NULL) { + pcb_io_incompat_save(NULL, NULL, "layer", "lihata board v1 did not support a layer stackup without top silk\n", "Either create the top silk layer or save in at least v2\nNote: only pcb-rnd above 2.1.0 will load boards without silk; best use v6 or higher."); + return NULL; + } + grp[g - PCB->LayerGroups.grp] = gtop; + + /* v1 needs to have silk at the end of the list */ + for(n = 0; n < pcb_max_layer(PCB); n++) { + if ((pcb_layer_flags(PCB, n) & PCB_LYT_SILK) == 0) { + rnd_layergrp_id_t gid = pcb_layer_get_group(PCB, n); + LAYER_GID_FIX_V1(); + lht_dom_list_append(layers, build_data_layer(data, data->Layer+n, gid, n)); + } + } + for(n = 0; n < pcb_max_layer(PCB); n++) { + if (pcb_layer_flags(PCB, n) & PCB_LYT_SILK) { + rnd_layer_id_t gid = pcb_layer_get_group(PCB, n); + LAYER_GID_FIX_V1(); + lht_dom_list_append(layers, build_data_layer(data, data->Layer+n, gid, n)); + } + } + } + else { + /* keep the original order from v2, to minimize diffs */ + for(n = 0; n < data->LayerN; n++) { + rnd_layergrp_id_t gid = pcb_layer_get_group(PCB, n); + lht_dom_list_append(layers, build_data_layer(data, data->Layer+n, gid, n)); + } + } + + return layers; +} + + +static lht_node_t *build_data(pcb_data_t *data) +{ + lht_node_t *grp, *ndt, *dlr; + pcb_pstk_t *ps; + pcb_subc_t *sc; + gdl_iterator_t it; + pcb_rat_t *line; + + dlr = build_data_layers(data); + if (dlr == NULL) + return NULL; + + ndt = lht_dom_node_alloc(LHT_HASH, "data"); + + /* build layers */ + lht_dom_hash_put(ndt, dlr); + + /* build a list of all global objects */ + grp = lht_dom_node_alloc(LHT_LIST, "objects"); + lht_dom_hash_put(ndt, grp); + + if (wrver >= 4) { + lht_dom_hash_put(ndt, build_pstk_protos(data, &data->ps_protos)); + for(ps = padstacklist_first(&data->padstack); ps != NULL; ps = padstacklist_next(ps)) + lht_dom_list_append(grp, build_pstk(ps)); + } + else { + for(ps = padstacklist_first(&data->padstack); ps != NULL; ps = padstacklist_next(ps)) { + lht_node_t *p = build_pstk_pinvia(data, ps, rnd_true, 0, 0); + if (p != NULL) + lht_dom_list_append(grp, p); + } + } + + for(sc = pcb_subclist_first(&data->subc); sc != NULL; sc = pcb_subclist_next(sc)) + lht_dom_list_append_safe(grp, build_subc(sc)); + + ratlist_foreach(&data->Rat, &it, line) + lht_dom_list_append(grp, build_rat(line)); + + return ndt; +} + +static lht_node_t *build_symbol(pcb_symbol_t *sym, const char *name) +{ + lht_node_t *lst, *ndt; + pcb_line_t *li; + pcb_poly_t *poly; + pcb_arc_t *arc; + int n; + + ndt = lht_dom_node_alloc(LHT_HASH, name); + lht_dom_hash_put(ndt, build_textf("width", CFMT, sym->Width)); + lht_dom_hash_put(ndt, build_textf("height", CFMT, sym->Height)); + lht_dom_hash_put(ndt, build_textf("delta", CFMT, sym->Delta)); + + lst = lht_dom_node_alloc(LHT_LIST, "objects"); + lht_dom_hash_put(ndt, lst); + for(n = 0, li = sym->Line; n < sym->LineN; n++, li++) + lht_dom_list_append(lst, build_line(li, n, 0, 0, 1)); + + for(arc = arclist_first(&sym->arcs); arc != NULL; arc = arclist_next(arc), n++) + lht_dom_list_append(lst, build_simplearc(arc, n)); + + for(poly = polylist_first(&sym->polys); poly != NULL; poly = polylist_next(poly), n++) + lht_dom_list_append(lst, build_simplepoly(poly, n)); + + return ndt; +} + +static lht_node_t *build_font(pcb_font_t *font) +{ + lht_node_t *syms, *ndt; + char *sid, sidbuff[64]; + int n; + + if (font->id > 0) { + sprintf(sidbuff, "%ld", font->id); + sid = sidbuff; + } + else + sid = "geda_pcb"; /* special case for comaptibility: font 0 is the geda_pcb font */ + + ndt = lht_dom_node_alloc(LHT_HASH, sid); + + lht_dom_hash_put(ndt, build_textf("cell_height", CFMT, font->MaxHeight)); + lht_dom_hash_put(ndt, build_textf("cell_width", CFMT, font->MaxWidth)); + lht_dom_hash_put(ndt, build_textf("id", "%ld", font->id)); + if (font->name != NULL) + lht_dom_hash_put(ndt, build_text("name", font->name)); +/* lht_dom_hash_put(ndt, build_symbol(&font->DefaultSymbol)); */ + + + syms = lht_dom_node_alloc(LHT_HASH, "symbols"); + lht_dom_hash_put(ndt, syms); + for(n = 0; n < PCB_MAX_FONTPOSITION + 1; n++) { + char sname[32]; + if (!font->Symbol[n].Valid) + continue; + if ((n <= 32) || (n > 126) || (n == '&') || (n == '#') || (n == '{') || (n == '}') || (n == '/') || (n == ':') || (n == ';') || (n == '=') || (n == '\\') || (n == ':')) { + sprintf(sname, "&%02x", n); + } + else { + sname[0] = n; + sname[1] = '\0'; + } + lht_dom_hash_put(syms, build_symbol(&font->Symbol[n], sname)); + } + return ndt; +} + +static lht_node_t *build_fontkit(pcb_fontkit_t *fk) +{ + lht_node_t *ndt, *frt; + + if (conf_io_lihata.plugins.io_lihata.omit_font) + return dummy_node("font"); + + frt = lht_dom_node_alloc(LHT_HASH, "font"); + + /* write the default font first - it's always there */ + ndt = build_font(&fk->dflt); + lht_dom_hash_put(frt, ndt); + + /* write extra fonts, if there are */ + if (fk->hash_inited) { + htip_entry_t *e; + for(e = htip_first(&fk->fonts); e; e = htip_next(&fk->fonts, e)) { + ndt = build_font(e->value); + lht_dom_hash_put(frt, ndt); + } + } + + + return frt; +} + + +static lht_node_t *build_styles(vtroutestyle_t *styles) +{ + lht_node_t *stl, *sn; + int n; + + if (conf_io_lihata.plugins.io_lihata.omit_styles) + return dummy_node("styles"); + + stl = lht_dom_node_alloc(LHT_LIST, "styles"); + for(n = 0; n < vtroutestyle_len(styles); n++) { + pcb_route_style_t *s = styles->array + n; + sn = lht_dom_node_alloc(LHT_HASH, s->name); + lht_dom_list_append(stl, sn); + lht_dom_hash_put(sn, build_textf("thickness", CFMT, s->Thick)); + lht_dom_hash_put(sn, build_textf("diameter", CFMT, s->Diameter)); + lht_dom_hash_put(sn, build_textf("hole", CFMT, s->Hole)); + lht_dom_hash_put(sn, build_textf("clearance", CFMT, s->Clearance)); + + if (wrver >= 5) { + if (s->via_proto_set) + lht_dom_hash_put(sn, build_textf("via_proto", "%ld", (long int)s->via_proto)); + else + lht_dom_hash_put(sn, dummy_text_node("via_proto")); + } + else + pcb_io_incompat_save(NULL, NULL, "route-style", "lihata boards before version v5 did not support padstack prototype in route style\n", "Either save in lihata v5+ or be aware of losing this information"); + + if (wrver >= 6) + lht_dom_hash_put(sn, build_textf("text_thick", CFMT, s->textt)); + else if (s->textt > 0) + pcb_io_incompat_save(NULL, NULL, "route-style", "lihata boards before version v6 did not support text thickness in route style\n", "Either save in lihata v6+ or be aware of losing this information"); + + if (wrver >= 6) + lht_dom_hash_put(sn, build_textf("text_scale", "%d", s->texts)); + else if (s->texts > 0) + pcb_io_incompat_save(NULL, NULL, "route-style", "lihata boards before version v6 did not support text scale in route style\n", "Either save in lihata v6+ or be aware of losing this information"); + + lht_dom_hash_put(sn, build_attributes(&s->attr)); + } + return stl; +} + +/* Build a plain old netlist */ +static lht_node_t *build_netlist(pcb_netlist_t *netlist, const char *name, int *nonempty) +{ + lht_node_t *nl, *pl, *pn, *nnet; + + if (netlist->used < 1) + return dummy_node(name); + + (*nonempty)++; + + nl = lht_dom_node_alloc(LHT_LIST, name); + + { + htsp_entry_t *e; + for(e = htsp_first(netlist); e != NULL; e = htsp_next(netlist, e)) { + pcb_net_t *net = e->value; + pcb_net_term_t *t; + const char *netname = net->name; + const char *style = pcb_attribute_get(&net->Attributes, "style"); + + /* create the net hash */ + nnet = lht_dom_node_alloc(LHT_HASH, netname); + + if (wrver >= 5) + lht_dom_hash_put(nnet, build_attributes(&net->Attributes)); + else if (net->Attributes.Number > 0) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)net, "net-attr", "Can not save netlist attributes in lihata formats below version 5.", "Either save in lihata v5 - or accept that attributes are not saved"); + + pl = lht_dom_node_alloc(LHT_LIST, "conn"); + lht_dom_hash_put(nnet, pl); + if ((style != NULL) && (*style == '\0')) style = NULL; + lht_dom_hash_put(nnet, build_text("style", style)); + + /* grow the connection list */ + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) { + pn = lht_dom_node_alloc(LHT_TEXT, ""); + pn->data.text.value = rnd_strdup_printf("%s-%s", t->refdes, t->term); + lht_dom_list_append(pl, pn); + } + lht_dom_list_append(nl, nnet); + } + } + + return nl; +} + +typedef struct { + lht_node_t *patch, *info; +} build_net_patch_t; + +static void build_net_patch_cb(void *ctx_, pcb_rats_patch_export_ev_t ev, const char *netn, const char *key, const char *val) +{ + build_net_patch_t *ctx = ctx_; + lht_node_t *n; + switch(ev) { + case PCB_RPE_INFO_BEGIN: + ctx->info = lht_dom_node_alloc(LHT_LIST, "net_info"); + lht_dom_list_append(ctx->info, build_text("net", netn)); + break; + case PCB_RPE_INFO_TERMINAL: + lht_dom_list_append(ctx->info, build_text("term", val)); + break; + case PCB_RPE_INFO_END: + lht_dom_list_append(ctx->patch, ctx->info); + ctx->info = NULL; + break; + case PCB_RPE_CONN_ADD: + n = lht_dom_node_alloc(LHT_HASH, "add_conn"); + goto append_term; + + case PCB_RPE_CONN_DEL: + n = lht_dom_node_alloc(LHT_HASH, "del_conn"); + append_term:; + lht_dom_hash_put(n, build_text("net", netn)); + lht_dom_hash_put(n, build_text("term", val)); + lht_dom_list_append(ctx->patch, n); + break; + + case PCB_RPE_ATTR_CHG: + n = lht_dom_node_alloc(LHT_HASH, "change_attrib"); + lht_dom_hash_put(n, build_text("net", netn)); + lht_dom_hash_put(n, build_text("key", key)); + lht_dom_hash_put(n, build_text("val", val)); + lht_dom_list_append(ctx->patch, n); + break; + } +} + +/* Build a netlist patch so that we don't need to export a complete new set of "as built" netlist */ +static lht_node_t *build_net_patch(pcb_board_t *pcb, pcb_ratspatch_line_t *pat, int *nonempty) +{ + lht_node_t *pn; + build_net_patch_t ctx; + + pn = lht_dom_node_alloc(LHT_LIST, "netlist_patch"); + + ctx.patch = pn; + pcb_rats_patch_export(pcb, pat, rnd_false, build_net_patch_cb, &ctx); + + if (pn->data.list.first == NULL) { + lht_dom_node_free(pn); + return dummy_node("netlist_patch"); + } + + (*nonempty)++; + return pn; +} + + +static lht_node_t *build_netlists(pcb_board_t *pcb, pcb_netlist_t *netlists, pcb_ratspatch_line_t *pat, int num_netlists) +{ + lht_node_t *nls; + int n, nonempty = 0; + + if (num_netlists > PCB_NUM_NETLISTS) + return dummy_node("netlists"); + + nls = lht_dom_node_alloc(LHT_HASH, "netlists"); + + for(n = 0; n < num_netlists; n++) { + lht_node_t *nl; + if (n == PCB_NETLIST_EDITED) + nl = build_net_patch(pcb, pat, &nonempty); + else + nl = build_netlist(netlists+n, pcb_netlist_names[n], &nonempty); + lht_dom_hash_put(nls, nl); + } + + if (!nonempty) { + lht_dom_node_free(nls); + return dummy_node("netlists"); + } + + return nls; +} + +extern lht_doc_t *pcb_conf_main_root[RND_CFR_max_alloc]; +static lht_node_t *build_conf() +{ + const char **s, *del_paths[] = { "editor/mode", NULL }; + lht_node_t *res, *n; + + if (conf_io_lihata.plugins.io_lihata.omit_config) + return dummy_node("pcb-rnd-conf-v1"); + + if ((pcb_conf_main_root[RND_CFR_DESIGN] == NULL) || (pcb_conf_main_root[RND_CFR_DESIGN]->root == NULL) || (pcb_conf_main_root[RND_CFR_DESIGN]->root->type != LHT_LIST)) + return lht_dom_node_alloc(LHT_LIST, "pcb-rnd-conf-v1"); + + res = lht_dom_duptree(pcb_conf_main_root[RND_CFR_DESIGN]->root); + + for(n = res->data.list.first; n != NULL; n = n->next) { + for(s = del_paths; *s != NULL; s++) { + lht_node_t *sub = lht_tree_path_(n->doc, n, *s, 0, 0, NULL); + if (sub != NULL) { + lht_tree_del(sub); + } + } + } + + return res; +} + +static lht_doc_t *build_board(pcb_board_t *pcb) +{ + char vers[32]; + lht_doc_t *brd = lht_dom_init(); + lht_node_t *ntmp; + + sprintf(vers, "pcb-rnd-board-v%d", wrver); + brd->root = lht_dom_node_alloc(LHT_HASH, vers); + pxm_init(); + lht_dom_hash_put(brd->root, build_board_meta(pcb)); + if (wrver >= 2) { + lht_node_t *stack = build_layer_stack(pcb); + if (stack == NULL) + goto error; + lht_dom_hash_put(brd->root, stack); + } + + ntmp = build_data(pcb->Data); + if (ntmp == NULL) + goto error; + + lht_dom_hash_put(brd->root, ntmp); + lht_dom_hash_put(brd->root, build_pxms()); + lht_dom_hash_put(brd->root, build_attributes(&pcb->Attributes)); + lht_dom_hash_put(brd->root, build_fontkit(&pcb->fontkit)); + lht_dom_hash_put(brd->root, build_styles(&pcb->RouteStyle)); + lht_dom_hash_put(brd->root, build_netlists(pcb, pcb->netlist, pcb->NetlistPatches, PCB_NUM_NETLISTS)); + lht_dom_hash_put(brd->root, build_conf()); + pxm_uninit(); + return brd; + + error:; + lht_dom_uninit(brd); + pxm_uninit(); + return NULL; +} + +static lhtpers_ev_res_t check_text(void *ev_ctx, lht_perstyle_t *style, lht_node_t *inmem_node, const char *ondisk_value) +{ + /* for coords, preserve formatting as long as values match */ + if (lhtpers_rule_find(io_lihata_out_coords, inmem_node) != NULL) { + rnd_coord_t v1, v2; + rnd_bool success1, success2; + +/* fprintf(stderr, "SMART d='%s' m='%s'\n", ondisk_value, inmem_node->data.text.value);*/ + + v1 = rnd_get_value_ex(ondisk_value, NULL, NULL, NULL, NULL, &success1); + v2 = rnd_get_value_ex(inmem_node->data.text.value, NULL, NULL, NULL, NULL, &success2); +/* rnd_fprintf(stderr, " %d %d | %mm %mm\n", success1, success2, v1, v2);*/ + if (success1 && success2) { + /* smart: if values are the same, keep the on-disk version */ + if (v1 == v2) + return LHTPERS_DISK; + else + return LHTPERS_MEM; + } + /* else fall back to the string compare below */ + } + + if (inmem_node->data.text.value == NULL) + return LHTPERS_INHIBIT; + + /* classic method: string mismatch => overwrite from mem */ + if (strcmp(inmem_node->data.text.value, ondisk_value) != 0) + return LHTPERS_MEM; + + return LHTPERS_DISK; +} + +static void clean_invalid(lht_node_t *node) +{ + lht_node_t *n; + lht_dom_iterator_t it; + for(n = lht_dom_first(&it, node); n != NULL; n = lht_dom_next(&it)) { + if (n->type == LHT_INVALID_TYPE) + lht_tree_del(n); + else + clean_invalid(n); + } +} + +static int io_lihata_write_pcb(pcb_plug_io_t *ctx, FILE * FP, const char *old_filename, const char *new_filename, rnd_bool emergency, int ver) +{ + int res; + lht_doc_t *brd; + + wrver = ver; + brd = build_board(PCB); + + if (brd == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to build the board at that version - nothing is written\n"); + return -1; + } + +#if IO_LIHATA_SAVE_BACKUP_IN_PCB + { + const char *fnpat = conf_io_lihata.plugins.io_lihata.aux_pcb_pattern; + + /* Backup in .pcb before saving in .lht so if the save code crashes, + the board is preserved. WARNING: since .pcb can't represent a lot + of details, it may degrade the board _before_ we save it in lht. + Thus this feature should be disabled */ + if ((fnpat != NULL) && (*fnpat != '\0')) { + char *orig_fn, *end; + char *pcb_fn = rnd_strdup_subst(fnpat, rnd_build_fn_cb, &PCB->hidlib, RND_SUBST_ALL); + + orig_fn = PCB->hidlib.filename; + PCB->hidlib.filename = NULL; + + /* avoid .lht.lht.pcb */ + end = pcb_fn + strlen(pcb_fn) - 1; + if ((end-11 > pcb_fn) && (strcmp(end-11, ".lht.lht.pcb") == 0)) + strcpy(end-11, ".lht.pcb"); + + fprintf(stderr, "NOTE: io_lihata_write_pcb will save to '%s' but first saves in '%s': res=%d (expected: 0)\n", new_filename, pcb_fn, pcb_save_pcb(pcb_fn, "pcb")); + free(pcb_fn); + + /* restore these because SaveTo() has changed them */ + free(PCB->hidlib.filename); + PCB->hidlib.filename = orig_fn; + PCB->Data->loader = ctx; + } + } +#endif + + if ((emergency) || ((old_filename == NULL) && (new_filename == NULL))) { + /* emergency or pipe save: use the canonical form */ + clean_invalid(brd->root); /* remove invalid nodes placed for persistency */ + res = lht_dom_export(brd->root, FP, ""); + } + else { + FILE *inf = NULL; + char *errmsg; + lhtpers_ev_t events; + + if (old_filename != NULL) + inf = rnd_fopen(&PCB->hidlib, old_filename, "r"); + + memset(&events, 0, sizeof(events)); + events.text = check_text; +/* events.list_empty = check_list_empty; + events.list_elem_removed = check_list_elem_removed;*/ + events.output_rules = io_lihata_out_rules; + + res = lhtpers_fsave_as(&events, brd, inf, FP, old_filename, &errmsg); + if ((res == LHTPERS_ERR_ROOT_MISMATCH) || (res == LHTPERS_ERR_ROOT_MISSING)) { + /* target is a different lht file or not even an lht file; the user requested the save, including overwrite, so do that */ + rewind(FP); + res = lhtpers_fsave_as(&events, brd, NULL, FP, old_filename, &errmsg); + } + if (res != 0) { + FILE *fe; + char *fe_name = rnd_concat(old_filename, ".mem.lht", NULL); + fe = rnd_fopen(&PCB->hidlib, fe_name, "w"); + if (fe != NULL) { + clean_invalid(brd->root); /* remove invalid nodes placed for persistency */ + res = lht_dom_export(brd->root, fe, ""); + fclose(fe); + } + rnd_message(RND_MSG_ERROR, "lhtpers_fsave_as() failed. Please include files %s and %s and %s in your bugreport\n", inf, old_filename, fe_name); + rnd_message(RND_MSG_ERROR, "in case this broke your file %s, please use the emergency save %s instead.\n", old_filename, fe_name); + } + fflush(FP); + if (inf != NULL) + fclose(inf); + } + + lht_dom_uninit(brd); + return res; +} + +int io_lihata_write_pcb_v1(pcb_plug_io_t *ctx, FILE * FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + return io_lihata_write_pcb(ctx, FP, old_filename, new_filename, emergency, 1); +} + +int io_lihata_write_pcb_v2(pcb_plug_io_t *ctx, FILE * FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + return io_lihata_write_pcb(ctx, FP, old_filename, new_filename, emergency, 2); +} + +int io_lihata_write_pcb_v3(pcb_plug_io_t *ctx, FILE * FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + return io_lihata_write_pcb(ctx, FP, old_filename, new_filename, emergency, 3); +} + +int io_lihata_write_pcb_v4(pcb_plug_io_t *ctx, FILE * FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + return io_lihata_write_pcb(ctx, FP, old_filename, new_filename, emergency, 4); +} + +int io_lihata_write_pcb_v5(pcb_plug_io_t *ctx, FILE * FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + return io_lihata_write_pcb(ctx, FP, old_filename, new_filename, emergency, 5); +} + +int io_lihata_write_pcb_v6(pcb_plug_io_t *ctx, FILE * FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + return io_lihata_write_pcb(ctx, FP, old_filename, new_filename, emergency, 6); +} + +int io_lihata_write_pcb_v7(pcb_plug_io_t *ctx, FILE * FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + return io_lihata_write_pcb(ctx, FP, old_filename, new_filename, emergency, 7); +} + +int io_lihata_write_font(pcb_plug_io_t *ctx, pcb_font_t *font, const char *Filename) +{ + FILE *f; + int res; + lht_doc_t *doc; + + + f = rnd_fopen_askovr(&PCB->hidlib, Filename, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to open font file %s for write\n", Filename); + return -1; + } + + /* create the doc */ + io_lihata_full_tree = 1; + doc = lht_dom_init(); + doc->root = lht_dom_node_alloc(LHT_LIST, "pcb-rnd-font-v1"); + lht_dom_list_append(doc->root, build_font(font)); + + clean_invalid(doc->root); + res = lht_dom_export(doc->root, f, ""); + + fclose(f); + lht_dom_uninit(doc); + io_lihata_full_tree = 0; + return res; +} + +static int plug2ver(const pcb_plug_io_t *ctx) +{ + if (ctx == &plug_io_lihata_v1) return 1; + if (ctx == &plug_io_lihata_v2) return 2; + if (ctx == &plug_io_lihata_v3) return 3; + if (ctx == &plug_io_lihata_v4) return 4; + if (ctx == &plug_io_lihata_v5) return 5; + if (ctx == &plug_io_lihata_v6) return 6; + if (ctx == &plug_io_lihata_v7) return 7; + return 0; +} + +static int io_lihata_dump_subc(pcb_plug_io_t *ctx, FILE *f, pcb_subc_t *sc) +{ + int res; + lht_doc_t *doc; + + /* create the doc */ + io_lihata_full_tree = 1; + doc = lht_dom_init(); + pxm_init(); + + /* determine version */ + wrver = plug2ver(ctx); + if (wrver < 3) + wrver = 1; + + /* bump version if features require */ +TODO("subc: for subc-in-subc this should be recursive") + if (padstacklist_first(&sc->data->padstack) != NULL) { + if (wrver < 4) { + rnd_message(RND_MSG_WARNING, "Had to bump lihata subc version to 4 because the subcircuit contains padstacks.\n"); + wrver = 4; + } + } + + if (wrver == 3) + doc->root = lht_dom_node_alloc(LHT_LIST, "pcb-rnd-subcircuit-v3"); + else if ((wrver >= 4) && (wrver < 6)) + doc->root = lht_dom_node_alloc(LHT_LIST, "pcb-rnd-subcircuit-v4"); + else if (wrver == 6) + doc->root = lht_dom_node_alloc(LHT_LIST, "pcb-rnd-subcircuit-v6"); + else if (wrver >= 7) + doc->root = lht_dom_node_alloc(LHT_LIST, "pcb-rnd-subcircuit-v7"); + else { + rnd_message(RND_MSG_ERROR, "Invalid lihata subc version to write: %d\n", wrver); + pxm_uninit(); + return -1; + } + + lht_dom_list_append(doc->root, build_subc(sc)); + if (wrver >= 7) + lht_dom_list_append(doc->root, build_pxms()); + + clean_invalid(doc->root); /* remove invalid nodes placed for persistency */ + res = lht_dom_export(doc->root, f, ""); + + lht_dom_uninit(doc); + io_lihata_full_tree = 0; + pxm_uninit(); + return res; +} + +int io_lihata_write_subcs_head(pcb_plug_io_t *ctx, void **udata, FILE *f, int lib, long num_subcs) +{ + if ((lib) || (num_subcs != 1)) { + rnd_message(RND_MSG_ERROR, "Only one subcircuit per footprint file can be written in lihata\n"); + return -1; + } + return 0; +} + +int io_lihata_write_subcs_subc(pcb_plug_io_t *ctx, void **udata, FILE *f, pcb_subc_t *subc) +{ + return io_lihata_dump_subc(ctx, f, subc); +} + +int io_lihata_write_subcs_tail(pcb_plug_io_t *ctx, void **udata, FILE *f) +{ + return 0; +} + + +int io_lihata_write_buffer(pcb_plug_io_t *ctx, FILE *f, pcb_buffer_t *buff) +{ + int res; + lht_doc_t *doc; + + wrver = plug2ver(ctx); + if (wrver < 6) + wrver = 6; + + io_lihata_full_tree = 1; + doc = lht_dom_init(); + doc->root = lht_dom_node_alloc(LHT_HASH, "pcb-rnd-buffer-v6"); + + lht_dom_hash_put(doc->root, build_data(buff->Data)); + lht_dom_hash_put(doc->root, build_textf("x", CFMT, buff->X)); + lht_dom_hash_put(doc->root, build_textf("y", CFMT, buff->Y)); + + clean_invalid(doc->root); /* remove invalid nodes placed for persistency */ + res = lht_dom_export(doc->root, f, ""); + + lht_dom_uninit(doc); + io_lihata_full_tree = 0; + return res; + +} + +int io_lihata_write_padstack(pcb_plug_io_t *ctx, FILE *f, pcb_pstk_proto_t *proto) +{ + int res; + lht_doc_t *doc; + + wrver = plug2ver(ctx); + if (wrver < 6) + wrver = 6; + + io_lihata_full_tree = 1; + doc = lht_dom_init(); + doc->root =lht_dom_node_alloc(LHT_HASH, "pcb-rnd-padstack-v6"); + lht_dom_hash_put(doc->root, build_pstk_proto(NULL, proto, 0)); + + clean_invalid(doc->root); /* remove invalid nodes placed for persistency */ + res = lht_dom_export(doc->root, f, ""); + + lht_dom_uninit(doc); + io_lihata_full_tree = 0; + return res; + +} + +typedef struct { + int womit_font, womit_config, womit_styles; + int ver; +} io_lihata_save_t; + +void *io_lihata_save_as_subd_init(const pcb_plug_io_t *ctx, rnd_hid_dad_subdialog_t *sub, pcb_plug_iot_t type) +{ + io_lihata_save_t *save = calloc(sizeof(io_lihata_save_t), 1); + + if (type == PCB_IOT_PCB) { + RND_DAD_BEGIN_HBOX(sub->dlg); + RND_DAD_LABEL(sub->dlg, "Omit font"); + RND_DAD_HELP(sub->dlg, "Do not save the font subtree\nWARNING: this will make the board depend on\nthe default font available on systems\nwhere it is loaded; if multiple fonts\nare used, all will be displayed using the default"); + RND_DAD_BOOL(sub->dlg); + RND_DAD_DEFAULT_NUM(sub->dlg, !!conf_io_lihata.plugins.io_lihata.omit_font); + save->womit_font = RND_DAD_CURRENT(sub->dlg); + RND_DAD_END(sub->dlg); + RND_DAD_BEGIN_HBOX(sub->dlg); + RND_DAD_LABEL(sub->dlg, "Omit config"); + RND_DAD_HELP(sub->dlg, "Do not save the config subtree\nWARNING: this will lose all DESIGN role\nconfig setting in the resulting file"); + RND_DAD_BOOL(sub->dlg); + RND_DAD_DEFAULT_NUM(sub->dlg, !!conf_io_lihata.plugins.io_lihata.omit_config); + save->womit_config = RND_DAD_CURRENT(sub->dlg); + RND_DAD_END(sub->dlg); + RND_DAD_BEGIN_HBOX(sub->dlg); + RND_DAD_LABEL(sub->dlg, "Omit styles"); + RND_DAD_HELP(sub->dlg, "Do not save the routing style subtree\nThe resulting file will have no\nrouting styles"); + RND_DAD_BOOL(sub->dlg); + RND_DAD_DEFAULT_NUM(sub->dlg, !!conf_io_lihata.plugins.io_lihata.omit_styles); + save->womit_styles = RND_DAD_CURRENT(sub->dlg); + RND_DAD_END(sub->dlg); + } + return save; +} + +void io_lihata_save_as_subd_uninit(const pcb_plug_io_t *ctx, void *plg_ctx, rnd_hid_dad_subdialog_t *sub, rnd_bool apply) +{ + io_lihata_save_t *save = plg_ctx; + + if (apply) { + int omit_font = !!sub->dlg[save->womit_font].val.lng; + int omit_config = !!sub->dlg[save->womit_config].val.lng; + int omit_styles = !!sub->dlg[save->womit_styles].val.lng; + + if (omit_font != !!conf_io_lihata.plugins.io_lihata.omit_font) + rnd_conf_setf(RND_CFR_CLI, "plugins/io_lihata/omit_font", 0, "%d", omit_font); + + if (omit_config != !!conf_io_lihata.plugins.io_lihata.omit_config) + rnd_conf_setf(RND_CFR_CLI, "plugins/io_lihata/omit_config", 0, "%d", omit_config); + + if (omit_styles != !!conf_io_lihata.plugins.io_lihata.omit_styles) + rnd_conf_setf(RND_CFR_CLI, "plugins/io_lihata/omit_styles", 0, "%d", omit_styles); + } + + free(save); +} + +void io_lihata_save_as_fmt_changed(const pcb_plug_io_t *ctx, void *plg_ctx, rnd_hid_dad_subdialog_t *sub) +{ + io_lihata_save_t *save = plg_ctx; + save->ver = plug2ver(ctx); +} + Index: tags/2.3.0/src_plugins/io_lihata/write.h =================================================================== --- tags/2.3.0/src_plugins/io_lihata/write.h (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/write.h (revision 33253) @@ -0,0 +1,45 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "plug_io.h" + +int io_lihata_write_pcb_v1(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency); +int io_lihata_write_pcb_v2(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency); +int io_lihata_write_pcb_v3(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency); +int io_lihata_write_pcb_v4(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency); +int io_lihata_write_pcb_v5(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency); +int io_lihata_write_pcb_v6(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency); +int io_lihata_write_pcb_v7(pcb_plug_io_t *ctx, FILE *FP, const char *old_filename, const char *new_filename, rnd_bool emergency); +int io_lihata_write_font(pcb_plug_io_t *ctx, pcb_font_t *font, const char *Filename); +int io_lihata_write_buffer(pcb_plug_io_t *ctx, FILE *f, pcb_buffer_t *buff); +int io_lihata_write_subcs_head(pcb_plug_io_t *ctx, void **udata, FILE *f, int lib, long num_subcs); +int io_lihata_write_subcs_subc(pcb_plug_io_t *ctx, void **udata, FILE *f, pcb_subc_t *subc); +int io_lihata_write_subcs_tail(pcb_plug_io_t *ctx, void **udata, FILE *f); +int io_lihata_write_padstack(pcb_plug_io_t *ctx, FILE *f, pcb_pstk_proto_t *proto); + +void *io_lihata_save_as_subd_init(const pcb_plug_io_t *ctx, rnd_hid_dad_subdialog_t *sub, pcb_plug_iot_t type); +void io_lihata_save_as_subd_uninit(const pcb_plug_io_t *ctx, void *plg_ctx, rnd_hid_dad_subdialog_t *sub, rnd_bool apply); +void io_lihata_save_as_fmt_changed(const pcb_plug_io_t *ctx, void *plg_ctx, rnd_hid_dad_subdialog_t *sub); Index: tags/2.3.0/src_plugins/io_lihata/write_style.c =================================================================== --- tags/2.3.0/src_plugins/io_lihata/write_style.c (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/write_style.c (revision 33253) @@ -0,0 +1,727 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Specify default output formatting style to be more compact than + the canonical lihata export style */ + +#include "config.h" +#include "write_style.h" + +#define PB_BEGIN {"*", 2, 2} +#define PB_BEGINSP {" *", 3, 3} +#define PB_BEGINNL {"\n *", 4, 4} +#define PB_EMPTY {"", 1, 1} +#define PB_SEMICOLON {";", 2, 2} +#define PB_SPACE {" ", 2, 2} +#define PB_LBRACE {"{", 2, 2} +#define PB_LBRACENL {"{\n", 3, 3} +#define PB_LBRACENLI {"{\n*", 4, 4} +#define PB_RBRACE {"}", 2, 2} +#define PB_RBRACENL {"}\n", 3, 3} +#define PB_RBRACENLI {"}\n*", 4, 4} +#define PB_RBRACESC {"};", 3, 3} +#define PB_NEWLINE {"\n", 2, 2} +#define PB_DEFAULT {NULL, 0, 0} + +/* Space spearated key=val; pairs */ +static lht_perstyle_t style_inline = { + /* buff */ {PB_SPACE, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_SEMICOLON}, + /* has_eq */ 1, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t style_inlinesp = { + /* buff */ {PB_BEGINSP, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_SEMICOLON}, + /* has_eq */ 1, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +/* tightly packed key=val; pairs */ +static lht_perstyle_t style_inline_tight = { + /* buff */ {PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_SEMICOLON}, + /* has_eq */ 1, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t style_newline = { + /* buff */ {PB_BEGIN, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_NEWLINE}, + /* has_eq */ 1, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t style_newline_sp = { + /* buff */ {PB_BEGINSP, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_NEWLINE}, + /* has_eq */ 1, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t style_istruct = { + /* buff */ {PB_SPACE, PB_SPACE, PB_LBRACE, PB_EMPTY, PB_EMPTY, PB_RBRACESC}, + /* has_eq */ 1, + /* val_brace */ 1, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t style_struct = { + /* buff */ {PB_BEGIN, PB_SPACE, PB_LBRACENL, PB_EMPTY, PB_EMPTY, PB_RBRACENL}, + /* has_eq */ 0, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t style_struct_thermal = { + /* buff */ {PB_BEGIN, PB_SPACE, PB_LBRACE, PB_EMPTY, PB_EMPTY, PB_RBRACENL}, + /* has_eq */ 0, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t style_structi = { + /* buff */ {PB_BEGIN, PB_SPACE, PB_LBRACENLI, PB_EMPTY, PB_EMPTY, PB_RBRACENL}, + /* has_eq */ 0, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t style_structs = { + /* buff */ {PB_BEGIN, PB_SPACE, PB_LBRACE, PB_EMPTY, PB_EMPTY, PB_RBRACENL}, + /* has_eq */ 0, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t style_structsp = { + /* buff */ {PB_BEGINSP, PB_SPACE, PB_LBRACE, PB_EMPTY, PB_EMPTY, PB_RBRACENL}, + /* has_eq */ 0, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t style_structnp = { + /* buff */ {PB_BEGINSP, PB_SPACE, PB_LBRACENL, PB_EMPTY, PB_EMPTY, PB_RBRACENL}, + /* has_eq */ 0, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t style_nlstruct = { + /* buff */ {PB_BEGINNL, PB_SPACE, PB_LBRACENL, PB_EMPTY, PB_EMPTY, PB_RBRACENL}, + /* has_eq */ 0, + /* val_brace */ 0, + /* etype */ 0, + /* ename */ 1, + /* name_braced */ 0 +}; + +static lht_perstyle_t early_nl = { + /* buff */ {PB_NEWLINE, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_EMPTY, PB_EMPTY}, +}; + + +static const char *pat_te_flags[] = {"te:*", "ha:flags", "*", NULL}; +static const char *pat_te_attr[] = {"te:*", "ha:attributes", "*", NULL}; +static lhtpers_rule_t r_ilists[] = { + {pat_te_flags, &style_inline_tight, NULL}, + {pat_te_attr, &style_newline_sp, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_thermal[] = {"ha:thermal", "ha:flags", "*", NULL}; +static lhtpers_rule_t r_thermal[] = { + {pat_thermal, &style_struct_thermal, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_ha_flags[] = {"ha:flags", "*", NULL}; +static lhtpers_rule_t r_flags[] = { + {pat_ha_flags, &style_istruct, r_thermal}, + {NULL, NULL, NULL} +}; + +static const char *pat_x1_line[] = {"te:x1", "*", NULL}; +static const char *pat_y1_line[] = {"te:y1", "*", NULL}; +static const char *pat_x2_line[] = {"te:x2", "*", NULL}; +static const char *pat_y2_line[] = {"te:y2", "*", NULL}; +static const char *pat_thickness[] = {"te:thickness", "*", NULL}; +static const char *pat_clearance[] = {"te:clearance", "*", NULL}; +static const char *pat_flags[] = {"ha:flags", "*", NULL}; +static const char *pat_attributes[] = {"ha:attributes", "*", NULL}; +static const char *pat_square[] = {"te:square", "*", NULL}; +static lhtpers_rule_t r_line[] = { + {pat_x1_line, &style_inline, NULL}, + {pat_y1_line, &style_inline, NULL}, + {pat_x2_line, &style_inline, NULL}, + {pat_y2_line, &style_inline, NULL}, + {pat_thickness, &style_inline, NULL}, + {pat_clearance, &style_inline, NULL}, + {lhtpers_early_end, &early_nl, NULL}, + {pat_flags, &style_nlstruct, r_thermal}, + {pat_attributes, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_lgrp1_line[] = {"te:lgrp1", "*", NULL}; +static const char *pat_lgrp2_line[] = {"te:lgrp2", "*", NULL}; +static const char *pat_anch1_line[] = {"te:anchor1", "*", NULL}; +static const char *pat_anch2_line[] = {"te:anchor2", "*", NULL}; +static lhtpers_rule_t r_rat[] = { + {pat_x1_line, &style_inline, NULL}, + {pat_y1_line, &style_inline, NULL}, + {pat_lgrp1_line, &style_inline, NULL}, + {pat_anch1_line, &style_inline, NULL}, + {pat_x2_line, &style_inline, NULL}, + {pat_y2_line, &style_inline, NULL}, + {pat_lgrp2_line, &style_inline, NULL}, + {pat_anch2_line, &style_inline, NULL}, + {lhtpers_early_end, &early_nl, NULL}, + {pat_flags, &style_nlstruct, r_thermal}, + {pat_attributes, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_x[] = {"te:x", "*", NULL}; +static const char *pat_y[] = {"te:y", "*", NULL}; +static const char *pat_width_arc[] = {"te:width", "*", NULL}; +static const char *pat_height_arc[] = {"te:height", "*", NULL}; +static const char *pat_astart_arc[] = {"te:astart", "*", NULL}; +static const char *pat_adelta_arc[] = {"te:adelta", "*", NULL}; +static lhtpers_rule_t r_arc[] = { + {pat_x, &style_inline, NULL}, + {pat_y, &style_inline, NULL}, + {pat_width_arc, &style_inline, NULL}, + {pat_height_arc, &style_inline, NULL}, + {pat_astart_arc, &style_inline, NULL}, + {pat_adelta_arc, &style_inline, NULL}, + {pat_thickness, &style_inline, NULL}, + {pat_clearance, &style_inline, NULL}, + {lhtpers_early_end, &early_nl, NULL}, + {pat_flags, &style_nlstruct, r_thermal}, + {pat_attributes, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_gfx_ref[] = {"te:pixmap_ref", "*", NULL}; +static const char *pat_gfx_sx[] = {"te:sx", "*", NULL}; +static const char *pat_gfx_sy[] = {"te:sy", "*", NULL}; +static const char *pat_gfx_cx[] = {"te:cx", "*", NULL}; +static const char *pat_gfx_cy[] = {"te:cy", "*", NULL}; +static const char *pat_gfx_rot[] = {"te:rot", "*", NULL}; +static const char *pat_gfx_xmirror[] = {"te:xmirror", "*", NULL}; +static const char *pat_gfx_ymirror[] = {"te:ymirror", "*", NULL}; +static lhtpers_rule_t r_gfx[] = { + {pat_gfx_ref, &style_inline, NULL}, + {pat_gfx_cx, &style_inline, NULL}, + {pat_gfx_cy, &style_inline, NULL}, + {pat_gfx_sx, &style_inline, NULL}, + {pat_gfx_sy, &style_inline, NULL}, + {pat_gfx_rot, &style_inline, NULL}, + {pat_gfx_xmirror, &style_inline, NULL}, + {pat_gfx_ymirror, &style_inline, NULL}, + {lhtpers_early_end, &early_nl, NULL}, + {pat_flags, &style_nlstruct, r_thermal}, + {pat_attributes, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_name[] = {"te:name", "*", NULL}; +static const char *pat_numb[] = {"te:number", "*", NULL}; +static const char *pat_hole[] = {"te:hole", "*", NULL}; +static const char *pat_mask[] = {"te:mask", "*", NULL}; +static lhtpers_rule_t r_pinvia[] = { + {pat_name, &style_inline, NULL}, + {pat_numb, &style_inline, NULL}, + {pat_x, &style_inline, NULL}, + {pat_y, &style_inline, NULL}, + {pat_hole, &style_inline, NULL}, + {pat_mask, &style_inline, NULL}, + {pat_thickness, &style_inline, NULL}, + {pat_clearance, &style_inline, NULL}, + {lhtpers_early_end, &early_nl, NULL}, + {pat_flags, &style_nlstruct, r_thermal}, + {pat_attributes, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_xmirror[] = {"te:xmirror", "*", NULL}; +static const char *pat_smirror[] = {"te:smirror", "*", NULL}; +static const char *pat_rot[] = {"te:rot", "*", NULL}; +static const char *pat_proto[] = {"te:proto", "*", NULL}; +static lhtpers_rule_t r_psref[] = { + {pat_proto, &style_inline, NULL}, + {pat_x, &style_inline, NULL}, + {pat_y, &style_inline, NULL}, + {pat_rot, &style_inline, NULL}, + {pat_xmirror, &style_inline, NULL}, + {pat_smirror, &style_inline, NULL}, + {pat_clearance, &style_inline, NULL}, + {lhtpers_early_end, &early_nl, NULL}, + {pat_flags, &style_nlstruct, r_thermal}, + {pat_thermal, &style_nlstruct, r_thermal}, + {pat_attributes, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + + +static lhtpers_rule_t r_pad[] = { + {pat_name, &style_inline, NULL}, + {pat_numb, &style_inline, NULL}, + {pat_x1_line, &style_inline, NULL}, + {pat_y1_line, &style_inline, NULL}, + {pat_x2_line, &style_inline, NULL}, + {pat_y2_line, &style_inline, NULL}, + {pat_mask, &style_inline, NULL}, + {pat_thickness, &style_inline, NULL}, + {pat_clearance, &style_inline, NULL}, + {lhtpers_early_end, &early_nl, NULL}, + {pat_flags, &style_nlstruct, r_thermal}, + {pat_attributes, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_ta_contour[] = {"ta:contour", "*", NULL}; +static const char *pat_ta_hole[] = {"ta:hole", "*", NULL}; +static lhtpers_rule_t r_geometry[] = { + {pat_ta_contour, &style_istruct, NULL}, + {pat_ta_hole, &style_istruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_geometry[] = {"li:geometry", "*", NULL}; +static lhtpers_rule_t r_polygon[] = { + {pat_clearance, &style_inline, NULL}, + {pat_geometry, &style_nlstruct, r_geometry}, + {pat_flags, &style_nlstruct, r_thermal}, + {pat_attributes, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_string[] = {"te:string", "*", NULL}; +static const char *pat_role[] = {"te:role", "*", NULL}; +static const char *pat_scale[] = {"te:scale", "*", NULL}; +static const char *pat_fid[] = {"te:fid", "*", NULL}; +static const char *pat_direct[] = {"te:direction", "*", NULL}; +static lhtpers_rule_t r_text[] = { + {pat_string, &style_inline, NULL}, + {pat_x, &style_inline, NULL}, + {pat_y, &style_inline, NULL}, + {pat_scale, &style_inline, NULL}, + {pat_fid, &style_inline, NULL}, + {pat_direct, &style_inline, NULL}, + {pat_role, &style_inline, NULL}, + {lhtpers_early_end, &early_nl, NULL}, + {pat_flags, &style_nlstruct, r_thermal}, + {pat_attributes, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + + +static const char *pat_objects[] = {"li:objects", "*", NULL}; +static lhtpers_rule_t r_element[] = { + {pat_x, &style_inline, NULL}, + {pat_y, &style_inline, NULL}, + {pat_flags, &style_nlstruct, r_thermal}, + {pat_attributes, &style_nlstruct, NULL}, + {pat_objects, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_visible[] = {"te:visible", "*", NULL}; +static const char *pat_group[] = {"te:group", "*", NULL}; +static const char *pat_lid[] = {"te:lid", "*", NULL}; +static const char *pat_combin[] = {"ha:combining", "*", NULL}; +static lhtpers_rule_t r_layer[] = { + {pat_lid, &style_newline, NULL}, + {pat_group, &style_newline, NULL}, + {pat_combin, &style_structs, NULL}, + {pat_visible, &style_newline, NULL}, + {pat_attributes, &style_nlstruct, NULL}, + {pat_objects, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_ps_line[] = {"ha:ps_line", "*", NULL}; +static lhtpers_rule_t r_ps_line[] = { + {pat_x1_line, &style_inline, NULL}, + {pat_y1_line, &style_inline, NULL}, + {pat_x2_line, &style_inline, NULL}, + {pat_y2_line, &style_inline, NULL}, + {pat_thickness, &style_inline, NULL}, + {pat_square, &style_inline, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_ps_circ[] = {"ha:ps_circ", "*", NULL}; +static const char *pat_dia[] = {"te:dia", "*", NULL}; +static lhtpers_rule_t r_ps_circ[] = { + {pat_x, &style_inline, NULL}, + {pat_y, &style_inline, NULL}, + {pat_dia, &style_inline, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_ps_shape_v4[] = {"ha:ps_shape_v4", "*", NULL}; +static const char *pat_layer_mask[] = {"ha:layer_mask", "*", NULL}; +static lhtpers_rule_t r_ps_shape_v4[] = { + {pat_ps_line, &style_struct_thermal, r_ps_line}, + {pat_ps_circ, &style_struct_thermal, r_ps_circ}, + {pat_combin, &style_structs, NULL}, + {pat_layer_mask, &style_struct, NULL}, + {pat_clearance, &style_newline, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_li_shape[] = {"li:shape", "*", NULL}; +static lhtpers_rule_t r_li_shape[] = { + {pat_ps_shape_v4, &style_structi, r_ps_shape_v4}, + {NULL, NULL, NULL} +}; + + +static const char *pat_ps_htop[] = {"te:htop", "*", NULL}; +static const char *pat_ps_hdia[] = {"te:hdia", "*", NULL}; +static const char *pat_ps_hbottom[] = {"te:hbottom", "*", NULL}; +static const char *pat_ps_hplated[] = {"te:hplated", "*", NULL}; + +static const char *pat_ps_proto[] = {"ha:ps_proto_v*", "*", NULL}; +static lhtpers_rule_t r_ps_proto[] = { + {pat_ps_hdia, &style_inlinesp, NULL}, + {pat_ps_hplated, &style_inline, NULL}, + {pat_ps_htop, &style_inline, NULL}, + {pat_ps_hbottom, &style_inline, NULL}, + {pat_li_shape, &style_nlstruct, r_li_shape}, + {NULL, NULL, NULL} +}; + +static const char *pat_ps_protos[] = {"li:padstack_prototypes", "*", NULL}; +static lhtpers_rule_t r_ps_protos[] = { + {pat_ps_proto, &style_struct, r_ps_proto}, + {NULL, NULL, NULL} +}; + + +static lhtpers_rule_t r_data[] = { + {pat_ps_protos, &style_struct, r_ps_protos}, + {pat_objects, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_width[] = {"te:width", "*", NULL}; +static const char *pat_height[] = {"te:height", "*", NULL}; +static const char *pat_delta[] = {"te:delta", "*", NULL}; +static lhtpers_rule_t r_symbol[] = { + {pat_width, &style_inline, NULL}, + {pat_height, &style_inline, NULL}, + {pat_delta, &style_inline, NULL}, + {pat_objects, &style_nlstruct, NULL}, + {pat_attributes, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + + +static const char *pat_cell_width[] = {"te:cell_width", "*", NULL}; +static const char *pat_cell_height[] = {"te:cell_height", "*", NULL}; +static const char *pat_ha_symbols[] = {"ha:symbols", "*", NULL}; +static lhtpers_rule_t r_font1[] = { + {pat_cell_width, &style_inline, NULL}, + {pat_cell_height, &style_inline, NULL}, + {pat_attributes, &style_nlstruct, NULL}, + {pat_ha_symbols, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_li_styles[] = {"li:styles", "*", NULL}; +static const char *pat_ha_meta[] = {"ha:meta", "*", NULL}; +static const char *pat_ha_data[] = {"ha:data", "*", NULL}; +static const char *pat_ha_font[] = {"ha:font", "*", NULL}; +static const char *pat_ha_netlists[] = {"ha:netlists", "*", NULL}; +static lhtpers_rule_t r_root[] = { + {pat_attributes, &style_nlstruct, NULL}, + {pat_li_styles, &style_nlstruct, NULL}, + {pat_ha_meta, &style_nlstruct, NULL}, + {pat_ha_data, &style_nlstruct, NULL}, + {pat_ha_font, &style_nlstruct, NULL}, + {pat_ha_netlists, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + +static const char *pat_net_input[] = {"ha:input", "*", NULL}; +static const char *pat_net_patch[] = {"ha:netlist_patch", "*", NULL}; +static lhtpers_rule_t r_netlists[] = { + {pat_net_input, &style_nlstruct, NULL}, + {pat_net_patch, &style_nlstruct, NULL}, + {NULL, NULL, NULL} +}; + + +static const char *pat_ls_type1[] = {"te:*", "ha:type", "ha:*", "li:groups", "ha:layer_stack", "*", NULL}; +static const char *pat_ls_type2[] = {"ha:type", "ha:*", "li:groups", "ha:layer_stack", "*", NULL}; +static const char *pat_ls_lyr1[] = {"te:*", "li:layers", "ha:*", "li:groups", "ha:layer_stack", "*", NULL}; +static const char *pat_ls_lyr2[] = {"li:layers", "ha:*", "li:groups", "ha:layer_stack", "*", NULL}; +static const char *pat_ls_name[] = {"te:name", "ha:*", "li:groups", "ha:layer_stack", "*", NULL}; +static const char *pat_ls_grps[] = {"li:groups", "ha:layer_stack", "*", NULL}; +static const char *pat_pxm_ulzw[] = {"ha:ulzw.*", "ha:pixmaps", "*", NULL}; +static const char *pat_ulzw_sx[] = {"te:sx", "ha:ulzw.*", "*", NULL}; +static const char *pat_ulzw_sy[] = {"te:sy", "ha:ulzw.*", "*", NULL}; +static const char *pat_ulzw_transp[] = {"te:transparent", "ha:ulzw.*", "*", NULL}; +static const char *pat_ulzw_pixmap[] = {"te:pixmap", "ha:ulzw.*", "*", NULL}; + +static lhtpers_rule_t r_layergrp[] = { + {pat_ls_name, NULL, NULL}, + {pat_ls_type2, &style_structsp, NULL}, + {pat_ls_lyr2, &style_structsp, NULL}, + {NULL, NULL, NULL} +}; + +static lhtpers_rule_t r_ulzw[] = { + {pat_ulzw_sx, &style_inlinesp, NULL}, + {pat_ulzw_sy, &style_inline, NULL}, + {pat_ulzw_transp, &style_inline, NULL}, + {pat_ulzw_pixmap, &style_inline, NULL}, + {NULL, NULL, NULL} +}; + + +static const char *pat_line[] = {"ha:line.*", "*", NULL}; +static const char *pat_spoly[]= {"li:simplepoly.*", "*", NULL}; +static const char *pat_rat[] = {"ha:rat.*", "*", NULL}; +static const char *pat_arc[] = {"ha:arc.*", "*", NULL}; +static const char *pat_gfx[] = {"ha:gfx.*", "*", NULL}; +static const char *pat_via[] = {"ha:via.*", "*", NULL}; +static const char *pat_psref[]= {"ha:padstack_ref.*", "*", NULL}; +static const char *pat_pin[] = {"ha:pin.*", "*", NULL}; +static const char *pat_pad[] = {"ha:pad.*", "*", NULL}; +static const char *pat_poly[] = {"ha:polygon.*", "*", NULL}; +static const char *pat_elem[] = {"ha:element.*", "*", NULL}; +static const char *pat_text[] = {"ha:text.*", "*", NULL}; +static const char *pat_data[] = {"ha:data", "*", NULL}; +static const char *pat_netlists[] = {"ha:netlists", "*", NULL}; +static const char *pat_font1[] = {"ha:geda_pcb", "ha:font", "*", NULL}; +static const char *pat_layer[] = {"ha:*", "li:layers", "*", NULL}; +static const char *pat_symbol[] = {"ha:*", "ha:symbols", "*", NULL}; +static const char *pat_thermt[] = {"te:*", "ha:thermal", "*", NULL}; +static const char *pat_flag[] = {"te:*", "ha:flags", "*", NULL}; +static const char *pat_cell[] = {"te:*", "ta:*", "*", NULL}; +static const char *pat_netinft[] = {"te:*", "li:net_info", "li:netlist_patch", "*", NULL}; +static const char *pat_nettxt[] = {"te:*", "ha:*", "li:netlist_patch", "*", NULL}; +static const char *pat_del_add[] = {"ha:*", "li:netlist_patch", "*", NULL}; +static const char *pat_netinfo[] = {"li:net_info", "li:netlist_patch", "*", NULL}; +static const char *pat_tconn[] = {"te:*", "li:conn", "ha:*", "li:*", "ha:netlists", "*", NULL}; +static const char *pat_lconn[] = {"li:conn", "ha:*", "li:*", "ha:netlists", "*", NULL}; +static const char *pat_layergrp[] = {"ha:*", "li:groups", "ha:layer_stack", "*", NULL}; +static const char *pat_combs[] = {"te:*", "ha:combining", "*", NULL}; +static const char *pat_root[] = {"^", NULL}; + +static lhtpers_rule_t r_istructs[] = { + {pat_root, &style_struct, r_root}, + + {pat_layer, &style_nlstruct, r_layer}, + {pat_symbol, &style_structi, r_symbol}, + + {pat_line, &style_structi, r_line}, + {pat_spoly, &style_structi, NULL}, + {pat_rat, &style_structi, r_rat}, + {pat_arc, &style_structi, r_arc}, + {pat_gfx, &style_structi, r_gfx}, + {pat_via, &style_structi, r_pinvia}, + {pat_psref, &style_structi, r_psref}, + {pat_pin, &style_structi, r_pinvia}, + {pat_pad, &style_structi, r_pad}, + {pat_poly, &style_structs, r_polygon}, + {pat_elem, &style_structi, r_element}, + {pat_text, &style_structi, r_text}, + {pat_data, &style_structi, r_data}, + {pat_font1, &style_structi, r_font1}, + {pat_netlists,&style_struct, r_netlists}, + {pat_ps_protos,&style_struct, r_ps_protos}, + {pat_ps_proto,&style_nlstruct, r_ps_proto}, + {pat_ps_shape_v4,&style_nlstruct,r_ps_shape_v4}, + {pat_objects, &style_nlstruct, NULL}, + {pat_flag, &style_newline, NULL}, + + {pat_layergrp,&style_structnp, r_layergrp}, + {pat_ls_grps, &style_structnp, NULL}, + + {pat_pxm_ulzw, &style_structsp, r_ulzw}, + + {pat_cell, &style_inline, NULL}, + {pat_thermt, &style_inline, NULL}, + {pat_del_add, &style_struct_thermal, NULL}, + {pat_netinfo, &style_struct_thermal, NULL}, + {pat_netinft, &style_inline, NULL}, + {pat_nettxt, &style_inline, NULL}, + {pat_tconn, &style_inline, NULL}, + {pat_lconn, &style_struct_thermal, NULL}, + + {pat_ls_type1, &style_inline, NULL}, + {pat_ls_lyr1, &style_inline, NULL}, + {pat_combs, &style_inline, NULL}, + + {NULL, NULL, NULL} +}; + +lhtpers_rule_t *io_lihata_out_rules[] = { + r_istructs, r_ilists, r_ilists, r_flags, NULL +}; + + +/*****************************************************************************/ +static const char *cpat_rat_x1[] = {"te:x1", "ha:rat.*", "*", NULL}; +static const char *cpat_rat_y1[] = {"te:y1", "ha:rat.*", "*", NULL}; +static const char *cpat_rat_x2[] = {"te:x2", "ha:rat.*", "*", NULL}; +static const char *cpat_rat_y2[] = {"te:y2", "ha:rat.*", "*", NULL}; +static const char *cpat_line_x1[] = {"te:x1", "ha:line.*", "*", NULL}; +static const char *cpat_line_y1[] = {"te:y1", "ha:line.*", "*", NULL}; +static const char *cpat_line_x2[] = {"te:x2", "ha:line.*", "*", NULL}; +static const char *cpat_line_y2[] = {"te:y2", "ha:line.*", "*", NULL}; +static const char *cpat_line_th[] = {"te:thickness", "ha:line.*", "*", NULL}; +static const char *cpat_line_cl[] = {"te:clearance", "ha:line.*", "*", NULL}; +static const char *cpat_size_x[] = {"te:x", "ha:size", "ha:meta", "*", NULL}; +static const char *cpat_size_y[] = {"te:y", "ha:size", "ha:meta", "*", NULL}; +static const char *cpat_curs_x[] = {"te:x", "ha:cursor", "ha:meta", "*", NULL}; +static const char *cpat_curs_y[] = {"te:y", "ha:cursor", "ha:meta", "*", NULL}; +static const char *cpat_curs_z[] = {"te:zoom", "ha:cursor", "ha:meta", "*", NULL}; +static const char *cpat_drc_min[] = {"te:min_*", "ha:drc", "ha:meta", "*", NULL}; +static const char *cpat_drc_blt[] = {"te:bloat", "ha:drc", "ha:meta", "*", NULL}; +static const char *cpat_drc_shr[] = {"te:shrink", "ha:drc", "ha:meta", "*", NULL}; +static const char *cpat_grido[] = {"te:offs_*", "ha:grid", "ha:meta", "*", NULL}; +static const char *cpat_grids[] = {"te:spacing", "ha:grid", "ha:meta", "*", NULL}; + +static const char *cpat_arc_x[] = {"te:x", "ha:arc.*", "*", NULL}; +static const char *cpat_arc_y[] = {"te:y", "ha:arc.*", "*", NULL}; +static const char *cpat_arc_w[] = {"te:width", "ha:arc.*", "*", NULL}; +static const char *cpat_arc_h[] = {"te:height", "ha:arc.*", "*", NULL}; +static const char *cpat_arc_th[] = {"te:thickness", "ha:arc.*", "*", NULL}; +static const char *cpat_arc_cl[] = {"te:clearance", "ha:arc.*", "*", NULL}; +static const char *cpat_geo_ta[] = {"te:*", "ta:*", "li:geometry", "*", NULL}; +static const char *cpat_text_x[] = {"te:x", "ha:text.*", "*", NULL}; +static const char *cpat_text_y[] = {"te:y", "ha:text.*", "*", NULL}; +static const char *cpat_pin_x[] = {"te:x", "ha:pin.*", "*", NULL}; +static const char *cpat_pin_y[] = {"te:y", "ha:pin.*", "*", NULL}; +static const char *cpat_pin_hole[] = {"te:hole", "ha:pin.*", "*", NULL}; +static const char *cpat_pin_mask[] = {"te:mask", "ha:pin.*", "*", NULL}; +static const char *cpat_pad_x1[] = {"te:x1", "ha:pad.*", "*", NULL}; +static const char *cpat_pad_y1[] = {"te:y1", "ha:pad.*", "*", NULL}; +static const char *cpat_pad_x2[] = {"te:x2", "ha:pad.*", "*", NULL}; +static const char *cpat_pad_y2[] = {"te:y2", "ha:pad.*", "*", NULL}; +static const char *cpat_pad_hole[] = {"te:hole", "ha:pad.*", "*", NULL}; +static const char *cpat_pad_mask[] = {"te:mask", "ha:pad.*", "*", NULL}; +static const char *cpat_elem_x[] = {"te:x", "ha:element.*", "*", NULL}; +static const char *cpat_elem_y[] = {"te:y", "ha:element.*", "*", NULL}; + +static const char *cpat_sym_w[] = {"te:width", "ha:*", "ha:symbols", "*", NULL}; +static const char *cpat_sym_h[] = {"te:height", "ha:*", "ha:symbols", "*", NULL}; +static const char *cpat_sym_d[] = {"te:delta", "ha:*", "ha:symbols", "*", NULL}; +static const char *cpat_font_w[] = {"te:cell_width", "ha:*", "ha:font", "*", NULL}; +static const char *cpat_font_h[] = {"te:cell_height", "ha:*", "ha:font", "*", NULL}; +static const char *cpat_styl_th[] = {"te:thickness", "ha:*", "li:styles", "*", NULL}; +static const char *cpat_styl_cl[] = {"te:clearance", "ha:*", "li:styles", "*", NULL}; +static const char *cpat_styl_hl[] = {"te:hole", "ha:*", "li:styles", "*", NULL}; +static const char *cpat_styl_da[] = {"te:diameter", "ha:*", "li:styles", "*", NULL}; + + +lhtpers_rule_t io_lihata_out_coords[] = { + {cpat_rat_x1, NULL, NULL}, + {cpat_rat_y1, NULL, NULL}, + {cpat_rat_x2, NULL, NULL}, + {cpat_rat_y2, NULL, NULL}, + {cpat_line_x1, NULL, NULL}, + {cpat_line_y1, NULL, NULL}, + {cpat_line_x2, NULL, NULL}, + {cpat_line_y2, NULL, NULL}, + {cpat_line_th, NULL, NULL}, + {cpat_line_cl, NULL, NULL}, + {cpat_size_x, NULL, NULL}, + {cpat_size_y, NULL, NULL}, + {cpat_curs_x, NULL, NULL}, + {cpat_curs_y, NULL, NULL}, + {cpat_curs_z, NULL, NULL}, + {cpat_drc_min, NULL, NULL}, + {cpat_drc_blt, NULL, NULL}, + {cpat_drc_shr, NULL, NULL}, + {cpat_grido, NULL, NULL}, + {cpat_grids, NULL, NULL}, + {cpat_arc_x, NULL, NULL}, + {cpat_arc_y, NULL, NULL}, + {cpat_arc_w, NULL, NULL}, + {cpat_arc_h, NULL, NULL}, + {cpat_arc_th, NULL, NULL}, + {cpat_arc_cl, NULL, NULL}, + {cpat_geo_ta, NULL, NULL}, + {cpat_text_x, NULL, NULL}, + {cpat_text_y, NULL, NULL}, + {cpat_pin_x, NULL, NULL}, + {cpat_pin_y, NULL, NULL}, + {cpat_pin_hole, NULL, NULL}, + {cpat_pin_mask, NULL, NULL}, + {cpat_pad_x1, NULL, NULL}, + {cpat_pad_y1, NULL, NULL}, + {cpat_pad_x2, NULL, NULL}, + {cpat_pad_y2, NULL, NULL}, + {cpat_pad_hole, NULL, NULL}, + {cpat_pad_mask, NULL, NULL}, + {cpat_elem_x, NULL, NULL}, + {cpat_elem_y, NULL, NULL}, + {cpat_sym_w, NULL, NULL}, + {cpat_sym_h, NULL, NULL}, + {cpat_sym_d, NULL, NULL}, + {cpat_font_w, NULL, NULL}, + {cpat_font_h, NULL, NULL}, + {cpat_styl_th, NULL, NULL}, + {cpat_styl_cl, NULL, NULL}, + {cpat_styl_hl, NULL, NULL}, + {cpat_styl_da, NULL, NULL}, + {NULL, NULL, NULL} +}; + Index: tags/2.3.0/src_plugins/io_lihata/write_style.h =================================================================== --- tags/2.3.0/src_plugins/io_lihata/write_style.h (nonexistent) +++ tags/2.3.0/src_plugins/io_lihata/write_style.h (revision 33253) @@ -0,0 +1,33 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Specify default output formatting style to be more compact than + the canonical lihata export style */ + +#include + +extern lhtpers_rule_t *io_lihata_out_rules[]; +extern lhtpers_rule_t io_lihata_out_coords[]; Index: tags/2.3.0/src_plugins/io_mentor_cell/Makefile =================================================================== --- tags/2.3.0/src_plugins/io_mentor_cell/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/io_mentor_cell/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_io_mentor_cell + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/io_mentor_cell/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/io_mentor_cell/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/io_mentor_cell/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {io_mentor_cell} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/io_mentor_cell/io_mentor_cell.o + $(PLUGDIR)/io_mentor_cell/read.o +@] + +switch /local/pcb/io_mentor_cell/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/io_mentor_cell/font.c =================================================================== --- tags/2.3.0/src_plugins/io_mentor_cell/font.c (nonexistent) +++ tags/2.3.0/src_plugins/io_mentor_cell/font.c (revision 33253) @@ -0,0 +1,88 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "font_geo.c" + +typedef enum { + FSR_SUCCESS = 0, + FSR_INVALID_FONT_ID, /* fatal, no output generated: print error and abort parsing */ + FSR_INVALID_GLYPH_ID /* non-fatal but sizes may be wrong: print error but do not abort */ +} font_size_res_t; + +/* Which glyph code to use for a glyph that is not in our arrays */ +#define UNKNOWN_GLYPH 32 + +#define LINE_END \ +do { \ + if (lw > tw) \ + tw = lw; \ + lw = 0; \ + lines++; \ +} while(0) + +/* Calculate the nominal size of a potentially multi-line text object. Output: + - width is the width of the longest line + - height is the total net height from bottom to top (depends on number of lines) + - yoffs is the vertical offset because of the baseline (does not depend on number of lines) +*/ +static font_size_res_t font_text_nominal_size(int font_id, const char *txt, rnd_coord_t *width, rnd_coord_t *height, rnd_coord_t *yoffs) +{ + const char *s; + double lw = 0; /* current line width */ + double tw = 0; /* total width */ + double *gw; + int lines = 0, bad_glyph = 0; + + if (!PCB_MENTOR_FONT_ID_VALID(font_id)) + return FSR_INVALID_FONT_ID; + + gw = pcb_mentor_font_widths[font_id]; + for(s = txt; *s != '\0'; s++) { + int code = *s; + if (*s == '\n') { + LINE_END; + continue; + } + if (!PCB_MENTOR_FONT_GLYPH_VALID(code)) { + bad_glyph = 1; + if (PCB_MENTOR_FONT_GLYPH_VALID(UNKNOWN_GLYPH)) + lw += gw[UNKNOWN_GLYPH]; + } + else + lw += gw[code]; + } + LINE_END; + + *width = RND_MM_TO_COORD(tw); + *height = RND_MM_TO_COORD((double)lines * (pcb_mentor_font_ymax[font_id] - pcb_mentor_font_ymin[font_id])); + *yoffs = RND_MM_TO_COORD(pcb_mentor_font_ymin[font_id]); + + return bad_glyph ? FSR_INVALID_GLYPH_ID : FSR_SUCCESS; +} + + +#undef UNKNOWN_GLYPH +#undef LINE_END Index: tags/2.3.0/src_plugins/io_mentor_cell/font_geo.c =================================================================== --- tags/2.3.0/src_plugins/io_mentor_cell/font_geo.c (nonexistent) +++ tags/2.3.0/src_plugins/io_mentor_cell/font_geo.c (revision 33253) @@ -0,0 +1,90 @@ +/* + Autogenerated file, please do not edit + Source: svn://repo.hu/pcb-rnd-aux/trunk/alien_fmt_test/io_mentor_cell/font +*/ + +/* Number of different fonts */ +#define PCB_MENTOR_FONT_IDS 2 +#define PCB_MENTOR_FONT_GLYPHS 127 + +/* Ymin and Ymax values per font (in mm) */ +static double pcb_mentor_font_ymax[PCB_MENTOR_FONT_IDS] = { 1.0248275862068965, 1.0248275862068965}; +static double pcb_mentor_font_ymin[PCB_MENTOR_FONT_IDS] = { -0.3972413793103448, -0.3972413793103448}; + +/* glyph widths, per font per glyph (in mm)*/ +static double pcb_mentor_font_width_0[PCB_MENTOR_FONT_GLYPHS] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0.689655172413793, 0.7393103448275862, 0.743448275862069, 0.913103448275862, + 0.9117241379310345, 0.9172413793103448, 0.9048275862068965, 0.0, + 0.8041379310344827, 0.8027586206896551, 0.8758620689655172, 0.8965517241379309, + 0.7448275862068965, 0.8758620689655172, 0.7420689655172413, 0.913103448275862, + 0.9117241379310345, 0.8786206896551724, 0.9117241379310345, 0.9117241379310345, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, + 0.9034482758620689, 0.9117241379310345, 0.7420689655172413, 0.7420689655172413, + 0.9006896551724137, 0.9117241379310345, 0.7820689655172414, 0.9117241379310345, + 0.9117241379310345, 0.9144827586206896, 0.9117241379310345, 0.9103448275862068, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.9103448275862068, + 0.9117241379310345, 0.8786206896551724, 0.9117241379310345, 0.9117241379310345, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.8648275862068965, + 0.9103448275862068, 0.8648275862068965, 0.84, 0.9103448275862068, + 0.9103448275862068, 0.9103448275862068, 0.9103448275862068, 0.9103448275862068, + 0.9103448275862068, 0.9103448275862068, 0.9048275862068965, 0.9103448275862068, + 0.9103448275862068, 0.84, 0.8620689655172413, 0.9103448275862068, + 0.8758620689655172, 0.9103448275862068, 0.9103448275862068, 0.9103448275862068, + 0.9103448275862068, 0.9103448275862068, 0.913103448275862, 0.9117241379310345, + 0.9048275862068965, 0.9117241379310345, 0.9103448275862068, 0.9089655172413792, + 0.9103448275862068, 0.913103448275862, 0.9089655172413792, 0.8634482758620688, + 0.689655172413793, 0.8634482758620688, 0.9103448275862068}; + +static double pcb_mentor_font_width_1[PCB_MENTOR_FONT_GLYPHS] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0.6910344827586207, 0.8786206896551724, 0.9186206896551723, + 0.8924137931034483, 0.9158620689655171, 0.9117241379310345, 0.7517241379310344, + 0.8068965517241379, 0.8027586206896551, 0.8772413793103447, 0.8993103448275861, + 0.7475862068965516, 0.8758620689655172, 0.689655172413793, 0.9103448275862068, + 0.9117241379310345, 0.8055172413793102, 0.9117241379310345, 0.9117241379310345, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, + 0.9117241379310345, 0.9117241379310345, 0.689655172413793, 0.8082758620689654, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.9103448275862068, + 0.9117241379310345, 0.9144827586206896, 0.9117241379310345, 0.9103448275862068, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.9103448275862068, + 0.9117241379310345, 0.8786206896551724, 0.9117241379310345, 0.9117241379310345, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, + 0.9117241379310345, 0.9103448275862068, 0.9117241379310345, 0.9117241379310345, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, + 0.9117241379310345, 0.9117241379310345, 0.9117241379310345, 0.8648275862068965, + 0.9103448275862068, 0.8648275862068965, 0.84, 0.9103448275862068, + 0.9117241379310345, 0.9103448275862068, 0.9103448275862068, 0.9103448275862068, + 0.9103448275862068, 0.9103448275862068, 0.9103448275862068, 0.9103448275862068, + 0.9103448275862068, 0.49241379310344824, 0.6193103448275862, 0.9103448275862068, + 0.49241379310344824, 0.9103448275862068, 0.9103448275862068, 0.9103448275862068, + 0.9103448275862068, 0.9103448275862068, 1.0124137931034483, 0.9075862068965517, + 0.9103448275862068, 0.9103448275862068, 0.9103448275862068, 0.9103448275862068, + 0.9103448275862068, 0.9103448275862068, 0.9117241379310345, 0.8413793103448275, + 0.689655172413793, 0.8413793103448275, 0.9103448275862068}; + +static double *pcb_mentor_font_widths[PCB_MENTOR_FONT_IDS] = { + pcb_mentor_font_width_0, + pcb_mentor_font_width_1 +}; + +/* Macros to determine whether an font id or glyph is within range */ +#define PCB_MENTOR_FONT_ID_VALID(id) (((id) >= 0) && ((id) < PCB_MENTOR_FONT_IDS)) +#define PCB_MENTOR_FONT_GLYPH_VALID(gl) (((gl) >= 0) && ((gl) < PCB_MENTOR_FONT_GLYPHS)) Index: tags/2.3.0/src_plugins/io_mentor_cell/io_mentor_cell.c =================================================================== --- tags/2.3.0/src_plugins/io_mentor_cell/io_mentor_cell.c (nonexistent) +++ tags/2.3.0/src_plugins/io_mentor_cell/io_mentor_cell.c (revision 33253) @@ -0,0 +1,88 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017 Tibor 'Igor2' Palinkas + * + * This module, io_mentor_cell, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include "plug_io.h" +#include "read.h" +#include + +static pcb_plug_io_t io_mentor_cell; +static const char *mentor_cell_cookie = "mentor_cell plugin"; + +int io_mentor_cell_fmt(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, int wr, const char *fmt) +{ + if (wr && (typ & PCB_IOT_FOOTPRINT)) /* no footprint write */ + return 0; + + if (strcmp(ctx->description, fmt) == 0) + return 200; + + if ((strcmp(fmt, "mentor_cell") != 0) || + ((typ & (~(PCB_IOT_FOOTPRINT | PCB_IOT_BUFFER | PCB_IOT_PCB))) != 0)) + return 0; + + return 100; +} + +int pplg_check_ver_io_mentor_cell(int ver_needed) { return 0; } + +void pplg_uninit_io_mentor_cell(void) +{ + rnd_remove_actions_by_cookie(mentor_cell_cookie); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_mentor_cell); +} + +int pplg_init_io_mentor_cell(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + io_mentor_cell.plugin_data = NULL; + io_mentor_cell.fmt_support_prio = io_mentor_cell_fmt; + io_mentor_cell.test_parse = io_mentor_cell_test_parse; + io_mentor_cell.parse_pcb = io_mentor_cell_read_pcb; + io_mentor_cell.parse_footprint = NULL; + io_mentor_cell.map_footprint = NULL; + io_mentor_cell.parse_font = NULL; + io_mentor_cell.write_buffer = NULL; + io_mentor_cell.write_pcb = NULL; + io_mentor_cell.default_fmt = "mentor_cell"; + io_mentor_cell.description = "Mentor graphics cell footprint lib"; + io_mentor_cell.save_preference_prio = 60; + io_mentor_cell.default_extension = ".hkp"; + io_mentor_cell.fp_extension = ".hkp"; + io_mentor_cell.mime_type = "application/x-mentor_cell"; + + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_mentor_cell); + + return 0; +} + Index: tags/2.3.0/src_plugins/io_mentor_cell/io_mentor_cell.pup =================================================================== --- tags/2.3.0/src_plugins/io_mentor_cell/io_mentor_cell.pup (nonexistent) +++ tags/2.3.0/src_plugins/io_mentor_cell/io_mentor_cell.pup (revision 33253) @@ -0,0 +1,9 @@ +$class io +$short Mentor Graphics cell footprints +$long Load Mentor Graphics cell footprint library and make footprints available (e.g. for fp_board) +$state WIP +$fmt-native no +$fmt-feature-r Mentor Graphics cell footprints +default disable + +autoload 1 Index: tags/2.3.0/src_plugins/io_mentor_cell/read.c =================================================================== --- tags/2.3.0/src_plugins/io_mentor_cell/read.c (nonexistent) +++ tags/2.3.0/src_plugins/io_mentor_cell/read.c (revision 33253) @@ -0,0 +1,1464 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,2019 Tibor 'Igor2' Palinkas + * + * This module, io_mentor_cell, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "conf_core.h" +#include "plug_io.h" +#include +#include +#include +#include +#include "netlist.h" + +#include "obj_subc.h" + +#define DEFAULT_OBJ_FLAG pcb_flag_make(PCB_FLAG_CLEARLINE) +#define DEFAULT_POLY_FLAG pcb_flag_make(PCB_FLAG_CLEARPOLY) + +#define ltrim(s) while(isspace(*s)) (s)++ + +#include "../src_plugins/lib_compat_help/pstk_help.h" + +#include "font.c" + +typedef struct node_s node_t; +typedef struct hkp_tree_s hkp_tree_t; + +struct node_s { + char **argv; + int argc; + int level; + hkp_tree_t *tree; + long lineno; + node_t *parent, *next; + node_t *first_child, *last_child; +}; + +struct hkp_tree_s { + char *filename; + node_t *root, *curr; +}; + +typedef struct { + const rnd_unit_t *unit; + node_t *subtree; + unsigned valid:1; /* whether it's already parsed */ + pcb_pstk_shape_t shp; +} hkp_shape_t; + +typedef struct { + const rnd_unit_t *unit; + node_t *subtree; + unsigned valid:1; /* whether it's already parsed */ + unsigned plated:1; + rnd_coord_t dia; /* Should be zero when defining w,h slot */ + rnd_coord_t w,h; /* Slot width and height */ +} hkp_hole_t; + +typedef struct { + const rnd_unit_t *unit; + node_t *subtree; + unsigned valid:1; /* whether it's already parsed */ + pcb_pstk_proto_t proto; +} hkp_pstk_t; + +typedef enum { + HKP_CLR_POLY2TRACE, + HKP_CLR_POLY2TERM, + HKP_CLR_POLY2VIA, + HKP_CLR_POLY2POLY, + HKP_CLR_max +} hkp_clearance_type_t; + +typedef struct { + rnd_coord_t clearance[PCB_MAX_LAYER][HKP_CLR_max]; +} hkp_netclass_t; + +typedef struct { + pcb_board_t *pcb; + + int num_cop_layers; + + const rnd_unit_t *unit; /* default unit used while converting coords any given time */ + const rnd_unit_t *pstk_unit; /* default unit for the padstacks file */ + + hkp_netclass_t nc_dflt; /* for default clearances */ + + htsp_t shapes; /* name -> hkp_shape_t */ + htsp_t holes; /* name -> hkp_hole_t */ + htsp_t pstks; /* name -> hkp_pstk_t */ + hkp_tree_t layout, padstacks; +} hkp_ctx_t; + +/*** read_pstk.c ***/ +static void parse_pin(hkp_ctx_t *ctx, pcb_subc_t *subc, const hkp_netclass_t *nc, node_t *nd, int on_bottom); +static hkp_pstk_t *parse_pstk(hkp_ctx_t *ctx, const char *ps); +static void set_pstk_clearance(hkp_ctx_t *ctx, const hkp_netclass_t *nc, pcb_pstk_t *ps, node_t *errnd); + +/*** read_net.c ***/ +static rnd_coord_t net_get_clearance(hkp_ctx_t *ctx, pcb_layer_t *ly, const hkp_netclass_t *nc, hkp_clearance_type_t type, node_t *errnode); + +/*** local ***/ +static pcb_layer_t *parse_layer(hkp_ctx_t *ctx, pcb_subc_t *subc, const char *ln, int user, node_t *err_node); + +/*** High level parser ***/ + +static int hkp_error(node_t *nd, char *fmt, ...) +{ + gds_t str; + va_list ap; + + gds_init(&str); + gds_append_str(&str, "io_mentor_cell ERROR"); + if (nd != NULL) + rnd_append_printf(&str, " at %s:%d: ", nd->tree->filename, nd->lineno); + else + gds_append_str(&str, ": "); + + va_start(ap, fmt); + rnd_safe_append_vprintf(&str, 0, fmt, ap); + va_end(ap); + + rnd_message(RND_MSG_ERROR, "%s", str.array); + + gds_uninit(&str); + return -1; +} + +/* Return the idxth sibling with matching name */ +static node_t *find_nth(node_t *nd, char *name, int idx) +{ + for(; nd != NULL; nd = nd->next) { + if (strcmp(nd->argv[0], name) == 0) { + if (idx == 0) + return nd; + idx--; + } + } + return NULL; +} + +/* parse a string it into a coord - modifies s; returns 0 on success */ +static int parse_coord(hkp_ctx_t *ctx, char *s, rnd_coord_t *crd) +{ + char *end; + rnd_bool suc; + + end = strchr(s, ','); + if (end != NULL) + *end = '\0'; + + *crd = rnd_get_value(s, ctx->unit->suffix, NULL, &suc); + return !suc; +} + +static int parse_x(hkp_ctx_t *ctx, char *s, rnd_coord_t *crd) +{ + return parse_coord(ctx, s, crd); +} + + +static int parse_y(hkp_ctx_t *ctx, char *s, rnd_coord_t *crd) +{ + rnd_coord_t tmp; + if (parse_coord(ctx, s, &tmp) != 0) + return -1; + *crd = -tmp; + return 0; +} + + +/* split s and parse it into (x,y) - modifies s */ +static int parse_xy(hkp_ctx_t *ctx, char *s, rnd_coord_t *x, rnd_coord_t *y, int xform) +{ + char *sy; + rnd_coord_t xx, yy; + rnd_bool suc1, suc2; + + if (s == NULL) + return -1; + sy = strchr(s, ','); + if (sy == NULL) + return -1; + + *sy = '\0'; + sy++; + + + xx = rnd_get_value(s, ctx->unit->suffix, NULL, &suc1); + yy = rnd_get_value(sy, ctx->unit->suffix, NULL, &suc2); + + if (xform) + yy = -yy; + + *x = xx; + *y = yy; + + return !(suc1 && suc2); +} + +/* split s and parse it into (x,y,r) - modifies s */ +static int parse_xyr(hkp_ctx_t *ctx, char *s, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t *r, int xform) +{ + char *sy, *sr; + rnd_coord_t xx, yy, rr; + rnd_bool suc1, suc2, suc3; + + if (s == NULL) + return -1; + + sy = strchr(s, ','); + if (sy == NULL) + return -1; + + *sy = '\0'; + sy++; + + sr = strchr(sy, ','); + if (sr == NULL) + return -1; + + *sr = '\0'; + sr++; + + xx = rnd_get_value(s, ctx->unit->suffix, NULL, &suc1); + yy = rnd_get_value(sy, ctx->unit->suffix, NULL, &suc2); + rr = rnd_get_value(sr, ctx->unit->suffix, NULL, &suc3); + + if (xform) + yy = -yy; + + *x = xx; + *y = yy; + *r = rr; + + if (suc1 == rnd_false) + hkp_error(NULL, "parse_xyr error parsing %s.\n", s); + if (suc2 == rnd_false) + hkp_error(NULL, "parse_xyr error parsing %s.\n", sy); + if (suc3 == rnd_false) + hkp_error(NULL, "parse_xyr error parsing %s.\n", sr); + return !(suc1 && suc2 && suc3); +} + +static int parse_rot(hkp_ctx_t *ctx, node_t *nd, double *rot_out, int on_bottom) +{ + double rot; + char *end; + + /* hkp rotation: top side positive value is CW; in pcb-rnd: that's negative */ + rot = -strtod(nd->argv[1], &end); + if (*end != '\0') + return hkp_error(nd, "Wrong rotation value '%s' (expected numeric)\n", nd->argv[1]); + if ((rot < -360) || (rot > 360)) + return hkp_error(nd, "Wrong rotation value '%s' (out of range)\n", nd->argv[1]); + if (on_bottom == 0) + rot = -rot; + *rot_out = rot; + return 0; +} + +#define DWG_LY(node, name, name2) \ + if (ly == NULL) { \ + node_t *__tmp__ = find_nth(node->first_child, name, 0), *__tmp2__ = NULL; \ + if ((__tmp__ == NULL) && (name2 != NULL)) \ + __tmp2__ = find_nth(node->first_child, name2, 0); \ + if (__tmp__ != NULL) { \ + ly = parse_layer(ctx, subc, __tmp__->argv[1], 0, __tmp__); \ + if (ly == NULL) { \ + hkp_error(__tmp__, "Invalid layer %s in %s\n", __tmp__->argv[1], name); \ + return; \ + } \ + } \ + else if (__tmp2__ != NULL) { \ + ly = parse_layer(ctx, subc, __tmp2__->argv[1], 1, __tmp2__); \ + if (ly == NULL) { \ + hkp_error(__tmp2__, "Invalid layer %s in %s\n", __tmp2__->argv[1], name2); \ + return; \ + } \ + }\ + else {\ + hkp_error(node, "Missing layer reference (%s)\n", name); \ + return; \ + } \ + } + + +#define DWG_REQ_LY(node) \ + if (ly == NULL) { \ + hkp_error(node, "Internal error: expected existing layer from the caller\n"); \ + return -1; \ + } + +static int parse_dwg_path_polyline(hkp_ctx_t *ctx, pcb_subc_t *subc, pcb_layer_t *ly, const hkp_netclass_t *nc, node_t *pp, int is_shape) +{ + node_t *tmp; + rnd_coord_t th = 1, px, py, x, y; + int n, filled = 0; + + DWG_REQ_LY(pp); + + if (is_shape) { + tmp = find_nth(pp->first_child, "SHAPE_OPTIONS", 0); + if (tmp != NULL) + filled = (strcmp(tmp->argv[1], "FILLED") == 0); + } + else { + th = RND_MM_TO_COORD(0.5); + tmp = find_nth(pp->first_child, "WIDTH", 0); + if (tmp != NULL) + parse_coord(ctx, tmp->argv[1], &th); + } + + tmp = find_nth(pp->first_child, "XY", 0); + if (tmp == NULL) + return hkp_error(pp, "Missing polyline XY, can't place via\n"); + + if (filled) { /* filled = polygon */ + pcb_poly_t *poly = pcb_poly_new(ly, 0, DEFAULT_POLY_FLAG); + for(n = 1; n < tmp->argc; n++) { + if (parse_xy(ctx, tmp->argv[n], &x, &y, 1) != 0) { + pcb_poly_free(poly); + return hkp_error(pp, "Failed to parse filled polygon point (%s), can't place polygon\n", tmp->argv[n]); + } + pcb_poly_point_new(poly, x, y); + } + pcb_add_poly_on_layer(ly, poly); + if (subc == NULL) + pcb_poly_init_clip(ctx->pcb->Data, ly, poly); + } + else { /* "polyline" = a bunch of line objects */ + rnd_coord_t cl = net_get_clearance(ctx, ly, nc, HKP_CLR_POLY2TRACE, tmp) * 2; + if (parse_xy(ctx, tmp->argv[1], &px, &py, 1) != 0) + return hkp_error(pp, "Failed to parse polyline start point (%s), can't place polygon\n", tmp->argv[1]); + for(n = 2; n < tmp->argc; n++) { + if (parse_xy(ctx, tmp->argv[n], &x, &y, 1) != 0) + return hkp_error(pp, "Failed to parse polyline point (%s), can't place polygon\n", tmp->argv[n]); + if (pcb_line_new(ly, px, py, x, y, th, cl, DEFAULT_OBJ_FLAG) == NULL) + return hkp_error(pp, "Failed to create line for POLYLINE_PATH\n"); + px = x; + py = y; + } + } + return 0; +} + +static void convert_arc(rnd_coord_t sx, rnd_coord_t sy, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t ex, rnd_coord_t ey, rnd_coord_t *r, double *sa, double *da) +{ + /* In pcb-rnd, start angle 0 is towards the left of the screen (-x direction)*/ + /* da > 0 is counterclockwise */ + /* In HKP format, r<0 means counterclockwise, r>0 means clockwise */ + double ea; + rnd_coord_t srx, sry, erx, ery; /* relative x;y from the center for start and end */ + + srx = -(sx - cx); sry = sy - cy; /* Since angle = 0 is towards -x, change sign to x part */ + erx = -(ex - cx); ery = ey - cy; /* Since angle = 0 is towards -x, change sign to x part */ + *sa = atan2(sry, srx) * RND_RAD_TO_DEG; + *sa = rnd_normalize_angle(360 + *sa); /* normalize angle between 0 and 359 */ + ea = atan2(ery, erx) * RND_RAD_TO_DEG; + ea = rnd_normalize_angle(360 + ea); /* normalize angle between 0 and 359 */ + + if (*r < 0) { + /* counterclockwise */ + *r = -(*r); + if (*sa < ea) + *da = ea - *sa; + else + *da = (360 - *sa) + ea; + } + else { + /* clockwise */ + if (*sa > ea) + *da = *sa - ea; + else + *da = *sa + (360 - ea); + *da = -*da; + } +} + +static int parse_dwg_path_polyarc(hkp_ctx_t *ctx, pcb_subc_t *subc, pcb_layer_t *ly, const hkp_netclass_t *nc, node_t *pp, int is_shape) +{ + node_t *tmp; + rnd_coord_t th = 1, r, ex, ey, dummy, x, y, px, py; + double sa, da; + int n, filled = 0; + rnd_coord_t cl; + + DWG_REQ_LY(pp); + + + if (is_shape) { + tmp = find_nth(pp->first_child, "SHAPE_OPTIONS", 0); + if (tmp != NULL) + filled = (strcmp(tmp->argv[1], "FILLED") == 0); + } + else { + th = RND_MM_TO_COORD(0.5); + tmp = find_nth(pp->first_child, "WIDTH", 0); + if (tmp != NULL) + parse_coord(ctx, tmp->argv[1], &th); + } + + tmp = find_nth(pp->first_child, "XYR", 0); + if (tmp == NULL) + return hkp_error(pp, "Missing polyarc XYR, can't place arc\n"); + + + if (parse_xyr(ctx, tmp->argv[1], &px, &py, &r, 1) != 0) + return hkp_error(pp, "Failed to parse polyarc XYR start point, can't place polyarc\n"); + if (r != 0) + return hkp_error(pp, "Failed to parse polyarc XYR start point (r must be zero), can't place polyarc\n"); + + cl = net_get_clearance(ctx, ly, nc, HKP_CLR_POLY2TRACE, tmp) * 2; + + for(n = 2; n < tmp->argc; n++) { + if (parse_xyr(ctx, tmp->argv[n], &x, &y, &r, 1) != 0) + return hkp_error(pp, "Failed to parse %dth polyarc XYR point (%s), can't place polyarc\n", n, tmp->argv[n]); + if (r != 0) { /* arc: px;py=start, x;y=center, ex;ey=end */ + n++; + if (parse_xyr(ctx, tmp->argv[n], &ex, &ey, &dummy, 1) != 0) + return hkp_error(pp, "Failed to parse %dth polyarc XYR point (arc end) (%s), can't place polyarc\n", n, tmp->argv[n]); + if (dummy != 0) + return hkp_error(pp, "Failed to parse %dth polyarc XYR point (r must be zero), can't place polyarc\n", n); + + convert_arc(px, py, x, y, ex, ey, &r, &sa, &da); + + if (pcb_arc_new(ly, x, y, r, r, sa, da, th, cl, DEFAULT_OBJ_FLAG, 0) == NULL) + return hkp_error(pp, "Failed to create arc for POLYARC_PATH\n"); + + px = ex; py = ey; + } + else { /* plain old line: px;py=start, x;y=end */ + if (pcb_line_new(ly, px, py, x, y, th, cl, DEFAULT_OBJ_FLAG) == NULL) + return hkp_error(pp, "Failed to create line for POLYARC_PATH\n"); + px = x; py = y; + } + } + + return 0; +} + +static int parse_dwg_rect(hkp_ctx_t *ctx, pcb_subc_t *subc, pcb_layer_t *ly, const hkp_netclass_t *nc, node_t *rp, int is_shape) +{ + node_t *tmp; + rnd_coord_t th = 1, x1, y1, x2, y2; + int filled = 0; + + DWG_REQ_LY(rp); + + if (is_shape) { + tmp = find_nth(rp->first_child, "SHAPE_OPTIONS", 0); + if (tmp != NULL) + filled = (strcmp(tmp->argv[1], "FILLED") == 0); + } + else { + tmp = find_nth(rp->first_child, "WIDTH", 0); + if (tmp != NULL) + parse_coord(ctx, tmp->argv[1], &th); + } + + tmp = find_nth(rp->first_child, "XY", 0); + if (parse_xy(ctx, tmp->argv[1], &x1, &y1, 1) != 0) + return hkp_error(tmp, "Failed to parse rect start point (%s), can't place rectangle\n", tmp->argv[1]); + if (parse_xy(ctx, tmp->argv[2], &x2, &y2, 1) != 0) + return hkp_error(tmp, "Failed to parse rect end point (%s), can't place rectangle\n", tmp->argv[2]); + if (filled) { + rnd_coord_t cl = net_get_clearance(ctx, ly, nc, HKP_CLR_POLY2POLY, tmp) * 2; +TODO("when to generate a rounded corner?"); + pcb_poly_new_from_rectangle(ly, x1, y1, x2, y2, cl, DEFAULT_POLY_FLAG); + } + else { + rnd_coord_t cl = net_get_clearance(ctx, ly, nc, HKP_CLR_POLY2TRACE, tmp) * 2; + pcb_line_new(ly, x1, y1, x2, y1, th, cl, DEFAULT_OBJ_FLAG); + pcb_line_new(ly, x2, y1, x2, y2, th, cl, DEFAULT_OBJ_FLAG); + pcb_line_new(ly, x2, y2, x1, y2, th, cl, DEFAULT_OBJ_FLAG); + pcb_line_new(ly, x1, y2, x1, y1, th, cl, DEFAULT_OBJ_FLAG); + } + return 0; +} + +static void parse_dwg_text(hkp_ctx_t *ctx, pcb_subc_t *subc, pcb_layer_t *ly, const hkp_netclass_t *nc, node_t *nt, int omit_on_silk, pcb_flag_values_t flg) +{ + node_t *attr, *tmp; + rnd_coord_t tx, ty, h, thickness, width, height, ymin; + rnd_coord_t anchx, anchy; + double rot; + unsigned long mirrored = 0; + long int font_id; + char *tmp_char; + font_size_res_t result; + + attr = find_nth(nt->first_child, "DISPLAY_ATTR", 0); + if (attr == NULL) + return; + + DWG_LY(attr, "TEXT_LYR", "USER_LYR") + + /* Special case: although the PARTNO is written on the silk layer by the + hkp file, it does not show up on the gerber so there must be some + mechanism in the original software to hide it */ + if (omit_on_silk && (pcb_layer_flags_(ly) & PCB_LYT_SILK)) + return; + + tmp = find_nth(attr->first_child, "XY", 0); + if (tmp != NULL) { + parse_x(ctx, tmp->argv[1], &tx); + parse_y(ctx, tmp->argv[2], &ty); + } + else { + hkp_error(attr, "Can not find XY position of text. Text will be NOT rendered.\n"); + return; + } + tmp = find_nth(attr->first_child, "ROTATION", 0); + if (tmp != NULL) + parse_rot(ctx, tmp, &rot, (pcb_layer_flags_(ly) & PCB_LYT_BOTTOM)); + else { + hkp_error(attr, "Can not find rotation of text. Text will be NOT rendered.\n"); + return; + } + + tmp = find_nth(attr->first_child, "TEXT_OPTIONS", 0); + if (tmp != NULL) + if (strcmp(tmp->argv[1], "MIRRORED") == 0) + mirrored = PCB_TXT_MIRROR_X; + + tmp = find_nth(attr->first_child, "HEIGHT", 0); + if (tmp != NULL) + parse_x(ctx, tmp->argv[1], &h); + else { + hkp_error(attr, "Can not find height of text. Text will be NOT rendered.\n"); + return; + } + + tmp = find_nth(attr->first_child, "STROKE_WIDTH", 0); + if (tmp != NULL) + parse_x(ctx, tmp->argv[1], &thickness); + else { + hkp_error(attr, "Can not find thickness (STROKE WIDTH) of text. Text will be NOT rendered.\n"); + return; + } + + tmp = find_nth(attr->first_child, "FONT", 0); + if (tmp != NULL) { + if (rnd_strncasecmp(tmp->argv[1], "VeriBest Gerber ", 16) != 0) + hkp_error(tmp, "Unknown font (%s). Text will be rendered, but it may not have a correct size.\n", tmp->argv[1]); + font_id = strtol(tmp->argv[1]+16, &tmp_char, 10); + if (*tmp_char != '\0') + hkp_error(tmp, "Unparsed text (%s) after font ID. Text will be rendered, but it may not have a correct size.\n", tmp_char); + } + else { + hkp_error(attr, "Can not find font of text. Text will be NOT rendered.\n"); + return; + } + + result = font_text_nominal_size(font_id, nt->argv[1], &width, &height, &ymin); + if (result == FSR_INVALID_GLYPH_ID) + hkp_error(tmp, "Invalid glyph ID. Text will be rendered, but it may not have a correct size.\n"); + else if (result == FSR_INVALID_FONT_ID) { + hkp_error(tmp, "Invalid font ID. Text will be NOT rendered.\n"); + return; + } + + width = width * RND_COORD_TO_MM(h) + thickness; + height = height * RND_COORD_TO_MM(h) + thickness; + ymin = ymin * RND_COORD_TO_MM(h); + + tmp = find_nth(attr->first_child, "HORZ_JUST", 0); + if (tmp != NULL) { + if (strcmp(tmp->argv[1], "Left") == 0) + anchx = 0; + else if (strcmp(tmp->argv[1], "Center") == 0) + anchx = width >> 1; + else if (strcmp(tmp->argv[1], "Right") == 0) + anchx = width; + else + hkp_error(tmp, "Unknown horizontal alignment (%s). Text will be rendered, but it may not have a correct size.\n", tmp->argv[1]); + } + else { + hkp_error(attr, "Can not find horizontal justification of text. Text will be NOT rendered.\n"); + return; + } + + tmp = find_nth(attr->first_child, "VERT_JUST", 0); + if (tmp != NULL) { + rnd_coord_t ymax = height+ymin; + if (strcmp(tmp->argv[1], "Top") == 0) + anchy = 0; + else if (strcmp(tmp->argv[1], "Center") == 0) + anchy = ymax >> 1; + else if (strcmp(tmp->argv[1], "Bottom") == 0) + anchy = height+ymin; /* ymin is negative */ + else + hkp_error(tmp, "Unknown horizontal alignment (%s). Text will be rendered, but it may not have a correct size.\n", tmp->argv[1]); + } + else { + hkp_error(attr, "Can not find vertical justification of text. Text will be NOT rendered.\n"); + return; + } + +TODO("figure what TEXT_OPTIONS we have. One of them is MIRRORED (brd2 example)"); + + if (mirrored != 0) + rot = -rot; + pcb_text_new_by_bbox(ly, pcb_font(ctx->pcb, 0, 0), tx, ty, width, height, anchx, anchy, 1, mirrored, rot, thickness, nt->argv[1], pcb_flag_make(flg)); +} + +static void parse_dgw_via(hkp_ctx_t *ctx, const hkp_netclass_t *nc, node_t *nv) +{ + rnd_coord_t vx, vy; + node_t *tmp; + hkp_pstk_t *hps; + rnd_cardinal_t pid; + pcb_pstk_t *ps; + + tmp = find_nth(nv->first_child, "XY", 0); + if (tmp == NULL) { + hkp_error(nv, "Missing VIA XY, can't place via\n"); + return; + } + parse_x(ctx, tmp->argv[1], &vx); + parse_y(ctx, tmp->argv[2], &vy); + + TODO("bbvia:"); +/* + tmp = find_nth(nv->first_child, "LAYER_PAIR", 0); + if (tmp != NULL) { + + } +*/ + + tmp = find_nth(nv->first_child, "VIA_OPTIONS", 0); + if (tmp != NULL) { + TODO("what's this?"); + } + + tmp = find_nth(nv->first_child, "PADSTACK", 0); + if (tmp == NULL) { + hkp_error(nv, "Missing VIA PADSTACK, can't place via\n"); \ + return; + } + hps = parse_pstk(ctx, tmp->argv[1]); + if (hps == NULL) { + hkp_error(nv, "Unknown VIA PADSTACK '%s', can't place via\n", tmp->argv[1]); + return; + } + + pid = pcb_pstk_proto_insert_dup(ctx->pcb->Data, &hps->proto, 1, 0); + ps = pcb_pstk_alloc(ctx->pcb->Data); + ps->Flags = DEFAULT_OBJ_FLAG; + ps->x = vx; + ps->y = vy; + ps->proto = pid; + pcb_pstk_add(ctx->pcb->Data, ps); + set_pstk_clearance(ctx, nc, ps, nv); +} + + +/* Returns number of objects drawn: 0 or 1 */ +static int parse_dwg(hkp_ctx_t *ctx, pcb_subc_t *subc, pcb_layer_t *ly, const hkp_netclass_t *nc, node_t *n) +{ + if ((strcmp(n->argv[0], "POLYLINE_PATH") == 0) || (strcmp(n->argv[0], "POLYLINE_SHAPE") == 0)) + parse_dwg_path_polyline(ctx, subc, ly, nc, n, n->argv[0][9] == 'S'); + if ((strcmp(n->argv[0], "POLYARC_PATH") == 0) || (strcmp(n->argv[0], "POLYARC_SHAPE") == 0)) + parse_dwg_path_polyarc(ctx, subc, ly, nc, n, n->argv[0][8] == 'S'); + else if ((strcmp(n->argv[0], "RECT_PATH") == 0) || (strcmp(n->argv[0], "RECT_SHAPE") == 0)) + parse_dwg_rect(ctx, subc, ly, nc, n, n->argv[0][5] == 'S'); + else if ((strcmp(n->argv[0], "TEXT") == 0) && (subc == NULL)) + parse_dwg_text(ctx, subc, ly, nc, n, 0, 0); + else + return 0; + + return 1; +} + +/* Returns number of objects drawn: 0 or more */ +static long parse_dwg_all(hkp_ctx_t *ctx, pcb_subc_t *subc, pcb_layer_t *ly, const hkp_netclass_t *nc, node_t *nd) +{ + node_t *n; + long cnt = 0; + + for(n = nd->first_child; n != NULL; n = n->next) + cnt += parse_dwg(ctx, subc, ly, nc, n); + + return cnt; +} + +/* Return 1 on success, 0 on fail + Return the side of "side", and set lyname to lyname_top or lyname_bottom depending on side + For a subcircuit, the side is given by MNT_SIDE argument */ +static int parse_side(node_t *n, pcb_subc_t *subc, pcb_layer_type_t *side, const char *lyname, const char *lyname_top, const char *lyname_bottom) +{ + node_t *tmp; + pcb_layer_type_t subc_side = 0; + int on_bottom=-1; + + if (n == NULL) + return 0; + + if (subc != NULL) { + if (pcb_subc_get_side(subc, &on_bottom) == -1) { + hkp_error(n, "Error getting subc side\n"); + } + else { + if (on_bottom == 1) + subc_side = PCB_LYT_BOTTOM; + else + subc_side = PCB_LYT_TOP; + } + } + + /* In some sections, like ..ASSEMBLY_OUTLINE inside .PACKAGE_CELL (a subcircuit), there is no explicit SIDE line. + So if this is a subcircuit, and there is no SIDE line, get the side from subc side.*/ + tmp = find_nth(n->first_child, "SIDE", 0); + if (tmp == NULL) { + if (subc != NULL) { + *side = subc_side; + if ((subc_side & PCB_LYT_TOP) != 0) + lyname = lyname_top; + else + lyname = lyname_bottom; + return 1; + } + else + return 0; + } + + if (strcmp(tmp->argv[1], "MNT_SIDE") == 0) { + if (subc_side != 0) { + *side = subc_side; + if ((subc_side & PCB_LYT_TOP) != 0) + lyname = lyname_top; + else + lyname = lyname_bottom; + return 1; + } + else + hkp_error(n, "Unknown MNT_SIDE while parsing package.\n"); + } + if (strcmp(tmp->argv[1], "OPP_SIDE") == 0) { + if (subc_side != 0) { + *side = (subc_side ^ PCB_LYT_TOP) ^ PCB_LYT_BOTTOM; + if ((subc_side & PCB_LYT_TOP) != 0) + lyname = lyname_bottom; + else + lyname = lyname_top; + return 1; + } + else + hkp_error(tmp, "Unknown MNT_SIDE while parsing package.\n"); + } + else if (strcmp(tmp->argv[1], "TOP") == 0) { + *side = PCB_LYT_TOP; + lyname = lyname_top; + return 1; + } + else if (strcmp(tmp->argv[1], "BOTTOM") == 0) { + *side = PCB_LYT_BOTTOM; + lyname = lyname_bottom; + return 1; + } + + hkp_error(n, "Unknown SIDE argument\n"); + return 0; +} + +/* Returns number of objects drawn: 0 or more for valid layers, -1 for invalid layer */ +static long parse_dwg_layer(hkp_ctx_t *ctx, pcb_subc_t *subc, const hkp_netclass_t *nc, node_t *n) +{ + pcb_layer_type_t type = 0; + pcb_layer_type_t side = PCB_LYT_TOP, subc_side = 0; + pcb_layer_combining_t lyc = 0; + const char *lyname = NULL, *purpose = NULL; + pcb_layer_t *ly; + + if (strcmp(n->argv[0], "SILKSCREEN_OUTLINE") == 0) { + type = PCB_LYT_SILK; + lyc = PCB_LYC_AUTO; + if (parse_side(n, subc, &side, lyname, "top-silk", "bot-silk") != 1) + hkp_error(n, "Error parsing silkscreen side.\n"); + } + else if (strcmp(n->argv[0], "SOLDER_MASK") == 0) { + type = PCB_LYT_MASK; + lyc = PCB_LYC_AUTO; + if (parse_side(n, subc, &side, lyname, "top-mask", "bot-mask") != 1) + hkp_error(n, "Error parsing solder mask side.\n"); + } + else if (strcmp(n->argv[0], "SOLDER_PASTE") == 0) { + type = PCB_LYT_PASTE; + lyc = PCB_LYC_AUTO; + if (parse_side(n, subc, &side, lyname, "top-paste", "bot-paste") != 1) + hkp_error(n, "Error parsing paste side.\n"); + } + else if (strcmp(n->argv[0], "ASSEMBLY_OUTLINE") == 0) { + type = PCB_LYT_DOC; + lyc = PCB_LYC_AUTO; + if (parse_side(n, subc, &side, lyname, "top-assy", "bot-assy") != 1) + hkp_error(n, "Error parsing assembly outline.\n"); + } + else if (strcmp(n->argv[0], "ROUTE_OUTLINE") == 0) { + type = PCB_LYT_BOUNDARY; + side = 0; /* global */ + lyname = "outline"; + purpose = "uroute"; + } + else + return -1; + + if (subc == NULL) { + rnd_layer_id_t lid; + if (purpose == NULL) { + if (pcb_layer_list(ctx->pcb, side | type, &lid, 1) != 1) + return 0; + } + else { + if (pcb_layer_listp(ctx->pcb, side | type, &lid, 1, -1, purpose) != 1) + return 0; + } + ly = &ctx->pcb->Data->Layer[lid]; + } + else + ly = pcb_subc_get_layer(subc, side | type, lyc, 1, lyname, 0); + return parse_dwg_all(ctx, subc, ly, nc, n); +} + +static pcb_layer_t *parse_layer(hkp_ctx_t *ctx, pcb_subc_t *subc, const char *ln, int user, node_t *err_node) +{ + pcb_layer_t *ly; + pcb_layer_type_t lyt = 0; + pcb_layer_combining_t lyc = 0; + char *purpose = NULL; + char *name = NULL; + + if (user) { /* user layers are DOC layers identified by name and are allocated on the go */ + rnd_layer_id_t lid; + pcb_dflgmap_t map[2]; + int retry; + +TODO("this should be done only when subc == NULL"); + + for(retry = 0; retry < 2; retry++) { + lid = pcb_layer_by_name(ctx->pcb->Data, ln); + if (lid >= 0) + return &ctx->pcb->Data->Layer[lid]; + + memset(map, 0, sizeof(map)); + map[0].name = ln; + map[0].lyt = PCB_LYT_DOC; + map[0].flags = PCB_DFLGMAP_FORCE_END; + pcb_layergrp_create_by_map(ctx->pcb, map); + } + return NULL; + } + + if (strncmp(ln, "LYR_", 4) == 0) { + int cidx; + char *end; + rnd_layergrp_id_t gid; + + TODO("can a subcircuit have intern copper objects? assume NO for now:"); + assert(subc == NULL); + cidx = strtol(ln+4, &end, 10); + if (*end != '\0') { + hkp_error(err_node, "Unknown layer '%s' (expected integer after LYR_)\n", ln); + return NULL; + } + cidx--; /* hkp numbers from 1, we number from 0 */ + if ((cidx < 0) || (cidx >= ctx->num_cop_layers)) { + hkp_error(err_node, "Layer '%s' is out of range (1..%d)\n", ln, ctx->num_cop_layers); + return NULL; + } + gid = pcb_layergrp_step(ctx->pcb, pcb_layergrp_get_top_copper(), cidx, PCB_LYT_COPPER); + if (gid < 0) { + hkp_error(err_node, "Layer '%s' is out of range (copper layer group not found)\n", ln); + return NULL; + } + assert(ctx->pcb->LayerGroups.grp[gid].len > 0); + return &ctx->pcb->Data->Layer[ctx->pcb->LayerGroups.grp[gid].lid[0]]; + } + else if (strcmp(ln, "SILKSCREEN_TOP") == 0) { + lyt = PCB_LYT_TOP | PCB_LYT_SILK; + lyc = PCB_LYC_AUTO; + name = "silk-top"; + } + else if (strcmp(ln, "SILKSCREEN_BOTTOM") == 0) { + lyt = PCB_LYT_BOTTOM | PCB_LYT_SILK; + lyc = PCB_LYC_AUTO; + name = "silk-bot"; + } + else if (strcmp(ln, "SOLDERMASK_TOP") == 0) { + lyt = PCB_LYT_TOP | PCB_LYT_MASK; + lyc = PCB_LYC_AUTO; + } + else if (strcmp(ln, "SOLDERMASK_BOTTOM") == 0) { + lyt = PCB_LYT_BOTTOM | PCB_LYT_MASK; + lyc = PCB_LYC_AUTO; + } + else if (strcmp(ln, "ASSEMBLY_TOP") == 0) { + lyt = PCB_LYT_TOP | PCB_LYT_DOC; + lyc = PCB_LYC_AUTO; + purpose = "assy"; + name = "top-assy"; + } + else if (strcmp(ln, "ASSEMBLY_BOTTOM") == 0) { + lyt = PCB_LYT_BOTTOM | PCB_LYT_DOC; + lyc = PCB_LYC_AUTO; + purpose = "assy"; + name = "bot-assy"; + } + else if (strncmp(ln, "DRILLDRAWING_", 13) == 0) { + lyt = PCB_LYT_TOP | PCB_LYT_DOC; + lyc = PCB_LYC_AUTO; + purpose = "fab"; + name = "top-fab"; + } + else { + hkp_error(err_node, "Unknown layer '%s'\n", ln); + return NULL; + } + + if (subc != NULL) { + ly = pcb_subc_get_layer(subc, lyt, lyc, 1, name, (purpose != NULL)); + if ((purpose != NULL) && (ly->meta.bound.purpose == NULL)) /* newly created bound layer */ + ly->meta.bound.purpose = rnd_strdup(purpose); + } + else { + rnd_layer_id_t lid; + int ln = pcb_layer_listp(ctx->pcb, lyt, &lid, 1, -1, purpose); + if (ln == 0) + return NULL; + return pcb_get_layer(ctx->pcb->Data, lid); + } + return ly; +} + +static void parse_subc_text(hkp_ctx_t *ctx, pcb_subc_t *subc, const hkp_netclass_t *nc, node_t *textnode) +{ + node_t *tt; + const char *text_str; + pcb_flag_values_t flg = PCB_FLAG_FLOATER; + int omit_on_silk = 0; + + tt = find_nth(textnode->first_child, "TEXT_TYPE", 0); + if (tt == NULL) + return; + + text_str = textnode->argv[1]; + if (strcmp(tt->argv[1], "REF_DES") == 0) { + pcb_attribute_put(&subc->Attributes, "refdes", textnode->argv[1]); + text_str = "%a.parent.refdes%"; + flg |= PCB_FLAG_DYNTEXT; + } + else if (strcmp(tt->argv[1], "PARTNO") == 0) { + pcb_attribute_put(&subc->Attributes, "footprint", textnode->argv[1]); + text_str = "%a.parent.footprint%"; + flg |= PCB_FLAG_DYNTEXT; + omit_on_silk = 1; + } + + parse_dwg_text(ctx, subc, NULL, nc, textnode, omit_on_silk, flg); +} + + +static pcb_subc_t *parse_package(hkp_ctx_t *ctx, pcb_data_t *dt, node_t *nd) +{ + pcb_subc_t *subc; + node_t *n; + rnd_coord_t ox, oy; + double rot = 0; + int on_bottom = 0, seen_oxy = 0; + const hkp_netclass_t *nc = NULL; + + subc = pcb_subc_alloc(); + + /* extract global */ + for(n = nd->first_child; n != NULL; n = n->next) { + if (strcmp(n->argv[0], "DESCRIPTION") == 0) { + pcb_attribute_put(&subc->Attributes, "description", n->argv[1]); + } + else if (strcmp(n->argv[0], "XY") == 0) { + if ((parse_x(ctx, n->argv[1], &ox) != 0) || (parse_y(ctx, n->argv[2], &oy) != 0)) { + hkp_error(n, "Can't load package: broken placement XY coord\n"); + return NULL; + } + seen_oxy = 1; + } + else if (strcmp(n->argv[0], "ROTATION") == 0) { + if (parse_rot(ctx, n, &rot, on_bottom) != 0) { + hkp_error(n, "Can't load package due to wrong rotation value\n"); + return NULL; + } + } + else if (strcmp(n->argv[0], "FACEMENT") == 0) { + if (strcmp(n->argv[1], "TOP") == 0) on_bottom = 0; + else if (strcmp(n->argv[1], "BOTTOM") == 0) on_bottom = 1; + else { + hkp_error(n, "Can't load package: broken facement (should be TOP or BOTTOM)\n"); + return NULL; + } + } + else if (strcmp(n->argv[0], "TEXT") == 0) + parse_subc_text(ctx, subc, nc, n); + } + + if (!seen_oxy) { + pcb_subc_free(subc); + hkp_error(nd, "Can't load package: no placement XY coord\n"); + return NULL; + } + + if (dt != NULL) { + pcb_subc_reg(dt, subc); + pcb_obj_id_reg(dt, subc); + + /* bind the via rtree so that vias added in this subc show up on the board */ + if (ctx->pcb != NULL) + pcb_subc_bind_globals(ctx->pcb, subc); + } + + pcb_subc_create_aux(subc, ox, oy, rot, on_bottom); + + /* extract pins and silk lines */ + for(n = nd->first_child; n != NULL; n = n->next) { + if (strcmp(n->argv[0], "PIN") == 0) + parse_pin(ctx, subc, nc, n, on_bottom); + else + parse_dwg_layer(ctx, subc, nc, n); + } + +#if 0 + /* extract tags */ + for(n = nd->first_child; n != NULL; n = n->next) { + for(t = tagnames; *t != NULL; t++) { + if (strcmp(n->argv[0], *t) == 0) { +/* printf("TAG %s=%s\n", *t, n->argv[1]); */ + } + } + } +#endif + + + pcb_subc_bbox(subc); + if ((dt != NULL) && (ctx->pcb != NULL)) { + + if (dt->subc_tree == NULL) + dt->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(dt->subc_tree, (rnd_box_t *)subc); + + pcb_subc_rebind(ctx->pcb, subc); + } + return subc; +} + +static void parse_net(hkp_ctx_t *ctx, node_t *netroot) +{ + node_t *n, *lyn; + pcb_layer_t *ly; + const char *netname = netroot->argv[1]; +TODO("netclass: fill this in:") + const hkp_netclass_t *nc = NULL; + + if (strcmp(netname, "Unconnected_Net") != 0) + pcb_net_get(ctx->pcb, &ctx->pcb->netlist[PCB_NETLIST_INPUT], netname, PCB_NETA_ALLOC); + + for(n = netroot->first_child; n != NULL; n = n->next) { + if ((strcmp(n->argv[0], "TRACE") == 0) || (strcmp(n->argv[0], "CONDUCTIVE_AREA") == 0)) { + lyn = find_nth(n->first_child, "ROUTE_LYR", 0); + if (lyn == NULL) + continue; + ly = parse_layer(ctx, NULL, lyn->argv[1], 0, lyn); + if (ly == NULL) { + hkp_error(lyn, "Unknown trace layer '%s'\n", lyn->argv[1]); + continue; + } + parse_dwg_all(ctx, NULL, ly, nc, n); + } + else if (strcmp(n->argv[0], "VIA") == 0) + parse_dgw_via(ctx, nc, n); + } +} + +static const rnd_unit_t *parse_units(const char *ust) +{ + if (strcmp(ust, "MIL") == 0) return rnd_get_unit_struct("mil"); + if (strcmp(ust, "TH") == 0) return rnd_get_unit_struct("mil"); + if (strcmp(ust, "MM") == 0) return rnd_get_unit_struct("mm"); + if (strcmp(ust, "IN") == 0) return rnd_get_unit_struct("inch"); + return NULL; +} + +static int parse_layout_globals(hkp_ctx_t *ctx, hkp_tree_t *tree) +{ + node_t *n; + char *end; + + ctx->num_cop_layers = -1; + + /* extract globals */ + for(n = tree->root->first_child; n != NULL; n = n->next) { + if (strcmp(n->argv[0], "NUMBER_OF_LAYERS") == 0) { + ctx->num_cop_layers = strtol(n->argv[1], &end, 10); + if (*end != '\0') + return hkp_error(n, "Invalid number of layers '%s' (expected integer)\n", n->argv[1]); + if ((ctx->num_cop_layers < 1) || (ctx->num_cop_layers > ((PCB_MAX_LAYER/2)-8))) + return hkp_error(n, "Invalid number of layers '%s' (out of range)\n", n->argv[1]); + } + else if (strcmp(n->argv[0], "UNITS") == 0) { + ctx->unit = parse_units(n->argv[1]); + if (ctx->unit == NULL) + return hkp_error(n, "Unknown unit '%s'\n", n->argv[1]); + } + } + + if (ctx->num_cop_layers < 0) + return hkp_error(tree->root, "Missing NUMBER_OF_LAYERS\n"); + + { /* create the layer stack: copper layers, as many as required by the header */ + int len = 0, n; + pcb_dflgmap_t map[PCB_MAX_LAYERGRP]; + const pcb_dflgmap_t *m; + + while(ctx->pcb->LayerGroups.len > 0) + pcb_layergrp_del(ctx->pcb, 0, 1, 0); + + for(m = pcb_dflg_top_noncop; m->name != NULL; m++) map[len++] = *m; + + map[len++] = pcb_dflg_top_copper; + map[len++] = pcb_dflg_substrate; + for(n = 0; n < (ctx->num_cop_layers-2); n++) { + map[len++] = pcb_dflg_int_copper; + map[len++] = pcb_dflg_substrate; + } + map[len++] = pcb_dflg_bot_copper; + + for(m = pcb_dflg_bot_noncop; m->name != NULL; m++) map[len++] = *m; + for(m = pcb_dflg_glob_noncop; m->name != NULL; m++) map[len++] = *m; + + map[len].name = NULL; /* terminator */ + pcb_layergrp_create_by_map(ctx->pcb, map); + } + + /* plus assy and fab layers */ + pcb_layergrp_upgrade_by_map(ctx->pcb, pcb_dflgmap_doc); + + return 0; +} + +static int parse_layout_root(hkp_ctx_t *ctx, hkp_tree_t *tree) +{ + node_t *n; + const hkp_netclass_t *nc = NULL; + + /* build packages and draw objects */ + for(n = tree->root->first_child; n != NULL; n = n->next) { + if (strcmp(n->argv[0], "PACKAGE_CELL") == 0) + parse_package(ctx, ctx->pcb->Data, n); + if (strcmp(n->argv[0], "NET") == 0) { + parse_net(ctx, n); +TODO("netclass: set nc for net's netclass"); + } + if (strcmp(n->argv[0], "GRAPHIC") == 0) { + pcb_layer_t *ly; + node_t *lyn; + + lyn = find_nth(n->first_child, "USER_LYR", 0); + if (lyn == NULL) + continue; + ly = parse_layer(ctx, NULL, lyn->argv[1], 1, lyn); + if (ly == NULL) { + hkp_error(lyn, "Unknown graphic layer '%s'\n", lyn->argv[1]); + continue; + } + parse_dwg_all(ctx, NULL, ly, nc, n); + } + else { /* global drawing objects in layers or outside of layers */ + parse_dwg(ctx, NULL, NULL, nc, n); + parse_dwg_layer(ctx, NULL, nc, n); + } + + } + + /* 'autocrop' the board for now (required by y mirror and unknown extents) */ + { + rnd_box_t bb; + pcb_data_normalize(ctx->pcb->Data); + pcb_data_bbox(&bb, ctx->pcb->Data, 0); + ctx->pcb->hidlib.size_x = bb.X2; + ctx->pcb->hidlib.size_y = bb.Y2; + } + + return 0; +} + + +/*** Low level parser ***/ + +static void dump(node_t *nd) +{ + int n; + for(n = 0; n < nd->level; n++) + printf(" "); + if (nd->argc > 0) { + printf("%s", nd->argv[0]); + for(n = 1; n < nd->argc; n++) + printf("|%s", nd->argv[n]); + } + else + printf(""); + printf("\n"); + for(nd = nd->first_child; nd != NULL; nd = nd->next) + dump(nd); +} + +static void node_destroy(node_t *nd) +{ + node_t *n, *next; + + if (nd == NULL) + return; + + qparse_free(nd->argc, &nd->argv); + + for(n = nd->first_child; n != NULL; n = next) { + next = n->next; + node_destroy(n); + } + + free(nd); +} + +static void tree_destroy(hkp_tree_t *tree) +{ + node_destroy(tree->root); + free(tree->filename); + tree->root = NULL; + tree->filename = NULL; +} + +/* Split up a virtual line and save it in the tree */ +void save_vline(hkp_tree_t *tree, char *vline, int level, long lineno) +{ + node_t *nd; + + nd = calloc(sizeof(node_t), 1); + nd->argc = qparse2(vline, &nd->argv, QPARSE_DOUBLE_QUOTE | QPARSE_PAREN | QPARSE_MULTISEP); + nd->level = level; + nd->lineno = lineno; + nd->tree = tree; + + if (level == tree->curr->level) { /* sibling */ + sibling:; + nd->parent = tree->curr->parent; + tree->curr->next = nd; + nd->parent->last_child = nd; + } + else if (level == tree->curr->level+1) { /* first child */ + tree->curr->first_child = tree->curr->last_child = nd; + nd->parent = tree->curr; + } + else if (level < tree->curr->level) { /* step back to a previous level */ + while(level < tree->curr->level) tree->curr = tree->curr->parent; + goto sibling; + } + tree->curr = nd; +} + +static void rtrim(gds_t *s) +{ + int n; + for(n = gds_len(s)-1; (n >= 0) && isspace(s->array[n]); n--) + s->array[n] = '\0'; +} + +static void load_hkp(hkp_tree_t *tree, FILE *f, const char *fn) +{ + char *s, line[1024]; + gds_t vline; + int level; + long lineno = 0; + + tree->filename = rnd_strdup(fn); + tree->curr = tree->root = calloc(sizeof(node_t), 1); + gds_init(&vline); + + /* read physical lines, build virtual lines and save them in the tree*/ + while(fgets(line, sizeof(line), f) != NULL) { + s = line; + if (*s == '!') s++; /* header line prefix? */ + while(isspace(*s)) s++; + + /* first char is '.' means it's a new virtual line */ + if (*s == '.') { + if (gds_len(&vline) > 0) { + rtrim(&vline); + save_vline(tree, vline.array, level, lineno); + gds_truncate(&vline, 0); + } + level = 0; + while(*s == '.') { s++; level++; }; + } + + if (gds_len(&vline) > 0) + gds_append(&vline, ' '); + gds_append_str(&vline, s); + lineno++; + } + + /* the last virtual line before eof */ + if (gds_len(&vline) > 0) { + rtrim(&vline); + save_vline(tree, vline.array, level, lineno); + } + gds_uninit(&vline); + +} + +#include "read_net.c" +#include "read_pstk.c" + +int io_mentor_cell_read_pcb(pcb_plug_io_t *pctx, pcb_board_t *pcb, const char *fn, rnd_conf_role_t settings_dest) +{ + hkp_ctx_t ctx; + int res = -1; + FILE *flay; + char *end, fn2[RND_PATH_MAX]; + + pcb_data_clip_inhibit_inc(pcb->Data); + pcb_layergrp_inhibit_inc(); + + memset(&ctx, 0, sizeof(ctx)); + + flay = rnd_fopen(&pcb->hidlib, fn, "r"); + if (flay == NULL) { + rnd_message(RND_MSG_ERROR, "can't open layout hkp '%s' for read\n", fn); + goto err; + } + + /* create the file name for the padstacks */ + strncpy(fn2, fn, RND_PATH_MAX); + fn2[RND_PATH_MAX-1] = '\0'; + end = strrchr(fn2, RND_DIR_SEPARATOR_C); + if (end == NULL) + end = fn2; + else + end++; + strcpy(end, "Padstack.hkp"); + + if (io_mentor_cell_pstks(&ctx, fn2) != 0) { + fclose(flay); + goto err; + } + + ctx.pcb = pcb; + ctx.unit = rnd_get_unit_struct("mm"); + + + + load_hkp(&ctx.layout, flay, fn); + fclose(flay); + + /* we are loading the cells into a board, make a default layer stack for that */ + pcb_layergrp_inhibit_inc(); + pcb_layers_reset(pcb); + pcb_layer_group_setup_default(pcb); + pcb_layer_group_setup_silks(pcb); + pcb_layer_auto_fixup(pcb); + pcb_layergrp_inhibit_dec(); + + /* parse the stackup and some global settings first, since netclass depends on this */ + parse_layout_globals(&ctx, &ctx.layout); + + strcpy(end, "NetClass.hkp"); + if (io_mentor_cell_netclass(&ctx, fn2) != 0) { + fclose(flay); + goto err; + } + + strcpy(end, "NetProps.hkp"); + if (io_mentor_cell_netlist(&ctx, fn2) != 0) { + fclose(flay); + goto err; + } + + /* parse the root */ + res = parse_layout_root(&ctx, &ctx.layout); + + pcb_layer_colors_from_conf(pcb, 1); + + res = 0; /* all ok */ + + err:; + free_pstks(&ctx); + if (res != 0) { + if (ctx.layout.root != NULL) { + printf("### layout tree:\n"); + dump(ctx.layout.root); + } + if (ctx.padstacks.root != NULL) { + printf("### padstack tree:\n"); + dump(ctx.padstacks.root); + } + } + tree_destroy(&ctx.padstacks); + tree_destroy(&ctx.layout); + + pcb_layergrp_inhibit_dec(); + pcb_data_clip_inhibit_dec(pcb->Data, 1); + + return res; +} + +int io_mentor_cell_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f) +{ + char line[1024], *s; + + while(!(feof(f))) { + if (fgets(line, sizeof(line), f) != NULL) { + s = line; + while(isspace(*s)) s++; /* strip leading whitespace */ + if (strncmp(s, ".FILETYPE LAYOUT", 16) == 0) /* valid root */ + return 1; + if ((*s == '\r') || (*s == '\n') || (*s == '\0')) /* ignore empty lines and comments */ + continue; + /* non-comment, non-empty line - and we don't have our root -> it's not an s-expression */ + return 0; + } + } + + /* hit eof before seeing a valid root -> bad */ + return 0; +} Index: tags/2.3.0/src_plugins/io_mentor_cell/read.h =================================================================== --- tags/2.3.0/src_plugins/io_mentor_cell/read.h (nonexistent) +++ tags/2.3.0/src_plugins/io_mentor_cell/read.h (revision 33253) @@ -0,0 +1,2 @@ +int io_mentor_cell_read_pcb(pcb_plug_io_t *ctx, pcb_board_t *pcb, const char *fn, rnd_conf_role_t settings_dest); +int io_mentor_cell_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); Index: tags/2.3.0/src_plugins/io_mentor_cell/read_net.c =================================================================== --- tags/2.3.0/src_plugins/io_mentor_cell/read_net.c (nonexistent) +++ tags/2.3.0/src_plugins/io_mentor_cell/read_net.c (revision 33253) @@ -0,0 +1,177 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,2019 Tibor 'Igor2' Palinkas + * + * This module, io_mentor_cell, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + + +static rnd_coord_t net_get_clearance_(hkp_ctx_t *ctx, rnd_layer_id_t lid, const hkp_netclass_t *nc, hkp_clearance_type_t type, node_t *errnode) +{ + if ((lid < 0) || (lid >= PCB_MAX_LAYER)) { + hkp_error(errnode, "failed to determine clearance, falling back to default value\n"); + return RND_MIL_TO_COORD(12); + } + return ctx->nc_dflt.clearance[lid][type]; +} + +static rnd_coord_t net_get_clearance(hkp_ctx_t *ctx, pcb_layer_t *ly, const hkp_netclass_t *nc, hkp_clearance_type_t type, node_t *errnode) +{ + rnd_layer_id_t lid; + + if (ly == NULL) /* typically non-copper layer: clearance is 0 */ + return 0; + + ly = pcb_layer_get_real(ly); + if (ly == NULL) + return 0; + lid = ly - ctx->pcb->Data->Layer; + return net_get_clearance_(ctx, lid, nc, type, errnode); +} + + +static int io_mentor_cell_netclass(hkp_ctx_t *ctx, const char *fn) +{ + FILE *fnc; + node_t *n, *ncl, *nsch, *ns, *nln, *ndefault = NULL, *ncrs = NULL; + hkp_tree_t nc_tree; /* no need to keep the tree in ctx, no data is needed after the function returns */ + + fnc = rnd_fopen(&ctx->pcb->hidlib, fn, "r"); + if (fnc == NULL) { + rnd_message(RND_MSG_ERROR, "can't open netclass hkp '%s' for read\n", fn); + return -1; + } + + load_hkp(&nc_tree, fnc, fn); + fclose(fnc); + + /* find the default NET_CLASS_SCHEME */ + for(nsch = nc_tree.root->first_child; nsch != NULL; nsch = nsch->next) { + if (strcmp(nsch->argv[0], "NET_CLASS_SCHEME") == 0) { + if (ndefault == NULL) + ndefault = nsch; + else if (strcmp(nsch->argv[1], "(Master)") == 0) + ndefault = nsch; + } + } + + /* load default NET_CLASS_SCHEME's children */ + if (ndefault != NULL) { + for(ncl = ndefault->first_child; ncl != NULL; ncl = ncl->next) { + if (strcmp(ncl->argv[0], "CLEARANCE_RULE_SET") == 0) { + if (ncrs == NULL) + ncrs = ncl; + else if (strcmp(ncl->argv[1], "(Default Rule)") == 0) + ncrs = ncl; + } + } + } + + if (ncrs == NULL) { + tree_destroy(&nc_tree); + rnd_message(RND_MSG_ERROR, "netclass hkp '%s' does not contain any NET_CLASS_SCHEME/CLEARANCE_RULE_SET section\n", fn); + return -1; + } + + /* load default CLEARANCE_RULE_SET's children */ + for(ns = ncrs->first_child; ns != NULL; ns = ns->next) { + rnd_layergrp_id_t gid; + pcb_layergrp_t *grp; + rnd_coord_t val; + int i; + + if (strcmp(ns->argv[0], "SUBRULE") != 0) continue; + + nln = find_nth(ns->first_child, "LAYER_NUM", 0); + if (nln == NULL) continue; /* layer number is required */ + + /* layer number is in copper offset, translate it to layer ID */ + gid = pcb_layergrp_step(ctx->pcb, pcb_layergrp_get_top_copper(), atoi(nln->argv[1])-1, PCB_LYT_COPPER); + grp = pcb_get_layergrp(ctx->pcb, gid); + if ((grp == NULL) || (grp->len < 1)) continue; + + for(n = ns->first_child; n != NULL; n = n->next) { + hkp_clearance_type_t type; + + if (parse_coord(ctx, n->argv[1], &val) != 0) { + hkp_error(n, "Ignoring invalid clearance value '%s'\n", n->argv[1]); + continue; + } + + if (strcmp(n->argv[0], "PLANE_TO_TRACE") == 0) type = HKP_CLR_POLY2TRACE; + else if (strcmp(n->argv[0], "PLANE_TO_PAD") == 0) type = HKP_CLR_POLY2TERM; + else if (strcmp(n->argv[0], "PLANE_TO_VIA") == 0) type = HKP_CLR_POLY2VIA; + else if (strcmp(n->argv[0], "PLANE_TO_PLANE") == 0) type = HKP_CLR_POLY2POLY; + else continue; /* ignore the rest for now */ + + for(i = 0; i < grp->len; i++) { + rnd_layer_id_t lid = grp->lid[i]; + ctx->nc_dflt.clearance[lid][type] = val; + } + } + } + + return 0; +} + +static int io_mentor_cell_netlist(hkp_ctx_t *ctx, const char *fn) +{ + FILE *fnet; + node_t *p, *nnet, *pinsect; + hkp_tree_t net_tree; /* no need to keep the tree in ctx, no data is needed after the function returns */ + + fnet = rnd_fopen(&ctx->pcb->hidlib, fn, "r"); + if (fnet == NULL) { + rnd_message(RND_MSG_ERROR, "can't open netprops hkp '%s' for read\n", fn); + return -1; + } + + load_hkp(&net_tree, fnet, fn); + fclose(fnet); + + for(nnet = net_tree.root->first_child; nnet != NULL; nnet = nnet->next) { + if (strcmp(nnet->argv[0], "NETNAME") == 0) { + pcb_net_t *net = pcb_net_get(ctx->pcb, &ctx->pcb->netlist[PCB_NETLIST_INPUT], nnet->argv[1], PCB_NETA_ALLOC); + if (net == NULL) { + hkp_error(nnet, "Failed to create net '%s' - netlist will be incomplete\n", nnet->argv[1]); + continue; + } + pinsect = find_nth(nnet->first_child, "PIN_SECTION", 0); + if (pinsect == NULL) + continue; + for(p = pinsect->first_child; p != NULL; p = p->next) { + pcb_net_term_t *term; + if (strcmp(p->argv[0], "REF_PINNAME") != 0) + continue; + term = pcb_net_term_get_by_pinname(net, p->argv[1], PCB_NETA_ALLOC); + if (term == NULL) + hkp_error(p, "Failed to create pin '%s' in net '%s' - netlist will be incomplete\n", p->argv[1], nnet->argv[1]); + } + } + } + + tree_destroy(&net_tree); + return 0; +} Index: tags/2.3.0/src_plugins/io_mentor_cell/read_pstk.c =================================================================== --- tags/2.3.0/src_plugins/io_mentor_cell/read_pstk.c (nonexistent) +++ tags/2.3.0/src_plugins/io_mentor_cell/read_pstk.c (revision 33253) @@ -0,0 +1,474 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,2019 Tibor 'Igor2' Palinkas + * + * This module, io_mentor_cell, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +static int parse_dia(hkp_ctx_t *ctx, node_t *roundn, rnd_coord_t *dia) +{ + node_t *hr = roundn->first_child; + if ((hr == NULL) || (strcmp(hr->argv[0], "DIAMETER") != 0)) + return hkp_error(hr, "Expected DIAMETER as first child of ROUND\n"); + if (parse_coord(ctx, hr->argv[1], dia) != 0) + return hkp_error(hr, "Invalid ROUND DIAMETER value '%s'\n", hr->argv[1]); + return 0; +} + + +static hkp_hole_t *parse_hole(hkp_ctx_t *ctx, const char *name) +{ + const rnd_unit_t *old_unit; + node_t *hr, *ho; + hkp_hole_t *h = htsp_get(&ctx->holes, name); + + if (h == NULL) + return NULL; + if (h->valid) + return h; + + old_unit = ctx->unit; + ctx->unit = h->unit; + + ho = find_nth(h->subtree->first_child, "HOLE_OPTIONS", 0); + if (ho != NULL) { + int n; + for(n = 1; n < ho->argc; n++) + if (strcmp(ho->argv[n], "PLATED") == 0) + h->plated = 1; + } + + hr = find_nth(h->subtree->first_child, "ROUND", 0); + if (hr != NULL) { + if (parse_dia(ctx, hr, &h->dia) != 0) + goto error; + } + else { + hr = find_nth(h->subtree->first_child, "SLOT", 0); + if (hr != NULL) { + node_t *tmp; + tmp = find_nth(hr->first_child, "WIDTH", 0); + if (parse_coord(ctx, tmp->argv[1], &h->w) != 0) { + hkp_error(tmp, "Invalid SLOT WIDTH value '%s'\n", tmp->argv[1]); + return NULL; + } + tmp = find_nth(hr->first_child, "HEIGHT", 0); + if (parse_coord(ctx, tmp->argv[1], &h->h) != 0) { + hkp_error(tmp, "Invalid SLOT HEIGHT value '%s'\n", tmp->argv[1]); + return NULL; + } + } + } + + + h->valid = 1; + ctx->unit = old_unit; + return h; + + error:; + ctx->unit = old_unit; + return NULL; +} + +#define SHAPE_CHECK_DUP \ +do { \ + if (has_shape) { \ + hkp_error(n, "PAD with multiple shapes\n"); \ + goto error; \ + } \ + has_shape = 1; \ +} while(0) +static hkp_shape_t *parse_shape(hkp_ctx_t *ctx, const char *name) +{ + const rnd_unit_t *old_unit; + node_t *n, *on, *tmp; + rnd_coord_t ox = 0, oy = 0; + hkp_shape_t *s = htsp_get(&ctx->shapes, name); + int has_shape = 0; + + if (s == NULL) + return NULL; + if (s->valid) + return s; + + old_unit = ctx->unit; + ctx->unit = s->unit; + + on = find_nth(s->subtree->first_child, "OFFSET", 0); + if (on != NULL) + parse_xy(ctx, on->argv[1], &ox, &oy, 0); + ox = -ox; + + memset(&s->shp, 0, sizeof(pcb_pstk_shape_t)); + + for(n = s->subtree->first_child; n != NULL; n = n->next) { + if (strcmp(n->argv[0], "ROUND") == 0) { + rnd_coord_t dia; + SHAPE_CHECK_DUP; + if (parse_dia(ctx, n, &dia) != 0) + goto error; + s->shp.shape = PCB_PSSH_CIRC; + s->shp.data.circ.dia = dia; + s->shp.data.circ.x = ox; + s->shp.data.circ.y = oy; + } + else if ((strcmp(n->argv[0], "RECTANGLE") == 0) || (strcmp(n->argv[0], "SQUARE") == 0)) { + rnd_coord_t w, h; + SHAPE_CHECK_DUP; + tmp = find_nth(n->first_child, "WIDTH", 0); + if (parse_coord(ctx, tmp->argv[1], &w) != 0) { + hkp_error(tmp, "Invalid RECTANGLE WIDTH value '%s'\n", tmp->argv[1]); + return NULL; + } + if (*n->argv[0] == 'R') { + tmp = find_nth(n->first_child, "HEIGHT", 0); + if (parse_coord(ctx, tmp->argv[1], &h) != 0) { + hkp_error(tmp, "Invalid RECTANGLE WIDTH value '%s'\n", tmp->argv[1]); + return NULL; + } + } + else + h = w; /* square */ + + s->shp.shape = PCB_PSSH_POLY; + pcb_pstk_shape_alloc_poly(&s->shp.data.poly, 4); + s->shp.data.poly.x[0] = ox - w/2; s->shp.data.poly.y[0] = oy - h/2; + s->shp.data.poly.x[1] = ox - w/2; s->shp.data.poly.y[1] = oy + h/2; + s->shp.data.poly.x[2] = ox + w/2; s->shp.data.poly.y[2] = oy + h/2; + s->shp.data.poly.x[3] = ox + w/2; s->shp.data.poly.y[3] = oy - h/2; + } + else if (strcmp(n->argv[0], "OBLONG") == 0) { + rnd_coord_t w, h; + SHAPE_CHECK_DUP; + tmp = find_nth(n->first_child, "WIDTH", 0); + if (parse_coord(ctx, tmp->argv[1], &w) != 0) { + hkp_error(tmp, "Invalid OBLONG WIDTH value '%s'\n", tmp->argv[1]); + return NULL; + } + tmp = find_nth(n->first_child, "HEIGHT", 0); + if (parse_coord(ctx, tmp->argv[1], &h) != 0) { + hkp_error(tmp, "Invalid OBLONG WIDTH value '%s'\n", tmp->argv[1]); + return NULL; + } + pcb_shape_oval(&(s->shp), w, h); + } + } + + if (!has_shape) { + hkp_error(s->subtree, "PAD without a shape\n"); + return NULL; + } + + s->valid = 1; + ctx->unit = old_unit; + return s; + + error:; + ctx->unit = old_unit; + return NULL; +} +#undef SHAPE_CHECK_DUP + +typedef struct { + const char *name; + pcb_layer_type_t lyt; + pcb_layer_combining_t lyc; +} lyt_name_t; + +lyt_name_t lyt_names[] = { + {"TOP_PAD", PCB_LYT_TOP | PCB_LYT_COPPER, 0 }, + {"BOTTOM_PAD", PCB_LYT_BOTTOM | PCB_LYT_COPPER, 0 }, + {"INTERNAL_PAD", PCB_LYT_INTERN | PCB_LYT_COPPER, 0 }, + {"TOP_SOLDERMASK_PAD", PCB_LYT_TOP | PCB_LYT_MASK, PCB_LYC_AUTO | PCB_LYC_SUB }, + {"BOTTOM_SOLDERMASK_PAD", PCB_LYT_BOTTOM | PCB_LYT_MASK, PCB_LYC_AUTO | PCB_LYC_SUB }, + {"TOP_SOLDERPASTE_PAD", PCB_LYT_TOP | PCB_LYT_PASTE, PCB_LYC_AUTO }, + {"BOTTOM_SOLDERPASTE_PAD", PCB_LYT_BOTTOM | PCB_LYT_PASTE, PCB_LYC_AUTO }, + {NULL, 0} +}; + +static void slot_shape(pcb_pstk_shape_t *shape, rnd_coord_t sx, rnd_coord_t sy) +{ + shape->shape = PCB_PSSH_LINE; + if (sx > sy) { /* horizontal */ + shape->data.line.thickness = sy; + shape->data.line.x1 = (-sx + sy)/2; + shape->data.line.x2 = (+sx - sy)/2; + shape->data.line.y1 = shape->data.line.y2 = 0; + } + else { /* vertical */ + shape->data.line.thickness = sx; + shape->data.line.y1 = (-sy + sx)/2; + shape->data.line.y2 = (+sy - sx)/2; + shape->data.line.x1 = shape->data.line.x2 = 0; + } + shape->layer_mask = PCB_LYT_MECH; + shape->comb = PCB_LYC_AUTO; +} + +static hkp_pstk_t *parse_pstk(hkp_ctx_t *ctx, const char *ps) +{ + const rnd_unit_t *old_unit; + rnd_coord_t ox = 0, oy = 0; + node_t *n, *hn, *on, *tn; + hkp_pstk_t *p = htsp_get(&ctx->pstks, ps); + int top_only = 0; + pcb_pstk_tshape_t *ts; + + if (p == NULL) + return NULL; + if (p->valid) + return p; + + n = find_nth(p->subtree->first_child, "TECHNOLOGY", 0); + if (n == NULL) { + hkp_error(p->subtree, "Padstack without technology\n"); + return NULL; + } + + old_unit = ctx->unit; + ctx->unit = p->unit; + + tn = find_nth(p->subtree->first_child, "PADSTACK_TYPE", 0); + if (tn == NULL) { + hkp_error(p->subtree, "Padstack without PADSTACK_TYPE\n"); + return NULL; + } + if (strcmp(tn->argv[1], "PIN_SMD") == 0) top_only = 1; + else if (strcmp(tn->argv[1], "PIN_THROUGH") == 0) top_only = 0; + else if (strcmp(tn->argv[1], "VIA") == 0) top_only = 0; + else { + hkp_error(tn, "Unknown PADSTACK_TYPE %s\n", tn->argv[1]); + return NULL; + } + + + + + ts = pcb_vtpadstack_tshape_alloc_insert(&p->proto.tr, 0, 1); + + memset(ts, 0, sizeof(pcb_vtpadstack_tshape_t)); + ts->shape = calloc(sizeof(pcb_pstk_shape_t), 8); /* large enough to host all possible shapes; ->len will be smaller; when copied to the final prorotype e.g. in subcircuits, only entries used will be allocated */ + + /* parse the shapes */ + for(n = n->first_child; n != NULL; n = n->next) { + lyt_name_t *ln; + for(ln = lyt_names; ln->name != NULL; ln++) { + if (top_only && ((ln->lyt & PCB_LYT_TOP) == 0)) /* ignore anything but top shapes for smd pads */ + continue; + if (strcmp(ln->name, n->argv[0]) == 0) { + hkp_shape_t *shp; + + shp = parse_shape(ctx, n->argv[1]); + if (shp == NULL) { + hkp_error(n, "Undefined shape '%s'\n", n->argv[1]); + goto error; + } + ts->shape[ts->len] = shp->shp; + ts->shape[ts->len].layer_mask = ln->lyt; + ts->shape[ts->len].comb = ln->lyc; + ts->len++; + } + } + } + + /* hole needs special threatment for two reasons: + - it's normally not a shape (except when it is a slot) + - it may have an offset on input, which will be an offset of all shapes + so we can keep the hole at 0;0 */ + n = find_nth(p->subtree->first_child, "TECHNOLOGY", 0); + hn = find_nth(n->first_child, "HOLE_NAME", 0); + if (hn != NULL) { + hkp_hole_t *hole; + + on = find_nth(hn->first_child, "OFFSET", 0); + if (on != NULL) { + parse_xy(ctx, on->argv[1], &ox, &oy, 1); + if (ox != 0) ox = -ox; + if (oy != 0) oy = -oy; + TODO("[easy] test this when ox;oy != 0"); + } + + hole = parse_hole(ctx, hn->argv[1]); + if (hole == NULL) { + hkp_error(hn, "Undefined hole '%s'\n", hn->argv[1]); + goto error; + } + if (hole->dia > 0) { + p->proto.hdia = hole->dia; + p->proto.hplated = hole->plated; + } + else { + slot_shape(&(ts->shape[ts->len]), hole->w, hole->h); + ts->len++; + } + TODO("htop/hbottom: do we get bbvia span from the hole or from the padstack?"); + } + + p->proto.in_use = 1; + p->valid = 1; + ctx->unit = old_unit; + return p; + + error:; + ctx->unit = old_unit; + return NULL; +} + +static void set_pstk_clearance(hkp_ctx_t *ctx, const hkp_netclass_t *nc, pcb_pstk_t *ps, node_t *errnd) +{ + pcb_layergrp_t *clgrp = pcb_get_layergrp(ctx->pcb, pcb_layergrp_get_top_copper()); + if ((clgrp != NULL) && (clgrp->len > 0)) + ps->Clearance = net_get_clearance_(ctx, clgrp->lid[0], nc, HKP_CLR_POLY2TERM, errnd); +} + +static void parse_pin(hkp_ctx_t *ctx, pcb_subc_t *subc, const hkp_netclass_t *nc, node_t *nd, int on_bottom) +{ + node_t *tmp; + rnd_coord_t px, py; + hkp_pstk_t *hpstk; + rnd_cardinal_t pid; + pcb_pstk_t *ps; + double rot = 0; + + tmp = find_nth(nd->first_child, "XY", 0); + if (tmp == NULL) { + hkp_error(nd, "Ignoring pin with no coords\n"); + return; + } + + parse_x(ctx, tmp->argv[1], &px); + parse_y(ctx, tmp->argv[2], &py); + + tmp = find_nth(nd->first_child, "ROTATION", 0); + if (tmp != NULL) + parse_rot(ctx, tmp, &rot, on_bottom); + + tmp = find_nth(nd->first_child, "PADSTACK", 0); + if (tmp == NULL) { + hkp_error(nd, "Ignoring pin with no padstack\n"); + return; + } + hpstk = parse_pstk(ctx, tmp->argv[1]); + if (hpstk == NULL) { + hkp_error(tmp, "Ignoring pin with undefined padstack '%s'\n", tmp->argv[1]); + return; + } + + pid = pcb_pstk_proto_insert_dup(subc->data, &hpstk->proto, 1, 0); + ps = pcb_pstk_alloc(subc->data); + ps->Flags = DEFAULT_OBJ_FLAG; + ps->x = px; + ps->y = py; + ps->rot = rot; + ps->proto = pid; + ps->xmirror = ps->smirror = on_bottom; + pcb_pstk_add(subc->data, ps); + pcb_attribute_put(&ps->Attributes, "term", nd->argv[1]); + + set_pstk_clearance(ctx, nc, ps, nd); +} + +static int io_mentor_cell_pstks(hkp_ctx_t *ctx, const char *fn) +{ + FILE *fpstk; + node_t *n; + + fpstk = rnd_fopen(&ctx->pcb->hidlib, fn, "r"); + if (fpstk == NULL) { + rnd_message(RND_MSG_ERROR, "can't open padstack hkp '%s' for read\n", fn); + return -1; + } + + load_hkp(&ctx->padstacks, fpstk, fn); + + /* build the indices */ + htsp_init(&ctx->shapes, strhash, strkeyeq); + htsp_init(&ctx->holes, strhash, strkeyeq); + htsp_init(&ctx->pstks, strhash, strkeyeq); + + for(n = ctx->padstacks.root->first_child; n != NULL; n = n->next) { + if (strcmp(n->argv[0], "UNITS") == 0) { + ctx->pstk_unit = parse_units(n->argv[1]); + if (ctx->pstk_unit == NULL) + return hkp_error(n, "Unknown unit '%s'\n", n->argv[1]); + } + else if (strcmp(n->argv[0], "PAD") == 0) { + if (!htsp_has(&ctx->shapes, n->argv[1])) { + hkp_shape_t *shp = calloc(sizeof(hkp_shape_t), 1); + shp->subtree = n; + shp->unit = ctx->pstk_unit; + htsp_insert(&ctx->shapes, n->argv[1], shp); + } + else + return hkp_error(n, "Duplicate PAD '%s'\n", n->argv[1]); + } + else if (strcmp(n->argv[0], "HOLE") == 0) { + if (!htsp_has(&ctx->holes, n->argv[1])) { + hkp_shape_t *hole = calloc(sizeof(hkp_hole_t), 1); + hole->subtree = n; + hole->unit = ctx->pstk_unit; + htsp_insert(&ctx->holes, n->argv[1], hole); + } + else + return hkp_error(n, "Duplicate HOLE '%s'\n", n->argv[1]); + } + else if (strcmp(n->argv[0], "PADSTACK") == 0) { + if (!htsp_has(&ctx->pstks, n->argv[1])) { + hkp_shape_t *pstk = calloc(sizeof(hkp_pstk_t), 1); + pstk->subtree = n; + pstk->unit = ctx->pstk_unit; + htsp_insert(&ctx->pstks, n->argv[1], pstk); + } + else + return hkp_error(n, "Duplicate PADSTACK '%s'\n", n->argv[1]); + } + } + + fclose(fpstk); + return 0; +} + +static void free_pstks(hkp_ctx_t *ctx) +{ + htsp_entry_t *e; + + for(e = htsp_first(&ctx->shapes); e != NULL; e = htsp_next(&ctx->shapes, e)) { + hkp_shape_t *shp = e->value; + free(shp); + } + htsp_uninit(&ctx->shapes); + + for(e = htsp_first(&ctx->holes); e != NULL; e = htsp_next(&ctx->holes, e)) { + hkp_hole_t *hole = e->value; + free(hole); + } + htsp_uninit(&ctx->holes); + + for(e = htsp_first(&ctx->pstks); e != NULL; e = htsp_next(&ctx->pstks, e)) { + hkp_pstk_t *pstk = e->value; + free(pstk); + } + htsp_uninit(&ctx->pstks); +} Index: tags/2.3.0/src_plugins/io_pcb/Makefile =================================================================== --- tags/2.3.0/src_plugins/io_pcb/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_io_pcb + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/io_pcb/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/io_pcb/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/Plug.tmpasm (revision 33253) @@ -0,0 +1,17 @@ +put /local/pcb/mod {io_pcb} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/io_pcb/io_pcb.o + $(PLUGDIR)/io_pcb/file.o + $(PLUGDIR)/io_pcb/parse_y.o + $(PLUGDIR)/io_pcb/parse_l.o + $(PLUGDIR)/io_pcb/attribs.o +@] +put /local/pcb/mod/YACC {$(PLUGDIR)/io_pcb/parse_y} +put /local/pcb/mod/LEX {$(PLUGDIR)/io_pcb/parse_l} + +switch /local/pcb/io_pcb/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end + Index: tags/2.3.0/src_plugins/io_pcb/attribs.c =================================================================== --- tags/2.3.0/src_plugins/io_pcb/attribs.c (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/attribs.c (revision 33253) @@ -0,0 +1,134 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include "board.h" +#include + +#define LISTSEP " [[pcb-rnd]] " + +/* Save and load pcb conf attributes, but do not save ::design:: (because they have flags) */ +static const char *conf_attr_prefix = "PCB::conf::"; +static const char *conf_attr_prefix_inhibit = "design::"; +/* The optimizer will fix this */ +#define conf_attr_prefix_len strlen(conf_attr_prefix) +#define conf_attr_prefix_inhibit_len strlen(conf_attr_prefix_inhibit) + +static int path_ok(const char *path) +{ + if (strncmp(path, conf_attr_prefix, conf_attr_prefix_len) != 0) + return 0; + if (strncmp(path + conf_attr_prefix_len, conf_attr_prefix_inhibit, conf_attr_prefix_inhibit_len) == 0) + return 0; + return 1; +} + +static void c2a(pcb_board_t *pcb, lht_node_t *tree, const char *path1) +{ + lht_dom_iterator_t it; + lht_node_t *n; + char apath[512], *path, *pe; + int path1l = strlen(path1); + + memcpy(apath, conf_attr_prefix, conf_attr_prefix_len); + path = apath + conf_attr_prefix_len; + + if (path1l != 0) { + memcpy(path, path1, path1l); + path[path1l] = '/'; + pe = path+path1l+1; + } + else + pe = path; + + /* a depth-first-search and save config items from the tree */ + for(n = lht_dom_first(&it, tree); n != NULL; n = lht_dom_next(&it)) { + strcpy(pe, n->name); + if (n->type == LHT_HASH) + c2a(pcb, n, path); + if (strncmp(path, "design/",7) == 0) { + continue; + } + if (n->type == LHT_TEXT) { + rnd_conf_native_t *nv = rnd_conf_get_field(path); + if ((nv != NULL) && (!nv->random_flags.io_pcb_no_attrib)) + pcb_attribute_put(&pcb->Attributes, apath, n->data.text.value); + } + else if (n->type == LHT_LIST) { + lht_node_t *i; + rnd_conf_native_t *nv = rnd_conf_get_field(path); + if ((nv != NULL) && (!nv->random_flags.io_pcb_no_attrib)) { + gds_t conc; + gds_init(&conc); + for(i = n->data.list.first; i != NULL; i = i->next) { + if (i->data.text.value == NULL) + continue; + if (i != n->data.list.first) + gds_append_str(&conc, LISTSEP); + gds_append_str(&conc, i->data.text.value); + } + pcb_attribute_put(&pcb->Attributes, apath, conc.array); + gds_uninit(&conc); + } + } + } +} + +void io_pcb_attrib_c2a(pcb_board_t *pcb) +{ + lht_node_t *nmain = rnd_conf_lht_get_first(RND_CFR_DESIGN, 0); + + c2a(pcb, nmain, ""); +} + +void io_pcb_attrib_a2c(pcb_board_t *pcb) +{ + int n; + + for (n = 0; n < pcb->Attributes.Number; n++) { + if (path_ok(pcb->Attributes.List[n].name)) { + rnd_conf_native_t *nv = rnd_conf_get_field(pcb->Attributes.List[n].name + conf_attr_prefix_len); + if (nv == NULL) + continue; + if (nv->type == RND_CFN_LIST) { + char *tmp = rnd_strdup(pcb->Attributes.List[n].value); + char *next, *curr; + for(curr = tmp; curr != NULL; curr = next) { + next = strstr(curr, LISTSEP); + if (next != NULL) { + *next = '\0'; + next += strlen(LISTSEP); + } + rnd_conf_set(RND_CFR_DESIGN, pcb->Attributes.List[n].name + conf_attr_prefix_len, -1, curr, RND_POL_APPEND); + } + free(tmp); + } + else /* assume plain string */ + rnd_conf_set(RND_CFR_DESIGN, pcb->Attributes.List[n].name + conf_attr_prefix_len, -1, pcb->Attributes.List[n].value, RND_POL_OVERWRITE); + } + } +} Index: tags/2.3.0/src_plugins/io_pcb/attribs.h =================================================================== --- tags/2.3.0/src_plugins/io_pcb/attribs.h (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/attribs.h (revision 33253) @@ -0,0 +1,2 @@ +void io_pcb_attrib_c2a(pcb_board_t *pcb); +void io_pcb_attrib_a2c(pcb_board_t *pcb); Index: tags/2.3.0/src_plugins/io_pcb/file.c =================================================================== --- tags/2.3.0/src_plugins/io_pcb/file.c (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/file.c (revision 33253) @@ -0,0 +1,1427 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,1997,1998,2005,2006 Thomas Nau + * Copyright (C) 2015, 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* file save, load, merge ... routines */ + +#include "config.h" +#include "conf_core.h" +#include + +#include +#include +#include +#include +#include + +#include "buffer.h" +#include "change.h" +#include "crosshair.h" +#include "data.h" +#include +#include "file.h" +#include "plug_io.h" +#include +#include "layer.h" +#include "layer_grp.h" +#include "move.h" +#include "parse_common.h" +#include +#include "polygon.h" +#include +#include "remove.h" +#include "flag_str.h" +#include +#include +#include +#include "rats_patch.h" +#include +#include "flag_str.h" +#include "attribs.h" +#include "route_style.h" +#include "obj_poly.h" +#include "thermal.h" +#include "event.h" +#include "funchash_core.h" +#include "netlist.h" +#include "plug_footprint.h" + +#include "src_plugins/lib_compat_help/layer_compat.h" +#include "src_plugins/lib_compat_help/pstk_compat.h" +#include "src_plugins/lib_compat_help/subc_help.h" +#include "src_plugins/lib_compat_help/elem_rot.h" + +/* Note: this works because of using str_flag compat_types */ +#define PCB_OBJ_VIA PCB_OBJ_PSTK +#define PCB_OBJ_PIN PCB_OBJ_PSTK +#define PCB_OBJ_PAD PCB_OBJ_PSTK +#define PCB_OBJ_ELEMENT PCB_OBJ_SUBC +#define PCB_OBJ_ELEMENT_NAME PCB_OBJ_TEXT + +pcb_unit_style_t pcb_io_pcb_usty_seen; + +static void WritePCBInfoHeader(FILE *); +static void WritePCBDataHeader(FILE *); +static void WritePCBFontData(FILE *); +static void WriteViaData(FILE *, pcb_data_t *); +static void WritePCBRatData(FILE *); +static void WriteLayerData(FILE *, rnd_cardinal_t, pcb_layer_t *); + +#define IGNORE_FLAGS (PCB_FLAG_FLOATER | PCB_FLAG_DRC_INTCONN | PCB_FLAG_CLEARPOLYPOLY | PCB_FLAG_DYNTEXT) + +static char *pcb_strflg_f2s_compat(pcb_flag_t flags, int object_type, unsigned char *intconn) +{ + flags.f &= ~IGNORE_FLAGS; + return pcb_strflg_f2s(flags, object_type, intconn, 1); +} + + +#define F2S(OBJ, TYPE) (pcb_strflg_f2s_compat(((OBJ)->Flags), TYPE, &((OBJ)->intconn))) + +/* The idea here is to avoid gratuitously breaking backwards + compatibility due to a new but rarely used feature. The first such + case, for example, was the polygon Hole - if your design included + polygon holes, you needed a newer PCB to read it, but if your + design didn't include holes, PCB would produce a file that older + PCBs could read, if only it had the correct version number in it. + + If, however, you have to add or change a feature that really does + require a new PCB version all the time, it's time to remove all the + tests below and just always output the new version. + + Note: Best practices here is to add support for a feature *first* + (and bump PCB_FILE_VERSION in file.h), and note the version that + added that support below, and *later* update the file format to + need that version (which may then be older than PCB_FILE_VERSION). + Hopefully, that allows for one release between adding support and + needing it, which should minimize breakage. Of course, that's not + *always* possible, practical, or desirable. + +*/ + +/* Hole[] in Polygon. */ +#define PCB_FILE_VERSION_HOLES 20100606 +/* First version ever saved. */ +#define PCB_FILE_VERSION_BASELINE 20070407 + +int PCBFileVersionNeeded(void) +{ + PCB_POLY_ALL_LOOP(PCB->Data); + { + if (polygon->HoleIndexN > 0) + return PCB_FILE_VERSION_HOLES; + } + PCB_ENDALL_LOOP; + + return PCB_FILE_VERSION_BASELINE; +} + +/* In future all use of this should be supplanted by + * pcb-printf and %mr/%m# spec */ +static const char *c_dtostr(double d) +{ + static char buf[100]; + int i, f; + char *bufp = buf; + + if (d < 0) { + *bufp++ = '-'; + d = -d; + } + d += 0.0000005; /* rounding */ + i = floor(d); + d -= i; + sprintf(bufp, "%d", i); + bufp += strlen(bufp); + *bufp++ = '.'; + + f = floor(d * 1000000.0); + sprintf(bufp, "%06d", f); + return buf; +} + +/* Returns pointer to private buffer */ +static char *LayerGroupsToString(pcb_layer_stack_t *lg) +{ +#if PCB_MAX_LAYER < 9998 + /* Allows for layer numbers 0..9999 */ + static char buf[(PCB_MAX_LAYER + 2) * 5 + 1]; +#endif + char *cp = buf; + char sep = 0; + int group, entry; +TODO("layer: revise this loop to save only what the original code saved") + for (group = 0; group < pcb_max_group(PCB); group++) + if (PCB->LayerGroups.grp[group].len) { + unsigned int gflg = pcb_layergrp_flags(PCB, group); + + if (gflg & PCB_LYT_SILK) /* silk is hacked in asusming there's a top and bottom copper */ + continue; + + if (sep) + *cp++ = ':'; + sep = 1; + for (entry = 0; entry < PCB->LayerGroups.grp[group].len; entry++) { + rnd_layer_id_t layer = PCB->LayerGroups.grp[group].lid[entry]; + + sprintf(cp, "%ld", layer + 1); + while (*++cp); + + if (entry != PCB->LayerGroups.grp[group].len - 1) + *cp++ = ','; + } + + if ((gflg & PCB_LYT_COPPER) && (gflg & PCB_LYT_TOP)) { + *cp++ = ','; + *cp++ = 'c'; + } + else if ((gflg & PCB_LYT_COPPER) && (gflg & PCB_LYT_BOTTOM)) { + *cp++ = ','; + *cp++ = 's'; + } + } + *cp++ = 0; + return buf; +} + + +static void WriteAttributeList(FILE * FP, pcb_attribute_list_t *list, const char *prefix, const char **inhibit) +{ + int i; + const char **ih; + + for (i = 0; i < list->Number; i++) { + if (inhibit != NULL) { + for(ih = inhibit; *ih != NULL; ih++) { + if (strcmp(list->List[i].name, *ih) == 0) + goto skip; + } + } + fprintf(FP, "%sAttribute(\"%s\" \"%s\")\n", prefix, list->List[i].name, list->List[i].value); + skip:; + } +} + +static void WritePCBInfoHeader(FILE * FP) +{ + /* write some useful comments */ + fprintf(FP, "# release: pcb-rnd " PCB_VERSION "\n"); + + /* avoid writing things like user name or date, as these cause merge + * conflicts in collaborative environments using version control systems + */ +} + +static void conf_update_pcb_flag(pcb_flag_t *dest, const char *hash_path, int binflag) +{ + rnd_conf_native_t *n = rnd_conf_get_field(hash_path); + struct { + pcb_flag_t Flags; + } *tmp = (void *)dest; + + if ((n == NULL) || (n->type != RND_CFN_BOOLEAN) || (n->used < 0) || (!n->val.boolean[0])) + PCB_FLAG_CLEAR(binflag, tmp); + else + PCB_FLAG_SET(binflag, tmp); +} + +/* data header: the name of the PCB, cursor location, zoom and grid + * layergroups and some flags */ +static void WritePCBDataHeader(FILE * FP) +{ + int group; + pcb_flag_t pcb_flags; + + memset(&pcb_flags, 0, sizeof(pcb_flags)); + + io_pcb_attrib_c2a(PCB); + + /* set binary flags from conf hash; these flags used to be checked + with PCB_FLAG_TEST() but got moved to the conf system */ + conf_update_pcb_flag(&pcb_flags, "plugins/mincut/enable", PCB_ENABLEPCB_FLAG_MINCUT); + conf_update_pcb_flag(&pcb_flags, "editor/show_number", PCB_SHOWNUMBERFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/show_drc", PCB_SHOWPCB_FLAG_DRC); + conf_update_pcb_flag(&pcb_flags, "editor/rubber_band_mode", PCB_RUBBERBANDFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/auto_drc", PCB_AUTOPCB_FLAG_DRC); + conf_update_pcb_flag(&pcb_flags, "editor/all_direction_lines", PCB_ALLDIRECTIONFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/swap_start_direction", PCB_SWAPSTARTDIRFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/unique_names", PCB_UNIQUENAMEFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/clear_line", PCB_CLEARNEWFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/full_poly", PCB_NEWPCB_FLAG_FULLPOLY); + conf_update_pcb_flag(&pcb_flags, "editor/snap_pin", PCB_SNAPPCB_FLAG_PIN); + conf_update_pcb_flag(&pcb_flags, "editor/orthogonal_moves", PCB_ORTHOMOVEFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/live_routing", PCB_LIVEROUTEFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/lock_names", PCB_LOCKNAMESFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/only_names", PCB_ONLYNAMESFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/hide_names", PCB_HIDENAMESFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/thin_draw", PCB_THINDRAWFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/thin_draw_poly", PCB_THINDRAWPOLYFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/local_ref", PCB_LOCALREFFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/check_planes",PCB_CHECKPLANESFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/description", PCB_DESCRIPTIONFLAG); + conf_update_pcb_flag(&pcb_flags, "editor/name_on_pcb", PCB_NAMEONPCBFLAG); + + fprintf(FP, "\n# To read pcb files, the pcb version (or the git source date) must be >= the file version\n"); + fprintf(FP, "FileVersion[%i]\n", PCBFileVersionNeeded()); + + fputs("\nPCB[", FP); + pcb_print_quoted_string(FP, (char *) RND_EMPTY(PCB->hidlib.name)); + rnd_fprintf(FP, " %[0] %[0]]\n\n", PCB->hidlib.size_x, PCB->hidlib.size_y); + rnd_fprintf(FP, "Grid[%[0] %[0] %[0] %d]\n", PCB->hidlib.grid, PCB->hidlib.grid_ox, PCB->hidlib.grid_oy, rnd_conf.editor.draw_grid); + rnd_fprintf(FP, "Cursor[%[0] %[0] 1000]\n", pcb_crosshair.X, pcb_crosshair.Y); + /* PolyArea should be output in square cmils, no suffix */ + fprintf(FP, "PolyArea[%s]\n", c_dtostr(RND_COORD_TO_MIL(RND_COORD_TO_MIL(conf_core.design.poly_isle_area) * 100) * 100)); + rnd_fprintf(FP, "Thermal[%s]\n", c_dtostr(PCB->ThermScale)); + rnd_fprintf(FP, "DRC[%[0] %[0] %[0] %[0] %[0] %[0]]\n", conf_core.design.bloat, conf_core.design.shrink, + conf_core.design.min_wid, conf_core.design.min_slk, conf_core.design.min_drill, conf_core.design.min_ring); + fprintf(FP, "Flags(%s)\n", pcb_strflg_board_f2s(pcb_flags)); + fprintf(FP, "Groups(\"%s\")\n", LayerGroupsToString(&PCB->LayerGroups)); + fputs("Styles[\"", FP); + + if (vtroutestyle_len(&PCB->RouteStyle) > 0) { + for (group = 0; group < vtroutestyle_len(&PCB->RouteStyle) - 1; group++) + rnd_fprintf(FP, "%s,%[0],%[0],%[0],%[0]:", PCB->RouteStyle.array[group].name, + PCB->RouteStyle.array[group].Thick, + PCB->RouteStyle.array[group].Diameter, PCB->RouteStyle.array[group].Hole, PCB->RouteStyle.array[group].Clearance); + rnd_fprintf(FP, "%s,%[0],%[0],%[0],%[0]\"]\n\n", PCB->RouteStyle.array[group].name, + PCB->RouteStyle.array[group].Thick, + PCB->RouteStyle.array[group].Diameter, PCB->RouteStyle.array[group].Hole, PCB->RouteStyle.array[group].Clearance); + } + else { + pcb_io_incompat_save(PCB->Data, NULL, "route-style", "There are no routing styles - many versions of gEDA/PCB will segfault on loading the file", "Create exactly 4 routing styles."); + fprintf(FP, "\"]\n\n"); + } +} + +/* writes font data of non empty symbols */ +static void WritePCBFontData(FILE * FP) +{ + rnd_cardinal_t i, j; + pcb_line_t *line; + pcb_font_t *font; + + for (font = pcb_font(PCB, 0, 1), i = 0; i <= PCB_MAX_FONTPOSITION; i++) { + if (!font->Symbol[i].Valid) + continue; + + if (isprint(i)) + rnd_fprintf(FP, "Symbol['%c' %[0]]\n(\n", i, font->Symbol[i].Delta); + else + rnd_fprintf(FP, "Symbol[%i %[0]]\n(\n", i, font->Symbol[i].Delta); + + line = font->Symbol[i].Line; + for (j = font->Symbol[i].LineN; j; j--, line++) + rnd_fprintf(FP, "\tSymbolLine[%[0] %[0] %[0] %[0] %[0]]\n", + line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, line->Thickness); + fputs(")\n", FP); + } +} + +static void WriteViaData(FILE * FP, pcb_data_t *Data) +{ + gdl_iterator_t it; + pcb_pstk_t *ps; + + /* write information about vias */ + padstacklist_foreach(&Data->padstack, &it, ps) { + rnd_coord_t x, y, drill_dia, pad_dia, clearance, mask; + pcb_pstk_compshape_t cshape; + rnd_bool plated; + char *name = pcb_attribute_get(&ps->Attributes, "name"); + + if (!pcb_pstk_export_compat_via(ps, &x, &y, &drill_dia, &pad_dia, &clearance, &mask, &cshape, &plated)) { + pcb_io_incompat_save(Data, (pcb_any_obj_t *)ps, "via", "Failed to convert to old-style via", "Old via format is very much restricted; try to use a simpler, uniform shape padstack"); + continue; + } + + rnd_fprintf(FP, "Via[%[0] %[0] %[0] %[0] %[0] %[0] ", x, y, + pad_dia, clearance*2, mask, drill_dia); + pcb_print_quoted_string(FP, (char *) RND_EMPTY(name)); + fprintf(FP, " %s]\n", pcb_strflg_f2s(pcb_pstk_compat_pinvia_flag(ps, cshape, PCB_PSTKCOMP_OLD_OCTAGON), PCB_OBJ_VIA, NULL, 1)); + } +} + +static void WritePCBRatData(FILE * FP) +{ + gdl_iterator_t it; + pcb_rat_t *line; + + /* write information about rats */ + ratlist_foreach(&PCB->Data->Rat, &it, line) { + rnd_fprintf(FP, "Rat[%[0] %[0] %d %[0] %[0] %d ", + line->Point1.X, line->Point1.Y, line->group1, line->Point2.X, line->Point2.Y, line->group2); + fprintf(FP, " %s]\n", F2S(line, PCB_OBJ_RAT)); + } +} + +static void WritePCBNetlistData(FILE *FP) +{ + htsp_entry_t *e; + + /* write out the netlist if it exists */ + if (PCB->netlist[PCB_NETLIST_INPUT].used < 1) + return; + + fprintf(FP, "NetList()\n(\n"); + + for(e = htsp_first(&PCB->netlist[PCB_NETLIST_INPUT]); e != NULL; e = htsp_next(&PCB->netlist[PCB_NETLIST_INPUT], e)) { + pcb_net_term_t *t; + pcb_net_t *net = e->value; + + fprintf(FP, "\tNet("); + pcb_print_quoted_string(FP, net->name); + fprintf(FP, " "); + pcb_print_quoted_string(FP, (char *) RND_UNKNOWN(pcb_attribute_get(&net->Attributes, "style"))); + fprintf(FP, ")\n\t(\n"); + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) { + fprintf(FP, "\t\tConnect(\""); + pcb_print_quoted_string_(FP, t->refdes); + fputc('-', FP); + pcb_print_quoted_string_(FP, t->term); + fprintf(FP, "\")\n"); + } + fprintf(FP, "\t)\n"); + } + fprintf(FP, ")\n"); +} + +static void WritePCBNetlistPatchData(FILE * FP) +{ + if (PCB->NetlistPatches != NULL) { + pcb_io_incompat_save(PCB->Data, NULL, "net-patch", "Saving netlist patch makes the file incompatible with geda/pcb.", "Either remove (or resolve) your netlist patches before save or remove the NetListPatch() subtree manually from the saved file before using with geda/pcb."); + fprintf(FP, "NetListPatch()\n(\n"); + pcb_ratspatch_fexport(PCB, FP, 1); + fprintf(FP, ")\n"); + } +} + +static void io_pcb_print_subc(pcb_plug_io_t *ctx, FILE *FP, pcb_subc_t *sc) +{ + const char *attr_inhibit[] = {"refdes", "value", "footprint", NULL }; /* these are saved in the header if the element */ + gdl_iterator_t it; + int l; + + rnd_coord_t ox, oy, rx = 0, ry = 0; + int rdir = 0, rscale = 100, on_bot = 0; + pcb_text_t *trefdes; + pcb_pstk_t *ps; + pcb_any_obj_t fobj; + + pcb_subc_get_origin(sc, &ox, &oy); + trefdes = pcb_subc_get_refdes_text(sc); + if (pcb_subc_get_side(sc, &on_bot) != 0) + pcb_io_incompat_save(sc->parent.data, (pcb_any_obj_t *)sc, "element-side", "Can not determine element side", "Missing or botched subc aux layer; can not tell if subc is on top or bottom layer, using top."); + + if (trefdes != NULL) { + int scale; + if (pcb_text_old_scale(trefdes, &scale) != 0) + pcb_io_incompat_save(sc->data, (pcb_any_obj_t *)trefdes, "text-scale", "file format does not support different x and y direction text scale - using average scale", "Use the scale field, set scale_x and scale_y to 0"); + if (trefdes->mirror_x) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)trefdes, "text-mirror-x", "file format does not support different mirroring text in the x direction", "do not mirror, or mirror in the y direction (with the ONSOLDER flag)"); + + rx = trefdes->X - ox; + ry = trefdes->Y - oy; + if (!pcb_text_old_direction(&rdir, trefdes->rot)) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)trefdes, "text rotation", "text rotation angle rounded", "the gEDA/PCB file format does not support text rotation other than multiple of 90 degree"); + rscale = scale; + } + else { + const char *tmp; + tmp = pcb_attribute_get(&sc->Attributes, "io_pcb::hidename_x"); + if (tmp != NULL) + rx = rnd_get_value(tmp, NULL, NULL, NULL) - ox; + tmp = pcb_attribute_get(&sc->Attributes, "io_pcb::hidename_y"); + if (tmp != NULL) + ry = rnd_get_value(tmp, NULL, NULL, NULL) - oy; + tmp = pcb_attribute_get(&sc->Attributes, "io_pcb::hidename_direction"); + if (tmp != NULL) + rdir = atoi(tmp); + tmp = pcb_attribute_get(&sc->Attributes, "io_pcb::hidename_scale"); + if (tmp != NULL) + rscale = atoi(tmp); + } + + memset(&fobj, 0, sizeof(fobj)); + fobj.Flags = sc->Flags; + if (trefdes == NULL) + fobj.Flags.f |= PCB_FLAG_HIDENAME; + if (on_bot) + fobj.Flags.f |= PCB_FLAG_ONSOLDER; + fprintf(FP, "\nElement[%s ", F2S(&fobj, PCB_OBJ_ELEMENT)); + pcb_print_quoted_string(FP, (char *) RND_EMPTY(pcb_attribute_get(&sc->Attributes, "footprint"))); + fputc(' ', FP); + pcb_print_quoted_string(FP, (char *) RND_EMPTY(pcb_attribute_get(&sc->Attributes, "refdes"))); + fputc(' ', FP); + pcb_print_quoted_string(FP, (char *) RND_EMPTY(pcb_attribute_get(&sc->Attributes, "value"))); + rnd_fprintf(FP, " %[0] %[0] %[0] %[0] %d %d %s]\n(\n", ox, oy, rx, ry, rdir, rscale, trefdes != NULL ? F2S(trefdes, PCB_OBJ_ELEMENT_NAME) : "\"\""); + WriteAttributeList(FP, &sc->Attributes, "\t", attr_inhibit); + + padstacklist_foreach(&sc->data->padstack, &it, ps) { + rnd_coord_t x, y, drill_dia, pad_dia, clearance, mask, x1, y1, x2, y2, thickness; + pcb_pstk_compshape_t cshape; + rnd_bool plated, square, nopaste; + unsigned char ic = ps->intconn; + if (pcb_pstk_export_compat_via(ps, &x, &y, &drill_dia, &pad_dia, &clearance, &mask, &cshape, &plated)) { + rnd_fprintf(FP, "\tPin[%[0] %[0] %[0] %[0] %[0] %[0] ", x - ox, y - oy, pad_dia, clearance*2, mask, drill_dia); + pcb_print_quoted_string(FP, (char *)RND_EMPTY(pcb_attribute_get(&ps->Attributes, "name"))); + fprintf(FP, " "); + pcb_print_quoted_string(FP, (char *) RND_EMPTY(pcb_attribute_get(&ps->Attributes, "term"))); + fprintf(FP, " %s]\n", pcb_strflg_f2s(pcb_pstk_compat_pinvia_flag(ps, cshape, PCB_PSTKCOMP_OLD_OCTAGON), PCB_OBJ_PIN, &ic, 1)); + } + else if (pcb_pstk_export_compat_pad(ps, &x1, &y1, &x2, &y2, &thickness, &clearance, &mask, &square, &nopaste)) { + unsigned long fl = (square ? PCB_FLAG_SQUARE : 0) | (nopaste ? PCB_FLAG_NOPASTE : 0) | (on_bot ? PCB_FLAG_ONSOLDER : 0); + rnd_fprintf(FP, "\tPad[%[0] %[0] %[0] %[0] %[0] %[0] %[0] ", + x1 - ox, y1 - oy, x2 - ox, y2 - oy, thickness, clearance, mask); + pcb_print_quoted_string(FP, (char *)RND_EMPTY(pcb_attribute_get(&ps->Attributes, "name"))); + fprintf(FP, " "); + pcb_print_quoted_string(FP, (char *) RND_EMPTY(pcb_attribute_get(&ps->Attributes, "term"))); + fprintf(FP, " %s]\n", pcb_strflg_f2s(pcb_flag_make(fl), PCB_OBJ_PAD, &ic, 1)); + } + else + pcb_io_incompat_save(sc->data, (pcb_any_obj_t *)ps, "pin-pad", "Padstack can not be exported as pin or pad", "use simpler padstack; for pins, all copper layers must have the same shape and there must be no paste; for pads, use a line or a rectangle; paste and mask must match the copper shape"); + } + + for(l = 0; l < sc->data->LayerN; l++) { + pcb_layer_type_t my_side; + pcb_layer_t *ly = &sc->data->Layer[l]; + pcb_line_t *line; + pcb_arc_t *arc; + + my_side = on_bot ? PCB_LYT_BOTTOM : PCB_LYT_TOP; + + if ((ly->meta.bound.type & PCB_LYT_SILK) && (ly->meta.bound.type & my_side)) { + linelist_foreach(&ly->Line, &it, line) { + rnd_fprintf(FP, "\tElementLine [%[0] %[0] %[0] %[0] %[0]]\n", + line->Point1.X - ox, line->Point1.Y - oy, + line->Point2.X - ox, line->Point2.Y - oy, + line->Thickness); + } + arclist_foreach(&ly->Arc, &it, arc) { + rnd_fprintf(FP, "\tElementArc [%[0] %[0] %[0] %[0] %ma %ma %[0]]\n", + arc->X - ox, arc->Y - oy, arc->Width, arc->Height, + arc->StartAngle, arc->Delta, arc->Thickness); + } + { + pcb_gfx_t *gfx; + for(gfx = gfxlist_first(&ly->Gfx); gfx != NULL; gfx = gfxlist_next(gfx)) + pcb_io_incompat_save(sc->data, (pcb_any_obj_t *)gfx, "element-obj", "gfx can not be exported in this format, please use lihata", "only lines and arcs are exported"); + } + if (polylist_length(&ly->Polygon) > 0) { + char *desc = rnd_strdup_printf("Polygons on layer %s can not be exported in an element", ly->name); + pcb_io_incompat_save(sc->data, NULL, "element-obj", desc, "only lines and arcs are exported"); + free(desc); + } + if (textlist_length(&ly->Text) > 1) { + char *desc = rnd_strdup_printf("Text on layer %s can not be exported in an element", ly->name); + pcb_io_incompat_save(sc->data, NULL, "element-obj", desc, "only lines and arcs are exported"); + free(desc); + } + continue; + } + + if (!(ly->meta.bound.type & PCB_LYT_VIRTUAL) && (!pcb_layer_is_pure_empty(ly))) { + char *desc = rnd_strdup_printf("Objects on layer %s can not be exported in an element", ly->name); + pcb_io_incompat_save(sc->data, NULL, "element-layer", desc, "only top silk lines and arcs are exported; heavy terminals are not supported, use padstacks only"); + free(desc); + } + } + fputs("\n)\n", FP); +} + +static int io_pcb_WriteSubcData(pcb_plug_io_t *ctx, FILE *FP, pcb_data_t *Data, long subc_idx) +{ + gdl_iterator_t sit; + pcb_subc_t *sc; + + rnd_printf_slot[0] = ((io_pcb_ctx_t *)(ctx->plugin_data))->write_coord_fmt; + + subclist_foreach(&Data->subc, &sit, sc) { + if ((subc_idx != -1) && (subc_idx != sit.count)) + continue; + + io_pcb_print_subc(ctx, FP, sc); + } + return 0; +} + +int io_pcb_write_subcs_head(pcb_plug_io_t *ctx, void **udata, FILE *f, int lib, long num_subcs) +{ + return 0; +} + +int io_pcb_write_subcs_subc(pcb_plug_io_t *ctx, void **udata, FILE *f, pcb_subc_t *subc) +{ + rnd_printf_slot[0] = ((io_pcb_ctx_t *)(ctx->plugin_data))->write_coord_fmt; + io_pcb_print_subc(ctx, f, subc); + return 0; +} + +int io_pcb_write_subcs_tail(pcb_plug_io_t *ctx, void **udata, FILE *f) +{ + return 0; +} + +static const char *layer_name_hack(pcb_layer_t *layer, const char *name) +{ + unsigned long lflg = pcb_layer_flags_(layer); + int purpi = pcb_layer_purpose_(layer, NULL); + /* The old PCB format encodes some properties in layer names - have to + alter the real layer name before save to get the same effect */ + if (PCB_LAYER_IS_OUTLINE(lflg, purpi)) { + if (rnd_strcasecmp(name, "outline") == 0) + return name; + return "Outline"; + } + if (lflg & PCB_LYT_SILK) { + if (rnd_strcasecmp(name, "silk") == 0) + return name; + return "silk"; + } + + /* plain layer */ + return name; +} + +static void WriteLayerData(FILE * FP, rnd_cardinal_t Number, pcb_layer_t *layer) +{ + gdl_iterator_t it; + pcb_line_t *line; + pcb_arc_t *arc; + pcb_text_t *text; + pcb_poly_t *polygon; + + /* write information about non empty layers */ + if (!pcb_layer_is_empty_(PCB, layer) || (layer->name && *layer->name)) { + fprintf(FP, "Layer(%i ", (int) Number + 1); + pcb_print_quoted_string(FP, layer_name_hack(layer, RND_EMPTY(layer->name))); + fputs(")\n(\n", FP); + WriteAttributeList(FP, &layer->Attributes, "\t", NULL); + + linelist_foreach(&layer->Line, &it, line) { + rnd_fprintf(FP, "\tLine[%[0] %[0] %[0] %[0] %[0] %[0] %s]\n", + line->Point1.X, line->Point1.Y, + line->Point2.X, line->Point2.Y, line->Thickness, line->Clearance, F2S(line, PCB_OBJ_LINE)); + } + { + pcb_gfx_t *gfx; + for(gfx = gfxlist_first(&layer->Gfx); gfx != NULL; gfx = gfxlist_next(gfx)) + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)gfx, "gfx", "gfx can not be exported in this format", "please use the lihata format"); + } + arclist_foreach(&layer->Arc, &it, arc) { + rnd_fprintf(FP, "\tArc[%[0] %[0] %[0] %[0] %[0] %[0] %ma %ma %s]\n", + arc->X, arc->Y, arc->Width, + arc->Height, arc->Thickness, arc->Clearance, arc->StartAngle, arc->Delta, F2S(arc, PCB_OBJ_ARC)); + } + textlist_foreach(&layer->Text, &it, text) { + int dir; + int scale; + if (pcb_text_old_scale(text, &scale) != 0) + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)text, "text-scale", "file format does not support different x and y direction text scale - using average scale", "Use the scale field, set scale_x and scale_y to 0"); + if (text->mirror_x) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-mirror-x", "file format does not support different mirroring text in the x direction", "do not mirror, or mirror in the y direction (with the ONSOLDER flag)"); + if (!pcb_text_old_direction(&dir, text->rot)) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text rotation", "text rotation angle rounded", "the gEDA/PCB file format does not support text rotation other than multiple of 90 degree"); + rnd_fprintf(FP, "\tText[%[0] %[0] %d %d ", text->X, text->Y, dir, scale); + pcb_print_quoted_string(FP, (char *) RND_EMPTY(text->TextString)); + fprintf(FP, " %s]\n", F2S(text, PCB_OBJ_TEXT)); + } + textlist_foreach(&layer->Polygon, &it, polygon) { + int p, i = 0; + rnd_cardinal_t hole = 0; + fprintf(FP, "\tPolygon(%s)\n\t(", F2S(polygon, PCB_OBJ_POLY)); + for (p = 0; p < polygon->PointN; p++) { + rnd_point_t *point = &polygon->Points[p]; + + if (hole < polygon->HoleIndexN && p == polygon->HoleIndex[hole]) { + if (hole > 0) + fputs("\n\t\t)", FP); + fputs("\n\t\tHole (", FP); + hole++; + i = 0; + } + + if (i++ % 5 == 0) { + fputs("\n\t\t", FP); + if (hole) + fputs("\t", FP); + } + rnd_fprintf(FP, "[%[0] %[0]] ", point->X, point->Y); + } + if (hole > 0) + fputs("\n\t\t)", FP); + fputs("\n\t)\n", FP); + } + fputs(")\n", FP); + } +} + +static rnd_layer_id_t pcb_layer_get_cached(pcb_board_t *pcb, unsigned int loc, unsigned int typ) +{ + pcb_layergrp_t *g = pcb_get_grp(&pcb->LayerGroups, loc, typ); + if ((g == NULL) || (g->len == 0)) + return -1; + if (g->len > 1) + pcb_io_incompat_save(PCB->Data, NULL, "layer", "Multiple silk layers per side not supported by gEDA/PCB", "Merge your silk layers into one layer per group; if there are negative silk layers: layer compositing is not supported by gEDA/PCB"); + return g->lid[0]; +} + +static rnd_layer_id_t pcb_layer_get_bottom_silk(void) +{ + return pcb_layer_get_cached(PCB, PCB_LYT_BOTTOM, PCB_LYT_SILK); +} + +static rnd_layer_id_t pcb_layer_get_top_silk(void) +{ + return pcb_layer_get_cached(PCB, PCB_LYT_TOP, PCB_LYT_SILK); +} + +static void LayersFixup(void) +{ + rnd_layer_id_t bs, ts; + int chg = 0; + + /* the PCB format requires 2 silk layers to be the last; swap layers to make that so */ + bs = pcb_layer_get_bottom_silk(); + ts = pcb_layer_get_top_silk(); + + if ((bs < 0) || (ts < 0)) { + rnd_message(RND_MSG_ERROR, "The geda/pcb file format requires top and bottom silk layers.\nExporting a board without those will not be usable in geda/pcb.\n"); + return; + } + + if (bs != pcb_max_layer(PCB) - 2) { + pcb_layer_swap(PCB, bs, pcb_max_layer(PCB) - 2); + chg = 1; + } + + bs = pcb_layer_get_bottom_silk(); + ts = pcb_layer_get_top_silk(); + + if (ts != pcb_max_layer(PCB) - 1) { + pcb_layer_swap(PCB, ts, pcb_max_layer(PCB) - 1); + chg = 1; + } + + if (chg) { + rnd_message(RND_MSG_ERROR, "The geda/pcb file format requires top and bottom silk be the last layers in the list.\nI had to swap layers in your board _before_ the save.\nAt the moment this is not undoable!\n"); + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); + } +} + +static void WriteLayers(FILE *FP, pcb_data_t *data) +{ + int i; + for (i = 0; i < data->LayerN; i++) { + pcb_layer_t *ly = &(data->Layer[i]); + pcb_layer_type_t lyt = pcb_layer_flags_(ly); + int purpi = pcb_layer_purpose_(ly, NULL); + if ((!(lyt & (PCB_LYT_COPPER | PCB_LYT_SILK))) && (!PCB_LAYER_IS_ROUTE(lyt, purpi))) { + if (!pcb_layer_is_pure_empty(ly)) { + char *desc = rnd_strdup_printf("Layer %s can be exported only as a copper layer", ly->name); + pcb_io_incompat_save(data, NULL, "layer", desc, NULL); + free(desc); + } + } + WriteLayerData(FP, i, ly); + } +} + +int io_pcb_WritePCB(pcb_plug_io_t *ctx, FILE * FP, const char *old_filename, const char *new_filename, rnd_bool emergency) +{ + pcb_attribute_put(&PCB->Attributes, "PCB::loader", ctx->description); + + LayersFixup(); + + rnd_printf_slot[0] = ((io_pcb_ctx_t *)(ctx->plugin_data))->write_coord_fmt; + WritePCBInfoHeader(FP); + WritePCBDataHeader(FP); + WritePCBFontData(FP); + WriteAttributeList(FP, &PCB->Attributes, "", NULL); + WriteViaData(FP, PCB->Data); + io_pcb_WriteSubcData(ctx, FP, PCB->Data, -1); + WritePCBRatData(FP); + WriteLayers(FP, PCB->Data); + WritePCBNetlistData(FP); + WritePCBNetlistPatchData(FP); + + return 0; +} + +/*** functions for loading elements-as-pcb ***/ +extern pcb_board_t *yyPCB; +extern pcb_data_t *yyData; +extern pcb_font_t *yyFont; +extern int yyElemFixLayers; + +void PreLoadElementPCB() +{ + + if (!yyPCB) + return; + + yyFont = &yyPCB->fontkit.dflt; + yyData = yyPCB->Data; + PCB_SET_PARENT(yyData, board, yyPCB); + yyData->LayerN = 0; +} + +void PostLoadElementPCB() +{ + pcb_board_t *pcb_save = PCB; + rnd_box_t dbb; + pcb_subc_t *sc; + + if (!yyPCB) + return; + + pcb_board_new_postproc(yyPCB, 0); + pcb_layer_group_setup_default(yyPCB); + PCB = yyPCB; + pcb_layer_group_setup_silks(yyPCB); + pcb_data_bbox(&dbb, yyPCB->Data, rnd_false); + pcb_data_normalize_(yyPCB->Data, &dbb); + PCB = pcb_save; + yyPCB->hidlib.size_x = dbb.X2*2; + yyPCB->hidlib.size_y = dbb.Y2*2; + yyPCB->is_footprint = 1; + + /* opening a footprint: we don't have a layer stack; make sure top and bottom copper exist */ + { + rnd_layergrp_id_t gid; + int res; + + res = pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_COPPER, &gid, 1); + assert(res == 1); + pcb_layer_create(PCB, gid, "top copper", 0); + res = pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_COPPER, &gid, 1); + assert(res == 1); + pcb_layer_create(PCB, gid, "bottom copper", 0); + } + + pcb_layergrp_upgrade_to_pstk(yyPCB); + + sc = pcb_subclist_first(&yyPCB->Data->subc); + if (sc != NULL) { + pcb_layer_create_all_for_recipe(yyPCB, sc->data->Layer, sc->data->LayerN); + pcb_subc_rebind(yyPCB, sc); + pcb_data_clip_polys(sc->data); + } +} + + +int io_pcb_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f) +{ + char line[1024]; + int bad = 0; + +/* + Look for any of these in the top few lines of the file: + # release: pcb-bin 20050609 + PCB["name" 600000 500000] + + or + PCB("name" 600000 500000] +*/ + + while(!(feof(f))) { + if (fgets(line, sizeof(line), f) != NULL) { + char *s = line; + while(isspace(*s)) s++; + if ((strncmp(s, "# release: pcb", 14) == 0) ) + return 1; + if (strncmp(s, "PCB", 3) == 0) { + char *b = s+3; + while(isspace(*b)) b++; + if ((*b == '(') || (*b == '[')) + return 1; + } + if (strncmp(s, "Element", 7) == 0) { + char *b = s+7; + while(isspace(*b)) b++; + if ((*b == '(') || (*b == '[')) + return 1; + } + if ((*s == '\r') || (*s == '\n') || (*s == '#') || (*s == '\0')) /* ignore empty lines and comments */ + continue; + /* non-comment, non-empty line: tolerate at most 16 of these before giving up */ + bad++; + if (bad > 16) + return 0; + } + } + + /* hit eof before finding anything familiar or too many bad lines: the file + is surely not a .pcb */ + return 0; +} + + +rnd_layer_id_t static new_ly_end(pcb_board_t *pcb, const char *name) +{ + rnd_layer_id_t lid; + if (pcb->Data->LayerN >= PCB_MAX_LAYER) + return -1; + lid = pcb->Data->LayerN; + pcb->Data->Layer[lid].name = rnd_strdup(name); + pcb->Data->Layer[lid].parent.data = pcb->Data; + pcb->Data->Layer[lid].parent_type = PCB_PARENT_DATA; + pcb->Data->Layer[lid].type = PCB_OBJ_LAYER; + pcb->Data->LayerN++; + return lid; +} + +rnd_layer_id_t static existing_or_new_ly_end(pcb_board_t *pcb, const char *name) +{ + rnd_layer_id_t lid = pcb_layer_by_name(pcb->Data, name); + if (lid >= 0) { + if (pcb->Data->Layer[lid].meta.real.grp >= 0) { + rnd_layergrp_id_t gid = pcb->Data->Layer[lid].meta.real.grp; + pcb_layergrp_del_layer(pcb, gid, lid); + pcb->Data->Layer[lid].meta.real.grp = -1; + } + return lid; + } + return new_ly_end(pcb, name); +} + +rnd_layer_id_t static new_ly_old(pcb_board_t *pcb, const char *name) +{ + rnd_layer_id_t lid; + for(lid = 0; lid < PCB_MAX_LAYER; lid++) { + if (pcb->Data->Layer[lid].meta.real.grp == 0) { + free((char *)pcb->Data->Layer[lid].name); + pcb->Data->Layer[lid].name = rnd_strdup(name); + pcb->Data->Layer[lid].parent.data = pcb->Data; + pcb->Data->Layer[lid].parent_type = PCB_PARENT_DATA; + pcb->Data->Layer[lid].type = PCB_OBJ_LAYER; + return lid; + } + } + return -1; +} + +int pcb_layer_improvise(pcb_board_t *pcb, rnd_bool setup) +{ + rnd_layergrp_id_t gid; + rnd_layer_id_t lid, silk = -1; + + if (setup) { + pcb_layer_group_setup_default(pcb); + + /* make sure every layer has a name */ + for(lid = 0; lid < pcb->Data->LayerN; lid++) + if (pcb->Data->Layer[lid].name == NULL) + pcb->Data->Layer[lid].name = rnd_strdup_printf("anon_%d", lid); + + for(lid = 0; lid < pcb->Data->LayerN; lid++) { + if (strcmp(pcb->Data->Layer[lid].name, "silk") == 0) { + if (silk < 0) + pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_SILK, &gid, 1); + else + pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_SILK, &gid, 1); + pcb_layer_add_in_group_(pcb, &pcb->LayerGroups.grp[gid], gid, lid); + silk = lid; + } + else { + if (*pcb->Data->Layer[lid].name == '\0') { + free((char *)pcb->Data->Layer[lid].name); + pcb->Data->Layer[lid].name = rnd_strdup("anonymous"); + } + if (lid == 0) + pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_COPPER, &gid, 1); + else + pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_COPPER, &gid, 1); + pcb_layer_add_in_group_(pcb, &pcb->LayerGroups.grp[gid], gid, lid); + } + } + + pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_SILK, &gid, 1); + if (pcb->LayerGroups.grp[gid].len < 1) { + lid = new_ly_end(pcb, "silk"); + if (lid < 0) + return -1; + pcb_layer_add_in_group_(pcb, &pcb->LayerGroups.grp[gid], gid, lid); + } + + pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_SILK, &gid, 1); + if (pcb->LayerGroups.grp[gid].len < 1) { + lid = new_ly_end(pcb, "silk"); + if (lid < 0) + return -1; + pcb_layer_add_in_group_(pcb, &pcb->LayerGroups.grp[gid], gid, lid); + } + + pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_COPPER, &gid, 1); + if (pcb->LayerGroups.grp[gid].len < 1) { + lid = new_ly_old(pcb, "top_copper"); + if (lid < 0) + return -1; + pcb_layer_add_in_group_(pcb, &pcb->LayerGroups.grp[gid], gid, lid); + } + + pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_COPPER, &gid, 1); + if (pcb->LayerGroups.grp[gid].len < 1) { + lid = new_ly_old(pcb, "bottom_copper"); + if (lid < 0) + return -1; + pcb_layer_add_in_group_(pcb, &pcb->LayerGroups.grp[gid], gid, lid); + } + } + + pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_MASK, &gid, 1); + if (pcb->LayerGroups.grp[gid].len < 1) { + lid = existing_or_new_ly_end(pcb, "top-mask"); + if (lid < 0) + return -1; + pcb->Data->Layer[lid].comb = PCB_LYC_AUTO | PCB_LYC_SUB; + pcb_layer_add_in_group_(pcb, &pcb->LayerGroups.grp[gid], gid, lid); + } + + pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_MASK, &gid, 1); + if (pcb->LayerGroups.grp[gid].len < 1) { + lid = existing_or_new_ly_end(pcb, "bottom-mask"); + if (lid < 0) + return -1; + pcb->Data->Layer[lid].comb = PCB_LYC_AUTO | PCB_LYC_SUB; + pcb_layer_add_in_group_(pcb, &pcb->LayerGroups.grp[gid], gid, lid); + } + + pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_PASTE, &gid, 1); + if (pcb->LayerGroups.grp[gid].len < 1) { + lid = existing_or_new_ly_end(pcb, "top-paste"); + if (lid < 0) + return -1; + pcb->Data->Layer[lid].comb = PCB_LYC_AUTO; + pcb_layer_add_in_group_(pcb, &pcb->LayerGroups.grp[gid], gid, lid); + } + + pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_PASTE, &gid, 1); + if (pcb->LayerGroups.grp[gid].len < 1) { + lid = existing_or_new_ly_end(pcb, "bottom-paste"); + if (lid < 0) + return -1; + pcb->Data->Layer[lid].comb = PCB_LYC_AUTO; + pcb_layer_add_in_group_(pcb, &pcb->LayerGroups.grp[gid], gid, lid); + } + +/* rnd_action(&pcb->hidlib, "dumplayers");*/ + + return 0; +} + +/*** Compatibility wrappers: create padstack and subc as if they were vias and elements ***/ + +static int yysubc_bottom; +extern pcb_subc_t *yysubc; +extern rnd_coord_t yysubc_ox, yysubc_oy; + +pcb_subc_t *io_pcb_element_new(pcb_data_t *Data, pcb_subc_t *subc, + pcb_font_t *PCBFont, pcb_flag_t Flags, char *Description, char *NameOnPCB, + char *Value, rnd_coord_t TextX, rnd_coord_t TextY, unsigned int Direction, + int TextScale, pcb_flag_t TextFlags, rnd_bool uniqueName) +{ + pcb_subc_t *sc = pcb_subc_new(); + pcb_text_t *txt; + pcb_subc_reg(Data, sc); + if (Data->padstack_tree == NULL) + Data->padstack_tree = rnd_r_create_tree(); + sc->data->padstack_tree = Data->padstack_tree; + + yysubc_ox = 0; + yysubc_oy = 0; + yysubc_bottom = !!(Flags.f & PCB_FLAG_ONSOLDER); + Flags.f &= ~PCB_FLAG_ONSOLDER; + + PCB_FLAG_SET(Flags.f, sc); + + if (Description != NULL) + pcb_attribute_put(&sc->Attributes, "footprint", Description); + if (NameOnPCB != NULL) + pcb_attribute_put(&sc->Attributes, "refdes", NameOnPCB); + if (Value != NULL) + pcb_attribute_put(&sc->Attributes, "value", Value); + +TODO("subc: TextFlags") + if (!(Flags.f & PCB_FLAG_HIDENAME)) + txt = pcb_subc_add_refdes_text(sc, TextX, TextY, Direction, TextScale, yysubc_bottom); + + if (Flags.f & PCB_FLAG_HIDENAME) { + char tmp[128]; + rnd_sprintf(tmp, "%$mm", TextX); + pcb_attribute_put(&sc->Attributes, "io_pcb::hidename_x", tmp); + rnd_sprintf(tmp, "%$mm", TextY); + pcb_attribute_put(&sc->Attributes, "io_pcb::hidename_y", tmp); + sprintf(tmp, "%d", Direction); + pcb_attribute_put(&sc->Attributes, "io_pcb::hidename_direction", tmp); + sprintf(tmp, "%d", TextScale); + pcb_attribute_put(&sc->Attributes, "io_pcb::hidename_scale", tmp); + } + + return sc; +} + +void io_pcb_element_fin(pcb_data_t *Data) +{ + const char *cent; + + pcb_subc_xy_rot_pnp(yysubc, yysubc_ox, yysubc_oy, yysubc_bottom); + + pcb_subc_bbox(yysubc); + if (Data->subc_tree == NULL) + Data->subc_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Data->subc_tree, (rnd_box_t *)yysubc); +} + +static pcb_layer_t *subc_silk_layer(pcb_subc_t *subc) +{ + pcb_layer_type_t side = yysubc_bottom ? PCB_LYT_BOTTOM : PCB_LYT_TOP; + const char *name = yysubc_bottom ? "bottom-silk" : "top-silk"; + return pcb_subc_get_layer(subc, PCB_LYT_SILK | side, /*PCB_LYC_AUTO*/0, rnd_true, name, rnd_false); +} + +pcb_line_t *io_pcb_element_line_new(pcb_subc_t *subc, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Thickness) +{ + pcb_layer_t *ly = subc_silk_layer(subc); + return pcb_line_new(ly, X1, Y1, X2, Y2, Thickness, 0, pcb_no_flags()); +} + +pcb_arc_t *io_pcb_element_arc_new(pcb_subc_t *subc, rnd_coord_t X, rnd_coord_t Y, + rnd_coord_t Width, rnd_coord_t Height, rnd_angle_t angle, rnd_angle_t delta, rnd_coord_t Thickness) +{ + pcb_layer_t *ly = subc_silk_layer(subc); + return pcb_arc_new(ly, X, Y, Width, Height, angle, delta, Thickness, 0, pcb_no_flags(), rnd_true); +} + +pcb_pstk_t *io_pcb_element_pin_new(pcb_subc_t *subc, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Thickness, rnd_coord_t Clearance, rnd_coord_t Mask, rnd_coord_t DrillingHole, const char *Name, const char *Number, pcb_flag_t Flags) +{ + pcb_pstk_t *p; + p = pcb_old_via_new(subc->data, -1, X, Y, Thickness, Clearance, Mask, DrillingHole, Name, Flags); + if (Number != NULL) + pcb_attribute_put(&p->Attributes, "term", Number); + if (Name != NULL) + pcb_attribute_put(&p->Attributes, "name", Name); + + if (yysubc_bottom) + pcb_pstk_mirror(p, PCB_PSTK_DONT_MIRROR_COORDS, 1, 0, 0); + return p; +} + +pcb_pstk_t *io_pcb_element_pad_new(pcb_subc_t *subc, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Thickness, rnd_coord_t Clearance, rnd_coord_t Mask, const char *Name, const char *Number, pcb_flag_t Flags) +{ + pcb_pstk_t *p; + + p = pcb_pstk_new_compat_pad(subc->data, -1, X1, Y1, X2, Y2, Thickness, Clearance, Mask, Flags.f & PCB_FLAG_SQUARE, Flags.f & PCB_FLAG_NOPASTE, (!!(Flags.f & PCB_FLAG_ONSOLDER)) != yysubc_bottom); + if (Number != NULL) + pcb_attribute_put(&p->Attributes, "term", Number); + if (Name != NULL) + pcb_attribute_put(&p->Attributes, "name", Name); + + if (yysubc_bottom) { + pcb_data_t *old_hack = pcb_pstk_data_hack; + pcb_pstk_data_hack = subc->parent.data; + pcb_pstk_mirror(p, PCB_PSTK_DONT_MIRROR_COORDS, 1, 1, 0); + pcb_pstk_data_hack = old_hack; + } + + return p; +} + +void io_pcb_preproc_board(pcb_board_t *pcb) +{ + int n; + + /* make postproc able to detect layers with broken link */ + for(n = 0; n < PCB_MAX_LAYER; n++) + PCB->Data->Layer[n].meta.real.grp = -1; +} + +void io_pcb_postproc_board(pcb_board_t *pcb) +{ + gdl_iterator_t it; + pcb_subc_t *sc; + int n; + + /* remove empty layer groups */ + for(n = 0; n < pcb->LayerGroups.len; n++) { + if (pcb->LayerGroups.grp[n].len == 0) { + pcb_layergrp_del(pcb, n, 0, 0); + n--; + } + } + + /* check if we have layers that are not present in the group string (broken input) */ + for(n = 0; n < PCB->Data->LayerN; n++) { + if (PCB->Data->Layer[n].meta.real.grp == -1) { + pcb_layergrp_t *grp = pcb_get_grp_new_intern(pcb, -1); + + rnd_message(RND_MSG_WARNING, "Broken input file: layer group string doesn't contain layer %ld\n(Trying to fix it by introducing a new intern copper layer)\n", n); + if (grp != NULL) { + rnd_layergrp_id_t gid = grp - PCB->LayerGroups.grp; + pcb_layer_move_to_group(pcb, n, gid); + } + else + rnd_message(RND_MSG_ERROR, "Failed to add a new layer group - the board in memory IS BROKEN.\n"); + } + } + + pcb_layergrp_create_missing_substrate(pcb); + + for(n = 0; n < pcb->LayerGroups.len; n++) + if ((pcb->LayerGroups.grp[n].ltype & PCB_LYT_COPPER) && (pcb->LayerGroups.grp[n].ltype & PCB_LYT_INTERN)) + pcb_layergrp_fix_old_outline_detect(pcb, &pcb->LayerGroups.grp[n]); + + pcb_layergrp_fix_old_outline(pcb); + + /* have to rebind all subcircuits because the layer stack was not ready + when they got loaded */ + subclist_foreach(&pcb->Data->subc, &it, sc) + pcb_subc_rebind(pcb, sc); + + pcb_layer_colors_from_conf(pcb, 1); + pcb_rat_all_anchor_guess(pcb->Data); +} + +#if !defined(RND_HAS_ATEXIT) +/* makes a temporary copy of the data. This is useful for systems which + * doesn't support calling functions on exit. We use this to save the data + * before LEX and YACC functions are called because they are able to abort + * the program.*/ +void pcb_tmp_data_save(void) +{ + char *fn = rnd_build_fn(&PCB->hidlib, conf_core.rc.emergency_name); + pcb_write_pcb_file(fn, rnd_true, NULL, rnd_true, rnd_false, -1, 0); + if (TMPFilename != NULL) + free(TMPFilename); + TMPFilename = fn; +} + +void pcb_tmp_data_remove(void) +{ + if (TMPFilename != NULL) + unlink(TMPFilename); +} +#endif + + +/* Decide about the type of a footprint file: + - it is a file element if the first non-comment is "Element(" or "Element[" + - else it's not an element. + - if a line of a file element starts with ## and doesn't contain @, it's a tag + - if need_tags is set, tags are saved +*/ +pcb_plug_fp_map_t *io_pcb_map_footprint(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags) +{ + int c, comment_len; + int first_element = 1; + long pos = 0; + enum { + ST_WS, + ST_COMMENT, + ST_ELEMENT, + ST_TAG + } state = ST_WS; + gds_t tag; + + gds_init(&tag); + while ((c = fgetc(f)) != EOF) { + if (pos++ > 1024) break; /* header must be in the first kilobyte */ + switch (state) { + case ST_ELEMENT: + if (isspace(c)) + break; + if ((c == '(') || (c == '[')) { + head->type = PCB_FP_FILE; + goto out; + } + case ST_WS: + if (isspace(c)) + break; + if (c == '#') { + comment_len = 0; + state = ST_COMMENT; + break; + } + else if ((first_element) && (c == 'E')) { + char s[8]; + /* Element */ + fgets(s, 7, f); + s[6] = '\0'; + if (strcmp(s, "lement") == 0) { + state = ST_ELEMENT; + break; + } + } + first_element = 0; + /* fall-thru for detecting @ */ + case ST_COMMENT: + comment_len++; + if ((c == '#') && (comment_len == 1)) { + state = ST_TAG; + break; + } + if ((c == '\r') || (c == '\n')) + state = ST_WS; + break; + case ST_TAG: + if ((c == '\r') || (c == '\n')) { /* end of a tag */ + if (need_tags && (tag.used != 0)) + vts0_append(&head->tags, (char *)pcb_fp_tag(tag.array, 1)); + + tag.used = 0; + state = ST_WS; + break; + } + gds_append(&tag, c); + } + } + +out:; + gds_uninit(&tag); + return head; +} + +/* old outline rules from geda/pcb */ +#define LAYER_IS_OUTLINE(idx) ((pcb->Data->Layer[idx].name != NULL) && ((strcmp(pcb->Data->Layer[idx].name, "route") == 0 || rnd_strcasecmp(pcb->Data->Layer[(idx)].name, "outline") == 0))) + +static int flush_item(const char *s, const char *start, rnd_layer_id_t *lids, int *lids_len, pcb_layer_type_t *loc) +{ + char *end; + rnd_layer_id_t lid; + switch (*start) { + case 'c': case 'C': case 't': case 'T': *loc = PCB_LYT_TOP; break; + case 's': case 'S': case 'b': case 'B': *loc = PCB_LYT_BOTTOM; break; + default: + lid = strtol(start, &end, 10)-1; + if (end != s) + return -1; + if ((*lids_len) >= PCB_MAX_LAYER) + return -1; + lids[*lids_len] = lid; + (*lids_len)++; + } + return 0; +} + +int pcb_layer_parse_group_string(pcb_board_t *pcb, const char *grp_str, int LayerN, int oldfmt) +{ + const char *s, *start; + rnd_layer_id_t lids[PCB_MAX_LAYER]; + int lids_len = 0; + pcb_layer_type_t loc = PCB_LYT_INTERN; + pcb_layergrp_t *g; + int n; + pcb_layer_stack_t *LayerGroup = &pcb->LayerGroups; + + pcb_layergrp_inhibit_inc(); + + /* clear struct */ + pcb_layer_group_setup_default(pcb); + + for(start = s = grp_str; ; s++) { + switch(*s) { + case ',': + if (flush_item(s, start, lids, &lids_len, &loc) != 0) + goto error; + start = s+1; + break; + case '\0': + case ':': + if (flush_item(s, start, lids, &lids_len, &loc) != 0) + goto error; + /* finalize group */ + if (loc & PCB_LYT_INTERN) { + g = pcb_get_grp_new_intern(pcb, -1); + if (g == NULL) { + rnd_message(RND_MSG_ERROR, "pcb_layer_parse_group_string(): unable to insert layer groups for copper\n"); + goto error; + } + } + else { + g = pcb_get_grp(LayerGroup, loc, PCB_LYT_COPPER); + if (g == NULL) { + rnd_message(RND_MSG_ERROR, "pcb_layer_parse_group_string(): unable to insert layer groups for copper\n"); + goto error; + } + } + + for(n = 0; n < lids_len; n++) { + if (lids[n] < 0) + continue; + if (LAYER_IS_OUTLINE(lids[n])) { + if (g->ltype & PCB_LYT_INTERN) { + pcb_layergrp_fix_turn_to_outline(g); + pcb->Data->Layer[lids[n]].comb |= PCB_LYC_AUTO; + } + else + rnd_message(RND_MSG_ERROR, "outline layer can not be on the solder or component side - converting it into a copper layer\n"); + } + if (g == NULL) { + rnd_message(RND_MSG_ERROR, "pcb_layer_parse_group_string(): unable to find copper group for creating the copper layer\n"); + goto error; + } + pcb_layer_add_in_group_(pcb, g, g - LayerGroup->grp, lids[n]); + } + + lids_len = 0; + + /* prepare for next iteration */ + loc = PCB_LYT_INTERN; + start = s+1; + break; + } + if (*s == '\0') + break; + } + + pcb_layergrp_fix_old_outline(pcb); + + /* set the two silks */ + g = pcb_get_grp(LayerGroup, PCB_LYT_BOTTOM, PCB_LYT_SILK); + if (g == NULL) { + rnd_message(RND_MSG_ERROR, "pcb_layer_parse_group_string(): unable to find bottom silk layer group\n"); + goto error; + } + pcb_layer_add_in_group_(pcb, g, g - LayerGroup->grp, LayerN-2); + + + g = pcb_get_grp(LayerGroup, PCB_LYT_TOP, PCB_LYT_SILK); + if (g == NULL) { + rnd_message(RND_MSG_ERROR, "pcb_layer_parse_group_string(): unable to find top silk layer group\n"); + goto error; + } + pcb_layer_add_in_group_(pcb, g, g - LayerGroup->grp, LayerN-1); + + pcb_layergrp_inhibit_dec(); + return 0; + + /* reset structure on error */ +error: + pcb_layergrp_inhibit_dec(); + memset(LayerGroup, 0, sizeof(pcb_layer_stack_t)); + return 1; +} Index: tags/2.3.0/src_plugins/io_pcb/file.h =================================================================== --- tags/2.3.0/src_plugins/io_pcb/file.h (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/file.h (revision 33253) @@ -0,0 +1,109 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_FILE_H +#define PCB_FILE_H + +#include /* needed to define 'FILE *' */ +#include "config.h" +#include "board.h" +#include "plug_io.h" + +/* This is used by the lexer/parser */ +typedef struct { + int ival; + rnd_coord_t bval; + double dval; + char has_units; +} PLMeasure; + +typedef enum { + PCB_USTY_CMIL = 1, /* unitless centimil */ + PCB_USTY_NANOMETER = 2, + PCB_USTY_UNITS = 4 /* using various units */ +} pcb_unit_style_t; + +extern pcb_unit_style_t pcb_io_pcb_usty_seen; + +typedef struct { + const char *write_coord_fmt; +} io_pcb_ctx_t; + +extern pcb_plug_io_t *pcb_preferred_io_pcb, *pcb_nanometer_io_pcb, *pcb_centimil_io_pcb; + +int io_pcb_WritePCB(pcb_plug_io_t *ctx, FILE *f, const char *old_filename, const char *new_filename, rnd_bool emergency); +int io_pcb_write_subcs_head(pcb_plug_io_t *ctx, void **udata, FILE *f, int lib, long num_subcs); +int io_pcb_write_subcs_subc(pcb_plug_io_t *ctx, void **udata, FILE *f, pcb_subc_t *subc); +int io_pcb_write_subcs_tail(pcb_plug_io_t *ctx, void **udata, FILE *f); + + +void PreLoadElementPCB(void); +void PostLoadElementPCB(void); + +int io_pcb_test_parse(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); + +/* + * Whenever the pcb file format is modified, this version number + * should be updated to the date when the new code is committed. + * It will be written out to the file and also used by pcb to give + * guidance to the user as to what the minimum version of pcb required + * is. + */ + +/* This is the version needed by the file we're saving. */ +int PCBFileVersionNeeded(void); + +/* Improvise layers and groups for a partial input file that lacks layer groups (and maybe even some layers) */ +int pcb_layer_improvise(pcb_board_t *pcb, rnd_bool setup); + +pcb_subc_t *io_pcb_element_new(pcb_data_t *Data, pcb_subc_t *Element, pcb_font_t *PCBFont, pcb_flag_t Flags, char *Description, char *NameOnPCB, char *Value, rnd_coord_t TextX, rnd_coord_t TextY, unsigned int Direction, int TextScale, pcb_flag_t TextFlags, rnd_bool uniqueName); +void io_pcb_element_fin(pcb_data_t *Data); +pcb_line_t *io_pcb_element_line_new(pcb_subc_t *subc, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Thickness); +pcb_arc_t *io_pcb_element_arc_new(pcb_subc_t *subc, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Width, rnd_coord_t Height, rnd_angle_t angle, rnd_angle_t delta, rnd_coord_t Thickness); +pcb_pstk_t *io_pcb_element_pin_new(pcb_subc_t *subc, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Thickness, rnd_coord_t Clearance, rnd_coord_t Mask, rnd_coord_t DrillingHole, const char *Name, const char *Number, pcb_flag_t Flags); +pcb_pstk_t *io_pcb_element_pad_new(pcb_subc_t *subc, rnd_coord_t X1, rnd_coord_t Y1, rnd_coord_t X2, rnd_coord_t Y2, rnd_coord_t Thickness, rnd_coord_t Clearance, rnd_coord_t Mask, const char *Name, const char *Number, pcb_flag_t Flags); +void io_pcb_preproc_board(pcb_board_t *pcb); +void io_pcb_postproc_board(pcb_board_t *pcb); + +#ifndef RND_HAS_ATEXIT +void pcb_tmp_data_save(void); +void pcb_tmp_data_remove(void); +#endif + +/* This is the version we support. */ +#define PCB_FILE_VERSION 20110603 + +pcb_plug_fp_map_t *io_pcb_map_footprint(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags); + +/* parses the group definition string which is a colon separated list of + comma separated layer numbers (1,2,b:4,6,8,t); oldfmt is 0 or 1 + depending on PCB() or PCB[] in the file header. */ +int pcb_layer_parse_group_string(pcb_board_t *pcb, const char *s, int LayerN, int oldfmt); + + +#endif Index: tags/2.3.0/src_plugins/io_pcb/io_pcb.c =================================================================== --- tags/2.3.0/src_plugins/io_pcb/io_pcb.c (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/io_pcb.c (revision 33253) @@ -0,0 +1,128 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This module, io_pcb, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include "parse_common.h" +#include "file.h" + +static pcb_plug_io_t io_pcb[3]; +static io_pcb_ctx_t ctx[3]; + +pcb_plug_io_t *pcb_preferred_io_pcb, *pcb_nanometer_io_pcb, *pcb_centimil_io_pcb; + +int io_pcb_fmt(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, int wr, const char *fmt) +{ + if (strcmp(ctx->description, fmt) == 0) + return 200; + + /* All types are supported. */ + if (strcmp(fmt, "pcb") != 0) + return 0; + return 100; /* read-write */ +} + +extern void pcb_lex_destroy(void); +int pplg_check_ver_io_pcb(int ver_needed) { return 0; } + +void pplg_uninit_io_pcb(void) +{ + int n; + pcb_lex_destroy(); + + for(n = 0; n < 3; n++) + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &(io_pcb[n])); +} + +int pplg_init_io_pcb(void) +{ + RND_API_CHK_VER; + + memset(&io_pcb, 0, sizeof(io_pcb)); + + /* register the IO hook */ + ctx[0].write_coord_fmt = rnd_printf_slot[8]; + io_pcb[0].plugin_data = &ctx[0]; + io_pcb[0].fmt_support_prio = io_pcb_fmt; + io_pcb[0].test_parse = io_pcb_test_parse; + io_pcb[0].parse_pcb = io_pcb_ParsePCB; + io_pcb[0].parse_footprint = io_pcb_ParseElement; + io_pcb[0].map_footprint = io_pcb_map_footprint; /* it is enough to have this in [0] so the same checks are not done multiple times, per version */ + io_pcb[0].parse_font = io_pcb_ParseFont; + io_pcb[0].write_buffer = NULL; + io_pcb[0].write_subcs_head = io_pcb_write_subcs_head; + io_pcb[0].write_subcs_subc = io_pcb_write_subcs_subc; + io_pcb[0].write_subcs_tail = io_pcb_write_subcs_tail; + io_pcb[0].write_pcb = io_pcb_WritePCB; + io_pcb[0].default_fmt = "pcb"; + io_pcb[0].description = "geda/pcb - mainline (centimils)"; + io_pcb[0].save_preference_prio = 89; + io_pcb[0].default_extension = ".pcb"; + io_pcb[0].fp_extension = ".fp"; + io_pcb[0].mime_type = "application/x-pcb-layout"; + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &(io_pcb[0])); + pcb_centimil_io_pcb = &io_pcb[0]; + + ctx[1].write_coord_fmt = rnd_printf_slot[9]; + io_pcb[1].plugin_data = &ctx[1]; + io_pcb[1].fmt_support_prio = io_pcb_fmt; + io_pcb[1].write_buffer = NULL; + io_pcb[1].write_subcs_head = io_pcb_write_subcs_head; + io_pcb[1].write_subcs_subc = io_pcb_write_subcs_subc; + io_pcb[1].write_subcs_tail = io_pcb_write_subcs_tail; + io_pcb[1].write_pcb = io_pcb_WritePCB; + io_pcb[1].default_fmt = "pcb"; + io_pcb[1].description = "geda/pcb - readable units"; + io_pcb[1].save_preference_prio = 90; + io_pcb[1].default_extension = ".pcb"; + io_pcb[1].fp_extension = ".fp"; + io_pcb[1].mime_type = "application/x-pcb-layout"; + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &(io_pcb[1])); + pcb_preferred_io_pcb = &io_pcb[1]; + + ctx[2].write_coord_fmt = "%$$mn"; + io_pcb[2].plugin_data = &ctx[2]; + io_pcb[2].fmt_support_prio = io_pcb_fmt; + io_pcb[2].write_buffer = NULL; + io_pcb[2].write_subcs_head = io_pcb_write_subcs_head; + io_pcb[2].write_subcs_subc = io_pcb_write_subcs_subc; + io_pcb[2].write_subcs_tail = io_pcb_write_subcs_tail; + io_pcb[2].write_pcb = io_pcb_WritePCB; + io_pcb[2].default_fmt = "pcb"; + io_pcb[2].description = "geda/pcb - nanometer"; + io_pcb[2].save_preference_prio = 88; + io_pcb[2].default_extension = ".pcb"; + io_pcb[2].fp_extension = ".fp"; + io_pcb[2].mime_type = "application/x-pcb-layout"; + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &(io_pcb[2])); + pcb_nanometer_io_pcb = &io_pcb[2]; + + + return 0; +} Index: tags/2.3.0/src_plugins/io_pcb/io_pcb.pup =================================================================== --- tags/2.3.0/src_plugins/io_pcb/io_pcb.pup (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/io_pcb.pup (revision 33253) @@ -0,0 +1,14 @@ +$class io +$short the original pcb format +$long Load and save the design and footprints in the original gEDA/PCB text format. +$state works +$fmt-native no +$fmt-feature-r gEDA/PCB .pcb board (any version up to 2017) +$fmt-feature-w gEDA/PCB .pcb board (various version up to 2017 ) +$fmt-feature-r gEDA/PCB .fp footprints +$fmt-feature-w gEDA/PCB .fp footprints +$fmt-feature-r gEDA/PCB font +$package io-standard +dep lib_compat_help +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/io_pcb/parse_common.h =================================================================== --- tags/2.3.0/src_plugins/io_pcb/parse_common.h (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/parse_common.h (revision 33253) @@ -0,0 +1,43 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * RCS: $Id$ + */ + +/* just defines common parser identifiers + */ + +#ifndef PCB_LEX_H +#define PCB_LEX_H + +#include "config.h" +#include "plug_io.h" + +int io_pcb_ParsePCB(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest); +int io_pcb_ParseElement(pcb_plug_io_t *ctx, pcb_data_t *, const char *, const char *); +int io_pcb_ParseFont(pcb_plug_io_t *ctx, pcb_font_t *, const char *); + +#endif Index: tags/2.3.0/src_plugins/io_pcb/parse_l.c =================================================================== --- tags/2.3.0/src_plugins/io_pcb/parse_l.c (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/parse_l.c (revision 33253) @@ -0,0 +1,2909 @@ +#line 2 "parse_l.c" + +#line 4 "parse_l.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer pcb__create_buffer +#define yy_delete_buffer pcb__delete_buffer +#define yy_scan_buffer pcb__scan_buffer +#define yy_scan_string pcb__scan_string +#define yy_scan_bytes pcb__scan_bytes +#define yy_init_buffer pcb__init_buffer +#define yy_flush_buffer pcb__flush_buffer +#define yy_load_buffer_state pcb__load_buffer_state +#define yy_switch_to_buffer pcb__switch_to_buffer +#define yypush_buffer_state pcb_push_buffer_state +#define yypop_buffer_state pcb_pop_buffer_state +#define yyensure_buffer_stack pcb_ensure_buffer_stack +#define yy_flex_debug pcb__flex_debug +#define yyin pcb_in +#define yyleng pcb_leng +#define yylex pcb_lex +#define yylineno pcb_lineno +#define yyout pcb_out +#define yyrestart pcb_restart +#define yytext pcb_text +#define yywrap pcb_wrap +#define yyalloc pcb_alloc +#define yyrealloc pcb_realloc +#define yyfree pcb_free + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yy_create_buffer +#define pcb__create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer pcb__create_buffer +#endif + +#ifdef yy_delete_buffer +#define pcb__delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer pcb__delete_buffer +#endif + +#ifdef yy_scan_buffer +#define pcb__scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer pcb__scan_buffer +#endif + +#ifdef yy_scan_string +#define pcb__scan_string_ALREADY_DEFINED +#else +#define yy_scan_string pcb__scan_string +#endif + +#ifdef yy_scan_bytes +#define pcb__scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes pcb__scan_bytes +#endif + +#ifdef yy_init_buffer +#define pcb__init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer pcb__init_buffer +#endif + +#ifdef yy_flush_buffer +#define pcb__flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer pcb__flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define pcb__load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state pcb__load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define pcb__switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer pcb__switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define pcb_push_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state pcb_push_buffer_state +#endif + +#ifdef yypop_buffer_state +#define pcb_pop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state pcb_pop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define pcb_ensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack pcb_ensure_buffer_stack +#endif + +#ifdef yylex +#define pcb_lex_ALREADY_DEFINED +#else +#define yylex pcb_lex +#endif + +#ifdef yyrestart +#define pcb_restart_ALREADY_DEFINED +#else +#define yyrestart pcb_restart +#endif + +#ifdef yylex_init +#define pcb_lex_init_ALREADY_DEFINED +#else +#define yylex_init pcb_lex_init +#endif + +#ifdef yylex_init_extra +#define pcb_lex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra pcb_lex_init_extra +#endif + +#ifdef yylex_destroy +#define pcb_lex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy pcb_lex_destroy +#endif + +#ifdef yyget_debug +#define pcb_get_debug_ALREADY_DEFINED +#else +#define yyget_debug pcb_get_debug +#endif + +#ifdef yyset_debug +#define pcb_set_debug_ALREADY_DEFINED +#else +#define yyset_debug pcb_set_debug +#endif + +#ifdef yyget_extra +#define pcb_get_extra_ALREADY_DEFINED +#else +#define yyget_extra pcb_get_extra +#endif + +#ifdef yyset_extra +#define pcb_set_extra_ALREADY_DEFINED +#else +#define yyset_extra pcb_set_extra +#endif + +#ifdef yyget_in +#define pcb_get_in_ALREADY_DEFINED +#else +#define yyget_in pcb_get_in +#endif + +#ifdef yyset_in +#define pcb_set_in_ALREADY_DEFINED +#else +#define yyset_in pcb_set_in +#endif + +#ifdef yyget_out +#define pcb_get_out_ALREADY_DEFINED +#else +#define yyget_out pcb_get_out +#endif + +#ifdef yyset_out +#define pcb_set_out_ALREADY_DEFINED +#else +#define yyset_out pcb_set_out +#endif + +#ifdef yyget_leng +#define pcb_get_leng_ALREADY_DEFINED +#else +#define yyget_leng pcb_get_leng +#endif + +#ifdef yyget_text +#define pcb_get_text_ALREADY_DEFINED +#else +#define yyget_text pcb_get_text +#endif + +#ifdef yyget_lineno +#define pcb_get_lineno_ALREADY_DEFINED +#else +#define yyget_lineno pcb_get_lineno +#endif + +#ifdef yyset_lineno +#define pcb_set_lineno_ALREADY_DEFINED +#else +#define yyset_lineno pcb_set_lineno +#endif + +#ifdef yywrap +#define pcb_wrap_ALREADY_DEFINED +#else +#define yywrap pcb_wrap +#endif + +#ifdef yyalloc +#define pcb_alloc_ALREADY_DEFINED +#else +#define yyalloc pcb_alloc +#endif + +#ifdef yyrealloc +#define pcb_realloc_ALREADY_DEFINED +#else +#define yyrealloc pcb_realloc +#endif + +#ifdef yyfree +#define pcb_free_ALREADY_DEFINED +#else +#define yyfree pcb_free +#endif + +#ifdef yytext +#define pcb_text_ALREADY_DEFINED +#else +#define yytext pcb_text +#endif + +#ifdef yyleng +#define pcb_leng_ALREADY_DEFINED +#else +#define yyleng pcb_leng +#endif + +#ifdef yyin +#define pcb_in_ALREADY_DEFINED +#else +#define yyin pcb_in +#endif + +#ifdef yyout +#define pcb_out_ALREADY_DEFINED +#else +#define yyout pcb_out +#endif + +#ifdef yy_flex_debug +#define pcb__flex_debug_ALREADY_DEFINED +#else +#define yy_flex_debug pcb__flex_debug +#endif + +#ifdef yylineno +#define pcb_lineno_ALREADY_DEFINED +#else +#define yylineno pcb_lineno +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + #define YY_LINENO_REWIND_TO(dst) \ + do {\ + const char *p;\ + for ( p = yy_cp-1; p >= (dst); --p)\ + if ( *p == '\n' )\ + --yylineno;\ + }while(0) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 56 +#define YY_END_OF_BUFFER 57 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[224] = + { 0, + 0, 0, 57, 55, 52, 53, 54, 55, 51, 55, + 55, 47, 47, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 39, 55, 55, 52, 0, 49, 0, + 51, 50, 0, 47, 47, 46, 0, 47, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 44, 40, 0, + 38, 36, 37, 50, 45, 46, 48, 27, 0, 0, + 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 29, 2, 11, 10, 0, 14, 0, 0, 0, + 0, 0, 12, 0, 0, 0, 0, 43, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 26, 0, 13, + 22, 0, 0, 0, 0, 0, 16, 0, 0, 0, + 42, 0, 41, 0, 0, 0, 0, 0, 8, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 23, 0, 0, 0, + 0, 24, 21, 0, 0, 0, 0, 0, 30, 19, + 0, 28, 0, 25, 0, 0, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 0, 0, 32, 0, + + 33, 35, 0, 0, 0, 0, 15, 0, 0, 18, + 0, 0, 0, 20, 0, 17, 1, 0, 0, 31, + 0, 34, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 5, 6, 1, 1, 1, 7, 1, + 1, 1, 8, 1, 8, 9, 1, 10, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 1, 1, 1, + 1, 1, 1, 1, 12, 13, 14, 15, 16, 17, + 18, 19, 1, 1, 1, 20, 21, 22, 1, 23, + 1, 24, 25, 26, 1, 27, 1, 1, 1, 1, + 1, 28, 1, 1, 29, 1, 30, 31, 32, 33, + + 34, 35, 36, 37, 38, 1, 39, 40, 41, 42, + 43, 44, 1, 45, 46, 47, 48, 1, 1, 49, + 50, 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, 1, 1 + } ; + +static const YY_CHAR yy_meta[51] = + { 0, + 1, 1, 2, 3, 1, 1, 1, 1, 1, 4, + 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, + 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + } ; + +static const flex_int16_t yy_base[229] = + { 0, + 0, 0, 260, 261, 257, 261, 261, 46, 252, 0, + 42, 45, 46, 13, 16, 233, 216, 23, 210, 211, + 32, 223, 218, 52, 35, 21, 38, 213, 217, 36, + 215, 206, 206, 38, 205, 204, 242, 73, 261, 239, + 0, 0, 235, 232, 74, 70, 0, 77, 208, 192, + 196, 192, 222, 201, 194, 203, 53, 192, 181, 188, + 184, 181, 214, 193, 183, 184, 176, 190, 171, 179, + 170, 184, 187, 183, 185, 176, 173, 261, 261, 172, + 261, 261, 173, 0, 261, 82, 0, 261, 165, 167, + 162, 261, 166, 172, 169, 171, 155, 168, 167, 166, + + 160, 178, 261, 261, 261, 147, 261, 149, 155, 163, + 146, 147, 261, 162, 148, 149, 159, 261, 147, 148, + 151, 141, 149, 155, 135, 261, 136, 261, 134, 261, + 261, 140, 77, 147, 142, 132, 261, 133, 141, 136, + 261, 139, 261, 139, 137, 123, 125, 132, 261, 119, + 261, 118, 118, 119, 119, 114, 119, 128, 114, 122, + 112, 106, 106, 261, 105, 106, 261, 103, 115, 106, + 111, 261, 126, 105, 102, 114, 100, 94, 261, 85, + 94, 116, 108, 261, 97, 98, 261, 93, 104, 91, + 98, 86, 92, 89, 93, 261, 85, 74, 261, 68, + + 261, 261, 80, 69, 67, 62, 261, 74, 60, 261, + 72, 62, 71, 261, 57, 261, 261, 63, 61, 261, + 67, 261, 261, 113, 117, 121, 125, 63 + } ; + +static const flex_int16_t yy_def[229] = + { 0, + 223, 1, 223, 223, 223, 223, 223, 224, 225, 226, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 224, 223, 224, + 225, 227, 223, 223, 223, 223, 228, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 227, 223, 223, 228, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 0, 223, 223, 223, 223, 223 + } ; + +static const flex_int16_t yy_nxt[312] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 4, 12, + 13, 14, 4, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 4, 4, 29, + 4, 30, 31, 4, 4, 4, 4, 32, 33, 4, + 34, 35, 4, 4, 4, 4, 4, 36, 4, 4, + 39, 44, 45, 46, 46, 48, 48, 49, 51, 50, + 55, 59, 56, 52, 67, 63, 87, 69, 68, 60, + 70, 71, 75, 40, 72, 80, 76, 39, 81, 86, + 86, 64, 46, 48, 48, 46, 48, 48, 153, 65, + 96, 86, 86, 47, 66, 97, 192, 222, 221, 220, + + 40, 219, 218, 217, 193, 216, 215, 214, 213, 212, + 211, 210, 154, 38, 209, 208, 38, 41, 207, 41, + 41, 43, 206, 43, 43, 84, 205, 84, 84, 204, + 203, 202, 201, 200, 199, 198, 197, 196, 195, 194, + 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, + 181, 180, 179, 178, 177, 176, 175, 174, 173, 172, + 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, + 161, 160, 159, 158, 157, 156, 155, 152, 151, 150, + 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, + 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, + + 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, + 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, + 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, + 99, 98, 95, 94, 93, 92, 91, 90, 89, 88, + 46, 85, 38, 37, 83, 82, 79, 78, 77, 74, + 73, 62, 61, 58, 57, 54, 53, 42, 37, 223, + 3, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223 + } ; + +static const flex_int16_t yy_chk[312] = + { 0, + 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, + 8, 11, 11, 12, 13, 13, 13, 14, 15, 14, + 18, 21, 18, 15, 25, 24, 228, 26, 25, 21, + 26, 27, 30, 8, 27, 34, 30, 38, 34, 46, + 46, 24, 45, 45, 45, 48, 48, 48, 133, 24, + 57, 86, 86, 12, 24, 57, 180, 221, 219, 218, + + 38, 215, 213, 212, 180, 211, 209, 208, 206, 205, + 204, 203, 133, 224, 200, 198, 224, 225, 197, 225, + 225, 226, 195, 226, 226, 227, 194, 227, 227, 193, + 192, 191, 190, 189, 188, 186, 185, 183, 182, 181, + 178, 177, 176, 175, 174, 173, 171, 170, 169, 168, + 166, 165, 163, 162, 161, 160, 159, 158, 157, 156, + 155, 154, 153, 152, 150, 148, 147, 146, 145, 144, + 142, 140, 139, 138, 136, 135, 134, 132, 129, 127, + 125, 124, 123, 122, 121, 120, 119, 117, 116, 115, + 114, 112, 111, 110, 109, 108, 106, 102, 101, 100, + + 99, 98, 97, 96, 95, 94, 93, 91, 90, 89, + 83, 80, 77, 76, 75, 74, 73, 72, 71, 70, + 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, + 59, 58, 56, 55, 54, 53, 52, 51, 50, 49, + 44, 43, 40, 37, 36, 35, 33, 32, 31, 29, + 28, 23, 22, 20, 19, 17, 16, 9, 5, 3, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + + 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, + 223 + } ; + +/* Table of booleans, true if rule could match eol. */ +static const flex_int32_t yy_rule_can_match_eol[57] = + { 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, }; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "parse_l.l" +#line 2 "parse_l.l" +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* lexical definitions to parse ASCII input of geda/pcb PCB and Element + description */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include + +#if defined(_POSIX_SOURCE) || defined(_HPUX_SOURCE) +#include +#endif + +#include "flag_str.h" + +#include "crosshair.h" +#include "data.h" +#include +#include "file.h" +#include "flag_str.h" +#include "parse_common.h" +#include "parse_y.h" +#include "plug_footprint.h" +#include "attribs.h" +#include +#include "obj_common.h" +#include +#include + +#define YY_NO_INPUT + +/* --------------------------------------------------------------------------- + * some shared parser identifiers + */ +#ifdef FLEX_SCANNER + +#define yyunput RND_FUNC_UNUSED yyunput +#endif + +const char *yyfilename; /* in this file */ +pcb_board_t * yyPCB; /* used by parser */ +pcb_data_t * yyData; +pcb_subc_t *yysubc; +rnd_coord_t yysubc_ox, yysubc_oy; +pcb_font_t * yyFont; +rnd_conf_role_t yy_settings_dest; +pcb_flag_t yy_pcb_flags; +int *yyFontkitValid; +int yy_parse_tags; +rnd_bool yyFontReset; +int yyElemFixLayers = 0; + +static int parse_number (void); +static void add_tag(char *line); + +/* --------------------------------------------------------------------------- + * an external prototypes + */ +int yyparse(void); + +static int Parse(FILE *Pipe, const char *Executable, const char *Path, const char *Filename); + +#line 965 "parse_l.c" +#line 966 "parse_l.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + + static void yyunput ( int c, char *buf_ptr ); + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 107 "parse_l.l" + + +#line 1186 "parse_l.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 224 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 261 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + yylineno++; +; + } + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 109 "parse_l.l" +{ return(T_FILEVERSION); } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 110 "parse_l.l" +{ return(T_PCB); } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 111 "parse_l.l" +{ return(T_GRID); } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 112 "parse_l.l" +{ return(T_CURSOR); } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 113 "parse_l.l" +{ return(T_THERMAL); } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 114 "parse_l.l" +{ return(T_AREA); } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 115 "parse_l.l" +{ return(T_DRC); } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 116 "parse_l.l" +{ return(T_FLAGS); } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 117 "parse_l.l" +{ return(T_LAYER); } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 118 "parse_l.l" +{ return(T_PIN); } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 119 "parse_l.l" +{ return(T_PAD); } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 120 "parse_l.l" +{ return(T_VIA); } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 121 "parse_l.l" +{ return(T_LINE); } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 122 "parse_l.l" +{ return(T_RAT); } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 123 "parse_l.l" +{ return(T_RECTANGLE); } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 124 "parse_l.l" +{ return(T_TEXT); } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 125 "parse_l.l" +{ return(T_ELEMENTLINE); } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 126 "parse_l.l" +{ return(T_ELEMENTARC); } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 127 "parse_l.l" +{ return(T_ELEMENT); } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 128 "parse_l.l" +{ return(T_SYMBOLLINE); } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 129 "parse_l.l" +{ return(T_SYMBOL); } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 130 "parse_l.l" +{ return(T_MARK); } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 131 "parse_l.l" +{ return(T_GROUPS); } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 132 "parse_l.l" +{ return(T_STYLES); } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 133 "parse_l.l" +{ return(T_POLYGON); } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 134 "parse_l.l" +{ return(T_POLYGON_HOLE); } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 135 "parse_l.l" +{ return(T_ARC); } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 136 "parse_l.l" +{ return(T_NETLIST); } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 137 "parse_l.l" +{ return(T_NET); } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 138 "parse_l.l" +{ return(T_CONN); } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 139 "parse_l.l" +{ return(T_NETLISTPATCH); } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 140 "parse_l.l" +{ return(T_ADD_CONN); } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 141 "parse_l.l" +{ return(T_DEL_CONN); } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 142 "parse_l.l" +{ return(T_CHANGE_ATTRIB); } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 143 "parse_l.l" +{ return(T_ATTRIBUTE); } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 145 "parse_l.l" +{ return T_NM; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 146 "parse_l.l" +{ return T_UM; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 147 "parse_l.l" +{ return T_MM; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 148 "parse_l.l" +{ return T_M; } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 149 "parse_l.l" +{ return T_KM; } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 150 "parse_l.l" +{ return T_UMIL; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 151 "parse_l.l" +{ return T_CMIL; } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 152 "parse_l.l" +{ return T_MIL; } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 153 "parse_l.l" +{ return T_IN; } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 155 "parse_l.l" +{ + pcb_lval.integer = (unsigned) *(yytext+1); + return(CHAR_CONST); + } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 159 "parse_l.l" +{ return parse_number(); } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 160 "parse_l.l" +{ pcb_lval.integer = rnd_round(strtod (yytext, NULL)); return INTEGER; } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 162 "parse_l.l" +{ unsigned n; + sscanf((char *) yytext, "%x", &n); + pcb_lval.integer = n; + return INTEGER; + } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 167 "parse_l.l" +{ + char *p1, *p2; + + /* return NULL on empty string */ + if (yyleng == 2) + { + pcb_lval.string = NULL; + return(STRING); + } + + /* allocate memory and copy string; + * stringlength is counted and copied without + * leading and trailing '"' + */ + yyleng -= 2; + pcb_lval.string = (char *)calloc (yyleng+1, sizeof (char)); + p1 = (char *) (yytext +1); + p2 = pcb_lval.string; + while(yyleng--) + { + /* check for special character */ + if (*p1 == '\\') + { + yyleng--; + p1++; + + } + *p2++ = *p1++; + } + *p2 = '\0'; + return(STRING); + } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 199 "parse_l.l" +{ if (yy_parse_tags) { add_tag(yytext); }} + YY_BREAK +case 51: +YY_RULE_SETUP +#line 200 "parse_l.l" +{} + YY_BREAK +case 52: +YY_RULE_SETUP +#line 201 "parse_l.l" +{} + YY_BREAK +case 53: +/* rule 53 can match eol */ +YY_RULE_SETUP +#line 202 "parse_l.l" +{ +#ifndef FLEX_SCANNER + yylineno++; +#endif + } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 207 "parse_l.l" +{} + YY_BREAK +case 55: +YY_RULE_SETUP +#line 208 "parse_l.l" +{ return(*yytext); } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 210 "parse_l.l" +ECHO; + YY_BREAK +#line 1576 "parse_l.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 224 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 224 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 223); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + + static void yyunput (int c, char * yy_bp ) +{ + char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + int number_to_move = (yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + if ( c == '\n' ){ + --yylineno; + } + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + if ( c == '\n' ) + + yylineno++; +; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + /* We do not touch yylineno unless the option is enabled. */ + yylineno = 1; + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 210 "parse_l.l" + + +/* sets up the preprocessor command */ +static int Parse(FILE *Pipe, const char *Executable, const char *Path, const char *Filename) +{ + static char *command = NULL; + int returncode; + int used_popen = 0; + char *tmps; + size_t l; +#ifdef FLEX_SCANNER + static rnd_bool firsttime = rnd_true; +#endif + pcb_io_pcb_usty_seen = 0; + if (Pipe == NULL) { + if (RND_EMPTY_STRING_P(Executable)) { + l = 2; + if (Path != NULL) + l += strlen(Path); + + l += strlen(Filename); + + if ((tmps = (char *)malloc(l * sizeof(char))) == NULL) { + fprintf(stderr, "Parse(): malloc failed\n"); + exit(1); + } + + if (Path != NULL && *Path != '\0') + sprintf(tmps, "%s%s%s", Path, RND_DIR_SEPARATOR_S, Filename); + else + sprintf(tmps, "%s", Filename); + + yyin = rnd_fopen(NULL, tmps, "r"); + if (!yyin) { + free(tmps); + return (1); + } + free(tmps); + } + else { + rnd_build_argfn_t p; + used_popen = 1; + memset(&p, 0, sizeof(p)); + p.params['p' - 'a'] = Path; + p.params['f' - 'a'] = Filename; + p.hidlib = &PCB->hidlib; + command = rnd_build_argfn(Executable, &p); + /* open pipe to stdout of command */ + if (*command == '\0' || (yyin = rnd_popen(NULL, command, "r")) == NULL) { + rnd_popen_error_message(command); + free(command); + return (1); + } + free(command); + } + } + else { + yyin = Pipe; + } + +#ifdef FLEX_SCANNER + /* reset parser if not called the first time */ + if (!firsttime) + yyrestart(yyin); + firsttime = rnd_false; +#endif + + /* init linenumber and filename for yyerror() */ + yylineno = 1; + yyfilename = Filename; + + /* We need to save the data temporarily because lex-yacc are able + * to break the application if the input file has an illegal format. + * It's not necessary if the system supports the call of functions + * on termination. + */ + + pcb_create_be_lenient(rnd_true); + +#if !defined(RND_HAS_ATEXIT) + if (PCB && PCB->Data) + pcb_tmp_data_save(); + returncode = pcb_parse(); + pcb_tmp_data_remove(); +#else + returncode = pcb_parse(); +#endif + /* clean up parse buffer */ + yy_delete_buffer(YY_CURRENT_BUFFER); + + pcb_create_be_lenient(rnd_false); + + if (Pipe != NULL) + return returncode; + + if (used_popen) + return (rnd_pclose(yyin) ? 1 : returncode); + return (fclose(yyin) ? 1 : returncode); +} + +/* --------------------------------------------------------------------------- + * initializes LEX and calls parser for a single element file + */ +int io_pcb_ParseElement(pcb_plug_io_t *ctx, pcb_data_t *Ptr, const char *name, const char *subfpname) +{ + FILE *f; + int ret; + pcb_fp_fopen_ctx_t st; + + f = pcb_fp_fopen(&conf_core.rc.library_search_paths, name, &st, NULL); + + /* set up the yy globals only after the pcb_fp_fopen() because it can + also call Parse */ + yy_parse_tags = 0; + yy_settings_dest = RND_CFR_invalid; + yyPCB = NULL; + yyData = Ptr; + pcb_data_set_layer_parents(Ptr); + yyFont = pcb_font(PCB, 0, 1); + yyFontReset = rnd_false; + yyFontkitValid = NULL; + yysubc = NULL; + yyElemFixLayers = 1; + + + if (f == NULL) { + pcb_fp_fclose(f, &st); + return -1; + } + + ret = Parse(f, NULL,NULL,NULL); + + yyElemFixLayers = 0; + + pcb_fp_fclose(f, &st); + + return(ret); +} + +/* --------------------------------------------------------------------------- + * initializes LEX and calls parser for a complete board + */ +#define TEST_FLAG_LOCAL(F,FLG) (((FLG) & (F)) ? 1 : 0) +#define CONF_BOOL_FLAG(F,FLG) (TEST_FLAG_LOCAL(F,FLG.f) ? "true" : "false") + +/* Hack: set a no-save-attribute flag while loading some fields from the file; + because we have all these flags set we won't need to list the paths that + have hardwired flags again in a "don't save these in attributes" list. */ +#define CONF_NO_ATTRIB(path) \ +do { \ + rnd_conf_native_t *n = rnd_conf_get_field(path); \ + if (n != NULL) \ + n->random_flags.io_pcb_no_attrib = 1; \ +} while(0) \ + +#define CONF_SET(target, path, arr_idx, new_val, pol) \ +do { \ + CONF_NO_ATTRIB(path); \ + rnd_conf_set(target, path, arr_idx, new_val, pol); \ +} while(0) \ + +int io_pcb_ParsePCB(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest) +{ + int retval; + const char *fcmd; + yy_parse_tags = 0; + yyPCB = Ptr; + yyData = NULL; + yyFont = NULL; + yyFontReset = rnd_true; + yyFontkitValid = NULL; + yysubc = NULL; + yy_settings_dest = settings_dest; + + if (settings_dest != RND_CFR_invalid) + rnd_conf_reset(settings_dest, Filename); + + io_pcb_preproc_board(PCB); + + pcb_data_clip_inhibit_inc(PCB->Data); + fcmd = conf_core.rc.file_command; + retval = Parse(NULL, fcmd, conf_core.rc.file_path, Filename); + + if ((settings_dest != RND_CFR_invalid) && (retval == 0)) { + /* overwrite settings from the flags, mark them not-to-save */ + rnd_conf_reset(settings_dest, ""); + rnd_conf_main_root_replace_cnt[settings_dest]++; + CONF_SET(settings_dest, "plugins/mincut/enable", -1, CONF_BOOL_FLAG(PCB_ENABLEPCB_FLAG_MINCUT, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/show_number", -1, CONF_BOOL_FLAG(PCB_SHOWNUMBERFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/show_drc", -1, CONF_BOOL_FLAG(PCB_SHOWPCB_FLAG_DRC, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/rubber_band_mode", -1, CONF_BOOL_FLAG(PCB_RUBBERBANDFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/auto_drc", -1, CONF_BOOL_FLAG(PCB_AUTOPCB_FLAG_DRC, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/all_direction_lines", -1, CONF_BOOL_FLAG(PCB_ALLDIRECTIONFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/swap_start_direction", -1, CONF_BOOL_FLAG(PCB_SWAPSTARTDIRFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/unique_names", -1, CONF_BOOL_FLAG(PCB_UNIQUENAMEFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/clear_line", -1, CONF_BOOL_FLAG(PCB_CLEARNEWFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/full_poly", -1, CONF_BOOL_FLAG(PCB_NEWPCB_FLAG_FULLPOLY, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/snap_pin", -1, CONF_BOOL_FLAG(PCB_SNAPPCB_FLAG_PIN, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/orthogonal_moves", -1, CONF_BOOL_FLAG(PCB_ORTHOMOVEFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/live_routing", -1, CONF_BOOL_FLAG(PCB_LIVEROUTEFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/lock_names", -1, CONF_BOOL_FLAG(PCB_LOCKNAMESFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/only_names", -1, CONF_BOOL_FLAG(PCB_ONLYNAMESFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/hide_names", -1, CONF_BOOL_FLAG(PCB_HIDENAMESFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/thin_draw", -1, CONF_BOOL_FLAG(PCB_THINDRAWFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/thin_draw_poly", -1, CONF_BOOL_FLAG(PCB_THINDRAWPOLYFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/local_ref", -1, CONF_BOOL_FLAG(PCB_LOCALREFFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/check_planes", -1, CONF_BOOL_FLAG(PCB_CHECKPLANESFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/description", -1, CONF_BOOL_FLAG(PCB_DESCRIPTIONFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/name_on_pcb", -1, CONF_BOOL_FLAG(PCB_NAMEONPCBFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + + /* don't save this because it is saved manually as PCB::grid::unit */ + CONF_NO_ATTRIB("editor/grid_unit"); + + /* don't save these to reduce noise - they are reset by the GUI anyway */ + CONF_NO_ATTRIB("editor/mode"); + + /* it's saved in [styles] */ + CONF_NO_ATTRIB("design/routes"); + + /* load config nodes not disabled above, from optional attributes */ + io_pcb_attrib_a2c(Ptr); + + rnd_conf_update(NULL, -1); + } + if (retval == 0) { + /* restore loader so the next save will use the same units */ + const char *loader = pcb_attribute_get(&PCB->Attributes, "PCB::loader"); + if (loader != NULL) { + pcb_find_io_t f; + int len; + + len = pcb_find_io(&f, 1, PCB_IOT_PCB, 1, loader); +/* printf("PCB::loader: %s -> %d\n", loader, len);*/ + if (len > 0) { +/* printf(" ::loader: '%s'\n", f.plug->description);*/ + PCB->Data->loader = f.plug; + } + } + else { + /* Loaded a file that did not have any information about preferred format */ + switch((int)pcb_io_pcb_usty_seen) { + case PCB_USTY_CMIL: + rnd_message(RND_MSG_INFO, "No preferred unit format info available for '%s' - will use '%s' on save (guessed from consistent unitless centimil input)\n", Filename, pcb_centimil_io_pcb->description); + PCB->Data->loader = pcb_centimil_io_pcb; + break; + case PCB_USTY_NANOMETER: + rnd_message(RND_MSG_INFO, "No preferred unit format info available for '%s' - will use '%s' on save (guessed from consistent nanometer input)\n", Filename, pcb_nanometer_io_pcb->description); + PCB->Data->loader = pcb_nanometer_io_pcb; + break; + case PCB_USTY_UNITS: + case PCB_USTY_UNITS | PCB_USTY_NANOMETER: + rnd_message(RND_MSG_INFO, "No preferred unit format info available for '%s' - will use '%s' on save (guessed from non-nanometer explicit unit usage)\n", Filename, pcb_preferred_io_pcb->description); + PCB->Data->loader = pcb_preferred_io_pcb; + break; + default: + rnd_message(RND_MSG_WARNING, "No preferred unit format info available and guessing failed for '%s' - will use '%s' on save\n", Filename, pcb_preferred_io_pcb->description); + PCB->Data->loader = pcb_preferred_io_pcb; + } + } + } + pcb_layer_auto_fixup(PCB); + io_pcb_postproc_board(PCB); + pcb_data_clip_inhibit_dec(PCB->Data, 1); + return retval; +} + +/* --------------------------------------------------------------------------- + * initializes LEX and calls parser for a font + */ +int io_pcb_ParseFont(pcb_plug_io_t *ctx, pcb_font_t *Ptr, const char *Filename) +{ + int r = 0, valid; + const char *fcmd; + yy_parse_tags = 1; + yyPCB = NULL; + yyFont = Ptr; + yyFontkitValid = &valid; + yysubc = NULL; + yyFontReset = rnd_false; + + yy_settings_dest = RND_CFR_invalid; + fcmd = conf_core.rc.font_command; + r = Parse(NULL, fcmd, NULL, Filename); + if (r == 0) { +#ifdef DEBUG + rnd_message(RND_MSG_DEBUG, "Found %s in %s\n", Filename, conf_core.rc.font_command); +#endif + } + return r; +} + +static int +parse_number () +{ + pcb_lval.number = strtod ((char *) yytext, NULL); + return FLOATING; +} + +static void add_tag(char *line) +{ + char *key, *val; + while((*line == '#') || isspace(*line)) line++; + key = line; + val = strchr(line, ':'); + if (val != NULL) { + *val = '\0'; + val++; + } + if (yyFont != NULL) { +/* printf("tag:%s=%s:\n", key,val); */ + if (strcmp(key, "name") == 0) { + free(yyFont->name); + yyFont->name = rnd_strdup(val); + } + } +} + + Index: tags/2.3.0/src_plugins/io_pcb/parse_l.h =================================================================== --- tags/2.3.0/src_plugins/io_pcb/parse_l.h (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/parse_l.h (revision 33253) @@ -0,0 +1,708 @@ +#ifndef pcb_HEADER_H +#define pcb_HEADER_H 1 +#define pcb_IN_HEADER 1 + +#line 6 "parse_l.h" + +#line 8 "parse_l.h" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yy_create_buffer +#define pcb__create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer pcb__create_buffer +#endif + +#ifdef yy_delete_buffer +#define pcb__delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer pcb__delete_buffer +#endif + +#ifdef yy_scan_buffer +#define pcb__scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer pcb__scan_buffer +#endif + +#ifdef yy_scan_string +#define pcb__scan_string_ALREADY_DEFINED +#else +#define yy_scan_string pcb__scan_string +#endif + +#ifdef yy_scan_bytes +#define pcb__scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes pcb__scan_bytes +#endif + +#ifdef yy_init_buffer +#define pcb__init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer pcb__init_buffer +#endif + +#ifdef yy_flush_buffer +#define pcb__flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer pcb__flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define pcb__load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state pcb__load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define pcb__switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer pcb__switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define pcb_push_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state pcb_push_buffer_state +#endif + +#ifdef yypop_buffer_state +#define pcb_pop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state pcb_pop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define pcb_ensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack pcb_ensure_buffer_stack +#endif + +#ifdef yylex +#define pcb_lex_ALREADY_DEFINED +#else +#define yylex pcb_lex +#endif + +#ifdef yyrestart +#define pcb_restart_ALREADY_DEFINED +#else +#define yyrestart pcb_restart +#endif + +#ifdef yylex_init +#define pcb_lex_init_ALREADY_DEFINED +#else +#define yylex_init pcb_lex_init +#endif + +#ifdef yylex_init_extra +#define pcb_lex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra pcb_lex_init_extra +#endif + +#ifdef yylex_destroy +#define pcb_lex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy pcb_lex_destroy +#endif + +#ifdef yyget_debug +#define pcb_get_debug_ALREADY_DEFINED +#else +#define yyget_debug pcb_get_debug +#endif + +#ifdef yyset_debug +#define pcb_set_debug_ALREADY_DEFINED +#else +#define yyset_debug pcb_set_debug +#endif + +#ifdef yyget_extra +#define pcb_get_extra_ALREADY_DEFINED +#else +#define yyget_extra pcb_get_extra +#endif + +#ifdef yyset_extra +#define pcb_set_extra_ALREADY_DEFINED +#else +#define yyset_extra pcb_set_extra +#endif + +#ifdef yyget_in +#define pcb_get_in_ALREADY_DEFINED +#else +#define yyget_in pcb_get_in +#endif + +#ifdef yyset_in +#define pcb_set_in_ALREADY_DEFINED +#else +#define yyset_in pcb_set_in +#endif + +#ifdef yyget_out +#define pcb_get_out_ALREADY_DEFINED +#else +#define yyget_out pcb_get_out +#endif + +#ifdef yyset_out +#define pcb_set_out_ALREADY_DEFINED +#else +#define yyset_out pcb_set_out +#endif + +#ifdef yyget_leng +#define pcb_get_leng_ALREADY_DEFINED +#else +#define yyget_leng pcb_get_leng +#endif + +#ifdef yyget_text +#define pcb_get_text_ALREADY_DEFINED +#else +#define yyget_text pcb_get_text +#endif + +#ifdef yyget_lineno +#define pcb_get_lineno_ALREADY_DEFINED +#else +#define yyget_lineno pcb_get_lineno +#endif + +#ifdef yyset_lineno +#define pcb_set_lineno_ALREADY_DEFINED +#else +#define yyset_lineno pcb_set_lineno +#endif + +#ifdef yywrap +#define pcb_wrap_ALREADY_DEFINED +#else +#define yywrap pcb_wrap +#endif + +#ifdef yyalloc +#define pcb_alloc_ALREADY_DEFINED +#else +#define yyalloc pcb_alloc +#endif + +#ifdef yyrealloc +#define pcb_realloc_ALREADY_DEFINED +#else +#define yyrealloc pcb_realloc +#endif + +#ifdef yyfree +#define pcb_free_ALREADY_DEFINED +#else +#define yyfree pcb_free +#endif + +#ifdef yytext +#define pcb_text_ALREADY_DEFINED +#else +#define yytext pcb_text +#endif + +#ifdef yyleng +#define pcb_leng_ALREADY_DEFINED +#else +#define yyleng pcb_leng +#endif + +#ifdef yyin +#define pcb_in_ALREADY_DEFINED +#else +#define yyin pcb_in +#endif + +#ifdef yyout +#define pcb_out_ALREADY_DEFINED +#else +#define yyout pcb_out +#endif + +#ifdef yy_flex_debug +#define pcb__flex_debug_ALREADY_DEFINED +#else +#define yy_flex_debug pcb__flex_debug +#endif + +#ifdef yylineno +#define pcb_lineno_ALREADY_DEFINED +#else +#define yylineno pcb_lineno +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +/* Begin user sect3 */ + +extern int yylineno; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define INITIAL 0 + +#endif + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +#ifndef pcb__create_buffer_ALREADY_DEFINED +#undef yy_create_buffer +#endif +#ifndef pcb__delete_buffer_ALREADY_DEFINED +#undef yy_delete_buffer +#endif +#ifndef pcb__scan_buffer_ALREADY_DEFINED +#undef yy_scan_buffer +#endif +#ifndef pcb__scan_string_ALREADY_DEFINED +#undef yy_scan_string +#endif +#ifndef pcb__scan_bytes_ALREADY_DEFINED +#undef yy_scan_bytes +#endif +#ifndef pcb__init_buffer_ALREADY_DEFINED +#undef yy_init_buffer +#endif +#ifndef pcb__flush_buffer_ALREADY_DEFINED +#undef yy_flush_buffer +#endif +#ifndef pcb__load_buffer_state_ALREADY_DEFINED +#undef yy_load_buffer_state +#endif +#ifndef pcb__switch_to_buffer_ALREADY_DEFINED +#undef yy_switch_to_buffer +#endif +#ifndef pcb_push_buffer_state_ALREADY_DEFINED +#undef yypush_buffer_state +#endif +#ifndef pcb_pop_buffer_state_ALREADY_DEFINED +#undef yypop_buffer_state +#endif +#ifndef pcb_ensure_buffer_stack_ALREADY_DEFINED +#undef yyensure_buffer_stack +#endif +#ifndef pcb_lex_ALREADY_DEFINED +#undef yylex +#endif +#ifndef pcb_restart_ALREADY_DEFINED +#undef yyrestart +#endif +#ifndef pcb_lex_init_ALREADY_DEFINED +#undef yylex_init +#endif +#ifndef pcb_lex_init_extra_ALREADY_DEFINED +#undef yylex_init_extra +#endif +#ifndef pcb_lex_destroy_ALREADY_DEFINED +#undef yylex_destroy +#endif +#ifndef pcb_get_debug_ALREADY_DEFINED +#undef yyget_debug +#endif +#ifndef pcb_set_debug_ALREADY_DEFINED +#undef yyset_debug +#endif +#ifndef pcb_get_extra_ALREADY_DEFINED +#undef yyget_extra +#endif +#ifndef pcb_set_extra_ALREADY_DEFINED +#undef yyset_extra +#endif +#ifndef pcb_get_in_ALREADY_DEFINED +#undef yyget_in +#endif +#ifndef pcb_set_in_ALREADY_DEFINED +#undef yyset_in +#endif +#ifndef pcb_get_out_ALREADY_DEFINED +#undef yyget_out +#endif +#ifndef pcb_set_out_ALREADY_DEFINED +#undef yyset_out +#endif +#ifndef pcb_get_leng_ALREADY_DEFINED +#undef yyget_leng +#endif +#ifndef pcb_get_text_ALREADY_DEFINED +#undef yyget_text +#endif +#ifndef pcb_get_lineno_ALREADY_DEFINED +#undef yyget_lineno +#endif +#ifndef pcb_set_lineno_ALREADY_DEFINED +#undef yyset_lineno +#endif +#ifndef pcb_get_column_ALREADY_DEFINED +#undef yyget_column +#endif +#ifndef pcb_set_column_ALREADY_DEFINED +#undef yyset_column +#endif +#ifndef pcb_wrap_ALREADY_DEFINED +#undef yywrap +#endif +#ifndef pcb_get_lval_ALREADY_DEFINED +#undef yyget_lval +#endif +#ifndef pcb_set_lval_ALREADY_DEFINED +#undef yyset_lval +#endif +#ifndef pcb_get_lloc_ALREADY_DEFINED +#undef yyget_lloc +#endif +#ifndef pcb_set_lloc_ALREADY_DEFINED +#undef yyset_lloc +#endif +#ifndef pcb_alloc_ALREADY_DEFINED +#undef yyalloc +#endif +#ifndef pcb_realloc_ALREADY_DEFINED +#undef yyrealloc +#endif +#ifndef pcb_free_ALREADY_DEFINED +#undef yyfree +#endif +#ifndef pcb_text_ALREADY_DEFINED +#undef yytext +#endif +#ifndef pcb_leng_ALREADY_DEFINED +#undef yyleng +#endif +#ifndef pcb_in_ALREADY_DEFINED +#undef yyin +#endif +#ifndef pcb_out_ALREADY_DEFINED +#undef yyout +#endif +#ifndef pcb__flex_debug_ALREADY_DEFINED +#undef yy_flex_debug +#endif +#ifndef pcb_lineno_ALREADY_DEFINED +#undef yylineno +#endif +#ifndef pcb_tables_fload_ALREADY_DEFINED +#undef yytables_fload +#endif +#ifndef pcb_tables_destroy_ALREADY_DEFINED +#undef yytables_destroy +#endif +#ifndef pcb_TABLES_NAME_ALREADY_DEFINED +#undef yyTABLES_NAME +#endif + +#line 210 "parse_l.l" + + +#line 707 "parse_l.h" +#undef pcb_IN_HEADER +#endif /* pcb_HEADER_H */ Index: tags/2.3.0/src_plugins/io_pcb/parse_l.l =================================================================== --- tags/2.3.0/src_plugins/io_pcb/parse_l.l (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/parse_l.l (revision 33253) @@ -0,0 +1,525 @@ +%{ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* lexical definitions to parse ASCII input of geda/pcb PCB and Element + description */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include + +#if defined(_POSIX_SOURCE) || defined(_HPUX_SOURCE) +#include +#endif + +#include "flag_str.h" + +#include "crosshair.h" +#include "data.h" +#include +#include "file.h" +#include "flag_str.h" +#include "parse_common.h" +#include "parse_y.h" +#include "plug_footprint.h" +#include "attribs.h" +#include +#include "obj_common.h" +#include +#include + +#define YY_NO_INPUT + +/* --------------------------------------------------------------------------- + * some shared parser identifiers + */ +#ifdef FLEX_SCANNER + +#define yyunput RND_FUNC_UNUSED yyunput +#endif + +const char *yyfilename; /* in this file */ +pcb_board_t * yyPCB; /* used by parser */ +pcb_data_t * yyData; +pcb_subc_t *yysubc; +rnd_coord_t yysubc_ox, yysubc_oy; +pcb_font_t * yyFont; +rnd_conf_role_t yy_settings_dest; +pcb_flag_t yy_pcb_flags; +int *yyFontkitValid; +int yy_parse_tags; +rnd_bool yyFontReset; +int yyElemFixLayers = 0; + +static int parse_number (void); +static void add_tag(char *line); + +/* --------------------------------------------------------------------------- + * an external prototypes + */ +int yyparse(void); + +static int Parse(FILE *Pipe, const char *Executable, const char *Path, const char *Filename); + +%} + +%option prefix="pcb_" + + +HEX 0x[0-9a-fA-F]+ +INTEGER [+-]?([1-9][0-9]*|0) +FLOATING {INTEGER}"."[0-9]* +STRINGCHAR ([^"\n\r\\]|\\.) + +%option yylineno + +%% + +FileVersion { return(T_FILEVERSION); } +PCB { return(T_PCB); } +Grid { return(T_GRID); } +Cursor { return(T_CURSOR); } +Thermal { return(T_THERMAL); } +PolyArea { return(T_AREA); } +DRC { return(T_DRC); } +Flags { return(T_FLAGS); } +Layer { return(T_LAYER); } +Pin { return(T_PIN); } +Pad { return(T_PAD); } +Via { return(T_VIA); } +Line { return(T_LINE); } +Rat { return(T_RAT); } +Rectangle { return(T_RECTANGLE); } +Text { return(T_TEXT); } +ElementLine { return(T_ELEMENTLINE); } +ElementArc { return(T_ELEMENTARC); } +Element { return(T_ELEMENT); } +SymbolLine { return(T_SYMBOLLINE); } +Symbol { return(T_SYMBOL); } +Mark { return(T_MARK); } +Groups { return(T_GROUPS); } +Styles { return(T_STYLES); } +Polygon { return(T_POLYGON); } +Hole { return(T_POLYGON_HOLE); } +Arc { return(T_ARC); } +NetList { return(T_NETLIST); } +Net { return(T_NET); } +Connect { return(T_CONN); } +NetListPatch { return(T_NETLISTPATCH); } +add_conn { return(T_ADD_CONN); } +del_conn { return(T_DEL_CONN); } +change_attrib { return(T_CHANGE_ATTRIB); } +Attribute { return(T_ATTRIBUTE); } + +nm { return T_NM; } +um { return T_UM; } +mm { return T_MM; } +m { return T_M; } +km { return T_KM; } +umil { return T_UMIL; } +cmil { return T_CMIL; } +mil { return T_MIL; } +in { return T_IN; } + +\'.\' { + pcb_lval.integer = (unsigned) *(yytext+1); + return(CHAR_CONST); + } +{FLOATING} { return parse_number(); } +{INTEGER} { pcb_lval.integer = rnd_round(strtod (yytext, NULL)); return INTEGER; } + +{HEX} { unsigned n; + sscanf((char *) yytext, "%x", &n); + pcb_lval.integer = n; + return INTEGER; + } +\"{STRINGCHAR}*\" { + char *p1, *p2; + + /* return NULL on empty string */ + if (yyleng == 2) + { + pcb_lval.string = NULL; + return(STRING); + } + + /* allocate memory and copy string; + * stringlength is counted and copied without + * leading and trailing '"' + */ + yyleng -= 2; + pcb_lval.string = (char *)calloc (yyleng+1, sizeof (char)); + p1 = (char *) (yytext +1); + p2 = pcb_lval.string; + while(yyleng--) + { + /* check for special character */ + if (*p1 == '\\') + { + yyleng--; + p1++; + + } + *p2++ = *p1++; + } + *p2 = '\0'; + return(STRING); + } +##.* { if (yy_parse_tags) { add_tag(yytext); }} +#.* {} +[ \t]+ {} +[\n] { +#ifndef FLEX_SCANNER + yylineno++; +#endif + } +[\r] {} +. { return(*yytext); } + +%% + +/* sets up the preprocessor command */ +static int Parse(FILE *Pipe, const char *Executable, const char *Path, const char *Filename) +{ + static char *command = NULL; + int returncode; + int used_popen = 0; + char *tmps; + size_t l; +#ifdef FLEX_SCANNER + static rnd_bool firsttime = rnd_true; +#endif + pcb_io_pcb_usty_seen = 0; + if (Pipe == NULL) { + if (RND_EMPTY_STRING_P(Executable)) { + l = 2; + if (Path != NULL) + l += strlen(Path); + + l += strlen(Filename); + + if ((tmps = (char *)malloc(l * sizeof(char))) == NULL) { + fprintf(stderr, "Parse(): malloc failed\n"); + exit(1); + } + + if (Path != NULL && *Path != '\0') + sprintf(tmps, "%s%s%s", Path, RND_DIR_SEPARATOR_S, Filename); + else + sprintf(tmps, "%s", Filename); + + yyin = rnd_fopen(NULL, tmps, "r"); + if (!yyin) { + free(tmps); + return (1); + } + free(tmps); + } + else { + rnd_build_argfn_t p; + used_popen = 1; + memset(&p, 0, sizeof(p)); + p.params['p' - 'a'] = Path; + p.params['f' - 'a'] = Filename; + p.hidlib = &PCB->hidlib; + command = rnd_build_argfn(Executable, &p); + /* open pipe to stdout of command */ + if (*command == '\0' || (yyin = rnd_popen(NULL, command, "r")) == NULL) { + rnd_popen_error_message(command); + free(command); + return (1); + } + free(command); + } + } + else { + yyin = Pipe; + } + +#ifdef FLEX_SCANNER + /* reset parser if not called the first time */ + if (!firsttime) + yyrestart(yyin); + firsttime = rnd_false; +#endif + + /* init linenumber and filename for yyerror() */ + yylineno = 1; + yyfilename = Filename; + + /* We need to save the data temporarily because lex-yacc are able + * to break the application if the input file has an illegal format. + * It's not necessary if the system supports the call of functions + * on termination. + */ + + pcb_create_be_lenient(rnd_true); + +#if !defined(RND_HAS_ATEXIT) + if (PCB && PCB->Data) + pcb_tmp_data_save(); + returncode = pcb_parse(); + pcb_tmp_data_remove(); +#else + returncode = pcb_parse(); +#endif + /* clean up parse buffer */ + yy_delete_buffer(YY_CURRENT_BUFFER); + + pcb_create_be_lenient(rnd_false); + + if (Pipe != NULL) + return returncode; + + if (used_popen) + return (rnd_pclose(yyin) ? 1 : returncode); + return (fclose(yyin) ? 1 : returncode); +} + +/* --------------------------------------------------------------------------- + * initializes LEX and calls parser for a single element file + */ +int io_pcb_ParseElement(pcb_plug_io_t *ctx, pcb_data_t *Ptr, const char *name, const char *subfpname) +{ + FILE *f; + int ret; + pcb_fp_fopen_ctx_t st; + + f = pcb_fp_fopen(&conf_core.rc.library_search_paths, name, &st, NULL); + + /* set up the yy globals only after the pcb_fp_fopen() because it can + also call Parse */ + yy_parse_tags = 0; + yy_settings_dest = RND_CFR_invalid; + yyPCB = NULL; + yyData = Ptr; + pcb_data_set_layer_parents(Ptr); + yyFont = pcb_font(PCB, 0, 1); + yyFontReset = rnd_false; + yyFontkitValid = NULL; + yysubc = NULL; + yyElemFixLayers = 1; + + + if (f == NULL) { + pcb_fp_fclose(f, &st); + return -1; + } + + ret = Parse(f, NULL,NULL,NULL); + + yyElemFixLayers = 0; + + pcb_fp_fclose(f, &st); + + return(ret); +} + +/* --------------------------------------------------------------------------- + * initializes LEX and calls parser for a complete board + */ +#define TEST_FLAG_LOCAL(F,FLG) (((FLG) & (F)) ? 1 : 0) +#define CONF_BOOL_FLAG(F,FLG) (TEST_FLAG_LOCAL(F,FLG.f) ? "true" : "false") + +/* Hack: set a no-save-attribute flag while loading some fields from the file; + because we have all these flags set we won't need to list the paths that + have hardwired flags again in a "don't save these in attributes" list. */ +#define CONF_NO_ATTRIB(path) \ +do { \ + rnd_conf_native_t *n = rnd_conf_get_field(path); \ + if (n != NULL) \ + n->random_flags.io_pcb_no_attrib = 1; \ +} while(0) \ + +#define CONF_SET(target, path, arr_idx, new_val, pol) \ +do { \ + CONF_NO_ATTRIB(path); \ + rnd_conf_set(target, path, arr_idx, new_val, pol); \ +} while(0) \ + +int io_pcb_ParsePCB(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest) +{ + int retval; + const char *fcmd; + yy_parse_tags = 0; + yyPCB = Ptr; + yyData = NULL; + yyFont = NULL; + yyFontReset = rnd_true; + yyFontkitValid = NULL; + yysubc = NULL; + yy_settings_dest = settings_dest; + + if (settings_dest != RND_CFR_invalid) + rnd_conf_reset(settings_dest, Filename); + + io_pcb_preproc_board(PCB); + + pcb_data_clip_inhibit_inc(PCB->Data); + fcmd = conf_core.rc.file_command; + retval = Parse(NULL, fcmd, conf_core.rc.file_path, Filename); + + if ((settings_dest != RND_CFR_invalid) && (retval == 0)) { + /* overwrite settings from the flags, mark them not-to-save */ + rnd_conf_reset(settings_dest, ""); + rnd_conf_main_root_replace_cnt[settings_dest]++; + CONF_SET(settings_dest, "plugins/mincut/enable", -1, CONF_BOOL_FLAG(PCB_ENABLEPCB_FLAG_MINCUT, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/show_number", -1, CONF_BOOL_FLAG(PCB_SHOWNUMBERFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/show_drc", -1, CONF_BOOL_FLAG(PCB_SHOWPCB_FLAG_DRC, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/rubber_band_mode", -1, CONF_BOOL_FLAG(PCB_RUBBERBANDFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/auto_drc", -1, CONF_BOOL_FLAG(PCB_AUTOPCB_FLAG_DRC, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/all_direction_lines", -1, CONF_BOOL_FLAG(PCB_ALLDIRECTIONFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/swap_start_direction", -1, CONF_BOOL_FLAG(PCB_SWAPSTARTDIRFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/unique_names", -1, CONF_BOOL_FLAG(PCB_UNIQUENAMEFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/clear_line", -1, CONF_BOOL_FLAG(PCB_CLEARNEWFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/full_poly", -1, CONF_BOOL_FLAG(PCB_NEWPCB_FLAG_FULLPOLY, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/snap_pin", -1, CONF_BOOL_FLAG(PCB_SNAPPCB_FLAG_PIN, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/orthogonal_moves", -1, CONF_BOOL_FLAG(PCB_ORTHOMOVEFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/live_routing", -1, CONF_BOOL_FLAG(PCB_LIVEROUTEFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/lock_names", -1, CONF_BOOL_FLAG(PCB_LOCKNAMESFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/only_names", -1, CONF_BOOL_FLAG(PCB_ONLYNAMESFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/hide_names", -1, CONF_BOOL_FLAG(PCB_HIDENAMESFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/thin_draw", -1, CONF_BOOL_FLAG(PCB_THINDRAWFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/thin_draw_poly", -1, CONF_BOOL_FLAG(PCB_THINDRAWPOLYFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/local_ref", -1, CONF_BOOL_FLAG(PCB_LOCALREFFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/check_planes", -1, CONF_BOOL_FLAG(PCB_CHECKPLANESFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/description", -1, CONF_BOOL_FLAG(PCB_DESCRIPTIONFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + CONF_SET(settings_dest, "editor/name_on_pcb", -1, CONF_BOOL_FLAG(PCB_NAMEONPCBFLAG, yy_pcb_flags), RND_POL_OVERWRITE); + + /* don't save this because it is saved manually as PCB::grid::unit */ + CONF_NO_ATTRIB("editor/grid_unit"); + + /* don't save these to reduce noise - they are reset by the GUI anyway */ + CONF_NO_ATTRIB("editor/mode"); + + /* it's saved in [styles] */ + CONF_NO_ATTRIB("design/routes"); + + /* load config nodes not disabled above, from optional attributes */ + io_pcb_attrib_a2c(Ptr); + + rnd_conf_update(NULL, -1); + } + if (retval == 0) { + /* restore loader so the next save will use the same units */ + const char *loader = pcb_attribute_get(&PCB->Attributes, "PCB::loader"); + if (loader != NULL) { + pcb_find_io_t f; + int len; + + len = pcb_find_io(&f, 1, PCB_IOT_PCB, 1, loader); +/* printf("PCB::loader: %s -> %d\n", loader, len);*/ + if (len > 0) { +/* printf(" ::loader: '%s'\n", f.plug->description);*/ + PCB->Data->loader = f.plug; + } + } + else { + /* Loaded a file that did not have any information about preferred format */ + switch((int)pcb_io_pcb_usty_seen) { + case PCB_USTY_CMIL: + rnd_message(RND_MSG_INFO, "No preferred unit format info available for '%s' - will use '%s' on save (guessed from consistent unitless centimil input)\n", Filename, pcb_centimil_io_pcb->description); + PCB->Data->loader = pcb_centimil_io_pcb; + break; + case PCB_USTY_NANOMETER: + rnd_message(RND_MSG_INFO, "No preferred unit format info available for '%s' - will use '%s' on save (guessed from consistent nanometer input)\n", Filename, pcb_nanometer_io_pcb->description); + PCB->Data->loader = pcb_nanometer_io_pcb; + break; + case PCB_USTY_UNITS: + case PCB_USTY_UNITS | PCB_USTY_NANOMETER: + rnd_message(RND_MSG_INFO, "No preferred unit format info available for '%s' - will use '%s' on save (guessed from non-nanometer explicit unit usage)\n", Filename, pcb_preferred_io_pcb->description); + PCB->Data->loader = pcb_preferred_io_pcb; + break; + default: + rnd_message(RND_MSG_WARNING, "No preferred unit format info available and guessing failed for '%s' - will use '%s' on save\n", Filename, pcb_preferred_io_pcb->description); + PCB->Data->loader = pcb_preferred_io_pcb; + } + } + } + pcb_layer_auto_fixup(PCB); + io_pcb_postproc_board(PCB); + pcb_data_clip_inhibit_dec(PCB->Data, 1); + return retval; +} + +/* --------------------------------------------------------------------------- + * initializes LEX and calls parser for a font + */ +int io_pcb_ParseFont(pcb_plug_io_t *ctx, pcb_font_t *Ptr, const char *Filename) +{ + int r = 0, valid; + const char *fcmd; + yy_parse_tags = 1; + yyPCB = NULL; + yyFont = Ptr; + yyFontkitValid = &valid; + yysubc = NULL; + yyFontReset = rnd_false; + + yy_settings_dest = RND_CFR_invalid; + fcmd = conf_core.rc.font_command; + r = Parse(NULL, fcmd, NULL, Filename); + if (r == 0) { +#ifdef DEBUG + rnd_message(RND_MSG_DEBUG, "Found %s in %s\n", Filename, conf_core.rc.font_command); +#endif + } + return r; +} + +static int +parse_number () +{ + pcb_lval.number = strtod ((char *) yytext, NULL); + return FLOATING; +} + +static void add_tag(char *line) +{ + char *key, *val; + while((*line == '#') || isspace(*line)) line++; + key = line; + val = strchr(line, ':'); + if (val != NULL) { + *val = '\0'; + val++; + } + if (yyFont != NULL) { +/* printf("tag:%s=%s:\n", key,val); */ + if (strcmp(key, "name") == 0) { + free(yyFont->name); + yyFont->name = rnd_strdup(val); + } + } +} + Index: tags/2.3.0/src_plugins/io_pcb/parse_y.c =================================================================== --- tags/2.3.0/src_plugins/io_pcb/parse_y.c (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/parse_y.c (revision 33253) @@ -0,0 +1,3365 @@ +/* A Bison parser, made by GNU Bison 3.3.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. + + 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 3 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, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.3.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse pcb_parse +#define yylex pcb_lex +#define yyerror pcb_error +#define yydebug pcb_debug +#define yynerrs pcb_nerrs + +#define yylval pcb_lval +#define yychar pcb_char + +/* First part of user prologue. */ +#line 1 "parse_y.y" /* yacc.c:337 */ + +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2017, 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* grammar to parse ASCII input of geda/PCB description (alien format) */ + +#include "config.h" +#include "flag.h" +#include "board.h" +#include "conf_core.h" +#include "layer.h" +#include "data.h" +#include +#include "file.h" +#include "parse_l.h" +#include "polygon.h" +#include "remove.h" +#include +#include "flag_str.h" +#include "obj_pinvia_therm.h" +#include "rats_patch.h" +#include "route_style.h" +#include +#include "src_plugins/lib_compat_help/pstk_compat.h" +#include "netlist.h" + +/* frame between the groundplane and the copper or mask - noone seems + to remember what these two are for; changing them may have unforeseen + side effects. */ +#define PCB_GROUNDPLANEFRAME RND_MIL_TO_COORD(15) +#define PCB_MASKFRAME RND_MIL_TO_COORD(3) + +/* default inner/outer ratio for pins/vias in percent */ +#define PCB_DEFAULT_DRILLINGHOLE 40 + +static pcb_layer_t *Layer; +static pcb_poly_t *Polygon; +static pcb_symbol_t *Symbol; +static int pin_num; +static pcb_net_t *currnet; +static rnd_bool LayerFlag[PCB_MAX_LAYER + 2]; +static int old_fmt; /* 1 if we are reading a PCB(), 0 if PCB[] */ +static unsigned char yy_intconn; + +extern char *yytext; /* defined by LEX */ +extern pcb_board_t * yyPCB; +extern pcb_data_t * yyData; +extern pcb_subc_t *yysubc; +extern rnd_coord_t yysubc_ox, yysubc_oy; +extern pcb_font_t * yyFont; +extern rnd_bool yyFontReset; +extern int pcb_lineno; /* linenumber */ +extern char *yyfilename; /* in this file */ +extern rnd_conf_role_t yy_settings_dest; +extern pcb_flag_t yy_pcb_flags; +extern int *yyFontkitValid; +extern int yyElemFixLayers; + +static char *layer_group_string; + +static pcb_attribute_list_t *attr_list; + +int yyerror(const char *s); +int yylex(); +static int check_file_version (int); + +static void do_measure (PLMeasure *m, rnd_coord_t i, double d, int u); +#define M(r,f,d) do_measure (&(r), f, d, 1) + +/* Macros for interpreting what "measure" means - integer value only, + old units (mil), or new units (cmil). */ +#define IV(m) integer_value (m) +#define OU(m) old_units (m) +#define NU(m) new_units (m) + +static int integer_value (PLMeasure m); +static rnd_coord_t old_units (PLMeasure m); +static rnd_coord_t new_units (PLMeasure m); +static pcb_flag_t pcb_flag_old(unsigned int flags); +static void load_meta_coord(const char *path, rnd_coord_t crd); +static void load_meta_float(const char *path, double val); + +#define YYDEBUG 1 +#define YYERROR_VERBOSE 1 + +#include "parse_y.h" + + +#line 193 "parse_y.c" /* yacc.c:337 */ +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "parse_y.h". */ +#ifndef YY_PCB_PARSE_Y_H_INCLUDED +# define YY_PCB_PARSE_Y_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int pcb_debug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + FLOATING = 258, + INTEGER = 259, + CHAR_CONST = 260, + STRING = 261, + T_FILEVERSION = 262, + T_PCB = 263, + T_LAYER = 264, + T_VIA = 265, + T_RAT = 266, + T_LINE = 267, + T_ARC = 268, + T_RECTANGLE = 269, + T_TEXT = 270, + T_ELEMENTLINE = 271, + T_ELEMENT = 272, + T_PIN = 273, + T_PAD = 274, + T_GRID = 275, + T_FLAGS = 276, + T_SYMBOL = 277, + T_SYMBOLLINE = 278, + T_CURSOR = 279, + T_ELEMENTARC = 280, + T_MARK = 281, + T_GROUPS = 282, + T_STYLES = 283, + T_POLYGON = 284, + T_POLYGON_HOLE = 285, + T_NETLIST = 286, + T_NET = 287, + T_CONN = 288, + T_NETLISTPATCH = 289, + T_ADD_CONN = 290, + T_DEL_CONN = 291, + T_CHANGE_ATTRIB = 292, + T_AREA = 293, + T_THERMAL = 294, + T_DRC = 295, + T_ATTRIBUTE = 296, + T_UMIL = 297, + T_CMIL = 298, + T_MIL = 299, + T_IN = 300, + T_NM = 301, + T_UM = 302, + T_MM = 303, + T_M = 304, + T_KM = 305 + }; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 121 "parse_y.y" /* yacc.c:352 */ + + int integer; + double number; + char *string; + pcb_flag_t flagtype; + PLMeasure measure; + +#line 295 "parse_y.c" /* yacc.c:352 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE pcb_lval; + +int pcb_parse (void); + +#endif /* !YY_PCB_PARSE_Y_H_INCLUDED */ + + + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 10 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 608 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 55 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 112 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 214 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 643 + +#define YYUNDEFTOK 2 +#define YYMAXUTOK 305 + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 53, 54, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 51, 2, 52, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50 +}; + +#if YYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 148, 148, 149, 150, 151, 155, 155, 229, 229, + 254, 254, 273, 274, 279, 279, 299, 301, 311, 318, + 325, 335, 336, 337, 340, 348, 363, 378, 382, 386, + 389, 391, 398, 400, 406, 408, 409, 410, 414, 424, + 435, 447, 451, 456, 460, 464, 468, 477, 486, 490, + 491, 495, 496, 500, 501, 501, 502, 503, 505, 505, + 512, 516, 517, 518, 519, 520, 525, 535, 546, 556, + 566, 582, 587, 597, 596, 627, 628, 632, 633, 637, + 638, 639, 640, 641, 642, 644, 649, 650, 651, 652, + 652, 653, 657, 666, 675, 686, 695, 704, 713, 723, + 741, 766, 765, 804, 806, 811, 810, 817, 819, 824, + 828, 835, 836, 837, 838, 839, 847, 846, 865, 864, + 883, 882, 903, 901, 925, 923, 948, 949, 953, 954, + 955, 956, 957, 959, 964, 969, 974, 979, 984, 989, + 989, 993, 994, 998, 999, 1000, 1001, 1003, 1009, 1016, + 1021, 1026, 1026, 1032, 1045, 1057, 1068, 1084, 1103, 1118, + 1131, 1142, 1153, 1154, 1158, 1159, 1162, 1164, 1180, 1199, + 1200, 1203, 1205, 1206, 1211, 1218, 1224, 1225, 1229, 1234, + 1235, 1239, 1240, 1246, 1245, 1257, 1258, 1262, 1263, 1267, + 1284, 1285, 1289, 1294, 1295, 1299, 1300, 1315, 1316, 1317, + 1321, 1334, 1335, 1339, 1340, 1345, 1346, 1347, 1348, 1349, + 1350, 1351, 1352, 1353, 1354 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "FLOATING", "INTEGER", "CHAR_CONST", + "STRING", "T_FILEVERSION", "T_PCB", "T_LAYER", "T_VIA", "T_RAT", + "T_LINE", "T_ARC", "T_RECTANGLE", "T_TEXT", "T_ELEMENTLINE", "T_ELEMENT", + "T_PIN", "T_PAD", "T_GRID", "T_FLAGS", "T_SYMBOL", "T_SYMBOLLINE", + "T_CURSOR", "T_ELEMENTARC", "T_MARK", "T_GROUPS", "T_STYLES", + "T_POLYGON", "T_POLYGON_HOLE", "T_NETLIST", "T_NET", "T_CONN", + "T_NETLISTPATCH", "T_ADD_CONN", "T_DEL_CONN", "T_CHANGE_ATTRIB", + "T_AREA", "T_THERMAL", "T_DRC", "T_ATTRIBUTE", "T_UMIL", "T_CMIL", + "T_MIL", "T_IN", "T_NM", "T_UM", "T_MM", "T_M", "T_KM", "'['", "']'", + "'('", "')'", "$accept", "parse", "parsepcb", "$@1", "$@2", "parsedata", + "$@3", "pcbfont", "parsefont", "$@4", "pcbfileversion", "pcbname", + "pcbgrid", "pcbgridold", "pcbgridnew", "pcbhigrid", "pcbcursor", + "polyarea", "pcbthermal", "pcbdrc", "pcbdrc1", "pcbdrc2", "pcbdrc3", + "pcbflags", "pcbgroups", "pcbstyles", "pcbdata", "pcbdefinitions", + "pcbdefinition", "$@5", "$@6", "via", "via_hi_format", "via_2.0_format", + "via_1.7_format", "via_newformat", "via_oldformat", "rats", "layer", + "$@7", "layerdata", "layerdefinitions", "layerdefinition", "$@8", + "line_hi_format", "line_1.7_format", "line_oldformat", "arc_hi_format", + "arc_1.7_format", "arc_oldformat", "text_oldformat", "text_newformat", + "text_hi_format", "polygon_format", "$@9", "polygonholes", "polygonhole", + "$@10", "polygonpoints", "polygonpoint", "element", "element_oldformat", + "$@11", "element_1.3.4_format", "$@12", "element_newformat", "$@13", + "element_1.7_format", "$@14", "element_hi_format", "$@15", + "elementdefinitions", "elementdefinition", "$@16", "relementdefs", + "relementdef", "$@17", "pin_hi_format", "pin_1.7_format", + "pin_1.6.3_format", "pin_newformat", "pin_oldformat", "pad_hi_format", + "pad_1.7_format", "pad_newformat", "pad", "flags", "symbols", "symbol", + "symbolhead", "symbolid", "symboldata", "symboldefinition", + "hiressymbol", "pcbnetlist", "pcbnetdef", "nets", "netdefs", "net", + "$@18", "connections", "conndefs", "conn", "pcbnetlistpatch", + "pcbnetpatchdef", "netpatches", "netpatchdefs", "netpatch", "attribute", + "opt_string", "number", "measure", YY_NULLPTR +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 91, 93, 40, 41 +}; +# endif + +#define YYPACT_NINF -449 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-449))) + +#define YYTABLE_NINF -90 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + 151, -449, 39, -449, 4, 30, -449, 23, -449, 56, + -449, 32, 97, -31, -449, -449, -449, -449, -449, -449, + -449, 73, -5, 26, -449, 169, -449, 88, 30, -449, + -449, -449, -449, -449, -449, -449, -449, 48, 56, -449, + -449, 129, 55, 116, 49, 113, 140, 63, 63, 63, + 63, -449, 95, -449, -449, 84, 84, -449, -16, 105, + 143, 157, 92, 147, -449, -449, -449, -449, -449, 158, + 161, 168, 176, -449, -449, 305, 63, 63, 63, 63, + 187, -449, -449, 63, 63, 134, -449, -449, -449, -449, + 63, 6, 63, 63, 160, 156, 191, 192, 63, 210, + -449, -449, -449, -449, -449, -449, -449, -449, -449, 63, + 63, 224, 229, 233, 196, 197, 63, 63, 63, -449, + 63, 63, 63, 63, 63, 218, 257, 272, 185, 63, + -449, 236, 63, 221, 63, 63, 245, 255, 270, 63, + 63, 274, 287, 63, 63, 63, 63, 63, 283, 302, + 63, 63, 63, 353, 312, 63, 362, 239, 63, 63, + -449, -449, -449, 63, 63, -449, -449, 378, 0, 63, + 63, 334, 63, 341, 372, -449, -449, -449, 63, 63, + 63, 342, -449, 63, 343, 394, 251, 397, 398, 63, + 63, 351, 350, -449, 354, 355, -449, 356, 63, 357, + 380, 63, 63, 63, 358, 260, 399, -449, 359, 408, + 409, 49, 410, 63, 63, -449, -449, -449, -449, -449, + 63, 228, 363, 389, 63, 63, 414, -449, 205, 226, + 366, 253, 367, 368, 260, -449, 88, -449, -449, -449, + -449, -449, -449, -449, -449, -449, -449, 49, -449, 369, + 417, 373, 370, 376, 375, 63, 379, 381, 424, 256, + 412, 63, 90, 384, 33, 63, 63, 63, 63, 63, + 63, 63, 49, -449, -449, -449, 385, -449, 386, -449, + -449, -449, -449, 11, -449, -449, 387, 433, 436, 195, + -449, 63, 390, 63, 393, 276, 403, 404, 279, 280, + 102, -449, 88, -449, -449, -449, -449, -449, 63, 63, + 63, 63, 63, 63, 63, 405, -449, -449, -449, 13, + -449, 391, 406, 416, 49, 411, 454, -449, 63, 63, + 63, 63, 63, 63, 63, 63, -449, -449, -449, 63, + 63, 63, 63, 63, 63, 63, 415, -449, 63, -449, + -449, 418, 427, -449, 413, -449, 419, 33, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 264, -449, 420, 421, 423, -449, -449, 425, + 33, 426, 121, 63, 63, 63, 63, 63, 63, 422, + 437, 63, 63, 63, 63, 458, 457, 465, 464, 320, + -449, 428, 438, -449, 183, -449, -449, 63, 63, 299, + 63, 63, 63, -449, -449, 63, 63, 63, 63, 439, + 49, 440, 473, 63, 63, -449, 320, 448, 442, 165, + -449, 165, 63, 63, 486, 490, 63, 63, 63, 49, + 2, 63, 63, -449, 445, -449, 444, 63, 63, -17, + -449, 446, 447, 448, -449, -10, 321, 326, 327, 330, + 222, -449, 88, -449, -449, -449, -449, 234, 450, 449, + 459, 352, 494, 63, 63, 460, 461, -449, 63, 110, + -449, -449, 462, 463, 466, -449, -449, 510, -449, -449, + 467, 468, 469, 478, -10, -449, 63, 63, 63, 63, + 63, 63, 63, 63, -449, -449, -449, -449, -449, -449, + -449, 479, 514, 383, 63, 63, -449, -449, 49, 480, + 519, -449, -449, -449, 529, 530, 531, 538, -449, -449, + 63, 63, 63, 63, 63, 63, 63, 63, -449, 493, + 495, 544, 502, 503, 506, -449, 505, 320, 507, 554, + 556, 557, 63, 63, 63, 63, 63, 63, 63, 63, + -449, -449, 515, -449, -449, -449, -449, 516, 518, 520, + 521, 562, 63, 63, 63, 63, 63, 63, 63, 63, + -449, -449, -449, -449, -449, 522, 63, 63, 63, 63, + 63, 63, 63, 63, 539, -449, 525, 524, 63, 63, + 63, 63, 63, 63, 526, 527, 539, -449, -449, -449, + 567, 574, 63, 63, 63, 63, 576, -449, -449, 577, + 578, 579, 580, 535, 534, 536, 49, 585, 586, 587, + -449, -449, -449, 542, 537, 49, 591, -449, -449, 545, + 546, -449, -449 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 5, 0, 2, 16, 0, 3, 0, 4, 0, + 1, 0, 0, 0, 9, 111, 112, 113, 114, 115, + 60, 0, 0, 0, 11, 0, 51, 0, 0, 53, + 61, 62, 63, 64, 65, 56, 57, 0, 15, 164, + 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 0, 55, 59, 0, 0, 165, 0, 0, + 0, 0, 0, 29, 21, 22, 23, 162, 163, 0, + 0, 0, 0, 203, 204, 205, 0, 0, 0, 0, + 0, 169, 170, 0, 0, 0, 166, 172, 173, 17, + 0, 0, 0, 0, 0, 30, 0, 0, 0, 202, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, + 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, + 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 200, 167, 168, 0, 0, 20, 19, 0, 0, 0, + 0, 0, 0, 0, 43, 35, 36, 37, 0, 0, + 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 24, 0, 0, 31, 0, 0, 0, + 45, 0, 0, 0, 0, 76, 0, 70, 0, 0, + 0, 0, 0, 0, 0, 26, 25, 28, 27, 33, + 0, 0, 0, 48, 0, 0, 0, 116, 0, 0, + 0, 0, 0, 0, 75, 77, 0, 79, 80, 81, + 82, 83, 84, 88, 87, 86, 91, 0, 69, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13, 0, 0, 0, 139, 0, 0, 0, 0, 0, + 0, 0, 0, 74, 78, 90, 0, 68, 0, 71, + 72, 175, 174, 0, 41, 42, 0, 0, 0, 0, + 12, 0, 204, 0, 0, 0, 0, 0, 0, 0, + 139, 126, 0, 128, 129, 130, 131, 132, 0, 0, + 0, 0, 0, 0, 0, 0, 66, 67, 38, 0, + 44, 0, 0, 177, 0, 0, 0, 118, 0, 0, + 0, 0, 0, 0, 0, 0, 117, 127, 140, 0, + 0, 0, 0, 0, 0, 0, 0, 39, 0, 47, + 46, 0, 191, 176, 0, 120, 0, 139, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 101, 0, 0, 0, 7, 190, 0, + 139, 0, 139, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, + 40, 0, 0, 124, 139, 122, 119, 0, 0, 0, + 0, 0, 0, 137, 138, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 103, 107, 180, 0, 151, + 121, 151, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 98, 0, 0, 0, 0, + 108, 0, 0, 179, 181, 194, 0, 0, 0, 0, + 151, 141, 0, 144, 143, 146, 145, 151, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, + 100, 99, 0, 0, 0, 102, 104, 0, 178, 182, + 0, 0, 0, 0, 193, 195, 0, 0, 0, 0, + 0, 0, 0, 0, 125, 142, 152, 123, 133, 134, + 157, 0, 0, 0, 0, 0, 92, 93, 0, 204, + 0, 110, 109, 105, 0, 0, 0, 0, 192, 196, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, + 0, 0, 0, 0, 0, 97, 0, 107, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 155, 161, 0, 135, 136, 95, 96, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 160, 106, 183, 197, 198, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 186, 199, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 185, 187, 147, 148, + 0, 0, 0, 0, 0, 0, 0, 184, 188, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 149, 150, 189, 0, 0, 0, 0, 153, 154, 0, + 0, 158, 159 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -449, -449, -449, -449, -449, -449, -449, -449, 336, -449, + -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, + -449, -449, -449, -449, -449, -449, 309, -449, 581, -449, + -449, -449, -449, -449, -449, -449, -449, -449, -449, -449, + -449, -449, 365, -449, -449, -449, -449, -449, -449, -449, + -449, -449, -449, -449, -449, -449, -449, -449, -423, -449, + 573, -449, -449, -449, -449, -449, -449, -449, -449, -449, + -449, -339, -292, -449, 171, -448, -449, -449, -449, -449, + -449, -449, -449, -449, -449, -449, -190, -449, 565, -449, + 548, -449, -449, -449, -449, -449, -449, -449, 152, -449, + -449, -449, 1, -449, -449, -449, -449, 114, -231, -449, + -47, -48 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 2, 3, 4, 5, 6, 7, 289, 8, 9, + 12, 43, 63, 64, 65, 66, 95, 126, 149, 174, + 175, 176, 177, 200, 223, 260, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 205, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 399, 449, 486, 547, 425, 426, + 14, 15, 264, 16, 357, 17, 380, 18, 431, 19, + 429, 300, 301, 302, 460, 461, 462, 463, 464, 303, + 304, 305, 465, 466, 306, 307, 69, 38, 39, 40, + 83, 58, 87, 88, 352, 353, 452, 453, 454, 594, + 605, 606, 607, 377, 378, 493, 494, 495, 53, 131, + 75, 76 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = +{ + 77, 78, 79, 450, 192, 275, 476, 85, 337, 73, + 74, 11, 505, 484, 73, 74, 73, 74, 382, 505, + 44, 251, 45, -50, 20, 490, 491, 492, 109, 110, + 111, 112, 21, 22, 23, 114, 115, 485, 86, 10, + -58, 404, 118, 120, 121, 122, 47, 13, 48, 295, + 129, 296, 297, 67, 193, 68, 477, 276, 298, 299, + 119, 132, 133, 318, -54, 347, 73, 74, 139, 140, + 141, 338, 142, 143, 144, 145, 146, 49, 37, 50, + 152, 153, 315, 41, 155, 157, 158, 159, 81, 82, + 337, 163, 164, 73, 292, 167, 168, 169, 170, 55, + 171, 56, 178, 179, 180, 42, 60, 183, 61, 186, + 187, 188, 337, 73, 519, 189, 190, 70, 295, 71, + 296, 297, 194, 195, 567, 197, 46, 298, 299, 52, + 201, 202, 203, 59, 354, 206, 62, 295, 210, 296, + 297, 213, 214, 92, 72, 93, 298, 299, 80, 90, + 220, -10, 1, 224, 225, 226, 336, 89, -6, -6, + -10, -10, -10, 91, 96, 253, 254, 97, -8, -49, + 20, 94, 255, -14, 98, 406, 261, 262, 21, 22, + 23, 456, 99, 457, 458, 116, -58, 117, 73, 74, + 459, 151, -10, 113, 125, -50, 20, 127, 128, 295, + -49, 296, 297, -49, 21, 22, 23, 283, 298, 299, + -54, 123, -58, 124, 291, 293, 130, 308, 309, 310, + 311, 312, 313, 314, 73, 74, -50, 156, 134, -50, + 444, 506, 256, 135, 257, 319, -54, 430, 456, 136, + 457, 458, 73, 74, 324, 185, 326, 459, 137, 475, + 456, 138, 457, 458, 73, 74, 265, 209, 266, 459, + 339, 340, 341, 342, 343, 344, 345, 73, 74, 147, + 397, 348, 228, 229, 230, 231, 504, 267, 150, 268, + 358, 359, 360, 361, 362, 363, 364, 365, 507, 232, + 154, 366, 367, 368, 369, 370, 148, 371, 372, 160, + 374, -89, 73, 74, 270, 434, 271, 287, 161, 288, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 162, 396, 398, 165, 328, 544, 329, + 332, 334, 333, 335, 172, 407, 408, 409, 410, 411, + 412, 166, 173, 415, 416, 417, 418, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 511, 181, 512, 432, + 433, 435, 436, 437, 438, 182, 184, 439, 440, 441, + 442, 423, 496, 424, 497, 447, 448, 498, 500, 499, + 501, 502, 191, 503, 468, 469, 196, 540, 472, 541, + 473, 474, 198, 199, 478, 479, 204, 207, 208, 482, + 483, 211, 212, 215, 216, 247, 217, 222, 219, 218, + 221, 227, 249, 248, 252, 250, 258, 259, 263, 269, + 272, 278, 273, 277, 280, 279, 514, 515, 281, 282, + 286, 518, 520, 284, -14, 285, 633, 316, 294, 321, + 317, 320, 322, 349, 325, 639, 327, 351, 530, 531, + 532, 533, 534, 535, 536, 537, 330, 331, 356, 346, + 350, 376, 419, 420, 355, 379, 542, 543, 373, 421, + 422, 375, 400, 381, 413, 401, 402, 446, 403, 405, + 451, 427, 552, 553, 554, 555, 556, 557, 558, 559, + 470, 414, 428, 443, 445, 455, 471, 480, 481, 487, + 513, 488, 508, 509, 572, 573, 574, 575, 576, 577, + 578, 579, 516, 510, 521, 517, 524, 522, 539, 523, + 525, 526, 527, 546, 586, 587, 588, 589, 590, 591, + 592, 593, 528, 538, 545, 548, 549, 550, 596, 597, + 598, 599, 600, 601, 551, 602, 603, 560, 562, 561, + 610, 611, 612, 613, 563, 614, 615, 564, 565, 566, + 569, 568, 570, 571, 621, 622, 623, 624, 585, 580, + 581, 582, 604, 619, 583, 584, 595, 608, 609, 616, + 620, 617, 625, 626, 627, 628, 629, 630, 631, 634, + 632, 638, 635, 636, 637, 640, 290, 641, 323, 274, + 642, 54, 467, 57, 84, 489, 51, 618, 529 +}; + +static const yytype_uint16 yycheck[] = +{ + 48, 49, 50, 426, 4, 236, 4, 23, 300, 3, + 4, 7, 460, 30, 3, 4, 3, 4, 357, 467, + 51, 211, 53, 0, 1, 35, 36, 37, 76, 77, + 78, 79, 9, 10, 11, 83, 84, 54, 54, 0, + 17, 380, 90, 91, 92, 93, 51, 17, 53, 16, + 98, 18, 19, 4, 54, 6, 54, 247, 25, 26, + 54, 109, 110, 52, 41, 52, 3, 4, 116, 117, + 118, 302, 120, 121, 122, 123, 124, 51, 22, 53, + 128, 129, 272, 51, 132, 133, 134, 135, 4, 5, + 382, 139, 140, 3, 4, 143, 144, 145, 146, 51, + 147, 53, 150, 151, 152, 8, 51, 155, 53, 157, + 158, 159, 404, 3, 4, 163, 164, 4, 16, 6, + 18, 19, 169, 170, 547, 172, 53, 25, 26, 41, + 178, 179, 180, 4, 324, 183, 20, 16, 186, 18, + 19, 189, 190, 51, 4, 53, 25, 26, 53, 6, + 198, 0, 1, 201, 202, 203, 54, 52, 7, 8, + 9, 10, 11, 6, 6, 213, 214, 6, 17, 0, + 1, 24, 220, 22, 6, 54, 224, 225, 9, 10, + 11, 16, 6, 18, 19, 51, 17, 53, 3, 4, + 25, 6, 41, 6, 38, 0, 1, 6, 6, 16, + 31, 18, 19, 34, 9, 10, 11, 255, 25, 26, + 41, 51, 17, 53, 261, 262, 6, 265, 266, 267, + 268, 269, 270, 271, 3, 4, 31, 6, 4, 34, + 420, 462, 4, 4, 6, 283, 41, 54, 16, 6, + 18, 19, 3, 4, 291, 6, 293, 25, 52, 439, + 16, 54, 18, 19, 3, 4, 51, 6, 53, 25, + 308, 309, 310, 311, 312, 313, 314, 3, 4, 51, + 6, 319, 12, 13, 14, 15, 54, 51, 6, 53, + 328, 329, 330, 331, 332, 333, 334, 335, 54, 29, + 54, 339, 340, 341, 342, 343, 39, 344, 345, 54, + 348, 41, 3, 4, 51, 6, 53, 51, 53, 53, + 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, + 368, 369, 370, 53, 371, 372, 52, 51, 518, 53, + 51, 51, 53, 53, 51, 383, 384, 385, 386, 387, + 388, 54, 40, 391, 392, 393, 394, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 4, 4, 6, 407, + 408, 409, 410, 411, 412, 53, 4, 415, 416, 417, + 418, 51, 51, 53, 53, 423, 424, 51, 51, 53, + 53, 51, 4, 53, 432, 433, 52, 4, 436, 6, + 437, 438, 51, 21, 441, 442, 54, 54, 4, 447, + 448, 4, 4, 52, 54, 6, 52, 27, 52, 54, + 53, 53, 4, 54, 4, 6, 53, 28, 4, 53, + 53, 4, 54, 54, 54, 52, 473, 474, 52, 54, + 6, 478, 479, 54, 22, 54, 626, 52, 54, 6, + 54, 54, 6, 52, 54, 635, 53, 31, 496, 497, + 498, 499, 500, 501, 502, 503, 53, 53, 4, 54, + 54, 34, 4, 6, 53, 52, 514, 515, 53, 4, + 6, 53, 52, 54, 52, 54, 53, 4, 53, 53, + 32, 53, 530, 531, 532, 533, 534, 535, 536, 537, + 4, 54, 54, 54, 54, 53, 6, 52, 54, 53, + 6, 54, 52, 54, 552, 553, 554, 555, 556, 557, + 558, 559, 52, 54, 52, 54, 6, 54, 4, 53, + 53, 53, 53, 4, 572, 573, 574, 575, 576, 577, + 578, 579, 54, 54, 54, 6, 6, 6, 586, 587, + 588, 589, 590, 591, 6, 592, 593, 54, 4, 54, + 598, 599, 600, 601, 52, 602, 603, 54, 52, 54, + 6, 54, 6, 6, 612, 613, 614, 615, 6, 54, + 54, 53, 33, 6, 54, 54, 54, 52, 54, 53, + 6, 54, 6, 6, 6, 6, 6, 52, 54, 4, + 54, 54, 6, 6, 52, 4, 260, 52, 289, 234, + 54, 28, 431, 38, 56, 453, 25, 606, 494 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 1, 56, 57, 58, 59, 60, 61, 63, 64, + 0, 7, 65, 17, 115, 116, 118, 120, 122, 124, + 1, 9, 10, 11, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 22, 142, 143, + 144, 51, 8, 66, 51, 53, 53, 51, 53, 51, + 53, 83, 41, 163, 115, 51, 53, 143, 146, 4, + 51, 53, 20, 67, 68, 69, 70, 4, 6, 141, + 4, 6, 4, 3, 4, 165, 166, 166, 166, 166, + 53, 4, 5, 145, 145, 23, 54, 147, 148, 52, + 6, 6, 51, 53, 24, 71, 6, 6, 6, 6, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 166, + 166, 166, 166, 6, 166, 166, 51, 53, 166, 54, + 166, 166, 166, 51, 53, 38, 72, 6, 6, 166, + 6, 164, 166, 166, 4, 4, 6, 52, 54, 166, + 166, 166, 166, 166, 166, 166, 166, 51, 39, 73, + 6, 6, 166, 166, 54, 166, 6, 166, 166, 166, + 54, 53, 53, 166, 166, 52, 54, 166, 166, 166, + 166, 165, 51, 40, 74, 75, 76, 77, 166, 166, + 166, 4, 53, 166, 4, 6, 166, 166, 166, 166, + 166, 4, 4, 54, 165, 165, 52, 165, 51, 21, + 78, 166, 166, 166, 54, 94, 166, 54, 4, 6, + 166, 4, 4, 166, 166, 52, 54, 52, 54, 52, + 166, 53, 27, 79, 166, 166, 166, 53, 12, 13, + 14, 15, 29, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 6, 54, 4, + 6, 141, 4, 166, 166, 166, 4, 6, 53, 28, + 80, 166, 166, 4, 117, 51, 53, 51, 53, 53, + 51, 53, 53, 54, 97, 163, 141, 54, 4, 52, + 54, 52, 54, 166, 54, 54, 6, 51, 53, 62, + 63, 165, 4, 165, 54, 16, 18, 19, 25, 26, + 126, 127, 128, 134, 135, 136, 139, 140, 166, 166, + 166, 166, 166, 166, 166, 141, 52, 54, 52, 166, + 54, 6, 6, 81, 165, 54, 165, 53, 51, 53, + 53, 53, 51, 53, 51, 53, 54, 127, 163, 166, + 166, 166, 166, 166, 166, 166, 54, 52, 166, 52, + 54, 31, 149, 150, 141, 53, 4, 119, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 165, 165, 53, 166, 53, 34, 158, 159, 52, + 121, 54, 126, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 165, 6, 165, 109, + 52, 54, 53, 53, 126, 53, 54, 166, 166, 166, + 166, 166, 166, 52, 54, 166, 166, 166, 166, 4, + 6, 4, 6, 51, 53, 113, 114, 53, 54, 125, + 54, 123, 166, 166, 6, 166, 166, 166, 166, 166, + 166, 166, 166, 54, 141, 54, 4, 166, 166, 110, + 113, 32, 151, 152, 153, 53, 16, 18, 19, 25, + 129, 130, 131, 132, 133, 137, 138, 129, 166, 166, + 4, 6, 166, 165, 165, 141, 4, 54, 165, 165, + 52, 54, 166, 166, 30, 54, 111, 53, 54, 153, + 35, 36, 37, 160, 161, 162, 51, 53, 51, 53, + 51, 53, 51, 53, 54, 130, 163, 54, 52, 54, + 54, 4, 6, 6, 165, 165, 52, 54, 165, 4, + 165, 52, 54, 53, 6, 53, 53, 53, 54, 162, + 166, 166, 166, 166, 166, 166, 166, 166, 54, 4, + 4, 6, 166, 166, 141, 54, 4, 112, 6, 6, + 6, 6, 166, 166, 166, 166, 166, 166, 166, 166, + 54, 54, 4, 52, 54, 52, 54, 113, 54, 6, + 6, 6, 166, 166, 166, 166, 166, 166, 166, 166, + 54, 54, 53, 54, 54, 6, 166, 166, 166, 166, + 166, 166, 166, 166, 154, 54, 166, 166, 166, 166, + 166, 166, 165, 165, 33, 155, 156, 157, 52, 54, + 166, 166, 166, 166, 165, 165, 53, 54, 157, 6, + 6, 166, 166, 166, 166, 6, 6, 6, 6, 6, + 52, 54, 54, 141, 4, 6, 6, 52, 54, 141, + 4, 52, 54 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 55, 56, 56, 56, 56, 58, 57, 59, 57, + 61, 60, 62, 62, 64, 63, 65, 65, 66, 66, + 66, 67, 67, 67, 68, 69, 70, 71, 71, 71, + 72, 72, 73, 73, 74, 74, 74, 74, 75, 76, + 77, 78, 78, 78, 79, 79, 80, 80, 80, 81, + 81, 82, 82, 83, 84, 83, 83, 83, 85, 83, + 83, 86, 86, 86, 86, 86, 87, 88, 89, 90, + 91, 92, 92, 94, 93, 95, 95, 96, 96, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, + 97, 97, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 109, 108, 110, 110, 112, 111, 113, 113, 114, + 114, 115, 115, 115, 115, 115, 117, 116, 119, 118, + 121, 120, 123, 122, 125, 124, 126, 126, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 128, + 127, 129, 129, 130, 130, 130, 130, 130, 130, 130, + 130, 131, 130, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 141, 142, 142, 143, 144, 144, 145, + 145, 146, 146, 146, 147, 148, 149, 149, 150, 151, + 151, 152, 152, 154, 153, 155, 155, 156, 156, 157, + 158, 158, 159, 160, 160, 161, 161, 162, 162, 162, + 163, 164, 164, 165, 165, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 1, 1, 1, 0, 15, 0, 2, + 0, 2, 1, 0, 0, 2, 0, 4, 4, 6, + 6, 1, 1, 1, 6, 7, 7, 6, 6, 0, + 0, 4, 0, 4, 0, 1, 1, 1, 6, 7, + 9, 4, 4, 0, 4, 0, 4, 4, 0, 1, + 0, 1, 2, 1, 0, 2, 1, 1, 0, 2, + 1, 1, 1, 1, 1, 1, 11, 11, 10, 9, + 8, 10, 10, 0, 10, 1, 0, 1, 2, 1, + 1, 1, 1, 1, 1, 8, 1, 1, 1, 0, + 2, 1, 10, 10, 9, 12, 12, 11, 8, 9, + 9, 0, 9, 0, 2, 0, 5, 0, 2, 4, + 4, 1, 1, 1, 1, 1, 0, 12, 0, 15, + 0, 16, 0, 18, 0, 18, 1, 2, 1, 1, + 1, 1, 1, 8, 8, 10, 10, 5, 5, 0, + 2, 1, 2, 1, 1, 1, 1, 8, 8, 10, + 10, 0, 2, 12, 12, 10, 9, 8, 13, 13, + 11, 10, 1, 1, 1, 2, 3, 6, 6, 1, + 1, 0, 2, 2, 8, 8, 1, 0, 6, 1, + 0, 1, 2, 0, 9, 1, 0, 1, 2, 4, + 1, 0, 6, 1, 0, 1, 2, 5, 5, 6, + 5, 1, 0, 1, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +{ + FILE *yyoutput = yyo; + YYUSE (yyoutput); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); +# endif + YYUSE (yytype); +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyo, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyo, yytype, yyvaluep); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +{ + unsigned long yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &yyvsp[(yyi + 1) - (yynrhs)] + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +yystrlen (const char *yystr) +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +{ + YYUSE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + *yyssp = (yytype_int16) yystate; + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 5: +#line 151 "parse_y.y" /* yacc.c:1652 */ + { YYABORT; } +#line 1812 "parse_y.c" /* yacc.c:1652 */ + break; + + case 6: +#line 155 "parse_y.y" /* yacc.c:1652 */ + { + /* reset flags for 'used layers'; + * init font and data pointers + */ + int i; + + if (!yyPCB) + { + rnd_message(RND_MSG_ERROR, "illegal fileformat\n"); + YYABORT; + } + for (i = 0; i < PCB_MAX_LAYER + 2; i++) + LayerFlag[i] = rnd_false; + yyFont = &yyPCB->fontkit.dflt; + yyFontkitValid = &yyPCB->fontkit.valid; + yyData = yyPCB->Data; + PCB_SET_PARENT(yyData, board, yyPCB); + yyData->LayerN = 0; + yyPCB->NetlistPatches = yyPCB->NetlistPatchLast = NULL; + layer_group_string = NULL; + old_fmt = 0; + } +#line 1839 "parse_y.c" /* yacc.c:1652 */ + break; + + case 7: +#line 191 "parse_y.y" /* yacc.c:1652 */ + { + pcb_board_t *pcb_save = PCB; + if ((yy_settings_dest != RND_CFR_invalid) && (layer_group_string != NULL)) + rnd_conf_set(yy_settings_dest, "design/groups", -1, layer_group_string, RND_POL_OVERWRITE); + pcb_board_new_postproc(yyPCB, 0); + if (layer_group_string == NULL) { + if (pcb_layer_improvise(yyPCB, rnd_true) != 0) { + rnd_message(RND_MSG_ERROR, "missing layer-group string, failed to improvise the groups\n"); + YYABORT; + } + rnd_message(RND_MSG_ERROR, "missing layer-group string: invalid input file, had to improvise, the layer stack is most probably broken\n"); + } + else { + if (pcb_layer_parse_group_string(yyPCB, layer_group_string, yyData->LayerN, old_fmt)) + { + rnd_message(RND_MSG_ERROR, "illegal layer-group string\n"); + YYABORT; + } + else { + if (pcb_layer_improvise(yyPCB, rnd_false) != 0) { + rnd_message(RND_MSG_ERROR, "failed to extend-improvise the groups\n"); + YYABORT; + } + } + } + /* initialize the polygon clipping now since + * we didn't know the layer grouping before. + */ + free(layer_group_string); + PCB = yyPCB; + PCB_POLY_ALL_LOOP(yyData); + { + pcb_poly_init_clip(yyData, layer, polygon); + } + PCB_ENDALL_LOOP; + PCB = pcb_save; + } +#line 1881 "parse_y.c" /* yacc.c:1652 */ + break; + + case 8: +#line 229 "parse_y.y" /* yacc.c:1652 */ + { PreLoadElementPCB (); + layer_group_string = NULL; } +#line 1888 "parse_y.c" /* yacc.c:1652 */ + break; + + case 9: +#line 232 "parse_y.y" /* yacc.c:1652 */ + { LayerFlag[0] = rnd_true; + LayerFlag[1] = rnd_true; + if (yyElemFixLayers) { + yyData->LayerN = 2; + free((char *)yyData->Layer[0].name); + yyData->Layer[0].name = rnd_strdup("top-silk"); + yyData->Layer[0].parent_type = PCB_PARENT_DATA; + yyData->Layer[0].parent.data = yyData; + yyData->Layer[0].is_bound = 1; + yyData->Layer[0].meta.bound.type = PCB_LYT_SILK | PCB_LYT_TOP; + free((char *)yyData->Layer[1].name); + yyData->Layer[1].name = rnd_strdup("bottom-silk"); + yyData->Layer[1].parent_type = PCB_PARENT_DATA; + yyData->Layer[1].parent.data = yyData; + yyData->Layer[1].is_bound = 1; + yyData->Layer[1].meta.bound.type = PCB_LYT_SILK | PCB_LYT_BOTTOM; + } + PostLoadElementPCB (); + } +#line 1912 "parse_y.c" /* yacc.c:1652 */ + break; + + case 10: +#line 254 "parse_y.y" /* yacc.c:1652 */ + { + /* reset flags for 'used layers'; + * init font and data pointers + */ + int i; + + if (!yyData || !yyFont) + { + rnd_message(RND_MSG_ERROR, "illegal fileformat\n"); + YYABORT; + } + for (i = 0; i < PCB_MAX_LAYER + 2; i++) + LayerFlag[i] = rnd_false; + yyData->LayerN = 0; + } +#line 1932 "parse_y.c" /* yacc.c:1652 */ + break; + + case 14: +#line 279 "parse_y.y" /* yacc.c:1652 */ + { + /* mark all symbols invalid */ + if (!yyFont) + { + rnd_message(RND_MSG_ERROR, "illegal fileformat\n"); + YYABORT; + } + if (yyFontReset) { + pcb_font_free (yyFont); + yyFont->id = 0; + } + *yyFontkitValid = rnd_false; + } +#line 1950 "parse_y.c" /* yacc.c:1652 */ + break; + + case 15: +#line 293 "parse_y.y" /* yacc.c:1652 */ + { + *yyFontkitValid = rnd_true; + pcb_font_set_info(yyFont); + } +#line 1959 "parse_y.c" /* yacc.c:1652 */ + break; + + case 17: +#line 302 "parse_y.y" /* yacc.c:1652 */ + { + if (check_file_version ((yyvsp[-1].integer)) != 0) + { + YYABORT; + } +} +#line 1970 "parse_y.c" /* yacc.c:1652 */ + break; + + case 18: +#line 312 "parse_y.y" /* yacc.c:1652 */ + { + yyPCB->hidlib.name = (yyvsp[-1].string); + yyPCB->hidlib.size_x = RND_MAX_COORD; + yyPCB->hidlib.size_y = RND_MAX_COORD; + old_fmt = 1; + } +#line 1981 "parse_y.c" /* yacc.c:1652 */ + break; + + case 19: +#line 319 "parse_y.y" /* yacc.c:1652 */ + { + yyPCB->hidlib.name = (yyvsp[-3].string); + yyPCB->hidlib.size_x = OU ((yyvsp[-2].measure)); + yyPCB->hidlib.size_y = OU ((yyvsp[-1].measure)); + old_fmt = 1; + } +#line 1992 "parse_y.c" /* yacc.c:1652 */ + break; + + case 20: +#line 326 "parse_y.y" /* yacc.c:1652 */ + { + yyPCB->hidlib.name = (yyvsp[-3].string); + yyPCB->hidlib.size_x = NU ((yyvsp[-2].measure)); + yyPCB->hidlib.size_y = NU ((yyvsp[-1].measure)); + old_fmt = 0; + } +#line 2003 "parse_y.c" /* yacc.c:1652 */ + break; + + case 24: +#line 341 "parse_y.y" /* yacc.c:1652 */ + { + yyPCB->hidlib.grid = OU ((yyvsp[-3].measure)); + yyPCB->hidlib.grid_ox = OU ((yyvsp[-2].measure)); + yyPCB->hidlib.grid_oy = OU ((yyvsp[-1].measure)); + } +#line 2013 "parse_y.c" /* yacc.c:1652 */ + break; + + case 25: +#line 349 "parse_y.y" /* yacc.c:1652 */ + { + yyPCB->hidlib.grid = OU ((yyvsp[-4].measure)); + yyPCB->hidlib.grid_ox = OU ((yyvsp[-3].measure)); + yyPCB->hidlib.grid_oy = OU ((yyvsp[-2].measure)); + if (yy_settings_dest != RND_CFR_invalid) { + if ((yyvsp[-1].integer)) + rnd_conf_set(yy_settings_dest, "editor/draw_grid", -1, "true", RND_POL_OVERWRITE); + else + rnd_conf_set(yy_settings_dest, "editor/draw_grid", -1, "false", RND_POL_OVERWRITE); + } + } +#line 2029 "parse_y.c" /* yacc.c:1652 */ + break; + + case 26: +#line 364 "parse_y.y" /* yacc.c:1652 */ + { + yyPCB->hidlib.grid = NU ((yyvsp[-4].measure)); + yyPCB->hidlib.grid_ox = NU ((yyvsp[-3].measure)); + yyPCB->hidlib.grid_oy = NU ((yyvsp[-2].measure)); + if (yy_settings_dest != RND_CFR_invalid) { + if ((yyvsp[-1].integer)) + rnd_conf_set(yy_settings_dest, "editor/draw_grid", -1, "true", RND_POL_OVERWRITE); + else + rnd_conf_set(yy_settings_dest, "editor/draw_grid", -1, "false", RND_POL_OVERWRITE); + } + } +#line 2045 "parse_y.c" /* yacc.c:1652 */ + break; + + case 27: +#line 379 "parse_y.y" /* yacc.c:1652 */ + { +/* Not loading cursor position and zoom anymore */ + } +#line 2053 "parse_y.c" /* yacc.c:1652 */ + break; + + case 28: +#line 383 "parse_y.y" /* yacc.c:1652 */ + { +/* Not loading cursor position and zoom anymore */ + } +#line 2061 "parse_y.c" /* yacc.c:1652 */ + break; + + case 31: +#line 392 "parse_y.y" /* yacc.c:1652 */ + { + /* Read in cmil^2 for now; in future this should be a noop. */ + load_meta_float("design/poly_isle_area", RND_MIL_TO_COORD(RND_MIL_TO_COORD ((yyvsp[-1].number)) / 100.0) / 100.0); + } +#line 2070 "parse_y.c" /* yacc.c:1652 */ + break; + + case 33: +#line 401 "parse_y.y" /* yacc.c:1652 */ + { + yyPCB->ThermScale = (yyvsp[-1].number); + } +#line 2078 "parse_y.c" /* yacc.c:1652 */ + break; + + case 38: +#line 415 "parse_y.y" /* yacc.c:1652 */ + { + load_meta_coord("design/bloat", NU((yyvsp[-3].measure))); + load_meta_coord("design/shrink", NU((yyvsp[-2].measure))); + load_meta_coord("design/min_wid", NU((yyvsp[-1].measure))); + load_meta_coord("design/min_ring", NU((yyvsp[-1].measure))); + } +#line 2089 "parse_y.c" /* yacc.c:1652 */ + break; + + case 39: +#line 425 "parse_y.y" /* yacc.c:1652 */ + { + load_meta_coord("design/bloat", NU((yyvsp[-4].measure))); + load_meta_coord("design/shrink", NU((yyvsp[-3].measure))); + load_meta_coord("design/min_wid", NU((yyvsp[-2].measure))); + load_meta_coord("design/min_slk", NU((yyvsp[-1].measure))); + load_meta_coord("design/min_ring", NU((yyvsp[-2].measure))); + } +#line 2101 "parse_y.c" /* yacc.c:1652 */ + break; + + case 40: +#line 436 "parse_y.y" /* yacc.c:1652 */ + { + load_meta_coord("design/bloat", NU((yyvsp[-6].measure))); + load_meta_coord("design/shrink", NU((yyvsp[-5].measure))); + load_meta_coord("design/min_wid", NU((yyvsp[-4].measure))); + load_meta_coord("design/min_slk", NU((yyvsp[-3].measure))); + load_meta_coord("design/min_drill", NU((yyvsp[-2].measure))); + load_meta_coord("design/min_ring", NU((yyvsp[-1].measure))); + } +#line 2114 "parse_y.c" /* yacc.c:1652 */ + break; + + case 41: +#line 448 "parse_y.y" /* yacc.c:1652 */ + { + yy_pcb_flags = pcb_flag_make((yyvsp[-1].integer) & PCB_FLAGS); + } +#line 2122 "parse_y.c" /* yacc.c:1652 */ + break; + + case 42: +#line 452 "parse_y.y" /* yacc.c:1652 */ + { + yy_pcb_flags = pcb_strflg_board_s2f((yyvsp[-1].string), yyerror); + free((yyvsp[-1].string)); + } +#line 2131 "parse_y.c" /* yacc.c:1652 */ + break; + + case 44: +#line 461 "parse_y.y" /* yacc.c:1652 */ + { + layer_group_string = (yyvsp[-1].string); + } +#line 2139 "parse_y.c" /* yacc.c:1652 */ + break; + + case 46: +#line 469 "parse_y.y" /* yacc.c:1652 */ + { + if (pcb_route_string_parse((yyvsp[-1].string), &yyPCB->RouteStyle, "mil")) + { + rnd_message(RND_MSG_ERROR, "illegal route-style string\n"); + YYABORT; + } + free((yyvsp[-1].string)); + } +#line 2152 "parse_y.c" /* yacc.c:1652 */ + break; + + case 47: +#line 478 "parse_y.y" /* yacc.c:1652 */ + { + if (pcb_route_string_parse(((yyvsp[-1].string) == NULL ? "" : (yyvsp[-1].string)), &yyPCB->RouteStyle, "cmil")) + { + rnd_message(RND_MSG_ERROR, "illegal route-style string\n"); + YYABORT; + } + free((yyvsp[-1].string)); + } +#line 2165 "parse_y.c" /* yacc.c:1652 */ + break; + + case 54: +#line 501 "parse_y.y" /* yacc.c:1652 */ + { attr_list = & yyPCB->Attributes; } +#line 2171 "parse_y.c" /* yacc.c:1652 */ + break; + + case 58: +#line 505 "parse_y.y" /* yacc.c:1652 */ + { + /* clear pointer to force memory allocation by + * the appropriate subroutine + */ + yysubc = NULL; + } +#line 2182 "parse_y.c" /* yacc.c:1652 */ + break; + + case 60: +#line 512 "parse_y.y" /* yacc.c:1652 */ + { YYABORT; } +#line 2188 "parse_y.c" /* yacc.c:1652 */ + break; + + case 66: +#line 526 "parse_y.y" /* yacc.c:1652 */ + { + pcb_old_via_new(yyData, -1, NU ((yyvsp[-8].measure)), NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), + NU ((yyvsp[-3].measure)), (yyvsp[-2].string), (yyvsp[-1].flagtype)); + free ((yyvsp[-2].string)); + } +#line 2198 "parse_y.c" /* yacc.c:1652 */ + break; + + case 67: +#line 536 "parse_y.y" /* yacc.c:1652 */ + { + pcb_old_via_new(yyData, -1, OU ((yyvsp[-8].measure)), OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), (yyvsp[-2].string), + pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-2].string)); + } +#line 2208 "parse_y.c" /* yacc.c:1652 */ + break; + + case 68: +#line 547 "parse_y.y" /* yacc.c:1652 */ + { + pcb_old_via_new(yyData, -1, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), + OU ((yyvsp[-5].measure)) + OU((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), (yyvsp[-2].string), pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-2].string)); + } +#line 2218 "parse_y.c" /* yacc.c:1652 */ + break; + + case 69: +#line 557 "parse_y.y" /* yacc.c:1652 */ + { + pcb_old_via_new(yyData, -1, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), 2*PCB_GROUNDPLANEFRAME, + OU((yyvsp[-4].measure)) + 2*PCB_MASKFRAME, OU ((yyvsp[-3].measure)), (yyvsp[-2].string), pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-2].string)); + } +#line 2228 "parse_y.c" /* yacc.c:1652 */ + break; + + case 70: +#line 567 "parse_y.y" /* yacc.c:1652 */ + { + rnd_coord_t hole = (OU((yyvsp[-3].measure)) * PCB_DEFAULT_DRILLINGHOLE); + + /* make sure that there's enough copper left */ + if (OU((yyvsp[-3].measure)) - hole < PCB_MIN_PINORVIACOPPER && + OU((yyvsp[-3].measure)) > PCB_MIN_PINORVIACOPPER) + hole = OU((yyvsp[-3].measure)) - PCB_MIN_PINORVIACOPPER; + + pcb_old_via_new(yyData, -1, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), 2*PCB_GROUNDPLANEFRAME, + OU((yyvsp[-3].measure)) + 2*PCB_MASKFRAME, hole, (yyvsp[-2].string), pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-2].string)); + } +#line 2245 "parse_y.c" /* yacc.c:1652 */ + break; + + case 71: +#line 583 "parse_y.y" /* yacc.c:1652 */ + { + pcb_rat_new(yyData, -1, NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), NU ((yyvsp[-4].measure)), NU ((yyvsp[-3].measure)), (yyvsp[-5].integer), (yyvsp[-2].integer), + conf_core.appearance.rat_thickness, (yyvsp[-1].flagtype), NULL, NULL); + } +#line 2254 "parse_y.c" /* yacc.c:1652 */ + break; + + case 72: +#line 588 "parse_y.y" /* yacc.c:1652 */ + { + pcb_rat_new(yyData, -1, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), (yyvsp[-5].integer), (yyvsp[-2].integer), + conf_core.appearance.rat_thickness, pcb_flag_old((yyvsp[-1].integer)), NULL, NULL); + } +#line 2263 "parse_y.c" /* yacc.c:1652 */ + break; + + case 73: +#line 597 "parse_y.y" /* yacc.c:1652 */ + { + if ((yyvsp[-4].integer) <= 0 || (yyvsp[-4].integer) > PCB_MAX_LAYER) + { + yyerror("Layernumber out of range"); + YYABORT; + } + if (LayerFlag[(yyvsp[-4].integer)-1]) + { + yyerror("Layernumber used twice"); + YYABORT; + } + Layer = &yyData->Layer[(yyvsp[-4].integer)-1]; + Layer->parent.data = yyData; + Layer->parent_type = PCB_PARENT_DATA; + Layer->type = PCB_OBJ_LAYER; + + /* memory for name is already allocated */ + if (Layer->name != NULL) + free((char*)Layer->name); + Layer->name = (yyvsp[-3].string); /* shouldn't this be strdup()'ed ? */ + LayerFlag[(yyvsp[-4].integer)-1] = rnd_true; + if (yyData->LayerN < (yyvsp[-4].integer)) + yyData->LayerN = (yyvsp[-4].integer); + if ((yyvsp[-2].string) != NULL) + free((yyvsp[-2].string)); + } +#line 2294 "parse_y.c" /* yacc.c:1652 */ + break; + + case 85: +#line 645 "parse_y.y" /* yacc.c:1652 */ + { + pcb_poly_new_from_rectangle(Layer, + OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-5].measure)) + OU ((yyvsp[-3].measure)), OU ((yyvsp[-4].measure)) + OU ((yyvsp[-2].measure)), 0, pcb_flag_old((yyvsp[-1].integer))); + } +#line 2303 "parse_y.c" /* yacc.c:1652 */ + break; + + case 89: +#line 652 "parse_y.y" /* yacc.c:1652 */ + { attr_list = & Layer->Attributes; } +#line 2309 "parse_y.c" /* yacc.c:1652 */ + break; + + case 92: +#line 658 "parse_y.y" /* yacc.c:1652 */ + { + pcb_line_new(Layer, NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), + NU ((yyvsp[-3].measure)), NU ((yyvsp[-2].measure)), (yyvsp[-1].flagtype)); + } +#line 2318 "parse_y.c" /* yacc.c:1652 */ + break; + + case 93: +#line 667 "parse_y.y" /* yacc.c:1652 */ + { + pcb_line_new(Layer, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), + OU ((yyvsp[-3].measure)), OU ((yyvsp[-2].measure)), pcb_flag_old((yyvsp[-1].integer))); + } +#line 2327 "parse_y.c" /* yacc.c:1652 */ + break; + + case 94: +#line 676 "parse_y.y" /* yacc.c:1652 */ + { + /* eliminate old-style rat-lines */ + if ((IV ((yyvsp[-1].measure)) & PCB_FLAG_RAT) == 0) + pcb_line_new(Layer, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), OU ((yyvsp[-2].measure)), + 200*PCB_GROUNDPLANEFRAME, pcb_flag_old(IV ((yyvsp[-1].measure)))); + } +#line 2338 "parse_y.c" /* yacc.c:1652 */ + break; + + case 95: +#line 687 "parse_y.y" /* yacc.c:1652 */ + { + pcb_arc_new(Layer, NU ((yyvsp[-9].measure)), NU ((yyvsp[-8].measure)), NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), (yyvsp[-3].number), (yyvsp[-2].number), + NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), (yyvsp[-1].flagtype), rnd_true); + } +#line 2347 "parse_y.c" /* yacc.c:1652 */ + break; + + case 96: +#line 696 "parse_y.y" /* yacc.c:1652 */ + { + pcb_arc_new(Layer, OU ((yyvsp[-9].measure)), OU ((yyvsp[-8].measure)), OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), (yyvsp[-3].number), (yyvsp[-2].number), + OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), pcb_flag_old((yyvsp[-1].integer)), rnd_true); + } +#line 2356 "parse_y.c" /* yacc.c:1652 */ + break; + + case 97: +#line 705 "parse_y.y" /* yacc.c:1652 */ + { + pcb_arc_new(Layer, OU ((yyvsp[-8].measure)), OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-6].measure)), IV ((yyvsp[-3].measure)), (yyvsp[-2].number), + OU ((yyvsp[-4].measure)), 200*PCB_GROUNDPLANEFRAME, pcb_flag_old((yyvsp[-1].integer)), rnd_true); + } +#line 2365 "parse_y.c" /* yacc.c:1652 */ + break; + + case 98: +#line 714 "parse_y.y" /* yacc.c:1652 */ + { + /* use a default scale of 100% */ + pcb_text_new(Layer,yyFont,OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), (yyvsp[-3].number) * 90.0, 100, 0, (yyvsp[-2].string), pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-2].string)); + } +#line 2375 "parse_y.c" /* yacc.c:1652 */ + break; + + case 99: +#line 724 "parse_y.y" /* yacc.c:1652 */ + { + if ((yyvsp[-1].integer) & PCB_FLAG_ONSILK) + { + pcb_layer_t *lay = &yyData->Layer[yyData->LayerN + + (((yyvsp[-1].integer) & PCB_FLAG_ONSOLDER) ? PCB_SOLDER_SIDE : PCB_COMPONENT_SIDE) - 2]; + + pcb_text_new(lay ,yyFont, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), (yyvsp[-4].number) * 90.0, (yyvsp[-3].number), 0, (yyvsp[-2].string), + pcb_flag_old((yyvsp[-1].integer))); + } + else + pcb_text_new(Layer, yyFont, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), (yyvsp[-4].number) * 90.0, (yyvsp[-3].number), 0, (yyvsp[-2].string), + pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-2].string)); + } +#line 2394 "parse_y.c" /* yacc.c:1652 */ + break; + + case 100: +#line 742 "parse_y.y" /* yacc.c:1652 */ + { + /* FIXME: shouldn't know about .f */ + /* I don't think this matters because anything with hi_format + * will have the silk on its own layer in the file rather + * than using the PCB_FLAG_ONSILK and having it in a copper layer. + * Thus there is no need for anything besides the 'else' + * part of this code. + */ + if ((yyvsp[-1].flagtype).f & PCB_FLAG_ONSILK) + { + pcb_layer_t *lay = &yyData->Layer[yyData->LayerN + + (((yyvsp[-1].flagtype).f & PCB_FLAG_ONSOLDER) ? PCB_SOLDER_SIDE : PCB_COMPONENT_SIDE) - 2]; + + pcb_text_new(lay, yyFont, NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), (yyvsp[-4].number) * 90.0, (yyvsp[-3].number), 0, (yyvsp[-2].string), (yyvsp[-1].flagtype)); + } + else + pcb_text_new(Layer, yyFont, NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), (yyvsp[-4].number) * 90.0, (yyvsp[-3].number), 0, (yyvsp[-2].string), (yyvsp[-1].flagtype)); + free ((yyvsp[-2].string)); + } +#line 2418 "parse_y.c" /* yacc.c:1652 */ + break; + + case 101: +#line 766 "parse_y.y" /* yacc.c:1652 */ + { + Polygon = pcb_poly_new(Layer, 0, (yyvsp[-2].flagtype)); + } +#line 2426 "parse_y.c" /* yacc.c:1652 */ + break; + + case 102: +#line 771 "parse_y.y" /* yacc.c:1652 */ + { + rnd_cardinal_t contour, contour_start, contour_end; + rnd_bool bad_contour_found = rnd_false; + /* ignore junk */ + for (contour = 0; contour <= Polygon->HoleIndexN; contour++) + { + contour_start = (contour == 0) ? + 0 : Polygon->HoleIndex[contour - 1]; + contour_end = (contour == Polygon->HoleIndexN) ? + Polygon->PointN : + Polygon->HoleIndex[contour]; + if (contour_end - contour_start < 3) + bad_contour_found = rnd_true; + } + + if (bad_contour_found) + { + rnd_message(RND_MSG_WARNING, "WARNING parsing file '%s'\n" + " line: %i\n" + " description: 'ignored polygon (< 3 points in a contour)'\n", + yyfilename, pcb_lineno); + pcb_destroy_object(yyData, PCB_OBJ_POLY, Layer, Polygon, Polygon); + } + else + { + pcb_poly_bbox(Polygon); + if (!Layer->polygon_tree) + Layer->polygon_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + } + } +#line 2462 "parse_y.c" /* yacc.c:1652 */ + break; + + case 105: +#line 811 "parse_y.y" /* yacc.c:1652 */ + { + pcb_poly_hole_new(Polygon); + } +#line 2470 "parse_y.c" /* yacc.c:1652 */ + break; + + case 109: +#line 825 "parse_y.y" /* yacc.c:1652 */ + { + pcb_poly_point_new(Polygon, OU ((yyvsp[-2].measure)), OU ((yyvsp[-1].measure))); + } +#line 2478 "parse_y.c" /* yacc.c:1652 */ + break; + + case 110: +#line 829 "parse_y.y" /* yacc.c:1652 */ + { + pcb_poly_point_new(Polygon, NU ((yyvsp[-2].measure)), NU ((yyvsp[-1].measure))); + } +#line 2486 "parse_y.c" /* yacc.c:1652 */ + break; + + case 116: +#line 847 "parse_y.y" /* yacc.c:1652 */ + { + yysubc = io_pcb_element_new(yyData, yysubc, yyFont, pcb_no_flags(), + (yyvsp[-6].string), (yyvsp[-5].string), NULL, OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), (yyvsp[-2].integer), 100, pcb_no_flags(), rnd_false); + free ((yyvsp[-6].string)); + free ((yyvsp[-5].string)); + pin_num = 1; + } +#line 2498 "parse_y.c" /* yacc.c:1652 */ + break; + + case 117: +#line 855 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_fin(yyData); + } +#line 2506 "parse_y.c" /* yacc.c:1652 */ + break; + + case 118: +#line 865 "parse_y.y" /* yacc.c:1652 */ + { + yysubc = io_pcb_element_new(yyData, yysubc, yyFont, pcb_flag_old((yyvsp[-9].integer)), + (yyvsp[-8].string), (yyvsp[-7].string), NULL, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), IV ((yyvsp[-4].measure)), IV ((yyvsp[-3].measure)), pcb_flag_old((yyvsp[-2].integer)), rnd_false); + free ((yyvsp[-8].string)); + free ((yyvsp[-7].string)); + pin_num = 1; + } +#line 2518 "parse_y.c" /* yacc.c:1652 */ + break; + + case 119: +#line 873 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_fin(yyData); + } +#line 2526 "parse_y.c" /* yacc.c:1652 */ + break; + + case 120: +#line 883 "parse_y.y" /* yacc.c:1652 */ + { + yysubc = io_pcb_element_new(yyData, yysubc, yyFont, pcb_flag_old((yyvsp[-10].integer)), + (yyvsp[-9].string), (yyvsp[-8].string), (yyvsp[-7].string), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), IV ((yyvsp[-4].measure)), IV ((yyvsp[-3].measure)), pcb_flag_old((yyvsp[-2].integer)), rnd_false); + free ((yyvsp[-9].string)); + free ((yyvsp[-8].string)); + free ((yyvsp[-7].string)); + pin_num = 1; + } +#line 2539 "parse_y.c" /* yacc.c:1652 */ + break; + + case 121: +#line 892 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_fin(yyData); + } +#line 2547 "parse_y.c" /* yacc.c:1652 */ + break; + + case 122: +#line 903 "parse_y.y" /* yacc.c:1652 */ + { + yysubc = io_pcb_element_new(yyData, yysubc, yyFont, pcb_flag_old((yyvsp[-12].integer)), + (yyvsp[-11].string), (yyvsp[-10].string), (yyvsp[-9].string), OU ((yyvsp[-8].measure)) + OU ((yyvsp[-6].measure)), OU ((yyvsp[-7].measure)) + OU ((yyvsp[-5].measure)), + (yyvsp[-4].number), (yyvsp[-3].number), pcb_flag_old((yyvsp[-2].integer)), rnd_false); + yysubc_ox = OU ((yyvsp[-8].measure)); + yysubc_oy = OU ((yyvsp[-7].measure)); + free ((yyvsp[-11].string)); + free ((yyvsp[-10].string)); + free ((yyvsp[-9].string)); + } +#line 2562 "parse_y.c" /* yacc.c:1652 */ + break; + + case 123: +#line 914 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_fin(yyData); + } +#line 2570 "parse_y.c" /* yacc.c:1652 */ + break; + + case 124: +#line 925 "parse_y.y" /* yacc.c:1652 */ + { + yysubc = io_pcb_element_new(yyData, yysubc, yyFont, (yyvsp[-12].flagtype), + (yyvsp[-11].string), (yyvsp[-10].string), (yyvsp[-9].string), NU ((yyvsp[-8].measure)) + NU ((yyvsp[-6].measure)), NU ((yyvsp[-7].measure)) + NU ((yyvsp[-5].measure)), + (yyvsp[-4].number), (yyvsp[-3].number), (yyvsp[-2].flagtype), rnd_false); + yysubc_ox = NU ((yyvsp[-8].measure)); + yysubc_oy = NU ((yyvsp[-7].measure)); + free ((yyvsp[-11].string)); + free ((yyvsp[-10].string)); + free ((yyvsp[-9].string)); + } +#line 2585 "parse_y.c" /* yacc.c:1652 */ + break; + + case 125: +#line 936 "parse_y.y" /* yacc.c:1652 */ + { + if (pcb_subc_is_empty(yysubc)) { + pcb_subc_free(yysubc); + yysubc = NULL; + } + else { + io_pcb_element_fin(yyData); + } + } +#line 2599 "parse_y.c" /* yacc.c:1652 */ + break; + + case 133: +#line 960 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_line_new(yysubc, NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), NU ((yyvsp[-3].measure)), NU ((yyvsp[-2].measure)), NU ((yyvsp[-1].measure))); + } +#line 2607 "parse_y.c" /* yacc.c:1652 */ + break; + + case 134: +#line 965 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_line_new(yysubc, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), OU ((yyvsp[-2].measure)), OU ((yyvsp[-1].measure))); + } +#line 2615 "parse_y.c" /* yacc.c:1652 */ + break; + + case 135: +#line 970 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_arc_new(yysubc, NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), (yyvsp[-3].number), (yyvsp[-2].number), NU ((yyvsp[-1].measure))); + } +#line 2623 "parse_y.c" /* yacc.c:1652 */ + break; + + case 136: +#line 975 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_arc_new(yysubc, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), (yyvsp[-3].number), (yyvsp[-2].number), OU ((yyvsp[-1].measure))); + } +#line 2631 "parse_y.c" /* yacc.c:1652 */ + break; + + case 137: +#line 980 "parse_y.y" /* yacc.c:1652 */ + { + yysubc_ox = NU ((yyvsp[-2].measure)); + yysubc_oy = NU ((yyvsp[-1].measure)); + } +#line 2640 "parse_y.c" /* yacc.c:1652 */ + break; + + case 138: +#line 985 "parse_y.y" /* yacc.c:1652 */ + { + yysubc_ox = OU ((yyvsp[-2].measure)); + yysubc_oy = OU ((yyvsp[-1].measure)); + } +#line 2649 "parse_y.c" /* yacc.c:1652 */ + break; + + case 139: +#line 989 "parse_y.y" /* yacc.c:1652 */ + { attr_list = & yysubc->Attributes; } +#line 2655 "parse_y.c" /* yacc.c:1652 */ + break; + + case 147: +#line 1004 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_line_new(yysubc, NU ((yyvsp[-5].measure)) + yysubc_ox, + NU ((yyvsp[-4].measure)) + yysubc_oy, NU ((yyvsp[-3].measure)) + yysubc_ox, + NU ((yyvsp[-2].measure)) + yysubc_oy, NU ((yyvsp[-1].measure))); + } +#line 2665 "parse_y.c" /* yacc.c:1652 */ + break; + + case 148: +#line 1010 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_line_new(yysubc, OU ((yyvsp[-5].measure)) + yysubc_ox, + OU ((yyvsp[-4].measure)) + yysubc_oy, OU ((yyvsp[-3].measure)) + yysubc_ox, + OU ((yyvsp[-2].measure)) + yysubc_oy, OU ((yyvsp[-1].measure))); + } +#line 2675 "parse_y.c" /* yacc.c:1652 */ + break; + + case 149: +#line 1017 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_arc_new(yysubc, NU ((yyvsp[-7].measure)) + yysubc_ox, + NU ((yyvsp[-6].measure)) + yysubc_oy, NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), (yyvsp[-3].number), (yyvsp[-2].number), NU ((yyvsp[-1].measure))); + } +#line 2684 "parse_y.c" /* yacc.c:1652 */ + break; + + case 150: +#line 1022 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_arc_new(yysubc, OU ((yyvsp[-7].measure)) + yysubc_ox, + OU ((yyvsp[-6].measure)) + yysubc_oy, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), (yyvsp[-3].number), (yyvsp[-2].number), OU ((yyvsp[-1].measure))); + } +#line 2693 "parse_y.c" /* yacc.c:1652 */ + break; + + case 151: +#line 1026 "parse_y.y" /* yacc.c:1652 */ + { attr_list = & yysubc->Attributes; } +#line 2699 "parse_y.c" /* yacc.c:1652 */ + break; + + case 153: +#line 1033 "parse_y.y" /* yacc.c:1652 */ + { + pcb_pstk_t *pin = io_pcb_element_pin_new(yysubc, NU ((yyvsp[-9].measure)) + yysubc_ox, + NU ((yyvsp[-8].measure)) + yysubc_oy, NU ((yyvsp[-7].measure)), NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), (yyvsp[-3].string), + (yyvsp[-2].string), (yyvsp[-1].flagtype)); + pcb_attrib_compat_set_intconn(&pin->Attributes, yy_intconn); + free ((yyvsp[-3].string)); + free ((yyvsp[-2].string)); + } +#line 2712 "parse_y.c" /* yacc.c:1652 */ + break; + + case 154: +#line 1046 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_pin_new(yysubc, OU ((yyvsp[-9].measure)) + yysubc_ox, + OU ((yyvsp[-8].measure)) + yysubc_oy, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), (yyvsp[-3].string), + (yyvsp[-2].string), pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-3].string)); + free ((yyvsp[-2].string)); + } +#line 2724 "parse_y.c" /* yacc.c:1652 */ + break; + + case 155: +#line 1058 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_pin_new(yysubc, OU ((yyvsp[-7].measure)), OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), 2*PCB_GROUNDPLANEFRAME, + OU ((yyvsp[-5].measure)) + 2*PCB_MASKFRAME, OU ((yyvsp[-4].measure)), (yyvsp[-3].string), (yyvsp[-2].string), pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-3].string)); + free ((yyvsp[-2].string)); + } +#line 2735 "parse_y.c" /* yacc.c:1652 */ + break; + + case 156: +#line 1069 "parse_y.y" /* yacc.c:1652 */ + { + char p_number[8]; + + sprintf(p_number, "%d", pin_num++); + io_pcb_element_pin_new(yysubc, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), 2*PCB_GROUNDPLANEFRAME, + OU ((yyvsp[-4].measure)) + 2*PCB_MASKFRAME, OU ((yyvsp[-3].measure)), (yyvsp[-2].string), p_number, pcb_flag_old((yyvsp[-1].integer))); + + free ((yyvsp[-2].string)); + } +#line 2749 "parse_y.c" /* yacc.c:1652 */ + break; + + case 157: +#line 1085 "parse_y.y" /* yacc.c:1652 */ + { + rnd_coord_t hole = OU ((yyvsp[-3].measure)) * PCB_DEFAULT_DRILLINGHOLE; + char p_number[8]; + + /* make sure that there's enough copper left */ + if (OU ((yyvsp[-3].measure)) - hole < PCB_MIN_PINORVIACOPPER && + OU ((yyvsp[-3].measure)) > PCB_MIN_PINORVIACOPPER) + hole = OU ((yyvsp[-3].measure)) - PCB_MIN_PINORVIACOPPER; + + sprintf(p_number, "%d", pin_num++); + io_pcb_element_pin_new(yysubc, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), 2*PCB_GROUNDPLANEFRAME, + OU ((yyvsp[-3].measure)) + 2*PCB_MASKFRAME, hole, (yyvsp[-2].string), p_number, pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-2].string)); + } +#line 2768 "parse_y.c" /* yacc.c:1652 */ + break; + + case 158: +#line 1104 "parse_y.y" /* yacc.c:1652 */ + { + pcb_pstk_t *pad = io_pcb_element_pad_new(yysubc, NU ((yyvsp[-10].measure)) + yysubc_ox, + NU ((yyvsp[-9].measure)) + yysubc_oy, + NU ((yyvsp[-8].measure)) + yysubc_ox, + NU ((yyvsp[-7].measure)) + yysubc_oy, NU ((yyvsp[-6].measure)), NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), + (yyvsp[-3].string), (yyvsp[-2].string), (yyvsp[-1].flagtype)); + pcb_attrib_compat_set_intconn(&pad->Attributes, yy_intconn); + free ((yyvsp[-3].string)); + free ((yyvsp[-2].string)); + } +#line 2783 "parse_y.c" /* yacc.c:1652 */ + break; + + case 159: +#line 1119 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_pad_new(yysubc,OU ((yyvsp[-10].measure)) + yysubc_ox, + OU ((yyvsp[-9].measure)) + yysubc_oy, OU ((yyvsp[-8].measure)) + yysubc_ox, + OU ((yyvsp[-7].measure)) + yysubc_oy, OU ((yyvsp[-6].measure)), OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), + (yyvsp[-3].string), (yyvsp[-2].string), pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-3].string)); + free ((yyvsp[-2].string)); + } +#line 2796 "parse_y.c" /* yacc.c:1652 */ + break; + + case 160: +#line 1132 "parse_y.y" /* yacc.c:1652 */ + { + io_pcb_element_pad_new(yysubc,OU ((yyvsp[-8].measure)),OU ((yyvsp[-7].measure)),OU ((yyvsp[-6].measure)),OU ((yyvsp[-5].measure)),OU ((yyvsp[-4].measure)), 2*PCB_GROUNDPLANEFRAME, + OU ((yyvsp[-4].measure)) + 2*PCB_MASKFRAME, (yyvsp[-3].string), (yyvsp[-2].string), pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-3].string)); + free ((yyvsp[-2].string)); + } +#line 2807 "parse_y.c" /* yacc.c:1652 */ + break; + + case 161: +#line 1143 "parse_y.y" /* yacc.c:1652 */ + { + char p_number[8]; + + sprintf(p_number, "%d", pin_num++); + io_pcb_element_pad_new(yysubc,OU ((yyvsp[-7].measure)),OU ((yyvsp[-6].measure)),OU ((yyvsp[-5].measure)),OU ((yyvsp[-4].measure)),OU ((yyvsp[-3].measure)), 2*PCB_GROUNDPLANEFRAME, + OU ((yyvsp[-3].measure)) + 2*PCB_MASKFRAME, (yyvsp[-2].string),p_number, pcb_flag_old((yyvsp[-1].integer))); + free ((yyvsp[-2].string)); + } +#line 2820 "parse_y.c" /* yacc.c:1652 */ + break; + + case 162: +#line 1153 "parse_y.y" /* yacc.c:1652 */ + { (yyval.flagtype) = pcb_flag_old((yyvsp[0].integer)); } +#line 2826 "parse_y.c" /* yacc.c:1652 */ + break; + + case 163: +#line 1154 "parse_y.y" /* yacc.c:1652 */ + { (yyval.flagtype) = pcb_strflg_s2f((yyvsp[0].string), yyerror, &yy_intconn, 1); free((yyvsp[0].string)); } +#line 2832 "parse_y.c" /* yacc.c:1652 */ + break; + + case 167: +#line 1165 "parse_y.y" /* yacc.c:1652 */ + { + if ((yyvsp[-3].integer) <= 0 || (yyvsp[-3].integer) > PCB_MAX_FONTPOSITION) + { + yyerror("fontposition out of range"); + YYABORT; + } + Symbol = &yyFont->Symbol[(yyvsp[-3].integer)]; + if (Symbol->Valid) + { + yyerror("symbol ID used twice"); + YYABORT; + } + Symbol->Valid = rnd_true; + Symbol->Delta = NU ((yyvsp[-2].measure)); + } +#line 2852 "parse_y.c" /* yacc.c:1652 */ + break; + + case 168: +#line 1181 "parse_y.y" /* yacc.c:1652 */ + { + if ((yyvsp[-3].integer) <= 0 || (yyvsp[-3].integer) > PCB_MAX_FONTPOSITION) + { + yyerror("fontposition out of range"); + YYABORT; + } + Symbol = &yyFont->Symbol[(yyvsp[-3].integer)]; + if (Symbol->Valid) + { + yyerror("symbol ID used twice"); + YYABORT; + } + Symbol->Valid = rnd_true; + Symbol->Delta = OU ((yyvsp[-2].measure)); + } +#line 2872 "parse_y.c" /* yacc.c:1652 */ + break; + + case 174: +#line 1212 "parse_y.y" /* yacc.c:1652 */ + { + pcb_font_new_line_in_sym(Symbol, OU ((yyvsp[-5].measure)), OU ((yyvsp[-4].measure)), OU ((yyvsp[-3].measure)), OU ((yyvsp[-2].measure)), OU ((yyvsp[-1].measure))); + } +#line 2880 "parse_y.c" /* yacc.c:1652 */ + break; + + case 175: +#line 1219 "parse_y.y" /* yacc.c:1652 */ + { + pcb_font_new_line_in_sym(Symbol, NU ((yyvsp[-5].measure)), NU ((yyvsp[-4].measure)), NU ((yyvsp[-3].measure)), NU ((yyvsp[-2].measure)), NU ((yyvsp[-1].measure))); + } +#line 2888 "parse_y.c" /* yacc.c:1652 */ + break; + + case 183: +#line 1246 "parse_y.y" /* yacc.c:1652 */ + { + currnet = pcb_net_get(yyPCB, &yyPCB->netlist[PCB_NETLIST_INPUT], (yyvsp[-3].string), PCB_NETA_ALLOC); + if (((yyvsp[-2].string) != NULL) && (*(yyvsp[-2].string) != '\0')) + pcb_attribute_put(&currnet->Attributes, "style", (yyvsp[-2].string)); + free ((yyvsp[-3].string)); + free ((yyvsp[-2].string)); + } +#line 2900 "parse_y.c" /* yacc.c:1652 */ + break; + + case 189: +#line 1268 "parse_y.y" /* yacc.c:1652 */ + { + pcb_net_term_get_by_pinname(currnet, (yyvsp[-1].string), 1); + free ((yyvsp[-1].string)); + } +#line 2909 "parse_y.c" /* yacc.c:1652 */ + break; + + case 197: +#line 1315 "parse_y.y" /* yacc.c:1652 */ + { pcb_ratspatch_append(yyPCB, RATP_ADD_CONN, (yyvsp[-2].string), (yyvsp[-1].string), NULL, 0); free((yyvsp[-2].string)); free((yyvsp[-1].string)); } +#line 2915 "parse_y.c" /* yacc.c:1652 */ + break; + + case 198: +#line 1316 "parse_y.y" /* yacc.c:1652 */ + { pcb_ratspatch_append(yyPCB, RATP_DEL_CONN, (yyvsp[-2].string), (yyvsp[-1].string), NULL, 0); free((yyvsp[-2].string)); free((yyvsp[-1].string)); } +#line 2921 "parse_y.c" /* yacc.c:1652 */ + break; + + case 199: +#line 1317 "parse_y.y" /* yacc.c:1652 */ + { pcb_ratspatch_append(yyPCB, RATP_CHANGE_ATTRIB, (yyvsp[-3].string), (yyvsp[-2].string), (yyvsp[-1].string), 0); free((yyvsp[-3].string)); free((yyvsp[-2].string)); free((yyvsp[-1].string)); } +#line 2927 "parse_y.c" /* yacc.c:1652 */ + break; + + case 200: +#line 1322 "parse_y.y" /* yacc.c:1652 */ + { + char *old_val, *key = (yyvsp[-2].string), *val = (yyvsp[-1].string) ? (yyvsp[-1].string) : (char *)""; + old_val = pcb_attribute_get(attr_list, key); + if (old_val != NULL) + rnd_message(RND_MSG_ERROR, "mutliple values for attribute %s: '%s' and '%s' - ignoring '%s'\n", key, old_val, val, val); + else + pcb_attribute_put(attr_list, key, val); + free(key); + free(val); + } +#line 2942 "parse_y.c" /* yacc.c:1652 */ + break; + + case 201: +#line 1334 "parse_y.y" /* yacc.c:1652 */ + { (yyval.string) = (yyvsp[0].string); } +#line 2948 "parse_y.c" /* yacc.c:1652 */ + break; + + case 202: +#line 1335 "parse_y.y" /* yacc.c:1652 */ + { (yyval.string) = 0; } +#line 2954 "parse_y.c" /* yacc.c:1652 */ + break; + + case 203: +#line 1339 "parse_y.y" /* yacc.c:1652 */ + { (yyval.number) = (yyvsp[0].number); } +#line 2960 "parse_y.c" /* yacc.c:1652 */ + break; + + case 204: +#line 1340 "parse_y.y" /* yacc.c:1652 */ + { (yyval.number) = (yyvsp[0].integer); } +#line 2966 "parse_y.c" /* yacc.c:1652 */ + break; + + case 205: +#line 1345 "parse_y.y" /* yacc.c:1652 */ + { do_measure(&(yyval.measure), (yyvsp[0].number), RND_MIL_TO_COORD ((yyvsp[0].number)) / 100.0, 0); } +#line 2972 "parse_y.c" /* yacc.c:1652 */ + break; + + case 206: +#line 1346 "parse_y.y" /* yacc.c:1652 */ + { M ((yyval.measure), (yyvsp[-1].number), RND_MIL_TO_COORD ((yyvsp[-1].number)) / 100000.0); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } +#line 2978 "parse_y.c" /* yacc.c:1652 */ + break; + + case 207: +#line 1347 "parse_y.y" /* yacc.c:1652 */ + { M ((yyval.measure), (yyvsp[-1].number), RND_MIL_TO_COORD ((yyvsp[-1].number)) / 100.0); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } +#line 2984 "parse_y.c" /* yacc.c:1652 */ + break; + + case 208: +#line 1348 "parse_y.y" /* yacc.c:1652 */ + { M ((yyval.measure), (yyvsp[-1].number), RND_MIL_TO_COORD ((yyvsp[-1].number))); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } +#line 2990 "parse_y.c" /* yacc.c:1652 */ + break; + + case 209: +#line 1349 "parse_y.y" /* yacc.c:1652 */ + { M ((yyval.measure), (yyvsp[-1].number), RND_INCH_TO_COORD ((yyvsp[-1].number))); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } +#line 2996 "parse_y.c" /* yacc.c:1652 */ + break; + + case 210: +#line 1350 "parse_y.y" /* yacc.c:1652 */ + { M ((yyval.measure), (yyvsp[-1].number), RND_MM_TO_COORD ((yyvsp[-1].number)) / 1000000.0); pcb_io_pcb_usty_seen |= PCB_USTY_NANOMETER; } +#line 3002 "parse_y.c" /* yacc.c:1652 */ + break; + + case 211: +#line 1351 "parse_y.y" /* yacc.c:1652 */ + { M ((yyval.measure), (yyvsp[-1].number), RND_MM_TO_COORD ((yyvsp[-1].number)) / 1000.0); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } +#line 3008 "parse_y.c" /* yacc.c:1652 */ + break; + + case 212: +#line 1352 "parse_y.y" /* yacc.c:1652 */ + { M ((yyval.measure), (yyvsp[-1].number), RND_MM_TO_COORD ((yyvsp[-1].number))); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } +#line 3014 "parse_y.c" /* yacc.c:1652 */ + break; + + case 213: +#line 1353 "parse_y.y" /* yacc.c:1652 */ + { M ((yyval.measure), (yyvsp[-1].number), RND_MM_TO_COORD ((yyvsp[-1].number)) * 1000.0); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } +#line 3020 "parse_y.c" /* yacc.c:1652 */ + break; + + case 214: +#line 1354 "parse_y.y" /* yacc.c:1652 */ + { M ((yyval.measure), (yyvsp[-1].number), RND_MM_TO_COORD ((yyvsp[-1].number)) * 1000000.0); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } +#line 3026 "parse_y.c" /* yacc.c:1652 */ + break; + + +#line 3030 "parse_y.c" /* yacc.c:1652 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} +#line 1357 "parse_y.y" /* yacc.c:1918 */ + + +/* --------------------------------------------------------------------------- + * error routine called by parser library + */ +int yyerror(const char * s) +{ + rnd_message(RND_MSG_ERROR, "ERROR parsing file '%s'\n" + " line: %i\n" + " description: '%s'\n", + yyfilename, pcb_lineno, s); + return(0); +} + +int pcb_wrap() +{ + return 1; +} + +static int +check_file_version (int ver) +{ + if ( ver > PCB_FILE_VERSION ) { + rnd_message(RND_MSG_ERROR, "ERROR: The file you are attempting to load is in a format\n" + "which is too new for this version of pcb. To load this file\n" + "you need a version of pcb which is >= %d. If you are\n" + "using a version built from git source, the source date\n" + "must be >= %d. This copy of pcb can only read files\n" + "up to file version %d.\n", ver, ver, PCB_FILE_VERSION); + return 1; + } + + return 0; +} + +static void +do_measure (PLMeasure *m, rnd_coord_t i, double d, int u) +{ + m->ival = i; + m->bval = rnd_round(d); + m->dval = d; + m->has_units = u; +} + +static int +integer_value (PLMeasure m) +{ + if (m.has_units) + yyerror("units ignored here"); + return m.ival; +} + +static rnd_coord_t +old_units (PLMeasure m) +{ + if (m.has_units) + return m.bval; + if (m.ival != 0) + pcb_io_pcb_usty_seen |= PCB_USTY_CMIL; /* ... because we can't save in mil */ + return rnd_round(RND_MIL_TO_COORD (m.ival)); +} + +static rnd_coord_t +new_units (PLMeasure m) +{ + if (m.has_units) + return m.bval; + if (m.dval != 0) + pcb_io_pcb_usty_seen |= PCB_USTY_CMIL; + /* if there's no unit m.dval already contains the converted value */ + return rnd_round(m.dval); +} + +/* This converts old flag bits (from saved PCB files) to new format. */ +static pcb_flag_t pcb_flag_old(unsigned int flags) +{ + pcb_flag_t rv; + int i, f; + memset(&rv, 0, sizeof(rv)); + /* If we move flag bits around, this is where we map old bits to them. */ + rv.f = flags & 0xffff; + f = 0x10000; + for (i = 0; i < 8; i++) { + /* use the closest thing to the old thermal style */ + if (flags & f) + rv.t[i / 2] |= (1 << (4 * (i % 2))); + f <<= 1; + } + return rv; +} + +/* load a board metadata into conf_core */ +static void load_meta_coord(const char *path, rnd_coord_t crd) +{ + char tmp[128]; + rnd_sprintf(tmp, "%$mm", crd); + rnd_conf_set(RND_CFR_DESIGN, path, -1, tmp, RND_POL_OVERWRITE); +} + +static void load_meta_float(const char *path, double val) +{ + char tmp[128]; + rnd_sprintf(tmp, "%f", val); + rnd_conf_set(RND_CFR_DESIGN, path, -1, tmp, RND_POL_OVERWRITE); +} Index: tags/2.3.0/src_plugins/io_pcb/parse_y.h =================================================================== --- tags/2.3.0/src_plugins/io_pcb/parse_y.h (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/parse_y.h (revision 33253) @@ -0,0 +1,129 @@ +/* A Bison parser, made by GNU Bison 3.3.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. + + 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 3 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, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +#ifndef YY_PCB_PARSE_Y_H_INCLUDED +# define YY_PCB_PARSE_Y_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int pcb_debug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + FLOATING = 258, + INTEGER = 259, + CHAR_CONST = 260, + STRING = 261, + T_FILEVERSION = 262, + T_PCB = 263, + T_LAYER = 264, + T_VIA = 265, + T_RAT = 266, + T_LINE = 267, + T_ARC = 268, + T_RECTANGLE = 269, + T_TEXT = 270, + T_ELEMENTLINE = 271, + T_ELEMENT = 272, + T_PIN = 273, + T_PAD = 274, + T_GRID = 275, + T_FLAGS = 276, + T_SYMBOL = 277, + T_SYMBOLLINE = 278, + T_CURSOR = 279, + T_ELEMENTARC = 280, + T_MARK = 281, + T_GROUPS = 282, + T_STYLES = 283, + T_POLYGON = 284, + T_POLYGON_HOLE = 285, + T_NETLIST = 286, + T_NET = 287, + T_CONN = 288, + T_NETLISTPATCH = 289, + T_ADD_CONN = 290, + T_DEL_CONN = 291, + T_CHANGE_ATTRIB = 292, + T_AREA = 293, + T_THERMAL = 294, + T_DRC = 295, + T_ATTRIBUTE = 296, + T_UMIL = 297, + T_CMIL = 298, + T_MIL = 299, + T_IN = 300, + T_NM = 301, + T_UM = 302, + T_MM = 303, + T_M = 304, + T_KM = 305 + }; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 121 "parse_y.y" /* yacc.c:1921 */ + + int integer; + double number; + char *string; + pcb_flag_t flagtype; + PLMeasure measure; + +#line 117 "parse_y.h" /* yacc.c:1921 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE pcb_lval; + +int pcb_parse (void); + +#endif /* !YY_PCB_PARSE_Y_H_INCLUDED */ Index: tags/2.3.0/src_plugins/io_pcb/parse_y.y =================================================================== --- tags/2.3.0/src_plugins/io_pcb/parse_y.y (nonexistent) +++ tags/2.3.0/src_plugins/io_pcb/parse_y.y (revision 33253) @@ -0,0 +1,1461 @@ +%{ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2017, 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* grammar to parse ASCII input of geda/PCB description (alien format) */ + +#include "config.h" +#include "flag.h" +#include "board.h" +#include "conf_core.h" +#include "layer.h" +#include "data.h" +#include +#include "file.h" +#include "parse_l.h" +#include "polygon.h" +#include "remove.h" +#include +#include "flag_str.h" +#include "obj_pinvia_therm.h" +#include "rats_patch.h" +#include "route_style.h" +#include +#include "src_plugins/lib_compat_help/pstk_compat.h" +#include "netlist.h" + +/* frame between the groundplane and the copper or mask - noone seems + to remember what these two are for; changing them may have unforeseen + side effects. */ +#define PCB_GROUNDPLANEFRAME RND_MIL_TO_COORD(15) +#define PCB_MASKFRAME RND_MIL_TO_COORD(3) + +/* default inner/outer ratio for pins/vias in percent */ +#define PCB_DEFAULT_DRILLINGHOLE 40 + +static pcb_layer_t *Layer; +static pcb_poly_t *Polygon; +static pcb_symbol_t *Symbol; +static int pin_num; +static pcb_net_t *currnet; +static rnd_bool LayerFlag[PCB_MAX_LAYER + 2]; +static int old_fmt; /* 1 if we are reading a PCB(), 0 if PCB[] */ +static unsigned char yy_intconn; + +extern char *yytext; /* defined by LEX */ +extern pcb_board_t * yyPCB; +extern pcb_data_t * yyData; +extern pcb_subc_t *yysubc; +extern rnd_coord_t yysubc_ox, yysubc_oy; +extern pcb_font_t * yyFont; +extern rnd_bool yyFontReset; +extern int pcb_lineno; /* linenumber */ +extern char *yyfilename; /* in this file */ +extern rnd_conf_role_t yy_settings_dest; +extern pcb_flag_t yy_pcb_flags; +extern int *yyFontkitValid; +extern int yyElemFixLayers; + +static char *layer_group_string; + +static pcb_attribute_list_t *attr_list; + +int yyerror(const char *s); +int yylex(); +static int check_file_version (int); + +static void do_measure (PLMeasure *m, rnd_coord_t i, double d, int u); +#define M(r,f,d) do_measure (&(r), f, d, 1) + +/* Macros for interpreting what "measure" means - integer value only, + old units (mil), or new units (cmil). */ +#define IV(m) integer_value (m) +#define OU(m) old_units (m) +#define NU(m) new_units (m) + +static int integer_value (PLMeasure m); +static rnd_coord_t old_units (PLMeasure m); +static rnd_coord_t new_units (PLMeasure m); +static pcb_flag_t pcb_flag_old(unsigned int flags); +static void load_meta_coord(const char *path, rnd_coord_t crd); +static void load_meta_float(const char *path, double val); + +#define YYDEBUG 1 +#define YYERROR_VERBOSE 1 + +#include "parse_y.h" + +%} + +%name-prefix "pcb_" + +%verbose + +%union /* define YYSTACK type */ +{ + int integer; + double number; + char *string; + pcb_flag_t flagtype; + PLMeasure measure; +} + +%token FLOATING /* line thickness, coordinates ... */ +%token INTEGER CHAR_CONST /* flags ... */ +%token STRING /* element names ... */ + +%token T_FILEVERSION T_PCB T_LAYER T_VIA T_RAT T_LINE T_ARC T_RECTANGLE T_TEXT T_ELEMENTLINE +%token T_ELEMENT T_PIN T_PAD T_GRID T_FLAGS T_SYMBOL T_SYMBOLLINE T_CURSOR +%token T_ELEMENTARC T_MARK T_GROUPS T_STYLES T_POLYGON T_POLYGON_HOLE T_NETLIST T_NET T_CONN +%token T_NETLISTPATCH T_ADD_CONN T_DEL_CONN T_CHANGE_ATTRIB +%token T_AREA T_THERMAL T_DRC T_ATTRIBUTE +%token T_UMIL T_CMIL T_MIL T_IN T_NM T_UM T_MM T_M T_KM +%type symbolid +%type opt_string +%type flags +%type number +%type measure + +%% + +parse + : parsepcb + | parsedata + | parsefont + | error { YYABORT; } + ; + +parsepcb + : { + /* reset flags for 'used layers'; + * init font and data pointers + */ + int i; + + if (!yyPCB) + { + rnd_message(RND_MSG_ERROR, "illegal fileformat\n"); + YYABORT; + } + for (i = 0; i < PCB_MAX_LAYER + 2; i++) + LayerFlag[i] = rnd_false; + yyFont = &yyPCB->fontkit.dflt; + yyFontkitValid = &yyPCB->fontkit.valid; + yyData = yyPCB->Data; + PCB_SET_PARENT(yyData, board, yyPCB); + yyData->LayerN = 0; + yyPCB->NetlistPatches = yyPCB->NetlistPatchLast = NULL; + layer_group_string = NULL; + old_fmt = 0; + } + pcbfileversion + pcbname + pcbgrid + pcbcursor + polyarea + pcbthermal + pcbdrc + pcbflags + pcbgroups + pcbstyles + pcbfont + pcbdata + pcbnetlist + pcbnetlistpatch + { + pcb_board_t *pcb_save = PCB; + if ((yy_settings_dest != RND_CFR_invalid) && (layer_group_string != NULL)) + rnd_conf_set(yy_settings_dest, "design/groups", -1, layer_group_string, RND_POL_OVERWRITE); + pcb_board_new_postproc(yyPCB, 0); + if (layer_group_string == NULL) { + if (pcb_layer_improvise(yyPCB, rnd_true) != 0) { + rnd_message(RND_MSG_ERROR, "missing layer-group string, failed to improvise the groups\n"); + YYABORT; + } + rnd_message(RND_MSG_ERROR, "missing layer-group string: invalid input file, had to improvise, the layer stack is most probably broken\n"); + } + else { + if (pcb_layer_parse_group_string(yyPCB, layer_group_string, yyData->LayerN, old_fmt)) + { + rnd_message(RND_MSG_ERROR, "illegal layer-group string\n"); + YYABORT; + } + else { + if (pcb_layer_improvise(yyPCB, rnd_false) != 0) { + rnd_message(RND_MSG_ERROR, "failed to extend-improvise the groups\n"); + YYABORT; + } + } + } + /* initialize the polygon clipping now since + * we didn't know the layer grouping before. + */ + free(layer_group_string); + PCB = yyPCB; + PCB_POLY_ALL_LOOP(yyData); + { + pcb_poly_init_clip(yyData, layer, polygon); + } + PCB_ENDALL_LOOP; + PCB = pcb_save; + } + + | { PreLoadElementPCB (); + layer_group_string = NULL; } + element + { LayerFlag[0] = rnd_true; + LayerFlag[1] = rnd_true; + if (yyElemFixLayers) { + yyData->LayerN = 2; + free((char *)yyData->Layer[0].name); + yyData->Layer[0].name = rnd_strdup("top-silk"); + yyData->Layer[0].parent_type = PCB_PARENT_DATA; + yyData->Layer[0].parent.data = yyData; + yyData->Layer[0].is_bound = 1; + yyData->Layer[0].meta.bound.type = PCB_LYT_SILK | PCB_LYT_TOP; + free((char *)yyData->Layer[1].name); + yyData->Layer[1].name = rnd_strdup("bottom-silk"); + yyData->Layer[1].parent_type = PCB_PARENT_DATA; + yyData->Layer[1].parent.data = yyData; + yyData->Layer[1].is_bound = 1; + yyData->Layer[1].meta.bound.type = PCB_LYT_SILK | PCB_LYT_BOTTOM; + } + PostLoadElementPCB (); + } + ; + +parsedata + : { + /* reset flags for 'used layers'; + * init font and data pointers + */ + int i; + + if (!yyData || !yyFont) + { + rnd_message(RND_MSG_ERROR, "illegal fileformat\n"); + YYABORT; + } + for (i = 0; i < PCB_MAX_LAYER + 2; i++) + LayerFlag[i] = rnd_false; + yyData->LayerN = 0; + } + pcbdata + ; + +pcbfont + : parsefont + | + ; + +parsefont + : + { + /* mark all symbols invalid */ + if (!yyFont) + { + rnd_message(RND_MSG_ERROR, "illegal fileformat\n"); + YYABORT; + } + if (yyFontReset) { + pcb_font_free (yyFont); + yyFont->id = 0; + } + *yyFontkitValid = rnd_false; + } + symbols + { + *yyFontkitValid = rnd_true; + pcb_font_set_info(yyFont); + } + ; + +pcbfileversion +: | +T_FILEVERSION '[' INTEGER ']' +{ + if (check_file_version ($3) != 0) + { + YYABORT; + } +} +; + +pcbname + : T_PCB '(' STRING ')' + { + yyPCB->hidlib.name = $3; + yyPCB->hidlib.size_x = RND_MAX_COORD; + yyPCB->hidlib.size_y = RND_MAX_COORD; + old_fmt = 1; + } + | T_PCB '(' STRING measure measure ')' + { + yyPCB->hidlib.name = $3; + yyPCB->hidlib.size_x = OU ($4); + yyPCB->hidlib.size_y = OU ($5); + old_fmt = 1; + } + | T_PCB '[' STRING measure measure ']' + { + yyPCB->hidlib.name = $3; + yyPCB->hidlib.size_x = NU ($4); + yyPCB->hidlib.size_y = NU ($5); + old_fmt = 0; + } + ; + +pcbgrid + : pcbgridold + | pcbgridnew + | pcbhigrid + ; +pcbgridold + : T_GRID '(' measure measure measure ')' + { + yyPCB->hidlib.grid = OU ($3); + yyPCB->hidlib.grid_ox = OU ($4); + yyPCB->hidlib.grid_oy = OU ($5); + } + ; +pcbgridnew + : T_GRID '(' measure measure measure INTEGER ')' + { + yyPCB->hidlib.grid = OU ($3); + yyPCB->hidlib.grid_ox = OU ($4); + yyPCB->hidlib.grid_oy = OU ($5); + if (yy_settings_dest != RND_CFR_invalid) { + if ($6) + rnd_conf_set(yy_settings_dest, "editor/draw_grid", -1, "true", RND_POL_OVERWRITE); + else + rnd_conf_set(yy_settings_dest, "editor/draw_grid", -1, "false", RND_POL_OVERWRITE); + } + } + ; + +pcbhigrid + : T_GRID '[' measure measure measure INTEGER ']' + { + yyPCB->hidlib.grid = NU ($3); + yyPCB->hidlib.grid_ox = NU ($4); + yyPCB->hidlib.grid_oy = NU ($5); + if (yy_settings_dest != RND_CFR_invalid) { + if ($6) + rnd_conf_set(yy_settings_dest, "editor/draw_grid", -1, "true", RND_POL_OVERWRITE); + else + rnd_conf_set(yy_settings_dest, "editor/draw_grid", -1, "false", RND_POL_OVERWRITE); + } + } + ; + +pcbcursor + : T_CURSOR '(' measure measure number ')' + { +/* Not loading cursor position and zoom anymore */ + } + | T_CURSOR '[' measure measure number ']' + { +/* Not loading cursor position and zoom anymore */ + } + | + ; + +polyarea + : + | T_AREA '[' number ']' + { + /* Read in cmil^2 for now; in future this should be a noop. */ + load_meta_float("design/poly_isle_area", RND_MIL_TO_COORD(RND_MIL_TO_COORD ($3) / 100.0) / 100.0); + } + ; + +pcbthermal + : + | T_THERMAL '[' number ']' + { + yyPCB->ThermScale = $3; + } + ; + +pcbdrc + : + | pcbdrc1 + | pcbdrc2 + | pcbdrc3 + ; + +pcbdrc1 + : T_DRC '[' measure measure measure ']' + { + load_meta_coord("design/bloat", NU($3)); + load_meta_coord("design/shrink", NU($4)); + load_meta_coord("design/min_wid", NU($5)); + load_meta_coord("design/min_ring", NU($5)); + } + ; + +pcbdrc2 + : T_DRC '[' measure measure measure measure ']' + { + load_meta_coord("design/bloat", NU($3)); + load_meta_coord("design/shrink", NU($4)); + load_meta_coord("design/min_wid", NU($5)); + load_meta_coord("design/min_slk", NU($6)); + load_meta_coord("design/min_ring", NU($5)); + } + ; + +pcbdrc3 + : T_DRC '[' measure measure measure measure measure measure ']' + { + load_meta_coord("design/bloat", NU($3)); + load_meta_coord("design/shrink", NU($4)); + load_meta_coord("design/min_wid", NU($5)); + load_meta_coord("design/min_slk", NU($6)); + load_meta_coord("design/min_drill", NU($7)); + load_meta_coord("design/min_ring", NU($8)); + } + ; + +pcbflags + : T_FLAGS '(' INTEGER ')' + { + yy_pcb_flags = pcb_flag_make($3 & PCB_FLAGS); + } + | T_FLAGS '(' STRING ')' + { + yy_pcb_flags = pcb_strflg_board_s2f($3, yyerror); + free($3); + } + | + ; + +pcbgroups + : T_GROUPS '(' STRING ')' + { + layer_group_string = $3; + } + | + ; + +pcbstyles + : T_STYLES '(' STRING ')' + { + if (pcb_route_string_parse($3, &yyPCB->RouteStyle, "mil")) + { + rnd_message(RND_MSG_ERROR, "illegal route-style string\n"); + YYABORT; + } + free($3); + } + | T_STYLES '[' STRING ']' + { + if (pcb_route_string_parse(($3 == NULL ? "" : $3), &yyPCB->RouteStyle, "cmil")) + { + rnd_message(RND_MSG_ERROR, "illegal route-style string\n"); + YYABORT; + } + free($3); + } + | + ; + +pcbdata + : pcbdefinitions + | + ; + +pcbdefinitions + : pcbdefinition + | pcbdefinitions pcbdefinition + ; + +pcbdefinition + : via + | { attr_list = & yyPCB->Attributes; } attribute + | rats + | layer + | + { + /* clear pointer to force memory allocation by + * the appropriate subroutine + */ + yysubc = NULL; + } + element + | error { YYABORT; } + ; + +via + : via_hi_format + | via_2.0_format + | via_1.7_format + | via_newformat + | via_oldformat + ; + +via_hi_format + /* x, y, thickness, clearance, mask, drilling-hole, name, flags */ + : T_VIA '[' measure measure measure measure measure measure STRING flags ']' + { + pcb_old_via_new(yyData, -1, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7), + NU ($8), $9, $10); + free ($9); + } + ; + +via_2.0_format + /* x, y, thickness, clearance, mask, drilling-hole, name, flags */ + : T_VIA '(' measure measure measure measure measure measure STRING INTEGER ')' + { + pcb_old_via_new(yyData, -1, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7), OU ($8), $9, + pcb_flag_old($10)); + free ($9); + } + ; + + +via_1.7_format + /* x, y, thickness, clearance, drilling-hole, name, flags */ + : T_VIA '(' measure measure measure measure measure STRING INTEGER ')' + { + pcb_old_via_new(yyData, -1, OU ($3), OU ($4), OU ($5), OU ($6), + OU ($5) + OU($6), OU ($7), $8, pcb_flag_old($9)); + free ($8); + } + ; + +via_newformat + /* x, y, thickness, drilling-hole, name, flags */ + : T_VIA '(' measure measure measure measure STRING INTEGER ')' + { + pcb_old_via_new(yyData, -1, OU ($3), OU ($4), OU ($5), 2*PCB_GROUNDPLANEFRAME, + OU($5) + 2*PCB_MASKFRAME, OU ($6), $7, pcb_flag_old($8)); + free ($7); + } + ; + +via_oldformat + /* old format: x, y, thickness, name, flags */ + : T_VIA '(' measure measure measure STRING INTEGER ')' + { + rnd_coord_t hole = (OU($5) * PCB_DEFAULT_DRILLINGHOLE); + + /* make sure that there's enough copper left */ + if (OU($5) - hole < PCB_MIN_PINORVIACOPPER && + OU($5) > PCB_MIN_PINORVIACOPPER) + hole = OU($5) - PCB_MIN_PINORVIACOPPER; + + pcb_old_via_new(yyData, -1, OU ($3), OU ($4), OU ($5), 2*PCB_GROUNDPLANEFRAME, + OU($5) + 2*PCB_MASKFRAME, hole, $6, pcb_flag_old($7)); + free ($6); + } + ; + +rats + : T_RAT '[' measure measure INTEGER measure measure INTEGER flags ']' + { + pcb_rat_new(yyData, -1, NU ($3), NU ($4), NU ($6), NU ($7), $5, $8, + conf_core.appearance.rat_thickness, $9, NULL, NULL); + } + | T_RAT '(' measure measure INTEGER measure measure INTEGER INTEGER ')' + { + pcb_rat_new(yyData, -1, OU ($3), OU ($4), OU ($6), OU ($7), $5, $8, + conf_core.appearance.rat_thickness, pcb_flag_old($9), NULL, NULL); + } + ; + +layer + /* name */ + : T_LAYER '(' INTEGER STRING opt_string ')' '(' + { + if ($3 <= 0 || $3 > PCB_MAX_LAYER) + { + yyerror("Layernumber out of range"); + YYABORT; + } + if (LayerFlag[$3-1]) + { + yyerror("Layernumber used twice"); + YYABORT; + } + Layer = &yyData->Layer[$3-1]; + Layer->parent.data = yyData; + Layer->parent_type = PCB_PARENT_DATA; + Layer->type = PCB_OBJ_LAYER; + + /* memory for name is already allocated */ + if (Layer->name != NULL) + free((char*)Layer->name); + Layer->name = $4; /* shouldn't this be strdup()'ed ? */ + LayerFlag[$3-1] = rnd_true; + if (yyData->LayerN < $3) + yyData->LayerN = $3; + if ($5 != NULL) + free($5); + } + layerdata ')' + ; + +layerdata + : layerdefinitions + | + ; + +layerdefinitions + : layerdefinition + | layerdefinitions layerdefinition + ; + +layerdefinition + : line_hi_format + | line_1.7_format + | line_oldformat + | arc_hi_format + | arc_1.7_format + | arc_oldformat + /* x1, y1, x2, y2, flags */ + | T_RECTANGLE '(' measure measure measure measure INTEGER ')' + { + pcb_poly_new_from_rectangle(Layer, + OU ($3), OU ($4), OU ($3) + OU ($5), OU ($4) + OU ($6), 0, pcb_flag_old($7)); + } + | text_hi_format + | text_newformat + | text_oldformat + | { attr_list = & Layer->Attributes; } attribute + | polygon_format + +line_hi_format + /* x1, y1, x2, y2, thickness, clearance, flags */ + : T_LINE '[' measure measure measure measure measure measure flags ']' + { + pcb_line_new(Layer, NU ($3), NU ($4), NU ($5), NU ($6), + NU ($7), NU ($8), $9); + } + ; + +line_1.7_format + /* x1, y1, x2, y2, thickness, clearance, flags */ + : T_LINE '(' measure measure measure measure measure measure INTEGER ')' + { + pcb_line_new(Layer, OU ($3), OU ($4), OU ($5), OU ($6), + OU ($7), OU ($8), pcb_flag_old($9)); + } + ; + +line_oldformat + /* x1, y1, x2, y2, thickness, flags */ + : T_LINE '(' measure measure measure measure measure measure ')' + { + /* eliminate old-style rat-lines */ + if ((IV ($8) & PCB_FLAG_RAT) == 0) + pcb_line_new(Layer, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7), + 200*PCB_GROUNDPLANEFRAME, pcb_flag_old(IV ($8))); + } + ; + +arc_hi_format + /* x, y, width, height, thickness, clearance, startangle, delta, flags */ + : T_ARC '[' measure measure measure measure measure measure number number flags ']' + { + pcb_arc_new(Layer, NU ($3), NU ($4), NU ($5), NU ($6), $9, $10, + NU ($7), NU ($8), $11, rnd_true); + } + ; + +arc_1.7_format + /* x, y, width, height, thickness, clearance, startangle, delta, flags */ + : T_ARC '(' measure measure measure measure measure measure number number INTEGER ')' + { + pcb_arc_new(Layer, OU ($3), OU ($4), OU ($5), OU ($6), $9, $10, + OU ($7), OU ($8), pcb_flag_old($11), rnd_true); + } + ; + +arc_oldformat + /* x, y, width, height, thickness, startangle, delta, flags */ + : T_ARC '(' measure measure measure measure measure measure number INTEGER ')' + { + pcb_arc_new(Layer, OU ($3), OU ($4), OU ($5), OU ($5), IV ($8), $9, + OU ($7), 200*PCB_GROUNDPLANEFRAME, pcb_flag_old($10), rnd_true); + } + ; + +text_oldformat + /* x, y, direction, text, flags */ + : T_TEXT '(' measure measure number STRING INTEGER ')' + { + /* use a default scale of 100% */ + pcb_text_new(Layer,yyFont,OU ($3), OU ($4), $5 * 90.0, 100, 0, $6, pcb_flag_old($7)); + free ($6); + } + ; + +text_newformat + /* x, y, direction, scale, text, flags */ + : T_TEXT '(' measure measure number number STRING INTEGER ')' + { + if ($8 & PCB_FLAG_ONSILK) + { + pcb_layer_t *lay = &yyData->Layer[yyData->LayerN + + (($8 & PCB_FLAG_ONSOLDER) ? PCB_SOLDER_SIDE : PCB_COMPONENT_SIDE) - 2]; + + pcb_text_new(lay ,yyFont, OU ($3), OU ($4), $5 * 90.0, $6, 0, $7, + pcb_flag_old($8)); + } + else + pcb_text_new(Layer, yyFont, OU ($3), OU ($4), $5 * 90.0, $6, 0, $7, + pcb_flag_old($8)); + free ($7); + } + ; +text_hi_format + /* x, y, direction, scale, text, flags */ + : T_TEXT '[' measure measure number number STRING flags ']' + { + /* FIXME: shouldn't know about .f */ + /* I don't think this matters because anything with hi_format + * will have the silk on its own layer in the file rather + * than using the PCB_FLAG_ONSILK and having it in a copper layer. + * Thus there is no need for anything besides the 'else' + * part of this code. + */ + if ($8.f & PCB_FLAG_ONSILK) + { + pcb_layer_t *lay = &yyData->Layer[yyData->LayerN + + (($8.f & PCB_FLAG_ONSOLDER) ? PCB_SOLDER_SIDE : PCB_COMPONENT_SIDE) - 2]; + + pcb_text_new(lay, yyFont, NU ($3), NU ($4), $5 * 90.0, $6, 0, $7, $8); + } + else + pcb_text_new(Layer, yyFont, NU ($3), NU ($4), $5 * 90.0, $6, 0, $7, $8); + free ($7); + } + ; + +polygon_format + : /* flags are passed in */ + T_POLYGON '(' flags ')' '(' + { + Polygon = pcb_poly_new(Layer, 0, $3); + } + polygonpoints + polygonholes ')' + { + rnd_cardinal_t contour, contour_start, contour_end; + rnd_bool bad_contour_found = rnd_false; + /* ignore junk */ + for (contour = 0; contour <= Polygon->HoleIndexN; contour++) + { + contour_start = (contour == 0) ? + 0 : Polygon->HoleIndex[contour - 1]; + contour_end = (contour == Polygon->HoleIndexN) ? + Polygon->PointN : + Polygon->HoleIndex[contour]; + if (contour_end - contour_start < 3) + bad_contour_found = rnd_true; + } + + if (bad_contour_found) + { + rnd_message(RND_MSG_WARNING, "WARNING parsing file '%s'\n" + " line: %i\n" + " description: 'ignored polygon (< 3 points in a contour)'\n", + yyfilename, pcb_lineno); + pcb_destroy_object(yyData, PCB_OBJ_POLY, Layer, Polygon, Polygon); + } + else + { + pcb_poly_bbox(Polygon); + if (!Layer->polygon_tree) + Layer->polygon_tree = rnd_r_create_tree(); + rnd_r_insert_entry(Layer->polygon_tree, (rnd_box_t *) Polygon); + } + } + ; + +polygonholes + : /* empty */ + | polygonholes polygonhole + ; + +polygonhole + : T_POLYGON_HOLE '(' + { + pcb_poly_hole_new(Polygon); + } + polygonpoints ')' + ; + +polygonpoints + : /* empty */ + | polygonpoint polygonpoints + ; + +polygonpoint + /* xcoord ycoord */ + : '(' measure measure ')' + { + pcb_poly_point_new(Polygon, OU ($2), OU ($3)); + } + | '[' measure measure ']' + { + pcb_poly_point_new(Polygon, NU ($2), NU ($3)); + } + ; + +element + : element_oldformat + | element_1.3.4_format + | element_newformat + | element_1.7_format + | element_hi_format + ; + +element_oldformat + /* element_flags, description, pcb-name, + * text_x, text_y, text_direction, text_scale, text_flags + */ + : T_ELEMENT '(' STRING STRING measure measure INTEGER ')' '(' + { + yysubc = io_pcb_element_new(yyData, yysubc, yyFont, pcb_no_flags(), + $3, $4, NULL, OU ($5), OU ($6), $7, 100, pcb_no_flags(), rnd_false); + free ($3); + free ($4); + pin_num = 1; + } + elementdefinitions ')' + { + io_pcb_element_fin(yyData); + } + ; + +element_1.3.4_format + /* element_flags, description, pcb-name, + * text_x, text_y, text_direction, text_scale, text_flags + */ + : T_ELEMENT '(' INTEGER STRING STRING measure measure measure measure INTEGER ')' '(' + { + yysubc = io_pcb_element_new(yyData, yysubc, yyFont, pcb_flag_old($3), + $4, $5, NULL, OU ($6), OU ($7), IV ($8), IV ($9), pcb_flag_old($10), rnd_false); + free ($4); + free ($5); + pin_num = 1; + } + elementdefinitions ')' + { + io_pcb_element_fin(yyData); + } + ; + +element_newformat + /* element_flags, description, pcb-name, value, + * text_x, text_y, text_direction, text_scale, text_flags + */ + : T_ELEMENT '(' INTEGER STRING STRING STRING measure measure measure measure INTEGER ')' '(' + { + yysubc = io_pcb_element_new(yyData, yysubc, yyFont, pcb_flag_old($3), + $4, $5, $6, OU ($7), OU ($8), IV ($9), IV ($10), pcb_flag_old($11), rnd_false); + free ($4); + free ($5); + free ($6); + pin_num = 1; + } + elementdefinitions ')' + { + io_pcb_element_fin(yyData); + } + ; + +element_1.7_format + /* element_flags, description, pcb-name, value, mark_x, mark_y, + * text_x, text_y, text_direction, text_scale, text_flags + */ + : T_ELEMENT '(' INTEGER STRING STRING STRING measure measure + measure measure number number INTEGER ')' '(' + { + yysubc = io_pcb_element_new(yyData, yysubc, yyFont, pcb_flag_old($3), + $4, $5, $6, OU ($7) + OU ($9), OU ($8) + OU ($10), + $11, $12, pcb_flag_old($13), rnd_false); + yysubc_ox = OU ($7); + yysubc_oy = OU ($8); + free ($4); + free ($5); + free ($6); + } + relementdefs ')' + { + io_pcb_element_fin(yyData); + } + ; + +element_hi_format + /* element_flags, description, pcb-name, value, mark_x, mark_y, + * text_x, text_y, text_direction, text_scale, text_flags + */ + : T_ELEMENT '[' flags STRING STRING STRING measure measure + measure measure number number flags ']' '(' + { + yysubc = io_pcb_element_new(yyData, yysubc, yyFont, $3, + $4, $5, $6, NU ($7) + NU ($9), NU ($8) + NU ($10), + $11, $12, $13, rnd_false); + yysubc_ox = NU ($7); + yysubc_oy = NU ($8); + free ($4); + free ($5); + free ($6); + } + relementdefs ')' + { + if (pcb_subc_is_empty(yysubc)) { + pcb_subc_free(yysubc); + yysubc = NULL; + } + else { + io_pcb_element_fin(yyData); + } + } + ; + +elementdefinitions + : elementdefinition + | elementdefinitions elementdefinition + ; + +elementdefinition + : pin_1.6.3_format + | pin_newformat + | pin_oldformat + | pad_newformat + | pad + /* x1, y1, x2, y2, thickness */ + | T_ELEMENTLINE '[' measure measure measure measure measure ']' + { + io_pcb_element_line_new(yysubc, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7)); + } + /* x1, y1, x2, y2, thickness */ + | T_ELEMENTLINE '(' measure measure measure measure measure ')' + { + io_pcb_element_line_new(yysubc, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7)); + } + /* x, y, width, height, startangle, anglediff, thickness */ + | T_ELEMENTARC '[' measure measure measure measure number number measure ']' + { + io_pcb_element_arc_new(yysubc, NU ($3), NU ($4), NU ($5), NU ($6), $7, $8, NU ($9)); + } + /* x, y, width, height, startangle, anglediff, thickness */ + | T_ELEMENTARC '(' measure measure measure measure number number measure ')' + { + io_pcb_element_arc_new(yysubc, OU ($3), OU ($4), OU ($5), OU ($6), $7, $8, OU ($9)); + } + /* x, y position */ + | T_MARK '[' measure measure ']' + { + yysubc_ox = NU ($3); + yysubc_oy = NU ($4); + } + | T_MARK '(' measure measure ')' + { + yysubc_ox = OU ($3); + yysubc_oy = OU ($4); + } + | { attr_list = & yysubc->Attributes; } attribute + ; + +relementdefs + : relementdef + | relementdefs relementdef + ; + +relementdef + : pin_1.7_format + | pin_hi_format + | pad_1.7_format + | pad_hi_format + /* x1, y1, x2, y2, thickness */ + | T_ELEMENTLINE '[' measure measure measure measure measure ']' + { + io_pcb_element_line_new(yysubc, NU ($3) + yysubc_ox, + NU ($4) + yysubc_oy, NU ($5) + yysubc_ox, + NU ($6) + yysubc_oy, NU ($7)); + } + | T_ELEMENTLINE '(' measure measure measure measure measure ')' + { + io_pcb_element_line_new(yysubc, OU ($3) + yysubc_ox, + OU ($4) + yysubc_oy, OU ($5) + yysubc_ox, + OU ($6) + yysubc_oy, OU ($7)); + } + /* x, y, width, height, startangle, anglediff, thickness */ + | T_ELEMENTARC '[' measure measure measure measure number number measure ']' + { + io_pcb_element_arc_new(yysubc, NU ($3) + yysubc_ox, + NU ($4) + yysubc_oy, NU ($5), NU ($6), $7, $8, NU ($9)); + } + | T_ELEMENTARC '(' measure measure measure measure number number measure ')' + { + io_pcb_element_arc_new(yysubc, OU ($3) + yysubc_ox, + OU ($4) + yysubc_oy, OU ($5), OU ($6), $7, $8, OU ($9)); + } + | { attr_list = & yysubc->Attributes; } attribute + ; + +pin_hi_format + /* x, y, thickness, clearance, mask, drilling hole, name, + number, flags */ + : T_PIN '[' measure measure measure measure measure measure STRING STRING flags ']' + { + pcb_pstk_t *pin = io_pcb_element_pin_new(yysubc, NU ($3) + yysubc_ox, + NU ($4) + yysubc_oy, NU ($5), NU ($6), NU ($7), NU ($8), $9, + $10, $11); + pcb_attrib_compat_set_intconn(&pin->Attributes, yy_intconn); + free ($9); + free ($10); + } + ; +pin_1.7_format + /* x, y, thickness, clearance, mask, drilling hole, name, + number, flags */ + : T_PIN '(' measure measure measure measure measure measure STRING STRING INTEGER ')' + { + io_pcb_element_pin_new(yysubc, OU ($3) + yysubc_ox, + OU ($4) + yysubc_oy, OU ($5), OU ($6), OU ($7), OU ($8), $9, + $10, pcb_flag_old($11)); + free ($9); + free ($10); + } + ; + +pin_1.6.3_format + /* x, y, thickness, drilling hole, name, number, flags */ + : T_PIN '(' measure measure measure measure STRING STRING INTEGER ')' + { + io_pcb_element_pin_new(yysubc, OU ($3), OU ($4), OU ($5), 2*PCB_GROUNDPLANEFRAME, + OU ($5) + 2*PCB_MASKFRAME, OU ($6), $7, $8, pcb_flag_old($9)); + free ($7); + free ($8); + } + ; + +pin_newformat + /* x, y, thickness, drilling hole, name, flags */ + : T_PIN '(' measure measure measure measure STRING INTEGER ')' + { + char p_number[8]; + + sprintf(p_number, "%d", pin_num++); + io_pcb_element_pin_new(yysubc, OU ($3), OU ($4), OU ($5), 2*PCB_GROUNDPLANEFRAME, + OU ($5) + 2*PCB_MASKFRAME, OU ($6), $7, p_number, pcb_flag_old($8)); + + free ($7); + } + ; + +pin_oldformat + /* old format: x, y, thickness, name, flags + * drilling hole is 40% of the diameter + */ + : T_PIN '(' measure measure measure STRING INTEGER ')' + { + rnd_coord_t hole = OU ($5) * PCB_DEFAULT_DRILLINGHOLE; + char p_number[8]; + + /* make sure that there's enough copper left */ + if (OU ($5) - hole < PCB_MIN_PINORVIACOPPER && + OU ($5) > PCB_MIN_PINORVIACOPPER) + hole = OU ($5) - PCB_MIN_PINORVIACOPPER; + + sprintf(p_number, "%d", pin_num++); + io_pcb_element_pin_new(yysubc, OU ($3), OU ($4), OU ($5), 2*PCB_GROUNDPLANEFRAME, + OU ($5) + 2*PCB_MASKFRAME, hole, $6, p_number, pcb_flag_old($7)); + free ($6); + } + ; + +pad_hi_format + /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */ + : T_PAD '[' measure measure measure measure measure measure measure STRING STRING flags ']' + { + pcb_pstk_t *pad = io_pcb_element_pad_new(yysubc, NU ($3) + yysubc_ox, + NU ($4) + yysubc_oy, + NU ($5) + yysubc_ox, + NU ($6) + yysubc_oy, NU ($7), NU ($8), NU ($9), + $10, $11, $12); + pcb_attrib_compat_set_intconn(&pad->Attributes, yy_intconn); + free ($10); + free ($11); + } + ; + +pad_1.7_format + /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */ + : T_PAD '(' measure measure measure measure measure measure measure STRING STRING INTEGER ')' + { + io_pcb_element_pad_new(yysubc,OU ($3) + yysubc_ox, + OU ($4) + yysubc_oy, OU ($5) + yysubc_ox, + OU ($6) + yysubc_oy, OU ($7), OU ($8), OU ($9), + $10, $11, pcb_flag_old($12)); + free ($10); + free ($11); + } + ; + +pad_newformat + /* x1, y1, x2, y2, thickness, name , pad number, flags */ + : T_PAD '(' measure measure measure measure measure STRING STRING INTEGER ')' + { + io_pcb_element_pad_new(yysubc,OU ($3),OU ($4),OU ($5),OU ($6),OU ($7), 2*PCB_GROUNDPLANEFRAME, + OU ($7) + 2*PCB_MASKFRAME, $8, $9, pcb_flag_old($10)); + free ($8); + free ($9); + } + ; + +pad + /* x1, y1, x2, y2, thickness, name and flags */ + : T_PAD '(' measure measure measure measure measure STRING INTEGER ')' + { + char p_number[8]; + + sprintf(p_number, "%d", pin_num++); + io_pcb_element_pad_new(yysubc,OU ($3),OU ($4),OU ($5),OU ($6),OU ($7), 2*PCB_GROUNDPLANEFRAME, + OU ($7) + 2*PCB_MASKFRAME, $8,p_number, pcb_flag_old($9)); + free ($8); + } + ; + +flags : INTEGER { $$ = pcb_flag_old($1); } + | STRING { $$ = pcb_strflg_s2f($1, yyerror, &yy_intconn, 1); free($1); } + ; + +symbols + : symbol + | symbols symbol + ; + +symbol : symbolhead symboldata ')' + +symbolhead : T_SYMBOL '[' symbolid measure ']' '(' + { + if ($3 <= 0 || $3 > PCB_MAX_FONTPOSITION) + { + yyerror("fontposition out of range"); + YYABORT; + } + Symbol = &yyFont->Symbol[$3]; + if (Symbol->Valid) + { + yyerror("symbol ID used twice"); + YYABORT; + } + Symbol->Valid = rnd_true; + Symbol->Delta = NU ($4); + } + | T_SYMBOL '(' symbolid measure ')' '(' + { + if ($3 <= 0 || $3 > PCB_MAX_FONTPOSITION) + { + yyerror("fontposition out of range"); + YYABORT; + } + Symbol = &yyFont->Symbol[$3]; + if (Symbol->Valid) + { + yyerror("symbol ID used twice"); + YYABORT; + } + Symbol->Valid = rnd_true; + Symbol->Delta = OU ($4); + } + ; + +symbolid + : INTEGER + | CHAR_CONST + ; + +symboldata + : /* empty */ + | symboldata symboldefinition + | symboldata hiressymbol + ; + +symboldefinition + /* x1, y1, x2, y2, thickness */ + : T_SYMBOLLINE '(' measure measure measure measure measure ')' + { + pcb_font_new_line_in_sym(Symbol, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7)); + } + ; +hiressymbol + /* x1, y1, x2, y2, thickness */ + : T_SYMBOLLINE '[' measure measure measure measure measure ']' + { + pcb_font_new_line_in_sym(Symbol, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7)); + } + ; + +pcbnetlist : pcbnetdef + | + ; +pcbnetdef + /* net(...) net(...) ... */ + : T_NETLIST '(' ')' '(' + nets ')' + ; + +nets + : netdefs + | + ; + +netdefs + : net + | netdefs net + ; + +net + /* name style pin pin ... */ + : T_NET '(' STRING STRING ')' '(' + { + currnet = pcb_net_get(yyPCB, &yyPCB->netlist[PCB_NETLIST_INPUT], $3, PCB_NETA_ALLOC); + if (($4 != NULL) && (*$4 != '\0')) + pcb_attribute_put(&currnet->Attributes, "style", $4); + free ($3); + free ($4); + } + connections ')' + ; + +connections + : conndefs + | + ; + +conndefs + : conn + | conndefs conn + ; + +conn + : T_CONN '(' STRING ')' + { + pcb_net_term_get_by_pinname(currnet, $3, 1); + free ($3); + } + ; + +/* %start-doc pcbfile Netlistpatch + +@syntax +NetListPatch ( ) ( +@ @ @ @dots{} netpatch @dots{} +) +@end syntax + +%end-doc */ + +pcbnetlistpatch : pcbnetpatchdef + | + ; +pcbnetpatchdef + /* net(...) net(...) ... */ + : T_NETLISTPATCH '(' ')' '(' + netpatches ')' + ; + +netpatches + : netpatchdefs + | + ; + +netpatchdefs + : netpatch + | netpatchdefs netpatch + ; + +/* %start-doc pcbfile NetPatch + +@syntax +op (arg1 arg2 ...) ( +@ @ @ @dots{} netlist patch directive @dots{} +) +@end syntax + +%end-doc */ + +netpatch + /* name style pin pin ... */ + : T_ADD_CONN '(' STRING STRING ')' { pcb_ratspatch_append(yyPCB, RATP_ADD_CONN, $3, $4, NULL, 0); free($3); free($4); } + | T_DEL_CONN '(' STRING STRING ')' { pcb_ratspatch_append(yyPCB, RATP_DEL_CONN, $3, $4, NULL, 0); free($3); free($4); } + | T_CHANGE_ATTRIB '(' STRING STRING STRING ')' { pcb_ratspatch_append(yyPCB, RATP_CHANGE_ATTRIB, $3, $4, $5, 0); free($3); free($4); free($5); } + ; + +attribute + : T_ATTRIBUTE '(' STRING STRING ')' + { + char *old_val, *key = $3, *val = $4 ? $4 : (char *)""; + old_val = pcb_attribute_get(attr_list, key); + if (old_val != NULL) + rnd_message(RND_MSG_ERROR, "mutliple values for attribute %s: '%s' and '%s' - ignoring '%s'\n", key, old_val, val, val); + else + pcb_attribute_put(attr_list, key, val); + free(key); + free(val); + } + ; + +opt_string : STRING { $$ = $1; } + | /* empty */ { $$ = 0; } + ; + +number + : FLOATING { $$ = $1; } + | INTEGER { $$ = $1; } + ; + +measure + /* Default unit (no suffix) is cmil */ + : number { do_measure(&$$, $1, RND_MIL_TO_COORD ($1) / 100.0, 0); } + | number T_UMIL { M ($$, $1, RND_MIL_TO_COORD ($1) / 100000.0); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } + | number T_CMIL { M ($$, $1, RND_MIL_TO_COORD ($1) / 100.0); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } + | number T_MIL { M ($$, $1, RND_MIL_TO_COORD ($1)); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } + | number T_IN { M ($$, $1, RND_INCH_TO_COORD ($1)); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } + | number T_NM { M ($$, $1, RND_MM_TO_COORD ($1) / 1000000.0); pcb_io_pcb_usty_seen |= PCB_USTY_NANOMETER; } + | number T_UM { M ($$, $1, RND_MM_TO_COORD ($1) / 1000.0); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } + | number T_MM { M ($$, $1, RND_MM_TO_COORD ($1)); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } + | number T_M { M ($$, $1, RND_MM_TO_COORD ($1) * 1000.0); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } + | number T_KM { M ($$, $1, RND_MM_TO_COORD ($1) * 1000000.0); pcb_io_pcb_usty_seen |= PCB_USTY_UNITS; } + ; + +%% + +/* --------------------------------------------------------------------------- + * error routine called by parser library + */ +int yyerror(const char * s) +{ + rnd_message(RND_MSG_ERROR, "ERROR parsing file '%s'\n" + " line: %i\n" + " description: '%s'\n", + yyfilename, pcb_lineno, s); + return(0); +} + +int pcb_wrap() +{ + return 1; +} + +static int +check_file_version (int ver) +{ + if ( ver > PCB_FILE_VERSION ) { + rnd_message(RND_MSG_ERROR, "ERROR: The file you are attempting to load is in a format\n" + "which is too new for this version of pcb. To load this file\n" + "you need a version of pcb which is >= %d. If you are\n" + "using a version built from git source, the source date\n" + "must be >= %d. This copy of pcb can only read files\n" + "up to file version %d.\n", ver, ver, PCB_FILE_VERSION); + return 1; + } + + return 0; +} + +static void +do_measure (PLMeasure *m, rnd_coord_t i, double d, int u) +{ + m->ival = i; + m->bval = rnd_round(d); + m->dval = d; + m->has_units = u; +} + +static int +integer_value (PLMeasure m) +{ + if (m.has_units) + yyerror("units ignored here"); + return m.ival; +} + +static rnd_coord_t +old_units (PLMeasure m) +{ + if (m.has_units) + return m.bval; + if (m.ival != 0) + pcb_io_pcb_usty_seen |= PCB_USTY_CMIL; /* ... because we can't save in mil */ + return rnd_round(RND_MIL_TO_COORD (m.ival)); +} + +static rnd_coord_t +new_units (PLMeasure m) +{ + if (m.has_units) + return m.bval; + if (m.dval != 0) + pcb_io_pcb_usty_seen |= PCB_USTY_CMIL; + /* if there's no unit m.dval already contains the converted value */ + return rnd_round(m.dval); +} + +/* This converts old flag bits (from saved PCB files) to new format. */ +static pcb_flag_t pcb_flag_old(unsigned int flags) +{ + pcb_flag_t rv; + int i, f; + memset(&rv, 0, sizeof(rv)); + /* If we move flag bits around, this is where we map old bits to them. */ + rv.f = flags & 0xffff; + f = 0x10000; + for (i = 0; i < 8; i++) { + /* use the closest thing to the old thermal style */ + if (flags & f) + rv.t[i / 2] |= (1 << (4 * (i % 2))); + f <<= 1; + } + return rv; +} + +/* load a board metadata into conf_core */ +static void load_meta_coord(const char *path, rnd_coord_t crd) +{ + char tmp[128]; + rnd_sprintf(tmp, "%$mm", crd); + rnd_conf_set(RND_CFR_DESIGN, path, -1, tmp, RND_POL_OVERWRITE); +} + +static void load_meta_float(const char *path, double val) +{ + char tmp[128]; + rnd_sprintf(tmp, "%f", val); + rnd_conf_set(RND_CFR_DESIGN, path, -1, tmp, RND_POL_OVERWRITE); +} Index: tags/2.3.0/src_plugins/io_tedax/Makefile =================================================================== --- tags/2.3.0/src_plugins/io_tedax/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_io_tedax + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/io_tedax/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/io_tedax/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/Plug.tmpasm (revision 33253) @@ -0,0 +1,26 @@ +put /local/pcb/mod {io_tedax} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/io_tedax/io_tedax.o + $(PLUGDIR)/io_tedax/tnetlist.o + $(PLUGDIR)/io_tedax/footprint.o + $(PLUGDIR)/io_tedax/stackup.o + $(PLUGDIR)/io_tedax/tlayer.o + $(PLUGDIR)/io_tedax/tboard.o + $(PLUGDIR)/io_tedax/tdrc.o + $(PLUGDIR)/io_tedax/tdrc_keys_sphash.o + $(PLUGDIR)/io_tedax/tdrc_query.o + $(PLUGDIR)/io_tedax/trouter.o + $(PLUGDIR)/io_tedax/tetest.o + $(PLUGDIR)/io_tedax/parse.o +@] +put /local/pcb/mod/MENUFILE {tedax-menu.lht} +put /local/pcb/mod/MENUVAR {tedax_menu} + +put /local/pcb/mod/SPHASH {$(PLUGDIR)/io_tedax/tdrc_keys.sphash} +put /local/pcb/mod/SPHASH_ARGS {--multi} + +switch /local/pcb/io_tedax/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/io_tedax/common_inlines.h =================================================================== --- tags/2.3.0/src_plugins/io_tedax/common_inlines.h (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/common_inlines.h (revision 33253) @@ -0,0 +1,66 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tedax IO plugin - inline functions used in multiple blocks + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +RND_INLINE void tedax_finsert_layernet_tags(FILE *f, pcb_netmap_t *nmap, pcb_any_obj_t *obj) +{ + pcb_net_t *net = htpp_get(&nmap->o2n, obj); + char constr[4], *end, *tmp; + const char *netname; + pcb_idpath_t *idp; + + end = constr; + + /* for now do not allow the autorouter to move or delete anything */ + if (obj->term != NULL) + *end++ = 't'; + *end++ = 'm'; + *end++ = 'd'; + + if (end == constr) + *end++ = '-'; + *end = '\0'; + + /* calculate the netname */ + if (net != NULL) { + netname = net->name; + if (strncmp(netname, "netmap_anon_", 12) == 0) + netname = "-"; + } + else + netname = "-"; + + idp = pcb_obj2idpath(obj); + tmp = pcb_idpath2str(idp, 0); + + fprintf(f, " %s ", tmp); + tedax_fprint_escape(f, netname); + fprintf(f, " %s", constr); + + free(tmp); + pcb_idpath_destroy(idp); +} Index: tags/2.3.0/src_plugins/io_tedax/footprint.c =================================================================== --- tags/2.3.0/src_plugins/io_tedax/footprint.c (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/footprint.c (revision 33253) @@ -0,0 +1,733 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tedax IO plugin - footprint import/export + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include +#include +#include + +#include "footprint.h" +#include "parse.h" + +#include +#include "attrib.h" +#include +#include "data.h" +#include "board.h" +#include "conf_core.h" +#include "plug_footprint.h" +#include +#include +#include +#include "obj_line.h" +#include "obj_arc.h" +#include "obj_pstk.h" +#include "obj_pstk_inlines.h" +#include "../src_plugins/lib_compat_help/subc_help.h" +#include "../src_plugins/lib_compat_help/pstk_help.h" + +static void print_sqpad_coords(FILE *f, pcb_any_line_t *Pad, rnd_coord_t cx, rnd_coord_t cy) +{ + rnd_coord_t x[4], y[4]; + + pcb_sqline_to_rect((pcb_line_t *)Pad, x, y); + rnd_fprintf(f, " %.9mm %.9mm", x[0] - cx, y[0] - cy); + rnd_fprintf(f, " %.9mm %.9mm", x[1] - cx, y[1] - cy); + rnd_fprintf(f, " %.9mm %.9mm", x[2] - cx, y[2] - cy); + rnd_fprintf(f, " %.9mm %.9mm", x[3] - cx, y[3] - cy); +} + +#define elem_layer(elem, obj) \ + ((PCB_FLAG_TEST(PCB_FLAG_ONSOLDER, (elem)) == PCB_FLAG_TEST(PCB_FLAG_ONSOLDER, (obj))) ? "primary" : "secondary") + +#define safe_term_num(out, obj, buff) \ +do { \ + out = obj->Number; \ + if ((out == NULL) || (*out == '\0')) { \ + sprintf(buff, "%p", (void *)obj); \ + out = buff; \ + if (out[1] == 'x') \ + out+=2; \ + } \ +} while(0) + +#define print_term(pnum, obj) \ +do { \ + if (htsp_get(&terms, pnum) == NULL) { \ + htsp_set(&terms, rnd_strdup(pnum), obj); \ + fprintf(f, " term %s %s - %s\n", pnum, pnum, obj->Name); \ + } \ +} while(0) + +#define print_terma(terms, pnum, obj) \ +do { \ + if (htsp_get(terms, pnum) == NULL) { \ + htsp_set(terms, rnd_strdup(pnum), obj); \ + fprintf(f, " term %s %s - %s\n", pnum, pnum, pnum); \ + } \ +} while(0) + +#define TERM_NAME(term) ((term == NULL) ? "-" : term) + +#define PIN_PLATED(obj) (PCB_FLAG_TEST(PCB_FLAG_HOLE, (obj)) ? "unplated" : "-") + +#define get_layer_props(lyt, lloc, ltyp, invalid) \ + ltyp = lloc = NULL; \ + if (lyt & PCB_LYT_LOGICAL) { invalid; } \ + else if (lyt & PCB_LYT_TOP) lloc = "primary"; \ + else if (lyt & PCB_LYT_BOTTOM) lloc = "secondary"; \ + else if (lyt & PCB_LYT_INTERN) lloc = "inner"; \ + else if ((lyt & PCB_LYT_ANYWHERE) == 0) lloc = "all"; \ + if (lyt & PCB_LYT_COPPER) ltyp = "copper"; \ + else if (lyt & PCB_LYT_SILK) ltyp = "silk"; \ + else if (lyt & PCB_LYT_MASK) ltyp = "mask"; \ + else if (lyt & PCB_LYT_PASTE) ltyp = "paste"; \ + else { invalid; } + +int tedax_pstk_fsave(pcb_pstk_t *padstack, rnd_coord_t ox, rnd_coord_t oy, FILE *f) +{ + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(padstack); + pcb_pstk_tshape_t *tshp; + pcb_pstk_shape_t *shp; + int n, i; + + if (proto == NULL) { + rnd_message(RND_MSG_ERROR, "tEDAx footprint export: omitting subc padstack with invalid prototype\n"); + return 1; + } + if (proto->hdia > 0) + rnd_fprintf(f, " hole %s %mm %mm %mm %s\n", TERM_NAME(padstack->term), padstack->x - ox, padstack->y - oy, proto->hdia, proto->hplated ? "-" : "unplated"); + + tshp = pcb_pstk_get_tshape(padstack); + for(n = 0, shp = tshp->shape; n < tshp->len; n++,shp++) { + const char *lloc, *ltyp; + rnd_coord_t clr; + + get_layer_props(shp->layer_mask, lloc, ltyp, continue); + clr = padstack->Clearance > 0 ? padstack->Clearance : shp->clearance; + switch(shp->shape) { + case PCB_PSSH_HSHADOW: + break; + case PCB_PSSH_CIRC: + rnd_fprintf(f, " fillcircle %s %s %s %mm %mm %mm %mm\n", lloc, ltyp, TERM_NAME(padstack->term), + padstack->x + shp->data.circ.x - ox, padstack->y + shp->data.circ.y - oy, + shp->data.circ.dia/2, clr); + break; + case PCB_PSSH_LINE: + if (shp->data.line.square) { + pcb_any_line_t tmp; + tmp.Point1.X = shp->data.line.x1 + padstack->x; + tmp.Point1.Y = shp->data.line.y1 + padstack->y; + tmp.Point2.X = shp->data.line.x2 + padstack->x; + tmp.Point2.Y = shp->data.line.y2 + padstack->y; + tmp.Thickness = shp->data.line.thickness; + rnd_fprintf(f, " polygon %s %s %s %mm 4", lloc, ltyp, TERM_NAME(padstack->term), clr); + print_sqpad_coords(f, &tmp, ox, oy); + rnd_fprintf(f, "\n"); + } + else { + rnd_fprintf(f, " line %s %s %s %mm %mm %mm %mm %mm %mm\n", lloc, ltyp, TERM_NAME(padstack->term), + shp->data.line.x1 + padstack->x - ox, shp->data.line.y1 + padstack->y - oy, + shp->data.line.x2 + padstack->x - ox, shp->data.line.y2 + padstack->y - oy, + shp->data.line.thickness, clr); + } + break; + case PCB_PSSH_POLY: + rnd_fprintf(f, " polygon %s %s %s %.06mm %ld", lloc, ltyp, TERM_NAME(padstack->term), + clr, shp->data.poly.len); + for(i = 0; i < shp->data.poly.len; i++) + rnd_fprintf(f, " %.06mm %.06mm", + shp->data.poly.x[i] + padstack->x - ox, + shp->data.poly.y[i] + padstack->y - oy); + rnd_fprintf(f, "\n"); + break; + } + } + return 0; +} + +int tedax_fp_fsave_subc_(pcb_subc_t *subc, const char *fpname, int lyrecipe, FILE *f) +{ + htsp_t terms; + htsp_entry_t *e; + rnd_coord_t ox = 0, oy = 0; + int l; + + htsp_init(&terms, strhash, strkeyeq); + pcb_subc_get_origin(subc, &ox, &oy); + + fprintf(f, "\nbegin footprint v1 "); + tedax_fprint_escape(f, fpname); + fprintf(f, "\n"); + + for(l = 0; l < subc->data->LayerN; l++) { + pcb_layer_t *ly = &subc->data->Layer[l]; + pcb_layer_type_t lyt; + const char *lloc, *ltyp; + + if (lyrecipe && ly->is_bound) + lyt = ly->meta.bound.type; + else + lyt = pcb_layer_flags_(ly); + + get_layer_props(lyt, lloc, ltyp, continue); + + PCB_LINE_LOOP(ly) + { + if (line->term != NULL) print_terma(&terms, line->term, line); + rnd_fprintf(f, " line %s %s %s %mm %mm %mm %mm %mm %mm\n", lloc, ltyp, TERM_NAME(line->term), + line->Point1.X - ox, line->Point1.Y - oy, line->Point2.X - ox, line->Point2.Y - oy, + line->Thickness, line->Clearance); + } + PCB_END_LOOP; + + PCB_ARC_LOOP(ly) + { + if (arc->term != NULL) print_terma(&terms, arc->term, arc); + rnd_fprintf(f, " arc %s %s %s %mm %mm %mm %f %f %mm %mm\n", lloc, ltyp, TERM_NAME(arc->term), + arc->X - ox, arc->Y - oy, (arc->Width + arc->Height)/2, arc->StartAngle, arc->Delta, + arc->Thickness, arc->Clearance); + } + PCB_END_LOOP; + + { + pcb_gfx_t *gfx; + for(gfx = gfxlist_first(&ly->Gfx); gfx != NULL; gfx = gfxlist_next(gfx)) + pcb_io_incompat_save(PCB->Data, (pcb_any_obj_t *)gfx, "gfx", "gfx can not be exported", "please use the lihata board format"); + } + + PCB_POLY_LOOP(ly) + { + int go; + long numpt = 0; + rnd_coord_t x, y; + pcb_poly_it_t it; + + if (polygon->Clipped == NULL) + pcb_poly_init_clip(polygon->parent.layer->parent.data, polygon->parent.layer, polygon); + + pcb_poly_iterate_polyarea(polygon->Clipped, &it); + if (pcb_poly_contour(&it) == NULL) { + rnd_message(RND_MSG_ERROR, "tEDAx footprint export: omitting subc polygon with no clipped contour\n"); + continue; + } + + /* iterate over the vectors of the contour */ + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) + numpt++; + + if (pcb_poly_hole_first(&it) != NULL) + rnd_message(RND_MSG_ERROR, "tEDAx footprint export: omitting subc polygon holes\n"); + + if (numpt == 0) { + rnd_message(RND_MSG_ERROR, "tEDAx footprint export: omitting subc polygon with no points\n"); + continue; + } + + if (polygon->term != NULL) print_terma(&terms, polygon->term, polygon); + rnd_fprintf(f, " polygon %s %s %s %.06mm %ld", lloc, ltyp, TERM_NAME(polygon->term), + (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, polygon) ? 0 : polygon->Clearance), + numpt); + + /* rewind the iterator*/ + pcb_poly_iterate_polyarea(polygon->Clipped, &it); + pcb_poly_contour(&it); + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) + rnd_fprintf(f, " %.06mm %.06mm", x - ox, y - oy); + rnd_fprintf(f, "\n"); + } + PCB_END_LOOP; + } + + PCB_PADSTACK_LOOP(subc->data) + { + if (padstack->term != NULL) print_terma(&terms, padstack->term, padstack); + tedax_pstk_fsave(padstack, ox, oy, f); + } + PCB_END_LOOP; + + fprintf(f, "end footprint\n"); + + for (e = htsp_first(&terms); e; e = htsp_next(&terms, e)) { + free(e->key); + htsp_delentry(&terms, e); + } + htsp_uninit(&terms); + return 0; +} + + +int tedax_fp_fsave_subc(pcb_subc_t *subc, FILE *f) +{ + const char *fpname = pcb_attribute_get(&subc->Attributes, "tedax::footprint"); + if (fpname == NULL) + fpname = pcb_attribute_get(&subc->Attributes, "visible_footprint"); + if (fpname == NULL) + fpname = pcb_attribute_get(&subc->Attributes, "footprint"); + if ((fpname == NULL) && (subc->refdes != NULL)) + fpname = subc->refdes; + if (fpname == NULL) + fpname = "-"; + + return tedax_fp_fsave_subc_(subc, fpname, 0, f); +} + +int tedax_fp_fsave(pcb_data_t *data, FILE *f, long subc_idx) +{ + int res = 0; + long cnt = 0; + + + fprintf(f, "tEDAx v1\n"); + + PCB_SUBC_LOOP(data) + { + if ((subc_idx == -1) || (subc_idx == cnt)) + res |= tedax_fp_fsave_subc(subc, f); + cnt++; + } + PCB_END_LOOP; + + + return res; +} + +int tedax_fp_save(pcb_data_t *data, const char *fn, long subc_idx) +{ + int res; + FILE *f; + + f = rnd_fopen_askovr(&PCB->hidlib, fn, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_fp_save(): can't open %s for writing\n", fn); + return -1; + } + res = tedax_fp_fsave(data, f, subc_idx); + fclose(f); + return res; +} + + +/*******************************/ + +typedef struct { + char *pinid; + /* type can be ignored in pcb-rnd */ + char *name; + + /* put all objects on this per terminal list so the padstack converter can pick them up */ + vtp0_t objs; +} term_t; + +static term_t *term_new(const char *pinid, const char *name) +{ + term_t *t = calloc(sizeof(term_t), 1); + t->pinid = rnd_strdup(pinid); + t->name = rnd_strdup(name); + return t; +} + +static void term_destroy(term_t *t) +{ + free(t->pinid); + free(t->name); + vtp0_uninit(&t->objs); + free(t); +} + +#define load_int(dst, src, msg) \ +do { \ + char *end; \ + dst = strtol(src, &end, 10); \ + if (*end != '\0') { \ + rnd_message(RND_MSG_ERROR, msg, src); \ + return -1; \ + } \ +} while(0) + +#define load_dbl(dst, src, msg) \ +do { \ + char *end; \ + dst = strtod(src, &end); \ + if (*end != '\0') { \ + rnd_message(RND_MSG_ERROR, msg, src); \ + return -1; \ + } \ +} while(0) + +#define load_val(dst, src, msg) \ +do { \ + rnd_bool succ; \ + dst = rnd_get_value_ex(src, NULL, NULL, NULL, "mm", &succ); \ + if (!succ) { \ + rnd_message(RND_MSG_ERROR, msg, src); \ + return -1; \ + } \ +} while(0) + +#define load_term(obj, src, msg) \ +do { \ + term_t *term; \ + if ((src[0] == '-') && (src[1] == '\0')) break; \ + term = htsp_get(&terms, src); \ + if (term == NULL) { \ + rnd_message(RND_MSG_ERROR, msg, src); \ + return -1; \ + } \ + pcb_attribute_put(&obj->Attributes, "term", term->name); \ + vtp0_append(&term->objs, obj); \ +} while(0) + +#define load_lloc(dst, src, msg) \ +do { \ + if (strcmp(src, "secondary") == 0) \ + dst = 1; \ + else if (strcmp(src, "primary") == 0) \ + dst = 0; \ + else { \ + rnd_message(RND_MSG_ERROR, msg, lloc); \ + return -1; \ + } \ +} while(0) + + +static int load_poly(rnd_coord_t *px, rnd_coord_t *py, int maxpt, int argc, char *argv[]) +{ + int max, n; + load_int(max, argv[0], "invalid number of points '%s' in poly, skipping footprint\n"); + argc--; + argv++; + if (max*2 != argc) { + rnd_message(RND_MSG_ERROR, "invalid number of polygon points: expected %d coords got %d skipping footprint\n", max*2, argc); + return -1; + } + for(n = 0; n < max; n++) { + load_val(px[n], argv[n*2+0], "invalid X '%s' in poly, skipping footprint\n"); + load_val(py[n], argv[n*2+1], "invalid Y '%s' in poly, skipping footprint\n"); + } + return max; +} + +/* Returns a NULL terminated list of layers to operate on or NULL on error; + not reentrant! */ +static pcb_layer_t **subc_get_layer(pcb_subc_t *subc, const char *lloc, const char *ltyp) +{ + pcb_layer_type_t lyt = 0; + static pcb_layer_t *layers[4]; + char name[128]; + + memset(layers, 0, sizeof(layers)); + + if (strcmp(ltyp, "copper") == 0) lyt |= PCB_LYT_COPPER; + else if (strcmp(ltyp, "silk") == 0) lyt |= PCB_LYT_SILK; + else if (strcmp(ltyp, "mask") == 0) lyt |= PCB_LYT_MASK; + else if (strcmp(ltyp, "paste") == 0) lyt |= PCB_LYT_PASTE; + else { + rnd_message(RND_MSG_ERROR, "tEDAx footprint load: invalid layer type %s\n", ltyp); + return NULL; + } + + if (strcmp(lloc, "all") == 0) { + sprintf(name, "top_%s", ltyp); + layers[0] = pcb_subc_get_layer(subc, lyt | PCB_LYT_TOP, -1, rnd_true, name, rnd_false); + sprintf(name, "bottom_%s", ltyp); + layers[1] = pcb_subc_get_layer(subc, lyt | PCB_LYT_BOTTOM, -1, rnd_true, name, rnd_false); + if (lyt == PCB_LYT_COPPER) { + sprintf(name, "intern_%s", ltyp); + layers[2] = pcb_subc_get_layer(subc, lyt | PCB_LYT_INTERN, -1, rnd_true, name, rnd_false); + } + return layers; + } + + if (strcmp(lloc, "primary") == 0) lyt |= PCB_LYT_TOP; + else if (strcmp(lloc, "secondary") == 0) lyt |= PCB_LYT_BOTTOM; + else if (strcmp(lloc, "inner") == 0) lyt |= PCB_LYT_INTERN; + else { + rnd_message(RND_MSG_ERROR, "tEDAx footprint load: invalid layer location %s\n", lloc); + return NULL; + } + + sprintf(name, "%s_%s", lloc, ltyp); + layers[0] = pcb_subc_get_layer(subc, lyt, -1, rnd_true, name, rnd_false); + return layers; +} + +/* Parse one footprint block */ +static int tedax_parse_1fp_(pcb_subc_t *subc, FILE *fn, char *buff, int buff_size, char *argv[], int argv_size) +{ + int argc, numpt, res = -1; + htsp_entry_t *ei; + htsp_t terms; + term_t *term; + rnd_coord_t px[256], py[256], clr; + pcb_layer_t **ly; + + htsp_init(&terms, strhash, strkeyeq); + while((argc = tedax_getline(fn, buff, buff_size, argv, argv_size)) >= 0) { + if ((argc == 5) && (strcmp(argv[0], "term") == 0)) { + term = term_new(argv[2], argv[4]); + htsp_set(&terms, rnd_strdup(argv[1]), term); + } + else if ((argc >= 12) && (strcmp(argv[0], "polygon") == 0)) { + pcb_poly_t *p; + ly = subc_get_layer(subc, argv[1], argv[2]); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "tEDAx footprint load: invalid polygon layer %s %s\n", argv[1], argv[2]); + return -1; + } + + numpt = load_poly(px, py, (sizeof(px) / sizeof(px[0])), argc-5, argv+5); + if (numpt < 0) { + rnd_message(RND_MSG_ERROR, "tEDAx footprint load: failed to load polygon\n"); + return -1; + } + load_val(clr, argv[4], "invalid clearance"); + + for(; *ly != NULL; ly++) { + int n; + p = pcb_poly_new(*ly, clr, pcb_no_flags()); + if (p == NULL) { + rnd_message(RND_MSG_ERROR, "tEDAx footprint load: failed to create poly, skipping footprint\n"); + return -1; + } + for(n = 0; n < numpt; n++) + pcb_poly_point_new(p, px[n], py[n]); + + load_term(p, argv[3], "invalid term ID for polygon: '%s', skipping footprint\n"); + + pcb_add_poly_on_layer(*ly, p); + } + } + else if ((argc == 10) && (strcmp(argv[0], "line") == 0)) { + rnd_coord_t x1, y1, x2, y2, w, clr; + pcb_line_t *l; + + ly = subc_get_layer(subc, argv[1], argv[2]); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "tEDAx footprint load: invalid line layer %s %s\n", argv[1], argv[2]); + return -1; + } + + load_val(x1, argv[4], "invalid line x1"); + load_val(y1, argv[5], "invalid line y1"); + load_val(x2, argv[6], "invalid line x2"); + load_val(y2, argv[7], "invalid line y2"); + load_val(w, argv[8], "invalid line width"); + load_val(clr, argv[9], "invalid line clearance"); + + for(; *ly != NULL; ly++) { + l = pcb_line_new(*ly, x1, y1, x2, y2, w, clr, pcb_flag_make(PCB_FLAG_CLEARLINE)); + load_term(l, argv[3], "invalid term ID for line: '%s', skipping footprint\n"); + } + } + else if ((argc == 11) && (strcmp(argv[0], "arc") == 0)) { + rnd_coord_t cx, cy, r, w; + double sa, da; + pcb_arc_t *a; + + ly = subc_get_layer(subc, argv[1], argv[2]); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "tEDAx footprint load: invalid arc layer %s %s\n", argv[1], argv[2]); + return -1; + } + + load_val(cx, argv[4], "invalid arc cx"); + load_val(cy, argv[5], "invalid arc cy"); + load_val(r, argv[6], "invalid arc radius"); + load_dbl(sa, argv[7], "invalid arc start angle"); + load_dbl(da, argv[8], "invalid arc delta angle"); + load_val(w, argv[9], "invalid arc width"); + + for(; *ly != NULL; ly++) { + a = pcb_arc_new(*ly, cx, cy, r, r, sa, da, w, clr, pcb_flag_make(PCB_FLAG_CLEARLINE), rnd_true); + load_term(a, argv[3], "invalid term ID for arc: '%s', skipping footprint\n"); + } + } + else if ((argc == 6) && (strcmp(argv[0], "hole") == 0)) { + rnd_coord_t cx, cy, d; + int plated; + pcb_pstk_t *ps; + + load_val(cx, argv[2], "invalid hole cx"); + load_val(cy, argv[3], "invalid hole cy"); + load_val(d, argv[4], "invalid hole radius"); + plated = !(strcmp(argv[5], "unplated") == 0); + + ps = pcb_pstk_new_hole(subc->data, cx, cy, d, plated); + load_term(ps, argv[1], "invalid term ID for hole: '%s', skipping footprint\n"); + } + else if ((argc == 8) && (strcmp(argv[0], "fillcircle") == 0)) { + rnd_coord_t cx, cy, r, clr; + pcb_line_t *l; + + ly = subc_get_layer(subc, argv[1], argv[2]); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "tEDAx footprint load: invalid fillcircle layer %s %s\n", argv[1], argv[2]); + return -1; + } + + load_val(cx, argv[4], "invalid fillcircle cx"); + load_val(cy, argv[5], "invalid fillcircle cy"); + load_val(r, argv[6], "invalid fillcircle radius"); + load_val(clr, argv[7], "invalid fillcircle clearance"); + + for(; *ly != NULL; ly++) { + l = pcb_line_new(*ly, cx, cy, cx, cy, r*2, clr, pcb_flag_make(PCB_FLAG_CLEARLINE)); + load_term(l, argv[3], "invalid term ID for fillcircle: '%s', skipping footprint\n"); + } + } + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "footprint") == 0)) { + res = 0; + break; + } + else { + rnd_message(RND_MSG_ERROR, "tEDAx footprint load: invalid object %s with %d fields\n", argv[0], argc); + return -1; + } + } + + /* By now we have heavy terminals and a list of object for each terminal in + the terms hash. Iterate over the terminals and try to convert the objects + into one or more padstacks */ + for(ei = htsp_first(&terms); ei; ei = htsp_next(&terms, ei)) { + term = ei->value; + pcb_pstk_vect2pstk(subc->data, &term->objs, rnd_true); + term_destroy(term); + free(ei->key); + } + htsp_uninit(&terms); + + pcb_attribute_put(&subc->Attributes, "refdes", "X1"); + pcb_subc_add_refdes_text(subc, 0, 0, 0, 100, rnd_false); + pcb_subc_create_aux(subc, 0, 0, 0.0, rnd_false); + + return res; +} + +pcb_subc_t *tedax_parse_1fp(pcb_data_t *data, FILE *fn, char *buff, int buff_size, char *argv[], int argv_size) +{ + pcb_subc_t *sc = pcb_subc_alloc(); + pcb_subc_reg(data, sc); + + if (tedax_parse_1fp_(sc, fn, buff, buff_size, argv, argv_size) != 0) { + pcb_subc_free(sc); + return NULL; + } + + return sc; +} + + +/* parse one or more footprint blocks */ +static int tedax_parse_fp(pcb_data_t *data, FILE *fn, int multi, const char *blk_id, int silent) +{ + char line[520]; + char *argv[16]; + int found = 0; + + if (tedax_seek_hdr(fn, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + do { + if (tedax_seek_block(fn, "footprint", "v1", blk_id, silent || (found > 0), line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + break; + + if (tedax_parse_1fp(data, fn, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) == NULL) + return -1; + found++; + } while(multi); + if (found == 0) + return -1; + return 0; +} + +int tedax_fp_load(pcb_data_t *data, const char *fn, int multi, const char *blk_id, int silent, int searchlib) +{ + FILE *f; + int ret = 0; + pcb_fp_fopen_ctx_t st; + + + if (searchlib) + f = pcb_fp_fopen(&conf_core.rc.library_search_paths, fn, &st, NULL); + else + f = rnd_fopen(&PCB->hidlib, fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fn); + return -1; + } + + ret = tedax_parse_fp(data, f, multi, blk_id, silent); + + if (searchlib) + pcb_fp_fclose(f, &st); + else + fclose(f); + return ret; +} + +pcb_plug_fp_map_t *tedax_fp_map(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags) +{ + char *s, line[515]; + int n; + + /* find tEDAx main header */ + for(n = 0; ;n++) { + if (n > 128) return NULL; + s = fgets(line, sizeof(line), f); + if (s == NULL) return NULL; + while(isspace(*s)) s++; + if ((*s == '\0') || (*s == '#')) continue; /* empty line or comment */ + if (strncmp(s, "tEDAx v", 7) == 0) break; /* accept */ + /* non-tedax content */ + return NULL; + } + + /* pick up all footprints */ + while((s = fgets(line, sizeof(line), f)) != NULL) { + while(isspace(*s)) s++; + if ((*s == '\0') || (*s == '#')) continue; /* empty line or comment */ + if (strncmp(s, "begin", 5) == 0) { + s += 5; + while(isspace(*s)) s++; + if (strncmp(s, "footprint", 9) == 0) { + s += 9; + while(isspace(*s)) s++; + /* footprint name is in s */ + TODO("don't return the first only"); + head->type = PCB_FP_FILE; + return head; + } + } + } + + /* no footprint found in the file */ + return NULL; +} Index: tags/2.3.0/src_plugins/io_tedax/footprint.h =================================================================== --- tags/2.3.0/src_plugins/io_tedax/footprint.h (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/footprint.h (revision 33253) @@ -0,0 +1,22 @@ +#include "data.h" +#include +#include "plug_io.h" + +int tedax_fp_save(pcb_data_t *data, const char *fn, long subc_idx); +int tedax_fp_fsave(pcb_data_t *data, FILE *f, long subc_idx); +int tedax_fp_fsave_subc(pcb_subc_t *subc, FILE *f); +int tedax_fp_load(pcb_data_t *data, const char *fn, int multi, const char *blk_id, int silent, int searchlib); + +/* parse a single footprint at current file pos; returns NULL on error */ +pcb_subc_t *tedax_parse_1fp(pcb_data_t *data, FILE *fn, char *buff, int buff_size, char *argv[], int argv_size); + +/* Save a single subc, with footprint header */ +int tedax_fp_fsave_subc_(pcb_subc_t *subc, const char *fpname, int lyrecipe, FILE *f); + +int tedax_pstk_fsave(pcb_pstk_t *padstack, rnd_coord_t ox, rnd_coord_t oy, FILE *f); + +pcb_plug_fp_map_t *tedax_fp_map(pcb_plug_io_t *ctx, FILE *f, const char *fn, pcb_plug_fp_map_t *head, int need_tags); + + + + Index: tags/2.3.0/src_plugins/io_tedax/io_tedax.c =================================================================== --- tags/2.3.0/src_plugins/io_tedax/io_tedax.c (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/io_tedax.c (revision 33253) @@ -0,0 +1,358 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tedax IO plugin - plugin coordination + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "footprint.h" + +#include "board.h" +#include "conf_core.h" +#include "buffer.h" +#include +#include +#include +#include +#include +#include +#include "plug_io.h" +#include "stackup.h" +#include "tlayer.h" +#include "tboard.h" +#include "trouter.h" +#include "tdrc.h" +#include "tdrc_query.h" +#include "tetest.h" +#include "tnetlist.h" +#include "trouter.h" + +#include "menu_internal.c" + +static const char *tedax_cookie = "tEDAx IO"; +static pcb_plug_io_t io_tedax; + +int io_tedax_fmt(pcb_plug_io_t *ctx, pcb_plug_iot_t typ, int wr, const char *fmt) +{ + if (strcmp(ctx->description, fmt) == 0) + return 200; + + if ((rnd_strcasecmp(fmt, "tedax") != 0) || + ((typ & (~(PCB_IOT_PCB | PCB_IOT_FOOTPRINT | PCB_IOT_BUFFER))) != 0)) + return 0; + + return 100; +} + + +static const char pcb_acts_Savetedax[] = + "SaveTedax(netlist|board-footprints|stackup|layer|board|drc|etest, filename)\n" + "SaveTedax(drc_query, filename, [rule_name])" + "SaveTedax(route_req, filename, [confkey=value, confkey=value, ...])"; +static const char pcb_acth_Savetedax[] = "Saves the specific type of data in a tEDAx file."; +static fgw_error_t pcb_act_Savetedax(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL, *type, *id = NULL; + + RND_ACT_CONVARG(1, FGW_STR, Savetedax, type = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, Savetedax, fname = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, Savetedax, id = argv[3].val.str); + + if (rnd_strcasecmp(type, "netlist") == 0) { + RND_ACT_IRES(tedax_net_save(PCB, NULL, fname)); + return 0; + } + + if (rnd_strcasecmp(type, "board-footprints") == 0) { + RND_ACT_IRES(tedax_fp_save(PCB->Data, fname, -1)); + return 0; + } + + if (rnd_strcasecmp(type, "stackup") == 0) { + RND_ACT_IRES(tedax_stackup_save(PCB, PCB->hidlib.name, fname)); + return 0; + } + + if (rnd_strcasecmp(type, "layer") == 0) { + RND_ACT_IRES(tedax_layer_save(PCB, pcb_layer_get_group_(PCB_CURRLAYER(PCB)), NULL, fname)); + return 0; + } + + if (rnd_strcasecmp(type, "board") == 0) { + RND_ACT_IRES(tedax_board_save(PCB, fname)); + return 0; + } + + if (rnd_strcasecmp(type, "drc") == 0) { + RND_ACT_IRES(tedax_drc_save(PCB, NULL, fname)); + return 0; + } + + if (rnd_strcasecmp(type, "drc_query") == 0) { + RND_ACT_IRES(tedax_drc_query_save(PCB, id, fname)); + return 0; + } + + if (rnd_strcasecmp(type, "etest") == 0) { + RND_ACT_IRES(tedax_etest_save(PCB, NULL, fname)); + return 0; + } + + if (rnd_strcasecmp(type, "route_req") == 0) { + RND_ACT_IRES(tedax_route_req_save(PCB, fname, argc-3, argv+3)); + return 0; + } + + RND_ACT_FAIL(Savetedax); + RND_ACT_IRES(1); + return 0; +} + +#define gen_load(type, fname) \ +do { \ + static char *default_file = NULL; \ + if ((fname == NULL) || (*fname == '\0')) { \ + fname = rnd_gui->fileselect(rnd_gui, "Load tedax " #type " file...", \ + "Picks a tedax " #type " file to load.\n", \ + default_file, ".tdx", NULL, "tedax-" #type, RND_HID_FSD_READ, NULL); \ + if (fname == NULL) \ + return 1; \ + if (default_file != NULL) { \ + free(default_file); \ + default_file = NULL; \ + } \ + } \ +} while(0) + +static const char pcb_acts_LoadtedaxFrom[] = "LoadTedaxFrom(netlist|board|footprint|stackup|layer|drc|drc_query|route_res, filename, [block_id, [silent, [src]]])"; +static const char pcb_acth_LoadtedaxFrom[] = "Loads the specified block from a tedax file."; +static fgw_error_t pcb_act_LoadtedaxFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL, *type, *id = NULL, *silents = NULL, *src = NULL; + int silent; + + RND_ACT_CONVARG(1, FGW_STR, LoadtedaxFrom, type = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, LoadtedaxFrom, fname = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, LoadtedaxFrom, id = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, LoadtedaxFrom, silents = argv[4].val.str); + RND_ACT_MAY_CONVARG(5, FGW_STR, LoadtedaxFrom, src = argv[5].val.str); + + if ((id != NULL) && (*id == '\0')) + id = NULL; + + silent = (silents != NULL) && (rnd_strcasecmp(silents, "silent") == 0); + + if (rnd_strcasecmp(type, "netlist") == 0) { + gen_load(netlist, fname); + RND_ACT_IRES(tedax_net_load(fname, 1, id, silent)); + return 0; + } + if (rnd_strcasecmp(type, "route_res") == 0) { + gen_load(route_res, fname); + RND_ACT_IRES(tedax_route_res_load(fname, id, silent)); + return 0; + } + if (rnd_strcasecmp(type, "route_conf_keys") == 0) { /* intentionally undocumented - for internal use, returns a pointer */ + gen_load(route_conf_keys, fname); + res->type = FGW_PTR; + res->val.ptr_void = tedax_route_conf_keys_load(fname, id, silent); + return 0; + } + if (rnd_strcasecmp(type, "board") == 0) { + gen_load(board, fname); + RND_ACT_IRES(tedax_board_load(PCB, fname, id, silent)); + return 0; + } + if (rnd_strcasecmp(type, "footprint") == 0) { + gen_load(footprint, fname); + RND_ACT_IRES(tedax_fp_load(PCB_PASTEBUFFER->Data, fname, 0, id, silent, 0)); + return 0; + } + if (rnd_strcasecmp(type, "stackup") == 0) { + gen_load(stackup, fname); + RND_ACT_IRES(tedax_stackup_load(PCB, fname, id, silent)); + return 0; + } + if (rnd_strcasecmp(type, "layer") == 0) { + gen_load(layer, fname); + RND_ACT_IRES(tedax_layers_load(PCB_PASTEBUFFER->Data, fname, id, silent)); + return 0; + } + if (rnd_strcasecmp(type, "drc") == 0) { + gen_load(drc, fname); + RND_ACT_IRES(tedax_drc_load(PCB, fname, id, silent)); + return 0; + } + if (rnd_strcasecmp(type, "drc_query") == 0) { + gen_load(drc_query, fname); + RND_ACT_IRES(tedax_drc_query_load(PCB, fname, id, src, silent)); + return 0; + } + RND_ACT_FAIL(LoadtedaxFrom); +} + +int pcb_io_tedax_test_parse(pcb_plug_io_t *plug_ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); + +static const char pcb_acts_TedaxTestParse[] = "TedaxTestParse(filename|FILE*)"; +static const char pcb_acth_TedaxTestParse[] = "Returns 1 if the file looks like tEDAx (0 if not)"; +static fgw_error_t pcb_act_TedaxTestParse(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + if (argc < 2) + return -1; + if ((argv[1].type & FGW_STR) == FGW_STR) { + FILE *f = rnd_fopen(RND_ACT_HIDLIB, argv[1].val.str, "r"); + if (f == NULL) { + RND_ACT_IRES(0); + return 0; + } + RND_ACT_IRES(pcb_io_tedax_test_parse(&io_tedax, 0, NULL, f)); + fclose(f); + return 0; + } + else if (((argv[1].type & FGW_PTR) == FGW_PTR)) { + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[1], RND_PTR_DOMAIN_FILE_PTR)) + return FGW_ERR_PTR_DOMAIN; + RND_ACT_IRES(pcb_io_tedax_test_parse(&io_tedax, 0, NULL, argv[1].val.ptr_void)); + return 0; + } + return FGW_ERR_ARG_CONV; +} + +rnd_action_t tedax_action_list[] = { + {"LoadTedaxFrom", pcb_act_LoadtedaxFrom, pcb_acth_LoadtedaxFrom, pcb_acts_LoadtedaxFrom}, + {"SaveTedax", pcb_act_Savetedax, pcb_acth_Savetedax, pcb_acts_Savetedax}, + {"TedaxTestParse", pcb_act_TedaxTestParse, pcb_acth_TedaxTestParse, pcb_acts_TedaxTestParse} +}; + +static int io_tedax_parse_footprint(pcb_plug_io_t *ctx, pcb_data_t *Ptr, const char *name, const char *subfpname) +{ + return tedax_fp_load(Ptr, name, 0, NULL, 0, 1); +} + +int io_tedax_fp_write_subcs_head(pcb_plug_io_t *ctx, void **udata, FILE *f, int lib, long num_subcs) +{ + fprintf(f, "tEDAx v1\n"); + return 0; +} + +int io_tedax_fp_write_subcs_subc(pcb_plug_io_t *ctx, void **udata, FILE *f, pcb_subc_t *subc) +{ + return tedax_fp_fsave_subc(subc, f); +} + +int io_tedax_fp_write_subcs_tail(pcb_plug_io_t *ctx, void **udata, FILE *f) +{ + return 0; +} + +int pcb_io_tedax_test_parse(pcb_plug_io_t *plug_ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f) +{ + char line[515], *s; + int n; + for(n = 0; n < 32; n++) { + s = fgets(line, sizeof(line), f); + if (s == NULL) + return 0; + while(isspace(*s)) s++; + if (*s == '#') + continue; + if (strncmp(s, "tEDAx", 5) == 0) { + s += 5; + while(isspace(*s)) s++; + if ((s[0] == 'v') && (s[1] == '1')) + return 1; /* support version 1 only */ + } + } + return 0; +} + +int io_tedax_parse_pcb(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, rnd_conf_role_t settings_dest) +{ + int res; + + Ptr->is_footprint = 1; + + res = tedax_fp_load(Ptr->Data, Filename, 0, NULL, 0, 0); + if (res == 0) { + pcb_subc_t *sc = Ptr->Data->subc.lst.first; + + pcb_layergrp_upgrade_to_pstk(Ptr); + pcb_layer_create_all_for_recipe(Ptr, sc->data->Layer, sc->data->LayerN); + pcb_subc_rebind(Ptr, sc); + pcb_data_clip_polys(sc->data); + } + return res; +} + + +int pplg_check_ver_io_tedax(int ver_needed) { return 0; } + +void pplg_uninit_io_tedax(void) +{ + rnd_remove_actions_by_cookie(tedax_cookie); + tedax_etest_uninit(); + RND_HOOK_UNREGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_tedax); + pcb_tedax_net_uninit(); + rnd_hid_menu_unload(rnd_gui, tedax_cookie); +} + +int pplg_init_io_tedax(void) +{ + RND_API_CHK_VER; + + /* register the IO hook */ + io_tedax.plugin_data = NULL; + io_tedax.fmt_support_prio = io_tedax_fmt; + io_tedax.test_parse = pcb_io_tedax_test_parse; + io_tedax.parse_pcb = io_tedax_parse_pcb; + io_tedax.parse_footprint = io_tedax_parse_footprint; + io_tedax.map_footprint = tedax_fp_map; + io_tedax.parse_font = NULL; + io_tedax.write_buffer = NULL; + io_tedax.write_subcs_head = io_tedax_fp_write_subcs_head; + io_tedax.write_subcs_subc = io_tedax_fp_write_subcs_subc; + io_tedax.write_subcs_tail = io_tedax_fp_write_subcs_tail; + io_tedax.write_pcb = NULL; + io_tedax.default_fmt = "tEDAx"; + io_tedax.description = "Trivial EDA eXchange format"; + io_tedax.save_preference_prio = 95; + io_tedax.default_extension = ".tdx"; + io_tedax.fp_extension = ".tdx"; + io_tedax.mime_type = "application/tEDAx"; + + RND_HOOK_REGISTER(pcb_plug_io_t, pcb_plug_io_chain, &io_tedax); + + tedax_etest_init(); + + RND_REGISTER_ACTIONS(tedax_action_list, tedax_cookie) + pcb_tedax_net_init(); + rnd_hid_menu_load(rnd_gui, NULL, tedax_cookie, 195, NULL, 0, tedax_menu, "plugin: io_tedax"); + return 0; +} Index: tags/2.3.0/src_plugins/io_tedax/io_tedax.pup =================================================================== --- tags/2.3.0/src_plugins/io_tedax/io_tedax.pup (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/io_tedax.pup (revision 33253) @@ -0,0 +1,19 @@ +$class io +$short tEDAx (Trivial EDA eXchange) +$long Import and export tEDAx netlists and footprints. +$state works +$fmt-native no +$fmt-feature-r tEDAx netlist (any version) +$fmt-feature-w tEDAx netlist (any version) +$fmt-feature-r tEDAx footprint (any version) +$fmt-feature-w tEDAx footprint (any version) +$fmt-feature-w tEDAx etest +$fmt-feature-r tEDAx drc +$fmt-feature-w tEDAx drc +$fmt-feature-r tEDAx pcb-rnd drc script +$fmt-feature-w tEDAx pcb-rnd drc script +$package io-standard +dep lib_compat_help +dep lib_netmap +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/io_tedax/parse.c =================================================================== --- tags/2.3.0/src_plugins/io_tedax/parse.c (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/parse.c (revision 33253) @@ -0,0 +1,190 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#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_fnprint_escape(FILE *f, const char *val, int len) +{ + if ((val == NULL) || (*val == '\0')) { + fputc('-', f); + return; + } + for(; (*val != '\0') && (len > 0); val++,len--) { + 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); + } + } +} + +void tedax_fprint_escape(FILE *f, const char *val) +{ + tedax_fnprint_escape(f, val, 510); +} + +#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/2.3.0/src_plugins/io_tedax/parse.h =================================================================== --- tags/2.3.0/src_plugins/io_tedax/parse.h (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/parse.h (revision 33253) @@ -0,0 +1,30 @@ +#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[0] == '\\') && ((end == s) || (end[-1] != '\\'))) \ + 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); +void tedax_fnprint_escape(FILE *f, const char *val, int len); +int tedax_strncpy_escape(char *dst, int dstlen, const char *val); + Index: tags/2.3.0/src_plugins/io_tedax/stackup.c =================================================================== --- tags/2.3.0/src_plugins/io_tedax/stackup.c (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/stackup.c (revision 33253) @@ -0,0 +1,438 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tedax IO plugin - stackup import/export + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include +#include +#include + +#include "stackup.h" +#include "parse.h" +#include +#include +#include +#include "plug_io.h" + +void tedax_stackup_init(tedax_stackup_t *ctx) +{ + htsp_init(&ctx->n2g, strhash, strkeyeq); + vtp0_init(&ctx->g2n); + ctx->include_grp_id = 0; +} + +void tedax_stackup_uninit(tedax_stackup_t *ctx) +{ + htsp_uninit(&ctx->n2g); + vtp0_uninit(&ctx->g2n); +} + + +static void gen_layer_name(tedax_stackup_t *ctx, char dst[65], const char *name, int prefix, rnd_layergrp_id_t gid) +{ + char *d = dst; + int rem = 64, l; + + if (ctx->include_grp_id) { + l = sprintf(dst, "%ld.", gid); + rem -= l; + d += l; + } + else if (prefix != 0) { + l = sprintf(dst, "%d_", prefix); + rem -= l; + d += l; + } + for(;(*name != '\0') && (rem > 0);rem--,name++) { + if (isalnum(*name) || (*name == '-') || (*name == '.') || (*name == '_')) + *d = *name; + else + *d = '_'; + d++; + } + *d = '\0'; +} + +static const char ANY_PURP[] = "any"; + +typedef enum { TDX_OUTER=1, TDX_INNER=2, TDX_ALL=4, TDX_VIRTUAL=8 } tedax_loc_t; + +typedef struct { + const char *typename; + const char *purpose; + pcb_layer_type_t type; + int force_virtual; + tedax_loc_t loc; +} tedax_layer_t; + +static const tedax_layer_t layertab[] = { + {"copper", NULL, PCB_LYT_COPPER, 0, TDX_OUTER | TDX_INNER}, + {"insulator", NULL, PCB_LYT_SUBSTRATE, 0, TDX_INNER}, + {"silk", NULL, PCB_LYT_SILK, 0, TDX_OUTER}, + {"paste", NULL, PCB_LYT_PASTE, 0, TDX_OUTER}, + {"mask", NULL, PCB_LYT_MASK, 0, TDX_OUTER}, + {"umech", "uroute", PCB_LYT_BOUNDARY, 0, TDX_ALL}, + {"umech", "udrill", PCB_LYT_BOUNDARY, 0, TDX_ALL}, + {"umech", "uroute", PCB_LYT_MECH, 0, TDX_ALL}, + {"umech", "udrill", PCB_LYT_MECH, 0, TDX_ALL}, + {"pmech", "proute", PCB_LYT_BOUNDARY, 0, TDX_ALL}, + {"pmech", "pdrill", PCB_LYT_BOUNDARY, 0, TDX_ALL}, + {"pmech", "proute", PCB_LYT_MECH, 0, TDX_ALL}, + {"pmech", "pdrill", PCB_LYT_MECH, 0, TDX_ALL}, + {"vcut", "vcut", PCB_LYT_BOUNDARY, 0, TDX_ALL}, + {"vcut", "vcut", PCB_LYT_MECH, 0, TDX_ALL}, + {"doc", ANY_PURP, PCB_LYT_DOC, 1, TDX_OUTER | TDX_INNER | TDX_ALL}, + {NULL} +}; + +static void save_prop(pcb_board_t *pcb, FILE *f, const char *name, const char *key, const char *val) +{ + if ((strlen(name) + strlen(key) + strlen(val)*2 + 32) >= 512) { + pcb_io_incompat_save(pcb->Data, NULL, "stackup", "Property value string too long", val); + return; + } + fprintf(f, " lprop %s material %s ", name, key); + tedax_fprint_escape(f, val); + fputc('\n', f); +} + + +static void save_user_props(pcb_board_t *pcb, FILE *f, pcb_layergrp_t *grp, const char *name) +{ + int n; + pcb_attribute_t *a; + char *mat = NULL, *thermk = NULL, *thick = NULL, *fab_color = NULL, *dielect = NULL; + + for(n = 0, a = grp->Attributes.List; n < grp->Attributes.Number; n++,a++) { + char *key = a->name, *val = a->value; + + if ((strcmp(key, "material") == 0) && (mat == NULL)) + mat = val; + else if (strcmp(key, "tedax::material")== 0) + mat = val; + else if ((strcmp(key, "thermk") == 0) && (thermk == NULL)) + thermk = val; + else if (strcmp(key, "tedax::thermk")== 0) + thermk = val; + else if ((strcmp(key, "fab-color") == 0) && (fab_color == NULL)) + fab_color = val; + else if (strcmp(key, "tedax::fab-color")== 0) + fab_color = val; + else if ((strcmp(key, "thickness") == 0) && (thick == NULL)) + thick = val; + else if (strcmp(key, "tedax::thickness")== 0) + thick = val; + else if ((strcmp(key, "dielect") == 0) && (dielect == NULL)) + dielect = val; + else if (strcmp(key, "tedax::dielect")== 0) + dielect = val; + } + + + if (thermk != NULL) + save_prop(pcb, f, name, "thermk", thermk); + if (fab_color != NULL) { + if (grp->ltype & (PCB_LYT_TOP | PCB_LYT_BOTTOM)) { + save_prop(pcb, f, name, "fab-color", fab_color); + } + else { + char *title = rnd_strdup_printf("Unsupported group fab-color: %s", grp->name); + pcb_io_incompat_save(pcb->Data, NULL, "stackup", title, "Only outer layer groups should have fab-color."); + free(title); + } + } + if (dielect != NULL) { + if (grp->ltype & PCB_LYT_SUBSTRATE) { + save_prop(pcb, f, name, "dielect", dielect); + } + else { + char *title = rnd_strdup_printf("Unsupported group dielect: %s", grp->name); + pcb_io_incompat_save(pcb->Data, NULL, "stackup", title, "Group type should not have dielect constant - only substrate layers should."); + free(title); + } + } + if (mat != NULL) { + if (grp->ltype & PCB_LYT_SUBSTRATE) { + save_prop(pcb, f, name, "material", mat); + } + else { + char *title = rnd_strdup_printf("Unsupported group material: %s", grp->name); + pcb_io_incompat_save(pcb->Data, NULL, "stackup", title, "Group type should not have a material - only substrate layers should."); + free(title); + } + } + + if (thick != NULL) { + if (grp->ltype & (PCB_LYT_SUBSTRATE | PCB_LYT_COPPER)) { + rnd_bool succ; + double th = rnd_get_value(thick, NULL, NULL, &succ); + if (succ) { + char tmp[64]; + rnd_sprintf(tmp, "%mu", (rnd_coord_t)th); + save_prop(pcb, f, name, "thickness", tmp); + } + else { + char *title = rnd_strdup_printf("Invalid thickness value: %s", grp->name); + pcb_io_incompat_save(pcb->Data, NULL, "stackup", title, "Thicnkess value must be a numeric with an unit suffix, e.g. 0.7mm"); + free(title); + } + } + else { + char *title = rnd_strdup_printf("Unsupported group thickness: %s", grp->name); + pcb_io_incompat_save(pcb->Data, NULL, "stackup", title, "Group type should not have a thickness - only substrate and copper layers should."); + free(title); + } + } +} + +static const tedax_layer_t *tedax_layer_lookup_by_type(pcb_board_t *pcb, const pcb_layergrp_t *grp, const char **lloc) +{ + const tedax_layer_t *t; + + for(t = layertab; t->typename != NULL; t++) { + int loc_accept = 0; + if ((grp->ltype & t->type) != t->type) + continue; + if (t->purpose != NULL) + if ((grp->purpose == NULL) || (strcmp(grp->purpose, t->purpose) != 0)) + continue; + + loc_accept |= ((t->loc & TDX_OUTER) && (grp->ltype & (PCB_LYT_TOP | PCB_LYT_BOTTOM))); + loc_accept |= ((t->loc & TDX_INNER) && (grp->ltype & PCB_LYT_INTERN)); + loc_accept |= ((t->loc & TDX_ALL) && (grp->ltype & PCB_LYT_ANYWHERE) == 0); + loc_accept |= ((t->loc & TDX_VIRTUAL) && (grp->ltype & PCB_LYT_VIRTUAL)); + + if (!loc_accept) + continue; + + /* found a match */ + if (!t->force_virtual) { + if (grp->ltype & PCB_LYT_TOP) *lloc = "top"; + else if (grp->ltype & PCB_LYT_INTERN) *lloc = "inner"; + else if (grp->ltype & PCB_LYT_BOTTOM) *lloc = "bottom"; + else if (grp->ltype & PCB_LYT_VIRTUAL) *lloc = "virtual"; + else if ((grp->ltype & PCB_LYT_ANYWHERE) == 0) *lloc = "all"; + else { + char *title = rnd_strdup_printf("Unsupported group loc: %s", grp->name); + pcb_io_incompat_save(pcb->Data, NULL, "stackup", title, "The group is omitted from the output."); + free(title); + continue; + } + } + else + *lloc = "virtual"; + return t; + } + return NULL; +} + +static int tedax_layer_set_by_str(pcb_board_t *pcb, pcb_layergrp_t *grp, const char *lloc, const char *typename) +{ + const tedax_layer_t *t; + + grp->ltype = 0; + if (strcmp(lloc, "top") == 0) grp->ltype |= PCB_LYT_TOP; + else if (strcmp(lloc, "inner") == 0) grp->ltype |= PCB_LYT_INTERN; + else if (strcmp(lloc, "bottom") == 0) grp->ltype |= PCB_LYT_BOTTOM; + else if (strcmp(lloc, "virtual") == 0) grp->ltype |= PCB_LYT_VIRTUAL; + else if (strcmp(lloc, "all") == 0) {} + else + rnd_message(RND_MSG_ERROR, "invalid layer location: %s\n", lloc); + + for(t = layertab; t->typename != NULL; t++) { + if (strcmp(typename, t->typename) == 0) { + grp->ltype |= t->type; + grp->purpose = NULL; + if (t->purpose != NULL) + pcb_layergrp_set_purpose(grp, t->purpose, 0); + return 0; + } + } + + rnd_message(RND_MSG_ERROR, "invalid layer type: %s\n", typename); + return -1; +} + +int tedax_stackup_fsave(tedax_stackup_t *ctx, pcb_board_t *pcb, const char *stackid, FILE *f, pcb_layer_type_t lyt) +{ + int prefix = 0; + rnd_layergrp_id_t gid; + pcb_layergrp_t *grp; + + fprintf(f, "begin stackup v1 "); + tedax_fprint_escape(f, stackid); + fputc('\n', f); + + vtp0_enlarge(&ctx->g2n, pcb->LayerGroups.len+1); + for(gid = 0, grp = pcb->LayerGroups.grp; gid < pcb->LayerGroups.len; gid++,grp++) { + char tname[66], *tn; + const char *lloc; + pcb_layer_t *ly = NULL; + const tedax_layer_t *lt; + + if ((grp->ltype & lyt) == 0) continue; + + lt = tedax_layer_lookup_by_type(pcb, grp, &lloc); + if (lt == NULL) { + char *title = rnd_strdup_printf("Unsupported group: %s", grp->name); + pcb_io_incompat_save(pcb->Data, NULL, "stackup", title, "Layer type/purpose/location is not supported by tEDAx, layer will be omitted from the save."); + free(title); + continue; + } + + gen_layer_name(ctx, tname, grp->name, 0, gid); + if (!ctx->include_grp_id && (htsp_has(&ctx->n2g, tname))) { + prefix++; + gen_layer_name(ctx, tname, grp->name, prefix, gid); + } + + if (grp->len > 1) { + char *title = rnd_strdup_printf("Multilayer group: %s", grp->name); + pcb_io_incompat_save(pcb->Data, NULL, "stackup", title, "All layers are merged into a single layer"); + free(title); + } + + + tn = rnd_strdup(tname); + htsp_set(&ctx->n2g, tn, grp); + vtp0_set(&ctx->g2n, gid, tn); + + fprintf(f, " layer %s %s %s\n", tn, lloc, lt->typename); + + if (grp->len > 0) + ly = pcb_get_layer(PCB->Data, grp->lid[0]); + if (ly != NULL) + fprintf(f, " lprop %s display-color #%02x%02x%02x\n", tn, ly->meta.real.color.r, ly->meta.real.color.g, ly->meta.real.color.b); + save_user_props(pcb, f, grp, tn); + } + + fprintf(f, "end stackup\n"); + return 0; +} + +int tedax_stackup_save(pcb_board_t *pcb, const char *stackid, const char *fn) +{ + int res; + FILE *f; + tedax_stackup_t ctx; + + f = rnd_fopen_askovr(&PCB->hidlib, fn, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_stackup_save(): can't open %s for writing\n", fn); + return -1; + } + tedax_stackup_init(&ctx); + fprintf(f, "tEDAx v1\n"); + res = tedax_stackup_fsave(&ctx, pcb, stackid, f, PCB_LYT_ANYTHING); + fclose(f); + tedax_stackup_uninit(&ctx); + return res; +} + +static pcb_layergrp_t *get_grp_by_name(tedax_stackup_t *ctx, pcb_board_t *pcb, const char *name) +{ + pcb_layergrp_t *grp = htsp_get(&ctx->n2g, name); + + if (grp == NULL) { + char *nn; + + grp = pcb_get_grp_new_raw(pcb, 0); + grp->name = rnd_strdup(name); + nn = rnd_strdup(name); + htsp_set(&ctx->n2g, nn, grp); + vtp0_set(&ctx->g2n, (grp - pcb->LayerGroups.grp), nn); + } + return grp; +} + +int tedax_stackup_parse(tedax_stackup_t *ctx, pcb_board_t *pcb, FILE *f, char *buff, int buff_size, char *argv[], int argv_size) +{ + int argc; + pcb_layers_reset(pcb); + + while((argc = tedax_getline(f, buff, buff_size, argv, argv_size)) >= 0) { + pcb_layergrp_t *grp; + if (strcmp(argv[0], "layer") == 0) { + grp = get_grp_by_name(ctx, pcb, argv[1]); + tedax_layer_set_by_str(pcb, grp, argv[2], argv[3]); + if (!(grp->ltype & PCB_LYT_SUBSTRATE)) + pcb_layer_create(pcb, grp - pcb->LayerGroups.grp, rnd_strdup(argv[1]), 0); + + } + else if (strcmp(argv[0], "lprop") == 0) { + grp = get_grp_by_name(ctx, pcb, argv[1]); + if (strcmp(argv[2], "display-color") == 0) { + if (grp->len > 0) { + pcb_layer_t *ly = pcb_get_layer(pcb->Data, grp->lid[0]); + if (ly != NULL) + rnd_color_load_str(&ly->meta.real.color, argv[3]); + } + } + else + pcb_attribute_put(&grp->Attributes, argv[2], argv[3]); + } + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "stackup") == 0)) + break; + } + return 0; +} + + +int tedax_stackup_fload(tedax_stackup_t *ctx, pcb_board_t *pcb, FILE *f, const char *blk_id, int silent) +{ + char line[520]; + char *argv[16]; + + if (tedax_seek_hdr(f, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + if (tedax_seek_block(f, "stackup", "v1", blk_id, silent, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + return tedax_stackup_parse(ctx, pcb, f, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])); +} + + +int tedax_stackup_load(pcb_board_t *pcb, const char *fn, const char *blk_id, int silent) +{ + int res; + FILE *f; + tedax_stackup_t ctx; + + f = rnd_fopen(&PCB->hidlib, fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_stackup_load(): can't open %s for reading\n", fn); + return -1; + } + tedax_stackup_init(&ctx); + res = tedax_stackup_fload(&ctx, pcb, f, blk_id, silent); + fclose(f); + tedax_stackup_uninit(&ctx); + return res; +} Index: tags/2.3.0/src_plugins/io_tedax/stackup.h =================================================================== --- tags/2.3.0/src_plugins/io_tedax/stackup.h (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/stackup.h (revision 33253) @@ -0,0 +1,19 @@ +#include "board.h" +#include +#include + +typedef struct { + htsp_t n2g; /* tedax name to layer group pointer */ + vtp0_t g2n; /* group ID to tedax layer name */ + unsigned include_grp_id:1; /* whether to include group IDs in the name as prefix */ +} tedax_stackup_t; + + +void tedax_stackup_init(tedax_stackup_t *ctx); +void tedax_stackup_uninit(tedax_stackup_t *ctx); + +int tedax_stackup_save(pcb_board_t *pcb, const char *stackid, const char *fn); +int tedax_stackup_fsave(tedax_stackup_t *ctx, pcb_board_t *pcb, const char *stackid, FILE *f, pcb_layer_type_t lyt); + +int tedax_stackup_load(pcb_board_t *pcb, const char *fn, const char *blk_id, int silent); +int tedax_stackup_fload(tedax_stackup_t *ctx, pcb_board_t *pcb, FILE *f, const char *blk_id, int silent); Index: tags/2.3.0/src_plugins/io_tedax/tboard.c =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tboard.c (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tboard.c (revision 33253) @@ -0,0 +1,559 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tedax IO plugin - stackup import/export + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "../src_plugins/lib_netmap/placement.h" + +#include "board.h" +#include "data.h" +#include "tboard.h" +#include "parse.h" +#include +#include +#include "stackup.h" +#include "footprint.h" +#include "tdrc.h" +#include "tlayer.h" +#include "ht_subc.h" +#include "obj_pstk.h" +#include +#include "plug_io.h" +#include "tnetlist.h" + +#define ps2fpname(fpname, padstack) \ + rnd_snprintf(fpname, sizeof(fpname), "ps_glob_%ld%s", padstack->protoi, (!!padstack->smirror) != (!!padstack->xmirror) ? "m" : "") + +#define subc2fpname(fpname, subc) \ + rnd_snprintf(fpname, sizeof(fpname), "sc_glob_%ld", subc->ID) + +static int tedax_global_pstk_fwrite(pcb_board_t *pcb, FILE *f) +{ + htsp_t seen; + htsp_entry_t *e; + + htsp_init(&seen, strhash, strkeyeq); + + PCB_PADSTACK_LOOP(pcb->Data) { + char fpname[256]; + ps2fpname(fpname, padstack); + if (!htsp_has(&seen, fpname)) { + fprintf(f, "\nbegin footprint v1 %s\n", fpname); + if (padstack->term != NULL) + fprintf(f, " term %s %s - -\n", padstack->term, padstack->term); + tedax_pstk_fsave(padstack, padstack->x, padstack->y, f); + htsp_set(&seen, rnd_strdup(fpname), padstack); + fprintf(f, "end footprint\n"); + } + } + PCB_END_LOOP; + + for(e = htsp_first(&seen); e != NULL; e = htsp_next(&seen, e)) + free(e->key); + htsp_uninit(&seen); + return 0; +} + +static int tedax_global_subc_fwrite(pcb_placement_t *ctx, FILE *f) +{ + htscp_entry_t *e; + + pcb_placement_build(ctx, ctx->pcb->Data); + for(e = htscp_first(&ctx->subcs); e != NULL; e = htscp_next(&ctx->subcs, e)) { + pcb_subc_t *subc = e->value; + char fpname[256]; + int res; + + subc2fpname(fpname, subc); + res = tedax_fp_fsave_subc_(subc, fpname, 1, f); + assert(res == 0); + } + return 0; +} + + +int tedax_board_fsave(pcb_board_t *pcb, FILE *f) +{ + htsi_t urefdes; + htsi_entry_t *re; + rnd_layergrp_id_t gid; + int n; + pcb_attribute_t *a; + tedax_stackup_t ctx; + pcb_placement_t plc; + static const char *stackupid = "board_stackup"; + static const char *netlistid = "board_netlist"; + static const char *drcid = "board_drc"; + + htsi_init(&urefdes, strhash, strkeyeq); + tedax_stackup_init(&ctx); + + fputc('\n', f); + tedax_drc_fsave(pcb, drcid, f); + + fputc('\n', f); + tedax_net_fsave(pcb, netlistid, f); + + fputc('\n', f); + pcb_placement_init(&plc, pcb); + tedax_global_subc_fwrite(&plc, f); + + fputc('\n', f); + if (tedax_stackup_fsave(&ctx, pcb, stackupid, f, PCB_LYT_ANYTHING) != 0) { + rnd_message(RND_MSG_ERROR, "internal error: failed to save the stackup\n"); + goto error; + } + + for(gid = 0; gid < ctx.g2n.used; gid++) { + char *name = ctx.g2n.array[gid]; + if (name != NULL) { + fputc('\n', f); + tedax_layer_fsave(pcb, gid, name, f, NULL); + } + } + + fputc('\n', f); + if (tedax_global_pstk_fwrite(pcb, f) != 0) + goto error; + + fprintf(f, "\nbegin board v1 "); + tedax_fprint_escape(f, pcb->hidlib.name); + fputc('\n', f); + rnd_fprintf(f, " drawing_area 0 0 %.06mm %.06mm\n", pcb->hidlib.size_x, pcb->hidlib.size_y); + for(n = 0, a = pcb->Attributes.List; n < pcb->Attributes.Number; n++,a++) { + rnd_fprintf(f, " attr "); + tedax_fprint_escape(f, a->name); + fputc(' ', f); + tedax_fprint_escape(f, a->value); + fputc('\n', f); + } + rnd_fprintf(f, " stackup %s\n", stackupid); + rnd_fprintf(f, " netlist %s\n", netlistid); + rnd_fprintf(f, " drc %s\n", drcid); + + PCB_PADSTACK_LOOP(pcb->Data) { + char fpname[256]; + ps2fpname(fpname, padstack); + rnd_fprintf(f, " place %ld %s %.06mm %.06mm %f %d via\n", padstack->ID, fpname, padstack->x, padstack->y, padstack->rot, !!padstack->smirror); + } + PCB_END_LOOP; + + PCB_SUBC_LOOP(pcb->Data) { + pcb_attribute_t *a; + pcb_host_trans_t tr; + char fpname[256], refdes[256]; + pcb_subc_t *proto = htscp_get(&plc.subcs, subc); + int n; + + if (subc->refdes != NULL) { + if (tedax_strncpy_escape(refdes, sizeof(refdes), subc->refdes) != 0) { + pcb_io_incompat_save(pcb->Data, (pcb_any_obj_t *)subc, "subc-refdes", "too long", "subc refdes too long, using an auto-generated one instead"); + goto fake_refdes; + } + if (htsi_has(&urefdes, refdes)) { + pcb_io_incompat_save(pcb->Data, (pcb_any_obj_t *)subc, "subc-refdes", "duplucate", "duplicate subc refdes; using an auto-generated one instead - netlist is most probably broken"); + goto fake_refdes; + } + } + else { + fake_refdes:; + sprintf(refdes, "ANON%ld", subc->ID); + } + htsi_insert(&urefdes, rnd_strdup(refdes), 1); + + subc2fpname(fpname, proto); + pcb_subc_get_host_trans(subc, &tr, 0); + rnd_fprintf(f, " place %s %s %.06mm %.06mm %f %d comp\n", refdes, fpname, tr.ox, tr.oy, tr.rot, tr.on_bottom); + + /* placement text */ + PCB_TEXT_ALL_LOOP(subc->data) { + if (PCB_FLAG_TEST(PCB_FLAG_FLOATER, text)) { + pcb_layer_t *rl = pcb_layer_get_real(layer); /* it is slower to resolve the layer here than in an outer per-layer-loop, but we expect only a few floater text objects, code simplicity is more important */ + if (rl != NULL) { + const char **lyname = (const char **)vtp0_get(&ctx.g2n, rl->meta.real.grp, 0); + if (lyname != NULL) { + gds_t tmp; + int scale; + if (pcb_text_old_scale(text, &scale) != 0) + pcb_io_incompat_save(subc->data, (pcb_any_obj_t *)text, "text-scale", "file format does not support different x and y direction text scale - using average scale", "Use the scale field, set scale_x and scale_y to 0"); + if (text->mirror_x) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-mirror-x", "file format does not support different mirroring text in the x direction", "do not mirror, or mirror in the y direction (with the ONSOLDER flag)"); + rnd_fprintf(f, " place_text %s %s %.06mm %.06mm %.06mm %.06mm %d %f ", + refdes, *lyname, text->bbox_naked.X1, text->bbox_naked.Y1, text->bbox_naked.X2, text->bbox_naked.Y2, + scale, text->rot); + gds_init(&tmp); + pcb_append_dyntext(&tmp, (pcb_any_obj_t *)text, text->TextString); + tedax_fprint_escape(f, tmp.array); + gds_uninit(&tmp); + fputc('\n', f); + } + } + } + } + PCB_ENDALL_LOOP; + + /* placement attributes */ + for(n = 0, a = subc->Attributes.List; n < subc->Attributes.Number; n++,a++) { + if ((strcmp(a->name, "footprint") == 0) || (strcmp(a->name, "value") == 0)) { + rnd_fprintf(f, " place_fattr %s %s ", refdes, a->name); + tedax_fprint_escape(f, a->value); + fputc('\n', f); + } + else { + rnd_fprintf(f, " place_attr %s ", refdes); + tedax_fprint_escape(f, a->name); + fputc(' ', f); + tedax_fprint_escape(f, a->value); + fputc('\n', f); + } + } + } + PCB_END_LOOP; + + fprintf(f, "end board\n"); + for(re = htsi_first(&urefdes); re != NULL; re = htsi_next(&urefdes, re)) free(re->key); + htsi_uninit(&urefdes); + tedax_stackup_uninit(&ctx); + pcb_placement_uninit(&plc); + return 0; + + error: + for(re = htsi_first(&urefdes); re != NULL; re = htsi_next(&urefdes, re)) free(re->key); + htsi_uninit(&urefdes); + tedax_stackup_uninit(&ctx); + pcb_placement_uninit(&plc); + return -1; +} + + +int tedax_board_save(pcb_board_t *pcb, const char *fn) +{ + int res; + FILE *f; + + f = rnd_fopen_askovr(&PCB->hidlib, fn, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_board_save(): can't open %s for writing\n", fn); + return -1; + } + fprintf(f, "tEDAx v1\n"); + res = tedax_board_fsave(pcb, f); + fclose(f); + return res; +} + +#define errexit(msg) \ +do { \ + if (!silent) \ + rnd_message(RND_MSG_ERROR, msg); \ + res = -1; \ + goto error; \ +} while(0) + +#define reqarg(what, reqargc) \ +do { \ + if (argc != reqargc) \ + errexit("tEDAx board load: too few or too many arguments for " #what " reference\n"); \ +} while(0) + +#define remember(what) \ +do { \ + if (what != NULL) \ + errexit("tEDAx board load: multiple instances of " #what " reference\n"); \ + reqarg(what, 2); \ + what = rnd_strdup(argv[1]); \ +} while(0) + +typedef struct tdx_plc_s tdx_plc_t; +typedef struct tdx_attr_s tdx_attr_t; +typedef struct tdx_text_s tdx_text_t; + +struct tdx_attr_s { + char *key; + char *val; + tdx_attr_t *next; +}; + +struct tdx_text_s { + char *layer; + rnd_box_t bbox; + double rot; + char *val; + tdx_text_t *next; +}; + +struct tdx_plc_s { + char *block; + rnd_coord_t ox, oy; + double rot; + char swapside; + char role; /* 'v' for via, 'c' for comp or 'm' for misc */ + tdx_attr_t *attr; + tdx_text_t *text; +}; + +static void free_plc(htsp_t *plc) +{ + htsp_entry_t *e; + tdx_attr_t *a, *an; + tdx_text_t *t, *tn; + + for(e = htsp_first(plc); e != NULL; e = htsp_next(plc, e)) { + tdx_plc_t *p = e->value; + free(e->key); + free(p->block); + for(a = p->attr; a != NULL; a = an) { + an = a->next; + free(a->key); + free(a->val); + free(a); + } + for(t = p->text; t != NULL; t = tn) { + tn = t->next; + free(t->layer); + free(t->val); + free(t); + } + } +} + +static tdx_plc_t *get_place(htsp_t *plc, const char *id) +{ + tdx_plc_t *p = htsp_get(plc, id); + if (p != NULL) + return p; + p = calloc(sizeof(tdx_plc_t), 1); + htsp_set(plc, rnd_strdup(id), p); + return p; +} + +static int tedax_board_parse(pcb_board_t *pcb, FILE *f, char *buff, int buff_size, char *argv[], int argv_size, int silent) +{ + char *stackup = NULL, *netlist = NULL, *drc = NULL; + int res = 0, argc; + tedax_stackup_t ctx; + tdx_plc_t *p; + htsp_t plc; + rnd_bool succ; + pcb_data_t *scdata = NULL; + + htsp_init(&plc, strhash, strkeyeq); + tedax_stackup_init(&ctx); + while((argc = tedax_getline(f, buff, buff_size, argv, argv_size)) >= 0) { + if (strcmp(argv[0], "drawing_area") == 0) { + rnd_coord_t x1, y1, x2, y2; + + reqarg("drawing_area", 5); + x1 = rnd_get_value(argv[1], "mm", NULL, &succ); + if (!succ) errexit("Invalid x1 coord in drawing_area\n"); + y1 = rnd_get_value(argv[2], "mm", NULL, &succ); + if (!succ) errexit("Invalid y1 coord in drawing_area\n"); + x2 = rnd_get_value(argv[3], "mm", NULL, &succ); + if (!succ) errexit("Invalid x2 coord in drawing_area\n"); + y2 = rnd_get_value(argv[4], "mm", NULL, &succ); + if (!succ) errexit("Invalid y2 coord in drawing_area\n"); + if ((x1 >= x2) || (y1 >= y2)) errexit("Invalid (unordered, negative box) drawing area\n"); + if ((x1 < 0) || (y1 < 0)) rnd_message(RND_MSG_WARNING, "drawing_area starts at negative coords; some objects may not display;\nyou may want to run autocrop()\n"); + PCB->hidlib.size_x = x2 - x1; + PCB->hidlib.size_y = y2 - y1; + } + else if (strcmp(argv[0], "attr") == 0) { + reqarg("attr", 3); + pcb_attribute_put(&PCB->Attributes, argv[1], argv[2]); + } + else if (strcmp(argv[0], "stackup") == 0) { + remember(stackup); + } + else if (strcmp(argv[0], "netlist") == 0) { + remember(netlist); + } + else if (strcmp(argv[0], "drc") == 0) { + remember(drc); + } + else if (strcmp(argv[0], "place") == 0) { + rnd_coord_t ox, oy; + double rot; + char *end; + char swapside, role; + + reqarg("place", 8); + + ox = rnd_get_value(argv[3], "mm", NULL, &succ); + if (!succ) errexit("Invalid ox coord in place\n"); + oy = rnd_get_value(argv[4], "mm", NULL, &succ); + if (!succ) errexit("Invalid ox coord in place\n"); + rot = strtod(argv[5], &end); + if (*end != '\0') errexit("Invalid rotation value in place\n"); + swapside = atoi(argv[6]); + if ((swapside < 0) || (swapside > 1)) errexit("Invalid swap side value in place\n"); + if (strcmp(argv[7], "via") == 0) role = 'v'; + else if (strcmp(argv[7], "comp") == 0) role = 'c'; + else if (strcmp(argv[7], "misc") == 0) role = 'm'; + else errexit("Invalid role value in place\n"); + + p = get_place(&plc, argv[1]); + p->block = rnd_strdup(argv[2]); + p->ox = ox; + p->oy = oy; + p->rot = rot; + p->swapside = swapside; + p->role = role; + } + else if ((strcmp(argv[0], "place_attr") == 0) || (strcmp(argv[0], "place_fattr") == 0)) { + tdx_attr_t *a; + reqarg(argv[0], 4); + p = get_place(&plc, argv[1]); + a = malloc(sizeof(tdx_attr_t)); + a->key = rnd_strdup(argv[2]); + a->val = rnd_strdup(argv[3]); + a->next = p->attr; + p->attr = a; + } + else if (strcmp(argv[0], "place_text") == 0) { + rnd_coord_t x1, y1, x2, y2; + tdx_text_t *t; + char *end; + double rot; + + reqarg("place_text", 10); + + x1 = rnd_get_value(argv[3], "mm", NULL, &succ); + if (!succ) errexit("Invalid x1 coord in place_text\n"); + y1 = rnd_get_value(argv[4], "mm", NULL, &succ); + if (!succ) errexit("Invalid y1 coord in place_text\n"); + x2 = rnd_get_value(argv[5], "mm", NULL, &succ); + if (!succ) errexit("Invalid x2 coord in place_text\n"); + y2 = rnd_get_value(argv[6], "mm", NULL, &succ); + if (!succ) errexit("Invalid y2 coord in place_text\n"); + rot = strtod(argv[8], &end); + if (*end != '\0') errexit("Invalid rotation value in place_text\n"); + + p = get_place(&plc, argv[1]); + t = malloc(sizeof(tdx_text_t)); + t->layer = rnd_strdup(argv[2]); + t->val = rnd_strdup(argv[9]); + t->bbox.X1 = x1; + t->bbox.Y1 = y1; + t->bbox.X2 = x2; + t->bbox.Y2 = y2; + t->rot = rot; + t->next = p->text; + p->text = t; + } + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "board") == 0)) + break; + else + errexit("Invalid command in board\n"); + } + + if (stackup != NULL) { + rewind(f); + res |= tedax_stackup_fload(&ctx, pcb, f, stackup, silent); + } + + if (netlist != NULL) { + rewind(f); + res |= tedax_net_fload(f, 0, netlist, silent); + } + + if (drc != NULL) { + rewind(f); + res |= tedax_drc_fload(pcb, f, drc, silent); + } + + /* if there's placement, read all footprint data in cache */ + if (plc.used > 0) { + scdata = pcb_data_new(pcb); + rewind(f); + tedax_seek_hdr(f, buff, buff_size, argv, argv_size); + for(;;) { + pcb_subc_t *sc; + + if (tedax_seek_block(f, "footprint", "v1", NULL, silent, buff, buff_size, argv, argv_size) < 0) + break; + + sc = tedax_parse_1fp(scdata, f, buff, buff_size, argv, argv_size); + if (sc == NULL) + errexit("Failed to parse footprint\n"); + } + } + + { /* placement */ + htsp_entry_t *e; + for(e = htsp_first(&plc); e != NULL; e = htsp_next(&plc, e)) { +rnd_trace("placing '%s'\n", e->key); + } + } + + error:; + free(stackup); + free(netlist); + free(drc); + tedax_stackup_uninit(&ctx); + free_plc(&plc); + htsp_uninit(&plc); + if (scdata != NULL) + pcb_data_free(scdata); + return res; +} + + +int tedax_board_fload(pcb_board_t *pcb, FILE *f, const char *blk_id, int silent) +{ + char line[520]; + char *argv[16]; + + if (tedax_seek_hdr(f, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + if (tedax_seek_block(f, "board", "v1", blk_id, silent, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + return tedax_board_parse(pcb, f, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]), silent); +} + + +int tedax_board_load(pcb_board_t *pcb, const char *fn, const char *blk_id, int silent) +{ + int res; + FILE *f; + + f = rnd_fopen(&PCB->hidlib, fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_board_load(): can't open %s for reading\n", fn); + return -1; + } + res = tedax_board_fload(pcb, f, blk_id, silent); + fclose(f); + return res; +} Index: tags/2.3.0/src_plugins/io_tedax/tboard.h =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tboard.h (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tboard.h (revision 33253) @@ -0,0 +1,7 @@ +#include "board.h" + +int tedax_board_save(pcb_board_t *pcb, const char *fn); +int tedax_board_fsave(pcb_board_t *pcb, FILE *f); + +int tedax_board_load(pcb_board_t *pcb, const char *fn, const char *blk_id, int silent); +int tedax_board_fload(pcb_board_t *pcb, FILE *f, const char *blk_id, int silent); Index: tags/2.3.0/src_plugins/io_tedax/tdrc.c =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tdrc.c (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tdrc.c (revision 33253) @@ -0,0 +1,363 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tedax IO plugin - generic DRC import/export + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* This file is for the generic tEDAx DRC block ("begin drc...", as documented + in the tEDAx project) */ + +#include "config.h" + +#include + +#include "board.h" +#include "parse.h" +#include +#include +#include +#include +#include "tdrc.h" +#include "tdrc_query.h" +#include "tdrc_keys_sphash.h" + + +#define SOURCE "tedax_drc" + +/* Old, hardwired or stock rules - so there's no interference with user + settings */ +typedef struct { + const char *oconf; /* full path in the conf - old drc for compatibility */ + const char *nconf; /* full path in the conf - new drc (drc_query) */ + const char *ttype; /* tEDAx layer type */ + const char *tkind; /* tEDAx layer kind */ +} drc_rule_t; + +#define QDRC "plugins/drc_query/definitions/" + +static const drc_rule_t stock_rules[] = { + {"design/bloat", QDRC "min_copper_clearance", "copper", "gap"}, + {"design/shrink", QDRC "min_copper_overlap", "copper", "overlap"}, + {"design/min_wid", QDRC "min_copper_thickness", "copper", "min_size"}, + {"design/min_slk", QDRC "min_silk_thickness", "silk", "min_size"}, + {"design/min_drill", QDRC "min_drill", "mech", "min_size"}, +}; + +#define NUM_STOCK_RULES (sizeof(stock_rules) / sizeof(stock_rules[0])) + +int tedax_drc_fsave(pcb_board_t *pcb, const char *drcid, FILE *f) +{ + const drc_rule_t *r; + rnd_conf_native_t *nat, *val; + int n; + + fprintf(f, "begin drc v1 "); + tedax_fprint_escape(f, drcid); + fputc('\n', f); + + for(n = 0, r = stock_rules; n < NUM_STOCK_RULES; r++,n++) { + rnd_conf_native_t *nat; + nat = rnd_conf_get_field(r->nconf); + if ((nat == NULL) || (nat->prop->src == NULL)) + nat = rnd_conf_get_field(r->oconf); + if ((nat != NULL) && (nat->prop->src != NULL)) + rnd_fprintf(f, " rule all %s %s %.06mm pcb_rnd_old_drc_from_conf\n", r->ttype, r->tkind, nat->val.coord[0]); + } + + nat = rnd_conf_get_field("plugins/drc_query/definitions"); + if (nat != NULL) { + gdl_iterator_t it; + rnd_conf_listitem_t *i; + rnd_conflist_foreach(nat->val.list, &it, i) { + lht_node_t *def = i->prop.src; + char *tmp, *s, *start, *cfgpath; + int token[4], n = 0, stay = 1; + + if (strncmp(def->name, "tedax_", 6) != 0) continue; + + tmp = rnd_strdup(def->name+6); + for(start = s = tmp; stay; s++) { + if ((*s == '_') || (*s == '\0')) { + if (*s == '\0') stay = 0; + if (n < sizeof(token)/sizeof(token[0])) { + *s = '\0'; + token[n++] = io_tedax_tdrc_keys_sphash(start); + } + if (stay) + *s = ' '; + start = s+1; + } + } + + if (!io_tedax_tdrc_keys_loc_isvalid(token[0])) { + rnd_message(RND_MSG_ERROR, "invalid layer location for tEDAx DRC rule from drc_query '%s'\n", def->name); + goto skip; + } + if ((token[0] != io_tedax_tdrc_keys_loc_named) && (!io_tedax_tdrc_keys_type_isvalid(token[1]))) { + rnd_message(RND_MSG_ERROR, "invalid layer type for tEDAx DRC rule from drc_query '%s'\n", def->name); + goto skip; + } + if (!io_tedax_tdrc_keys_op_isvalid(token[2])) { + rnd_message(RND_MSG_ERROR, "invalid op for tEDAx DRC rule from drc_query '%s'\n", def->name); + goto skip; + } + + cfgpath = rnd_concat("design/drc/", def->name, NULL); + val = rnd_conf_get_field(cfgpath); + if (val == NULL) + rnd_message(RND_MSG_ERROR, "tEDAx DRC rule: no configured value for '%s'\n", def->name); + else if (val->type != RND_CFN_COORD) + rnd_message(RND_MSG_ERROR, "tEDAx DRC rule: configured value for '%s' is not a coord\n", def->name); + else + rnd_fprintf(f, " rule %s %.08mm pcb_rnd_io_tedax_tdrc\n", tmp, val->val.coord[0]); + + free(cfgpath); + + skip:; + free(tmp); + } + } + + fprintf(f, "end drc\n"); + return 0; +} + +int tedax_drc_save(pcb_board_t *pcb, const char *drcid, const char *fn) +{ + int res; + FILE *f; + + f = rnd_fopen_askovr(&PCB->hidlib, fn, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_drc_save(): can't open %s for writing\n", fn); + return -1; + } + fprintf(f, "tEDAx v1\n"); + res = tedax_drc_fsave(pcb, drcid, f); + fclose(f); + return res; +} + +static int load_stock_rule(char *argv[], double d, rnd_coord_t *val) +{ + const drc_rule_t *r; + int n; + + for(n = 0, r = stock_rules; n < NUM_STOCK_RULES; r++,n++) { + if ((strcmp(argv[2], r->ttype) != 0) || (strcmp(argv[3], r->tkind) != 0)) + continue; + val[n] = d; + return 0; + } + return -1; +} + +static const char *op_title(int op) +{ + switch(op) { + case io_tedax_tdrc_keys_op_min_object_around_cut: return "min. object around cut"; + case io_tedax_tdrc_keys_op_min_dist_from_boundary: return "min. distance from boundary"; + case io_tedax_tdrc_keys_op_overlap: return "min. object overlap"; + case io_tedax_tdrc_keys_op_gap: return "min. object gap"; + case io_tedax_tdrc_keys_op_max_size: return "max. object size"; + case io_tedax_tdrc_keys_op_min_size: return "min. object size"; + } + return NULL; +} + +static char *op_cond(int op, const char **listing, const char *defid) +{ + *listing = ""; + switch(op) { + case io_tedax_tdrc_keys_op_min_object_around_cut: + return NULL; + case io_tedax_tdrc_keys_op_min_dist_from_boundary: + *listing = "let B ((@.layer.type == MECH) || (@.layer.type == BOUNDARY)) thus @\n"; + return rnd_strdup_printf("(overlap(@, B, $%s)) thus violation(DRCGRP1, @, DRCGRP2, B, DRCEXPECT, $%s)", defid, defid); + case io_tedax_tdrc_keys_op_overlap: + *listing = "let B @\n"; + return rnd_strdup_printf("(@.IID < B.IID) && intersect(@, B) && (@.netname == B.netname) && (!intersect(@, B, -1 * $%s)) thus violation(DRCGRP1, @, DRCGRP2, B, DRCEXPECT, $%s)", defid, defid); + case io_tedax_tdrc_keys_op_gap: + *listing = "let B @\n"; + return rnd_strdup_printf("(@.IID < B.IID) && (@.netname != B.netname) && intersect(@, B, $%s) thus violation(DRCGRP1, @, DRCGRP2, B, DRCEXPECT, $%s)", defid, defid); + case io_tedax_tdrc_keys_op_max_size: + return rnd_strdup_printf("(@.thickness > $%s)", defid); + case io_tedax_tdrc_keys_op_min_size: + return rnd_strdup_printf("(@.thickness != 0) && (@.thickness < $%s)", defid); + } + return NULL; +} + +static const char *type_cond(int type) +{ + switch(type) { + case io_tedax_tdrc_keys_type_all: return ""; + case io_tedax_tdrc_keys_type_mech: return "(@.layer.type == MECH) && "; + case io_tedax_tdrc_keys_type_vcut: return "((@.layer.type == MECH) || (@.layer.type == BOUNDARY)) && (@.layer.purpoe == \"vcut\") && "; + case io_tedax_tdrc_keys_type_umech: return "((@.layer.type == MECH) || (@.layer.type == BOUNDARY)) && (@.layer.purpoe ~ \"^u\") && "; + case io_tedax_tdrc_keys_type_pmech: return "((@.layer.type == MECH) || (@.layer.type == BOUNDARY)) && (@.layer.purpoe ~ \"^p\") && "; + case io_tedax_tdrc_keys_type_paste: return "(@.layer.type == PASTE) && "; + case io_tedax_tdrc_keys_type_mask: return "(@.layer.type == MASK) && "; + case io_tedax_tdrc_keys_type_silk: return "(@.layer.type == SILK) && "; + case io_tedax_tdrc_keys_type_copper: return "(@.layer.type == COPPER) && "; + } + return NULL; +} + +static const char *loc_cond(int loc) +{ + switch(loc) { + case io_tedax_tdrc_keys_loc_all: return ""; + case io_tedax_tdrc_keys_loc_outer: return "((@.layer.position == TOP) || (@.layer.position == BOTTOM)) && "; + case io_tedax_tdrc_keys_loc_inner: return "(@.layer.position == INTERN) && "; + case io_tedax_tdrc_keys_loc_bottom: return "(@.layer.position == BOTTOM) && "; + case io_tedax_tdrc_keys_loc_top: return "(@.layer.position == TOP) && "; + } + return NULL; +} + +static void reg_def_rule(pcb_board_t *pcb, const char *id, const char *title, const char *type, const char *query, const char *val_) +{ + char val[128]; + + rnd_snprintf(val, sizeof(val), "%smm", val_); + + rnd_actionva(&pcb->hidlib, RULEMOD, "create", id, NULL); + rnd_actionva(&pcb->hidlib, RULEMOD, "set", id, "title", title, NULL); + rnd_actionva(&pcb->hidlib, RULEMOD, "set", id, "type", type, NULL); + rnd_actionva(&pcb->hidlib, RULEMOD, "set", id, "query", query, NULL); + + rnd_actionva(&pcb->hidlib, DEFMOD, "create", id, NULL); + rnd_actionva(&pcb->hidlib, DEFMOD, "set", id, "title", title, NULL); + rnd_actionva(&pcb->hidlib, DEFMOD, "set", id, "type", "coord", NULL); + rnd_actionva(&pcb->hidlib, DEFMOD, "set", id, "default", val, NULL); +} + +static void load_drc_query_rule(pcb_board_t *pcb, char *argv[], int loc) +{ + int op = io_tedax_tdrc_keys_sphash(argv[3]); + const char *title = op_title(op), *clisting; + char *sop, *defid, *stype = NULL, *query = NULL; + + if (title == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_drc_load(): invalid rule op: '%s'\n", argv[3]); + return; + } + defid = rnd_concat("tedax_", argv[1], "_", argv[2], "_", argv[3], NULL); + sop = op_cond(op, &clisting, defid); + if (sop == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_drc_load(): can not apply op: '%s'\n", argv[3]); + free(defid); + return; + } + + if (loc != io_tedax_tdrc_keys_loc_named) { + int type = io_tedax_tdrc_keys_sphash(argv[2]); + const char *ctype = type_cond(type); + const char *cloc = loc_cond(loc); + + if (ctype == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_drc_load(): invalid layer type: '%s'\n", argv[2]); + return; + } + + if (cloc == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_drc_load(): invalid location: '%s'\n", argv[1]); + return; + } + + stype = rnd_concat(argv[1], " ", argv[2], " ", argv[3], NULL); + query = rnd_concat("rule tedax\n", clisting, "assert ", ctype, cloc, sop, "\n", NULL); + reg_def_rule(pcb, defid, title, stype, query, argv[4]); + } + else { + stype = rnd_concat("name ", argv[2], " ", argv[3], NULL); + query = rnd_strdup_printf("rule tedax\n%sassert (@.layer.name == \"%s\") && %s\n", clisting, argv[2], sop); + reg_def_rule(pcb, defid, title, stype, query, argv[4]); + } + free(sop); + free(query); + free(stype); + free(defid); +} + +int tedax_drc_fload(pcb_board_t *pcb, FILE *f, const char *blk_id, int silent) +{ + const drc_rule_t *r; + char line[520], *argv[16]; + int argc, n; + rnd_coord_t val[NUM_STOCK_RULES] = {0}; + + if (tedax_seek_hdr(f, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + if ((argc = tedax_seek_block(f, "drc", "v1", blk_id, silent, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]))) < 1) + return -1; + + tedax_drc_query_rule_clear(pcb, SOURCE); + + while((argc = tedax_getline(f, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]))) >= 0) { + if ((strcmp(argv[0], "rule") == 0) && (argc > 4)) { + rnd_bool succ; + double d = rnd_get_value(argv[4], "mm", NULL, &succ); + if (succ) { + int loc = io_tedax_tdrc_keys_sphash(argv[1]); + if ((loc != io_tedax_tdrc_keys_loc_all) || (load_stock_rule(argv, d, val) != 0)) + load_drc_query_rule(pcb, argv, loc); + } + else + rnd_message(RND_MSG_ERROR, "ignoring invalid numeric value '%s'\n", argv[4]);; + } + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "drc") == 0)) + break; + else + rnd_message(RND_MSG_ERROR, "ignoring invalid command in drc %s\n", argv[0]); + } + + for(n = 0, r = stock_rules; n < NUM_STOCK_RULES; r++,n++) { + if (val[n] > 0) { + rnd_conf_setf(RND_CFR_DESIGN, r->oconf, -1, "%$mm", val[n]); + rnd_conf_setf(RND_CFR_DESIGN, r->nconf, -1, "%$mm", val[n]); + } + } + return 0; +} + +int tedax_drc_load(pcb_board_t *pcb, const char *fn, const char *blk_id, int silent) +{ + int res; + FILE *f; + + f = rnd_fopen(&PCB->hidlib, fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_drc_load(): can't open %s for reading\n", fn); + return -1; + } + res = tedax_drc_fload(pcb, f, blk_id, silent); + fclose(f); + return res; +} + + Index: tags/2.3.0/src_plugins/io_tedax/tdrc.h =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tdrc.h (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tdrc.h (revision 33253) @@ -0,0 +1,7 @@ +#include "board.h" + +int tedax_drc_save(pcb_board_t *pcb, const char *drcid, const char *fn); +int tedax_drc_fsave(pcb_board_t *pcb, const char *drcid, FILE *f); + +int tedax_drc_load(pcb_board_t *pcb, const char *fn, const char *blk_id, int silent); +int tedax_drc_fload(pcb_board_t *pcb, FILE *f, const char *blk_id, int silent); Index: tags/2.3.0/src_plugins/io_tedax/tdrc_keys.sphash =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tdrc_keys.sphash (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tdrc_keys.sphash (revision 33253) @@ -0,0 +1,24 @@ +loc + top + bottom + outer + inner + all + named +type + copper + silk + mask + paste + pmech + umech + vcut + mech + all +op + min_size + max_size + gap + overlap + min_dist_from_boundary + min_object_around_cut Index: tags/2.3.0/src_plugins/io_tedax/tdrc_query.c =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tdrc_query.c (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tdrc_query.c (revision 33253) @@ -0,0 +1,298 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tedax IO plugin - load DRC rules and constants for drc_query + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* This file is for the drc_query specific tEDAx block ("begin drc_query_* ...", + as documented in the pcb-rnd project) */ + +#include "config.h" + +#include + +#include "board.h" +#include "parse.h" +#include +#include +#include +#include +#include "tdrc_query.h" + +void tedax_drc_query_rule_clear(pcb_board_t *pcb, const char *target_src) +{ + rnd_actionva(&pcb->hidlib, RULEMOD, "clear", target_src, NULL); + rnd_actionva(&pcb->hidlib, DEFMOD, "clear", target_src, NULL); +} + +int tedax_drc_query_rule_parse(pcb_board_t *pcb, FILE *f, const char *src, char *rule_name) +{ + int argc; + char line[520], *argv[4]; + gds_t qry; + + gds_init(&qry); + rnd_actionva(&pcb->hidlib, RULEMOD, "create", rule_name, NULL); + + while((argc = tedax_getline(f, line, sizeof(line), argv, 2)) >= 0) { + if ((strcmp(argv[0], "type") == 0) || (strcmp(argv[0], "title") == 0) || (strcmp(argv[0], "desc") == 0)) { + rnd_actionva(&pcb->hidlib, RULEMOD, "set", rule_name, argv[0], argv[1], NULL); + } + else if (strcmp(argv[0], "query") == 0) { + gds_append_str(&qry, argv[1]); + gds_append(&qry, '\n'); + } + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "drc_query_rule") == 0)) + break; + else + rnd_message(RND_MSG_ERROR, "ignoring invalid command in drc_query_rule %s\n", argv[0]); + } + + + if (qry.used > 0) { + rnd_actionva(&pcb->hidlib, RULEMOD, "set", rule_name, "query", qry.array, NULL); + gds_uninit(&qry); + } + + if (src != NULL) + rnd_actionva(&pcb->hidlib, RULEMOD, "set", rule_name, "source", src, NULL); + + return 0; +} + +int tedax_drc_query_def_parse(pcb_board_t *pcb, FILE *f, const char *src, char *rule_name) +{ + int argc; + char line[520], *argv[4]; + + rnd_actionva(&pcb->hidlib, DEFMOD, "create", rule_name, NULL); + + while((argc = tedax_getline(f, line, sizeof(line), argv, 2)) >= 0) { + if ((strcmp(argv[0], "type") == 0) || (strcmp(argv[0], "desc") == 0) || (strcmp(argv[0], "default") == 0)) { + rnd_actionva(&pcb->hidlib, DEFMOD, "set", rule_name, argv[0], argv[1], NULL); + } + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "drc_query_def") == 0)) + break; + else + rnd_message(RND_MSG_ERROR, "ignoring invalid command in drc_query_def %s\n", argv[0]); + } + + if (src != NULL) + rnd_actionva(&pcb->hidlib, DEFMOD, "set", rule_name, "source", src, NULL); + + return 0; +} + +int tedax_drc_query_fload(pcb_board_t *pcb, FILE *f, const char *blk_id, const char *src, int silent) +{ + char line[520], *argv[16]; + int argc; + long cnt = 0; + + if (tedax_seek_hdr(f, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + while((argc = tedax_getline(f, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]))) >= 0) { + if ((argc < 2) || (strcmp(argv[0], "begin") != 0)) + continue; + if (strcmp(argv[1], "drc_query_rule") == 0) { + if (strcmp(argv[2], "v1") != 0) { + if (!silent) + rnd_message(RND_MSG_ERROR, "Wrong drc_query_rule version: %s\n", argv[2]); + continue; + } + if ((blk_id != NULL) && (strcmp(argv[3], blk_id) != 0)) + continue; + if (tedax_drc_query_rule_parse(pcb, f, src, argv[3]) < 0) + return -1; + cnt++; + } + if (strcmp(argv[1], "drc_query_def") == 0) { + if (strcmp(argv[2], "v1") != 0) { + if (!silent) + rnd_message(RND_MSG_ERROR, "Wrong drc_query_def version: %s\n", argv[2]); + continue; + } + if ((blk_id != NULL) && (strcmp(argv[3], blk_id) != 0)) + continue; + if (tedax_drc_query_def_parse(pcb, f, src, argv[3]) < 0) + return -1; + } + } + return (cnt == 0) ? -1 : 0; +} + +int tedax_drc_query_load(pcb_board_t *pcb, const char *fn, const char *blk_id, const char *src, int silent) +{ + int res; + FILE *f; + + f = rnd_fopen(&PCB->hidlib, fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_drc_query_load(): can't open %s for reading\n", fn); + return -1; + } + res = tedax_drc_query_fload(pcb, f, blk_id, src, silent); + fclose(f); + return res; +} + +static const char *drc_query_any_get(const char *act, const char *ruleid, const char *field, int *err) +{ + fgw_error_t ferr; + fgw_arg_t res, args[4]; + + args[0].type = FGW_VOID; + args[1].type = FGW_STR; args[1].val.cstr = "get"; + args[2].type = FGW_STR; args[2].val.cstr = ruleid; + args[3].type = FGW_STR; args[3].val.cstr = field; + + ferr = rnd_actionv_bin(&PCB->hidlib, act, &res, 4, args); + if (ferr != 0) { + *err = 1; + return "-"; + } + if (res.type != FGW_STR) { + fgw_arg_free(&rnd_fgw, &res); + *err = 1; + return "-"; + } + return res.val.cstr; +} + +static const char *drc_query_rule_get(const char *ruleid, const char *field, int *err) +{ + return drc_query_any_get("DrcQueryRuleMod", ruleid, field, err); +} + +static const char *drc_query_def_get(const char *ruleid, const char *field, int *err) +{ + return drc_query_any_get("DrcQueryDefMod", ruleid, field, err); +} + +static void print_multiline(FILE *f, const char *prefix, const char *text) +{ + const char *curr, *next; + while(isspace(*text)) text++; + for(curr = text; curr != NULL; curr = next) { + next = strchr(curr, '\n'); + if (next != NULL) { + fprintf(f, "%s ", prefix); + fwrite(curr, next-curr, 1, f); + fputc('\n', f); + while(*next == '\n') next++; + if (*next == '\0') next = NULL; + } + } +} + +int tedax_drc_query_def_fsave(pcb_board_t *pcb, const char *defid, FILE *f) +{ + int err = 0; + + fprintf(f, "\nbegin drc_query_def v1 "); + tedax_fprint_escape(f, defid); + fputc('\n', f); + + fprintf(f, " type %s\n", drc_query_def_get(defid, "type", &err)); + fprintf(f, " default %s\n", drc_query_def_get(defid, "default", &err)); + fprintf(f, " desc %s\n", drc_query_def_get(defid, "desc", &err)); + + fprintf(f, "end drc_query_def\n"); + + return err; +} + + +int tedax_drc_query_rule_fsave(pcb_board_t *pcb, const char *ruleid, FILE *f, rnd_bool save_def) +{ + + int err = 0; + + /* when enabled, get a list of definitions used by the rule and save them all */ + if (save_def) { + fgw_error_t ferr; + fgw_arg_t res, args[4]; + + args[0].type = FGW_VOID; + args[1].type = FGW_STR; args[1].val.cstr = "get"; + args[2].type = FGW_STR; args[2].val.cstr = ruleid; + args[3].type = FGW_STR; args[3].val.cstr = "defs"; + + ferr = rnd_actionv_bin(&PCB->hidlib, "DrcQueryRuleMod", &res, 4, args); + if (ferr == 0) { + if ((res.type & FGW_STR) && (res.val.str != NULL) && (*res.val.str != '\0')) { + char *lst, *curr, *next; + for(curr = lst = rnd_strdup(res.val.str); next != NULL; curr = next) { + next = strchr(curr, '\n'); + if (next != NULL) *next = '\0'; + if (tedax_drc_query_def_fsave(pcb, curr, f) != 0) { + err = -1; + break; + } + } + free(lst); + } + fgw_arg_free(&rnd_fgw, &res); + if (err != 0) + return err; + } + } + + fprintf(f, "\nbegin drc_query_rule v1 "); + tedax_fprint_escape(f, ruleid); + fputc('\n', f); + + fprintf(f, " type %s\n", drc_query_rule_get(ruleid, "type", &err)); + fprintf(f, " title %s\n", drc_query_rule_get(ruleid, "title", &err)); + fprintf(f, " desc %s\n", drc_query_rule_get(ruleid, "desc", &err)); + + print_multiline(f, " query", drc_query_rule_get(ruleid, "query", &err)); + + fprintf(f, "end drc_query_rule\n"); + return err; +} + +int tedax_drc_query_save(pcb_board_t *pcb, const char *ruleid, const char *fn) +{ + int res; + FILE *f; + + if (ruleid == NULL) { +TODO("save all"); +rnd_message(RND_MSG_ERROR, "Can't save all rules yet, please name one rule to save\n"); + return -1; + } + + f = rnd_fopen_askovr(&PCB->hidlib, fn, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_drc_query_save(): can't open %s for writing\n", fn); + return -1; + } + fprintf(f, "tEDAx v1\n"); + res = tedax_drc_query_rule_fsave(pcb, ruleid, f, rnd_true); + fclose(f); + return res; +} Index: tags/2.3.0/src_plugins/io_tedax/tdrc_query.h =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tdrc_query.h (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tdrc_query.h (revision 33253) @@ -0,0 +1,14 @@ +#include "board.h" + +int tedax_drc_query_load(pcb_board_t *pcb, const char *fn, const char *blk_id, const char *src, int silent); +int tedax_drc_query_fload(pcb_board_t *pcb, FILE *f, const char *blk_id, const char *src, int silent); + + +int tedax_drc_query_save(pcb_board_t *pcb, const char *ruleid, const char *fn); +int tedax_drc_query_rule_fsave(pcb_board_t *pcb, const char *ruleid, FILE *f, rnd_bool save_def); + +/* clear all rules and defs with source matching target_src */ +void tedax_drc_query_rule_clear(pcb_board_t *pcb, const char *target_src); + +#define RULEMOD "DrcQueryRuleMod" +#define DEFMOD "DrcQueryDefMod" Index: tags/2.3.0/src_plugins/io_tedax/tedax-menu.lht =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tedax-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tedax-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@import_top { + li:submenu { + ha:Import tEDAx schematics = { action=LoadTedaxFrom(netlist) } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/io_tedax/tetest.c =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tetest.c (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tetest.c (revision 33253) @@ -0,0 +1,268 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tedax IO plugin - electric test export + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include "board.h" +#include "data.h" +#include "parse.h" +#include +#include +#include "tetest.h" +#include +#include "obj_subc_parent.h" +#include "obj_pstk.h" +#include "obj_pstk_inlines.h" +#include "netlist.h" +#include +#include "plug_io.h" +#include +#include "hid_cam.h" +#include +#include +#include + +static const char *sides(pcb_layer_type_t lyt) +{ + if ((lyt & PCB_LYT_TOP) && (lyt & PCB_LYT_BOTTOM)) return "both"; + if (lyt & PCB_LYT_TOP) return "top"; + if (lyt & PCB_LYT_BOTTOM) return "bottom"; + return "-"; +} + +static void tedax_etest_fsave_pstk(FILE *f, pcb_pstk_t *ps, const char *netname, const char *refdes, const char *term) +{ + int n, has_slot = 0; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + pcb_pstk_tshape_t *ts; + pcb_layer_type_t copper = 0, exposed = 0, side; + pcb_pstk_shape_t *shp, *minshp = NULL; + rnd_coord_t shx, shy, dia, mindia; + + if (proto == NULL) + return; + ts = &proto->tr.array[0]; + if (ts == NULL) + return; + + if (netname == NULL) + netname = "-"; + + shp = ts->shape; + for(n = 0; n < ts->len; n++,shp++) { + int accept = 0; + side = (shp->layer_mask & (PCB_LYT_TOP | PCB_LYT_BOTTOM)); + if (shp->layer_mask & PCB_LYT_MECH) + has_slot = 1; + if ((side != 0) && (shp->layer_mask & PCB_LYT_MASK)) { + exposed |= side; + accept = 1; + } + if ((side != 0) && (shp->layer_mask & PCB_LYT_COPPER)) { + copper |= side; + accept = 1; + } + if (accept) { + TODO("calculate dia"); + dia = RND_MM_TO_COORD(0.5); + if ((minshp == NULL) || (dia < mindia)) { + minshp = shp; + shx = 0; shy = 0; + mindia = dia; + } + } + } + + if ((minshp == NULL) || (copper == 0) || has_slot) + return; + + fprintf(f, " pad "); + tedax_fprint_escape(f, netname == NULL ? "-" : netname); + + fprintf(f, " "); + tedax_fprint_escape(f, refdes == NULL ? "-" : refdes); + + fprintf(f, " "); + tedax_fprint_escape(f, term == NULL ? "-" : term); + + rnd_fprintf(f, " %.06mm %.06mm %s round %.06mm %.06mm 0 ", ps->x + shx, ps->y + shy, sides(copper), dia, dia); + if (proto->hdia > 0) + rnd_fprintf(f, "%s %.06mm ", proto->hplated ? "plated" : "unplated", proto->hdia); + else + fprintf(f, "- - "); + + fprintf(f, " %s %s\n", sides(exposed), sides(exposed)); +} + +int tedax_etest_fsave(pcb_board_t *pcb, const char *etestid, FILE *f) +{ + rnd_box_t *b; + rnd_rtree_it_t it; + + fprintf(f, "begin etest v1 "); + tedax_fprint_escape(f, etestid); + fputc('\n', f); + + for(b = rnd_r_first(pcb->Data->padstack_tree, &it); b != NULL; b = rnd_r_next(&it)) { + pcb_pstk_t *ps = (pcb_pstk_t *)b; + pcb_subc_t *sc; + pcb_net_term_t *t; + + assert(ps->type == PCB_OBJ_PSTK); + if (ps->term == NULL) + continue; + sc = pcb_gobj_parent_subc(ps->parent_type, &ps->parent); + if ((sc == NULL) || (sc->refdes == NULL)) + continue; + t = pcb_net_find_by_refdes_term(&pcb->netlist[PCB_NETLIST_EDITED], sc->refdes, ps->term); + if (t == NULL) /* export named nets only, for now */ + continue; + tedax_etest_fsave_pstk(f, ps, t->parent.net->name, sc->refdes, ps->term); + } + + fprintf(f, "end etest\n"); + return 0; +} + +int tedax_etest_save(pcb_board_t *pcb, const char *etestid, const char *fn) +{ + int res; + FILE *f; + + f = rnd_fopen_askovr(&PCB->hidlib, fn, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_etest_save(): can't open %s for writing\n", fn); + return -1; + } + fprintf(f, "tEDAx v1\n"); + res = tedax_etest_fsave(pcb, etestid, f); + fclose(f); + return res; +} + + +/*** export HID ***/ + +static rnd_export_opt_t tedax_etest_options[] = { + {"outfile", "Name of the tedax etest output file", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_outfile 0 + + {"cam", "CAM instruction", + RND_HATT_STRING, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_cam 1 +}; + +#define NUM_OPTIONS (sizeof(tedax_etest_options)/sizeof(tedax_etest_options[0])) + +static rnd_hid_attr_val_t tedax_etest_values[NUM_OPTIONS]; + +static const char *tedax_etest_filename; + +static rnd_export_opt_t *tedax_etest_get_export_options(rnd_hid_t *hid, int *n) +{ + if ((PCB != NULL) && (tedax_etest_options[HA_outfile].default_val.str == NULL)) + pcb_derive_default_filename(PCB->hidlib.filename, &tedax_etest_options[HA_outfile], ".etest.tdx"); + + if (n) + *n = NUM_OPTIONS; + return tedax_etest_options; +} + +static void tedax_etest_do_export(rnd_hid_t *hid, rnd_hid_attr_val_t *options) +{ + int i; + const char *name; + pcb_cam_t cam; + + if (!options) { + tedax_etest_get_export_options(hid, 0); + for (i = 0; i < NUM_OPTIONS; i++) + tedax_etest_values[i] = tedax_etest_options[i].default_val; + options = tedax_etest_values; + } + + tedax_etest_filename = options[HA_outfile].str; + if (!tedax_etest_filename) + tedax_etest_filename = "unknown.etest.tdx"; + + pcb_cam_begin_nolayer(PCB, &cam, NULL, options[HA_cam].str, &tedax_etest_filename); + + + name = PCB->hidlib.name; + if (name == NULL) name = PCB->hidlib.filename; + if (name == NULL) name = "-"; + tedax_etest_save(PCB, name, tedax_etest_filename); + pcb_cam_end(&cam); +} + +static int tedax_etest_usage(rnd_hid_t *hid, const char *topic) +{ + fprintf(stderr, "\ntEDAx etest exporter command line arguments:\n\n"); + rnd_hid_usage(tedax_etest_options, sizeof(tedax_etest_options) / sizeof(tedax_etest_options[0])); + fprintf(stderr, "\nUsage: pcb-rnd [generic_options] -x tedax-etest [tedax_etest_options] foo.pcb\n\n"); + return 0; +} + +static const char *tedax_etest_cookie = "tEDAx etest"; +static int tedax_etest_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv) +{ + rnd_export_register_opts(tedax_etest_options, sizeof(tedax_etest_options) / sizeof(tedax_etest_options[0]), tedax_etest_cookie, 0); + return rnd_hid_parse_command_line(argc, argv); +} + +static rnd_hid_t exp_tedax_etest; + +void tedax_etest_uninit(void) +{ + rnd_export_remove_opts_by_cookie(tedax_etest_cookie); + rnd_hid_remove_hid(&exp_tedax_etest); +} + +void tedax_etest_init(void) +{ + memset(&exp_tedax_etest, 0, sizeof(rnd_hid_t)); + + rnd_hid_nogui_init(&exp_tedax_etest); + + exp_tedax_etest.struct_size = sizeof(rnd_hid_t); + exp_tedax_etest.name = "tedax-etest"; + exp_tedax_etest.description = "Electric test (list of exposed pads)"; + exp_tedax_etest.exporter = 1; + + exp_tedax_etest.get_export_options = tedax_etest_get_export_options; + exp_tedax_etest.do_export = tedax_etest_do_export; + exp_tedax_etest.parse_arguments = tedax_etest_parse_arguments; + + exp_tedax_etest.usage = tedax_etest_usage; + + rnd_hid_register_hid(&exp_tedax_etest); +} Index: tags/2.3.0/src_plugins/io_tedax/tetest.h =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tetest.h (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tetest.h (revision 33253) @@ -0,0 +1,8 @@ +#include "board.h" + +int tedax_etest_save(pcb_board_t *pcb, const char *etestid, const char *fn); +int tedax_etest_fsave(pcb_board_t *pcb, const char *etestid, FILE *f); + +void tedax_etest_init(void); +void tedax_etest_uninit(void); + Index: tags/2.3.0/src_plugins/io_tedax/tlayer.c =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tlayer.c (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tlayer.c (revision 33253) @@ -0,0 +1,483 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tedax IO plugin - stackup import/export + * pcb-rnd Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include +#include "data.h" +#include "tlayer.h" +#include +#include +#include "parse.h" +#include +#include "obj_line.h" +#include "obj_arc.h" +#include "obj_poly.h" +#include +#include "plug_io.h" +#include "obj_pstk_inlines.h" + +#include "common_inlines.h" + +#define LAYERNET(obj) if (nmap != NULL) tedax_finsert_layernet_tags(f, nmap, (pcb_any_obj_t *)obj) + +static void tedax_layer_fsave_pstk_polys(pcb_board_t *pcb, pcb_data_t *data, pcb_layer_t *ly, FILE *f) +{ + PCB_PADSTACK_LOOP(data) { + pcb_pstk_shape_t *shp = pcb_pstk_shape_at(pcb, padstack, ly); + if ((shp != NULL) && (shp->shape == PCB_PSSH_POLY)) { + int n; + fprintf(f, "begin polyline v1 pstk_%p_%p\n", (void *)padstack, (void *)ly); + for(n = 0; n < shp->data.poly.len; n++) + rnd_fprintf(f, " v %.06mm %.06mm\n", shp->data.poly.x[n], shp->data.poly.y[n]); + fprintf(f, "end polyline\n"); + } + } + PCB_END_LOOP; + + PCB_SUBC_LOOP(data) { + tedax_layer_fsave_pstk_polys(pcb, subc->data, ly, f); + } + PCB_END_LOOP; +} + +static void tedax_layer_fsave_pstk_shape(pcb_board_t *pcb, pcb_data_t *data, pcb_layer_t *ly, FILE *f, pcb_netmap_t *nmap) +{ + PCB_PADSTACK_LOOP(data) { + pcb_pstk_shape_t *shp = pcb_pstk_shape_at(pcb, padstack, ly); + if (shp == NULL) + continue; + switch(shp->shape) { + case PCB_PSSH_HSHADOW: /* no shape drawn */ break; + case PCB_PSSH_LINE: + rnd_fprintf(f, " line"); + LAYERNET(padstack); + rnd_fprintf(f, " %.06mm %.06mm %.06mm %.06mm %.06mm %.06mm\n", + padstack->x + shp->data.line.x1, padstack->y + shp->data.line.y1, + padstack->x + shp->data.line.x2, padstack->y + shp->data.line.y2, + shp->data.line.thickness, PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, padstack) ? (rnd_coord_t)rnd_round(padstack->Clearance/2) : 0); + break; + case PCB_PSSH_CIRC: + rnd_fprintf(f, " line"); + LAYERNET(padstack); + rnd_fprintf(f, " %.06mm %.06mm %.06mm %.06mm %.06mm %.06mm\n", + padstack->x + shp->data.circ.x, padstack->y + shp->data.circ.y, + padstack->x + shp->data.circ.x, padstack->y + shp->data.circ.y, + shp->data.circ.dia, PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, padstack) ? (rnd_coord_t)rnd_round(padstack->Clearance/2) : 0); + break; + case PCB_PSSH_POLY: + rnd_fprintf(f, " poly"); + LAYERNET(padstack); + rnd_fprintf(f, " pstk_%p_%p %.06mm %.06mm\n", (void *)padstack, (void *)ly, padstack->x, padstack->y); + break; + } + } + PCB_END_LOOP; + + PCB_SUBC_LOOP(data) { + tedax_layer_fsave_pstk_shape(pcb, subc->data, ly, f, nmap); + } + PCB_END_LOOP; +} + +int tedax_layer_fsave(pcb_board_t *pcb, rnd_layergrp_id_t gid, const char *layname, FILE *f, pcb_netmap_t *nmap) +{ + char lntmp[64]; + int lno; + rnd_pline_t *pl; + long plid; + const char *blockid = ((nmap == NULL) ? "layer" : "layernet"); + pcb_layergrp_t *g = pcb_get_layergrp(pcb, gid); + + if (g == NULL) + return -1; + + if (layname == NULL) + layname = g->name; + if (layname == NULL) { + layname = lntmp; + sprintf(lntmp, "anon_%ld", gid); + } + + for(lno = 0; lno < g->len; lno++) { + pcb_layer_t *ly = pcb_get_layer(pcb->Data, g->lid[lno]); + if (ly == NULL) + continue; + + PCB_POLY_LOOP(ly) { + rnd_pline_t *pl; + if (!polygon->NoHolesValid) + pcb_poly_compute_no_holes(polygon); + + for(pl = polygon->NoHoles, plid = 0; pl != NULL; pl = pl->next, plid++) { + rnd_vnode_t *v; + long i, n; + fprintf(f, "begin polyline v1 pllay_%ld_%ld_%ld\n", gid, polygon->ID, plid); + n = pl->Count; + for(v = pl->head, i = 0; i < n; v = v->next, i++) + rnd_fprintf(f, " v %.06mm %.06mm\n", v->point[0], v->point[1]); + fprintf(f, "end polyline\n"); + } + } PCB_END_LOOP; + + if (nmap != NULL) { /* text objets have to be approximated with a rectangular polygon "keepout" */ + PCB_TEXT_LOOP(ly) { + fprintf(f, "begin polyline v1 txlay_%ld\n", text->ID); + rnd_fprintf(f, " v %.06mm %.06mm\n", text->bbox_naked.X1, text->bbox_naked.Y1); + rnd_fprintf(f, " v %.06mm %.06mm\n", text->bbox_naked.X1, text->bbox_naked.Y2); + rnd_fprintf(f, " v %.06mm %.06mm\n", text->bbox_naked.X2, text->bbox_naked.Y2); + rnd_fprintf(f, " v %.06mm %.06mm\n", text->bbox_naked.X2, text->bbox_naked.Y1); + fprintf(f, "end polyline\n"); + } PCB_END_LOOP; + + if (lno == 0) + tedax_layer_fsave_pstk_polys(pcb, pcb->Data, ly, f); + } + } + + fprintf(f, "begin %s v1 %s\n", blockid, layname); + for(lno = 0; lno < g->len; lno++) { + pcb_layer_t *ly = pcb_get_layer(pcb->Data, g->lid[lno]); + if (ly == NULL) + continue; + PCB_LINE_LOOP(ly) { + rnd_fprintf(f, " line"); + LAYERNET(line); + rnd_fprintf(f, " %.06mm %.06mm %.06mm %.06mm %.06mm %.06mm\n", + line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, + line->Thickness, PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, line) ? rnd_round(line->Clearance/2) : 0); + } PCB_END_LOOP; + PCB_ARC_LOOP(ly) { + rnd_coord_t sx, sy, ex, ey, clr; + + if (arc->Width != arc->Height) + pcb_io_incompat_save(pcb->Data, (pcb_any_obj_t *)arc, "arc", "Elliptical arc", "Saving as circular arc instead - geometry will differ"); + + pcb_arc_get_end(arc, 0, &sx, &sy); + pcb_arc_get_end(arc, 1, &ex, &ey); + clr = PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, arc) ? rnd_round(arc->Clearance/2) : 0; + rnd_fprintf(f, " arc"); + LAYERNET(arc); + rnd_fprintf(f, " %.06mm %.06mm %.06mm %f %f %.06mm %.06mm ", + arc->X, arc->Y, arc->Width, arc->StartAngle, arc->Delta, arc->Thickness, clr); + rnd_fprintf(f, "%.06mm %.06mm %.06mm %.06mm\n", sx, sy, ex, ey); + } PCB_END_LOOP; + { + pcb_gfx_t *gfx; + for(gfx = gfxlist_first(&ly->Gfx); gfx != NULL; gfx = gfxlist_next(gfx)) + pcb_io_incompat_save(pcb->Data, (pcb_any_obj_t *)gfx, "gfx", "gfx can not be exported", "please use the lihata board format"); + } + + if (nmap == NULL) { + PCB_TEXT_LOOP(ly) { + int scale; + if (pcb_text_old_scale(text, &scale) != 0) + pcb_io_incompat_save(pcb->Data, (pcb_any_obj_t *)text, "text-scale", "file format does not support different x and y direction text scale - using average scale", "Use the scale field, set scale_x and scale_y to 0"); + if (text->mirror_x) + pcb_io_incompat_save(NULL, (pcb_any_obj_t *)text, "text-mirror-x", "file format does not support different mirroring text in the x direction", "do not mirror, or mirror in the y direction (with the ONSOLDER flag)"); + rnd_fprintf(f, " text %.06mm %.06mm %.06mm %.06mm %d %f %.06mm ", + text->bbox_naked.X1, text->bbox_naked.Y1, text->bbox_naked.X2, text->bbox_naked.Y2, + scale, text->rot, PCB_FLAG_TEST(PCB_FLAG_CLEARLINE, text) ? 1 : 0); + tedax_fprint_escape(f, text->TextString); + fputc('\n', f); + } PCB_END_LOOP; + } + else { + PCB_TEXT_LOOP(ly) { + rnd_fprintf(f, " poly"); + LAYERNET(text); + rnd_fprintf(f, " txlay_%ld 0 0\n", text->ID); + } PCB_END_LOOP; + } + + PCB_POLY_LOOP(ly) { + for(pl = polygon->NoHoles, plid = 0; pl != NULL; pl = pl->next, plid++) { + rnd_fprintf(f, " poly"); + LAYERNET(polygon); + rnd_fprintf(f, " pllay_%ld_%ld_%ld 0 0\n", gid, polygon->ID, plid); + } + } PCB_END_LOOP; + if (lno == 0) + tedax_layer_fsave_pstk_shape(pcb, pcb->Data, ly, f, nmap); + } + fprintf(f, "end %s\n", blockid); + return 0; +} + +int tedax_layer_save(pcb_board_t *pcb, rnd_layergrp_id_t gid, const char *layname, const char *fn) +{ + int res; + FILE *f; + + f = rnd_fopen_askovr(&PCB->hidlib, fn, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_layer_save(): can't open %s for writing\n", fn); + return -1; + } + fprintf(f, "tEDAx v1\n"); + res = tedax_layer_fsave(pcb, gid, layname, f, NULL); + fclose(f); + return res; +} + +int tedax_layers_fload(pcb_data_t *data, FILE *f, const char *blk_id, int silent) +{ + long start, n; + int argc, res = 0; + char line[520]; + char *argv[16], *end; + htsp_t plines; + htsp_entry_t *e; + vtc0_t *coords; + + if (tedax_seek_hdr(f, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + start = ftell(f); + + htsp_init(&plines, strhash, strkeyeq); + while((argc = tedax_seek_block(f, "polyline", "v1", NULL, 1, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]))) > 1) { + char *pname; + if (htsp_has(&plines, argv[3])) { + rnd_message(RND_MSG_ERROR, "duplicate polyline: %s\n", argv[3]); + res = -1; + goto error; + } + pname = rnd_strdup(argv[3]); + coords = malloc(sizeof(vtc0_t)); + vtc0_init(coords); + + while((argc = tedax_getline(f, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]))) >= 0) { + + if ((argc == 3) && (strcmp(argv[0], "v") == 0)) { + rnd_bool s1, s2; + vtc0_append(coords, rnd_get_value(argv[1], "mm", NULL, &s1)); + vtc0_append(coords, rnd_get_value(argv[2], "mm", NULL, &s2)); + if (!s1 || !s2) { + rnd_message(RND_MSG_ERROR, "invalid coords in polyline %s: %s;%s\n", pname, argv[1], argv[2]); + res = -1; + free(pname); + goto error; + } + } + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "polyline") == 0)) { + break; + } + else { + rnd_message(RND_MSG_ERROR, "invalid command in polyline %s: %s\n", pname, argv[0]); + res = -1; + free(pname); + goto error; + } + } + + htsp_insert(&plines, pname, coords); + } + + fseek(f, start, SEEK_SET); + + while((argc = tedax_seek_block(f, "layer", "v1", blk_id, silent, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]))) > 1) { + pcb_layer_t *ly; + if (data->LayerN >= PCB_MAX_LAYER) { + rnd_message(RND_MSG_ERROR, "too many layers\n"); + res = -1; + goto error; + } + ly = &data->Layer[data->LayerN++]; + free((char *)ly->name); + ly->name = rnd_strdup(argv[3]); + ly->is_bound = data->parent_type != PCB_PARENT_BOARD; + if (!ly->is_bound) { + /* real layer */ + memset(&ly->meta.real, 0, sizeof(ly->meta.real)); + ly->meta.real.grp = -1; /* group insertion is to be done by the caller */ + ly->meta.real.vis = 1; + } + else + memset(&ly->meta.bound, 0, sizeof(ly->meta.bound)); + + while((argc = tedax_getline(f, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]))) >= 0) { + if ((argc == 7) && (strcmp(argv[0], "line") == 0)) { + rnd_coord_t x1, y1, x2, y2, th, cl; + rnd_bool s1, s2, s3, s4; + + x1 = rnd_get_value(argv[1], "mm", NULL, &s1); + y1 = rnd_get_value(argv[2], "mm", NULL, &s2); + x2 = rnd_get_value(argv[3], "mm", NULL, &s3); + y2 = rnd_get_value(argv[4], "mm", NULL, &s4); + if (!s1 || !s2 || !s3 || !s4) { + rnd_message(RND_MSG_ERROR, "invalid line coords in line: %s;%s %s;%s\n", argv[1], argv[2], argv[3], argv[4]); + res = -1; + goto error; + } + th = rnd_get_value(argv[5], "mm", NULL, &s1); + cl = rnd_get_value(argv[6], "mm", NULL, &s2); + if (!s1 || !s2) { + rnd_message(RND_MSG_ERROR, "invalid thickness or clearance in line: %s;%s\n", argv[5], argv[6]); + res = -1; + goto error; + } + pcb_line_new_merge(ly, x1, y1, x2, y2, th, cl*2, pcb_flag_make(PCB_FLAG_CLEARLINE)); + } + else if ((argc == 12) && (strcmp(argv[0], "arc") == 0)) { + rnd_coord_t cx, cy, r, th, cl; + double sa, da; + rnd_bool s1, s2, s3; + + cx = rnd_get_value(argv[1], "mm", NULL, &s1); + cy = rnd_get_value(argv[2], "mm", NULL, &s2); + r = rnd_get_value(argv[3], "mm", NULL, &s3); + if (!s1 || !s2 || !s3) { + rnd_message(RND_MSG_ERROR, "invalid arc coords or radius in line: %s;%s %s\n", argv[1], argv[2], argv[3]); + res = -1; + goto error; + } + sa = strtod(argv[4], &end); + if ((*end != '\0') || (sa < 0) || (sa >= 360.0)) { + rnd_message(RND_MSG_ERROR, "invalid arc start angle %s\n", argv[4]); + res = -1; + goto error; + } + da = strtod(argv[5], &end); + if ((*end != '\0') || (da < -360.0) || (da > 360.0)) { + rnd_message(RND_MSG_ERROR, "invalid arc delta angle %s\n", argv[5]); + res = -1; + goto error; + } + th = rnd_get_value(argv[6], "mm", NULL, &s1); + cl = rnd_get_value(argv[7], "mm", NULL, &s2); + if (!s1 || !s2) { + rnd_message(RND_MSG_ERROR, "invalid thickness or clearance in arc: %s;%s\n", argv[6], argv[7]); + res = -1; + goto error; + } + pcb_arc_new(ly, cx, cy, r, r, sa, da, th, cl*2, pcb_flag_make(PCB_FLAG_CLEARLINE), 1); + } + else if ((argc == 9) && (strcmp(argv[0], "text") == 0)) { + rnd_coord_t bx1, by1, bx2, by2, rw, rh, aw, ah; + rnd_bool s1, s2, s3, s4; + double rot, zx, zy, z; + pcb_text_t *text; + + bx1 = rnd_get_value(argv[1], "mm", NULL, &s1); + by1 = rnd_get_value(argv[2], "mm", NULL, &s2); + bx2 = rnd_get_value(argv[3], "mm", NULL, &s3); + by2 = rnd_get_value(argv[4], "mm", NULL, &s4); + if (!s1 || !s2 || !s3 || !s4) { + rnd_message(RND_MSG_ERROR, "invalid bbox coords in text %s;%s %s;%s \n", argv[1], argv[2], argv[3], argv[4]); + res = -1; + goto error; + } + rot = strtod(argv[6], &end); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "invalid text rotation %s \n", argv[6]); + res = -1; + goto error; + } + if (rot < 0) + rot += 360; + text = pcb_text_new(ly, pcb_font(PCB, 0, 1), bx1, by1, rot, 100, 0, argv[8], pcb_flag_make(PCB_FLAG_CLEARLINE)); + rw = bx2-bx1; rh = by2-by1; + pcb_text_pre(text); + for(n = 0; n < 8; n++) { + pcb_text_bbox(pcb_font(PCB, 0, 1), text); + aw = text->bbox_naked.X2 - text->bbox_naked.X1; ah = text->bbox_naked.Y2 - text->bbox_naked.Y1; + zx = (double)rw/(double)aw; zy = (double)rh/(double)ah; + z = zx < zy ? zx : zy; + if ((z > 0.999) && (z < 1.001)) + break; + text->Scale = rnd_round(text->Scale*z); + } + pcb_text_bbox(pcb_font(PCB, 0, 1), text); + aw = text->bbox_naked.X2 - text->bbox_naked.X1; ah = text->bbox_naked.Y2 - text->bbox_naked.Y1; + text->X += (double)(rw-aw)/2.0; + text->Y += (double)(rh-ah)/2.0; + pcb_text_post(text); + + } + else if ((argc == 4) && (strcmp(argv[0], "poly") == 0)) { + rnd_bool s1, s2; + rnd_coord_t ox, oy; + pcb_poly_t *poly; + + ox = rnd_get_value(argv[2], "mm", NULL, &s1); + oy = rnd_get_value(argv[3], "mm", NULL, &s2); + if (!s1 || !s2) { + rnd_message(RND_MSG_ERROR, "invalid coords in poly %s;%s\n", argv[2], argv[3]); + res = -1; + goto error; + } + coords = htsp_get(&plines, argv[1]); + if (coords == NULL) { + rnd_message(RND_MSG_ERROR, "invalid polyline referecnce %s\n", argv[1]); + res = -1; + goto error; + } + rnd_trace("POLY: %mm %mm %s\n", ox, oy, argv[1]); + poly = pcb_poly_new(ly, 0, pcb_no_flags()); + for(n = 0; n < coords->used; n+=2) + pcb_poly_point_new(poly, ox+coords->array[n], oy+coords->array[n+1]); + pcb_add_poly_on_layer(ly, poly); + } + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "layer") == 0)) + break; + else { + rnd_message(RND_MSG_ERROR, "invalid layer object %s\n", argv[0]); + res = -1; + goto error; + } + } + } + + + error:; + for(e = htsp_first(&plines); e != NULL; e = htsp_next(&plines, e)) { + free(e->key); + vtc0_uninit(e->value); + free(e->value); + } + htsp_uninit(&plines); + return res; +} + +int tedax_layers_load(pcb_data_t *data, const char *fn, const char *blk_id, int silent) +{ + int res; + FILE *f; + + f = rnd_fopen(&PCB->hidlib, fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_layers_load(): can't open %s for reading\n", fn); + return -1; + } + res = tedax_layers_fload(data, f, blk_id, silent); + fclose(f); + return res; +} + Index: tags/2.3.0/src_plugins/io_tedax/tlayer.h =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tlayer.h (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tlayer.h (revision 33253) @@ -0,0 +1,10 @@ +#include "board.h" +#include "layer.h" +#include "../src_plugins/lib_netmap/netmap.h" + + +int tedax_layer_save(pcb_board_t *pcb, rnd_layergrp_id_t gid, const char *layname, const char *fn); +int tedax_layer_fsave(pcb_board_t *pcb, rnd_layergrp_id_t gid, const char *layname, FILE *f, pcb_netmap_t *nmap); + +int tedax_layers_load(pcb_data_t *data, const char *fn, const char *blk_id, int silent); +int tedax_layers_fload(pcb_data_t *data, FILE *f, const char *blk_id, int silent); Index: tags/2.3.0/src_plugins/io_tedax/tnetlist.c =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tnetlist.c (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tnetlist.c (revision 33253) @@ -0,0 +1,324 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tedax IO plugin - netlist import + * pcb-rnd Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include "board.h" +#include "data.h" +#include "undo.h" +#include "plug_import.h" +#include "plug_io.h" +#include +#include +#include +#include +#include +#include +#include "obj_subc.h" +#include "netlist.h" + +#include "tnetlist.h" +#include "tdrc_query.h" +#include "parse.h" + +typedef struct { + char *value; + char *footprint; +} fp_t; + +static void *htsp_get2(htsp_t *ht, const char *key, size_t size) +{ + void *res = htsp_get(ht, key); + if (res == NULL) { + res = calloc(size, 1); + htsp_set(ht, rnd_strdup(key), res); + } + return res; +} + +int tedax_net_fload(FILE *fn, int import_fp, const char *blk_id, int silent) +{ + char line[520]; + char *argv[16]; + int argc; + htsp_t fps, pinnames; + htsp_entry_t *e; + + if (tedax_seek_hdr(fn, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + if (tedax_seek_block(fn, "netlist", "v1", blk_id, silent, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + htsp_init(&fps, strhash, strkeyeq); + htsp_init(&pinnames, strhash, strkeyeq); + + rnd_actionva(&PCB->hidlib, "Netlist", "Freeze", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Clear", NULL); + + while((argc = tedax_getline(fn, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]))) >= 0) { + if ((argc == 3) && (strcmp(argv[0], "footprint") == 0)) { + fp_t *fp = htsp_get2(&fps, argv[1], sizeof(fp_t)); + fp->footprint = rnd_strdup(argv[2]); + } + else if ((argc == 3) && (strcmp(argv[0], "value") == 0)) { + fp_t *fp = htsp_get2(&fps, argv[1], sizeof(fp_t)); + fp->value = rnd_strdup(argv[2]); + } + else if ((argc == 4) && (strcmp(argv[0], "conn") == 0)) { + char id[512]; + sprintf(id, "%s-%s", argv[2], argv[3]); + rnd_actionva(&PCB->hidlib, "Netlist", "Add", argv[1], id, NULL); + } + else if ((argc == 4) && (strcmp(argv[0], "pinname") == 0)) { + char id[512]; + sprintf(id, "%s-%s", argv[1], argv[2]); + e = htsp_popentry(&pinnames, id); + if (e != NULL) { + free(e->key); + free(e->value); + } + htsp_set(&pinnames, rnd_strdup(id), rnd_strdup(argv[3])); + } + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "netlist") == 0)) + break; + } + + rnd_actionva(&PCB->hidlib, "Netlist", "Sort", NULL); + rnd_actionva(&PCB->hidlib, "Netlist", "Thaw", NULL); + + if (import_fp) { + rnd_actionva(&PCB->hidlib, "ElementList", "start", NULL); + for (e = htsp_first(&fps); e; e = htsp_next(&fps, e)) { + fp_t *fp = e->value; + +/* rnd_trace("tedax fp: refdes=%s val=%s fp=%s\n", e->key, fp->value, fp->footprint);*/ + if (fp->footprint == NULL) + rnd_message(RND_MSG_ERROR, "tedax: not importing refdes=%s: no footprint specified\n", e->key); + else + rnd_actionva(&PCB->hidlib, "ElementList", "Need", null_empty(e->key), null_empty(fp->footprint), null_empty(fp->value), NULL); + + free(e->key); + free(fp->value); + free(fp->footprint); + free(fp); + } + rnd_actionva(&PCB->hidlib, "ElementList", "Done", NULL); + } + + for (e = htsp_first(&pinnames); e; e = htsp_next(&pinnames, e)) { + char *refdes = e->key, *name = e->value, *pin; + pin = strchr(refdes, '-'); + if (pin != NULL) { + *pin = '\0'; + pin++; + rnd_actionva(&PCB->hidlib, "ChangePinName", refdes, pin, name, NULL); + } + free(e->key); + free(e->value); + } + + htsp_uninit(&fps); + htsp_uninit(&pinnames); + + return 0; +} + + +int tedax_net_load(const char *fname_net, int import_fp, const char *blk_id, int silent) +{ + FILE *fn; + int ret = 0; + + fn = rnd_fopen(&PCB->hidlib, fname_net, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname_net); + return -1; + } + + pcb_undo_freeze_serial(); + ret = tedax_net_fload(fn, import_fp, blk_id, silent); + pcb_undo_unfreeze_serial(); + pcb_undo_inc_serial(); + + fclose(fn); + return ret; +} + +int tedax_net_fsave(pcb_board_t *pcb, const char *netlistid, FILE *f) +{ + rnd_cardinal_t n; + htsp_entry_t *e; + pcb_netlist_t *nl = &pcb->netlist[PCB_NETLIST_EDITED]; + + fprintf(f, "begin netlist v1 "); + tedax_fprint_escape(f, netlistid); + fputc('\n', f); + + + for(e = htsp_first(nl); e != NULL; e = htsp_next(nl, e)) { + pcb_net_term_t *t; + pcb_net_t *net = e->value; + + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) + fprintf(f, " conn %s %s %s\n", net->name, t->refdes, t->term); + } + + PCB_SUBC_LOOP(pcb->Data) { + pcb_attribute_t *a; + + if ((subc->refdes == NULL) || (*subc->refdes == '\0') || PCB_FLAG_TEST(PCB_FLAG_NONETLIST, subc)) + continue; + + for(n = 0, a = subc->Attributes.List; n < subc->Attributes.Number; n++,a++) { + if (strcmp(a->name, "refdes") == 0) + continue; + if (strcmp(a->name, "footprint") == 0) { + fprintf(f, " footprint %s ", subc->refdes); + tedax_fprint_escape(f, a->value); + fputc('\n', f); + continue; + } + if (strcmp(a->name, "value") == 0) { + fprintf(f, " value %s ", subc->refdes); + tedax_fprint_escape(f, a->value); + fputc('\n', f); + continue; + } + if (strcmp(a->name, "device") == 0) { + fprintf(f, " device %s ", subc->refdes); + tedax_fprint_escape(f, a->value); + fputc('\n', f); + continue; + } + rnd_fprintf(f, " comptag %s ", subc->refdes); + tedax_fprint_escape(f, a->name); + fputc(' ', f); + tedax_fprint_escape(f, a->value); + fputc('\n', f); + } + } PCB_END_LOOP; + + fprintf(f, "end netlist\n"); + return 0; +} + + +int tedax_net_save(pcb_board_t *pcb, const char *netlistid, const char *fn) +{ + int res; + FILE *f; + + f = rnd_fopen_askovr(&PCB->hidlib, fn, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_net_save(): can't open %s for writing\n", fn); + return -1; + } + fprintf(f, "tEDAx v1\n"); + res = tedax_net_fsave(pcb, netlistid, f); + fclose(f); + return res; +} + + +extern int pcb_io_tedax_test_parse(pcb_plug_io_t *plug_ctx, pcb_plug_iot_t typ, const char *Filename, FILE *f); + +static int tedaxnet_support_prio(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + FILE *f; + int res; + + if ((aspects != IMPORT_ASPECT_NETLIST) || (numargs != 1)) + return 0; /* only pure netlist import is supported from a single file*/ + + + f = rnd_fopen(&PCB->hidlib, args[0], "r"); + if (f == NULL) + return 0; + + res = pcb_io_tedax_test_parse(NULL, 0, args[0], f); + fclose(f); + return res ? 100 : 0; +} + + +int tedax_net_and_drc_load(const char *fname_net, int import_fp, int silent) +{ + FILE *fn; + int ret = 0; + + fn = rnd_fopen(&PCB->hidlib, fname_net, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname_net); + return -1; + } + + ret = tedax_net_fload(fn, import_fp, NULL, silent); + rewind(fn); + tedax_drc_query_rule_clear(PCB, "netlist"); + ret |= tedax_drc_query_fload(PCB, fn, NULL, "netlist", silent); + + fclose(fn); + return ret; +} + +static int tedaxnet_import(pcb_plug_import_t *ctx, unsigned int aspects, const char **args, int numargs) +{ + if (numargs != 1) { + rnd_message(RND_MSG_ERROR, "import_tedaxnet: requires exactly 1 input file name\n"); + return -1; + } + return tedax_net_and_drc_load(args[0], 1, 0); +} + +static pcb_plug_import_t import_tedaxnet; + +void pcb_tedax_net_uninit(void) +{ + RND_HOOK_UNREGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_tedaxnet); +} + +void pcb_tedax_net_init(void) +{ + /* register the IO hook */ + import_tedaxnet.plugin_data = NULL; + + import_tedaxnet.fmt_support_prio = tedaxnet_support_prio; + import_tedaxnet.import = tedaxnet_import; + import_tedaxnet.name = "tEDAx"; + import_tedaxnet.desc = "netlist+footprints+drc from tEDAx"; + import_tedaxnet.ui_prio = 100; + import_tedaxnet.single_arg = 1; + import_tedaxnet.all_filenames = 1; + import_tedaxnet.ext_exec = 0; + + RND_HOOK_REGISTER(pcb_plug_import_t, pcb_plug_import_chain, &import_tedaxnet); +} Index: tags/2.3.0/src_plugins/io_tedax/tnetlist.h =================================================================== --- tags/2.3.0/src_plugins/io_tedax/tnetlist.h (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/tnetlist.h (revision 33253) @@ -0,0 +1,8 @@ +int tedax_net_load(const char *fname_net, int import_fp, const char *blk_id, int silent); +int tedax_net_fload(FILE *f, int import_fp, const char *blk_id, int silent); + +int tedax_net_save(pcb_board_t *pcb, const char *netlistid, const char *fn); +int tedax_net_fsave(pcb_board_t *pcb, const char *netlistid, FILE *f); + +void pcb_tedax_net_init(void); +void pcb_tedax_net_uninit(void); Index: tags/2.3.0/src_plugins/io_tedax/trouter.c =================================================================== --- tags/2.3.0/src_plugins/io_tedax/trouter.c (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/trouter.c (revision 33253) @@ -0,0 +1,421 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * tedax IO plugin - autorouter import/export + * pcb-rnd 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "../src_plugins/lib_netmap/placement.h" +#include "../src_plugins/lib_compat_help/pstk_compat.h" + +#include "board.h" +#include "data.h" +#include "tboard.h" +#include "parse.h" +#include +#include +#include "obj_pstk_inlines.h" +#include "stackup.h" +#include "tlayer.h" +#include "obj_pstk.h" +#include +#include +#include +#include "plug_io.h" +#include "conf_core.h" +#include "undo_old.h" +#include "undo.h" + +#include "common_inlines.h" + +#define LAYERNET(obj) tedax_finsert_layernet_tags(f, nmap, (pcb_any_obj_t *)obj) + +static int tedax_global_via_fwrite(pcb_board_t *pcb, pcb_data_t *data, FILE *f, pcb_netmap_t *nmap) +{ + PCB_PADSTACK_LOOP(data) { + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(padstack); + if (proto != NULL) { + rnd_coord_t cx, cy, dia = 0; + + if (proto->hdia > 0) { + cx = padstack->x; + cy = padstack->y; + dia = proto->hdia; + } + else { + TODO("look for a slot"); + } + + if (dia > 0) { + fprintf(f, " via"); + LAYERNET(padstack); + rnd_fprintf(f, " %.06mm %.06mm %.06mm 0\n", cx, cy, dia); + TODO("bbvia: two more arguments"); + } + } + } + PCB_END_LOOP; + + PCB_SUBC_LOOP(data) { + tedax_global_via_fwrite(pcb, subc->data, f, nmap); + } + PCB_END_LOOP; + return 0; +} + +static void write_conf(FILE *f, int argc, fgw_arg_t *argv) +{ + int n; + + for(n = 0; n < argc; n++) { + const char *key, *sep; + if (fgw_arg_conv(&rnd_fgw, &argv[n], FGW_STR) != 0) { + rnd_message(RND_MSG_ERROR, "Error: route_req: confkey #%d can not be converted to string and is ignored\n", n); + continue; + } + key = argv[n].val.str; + sep = strchr(key, '='); + if (sep == NULL) { + rnd_message(RND_MSG_ERROR, "Error: route_req: confkey %s: no '=' and no value\n", key); + continue; + } + if (strlen(key) > 500) { + rnd_message(RND_MSG_ERROR, "Error: route_req: confkey %s: value too long\n", key); + continue; + } + sep++; + fprintf(f, " conf "); + tedax_fnprint_escape(f, key, sep-key-1); + fprintf(f, " "); + tedax_fprint_escape(f, sep); + fprintf(f, "\n"); + } +} + +int tedax_route_req_fsave(pcb_board_t *pcb, FILE *f, int cfg_argc, fgw_arg_t *cfg_argv) +{ + rnd_layergrp_id_t gid; + int res = -1; + tedax_stackup_t ctx; + pcb_netmap_t nmap; + static const char *stackupid = "board_stackup"; + + if (pcb_netmap_init(&nmap, pcb, PCB_NETMAPCTRL_RATTED) != 0) { + rnd_message(RND_MSG_ERROR, "internal error: failed to map networks\n"); + goto error; + } + + tedax_stackup_init(&ctx); + ctx.include_grp_id = 1; + fputc('\n', f); + if (tedax_stackup_fsave(&ctx, pcb, stackupid, f, PCB_LYT_COPPER) != 0) { + rnd_message(RND_MSG_ERROR, "internal error: failed to save the stackup\n"); + goto error; + } + + for(gid = 0; gid < ctx.g2n.used; gid++) { + char *name = ctx.g2n.array[gid]; + if (name != NULL) { + fputc('\n', f); + tedax_layer_fsave(pcb, gid, name, f, &nmap); + } + } + + fputc('\n', f); + + fprintf(f, "\nbegin route_req v1 "); + tedax_fprint_escape(f, pcb->hidlib.name); + fputc('\n', f); + + write_conf(f, cfg_argc, cfg_argv); + + rnd_fprintf(f, " stackup %s\n", stackupid); + + if (tedax_global_via_fwrite(pcb, pcb->Data, f, &nmap) != 0) + goto error; + + /* For now only full-routing is specified */ + fprintf(f, " route_all\n"); + + fprintf(f, "end route_req\n"); + + res = 0; + error:; + tedax_stackup_uninit(&ctx); + pcb_netmap_uninit(&nmap); + return res; +} + + +int tedax_route_req_save(pcb_board_t *pcb, const char *fn, int cfg_argc, fgw_arg_t *cfg_argv) +{ + int res; + FILE *f; + + f = rnd_fopen_askovr(&PCB->hidlib, fn, "w", NULL); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "tedax_route_req_save(): can't open %s for writing\n", fn); + return -1; + } + fprintf(f, "tEDAx v1\n"); + res = tedax_route_req_fsave(pcb, f, cfg_argc, cfg_argv); + fclose(f); + return res; +} + + + +#define PARSE_COORD(dst, src) \ + dst = rnd_get_value(src, "mm", NULL, &succ); \ + if (!succ) { \ + rnd_message(RND_MSG_ERROR, "External autorouter: invalid coordinate '%s'\n", src); \ + continue; \ + } + +int tedax_route_res_fload(FILE *fn, const char *blk_id, int silent) +{ + char line[520]; + char *argv[16]; + int argc; + long cnt_add = 0, cnt_del = 0; + rnd_bool succ; + + if (tedax_seek_hdr(fn, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + if (tedax_seek_block(fn, "route_res", "v1", blk_id, silent, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return -1; + + while((argc = tedax_getline(fn, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]))) >= 0) { + if ((argc > 5) && (strcmp(argv[0], "add") == 0)) { + rnd_layergrp_id_t gid; + pcb_layer_t *ly; + pcb_layergrp_t *grp; + char *end; + + if ((argc == 9) && (strcmp(argv[2], "via") == 0)) { /* special case: won't have a layer */ + pcb_pstk_t *ps; + rnd_coord_t cx, cy, th, clr, hole; + + PARSE_COORD(cx, argv[5]); + PARSE_COORD(cy, argv[6]); + PARSE_COORD(th, argv[7]); + PARSE_COORD(clr, argv[8]); + + hole = conf_core.design.via_drilling_hole; + if (hole > th*4/5) + hole = th*4/5; + + ps = pcb_pstk_new_compat_via(PCB->Data, -1, cx, cy, hole, th, clr, 0, PCB_PSTK_COMPAT_ROUND, rnd_true); + pcb_undo_add_obj_to_create(PCB_OBJ_PSTK, ps, ps, ps); + + PCB_FLAG_SET(PCB_FLAG_AUTO, ps); + cnt_add++; + continue; + } + + /* convert the layer */ + gid = strtol(argv[1], &end, 10); + if ((*end != '.') || (gid < 0) || (gid >= PCB->LayerGroups.len)) { + rnd_message(RND_MSG_ERROR, "External autorouter: invalid layer group '%s'\n", argv[1]); + continue; + } + grp = &PCB->LayerGroups.grp[gid]; + if ((!(grp->ltype & PCB_LYT_COPPER)) || (grp->len < 1)) { + rnd_message(RND_MSG_ERROR, "External autorouter: on layer group '%s' which is either not copper or doesn't have layers\n", argv[1]); + continue; + } + ly = pcb_get_layer(PCB->Data, grp->lid[0]); + if (ly == NULL) { + rnd_message(RND_MSG_ERROR, "External autorouter: on layer group '%s' which is broken\n", argv[1]); + continue; + } + + if ((argc == 11) && (strcmp(argv[2], "line") == 0)) { + rnd_coord_t x1, y1, x2, y2, th, cl; + pcb_line_t *line; + PARSE_COORD(x1, argv[5]); + PARSE_COORD(y1, argv[6]); + PARSE_COORD(x2, argv[7]); + PARSE_COORD(y2, argv[8]); + PARSE_COORD(th, argv[9]); + PARSE_COORD(cl, argv[10]); + line = pcb_line_new_merge(ly, x1, y1, x2, y2, th, cl, pcb_flag_make(PCB_FLAG_CLEARLINE | PCB_FLAG_AUTO)); + if (line != NULL) + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, ly, line, line); + } + else + rnd_message(RND_MSG_ERROR, "External autorouter: can't add object type '%s' with %d args\n", argv[2], argc); + cnt_add++; + } + else if (strcmp(argv[0], "del") == 0) { + } + else if ((argc == 3) && (strcmp(argv[0], "log") == 0)) { + rnd_message_level_t level = RND_MSG_DEBUG; + switch(argv[1][0]) { + case 'I': level = RND_MSG_INFO; break; + case 'W': level = RND_MSG_WARNING; break; + case 'E': level = RND_MSG_ERROR; break; + } + if (level == RND_MSG_DEBUG) break; + rnd_message(level, "%s\n", argv[2]); + } + else if (strcmp(argv[0], "stat") == 0) { + } + else if (strcmp(argv[0], "confkey") == 0) { + } + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "route_res") == 0)) + break; + } + + if ((cnt_add > 0) || (cnt_del > 0)) + pcb_undo_inc_serial(); + + rnd_message(RND_MSG_INFO, "External autorouter: imported %ld objects, removed %ld objets\n", cnt_add, cnt_del); + + return 0; +} + + +int tedax_route_res_load(const char *fname, const char *blk_id, int silent) +{ + FILE *fn; + int ret = 0; + + fn = rnd_fopen(&PCB->hidlib, fname, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname); + return -1; + } + + ret = tedax_route_res_fload(fn, blk_id, silent); + + fclose(fn); + return ret; +} + + +#define LOAD_MINMAX(s) \ +do { \ + cfg->min_val = -HUGE_VAL; cfg->max_val = HUGE_VAL; \ + v = strtod(s, &end); \ + if (*end == ':') { \ + cfg->min_val = strtod(s, &end); \ + if (*end == ':') \ + cfg->max_val = strtod(s, &end); \ + } \ +} while(0) + +void *tedax_route_conf_keys_fload(FILE *fn, const char *blk_id, int silent) +{ + char line[520]; + char *argv[16], *end; + int argc; + long start, cnt = 0; + rnd_export_opt_t *table, *cfg; + double v; + + + if (tedax_seek_hdr(fn, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return NULL; + + if (tedax_seek_block(fn, "route_res", "v1", blk_id, silent, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0])) < 0) + return NULL; + + start = ftell(fn); + while((argc = tedax_getline(fn, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]))) >= 0) { + if (strcmp(argv[0], "confkey") == 0) + cnt++; + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "route_res") == 0)) + break; + } + + cfg = table = calloc(sizeof(rnd_hid_attribute_t), cnt+1); + + fseek(fn, start, SEEK_SET); + while((argc = tedax_getline(fn, line, sizeof(line), argv, sizeof(argv)/sizeof(argv[0]))) >= 0) { + if ((argc == 5) && (strcmp(argv[0], "confkey") == 0)) { + cfg->name = rnd_strdup(argv[1]); + cfg->help_text = rnd_strdup(argv[4]); + if (strcmp(argv[2], "boolean") == 0) cfg->type = RND_HATT_BOOL; + else if (strcmp(argv[2], "integer") == 0) cfg->type = RND_HATT_INTEGER; + else if (strcmp(argv[2], "double") == 0) cfg->type = RND_HATT_REAL; + else if (strcmp(argv[2], "coord") == 0) cfg->type = RND_HATT_COORD; + else if (strcmp(argv[2], "string") == 0) cfg->type = RND_HATT_STRING; + else cfg->type = RND_HATT_LABEL; + + switch(cfg->type) { + case RND_HATT_BOOL: + cfg->default_val.lng = rnd_istrue(argv[3]); + break; + case RND_HATT_INTEGER: + LOAD_MINMAX(argv[3]); + cfg->default_val.lng = v; + break; + case RND_HATT_REAL: + LOAD_MINMAX(argv[3]); + cfg->default_val.dbl = v; + break; + case RND_HATT_COORD: + LOAD_MINMAX(argv[3]); + cfg->default_val.crd = RND_MM_TO_COORD(v); + break; + case RND_HATT_STRING: + cfg->default_val.str = rnd_strdup(argv[3]); + break; + default: + break; + } + cfg++; + } + else if ((argc == 2) && (strcmp(argv[0], "end") == 0) && (strcmp(argv[1], "route_res") == 0)) + break; + } + + return table; +} + +void *tedax_route_conf_keys_load(const char *fname, const char *blk_id, int silent) +{ + FILE *fn; + void *ret; + + fn = rnd_fopen(&PCB->hidlib, fname, "r"); + if (fn == NULL) { + rnd_message(RND_MSG_ERROR, "can't open file '%s' for read\n", fname); + return NULL; + } + + ret = tedax_route_conf_keys_fload(fn, blk_id, silent); + + fclose(fn); + return ret; +} Index: tags/2.3.0/src_plugins/io_tedax/trouter.h =================================================================== --- tags/2.3.0/src_plugins/io_tedax/trouter.h (nonexistent) +++ tags/2.3.0/src_plugins/io_tedax/trouter.h (revision 33253) @@ -0,0 +1,11 @@ +#include "board.h" + +int tedax_route_req_save(pcb_board_t *pcb, const char *fn, int cfg_argc, fgw_arg_t *cfg_argv); +int tedax_route_req_fsave(pcb_board_t *pcb, FILE *f, int cfg_argc, fgw_arg_t *cfg_argv); + +int tedax_route_res_fload(FILE *fn, const char *blk_id, int silent); +int tedax_route_res_load(const char *fname, const char *blk_id, int silent); + + +void *tedax_route_conf_keys_load(const char *fname, const char *blk_id, int silent); + Index: tags/2.3.0/src_plugins/jostle/Makefile =================================================================== --- tags/2.3.0/src_plugins/jostle/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/jostle/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_jostle + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/jostle/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/jostle/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/jostle/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {jostle} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/jostle/jostle.o @] + +switch /local/pcb/jostle/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/jostle/jostle.c =================================================================== --- tags/2.3.0/src_plugins/jostle/jostle.c (nonexistent) +++ tags/2.3.0/src_plugins/jostle/jostle.c (revision 33253) @@ -0,0 +1,530 @@ +/* + * jostle plug-in for PCB. + * + * Copyright (C) 2007 Ben Jackson + * + * Licensed under the terms of the GNU General Public + * License, version 2 or later. + * + * Ported to pcb-rnd by Tibor 'Igor2' Palinkas in 2016. + * + * + * Pushes lines out of the way. + */ + +#include +#include +#include +#include + +#include "config.h" +#include "board.h" +#include "data.h" +#include +#include +#include "undo.h" +#include "polygon.h" +#include +#include "remove.h" +#include +#include +#include +#include +#include "layer.h" +#include "conf_core.h" +#include +#include "obj_line.h" +#include + +/*#define DEBUG_pcb_polyarea_t*/ + +double rnd_vect_dist2(rnd_vector_t v1, rnd_vector_t v2); +#define Vcpy2(r,a) {(r)[0] = (a)[0]; (r)[1] = (a)[1];} +#define Vswp2(a,b) { long t; \ + t = (a)[0], (a)[0] = (b)[0], (b)[0] = t; \ + t = (a)[1], (a)[1] = (b)[1], (b)[1] = t; \ +} + +enum { + JNORTH, + JNORTHEAST, + JEAST, + JSOUTHEAST, + JSOUTH, + JSOUTHWEST, + JWEST, + JNORTHWEST +}; + +const char *dirnames[] = { + "JNORTH", + "JNORTHEAST", + "JEAST", + "JSOUTHEAST", + "JSOUTH", + "JSOUTHWEST", + "JWEST", + "JNORTHWEST" +}; + +#define ARG(n) (argc > (n) ? argv[n] : 0) + +/* DEBUG */ +static void Debugpcb_polyarea_t(rnd_polyarea_t * s, char *color) +{ + int *x, *y, n, i = 0; + rnd_pline_t *pl; + rnd_vnode_t *v; + rnd_polyarea_t *p; + +#ifndef DEBUG_pcb_polyarea_t + return; +#endif + +/* TODO: rewrite this to UI layers if needed + ddraw = rnd_gui->request_debug_draw(); + ddgc = ddraw->make_gc(); +*/ + + p = s; + do { + for (pl = p->contours; pl; pl = pl->next) { + n = pl->Count; + x = (int *) malloc(n * sizeof(int)); + y = (int *) malloc(n * sizeof(int)); + for (v = pl->head; i < n; v = v->next) { + x[i] = v->point[0]; + y[i++] = v->point[1]; + } +/* if (1) { + rnd_render->set_color(ddgc, color ? color : conf_core.appearance.color.connected); + rnd_hid_set_line_width(ddgc, 1); + for (i = 0; i < n - 1; i++) { + rnd_render->draw_line(ddgc, x[i], y[i], x[i + 1], y[i + 1]); + rnd_render->fill_circle (ddgc, x[i], y[i], 30); + } + rnd_render->draw_line(ddgc, x[n - 1], y[n - 1], x[0], y[0]); + }*/ + free(x); + free(y); + } + } while ((p = p->f) != s); +/* ddraw->flush_debug_draw();*/ +/* rnd_hid_busy(PCB, 1); */ +/* sleep(3); + ddraw->finish_debug_draw();*/ +/* rnd_hid_busy(PCB, 0); */ +} + +/* Find the bounding box of a rnd_polyarea_t. + * + * pcb_polyarea_ts linked by ->f/b are outlines.\n + * n->contours->next would be the start of the inner holes (irrelevant + * for bounding box). */ +static rnd_box_t pcb_polyarea_t_boundingBox(rnd_polyarea_t * a) +{ + rnd_polyarea_t *n; + rnd_pline_t *pa; + rnd_box_t box; + int first = 1; + + n = a; + do { + pa = n->contours; + if (first) { + box.X1 = pa->xmin; + box.X2 = pa->xmax + 1; + box.Y1 = pa->ymin; + box.Y2 = pa->ymax + 1; + first = 0; + } + else { + RND_MAKE_MIN(box.X1, pa->xmin); + RND_MAKE_MAX(box.X2, pa->xmax + 1); + RND_MAKE_MIN(box.Y1, pa->ymin); + RND_MAKE_MAX(box.Y2, pa->ymax + 1); + } + } while ((n = n->f) != a); + return box; +} + +/* Given a polygon and a side of it (a direction north/northeast/etc), find a + line tangent to that side, offset by clearance, and return it as a pair of + vectors PQ. Make it long so it will intersect everything in the area. */ +static void pcb_polyarea_t_findXmostLine(rnd_polyarea_t * a, int side, rnd_vector_t p, rnd_vector_t q, int clearance) +{ + int extra; + p[0] = p[1] = 0; + q[0] = q[1] = 0; + extra = a->contours->xmax - a->contours->xmin + a->contours->ymax - a->contours->ymin; + switch (side) { + case JNORTH: + p[1] = q[1] = a->contours->ymin - clearance; + p[0] = a->contours->xmin - extra; + q[0] = a->contours->xmax + extra; + break; + case JSOUTH: + p[1] = q[1] = a->contours->ymax + clearance; + p[0] = a->contours->xmin - extra; + q[0] = a->contours->xmax + extra; + break; + case JEAST: + p[0] = q[0] = a->contours->xmax + clearance; + p[1] = a->contours->ymin - extra; + q[1] = a->contours->ymax + extra; + break; + case JWEST: + p[0] = q[0] = a->contours->xmin - clearance; + p[1] = a->contours->ymin - extra; + q[1] = a->contours->ymax + extra; + break; + default: /* diagonal case */ + { + int kx, ky, minmax, dq, ckx, cky; + rnd_coord_t mm[2] = { RND_MAX_COORD, -RND_MAX_COORD }; + rnd_vector_t mmp[2]; + rnd_vnode_t *v; + + switch (side) { + case JNORTHWEST: + kx = 1; /* new_x = kx * x + ky * y */ + ky = 1; + dq = -1; /* extend line in +x, dq*y */ + ckx = cky = -1; /* clear line in ckx*clear, cky*clear */ + minmax = 0; /* min or max */ + break; + case JSOUTHWEST: + kx = 1; + ky = -1; + dq = 1; + ckx = -1; + cky = 1; + minmax = 0; + break; + case JNORTHEAST: + kx = 1; + ky = -1; + dq = 1; + ckx = 1; + cky = -1; + minmax = 1; + break; + case JSOUTHEAST: + kx = ky = 1; + dq = -1; + ckx = cky = 1; + minmax = 1; + break; + default: + rnd_message(RND_MSG_ERROR, "jostle: aiee, what side?"); + return; + } + v = a->contours->head; + do { + int test = kx * v->point[0] + ky * v->point[1]; + if (test < mm[0]) { + mm[0] = test; + mmp[0][0] = v->point[0]; + mmp[0][1] = v->point[1]; + } + if (test > mm[1]) { + mm[1] = test; + mmp[1][0] = v->point[0]; + mmp[1][1] = v->point[1]; + } + } while ((v = v->next) != a->contours->head); + Vcpy2(p, mmp[minmax]); + /* add clearance in the right direction */ + clearance *= 0.707123; /* = cos(45) = sqrt(2)/2 */ + p[0] += ckx * clearance; + p[1] += cky * clearance; + /* now create a tangent line to that point */ + Vcpy2(q, p); + p[0] += -extra; + p[1] += -extra * dq; + q[0] += extra; + q[1] += extra * dq; + } + } +} + +/* Given a 'side' from the JNORTH/JSOUTH/etc enum, rotate it by n. */ +static int rotateSide(int side, int n) +{ + return (side + n + 8) % 8; +} + +/* Wrapper for CreateNewLineOnLayer that takes vectors and deals with Undo */ +static pcb_line_t *Createpcb_vector_tLineOnLayer(pcb_layer_t * layer, rnd_vector_t a, rnd_vector_t b, int thickness, int clearance, pcb_flag_t flags) +{ + pcb_line_t *line; + + line = pcb_line_new(layer, a[0], a[1], b[0], b[1], thickness, clearance, flags); + if (line) { + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, layer, line, line); + } + return line; +} + +static pcb_line_t *MakeBypassLine(pcb_layer_t * layer, rnd_vector_t a, rnd_vector_t b, pcb_line_t * orig, rnd_polyarea_t ** expandp) +{ + pcb_line_t *line; + + line = Createpcb_vector_tLineOnLayer(layer, a, b, orig->Thickness, orig->Clearance, orig->Flags); + if (line && expandp) { + rnd_polyarea_t *p = pcb_poly_from_pcb_line(line, line->Thickness + line->Clearance); + rnd_polyarea_boolean_free(*expandp, p, expandp, RND_PBO_UNITE); + } + return line; +} + +/* Given a 'brush' that's pushing things out of the way (possibly already + * cut down to just the part relevant to our line) and a line that + * intersects it on some layer, find the 45/90 lines required to go around + * the brush on the named side. Create them and remove the original. + * + * Imagine side = north: + / \ + ----b##FLAT##c---- + Q P + lA-ORIG####a d####ORIG-lB + / \ + * First find the extended three lines that go around the brush. + * Then intersect them with each other and the original to find + * points a, b, c, d. Finally connect the dots and remove the + * old straight line. */ +static int MakeBypassingLines(rnd_polyarea_t * brush, pcb_layer_t * layer, pcb_line_t * line, int side, rnd_polyarea_t ** expandp) +{ + rnd_vector_t pA, pB, flatA, flatB, qA, qB; + rnd_vector_t lA, lB; + rnd_vector_t a, b, c, d, junk; + int hits; + + PCB_FLAG_SET(PCB_FLAG_DRC, line); /* will cause sublines to inherit */ + lA[0] = line->Point1.X; + lA[1] = line->Point1.Y; + lB[0] = line->Point2.X; + lB[1] = line->Point2.Y; + + pcb_polyarea_t_findXmostLine(brush, side, flatA, flatB, line->Thickness / 2); + pcb_polyarea_t_findXmostLine(brush, rotateSide(side, 1), pA, pB, line->Thickness / 2); + pcb_polyarea_t_findXmostLine(brush, rotateSide(side, -1), qA, qB, line->Thickness / 2); + hits = rnd_vect_inters2(lA, lB, qA, qB, a, junk) + + rnd_vect_inters2(qA, qB, flatA, flatB, b, junk) + + rnd_vect_inters2(pA, pB, flatA, flatB, c, junk) + rnd_vect_inters2(lA, lB, pA, pB, d, junk); + if (hits != 4) { + return 0; + } + /* flip the line endpoints to match up with a/b */ + if (rnd_vect_dist2(lA, d) < rnd_vect_dist2(lA, a)) { + Vswp2(lA, lB); + } + MakeBypassLine(layer, lA, a, line, NULL); + MakeBypassLine(layer, a, b, line, expandp); + MakeBypassLine(layer, b, c, line, expandp); + MakeBypassLine(layer, c, d, line, expandp); + MakeBypassLine(layer, d, lB, line, NULL); + pcb_line_destroy(layer, line); + return 1; +} + +struct info { + rnd_box_t box; + rnd_polyarea_t *brush; + pcb_layer_t *layer; + rnd_polyarea_t *smallest; /* after cutting brush with line, the smallest chunk, which we will go around on 'side'. */ + pcb_line_t *line; + int side; + double centroid; /* smallest difference between slices of brush after cutting with line, trying to find the line closest to the centroid to process first */ +}; + +/* Process lines that intersect our 'brush'. */ +static rnd_r_dir_t jostle_callback(const rnd_box_t * targ, void *private) +{ + pcb_line_t *line = (pcb_line_t *) targ; + struct info *info = private; + rnd_polyarea_t *lp, *copy, *tmp, *n, *smallest = NULL; + rnd_vector_t p; + int inside = 0, side, r; + double small, big; + int nocentroid = 0; + + if (PCB_FLAG_TEST(PCB_FLAG_DRC, line)) { + return 0; + } + fprintf(stderr, "hit! %p\n", (void *)line); + p[0] = line->Point1.X; + p[1] = line->Point1.Y; + if (rnd_poly_contour_inside(info->brush->contours, p)) { + rnd_fprintf(stderr, "\tinside1 %ms,%ms\n", p[0], p[1]); + inside++; + } + p[0] = line->Point2.X; + p[1] = line->Point2.Y; + if (rnd_poly_contour_inside(info->brush->contours, p)) { + rnd_fprintf(stderr, "\tinside2 %ms,%ms\n", p[0], p[1]); + inside++; + } + lp = pcb_poly_from_pcb_line(line, line->Thickness); + if (!rnd_polyarea_touching(lp, info->brush)) { + /* not a factor */ + return 0; + } + rnd_polyarea_free(&lp); + if (inside) { + /* XXX not done! + XXX if this is part of a series of lines passing + XXX through, need to process as a group. + XXX if it just ends in here, shorten it?? */ + return 0; + } + /* + * Cut the brush with the line to figure out which side to go + * around. Use a very fine line. XXX can still graze. + */ + lp = pcb_poly_from_pcb_line(line, 1); + if (!rnd_polyarea_m_copy0(©, info->brush)) + return 0; + r = rnd_polyarea_boolean_free(copy, lp, &tmp, RND_PBO_SUB); + if (r != rnd_err_ok) { + rnd_fprintf(stderr, "Error while jostling RND_PBO_SUB: %d\n", r); + return 0; + } + if (tmp == tmp->f) { + /* it didn't slice, must have glanced. intersect instead + * to get the glancing sliver?? + */ + rnd_fprintf(stderr, "try isect??\n"); + lp = pcb_poly_from_pcb_line(line, line->Thickness); + r = rnd_polyarea_boolean_free(tmp, lp, &tmp, RND_PBO_ISECT); + if (r != rnd_err_ok) { + fprintf(stderr, "Error while jostling RND_PBO_ISECT: %d\n", r); + return 0; + } + nocentroid = 1; + } + /* XXX if this operation did not create two chunks, bad things are about to happen */ + if (!tmp) + return 0; + n = tmp; + small = big = tmp->contours->area; + do { + rnd_fprintf(stderr, "\t\tarea %g, %ms,%ms %ms,%ms\n", n->contours->area, n->contours->xmin, n->contours->ymin, + n->contours->xmax, n->contours->ymax); + if (n->contours->area <= small) { + smallest = n; + small = n->contours->area; + } + if (n->contours->area >= big) { + big = n->contours->area; + } + } while ((n = n->f) != tmp); + if (line->Point1.X == line->Point2.X) { /* | */ + if (info->box.X2 - smallest->contours->xmax > smallest->contours->xmin - info->box.X1) { + side = JWEST; + } + else { + side = JEAST; + } + } + else if (line->Point1.Y == line->Point2.Y) { /* - */ + if (info->box.Y2 - smallest->contours->ymax > smallest->contours->ymin - info->box.Y1) { + side = JNORTH; + } + else { + side = JSOUTH; + } + } + else if ((line->Point1.X > line->Point2.X) == (line->Point1.Y > line->Point2.Y)) { /* \ */ + if (info->box.X2 - smallest->contours->xmax > smallest->contours->xmin - info->box.X1) { + side = JSOUTHWEST; + } + else { + side = JNORTHEAST; + } + } + else { /* / */ + if (info->box.X2 - smallest->contours->xmax > smallest->contours->xmin - info->box.X1) { + side = JNORTHWEST; + } + else { + side = JSOUTHEAST; + } + } + rnd_fprintf(stderr, "\t%s\n", dirnames[side]); + if (info->line == NULL || (!nocentroid && (big - small) < info->centroid)) { + rnd_fprintf(stderr, "\tkeep it!\n"); + if (info->smallest) { + rnd_polyarea_free(&info->smallest); + } + info->centroid = nocentroid ? DBL_MAX : (big - small); + info->side = side; + info->line = line; + info->smallest = smallest; + return 1; + } + return 0; +} + +static const char pcb_acts_jostle[] = "Jostle(diameter)"; +static const char pcb_acth_jostle[] = "Make room by moving wires away."; +static fgw_error_t pcb_act_jostle(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_coord_t x, y; + rnd_polyarea_t *expand; + float value = conf_core.design.via_thickness + (conf_core.design.bloat + 1) * 2 + 50; + struct info info; + int found; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, jostle, value = fgw_keyword(&argv[1])); + + x = pcb_crosshair.X; + y = pcb_crosshair.Y; + fprintf(stderr, "%d, %d, %f\n", (int) x, (int) y, value); + info.brush = rnd_poly_from_circle(x, y, value / 2); + info.layer = PCB_CURRLAYER(PCB); + PCB_LINE_LOOP(info.layer); + { + PCB_FLAG_CLEAR(PCB_FLAG_DRC, line); + } + PCB_END_LOOP; + do { + info.box = pcb_polyarea_t_boundingBox(info.brush); + Debugpcb_polyarea_t(info.brush, NULL); + rnd_fprintf(stderr, "search (%ms,%ms)->(%ms,%ms):\n", info.box.X1, info.box.Y1, info.box.X2, info.box.Y2); + info.line = NULL; + info.smallest = NULL; + rnd_r_search(info.layer->line_tree, &info.box, NULL, jostle_callback, &info, &found); + if (found) { + expand = NULL; + MakeBypassingLines(info.smallest, info.layer, info.line, info.side, &expand); + rnd_polyarea_free(&info.smallest); + rnd_polyarea_boolean_free(info.brush, expand, &info.brush, RND_PBO_UNITE); + } + } while (found); + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + pcb_undo_inc_serial(); + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t jostle_action_list[] = { + {"jostle", pcb_act_jostle, pcb_acth_jostle, pcb_acts_jostle} +}; + +char *jostle_cookie = "jostle plugin"; + +int pplg_check_ver_jostle(int ver_needed) { return 0; } + +void pplg_uninit_jostle(void) +{ + rnd_remove_actions_by_cookie(jostle_cookie); +} + +int pplg_init_jostle(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(jostle_action_list, jostle_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/jostle/jostle.pup =================================================================== --- tags/2.3.0/src_plugins/jostle/jostle.pup (nonexistent) +++ tags/2.3.0/src_plugins/jostle/jostle.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short push lines out of the way +$long Pushes lines out of the way. +$state works +$package extra +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/lib_compat_help/Makefile =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_lib_compat_help + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/lib_compat_help/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {lib_compat_help} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/lib_compat_help/lib_compat_help.o + $(PLUGDIR)/lib_compat_help/media.o +@] + +switch /local/pcb/lib_compat_help/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/lib_compat_help/elem_rot.c =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/elem_rot.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/elem_rot.c (revision 33253) @@ -0,0 +1,250 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * + * (This file was part of the original PCB source on the import, as bom.c, + * but did not have a copyright banner. The names of the original authors + * potentially can be found in the old CVS.) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "elem_rot.h" +#include "conf_core.h" +#include "data_it.h" + +static const int verbose_rot = 0; + +/* In order of preference. + * Includes numbered and BGA pins. + * Possibly BGA pins can be missing, so we add a few to try. */ +#define MAXREFPINS 32 /* max length of following list */ +static char *reference_pin_names[] = {"1", "2", "A1", "A2", "B1", "B2", 0}; + +static double xyToAngle(double x, double y, rnd_bool morethan2pins) +{ + double d = atan2(-y, x) * 180.0 / M_PI; + + if (verbose_rot) + rnd_trace(" xyToAngle: %f %f %d ->%f\n", x, y, morethan2pins, d); + + /* IPC 7351 defines different rules for 2 pin elements */ + if (morethan2pins) { + /* Multi pin case: + * Output 0 degrees if pin1 in is top left or top, i.e. between angles of + * 80 to 170 degrees. + * Pin #1 can be at dead top (e.g. certain PLCCs) or anywhere in the top + * left. + */ + if (d < -100) + return 90; /* -180 to -100 */ + else if (d < -10) + return 180; /* -100 to -10 */ + else if (d < 80) + return 270; /* -10 to 80 */ + else if (d < 170) + return 0; /* 80 to 170 */ + else + return 90; /* 170 to 180 */ + } + else { + /* 2 pin element: + * Output 0 degrees if pin #1 is in top left or left, i.e. in sector + * between angles of 95 and 185 degrees. + */ + if (d < -175) + return 0; /* -180 to -175 */ + else if (d < -85) + return 90; /* -175 to -85 */ + else if (d < 5) + return 180; /* -85 to 5 */ + else if (d < 95) + return 270; /* 5 to 95 */ + else + return 0; /* 95 to 180 */ + } +} + +void pcb_subc_xy_rot(pcb_subc_t *subc, rnd_coord_t *cx, rnd_coord_t *cy, double *theta, double *xray_theta, rnd_bool autodetect) +{ + double centroidx, centroidy; + int found_any_not_at_centroid, found_any, rpindex; + double sumx, sumy; + double pin1x = 0.0, pin1y = 0.0; + int pin_cnt, bott = 0; + int pinfound[MAXREFPINS]; + double pinx[MAXREFPINS]; + double piny[MAXREFPINS]; + const char *fixed_rotation; + rnd_coord_t ox = 0, oy = 0; + pcb_any_obj_t *o; + pcb_data_it_t it; + + memset(pinfound, 0, sizeof(pinfound)); + + if (!autodetect) { + if (pcb_subc_get_origin(subc, &ox, &oy) != 0) + rnd_message(RND_MSG_ERROR, "pcb_subc_xy_rot(): can't get subc origin for %s\n", subc->refdes); + + if (pcb_subc_get_side(subc, &bott) != 0) + rnd_message(RND_MSG_ERROR, "pcb_subc_xy_rot(): can't get subc side for %s\n", subc->refdes); + } + + /* initialize our pin count and our totals for finding the + centriod */ + pin_cnt = 0; + sumx = 0.0; + sumy = 0.0; + + /* + * iterate over the pins and pads keeping a running count of how + * many pins/pads total and the sum of x and y coordinates + * + * While we're at it, store the location of pin/pad #1 and #2 if + * we can find them + */ + for(o = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + rnd_coord_t px, py; + + if (o->term == NULL) + continue; + + if (o->type == PCB_OBJ_PSTK) { + px = ((pcb_pstk_t *)o)->x; + py = ((pcb_pstk_t *)o)->y; + } + else { + px = (o->BoundingBox.X1 + o->BoundingBox.X2) / 2; + py = (o->BoundingBox.Y1 + o->BoundingBox.Y2) / 2; + } + + sumx += (double)px; + sumy += (double)py; + pin_cnt++; + + for (rpindex = 0; reference_pin_names[rpindex]; rpindex++) { + if (RND_NSTRCMP(o->term, reference_pin_names[rpindex]) == 0) { + pinx[rpindex] = (double)px; + piny[rpindex] = (double)py; + pinfound[rpindex] = 1; + } + } + } + + if (pin_cnt > 0) { + centroidx = sumx / (double) pin_cnt; + centroidy = sumy / (double) pin_cnt; + + if (!autodetect && (RND_NSTRCMP(pcb_attribute_get(&subc->Attributes, "xy-centre"), "origin") == 0)) { + *cx = ox; + *cy = oy; + } + else { + *cx = centroidx; + *cy = centroidy; + } + + fixed_rotation = pcb_attribute_get(&subc->Attributes, "xy-fixed-rotation"); + if (fixed_rotation != NULL) { + /* The user specified a fixed rotation */ + *theta = atof(fixed_rotation); + found_any_not_at_centroid = 1; + found_any = 1; + } + else { + /* Find first reference pin not at the centroid */ + found_any_not_at_centroid = 0; + found_any = 0; + *theta = 0.0; + for (rpindex = 0; reference_pin_names[rpindex] && !found_any_not_at_centroid; rpindex++) { + if (pinfound[rpindex]) { + found_any = 1; + + /* Recenter pin "#1" onto the axis which cross at the part + centroid */ + pin1x = pinx[rpindex] - *cx; + pin1y = piny[rpindex] - *cy; + + if (verbose_rot) + rnd_trace("\npcb_subc_xy_rot: %s pin_cnt=%d pin1x=%d pin1y=%d\n", RND_UNKNOWN(subc->refdes), pin_cnt, pin1x, pin1y); + + /* if only 1 pin, we are doomed */ + if (pin_cnt == 1) { + *theta = 0; + found_any_not_at_centroid = 1; + } + else { + if ((pin1x != 0.0) || (pin1y != 0.0)) + *xray_theta = xyToAngle(pin1x, pin1y, pin_cnt > 2); + + /* flip x, to reverse rotation for elements on back */ + if (bott) + pin1x = -pin1x; + + if ((pin1x != 0.0) || (pin1y != 0.0)) { + *theta = xyToAngle(pin1x, pin1y, pin_cnt > 2); + found_any_not_at_centroid = 1; + } + } + if (verbose_rot) + rnd_trace(" ->theta=%f\n", *theta); + } + } + + if (!found_any) { + rnd_message + (RND_MSG_WARNING, "pcb_subc_xy_rot: unable to figure out angle because I could\n" + " not find a suitable reference pin of element %s\n" + " Setting to %g degrees\n", RND_UNKNOWN(subc->refdes), *theta); + } + else if (!found_any_not_at_centroid) { + rnd_message + (RND_MSG_WARNING, "pcb_subc_xy_rot: unable to figure out angle of element\n" + " %s because the reference pin(s) are at the centroid of the part.\n" + " Setting to %g degrees\n", RND_UNKNOWN(subc->refdes), *theta); + } + } + } +} + +void pcb_subc_xy_rot_pnp(pcb_subc_t *subc, rnd_coord_t subc_ox, rnd_coord_t subc_oy, rnd_bool on_bottom) +{ + rnd_coord_t cx = subc_ox, cy = subc_oy; + double rot = 0.0, tmp; + const char *cent; + + pcb_subc_xy_rot(subc, &cx, &cy, &rot, &tmp, 1); + + /* unless xy-centre or pnp-centre is set to origin, place a pnp origin mark */ + cent = pcb_attribute_get(&subc->Attributes, "xy-centre"); + if (cent == NULL) + cent = pcb_attribute_get(&subc->Attributes, "pnp-centre"); + if ((cent == NULL) || (strcmp(cent, "origin") != 0)) + pcb_subc_create_aux_point(subc, cx, cy, "pnp-origin"); + + /* add the base vector at the origin imported, but with the rotation + reverse engineered: the original element format does have an explicit + origin but no rotation info */ + pcb_subc_create_aux(subc, subc_ox, subc_oy, rot, on_bottom); +} + Index: tags/2.3.0/src_plugins/lib_compat_help/elem_rot.h =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/elem_rot.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/elem_rot.h (revision 33253) @@ -0,0 +1,5 @@ +void pcb_subc_xy_rot(pcb_subc_t *subc, rnd_coord_t *cx, rnd_coord_t *cy, double *theta, double *xray_theta, rnd_bool autodetect); + +/* Automatic version of pcb_subc_xy_rot: inserts all the p&p attributes and creates the aux layer */ +void pcb_subc_xy_rot_pnp(pcb_subc_t *subc, rnd_coord_t subc_ox, rnd_coord_t subc_oy, rnd_bool on_bottom); + Index: tags/2.3.0/src_plugins/lib_compat_help/layer_compat.c =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/layer_compat.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/layer_compat.c (revision 33253) @@ -0,0 +1,87 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2004,2006 Thomas Nau + * Copyright (C) 2016, 2017 Tibor 'Igor2' Palinkas (pcb-rnd extensions) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include "layer_compat.h" +#include "pstk_compat.h" + +#include "board.h" +#include "data.h" + +static void swap_one_thermal(pcb_pstk_t *pstk, int lid1, int lid2, int udoable) +{ + unsigned char *p1 = pcb_pstk_get_thermal(pstk, lid1, 0); + unsigned char *p2 = pcb_pstk_get_thermal(pstk, lid2, 0); + unsigned char t1, t2; + + t1 = (p1 == NULL) ? 0 : *p1; + t2 = (p2 == NULL) ? 0 : *p2; + + if (t1 == t2) return; + + pcb_pstk_set_thermal(pstk, lid1, t2, udoable); + pcb_pstk_set_thermal(pstk, lid2, t1, udoable); +} + +int pcb_layer_swap(pcb_board_t *pcb, rnd_layer_id_t lid1, rnd_layer_id_t lid2) +{ + rnd_rtree_it_t it; + pcb_layer_t l1tmp, l2tmp; + rnd_layergrp_id_t gid; + rnd_box_t *n; + + if (lid1 == lid2) + return 0; + + pcb_layer_move_(&l1tmp, &pcb->Data->Layer[lid1]); + pcb_layer_move_(&l2tmp, &pcb->Data->Layer[lid2]); + + pcb_layer_move_(&pcb->Data->Layer[lid1], &l2tmp); + pcb_layer_move_(&pcb->Data->Layer[lid2], &l1tmp); + + /* thermals are referenced by layer IDs which are going to change now */ + for(n = rnd_r_first(pcb->Data->padstack_tree, &it); n != NULL; n = rnd_r_next(&it)) + swap_one_thermal((pcb_pstk_t *)n, lid1, lid2, 0); + + for(gid = 0; gid < pcb_max_group(pcb); gid++) { + pcb_layergrp_t *g = &pcb->LayerGroups.grp[gid]; + int n; + + for(n = 0; n < g->len; n++) { + if (g->lid[n] == lid1) + g->lid[n] = lid2; + else if (g->lid[n] == lid2) + g->lid[n] = lid1; + } + } + + return 0; +} + Index: tags/2.3.0/src_plugins/lib_compat_help/layer_compat.h =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/layer_compat.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/layer_compat.h (revision 33253) @@ -0,0 +1,39 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,2004,2006 Thomas Nau + * Copyright (C) 2016, 2017 Tibor 'Igor2' Palinkas (pcb-rnd extensions) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_LAYER_COMPAT_H +#define PCB_LAYER_COMPAT_H + +#include "layer.h" + + +/* Swap two layers in pcb; useful only in writing the old .pcb format, + because silk layers must be the last 2 layers there */ +int pcb_layer_swap(pcb_board_t *pcb, rnd_layer_id_t lid1, rnd_layer_id_t lid2); +#endif Index: tags/2.3.0/src_plugins/lib_compat_help/lib_compat_help.c =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/lib_compat_help.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/lib_compat_help.c (revision 33253) @@ -0,0 +1,20 @@ +#include +#include + +#include "layer_compat.c" +#include "pstk_compat.c" +#include "pstk_help.c" +#include "subc_help.c" +#include "elem_rot.c" + +int pplg_check_ver_lib_compat_help(int ver_needed) { return 0; } + +void pplg_uninit_lib_compat_help(void) +{ +} + +int pplg_init_lib_compat_help(void) +{ + RND_API_CHK_VER; + return 0; +} Index: tags/2.3.0/src_plugins/lib_compat_help/lib_compat_help.pup =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/lib_compat_help.pup (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/lib_compat_help.pup (revision 33253) @@ -0,0 +1,7 @@ +$class lib +$short #compatibility helper functions +$long a library of functions providing a simplified API compatibility layer, mainly for I/O plugins +$state works +$package (core) +#default disable-all +default buildin Index: tags/2.3.0/src_plugins/lib_compat_help/media.c =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/media.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/media.c (revision 33253) @@ -0,0 +1,124 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Media (paper) sizes; moved from export_ps */ + +#include "config.h" +#include + +#include + +#include "media.h" + +/* + * Metric ISO sizes in mm. See http://en.wikipedia.org/wiki/ISO_paper_sizes + * + * A0 841 x 1189 + * A1 594 x 841 + * A2 420 x 594 + * A3 297 x 420 + * A4 210 x 297 + * A5 148 x 210 + * A6 105 x 148 + * A7 74 x 105 + * A8 52 x 74 + * A9 37 x 52 + * A10 26 x 37 + * + * B0 1000 x 1414 + * B1 707 x 1000 + * B2 500 x 707 + * B3 353 x 500 + * B4 250 x 353 + * B5 176 x 250 + * B6 125 x 176 + * B7 88 x 125 + * B8 62 x 88 + * B9 44 x 62 + * B10 31 x 44 + * + * awk '{printf(" {\"%s\", %d, %d, MARGINX, MARGINY},\n", $2, $3*100000/25.4, $5*100000/25.4)}' + * + * See http://en.wikipedia.org/wiki/Paper_size#Loose_sizes for some of the other sizes. The + * {A,B,C,D,E}-Size here are the ANSI sizes and not the architectural sizes. + */ + +#define MARGINX RND_MIL_TO_COORD(500) +#define MARGINY RND_MIL_TO_COORD(500) + +pcb_media_t pcb_media_data[] = { + {"A0", RND_MM_TO_COORD(841), RND_MM_TO_COORD(1189), MARGINX, MARGINY}, + {"A1", RND_MM_TO_COORD(594), RND_MM_TO_COORD(841), MARGINX, MARGINY}, + {"A2", RND_MM_TO_COORD(420), RND_MM_TO_COORD(594), MARGINX, MARGINY}, + {"A3", RND_MM_TO_COORD(297), RND_MM_TO_COORD(420), MARGINX, MARGINY}, + {"A4", RND_MM_TO_COORD(210), RND_MM_TO_COORD(297), MARGINX, MARGINY}, + {"A5", RND_MM_TO_COORD(148), RND_MM_TO_COORD(210), MARGINX, MARGINY}, + {"A6", RND_MM_TO_COORD(105), RND_MM_TO_COORD(148), MARGINX, MARGINY}, + {"A7", RND_MM_TO_COORD(74), RND_MM_TO_COORD(105), MARGINX, MARGINY}, + {"A8", RND_MM_TO_COORD(52), RND_MM_TO_COORD(74), MARGINX, MARGINY}, + {"A9", RND_MM_TO_COORD(37), RND_MM_TO_COORD(52), MARGINX, MARGINY}, + {"A10", RND_MM_TO_COORD(26), RND_MM_TO_COORD(37), MARGINX, MARGINY}, + {"B0", RND_MM_TO_COORD(1000), RND_MM_TO_COORD(1414), MARGINX, MARGINY}, + {"B1", RND_MM_TO_COORD(707), RND_MM_TO_COORD(1000), MARGINX, MARGINY}, + {"B2", RND_MM_TO_COORD(500), RND_MM_TO_COORD(707), MARGINX, MARGINY}, + {"B3", RND_MM_TO_COORD(353), RND_MM_TO_COORD(500), MARGINX, MARGINY}, + {"B4", RND_MM_TO_COORD(250), RND_MM_TO_COORD(353), MARGINX, MARGINY}, + {"B5", RND_MM_TO_COORD(176), RND_MM_TO_COORD(250), MARGINX, MARGINY}, + {"B6", RND_MM_TO_COORD(125), RND_MM_TO_COORD(176), MARGINX, MARGINY}, + {"B7", RND_MM_TO_COORD(88), RND_MM_TO_COORD(125), MARGINX, MARGINY}, + {"B8", RND_MM_TO_COORD(62), RND_MM_TO_COORD(88), MARGINX, MARGINY}, + {"B9", RND_MM_TO_COORD(44), RND_MM_TO_COORD(62), MARGINX, MARGINY}, + {"B10", RND_MM_TO_COORD(31), RND_MM_TO_COORD(44), MARGINX, MARGINY}, + {"Letter", RND_INCH_TO_COORD(8.5), RND_INCH_TO_COORD(11), MARGINX, MARGINY}, + {"USLetter", RND_INCH_TO_COORD(8.5), RND_INCH_TO_COORD(11), MARGINX, MARGINY}, /* kicad */ + {"11x17", RND_INCH_TO_COORD(11), RND_INCH_TO_COORD(17), MARGINX, MARGINY}, + {"Ledger", RND_INCH_TO_COORD(17), RND_INCH_TO_COORD(11), MARGINX, MARGINY}, + {"Legal", RND_INCH_TO_COORD(8.5), RND_INCH_TO_COORD(14), MARGINX, MARGINY}, + {"Executive", RND_INCH_TO_COORD(7.5), RND_INCH_TO_COORD(10), MARGINX, MARGINY}, + {"A-size", RND_INCH_TO_COORD(8.5), RND_INCH_TO_COORD(11), MARGINX, MARGINY}, + {"B-size", RND_INCH_TO_COORD(11), RND_INCH_TO_COORD(17), MARGINX, MARGINY}, + {"C-size", RND_INCH_TO_COORD(17), RND_INCH_TO_COORD(22), MARGINX, MARGINY}, + {"D-size", RND_INCH_TO_COORD(22), RND_INCH_TO_COORD(34), MARGINX, MARGINY}, + {"E-size", RND_INCH_TO_COORD(34), RND_INCH_TO_COORD(44), MARGINX, MARGINY}, + {"US-Business_Card", RND_INCH_TO_COORD(3.5), RND_INCH_TO_COORD(2.0), 0, 0}, + {"Intl-Business_Card", RND_INCH_TO_COORD(3.375), RND_INCH_TO_COORD(2.125), 0, 0}, + {NULL, 0, 0, 0, 0}, +}; + +/* MUST BE IN SYNC with the above table */ +const char *pcb_medias[] = { + "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10", + "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B10", + "Letter", "USLetter", "11x17", "Ledger", "Legal", "Executive", + "A-Size", "B-size", "C-Size", "D-size", "E-size", + "US-Business_Card", "Intl-Business_Card", + NULL +}; + +#undef MARGINX +#undef MARGINY Index: tags/2.3.0/src_plugins/lib_compat_help/media.h =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/media.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/media.h (revision 33253) @@ -0,0 +1,9 @@ +typedef struct { + const char *name; + rnd_coord_t width, height; /* orientation: landscape */ + rnd_coord_t margin_x, margin_y; +} pcb_media_t; + +extern pcb_media_t pcb_media_data[]; +extern const char *pcb_medias[]; + Index: tags/2.3.0/src_plugins/lib_compat_help/pstk_compat.c =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/pstk_compat.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/pstk_compat.c (revision 33253) @@ -0,0 +1,814 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include "pstk_compat.h" +#include "obj_pstk_inlines.h" +#include +#include + +#include "plug_io.h" + +#define sqr(o) ((double)(o)*(double)(o)) + +/* set up x and y multiplier for an octa poly, depending on square pin style + (used in early versions of pcb-rnd, before custom shape padstacks) */ +void rnd_poly_square_pin_factors(int style, double *xm, double *ym) +{ + int i; + const double factor = 2.0; + + /* reset multipliers */ + for (i = 0; i < 8; i++) { + xm[i] = 1; + ym[i] = 1; + } + + style--; + if (style & 1) + xm[0] = xm[1] = xm[6] = xm[7] = factor; + if (style & 2) + xm[2] = xm[3] = xm[4] = xm[5] = factor; + if (style & 4) + ym[4] = ym[5] = ym[6] = ym[7] = factor; + if (style & 8) + ym[0] = ym[1] = ym[2] = ym[3] = factor; +} + +/* emulate old pcb-rnd "pin shape" feature */ +static void octa_shape(pcb_pstk_poly_t *dst, rnd_coord_t x0, rnd_coord_t y0, rnd_coord_t rx, rnd_coord_t ry, int style) +{ + double xm[8], ym[8]; + + pcb_pstk_shape_alloc_poly(dst, 8); + + rnd_poly_square_pin_factors(style, xm, ym); + + dst->x[7] = x0 + rnd_round(rx * 0.5) * xm[7]; + dst->y[7] = y0 + rnd_round(ry * RND_TAN_22_5_DEGREE_2) * ym[7]; + dst->x[6] = x0 + rnd_round(rx * RND_TAN_22_5_DEGREE_2) * xm[6]; + dst->y[6] = y0 + rnd_round(ry * 0.5) * ym[6]; + dst->x[5] = x0 - rnd_round(rx * RND_TAN_22_5_DEGREE_2) * xm[5]; + dst->y[5] = y0 + rnd_round(ry * 0.5) * ym[5]; + dst->x[4] = x0 - rnd_round(rx * 0.5) * xm[4]; + dst->y[4] = y0 + rnd_round(ry * RND_TAN_22_5_DEGREE_2) * ym[4]; + dst->x[3] = x0 - rnd_round(rx * 0.5) * xm[3]; + dst->y[3] = y0 - rnd_round(ry * RND_TAN_22_5_DEGREE_2) * ym[3]; + dst->x[2] = x0 - rnd_round(rx * RND_TAN_22_5_DEGREE_2) * xm[2]; + dst->y[2] = y0 - rnd_round(ry * 0.5) * ym[2]; + dst->x[1] = x0 + rnd_round(rx * RND_TAN_22_5_DEGREE_2) * xm[1]; + dst->y[1] = y0 - rnd_round(ry * 0.5) * ym[1]; + dst->x[0] = x0 + rnd_round(rx * 0.5) * xm[0]; + dst->y[0] = y0 - rnd_round(ry * RND_TAN_22_5_DEGREE_2) * ym[0]; +} + +/* emulate the old 'square flag' feature */ +static void square_shape(pcb_pstk_poly_t *dst, rnd_coord_t x0, rnd_coord_t y0, rnd_coord_t radius, int style) +{ + rnd_coord_t r2 = rnd_round(radius * 0.5); + + pcb_pstk_shape_alloc_poly(dst, 4); + + dst->x[0] = x0 - r2; dst->y[0] = y0 - r2; + dst->x[1] = x0 + r2; dst->y[1] = y0 - r2; + dst->x[2] = x0 + r2; dst->y[2] = y0 + r2; + dst->x[3] = x0 - r2; dst->y[3] = y0 + r2; +} + + +static int compat_via_shape_gen(pcb_pstk_shape_t *dst, pcb_pstk_compshape_t cshape, rnd_coord_t pad_dia) +{ + if ((cshape >= PCB_PSTK_COMPAT_SHAPED) && (cshape <= PCB_PSTK_COMPAT_SHAPED_END)) { + dst->shape = PCB_PSSH_POLY; + octa_shape(&dst->data.poly, 0, 0, pad_dia, pad_dia, cshape); + return 0; + } + + switch(cshape) { + case PCB_PSTK_COMPAT_ROUND: + dst->shape = PCB_PSSH_CIRC; + dst->data.circ.x = dst->data.circ.y = 0; + dst->data.circ.dia = pad_dia; + break; + case PCB_PSTK_COMPAT_SQUARE: + /* using a zero-length line is not a good idea here as rotation wouldn't affect it */ + dst->shape = PCB_PSSH_POLY; + square_shape(&dst->data.poly, 0, 0, pad_dia, 1); + break; + case PCB_PSTK_COMPAT_OCTAGON: + dst->shape = PCB_PSSH_POLY; + octa_shape(&dst->data.poly, 0, 0, pad_dia, pad_dia, 1); + break; + default: + return -1; + } + return 0; +} + +static void compat_shape_free(pcb_pstk_shape_t *shp) +{ + if (shp->shape == PCB_PSSH_POLY) + free(shp->data.poly.x); +} + +static pcb_pstk_t *pcb_pstk_new_compat_via_(pcb_data_t *data, long int id, rnd_coord_t x, rnd_coord_t y, rnd_coord_t drill_dia, rnd_coord_t pad_dia, rnd_coord_t clearance, rnd_coord_t mask, pcb_pstk_compshape_t cshape, rnd_bool plated, rnd_bool hole_clearance_hack) +{ + pcb_pstk_proto_t proto; + pcb_pstk_shape_t shape[5]; /* max number of shapes: 3 coppers, 2 masks */ + rnd_cardinal_t pid; + pcb_pstk_shape_t copper_master, mask_master; + pcb_pstk_tshape_t tshp; + int n; + + if (hole_clearance_hack && !plated) { + /* in PCB hole means unplated with clearance; emulate this by placing a + zero diameter copper circle on all layers and set clearance large + enough to cover the hole too */ + clearance = rnd_round((double)clearance + (double)drill_dia/2.0); + pad_dia = 0.0; + } + + /* for plated vias, positive pad is required */ + if (plated && !hole_clearance_hack) + assert(pad_dia > drill_dia); + + assert(drill_dia > 0); + assert(clearance >= 0); + assert(mask >= 0); + + memset(&proto, 0, sizeof(proto)); + memset(&tshp, 0, sizeof(tshp)); + memset(&copper_master, 0, sizeof(copper_master)); + memset(&mask_master, 0, sizeof(mask_master)); + + tshp.shape = shape; + proto.tr.alloced = proto.tr.used = 1; /* has the canonical form only */ + proto.tr.array = &tshp; + + if (plated || hole_clearance_hack) { + tshp.len = 3 + (mask > 0 ? 2 : 0); + + /* we need to generate the shape only once as it's the same on all */ + if (compat_via_shape_gen(&copper_master, cshape, pad_dia) != 0) + return NULL; + + for(n = 0; n < 3; n++) + memcpy(&shape[n], &copper_master, sizeof(copper_master)); + shape[0].layer_mask = PCB_LYT_COPPER | PCB_LYT_TOP; shape[0].comb = 0; + shape[1].layer_mask = PCB_LYT_COPPER | PCB_LYT_BOTTOM; shape[1].comb = 0; + shape[2].layer_mask = PCB_LYT_COPPER | PCB_LYT_INTERN; shape[2].comb = 0; + tshp.len = 3; + } + else + tshp.len = 0; + + if (mask > 0) { + if (compat_via_shape_gen(&mask_master, cshape, mask) != 0) + return NULL; + + memcpy(&shape[tshp.len+0], &mask_master, sizeof(mask_master)); + memcpy(&shape[tshp.len+1], &mask_master, sizeof(mask_master)); + shape[tshp.len+0].layer_mask = PCB_LYT_MASK | PCB_LYT_TOP; shape[tshp.len+0].comb = PCB_LYC_SUB + PCB_LYC_AUTO; + shape[tshp.len+1].layer_mask = PCB_LYT_MASK | PCB_LYT_BOTTOM; shape[tshp.len+1].comb = PCB_LYC_SUB + PCB_LYC_AUTO; + tshp.len += 2; + } + + proto.hdia = drill_dia; + proto.hplated = plated; + + pcb_pstk_proto_update(&proto); + pid = pcb_pstk_proto_insert_dup(data, &proto, 1, 0); + if (pid == PCB_PADSTACK_INVALID) { + compat_shape_free(&copper_master); + return NULL; + } + + compat_shape_free(&copper_master); + + if (mask > 0) + compat_shape_free(&mask_master); + + return pcb_pstk_new(data, -1, pid, x, y, clearance, pcb_flag_make(PCB_FLAG_CLEARLINE)); +} + +pcb_pstk_t *pcb_pstk_new_compat_via(pcb_data_t *data, long int id, rnd_coord_t x, rnd_coord_t y, rnd_coord_t drill_dia, rnd_coord_t pad_dia, rnd_coord_t clearance, rnd_coord_t mask, pcb_pstk_compshape_t cshape, rnd_bool plated) +{ + return pcb_pstk_new_compat_via_(data, id, x, y, drill_dia, pad_dia, clearance, mask, cshape, plated, 0); +} + + +static pcb_pstk_compshape_t get_old_shape_square(rnd_coord_t *dia, const pcb_pstk_shape_t *shp) +{ + double sq, len2, l, a; + int n; + + sq = sqr(shp->data.poly.x[0] - shp->data.poly.x[2]) + sqr(shp->data.poly.y[0] - shp->data.poly.y[2]); + /* cross-bars must be of equal length */ + if (sq != sqr(shp->data.poly.x[1] - shp->data.poly.x[3]) + sqr(shp->data.poly.y[1] - shp->data.poly.y[3])) + return PCB_PSTK_COMPAT_INVALID; + + /* all sides must be of equal length */ + len2 = fabs(sqr(shp->data.poly.x[3] - shp->data.poly.x[0]) + sqr(shp->data.poly.y[3] - shp->data.poly.y[0])); + for(n = 0; n < 3; n++) { + l = fabs(sqr(shp->data.poly.x[n+1] - shp->data.poly.x[n]) + sqr(shp->data.poly.y[n+1] - shp->data.poly.y[n])); + if (fabs(l - len2) > 10) + return PCB_PSTK_COMPAT_INVALID; + } + + /* must be axis aligned */ + a = atan2(shp->data.poly.y[3] - shp->data.poly.y[0], shp->data.poly.x[3] - shp->data.poly.x[0]) * RND_RAD_TO_DEG; + if (fmod(a, 90.0) > 0.1) + return PCB_PSTK_COMPAT_INVALID; + + /* found a valid square */ + *dia = rnd_round(sqrt(sq / 2.0)); + + return PCB_PSTK_COMPAT_SQUARE; +} + + +static pcb_pstk_compshape_t get_old_shape_octa(rnd_coord_t *dia, const pcb_pstk_shape_t *shp) +{ + double x[8], y[8], xm[8], ym[8], minx = 0.0, miny = 0.0, tmp; + int shi, n, found; + + /* collect offsets */ + for(n = 0; n < 8; n++) { + x[n] = shp->data.poly.x[n]; + y[n] = shp->data.poly.y[n]; + } + + /* compensate for the octagon shape */ + x[7] /= 0.5; + y[7] /= RND_TAN_22_5_DEGREE_2; + x[6] /= RND_TAN_22_5_DEGREE_2; + y[6] /= 0.5; + x[5] /= RND_TAN_22_5_DEGREE_2; + y[5] /= 0.5; + x[4] /= 0.5; + y[4] /= RND_TAN_22_5_DEGREE_2; + x[3] /= 0.5; + y[3] /= RND_TAN_22_5_DEGREE_2; + x[2] /= RND_TAN_22_5_DEGREE_2; + y[2] /= 0.5; + x[1] /= RND_TAN_22_5_DEGREE_2; + y[1] /= 0.5; + x[0] /= 0.5; + y[0] /= RND_TAN_22_5_DEGREE_2; + + /* check min distances */ + for(n = 0; n < 8; n++) { + tmp = fabs(x[n]); + if ((minx == 0.0) || (tmp < minx)) + minx = tmp; + tmp = fabs(y[n]); + if ((miny == 0.0) || (tmp < miny)) + miny = tmp; + } + + if ((minx == 0.0) || (miny == 0.0)) + return PCB_PSTK_COMPAT_INVALID; + + if (minx < miny) + miny = minx; + else + minx = miny; + + /* normalize the factors */ + for(n = 0; n < 8; n++) { + x[n] = fabs(x[n] / minx); + y[n] = fabs(y[n] / miny); + if (fabs(x[n] - 1.0) < 0.01) + x[n] = 1.0; + else if (fabs(x[n] - 2.0) < 0.01) + x[n] = 2.0; + else + return PCB_PSTK_COMPAT_INVALID; + if (fabs(y[n] - 1.0) < 0.01) + y[n] = 1.0; + else if (fabs(y[n] - 2.0) < 0.01) + y[n] = 2.0; + else + return PCB_PSTK_COMPAT_INVALID; + } + + /* compare to all known shape factors */ + for(shi = PCB_PSTK_COMPAT_SHAPED; shi <= PCB_PSTK_COMPAT_SHAPED_END; shi++) { + rnd_poly_square_pin_factors(shi - PCB_PSTK_COMPAT_SHAPED, xm, ym); + found = 1; + for(n = 0; n < 8; n++) { + if ((xm[n] != x[n]) || (ym[n] != y[n])) { + found = 0; + break; + } + } + if (found) { + *dia = rnd_round(sqrt((sqr(minx) + sqr(miny)) / 2.0)); + return shi; + } + } + + return PCB_PSTK_COMPAT_INVALID; +} + +static pcb_pstk_compshape_t get_old_shape(rnd_coord_t *dia, const pcb_pstk_shape_t *shp) +{ + switch(shp->shape) { + case PCB_PSSH_LINE: + return PCB_PSTK_COMPAT_INVALID; + case PCB_PSSH_CIRC: + if ((shp->data.circ.x != 0) || (shp->data.circ.x != 0)) + return PCB_PSTK_COMPAT_INVALID; + *dia = shp->data.circ.dia; + return PCB_PSTK_COMPAT_ROUND; + case PCB_PSSH_POLY: + if (shp->data.poly.len == 4) + return get_old_shape_square(dia, shp); + if (shp->data.poly.len == 8) + return get_old_shape_octa(dia, shp); + break; + case PCB_PSSH_HSHADOW: + break; + } + return PCB_PSTK_COMPAT_INVALID; +} + +rnd_bool pcb_pstk_export_compat_via(pcb_pstk_t *ps, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t *drill_dia, rnd_coord_t *pad_dia, rnd_coord_t *clearance, rnd_coord_t *mask, pcb_pstk_compshape_t *cshape, rnd_bool *plated) +{ + pcb_pstk_proto_t *proto; + pcb_pstk_tshape_t *tshp; + int n, coppern = -1, maskn = -1; + pcb_pstk_compshape_t old_shape[5]; + rnd_coord_t old_dia[5]; + + proto = pcb_pstk_get_proto_(ps->parent.data, ps->proto); + if ((proto == NULL) || (proto->tr.used < 1)) + return rnd_false; + + tshp = &proto->tr.array[0]; + + if ((tshp->len != 3) && (tshp->len != 5)) + return rnd_false; /* allow only 3 coppers + optionally 2 masks */ + + for(n = 0; n < tshp->len; n++) { + if (tshp->shape[n].shape != tshp->shape[0].shape) + return rnd_false; /* all shapes must be the same */ + if ((tshp->shape[n].layer_mask & PCB_LYT_ANYWHERE) == 0) + return rnd_false; + if (tshp->shape[n].layer_mask & PCB_LYT_COPPER) { + coppern = n; + continue; + } + if (tshp->shape[n].layer_mask & PCB_LYT_INTERN) + return rnd_false; /* accept only copper as intern */ + if (tshp->shape[n].layer_mask & PCB_LYT_MASK) { + maskn = n; + continue; + } + return rnd_false; /* refuse anything else */ + } + + /* we must have copper shapes */ + if (coppern < 0) + return rnd_false; + + if (tshp->shape[0].shape == PCB_PSSH_POLY) + for(n = 1; n < tshp->len; n++) + if (tshp->shape[n].data.poly.len != tshp->shape[0].data.poly.len) + return rnd_false; /* all polygons must have the same number of corners */ + + for(n = 0; n < tshp->len; n++) { + old_shape[n] = get_old_shape(&old_dia[n], &tshp->shape[n]); + if (old_shape[n] == PCB_PSTK_COMPAT_INVALID) + return rnd_false; + if (old_shape[n] != old_shape[0]) + return rnd_false; + } + + /* all copper sizes must be the same, all mask sizes must be the same */ + for(n = 0; n < tshp->len; n++) { + if ((tshp->shape[n].layer_mask & PCB_LYT_COPPER) && (RND_ABS(old_dia[n] - old_dia[coppern]) > 10)) + return rnd_false; + if (maskn >= 0) + if ((tshp->shape[n].layer_mask & PCB_LYT_MASK) && (RND_ABS(old_dia[n] - old_dia[maskn]) > 10)) + return rnd_false; + } + + /* all went fine, collect and return data */ + *x = ps->x; + *y = ps->y; + *drill_dia = proto->hdia; + *pad_dia = old_dia[coppern]; + *clearance = ps->Clearance; + *mask = maskn >= 0 ? old_dia[maskn] : 0; + *cshape = old_shape[0]; + *plated = proto->hplated; + + /* clerance workaround for copper smaller than hole; inverse of r25735 */ + if (*pad_dia < *drill_dia) + *clearance -= (*drill_dia - *pad_dia)/2; + + return rnd_true; +} + +/* emulate the old 'square flag' pad */ +static void pad_shape(pcb_pstk_poly_t *dst, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t thickness) +{ + double d, dx, dy; + rnd_coord_t nx, ny; + rnd_coord_t halfthick = (thickness + 1) / 2; + + dx = x2 - x1; + dy = y2 - y1; + + d = sqrt((double)sqr(dx) + (double)sqr(dy)); + if (d != 0) { + double v = (double)halfthick / d; + nx = (double)(y1 - y2) * v; + ny = (double)(x2 - x1) * v; + + x1 -= ny; + y1 += nx; + x2 += ny; + y2 -= nx; + } + else { + nx = halfthick; + ny = 0; + + y1 += nx; + y2 -= nx; + } + + pcb_pstk_shape_alloc_poly(dst, 4); + dst->x[0] = x1 - nx; dst->y[0] = y1 - ny; + dst->x[1] = x1 + nx; dst->y[1] = y1 + ny; + dst->x[2] = x2 + nx; dst->y[2] = y2 + ny; + dst->x[3] = x2 - nx; dst->y[3] = y2 - ny; +} + +/* Generate a square or round pad of a given thickness - typically mask or copper */ +static void gen_pad(pcb_pstk_shape_t *dst, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t thickness, rnd_bool square) +{ + if (square) { + dst->shape = PCB_PSSH_POLY; + pad_shape(&dst->data.poly, x1, y1, x2, y2, thickness); + } + else if (x1 == x2 && y1 == y2) { + dst->shape = PCB_PSSH_CIRC; + dst->data.circ.x = x1; + dst->data.circ.y = y1; + dst->data.circ.dia = thickness; + } + else { + dst->shape = PCB_PSSH_LINE; + dst->data.line.x1 = x1; + dst->data.line.y1 = y1; + dst->data.line.x2 = x2; + dst->data.line.y2 = y2; + dst->data.line.thickness = thickness; + dst->data.line.square = 0; + } +} + +pcb_pstk_t *pcb_pstk_new_compat_pad(pcb_data_t *data, long int id, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t thickness, rnd_coord_t clearance, rnd_coord_t mask, rnd_bool square, rnd_bool nopaste, rnd_bool onotherside) +{ + pcb_layer_type_t side; + pcb_pstk_proto_t proto; + pcb_pstk_shape_t shape[3]; /* max number of shapes: 1 copper, 1 mask, 1 paste */ + rnd_cardinal_t pid; + pcb_pstk_tshape_t tshp; + int n; + rnd_coord_t cx, cy; + + assert(thickness >= 0); + assert(clearance >= 0); + assert(mask >= 0); + + cx = (x1 + x2) / 2; + cy = (y1 + y2) / 2; + + memset(&proto, 0, sizeof(proto)); + memset(&tshp, 0, sizeof(tshp)); + memset(&shape, 0, sizeof(shape)); + + tshp.len = nopaste ? 2 : 3; + tshp.shape = shape; + proto.tr.alloced = proto.tr.used = 1; /* has the canonical form only */ + proto.tr.array = &tshp; + + gen_pad(&shape[0], x1 - cx, y1 - cy, x2 - cx, y2 - cy, thickness, square); /* copper */ + gen_pad(&shape[1], x1 - cx, y1 - cy, x2 - cx, y2 - cy, mask, square); /* mask */ + if (!nopaste) + pcb_pstk_shape_copy(&shape[2], &shape[0]); /* paste is the same */ + + side = onotherside ? PCB_LYT_BOTTOM : PCB_LYT_TOP; + shape[0].layer_mask = side | PCB_LYT_COPPER; shape[0].comb = 0; + shape[1].layer_mask = side | PCB_LYT_MASK; shape[1].comb = PCB_LYC_AUTO | PCB_LYC_SUB; + if (!nopaste) { + shape[2].layer_mask = side | PCB_LYT_PASTE; + shape[2].comb = PCB_LYC_AUTO; + } + + pcb_pstk_proto_update(&proto); + pid = pcb_pstk_proto_insert_dup(data, &proto, 1, 0); + + for(n = 0; n < tshp.len; n++) + compat_shape_free(&shape[n]); + + if (pid == PCB_PADSTACK_INVALID) + return NULL; + + return pcb_pstk_new(data, id, pid, cx, cy, clearance/2, pcb_flag_make(PCB_FLAG_CLEARLINE)); +} + + +rnd_bool pcb_pstk_export_compat_pad(pcb_pstk_t *ps, rnd_coord_t *x1, rnd_coord_t *y1, rnd_coord_t *x2, rnd_coord_t *y2, rnd_coord_t *thickness, rnd_coord_t *clearance, rnd_coord_t *mask, rnd_bool *square, rnd_bool *nopaste) +{ + pcb_pstk_proto_t *proto; + pcb_pstk_tshape_t *tshp; + int n, coppern = -1, maskn = -1, pasten = -1; + pcb_layer_type_t side; + rnd_coord_t lx1[3], ly1[3], lx2[3], ly2[3], lt[3]; /* poly->line conversion cache */ + + proto = pcb_pstk_get_proto_(ps->parent.data, ps->proto); + if ((proto == NULL) || (proto->tr.used < 1)) + return rnd_false; + + tshp = &proto->tr.array[0]; + + if ((tshp->len < 2) || (tshp->len > 3)) + return rnd_false; /* allow at most a copper, a mask and a paste */ + + /* determine whether we are on top or bottom */ + side = tshp->shape[0].layer_mask & (PCB_LYT_TOP | PCB_LYT_BOTTOM); + if ((side == 0) || (side == (PCB_LYT_TOP | PCB_LYT_BOTTOM))) + return rnd_false; + + for(n = 0; n < tshp->len; n++) { + if (tshp->shape[n].shape != tshp->shape[0].shape) + return rnd_false; /* all shapes must be the same */ + if ((tshp->shape[n].layer_mask & PCB_LYT_ANYWHERE) != side) + return rnd_false; /* all shapes must be the same side */ + if (tshp->shape[n].layer_mask & PCB_LYT_COPPER) { + coppern = n; + continue; + } + if (tshp->shape[n].layer_mask & PCB_LYT_INTERN) + return rnd_false; /* accept only copper as intern */ + if (tshp->shape[n].layer_mask & PCB_LYT_MASK) { + maskn = n; + continue; + } + if (tshp->shape[n].layer_mask & PCB_LYT_PASTE) { + pasten = n; + continue; + } + return rnd_false; /* refuse anything else */ + } + + /* require copper and mask shapes */ + if ((coppern < 0) || (maskn < 0)) + return rnd_false; + + /* if the shape is poly, convert to line to make the rest of the code simpler */ + if (tshp->shape[0].shape == PCB_PSSH_POLY) { + for(n = 0; n < tshp->len; n++) { + rnd_coord_t w, h, x1, x2, y1, y2; + double stepd, step2; + int step; + + if (tshp->shape[n].shape != PCB_PSSH_POLY) + continue; + + if (tshp->shape[n].data.poly.len != 4) + return rnd_false; + + stepd = ps->rot / 90.0; + step = stepd; + step2 = (double)step * 90.0; + if (fabs(ps->rot - step2) > 0.01) + return rnd_false; + + x1 = tshp->shape[n].data.poly.x[0]; + x2 = tshp->shape[n].data.poly.x[2]; + if (x1 < x2) { + x2 = tshp->shape[n].data.poly.x[0]; + x1 = tshp->shape[n].data.poly.x[2]; + } + y1 = tshp->shape[n].data.poly.y[0]; + y2 = tshp->shape[n].data.poly.y[2]; + if (y1 < y2) { + y2 = tshp->shape[n].data.poly.y[0]; + y1 = tshp->shape[n].data.poly.y[2]; + } + if ((step % 2) == 1) { + h = x1 - x2; + w = y1 - y2; + } + else { + w = x1 - x2; + h = y1 - y2; + } + lt[n] = (w < h) ? w : h; + lx1[n] = x2 + lt[n] / 2; + ly1[n] = y2 + lt[n] / 2; + lx2[n] = lx1[n] + (w - lt[n]); + ly2[n] = ly1[n] + (h - lt[n]); + } + } + + /* require all shapes to be concentric */ + for(n = 1; n < tshp->len; n++) { + switch(tshp->shape[0].shape) { + case PCB_PSSH_HSHADOW: + return rnd_false; + case PCB_PSSH_LINE: + if (tshp->shape[0].data.line.x1 != tshp->shape[n].data.line.x1) + return rnd_false; + if (tshp->shape[0].data.line.y1 != tshp->shape[n].data.line.y1) + return rnd_false; + if (tshp->shape[0].data.line.x2 != tshp->shape[n].data.line.x2) + return rnd_false; + if (tshp->shape[0].data.line.y2 != tshp->shape[n].data.line.y2) + return rnd_false; + break; + case PCB_PSSH_CIRC: + if (tshp->shape[0].data.circ.x != tshp->shape[n].data.circ.x) + return rnd_false; + if (tshp->shape[0].data.circ.y != tshp->shape[n].data.circ.y) + return rnd_false; + break; + case PCB_PSSH_POLY: + if (lx1[0] != lx1[n]) + return rnd_false; + if (ly1[0] != ly1[n]) + return rnd_false; + if (lx2[0] != lx2[n]) + return rnd_false; + if (ly2[0] != ly2[n]) + return rnd_false; + break; + } + } + + /* generate the return pad (line-like) */ + switch(tshp->shape[0].shape) { + case PCB_PSSH_LINE: + *x1 = tshp->shape[coppern].data.line.x1 + ps->x; + *y1 = tshp->shape[coppern].data.line.y1 + ps->y; + *x2 = tshp->shape[coppern].data.line.x2 + ps->x; + *y2 = tshp->shape[coppern].data.line.y2 + ps->y; + *thickness = tshp->shape[coppern].data.line.thickness; + *mask = tshp->shape[maskn].data.line.thickness; + *square = tshp->shape[coppern].data.line.square; + break; + case PCB_PSSH_CIRC: + *x1 = *x2 = tshp->shape[coppern].data.circ.x + ps->x; + *y1 = *y2 = tshp->shape[coppern].data.circ.y + ps->y; + *thickness = tshp->shape[coppern].data.circ.dia; + *mask = tshp->shape[maskn].data.circ.dia; + *square = 0; + break; + case PCB_PSSH_POLY: + *square = 1; + *x1 = lx1[0] + ps->x; + *y1 = ly1[0] + ps->y; + *x2 = lx2[0] + ps->x; + *y2 = ly2[0] + ps->y; + *thickness = lt[coppern]; + *mask = lt[maskn]; + break; + case PCB_PSSH_HSHADOW: + break; + } + + *clearance = (ps->Clearance > 0 ? ps->Clearance : tshp->shape[0].clearance) * 2; + *nopaste = pasten < 0; + + return rnd_true; +} + +pcb_flag_t pcb_pstk_compat_pinvia_flag(pcb_pstk_t *ps, pcb_pstk_compshape_t cshape, pcb_pstk_compat_t compat) +{ + pcb_flag_t flg; + int n; + + memset(&flg, 0, sizeof(flg)); + flg.f = ps->Flags.f & PCB_PSTK_VIA_COMPAT_FLAGS; + switch(cshape) { + case PCB_PSTK_COMPAT_ROUND: + break; + case PCB_PSTK_COMPAT_OCTAGON: + flg.f |= PCB_FLAG_OCTAGON; + break; + case PCB_PSTK_COMPAT_SQUARE: + flg.f |= PCB_FLAG_SQUARE; + flg.q = 1; + break; + default: + if ((cshape >= PCB_PSTK_COMPAT_SHAPED) && (cshape <= PCB_PSTK_COMPAT_SHAPED_END)) { + cshape -= PCB_PSTK_COMPAT_SHAPED; + if (cshape == 1) + cshape = 17; + if ((cshape == 17) && (compat & PCB_PSTKCOMP_OLD_OCTAGON)) { + cshape = 0; + flg.f |= PCB_FLAG_OCTAGON; + } + else { + flg.q = cshape; + flg.f |= PCB_FLAG_SQUARE; + } + } + else + pcb_io_incompat_save(ps->parent.data, (pcb_any_obj_t *)ps, "padstack-shape", "Failed to convert shape to old-style pin/via", "Old pin/via format is very much restricted; try to use a simpler shape (e.g. circle)"); + } + + for(n = 0; n < sizeof(flg.t) / sizeof(flg.t[0]); n++) { + unsigned char *ot = pcb_pstk_get_thermal(ps, n, 0); + int nt; + if ((ot == NULL) || (*ot == 0) || !((*ot) & PCB_THERMAL_ON)) + continue; + switch(((*ot) & ~PCB_THERMAL_ON)) { + case PCB_THERMAL_SHARP | PCB_THERMAL_DIAGONAL: nt = 1; break; + case PCB_THERMAL_SHARP: nt = 2; break; + case PCB_THERMAL_SOLID: nt = 3; break; + case PCB_THERMAL_ROUND | PCB_THERMAL_DIAGONAL: nt = 4; break; + case PCB_THERMAL_ROUND: nt = 5; break; + default: nt = 0; pcb_io_incompat_save(ps->parent.data, (pcb_any_obj_t *)ps, "padstack-shape", "Failed to convert thermal to old-style via", "Old via format is very much restricted; try to use a simpler thermal shape"); + } + PCB_FLAG_THERM_ASSIGN_(n, nt, flg); + } + return flg; +} + + +pcb_pstk_t *pcb_old_via_new(pcb_data_t *data, long int id, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Thickness, rnd_coord_t Clearance, rnd_coord_t Mask, rnd_coord_t DrillingHole, const char *Name, pcb_flag_t Flags) +{ + pcb_pstk_t *p; + pcb_pstk_compshape_t shp; + int n; + + if (Flags.f & PCB_FLAG_SQUARE) { + shp = Flags.q /*+ PCB_PSTK_COMPAT_SHAPED*/; + if (shp == 0) + shp = PCB_PSTK_COMPAT_SQUARE; + } + else if (Flags.f & PCB_FLAG_OCTAGON) + shp = PCB_PSTK_COMPAT_OCTAGON; + else + shp = PCB_PSTK_COMPAT_ROUND; + + p = pcb_pstk_new_compat_via_(data, id, X, Y, DrillingHole, Thickness, Clearance/2, Mask, shp, !(Flags.f & PCB_FLAG_HOLE), 1); + p->Flags.f |= Flags.f & PCB_PSTK_VIA_COMPAT_FLAGS; + for(n = 0; n < sizeof(Flags.t) / sizeof(Flags.t[0]); n++) { + int nt = PCB_THERMAL_ON, t = ((Flags.t[n/2] >> (4 * (n % 2))) & 0xf); + if (t != 0) { + switch(t) { + case 1: nt |= PCB_THERMAL_SHARP | PCB_THERMAL_DIAGONAL; break; + case 2: nt |= PCB_THERMAL_SHARP; break; + case 3: nt |= PCB_THERMAL_SOLID; break; + case 4: nt |= PCB_THERMAL_ROUND | PCB_THERMAL_DIAGONAL; break; + case 5: nt |= PCB_THERMAL_ROUND; break; + } + pcb_pstk_set_thermal(p, n, nt, 0); + } + } + + if (Name != NULL) + pcb_attribute_put(&p->Attributes, "name", Name); + + return p; +} + +void pcb_shape_octagon(pcb_pstk_shape_t *dst, rnd_coord_t radiusx, rnd_coord_t radiusy) +{ + dst->shape = PCB_PSSH_POLY; + octa_shape(&dst->data.poly, 0, 0, radiusx, radiusy, 0); +} Index: tags/2.3.0/src_plugins/lib_compat_help/pstk_compat.h =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/pstk_compat.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/pstk_compat.h (revision 33253) @@ -0,0 +1,44 @@ +#ifndef PCB_PSTK_COMPAT_H +#define PCB_PSTK_COMPAT_H + +#include "obj_pstk.h" + +typedef enum { + PCB_PSTK_COMPAT_ROUND = 0, + PCB_PSTK_COMPAT_SQUARE = 1, + PCB_PSTK_COMPAT_SHAPED = 2, /* old pcb-rnd pin shapes */ + PCB_PSTK_COMPAT_SHAPED_END = 16, /* old pcb-rnd pin shapes */ + PCB_PSTK_COMPAT_OCTAGON, + PCB_PSTK_COMPAT_INVALID +} pcb_pstk_compshape_t; + +/* Create a padstack that emulates an old-style via - register proto as needed + if id <= 0, allocate a new id automatically */ +pcb_pstk_t *pcb_pstk_new_compat_via(pcb_data_t *data, long int id, rnd_coord_t x, rnd_coord_t y, rnd_coord_t drill_dia, rnd_coord_t pad_dia, rnd_coord_t clearance, rnd_coord_t mask, pcb_pstk_compshape_t shp, rnd_bool plated); + +/* Convert an existing padstack to old-style via and return broken down parameters */ +rnd_bool pcb_pstk_export_compat_via(pcb_pstk_t *ps, rnd_coord_t *x, rnd_coord_t *y, rnd_coord_t *drill_dia, rnd_coord_t *pad_dia, rnd_coord_t *clearance, rnd_coord_t *mask, pcb_pstk_compshape_t *cshape, rnd_bool *plated); + +/* Create a padstack that emulates an old-style pad - register proto as needed + If id <= 0, allocate an id automatically. */ +pcb_pstk_t *pcb_pstk_new_compat_pad(pcb_data_t *data, long int id, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2, rnd_coord_t thickness, rnd_coord_t clearance, rnd_coord_t mask, rnd_bool square, rnd_bool nopaste, rnd_bool onotherside); + +/* Convert an existing padstack to old-style pad and return broken down parameters */ +rnd_bool pcb_pstk_export_compat_pad(pcb_pstk_t *ps, rnd_coord_t *x1, rnd_coord_t *y1, rnd_coord_t *x2, rnd_coord_t *y2, rnd_coord_t *thickness, rnd_coord_t *clearance, rnd_coord_t *mask, rnd_bool *square, rnd_bool *nopaste); + +typedef enum { + PCB_PSTKCOMP_OLD_OCTAGON = 1 +} pcb_pstk_compat_t; + +/* Convert padstack flags to old pin/via flag. Use only in gEDA/PCB + compatibility code: io_pcb and io_lihata. */ +pcb_flag_t pcb_pstk_compat_pinvia_flag(pcb_pstk_t *ps, pcb_pstk_compshape_t cshape, pcb_pstk_compat_t compat); + +#define PCB_PSTK_VIA_COMPAT_FLAGS (PCB_FLAG_CLEARLINE | PCB_FLAG_SELECTED | PCB_FLAG_FOUND | PCB_FLAG_WARN | PCB_FLAG_USETHERMAL | PCB_FLAG_LOCK) + +/* Create a padstack that mimics the old gEDA/PCB via (or pin). + If id <= 0, allocate a new ID automatically. + Should not be used anywhere but io_pcb and io_lihata. */ +pcb_pstk_t *pcb_old_via_new(pcb_data_t *data, long int id, rnd_coord_t X, rnd_coord_t Y, rnd_coord_t Thickness, rnd_coord_t Clearance, rnd_coord_t Mask, rnd_coord_t DrillingHole, const char *Name, pcb_flag_t Flags); + +#endif Index: tags/2.3.0/src_plugins/lib_compat_help/pstk_help.c =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/pstk_help.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/pstk_help.c (revision 33253) @@ -0,0 +1,367 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "pstk_help.h" +#include "obj_pstk_inlines.h" +#include +#include "search.h" +#include "remove.h" +#include "find.h" + + +pcb_pstk_t *pcb_pstk_new_hole(pcb_data_t *data, rnd_coord_t x, rnd_coord_t y, rnd_coord_t drill_dia, rnd_bool plated) +{ + pcb_pstk_proto_t proto; + rnd_cardinal_t pid; + + memset(&proto, 0, sizeof(proto)); + proto.hdia = drill_dia; + proto.hplated = plated; + + pcb_pstk_proto_update(&proto); + pid = pcb_pstk_proto_insert_dup(data, &proto, 1, 0); + + return pcb_pstk_new(data, -1, pid, x, y, 0, pcb_flag_make(PCB_FLAG_CLEARLINE)); +} + +pcb_layer_type_t lyts[] = { + /* primary for thru-hole */ + PCB_LYT_TOP | PCB_LYT_COPPER, + PCB_LYT_BOTTOM | PCB_LYT_COPPER, + + /* secondary */ + PCB_LYT_INTERN | PCB_LYT_COPPER, + PCB_LYT_TOP | PCB_LYT_PASTE, + PCB_LYT_TOP | PCB_LYT_SILK, + PCB_LYT_TOP | PCB_LYT_MASK, + PCB_LYT_BOTTOM | PCB_LYT_MASK, + PCB_LYT_BOTTOM | PCB_LYT_SILK, + PCB_LYT_BOTTOM | PCB_LYT_PASTE +}; + +#define NUM_LYTS (sizeof(lyts) / sizeof(lyts[0])) + + +static int vect2pstk_conv_cand(pcb_data_t *data, vtp0_t *objs, rnd_bool_t quiet, pcb_any_obj_t **cand, int *num_cand, rnd_coord_t cx, rnd_coord_t cy, int plated, pcb_any_obj_t *extrao) +{ + pcb_pstk_proto_t proto; + int l, ci, res = -1; + vtp0_t tmp; + char *term = NULL; + + vtp0_init(&tmp); + if (extrao != NULL) + vtp0_append(&tmp, extrao); + for(l = 0; l < NUM_LYTS; l++) { + if (num_cand[l] == 1) { + vtp0_append(&tmp, cand[l]); + if (term == NULL) + term = pcb_attribute_get(&cand[l]->Attributes, "term"); + } + } + + rnd_trace("Converting %d objects into a pstk\n", tmp.used); + + memset(&proto, 0, sizeof(proto)); + if (pcb_pstk_proto_conv(data, &proto, quiet, &tmp, cx, cy) == 0) { + rnd_cardinal_t pid; + if (plated != -1) + proto.hplated = plated; + pid = pcb_pstk_proto_insert_or_free(data, &proto, quiet, 0); + if (pid != PCB_PADSTACK_INVALID) { + pcb_pstk_t *ps = pcb_pstk_new(data, -1, pid, cx, cy, 0, pcb_flag_make(PCB_FLAG_CLEARLINE | PCB_FLAG_FOUND)); + vtp0_append(objs, ps); + if (term != NULL) + pcb_attribute_put(&ps->Attributes, "term", term); + /* got our new proto - remove the objects we used */ + for(ci = 0; ci < tmp.used; ci++) { + int i; + pcb_any_obj_t *o = tmp.array[ci]; + for(i = 0; i < objs->used; i++) { + if (objs->array[i] == o) { + vtp0_remove(objs, i, 1); + pcb_destroy_object(data, o->type, o->parent.any, o, o); + break; + } + } + } + } + res = 0; + } + vtp0_uninit(&tmp); + return res; +} + +int pcb_pstk_vect2pstk_thr(pcb_data_t *data, vtp0_t *objs, rnd_bool_t quiet) +{ + int l, n, plated, done = 0, ci; + pcb_pstk_proto_t *p; + rnd_coord_t cx, cy, d, r, valid; + pcb_any_obj_t *cand[NUM_LYTS]; + int num_cand[NUM_LYTS]; + + /* output padstacks are going to be marked with the FOUND flag */ + for(n = 0; n < objs->used; n++) PCB_FLAG_CLEAR(PCB_FLAG_FOUND, (pcb_any_obj_t *)(objs->array[n])); + + for(n = 0; n < objs->used; n++) { + pcb_any_obj_t *h = objs->array[n]; + + /* find holes */ + switch(h->type) { + case PCB_OBJ_PSTK: + p = pcb_pstk_get_proto((pcb_pstk_t *)h); + if ((p == NULL) || (p->hdia <= 0)) + continue; + cx = ((pcb_pstk_t *)h)->x; + cy = ((pcb_pstk_t *)h)->y; + d = p->hdia; + plated = p->hplated; + break; + default: + continue; + } + r = d/2; + + /* we have a hole center and dia - look for objects that could be pads for this hole */ + memset(cand, 0, sizeof(cand)); + memset(num_cand, 0, sizeof(num_cand)); + for(ci = 0; ci < objs->used; ci++) { + pcb_layer_type_t lyt; + pcb_any_obj_t *c = objs->array[ci]; /* candidate */ + if (PCB_FLAG_TEST(PCB_FLAG_FOUND, c)) continue; /* already used */ + switch(c->type) { + case PCB_OBJ_LINE: + if (!pcb_is_point_in_line(cx, cy, r, (pcb_any_line_t *)c)) continue; + break; + case PCB_OBJ_POLY: + if (!pcb_poly_is_point_in_p(cx, cy, r, (pcb_poly_t *)c)) continue; + break; + default: continue; /* this type can not be used */ + } + + /* candidate is around the hole - figure the indexing from lyt */ + assert(c->parent_type == PCB_PARENT_LAYER); + lyt = pcb_layer_flags_(c->parent.layer); + for(l = 0; l < NUM_LYTS; l++) { + if (lyts[l] == lyt) { + cand[l] = c; + num_cand[l]++; + break; + } + } + } + + + /* all candidates are in cand[] and num_cand[]; check if there's any + usable candidate (layer type with only one candidate); allow multiple + intern coppers for now */ + valid = 0; + for(l = 0; l < NUM_LYTS; l++) { + if ((num_cand[l] == 1) || ((num_cand[l] > 1) && (lyts[l] & PCB_LYT_INTERN))) { + num_cand[l] = 1; + valid = 1; + break; + } + } + + if (!valid) continue; /* this hole can not be converted */ + + if (vect2pstk_conv_cand(data, objs, quiet, cand, num_cand, cx, cy, plated, h) == 0) { + /* we have deleted from objs, need to start over the main loop */ + n = 0; + } + } + + /* output padstacks are going to be marked with the FOUND flag */ + for(n = 0; n < objs->used; n++) PCB_FLAG_CLEAR(PCB_FLAG_FOUND, (pcb_any_obj_t *)(objs->array[n])); + + return done; +} + +int pcb_pstk_vect2pstk_smd(pcb_data_t *data, vtp0_t *objs, rnd_bool_t quiet) +{ + int l, n, done = 0, ci; + rnd_coord_t cx, cy; + pcb_any_obj_t *cand[NUM_LYTS]; + int num_cand[NUM_LYTS]; + + /* output padstacks are going to be marked with the FOUND flag */ + for(n = 0; n < objs->used; n++) PCB_FLAG_CLEAR(PCB_FLAG_FOUND, (pcb_any_obj_t *)(objs->array[n])); + + for(n = 0; n < objs->used; n++) { + pcb_any_obj_t *o = objs->array[n]; + + if ((o->type == PCB_OBJ_LINE) || (o->type == PCB_OBJ_ARC) || (o->type == PCB_OBJ_POLY)) { + pcb_layer_type_t olyt; + + assert(o->parent_type == PCB_PARENT_LAYER); + olyt = pcb_layer_flags_(o->parent.layer); + if ((!(olyt & PCB_LYT_COPPER)) || (olyt & PCB_LYT_INTERN)) + continue; /* deal with outer copper objects only */ + + /* assume padstack origin is middle of the object, which is approximated here */ + cx = (o->BoundingBox.X1 + o->BoundingBox.X2) / 2; + cy = (o->BoundingBox.Y1 + o->BoundingBox.Y2) / 2; + + memset(cand, 0, sizeof(cand)); + memset(num_cand, 0, sizeof(num_cand)); + for(l = 0; l < NUM_LYTS; l++) { + if (lyts[l] == olyt) { + cand[l] = o; + num_cand[l]++; + break; + } + } + + for(ci = 0; ci < objs->used; ci++) { + pcb_layer_type_t lyt; + pcb_any_obj_t *c = objs->array[ci]; /* candidate */ + + lyt = pcb_layer_flags_(c->parent.layer); + + if ((lyt & PCB_LYT_ANYWHERE) != (olyt & PCB_LYT_ANYWHERE)) + continue; /* care for the same side only */ + + if (!((lyt & (PCB_LYT_MASK | PCB_LYT_PASTE)))) + continue; /* care for mask and paste objects */ + + if (!pcb_intersect_obj_obj(pcb_find0, o, c)) + continue; /* only if intersects with the original copper pad */ + + for(l = 0; l < NUM_LYTS; l++) { + if (lyts[l] == lyt) { + cand[l] = c; + num_cand[l]++; + break; + } + } + } + if (vect2pstk_conv_cand(data, objs, quiet, cand, num_cand, cx, cy, -1, NULL) == 0) { + /* we have deleted from objs, need to start over the main loop */ + n = 0; + } + } + } + + return done; +} + +int pcb_pstk_vect2pstk(pcb_data_t *data, vtp0_t *objs, rnd_bool_t quiet) +{ + int t = pcb_pstk_vect2pstk_thr(data, objs, quiet); + int s = pcb_pstk_vect2pstk_smd(data, objs, quiet); + if ((t < 0) && (s < 0)) + return -1; + if (t < 0) t = 0; + if (s < 0) s = 0; + return t+s; +} + + +pcb_pstk_t *pcb_pstk_new_from_shape(pcb_data_t *data, rnd_coord_t x, rnd_coord_t y, rnd_coord_t drill_dia, rnd_bool plated, rnd_coord_t glob_clearance, pcb_pstk_shape_t *shape) +{ + pcb_pstk_proto_t proto; + rnd_cardinal_t pid; + pcb_pstk_tshape_t tshp; + pcb_pstk_shape_t *s; + + memset(&proto, 0, sizeof(proto)); + memset(&tshp, 0, sizeof(tshp)); + + tshp.len = 0; + for(s = shape; s->layer_mask != 0; s++,tshp.len++) ; + tshp.shape = shape; + proto.tr.alloced = proto.tr.used = 1; /* has the canonical form only */ + proto.tr.array = &tshp; + + proto.hdia = drill_dia; + proto.hplated = plated; + + pcb_pstk_proto_update(&proto); + pid = pcb_pstk_proto_insert_dup(data, &proto, 1, 0); + if (pid == PCB_PADSTACK_INVALID) + return NULL; + + return pcb_pstk_new(data, -1, pid, x, y, glob_clearance, pcb_flag_make(PCB_FLAG_CLEARLINE)); +} + +void pcb_shape_rect(pcb_pstk_shape_t *shape, rnd_coord_t width, rnd_coord_t height) +{ + pcb_pstk_poly_t *dst = &shape->data.poly; + + pcb_pstk_shape_alloc_poly(dst, 4); + shape->shape = PCB_PSSH_POLY; + + width/=2; + height/=2; + + dst->x[0] = -width; dst->y[0] = -height; + dst->x[1] = +width; dst->y[1] = -height; + dst->x[2] = +width; dst->y[2] = +height; + dst->x[3] = -width; dst->y[3] = +height; +} + +void pcb_shape_rect_trdelta(pcb_pstk_shape_t *shape, rnd_coord_t width, rnd_coord_t height, rnd_coord_t dx, rnd_coord_t dy) +{ + pcb_pstk_poly_t *dst = &shape->data.poly; + + pcb_pstk_shape_alloc_poly(dst, 4); + shape->shape = PCB_PSSH_POLY; + + width/=2; + height/=2; + dx/=2; + dy/=2; + + dst->x[0] = -width+dx; dst->y[0] = -height-dy; + dst->x[1] = +width-dx; dst->y[1] = -height+dy; + dst->x[2] = +width+dx; dst->y[2] = +height-dy; + dst->x[3] = -width-dx; dst->y[3] = +height+dy; +} + +void pcb_shape_oval(pcb_pstk_shape_t *shape, rnd_coord_t width, rnd_coord_t height) +{ + shape->shape = PCB_PSSH_LINE; + + if (width == height) { + shape->shape = PCB_PSSH_CIRC; + + shape->data.circ.x = shape->data.circ.y = 0; + shape->data.circ.dia = height; + } + else if (width > height) { + shape->data.line.x1 = -width/2 + height/2; shape->data.line.y1 = 0; + shape->data.line.x2 = +width/2 - height/2; shape->data.line.y2 = 0; + shape->data.line.thickness = height; + } + else { + shape->data.line.x1 = 0; shape->data.line.y1 = -height/2 + width/2; + shape->data.line.x2 = 0; shape->data.line.y2 = +height/2 - width/2; + shape->data.line.thickness = width; + } +} Index: tags/2.3.0/src_plugins/lib_compat_help/pstk_help.h =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/pstk_help.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/pstk_help.h (revision 33253) @@ -0,0 +1,38 @@ +#ifndef PCB_PSTK_HELP_H +#define PCB_PSTK_HELP_H + +#include "obj_pstk.h" +#include + +/* create a new adstack that contains only a hole, but no shapes */ +pcb_pstk_t *pcb_pstk_new_hole(pcb_data_t *data, rnd_coord_t x, rnd_coord_t y, rnd_coord_t drill_dia, rnd_bool plated); + +/* Convert an array of shapes, terminated by a shape with layer_mask=0, into + a padstack. */ +pcb_pstk_t *pcb_pstk_new_from_shape(pcb_data_t *data, rnd_coord_t x, rnd_coord_t y, rnd_coord_t drill_dia, rnd_bool plated, rnd_coord_t glob_clearance, pcb_pstk_shape_t *shape); + +/* Convert a vector of (pcb_any_obj_t *) into zero or more padstacks. Remove + objects that are converted from both data and objs. New padstacks are + placed back in objs. Quiet controls log messages. Return the number + of padstacks created. Return -1 on error. + WARNING: O(n^2) loops, assuming there are only a dozen of objects passed. */ +int pcb_pstk_vect2pstk_thr(pcb_data_t *data, vtp0_t *objs, rnd_bool_t quiet); /* thru-hole pins only */ +int pcb_pstk_vect2pstk_smd(pcb_data_t *data, vtp0_t *objs, rnd_bool_t quiet); /* smd pads only */ + +/* Same as above, but convert both; returns -1 only if both failed */ +int pcb_pstk_vect2pstk(pcb_data_t *data, vtp0_t *objs, rnd_bool_t quiet); + +/*** shape generators ***/ +void pcb_shape_rect(pcb_pstk_shape_t *shape, rnd_coord_t width, rnd_coord_t height); +void pcb_shape_oval(pcb_pstk_shape_t *shape, rnd_coord_t width, rnd_coord_t height); + +/* trapezoid: deform the rectangle so that upper horizontal edge is smaller + by dx and lower horizontal edge is larger by dx; same happens to the vertical + edges and dy. */ +void pcb_shape_rect_trdelta(pcb_pstk_shape_t *shape, rnd_coord_t width, rnd_coord_t height, rnd_coord_t dx, rnd_coord_t dy); + +/* Create a regular octagon shape */ +void pcb_shape_octagon(pcb_pstk_shape_t *dst, rnd_coord_t radiusx, rnd_coord_t radiusy); + + +#endif Index: tags/2.3.0/src_plugins/lib_compat_help/subc_help.c =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/subc_help.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/subc_help.c (revision 33253) @@ -0,0 +1,68 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "subc_help.h" + +pcb_text_t *pcb_subc_add_dyntex(pcb_subc_t *sc, rnd_coord_t x, rnd_coord_t y, unsigned direction, int scale, rnd_bool bottom, const char *pattern) +{ + pcb_layer_type_t side = bottom ? PCB_LYT_BOTTOM : PCB_LYT_TOP; + pcb_layer_t *ly = pcb_subc_get_layer(sc, side | PCB_LYT_SILK, 0, rnd_true, "top-silk", rnd_false); + if (ly != NULL) + return pcb_text_new(ly, pcb_font(PCB, 0, 0), x, y, 90.0 * direction, scale, 0, pattern, pcb_flag_make(PCB_FLAG_DYNTEXT | PCB_FLAG_FLOATER | (bottom ? PCB_FLAG_ONSOLDER : 0))); + return 0; +} + +pcb_text_t *pcb_subc_add_refdes_text(pcb_subc_t *sc, rnd_coord_t x, rnd_coord_t y, unsigned direction, int scale, rnd_bool bottom) +{ + return pcb_subc_add_dyntex(sc, x, y, direction, scale, bottom, "%a.parent.refdes%"); +} + +pcb_text_t *pcb_subc_get_refdes_text(pcb_subc_t *sc) +{ + int l, score, best_score = 0; + pcb_text_t *best = NULL; + for(l = 0; l < sc->data->LayerN; l++) { + pcb_layer_t *ly = &sc->data->Layer[l]; + pcb_text_t *text; + gdl_iterator_t it; + textlist_foreach(&ly->Text, &it, text) { + if (!PCB_FLAG_TEST(PCB_FLAG_DYNTEXT, text)) + continue; + if (!strstr(text->TextString, "%a.parent.refdes%")) + continue; + score = 1; + if (ly->meta.bound.type & PCB_LYT_SILK) score += 5; + if (ly->meta.bound.type & PCB_LYT_TOP) score += 2; + if (score > best_score) { + best = text; + best_score = score; + } + } + } + + return best; +} + Index: tags/2.3.0/src_plugins/lib_compat_help/subc_help.h =================================================================== --- tags/2.3.0/src_plugins/lib_compat_help/subc_help.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_compat_help/subc_help.h (revision 33253) @@ -0,0 +1,18 @@ +#ifndef PCB_SUBC_HELP_H +#define PCB_SUBC_HELP_H + +#include "obj_subc.h" +#include "layer.h" + +/* Create dynamic text on the top silk layer (creates the layer if needed). + Returns the text object, or NULL on error. Does not set any subc + attribute. The refdes version is just a shorthand for the pattern. */ +pcb_text_t *pcb_subc_add_dyntex(pcb_subc_t *sc, rnd_coord_t x, rnd_coord_t y, unsigned direction, int scale, rnd_bool bottom, const char *pattern); +pcb_text_t *pcb_subc_add_refdes_text(pcb_subc_t *sc, rnd_coord_t x, rnd_coord_t y, unsigned direction, int scale, rnd_bool bottom); + +/* Returns the refdes text objects; must be DYNTEXT and must contain the + refdes attribute printing. If there's are multiple objects, silk is + preferred. */ +pcb_text_t *pcb_subc_get_refdes_text(pcb_subc_t *sc); + +#endif Index: tags/2.3.0/src_plugins/lib_formula/Makefile =================================================================== --- tags/2.3.0/src_plugins/lib_formula/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/lib_formula/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_lib_formula + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/lib_formula/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/lib_formula/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/lib_formula/Plug.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +put /local/pcb/mod {lib_formula} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/lib_formula/lib_formula.o + $(PLUGDIR)/lib_formula/impedance.o + $(PLUGDIR)/lib_formula/bisect.o +@] + +switch /local/pcb/lib_formula/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/lib_formula/bisect.c =================================================================== --- tags/2.3.0/src_plugins/lib_formula/bisect.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_formula/bisect.c (revision 33253) @@ -0,0 +1,165 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include "bisect.h" + +#define CALL(dst, value) \ +do { \ + argv[specn].type = FGW_DOUBLE; \ + argv[specn].val.nat_double = value; \ + r.val.nat_double = -1; r.type = FGW_DOUBLE; \ + ferr = f->func(&r, argc-2, argv+2); \ + if (ferr != 0) { \ + rnd_message(RND_MSG_ERROR, "formula_bisect: '%s' returned error on value %f\n", actname, value); \ + return -1; \ + } \ + fgw_arg_conv(&rnd_fgw, &r, FGW_DOUBLE); \ + if (r.type != FGW_DOUBLE) { \ + rnd_message(RND_MSG_ERROR, "formula_bisect: '%s' returned not-a-number on value %f\n", actname, value); \ + return -1; \ + } \ + dst = r.val.nat_double; \ +} while(0) + +RND_INLINE int is_between(double target, double low, double high) +{ + if (low > high) + rnd_swap(double, low, high); + return (target > low) && (target < high); +} + +const char pcb_acts_formula_bisect[] = "formula_bisect(action, res, args)"; +const char pcb_acth_formula_bisect[] = "Find the value for exactly one of the arguments that produces the expected result. One argument must be a string with type:min:max:precision, the rest of the arguments and res must be numeric."; +fgw_error_t pcb_act_formula_bisect(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *actname, *spec; + double target, min, max, minv, maxv, v, err, at; + fgw_arg_t r; + int n, specn = 0, unitlen, var_is_coord = 0; + const fgw_func_t *f; + fgw_error_t ferr; + const rnd_unit_t *unit; + char sunit[32]; + + RND_ACT_CONVARG(1, FGW_STR, formula_bisect, actname = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_DOUBLE, formula_bisect, target = argv[2].val.nat_double); + for(n = 3; n < argc; n++) { + if (((argv[n].type & FGW_STR) == FGW_STR) && (strchr(argv[n].val.str, ':') != NULL)) { + if (specn > 0) { + rnd_message(RND_MSG_ERROR, "formula_bisect: only one argument can be variable; the two are %d and %d now\n", specn, n); + return FGW_ERR_ARG_CONV; + } + else + specn = n; + } + } + + if (specn <= 0) { + rnd_message(RND_MSG_ERROR, "formula_bisect: one argument needs to be a variable specification string\n"); + return FGW_ERR_ARG_CONV; + } + + f = rnd_act_lookup(actname); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "formula_bisect: no such action: %s\n", actname); + return FGW_ERR_ARG_CONV; + } + + spec = strchr(argv[specn].val.str, ':'); + unitlen = spec - argv[specn].val.str; + if (unitlen >= sizeof(sunit)) { + rnd_message(RND_MSG_ERROR, "formula_bisect: invalid unit spec (too long): '%s'\n", spec); + return FGW_ERR_ARG_CONV; + } + if (sscanf(spec+1, "%lf:%lf:%lf", &min, &max, &err) != 3) { + rnd_message(RND_MSG_ERROR, "formula_bisect: invalid range spec: '%s'\n", spec); + return FGW_ERR_ARG_CONV; + } + + if (unitlen > 0) { + strncpy(sunit, argv[specn].val.str, unitlen); + sunit[unitlen] = '\0'; + } + if ((unitlen == 0) || (strcmp(sunit, "double") == 0) || (strcmp(sunit, "num") == 0)) { + /* do nothing */ + } + else { + unit = get_unit_by_suffix(sunit); + if (unit == NULL) { + rnd_message(RND_MSG_ERROR, "formula_bisect: invalid unit spec: '%s'\n", spec); + return FGW_ERR_ARG_CONV; + } + min = RND_MM_TO_COORD(min / unit->scale_factor); + max = RND_MM_TO_COORD(max / unit->scale_factor); + var_is_coord = ((unit->family == RND_UNIT_METRIC) || (unit->family == RND_UNIT_IMPERIAL)); + } + + fgw_arg_free(&rnd_fgw, &argv[specn]); + argv[specn].type = FGW_DOUBLE; + + CALL(minv, min); + if (fabs(minv - target) < err) goto found; + + CALL(maxv, max); + if (fabs(maxv - target) < err) goto found; + + for(n = 0; (n < 256); n++) { + at = (min+max)/2.0; + CALL(v, at); +/*rnd_trace("try1: [%f %f] %f -> %f\n", min, max, at, v);*/ + if (fabs(v - target) < err) + goto found; + + if (is_between(target, minv, v)) + max = at; + else if (is_between(target, v, maxv)) + min = at; + else { + rnd_message(RND_MSG_ERROR, "formula_bisect: convergence error\n"); + return -1; + } + } + + res->type = FGW_PTR; + res->val.ptr_void = NULL; + return 0; + + found:; + + if (var_is_coord) { + res->type = FGW_COORD; + fgw_coord(res) = at; + } + else { + res->type = FGW_DOUBLE; + res->val.nat_double = at; + } + + return 0; +} + Index: tags/2.3.0/src_plugins/lib_formula/bisect.h =================================================================== --- tags/2.3.0/src_plugins/lib_formula/bisect.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_formula/bisect.h (revision 33253) @@ -0,0 +1,4 @@ +extern const char pcb_acts_formula_bisect[]; +extern const char pcb_acth_formula_bisect[]; +fgw_error_t pcb_act_formula_bisect(fgw_arg_t *res, int argc, fgw_arg_t *argv); + Index: tags/2.3.0/src_plugins/lib_formula/impedance.c =================================================================== --- tags/2.3.0/src_plugins/lib_formula/impedance.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_formula/impedance.c (revision 33253) @@ -0,0 +1,132 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include +#include +#include "impedance.h" + +#define TOM(x) RND_COORD_TO_MM(x) +#define SQR(x) ((x)*(x)) +#define N0 377 + +/* Formulas from: https://www.eeweb.com/tools/microstrip-impedance + ref: "The source of this formula is based on Wheeler's equation." */ +double pcb_impedance_microstrip(rnd_coord_t trace_width, rnd_coord_t trace_height, rnd_coord_t subst_height, double dielect) +{ + double w = TOM(trace_width), t = TOM(trace_height), h = TOM(subst_height), Er = dielect; + double weff, x1, x2; + + weff = w + (t/M_PI) * log(4*M_E / sqrt(SQR(t/h)+SQR(t/(w*M_PI+1.1*t*M_PI)))) * (Er+1)/(2*Er); + x1 = 4 * ((14*Er+8)/(11*Er)) * (h/weff); + x2 = sqrt(16 * SQR(h/weff) * SQR((14*Er+8)/(11*Er)) + ((Er+1)/(2*Er))*M_PI*M_PI); + return N0 / (2*M_PI * sqrt(2) * sqrt(Er+1)) * log(1+4*(h/weff)*(x1+x2)); +} + + +const char pcb_acts_impedance_microstrip[] = "impedance_microstrip(trace_width, trace_height, subst_height, dielectric)"; +const char pcb_acth_impedance_microstrip[] = "Calculate the approximated impedance of a microstrip transmission line, in ohms"; +fgw_error_t pcb_act_impedance_microstrip(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_coord_t trace_width, trace_height, subst_height; + double dielectric; + + RND_ACT_CONVARG(1, FGW_COORD, impedance_microstrip, trace_width = fgw_coord(&argv[1])); + RND_ACT_CONVARG(2, FGW_COORD, impedance_microstrip, trace_height = fgw_coord(&argv[2])); + RND_ACT_CONVARG(3, FGW_COORD, impedance_microstrip, subst_height = fgw_coord(&argv[3])); + RND_ACT_CONVARG(4, FGW_DOUBLE, impedance_microstrip, dielectric = argv[4].val.nat_double); + + res->type = FGW_DOUBLE; + res->val.nat_double = pcb_impedance_microstrip(trace_width, trace_height, subst_height, dielectric); + return 0; +} + + +/* As documented at https://chemandy.com/calculators/elliptical-integrals-of-the-first-kind-calculator.htm + refrerence: These recursive equations were originally given for use in calculating the inductance of helical coils and are taken from Miller, H Craig, "Inductance Equation for a Single-Layer Circular Coil" Proceedings of the IEEE, Vol. 75, No 2, February 1987, pp. 256-257. +*/ +static double ellint(double k) +{ + double a = 1.0, b = sqrt(1.0-k*k), c = k, K, lastc = 100; + + if ((k <= -1.0) || (k >= 1.0)) + return 0; + + for(K = M_PI/(2*a); (c != 0) && (c != lastc);) { + double an, bn, cn; + + an = (a+b)/2; + bn = sqrt(a*b); + cn = (a-b)/2; + lastc = c; + a = an; b = bn; c = cn; + K = M_PI/(2*a); + } + return K; +} + +/* Formula from https://chemandy.com/calculators/coplanar-waveguide-with-ground-calculator.htm + ref: Transmission Line Design Handbook by Brian C Wadell, Artech House 1991 page 79 */ +double pcb_impedance_coplanar_waveguide(rnd_coord_t trace_width, rnd_coord_t trace_clearance, rnd_coord_t subst_height, double dielect) +{ + double a = TOM(trace_width), clr = TOM(trace_clearance), h = TOM(subst_height), Er = dielect; + double b = clr+a+clr, eeff, ktmp, k, k_, kl, kl_, ktmp2; + + k = a/b; + k_ = sqrt(1.0 - k*k); + kl = tanh((M_PI * a)/(4.0*h)) / tanh((M_PI * b)/(4.0*h)); + kl_ = sqrt(1.0 - kl*kl); + + k = ellint(k); + k_ = ellint(k_); + kl = ellint(kl); + kl_ = ellint(kl_); + + ktmp = (k_ * kl) / (k * kl_); + eeff = (1.0 + Er * ktmp) / (1.0 + ktmp); + + ktmp2 = k / k_ + kl / kl_; + return ((60.0*M_PI) / sqrt(eeff)) * (1.0 / ktmp2); +} + +const char pcb_acts_impedance_coplanar_waveguide[] = "impedance_coplanar_waveguide(trace_width, trace_clearance, subst_height, dielectric)"; +const char pcb_acth_impedance_coplanar_waveguide[] = "Calculate the approximated impedance of a coplanar_waveguide transmission line, in ohms"; +fgw_error_t pcb_act_impedance_coplanar_waveguide(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_coord_t trace_width, trace_clearance, subst_height; + double dielectric; + + RND_ACT_CONVARG(1, FGW_COORD, impedance_coplanar_waveguide, trace_width = fgw_coord(&argv[1])); + RND_ACT_CONVARG(2, FGW_COORD, impedance_coplanar_waveguide, trace_clearance = fgw_coord(&argv[2])); + RND_ACT_CONVARG(3, FGW_COORD, impedance_coplanar_waveguide, subst_height = fgw_coord(&argv[3])); + RND_ACT_CONVARG(4, FGW_DOUBLE, impedance_coplanar_waveguide, dielectric = argv[4].val.nat_double); + + res->type = FGW_DOUBLE; + res->val.nat_double = pcb_impedance_coplanar_waveguide(trace_width, trace_clearance, subst_height, dielectric); + return 0; +} Index: tags/2.3.0/src_plugins/lib_formula/impedance.h =================================================================== --- tags/2.3.0/src_plugins/lib_formula/impedance.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_formula/impedance.h (revision 33253) @@ -0,0 +1,11 @@ +#include + +double pcb_impedance_microstrip(rnd_coord_t trace_width, rnd_coord_t trace_height, rnd_coord_t subst_height, double dielect); + +extern const char pcb_acts_impedance_microstrip[]; +extern const char pcb_acth_impedance_microstrip[]; +fgw_error_t pcb_act_impedance_microstrip(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char pcb_acts_impedance_coplanar_waveguide[]; +extern const char pcb_acth_impedance_coplanar_waveguide[]; +fgw_error_t pcb_act_impedance_coplanar_waveguide(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/2.3.0/src_plugins/lib_formula/lib_formula.c =================================================================== --- tags/2.3.0/src_plugins/lib_formula/lib_formula.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_formula/lib_formula.c (revision 33253) @@ -0,0 +1,55 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include "impedance.h" +#include "bisect.h" + +static rnd_action_t lib_formula_action_list[] = { + {"impedance_microstrip", pcb_act_impedance_microstrip, pcb_acth_impedance_microstrip, pcb_acts_impedance_microstrip}, + {"impedance_coplanar_waveguide", pcb_act_impedance_coplanar_waveguide, pcb_acth_impedance_coplanar_waveguide, pcb_acts_impedance_coplanar_waveguide}, + {"formula_bisect", pcb_act_formula_bisect, pcb_acth_formula_bisect, pcb_acts_formula_bisect} +}; + +char *lib_formula_cookie = "lib_formula plugin"; + +int pplg_check_ver_lib_formula(int ver_needed) { return 0; } + +void pplg_uninit_lib_formula(void) +{ + rnd_remove_actions_by_cookie(lib_formula_cookie); +} + +int pplg_init_lib_formula(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(lib_formula_action_list, lib_formula_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/lib_formula/lib_formula.pup =================================================================== --- tags/2.3.0/src_plugins/lib_formula/lib_formula.pup (nonexistent) +++ tags/2.3.0/src_plugins/lib_formula/lib_formula.pup (revision 33253) @@ -0,0 +1,6 @@ +$class lib +$short mathematical forumlas +$long simple formulas, for efficient rule-of-thumb calculations +$state works +$package core +default buildin Index: tags/2.3.0/src_plugins/lib_formula/test/Makefile =================================================================== --- tags/2.3.0/src_plugins/lib_formula/test/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/lib_formula/test/Makefile (revision 33253) @@ -0,0 +1,8 @@ +CFLAGS = -Wall -I. -I../../../src -I../../../src_3rd -I../../.. +LDFLAGS = -lm -ldl +LIBRND = ../../../src/librnd-hid.a ../../../src/librnd-3rd.a + +main: main.o $(LIBRND) + +main.o: main.c ../impedance.c glue.c + Index: tags/2.3.0/src_plugins/lib_formula/test/glue.c =================================================================== --- tags/2.3.0/src_plugins/lib_formula/test/glue.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_formula/test/glue.c (revision 33253) @@ -0,0 +1,17 @@ +/* glue for hidlib */ + +#include + +const char *rnd_menu_file_paths[4]; +const char *rnd_menu_name_fmt = "pcb-menu-%s.lht"; + +const char *rnd_hidlib_default_embedded_menu = ""; + +void rnd_hidlib_crosshair_move_to(rnd_hidlib_t *hl, rnd_coord_t abs_x, rnd_coord_t abs_y, int mouse_mot) { } + +const char *rnd_conf_userdir_path; +const char *rnd_pcphl_conf_user_path; +const char *rnd_conf_sysdir_path; +const char *rnd_conf_sys_path; + +const char pcb_conf_internal_arr[] = {""}, *pcb_conf_internal = pcb_conf_internal_arr; Index: tags/2.3.0/src_plugins/lib_formula/test/main.c =================================================================== --- tags/2.3.0/src_plugins/lib_formula/test/main.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_formula/test/main.c (revision 33253) @@ -0,0 +1,16 @@ +#include +#include "glue.c" +#include "../impedance.c" +int main() +{ + double tt, th, sh, d, res; + + if (scanf("%lf %lf %lf %lf", &tt, &th, &sh, &d) != 4) { + fprintf(stderr, "need: trace_width, trace_height, subst_height, dielect\n"); + return 1; + } + + res = pcb_impedance_microstrip(RND_MM_TO_COORD(tt), RND_MM_TO_COORD(th), RND_MM_TO_COORD(sh), d); + printf("res=%f\n", res); + return 0; +} Index: tags/2.3.0/src_plugins/lib_hid_pcbui/Makefile =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_lib_hid_common + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/lib_hid_pcbui/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/Plug.tmpasm (revision 33253) @@ -0,0 +1,15 @@ +put /local/pcb/mod {lib_hid_pcbui} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/lib_hid_pcbui/lib_hid_pcbui.o + $(PLUGDIR)/lib_hid_pcbui/layer_menu.o + $(PLUGDIR)/lib_hid_pcbui/routest.o + $(PLUGDIR)/lib_hid_pcbui/status.o + $(PLUGDIR)/lib_hid_pcbui/act.o + $(PLUGDIR)/lib_hid_pcbui/layersel.o +@] + +switch /local/pcb/lib_hid_pcbui/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/lib_hid_pcbui/act.c =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/act.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/act.c (revision 33253) @@ -0,0 +1,314 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017..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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include "board.h" +#include +#include +#include "conf_core.h" +#include +#include "draw.h" +#include +#include "layer.h" +#include "layer_vis.h" +#include "search.h" +#include "obj_subc_parent.h" + +#include + +#include "util.h" +#include "act.h" + +const char pcb_acts_Zoom_[] = + pcb_gui_acts_zoom + "Zoom(found|selected)\n"; +const char pcb_acth_Zoom[] = "GUI zoom"; +/* DOC: zoom.html */ +fgw_error_t pcb_act_Zoom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_acts_Zoom = pcb_acts_Zoom_; + PCB_GUI_NOGUI(); + + if (argc == 2) { + const char *vp; + + RND_ACT_CONVARG(1, FGW_STR, Zoom, vp = argv[1].val.str); + + if (rnd_strcasecmp(vp, "selected") == 0) { + rnd_box_t sb; + if (pcb_get_selection_bbox(&sb, PCB->Data) > 0) + rnd_gui->zoom_win(rnd_gui, sb.X1, sb.Y1, sb.X2, sb.Y2, 1); + else + rnd_message(RND_MSG_ERROR, "Can't zoom to selection: nothing selected\n"); + return 0; + } + + if (rnd_strcasecmp(vp, "found") == 0) { + rnd_box_t sb; + if (pcb_get_found_bbox(&sb, PCB->Data) > 0) + rnd_gui->zoom_win(rnd_gui, sb.X1, sb.Y1, sb.X2, sb.Y2, 1); + else + rnd_message(RND_MSG_ERROR, "Can't zoom to 'found': nothing found\n"); + return 0; + } + } + + return pcb_gui_act_zoom(res, argc, argv); +} + +const char pcb_acts_SwapSides[] = "SwapSides(|v|h|r, [S])"; +const char pcb_acth_SwapSides[] = "Swaps the side of the board you're looking at."; +/* DOC: swapsides.html */ +fgw_error_t pcb_act_SwapSides(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_layergrp_id_t active_group = pcb_layer_get_group(PCB, pcb_layer_stack[0]); + rnd_layergrp_id_t comp_group = -1, solder_group = -1; + rnd_bool comp_on = rnd_false, solder_on = rnd_false; + rnd_box_t vb; + rnd_coord_t x, y; + double xcent, ycent, xoffs, yoffs; + + PCB_GUI_NOGUI(); + + rnd_hid_get_coords("Click to center of flip", &x, &y, 0); + + x = pcb_crosshair.X; + y = pcb_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; +/* rnd_trace("SwapSides: xy=%mm;%mm cent=%mm;%mm ofs=%mm;%mm\n", x, y, (rnd_coord_t)xcent, (rnd_coord_t)ycent, (rnd_coord_t)xoffs, (rnd_coord_t)yoffs);*/ + + if (pcb_layergrp_list(PCB, PCB_LYT_BOTTOM | PCB_LYT_COPPER, &solder_group, 1) > 0) + solder_on = pcb_get_layer(PCB->Data, PCB->LayerGroups.grp[solder_group].lid[0])->meta.real.vis; + + if (pcb_layergrp_list(PCB, PCB_LYT_TOP | PCB_LYT_COPPER, &comp_group, 1) > 0) + comp_on = pcb_get_layer(PCB->Data, PCB->LayerGroups.grp[comp_group].lid[0])->meta.real.vis; + + pcb_draw_inhibit_inc(); + if (argc > 1) { + const char *a, *b = ""; + rnd_layer_id_t lid; + pcb_layer_type_t lyt; + + 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 '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); + rnd_conf_toggle_editor(show_solder_side); /* Swapped back below */ + break; + + default: + pcb_draw_inhibit_dec(); + RND_ACT_IRES(1); + return 0; + } + + switch (b[0]) { + case 'S': + case 's': + lyt = (pcb_layer_flags_(PCB_CURRLAYER(PCB)) & PCB_LYT_ANYTHING) | (!conf_core.editor.show_solder_side ? PCB_LYT_BOTTOM : PCB_LYT_TOP); + lid = pcb_layer_vis_last_lyt(lyt); + if (lid >= 0) + pcb_layervis_change_group_vis(&PCB->hidlib, lid, 1, 1); + } + } + + rnd_conf_toggle_editor(show_solder_side); + + if ((active_group == comp_group && comp_on && !solder_on) || (active_group == solder_group && solder_on && !comp_on)) { + rnd_bool new_solder_vis = conf_core.editor.show_solder_side; + + if (comp_group >= 0) + pcb_layervis_change_group_vis(&PCB->hidlib, PCB->LayerGroups.grp[comp_group].lid[0], !new_solder_vis, !new_solder_vis); + if (solder_group >= 0) + pcb_layervis_change_group_vis(&PCB->hidlib, PCB->LayerGroups.grp[solder_group].lid[0], new_solder_vis, new_solder_vis); + } + + pcb_draw_inhibit_dec(); + +/*rnd_trace("-jump-> %mm;%mm -> %mm;%mm\n", x, y, (rnd_coord_t)(x + xoffs), (rnd_coord_t)(y + yoffs));*/ + rnd_gui->pan(rnd_gui, rnd_round(x + xoffs), rnd_round(y + yoffs), 0); + rnd_gui->set_crosshair(rnd_gui, x, y, HID_SC_PAN_VIEWPORT); + + rnd_gui->invalidate_all(rnd_gui); + + RND_ACT_IRES(0); + return 0; +} + +const char pcb_acts_Popup[] = "Popup(MenuName, [obj-type])"; +const char pcb_acth_Popup[] = "Bring up the popup menu specified by MenuName, optionally modified with the object type under the cursor.\n"; +/* DOC: popup.html */ +fgw_error_t pcb_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; + + PCB_GUI_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; + pcb_any_obj_t *o; + + rnd_hid_get_coords("context sensitive popup: select object", &x, &y, 0); + + /* the 'E' mark of an extended object shall be top prio so it can be clicked even over some other subc part of the extobj */ + type = pcb_search_screen(x, y, PCB_OBJ_SUBC, &o1, &o2, &o3); + if ((type == PCB_OBJ_SUBC) && (pcb_attribute_get(&((pcb_any_obj_t *)o2)->Attributes, "extobj") != 0)) { + sprintf(name, "/popups/%s-extobj-subcircuit", a0); + goto do_popup; + } + + /* Normal search: lookg for padstacks ("pins") first */ + type = pcb_search_screen(x, y, PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART, &o1, &o2, &o3); + o = o2; + if ((type == 0) || ((o != NULL) && (pcb_gobj_parent_subc(o->parent_type, &o->parent) == NULL))) { + /* ...or anything else as a fallback */ + type = pcb_search_screen(x, y, PCB_OBJ_CLASS_REAL | PCB_LOOSE_SUBC(PCB_ACT_BOARD), &o1, &o2, &o3); + switch(type) { + case 0: tn = "none"; break; + default: + tn = pcb_obj_type_name(type); + break; + } + sprintf(name, "/popups/%s-%s", a0, tn); + } + else + sprintf(name, "/popups/%s-padstack-in-subc", a0); + sprintf(name2, "/popups/%s-misc", a0); + } + break; + case CTX_NONE: + sprintf(name, "/popups/%s", a0); + break; + + } + } + + do_popup:; + 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; +} + +const char pcb_acts_LayerHotkey[] = "LayerHotkey(layer, select|vis)"; +const char pcb_acth_LayerHotkey[] = "Change the key binding for a layer"; +/* DOC: layerhotkey.html */ +fgw_error_t pcb_act_LayerHotkey(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_layer_t *ly; + char *op; + const char *key, *val, *title, *msg; + fgw_error_t er; + fgw_arg_t r, args[4]; + + RND_ACT_CONVARG(1, FGW_LAYER, LayerHotkey, ly = fgw_layer(&argv[1])); + RND_ACT_CONVARG(2, FGW_STR, LayerHotkey, op = argv[2].val.str); + + if (rnd_strcasecmp(op, "select") == 0) { key = "pcb-rnd::key::select"; title = "set layer selection hotkey"; } + else if (rnd_strcasecmp(op, "vis") == 0) { key = "pcb-rnd::key::vis"; title = "set layer visibility hotkey"; } + else RND_ACT_FAIL(LayerHotkey); + + msg = + "Layer hotkey syntax is the same as\n" + "the 'a' field in the menu file: it is\n" + "a semicolon separated sequence of keys,\n" + "each is specified as modifierk,\n" + "where modifier is empty, Alt, Ctrl, Shift\n" + "and k is the name of the key. For example\n" + "{l shift-t} is written as:\n" + "l; Shiftt\n"; + + val = pcb_attribute_get(&ly->Attributes, key); + args[1].type = FGW_STR; args[1].val.cstr = msg; + args[2].type = FGW_STR; args[2].val.cstr = val; + args[3].type = FGW_STR; args[3].val.cstr = title; + er = rnd_actionv_bin(RND_ACT_HIDLIB, "promptfor", &r, 4, args); + + if ((er != 0) || ((r.type & FGW_STR) != FGW_STR)) { + fgw_arg_free(&rnd_fgw, &r); + RND_ACT_IRES(1); + return 0; + } + + pcb_attribute_put(&ly->Attributes, key, r.val.str); + fgw_arg_free(&rnd_fgw, &r); + + RND_ACT_IRES(0); + return 0; +} Index: tags/2.3.0/src_plugins/lib_hid_pcbui/act.h =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/act.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/act.h (revision 33253) @@ -0,0 +1,19 @@ +extern const char pcb_acts_Zoom_[]; +extern const char pcb_acth_Zoom[]; +fgw_error_t pcb_act_Zoom(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char pcb_acts_SwapSides[]; +extern const char pcb_acth_SwapSides[]; +fgw_error_t pcb_act_SwapSides(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char pcb_acts_Command[]; +extern const char pcb_acth_Command[]; +fgw_error_t pcb_act_Command(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char pcb_acts_Popup[]; +extern const char pcb_acth_Popup[]; +fgw_error_t pcb_act_Popup(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char pcb_acts_LayerHotkey[]; +extern const char pcb_acth_LayerHotkey[]; +fgw_error_t pcb_act_LayerHotkey(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/2.3.0/src_plugins/lib_hid_pcbui/infobar.c =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/infobar.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/infobar.c (revision 33253) @@ -0,0 +1,97 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "board.h" +#include "conf_core.h" +#include + +static rnd_hidval_t infobar_timer; +static int infobar_timer_active = 0; +static double last_interval = -2; +static double last_date = -1; +static int infobar_gui_inited = 0; + +static void pcb_infobar_brdchg_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + rnd_actionva(hidlib, "InfoBarFileChanged", "close", NULL); + if ((hidlib != NULL) && (hidlib->filename != NULL)) + last_date = rnd_file_mtime(NULL, PCB->hidlib.filename); + else + last_date = -1; +} + + +static void infobar_tick(rnd_hidval_t user_data) +{ + if (conf_core.rc.file_changed_interval > 0) { + infobar_timer = rnd_gui->add_timer(rnd_gui, infobar_tick, (conf_core.rc.file_changed_interval * 1000.0), user_data); + last_interval = conf_core.rc.file_changed_interval; + infobar_timer_active = 1; + } + else + infobar_timer_active = 0; + + if (infobar_timer_active) { /* check for file change */ + if ((PCB != NULL) && (PCB->hidlib.filename != NULL)) { + double last_chg = rnd_file_mtime(NULL, PCB->hidlib.filename); + if (last_chg > last_date) { + last_date = last_chg; + rnd_actionva(&PCB->hidlib, "InfoBarFileChanged", "open", NULL); + } + } + } +} + +static void pcb_infobar_update_conf(rnd_conf_native_t *cfg, int arr_idx) +{ + if ((!infobar_gui_inited) || (last_interval == conf_core.rc.file_changed_interval)) + return; + if ((infobar_timer_active) && (rnd_gui != NULL) && (rnd_gui->stop_timer != NULL)) { + rnd_gui->stop_timer(rnd_gui, infobar_timer); + infobar_timer_active = 0; + } + infobar_tick(infobar_timer); +} + + +static void pcb_infobar_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + infobar_gui_inited = 1; + pcb_infobar_brdchg_ev(hidlib, NULL, 0, NULL); /* this may have happened ebfore plugin init if file was specified on the CLI and is already loaded - pick up file data from memory */ + if (!infobar_timer_active) + infobar_tick(infobar_timer); +} + +static void pcb_infobar_fn_chg_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((PCB != NULL) && (PCB->hidlib.filename != NULL)) { + last_date = rnd_file_mtime(NULL, PCB->hidlib.filename); + rnd_actionva(hidlib, "InfoBarFileChanged", "close", NULL); + } +} + Index: tags/2.3.0/src_plugins/lib_hid_pcbui/layer_menu.c =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/layer_menu.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/layer_menu.c (revision 33253) @@ -0,0 +1,263 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017, 2018, 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include "board.h" +#include "data.h" +#include "conf_core.h" +#include +#include +#include "layer.h" +#include "layer_ui.h" +#include "layer_grp.h" +#include +#include +#include + +#include "layer_menu.h" + +static const char *menu_cookie = "lib_hid_pcbui layer menus"; + +static void layer_install_menu1(const char *anch, int view) +{ + int plen = strlen(anch); + rnd_menu_prop_t props; + char act[256], chk[256]; + int idx, max_ml, sect; + rnd_layergrp_id_t gid; + const pcb_menu_layers_t *ml; + gds_t path = {0}; + + memset(&props, 0, sizeof(props)); + props.action = act; + props.update_on = ""; + props.cookie = menu_cookie; + + /* prepare for appending the strings at the end of the path, "under" the anchor */ + gds_append_str(&path, anch); + gds_append(&path, '/'); + plen++; + + /* ui layers; have to go reverse to keep order because this will insert items */ + if ((view) && (vtp0_len(&pcb_uilayers) > 0)) { + for(idx = vtp0_len(&pcb_uilayers)-1; idx >= 0; idx--) { + pcb_layer_t *ly = pcb_uilayers.array[idx]; + if ((ly == NULL) || (ly->name == NULL)) + continue; + + props.checked = chk; + sprintf(act, "ToggleView(ui:%d)", idx); + sprintf(chk, "ChkView(ui:%d)", idx); + + gds_truncate(&path, plen); + gds_append_str(&path, " "); + gds_append_str(&path, ly->name); + rnd_hid_menu_create(path.array, &props); + } + + props.checked = NULL; + gds_truncate(&path, plen); + gds_append_str(&path, "[UI]"); + + rnd_hid_menu_create(path.array, &props); + } + + /* menu-only virtual layers; have to go reverse to keep order because this will insert items */ + for(ml = pcb_menu_layers, max_ml = 0; ml->name != NULL; ml++) max_ml++; + for(idx = max_ml-1; idx >= 0; idx--) { + ml = &pcb_menu_layers[idx]; + props.checked = chk; + if (view) { + sprintf(act, "ToggleView(%s)", ml->abbrev); + sprintf(chk, "ChkView(%s)", ml->abbrev); + } + else { + if (ml->sel_offs == 0) /* do not list layers that can not be selected */ + continue; + sprintf(act, "SelectLayer(%s)", ml->abbrev); + sprintf(chk, "ChkLayer(%s)", ml->abbrev); + } + gds_truncate(&path, plen); + gds_append_str(&path, " "); + gds_append_str(&path, ml->name); + rnd_hid_menu_create(path.array, &props); + } + + props.checked = NULL; + gds_truncate(&path, plen); + gds_append_str(&path, "[virtual]"); + rnd_hid_menu_create(path.array, &props); + + + /* have to go reverse to keep order because this will insert items */ + for(sect = 0; sect < 2; sect++) { + gds_truncate(&path, plen); + gds_append(&path, '-'); + props.foreground = NULL; + props.background = NULL; + props.checked = NULL; + *act = '\0'; + *chk = '\0'; + rnd_hid_menu_create(path.array, &props); + + for(gid = pcb_max_group(PCB)-1; gid >= 0; gid--) { + pcb_layergrp_t *g = &PCB->LayerGroups.grp[gid]; + int n; + + if (g->ltype & PCB_LYT_SUBSTRATE) + continue; + + if (!!sect != !!(PCB_LAYER_IN_STACK(g->ltype))) + continue; + + for(n = g->len-1; n >= 0; n--) { + rnd_layer_id_t lid = g->lid[n]; + pcb_layer_t *l = pcb_get_layer(PCB->Data, lid); + pcb_layer_type_t lyt = pcb_layer_flags_(l); + + props.background = &l->meta.real.color; + props.foreground = &rnd_conf.appearance.color.background; + props.checked = chk; + if (view) { + sprintf(act, "ToggleView(%ld)", lid+1); + sprintf(chk, "ChkView(%ld)", lid+1); + } + else { + sprintf(act, "SelectLayer(%ld)", lid+1); + sprintf(chk, "ChkLayer(%ld)", lid+1); + } + gds_truncate(&path, plen); + gds_append_str(&path, " "); + gds_append_str(&path, l->name); + rnd_hid_menu_create(path.array, &props); + } + + props.foreground = NULL; + props.background = NULL; + props.checked = NULL; + gds_truncate(&path, plen); + gds_append(&path, '['); + gds_append_str(&path, g->name); + gds_append(&path, ']'); + rnd_hid_menu_create(path.array, &props); + } + } + + gds_uninit(&path); +} + +static void custom_layer_attr_key(pcb_layer_t *l, rnd_layer_id_t lid, const char *attrname, const char *menu_prefix, const char *action_prefix, rnd_menu_prop_t *keyprops, gds_t *path, int plen) +{ + char *key = pcb_attribute_get(&l->Attributes, attrname); + if (key != NULL) { + keyprops->accel = key; + gds_truncate(path, plen); + rnd_append_printf(path, "%s %ld:%s", menu_prefix, lid+1, l->name); + sprintf((char *)keyprops->action, "%s(%ld)", action_prefix, lid+1); + rnd_hid_menu_create(path->array, keyprops); + } +} + + +static void layer_install_menu_key(const char *anch, int view) +{ + int plen = strlen(anch); + char act[256]; + rnd_layer_id_t lid; + pcb_layer_t *l; + rnd_menu_prop_t keyprops; + gds_t path = {0}; + + /* prepare for appending the strings at the end of the path, "under" the anchor */ + gds_append_str(&path, anch); + gds_append(&path, '/'); + plen++; + + memset(&keyprops, 0, sizeof(keyprops)); + keyprops.action = act; + keyprops.update_on = ""; + keyprops.cookie = menu_cookie; + + + for(lid = 0, l = PCB->Data->Layer; lid < PCB->Data->LayerN; lid++,l++) { + custom_layer_attr_key(l, lid, "pcb-rnd::key::select", "select", "SelectLayer", &keyprops, &path, plen); + custom_layer_attr_key(l, lid, "pcb-rnd::key::vis", "vis", "ToggleView", &keyprops, &path, plen); + } + + gds_uninit(&path); +} + +static int need_layer_menu_update = 0, need_layer_key_update = 0; +void pcb_layer_menu_batch_timer_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + int keys_done = 0; + + if (need_layer_menu_update) { +/*rnd_trace("layer menu update.\n");*/ + rnd_hid_menu_unload(rnd_gui, menu_cookie); + + layer_install_menu1("/anchored/@layerview", 1); + layer_install_menu1("/anchored/@layerpick", 0); + layer_install_menu_key("/anchored/@layerkeys", 0); + + need_layer_menu_update = 0; + keys_done = 1; + } + + if (need_layer_key_update) { +/*rnd_trace("layer key update timer!\n");*/ + if (!keys_done) + layer_install_menu_key("/anchored/@layerkeys", 0); + need_layer_key_update = 0; + } +} + +static void layer_install_menu(rnd_hidlib_t *hidlib) +{ + need_layer_menu_update = 1; + rnd_hid_gui_batch_timer(hidlib); +} + +void pcb_layer_menu_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + layer_install_menu(hidlib); + if ((rnd_gui != NULL) && (rnd_gui->update_menu_checkbox != NULL)) + rnd_gui->update_menu_checkbox(rnd_gui, NULL); +} + +void pcb_layer_menu_vis_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if ((rnd_gui != NULL) && (rnd_gui->update_menu_checkbox != NULL)) + rnd_gui->update_menu_checkbox(rnd_gui, NULL); +} + +void pcb_layer_menu_key_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + need_layer_key_update = 1; + rnd_hid_gui_batch_timer(hidlib); +} Index: tags/2.3.0/src_plugins/lib_hid_pcbui/layer_menu.h =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/layer_menu.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/layer_menu.h (revision 33253) @@ -0,0 +1,8 @@ +#include + +void pcb_layer_menu_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void pcb_layer_menu_vis_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void pcb_layer_menu_key_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void pcb_layer_menu_batch_timer_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); + + Index: tags/2.3.0/src_plugins/lib_hid_pcbui/layersel.c =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/layersel.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/layersel.c (revision 33253) @@ -0,0 +1,910 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include +#include +#include + +#include +#include "board.h" +#include "data.h" +#include "event.h" +#include "layer.h" +#include "layer_grp.h" +#include "layer_ui.h" +#include "layer_vis.h" +#include + +#include "layersel.h" + +static const char *grpsep[] = { /* 8 pixel high transparent for spacing */ + "1 8 1 1", + ". c None", + ".",".",".",".",".",".",".","." +}; + +static const char *closed_grp_layer_unsel[] = { /* layer unselected icon in a closed layer group */ + "10 8 2 1", + ". c None", + "x c #000000", + "..........", + "xx......xx", + "x........x", + "..........", + "..........", + "..........", + "x........x", + "xx......xx" +}; + +static const char *closed_grp_layer_sel[] = { /* layer unselected icon in a closed layer group */ + "10 8 3 1", + ". c None", + "x c #000000", + "o c #6EA5D7", + "..........", + "xx.xxxx.xx", + "x.xoooox.x", + ".xoooooox.", + ".xoooooox.", + ".xoooooox.", + "x.xoooox.x", + "xx.xxxx.xx" +}; + +static const char *closed_grp_layer_nosel[] = { /* layer unselected icon in a closed layer group */ + "10 8 1 1", + ". c None", + "..........", + "..........", + "..........", + "..........", + "..........", + "..........", + "..........", + ".........." +}; + +static const char *all_open_xpm[] = { +"10 10 3 1", +" c None", +"@ c #6EA5D7", +"+ c #000000", +" ++++ ", +" +@@+ ", +" +@@+ ", +"++++@@++++", +"+@@@@@@@@+", +"+@@@@@@@@+", +"++++@@++++", +" +@@+ ", +" +@@+ ", +" ++++ ", +}; + +static const char *all_closed_xpm[] = { +"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_open, wvis_off_open, wvis_on_closed, wvis_off_closed, wlab; + int wunsel_closed, wsel_closed; + gen_xpm_t on_open, off_open, on_closed, off_closed; + layersel_ctx_t *ls; + pcb_layer_t *ly; + const pcb_menu_layers_t *ml; + unsigned grp_vis:1; +} ls_layer_t; + +/* virtual group GIDs */ +typedef enum { + LGS_invlaid = -1, + LGS_VIRTUAL = 0, + LGS_UI = 1, + LGS_max +} virt_grp_id_t; + +typedef struct { + int wopen, wclosed; + layersel_ctx_t *ls; + rnd_layergrp_id_t gid; + virt_grp_id_t vid; + unsigned int is_open:1; +} ls_group_t; + +struct layersel_ctx_s { + rnd_hid_dad_subdialog_t sub; + int sub_inited; + int lock_vis, lock_sel; + int w_last_sel, w_last_sel_closed, w_last_unsel_closed; + vtp0_t real_layer, menu_layer, ui_layer; /* -> ls_layer_t */ + vtp0_t group; /* -> ls_group_t */ +}; + +static layersel_ctx_t layersel; + +static ls_layer_t *lys_get(layersel_ctx_t *ls, vtp0_t *vt, size_t idx, int alloc) +{ + ls_layer_t **res = (ls_layer_t **)vtp0_get(vt, idx, alloc); + if (res == NULL) + return NULL; + if ((*res == NULL) && alloc) { + *res = calloc(sizeof(ls_layer_t), 1); + (*res)->ls = ls; + } + return *res; +} + +static ls_group_t *lgs_get_(layersel_ctx_t *ls, size_t gid, int alloc) +{ + ls_group_t **res = (ls_group_t **)vtp0_get(&ls->group, gid, alloc); + if (res == NULL) + return NULL; + if ((*res == NULL) && alloc) { + *res = calloc(sizeof(ls_group_t), 1); + (*res)->ls = ls; + (*res)->is_open = 1; + } + return *res; +} + +static ls_group_t *lgs_get_real(layersel_ctx_t *ls, rnd_layergrp_id_t gid, int alloc) +{ + ls_group_t *lgs = lgs_get_(ls, gid+LGS_max, alloc); + lgs->gid = gid; + lgs->vid = -1; + return lgs; +} + +static void lgs_reset(layersel_ctx_t *ls) +{ + ls->group.used = 0; +} + + +static ls_group_t *lgs_get_virt(layersel_ctx_t *ls, virt_grp_id_t vid, int alloc) +{ + ls_group_t *lgs = lgs_get_(ls, vid, alloc); + lgs->gid = -1; + lgs->vid = vid; + return lgs; +} + +static void locked_layersel(layersel_ctx_t *ls, int wid, int wid_unsel_closed, int wid_sel_closed) +{ + if (ls->lock_sel > 0) + return; + + ls->lock_sel = 1; + if (ls->w_last_sel != 0) { + rnd_gui->attr_dlg_widget_state(ls->sub.dlg_hid_ctx, ls->w_last_sel, 1); + rnd_gui->attr_dlg_widget_hide(ls->sub.dlg_hid_ctx, ls->w_last_unsel_closed, 0); + rnd_gui->attr_dlg_widget_hide(ls->sub.dlg_hid_ctx, ls->w_last_sel_closed, 1); + } + ls->w_last_sel = wid; + ls->w_last_sel_closed = wid_sel_closed; + ls->w_last_unsel_closed = wid_unsel_closed; + if (ls->w_last_sel != 0) { + rnd_gui->attr_dlg_widget_state(ls->sub.dlg_hid_ctx, ls->w_last_sel, 2); + rnd_gui->attr_dlg_widget_hide(ls->sub.dlg_hid_ctx, ls->w_last_unsel_closed, 1); + rnd_gui->attr_dlg_widget_hide(ls->sub.dlg_hid_ctx, ls->w_last_sel_closed, 0); + } + ls->lock_sel = 0; +} + +static void locked_layervis_ev(layersel_ctx_t *ls) +{ + ls->lock_vis++; + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERVIS_CHANGED, NULL); + ls->lock_vis--; +} + +static void lys_update_vis(ls_layer_t *lys, rnd_bool_t vis) +{ + rnd_gui->attr_dlg_widget_hide(lys->ls->sub.dlg_hid_ctx, lys->wvis_on_open, !vis); + rnd_gui->attr_dlg_widget_hide(lys->ls->sub.dlg_hid_ctx, lys->wvis_on_closed, !vis); + rnd_gui->attr_dlg_widget_hide(lys->ls->sub.dlg_hid_ctx, lys->wvis_off_open, !!vis); + rnd_gui->attr_dlg_widget_hide(lys->ls->sub.dlg_hid_ctx, lys->wvis_off_closed, !!vis); +} + +static void layer_select(ls_layer_t *lys) +{ + rnd_bool *vis = NULL; + + if (lys->ly != NULL) { + if (lys->grp_vis) { + rnd_layer_id_t lid = lys->ly - PCB->Data->Layer; + pcb_layervis_change_group_vis(&PCB->hidlib, lid, 1, 1); + } + else { + vis = &lys->ly->meta.real.vis; + *vis = 1; + } + PCB->RatDraw = 0; + } + else if (lys->ml != NULL) { + vis = (rnd_bool *)((char *)PCB + lys->ml->vis_offs); + *vis = 1; + rnd_actionva(&PCB->hidlib, "SelectLayer", lys->ml->select_name, NULL); + } + else + return; + + rnd_hid_redraw(PCB); + + if (vis != NULL) { + lys_update_vis(lys, *vis); + locked_layervis_ev(lys->ls); + } + locked_layersel(lys->ls, lys->wlab, lys->wunsel_closed, lys->wsel_closed); +} + +static void layer_sel_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + layer_select(attr->user_data); +} + +static void group_sync_core(pcb_board_t *pcb, ls_group_t *lgs, int update_from_core) +{ + pcb_layergrp_t *g; + + if (lgs->gid < 0) + return; + g = pcb_get_layergrp(pcb, lgs->gid); + if (g == NULL) + return; + + if (update_from_core) + lgs->is_open = !!g->open; + else + g->open = !!lgs->is_open; +} + +static void group_open_close_update(ls_group_t *lgs) +{ + group_sync_core(PCB, lgs, 0); + + rnd_gui->attr_dlg_widget_hide(lgs->ls->sub.dlg_hid_ctx, lgs->wopen, !lgs->is_open); + rnd_gui->attr_dlg_widget_hide(lgs->ls->sub.dlg_hid_ctx, lgs->wclosed, !!lgs->is_open); +} + +static void all_open_close(int is_open) +{ + int n; + for(n = 0; n < layersel.group.used; n++) { + ls_group_t *lgs = layersel.group.array[n]; + if ((lgs != NULL) && (lgs->is_open != is_open)) { + lgs->is_open = is_open; + group_open_close_update(lgs); + } + + } +} + +static void all_open_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + all_open_close(1); +} + +static void all_close_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + all_open_close(0); +} + +static void all_vis_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(rnd_gui->get_dad_hidlib(hid_ctx), "ToggleView", "all", "vis", "set", NULL); +} + +static void all_invis_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(rnd_gui->get_dad_hidlib(hid_ctx), "ToggleView", "all", "vis", "clear", NULL); +} + +/* Select the first visible layer (physically) below the one turned off or + reenable the original if all are off; this how we ensure the current layer + is visible and avoid drawing on inivisible layers */ +static void ensure_visible_current(pcb_board_t *pcb, layersel_ctx_t *ls) +{ + pcb_layer_t *ly; + rnd_layer_id_t lid; + rnd_layergrp_id_t gid; + pcb_layer_t *l; + ls_layer_t *lys; + int repeat = 0; + + ly = PCB_CURRLAYER(pcb); + if ((ly == NULL) || (ly->meta.real.vis)) + return; + + /* currently selected layer lost visible state - choose another */ + + /* At the moment the layer selector displays only board layers which are always real */ + assert(!PCB_CURRLAYER(pcb)->is_bound); + + /* look for the next one to enable, group-wise */ + for(gid = PCB_CURRLAYER(pcb)->meta.real.grp + 1; gid != PCB_CURRLAYER(pcb)->meta.real.grp; gid++) { + pcb_layergrp_t *g; + if (gid >= pcb_max_group(pcb)) { + gid = 0; + repeat++; + if (repeat > 1) + break; /* failed to find one */ + } + g = &pcb->LayerGroups.grp[gid]; + if (g->len < 1) + continue; + l = pcb->Data->Layer + g->lid[0]; + if (l->meta.real.vis) + goto change_selection; + } + + /* fallback: all off; turn the current one back on */ + l = PCB_CURRLAYER(pcb); + + change_selection:; + lid = pcb_layer_id(pcb->Data, l); + pcb_layervis_change_group_vis(&pcb->hidlib, lid, 1, 1); + + lys = lys_get(ls, &ls->real_layer, lid, 0); + if (lys != 0) + locked_layersel(lys->ls, lys->wlab, lys->wunsel_closed, lys->wsel_closed); + else + locked_layersel(lys->ls, 0, 0, 0); +} + + +static void layer_vis_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + ls_layer_t *lys = attr->user_data; + rnd_bool *vis; + + if (lys->ly != NULL) + vis = &lys->ly->meta.real.vis; + else if (lys->ml != NULL) + vis = (rnd_bool *)((char *)PCB + lys->ml->vis_offs); + else + return; + + if (lys->grp_vis) { + rnd_layer_id_t lid = lys->ly - PCB->Data->Layer; + pcb_layervis_change_group_vis(&PCB->hidlib, lid, !*vis, 1); + } + else { + *vis = !(*vis); + lys_update_vis(lys, *vis); + locked_layervis_ev(lys->ls); + } + + ensure_visible_current(PCB, lys->ls); + + rnd_hid_redraw(PCB); +} + +static void layer_right_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + ls_layer_t *lys = attr->user_data; + + /* enable the popup only when there is a real layer behind the button; + example: rats is selectable, drawable, but there's no real layer */ + if (lys->ly == NULL) + return; + + layer_select(lys); + rnd_actionva(&PCB->hidlib, "Popup", "layer", NULL); +} + +extern rnd_layergrp_id_t pcb_actd_EditGroup_gid; +static void group_right_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + ls_group_t *grp = attr->user_data; + if (grp->gid < 0) + return; + pcb_actd_EditGroup_gid = grp->gid; + rnd_actionva(&PCB->hidlib, "Popup", "group", NULL); +} + + +static void group_open_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + ls_group_t *lgs = attr->user_data; + lgs->is_open = !lgs->is_open; + + group_open_close_update(lgs); +} + +/* 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_begin_grp_open(layersel_ctx_t *ls, const char *name, ls_group_t *lsg) +{ + RND_DAD_BEGIN_HBOX(ls->sub.dlg); + lsg->wopen = RND_DAD_CURRENT(ls->sub.dlg); + + /* vertical group name */ + RND_DAD_LABEL(ls->sub.dlg, name); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_TIGHT | RND_HATF_TEXT_VERTICAL | RND_HATF_TEXT_TRUNCATED); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, lsg); + RND_DAD_RIGHT_CB(ls->sub.dlg, group_right_cb); + RND_DAD_CHANGE_CB(ls->sub.dlg, group_open_cb); + RND_DAD_HELP(ls->sub.dlg, name); + + /* vert sep */ + RND_DAD_BEGIN_HBOX(ls->sub.dlg); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_TIGHT | RND_HATF_FRAME); + RND_DAD_END(ls->sub.dlg); + + /* layer list box */ + RND_DAD_BEGIN_VBOX(ls->sub.dlg); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_TIGHT); +} + +static void layersel_end_grp_open(layersel_ctx_t *ls) +{ + RND_DAD_END(ls->sub.dlg); + RND_DAD_END(ls->sub.dlg); +} + +static void layersel_begin_grp_closed(layersel_ctx_t *ls, const char *name, ls_group_t *lsg) +{ + RND_DAD_BEGIN_HBOX(ls->sub.dlg); + lsg->wclosed = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_LABEL(ls->sub.dlg, name); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, lsg); + RND_DAD_RIGHT_CB(ls->sub.dlg, group_right_cb); + RND_DAD_CHANGE_CB(ls->sub.dlg, group_open_cb); + + /* vert sep */ + RND_DAD_BEGIN_HBOX(ls->sub.dlg); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_TIGHT | RND_HATF_FRAME); + RND_DAD_END(ls->sub.dlg); + +} + +static void layersel_end_grp_closed(layersel_ctx_t *ls) +{ + RND_DAD_END(ls->sub.dlg); +} + + +static void layersel_create_layer_open(layersel_ctx_t *ls, ls_layer_t *lys, const char *name, const rnd_color_t *color, int brd, int hatch, int selectable) +{ + layer_vis_box(&lys->on_open, 1, color, brd, hatch, 16, 16, 5); + layer_vis_box(&lys->off_open, 0, color, brd, hatch, 16, 16, 5); + + RND_DAD_BEGIN_HBOX(ls->sub.dlg); + RND_DAD_PICTURE(ls->sub.dlg, lys->on_open.xpm); + lys->wvis_on_open = 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_open.xpm); + lys->wvis_off_open = 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_LABEL(ls->sub.dlg, name); + lys->wlab = RND_DAD_CURRENT(ls->sub.dlg); + RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, lys); + if (selectable) { + RND_DAD_CHANGE_CB(ls->sub.dlg, layer_sel_cb); + RND_DAD_RIGHT_CB(ls->sub.dlg, layer_right_cb); + } + RND_DAD_END(ls->sub.dlg); +} + +static void layersel_create_layer_closed(layersel_ctx_t *ls, ls_layer_t *lys, const char *name, const rnd_color_t *color, int brd, int hatch, int selected, int selectable) +{ + layer_vis_box(&lys->on_closed, 1, color, brd, hatch, 10, 10, 0); + layer_vis_box(&lys->off_closed, 0, color, brd, hatch, 10, 10, 0); + + RND_DAD_BEGIN_VBOX(ls->sub.dlg); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_TIGHT); + RND_DAD_PICTURE(ls->sub.dlg, lys->on_closed.xpm); + lys->wvis_on_closed = 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_HELP(ls->sub.dlg, name); + RND_DAD_PICTURE(ls->sub.dlg, lys->off_closed.xpm); + lys->wvis_off_closed = 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_HELP(ls->sub.dlg, name); + if (selectable) { + RND_DAD_PICTURE(ls->sub.dlg, closed_grp_layer_unsel); + if (selected) + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_HIDE); + lys->wunsel_closed = 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_HELP(ls->sub.dlg, name); + RND_DAD_PICTURE(ls->sub.dlg, closed_grp_layer_sel); + if (!selected) + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_HIDE); + lys->wsel_closed = 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_HELP(ls->sub.dlg, name); + } + else { + RND_DAD_PICTURE(ls->sub.dlg, closed_grp_layer_nosel); + lys->wunsel_closed = lys->wsel_closed = RND_DAD_CURRENT(ls->sub.dlg); + } + RND_DAD_END(ls->sub.dlg); +} + +static void layersel_create_grp(layersel_ctx_t *ls, pcb_board_t *pcb, pcb_layergrp_t *g, ls_group_t *lgs, int is_open) +{ + rnd_cardinal_t n; + const char *gname = g->name == NULL ? "" : g->name; + + if (is_open) + layersel_begin_grp_open(ls, gname, lgs); + else + layersel_begin_grp_closed(ls, gname, lgs); + for(n = 0; n < g->len; n++) { + pcb_layer_t *ly = pcb_get_layer(pcb->Data, g->lid[n]); + assert(ly != NULL); + if (ly != NULL) { + int brd = (((ly != NULL) && (ly->comb & PCB_LYC_SUB)) ? 2 : 1); + int hatch = (((ly != NULL) && (ly->comb & PCB_LYC_AUTO)) ? 1 : 0); + const rnd_color_t *clr = &ly->meta.real.color; + ls_layer_t *lys = lys_get(ls, &ls->real_layer, g->lid[n], 1); + + lys->ly = ly; + lys->grp_vis = 1; + if (is_open) + layersel_create_layer_open(ls, lys, ly->name, clr, brd, hatch, 1); + else + layersel_create_layer_closed(ls, lys, ly->name, clr, brd, hatch, (ly ==PCB_CURRLAYER(PCB)), 1); + } + } + if (is_open) + layersel_end_grp_open(ls); + else + layersel_end_grp_closed(ls); +} + +static void layersel_add_grpsep(layersel_ctx_t *ls) +{ + RND_DAD_BEGIN_HBOX(ls->sub.dlg); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_EXPFILL); + RND_DAD_PICTURE(ls->sub.dlg, grpsep); + RND_DAD_END(ls->sub.dlg); + +} + +/* Editable layer groups that are part of the stack */ +static void layersel_create_stack(layersel_ctx_t *ls, pcb_board_t *pcb) +{ + rnd_layergrp_id_t gid; + pcb_layergrp_t *g; + rnd_cardinal_t created = 0; + + for(gid = 0, g = pcb->LayerGroups.grp; gid < pcb->LayerGroups.len; gid++,g++) { + ls_group_t *lgs; + + if (!(PCB_LAYER_IN_STACK(g->ltype)) || (g->ltype & PCB_LYT_SUBSTRATE)) + continue; + if (created > 0) + layersel_add_grpsep(ls); + lgs = lgs_get_real(ls, gid, 1); + layersel_create_grp(ls, pcb, g, lgs, 1); + layersel_create_grp(ls, pcb, g, lgs, 0); + created++; + } +} + +/* Editable layer groups that are not part of the stack */ +static void layersel_create_global(layersel_ctx_t *ls, pcb_board_t *pcb) +{ + rnd_layergrp_id_t gid; + pcb_layergrp_t *g; + rnd_cardinal_t created = 0; + + for(gid = 0, g = pcb->LayerGroups.grp; gid < pcb->LayerGroups.len; gid++,g++) { + ls_group_t *lgs; + + if (PCB_LAYER_IN_STACK(g->ltype)) + continue; + if (created > 0) + layersel_add_grpsep(ls); + lgs = lgs_get_real(ls, gid, 1); + layersel_create_grp(ls, pcb, g, lgs, 1); + layersel_create_grp(ls, pcb, g, lgs, 0); + created++; + } +} + +/* hardwired/virtual: typically Non-editable layers (no group) */ +static void layersel_create_virtual(layersel_ctx_t *ls, pcb_board_t *pcb) +{ + const pcb_menu_layers_t *ml; + int n; + ls_group_t *lgs = lgs_get_virt(ls, LGS_VIRTUAL, 1); + + layersel_begin_grp_open(ls, "Virtual", lgs); + for(n = 0, ml = pcb_menu_layers; ml->name != NULL; n++,ml++) { + ls_layer_t *lys = lys_get(ls, &ls->menu_layer, n, 1); + lys->ml = ml; + lys->grp_vis = 0; + layersel_create_layer_open(ls, lys, ml->name, ml->force_color, 1, 0, (ml->sel_offs != 0)); + } + layersel_end_grp_open(ls); + + layersel_begin_grp_closed(ls, "Virtual", lgs); + for(n = 0, ml = pcb_menu_layers; ml->name != NULL; n++,ml++) { + ls_layer_t *lys = lys_get(ls, &ls->menu_layer, n, 0); + layersel_create_layer_closed(ls, lys, ml->name, ml->force_color, 1, 0, 0, (ml->sel_offs != 0)); + } + layersel_end_grp_closed(ls); +} + +/* user-interface layers (no group) */ +static void layersel_create_ui(layersel_ctx_t *ls, pcb_board_t *pcb) +{ + ls_group_t *lgs = lgs_get_virt(ls, LGS_UI, 1); + int n; + + layersel_begin_grp_open(ls, "UI", lgs); + if (vtp0_len(&pcb_uilayers) == 0) + RND_DAD_LABEL(ls->sub.dlg, "(no layers)"); + for(n = 0; n < vtp0_len(&pcb_uilayers); n++) { + pcb_layer_t *ly = pcb_uilayers.array[n]; + if ((ly != NULL) && (ly->name != NULL)) { + ls_layer_t *lys = lys_get(ls, &ls->ui_layer, n, 1); + lys->ly = ly; + lys->grp_vis = 0; + layersel_create_layer_open(ls, lys, ly->name, &ly->meta.real.color, 1, 0, 0); + } + } + layersel_end_grp_open(ls); + + layersel_begin_grp_closed(ls, "UI", lgs); + for(n = 0; n < vtp0_len(&pcb_uilayers); n++) { + pcb_layer_t *ly = pcb_uilayers.array[n]; + if ((ly != NULL) && (ly->name != NULL)) { + ls_layer_t *lys = lys_get(ls, &ls->ui_layer, n, 0); + layersel_create_layer_closed(ls, lys, ly->name, &ly->meta.real.color, 1, 0, 0, 0); + } + } + layersel_end_grp_closed(ls); +} + +static void hsep(layersel_ctx_t *ls) +{ + RND_DAD_BEGIN_VBOX(ls->sub.dlg); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_TIGHT | RND_HATF_FRAME); + RND_DAD_END(ls->sub.dlg); +} + +static void layersel_docked_create(layersel_ctx_t *ls, pcb_board_t *pcb) +{ + lgs_reset(ls); + RND_DAD_BEGIN_VBOX(ls->sub.dlg); + RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_EXPFILL | RND_HATF_TIGHT | RND_HATF_SCROLL); + layersel_create_stack(&layersel, pcb); + hsep(&layersel); + layersel_create_global(&layersel, pcb); + hsep(&layersel); + layersel_create_virtual(&layersel, pcb); + layersel_add_grpsep(ls); + layersel_create_ui(&layersel, pcb); + layersel_add_grpsep(ls); + RND_DAD_BEGIN_HBOX(ls->sub.dlg); + RND_DAD_PICBUTTON(ls->sub.dlg, all_open_xpm); + RND_DAD_HELP(ls->sub.dlg, "expand/open all layer groups\nso that layer names are\ndisplayed, one layer per row"); + RND_DAD_CHANGE_CB(ls->sub.dlg, all_open_cb); + RND_DAD_PICBUTTON(ls->sub.dlg, all_closed_xpm); + RND_DAD_HELP(ls->sub.dlg, "collapse/close all layer groups\nso that layer names are\nnot displayed,\neach row is a layer group"); + RND_DAD_CHANGE_CB(ls->sub.dlg, all_close_cb); + 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, all_vis_cb); + 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, all_invis_cb); + 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, 180, 200); + RND_DAD_MINSIZE(ls->sub.dlg, 100, 100); + ls->w_last_sel = 0; +} + +static void layersel_update_vis(layersel_ctx_t *ls, pcb_board_t *pcb) +{ + pcb_layer_t *ly = pcb->Data->Layer; + ls_layer_t **lys = (ls_layer_t **)ls->real_layer.array; + ls_group_t **lgs = (ls_group_t **)ls->group.array; + const pcb_menu_layers_t *ml; + rnd_cardinal_t n; + + if (lys == NULL) + return; + + for(n = 0; n < pcb->Data->LayerN; n++,ly++,lys++) { + if (*lys == NULL) + continue; + lys_update_vis(*lys, ly->meta.real.vis); + } + + + lys = (ls_layer_t **)ls->menu_layer.array; + for(ml = pcb_menu_layers; ml->name != NULL; ml++,lys++) { + rnd_bool *b; + if (*lys == NULL) + continue; + b = (rnd_bool *)((char *)pcb + ml->vis_offs); + lys_update_vis(*lys, *b); + } + + lys = (ls_layer_t **)ls->ui_layer.array; + for(n = 0; n < vtp0_len(&pcb_uilayers); n++,lys++) { + pcb_layer_t *ly = pcb_uilayers.array[n]; + if (ly != NULL) + lys_update_vis(*lys, ly->meta.real.vis); + } + + /* update group open/close hides */ + for(n = 0; n < vtp0_len(&ls->group); n++,lgs++) { + if (*lgs == NULL) + continue; + + group_sync_core(pcb, *lgs, 1); + rnd_gui->attr_dlg_widget_hide(ls->sub.dlg_hid_ctx, (*lgs)->wopen, !(*lgs)->is_open); + rnd_gui->attr_dlg_widget_hide(ls->sub.dlg_hid_ctx, (*lgs)->wclosed, (*lgs)->is_open); + } + + { /* ifPCB_CURRLAYER(PCB) is not selected, select it */ + ls_layer_t *lys = lys_get(ls, &ls->real_layer, pcb_layer_id(pcb->Data,PCB_CURRLAYER(pcb)), 0); + if ((lys != NULL) && (lys->wlab != ls->w_last_sel)) + locked_layersel(ls, lys->wlab, lys->wunsel_closed, lys->wsel_closed); + } + + ensure_visible_current(pcb, ls); +} + +static void layersel_build(void) +{ + layersel_docked_create(&layersel, PCB); + if (rnd_hid_dock_enter(&layersel.sub, RND_HID_DOCK_LEFT, "layersel") == 0) { + layersel.sub_inited = 1; + layersel_update_vis(&layersel, PCB); + } +} + +void pcb_layersel_gui_init_ev(rnd_hidlib_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_build(); +} + +void pcb_layersel_vis_chg_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pcb_board_t *pcb = (pcb_board_t *)hidlib; + if ((!layersel.sub_inited) || (layersel.lock_vis > 0)) + return; + layersel_update_vis(&layersel, pcb); +} + +void pcb_layersel_stack_chg_ev(rnd_hidlib_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(); + } +} Index: tags/2.3.0/src_plugins/lib_hid_pcbui/layersel.h =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/layersel.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/layersel.h (revision 33253) @@ -0,0 +1,3 @@ +void pcb_layersel_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void pcb_layersel_vis_chg_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void pcb_layersel_stack_chg_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); Index: tags/2.3.0/src_plugins/lib_hid_pcbui/lib_hid_pcbui.c =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/lib_hid_pcbui.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/lib_hid_pcbui.c (revision 33253) @@ -0,0 +1,164 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include "event.h" + +#include "layer_menu.h" +#include "layersel.h" +#include "routest.h" +#include +#include "status.h" +#include "act.h" + +#include "util.c" +#include "rendering.c" +#include "infobar.c" +#include "title.c" + + +static const char *layer_cookie = "lib_hid_pcbui/layer"; +static const char *rst_cookie = "lib_hid_pcbui/route_style"; +static const char *act_cookie = "lib_hid_pcbui/actions"; +static const char *status_cookie = "lib_hid_pcbui/status"; +static const char *status_rd_cookie = "lib_hid_pcbui/status/readouts"; +static const char *rendering_cookie = "lib_hid_pcbui/rendering"; +static const char *infobar_cookie = "lib_hid_pcbui/infobar"; +static const char *title_cookie = "lib_hid_pcbui/title"; +static const char *layersel_cookie = "lib_hid_pcbui/layersel"; + +static rnd_action_t rst_action_list[] = { + {"AdjustStyle", pcb_act_AdjustStyle, pcb_acth_AdjustStyle, pcb_acts_AdjustStyle} +}; + +static rnd_action_t status_action_list[] = { + {"StatusSetText", pcb_act_StatusSetText, pcb_acth_StatusSetText, pcb_acts_StatusSetText}, + {"DescribeLocation", pcb_act_DescribeLocation, pcb_acth_DescribeLocation, pcb_acts_DescribeLocation} +}; + +static rnd_action_t act_action_list[] = { + {"Zoom", pcb_act_Zoom, pcb_acth_Zoom, pcb_acts_Zoom_}, + {"ZoomTo", pcb_act_Zoom, pcb_acth_Zoom, pcb_acts_Zoom_}, + {"SwapSides", pcb_act_SwapSides, pcb_acth_SwapSides, pcb_acts_SwapSides}, + {"Popup", pcb_act_Popup, pcb_acth_Popup, pcb_acts_Popup}, + {"LayerHotkey", pcb_act_LayerHotkey, pcb_acth_LayerHotkey, pcb_acts_LayerHotkey} +}; + +int pplg_check_ver_lib_hid_pcbui(int ver_needed) { return 0; } + + +void pplg_uninit_lib_hid_pcbui(void) +{ + rnd_remove_actions_by_cookie(rst_cookie); + rnd_remove_actions_by_cookie(status_cookie); + rnd_remove_actions_by_cookie(act_cookie); + rnd_event_unbind_allcookie(layer_cookie); + rnd_event_unbind_allcookie(rst_cookie); + rnd_event_unbind_allcookie(status_cookie); + rnd_event_unbind_allcookie(rendering_cookie); + rnd_event_unbind_allcookie(infobar_cookie); + rnd_event_unbind_allcookie(title_cookie); + rnd_event_unbind_allcookie(layersel_cookie); + rnd_conf_hid_unreg(rst_cookie); + rnd_conf_hid_unreg(status_cookie); + rnd_conf_hid_unreg(status_rd_cookie); + rnd_conf_hid_unreg(infobar_cookie); + rnd_toolbar_uninit(); +} + +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)) +{ + 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_lib_hid_pcbui(void) +{ +TODO("padstack: remove some paths when route style has proto") + const char *rpaths[] = {"design/line_thickness", "design/via_thickness", "design/via_drilling_hole", "design/clearance", NULL}; + const char *stpaths[] = { "editor/show_solder_side", "design/line_thickness", "editor/all_direction_lines", "editor/line_refraction", "editor/rubber_band_mode", "design/via_thickness", "design/via_drilling_hole", "design/clearance", "design/text_scale", "design/text_thickness", "editor/buffer_number", "editor/grid_unit", "editor/grid", "appearance/compact", NULL }; + const char *rdpaths[] = { "editor/grid_unit", "appearance/compact", NULL }; + const char *ibpaths[] = { "rc/file_changed_interval", NULL }; + static rnd_conf_hid_callbacks_t rcb[sizeof(rpaths)/sizeof(rpaths[0])]; + static rnd_conf_hid_callbacks_t stcb[sizeof(stpaths)/sizeof(stpaths[0])]; + static rnd_conf_hid_callbacks_t rdcb[sizeof(rdpaths)/sizeof(rdpaths[0])]; + static rnd_conf_hid_callbacks_t ibcb[sizeof(rdpaths)/sizeof(ibpaths[0])]; + + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(rst_action_list, rst_cookie); + RND_REGISTER_ACTIONS(status_action_list, status_cookie); + RND_REGISTER_ACTIONS(act_action_list, act_cookie); + + rnd_event_bind(RND_EVENT_BOARD_CHANGED, pcb_layer_menu_update_ev, NULL, layer_cookie); + rnd_event_bind(PCB_EVENT_LAYERS_CHANGED, pcb_layer_menu_update_ev, NULL, layer_cookie); + rnd_event_bind(PCB_EVENT_LAYERS_CHANGED, pcb_layersel_stack_chg_ev, NULL, layersel_cookie); + rnd_event_bind(PCB_EVENT_LAYERVIS_CHANGED, pcb_layer_menu_vis_update_ev, NULL, layer_cookie); + rnd_event_bind(PCB_EVENT_LAYERVIS_CHANGED, pcb_layersel_vis_chg_ev, NULL, layersel_cookie); + rnd_event_bind(PCB_EVENT_LAYER_KEY_CHANGE, pcb_layer_menu_key_update_ev, NULL, layer_cookie); + rnd_event_bind(PCB_EVENT_ROUTE_STYLES_CHANGED, pcb_rst_update_ev, NULL, rst_cookie); + rnd_event_bind(RND_EVENT_BOARD_CHANGED, pcb_rst_update_ev, NULL, rst_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, pcb_rst_gui_init_ev, NULL, rst_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, pcb_layersel_gui_init_ev, NULL, layersel_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, pcb_status_gui_init_ev, NULL, status_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, pcb_rendering_gui_init_ev, NULL, rendering_cookie); + rnd_event_bind(RND_EVENT_USER_INPUT_KEY, pcb_status_st_update_ev, NULL, status_cookie); + rnd_event_bind(RND_EVENT_CROSSHAIR_MOVE, pcb_status_rd_update_ev, NULL, status_cookie); + rnd_event_bind(RND_EVENT_BOARD_CHANGED, pcb_infobar_brdchg_ev, NULL, infobar_cookie); + rnd_event_bind(RND_EVENT_BOARD_FN_CHANGED, pcb_infobar_fn_chg_ev, NULL, infobar_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, pcb_infobar_gui_init_ev, NULL, infobar_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, pcb_title_gui_init_ev, NULL, title_cookie); + rnd_event_bind(RND_EVENT_BOARD_CHANGED, pcb_title_board_changed_ev, NULL, title_cookie); + rnd_event_bind(RND_EVENT_BOARD_META_CHANGED, pcb_title_meta_changed_ev, NULL, title_cookie); + rnd_event_bind(RND_EVENT_GUI_BATCH_TIMER, pcb_layer_menu_batch_timer_ev, NULL, layer_cookie); + rnd_event_bind(RND_EVENT_GUI_BATCH_TIMER, pcb_rst_menu_batch_timer_ev, NULL, rst_cookie); + + install_events(rst_cookie, rpaths, rcb, pcb_rst_update_conf); + install_events(status_cookie, stpaths, stcb, pcb_status_st_update_conf); + install_events(status_rd_cookie, rdpaths, rdcb, pcb_status_rd_update_conf); + install_events(infobar_cookie, ibpaths, ibcb, pcb_infobar_update_conf); + + rnd_toolbar_init(); + + return 0; +} Index: tags/2.3.0/src_plugins/lib_hid_pcbui/lib_hid_pcbui.pup =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/lib_hid_pcbui.pup (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/lib_hid_pcbui.pup (revision 33253) @@ -0,0 +1,7 @@ +$class lib +$short common PCB-related GUI elements +$long PCB related helper functions for GUI HIDs +$state works +$package lib-gui +dep lib_hid_common +default disable-all Index: tags/2.3.0/src_plugins/lib_hid_pcbui/rendering.c =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/rendering.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/rendering.c (revision 33253) @@ -0,0 +1,99 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "board.h" +#include "conf_core.h" +#include "funchash_core.h" +#include "layer.h" + +static int (*gui_set_layer_group)(rnd_hid_t *hid, 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 int common_set_layer_group(rnd_hid_t *hid, 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) +{ + int idx = group; + if (idx >= 0 && idx < pcb_max_group(PCB)) { + int n = PCB->LayerGroups.grp[group].len; + for (idx = 0; idx < n - 1; idx++) { + int ni = PCB->LayerGroups.grp[group].lid[idx]; + if (ni >= 0 && ni < pcb_max_layer(PCB) && PCB->Data->Layer[ni].meta.real.vis) + break; + } + idx = PCB->LayerGroups.grp[group].lid[idx]; + } + + /* non-virtual layers with group visibility */ + switch (flags & PCB_LYT_ANYTHING) { + case PCB_LYT_MASK: + case PCB_LYT_PASTE: + return (PCB_LAYERFLG_ON_VISIBLE_SIDE(flags) && PCB->LayerGroups.grp[group].vis); + } + + if (idx >= 0 && idx < pcb_max_layer(PCB) && ((flags & PCB_LYT_ANYTHING) != PCB_LYT_SILK)) + return PCB->Data->Layer[idx].meta.real.vis; + + /* virtual layers */ + { + if (PCB_LAYER_IS_DRILL(flags, purpi)) + return 1; + + switch (flags & PCB_LYT_ANYTHING) { + case PCB_LYT_INVIS: + return PCB->InvisibleObjectsOn; + case PCB_LYT_SILK: + if (PCB_LAYERFLG_ON_VISIBLE_SIDE(flags)) + return pcb_silk_on(PCB); + return 0; + case PCB_LYT_UI: + return 1; + case PCB_LYT_RAT: + return PCB->RatOn; + } + } + return 0; +} + +static int pcbui_set_layer_group(rnd_hid_t *hid, 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) +{ + int res; + + res = gui_set_layer_group(hid, group, purpose, purpi, layer, flags, is_empty, xform); + + /* if the HID doesn't want it, don't even bother running the above heuristics */ + if (res == 0) + return 0; + + return common_set_layer_group(hid, group, purpose, purpi, layer, flags, is_empty, xform); +} + +static void pcb_rendering_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + /* hook in our dispatcher */ + gui_set_layer_group = rnd_gui->set_layer_group; + rnd_gui->set_layer_group = pcbui_set_layer_group; +} + Index: tags/2.3.0/src_plugins/lib_hid_pcbui/routest.c =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/routest.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/routest.c (revision 33253) @@ -0,0 +1,245 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "board.h" +#include +#include "conf_core.h" +#include "route_style.h" +#include "event.h" +#include +#include +#include +#include + +#include "routest.h" + +#define ANCH "/anchored/@routestyles" + +#define MAX_STYLES 64 + +typedef struct { + rnd_hid_dad_subdialog_t sub; + int sub_inited, last_len; + int whbox[MAX_STYLES], wchk[MAX_STYLES], wlab[MAX_STYLES]; +} rst_ctx_t; + +static rst_ctx_t rst; + +#include "routest_dlg.c" + +static void rst_install_menu(void) +{ + rnd_menu_prop_t props; + char act[256], chk[256], *path, *end; + int idx; + size_t len = 0; + + for(idx = vtroutestyle_len(&PCB->RouteStyle)-1; idx >= 0; idx--) { + size_t l = strlen(PCB->RouteStyle.array[idx].name); + if (l > len) len = l; + } + + path = malloc(len + 32); + strcpy(path, ANCH); + end = path + strlen(ANCH); + + memset(&props, 0,sizeof(props)); + props.action = act; + props.checked = chk; + props.update_on = ""; + props.cookie = "lib_hid_pcbui route styles"; + + /* prepare for appending the strings at the end of the path, "under" the anchor */ + *end = '/'; + end++; + + rnd_hid_menu_merge_inhibit_inc(); + rnd_hid_menu_unload(rnd_gui, props.cookie); + /* have to go reverse to keep order because this will insert items */ + for(idx = vtroutestyle_len(&PCB->RouteStyle)-1; idx >= 0; idx--) { + sprintf(act, "RouteStyle(%d)", idx+1); /* for historical reasons this action counts from 1 */ + sprintf(chk, "ChkRst(%d)", idx); + strcpy(end, PCB->RouteStyle.array[idx].name); + rnd_hid_menu_create(path, &props); + } + rnd_hid_menu_merge_inhibit_dec(); + free(path); +} + +/* Update the edit dialog and all checkboxes, but nothing else on the sub */ +static void rst_force_update_chk_and_dlg() +{ + int n, target = pcb_route_style_lookup(&PCB->RouteStyle, conf_core.design.line_thickness, conf_core.design.via_thickness, conf_core.design.via_drilling_hole, conf_core.design.clearance, NULL); + rnd_hid_attr_val_t hv; + + idx_changed(); + + for(n = 0; n < vtroutestyle_len(&PCB->RouteStyle); n++) { + hv.lng = (n == target); + rnd_gui->attr_dlg_set_value(rst.sub.dlg_hid_ctx, rst.wchk[n], &hv); + } + rstdlg_pcb2dlg(target); +} + +static int need_rst_menu = 0; + +void pcb_rst_menu_batch_timer_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (need_rst_menu) { +/* rnd_trace("layer key update timer!\n");*/ + rst_install_menu(); + need_rst_menu = 0; + } +} + + +static int rst_lock = 0; +static void rst_update(rnd_hidlib_t *hidlib) +{ + if (rst_lock) return; + rst_lock++; + + need_rst_menu = 1; + rnd_hid_gui_batch_timer(hidlib); + + if (rst.sub_inited) { + int n, target; + target = pcb_route_style_lookup(&PCB->RouteStyle, conf_core.design.line_thickness, conf_core.design.via_thickness, conf_core.design.via_drilling_hole, conf_core.design.clearance, NULL); + for(n = 0; n < vtroutestyle_len(&PCB->RouteStyle); n++) { + rnd_hid_attr_val_t hv; + + hv.lng = (n == target); + if (rst.sub.dlg[rst.wlab[n]].val.lng != hv.lng) + rnd_gui->attr_dlg_set_value(rst.sub.dlg_hid_ctx, rst.wchk[n], &hv); + + hv.str = PCB->RouteStyle.array[n].name; + if (strcmp(rst.sub.dlg[rst.wlab[n]].name, hv.str) != 0) + rnd_gui->attr_dlg_set_value(rst.sub.dlg_hid_ctx, rst.wlab[n], &hv); + } + if (vtroutestyle_len(&PCB->RouteStyle) != rst.last_len) { + rst.last_len = vtroutestyle_len(&PCB->RouteStyle); + for(n = 0; n < MAX_STYLES; n++) + rnd_gui->attr_dlg_widget_hide(rst.sub.dlg_hid_ctx, rst.whbox[n], n >= rst.last_len); + } + rstdlg_pcb2dlg(target); + } + rst_lock--; +} + +static void rst_select_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int n, ridx = -1; + for(n = 0; n < vtroutestyle_len(&PCB->RouteStyle); n++) { + if ((attr == &rst.sub.dlg[rst.wlab[n]]) || (attr == &rst.sub.dlg[rst.wchk[n]])) { + ridx = n; + break; + } + } + if (ridx < 0) + return; + pcb_use_route_style(&(PCB->RouteStyle.array[ridx])); + rst_force_update_chk_and_dlg(); +} + +static void rst_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int target = pcb_route_style_lookup(&PCB->RouteStyle, conf_core.design.line_thickness, conf_core.design.via_thickness, conf_core.design.via_drilling_hole, conf_core.design.clearance, NULL); + if (target >= 0) + pcb_dlg_rstdlg(target); +} + +static void rst_new_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int target = pcb_route_style_new(PCB, "new style", 1); + pcb_use_route_style(&(PCB->RouteStyle.array[target])); + pcb_dlg_rstdlg(target); +} + +static void rst_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int target = pcb_route_style_lookup(&PCB->RouteStyle, conf_core.design.line_thickness, conf_core.design.via_thickness, conf_core.design.via_drilling_hole, conf_core.design.clearance, NULL); + if (target >= 0) { + pcb_route_style_del(PCB, target, 1); + rst_updated(NULL); + rst_force_update_chk_and_dlg(); + } +} + +static void rst_docked_create() +{ + int n; + RND_DAD_BEGIN_VBOX(rst.sub.dlg); + for(n = 0; n < MAX_STYLES; n++) { + RND_DAD_BEGIN_HBOX(rst.sub.dlg); + RND_DAD_COMPFLAG(rst.sub.dlg, RND_HATF_HIDE); + rst.whbox[n] = RND_DAD_CURRENT(rst.sub.dlg); + RND_DAD_BOOL(rst.sub.dlg); + rst.wchk[n] = RND_DAD_CURRENT(rst.sub.dlg); + RND_DAD_CHANGE_CB(rst.sub.dlg, rst_select_cb); + RND_DAD_LABEL(rst.sub.dlg, "unused"); + rst.wlab[n] = RND_DAD_CURRENT(rst.sub.dlg); + RND_DAD_CHANGE_CB(rst.sub.dlg, rst_select_cb); + RND_DAD_END(rst.sub.dlg); + } + + RND_DAD_BEGIN_HBOX(rst.sub.dlg); + RND_DAD_BUTTON(rst.sub.dlg, "New"); + RND_DAD_CHANGE_CB(rst.sub.dlg, rst_new_cb); + RND_DAD_BUTTON(rst.sub.dlg, "Edit"); + RND_DAD_CHANGE_CB(rst.sub.dlg, rst_edit_cb); + RND_DAD_BUTTON(rst.sub.dlg, "Del"); + RND_DAD_CHANGE_CB(rst.sub.dlg, rst_del_cb); + RND_DAD_END(rst.sub.dlg); + RND_DAD_END(rst.sub.dlg); +} + + +void pcb_rst_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + rst_update(hidlib); +} + +void pcb_rst_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (RND_HAVE_GUI_ATTR_DLG) { + rst_docked_create(); + if (rnd_hid_dock_enter(&rst.sub, RND_HID_DOCK_LEFT, "Route styles") == 0) + rst.sub_inited = 1; + } + rst_update(hidlib); +} + +void pcb_rst_update_conf(rnd_conf_native_t *cfg, int arr_idx) +{ + if ((PCB != NULL) && (rnd_gui != NULL)) { + if (rnd_gui->update_menu_checkbox != NULL) + rnd_gui->update_menu_checkbox(rnd_gui, NULL); + if (rst.sub_inited) + rst_force_update_chk_and_dlg(); + } +} Index: tags/2.3.0/src_plugins/lib_hid_pcbui/routest.h =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/routest.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/routest.h (revision 33253) @@ -0,0 +1,13 @@ +#include +#include +#include + +void pcb_rst_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void pcb_rst_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void pcb_rst_update_conf(rnd_conf_native_t *cfg, int arr_idx); +void pcb_rst_menu_batch_timer_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); + + +extern const char pcb_acts_AdjustStyle[]; +extern const char pcb_acth_AdjustStyle[]; +fgw_error_t pcb_act_AdjustStyle(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/2.3.0/src_plugins/lib_hid_pcbui/routest_dlg.c =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/routest_dlg.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/routest_dlg.c (revision 33253) @@ -0,0 +1,412 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* included from routest.c - split for clarity */ + +#include + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ + int curr; + int wname, wlineth, wclr, wtxtscale, wtxtth, wviahole, wviaring, wattr; + + rnd_hidval_t name_timer; + + char name[PCB_RST_NAME_LEN]; + unsigned name_pending:1; +} rstdlg_ctx_t; + +rstdlg_ctx_t rstdlg_ctx; + + +static void rstdlg_pcb2dlg(int rst_idx) +{ + int n; + rnd_hid_attr_val_t hv; + pcb_route_style_t *rst; + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + pcb_attribute_t *a; + + if (!rstdlg_ctx.active) + return; + + attr = &rstdlg_ctx.dlg[rstdlg_ctx.wattr]; + tree = attr->wdata; + + if (rst_idx < 0) + rst_idx = rstdlg_ctx.curr; + + if ((rst_idx < 0) || (rst_idx >= vtroutestyle_len(&PCB->RouteStyle))) { + hv.str = ""; + rnd_gui->attr_dlg_set_value(rstdlg_ctx.dlg_hid_ctx, rstdlg_ctx.wname, &hv); + return; + } + + + rst = vtroutestyle_get(&PCB->RouteStyle, rst_idx, 0); + + hv.str = rst->name; + rnd_gui->attr_dlg_set_value(rstdlg_ctx.dlg_hid_ctx, rstdlg_ctx.wname, &hv); + + hv.crd = rst->Thick; + rnd_gui->attr_dlg_set_value(rstdlg_ctx.dlg_hid_ctx, rstdlg_ctx.wlineth, &hv); + + hv.crd = rst->textt; + rnd_gui->attr_dlg_set_value(rstdlg_ctx.dlg_hid_ctx, rstdlg_ctx.wtxtth, &hv); + + hv.lng = rst->texts; + rnd_gui->attr_dlg_set_value(rstdlg_ctx.dlg_hid_ctx, rstdlg_ctx.wtxtscale, &hv); + + hv.crd = rst->Clearance; + rnd_gui->attr_dlg_set_value(rstdlg_ctx.dlg_hid_ctx, rstdlg_ctx.wclr, &hv); + + hv.crd = rst->Hole; + rnd_gui->attr_dlg_set_value(rstdlg_ctx.dlg_hid_ctx, rstdlg_ctx.wviahole, &hv); + + hv.crd = rst->Diameter; + rnd_gui->attr_dlg_set_value(rstdlg_ctx.dlg_hid_ctx, rstdlg_ctx.wviaring, &hv); + + rnd_dad_tree_clear(tree); + + for(a = rst->attr.List, n = 0; n < rst->attr.Number; a++,n++) { + char *cell[3]= {NULL}; + cell[0] = rnd_strdup(a->name); + cell[1] = rnd_strdup(a->value); + rnd_dad_tree_append(attr, NULL, cell); + } + + rstdlg_ctx.curr = rst_idx; +} + +static void rst_updated(pcb_route_style_t *rst) +{ + if (rst != NULL) + pcb_use_route_style(rst); + rnd_event(&PCB->hidlib, PCB_EVENT_ROUTE_STYLES_CHANGED, NULL); + pcb_board_set_changed_flag(PCB, 1); +} + +/* if the change is silent, do not use the new route style */ +static void name_chg_cb_silent(int silent) +{ + if (rstdlg_ctx.name_pending) { + pcb_route_style_t *rst = vtroutestyle_get(&PCB->RouteStyle, rstdlg_ctx.curr, 0); + pcb_route_style_change_name(PCB, rstdlg_ctx.curr, rstdlg_ctx.name, 1); + rstdlg_ctx.name_pending = 0; + rst_updated(silent ? NULL : rst); + } +} + +/* delayed name change */ +static void name_chg_cb(rnd_hidval_t data) +{ + name_chg_cb_silent(0); +} + +/* call this if idx changes */ +static void idx_changed(void) +{ + if (rstdlg_ctx.name_pending) { /* make sure pending name update is executed on the old style */ + if (rnd_gui->stop_timer != NULL) + rnd_gui->stop_timer(rnd_gui, rstdlg_ctx.name_timer); + name_chg_cb_silent(1); + } +} + +static void rst_change_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + int idx = attr - rstdlg_ctx.dlg; + pcb_route_style_t *rst = vtroutestyle_get(&PCB->RouteStyle, rstdlg_ctx.curr, 0); + rnd_hid_attr_val_t hv; + + if (rst == NULL) { + rnd_message(RND_MSG_ERROR, "route style does not exist"); + return; + } + + if (idx == rstdlg_ctx.wname) { + const char *s = attr->val.str; + while(isspace(*s)) s++; + strncpy(rstdlg_ctx.name, s, sizeof(rst->name)); + + /* If we already have a timer going, then cancel it out */ + if (rstdlg_ctx.name_pending && (rnd_gui->stop_timer != NULL)) + rnd_gui->stop_timer(rnd_gui, rstdlg_ctx.name_timer); + + /* Start up a new timer */ + rstdlg_ctx.name_pending = 1; + if (rnd_gui->add_timer != NULL) + rstdlg_ctx.name_timer = rnd_gui->add_timer(rnd_gui, name_chg_cb, 1000 * 2, rstdlg_ctx.name_timer); + else + name_chg_cb(rstdlg_ctx.name_timer); + } + else if (idx == rstdlg_ctx.wlineth) + pcb_route_style_change(PCB, rstdlg_ctx.curr, &attr->val.crd, NULL, NULL, NULL, NULL, 1); + else if (idx == rstdlg_ctx.wtxtth) + pcb_route_style_change(PCB, rstdlg_ctx.curr, NULL, &attr->val.crd, NULL, NULL, NULL, 1); + else if (idx == rstdlg_ctx.wtxtscale) { + int tmp = attr->val.lng; + pcb_route_style_change(PCB, rstdlg_ctx.curr, NULL, NULL, &tmp, NULL, NULL, 1); + } + else if (idx == rstdlg_ctx.wclr) + pcb_route_style_change(PCB, rstdlg_ctx.curr, NULL, NULL, NULL, &attr->val.crd, NULL, 1); + else if (idx == rstdlg_ctx.wviahole) { + rst->Hole = attr->val.crd; + if (rst->Hole * 1.1 >= rstdlg_ctx.dlg[rstdlg_ctx.wviaring].val.crd) { + hv.crd = rst->Hole * 1.1; + rnd_gui->attr_dlg_set_value(rstdlg_ctx.dlg_hid_ctx, rstdlg_ctx.wviaring, &hv); + rst->Diameter = hv.crd; + } + rst_updated(rst); + } + else if (idx == rstdlg_ctx.wviaring) { + rst->Diameter = attr->val.crd; + if (rst->Diameter / 1.1 <= rstdlg_ctx.dlg[rstdlg_ctx.wviahole].val.crd) { + hv.crd = rst->Diameter / 1.1; + rnd_gui->attr_dlg_set_value(rstdlg_ctx.dlg_hid_ctx, rstdlg_ctx.wviahole, &hv); + rst->Hole = hv.crd; + } + rst_updated(rst); + } + else { + rnd_message(RND_MSG_ERROR, "Internal error: route style field does not exist"); + return; + } +} + +static int rst_edit_attr(char **key, char **val) +{ + int wkey, wval, res; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"ok", 0}, {NULL, 0}}; + RND_DAD_DECL(dlg); + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABLE(dlg, 2); + RND_DAD_LABEL(dlg, "key"); + RND_DAD_STRING(dlg); + wkey = RND_DAD_CURRENT(dlg); + if (*key != NULL) + RND_DAD_DEFAULT_PTR(dlg, rnd_strdup(*key)); + RND_DAD_LABEL(dlg, "value"); + RND_DAD_STRING(dlg); + wval = RND_DAD_CURRENT(dlg); + if (*val != NULL) + RND_DAD_DEFAULT_PTR(dlg, rnd_strdup(*val)); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + RND_DAD_NEW("route_style_attr", dlg, "Edit route style attribute", NULL, rnd_true, NULL); + res = RND_DAD_RUN(dlg); + if (res == 0) { + *key = rnd_strdup(dlg[wkey].val.str); + *val = rnd_strdup(dlg[wval].val.str); + } + RND_DAD_FREE(dlg); + return res; +} + +static void rst_add_attr_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_route_style_t *rst = vtroutestyle_get(&PCB->RouteStyle, rstdlg_ctx.curr, 0); + char *key = NULL, *val = NULL; + + if (rst_edit_attr(&key, &val) == 0) { + pcb_attribute_put(&rst->attr, key, val); + rst_updated(rst); + } +} + +static void rst_edit_attr_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_route_style_t *rst = vtroutestyle_get(&PCB->RouteStyle, rstdlg_ctx.curr, 0); + rnd_hid_attribute_t *treea = &rstdlg_ctx.dlg[rstdlg_ctx.wattr]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(treea); + char *key, *val; + + if (row == NULL) + return; + + key = row->cell[0]; + val = row->cell[1]; + + if (rst_edit_attr(&key, &val) == 0) { + pcb_attribute_remove(&rst->attr, row->cell[0]); + pcb_attribute_put(&rst->attr, key, val); + rst_updated(rst); + } +} + +static void rst_del_attr_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + pcb_route_style_t *rst = vtroutestyle_get(&PCB->RouteStyle, rstdlg_ctx.curr, 0); + rnd_hid_attribute_t *treea = &rstdlg_ctx.dlg[rstdlg_ctx.wattr]; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(treea); + + if (row == NULL) + return; + + pcb_attribute_remove(&rst->attr, row->cell[0]); + rst_updated(rst); +} + +static void rstdlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + rstdlg_ctx_t *ctx = caller_data; + + idx_changed(); /* flush pending timed changes */ + + { /* can be safely removed when route style switches over to padstacks */ + pcb_route_style_t *rst = vtroutestyle_get(&PCB->RouteStyle, ctx->curr, 0); + if (rst->Diameter <= rst->Hole) { + rnd_message(RND_MSG_ERROR, "had to increase the via ring diameter - can not be smaller than the hole"); + rst->Diameter = rst->Hole+RND_MIL_TO_COORD(1); + } + } + + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(rstdlg_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static int pcb_dlg_rstdlg(int rst_idx) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + static const char *attr_hdr[] = {"attribute key", "attribute value", NULL}; + + if (rstdlg_ctx.active) { /* do not open another, just refresh data to target */ + idx_changed(); + rstdlg_pcb2dlg(rst_idx); + return 0; + } + + RND_DAD_BEGIN_VBOX(rstdlg_ctx.dlg); + RND_DAD_COMPFLAG(rstdlg_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABLE(rstdlg_ctx.dlg, 2); + + RND_DAD_LABEL(rstdlg_ctx.dlg, "Name:"); + RND_DAD_STRING(rstdlg_ctx.dlg); + rstdlg_ctx.wname = RND_DAD_CURRENT(rstdlg_ctx.dlg); + RND_DAD_HELP(rstdlg_ctx.dlg, "Name of the routing style"); + RND_DAD_CHANGE_CB(rstdlg_ctx.dlg, rst_change_cb); + + RND_DAD_LABEL(rstdlg_ctx.dlg, "Line thick.:"); + RND_DAD_COORD(rstdlg_ctx.dlg); + rstdlg_ctx.wlineth = RND_DAD_CURRENT(rstdlg_ctx.dlg); + RND_DAD_HELP(rstdlg_ctx.dlg, "Thickness of line/arc objects"); + RND_DAD_MINMAX(rstdlg_ctx.dlg, 1, RND_MAX_COORD); + RND_DAD_CHANGE_CB(rstdlg_ctx.dlg, rst_change_cb); + + RND_DAD_LABEL(rstdlg_ctx.dlg, "Text scale:"); + RND_DAD_INTEGER(rstdlg_ctx.dlg); + rstdlg_ctx.wtxtscale = RND_DAD_CURRENT(rstdlg_ctx.dlg); + RND_DAD_HELP(rstdlg_ctx.dlg, "Text size scale in %; 100 means normal size"); + RND_DAD_MINMAX(rstdlg_ctx.dlg, 1, 100000); + RND_DAD_CHANGE_CB(rstdlg_ctx.dlg, rst_change_cb); + + RND_DAD_LABEL(rstdlg_ctx.dlg, "Clearance:"); + RND_DAD_COORD(rstdlg_ctx.dlg); + rstdlg_ctx.wclr = RND_DAD_CURRENT(rstdlg_ctx.dlg); + RND_DAD_HELP(rstdlg_ctx.dlg, "Object clearance: any object placed with this style\nwill clear this much from sorrunding clearing-enabled polygons\n(unless the object is joined to the polygon)"); + RND_DAD_MINMAX(rstdlg_ctx.dlg, 1, RND_MAX_COORD); + RND_DAD_CHANGE_CB(rstdlg_ctx.dlg, rst_change_cb); + + RND_DAD_LABEL(rstdlg_ctx.dlg, "Text thick.:"); + RND_DAD_COORD(rstdlg_ctx.dlg); + rstdlg_ctx.wtxtth = RND_DAD_CURRENT(rstdlg_ctx.dlg); + RND_DAD_HELP(rstdlg_ctx.dlg, "Text stroke thickness;\nif 0 use the default heuristics that\ncalculates it from text scale"); + RND_DAD_MINMAX(rstdlg_ctx.dlg, 1, RND_MAX_COORD); + RND_DAD_CHANGE_CB(rstdlg_ctx.dlg, rst_change_cb); + + RND_DAD_LABEL(rstdlg_ctx.dlg, "*Via hole:"); + RND_DAD_COORD(rstdlg_ctx.dlg); + rstdlg_ctx.wviahole = RND_DAD_CURRENT(rstdlg_ctx.dlg); + RND_DAD_HELP(rstdlg_ctx.dlg, "Via hole diameter\nwarning: will be replaced with the padstack selector"); + RND_DAD_MINMAX(rstdlg_ctx.dlg, 1, RND_MAX_COORD); + RND_DAD_CHANGE_CB(rstdlg_ctx.dlg, rst_change_cb); + + RND_DAD_LABEL(rstdlg_ctx.dlg, "*Via ring:"); + RND_DAD_COORD(rstdlg_ctx.dlg); + rstdlg_ctx.wviaring = RND_DAD_CURRENT(rstdlg_ctx.dlg); + RND_DAD_HELP(rstdlg_ctx.dlg, "Via ring diameter\nwarning: will be replaced with the padstack selector"); + RND_DAD_MINMAX(rstdlg_ctx.dlg, 1, RND_MAX_COORD); + RND_DAD_CHANGE_CB(rstdlg_ctx.dlg, rst_change_cb); + + RND_DAD_END(rstdlg_ctx.dlg); + RND_DAD_TREE(rstdlg_ctx.dlg, 2, 0, attr_hdr); + RND_DAD_HELP(rstdlg_ctx.dlg, "These attributes are automatically added to\nany object drawn with this routing style"); + rstdlg_ctx.wattr = RND_DAD_CURRENT(rstdlg_ctx.dlg); + RND_DAD_BEGIN_HBOX(rstdlg_ctx.dlg); + RND_DAD_BUTTON(rstdlg_ctx.dlg, "add"); + RND_DAD_CHANGE_CB(rstdlg_ctx.dlg, rst_add_attr_cb); + RND_DAD_BUTTON(rstdlg_ctx.dlg, "edit"); + RND_DAD_CHANGE_CB(rstdlg_ctx.dlg, rst_edit_attr_cb); + RND_DAD_BUTTON(rstdlg_ctx.dlg, "del"); + RND_DAD_CHANGE_CB(rstdlg_ctx.dlg, rst_del_attr_cb); + RND_DAD_END(rstdlg_ctx.dlg); + RND_DAD_BUTTON_CLOSES(rstdlg_ctx.dlg, clbtn); + RND_DAD_END(rstdlg_ctx.dlg); + + /* set up the context */ + rstdlg_ctx.active = 1; + + RND_DAD_NEW("route_style", rstdlg_ctx.dlg, "Edit route style", &rstdlg_ctx, rnd_false, rstdlg_close_cb); + + rstdlg_pcb2dlg(rst_idx); + return 0; +} + + +const char pcb_acts_AdjustStyle[] = "AdjustStyle([routestyle_idx])\n"; +const char pcb_acth_AdjustStyle[] = "Open the dialog box for editing the route styles."; +/* DOC: adjuststyle.html */ +fgw_error_t pcb_act_AdjustStyle(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + long idx = -1; + + if (argc > 2) + RND_ACT_FAIL(AdjustStyle); + + RND_ACT_MAY_CONVARG(1, FGW_LONG, AdjustStyle, idx = argv[1].val.nat_long); + + if (idx >= (long)vtroutestyle_len(&PCB->RouteStyle)) { + rnd_message(RND_MSG_ERROR, "Invalid route style %ld index; max value: %ld\n", idx, vtroutestyle_len(&PCB->RouteStyle)-1); + RND_ACT_IRES(-1); + return 0; + } + + if (idx < 0) { + idx = pcb_route_style_lookup(&PCB->RouteStyle, conf_core.design.line_thickness, conf_core.design.via_thickness, conf_core.design.via_drilling_hole, conf_core.design.clearance, NULL); + if (idx < 0) { + rnd_message(RND_MSG_ERROR, "No style selected\n"); + RND_ACT_IRES(-1); + } + } + + RND_ACT_IRES(pcb_dlg_rstdlg(idx)); + return 0; +} Index: tags/2.3.0/src_plugins/lib_hid_pcbui/status.c =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/status.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/status.c (revision 33253) @@ -0,0 +1,533 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include "board.h" +#include +#include +#include +#include "conf_core.h" +#include +#include "crosshair.h" +#include "layer.h" +#include "search.h" +#include "find.h" +#include "obj_subc.h" +#include "obj_subc_parent.h" +#include "netlist.h" + +#include "status.h" + +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, wst2, wsttxt; + int st_has_text; + int wrdunit, wrd1[3], 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]; + const char *flag = conf_core.editor.all_direction_lines ? "*" : (conf_core.editor.line_refraction == 0 ? "X" : (conf_core.editor.line_refraction == 1 ? "_/" : "\\_")); + 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+view=%s " + "grid=%$mS " + "line=%mS (%s%s) " + "kbd=%s", + rnd_conf.editor.grid_unit->allow, conf_core.editor.show_solder_side ? "bottom" : "top", + PCB->hidlib.grid, + conf_core.design.line_thickness, flag, conf_core.editor.rubber_band_mode ? ",R" : "", + kbd); +} + +static void build_st_line2(void) +{ + rnd_append_printf(&status.buf, + "via=%mS (%mS) " + "clr=%mS " + "text=%d%% %$mS " + "buff=#%d", + conf_core.design.via_thickness, conf_core.design.via_drilling_hole, + conf_core.design.clearance, + conf_core.design.text_scale, + conf_core.design.text_thickness, + conf_core.editor.buffer_number + 1); +} + +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 " + "line=%mS " + "via=%mS (%mS) " + "clearance=%mS", + unit_inv->allow, + PCB->hidlib.grid, + conf_core.design.line_thickness, + conf_core.design.via_thickness, conf_core.design.via_drilling_hole, + conf_core.design.clearance); +} + + +static void status_st_pcb2dlg(void) +{ + static rnd_hid_attr_val_t hv; + + if (!status.stsub_inited) + return; + + status.buf.used = 0; + build_st_line1(); + if (!conf_core.appearance.compact) { + build_st_line2(); + rnd_gui->attr_dlg_widget_hide(status.stsub.dlg_hid_ctx, status.wst2, 1); + } + hv.str = status.buf.array; + rnd_gui->attr_dlg_set_value(status.stsub.dlg_hid_ctx, status.wst1, &hv); + + if (conf_core.appearance.compact) { + status.buf.used = 0; + build_st_line2(); + hv.str = status.buf.array; + rnd_gui->attr_dlg_set_value(status.stsub.dlg_hid_ctx, status.wst2, &hv); + if (!status.st_has_text) + rnd_gui->attr_dlg_widget_hide(status.stsub.dlg_hid_ctx, status.wst2, 0); + } + + status.buf.used = 0; + build_st_help(); + rnd_gui->attr_dlg_set_help(status.stsub.dlg_hid_ctx, status.wst1, status.buf.array); + rnd_gui->attr_dlg_set_help(status.stsub.dlg_hid_ctx, status.wst2, status.buf.array); +} + +static void status_rd_pcb2dlg(void) +{ + static rnd_hid_attr_val_t hv; + const char *s1, *s2, *s3; + char sep; + + if ((status.lock) || (!status.rdsub_inited)) + return; + + /* coordinate readout (right side box) */ + if (conf_core.appearance.compact) { + status.buf.used = 0; + rnd_append_printf(&status.buf, "%m+%-mS", rnd_conf.editor.grid_unit->allow, pcb_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, pcb_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, pcb_crosshair.X, pcb_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); + } + + /* distance readout (left side box) */ + sep = (conf_core.appearance.compact) ? '\0' : ';'; + + status.buf.used = 0; + if (pcb_marked.status) { + rnd_coord_t dx = pcb_crosshair.X - pcb_marked.X; + rnd_coord_t dy = pcb_crosshair.Y - pcb_marked.Y; + rnd_coord_t r = rnd_distance(pcb_crosshair.X, pcb_crosshair.Y, pcb_marked.X, pcb_marked.Y); + double a = atan2(dy, dx) * RND_RAD_TO_DEG; + + s1 = status.buf.array; + rnd_append_printf(&status.buf, "%m+r %-mS%c", rnd_conf.editor.grid_unit->allow, r, sep); + s2 = status.buf.array + status.buf.used; + rnd_append_printf(&status.buf, "phi %-.1f%c", a, sep); + s3 = status.buf.array + status.buf.used; + rnd_append_printf(&status.buf, "%m+ %-mS %-mS", rnd_conf.editor.grid_unit->allow, dx, dy); + } + else { + rnd_append_printf(&status.buf, "r __.__%cphi __._%c__.__ __.__", sep, sep, sep); + s1 = status.buf.array; + s2 = status.buf.array + 8; + s3 = status.buf.array + 17; + } + + hv.str = s1; + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wrd1[0], &hv); + if (conf_core.appearance.compact) { + hv.str = s2; + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wrd1[1], &hv); + hv.str = s3; + rnd_gui->attr_dlg_set_value(status.rdsub.dlg_hid_ctx, status.wrd1[2], &hv); + rnd_gui->attr_dlg_widget_hide(status.rdsub.dlg_hid_ctx, status.wrd1[1], 0); + rnd_gui->attr_dlg_widget_hide(status.rdsub.dlg_hid_ctx, status.wrd1[2], 0); + } + else { + rnd_gui->attr_dlg_widget_hide(status.rdsub.dlg_hid_ctx, status.wrd1[1], 1); + rnd_gui->attr_dlg_widget_hide(status.rdsub.dlg_hid_ctx, status.wrd1[2], 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(&PCB->hidlib, "SetUnits", "mil", NULL); + else + rnd_actionva(&PCB->hidlib, "SetUnits", "mm", NULL); + + status_rd_pcb2dlg(); +} + +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_LABEL(status.stsub.dlg, ""); + RND_DAD_COMPFLAG(status.stsub.dlg, RND_HATF_HIDE); + status.wst2 = 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); +} + +/* XPM */ +static char *support_icon[] = { +"50 42 3 1", +"* c #000000", +". c #6EA5D7", +" c None", +" .......................................... ", +" .............................................. ", +" ....**...**..*********..**.........*******...... ", +" ....**...**..*********..**.........********..... ", +".....**...**..**.........**.........**.....**.....", +".....**...**..**.........**.........**.....**.....", +".....*******..*******....**.........********......", +".....*******..*******....**.........*******.......", +".....**...**..**.........**.........**............", +".....**...**..**.........**.........**............", +".....**...**..**.........**.........**............", +".....**...**..*********..*********..**............", +".....**...**..*********..*********..**............", +"..................................................", +"..................................................", +"........................*.........................", +"........................*..*......................", +"........................*.........................", +"......***...*.**........*..*..*.**......**........", +".....*...*..*...*.......*..*..*...*...*...*.......", +".....*...*..*...*.......*..*..*...*...*...*.......", +".....*...*..*...*..***..*..*..*...*...*****.......", +".....*...*..*...*.......*..*..*...*...*...........", +".....*...*..*...*.......*..*..*...*...*...........", +"......***...*...*.......*..*..*...*.....***.......", +"..................................................", +"..................................................", +"..................................................", +".............................................*....", +".............................................*....", +"...**...*...*...*.**....*.**.....***...*.**.****..", +"..*.....*...*...**..*...**..*...*...*..*.....*....", +"..*.....*...*...*....*..*....*..*...*..*.....*....", +"...**...*...*...*....*..*....*..*...*..*.....*....", +".....*..*...*...*....*..*....*..*...*..*.....*....", +".....*..*...*...**..*...**..*...*...*..*.....*....", +"..***....***....*.**....*.**.....***...*......**..", +"................*.......*.........................", +" ...............*.......*........................ ", +" ...............*.......*........................ ", +" .............................................. ", +" .......................................... "}; + +static void btn_support_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + rnd_actionva(&PCB->hidlib, "irc", NULL); +} + +static void status_docked_create_rd() +{ + int n; + 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 | RND_HATF_TIGHT); + vpad(&status.rdsub); + for(n = 0; n < 3; n++) { + RND_DAD_LABEL(status.rdsub.dlg, ""); + status.wrd1[n] = RND_DAD_CURRENT(status.rdsub.dlg); + } + vpad(&status.rdsub); + RND_DAD_END(status.rdsub.dlg); + 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 pcb_status_gui_init_ev(rnd_hidlib_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_pcb2dlg(); + } + + status_docked_create_rd(); + if (rnd_hid_dock_enter(&status.rdsub, RND_HID_DOCK_TOP_RIGHT, "readout") == 0) { + status.rdsub_inited = 1; + status_rd_pcb2dlg(); + } + } +} + +void pcb_status_st_update_conf(rnd_conf_native_t *cfg, int arr_idx) +{ + status_st_pcb2dlg(); +} + +void pcb_status_rd_update_conf(rnd_conf_native_t *cfg, int arr_idx) +{ + status_rd_pcb2dlg(); +} + +void pcb_status_st_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + status_st_pcb2dlg(); +} + +void pcb_status_rd_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + status_rd_pcb2dlg(); +} + +const char pcb_acts_StatusSetText[] = "StatusSetText([text])\n"; +const char pcb_acth_StatusSetText[] = "Replace status printout with text temporarily; turn status printout back on if text is not provided."; +fgw_error_t pcb_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); + hv.str = ""; + rnd_gui->attr_dlg_set_value(status.stsub.dlg_hid_ctx, status.wst2, &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_pcb2dlg(); + } + + RND_ACT_IRES(0); + return 0; +} + +/* The following code is used for the object tooltip hints: */ + +static void append_obj_desc(pcb_board_t *pcb, gds_t *dst, pcb_any_obj_t *obj, rnd_layergrp_id_t gid, const char *prefix) +{ + pcb_layergrp_t *grp; + + if (obj == NULL) + return; + + grp = pcb_get_layergrp(pcb, gid); + + gds_append_str(dst, prefix); + gds_append_str(dst, pcb_obj_type_name(obj->type)); + if (grp != NULL) { + gds_append_str(dst, " on"); + gds_append_str(dst, prefix); + gds_append_str(dst, grp->name); + } + +} + +#define PCB_DESCRIBE_TYPE (PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY) + +const char pcb_acts_DescribeLocation[] = "DescribeLocation(x, y)\n"; +const char pcb_acth_DescribeLocation[] = "Return a string constant (valud until the next call) containing a short description at x;y (object, net, etc.)"; +fgw_error_t pcb_act_DescribeLocation(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_coord_t x, y; + void *ptr1, *ptr2, *ptr3, *rptr1, *rptr2, *rptr3; + pcb_any_obj_t *obj; + int type, rattype; + pcb_subc_t *subc; + pcb_net_term_t *term = NULL; + static gds_t desc; + const char *ret = NULL; + char ids[64]; + + if (argc > 3) + RND_ACT_FAIL(StatusSetText); + + RND_ACT_MAY_CONVARG(1, FGW_COORD, StatusSetText, x = fgw_coord(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_COORD, StatusSetText, y = fgw_coord(&argv[2])); + + desc.used = 0; + if (desc.array != NULL) + desc.array[0] = '\0'; + + /* check if there are any pins or pads at that position */ + rattype = pcb_search_obj_by_location(PCB_OBJ_RAT, &rptr1, &rptr2, &rptr3, x, y, 0); + type = pcb_search_obj_by_location(PCB_OBJ_CLASS_TERM, &ptr1, &ptr2, &ptr3, x, y, 0); + if ((type == PCB_OBJ_VOID) && (rattype == PCB_OBJ_VOID)) + goto fin; + + /* don't mess with silk objects! */ + if ((type & PCB_DESCRIBE_TYPE) && (pcb_layer_flags_((pcb_layer_t *)ptr1) & PCB_LYT_SILK)) + goto maybe_rat; + + obj = ptr2; + if (obj->term == NULL) + goto maybe_rat; + + subc = pcb_obj_parent_subc(ptr2); + if (subc == NULL) + goto maybe_rat; + + if ((subc->refdes != NULL) && (obj->term != NULL)) + term = pcb_net_find_by_refdes_term(&PCB->netlist[PCB_NETLIST_EDITED], subc->refdes, obj->term); + + gds_append_str(&desc, "Subc. refdes:\t"); gds_append_str(&desc, subc->refdes == NULL ? "--" : subc->refdes); + gds_append_str(&desc, "\nTerminal: \t"); gds_append_str(&desc, obj->term == NULL ? "--" : obj->term); + if (obj->term != NULL) { /* print terminal name if not empty and not the same as term */ + const char *name = pcb_attribute_get(&obj->Attributes, "name"); + if ((name != NULL) && (strcmp(name, obj->term) != 0)) { + gds_append_str(&desc, " ("); + gds_append_str(&desc, name); + gds_append(&desc, ')'); + } + } + gds_append_str(&desc, "\nNetlist: \t"); gds_append_str(&desc, term == NULL ? "--" : term->parent.net->name); + sprintf(ids, "#%ld", subc->ID); + gds_append_str(&desc, "\nSubcircuit ID:\t"); gds_append_str(&desc, ids); + sprintf(ids, "#%ld", obj->ID); + gds_append_str(&desc, "\nTerm. obj. ID:\t"); gds_append_str(&desc, ids); + if (rattype == PCB_OBJ_RAT) + gds_append(&desc, '\n'); + + maybe_rat:; + if (rattype == PCB_OBJ_RAT) { + pcb_rat_t *rat = rptr2; + pcb_any_obj_t *e0 = pcb_rat_anchor_guess(rat, 0, 0), *e1 = pcb_rat_anchor_guess(rat, 1, 0); + gds_append_str(&desc, "Rat line between:"); + append_obj_desc(PCB_ACT_BOARD, &desc, e0, rat->group1, "\n\t"); + append_obj_desc(PCB_ACT_BOARD, &desc, e1, rat->group2, "\n\t"); + } + + ret = desc.array; + + fin:; + res->type = FGW_STR; + res->val.cstr = ret; + return 0; +} + +#undef PCB_DESCRIBE_TYPE Index: tags/2.3.0/src_plugins/lib_hid_pcbui/status.h =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/status.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/status.h (revision 33253) @@ -0,0 +1,17 @@ +#include +#include +#include + +void pcb_status_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void pcb_status_st_update_conf(rnd_conf_native_t *cfg, int arr_idx); +void pcb_status_rd_update_conf(rnd_conf_native_t *cfg, int arr_idx); +void pcb_status_st_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); +void pcb_status_rd_update_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]); + +extern const char pcb_acts_StatusSetText[]; +extern const char pcb_acth_StatusSetText[]; +fgw_error_t pcb_act_StatusSetText(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +extern const char pcb_acts_DescribeLocation[]; +extern const char pcb_acth_DescribeLocation[]; +fgw_error_t pcb_act_DescribeLocation(fgw_arg_t *res, int argc, fgw_arg_t *argv); Index: tags/2.3.0/src_plugins/lib_hid_pcbui/title.c =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/title.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/title.c (revision 33253) @@ -0,0 +1,78 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include "board.h" +#include "conf_core.h" + +static gds_t title_buf; +static int gui_inited = 0, brd_changed; + +static void update_title(void) +{ + const char *filename, *name; + + if ((rnd_gui == NULL) || (rnd_gui->set_top_title == NULL) || (!gui_inited)) + return; + + if ((PCB->hidlib.name == NULL) || (*PCB->hidlib.name == '\0')) + name = "Unnamed"; + else + name = PCB->hidlib.name; + + if ((PCB->hidlib.filename == NULL) || (*PCB->hidlib.filename == '\0')) + filename = ""; + else + filename = PCB->hidlib.filename; + + title_buf.used = 0; + rnd_append_printf(&title_buf, "%s%s (%s) - %s - pcb-rnd", PCB->Changed ? "*" : "", name, filename, PCB->is_footprint ? "footprint" : "board"); + rnd_gui->set_top_title(rnd_gui, title_buf.array); +} + +static void pcb_title_board_changed_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + brd_changed = 0; + update_title(); +} + +static void pcb_title_meta_changed_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (brd_changed == PCB->Changed) + return; + brd_changed = PCB->Changed; + update_title(); +} + +static void pcb_title_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + gui_inited = 1; + update_title(); +} + Index: tags/2.3.0/src_plugins/lib_hid_pcbui/util.c =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/util.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/util.c (revision 33253) @@ -0,0 +1,59 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "util.h" +#include "data_it.h" +#include "flag.h" + +static rnd_cardinal_t pcb_get_bbox_by_flag(rnd_box_t *dst, const pcb_data_t *data, pcb_flag_values_t flg) +{ + pcb_any_obj_t *o; + pcb_data_it_t it; + rnd_cardinal_t cnt = 0; + + dst->X1 = dst->Y1 = RND_MAX_COORD; + dst->X2 = dst->Y2 = -RND_MAX_COORD; + + for(o = pcb_data_first(&it, (pcb_data_t *)data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + if (!PCB_FLAG_TEST(flg, o)) + continue; + cnt++; + rnd_box_bump_box(dst, &o->BoundingBox); + } + return cnt; +} + +rnd_cardinal_t pcb_get_selection_bbox(rnd_box_t *dst, const pcb_data_t *data) +{ + return pcb_get_bbox_by_flag(dst, data, PCB_FLAG_SELECTED); +} + +rnd_cardinal_t pcb_get_found_bbox(rnd_box_t *dst, const pcb_data_t *data) +{ + return pcb_get_bbox_by_flag(dst, data, PCB_FLAG_FOUND); +} Index: tags/2.3.0/src_plugins/lib_hid_pcbui/util.h =================================================================== --- tags/2.3.0/src_plugins/lib_hid_pcbui/util.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_hid_pcbui/util.h (revision 33253) @@ -0,0 +1,7 @@ +#include "data.h" + +/* calculate the bounding box of all selections/founds in data, return the number + of selected objects. When returns 0, the dst box is infinitely large. */ +rnd_cardinal_t pcb_get_selection_bbox(rnd_box_t *dst, const pcb_data_t *data); +rnd_cardinal_t pcb_get_found_bbox(rnd_box_t *dst, const pcb_data_t *data); + Index: tags/2.3.0/src_plugins/lib_netmap/Makefile =================================================================== --- tags/2.3.0/src_plugins/lib_netmap/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/lib_netmap/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_lib_netmap + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/lib_netmap/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/lib_netmap/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/lib_netmap/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {lib_netmap} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/lib_netmap/netmap.o + $(PLUGDIR)/lib_netmap/placement.o +@] + +switch /local/pcb/lib_netmap/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/lib_netmap/lib_netmap.pup =================================================================== --- tags/2.3.0/src_plugins/lib_netmap/lib_netmap.pup (nonexistent) +++ tags/2.3.0/src_plugins/lib_netmap/lib_netmap.pup (revision 33253) @@ -0,0 +1,6 @@ +$class lib +$short map nets and objects +$long create disposable cross-reference maps between all objects and all nets +$state works +$package lib-io +default disable-all Index: tags/2.3.0/src_plugins/lib_netmap/netmap.c =================================================================== --- tags/2.3.0/src_plugins/lib_netmap/netmap.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_netmap/netmap.c (revision 33253) @@ -0,0 +1,200 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include "netmap.h" +#include "data.h" +#include "find.h" +#include "netlist.h" +#include +#include + +static pcb_net_t *alloc_net(pcb_netmap_t *map) +{ + dyn_net_t *dn = calloc(sizeof(dyn_net_t), 1); + dn->next = map->dyn_nets; + map->dyn_nets = dn; + dn->net.name = rnd_strdup_printf("netmap_anon_%d", map->anon_cnt++); + return &dn->net; +} + +static int found(pcb_find_t *fctx, pcb_any_obj_t *obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + pcb_netmap_t *map = fctx->user_data; + dyn_obj_t *d, *dl; + + if (map->curr_net == NULL) + map->curr_net = alloc_net(map); + + htpp_set(&map->o2n, obj, map->curr_net); + + dl = htpp_get(&map->n2o, map->curr_net); + d = malloc(sizeof(dyn_obj_t)); + d->obj = obj; + d->next = dl; + htpp_set(&map->n2o, map->curr_net, d); + + return 0; +} + +static void list_obj(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_any_obj_t *obj) +{ + pcb_find_t fctx; + pcb_netmap_t *map = ctx; + map->curr_net = NULL; + + if (obj->term != NULL) { + pcb_net_term_t *t = pcb_net_find_by_obj(&pcb->netlist[PCB_NETLIST_EDITED], obj); + if (t != NULL) { + if (!((map->how & PCB_NETMAPCTRL_RATTED) && (t->parent.net->inhibit_rats))) + map->curr_net = t->parent.net; + } + } + + if (htpp_get(&map->o2n, obj) != NULL) + return; + + if ((layer != NULL) && (pcb_layer_flags_(layer) & PCB_LYT_COPPER) == 0) + return; + + + memset(&fctx, 0, sizeof(fctx)); + fctx.ignore_intconn = 1; + fctx.found_cb = found; + fctx.user_data = map; + pcb_find_from_obj(&fctx, pcb->Data, obj); + pcb_find_free(&fctx); +} + +static void list_line_cb(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_line_t *line) +{ + list_obj(ctx, pcb, layer, (pcb_any_obj_t *)line); +} + +static void list_arc_cb(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_arc_t *arc) +{ + list_obj(ctx, pcb, layer, (pcb_any_obj_t *)arc); +} + +static void list_poly_cb(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_poly_t *poly) +{ + list_obj(ctx, pcb, layer, (pcb_any_obj_t *)poly); +} + +static void list_pstk_cb(void *ctx, pcb_board_t *pcb, pcb_pstk_t *ps) +{ + list_obj(ctx, pcb, NULL, (pcb_any_obj_t *)ps); +} + +int list_subc_cb(void *ctx, pcb_board_t *pcb, pcb_subc_t *subc, int enter) +{ + PCB_PADSTACK_LOOP(subc->data) { + list_pstk_cb(ctx, pcb, padstack); + } PCB_END_LOOP; +TODO("subc: heavy terminals - test on io_hyp") + return 0; +} + +int pcb_netmap_init(pcb_netmap_t *map, pcb_board_t *pcb, pcb_netmap_control_t how) +{ + htpp_init(&map->o2n, ptrhash, ptrkeyeq); + htpp_init(&map->n2o, ptrhash, ptrkeyeq); + map->anon_cnt = 0; + map->curr_net = NULL; + map->dyn_nets = 0; + map->pcb = pcb; + map->how = how; + +/* step 1: find known nets (from terminals) */ + pcb_loop_all(PCB, map, + NULL, /* layer */ + NULL, /* line */ + NULL, /* arc */ + NULL, /* text */ + NULL, /* poly */ + NULL, /* gfx */ + list_subc_cb, /* subc */ + NULL /* pstk */ + ); + + /* step 2: find unknown nets and uniquely name them */ + pcb_loop_all(PCB, map, + NULL, /* layer */ + list_line_cb, + list_arc_cb, + NULL, /* text */ + list_poly_cb, + NULL, /* gfx */ + NULL, /* subc */ + list_pstk_cb + ); + return 0; +} + +int pcb_netmap_uninit(pcb_netmap_t *map) +{ + + { + htpp_entry_t *e; + for(e = htpp_first(&map->n2o); e != NULL; e = htpp_next(&map->n2o, e)) { + dyn_obj_t *o, *next; + for(o = e->value; o != NULL; o = next) { + next = o->next; + free(o); + } + } + } + + { + dyn_net_t *dn, *next; + for(dn = map->dyn_nets; dn != NULL; dn = next) { + next = dn->next; + free(dn->net.name); + free(dn); + } + } + + htpp_uninit(&map->o2n); + htpp_uninit(&map->n2o); + return 0; +} + + +int pplg_check_ver_lib_netmap(int ver_needed) { return 0; } + +void pplg_uninit_lib_netmap(void) +{ +} + +int pplg_init_lib_netmap(void) +{ + RND_API_CHK_VER; + return 0; +} Index: tags/2.3.0/src_plugins/lib_netmap/netmap.h =================================================================== --- tags/2.3.0/src_plugins/lib_netmap/netmap.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_netmap/netmap.h (revision 33253) @@ -0,0 +1,63 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include "board.h" +#include "netlist.h" + +typedef struct dyn_net_s dyn_net_t; +typedef struct dyn_obj_s dyn_obj_t; + +struct dyn_net_s { + pcb_net_t net; + dyn_net_t *next; +}; + +struct dyn_obj_s { + pcb_any_obj_t *obj; + dyn_obj_t *next; +}; + +typedef enum { /* bits */ + PCB_NETMAPCTRL_RATTED = 1 /* ignore nets that with disabled rats */ +} pcb_netmap_control_t; + +typedef struct pcb_netmap_s { + htpp_t o2n; /* of (pcb_net_t *); tells the net for an object */ + htpp_t n2o; /* of (dyn_obj_t *); tells the object list for a net */ + rnd_cardinal_t anon_cnt; + pcb_board_t *pcb; + pcb_net_t *curr_net; + dyn_net_t *dyn_nets; + + /* internal */ + pcb_netmap_control_t how; +} pcb_netmap_t; + + +int pcb_netmap_init(pcb_netmap_t *map, pcb_board_t *pcb, pcb_netmap_control_t how); +int pcb_netmap_uninit(pcb_netmap_t *map); + Index: tags/2.3.0/src_plugins/lib_netmap/placement.c =================================================================== --- tags/2.3.0/src_plugins/lib_netmap/placement.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_netmap/placement.c (revision 33253) @@ -0,0 +1,77 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "placement.h" + +void pcb_placement_init(pcb_placement_t *ctx, pcb_board_t *pcb) +{ + memset(ctx, 0, sizeof(pcb_placement_t)); + htscp_init(&ctx->subcs, pcb_subc_hash, pcb_subc_eq); + pcb_data_init(&ctx->data); + pcb_data_bind_board_layers(pcb, &ctx->data, 0); + ctx->pcb = pcb; +} + +void pcb_placement_uninit(pcb_placement_t *ctx) +{ + htscp_uninit(&ctx->subcs); + pcb_data_uninit(&ctx->data); +} + +void pcb_placement_build(pcb_placement_t *ctx, pcb_data_t *data) +{ + PCB_SUBC_LOOP(data) { + if (!htscp_has(&ctx->subcs, subc)) { + pcb_host_trans_t tr; + pcb_data_t *oldhack; + pcb_subc_t *proto = pcb_subc_dup_at(ctx->pcb, &ctx->data, subc, 0, 0, 0, rnd_true); /* do not keep IDs because that fools pstk parent logic */ + pcb_subc_get_host_trans(subc, &tr, 1); + + oldhack = pcb_pstk_data_hack; + pcb_pstk_data_hack = &ctx->data; + + pcb_subc_move(proto, tr.ox, tr.oy, 1); + if (tr.rot != 0) { + double rr = tr.rot / RND_RAD_TO_DEG; + pcb_subc_rotate(proto, 0, 0, cos(rr), sin(rr), tr.rot); + } + if (tr.on_bottom) { + int n; + pcb_data_mirror(proto->data, 0, PCB_TXM_SIDE, 1, 0); + for(n = 0; n < proto->data->LayerN; n++) { + pcb_layer_t *ly = proto->data->Layer + n; + ly->meta.bound.type = pcb_layer_mirror_type(ly->meta.bound.type); + ly->meta.bound.stack_offs = -ly->meta.bound.stack_offs; + } + } + + htscp_insert(&ctx->subcs, subc, proto); + pcb_pstk_data_hack = oldhack; + } + } + PCB_END_LOOP; +} Index: tags/2.3.0/src_plugins/lib_netmap/placement.h =================================================================== --- tags/2.3.0/src_plugins/lib_netmap/placement.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_netmap/placement.h (revision 33253) @@ -0,0 +1,13 @@ +#include "board.h" +#include "data.h" +#include "ht_subc.h" + +typedef struct { + htscp_t subcs; + pcb_board_t *pcb; + pcb_data_t data; /* temp buffer to place prototype subcs in */ +} pcb_placement_t; + +void pcb_placement_init(pcb_placement_t *ctx, pcb_board_t *pcb); +void pcb_placement_uninit(pcb_placement_t *ctx); +void pcb_placement_build(pcb_placement_t *ctx, pcb_data_t *data); Index: tags/2.3.0/src_plugins/lib_polyhelp/Makefile =================================================================== --- tags/2.3.0/src_plugins/lib_polyhelp/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/lib_polyhelp/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_lib_polyhelp + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/lib_polyhelp/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/lib_polyhelp/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/lib_polyhelp/Plug.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +put /local/pcb/mod {lib_polyhelp} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/lib_polyhelp/polyhelp.o + $(PLUGDIR)/lib_polyhelp/topoly.o + $(PLUGDIR)/lib_polyhelp/triangulate.o +@] + +switch /local/pcb/lib_polyhelp/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/lib_polyhelp/lib_polyhelp.pup =================================================================== --- tags/2.3.0/src_plugins/lib_polyhelp/lib_polyhelp.pup (nonexistent) +++ tags/2.3.0/src_plugins/lib_polyhelp/lib_polyhelp.pup (revision 33253) @@ -0,0 +1,6 @@ +$class lib +$short polygon helpers +$long functions to help plugins processing polygons and PolyHatch() action +$state works +$package (core) +default buildin Index: tags/2.3.0/src_plugins/lib_polyhelp/polyhelp.c =================================================================== --- tags/2.3.0/src_plugins/lib_polyhelp/polyhelp.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_polyhelp/polyhelp.c (revision 33253) @@ -0,0 +1,562 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include "polyhelp.h" +#include "polygon.h" +#include +#include +#include "obj_line.h" +#include "undo_old.h" +#include "undo.h" +#include +#include +#include + +#include "topoly.h" + +/* for the action: */ +static const char *polyhelp_cookie = "lib_polyhelp"; +#include +#include "board.h" +#include "data.h" +#include "conf_core.h" +#include +#include +#include + +void pcb_pline_fprint_anim(FILE *f, const rnd_pline_t *pl) +{ + const rnd_vnode_t *v, *n; + fprintf(f, "!pline start\n"); + v = pl->head; + do { + n = v->next; + rnd_fprintf(f, "line %#mm %#mm %#mm %#mm\n", v->point[0], v->point[1], n->point[0], n->point[1]); + } + while((v = v->next) != pl->head); + fprintf(f, "!pline end\n"); +} + +#if 0 +/* debug helper */ +static void cross(FILE *f, rnd_coord_t x, rnd_coord_t y) +{ + static rnd_coord_t cs = RND_MM_TO_COORD(0.2); + rnd_fprintf(f, "line %#mm %#mm %#mm %#mm\n", x - cs, y, x + cs, y); + rnd_fprintf(f, "line %#mm %#mm %#mm %#mm\n", x, y - cs, x, y + cs); +} +#endif + +rnd_cardinal_t pcb_pline_to_lines(pcb_layer_t *dst, const rnd_pline_t *src, rnd_coord_t thickness, rnd_coord_t clearance, pcb_flag_t flags, rnd_bool undoable) +{ + rnd_cardinal_t cnt = 0; + vtp0_t tracks; + long i; + + vtp0_init(&tracks); + rnd_pline_dup_offsets(&tracks, src, -((thickness/2)+1)); + + for(i = 0; i < tracks.used; i++) { + const rnd_vnode_t *v, *n; + rnd_pline_t *track = tracks.array[i]; + + v = track->head; + do { + pcb_line_t *l; + + n = v->next; + l = pcb_line_new(dst, v->point[0], v->point[1], n->point[0], n->point[1], thickness, clearance, flags); + if (undoable) + pcb_undo_add_obj_to_create_noclear(PCB_OBJ_LINE, dst, l, l); + + cnt++; + } + while((v = v->next) != track->head); + rnd_poly_contour_del(&track); + } + + vtp0_uninit(&tracks); + return cnt; +} + +rnd_bool pcb_pline_is_aligned(const rnd_pline_t *src) +{ + const rnd_vnode_t *v, *n; + + v = src->head; + do { + n = v->next; + if ((v->point[0] != n->point[0]) && (v->point[1] != n->point[1])) + return rnd_false; + } + while((v = v->next) != src->head); + return rnd_true; +} + + +rnd_bool pcb_cpoly_is_simple_rect(const pcb_poly_t *p) +{ + if (p->Clipped->f != p->Clipped) + return rnd_false; /* more than one islands */ + if (p->Clipped->contours->next != NULL) + return rnd_false; /* has holes */ + return pcb_pline_is_rectangle(p->Clipped->contours); +} + +rnd_cardinal_t pcb_cpoly_num_corners(const pcb_poly_t *src) +{ + rnd_cardinal_t res = 0; + pcb_poly_it_t it; + rnd_polyarea_t *pa; + + + for(pa = pcb_poly_island_first(src, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_pline_t *pl; + + pl = pcb_poly_contour(&it); + if (pl != NULL) { /* we have a contour */ + res += pl->Count; + for(pl = pcb_poly_hole_first(&it); pl != NULL; pl = pcb_poly_hole_next(&it)) + res += pl->Count; + } + } + + return res; +} + +static void add_track_seg(pcb_cpoly_edgetree_t *dst, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + pcb_cpoly_edge_t *e = &dst->edges[dst->used++]; + rnd_box_t *b = &e->bbox; + + if (x1 <= x2) { + b->X1 = x1; + b->X2 = x2; + } + else { + b->X1 = x2; + b->X2 = x1; + } + if (y1 <= y2) { + b->Y1 = y1; + b->Y2 = y2; + } + else { + b->Y1 = y2; + b->Y2 = y1; + } + + e->x1 = x1; + e->y1 = y1; + e->x2 = x2; + e->y2 = y2; + + rnd_box_bump_box(&dst->bbox, b); + rnd_r_insert_entry(dst->edge_tree, (rnd_box_t *)e); +} + +static void add_track(pcb_cpoly_edgetree_t *dst, rnd_pline_t *track) +{ + int go, first = 1; + rnd_coord_t x, y, px, py; + pcb_poly_it_t it; + + it.cntr = track; + for(go = pcb_poly_vect_first(&it, &x, &y); go; go = pcb_poly_vect_next(&it, &x, &y)) { + if (!first) + add_track_seg(dst, px, py, x, y); + first = 0; + px = x; + py = y; + } + + pcb_poly_vect_first(&it, &x, &y); + add_track_seg(dst, px, py, x, y); +} + + +/* collect all edge lines (contour and holes) in an rtree, calculate the bbox */ +pcb_cpoly_edgetree_t *pcb_cpoly_edgetree_create(const pcb_poly_t *src, rnd_coord_t offs) +{ + pcb_poly_it_t it; + rnd_polyarea_t *pa; + pcb_cpoly_edgetree_t *res; + rnd_cardinal_t alloced = pcb_cpoly_num_corners(src) * sizeof(pcb_cpoly_edge_t); + + res = malloc(sizeof(pcb_cpoly_edgetree_t) + alloced); + + res->alloced = alloced; + res->used = 0; + res->edge_tree = rnd_r_create_tree(); + res->bbox.X1 = res->bbox.Y1 = RND_MAX_COORD; + res->bbox.X2 = res->bbox.Y2 = -RND_MAX_COORD; + + for(pa = pcb_poly_island_first(src, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_pline_t *pl, *track; + + pl = pcb_poly_contour(&it); + if (pl != NULL) { /* we have a contour */ + track = rnd_pline_dup_offset(pl, -offs); + add_track(res, track); + rnd_poly_contour_del(&track); + + for(pl = pcb_poly_hole_first(&it); pl != NULL; pl = pcb_poly_hole_next(&it)) { + track = rnd_pline_dup_offset(pl, -offs); + add_track(res, track); + rnd_poly_contour_del(&track); + } + } + } + + return res; +} + +void pcb_cpoly_edgetree_destroy(pcb_cpoly_edgetree_t *etr) +{ + rnd_r_destroy_tree(&etr->edge_tree); + free(etr); +} + +typedef struct { + int used; + rnd_coord_t at; + rnd_coord_t coord[1]; +} intersect_t; + +static rnd_r_dir_t pcb_cploy_hatch_edge_hor(const rnd_box_t *region, void *cl) +{ + intersect_t *is = (intersect_t *)cl; + pcb_cpoly_edge_t *e = (pcb_cpoly_edge_t *)region; + + if (e->y1 != e->y2) { + /* consider only non-horizontal edges */ + if (e->x1 != e->x2) { + double y = ((double)e->x2 - (double)e->x1) / ((double)e->y2 - (double)e->y1) * ((double)is->at - (double)e->y1) + (double)e->x1; + is->coord[is->used] = y; + } + else + is->coord[is->used] = e->x1; /* faster method for vertical */ + is->used++; + } + + return RND_R_DIR_FOUND_CONTINUE; +} + +static rnd_r_dir_t pcb_cploy_hatch_edge_ver(const rnd_box_t *region, void *cl) +{ + intersect_t *is = (intersect_t *)cl; + pcb_cpoly_edge_t *e = (pcb_cpoly_edge_t *)region; + + if (e->x1 != e->x2) { + /* consider only non-vertical edges */ + if (e->y1 != e->y2) { + double x = ((double)e->y2 - (double)e->y1) / ((double)e->x2 - (double)e->x1) * ((double)is->at - (double)e->x1) + (double)e->y1; + is->coord[is->used] = x; + } + else + is->coord[is->used] = e->y1; /* faster method for vertical */ + is->used++; + } + + return RND_R_DIR_FOUND_CONTINUE; +} + +static int coord_cmp(const void *p1, const void *p2) +{ + const rnd_coord_t *c1 = p1, *c2 = p2; + if (*c1 < *c2) + return -1; + return 1; +} + + +void pcb_cpoly_hatch(const pcb_poly_t *src, pcb_cpoly_hatchdir_t dir, rnd_coord_t offs, rnd_coord_t period, void *ctx, void (*cb)(void *ctx, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2)) +{ + pcb_cpoly_edgetree_t *etr; + rnd_box_t scan; + int n; + intersect_t *is; + + if (dir == 0) + return; + + etr = pcb_cpoly_edgetree_create(src, offs); + + is = malloc(sizeof(intersect_t) + sizeof(rnd_coord_t) * etr->alloced); + + if (dir & PCB_CPOLY_HATCH_HORIZONTAL) { + rnd_coord_t y; + + for(y = etr->bbox.Y1; y <= etr->bbox.Y2; y += period) { + scan.X1 = -RND_MAX_COORD; + scan.X2 = RND_MAX_COORD; + scan.Y1 = y; + scan.Y2 = y+1; + + is->used = 0; + is->at = y; + rnd_r_search(etr->edge_tree, &scan, NULL, pcb_cploy_hatch_edge_hor, is, NULL); + qsort(is->coord, is->used, sizeof(rnd_coord_t), coord_cmp); + for(n = 1; n < is->used; n+=2) /* call the callback for the odd scan lines */ + cb(ctx, is->coord[n-1], y, is->coord[n], y); + } + } + + if (dir & PCB_CPOLY_HATCH_VERTICAL) { + rnd_coord_t x; + + for(x = etr->bbox.X1; x <= etr->bbox.X2; x += period) { + scan.Y1 = -RND_MAX_COORD; + scan.Y2 = RND_MAX_COORD; + scan.X1 = x; + scan.X2 = x+1; + + is->used = 0; + is->at = x; + rnd_r_search(etr->edge_tree, &scan, NULL, pcb_cploy_hatch_edge_ver, is, NULL); + qsort(is->coord, is->used, sizeof(rnd_coord_t), coord_cmp); + for(n = 1; n < is->used; n+=2) /* call the callback for the odd scan lines */ + cb(ctx, x, is->coord[n-1], x, is->coord[n]); + } + } + + free(is); + pcb_cpoly_edgetree_destroy(etr); +} + + +typedef struct { + pcb_layer_t *dst; + rnd_coord_t thickness, clearance; + pcb_flag_t flags; + unsigned undoable:1; +} hatch_ctx_t; + +static void hatch_cb(void *ctx_, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2) +{ + hatch_ctx_t *ctx = (hatch_ctx_t *)ctx_; + pcb_line_t *l = pcb_line_new(ctx->dst, x1, y1, x2, y2, ctx->thickness, ctx->clearance, ctx->flags); + if (ctx->undoable) + pcb_undo_add_obj_to_create_noclear(PCB_OBJ_LINE, ctx->dst, l, l); +} + +void pcb_cpoly_hatch_lines(pcb_layer_t *dst, const pcb_poly_t *src, pcb_cpoly_hatchdir_t dir, rnd_coord_t period, rnd_coord_t thickness, rnd_coord_t clearance, pcb_flag_t flags, rnd_bool undoable) +{ + hatch_ctx_t ctx; + + + ctx.dst = dst; + ctx.thickness = thickness; + ctx.clearance = clearance; + ctx.flags = flags; + ctx.undoable = undoable; + + pcb_cpoly_hatch(src, dir, (thickness/2)+1, period, &ctx, hatch_cb); +} + +static int polyhatch_gui(rnd_coord_t *period, pcb_cpoly_hatchdir_t *dir, pcb_flag_t *flg, int *want_contour) +{ + int wspc, wcont, whor, wver, wclr; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"ok", 0}, {NULL, 0}}; + RND_DAD_DECL(dlg); + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_BEGIN_TABLE(dlg, 2); + + RND_DAD_LABEL(dlg, "Spacing"); + RND_DAD_COORD(dlg); + RND_DAD_HELP(dlg, "Distance between centerlines of adjacent hatch lines for vertical and horizontal hatching"); + RND_DAD_DEFAULT_NUM(dlg, conf_core.design.line_thickness * 2); + RND_DAD_MINMAX(dlg, 1, RND_MM_TO_COORD(100)); + wspc = RND_DAD_CURRENT(dlg); + + RND_DAD_LABEL(dlg, "Draw contour"); + RND_DAD_BOOL(dlg); + RND_DAD_HELP(dlg, "Draw the contour of the polygon"); + wcont = RND_DAD_CURRENT(dlg); + + RND_DAD_LABEL(dlg, "Draw horizontal hatch"); + RND_DAD_BOOL(dlg); + RND_DAD_HELP(dlg, "Draw evenly spaced horizontal hatch lines"); + whor = RND_DAD_CURRENT(dlg); + + RND_DAD_LABEL(dlg, "Draw vertical hatch"); + RND_DAD_BOOL(dlg); + RND_DAD_HELP(dlg, "Draw evenly spaced vertical hatch lines"); + wver = RND_DAD_CURRENT(dlg); + + RND_DAD_LABEL(dlg, "Clear-line"); + RND_DAD_BOOL(dlg); + RND_DAD_HELP(dlg, "Hatch lines have clearance"); + wclr = RND_DAD_CURRENT(dlg); + + RND_DAD_END(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + RND_DAD_NEW("poly_hatch", dlg, "Polygon hatch", NULL, rnd_true, NULL); + if (RND_DAD_RUN(dlg) != 0) { + /* cancel */ + RND_DAD_FREE(dlg); + return -1; + } + + *period = dlg[wspc].val.crd; + if (dlg[wcont].val.lng) *want_contour = 1; + + *dir = 0; + if (dlg[whor].val.lng) *dir |= PCB_CPOLY_HATCH_HORIZONTAL; + if (dlg[wver].val.lng) *dir |= PCB_CPOLY_HATCH_VERTICAL; + + *flg = pcb_flag_make(dlg[wclr].val.lng ? PCB_FLAG_CLEARLINE : 0); + + RND_DAD_FREE(dlg); + return 0; +} + +static const char pcb_acts_PolyHatch[] = "PolyHatch([spacing], [hvcp])\nPolyHatch(interactive)\n"; +static const char pcb_acth_PolyHatch[] = "hatch the selected polygon(s) with lines of the current style; lines are drawn on the current layer; flags are h:horizontal, v:vertical, c:contour, p:poly"; +static fgw_error_t pcb_act_PolyHatch(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *op, *arg = NULL; + rnd_coord_t period = 0; + pcb_cpoly_hatchdir_t dir = 0; + pcb_flag_t flg; + int want_contour = 0, want_poly = 0, cont_specd = 0, undoable = 1; + + RND_ACT_CONVARG(1, FGW_STR, PolyHatch, op = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, PolyHatch, arg = argv[2].val.str); + + if (rnd_strcasecmp(op, "interactive") == 0) { + if (polyhatch_gui(&period, &dir, &flg, &want_contour) != 0) { + RND_ACT_IRES(1); + return 0; + } + } + else { + if (op != NULL) { + rnd_bool succ; + period = rnd_get_value(op, NULL, NULL, &succ); + if (!succ) { + rnd_message(RND_MSG_ERROR, "Invalid spacing value - must be a coordinate\n"); + return -1; + } + } + + if (arg != NULL) { + if (strchr(arg, 'c')) want_contour = 1; + if (strchr(arg, 'p')) want_poly = 1; + if (strchr(arg, 'h')) dir |= PCB_CPOLY_HATCH_HORIZONTAL; + if (strchr(arg, 'v')) dir |= PCB_CPOLY_HATCH_VERTICAL; + cont_specd = 1; + } + + if (cont_specd == 0) { + dir = PCB_CPOLY_HATCH_HORIZONTAL | PCB_CPOLY_HATCH_VERTICAL; + want_contour = 1; + } + if (period == 0) + period = conf_core.design.line_thickness * 2; + + flg = pcb_flag_make(conf_core.editor.clear_line ? PCB_FLAG_CLEARLINE : 0); + } + + PCB_POLY_ALL_LOOP(PCB->Data); { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, polygon)) + continue; + if (want_contour) { + pcb_poly_it_t it; + rnd_polyarea_t *pa; + for(pa = pcb_poly_island_first(polygon, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_pline_t *pl = pcb_poly_contour(&it); + if (pl != NULL) { /* we have a contour */ + pcb_pline_to_lines(PCB_CURRLAYER(PCB), pl, conf_core.design.line_thickness, conf_core.design.line_thickness * 2, flg, undoable); + for(pl = pcb_poly_hole_first(&it); pl != NULL; pl = pcb_poly_hole_next(&it)) + pcb_pline_to_lines(PCB_CURRLAYER(PCB), pl, conf_core.design.line_thickness, conf_core.design.line_thickness * 2, flg, undoable); + } + } + } + if (want_poly) { + pcb_poly_t *p = pcb_poly_new_from_poly(PCB_CURRLAYER(PCB), polygon, period, polygon->Clearance, polygon->Flags); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, p); + } + pcb_cpoly_hatch_lines(PCB_CURRLAYER(PCB), polygon, dir, period, conf_core.design.line_thickness, conf_core.design.line_thickness * 2, flg, undoable); + } PCB_ENDALL_LOOP; + + if (undoable) + pcb_undo_inc_serial(); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_PolyOffs[] = "PolyOffs(offset)\n"; +static const char pcb_acth_PolyOffs[] = "replicate the outer contour of the selected polygon(s) with growing or shrinking them by offset; the new polygon is drawn on the current layer"; +static fgw_error_t pcb_act_PolyOffs(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_coord_t offs; + + RND_ACT_CONVARG(1, FGW_COORD, PolyOffs, offs = fgw_coord(&argv[1])); + + PCB_POLY_ALL_LOOP(PCB->Data); { + pcb_poly_t *p; + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, polygon)) + continue; + + p = pcb_poly_new_from_poly(PCB_CURRLAYER(PCB), polygon, offs, polygon->Clearance, polygon->Flags); + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, p); + } PCB_ENDALL_LOOP; + + RND_ACT_IRES(0); + return 0; +} + + +static rnd_action_t polyhelp_action_list[] = { + {"PolyHatch", pcb_act_PolyHatch, pcb_acth_PolyHatch, pcb_acts_PolyHatch}, + {"PolyOffs", pcb_act_PolyOffs, pcb_acth_PolyOffs, pcb_acts_PolyOffs}, + {"ToPoly", pcb_act_topoly, pcb_acth_topoly, pcb_acts_topoly} +}; + +int pplg_check_ver_lib_polyhelp(int ver_needed) { return 0; } + +void pplg_uninit_lib_polyhelp(void) +{ + rnd_remove_actions_by_cookie(polyhelp_cookie); +} + +int pplg_init_lib_polyhelp(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(polyhelp_action_list, polyhelp_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/lib_polyhelp/polyhelp.h =================================================================== --- tags/2.3.0/src_plugins/lib_polyhelp/polyhelp.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_polyhelp/polyhelp.h (revision 33253) @@ -0,0 +1,76 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "obj_poly.h" + + +void pcb_pline_fprint_anim(FILE *f, const rnd_pline_t *pl); + +/* Add lines on dst tracing pline from the inner side (no line will extend + outside of the original pline, except when the original polygon has a hair + narrower than thickness). Returns number of lines created */ +rnd_cardinal_t pcb_pline_to_lines(pcb_layer_t *dst, const rnd_pline_t *src, rnd_coord_t thickness, rnd_coord_t clearance, pcb_flag_t flags, rnd_bool undoable); + +/* Returns whether the clipped polygon is a simple rectangle (single island, + no-hole rectangle). */ +rnd_bool pcb_cpoly_is_simple_rect(const pcb_poly_t *p); + +/* Returns whether all edges of a pline are axis aligned */ +rnd_bool pcb_pline_is_aligned(const rnd_pline_t *src); + +/*** Generate an rtree of all edges if a polygon */ + +typedef struct { + rnd_box_t bbox; + rnd_coord_t x1, y1, x2, y2; +} pcb_cpoly_edge_t; + +typedef struct { + rnd_rtree_t *edge_tree; + rnd_box_t bbox; + rnd_cardinal_t used, alloced; + pcb_cpoly_edge_t edges[1]; +} pcb_cpoly_edgetree_t; + +pcb_cpoly_edgetree_t *pcb_cpoly_edgetree_create(const pcb_poly_t *src, rnd_coord_t offs); +void pcb_cpoly_edgetree_destroy(pcb_cpoly_edgetree_t *etr); + + +/*** hatching ***/ + +/* bitfield to request horizontal and/or vertical hatching or striping */ +typedef enum { + PCB_CPOLY_HATCH_HORIZONTAL = 1, + PCB_CPOLY_HATCH_VERTICAL = 2 +} pcb_cpoly_hatchdir_t; + +/* hatch a polygon with horizontal and/or vertical lines drawn on dst, + one line per period */ +void pcb_cpoly_hatch_lines(pcb_layer_t *dst, const pcb_poly_t *src, pcb_cpoly_hatchdir_t dir, rnd_coord_t period, rnd_coord_t thickness, rnd_coord_t clearance, pcb_flag_t flags, rnd_bool undoable); + +/* Generic hor-ver hatch with a callback */ +void pcb_cpoly_hatch(const pcb_poly_t *src, pcb_cpoly_hatchdir_t dir, rnd_coord_t offs, rnd_coord_t period, void *ctx, void (*cb)(void *ctx, rnd_coord_t x1, rnd_coord_t y1, rnd_coord_t x2, rnd_coord_t y2)); + Index: tags/2.3.0/src_plugins/lib_polyhelp/topoly.c =================================================================== --- tags/2.3.0/src_plugins/lib_polyhelp/topoly.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_polyhelp/topoly.c (revision 33253) @@ -0,0 +1,479 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include "topoly.h" + +#include +#include +#include "data.h" +#include "obj_arc.h" +#include "obj_line.h" +#include "obj_poly.h" +#include "obj_poly_draw.h" +#include "obj_pstk_inlines.h" +#include "find.h" +#include "polygon.h" +#include "search.h" +#include +#include +#include "funchash_core.h" + +#define VALID_TYPE(obj) (((obj)->type == PCB_OBJ_ARC) || ((obj)->type == PCB_OBJ_LINE)) +#define CONT_TYPE (PCB_OBJ_LINE | PCB_OBJ_ARC) + +#define NEAR(x1, x2, y1, y2) (((double)(x1-x2)*(double)(x1-x2) + (double)(y1-y2)*(double)(y1-y2)) < 4) + +/*** map the contour ***/ +typedef struct { + vtp0_t *list; + vti0_t *endlist; + pcb_any_obj_t *curr, *result; + rnd_coord_t tx, ty; + pcb_dynf_t mark; +} next_conn_t; + +static rnd_r_dir_t next_conn_found_arc(const rnd_box_t *box, void *cl) +{ + rnd_coord_t ex, ey; + next_conn_t *ctx = cl; + pcb_any_obj_t *obj = (pcb_any_obj_t *)box; + int n; + + if (PCB_DFLAG_TEST(&obj->Flags, ctx->mark)) + return RND_R_DIR_NOT_FOUND; /* object already mapped */ + + for(n = 0; n < 2; n++) { + pcb_arc_get_end((pcb_arc_t *)obj, n, &ex, &ey); + if (NEAR(ctx->tx, ex, ctx->ty, ey)) { + vti0_append(ctx->endlist, n); + vtp0_append(ctx->list, obj); + PCB_DFLAG_SET(&obj->Flags, ctx->mark); + ctx->result = obj; + return RND_R_DIR_FOUND_CONTINUE; + } + } + + return RND_R_DIR_NOT_FOUND; +} + +static rnd_r_dir_t next_conn_found_line(const rnd_box_t *box, void *cl) +{ + next_conn_t *ctx = cl; + pcb_any_obj_t *obj = (pcb_any_obj_t *)box; + pcb_line_t *l = (pcb_line_t *)box; + + if (PCB_DFLAG_TEST(&obj->Flags, ctx->mark)) + return RND_R_DIR_NOT_FOUND; /* object already mapped */ + + if (NEAR(ctx->tx, l->Point1.X, ctx->ty, l->Point1.Y)) { + vti0_append(ctx->endlist, 0); + vtp0_append(ctx->list, obj); + PCB_DFLAG_SET(&obj->Flags, ctx->mark); + ctx->result = obj; + return RND_R_DIR_FOUND_CONTINUE; + } + + if (NEAR(ctx->tx, l->Point2.X, ctx->ty, l->Point2.Y)) { + vti0_append(ctx->endlist, 1); + vtp0_append(ctx->list, obj); + PCB_DFLAG_SET(&obj->Flags, ctx->mark); + ctx->result = obj; + return RND_R_DIR_FOUND_CONTINUE; + } + + return RND_R_DIR_NOT_FOUND; +} + +static pcb_any_obj_t *next_conn(vtp0_t *list, vti0_t *endlist, pcb_any_obj_t *curr, pcb_dynf_t df) +{ + pcb_line_t *l; + int n; + next_conn_t ctx; + rnd_coord_t cx[2], cy[2]; + + /* determine the endpoints of the current object */ + switch(curr->type) { + case PCB_OBJ_ARC: + pcb_arc_get_end((pcb_arc_t *)curr, 0, &cx[0], &cy[0]); + pcb_arc_get_end((pcb_arc_t *)curr, 1, &cx[1], &cy[1]); + break; + case PCB_OBJ_LINE: + l = (pcb_line_t *)curr; + cx[0] = l->Point1.X; cy[0] = l->Point1.Y; + cx[1] = l->Point2.X; cy[1] = l->Point2.Y; + break; + default: + return NULL; + } + + ctx.curr = curr; + ctx.list = list; + ctx.endlist = endlist; + ctx.result = NULL; + ctx.mark = df; + + for(n = 0; n < 2; n++) { + rnd_box_t region; + int len; + + region.X1 = cx[n]-1; + region.Y1 = cy[n]-1; + region.X2 = cx[n]+1; + region.Y2 = cy[n]+1; + ctx.tx = cx[n]; + ctx.ty = cy[n]; + + rnd_r_search(curr->parent.layer->arc_tree, ®ion, NULL, next_conn_found_arc, &ctx, &len); + if (len > 1) { + rnd_message(RND_MSG_ERROR, "map_contour(): contour is not a clean loop: it contains at least one stub or subloop\n"); + return NULL; + } + if (ctx.result != NULL) + return ctx.result; + + rnd_r_search(curr->parent.layer->line_tree, ®ion, NULL, next_conn_found_line, &ctx, &len); + if (len > 1) { + rnd_message(RND_MSG_ERROR, "map_contour(): contour is not a clean loop: it contains at least one stub or subloop\n"); + return NULL; + } + if (ctx.result != NULL) + return ctx.result; + } + + return NULL; /* nothing found */ +} + +static int map_contour_with(pcb_data_t *data, vtp0_t *list, vti0_t *endlist, pcb_any_obj_t *start, pcb_dynf_t df) +{ + long i; + pcb_any_obj_t *n; + +/*rnd_trace("loop start: %d\n", start->ID);*/ + vtp0_append(list, start); + PCB_DFLAG_SET(&start->Flags, df); + for(i = 0, n = next_conn(list, endlist, start, df); n != start; n = next_conn(list, endlist, n, df), i++) { + if (n == NULL) { +/* rnd_trace(" broken trace\n");*/ + return -1; + } + if (i == 1) + PCB_DFLAG_CLR(&start->Flags, df); /* allow finding the start object again for proper closing */ + } + + return 0; +} + +static int map_contour(pcb_data_t *data, vtp0_t *list, vti0_t *endlist, pcb_any_obj_t *start) +{ + int res; + pcb_dynf_t df; + df = pcb_dynflag_alloc("topoly_map_contour"); + pcb_data_dynflag_clear(data, df); + + res = map_contour_with(data, list, endlist, start, df); + + pcb_dynflag_free(df); + return res; +} + +static int contour2poly_cb(void *uctx, rnd_coord_t x, rnd_coord_t y) +{ + pcb_poly_t *poly = uctx; + pcb_poly_point_new(poly, x, y); + return 0; +} + +pcb_poly_t *contour2poly(pcb_board_t *pcb, vtp0_t *objs, vti0_t *ends, pcb_topoly_t how) +{ + int n; + pcb_any_obj_t **obj = (pcb_any_obj_t **)(&objs->array[0]); + int *end = &ends->array[0]; + pcb_layer_t *layer = (*obj)->parent.layer; + pcb_poly_t *poly = pcb_poly_alloc(layer); + + obj++; + for(n = 1; n < vtp0_len(objs); obj++,end++,n++) { + pcb_line_t *l = (pcb_line_t *)*obj; + pcb_arc_t *a = (pcb_arc_t *)*obj; + + /* end[0] is the starting endpoint of the current *obj, + end[1] is the starting endpoint of the next *obj */ + switch((*obj)->type) { + case PCB_OBJ_LINE: + switch(end[0]) { + case 0: pcb_poly_point_new(poly, l->Point1.X, l->Point1.Y); break; + case 1: pcb_poly_point_new(poly, l->Point2.X, l->Point2.Y); break; + default: abort(); + } + break; + case PCB_OBJ_ARC: + pcb_arc_approx(a, 0, end[0] != 0, poly, contour2poly_cb); + poly->PointN--; /* remove the arc endpoint to avoid redundant point on the start of the next object */ + break; + default: + pcb_poly_free(poly); + return NULL; + } + } + + if (!(how & PCB_TOPOLY_FLOATING)) { + pcb_add_poly_on_layer(layer, poly); + pcb_poly_init_clip(pcb->Data, layer, poly); + pcb_poly_invalidate_draw(layer, poly); + pcb_board_set_changed_flag(pcb, rnd_true); + } + + return poly; +} + +pcb_poly_t *pcb_topoly_conn_with(pcb_board_t *pcb, pcb_any_obj_t *start, pcb_topoly_t how, pcb_dynf_t df) +{ + vtp0_t objs; + vti0_t ends; + int res; + pcb_poly_t *poly; + + if (!VALID_TYPE(start)) { + rnd_message(RND_MSG_ERROR, "pcb_topoly_conn(): starting object is not a line or arc\n"); + return NULL; + } + + vtp0_init(&objs); + vti0_init(&ends); + if (df < 0) + res = map_contour(pcb->Data, &objs, &ends, start); + else + res = map_contour_with(pcb->Data, &objs, &ends, start, df); + if (res != 0) { + rnd_message(RND_MSG_ERROR, "pcb_topoly_conn(): failed to find a closed loop of lines and arcs\n"); + vtp0_uninit(&objs); + vti0_uninit(&ends); + return NULL; + } + + poly = contour2poly(pcb, &objs, &ends, how); + + vtp0_uninit(&objs); + vti0_uninit(&ends); + return poly; +} + +pcb_poly_t *pcb_topoly_conn(pcb_board_t *pcb, pcb_any_obj_t *start, pcb_topoly_t how) +{ + return pcb_topoly_conn_with(pcb, start, how, -1); +} + +typedef struct { + pcb_board_t *pcb; + pcb_poly_t *poly; + pcb_dynf_t df; + vtp0_t pstks; /* a list of (pcb_pstk_t *) of padstacks having mech shape crossing the poly border */ + + /* temporary, per pline callback fields */ + pcb_pstk_t *ps; + pcb_pstk_shape_t *shape; +} pstk_on_outline_t; + +/* rtree callback on pline segment crossing padstack bbox */ +static rnd_r_dir_t pcb_topoly_check_pstk_on_pline_cb(const rnd_box_t *box, void *cl) +{ + pstk_on_outline_t *ctx = cl; + pcb_find_t fctx = {0}; + pcb_line_t line = {0}; + rnd_vnode_t *vn = rnd_pline_seg2vnode((void *)box); + + line.Point1.X = vn->point[0]; line.Point1.Y = vn->point[1]; + line.Point2.X = vn->next->point[0]; line.Point2.Y = vn->next->point[1]; + if (pcb_isc_pstk_line_shp(&fctx, ctx->ps, &line, ctx->shape)) { + if (ctx->df != -1) + PCB_DFLAG_SET(&ctx->ps->Flags, ctx->df); + vtp0_append(&ctx->pstks, ctx->ps); + } + + return RND_R_DIR_NOT_FOUND; +} + +/* rtree callback on generated polygon overlapping padstack */ +static rnd_r_dir_t pcb_topoly_check_pstk_on_outline_cb(const rnd_box_t *box, void *cl) +{ + pstk_on_outline_t *ctx = cl; + pcb_pstk_t *ps = (pcb_pstk_t *)box; + pcb_pstk_shape_t holetmp; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + pcb_pstk_shape_t *shape = pcb_pstk_shape_mech_or_hole_(ps, proto, &holetmp); + + if (shape == NULL) + return RND_R_DIR_NOT_FOUND; + + ctx->ps = ps; + ctx->shape = shape; + rnd_r_search(ctx->poly->Clipped->contours->tree, &ps->bbox_naked, NULL, pcb_topoly_check_pstk_on_pline_cb, ctx, NULL); + ctx->ps = NULL; + ctx->shape = NULL; + + return RND_R_DIR_NOT_FOUND; +} + +#define check(x, y, obj) \ +do { \ + double dist = (double)x*(double)x + (double)y*(double)y; \ + if (dist < bestd) { \ + bestd = dist; \ + best = (pcb_any_obj_t *)obj; \ + } \ +} while(0) + +pcb_any_obj_t *pcb_topoly_find_1st_outline(pcb_board_t *pcb) +{ + rnd_layer_id_t lid; + pcb_layer_t *layer; + pcb_any_obj_t *best = NULL; + rnd_coord_t x, y; + double bestd = (double)pcb->hidlib.size_y*(double)pcb->hidlib.size_y + (double)pcb->hidlib.size_x*(double)pcb->hidlib.size_x; + + for(lid = 0; lid < pcb->Data->LayerN; lid++) { + if (!PCB_LAYER_IS_OUTLINE(pcb_layer_flags(PCB, lid), pcb_layer_purpose(PCB, lid, NULL))) + continue; + + layer = pcb_get_layer(PCB->Data, lid); + PCB_LINE_LOOP(layer) { + check(line->Point1.X, line->Point1.Y, line); + check(line->Point2.X, line->Point2.Y, line); + } + PCB_END_LOOP; + + PCB_ARC_LOOP(layer) { + pcb_arc_get_end(arc, 0, &x, &y); + check(x, y, arc); + pcb_arc_get_end(arc, 1, &x, &y); + check(x, y, arc); + pcb_arc_middle(arc, &x, &y); + check(x, y, arc); + } + PCB_END_LOOP; + } + + return best; +} +#undef check + +pcb_poly_t *pcb_topoly_1st_outline_with(pcb_board_t *pcb, pcb_topoly_t how, pcb_dynf_t df) +{ + pcb_poly_t *poly; + pcb_any_obj_t *start = pcb_topoly_find_1st_outline(pcb); + pstk_on_outline_t pctx; + int need_full; + long n; + + if (start == NULL) { + poly = pcb_poly_alloc(pcb->Data->Layer); + pcb_poly_point_new(poly, 0, 0); + pcb_poly_point_new(poly, pcb->hidlib.size_x, 0); + pcb_poly_point_new(poly, pcb->hidlib.size_x, pcb->hidlib.size_y); + pcb_poly_point_new(poly, 0, pcb->hidlib.size_y); + } + else + poly = pcb_topoly_conn_with(pcb, start, how, df); + + if (poly == NULL) + return NULL; + + pcb_poly_bbox(poly); + poly->Clipped = pcb_poly_to_polyarea(poly, &need_full); + + if (need_full) + rnd_message(RND_MSG_ERROR, "pcb_topoly_1st_outline_with: internal error: need full poly\nPlease report this bug with an example file!\n"); + + /* padstacks crossing polygon boundary need to be subtracted from the poly as + they modify the contour */ + pctx.pcb = pcb; + pctx.poly = poly; + pctx.df = df; + vtp0_init(&pctx.pstks); + + /* map: first search (and mark) all offending padstacks */ + rnd_r_search(pcb->Data->padstack_tree, &poly->bbox_naked, NULL, pcb_topoly_check_pstk_on_outline_cb, &pctx, NULL); + + /* apply: subtract all padstacks found while mapping */ + for(n = 0; n < pctx.pstks.used; n++) { + pcb_pstk_t *ps = pctx.pstks.array[n]; + pcb_pstk_shape_t holetmp; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + pcb_pstk_shape_t *shape = pcb_pstk_shape_mech_or_hole_(ps, proto, &holetmp); + rnd_polyarea_t *mpa = pcb_pstk_shape2polyarea(ps, shape); + if (mpa != NULL) + pcb_poly_subtract(mpa, poly, 1); + } + + vtp0_uninit(&pctx.pstks); + return poly; +} + +pcb_poly_t *pcb_topoly_1st_outline(pcb_board_t *pcb, pcb_topoly_t how) +{ + return pcb_topoly_1st_outline_with(pcb, how, -1); +} + +const char pcb_acts_topoly[] = "ToPoly()\nToPoly(outline)\n"; +const char pcb_acth_topoly[] = "convert a closed loop of lines and arcs into a polygon"; +fgw_error_t pcb_act_topoly(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *op = NULL; + void *r1, *r2, *r3; + + RND_ACT_MAY_CONVARG(1, FGW_STR, topoly, op = argv[1].val.str); + + if (op == NULL) { + rnd_coord_t x, y; + rnd_hid_get_coords("Click on a line or arc of the contour loop", &x, &y, 0); + if (pcb_search_screen(x, y, CONT_TYPE, &r1, &r2, &r3) == 0) { + rnd_message(RND_MSG_ERROR, "ToPoly(): failed to find a line or arc there\n"); + RND_ACT_IRES(1); + return 0; + } + } + else { + if (strcmp(op, "outline") == 0) { + pcb_topoly_1st_outline(PCB, 0); + RND_ACT_IRES(0); + return 0; + } + else { + rnd_message(RND_MSG_ERROR, "Invalid first argument\n"); + RND_ACT_IRES(1); + return 0; + } + } + + pcb_topoly_conn(PCB, r2, 0); + RND_ACT_IRES(0); + return 0; +} Index: tags/2.3.0/src_plugins/lib_polyhelp/topoly.h =================================================================== --- tags/2.3.0/src_plugins/lib_polyhelp/topoly.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_polyhelp/topoly.h (revision 33253) @@ -0,0 +1,63 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_TOPOLY_H +#define PCB_TOPOLY_H + +#include "board.h" +#include "obj_common.h" +#include + +typedef enum pcb_topoly_e { + PCB_TOPOLY_KEEP_ORIG = 1, /* keep original objects */ + PCB_TOPOLY_FLOATING = 2 /* do not add the new polygon on any layer */ +} pcb_topoly_t; + +/* Convert a loop of connected objects into a polygon (with no holes); the first + object is named in start. The _with version uses a caller provided dynamic + flag that is not cleared within the call so multiple loops can be mapped. */ +pcb_poly_t *pcb_topoly_conn(pcb_board_t *pcb, pcb_any_obj_t *start, pcb_topoly_t how); +pcb_poly_t *pcb_topoly_conn_with(pcb_board_t *pcb, pcb_any_obj_t *start, pcb_topoly_t how, pcb_dynf_t df); + + +/* Find the first line/arc on the outline layer from top-left */ +pcb_any_obj_t *pcb_topoly_find_1st_outline(pcb_board_t *pcb); + +/* Construct a polygon of the first line/arc on the outline layer from + top-left; if df is not -1, lines and arcs are marked with df. Furthermore + padstacks with hole/slot that cross the contour of the polygon are marked + with df (if df is not -1) */ +pcb_poly_t *pcb_topoly_1st_outline_with(pcb_board_t *pcb, pcb_topoly_t how, pcb_dynf_t df); + +/* Construct a polygon of the first line/arc on the outline layer from top-left */ +pcb_poly_t *pcb_topoly_1st_outline(pcb_board_t *pcb, pcb_topoly_t how); + + +extern const char pcb_acts_topoly[]; +extern const char pcb_acth_topoly[]; +fgw_error_t pcb_act_topoly(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv); + +#endif Index: tags/2.3.0/src_plugins/lib_polyhelp/triangulate.c =================================================================== --- tags/2.3.0/src_plugins/lib_polyhelp/triangulate.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_polyhelp/triangulate.c (revision 33253) @@ -0,0 +1,5 @@ +#include "config.h" + +#define FP2T_POLY2TRI_IMPLEMENTATION +#include "triangulate.h" + Index: tags/2.3.0/src_plugins/lib_polyhelp/triangulate.h =================================================================== --- tags/2.3.0/src_plugins/lib_polyhelp/triangulate.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_polyhelp/triangulate.h (revision 33253) @@ -0,0 +1,18 @@ +#ifndef PCB_POLYHELP_TRIANGULATE_H +#define PCB_POLYHELP_TRIANGULATE_H + +#include + +typedef unsigned char fp2t_u8_t; +typedef long fp2t_i32_t; +typedef int fp2t_b32_t; +typedef unsigned long fp2t_u32_t; +typedef size_t fp2t_uxx_t; +typedef int fp2t_bxx_t; +typedef size_t fp2t_imm_t; +typedef size_t fp2t_umm_t; + +#define FP2T_APIFUNC +#include "../src_3rd/fast89-poly2tri/fast89_poly2tri.h" + +#endif Index: tags/2.3.0/src_plugins/lib_vfs/Makefile =================================================================== --- tags/2.3.0/src_plugins/lib_vfs/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/lib_vfs/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_lib_vfs + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/lib_vfs/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/lib_vfs/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/lib_vfs/Plug.tmpasm (revision 33253) @@ -0,0 +1,10 @@ +put /local/pcb/mod {lib_vfs} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/lib_vfs/lib_vfs.o +@] + +switch /local/pcb/lib_vfs/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/lib_vfs/lib_vfs.c =================================================================== --- tags/2.3.0/src_plugins/lib_vfs/lib_vfs.c (nonexistent) +++ tags/2.3.0/src_plugins/lib_vfs/lib_vfs.c (revision 33253) @@ -0,0 +1,593 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "board.h" +#include "data.h" +#include +#include +#include +#include + +#include "../src_plugins/propedit/props.h" +#include "../src_plugins/propedit/propsel.h" + +#include "lib_vfs.h" + +static void cb_mknode(pcb_vfs_list_cb cb, void *ctx, gds_t *path, const char *append, int isdir) +{ + int ou = path->used; + gds_append_str(path, append); + cb(ctx, path->array, isdir); + path->used = ou; +} + +static void cb_mkdir(pcb_vfs_list_cb cb, void *ctx, gds_t *path, const char *append) +{ + cb_mknode(cb, ctx, path, append, 1); +} + +/* append 'append' to path, assuming it is a data node, not a directory; create + all parent directories found within 'append' if they are not already in 'seen' + and store them in 'seen' */ +static void cb_mkdirp(pcb_vfs_list_cb cb, void *ctx, gds_t *path, const char *append, htsp_t *seen) +{ + int ou = path->used; + char *s, *next; + + gds_append_str(path, append); +/*rnd_trace("---- mkdirp '%s'\n", path->array);*/ + for(s = path->array + ou;; s = next) { + next = strchr(s, '/'); + if (next == NULL) + break; + *next= '\0'; +/*rnd_trace(" dir '%s'\n", path->array);*/ + if (!htsp_has(seen, path->array)) { + htsp_set(seen, rnd_strdup(path->array), ctx); + cb(ctx, path->array, 1); + } + *next= '/'; + next++; + } + + path->used = ou; +} + +#define SEE \ + htsp_init(&seen, strhash, strkeyeq); + +#define UNSEE \ + do { \ + htsp_entry_t *e; \ + for(e = htsp_first(&seen); e != NULL; e = htsp_next(&seen, e)) \ + free(e->key); \ + htsp_uninit(&seen); \ + } while(0) + +static void vfs_list_props(gds_t *path, pcb_propedit_t *pctx, pcb_vfs_list_cb cb, void *ctx) +{ + htsp_t seen; + htsp_entry_t *e; + size_t ou, orig_used; + + pcb_propsel_map_core(pctx); + SEE; + + orig_used = path->used; + gds_append(path, '/'); + ou = path->used; + for(e = htsp_first(&pctx->props); e != NULL; e = htsp_next(&pctx->props, e)) { + path->used = ou; + cb_mkdirp(cb, ctx, path, e->key, &seen); + path->used = ou; + gds_append_str(path, e->key); + cb(ctx, path->array, 0); + } + path->used = orig_used; + UNSEE; +} + +static int vfs_access_prop(pcb_propedit_t *pctx, const char *path, gds_t *buff, int wr, int *isdir) +{ + pcb_props_t *pt; + pcb_propval_t *pv; + htprop_entry_t *e; + + if ((*path == '\0') || (strcmp(path, "p") == 0)) + goto ret_dir; + + pcb_propsel_map_core(pctx); + pt = htsp_get(&pctx->props, path); + + if (pt == NULL) + goto ret_dir; /* trust our listing */ + + if (isdir != NULL) + *isdir = 0; + + if (wr) { + pcb_propset_ctx_t sctx; + sctx.s = buff->array; + TODO("convert the other fields as well"); + return pcb_propsel_set(pctx, path, &sctx) == 1; + } + + e = htprop_first(&pt->values); + pv = &e->key; + + if (buff != NULL) { + free(buff->array); + buff->array = pcb_propsel_printval(pt->type, pv); + buff->used = buff->alloced = strlen(buff->array); + gds_append(buff, '\n'); + } + + return 0; + + ret_dir:; + if (isdir != NULL) + *isdir = 1; + if (wr == 0) + return 0; + return -1; +} + +static void vfs_list_obj(pcb_board_t *pcb, gds_t *path, pcb_any_obj_t *obj, pcb_vfs_list_cb cb, void *ctx) +{ + htsp_t seen; + pcb_propedit_t pctx; + pcb_idpath_t *idp; + htsp_entry_t *e; + size_t ou, orig_used; + + idp = pcb_obj2idpath(obj); + if (idp == NULL) + return; + + pcb_props_init(&pctx, pcb); + pcb_idpath_list_append(&pctx.objs, idp); + pcb_propsel_map_core(&pctx); + + SEE; + + orig_used = path->used; + rnd_append_printf(path, "/%s/%ld", pcb_obj_type_name(obj->type), obj->ID); + cb(ctx, path->array, 1); + gds_append(path, '/'); + ou = path->used; + for(e = htsp_first(&pctx.props); e != NULL; e = htsp_next(&pctx.props, e)) { + path->used = ou; + cb_mkdirp(cb, ctx, path, e->key, &seen); + gds_append_str(path, e->key); + cb(ctx, path->array, 0); + } + path->used = orig_used; + + pcb_props_uninit(&pctx); + pcb_idpath_destroy(idp); + UNSEE; +} + +static int vfs_access_obj(pcb_board_t *pcb, pcb_any_obj_t *obj, const char *path, gds_t *buff, int wr, int *isdir) +{ + pcb_propedit_t pctx; + pcb_idpath_t *idp; + int res; + + idp = pcb_obj2idpath(obj); + if (idp == NULL) + return -1; + + if (*path == '\0') { + if (isdir != NULL) + *isdir = 1; + if (wr == 0) + return 0; + return -1; + } + + pcb_props_init(&pctx, pcb); + pcb_idpath_list_append(&pctx.objs, idp); + res = vfs_access_prop(&pctx, path, buff, wr, isdir); + pcb_props_uninit(&pctx); + pcb_idpath_destroy(idp); + + return res; +} + +static void vfs_list_layers(pcb_board_t *pcb, pcb_vfs_list_cb cb, void *ctx, const char *datapath, pcb_data_t *data) +{ + gds_t path; + rnd_layer_id_t lid; + size_t orig_used; + + gds_init(&path); + gds_append_str(&path, datapath); + gds_append_str(&path, "/layers"); + cb(ctx, path.array, 1); + + gds_append(&path, '/'); + orig_used = path.used; + + + for(lid = 0; lid < data->LayerN; lid++) { + pcb_propedit_t pctx; + + path.used = orig_used; + rnd_append_printf(&path, "%ld", lid); + cb(ctx, path.array, 1); + + cb_mkdir(cb, ctx, &path, "/line"); + cb_mkdir(cb, ctx, &path, "/poly"); + cb_mkdir(cb, ctx, &path, "/text"); + cb_mkdir(cb, ctx, &path, "/arc"); + + pcb_props_init(&pctx, pcb); + vtl0_append(&pctx.layers, lid); + vfs_list_props(&path, &pctx, cb, ctx); + pcb_props_uninit(&pctx); + + { + pcb_layer_t *layer = pcb_get_layer(data, lid); + pcb_line_t *l; + pcb_arc_t *a; + pcb_poly_t *p; + pcb_text_t *t; + gdl_iterator_t it; + + linelist_foreach(&layer->Line, &it, l) + vfs_list_obj(pcb, &path, (pcb_any_obj_t *)l, cb, ctx); + polylist_foreach(&layer->Polygon, &it, p) + vfs_list_obj(pcb, &path, (pcb_any_obj_t *)p, cb, ctx); + textlist_foreach(&layer->Text, &it, t) + vfs_list_obj(pcb, &path, (pcb_any_obj_t *)t, cb, ctx); + arclist_foreach(&layer->Arc, &it, a) + vfs_list_obj(pcb, &path, (pcb_any_obj_t *)a, cb, ctx); + } + } + gds_uninit(&path); +} + +static void vfs_list_subcs(pcb_board_t *pcb, pcb_vfs_list_cb cb, void *ctx, const char *datapath, pcb_data_t *data) +{ + pcb_subc_t *subc; + gdl_iterator_t it; + gds_t path; + size_t shrt, orig_used; + + gds_init(&path); + gds_append_str(&path, datapath); + shrt = path.used; + gds_append_str(&path, "/subcircuit"); + cb(ctx, path.array, 1); + + gds_append(&path, '/'); + orig_used = path.used; + + subclist_foreach(&data->subc, &it, subc) { + path.used = shrt; + vfs_list_obj(pcb, &path, (pcb_any_obj_t *)subc, cb, ctx); + + + path.used = orig_used; + rnd_append_printf(&path, "%ld/data", subc->ID); + cb(ctx, path.array, 1); + vfs_list_layers(pcb, cb, ctx, path.array, subc->data); + } + gds_uninit(&path); +} + +static void vfs_list_data(pcb_board_t *pcb, pcb_vfs_list_cb cb, void *ctx, const char *datapath, pcb_data_t *data) +{ + vfs_list_layers(pcb, cb, ctx, datapath, data); + vfs_list_subcs(pcb, cb, ctx, datapath, data); +} + +static int vfs_access_layer(pcb_board_t *pcb, const char *path, gds_t *buff, int wr, int *isdir, pcb_data_t *data) +{ + pcb_propedit_t pctx; + char *end; + rnd_layer_id_t lid = strtol(path, &end, 10); + int res; + + if (*end == '\0') { + pcb_layer_t *ly = pcb_get_layer(data, lid); + if (ly == NULL) + return -1; + goto ret_dir; + } + + if (*end != '/') + return -1; + path=end+1; + + if (path[1] == '/') { /* direct layer access */ + pcb_props_init(&pctx, pcb); + vtl0_append(&pctx.layers, lid); + res = vfs_access_prop(&pctx, path, buff, wr, isdir); + pcb_props_uninit(&pctx); + } + else { + char *sep = strchr(path, '/'); + long oid; + pcb_any_obj_t *obj = NULL; + pcb_objtype_t ty; + + if (sep == NULL) + goto ret_dir; + + oid = strtol(sep+1, &end, 10); + + if ((*end != '/') && (*end != '\0')) + return -1; + + if ((strncmp(path, "line/", 5) == 0) || (strcmp(path, "line") == 0)) + ty = PCB_OBJ_LINE; + else if ((strncmp(path, "poly/", 5) == 0) || (strcmp(path, "poly") == 0)) + ty = PCB_OBJ_POLY; + else if ((strncmp(path, "text/", 5) == 0) || (strcmp(path, "text") == 0)) + ty = PCB_OBJ_TEXT; + else if ((strncmp(path, "arc/", 4) == 0) || (strcmp(path, "arc") == 0)) + ty = PCB_OBJ_ARC; + else if ((strncmp(path, "gfx/", 4) == 0) || (strcmp(path, "gfx") == 0)) + ty = PCB_OBJ_GFX; + else + return -1; + + if (*end == '\0') + path = end; + else + path=end+1; + obj = htip_get(&data->id2obj, oid); + if ((obj == NULL) || (obj->type != ty)) + return -1; + if ((obj->parent_type != PCB_PARENT_LAYER) || (obj->parent.layer != pcb_get_layer(data, lid))) + return -1; + res = vfs_access_obj(pcb, obj, path, buff, wr, isdir); + } + + return res; + + ret_dir:; + if (isdir != NULL) + *isdir = 1; + return 0; +} + + +static int vfs_access_subcircuit(pcb_board_t *pcb, const char *path, gds_t *buff, int wr, int *isdir) +{ + char *end; + long int oid = strtol(path, &end, 10); + pcb_subc_t *subc; + + if (*end == '\0') + goto ret_dir; + + if (*end != '/') + return -1; + + subc = htip_get(&pcb->Data->id2obj, oid); + if ((subc == NULL) || (subc->type != PCB_OBJ_SUBC)) + return -1; + + end++; + + /* single char dir, like a/ or p/ means object property of the subc itself */ + if ((end[1] == '/') || (end[1] == '\0')) + return vfs_access_obj(pcb, (pcb_any_obj_t *)subc, end, buff, wr, isdir); + + if (strncmp(end, "data", 4) == 0) { + if (end[4] == '\0') + goto ret_dir; + if (end[4] != '/') + return -1; + end += 5; + if (strcmp(end, "layers") == 0) + goto ret_dir; + return vfs_access_layer(pcb, end+7, buff, wr, isdir, subc->data); + } + + /* unknown subtree */ + return -1; + + ret_dir:; + if (isdir != NULL) + *isdir = 1; + return 0; +} + + +static void vfs_list_layergrps(pcb_board_t *pcb, pcb_vfs_list_cb cb, void *ctx) +{ + gds_t path; + rnd_layergrp_id_t gid; + size_t orig_used; + + cb(ctx, "layer_groups", 1); + gds_init(&path); + gds_append_str(&path, "layer_groups/"); + orig_used = path.used; + + for(gid = 0; gid < pcb->LayerGroups.len; gid++) { + pcb_propedit_t pctx; + + path.used = orig_used; + rnd_append_printf(&path, "%ld", gid); + cb(ctx, path.array, 1); + + pcb_props_init(&pctx, pcb); + vtl0_append(&pctx.layergrps, gid); + vfs_list_props(&path, &pctx, cb, ctx); + pcb_props_uninit(&pctx); + } + gds_uninit(&path); +} + +static int vfs_access_layergrp(pcb_board_t *pcb, const char *path, gds_t *buff, int wr, int *isdir) +{ + pcb_propedit_t pctx; + char *end; + rnd_layergrp_id_t gid = strtol(path, &end, 10); + int res; + + if ((*end != '/') && (*end != '\0')) + return -1; + + if (*end == '\0') + path = end; + else + path=end+1; + + pcb_props_init(&pctx, pcb); + vtl0_append(&pctx.layergrps, gid); + res = vfs_access_prop(&pctx, path, buff, wr, isdir); + pcb_props_uninit(&pctx); + + return res; +} + + +static void vfs_list_conf(pcb_board_t *pcb, pcb_vfs_list_cb cb, void *ctx) +{ + gds_t path; + htsp_entry_t *e; + htsp_t seen; + int ou; + + gds_init(&path); + gds_append_str(&path, "conf/"); + ou = path.used; + SEE; + rnd_conf_fields_foreach(e) { + path.used = ou; + cb_mkdirp(cb, ctx, &path, e->key, &seen); + gds_append_str(&path, e->key); + cb(ctx, path.array, 0); + } + UNSEE; + gds_uninit(&path); +} + +static int vfs_conf_printf(void *ctx, const char *fmt, ...) +{ + va_list ap; + gds_t *buff = ctx; + int res; + + va_start(ap, fmt); + res = rnd_safe_append_vprintf(buff, 0, fmt, ap); + va_end(ap); + return res; +} + +static int vfs_access_conf(pcb_board_t *pcb, const char *path, gds_t *buff, int wr, int *isdir) +{ + rnd_conf_native_t *nat = rnd_conf_get_field(path); + if (nat == NULL) { + if (isdir != NULL) + *isdir = 1; + if (wr == 0) + return 0; + return 1; + } + + + if (isdir != NULL) + *isdir = 0; + + if (wr) + return rnd_conf_set(RND_CFR_DESIGN, path, 0, buff->array, RND_POL_OVERWRITE); + else + rnd_conf_print_native((rnd_conf_pfn)vfs_conf_printf, buff, NULL, 0, nat); + + return 0; +} + +int pcb_vfs_list(pcb_board_t *pcb, pcb_vfs_list_cb cb, void *ctx) +{ + vfs_list_layergrps(pcb, cb, ctx); + cb(ctx, "data", 1); + vfs_list_data(pcb, cb, ctx, "data", pcb->Data); + cb(ctx, "conf", 1); + vfs_list_conf(pcb, cb, ctx); + + TODO("cb(ctx, route_styles, 1)"); + TODO("cb(ctx, netlist, 1)"); + + return 0; +} + + + +int pcb_vfs_access(pcb_board_t *pcb, const char *path, gds_t *buff, int wr, int *isdir) +{ + if ((strcmp(path, "data") == 0) || (strcmp(path, "data/layers") == 0) || (strcmp(path, "data/subcircuit") == 0)) { + if (isdir != NULL) + *isdir = 1; + if (!wr) + return 0; + } + if (strncmp(path, "data/layers/", 12) == 0) + return vfs_access_layer(pcb, path+12, buff, wr, isdir, pcb->Data); + if (strncmp(path, "data/subcircuit/", 16) == 0) + return vfs_access_subcircuit(pcb, path+16, buff, wr, isdir); + + if (strcmp(path, "layer_groups") == 0) { + if (isdir != NULL) + *isdir = 1; + if (!wr) + return 0; + } + if (strncmp(path, "layer_groups/", 13) == 0) + return vfs_access_layergrp(pcb, path+13, buff, wr, isdir); + + if (strcmp(path, "conf") == 0) { + if (isdir != NULL) + *isdir = 1; + if (!wr) + return 0; + } + if (strncmp(path, "conf/", 5) == 0) + return vfs_access_conf(pcb, path+5, buff, wr, isdir); + + return -1; +} + + +int pplg_check_ver_lib_vfs(int ver_needed) { return 0; } + +void pplg_uninit_lib_vfs(void) +{ +} + +int pplg_init_lib_vfs(void) +{ + RND_API_CHK_VER; + return 0; +} Index: tags/2.3.0/src_plugins/lib_vfs/lib_vfs.h =================================================================== --- tags/2.3.0/src_plugins/lib_vfs/lib_vfs.h (nonexistent) +++ tags/2.3.0/src_plugins/lib_vfs/lib_vfs.h (revision 33253) @@ -0,0 +1,33 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "board.h" + +typedef void (*pcb_vfs_list_cb)(void *ctx, const char *path, int isdir); + +int pcb_vfs_list(pcb_board_t *pcb, pcb_vfs_list_cb cb, void *ctx); +int pcb_vfs_access(pcb_board_t *pcb, const char *path, gds_t *buff, int wr, int *isdir); + Index: tags/2.3.0/src_plugins/lib_vfs/lib_vfs.pup =================================================================== --- tags/2.3.0/src_plugins/lib_vfs/lib_vfs.pup (nonexistent) +++ tags/2.3.0/src_plugins/lib_vfs/lib_vfs.pup (revision 33253) @@ -0,0 +1,6 @@ +$class lib +$short fetch data for VFS export +$long Retrieve, sort and query data under VFS export plugins +$state works +dep propedit +default disable-all Index: tags/2.3.0/src_plugins/millpath/Makefile =================================================================== --- tags/2.3.0/src_plugins/millpath/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/millpath/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_millpath + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/millpath/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/millpath/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/millpath/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {millpath} +append /local/pcb/mod/OBJS [@ + $(PLUGDIR)/millpath/millpath.o + $(PLUGDIR)/millpath/toolpath.o +@] + +switch /local/pcb/millpath/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/millpath/millpath.c =================================================================== --- tags/2.3.0/src_plugins/millpath/millpath.c (nonexistent) +++ tags/2.3.0/src_plugins/millpath/millpath.c (revision 33253) @@ -0,0 +1,83 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include +#include +#include "toolpath.h" + +#include "board.h" +#include "data.h" +#include "layer.h" + +const char *pcb_millpath_cookie = "millpath plugin"; + +static pcb_tlp_session_t ctx; +static rnd_coord_t tool_dias[] = { + RND_MM_TO_COORD(0.5), + RND_MM_TO_COORD(3) +}; +static pcb_tlp_tools_t tools = { sizeof(tool_dias)/sizeof(tool_dias[0]), tool_dias}; + +static const char pcb_acts_mill[] = "mill([script])"; +static const char pcb_acth_mill[] = "Calculate toolpath for milling away copper"; +fgw_error_t pcb_act_mill(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *script = NULL; + pcb_board_t *pcb = (pcb_board_t *)RND_ACT_HIDLIB; + ctx.edge_clearance = RND_MM_TO_COORD(0.05); + ctx.tools = &tools; + + RND_ACT_MAY_CONVARG(1, FGW_STR, mill, script = argv[1].val.str); + + if (script == NULL) + RND_ACT_IRES(pcb_tlp_mill_copper_layer(pcb, &ctx, pcb_get_layergrp(pcb, PCB_CURRLAYER(PCB)->meta.real.grp))); + else + RND_ACT_IRES(pcb_tlp_mill_script(pcb, &ctx, pcb_get_layergrp(pcb, PCB_CURRLAYER(PCB)->meta.real.grp), script)); + + return 0; +} + + +rnd_action_t millpath_action_list[] = { + {"mill", pcb_act_mill, pcb_acth_mill, pcb_acts_mill} +}; + +int pplg_check_ver_millpath(int ver_needed) { return 0; } + +void pplg_uninit_millpath(void) +{ + rnd_remove_actions_by_cookie(pcb_millpath_cookie); +} + + +int pplg_init_millpath(void) +{ + RND_API_CHK_VER; + + RND_REGISTER_ACTIONS(millpath_action_list, pcb_millpath_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/millpath/millpath.pup =================================================================== --- tags/2.3.0/src_plugins/millpath/millpath.pup (nonexistent) +++ tags/2.3.0/src_plugins/millpath/millpath.pup (revision 33253) @@ -0,0 +1,8 @@ +$class feature +$short calculate toolpath for milling +$long Calculate and simulate toolpath for milling away opper +$state WIP +$package export +default disable +autoload 1 +dep lib_polyhelp Index: tags/2.3.0/src_plugins/millpath/toolpath.c =================================================================== --- tags/2.3.0/src_plugins/millpath/toolpath.c (nonexistent) +++ tags/2.3.0/src_plugins/millpath/toolpath.c (revision 33253) @@ -0,0 +1,535 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include + +#include "toolpath.h" + +#include "board.h" +#include "data.h" +#include "flag.h" +#include "layer.h" +#include "layer_grp.h" +#include "layer_ui.h" +#include "obj_line.h" +#include "obj_line_op.h" +#include "obj_arc.h" +#include "obj_poly.h" +#include "obj_poly_op.h" +#include "obj_text_draw.h" +#include "polygon.h" +#include +#include "funchash_core.h" +#include + +#include "src_plugins/lib_polyhelp/polyhelp.h" +#include "src_plugins/ddraft/centgeo.h" + +extern const char *pcb_millpath_cookie; + +RND_INLINE void sub_layer_line(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layer_t *layer, const pcb_line_t *line_in, int centerline) +{ + pcb_line_t line_tmp; + + memcpy(&line_tmp, line_in, sizeof(line_tmp)); + PCB_FLAG_SET(PCB_FLAG_CLEARLINE, &line_tmp); + if (centerline) { + line_tmp.Thickness = 1; + line_tmp.Clearance = result->edge_clearance; + } + else + line_tmp.Clearance = 1; + pcb_poly_sub_obj(pcb->Data, layer, result->fill, PCB_OBJ_LINE, &line_tmp); +} + +RND_INLINE void sub_layer_arc(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layer_t *layer, const pcb_arc_t *arc_in, int centerline) +{ + pcb_arc_t arc_tmp; + + memcpy(&arc_tmp, arc_in, sizeof(arc_tmp)); + PCB_FLAG_SET(PCB_FLAG_CLEARLINE, &arc_tmp); + if (centerline) { + arc_tmp.Thickness = 1; + arc_tmp.Clearance = result->edge_clearance; + } + else + arc_tmp.Clearance = 1; + pcb_poly_sub_obj(pcb->Data, layer, result->fill, PCB_OBJ_ARC, &arc_tmp); +} + +RND_INLINE void sub_layer_poly(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layer_t *layer, const pcb_poly_t *poly, int centerline) +{ + rnd_polyarea_t *f, *b, *ra; + + if (!PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, poly)) { + f = poly->Clipped->f; + b = poly->Clipped->b; + poly->Clipped->f = poly->Clipped->b = poly->Clipped; + } + + rnd_polyarea_boolean(result->fill->Clipped, poly->Clipped, &ra, RND_PBO_SUB); + rnd_polyarea_free(&result->fill->Clipped); + result->fill->Clipped = ra; + + if (!PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, poly)) { + poly->Clipped->f = f; + poly->Clipped->b = b; + } +} + +typedef struct { + pcb_board_t *pcb; + pcb_tlp_session_t *result; + int centerline; + pcb_layer_t *layer; +} sub_layer_text_t; + +static void sub_layer_text(void *ctx_, pcb_any_obj_t *obj) +{ + sub_layer_text_t *ctx = ctx_; + pcb_poly_t *poly = (pcb_poly_t *)obj; + rnd_bool dummy; + + switch(obj->type) { + case PCB_OBJ_LINE: sub_layer_line(ctx->pcb, ctx->result, ctx->layer, (pcb_line_t *)obj, ctx->centerline); break; + case PCB_OBJ_ARC: sub_layer_arc(ctx->pcb, ctx->result, ctx->layer, (pcb_arc_t *)obj, ctx->centerline); break; + case PCB_OBJ_POLY: + poly->Clipped = pcb_poly_to_polyarea(poly, &dummy); + sub_layer_poly(ctx->pcb, ctx->result, ctx->layer, poly, ctx->centerline); + rnd_polyarea_free(&poly->Clipped); + break; + default: rnd_message(RND_MSG_ERROR, "Internal error: toolpath sub_layer_text() invalid object type %ld\n", obj->type); + } +} + +static void sub_layer_all(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layer_t *layer, int centerline) +{ + rnd_rtree_it_t it; + pcb_line_t *line; + pcb_arc_t *arc; + pcb_poly_t *poly; + pcb_text_t *text; + sub_layer_text_t slt; + + for(line = (pcb_line_t *)rnd_r_first(layer->line_tree, &it); line != NULL; line = (pcb_line_t *)rnd_r_next(&it)) + sub_layer_line(pcb, result, layer, line, centerline); + + for(arc = (pcb_arc_t *)rnd_r_first(layer->arc_tree, &it); arc != NULL; arc = (pcb_arc_t *)rnd_r_next(&it)) + sub_layer_arc(pcb, result, layer, arc, centerline); + + for(poly = (pcb_poly_t *)rnd_r_first(layer->polygon_tree, &it); poly != NULL; poly = (pcb_poly_t *)rnd_r_next(&it)) + sub_layer_poly(pcb, result, layer, poly, centerline); + + slt.pcb = pcb; + slt.layer = layer; + slt.centerline = centerline; + slt.result = result; + for(text = (pcb_text_t *)rnd_r_first(layer->text_tree, &it); text != NULL; text = (pcb_text_t *)rnd_r_next(&it)) + pcb_text_decompose_text(NULL, text, sub_layer_text, &slt); +} + + +static void sub_group_all(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layergrp_t *grp, int centerline) +{ + int n; + for(n = 0; n < grp->len; n++) { + pcb_layer_t *l = pcb_get_layer(PCB->Data, grp->lid[n]); + if (l != NULL) + sub_layer_all(pcb, result, l, centerline); + } +} + +static void sub_global_all(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layer_t *layer) +{ + pcb_pstk_t *ps, ps_tmp; + rnd_rtree_it_t it; + + for(ps = (pcb_pstk_t *)rnd_r_first(pcb->Data->padstack_tree, &it); ps != NULL; ps = (pcb_pstk_t *)rnd_r_next(&it)) { + memcpy(&ps_tmp, ps, sizeof(ps_tmp)); + ps_tmp.Clearance = 1; + ps_tmp.thermals.used = 0; + pcb_poly_sub_obj(pcb->Data, layer, result->fill, PCB_OBJ_PSTK, &ps_tmp); + } +} + +static void setup_ui_layers(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layergrp_t *grp) +{ + gdl_iterator_t it; + pcb_line_t *line; + static rnd_color_t clr1, clr2, clr3; + + if (clr1.str[0] != '#') + rnd_color_load_str(&clr1, "#EE9922"); + if (clr2.str[0] != '#') + rnd_color_load_str(&clr2, "#886611"); + if (clr3.str[0] != '#') + rnd_color_load_str(&clr3, "#FFCC55"); + + if (result->res_ply == NULL) + result->res_ply = pcb_uilayer_alloc(pcb_millpath_cookie, "mill remove", &clr1); + + if (result->res_remply == NULL) + result->res_remply = pcb_uilayer_alloc(pcb_millpath_cookie, "mill remain", &clr3); + + if (result->res_path == NULL) + result->res_path = pcb_uilayer_alloc(pcb_millpath_cookie, "mill toolpath", &clr2); + + if (result->fill != NULL) + pcb_polyop_destroy(NULL, result->res_ply, result->fill); + + if (result->remain != NULL) + pcb_polyop_destroy(NULL, result->res_remply, result->remain); + + linelist_foreach(&result->res_path->Line, &it, line) { + pcb_lineop_destroy(NULL, result->res_path, line); + } +} + +static void setup_remove_poly(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layergrp_t *grp, int polarity) +{ + int has_otl; + rnd_layergrp_id_t i; + pcb_layergrp_t *g; + + result->grp = grp; + + has_otl = 0; + for(i = 0, g = pcb->LayerGroups.grp; i < pcb->LayerGroups.len; i++,g++) { + if ((PCB_LAYER_IS_OUTLINE(g->ltype, g->purpi)) && (!pcb_layergrp_is_pure_empty(pcb, i))) { + has_otl = 1; + break; + } + } + + + if (has_otl) { /* if there's an outline layer, the remove-poly shouldn't be bigger than that */ + pcb_line_t *line; + pcb_arc_t *arc; + rnd_rtree_it_t it; + rnd_box_t otlbb; + rnd_layer_id_t lid; + + otlbb.X1 = otlbb.Y1 = RND_MAX_COORD; + otlbb.X2 = otlbb.Y2 = -RND_MAX_COORD; + + for(lid = 0; lid < pcb->Data->LayerN; lid++) { + pcb_layer_t *l; + if (!PCB_LAYER_IS_OUTLINE(pcb_layer_flags(PCB, lid), pcb_layer_purpose(PCB, lid, NULL))) + continue; + + l = pcb_get_layer(PCB->Data, lid); + if (l == NULL) + continue; + + for(line = (pcb_line_t *)rnd_r_first(l->line_tree, &it); line != NULL; line = (pcb_line_t *)rnd_r_next(&it)) + rnd_box_bump_box(&otlbb, (rnd_box_t *)line); + + for(arc = (pcb_arc_t *)rnd_r_first(l->arc_tree, &it); arc != NULL; arc = (pcb_arc_t *)rnd_r_next(&it)) + rnd_box_bump_box(&otlbb, (rnd_box_t *)arc); + } + result->fill = pcb_poly_new_from_rectangle(result->res_ply, otlbb.X1, otlbb.Y1, otlbb.X2, otlbb.Y2, 0, pcb_flag_make(PCB_FLAG_FULLPOLY)); + result->remain = pcb_poly_new_from_rectangle(result->res_remply, otlbb.X1, otlbb.Y1, otlbb.X2, otlbb.Y2, 0, pcb_flag_make(PCB_FLAG_FULLPOLY)); + } + else { + result->fill = pcb_poly_new_from_rectangle(result->res_ply, 0, 0, pcb->hidlib.size_x, pcb->hidlib.size_y, 0, pcb_flag_make(PCB_FLAG_FULLPOLY)); + result->remain = pcb_poly_new_from_rectangle(result->res_remply, 0, 0, pcb->hidlib.size_x, pcb->hidlib.size_y, 0, pcb_flag_make(PCB_FLAG_FULLPOLY)); + } + + pcb_poly_init_clip(pcb->Data, result->res_ply, result->fill); + pcb_poly_init_clip(pcb->Data, result->res_remply, result->remain); + + sub_group_all(pcb, result, result->grp, 0); + if (has_otl) + for(i = 0, g = pcb->LayerGroups.grp; i < pcb->LayerGroups.len; i++,g++) + if (PCB_LAYER_IS_OUTLINE(g->ltype, g->purpi)) + sub_group_all(pcb, result, g, 1); + + + { /* apply all layers within the group */ + long n; + for(n = 0; n < grp->len; n++) { + pcb_layer_t *ly = pcb_get_layer(pcb->Data, grp->lid[n]); + if (ly != NULL) + sub_global_all(pcb, result, ly); + } + } + + /* remove fill from remain */ + { + rnd_polyarea_t *rp; + rnd_polyarea_boolean(result->remain->Clipped, result->fill->Clipped, &rp, RND_PBO_SUB); + rnd_polyarea_free(&result->remain->Clipped); + result->remain->Clipped = rp; + result->remain->Flags.f |= PCB_FLAG_FULLPOLY; + } + + /* for positive polarity, simply swap the two polygons to invert the scene */ + if (polarity > 0) { + pcb_poly_t *tmp = result->remain; + result->remain = result->fill; + result->fill = tmp; + } +} + +static rnd_cardinal_t trace_contour(pcb_board_t *pcb, pcb_tlp_session_t *result, int tool_idx, rnd_coord_t extra_offs) +{ + pcb_poly_it_t it; + rnd_polyarea_t *pa; + rnd_coord_t tool_dia = result->tools->dia[tool_idx]; + rnd_cardinal_t cnt = 0; + + for(pa = pcb_poly_island_first(result->fill, &it); pa != NULL; pa = pcb_poly_island_next(&it)) { + rnd_pline_t *pl = pcb_poly_contour(&it); + if (pl != NULL) { /* we have a contour */ + pcb_pline_to_lines(result->res_path, pl, tool_dia + extra_offs, 0, pcb_no_flags(), 0); + cnt++; + for(pl = pcb_poly_hole_first(&it); pl != NULL; pl = pcb_poly_hole_next(&it)) { + pcb_pline_to_lines(result->res_path, pl, tool_dia + extra_offs, 0, pcb_no_flags(), 0); + cnt++; + } + } + } + return cnt; +} + +static long trace_spiral(pcb_board_t *pcb, pcb_tlp_session_t *result, int tool_idx, rnd_coord_t extra_offs, long passes) +{ + long pass = 0; + rnd_coord_t tool_dia = result->tools->dia[tool_idx]; + + for(;;) { + if ((passes > 0) && (pass >= passes)) + return pass; + if (trace_contour(pcb, result, tool_idx, extra_offs) <= 0) + return pass; + extra_offs += tool_dia; + pass++; + } +} + +/*** remove cuts that would cut into remaining copper ***/ +typedef struct { + pcb_tlp_session_t *result; + pcb_any_obj_t *cut; +} pline_ctx_t; + +rnd_rtree_dir_t fix_overcuts_in_seg(void *ctx_, void *obj, const rnd_rtree_box_t *box) +{ + pline_ctx_t *ctx = ctx_; + pcb_line_t *l = (pcb_line_t *)ctx->cut, lo, vl; + rnd_box_t ip; + double offs[2], ox, oy, vx, vy, len, r; + + assert(ctx->cut->type == PCB_OBJ_LINE); /* need to handle arc later */ + + rnd_polyarea_get_tree_seg(obj, &vl.Point1.X, &vl.Point1.Y, &vl.Point2.X, &vl.Point2.Y); + + /* ox;oy: normal vector scaled to thickness/2 */ + vx = l->Point2.X - l->Point1.X; + vy = l->Point2.Y - l->Point1.Y; + len = sqrt(vx*vx + vy*vy); + r = (double)l->Thickness/2.0 - 500; + vx /= len; + vy /= len; + ox = vy * r; + oy = -vx * r; + + /* check shifted edges for intersection */ + lo.Point1.X = l->Point1.X + ox + vx*500; lo.Point1.Y = l->Point1.Y + oy + vy*500; + lo.Point2.X = l->Point2.X + ox - vx*500; lo.Point2.Y = l->Point2.Y + oy - vy*500; + if (pcb_intersect_cline_cline(&lo, &vl, &ip, offs)) { +/* + pcb_layer_t *ly = &PCB->Data->Layer[1]; + pcb_line_new(ly, l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y, 1, 0, pcb_no_flags()); + pcb_line_new(ly, lo.Point1.X, lo.Point1.Y, lo.Point2.X, lo.Point2.Y, 1, 0, pcb_no_flags()); +*/ + return rnd_RTREE_DIR_FOUND | rnd_RTREE_DIR_STOP; + } + + lo.Point1.X = l->Point1.X - ox + vx*500; lo.Point1.Y = l->Point1.Y - oy + vy*500; + lo.Point2.X = l->Point2.X - ox - vx*500; lo.Point2.Y = l->Point2.Y - oy - vy*500; + if (pcb_intersect_cline_cline(&lo, &vl, &ip, offs)) { +/* + pcb_layer_t *ly = &PCB->Data->Layer[1]; + pcb_line_new(ly, l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y, 1, 0, pcb_no_flags()); + pcb_line_new(ly, lo.Point1.X, lo.Point1.Y, lo.Point2.X, lo.Point2.Y, 1, 0, pcb_no_flags()); +*/ + return rnd_RTREE_DIR_FOUND | rnd_RTREE_DIR_STOP; + } + + return 0; +} + +rnd_rtree_dir_t fix_overcuts_in_pline(void *ctx_, void *obj, const rnd_rtree_box_t *box) +{ + pline_ctx_t *ctx = ctx_; + rnd_pline_t *pl = obj; + + return rnd_rtree_search_obj(pl->tree, (const rnd_rtree_box_t *)&ctx->cut->BoundingBox, fix_overcuts_in_seg, ctx); +} + +static long fix_overcuts(pcb_board_t *pcb, pcb_tlp_session_t *result) +{ + pcb_line_t *line; + gdl_iterator_t it; + pline_ctx_t pctx; + long error = 0; + + pctx.result = result; + + linelist_foreach(&result->res_path->Line, &it, line) { + rnd_polyarea_t *pa; + + pa = result->remain->Clipped; + do { + rnd_rtree_dir_t dir; + + pctx.cut = (pcb_any_obj_t *)line; + + if (pa == NULL) + continue; + dir = rnd_rtree_search_obj(pa->contour_tree, (const rnd_rtree_box_t *)&line->BoundingBox, fix_overcuts_in_pline, &pctx); + if (dir & rnd_RTREE_DIR_FOUND) { /* line crosses poly */ + error++; + pcb_line_free(line); + line = NULL; + } + else { /* check endpoints only if side didn't intersect */ + rnd_polyarea_t *c; + rnd_coord_t r = (line->Thickness-1)/2 - 1000; + int within = 0; + + c = rnd_poly_from_circle(line->Point1.X, line->Point1.Y, r); + within |= rnd_polyarea_touching(pa, c); + rnd_polyarea_free(&c); + + if (!within) { + c = rnd_poly_from_circle(line->Point2.X, line->Point2.Y, r); + if (!within) + within |= rnd_polyarea_touching(pa, c); + rnd_polyarea_free(&c); + } + + if (within) { +/* error++; end circle intersection is normally harmless */ + pcb_line_free(line); + line = NULL; + } + } + + if (line == NULL) + break; + pa = pa->f; + } while(pa != result->remain->Clipped); + } + return error; +} + + +int pcb_tlp_mill_copper_layer(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layergrp_t *grp) +{ + long rem; + + setup_ui_layers(pcb, result, grp); + setup_remove_poly(pcb, result, grp, -1); + + trace_contour(pcb, result, 0, 1000); + + rem = fix_overcuts(pcb, result); + if (rem != 0) + rnd_message(RND_MSG_WARNING, "toolpath: had to remove %ld cuts, there might be short circuits;\ncheck your clearance vs. tool size!\n", rem); + + return 0; +} + +#define req_setup(target) \ + if (setup != target) { \ + if (target) \ + rnd_message(RND_MSG_ERROR, "millpath script: need to call a setup_* function before milling"); \ + else \ + rnd_message(RND_MSG_ERROR, "millpath script: can not call multiple setup_* functions"); \ + continue; \ + } + +int pcb_tlp_mill_script(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layergrp_t *grp, const char *script) +{ + int setup = 0; + setup_ui_layers(pcb, result, grp); + + for(;;) { + size_t consumed; + char **argv; + int argc; + + while(isspace(*script) || (*script == ';')) script++; + if (*script == '\0') break; + + argc = qparse3(script, &argv, QPARSE_DOUBLE_QUOTE | QPARSE_SINGLE_QUOTE | QPARSE_TERM_SEMICOLON | QPARSE_TERM_NEWLINE | QPARSE_SEP_COMMA, &consumed); + + if (strcmp(argv[0], "setup_negative") == 0) { + req_setup(0); + setup_remove_poly(pcb, result, grp, -1); + setup = 1; + } + if (strcmp(argv[0], "setup_positive") == 0) { + req_setup(0); + setup_remove_poly(pcb, result, grp, +1); + setup = 1; + } + else if (strcmp(argv[0], "trace_contour") == 0) { + int tool = 0; + rnd_coord_t extra = 1000; + req_setup(1); + if (argc > 1) tool = atoi(argv[1]); + if (argc > 2) extra = rnd_get_value(argv[2], NULL, NULL, NULL); + trace_contour(pcb, result, tool, extra); + } + else if (strcmp(argv[0], "trace_spiral") == 0) { + long passes = -1; + int tool = 0; + rnd_coord_t extra = 1000; + req_setup(1); + if (argc > 1) tool = atoi(argv[1]); + if (argc > 2) extra = rnd_get_value(argv[2], NULL, NULL, NULL); + if (argc > 3) passes = strtol(argv[3], NULL, 10); + trace_spiral(pcb, result, tool, extra, passes); + } + else if (strcmp(argv[0], "fix_overcuts") == 0) { + long rem = fix_overcuts(pcb, result); + req_setup(1); + if (rem != 0) + rnd_message(RND_MSG_WARNING, "toolpath: had to remove %ld cuts, there might be short circuits;\ncheck your clearance vs. tool size!\n", rem); + } + + qparse_free(argc, &argv); + script += consumed; + } + return 0; +} + Index: tags/2.3.0/src_plugins/millpath/toolpath.h =================================================================== --- tags/2.3.0/src_plugins/millpath/toolpath.h (nonexistent) +++ tags/2.3.0/src_plugins/millpath/toolpath.h (revision 33253) @@ -0,0 +1,77 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2017,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "layer.h" +#include "layer_grp.h" +#include "polygon.h" + +typedef struct pcb_tlp_tools_s pcb_tlp_tools_t; +typedef struct pcb_tlp_line_s pcb_tlp_line_t; +typedef struct pcb_tlp_seg_s pcb_tlp_seg_t; +typedef struct pcb_tlp_session_s pcb_tlp_session_t; + +typedef enum pcb_tlp_segtype_s { + PCB_TLP_SEG_LINE +} pcb_tlp_segtype_t; + + +struct pcb_tlp_tools_s { + int used; /* number of tools */ + rnd_coord_t *dia; /* tool diameters */ +}; + +struct pcb_tlp_line_s { + rnd_coord_t x1, y1, x2, y2; +}; + +struct pcb_tlp_seg_s { + pcb_tlp_segtype_t type; + union { + pcb_tlp_line_t line; + } seg; + /* TODO: list link */ +}; + +struct pcb_tlp_session_s { + const pcb_tlp_tools_t *tools; + rnd_coord_t edge_clearance; /* when milling copper, keep this clearance from the edges */ + + /* temp data */ + pcb_layer_t *res_ply; /* resulting "remove" polygon */ + pcb_layer_t *res_path; /* resulting toolpath */ + pcb_layer_t *res_remply; /* resulting "remain" polygon */ + pcb_poly_t *fill; /* base fill: copper to remove */ + pcb_poly_t *remain; /* remaining copper */ + + pcb_layergrp_t *grp; + + /* TODO: list on segments */ +}; + +int pcb_tlp_mill_copper_layer(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layergrp_t *grp); + +int pcb_tlp_mill_script(pcb_board_t *pcb, pcb_tlp_session_t *result, pcb_layergrp_t *grp, const char *script); + Index: tags/2.3.0/src_plugins/mincut/Makefile =================================================================== --- tags/2.3.0/src_plugins/mincut/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/mincut/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_mincut + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/mincut/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/mincut/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/mincut/Plug.tmpasm (revision 33253) @@ -0,0 +1,9 @@ +put /local/pcb/mod {mincut} +append /local/pcb/mod/OBJS [@ $(PLUGDIR)/mincut/rats_mincut.o $(PLUGDIR)/mincut/pcb-mincut/graph.o $(PLUGDIR)/mincut/pcb-mincut/solve.o @] +put /local/pcb/mod/CONF {$(PLUGDIR)/mincut/rats_mincut_conf.h} + +switch /local/pcb/mincut/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/mincut/mincut.pup =================================================================== --- tags/2.3.0/src_plugins/mincut/mincut.pup (nonexistent) +++ tags/2.3.0/src_plugins/mincut/mincut.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short minimal cut shorts +$long Use the minimal cut algorithm to indicate shorts: instead of highlighting two random pins/pads, try to highlight the least number of objects that connect the two networks. +$state works +$package (core) +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/COPYING =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/COPYING (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/COPYING (revision 33253) @@ -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/2.3.0/src_plugins/mincut/pcb-mincut/H.in =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/H.in (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/H.in (revision 33253) @@ -0,0 +1,8 @@ +# a-1-b +# | +# C-2-D + +net1 a b +net2 C D +neut 1 2 +conn C-2 D-2 a-1 b-1 1-2 Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/Makefile =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/Makefile (revision 33253) @@ -0,0 +1,14 @@ +CFLAGS = -g -Wall -I../../../src_3rd -I../../../src -I../../.. +LDFLAGS = -lm +OBJS = main.o solve.o load.o graph.o ../../../src_3rd/genht/htsi.o ../../../src_3rd/genht/hash.o + +all: main + +main: $(OBJS) + +test: + cd test_cases && make + + +clean: + rm $(OBJS) 2>/dev/null ; true Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/README =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/README (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/README (revision 33253) @@ -0,0 +1,16 @@ +This mini-project demonstrates a minimal cut implementation tailored +to solve pcb-rnd "how to highlight shorts" problem. + +It should compile out of the box on GNU/Linux using make. Running +a test case: + +./main < test_cases/H3.in + +If graphviz is installed, input graphs are drawn. Changing the +#defines in solve.c causes more debug messages printed and/or +debug graphs drawn. + +The solver is portable as it is part of pcb-rnd. The stand-alone testbench is +not that portable. The production code is solve.[ch], the rest is for +the testbench. + Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/graph.c =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/graph.c (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/graph.c (revision 33253) @@ -0,0 +1,141 @@ +/* pcb-mincut, a prototype project demonstrating how to highlight shorts + * Copyright (C) 2012 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. +*/ + +#include +#include +#include +#include "graph.h" + +/* allow direct use, bypassing safe_fs */ +#undef popen +#undef pclose + +/* allocate a new graph of n nodes with no edges */ +gr_t *gr_alloc(int n) +{ + gr_t *g = malloc(sizeof(gr_t)); + g->n = n; + g->adj = calloc(n * n, sizeof(int)); + return g; +} + +/* create a new graph by cloning graph g */ +gr_t *gr_clone(gr_t *g) +{ + int size = g->n * g->n * sizeof(int); + gr_t *o = malloc(sizeof(gr_t)); + + o->n = g->n; + o->adj = malloc(size); + memcpy(o->adj, g->adj, size); + o->node2name = g->node2name; + return o; +} + +/* free all resouces used by the graph */ +void gr_free(gr_t *g) +{ + free(g->adj); + free(g); +} + +void gr_merge_nodes(gr_t *g, int n1, int n2) +{ + int n; + gr_bound_chk(g, n1, n2); + + for(n = 0; n < g->n; n++) { + if (n != n2) + gr_add_(g, n, n1, gr_set_(g, n, n2, 0)); + else + gr_add_(g, n1, n1, gr_set_(g, n2, n2, 0)/2); + } +} + +void gr_print(gr_t *g, FILE *f, const char *prefix) +{ + int x, y; + + fprintf(f, "%s ", prefix); + for(x = 0; x < g->n; x++) + fprintf(f, "% 4d ", x); + fprintf(f, "\n"); + + for(y = 0; y < g->n; y++) { + fprintf(f, "%s % 4d ", prefix, y); + for(x = 0; x < g->n; x++) + fprintf(f, "% 4d ", gr_get_(g, x, y)); + fprintf(f, "\n"); + } + fprintf(f, "%s\n", prefix); + if (g->node2name != NULL) { + fprintf(f, "%snames:\n", prefix); + for(x = 0; x < g->n; x++) + fprintf(f, "%s % 4d=%s\n", prefix, x, g->node2name[x]); + } +} + +int gr_draw(gr_t *g, const char *name, const char *type) +{ + char *cmd; + FILE *f; + int x, y; + + if (type == NULL) + type = "png"; + + cmd = malloc(strlen(type)*2 + strlen(name) + 64); + sprintf(cmd, "dot -T%s -o %s.%s", type, name, type); + f = popen(cmd, "w"); + if (f == NULL) + return -1; + + fprintf(f, "graph %s {\n", name); + + if (g->node2name != NULL) + for(x = 0; x < g->n; x++) + fprintf(f, "\t% 4d[label=\"%d\\n%s\"]\n", x, x, g->node2name[x] == NULL ? "NULL" : g->node2name[x]); + + for(y = 0; y < g->n; y++) { + for(x = y; x < g->n; x++) { + +#ifdef MULTI_EDGE + int n; + for(n = gr_get_(g, x, y); n > 0; n--) + fprintf(f, "\t% 4d -- % 4d\n", x, y); +#else + if (gr_get_(g, x, y) > 0) + fprintf(f, "\t% 4d -- % 4d [label=\"*%d\"]\n", x, y, gr_get_(g, x, y)); +#endif + } + } + + fprintf(f, "}\n"); + pclose(f); + return 0; +} + +int gr_node_edges(gr_t *g, int node) +{ + int n, sum; + sum = 0; + gr_bound_chk(g, 0, node); + for(n = 0; n < g->n; n++) + sum += gr_get_(g, n, node); + return sum; +} Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/graph.h =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/graph.h (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/graph.h (revision 33253) @@ -0,0 +1,98 @@ +/* pcb-mincut, a prototype project demonstrating how to highlight shorts + * Copyright (C) 2012 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. +*/ + +#ifndef GRAPH_H +#define GRAPH_H +#include +#include +#include "../../../config.h" + +typedef struct gr_s { + int n; /* number of nodes */ + int *adj; /* adjacency matrix of n*n ints */ + char **node2name; /* optional node names */ +} gr_t; + +/* allocate a new graph of n nodes with no edges */ +gr_t *gr_alloc(int n); + +/* create a new graph by cloning graph g */ +gr_t *gr_clone(gr_t *g); + +/* free all resouces used by the graph */ +void gr_free(gr_t *g); + + +RND_INLINE void gr_bound_chk(gr_t *g, int n1, int n2) +{ + assert((n1 >= 0) && (n1 < g->n)); + assert((n2 >= 0) && (n2 < g->n)); +} + +/* return number of edges between nodes n1 and n2 - without checks */ +RND_INLINE int gr_get_(gr_t *g, int n1, int n2) +{ + return g->adj[n1 * g->n + n2]; +} + +/* return number of edges between nodes n1 and n2 - with checks */ +RND_INLINE int gr_get(gr_t *g, int n1, int n2) +{ + gr_bound_chk(g, n1, n2); + return gr_get_(g, n1, n2); +} + +/* return old number of edges between nodes n1 and n2 and change it to newnum - no check*/ +RND_INLINE int gr_set_(gr_t *g, int n1, int n2, int newnum) +{ + int old; + old = g->adj[n1 * g->n + n2]; + g->adj[n1 * g->n + n2] = newnum; + g->adj[n2 * g->n + n1] = newnum; + return old; +} + +/* return old number of edges between nodes n1 and n2 and increase it by newnum - no check*/ +RND_INLINE int gr_add_(gr_t *g, int n1, int n2, int newnum) +{ + int old; + old = g->adj[n1 * g->n + n2]; + g->adj[n1 * g->n + n2] += newnum; + g->adj[n2 * g->n + n1] += newnum; + return old; +} + +/* return old number of edges between nodes n1 and n2 and change it to newnum - check*/ +RND_INLINE int gr_set(gr_t *g, int n1, int n2, int newnum) +{ + gr_bound_chk(g, n1, n2); + return gr_set_(g, n1, n2, newnum); +} + +/* merge two nodes n1 and n2 (contraction) */ +void gr_merge_nodes(gr_t *g, int n1, int n2); + +/* print the connection matrix */ +void gr_print(gr_t *g, FILE *f, const char *prefix); + +/* draw graph using graphviz/dot */ +int gr_draw(gr_t *g, const char *name, const char *type); + +/* return total number of edges of a node */ +int gr_node_edges(gr_t *g, int node); +#endif Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/load.c =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/load.c (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/load.c (revision 33253) @@ -0,0 +1,262 @@ +/* pcb-mincut, a prototype project demonstrating how to highlight shorts + * Copyright (C) 2012 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. +*/ + +#include +#include +#include +#include +#include "genht/htsi.h" +#include "genht/hash.h" +#include "graph.h" +#include + +/*#define DEBUG_GR*/ + +/* maximum number of nodes */ +#define MAXNODES 1024 + +/* maximum length of a name */ +#define NAMELEN 128 + +/* how many edges net nodes are connected with - this would balance + mincut to avoid cutting such connections */ +#define NET_EDGES 8 + +#define isspc(c) (((c) == ' ') || ((c) == '\t')) +#define isid(c) ((((c) >= 'a') && ((c) <= 'z')) || (((c) >= 'A') && ((c) <= 'Z')) || (((c) >= '0') && ((c) <= '9')) || ((c) == '_')) + +htsi_t *name2node = NULL; /* hash for looking up known node name -> node id pairs */ +char *node2name[MAXNODES] = {NULL}; +int num_nodes; + +static unsigned int keyhash(char *key) { + unsigned char *p = (unsigned char *)key; + unsigned int hash = 0; + + while (*p) + hash += (hash << 2) + *p++; + return hash; +} + +gr_t *load(FILE *f) +{ + int lineno; + int nets[2][MAXNODES]; /* nodes in nets */ + int neut[MAXNODES]; /* neutral nodes */ + int nn_net[2]; /* number of nodes in nets */ + int nn_neut; /* number of nodes in nets */ + int nodes_fin; /* 1 after reading the first conn line */ + gr_t *g = NULL; + +/* peek at next char and return if it is a newline */ +#define return_at_eol \ + do { \ + char c; \ + c = fgetc(f); \ + if ((c == '\r') || (c == '\n')) \ + return; \ + ungetc(c, f); \ + } while(0) + + + /* eat up space and tabs */ + void eat_space(void) + { + int c; + do { + c = fgetc(f); + } while(isspc(c)); + ungetc(c, f); + } + + /* load next token of type id */ + const char *token_id(void) + { + static char id[NAMELEN]; + char *s; + int n; + + n = sizeof(id) - 1; + s = id-1; + do { + s++; + *s = fgetc(f); + n--; + if (n <= 0) { + *s = '\0'; + fprintf(stderr, "Error: name too long: %s...\n", id); + } + } while(isid(*s)); + ungetc(*s, f); + *s = '\0'; + return id; + } + + /* read next id token and look it up as a node name; if it does not + exist and alloc is 1, allocate it; if it does not exist and + alloc is 0, abort with error */ + int token_node(int alloc) + { + const char *id = token_id(); + if (htsi_has(name2node, (char *)id)) + return htsi_get(name2node, (char *)id); + if (alloc) { + node2name[num_nodes] = rnd_strdup(id); + htsi_set(name2node, node2name[num_nodes], num_nodes); + return num_nodes++; + } + fprintf(stderr, "Error: unknown node %s\n", id); + abort(); + } + + /* load a net1 or net2 statement */ + void load_net(int net) + { + int node; + if (nodes_fin) { + fprintf(stderr, "Error: net%d after conn\n", net); + abort(); + } + /* load each node and append */ + while(1) { + eat_space(); + return_at_eol; + node = token_node(1); + nets[net][nn_net[net]] = node; + nn_net[net]++; + } + } + + /* load a neut statement */ + void load_neut(void) + { + int node; + if (nodes_fin) { + fprintf(stderr, "Error: neut after conn\n"); + abort(); + } + /* load each node and append */ + while(1) { + eat_space(); + return_at_eol; + node = token_node(1); + neut[nn_neut] = node; + nn_neut++; + } + } + + /* load a list of connections */ + void load_conn(void) + { + int n1, n2; + char c; + + /* if this is the first conn, create the graph */ + if (!nodes_fin) { + g = gr_alloc(num_nodes); + g->node2name = node2name; + } + nodes_fin = 1; + + /* load each n1-n2 pair */ + while(1) { + eat_space(); + return_at_eol; + n1 = token_node(0); + c = fgetc(f); + if (c != '-') { + fprintf(stderr, "Error: expected '-' between nodes in conn list (got '%c' instead)\n", c); + abort(); + } + n2 = token_node(0); + gr_add_(g, n1, n2, 1); + } + } + + name2node = htsi_alloc(keyhash, strkeyeq); + node2name[0] = rnd_strdup("(S)"); htsi_set(name2node, node2name[0], 0); + node2name[1] = rnd_strdup("(T)"); htsi_set(name2node, node2name[1], 1); + num_nodes = 2; + nn_net[0] = 0; + nn_net[1] = 0; + nn_neut = 0; + + nodes_fin = 0; + lineno = 0; + while(!(feof(f))) { + char cmd[6]; + lineno++; + eat_space(); + *cmd = '\0'; + fgets(cmd, 5, f); + if (*cmd == '#') { + char s[1024]; /* will break for comment lines longer than 1k */ + fgets(s, sizeof(s), f); + continue; + } + if ((*cmd == '\n') || (*cmd == '\t') || (*cmd == '\0')) + continue; + if (strcmp(cmd, "net1") == 0) + load_net(0); + else if (strcmp(cmd, "net2") == 0) + load_net(1); + else if (strcmp(cmd, "neut") == 0) + load_neut(); + else if (strcmp(cmd, "conn") == 0) + load_conn(); + } + + +#ifdef DEBUG_GR + gr_print(g, stdout, "(input0) "); + gr_draw(g, "input0", "png"); +#endif + + /* preprocessing nets */ + { + int net, node; + +#if 0 +/* this optimization looked like a good idea but fails for O.in because + it's always cheaper to cut T-> and S-> bounding than anything else */ + /* merge net nodes into (S) and (T) */ + for(net = 0; net < 2; net++) + for(node = 0; node < nn_net[net]; node++) + gr_merge_nodes(g, net, nets[net][node]); + + /* make sure (S) and (T) connections are heavy */ + for(net = 0; net < 2; net++) + for(node = 0; node < g->n; node++) + if (gr_get_(g, net, node)) + gr_add_(g, net, node, NET_EDGES); +#endif + + /* make sure (S) and (T) connections are heavy */ + for(net = 0; net < 2; net++) + for(node = 0; node < nn_net[net]; node++) + gr_add_(g, net, nets[net][node], NET_EDGES); + } + +#ifdef DEBUG_GR + gr_print(g, stdout, "(input1) "); + gr_draw(g, "input1", "png"); +#endif + + return g; +} + Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/load.h =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/load.h (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/load.h (revision 33253) @@ -0,0 +1,5 @@ +#include +#include "graph.h" + +/* load example input from FILE f and return the preprocessed graph */ +gr_t *load(FILE *f); Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/main.c =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/main.c (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/main.c (revision 33253) @@ -0,0 +1,34 @@ +#include +#include +#include +#include "graph.h" +#include "load.h" +#include "solve.h" + +#define strempty(s) ((s) == NULL ? "" : (s)) + +#undef strdup + +char *rnd_strdup(const char *s) { return strdup(s); } +int rnd_rand() { return rand(); } + +int main() +{ + int *best; + gr_t *g; + int n, cancel; + + g = load(stdin); + if (g == NULL) { + fprintf(stderr, "Failed to load input, exiting\n"); + exit(1); + } + best = pcb_mincut_solve(g, NULL, &cancel); + for(n = 0; best[n*2] != -1; n++) + printf("%s-%s\n", strempty(g->node2name[best[n*2+0]]), strempty(g->node2name[best[n*2+1]])); + + gr_free(g); + free(best); + + return 0; +} Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/solve.c =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/solve.c (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/solve.c (revision 33253) @@ -0,0 +1,277 @@ +/* pcb-mincut, a prototype project demonstrating how to highlight shorts + * Copyright (C) 2012 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. +*/ + +#include +#include +#include +#include +#include "solve.h" +#include + +/* Karger's algorithm as described in the wikipedia article + http://en.wikipedia.org/wiki/Karger%27s_algorithm +*/ + +#define BAD 1000000 + +/*#define DEBUG_MERGES*/ +/*#define DEBUG_TAGS*/ +/*#define DEBUG_SOLVE*/ + +typedef struct { + gr_t *g; + int *avail; /* nodes IDs still avaialble for merging */ + int *neigh; /* neighbor list */ + int *tag; + int num_avail; /* number of nodes still avaialble for merging */ +} sstate_t; + +static int pick_del(sstate_t *st) +{ + int idx, ret, size; + idx = rnd_rand() % st->num_avail; + ret = st->avail[idx]; + size = (st->num_avail-idx-1) * sizeof(int); + if (size > 0) + memmove(&st->avail[idx], &st->avail[idx+1], size); + st->num_avail--; + return ret; +} + +static int pick_neigh(sstate_t *st, int node) +{ + int n, num_neigh; + + num_neigh = 0; + for(n = 0; n < st->g->n; n++) { + if ((n != node) && (gr_get_(st->g, n, node) > 0)) { + st->neigh[num_neigh] = n; + num_neigh++; + } + } + if (num_neigh == 0) + return -1; + return st->neigh[rnd_rand() % num_neigh]; +} + +static void retag(sstate_t *st, int from, int to) +{ + int n; + for(n = 0; n < st->g->n; n++) + if (st->tag[n] == from) + st->tag[n] = to; +} + + +/* clone graph and do a randon contraction */ +int solve_(gr_t *g_, int *cuts) +{ + sstate_t st; + int n, result, tags; + static int solution = -1; +#ifdef DEBUG_MERGES + int cnt = 0; + char fn[512]; +#endif + + solution++; + st.g = gr_clone(g_); + st.avail = malloc(sizeof(int) * st.g->n); + st.neigh = malloc(sizeof(int) * st.g->n); + st.tag = malloc(sizeof(int) * st.g->n); + +#define FREE_ALL() \ + gr_free(st.g); \ + free(st.avail); \ + free(st.neigh); \ + free(st.tag); + + for(n = 2; n < st.g->n; n++) + st.tag[n] = -1; + st.tag[0] = 0; + st.tag[1] = 1; + tags = 2; + + st.num_avail = 0; + for(n = 0; n < st.g->n; n++) { + if (gr_node_edges(st.g, n) > 0) { + st.avail[st.num_avail] = n; + st.num_avail++; + } + } + + while(st.num_avail > 2) { + int n1, n2; + n2 = pick_del(&st); + n1 = pick_neigh(&st, n2); + if (n1 < 0) { + FREE_ALL(); + return BAD; + } +#ifndef DEBUG_MERGES +#ifdef DEBUG_SOLVE + printf("Merge %d (%s) into %d (%s)\n", n2, st.g->node2name[n2], n1, st.g->node2name[n1]); +#endif +#endif + assert(n2 != n1); + + /* propagate tags */ + if ((st.tag[n1] != -1) && (st.tag[n2] == -1)) + st.tag[n2] = st.tag[n1]; + else if ((st.tag[n1] == -1) && (st.tag[n2] != -1)) + st.tag[n1] = st.tag[n2]; + else if ((st.tag[n1] == -1) && (st.tag[n2] == -1)) + st.tag[n1] = st.tag[n2] = tags++; + else if ((st.tag[n1] != -1) && (st.tag[n2] != -1)) { + if ((st.tag[n1] > 1) && (st.tag[n2] <= 1)) + retag(&st, st.tag[n1], st.tag[n2]); + else if ((st.tag[n2] > 1) && (st.tag[n1] <= 1)) + retag(&st, st.tag[n2], st.tag[n1]); + else { + /* tag collision means we won't be able to distinguish between our + two groups and our cut won't resolve the short anyway */ +#ifdef DEBUG_TAGS + printf("Tag collision!\n"); +#endif + FREE_ALL(); + return BAD; + } + } + + gr_merge_nodes(st.g, n1, n2); + +#ifdef DEBUG_MERGES + sprintf(fn, "contraction_%02d_%02d", solution, cnt); + cnt++; + gr_draw(st.g, fn, "png"); + printf("Merge %d into %d, result in %s leaving %d available nodes\n", n2, n1, fn, st.num_avail); +#endif + } + +#ifdef DEBUG_SOLVE + { + char fn[128]; + sprintf(fn, "contraction_%02d", solution); + gr_draw(st.g, fn, "png"); + } +#endif + + result = gr_get(st.g, st.avail[0], st.avail[1]); + +#ifdef DEBUG_TAGS + { + int t, n; + printf("Groups:\n"); + for(t = 0; t < 2; t++) { + printf(" [%d] is", t); + for(n = 0; n < st.g->n; n++) { + if (st.tag[n] == t) + printf(" %s", st.g->node2name[n]); + } + printf("\n"); + } + } +#endif + { + int x, y, num_cuts = 0; + for(y = 0; y < st.g->n; y++) + for(x = y+1; x < st.g->n; x++) + if ((gr_get_(g_, x, y) > 0) && (st.tag[x] != st.tag[y])) { +#ifdef DEBUG_TAGS + printf("CUT %s-%s\n", st.g->node2name[x], st.g->node2name[y]); +#endif + cuts[num_cuts*2+0] = x; + cuts[num_cuts*2+1] = y; + num_cuts++; + } + cuts[num_cuts*2+0] = -1; + cuts[num_cuts*2+1] = -1; + } + FREE_ALL(); + return result; +} + +#define strempty(s) ((s) == NULL ? "" : (s)) +int *pcb_mincut_solve(gr_t *g, int (*progress)(long so_far, long total, const char *msg), int *cancel) +{ + int n, best, res, till, cuts_size, have_progress = 0; + double nd; + int *cuts, *best_cuts; + time_t currt, nextt; + + /* count how many nodes we really have - the ones not cut down from the graph by the preprocessor */ + nd = 0; + for(n = 0; n < g->n; n++) + if (gr_node_edges(g, n) > 0) + nd++; + + till = (int)(nd * (nd-1.0) / 2.0 * log(nd))+1; +#ifdef DEBUG_SOLVE + printf("Running solver at most %d times for %d relevant nodes\n", till, (int)nd); +#endif + + cuts_size = ((nd * nd) + 1) * sizeof(int); + cuts = malloc(cuts_size); + best_cuts = malloc(cuts_size); + + best = BAD; + nextt = time(NULL)+2; + for(n = 0; n < till; n++) { + if ((progress != NULL) && ((n % 128) == 0)) { + currt = time(NULL); + if (currt >= nextt) { + have_progress = 1; + if (progress(n, till, "Optimizing shortcircuit indication\nusing mincut... Press cancel\nto get a dumb indication")) { + *cancel = 1; + break; + } + nextt = currt+1; + } + } + res = solve_(g, cuts); +#ifdef DEBUG_SOLVE + printf("solution %d=%d\n", n, res); +#endif + if (res < best) { + best = res; + memcpy(best_cuts, cuts, cuts_size); + } + if (best == 1) /* we won't find a better solution ever */ + break; + } + + if (have_progress) + progress(0, 0, NULL); + +#ifdef DEBUG_SOLVE + printf("Best solution cuts %d edge%s:", best, best == 1 ? "" : "s"); + for(n = 0; best_cuts[n*2] != -1; n++) { + printf(" %d:%s-%d:%s", best_cuts[n*2+0], strempty(g->node2name[best_cuts[n*2+0]]), best_cuts[n*2+1], strempty(g->node2name[best_cuts[n*2+1]])); + } + printf("\n"); +#endif + if (best == BAD) { + free(best_cuts); + free(cuts); + return NULL; + } + free(cuts); + return best_cuts; +} + + Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/solve.h =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/solve.h (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/solve.h (revision 33253) @@ -0,0 +1,5 @@ +#include "graph.h" + +/* returns a list of object ID pairs (each nth and n+1th element) terminated + by a -1;-1. Cutting these vertices would separate g. */ +int *pcb_mincut_solve(gr_t *g, int (*progress)(long so_far, long total, const char *msg), int *cancel); Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/C.in =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/C.in (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/C.in (revision 33253) @@ -0,0 +1,9 @@ +# a---b +# | +# C---D + +net1 a b +net2 C D +conn a-b C-D +conn a-C + Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/C.ref =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/C.ref (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/C.ref (revision 33253) @@ -0,0 +1 @@ +C-a Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H.in =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H.in (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H.in (revision 33253) @@ -0,0 +1,8 @@ +# a-1-b +# | +# C-2-D + +net1 a b +net2 C D +neut 1 2 +conn C-2 D-2 a-1 b-1 1-2 Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H.ref =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H.ref (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H.ref (revision 33253) @@ -0,0 +1 @@ +2-1 Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H2.in =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H2.in (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H2.in (revision 33253) @@ -0,0 +1,16 @@ +# a-1-2-3-4-5-b +# | +# 6 +# | +# 7 +# | +# C-8-9-10-11-D + +net1 a b +net2 C D +neut 1 2 3 4 5 6 7 8 9 10 11 +conn a-1 1-2 2-3 3-4 4-5 5-b +conn C-8 8-9 9-10 10-11 11-D +conn 3-6 6-7 7-10 + + Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H2.ref =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H2.ref (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H2.ref (revision 33253) @@ -0,0 +1 @@ +7-6 Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H3.in =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H3.in (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H3.in (revision 33253) @@ -0,0 +1,18 @@ +# a-1-2-3-4-5-b +# | +# 6-+ +# | | +# 7-+ +# |/ +# C-8-9-10-11-D + +net1 a b +net2 C D +neut 1 2 3 4 5 6 7 8 9 10 11 +conn a-1 1-2 2-3 3-4 4-5 5-b +conn C-8 8-9 9-10 10-11 11-D +conn 3-6 6-7 7-10 + +#redundancy - cut 3-6 is the best: +conn 6-7 7-10 + Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H3.ref =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H3.ref (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H3.ref (revision 33253) @@ -0,0 +1 @@ +6-3 Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H4.in =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H4.in (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H4.in (revision 33253) @@ -0,0 +1,12 @@ +# a b +# | | +# 1---2 +# | | +# C D + +net1 a b +net2 C D +neut 1 2 +conn a-1 b-2 +conn C-1 D-2 +conn 1-2 Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H4.ref =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H4.ref (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/H4.ref (revision 33253) @@ -0,0 +1,2 @@ +1-C +2-D Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/Makefile =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/Makefile (revision 33253) @@ -0,0 +1,12 @@ +TESTS = C.diff H.diff H2.diff H3.diff H4.diff O.diff \ + rats1.diff rats2.diff rats3.diff + +all: $(TESTS) + +.SUFFIXES: .in .out .diff .ref + +.out.diff: + @diff -u $*.out $*.ref + +.in.out: + @../main < $*.in >$*.out Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/O.in =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/O.in (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/O.in (revision 33253) @@ -0,0 +1,9 @@ +# a---b +# | | +# C---D + +net1 a b +net2 C D +conn a-b C-D +conn a-C b-D + Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/O.ref =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/O.ref (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/O.ref (revision 33253) @@ -0,0 +1,2 @@ +C-a +D-b Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats1.in =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats1.in (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats1.in (revision 33253) @@ -0,0 +1,12 @@ +# a b +# | | +# 1 2 +# | | +# C D + +net1 a b +net2 C D +neut 1 2 +conn a-1 b-2 +conn C-1 D-2 + Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats1.ref =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats1.ref (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats1.ref (revision 33253) @@ -0,0 +1,2 @@ +1-C +2-D Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats2.in =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats2.in (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats2.in (revision 33253) @@ -0,0 +1,8 @@ +# a---C---b---D + +net1 a b +net2 C D +conn a-C C-b b-D + + + Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats2.ref =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats2.ref (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats2.ref (revision 33253) @@ -0,0 +1,3 @@ +C-a +C-b +D-b Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats3.in =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats3.in (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats3.in (revision 33253) @@ -0,0 +1,9 @@ +# C---a---b---D + +net1 a b +net2 C D +conn C-a a-b b-D + + + + Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats3.ref =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats3.ref (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/rats3.ref (revision 33253) @@ -0,0 +1,2 @@ +C-a +D-b Index: tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/redundant.in =================================================================== --- tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/redundant.in (nonexistent) +++ tags/2.3.0/src_plugins/mincut/pcb-mincut/test_cases/redundant.in (revision 33253) @@ -0,0 +1,20 @@ +# 12----13---14 +# | | +# a-1-2-3-4-5-b +# | +# 6-+ +# | | +# 7-+ +# | +# C-8-9-10-11-D + +net1 a b +net2 C D +neut 1 2 3 4 5 6 7 8 9 10 11 12 13 14 +conn a-1 1-2 2-3 3-4 4-5 5-b +conn C-8 8-9 9-10 10-11 11-D +conn 3-6 6-7 7-10 +conn a-12 12-13 13-14 14-b +conn 6-7 + + Index: tags/2.3.0/src_plugins/mincut/rats_mincut.c =================================================================== --- tags/2.3.0/src_plugins/mincut/rats_mincut.c (nonexistent) +++ tags/2.3.0/src_plugins/mincut/rats_mincut.c (revision 33253) @@ -0,0 +1,380 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2013..2015,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "draw.h" +#include +#include "event.h" +#include "plug_io.h" +#include "find.h" +#include "polygon.h" +#include "search.h" +#include "undo.h" +#include +#include "netlist.h" +#include +#include "obj_common.h" +#include "obj_subc_parent.h" + +#include "pcb-mincut/graph.h" +#include "pcb-mincut/solve.h" + +#include +#include "rats_mincut_conf.h" +conf_mincut_t conf_mincut; + +static const char *pcb_mincut_cookie = "mincut"; + +/* define to 1 to enable debug prints */ +#if 0 +# define debprintf pcb_trace +#else + static void debprintf(const char *fmt, ...) {} +#endif + +typedef struct short_conn_s short_conn_t; +struct short_conn_s { + int gid; /* id in the graph */ + int from_type; + int from_id; + int to_type; + int edges; /* number of edges */ + pcb_any_obj_t *to; + pcb_found_conn_type_t type; + short_conn_t *next; +}; + +typedef struct { + short_conn_t *short_conns; + int num_short_conns; + int short_conns_maxid; +} shctx_t; + +static int proc_short_cb(pcb_find_t *fctx, pcb_any_obj_t *curr, pcb_any_obj_t *from, pcb_found_conn_type_t type) +{ + short_conn_t *s; + shctx_t *shctx = fctx->user_data; + + s = malloc(sizeof(short_conn_t)); + if (from != NULL) { + s->from_type = from->type; + s->from_id = from->ID; + } + else { + s->from_type = 0; + s->from_id = -1; + } + s->to_type = curr->type; + s->to = curr; + s->type = type; + s->edges = 0; + s->next = shctx->short_conns; + shctx->short_conns = s; + if (curr->ID > shctx->short_conns_maxid) + shctx->short_conns_maxid = curr->ID; + shctx->num_short_conns++; + + debprintf(" found %d %d/%p type=%d from %d\n", curr->type, curr->ID, (void *)curr, s->type, from == NULL ? -1 : from->ID); + return 0; +} + +/* returns 0 on succes */ +static int proc_short(pcb_any_obj_t *term, pcb_net_t *Snet, pcb_net_t *Tnet, int *cancel) +{ + rnd_coord_t x, y; + short_conn_t *n, **lut_by_oid, **lut_by_gid, *next; + int gids; + gr_t *g; + void *S, *T; + int *solution; + int i, maxedges, nonterms = 0; + int bad_gr = 0; + pcb_find_t fctx; + shctx_t shctx; + + pcb_obj_center(term, &x, &y); + debprintf("short on terminal\n"); + + /* perform a search calling back proc_short_cb() with the connections */ + memset(&shctx, 0, sizeof(shctx)); + memset(&fctx, 0, sizeof(fctx)); + fctx.found_cb = proc_short_cb; + fctx.user_data = &shctx; + pcb_find_from_obj(&fctx, PCB->Data, term); + pcb_find_free(&fctx); + + + debprintf("- alloced for %d\n", (shctx.short_conns_maxid + 1)); + lut_by_oid = calloc(sizeof(short_conn_t *), (shctx.short_conns_maxid + 1)); + lut_by_gid = calloc(sizeof(short_conn_t *), (shctx.num_short_conns + 3)); + + g = gr_alloc(shctx.num_short_conns + 2); + + g->node2name = calloc(sizeof(char *), (shctx.num_short_conns + 2)); + + /* conn 0 is S and conn 1 is T and set up lookup arrays */ + for (n = shctx.short_conns, gids = 2; n != NULL; n = n->next, gids++) { + char *s; + const char *typ; + pcb_subc_t *parent; + pcb_any_obj_t *o = (pcb_any_obj_t *)n->to; + + n->gid = gids; + debprintf(" {%d} found %d %d/%p type=%d from %d\n", n->gid, n->to_type, n->to->ID, (void *)n->to, n->type, n->from_id); + lut_by_oid[n->to->ID] = n; + lut_by_gid[n->gid] = n; + + parent = NULL; + switch (n->to_type) { + case PCB_OBJ_LINE: typ = "line"; parent = pcb_lobj_parent_subc(o->parent_type, &o->parent); break; + case PCB_OBJ_ARC: typ = "arc"; parent = pcb_lobj_parent_subc(o->parent_type, &o->parent); break; + case PCB_OBJ_POLY: typ = "polygon"; parent = pcb_lobj_parent_subc(o->parent_type, &o->parent); break; + case PCB_OBJ_TEXT: typ = "text"; parent = pcb_lobj_parent_subc(o->parent_type, &o->parent); break; + case PCB_OBJ_PSTK: typ = "padstack"; parent = pcb_gobj_parent_subc(o->parent_type, &o->parent); break; + case PCB_OBJ_SUBC: typ = "subcircuit"; parent = pcb_gobj_parent_subc(o->parent_type, &o->parent); break; + default: typ = ""; parent = NULL; break; + } + if (parent != NULL) { + if (parent->refdes == NULL) + s = rnd_strdup_printf("%s #%ld \\nof #%ld", typ, n->to->ID, parent->ID); + else + s = rnd_strdup_printf("%s #%ld \\nof %s", typ, n->to->ID, parent->refdes); + } + else + s = rnd_strdup_printf("%s #%ld", typ, n->to->ID); + + g->node2name[n->gid] = s; + if ((o->term == NULL) && (o->type != PCB_OBJ_RAT)) + nonterms++; + } + + /* Shortcut: do not even attempt to do the mincut if there are no objects + between S and T that could be cut. This is a typical case when a lot of + parts are thrown on the board with overlapping terminals after an initial + import sch. */ + if (nonterms < 1) + bad_gr = 1; + + g->node2name[0] = rnd_strdup("S"); + g->node2name[1] = rnd_strdup("T"); + + /* calculate how many edges each node has and the max edge count */ + maxedges = 0; + for (n = shctx.short_conns; n != NULL; n = n->next) { + short_conn_t *from; + + n->edges++; + if (n->edges > maxedges) + maxedges = n->edges; + + if (n->from_id >= 0) { + from = lut_by_oid[n->from_id]; + if (from == NULL) { + /* no from means broken graph (multiple components) */ + if (n->from_id >= 2) { /* ID 0 and 1 are start/stop, there won't be from for them */ + fprintf(stderr, "rats_mincut.c error: graph has multiple components, bug in find.c (n->from_id=%d)!\n", n->from_id); + bad_gr = 1; + } + continue; + } + from->edges++; + if (from->edges > maxedges) + maxedges = from->edges; + } + } + + S = NULL; + T = NULL; + + if (Snet != NULL) { + S = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], Snet->name, 0); + assert(S != NULL); + } + if (Tnet != NULL) { + T = pcb_net_get(PCB, &PCB->netlist[PCB_NETLIST_EDITED], Tnet->name, 0); + assert(T != NULL); + } + + for (n = shctx.short_conns; n != NULL; n = n->next) { + pcb_any_obj_t *o = (pcb_any_obj_t *)n->to; + if (o->term != NULL) { + pcb_subc_t *sc = pcb_obj_parent_subc(o); + if ((sc != NULL) && !PCB_FLAG_TEST(PCB_FLAG_NONETLIST, sc)) { + if ((sc->refdes != NULL) && (o->term != NULL)) { + pcb_net_term_t *t = pcb_net_find_by_refdes_term(&PCB->netlist[PCB_NETLIST_EDITED], sc->refdes, o->term); + if (t != NULL) { + if (t->parent.net == Snet) + gr_add_(g, n->gid, 0, 100000); + else if (t->parent.net == Tnet) + gr_add_(g, n->gid, 1, 100000); + } + } + else + rnd_message(RND_MSG_WARNING, "Ignoring subcircuit %ld connecting to a net because it has no refdes;\nplease use the nonetlist flag on the subcircuit to suppress this warning\n", sc->ID); + } + } + + /* if we have a from object, look it up and make a connection between the two gids */ + if (n->from_id >= 0) { + int weight; + short_conn_t *from = lut_by_oid[n->from_id]; + + from = lut_by_oid[n->from_id]; + /* weight: 1 for connections we can break, large value for connections we shall not break */ + if ((n->type == PCB_FCT_COPPER) || (n->type == PCB_FCT_START)) { + /* connection to a pin/pad is slightly stronger than the + strongest obj-obj conn; obj-obj conns are weaker at junctions where many + objects connect */ + if ((n->from_type == PCB_OBJ_PSTK) || (n->to_type == PCB_OBJ_PSTK)) + weight = maxedges * 2 + 2; + else + weight = maxedges * 2 - n->edges - from->edges + 1; + } + else + weight = 10000; + if (from != NULL) { + gr_add_(g, n->gid, from->gid, weight); + debprintf(" CONN %d %d\n", n->gid, from->gid); + } + } + } + +/*#define MINCUT_DRAW*/ +#ifdef MINCUT_DRAW + { + static int drw = 0; + char gfn[256]; + drw++; + sprintf(gfn, "A_%d_a", drw); + debprintf("gfn=%s\n", gfn); + gr_draw(g, gfn, "png"); + } +#endif + + if (!bad_gr) { + solution = pcb_mincut_solve(g, rnd_hid_progress, cancel); + if (cancel) + return 1; + + if (solution != NULL) { + debprintf("Would cut:\n"); + for (i = 0; solution[i] != -1; i++) { + short_conn_t *s; + debprintf("%d:", i); + s = lut_by_gid[solution[i]]; + debprintf("%d %p", solution[i], (void *)s); + if (s != NULL) { + PCB_FLAG_SET(PCB_FLAG_WARN, s->to); + debprintf(" -> %d", s->to->ID); + } + debprintf("\n"); + } + + free(solution); + } + else { + fprintf(stderr, "mincut didn't find a solution, falling back to the old warn\n"); + bad_gr = 1; + } + } + free(lut_by_oid); + free(lut_by_gid); + + for (n = shctx.short_conns; n != NULL; n = next) { + next = n->next; + free(n); + } + + for(i = 0; i < g->n; i++) + free(g->node2name[i]); + free(g->node2name); + gr_free(g); + + return bad_gr; +} + +static void pcb_mincut_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + int *handled, *cancel; + pcb_any_obj_t *term; + pcb_net_t *Snet, *Tnet; + + if (!conf_mincut.plugins.mincut.enable) + return; + + if (argc < 5) + return; + + if ((argv[4].type != RND_EVARG_PTR) || (argv[5].type != RND_EVARG_PTR)) + return; + handled = (int *)argv[4].d.p; + cancel = (int *)argv[5].d.p; + if (*handled || *cancel) + return; + + if (argv[2].type != RND_EVARG_PTR) + return; + term = (pcb_any_obj_t *)argv[2].d.p; + + if (argv[1].type != RND_EVARG_PTR) + return; + Snet = (pcb_net_t *)argv[1].d.p; + + if (argv[3].type != RND_EVARG_PTR) + return; + Tnet = (pcb_net_t *)argv[3].d.p; + + if (proc_short(term, Snet, Tnet, cancel) == 0) + *handled = 1; +} + + +int pplg_check_ver_mincut(int ver_needed) { return 0; } + +void pplg_uninit_mincut(void) +{ + rnd_conf_unreg_fields("plugins/mincut/"); + rnd_event_unbind_allcookie(pcb_mincut_cookie); +} + +int pplg_init_mincut(void) +{ + RND_API_CHK_VER; + + rnd_event_bind(PCB_EVENT_NET_INDICATE_SHORT, pcb_mincut_ev, NULL, pcb_mincut_cookie); + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_mincut, field,isarray,type_name,cpath,cname,desc,flags); +#include "rats_mincut_conf_fields.h" + return 0; +} Index: tags/2.3.0/src_plugins/mincut/rats_mincut_conf.h =================================================================== --- tags/2.3.0/src_plugins/mincut/rats_mincut_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/mincut/rats_mincut_conf.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_MINCUT_CONF_H +#define PCB_MINCUT_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN enable; /* Enable calculating mincut on shorts (rats_mincut.c) when non-zero */ + } mincut; + } plugins; +} conf_mincut_t; + +#endif Index: tags/2.3.0/src_plugins/oldactions/Makefile =================================================================== --- tags/2.3.0/src_plugins/oldactions/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/oldactions/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_oldactions + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/oldactions/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/oldactions/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/oldactions/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {oldactions} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/oldactions/oldactions.o @] + +switch /local/pcb/oldactions/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/oldactions/oldactions.c =================================================================== --- tags/2.3.0/src_plugins/oldactions/oldactions.c (nonexistent) +++ tags/2.3.0/src_plugins/oldactions/oldactions.c (revision 33253) @@ -0,0 +1,586 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" +#include +#include "data.h" +#include "event.h" +#include "change.h" +#include +#include "undo.h" +#include +#include +#include "plug_footprint.h" +#include "obj_subc.h" +#include +#include "netlist.h" +#include "funchash_core.h" +#include "search.h" + +static void conf_toggle(rnd_conf_role_t role, const char *path) +{ + rnd_conf_native_t *n = rnd_conf_get_field(path); + if (n == NULL) { + rnd_message(RND_MSG_ERROR, "Error: can't find config node %s to toggle\n", path); + return; + } + if (n->type != RND_CFN_BOOLEAN) { + rnd_message(RND_MSG_ERROR, "Error: config node %s is not a boolean, can't toggle\n", path); + return; + } + + rnd_conf_set(role, path, -1, n->val.boolean[0] ? "0" : "1", RND_POL_OVERWRITE); +} + +static const char pcb_acts_DumpLibrary[] = "DumpLibrary()"; +static const char pcb_acth_DumpLibrary[] = "Display the entire contents of the libraries."; +static void ind(int level) +{ + static char inds[] = " "; + + if (level > sizeof(inds)-1) + return; + inds[level] = '\0'; + printf("%s", inds); + inds[level] = ' '; +} + +static void dump_lib_any(int level, pcb_fplibrary_t *l); + +static void dump_lib_dir(int level, pcb_fplibrary_t *l) +{ + rnd_cardinal_t n; + + ind(level); + printf("%s/\n", l->name); + for(n = 0; n < vtlib_len(&l->data.dir.children); n++) + dump_lib_any(level+1, l->data.dir.children.array+n); +} + +static void dump_lib_fp(int level, pcb_fplibrary_t *l) +{ + ind(level); + printf("%s", l->name); + switch(l->data.fp.type) { + case PCB_FP_INVALID: printf(" type(INVALID)"); break; + case PCB_FP_DIR: printf(" type(DIR)"); break; + case PCB_FP_FILEDIR: printf(" type(FILEDIR)"); break; + case PCB_FP_FILE: printf(" type(file)"); break; + case PCB_FP_PARAMETRIC: printf(" type(parametric)"); break; + } + printf(" loc_info(%s)\n", l->data.fp.loc_info); +} + +static void dump_lib_any(int level, pcb_fplibrary_t *l) +{ + switch(l->type) { + case PCB_LIB_INVALID: printf("??\n"); break; + case PCB_LIB_DIR: dump_lib_dir(level, l); break; + case PCB_LIB_FOOTPRINT: dump_lib_fp(level, l); break; + } +} + + +static fgw_error_t pcb_act_DumpLibrary(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + dump_lib_any(0, &pcb_library); + + RND_ACT_IRES(0); + return 0; +} + +/* --------------------------------------------------------------------------- + * no operation, just for testing purposes + * syntax: Bell(volume) + */ +static const char pcb_acts_Bell[] = "Bell()"; + +static const char pcb_acth_Bell[] = "Attempt to produce audible notification (e.g. beep the speaker)."; + +static fgw_error_t pcb_act_Bell(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_gui->beep(rnd_gui); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_debug[] = "Debug(...)"; +static const char pcb_acth_debug[] = "Debug action."; +/* This action exists to help debug scripts; it simply prints all its arguments to stdout. */ + +static const char pcb_acts_debugxy[] = "DebugXY(...)"; +static const char pcb_acth_debugxy[] = "Debug action, with coordinates"; +/* Like @code{Debug}, but requires a coordinate. If the user hasn't yet indicated a location on the board, the user will be prompted to click on one. */ + +static fgw_error_t pcb_act_Debug(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_coord_t x, y; + int i; + printf("Debug:"); + for (i = 1; i < argc; i++) { + const char *s; + RND_ACT_CONVARG(i, FGW_STR, debugxy, s = argv[i].val.str); + printf(" [%d] `%s'", i, s); + } + rnd_hid_get_coords("Click X,Y for Debug", &x, &y, 0); + rnd_printf(" x,y %$mD\n", x, y); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_djopt_sao[] = "OptAutoOnly()"; +static const char pcb_acth_djopt_sao[] = "Toggles the optimize-only-autorouted flag."; +/* +The original purpose of the trace optimizer was to clean up the traces +created by the various autorouters that have been used with PCB. When +a board has a mix of autorouted and carefully hand-routed traces, you +don't normally want the optimizer to move your hand-routed traces. +But, sometimes you do. By default, the optimizer only optimizes +autorouted traces. This action toggles that setting, so that you can +optimize hand-routed traces also. +*/ +fgw_error_t pcb_act_djopt_set_auto_only(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + conf_toggle(RND_CFR_DESIGN, "plugins/djopt/auto_only"); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_toggle_vendor[] = "ToggleVendor()"; +static const char pcb_acth_toggle_vendor[] = "Toggles the state of automatic drill size mapping."; +/* +@cindex vendor map +@cindex vendor drill table +@findex ToggleVendor() + +When drill mapping is enabled, new instances of pins and vias will +have their drill holes mapped to one of the allowed drill sizes +specified in the currently loaded vendor drill table. To enable drill +mapping, a vendor lihata file containing a drill table must be +loaded first. +*/ +fgw_error_t pcb_act_ToggleVendor(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + conf_toggle(RND_CFR_DESIGN, "plugins/vendor/enable"); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_enable_vendor[] = "EnableVendor()"; +static const char pcb_acth_enable_vendor[] = "Enables automatic drill size mapping."; +/* +@cindex vendor map +@cindex vendor drill table +@findex EnableVendor() +When drill mapping is enabled, new instances of pins and vias will +have their drill holes mapped to one of the allowed drill sizes +specified in the currently loaded vendor drill table. To enable drill +mapping, a vendor lihata file containing a drill table must be +loaded first. +*/ +fgw_error_t pcb_act_EnableVendor(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_conf_set(RND_CFR_DESIGN, "plugins/vendor/enable", -1, "1", RND_POL_OVERWRITE); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_disable_vendor[] = "DisableVendor()"; +static const char pcb_acth_disable_vendor[] = "Disables automatic drill size mapping."; +/* +@cindex vendor map +@cindex vendor drill table +@findex DisableVendor() +When drill mapping is enabled, new instances of pins and vias will +have their drill holes mapped to one of the allowed drill sizes +specified in the currently loaded vendor drill table. +*/ +fgw_error_t pcb_act_DisableVendor(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_conf_set(RND_CFR_DESIGN, "plugins/vendor/enable", -1, "0", RND_POL_OVERWRITE); + RND_ACT_IRES(0); + return 0; +} + +fgw_error_t pcb_act_ListRotations(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + PCB_SUBC_LOOP(PCB->Data); + { + double rot; + const char *refdes = RND_UNKNOWN(subc->refdes); + if (pcb_subc_get_rotation(subc, &rot) == 0) + rnd_message(RND_MSG_INFO, "%f %s\n", rot, refdes); + else + rnd_message(RND_MSG_INFO, " %s\n", refdes); + } + PCB_END_LOOP; + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_PCBChanged[] = "PCBChanged([revert])"; +static const char pcb_acth_PCBChanged[] = + "Tells the GUI that the whole PCB has changed. The optional \"revert\"" + "parameter can be used as a hint to the GUI that the same design is being" + "reloaded, and that it might keep some viewport settings"; +static fgw_error_t pcb_act_PCBChanged(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *rv = NULL; + RND_ACT_IRES(0); + RND_ACT_MAY_CONVARG(1, FGW_STR, PCBChanged, rv = argv[1].val.str); + pcb_board_changed((rv != NULL) && (rnd_strcasecmp(rv, "revert") == 0)); + return 0; +} + +static const char pcb_acts_NetlistChanged[] = "NetlistChanged()"; +static const char pcb_acth_NetlistChanged[] = "Tells the GUI that the netlist has changed."; +static fgw_error_t pcb_act_NetlistChanged(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_netlist_changed(0); + return 0; +} + + +static const char pcb_acts_RouteStylesChanged[] = "RouteStylesChanged()"; +static const char pcb_acth_RouteStylesChanged[] = "Tells the GUI that the routing styles have changed."; +static fgw_error_t pcb_act_RouteStylesChanged(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_event(&PCB->hidlib, PCB_EVENT_ROUTE_STYLES_CHANGED, NULL); + return 0; +} + +static const char pcb_acts_LibraryChanged[] = "LibraryChanged()"; +static const char pcb_acth_LibraryChanged[] = "Tells the GUI that the libraries have changed."; +static fgw_error_t pcb_act_LibraryChanged(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_event(&PCB->hidlib, PCB_EVENT_LIBRARY_CHANGED, NULL); + return 0; +} + +static const char pcb_acts_ImportGUI[] = "ImportGUI()"; +static const char pcb_acth_ImportGUI[] = "Asks user which schematics to import into PCB.\n"; +/* DOC: importgui.html */ +static fgw_error_t pcb_act_ImportGUI(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "The ImportGUI() action is deprecated. Using ImportSch() instead.\nFor details see: http://repo.hu/projects/pcb-rnd/help/err0002.html\n"); + RND_ACT_IRES(rnd_actionva(RND_ACT_HIDLIB, "ImportSch", NULL)); + return 0; +} + +static const char pcb_acts_Import[] = + "Import()\n" + "Import([gnetlist|make[,source,source,...]])\n" + "Import(setnewpoint[,(mark|center|X,Y)])\n" + "Import(setdisperse,D,units)\n"; +static const char pcb_acth_Import[] = "Import schematics."; +/* DOC: import.html */ +static fgw_error_t pcb_act_Import(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "Import() is the old, deprecated import netlist/schematics action that got removed\nPlease switch over to using the new action, ImportSch().\nFor details see: http://repo.hu/projects/pcb-rnd/help/err0002.html\n"); + RND_ACT_IRES(1); + return 0; +} + +/*** deprecated ***/ + +static fgw_error_t pcb_act_ToggleHideName(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "ToggleHideName: deprecated feature removed with subcircuits; just delete\nthe text object if it should not be on the silk of the final board.\n"); + return 1; +} + +static fgw_error_t pcb_act_MinMaskGap(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "MinMaskGap: deprecated feature; use padstackedit() instead\n"); + return 1; +} + +static fgw_error_t pcb_act_ChangeHole(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "ChangeHole: deprecated feature; use padstackedit() instead\n"); + return 1; +} + +static fgw_error_t pcb_act_ChangePaste(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "ChangePaste: deprecated feature; use padstackedit() instead\n"); + return 1; +} + +static fgw_error_t pcb_act_ChangeSquare(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "ChangeSquare: deprecated feature; use padstackedit() instead\n"); + return 1; +} + +static fgw_error_t pcb_act_SetSquare(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "SetSquare: deprecated feature; use padstackedit() instead\n"); + return 1; +} + +static fgw_error_t pcb_act_ClearSquare(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "ClearSquare: deprecated feature; use padstackedit() instead\n"); + return 1; +} + +static fgw_error_t pcb_act_ChangeOctagon(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "ChangeOctagon: deprecated feature; use padstackedit() instead\n"); + return 1; +} + +static fgw_error_t pcb_act_SetOctagon(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "SetOctagon: deprecated feature; use padstackedit() instead\n"); + return 1; +} + +static fgw_error_t pcb_act_ClearOctagon(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_ERROR, "ClearOctagon: deprecated feature; use padstackedit() instead\n"); + return 1; +} + +static const char pcb_acts_MinClearGap[] = "MinClearGap(delta)\n" "MinClearGap(Selected, delta)"; +static const char pcb_acth_MinClearGap[] = "Ensures that polygons are a minimum distance from objects."; +static void minclr(pcb_data_t *data, rnd_coord_t value, int flags) +{ + PCB_SUBC_LOOP(data); + { + if (!PCB_FLAGS_TEST(flags, subc)) + continue; + minclr(subc->data, value, 0); + } + PCB_END_LOOP; + + PCB_PADSTACK_LOOP(data); + { + if (!PCB_FLAGS_TEST(flags, padstack)) + continue; + if (padstack->Clearance < value) { + pcb_chg_obj_clear_size(PCB_OBJ_PSTK, padstack, 0, 0, value, 1); + pcb_undo_restore_serial(); + } + } + PCB_END_LOOP; + + PCB_LINE_ALL_LOOP(data); + { + if (!PCB_FLAGS_TEST(flags, line)) + continue; + if ((line->Clearance != 0) && (line->Clearance < value)) { + pcb_chg_obj_clear_size(PCB_OBJ_LINE, layer, line, 0, value, 1); + pcb_undo_restore_serial(); + } + } + PCB_ENDALL_LOOP; + PCB_ARC_ALL_LOOP(data); + { + if (!PCB_FLAGS_TEST(flags, arc)) + continue; + if ((arc->Clearance != 0) && (arc->Clearance < value)) { + pcb_chg_obj_clear_size(PCB_OBJ_ARC, layer, arc, 0, value, 1); + pcb_undo_restore_serial(); + } + } + PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(data); + { + if (!PCB_FLAGS_TEST(flags, polygon)) + continue; + if ((polygon->Clearance != 0) && (polygon->Clearance < value)) { + pcb_chg_obj_clear_size(PCB_OBJ_POLY, layer, polygon, 0, value, 1); + pcb_undo_restore_serial(); + } + } + PCB_ENDALL_LOOP; +} + +static fgw_error_t pcb_act_MinClearGap(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *function; + const char *delta = NULL; + const char *units = NULL; + rnd_bool absolute; + rnd_coord_t value; + int flags; + + RND_ACT_CONVARG(1, FGW_STR, MinClearGap, function = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, MinClearGap, delta = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, MinClearGap, delta = argv[3].val.str); + + if (rnd_strcasecmp(function, "Selected") == 0) + flags = PCB_FLAG_SELECTED; + else { + units = delta; + delta = function; + flags = 0; + } + value = 2 * rnd_get_value(delta, units, &absolute, NULL); + + pcb_undo_save_serial(); + minclr(pcb->Data, value, flags); + pcb_undo_restore_serial(); + pcb_undo_inc_serial(); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_Attributes[] = "Attributes(Layout|Layer|Element|Subc)\n" "Attributes(Layer,layername)"; +static const char pcb_acth_Attributes[] = + "Let the user edit the attributes of the layout, current or given\n" + "layer, or selected subcircuit."; +/* DOC: attributes.html */ +static fgw_error_t pcb_act_Attributes(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + int id; + const char *layername = NULL; + + RND_ACT_CONVARG(1, FGW_KEYWORD, Attributes, id = fgw_keyword(&argv[1])); + RND_ACT_MAY_CONVARG(2, FGW_STR, Attributes, layername = argv[2].val.str); + RND_ACT_IRES(0); + + switch(id) { + case F_Layout: + rnd_actionl("propedit", "board", NULL); + break; + + case F_Layer: + if (layername != NULL) { + char *tmp = rnd_concat("layer:", layername, NULL); + rnd_actionl("propedit", tmp, NULL); + free(tmp); + } + else + rnd_actionl("propedit", "layer", NULL); + break; + + case F_Element: + case F_Subc: + { + int n_found = 0; + pcb_subc_t *s = NULL; + PCB_SUBC_LOOP(pcb->Data); + { + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, subc)) { + s = subc; + n_found++; + } + } + PCB_END_LOOP; + if (n_found > 1) { + rnd_message(RND_MSG_ERROR, "Too many subcircuits selected\n"); + return 1; + } + if (n_found == 0) { + rnd_coord_t x, y; + void *ptrtmp; + rnd_hid_get_coords("Click on a subcircuit", &x, &y, 0); + if ((pcb_search_screen(x, y, PCB_OBJ_SUBC, &ptrtmp, &ptrtmp, &ptrtmp)) != PCB_OBJ_VOID) + s = (pcb_subc_t *)ptrtmp; + else { + rnd_message(RND_MSG_ERROR, "No subcircuit found there\n"); + RND_ACT_IRES(-1); + return 0; + } + } + + { + char *tmp = rnd_strdup_printf("object:%ld", s->ID); + rnd_actionl("propedit", tmp, NULL); + free(tmp); + } + + break; + } + + default: + RND_ACT_FAIL(Attributes); + } + + return 0; +} + + + +rnd_action_t oldactions_action_list[] = { + {"DumpLibrary", pcb_act_DumpLibrary, pcb_acth_DumpLibrary, pcb_acts_DumpLibrary}, + {"Bell", pcb_act_Bell, pcb_acth_Bell, pcb_acts_Bell}, + {"Debug", pcb_act_Debug, pcb_acth_debug, pcb_acts_debug}, + {"DebugXY", pcb_act_Debug, pcb_acth_debugxy, pcb_acts_debugxy}, + {"OptAutoOnly", pcb_act_djopt_set_auto_only, pcb_acth_djopt_sao, pcb_acts_djopt_sao}, + {"ToggleVendor", pcb_act_ToggleVendor, pcb_acth_toggle_vendor, pcb_acts_toggle_vendor}, + {"EnableVendor", pcb_act_EnableVendor, pcb_acth_enable_vendor, pcb_acts_enable_vendor}, + {"DisableVendor", pcb_act_DisableVendor, pcb_acth_disable_vendor, pcb_acts_disable_vendor}, + {"ListRotations", pcb_act_ListRotations, 0, 0}, + {"PCBChanged", pcb_act_PCBChanged, pcb_acth_PCBChanged, pcb_acts_PCBChanged}, + {"NetlistChanged", pcb_act_NetlistChanged, pcb_acth_NetlistChanged, pcb_acts_NetlistChanged}, + {"RouteStylesChanged", pcb_act_RouteStylesChanged, pcb_acth_RouteStylesChanged, pcb_acts_RouteStylesChanged}, + {"LibraryChanged", pcb_act_LibraryChanged, pcb_acth_LibraryChanged, pcb_acts_LibraryChanged}, + {"ImportGUI", pcb_act_ImportGUI, pcb_acth_ImportGUI, pcb_acts_ImportGUI}, + {"Import", pcb_act_Import, pcb_acth_Import, pcb_acts_Import}, + {"Attributes", pcb_act_Attributes, pcb_acth_Attributes, pcb_acts_Attributes}, + + /* deprecated actions */ + {"ToggleHideName", pcb_act_ToggleHideName, 0, 0}, + {"MinMaskGap", pcb_act_MinMaskGap, 0, 0}, + {"MinClearGap", pcb_act_MinClearGap, pcb_acth_MinClearGap, pcb_acts_MinClearGap}, + {"ChangeHole", pcb_act_ChangeHole, 0, 0}, + {"ChangePaste", pcb_act_ChangePaste, 0, 0}, + {"ChangeSquare", pcb_act_ChangeSquare, 0, 0}, + {"ChangeOctagon", pcb_act_ChangeOctagon, 0, 0}, + {"ClearSquare", pcb_act_ClearSquare, 0, 0}, + {"ClearOctagon", pcb_act_ClearOctagon, 0, 0}, + {"SetSquare", pcb_act_SetSquare, 0, 0}, + {"SetOctagon", pcb_act_SetOctagon, 0, 0} +}; + +static const char *oldactions_cookie = "oldactions plugin"; + +int pplg_check_ver_oldactions(int ver_needed) { return 0; } + +void pplg_uninit_oldactions(void) +{ + rnd_remove_actions_by_cookie(oldactions_cookie); +} + +int pplg_init_oldactions(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(oldactions_action_list, oldactions_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/oldactions/oldactions.pup =================================================================== --- tags/2.3.0/src_plugins/oldactions/oldactions.pup (nonexistent) +++ tags/2.3.0/src_plugins/oldactions/oldactions.pup (revision 33253) @@ -0,0 +1,6 @@ +$class feature +$short old/obsolete actions +$long Random collection of old/obsolete actions. Bell(): audible feedback, DumpLibrary(): print footprint library on stdout, a set of debug actions useful for writing pcb scripts: Debug(), DebugXY(), Return(). Old plugin actions to toggle or set settings that are now accessible via the unified config system (vendordrill, djopt) +$state works +default disable +autoload 1 Index: tags/2.3.0/src_plugins/order/Makefile =================================================================== --- tags/2.3.0/src_plugins/order/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/order/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_order + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/order/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/order/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/order/Plug.tmpasm (revision 33253) @@ -0,0 +1,15 @@ +put /local/pcb/mod {order} +put /local/pcb/mod/CONF {$(PLUGDIR)/order/order_conf.h} +put /local/pcb/mod/CONFFILE {order.conf} +put /local/pcb/mod/CONFVAR {order_conf_internal} +put /local/pcb/mod/MENUFILE {order-menu.lht} +put /local/pcb/mod/MENUVAR {order_menu} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/order/order.o +@] + +switch /local/pcb/order/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/order/order-menu.lht =================================================================== --- tags/2.3.0/src_plugins/order/order-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/order/order-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@feature_plugins { + li:submenu { + ha:Order PCB = { a={f;x;o}; action=OrderPCB(gui); tip={Order your PCB from a fab\nusing a dialog box} } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/order/order.c =================================================================== --- tags/2.3.0/src_plugins/order/order.c (nonexistent) +++ tags/2.3.0/src_plugins/order/order.c (revision 33253) @@ -0,0 +1,199 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include +#include "board.h" +#include "data.h" +#include +#include +#include +#include +#include +#include "layer.h" +#include +#include "order_conf.h" +#include "../src_plugins/order/conf_internal.c" + +#include "order.h" + +#include "menu_internal.c" + +static const char *order_cookie = "order plugin"; + +conf_order_t conf_order; +#define ORDER_CONF_FN "order.conf" + +vtp0_t pcb_order_imps; + +void pcb_order_reg(const pcb_order_imp_t *imp) +{ + vtp0_append(&pcb_order_imps, (void *)imp); +} + + +#include "order_dlg.c" + +static const char pcb_acts_OrderPCB[] = "orderPCB([gui])"; +static const char pcb_acth_OrderPCB[] = "Order the board from a fab"; +fgw_error_t pcb_act_OrderPCB(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd = "gui"; + + RND_ACT_MAY_CONVARG(1, FGW_STR, OrderPCB, cmd = argv[1].val.str); + + if (strcmp(cmd, "gui") == 0) { + RND_ACT_IRES(order_dialog()); + return 0; + } + + rnd_message(RND_MSG_ERROR, "CLI version of OrderPCB() not yet implemented\n"); + RND_ACT_IRES(-1); + return 0; +} + +static rnd_action_t order_action_list[] = { + {"OrderPCB", pcb_act_OrderPCB, pcb_acth_OrderPCB, pcb_acts_OrderPCB} +}; + +void pcb_order_free_field_data(order_ctx_t *octx, pcb_order_field_t *f) +{ + if (f->enum_vals != NULL) { + char **s; + for(s = f->enum_vals; *s != NULL; s++) + free(s); + free(f->enum_vals); + f->enum_vals = NULL; + } + if (f->val.str != NULL) { + free((char *)f->val.str); + f->val.str = NULL; + } +} + +static void autoload_field_crd(order_ctx_t *octx, pcb_order_field_t *f, rnd_coord_t c) +{ + switch(f->type) { + case RND_HATT_INTEGER: f->val.lng = c; break; + case RND_HATT_COORD: f->val.crd = c; break; + case RND_HATT_STRING: + free((char *)f->val.str); + f->val.str = rnd_strdup_printf("%$mm", c); + break; + default: break; + } +} + +static void autoload_field_lng(order_ctx_t *octx, pcb_order_field_t *f, long l, int roundup) +{ + long tmp, best, diff; + int n, bestn; + char **s; + + switch(f->type) { + case RND_HATT_INTEGER: f->val.lng = l; break; + case RND_HATT_COORD: f->val.crd = RND_MM_TO_COORD(l); break; + case RND_HATT_STRING: + free((char *)f->val.str); + f->val.str = rnd_strdup_printf("%ld", l); + break; + case RND_HATT_ENUM: + bestn = -1; + /* find the closest enum value, rounding l up or down only */ + for(n = 0, s = f->enum_vals; *s != NULL; n++,s++) { + tmp = strtol(*s, NULL, 10); + if (roundup) { + if (tmp < l) continue; + } + else { + if (tmp > l) continue; + } + diff = tmp - l; + if (diff < 0) diff = -diff; + if ((diff < best) || (bestn < 0)) { + bestn = n; + best = diff; + } + } + if (bestn >= 0) + f->val.lng = bestn; + break; + default: break; + } +} + +void pcb_order_autoload_field(order_ctx_t *octx, pcb_order_field_t *f) +{ + rnd_box_t bb; + long l; + rnd_layergrp_id_t gid; + + switch(f->autoload) { + case PCB_OAL_none: return; + case PCB_OAL_WIDTH: + pcb_data_bbox(&bb, PCB->Data, 0); + autoload_field_crd(octx, f, bb.X2 - bb.X1); + break; + case PCB_OAL_HEIGHT: + pcb_data_bbox(&bb, PCB->Data, 0); + autoload_field_crd(octx, f, bb.X2 - bb.X1); + break; + case PCB_OAL_LAYERS: + for(gid = 0, l = 0; gid < PCB->LayerGroups.len; gid++) + if (PCB->LayerGroups.grp[gid].ltype & PCB_LYT_COPPER) + l++; + autoload_field_lng(octx, f, l, 1); + break; + } +} + + +int pplg_check_ver_order(int ver_needed) { return 0; } + +void pplg_uninit_order(void) +{ + rnd_remove_actions_by_cookie(order_cookie); + rnd_conf_unreg_file(ORDER_CONF_FN, order_conf_internal); + rnd_conf_unreg_fields("plugins/order/"); + rnd_hid_menu_unload(rnd_gui, order_cookie); +} + +int pplg_init_order(void) +{ + RND_API_CHK_VER; + + rnd_conf_reg_file(ORDER_CONF_FN, order_conf_internal); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_order, field,isarray,type_name,cpath,cname,desc,flags); +#include "order_conf_fields.h" + + RND_REGISTER_ACTIONS(order_action_list, order_cookie) + rnd_hid_menu_load(rnd_gui, NULL, order_cookie, 110, NULL, 0, order_menu, "plugin: order pcb"); + return 0; +} Index: tags/2.3.0/src_plugins/order/order.conf =================================================================== --- tags/2.3.0/src_plugins/order/order.conf (nonexistent) +++ tags/2.3.0/src_plugins/order/order.conf (revision 33253) @@ -0,0 +1,9 @@ +li:pcb-rnd-conf-v1 { + ha:append { + ha:plugins { + ha:order { + cache = {~/.pcb-rnd/order_cache} + } + } + } +} Index: tags/2.3.0/src_plugins/order/order.h =================================================================== --- tags/2.3.0/src_plugins/order/order.h (nonexistent) +++ tags/2.3.0/src_plugins/order/order.h (revision 33253) @@ -0,0 +1,88 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_ORDER_H +#define PCB_ORDER_H + +#include +#include +#include "../src_plugins/order/order_conf.h" + +extern conf_order_t conf_order; + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ + vtp0_t names; + void *odata; /* implementation-specific data of the current order */ +} order_ctx_t; + +/* order implementation - registered by an order plugin */ +typedef struct pcb_order_imp_s pcb_order_imp_t; +struct pcb_order_imp_s { + const char *name; + int (*enabled)(pcb_order_imp_t *imp); /* returns 1 if the plugin is enabled */ + int (*load_fields)(pcb_order_imp_t *imp, order_ctx_t *octx); + void (*free_fields)(pcb_order_imp_t *imp, order_ctx_t *octx); + void (*populate_dad)(pcb_order_imp_t *imp, order_ctx_t *octx); +}; + +extern vtp0_t pcb_order_imps; /* of (pcb_order_imp_t *) items */ + +void pcb_order_reg(const pcb_order_imp_t *imp); + +/* Generic field handling */ +typedef enum pcb_order_autoload_e { + PCB_OAL_none, + PCB_OAL_WIDTH, + PCB_OAL_HEIGHT, + PCB_OAL_LAYERS +} pcb_order_autoload_t; + +typedef struct pcb_order_field_s { + rnd_hid_attr_type_t type; + rnd_hid_attr_val_t val; + char **enum_vals; + char *help; + pcb_order_autoload_t autoload; + int wid; /* widget id, if any */ + char name[1]; /* dynamic length */ +} pcb_order_field_t; + +/* Build a hbox from a field */ +void pcb_order_dad_field(order_ctx_t *octx, pcb_order_field_t *f); + + +/* Free data stored in a field, but not the field itself. Note: ->name and + ->type remains valid after the call */ +void pcb_order_free_field_data(order_ctx_t *octx, pcb_order_field_t *f); + +/* If the field is autoloadable from board data, pick up data from board and + modify field value */ +void pcb_order_autoload_field(order_ctx_t *octx, pcb_order_field_t *f); + + +#endif Index: tags/2.3.0/src_plugins/order/order.pup =================================================================== --- tags/2.3.0/src_plugins/order/order.pup (nonexistent) +++ tags/2.3.0/src_plugins/order/order.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short online board ordering +$long order boards through the Internet +$state WIP +#$package cloud +default disable +autoload 1 Index: tags/2.3.0/src_plugins/order/order_conf.h =================================================================== --- tags/2.3.0/src_plugins/order/order_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/order/order_conf.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_ORDER_CONF_H +#define PCB_ORDER_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_STRING cache; /* path to the cache directory where order related vendor data are saved */ + } order; + } plugins; +} conf_order_t; + +#endif Index: tags/2.3.0/src_plugins/order/order_dlg.c =================================================================== --- tags/2.3.0/src_plugins/order/order_dlg.c (nonexistent) +++ tags/2.3.0/src_plugins/order/order_dlg.c (revision 33253) @@ -0,0 +1,90 @@ +order_ctx_t order_ctx; + +static void order_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + order_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(order_ctx_t)); +} + +static int order_dialog(void) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + pcb_order_imp_t *imp; + int n; + + if (order_ctx.active) + return -1; /* do not open another */ + + if (pcb_order_imps.used == 0) { + rnd_message(RND_MSG_ERROR, "OrderPCB(): there are no ordering plugins compiled/loaded\n"); + return -1; + } + + order_ctx.names.used = 0; + vtp0_enlarge(&order_ctx.names, pcb_order_imps.used); + for(n = 0; n < pcb_order_imps.used; n++) { + imp = pcb_order_imps.array[n]; + vtp0_set(&order_ctx.names, n, (char *)imp->name); + } + vtp0_set(&order_ctx.names, n, NULL); + + RND_DAD_BEGIN_VBOX(order_ctx.dlg); + RND_DAD_COMPFLAG(order_ctx.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(order_ctx.dlg, order_ctx.names.array); + RND_DAD_COMPFLAG(order_ctx.dlg, RND_HATF_EXPFILL | RND_HATF_LEFT_TAB); + for(n = 0; n < pcb_order_imps.used; n++) { + imp = pcb_order_imps.array[n]; + if (imp->load_fields(pcb_order_imps.array[n], &order_ctx) == 0) { + RND_DAD_BEGIN_VBOX(order_ctx.dlg); + RND_DAD_COMPFLAG(order_ctx.dlg, RND_HATF_EXPFILL); + + imp->populate_dad(pcb_order_imps.array[n], &order_ctx); + RND_DAD_END(order_ctx.dlg); + } + else + RND_DAD_LABEL(order_ctx.dlg, "Failed to determine form fields"); + } + + RND_DAD_END(order_ctx.dlg); + RND_DAD_BUTTON_CLOSES(order_ctx.dlg, clbtn); + RND_DAD_END(order_ctx.dlg); + + /* set up the context */ + order_ctx.active = 1; + + RND_DAD_NEW("order", order_ctx.dlg, "Order PCB", &order_ctx, rnd_false, order_close_cb); + return 0; +} + +void pcb_order_dad_field(order_ctx_t *octx, pcb_order_field_t *f) +{ + RND_DAD_BEGIN_HBOX(octx->dlg); + RND_DAD_LABEL(octx->dlg, f->name); + RND_DAD_BEGIN_VBOX(octx->dlg); + RND_DAD_COMPFLAG(octx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(octx->dlg); + switch(f->type) { + case RND_HATT_ENUM: + RND_DAD_ENUM(octx->dlg, f->enum_vals); + RND_DAD_DEFAULT_NUM(octx->dlg, f->val.lng); + break; + case RND_HATT_INTEGER: + RND_DAD_INTEGER(octx->dlg); + RND_DAD_DEFAULT_NUM(octx->dlg, f->val.lng); + break; + case RND_HATT_COORD: + RND_DAD_COORD(octx->dlg); + RND_DAD_DEFAULT_NUM(octx->dlg, f->val.crd); + break; + case RND_HATT_STRING: + RND_DAD_STRING(octx->dlg); + RND_DAD_DEFAULT_PTR(octx->dlg, f->val.str); + break; + case RND_HATT_LABEL: break; + default: + RND_DAD_LABEL(octx->dlg, ""); + } + f->wid = RND_DAD_CURRENT(octx->dlg); + RND_DAD_END(octx->dlg); +} Index: tags/2.3.0/src_plugins/order_pcbway/Makefile =================================================================== --- tags/2.3.0/src_plugins/order_pcbway/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/order_pcbway/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_order_pcbway + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/order_pcbway/PCBWay_Api.xml =================================================================== --- tags/2.3.0/src_plugins/order_pcbway/PCBWay_Api.xml (nonexistent) +++ tags/2.3.0/src_plugins/order_pcbway/PCBWay_Api.xml (revision 33253) @@ -0,0 +1,120 @@ + + + + + + + TG130 + TG150 + TG170 + + + 1 oz Cu + 2 oz Cu + 3 oz Cu + 4 oz Cu + + + Yes + No + + + 1 + 2 + 4 + 6 + 8 + 10 + 12 + 14 + + + + FR-4 + Aluminum board + Rigid-Flex + + + 0.2 + 0.25 + 0.3 + -1 + + + 4/4mil + 5/5mil + 6/6mil + + + + White + Black + None + + + Green + Red + Yellow + Blue + White + Black + Purple + Matt black + Matt green + None + + + HASL with lead + HASL lead free + Immersion gold + Hard Gold + OSP + None + + + 0.4 + 0.6 + 0.8 + 1.0 + 1.2 + 1.6 + 2.0 + 2.4 + + + Tenting vias + Plugged vias + Vias not covered + + + + + + + + DHL + HK_post + SF_Express + Freight_Collect_Account + EMS + E_packet + HK_DHL + China_Post + FedEx_IP + FedEx_IE + + + \ No newline at end of file Index: tags/2.3.0/src_plugins/order_pcbway/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/order_pcbway/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/order_pcbway/Plug.tmpasm (revision 33253) @@ -0,0 +1,22 @@ +put /local/pcb/mod {order_pcbway} +put /local/pcb/mod/CONF {$(PLUGDIR)/order_pcbway/order_pcbway_conf.h} +put /local/pcb/mod/CONFFILE {order_pcbway.conf} +put /local/pcb/mod/CONFVAR {order_pcbway_conf_internal} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/order_pcbway/pcbway.o +@] + +switch /local/pcb/order_pcbway/controls + case {disable} end; + default + put /local/pcb/mod/CFLAGS /target/libs/sul/libxml2/cflags + put /local/pcb/mod/LDFLAGS /target/libs/sul/libxml2/ldflags + end +end + + +switch /local/pcb/order_pcbway/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/order_pcbway/TODO =================================================================== --- tags/2.3.0/src_plugins/order_pcbway/TODO (nonexistent) +++ tags/2.3.0/src_plugins/order_pcbway/TODO (revision 33253) @@ -0,0 +1,4 @@ +- host the xml +- is the API key per software or per person? +- missing options in the API xml compared to the web page (e.g. bbvia!) +- shipping cost: $50 instead of $25 to AU; $47 instead of $17 to US Index: tags/2.3.0/src_plugins/order_pcbway/order_pcbway.conf =================================================================== --- tags/2.3.0/src_plugins/order_pcbway/order_pcbway.conf (nonexistent) +++ tags/2.3.0/src_plugins/order_pcbway/order_pcbway.conf (revision 33253) @@ -0,0 +1,11 @@ +li:pcb-rnd-conf-v1 { + ha:append { + ha:plugins { + ha:order_pcbway { + api_key={} + verbose=1 + cache_update_sec = 604800 + } + } + } +} Index: tags/2.3.0/src_plugins/order_pcbway/order_pcbway.pup =================================================================== --- tags/2.3.0/src_plugins/order_pcbway/order_pcbway.pup (nonexistent) +++ tags/2.3.0/src_plugins/order_pcbway/order_pcbway.pup (revision 33253) @@ -0,0 +1,9 @@ +$class feature +$short board ordering from PCBWay +$long order from PCBWay through the Internet +$state WIP +#$package cloud +dep order +dep lib_wget +default disable +autoload 1 Index: tags/2.3.0/src_plugins/order_pcbway/order_pcbway_conf.h =================================================================== --- tags/2.3.0/src_plugins/order_pcbway/order_pcbway_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/order_pcbway/order_pcbway_conf.h (revision 33253) @@ -0,0 +1,16 @@ +#ifndef PCB_ORDER_PCBWAY_CONF_H +#define PCB_ORDER_PCBWAY_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_STRING api_key; + RND_CFT_BOOLEAN verbose; /* print log messages about the web traffic the plugin does */ + RND_CFT_INTEGER cache_update_sec; /* re-download cached vendor files if they are older than the value specified here, in sec */ + } order_pcbway; + } plugins; +} conf_order_pcbway_t; + +#endif Index: tags/2.3.0/src_plugins/order_pcbway/pcbway.c =================================================================== --- tags/2.3.0/src_plugins/order_pcbway/pcbway.c (nonexistent) +++ tags/2.3.0/src_plugins/order_pcbway/pcbway.c (revision 33253) @@ -0,0 +1,588 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "board.h" +#include +#include +#include +#include +#include +#include +#include "../src_plugins/order/order.h" +#include "order_pcbway_conf.h" +#include "../src_plugins/order_pcbway/conf_internal.c" + +conf_order_pcbway_t conf_order_pcbway; +#define ORDER_PCBWAY_CONF_FN "order_pcbway.conf" + +#define CFG conf_order_pcbway.plugins.order_pcbway +#define SERVER "http://api-partner.pcbway.com" + +static const char *order_xpm[] = { +"23 5 2 1", +" c None", +"+ c #000000", +" ++ +++ +++ +++ +++ ", +"+ + + + + + + + + ", +"+ + ++ + + ++ ++ ", +"+ + + + + + + + + ", +" ++ + + +++ +++ + + ", +}; + +typedef struct pcbway_form_s { + vtp0_t fields; /* of pcb_order_field_t */ + vts0_t country_codes; +} pcbway_form_t; + +static int pcbway_cahce_update_(rnd_hidlib_t *hidlib, const char *url, const char *path, int update, pcb_wget_opts_t *wopts) +{ + double mt, now = rnd_dtime(); + + mt = rnd_file_mtime(hidlib, path); + if (update || (mt < 0) || ((now - mt) > CFG.cache_update_sec)) { + if (CFG.verbose) { + if (update) + rnd_message(RND_MSG_INFO, "pcbway: static '%s', updating it in the cache\n", path); + else + rnd_message(RND_MSG_INFO, "pcbway: stale '%s', updating it in the cache\n", path); + } + if (pcb_wget_disk(url, path, update, wopts) != 0) { + rnd_message(RND_MSG_ERROR, "pcbway: failed to download %s\n", url); + return -1; + } + + } + else if (CFG.verbose) + rnd_message(RND_MSG_INFO, "pcbway: '%s' from cache\n", path); + return 0; +} + +static int pcbway_cache_update(rnd_hidlib_t *hidlib) +{ + char *hdr[5]; + pcb_wget_opts_t wopts; + char *cachedir, *path; + int res = 0; + + wopts.header = (const char **)hdr; + hdr[0] = rnd_concat("api-key: ", CFG.api_key, NULL); + hdr[1] = "Content-Type: application/xml"; + hdr[2] = "Accept: application/xml"; + hdr[3] = NULL; + + cachedir = rnd_build_fn(hidlib, conf_order.plugins.order.cache); + + rnd_mkdir(hidlib, cachedir, 0755); + wopts.post_file = "/dev/null"; + path = rnd_strdup_printf("%s%cGetCountry", cachedir, RND_DIR_SEPARATOR_C); + if (pcbway_cahce_update_(hidlib, SERVER "/api/Address/GetCountry", path, 0, &wopts) != 0) { + res = -1; + goto quit; + } + free(path); + + path = rnd_strdup_printf("%s%cPCBWay_Api.xml", cachedir, RND_DIR_SEPARATOR_C); + if (pcbway_cahce_update_(hidlib, SERVER "/xml/PCBWay_Api.xml", path, 1, NULL) != 0) { + res = -1; + goto quit; + } + + + quit:; + free(path); + free(hdr[0]); + free(cachedir); + return res; +} + + + +static xmlDoc *pcbway_xml_load(const char *fn) +{ + xmlDoc *doc; + FILE *f; + char *efn = NULL; + + f = rnd_fopen_fn(NULL, fn, "r", &efn); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "pcbway: can't open '%s' (%s) for read\n", fn, efn); + free(efn); + return NULL; + } + fclose(f); + + doc = xmlReadFile(efn, NULL, 0); + if (doc == NULL) { + rnd_message(RND_MSG_ERROR, "xml parsing error on file %s (%s)\n", fn, efn); + free(efn); + return NULL; + } + free(efn); + + return doc; +} + +static int pcbway_load_countries(pcbway_form_t *form, const char *fn) +{ + xmlDoc *doc = pcbway_xml_load(fn); + xmlNode *root, *n, *c; + + if (doc == NULL) { + rnd_message(RND_MSG_ERROR, "order_pcbway: failed to parse the country xml\n"); + return -1; + } + root = xmlDocGetRootElement(doc); + if ((root != NULL) && (xmlStrcmp(root->name, (xmlChar *)"Country") != 0)) { + rnd_message(RND_MSG_ERROR, "order_pcbway: wrong root node in the country xml\n"); + return -1; + } + + for(root = root->children; (root != NULL) && (xmlStrcmp(root->name, (xmlChar *)"Countrys") != 0); root = root->next) ; + if (root == NULL) { + rnd_message(RND_MSG_ERROR, "order_pcbway: failed to find a node\n"); + return -1; + } + + for(n = root->children; n != NULL; n = n->next) { + if (xmlStrcmp(n->name, (xmlChar *)"CountryModel") != 0) + continue; + for(c = n->children; c != NULL; c = c->next) + if ((c->children != NULL) && (c->children->type == XML_TEXT_NODE) && (xmlStrcmp(c->name, (xmlChar *)"CountryCode") == 0)) + vts0_append(&form->country_codes, rnd_strdup(c->children->content)); + } + + xmlFreeDoc(doc); +} + + +static int pcbway_load_fields_(rnd_hidlib_t *hidlib, pcb_order_imp_t *imp, order_ctx_t *octx, xmlNode *root) +{ + xmlNode *n, *v; + pcbway_form_t *form = (pcbway_form_t *)octx->odata; + for(root = root->children; (root != NULL) && (xmlStrcmp(root->name, (xmlChar *)"PcbQuotationRequest") != 0); root = root->next) ; + + if (root == NULL) + return -1; + + for(n = root->children; n != NULL; n = n->next) { + const char *type, *note, *dflt; + pcb_order_field_t *f; + if ((n->type == XML_TEXT_NODE) || (n->name == NULL)) + continue; + type = (const char *)xmlGetProp(n, (const xmlChar *)"type"); + note = (const char *)xmlGetProp(n, (const xmlChar *)"note"); + dflt = (const char *)xmlGetProp(n, (const xmlChar *)"default"); + + if ((type != NULL && strlen(type) > 128) || (strlen((char *)n->name) > 128) || (note != NULL && strlen(note) > 256) || (dflt != NULL && strlen(dflt) > 128)) { + rnd_message(RND_MSG_ERROR, "order_pcbway: invalid field description: too long\n"); + return -1; + } + + f = calloc(sizeof(pcb_order_field_t) + strlen((char *)n->name), 1); + strcpy(f->name, (char *)n->name); + if (note != NULL) + f->help = rnd_strdup(note); + if (type == NULL) { + f->type = RND_HATT_LABEL; + } + else if (strcmp(type, "enum") == 0) { + int di = 0, i; + vtp0_t tmp; + + f->type = RND_HATT_ENUM; + vtp0_init(&tmp); + for(v = n->children, i = 0; v != NULL; v = v->next) { + char *s; + if ((n->type == XML_TEXT_NODE) || (xmlStrcmp(v->name, (xmlChar *)"Value") != 0) || (n->children->type != XML_TEXT_NODE)) + continue; + s = rnd_strdup((char *)v->children->content); + vtp0_append(&tmp, s); + if ((dflt != NULL) && (strcmp(s, dflt) == 0)) + di = i; + i++; + } + vtp0_append(&tmp, NULL); + f->enum_vals = (char **)tmp.array; + if (dflt != NULL) + f->val.lng = di; + } + else if (strcmp(type, "enum:country:code") == 0) { + f->type = RND_HATT_ENUM; + f->enum_vals = form->country_codes.array; + } + else if (strcmp(type, "integer") == 0) { + f->type = RND_HATT_INTEGER; + if (dflt != NULL) + f->val.lng = atoi(dflt); + } + else if (strcmp(type, "mm") == 0) { + f->type = RND_HATT_COORD; + if (dflt != NULL) + f->val.crd = RND_MM_TO_COORD(strtod(dflt, NULL)); + } + else if (strcmp(type, "string") == 0) { + f->type = RND_HATT_STRING; + if (dflt != NULL) + f->val.str = rnd_strdup(dflt); + } + else { + f->type = RND_HATT_LABEL; + } + if (strcmp(f->name, "Layers") == 0) f->autoload = PCB_OAL_LAYERS; + else if (strcmp(f->name, "Width") == 0) f->autoload = PCB_OAL_WIDTH; + else if (strcmp(f->name, "Length") == 0) f->autoload = PCB_OAL_HEIGHT; + + pcb_order_autoload_field(octx, f); + + vtp0_append(&form->fields, f); + if (form->fields.used > 128) { + rnd_message(RND_MSG_ERROR, "order_pcbway: too many fields for a form\n"); + return -1; + } + } + return 0; +} + +static int pcbway_load_fields(pcb_order_imp_t *imp, order_ctx_t *octx) +{ + char *cachedir, *path, *country_fn; + xmlDoc *doc; + xmlNode *root; + int res = 0; + + octx->odata = NULL; + + if ((CFG.api_key == NULL) || (*CFG.api_key == '\0')) { + rnd_message(RND_MSG_ERROR, "order_pcbway: no api_key available."); + return -1; + } + if (pcbway_cache_update(&PCB->hidlib) != 0) { + rnd_message(RND_MSG_ERROR, "order_pcbway: failed to update the cache."); + return -1; + } + + cachedir = rnd_build_fn(&PCB->hidlib, conf_order.plugins.order.cache); + path = rnd_strdup_printf("%s%cPCBWay_Api.xml", cachedir, RND_DIR_SEPARATOR_C); + doc = pcbway_xml_load(path); + if (doc != NULL) { + root = xmlDocGetRootElement(doc); + if ((root != NULL) && (xmlStrcmp(root->name, (xmlChar *)"PCBWayAPI") == 0)) { + octx->odata = calloc(sizeof(pcbway_form_t), 1); + country_fn = rnd_strdup_printf("%s%cGetCountry", cachedir, RND_DIR_SEPARATOR_C); + if (pcbway_load_countries(octx->odata, country_fn) != 0) + res = -1; + else if (pcbway_load_fields_(&PCB->hidlib, imp, octx, root) != 0) { + rnd_message(RND_MSG_ERROR, "order_pcbway: xml error: invalid API xml\n"); + res = -1; + } + free(country_fn); + } + else + rnd_message(RND_MSG_ERROR, "order_pcbway: xml error: root is not \n"); + } + else + rnd_message(RND_MSG_ERROR, "order_pcbway: xml error: failed to parse the xml\n"); + + xmlFreeDoc(doc); + free(cachedir); + free(path); + + return res; +} + +static void pcbway_free_fields(pcb_order_imp_t *imp, order_ctx_t *octx) +{ + int n; + pcbway_form_t *form = octx->odata; + for(n = 0; n < form->fields.used; n++) { + pcb_order_field_t *f = form->fields.array[n]; + pcb_order_free_field_data(octx, f); + free(f); + } + for(n = 0; n < form->country_codes.used; n++) + free(form->country_codes.array[n]); + vtp0_uninit(&form->fields); + vts0_uninit(&form->country_codes); + free(form); +} + +static void pcbway_dlg2fields(order_ctx_t *octx, pcbway_form_t *form) +{ + int n; + for(n = 0; n < form->fields.used; n++) { + pcb_order_field_t *f = form->fields.array[n]; + if (f->wid <= 0) + continue; + f->val = octx->dlg[f->wid].val; + } +} + +#define XML_TBL(dlg, node, price, pricetag) \ + do { \ + xmlNode *__n__; \ + double __prc__; \ + price = -1; \ + for(__n__ = node->children; __n__ != NULL; __n__ = __n__->next) { \ + char *val = NULL; \ + if ((__n__->children != NULL) && (__n__->children->type == XML_TEXT_NODE)) \ + val = __n__->children->content; \ + RND_DAD_LABEL(dlg, (char *)__n__->name); \ + if ((val != NULL) && (xmlStrcmp(__n__->name, (xmlChar *)pricetag) == 0)) { \ + char *__end__, *__tmp__ = rnd_concat("$", val, NULL); \ + RND_DAD_LABEL(dlg, __tmp__); \ + free(__tmp__); \ + __prc__ = strtod(val, &__end__); \ + if (*__end__ == '\0') price = __prc__; \ + } \ + else \ + RND_DAD_LABEL(dlg, val); \ + } \ + } while(0) + +static int pcbway_present_quote(order_ctx_t *octx, const char *respfn) +{ + double shipcost, cost; + xmlNode *root, *n, *error = NULL, *status = NULL, *ship = NULL, *prices = NULL; + xmlDoc *doc = pcbway_xml_load(respfn); + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {NULL, 0}}; + RND_DAD_DECL(dlg); + + if (doc == NULL) + return -1; + + root = xmlDocGetRootElement(doc); + if ((root != NULL) && (xmlStrcmp(root->name, (xmlChar *)"PcbQuotationResponse") != 0)) { + rnd_message(RND_MSG_ERROR, "order_pcbway: wrong root node on quote answer\n"); + xmlFreeDoc(doc); + return -1; + } + + for(n = root->children; n != NULL; n = n->next) { + if (xmlStrcmp(n->name, (xmlChar *)"ErrorText") == 0) error = n; + else if (xmlStrcmp(n->name, (xmlChar *)"Status") == 0) status = n; + else if (xmlStrcmp(n->name, (xmlChar *)"Shipping") == 0) ship = n; + else if (xmlStrcmp(n->name, (xmlChar *)"priceList") == 0) prices = n; + } + + if ((status == NULL) || (status->children == NULL) || (status->children->type != XML_TEXT_NODE)) { + rnd_message(RND_MSG_ERROR, "order_pcbway: missing from the quote response\n"); + xmlFreeDoc(doc); + return -1; + } + if (xmlStrcmp(status->children->content, (xmlChar *)"ok") != 0) { + rnd_message(RND_MSG_ERROR, "order_pcbway: server error in quote\n"); + if ((error != NULL) && (error->children != NULL) && (error->children->type == XML_TEXT_NODE)) + rnd_message(RND_MSG_ERROR, " %s\n", error->children->content); + xmlFreeDoc(doc); + return -1; + } + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + + RND_DAD_BEGIN_TABLE(dlg, 2); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_LABEL(dlg, "=== Shipping ==="); RND_DAD_LABEL(dlg, ""); + XML_TBL(dlg, ship, shipcost, "ShipCost"); + for(n = prices->children; n != NULL; n = n->next) { + char tmp[128]; + RND_DAD_LABEL(dlg, "=== Option ==="); RND_DAD_LABEL(dlg, ""); + XML_TBL(dlg, n, cost, "Price"); + if ((shipcost >= 0) && (cost >= 0)) + sprintf(tmp, "$%.2f ", shipcost+cost); + else + *tmp = 0; + + RND_DAD_LABEL(dlg, " Total:"); + RND_DAD_COMPFLAG(dlg, RND_HATF_TIGHT); + + RND_DAD_BEGIN_HBOX(dlg); + RND_DAD_COMPFLAG(dlg, RND_HATF_TIGHT); + RND_DAD_LABEL(dlg, tmp); + RND_DAD_PICBUTTON(dlg, order_xpm); + RND_DAD_END(dlg); + + + } + RND_DAD_END(dlg); + + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + + RND_DAD_NEW("pcbway_quote", dlg, "PCBWay: quote", NULL, rnd_true, NULL); + RND_DAD_RUN(dlg); + RND_DAD_FREE(dlg); + + xmlFreeDoc(doc); + return 0; +} + +static void pcbway_quote_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + order_ctx_t *octx = caller_data; + pcbway_form_t *form = octx->odata; + int n; + FILE *fx; + char *tmpfn, *respfn = "Resp.xml"; + + pcbway_dlg2fields(octx, form); + + tmpfn = rnd_tempfile_name_new("pcbway_quote.xml"); + if (tmpfn == NULL) { + rnd_message(RND_MSG_ERROR, "order_pcbway: can't get temp file name\n"); + return; + } + + fx = rnd_fopen(&PCB->hidlib, tmpfn, "w"); + if (fx == NULL) { + rnd_tempfile_unlink(tmpfn); + rnd_message(RND_MSG_ERROR, "order_pcbway: can't open temp file\n"); + return; + } + + + fprintf(fx, "\n"); + for(n = 0; n < form->fields.used; n++) { + pcb_order_field_t *f = form->fields.array[n]; + fprintf(fx, " <%s>", (char *)f->name); + + switch(f->type) { + case RND_HATT_ENUM: + fprintf(fx, "%s", f->enum_vals[f->val.lng]); + break; + case RND_HATT_INTEGER: + fprintf(fx, "%d", f->val.lng); + break; + case RND_HATT_COORD: + rnd_fprintf(fx, "%mm", f->val.crd); + break; + + case RND_HATT_STRING: + if (f->val.str != NULL) + fprintf(fx, "%s", f->val.str); + break; + + default: + break; + } + + fprintf(fx, "\n", (char *)f->name); + } + fprintf(fx, "\n"); + fclose(fx); + + { + char *hdr[5]; + pcb_wget_opts_t wopts; + + wopts.header = (const char **)hdr; + hdr[0] = rnd_concat("api-key: ", CFG.api_key, NULL); + hdr[1] = "Content-Type: application/xml"; + hdr[2] = "Accept: application/xml"; + hdr[3] = NULL; + wopts.post_file = tmpfn; + + if (pcb_wget_disk(SERVER "/api/Pcb/PcbQuotation", respfn, 0, &wopts) != 0) { + rnd_message(RND_MSG_ERROR, "pcbway: failed to get a quote from the server\n"); + goto err; + } + } + + pcbway_present_quote(octx, respfn); + + err:; + rnd_tempfile_unlink(tmpfn); +} + + +static void pcbway_populate_dad(pcb_order_imp_t *imp, order_ctx_t *octx) +{ + int n; + pcbway_form_t *form = octx->odata; + + RND_DAD_BEGIN_VBOX(octx->dlg); + RND_DAD_COMPFLAG(octx->dlg, RND_HATF_SCROLL | RND_HATF_EXPFILL); + + for(n = 0; n < form->fields.used; n++) + pcb_order_dad_field(octx, form->fields.array[n]); + + RND_DAD_BEGIN_VBOX(octx->dlg); + RND_DAD_COMPFLAG(octx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(octx->dlg, ""); + RND_DAD_LABEL(octx->dlg, ""); + RND_DAD_END(octx->dlg); + + RND_DAD_BEGIN_HBOX(octx->dlg); + RND_DAD_BUTTON(octx->dlg, "Update data"); + RND_DAD_HELP(octx->dlg, "Copy data from board to form"); + RND_DAD_BEGIN_VBOX(octx->dlg); + RND_DAD_COMPFLAG(octx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(octx->dlg); + RND_DAD_BUTTON(octx->dlg, "Quote & order"); + RND_DAD_HELP(octx->dlg, "Generate a price quote"); + RND_DAD_CHANGE_CB(octx->dlg, pcbway_quote_cb); + RND_DAD_END(octx->dlg); + + RND_DAD_END(octx->dlg); +} + +static pcb_order_imp_t pcbway = { + "PCBWay", + NULL, + pcbway_load_fields, + pcbway_free_fields, + pcbway_populate_dad +}; + + +int pplg_check_ver_order_pcbway(int ver_needed) { return 0; } + +void pplg_uninit_order_pcbway(void) +{ + rnd_conf_unreg_file(ORDER_PCBWAY_CONF_FN, order_pcbway_conf_internal); + rnd_conf_unreg_fields("plugins/order_pcbway/"); +} + +int pplg_init_order_pcbway(void) +{ + RND_API_CHK_VER; + + rnd_conf_reg_file(ORDER_PCBWAY_CONF_FN, order_pcbway_conf_internal); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_order_pcbway, field,isarray,type_name,cpath,cname,desc,flags); +#include "order_pcbway_conf_fields.h" + + pcb_order_reg(&pcbway); + return 0; +} Index: tags/2.3.0/src_plugins/plugins_ALL.tmpasm =================================================================== --- tags/2.3.0/src_plugins/plugins_ALL.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/plugins_ALL.tmpasm (revision 33253) @@ -0,0 +1,125 @@ +# List of all plugins - generated by make map_plugins - do NOT edit +include {../src_3rd/librnd/plugins/hid_batch/Plug.tmpasm} +include {../src_3rd/librnd/plugins/hid_gtk2_gdk/Plug.tmpasm} +include {../src_3rd/librnd/plugins/hid_gtk2_gl/Plug.tmpasm} +include {../src_3rd/librnd/plugins/hid_lesstif/Plug.tmpasm} +include {../src_3rd/librnd/plugins/hid_remote/Plug.tmpasm} +include {../src_3rd/librnd/plugins/irc/Plug.tmpasm} +include {../src_3rd/librnd/plugins/lib_gensexpr/Plug.tmpasm} +include {../src_3rd/librnd/plugins/lib_gtk_common/Plug.tmpasm} +include {../src_3rd/librnd/plugins/lib_hid_common/Plug.tmpasm} +include {../src_3rd/librnd/plugins/lib_hid_gl/Plug.tmpasm} +include {../src_3rd/librnd/plugins/lib_portynet/Plug.tmpasm} +include {../src_3rd/librnd/plugins/lib_wget/Plug.tmpasm} +include {../src_3rd/librnd/plugins/loghid/Plug.tmpasm} +include {../src_3rd/librnd/plugins/stroke/Plug.tmpasm} +include {../src_plugins/acompnet/Plug.tmpasm} +include {../src_plugins/act_draw/Plug.tmpasm} +include {../src_plugins/act_read/Plug.tmpasm} +include {../src_plugins/ar_cpcb/Plug.tmpasm} +include {../src_plugins/ar_extern/Plug.tmpasm} +include {../src_plugins/asm/Plug.tmpasm} +include {../src_plugins/autocrop/Plug.tmpasm} +include {../src_plugins/autoplace/Plug.tmpasm} +include {../src_plugins/autoroute/Plug.tmpasm} +include {../src_plugins/cam/Plug.tmpasm} +include {../src_plugins/ch_editpoint/Plug.tmpasm} +include {../src_plugins/ch_onpoint/Plug.tmpasm} +include {../src_plugins/ddraft/Plug.tmpasm} +include {../src_plugins/diag/Plug.tmpasm} +include {../src_plugins/dialogs/Plug.tmpasm} +include {../src_plugins/distalign/Plug.tmpasm} +include {../src_plugins/djopt/Plug.tmpasm} +include {../src_plugins/draw_csect/Plug.tmpasm} +include {../src_plugins/draw_fab/Plug.tmpasm} +include {../src_plugins/draw_fontsel/Plug.tmpasm} +include {../src_plugins/drc_query/Plug.tmpasm} +include {../src_plugins/expfeat/Plug.tmpasm} +include {../src_plugins/export_bom/Plug.tmpasm} +include {../src_plugins/export_dsn/Plug.tmpasm} +include {../src_plugins/export_dxf/Plug.tmpasm} +include {../src_plugins/export_excellon/Plug.tmpasm} +include {../src_plugins/export_fidocadj/Plug.tmpasm} +include {../src_plugins/export_gcode/Plug.tmpasm} +include {../src_plugins/export_gerber/Plug.tmpasm} +include {../src_plugins/export_ipcd356/Plug.tmpasm} +include {../src_plugins/export_lpr/Plug.tmpasm} +include {../src_plugins/export_oldconn/Plug.tmpasm} +include {../src_plugins/export_openems/Plug.tmpasm} +include {../src_plugins/export_openscad/Plug.tmpasm} +include {../src_plugins/export_png/Plug.tmpasm} +include {../src_plugins/export_ps/Plug.tmpasm} +include {../src_plugins/export_stat/Plug.tmpasm} +include {../src_plugins/export_stl/Plug.tmpasm} +include {../src_plugins/export_svg/Plug.tmpasm} +include {../src_plugins/export_vfs_fuse/Plug.tmpasm} +include {../src_plugins/export_vfs_mc/Plug.tmpasm} +include {../src_plugins/export_xy/Plug.tmpasm} +include {../src_plugins/extedit/Plug.tmpasm} +include {../src_plugins/exto_std/Plug.tmpasm} +include {../src_plugins/fontmode/Plug.tmpasm} +include {../src_plugins/fp_board/Plug.tmpasm} +include {../src_plugins/fp_fs/Plug.tmpasm} +include {../src_plugins/fp_wget/Plug.tmpasm} +include {../src_plugins/import_accel_net/Plug.tmpasm} +include {../src_plugins/import_calay/Plug.tmpasm} +include {../src_plugins/import_dsn/Plug.tmpasm} +include {../src_plugins/import_edif/Plug.tmpasm} +include {../src_plugins/import_fpcb_nl/Plug.tmpasm} +include {../src_plugins/import_gnetlist/Plug.tmpasm} +include {../src_plugins/import_hpgl/Plug.tmpasm} +include {../src_plugins/import_ipcd356/Plug.tmpasm} +include {../src_plugins/import_ltspice/Plug.tmpasm} +include {../src_plugins/import_mentor_sch/Plug.tmpasm} +include {../src_plugins/import_mucs/Plug.tmpasm} +include {../src_plugins/import_net_action/Plug.tmpasm} +include {../src_plugins/import_net_cmd/Plug.tmpasm} +include {../src_plugins/import_netlist/Plug.tmpasm} +include {../src_plugins/import_orcad_net/Plug.tmpasm} +include {../src_plugins/import_pads_net/Plug.tmpasm} +include {../src_plugins/import_protel_net/Plug.tmpasm} +include {../src_plugins/import_pxm_gd/Plug.tmpasm} +include {../src_plugins/import_pxm_pnm/Plug.tmpasm} +include {../src_plugins/import_sch2/Plug.tmpasm} +include {../src_plugins/import_tinycad/Plug.tmpasm} +include {../src_plugins/import_ttf/Plug.tmpasm} +include {../src_plugins/io_autotrax/Plug.tmpasm} +include {../src_plugins/io_bxl/Plug.tmpasm} +include {../src_plugins/io_dsn/Plug.tmpasm} +include {../src_plugins/io_eagle/Plug.tmpasm} +include {../src_plugins/io_hyp/Plug.tmpasm} +include {../src_plugins/io_kicad/Plug.tmpasm} +include {../src_plugins/io_kicad_legacy/Plug.tmpasm} +include {../src_plugins/io_lihata/Plug.tmpasm} +include {../src_plugins/io_mentor_cell/Plug.tmpasm} +include {../src_plugins/io_pcb/Plug.tmpasm} +include {../src_plugins/io_tedax/Plug.tmpasm} +include {../src_plugins/jostle/Plug.tmpasm} +include {../src_plugins/lib_compat_help/Plug.tmpasm} +include {../src_plugins/lib_formula/Plug.tmpasm} +include {../src_plugins/lib_hid_pcbui/Plug.tmpasm} +include {../src_plugins/lib_netmap/Plug.tmpasm} +include {../src_plugins/lib_polyhelp/Plug.tmpasm} +include {../src_plugins/lib_vfs/Plug.tmpasm} +include {../src_plugins/millpath/Plug.tmpasm} +include {../src_plugins/mincut/Plug.tmpasm} +include {../src_plugins/oldactions/Plug.tmpasm} +include {../src_plugins/order/Plug.tmpasm} +include {../src_plugins/order_pcbway/Plug.tmpasm} +include {../src_plugins/polycombine/Plug.tmpasm} +include {../src_plugins/polystitch/Plug.tmpasm} +include {../src_plugins/propedit/Plug.tmpasm} +include {../src_plugins/puller/Plug.tmpasm} +include {../src_plugins/query/Plug.tmpasm} +include {../src_plugins/renumber/Plug.tmpasm} +include {../src_plugins/report/Plug.tmpasm} +include {../src_plugins/rubberband_orig/Plug.tmpasm} +include {../src_plugins/script/Plug.tmpasm} +include {../src_plugins/serpentine/Plug.tmpasm} +include {../src_plugins/shand_cmd/Plug.tmpasm} +include {../src_plugins/shape/Plug.tmpasm} +include {../src_plugins/sketch_route/Plug.tmpasm} +include {../src_plugins/smartdisperse/Plug.tmpasm} +include {../src_plugins/teardrops/Plug.tmpasm} +include {../src_plugins/tool_std/Plug.tmpasm} +include {../src_plugins/vendordrill/Plug.tmpasm} Index: tags/2.3.0/src_plugins/polycombine/Makefile =================================================================== --- tags/2.3.0/src_plugins/polycombine/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/polycombine/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_polycombine + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/polycombine/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/polycombine/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/polycombine/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {polycombine} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/polycombine/polycombine.o @] + +switch /local/pcb/polycombine/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/polycombine/polycombine.c =================================================================== --- tags/2.3.0/src_plugins/polycombine/polycombine.c (nonexistent) +++ tags/2.3.0/src_plugins/polycombine/polycombine.c (revision 33253) @@ -0,0 +1,353 @@ +/* + * PolyCombine plug-in for PCB. + * + * Copyright (C) 2010 Peter Clifton + * + * Licensed under the terms of the GNU General Public + * License, version 2. + * + * Ported to pcb-rnd by Tibor 'Igor2' Palinkas in 2016. + * + */ + +#include +#include + +#include "config.h" +#include "board.h" +#include "data.h" +#include "remove.h" +#include +#include +#include +#include "polygon.h" +#include +#include "assert.h" +#include "flag_str.h" +#include "find.h" +#include "draw.h" +#include "undo.h" +#include +#include +#include "obj_poly.h" + +static rnd_polyarea_t *original_poly(pcb_poly_t *p, rnd_bool *forward) +{ + rnd_pline_t *contour = NULL; + rnd_polyarea_t *np = NULL; + rnd_cardinal_t n; + rnd_vector_t v; + int hole = 0; + + *forward = rnd_true; + + if ((np = rnd_polyarea_create()) == NULL) + return NULL; + + /* first make initial polygon contour */ + for (n = 0; n < p->PointN; n++) { + /* No current contour? Make a new one starting at point */ + /* (or) Add point to existing contour */ + + v[0] = p->Points[n].X; + v[1] = p->Points[n].Y; + if (contour == NULL) { + if ((contour = rnd_poly_contour_new(v)) == NULL) + return NULL; + } + else { + rnd_poly_vertex_include(contour->head->prev, rnd_poly_node_create(v)); + } + + /* Is current point last in contour? If so process it. */ + if (n == p->PointN - 1 || (hole < p->HoleIndexN && n == p->HoleIndex[hole] - 1)) { + rnd_poly_contour_pre(contour, rnd_true); + + /* Log the direction in which the outer contour was specified */ + if (hole == 0) + *forward = (contour->Flags.orient == RND_PLF_DIR); + + /* make sure it is a positive contour (outer) or negative (hole) */ + if (contour->Flags.orient != (hole ? RND_PLF_INV : RND_PLF_DIR)) + rnd_poly_contour_inv(contour); + assert(contour->Flags.orient == (hole ? RND_PLF_INV : RND_PLF_DIR)); + + rnd_polyarea_contour_include(np, contour); + contour = NULL; + assert(rnd_poly_valid(np)); + + hole++; + } + } + return np; +} + +typedef struct poly_tree poly_tree; + +struct poly_tree { + pcb_poly_t *polygon; + rnd_bool forward; + rnd_polyarea_t *polyarea; + poly_tree *parent; + poly_tree *child; + poly_tree *prev; + poly_tree *next; +}; + +/* + * ______ + * ___________________|_ P6 | +P1 ____ +P6 + * | P1 | | | | + * | _____ ____ |_|____| -P2 ____ -P4 ____ -P5 + * | |P2 | |P5 | | | + * | | [] | |____| | +P3 + * | | P3 | | + * | |_____| | + * | | + * | ___ | + * | |P4 | | + * | |___| | + * | | + * |_____________________| + * + * As we encounter each polygon, it gets a record. We need to check + * whether it contains any of the polygons existing in our tree. If + * it does, it will become the parent of them. (Check breadth first). + * + * When processing, work top down (breadth first), although if the + * contours can be assumed not to overlap, we can drill down in this + * order: P1, P2, P3, P4, P5, P6. + */ +static rnd_bool PolygonContainsPolygon(rnd_polyarea_t *outer, rnd_polyarea_t *inner) +{ +/* int contours_isect;*/ + /* Should check outer contours don't intersect? */ +/* contours_isect = rnd_polyarea_touching(outer, inner);*/ + /* Cheat and assume simple single contour polygons for now */ +/* return contours_isect ? + 0 : rnd_poly_contour_in_contour(outer->contours, inner->contours);*/ + return rnd_poly_contour_in_contour(outer->contours, inner->contours); +} + + +static poly_tree *insert_node_recursive(poly_tree * start_point, poly_tree * to_insert) +{ + poly_tree *cur_node, *next = NULL; +/* bool to_insert_isects_cur_node; Intersection */ + rnd_bool to_insert_contains_cur_node; /* Containment */ + rnd_bool cur_node_contains_to_insert; /* Containment */ + rnd_bool placed_to_insert = rnd_false; + + poly_tree *return_root = start_point; + + if (start_point == NULL) { +/* printf ("start_point is NULL, so returning to_insert\n"); + to_insert->parent = !!; UNDEFINED*/ + return to_insert; + } + + /* Investigate the start point and its peers first */ + for (cur_node = start_point; cur_node != NULL; cur_node = next) { + next = cur_node->next; + +/* to_insert_isects_cur_node = pcb_is_poly_in_poly(to_insert->polygon, cur_node->polygon);*/ + to_insert_contains_cur_node = PolygonContainsPolygon(to_insert->polyarea, cur_node->polyarea); + +#if 0 + printf("Inspecting polygon %ld %s, curnode is %ld %s: to_insert_isects_cur_node = %d, to_insert_contains_cur_node = %i\n", + to_insert->polygon->ID, + to_insert->forward ? "FWD" : "BWD", + cur_node->polygon->ID, cur_node->forward ? "FWD" : "BWD", to_insert_isects_cur_node, to_insert_contains_cur_node); + + if (to_insert_isects_cur_node) { /* Place as peer of this node? */ + } +#endif + + if (to_insert_contains_cur_node) { /* Should be a parent of this node */ + /* Remove cur_node from its peers */ + if (cur_node->prev) + cur_node->prev->next = cur_node->next; + if (cur_node->next) + cur_node->next->prev = cur_node->prev; + + /* If we've not yet got a home, insert the to_insert node where cur_node was previously */ + if (!placed_to_insert) { + to_insert->parent = cur_node->parent; + to_insert->next = cur_node->next; + to_insert->prev = cur_node->prev; + if (to_insert->prev) + to_insert->prev->next = to_insert; + if (to_insert->next) + to_insert->next->prev = to_insert; + placed_to_insert = rnd_true; + + if (cur_node == start_point) + return_root = to_insert; + } + + /* Prepend cur_node to our list of children */ + cur_node->parent = to_insert; + + cur_node->prev = NULL; + cur_node->next = to_insert->child; + if (to_insert->child) + to_insert->child->prev = cur_node; + to_insert->child = cur_node; + + } + } + + if (placed_to_insert) { +/* printf ("Returning new root %ld\n", return_root->polygon->ID);*/ + return return_root; + } +/* return (to_insert->parent == NULL) ? to_insert : to_insert->parent;*/ + + /* Ok, so we still didn't find anywhere which the to_insert contour contained, + * we need to start looking at the children of the start_point and its peers. + */ +/* printf ("Looking at child nodes of the start_point\n");*/ + + /* Investigate the start point and its peers first */ + for (cur_node = start_point; cur_node != NULL; cur_node = next) { + next = cur_node->next; + + cur_node_contains_to_insert = PolygonContainsPolygon(cur_node->polyarea, to_insert->polyarea); + +#if 0 + printf("Inspecting polygon %ld, curnode is %ld: cur_node_contains_to_insert = %d\n", + to_insert->polygon->ID, cur_node->polygon->ID, cur_node_contains_to_insert); +#endif + + /* Need to look at the child, ONLY if we know it engulfs our to_insert polygon */ + if (cur_node_contains_to_insert) { + /* Can't set the parent within the call, so: */ + to_insert->parent = cur_node; + cur_node->child = insert_node_recursive(cur_node->child, to_insert); + return start_point; + /*return cur_node->parent;*/ + } + } + +/* if (!placed_to_insert)*/ + /* prepend to_insert polygon to peer of start_point ? */ +/* printf ("Prepending as peer to start_poly\n");*/ + to_insert->parent = start_point->parent; + to_insert->prev = NULL; + to_insert->next = start_point; + to_insert->next->prev = to_insert; + + return to_insert; +} + +static rnd_polyarea_t *compute_polygon_recursive(poly_tree * root, rnd_polyarea_t * accumulate) +{ + rnd_polyarea_t *res; + poly_tree *cur_node; + for (cur_node = root; cur_node != NULL; cur_node = cur_node->next) { + /* Process this element */ +/* printf ("Processing node %ld %s\n", cur_node->polygon->ID, cur_node->forward ? "FWD" : "BWD");*/ + rnd_polyarea_boolean_free(accumulate, cur_node->polyarea, &res, cur_node->forward ? RND_PBO_UNITE : RND_PBO_SUB); + accumulate = res; + + /* And its children if it has them */ + if (cur_node->child) { +/* printf ("Processing children\n");*/ + accumulate = compute_polygon_recursive(cur_node->child, accumulate); + } + } + return accumulate; +} + +/* DOC: polycombine.html */ +static fgw_error_t pcb_act_polycombine(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_polyarea_t *rs; + rnd_bool forward; + rnd_polyarea_t *np; +/* bool outer; + rnd_polyarea_t *pa; + rnd_pline_t *pline; + rnd_vnode_t *node; + pcb_poly_t *Polygon;*/ + pcb_layer_t *Layer = NULL; + poly_tree *root = NULL; + poly_tree *this_node; + + /* First pass to combine the forward and backward contours */ + PCB_POLY_VISIBLE_LOOP(PCB->Data); + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, polygon)) + continue; + + /* Pick the layer of the first polygon we find selected */ + if (Layer == NULL) + Layer = layer; + + /* Only combine polygons on the same layer */ + if (Layer != layer) + continue; + + np = original_poly(polygon, &forward); + + /* Build a poly_tree record */ + this_node = calloc(1, sizeof(poly_tree)); + this_node->polygon = polygon; + this_node->forward = forward; + this_node->polyarea = np; + + /* Check where we should place the node in the tree */ + root = insert_node_recursive(root, this_node); + + /*pcb_poly_remove(layer, polygon);*/ + } + PCB_ENDALL_LOOP; + + /* Now perform a traversal of the tree, computing a polygon */ + rs = compute_polygon_recursive(root, NULL); + + pcb_undo_save_serial(); + + /* Second pass to remove the input polygons */ + PCB_POLY_VISIBLE_LOOP(PCB->Data); + { + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, polygon)) + continue; + + /* Only combine polygons on the same layer */ + if (Layer != layer) + continue; + + pcb_poly_remove(layer, polygon); + } + PCB_ENDALL_LOOP; + + /* Now de-construct the resulting polygon into raw PCB polygons */ + pcb_poly_to_polygons_on_layer(PCB->Data, Layer, rs, pcb_strflg_board_s2f("clearpoly", NULL)); + pcb_undo_restore_serial(); + pcb_undo_inc_serial(); + pcb_draw(); + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t polycombine_action_list[] = { + {"PolyCombine", pcb_act_polycombine, NULL, NULL} +}; + +char *polycombine_cookie = "polycombine plugin"; + +int pplg_check_ver_polycombine(int ver_needed) { return 0; } + +void pplg_uninit_polycombine(void) +{ + rnd_remove_actions_by_cookie(polycombine_cookie); +} + +int pplg_init_polycombine(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(polycombine_action_list, polycombine_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/polycombine/polycombine.pup =================================================================== --- tags/2.3.0/src_plugins/polycombine/polycombine.pup (nonexistent) +++ tags/2.3.0/src_plugins/polycombine/polycombine.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short combine selected polygons +$long The selected polygons are combined together according to the ordering of their points. +$state works +$package extra +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/polystitch/Makefile =================================================================== --- tags/2.3.0/src_plugins/polystitch/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/polystitch/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_polystitch + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/polystitch/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/polystitch/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/polystitch/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {polystitch} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/polystitch/polystitch.o @] + +switch /local/pcb/polystitch/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/polystitch/polystitch.c =================================================================== --- tags/2.3.0/src_plugins/polystitch/polystitch.c (nonexistent) +++ tags/2.3.0/src_plugins/polystitch/polystitch.c (revision 33253) @@ -0,0 +1,135 @@ +/* + * PolyStitch plug-in for PCB. + * + * Copyright (C) 2010 DJ Delorie + * + * Licensed under the terms of the GNU General Public + * License, version 2 or later. + * + * Ported to pcb-rnd by Tibor 'Igor2' Palinkas in 2016. + * Mostly rewritten for poly holes by Tibor 'Igor2' Palinkas in 2018. + * + * Original source: http://www.delorie.com/pcb/polystitch.c + */ + +#include +#include + +#include "config.h" +#include "board.h" +#include "data.h" +#include "remove.h" +#include +#include +#include +#include "draw.h" +#include "polygon.h" +#include +#include +#include "obj_poly.h" +#include "obj_poly_draw.h" + +/* Given the X,Y, find the inmost (closest) polygon */ +static pcb_poly_t *find_crosshair_poly(rnd_coord_t x, rnd_coord_t y) +{ + double best = 0, dist; + pcb_poly_t *res = NULL; + + PCB_POLY_VISIBLE_LOOP(PCB->Data); + { + /* layer, polygon */ + PCB_POLY_POINT_LOOP(polygon); + { + /* point */ + rnd_coord_t dx = x - point->X; + rnd_coord_t dy = y - point->Y; + dist = (double)dx * dx + (double)dy * dy; + if ((dist < best) || (res == NULL)) { + res = polygon; + best = dist; + } + } + PCB_END_LOOP; + } + PCB_ENDALL_LOOP; + + if (res == NULL) + rnd_message(RND_MSG_ERROR, "Cannot find any polygons"); + + return res; +} + +/* Set outer_poly to the enclosing poly. We assume there's only one. */ +static pcb_poly_t *find_enclosing_poly(pcb_poly_t *inner_poly) +{ + pcb_layer_t *poly_layer = inner_poly->parent.layer; + + PCB_POLY_LOOP(poly_layer); + { + if (polygon == inner_poly) + continue; + if (polygon->BoundingBox.X1 <= inner_poly->BoundingBox.X1 + && polygon->BoundingBox.X2 >= inner_poly->BoundingBox.X2 + && polygon->BoundingBox.Y1 <= inner_poly->BoundingBox.Y1 && polygon->BoundingBox.Y2 >= inner_poly->BoundingBox.Y2) { + return polygon; + } + } + PCB_END_LOOP; + + rnd_message(RND_MSG_ERROR, "Cannot find a polygon enclosing the one you selected"); + return NULL; +} + + +static fgw_error_t pcb_act_polystitch(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_coord_t x, y; + pcb_poly_t *inner_poly, *outer_poly; + + rnd_hid_get_coords("Select a corner on the inner polygon", &x, &y, 0); + inner_poly = find_crosshair_poly(x, y); + + if (inner_poly) { + outer_poly = find_enclosing_poly(inner_poly); + if (outer_poly) { + rnd_cardinal_t n, end; + + /* figure how many contour points the inner poly has (holes are going to be ignored) */ + if (inner_poly->HoleIndexN > 0) + end = inner_poly->HoleIndex[0]; + else + end = inner_poly->PointN; + + /* convert the inner poly into a hole */ + pcb_poly_hole_new(outer_poly); + for(n = 0; n < end; n++) + pcb_poly_point_new(outer_poly, inner_poly->Points[n].X, inner_poly->Points[n].Y); + pcb_poly_init_clip(PCB->Data, outer_poly->parent.layer, outer_poly); + pcb_poly_bbox(outer_poly); + + pcb_poly_remove(inner_poly->parent.layer, inner_poly); + } + } + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t polystitch_action_list[] = { + {"PolyStitch", pcb_act_polystitch, NULL, NULL} +}; + +char *polystitch_cookie = "polystitch plugin"; + +int pplg_check_ver_polystitch(int ver_needed) { return 0; } + +void pplg_uninit_polystitch(void) +{ + rnd_remove_actions_by_cookie(polystitch_cookie); +} + +int pplg_init_polystitch(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(polystitch_action_list, polystitch_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/polystitch/polystitch.pup =================================================================== --- tags/2.3.0/src_plugins/polystitch/polystitch.pup (nonexistent) +++ tags/2.3.0/src_plugins/polystitch/polystitch.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short stitch polygon at cursor +$long The polygon under the cursor (based on closest-corner) is stitched together with the polygon surrounding it on the same layer. Use with pstoedit conversions where there's a "hole" in the shape - select the hole. +$state works +$package extra +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/propedit/Makefile =================================================================== --- tags/2.3.0/src_plugins/propedit/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/propedit/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_propedit + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/propedit/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/propedit/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/propedit/Plug.tmpasm (revision 33253) @@ -0,0 +1,13 @@ +put /local/pcb/mod {propedit} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/propedit/propedit.o + $(PLUGDIR)/propedit/props.o + $(PLUGDIR)/propedit/propsel.o + $(PLUGDIR)/propedit/propdlg.o +@] + +switch /local/pcb/propedit/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/propedit/propdlg.c =================================================================== --- tags/2.3.0/src_plugins/propedit/propdlg.c (nonexistent) +++ tags/2.3.0/src_plugins/propedit/propdlg.c (revision 33253) @@ -0,0 +1,734 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include +#include +#include +#include +#include "netlist.h" + +#include "props.h" +#include "propsel.h" + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + pcb_propedit_t pe; + int wtree, wfilter, wtype, wvals, wscope; + int wabs[PCB_PROPT_max], wedit[PCB_PROPT_max]; + gdl_elem_t link; +} propdlg_t; + +gdl_list_t propdlgs; + +static void prop_refresh(propdlg_t *ctx); + +static void propdlgclose_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + propdlg_t *ctx = caller_data; + gdl_remove(&propdlgs, ctx, link); + pcb_props_uninit(&ctx->pe); + RND_DAD_FREE(ctx->dlg); + free(ctx); +} + +static void prop_filter_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_ign) +{ + propdlg_t *ctx = caller_data; + rnd_hid_attribute_t *attr, *attr_inp; + rnd_hid_tree_t *tree; + const char *text; + int have_filter_text; + + attr = &ctx->dlg[ctx->wtree]; + attr_inp = &ctx->dlg[ctx->wfilter]; + tree = attr->wdata; + text = attr_inp->val.str; + have_filter_text = (text != NULL) && (*text != '\0'); + + /* hide or unhide everything */ + rnd_dad_tree_hide_all(tree, &tree->rows, have_filter_text); + + if (have_filter_text) /* unhide hits and all their parents */ + rnd_dad_tree_unhide_filter(tree, &tree->rows, 0, text); + + rnd_dad_tree_update_hide(attr); +} + +static void prop_pcb2dlg(propdlg_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + rnd_hid_tree_t *tree = attr->wdata; + rnd_hid_row_t *r; + htsp_entry_t *sorted, *e; + char *cursor_path = NULL; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->path); + + rnd_dad_tree_clear(tree); + + pcb_props_clear(&ctx->pe); + pcb_propsel_map_core(&ctx->pe); + sorted = pcb_props_sort(&ctx->pe); + for(e = sorted; e->key != NULL; e++) { + char *cell[6] = {NULL}; + pcb_props_t *p = e->value; + pcb_propval_t com, min, max, avg; + + if (p->type == PCB_PROPT_STRING) { + pcb_props_stat(&ctx->pe, p, &com, NULL, NULL, NULL); + } + else { + pcb_props_stat(&ctx->pe, p, &com, &min, &max, &avg); + cell[2] = pcb_propsel_printval(p->type, &min); + cell[3] = pcb_propsel_printval(p->type, &max); + cell[4] = pcb_propsel_printval(p->type, &avg); + } + + cell[0] = rnd_strdup(e->key); + cell[1] = pcb_propsel_printval(p->type, &com); + + r = rnd_dad_tree_mkdirp(tree, cell[0], cell); + r->user_data = e->key; + } + free(sorted); + prop_filter_cb(ctx->dlg_hid_ctx, ctx, NULL); + + rnd_dad_tree_expcoll(attr, NULL, 1, 1); + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtree, &hv); + free(cursor_path); + } + + /* set scope */ + { + rnd_hid_attr_val_t hv; + gds_t scope; + int n, inv; + long *l; + pcb_idpath_t *idp; + + gds_init(&scope); + if (ctx->pe.board) + gds_append_str(&scope, "board, "); + if (ctx->pe.selection) + gds_append_str(&scope, "selected objects, "); + inv = 0; + for(n = 0, l = ctx->pe.layers.array; n < vtl0_len(&ctx->pe.layers); n++, l++) { + const char *name = pcb_layer_name(ctx->pe.data, *l); + if (name != 0) { + gds_append_str(&scope, "layer: "); + gds_append_str(&scope, name); + gds_append_str(&scope, ", "); + } + else + inv++; + } + if (inv > 0) + rnd_append_printf(&scope, "%d invalid layers, ", inv); + inv = 0; + for(n = 0, l = ctx->pe.layergrps.array; n < vtl0_len(&ctx->pe.layergrps); n++, l++) { + const char *name = pcb_layergrp_name(ctx->pe.pcb, *l); + if (name != 0) { + gds_append_str(&scope, "layergrp: "); + gds_append_str(&scope, name); + gds_append_str(&scope, ", "); + } + else + inv++; + } + if (inv > 0) + rnd_append_printf(&scope, "%d invalid layer groups, ", inv); + + if (ctx->pe.nets_inited) { + htsp_entry_t *e; + inv = 0; + for(e = htsp_first(&ctx->pe.nets); e != NULL; e = htsp_next(&ctx->pe.nets, e)) { + if (pcb_net_get(ctx->pe.pcb, &ctx->pe.pcb->netlist[PCB_NETLIST_EDITED], e->key, 0) != NULL) { + gds_append_str(&scope, "net: "); + gds_append_str(&scope, e->key); + gds_append_str(&scope, ", "); + } + else + inv++; + } + if (inv > 0) + rnd_append_printf(&scope, "%d invalid nets, ", inv); + } + + inv = 0; + for(idp = pcb_idpath_list_first(&ctx->pe.objs); idp != NULL; idp = pcb_idpath_list_next(idp)) { + pcb_any_obj_t *o = pcb_idpath2obj_in(ctx->pe.data, idp); + if (o != NULL) + rnd_append_printf(&scope, "%s #%ld, ", pcb_obj_type_name(o->type), o->ID); + else + inv++; + } + if (inv > 0) + rnd_append_printf(&scope, "%d invalid objects, ", inv); + + gds_truncate(&scope, gds_len(&scope)-2); + + hv.str = scope.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wscope, &hv); + } +} + +static void prop_prv_expose_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_gc_t gc, const rnd_hid_expose_ctx_t *e) +{ + +} + + +static rnd_bool prop_prv_mouse_cb(rnd_hid_attribute_t *attrib, rnd_hid_preview_t *prv, rnd_hid_mouse_ev_t kind, rnd_coord_t x, rnd_coord_t y) +{ + return rnd_false; /* don't redraw */ +} + +static void prop_valedit_update(propdlg_t *ctx, pcb_props_t *p, pcb_propval_t *pv) +{ + rnd_hid_attr_val_t hv; + + /* do not update the value if widget is numeric and the user wants a relative value */ + switch(p->type) { + case PCB_PROPT_COORD: + case PCB_PROPT_ANGLE: + case PCB_PROPT_DOUBLE: + case PCB_PROPT_INT: + if (!ctx->dlg[ctx->wabs[p->type]].val.lng) + return; + default: break; + } + + + memset(&hv, 0, sizeof(hv)); + switch(p->type) { + case PCB_PROPT_STRING: hv.str = rnd_strdup(pv->string == NULL ? "" : pv->string); break; + case PCB_PROPT_COORD: hv.crd = pv->coord; break; + case PCB_PROPT_ANGLE: hv.dbl = pv->angle; break; + case PCB_PROPT_DOUBLE: hv.dbl = pv->d; break; + case PCB_PROPT_BOOL: + case PCB_PROPT_INT: hv.lng = pv->i; break; + case PCB_PROPT_COLOR: hv.clr = pv->clr; break; + case PCB_PROPT_invalid: + case PCB_PROPT_max: return; + } + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wedit[p->type], &hv); +} + +typedef struct { + pcb_propval_t *val; + unsigned int cnt; +} pvsort_t; + +static int sort_pv(const void *pv1_, const void *pv2_) +{ + const pvsort_t *pv1 = pv1_, *pv2 = pv2_; + return pv1->cnt > pv2->cnt ? -1 : +1; +} + +static void prop_vals_update(propdlg_t *ctx, pcb_props_t *p) +{ + rnd_hid_attr_val_t hv; + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wvals]; + rnd_hid_tree_t *tree = attr->wdata; + htprop_entry_t *e; + pvsort_t *pvs; + char *cell[3] = {NULL, NULL, NULL}; + int n; + + rnd_dad_tree_clear(tree); + + if (p == NULL) { /* deselect or not found */ + hv.lng = 0; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtype, &hv); + return; + } + + /* get a sorted list of all values, by frequency */ + pvs = malloc(sizeof(pvsort_t) * p->values.used); + for (e = htprop_first(&p->values), n = 0; e; e = htprop_next(&p->values, e), n++) { + pvs[n].val = &e->key; + pvs[n].cnt = e->value; + } + qsort(pvs, p->values.used, sizeof(pvsort_t), sort_pv); + + for(n = 0; n < p->values.used; n++) { + rnd_hid_row_t *r; + cell[0] = rnd_strdup_printf("%ld", pvs[n].cnt); + cell[1] = pcb_propsel_printval(p->type, pvs[n].val); + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data = pvs[n].val; + } + + hv.lng = p->type; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wtype, &hv); + + prop_valedit_update(ctx, p, pvs[0].val); + + free(pvs); +} + +static void prop_select_node_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + propdlg_t *ctx = tree->user_ctx; + pcb_props_t *p = NULL; + + if (row != NULL) + p = pcb_props_get(&ctx->pe, row->user_data); + + prop_vals_update(ctx, p); +} + + +static void prop_data_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr, int force_update) +{ + propdlg_t *ctx = caller_data; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wtree]); + pcb_props_t *p = NULL; + pcb_propset_ctx_t sctx; + + if (r == NULL) + return; + p = pcb_props_get(&ctx->pe, r->user_data); + if (p == NULL) + return; + + memset(&sctx, 0, sizeof(sctx)); + switch(p->type) { + case PCB_PROPT_invalid: + case PCB_PROPT_max: + return; + case PCB_PROPT_STRING: + sctx.s = ctx->dlg[ctx->wedit[p->type]].val.str; + break; + case PCB_PROPT_COORD: + sctx.c = ctx->dlg[ctx->wedit[p->type]].val.crd; + sctx.c_absolute = ctx->dlg[ctx->wabs[p->type]].val.lng; + sctx.c_valid = 1; + break; + case PCB_PROPT_ANGLE: + sctx.d = ctx->dlg[ctx->wedit[p->type]].val.dbl; + sctx.d_absolute = ctx->dlg[ctx->wabs[p->type]].val.lng; + sctx.d_valid = 1; + break; + case PCB_PROPT_DOUBLE: + sctx.d = ctx->dlg[ctx->wedit[p->type]].val.dbl; + sctx.d_absolute = ctx->dlg[ctx->wabs[p->type]].val.lng; + sctx.d_valid = 1; + break; + case PCB_PROPT_INT: + sctx.c = ctx->dlg[ctx->wedit[p->type]].val.lng; + sctx.c_absolute = ctx->dlg[ctx->wabs[p->type]].val.lng; + sctx.c_valid = 1; + break; + case PCB_PROPT_BOOL: + sctx.c = ctx->dlg[ctx->wedit[p->type]].val.lng; + sctx.c_absolute = ctx->dlg[ctx->wabs[p->type]].val.lng; + sctx.c_valid = 1; + break; + case PCB_PROPT_COLOR: + sctx.color = ctx->dlg[ctx->wedit[p->type]].val.clr; + sctx.clr_valid = 1; + break; + } + + if (force_update || ctx->dlg[ctx->wabs[p->type]].val.lng) { + pcb_propsel_set(&ctx->pe, r->user_data, &sctx); + prop_refresh(ctx); + rnd_gui->invalidate_all(rnd_gui); + } +} + +static void prop_data_auto_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + prop_data_cb(hid_ctx, caller_data, attr, 0); +} + +static void prop_data_force_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + prop_data_cb(hid_ctx, caller_data, attr, 1); +} + + +static void prop_add_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + RND_DAD_DECL(dlg) + propdlg_t *ctx = caller_data; + const char *key; + int wkey, wval, failed; + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"OK", 0}, {NULL, 0}}; + + RND_DAD_BEGIN_VBOX(dlg); + RND_DAD_BEGIN_TABLE(dlg, 2); + RND_DAD_COMPFLAG(dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(dlg, "Attribute key:"); + RND_DAD_STRING(dlg); + wkey = RND_DAD_CURRENT(dlg); + RND_DAD_LABEL(dlg, "Attribute value:"); + RND_DAD_STRING(dlg); + wval = RND_DAD_CURRENT(dlg); + RND_DAD_END(dlg); + RND_DAD_BUTTON_CLOSES(dlg, clbtn); + RND_DAD_END(dlg); + RND_DAD_AUTORUN("propedit_add", dlg, "Propedit: add new attribute", NULL, failed); + + key = dlg[wkey].val.str; + if (key == NULL) key = ""; + while(isspace(*key)) key++; + + if ((failed == 0) && (*key != '\0')) { + char *path = rnd_strdup_printf("a/%s", key); + pcb_propsel_set_str(&ctx->pe, path, dlg[wval].val.str); + free(path); + prop_refresh(ctx); + } + RND_DAD_FREE(dlg); +} + +static void prop_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + propdlg_t *ctx = caller_data; + rnd_hid_row_t *r = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wtree]); + if (r == NULL) { + rnd_message(RND_MSG_ERROR, "can not delete: no attribute selected\n"); + return; + } + if (r->path[0] != 'a') { + rnd_message(RND_MSG_ERROR, "Only atributes (a/ subtree) can be deleted.\n"); + return; + } + if (pcb_propsel_del(&ctx->pe, r->path) < 1) { + rnd_message(RND_MSG_ERROR, "Failed to remove the attribute from any object.\n"); + return; + } + prop_refresh(ctx); +} + +static void prop_preset_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + propdlg_t *ctx = caller_data; + rnd_hid_row_t *rv = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wvals]); + rnd_hid_row_t *rp = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wtree]); + pcb_props_t *p; + + if ((rv == NULL) || (rv->user_data == NULL) || (rp == NULL)) + return; + + p = pcb_props_get(&ctx->pe, rp->user_data); + if (p != NULL) + prop_valedit_update(ctx, p, rv->user_data); +} + + +static void prop_refresh_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + prop_refresh((propdlg_t *)caller_data); +} + + +static void prop_refresh(propdlg_t *ctx) +{ + rnd_hid_attribute_t *attr = &ctx->dlg[ctx->wtree]; + prop_pcb2dlg(ctx); + prop_select_node_cb(attr, ctx->dlg_hid_ctx, rnd_dad_tree_get_selected(attr)); +} + + +static void build_propval(propdlg_t *ctx) +{ + static const char *type_tabs[] = {"none", "string", "coord", "angle", "double", "int", NULL}; + static const char *abshelp = "When unticked each apply is a relative change added to\nthe current value of each object"; + + RND_DAD_BEGIN_TABBED(ctx->dlg, type_tabs); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE_TABLAB); + ctx->wtype = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "(nothing to edit)"); + ctx->wabs[0] = 0; + ctx->wedit[0] = 0; + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: string"); + RND_DAD_STRING(ctx->dlg); + ctx->wedit[1] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_ENTER_CB(ctx->dlg, prop_data_auto_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wabs[1] = 0; + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: coord"); + RND_DAD_COORD(ctx->dlg); + ctx->wedit[2] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -RND_MAX_COORD, RND_MAX_COORD); + RND_DAD_ENTER_CB(ctx->dlg, prop_data_auto_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "abs"); + RND_DAD_BOOL(ctx->dlg); + ctx->wabs[2] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, abshelp); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: angle"); + RND_DAD_REAL(ctx->dlg); + ctx->wedit[3] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -360.0, +360.0); + RND_DAD_ENTER_CB(ctx->dlg, prop_data_auto_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "abs"); + RND_DAD_BOOL(ctx->dlg); + ctx->wabs[3] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, abshelp); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: double"); + RND_DAD_REAL(ctx->dlg); + ctx->wedit[4] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -1000, +1000); + RND_DAD_ENTER_CB(ctx->dlg, prop_data_auto_cb); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "abs"); + RND_DAD_BOOL(ctx->dlg); + ctx->wabs[4] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, abshelp); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: int"); + RND_DAD_INTEGER(ctx->dlg); + ctx->wedit[5] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_ENTER_CB(ctx->dlg, prop_data_auto_cb); + RND_DAD_MINMAX(ctx->dlg, -(1<<30), 1<<30); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "abs"); + RND_DAD_BOOL(ctx->dlg); + ctx->wabs[5] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, abshelp); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: boolean"); + RND_DAD_BOOL(ctx->dlg); + ctx->wedit[6] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wabs[6] = 0; + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Data type: color"); + RND_DAD_COLOR(ctx->dlg); + ctx->wedit[7] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wabs[7] = 0; + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "apply"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_data_force_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_END(ctx->dlg); +} + +static void pcb_dlg_propdlg(propdlg_t *ctx) +{ + const char *hdr[] = {"property", "common", "min", "max", "avg", NULL}; + const char *hdr_val[] = {"use", "values"}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + static rnd_box_t prvbb = {0, 0, RND_MM_TO_COORD(10), RND_MM_TO_COORD(10)}; + int n; + rnd_hid_attr_val_t hv; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(ctx->dlg); + + /* left: property tree and filter */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 5, 1, hdr); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + ctx->wtree = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, prop_select_node_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_STRING(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "Filter text:\nlist properties with\nmatching name only"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_filter_cb); + ctx->wfilter = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "add"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_add_cb); + RND_DAD_HELP(ctx->dlg, "Create a new attribute\n(in the a/ subtree)"); + RND_DAD_BUTTON(ctx->dlg, "del"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_del_cb); + RND_DAD_HELP(ctx->dlg, "Remove the selected attribute\n(from the a/ subtree)"); + RND_DAD_BUTTON(ctx->dlg, "rfr"); + RND_DAD_CHANGE_CB(ctx->dlg, prop_refresh_cb); + RND_DAD_HELP(ctx->dlg, "Refresh: rebuild the tree\nupdating all values from the board"); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + /* right: preview and per type edit */ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_PREVIEW(ctx->dlg, prop_prv_expose_cb, prop_prv_mouse_cb, NULL, NULL, &prvbb, 100, 100, ctx); + RND_DAD_END(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, ""); + ctx->wscope = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_HELP(ctx->dlg, "Scope: list of objects affected"); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_TREE(ctx->dlg, 2, 0, hdr_val); + ctx->wvals = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, prop_preset_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + build_propval(ctx); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_NEW("propedit", ctx->dlg, "Property editor", ctx, rnd_false, propdlgclose_cb); + + prop_refresh(ctx); + gdl_append(&propdlgs, ctx, link); + + /* default all abs */ + hv.lng = 1; + for(n = 0; n < PCB_PROPT_max; n++) + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wabs[n], &hv); +} + +extern int prop_scope_add(pcb_propedit_t *pe, const char *cmd, int quiet); + +const char pcb_acts_propedit[] = "propedit(object[:id]|layer[:id]|layergrp[:id]|pcb|subc|selection|selected)\n"; +const char pcb_acth_propedit[] = ""; +fgw_error_t pcb_act_propedit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + propdlg_t *ctx = calloc(sizeof(propdlg_t), 1); + int a, r; + + pcb_props_init(&ctx->pe, PCB); + + if (argc > 1) { + for(a = 1; a < argc; a++) { + const char *cmd; + RND_ACT_CONVARG(a, FGW_STR, propedit, cmd = argv[a].val.str); + r = prop_scope_add(&ctx->pe, cmd, 0); + if (r != 0) + return r; + } + } + else + ctx->pe.selection = 1; + + pcb_dlg_propdlg(ctx); + return 0; +} + +static void propdlg_unit_change(rnd_conf_native_t *cfg, int arr_idx) +{ + propdlg_t *ctx; + gdl_iterator_t it; + + gdl_foreach(&propdlgs, &it, ctx) { + prop_pcb2dlg(ctx); + } +} + +static rnd_conf_hid_id_t propdlg_conf_id; +static const char *propdlg_cookie = "propdlg"; +void pcb_propdlg_init(void) +{ + static rnd_conf_hid_callbacks_t cbs; + rnd_conf_native_t *n = rnd_conf_get_field("editor/grid_unit"); + propdlg_conf_id = rnd_conf_hid_reg(propdlg_cookie, NULL); + + if (n != NULL) { + cbs.val_change_post = propdlg_unit_change; + rnd_conf_hid_set_cb(n, propdlg_conf_id, &cbs); + } +} + +void pcb_propdlg_uninit(void) +{ + rnd_conf_hid_unreg(propdlg_cookie); +} Index: tags/2.3.0/src_plugins/propedit/propdlg.h =================================================================== --- tags/2.3.0/src_plugins/propedit/propdlg.h (nonexistent) +++ tags/2.3.0/src_plugins/propedit/propdlg.h (revision 33253) @@ -0,0 +1,13 @@ +#ifndef PCB_PROPDLG_H +#define PCB_PROPDLG_H + +#include + +extern const char pcb_acts_propedit[]; +extern const char pcb_acth_propedit[]; +fgw_error_t pcb_act_propedit(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void pcb_propdlg_init(void); +void pcb_propdlg_uninit(void); + +#endif Index: tags/2.3.0/src_plugins/propedit/propedit.c =================================================================== --- tags/2.3.0/src_plugins/propedit/propedit.c (nonexistent) +++ tags/2.3.0/src_plugins/propedit/propedit.c (revision 33253) @@ -0,0 +1,403 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include "board.h" +#include "data.h" +#include +#include "config.h" +#include "props.h" +#include "propsel.h" +#include "propdlg.h" +#include +#include +#include +#include "layer.h" +#include "layer_addr.h" +#include "layer_grp.h" +#include "search.h" +#include "crosshair.h" +#include + +extern rnd_layergrp_id_t pcb_actd_EditGroup_gid; + +int prop_scope_add(pcb_propedit_t *pe, const char *cmd, int quiet) +{ + pcb_idpath_t *idp; + long id; + void *o2; + + + if (strcmp(cmd, "subc") == 0) { + void *o1, *o3; + pcb_objtype_t type = pcb_search_obj_by_location(PCB_OBJ_SUBC, &o1, &o2, &o3, pcb_crosshair.X, pcb_crosshair.Y, PCB_SLOP); + if (type == 0) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "No object under the cursor\n"); + return FGW_ERR_ARG_CONV; + } + goto object_scope; + } + if (strncmp(cmd, "object", 6) == 0) { + if (cmd[6] == ':') { + idp = pcb_str2idpath(pe->pcb, cmd+7); + if (idp == NULL) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Failed to convert object ID: '%s'\n", cmd+7); + return FGW_ERR_ARG_CONV; + } + pcb_idpath_list_append(&pe->objs, idp); + } + else { + void *o1, *o3; + pcb_objtype_t type; + + type = pcb_search_obj_by_location(PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART, &o1, &o2, &o3, pcb_crosshair.X, pcb_crosshair.Y, PCB_SLOP); + if (type == 0) + type = pcb_search_obj_by_location(PCB_OBJ_CLASS_REAL | PCB_LOOSE_SUBC(pe->pcb), &o1, &o2, &o3, pcb_crosshair.X, pcb_crosshair.Y, PCB_SLOP); + if (type == 0) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "No object under the cursor\n"); + return FGW_ERR_ARG_CONV; + } + object_scope:; + idp = pcb_obj2idpath(o2); + if (idp == NULL) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Object under the cursor has no idpath\n"); + return FGW_ERR_ARG_CONV; + } + pcb_idpath_list_append(&pe->objs, idp); + } + } + else if (strncmp(cmd, "layergrp", 8) == 0) { + if (cmd[8] == ':') { + if (strcmp(cmd+9, "editgroup") != 0) { + id = pcb_layergrp_str2id(pe->pcb, cmd+9); + if (id < 0) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Invalid layergrp ID '%s'\n", cmd+9); + return FGW_ERR_ARG_CONV; + } + } + else + id = pcb_actd_EditGroup_gid; + vtl0_append(&pe->layergrps, id); + } + else { + vtl0_append(&pe->layergrps, PCB_CURRLAYER(PCB)->meta.real.grp); + } + } + else if (strncmp(cmd, "layer", 5) == 0) { + if (cmd[5] == ':') { + id = pcb_layer_str2id(pe->data, cmd+6); + if (id < 0) { + if (!quiet) + rnd_message(RND_MSG_ERROR, "Invalid layer ID '%s'\n", cmd+6); + return FGW_ERR_ARG_CONV; + } + vtl0_append(&pe->layers, id); + } + else { + vtl0_append(&pe->layers, PCB_CURRLID(pe->pcb)); + } + } + else if (strncmp(cmd, "net:", 4) == 0) { + char *name = rnd_strdup(cmd+4); + if (!pe->nets_inited) { + htsp_init(&pe->nets, strhash, strkeyeq); + pe->nets_inited = 1; + } + htsp_set(&pe->nets, name, name); + } + else if ((strcmp(cmd, "board") == 0) || (strcmp(cmd, "pcb") == 0)) + pe->board = 1; + else if (strcmp(cmd, "selection") == 0) + pe->selection = 1; + else if (strcmp(cmd, "geo") == 0) + pe->geo = 1; + else { + char *end; + pcb_idpath_t *idp = (void *)strtol(cmd, &end, 0); + if ((*end == '\0') && (idp != NULL) && (htpp_get(&rnd_fgw.ptr_tbl, idp) == RND_PTR_DOMAIN_IDPATH)) { + pcb_idpath_list_append(&pe->objs, idp); + return 0; + } + if (!quiet) + rnd_message(RND_MSG_ERROR, "Invalid scope: %s\n", cmd); + return FGW_ERR_ARG_CONV; + } + return 0; +} + +/* pair of prop_scope_add() - uninits the scope */ +static void prop_scope_finish(pcb_propedit_t *pe) +{ + pcb_idpath_t *idp; + + /* need to remove idpaths from the scope list, else it won't be possible + to add them again */ + while((idp = pcb_idpath_list_first(&pe->objs)) != NULL) + pcb_idpath_list_remove(idp); + + if (pe->nets_inited) { + htsp_entry_t *e; + for(e = htsp_first(&pe->nets); e != NULL; e = htsp_next(&pe->nets, e)) + free(e->key); + htsp_uninit(&pe->nets); + pe->nets_inited = 0; + } +} + +extern rnd_layergrp_id_t pcb_actd_EditGroup_gid; + +static const char pcb_acts_propset[] = "propset([scope], name, value)"; +static const char pcb_acth_propset[] = "Change the named property of scope or all selected objects to/by value. Scope is documented at PropEdit()."; +fgw_error_t pcb_act_propset(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *first, *name, *val; + pcb_propedit_t ctx; + + pcb_props_init(&ctx, PCB); + + RND_ACT_CONVARG(1, FGW_STR, propset, first = argv[1].val.str); + if (prop_scope_add(&ctx, first, 1) == 0) { + RND_ACT_CONVARG(2, FGW_STR, propset, name = argv[2].val.str); + RND_ACT_CONVARG(3, FGW_STR, propset, val = argv[3].val.str); + } + else { + name = first; + ctx.selection = 1; + RND_ACT_CONVARG(2, FGW_STR, propset, val = argv[2].val.str); + } + + RND_ACT_IRES(pcb_propsel_set_str(&ctx, name, val)); + + prop_scope_finish(&ctx); + pcb_props_uninit(&ctx); + return 0; +} + +static const char pcb_acts_proptoggle[] = "proptoggle([scope], name, [create])"; +static const char pcb_acth_proptoggle[] = "Toggle the named property of scope or all selected objects, assuming the property is boolean. Scope is documented at PropEdit(). If create is true, non-existing attributes are created as true."; +fgw_error_t pcb_act_proptoggle(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *first, *name, *create = NULL; + pcb_propedit_t ctx; + + pcb_props_init(&ctx, PCB); + + RND_ACT_CONVARG(1, FGW_STR, proptoggle, first = argv[1].val.str); + if (prop_scope_add(&ctx, first, 1) == 0) { + RND_ACT_CONVARG(2, FGW_STR, proptoggle, name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, proptoggle, create = argv[3].val.str); + } + else { + name = first; + RND_ACT_MAY_CONVARG(2, FGW_STR, proptoggle, create = argv[2].val.str); + ctx.selection = 1; + } + + RND_ACT_IRES(pcb_propsel_toggle(&ctx, name, rnd_istrue(create))); + + prop_scope_finish(&ctx); + pcb_props_uninit(&ctx); + return 0; +} + +static const char pcb_acts_propget[] = "propget([scope], name, [stattype])"; +static const char pcb_acth_propget[] = "Return the named property of scope or all selected objects to/by value. Scope is documented at PropEdit()."; +fgw_error_t pcb_act_propget(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *first, *name, *stty = "common"; + pcb_propedit_t ctx; + pcb_props_t *p; + pcb_propval_t *out, most_common, min, max, avg; + htprop_entry_t *e; + int r; + + pcb_props_init(&ctx, PCB); + + RND_ACT_CONVARG(1, FGW_STR, propget, first = argv[1].val.str); + if (prop_scope_add(&ctx, first, 1) == 0) { + RND_ACT_CONVARG(2, FGW_STR, propget, name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, propget, stty = argv[3].val.str); + } + else { + name = first; + ctx.selection = 1; + RND_ACT_CONVARG(2, FGW_STR, propget, stty = argv[2].val.str); + } + + ctx.geo = 1; + pcb_propsel_map_core(&ctx); + + p = htsp_get(&ctx.props, name); + if (p == NULL) + goto error; + + if (p->type == PCB_PROPT_STRING) + r = pcb_props_stat(&ctx, p, &most_common, NULL, NULL, NULL); + else + r = pcb_props_stat(&ctx, p, &most_common, &min, &max, &avg); + + if (r != 0) + goto error; + + if (strcmp(stty, "common") == 0) out = &most_common; + else if (strcmp(stty, "min") == 0) out = &min; + else if (strcmp(stty, "max") == 0) out = &max; + else if (strcmp(stty, "avg") == 0) out = &avg; + else goto error; + + switch(p->type) { + case PCB_PROPT_STRING: + if (out != &most_common) + goto error; + + /* get the first one for now */ + e = htprop_first(&p->values); + most_common = e->key; + res->type = FGW_STR | FGW_DYN; + res->val.str = rnd_strdup(out->string == NULL ? "" : out->string); + break; + case PCB_PROPT_COORD: res->type = FGW_COORD; fgw_coord(res) = out->coord; break; + case PCB_PROPT_ANGLE: res->type = FGW_DOUBLE; res->val.nat_double = out->angle; break; + case PCB_PROPT_DOUBLE: res->type = FGW_DOUBLE; res->val.nat_double = out->d; break; + case PCB_PROPT_BOOL: + case PCB_PROPT_INT: res->type = FGW_INT; res->val.nat_int = out->i; break; + case PCB_PROPT_COLOR: res->type = FGW_STR | FGW_DYN; res->val.str = rnd_strdup(out->clr.str); break; + case PCB_PROPT_invalid: + case PCB_PROPT_max: goto error; + } + prop_scope_finish(&ctx); + pcb_props_uninit(&ctx); + return 0; + + error:; + prop_scope_finish(&ctx); + pcb_props_uninit(&ctx); + return FGW_ERR_ARG_CONV; +} + +static const char pcb_acts_propprint[] = "PropPrint([scope])"; +static const char pcb_acth_propprint[] = "Print a property map of objects matching the scope. Scope is documented at PropEdit()."; +fgw_error_t pcb_act_propprint(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *scope = NULL; + pcb_propedit_t ctx; + htsp_entry_t *e, *sorted; + + pcb_props_init(&ctx, PCB); + + RND_ACT_MAY_CONVARG(1, FGW_STR, propprint, scope = argv[1].val.str); + if (scope != NULL) { + if (prop_scope_add(&ctx, scope, 0) != 0) + return FGW_ERR_ARG_CONV; + } + else + ctx.selection = 1; + + pcb_propsel_map_core(&ctx); + sorted = pcb_props_sort(&ctx); + for(e = sorted; e->key != NULL; e++) { + pcb_props_t *p = e->value; + pcb_propval_t com, min, max, avg; + + printf("%s\n", e->key); + if (p->type == PCB_PROPT_STRING) + pcb_props_stat(&ctx, p, &com, NULL, NULL, NULL); + else + pcb_props_stat(&ctx, p, &com, &min, &max, &avg); + switch(p->type) { + case PCB_PROPT_STRING: printf(" common='%s'\n", com.string); break; + case PCB_PROPT_COORD: + rnd_printf(" common='%$$mm'\n", com.coord); + rnd_printf(" min/avg/max=%$$mm/%$$mm/%$$mm\n", min.coord, avg.coord, max.coord); + break; + case PCB_PROPT_ANGLE: + rnd_printf(" common='%f'\n", com.angle); + rnd_printf(" min/avg/max=%f/%f/%f\n", min.angle, avg.angle, max.angle); + break; + case PCB_PROPT_DOUBLE: + rnd_printf(" common='%f'\n", com.d); + rnd_printf(" min/avg/max=%f/%f/%f\n", min.d, avg.d, max.d); + break; + case PCB_PROPT_INT: + case PCB_PROPT_BOOL: + rnd_printf(" common='%d'\n", com.i); + rnd_printf(" min/avg/max=%d/%d/%d\n", min.i, avg.i, max.i); + break; + case PCB_PROPT_COLOR: printf(" common=#%02d%02d%02d\n", com.clr.r, com.clr.g, com.clr.b); break; + case PCB_PROPT_invalid: + case PCB_PROPT_max: + break; + } + } + free(sorted); + + prop_scope_finish(&ctx); + pcb_props_uninit(&ctx); + RND_ACT_IRES(0); + return 0; +} + +static const char *propedit_cookie = "propedit"; + +rnd_action_t propedit_action_list[] = { + {"propedit", pcb_act_propedit, pcb_acth_propedit, pcb_acts_propedit}, + {"propprint", pcb_act_propprint, pcb_acth_propprint, pcb_acts_propprint}, + {"propset", pcb_act_propset, pcb_acth_propset, pcb_acts_propset}, + {"proptoggle", pcb_act_proptoggle, pcb_acth_proptoggle, pcb_acts_proptoggle}, + {"propget", pcb_act_propget, pcb_acth_propget, pcb_acts_propget} +}; + +int pplg_check_ver_propedit(int ver_needed) { return 0; } + +void pplg_uninit_propedit(void) +{ + pcb_propdlg_uninit(); + rnd_remove_actions_by_cookie(propedit_cookie); +} + +int pplg_init_propedit(void) +{ + RND_API_CHK_VER; + + if (sizeof(long) < sizeof(rnd_layer_id_t)) { + rnd_message(RND_MSG_ERROR, "can't load propedig: layer id type wider than long\n"); + return -1; + } + + if (sizeof(long) < sizeof(rnd_layergrp_id_t)) { + rnd_message(RND_MSG_ERROR, "can't load propedig: layergrp id type wider than long\n"); + return -1; + } + + RND_REGISTER_ACTIONS(propedit_action_list, propedit_cookie) + pcb_propdlg_init(); + return 0; +} Index: tags/2.3.0/src_plugins/propedit/propedit.pup =================================================================== --- tags/2.3.0/src_plugins/propedit/propedit.pup (nonexistent) +++ tags/2.3.0/src_plugins/propedit/propedit.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short object property editor +$long List and edit properties of a group of objects. +$state works +$package (core) +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/propedit/props.c =================================================================== --- tags/2.3.0/src_plugins/propedit/props.c (nonexistent) +++ tags/2.3.0/src_plugins/propedit/props.c (revision 33253) @@ -0,0 +1,270 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ +#include "config.h" +#include "props.h" +#include "propsel.h" +#include +#include "board.h" +#include +#include +#include +/*#define HT_INVALID_VALUE ((pcb_propval_t){PCB_PROPT_invalid, {0}})*/ +#define HT(x) htprop_ ## x +#include +#undef HT + +/* Type names in text */ +static const char *type_names[] = { "invalid", "string", "coord", "angle", "double", "int" }; + +/* A hash function for each known type */ +static unsigned int prophash_coord(pcb_propval_t key) { return longhash(key.coord); } +static unsigned int prophash_angle(pcb_propval_t key) { return longhash(key.angle); } +static unsigned int prophash_double(pcb_propval_t key) { return longhash(key.d); } +static unsigned int prophash_int(pcb_propval_t key) { return longhash(key.i); } +static unsigned int prophash_bool(pcb_propval_t key) { return longhash(key.i); } +static unsigned int prophash_color(pcb_propval_t key) { return longhash(key.clr.packed); } +static unsigned int prophash_string(pcb_propval_t key) { return key.string == NULL ? 0 : strhash(key.string); } + +typedef unsigned int (*prophash_ft)(pcb_propval_t key); +static prophash_ft prophash[PCB_PROPT_max] = { + NULL, prophash_string, prophash_coord, prophash_angle, prophash_double, prophash_int, prophash_bool, prophash_color +}; + +/* A keyeq function for each known type */ +static int propkeyeq_coord(pcb_propval_t a, pcb_propval_t b) { return a.coord == b.coord; } +static int propkeyeq_angle(pcb_propval_t a, pcb_propval_t b) { return a.angle == b.angle; } +static int propkeyeq_double(pcb_propval_t a, pcb_propval_t b) { return a.d == b.d; } +static int propkeyeq_int(pcb_propval_t a, pcb_propval_t b) { return a.i == b.i; } +static int propkeyeq_bool(pcb_propval_t a, pcb_propval_t b) { return a.i == b.i; } +static int propkeyeq_color(pcb_propval_t a, pcb_propval_t b) { return a.clr.packed == b.clr.packed; } +static int propkeyeq_string(pcb_propval_t a, pcb_propval_t b) +{ + if ((b.string == NULL) && (a.string == NULL)) + return 1; + if ((b.string == NULL) || (a.string == NULL)) + return 0; + return (strcmp(a.string, b.string) == 0); +} + + +typedef int (*propkeyeq_ft)(pcb_propval_t a, pcb_propval_t b); +static propkeyeq_ft propkeyeq[PCB_PROPT_max] = { + NULL, propkeyeq_string, propkeyeq_coord, propkeyeq_angle, propkeyeq_double, propkeyeq_int, propkeyeq_bool, propkeyeq_color +}; + + +/* Init & uninit */ +void pcb_props_init(pcb_propedit_t *ctx, pcb_board_t *pcb) +{ + memset(ctx, 0, sizeof(pcb_propedit_t)); + htsp_init(&ctx->props, strhash, strkeyeq); + ctx->pcb = pcb; + ctx->data = pcb == NULL ? NULL : pcb->Data; +} + +void pcb_props_reset(pcb_propedit_t *ctx) +{ + htsp_entry_t *e; + for(e = htsp_first(&ctx->props); e != NULL; e = htsp_next(&ctx->props, e)) { + pcb_props_t *p = e->value; + htprop_clear(&p->values); + } +} + + +void pcb_props_clear(pcb_propedit_t *ctx) +{ + htsp_entry_t *e; + for(e = htsp_first(&ctx->props); e != NULL; e = htsp_next(&ctx->props, e)) { + pcb_props_t *p = e->value; + htprop_uninit(&p->values); + free(p); + free(e->key); + } + htsp_clear(&ctx->props); +} + + +void pcb_props_uninit(pcb_propedit_t *ctx) +{ + pcb_props_clear(ctx); + TODO("clear the vectors") + memset(ctx, 0, sizeof(pcb_propedit_t)); +} + +/* Retrieve values for a prop */ +pcb_props_t *pcb_props_get(pcb_propedit_t *ctx, const char *propname) +{ + if (propname == NULL) + return NULL; + return htsp_get(&ctx->props, propname); +} + +/* Store a new value */ +pcb_props_t *pcb_props_add(pcb_propedit_t *ctx, const char *propname, pcb_prop_type_t type, pcb_propval_t val) +{ + pcb_props_t *p; + htprop_entry_t *e; + + if ((type <= PCB_PROPT_invalid) || (type >= PCB_PROPT_max)) + return NULL; + + /* look up or create the value list (p) associated with the property name */ + p = htsp_get(&ctx->props, propname); + if (p == NULL) { + p = malloc(sizeof(pcb_props_t)); + p->type = type; + htprop_init(&p->values, prophash[type], propkeyeq[type]); + htsp_set(&ctx->props, rnd_strdup(propname), p); + } + else { + if (type != p->type) + return NULL; + } + + /* Check if we already have this value */ + e = htprop_getentry(&p->values, val); + if (e == NULL) + htprop_set(&p->values, val, 1); + else + e->value++; + + return p; +} + + +const char *pcb_props_type_name(pcb_prop_type_t type) +{ + if (((int)type < 0) || (type >= PCB_PROPT_max)) + return NULL; + + return type_names[type]; +} + +#define STAT(val, field, cnt) \ +do { \ + if (val.field < minp.field) minp = val; \ + if (val.field > maxp.field) maxp = val; \ + avgp.field += val.field * cnt; \ +} while(0) + +int pcb_props_stat(pcb_propedit_t *ctx, pcb_props_t *p, pcb_propval_t *most_common, pcb_propval_t *min, pcb_propval_t *max, pcb_propval_t *avg) +{ + htprop_entry_t *e; + pcb_propval_t bestp, minp, maxp, avgp; + unsigned long best = 0, num_vals = 0; + + if (most_common != NULL) + most_common->string = NULL; + if (min != NULL) + min->string = NULL; + if (max != NULL) + max->string = NULL; + if (avg != NULL) + avg->string = NULL; + + if ((p->type == PCB_PROPT_STRING) && ((min != NULL) || (max != NULL) || (avg != NULL))) + return -1; + + /* set up internal avg, min, max */ + memset(&avgp, 0, sizeof(avgp)); + switch(p->type) { + case PCB_PROPT_invalid: break; + case PCB_PROPT_max: break; + case PCB_PROPT_STRING: break; + case PCB_PROPT_COORD: minp.coord = RND_COORD_MAX; maxp.coord = -minp.coord; break; + case PCB_PROPT_ANGLE: minp.angle = 100000; maxp.angle = -minp.angle; break; + case PCB_PROPT_DOUBLE: minp.d = 100000; maxp.d = -minp.d; break; + case PCB_PROPT_INT: minp.i = INT_MAX; maxp.i = -minp.i; break; + case PCB_PROPT_BOOL: minp.i = 1; maxp.i = 0; break; + case PCB_PROPT_COLOR: break; + } + + /* walk through all known values */ + for (e = htprop_first(&p->values); e; e = htprop_next(&p->values, e)) { + if (e->value > best) { + best = e->value; + bestp = e->key; + } + num_vals += e->value; + switch(p->type) { + case PCB_PROPT_invalid: break; + case PCB_PROPT_max: break; + case PCB_PROPT_STRING: break; + case PCB_PROPT_COORD: STAT(e->key, coord, e->value); break; + case PCB_PROPT_ANGLE: STAT(e->key, angle, e->value); break; + case PCB_PROPT_DOUBLE: STAT(e->key, d, e->value); break; + case PCB_PROPT_INT: STAT(e->key, i, e->value); break; + case PCB_PROPT_BOOL: STAT(e->key, i, e->value); break; + case PCB_PROPT_COLOR: break; + } + } + + /* generate the result */ + if (num_vals != 0) { + switch(p->type) { + case PCB_PROPT_invalid: break; + case PCB_PROPT_max: break; + case PCB_PROPT_STRING: break; + case PCB_PROPT_COORD: avgp.coord = avgp.coord/num_vals; break; + case PCB_PROPT_ANGLE: avgp.angle = avgp.angle/num_vals; break; + case PCB_PROPT_DOUBLE: avgp.angle = avgp.d/num_vals; break; + case PCB_PROPT_INT: avgp.i = avgp.i/num_vals; break; + case PCB_PROPT_BOOL: avgp.i = avgp.i * 100/num_vals; break; + case PCB_PROPT_COLOR: break; + } + if (avg != NULL) *avg = avgp; + if (min != NULL) *min = minp; + if (max != NULL) *max = maxp; + if (most_common != NULL) *most_common = bestp; + } + return 0; +} + +int prop_cmp(const void *e1_, const void *e2_) +{ + const htsp_entry_t *e1 = e1_, *e2 = e2_; + if (e1->key[0] != e2->key[0]) /* special exception: list p/ first then a/ */ + return e1->key[0] < e2->key[0] ? 1 : -1; + return strcmp(e1->key, e2->key) > 0 ? 1 : -1; +} + +htsp_entry_t *pcb_props_sort(pcb_propedit_t *ctx) +{ + htsp_entry_t *e, *arr = malloc(sizeof(htsp_entry_t) * (ctx->props.used + 1)); + int n; + + for(e = htsp_first(&ctx->props), n = 0; e != NULL; e = htsp_next(&ctx->props, e), n++) + arr[n] = *e; + + qsort(arr, n, sizeof(htsp_entry_t), prop_cmp); + + arr[ctx->props.used].key = NULL; + return arr; +} + + +#undef STAT Index: tags/2.3.0/src_plugins/propedit/props.h =================================================================== --- tags/2.3.0/src_plugins/propedit/props.h (nonexistent) +++ tags/2.3.0/src_plugins/propedit/props.h (revision 33253) @@ -0,0 +1,134 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* This API builds and maintains a collection of values for each named property. + A value can be added any time. All values ever seen for a property is stored. + Duplicate values per property are stored only once, but number of occurence + per value (per property) is kept track on. Typically at the end of + a query, but generally ny time, the caller may query for: + - all known properties (it's a htsp) + - all known values of a property + - statistics of values of a property +*/ + +#include +#include +#include +#include + +#include "idpath.h" +#include + +typedef enum { + PCB_PROPT_invalid, + PCB_PROPT_STRING, + PCB_PROPT_COORD, + PCB_PROPT_ANGLE, + PCB_PROPT_DOUBLE, + PCB_PROPT_INT, + PCB_PROPT_BOOL, + PCB_PROPT_COLOR, + PCB_PROPT_max +} pcb_prop_type_t; + +typedef union { + const char *string; + rnd_coord_t coord; + rnd_angle_t angle; + int i; + double d; + rnd_color_t clr; +} pcb_propval_t; + +typedef pcb_propval_t htprop_key_t; +typedef unsigned long int htprop_value_t; +#define HT(x) htprop_ ## x +#include +#undef HT + +typedef struct { + pcb_prop_type_t type; + htprop_t values; + unsigned core:1; /* 1 if it is a core property */ +} pcb_props_t; + +typedef struct { + htsp_t props; + + /* scope */ + pcb_board_t *pcb; + pcb_data_t *data; /* change this after init in case of subc */ + htsp_t nets; + + /* target objects */ + pcb_idpath_list_t objs; + vtl0_t layers; /* layer IDs */ + vtl0_t layergrps; /* layer group IDs */ + unsigned selection:1; /* all selected objects on the current pcb */ + unsigned board:1; /* run on the board too */ + unsigned nets_inited:1; /* whether the ->nets hash is initialized */ + unsigned geo:1; /* include fields related to geometry of objects */ +} pcb_propedit_t; + +/* A property list (props) is a string->pcb_props_t. Each entry is a named + property with a value that's a type and a value hash (vhash). vhash's + key is each value that the property ever took, and vhash's value is an + integer value of how many times the given property is taken */ +void pcb_props_init(pcb_propedit_t *ctx, pcb_board_t *pcb); +void pcb_props_uninit(pcb_propedit_t *ctx); + + +/* Reset stored values from the hash (ctx->props) */ +void pcb_props_reset(pcb_propedit_t *ctx); + +/* Free and remove all items from the hash (ctx->props) */ +void pcb_props_clear(pcb_propedit_t *ctx); + +/* Add a value of a named property; if the value is already known, its counter + is increased. If propname didn't exist, create it. Returns NULL on error. + Error conditions: + - invalid type + - mismatching type for the property (all values of a given property must be the same) +*/ +pcb_props_t *pcb_props_add(pcb_propedit_t *ctx, const char *propname, pcb_prop_type_t type, pcb_propval_t val); + +/* Retrieve values for a prop - returns NULL if propname doesn't exist */ +pcb_props_t *pcb_props_get(pcb_propedit_t *ctx, const char *propname); + + +/* Return the type name of a property type or NULL on error. */ +const char *pcb_props_type_name(pcb_prop_type_t type); + +/* Look up property p and calculate statistics for all values occured so far. + Any of most_common, min, max and avg can be NULL. Returns non-zero if propname + doesn't exist or stat values that can not be calculated for the given type + are not NULL. Invalid type/stat combinations: + type=string min, max, avg +*/ +int pcb_props_stat(pcb_propedit_t *ctx, pcb_props_t *p, pcb_propval_t *most_common, pcb_propval_t *min, pcb_propval_t *max, pcb_propval_t *avg); + +/* Return a key=NULL terminated array of all entries from the hash, alphabetically sorted */ +htsp_entry_t *pcb_props_sort(pcb_propedit_t *ctx); Index: tags/2.3.0/src_plugins/propedit/propsel.c =================================================================== --- tags/2.3.0/src_plugins/propedit/propsel.c (nonexistent) +++ tags/2.3.0/src_plugins/propedit/propsel.c (revision 33253) @@ -0,0 +1,1173 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2018,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include "config.h" +#include "data.h" +#include "data_it.h" +#include "props.h" +#include "propsel.h" +#include "change.h" +#include "draw.h" +#include +#include "flag_str.h" +#include +#include "undo.h" +#include "rotate.h" +#include "obj_pstk_inlines.h" +#include +#include "conf_core.h" +#include +#include "netlist.h" + +#include "obj_line_op.h" +#include "obj_arc_op.h" +#include "obj_text_op.h" +#include "obj_pstk_op.h" +#include "obj_subc_op.h" + +/*********** map ***********/ +#define type2field_String string +#define type2field_rnd_coord_t coord +#define type2field_rnd_angle_t angle +#define type2field_double d +#define type2field_int i +#define type2field_bool i +#define type2field_color clr + +#define type2TYPE_String PCB_PROPT_STRING +#define type2TYPE_rnd_coord_t PCB_PROPT_COORD +#define type2TYPE_rnd_angle_t PCB_PROPT_ANGLE +#define type2TYPE_double PCB_PROPT_DOUBLE +#define type2TYPE_int PCB_PROPT_INT +#define type2TYPE_bool PCB_PROPT_BOOL +#define type2TYPE_color PCB_PROPT_COLOR + +#define map_add_prop(ctx, name, type, val) \ +do { \ + pcb_propval_t v; \ + v.type2field_ ## type = (val); \ + pcb_props_add(ctx, name, type2TYPE_ ## type, v); \ +} while(0) + +static void map_attr(void *ctx, const pcb_attribute_list_t *list) +{ + int i, bl = 0; + char small[256]; + char *big = NULL; + + small[0] = 'a'; + small[1] = '/'; + + for (i = 0; i < list->Number; i++) { + int len = strlen(list->List[i].name); + char *nm; + if (len >= sizeof(small)-3) { + if (len > bl) { + bl = len + 128; + if (big != NULL) + free(big); + big = malloc(bl); + big[0] = 'a'; + big[1] = '/'; + } + nm = big; + } + else + nm = small; + strcpy(nm+2, list->List[i].name); + map_add_prop(ctx, nm, String, list->List[i].value); + } + if (big != NULL) + free(big); +} + +static void map_common(void *ctx, pcb_any_obj_t *obj) +{ + unsigned long bit; + char name[256], *end; + + strcpy(name, "p/flags/"); + end = name + 8; + for(bit = 1; bit < (1UL<<31); bit <<= 1) { + const pcb_flag_bits_t *i; + if ((bit == PCB_FLAG_SELECTED) || (bit == PCB_FLAG_RUBBEREND)) + continue; + i = pcb_strflg_1bit(bit, obj->type); + if (i == NULL) + continue; + strcpy(end, i->name); + map_add_prop(ctx, name, bool, PCB_FLAG_TEST(bit, obj)); + } +} + +static void map_board(pcb_propedit_t *ctx, pcb_board_t *pcb) +{ + map_add_prop(ctx, "p/board/name", String, pcb->hidlib.name); + map_add_prop(ctx, "p/board/filename", String, pcb->hidlib.filename); + map_add_prop(ctx, "p/board/width", rnd_coord_t, pcb->hidlib.size_x); + map_add_prop(ctx, "p/board/height", rnd_coord_t, pcb->hidlib.size_y); + map_attr(ctx, &pcb->Attributes); +} + +static void map_layer(pcb_propedit_t *ctx, pcb_layer_t *layer) +{ + if (layer == NULL) + return; + map_add_prop(ctx, "p/layer/name", String, layer->name); + map_add_prop(ctx, "p/layer/comb/negative", bool, !!(layer->comb & PCB_LYC_SUB)); + map_add_prop(ctx, "p/layer/comb/auto", bool, !!(layer->comb & PCB_LYC_AUTO)); + if (!layer->is_bound) + map_add_prop(ctx, "p/layer/color", color, layer->meta.real.color); + map_attr(ctx, &layer->Attributes); +} + +static void map_layergrp(pcb_propedit_t *ctx, pcb_layergrp_t *grp) +{ + const char *s; + + if (grp == NULL) + return; + + map_add_prop(ctx, "p/layer_group/name", String, grp->name); + map_add_prop(ctx, "p/layer_group/purpose", String, grp->purpose); + + s = pcb_layer_type_bit2str(grp->ltype & PCB_LYT_ANYWHERE); + if (s == NULL) s = "global"; + map_add_prop(ctx, "p/layer_group/location", String, s); + + map_add_prop(ctx, "p/layer_group/main_type", String, pcb_layer_type_bit2str(grp->ltype & PCB_LYT_ANYTHING)); + map_add_prop(ctx, "p/layer_group/prop_type", String, pcb_layer_type_bit2str(grp->ltype & PCB_LYT_ANYPROP)); + + map_attr(ctx, &grp->Attributes); +} + +static void map_net(pcb_propedit_t *ctx, const char *netname) +{ + pcb_net_t *net = pcb_net_get(ctx->pcb, &ctx->pcb->netlist[PCB_NETLIST_EDITED], netname, 0); + if (net == NULL) + return; + map_attr(ctx, &net->Attributes); +} + +static void map_line(pcb_propedit_t *ctx, pcb_line_t *line) +{ + map_add_prop(ctx, "p/trace/thickness", rnd_coord_t, line->Thickness); + map_add_prop(ctx, "p/trace/clearance", rnd_coord_t, line->Clearance/2); + map_common(ctx, (pcb_any_obj_t *)line); + map_attr(ctx, &line->Attributes); + if (ctx->geo) { + map_add_prop(ctx, "p/line/x1", rnd_coord_t, line->Point1.X); + map_add_prop(ctx, "p/line/y1", rnd_coord_t, line->Point1.Y); + map_add_prop(ctx, "p/line/x2", rnd_coord_t, line->Point2.X); + map_add_prop(ctx, "p/line/y2", rnd_coord_t, line->Point2.Y); + } +} + +static void map_arc(pcb_propedit_t *ctx, pcb_arc_t *arc) +{ + map_add_prop(ctx, "p/trace/thickness", rnd_coord_t, arc->Thickness); + map_add_prop(ctx, "p/trace/clearance", rnd_coord_t, arc->Clearance/2); + map_add_prop(ctx, "p/arc/width", rnd_coord_t, arc->Width); + map_add_prop(ctx, "p/arc/height", rnd_coord_t, arc->Height); + map_add_prop(ctx, "p/arc/angle/start", rnd_angle_t, arc->StartAngle); + map_add_prop(ctx, "p/arc/angle/delta", rnd_angle_t, arc->Delta); + map_common(ctx, (pcb_any_obj_t *)arc); + map_attr(ctx, &arc->Attributes); + if (ctx->geo) { + map_add_prop(ctx, "p/arc/x", rnd_coord_t, arc->X); + map_add_prop(ctx, "p/arc/y", rnd_coord_t, arc->Y); + } +} + +static void map_gfx(pcb_propedit_t *ctx, pcb_gfx_t *gfx) +{ + map_add_prop(ctx, "p/gfx/sx", rnd_coord_t, gfx->sx); + map_add_prop(ctx, "p/gfx/sy", rnd_coord_t, gfx->sy); + map_add_prop(ctx, "p/gfx/rot", rnd_angle_t, gfx->rot); + map_common(ctx, (pcb_any_obj_t *)gfx); + map_attr(ctx, &gfx->Attributes); + if (ctx->geo) { + map_add_prop(ctx, "p/gfx/cx", rnd_coord_t, gfx->cx); + map_add_prop(ctx, "p/gfx/cy", rnd_coord_t, gfx->cy); + } +} + +static void map_text(pcb_propedit_t *ctx, pcb_text_t *text) +{ + map_add_prop(ctx, "p/text/scale", int, text->Scale); + map_add_prop(ctx, "p/text/scale_x", double, text->scale_x); + map_add_prop(ctx, "p/text/scale_y", double, text->scale_y); + map_add_prop(ctx, "p/text/fid", int, text->fid); + map_add_prop(ctx, "p/text/rotation", rnd_angle_t, text->rot); + map_add_prop(ctx, "p/text/thickness", rnd_coord_t, text->thickness); + map_add_prop(ctx, "p/text/string", String, text->TextString); + map_common(ctx, (pcb_any_obj_t *)text); + map_attr(ctx, &text->Attributes); + if (ctx->geo) { + map_add_prop(ctx, "p/text/x", rnd_coord_t, text->X); + map_add_prop(ctx, "p/text/y", rnd_coord_t, text->Y); + } +} + +static void map_poly(pcb_propedit_t *ctx, pcb_poly_t *poly) +{ + map_attr(ctx, &poly->Attributes); + map_common(ctx, (pcb_any_obj_t *)poly); + map_add_prop(ctx, "p/trace/clearance", rnd_coord_t, poly->Clearance/2); + map_add_prop(ctx, "p/trace/enforce_clearance", rnd_coord_t, poly->enforce_clearance); +} + +static void map_pstk(pcb_propedit_t *ctx, pcb_pstk_t *ps) +{ + pcb_pstk_proto_t *proto; + + map_add_prop(ctx, "p/padstack/xmirror", rnd_coord_t, ps->xmirror); + map_add_prop(ctx, "p/padstack/smirror", rnd_coord_t, ps->smirror); + map_add_prop(ctx, "p/padstack/rotation", rnd_angle_t, ps->rot); + map_add_prop(ctx, "p/padstack/proto", int, ps->proto); + + proto = pcb_pstk_get_proto(ps); + map_add_prop(ctx, "p/padstack/clearance", rnd_coord_t, ps->Clearance); + map_add_prop(ctx, "p/padstack/hole", rnd_coord_t, proto->hdia); + map_add_prop(ctx, "p/padstack/plated", int, proto->hplated); + map_add_prop(ctx, "p/padstack/htop", int, proto->htop); + map_add_prop(ctx, "p/padstack/hbottom", int, proto->hbottom); + + map_attr(ctx, &ps->Attributes); + map_common(ctx, (pcb_any_obj_t *)ps); + + if (ctx->geo) { + map_add_prop(ctx, "p/padstack/x", rnd_coord_t, ps->x); + map_add_prop(ctx, "p/padstack/y", rnd_coord_t, ps->y); + } +} + +static void map_subc(pcb_propedit_t *ctx, pcb_subc_t *msubc) +{ + PCB_ARC_ALL_LOOP(msubc->data); { + if (pcb_subc_part_editable(ctx->pcb, arc)) + map_arc(ctx, arc); + } PCB_ENDALL_LOOP; + PCB_LINE_ALL_LOOP(msubc->data); { + if (pcb_subc_part_editable(ctx->pcb, line)) + map_line(ctx, line); + } PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(msubc->data); { + if (pcb_subc_part_editable(ctx->pcb, polygon)) + map_poly(ctx, polygon); + } PCB_ENDALL_LOOP; + PCB_TEXT_ALL_LOOP(msubc->data); { + if (pcb_subc_part_editable(ctx->pcb, text)) + map_text(ctx, text); + } PCB_ENDALL_LOOP; + PCB_PADSTACK_LOOP(msubc->data); { + if (pcb_subc_part_editable(ctx->pcb, padstack)) + map_pstk(ctx, padstack); + } PCB_END_LOOP; + PCB_SUBC_LOOP(msubc->data); { + if (pcb_subc_part_editable(ctx->pcb, subc)) + map_subc(ctx, subc); + } PCB_END_LOOP; + map_attr(ctx, &msubc->Attributes); + map_common(ctx, (pcb_any_obj_t *)msubc); + + if (ctx->geo) { + rnd_coord_t x, y; + if (pcb_subc_get_origin(msubc, &x, &y) == 0) { + map_add_prop(ctx, "p/subcircuit/x", rnd_coord_t, x); + map_add_prop(ctx, "p/subcircuit/y", rnd_coord_t, y); + } + } +} + +static void map_any(pcb_propedit_t *ctx, pcb_any_obj_t *o) +{ + if (o == NULL) + return; + switch(o->type) { + case PCB_OBJ_ARC: map_arc(ctx, (pcb_arc_t *)o); break; + case PCB_OBJ_GFX: map_gfx(ctx, (pcb_gfx_t *)o); break; + case PCB_OBJ_LINE: map_line(ctx, (pcb_line_t *)o); break; + case PCB_OBJ_POLY: map_poly(ctx, (pcb_poly_t *)o); break; + case PCB_OBJ_TEXT: map_text(ctx, (pcb_text_t *)o); break; + case PCB_OBJ_SUBC: map_subc(ctx, (pcb_subc_t *)o); break; + case PCB_OBJ_PSTK: map_pstk(ctx, (pcb_pstk_t *)o); break; + default: break; + } +} + +void pcb_propsel_map_core(pcb_propedit_t *ctx) +{ + pcb_idpath_t *idp; + size_t n; + + for(n = 0; n < vtl0_len(&ctx->layers); n++) + map_layer(ctx, pcb_get_layer(ctx->data, ctx->layers.array[n])); + + for(n = 0; n < vtl0_len(&ctx->layergrps); n++) + map_layergrp(ctx, pcb_get_layergrp(ctx->pcb, ctx->layergrps.array[n])); + + for(idp = pcb_idpath_list_first(&ctx->objs); idp != NULL; idp = pcb_idpath_list_next(idp)) + map_any(ctx, pcb_idpath2obj_in(ctx->data, idp)); + + if (ctx->nets_inited) { + htsp_entry_t *e; + for(e = htsp_first(&ctx->nets); e != NULL; e = htsp_next(&ctx->nets, e)) + map_net(ctx, e->key); + } + + if (ctx->selection) { + pcb_any_obj_t *o; + pcb_data_it_t it; + TODO("TODO#28: should be rtree based for recursion"); + for(o = pcb_data_first(&it, ctx->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, o)) + map_any(ctx, o); + } + + if (ctx->board) + map_board(ctx, ctx->pcb); +} + +/*******************/ + +static int attr_key_has_side_effect(const char *key) +{ + if (strcmp(key, "tight_clearance") == 0) return 1; + if (strcmp(key, "mirror_x") == 0) return 1; + return 0; +} + +static void toggle_attr(pcb_propset_ctx_t *st, pcb_attribute_list_t *list, int undoable, pcb_any_obj_t *obj) +{ + const char *key = st->name+2, *newval = NULL; + const char *orig = pcb_attribute_get(list, key); + int side_effect = 0; + + if (orig == NULL) { + if (st->toggle_create) { + newval = "true"; + goto do_set; + } + /* else do not create non-existing attributes */ + return; + } + if (rnd_istrue(orig)) { + newval = "false"; + goto do_set; + } + else if (rnd_isfalse(orig)) { + newval = "true"; + goto do_set; + } + return; + + do_set:; + side_effect = attr_key_has_side_effect(key); + if ((obj != NULL) && side_effect) + pcb_obj_pre(obj); + if (undoable) + pcb_uchg_attr(st->pcb, obj, key, newval); + else + pcb_attribute_put(list, key, newval); + if ((obj != NULL) && side_effect) { + pcb_obj_update_bbox(st->pcb, obj); + pcb_obj_post(obj); + pcb_draw_invalidate(obj); + } + st->set_cnt++; +} + +static void set_attr_raw(pcb_propset_ctx_t *st, pcb_attribute_list_t *list) +{ + const char *key = st->name+2; + const char *orig; + + if (st->toggle) { + toggle_attr(st, list, 0, NULL); + return; + } + + orig = pcb_attribute_get(list, key); + if ((orig != NULL) && (strcmp(orig, st->s) == 0)) + return; + + pcb_attribute_put(list, key, st->s); + st->set_cnt++; +} + +static void set_attr_obj(pcb_propset_ctx_t *st, pcb_any_obj_t *obj) +{ + const char *key = st->name+2; + int side_effect, res; + + if (st->toggle) { + toggle_attr(st, &obj->Attributes, 1, obj); + return; + } + + side_effect = attr_key_has_side_effect(key); + + if (side_effect) + pcb_obj_pre(obj); + res = pcb_uchg_attr(st->pcb, obj, key, st->s); + if (side_effect) { + pcb_obj_update_bbox(st->pcb, obj); + pcb_obj_post(obj); + pcb_draw_invalidate(obj); + } + + + if (res != 0) + return; + + st->set_cnt++; +} + +#define DONE { st->set_cnt++; pcb_undo_restore_serial(); return; } +#define DONE0 { st->set_cnt++; pcb_undo_restore_serial(); return 0; } +#define DONE1 { st->set_cnt++; pcb_undo_restore_serial(); return 1; } + +static int set_common(pcb_propset_ctx_t *st, pcb_any_obj_t *obj) +{ + const pcb_flag_bits_t *i = pcb_strflg_name(st->name + 8, obj->type); + + if (i != NULL) { + if (i->mask & PCB_FLAG_CLEARLINE) + pcb_obj_pre(obj); + + pcb_undo_add_obj_to_flag(obj); + + if (st->toggle) + pcb_flag_change(st->pcb, PCB_CHGFLG_TOGGLE, i->mask, obj->type, obj->parent.any, obj, obj); + else + pcb_flag_change(st->pcb, st->c ? PCB_CHGFLG_SET : PCB_CHGFLG_CLEAR, i->mask, obj->type, obj->parent.any, obj, obj); + if (i->mask & PCB_FLAG_CLEARLINE) + pcb_obj_post(obj); + DONE1; + } + + return 0; +} + +static int brd_resize(rnd_coord_t w, rnd_coord_t h) +{ + pcb_board_resize(w, h, 0); + return 1; +} + +static void set_board(pcb_propset_ctx_t *st, pcb_board_t *pcb) +{ + const char *pn = st->name + 8; + + if (st->is_attr) { + set_attr_raw(st, &pcb->Attributes); + return; + } + + if (st->toggle) + return; /* can't toggle anything else */ + + if (strncmp(st->name, "p/board/", 8) == 0) { + if ((strcmp(pn, "name") == 0) && + (pcb_board_change_name(rnd_strdup(st->s)))) DONE; + + if ((strcmp(pn, "filename") == 0)) { + free(pcb->hidlib.filename); + pcb->hidlib.filename = rnd_strdup(st->s); + DONE; + } + + if (st->c_valid && (strcmp(pn, "width") == 0) && + brd_resize(st->c, PCB->hidlib.size_y)) DONE; + + if (st->c_valid && (strcmp(pn, "height") == 0) && + brd_resize(PCB->hidlib.size_x,st->c)) DONE; + } +} + +static int layer_recolor(pcb_layer_t *layer, const char *clr) +{ + rnd_color_t c; + if (rnd_color_load_str(&c, clr) != 0) + return -1; + return pcb_layer_recolor_(layer, &c, 1); +} + +static int layer_recomb(pcb_layer_t *layer, int val, pcb_layer_combining_t bit) +{ + if (val) + return pcb_layer_recomb(layer, layer->comb | bit, 1); + return pcb_layer_recomb(layer, layer->comb & ~bit, 1); +} + +static int set_layer(pcb_propset_ctx_t *st, pcb_layer_t *layer) +{ + const char *pn = st->name + 8; + + if (st->is_attr) { + set_attr_obj(st, (pcb_any_obj_t *)layer); + return 0; + } + + if (st->toggle) + return 0; /* can't toggle anything else */ + + if (strncmp(st->name, "p/layer/", 8) == 0) { + if ((strcmp(pn, "name") == 0) && + (pcb_layer_rename_(layer, rnd_strdup(st->s), 1) == 0)) DONE0; + + if ((strcmp(pn, "color") == 0) && + (layer_recolor(layer, st->color.str) == 0)) DONE0; + + if ((strcmp(pn, "comb/negative") == 0) && + (layer_recomb(layer, st->c, PCB_LYC_SUB) == 0)) DONE0; + + if ((strcmp(pn, "comb/auto") == 0) && + (layer_recomb(layer, st->c, PCB_LYC_AUTO) == 0)) DONE0; + } + + return 0; +} + + +static void set_layergrp(pcb_propset_ctx_t *st, pcb_layergrp_t *grp) +{ + const char *pn = st->name + 14; + + if (st->is_attr) { + set_attr_obj(st, (pcb_any_obj_t *)grp); + return; + } + + if (st->toggle) + return; /* can't toggle anything else */ + + if (strncmp(st->name, "p/layer_group/", 14) == 0) { + if ((strcmp(pn, "name") == 0) && + (pcb_layergrp_rename_(grp, rnd_strdup(st->s), 1) == 0)) DONE; + + if ((strcmp(pn, "purpose") == 0) && + (pcb_layergrp_set_purpose(grp, st->s, 1) == 0)) DONE; + } +} + +static void set_net(pcb_propset_ctx_t *st, const char *netname) +{ + pcb_net_t *net = pcb_net_get(st->pcb, &st->pcb->netlist[PCB_NETLIST_EDITED], netname, 0); + if (net == NULL) + return; + + if (st->toggle) + return; /* can't toggle anything else */ + + if (st->is_attr) { + const char *key = st->name+2; + const char *orig = pcb_attribute_get(&net->Attributes, key); + + if ((orig != NULL) && (strcmp(orig, st->s) == 0)) + return; + + st->set_cnt++; + pcb_ratspatch_append_optimize(st->pcb, RATP_CHANGE_ATTRIB, netname, key, st->s); + return; + } +} + +static void set_line(pcb_propset_ctx_t *st, pcb_line_t *line) +{ + const char *pn = st->name + 8; + + if (st->is_attr) { + set_attr_obj(st, (pcb_any_obj_t *)line); + return; + } + + if (set_common(st, (pcb_any_obj_t *)line)) return; + + if (st->toggle) + return; /* can't toggle anything else */ + + if (strncmp(st->name, "p/trace/", 8) == 0) { + if (st->is_trace && st->c_valid && (strcmp(pn, "thickness") == 0) && + pcb_chg_obj_1st_size(PCB_OBJ_LINE, line->parent.layer, line, NULL, st->c, st->c_absolute)) DONE; + + if (st->is_trace && st->c_valid && (strcmp(pn, "clearance") == 0) && + pcb_chg_obj_clear_size(PCB_OBJ_LINE, line->parent.layer, line, NULL, st->c*2, st->c_absolute)) DONE; + } + + if (strncmp(st->name, "p/line/", 7) == 0) { + pcb_opctx_t op; + memset(&op, 0, sizeof(op)); + op.move.pcb = st->pcb; + pn = st->name + 7; + if (st->c_valid && (strcmp(pn, "x1") == 0)) { + op.move.dx = st->c - line->Point1.X; + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, line->parent.layer, line, &line->Point1, op.move.dx, op.move.dy); + if (pcb_lineop_move_point(&op, line->parent.layer, line, &line->Point1) != NULL) + DONE; + } + if (st->c_valid && (strcmp(pn, "y1") == 0)) { + op.move.dy = st->c - line->Point1.Y; + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, line->parent.layer, line, &line->Point1, op.move.dx, op.move.dy); + if (pcb_lineop_move_point(&op, line->parent.layer, line, &line->Point1) != NULL) + DONE; + } + if (st->c_valid && (strcmp(pn, "x2") == 0)) { + op.move.dx = st->c - line->Point2.X; + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, line->parent.layer, line, &line->Point2, op.move.dx, op.move.dy); + if (pcb_lineop_move_point(&op, line->parent.layer, line, &line->Point2) != NULL) + DONE; + } + if (st->c_valid && (strcmp(pn, "y2") == 0)) { + op.move.dy = st->c - line->Point2.Y; + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, line->parent.layer, line, &line->Point2, op.move.dx, op.move.dy); + if (pcb_lineop_move_point(&op, line->parent.layer, line, &line->Point2) != NULL) + DONE; + } + } +} + +static void set_arc(pcb_propset_ctx_t *st, pcb_arc_t *arc) +{ + const char *pn = st->name + 8; + + if (st->is_attr) { + set_attr_obj(st, (pcb_any_obj_t *)arc); + return; + } + + if (set_common(st, (pcb_any_obj_t *)arc)) return; + + if (st->toggle) + return; /* can't toggle anything else */ + + if (strncmp(st->name, "p/trace/", 8) == 0) { + if (st->is_trace && st->c_valid && (strcmp(pn, "thickness") == 0) && + pcb_chg_obj_1st_size(PCB_OBJ_ARC, arc->parent.layer, arc, NULL, st->c, st->c_absolute)) DONE; + + if (st->is_trace && st->c_valid && (strcmp(pn, "clearance") == 0) && + pcb_chg_obj_clear_size(PCB_OBJ_ARC, arc->parent.layer, arc, NULL, st->c*2, st->c_absolute)) DONE; + } + + pn = st->name + 6; + if (strncmp(st->name, "p/arc/", 6) == 0) { + if (!st->is_trace && st->c_valid && (strcmp(pn, "width") == 0) && + pcb_chg_obj_radius(PCB_OBJ_ARC, arc->parent.layer, arc, NULL, 0, st->c, st->c_absolute)) DONE; + + if (!st->is_trace && st->c_valid && (strcmp(pn, "height") == 0) && + pcb_chg_obj_radius(PCB_OBJ_ARC, arc->parent.layer, arc, NULL, 1, st->c, st->c_absolute)) DONE; + + if (!st->is_trace && st->d_valid && (strcmp(pn, "angle/start") == 0) && + pcb_chg_obj_angle(PCB_OBJ_ARC, arc->parent.layer, arc, NULL, 0, st->d, st->d_absolute)) DONE; + + if (!st->is_trace && st->d_valid && (strcmp(pn, "angle/delta") == 0) && + pcb_chg_obj_angle(PCB_OBJ_ARC, arc->parent.layer, arc, NULL, 1, st->d, st->d_absolute)) DONE; + } + + if (strncmp(st->name, "p/arc/", 6) == 0) { + pcb_opctx_t op; + memset(&op, 0, sizeof(op)); + op.move.pcb = st->pcb; + pn = st->name + 6; + if (st->c_valid && (strcmp(pn, "x") == 0)) { + op.move.dx = st->c - arc->X; + pcb_undo_add_obj_to_move(PCB_OBJ_ARC, arc->parent.layer, arc, arc, op.move.dx, op.move.dy); + if (pcb_arcop_move(&op, arc->parent.layer, arc) != NULL) + DONE; + } + if (st->c_valid && (strcmp(pn, "y") == 0)) { + op.move.dy = st->c - arc->Y; + pcb_undo_add_obj_to_move(PCB_OBJ_ARC, arc->parent.layer, arc, arc, op.move.dx, op.move.dy); + if (pcb_arcop_move(&op, arc->parent.layer, arc) != NULL) + DONE; + } + } +} + +static void set_gfx(pcb_propset_ctx_t *st, pcb_gfx_t *gfx) +{ + const char *pn = st->name + 6; + + if (st->is_attr) { + set_attr_obj(st, (pcb_any_obj_t *)gfx); + return; + } + + if (set_common(st, (pcb_any_obj_t *)gfx)) return; + + if (st->toggle) + return; /* can't toggle anything else */ + + if (strncmp(st->name, "p/gfx/", 6) == 0) { + if (st->c_valid && (strcmp(pn, "sx") == 0)) { + pcb_gfx_chg_geo(gfx, gfx->cx, gfx->cy, st->c, gfx->sy, gfx->rot, 1); DONE; + } + if (st->c_valid && (strcmp(pn, "sy") == 0)) { + pcb_gfx_chg_geo(gfx, gfx->cx, gfx->cy, gfx->sx, st->c, gfx->rot, 1); DONE; + } + if (st->d_valid && (strcmp(pn, "rot") == 0)) { + pcb_gfx_chg_geo(gfx, gfx->cx, gfx->cy, gfx->sx, gfx->sy, st->d, 1); DONE; + } + } +} + +static void set_text(pcb_propset_ctx_t *st, pcb_text_t *text) +{ + const char *pn = st->name + 7; + char *old; + + if (st->is_attr) { + set_attr_obj(st, (pcb_any_obj_t *)text); + return; + } + + if (set_common(st, (pcb_any_obj_t *)text)) return; + + if (st->toggle) + return; /* can't toggle anything else */ + + if (strncmp(st->name, "p/text/", 7) == 0) { + pcb_opctx_t op; + + if (st->c_valid && (strcmp(pn, "scale") == 0) && + pcb_chg_obj_size(PCB_OBJ_TEXT, text->parent.layer, text, text, RND_MIL_TO_COORD(st->c), st->c_absolute)) DONE; + + if (st->d_valid && (strcmp(pn, "scale_x") == 0) && + (pcb_text_chg_scale(text, st->d, st->d_absolute, text->scale_y, 1, 1) == 0)) DONE; + + if (st->d_valid && (strcmp(pn, "scale_y") == 0) && + (pcb_text_chg_scale(text, text->scale_x, 1, st->d, st->d_absolute, 1) == 0)) DONE; + + if (st->c_valid && (strcmp(pn, "fid") == 0)) { + pcb_text_set_font(text, st->c); + DONE; + } + + if ((strcmp(pn, "string") == 0) && + (old = pcb_chg_obj_name(PCB_OBJ_TEXT, text->parent.layer, text, NULL, rnd_strdup(st->s)))) { + free(old); + DONE; + } + + if (st->d_valid && (strcmp(pn, "rotation") == 0) && + pcb_chg_obj_rot(PCB_OBJ_TEXT, text->parent.layer, text, text, st->d, st->d_absolute, rnd_true)) DONE; + + if (st->c_valid && (strcmp(pn, "thickness") == 0) && + pcb_chg_obj_2nd_size(PCB_OBJ_TEXT, text->parent.layer, text, text, st->c, st->c_absolute, rnd_true)) DONE; + + memset(&op, 0, sizeof(op)); + op.move.pcb = st->pcb; + if (st->c_valid && (strcmp(pn, "x") == 0)) { + op.move.dx = st->c - text->X; + pcb_undo_add_obj_to_move(PCB_OBJ_TEXT, text->parent.layer, text, text, op.move.dx, op.move.dy); + if (pcb_textop_move(&op, text->parent.layer, text) != NULL) + DONE; + } + if (st->c_valid && (strcmp(pn, "y") == 0)) { + op.move.dy = st->c - text->Y; + pcb_undo_add_obj_to_move(PCB_OBJ_TEXT, text->parent.layer, text, text, op.move.dx, op.move.dy); + if (pcb_textop_move(&op, text->parent.layer, text) != NULL) + DONE; + } + } +} + +static void set_poly(pcb_propset_ctx_t *st, pcb_poly_t *poly) +{ + const char *pn = st->name + 8; + + if (st->is_attr) { + set_attr_obj(st, (pcb_any_obj_t *)poly); + return; + } + + if (set_common(st, (pcb_any_obj_t *)poly)) return; + + if (st->toggle) + return; /* can't toggle anything else */ + + if (strncmp(st->name, "p/trace/", 8) == 0) { + if (st->is_trace && st->c_valid && (strcmp(pn, "clearance") == 0) && + pcb_chg_obj_clear_size(PCB_OBJ_POLY, poly->parent.layer, poly, NULL, st->c*2, st->c_absolute)) DONE; + if (st->is_trace && st->c_valid && (strcmp(pn, "enforce_clearance") == 0) && + pcb_chg_obj_enforce_clear_size(PCB_OBJ_POLY, poly->parent.layer, poly, NULL, st->c, st->c_absolute)) DONE; + } +} + +static void set_pstk(pcb_propset_ctx_t *st, pcb_pstk_t *ps) +{ + const char *pn = st->name + 11; + int i; + rnd_cardinal_t ca; + pcb_pstk_proto_t *proto; + + if (st->is_attr) { + set_attr_obj(st, (pcb_any_obj_t *)ps); + return; + } + + if (set_common(st, (pcb_any_obj_t *)ps)) return; + + if (st->toggle) + return; /* can't toggle anything else */ + + ca = st->c; + i = (st->c != 0); + proto = pcb_pstk_get_proto(ps); + + if (strncmp(st->name, "p/padstack/", 11) == 0) { + pcb_opctx_t op; + + if (st->c_valid && (strcmp(pn, "clearance") == 0) && + pcb_chg_obj_clear_size(PCB_OBJ_PSTK, ps, ps, NULL, st->c*2, st->c_absolute)) DONE; + if (st->d_valid && (strcmp(pn, "rotation") == 0)) { + if (st->d_absolute) { + if (pcb_obj_rotate(st->pcb, (pcb_any_obj_t *)ps, ps->x, ps->y, st->d - ps->rot)) DONE; + } + else { + if (pcb_obj_rotate(st->pcb, (pcb_any_obj_t *)ps, ps->x, ps->y, st->d)) DONE; + } + return; + } + if (st->c_valid && (strcmp(pn, "xmirror") == 0) && + (pcb_pstk_change_instance(ps, NULL, NULL, NULL, &i, NULL) == 0)) DONE; + if (st->c_valid && (strcmp(pn, "smirror") == 0) && + (pcb_pstk_change_instance(ps, NULL, NULL, NULL, NULL, &i) == 0)) DONE; + if (st->c_valid && (strcmp(pn, "proto") == 0) && + (pcb_pstk_change_instance(ps, &ca, NULL, NULL, NULL, NULL) == 0)) DONE; + if (st->c_valid && (strcmp(pn, "hole") == 0) && + (pcb_pstk_proto_change_hole(proto, NULL, &st->c, NULL, NULL) == 0)) DONE; + if (st->c_valid && (strcmp(pn, "plated") == 0) && + (pcb_pstk_proto_change_hole(proto, &i, NULL, NULL, NULL) == 0)) DONE; + if (st->c_valid && (strcmp(pn, "htop") == 0) && + (pcb_pstk_proto_change_hole(proto, NULL, NULL, &i, NULL) == 0)) DONE; + if (st->c_valid && (strcmp(pn, "hbottom") == 0) && + (pcb_pstk_proto_change_hole(proto, NULL, NULL, NULL, &i) == 0)) DONE; + + memset(&op, 0, sizeof(op)); + op.move.pcb = st->pcb; + if (st->c_valid && (strcmp(pn, "x") == 0)) { + op.move.dx = st->c - ps->x; + pcb_undo_add_obj_to_move(PCB_OBJ_PSTK, ps->parent.data, ps, ps, op.move.dx, op.move.dy); + if (pcb_pstkop_move(&op, ps) != NULL) + DONE; + } + if (st->c_valid && (strcmp(pn, "y") == 0)) { + op.move.dy = st->c - ps->y; + pcb_undo_add_obj_to_move(PCB_OBJ_PSTK, ps->parent.data, ps, ps, op.move.dx, op.move.dy); + if (pcb_pstkop_move(&op, ps) != NULL) + DONE; + } + } +} + +static void set_subc(pcb_propset_ctx_t *st, pcb_subc_t *ssubc) +{ + + if (((st->name[0] != 'a') && (st->name[0] != 'f')) || (st->name[1] != '/')) { /* attributes and flags are not recursive */ + PCB_ARC_ALL_LOOP(ssubc->data); { + if (pcb_subc_part_editable(st->pcb, arc)) + set_arc(st, arc); + } PCB_ENDALL_LOOP; + PCB_LINE_ALL_LOOP(ssubc->data); { + if (pcb_subc_part_editable(st->pcb, line)) + set_line(st, line); + } PCB_ENDALL_LOOP; + PCB_POLY_ALL_LOOP(ssubc->data); { + if (pcb_subc_part_editable(st->pcb, polygon)) + set_poly(st, polygon); + } PCB_ENDALL_LOOP; + PCB_TEXT_ALL_LOOP(ssubc->data); { + if (pcb_subc_part_editable(st->pcb, text)) + set_text(st, text); + } PCB_ENDALL_LOOP; + PCB_PADSTACK_LOOP(ssubc->data); { + if (pcb_subc_part_editable(st->pcb, padstack)) + set_pstk(st, padstack); + } PCB_END_LOOP; + PCB_SUBC_LOOP(ssubc->data); { + if (pcb_subc_part_editable(st->pcb, subc)) + set_subc(st, subc); + } PCB_END_LOOP; + } + + if (set_common(st, (pcb_any_obj_t *)ssubc)) return; + + if (st->is_attr) { + set_attr_obj(st, (pcb_any_obj_t *)ssubc); + return; + } + + if (st->toggle) + return; /* can't toggle anything else */ + + if (strncmp(st->name, "p/subcircuit/", 13) == 0) { + pcb_opctx_t op; + rnd_coord_t x = 0, y = 0; + const char *pn = st->name + 13; + + pcb_subc_get_origin(ssubc, &x, &y); + memset(&op, 0, sizeof(op)); + op.move.pcb = st->pcb; + if (st->c_valid && (strcmp(pn, "x") == 0)) { + op.move.dx = st->c - x; + pcb_undo_add_obj_to_move(PCB_OBJ_SUBC, ssubc->parent.data, ssubc, ssubc, op.move.dx, op.move.dy); + if (pcb_subcop_move(&op, ssubc) != NULL) + DONE; + } + if (st->c_valid && (strcmp(pn, "y") == 0)) { + op.move.dy = st->c - y; + pcb_undo_add_obj_to_move(PCB_OBJ_SUBC, ssubc->parent.data, ssubc, ssubc, op.move.dx, op.move.dy); + if (pcb_subcop_move(&op, ssubc) != NULL) + DONE; + } + + } +} + +static void set_any(pcb_propset_ctx_t *ctx, pcb_any_obj_t *o) +{ + if (o == NULL) + return; + switch(o->type) { + case PCB_OBJ_ARC: set_arc(ctx, (pcb_arc_t *)o); break; + case PCB_OBJ_GFX: set_gfx(ctx, (pcb_gfx_t *)o); break; + case PCB_OBJ_LINE: set_line(ctx, (pcb_line_t *)o); break; + case PCB_OBJ_POLY: set_poly(ctx, (pcb_poly_t *)o); break; + case PCB_OBJ_TEXT: set_text(ctx, (pcb_text_t *)o); break; + case PCB_OBJ_SUBC: set_subc(ctx, (pcb_subc_t *)o); break; + case PCB_OBJ_PSTK: set_pstk(ctx, (pcb_pstk_t *)o); break; + default: break; + } +} + +int pcb_propsel_set(pcb_propedit_t *ctx, const char *prop, pcb_propset_ctx_t *sctx) +{ + size_t n; + pcb_idpath_t *idp; + + sctx->pcb = ctx->pcb; + sctx->data = ctx->data; + sctx->is_trace = (strncmp(prop, "p/trace/", 8) == 0); + sctx->is_attr = (prop[0] == 'a'); + sctx->name = prop; + + pcb_undo_save_serial(); + + for(n = 0; n < vtl0_len(&ctx->layers); n++) + set_layer(sctx, pcb_get_layer(ctx->data, ctx->layers.array[n])); + + for(n = 0; n < vtl0_len(&ctx->layergrps); n++) + set_layergrp(sctx, pcb_get_layergrp(ctx->pcb, ctx->layergrps.array[n])); + + for(idp = pcb_idpath_list_first(&ctx->objs); idp != NULL; idp = pcb_idpath_list_next(idp)) { + pcb_any_obj_t *obj = pcb_idpath2obj_in(ctx->data, idp); + if (obj == NULL) /* workaround: idp sometimes points into the buffer */ + obj = pcb_idpath2obj(PCB, idp); + set_any(sctx, obj); + } + + if (ctx->nets_inited) { + long old_set_cnt = sctx->set_cnt; + htsp_entry_t *e; + for(e = htsp_first(&ctx->nets); e != NULL; e = htsp_next(&ctx->nets, e)) + set_net(sctx, e->key); + if (old_set_cnt != sctx->set_cnt) + pcb_ratspatch_make_edited(sctx->pcb); + } + + if (ctx->selection) { + pcb_any_obj_t *o; + pcb_data_it_t it; + TODO("TODO#28: should be rtree based for recursion"); + for(o = pcb_data_first(&it, ctx->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, o)) + set_any(sctx, o); + } + + if (ctx->board) + set_board(sctx, ctx->pcb); + + pcb_board_set_changed_flag(ctx->pcb, rnd_true); + pcb_undo_inc_serial(); + return sctx->set_cnt; +} + + +int pcb_propsel_set_str(pcb_propedit_t *ctx, const char *prop, const char *value) +{ + pcb_propset_ctx_t sctx; + char *end; + const char *start; + + /* sanity checks for invalid props */ + if ((prop[1] != '/') || ((prop[0] != 'a') && (prop[0] != 'p'))) { + rnd_message(RND_MSG_ERROR, "Invalid property path: '%s':\n must start with p/ for property or a/ for attribute\n", prop); + return 0; + } + + memset(&sctx, 0, sizeof(sctx)); + + if (value == NULL) + value = ""; + sctx.s = value; + start = value; + while(isspace(*start)) start++; + if (*start == '#') { + sctx.d_absolute = 1; + start++; + } + else + sctx.d_absolute = ((*start != '-') && (*start != '+')); + sctx.toggle = 0; + sctx.c = rnd_get_value_ex(start, NULL, &sctx.c_absolute, NULL, NULL, &sctx.c_valid); + sctx.d = strtod(start, &end); + sctx.d_valid = (*end == '\0'); + sctx.set_cnt = 0; + + return pcb_propsel_set(ctx, prop, &sctx); +} + +int pcb_propsel_toggle(pcb_propedit_t *ctx, const char *prop, rnd_bool create) +{ + pcb_propset_ctx_t sctx; + + /* sanity checks for invalid props */ + if (prop[1] != '/') + return 0; + if ((prop[0] != 'a') && (prop[0] != 'p')) + return 0; + + memset(&sctx, 0, sizeof(sctx)); + + sctx.toggle = 1; + sctx.toggle_create = create; + sctx.set_cnt = 0; + + return pcb_propsel_set(ctx, prop, &sctx); +} + +/*******************/ + +static long del_attr(void *ctx, pcb_attribute_list_t *list, const char *key) +{ + if (pcb_attribute_remove(list, key)) + return 1; + return 0; +} + +static long del_layer(void *ctx, pcb_layer_t *ly, const char *key) +{ + return del_attr(ctx, &ly->Attributes, key); +} + +static long del_layergrp(void *ctx, pcb_layergrp_t *grp, const char *key) +{ + return del_attr(ctx, &grp->Attributes, key); +} + +static long del_net(pcb_propedit_t *ctx, const char *netname, const char *key) +{ + pcb_net_t *net = pcb_net_get(ctx->pcb, &ctx->pcb->netlist[PCB_NETLIST_EDITED], netname, 0); + if ((net == NULL) || (pcb_attribute_get(&net->Attributes, key) == NULL)) + return 0; + + pcb_ratspatch_append_optimize(ctx->pcb, RATP_CHANGE_ATTRIB, netname, key, NULL); + return 1; +} + +static long del_any(void *ctx, pcb_any_obj_t *o, const char *key) +{ + return del_attr(ctx, &o->Attributes, key); +} + +static long del_board(void *ctx, pcb_board_t *pcb, const char *key) +{ + return del_attr(ctx, &pcb->Attributes, key); +} + +int pcb_propsel_del(pcb_propedit_t *ctx, const char *key) +{ + long del_cnt = 0; + pcb_idpath_t *idp; + size_t n; + + if ((key[0] != 'a') || (key[1] != '/')) /* do not attempt to remove anything but attributes */ + return 0; + + key += 2; + + for(n = 0; n < vtl0_len(&ctx->layers); n++) + del_cnt += del_layer(ctx, pcb_get_layer(ctx->data, ctx->layers.array[n]), key); + + for(n = 0; n < vtl0_len(&ctx->layergrps); n++) + del_cnt += del_layergrp(ctx, pcb_get_layergrp(ctx->pcb, ctx->layergrps.array[n]), key); + + for(idp = pcb_idpath_list_first(&ctx->objs); idp != NULL; idp = pcb_idpath_list_next(idp)) + del_cnt += del_any(ctx, pcb_idpath2obj_in(ctx->data, idp), key); + + if (ctx->nets_inited) { + htsp_entry_t *e; + long old_del_cnt = del_cnt; + for(e = htsp_first(&ctx->nets); e != NULL; e = htsp_next(&ctx->nets, e)) + del_cnt += del_net(ctx, e->key, key); + if (old_del_cnt != del_cnt) + pcb_ratspatch_make_edited(ctx->pcb); + } + + if (ctx->selection) { + pcb_any_obj_t *o; + pcb_data_it_t it; + TODO("TODO#28: should be rtree based for recursion"); + for(o = pcb_data_first(&it, ctx->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) + if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, o)) + del_cnt += del_any(ctx, o, key); + } + + if (ctx->board) + del_cnt += del_board(&ctx, ctx->pcb, key); + + pcb_board_set_changed_flag(ctx->pcb, rnd_true); + return del_cnt; +} + + +char *pcb_propsel_printval(pcb_prop_type_t type, const pcb_propval_t *val) +{ + switch(type) { + case PCB_PROPT_STRING: return val->string == NULL ? rnd_strdup("") : rnd_strdup(val->string); + case PCB_PROPT_COORD: return rnd_strdup_printf("%m+%.02mS", rnd_conf.editor.grid_unit->allow, val->coord); + case PCB_PROPT_ANGLE: return rnd_strdup_printf("%f", val->angle); + case PCB_PROPT_DOUBLE: return rnd_strdup_printf("%f", val->d); + case PCB_PROPT_INT: return rnd_strdup_printf("%d", val->i); + case PCB_PROPT_BOOL: return rnd_strdup(val->i ? "true" : "false"); + case PCB_PROPT_COLOR: return rnd_strdup_printf("#%02x%02x%02x", val->clr.r, val->clr.g, val->clr.b); + default: + return rnd_strdup(""); + } +} Index: tags/2.3.0/src_plugins/propedit/propsel.h =================================================================== --- tags/2.3.0/src_plugins/propedit/propsel.h (nonexistent) +++ tags/2.3.0/src_plugins/propedit/propsel.h (revision 33253) @@ -0,0 +1,56 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* This API builds a prop list by looking at all selected objects on a design. */ +void pcb_propsel_map_core(pcb_propedit_t *ctx); + +typedef struct set_ctx_s { + const char *s; /* only for string */ + rnd_coord_t c; /* also int */ + double d; + rnd_color_t color; + rnd_bool c_absolute, d_absolute, c_valid, d_valid, clr_valid; + unsigned toggle:1; /* when 1, ignore value and attempt to toggle */ + unsigned toggle_create:1; /* when 1, create non-existing attribute on toggle, with value true */ + + /* private */ + unsigned is_trace:1; + unsigned is_attr:1; + pcb_board_t *pcb; + pcb_data_t *data; + const char *name; + int set_cnt; +} pcb_propset_ctx_t; + + +int pcb_propsel_set_str(pcb_propedit_t *ctx, const char *prop, const char *value); +int pcb_propsel_set(pcb_propedit_t *ctx, const char *prop, pcb_propset_ctx_t *sctx); +int pcb_propsel_toggle(pcb_propedit_t *ctx, const char *prop, rnd_bool create); +int pcb_propsel_del(pcb_propedit_t *ctx, const char *attr_name); + +/* Allocate new string and print the value using current unit */ +char *pcb_propsel_printval(pcb_prop_type_t type, const pcb_propval_t *val); + Index: tags/2.3.0/src_plugins/puller/Makefile =================================================================== --- tags/2.3.0/src_plugins/puller/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/puller/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_puller + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/puller/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/puller/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/puller/Plug.tmpasm (revision 33253) @@ -0,0 +1,17 @@ +put /local/pcb/mod {puller} +append /local/pcb/mod/OBJS_C99 [@ $(PLUGDIR)/puller/puller.o @] + +switch /local/pcb/puller/controls + case {disable} end; + default + put /local/pcb/mod/CFLAGS /target/libs/sul/glib/cflags + put /local/pcb/mod/LDFLAGS /target/libs/sul/glib/ldflags + end +end + +switch /local/pcb/puller/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end + Index: tags/2.3.0/src_plugins/puller/puller.c =================================================================== --- tags/2.3.0/src_plugins/puller/puller.c (nonexistent) +++ tags/2.3.0/src_plugins/puller/puller.c (revision 33253) @@ -0,0 +1,2220 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2006 DJ Delorie + * Copyright (C) 2011 PCB Contributers (See ChangeLog for details) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA + * dj@delorie.com + * + */ + +/* FIXME: Things that need to be fixed before this is "perfect". + Add to this list as we find things. + + - respect the outline layer. + + - don't consider points that are perpendicular to our start_arc. + I.e. when we have busses going around corners, we have a *lot* of + arcs and endpoints that are all in the same direction and all + equally "good", but rounding the arc angles to integers causes + all sorts of tiny differences that result in bumps, reversals, + and other messes. + + - Store the X,Y values in our shadow struct so we don't fill up the + undo buffer with all our line reversals. + + - at least check the other layers in our layer group. + +*/ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "draw.h" +#include "move.h" +#include +#include "remove.h" +#include +#include "flag_str.h" +#include "undo.h" +#include "layer.h" +#include +#include +#include +#include +#include "obj_pstk_inlines.h" +#include "funchash_core.h" +#include "search.h" +#include "find.h" + +#define abort1() fprintf(stderr, "abort at line %d\n", __LINE__), abort() + +#define TRACE0 0 +#define TRACE1 0 + +/* sine of one degree */ +#define SIN1D 0.0174524064372835 + +static jmp_buf abort_buf; + +#define sqr(x) (1.0*(x)*(x)) + +static int multi, line_exact, arc_exact; +static pcb_line_t *the_line; +static pcb_arc_t *the_arc; +static double arc_dist; + +/* We canonicalize the arc and line such that the point to be moved is + always Point2 for the line, and at start+delta for the arc. */ + +static int x, y; /* the point we're moving */ +static int cx, cy; /* centerpoint of the arc */ +static int ex, ey; /* fixed end of the line */ + +/* 0 is left (-x), 90 is down (+y), 180 is right (+x), 270 is up (-y) */ + +static int within(int x1, int y1, int x2, int y2, int r) +{ + return rnd_distance(x1, y1, x2, y2) <= r / 2; +} + +static int arc_endpoint_is(pcb_arc_t *a, int angle, int x, int y) +{ + int ax = a->X, ay = a->Y; + + if (angle % 90 == 0) { + int ai = (int) (angle / 90) & 3; + switch (ai) { + case 0: + ax -= a->Width; + break; + case 1: + ay += a->Height; + break; + case 2: + ax += a->Width; + break; + case 3: + ay -= a->Height; + break; + } + } + else { + double rad = angle * M_PI / 180; + ax -= a->Width * cos(rad); + ay += a->Width * sin(rad); + } +#if TRACE1 + rnd_printf(" - arc endpoint %#mD\n", ax, ay); +#endif + arc_dist = rnd_distance(ax, ay, x, y); + if (arc_exact) + return arc_dist < 2; + return arc_dist < a->Thickness / 2; +} + +/* Cross c->u and c->v, return the magnitute */ +static double cross2d(int cx, int cy, int ux, int uy, int vx, int vy) +{ + ux -= cx; + uy -= cy; + vx -= cx; + vy -= cy; + return (double) ux *vy - (double) uy *vx; +} + +/* Likewise, for dot product. */ +static double dot2d(int cx, int cy, int ux, int uy, int vx, int vy) +{ + ux -= cx; + uy -= cy; + vx -= cx; + vy -= cy; + return (double) ux *vx + (double) uy *vy; +} + +#if 0 +/* angle of c->v, relative to c->u, in radians. Range is -pi..pi */ +static double angle2d(int cx, int cy, int ux, int uy, int vx, int vy) +{ + double cross; + double magu, magv, sintheta; +#if TRACE1 + printf("angle2d %d,%d %d,%d %d,%d\n", cx, cy, ux, uy, vx, vy); +#endif + ux -= cx; + uy -= cy; + vx -= cx; + vy -= cy; +#if TRACE1 + printf(" = %d,%d %d,%d\n", ux, uy, vx, vy); +#endif + cross = (double) ux *vy - (double) uy *vx; + magu = sqrt((double) ux * ux + (double) uy * uy); + magv = sqrt((double) vx * vx + (double) vy * vy); + sintheta = cross / (magu * magv); +#if TRACE1 + printf(" = %f / (%f * %f) = %f\n", cross, magu, magv, sintheta); +#endif + return asin(sintheta); +} +#endif + +static int same_sign(double a, double b) +{ + return (a * b >= 0); +} + +static double r2d(double r) +{ + return 180.0 * r / M_PI; +} + +static double d2r(double d) +{ + return M_PI * d / 180.0; +} + +/* | a b | + | c d | */ +static double det(double a, double b, double c, double d) +{ + return a * d - b * c; +} + +/* The lines are x1y1-x2y2 and x3y3-x4y4. Returns rnd_true if they + intersect. */ +static int intersection_of_lines(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int *xr, int *yr) +{ + double x, y, d; + d = det(x1 - x2, y1 - y2, x3 - x4, y3 - y4); + if (!d) + return 0; + x = (det(det(x1, y1, x2, y2), x1 - x2, det(x3, y3, x4, y4), x3 - x4) / d); + y = (det(det(x1, y1, x2, y2), y1 - y2, det(x3, y3, x4, y4), y3 - y4) / d); + *xr = (int) (x + 0.5); + *yr = (int) (y + 0.5); + return 1; +} + +/* distance between a line and a point */ +static double dist_lp(int x1, int y1, int x2, int y2, int px, int py) +{ + double den = rnd_distance(x1, y1, x2, y2); + double rv = (fabs(((double) x2 - x1) * ((double) y1 - py) + - ((double) x1 - px) * ((double) y2 - y1)) + / den); +#if TRACE1 + rnd_printf("dist %#mD-%#mD to %#mD is %f\n", x1, y1, x2, y2, px, py, rv); +#endif + return rv; +} + +/*****************************************************************************/ +/* */ +/* Single Pofgw_error_t pcb_act_Puller */ +/* */ +/*****************************************************************************/ + +static rnd_r_dir_t line_callback(const rnd_box_t * b, void *cl) +{ + /* pcb_layer_t *layer = (pcb_layer_t *)cl; */ + pcb_line_t *l = (pcb_line_t *) b; + double d1, d2, t; +#if TRACE1 + rnd_printf("line %#mD .. %#mD\n", l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y); +#endif + d1 = rnd_distance(l->Point1.X, l->Point1.Y, x, y); + d2 = rnd_distance(l->Point2.X, l->Point2.Y, x, y); + if ((d1 < 2 || d2 < 2) && !line_exact) { + line_exact = 1; + the_line = 0; + } + t = line_exact ? 2 : l->Thickness / 2; + if (d1 < t || d2 < t) { + if (the_line) + multi = 1; + the_line = l; +#if TRACE1 + printf("picked, exact %d\n", line_exact); +#endif + } + return RND_R_DIR_FOUND_CONTINUE; +} + +static rnd_r_dir_t arc_callback(const rnd_box_t * b, void *cl) +{ + /* pcb_layer_t *layer = (pcb_layer_t *) cl; */ + pcb_arc_t *a = (pcb_arc_t *) b; + +#if TRACE1 + rnd_printf("arc a %#mD r %#mS sa %ld d %ld\n", a->X, a->Y, a->Width, a->StartAngle, a->Delta); +#endif + if (!arc_endpoint_is(a, a->StartAngle, x, y) + && !arc_endpoint_is(a, a->StartAngle + a->Delta, x, y)) + return 1; + if (arc_dist < 2) { + if (!arc_exact) { + arc_exact = 1; + the_arc = 0; + } + if (the_arc) + multi = 1; + the_arc = a; +#if TRACE1 + printf("picked, exact %d\n", arc_exact); +#endif + } + else if (!arc_exact) { + if (the_arc) + multi = 1; + the_arc = a; +#if TRACE1 + printf("picked, exact %d\n", arc_exact); +#endif + } + return RND_R_DIR_FOUND_CONTINUE; +} + +static int find_pair(int Px, int Py) +{ + rnd_box_t spot; + +#if TRACE1 + rnd_printf("\nPuller find_pair at %#mD\n", pcb_crosshair.X, pcb_crosshair.Y); +#endif + + x = Px; + y = Py; + multi = 0; + line_exact = arc_exact = 0; + the_line = 0; + the_arc = 0; + spot.X1 = x - 1; + spot.Y1 = y - 1; + spot.X2 = x + 1; + spot.Y2 = y + 1; + rnd_r_search(PCB_CURRLAYER(PCB)->line_tree, &spot, NULL, line_callback, PCB_CURRLAYER(PCB), NULL); + rnd_r_search(PCB_CURRLAYER(PCB)->arc_tree, &spot, NULL, arc_callback, PCB_CURRLAYER(PCB), NULL); + if (the_line && the_arc && !multi) + return 1; + x = Px; + y = Py; + return 0; +} + + +static const char pcb_acts_Puller[] = "pcb_act_Puller()"; +static const char pcb_acth_Puller[] = "Pull an arc-line junction tight."; +/* DOC: puller.html */ +static fgw_error_t pcb_act_Puller(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_coord_t Ux, Uy; + double arc_angle, base_angle; +#if TRACE1 + double line_angle, rel_angle; +#endif + double tangent; + int new_delta_angle; + + rnd_hid_get_coords("Click on a line-arc intersection or line segment", &Ux, &Uy, 0); + + if (!find_pair(pcb_crosshair.X, pcb_crosshair.Y)) { + if (!find_pair(Ux, Uy)) { + RND_ACT_IRES(1); + return 0; + } + } + + if (within(the_line->Point1.X, the_line->Point1.Y, x, y, the_line->Thickness)) { + ex = the_line->Point2.X; + ey = the_line->Point2.Y; + the_line->Point2.X = the_line->Point1.X; + the_line->Point2.Y = the_line->Point1.Y; + the_line->Point1.X = ex; + the_line->Point1.Y = ey; + } + else if (!within(the_line->Point2.X, the_line->Point2.Y, x, y, the_line->Thickness)) { +#if TRACE1 + printf("Line endpoint not at cursor\n"); +#endif + RND_ACT_IRES(1); + return 0; + } + ex = the_line->Point1.X; + ey = the_line->Point1.Y; + + cx = the_arc->X; + cy = the_arc->Y; + if (arc_endpoint_is(the_arc, the_arc->StartAngle, x, y)) { + pcb_arc_set_angles(PCB_CURRLAYER(PCB), the_arc, the_arc->StartAngle + the_arc->Delta, -the_arc->Delta); + } + else if (!arc_endpoint_is(the_arc, the_arc->StartAngle + the_arc->Delta, x, y)) { +#if TRACE1 + printf("arc not endpoints\n"); +#endif + RND_ACT_IRES(1); + return 0; + } + + if (within(cx, cy, ex, ey, the_arc->Width * 2)) { +#if TRACE1 + printf("line ends inside arc\n"); +#endif + RND_ACT_IRES(1); + return 0; + } + + if (the_arc->Delta > 0) + arc_angle = the_arc->StartAngle + the_arc->Delta + 90; + else + arc_angle = the_arc->StartAngle + the_arc->Delta - 90; + base_angle = r2d(atan2(ey - cy, cx - ex)); + + tangent = r2d(acos(the_arc->Width / rnd_distance(cx, cy, ex, ey))); + +#if TRACE1 + line_angle = r2d(atan2(ey - y, x - ex)); + rel_angle = line_angle - arc_angle; + printf("arc %g line %g rel %g base %g\n", arc_angle, line_angle, rel_angle, base_angle); + printf("tangent %g\n", tangent); + + printf("arc was start %ld end %ld\n", the_arc->StartAngle, the_arc->StartAngle + the_arc->Delta); +#endif + + if (the_arc->Delta > 0) + arc_angle = base_angle - tangent; + else + arc_angle = base_angle + tangent; +#if TRACE1 + printf("new end angle %g\n", arc_angle); +#endif + + new_delta_angle = arc_angle - the_arc->StartAngle; + if (new_delta_angle > 180) + new_delta_angle -= 360; + if (new_delta_angle < -180) + new_delta_angle += 360; + pcb_arc_set_angles(PCB_CURRLAYER(PCB), the_arc, the_arc->StartAngle, new_delta_angle); + +#if TRACE1 + printf("arc now start %ld end %ld\n", the_arc->StartAngle, the_arc->StartAngle + new_delta_angle); +#endif + + arc_angle = the_arc->StartAngle + the_arc->Delta; + x = the_arc->X - the_arc->Width * cos(d2r(arc_angle)) + 0.5; + y = the_arc->Y + the_arc->Height * sin(d2r(arc_angle)) + 0.5; + + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), the_line, &(the_line->Point2), x - the_line->Point2.X, y - the_line->Point2.Y); + + rnd_gui->invalidate_all(rnd_gui); + pcb_undo_inc_serial(); + + RND_ACT_IRES(0); + return 0; +} + +/*****************************************************************************/ +/* */ +/* Global pcb_act_Puller */ +/* */ +/*****************************************************************************/ + +static const char pcb_acts_GlobalPuller[] = "pcb_act_GlobalPuller([Found|Selected])"; +static const char pcb_acth_GlobalPuller[] = "Pull all traces tight. With no argument it runs on the current layer."; + +/* Ok, here's the deal. We look for the intersection of two traces. + The triangle formed by those traces is searched for things we need + to avoid. From the other two corners of the triangle, we compute + the angle to each obstacle, and remember the ones closest to the + start angles. If the two traces hit the same obstacle, we put in + the arc and we're done. Else, we bring the traces up to the + obstacles and start again. + + Note that we assume each start point is a tangent to an arc. We + start with a radius of zero, but future steps use the arcs we + create as we go. + + For obstacles, we list each round pin, pad, via, and line/arc + endpoints as points with a given radius. For each square pin, pad, + via, and polygon points, we list each corner with a zero radius. + We also list arcs from their centerpoint. + + We don't currently do anything to move vias, or intersections of + three or more traces. In the future, three-way intersections will + be handles similarly to two-way - calculate the range of angles + valid from each of the three other endpoints, choose the angle + closest to making 120 degree angles at the center. For four-way or + more intersections, we break them up into multiple three-way + intersections. + + For simplicity, we only do the current layer at this time. We will + also edit the lines and arcs in place so that the intersection is + always on the second point, and the other ends are always at + start+delta for arcs. + + We also defer intersections which are blocked by other + intersections yet to be moved; the idea is to wait until those have + been moved so we don't end up with arcs that no longer wrap around + things. At a later point, we may choose to pull arced corners in + also. + + You'll see lots of variables of the form "foo_sign" which keep + track of which way things are pointing. This is because everything + is relative to corners and arcs, not absolute directions. +*/ + +static int nloops, npulled; + +static void status() +{ + fprintf(stderr, "%6d loops, %d pulled \r", nloops, npulled); +} + +/* Extra data we need to temporarily attach to all lines and arcs. */ +typedef struct End { + /* These point to "multi_next" if there are more than one. */ + struct Extra *next; + void *pin; + unsigned in_pin:1; + unsigned at_pin:1; + unsigned is_pad:1; + unsigned pending:1; /* set if this may be moved later */ + int x, y; /* arc endpoint */ + /* If not NULL, points to End with pending==1 we're blocked on. */ + struct End *waiting_for; +} End; + +typedef struct Extra { + End start; + End end; + unsigned found:1; + unsigned deleted:1; + int type; + union { + pcb_line_t *line; + pcb_arc_t *arc; + } parent; +} Extra; + +static Extra multi_next; +static GHashTable *lines; +static GHashTable *arcs; +static int did_something; +static int current_is_component, current_is_solder; + +/* If set, these are the pins/pads/vias that this path ends on. */ +/* static void *start_pin_pad, *end_pin_pad; */ + +#if TRACE1 +static void trace_paths(); +#endif +static void mark_line_for_deletion(pcb_line_t *); + +#define LINE2EXTRA(l) ((Extra *)g_hash_table_lookup (lines, l)) +#define ARC2EXTRA(a) ((Extra *)g_hash_table_lookup (arcs, a)) +#define EXTRA2LINE(e) (e->parent.line) +#define EXTRA2ARC(e) (e->parent.arc) +#define EXTRA_IS_LINE(e) (e->type == PCB_OBJ_LINE) +#define EXTRA_IS_ARC(e) (e->type == PCB_OBJ_ARC) + +static void unlink_end(Extra * x, Extra ** e) +{ + if (*e) { + if ((*e)->start.next == x) { +#if TRACE1 + printf("%d: unlink_end, was %p\n", __LINE__, (void *)(*e)->start.next); +#endif + (*e)->start.next = &multi_next; + } + if ((*e)->end.next == x) { +#if TRACE1 + printf("%d: unlink_end, was %p\n", __LINE__, (void *)(*e)->start.next); +#endif + (*e)->end.next = &multi_next; + } + } +#if TRACE1 + printf("%d: unlink_end, was %p\n", __LINE__, (void *)(*e)); +#endif + (*e) = &multi_next; +} + +#if TRACE1 + +static void clear_found_cb(pcb_any_obj_t * ptr, Extra * extra, void *userdata) +{ + extra->found = 0; +} + +static void clear_found() +{ + g_hash_table_foreach(lines, (GHFunc) clear_found_cb, NULL); + g_hash_table_foreach(arcs, (GHFunc) clear_found_cb, NULL); +} +#endif + +static void fix_arc_extra(pcb_arc_t *a, Extra * e) +{ +#if TRACE1 + printf("new arc angles %ld %ld\n", a->StartAngle, a->Delta); +#endif + e->start.x = a->X - (a->Width * cos(d2r(a->StartAngle)) + 0.5); + e->start.y = a->Y + (a->Height * sin(d2r(a->StartAngle)) + 0.5); + e->end.x = a->X - (a->Width * cos(d2r(a->StartAngle + a->Delta)) + 0.5); + e->end.y = a->Y + (a->Height * sin(d2r(a->StartAngle + a->Delta)) + 0.5); +#if TRACE1 + rnd_printf("new X,Y is %#mD to %#mD\n", e->start.x, e->start.y, e->end.x, e->end.y); +#endif +} + +typedef struct { + void *me; + int x, y; + int is_arc; + Extra **extra_ptr; +} FindPairCallbackStruct; + +#define NEAR(a,b) ((a) <= (b) + 2 && (a) >= (b) - 2) + +static rnd_r_dir_t find_pair_line_callback(const rnd_box_t * b, void *cl) +{ + pcb_line_t *line = (pcb_line_t *) b; +#if TRACE1 + Extra *e = LINE2EXTRA(line); +#endif + FindPairCallbackStruct *fpcs = (FindPairCallbackStruct *) cl; + + if (line == fpcs->me) + return RND_R_DIR_NOT_FOUND; +#ifdef CHECK_LINE_PT_NEG + if (line->Point1.X < 0) + abort1(); +#endif +#if TRACE1 + rnd_printf(" - %p line %#mD or %#mD\n", (void *)e, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); +#endif + if ((NEAR(line->Point1.X, fpcs->x) && NEAR(line->Point1.Y, fpcs->y)) + || (NEAR(line->Point2.X, fpcs->x) && NEAR(line->Point2.Y, fpcs->y))) { + if (*fpcs->extra_ptr) { +#if TRACE1 + printf("multiple, was %p\n", (void *)*fpcs->extra_ptr); +#endif + *fpcs->extra_ptr = &multi_next; + } + else { + *fpcs->extra_ptr = LINE2EXTRA(line); +#if TRACE1 + printf(" - next now %p\n", (void *)*fpcs->extra_ptr); +#endif + } + } + return RND_R_DIR_NOT_FOUND; +} + +static rnd_r_dir_t find_pair_arc_callback(const rnd_box_t * b, void *cl) +{ + pcb_arc_t *arc = (pcb_arc_t *) b; + Extra *e = ARC2EXTRA(arc); + FindPairCallbackStruct *fpcs = (FindPairCallbackStruct *) cl; + + if (arc == fpcs->me) + return RND_R_DIR_NOT_FOUND; +#if TRACE1 + rnd_printf(" - %p arc %#mD or %#mD\n", (void *)e, e->start.x, e->start.y, e->end.x, e->end.y); +#endif + if ((NEAR(e->start.x, fpcs->x) && NEAR(e->start.y, fpcs->y)) + || (NEAR(e->end.x, fpcs->x) && NEAR(e->end.y, fpcs->y))) { + if (*fpcs->extra_ptr) { +#if TRACE1 + printf("multiple, was %p\n", (void *)*fpcs->extra_ptr); +#endif + *fpcs->extra_ptr = &multi_next; + } + else + *fpcs->extra_ptr = e; + } + return RND_R_DIR_NOT_FOUND; +} + +static void find_pairs_1(void *me, Extra ** e, int x, int y) +{ + FindPairCallbackStruct fpcs; + rnd_box_t b; + + if (*e) + return; + + fpcs.me = me; + fpcs.extra_ptr = e; + fpcs.x = x; + fpcs.y = y; +#if TRACE1 + rnd_printf("looking for %#mD\n", x, y); +#endif + b.X1 = x - 10; + b.X2 = x + 10; + b.Y1 = y - 10; + b.Y2 = y + 10; + rnd_r_search(PCB_CURRLAYER(PCB)->line_tree, &b, NULL, find_pair_line_callback, &fpcs, NULL); + rnd_r_search(PCB_CURRLAYER(PCB)->arc_tree, &b, NULL, find_pair_arc_callback, &fpcs, NULL); +} + +static int check_point_in_pstk(pcb_pstk_t *ps, pcb_layer_t *layer, int x, int y, End *e) +{ + pcb_pstk_shape_t *shape = pcb_pstk_shape_at(PCB, ps, layer); + if (shape == NULL) return 0; + switch(shape->shape) { + case PCB_PSSH_POLY: + if (shape->data.poly.pa == NULL) + pcb_pstk_shape_update_pa(&shape->data.poly); + return pcb_pline_embraces_circ(shape->data.poly.pa->contours, x - ps->x, y - ps->y, 1); + case PCB_PSSH_LINE: + { + pcb_any_line_t tmp; + tmp.Point1.X = shape->data.line.x1 + ps->x; + tmp.Point1.Y = shape->data.line.y1 + ps->y; + tmp.Point2.X = shape->data.line.x2 + ps->x; + tmp.Point2.Y = shape->data.line.y2 + ps->y; + tmp.Clearance = 0; + tmp.Thickness = shape->data.line.thickness; + tmp.Flags = shape->data.line.square ? pcb_flag_make(PCB_FLAG_SQUARE) : pcb_no_flags(); + return pcb_is_point_in_line(x, y, 1, &tmp); + } + case PCB_PSSH_CIRC: + { + rnd_coord_t cx = shape->data.circ.x + ps->x, cy = shape->data.circ.y + ps->y; + double max_dist2 = ((double)shape->data.circ.dia/2.0) * ((double)shape->data.circ.dia/2.0); + double dist2 = rnd_distance2(cx, cy, x, y); + return (dist2 <= max_dist2); + } + case PCB_PSSH_HSHADOW: + return 0; + } + return 0; +} + +static rnd_r_dir_t find_pair_pstkline_callback(const rnd_box_t *b, void *cl) +{ + pcb_line_t *line = (pcb_line_t *)b; + pcb_pstk_t *pin = (pcb_pstk_t *)cl; + Extra *e = LINE2EXTRA(line); + int hits; + +#ifdef CHECK_LINE_PT_NEG + if (line->Point1.X < 0) + abort1(); +#endif + + assert(line->parent_type == PCB_PARENT_LAYER); + hits = check_point_in_pstk(pin, line->parent.layer, line->Point1.X, line->Point1.Y, &(e->start)); + hits += check_point_in_pstk(pin, line->parent.layer, line->Point2.X, line->Point2.Y, &(e->end)); + + if (hits) + return RND_R_DIR_NOT_FOUND; + + /* See if the line passes through this pin - if so, split it into two + lines so they can be pulled independently. */ + if (pcb_isc_pstk_line(pcb_find0, pin, line, rnd_false)) { +#if TRACE1 + rnd_printf("splitting line %#mD-%#mD because it passes through pin %#mD r%d\n", + line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y, pin->x, pin->y, pin->Thickness / 2); +#endif + unlink_end(e, &e->start.next); + unlink_end(e, &e->end.next); + } + return RND_R_DIR_NOT_FOUND; +} + +static rnd_r_dir_t find_pair_pstkarc_callback(const rnd_box_t *b, void *cl) +{ + pcb_arc_t *arc = (pcb_arc_t *)b; + pcb_pstk_t *pin = (pcb_pstk_t *)cl; + Extra *e = ARC2EXTRA(arc); + int hits; + + assert(arc->parent_type == PCB_PARENT_LAYER); + hits = check_point_in_pstk(pin, arc->parent.layer, e->start.x, e->start.y, &(e->start)); + hits += check_point_in_pstk(pin, arc->parent.layer, e->end.x, e->end.y, &(e->end)); + return RND_R_DIR_NOT_FOUND; +} + +static void null_multi_next_ends(pcb_any_obj_t * ptr, Extra * extra, void *userdata) +{ + if (extra->start.next == &multi_next) + extra->start.next = NULL; + + if (extra->end.next == &multi_next) + extra->end.next = NULL; +} + +static Extra *new_line_extra(pcb_line_t * line) +{ + Extra *extra = g_slice_new0(Extra); + g_hash_table_insert(lines, line, extra); + extra->parent.line = line; + extra->type = PCB_OBJ_LINE; + return extra; +} + +static Extra *new_arc_extra(pcb_arc_t * arc) +{ + Extra *extra = g_slice_new0(Extra); + g_hash_table_insert(arcs, arc, extra); + extra->parent.arc = arc; + extra->type = PCB_OBJ_ARC; + return extra; +} + +static void find_pairs_pstk(pcb_data_t *data) +{ + PCB_PADSTACK_LOOP(PCB->Data); { + rnd_box_t box; + box = padstack->BoundingBox; + rnd_r_search(PCB_CURRLAYER(PCB)->line_tree, &box, NULL, find_pair_pstkline_callback, padstack, NULL); + rnd_r_search(PCB_CURRLAYER(PCB)->arc_tree, &box, NULL, find_pair_pstkarc_callback, padstack, NULL); + } + PCB_END_LOOP; +} + +static void find_pairs_subc_pstk(pcb_data_t *data) +{ + PCB_SUBC_LOOP(data) { + find_pairs_pstk(subc->data); + find_pairs_subc_pstk(subc->data); + } + PCB_END_LOOP; +} + +static void find_pairs() +{ + PCB_ARC_LOOP(PCB_CURRLAYER(PCB)); { + Extra *e = new_arc_extra(arc); + fix_arc_extra(arc, e); + } PCB_END_LOOP; + + PCB_LINE_LOOP(PCB_CURRLAYER(PCB)); { + new_line_extra(line); + } PCB_END_LOOP; + + PCB_LINE_LOOP(PCB_CURRLAYER(PCB)); { + Extra *e = LINE2EXTRA(line); + if (line->Point1.X >= 0) { + find_pairs_1(line, &e->start.next, line->Point1.X, line->Point1.Y); + find_pairs_1(line, &e->end.next, line->Point2.X, line->Point2.Y); + } + } + PCB_END_LOOP; + + PCB_ARC_LOOP(PCB_CURRLAYER(PCB)); { + Extra *e = ARC2EXTRA(arc); + if (!e->deleted) { + find_pairs_1(arc, &e->start.next, e->start.x, e->start.y); + find_pairs_1(arc, &e->end.next, e->end.x, e->end.y); + } + } + PCB_END_LOOP; + + find_pairs_pstk(PCB->Data); + find_pairs_subc_pstk(PCB->Data); + + g_hash_table_foreach(lines, (GHFunc) null_multi_next_ends, NULL); + g_hash_table_foreach(arcs, (GHFunc) null_multi_next_ends, NULL); +} + +#define PROP_NEXT(e,n,f) \ + if (f->next->start.next == e) { \ + e = f->next; \ + n = & e->start; \ + f = & e->end; \ + } else { \ + e = f->next; \ + n = & e->end; \ + f = & e->start; } + +static void propogate_ends_at(Extra * e, End * near, End * far) +{ + while (far->in_pin && far->pin == near->pin) { + far->in_pin = 0; + if (!far->next) + return; + PROP_NEXT(e, near, far); + near->in_pin = 0; + } +} + +static void propogate_end_pin(Extra * e, End * near, End * far) +{ + void *pinpad = near->pin; + int ispad = near->is_pad; + while (far->next) { + PROP_NEXT(e, near, far); + if (near->pin == pinpad) + break; + near->pin = pinpad; + near->is_pad = ispad; + } +} + +static void propogate_end_step1_cb(pcb_any_obj_t * ptr, Extra * extra, void *userdata) +{ + if (extra->start.next != NULL && extra->start.next == extra->end.next) { + extra->end.next = NULL; + mark_line_for_deletion((pcb_line_t *) ptr); + } + + if (extra->start.at_pin) + propogate_ends_at(extra, &extra->start, &extra->end); + + if (extra->end.at_pin) + propogate_ends_at(extra, &extra->end, &extra->start); +} + +static void propogate_end_step2_cb(pcb_any_obj_t * ptr, Extra * extra, void *userdata) +{ + if (extra->start.in_pin) { +#if TRACE1 + printf("MULTI at %d: was %p\n", __LINE__, (void *)extra->start.next); +#endif + extra->start.next = NULL; + } + if (extra->end.in_pin) { +#if TRACE1 + printf("MULTI at %d: was %p\n", __LINE__, (void *)extra->end.next); +#endif + extra->end.next = NULL; + } +} + +static void propogate_end_step3_cb(pcb_any_obj_t * ptr, Extra * extra, void *userdata) +{ + if (extra->start.next) + propogate_end_pin(extra, &extra->end, &extra->start); + if (extra->end.next) + propogate_end_pin(extra, &extra->start, &extra->end); +} + +static void propogate_ends() +{ + /* First, shut of "in pin" when we have an "at pin". We also clean + up zero-length lines. */ + g_hash_table_foreach(lines, (GHFunc) propogate_end_step1_cb, NULL); + + /* Now end all paths at pins/pads. */ + g_hash_table_foreach(lines, (GHFunc) propogate_end_step2_cb, NULL); + + /* Now, propogate the pin/pad/vias along paths. */ + g_hash_table_foreach(lines, (GHFunc) propogate_end_step3_cb, NULL); +} + +static Extra *last_pextra = 0; + +static void print_extra(Extra * e, Extra * prev) +{ + int which = 0; + if (e->start.next == last_pextra) + which = 1; + else if (e->end.next == last_pextra) + which = 2; + switch (which) { + case 0: + printf("%10p %10p %10p :", (void *)e, (void *)e->start.next, (void *)e->end.next); + break; + case 1: + printf("%10p \033[33m%10p\033[0m %10p :", (void *)e, (void *)e->start.next, (void *)e->end.next); + break; + case 2: + printf("%10p %10p \033[33m%10p\033[0m :", (void *)e, (void *)e->start.next, (void *)e->end.next); + break; + } + last_pextra = e; + printf(" %c%c", e->deleted ? 'd' : '-', e->found ? 'f' : '-'); + printf(" s:%s%s%s%s", + e->start.in_pin ? "I" : "-", e->start.at_pin ? "A" : "-", e->start.is_pad ? "P" : "-", e->start.pending ? "p" : "-"); + printf(" e:%s%s%s%s ", + e->end.in_pin ? "I" : "-", e->end.at_pin ? "A" : "-", e->end.is_pad ? "P" : "-", e->end.pending ? "p" : "-"); + + if (EXTRA_IS_LINE(e)) { + pcb_line_t *line = EXTRA2LINE(e); + rnd_printf(" %p L %#mD-%#mD", (void *)line, line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); + printf(" %s %p %s %p\n", e->start.is_pad ? "pad" : "pin", (void *)e->start.pin, e->end.is_pad ? "pad" : "pin", (void *)e->end.pin); + } + else if (EXTRA_IS_ARC(e)) { + pcb_arc_t *arc = EXTRA2ARC(e); + rnd_printf(" %p A %#mD-%#mD", (void *)arc, e->start.x, e->start.y, e->end.x, e->end.y); + rnd_printf(" at %#mD ang %ld,%ld\n", arc->X, arc->Y, arc->StartAngle, arc->Delta); + } + else if (e == &multi_next) { + printf("-- Multi-next\n"); + } + else { + printf("-- Unknown extra: %p\n", (void *)e); + } +} + +#if TRACE1 +static void trace_path(Extra * e) +{ + Extra *prev = 0; + if ((e->start.next && e->end.next) + || (!e->start.next && !e->end.next)) + return; + if (e->found) + return; + printf("- path -\n"); + last_pextra = 0; + while (e) { + e->found = 1; + print_extra(e, prev); + if (e->start.next == prev) { + prev = e; + e = e->end.next; + } + else { + prev = e; + e = e->start.next; + } + } +} + +static void trace_paths() +{ + Extra *e; + + clear_found(); + PCB_LINE_LOOP(PCB_CURRLAYER(PCB)); { + e = LINE2EXTRA(line); + trace_path(e); + } PCB_END_LOOP; + PCB_ARC_LOOP(PCB_CURRLAYER(PCB)); { + e = ARC2EXTRA(arc); + trace_path(e); + } PCB_END_LOOP; +} +#endif + +static void reverse_line(pcb_line_t *line) +{ + Extra *e = LINE2EXTRA(line); + int x, y; + End etmp; + + x = line->Point1.X; + y = line->Point1.Y; +#if 1 + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), line, &(line->Point1), line->Point2.X - line->Point1.X, line->Point2.Y - line->Point1.Y); + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), line, &(line->Point2), x - line->Point2.X, y - line->Point2.Y); +#else + /* In theory, we should be using the above so that undo works. */ + line->Point1.X = line->Point2.X; + line->Point1.Y = line->Point2.Y; + line->Point2.X = x; + line->Point2.Y = y; +#endif + memcpy(&etmp, &e->start, sizeof(End)); + memcpy(&e->start, &e->end, sizeof(End)); + memcpy(&e->end, &etmp, sizeof(End)); +} + +static void reverse_arc(pcb_arc_t *arc) +{ + Extra *e = ARC2EXTRA(arc); + End etmp; + +#if 1 + pcb_arc_set_angles(PCB_CURRLAYER(PCB), arc, arc->StartAngle + arc->Delta, -arc->Delta); +#else + /* Likewise, see above. */ + arc->StartAngle += arc->Delta; + arc->Delta *= -1; +#endif + memcpy(&etmp, &e->start, sizeof(End)); + memcpy(&e->start, &e->end, sizeof(End)); + memcpy(&e->end, &etmp, sizeof(End)); +} + +static void expand_box(rnd_box_t *b, int x, int y, int t) +{ + b->X1 = MIN(b->X1, x - t); + b->X2 = MAX(b->X2, x + t); + b->Y1 = MIN(b->Y1, y - t); + b->Y2 = MAX(b->Y2, y + t); +} + +/* ---------------------------------------------------------------------- */ +/* These are the state variables for the intersection we're currently + working on. */ + +/* what we're working with */ +static pcb_arc_t *start_arc; +static pcb_line_t *start_line; +static pcb_line_t *end_line; +static pcb_arc_t *end_arc; +static Extra *start_extra, *end_extra; +static Extra *sarc_extra, *earc_extra; +static void *start_pinpad, *end_pinpad; +static int thickness; + +/* Pre-computed values. Note that all values are computed according + to CARTESIAN coordinates, not PCB coordinates. Do an up-down board + flip before wrapping your brain around the math. */ + +/* se_sign is positive when you make a right turn going from start to end. */ +/* sa_sign is positive when start's arc is on the same side of start as end. */ +/* ea_sign is positive when end's arc is on the same side of end as start. */ +/* sa_sign and ea_sign may be zero if there's no arc. */ +static double se_sign, sa_sign, ea_sign; + +static double best_angle, start_angle, end_dist; +/* arc radii are positive when they're on the same side as the things + we're interested in. */ +static int sa_r, ea_r; +static int sa_x, sa_y; /* start "arc" point */ + +/* what we've found so far */ +static int fx, fy, fr, fp; +static End *fp_end; +static double fa; /* relative angle */ + +#define gp_point_(x,y,t,e, file,line) gp_point_2(x,y,t,e,0,0, file ":" #line) +#define gp_point(x,y,t,e) gp_point_(x,y,t,e, __FILE__, __LINE__) + +static int gp_point_force(int x, int y, int t, End * e, int esa, int eda, int force, const char *name) +{ + double r, a, d; + int scx, scy, sr; + double base_angle, rel_angle, point_angle; + +#if TRACE1 + rnd_printf("\033[34mgp_point_force %#mD %#mS via %s\033[0m\n", x, y, t, name); +#endif + + if (start_arc) { + scx = start_arc->X; + scy = start_arc->Y; + sr = start_arc->Width; + } + else { + scx = start_line->Point1.X; + scy = start_line->Point1.Y; + sr = 0; + } + + r = t + thickness; + + /* See if the point is inside our start arc. */ + d = rnd_distance(scx, scy, x, y); +#if TRACE1 + rnd_printf("%f = dist #mD to %#mD\n", d, scx, scy, x, y); + rnd_printf("sr %#mS r %f d %f\n", sr, r, d); +#endif + if (d < sr - r) { +#if TRACE1 + printf("inside start arc, %f < %f\n", d, sr - r); +#endif + return 0; + } + if (sr == 0 && d < r) { +#if TRACE1 + printf("start is inside arc, %f < %f\n", d, r); +#endif + return 0; + } + + /* Now for the same tricky math we needed for the single puller. + sr and r are the radii for the two points scx,scy and x,y. */ + + /* angle between points (NOT pcb arc angles) */ + base_angle = atan2(y - scy, x - scx); +#if TRACE1 + rnd_printf("%.1f = atan2 (%#mS-%#mS = %#mS, %#mS-%#mS = %#mS)\n", r2d(base_angle), y, scy, y - scy, x, scx, x - scx); +#endif + + if ((sa_sign * sr - r) / d > 1 || (sa_sign * sr - r) / d < -1) + return 0; + + /* Angle of tangent, relative to the angle between point centers. */ + rel_angle = se_sign * asin((sa_sign * sr - r) / d); +#if TRACE1 + printf("%.1f = %d * asin ((%d * %d - %f) / %f)\n", r2d(rel_angle), (int) se_sign, (int) sa_sign, sr, r, d); +#endif + + /* Absolute angle of tangent. */ + point_angle = base_angle + rel_angle; +#if TRACE1 + printf("base angle %.1f rel_angle %.1f point_angle %.1f\n", r2d(base_angle), r2d(rel_angle), r2d(point_angle)); +#endif + + if (eda) { + /* Check arc angles */ + double pa = point_angle; + double sa = d2r(180 - esa); + double da = d2r(-eda); + + if (da < 0) { + sa = sa + da; + da = -da; + } + + pa -= se_sign * M_PI / 2; + while (sa + da < pa) + sa += M_PI * 2; + while (sa > pa) + sa -= M_PI * 2; + if (sa + da < pa) { +#if TRACE1 + printf("arc doesn't apply: sa %.1f da %.1f pa %.1f\n", r2d(sa), r2d(da), r2d(pa)); +#endif + return 0; + } + } + + a = point_angle - start_angle; + while (a > M_PI) + a -= M_PI * 2; + while (a < -M_PI) + a += M_PI * 2; +#if TRACE1 + printf(" - angle relative to S-E baseline is %.1f\n", r2d(a)); +#endif + + if (!force && a * se_sign < -0.007) { + double new_r; +#if TRACE1 + printf("skipping, would increase angle (%f * %f)\n", a, se_sign); +#endif + new_r = dist_lp(start_line->Point1.X, start_line->Point1.Y, start_line->Point2.X, start_line->Point2.Y, x, y); +#if TRACE1 + rnd_printf("point %#mD dist %#mS vs thickness %#mS\n", x, y, new_r, thickness); +#endif + new_r -= thickness; + new_r = (int) new_r - 1; +#if TRACE1 + rnd_printf(" - new thickness %f old %#mS\n", new_r, t); +#endif + if (new_r < t) + gp_point_force(x, y, new_r, e, esa, eda, 1, "gp_point_force"); + return 0; + } + +#if TRACE1 + printf("%f * %f < %f * %f ?\n", a, se_sign, best_angle, se_sign); +#endif + if (a * se_sign == best_angle * se_sign) { + double old_d = rnd_distance(start_line->Point1.X, start_line->Point1.Y, + fx, fy); + double new_d = rnd_distance(start_line->Point1.X, start_line->Point1.Y, + x, y); + if (new_d > old_d) { + best_angle = a; + fx = x; + fy = y; + fr = r; + fa = a; + fp = e ? e->pending : 0; + fp_end = e; + } + } + else if (a * se_sign < best_angle * se_sign) { + best_angle = a; + fx = x; + fy = y; + fr = r; + fa = a; + fp = e ? e->pending : 0; + fp_end = e; + } + + return 1; +} + +static int gp_point_2(int x, int y, int t, End * e, int esa, int eda, const char *func) +{ + double sc, ec; + double sd, ed; + + if (x == sa_x && y == sa_y) + return 0; + +#if TRACE1 + rnd_printf("\033[34mgp_point %#mD %#mS via %s\033[0m\n", x, y, t, func); +#endif + + /* There are two regions we care about. For points inside our + triangle, we check the crosses against start_line and end_line to + make sure the point is "inside" the triangle. For points on the + other side of the s-e line of the triangle, we check the dots to + make sure it's between our endpoints. */ + + /* See what side of the s-e line we're on */ + sc = cross2d(start_line->Point1.X, start_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y, x, y); +#if TRACE1 + printf("s-e cross = %f\n", sc); +#endif + if (t >= 0) { + if (same_sign(sc, se_sign)) { + /* Outside, check dots. */ + + /* Ok, is it "in front of" our vectors? */ + sd = dot2d(start_line->Point1.X, start_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y, x, y); +#if TRACE1 + printf("sd = %f\n", sd); +#endif + if (sd <= 0) + return 0; + + ed = dot2d(end_line->Point2.X, end_line->Point2.Y, start_line->Point1.X, start_line->Point1.Y, x, y); +#if TRACE1 + printf("ed = %f\n", ed); +#endif + if (ed <= 0) + return 0; + + sd = dist_lp(start_line->Point1.X, start_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y, x, y); + if (sd > t + thickness) + return 0; + } + else { + /* Inside, check crosses. */ + + /* First off, is it on the correct side of the start line? */ + sc = cross2d(start_line->Point1.X, start_line->Point1.Y, start_line->Point2.X, start_line->Point2.Y, x, y); +#if TRACE1 + printf("sc = %f\n", sc); +#endif + if (!same_sign(sc, se_sign)) + return 0; + + /* Ok, is it on the correct side of the end line? */ + ec = cross2d(end_line->Point1.X, end_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y, x, y); +#if TRACE1 + printf("ec = %f\n", ec); +#endif + if (!same_sign(ec, se_sign)) + return 0; + } + } + +#if TRACE1 + printf("in range!\n"); +#endif + + return gp_point_force(x, y, t, e, esa, eda, 0, func); +} + +static rnd_r_dir_t gp_line_cb(const rnd_box_t * b, void *cb) +{ + const pcb_line_t *l = (pcb_line_t *) b; + Extra *e = LINE2EXTRA(l); + if (l == start_line || l == end_line) + return RND_R_DIR_NOT_FOUND; + if (e->deleted) + return RND_R_DIR_NOT_FOUND; +#ifdef CHECK_LINE_PT_NEG + if (l->Point1.X < 0) + abort1(); +#endif + if (!e->start.next || !EXTRA_IS_ARC(e->start.next)) + gp_point(l->Point1.X, l->Point1.Y, l->Thickness / 2, &e->start); + if (!e->end.next || !EXTRA_IS_ARC(e->end.next)) + gp_point(l->Point2.X, l->Point2.Y, l->Thickness / 2, &e->end); + return RND_R_DIR_NOT_FOUND; +} + +static rnd_r_dir_t gp_arc_cb(const rnd_box_t * b, void *cb) +{ + const pcb_arc_t *a = (pcb_arc_t *) b; + Extra *e = ARC2EXTRA(a); + if (a == start_arc || a == end_arc) + return RND_R_DIR_NOT_FOUND; + if (e->deleted) + return RND_R_DIR_NOT_FOUND; + gp_point_2(a->X, a->Y, a->Width + a->Thickness / 2, 0, a->StartAngle, a->Delta, "gp_arc_cb"); + if (start_arc && a->X == start_arc->X && a->Y == start_arc->Y) + return RND_R_DIR_NOT_FOUND; + if (end_arc && a->X != end_arc->X && a->Y != end_arc->Y) + return RND_R_DIR_NOT_FOUND; + + if (e->start.next || e->end.next) + return RND_R_DIR_NOT_FOUND; + + gp_point(e->start.x, e->start.y, a->Thickness / 2, 0); + gp_point(e->end.x, e->end.y, a->Thickness / 2, 0); + return RND_R_DIR_NOT_FOUND; +} + +static rnd_r_dir_t gp_text_cb(const rnd_box_t * b, void *cb) +{ + const pcb_text_t *t = (pcb_text_t *) b; + /* FIXME: drop in the actual text-line endpoints later. */ + gp_point(t->BoundingBox.X1, t->BoundingBox.Y1, 0, 0); + gp_point(t->BoundingBox.X1, t->BoundingBox.Y2, 0, 0); + gp_point(t->BoundingBox.X2, t->BoundingBox.Y2, 0, 0); + gp_point(t->BoundingBox.X2, t->BoundingBox.Y1, 0, 0); + return RND_R_DIR_NOT_FOUND; +} + +static rnd_r_dir_t gp_poly_cb(const rnd_box_t * b, void *cb) +{ + int i; + const pcb_poly_t *p = (pcb_poly_t *) b; + for (i = 0; i < p->PointN; i++) + gp_point(p->Points[i].X, p->Points[i].Y, 0, 0); + return RND_R_DIR_NOT_FOUND; +} + +static rnd_r_dir_t gp_pstk_cb(const rnd_box_t *b, void *cb) +{ + pcb_pstk_t *ps = (pcb_pstk_t *)b; /* have to drop const because we may update the cache in ps */ + pcb_layer_t *layer = PCB_CURRLAYER(PCB); + pcb_pstk_shape_t *shape = pcb_pstk_shape_at(PCB, ps, layer), tmpshp; + int n; + + if (ps == start_pinpad || ps == end_pinpad) + return RND_R_DIR_NOT_FOUND; + + if (shape == NULL) return 0; + retry:; + switch(shape->shape) { + case PCB_PSSH_HSHADOW: + shape = pcb_pstk_hshadow_shape(ps, shape, &tmpshp); + if (shape == NULL) + return 0; + goto retry; + case PCB_PSSH_CIRC: + gp_point(ps->x + shape->data.circ.x, ps->y + shape->data.circ.y, shape->data.circ.dia/2, 0); + break; + case PCB_PSSH_POLY: + for(n = 0; n < shape->data.poly.len; n++) + gp_point(ps->x + shape->data.poly.x[n], ps->y + shape->data.poly.y[n], 0, 0); + break; + case PCB_PSSH_LINE: + if (shape->data.line.square) { + gp_point(ps->bbox_naked.X1, ps->bbox_naked.Y1, 0, 0); + gp_point(ps->bbox_naked.X1, ps->bbox_naked.Y2, 0, 0); + gp_point(ps->bbox_naked.X2, ps->bbox_naked.Y1, 0, 0); + gp_point(ps->bbox_naked.X2, ps->bbox_naked.Y2, 0, 0); + } + else { + gp_point(ps->x + shape->data.line.x1, ps->y + shape->data.line.y1, shape->data.line.thickness/2, 0); + gp_point(ps->x + shape->data.line.x2, ps->y + shape->data.line.y2, shape->data.line.thickness/2, 0); + } + break; + } + return RND_R_DIR_NOT_FOUND; +} + +static pcb_line_t *create_line(pcb_line_t *sample, int x1, int y1, int x2, int y2) +{ +#if TRACE1 + Extra *e; + rnd_printf("create_line from %#mD to %#mD\n", x1, y1, x2, y2); +#endif + pcb_line_t *line = pcb_line_new(PCB_CURRLAYER(PCB), x1, y1, x2, y2, + sample->Thickness, sample->Clearance, sample->Flags); + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, PCB_CURRLAYER(PCB), line, line); + +#if TRACE1 + e = +#endif + new_line_extra(line); +#if TRACE1 + printf(" - line extra is %p\n", (void *)e); +#endif + return line; +} + +static pcb_arc_t *create_arc(pcb_line_t *sample, int x, int y, int r, int sa, int da) +{ + Extra *e; + pcb_arc_t *arc; + + if (r % 100 == 1) + r--; + if (r % 100 == 99) + r++; +#if TRACE1 + rnd_printf("create_arc at %#mD r %#mS sa %d delta %d\n", x, y, r, sa, da); +#endif + arc = pcb_arc_new(PCB_CURRLAYER(PCB), x, y, r, r, sa, da, sample->Thickness, sample->Clearance, sample->Flags, rnd_true); + if (arc == 0) { + arc = pcb_arc_new(PCB_CURRLAYER(PCB), x, y, r, r, sa, da * 2, sample->Thickness, sample->Clearance, sample->Flags, rnd_true); + } + pcb_undo_add_obj_to_create(PCB_OBJ_ARC, PCB_CURRLAYER(PCB), arc, arc); + + if (!arc) + longjmp(abort_buf, 1); + + e = new_arc_extra(arc); +#if TRACE1 + printf(" - arc extra is %p\n", (void *)e); +#endif + fix_arc_extra(arc, e); + return arc; +} + +static void unlink_extras(Extra * e) +{ +#if TRACE1 + fprintf(stderr, "unlink %p\n", (void *)e); + print_extra(e, 0); +#endif + if (e->start.next) { +#if TRACE1 + print_extra(e->start.next, 0); +#endif + if (e->start.next->start.next == e) { +#if TRACE1 + fprintf(stderr, " - %p->start points to me\n", (void *)e->start.next); +#endif + e->start.next->start.next = e->end.next; + } + else if (e->start.next->end.next == e) { +#if TRACE1 + fprintf(stderr, " - %p->end points to me\n", (void *)e->start.next); +#endif + e->start.next->end.next = e->end.next; + } + else { + fprintf(stderr, " - %p doesn't point to me!\n", (void *)e->start.next); + abort(); + } + } + if (e->end.next) { +#if TRACE1 + print_extra(e->end.next, 0); +#endif + if (e->end.next->start.next == e) { +#if TRACE1 + fprintf(stderr, " - %p->end points to me\n", (void *)e->end.next); +#endif + e->end.next->start.next = e->start.next; + } + else if (e->end.next->end.next == e) { +#if TRACE1 + fprintf(stderr, " - %p->end points to me\n", (void *)e->end.next); +#endif + e->end.next->end.next = e->start.next; + } + else { + fprintf(stderr, " - %p doesn't point to me!\n", (void *)e->end.next); + abort(); + } + } + e->start.next = e->end.next = 0; +} + +static void mark_line_for_deletion(pcb_line_t *l) +{ + Extra *e = LINE2EXTRA(l); + if (e->deleted) { + fprintf(stderr, "double delete?\n"); + abort(); + } + e->deleted = 1; + unlink_extras(e); +#if TRACE1 + rnd_printf("pcb_marked line %p for deletion %#mD to %#mD\n", (void *)e, l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y); +#endif +#if 0 + if (l->Point1.X < 0) { + fprintf(stderr, "double neg move?\n"); + abort(); + } + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), l, &(l->Point1), -1 - l->Point1.X, -1 - l->Point1.Y); + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), l, &(l->Point2), -1 - l->Point2.X, -1 - l->Point2.Y); +#endif +} + +static void mark_arc_for_deletion(pcb_arc_t *a) +{ + Extra *e = ARC2EXTRA(a); + e->deleted = 1; + unlink_extras(e); +#if TRACE1 + printf("pcb_marked arc %p for deletion %ld < %ld\n", (void *)e, a->StartAngle, a->Delta); +#endif +} + +/* Given a starting line, which may be attached to an arc, and which + intersects with an ending line, which also may be attached to an + arc, maybe pull them. We assume start_line is attached to the arc + via Point1, and attached to the end line via Point2. Likewise, we + make end_line attach to the start_line via Point1 and the arc via + Point 2. We also make the arcs attach on the Delta end, not the + Start end. Here's a picture: + + S S+D P1 P2 P1 P2 S+D S + *--- start_arc ---*--- start_line ---*--- end_line ---*--- end_arc ---* + S E S E S E E S +*/ + +static void maybe_pull_1(pcb_line_t *line) +{ + rnd_box_t box; + /* Line half-thicknesses, including line space */ + int ex, ey; + pcb_line_t *new_line; + Extra *new_lextra; + pcb_arc_t *new_arc; + Extra *new_aextra; + double abs_angle; + + start_line = line; + start_extra = LINE2EXTRA(start_line); + end_extra = start_extra->end.next; + end_line = EXTRA2LINE(end_extra); + if (end_extra->deleted) { + start_extra->end.pending = 0; + return; + } + + if (end_extra->end.next == start_extra) + reverse_line(end_line); + + if (start_extra->start.next && EXTRA_IS_ARC(start_extra->start.next)) { + sarc_extra = start_extra->start.next; + start_arc = EXTRA2ARC(sarc_extra); + if (sarc_extra->start.next == start_extra) + reverse_arc(start_arc); + } + else { + start_arc = 0; + sarc_extra = 0; + } + + if (end_extra->end.next && EXTRA_IS_ARC(end_extra->end.next)) { + earc_extra = end_extra->end.next; + end_arc = EXTRA2ARC(earc_extra); + if (earc_extra->start.next == end_extra) + reverse_arc(end_arc); + } + else { + end_arc = 0; + earc_extra = 0; + } + +#if TRACE1 + printf("maybe_pull_1 %p %p %p %p\n", (void *)sarc_extra, (void *)start_extra, (void *)end_extra, (void *)earc_extra); + if (sarc_extra) + print_extra(sarc_extra, 0); + print_extra(start_extra, 0); + print_extra(end_extra, 0); + if (earc_extra) + print_extra(earc_extra, 0); + + if (start_extra->deleted || end_extra->deleted || (sarc_extra && sarc_extra->deleted) + || (earc_extra && earc_extra->deleted)) { + printf(" one is deleted?\n"); + fflush(stdout); + abort(); + } +#endif + + if (!start_extra->end.pending) + return; +#if 0 + if (start_extra->end.waiting_for && start_extra->end.waiting_for->pending) + return; +#endif + + if (start_line->Thickness != end_line->Thickness) + return; + thickness = (start_line->Thickness + 1) / 2 + conf_core.design.bloat; + + /* At this point, our expectations are all met. */ + + box.X1 = start_line->Point1.X - thickness; + box.X2 = start_line->Point1.X + thickness; + box.Y1 = start_line->Point1.Y - thickness; + box.Y2 = start_line->Point1.Y + thickness; + expand_box(&box, start_line->Point2.X, start_line->Point2.Y, thickness); + expand_box(&box, end_line->Point2.X, end_line->Point2.Y, thickness); + if (start_arc) + expand_box(&box, sarc_extra->start.x, sarc_extra->start.y, start_arc->Thickness / 2); + if (end_arc) + expand_box(&box, earc_extra->start.x, earc_extra->start.y, end_arc->Thickness / 2); + + + se_sign = copysign(1, cross2d(start_line->Point1.X, start_line->Point1.Y, + start_line->Point2.X, start_line->Point2.Y, end_line->Point2.X, end_line->Point2.Y)); + best_angle = se_sign * M_PI; + if (start_arc) { + sa_sign = copysign(1, -start_arc->Delta); + sa_sign *= se_sign; + } + else + sa_sign = 0; + if (end_arc) { + ea_sign = copysign(1, -end_arc->Delta); + ea_sign *= -se_sign; + } + else + ea_sign = 0; + + start_angle = atan2(start_line->Point2.Y - start_line->Point1.Y, start_line->Point2.X - start_line->Point1.X); +#if TRACE1 + printf("se_sign %f sa_sign %f ea_sign %f best_angle %f start_angle %f\n", + se_sign, sa_sign, ea_sign, r2d(best_angle), r2d(start_angle)); +#endif + + if (start_arc) { + sa_x = start_arc->X; + sa_y = start_arc->Y; + if (same_sign(start_arc->Delta, se_sign)) + sa_r = -start_arc->Width; + else + sa_r = start_arc->Width; + } + else { + sa_x = start_line->Point1.X; + sa_y = start_line->Point1.Y; + sa_r = 0; + } + + if (end_arc) { + if (ea_sign < 0) + ea_r = end_arc->Width; + else + ea_r = -end_arc->Width; + } + else + ea_r = 0; + +#if TRACE1 + trace_path(sarc_extra ? sarc_extra : start_extra); +#endif + + if (end_arc) { + gp_point_force(end_arc->X, end_arc->Y, -ea_r - thickness, 0, 0, 0, 1, "end arc"); + ex = end_arc->X; + ey = end_arc->Y; + } + else { + gp_point_force(end_line->Point2.X, end_line->Point2.Y, -thickness, 0, 0, 0, 1, "end arc"); + ex = end_line->Point2.X; + ey = end_line->Point2.Y; + } + + fx = ex; + fy = ey; + if (fx < 0) { + rnd_fprintf(stderr, "end line corrupt? f is %#mD\n", fx, fy); + print_extra(end_extra, 0); + if (earc_extra) + print_extra(earc_extra, 0); + abort(); + } + + end_dist = rnd_distance(end_line->Point1.X, end_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y); + + start_pinpad = start_extra->start.pin; + end_pinpad = start_extra->end.pin; + fp = 0; + + rnd_r_search(PCB_CURRLAYER(PCB)->line_tree, &box, NULL, gp_line_cb, 0, NULL); + rnd_r_search(PCB_CURRLAYER(PCB)->arc_tree, &box, NULL, gp_arc_cb, 0, NULL); + rnd_r_search(PCB_CURRLAYER(PCB)->text_tree, &box, NULL, gp_text_cb, 0, NULL); + rnd_r_search(PCB_CURRLAYER(PCB)->polygon_tree, &box, NULL, gp_poly_cb, 0, NULL); + rnd_r_search(PCB->Data->padstack_tree, &box, NULL, gp_pstk_cb, 0, NULL); + + /* radians, absolute angle of (at the moment) the start_line */ + abs_angle = fa + start_angle; + +#if TRACE1 + rnd_printf("\033[43;30mBest: at %#mD r %#mS, angle %.1f fp %d\033[0m\n", fx, fy, fr, r2d(fa), fp); +#endif + +#if 0 + if (fa > M_PI / 2 || fa < -M_PI / 2) { + PCB_FLAG_SET(PCB_FLAG_FOUND, line); + longjmp(abort_buf, 1); + } +#endif + + if (fp) { + start_extra->end.waiting_for = fp_end; + return; + } + start_extra->end.pending = 0; + + /* Step 0: check for merged arcs (special case). */ + + if (fx == ex && fy == ey && start_arc && end_arc && start_arc->X == end_arc->X && start_arc->Y == end_arc->Y) { + /* Merge arcs */ + int new_delta; + + new_delta = end_arc->StartAngle - start_arc->StartAngle; + if (start_arc->Delta > 0) { + while (new_delta > 360) + new_delta -= 360; + while (new_delta < 0) + new_delta += 360; + } + else { + while (new_delta < -360) + new_delta += 360; + while (new_delta > 0) + new_delta -= 360; + } +#if TRACE1 + rnd_printf("merging arcs at %#mS nd %d\n", start_arc->X, start_arc->Y, new_delta); + print_extra(sarc_extra, 0); + print_extra(earc_extra, 0); +#endif + mark_arc_for_deletion(end_arc); + mark_line_for_deletion(start_line); + mark_line_for_deletion(end_line); + pcb_arc_set_angles(PCB_CURRLAYER(PCB), start_arc, start_arc->StartAngle, new_delta); + fix_arc_extra(start_arc, sarc_extra); + did_something++; + return; + } + + /* Step 1: adjust start_arc's angles and move start_line's Point1 to + match it. */ + + if (start_arc) { + double new_delta; + int del_arc = 0; + + /* We must always round towards "larger arcs", whichever way that is. */ + new_delta = 180 - r2d(abs_angle); +#if TRACE1 + printf("new_delta starts at %d vs %d < %d\n", (int) new_delta, (int) start_arc->StartAngle, (int) start_arc->Delta); +#endif + if (start_arc->Delta < 0) + new_delta = (int) (new_delta) + 90; + else + new_delta = (int) new_delta - 90; + new_delta = new_delta - start_arc->StartAngle; + while (new_delta > start_arc->Delta + 180) + new_delta -= 360; + while (new_delta < start_arc->Delta - 180) + new_delta += 360; +#if TRACE1 + printf("new_delta adjusts to %d\n", (int) new_delta); + printf("fa = %f, new_delta ends at %.1f vs start %d\n", fa, new_delta, (int) start_arc->StartAngle); +#endif + + if (new_delta * start_arc->Delta <= 0) + del_arc = 1; + + pcb_arc_set_angles(PCB_CURRLAYER(PCB), start_arc, start_arc->StartAngle, new_delta); + fix_arc_extra(start_arc, sarc_extra); + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), start_line, &(start_line->Point1), + sarc_extra->end.x - start_line->Point1.X, sarc_extra->end.y - start_line->Point1.Y); + + if (del_arc) { + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), start_line, &(start_line->Point1), + sarc_extra->start.x - start_line->Point1.X, sarc_extra->start.y - start_line->Point1.Y); + mark_arc_for_deletion(start_arc); + } + } + + /* Step 1.5: If the "obstacle" is right at the end, ignore it. */ + + { + double oa = start_angle + fa - M_PI / 2 * se_sign; + double ox = fx + fr * cos(oa); + double oy = fy + fr * sin(oa); +#if TRACE1 + rnd_printf("obstacle at %#mD angle %d = arc starts at %#mD\n", fx, fy, (int) r2d(oa), (int) ox, (int) oy); +#endif + + if (rnd_distance(ox, oy, end_line->Point2.X, end_line->Point2.Y) + < fr * SIN1D) { + /* Pretend it doesn't exist. */ + fx = ex; + fy = ey; + } + } + + /* Step 2: If we have no obstacles, connect start and end. */ + +#if TRACE1 + rnd_printf("fx %#mS ex %#mS fy %#mS ey %#mS\n", fx, ex, fy, ey); +#endif + if (fx == ex && fy == ey) { + /* No obstacles. */ +#if TRACE1 + printf("\033[32mno obstacles\033[0m\n"); +#endif + if (end_arc) { + int del_arc = 0; + int new_delta, end_angle, pcb_fa, end_change; + + end_angle = end_arc->StartAngle + end_arc->Delta; + if (end_arc->Delta < 0) + end_angle -= 90; + else + end_angle += 90; + + /* We must round so as to make the larger arc. */ + if (end_arc->Delta < 0) + pcb_fa = -r2d(start_angle + fa); + else + pcb_fa = 1 - r2d(start_angle + fa); + end_change = pcb_fa - end_angle; + + while (end_change > 180) + end_change -= 360; + while (end_change < -180) + end_change += 360; + new_delta = end_arc->Delta + end_change; + + if (new_delta * end_arc->Delta <= 0) + del_arc = 1; + + pcb_arc_set_angles(PCB_CURRLAYER(PCB), end_arc, end_arc->StartAngle, new_delta); + fix_arc_extra(end_arc, earc_extra); + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), start_line, &(start_line->Point2), + earc_extra->end.x - start_line->Point2.X, earc_extra->end.y - start_line->Point2.Y); + + if (del_arc) { + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), start_line, &(start_line->Point2), + earc_extra->start.x - start_line->Point2.X, earc_extra->start.y - start_line->Point2.Y); + mark_arc_for_deletion(end_arc); + } + } + else { + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), start_line, &(start_line->Point2), + end_line->Point2.X - start_line->Point2.X, end_line->Point2.Y - start_line->Point2.Y); + } + mark_line_for_deletion(end_line); + start_extra->end.pending = 1; + +#if TRACE1 + printf("\033[35mdid_something: no obstacles\033[0m\n"); +#endif + did_something++; + npulled++; + status(); + return; + } + + /* Step 3: Compute the new intersection of start_line and end_line. */ + + ex = start_line->Point1.X + cos(start_angle + fa) * 10000.0; + ey = start_line->Point1.Y + sin(start_angle + fa) * 10000.0; +#if TRACE1 + rnd_printf("temp point %#mS\n", ex, ey); + rnd_printf("intersect %#mS-%#mS with %#mS-%#mS\n", + start_line->Point1.X, start_line->Point1.Y, + ex, ey, end_line->Point1.X, end_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y); +#endif + if (!intersection_of_lines(start_line->Point1.X, start_line->Point1.Y, + ex, ey, + end_line->Point1.X, end_line->Point1.Y, end_line->Point2.X, end_line->Point2.Y, &ex, &ey)) { + ex = end_line->Point2.X; + ey = end_line->Point2.Y; + } +#if TRACE1 + rnd_printf("new point %#mS\n", ex, ey); +#endif + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), end_line, &(end_line->Point1), ex - end_line->Point1.X, ey - end_line->Point1.Y); + + /* Step 4: Split start_line at the obstacle and insert a zero-delta + arc at it. */ + + new_arc = create_arc(start_line, fx, fy, fr, 90 - (int) (r2d(start_angle + fa) + 0.5) + 90 + 90 * se_sign, -se_sign); + new_aextra = ARC2EXTRA(new_arc); + + if (start_arc) + sarc_extra = ARC2EXTRA(start_arc); + if (end_arc) + earc_extra = ARC2EXTRA(end_arc); + + pcb_move_obj(PCB_OBJ_LINE_POINT, PCB_CURRLAYER(PCB), start_line, &(start_line->Point2), + new_aextra->start.x - start_line->Point2.X, new_aextra->start.y - start_line->Point2.Y); + + new_line = create_line(start_line, new_aextra->end.x, new_aextra->end.y, ex, ey); + start_extra = LINE2EXTRA(start_line); + new_lextra = LINE2EXTRA(new_line); + end_extra = LINE2EXTRA(end_line); + + new_lextra->start.pin = start_extra->start.pin; + new_lextra->end.pin = start_extra->end.pin; + new_lextra->start.pending = 1; + new_lextra->end.pending = 1; + + start_extra->end.next = new_aextra; + new_aextra->start.next = start_extra; + new_aextra->end.next = new_lextra; + new_lextra->start.next = new_aextra; + new_lextra->end.next = end_extra; + end_extra->start.next = new_lextra; + + /* Step 5: Recurse. */ + + did_something++; + npulled++; + status(); +#if TRACE0 + printf("\033[35mdid_something: recursing\033[0m\n"); + { + int i = rnd_gui->confirm_dialog("recurse?", 0); + printf("confirm = %d\n", i); + if (i == 0) + return; + } + printf("\n\033[33mRECURSING\033[0m\n\n"); + pcb_undo_inc_serial(); +#endif + maybe_pull_1(new_line); +} + +/* Given a line with a end_next, attempt to pull both ends. */ +static void maybe_pull(pcb_line_t *line, Extra * e) +{ +#if TRACE0 + printf("maybe_pull: "); + print_extra(e, 0); +#endif + if (e->end.next && EXTRA_IS_LINE(e->end.next)) { + maybe_pull_1(line); + } + else { + e->end.pending = 0; + if (e->start.next && EXTRA_IS_LINE(e->start.next)) { + reverse_line(line); + maybe_pull_1(line); + } + else + e->start.pending = 0; + } +} + +static void validate_pair(Extra * e, End * end) +{ + if (!end->next) + return; + if (end->next->start.next == e) + return; + if (end->next->end.next == e) + return; + fprintf(stderr, "no backlink!\n"); + print_extra(e, 0); + print_extra(end->next, 0); + abort(); +} + +static void validate_pair_cb(pcb_any_obj_t * ptr, Extra * extra, void *userdata) +{ + validate_pair(extra, &extra->start); + validate_pair(extra, &extra->end); +} + +static void validate_pairs() +{ + g_hash_table_foreach(lines, (GHFunc) validate_pair_cb, NULL); +#if TRACE1 + printf("\narcs\n"); +#endif + g_hash_table_foreach(arcs, (GHFunc) validate_pair_cb, NULL); +} + +static void FreeExtra(Extra * extra) +{ + g_slice_free(Extra, extra); +} + +static void mark_ends_pending(pcb_line_t * line, Extra * extra, void *userdata) +{ + int *select_flags = userdata; + if (PCB_FLAGS_TEST(*select_flags, line)) { + extra->start.pending = 1; + extra->end.pending = 1; + } +} + +#if TRACE1 +static void trace_print_extra(pcb_any_obj_t * ptr, Extra * extra, void *userdata) +{ + last_pextra = (Extra *) 1; + print_extra(extra, 0); +} + +static void trace_print_lines_arcs(void) +{ + printf("\nlines\n"); + g_hash_table_foreach(lines, (GHFunc) trace_print_extra, NULL); + + printf("\narcs\n"); + g_hash_table_foreach(arcs, (GHFunc) trace_print_extra, NULL); + + printf("\n"); +} +#endif + +static fgw_error_t pcb_act_GlobalPuller(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op = -2, select_flags = 0; + unsigned int cflg; + + setbuf(stdout, 0); + nloops = 0; + npulled = 0; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, GlobalPuller, op = fgw_keyword(&argv[1])); + + switch(op) { + case F_Selected: select_flags = PCB_FLAG_SELECTED; break; + case F_Found: select_flags = PCB_FLAG_FOUND; break; + case -2: select_flags = 0; break; + default: + RND_ACT_FAIL(GlobalPuller); + } + + /* This canonicalizes all the lines, and cleans up near-misses. */ + /* rnd_actionva(&PCB->hidlib, "djopt", "puller", 0); */ + + cflg = pcb_layergrp_flags(PCB, pcb_layer_get_group_(PCB_CURRLAYER(PCB))); + current_is_solder = (cflg & PCB_LYT_BOTTOM); + current_is_component = (cflg & PCB_LYT_TOP); + + lines = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify) FreeExtra); + arcs = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify) FreeExtra); + + printf("pairing...\n"); + find_pairs(); + validate_pairs(); + + g_hash_table_foreach(lines, (GHFunc) mark_ends_pending, &select_flags); + +#if TRACE1 + trace_print_lines_arcs(); +#endif + + propogate_ends(); + +#if TRACE1 + trace_print_lines_arcs(); + trace_paths(); +#endif + + printf("pulling...\n"); + if (setjmp(abort_buf) == 0) { +#if TRACE0 + int old_did_something = -1; +#endif + did_something = 1; + while (did_something) { + nloops++; + status(); + did_something = 0; + PCB_LINE_LOOP(PCB_CURRLAYER(PCB)); { + Extra *e = LINE2EXTRA(line); + if (e->deleted) + continue; +#ifdef CHECK_LINE_PT_NEG + if (line->Point1.X < 0) + abort1(); +#endif + if (e->start.next || e->end.next) + maybe_pull(line, e); +#if TRACE0 + if (did_something != old_did_something) { + pcb_undo_inc_serial(); + old_did_something = did_something; + if (rnd_gui->confirm_dialog("more?", 0) == 0) { + did_something = 0; + break; + } + } +#endif + /*rnd_gui->progress(0,0,0); */ + } + PCB_END_LOOP; + } + } + +#if TRACE0 + printf("\nlines\n"); + g_hash_table_foreach(lines, (GHFunc) trace_print_extra, NULL); + printf("\narcs\n"); + g_hash_table_foreach(arcs, (GHFunc) trace_print_extra, NULL); + printf("\n"); + printf("\nlines\n"); +#endif + + PCB_LINE_LOOP(PCB_CURRLAYER(PCB)); + { + if (LINE2EXTRA(line)->deleted) + pcb_line_destroy(PCB_CURRLAYER(PCB), line); + } + PCB_END_LOOP; + + PCB_ARC_LOOP(PCB_CURRLAYER(PCB)); + { + if (ARC2EXTRA(arc)->deleted) + pcb_arc_destroy(PCB_CURRLAYER(PCB), arc); + } + PCB_END_LOOP; + + g_hash_table_unref(lines); + g_hash_table_unref(arcs); + + pcb_undo_inc_serial(); + RND_ACT_IRES(0); + return 0; +} + +/*****************************************************************************/ +/* */ +/* Actions */ +/* */ +/*****************************************************************************/ + +rnd_action_t puller_action_list[] = { + {"Puller", pcb_act_Puller, pcb_acth_Puller, pcb_acts_Puller}, + {"GlobalPuller", pcb_act_GlobalPuller, pcb_acth_GlobalPuller, pcb_acts_GlobalPuller} +}; + +static const char *puller_cookie = "puller plugin"; + +int pplg_check_ver_puller(int ver_needed) { return 0; } + +void pplg_uninit_puller(void) +{ + rnd_remove_actions_by_cookie(puller_cookie); +} + +int pplg_init_puller(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(puller_action_list, puller_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/puller/puller.pup =================================================================== --- tags/2.3.0/src_plugins/puller/puller.pup (nonexistent) +++ tags/2.3.0/src_plugins/puller/puller.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short puller +$long Pull traces to minimize their length. +$state works +$package extra +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/query/Makefile =================================================================== --- tags/2.3.0/src_plugins/query/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/query/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_query + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/query/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/query/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/query/Plug.tmpasm (revision 33253) @@ -0,0 +1,23 @@ +put /local/pcb/mod {query} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/query/query.o + $(PLUGDIR)/query/query_access.o + $(PLUGDIR)/query/query_act.o + $(PLUGDIR)/query/query_exec.o + $(PLUGDIR)/query/query_l.o + $(PLUGDIR)/query/query_y.o + $(PLUGDIR)/query/fnc.o + $(PLUGDIR)/query/net_int.o + $(PLUGDIR)/query/net_len.o + $(PLUGDIR)/query/fields_sphash.o + $(PLUGDIR)/query/dlg_search.o +@] +put /local/pcb/mod/YACC {$(PLUGDIR)/query/query_y} +put /local/pcb/mod/LEX {$(PLUGDIR)/query/query_l} +put /local/pcb/mod/SPHASH {$(PLUGDIR)/query/fields.sphash} + +switch /local/pcb/query/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/query/dlg_search.c =================================================================== --- tags/2.3.0/src_plugins/query/dlg_search.c (nonexistent) +++ tags/2.3.0/src_plugins/query/dlg_search.c (revision 33253) @@ -0,0 +1,585 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include +#include +#include +#include +#include +#include +#include "query.h" +#include "board.h" + +#define MAX_ROW 8 +#define MAX_COL 4 + +static const char *search_acts[] = { "select", "unselect", "view", NULL }; + +#define NEW_EXPR_LAB "" + +/* for debugging: */ +/*#define NEW_EXPR_LAB rnd_strdup_printf("%d:%d", row, col)*/ + +#include "dlg_search_tab.h" + +typedef struct { + int valid; + const expr_wizard_t *expr; + const char *op; + char *right; +} search_expr_t; + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int wexpr_str, wwizard, wact; + int wrowbox[MAX_ROW]; + int wexpr[MAX_ROW][MAX_COL]; /* expression framed box */ + int wexpr_lab[MAX_ROW][MAX_COL]; /* the label within the expression box */ + int wexpr_del[MAX_ROW][MAX_COL], wexpr_edit[MAX_ROW][MAX_COL]; /* expression buttons */ + int wor[MAX_ROW][MAX_COL]; /* before the current col */ + int wand[MAX_ROW]; /* before the current row */ + int wnew_or[MAX_ROW], wnew_and; + int visible[MAX_ROW][MAX_COL]; + search_expr_t expr[MAX_ROW][MAX_COL]; +} search_ctx_t; + +#define WIZ(ctx) (ctx->dlg[ctx->wwizard].val.lng) + +#include "dlg_search_edit.c" + +static void free_expr(search_expr_t *e) +{ + free(e->right); + memset(e, 0, sizeof(search_expr_t)); +} + +static void search_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + int r, c; + search_ctx_t *ctx = caller_data; + for(r = 0; r < MAX_ROW; r++) + for(c = 0; c < MAX_COL; c++) + free_expr(&ctx->expr[r][c]); + free(ctx); +} + +static void hspacer(search_ctx_t *ctx) +{ + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); +} + +static void vspacer(search_ctx_t *ctx) +{ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); +} + +static void update_vis(search_ctx_t *ctx) +{ + int c, r, wen; + + wen = WIZ(ctx); + + for(r = 0; r < MAX_ROW; r++) { + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wrowbox[r],!ctx->visible[r][0]); + for(c = 0; c < MAX_COL; c++) { + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wexpr[r][c], !ctx->visible[r][c]); + if (c > 0) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wor[r][c], !((ctx->visible[r][c-1] && ctx->visible[r][c]))); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_del[r][c], wen); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_edit[r][c], wen); + } + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wnew_or[r], !ctx->visible[r][0]); + if (r > 0) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wand[r], !((ctx->visible[r-1][0] && ctx->visible[r][0]))); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wnew_or[r], wen); + } + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wnew_and, wen); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_str, !wen); +} + +/* look up row and col for a widget attr in a [row][col] widget idx array; returns 0 on success */ +static int rc_lookup(search_ctx_t *ctx, int w[MAX_ROW][MAX_COL], rnd_hid_attribute_t *attr, int *row, int *col) +{ + int r, c, idx = attr - ctx->dlg; + for(r = 0; r < MAX_ROW; r++) { + for(c = 0; c < MAX_COL; c++) { + if (w[r][c] == idx) { + *row = r; + *col = c; + return 0; + } + } + } + return -1; +} + +/* look up row for a widget attr in a [row] widget idx array; returns 0 on success */ +static int r_lookup(search_ctx_t *ctx, int w[MAX_ROW], rnd_hid_attribute_t *attr, int *row) +{ + int r, idx = attr - ctx->dlg; + for(r = 0; r < MAX_ROW; r++) { + if (w[r] == idx) { + *row = r; + return 0; + } + } + return -1; +} + +static void append_expr(gds_t *dst, search_expr_t *e, int sepchar) +{ + gds_append_str(dst, e->expr->left_var); + gds_append(dst, sepchar); + gds_append_str(dst, e->op); + gds_append(dst, sepchar); + gds_append_str(dst, e->right); +} + +static void redraw_expr(search_ctx_t *ctx, int row, int col) +{ + rnd_hid_attr_val_t hv; + gds_t buf; + search_expr_t *e = &(ctx->expr[row][col]); + + if (e->valid) { + gds_init(&buf); + append_expr(&buf, e, '\n'); + hv.str = buf.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_lab[row][col], &hv); + gds_uninit(&buf); + } + else { + hv.str = NEW_EXPR_LAB; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_lab[row][col], &hv); + } +} + +static void search_recompile(search_ctx_t *ctx) +{ + rnd_hid_attr_val_t hv; + gds_t buf; + int row, col; + + gds_init(&buf); + for(row = 0; row < MAX_ROW; row++) { + if (!ctx->visible[row][0] || !ctx->expr[row][0].valid) + continue; + if (row > 0) + gds_append_str(&buf, " && "); + gds_append(&buf, '('); + for(col = 0; col < MAX_COL; col++) { + if (!ctx->visible[row][col] || !ctx->expr[row][col].valid) + continue; + if (col > 0) + gds_append_str(&buf, " || "); + gds_append(&buf, '('); + append_expr(&buf, &(ctx->expr[row][col]), ' '); + gds_append(&buf, ')'); + } + gds_append(&buf, ')'); + } + hv.str = buf.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_str, &hv); + gds_uninit(&buf); +} + +static const char *qop_text[] = {"==", "!=", ">=", "<=", ">", "<", "~"}; +static const pcb_qry_nodetype_t qop[] = {PCBQ_OP_EQ, PCBQ_OP_NEQ, PCBQ_OP_GTEQ, PCBQ_OP_LTEQ, PCBQ_OP_GT, PCBQ_OP_LT, PCBQ_OP_MATCH}; + +static int search_decompile_op(gds_t *dst, pcb_qry_node_t *nd, rnd_bool want_coord) +{ + int res; + + switch(nd->type) { + case PCBQ_FIELD_OF: + for(nd = nd->data.children, res = 0; nd != NULL; nd = nd->next) + res |= search_decompile_op(dst, nd, want_coord); + return res; + case PCBQ_FIELD: + gds_append(dst, '.'); + gds_append_str(dst, nd->data.str); + return 0; + case PCBQ_VAR: + gds_append(dst, '@'); + return 0; + case PCBQ_DATA_COORD: + rnd_append_printf(dst, "%m+%$mS", rnd_conf.editor.grid_unit->allow, nd->data.crd); + return 0; + case PCBQ_DATA_DOUBLE: + if (want_coord) + rnd_append_printf(dst, "%m+%$mS", rnd_conf.editor.grid_unit->allow, (rnd_coord_t)nd->data.dbl); + else + rnd_append_printf(dst, "%f", nd->data.dbl); + return 0; + case PCBQ_DATA_STRING: + case PCBQ_DATA_REGEX: + case PCBQ_DATA_CONST: + gds_append_str(dst, nd->data.str); + return 0; + default: + break; + } + return -1; +} + +static int search_decompile_(search_ctx_t *ctx, pcb_qry_node_t *nd, int dry, int row, int col) +{ + int n, res; + const char *qopt = NULL, *right; + gds_t e; + const expr_wizard_t *w; + + + if (nd->type == PCBQ_EXPR_PROG) + return search_decompile_(ctx, nd->data.children, dry, row, col); + + if (nd->type == PCBQ_ITER_CTX) + return search_decompile_(ctx, nd->next, dry, row, col); + + if (nd->type == PCBQ_OP_AND) { + if ((nd->parent == NULL) || ((nd->parent->type != PCBQ_OP_AND) && (nd->parent->type != PCBQ_EXPR_PROG))) /* first level of ops must be AND */ + return -1; + if (search_decompile_(ctx, nd->data.children, dry, row, col) != 0) + return -1; + return search_decompile_(ctx, nd->data.children->next, dry, row+1, col); + } + + if (nd->type == PCBQ_OP_OR) { + if ((nd->parent == NULL) || ((nd->parent->type != PCBQ_OP_AND) && (nd->parent->type != PCBQ_OP_OR))) /* second level of ops must be OR */ + return -1; + if (search_decompile_(ctx, nd->data.children, dry, row, col) != 0) + return -1; + return search_decompile_(ctx, nd->data.children->next, dry, row, col+1); + } + + /* plain op */ + for(n = 0; n < sizeof(qop) / sizeof(qop[0]); n++) { + if (qop[n] == nd->type) { + qopt = qop_text[n]; + break; + } + } + + if (qopt == NULL) + return -1; /* unknown binary op */ + + gds_init(&e); + + res = search_decompile_op(&e, nd->data.children, 0); + + /* look up the left side to know how to fill in the expr editor dialog */ + for(w = expr_tab; w->left_desc != NULL; w++) + if ((w->left_var != NULL) && (strcmp(w->left_var, e.array) == 0)) + break; + if (w->left_desc == NULL) + w = NULL; + + gds_append(&e, '\n'); + gds_append_str(&e, qopt); + gds_append(&e, '\n'); + right = e.array + e.used; + res |= search_decompile_op(&e, nd->data.children->next, (w->rtype == RIGHT_COORD)); + + if (res == 0) { + rnd_hid_attr_val_t hv; + + if (w != NULL) { + ctx->expr[row][col].expr = w; + ctx->expr[row][col].op = qopt; + ctx->expr[row][col].right = rnd_strdup(right); + ctx->expr[row][col].valid = 1; + + hv.str = e.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_lab[row][col], &hv); + ctx->visible[row][col] = 1; + } + else + res = -1; + } + + gds_uninit(&e); + + return res; +} + +static void search_decompile(search_ctx_t *ctx) +{ + const char *script = ctx->dlg[ctx->wexpr_str].val.str; + pcb_qry_node_t *root; + int row, col; + + if (script == NULL) return; + while(isspace(*script)) script++; + if (*script == '\0') return; + + root = pcb_query_compile(script); + if (root == NULL) { + rnd_message(RND_MSG_ERROR, "Syntax error compiling the script\nThe GUI will not be filled in by the script\n"); + return; + } + + if (search_decompile_(ctx, root, 1, 0, 0) != 0) { + rnd_message(RND_MSG_ERROR, "The script is too complex for the GUI\nThe GUI will not be filled in by the script\n"); + return; + } + + for(row = 0; row < MAX_ROW; row++) { + for(col = 0; col < MAX_COL; col++) { + ctx->visible[row][col] = 0; + ctx->expr[row][col].valid = 0; + } + } + + search_decompile_(ctx, root, 0, 0, 0); + update_vis(ctx); +} + +static void search_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row, col; + + if (rc_lookup(ctx, ctx->wexpr_del, attr, &row, &col) != 0) + return; + + free_expr(&(ctx->expr[row][col])); + for(;col < MAX_COL-1; col++) { + if (!ctx->visible[row][col+1]) { + ctx->visible[row][col] = 0; + memset(&ctx->expr[row][col], 0, sizeof(search_expr_t)); + break; + } + ctx->expr[row][col] = ctx->expr[row][col+1]; + redraw_expr(ctx, row, col); + } + update_vis(ctx); + search_recompile(ctx); +} + +static void search_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row, col; + search_expr_t *e; + + if (rc_lookup(ctx, ctx->wexpr_edit, attr, &row, &col) != 0) + return; + + e = &(ctx->expr[row][col]); + if (srchedit_window(e) == 0) { + redraw_expr(ctx, row, col); + search_recompile(ctx); + } +} + +static void search_enable_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + if (WIZ(ctx)) { + search_decompile(ctx); /* fills in the GUI from the expression, if possible */ + search_recompile(ctx); /* overwrite the edit box just in case the user had something custom in it */ + } + + update_vis(ctx); +} + +static void search_append_col_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row, col; + + if (r_lookup(ctx, ctx->wnew_or, attr, &row) != 0) + return; + + for(col = 0; col < MAX_COL; col++) { + if (!ctx->visible[row][col]) { + ctx->visible[row][col] = 1; + redraw_expr(ctx, row, col); + update_vis(ctx); + search_recompile(ctx); + return; + } + } + rnd_message(RND_MSG_ERROR, "Too many expressions in the row, can not add more\n"); +} + +static void search_append_row_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row; + + for(row = 0; row < MAX_ROW; row++) { + if (!ctx->visible[row][0]) { + ctx->visible[row][0] = 1; + redraw_expr(ctx, row, 0); + update_vis(ctx); + search_recompile(ctx); + return; + } + } + rnd_message(RND_MSG_ERROR, "Too many expression rows, can not add more\n"); +} + +static void search_apply_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + if (ctx->dlg[ctx->wexpr_str].val.str != NULL) + rnd_actionva(&PCB->hidlib, "query", search_acts[ctx->dlg[ctx->wact].val.lng], ctx->dlg[ctx->wexpr_str].val.str, NULL); +} + + +static const char *icon_del[] = { +"5 5 2 1", +" c None", +"+ c #FF0000", +"+ +", +" + + ", +" + ", +" + + ", +"+ +", +}; + +static const char *icon_edit[] = { +"5 5 2 1", +" c None", +"+ c #000000", +"++++ ", +"+ ", +"+++ ", +"+ ", +"++++ ", +}; + +static void search_window_create(void) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + search_ctx_t *ctx = calloc(sizeof(search_ctx_t), 1); + int row, col; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, "Query expression:"); + RND_DAD_STRING(ctx->dlg); + RND_DAD_WIDTH_CHR(ctx->dlg, 64); + ctx->wexpr_str = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Action on the results:"); + RND_DAD_ENUM(ctx->dlg, search_acts); + ctx->wact = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Enable the wizard:"); + RND_DAD_BOOL(ctx->dlg); + ctx->wwizard = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_DEFAULT_NUM(ctx->dlg, 1); + RND_DAD_CHANGE_CB(ctx->dlg, search_enable_cb); + RND_DAD_END(ctx->dlg); + for(row = 0; row < MAX_ROW; row++) { + if (row > 0) { + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wand[row] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_HIDE); + RND_DAD_LABEL(ctx->dlg, "AND"); + RND_DAD_END(ctx->dlg); + } + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, /*RND_HATF_EXPFILL | */RND_HATF_HIDE); + ctx->wrowbox[row] = RND_DAD_CURRENT(ctx->dlg); + for(col = 0; col < MAX_COL; col++) { + ctx->visible[row][col] = 0; + if (col > 0) { + RND_DAD_LABEL(ctx->dlg, " OR "); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wor[row][col] = RND_DAD_CURRENT(ctx->dlg); + } + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_TIGHT | RND_HATF_HIDE); + ctx->wexpr[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, NEW_EXPR_LAB); + ctx->wexpr_lab[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_TIGHT); + RND_DAD_PICBUTTON(ctx->dlg, icon_del); + RND_DAD_HELP(ctx->dlg, "Remove expression"); + ctx->wexpr_del[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_del_cb); + RND_DAD_PICBUTTON(ctx->dlg, icon_edit); + RND_DAD_HELP(ctx->dlg, "Edit expression"); + ctx->wexpr_edit[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_edit_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + } + hspacer(ctx); + RND_DAD_BUTTON(ctx->dlg, "append OR"); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wnew_or[row] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_append_col_cb); + RND_DAD_END(ctx->dlg); + } + vspacer(ctx); + RND_DAD_BUTTON(ctx->dlg, "append AND"); + ctx->wnew_and = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_append_row_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Apply"); + RND_DAD_CHANGE_CB(ctx->dlg, search_apply_cb); + RND_DAD_HELP(ctx->dlg, "Execute the search expression\nusing the selected action"); + hspacer(ctx); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 350); + RND_DAD_NEW("search", ctx->dlg, "pcb-rnd search", ctx, rnd_false, search_close_cb); + + ctx->visible[0][0] = 1; + update_vis(ctx); + search_recompile(ctx); +} + + +const char pcb_acts_SearchDialog[] = "SearchDialog()\n"; +const char pcb_acth_SearchDialog[] = "Open the log dialog."; +fgw_error_t pcb_act_SearchDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + search_window_create(); + RND_ACT_IRES(0); + return 0; +} + + Index: tags/2.3.0/src_plugins/query/dlg_search.h =================================================================== --- tags/2.3.0/src_plugins/query/dlg_search.h (nonexistent) +++ tags/2.3.0/src_plugins/query/dlg_search.h (revision 33253) @@ -0,0 +1,4 @@ +extern const char pcb_acts_SearchDialog[]; +extern const char pcb_acth_SearchDialog[]; +fgw_error_t pcb_act_SearchDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + Index: tags/2.3.0/src_plugins/query/dlg_search_edit.c =================================================================== --- tags/2.3.0/src_plugins/query/dlg_search_edit.c (nonexistent) +++ tags/2.3.0/src_plugins/query/dlg_search_edit.c (revision 33253) @@ -0,0 +1,371 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + search_expr_t se; + int wleft, wop, wright[RIGHT_max]; + const expr_wizard_op_t *last_op; + right_type last_rtype; +} srchedit_ctx_t; + +static srchedit_ctx_t srchedit_ctx; + +/* Set the right side of the expression from the non-enum value of an widget attr */ +static void set_right(srchedit_ctx_t *ctx, rnd_hid_attribute_t *attr) +{ + free(ctx->se.right); + ctx->se.right = NULL; + + switch(ctx->se.expr->rtype) { + case RIGHT_STR: + ctx->se.right = rnd_strdup_printf("\"%s\"", attr->val.str); + break; + case RIGHT_INT: + ctx->se.right = rnd_strdup_printf("%d", attr->val.lng); + break; + case RIGHT_DOUBLE: + ctx->se.right = rnd_strdup_printf("%f", attr->val.dbl); + break; + case RIGHT_COORD: + ctx->se.right = rnd_strdup_printf("%$mm", attr->val.crd); + break; + case RIGHT_CONST: + case RIGHT_max: + break; + } +} + +static void srch_expr_set_ops(srchedit_ctx_t *ctx, const expr_wizard_op_t *op, int click) +{ + rnd_hid_tree_t *tree; + rnd_hid_attribute_t *attr; + rnd_hid_row_t *r, *cur = NULL; + char *cell[2], *cursor_path = NULL; + const char **o; + + if (op == ctx->last_op) + return; + + attr = &ctx->dlg[ctx->wop]; + tree = attr->wdata; + + /* remember cursor */ + if (click) { + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + } + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + cell[1] = NULL; + for(o = op->ops; *o != NULL; o++) { + cell[0] = rnd_strdup_printf(*o); + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data = (void *)(*o); /* will be casted back to const char * only */ + if ((!click) && (ctx->se.op == *o)) + cur = r; + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wop, &hv); + free(cursor_path); + } + if (cur != NULL) + rnd_dad_tree_jumpto(attr, cur); + ctx->last_op = op; +} + +static void srch_expr_fill_in_right_const(srchedit_ctx_t *ctx, const search_expr_t *s) +{ + rnd_hid_tree_t *tree; + rnd_hid_attribute_t *attr; + char *cell[2]; + const char **o; + + attr = &ctx->dlg[ctx->wright[RIGHT_CONST]]; + tree = attr->wdata; + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + cell[1] = NULL; + for(o = s->expr->right_const->ops; *o != NULL; o++) { + cell[0] = rnd_strdup_printf(*o); + rnd_dad_tree_append(attr, NULL, cell); + } + + /* set cursor to last known value */ + if ((s != NULL) && (s->right != NULL)) { + rnd_hid_attr_val_t hv; + hv.str = s->right; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[RIGHT_CONST], &hv); + } +} + +static void srch_expr_fill_in_right(srchedit_ctx_t *ctx, const search_expr_t *s) +{ + int n, empty = 0; + rnd_hid_attr_val_t hv; + + /* don't recalc if the same type; except for const, because there the same type means different set of values for each expr */ + if ((s->expr->rtype == ctx->last_rtype) && (s->expr->rtype != RIGHT_CONST)) + return; + + for(n = 0; n < RIGHT_max; n++) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[n], 1); + + hv.str = ctx->se.right; + if (hv.str == NULL) { + hv.str = ""; + empty = 1; + } + + switch(s->expr->rtype) { + case RIGHT_STR: + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + break; + case RIGHT_INT: + hv.lng = strtol(hv.str, NULL, 10); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + if (empty) + set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); + break; + case RIGHT_DOUBLE: + hv.dbl = strtod(hv.str, NULL); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + if (empty) + set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); + break; + case RIGHT_COORD: + hv.crd = rnd_get_value_ex(hv.str, NULL, NULL, NULL, "mm", NULL); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + if (empty) + set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); + break; + case RIGHT_CONST: srch_expr_fill_in_right_const(ctx, s); break; + case RIGHT_max: break; + } + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], 0); + ctx->last_rtype = s->expr->rtype; +} + +static void srch_expr_left_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + srchedit_ctx_t *ctx = tree->user_ctx; + const expr_wizard_t *e; + + if (row == NULL) + return; + + e = row->user_data; + if (e->left_var == NULL) /* category */ + return; + + ctx->se.expr = e; + srch_expr_set_ops(ctx, e->op, 1); + srch_expr_fill_in_right(ctx, &ctx->se); +} + +static void srch_expr_op_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + srchedit_ctx_t *ctx = tree->user_ctx; + + if (row != NULL) + ctx->se.op = row->user_data; + else + ctx->se.op = NULL; +} + +/* the table on the left is static, needs to be filled in only once; + returns 1 if filled in op and right, else 0 */ +static int fill_in_left(srchedit_ctx_t *ctx) +{ + const expr_wizard_t *t; + rnd_hid_attribute_t *attr; + rnd_hid_row_t *r, *parent = NULL, *cur = NULL; + char *cell[2]; + + attr = &ctx->dlg[ctx->wleft]; + + cell[1] = NULL; + for(t = expr_tab; t->left_desc != NULL; t++) { + if (t->left_var == NULL) + parent = NULL; + cell[0] = rnd_strdup(t->left_desc); + if (parent != NULL) + r = rnd_dad_tree_append_under(attr, parent, cell); + else + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data = (void *)t; + if (t->left_var == NULL) + parent = r; + if (t == ctx->se.expr) + cur = r; + } + + if (cur != NULL) { + rnd_dad_tree_jumpto(attr, cur); + + /* clear all cache fields so a second window open won't inhibit refreshes */ + ctx->last_op = NULL; + ctx->last_rtype = RIGHT_max; + + srch_expr_set_ops(ctx, ctx->se.expr->op, 0); + srch_expr_fill_in_right(ctx, &ctx->se); + return 1; + } + return 0; +} + +static void srchexpr_right_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + srchedit_ctx_t *ctx = caller_data; + + set_right(ctx, attr); +} + +static void srch_expr_right_table_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + srchedit_ctx_t *ctx = tree->user_ctx; + + free(ctx->se.right); + ctx->se.right = NULL; + if (row != NULL) + ctx->se.right = rnd_strdup(row->cell[0]); +} + +static int srchedit_window(search_expr_t *expr) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 1}, {"OK", 0}, {NULL, 0}}; + srchedit_ctx_t *ctx = &srchedit_ctx; + int res; + + ctx->se = *expr; + if (ctx->se.right != NULL) + ctx->se.right = rnd_strdup(ctx->se.right); + + /* clear all cache fields so a second window open won't inhibit refreshes */ + ctx->last_op = NULL; + ctx->last_rtype = RIGHT_max; + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 1, 1, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_SCROLL); + ctx->wleft = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_left_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_TREE(ctx->dlg, 1, 0, NULL); + ctx->wop = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_op_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_STRING(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_STR] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_INTEGER(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_INT] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -(1L<<30), (1L<<30)); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_REAL(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_DOUBLE] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -(1L<<30), (1L<<30)); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_COORD(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_COORD] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -RND_MAX_COORD, RND_MAX_COORD); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_TREE(ctx->dlg, 1, 0, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_CONST] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_right_table_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 450, 450); + RND_DAD_NEW("search_expr", ctx->dlg, "pcb-rnd search expression", ctx, rnd_true, NULL); + + if (fill_in_left(ctx) != 1) { + srch_expr_set_ops(ctx, op_tab, 1); /* just to get the initial tree widget width */ + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[RIGHT_CONST], 0); /* just to get something harmless display on the right side after open */ + } + + res = RND_DAD_RUN(ctx->dlg); + if (res == 0) { + free(expr->right); + *expr = ctx->se; + if (ctx->se.op != NULL) + expr->valid = 1; + } + else + free(ctx->se.right); + + RND_DAD_FREE(ctx->dlg); + return res; +} + + Index: tags/2.3.0/src_plugins/query/dlg_search_tab.h =================================================================== --- tags/2.3.0/src_plugins/query/dlg_search_tab.h (nonexistent) +++ tags/2.3.0/src_plugins/query/dlg_search_tab.h (revision 33253) @@ -0,0 +1,203 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* advanced search dialog - expressioin wizard tables; intended to be + included from the search dialog only */ + +typedef enum { + RIGHT_STR, + RIGHT_INT, + RIGHT_DOUBLE, + RIGHT_COORD, + RIGHT_CONST, + RIGHT_max +} right_type; + +typedef enum { + OPS_ANY, + OPS_EQ, + OPS_STR +} op_type_t; + +static const char *ops_any[] = {"==", "!=", ">=", "<=", ">", "<", NULL}; +static const char *ops_eq[] = {"==", "!=", NULL}; +static const char *ops_str[] = {"==", "!=", "~", NULL}; + +typedef struct expr_wizard_op_s expr_wizard_op_t; +struct expr_wizard_op_s { + const char **ops; +}; + +static expr_wizard_op_t op_tab[] = { + {ops_any}, + {ops_eq}, + {ops_str}, + {NULL} +}; + +typedef struct expr_wizard_s expr_wizard_t; +struct expr_wizard_s { + const char *left_var; + const char *left_desc; + const expr_wizard_op_t *op; + right_type rtype; + const expr_wizard_op_t *right_const; +}; + +static const char *right_const_objtype[] = { "POINT", "LINE", "TEXT", "POLYGON", "ARC", "PADSTACK", "GFX", "SUBC", "RAT", "NET", "LAYER", NULL }; +static const char *right_const_yesno[] = {"YES", "NO", NULL}; +static const char *right_const_10[] = {"1", "0", NULL}; +static const char *right_const_layerpos[] = {"TOP", "BOTTOM", "INTERNAL", NULL}; +static const char *right_const_layertype[] = {"COPPER", "SILK", "MASK", "PASTE", "BOUNDARY", "MECH", "DOC" , NULL}; +static const char *right_const_side[] = {"TOP", "BOTTOM", NULL}; + +enum { + RC_OBJTYPE, + RC_YESNO, + RC_10, + RC_LAYERPOS, + RC_LAYERTYPE, + RC_SIDE +}; + +static expr_wizard_op_t right_const_tab[] = { + {right_const_objtype}, + {right_const_yesno}, + {right_const_10}, + {right_const_layerpos}, + {right_const_layertype}, + {right_const_side}, + {NULL} +}; + +static const expr_wizard_t expr_tab[] = { + {"@.ID", "object ID", &op_tab[OPS_ANY], RIGHT_INT, NULL}, + {"@.type", "object type", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_OBJTYPE]}, + + {NULL, "bounding box", NULL, 0, NULL}, + {"@.bbox.x1", "X1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.y1", "Y1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.x2", "X2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.y2", "Y2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.w", "width", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.h", "height", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + + + {NULL, "trace object's", NULL, 0, NULL}, + {"@.thickness", "thickness", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.clearance", "clearance", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.length", "length", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + + {NULL, "line", NULL, 0, NULL}, + {"@.x1", "X1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y1", "Y1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.x2", "X2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y2", "Y2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + + {NULL, "arc", NULL, 0, NULL}, + {"@.x", "center X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y", "center Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.angle.start", "start angle", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.angle.delta", "delta angle", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + + {NULL, "text", NULL, 0, NULL}, + {"@.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.scale", "scale", &op_tab[OPS_ANY], RIGHT_INT, NULL}, + {"@.scale_x", "scale_x", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.scale_y", "scale_y", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.string", "string", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.thickness", "thickness", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + + {NULL, "polygon", NULL, 0, NULL}, + {"@.points", "points", &op_tab[OPS_ANY], RIGHT_INT, NULL}, + + {NULL, "padstack", NULL, 0, NULL}, + {"@.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.clearance", "global clearance", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.xmirror", "x coords mirrored",&op_tab[OPS_ANY], RIGHT_INT, NULL}, + {"@.smirror", "stackup mirrored", &op_tab[OPS_ANY], RIGHT_INT, NULL}, + {"@.name", "name", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.number", "number", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.hole", "proto: hole dia", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.plated", "proto: is plated?",&op_tab[OPS_ANY], RIGHT_INT, NULL}, + + {NULL, "subcircuit", NULL, 0, NULL}, + {"@.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.side", "side", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_SIDE]}, + {"@.a.refdes", "refdes", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.a.footprint", "footprint", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.a.value", "value", &op_tab[OPS_STR], RIGHT_STR, NULL}, + + {NULL, "gfx", NULL, 0, NULL}, + {"@.cx", "center X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.cy", "center Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.sx", "size X (width)", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.sy", "size Y (height)", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.rot", "rotation angle", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + + {NULL, "host layer's", NULL, 0, NULL}, + {"@.layer.name", "name", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.layer.visible", "visible", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_YESNO]}, + {"@.layer.position", "stack position", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_LAYERPOS]}, + {"@.layer.type", "type", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_LAYERTYPE]}, + {"@.layer.purpose", "purpose", &op_tab[OPS_STR], RIGHT_STR, NULL}, + + {NULL, "host subcircuit's",NULL, 0, NULL}, + {"@.subc.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.subc.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.subc.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.subc.side", "side", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_SIDE]}, + {"@.subc.refdes", "refdes", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.subc.footprint", "a.footprint", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.subc.value", "a.value", &op_tab[OPS_STR], RIGHT_STR, NULL}, + + {NULL, "flag", NULL, 0, NULL}, + {"@.p.flag.found", "found", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.hole", "hole", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.clearpoly","clearpoly", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.clearline","clearline", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.selected", "selected", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.onsolder", "onsolder", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.auto", "auto", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.warn", "warn", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.drc", "drc", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.lock", "lock", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.fullpoly", "fullpoly", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.nonetlist","nonetlist", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.termname", "termname", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.clearpolypoly","clearpolypoly",&op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.p.dyntext","dyntext", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.p.floater","floater", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + + {NULL, NULL, NULL, 0, NULL} +}; + Index: tags/2.3.0/src_plugins/query/fields.sphash =================================================================== --- tags/2.3.0/src_plugins/query/fields.sphash (nonexistent) +++ tags/2.3.0/src_plugins/query/fields.sphash (revision 33253) @@ -0,0 +1,58 @@ +a +p +x +y +cx +cy +sx +sy +x1 +y1 +x2 +y2 +thickness +clearance +layer +layergroup +width +height +name +visible +position +purpose +type +angle +start +delta +scale +scale_x +scale_y +rotation +rot +direction +string +points +hole +mask +number +description +value +ID +IID +bbox +bbox_naked +type +area +refdes +length +length2 +xmirror +smirror +plated +shape +subc +side +proto +netname +netseg +net Index: tags/2.3.0/src_plugins/query/fnc.c =================================================================== --- tags/2.3.0/src_plugins/query/fnc.c (nonexistent) +++ tags/2.3.0/src_plugins/query/fnc.c (revision 33253) @@ -0,0 +1,177 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - basic functions */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "find.h" +#include "obj_term.h" +#include "netlist.h" +#include "net_int.h" +#include "net_len.h" + +#include "query_access.h" +#include "query_exec.h" + +#define PCB dontuse + +static int fnc_llen(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if (argc != 1) + return -1; + if (argv[0].type != PCBQ_VT_LST) + PCB_QRY_RET_INV(res); + PCB_QRY_RET_INT(res, vtp0_len(&argv[0].data.lst)); +} + +static int fnc_isvoid(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if (argc != 1) + return -1; + PCB_QRY_RET_INT(res, argv[0].type == PCBQ_VT_VOID); +} + +static int fnc_distance(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if ((argc == 4) && (argv[0].type == PCBQ_VT_COORD) && (argv[1].type == PCBQ_VT_COORD) && (argv[2].type == PCBQ_VT_COORD) && (argv[3].type == PCBQ_VT_COORD)) + PCB_QRY_RET_DBL(res, rnd_distance(argv[0].data.crd, argv[1].data.crd, argv[2].data.crd, argv[3].data.crd)); + PCB_QRY_RET_INV(res); +} + +static int fnc_abs(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if (argc == 1) { + switch(argv[0].type) { + case PCBQ_VT_COORD: PCB_QRY_RET_COORD(res, RND_ABS(argv[0].data.crd)); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, RND_ABS(argv[0].data.lng)); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, RND_ABS(argv[0].data.dbl)); + default: break; + } + } + PCB_QRY_RET_INV(res); +} + +static int fnc_double(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + char *end; + double d; + if (argc == 1) { + switch(argv[0].type) { + case PCBQ_VT_COORD: PCB_QRY_RET_DBL(res, argv[0].data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_DBL(res, argv[0].data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, argv[0].data.dbl); + case PCBQ_VT_STRING: + d = strtod(argv[0].data.str, &end); + if (*end == '\0') + PCB_QRY_RET_DBL(res, d); + default: break; + } + } + PCB_QRY_RET_INV(res); +} + +static int fnc_int(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + char *end; + long d; + if (argc == 1) { + switch(argv[0].type) { + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, argv[0].data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, argv[0].data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, argv[0].data.dbl); + case PCBQ_VT_STRING: + d = strtol(argv[0].data.str, &end, 10); + if (*end == '\0') + PCB_QRY_RET_INT(res, d); + default: break; + } + } + PCB_QRY_RET_INV(res); +} + +static int fnc_coord(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if (argc == 1) { + switch(argv[0].type) { + case PCBQ_VT_COORD: PCB_QRY_RET_COORD(res, argv[0].data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_COORD(res, argv[0].data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_COORD(res, argv[0].data.dbl); + case PCBQ_VT_STRING: PCB_QRY_RET_COORD(res, (rnd_coord_t)rnd_get_value(argv[0].data.str, NULL, NULL, NULL)); + default: break; + } + } + PCB_QRY_RET_INV(res); +} + +#include "fnc_glue.c" +#include "fnc_list.c" +#include "fnc_geo.c" +#include "fnc_obj.c" +#include "fnc_layer_setup.c" + +void pcb_qry_basic_fnc_init(void) +{ + pcb_qry_fnc_reg("llen", fnc_llen); + pcb_qry_fnc_reg("abs", fnc_abs); + pcb_qry_fnc_reg("double", fnc_double); + pcb_qry_fnc_reg("int", fnc_int); + pcb_qry_fnc_reg("isvoid", fnc_isvoid); + pcb_qry_fnc_reg("coord", fnc_coord); + pcb_qry_fnc_reg("distance", fnc_distance); + pcb_qry_fnc_reg("mklist", fnc_mklist); + pcb_qry_fnc_reg("violation", fnc_violation); + pcb_qry_fnc_reg("layerlist", fnc_layerlist); + pcb_qry_fnc_reg("netlist", fnc_netlist); + pcb_qry_fnc_reg("netterms", fnc_netterms); + pcb_qry_fnc_reg("netobjs", fnc_netobjs); + pcb_qry_fnc_reg("netsegs", fnc_netsegs); + pcb_qry_fnc_reg("netbreak", fnc_netbreak); + pcb_qry_fnc_reg("netshort", fnc_netshort); + pcb_qry_fnc_reg("subcobjs", fnc_subcobjs); + pcb_qry_fnc_reg("action", fnc_action); + pcb_qry_fnc_reg("getconf", pcb_qry_fnc_getconf); + pcb_qry_fnc_reg("pstkring", fnc_pstkring); + pcb_qry_fnc_reg("netlen", fnc_netlen); + + pcb_qry_fnc_reg("thermal_on", fnc_thermal_on); + + pcb_qry_fnc_reg("poly_num_islands", fnc_poly_num_islands); + pcb_qry_fnc_reg("overlap", fnc_overlap); + pcb_qry_fnc_reg("intersect", fnc_intersect); + + pcb_qry_fnc_reg("layer_setup", fnc_layer_setup); +} Index: tags/2.3.0/src_plugins/query/fnc_geo.c =================================================================== --- tags/2.3.0/src_plugins/query/fnc_geo.c (nonexistent) +++ tags/2.3.0/src_plugins/query/fnc_geo.c (revision 33253) @@ -0,0 +1,141 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - geometry functions */ + +#include "obj_poly.h" +#include "data_it.h" + +#define PCB dontuse + +static int fnc_poly_num_islands(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + pcb_poly_t *poly; + long cnt = 0; + pcb_poly_it_t it; + rnd_polyarea_t *pa; + + if ((argc != 1) || (argv[0].type != PCBQ_VT_OBJ)) + return -1; + + poly = (pcb_poly_t *)argv[0].data.obj; + if (poly->type != PCB_OBJ_POLY) + PCB_QRY_RET_INV(res); + + if (poly->Clipped != NULL) { + if (PCB_FLAG_TEST(PCB_FLAG_FULLPOLY, poly)) + for(pa = pcb_poly_island_first(poly, &it); pa != NULL; pa = pcb_poly_island_next(&it)) + cnt++; + else + cnt = 1; + } + + PCB_QRY_RET_INT(res, cnt); +} + +/* pcb_intersect_obj_obj() wrapper that fails for layerobj-layerobj + check if they are in different groups */ +RND_INLINE int isc_obj_obj(pcb_find_t *fctx, pcb_any_obj_t *o1, pcb_any_obj_t *o2) +{ + /* in case of anylayer just skip, they don't have to be on the same layer group; + else if any object is a padstack, the low level isc function will handle it */ + if (fctx->pstk_anylayer || (o1->type == PCB_OBJ_PSTK) || (o2->type == PCB_OBJ_PSTK)) + return pcb_intersect_obj_obj(fctx, o1, o2); + + /* one final fallback: non-layer-objects can't be compared on group level */ + if ((o1->parent_type != PCB_PARENT_LAYER) || (o2->parent_type != PCB_PARENT_LAYER)) + return pcb_intersect_obj_obj(fctx, o1, o2); + + /* we are not anylayer; if the two objects are not on the same layer group, + it is impossible for them to intersect */ + if ((o1->parent.layer != o2->parent.layer) && (pcb_layer_get_group_(o1->parent.layer) != pcb_layer_get_group_(o2->parent.layer))) + return rnd_false; + + + return pcb_intersect_obj_obj(fctx, o1, o2); +} + +static int isc_subc_obj(pcb_qry_exec_t *ectx, pcb_find_t *fctx, pcb_subc_t *subc, pcb_any_obj_t *obj) +{ + pcb_any_obj_t *so; + pcb_data_it_t it; + for(so = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); so != NULL; so = pcb_data_next(&it)) + if (isc_obj_obj(fctx, obj, so)) + return 1; + return 0; +} + +static int isc_subc_subc(pcb_qry_exec_t *ectx, pcb_find_t *fctx, pcb_subc_t *subc1, pcb_subc_t *subc2) +{ + pcb_any_obj_t *so; + pcb_data_it_t it; + for(so = pcb_data_first(&it, subc1->data, PCB_OBJ_CLASS_REAL); so != NULL; so = pcb_data_next(&it)) + if (isc_subc_obj(ectx, fctx, subc2, so)) + return 1; + return 0; +} + +static int overlap_(pcb_qry_exec_t *ectx, pcb_find_t *fctx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if ((argc < 2) || (argv[0].type != PCBQ_VT_OBJ) || (argv[1].type != PCBQ_VT_OBJ)) + return -1; + if (argc > 2) { + PCB_QRY_ARG_CONV_TO_COORD(fctx->bloat, &argv[2], return -1); + } + if (argc > 3) + return -1; + + if ((argv[0].data.obj->type == PCB_OBJ_SUBC) && (argv[1].data.obj->type == PCB_OBJ_SUBC)) + PCB_QRY_RET_INT(res, isc_subc_subc(ectx, fctx, (pcb_subc_t *)argv[0].data.obj, (pcb_subc_t *)argv[1].data.obj)); + if (argv[0].data.obj->type == PCB_OBJ_SUBC) + PCB_QRY_RET_INT(res, isc_subc_obj(ectx, fctx, (pcb_subc_t *)argv[0].data.obj, argv[1].data.obj)); + if (argv[1].data.obj->type == PCB_OBJ_SUBC) + PCB_QRY_RET_INT(res, isc_subc_obj(ectx, fctx, (pcb_subc_t *)argv[1].data.obj, argv[0].data.obj)); + + PCB_QRY_RET_INT(res, isc_obj_obj(fctx, argv[0].data.obj, argv[1].data.obj)); +} + +static int fnc_overlap(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + static pcb_find_t fctx = {0}; + + fctx.ignore_clearance = 1; + fctx.allow_noncopper_pstk = 1; + fctx.pstk_anylayer = 1; + + return overlap_(ectx, &fctx, argc, argv, res); +} + +static int fnc_intersect(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + static pcb_find_t fctx = {0}; + + fctx.ignore_clearance = 1; + fctx.allow_noncopper_pstk = 1; + + return overlap_(ectx, &fctx, argc, argv, res); +} + Index: tags/2.3.0/src_plugins/query/fnc_glue.c =================================================================== --- tags/2.3.0/src_plugins/query/fnc_glue.c (nonexistent) +++ tags/2.3.0/src_plugins/query/fnc_glue.c (revision 33253) @@ -0,0 +1,306 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - glue functions to other infra */ + +#define PCB dontuse + +static int fnc_action(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + int n, retv = 0; + fgw_arg_t tmp, resa, arga[PCB_QRY_MAX_FUNC_ARGS], *arg; + + if (argv[0].type != PCBQ_VT_STRING) { + rnd_message(RND_MSG_ERROR, "query: action() first argument must be a string\n"); + return -1; + } + + /* convert query arguments to action arguments */ + for(n = 1; n < argc; n++) { + switch(argv[n].type) { + case PCBQ_VT_VOID: + arga[n].type = FGW_PTR; + arga[n].val.ptr_void = 0; + break; + case PCBQ_VT_LST: + { + long i; + pcb_idpath_list_t *list = calloc(sizeof(pcb_idpath_list_t), 1); + for(i = 0; i < argv[n].data.lst.used; i++) { + fgw_ptr_reg(&rnd_fgw, &tmp, RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, pcb_obj2idpath(argv[n].data.lst.array[i])); + pcb_idpath_list_append(list, fgw_idpath(&tmp)); + } + fgw_ptr_reg(&rnd_fgw, &(arga[n]), RND_PTR_DOMAIN_IDPATH_LIST, FGW_PTR | FGW_STRUCT, list); + } + break; + case PCBQ_VT_OBJ: + fgw_ptr_reg(&rnd_fgw, &(arga[n]), RND_PTR_DOMAIN_IDPATH, FGW_PTR | FGW_STRUCT, pcb_obj2idpath(argv[n].data.obj)); + break; + case PCBQ_VT_COORD: + arga[n].type = FGW_COORD; + fgw_coord(&arga[n]) = argv[n].data.crd; + break; + case PCBQ_VT_LONG: + arga[n].type = FGW_LONG; + arga[n].val.nat_long = argv[n].data.lng; + break; + case PCBQ_VT_DOUBLE: + arga[n].type = FGW_DOUBLE; + arga[n].val.nat_double = argv[n].data.dbl; + break; + case PCBQ_VT_STRING: + arga[n].type = FGW_STR; + arga[n].val.cstr = argv[n].data.str; + break; + } + } + + if (rnd_actionv_bin(&ectx->pcb->hidlib, argv[0].data.str, &resa, argc, arga) != 0) { + retv = -1; + goto fin; + } + + /* convert action result to query result */ + +# define FGW_TO_QRY_NUM(lst, val) res->source = NULL; res->type = PCBQ_VT_LONG; res->data.lng = val; goto fin; +# define FGW_TO_QRY_STR(lst, val) res->source = NULL; res->type = PCBQ_VT_STRING; res->data.str = rnd_strdup(val == NULL ? "" : val); goto fin; +# define FGW_TO_QRY_NIL(lst, val) res->source = NULL; res->type = PCBQ_VT_VOID; goto fin; + +/* has to free idpath and idpathlist return, noone else will have the chance */ +# define FGW_TO_QRY_PTR(lst, val) \ + if (val == NULL) { \ + res->source = NULL; \ + res->type = PCBQ_VT_VOID; \ + goto fin; \ + } \ + else if (fgw_ptr_in_domain(&rnd_fgw, val, RND_PTR_DOMAIN_IDPATH)) { \ + pcb_idpath_t *idp = val; \ + res->source = NULL; \ + res->type = PCBQ_VT_OBJ; \ + res->data.obj = pcb_idpath2obj(ectx->pcb, idp); \ + pcb_idpath_list_remove(idp); \ + fgw_ptr_unreg(&rnd_fgw, &resa, RND_PTR_DOMAIN_IDPATH); \ + free(idp); \ + goto fin; \ + } \ + else if (fgw_ptr_in_domain(&rnd_fgw, val, RND_PTR_DOMAIN_IDPATH_LIST)) { \ + rnd_message(RND_MSG_ERROR, "query action(): can not convert object list yet\n"); \ + res->source = NULL; \ + res->type = PCBQ_VT_VOID; \ + goto fin; \ + } \ + else { \ + rnd_message(RND_MSG_ERROR, "query action(): can not convert unknown pointer\n"); \ + res->source = NULL; \ + res->type = PCBQ_VT_VOID; \ + goto fin; \ + } + + arg = &resa; + if (FGW_IS_TYPE_CUSTOM(resa.type)) + fgw_arg_conv(&rnd_fgw, &resa, FGW_AUTO); + + switch(FGW_BASE_TYPE(resa.type)) { + ARG_CONV_CASE_LONG(lst, FGW_TO_QRY_NUM); + ARG_CONV_CASE_LLONG(lst, FGW_TO_QRY_NUM); + ARG_CONV_CASE_DOUBLE(lst, FGW_TO_QRY_NUM); + ARG_CONV_CASE_LDOUBLE(lst, FGW_TO_QRY_NUM); + ARG_CONV_CASE_PTR(lst, FGW_TO_QRY_PTR); + ARG_CONV_CASE_STR(lst, FGW_TO_QRY_STR); + ARG_CONV_CASE_CLASS(lst, FGW_TO_QRY_NIL); + ARG_CONV_CASE_INVALID(lst, FGW_TO_QRY_NIL); + } + if (arg->type & FGW_PTR) { + FGW_TO_QRY_PTR(lst, arg->val.ptr_void); + } + else { + FGW_TO_QRY_NIL(lst, 0); + } + + fin:; + for(n = 1; n < argc; n++) { + switch(argv[n].type) { + case PCBQ_VT_LST: + { + pcb_idpath_list_t *list = arga[n].val.ptr_void; + pcb_idpath_list_clear(list); + free(list); + arga[n].val.ptr_void = NULL; + } + break; + default: break; + } + } + + fgw_arg_free(&rnd_fgw, &resa); + return retv; +} + +/*** net integrity ***/ + +typedef struct { + pcb_qry_exec_t *ectx; + pcb_qry_val_t *res; +} fnc_netint_t; + +static int fnc_netint_cb(pcb_net_int_t *nictx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + fnc_netint_t *ctx = nictx->cb_data; + + ctx->res->type = PCBQ_VT_LST; + vtp0_init(&ctx->res->data.lst); + vtp0_append(&ctx->res->data.lst, &pcb_qry_drc_ctrl[PCB_QRY_DRC_GRP1]); + vtp0_append(&ctx->res->data.lst, new_obj); + vtp0_append(&ctx->res->data.lst, &pcb_qry_drc_ctrl[PCB_QRY_DRC_GRP2]); + vtp0_append(&ctx->res->data.lst, arrived_from); + + return 1; /*can return only one pair at the moment so break the search */ +} + +static int fnc_netint_any(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res, int is_shrink) +{ + rnd_coord_t shrink = 0, bloat = 0; + fnc_netint_t ctx; + + if ((argc != 2) || (argv[0].type != PCBQ_VT_OBJ) || ((argv[1].type != PCBQ_VT_COORD) && (argv[1].type != PCBQ_VT_LONG))) + return -1; + + if (is_shrink) + shrink = argv[1].data.crd; + else + bloat = argv[1].data.crd; + + ctx.ectx = ectx; + ctx.res = res; + res->type = PCBQ_VT_VOID; + pcb_net_integrity(ectx->pcb, argv[0].data.obj, shrink, bloat, fnc_netint_cb, &ctx); + return 0; +} + +static int fnc_netbreak(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + return fnc_netint_any(ectx, argc, argv, res, 1); +} + +static int fnc_netshort(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + return fnc_netint_any(ectx, argc, argv, res, 0); +} + +int pcb_qry_fnc_getconf(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + rnd_conf_native_t *nat; + + if (argc != 1) + return -1; + if (argv[0].type != PCBQ_VT_STRING) + return -1; + + nat = rnd_conf_get_field(argv[0].data.str); + if (nat == NULL) + PCB_QRY_RET_INV(res); + + switch(nat->type) { + case RND_CFN_STRING: PCB_QRY_RET_STR(res, nat->val.string[0]); + case RND_CFN_BOOLEAN: PCB_QRY_RET_INT(res, nat->val.boolean[0]); + case RND_CFN_INTEGER: PCB_QRY_RET_INT(res, nat->val.integer[0]); + case RND_CFN_REAL: PCB_QRY_RET_DBL(res, nat->val.real[0]); + case RND_CFN_COORD: PCB_QRY_RET_COORD(res, nat->val.coord[0]); + + case RND_CFN_COLOR: PCB_QRY_RET_STR(res, nat->val.color[0].str); + + case RND_CFN_UNIT: + if (nat->val.unit[0] == NULL) + PCB_QRY_RET_INV(res); + else + PCB_QRY_RET_STR(res, nat->val.unit[0]->suffix); + break; + + case RND_CFN_LIST: + case RND_CFN_HLIST: + case RND_CFN_max: + PCB_QRY_RET_INV(res); + } + return 0; +} + + +static int fnc_pstkring(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + rnd_coord_t cnt = 0; + pcb_pstk_t *ps; + + if ((argc != 2) || (argv[0].type != PCBQ_VT_OBJ) || ((argv[1].type != PCBQ_VT_COORD) && (argv[1].type != PCBQ_VT_LONG))) + return -1; + + ps = (pcb_pstk_t *)argv[0].data.obj; + if (ps->type != PCB_OBJ_PSTK) + PCB_QRY_RET_INV(res); + + pcb_pstk_drc_check_and_warn(ps, &cnt, NULL, argv[1].data.crd, 0); + + PCB_QRY_RET_INT(res, cnt); +} + +static int fnc_netlen(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + pcb_board_t *pcb = ectx->pcb; + pcb_net_t *net = NULL; + pcb_net_term_t *t; + pcb_any_obj_t *obj; + pcb_qry_netseg_len_t *nl; + + if (argc != 1) + return -1; + + switch(argv[0].type) { + case PCBQ_VT_STRING: + net = pcb_net_get(pcb, &pcb->netlist[PCB_NETLIST_EDITED], argv[0].data.str, 0); + break; + case PCBQ_VT_OBJ: + if (argv[0].data.obj->type == PCB_OBJ_NET) + net = (pcb_net_t *)argv[0].data.obj; + default: + break; + } + + if (net == NULL) + PCB_QRY_RET_INV(res); + + if (pcb_termlist_length(&net->conns) > 2) + PCB_QRY_RET_INV(res); + + t = pcb_termlist_first(&net->conns); + if ((t == NULL) || ((obj = pcb_term_find_name(pcb, pcb->Data, PCB_LYT_COPPER, t->refdes, t->term, NULL, NULL)) == NULL)) + PCB_QRY_RET_INV(res); + + nl = pcb_qry_parent_net_lenseg(ectx, obj); + + if ((nl->has_nontrace) || (nl->has_junction)) + PCB_QRY_RET_INV(res); + + PCB_QRY_RET_COORD(res, nl->len); +} Index: tags/2.3.0/src_plugins/query/fnc_layer_setup.c =================================================================== --- tags/2.3.0/src_plugins/query/fnc_layer_setup.c (nonexistent) +++ tags/2.3.0/src_plugins/query/fnc_layer_setup.c (revision 33253) @@ -0,0 +1,565 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - layer setup checks */ + +typedef enum { LSL_ON, LSL_BELOW, LSL_ABOVE, LSL_max } layer_setup_loc_t; +typedef enum { LST_NONE, LST_TYPE, LST_NET, LST_NETMARGIN, LST_RESULT, LST_UNCOVERED, LST_SUBSTRATE } layer_setup_target_t; + +typedef struct { + /* condition/check */ + pcb_layer_type_t require_lyt[LSL_max]; + pcb_layer_type_t refuse_lyt[LSL_max]; + pcb_net_t *require_net[LSL_max]; + rnd_coord_t net_margin[LSL_max]; + + + /* query result request: loc and target */ + layer_setup_loc_t res_loc; + layer_setup_target_t res_target; + + unsigned valid:1; /* 0 on syntax error */ +} layer_setup_t; + +/* measurements saved during the condition/check phase */ +typedef struct { + int matched; /* 1 if condition matched, 0 otherwise */ + double uncovered[LSL_max]; /* area of uncovered portion in nm^2, after a require_net check */ + pcb_layergrp_t *substrate[LSL_max]; +} layer_setup_res_t; + +static layer_setup_res_t ls_invalid; + +typedef struct { + pcb_any_obj_t *obj; + const layer_setup_t *ls; + int above_dir; +} layer_setup_req_t; + + +typedef layer_setup_req_t htls_key_t; +typedef layer_setup_res_t htls_value_t; +#define HT_INVALID_VALUE ls_invalid +#define HT(x) htls_ ## x +#include +#include +#undef HT_INVALID_VALUE +#undef HT + +static int lsreqkeyeq(layer_setup_req_t a, layer_setup_req_t b) +{ + if (a.obj != b.obj) return 0; + if (a.ls != b.ls) return 0; + if (a.above_dir != b.above_dir) return 0; + return 1; +} + +static unsigned lsreqhash(layer_setup_req_t k) +{ + return ptrhash(k.obj) ^ ptrhash(k.ls) ^ k.above_dir; +} + +void pcb_qry_uninit_layer_setup(pcb_qry_exec_t *ectx) +{ + if (!ectx->layer_setup_inited) + return; + + genht_uninit_deep(htpp, &ectx->layer_setup_precomp, { + free(htent->value); + }); + + vtp0_uninit(&ectx->layer_setup_netobjs); + ectx->layer_setup_inited = 0; + htls_free(ectx->layer_setup_res_cache); +} + +static void pcb_qry_init_layer_setup(pcb_qry_exec_t *ectx) +{ + htpp_init(&ectx->layer_setup_precomp, ptrhash, ptrkeyeq); + ectx->layer_setup_inited = 1; + vtp0_init(&ectx->layer_setup_netobjs); + ectx->layer_setup_res_cache = htls_alloc(lsreqhash, lsreqkeyeq); +} + +#define LSC_RESET() \ +do { \ + val = NULL; \ + loc = LSL_ON; \ + target = LST_NONE; \ +} while(0) + +#define LSC_GET_VAL(err_stmt) \ +do { \ + len = s-val; \ + if ((val == NULL) || (len >= sizeof(tmp))) { err_stmt; } \ + strncpy(tmp, val, len); \ + tmp[len] = '\0'; \ +} while(0) + +#define LSC_PARSE_LOCTARGET(s) \ +do { \ + if (strncmp(s, "above", 5) == 0) { s += 5; loc = LSL_ABOVE; } \ + else if (strncmp(s, "below", 5) == 0) { s += 5; loc = LSL_BELOW; } \ + else if (strncmp(s, "result", 6) == 0) { s += 6; target = LST_RESULT; } \ + else if (strncmp(s, "substrate", 9) == 0) { s += 9; target = LST_SUBSTRATE; } \ + else if (strncmp(s, "netmargin", 9) == 0) { s += 9; target = LST_NETMARGIN; } \ + else if (strncmp(s, "uncovered", 9) == 0) { s += 9; target = LST_UNCOVERED; } \ + else if (strncmp(s, "type", 4) == 0) { s += 4; target = LST_TYPE; } \ + else if (strncmp(s, "net", 3) == 0) { s += 3; target = LST_NET; } \ + else if (strncmp(s, "on", 2) == 0) { s += 2; loc = LSL_ON; } \ + else { \ + rnd_message(RND_MSG_ERROR, "layer_setup() compilation error: invalid target or location in '%s'\n", s); \ + return -1; \ + } \ +} while(0) + +static long layer_setup_compile_(pcb_qry_exec_t *ectx, layer_setup_t *ls, const char *s_) +{ + const char *val, *lys, *rest; + layer_setup_loc_t loc; + layer_setup_target_t target; + const char *s; + char tmp[1024]; + int len; + rnd_bool succ; + static const pcb_layer_type_t lyt_allow = PCB_LYT_COPPER | PCB_LYT_SILK | PCB_LYT_MASK | PCB_LYT_PASTE; + pcb_net_t *net; + + LSC_RESET(); + + /* above-type:!copper,below-net:gnd;below-netmargin:10mil */ + for(s = s_;;) { + while(isspace(*s) || (*s == '-')) s++; + if ((*s == '\0') || (*s == ',') || (*s == ';') || (*s == ':')) { + + if (*s == ':') { + s++; + val = s; + if (target != LST_RESULT) /* result has its own parser, don't change s */ + while((*s != '\0') && (*s != ',') && (*s != ';')) s++; + } + + /* close current rule */ + switch(target) { + case LST_RESULT: + /* parse the result part on the right of ':' */ + rest = s; + LSC_RESET(); + + for(;;) { + while(isspace(*s) || (*s == '-')) s++; + if ((*s == '\0') || (*s == ',') || (*s == ';')) + break; + LSC_PARSE_LOCTARGET(s); + } + ls->res_loc = loc; + ls->res_target = target; + switch(target) { + case LST_TYPE: case LST_NET: case LST_NETMARGIN: + rnd_message(RND_MSG_ERROR, "layer_setup() compilation error: invalid result in '%s'\n", rest); + return -1; + default:; + } + break; + case LST_TYPE: + { + int invert = 0; + pcb_layer_type_t lyt; + + LSC_GET_VAL({ + rnd_message(RND_MSG_ERROR, "layer_setup() compilation error: invalid layer type value '%s'\n", val == NULL ? s_ : val); + return -1; + }); + + lys = tmp; + if (*lys == '!') { + invert = 1; + lys++; + } + lyt = pcb_layer_type_str2bit(lys); + if ((lyt == 0) || ((lyt & lyt_allow) != lyt)) { + rnd_message(RND_MSG_ERROR, "layer_setup() compilation error: invalid netmargin value '%s'\n", val); + return -1; + } + if (invert) + ls->refuse_lyt[loc] = lyt; + else + ls->require_lyt[loc] = lyt; + } + break; + + case LST_NET: + LSC_GET_VAL({ + rnd_message(RND_MSG_ERROR, "layer_setup() compilation error: invalid net name '%s'\n", val == NULL ? s_ : val); + return -1; + }); + net = pcb_net_get(ectx->pcb, &ectx->pcb->netlist[PCB_NETLIST_EDITED], tmp, 0); + if (net == NULL) { + rnd_message(RND_MSG_ERROR, "layer_setup() compilation error: net not found: '%s'\n", val); + return -1; + } + ls->require_net[loc] = net; + break; + + case LST_NETMARGIN: + LSC_GET_VAL(goto err_coord); + ls->net_margin[loc] = rnd_get_value(tmp, NULL, NULL, &succ); + if (!succ) { + err_coord:; + rnd_message(RND_MSG_ERROR, "layer_setup() compilation error: invalid netmargin value '%s'\n", val); + return -1; + } + break; + case LST_NONE: + rnd_message(RND_MSG_ERROR, "layer_setup() compilation error: missing target in '%s'\n", s_); + return -1; + default: + rnd_message(RND_MSG_ERROR, "layer_setup() compilation error: wrong target for check in '%s'\n", s_); + return -1; + } + + /* continue with the next rule */ + LSC_RESET(); + if (*s == '\0') + break; + s++; + continue; + } + + LSC_PARSE_LOCTARGET(s); + + } + + return 0; +} + +/* Cache access wrapper around compile - assume the same string will have the same pointer (e.g. net attribute) */ +static const layer_setup_t *layer_setup_compile(pcb_qry_exec_t *ectx, const char *s) +{ + layer_setup_t *ls; + ls = htpp_get(&ectx->layer_setup_precomp, s); + if (ls != NULL) + return ls; + + ls = calloc(sizeof(layer_setup_t), 1); + if (layer_setup_compile_(ectx, ls, s) == 0) + ls->valid = 1; + htpp_set(&ectx->layer_setup_precomp, (void *)s, ls); + return ls; +} + +/* retruns 1 if there is an "adjacent" layer group of lyt in direction dir */ +static rnd_bool lse_next_layer_type(pcb_qry_exec_t *ectx, pcb_any_obj_t *obj, pcb_layergrp_t *grp, pcb_layer_type_t lyt, int dir) +{ + pcb_layer_type_t nextloc = (dir == -1) ? PCB_LYT_TOP : PCB_LYT_BOTTOM; + rnd_layergrp_id_t tmp; + + /* assuming nextloc=top; want to have mask/silk/whatever over us; + only top copper/silk/mask/etc will have a chance to be above */ + if ((lyt & (PCB_LYT_MASK | PCB_LYT_PASTE | PCB_LYT_SILK)) && (!(grp->ltype & nextloc))) + return 0; + + /* assuming nextloc=top; want to have copper over us; + only top copper should fail*/ + if ((lyt & PCB_LYT_COPPER) && (grp->ltype & nextloc)) + return 0; + + /* make sure the referenced layers do exist */ + if ((lyt & PCB_LYT_MASK) && (pcb_layergrp_list(ectx->pcb, PCB_LYT_MASK | nextloc, &tmp, 1) < 1)) + return 0; + if ((lyt & PCB_LYT_SILK) && (pcb_layergrp_list(ectx->pcb, PCB_LYT_SILK | nextloc, &tmp, 1) < 1)) + return 0; + if ((lyt & PCB_LYT_PASTE) && (pcb_layergrp_list(ectx->pcb, PCB_LYT_PASTE | nextloc, &tmp, 1) < 1)) + return 0; + + return 1; +} + +/* append obj to objs if obj is on net */ +static void lse_netcover_add_obj(pcb_qry_exec_t *ectx, vtp0_t *objs, pcb_any_obj_t *obj, pcb_net_t *net) +{ + pcb_any_obj_t *term = pcb_qry_parent_net_term(ectx, obj); + + if ((term == NULL) || (term->type != PCB_OBJ_NET_TERM)) + return; + if (term->parent.net != net) + return; + + vtp0_append(objs, obj); +} + +/* returns 1 if object is fully covered on adjacent copper layer group in direction + dir by objects of net (obj bloated by bloat first); tolerance for full cover is 0.1 mm^2 */ +static int lse_non_covered(pcb_qry_exec_t *ectx, pcb_any_obj_t *obj, rnd_layergrp_id_t ogid, pcb_net_t *net, int dir, rnd_coord_t bloat, double *area_out) +{ + rnd_layergrp_id_t ngid = pcb_layergrp_step(ectx->pcb, ogid, dir, PCB_LYT_COPPER); + pcb_layergrp_t *grp; + vtp0_t *objs = &ectx->layer_setup_netobjs; + rnd_rtree_it_t it; + pcb_any_obj_t *o; + rnd_polyarea_t *iceberg, *ptmp; + static rnd_coord_t zero = 0; + long n; + double final_area2; + + if (ngid == -1) + return 0; + + /* handle only the simple cases for now */ + if ((obj->type != PCB_OBJ_LINE) && (obj->type != PCB_OBJ_ARC) && (obj->type != PCB_OBJ_POLY)) + return 0; + + grp = &ectx->pcb->LayerGroups.grp[ngid]; + objs->used = 0; + + /* gather objects that might be overlapping the target object and are on + the target net */ + for(n = 0; n < grp->len; n++) { + pcb_layer_t *ly = pcb_get_layer(ectx->pcb->Data, grp->lid[n]); + if (ly->arc_tree != NULL) + for(o = rnd_rtree_first(&it, ly->arc_tree, (rnd_rtree_box_t *)&obj->bbox_naked); o != NULL; o = rnd_rtree_next(&it)) + lse_netcover_add_obj(ectx, objs, o, net); + if (ly->line_tree != NULL) + for(o = rnd_rtree_first(&it, ly->line_tree, (rnd_rtree_box_t *)&obj->bbox_naked); o != NULL; o = rnd_rtree_next(&it)) + lse_netcover_add_obj(ectx, objs, o, net); + if (ly->polygon_tree != NULL) + for(o = rnd_rtree_first(&it, ly->polygon_tree, (rnd_rtree_box_t *)&obj->bbox_naked); o != NULL; o = rnd_rtree_next(&it)) + lse_netcover_add_obj(ectx, objs, o, net); + } + +/*rnd_trace("objects on the right net: %d\n", objs->used);*/ + + if (objs->used == 0) /* no object found */ + return 0; + + /* create the bloated polygon of the initial object; use the resulting + polyarea as the 'iceberg, then...' */ + switch(obj->type) { + case PCB_OBJ_LINE: iceberg = pcb_poly_from_pcb_line((pcb_line_t *)obj, ((pcb_line_t *)obj)->Thickness + 2*bloat); break; + case PCB_OBJ_ARC: iceberg = pcb_poly_from_pcb_arc((pcb_arc_t *)obj, ((pcb_arc_t *)obj)->Thickness + 2*bloat); break; + case PCB_OBJ_POLY: iceberg = pcb_poly_clearance_construct((pcb_poly_t *)obj, &bloat, NULL); break; + default: return 0; /* shouldn't get here because input sanity check */ + } + + /* ...subtract each object found from the 'iceberg', melting it down... */ + for(n = 0; n < objs->used; n++) { + pcb_any_obj_t *o = objs->array[n]; + rnd_polyarea_t *heat; + switch(o->type) { + case PCB_OBJ_LINE: heat = pcb_poly_from_pcb_line((pcb_line_t *)o, ((pcb_line_t *)o)->Thickness); break; + case PCB_OBJ_ARC: heat = pcb_poly_from_pcb_arc((pcb_arc_t *)o, ((pcb_arc_t *)o)->Thickness); break; + case PCB_OBJ_POLY: heat = pcb_poly_clearance_construct((pcb_poly_t *)o, &zero, NULL); break; + default: heat = 0; + } + if (heat != 0) { +/*rnd_trace(" sub! %p %$mm\n", iceberg, (rnd_coord_t)sqrt(iceberg->contours->area));*/ + rnd_polyarea_boolean_free(iceberg, heat, &ptmp, RND_PBO_SUB); + iceberg = ptmp; + if (iceberg == NULL) + break; + } + } + + if (iceberg != NULL) { + final_area2 = iceberg->contours->area; + *area_out = sqrt(final_area2); + rnd_polyarea_free(&iceberg); + } + else + *area_out = final_area2 = 0; + + /* by now iceberg contains 'exposed' parts, anything not covered by objects + found; if it is not zero, the cover was not full */ + return final_area2 < RND_MM_TO_COORD(0.01); +} + +/* execute ls on obj, assuming 'above' is in layer stack direction 'above_dir'; + returns true if ls matches obj's current setup */ +static rnd_bool layer_setup_exec(pcb_qry_exec_t *ectx, pcb_any_obj_t *obj, const layer_setup_t *ls, const layer_setup_t *ls_res, int above_dir, layer_setup_res_t *lsr) +{ + pcb_layer_t *ly; + pcb_layergrp_t *grp; + rnd_layergrp_id_t gid, sgid; + layer_setup_req_t req; + int need_set = 0; + htls_entry_t *he; + + /* look up the result in the cache */ + req.obj = obj; + req.ls = ls; + req.above_dir = above_dir; + he = htls_getentry(ectx->layer_setup_res_cache, req); +#ifdef CACHE_DEBUG + rnd_trace("cache %s: %p:%p:%d\n", he == NULL ? "miss":"hit ", obj, ls, above_dir); +#endif + if (he != NULL) { /* cache hit */ + *lsr = he->value; + if (!he->value.matched) /* mismatch -> quick return */ + return 0; + goto cache_hit; /* some parts of the result may not have been calculated on the first insertion, check those again */ + } + + /* not cached, need to apply the condition... */ + need_set = 1; + lsr->matched = 0; + lsr->uncovered[LSL_ABOVE] = lsr->uncovered[LSL_BELOW] = -1; + + /* only layer objects may match */ + if (obj->parent_type != PCB_PARENT_LAYER) + return 0; + + ly = pcb_layer_get_real(obj->parent.layer); + if (ly == NULL) + return 0; + gid = pcb_layer_get_group_(ly); + if (gid == -1) + return 0; + grp = &ectx->pcb->LayerGroups.grp[gid]; + + /*** find any rule we fail to match and return false ***/ + + /* require object's layer type */ + if ((ls->require_lyt[LSL_ON] != 0) && (((ls->require_lyt[LSL_ON] & pcb_layer_flags_(ly)) == 0))) + return 0; + if ((ls->refuse_lyt[LSL_ON] != 0) && (((ls->refuse_lyt[LSL_ON] & pcb_layer_flags_(ly)) != 0))) + return 0; + + + /* require above/below layer's type */ + if ((ls->require_lyt[LSL_ABOVE] != 0) && (!lse_next_layer_type(ectx, obj, grp, ls->require_lyt[LSL_ABOVE], above_dir))) + return 0; + if ((ls->refuse_lyt[LSL_ABOVE] != 0) && (lse_next_layer_type(ectx, obj, grp, ls->refuse_lyt[LSL_ABOVE], above_dir))) + return 0; + if ((ls->require_lyt[LSL_BELOW] != 0) && (!lse_next_layer_type(ectx, obj, grp, ls->require_lyt[LSL_BELOW], -above_dir))) + return 0; + if ((ls->refuse_lyt[LSL_BELOW] != 0) && (lse_next_layer_type(ectx, obj, grp, ls->refuse_lyt[LSL_BELOW], -above_dir))) + return 0; + + + /* check for net coverage on adjacent layer */ + if ((ls->require_net[LSL_ABOVE] != NULL) && (!lse_non_covered(ectx, obj, gid, ls->require_net[LSL_ABOVE], above_dir, ls->net_margin[LSL_ABOVE], &lsr->uncovered[LSL_ABOVE]))) + return 0; + if ((ls->require_net[LSL_BELOW] != NULL) && (!lse_non_covered(ectx, obj, gid, ls->require_net[LSL_BELOW], -above_dir, ls->net_margin[LSL_BELOW], &lsr->uncovered[LSL_BELOW]))) + return 0; + + /* if nothing failed, we have a match */ + lsr->matched = 1; + + /* store above/below substrate */ + sgid = pcb_layergrp_step(ectx->pcb, gid, above_dir, PCB_LYT_SUBSTRATE); + lsr->substrate[LSL_ABOVE] = (sgid != -1) ? &ectx->pcb->LayerGroups.grp[sgid] : NULL; + sgid = pcb_layergrp_step(ectx->pcb, gid, -above_dir, PCB_LYT_SUBSTRATE); + lsr->substrate[LSL_BELOW] = (sgid != -1) ? &ectx->pcb->LayerGroups.grp[sgid] : NULL; + + cache_hit:; + + /* calculate the return value; use ->res_* fields from ls_res */ + /* if condition didn't calculate the result, do it now */ + if ((ls_res->res_target == LST_UNCOVERED) && ((ls_res->res_loc == LSL_BELOW) || (ls_res->res_loc == LSL_ABOVE))) { + if (lsr->uncovered[ls_res->res_loc] < 0) { + int dir = (ls_res->res_loc == LSL_ABOVE) ? above_dir : -above_dir; + lse_non_covered(ectx, obj, gid, ls->require_net[ls_res->res_loc], dir, ls->net_margin[ls_res->res_loc], &lsr->uncovered[ls_res->res_loc]); + need_set = 1; + } + } + + if (need_set) /* not cached yet, need to remember this result */ + htls_set(ectx->layer_setup_res_cache, req, *lsr); + + return 1; +} + +static int fnc_layer_setup(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + pcb_any_obj_t *obj; + const char *lss, *lss_res = NULL; + const layer_setup_t *ls, *ls_res = NULL; + layer_setup_res_t lsr; + + if ((argc < 2) || (argc > 3) || (argv[0].type != PCBQ_VT_OBJ) || (argv[1].type != PCBQ_VT_STRING)) + return -1; + + if (argc == 3) { + if (argv[2].type != PCBQ_VT_STRING) + return -1; + lss_res = argv[2].data.str; + } + + lss = argv[1].data.str; + + if (!ectx->layer_setup_inited) + pcb_qry_init_layer_setup(ectx); + + obj = (pcb_any_obj_t *)argv[0].data.obj; + ls = layer_setup_compile(ectx, lss); + + if (!ls->valid) + return -1; + + if (lss_res != NULL) { + ls_res = layer_setup_compile(ectx, lss_res); + if (!ls->valid) + return -1; + } + else + ls_res = ls; + +/*rnd_trace("layer_setup: %p/'%s' -> %p (ls_res=%p)\n", lss, lss, ls, ls_res);*/ + + /* try above=-1, below=+1 (directions matching normal layer stack ordering) */ + if (layer_setup_exec(ectx, obj, ls, ls_res, -1, &lsr)) + goto done; + + /* try above=+1, below=-1 (opposite directions to normal layer stack ordering) */ + if (layer_setup_exec(ectx, obj, ls, ls_res, 1, &lsr)) + goto done; + + /* both failed -> this layer setup is invalid in any direction */ + + /* generate the result according to ls_res */ + done:; + switch(ls_res->res_target) { + case LST_NONE: + PCB_QRY_RET_INT(res, lsr.matched); + + case LST_UNCOVERED: + if (!lsr.matched) PCB_QRY_RET_INV(res); + PCB_QRY_RET_DBL(res, lsr.uncovered[ls_res->res_loc]); + + case LST_SUBSTRATE: + if (!lsr.matched) PCB_QRY_RET_INV(res); + PCB_QRY_RET_OBJ(res, (pcb_any_obj_t *)lsr.substrate[ls_res->res_loc]); + + case LST_TYPE: + case LST_NET: + case LST_NETMARGIN: + case LST_RESULT: + PCB_QRY_RET_INV(res); + } + + return -1; +} + Index: tags/2.3.0/src_plugins/query/fnc_list.c =================================================================== --- tags/2.3.0/src_plugins/query/fnc_list.c (nonexistent) +++ tags/2.3.0/src_plugins/query/fnc_list.c (revision 33253) @@ -0,0 +1,240 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - listing functions */ + +#define PCB dontuse + +static int fnc_mklist(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + int n; + res->type = PCBQ_VT_LST; + vtp0_init(&res->data.lst); + for(n = 0; n < argc; n++) { + if (argv[n].type == PCBQ_VT_OBJ) + vtp0_append(&res->data.lst, argv[n].data.obj); + } + return 0; +} + +static int fnc_violation(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + int n; + + if ((argc < 2) || (argc % 2 != 0)) + return -1; + + /* argument sanity checks */ + for(n = 0; n < argc; n+=2) { + pcb_qry_val_t *val = &argv[n+1]; + pcb_qry_drc_ctrl_t ctrl = pcb_qry_drc_ctrl_decode(argv[n].data.obj); + switch(ctrl) { + case PCB_QRY_DRC_GRP1: + case PCB_QRY_DRC_GRP2: + if (val->type != PCBQ_VT_OBJ) + return -1; + break; + case PCB_QRY_DRC_EXPECT: + case PCB_QRY_DRC_MEASURE: + break; /* accept as is */ + case PCB_QRY_DRC_TEXT: + break; /* accept anything */ + default: + return -1; + } + } + + res->type = PCBQ_VT_LST; + vtp0_init(&res->data.lst); + for(n = 0; n < argc; n+=2) { + pcb_qry_drc_ctrl_t ctrl = pcb_qry_drc_ctrl_decode(argv[n].data.obj); + pcb_qry_val_t *val = &argv[n+1]; + pcb_obj_qry_const_t *tmp; + + if (ctrl == PCB_QRY_DRC_TEXT) { + char *str = "", buff[128]; + switch(val->type) { + case PCBQ_VT_VOID: str = ""; break; + case PCBQ_VT_OBJ: str = ""; break; + case PCBQ_VT_LST: str = ""; break; + case PCBQ_VT_COORD: rnd_snprintf(buff, sizeof(buff), "%mH$", argv[n+1].data.crd); str = buff; break; + case PCBQ_VT_LONG: rnd_snprintf(buff, sizeof(buff), "%ld", argv[n+1].data.lng); str = buff; break; + case PCBQ_VT_DOUBLE: rnd_snprintf(buff, sizeof(buff), "%f", argv[n+1].data.dbl); str = buff; break; + case PCBQ_VT_STRING: str = (char *)argv[n+1].data.str; break; + } + str = rnd_strdup(str == NULL ? "" : str); + vtp0_append(&res->data.lst, argv[n].data.obj); + vtp0_append(&res->data.lst, str); + vtp0_append(&ectx->autofree, str); + } + else if ((ctrl == PCB_QRY_DRC_EXPECT) || (ctrl == PCB_QRY_DRC_MEASURE)) { + tmp = malloc(sizeof(pcb_obj_qry_const_t)); + tmp->val = *val; + tmp->type = PCB_OBJ_QRY_CONST; + vtp0_append(&res->data.lst, argv[n].data.obj); + vtp0_append(&res->data.lst, tmp); + vtp0_append(&ectx->autofree, tmp); + } + else switch(val->type) { + case PCBQ_VT_OBJ: + vtp0_append(&res->data.lst, argv[n].data.obj); + vtp0_append(&res->data.lst, argv[n+1].data.obj); + break; + case PCBQ_VT_COORD: + case PCBQ_VT_LONG: + case PCBQ_VT_DOUBLE: + tmp = malloc(sizeof(pcb_obj_qry_const_t)); + memcpy(&tmp->val, val, sizeof(pcb_qry_val_t)); + vtp0_append(&res->data.lst, argv[n].data.obj); + vtp0_append(&res->data.lst, tmp); + vtp0_append(&ectx->autofree, tmp); + break; + case PCBQ_VT_VOID: + case PCBQ_VT_LST: + case PCBQ_VT_STRING: + /* can't be on a violation list at the moment */ + break; + } + } + return 0; +} + +static int fnc_netlist(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + long n; + htsp_entry_t *e; + pcb_netlist_t *nl = &ectx->pcb->netlist[PCB_NETLIST_EDITED]; + + res->type = PCBQ_VT_LST; + vtp0_init(&res->data.lst); + + if (nl->used != 0) + for(e = htsp_first(nl), n = 0; e != NULL; e = htsp_next(nl, e), n++) + vtp0_append(&res->data.lst, e->value); + + return 0; +} + +static int fnc_layerlist(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + long n; + + res->type = PCBQ_VT_LST; + vtp0_init(&res->data.lst); + for(n = 0; n < ectx->pcb->Data->LayerN; n++) + vtp0_append(&res->data.lst, &ectx->pcb->Data->Layer[n]); + + return 0; +} + +static int fnc_net_cb(pcb_find_t *fctx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + vtp0_t *v = fctx->user_data; + vtp0_append(v, new_obj); + return 0; +} + +static void fnc_find_init(pcb_qry_exec_t *ectx, pcb_find_t *fctx, vtp0_t *resvt, int rats) +{ + memset(fctx, 0, sizeof(pcb_find_t)); + fctx->consider_rats = rats; + if (resvt != NULL) { + fctx->found_cb = fnc_net_cb; + fctx->user_data = resvt; + } + pcb_find_from_obj(fctx, ectx->pcb->Data, NULL); +} + +static void fnc_find_from(pcb_qry_exec_t *ectx, pcb_find_t *fctx, pcb_any_obj_t *from) +{ + if (!PCB_FIND_IS_MARKED(fctx, from)) + pcb_find_from_obj_next(fctx, ectx->pcb->Data, from); +} + +static int fnc_net_any(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res, int find_all, int netseg) +{ + pcb_net_t *net; + pcb_net_term_t *t; + pcb_find_t fctx; + + + if ((argv[0].type != PCBQ_VT_OBJ) || (argv[0].data.obj->type != PCB_OBJ_NET)) + return -1; + + if (find_all) + fnc_find_init(ectx, &fctx, netseg ? NULL : &res->data.lst, 0); + + res->type = PCBQ_VT_LST; + vtp0_init(&res->data.lst); + + net = (pcb_net_t *)argv[0].data.obj; + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) { + pcb_any_obj_t *o = pcb_term_find_name(ectx->pcb, ectx->pcb->Data, PCB_LYT_COPPER, t->refdes, t->term, NULL, NULL); + if (o != NULL) { + if (find_all) { + if (netseg && !PCB_FIND_IS_MARKED(&fctx, o)) /* report first (unmarked) object of the seg */ + vtp0_append(&res->data.lst, o); + fnc_find_from(ectx, &fctx, o); /* mark all objects on this seg, potentiall also reporting them */ + } + else + vtp0_append(&res->data.lst, o); /* no search required, just report all terminals */ + } + } + + if (find_all) + pcb_find_free(&fctx); + + return 0; +} + +static int fnc_netterms(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + return fnc_net_any(ectx, argc, argv, res, 0, 0); +} + +static int fnc_netobjs(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + return fnc_net_any(ectx, argc, argv, res, 1, 0); +} + +static int fnc_netsegs(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + return fnc_net_any(ectx, argc, argv, res, 1, 1); +} + + +static int fnc_subcobjs(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + if ((argv[0].type != PCBQ_VT_OBJ) || (argv[0].data.obj->type != PCB_OBJ_SUBC)) + return -1; + + res->type = PCBQ_VT_LST; + vtp0_init(&res->data.lst); + pcb_qry_list_all_subc(res, (pcb_subc_t *)argv[0].data.obj, PCB_OBJ_ANY & (~PCB_OBJ_LAYER)); + + return 0; +} + Index: tags/2.3.0/src_plugins/query/fnc_obj.c =================================================================== --- tags/2.3.0/src_plugins/query/fnc_obj.c (nonexistent) +++ tags/2.3.0/src_plugins/query/fnc_obj.c (revision 33253) @@ -0,0 +1,70 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - special object accessor functions */ + +#include "thermal.h" + +#define PCB dontuse + +static int fnc_thermal_on(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res) +{ + pcb_any_obj_t *obj, *lo; + pcb_layer_t *ly = NULL; + unsigned char *t; + + if ((argc != 2) || (argv[0].type != PCBQ_VT_OBJ) || (argv[1].type != PCBQ_VT_OBJ)) + return -1; + + obj = (pcb_any_obj_t *)argv[0].data.obj; + lo = (pcb_any_obj_t *)argv[1].data.obj; + + if (lo->type == PCB_OBJ_LAYER) + ly = pcb_layer_get_real((pcb_layer_t *)lo); + else if (lo->type & PCB_OBJ_CLASS_LAYER) + ly = pcb_layer_get_real(lo->parent.layer); + else + return -1; + + if (ly == NULL) + return -1; + + if (obj->type != PCB_OBJ_PSTK) { + if (pcb_layer_get_real(obj->parent.layer) != ly) + PCB_QRY_RET_STR(res, ""); + t = &obj->thermal; + } + else + t = pcb_obj_common_get_thermal(obj, pcb_layer_id(ectx->pcb->Data, ly), 0); + + if (t == NULL) + PCB_QRY_RET_STR(res, ""); + + pcb_thermal_bits2chars(res->data.local_str.tmp, t[0]); + + PCB_QRY_RET_STR(res, res->data.local_str.tmp); +} + Index: tags/2.3.0/src_plugins/query/net_int.c =================================================================== --- tags/2.3.0/src_plugins/query/net_int.c (nonexistent) +++ tags/2.3.0/src_plugins/query/net_int.c (revision 33253) @@ -0,0 +1,203 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2018,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include +#include + +#include "board.h" +#include "find.h" +#include "netlist.h" +#include "net_int.h" + +#define PCB dontuse + +/* evaluates to true if obj was marked on list (fa or fb) */ +#define IS_FOUND(obj, list) PCB_FIND_IS_MARKED(&ctx->list, obj) + +static int pcb_int_broken_cb(pcb_find_t *fctx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + pcb_net_int_t *ctx = fctx->user_data; + + if (arrived_from == NULL) /* ingore the starting object - it must be marked as we started from the same object in the first search */ + return 0; + + /* broken if new object is not marked in the shrunk search (fa) but + the arrived_from object was marked (so we notify direct breaks only) */ + if (!IS_FOUND(new_obj, fa) && IS_FOUND(arrived_from, fa)) { + int r = ctx->broken_cb(ctx, new_obj, arrived_from, ctype); + if (r != 0) return r; + return ctx->fast; /* if fast is 1, we are aborting the search, returning the first hit only */ + } + return 0; +} + +rnd_bool pcb_net_integrity(pcb_board_t *pcb, pcb_any_obj_t *from, rnd_coord_t shrink, rnd_coord_t bloat, pcb_int_broken_cb_t *cb, void *cb_data) +{ + pcb_net_int_t ctx; + + ctx.pcb = pcb; + ctx.fast = 1; + ctx.data = pcb->Data; + ctx.bloat = bloat; + ctx.shrink = shrink; + ctx.broken_cb = cb; + ctx.cb_data = cb_data; + + memset(&ctx.fa, 0, sizeof(ctx.fa)); + memset(&ctx.fb, 0, sizeof(ctx.fb)); + ctx.fa.user_data = ctx.fb.user_data = &ctx; + ctx.fb.found_cb = pcb_int_broken_cb; + + /* Check for minimal overlap: shrink mark all objects on the net in fa; + restart the search without shrink in fb: if anything new is found, it did + not have enough overlap and shrink disconnected it. */ + if (shrink != 0) { + ctx.shrunk = 1; + ctx.fa.bloat = -shrink; + pcb_find_from_obj(&ctx.fa, pcb->Data, from); + ctx.fa.bloat = 0; + pcb_find_from_obj(&ctx.fb, pcb->Data, from); + pcb_find_free(&ctx.fa); + pcb_find_free(&ctx.fb); + } + + /* Check for minimal distance: bloat mark all objects on the net in fa; + restart the search without bloat in fb: if anything new is found, it did + not have a connection without the bloat. */ + if (bloat != 0) { + ctx.shrunk = 0; + ctx.fa.bloat = 0; + pcb_find_from_obj(&ctx.fa, pcb->Data, from); + ctx.fb.bloat = bloat; + pcb_find_from_obj(&ctx.fb, pcb->Data, from); + pcb_find_free(&ctx.fa); + pcb_find_free(&ctx.fb); + } + + return rnd_false; +} + + +/*** cached object -> network-terminal ***/ + +/* Whenever a net tag of an object is queried: + 1. look at the cache - if the object is already mapped, return result from + cache (ec->obj2netterm) + 2. else map the whole network segment starting from obj, using galvanic + connections only; remember every object being in the segment + (using ec->tmplst) + 3. at the end of the mapping, select the best terminal object for the + segment: terminal with the lowest ID (when segment is part of a netlisted + net) or random object with the lowest ID (when segment is floating with + no connection to terminal) + 4. assign the resulting terminal object to all objects on the net in + the cache (ec->obj2netterm) so subsequent calls on any segment object + will bail out in step 1 +*/ + +typedef struct { + pcb_qry_exec_t *ec; + pcb_any_obj_t *best_term; + pcb_any_obj_t *best_nonterm; +} parent_net_term_t; + +static int parent_net_term_found_cb(pcb_find_t *fctx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + parent_net_term_t *ctx = fctx->user_data; + + vtp0_append(&ctx->ec->tmplst, new_obj); + + if (new_obj->term != NULL) { + if ((ctx->best_term == NULL) || (new_obj->ID < ctx->best_term->ID)) + ctx->best_term = new_obj; + } + else { + if ((ctx->best_nonterm == NULL) || (new_obj->ID < ctx->best_nonterm->ID)) + ctx->best_nonterm = new_obj; + } + return 0; +} + + +RND_INLINE pcb_any_obj_t *pcb_qry_parent_net_term_(pcb_qry_exec_t *ec, pcb_any_obj_t *from) +{ + pcb_find_t fctx; + parent_net_term_t ctx; + pcb_any_obj_t *res = NULL; + long n; + + assert(ec->tmplst.used == 0); /* temp list must be empty so we are nto getting void * ptrs to anything else than we find */ + + ctx.ec = ec; + ctx.best_term = NULL; + ctx.best_nonterm = from; /* worst case: floating segment with only this object */ + + memset(&fctx, 0, sizeof(fctx)); + fctx.user_data = &ctx; + fctx.found_cb = parent_net_term_found_cb; + pcb_find_from_obj(&fctx, ec->pcb->Data, from); + pcb_find_free(&fctx); + + /* for terminals do the expensive lookup and return the PCB_OBJ_NET_TERM object */ + if (ctx.best_term != NULL) { + pcb_net_term_t *t; + t = pcb_net_find_by_obj(&ec->pcb->netlist[PCB_NETLIST_EDITED], ctx.best_term); + res = (t == NULL) ? ctx.best_term : (pcb_any_obj_t *)t; + } + else + res = ctx.best_nonterm; + + for(n = 0; n < ec->tmplst.used; n++) + htpp_set(&ec->obj2netterm, ec->tmplst.array[n], res); + + ec->tmplst.used = 0; + + return res; +} + + +pcb_any_obj_t *pcb_qry_parent_net_term(pcb_qry_exec_t *ec, pcb_any_obj_t *from) +{ + pcb_any_obj_t *res; + if (!ec->obj2netterm_inited) { + htpp_init(&ec->obj2netterm, ptrhash, ptrkeyeq); + ec->obj2netterm_inited = 1; + res = NULL; + } + else + res = htpp_get(&ec->obj2netterm, from); + + if (res == NULL) + res = pcb_qry_parent_net_term_(ec, from); + + return res; +} + Index: tags/2.3.0/src_plugins/query/net_int.h =================================================================== --- tags/2.3.0/src_plugins/query/net_int.h (nonexistent) +++ tags/2.3.0/src_plugins/query/net_int.h (revision 33253) @@ -0,0 +1,35 @@ +#include "find.h" +#include "obj_common.h" +#include "query_exec.h" + +typedef struct pcb_net_int_s pcb_net_int_t; +typedef int (pcb_int_broken_cb_t)(pcb_net_int_t *ctx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype); + +struct pcb_net_int_s { + pcb_board_t *pcb; + pcb_find_t fa, fb; + pcb_data_t *data; + rnd_coord_t bloat, shrink; + unsigned fast:1; + unsigned shrunk:1; + + /* called on integrity check failure: either broken trace (shrunk==1) or + short circuit (shrunk==0); like 'find' callback; return + non-zero to break the search */ + pcb_int_broken_cb_t *broken_cb; + void *cb_data; +}; + + +/* Check for DRC violations on a single net starting from the pad or pin + sees if the connectivity changes when everything is bloated, or shrunk. + If shrink or bloat is 0, that side of the test is skipped */ +rnd_bool pcb_net_integrity(pcb_board_t *pcb, pcb_any_obj_t *from, rnd_coord_t shrink, rnd_coord_t bloat, pcb_int_broken_cb_t *cb, void *cb_data); + + +/* Map the network of the from object. If it's a segment of a netlisted net, + return the terminal object with the lowest ID from that segment. If it's + an unlisted (floating) net, return the lowest ID copper object. (Worst + case it is a floating net with only this one object - then the object + is returned). The search is cached. */ +pcb_any_obj_t *pcb_qry_parent_net_term(pcb_qry_exec_t *ec, pcb_any_obj_t *from); Index: tags/2.3.0/src_plugins/query/net_len.c =================================================================== --- tags/2.3.0/src_plugins/query/net_len.c (nonexistent) +++ tags/2.3.0/src_plugins/query/net_len.c (revision 33253) @@ -0,0 +1,543 @@ +/* + * + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include +#include +#include + +#include "board.h" +#include "find.h" +#include "netlist.h" +#include "query_exec.h" +#include "net_len.h" +#include "obj_arc.h" +#include "obj_line.h" +#include "obj_pstk.h" +#include "obj_term.h" + +#include +#include + +#define PCB dontuse + +/* evaluates to true if obj was marked on list (fa or fb) */ +#define IS_FOUND(obj, list) (PCB_DFLAG_TEST(&(obj->Flags), ctx->list.mark)) + +/*** cached object -> net length-segment ***/ + +/* Whenever a net tag of an object is queried: + 1. look at the cache - if the object is already mapped, return result from + cache (ec->obj2lenseg) + 2. else map the whole network segment starting from obj, using galvanic + connections only, up to the first junction; remember every object + being in the segment (using ec->tmplst) + 3. assign the result struct to all objects on the net in + the cache (ec->obj2lenseg) so subsequent calls on any segment object + will bail out in step 1 +*/ + +typedef struct { + pcb_qry_exec_t *ec; + pcb_any_obj_t *start, *best; + pcb_qry_netseg_len_t *seglen; +} parent_net_len_t; + +/* set a cc bit for an object; returns 0 on success, 1 if the bit was already set */ +static int set_cc(parent_net_len_t *ctx, pcb_any_obj_t *o, int val) +{ + htpi_entry_t *e = htpi_getentry(&ctx->ec->obj2lenseg_cc, o); + +rnd_trace("set_cc: #%ld %d pstk: %d\n", o->ID, val, (o->type == PCB_OBJ_PSTK)); + + if (e == NULL) { + htpi_set(&ctx->ec->obj2lenseg_cc, o, val); + return 0; + } + + if (o->type == PCB_OBJ_PSTK) { /* padstacks have only one end */ + e->value++; + if (e->value > 2) + return 1; + } + else { + if ((e->value & val) == val) + return 1; + + e->value |= val; + } + return 0; +} + +static int obj_ends(pcb_any_obj_t *o, rnd_coord_t ends[4], rnd_coord_t *thick) +{ + pcb_arc_t *a = (pcb_arc_t *)o; + pcb_line_t *l = (pcb_line_t *)o; + pcb_pstk_t *p = (pcb_pstk_t *)o; + + switch(o->type) { + case PCB_OBJ_ARC: + pcb_arc_get_end(a, 0, &ends[0], &ends[1]); + pcb_arc_get_end(a, 1, &ends[2], &ends[3]); + *thick = a->Thickness; + return 0; + + case PCB_OBJ_LINE: + ends[0] = l->Point1.X; ends[1] = l->Point1.Y; + ends[2] = l->Point2.X; ends[3] = l->Point2.Y; + *thick = l->Thickness; + return 0; + + case PCB_OBJ_PSTK: + ends[0] = p->x; ends[1] = p->y; + ends[2] = ends[3] = RND_COORD_MAX; + /* thickness estimation: smaller bbox size */ + *thick = RND_MIN(p->bbox_naked.X2-p->bbox_naked.X1, p->bbox_naked.Y2-p->bbox_naked.Y1); + return 0; + + /* netlen segment breaking objects */ + case PCB_OBJ_VOID: case PCB_OBJ_POLY: case PCB_OBJ_TEXT: case PCB_OBJ_SUBC: + case PCB_OBJ_RAT: case PCB_OBJ_GFX: case PCB_OBJ_NET: case PCB_OBJ_NET_TERM: + case PCB_OBJ_LAYER: case PCB_OBJ_LAYERGRP: + return -1; + } + return -1; +} + +static rnd_coord_t obj_len(pcb_any_obj_t *o) +{ + switch(o->type) { + case PCB_OBJ_ARC: return pcb_arc_length((pcb_arc_t *)o); + case PCB_OBJ_LINE: return pcb_line_length((pcb_line_t *)o); + case PCB_OBJ_PSTK: return 0; + + /* netlen segment breaking objects */ + case PCB_OBJ_VOID: case PCB_OBJ_POLY: case PCB_OBJ_TEXT: case PCB_OBJ_SUBC: + case PCB_OBJ_RAT: case PCB_OBJ_GFX: case PCB_OBJ_NET: case PCB_OBJ_NET_TERM: + case PCB_OBJ_LAYER: case PCB_OBJ_LAYERGRP: + return -1; + } + return -1; +} + +static int endp_match(parent_net_len_t *ctx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, double *dist) +{ + rnd_coord_t new_end[4], new_th, old_end[4], old_th; + double th, d2; + int n, conns = 0, bad = 0; + + if (obj_ends(new_obj, new_end, &new_th) != 0) { + ctx->seglen->has_nontrace = 1; + rnd_trace("NSL: badobj: #%ld\n", new_obj->ID); + return -1; + } + obj_ends(arrived_from, old_end, &old_th); + th = RND_MIN(new_th, old_th) * 4 / 5; + th = th * th; + + for(n = 0; n < 4; n+=2) { + d2 = rnd_distance2(old_end[0], old_end[1], new_end[0+n], new_end[1+n]); + if (d2 < th) { + if (dist != NULL) { + *dist = sqrt(d2); + return 0; + } + if (set_cc(ctx, arrived_from, 1) != 0) { + rnd_trace("NSL: junction at end: 0 of #%ld at %$$mm;%$$mm\n", arrived_from->ID, old_end[0], old_end[1]); + bad = 1; + } + if (set_cc(ctx, new_obj, n == 0 ? 1 : 2) != 0) { + rnd_trace("NSL: junction at end: %d of #%ld at %$$mm;%$$mm\n", n, new_obj->ID, new_end[0+n], new_end[1+n]); + bad = 1; + } + if (bad) + return -1; + conns++; + } + + d2 = rnd_distance2(old_end[2], old_end[3], new_end[0+n], new_end[1+n]); + if (d2 < th) { + if (dist != NULL) { + *dist = sqrt(d2); + return 0; + } + if (set_cc(ctx, arrived_from, 2) != 0) { + rnd_trace("NSL: junction at end: 0 of #%ld at %$$mm;%$$mm\n", arrived_from->ID, old_end[2], old_end[3]); + bad = 1; + } + if (set_cc(ctx, new_obj, n == 0 ? 1 : 2) != 0) { + rnd_trace("NSL: junction at end: %d of #%ld at %$$mm;%$$mm\n", n, new_obj->ID, new_end[0+n], new_end[1+n]); + bad = 1; + } + if (bad) + return -1; + conns++; + } + } + + if (conns == 0) { + if (dist == NULL) + rnd_trace("NSL: junction at: middle of #%ld vs. #%ld\n", new_obj->ID, arrived_from->ID); + return -2; + } + if (conns > 1) { + if (dist == NULL) + rnd_trace("NSL: junction at: #%ld overlap with #%ld\n", new_obj->ID, arrived_from->ID); + return -2; + } + + return 0; +} + +static void remove_offender_from_open(pcb_find_t *fctx, pcb_any_obj_t *offender) +{ + long n; + + /* remove anything from the open list has contect with the offending object, + so we are not going to follow a thread that is also affected */ + for(n = 0; n < fctx->open.used; n++) { + pcb_any_obj_t *o = fctx->open.array[n]; + + if (pcb_intersect_obj_obj(fctx, offender, o)) { + rnd_trace(" REMOVE1: #%ld\n", o->ID); + vtp0_remove(&fctx->open, n, 1); + n--; + } + } +} + +/* also remove affected objects from the found list */ +static void remove_offender_from_closed(pcb_find_t *fctx, pcb_any_obj_t *offender, pcb_any_obj_t *dont_remove) +{ + long n; + parent_net_len_t *ctx = fctx->user_data; + + for(n = 0; n < ctx->ec->tmplst.used; n++) { + pcb_any_obj_t *o = ctx->ec->tmplst.array[n]; + if ((o != dont_remove) && (pcb_intersect_obj_obj(fctx, offender, o))) { + rnd_trace(" REMOVE2: #%ld\n", o->ID); + vtp0_remove(&ctx->ec->tmplst, n, 1); + n--; + } + } +} + + +static int parent_net_len_found_cb(pcb_find_t *fctx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + parent_net_len_t *ctx = fctx->user_data; + +rnd_trace("from: #%ld to #%ld\n", arrived_from == NULL ? 0 : arrived_from->ID, new_obj->ID); + + if (arrived_from != NULL) { + int coll = endp_match(ctx, new_obj, arrived_from, NULL); + if (coll != 0) { + ctx->seglen->has_junction = 1; +/*rnd_trace("BUMP new=#%ld from=#%ld last=#%ld coll=%d\n", new_obj->ID, arrived_from->ID, ((pcb_any_obj_t *)ctx->ec->tmplst.array[ctx->ec->tmplst.used-1])->ID, coll);*/ + + + if (coll == -1) { + /* remove from new_obj: keeps the hub object we are at (only endpoint + of it is affected*/ + remove_offender_from_open(fctx, new_obj); + remove_offender_from_closed(fctx, new_obj, arrived_from); + } + else if (coll == -2) { + long n; + int cnt; + + /* remove from arrived_from: removes the hub object */ + remove_offender_from_open(fctx, arrived_from); + remove_offender_from_closed(fctx, new_obj, arrived_from); + + + /* plus remove the hub itself from found if it's not the startin object */ + if (arrived_from != ctx->start) { + for(n = 0; n < ctx->ec->tmplst.used; n++) { + pcb_any_obj_t *o = ctx->ec->tmplst.array[n]; + if (o == arrived_from) { + vtp0_remove(&ctx->ec->tmplst, n, 1); + break; + } + } + } + + /* plus remove anything but the first object that is in contact with it + (this removes started outgoing threads but not the object we once + came from to reach arrived_from) */ + for(n = 0, cnt = 0; n < ctx->ec->tmplst.used; n++) { + pcb_any_obj_t *o = ctx->ec->tmplst.array[n]; + if (pcb_intersect_obj_obj(fctx, o, arrived_from)) { + cnt++; + if (cnt > 1) { + vtp0_remove(&ctx->ec->tmplst, n, 1); + n--; + } + } + } + + } + return PCB_FIND_DROP_THREAD; + } + } + + vtp0_append(&ctx->ec->tmplst, new_obj); + + if ((ctx->best == NULL) || (new_obj < ctx->best)) + ctx->best = new_obj; + + return 0; +} + +/* returns 1 if o1 and o2 are not ordered; ordered means left->right (x+) + or top->bottom (y+) direction between o1 and o2 center */ +static int seg_dir_reversed(pcb_any_obj_t *o1, pcb_any_obj_t *o2) +{ + rnd_coord_t x1, y1, x2, y2, dx, dy, adx, ady; + + pcb_obj_center(o1, &x1, &y1); + pcb_obj_center(o2, &x2, &y2); + dx = x2 - x1; + dy = y2 - y1; + + adx = RND_ABS(dx); + ady = RND_ABS(dy); + + /* determine main direction */ + if (adx > (ady+ady/4)) /* horizontal */ + return dx < 0; + if (ady > (adx+adx/4)) /* vertical */ + return dy < 0; + + /* diagonal */ + return dx < 0; +} + +static pcb_layergrp_t *get_obj_grp(pcb_board_t *pcb, pcb_any_obj_t *o) +{ + switch(o->type) { + case PCB_OBJ_ARC: + case PCB_OBJ_LINE: + /* plain layer obj */ + assert(o->parent_type == PCB_PARENT_LAYER); + return pcb_get_layergrp(pcb, pcb_layer_get_group_(o->parent.layer)); + + case PCB_OBJ_PSTK: + TODO("special case: padstack with copper only on top or bottom"); + return NULL; + + /* netlen segment breaking objects */ + case PCB_OBJ_VOID: case PCB_OBJ_POLY: case PCB_OBJ_TEXT: case PCB_OBJ_SUBC: + case PCB_OBJ_RAT: case PCB_OBJ_GFX: case PCB_OBJ_NET: case PCB_OBJ_NET_TERM: + case PCB_OBJ_LAYER: case PCB_OBJ_LAYERGRP: + return NULL; + } + return NULL; +} + +RND_INLINE pcb_qry_netseg_len_t *pcb_qry_parent_net_lenseg_(pcb_qry_exec_t *ec, pcb_any_obj_t *from) +{ + pcb_find_t fctx; + parent_net_len_t ctx; + long n, revp = -1; + pcb_layergrp_t *lg; + + assert(ec->tmplst.used == 0); /* temp list must be empty so we are nto getting void * ptrs to anything else than we find */ + + ctx.ec = ec; + ctx.start = from; + ctx.best = NULL; + ctx.seglen = calloc(sizeof(pcb_qry_netseg_len_t), 1); + vtp0_append(&ec->obj2lenseg_free, ctx.seglen); + + memset(&fctx, 0, sizeof(fctx)); + fctx.user_data = &ctx; + fctx.found_cb = parent_net_len_found_cb; + pcb_find_from_obj(&fctx, ec->pcb->Data, from); + pcb_find_free(&fctx); + + for(n = 0; n < ec->tmplst.used; n++) { + pcb_any_obj_t *o = ec->tmplst.array[n]; + + htpp_set(&ec->obj2lenseg, o, ctx.seglen); + ctx.seglen->len += obj_len(o); + vtp0_append(&ctx.seglen->objs, o); + + if (n > 0) { + double offs = 0; + if (endp_match(&ctx, o, (pcb_any_obj_t *)ec->tmplst.array[n-1], &offs) < 0) { + /* remember the first place in the list where endpoints don't meet - this + must be the place where the search started in the other direction from + the starting object - see below at "reversing" */ + if (revp > 0) + rnd_message(RND_MSG_ERROR, "Internal error: pcb_qry_parent_net_lenseg_(): multiple revp's\n"); + else + revp = n; + } +/* rnd_trace("offs: #%ld #%ld: %$mm (%f) %d\n", ((pcb_any_obj_t *)ec->tmplst.array[n-1])->ID, o->ID, (rnd_coord_t)(offs), offs);*/ + ctx.seglen->len += offs; + } + } + + /* reversing: take the following thread of lines by ID: + #1 #5 #8 #11 #14 + A search starting from 8 will yield the following raw list: + #8 #5 #1 #11 #14 + If there's no loop or other error, #1 and #11 won't have a common + endpoint and thus revp will be set to 3, which is #11's IDX. + When that happens, we need to reverse the order of items before revp to + get: + #1 #5 #8 #11 #14 + */ + if (revp > 0) { + for(n = 0; n < revp/2; n++) + rnd_swap(void *, ctx.seglen->objs.array[n], ctx.seglen->objs.array[revp-n-1]); + } + + /* make sure objects are always returned in the same order for the same net, + no matter which object was the start of the mapping */ + if ((ctx.seglen->objs.used > 1) && (seg_dir_reversed(ctx.seglen->objs.array[0], ctx.seglen->objs.array[ctx.seglen->objs.used-1]))) { + for(n = 0; n < ctx.seglen->objs.used/2; n++) + rnd_swap(void *, ctx.seglen->objs.array[n], ctx.seglen->objs.array[ctx.seglen->objs.used-n-1]); + } + + /* count vias (layer jumps) */ + lg = NULL; + ctx.seglen->num_vias = 0; + for(n = 0; n < ctx.seglen->objs.used; n++) { + pcb_any_obj_t *o = ctx.seglen->objs.array[n]; + pcb_layergrp_t *g = get_obj_grp(ec->pcb, o); + + if (g == NULL) + continue; /* multi-layer padstacks */ + if ((lg != NULL) && (g != lg)) { /* layer group change other than the initial layer group */ + rnd_coord_t vert = pcb_stack_thickness(ec->pcb, NULL, 0, lg - ec->pcb->LayerGroups.grp, 0, g - ec->pcb->LayerGroups.grp, 0, PCB_LYT_SUBSTRATE | PCB_LYT_COPPER); + if ((vert <= 0) && (!ec->warned_missing_thickness)) { + ec->warned_missing_thickness = 1; + rnd_message(RND_MSG_ERROR, "Some of the substrate or copper layers are missing the 'thickness' attribute; network length does not include via length\n"); + } + else + ctx.seglen->len += vert; + ctx.seglen->num_vias++; + } + lg = g; + } + + + ec->tmplst.used = 0; + return ctx.seglen; +} + + +pcb_qry_netseg_len_t *pcb_qry_parent_net_lenseg(pcb_qry_exec_t *ec, pcb_any_obj_t *from) +{ + pcb_qry_netseg_len_t *res; + + if ((from->type != PCB_OBJ_LINE) && (from->type != PCB_OBJ_ARC) && (from->type != PCB_OBJ_PSTK)) + return NULL; + + if (!ec->obj2lenseg_inited) { + htpp_init(&ec->obj2lenseg, ptrhash, ptrkeyeq); + htpi_init(&ec->obj2lenseg_cc, ptrhash, ptrkeyeq); + vtp0_init(&ec->obj2lenseg_free); + ec->obj2lenseg_inited = 1; + res = NULL; + } + else + res = htpp_get(&ec->obj2lenseg, from); + + if (res == NULL) + res = pcb_qry_parent_net_lenseg_(ec, from); + + return res; +} + + +void pcb_qry_lenseg_free_fields(pcb_qry_netseg_len_t *ns) +{ + vtp0_uninit(&ns->objs); +} + +const char pcb_acts_QueryCalcNetLen[] = "QueryCalcNetLen(netname)"; +const char pcb_acth_QueryCalcNetLen[] = "Calculates the network length by netname; returns an error message string or a positive coord with the length"; +fgw_error_t pcb_act_QueryCalcNetLen(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *netname, *err = NULL; + pcb_net_t *net; + pcb_net_term_t *t; + pcb_any_obj_t *obj; + pcb_qry_netseg_len_t *nl; + pcb_qry_exec_t ec; + + RND_ACT_CONVARG(1, FGW_STR, QueryCalcNetLen, netname = argv[1].val.str); + + pcb_qry_init(&ec, pcb, NULL, -1); + + net = pcb_net_get(pcb, &pcb->netlist[PCB_NETLIST_EDITED], netname, 0); + if (net == NULL) { + err = "not found"; + goto out; + } + + if (pcb_termlist_length(&net->conns) > 2) { + err = "more than 2 terminals"; + goto out; + } + + t = pcb_termlist_first(&net->conns); + if ((t == NULL) || ((obj = pcb_term_find_name(pcb, pcb->Data, PCB_LYT_COPPER, t->refdes, t->term, NULL, NULL)) == NULL)) { + err = "missing terminal"; + goto out; + } + + nl = pcb_qry_parent_net_lenseg(&ec, obj); + + if (nl->has_nontrace) { + err = "not a trace"; + goto out; + } + if (nl->has_junction) { + err = "junction"; + goto out; + } + + out:; + if (err != NULL) { + res->type = FGW_STR; + res->val.cstr = err; + } + else { + res->type = FGW_COORD; + fgw_coord(res) = nl->len; + } + pcb_qry_uninit(&ec); + return 0; +} Index: tags/2.3.0/src_plugins/query/net_len.h =================================================================== --- tags/2.3.0/src_plugins/query/net_len.h (nonexistent) +++ tags/2.3.0/src_plugins/query/net_len.h (revision 33253) @@ -0,0 +1,17 @@ +#include "query_exec.h" + +typedef struct { + vtp0_t objs; + unsigned has_junction:1; + unsigned has_nontrace:1; + pcb_any_obj_t *junction1, *junction2; /* object with a junction on it before and afterthe list */ + rnd_coord_t ex1, ey1, ex2, ey2; /* extend from the first and last object to the junction point */ + rnd_coord_t len; + int num_vias; /* number of functional vias, a.k.a. layer group changes */ +} pcb_qry_netseg_len_t; + +pcb_qry_netseg_len_t *pcb_qry_parent_net_lenseg(pcb_qry_exec_t *ec, pcb_any_obj_t *from); + + +void pcb_qry_lenseg_free_fields(pcb_qry_netseg_len_t *ns); + Index: tags/2.3.0/src_plugins/query/query.c =================================================================== --- tags/2.3.0/src_plugins/query/query.c (nonexistent) +++ tags/2.3.0/src_plugins/query/query.c (revision 33253) @@ -0,0 +1,457 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - common code for the compiled tree and plugin administration */ + +#include "config.h" +#include +#include +#include +#include "data.h" +#include "change.h" +#include +#include "undo.h" +#include +#include +#include +#include +#include "query.h" +#include "query_l.h" +#include + +#define PCB dontuse + +/******** tree helper ********/ + +pcb_any_obj_t pcb_qry_drc_ctrl[PCB_QRY_DRC_invalid]; + +typedef struct { + const char *name; + int has_children; +} pcb_qry_type_tab_t; + +const pcb_qry_type_tab_t type_tab[PCBQ_nodetype_max] = { + {"PCBQ_RULE", 1}, + {"PCBQ_RNAME", 0}, + {"PCBQ_EXPR_PROG", 1}, + {"PCBQ_EXPR", 1}, + {"PCBQ_ASSERT", 1}, + {"PCBQ_ITER_CTX", 0}, + {"PCBQ_OP_THUS", 1}, + {"PCBQ_OP_AND", 1}, + {"PCBQ_OP_OR", 1}, + {"PCBQ_OP_EQ", 1}, + {"PCBQ_OP_NEQ", 1}, + {"PCBQ_OP_GTEQ", 1}, + {"PCBQ_OP_LTEQ", 1}, + {"PCBQ_OP_GT", 1}, + {"PCBQ_OP_LT", 1}, + {"PCBQ_OP_ADD", 1}, + {"PCBQ_OP_SUB", 1}, + {"PCBQ_OP_MUL", 1}, + {"PCBQ_OP_DIV", 1}, + {"PCBQ_OP_MATCH", 1}, + {"PCBQ_OP_NOT", 1}, + {"PCBQ_FIELD", 0}, + {"PCBQ_FIELD_OF", 1}, + {"PCBQ_LISTVAR", 0}, + {"PCBQ_LET", 1}, + {"PCBQ_VAR", 0}, + {"PCBQ_FNAME", 0}, + {"PCBQ_FCALL", 1}, + {"PCBQ_FUNCTION", 1}, + {"PCBQ_RETURN", 1}, + {"PCBQ_ARG", 0}, + {"PCBQ_FLAG", 0}, + {"PCBQ_DATA_COORD", 0}, + {"PCBQ_DATA_DOUBLE", 0}, + {"PCBQ_DATA_STRING", 0}, + {"PCBQ_DATA_REGEX", 0}, + {"PCBQ_DATA_CONST", 0}, + {"PCBQ_DATA_OBJ", 0}, + {"PCBQ_DATA_INVALID", 0}, + {"PCBQ_DATA_LYTC", 0} +}; + +char *pcb_query_sprint_val(pcb_qry_val_t *val) +{ + switch(val->type) { + case PCBQ_VT_VOID: return rnd_strdup(""); + case PCBQ_VT_COORD: return rnd_strdup_printf("%mI=%$mH", val->data.crd, val->data.crd); + case PCBQ_VT_LONG: return rnd_strdup_printf("%ld", val->data.lng, val->data.lng); + case PCBQ_VT_DOUBLE: return rnd_strdup_printf("%f", val->data.dbl); + case PCBQ_VT_STRING: return rnd_strdup_printf("\"%s\"", val->data.str); + case PCBQ_VT_OBJ: return rnd_strdup_printf("", val->data.obj->ID); + case PCBQ_VT_LST: return rnd_strdup(""); + } + return rnd_strdup(""); +} + +const char *pcb_qry_nodetype_name(pcb_qry_nodetype_t ntype) +{ + int type = ntype; + if ((type < 0) || (type >= PCBQ_nodetype_max)) + return ""; + return type_tab[type].name; +} + +int pcb_qry_nodetype_has_children(pcb_qry_nodetype_t ntype) +{ + int type = ntype; + if ((type < 0) || (type >= PCBQ_nodetype_max)) + return 0; + return type_tab[type].has_children; +} + +pcb_qry_node_t *pcb_qry_n_alloc(pcb_qry_nodetype_t ntype) +{ + pcb_qry_node_t *nd = calloc(sizeof(pcb_qry_node_t), 1); + nd->type = ntype; + return nd; +} + +void pcb_qry_n_free(pcb_qry_node_t *nd) +{ + pcb_qry_node_t *ch, *chn; + + switch(nd->type) { + case PCBQ_RNAME: + case PCBQ_FIELD: + case PCBQ_LISTVAR: + case PCBQ_DATA_STRING: + case PCBQ_DATA_CONST: + case PCBQ_DATA_OBJ: + case PCBQ_FNAME: + free((char *)nd->data.str); + break; + + case PCBQ_DATA_REGEX: + free((char *)nd->data.str); + re_se_free(nd->precomp.regex); + break; + + case PCBQ_ITER_CTX: + pcb_qry_iter_free(nd->data.iter_ctx); + break; + + case PCBQ_FLAG: + case PCBQ_DATA_COORD: + case PCBQ_DATA_DOUBLE: + case PCBQ_DATA_INVALID: + case PCBQ_DATA_LYTC: + case PCBQ_VAR: + case PCBQ_ARG: + /* no allocated field */ + break; + + case PCBQ_LET: + case PCBQ_ASSERT: + case PCBQ_RETURN: + case PCBQ_FUNCTION: + if (nd->precomp.it_active != NULL) { + vti0_uninit(nd->precomp.it_active); + free(nd->precomp.it_active); + } + goto free_children; + + case PCBQ_OP_NOT: + case PCBQ_FIELD_OF: + case PCBQ_FCALL: + case PCBQ_OP_THUS: + case PCBQ_OP_AND: + case PCBQ_OP_OR: + case PCBQ_OP_EQ: + case PCBQ_OP_NEQ: + case PCBQ_OP_GTEQ: + case PCBQ_OP_LTEQ: + case PCBQ_OP_GT: + case PCBQ_OP_LT: + case PCBQ_OP_ADD: + case PCBQ_OP_SUB: + case PCBQ_OP_MUL: + case PCBQ_OP_DIV: + case PCBQ_OP_MATCH: + case PCBQ_RULE: + case PCBQ_EXPR_PROG: + case PCBQ_EXPR: + free_children:; + for(ch = nd->data.children; ch != NULL; ch = chn) { + chn = ch->next; + pcb_qry_n_free(ch); + } + break; + + case PCBQ_nodetype_max: break; + } + free(nd); +} + + +pcb_qry_node_t *pcb_qry_n_insert(pcb_qry_node_t *parent, pcb_qry_node_t *ch) +{ + ch->next = parent->data.children; + parent->data.children = ch; + ch->parent = parent; + return parent; +} + +pcb_qry_node_t *pcb_qry_n_append(pcb_qry_node_t *parent, pcb_qry_node_t *ch) +{ + pcb_qry_node_t *n; + + if (parent->data.children != NULL) { + for(n = parent->data.children; n->next != NULL; n = n->next) ; + n->next = ch; + } + else + parent->data.children = ch; + + /* set parent of all nodes */ + for(n = ch; n != NULL; n = n->next) + n->parent = parent; + + return parent; +} + + +static char ind[] = " "; +void pcb_qry_dump_tree_(const char *prefix, int level, pcb_qry_node_t *nd, pcb_query_iter_t *it_ctx) +{ + pcb_qry_node_t *n; + if (level < sizeof(ind)) ind[level] = '\0'; + printf("%s%s%s ", prefix, ind, pcb_qry_nodetype_name(nd->type)); + switch(nd->type) { + case PCBQ_DATA_INVALID:rnd_printf("%s%s invalid (literal)\n", prefix, ind); break; + case PCBQ_DATA_COORD: rnd_printf("%s%s %mI (%$mm)\n", prefix, ind, nd->data.crd, nd->data.crd); break; + case PCBQ_DATA_DOUBLE: rnd_printf("%s%s %f\n", prefix, ind, nd->data.dbl); break; + case PCBQ_DATA_CONST: rnd_printf("%s%s %s\n", prefix, ind, nd->data.str); break; + case PCBQ_DATA_OBJ: rnd_printf("%s%s %s\n", prefix, ind, nd->data.str); break; + case PCBQ_ITER_CTX: rnd_printf("%s%s vars=%d\n", prefix, ind, nd->data.iter_ctx->num_vars); break; + case PCBQ_FLAG: rnd_printf("%s%s %s\n", prefix, ind, nd->precomp.flg->name); break; + case PCBQ_VAR: + rnd_printf("%s%s ", prefix, ind); + if ((it_ctx != NULL) && (nd->data.crd < it_ctx->num_vars)) { + if (it_ctx->vects == NULL) + pcb_qry_iter_init(it_ctx); + printf("%s\n", it_ctx->vn[nd->data.crd]); + } + else + printf("\n", nd->data.crd); + break; + case PCBQ_FNAME: + if (nd->precomp.fnc.bui != NULL) { + const char *name = pcb_qry_fnc_name(nd->precomp.fnc.bui); + if (name == NULL) + rnd_printf("%s%s \n", prefix, ind); + else + rnd_printf("%s%s builtin %s()\n", prefix, ind, name); + } + else + rnd_printf("%s%s user %s()%s\n", prefix, ind, nd->data.str, (nd->precomp.fnc.uf == NULL ? " ERROR: not found" : "")); + break; + case PCBQ_RULE: + rnd_printf("%s%s%s\n", prefix, ind, nd->data.children->next->data.str); + n = nd->data.children->next->next; + if (n != NULL) { + for(; n != NULL; n = n->next) + pcb_qry_dump_tree_(prefix, level+1, n, it_ctx); + } + else + rnd_printf("%s%s\n", prefix, ind); + break; + case PCBQ_FIELD: + case PCBQ_LISTVAR: + case PCBQ_DATA_REGEX: + case PCBQ_DATA_STRING: rnd_printf("%s%s '%s'\n", prefix, ind, nd->data.str); break; + default: + printf("\n"); + if (level < sizeof(ind)) ind[level] = ' '; + for(n = nd->data.children; n != NULL; n = n->next) { + if (n->parent != nd) + printf("#parent# "); + pcb_qry_dump_tree_(prefix, level+1, n, it_ctx); + } + return; + } + if (level < sizeof(ind)) ind[level] = ' '; +} + +pcb_query_iter_t *pcb_qry_find_iter(pcb_qry_node_t *node) +{ + for(; node != NULL;node = node->parent) { + if ((node->type == PCBQ_EXPR_PROG) || (node->type == PCBQ_RULE) || (node->type == PCBQ_FUNCTION)) { + if (node->data.children->type == PCBQ_ITER_CTX) + return node->data.children->data.iter_ctx; + } + } + + return NULL; +} + +void pcb_qry_dump_tree(const char *prefix, pcb_qry_node_t *top) +{ + pcb_query_iter_t *iter_ctx = pcb_qry_find_iter(top); + + if (iter_ctx == NULL) + printf("\n"); + + for(; top != NULL; top = top->next) + pcb_qry_dump_tree_(prefix, 0, top, iter_ctx); +} + +/******** iter admin ********/ +pcb_query_iter_t *pcb_qry_iter_alloc(void) +{ + pcb_query_iter_t *it = calloc(1, sizeof(pcb_query_iter_t)); + htsi_init(&it->names, strhash, strkeyeq); + return it; +} + +void pcb_qry_iter_free(pcb_query_iter_t *it) +{ + htsi_entry_t *e; + for(e = htsi_first(&it->names); e != NULL; e = htsi_next(&it->names, e)) + free(e->key); + htsi_uninit(&it->names); + free(it->vects); + free(it->idx); + free(it->lst); + free(it->vn); + free(it); +} + + +int pcb_qry_iter_var(pcb_query_iter_t *it, const char *varname, int alloc) +{ + htsi_entry_t *e = htsi_getentry(&it->names, varname); + + if (e != NULL) + return e->value; + + if (!alloc) + return -1; + + htsi_set(&it->names, rnd_strdup(varname), it->num_vars); + return it->num_vars++; +} + +void pcb_qry_iter_init(pcb_query_iter_t *it) +{ + htsi_entry_t *e; + + if (it->vn != NULL) + return; + it->vects = calloc(sizeof(vtp0_t *), it->num_vars); + it->idx = calloc(sizeof(rnd_cardinal_t), it->num_vars); + it->lst = calloc(sizeof(pcb_qry_val_t), it->num_vars); + + it->vn = malloc(sizeof(char *) * it->num_vars); + for (e = htsi_first(&it->names); e; e = htsi_next(&it->names, e)) + it->vn[e->value] = e->key; + it->last_obj = NULL; +} + +/******** functions ********/ +static htsp_t *qfnc = NULL; + +static void pcb_qry_fnc_destroy(void) +{ + htsp_entry_t *e; + for(e = htsp_first(qfnc); e != NULL; e = htsp_next(qfnc, e)) + free(e->key); + htsp_free(qfnc); + qfnc = NULL; +} + +int pcb_qry_fnc_reg(const char *name, pcb_qry_fnc_t fnc) +{ + if (qfnc == NULL) + qfnc = htsp_alloc(strhash, strkeyeq); + if (htsp_get(qfnc, name) != NULL) + return -1; + + htsp_set(qfnc, rnd_strdup(name), rnd_cast_f2d((rnd_fptr_t)fnc)); + + return 0; +} + +pcb_qry_fnc_t pcb_qry_fnc_lookup(const char *name) +{ + if (qfnc == NULL) + return NULL; + + return (pcb_qry_fnc_t)rnd_cast_d2f(htsp_get(qfnc, name)); +} + +/* slow linear search: it's only for the dump */ +const char *pcb_qry_fnc_name(pcb_qry_fnc_t fnc) +{ + htsp_entry_t *e; + void *target = rnd_cast_f2d((rnd_fptr_t)fnc); + + if (qfnc == NULL) + return NULL; + + for(e = htsp_first(qfnc); e != NULL; e = htsp_next(qfnc, e)) + if (e->value == target) + return e->key; + return NULL; +} + +/******** parser helper ********/ +void qry_error(void *prog, const char *err) +{ + rnd_trace("qry_error: %s\n", err); +} + +int qry_wrap() +{ + return 1; +} + +/******** plugin helper ********/ +void query_action_reg(const char *cookie); + +static const char *query_cookie = "query plugin"; + +int pplg_check_ver_query(int ver_needed) { return 0; } + +void pplg_uninit_query(void) +{ + rnd_remove_actions_by_cookie(query_cookie); + pcb_qry_fnc_destroy(); + qry_lex_destroy(); +} + +void pcb_qry_basic_fnc_init(void); + +int pplg_init_query(void) +{ + RND_API_CHK_VER; + pcb_qry_basic_fnc_init(); + query_action_reg(query_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/query/query.h =================================================================== --- tags/2.3.0/src_plugins/query/query.h (nonexistent) +++ tags/2.3.0/src_plugins/query/query.h (revision 33253) @@ -0,0 +1,244 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#ifndef PCB_QUERY_H +#define PCB_QUERY_H + +#include +#include +#include +#include +#include "fields_sphash.h" +#include "obj_common.h" +#include "layer.h" +#include "flag_str.h" + +typedef struct pcb_qry_val_s pcb_qry_val_t; +typedef struct pcb_query_iter_s pcb_query_iter_t; +typedef struct pcb_qry_exec_s pcb_qry_exec_t; + +typedef int (*pcb_qry_fnc_t)(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res); + +/* value of an expression */ +typedef enum pcb_qry_valtype_e { + PCBQ_VT_VOID, + PCBQ_VT_OBJ, + PCBQ_VT_LST, + PCBQ_VT_COORD, + PCBQ_VT_LONG, + PCBQ_VT_DOUBLE, + PCBQ_VT_STRING +} pcb_qry_valtype_t; + +typedef struct pcb_qry_node_s pcb_qry_node_t; + +struct pcb_qry_val_s { + pcb_qry_valtype_t type; + union { + pcb_any_obj_t *obj; + vtp0_t lst; + rnd_coord_t crd; + double dbl; + long lng; + const char *str; + struct { + const char *str; + char tmp[4]; + } local_str; + } data; + void *source; /* TODO: for the cache */ +}; + +/* Script parsed into a tree */ +typedef enum { + PCBQ_RULE, + PCBQ_RNAME, + PCBQ_EXPR_PROG, + PCBQ_EXPR, + PCBQ_ASSERT, + PCBQ_ITER_CTX, + + PCBQ_OP_THUS, + PCBQ_OP_AND, + PCBQ_OP_OR, + PCBQ_OP_EQ, + PCBQ_OP_NEQ, + PCBQ_OP_GTEQ, + PCBQ_OP_LTEQ, + PCBQ_OP_GT, + PCBQ_OP_LT, + PCBQ_OP_ADD, + PCBQ_OP_SUB, + PCBQ_OP_MUL, + PCBQ_OP_DIV, + PCBQ_OP_MATCH, + + PCBQ_OP_NOT, + PCBQ_FIELD, + PCBQ_FIELD_OF, + PCBQ_LISTVAR, + PCBQ_LET, + PCBQ_VAR, + PCBQ_FNAME, + PCBQ_FCALL, + PCBQ_FUNCTION, + PCBQ_RETURN, + PCBQ_ARG, + + PCBQ_FLAG, /* leaf */ + + PCBQ_DATA_COORD, /* leaf */ + PCBQ_DATA_DOUBLE, /* leaf */ + PCBQ_DATA_STRING, /* leaf */ + PCBQ_DATA_REGEX, /* leaf */ + PCBQ_DATA_CONST, /* leaf */ + PCBQ_DATA_OBJ, /* leaf */ + PCBQ_DATA_INVALID, /* leaf */ + PCBQ_DATA_LYTC, /* leaf */ + + PCBQ_nodetype_max +} pcb_qry_nodetype_t; + +struct pcb_qry_node_s { + pcb_qry_nodetype_t type; + pcb_qry_node_t *next; /* sibling on this level of the tree (or NULL) */ + pcb_qry_node_t *parent; + union { /* field selection depends on ->type */ + rnd_coord_t crd; + double dbl; + const char *str; + pcb_query_iter_t *iter_ctx; + pcb_qry_node_t *children; /* first child (NULL for a leaf node) */ + struct pcb_qry_lytc_s { + pcb_layer_type_t lyt; + pcb_layer_combining_t lyc; + } lytc; + } data; + union { /* field selection depends on ->type */ + query_fields_keys_t fld; /* field_sphash value from str */ + pcb_qry_val_t result; /* of pure functions and subtrees and constant values converted e.g. to coord */ + re_se_t *regex; + long cnst; /* named constant */ + pcb_any_obj_t *obj; + const pcb_flag_bits_t *flg; + vti0_t *it_active; + struct { /* FCALL's FNAME*/ + pcb_qry_fnc_t bui; /* if not NULL, then data.str is NULL and this is a builtin call; if NULL, this is an user function call to node .uf */ + pcb_qry_node_t *uf; + } fnc; + } precomp; +}; + + +pcb_qry_node_t *pcb_qry_n_alloc(pcb_qry_nodetype_t ntype); +pcb_qry_node_t *pcb_qry_n_insert(pcb_qry_node_t *parent, pcb_qry_node_t *ch); +pcb_qry_node_t *pcb_qry_n_append(pcb_qry_node_t *parent, pcb_qry_node_t *ch); + +void pcb_qry_dump_tree(const char *prefix, pcb_qry_node_t *top); + +void pcb_qry_set_input(const char *script); + +struct pcb_query_iter_s { + htsi_t names; /* name->index hash */ + int num_vars, last_active; + + const char **vn; /* pointers to the hash names so they can be indexed */ + pcb_qry_val_t *lst; + vti0_t *it_active; /* points to a char array of which iterators are active */ + + /* iterator state for each variable - point into the corresponding lst[] */ + vtp0_t **vects; + rnd_cardinal_t *idx; + + pcb_any_obj_t *last_obj; /* last object retrieved by the expression */ +}; + +pcb_query_iter_t *pcb_qry_iter_alloc(void); +void pcb_qry_iter_free(pcb_query_iter_t *it); +int pcb_qry_iter_var(pcb_query_iter_t *it, const char *varname, int alloc); +void pcb_qry_iter_init(pcb_query_iter_t *it); + +void pcb_qry_n_free(pcb_qry_node_t *nd); + +pcb_query_iter_t *pcb_qry_find_iter(pcb_qry_node_t *node); + +char *pcb_query_sprint_val(pcb_qry_val_t *val); + +const char *pcb_qry_nodetype_name(pcb_qry_nodetype_t ntype); +int pcb_qry_nodetype_has_children(pcb_qry_nodetype_t ntype); + +/* functions */ +int pcb_qry_fnc_reg(const char *name, pcb_qry_fnc_t fnc); +pcb_qry_fnc_t pcb_qry_fnc_lookup(const char *name); +const char *pcb_qry_fnc_name(pcb_qry_fnc_t fnc); + +/* parser */ +void qry_error(void *prog, const char *err); + +/* external entry points for convenience */ + +/* Compile and execute a script, calling cb for each object. Returns the number + of evaluation errors or -1 if evaluation couldn't start */ +int pcb_qry_run_script(pcb_qry_exec_t *ec, pcb_board_t *pcb, const char *script, const char *scope, void (*cb)(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current), void *user_ctx); + +/* Compile a script; returns NULL on error, else the caller needs to call + pcb_qry_n_free() on the result to free it after use */ +pcb_qry_node_t *pcb_query_compile(const char *script); + +/* Extract a list of definitions used by the script (by compiling the script); + dst key is the definition name, val is the number of uses. Return value + is total number of definition usage. */ +int pcb_qry_extract_defs(htsi_t *dst, const char *script); + +/*** drc list-reports ***/ + +/* dynamic alloced fake objects that store constants */ + +#define PCB_OBJ_QRY_CONST 0x0100000 +typedef struct pcb_obj_qry_const_s { + PCB_ANY_OBJ_FIELDS; + pcb_qry_val_t val; +} pcb_obj_qry_const_t; + +/* static alloced marker fake objects */ +typedef enum { + PCB_QRY_DRC_GRP1, + PCB_QRY_DRC_GRP2, + PCB_QRY_DRC_EXPECT, + PCB_QRY_DRC_MEASURE, + PCB_QRY_DRC_TEXT, + PCB_QRY_DRC_invalid +} pcb_qry_drc_ctrl_t; + +extern pcb_any_obj_t pcb_qry_drc_ctrl[PCB_QRY_DRC_invalid]; + +#define pcb_qry_drc_ctrl_decode(obj) \ +((((obj) >= &pcb_qry_drc_ctrl[0]) && ((obj) < &pcb_qry_drc_ctrl[PCB_QRY_DRC_invalid])) \ + ? ((obj) - &pcb_qry_drc_ctrl[0]) : PCB_QRY_DRC_invalid) + + + +#endif Index: tags/2.3.0/src_plugins/query/query.pup =================================================================== --- tags/2.3.0/src_plugins/query/query.pup (nonexistent) +++ tags/2.3.0/src_plugins/query/query.pup (revision 33253) @@ -0,0 +1,8 @@ +$class feature +$short query language +$long pcb-rnd query language: execute expressions on objects and rules for the programmed drc. +$state works +$package (core) +default buildin +dep lib_formula +autoload 1 Index: tags/2.3.0/src_plugins/query/query_access.c =================================================================== --- tags/2.3.0/src_plugins/query/query_access.c (nonexistent) +++ tags/2.3.0/src_plugins/query/query_access.c (revision 33253) @@ -0,0 +1,1032 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - access to / extract core data */ + +#include "config.h" +#include +#include +#include "board.h" +#include "data.h" +#include "query_access.h" +#include "query_exec.h" +#include "layer.h" +#include "netlist.h" +#include "fields_sphash.h" +#include "obj_pstk_inlines.h" +#include "obj_subc_parent.h" +#include "net_int.h" + +#define APPEND(_lst_, _obj_) vtp0_append((vtp0_t *)_lst_, _obj_) + +static int list_layer_cb(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, int enter) +{ + if (enter) + APPEND(ctx, layer); + return 0; +} + +static void list_line_cb(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_line_t *line) +{ + APPEND(ctx, line); +} + +static void list_arc_cb(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_arc_t *arc) +{ + APPEND(ctx, arc); +} + +static void list_text_cb(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_text_t *text) +{ + APPEND(ctx, text); +} + +static void list_poly_cb(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_poly_t *poly) +{ + APPEND(ctx, poly); +} + +static void list_pstk_cb(void *ctx, pcb_board_t *pcb, pcb_pstk_t *ps) +{ + APPEND(ctx, ps); +} + +static void list_gfx_cb(void *ctx, pcb_board_t *pcb, pcb_layer_t *layer, pcb_gfx_t *gfx) +{ + APPEND(ctx, gfx); +} + +static int list_subc_cb(void *ctx, pcb_board_t *pcb, pcb_subc_t *subc, int enter); + +static int list_data(void *ctx, pcb_board_t *pcb, pcb_data_t *data, int enter, pcb_objtype_t mask) +{ + if (mask & PCB_OBJ_SUBC) { + PCB_SUBC_LOOP(data); + { + list_subc_cb(ctx, pcb, subc, 1); + } + PCB_END_LOOP; + } + + if (mask & PCB_OBJ_PSTK) { + PCB_PADSTACK_LOOP(data); + { + list_pstk_cb(ctx, pcb, padstack); + } + PCB_END_LOOP; + } + + if (mask & PCB_OBJ_ARC) { + PCB_ARC_ALL_LOOP(data); + { + list_arc_cb(ctx, pcb, layer, arc); + } + PCB_ENDALL_LOOP; + } + + if (mask & PCB_OBJ_GFX) { + PCB_GFX_ALL_LOOP(data); + { + list_gfx_cb(ctx, pcb, layer, gfx); + } + PCB_ENDALL_LOOP; + } + + if (mask & PCB_OBJ_LINE) { + PCB_LINE_ALL_LOOP(data); + { + list_line_cb(ctx, pcb, layer, line); + } + PCB_ENDALL_LOOP; + } + + if (mask & PCB_OBJ_TEXT) { + PCB_TEXT_ALL_LOOP(data); + { + list_text_cb(ctx, pcb, layer, text); + } + PCB_ENDALL_LOOP; + } + + if (mask & PCB_OBJ_POLY) { + PCB_POLY_ALL_LOOP(data); + { + list_poly_cb(ctx, pcb, layer, polygon); + } + PCB_ENDALL_LOOP; + } + + return 0; +} + +static int list_subc_cb(void *ctx, pcb_board_t *pcb, pcb_subc_t *subc, int enter) +{ + if (enter) { + APPEND(ctx, subc); + list_data(ctx, pcb, subc->data, enter, PCB_OBJ_ANY); + } + return 0; +} + +void pcb_qry_list_all_pcb(pcb_qry_val_t *lst, pcb_objtype_t mask) +{ + assert(lst->type == PCBQ_VT_LST); +TODO(": rather do rtree search here to avoid recursion") + pcb_loop_all(PCB, &lst->data.lst, + (mask & PCB_OBJ_LAYER) ? list_layer_cb : NULL, + (mask & PCB_OBJ_LINE) ? list_line_cb : NULL, + (mask & PCB_OBJ_ARC) ? list_arc_cb : NULL, + (mask & PCB_OBJ_TEXT) ? list_text_cb : NULL, + (mask & PCB_OBJ_POLY) ? list_poly_cb : NULL, + (mask & PCB_OBJ_GFX) ? list_gfx_cb : NULL, + (mask & PCB_OBJ_SUBC) ? list_subc_cb : NULL, + (mask & PCB_OBJ_PSTK) ? list_pstk_cb : NULL + ); +} + +void pcb_qry_list_all_data(pcb_qry_val_t *lst, pcb_data_t *data, pcb_objtype_t mask) +{ + list_data(&lst->data.lst, PCB, data, 1, mask); +} + +void pcb_qry_list_all_subc(pcb_qry_val_t *lst, pcb_subc_t *sc, pcb_objtype_t mask) +{ + list_data(&lst->data.lst, PCB, sc->data, 1, mask); +} + + +void pcb_qry_list_free(pcb_qry_val_t *lst_) +{ + vtp0_uninit(&lst_->data.lst); +} + +int pcb_qry_list_cmp(pcb_qry_val_t *lst1, pcb_qry_val_t *lst2) +{ + abort(); +} + +/***********************/ + +/* set dst to point to the idxth field assuming field 0 is fld. Returns -1 + if there are not enough fields */ +#define fld_nth_req(dst, fld, idx) \ +do { \ + int __i__ = idx; \ + pcb_qry_node_t *__f__; \ + for(__f__ = (fld); __i__ > 0; __i__--, __f__ = __f__->next) { \ + if (__f__ == NULL) \ + return -1; \ + } \ + (dst) = __f__; \ +} while(0) + +#define fld_nth_opt(dst, fld, idx) \ +do { \ + int __i__ = idx; \ + pcb_qry_node_t *__f__; \ + for(__f__ = (fld); (__i__ > 0) && (__f__ != NULL); __i__--, __f__ = __f__->next) ; \ + (dst) = __f__; \ +} while(0) + +/* sets const char *s to point to the string data of the idxth field. Returns + -1 if tere are not enooung fields */ +#define fld2str_req(s, fld, idx) \ +do { \ + pcb_qry_node_t *_f_; \ + fld_nth_req(_f_, fld, idx); \ + if ((_f_ == NULL) || (_f_->type != PCBQ_FIELD)) \ + return -1; \ + (s) = _f_->data.str; \ +} while(0) + +/* Same, but doesn't return -1 on missing field but sets s to NULL */ +#define fld2str_opt(s, fld, idx) \ +do { \ + pcb_qry_node_t *_f_; \ + const char *__res__; \ + fld_nth_opt(_f_, fld, idx); \ + if (_f_ != NULL) { \ + if (_f_->type != PCBQ_FIELD) \ + return -1; \ + __res__ = _f_->data.str; \ + } \ + else \ + __res__ = NULL; \ + (s) = __res__; \ +} while(0) + +/* sets query_fields_keys_t h to point to the precomp field of the idxth field. + Returns -1 if tere are not enooung fields */ +#define fld2hash_req(h, fld, idx) \ +do { \ + pcb_qry_node_t *_f_; \ + fld_nth_req(_f_, fld, idx); \ + if ((_f_ == NULL) || (_f_->type != PCBQ_FIELD)) \ + return -1; \ + (h) = _f_->precomp.fld; \ +} while(0) + +/* Same, but doesn't return -1 on missing field but sets s to query_fields_SPHASH_INVALID */ +#define fld2hash_opt(h, fld, idx) \ +do { \ + pcb_qry_node_t *_f_; \ + query_fields_keys_t *__res__; \ + fld_nth_opt(_f_, fld, idx); \ + if (_f_ != NULL) { \ + if (_f_->type != PCBQ_FIELD) \ + return -1; \ + __res__ = _f_->precomp.fld; \ + } \ + else \ + __res__ = query_fields_SPHASH_INVALID; \ + (s) = __res__; \ +} while(0) + +/* convert a layer type description and cache the result (overwriting the string in the field!) */ +#define fld2lyt_req(ec, lyt, lyc, fld, idx) \ +do { \ + pcb_qry_node_t *_f_; \ + fld_nth_req(_f_, fld, idx); \ + if (_f_->type != PCBQ_DATA_LYTC) { \ + const char *_s2_; \ + fld2str_req(_s2_, fld, 1); \ + _f_->data.lytc = field_pstk_lyt(ec, p, _s2_); \ + _f_->type = PCBQ_DATA_LYTC; \ + } \ + lyt = _f_->data.lytc.lyt; \ + lyc = _f_->data.lytc.lyc; \ +} while(0) + +#define COMMON_FIELDS(ec, obj, fh1, fld, res) \ +do { \ + if (fh1 == query_fields_a) { \ + const char *s2; \ + fld2str_req(s2, fld, 1); \ + if (!PCB_OBJ_IS_CLASS(obj->type, PCB_OBJ_CLASS_OBJ)) \ + PCB_QRY_RET_INV(res); \ + PCB_QRY_RET_STR(res, pcb_attribute_get(&obj->Attributes, s2)); \ + } \ + \ + if (fh1 == query_fields_ID) { \ + if (!PCB_OBJ_IS_CLASS(obj->type, PCB_OBJ_CLASS_OBJ)) \ + PCB_QRY_RET_INV(res); \ + PCB_QRY_RET_INT(res, obj->ID); \ + } \ + if (fh1 == query_fields_IID) { \ + if (!PCB_OBJ_IS_CLASS(obj->type, PCB_OBJ_CLASS_OBJ)) \ + PCB_QRY_RET_INV(res); \ + PCB_QRY_RET_INT(res, pcb_obj_iid(obj)); \ + } \ + \ + if ((fh1 == query_fields_bbox) || (fh1 == query_fields_bbox_naked)) { \ + rnd_box_t *bx = (fh1 == query_fields_bbox) ? &(obj)->BoundingBox : &(obj)->bbox_naked; \ + query_fields_keys_t fh2; \ + \ + if (!PCB_OBJ_IS_CLASS(obj->type, PCB_OBJ_CLASS_OBJ)) \ + PCB_QRY_RET_INV(res); \ + \ + fld2hash_req(fh2, fld, 1); \ + switch(fh2) { \ + case query_fields_x1: PCB_QRY_RET_COORD(res, bx->X1); \ + case query_fields_y1: PCB_QRY_RET_COORD(res, bx->Y1); \ + case query_fields_x2: PCB_QRY_RET_COORD(res, bx->X2); \ + case query_fields_y2: PCB_QRY_RET_COORD(res, bx->Y2); \ + case query_fields_width: PCB_QRY_RET_COORD(res, bx->X2 - bx->X1); \ + case query_fields_height: PCB_QRY_RET_COORD(res, bx->Y2 - bx->Y1); \ + default:; \ + } \ + PCB_QRY_RET_INV(res); \ + } \ + \ + if (fh1 == query_fields_type) \ + PCB_QRY_RET_INT(res, obj->type); \ + \ + if (fh1 == query_fields_subc) \ + return field_subc_obj(ec, obj, fld->next, res); \ + \ +} while(0) + +static int field_net(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res); + +#define NETNAME_FIELDS(ec) \ +do { \ + if (fh1 == query_fields_netname) { \ + if (ec != NULL) { \ + pcb_any_obj_t *term = pcb_qry_parent_net_term(ec, obj); \ + pcb_net_t *net; \ + if ((term == NULL) || (term->type != PCB_OBJ_NET_TERM)) \ + PCB_QRY_RET_INV(res); \ + net = term->parent.net; \ + if ((net == NULL) || (net->type != PCB_OBJ_NET)) \ + PCB_QRY_RET_INV(res); \ + PCB_QRY_RET_STR(res, net->name); \ + } \ + else \ + PCB_QRY_RET_INV(res); \ + } \ + if (fh1 == query_fields_net) { \ + if (ec != NULL) { \ + pcb_any_obj_t *term = pcb_qry_parent_net_term(ec, obj); \ + pcb_net_t *net; \ + if ((term == NULL) || (term->type != PCB_OBJ_NET_TERM)) \ + PCB_QRY_RET_INV(res); \ + net = term->parent.net; \ + if ((net == NULL) || (net->type != PCB_OBJ_NET)) \ + PCB_QRY_RET_INV(res); \ + if (fld->next == NULL) \ + PCB_QRY_RET_OBJ(res, (pcb_any_obj_t *)net); \ + else { \ + pcb_qry_node_t *__fn__ = (fld)->next; \ + return field_net(ec, (pcb_any_obj_t *)net, __fn__, res); \ + } \ + PCB_QRY_RET_INV(res); \ + } \ + else \ + PCB_QRY_RET_INV(res); \ + } \ + if (fh1 == query_fields_netseg) { \ + if (ec != NULL) { \ + pcb_any_obj_t *term = pcb_qry_parent_net_term(ec, obj); \ + if (term == NULL) \ + PCB_QRY_RET_INV(res); \ + PCB_QRY_RET_OBJ(res, term); \ + } \ + else \ + PCB_QRY_RET_INV(res); \ + } \ +} while(0) + +static int field_layer(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_layer_t *rl, *l = (pcb_layer_t *)obj; + query_fields_keys_t fh1; + const char *prp; + + if (l->is_bound) { + rl = pcb_layer_get_real(l); + if (rl != NULL) + l = rl; + } + + + fld2hash_req(fh1, fld, 0); + + /* in some cases .type will do the wrong thing at the caller; the escape is .layer.type; drop the redundant .layer */ + if (fh1 == query_fields_layer) { + fld = fld->next; + fld2hash_req(fh1, fld, 0); + } + + if (fh1 == query_fields_a) { + const char *s2; + fld2str_req(s2, fld, 1); + PCB_QRY_RET_STR(res, pcb_attribute_get(&l->Attributes, s2)); + } + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_IID: PCB_QRY_RET_INT(res, pcb_obj_iid((pcb_any_obj_t *)l)); + case query_fields_name: PCB_QRY_RET_STR(res, l->name); + case query_fields_visible: PCB_QRY_RET_INT(res, l->meta.real.vis); + case query_fields_position: PCB_QRY_RET_INT(res, pcb_layer_flags_(l) & PCB_LYT_ANYWHERE); + case query_fields_type: PCB_QRY_RET_INT(res, pcb_layer_flags_(l) & PCB_LYT_ANYTHING); + case query_fields_purpose: + pcb_layer_purpose_(l, &prp); + PCB_QRY_RET_STR(res, prp); + default:; + } + + PCB_QRY_RET_INV(res); +} + +static int field_layergrp(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_layergrp_t *g = (pcb_layergrp_t *)obj; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + + /* in some cases .type will do the wrong thing at the caller; the escape is .layer.type; drop the redundant .layer */ + if (fh1 == query_fields_layergroup) { + fld = fld->next; + fld2hash_req(fh1, fld, 0); + } + + if (fh1 == query_fields_a) { + const char *s2; + fld2str_req(s2, fld, 1); + PCB_QRY_RET_STR(res, pcb_attribute_get(&g->Attributes, s2)); + } + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_IID: PCB_QRY_RET_INT(res, pcb_obj_iid((pcb_any_obj_t *)g)); + case query_fields_name: PCB_QRY_RET_STR(res, g->name); + case query_fields_visible: PCB_QRY_RET_INT(res, g - ec->pcb->LayerGroups.grp); + case query_fields_position: PCB_QRY_RET_INT(res, g->ltype & PCB_LYT_ANYWHERE); + case query_fields_type: PCB_QRY_RET_INT(res, g->ltype & PCB_LYT_ANYTHING); + case query_fields_purpose: PCB_QRY_RET_STR(res, g->purpose); + default:; + } + + PCB_QRY_RET_INV(res); +} + +static int field_layer_from_ptr(pcb_qry_exec_t *ec, pcb_layer_t *l, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + return field_layer(ec, (pcb_any_obj_t *)l, fld, res); +} + +static int field_layergrp_from_ptr(pcb_qry_exec_t *ec, pcb_layergrp_t *l, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + return field_layergrp(ec, (pcb_any_obj_t *)l, fld, res); +} + +static int field_layergrp_from_layer_ptr(pcb_qry_exec_t *ec, pcb_layer_t *l, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_layergrp_t *grp; + + l = pcb_layer_get_real(l); + if (l == NULL) + PCB_QRY_RET_INV(res); + + grp = pcb_get_layergrp(ec->pcb, l->meta.real.grp); + if (grp == NULL) + PCB_QRY_RET_INV(res); + + return field_layergrp(ec, (pcb_any_obj_t *)grp, fld, res); +} + +/* process from .layer */ +static int layer_of_obj(pcb_qry_exec_t *ec, pcb_qry_node_t *fld, pcb_qry_val_t *res, pcb_layer_type_t mask) +{ + rnd_layer_id_t id; + const char *s1; + + if (pcb_layer_list(PCB, mask, &id, 1) != 1) + PCB_QRY_RET_INV(res); + + fld2str_req(s1, fld, 0); + + if (s1 == NULL) { + res->source = NULL; + res->type = PCBQ_VT_OBJ; + res->data.obj = (pcb_any_obj_t *)&(PCB->Data->Layer[id]); + return 0; + } + + return field_layer_from_ptr(ec, PCB->Data->Layer+id, fld, res); +} + +/* process from .layergroup */ +static int layergrp_of_obj(pcb_qry_exec_t *ec, pcb_qry_node_t *fld, pcb_qry_val_t *res, pcb_layer_type_t mask) +{ + rnd_layergrp_id_t id; + const char *s1; + + if (pcb_layergrp_list(PCB, mask, &id, 1) != 1) + PCB_QRY_RET_INV(res); + + fld2str_req(s1, fld, 0); + + if (s1 == NULL) { + res->source = NULL; + res->type = PCBQ_VT_OBJ; + res->data.obj = (pcb_any_obj_t *)&(PCB->LayerGroups.grp[id]); + return 0; + } + + return field_layergrp_from_ptr(ec, PCB->LayerGroups.grp+id, fld, res); +} + +static double pcb_line_len2(pcb_line_t *l) +{ + double x = l->Point1.X - l->Point2.X; + double y = l->Point1.Y - l->Point2.Y; + return x*x + y*y; +} + +static int field_line(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_line_t *l = (pcb_line_t *)obj; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + + if (fh1 == query_fields_a) { + const char *s2; + fld2str_req(s2, fld, 1); + PCB_QRY_RET_STR(res, pcb_attribute_get(&l->Attributes, s2)); + } + + if (fh1 == query_fields_layer) { + if (obj->parent_type == PCB_PARENT_LAYER) + return field_layer_from_ptr(ec, obj->parent.layer, fld->next, res); + else + PCB_QRY_RET_INV(res); + } + else if (fh1 == query_fields_layergroup) { + if (obj->parent_type == PCB_PARENT_LAYER) + return field_layergrp_from_layer_ptr(ec, obj->parent.layer, fld->next, res); + else + PCB_QRY_RET_INV(res); + } + + NETNAME_FIELDS(ec); + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_x1: PCB_QRY_RET_COORD(res, l->Point1.X); + case query_fields_y1: PCB_QRY_RET_COORD(res, l->Point1.Y); + case query_fields_x2: PCB_QRY_RET_COORD(res, l->Point2.X); + case query_fields_y2: PCB_QRY_RET_COORD(res, l->Point2.Y); + case query_fields_thickness: PCB_QRY_RET_COORD(res, l->Thickness); + case query_fields_clearance: PCB_QRY_RET_COORD(res, rnd_round((double)l->Clearance/2.0)); + case query_fields_length: + PCB_QRY_RET_DBL(res, ((rnd_coord_t)rnd_round(sqrt(pcb_line_len2(l))))); + break; + case query_fields_length2: + PCB_QRY_RET_DBL(res, pcb_line_len2(l)); + break; + case query_fields_area: + { + double th = l->Thickness; + double len = rnd_round(sqrt(pcb_line_len2(l))); + if (PCB_FLAG_TEST(PCB_FLAG_SQUARE, l)) + PCB_QRY_RET_DBL(res, (len+th) * th); + else + PCB_QRY_RET_DBL(res, len * th + th*th/4*M_PI); + break; + } + default:; + } + + PCB_QRY_RET_INV(res); +} + +static double pcb_arc_len(pcb_arc_t *a) +{ +TODO(": this breaks for elliptics; see http://tutorial.math.lamar.edu/Classes/CalcII/ArcLength.aspx") + double r = (a->Width + a->Height)/2; + return r * M_PI / 180.0 * a->Delta; +} + +static int field_arc(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_arc_t *a = (pcb_arc_t *)obj; + query_fields_keys_t fh1, fh2; + + fld2hash_req(fh1, fld, 0); + + if (fh1 == query_fields_a) { + const char *s2; + fld2str_req(s2, fld, 1); + PCB_QRY_RET_STR(res, pcb_attribute_get(&a->Attributes, s2)); + } + + if (fh1 == query_fields_angle) { + fld2hash_req(fh2, fld, 1); + switch(fh2) { + case query_fields_start: PCB_QRY_RET_DBL(res, a->StartAngle); + case query_fields_delta: PCB_QRY_RET_DBL(res, a->Delta); + default:; + } + PCB_QRY_RET_INV(res); + } + + if (fh1 == query_fields_layer) { + if (obj->parent_type == PCB_PARENT_LAYER) + return field_layer_from_ptr(ec, obj->parent.layer, fld->next, res); + else + PCB_QRY_RET_INV(res); + } + else if (fh1 == query_fields_layergroup) { + if (obj->parent_type == PCB_PARENT_LAYER) + return field_layergrp_from_layer_ptr(ec, obj->parent.layer, fld->next, res); + else + PCB_QRY_RET_INV(res); + } + + NETNAME_FIELDS(ec); + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_cx: + case query_fields_x: PCB_QRY_RET_COORD(res, a->X); + case query_fields_cy: + case query_fields_y: PCB_QRY_RET_COORD(res, a->Y); + case query_fields_width: PCB_QRY_RET_COORD(res, a->Width); + case query_fields_height: PCB_QRY_RET_COORD(res, a->Height); + case query_fields_thickness: PCB_QRY_RET_COORD(res, a->Thickness); + case query_fields_clearance: PCB_QRY_RET_COORD(res, (rnd_coord_t)rnd_round((double)a->Clearance/2.0)); + case query_fields_length: + PCB_QRY_RET_COORD(res, ((rnd_coord_t)rnd_round(pcb_arc_len(a)))); + break; + case query_fields_length2: + { + double l = pcb_arc_len(a); + PCB_QRY_RET_DBL(res, l*l); + } + break; + case query_fields_area: + { + double th = a->Thickness; + double len = pcb_arc_len(a); + PCB_QRY_RET_DBL(res, len * th + th*th/4*M_PI); /* approx */ + } + break; + default:; + } + + PCB_QRY_RET_INV(res); +} + +static int field_gfx(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_gfx_t *g = (pcb_gfx_t *)obj; + query_fields_keys_t fh1, fh2; + + fld2hash_req(fh1, fld, 0); + + if (fh1 == query_fields_a) { + const char *s2; + fld2str_req(s2, fld, 1); + PCB_QRY_RET_STR(res, pcb_attribute_get(&g->Attributes, s2)); + } + + if (fh1 == query_fields_layer) { + if (obj->parent_type == PCB_PARENT_LAYER) + return field_layer_from_ptr(ec, obj->parent.layer, fld->next, res); + else + PCB_QRY_RET_INV(res); + } + else if (fh1 == query_fields_layergroup) { + if (obj->parent_type == PCB_PARENT_LAYER) + return field_layergrp_from_layer_ptr(ec, obj->parent.layer, fld->next, res); + else + PCB_QRY_RET_INV(res); + } + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_area: PCB_QRY_RET_DBL(res, (double)g->sx * (double)g->sy); break; + case query_fields_sx: PCB_QRY_RET_COORD(res, g->sx); break; + case query_fields_sy: PCB_QRY_RET_COORD(res, g->sy); break; + case query_fields_cx: PCB_QRY_RET_COORD(res, g->cx); break; + case query_fields_cy: PCB_QRY_RET_COORD(res, g->cy); break; + case query_fields_rot: PCB_QRY_RET_DBL(res, g->rot); break; + default:; + } + PCB_QRY_RET_INV(res); +} + +static int field_text(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_text_t *t = (pcb_text_t *)obj; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + + if (fh1 == query_fields_a) { + const char *s2; + fld2str_req(s2, fld, 1); + PCB_QRY_RET_STR(res, pcb_attribute_get(&t->Attributes, s2)); + } + + if (fh1 == query_fields_layer) { + if (obj->parent_type == PCB_PARENT_LAYER) + return field_layer_from_ptr(ec, obj->parent.layer, fld->next, res); + else + PCB_QRY_RET_INV(res); + } + else if (fh1 == query_fields_layergroup) { + if (obj->parent_type == PCB_PARENT_LAYER) + return field_layergrp_from_layer_ptr(ec, obj->parent.layer, fld->next, res); + else + PCB_QRY_RET_INV(res); + } + + NETNAME_FIELDS(ec); + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_x: PCB_QRY_RET_COORD(res, t->X); + case query_fields_y: PCB_QRY_RET_COORD(res, t->Y); + case query_fields_scale: PCB_QRY_RET_INT(res, t->Scale); + case query_fields_scale_x: PCB_QRY_RET_DBL(res, t->scale_x); + case query_fields_scale_y: PCB_QRY_RET_DBL(res, t->scale_y); + case query_fields_rotation: + case query_fields_rot: PCB_QRY_RET_DBL(res, t->rot); + case query_fields_thickness:PCB_QRY_RET_COORD(res, t->thickness); + case query_fields_string: PCB_QRY_RET_STR(res, t->TextString); + case query_fields_area: PCB_QRY_RET_DBL(res, (double)(t->BoundingBox.Y2 - t->BoundingBox.Y1) * (double)(t->BoundingBox.X2 - t->BoundingBox.X1)); + default:; + } + + PCB_QRY_RET_INV(res); +} + +static int field_polygon(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_poly_t *p = (pcb_poly_t *)obj; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + + if (fh1 == query_fields_a) { + const char *s2; + fld2str_req(s2, fld, 1); + PCB_QRY_RET_STR(res, pcb_attribute_get(&p->Attributes, s2)); + } + + if (fh1 == query_fields_layer) { + if (obj->parent_type == PCB_PARENT_LAYER) + return field_layer_from_ptr(ec, obj->parent.layer, fld->next, res); + else + PCB_QRY_RET_INV(res); + } + else if (fh1 == query_fields_layergroup) { + if (obj->parent_type == PCB_PARENT_LAYER) + return field_layergrp_from_layer_ptr(ec, obj->parent.layer, fld->next, res); + else + PCB_QRY_RET_INV(res); + } + + NETNAME_FIELDS(ec); + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_clearance: + if (PCB_FLAG_TEST(PCB_FLAG_CLEARPOLYPOLY, p)) + PCB_QRY_RET_COORD(res, (rnd_coord_t)rnd_round((double)p->Clearance/2.0)); + else + PCB_QRY_RET_INV(res); + break; + case query_fields_points: PCB_QRY_RET_INT(res, p->PointN); + case query_fields_area: + PCB_QRY_RET_DBL(res, p->Clipped->contours->area); + default:; + } + + PCB_QRY_RET_INV(res); +} + +static int field_rat(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ +/* const char *s1, *s2; + + fld2str_req(s1, fld, 0); + fld2str_opt(s2, fld, 1);*/ +TODO("TODO") + PCB_QRY_RET_INV(res); +} + +static struct pcb_qry_lytc_s field_pstk_lyt(pcb_qry_exec_t *ec, pcb_pstk_t *ps, const char *where) +{ + struct pcb_qry_lytc_s lytc; + pcb_layer_typecomb_str2bits(where, &lytc.lyt, &lytc.lyc, 1); + return lytc; +} + +static int field_pstk(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_pstk_t *p = (pcb_pstk_t *)obj; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(p); + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + + if (fh1 == query_fields_a) { + const char *s2; + fld2str_req(s2, fld, 1); + PCB_QRY_RET_STR(res, pcb_attribute_get(&p->Attributes, s2)); + } + + if (fh1 == query_fields_shape) { + pcb_layer_type_t lyt; + pcb_layer_combining_t lyc = 0; + pcb_pstk_shape_t *shp; + + fld2lyt_req(ec, lyt, lyc, fld, 1); + if (lyt == 0) + PCB_QRY_RET_INV(res); + + shp = pcb_pstk_shape(p, lyt, lyc); + if (shp != NULL) { + switch(shp->shape) { + case PCB_PSSH_POLY: PCB_QRY_RET_STR(res, "polygon"); + case PCB_PSSH_LINE: PCB_QRY_RET_STR(res, "line"); + case PCB_PSSH_CIRC: PCB_QRY_RET_STR(res, "circle"); + case PCB_PSSH_HSHADOW: PCB_QRY_RET_STR(res, "hshadow"); + } + } + PCB_QRY_RET_STR(res, ""); + } + + NETNAME_FIELDS(ec); + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_x: PCB_QRY_RET_COORD(res, p->x); + case query_fields_y: PCB_QRY_RET_COORD(res, p->y); + case query_fields_clearance: PCB_QRY_RET_COORD(res, p->Clearance); + case query_fields_rotation: PCB_QRY_RET_DBL(res, p->rot); + case query_fields_xmirror: PCB_QRY_RET_INT(res, p->xmirror); + case query_fields_smirror: PCB_QRY_RET_INT(res, p->smirror); + case query_fields_plated: PCB_QRY_RET_INT(res, PCB_PSTK_PROTO_PLATES(proto)); + case query_fields_hole: PCB_QRY_RET_COORD(res, proto->hdia); + case query_fields_area: PCB_QRY_RET_DBL(res, (double)(p->BoundingBox.Y2 - p->BoundingBox.Y1) * (double)(p->BoundingBox.X2 - p->BoundingBox.X1)); + case query_fields_proto: PCB_QRY_RET_INT(res, p->proto); + default:; + } + + PCB_QRY_RET_INV(res); +} + +static int field_net(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_net_t *net = (pcb_net_t *)obj; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + + if (fh1 == query_fields_a) { + const char *s2; + fld2str_req(s2, fld, 1); + PCB_QRY_RET_STR(res, pcb_attribute_get(&net->Attributes, s2)); + } + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_name: PCB_QRY_RET_STR(res, net->name); + default:; + } + + PCB_QRY_RET_INV(res); + +} + +static int field_subc(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_subc_t *p = (pcb_subc_t *)obj; + query_fields_keys_t fh1; + rnd_coord_t x, y; + double rot; + int on_bottom; + + fld2hash_req(fh1, fld, 0); + if (fh1 == query_fields_a) { + const char *s2; + fld2str_req(s2, fld, 1); + PCB_QRY_RET_STR(res, pcb_attribute_get(&p->Attributes, s2)); + } + + if (fh1 == query_fields_layer) + return layer_of_obj(ec, fld->next, res, PCB_LYT_SILK | (PCB_FLAG_TEST(PCB_FLAG_ONSOLDER, p) ? PCB_LYT_BOTTOM : PCB_LYT_TOP)); + + if (fh1 == query_fields_layergroup) + return layergrp_of_obj(ec, fld->next, res, PCB_LYT_SILK | (PCB_FLAG_TEST(PCB_FLAG_ONSOLDER, p) ? PCB_LYT_BOTTOM : PCB_LYT_TOP)); + + if (fld->next != NULL) + PCB_QRY_RET_INV(res); + + switch(fh1) { + case query_fields_x: pcb_subc_get_origin(p, &x, &y); PCB_QRY_RET_COORD(res, x); + case query_fields_y: pcb_subc_get_origin(p, &x, &y); PCB_QRY_RET_COORD(res, y); + case query_fields_rotation: pcb_subc_get_rotation(p, &rot); PCB_QRY_RET_DBL(res, rot); + case query_fields_side: pcb_subc_get_side(p, &on_bottom); PCB_QRY_RET_SIDE(res, on_bottom); + case query_fields_refdes: PCB_QRY_RET_STR(res, p->refdes); + case query_fields_area: PCB_QRY_RET_DBL(res, (double)(p->BoundingBox.Y2 - p->BoundingBox.Y1) * (double)(p->BoundingBox.X2 - p->BoundingBox.X1)); + default:; + } + PCB_QRY_RET_INV(res); +} + +static int field_subc_obj(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res); + +static int field_subc_from_ptr(pcb_qry_exec_t *ec, pcb_subc_t *s, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_any_obj_t *obj = (pcb_any_obj_t *)s; + query_fields_keys_t fh1; + + fld2hash_req(fh1, fld, 0); + COMMON_FIELDS(ec, obj, fh1, fld, res); + + return field_subc(ec, obj, fld, res); +} + +static int field_subc_obj(pcb_qry_exec_t *ec, pcb_any_obj_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + const char *s1; + pcb_subc_t *parent = pcb_obj_parent_subc(obj); + + /* if parent is not a subc (or not available) evaluate to invalid */ + if (parent == NULL) + PCB_QRY_RET_INV(res); + + /* check subfield, if there's none, return the subcircuit object */ + fld2str_opt(s1, fld, 0); + if (s1 == NULL) { + res->source = NULL; + res->type = PCBQ_VT_OBJ; + res->data.obj = (pcb_any_obj_t *)parent; + return 0; + } + + /* return subfields of the subcircuit */ + return field_subc_from_ptr(ec, parent, fld, res); +} + +/***/ + +static int pcb_qry_obj_flag(pcb_any_obj_t *obj, pcb_qry_node_t *nflg, pcb_qry_val_t *res) +{ + if (obj == NULL) + return -1; + + if ((nflg->precomp.flg->object_types & obj->type) != obj->type) { + /* flag not applicable on object type */ + PCB_QRY_RET_INV(res); + } + PCB_QRY_RET_INT(res, PCB_FLAG_TEST(nflg->precomp.flg->mask, obj)); +} + +int pcb_qry_obj_field(pcb_qry_exec_t *ec, pcb_qry_val_t *objval, pcb_qry_node_t *fld, pcb_qry_val_t *res) +{ + pcb_any_obj_t *obj; + query_fields_keys_t fh1; + + if (objval->type != PCBQ_VT_OBJ) + return -1; + obj = objval->data.obj; + + res->source = NULL; + + if (fld->type == PCBQ_FLAG) + return pcb_qry_obj_flag(obj, fld, res); + + fld2hash_req(fh1, fld, 0); + + COMMON_FIELDS(ec, obj, fh1, fld, res); + + switch(obj->type) { +/* case PCB_OBJ_POINT: return field_point(ec, obj, fld, res);*/ + case PCB_OBJ_LINE: return field_line(ec, obj, fld, res); + case PCB_OBJ_TEXT: return field_text(ec, obj, fld, res); + case PCB_OBJ_POLY: return field_polygon(ec, obj, fld, res); + case PCB_OBJ_ARC: return field_arc(ec, obj, fld, res); + case PCB_OBJ_GFX: return field_gfx(ec, obj, fld, res); + case PCB_OBJ_RAT: return field_rat(ec, obj, fld, res); + case PCB_OBJ_PSTK: return field_pstk(ec, obj, fld, res); + case PCB_OBJ_SUBC: return field_subc(ec, obj, fld, res); + + case PCB_OBJ_NET: return field_net(ec, obj, fld, res); + case PCB_OBJ_LAYER: return field_layer(ec, obj, fld, res); + case PCB_OBJ_LAYERGRP: return field_layergrp(ec, obj, fld, res); + default:; + } + + return -1; +} + Index: tags/2.3.0/src_plugins/query/query_access.h =================================================================== --- tags/2.3.0/src_plugins/query/query_access.h (nonexistent) +++ tags/2.3.0/src_plugins/query/query_access.h (revision 33253) @@ -0,0 +1,46 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - access to / extract core data */ + +#ifndef PCB_QUERY_ACCESS_H +#define PCB_QUERY_ACCESS_H + +#include "query.h" + +/* Append objects with matching type to lst */ +void pcb_qry_list_all_pcb(pcb_qry_val_t *lst, pcb_objtype_t mask); +void pcb_qry_list_all_data(pcb_qry_val_t *lst, pcb_data_t *data, pcb_objtype_t mask); +void pcb_qry_list_all_subc(pcb_qry_val_t *lst, pcb_subc_t *sc, pcb_objtype_t mask); /* only first level objects */ + +int pcb_qry_list_cmp(pcb_qry_val_t *lst1, pcb_qry_val_t *lst2); + +void pcb_qry_list_free(pcb_qry_val_t *lst_); + +int pcb_qry_obj_field(pcb_qry_exec_t *ec, pcb_qry_val_t *obj, pcb_qry_node_t *fld, pcb_qry_val_t *res); + + +#endif Index: tags/2.3.0/src_plugins/query/query_act.c =================================================================== --- tags/2.3.0/src_plugins/query/query_act.c (nonexistent) +++ tags/2.3.0/src_plugins/query/query_act.c (revision 33253) @@ -0,0 +1,631 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - actions */ + +#include +#include +#include +#include "config.h" +#include "conf_core.h" +#include +#include "query.h" +#include "query_y.h" +#include "query_exec.h" +#include "query_access.h" +#include "draw.h" +#include "select.h" +#include "board.h" +#include "idpath.h" +#include "view.h" +#include "actions_pcb.h" +#include "net_len.h" +#include "dlg_search.h" +#include + +static const char pcb_acts_query[] = + "query(dump, expr) - dry run: compile and dump an expression\n" + "query(eval|evalidp, expr) - compile and evaluate an expression and print a list of results on stdout\n" + "query(select|unselect|view, expr) - select or unselect or build a view of objects matching an expression\n" + "query(setflag:flag|unsetflag:flag, expr) - set or unset a named flag on objects matching an expression\n" + "query(append, idplist, expr) - compile and run expr and append the idpath of resulting objects on idplist\n" + ; +static const char pcb_acth_query[] = "Perform various queries on PCB data."; + +typedef struct { + int trues, falses; + unsigned print_idpath:1; +} eval_stat_t; + +static void eval_cb(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current) +{ + char *resv; + eval_stat_t *st = (eval_stat_t *)user_ctx; + int t; + + if (res->type == PCBQ_VT_VOID) { + printf(" \n"); + st->falses++; + return; + } + + if (st->print_idpath && (res->type == PCBQ_VT_OBJ)) { + pcb_idpath_t *idp = pcb_obj2idpath(res->data.obj); + char *idps = pcb_idpath2str(idp, 0); + st->trues++; + printf(" \n", idps); + free(idps); + pcb_idpath_destroy(idp); + return; + } + + if ((res->type != PCBQ_VT_COORD) && (res->type != PCBQ_VT_LONG)) { + st->trues++; + resv = pcb_query_sprint_val(res); + printf(" %s\n", resv); + free(resv); + return; + } + + t = pcb_qry_is_true(res); + printf(" %s", t ? "true" : "false"); + if (t) { + resv = pcb_query_sprint_val(res); + printf(" (%s)\n", resv); + free(resv); + st->trues++; + } + else { + printf("\n"); + st->falses++; + } +} + +typedef struct { + rnd_cardinal_t cnt; + pcb_change_flag_t how; + pcb_flag_values_t what; +} flagop_t; + +static void flagop_cb(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current) +{ + flagop_t *sel = (flagop_t *)user_ctx; + if (!pcb_qry_is_true(res)) + return; + if (PCB_OBJ_IS_CLASS(current->type, PCB_OBJ_CLASS_OBJ)) { + int state_wanted = (sel->how == PCB_CHGFLG_SET); + int state_is = PCB_FLAG_TEST(sel->what, current); + if (state_wanted != state_is) { + PCB_FLAG_CHANGE(sel->how, sel->what, current); + sel->cnt++; + } + } +} + +static void append_cb(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current) +{ + pcb_idpath_list_t *list = user_ctx; + pcb_idpath_t *idp; + + if (!pcb_qry_is_true(res)) + return; + if (!PCB_OBJ_IS_CLASS(current->type, PCB_OBJ_CLASS_OBJ)) + return; + + idp = pcb_obj2idpath(current); + pcb_idpath_list_append(list, idp); +} + +static void view_cb(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current) +{ + pcb_view_list_t *view = user_ctx; + pcb_view_t *v; + + if (!pcb_qry_is_true(res)) + return; + if (!PCB_OBJ_IS_CLASS(current->type, PCB_OBJ_CLASS_OBJ)) + return; + + v = pcb_view_new(&PCB->hidlib, "search result", NULL, NULL); + pcb_view_append_obj(v, 0, current); + pcb_view_set_bbox_by_objs(PCB->Data, v); + pcb_view_list_append(view, v); +} + +pcb_qry_node_t *pcb_query_compile(const char *script) +{ + pcb_qry_node_t *prg = NULL; + + pcb_qry_set_input(script); + qry_parse(&prg); + return prg; +} + +int pcb_qry_run_script(pcb_qry_exec_t *ec, pcb_board_t *pcb, const char *script, const char *scope, void (*cb)(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current), void *user_ctx) +{ + pcb_qry_node_t *prg = NULL; + int res, bufno = -1; /* empty scope means board */ + + if (script == NULL) { + rnd_message(RND_MSG_ERROR, "Compilation error: no script specified.\n"); + return -1; + } + + pcb_qry_set_input(script); + qry_parse(&prg); + + if (prg == NULL) { + rnd_message(RND_MSG_ERROR, "Compilation error.\n"); + return -1; + } + + /* decode scope and set bufno */ + if ((scope != NULL) && (*scope != '\0')) { + if (strcmp(scope, "board") == 0) bufno = -1; + else if (strncmp(scope, "buffer", 6) == 0) { + scope += 6; + if (*scope != '\0') { + char *end; + bufno = strtol(scope, &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "Invalid buffer number: '%s': not an integer\n", scope); + pcb_qry_n_free(prg); + return -1; + } + bufno--; + if ((bufno < 0) || (bufno >= PCB_MAX_BUFFER)) { + rnd_message(RND_MSG_ERROR, "Invalid buffer number: '%d' out of range 1..%d\n", bufno+1, PCB_MAX_BUFFER); + pcb_qry_n_free(prg); + return -1; + } + } + else + bufno = conf_core.editor.buffer_number; + } + else { + rnd_message(RND_MSG_ERROR, "Invalid scope: '%s': must be board or buffer or bufferN\n", scope); + pcb_qry_n_free(prg); + return -1; + } + } + + res = pcb_qry_run(ec, pcb, prg, bufno, cb, user_ctx); + pcb_qry_n_free(prg); + return res; +} + +extern int pcb_qry_fnc_getconf(pcb_qry_exec_t *ectx, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res); +static void pcb_qry_extract_defs_(htsi_t *dst, pcb_qry_node_t *nd, int *total) +{ + if (nd->type == PCBQ_FCALL) { + pcb_qry_node_t *fname = nd->data.children; + if ((fname->type == PCBQ_FNAME) && (fname->precomp.fnc.bui == pcb_qry_fnc_getconf) && (fname->next->type == PCBQ_DATA_STRING)) { + const char *name = fname->next->data.str; + htsi_entry_t *e; + if (strncmp(name, "design/drc/", 11) == 0) { + name += 11; + e = htsi_getentry(dst, name); + if (e == NULL) { + htsi_set(dst, rnd_strdup(name), 0); + e = htsi_getentry(dst, name); + } + e->value++; + (*total)++; + } + } + } + + /* RULE needs special recursion */ + if (nd->type == PCBQ_RULE) { + for(nd = nd->data.children->next->next; nd != NULL; nd = nd->next) + pcb_qry_extract_defs_(dst, nd, total); + return; + } + + /* recurse */ + if (pcb_qry_nodetype_has_children(nd->type)) + for(nd = nd->data.children; nd != NULL; nd = nd->next) + pcb_qry_extract_defs_(dst, nd, total); +} + +int pcb_qry_extract_defs(htsi_t *dst, const char *script) +{ + pcb_qry_node_t *prg = NULL; + int total = 0; + + pcb_qry_set_input(script); + qry_parse(&prg); + if (prg == NULL) + return -1; + + pcb_qry_extract_defs_(dst, prg, &total); + + pcb_qry_n_free(prg); + return total; +} + + +static fgw_error_t pcb_act_query(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd, *arg = NULL, *scope = NULL; + flagop_t sel; + + sel.cnt = 0; + + RND_ACT_CONVARG(1, FGW_STR, query, cmd = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + + if (strcmp(cmd, "version") == 0) { + RND_ACT_IRES(0100); /* 1.0 */ + return 0; + } + + if (strcmp(cmd, "dump") == 0) { + pcb_qry_node_t *prg = NULL; + + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + printf("Script dump: '%s'\n", arg); + pcb_qry_set_input(arg); + qry_parse(&prg); + if (prg != NULL) { + pcb_qry_dump_tree(" ", prg); + pcb_qry_n_free(prg); + RND_ACT_IRES(0); + } + else + RND_ACT_IRES(1); + return 0; + } + + if ((strcmp(cmd, "eval") == 0) || (strcmp(cmd, "evalidp") == 0)) { + int errs; + eval_stat_t st; + + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, query, scope = argv[3].val.str); + + memset(&st, 0, sizeof(st)); + st.print_idpath = (cmd[4] != '\0'); + printf("Script eval: '%s' scope='%s'\n", arg, scope == NULL ? "" : scope); + errs = pcb_qry_run_script(NULL, PCB_ACT_BOARD, arg, scope, eval_cb, &st); + + if (errs < 0) + printf("Failed to run the query\n"); + else + printf("eval statistics: true=%d false=%d errors=%d\n", st.trues, st.falses, errs); + RND_ACT_IRES(0); + return 0; + } + + if ((strcmp(cmd, "select") == 0) || (strncmp(cmd, "setflag:", 8) == 0)) { + sel.how = PCB_CHGFLG_SET; + sel.what = PCB_FLAG_SELECTED; + + if (cmd[3] == 'f') { + pcb_flag_t flg = pcb_strflg_s2f(cmd + 8, NULL, NULL, 0); + sel.what = flg.f; + if (sel.what == 0) { + rnd_message(RND_MSG_ERROR, "Invalid flag '%s'\n", cmd+8); + RND_ACT_IRES(0); + return 0; + } + } + + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, query, scope = argv[3].val.str); + + if (pcb_qry_run_script(NULL, PCB_ACT_BOARD, arg, scope, flagop_cb, &sel) < 0) + printf("Failed to run the query\n"); + if (sel.cnt > 0) { + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + if (RND_HAVE_GUI_ATTR_DLG) + rnd_hid_redraw(PCB); + } + RND_ACT_IRES(0); + return 0; + } + + if ((strcmp(cmd, "unselect") == 0) || (strncmp(cmd, "unsetflag:", 10) == 0)) { + sel.how = PCB_CHGFLG_CLEAR; + sel.what = PCB_FLAG_SELECTED; + + if (cmd[5] == 'f') { + pcb_flag_t flg = pcb_strflg_s2f(cmd + 10, NULL, NULL, 0); + sel.what = flg.f; + if (sel.what == 0) { + rnd_message(RND_MSG_ERROR, "Invalid flag '%s'\n", cmd+8); + RND_ACT_IRES(0); + return 0; + } + } + + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, query, scope = argv[3].val.str); + + if (pcb_qry_run_script(NULL, PCB_ACT_BOARD, arg, scope, flagop_cb, &sel) < 0) + printf("Failed to run the query\n"); + if (sel.cnt > 0) { + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + if (RND_HAVE_GUI_ATTR_DLG) + rnd_hid_redraw(PCB); + } + RND_ACT_IRES(0); + return 0; + } + + if (strcmp(cmd, "append") == 0) { + pcb_idpath_list_t *list; + + RND_ACT_CONVARG(2, FGW_IDPATH_LIST, query, list = fgw_idpath_list(&argv[2])); + RND_ACT_MAY_CONVARG(3, FGW_STR, query, arg = argv[3].val.str); + RND_ACT_MAY_CONVARG(4, FGW_STR, query, scope = argv[4].val.str); + + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[2], RND_PTR_DOMAIN_IDPATH_LIST)) + return FGW_ERR_PTR_DOMAIN; + + if (pcb_qry_run_script(NULL, PCB_ACT_BOARD, arg, scope, append_cb, list) < 0) + RND_ACT_IRES(1); + else + RND_ACT_IRES(0); + return 0; + } + + if (strcmp(cmd, "view") == 0) { + fgw_arg_t args[4], ares; + pcb_view_list_t *view = calloc(sizeof(pcb_view_list_t), 1); + RND_ACT_MAY_CONVARG(2, FGW_STR, query, arg = argv[2].val.str); + if (pcb_qry_run_script(NULL, PCB_ACT_BOARD, arg, scope, view_cb, view) >= 0) { + args[1].type = FGW_STR; args[1].val.str = "advanced search results"; + args[2].type = FGW_STR; args[2].val.str = "search_res"; + fgw_ptr_reg(&rnd_fgw, &args[3], PCB_PTR_DOMAIN_VIEWLIST, FGW_PTR | FGW_STRUCT, view); + rnd_actionv_bin(RND_ACT_HIDLIB, "viewlist", &ares, 4, args); + RND_ACT_IRES(0); + } + else { + free(view); + RND_ACT_IRES(1); + } + return 0; + } + + RND_ACT_FAIL(query); +} + +static const char *PTR_DOMAIN_PCFIELD = "ptr_domain_query_precompiled_field"; + +static pcb_qry_node_t *field_comp(const char *fields) +{ + char fname[64], *fno; + const char *s; + int len = 1, flen = 0, idx = 0, quote = 0; + pcb_qry_node_t *res; + + if (*fields == '.') fields++; + if (*fields == '\0') + return NULL; + + for(s = fields; *s != '\0'; s++) { + if (*s == '.') { + len++; + if (len > 16) + return NULL; /* too many fields chained */ + if (flen >= sizeof(fname)) + return NULL; /* field name segment too long */ + flen = 0; + } + else + flen++; + } + + res = calloc(sizeof(pcb_qry_node_t), len); + fno = fname; + for(s = fields;; s++) { + if ((quote == 0) && ((*s == '.') || (*s == '\0'))) { + *fno = '\0'; + if (idx > 0) + res[idx-1].next = &res[idx]; + res[idx].type = PCBQ_FIELD; + res[idx].precomp.fld = query_fields_sphash(fname); +/*rnd_trace("[%d/%d] '%s' -> %d\n", idx, len, fname, res[idx].precomp.fld);*/ + if (res[idx].precomp.fld < 0) /* if compilation failed, this will need to be evaluated run-time, save as string */ + res[idx].data.str = rnd_strdup(fname); + fno = fname; + if (*s == '\0') + break; + idx++; + if (s[1] == '\"') { + quote = s[1]; + s++; + } + } + else { + if (*s == quote) + quote = 0; + else + *fno++ = *s; + } + } + + return res; +} + +static void field_free(pcb_qry_node_t *fld) +{ + pcb_qry_node_t *f; + for(f = fld; f != NULL; f = f->next) + if (f->data.str != NULL) + free((char *)f->data.str); + free(fld); +} + + +static void val2fgw(fgw_arg_t *dst, pcb_qry_val_t *src) +{ + switch(src->type) { + case PCBQ_VT_COORD: + dst->type = FGW_COORD_; + fgw_coord(dst) = src->data.crd; + break; + case PCBQ_VT_LONG: + dst->type = FGW_LONG; + dst->val.nat_long = src->data.lng; + break; + case PCBQ_VT_DOUBLE: + dst->type = FGW_DOUBLE; + dst->val.nat_double = src->data.dbl; + break; + case PCBQ_VT_STRING: + if (src->data.str != NULL) { + dst->type = FGW_STR | FGW_DYN; + dst->val.str = rnd_strdup(src->data.str); + } + else { + dst->type = FGW_PTR; + dst->val.ptr_void = NULL; + } + break; + case PCBQ_VT_VOID: + case PCBQ_VT_OBJ: + case PCBQ_VT_LST: + default:; + break; + } +} + +static const char pcb_acts_QueryObj[] = "QueryObj(idpath, [.fieldname|fieldID])"; +static const char pcb_acth_QueryObj[] = "Return the value of a field of an object, addressed by the object's idpath and the field's name or precompiled ID. Returns NIL on error."; +static fgw_error_t pcb_act_QueryObj(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_idpath_t *idp; + pcb_qry_node_t *fld = NULL; + pcb_qry_val_t obj; + pcb_qry_val_t val; + int free_fld = 0; + + RND_ACT_CONVARG(1, FGW_IDPATH, QueryObj, idp = fgw_idpath(&argv[1])); + + if ((argv[2].type & FGW_STR) == FGW_STR) { + const char *field; + RND_ACT_CONVARG(2, FGW_STR, QueryObj, field = argv[2].val.str); + if (field == NULL) + goto err; + if (*field != '.') + goto id; + fld = field_comp(field); + free_fld = 1; + } + else if ((argv[2].type & FGW_PTR) == FGW_PTR) { + id:; + RND_ACT_CONVARG(2, FGW_PTR, QueryObj, fld = argv[2].val.ptr_void); + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[2], PTR_DOMAIN_PCFIELD)) + return FGW_ERR_PTR_DOMAIN; + } + + if ((fld == NULL) || (!fgw_ptr_in_domain(&rnd_fgw, &argv[1], RND_PTR_DOMAIN_IDPATH))) { + if (free_fld) + field_free(fld); + return FGW_ERR_PTR_DOMAIN; + } + + obj.type = PCBQ_VT_OBJ; + obj.data.obj = pcb_idpath2obj_in(PCB->Data, idp); + if (obj.data.obj == NULL) + goto err; + + { + int ret; + pcb_qry_exec_t ec; + + pcb_qry_init(&ec, PCB, NULL, -1); + ret = pcb_qry_obj_field(NULL, &obj, fld, &val); + pcb_qry_uninit(&ec); + + if (ret != 0) + goto err; + } + + if (free_fld) + field_free(fld); + + val2fgw(res, &val); + return 0; + + err:; + if (free_fld) + field_free(fld); + res->type = FGW_PTR; + res->val.ptr_void = NULL; + return 0; +} + +static const char pcb_acts_QueryCompileField[] = + "QueryCompileField(compile, fieldname)\n" + "QueryCompileField(free, fieldID)"; +static const char pcb_acth_QueryCompileField[] = "With \"compile\": precompiles textual field name to field ID; with \"free\": frees the memory allocated for a previously precompiled fieldID."; +static fgw_error_t pcb_act_QueryCompileField(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd, *fname; + pcb_qry_node_t *fld; + + RND_ACT_CONVARG(1, FGW_STR, QueryCompileField, cmd = argv[1].val.str); + switch(*cmd) { + case 'c': /* compile */ + RND_ACT_CONVARG(2, FGW_STR, QueryCompileField, fname = argv[2].val.str); + fld = field_comp(fname); + fgw_ptr_reg(&rnd_fgw, res, PTR_DOMAIN_PCFIELD, FGW_PTR | FGW_STRUCT, fld); + return 0; + case 'f': /* free */ + if (!fgw_ptr_in_domain(&rnd_fgw, &argv[2], PTR_DOMAIN_PCFIELD)) + return FGW_ERR_PTR_DOMAIN; + RND_ACT_CONVARG(2, FGW_PTR, QueryCompileField, fld = argv[2].val.ptr_void); + fgw_ptr_unreg(&rnd_fgw, &argv[2], PTR_DOMAIN_PCFIELD); + field_free(fld); + break; + default: + return FGW_ERR_ARG_CONV; + } + res->type = FGW_PTR; + res->val.ptr_void = fld; + return 0; +} + +/* in net_len.c */ +extern const char pcb_acts_QueryCalcNetLen[]; +extern const char pcb_acth_QueryCalcNetLen[]; +extern fgw_error_t pcb_act_QueryCalcNetLen(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +rnd_action_t query_action_list[] = { + {"query", pcb_act_query, pcb_acth_query, pcb_acts_query}, + {"QueryObj", pcb_act_QueryObj, pcb_acth_QueryObj, pcb_acts_QueryObj}, + {"QueryCompileField", pcb_act_QueryCompileField, pcb_acth_QueryCompileField, pcb_acts_QueryCompileField}, + {"QueryCalcNetLen", pcb_act_QueryCalcNetLen, pcb_acth_QueryCalcNetLen, pcb_acts_QueryCalcNetLen}, + {"SearchDialog", pcb_act_SearchDialog, pcb_acth_SearchDialog, pcb_acts_SearchDialog} +}; + +void query_action_reg(const char *cookie) +{ + RND_REGISTER_ACTIONS(query_action_list, cookie) +} Index: tags/2.3.0/src_plugins/query/query_exec.c =================================================================== --- tags/2.3.0/src_plugins/query/query_exec.c (nonexistent) +++ tags/2.3.0/src_plugins/query/query_exec.c (revision 33253) @@ -0,0 +1,889 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - execution */ + +#include +#include "config.h" +#include "data.h" +#include "query.h" +#include "query_exec.h" +#include "query_access.h" +#include "net_len.h" +#include + +#define PCB dontuse + +void pcb_qry_setup(pcb_qry_exec_t *ctx, pcb_board_t *pcb, pcb_qry_node_t *root) +{ + ctx->pcb = pcb; + ctx->root = root; + ctx->iter = NULL; +} + +void pcb_qry_init(pcb_qry_exec_t *ctx, pcb_board_t *pcb, pcb_qry_node_t *root, int bufno) +{ + memset(ctx, 0, sizeof(pcb_qry_exec_t)); + ctx->all.type = PCBQ_VT_LST; + if (bufno == -1) + pcb_qry_list_all_pcb(&ctx->all, PCB_OBJ_ANY & (~PCB_OBJ_LAYER)); + else + pcb_qry_list_all_data(&ctx->all, pcb_buffers[bufno].Data, PCB_OBJ_ANY & (~PCB_OBJ_LAYER)); + + pcb_qry_setup(ctx, pcb, root); +} + +void pcb_qry_autofree(pcb_qry_exec_t *ctx) +{ + long l; + + if (ctx->iter != NULL) { + for(l = 0; l < ctx->iter->num_vars; l++) { + if (ctx->iter->lst[l].data.lst.array != ctx->all.data.lst.array) /* some lists are just alias to ->all, do not free them */ + pcb_qry_list_free(&ctx->iter->lst[l]); + } + } + + for(l = 0; l < ctx->autofree.used; l++) + free(ctx->autofree.array[l]); + vtp0_uninit(&ctx->autofree); + + ctx->iter = NULL; /* no need to free the iterator: ctx->root free handled that as it was allocated in one of the nodes */ +} + +extern void pcb_qry_uninit_layer_setup(pcb_qry_exec_t *ectx); + +void pcb_qry_uninit(pcb_qry_exec_t *ctx) +{ + pcb_qry_autofree(ctx); + + pcb_qry_list_free(&ctx->all); + + if (ctx->obj2netterm_inited) + htpp_uninit(&ctx->obj2netterm); + + if (ctx->obj2lenseg_inited) { + long n; + htpp_uninit(&ctx->obj2lenseg); + htpi_uninit(&ctx->obj2lenseg_cc); + for(n = 0; n < ctx->obj2lenseg_free.used; n++) { + pcb_qry_netseg_len_t *ns = ctx->obj2lenseg_free.array[n]; + pcb_qry_lenseg_free_fields(ns); + free(ns); + } + vtp0_uninit(&ctx->obj2lenseg_free); + } + + vtp0_uninit(&ctx->tmplst); + pcb_qry_uninit_layer_setup(ctx); +} + +static void val_free_fields(pcb_qry_val_t *val) +{ + switch(val->type) { + case PCBQ_VT_LST: + pcb_qry_list_free(val); + break; + case PCBQ_VT_STRING: + TODO("decide if strings are strdup'd; action return may need to, ther est not; maybe introduce DSTR for dynamic string?"); + break; + case PCBQ_VT_VOID: + case PCBQ_VT_OBJ: + case PCBQ_VT_COORD: + case PCBQ_VT_LONG: + case PCBQ_VT_DOUBLE: + break; + } +} + +static int pcb_qry_run_(pcb_qry_exec_t *ec, pcb_qry_node_t *prg, pcb_qry_val_t *res, int it_reset, int eval_list, void (*cb)(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current), void *user_ctx) +{ + pcb_qry_val_t restmp; + int errs = 0, keep_res = 1; + + if (it_reset && (pcb_qry_it_reset(ec, prg) != 0)) + return -1; + + if (res == NULL) { + res = &restmp; + keep_res = 0; + } + res->type = PCBQ_VT_VOID; + + do { + val_free_fields(res); + if ((pcb_qry_eval(ec, prg, res, cb, user_ctx) == 0) && (cb != NULL)) { + if ((eval_list) && (res->type == PCBQ_VT_LST)) { + long n; + + /* special case: result is a list, need to return each object so 'let' gets it */ + for(n = 0; n < res->data.lst.used; n++) + cb(user_ctx, res, res->data.lst.array[n]); + } + else if (ec->iter->last_obj != NULL) { + cb(user_ctx, res, ec->iter->last_obj); + } + } + else + errs++; + } while(pcb_qry_it_next(ec)); + if (!keep_res) + val_free_fields(res); + return errs; +} + + +typedef struct { + pcb_qry_exec_t *ctx; + vtp0_t *vt; +} let_ctx_t; + +static void let_cb(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current) +{ + let_ctx_t *lctx = user_ctx; + + if (res->type == PCBQ_VT_OBJ) /* result overwrites last checked node */ + current = res->data.obj; + + if (pcb_qry_is_true(res)) + vtp0_append(lctx->vt, current); +} + +static int pcb_qry_it_reset_(pcb_qry_exec_t *ctx); +static void pcb_qry_let(pcb_qry_exec_t *ctx, pcb_qry_node_t *node) +{ + let_ctx_t lctx; + int vi = node->data.children->data.crd; + pcb_qry_node_t *expr = node->data.children->next; + + lctx.ctx = ctx; + pcb_qry_it_reset(ctx, node); + + /* set up the list */ + ctx->iter->lst[vi].type = PCBQ_VT_LST; + lctx.vt = &ctx->iter->lst[vi].data.lst; + + /* evaluate 'let' the expression, filling up the list */ + pcb_qry_it_reset_(lctx.ctx); + ctx->iter->it_active = node->precomp.it_active; + pcb_qry_run_(lctx.ctx, expr, NULL, 0, 1,let_cb, &lctx); + ctx->iter->it_active = NULL; + + /* initialize the iterator */ + ctx->iter->vects[vi] = &ctx->iter->lst[vi].data.lst; + ctx->iter->idx[vi] = 0; +} + +/* Run one node; increment ret by the number of hits and return that, or -1 on error. + If res is not NULL the value of PCBQ_RETURN is loaded in it. + Call cb/user_ctx when assert is true. */ +static int pcb_qry_run_one(pcb_qry_exec_t *ec, pcb_qry_node_t *prg, int ret, pcb_qry_val_t *res, void (*cb)(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current), void *user_ctx) +{ + int r; + pcb_qry_node_t *start; + int is_ret = 0; + + if (res != NULL) + res->type = PCBQ_VT_VOID; + + if (prg->type == PCBQ_FUNCTION) { + if (ec->trace) + rnd_message(RND_MSG_INFO, "query: entering user function %s\n", prg->data.children->next->data.str); + start = prg->data.children->next->next; + while(start->type == PCBQ_ARG) + start = start->next; + goto run_all; + } + else if (prg->type == PCBQ_RULE) { + pcb_qry_node_t *n; + start = prg->data.children->next->next; + + /* execute 'let' statements first */ + run_all:; + for(n = start; n != NULL; n = n->next) { + if (n->type == PCBQ_LET) + pcb_qry_let(ec, n); + if (n->type == PCBQ_RETURN) + break; + } + + for(n = start; n != NULL; n = n->next) { + if (ec->trace) + rnd_message(RND_MSG_INFO, "query: %p %s\n", n, pcb_qry_nodetype_name(n->type)); + switch(n->type) { + case PCBQ_LET: break; + case PCBQ_RETURN: + is_ret = 1; + case PCBQ_ASSERT: + ec->root = n; + if (ec->iter != NULL) + ec->iter->it_active = n->precomp.it_active; + r = pcb_qry_run_(ec, n->data.children, (is_ret ? res : NULL), 1, 0, (n->type == PCBQ_RETURN ? NULL : cb), user_ctx); + if (ec->iter != NULL) + ec->iter->it_active = NULL; + if (r < 0) + ret = r; + else if (ret >= 0) + ret += r; + ec->root = NULL; + break; + default:; + } + if (is_ret) + break; + } + } + else + return -1; + + return ret; +} + +static int pcb_qry_run_all(pcb_qry_exec_t *ec, pcb_qry_node_t *prg, int ret, void (*cb)(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current), void *user_ctx) +{ + while(prg != NULL) { /* execute a list of rules */ + if (prg->type != PCBQ_FUNCTION) + ret = pcb_qry_run_one(ec, prg, ret, NULL, cb, user_ctx); + prg = prg->next; + } + return ret; +} + +int pcb_qry_run(pcb_qry_exec_t *ec, pcb_board_t *pcb, pcb_qry_node_t *prg, int bufno, void (*cb)(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current), void *user_ctx) +{ + int ret = 0, ec_uninit = 0; + pcb_qry_exec_t ec_local; + + if (ec == NULL) { + ec = &ec_local; + ec_uninit = 1; + pcb_qry_init(ec, pcb, prg, bufno); + } + else { + if (ec->pcb != pcb) + return -1; + pcb_qry_setup(ec, pcb, prg); + } + + if (prg->type == PCBQ_EXPR_PROG) + ret = pcb_qry_run_(ec, prg, NULL, 1, 0, cb, user_ctx); + else + ret = pcb_qry_run_all(ec, prg, ret, cb, user_ctx); + + if (ec_uninit) + pcb_qry_uninit(&ec_local); + else + pcb_qry_autofree(ec); + return ret; +} + +static int qry_exec_user_func(pcb_qry_exec_t *ectx, pcb_qry_node_t *fdef, int argc, pcb_qry_val_t *argv, pcb_qry_val_t *res, void (*cb)(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current), void *user_ctx) +{ + pcb_qry_exec_t fctx; + int n, ret, alloced[PCB_QRY_MAX_FUNC_ARGS]; + pcb_qry_node_t *fname; + + if (argc > PCB_QRY_MAX_FUNC_ARGS) + return -1; + + if (fdef == NULL) { + rnd_message(RND_MSG_ERROR, "call to unknown/undefined function\n"); + return -1; + } + + fctx = *ectx; + + assert(fdef->type == PCBQ_FUNCTION); + fname = fdef->data.children; + assert(fname->type == PCBQ_ITER_CTX); + fctx.iter = fname->data.iter_ctx; + fname = fname->next; /* skip iter */ + + pcb_qry_iter_init(fctx.iter); + + /* accept only objects and lists as argument */ + for(n = 0; n < argc; n++) { + if ((argv[n].type != PCBQ_VT_OBJ) && (argv[n].type != PCBQ_VT_LST)) + return -1; + } + + for(n = 0; n < argc; n++) { + if (argv[n].type == PCBQ_VT_OBJ) { + fctx.iter->lst[n].type = PCBQ_VT_LST; + vtp0_init(&fctx.iter->lst[n].data.lst); + vtp0_append(&fctx.iter->lst[n].data.lst, argv[n].data.obj); + alloced[n] = 1; + } + else { + fctx.iter->lst[n] = argv[n]; + alloced[n] = 0; + } + fctx.iter->vects[n] = &fctx.iter->lst[n].data.lst; + fctx.iter->idx[n] = 0; + } + + /* reset lists from the previous calls */ + for(; n < fctx.iter->num_vars; n++) { + vtp0_t *v = fctx.iter->vects[n]; + if (v != NULL) + v->used = 0; + } + + ret = pcb_qry_run_one(&fctx, fdef, 0, res, cb, user_ctx); + + for(n = 0; n < argc; n++) { + if (alloced[n]) + vtp0_uninit(&fctx.iter->lst[n].data.lst); + } + + return ret; +} + +/* load unary operand to o1 */ +#define UNOP() \ +do { \ + if ((node->data.children == NULL) || (node->data.children->next != NULL)) \ + return -1; \ + if (pcb_qry_eval(ctx, node->data.children, &o1, cb, user_ctx) < 0) \ + return -1; \ +} while(0) + +/* load 1st binary operand to o1 */ +#define BINOPS1() \ +do { \ + if ((node->data.children == NULL) || (node->data.children->next == NULL) || (node->data.children->next->next != NULL)) \ + return -1; \ + if (pcb_qry_eval(ctx, node->data.children, &o1, cb, user_ctx) < 0) \ + return -1; \ +} while(0) + +/* load 2nd binary operand to o2 */ +#define BINOPS2() \ +do { \ + if (pcb_qry_eval(ctx, node->data.children->next, &o2, cb, user_ctx) < 0) \ + return -1; \ +} while(0) + +/* load binary operands to o1 and o2 */ +#define BINOPS() \ +do { \ + BINOPS1(); \ + BINOPS2(); \ +} while(0) + +static int promote(pcb_qry_val_t *a, pcb_qry_val_t *b) +{ + if ((a->type == PCBQ_VT_VOID) || (b->type == PCBQ_VT_VOID)) { + a->type = b->type = PCBQ_VT_VOID; + return 0; + } + if (a->type == b->type) + return 0; + switch(a->type) { + case PCBQ_VT_OBJ: return -1; + case PCBQ_VT_LST: return -1; + case PCBQ_VT_COORD: + if (b->type == PCBQ_VT_DOUBLE) PCB_QRY_RET_DBL(a, a->data.crd); + if (b->type == PCBQ_VT_LONG) PCB_QRY_RET_COORD(b, b->data.lng); + return -1; + case PCBQ_VT_LONG: + if (b->type == PCBQ_VT_DOUBLE) PCB_QRY_RET_DBL(a, a->data.lng); + if (b->type == PCBQ_VT_COORD) PCB_QRY_RET_COORD(a, a->data.lng); + return -1; + case PCBQ_VT_DOUBLE: + if (b->type == PCBQ_VT_COORD) PCB_QRY_RET_DBL(b, b->data.crd); + if (b->type == PCBQ_VT_LONG) PCB_QRY_RET_DBL(b, b->data.lng); + return -1; + case PCBQ_VT_STRING: + case PCBQ_VT_VOID: + return -1; + } + return -1; +} + +static const char *op2str(char *buff, int buff_size, pcb_qry_val_t *val) +{ + switch(val->type) { + case PCBQ_VT_COORD: + rnd_snprintf(buff, buff_size, "%mI", val->data.crd); + return buff; + case PCBQ_VT_LONG: + rnd_snprintf(buff, buff_size, "%ld", val->data.lng); + return buff; + case PCBQ_VT_DOUBLE: + rnd_snprintf(buff, buff_size, "%f", val->data.crd); + return buff; + case PCBQ_VT_STRING: + return val->data.str; + case PCBQ_VT_VOID: + case PCBQ_VT_OBJ: + case PCBQ_VT_LST: return NULL; + } + return NULL; +} + +int pcb_qry_is_true(pcb_qry_val_t *val) +{ + switch(val->type) { + case PCBQ_VT_VOID: return 0; + case PCBQ_VT_OBJ: return val->data.obj->type != PCB_OBJ_VOID; + case PCBQ_VT_LST: return vtp0_len(&val->data.lst) > 0; + case PCBQ_VT_COORD: return val->data.crd; + case PCBQ_VT_LONG: return val->data.lng; + case PCBQ_VT_DOUBLE: return val->data.dbl; + case PCBQ_VT_STRING: return (val->data.str != NULL) && (*val->data.str != '\0'); + } + return 0; +} + +static void setup_iter_list(pcb_qry_exec_t *ctx, int var_id, pcb_qry_val_t *listval) +{ + ctx->iter->lst[var_id] = *listval; + assert(listval->type == PCBQ_VT_LST); + + ctx->iter->vects[var_id] = &listval->data.lst; + ctx->iter->idx[var_id] = 0; +} + +static int pcb_qry_it_active(pcb_query_iter_t *iter, int i) +{ + if (iter->it_active == NULL) return 1; /* no activity map: all iterators are active */ + if (i >= iter->it_active->used) return 0; + return iter->it_active->array[i]; +} + +static int pcb_qry_it_reset_(pcb_qry_exec_t *ctx) +{ + int n; + + pcb_qry_iter_init(ctx->iter); + for(n = 0; n < ctx->iter->num_vars; n++) { + if (strcmp(ctx->iter->vn[n], "@") == 0) { + setup_iter_list(ctx, n, &ctx->all); + ctx->iter->last_obj = NULL; + break; + } + } + + ctx->iter->last_active = -1; + for(n = 0; n < ctx->iter->num_vars; n++) + if ((ctx->iter->vects[n] != NULL) && pcb_qry_it_active(ctx->iter, n)) + ctx->iter->last_active = n; + + return 0; +} + +int pcb_qry_it_reset(pcb_qry_exec_t *ctx, pcb_qry_node_t *node) +{ + ctx->iter = pcb_qry_find_iter(node); + if (ctx->iter == NULL) + return -1; + + return pcb_qry_it_reset_(ctx); +} + + +#define PROGRESS_CB(ctx, at, total, cancel) \ +do { \ + time_t now; \ + cancel = 0; \ + if (ctx->progress_cb == NULL) break; \ + now = time(NULL); \ + if (ctx->last_prog_cb == 0) \ + ctx->last_prog_cb = now; \ + else if (now > ctx->last_prog_cb) { \ + ctx->last_prog_cb = now; \ + cancel = ctx->progress_cb(ctx, at, total); \ + } \ +} while(0) + +int pcb_qry_it_next(pcb_qry_exec_t *ctx) +{ + int i; + for(i = 0; i < ctx->iter->num_vars; i++) { + if ((ctx->iter->vects[i] != NULL) && pcb_qry_it_active(ctx->iter, i)) { + long ilen = vtp0_len(ctx->iter->vects[i]); + long at = ++ctx->iter->idx[i]; + if (at < ilen) { + if (i == ctx->iter->last_active) { + int cancel; + PROGRESS_CB(ctx, at, ilen, cancel); + if (cancel) + return 0; + } + return 1; + } + } + ctx->iter->idx[i] = 0; + } + return 0; +} + + +/* load s1 and s2 from o1 and o2, convert empty string to NULL */ +#define load_strings_null() \ +do { \ + s1 = o1.data.str; \ + s2 = o2.data.str; \ + if ((s1 != NULL) && (*s1 == '\0')) s1 = NULL; \ + if ((s2 != NULL) && (*s2 == '\0')) s2 = NULL; \ +} while(0) + +static char *pcb_qry_empty = ""; + +/* load s1 and s2 from o1 and o2, convert NULL to empty string */ +#define load_strings_empty() \ +do { \ + s1 = o1.data.str; \ + s2 = o2.data.str; \ + if (s1 == NULL) s1 = pcb_qry_empty; \ + if (s2 == NULL) s2 = pcb_qry_empty; \ +} while(0) + +int pcb_qry_eval(pcb_qry_exec_t *ctx, pcb_qry_node_t *node, pcb_qry_val_t *res, void (*cb)(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current), void *user_ctx) +{ + pcb_qry_val_t o1, o2; + pcb_any_obj_t **tmp; + const char *s1, *s2; + + switch(node->type) { + case PCBQ_EXPR: + return pcb_qry_eval(ctx, node->data.children, res, cb, user_ctx); + + case PCBQ_EXPR_PROG: { + pcb_qry_node_t *itn, *exprn; + itn = node->data.children; + if (itn == NULL) + return -1; + exprn = itn->next; + if (exprn == NULL) + return -1; + if (itn->type != PCBQ_ITER_CTX) + return -1; + if (ctx->iter != itn->data.iter_ctx) + return -1; + return pcb_qry_eval(ctx, exprn, res, cb, user_ctx); + } + + + case PCBQ_OP_AND: /* lazy */ + BINOPS1(); + if (!pcb_qry_is_true(&o1)) + PCB_QRY_RET_INT(res, 0); + BINOPS2(); + if (!pcb_qry_is_true(&o2)) + PCB_QRY_RET_INT(res, 0); + PCB_QRY_RET_INT(res, 1); + + case PCBQ_OP_THUS: /* lazy */ + BINOPS1(); + if (!pcb_qry_is_true(&o1)) + PCB_QRY_RET_INV(res); + BINOPS2(); + *res = o2; + return 0; + + case PCBQ_OP_OR: /* lazy */ + BINOPS1(); + if (pcb_qry_is_true(&o1)) + PCB_QRY_RET_INT(res, 1); + BINOPS2(); + if (pcb_qry_is_true(&o2)) + PCB_QRY_RET_INT(res, 1); + PCB_QRY_RET_INT(res, 0); + + case PCBQ_OP_EQ: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_OBJ: PCB_QRY_RET_INT(res, ((o1.data.obj) == (o2.data.obj))); + case PCBQ_VT_LST: PCB_QRY_RET_INT(res, pcb_qry_list_cmp(&o1, &o2)); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd == o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng == o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl == o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_null(); + if (s1 == s2) + PCB_QRY_RET_INT(res, 1); + if ((s1 == NULL) || (s2 == NULL)) + PCB_QRY_RET_INT(res, 0); + PCB_QRY_RET_INT(res, strcmp(s1, s2) == 0); + } + return -1; + + case PCBQ_OP_NEQ: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_OBJ: PCB_QRY_RET_INT(res, ((o1.data.obj) != (o2.data.obj))); + case PCBQ_VT_LST: PCB_QRY_RET_INT(res, !pcb_qry_list_cmp(&o1, &o2)); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd != o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng != o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl != o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_null(); + if (s1 == s2) + PCB_QRY_RET_INT(res, 0); + if ((s1 == NULL) || (s2 == NULL)) + PCB_QRY_RET_INT(res, 1); + PCB_QRY_RET_INT(res, strcmp(s1, s2) != 0); + } + return -1; + + case PCBQ_OP_GTEQ: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd >= o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng >= o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl >= o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_empty(); + PCB_QRY_RET_INT(res, strcmp(s1, s2) >= 0); + default: return -1; + } + return -1; + + case PCBQ_OP_LTEQ: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd <= o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng <= o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl <= o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_empty(); + PCB_QRY_RET_INT(res, strcmp(s1, s2) <= 0); + default: return -1; + } + return -1; + + case PCBQ_OP_GT: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd > o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng > o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl > o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_empty(); + PCB_QRY_RET_INT(res, strcmp(s1, s2) > 0); + default: return -1; + } + return -1; + case PCBQ_OP_LT: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd < o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng < o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_INT(res, o1.data.dbl < o2.data.dbl); + case PCBQ_VT_STRING: + load_strings_empty(); + PCB_QRY_RET_INT(res, strcmp(s1, s2) < 0); + default: return -1; + } + return -1; + + case PCBQ_OP_ADD: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd + o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng + o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, o1.data.dbl + o2.data.dbl); + default: return -1; + } + return -1; + + case PCBQ_OP_SUB: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd - o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng - o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, o1.data.dbl - o2.data.dbl); + default: return -1; + } + return -1; + + case PCBQ_OP_MUL: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd * o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng * o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, o1.data.dbl * o2.data.dbl); + default: return -1; + } + return -1; + + case PCBQ_OP_DIV: + BINOPS(); + if (promote(&o1, &o2) != 0) + return -1; + switch(o1.type) { + case PCBQ_VT_VOID: PCB_QRY_RET_INV(res); + case PCBQ_VT_COORD: PCB_QRY_RET_INT(res, o1.data.crd / o2.data.crd); + case PCBQ_VT_LONG: PCB_QRY_RET_INT(res, o1.data.lng / o2.data.lng); + case PCBQ_VT_DOUBLE: PCB_QRY_RET_DBL(res, o1.data.dbl / o2.data.dbl); + default: return -1; + } + return -1; + + case PCBQ_OP_MATCH: + BINOPS1(); + { + pcb_qry_node_t *o2n =node->data.children->next; + char buff[128]; + const char *s; + if (o2n->type != PCBQ_DATA_REGEX) + return -1; + s = op2str(buff, sizeof(buff), &o1); + if (s != NULL) + PCB_QRY_RET_INT(res, re_se_exec(o2n->precomp.regex, s)); + } + PCB_QRY_RET_INV(res); + + case PCBQ_OP_NOT: + UNOP(); + PCB_QRY_RET_INT(res, !pcb_qry_is_true(&o1)); + + case PCBQ_FIELD_OF: + if ((node->data.children == NULL) || (node->data.children->next == NULL)) + return -1; + if (pcb_qry_eval(ctx, node->data.children, &o1, cb, user_ctx) < 0) + return -1; + return pcb_qry_obj_field(ctx, &o1, node->data.children->next, res); + + case PCBQ_LET: + /* no-op: present only in rules and are executed before any assert expression */ + return 0; + + case PCBQ_ASSERT: + /* no-op: present only in rules and are executed manually */ + return 0; + + case PCBQ_VAR: + assert((node->data.crd >= 0) && (node->data.crd < ctx->iter->num_vars)); + res->source = NULL; + res->type = PCBQ_VT_VOID; + if (ctx->iter->vects[node->data.crd] == NULL) + return -1; + tmp = (pcb_any_obj_t **)vtp0_get(ctx->iter->vects[node->data.crd], ctx->iter->idx[node->data.crd], 0); + if ((tmp == NULL) || (*tmp == NULL)) + return -1; + res->type = PCBQ_VT_OBJ; + res->data.obj = ctx->iter->last_obj = *tmp; + return 0; + + case PCBQ_LISTVAR: { + int vi = pcb_qry_iter_var(ctx->iter, node->data.str, 0); + if ((vi < 0) && (strcmp(node->data.str, "@") == 0)) { + res->source = NULL; + res->type = PCBQ_VT_LST; + res->data.lst = ctx->all.data.lst; + return 0; + } + if (vi >= 0) { + res->source = NULL; + res->type = PCBQ_VT_LST; + res->data.lst = ctx->iter->lst[vi].data.lst; + return 0; + } + } + return -1; + + case PCBQ_FNAME: + return -1; /* shall not eval such a node */ + + case PCBQ_FCALL: { + pcb_qry_val_t args[PCB_QRY_MAX_FUNC_ARGS]; + int n; + pcb_qry_node_t *farg, *fname = node->data.children; + if (fname == NULL) + return -1; + farg = fname->next; + if (fname->type != PCBQ_FNAME) + return -1; + memset(args, 0, sizeof(args)); + for(n = 0; (n < PCB_QRY_MAX_FUNC_ARGS) && (farg != NULL); n++, farg = farg->next) + if (pcb_qry_eval(ctx, farg, &args[n], cb, user_ctx) < 0) + return -1; + + if (farg != NULL) { + rnd_message(RND_MSG_ERROR, "too many function arguments\n"); + return -1; + } + if (fname->precomp.fnc.bui != NULL) + return fname->precomp.fnc.bui(ctx, n, args, res); + else + return qry_exec_user_func(ctx, fname->precomp.fnc.uf, n, args, res, cb, user_ctx); + } + + case PCBQ_DATA_COORD: PCB_QRY_RET_INT_SRC(res, node->data.crd, node); + case PCBQ_DATA_DOUBLE: PCB_QRY_RET_DBL_SRC(res, node->data.dbl, node); + case PCBQ_DATA_STRING: PCB_QRY_RET_STR_SRC(res, node->data.str, node); + case PCBQ_DATA_CONST: PCB_QRY_RET_INT_SRC(res, node->precomp.cnst, node); + case PCBQ_DATA_OBJ: PCB_QRY_RET_OBJ_SRC(res, node->precomp.obj, node); + case PCBQ_DATA_INVALID: PCB_QRY_RET_INV_SRC(res, node); + + /* not yet implemented: */ + case PCBQ_RULE: + + /* must not meet these while executing a node */ + case PCBQ_FLAG: + case PCBQ_DATA_REGEX: + case PCBQ_nodetype_max: + case PCBQ_FIELD: + case PCBQ_RNAME: + case PCBQ_DATA_LYTC: + case PCBQ_ITER_CTX: + case PCBQ_FUNCTION: + case PCBQ_RETURN: + case PCBQ_ARG: + return -1; + } + return -1; +} Index: tags/2.3.0/src_plugins/query/query_exec.h =================================================================== --- tags/2.3.0/src_plugins/query/query_exec.h (nonexistent) +++ tags/2.3.0/src_plugins/query/query_exec.h (revision 33253) @@ -0,0 +1,172 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Query language - execution */ + +#ifndef PCB_QUERY_EXEC_H +#define PCB_QUERY_EXEC_H + +#include "query.h" +#include +#include +#include + +#define PCB_QRY_MAX_FUNC_ARGS 64 + +struct pcb_qry_exec_s { + pcb_board_t *pcb; + pcb_qry_node_t *root; + pcb_qry_val_t all; /* a list of all objects */ + pcb_query_iter_t *iter; /* current iterator */ + vtp0_t autofree; + + int (*progress_cb)(pcb_qry_exec_t *ec, long at, long total); + void *progress_ctx; + + /* data/call cache */ + htpp_t obj2netterm; /* (pcb_any_obj_t *) object -> (pcb_any_obj_t *) terminal with the lowest ID on the net segment; for floating segments any object with the lowest ID will be accepted */ + htpp_t obj2lenseg; /* (pcb_any_obj_t *) object -> (pcb_any_obj_t *) length-segment head: each length-segment is a junction-free part of the network */ + htpi_t obj2lenseg_cc; /* (pcb_any_obj_t *) object -> connection-counter (how many different objects are connected) */ + vtp0_t obj2lenseg_free; /* delayed free of obj2lenseg_cc objects */ + vtp0_t tmplst; /* may be reused in a function call to save on allocation; always clear it at the end of the fnc */ + htpp_t layer_setup_precomp; /* fnc layer_setup(): cache precompiled conditions */ + vtp0_t layer_setup_netobjs; /* fnc layer_setup(): tmp allocation cache for object listing */ + void *layer_setup_res_cache; /* fnc layer_setup(): cached results for each condition evaluated - requests tend to repeat */ + time_t last_prog_cb; + + unsigned obj2netterm_inited:1; + unsigned obj2lenseg_inited:1; + unsigned layer_setup_inited:1; + unsigned warned_missing_thickness:1; + unsigned trace:1; +}; + +/* if bufno is -1, scope is the board, else scope is the buffer addressed by bufno */ +void pcb_qry_init(pcb_qry_exec_t *ctx, pcb_board_t *pcb, pcb_qry_node_t *root, int bufno); +void pcb_qry_uninit(pcb_qry_exec_t *ctx); + +/* parts of init/uninit for the case a single pcb_qry_exec_t is used for + multiple queries for sharing the cache */ +void pcb_qry_setup(pcb_qry_exec_t *ctx, pcb_board_t *pcb, pcb_qry_node_t *root); +void pcb_qry_autofree(pcb_qry_exec_t *ctx); + +/* Execute an expression or a rule; if ec is NULL, use a temporary context and + free it before returning; else ec is the shared context for multiple queries + with persistent cache */ +int pcb_qry_run(pcb_qry_exec_t *ec, pcb_board_t *pcb, pcb_qry_node_t *prg, int bufno, void (*cb)(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current), void *user_ctx); + +int pcb_qry_is_true(pcb_qry_val_t *val); + +int pcb_qry_eval(pcb_qry_exec_t *ctx, pcb_qry_node_t *node, pcb_qry_val_t *res, void (*cb)(void *user_ctx, pcb_qry_val_t *res, pcb_any_obj_t *current), void *user_ctx); + +int pcb_qry_it_reset(pcb_qry_exec_t *ctx, pcb_qry_node_t *node); + +/* Returns 1 if context iterator is valid, 0 if the loop is over */ +int pcb_qry_it_next(pcb_qry_exec_t *ctx); + + + +/* Helper macros: load value o and return 0 */ +#define PCB_QRY_RET_INT_SRC(o, value, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_LONG; \ + o->data.lng = value; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_INT(o, value) PCB_QRY_RET_INT_SRC(o, value, NULL) + + +#define PCB_QRY_RET_OBJ_SRC(o, value, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_OBJ; \ + o->data.obj = value; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_OBJ(o, value) PCB_QRY_RET_OBJ_SRC(o, value, NULL) + +#define PCB_QRY_RET_DBL_SRC(o, value, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_DOUBLE; \ + o->data.dbl = value; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_DBL(o, value) PCB_QRY_RET_DBL_SRC(o, value, NULL) + +#define PCB_QRY_RET_COORD_SRC(o, value, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_COORD; \ + o->data.crd = value; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_COORD(o, value) PCB_QRY_RET_COORD_SRC(o, value, NULL) + +#define PCB_QRY_RET_STR_SRC(o, value, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_STRING; \ + o->data.str = value; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_STR(o, value) PCB_QRY_RET_STR_SRC(o, value, NULL) + +#define PCB_QRY_RET_SIDE_SRC(o, on_bottom, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_STRING; \ + o->data.str = on_bottom ? "BOTTOM" : "TOP"; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_SIDE(o, value) PCB_QRY_RET_SIDE_SRC(o, value, NULL) + +/* The case when the operation couldn't be carried out, sort of NaN */ +#define PCB_QRY_RET_INV_SRC(o, node) \ +do { \ + o->source = node; \ + o->type = PCBQ_VT_VOID; \ + return 0; \ +} while(0) +#define PCB_QRY_RET_INV(o) PCB_QRY_RET_INV_SRC(o, NULL) + +/* Convert src_arg to coordinate and cache the result if src_arg is tied + to a tree node */ +#define PCB_QRY_ARG_CONV_TO_COORD(dst_crd, src_arg, err_inst) \ +do { \ + rnd_bool succ; \ + if ((src_arg)->type == PCBQ_VT_COORD) { dst_crd = (src_arg)->data.crd; break; } \ + if ((src_arg)->type == PCBQ_VT_LONG) { dst_crd = (src_arg)->data.lng; break; } \ + if ((src_arg)->type == PCBQ_VT_DOUBLE) { dst_crd = rnd_round((src_arg)->data.dbl); break; } \ + if ((src_arg)->type == PCBQ_VT_STRING) { \ + dst_crd = rnd_get_value((src_arg)->data.str, NULL, NULL, &succ); \ + if (succ) break; \ + } \ + err_inst; \ +} while(0) + +#endif Index: tags/2.3.0/src_plugins/query/query_l.c =================================================================== --- tags/2.3.0/src_plugins/query/query_l.c (nonexistent) +++ tags/2.3.0/src_plugins/query/query_l.c (revision 33253) @@ -0,0 +1,2612 @@ +#line 2 "query_l.c" + +#line 4 "query_l.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define yy_create_buffer qry__create_buffer +#define yy_delete_buffer qry__delete_buffer +#define yy_scan_buffer qry__scan_buffer +#define yy_scan_string qry__scan_string +#define yy_scan_bytes qry__scan_bytes +#define yy_init_buffer qry__init_buffer +#define yy_flush_buffer qry__flush_buffer +#define yy_load_buffer_state qry__load_buffer_state +#define yy_switch_to_buffer qry__switch_to_buffer +#define yypush_buffer_state qry_push_buffer_state +#define yypop_buffer_state qry_pop_buffer_state +#define yyensure_buffer_stack qry_ensure_buffer_stack +#define yy_flex_debug qry__flex_debug +#define yyin qry_in +#define yyleng qry_leng +#define yylex qry_lex +#define yylineno qry_lineno +#define yyout qry_out +#define yyrestart qry_restart +#define yytext qry_text +#define yywrap qry_wrap +#define yyalloc qry_alloc +#define yyrealloc qry_realloc +#define yyfree qry_free + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yy_create_buffer +#define qry__create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer qry__create_buffer +#endif + +#ifdef yy_delete_buffer +#define qry__delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer qry__delete_buffer +#endif + +#ifdef yy_scan_buffer +#define qry__scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer qry__scan_buffer +#endif + +#ifdef yy_scan_string +#define qry__scan_string_ALREADY_DEFINED +#else +#define yy_scan_string qry__scan_string +#endif + +#ifdef yy_scan_bytes +#define qry__scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes qry__scan_bytes +#endif + +#ifdef yy_init_buffer +#define qry__init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer qry__init_buffer +#endif + +#ifdef yy_flush_buffer +#define qry__flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer qry__flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define qry__load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state qry__load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define qry__switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer qry__switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define qry_push_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state qry_push_buffer_state +#endif + +#ifdef yypop_buffer_state +#define qry_pop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state qry_pop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define qry_ensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack qry_ensure_buffer_stack +#endif + +#ifdef yylex +#define qry_lex_ALREADY_DEFINED +#else +#define yylex qry_lex +#endif + +#ifdef yyrestart +#define qry_restart_ALREADY_DEFINED +#else +#define yyrestart qry_restart +#endif + +#ifdef yylex_init +#define qry_lex_init_ALREADY_DEFINED +#else +#define yylex_init qry_lex_init +#endif + +#ifdef yylex_init_extra +#define qry_lex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra qry_lex_init_extra +#endif + +#ifdef yylex_destroy +#define qry_lex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy qry_lex_destroy +#endif + +#ifdef yyget_debug +#define qry_get_debug_ALREADY_DEFINED +#else +#define yyget_debug qry_get_debug +#endif + +#ifdef yyset_debug +#define qry_set_debug_ALREADY_DEFINED +#else +#define yyset_debug qry_set_debug +#endif + +#ifdef yyget_extra +#define qry_get_extra_ALREADY_DEFINED +#else +#define yyget_extra qry_get_extra +#endif + +#ifdef yyset_extra +#define qry_set_extra_ALREADY_DEFINED +#else +#define yyset_extra qry_set_extra +#endif + +#ifdef yyget_in +#define qry_get_in_ALREADY_DEFINED +#else +#define yyget_in qry_get_in +#endif + +#ifdef yyset_in +#define qry_set_in_ALREADY_DEFINED +#else +#define yyset_in qry_set_in +#endif + +#ifdef yyget_out +#define qry_get_out_ALREADY_DEFINED +#else +#define yyget_out qry_get_out +#endif + +#ifdef yyset_out +#define qry_set_out_ALREADY_DEFINED +#else +#define yyset_out qry_set_out +#endif + +#ifdef yyget_leng +#define qry_get_leng_ALREADY_DEFINED +#else +#define yyget_leng qry_get_leng +#endif + +#ifdef yyget_text +#define qry_get_text_ALREADY_DEFINED +#else +#define yyget_text qry_get_text +#endif + +#ifdef yyget_lineno +#define qry_get_lineno_ALREADY_DEFINED +#else +#define yyget_lineno qry_get_lineno +#endif + +#ifdef yyset_lineno +#define qry_set_lineno_ALREADY_DEFINED +#else +#define yyset_lineno qry_set_lineno +#endif + +#ifdef yywrap +#define qry_wrap_ALREADY_DEFINED +#else +#define yywrap qry_wrap +#endif + +#ifdef yyalloc +#define qry_alloc_ALREADY_DEFINED +#else +#define yyalloc qry_alloc +#endif + +#ifdef yyrealloc +#define qry_realloc_ALREADY_DEFINED +#else +#define yyrealloc qry_realloc +#endif + +#ifdef yyfree +#define qry_free_ALREADY_DEFINED +#else +#define yyfree qry_free +#endif + +#ifdef yytext +#define qry_text_ALREADY_DEFINED +#else +#define yytext qry_text +#endif + +#ifdef yyleng +#define qry_leng_ALREADY_DEFINED +#else +#define yyleng qry_leng +#endif + +#ifdef yyin +#define qry_in_ALREADY_DEFINED +#else +#define yyin qry_in +#endif + +#ifdef yyout +#define qry_out_ALREADY_DEFINED +#else +#define yyout qry_out +#endif + +#ifdef yy_flex_debug +#define qry__flex_debug_ALREADY_DEFINED +#else +#define yy_flex_debug qry__flex_debug +#endif + +#ifdef yylineno +#define qry_lineno_ALREADY_DEFINED +#else +#define yylineno qry_lineno +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 76 +#define YY_END_OF_BUFFER 77 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[273] = + { 0, + 74, 74, 77, 76, 75, 74, 72, 76, 72, 76, + 76, 72, 72, 68, 72, 76, 72, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 76, 71, 71, 71, 71, + 71, 55, 71, 71, 71, 71, 71, 76, 74, 65, + 0, 1, 0, 63, 0, 2, 69, 70, 68, 67, + 64, 66, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 35, 71, 30, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 73, 11, 71, 57, 71, 71, 71, 71, 71, 71, + + 54, 58, 10, 71, 71, 71, 56, 62, 0, 70, + 18, 71, 71, 71, 45, 71, 71, 19, 71, 71, + 71, 71, 71, 71, 25, 34, 71, 71, 71, 71, + 20, 71, 71, 71, 36, 71, 71, 31, 71, 71, + 71, 71, 71, 3, 71, 59, 71, 71, 71, 0, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 15, 42, 44, 71, 71, 71, 22, 41, 23, + 16, 28, 71, 71, 71, 71, 60, 71, 8, 71, + 5, 61, 0, 71, 71, 71, 71, 71, 71, 71, + 32, 71, 71, 26, 71, 71, 43, 71, 71, 71, + + 71, 71, 12, 71, 71, 71, 0, 37, 71, 40, + 71, 71, 71, 71, 38, 71, 71, 71, 71, 71, + 71, 71, 71, 4, 71, 71, 7, 0, 71, 71, + 47, 48, 71, 51, 71, 71, 71, 71, 71, 17, + 71, 71, 29, 71, 9, 0, 46, 71, 71, 39, + 71, 27, 71, 21, 71, 71, 6, 0, 49, 71, + 33, 71, 71, 71, 0, 50, 13, 14, 24, 52, + 53, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 1, 6, 1, 7, 8, 9, + 9, 9, 9, 9, 9, 10, 9, 11, 12, 13, + 11, 11, 11, 11, 11, 11, 11, 1, 14, 15, + 16, 17, 1, 9, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 27, 34, 35, 36, 37, 38, 27, 39, 40, 27, + 1, 41, 1, 1, 42, 1, 43, 27, 44, 45, + + 46, 47, 48, 49, 50, 27, 27, 51, 52, 53, + 54, 55, 27, 56, 57, 58, 59, 60, 61, 62, + 63, 27, 1, 64, 1, 9, 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 + } ; + +static const YY_CHAR yy_meta[65] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 1 + } ; + +static const flex_int16_t yy_base[276] = + { 0, + 0, 0, 311, 312, 312, 62, 294, 304, 263, 300, + 298, 312, 55, 59, 289, 288, 287, 268, 269, 268, + 41, 0, 281, 275, 266, 56, 59, 56, 56, 62, + 278, 58, 64, 269, 272, 290, 73, 240, 34, 238, + 53, 39, 238, 279, 46, 239, 235, 222, 87, 312, + 280, 312, 223, 312, 275, 312, 95, 98, 102, 312, + 312, 312, 0, 262, 80, 248, 260, 259, 249, 238, + 64, 236, 244, 239, 253, 236, 0, 248, 0, 83, + 241, 233, 232, 238, 247, 226, 231, 226, 227, 226, + 312, 312, 203, 0, 216, 205, 75, 199, 199, 204, + + 0, 0, 312, 196, 202, 193, 0, 312, 203, 109, + 0, 214, 218, 215, 0, 101, 212, 0, 224, 219, + 222, 221, 214, 216, 0, 0, 205, 203, 198, 209, + 0, 208, 215, 198, 0, 211, 206, 0, 185, 182, + 185, 179, 184, 0, 168, 0, 166, 178, 166, 180, + 189, 199, 197, 179, 183, 194, 193, 192, 179, 177, + 177, 168, 0, 0, 173, 186, 100, 0, 0, 181, + 0, 0, 187, 149, 194, 145, 0, 151, 0, 145, + 0, 0, 157, 169, 180, 163, 163, 162, 176, 154, + 0, 161, 165, 166, 156, 170, 0, 155, 153, 151, + + 155, 125, 312, 132, 131, 127, 123, 0, 144, 0, + 155, 114, 141, 139, 156, 154, 138, 139, 150, 138, + 136, 147, 144, 0, 111, 119, 0, 117, 122, 141, + 0, 0, 123, 0, 130, 129, 124, 130, 127, 0, + 128, 116, 0, 99, 0, 108, 0, 114, 115, 0, + 126, 0, 116, 0, 110, 114, 0, 97, 0, 116, + 0, 100, 98, 97, 66, 0, 0, 0, 0, 312, + 312, 312, 142, 144, 130 + } ; + +static const flex_int16_t yy_def[276] = + { 0, + 272, 1, 272, 272, 272, 272, 272, 273, 272, 272, + 274, 272, 272, 272, 272, 272, 272, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 272, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 272, 272, 272, + 273, 272, 272, 272, 274, 272, 272, 272, 272, 272, + 272, 272, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 272, 272, 275, 275, 275, 275, 275, 275, 275, 275, + + 275, 275, 272, 275, 275, 275, 275, 272, 272, 272, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 272, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 272, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + + 275, 275, 272, 275, 275, 275, 272, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 272, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 272, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 272, 275, 275, + 275, 275, 275, 275, 272, 275, 275, 275, 275, 272, + 272, 0, 272, 272, 272 + } ; + +static const flex_int16_t yy_nxt[377] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 14, 14, 6, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 22, 25, 22, 22, 26, 27, + 28, 29, 30, 31, 32, 33, 22, 34, 22, 35, + 36, 22, 37, 38, 22, 22, 39, 22, 22, 40, + 41, 42, 43, 22, 44, 45, 22, 46, 47, 22, + 22, 22, 22, 48, 49, 57, 57, 57, 58, 59, + 59, 59, 67, 72, 68, 49, 74, 76, 78, 80, + 75, 73, 92, 84, 95, 86, 79, 77, 100, 49, + 101, 104, 96, 81, 85, 87, 82, 88, 98, 119, + + 49, 120, 99, 127, 105, 57, 57, 57, 110, 110, + 110, 58, 59, 59, 59, 112, 113, 128, 142, 110, + 110, 110, 154, 198, 155, 231, 232, 270, 271, 93, + 156, 63, 269, 268, 143, 267, 157, 266, 265, 264, + 263, 199, 51, 51, 55, 55, 262, 261, 260, 259, + 258, 257, 256, 255, 254, 253, 252, 251, 250, 249, + 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, + 238, 237, 236, 235, 234, 233, 230, 229, 228, 227, + 226, 225, 224, 223, 222, 221, 220, 219, 218, 217, + 216, 215, 214, 213, 212, 211, 210, 209, 208, 207, + + 206, 205, 204, 203, 202, 201, 200, 197, 196, 195, + 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, + 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, + 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, + 164, 163, 162, 161, 160, 159, 158, 153, 152, 151, + 150, 149, 148, 147, 146, 145, 144, 141, 140, 139, + 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, + 126, 125, 124, 123, 122, 121, 118, 117, 116, 115, + 114, 111, 56, 109, 52, 108, 107, 106, 103, 102, + 97, 94, 91, 90, 89, 83, 71, 70, 69, 66, + + 65, 64, 62, 61, 60, 56, 54, 53, 52, 50, + 272, 3, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272 + } ; + +static const flex_int16_t yy_chk[377] = + { 0, + 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, 6, 13, 13, 13, 14, 14, + 14, 14, 21, 26, 21, 6, 27, 28, 29, 30, + 27, 26, 37, 32, 39, 33, 29, 28, 42, 49, + 42, 45, 39, 30, 32, 33, 30, 33, 41, 71, + + 49, 71, 41, 80, 45, 57, 57, 57, 58, 58, + 58, 59, 59, 59, 59, 65, 65, 80, 97, 110, + 110, 110, 116, 167, 116, 212, 212, 265, 265, 37, + 116, 275, 264, 263, 97, 262, 116, 260, 258, 256, + 255, 167, 273, 273, 274, 274, 253, 251, 249, 248, + 246, 244, 242, 241, 239, 238, 237, 236, 235, 233, + 230, 229, 228, 226, 225, 223, 222, 221, 220, 219, + 218, 217, 216, 215, 214, 213, 211, 209, 207, 206, + 205, 204, 202, 201, 200, 199, 198, 196, 195, 194, + 193, 192, 190, 189, 188, 187, 186, 185, 184, 183, + + 180, 178, 176, 175, 174, 173, 170, 166, 165, 162, + 161, 160, 159, 158, 157, 156, 155, 154, 153, 152, + 151, 150, 149, 148, 147, 145, 143, 142, 141, 140, + 139, 137, 136, 134, 133, 132, 130, 129, 128, 127, + 124, 123, 122, 121, 120, 119, 117, 114, 113, 112, + 109, 106, 105, 104, 100, 99, 98, 96, 95, 93, + 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, + 78, 76, 75, 74, 73, 72, 70, 69, 68, 67, + 66, 64, 55, 53, 51, 48, 47, 46, 44, 43, + 40, 38, 36, 35, 34, 31, 25, 24, 23, 20, + + 19, 18, 17, 16, 15, 11, 10, 9, 8, 7, + 3, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "query_l.l" +#line 2 "query_l.l" +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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. + * + */ + +/* Query language - compiler: lexical analyzer */ + +#include +#include "query.h" +#include "query_y.h" +#include +#include "layer.h" +#include "board.h" + +static const char *pcb_qry_program, *pcb_qry_program_ptr; +static int qry_yy_input(char *buf, int buflen); +static pcb_qry_node_t *make_constant(char *str, long val); +static pcb_qry_node_t *make_const_obj(char *str, pcb_any_obj_t *obj); +#define YY_INPUT(buf, res, buflen) (res = qry_yy_input(buf, buflen)) +#line 911 "query_l.c" +#line 912 "query_l.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + + static void yyunput ( int c, char *buf_ptr ); + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 42 "query_l.l" + +#line 1131 "query_l.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 273 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 312 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +/* rule 1 can match eol */ +YY_RULE_SETUP +#line 43 "query_l.l" +{ qry_lval.s = rnd_strdup(yytext+1); qry_lval.s[strlen(qry_lval.s)-1] = '\0'; return T_QSTR; /*"*/ } + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 44 "query_l.l" +{ qry_lval.s = rnd_strdup(yytext+1); qry_lval.s[strlen(qry_lval.s)-1] = '\0'; return T_QSTR; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 46 "query_l.l" +{ return T_LET; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 47 "query_l.l" +{ return T_ASSERT; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 48 "query_l.l" +{ return T_RULE; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 49 "query_l.l" +{ return T_FUNCTION; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 50 "query_l.l" +{ return T_RETURN; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 51 "query_l.l" +{ return T_LIST; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 52 "query_l.l" +{ return T_INVALID; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 53 "query_l.l" +{ return T_FLD_P; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 54 "query_l.l" +{ return T_FLD_A; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 55 "query_l.l" +{ return T_FLD_FLAG; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 57 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_LINE_POINT); return T_CONST; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 58 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_POLY_POINT); return T_CONST; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 59 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_LINE); return T_CONST; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 60 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_TEXT); return T_CONST; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 61 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_POLY); return T_CONST; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 62 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_ARC); return T_CONST; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 63 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_GFX); return T_CONST; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 64 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_RAT); return T_CONST; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 65 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_PSTK); return T_CONST; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 66 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_PSTK); return T_CONST; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 67 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_SUBC); return T_CONST; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 68 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_SUBC); return T_CONST; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 69 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_NET); return T_CONST; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 70 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_LAYER); return T_CONST; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 71 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_OBJ_LAYERGRP); return T_CONST; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 73 "query_l.l" +{ qry_lval.n = make_constant(yytext, 1); return T_CONST; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 74 "query_l.l" +{ qry_lval.n = make_constant(yytext, 1); return T_CONST; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 75 "query_l.l" +{ qry_lval.n = make_constant(yytext, 1); return T_CONST; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 76 "query_l.l" +{ qry_lval.n = make_constant(yytext, 1); return T_CONST; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 78 "query_l.l" +{ qry_lval.n = make_constant(yytext, 0); return T_CONST; } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 79 "query_l.l" +{ qry_lval.n = make_constant(yytext, 0); return T_CONST; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 80 "query_l.l" +{ qry_lval.n = make_constant(yytext, 0); return T_CONST; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 81 "query_l.l" +{ qry_lval.n = make_constant(yytext, 0); return T_CONST; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 83 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_LYT_TOP); return T_CONST; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 84 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_LYT_BOTTOM); return T_CONST; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 85 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_LYT_INTERN); return T_CONST; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 86 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_LYT_INTERN); return T_CONST; } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 87 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_LYT_COPPER); return T_CONST; } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 88 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_LYT_SILK); return T_CONST; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 89 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_LYT_MASK); return T_CONST; } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 90 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_LYT_PASTE); return T_CONST; } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 91 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_LYT_MECH); return T_CONST; } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 92 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_LYT_DOC); return T_CONST; } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 93 "query_l.l" +{ qry_lval.n = make_constant(yytext, PCB_LYT_BOUNDARY); return T_CONST; } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 95 "query_l.l" +{ qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_GRP1]); return T_CONST; } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 96 "query_l.l" +{ qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_GRP2]); return T_CONST; } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 97 "query_l.l" +{ qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_EXPECT]); return T_CONST; } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 98 "query_l.l" +{ qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_MEASURE]); return T_CONST; } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 99 "query_l.l" +{ qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_TEXT]); return T_CONST; } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 101 "query_l.l" +{ qry_lval.c = PCB->hidlib.size_x; return T_INT; } + YY_BREAK +case 53: +YY_RULE_SETUP +#line 102 "query_l.l" +{ qry_lval.c = PCB->hidlib.size_y; return T_INT; } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 104 "query_l.l" +{ qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_MM); return T_UNIT; } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 105 "query_l.l" +{ qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_M); return T_UNIT; } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 106 "query_l.l" +{ qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_UM); return T_UNIT; } + YY_BREAK +case 57: +YY_RULE_SETUP +#line 107 "query_l.l" +{ qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_CM); return T_UNIT; } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 108 "query_l.l" +{ qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_NM); return T_UNIT; } + YY_BREAK +case 59: +YY_RULE_SETUP +#line 109 "query_l.l" +{ qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_MIL); return T_UNIT; } + YY_BREAK +case 60: +YY_RULE_SETUP +#line 110 "query_l.l" +{ qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_IN); return T_UNIT; } + YY_BREAK +case 61: +YY_RULE_SETUP +#line 112 "query_l.l" +{ return T_THUS; } + YY_BREAK +case 62: +YY_RULE_SETUP +#line 113 "query_l.l" +{ return T_OR; } + YY_BREAK +case 63: +YY_RULE_SETUP +#line 114 "query_l.l" +{ return T_AND; } + YY_BREAK +case 64: +YY_RULE_SETUP +#line 115 "query_l.l" +{ return T_EQ; } + YY_BREAK +case 65: +YY_RULE_SETUP +#line 116 "query_l.l" +{ return T_NEQ; } + YY_BREAK +case 66: +YY_RULE_SETUP +#line 117 "query_l.l" +{ return T_GTEQ; } + YY_BREAK +case 67: +YY_RULE_SETUP +#line 118 "query_l.l" +{ return T_LTEQ; } + YY_BREAK +case 68: +YY_RULE_SETUP +#line 120 "query_l.l" +{ qry_lval.c = strtol(yytext, NULL, 10); return T_INT; } + YY_BREAK +case 69: +YY_RULE_SETUP +#line 121 "query_l.l" +{ qry_lval.d = strtod(yytext, NULL); return T_DBL; } + YY_BREAK +case 70: +YY_RULE_SETUP +#line 122 "query_l.l" +{ qry_lval.d = strtod(yytext, NULL); return T_DBL; } + YY_BREAK +case 71: +YY_RULE_SETUP +#line 123 "query_l.l" +{ qry_lval.s = rnd_strdup(yytext); return T_STR; } + YY_BREAK +case 72: +YY_RULE_SETUP +#line 125 "query_l.l" +{ return *yytext; } + YY_BREAK +case 73: +/* rule 73 can match eol */ +YY_RULE_SETUP +#line 127 "query_l.l" +{ continue; /* multiline rules */} + YY_BREAK +case 74: +/* rule 74 can match eol */ +YY_RULE_SETUP +#line 128 "query_l.l" +{ return T_NL; } + YY_BREAK +case 75: +YY_RULE_SETUP +#line 129 "query_l.l" +{ continue; } + YY_BREAK +case 76: +YY_RULE_SETUP +#line 131 "query_l.l" +ECHO; + YY_BREAK +#line 1572 "query_l.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 273 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 273 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 272); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + + static void yyunput (int c, char * yy_bp ) +{ + char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + int number_to_move = (yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 131 "query_l.l" + + +static int qry_yy_input(char *buf, int buflen) +{ + int len; + for(len = 0; (*pcb_qry_program_ptr != '\0') && (buflen > 0); len++,buflen--) { +/* printf("IN: '%c'\n", *pcb_qry_program_ptr);*/ + *buf = *pcb_qry_program_ptr; + buf++; + pcb_qry_program_ptr++; + } + return len; +} + +void pcb_qry_set_input(const char *script) +{ + while(isspace(*script)) script++; + pcb_qry_program = pcb_qry_program_ptr = script; +} + +static pcb_qry_node_t *make_constant(char *str, long val) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_CONST); + res->data.str = rnd_strdup(str); + res->precomp.cnst = val; + return res; +} + +static pcb_qry_node_t *make_const_obj(char *str, pcb_any_obj_t *o) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_OBJ); + res->data.str = rnd_strdup(str); + res->precomp.obj = o; + return res; +} + Index: tags/2.3.0/src_plugins/query/query_l.h =================================================================== --- tags/2.3.0/src_plugins/query/query_l.h (nonexistent) +++ tags/2.3.0/src_plugins/query/query_l.h (revision 33253) @@ -0,0 +1,708 @@ +#ifndef qry_HEADER_H +#define qry_HEADER_H 1 +#define qry_IN_HEADER 1 + +#line 6 "query_l.h" + +#line 8 "query_l.h" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yy_create_buffer +#define qry__create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer qry__create_buffer +#endif + +#ifdef yy_delete_buffer +#define qry__delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer qry__delete_buffer +#endif + +#ifdef yy_scan_buffer +#define qry__scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer qry__scan_buffer +#endif + +#ifdef yy_scan_string +#define qry__scan_string_ALREADY_DEFINED +#else +#define yy_scan_string qry__scan_string +#endif + +#ifdef yy_scan_bytes +#define qry__scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes qry__scan_bytes +#endif + +#ifdef yy_init_buffer +#define qry__init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer qry__init_buffer +#endif + +#ifdef yy_flush_buffer +#define qry__flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer qry__flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define qry__load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state qry__load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define qry__switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer qry__switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define qry_push_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state qry_push_buffer_state +#endif + +#ifdef yypop_buffer_state +#define qry_pop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state qry_pop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define qry_ensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack qry_ensure_buffer_stack +#endif + +#ifdef yylex +#define qry_lex_ALREADY_DEFINED +#else +#define yylex qry_lex +#endif + +#ifdef yyrestart +#define qry_restart_ALREADY_DEFINED +#else +#define yyrestart qry_restart +#endif + +#ifdef yylex_init +#define qry_lex_init_ALREADY_DEFINED +#else +#define yylex_init qry_lex_init +#endif + +#ifdef yylex_init_extra +#define qry_lex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra qry_lex_init_extra +#endif + +#ifdef yylex_destroy +#define qry_lex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy qry_lex_destroy +#endif + +#ifdef yyget_debug +#define qry_get_debug_ALREADY_DEFINED +#else +#define yyget_debug qry_get_debug +#endif + +#ifdef yyset_debug +#define qry_set_debug_ALREADY_DEFINED +#else +#define yyset_debug qry_set_debug +#endif + +#ifdef yyget_extra +#define qry_get_extra_ALREADY_DEFINED +#else +#define yyget_extra qry_get_extra +#endif + +#ifdef yyset_extra +#define qry_set_extra_ALREADY_DEFINED +#else +#define yyset_extra qry_set_extra +#endif + +#ifdef yyget_in +#define qry_get_in_ALREADY_DEFINED +#else +#define yyget_in qry_get_in +#endif + +#ifdef yyset_in +#define qry_set_in_ALREADY_DEFINED +#else +#define yyset_in qry_set_in +#endif + +#ifdef yyget_out +#define qry_get_out_ALREADY_DEFINED +#else +#define yyget_out qry_get_out +#endif + +#ifdef yyset_out +#define qry_set_out_ALREADY_DEFINED +#else +#define yyset_out qry_set_out +#endif + +#ifdef yyget_leng +#define qry_get_leng_ALREADY_DEFINED +#else +#define yyget_leng qry_get_leng +#endif + +#ifdef yyget_text +#define qry_get_text_ALREADY_DEFINED +#else +#define yyget_text qry_get_text +#endif + +#ifdef yyget_lineno +#define qry_get_lineno_ALREADY_DEFINED +#else +#define yyget_lineno qry_get_lineno +#endif + +#ifdef yyset_lineno +#define qry_set_lineno_ALREADY_DEFINED +#else +#define yyset_lineno qry_set_lineno +#endif + +#ifdef yywrap +#define qry_wrap_ALREADY_DEFINED +#else +#define yywrap qry_wrap +#endif + +#ifdef yyalloc +#define qry_alloc_ALREADY_DEFINED +#else +#define yyalloc qry_alloc +#endif + +#ifdef yyrealloc +#define qry_realloc_ALREADY_DEFINED +#else +#define yyrealloc qry_realloc +#endif + +#ifdef yyfree +#define qry_free_ALREADY_DEFINED +#else +#define yyfree qry_free +#endif + +#ifdef yytext +#define qry_text_ALREADY_DEFINED +#else +#define yytext qry_text +#endif + +#ifdef yyleng +#define qry_leng_ALREADY_DEFINED +#else +#define yyleng qry_leng +#endif + +#ifdef yyin +#define qry_in_ALREADY_DEFINED +#else +#define yyin qry_in +#endif + +#ifdef yyout +#define qry_out_ALREADY_DEFINED +#else +#define yyout qry_out +#endif + +#ifdef yy_flex_debug +#define qry__flex_debug_ALREADY_DEFINED +#else +#define yy_flex_debug qry__flex_debug +#endif + +#ifdef yylineno +#define qry_lineno_ALREADY_DEFINED +#else +#define yylineno qry_lineno +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +/* Begin user sect3 */ + +extern int yylineno; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define INITIAL 0 + +#endif + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +#ifndef qry__create_buffer_ALREADY_DEFINED +#undef yy_create_buffer +#endif +#ifndef qry__delete_buffer_ALREADY_DEFINED +#undef yy_delete_buffer +#endif +#ifndef qry__scan_buffer_ALREADY_DEFINED +#undef yy_scan_buffer +#endif +#ifndef qry__scan_string_ALREADY_DEFINED +#undef yy_scan_string +#endif +#ifndef qry__scan_bytes_ALREADY_DEFINED +#undef yy_scan_bytes +#endif +#ifndef qry__init_buffer_ALREADY_DEFINED +#undef yy_init_buffer +#endif +#ifndef qry__flush_buffer_ALREADY_DEFINED +#undef yy_flush_buffer +#endif +#ifndef qry__load_buffer_state_ALREADY_DEFINED +#undef yy_load_buffer_state +#endif +#ifndef qry__switch_to_buffer_ALREADY_DEFINED +#undef yy_switch_to_buffer +#endif +#ifndef qry_push_buffer_state_ALREADY_DEFINED +#undef yypush_buffer_state +#endif +#ifndef qry_pop_buffer_state_ALREADY_DEFINED +#undef yypop_buffer_state +#endif +#ifndef qry_ensure_buffer_stack_ALREADY_DEFINED +#undef yyensure_buffer_stack +#endif +#ifndef qry_lex_ALREADY_DEFINED +#undef yylex +#endif +#ifndef qry_restart_ALREADY_DEFINED +#undef yyrestart +#endif +#ifndef qry_lex_init_ALREADY_DEFINED +#undef yylex_init +#endif +#ifndef qry_lex_init_extra_ALREADY_DEFINED +#undef yylex_init_extra +#endif +#ifndef qry_lex_destroy_ALREADY_DEFINED +#undef yylex_destroy +#endif +#ifndef qry_get_debug_ALREADY_DEFINED +#undef yyget_debug +#endif +#ifndef qry_set_debug_ALREADY_DEFINED +#undef yyset_debug +#endif +#ifndef qry_get_extra_ALREADY_DEFINED +#undef yyget_extra +#endif +#ifndef qry_set_extra_ALREADY_DEFINED +#undef yyset_extra +#endif +#ifndef qry_get_in_ALREADY_DEFINED +#undef yyget_in +#endif +#ifndef qry_set_in_ALREADY_DEFINED +#undef yyset_in +#endif +#ifndef qry_get_out_ALREADY_DEFINED +#undef yyget_out +#endif +#ifndef qry_set_out_ALREADY_DEFINED +#undef yyset_out +#endif +#ifndef qry_get_leng_ALREADY_DEFINED +#undef yyget_leng +#endif +#ifndef qry_get_text_ALREADY_DEFINED +#undef yyget_text +#endif +#ifndef qry_get_lineno_ALREADY_DEFINED +#undef yyget_lineno +#endif +#ifndef qry_set_lineno_ALREADY_DEFINED +#undef yyset_lineno +#endif +#ifndef qry_get_column_ALREADY_DEFINED +#undef yyget_column +#endif +#ifndef qry_set_column_ALREADY_DEFINED +#undef yyset_column +#endif +#ifndef qry_wrap_ALREADY_DEFINED +#undef yywrap +#endif +#ifndef qry_get_lval_ALREADY_DEFINED +#undef yyget_lval +#endif +#ifndef qry_set_lval_ALREADY_DEFINED +#undef yyset_lval +#endif +#ifndef qry_get_lloc_ALREADY_DEFINED +#undef yyget_lloc +#endif +#ifndef qry_set_lloc_ALREADY_DEFINED +#undef yyset_lloc +#endif +#ifndef qry_alloc_ALREADY_DEFINED +#undef yyalloc +#endif +#ifndef qry_realloc_ALREADY_DEFINED +#undef yyrealloc +#endif +#ifndef qry_free_ALREADY_DEFINED +#undef yyfree +#endif +#ifndef qry_text_ALREADY_DEFINED +#undef yytext +#endif +#ifndef qry_leng_ALREADY_DEFINED +#undef yyleng +#endif +#ifndef qry_in_ALREADY_DEFINED +#undef yyin +#endif +#ifndef qry_out_ALREADY_DEFINED +#undef yyout +#endif +#ifndef qry__flex_debug_ALREADY_DEFINED +#undef yy_flex_debug +#endif +#ifndef qry_lineno_ALREADY_DEFINED +#undef yylineno +#endif +#ifndef qry_tables_fload_ALREADY_DEFINED +#undef yytables_fload +#endif +#ifndef qry_tables_destroy_ALREADY_DEFINED +#undef yytables_destroy +#endif +#ifndef qry_TABLES_NAME_ALREADY_DEFINED +#undef yyTABLES_NAME +#endif + +#line 131 "query_l.l" + + +#line 707 "query_l.h" +#undef qry_IN_HEADER +#endif /* qry_HEADER_H */ Index: tags/2.3.0/src_plugins/query/query_l.l =================================================================== --- tags/2.3.0/src_plugins/query/query_l.l (nonexistent) +++ tags/2.3.0/src_plugins/query/query_l.l (revision 33253) @@ -0,0 +1,165 @@ +%{ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,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. + * + */ + +/* Query language - compiler: lexical analyzer */ + +#include +#include "query.h" +#include "query_y.h" +#include +#include "layer.h" +#include "board.h" + +static const char *pcb_qry_program, *pcb_qry_program_ptr; +static int qry_yy_input(char *buf, int buflen); +static pcb_qry_node_t *make_constant(char *str, long val); +static pcb_qry_node_t *make_const_obj(char *str, pcb_any_obj_t *obj); +#define YY_INPUT(buf, res, buflen) (res = qry_yy_input(buf, buflen)) +%} + +%option prefix="qry_" + +%% +["][^"]*["] { qry_lval.s = rnd_strdup(yytext+1); qry_lval.s[strlen(qry_lval.s)-1] = '\0'; return T_QSTR; /*"*/ } +['][^']*['] { qry_lval.s = rnd_strdup(yytext+1); qry_lval.s[strlen(qry_lval.s)-1] = '\0'; return T_QSTR; } + +let { return T_LET; } +assert { return T_ASSERT; } +rule { return T_RULE; } +function { return T_FUNCTION; } +return { return T_RETURN; } +list { return T_LIST; } +invalid { return T_INVALID; } +p[.] { return T_FLD_P; } +a[.] { return T_FLD_A; } +flag[.] { return T_FLD_FLAG; } + +"LINE_POINT" { qry_lval.n = make_constant(yytext, PCB_OBJ_LINE_POINT); return T_CONST; } +"POLY_POINT" { qry_lval.n = make_constant(yytext, PCB_OBJ_POLY_POINT); return T_CONST; } +"LINE" { qry_lval.n = make_constant(yytext, PCB_OBJ_LINE); return T_CONST; } +"TEXT" { qry_lval.n = make_constant(yytext, PCB_OBJ_TEXT); return T_CONST; } +"POLYGON" { qry_lval.n = make_constant(yytext, PCB_OBJ_POLY); return T_CONST; } +"ARC" { qry_lval.n = make_constant(yytext, PCB_OBJ_ARC); return T_CONST; } +"GFX" { qry_lval.n = make_constant(yytext, PCB_OBJ_GFX); return T_CONST; } +"RAT" { qry_lval.n = make_constant(yytext, PCB_OBJ_RAT); return T_CONST; } +"PADSTACK" { qry_lval.n = make_constant(yytext, PCB_OBJ_PSTK); return T_CONST; } +"PSTK" { qry_lval.n = make_constant(yytext, PCB_OBJ_PSTK); return T_CONST; } +"SUBC" { qry_lval.n = make_constant(yytext, PCB_OBJ_SUBC); return T_CONST; } +"SUBCIRCUIT" { qry_lval.n = make_constant(yytext, PCB_OBJ_SUBC); return T_CONST; } +"NET" { qry_lval.n = make_constant(yytext, PCB_OBJ_NET); return T_CONST; } +"LAYER" { qry_lval.n = make_constant(yytext, PCB_OBJ_LAYER); return T_CONST; } +"LAYERGRP" { qry_lval.n = make_constant(yytext, PCB_OBJ_LAYERGRP); return T_CONST; } + +"TRUE" { qry_lval.n = make_constant(yytext, 1); return T_CONST; } +"VISIBLE" { qry_lval.n = make_constant(yytext, 1); return T_CONST; } +"ON" { qry_lval.n = make_constant(yytext, 1); return T_CONST; } +"YES" { qry_lval.n = make_constant(yytext, 1); return T_CONST; } + +"FALSE" { qry_lval.n = make_constant(yytext, 0); return T_CONST; } +"INVISIBLE" { qry_lval.n = make_constant(yytext, 0); return T_CONST; } +"OFF" { qry_lval.n = make_constant(yytext, 0); return T_CONST; } +"NO" { qry_lval.n = make_constant(yytext, 0); return T_CONST; } + +"TOP" { qry_lval.n = make_constant(yytext, PCB_LYT_TOP); return T_CONST; } +"BOTTOM" { qry_lval.n = make_constant(yytext, PCB_LYT_BOTTOM); return T_CONST; } +"INTERN" { qry_lval.n = make_constant(yytext, PCB_LYT_INTERN); return T_CONST; } +"INTERNAL" { qry_lval.n = make_constant(yytext, PCB_LYT_INTERN); return T_CONST; } +"COPPER" { qry_lval.n = make_constant(yytext, PCB_LYT_COPPER); return T_CONST; } +"SILK" { qry_lval.n = make_constant(yytext, PCB_LYT_SILK); return T_CONST; } +"MASK" { qry_lval.n = make_constant(yytext, PCB_LYT_MASK); return T_CONST; } +"PASTE" { qry_lval.n = make_constant(yytext, PCB_LYT_PASTE); return T_CONST; } +"MECH" { qry_lval.n = make_constant(yytext, PCB_LYT_MECH); return T_CONST; } +"DOC" { qry_lval.n = make_constant(yytext, PCB_LYT_DOC); return T_CONST; } +"BOUNDARY" { qry_lval.n = make_constant(yytext, PCB_LYT_BOUNDARY); return T_CONST; } + +"DRCGRP1" { qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_GRP1]); return T_CONST; } +"DRCGRP2" { qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_GRP2]); return T_CONST; } +"DRCEXPECT" { qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_EXPECT]); return T_CONST; } +"DRCMEASURE" { qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_MEASURE]); return T_CONST; } +"DRCTEXT" { qry_lval.n = make_const_obj(yytext, &pcb_qry_drc_ctrl[PCB_QRY_DRC_TEXT]); return T_CONST; } + +"$dwg_area_x" { qry_lval.c = PCB->hidlib.size_x; return T_INT; } +"$dwg_area_y" { qry_lval.c = PCB->hidlib.size_y; return T_INT; } + +mm { qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_MM); return T_UNIT; } +m { qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_M); return T_UNIT; } +um { qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_UM); return T_UNIT; } +cm { qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_CM); return T_UNIT; } +nm { qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_NM); return T_UNIT; } +mil { qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_MIL); return T_UNIT; } +inch { qry_lval.u = rnd_get_unit_struct_by_allow(RND_UNIT_ALLOW_IN); return T_UNIT; } + +thus { return T_THUS; } +[|][|] { return T_OR; } +[&][&] { return T_AND; } +[=][=] { return T_EQ; } +[!][=] { return T_NEQ; } +[>][=] { return T_GTEQ; } +[<][=] { return T_LTEQ; } + +[0-9]+ { qry_lval.c = strtol(yytext, NULL, 10); return T_INT; } +[.][0-9]+ { qry_lval.d = strtod(yytext, NULL); return T_DBL; } +[0-9]+[.][0-9]* { qry_lval.d = strtod(yytext, NULL); return T_DBL; } +[A-Za-z_][0-9A-Za-z_]* { qry_lval.s = rnd_strdup(yytext); return T_STR; } + +[$@().,<>!*+/~-] { return *yytext; } + +[\\][\r\n] { continue; /* multiline rules */} +[;\r\n]* { return T_NL; } +[ \t] { continue; } + +%% + +static int qry_yy_input(char *buf, int buflen) +{ + int len; + for(len = 0; (*pcb_qry_program_ptr != '\0') && (buflen > 0); len++,buflen--) { +/* printf("IN: '%c'\n", *pcb_qry_program_ptr);*/ + *buf = *pcb_qry_program_ptr; + buf++; + pcb_qry_program_ptr++; + } + return len; +} + +void pcb_qry_set_input(const char *script) +{ + while(isspace(*script)) script++; + pcb_qry_program = pcb_qry_program_ptr = script; +} + +static pcb_qry_node_t *make_constant(char *str, long val) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_CONST); + res->data.str = rnd_strdup(str); + res->precomp.cnst = val; + return res; +} + +static pcb_qry_node_t *make_const_obj(char *str, pcb_any_obj_t *o) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_OBJ); + res->data.str = rnd_strdup(str); + res->precomp.obj = o; + return res; +} Index: tags/2.3.0/src_plugins/query/query_y.c =================================================================== --- tags/2.3.0/src_plugins/query/query_y.c (nonexistent) +++ tags/2.3.0/src_plugins/query/query_y.c (revision 33253) @@ -0,0 +1,2332 @@ +/* A Bison parser, made by GNU Bison 3.3.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. + + 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 3 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, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.3.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + +/* Substitute the variable and function names. */ +#define yyparse qry_parse +#define yylex qry_lex +#define yyerror qry_error +#define yydebug qry_debug +#define yynerrs qry_nerrs + +#define yylval qry_lval +#define yychar qry_char + +/* First part of user prologue. */ +#line 1 "query_y.y" /* yacc.c:337 */ + +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Query language - compiler: grammar */ + +#include +#include +#include +#include +#include "query.h" +#include "query_l.h" +#include +#include "flag_str.h" +#include "fields_sphash.h" + +#define UNIT_CONV(dst, negative, val, unit) \ +do { \ + dst = val; \ + if (negative) \ + dst = -dst; \ + if (unit != NULL) { \ + if (unit->family == RND_UNIT_IMPERIAL) \ + dst = RND_MIL_TO_COORD(dst); \ + else if (unit->family == RND_UNIT_METRIC) \ + dst = RND_MM_TO_COORD(dst); \ + dst /= unit->scale_factor; \ + } \ +} while(0) + +#define BINOP(dst, op1, operator, op2) \ +do { \ + assert(op2->next == NULL); \ + assert(op2->next == NULL); \ + dst = pcb_qry_n_alloc(operator); \ + pcb_qry_n_insert(dst, op2); \ + pcb_qry_n_insert(dst, op1); \ +} while(0) + +#define UNOP(dst, operator, op) \ +do { \ + assert(op->next == NULL); \ + dst = pcb_qry_n_alloc(operator); \ + pcb_qry_n_insert(dst, op); \ +} while(0) + +static pcb_query_iter_t *iter_ctx; +static vti0_t *iter_active_ctx; +static htsp_t *user_funcs; + +static char *attrib_prepend_free(char *orig, char *prep, char sep) +{ + int l1 = strlen(orig), l2 = strlen(prep); + char *res = malloc(l1+l2+2); + memcpy(res, prep, l2); + res[l2] = sep; + memcpy(res+l2+1, orig, l1+1); + free(orig); + free(prep); + return res; +} + +static pcb_qry_node_t *make_regex_free(char *str) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_REGEX); + res->data.str = str; + res->precomp.regex = re_se_comp(str); + if (res->precomp.regex == NULL) + yyerror(NULL, "Invalid regex\n"); + return res; +} + + +static pcb_qry_node_t *make_flag_free(char *str) +{ + const pcb_flag_bits_t *i = pcb_strflg_name(str, 0x7FFFFFFF); + pcb_qry_node_t *nd; + + if (i == NULL) { + yyerror(NULL, "Unknown flag"); + free(str); + return NULL; + } + + nd = pcb_qry_n_alloc(PCBQ_FLAG); + nd->precomp.flg = i; + free(str); + return nd; +} + +static void link_user_funcs_(pcb_qry_node_t *root, int allow) +{ + pcb_qry_node_t *n, *f, *fname; + + for(n = root; n != NULL; n = n->next) { + if (pcb_qry_nodetype_has_children(n->type)) + link_user_funcs_(n->data.children, allow); + if (n->type == PCBQ_FCALL) { + fname = n->data.children; + if (fname->precomp.fnc.bui != NULL) /* builtin */ + continue; + + if (user_funcs != NULL) + f = htsp_get(user_funcs, fname->data.str); + else + f = NULL; + + fname->precomp.fnc.uf = f; + if (f == NULL) { + yyerror(NULL, "user function not defined:"); + yyerror(NULL, fname->data.str); + } + } + } + +} + +static void link_user_funcs(pcb_qry_node_t *root, int allow) +{ + link_user_funcs_(root, allow); + + if (user_funcs != NULL) + htsp_free(user_funcs); + user_funcs = NULL; +} + + + +#line 231 "query_y.c" /* yacc.c:337 */ +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "query_y.h". */ +#ifndef YY_QRY_QUERY_Y_H_INCLUDED +# define YY_QRY_QUERY_Y_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int qry_debug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + T_LET = 258, + T_ASSERT = 259, + T_RULE = 260, + T_LIST = 261, + T_INVALID = 262, + T_FLD_P = 263, + T_FLD_A = 264, + T_FLD_FLAG = 265, + T_FUNCTION = 266, + T_RETURN = 267, + T_OR = 268, + T_AND = 269, + T_EQ = 270, + T_NEQ = 271, + T_GTEQ = 272, + T_LTEQ = 273, + T_NL = 274, + T_UNIT = 275, + T_STR = 276, + T_QSTR = 277, + T_INT = 278, + T_DBL = 279, + T_CONST = 280, + T_THUS = 281 + }; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 158 "query_y.y" /* yacc.c:352 */ + + char *s; + rnd_coord_t c; + double d; + const rnd_unit_t *u; + pcb_qry_node_t *n; + +#line 309 "query_y.c" /* yacc.c:352 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE qry_lval; + +int qry_parse (pcb_qry_node_t **prg_out); + +#endif /* !YY_QRY_QUERY_Y_H_INCLUDED */ + + + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 14 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 249 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 41 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 32 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 80 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 134 + +#define YYUNDEFTOK 2 +#define YYMAXUTOK 281 + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 34, 2, 2, 39, 2, 2, 2, + 35, 36, 31, 29, 40, 30, 33, 32, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 27, 2, 28, 2, 38, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 37, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26 +}; + +#if YYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 199, 199, 200, 205, 205, 218, 219, 223, 231, + 232, 244, 245, 246, 247, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 287, 288, 289, 290, 294, 298, 299, 303, 304, 305, + 306, 307, 311, 312, 313, 318, 317, 337, 336, 351, + 350, 364, 365, 366, 367, 372, 392, 393, 397, 412, + 413, 418, 425, 426, 430, 437, 438, 443, 442, 464, + 465 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 1 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "T_LET", "T_ASSERT", "T_RULE", "T_LIST", + "T_INVALID", "T_FLD_P", "T_FLD_A", "T_FLD_FLAG", "T_FUNCTION", + "T_RETURN", "T_OR", "T_AND", "T_EQ", "T_NEQ", "T_GTEQ", "T_LTEQ", "T_NL", + "T_UNIT", "T_STR", "T_QSTR", "T_INT", "T_DBL", "T_CONST", "T_THUS", + "'<'", "'>'", "'+'", "'-'", "'*'", "'/'", "'.'", "'!'", "'('", "')'", + "'~'", "'@'", "'$'", "','", "$accept", "program", "program_expr", "$@1", + "program_rules", "rule", "rule_or_fdef", "rule_item", "expr", "number", + "string_literal", "maybe_unit", "fields", "attribs", "let", "$@2", + "assert", "$@3", "freturn", "$@4", "var", "constant", "fcall", + "fcallname", "fargs", "fdefarg", "fdefargs", "fdefname", "fdef_", "fdef", + "$@5", "words", YY_NULLPTR +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 60, 62, 43, + 45, 42, 47, 46, 33, 40, 41, 126, 64, 36, + 44 +}; +# endif + +#define YYPACT_NINF -90 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-90))) + +#define YYTABLE_NINF -69 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + 4, -11, -7, 16, -90, 34, -90, 2, 13, -90, + -11, -90, -90, -90, -90, 1, -90, 28, -90, 45, + 45, -90, 85, 34, 34, -90, 46, 114, -90, -90, + -90, -90, -90, 75, -90, 27, -90, 88, -10, -90, + -90, -90, 45, 45, 87, 89, -90, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 62, 78, -1, -90, -90, -90, -90, 94, 115, 116, + -19, -90, 97, 100, -90, -90, -90, 163, 186, 203, + 203, 212, 212, 139, 212, 212, 29, 29, -25, -25, + 76, 90, 104, -90, -90, -90, -90, 61, 102, 118, + 34, 34, 27, 27, 27, -90, -90, 108, 113, -90, + -90, 129, -90, 125, -90, -90, 62, 34, -90, 34, + 114, 114, -90, -90, -90, 138, -90, -90, 90, -90, + -90, 114, -90, -90 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 4, 79, 0, 0, 3, 0, 2, 6, 0, 9, + 79, 10, 74, 77, 1, 0, 18, 61, 44, 45, + 45, 36, 0, 0, 0, 64, 0, 5, 16, 17, + 37, 38, 15, 0, 7, 11, 80, 0, 0, 46, + 40, 41, 45, 45, 19, 0, 65, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 55, 57, 59, 8, 0, 0, 0, + 0, 78, 0, 0, 42, 43, 20, 23, 22, 24, + 25, 26, 27, 21, 29, 28, 30, 31, 32, 33, + 0, 0, 47, 39, 34, 35, 67, 69, 0, 0, + 0, 0, 11, 11, 11, 71, 76, 72, 0, 63, + 62, 0, 49, 52, 54, 51, 0, 0, 66, 0, + 58, 60, 13, 12, 14, 0, 75, 50, 0, 48, + 70, 56, 73, 53 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -90, -90, -90, -90, 153, -90, -90, -22, -5, -90, + -90, -17, -89, 33, -90, -90, -90, -90, -90, -90, + -90, -90, -90, -90, 47, 37, -90, -90, -90, -90, + -90, 155 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 3, 4, 5, 6, 7, 8, 66, 97, 28, + 29, 40, 93, 115, 67, 99, 68, 100, 69, 101, + 30, 31, 32, 33, 98, 107, 108, 13, 71, 9, + 37, 11 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = +{ + 27, 112, 105, 41, -6, 15, 16, 1, 60, 1, + 10, 72, 61, 2, 12, 2, 14, 106, 44, 45, + 17, 18, 19, 20, 21, 74, 75, 129, 73, 22, + 63, 64, 35, 23, 24, 96, 38, 25, 26, 65, + 15, 16, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 17, 18, 19, 20, 21, + 58, 59, 60, -68, 22, 39, 61, 46, 23, 24, + 90, 91, 25, 26, 47, 48, 49, 50, 51, 52, + 122, 123, 124, 92, 90, 91, 111, 53, 54, 55, + 56, 57, 58, 59, 60, 120, 121, 92, 61, 94, + 95, 117, 47, 48, 49, 50, 51, 52, 42, 43, + 62, 113, 114, 102, 131, 53, 54, 55, 56, 57, + 58, 59, 60, 70, 61, 76, 61, 47, 48, 49, + 50, 51, 52, 109, 103, 104, 110, 116, 118, 119, + 53, 54, 55, 56, 57, 58, 59, 60, 125, 126, + 127, 61, 47, 48, 49, 50, 51, 52, 128, 105, + 34, 133, 132, 0, 130, 36, 54, 55, 56, 57, + 58, 59, 60, 0, 0, 0, 61, 48, 49, 50, + 51, 52, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 55, 56, 57, 58, 59, 60, 0, 0, 0, + 61, 49, 50, 51, 52, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 55, 56, 57, 58, 59, 60, + 51, 52, 0, 61, 0, 0, 0, 0, 0, 0, + 54, 55, 56, 57, 58, 59, 60, 0, 0, 0, + 61, 56, 57, 58, 59, 60, 0, 0, 0, 61 +}; + +static const yytype_int16 yycheck[] = +{ + 5, 90, 21, 20, 0, 6, 7, 5, 33, 5, + 21, 21, 37, 11, 21, 11, 0, 36, 23, 24, + 21, 22, 23, 24, 25, 42, 43, 116, 38, 30, + 3, 4, 19, 34, 35, 36, 35, 38, 39, 12, + 6, 7, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 21, 22, 23, 24, 25, + 31, 32, 33, 35, 30, 20, 37, 21, 34, 35, + 8, 9, 38, 39, 13, 14, 15, 16, 17, 18, + 102, 103, 104, 21, 8, 9, 10, 26, 27, 28, + 29, 30, 31, 32, 33, 100, 101, 21, 37, 21, + 22, 40, 13, 14, 15, 16, 17, 18, 23, 24, + 35, 21, 22, 19, 119, 26, 27, 28, 29, 30, + 31, 32, 33, 35, 37, 36, 37, 13, 14, 15, + 16, 17, 18, 36, 19, 19, 36, 33, 36, 21, + 26, 27, 28, 29, 30, 31, 32, 33, 40, 36, + 21, 37, 13, 14, 15, 16, 17, 18, 33, 21, + 7, 128, 125, -1, 117, 10, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, 37, 14, 15, 16, + 17, 18, -1, -1, -1, -1, -1, -1, -1, -1, + 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, + 37, 15, 16, 17, 18, -1, -1, -1, -1, -1, + -1, -1, -1, 27, 28, 29, 30, 31, 32, 33, + 17, 18, -1, 37, -1, -1, -1, -1, -1, -1, + 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, + 37, 29, 30, 31, 32, 33, -1, -1, -1, 37 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 5, 11, 42, 43, 44, 45, 46, 47, 70, + 21, 72, 21, 68, 0, 6, 7, 21, 22, 23, + 24, 25, 30, 34, 35, 38, 39, 49, 50, 51, + 61, 62, 63, 64, 45, 19, 72, 71, 35, 20, + 52, 52, 23, 24, 49, 49, 21, 13, 14, 15, + 16, 17, 18, 26, 27, 28, 29, 30, 31, 32, + 33, 37, 35, 3, 4, 12, 48, 55, 57, 59, + 35, 69, 21, 38, 52, 52, 36, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 8, 9, 21, 53, 21, 22, 36, 49, 65, 56, + 58, 60, 19, 19, 19, 21, 36, 66, 67, 36, + 36, 10, 53, 21, 22, 54, 33, 40, 36, 21, + 49, 49, 48, 48, 48, 40, 36, 21, 33, 53, + 65, 49, 66, 54 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 41, 42, 42, 44, 43, 45, 45, 46, 47, + 47, 48, 48, 48, 48, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 50, 50, 50, 50, 51, 52, 52, 53, 53, 53, + 53, 53, 54, 54, 54, 56, 55, 58, 57, 60, + 59, 61, 61, 61, 61, 62, 63, 63, 64, 65, + 65, 66, 67, 67, 68, 69, 69, 71, 70, 72, + 72 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 1, 0, 2, 0, 2, 3, 1, + 2, 0, 3, 3, 3, 1, 1, 1, 1, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 1, 1, 1, 3, + 2, 2, 3, 3, 1, 0, 1, 1, 3, 2, + 3, 2, 1, 3, 1, 0, 4, 0, 3, 0, + 3, 1, 4, 4, 1, 2, 4, 3, 1, 1, + 3, 1, 1, 3, 1, 3, 2, 0, 4, 0, + 2 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (prg_out, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, prg_out); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, pcb_qry_node_t **prg_out) +{ + FILE *yyoutput = yyo; + YYUSE (yyoutput); + YYUSE (prg_out); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); +# endif + YYUSE (yytype); +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, pcb_qry_node_t **prg_out) +{ + YYFPRINTF (yyo, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyo, yytype, yyvaluep, prg_out); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, pcb_qry_node_t **prg_out) +{ + unsigned long yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &yyvsp[(yyi + 1) - (yynrhs)] + , prg_out); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule, prg_out); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +yystrlen (const char *yystr) +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return 2; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, pcb_qry_node_t **prg_out) +{ + YYUSE (yyvaluep); + YYUSE (prg_out); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (pcb_qry_node_t **prg_out) +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yynewstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + *yyssp = (yytype_int16) yystate; + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + goto yyexhaustedlab; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 199 "query_y.y" /* yacc.c:1652 */ + { *prg_out = (yyvsp[0].n); link_user_funcs((yyvsp[0].n), 1); } +#line 1524 "query_y.c" /* yacc.c:1652 */ + break; + + case 3: +#line 200 "query_y.y" /* yacc.c:1652 */ + { *prg_out = (yyvsp[0].n); assert(user_funcs == NULL); link_user_funcs((yyvsp[0].n), 0); } +#line 1530 "query_y.c" /* yacc.c:1652 */ + break; + + case 4: +#line 205 "query_y.y" /* yacc.c:1652 */ + { iter_ctx = pcb_qry_iter_alloc(); } +#line 1536 "query_y.c" /* yacc.c:1652 */ + break; + + case 5: +#line 206 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_EXPR_PROG); + (yyval.n)->data.children = pcb_qry_n_alloc(PCBQ_ITER_CTX); + (yyval.n)->data.children->parent = (yyval.n); + (yyval.n)->data.children->data.iter_ctx = iter_ctx; + (yyval.n)->data.children->next = (yyvsp[0].n); + (yyvsp[0].n)->parent = (yyval.n); + } +#line 1549 "query_y.c" /* yacc.c:1652 */ + break; + + case 6: +#line 218 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = NULL; } +#line 1555 "query_y.c" /* yacc.c:1652 */ + break; + + case 7: +#line 219 "query_y.y" /* yacc.c:1652 */ + { if ((yyvsp[-1].n) != NULL) { (yyval.n) = (yyvsp[-1].n); (yyvsp[-1].n)->next = (yyvsp[0].n); } else { (yyval.n) = (yyvsp[0].n); } } +#line 1561 "query_y.c" /* yacc.c:1652 */ + break; + + case 8: +#line 223 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = (yyvsp[-2].n); + if ((yyvsp[0].n) != NULL) + pcb_qry_n_append((yyval.n), (yyvsp[0].n)); + } +#line 1571 "query_y.c" /* yacc.c:1652 */ + break; + + case 9: +#line 231 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1577 "query_y.c" /* yacc.c:1652 */ + break; + + case 10: +#line 232 "query_y.y" /* yacc.c:1652 */ + { + pcb_qry_node_t *nd; + iter_ctx = pcb_qry_iter_alloc(); + (yyval.n) = pcb_qry_n_alloc(PCBQ_RULE); + pcb_qry_n_insert((yyval.n), (yyvsp[0].n)); + nd = pcb_qry_n_alloc(PCBQ_ITER_CTX); + nd->data.iter_ctx = iter_ctx; + pcb_qry_n_insert((yyval.n), nd); + } +#line 1591 "query_y.c" /* yacc.c:1652 */ + break; + + case 11: +#line 244 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = NULL; } +#line 1597 "query_y.c" /* yacc.c:1652 */ + break; + + case 12: +#line 245 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-2].n); (yyvsp[-2].n)->next = (yyvsp[0].n); } +#line 1603 "query_y.c" /* yacc.c:1652 */ + break; + + case 13: +#line 246 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-2].n); (yyvsp[-2].n)->next = (yyvsp[0].n); } +#line 1609 "query_y.c" /* yacc.c:1652 */ + break; + + case 14: +#line 247 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-2].n); (yyvsp[-2].n)->next = (yyvsp[0].n); } +#line 1615 "query_y.c" /* yacc.c:1652 */ + break; + + case 15: +#line 251 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1621 "query_y.c" /* yacc.c:1652 */ + break; + + case 16: +#line 252 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1627 "query_y.c" /* yacc.c:1652 */ + break; + + case 17: +#line 253 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1633 "query_y.c" /* yacc.c:1652 */ + break; + + case 18: +#line 254 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_INVALID); } +#line 1639 "query_y.c" /* yacc.c:1652 */ + break; + + case 19: +#line 255 "query_y.y" /* yacc.c:1652 */ + { UNOP((yyval.n), PCBQ_OP_NOT, (yyvsp[0].n)); } +#line 1645 "query_y.c" /* yacc.c:1652 */ + break; + + case 20: +#line 256 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-1].n); } +#line 1651 "query_y.c" /* yacc.c:1652 */ + break; + + case 21: +#line 257 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_THUS, (yyvsp[0].n)); } +#line 1657 "query_y.c" /* yacc.c:1652 */ + break; + + case 22: +#line 258 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_AND, (yyvsp[0].n)); } +#line 1663 "query_y.c" /* yacc.c:1652 */ + break; + + case 23: +#line 259 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_OR, (yyvsp[0].n)); } +#line 1669 "query_y.c" /* yacc.c:1652 */ + break; + + case 24: +#line 260 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_EQ, (yyvsp[0].n)); } +#line 1675 "query_y.c" /* yacc.c:1652 */ + break; + + case 25: +#line 261 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_NEQ, (yyvsp[0].n)); } +#line 1681 "query_y.c" /* yacc.c:1652 */ + break; + + case 26: +#line 262 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_GTEQ, (yyvsp[0].n)); } +#line 1687 "query_y.c" /* yacc.c:1652 */ + break; + + case 27: +#line 263 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_LTEQ, (yyvsp[0].n)); } +#line 1693 "query_y.c" /* yacc.c:1652 */ + break; + + case 28: +#line 264 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_GT, (yyvsp[0].n)); } +#line 1699 "query_y.c" /* yacc.c:1652 */ + break; + + case 29: +#line 265 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_LT, (yyvsp[0].n)); } +#line 1705 "query_y.c" /* yacc.c:1652 */ + break; + + case 30: +#line 266 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_ADD, (yyvsp[0].n)); } +#line 1711 "query_y.c" /* yacc.c:1652 */ + break; + + case 31: +#line 267 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_SUB, (yyvsp[0].n)); } +#line 1717 "query_y.c" /* yacc.c:1652 */ + break; + + case 32: +#line 268 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_MUL, (yyvsp[0].n)); } +#line 1723 "query_y.c" /* yacc.c:1652 */ + break; + + case 33: +#line 269 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_DIV, (yyvsp[0].n)); } +#line 1729 "query_y.c" /* yacc.c:1652 */ + break; + + case 34: +#line 270 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_MATCH, make_regex_free((yyvsp[0].s))); } +#line 1735 "query_y.c" /* yacc.c:1652 */ + break; + + case 35: +#line 271 "query_y.y" /* yacc.c:1652 */ + { BINOP((yyval.n), (yyvsp[-2].n), PCBQ_OP_MATCH, make_regex_free((yyvsp[0].s))); } +#line 1741 "query_y.c" /* yacc.c:1652 */ + break; + + case 36: +#line 272 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1747 "query_y.c" /* yacc.c:1652 */ + break; + + case 37: +#line 273 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1753 "query_y.c" /* yacc.c:1652 */ + break; + + case 38: +#line 274 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 1759 "query_y.c" /* yacc.c:1652 */ + break; + + case 39: +#line 275 "query_y.y" /* yacc.c:1652 */ + { + pcb_qry_node_t *n; + (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD_OF); + (yyval.n)->data.children = (yyvsp[-2].n); + (yyvsp[-2].n)->next = (yyvsp[0].n); + (yyvsp[-2].n)->parent = (yyval.n); + for(n = (yyvsp[0].n); n != NULL; n = n->next) + n->parent = (yyval.n); + } +#line 1773 "query_y.c" /* yacc.c:1652 */ + break; + + case 40: +#line 287 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_COORD); UNIT_CONV((yyval.n)->data.crd, 0, (yyvsp[-1].c), (yyvsp[0].u)); } +#line 1779 "query_y.c" /* yacc.c:1652 */ + break; + + case 41: +#line 288 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_DOUBLE); UNIT_CONV((yyval.n)->data.dbl, 0, (yyvsp[-1].d), (yyvsp[0].u)); } +#line 1785 "query_y.c" /* yacc.c:1652 */ + break; + + case 42: +#line 289 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_COORD); UNIT_CONV((yyval.n)->data.crd, 1, (yyvsp[-1].c), (yyvsp[0].u)); } +#line 1791 "query_y.c" /* yacc.c:1652 */ + break; + + case 43: +#line 290 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_DOUBLE); UNIT_CONV((yyval.n)->data.dbl, 1, (yyvsp[-1].d), (yyvsp[0].u)); } +#line 1797 "query_y.c" /* yacc.c:1652 */ + break; + + case 44: +#line 294 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_DATA_STRING); (yyval.n)->data.str = (yyvsp[0].s); } +#line 1803 "query_y.c" /* yacc.c:1652 */ + break; + + case 45: +#line 298 "query_y.y" /* yacc.c:1652 */ + { (yyval.u) = NULL; } +#line 1809 "query_y.c" /* yacc.c:1652 */ + break; + + case 46: +#line 299 "query_y.y" /* yacc.c:1652 */ + { (yyval.u) = (yyvsp[0].u); } +#line 1815 "query_y.c" /* yacc.c:1652 */ + break; + + case 47: +#line 303 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = (yyvsp[0].s); (yyval.n)->precomp.fld = query_fields_sphash((yyvsp[0].s)); } +#line 1821 "query_y.c" /* yacc.c:1652 */ + break; + + case 48: +#line 304 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = (yyvsp[-2].s); (yyval.n)->precomp.fld = query_fields_sphash((yyvsp[-2].s)); (yyval.n)->next = (yyvsp[0].n); } +#line 1827 "query_y.c" /* yacc.c:1652 */ + break; + + case 49: +#line 305 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); /* just ignore .p. */ } +#line 1833 "query_y.c" /* yacc.c:1652 */ + break; + + case 50: +#line 306 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = make_flag_free((yyvsp[0].s)); } +#line 1839 "query_y.c" /* yacc.c:1652 */ + break; + + case 51: +#line 307 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = rnd_strdup("a"); (yyval.n)->precomp.fld = query_fields_sphash("a"); (yyval.n)->next = (yyvsp[0].n); } +#line 1845 "query_y.c" /* yacc.c:1652 */ + break; + + case 52: +#line 311 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = (yyvsp[0].s); } +#line 1851 "query_y.c" /* yacc.c:1652 */ + break; + + case 53: +#line 312 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = attrib_prepend_free((char *)(yyvsp[0].n)->data.str, (yyvsp[-2].s), '.'); } +#line 1857 "query_y.c" /* yacc.c:1652 */ + break; + + case 54: +#line 313 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FIELD); (yyval.n)->data.str = (yyvsp[0].s); } +#line 1863 "query_y.c" /* yacc.c:1652 */ + break; + + case 55: +#line 318 "query_y.y" /* yacc.c:1652 */ + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } +#line 1871 "query_y.c" /* yacc.c:1652 */ + break; + + case 56: +#line 322 "query_y.y" /* yacc.c:1652 */ + { + pcb_qry_node_t *nd; + (yyval.n) = pcb_qry_n_alloc(PCBQ_LET); + (yyval.n)->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert((yyval.n), (yyvsp[0].n)); + nd = pcb_qry_n_alloc(PCBQ_VAR); + nd->data.crd = pcb_qry_iter_var(iter_ctx, (yyvsp[-1].s), 1); + pcb_qry_n_insert((yyval.n), nd); + free((yyvsp[-1].s)); + } +#line 1887 "query_y.c" /* yacc.c:1652 */ + break; + + case 57: +#line 337 "query_y.y" /* yacc.c:1652 */ + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } +#line 1895 "query_y.c" /* yacc.c:1652 */ + break; + + case 58: +#line 341 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_ASSERT); + (yyval.n)->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert((yyval.n), (yyvsp[0].n)); + } +#line 1906 "query_y.c" /* yacc.c:1652 */ + break; + + case 59: +#line 351 "query_y.y" /* yacc.c:1652 */ + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } +#line 1914 "query_y.c" /* yacc.c:1652 */ + break; + + case 60: +#line 355 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_RETURN); + (yyval.n)->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert((yyval.n), (yyvsp[0].n)); + } +#line 1925 "query_y.c" /* yacc.c:1652 */ + break; + + case 61: +#line 364 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_VAR); (yyval.n)->data.crd = pcb_qry_iter_var(iter_ctx, (yyvsp[0].s), 1); if (iter_active_ctx != NULL) vti0_set(iter_active_ctx, (yyval.n)->data.crd, 1); free((yyvsp[0].s)); } +#line 1931 "query_y.c" /* yacc.c:1652 */ + break; + + case 62: +#line 365 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_LISTVAR); (yyval.n)->data.str = rnd_strdup("@"); /* delibertely not setting iter_active, list() protects against turning it into an iterator */ } +#line 1937 "query_y.c" /* yacc.c:1652 */ + break; + + case 63: +#line 366 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_LISTVAR); (yyval.n)->data.str = (yyvsp[-1].s); /* delibertely not setting iter_active, list() protects against turning it into an iterator */ } +#line 1943 "query_y.c" /* yacc.c:1652 */ + break; + + case 64: +#line 367 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_VAR); (yyval.n)->data.crd = pcb_qry_iter_var(iter_ctx, "@", 1); if (iter_active_ctx != NULL) vti0_set(iter_active_ctx, (yyval.n)->data.crd, 1); } +#line 1949 "query_y.c" /* yacc.c:1652 */ + break; + + case 65: +#line 373 "query_y.y" /* yacc.c:1652 */ + { + pcb_qry_node_t *fname, *nname; + + nname = pcb_qry_n_alloc(PCBQ_DATA_STRING); + nname->data.str = rnd_concat("design/drc/", (yyvsp[0].s), NULL); + free((yyvsp[0].s)); + + fname = pcb_qry_n_alloc(PCBQ_FNAME); + fname->data.str = NULL; + fname->precomp.fnc.bui = pcb_qry_fnc_lookup("getconf"); + + (yyval.n) = pcb_qry_n_alloc(PCBQ_FCALL); + fname->parent = nname->parent = (yyval.n); + (yyval.n)->data.children = fname; + (yyval.n)->data.children->next = nname; + } +#line 1970 "query_y.c" /* yacc.c:1652 */ + break; + + case 66: +#line 392 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FCALL); (yyval.n)->data.children = (yyvsp[-3].n); (yyval.n)->data.children->next = (yyvsp[-1].n); (yyvsp[-3].n)->parent = (yyvsp[-1].n)->parent = (yyval.n); } +#line 1976 "query_y.c" /* yacc.c:1652 */ + break; + + case 67: +#line 393 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_FCALL); (yyval.n)->data.children = (yyvsp[-2].n); (yyvsp[-2].n)->parent = (yyval.n); } +#line 1982 "query_y.c" /* yacc.c:1652 */ + break; + + case 68: +#line 397 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_FNAME); + (yyval.n)->precomp.fnc.bui = pcb_qry_fnc_lookup((yyvsp[0].s)); + if ((yyval.n)->precomp.fnc.bui != NULL) { + /* builtin function */ + free((yyvsp[0].s)); + (yyval.n)->data.str = NULL; + } + else + (yyval.n)->data.str = (yyvsp[0].s); /* user function: save the name */ + } +#line 1998 "query_y.c" /* yacc.c:1652 */ + break; + + case 69: +#line 412 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 2004 "query_y.c" /* yacc.c:1652 */ + break; + + case 70: +#line 413 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-2].n); (yyval.n)->next = (yyvsp[0].n); } +#line 2010 "query_y.c" /* yacc.c:1652 */ + break; + + case 71: +#line 418 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_ARG); + (yyval.n)->data.crd = pcb_qry_iter_var(iter_ctx, (yyvsp[0].s), 1); + } +#line 2019 "query_y.c" /* yacc.c:1652 */ + break; + + case 72: +#line 425 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[0].n); } +#line 2025 "query_y.c" /* yacc.c:1652 */ + break; + + case 73: +#line 426 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-2].n); (yyval.n)->next = (yyvsp[0].n); } +#line 2031 "query_y.c" /* yacc.c:1652 */ + break; + + case 74: +#line 430 "query_y.y" /* yacc.c:1652 */ + { + (yyval.n) = pcb_qry_n_alloc(PCBQ_FNAME); + (yyval.n)->data.str = (yyvsp[0].s); + } +#line 2040 "query_y.c" /* yacc.c:1652 */ + break; + + case 75: +#line 437 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = (yyvsp[-1].n); } +#line 2046 "query_y.c" /* yacc.c:1652 */ + break; + + case 76: +#line 438 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = NULL; } +#line 2052 "query_y.c" /* yacc.c:1652 */ + break; + + case 77: +#line 443 "query_y.y" /* yacc.c:1652 */ + { iter_ctx = pcb_qry_iter_alloc(); } +#line 2058 "query_y.c" /* yacc.c:1652 */ + break; + + case 78: +#line 444 "query_y.y" /* yacc.c:1652 */ + { + pcb_qry_node_t *nd; + + (yyval.n) = pcb_qry_n_alloc(PCBQ_FUNCTION); + + if ((yyvsp[0].n) != NULL) + pcb_qry_n_append((yyval.n), (yyvsp[0].n)); + + pcb_qry_n_insert((yyval.n), (yyvsp[-2].n)); + + nd = pcb_qry_n_alloc(PCBQ_ITER_CTX); + nd->data.iter_ctx = iter_ctx; + pcb_qry_n_insert((yyval.n), nd); + + if (user_funcs == NULL) + user_funcs = htsp_alloc(strhash, strkeyeq); + htsp_set(user_funcs, (char *)(yyvsp[-2].n)->data.str, (yyval.n)); + } +#line 2081 "query_y.c" /* yacc.c:1652 */ + break; + + case 79: +#line 464 "query_y.y" /* yacc.c:1652 */ + { (yyval.n) = pcb_qry_n_alloc(PCBQ_RNAME); (yyval.n)->data.str = (const char *)rnd_strdup(""); } +#line 2087 "query_y.c" /* yacc.c:1652 */ + break; + + case 80: +#line 465 "query_y.y" /* yacc.c:1652 */ + { + char *old = (char *)(yyvsp[0].n)->data.str, *sep = ((*old != '\0') ? " " : ""); + (yyvsp[0].n)->data.str = rnd_concat((yyvsp[-1].s), sep, old, NULL); + free(old); + free((yyvsp[-1].s)); + (yyval.n) = (yyvsp[0].n); + } +#line 2099 "query_y.c" /* yacc.c:1652 */ + break; + + +#line 2103 "query_y.c" /* yacc.c:1652 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (prg_out, YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (prg_out, yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, prg_out); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp, prg_out); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (prg_out, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + + +/*-----------------------------------------------------. +| yyreturn -- parsing is finished, return the result. | +`-----------------------------------------------------*/ +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, prg_out); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, prg_out); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} Index: tags/2.3.0/src_plugins/query/query_y.h =================================================================== --- tags/2.3.0/src_plugins/query/query_y.h (nonexistent) +++ tags/2.3.0/src_plugins/query/query_y.h (revision 33253) @@ -0,0 +1,105 @@ +/* A Bison parser, made by GNU Bison 3.3.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation, + Inc. + + 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 3 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, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + +#ifndef YY_QRY_QUERY_Y_H_INCLUDED +# define YY_QRY_QUERY_Y_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int qry_debug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + T_LET = 258, + T_ASSERT = 259, + T_RULE = 260, + T_LIST = 261, + T_INVALID = 262, + T_FLD_P = 263, + T_FLD_A = 264, + T_FLD_FLAG = 265, + T_FUNCTION = 266, + T_RETURN = 267, + T_OR = 268, + T_AND = 269, + T_EQ = 270, + T_NEQ = 271, + T_GTEQ = 272, + T_LTEQ = 273, + T_NL = 274, + T_UNIT = 275, + T_STR = 276, + T_QSTR = 277, + T_INT = 278, + T_DBL = 279, + T_CONST = 280, + T_THUS = 281 + }; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 158 "query_y.y" /* yacc.c:1921 */ + + char *s; + rnd_coord_t c; + double d; + const rnd_unit_t *u; + pcb_qry_node_t *n; + +#line 93 "query_y.h" /* yacc.c:1921 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE qry_lval; + +int qry_parse (pcb_qry_node_t **prg_out); + +#endif /* !YY_QRY_QUERY_Y_H_INCLUDED */ Index: tags/2.3.0/src_plugins/query/query_y.y =================================================================== --- tags/2.3.0/src_plugins/query/query_y.y (nonexistent) +++ tags/2.3.0/src_plugins/query/query_y.y (revision 33253) @@ -0,0 +1,472 @@ +%{ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Query language - compiler: grammar */ + +#include +#include +#include +#include +#include "query.h" +#include "query_l.h" +#include +#include "flag_str.h" +#include "fields_sphash.h" + +#define UNIT_CONV(dst, negative, val, unit) \ +do { \ + dst = val; \ + if (negative) \ + dst = -dst; \ + if (unit != NULL) { \ + if (unit->family == RND_UNIT_IMPERIAL) \ + dst = RND_MIL_TO_COORD(dst); \ + else if (unit->family == RND_UNIT_METRIC) \ + dst = RND_MM_TO_COORD(dst); \ + dst /= unit->scale_factor; \ + } \ +} while(0) + +#define BINOP(dst, op1, operator, op2) \ +do { \ + assert(op2->next == NULL); \ + assert(op2->next == NULL); \ + dst = pcb_qry_n_alloc(operator); \ + pcb_qry_n_insert(dst, op2); \ + pcb_qry_n_insert(dst, op1); \ +} while(0) + +#define UNOP(dst, operator, op) \ +do { \ + assert(op->next == NULL); \ + dst = pcb_qry_n_alloc(operator); \ + pcb_qry_n_insert(dst, op); \ +} while(0) + +static pcb_query_iter_t *iter_ctx; +static vti0_t *iter_active_ctx; +static htsp_t *user_funcs; + +static char *attrib_prepend_free(char *orig, char *prep, char sep) +{ + int l1 = strlen(orig), l2 = strlen(prep); + char *res = malloc(l1+l2+2); + memcpy(res, prep, l2); + res[l2] = sep; + memcpy(res+l2+1, orig, l1+1); + free(orig); + free(prep); + return res; +} + +static pcb_qry_node_t *make_regex_free(char *str) +{ + pcb_qry_node_t *res = pcb_qry_n_alloc(PCBQ_DATA_REGEX); + res->data.str = str; + res->precomp.regex = re_se_comp(str); + if (res->precomp.regex == NULL) + yyerror(NULL, "Invalid regex\n"); + return res; +} + + +static pcb_qry_node_t *make_flag_free(char *str) +{ + const pcb_flag_bits_t *i = pcb_strflg_name(str, 0x7FFFFFFF); + pcb_qry_node_t *nd; + + if (i == NULL) { + yyerror(NULL, "Unknown flag"); + free(str); + return NULL; + } + + nd = pcb_qry_n_alloc(PCBQ_FLAG); + nd->precomp.flg = i; + free(str); + return nd; +} + +static void link_user_funcs_(pcb_qry_node_t *root, int allow) +{ + pcb_qry_node_t *n, *f, *fname; + + for(n = root; n != NULL; n = n->next) { + if (pcb_qry_nodetype_has_children(n->type)) + link_user_funcs_(n->data.children, allow); + if (n->type == PCBQ_FCALL) { + fname = n->data.children; + if (fname->precomp.fnc.bui != NULL) /* builtin */ + continue; + + if (user_funcs != NULL) + f = htsp_get(user_funcs, fname->data.str); + else + f = NULL; + + fname->precomp.fnc.uf = f; + if (f == NULL) { + yyerror(NULL, "user function not defined:"); + yyerror(NULL, fname->data.str); + } + } + } + +} + +static void link_user_funcs(pcb_qry_node_t *root, int allow) +{ + link_user_funcs_(root, allow); + + if (user_funcs != NULL) + htsp_free(user_funcs); + user_funcs = NULL; +} + + +%} + +%name-prefix "qry_" +%error-verbose +%parse-param {pcb_qry_node_t **prg_out} + +%union { + char *s; + rnd_coord_t c; + double d; + const rnd_unit_t *u; + pcb_qry_node_t *n; +} + +%token T_LET T_ASSERT T_RULE T_LIST T_INVALID T_FLD_P T_FLD_A T_FLD_FLAG +%token T_FUNCTION T_RETURN +%token T_OR T_AND T_EQ T_NEQ T_GTEQ T_LTEQ +%token T_NL +%token T_UNIT +%token T_STR T_QSTR +%token T_INT +%token T_DBL +%token T_CONST + +/* the usual binary operators */ +%left T_THUS +%left T_OR +%left T_AND +%left T_EQ T_NEQ +%left '<' '>' T_GTEQ T_LTEQ +%left '+' '-' +%left '*' '/' +%left '.' + +/* Unary operators */ +%right '!' + +%left '(' + +%type number fields attribs let assert var constant fcallname fcall +%type fargs words freturn fdefarg fdefargs fdef_ fdef fdefname rule_or_fdef +%type string_literal expr rule_item program_expr program_rules rule +%type maybe_unit + +%% + +program: + program_rules { *prg_out = $1; link_user_funcs($1, 1); } + | program_expr { *prg_out = $1; assert(user_funcs == NULL); link_user_funcs($1, 0); } + ; + +/* The program is a single expression - useful for search */ +program_expr: + { iter_ctx = pcb_qry_iter_alloc(); } + expr { + $$ = pcb_qry_n_alloc(PCBQ_EXPR_PROG); + $$->data.children = pcb_qry_n_alloc(PCBQ_ITER_CTX); + $$->data.children->parent = $$; + $$->data.children->data.iter_ctx = iter_ctx; + $$->data.children->next = $2; + $2->parent = $$; + } + ; + +/* The program is a collection of rules - useful for the DRC */ +program_rules: + /* empty */ { $$ = NULL; } + | rule program_rules { if ($1 != NULL) { $$ = $1; $1->next = $2; } else { $$ = $2; } } + ; + +rule: + rule_or_fdef T_NL rule_item { + $$ = $1; + if ($3 != NULL) + pcb_qry_n_append($$, $3); + } + ; + +rule_or_fdef: + fdef { $$ = $1; } + | T_RULE words { + pcb_qry_node_t *nd; + iter_ctx = pcb_qry_iter_alloc(); + $$ = pcb_qry_n_alloc(PCBQ_RULE); + pcb_qry_n_insert($$, $2); + nd = pcb_qry_n_alloc(PCBQ_ITER_CTX); + nd->data.iter_ctx = iter_ctx; + pcb_qry_n_insert($$, nd); + } + ; + +rule_item: + /* empty */ { $$ = NULL; } + | assert T_NL rule_item { $$ = $1; $1->next = $3; } + | let T_NL rule_item { $$ = $1; $1->next = $3; } + | freturn T_NL rule_item { $$ = $1; $1->next = $3; } + ; + +expr: + fcall { $$ = $1; } + | number { $$ = $1; } + | string_literal { $$ = $1; } + | T_INVALID { $$ = pcb_qry_n_alloc(PCBQ_DATA_INVALID); } + | '!' expr { UNOP($$, PCBQ_OP_NOT, $2); } + | '(' expr ')' { $$ = $2; } + | expr T_THUS expr { BINOP($$, $1, PCBQ_OP_THUS, $3); } + | expr T_AND expr { BINOP($$, $1, PCBQ_OP_AND, $3); } + | expr T_OR expr { BINOP($$, $1, PCBQ_OP_OR, $3); } + | expr T_EQ expr { BINOP($$, $1, PCBQ_OP_EQ, $3); } + | expr T_NEQ expr { BINOP($$, $1, PCBQ_OP_NEQ, $3); } + | expr T_GTEQ expr { BINOP($$, $1, PCBQ_OP_GTEQ, $3); } + | expr T_LTEQ expr { BINOP($$, $1, PCBQ_OP_LTEQ, $3); } + | expr '>' expr { BINOP($$, $1, PCBQ_OP_GT, $3); } + | expr '<' expr { BINOP($$, $1, PCBQ_OP_LT, $3); } + | expr '+' expr { BINOP($$, $1, PCBQ_OP_ADD, $3); } + | expr '-' expr { BINOP($$, $1, PCBQ_OP_SUB, $3); } + | expr '*' expr { BINOP($$, $1, PCBQ_OP_MUL, $3); } + | expr '/' expr { BINOP($$, $1, PCBQ_OP_DIV, $3); } + | expr '~' T_STR { BINOP($$, $1, PCBQ_OP_MATCH, make_regex_free($3)); } + | expr '~' T_QSTR { BINOP($$, $1, PCBQ_OP_MATCH, make_regex_free($3)); } + | T_CONST { $$ = $1; } + | var { $$ = $1; } + | constant { $$ = $1; } + | expr '.' fields { + pcb_qry_node_t *n; + $$ = pcb_qry_n_alloc(PCBQ_FIELD_OF); + $$->data.children = $1; + $1->next = $3; + $1->parent = $$; + for(n = $3; n != NULL; n = n->next) + n->parent = $$; + } + ; + +number: + T_INT maybe_unit { $$ = pcb_qry_n_alloc(PCBQ_DATA_COORD); UNIT_CONV($$->data.crd, 0, $1, $2); } + | T_DBL maybe_unit { $$ = pcb_qry_n_alloc(PCBQ_DATA_DOUBLE); UNIT_CONV($$->data.dbl, 0, $1, $2); } + | '-' T_INT maybe_unit { $$ = pcb_qry_n_alloc(PCBQ_DATA_COORD); UNIT_CONV($$->data.crd, 1, $2, $3); } + | '-' T_DBL maybe_unit { $$ = pcb_qry_n_alloc(PCBQ_DATA_DOUBLE); UNIT_CONV($$->data.dbl, 1, $2, $3); } + ; + +string_literal: + T_QSTR { $$ = pcb_qry_n_alloc(PCBQ_DATA_STRING); $$->data.str = $1; } + ; + +maybe_unit: + /* empty */ { $$ = NULL; } + | T_UNIT { $$ = $1; } + ; + +fields: + T_STR { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = $1; $$->precomp.fld = query_fields_sphash($1); } + | T_STR '.' fields { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = $1; $$->precomp.fld = query_fields_sphash($1); $$->next = $3; } + | T_FLD_P fields { $$ = $2; /* just ignore .p. */ } + | T_FLD_P T_FLD_FLAG T_STR { $$ = make_flag_free($3); } + | T_FLD_A attribs { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = rnd_strdup("a"); $$->precomp.fld = query_fields_sphash("a"); $$->next = $2; } + ; + +attribs: + T_STR { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = $1; } + | T_STR '.' attribs { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = attrib_prepend_free((char *)$3->data.str, $1, '.'); } + | T_QSTR { $$ = pcb_qry_n_alloc(PCBQ_FIELD); $$->data.str = $1; } + ; + +let: + T_LET + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } + T_STR expr + { + pcb_qry_node_t *nd; + $$ = pcb_qry_n_alloc(PCBQ_LET); + $$->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert($$, $4); + nd = pcb_qry_n_alloc(PCBQ_VAR); + nd->data.crd = pcb_qry_iter_var(iter_ctx, $3, 1); + pcb_qry_n_insert($$, nd); + free($3); + } + ; + +assert: + T_ASSERT + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } + expr + { + $$ = pcb_qry_n_alloc(PCBQ_ASSERT); + $$->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert($$, $3); + } + ; + +freturn: + T_RETURN + { + iter_active_ctx = calloc(sizeof(vti0_t), 1); + } + expr + { + $$ = pcb_qry_n_alloc(PCBQ_RETURN); + $$->precomp.it_active = iter_active_ctx; + iter_active_ctx = NULL; + pcb_qry_n_insert($$, $3); + } + ; + +var: + T_STR { $$ = pcb_qry_n_alloc(PCBQ_VAR); $$->data.crd = pcb_qry_iter_var(iter_ctx, $1, 1); if (iter_active_ctx != NULL) vti0_set(iter_active_ctx, $$->data.crd, 1); free($1); } + | T_LIST '(' '@' ')' { $$ = pcb_qry_n_alloc(PCBQ_LISTVAR); $$->data.str = rnd_strdup("@"); /* delibertely not setting iter_active, list() protects against turning it into an iterator */ } + | T_LIST '(' T_STR ')' { $$ = pcb_qry_n_alloc(PCBQ_LISTVAR); $$->data.str = $3; /* delibertely not setting iter_active, list() protects against turning it into an iterator */ } + | '@' { $$ = pcb_qry_n_alloc(PCBQ_VAR); $$->data.crd = pcb_qry_iter_var(iter_ctx, "@", 1); if (iter_active_ctx != NULL) vti0_set(iter_active_ctx, $$->data.crd, 1); } + ; + +/* $foo is shorthand for getconf("design/drc/foo") */ +constant: + '$' T_STR + { + pcb_qry_node_t *fname, *nname; + + nname = pcb_qry_n_alloc(PCBQ_DATA_STRING); + nname->data.str = rnd_concat("design/drc/", $2, NULL); + free($2); + + fname = pcb_qry_n_alloc(PCBQ_FNAME); + fname->data.str = NULL; + fname->precomp.fnc.bui = pcb_qry_fnc_lookup("getconf"); + + $$ = pcb_qry_n_alloc(PCBQ_FCALL); + fname->parent = nname->parent = $$; + $$->data.children = fname; + $$->data.children->next = nname; + } + ; + +fcall: + fcallname '(' fargs ')' { $$ = pcb_qry_n_alloc(PCBQ_FCALL); $$->data.children = $1; $$->data.children->next = $3; $1->parent = $3->parent = $$; } + | fcallname '(' ')' { $$ = pcb_qry_n_alloc(PCBQ_FCALL); $$->data.children = $1; $1->parent = $$; } + ; + +fcallname: + T_STR { + $$ = pcb_qry_n_alloc(PCBQ_FNAME); + $$->precomp.fnc.bui = pcb_qry_fnc_lookup($1); + if ($$->precomp.fnc.bui != NULL) { + /* builtin function */ + free($1); + $$->data.str = NULL; + } + else + $$->data.str = $1; /* user function: save the name */ + } + ; + + +fargs: + expr { $$ = $1; } + | expr ',' fargs { $$ = $1; $$->next = $3; } + ; + + +fdefarg: + T_STR { + $$ = pcb_qry_n_alloc(PCBQ_ARG); + $$->data.crd = pcb_qry_iter_var(iter_ctx, $1, 1); + } + ; + +fdefargs: + fdefarg { $$ = $1; } + | fdefarg ',' fdefarg { $$ = $1; $$->next = $3; } + ; + +fdefname: + T_STR { + $$ = pcb_qry_n_alloc(PCBQ_FNAME); + $$->data.str = $1; + } + ; + +fdef_: + '(' fdefargs ')' { $$ = $2; } + | '(' ')' { $$ = NULL; } + ; + +fdef: + T_FUNCTION fdefname + { iter_ctx = pcb_qry_iter_alloc(); } + fdef_ { + pcb_qry_node_t *nd; + + $$ = pcb_qry_n_alloc(PCBQ_FUNCTION); + + if ($4 != NULL) + pcb_qry_n_append($$, $4); + + pcb_qry_n_insert($$, $2); + + nd = pcb_qry_n_alloc(PCBQ_ITER_CTX); + nd->data.iter_ctx = iter_ctx; + pcb_qry_n_insert($$, nd); + + if (user_funcs == NULL) + user_funcs = htsp_alloc(strhash, strkeyeq); + htsp_set(user_funcs, (char *)$2->data.str, $$); + } + ; +words: + /* empty */ { $$ = pcb_qry_n_alloc(PCBQ_RNAME); $$->data.str = (const char *)rnd_strdup(""); } + | T_STR words { + char *old = (char *)$2->data.str, *sep = ((*old != '\0') ? " " : ""); + $2->data.str = rnd_concat($1, sep, old, NULL); + free(old); + free($1); + $$ = $2; + } + ; Index: tags/2.3.0/src_plugins/renumber/Makefile =================================================================== --- tags/2.3.0/src_plugins/renumber/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/renumber/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_renumber + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/renumber/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/renumber/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/renumber/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {renumber} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/renumber/renumber.o $(PLUGDIR)/renumber/renumberblock.o @] + +switch /local/pcb/renumber/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/renumber/renumber.c =================================================================== --- tags/2.3.0/src_plugins/renumber/renumber.c (nonexistent) +++ tags/2.3.0/src_plugins/renumber/renumber.c (revision 33253) @@ -0,0 +1,375 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2018,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ +#include "config.h" +#include "board.h" +#include "data.h" +#include "change.h" +#include +#include "undo.h" +#include +#include +#include "conf_core.h" +#include +#include "netlist.h" +#include + +#include + +static const char pcb_acts_Renumber[] = "Renumber()\n" "Renumber(filename)"; +static const char pcb_acth_Renumber[] = + "Renumber all subcircuits. The changes will be recorded to filename\n" + "for use in backannotating these changes to the schematic."; + +static const char *or_empty(const char *s) +{ + if (s == NULL) return ""; + return s; +} + +static fgw_error_t pcb_act_Renumber(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_bool changed = rnd_false; + pcb_subc_t **subc_list; + pcb_subc_t **locked_subc_list; + rnd_coord_t *ox_list, *oy_list; + unsigned int i, j, k, cnt, lock_cnt; + unsigned int tmpi; + size_t sz; + char *tmps; + const char *name = NULL; + FILE *out; + static char *default_file = NULL; + size_t cnt_list_sz = 100; + struct _cnt_list { + char *name; + unsigned int cnt; + } *cnt_list; + char **was, **is; + unsigned int c_cnt = 0, numsubc; + int ok; + rnd_bool free_name = rnd_false; + + RND_ACT_MAY_CONVARG(1, FGW_STR, Renumber, name = argv[1].val.str); + + if (name == NULL) { + /* + * We deal with the case where name already exists in this + * function so the GUI doesn't need to deal with it + */ + name = rnd_gui->fileselect(rnd_gui, "Save Renumber Annotation File As ...", + "Choose a file to record the renumbering to.\n" + "This file may be used to back annotate the\n" + "change to the schematics.\n", default_file, ".eco", NULL, "eco", 0, NULL); + + free_name = rnd_true; + } + + if (default_file) { + free(default_file); + default_file = NULL; + } + + if (name && *name) { + default_file = rnd_strdup(name); + } + + if ((out = rnd_fopen(&PCB->hidlib, name, "r"))) { + fclose(out); + if (rnd_hid_message_box(&PCB->hidlib, "warning", "Renumber: overwrite", "File exists! Ok to overwrite?", "cancel", 0, "overwrite", 1, NULL) != 1) { + if (free_name && name) + free((char*)name); + RND_ACT_IRES(1); + return 0; + } + } + + if ((out = rnd_fopen_askovr(&PCB->hidlib, name, "w", NULL)) == NULL) { + rnd_message(RND_MSG_ERROR, "Could not open %s\n", name); + if (free_name && name) + free((char*)name); + RND_ACT_IRES(1); + return 0; + } + + if (free_name && name) + free((char*)name); + + fprintf(out, "*COMMENT* PCB Annotation File\n"); + fprintf(out, "*FILEVERSION* 20061031\n"); + + /* + * Make a first pass through all of the subcircuits and sort them out + * by location on the board. While here we also collect a list of + * locked subcircuits. + * + * We'll actually renumber things in the 2nd pass. + */ + numsubc = pcb_subclist_length(&PCB->Data->subc); + subc_list = calloc(numsubc, sizeof(pcb_subc_t *)); + ox_list = calloc(numsubc, sizeof(rnd_coord_t)); + oy_list = calloc(numsubc, sizeof(rnd_coord_t)); + locked_subc_list = calloc(numsubc, sizeof(pcb_subc_t *)); + was = calloc(numsubc, sizeof(char *)); + is = calloc(numsubc, sizeof(char *)); + if (subc_list == NULL || locked_subc_list == NULL || was == NULL || is == NULL || ox_list == NULL || oy_list == NULL) { + fprintf(stderr, "calloc() failed in pcb_act_Renumber\n"); + exit(1); + } + + + cnt = 0; + lock_cnt = 0; + + PCB_SUBC_LOOP(PCB->Data); + { + rnd_coord_t ox, oy; + + if (pcb_subc_get_origin(subc, &ox, &oy) != 0) { + ox = (subc->BoundingBox.X1 + subc->BoundingBox.X2)/2; + oy = (subc->BoundingBox.Y1 + subc->BoundingBox.Y2)/2; + } + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, subc)) { + /* add to the list of locked subcircuits which we won't try to renumber and whose reference designators are now reserved. */ + rnd_fprintf(out, + "*WARN* subc \"%s\" at %$md is locked and will not be renumbered.\n", + RND_UNKNOWN(subc->refdes), ox, oy); + locked_subc_list[lock_cnt] = subc; + lock_cnt++; + } + else { + /* count of devices which will be renumbered */ + cnt++; + + /* search for correct position in the list */ + i = 0; + while (subc_list[i] && oy > oy_list[i]) + i++; + + /* We have found the position where we have the first subcircuits that + * has the same Y value or a lower Y value. Now move forward if + * needed through the X values */ + while (subc_list[i] && oy == oy_list[i] && ox > ox_list[i]) + i++; + + for (j = cnt - 1; j > i; j--) { + subc_list[j] = subc_list[j - 1]; + ox_list[j] = ox_list[j - 1]; + oy_list[j] = oy_list[j - 1]; + } + subc_list[i] = subc; + ox_list[j] = ox; + oy_list[j] = oy; + } + } + PCB_END_LOOP; + + + /* + * Now that the subcircuits are sorted by board position, we go through + * and renumber them. + */ + + cnt_list = (struct _cnt_list *) calloc(cnt_list_sz, sizeof(struct _cnt_list)); + for (i = 0; i < cnt; i++) { + if (subc_list[i]->refdes) { + /* figure out the prefix */ + tmps = rnd_strdup(or_empty(subc_list[i]->refdes)); + j = 0; + while (tmps[j] && (tmps[j] < '0' || tmps[j] > '9') + && tmps[j] != '?') + j++; + tmps[j] = '\0'; + + /* check the counter for this prefix */ + for (j = 0; cnt_list[j].name && (strcmp(cnt_list[j].name, tmps) != 0) + && j < cnt_list_sz; j++); + + /* grow the list if needed */ + if (j == cnt_list_sz) { + cnt_list_sz += 100; + cnt_list = (struct _cnt_list *) realloc(cnt_list, cnt_list_sz); + if (cnt_list == NULL) { + fprintf(stderr, "realloc() failed in pcb_act_Renumber\n"); + exit(1); + } + /* zero out the memory that we added */ + for (tmpi = j; tmpi < cnt_list_sz; tmpi++) { + cnt_list[tmpi].name = NULL; + cnt_list[tmpi].cnt = 0; + } + } + + /* start a new counter if we don't have a counter for this prefix */ + if (!cnt_list[j].name) { + cnt_list[j].name = rnd_strdup(tmps); + cnt_list[j].cnt = 0; + } + + /* check to see if the new refdes is already used by a locked subcircuit */ + do { + ok = 1; + cnt_list[j].cnt++; + free(tmps); + + /* space for the prefix plus 1 digit plus the '\0' */ + sz = strlen(cnt_list[j].name) + 2; + + /* and 1 more per extra digit needed to hold the number */ + tmpi = cnt_list[j].cnt; + while (tmpi > 10) { + sz++; + tmpi = tmpi / 10; + } + tmps = (char *) malloc(sz * sizeof(char)); + sprintf(tmps, "%s%d", cnt_list[j].name, cnt_list[j].cnt); + + /* + * now compare to the list of reserved (by locked + * subcircuits) names + */ + for (k = 0; k < lock_cnt; k++) { + if (strcmp(RND_UNKNOWN(locked_subc_list[k]->refdes), tmps) == 0) { + ok = 0; + break; + } + } + + } + while (!ok); + + if (strcmp(tmps, or_empty(subc_list[i]->refdes)) != 0) { + fprintf(out, "*RENAME* \"%s\" \"%s\"\n", or_empty(subc_list[i]->refdes), tmps); + + /* add this rename to our table of renames so we can update the netlist */ + was[c_cnt] = rnd_strdup(or_empty(subc_list[i]->refdes)); + is[c_cnt] = rnd_strdup(tmps); + c_cnt++; + + pcb_undo_add_obj_to_change_name(PCB_OBJ_SUBC, NULL, NULL, subc_list[i], (char *)or_empty(subc_list[i]->refdes)); + + pcb_chg_obj_name(PCB_OBJ_SUBC, subc_list[i], NULL, NULL, tmps); + changed = rnd_true; + + /* we don't free tmps in this case because it is used */ + } + else + free(tmps); + } + else { + /* If there is no refdes, maybe just spit out a warning */ + rnd_fprintf(out, "*WARN* Subcircuit at %$md has no name.\n", ox_list[i], oy_list[i]); + } + } + + fclose(out); + + /* restore the unique flag setting */ + rnd_conf_update(NULL, -1); + + if (changed) { + htsp_entry_t *e; + + /* iterate over each net */ + for(e = htsp_first(&PCB->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&PCB->netlist[PCB_NETLIST_EDITED], e)) { + pcb_net_term_t *t; + pcb_net_t *net = e->value; + + /* iterate over each pin on the net */ + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) { + + /* iterate over the list of changed reference designators */ + for (k = 0; k < c_cnt; k++) { + /* + * if the pin needs to change, change it and quit + * searching in the list. + */ + if (strcmp(t->refdes, was[k]) == 0) { + free(t->refdes); + t->refdes = rnd_strdup(is[k]); + k = c_cnt; + } + } + } + } + for (k = 0; k < c_cnt; k++) { + free(was[k]); + free(is[k]); + } + + pcb_netlist_changed(0); + pcb_undo_inc_serial(); + pcb_board_set_changed_flag(PCB_ACT_BOARD, rnd_true); + } + + free(locked_subc_list); + free(subc_list); + free(ox_list); + free(oy_list); + free(cnt_list); + RND_ACT_IRES(0); + return 0; +} + +extern const char pcb_acts_RenumberBlock[]; +extern const char pcb_acth_RenumberBlock[]; +fgw_error_t pcb_act_RenumberBlock(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv); + +extern const char pcb_acts_RenumberBuffer[]; +extern const char pcb_acth_RenumberBuffer[]; +fgw_error_t pcb_act_RenumberBuffer(fgw_arg_t *ores, int oargc, fgw_arg_t *oargv); + + +static const char *renumber_cookie = "renumber plugin"; + +rnd_action_t renumber_action_list[] = { + {"Renumber", pcb_act_Renumber, pcb_acth_Renumber, pcb_acts_Renumber}, + {"RenumberBlock", pcb_act_RenumberBlock, pcb_acth_RenumberBlock, pcb_acts_RenumberBlock}, + {"RenumberBuffer", pcb_act_RenumberBuffer, pcb_acth_RenumberBuffer, pcb_acts_RenumberBuffer} +}; + +int pplg_check_ver_renumber(int ver_needed) { return 0; } + +void pplg_uninit_renumber(void) +{ + rnd_remove_actions_by_cookie(renumber_cookie); +} + +int pplg_init_renumber(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(renumber_action_list, renumber_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/renumber/renumber.pup =================================================================== --- tags/2.3.0/src_plugins/renumber/renumber.pup (nonexistent) +++ tags/2.3.0/src_plugins/renumber/renumber.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short renumber action +$long Renumber subcircuits (renaming them) and generate a text file for back annotation. +$state works +$package extra +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/renumber/renumberblock.c =================================================================== --- tags/2.3.0/src_plugins/renumber/renumberblock.c (nonexistent) +++ tags/2.3.0/src_plugins/renumber/renumberblock.c (revision 33253) @@ -0,0 +1,113 @@ +/* + * RenumberBlock plug-in for PCB. + * + * Copyright (C) 2006 DJ Delorie + * Copyright (C) 2018 Tibor 'Igor2' Palinkas for pcb-rnd data model + * + * Licensed under the terms of the GNU General Public + * License, version 2 or later. + * + * Original source: http://www.delorie.com/pcb/renumberblock.c + * + */ + +#include +#include + +#include "config.h" +#include "board.h" +#include +#include "data.h" +#include +#include +#include "undo.h" +#include +#include "change.h" +#include "conf_core.h" + +const char pcb_acts_RenumberBlock[] = "RenumberBlock(old_base,new_base)\n"; +const char pcb_acth_RenumberBlock[] = "Renumber selected subcircuit refdes attributes by adding (new_base-old_base)."; +/* DOC: renumberblock.html */ +fgw_error_t pcb_act_RenumberBlock(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char num_buf[15]; + int old_base, new_base; + + RND_ACT_CONVARG(1, FGW_INT, RenumberBlock, old_base = argv[1].val.nat_int); + RND_ACT_CONVARG(2, FGW_INT, RenumberBlock, new_base = argv[2].val.nat_int); + + rnd_conf_set_editor(name_on_pcb, 1); + + PCB_SUBC_LOOP(PCB->Data); + { + char *new_ref; + const char *old_ref, *cp, *refdes_split; + int num; + + if (!PCB_FLAG_TEST(PCB_FLAG_SELECTED, subc) || (subc->refdes == NULL)) + continue; + + old_ref = subc->refdes; + for (refdes_split = cp = old_ref; *cp; cp++) + if (!isdigit(*cp)) + refdes_split = cp + 1; + + num = atoi(refdes_split); + num += (new_base - old_base); + sprintf(num_buf, "%d", num); + new_ref = (char *) malloc(refdes_split - old_ref + strlen(num_buf) + 1); + memcpy(new_ref, old_ref, refdes_split - old_ref); + strcpy(new_ref + (refdes_split - old_ref), num_buf); + + pcb_undo_add_obj_to_change_name(PCB_OBJ_SUBC, NULL, NULL, subc, (char *)subc->refdes); + + pcb_chg_obj_name(PCB_OBJ_SUBC, subc, subc, subc, new_ref); + } + PCB_END_LOOP; + pcb_undo_inc_serial(); + RND_ACT_IRES(0); + return 0; +} + + +const char pcb_acts_RenumberBuffer[] = "RenumberBuffer(old_base,new_base)\n"; +const char pcb_acth_RenumberBuffer[] = "Renumber buffer subcircuit refdes attributes by adding (new_base-old_base)."; +/* DOC: renumberbuffer.html */ +fgw_error_t pcb_act_RenumberBuffer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + char num_buf[15]; + int old_base, new_base; + + RND_ACT_CONVARG(1, FGW_INT, RenumberBuffer, old_base = argv[1].val.nat_int); + RND_ACT_CONVARG(2, FGW_INT, RenumberBuffer, new_base = argv[2].val.nat_int); + + rnd_conf_set_editor(name_on_pcb, 1); + + PCB_SUBC_LOOP(PCB_PASTEBUFFER->Data); + { + const char *refdes_split, *cp, *old_ref; + char *new_ref; + int num; + + if (subc->refdes == NULL) + continue; + + old_ref = subc->refdes; + for (refdes_split = cp = old_ref; *cp; cp++) + if (!isdigit(*cp)) + refdes_split = cp + 1; + + num = atoi(refdes_split); + num += (new_base - old_base); + sprintf(num_buf, "%d", num); + new_ref = (char *) malloc(refdes_split - old_ref + strlen(num_buf) + 1); + memcpy(new_ref, old_ref, refdes_split - old_ref); + strcpy(new_ref + (refdes_split - old_ref), num_buf); + + pcb_chg_obj_name(PCB_OBJ_SUBC, subc, subc, subc, new_ref); + } + PCB_END_LOOP; + + RND_ACT_IRES(0); + return 0; +} Index: tags/2.3.0/src_plugins/report/Makefile =================================================================== --- tags/2.3.0/src_plugins/report/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/report/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_report + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/report/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/report/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/report/Plug.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +put /local/pcb/mod {report} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/report/report.o + $(PLUGDIR)/report/drill.o +@] +put /local/pcb/mod/CONF {$(PLUGDIR)/report/report_conf.h} + +switch /local/pcb/report/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/report/drill.c =================================================================== --- tags/2.3.0/src_plugins/report/drill.c (nonexistent) +++ tags/2.3.0/src_plugins/report/drill.c (revision 33253) @@ -0,0 +1,238 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2017 Tibor 'Igor2' Palinkas + * + * This module, drill.c, was written and is Copyright (C) 1997 harry eaton + * and upgraded by Tibor 'Igor2' Palinkas for padstacks in 2017 + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#include "config.h" + +#include "data.h" +#include "drill.h" +#include "obj_pstk_inlines.h" + +#define STEP_ELEMENT 50 +#define STEP_DRILL 30 +#define STEP_POINT 100 + +static void drill_fill(pcb_drill_t * Drill, pcb_any_obj_t *hole, int unplated) +{ + rnd_cardinal_t n; + pcb_any_obj_t **pnew; + pcb_any_obj_t **hnew; + + hnew = drill_pin_alloc(Drill); + *hnew = hole; + if (hole->parent_type == PCB_PARENT_SUBC) { + Drill->PinCount++; + for (n = Drill->ElementN - 1; n != -1; n--) + if (Drill->parent[n] == hole->parent.any) + break; + if (n == -1) { + pnew = drill_element_alloc(Drill); + *pnew = hole->parent.any; + } + } + else + Drill->ViaCount++; + if (unplated) + Drill->UnplatedCount++; +} + +static int drill_qsort_cmp(const void *va, const void *vb) +{ + pcb_drill_t *a = (pcb_drill_t *) va; + pcb_drill_t *b = (pcb_drill_t *) vb; + return a->DrillSize - b->DrillSize; +} + +pcb_drill_info_t *drill_get_info(pcb_data_t *top) +{ + pcb_drill_info_t *AllDrills; + pcb_drill_t *Drill = NULL; + rnd_bool DrillFound = rnd_false; + rnd_rtree_it_t it; + rnd_box_t *pb; + + AllDrills = (pcb_drill_info_t *)calloc(1, sizeof(pcb_drill_info_t)); + + for(pb = rnd_r_first(top->padstack_tree, &it); pb != NULL; pb = rnd_r_next(&it)) { + pcb_pstk_t *ps = (pcb_pstk_t *)pb; + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(ps); + if (proto->hdia <= 0) + continue; + if (!DrillFound) { + DrillFound = rnd_true; + Drill = drill_info_alloc(AllDrills); + Drill->DrillSize = proto->hdia; + drill_fill(Drill, (pcb_any_obj_t *)ps, !proto->hplated); + } + else { + if (Drill->DrillSize != proto->hdia) { + DRILL_LOOP(AllDrills); + { + if (drill->DrillSize == proto->hdia) { + Drill = drill; + drill_fill(Drill, (pcb_any_obj_t *)ps, !proto->hplated); + break; + } + } + PCB_END_LOOP; + if (Drill->DrillSize != proto->hdia) { + Drill = drill_info_alloc(AllDrills); + Drill->DrillSize = proto->hdia; + drill_fill(Drill, (pcb_any_obj_t *)ps, !proto->hplated); + } + } + else + drill_fill(Drill, (pcb_any_obj_t *)ps, !proto->hplated); + } + } + + qsort(AllDrills->Drill, AllDrills->DrillN, sizeof(pcb_drill_t), drill_qsort_cmp); + return AllDrills; +} + +#define ROUND(x,n) ((int)(((x)+(n)/2)/(n))*(n)) + +void drill_round_info(pcb_drill_info_t *d, int roundto) +{ + unsigned int i = 0; + + while ((d->DrillN > 0) && (i < d->DrillN - 1)) { + int diam1 = ROUND(d->Drill[i].DrillSize, roundto); + int diam2 = ROUND(d->Drill[i + 1].DrillSize, roundto); + + if (diam1 == diam2) { + int ei, ej; + + d->Drill[i].ElementMax = d->Drill[i].ElementN + d->Drill[i + 1].ElementN; + if (d->Drill[i].ElementMax) { + d->Drill[i].parent = realloc(d->Drill[i].parent, d->Drill[i].ElementMax * sizeof(pcb_any_obj_t *)); + + for (ei = 0; ei < d->Drill[i + 1].ElementN; ei++) { + for (ej = 0; ej < d->Drill[i].ElementN; ej++) + if (d->Drill[i].parent[ej] == d->Drill[i + 1].parent[ei]) + break; + if (ej == d->Drill[i].ElementN) + d->Drill[i].parent[d->Drill[i].ElementN++] + = d->Drill[i + 1].parent[ei]; + } + } + free(d->Drill[i + 1].parent); + d->Drill[i + 1].parent = NULL; + + d->Drill[i].PinMax = d->Drill[i].PinN + d->Drill[i + 1].PinN; + d->Drill[i].hole = realloc(d->Drill[i].hole, d->Drill[i].PinMax * sizeof(pcb_any_obj_t *)); + memcpy(d->Drill[i].hole + d->Drill[i].PinN, d->Drill[i + 1].hole, d->Drill[i + 1].PinN * sizeof(pcb_any_obj_t *)); + d->Drill[i].PinN += d->Drill[i + 1].PinN; + free(d->Drill[i + 1].hole); + d->Drill[i + 1].hole = NULL; + + d->Drill[i].PinCount += d->Drill[i + 1].PinCount; + d->Drill[i].ViaCount += d->Drill[i + 1].ViaCount; + d->Drill[i].UnplatedCount += d->Drill[i + 1].UnplatedCount; + + d->Drill[i].DrillSize = diam1; + + memmove(d->Drill + i + 1, d->Drill + i + 2, (d->DrillN - i - 2) * sizeof(pcb_drill_t)); + d->DrillN--; + } + else { + d->Drill[i].DrillSize = diam1; + i++; + } + } +} + +void drill_info_free(pcb_drill_info_t *Drills) +{ + DRILL_LOOP(Drills); + { + free(drill->parent); + free(drill->hole); + } + PCB_END_LOOP; + free(Drills->Drill); + free(Drills); +} + +/* --------------------------------------------------------------------------- + * get next slot for a Drill, allocates memory if necessary + */ +pcb_drill_t *drill_info_alloc(pcb_drill_info_t *DrillInfo) +{ + pcb_drill_t *drill = DrillInfo->Drill; + + /* realloc new memory if necessary and clear it */ + if (DrillInfo->DrillN >= DrillInfo->DrillMax) { + DrillInfo->DrillMax += STEP_DRILL; + drill = (pcb_drill_t *) realloc(drill, DrillInfo->DrillMax * sizeof(pcb_drill_t)); + DrillInfo->Drill = drill; + memset(drill + DrillInfo->DrillN, 0, STEP_DRILL * sizeof(pcb_drill_t)); + } + return (drill + DrillInfo->DrillN++); +} + +/* --------------------------------------------------------------------------- + * get next slot for a DrillPoint, allocates memory if necessary + */ +pcb_any_obj_t **drill_pin_alloc(pcb_drill_t *Drill) +{ + pcb_any_obj_t **pin; + + pin = Drill->hole; + + /* realloc new memory if necessary and clear it */ + if (Drill->PinN >= Drill->PinMax) { + Drill->PinMax += STEP_POINT; + pin = realloc(pin, Drill->PinMax * sizeof(pcb_any_obj_t **)); + Drill->hole = pin; + memset(pin + Drill->PinN, 0, STEP_POINT * sizeof(pcb_any_obj_t **)); + } + return (pin + Drill->PinN++); +} + +/* --------------------------------------------------------------------------- + * get next slot for a DrillElement, allocates memory if necessary + */ +pcb_any_obj_t **drill_element_alloc(pcb_drill_t *Drill) +{ + pcb_any_obj_t **element; + + element = Drill->parent; + + /* realloc new memory if necessary and clear it */ + if (Drill->ElementN >= Drill->ElementMax) { + Drill->ElementMax += STEP_ELEMENT; + element = realloc(element, Drill->ElementMax * sizeof(pcb_any_obj_t **)); + Drill->parent = element; + memset(element + Drill->ElementN, 0, STEP_ELEMENT * sizeof(pcb_subc_t **)); + } + return (element + Drill->ElementN++); +} + Index: tags/2.3.0/src_plugins/report/drill.h =================================================================== --- tags/2.3.0/src_plugins/report/drill.h (nonexistent) +++ tags/2.3.0/src_plugins/report/drill.h (revision 33253) @@ -0,0 +1,66 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * + * This module, drill.h, was written and is Copyright (C) 1997 harry eaton + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ +#ifndef PCB_DRILL_H +#define PCB_DRILL_H + +typedef struct { /* holds drill information */ + rnd_coord_t DrillSize; /* this drill's diameter */ + rnd_cardinal_t ElementN, /* the number of elements using this drill size */ + ElementMax, /* max number of elements from malloc() */ + PinCount, /* number of pins drilled this size */ + ViaCount, /* number of vias drilled this size */ + UnplatedCount, /* number of these holes that are unplated */ + PinN, /* number of drill coordinates in the list */ + PinMax; /* max number of coordinates from malloc() */ + pcb_any_obj_t **hole; /* the objects that had the drill */ + pcb_any_obj_t **parent; /* all parents referenced by any hole above */ +} pcb_drill_t; + +typedef struct { /* holds a range of Drill Infos */ + rnd_cardinal_t DrillN, /* number of drill sizes */ + DrillMax; /* max number from malloc() */ + pcb_drill_t *Drill; /* plated holes */ +} pcb_drill_info_t; + +pcb_drill_info_t *drill_get_info(pcb_data_t *); +void drill_info_free(pcb_drill_info_t *); +void drill_round_info(pcb_drill_info_t *, int); +pcb_drill_t *drill_info_alloc(pcb_drill_info_t *); +pcb_any_obj_t **drill_pin_alloc(pcb_drill_t *); +pcb_any_obj_t **drill_element_alloc(pcb_drill_t *); + +#define DRILL_LOOP(top) do { \ + rnd_cardinal_t n; \ + pcb_drill_t *drill; \ + for (n = 0; (top)->DrillN > 0 && n < (top)->DrillN; n++) \ + { \ + drill = &(top)->Drill[n] + +#endif Index: tags/2.3.0/src_plugins/report/report.c =================================================================== --- tags/2.3.0/src_plugins/report/report.c (nonexistent) +++ tags/2.3.0/src_plugins/report/report.c (revision 33253) @@ -0,0 +1,958 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996,1997,1998,1999 Thomas Nau + * Copyright (C) 2018,2019,2020 Tibor 'Igor2' Palinkas + * + * This module, report.c, was written and is Copyright (C) 1997 harry eaton + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + + +#include "config.h" + +#include "conf_core.h" +#include +#include "src_plugins/query/net_len.h" + +#include + +#include "report.h" +#include +#include "crosshair.h" +#include "board.h" +#include "data.h" +#include "data_it.h" +#include "drill.h" +#include +#include "search.h" +#include +#include "flag_str.h" +#include "undo.h" +#include "find.h" +#include "draw.h" +#include +#include +#include +#include +#include "report_conf.h" +#include +#include "layer.h" +#include "layer_ui.h" +#include "obj_term.h" +#include "obj_pstk.h" +#include "obj_pstk_inlines.h" +#include "obj_subc_parent.h" +#include +#include "netlist.h" + +#include + +conf_report_t conf_report; + +static const char pcb_acts_Report[] = + "Report([DrillReport|FoundPins|NetLengthTo])\n" + "Report(NetLength, [netname])\n" + "Report(Object|Subc, [log])\n" + "Report(AllNetLengths, [unit])"; +static const char pcb_acth_Report[] = "Produce various report."; + +#define USER_UNITMASK (rnd_conf.editor.grid_unit->allow) + + +typedef struct rdialog_ctx_s { + RND_DAD_DECL_NOINIT(dlg) +} rdialog_ctx_t; + +static void rdialog_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + rdialog_ctx_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + free(ctx); +} + +static void rdialog(const char *name, const char *content) +{ + rdialog_ctx_t *ctx = calloc(sizeof(rdialog_ctx_t), 1); + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, content); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + + RND_DAD_NEW("report", ctx->dlg, name, ctx, rnd_false, rdialog_close_cb); +} + + +static int report_drills(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_drill_info_t *AllDrills; + rnd_cardinal_t n; + char *stringlist, *thestring; + int total_drills = 0; + + AllDrills = drill_get_info(PCB->Data); + drill_round_info(AllDrills, 100); + + for (n = 0; n < AllDrills->DrillN; n++) { + total_drills += AllDrills->Drill[n].PinCount; + total_drills += AllDrills->Drill[n].ViaCount; + total_drills += AllDrills->Drill[n].UnplatedCount; + } + + stringlist = (char *) malloc(512L + AllDrills->DrillN * 64L); + + /* Use tabs for formatting since can't count on a fixed font anymore. + And even that probably isn't going to work in all cases. */ + sprintf(stringlist, + "There are %d different drill sizes used in this layout, %d holes total\n\n" + "Drill Diam. (%s)\t# of Pins\t# of Vias\t# of Elements\t# Unplated\n", + AllDrills->DrillN, total_drills, rnd_conf.editor.grid_unit->suffix); + thestring = stringlist; + while (*thestring != '\0') + thestring++; + for (n = 0; n < AllDrills->DrillN; n++) { + rnd_sprintf(thestring, + "%10m*\t\t\t%d\t\t%d\t\t%d\t\t\t\t%d\n", + rnd_conf.editor.grid_unit->suffix, + AllDrills->Drill[n].DrillSize, + AllDrills->Drill[n].PinCount, AllDrills->Drill[n].ViaCount, + AllDrills->Drill[n].ElementN, AllDrills->Drill[n].UnplatedCount); + while (*thestring != '\0') + thestring++; + } + drill_info_free(AllDrills); + + /* create dialog box */ + rdialog("Drill Report", stringlist); + + free(stringlist); + return 0; +} + + +static const char pcb_acts_reportdialog[] = "ReportObject()"; +static const char pcb_acth_reportdialog[] = "Report on the object under the crosshair"; +/* DOC: reportdialog.html */ + +#define gen_locked(obj) (PCB_FLAG_TEST(PCB_FLAG_LOCK, obj) ? "It is LOCKED.\n" : "") +#define gen_term(obj) \ + (((obj)->term != NULL) ? "It is terminal " : ""), \ + (((obj)->term != NULL) ? (obj)->term : ""), \ + (((obj)->term != NULL) ? "\n" : "") + +static const char *grpname(rnd_layergrp_id_t gid) +{ + pcb_layergrp_t *grp = pcb_get_layergrp(PCB, gid); + if (grp == NULL) + return ""; + if ((grp->name == NULL) || (*grp->name == '\0')) + return ""; + return grp->name; +} + +static void report_pstk(gds_t *dst, pcb_pstk_t *ps) +{ + pcb_pstk_proto_t *proto; + +#ifndef NDEBUG + if (rnd_gui->shift_is_pressed(rnd_gui)) + rnd_r_dump_tree(PCB->Data->padstack_tree, 0); +#endif + proto = pcb_pstk_get_proto(ps); + + rnd_append_printf(dst, "%m+PADSTACK ID# %ld; Flags:%s\n" + "(X,Y) = %$mD.\n", USER_UNITMASK, ps->ID, pcb_strflg_f2s(ps->Flags, PCB_OBJ_PSTK, NULL, 0), + ps->x, ps->y); + + if ((proto != NULL) && (proto->hdia > 0)) + rnd_append_printf(dst, "%m+Hole diameter: %$mS", USER_UNITMASK, proto->hdia); + + rnd_append_printf(dst, "\n%s%s%s", gen_locked(ps), gen_term(ps)); +} + +static void report_line(gds_t *dst, pcb_line_t *line) +{ +#ifndef NDEBUG + if (rnd_gui->shift_is_pressed(rnd_gui)) + rnd_r_dump_tree(line->parent.layer->line_tree, 0); +#endif + rnd_append_printf(dst, "%m+LINE ID# %ld; Flags:%s\n" + "FirstPoint(X,Y) = %$mD, ID = %ld.\n" + "SecondPoint(X,Y) = %$mD, ID = %ld.\n" + "Width = %$mS.\nClearance = %$mS.\n" + "It is on layer %d\n" + "and has name \"%s\".\n" + "%s" + "%s%s", USER_UNITMASK, + line->ID, pcb_strflg_f2s(line->Flags, PCB_OBJ_LINE, NULL, 0), + line->Point1.X, line->Point1.Y, line->Point1.ID, + line->Point2.X, line->Point2.Y, line->Point2.ID, + line->Thickness, line->Clearance / 2, + pcb_layer_id(PCB->Data, line->parent.layer), + gen_locked(line), gen_term(line)); +} + +static void report_rat(gds_t *dst, pcb_rat_t *line) +{ + char *anchor1 = "n/a", *anchor2 = "n/a"; +#ifndef NDEBUG + if (rnd_gui->shift_is_pressed(rnd_gui)) + rnd_r_dump_tree(PCB->Data->rat_tree, 0); +#endif + rnd_append_printf(dst, "%m+RAT-LINE ID# %ld; Flags:%s\n" + "FirstPoint(X,Y) = %$mD; ID = %ld; " + "connects to layer group #%d (%s).\n" + "SecondPoint(X,Y) = %$mD; ID = %ld; " + "connects to layer group #%d (%s).\n", + USER_UNITMASK, line->ID, pcb_strflg_f2s(line->Flags, PCB_OBJ_LINE, NULL, 0), + line->Point1.X, line->Point1.Y, line->Point1.ID, line->group1, grpname(line->group1), + line->Point2.X, line->Point2.Y, line->Point2.ID, line->group2, grpname(line->group2)); + + if ((line->anchor[0] != NULL) && (line->anchor[0]->len > 0)) + anchor1 = pcb_idpath2str(line->anchor[0], 0); + if ((line->anchor[1] != NULL) && (line->anchor[1]->len > 0)) + anchor2 = pcb_idpath2str(line->anchor[1], 0); + + rnd_append_printf(dst, "Anchors: %s <-> %s\n", anchor1, anchor2); + +} + +static void report_arc(gds_t *dst, pcb_arc_t *arc) +{ + rnd_box_t box; +#ifndef NDEBUG + if (rnd_gui->shift_is_pressed(rnd_gui)) + rnd_r_dump_tree(arc->parent.layer->arc_tree, 0); +#endif + pcb_arc_get_end(arc, 0, &box.X1, &box.Y1); + pcb_arc_get_end(arc, 1, &box.X2, &box.Y2); + + rnd_append_printf(dst, "%m+ARC ID# %ld; Flags:%s\n" + "CenterPoint(X,Y) = %$mD.\n" + "Width = %$mS.\nClearance = %$mS.\n" + "Radius = %$mS, StartAngle = %ma degrees, DeltaAngle = %ma degrees.\n" + "Bounding Box is %$mD, %$mD.\n" + "That makes the end points at %$mD and %$mD.\n" + "It is on layer %d.\n" + "%s" + "%s%s%s", USER_UNITMASK, arc->ID, pcb_strflg_f2s(arc->Flags, PCB_OBJ_ARC, NULL, 0), + arc->X, arc->Y, + arc->Thickness, arc->Clearance / 2, + arc->Width, arc->StartAngle, arc->Delta, + arc->BoundingBox.X1, arc->BoundingBox.Y1, + arc->BoundingBox.X2, arc->BoundingBox.Y2, + box.X1, box.Y1, + box.X2, box.Y2, + pcb_layer_id(PCB->Data, arc->parent.layer), gen_locked(arc), gen_term(arc)); +} + +static void report_poly(gds_t *dst, pcb_poly_t *poly) +{ + const char *aunit; + double area, u; + +#ifndef NDEBUG + if (rnd_gui->shift_is_pressed(rnd_gui)) + rnd_r_dump_tree(poly->parent.layer->polygon_tree, 0); +#endif + + aunit = rnd_conf.editor.grid_unit->suffix; + if (aunit[1] == 'm') + u = RND_MM_TO_COORD(1); + else + u = RND_MIL_TO_COORD(1); + + area = pcb_poly_area(poly); + area = area / u; + area = area / u; + + rnd_append_printf(dst, "%m+POLYGON ID# %ld; Flags:%s\n" + "Its bounding box is %$mD %$mD.\n" + "It has %d points and could store %d more\n" + " without using more memory.\n" + "It has %d holes and resides on layer %d.\n" + "Its unclipped area is %f square %s.\n", USER_UNITMASK, poly->ID, + pcb_strflg_f2s(poly->Flags, PCB_OBJ_POLY, NULL, 0), + poly->BoundingBox.X1, poly->BoundingBox.Y1, + poly->BoundingBox.X2, poly->BoundingBox.Y2, + poly->PointN, poly->PointMax - poly->PointN, + poly->HoleIndexN, + pcb_layer_id(PCB->Data, poly->parent.layer), + area, aunit); + + if (poly->enforce_clearance > 0) + rnd_append_printf(dst, "%m+Polygon enforced min. clearance: %$mS\n", USER_UNITMASK, poly->enforce_clearance); + + rnd_append_printf(dst, "%s %s%s%s", gen_locked(poly), gen_term(poly)); +} + +static void report_subc(gds_t *dst, pcb_subc_t *subc) +{ +#ifndef NDEBUG + if (rnd_gui->shift_is_pressed(rnd_gui)) + rnd_r_dump_tree(PCB->Data->subc_tree, 0); +#endif + rnd_append_printf(dst, "%m+SUBCIRCUIT ID# %ld; Flags:%s\n" + "BoundingBox %$mD %$mD.\n" + "Refdes \"%s\".\n" + "Footprint \"%s\".\n" + "%s", USER_UNITMASK, + subc->ID, pcb_strflg_f2s(subc->Flags, PCB_OBJ_SUBC, NULL, 0), + subc->BoundingBox.X1, subc->BoundingBox.Y1, + subc->BoundingBox.X2, subc->BoundingBox.Y2, + RND_EMPTY(subc->refdes), + RND_EMPTY(pcb_attribute_get(&subc->Attributes, "footprint")), + gen_locked(subc)); +} + +static void report_text(gds_t *dst, pcb_text_t *text) +{ +#ifndef NDEBUG + if (rnd_gui->shift_is_pressed(rnd_gui)) + rnd_r_dump_tree(text->parent.layer->text_tree, 0); +#endif + + rnd_append_printf(dst, "%m+TEXT ID# %ld; Flags:%s\n" + "BoundingBox %$mD %$mD.\n" + "Font id %d\nclearance %$mS\nthickness %$mS\nrotation %f\nScale: %d %f;%f\n" + , USER_UNITMASK, + text->ID, pcb_strflg_f2s(text->Flags, PCB_OBJ_TEXT, NULL, 0), + text->BoundingBox.X1, text->BoundingBox.Y1, + text->BoundingBox.X2, text->BoundingBox.Y2, + text->fid, text->clearance, text->thickness, text->rot, + text->Scale, text->scale_x, text->scale_y); +} + +static void report_gfx(gds_t *dst, pcb_gfx_t *gfx) +{ +#ifndef NDEBUG + if (rnd_gui->shift_is_pressed(rnd_gui)) + rnd_r_dump_tree(gfx->parent.layer->gfx_tree, 0); +#endif + + rnd_append_printf(dst, "%m+GFX ID# %ld; Flags:%s\n" + "BoundingBox %$mD %$mD.\n" + "Center %$mD\nSize %$mD\nrotation %f\n" + , USER_UNITMASK, + gfx->ID, pcb_strflg_f2s(gfx->Flags, PCB_OBJ_GFX, NULL, 0), + gfx->BoundingBox.X1, gfx->BoundingBox.Y1, + gfx->BoundingBox.X2, gfx->BoundingBox.Y2, + gfx->cx, gfx->cy, gfx->sx, gfx->sx, gfx->rot); +} + +static void report_point(gds_t *dst, int type, pcb_layer_t *layer, rnd_point_t *point) +{ + rnd_append_printf(dst, "%m+POINT ID# %ld.\n" + "Located at (X,Y) = %$mD.\n" + "It belongs to a %s on layer %d.\n", USER_UNITMASK, point->ID, + point->X, point->Y, + (type == PCB_OBJ_LINE_POINT) ? "line" : "polygon", pcb_layer_id(PCB->Data, layer)); +} + + +static fgw_error_t pcb_act_report_dialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + gds_t tmp; + void *ptr1, *ptr2, *ptr3; + int type = REPORT_TYPES; + char *op = NULL, *how = NULL; + pcb_subc_t *subc; + rnd_coord_t x, y; + rnd_hid_get_coords("Click on object to report on", &x, &y, 0); + + RND_ACT_MAY_CONVARG(1, FGW_STR, reportdialog, op = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, reportdialog, how = argv[2].val.str); + + gds_init(&tmp); + + if (op != NULL) { + if (rnd_strncasecmp(op, "Subc", 4) == 0) + type = PCB_OBJ_SUBC; + } + type = pcb_search_screen(x, y, type, &ptr1, &ptr2, &ptr3); + if ((type == PCB_OBJ_VOID) && (op == NULL)) + type = pcb_search_screen(x, y, REPORT_TYPES | PCB_OBJ_LOCKED, &ptr1, &ptr2, &ptr3); + + switch (type) { + case PCB_OBJ_PSTK: report_pstk(&tmp, ptr2); break; + case PCB_OBJ_LINE: report_line(&tmp, ptr2); break; + case PCB_OBJ_RAT: report_rat(&tmp, ptr2); break; + case PCB_OBJ_ARC: report_arc(&tmp, ptr2); break; + case PCB_OBJ_POLY: report_poly(&tmp, ptr2); break; + case PCB_OBJ_SUBC: report_subc(&tmp, ptr2); break; + case PCB_OBJ_TEXT: report_text(&tmp, ptr2); break; + case PCB_OBJ_GFX: report_gfx(&tmp, ptr2); break; + case PCB_OBJ_LINE_POINT: + case PCB_OBJ_POLY_POINT: report_point(&tmp, type, ptr1, ptr2); break; + case PCB_OBJ_VOID: + rnd_message(RND_MSG_INFO, "Nothing found to report on\n"); + RND_ACT_IRES(1); + return 0; + default: rnd_append_printf(&tmp, "Unknown\n"); break; + } + + subc = pcb_obj_parent_subc((pcb_any_obj_t *)ptr2); + if (subc != NULL) + rnd_append_printf(&tmp, "\nPart of subcircuit #%ld\n", subc->ID); + + { + pcb_idpath_t *idp = pcb_obj2idpath((pcb_any_obj_t *)ptr2); + gds_append_str(&tmp, "\nidpath: "); + pcb_append_idpath(&tmp, idp, 0); + pcb_idpath_destroy(idp); + } + + /* create dialog box */ + if ((how != NULL) && (strcmp(how, "log") == 0)) + rnd_message(RND_MSG_INFO, "--- Report ---\n%s---\n", tmp.array); + else + rdialog("Report", tmp.array); + gds_uninit(&tmp); + + RND_ACT_IRES(0); + return 0; +} + +static int report_found_pins(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + gds_t list; + int col = 0; + gdl_iterator_t sit; + pcb_subc_t *subc; + + gds_init(&list); + gds_append_str(&list, "The following terminals are FOUND:\n"); + + subclist_foreach(&PCB->Data->subc, &sit, subc) { + pcb_any_obj_t *o; + pcb_data_it_t it; + for(o = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) + if ((o->term != NULL) && (PCB_FLAG_TEST(PCB_FLAG_FOUND, o))) + rnd_append_printf(&list, "%s-%s,%c", subc->refdes, o->term, ((col++ % (conf_report.plugins.report.columns + 1)) == conf_report.plugins.report.columns) ? '\n' : ' '); + } + + rdialog("Report", list.array); + gds_uninit(&list); + return 0; +} + +static double xy_to_net_length(pcb_board_t *pcb, rnd_coord_t x, rnd_coord_t y, int *found, gds_t *err) +{ + long n, type, terms = 0; + void *p1, *p2, *p3; + pcb_qry_netseg_len_t *nl; + pcb_qry_exec_t ec; + double ret = -1; + pcb_net_t *onet = NULL; + + type = pcb_search_screen(x, y, PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_PSTK, &p1, &p2, &p3); + if (type == PCB_OBJ_VOID) { + rnd_append_printf(err, "\nno suitable starting object there!"); + *found = 0; + return -1; + } + + pcb_qry_init(&ec, pcb, NULL, -1); + nl = pcb_qry_parent_net_lenseg(&ec, (pcb_any_obj_t *)p2); + ret = nl->len; + *found = nl->objs.used; + + for(n = 0; n < nl->objs.used; n++) { + pcb_net_term_t *t = pcb_net_find_by_obj(&pcb->netlist[PCB_NETLIST_EDITED], nl->objs.array[n]); + if (t != NULL) { + pcb_net_t *net = t->parent.net; + assert(t->parent_type == PCB_PARENT_NET); + if (net != NULL) { + if (onet != net) + rnd_append_printf(err, "\nterminals or other networks are connected (shorted)"); + onet = net; + terms++; + } + } + } + + if (onet != NULL) { + long explen = pcb_termlist_length(&onet->conns); + if (explen != terms) + rnd_append_printf(err, "\nonly %ld terminals of the %ld on the network are connected!", terms, explen); + } + + if (nl->has_nontrace) + rnd_append_printf(err, "\n%Partial result: polygons/texts blocked the search"); + else if (nl->has_junction) + rnd_append_printf(err, "\n%Partial result: a junction blocked the search"); + + pcb_qry_uninit(&ec); + + return ret; +} + +static int report_all_net_lengths(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int found; + htsp_entry_t *e; + + for(e = htsp_first(&PCB->netlist[PCB_NETLIST_EDITED]); e != NULL; e = htsp_next(&PCB->netlist[PCB_NETLIST_EDITED], e)) { + pcb_net_t *net = e->value; + pcb_net_term_t *t; + pcb_any_obj_t *term; + + /* find the first terminal object referenced from the net that actually exist */ + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) { + term = pcb_term_find_name(PCB, PCB->Data, PCB_LYT_COPPER, t->refdes, t->term, NULL, NULL); + if (term != NULL) + break; + } + + if (term != NULL) { + char buf[50]; + const char *units_name = rnd_conf.editor.grid_unit->suffix; + rnd_coord_t length; + rnd_coord_t x = 0, y = 0; + gds_t err; + + RND_ACT_MAY_CONVARG(2, FGW_STR, Report, units_name = argv[2].val.str); + + pcb_obj_center(term, &x, &y); + + gds_init(&err); + length = xy_to_net_length(PCB_ACT_BOARD, x, y, &found, &err); + + rnd_snprintf(buf, sizeof(buf), "%$m*", units_name, length); + if (err.used != 0) + rnd_message(RND_MSG_INFO, "Net %s length %s, BUT BEWARE:%s\n", net->name, buf, err.array); + else + rnd_message(RND_MSG_INFO, "Net %s length %s\n", net->name, buf); + gds_uninit(&err); + } + } + + return 0; +} + +/* find any found object with a terminal ID and return the associated netname */ +static const char *net_name_found(pcb_board_t *pcb) +{ + PCB_SUBC_LOOP(pcb->Data); + { + pcb_any_obj_t *o; + pcb_data_it_t it; + + if (subc->refdes == NULL) + continue; + + for(o = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); o != NULL; o = pcb_data_next(&it)) { + pcb_net_term_t *t; + + if (o->term == NULL) + continue; + if (!PCB_FLAG_TEST(PCB_FLAG_FOUND, o)) + continue; + + t = pcb_net_find_by_refdes_term(&PCB->netlist[PCB_NETLIST_EDITED], subc->refdes, o->term); + if ((t != NULL) && (t->parent.net != NULL)) + return t->parent.net->name; + } + } + PCB_END_LOOP; + return NULL; +} + +static int report_net_length_(fgw_arg_t *res, int argc, fgw_arg_t *argv, rnd_coord_t x, rnd_coord_t y) +{ + rnd_coord_t length = 0; + int found = 0, ret; + gds_t err; + + gds_init(&err); + length = xy_to_net_length(PCB_ACT_BOARD, x, y, &found, &err); + + if (found) { + char buf[50]; + const char *netname = net_name_found(PCB); + + rnd_snprintf(buf, sizeof(buf), "%$m*", rnd_conf.editor.grid_unit->suffix, length); + if (netname) + rnd_message(RND_MSG_INFO, "Net \"%s\" length: %s\n", netname, buf); + else + rnd_message(RND_MSG_INFO, "Net length: %s\n", buf); + + if (err.used != 0) + rnd_message(RND_MSG_INFO, "BUT BEWARE: %s\n", err.array); + + ret = 0; + } + else { + rnd_message(RND_MSG_ERROR, "No net under cursor.\n"); + ret = 1; + } + + gds_uninit(&err); + return ret; +} + +static int report_net_length(fgw_arg_t *res, int argc, fgw_arg_t *argv, int split) +{ + + if (split) { + void *r1, *r2, *r3; + pcb_line_t *l; + pcb_layer_t *ly; + int type; + rnd_coord_t ox, oy, x, y; + + rnd_hid_get_coords("Click on a copper line", &x, &y, 0); + + type = pcb_search_screen(x, y, PCB_OBJ_LINE, &r1, &r2, &r3); + if (type != PCB_OBJ_LINE) { + rnd_message(RND_MSG_ERROR, "can't find a line to split\n"); + return -1; + } + l = r2; + assert(l->parent_type == PCB_PARENT_LAYER); + ly = l->parent.layer; + if (!(pcb_layer_flags_(ly) & PCB_LYT_COPPER)) { + rnd_message(RND_MSG_ERROR, "not a copper line, can't split it\n"); + return -1; + } + +#define MINDIST RND_MIL_TO_COORD(40) + if ((rnd_distance(l->Point1.X, l->Point1.Y, x, y) < MINDIST) || (rnd_distance(l->Point2.X, l->Point2.Y, x, y) < MINDIST)) { + rnd_message(RND_MSG_ERROR, "Can not split near the endpoint of a line\n"); + return -1; + } +#undef MINDIST2 + + rnd_message(RND_MSG_INFO, "The two arms of the net are:\n"); + rnd_r_delete_entry(ly->line_tree, (rnd_box_t *)l); + ox = l->Point1.X; oy = l->Point1.Y; l->Point1.X = x; l->Point1.Y = y; + rnd_r_insert_entry(ly->line_tree, (rnd_box_t *)l); + report_net_length_(res, argc, argv, x, y); + rnd_r_delete_entry(ly->line_tree, (rnd_box_t *)l); + l->Point1.X = ox; l->Point1.Y = oy; + rnd_r_insert_entry(ly->line_tree, (rnd_box_t *)l); + + rnd_r_delete_entry(ly->line_tree, (rnd_box_t *)l); + ox = l->Point2.X; oy = l->Point2.Y; l->Point2.X = x; l->Point2.Y = y; + rnd_r_insert_entry(ly->line_tree, (rnd_box_t *)l); + report_net_length_(res, argc, argv, x, y); + rnd_r_delete_entry(ly->line_tree, (rnd_box_t *)l); + l->Point2.X = ox; l->Point2.Y = oy; + rnd_r_insert_entry(ly->line_tree, (rnd_box_t *)l); + + PCB_FLAG_SET(PCB_FLAG_SELECTED, l); + + return 0; + } + else { + rnd_coord_t x, y; + rnd_hid_get_coords("Click on a network", &x, &y, 0); + return report_net_length_(res, argc, argv, x, y); + } +} + +static int report_net_length_by_name(pcb_board_t *pcb, const char *tofind) +{ + const char *netname = NULL; + pcb_net_t *net; + rnd_coord_t length = 0; + int found = 0; + rnd_coord_t x, y; + gds_t err; + + if (pcb == NULL) + return 1; + + if (!tofind) + return 1; + + { + net = pcb_net_get_user(pcb, &pcb->netlist[PCB_NETLIST_EDITED], tofind); + if (net != NULL) { + pcb_net_term_t *term; + pcb_any_obj_t *obj = NULL; + + netname = net->name; + term = pcb_termlist_first(&net->conns); + if (term == NULL) { + rnd_message(RND_MSG_INFO, "Net found, but it has not terminals.\n"); + return 1; + } + + obj = pcb_term_find_name(pcb, pcb->Data, PCB_LYT_COPPER, term->refdes, term->term, NULL, NULL); + if (obj == NULL) { + rnd_message(RND_MSG_INFO, "Net found, but its terminal %s-%s is not on the board.\n", term->refdes, term->term); + return 1; + } + pcb_obj_center(obj, &x, &y); + } + } + + if (netname == NULL) { + rnd_message(RND_MSG_ERROR, "No net named %s\n", tofind); + return 1; + } + + + gds_init(&err); + length = xy_to_net_length(pcb, x, y, &found, &err); + + if (!found) { + if (netname != NULL) + rnd_message(RND_MSG_INFO, "Net found, but no lines or arcs were flagged.\n"); + else + rnd_message(RND_MSG_ERROR, "Net not found.\n"); + + gds_uninit(&err); + return 1; + } + + { + char buf[50]; + rnd_snprintf(buf, sizeof(buf), "%$m*", rnd_conf.editor.grid_unit->suffix, length); + if (netname) + rnd_message(RND_MSG_INFO, "Net \"%s\" length: %s\n", netname, buf); + else + rnd_message(RND_MSG_INFO, "Net length: %s\n", buf); + if (err.used != 0) + rnd_message(RND_MSG_INFO, "BUT BEWARE: %s\n", err.array); + } + + gds_uninit(&err); + return 0; +} + +/* DOC: report.html */ +static fgw_error_t pcb_act_Report(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd, *name; + rnd_coord_t x, y; + + RND_ACT_CONVARG(1, FGW_STR, Report, cmd = argv[1].val.str); + + if (rnd_strcasecmp(cmd, "Object") == 0) { + rnd_hid_get_coords("Click on an object", &x, &y, 0); + return pcb_act_report_dialog(res, argc, argv); + } + else if (rnd_strncasecmp(cmd, "Subc", 4) == 0) { + rnd_hid_get_coords("Click on a subcircuit", &x, &y, 0); + return pcb_act_report_dialog(res, argc, argv); + } + + rnd_hid_get_coords("Click on object to report on", &x, &y, 0); + + if (rnd_strcasecmp(cmd, "DrillReport") == 0) + return report_drills(res, argc, argv); + else if (rnd_strcasecmp(cmd, "FoundPins") == 0) + return report_found_pins(res, argc, argv); + else if ((rnd_strcasecmp(cmd, "NetLength") == 0) && (argc == 2)) + return report_net_length(res, argc, argv, 0); + else if ((rnd_strcasecmp(cmd, "NetLengthTo") == 0) && (argc == 2)) + return report_net_length(res, argc, argv, 1); + else if (rnd_strcasecmp(cmd, "AllNetLengths") == 0) + return report_all_net_lengths(res, argc, argv); + else if (rnd_strcasecmp(cmd, "NetLength") == 0) { + RND_ACT_CONVARG(2, FGW_STR, Report, name = argv[2].val.str); + return report_net_length_by_name(PCB_ACT_BOARD, name); + } + + RND_ACT_FAIL(Report); +} + +static fgw_error_t pcb_act_info(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int i, j; + if (!PCB || !PCB->Data || !PCB->hidlib.filename) { + printf("No PCB loaded.\n"); + return 0; + } + printf("Filename: %s\n", PCB->hidlib.filename); + rnd_printf("Size: %ml x %ml mils, %mm x %mm mm\n", PCB->hidlib.size_x, PCB->hidlib.size_y, PCB->hidlib.size_x, PCB->hidlib.size_y); + for (i = 0; i < PCB_MAX_LAYER; i++) { + rnd_layergrp_id_t lg = pcb_layer_get_group(PCB, i); + unsigned int gflg = pcb_layergrp_flags(PCB, lg); + for (j = 0; j < PCB_MAX_LAYER; j++) + putchar(j == lg ? '#' : '-'); + printf(" %c %s\n", (gflg & PCB_LYT_TOP) ? 'c' : (gflg & PCB_LYT_BOTTOM) ? 's' : '-', PCB->Data->Layer[i].name); + } + RND_ACT_IRES(0); + return 0; +} + +static void print_net_length_label(pcb_board_t *pcb, pcb_layer_t *ly, pcb_qry_netseg_len_t *nl, rnd_coord_t atx, rnd_coord_t aty, rnd_coord_t ldx, rnd_coord_t ldy, rnd_coord_t th) +{ + rnd_coord_t tx, ty; + double dx, dy, len; + char tmp[256]; + pcb_text_t *t; + + if ((ldx == 0) && (ldy == 0)) + ldx = ldy = 1; + len = sqrt((double)ldx*(double)ldx + (double)ldy*(double)ldy); + dx = (double)ldx / len; dy = (double)ldy / len; + + rnd_snprintf(tmp, sizeof(tmp), "%m+len=%.02$$mS via=%d%s", rnd_conf.editor.grid_unit->allow, nl->len, nl->num_vias, nl->has_junction ? " BAD" : ""); + + tx = atx+dx*th*50; ty = aty+dy*th*50; + t = pcb_text_new(ly, pcb_font(pcb, 0, 1), tx, ty, 0, 25, th, tmp, pcb_no_flags()); + if (nl->has_junction) + t->override_color = rnd_clrdup(rnd_color_red); + + pcb_line_new(ly, t->bbox_naked.X1, t->bbox_naked.Y1, t->bbox_naked.X2, t->bbox_naked.Y1, th, 0, pcb_no_flags()); + pcb_line_new(ly, t->bbox_naked.X1, t->bbox_naked.Y1, t->bbox_naked.X1, t->bbox_naked.Y2, th, 0, pcb_no_flags()); + pcb_line_new(ly, t->bbox_naked.X2, t->bbox_naked.Y2, t->bbox_naked.X2, t->bbox_naked.Y1, th, 0, pcb_no_flags()); + pcb_line_new(ly, t->bbox_naked.X2, t->bbox_naked.Y2, t->bbox_naked.X1, t->bbox_naked.Y2, th, 0, pcb_no_flags()); + + pcb_line_new(ly, atx, aty, t->bbox_naked.X1, t->bbox_naked.Y1, th, 0, pcb_no_flags()); + +} + +static void print_net_length(pcb_board_t *pcb, pcb_layer_t *ly, pcb_qry_netseg_len_t *nl) +{ + pcb_any_obj_t *lo = NULL; + rnd_coord_t ldx, ldy, atx, aty; + long n; + static const rnd_coord_t th = RND_MM_TO_COORD(0.025); + for(n = 0; n < nl->objs.used; n++) { + pcb_line_t *l = (pcb_line_t *)nl->objs.array[n]; + pcb_arc_t *a = (pcb_arc_t *)l; + pcb_pstk_t *ps = (pcb_pstk_t *)l; + + switch(l->type) { + case PCB_OBJ_LINE: + pcb_line_new(ly, l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y, th, 0, pcb_no_flags()); + if (n == 0) { + ldx = -(l->Point2.Y - l->Point1.Y); /* perpendicular to the line */ + ldy = +(l->Point2.X - l->Point1.X); + atx = (l->Point1.X + l->Point2.X)/2; + aty = (l->Point1.Y + l->Point2.Y)/2; + lo = (pcb_any_obj_t *)l; + } + break; + case PCB_OBJ_ARC: + pcb_arc_new(ly, a->X, a->Y, a->Width, a->Height, a->StartAngle, a->Delta, th, 0, pcb_no_flags(), 0); + if (n == 0) { + ldx = -1; + ldy = -1; + atx = ps->x; + aty = ps->y; + lo = (pcb_any_obj_t *)l; + } + break; + case PCB_OBJ_PSTK: + pcb_arc_new(ly, ps->x, ps->y, th*4, th*4, 0, 360, th, 0, pcb_no_flags(), 0); + if (n == 0) { + + atx = ps->x; + aty = ps->y; + ldx = ldy = 1; + lo = (pcb_any_obj_t *)l; + } + break; + default: break; + } + } + + if (lo != NULL) + print_net_length_label(pcb, ly, nl, atx, aty, ldx, ldy, th/4); +} + +static const char pcb_acts_NetLength[] = + "NetLength(clear)\n" + "NetLength(object)\n"; +static const char pcb_acth_NetLength[] = "Report physical network length"; +static fgw_error_t pcb_act_NetLength(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_board_t *pcb = PCB_ACT_BOARD; + const char *cmd; + static pcb_layer_t *ly = NULL; + + RND_ACT_CONVARG(1, FGW_STR, NetLength, cmd = argv[1].val.str); + + if (strcmp(cmd, "clear") == 0) { + if (ly != NULL) { + pcb_uilayer_free(ly); + ly = NULL; + } + return 0; + } + + /* anything below needs the layer */ + + if (ly == NULL) + ly = pcb_uilayer_alloc("NetLength", "Net length", rnd_color_blue); + + if (strcmp(cmd, "object") == 0) { + int type; + rnd_coord_t x, y; + void *p1, *p2, *p3; + pcb_qry_netseg_len_t *nl; + pcb_qry_exec_t ec; + + rnd_hid_get_coords("Click on an object for net length measurement", &x, &y, 0); + + type = pcb_search_screen(x, y, PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_PSTK, &p1, &p2, &p3); + if (type == PCB_OBJ_VOID) + goto error; + + pcb_qry_init(&ec, pcb, NULL, -1); + nl = pcb_qry_parent_net_lenseg(&ec, (pcb_any_obj_t *)p2); + print_net_length(pcb, ly, nl); + pcb_qry_uninit(&ec); + } + + return 0; + error: + RND_ACT_IRES(-1); + return 0; +} + +rnd_action_t report_action_list[] = { + {"ReportObject", pcb_act_report_dialog, pcb_acth_reportdialog, pcb_acts_reportdialog}, + {"Report", pcb_act_Report, pcb_acth_Report, pcb_acts_Report}, + {"NetLength", pcb_act_NetLength, pcb_acth_NetLength, pcb_acts_NetLength}, + {"Info", pcb_act_info} +}; + +static const char *report_cookie = "report plugin"; + +int pplg_check_ver_report(int ver_needed) { return 0; } + +void pplg_uninit_report(void) +{ + rnd_remove_actions_by_cookie(report_cookie); + rnd_conf_unreg_fields("plugins/report/"); +} + +int pplg_init_report(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(report_action_list, report_cookie) +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_report, field,isarray,type_name,cpath,cname,desc,flags); +#include "report_conf_fields.h" + return 0; +} Index: tags/2.3.0/src_plugins/report/report.h =================================================================== --- tags/2.3.0/src_plugins/report/report.h (nonexistent) +++ tags/2.3.0/src_plugins/report/report.h (revision 33253) @@ -0,0 +1,39 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_REPORT_H +#define PCB_REPORT_H + +#include "config.h" + +#define REPORT_TYPES \ + (PCB_OBJ_PSTK | PCB_OBJ_LINE | PCB_OBJ_TEXT | PCB_OBJ_POLY | PCB_OBJ_GFX | \ + PCB_OBJ_ARC | PCB_OBJ_RAT | PCB_OBJ_POLY_POINT | \ + PCB_OBJ_LINE_POINT | PCB_OBJ_SUBC_PART | PCB_OBJ_SUBC) + +#endif Index: tags/2.3.0/src_plugins/report/report.pup =================================================================== --- tags/2.3.0/src_plugins/report/report.pup (nonexistent) +++ tags/2.3.0/src_plugins/report/report.pup (revision 33253) @@ -0,0 +1,8 @@ +$class feature +$short report actions +$long Report() and ReportObject() actions - print a report about design objects. +$state works +$package (core) +dep query +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/report/report_conf.h =================================================================== --- tags/2.3.0/src_plugins/report/report_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/report/report_conf.h (revision 33253) @@ -0,0 +1,16 @@ +#ifndef PCB_MINCUT_CONF_H +#define PCB_MINCUT_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_INTEGER columns; /* @usage number of columns for found pin report */ + } report; + } plugins; +} conf_report_t; + +extern conf_report_t conf_report; + +#endif Index: tags/2.3.0/src_plugins/rubberband_orig/Makefile =================================================================== --- tags/2.3.0/src_plugins/rubberband_orig/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/rubberband_orig/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_rubberband_orig + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/rubberband_orig/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/rubberband_orig/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/rubberband_orig/Plug.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +put /local/pcb/mod {rubberband_orig} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/rubberband_orig/rubberband.o + $(PLUGDIR)/rubberband_orig/fgeometry.o +@] +put /local/pcb/mod/CONF {$(PLUGDIR)/rubberband_orig/rubberband_conf.h} + +switch /local/pcb/rubberband_orig/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/rubberband_orig/fgeometry.c =================================================================== --- tags/2.3.0/src_plugins/rubberband_orig/fgeometry.c (nonexistent) +++ tags/2.3.0/src_plugins/rubberband_orig/fgeometry.c (revision 33253) @@ -0,0 +1,177 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2017 Luis de Arquer + * + * 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. + * + + some parts based on src/polygon1.c + based on: + poly_Boolean: a polygon clip library + Copyright (C) 1997 Alexey Nikitin, Michael Leonov + (also the authors of the paper describing the actual algorithm) + leonov@propro.iis.nsk.su + + in turn based on: + nclip: a polygon clip library + Copyright (C) 1993 Klamer Schutte + + polygon1.c + (C) 1997 Alexey Nikitin, Michael Leonov + (C) 1993 Klamer Schutte + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") +*/ + + +#include "fgeometry.h" +#include +#include + +#define MIN_COMPONENT 0.000001 + +int pcb_fvector_is_null(pcb_fvector_t v) +{ + return fabs(v.x) < MIN_COMPONENT && fabs(v.y) < MIN_COMPONENT; +} + +double pcb_fvector_dot(pcb_fvector_t v1, pcb_fvector_t v2) +{ + return v1.x * v2.x + v1.y * v2.y; +} + + +void pcb_fvector_normalize(pcb_fvector_t *v) +{ + double module = sqrt(v->x * v->x + v->y * v->y); + + v->x /= module; + v->y /= module; +} + +int pcb_fline_is_valid(pcb_fline_t l) +{ + return !pcb_fvector_is_null(l.direction); +} + +pcb_fline_t pcb_fline_create(pcb_any_line_t *line) +{ + pcb_fline_t ret; + + ret.point.x = line->Point1.X; + ret.point.y = line->Point1.Y; + ret.direction.x = line->Point2.X - line->Point1.X; + ret.direction.y = line->Point2.Y - line->Point1.Y; + + if (!pcb_fvector_is_null(ret.direction)) + pcb_fvector_normalize(&ret.direction); + + return ret; +} + + +pcb_fline_t pcb_fline_create_from_points(struct rnd_point_s *base_point, struct rnd_point_s *other_point) +{ + pcb_fline_t ret; + + ret.point.x = base_point->X; + ret.point.y = base_point->Y; + ret.direction.x = other_point->X - base_point->X; + ret.direction.y = other_point->Y - base_point->Y; + + if (!pcb_fvector_is_null(ret.direction)) + pcb_fvector_normalize(&ret.direction); + + return ret; +} + + +pcb_fvector_t pcb_fline_intersection(pcb_fline_t l1, pcb_fline_t l2) +{ + pcb_fvector_t ret; + double lines_dot; + + ret.x = 0; + ret.y = 0; + + lines_dot = pcb_fvector_dot(l1.direction, l2.direction); + if (fabs(lines_dot) > 0.990) { + /* Consider them parallel. Return null point (vector) */ + return ret; + } + + { + /* + * *** From polygon1.c *** + * We have the lines: + * l1: p1 + s*d1 + * l2: p2 + t*d2 + * And we want to know the intersection point. + * Calculate t: + * p1 + s*d1 = p2 + t*d2 + * which is similar to the two equations: + * p1x + s * d1x = p2x + t * d2x + * p1y + s * d1y = p2y + t * d2y + * Multiplying these by d1y resp. d1x gives: + * d1y * p1x + s * d1x * d1y = d1y * p2x + t * d1y * d2x + * d1x * p1y + s * d1x * d1y = d1x * p2y + t * d1x * d2y + * Subtracting these gives: + * d1y * p1x - d1x * p1y = d1y * p2x - d1x * p2y + t * ( d1y * d2x - d1x * d2y ) + * So t can be isolated: + * t = (d1y * ( p1x - p2x ) + d1x * ( - p1y + p2y )) / ( d1y * d2x - d1x * d2y ) + * and s can be found similarly + * s = (d2y * ( p2x - p1x ) + d2x * ( p1y - p2y )) / ( d2y * d1x - d2x * d1y) + */ + + double t; + double p1x, p1y, d1x, d1y; + double p2x, p2y, d2x, d2y; + + p1x = l1.point.x; + p1y = l1.point.y; + d1x = l1.direction.x; + d1y = l1.direction.y; + + p2x = l2.point.x; + p2y = l2.point.y; + d2x = l2.direction.x; + d2y = l2.direction.y; + + t = (d1y * (p1x - p2x) + d1x * (-p1y + p2y)) / (d1y * d2x - d1x * d2y); + +#if 0 +/* Can we remove this? */ + { + double s = (d2y * (p2x - p1x) + d2x * (p1y - p2y)) / (d2y * d1x - d2x * d1y); + rnd_trace("Intersection t=%f, s=%f\n", t, s); + + ret.x = p1x + s * d1x; + ret.y = p1y + s * d1y; + } +#endif + + ret.x = p2x + t * d2x; + ret.y = p2y + t * d2y; + + /*rnd_trace("Intersection x=%f, y=%f\n", ret.x, ret.y); */ + } + return ret; +} Index: tags/2.3.0/src_plugins/rubberband_orig/fgeometry.h =================================================================== --- tags/2.3.0/src_plugins/rubberband_orig/fgeometry.h (nonexistent) +++ tags/2.3.0/src_plugins/rubberband_orig/fgeometry.h (revision 33253) @@ -0,0 +1,38 @@ + +#ifndef PCB_FGEOMETRY_H +#define PCB_FGEOMETRY_H + +#include "obj_common.h" + +typedef struct pcb_fvector_s { + double x; + double y; +} pcb_fvector_t; + + +/* flines should be created through fline_create* functions. + * Alternatively, they can be created manually as long as + * direction is normalized + */ +typedef struct pcb_fline_s { + pcb_fvector_t point; + pcb_fvector_t direction; +} pcb_fline_t; + +int pcb_fvector_is_null(pcb_fvector_t v); + + +/* Any vector given to the following functions has to be non-null */ +double pcb_fvector_dot(pcb_fvector_t v1, pcb_fvector_t v2); +void pcb_fvector_normalize(pcb_fvector_t *v); + + +pcb_fline_t pcb_fline_create(pcb_any_line_t *line); +pcb_fline_t pcb_fline_create_from_points(struct rnd_point_s *base_point, struct rnd_point_s *other_point); + +int pcb_fline_is_valid(pcb_fline_t l); + +/* l1.direction and l2.direction are expected to be normalized */ +pcb_fvector_t pcb_fline_intersection(pcb_fline_t l1, pcb_fline_t l2); + +#endif Index: tags/2.3.0/src_plugins/rubberband_orig/rubberband.c =================================================================== --- tags/2.3.0/src_plugins/rubberband_orig/rubberband.c (nonexistent) +++ tags/2.3.0/src_plugins/rubberband_orig/rubberband.c (revision 33253) @@ -0,0 +1,1491 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 Thomas Nau + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "board.h" +#include "data.h" +#include "data_it.h" +#include "data_list.h" +#include +#include "event.h" +#include "undo.h" +#include "operation.h" +#include "rotate.h" +#include "draw.h" +#include "draw_wireframe.h" +#include "crosshair.h" +#include "obj_rat_draw.h" +#include "obj_line_op.h" +#include "obj_line_draw.h" +#include "obj_pstk_inlines.h" +#include "route_draw.h" +#include +#include "conf_core.h" +#include +#include "layer_grp.h" +#include "fgeometry.h" +#include "search.h" + +#include "polygon.h" + +#include "rubberband_conf.h" +conf_rubberband_orig_t conf_rbo; + + +typedef struct { /* rubberband lines for element moves */ + pcb_layer_t *Layer; /* layer that holds the line */ + pcb_line_t *Line; /* the line itself */ + int delta_index[2]; /* The index into the delta array for the two line points */ +} pcb_rb_line_t; + +typedef struct { + pcb_layer_t *Layer; /* Layer that holds the arc */ + pcb_arc_t *Arc; /* The arc itself */ + int delta_index[2]; /* The index into the delta array for each arc end. -1 = end not attached */ +} pcb_rb_arc_t; + +#define GVT(x) vtrbli_ ## x +#define GVT_ELEM_TYPE pcb_rb_line_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 +#include + +#define GVT(x) vtrbar_ ## x +#define GVT_ELEM_TYPE pcb_rb_arc_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 +#include + + + +typedef struct { + vtrbli_t lines; + vtrbar_t arcs; +} rubber_ctx_t; + +static rubber_ctx_t rubber_band_state; + + +struct rubber_info { + rnd_coord_t radius; + rnd_coord_t X, Y; + pcb_line_t *line; + rnd_box_t box; + pcb_layer_t *layer; + rubber_ctx_t *rbnd; + int delta_index; +}; + + +static pcb_rb_line_t *pcb_rubber_band_create(rubber_ctx_t *rbnd, pcb_layer_t *Layer, pcb_line_t *Line, int point_number, int delta_index); +static pcb_rb_arc_t *pcb_rubber_band_create_arc(rubber_ctx_t *rbnd, pcb_layer_t *Layer, pcb_arc_t *Line, int end, int delta_index); +static void CheckLinePointForRubberbandConnection(rubber_ctx_t *rbnd, pcb_layer_t *, pcb_line_t *, rnd_point_t *, int delta_index); +static void CheckArcPointForRubberbandConnection(rubber_ctx_t *rbnd, pcb_layer_t *, pcb_arc_t *, int *, rnd_bool); +static void CheckArcForRubberbandConnection(rubber_ctx_t *rbnd, pcb_layer_t *, pcb_arc_t *, rnd_bool); +static void CheckPolygonForRubberbandConnection(rubber_ctx_t *rbnd, pcb_layer_t *, pcb_poly_t *); +static void CheckLinePointForRat(rubber_ctx_t *rbnd, pcb_layer_t *, rnd_point_t *); +static void CheckLineForRubberbandConnection(rubber_ctx_t *rbnd, pcb_layer_t *, pcb_line_t *); + +static void calculate_route_rubber_arc_point_move(pcb_rb_arc_t *arcptr, int end, rnd_coord_t dx, rnd_coord_t dy, pcb_route_t *route); + +static void CheckLinePointForRubberbandArcConnection(rubber_ctx_t *rbnd, pcb_layer_t *, pcb_line_t *, rnd_point_t *, rnd_bool); + +static rnd_r_dir_t rubber_callback(const rnd_box_t *b, void *cl); +static rnd_r_dir_t rubber_callback_arc(const rnd_box_t *b, void *cl); + +/* Returns whether obj is under subc lock: part of a subc and is not a floater */ +static int rbe_subc_locked(pcb_any_obj_t *obj) +{ + pcb_data_t *data = obj->parent.layer->parent.data; + + if ((data == NULL) || (data->parent_type != PCB_PARENT_SUBC)) + return 0; + + if (PCB_FLAG_TEST(PCB_FLAG_FLOATER, obj)) + return 0; + + return 1; +} + +static rnd_r_dir_t rubber_callback(const rnd_box_t *b, void *cl) +{ + pcb_line_t *line = (pcb_line_t *) b; + pcb_rb_line_t *have_line = NULL; + struct rubber_info *i = (struct rubber_info *)cl; + rubber_ctx_t *rbnd = i->rbnd; + double x, y, rad, dist1, dist2; + rnd_coord_t t; + int n, touches1 = 0, touches2 = 0; + int have_point1 = 0; + int have_point2 = 0; + + t = line->Thickness / 2; + + /* Don't add the line if both ends of it are already in the list. */ + for(n = 0; (n < rbnd->lines.used) && (have_line == NULL); n++) + if (rbnd->lines.array[n].Line == line) { + have_line = &rbnd->lines.array[n]; + if (rbnd->lines.array[n].delta_index[0] >= 0) + have_point1 = 1; + if (rbnd->lines.array[n].delta_index[1] >= 0) + have_point2 = 1; + } + + if (have_point1 && have_point2) + return RND_R_DIR_NOT_FOUND; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, line)) + return RND_R_DIR_NOT_FOUND; + + /* subc lock: only floaters may be modified */ + if (rbe_subc_locked((pcb_any_obj_t *)line)) + return RND_R_DIR_NOT_FOUND; + + if (line == i->line) + return RND_R_DIR_NOT_FOUND; + + /* + * Check to see if the line touches a rectangular region. + * To do this we need to look for the intersection of a circular + * region and a rectangular region. + */ + if (i->radius == 0) { + + if (!have_point1 && line->Point1.X + t >= i->box.X1 && line->Point1.X - t <= i->box.X2 && line->Point1.Y + t >= i->box.Y1 && line->Point1.Y - t <= i->box.Y2) { + if (((i->box.X1 <= line->Point1.X) && (line->Point1.X <= i->box.X2)) || ((i->box.Y1 <= line->Point1.Y) && (line->Point1.Y <= i->box.Y2))) { + /* + * The circle is positioned such that the closest point + * on the rectangular region boundary is not at a corner + * of the rectangle. i.e. the shortest line from circle + * center to rectangle intersects the rectangle at 90 + * degrees. In this case our first test is sufficient + */ + touches1 = 1; + } + else { + /* + * Now we must check the distance from the center of the + * circle to the corners of the rectangle since the + * closest part of the rectangular region is the corner. + */ + x = MIN(coord_abs(i->box.X1 - line->Point1.X), coord_abs(i->box.X2 - line->Point1.X)); + x *= x; + y = MIN(coord_abs(i->box.Y1 - line->Point1.Y), coord_abs(i->box.Y2 - line->Point1.Y)); + y *= y; + x = x + y - (t * t); + + if (x <= 0) + touches1 = 1; + } + } + if (!have_point2 && line->Point2.X + t >= i->box.X1 && line->Point2.X - t <= i->box.X2 && line->Point2.Y + t >= i->box.Y1 && line->Point2.Y - t <= i->box.Y2) { + if (((i->box.X1 <= line->Point2.X) && (line->Point2.X <= i->box.X2)) || ((i->box.Y1 <= line->Point2.Y) && (line->Point2.Y <= i->box.Y2))) { + touches2 = 1; + } + else { + x = MIN(coord_abs(i->box.X1 - line->Point2.X), coord_abs(i->box.X2 - line->Point2.X)); + x *= x; + y = MIN(coord_abs(i->box.Y1 - line->Point2.Y), coord_abs(i->box.Y2 - line->Point2.Y)); + y *= y; + x = x + y - (t * t); + + if (x <= 0) + touches2 = 1; + } + } + } + else { + /* circular search region */ + if (i->radius < 0) + rad = 0; /* require exact match */ + else + rad = RND_SQUARE(i->radius + t); + + x = (i->X - line->Point1.X); + x *= x; + y = (i->Y - line->Point1.Y); + y *= y; + dist1 = x + y - rad; + + x = (i->X - line->Point2.X); + x *= x; + y = (i->Y - line->Point2.Y); + y *= y; + dist2 = x + y - rad; + + if (dist1 > 0 && dist2 > 0) + return RND_R_DIR_NOT_FOUND; +#if 0 +#ifdef CLOSEST_ONLY /* keep this to remind me */ + if ((dist1 < dist2) && !have_point1) + touches1 = 1; + else if (!have_point2) + touches2 = 1; +#else + if ((dist1 <= 0) && !have_point1) + touches1 = 1; + if ((dist2 <= 0) && !have_point2) + touches2 = 1; +#endif +#endif + if ((dist1 <= 0) && !have_point1) + touches1 = 1; + if ((dist2 <= 0) && !have_point2) + touches2 = 1; + } + + if (touches1) { + if (have_line) + have_line->delta_index[0] = i->delta_index; + else + have_line = pcb_rubber_band_create(rbnd, i->layer, line, 0, i->delta_index); + } + + if (touches2) { + if (have_line) + have_line->delta_index[1] = i->delta_index; + else + pcb_rubber_band_create(rbnd, i->layer, line, 1, i->delta_index); + } + + return touches1 || touches2 ? RND_R_DIR_FOUND_CONTINUE : RND_R_DIR_NOT_FOUND; +} + +static rnd_r_dir_t rubber_callback_arc(const rnd_box_t *b, void *cl) +{ + pcb_arc_t *arc = (pcb_arc_t *) b; + struct rubber_info *i = (struct rubber_info *)cl; + rubber_ctx_t *rbnd = i->rbnd; + double x, y, rad, dist1, dist2; + rnd_coord_t t; + rnd_coord_t ex1, ey1; + rnd_coord_t ex2, ey2; + int n = 0; + int have_point1 = 0; + int have_point2 = 0; + + /* If the arc is locked then don't add it to the rubberband list. */ + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, arc)) + return RND_R_DIR_NOT_FOUND; + + /* subc lock: only floaters may be modified */ + if (rbe_subc_locked((pcb_any_obj_t *)arc)) + return RND_R_DIR_NOT_FOUND; + + /* Don't add the arc if both ends of it are already in the list. */ + for(n = 0; n < rbnd->arcs.used; n++) + if (rbnd->arcs.array[n].Arc == arc) { + have_point1 = !(rbnd->arcs.array[n].delta_index[0] < 0); + have_point2 = !(rbnd->arcs.array[n].delta_index[1] < 0); + } + + if (have_point1 && have_point2) + return RND_R_DIR_NOT_FOUND; + + /* Calculate the arc end points */ + pcb_arc_get_end(arc, 0, &ex1, &ey1); + pcb_arc_get_end(arc, 1, &ex2, &ey2); + + /* circular search region */ + t = arc->Thickness / 2; + + if (i->radius < 0) + rad = 0; /* require exact match */ + else + rad = RND_SQUARE(i->radius + t); + + x = (i->X - ex1); + x *= x; + y = (i->Y - ey1); + y *= y; + dist1 = x + y - rad; + + x = (i->X - ex2); + x *= x; + y = (i->Y - ey2); + y *= y; + dist2 = x + y - rad; + + if (dist1 > 0 && dist2 > 0) + return RND_R_DIR_NOT_FOUND; + + /* The Arc end-point is touching so create an entry in the rubberband arc list */ + +#ifdef CLOSEST_ONLY /* keep this to remind me */ + if ((dist1 < dist2) && !have_point1) + pcb_rubber_band_create_arc(rbnd, i->layer, arc, 0); + else if (!have_point2) + pcb_rubber_band_create_arc(rbnd, i->layer, arc, 1); +#else + if ((dist1 <= 0) && !have_point1) + pcb_rubber_band_create_arc(rbnd, i->layer, arc, 0, i->delta_index); + if ((dist2 <= 0) && !have_point2) + pcb_rubber_band_create_arc(rbnd, i->layer, arc, 1, i->delta_index); +#endif + + return RND_R_DIR_FOUND_CONTINUE; +} + +struct rinfo { + int type; + rnd_layergrp_id_t group; + pcb_pstk_t *pstk; + rnd_point_t *point; + rubber_ctx_t *rbnd; + int delta_index; +}; + +static rnd_r_dir_t rat_callback(const rnd_box_t *box, void *cl) +{ + pcb_rat_t *rat = (pcb_rat_t *) box; + struct rinfo *i = (struct rinfo *)cl; + rubber_ctx_t *rbnd = i->rbnd; + + switch (i->type) { + case PCB_OBJ_PSTK: + if (rat->Point1.X == i->pstk->x && rat->Point1.Y == i->pstk->y) + pcb_rubber_band_create(rbnd, NULL, (pcb_line_t *) rat, 0, i->delta_index); + else if (rat->Point2.X == i->pstk->x && rat->Point2.Y == i->pstk->y) + pcb_rubber_band_create(rbnd, NULL, (pcb_line_t *) rat, 1, i->delta_index); + break; + case PCB_OBJ_LINE_POINT: + if (rat->group1 == i->group && rat->Point1.X == i->point->X && rat->Point1.Y == i->point->Y) + pcb_rubber_band_create(rbnd, NULL, (pcb_line_t *) rat, 0, i->delta_index); + else if (rat->group2 == i->group && rat->Point2.X == i->point->X && rat->Point2.Y == i->point->Y) + pcb_rubber_band_create(rbnd, NULL, (pcb_line_t *) rat, 1, i->delta_index); + break; + default: + rnd_message(RND_MSG_ERROR, "hace: bad rubber-rat lookup callback\n"); + } + return RND_R_DIR_NOT_FOUND; +} + +static void CheckPadstackForRat(rubber_ctx_t *rbnd, pcb_pstk_t *pstk) +{ + struct rinfo info; + + info.type = PCB_OBJ_PSTK; + info.pstk = pstk; + info.rbnd = rbnd; + info.delta_index = 0; + rnd_r_search(PCB->Data->rat_tree, &pstk->BoundingBox, NULL, rat_callback, &info, NULL); +} + +static void CheckLinePointForRat(rubber_ctx_t *rbnd, pcb_layer_t *Layer, rnd_point_t *Point) +{ + struct rinfo info; + info.group = pcb_layer_get_group_(Layer); + info.point = Point; + info.type = PCB_OBJ_LINE_POINT; + info.rbnd = rbnd; + info.delta_index = 0; + + rnd_r_search(PCB->Data->rat_tree, (rnd_box_t *) Point, NULL, rat_callback, &info, NULL); +} + +/* checks all visible lines which belong to the same group as the passed line. + * If one of the endpoints of the line is connected to an endpoint of the + * passed line, the scanned line is added to the 'rubberband' list */ +static void CheckLinePointForRubberbandConnection(rubber_ctx_t *rbnd, pcb_layer_t *Layer, pcb_line_t *Line, rnd_point_t *LinePoint, int delta_index) +{ + const rnd_layergrp_id_t group = pcb_layer_get_group_(Layer); + pcb_board_t *board = pcb_data_get_top(PCB->Data); + + if (board == NULL) + board = PCB; + + if (group >= 0) { + rnd_cardinal_t length = board->LayerGroups.grp[group].len; + rnd_cardinal_t entry; + const rnd_coord_t t = Line->Thickness / 2; + const int comb = Layer->comb & PCB_LYC_SUB; + struct rubber_info info; + + info.radius = -1; + info.box.X1 = LinePoint->X - t; + info.box.X2 = LinePoint->X + t; + info.box.Y1 = LinePoint->Y - t; + info.box.Y2 = LinePoint->Y + t; + info.line = Line; + info.rbnd = rbnd; + info.X = LinePoint->X; + info.Y = LinePoint->Y; + info.delta_index = delta_index; + + for(entry = 0; entry < length; ++entry) { + const rnd_layer_id_t layer_id = board->LayerGroups.grp[group].lid[entry]; + pcb_layer_t *layer = &PCB->Data->Layer[layer_id]; + + if (layer->meta.real.vis && ((layer->comb & PCB_LYC_SUB) == comb)) { + info.layer = layer; + rnd_r_search(layer->line_tree, &info.box, NULL, rubber_callback, &info, NULL); + } + } + } +} + +/* checks all visible arcs which belong to the same group as the passed line. + * If one of the endpoints of the arc lays * inside the passed line, + * the scanned arc is added to the 'rubberband' list */ +static void CheckLinePointForRubberbandArcConnection(rubber_ctx_t *rbnd, pcb_layer_t *Layer, pcb_line_t *Line, rnd_point_t *LinePoint, rnd_bool Exact) +{ + const rnd_layergrp_id_t group = pcb_layer_get_group_(Layer); + pcb_board_t *board = pcb_data_get_top(PCB->Data); + + if (board == NULL) + board = PCB; + + if (group >= 0) { + rnd_cardinal_t length = board->LayerGroups.grp[group].len; + rnd_cardinal_t entry; + const rnd_coord_t t = Line->Thickness / 2; + const int comb = Layer->comb & PCB_LYC_SUB; + struct rubber_info info; + + info.radius = Exact ? -1 : MAX(Line->Thickness / 2, 1); + info.box.X1 = LinePoint->X - t; + info.box.X2 = LinePoint->X + t; + info.box.Y1 = LinePoint->Y - t; + info.box.Y2 = LinePoint->Y + t; + info.line = Line; + info.rbnd = rbnd; + info.X = LinePoint->X; + info.Y = LinePoint->Y; + info.delta_index = 0; + + for(entry = 0; entry < length; ++entry) { + const rnd_layer_id_t layer_id = board->LayerGroups.grp[group].lid[entry]; + pcb_layer_t *layer = &PCB->Data->Layer[layer_id]; + + if (layer->meta.real.vis && ((layer->comb & PCB_LYC_SUB) == comb)) { + info.layer = layer; + rnd_r_search(layer->arc_tree, &info.box, NULL, rubber_callback_arc, &info, NULL); + } + } + } +} + +/* checks all visible lines which belong to the same group as the passed arc. + * If one of the endpoints of the line is on the selected arc end, + * the scanned line is added to the 'rubberband' list */ +static void CheckArcPointForRubberbandConnection(rubber_ctx_t *rbnd, pcb_layer_t *Layer, pcb_arc_t *Arc, int *end_pt, rnd_bool Exact) +{ + const rnd_layergrp_id_t group = pcb_layer_get_group_(Layer); + pcb_board_t *board = pcb_data_get_top(PCB->Data); + + if (board == NULL) + board = PCB; + + if (group >= 0) { + rnd_cardinal_t length = board->LayerGroups.grp[group].len; + rnd_cardinal_t entry; + const rnd_coord_t t = Arc->Thickness / 2; + const int comb = Layer->comb & PCB_LYC_SUB; + struct rubber_info info; + int end; /* = end_pt == pcb_arc_start_ptr ? 0 : 1; */ + + for(end = 0; end <= 1; ++end) { + rnd_coord_t ex, ey; + pcb_arc_get_end(Arc, end, &ex, &ey); + + info.radius = Exact ? -1 : MAX(Arc->Thickness / 2, 1); + info.box.X1 = ex - t; + info.box.X2 = ex + t; + info.box.Y1 = ey - t; + info.box.Y2 = ey + t; + info.line = NULL; /* used only to make sure the current object is not added - we are adding lines only and the current object is an arc */ + info.rbnd = rbnd; + info.X = ex; + info.Y = ey; + info.delta_index = end; + + for(entry = 0; entry < length; ++entry) { + const rnd_layer_id_t layer_id = board->LayerGroups.grp[group].lid[entry]; + pcb_layer_t *layer = &PCB->Data->Layer[layer_id]; + + if (layer->meta.real.vis && ((layer->comb & PCB_LYC_SUB) == comb)) { + info.layer = layer; + rnd_r_search(layer->line_tree, &info.box, NULL, rubber_callback, &info, NULL); + } + } + } + } +} + +/* checks all visible lines which belong to the same group as the passed arc. + * If one of the endpoints of the line is on either of the selected arcs ends, + * the scanned line is added to the 'rubberband' list. */ +static void CheckArcForRubberbandConnection(rubber_ctx_t *rbnd, pcb_layer_t *Layer, pcb_arc_t *Arc, rnd_bool Exact) +{ + struct rubber_info info; + int which; + rnd_coord_t t = Arc->Thickness / 2, ex, ey; + const rnd_layergrp_id_t group = pcb_layer_get_group_(Layer); + pcb_board_t *board = pcb_data_get_top(PCB->Data); + + if (board == NULL) + board = PCB; + + if (group >= 0) { + rnd_cardinal_t length = board->LayerGroups.grp[group].len; + rnd_cardinal_t entry; + const int comb = Layer->comb & PCB_LYC_SUB; + + for(which = 0; which <= 1; ++which) { + pcb_arc_get_end(Arc, which, &ex, &ey); + + /* lookup layergroup and check all visible lines in this group */ + info.radius = Exact ? -1 : MAX(Arc->Thickness / 2, 1); + info.box.X1 = ex - t; + info.box.X2 = ex + t; + info.box.Y1 = ey - t; + info.box.Y2 = ey + t; + info.line = NULL; /* used only to make sure the current object is not added - we are adding lines only and the current object is an arc */ + info.rbnd = rbnd; + info.X = ex; + info.Y = ey; + info.delta_index = which; + + for(entry = 0; entry < length; ++entry) { + const rnd_layer_id_t layer_id = board->LayerGroups.grp[group].lid[entry]; + pcb_layer_t *layer = &PCB->Data->Layer[layer_id]; + + if (layer->meta.real.vis && ((layer->comb & PCB_LYC_SUB) == comb)) { + /* check all visible lines of the group member */ + info.layer = layer; + rnd_r_search(layer->line_tree, &info.box, NULL, rubber_callback, &info, NULL); + } + } + } + } +} + +/* checks all visible lines which belong to the same group as the passed Arc. + * If either of the endpoints of the line lays anywhere inside the passed Arc, + * the scanned line is added to the 'rubberband' list */ +static void CheckEntireArcForRubberbandConnection(rubber_ctx_t *rbnd, pcb_layer_t *Layer, pcb_arc_t *Arc) +{ + pcb_board_t *board = pcb_data_get_top(PCB->Data); + rnd_layergrp_id_t group; + + if (board == NULL) + board = PCB; + + /* lookup layergroup and check all visible lines in this group */ + group = pcb_layer_get_group_(Layer); + + if (group >= 0) { + rnd_cardinal_t length = board->LayerGroups.grp[group].len; + rnd_cardinal_t entry; + const int comb = Layer->comb & PCB_LYC_SUB; + + for(entry = 0; entry < length; ++entry) { + const rnd_layer_id_t layer_id = board->LayerGroups.grp[group].lid[entry]; + pcb_layer_t *layer = &PCB->Data->Layer[layer_id]; + + if (layer->meta.real.vis && ((layer->comb & PCB_LYC_SUB) == comb)) { + rnd_coord_t thick; + + /* the following code just stupidly compares the endpoints of the lines */ + PCB_LINE_LOOP(layer); + { + pcb_rb_line_t *have_line = NULL; + rnd_bool touches1 = rnd_false; + rnd_bool touches2 = rnd_false; + int l; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, line) || rbe_subc_locked((pcb_any_obj_t *)line)) + continue; + + /* Check whether the line is already in the rubberband list. */ + for(l = 0; (l < rbnd->lines.used) && (have_line == NULL); l++) + if (rbnd->lines.array[l].Line == line) + have_line = &rbnd->lines.array[l]; + + /* Check whether any of the scanned line points touch the passed line */ + thick = (line->Thickness + 1) / 2; + touches1 = pcb_is_point_on_arc(line->Point1.X, line->Point1.Y, thick, Arc); + touches2 = pcb_is_point_on_arc(line->Point2.X, line->Point2.Y, thick, Arc); + + if (touches1) { + if (have_line) + have_line->delta_index[0] = 0; + else + have_line = pcb_rubber_band_create(rbnd, layer, line, 0, 0); + } + + if (touches2) { + if (have_line) + have_line->delta_index[1] = 0; + else + have_line = pcb_rubber_band_create(rbnd, layer, line, 1, 0); + } + } + PCB_END_LOOP; + } + } + } +} + +/* checks all visible lines which belong to the same group as the passed polygon. + * If one of the endpoints of the line lays inside the passed polygon, + * the scanned line is added to the 'rubberband' list */ +static void CheckPolygonForRubberbandConnection(rubber_ctx_t *rbnd, pcb_layer_t *Layer, pcb_poly_t *Polygon) +{ + const rnd_bool clearpoly = PCB_FLAG_TEST(PCB_FLAG_CLEARPOLY, Polygon); + rnd_layergrp_id_t group = pcb_layer_get_group_(Layer); + pcb_board_t *board = pcb_data_get_top(PCB->Data); + + if (board == NULL) + board = PCB; + + if (group >= 0) { + rnd_cardinal_t length = board->LayerGroups.grp[group].len; + rnd_cardinal_t entry; + const int comb = Layer->comb & PCB_LYC_SUB; + + for(entry = 0; entry < length; ++entry) { + const rnd_layer_id_t layer_id = board->LayerGroups.grp[group].lid[entry]; + pcb_layer_t *layer = &PCB->Data->Layer[layer_id]; + + if (layer->meta.real.vis && ((layer->comb & PCB_LYC_SUB) == comb)) { + rnd_coord_t thick; + + /* the following code just stupidly compares the endpoints + * of the lines + */ + PCB_LINE_LOOP(layer); + { + pcb_rb_line_t *have_line = NULL; + int touches1 = 0, touches2 = 0; + int l; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, line) || rbe_subc_locked((pcb_any_obj_t *)line)) + continue; + if ((pcb_layer_flags_(layer) & PCB_LYT_COPPER) && clearpoly && PCB_OBJ_HAS_CLEARANCE(line)) + continue; + + /* Check whether the line is already in the rubberband list. */ + for(l = 0; (l < rbnd->lines.used) && (have_line == NULL); l++) + if (rbnd->lines.array[l].Line == line) + have_line = &rbnd->lines.array[l]; + + /* Check whether any of the line points touch the polygon */ + thick = (line->Thickness + 1) / 2; + touches1 = (pcb_poly_is_point_in_p(line->Point1.X, line->Point1.Y, thick, Polygon)); + touches2 = (pcb_poly_is_point_in_p(line->Point2.X, line->Point2.Y, thick, Polygon)); + + if (touches1) { + if (have_line) + have_line->delta_index[0] = 0; + else + have_line = pcb_rubber_band_create(rbnd, layer, line, 0, 0); + } + + if (touches2) { + if (have_line) + have_line->delta_index[1] = 0; + else + have_line = pcb_rubber_band_create(rbnd, layer, line, 1, 0); + } + } + PCB_END_LOOP; + } + } + } +} + +/* checks all visible lines which belong to the same group as the passed Line. + * If either of the endpoints of the line lays anywhere inside the passed line, + * the scanned line is added to the 'rubberband' list */ +static void CheckLineForRubberbandConnection(rubber_ctx_t *rbnd, pcb_layer_t *Layer, pcb_line_t *Line) +{ + rnd_layergrp_id_t group = pcb_layer_get_group_(Layer); + pcb_board_t *board = pcb_data_get_top(PCB->Data); + + if (board == NULL) + board = PCB; + + if (group >= 0) { + rnd_cardinal_t length = board->LayerGroups.grp[group].len; + rnd_cardinal_t entry; + const int comb = Layer->comb & PCB_LYC_SUB; + + for(entry = 0; entry < length; ++entry) { + const rnd_layer_id_t layer_id = board->LayerGroups.grp[group].lid[entry]; + pcb_layer_t *layer = &PCB->Data->Layer[layer_id]; + + if (layer->meta.real.vis && ((layer->comb & PCB_LYC_SUB) == comb)) { + rnd_coord_t thick; + + /* the following code just stupidly compares the endpoints of the lines */ + PCB_LINE_LOOP(layer); + { + pcb_rb_line_t *have_line = NULL; + rnd_bool touches1 = rnd_false; + rnd_bool touches2 = rnd_false; + int l; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, line) || rbe_subc_locked((pcb_any_obj_t *)line)) + continue; + + /* Check whether the line is already in the rubberband list. */ + for(l = 0; (l < rbnd->lines.used) && (have_line == NULL); l++) + if (rbnd->lines.array[l].Line == line) + have_line = &rbnd->lines.array[l]; + + /* Check whether any of the scanned line points touch the passed line */ + thick = (line->Thickness + 1) / 2; + touches1 = pcb_is_point_on_line(line->Point1.X, line->Point1.Y, thick, Line); + touches2 = pcb_is_point_on_line(line->Point2.X, line->Point2.Y, thick, Line); + + if (touches1) { + if (have_line) + have_line->delta_index[0] = 0; + else + have_line = pcb_rubber_band_create(rbnd, layer, line, 0, 0); + } + + if (touches2) { + if (have_line) + have_line->delta_index[1] = 0; + else + have_line = pcb_rubber_band_create(rbnd, layer, line, 1, 0); + } + } + PCB_END_LOOP; + } + } + } +} + +/* checks all visible lines. If either of the endpoints of the line lays + * anywhere inside the passed padstack, the scanned line is added to the + * 'rubberband' list. */ +static void CheckPadStackForRubberbandConnection(rubber_ctx_t *rbnd, pcb_pstk_t *pstk) +{ + rnd_layergrp_id_t top; + rnd_layergrp_id_t bottom; + pcb_bb_type_t bb_type; + + bb_type = pcb_pstk_bbspan(PCB, pstk, &top, &bottom, NULL); + + if (bb_type != PCB_BB_INVALID) { + for(; top <= bottom; ++top) { + PCB_COPPER_GROUP_LOOP(PCB->Data, top); + { + if (layer->meta.real.vis) { + rnd_coord_t thick; + + /* the following code just stupidly compares the endpoints of the lines */ + PCB_LINE_LOOP(layer); + { + pcb_rb_line_t *have_line = NULL; + rnd_bool touches1 = rnd_false; + rnd_bool touches2 = rnd_false; + int l; + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, line) || rbe_subc_locked((pcb_any_obj_t *)line)) + continue; + + /* Check whether the line is already in the rubberband list. */ + for(l = 0; (l < rbnd->lines.used) && (have_line == NULL); l++) + if (rbnd->lines.array[l].Line == line) + have_line = &rbnd->lines.array[l]; + + /* Check whether any of the scanned line points touch the passed padstack */ + thick = (line->Thickness + 1) / 2; + touches1 = pcb_is_point_in_pstk(line->Point1.X, line->Point1.Y, thick, pstk, layer); + touches2 = pcb_is_point_in_pstk(line->Point2.X, line->Point2.Y, thick, pstk, layer); + + if (touches1) { + if (have_line) + have_line->delta_index[0] = 0; + else + have_line = pcb_rubber_band_create(rbnd, layer, line, 0, 0); + } + + if (touches2) { + if (have_line) + have_line->delta_index[1] = 0; + else + have_line = pcb_rubber_band_create(rbnd, layer, line, 1, 0); + } + } + PCB_END_LOOP; + } + } + PCB_END_LOOP; + } + } +} + +/* lookup all lines that are connected to an object and save the + * data to 'pcb_crosshair.AttachedObject.Rubberband' + * lookup is only done for visible layers */ +static void pcb_rubber_band_lookup_lines(rubber_ctx_t *rbnd, int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + + /* the function is only supported for some types + * check all visible lines; + * it is only necessary to check if one of the endpoints + * is connected + */ + switch (Type) { + case PCB_OBJ_PSTK: + CheckPadStackForRubberbandConnection(rbnd, (pcb_pstk_t *) Ptr1); + break; + + case PCB_OBJ_SUBC: + { + pcb_subc_t *subc = (pcb_subc_t *) Ptr1; + pcb_data_it_t it; + pcb_any_obj_t *p_obj; + + p_obj = pcb_data_first(&it, subc->data, PCB_OBJ_CLASS_REAL); + + while(p_obj) { + pcb_layer_t *layer = p_obj->parent.layer; + switch (p_obj->type) { + case PCB_OBJ_LINE: + if (p_obj->term) + CheckLineForRubberbandConnection(rbnd, layer, (pcb_line_t *) p_obj); + break; + case PCB_OBJ_POLY: + if (p_obj->term) + CheckPolygonForRubberbandConnection(rbnd, layer, (pcb_poly_t *) p_obj); + break; + case PCB_OBJ_ARC: /*if(p_obj->term) */ + CheckEntireArcForRubberbandConnection(rbnd, layer, (pcb_arc_t *) p_obj); + break; + case PCB_OBJ_PSTK: + CheckPadStackForRubberbandConnection(rbnd, (pcb_pstk_t *) p_obj); + break; + default: + break; + } + p_obj = pcb_data_next(&it); + } + break; + } + + case PCB_OBJ_LINE: + { + pcb_layer_t *layer = (pcb_layer_t *) Ptr1; + pcb_line_t *line = (pcb_line_t *) Ptr2; + CheckLinePointForRubberbandConnection(rbnd, layer, line, &line->Point1, 0); + CheckLinePointForRubberbandConnection(rbnd, layer, line, &line->Point2, 1); + if (conf_rbo.plugins.rubberband_orig.enable_rubberband_arcs != 0) { + CheckLinePointForRubberbandArcConnection(rbnd, layer, line, &line->Point1, rnd_true); + CheckLinePointForRubberbandArcConnection(rbnd, layer, line, &line->Point2, rnd_true); + } + break; + } + + case PCB_OBJ_LINE_POINT: + CheckLinePointForRubberbandConnection(rbnd, (pcb_layer_t *) Ptr1, (pcb_line_t *) Ptr2, (rnd_point_t *) Ptr3, 0); + if (conf_rbo.plugins.rubberband_orig.enable_rubberband_arcs != 0) + CheckLinePointForRubberbandArcConnection(rbnd, (pcb_layer_t *) Ptr1, (pcb_line_t *) Ptr2, (rnd_point_t *) Ptr3, rnd_true); + break; + + case PCB_OBJ_ARC_POINT: + CheckArcPointForRubberbandConnection(rbnd, (pcb_layer_t *) Ptr1, (pcb_arc_t *) Ptr2, (int *)Ptr3, rnd_true); + break; + + case PCB_OBJ_ARC: + CheckArcForRubberbandConnection(rbnd, (pcb_layer_t *) Ptr1, (pcb_arc_t *) Ptr2, rnd_true); + break; + + case PCB_OBJ_POLY: + CheckPolygonForRubberbandConnection(rbnd, (pcb_layer_t *) Ptr1, (pcb_poly_t *) Ptr2); + break; + } +} + +static void pcb_rubber_band_lookup_rat_lines(rubber_ctx_t *rbnd, int Type, void *Ptr1, void *Ptr2, void *Ptr3) +{ + switch (Type) { + + case PCB_OBJ_SUBC: + { + pcb_subc_t *subc = (pcb_subc_t *) Ptr1; + + PCB_PADSTACK_LOOP(subc->data); + { + CheckPadstackForRat(rbnd, padstack); + } + PCB_END_LOOP; + break; + } + + case PCB_OBJ_LINE: + { + pcb_layer_t *layer = (pcb_layer_t *) Ptr1; + pcb_line_t *line = (pcb_line_t *) Ptr2; + + CheckLinePointForRat(rbnd, layer, &line->Point1); + CheckLinePointForRat(rbnd, layer, &line->Point2); + break; + } + + case PCB_OBJ_LINE_POINT: + CheckLinePointForRat(rbnd, (pcb_layer_t *) Ptr1, (rnd_point_t *) Ptr3); + break; + + } +} + +/* adds a new line to the rubberband list of 'pcb_crosshair.AttachedObject' + if Layer == 0 it is a rat line; point_number and delta_index is 0 or 1 */ +static pcb_rb_line_t *pcb_rubber_band_create(rubber_ctx_t *rbnd, pcb_layer_t *Layer, pcb_line_t *Line, int point_number, int delta_index) +{ + pcb_rb_line_t *ptr = NULL; + int n; + + assert((point_number == 0) || (point_number == 1)); + + /* do not add any object twice; slow linear search but we expect to have only + a few objects to check. Required for two special cases: + + 1. multiple terminals on the very same coord, the same rat endpoint + found and added multiple times so the move operation is executed + on it multiple times causing the move to end up with multiplied delta. + 2. the same rat line is referenced twice: both endpoints are being moved, + e.g. when the rat is within a subc and the subc is moved. */ + for(n = 0; n < rbnd->lines.used; n++) { + if ((rbnd->lines.array[n].Line == Line) && (rbnd->lines.array[n].Layer == Layer)) { + ptr = &rbnd->lines.array[n]; + break; + } + } + + if (ptr == NULL) { + ptr = vtrbli_alloc_append(&rbnd->lines, 1); + ptr->Layer = Layer; + ptr->Line = Line; + ptr->delta_index[0] = ptr->delta_index[1] = -1; + } + + ptr->delta_index[point_number] = delta_index; + + return ptr; +} + +static pcb_rb_arc_t *pcb_rubber_band_create_arc(rubber_ctx_t *rbnd, pcb_layer_t *Layer, pcb_arc_t *Arc, int end, int delta_index) +{ + pcb_rb_arc_t *ptr = NULL; + int n; + + for(n = 0; (n < rbnd->arcs.used) && (ptr == NULL); n++) + if (rbnd->arcs.array[n].Arc == Arc) + ptr = &rbnd->arcs.array[n]; + + if (ptr == NULL) { + ptr = vtrbar_alloc_append(&rbnd->arcs, 1); + ptr->Layer = Layer; + ptr->Arc = Arc; + ptr->delta_index[0] = -1; + ptr->delta_index[1] = -1; + } + + ptr->delta_index[end] = delta_index; + + return ptr; +} + +/*** event handlers ***/ +static void rbe_reset(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + rubber_ctx_t *rbnd = user_data; + rbnd->lines.used = 0; + rbnd->arcs.used = 0; +} + +static void rbe_move(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + rubber_ctx_t *rbnd = user_data; + pcb_rb_line_t *ptr = rbnd->lines.array; + int direct = argv[1].d.i; + + if (conf_core.editor.line_refraction == 0) { + TODO("what to do in ortho mode? - disable rubber band for now"); + return; + } + + while(rbnd->lines.used) { + const int dindex1 = ptr->delta_index[0]; + const int dindex2 = ptr->delta_index[1]; + + if ((dindex1 >= 0) && (dindex2 >= 0) && !direct && (ptr->Layer != NULL)) { + /* Move both ends with route. */ + const int argi1 = (dindex1 * 2) + 2; + const int argi2 = (dindex2 * 2) + 2; + rnd_point_t point1 = ptr->Line->Point1; + rnd_point_t point2 = ptr->Line->Point2; + pcb_route_t route; + + point1.X += argv[argi1].d.i; + point1.Y += argv[argi1 + 1].d.i; + point2.X += argv[argi2].d.i; + point2.Y += argv[argi2 + 1].d.i; + + pcb_route_init(&route); + pcb_route_calculate(PCB, &route, &point1, &point2, pcb_layer_id(PCB->Data, ptr->Layer), ptr->Line->Thickness, ptr->Line->Clearance, ptr->Line->Flags, rnd_gui->shift_is_pressed(rnd_gui), rnd_gui->control_is_pressed(rnd_gui)); + pcb_route_apply_to_line(&route, ptr->Layer, ptr->Line); + pcb_route_destroy(&route); + } + else { + if (dindex1 >= 0) { + const int argi = (dindex1 * 2) + 2; + pcb_opctx_t ctx; + ctx.move.pcb = PCB; + ctx.move.dx = argv[argi].d.i; + ctx.move.dy = argv[argi + 1].d.i; + + if (direct) { + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, ptr->Layer, ptr->Line, &ptr->Line->Point1, ctx.move.dx, ctx.move.dy); + pcb_lineop_move_point(&ctx, ptr->Layer, ptr->Line, &ptr->Line->Point1); + pcb_line_mod_merge(ptr->Line, 1); + } + else + pcb_lineop_move_point_with_route(&ctx, ptr->Layer, ptr->Line, &ptr->Line->Point1); + } + + if (dindex2 >= 0) { + const int argi = (dindex2 * 2) + 2; + pcb_opctx_t ctx; + ctx.move.pcb = PCB; + ctx.move.dx = argv[argi].d.i; + ctx.move.dy = argv[argi + 1].d.i; + + if (direct) { + pcb_undo_add_obj_to_move(PCB_OBJ_LINE_POINT, ptr->Layer, ptr->Line, &ptr->Line->Point2, ctx.move.dx, ctx.move.dy); + pcb_lineop_move_point(&ctx, ptr->Layer, ptr->Line, &ptr->Line->Point2); + pcb_line_mod_merge(ptr->Line, 1); + } + else + pcb_lineop_move_point_with_route(&ctx, ptr->Layer, ptr->Line, &ptr->Line->Point2); + } + } + + rbnd->lines.used--; + ptr++; + } + + /* TODO: Move rubberband arcs. */ + if (conf_rbo.plugins.rubberband_orig.enable_rubberband_arcs != 0) { + pcb_rb_arc_t *arcptr = rbnd->arcs.array; + int i = rbnd->arcs.used; + + while(i) { + int connections = (arcptr->delta_index[0] >= 0 ? 1 : 0) | (arcptr->delta_index[1] >= 0 ? 2 : 0); + int end = 0; + + switch (connections) { + case 2: + ++end; + case 1: + { + const int argi = (arcptr->delta_index[end] * 2) + 2; + const rnd_coord_t dx = argv[argi].d.i; + const rnd_coord_t dy = argv[argi + 1].d.i; + pcb_route_t route; + pcb_route_init(&route); + calculate_route_rubber_arc_point_move(arcptr, end, dx, dy, &route); + pcb_route_apply_to_arc(&route, arcptr->Layer, arcptr->Arc); + pcb_route_destroy(&route); + } + break; + + case 3: + break; /* TODO: Both arc points are moving */ + default: + break; + } + + arcptr++; + i--; + } + } +} + +static void rbe_draw(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + rubber_ctx_t *rbnd = user_data; + pcb_rb_line_t *ptr; + rnd_cardinal_t i; + int direct = argv[1].d.i; + + if (conf_core.editor.line_refraction == 0) { + TODO("what to do in ortho mode? - disable rubber band for now"); + return; + } + + /* draw the attached rubberband lines too */ + i = rbnd->lines.used; + ptr = rbnd->lines.array; + while(i) { + + if (PCB_FLAG_TEST(PCB_FLAG_VIA, ptr->Line)) { + /* this is a rat going to a polygon. do not draw for rubberband */ ; + } + else { + rnd_coord_t x[2]; + rnd_coord_t y[2]; + int p; + + x[0] = ptr->Line->Point1.X; + y[0] = ptr->Line->Point1.Y; + x[1] = ptr->Line->Point2.X; + y[1] = ptr->Line->Point2.Y; + + for(p = 0; p < 2; ++p) { + const int dindex = ptr->delta_index[p]; + + if (dindex >= 0) { + const int argi = (dindex * 2) + 2; + x[p] += argv[argi].d.i; + y[p] += argv[argi + 1].d.i; + } + } + + if (PCB_FLAG_TEST(PCB_FLAG_RAT, ptr->Line)) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.rat); + pcb_draw_wireframe_line(pcb_crosshair.GC, x[0], y[0], x[1], y[1], ptr->Line->Thickness, 0); + } + else if (direct || (conf_core.editor.move_linepoint_uses_route == 0)) { + rnd_render->set_color(pcb_crosshair.GC, &ptr->Layer->meta.real.color); + pcb_draw_wireframe_line(pcb_crosshair.GC, x[0], y[0], x[1], y[1], ptr->Line->Thickness, 0); + /* Draw the DRC outline if it is enabled */ + if (conf_core.editor.show_drc) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + pcb_draw_wireframe_line(pcb_crosshair.GC, x[0], y[0], x[1], y[1], ptr->Line->Thickness + 2 * (conf_core.design.clearance + 1), 0); + } + } + else { + rnd_point_t point1; + rnd_point_t point2; + pcb_route_t route; + + point1.X = x[0]; + point1.Y = y[0]; + point2.X = x[1]; + point2.Y = y[1]; + + pcb_route_init(&route); + pcb_route_calculate(PCB, + &route, + ptr->delta_index[0] < 0 ? &point1 : &point2, + ptr->delta_index[0] < 0 ? &point2 : &point1, pcb_layer_id(PCB->Data, ptr->Layer), ptr->Line->Thickness, ptr->Line->Clearance, ptr->Line->Flags, rnd_gui->shift_is_pressed(rnd_gui), rnd_gui->control_is_pressed(rnd_gui)); + pcb_route_draw(&route, pcb_crosshair.GC); + if (conf_core.editor.show_drc) + pcb_route_draw_drc(&route, pcb_crosshair.GC); + pcb_route_destroy(&route); + } + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } + + ptr++; + i--; + } + + /* draw the attached rubberband arcs */ + if (conf_rbo.plugins.rubberband_orig.enable_rubberband_arcs != 0) { + pcb_rb_arc_t *arcptr = rbnd->arcs.array; + i = rbnd->arcs.used; + + while(i) { + int connections = (arcptr->delta_index[0] >= 0 ? 1 : 0) | (arcptr->delta_index[1] >= 0 ? 2 : 0); + int end = 0; + + switch (connections) { + case 2: + ++end; + case 1: + { + const int argi = (arcptr->delta_index[end] * 2) + 2; + const rnd_coord_t dx = argv[argi].d.i; + const rnd_coord_t dy = argv[argi + 1].d.i; + pcb_route_t route; + pcb_route_init(&route); + calculate_route_rubber_arc_point_move(arcptr, end, dx, dy, &route); + pcb_route_draw(&route, pcb_crosshair.GC); + pcb_route_destroy(&route); + } + break; + + case 3: + break; /* TODO: Both arc points are moving */ + default: + break; + } + + arcptr++; + i--; + } + } +} + +static void rbe_rotate90(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + rubber_ctx_t *rbnd = user_data; + pcb_rb_line_t *ptr; + rnd_coord_t cx = argv[5].d.c, cy = argv[6].d.c; + int steps = argv[7].d.i; + int *changed = argv[8].d.p; + + /* move all the rubberband lines... and reset the counter */ + ptr = rbnd->lines.array; + while(rbnd->lines.used) { + const int dindex1 = ptr->delta_index[0]; + const int dindex2 = ptr->delta_index[1]; + + *changed = 1; + + if (dindex1 >= 0) + pcb_undo_add_obj_to_rotate90(PCB_OBJ_LINE_POINT, ptr->Layer, ptr->Line, &ptr->Line->Point1, cx, cy, steps); + if (dindex2 >= 0) + pcb_undo_add_obj_to_rotate90(PCB_OBJ_LINE_POINT, ptr->Layer, ptr->Line, &ptr->Line->Point2, cx, cy, steps); + + pcb_line_invalidate_erase(ptr->Line); + if (ptr->Layer) { + pcb_poly_restore_to_poly(PCB->Data, PCB_OBJ_LINE, ptr->Layer, ptr->Line); + rnd_r_delete_entry(ptr->Layer->line_tree, (rnd_box_t *) ptr->Line); + } + else + rnd_r_delete_entry(PCB->Data->rat_tree, (rnd_box_t *) ptr->Line); + + if (dindex1 >= 0) + pcb_point_rotate90(&ptr->Line->Point1, cx, cy, steps); + + if (dindex2 >= 0) + pcb_point_rotate90(&ptr->Line->Point2, cx, cy, steps); + + pcb_line_bbox(ptr->Line); + if (ptr->Layer) { + rnd_r_insert_entry(ptr->Layer->line_tree, (rnd_box_t *) ptr->Line); + pcb_poly_clear_from_poly(PCB->Data, PCB_OBJ_LINE, ptr->Layer, ptr->Line); + pcb_line_invalidate_draw(ptr->Layer, ptr->Line); + } + else { + rnd_r_insert_entry(PCB->Data->rat_tree, (rnd_box_t *) ptr->Line); + pcb_rat_invalidate_draw((pcb_rat_t *) ptr->Line); + } + + rbnd->lines.used--; + ptr++; + } +} + +static void rbe_rotate(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ +TODO("TODO") +} + +static void rbe_lookup_lines(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + rubber_ctx_t *rbnd = user_data; + int type = argv[1].d.i; + void *ptr1 = argv[2].d.p, *ptr2 = argv[3].d.p, *ptr3 = argv[4].d.p; + + if (conf_core.editor.rubber_band_mode) + pcb_rubber_band_lookup_lines(rbnd, type, ptr1, ptr2, ptr3); +} + +static void rbe_lookup_rats(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + rubber_ctx_t *rbnd = user_data; + int type = argv[1].d.i; + void *ptr1 = argv[2].d.p, *ptr2 = argv[3].d.p, *ptr3 = argv[4].d.p; + + pcb_rubber_band_lookup_rat_lines(rbnd, type, ptr1, ptr2, ptr3); +} + +static void rbe_constrain_main_line(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + rubber_ctx_t *rbnd = user_data; + pcb_line_t *line = argv[1].d.p; + int *constrained = argv[2].d.p; + rnd_coord_t *dx1 = argv[3].d.p; /* in/out */ + rnd_coord_t *dy1 = argv[4].d.p; /* in/out */ + rnd_coord_t *dx2 = argv[5].d.p; /* out */ + rnd_coord_t *dy2 = argv[6].d.p; /* out */ + pcb_line_t *rub1, *rub2; + int rub1end, rub2end; + pcb_fline_t fmain, frub1, frub2; + + *constrained = 0; + + if (rbnd->lines.used != 2) + return; + + rub1 = rbnd->lines.array[0].Line; + rub2 = rbnd->lines.array[1].Line; + rub1end = rbnd->lines.array[0].delta_index[0] >= 0 ? 1 : 2; + rub2end = rbnd->lines.array[1].delta_index[0] >= 0 ? 1 : 2; + + /* Create float point-vector representations of the lines */ + fmain = pcb_fline_create_from_points(&line->Point1, &line->Point2); + + if (rub1end == 1) + frub1 = pcb_fline_create_from_points(&rub1->Point1, &rub1->Point2); + else + frub1 = pcb_fline_create_from_points(&rub1->Point2, &rub1->Point1); + + if (rub2end == 1) + frub2 = pcb_fline_create_from_points(&rub2->Point1, &rub2->Point2); + else + frub2 = pcb_fline_create_from_points(&rub2->Point2, &rub2->Point1); + + /* If either of the lines are parallel to the main line then the main line cannot be constrained */ + if ((fabs(pcb_fvector_dot(fmain.direction, frub1.direction)) > 0.990) || (fabs(pcb_fvector_dot(fmain.direction, frub2.direction)) > 0.990)) + return; + + *constrained = 1; + + /* If they are valid (non-null directions) we carry on */ + if (pcb_fline_is_valid(fmain) && pcb_fline_is_valid(frub1) && pcb_fline_is_valid(frub2)) { + pcb_fvector_t fmove; + + fmove.x = *dx1; + fmove.y = *dy1; + + if (!pcb_fvector_is_null(fmove)) { + pcb_fvector_t fnormal; + double rub1_move, rub2_move; + + fnormal.x = fmain.direction.y; + fnormal.y = -fmain.direction.x; + if (pcb_fvector_dot(fnormal, fmove) < 0) { + fnormal.x = -fnormal.x; + fnormal.y = -fnormal.y; + } + rub1_move = pcb_fvector_dot(fmove, fnormal) / pcb_fvector_dot(frub1.direction, fnormal); + *dx1 = rub1_move * frub1.direction.x; + *dy1 = rub1_move * frub1.direction.y; + + rub2_move = pcb_fvector_dot(fmove, fnormal) / pcb_fvector_dot(frub2.direction, fnormal); + *dx2 = rub2_move * frub2.direction.x; + *dy2 = rub2_move * frub2.direction.y; + } + } +} + +static void calculate_route_rubber_arc_point_move(pcb_rb_arc_t *arcptr, int end, rnd_coord_t dx, rnd_coord_t dy, pcb_route_t *route) +{ + /* This basic implementation simply connects the arc to the moving + point with a new route so that they remain connected. */ + + /* TODO: Add more elaberate techniques for rubberbanding with an attached arc. */ + + rnd_layer_id_t layerid = pcb_layer_id(PCB->Data, arcptr->Layer); + pcb_arc_t arc = *(arcptr->Arc); + rnd_point_t startpoint; + rnd_point_t endpoint; + rnd_point_t center; + + if (end == 1) { + arc.StartAngle += arc.Delta; + arc.Delta = -arc.Delta; + } + + pcb_arc_get_end(&arc, 0, &startpoint.X, &startpoint.Y); + pcb_route_start(PCB, route, &startpoint, layerid, arc.Thickness, arc.Clearance, arc.Flags); + + center.X = arc.X; + center.Y = arc.Y; + endpoint.X = route->end_point.X + dx; + endpoint.Y = route->end_point.Y + dy; + + pcb_route_add_arc(route, ¢er, arc.StartAngle, arc.Delta, arc.Width, layerid); + + if ((dx != 0) || (dy != 0)) + pcb_route_calculate_to(route, &endpoint, rnd_gui->shift_is_pressed(rnd_gui), rnd_gui->control_is_pressed(rnd_gui)); +} + + +static const char *rubber_cookie = "old rubberband"; + +void rb_uninit(void) +{ + rnd_event_unbind_allcookie(rubber_cookie); +} + +int pplg_check_ver_rubberband_orig(int ver_needed) +{ + return 0; +} + +void pplg_uninit_rubberband_orig(void) +{ + rnd_event_unbind_allcookie(rubber_cookie); + rnd_conf_unreg_fields("plugins/rubberband_orig/"); +} + +int pplg_init_rubberband_orig(void) +{ + void *ctx = &rubber_band_state; + RND_API_CHK_VER; + rnd_event_bind(PCB_EVENT_RUBBER_RESET, rbe_reset, ctx, rubber_cookie); + rnd_event_bind(PCB_EVENT_RUBBER_MOVE, rbe_move, ctx, rubber_cookie); + rnd_event_bind(PCB_EVENT_RUBBER_MOVE_DRAW, rbe_draw, ctx, rubber_cookie); + rnd_event_bind(PCB_EVENT_RUBBER_ROTATE90, rbe_rotate90, ctx, rubber_cookie); + rnd_event_bind(PCB_EVENT_RUBBER_ROTATE, rbe_rotate, ctx, rubber_cookie); + rnd_event_bind(PCB_EVENT_RUBBER_LOOKUP_LINES, rbe_lookup_lines, ctx, rubber_cookie); + rnd_event_bind(PCB_EVENT_RUBBER_LOOKUP_RATS, rbe_lookup_rats, ctx, rubber_cookie); + rnd_event_bind(PCB_EVENT_RUBBER_CONSTRAIN_MAIN_LINE, rbe_constrain_main_line, ctx, rubber_cookie); + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_rbo, field,isarray,type_name,cpath,cname,desc,flags); +#include "rubberband_conf_fields.h" + + return 0; +} Index: tags/2.3.0/src_plugins/rubberband_orig/rubberband.h =================================================================== --- tags/2.3.0/src_plugins/rubberband_orig/rubberband.h (nonexistent) +++ tags/2.3.0/src_plugins/rubberband_orig/rubberband.h (revision 33253) @@ -0,0 +1,38 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +/* Rubberband: when moving objects, try to keep connections to other objects - + sort of scretching nets as rubber bands */ + +#ifndef PCB_RUBBERBAND_H +#define PCB_RUBBERBAND_H + +/* temporary call until rubber band is moved out into a plugin */ +void pcb_rubberband_init(void); + +#endif Index: tags/2.3.0/src_plugins/rubberband_orig/rubberband_conf.h =================================================================== --- tags/2.3.0/src_plugins/rubberband_orig/rubberband_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/rubberband_orig/rubberband_conf.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_MINCUT_CONF_H +#define PCB_MINCUT_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN enable_rubberband_arcs; /* TODO: Enable to allow attached arcs to rubberband. */ + } rubberband_orig; + } plugins; +} conf_rubberband_orig_t; + +#endif Index: tags/2.3.0/src_plugins/rubberband_orig/rubberband_orig.pup =================================================================== --- tags/2.3.0/src_plugins/rubberband_orig/rubberband_orig.pup (nonexistent) +++ tags/2.3.0/src_plugins/rubberband_orig/rubberband_orig.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short the original rubberband +$long The original rubberband code. +$state works +$package (core) +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/script/Makefile =================================================================== --- tags/2.3.0/src_plugins/script/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/script/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_script + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/script/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/script/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/script/Plug.tmpasm (revision 33253) @@ -0,0 +1,27 @@ +put /local/pcb/mod {script} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/script/script.o + $(PLUGDIR)/script/live_script.o +@] +put /local/pcb/mod/MENUFILE {script-menu.lht} +put /local/pcb/mod/MENUVAR {script_menu} + +# Fallback scripting: if no system installed fungw is available, static link libfawk +if /local/pcb/fungw_system +then +else + append /local/pcb/mod/OBJS [@ + $(SRC_3RD_DIR)/libfungwbind/fawk/fungw_fawk.o + @] + append /local/pcb/RULES [@ + +#$(SRC_3RD_DIR)/libfungwbind/fawk/fungw_fawk.o: $(SRC_3RD_DIR)/libfungwbind/fawk/fungw_fawk.c +# $(CC) $(CFLAGS) -c $(SRC_3RD_DIR)/libfungwbind/fawk/fungw_fawk.c -o $(SRC_3RD_DIR)/libfungwbind/fawk/fungw_fawk.o +# @] +end + +switch /local/pcb/script/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/script/c_script.c =================================================================== --- tags/2.3.0/src_plugins/script/c_script.c (nonexistent) +++ tags/2.3.0/src_plugins/script/c_script.c (revision 33253) @@ -0,0 +1,110 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This module, debug, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Fungw engine for loading and runnign "scripts" written in C. The .so files + are loaded with puplug low level */ + +#include +#include +#include + +#include + +static fgw_error_t fgws_c_call_script(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + fgw_error_t rv; + fgw_func_t *fnc = argv[0].val.func; + rv = fnc->func(res, argc, argv); + fgw_argv_free(fnc->obj->parent, argc, argv); + return rv; +} + + +int fgws_c_load(fgw_obj_t *obj, const char *filename, const char *opts) +{ + pup_plugin_t *library = calloc(sizeof(pup_plugin_t), 1); + typedef int (*init_t)(fgw_obj_t *obj, const char *opts); + init_t init; + + + if (pup_load_lib(&script_pup, library, filename) != 0) { + rnd_message(RND_MSG_ERROR, "Can't dlopen() %s\n", filename); + free(library); + return -1; + } + + init = (init_t)rnd_cast_d2f(pup_dlsym(library, "pcb_rnd_init")); + if (init == NULL) { + rnd_message(RND_MSG_ERROR, "Can't find pcb_rnd_init() in %s - not a pcb-rnd c \"script\".\n", filename); + free(library); + return -1; + } + + if (init(obj, opts) != 0) { + rnd_message(RND_MSG_ERROR, "%s pcb_rnd_init() returned error\n", filename); + free(library); + return -1; + } + + library->name = rnd_strdup(filename); + obj->script_data = library; + return 0; +} + +int fgws_c_unload(fgw_obj_t *obj) +{ + pup_plugin_t *library = obj->script_data; + typedef void (*uninit_t)(fgw_obj_t *obj); + uninit_t uninit; + + uninit = (uninit_t)rnd_cast_d2f(pup_dlsym(library, "pcb_rnd_uninit")); + if (uninit != NULL) + uninit(obj); + + pup_unload_lib(library); + + free(library->name); + free(library); + + return 0; +} + +static fgw_eng_t pcb_fgw_c_eng = { + "pcb_rnd_c", + fgws_c_call_script, + NULL, + fgws_c_load, + fgws_c_unload, + NULL, NULL +}; + +static void pcb_c_script_init(void) +{ + fgw_eng_reg(&pcb_fgw_c_eng); +} Index: tags/2.3.0/src_plugins/script/live_script.c =================================================================== --- tags/2.3.0/src_plugins/script/live_script.c (nonexistent) +++ tags/2.3.0/src_plugins/script/live_script.c (revision 33253) @@ -0,0 +1,533 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "undo.h" +#include "globalconst.h" + +#include "script.h" + +#include "live_script.h" + +#include "menu_internal.c" + +static const char *lvs_cookie = "live_script"; + + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + rnd_hidlib_t *hidlib; + char *name, *longname, *fn; + char **langs; + char **lang_engines; + int wtxt, wrerun, wrun, wstop, wundo, wload, wsave, wreload, wpers, wlang; + uundo_serial_t undo_pre, undo_post; /* undo serials pre-run and post-run */ + unsigned loaded:1; +} live_script_t; + +static htsp_t pcb_live_scripts; + +static void lvs_free_langs(live_script_t *lvs) +{ + char **s; + if (lvs->langs != NULL) + for(s = lvs->langs; *s != NULL; s++) free(*s); + if (lvs->lang_engines != NULL) + for(s = lvs->lang_engines; *s != NULL; s++) free(*s); + free(lvs->langs); + free(lvs->lang_engines); +} + + +static void lvs_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + live_script_t *lvs = caller_data; + + htsp_popentry(&pcb_live_scripts, lvs->name); + + if (lvs->loaded) + pcb_script_unload(lvs->longname, NULL); + + if (rnd_gui != NULL) + RND_DAD_FREE(lvs->dlg); + lvs_free_langs(lvs); + free(lvs->name); + free(lvs->longname); + free(lvs->fn); + free(lvs); +} + +#ifdef RND_HAVE_SYS_FUNGW +static int lvs_list_langs(rnd_hidlib_t *hl, live_script_t *lvs) +{ + const char **path; + vtp0_t vl, ve; + + vtp0_init(&vl); + vtp0_init(&ve); + + for(path = pcb_script_pup_paths; *path != NULL; path++) { + char fn[RND_PATH_MAX*2], *fn_end; + int dirlen; + struct dirent *de; + DIR *d = rnd_opendir(hl, *path); + + if (d == NULL) + continue; + + dirlen = strlen(*path); + memcpy(fn, *path, dirlen); + fn_end = fn + dirlen; + *fn_end = RND_DIR_SEPARATOR_C; + fn_end++; + + while((de = rnd_readdir(d)) != NULL) { + FILE *f; + int el, len = strlen(de->d_name); + char *s1, *s2, *eng, *s, *end, line[1024]; + + if (len < 5) + continue; + end = de->d_name + len -4; + if ((strcmp(end, ".pup") != 0) || (strncmp(de->d_name, "fungw_", 6) != 0)) + continue; + + strcpy(fn_end, de->d_name); + + f = rnd_fopen(hl, fn, "r"); + if (f == NULL) + continue; + while((s = fgets(line, sizeof(line), f)) != NULL) { + while(isspace(*s)) s++; + if (strncmp(s, "$desc", 5) != 0) + continue; + s += 5; + if (((s1 = strstr(s, "binding")) == NULL) || ((s2 = strstr(s, "engine")) == NULL)) + continue; + if (s1 < s2) *s1 = '\0'; + else *s2 = '\0'; + eng = rnd_strdup(de->d_name + 6); /* remove the fungw_ prefix, the low level script runner will insert it */ + el = strlen(eng); + eng[el-4] = '\0'; + vtp0_append(&ve, eng); + vtp0_append(&vl, rnd_strdup(s)); + } + fclose(f); + } + rnd_closedir(d); + } + lvs->langs = (char **)vl.array; + lvs->lang_engines = (char **)ve.array; + return vl.used; +} +#else +static int lvs_list_langs(rnd_hidlib_t *hl, live_script_t *lvs) +{ + vtp0_t vl, ve; + + vtp0_init(&vl); + vtp0_init(&ve); + + vtp0_append(&vl, rnd_strdup("fawk")); vtp0_append(&ve, rnd_strdup("fawk")); + vtp0_append(&vl, rnd_strdup("fbas")); vtp0_append(&ve, rnd_strdup("fbas")); + vtp0_append(&vl, rnd_strdup("fpas")); vtp0_append(&ve, rnd_strdup("fpas")); + + lvs->langs = (char **)vl.array; + lvs->lang_engines = (char **)ve.array; + return vl.used; +} + +#endif + +static void lvs_button_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn) +{ + live_script_t *lvs = caller_data; + const char *arg; + int w = attr_btn - lvs->dlg; + + + if (w == lvs->wrerun) arg = "rerun"; + else if (w == lvs->wrun) arg = "run"; + else if (w == lvs->wstop) arg = "stop"; + else if (w == lvs->wundo) arg = "undo"; + else if (w == lvs->wload) arg = "load"; + else if (w == lvs->wsave) arg = "save"; + else if (w == lvs->wreload) arg = "reload-rerun"; + else { + rnd_message(RND_MSG_ERROR, "lvs_button_cb(): internal error: unhandled switch case\n"); + return; + } + + rnd_actionva(lvs->hidlib, "livescript", arg, lvs->name, NULL); +} + +static live_script_t *pcb_dlg_live_script(rnd_hidlib_t *hidlib, const char *name) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + char *title; + live_script_t *lvs = calloc(sizeof(live_script_t), 1); + + if (lvs_list_langs(NULL, lvs) < 1) { + lvs_free_langs(lvs); + free(lvs); + rnd_message(RND_MSG_ERROR, "live_script: no scripting language engines found\nPlease compile and install fungw from source, then\nreconfigure and recompile pcb-rnd.\n"); + return NULL; + } + + lvs->hidlib = hidlib; + lvs->name = rnd_strdup(name); + lvs->longname = rnd_concat("_live_script_", name, NULL); + RND_DAD_BEGIN_VBOX(lvs->dlg); + RND_DAD_COMPFLAG(lvs->dlg, RND_HATF_EXPFILL); + RND_DAD_TEXT(lvs->dlg, lvs); + RND_DAD_COMPFLAG(lvs->dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + lvs->wtxt = RND_DAD_CURRENT(lvs->dlg); + + RND_DAD_BEGIN_HBOX(lvs->dlg); + RND_DAD_BUTTON(lvs->dlg, "re-run"); + lvs->wrerun = RND_DAD_CURRENT(lvs->dlg); + RND_DAD_CHANGE_CB(lvs->dlg, lvs_button_cb); + RND_DAD_HELP(lvs->dlg, "Stop the script if it is running\nundo the changes the script performed if no\nuser modification happened since\nrun the script again"); + RND_DAD_BUTTON(lvs->dlg, "run"); + lvs->wrun = RND_DAD_CURRENT(lvs->dlg); + RND_DAD_CHANGE_CB(lvs->dlg, lvs_button_cb); + RND_DAD_HELP(lvs->dlg, "Run the script:\nonce and unload, if not persistent\nor keep it running in persistent mode"); + RND_DAD_BUTTON(lvs->dlg, "stop"); + lvs->wstop = RND_DAD_CURRENT(lvs->dlg); + RND_DAD_CHANGE_CB(lvs->dlg, lvs_button_cb); + RND_DAD_HELP(lvs->dlg, "Halt and unload the script\nand unregister any action, menu, etc. it registered"); + RND_DAD_BUTTON(lvs->dlg, "undo"); + lvs->wundo = RND_DAD_CURRENT(lvs->dlg); + RND_DAD_CHANGE_CB(lvs->dlg, lvs_button_cb); + RND_DAD_HELP(lvs->dlg, "undo the changes the script performed if no\nuser modification happened since"); + RND_DAD_BUTTON(lvs->dlg, "save"); + lvs->wsave = RND_DAD_CURRENT(lvs->dlg); + RND_DAD_CHANGE_CB(lvs->dlg, lvs_button_cb); + RND_DAD_HELP(lvs->dlg, "Save script source to a file"); + RND_DAD_BUTTON(lvs->dlg, "load"); + lvs->wload = RND_DAD_CURRENT(lvs->dlg); + RND_DAD_CHANGE_CB(lvs->dlg, lvs_button_cb); + RND_DAD_HELP(lvs->dlg, "Load script source from a file"); + RND_DAD_BUTTON(lvs->dlg, "reload&rerun"); + lvs->wreload = RND_DAD_CURRENT(lvs->dlg); + RND_DAD_CHANGE_CB(lvs->dlg, lvs_button_cb); + RND_DAD_HELP(lvs->dlg, "Reload script source and rerun\n(Ideal with external editor)"); + RND_DAD_END(lvs->dlg); + RND_DAD_BEGIN_HBOX(lvs->dlg); + RND_DAD_BOOL(lvs->dlg); + lvs->wpers = RND_DAD_CURRENT(lvs->dlg); + RND_DAD_LABEL(lvs->dlg, "persistent"); + RND_DAD_HELP(lvs->dlg, "Persistent mode: keep the script loaded and running\n(useful if the script registers actions)\nNon-persistent mode: run once then unload."); + RND_DAD_ENUM(lvs->dlg, (const char **)lvs->langs); + lvs->wlang = RND_DAD_CURRENT(lvs->dlg); + RND_DAD_BEGIN_HBOX(lvs->dlg); + RND_DAD_COMPFLAG(lvs->dlg, RND_HATF_EXPFILL); + RND_DAD_END(lvs->dlg); + RND_DAD_BUTTON_CLOSES(lvs->dlg, clbtn); + RND_DAD_END(lvs->dlg); + RND_DAD_END(lvs->dlg); + RND_DAD_DEFSIZE(lvs->dlg, 300, 500); + + title = rnd_concat("Live Scripting: ", name, NULL); + RND_DAD_NEW("live_script", lvs->dlg, title, lvs, rnd_false, lvs_close_cb); + free(title); + rnd_gui->attr_dlg_widget_state(lvs->dlg_hid_ctx, lvs->wstop, 0); + return lvs; +} + +static int live_stop(live_script_t *lvs) +{ + if (lvs->loaded) { + pcb_script_unload(lvs->longname, NULL); + lvs->loaded = 0; + } + + rnd_gui->attr_dlg_widget_state(lvs->dlg_hid_ctx, lvs->wrun, 1); + rnd_gui->attr_dlg_widget_state(lvs->dlg_hid_ctx, lvs->wstop, 0); + return 0; +} + +static int live_run(rnd_hidlib_t *hl, live_script_t *lvs) +{ + rnd_hid_attribute_t *atxt = &lvs->dlg[lvs->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + FILE *f; + char *src, *fn, *lang; + int res = 0; + long numu; + + fn = rnd_tempfile_name_new("live_script"); + f = rnd_fopen(hl, fn, "w"); + if (f == NULL) { + rnd_tempfile_unlink(fn); + rnd_message(RND_MSG_ERROR, "live_script: can't open temp file for write\n"); + return -1; + } + + src = txt->hid_get_text(atxt, lvs->dlg_hid_ctx); + fputs(src, f); + free(src); + fclose(f); + + lang = lvs->lang_engines[lvs->dlg[lvs->wlang].val.lng]; + + live_stop(lvs); + + lvs->undo_pre = pcb_undo_serial(); + numu = pcb_num_undo(); + + if (pcb_script_load(lvs->longname, fn, lang) != 0) { + rnd_message(RND_MSG_ERROR, "live_script: can't load/parse the script\n"); + res = -1; + } + lvs->loaded = 1; + rnd_gui->attr_dlg_widget_state(lvs->dlg_hid_ctx, lvs->wrun, 0); + rnd_gui->attr_dlg_widget_state(lvs->dlg_hid_ctx, lvs->wstop, 1); + + if (!lvs->dlg[lvs->wpers].val.lng) + live_stop(lvs); + + if ((pcb_num_undo() != numu) && (lvs->undo_pre == pcb_undo_serial())) + pcb_undo_inc_serial(); + lvs->undo_post = pcb_undo_serial(); + + rnd_gui->invalidate_all(rnd_gui); /* if the script drew anything, get it displayed */ + + rnd_tempfile_unlink(fn); + return res; +} + +static const char *live_default_ext(live_script_t *lvs) +{ + TODO("get this info from fungw for the selected language"); + return NULL; +} + +static int live_undo(live_script_t *lvs) +{ + if (lvs->undo_pre == lvs->undo_post) + return 0; /* the script did nothing */ + if (lvs->undo_post < pcb_undo_serial()) { + rnd_message(RND_MSG_WARNING, "Can not undo live script modifications:\nthere was user edit after script executaion.\n"); + return 1; + } + pcb_undo_above(lvs->undo_pre); + rnd_gui->invalidate_all(rnd_gui); + return 0; +} + + +static int live_load(rnd_hidlib_t *hl, live_script_t *lvs, const char *fn) +{ + rnd_hid_attribute_t *atxt = &lvs->dlg[lvs->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + FILE *f; + gds_t tmp; + + if (fn == NULL) { + const char *default_ext = live_default_ext(lvs); + fn = rnd_gui->fileselect(rnd_gui, + "Load live script", "Load the a live script from file", + lvs->fn, default_ext, rnd_hid_fsd_filter_any, "live_script", RND_HID_FSD_READ, NULL); + if (fn == NULL) + return 0; + lvs->fn = rnd_strdup(fn); + } + + f = rnd_fopen(hl, fn, "r"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "live_script: failed to open '%s' for read\n", fn); + return -1; + } + + gds_init(&tmp); + + while(!feof(f)) { + int len, ou = tmp.used; + gds_alloc_append(&tmp, 1024); + len = fread(tmp.array+ou, 1, 1024, f); + if (len > 0) { + tmp.used = ou+len; + tmp.array[tmp.used] = '\0'; + } + } + + txt->hid_set_text(atxt, lvs->dlg_hid_ctx, RND_HID_TEXT_REPLACE, tmp.array); + + gds_uninit(&tmp); + fclose(f); + return 0; +} + +static int live_save(rnd_hidlib_t *hl, live_script_t *lvs, const char *fn) +{ + rnd_hid_attribute_t *atxt = &lvs->dlg[lvs->wtxt]; + rnd_hid_text_t *txt = atxt->wdata; + FILE *f; + char *src; + int res = 0; + + if (fn == NULL) { + const char *default_ext = live_default_ext(lvs); + + if (lvs->fn == NULL) + lvs->fn = rnd_concat(lvs->name, ".", default_ext, NULL); + + fn = rnd_gui->fileselect(rnd_gui, + "Save live script", "Save the source of a live script", + lvs->fn, default_ext, rnd_hid_fsd_filter_any, "live_script", 0, NULL); + if (fn == NULL) + return 0; + } + + f = rnd_fopen(hl, fn, "w"); + if (f == NULL) { + rnd_message(RND_MSG_ERROR, "live_script: failed to open '%s' for write\n", fn); + return -1; + } + + src = txt->hid_get_text(atxt, lvs->dlg_hid_ctx); + if (fwrite(src, strlen(src), 1, f) != 1) { + rnd_message(RND_MSG_ERROR, "live_script: failed to write script source to '%s'\n", fn); + res = -1; + } + free(src); + + fclose(f); + return res; +} + + +const char pcb_acts_LiveScript[] = + "LiveScript([new], [name])\n" + "LiveScript(load|save, name, [filame])\n" + "LiveScript(run|stop|rerun|undo, name)\n"; +const char pcb_acth_LiveScript[] = "Manage a live script"; +/* DOC: livescript.html */ +fgw_error_t pcb_act_LiveScript(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + live_script_t *lvs; + const char *cmd = "new", *name = NULL, *arg = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LiveScript, cmd = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, LiveScript, name = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, LiveScript, arg = argv[3].val.str); + + if (rnd_strcasecmp(cmd, "new") == 0) { + if (name == NULL) name = "default"; + lvs = htsp_get(&pcb_live_scripts, name); + if (lvs != NULL) { + rnd_message(RND_MSG_ERROR, "live script '%s' is already open\n", name); + RND_ACT_IRES(1); + return 0; + } + lvs = pcb_dlg_live_script(RND_ACT_HIDLIB, name); + if (lvs != NULL) { + htsp_set(&pcb_live_scripts, lvs->name, lvs); + RND_ACT_IRES(0); + } + else + RND_ACT_IRES(1); + return 0; + } + + if (name == NULL) { + rnd_message(RND_MSG_ERROR, "script name (second argument) required\n"); + RND_ACT_IRES(1); + return 0; + } + + lvs = htsp_get(&pcb_live_scripts, name); + if (lvs == NULL) { + rnd_message(RND_MSG_ERROR, "script '%s' does not exist\n", name); + RND_ACT_IRES(1); + return 0; + } + + RND_ACT_IRES(0); + if (rnd_strcasecmp(cmd, "load") == 0) { + RND_ACT_IRES(live_load(NULL, lvs, arg)); + } + else if (rnd_strcasecmp(cmd, "save") == 0) { + RND_ACT_IRES(live_save(NULL, lvs, arg)); + } + else if (rnd_strcasecmp(cmd, "undo") == 0) { + RND_ACT_IRES(live_undo(lvs)); + } + else if (rnd_strcasecmp(cmd, "run") == 0) { + live_run(NULL, lvs); + } + else if (rnd_strcasecmp(cmd, "stop") == 0) { + live_stop(lvs); + } + else if (rnd_strcasecmp(cmd, "rerun") == 0) { + live_stop(lvs); + live_undo(lvs); + live_run(NULL, lvs); + } + if (rnd_strcasecmp(cmd, "reload-rerun") == 0) { + RND_ACT_IRES(live_load(NULL, lvs, lvs->fn)); + live_stop(lvs); + live_undo(lvs); + live_run(NULL, lvs); + } + + return 0; +} + +void pcb_live_script_init(void) +{ + htsp_init(&pcb_live_scripts, strhash, strkeyeq); + rnd_hid_menu_load(rnd_gui, NULL, lvs_cookie, 110, NULL, 0, script_menu, "plugin: live scripting"); +} + +void pcb_live_script_uninit(void) +{ + htsp_entry_t *e; + for(e = htsp_first(&pcb_live_scripts); e != NULL; e = htsp_next(&pcb_live_scripts, e)) { + live_script_t *lvs = e->value; + lvs_close_cb(lvs, RND_HID_ATTR_EV_CODECLOSE); + } + htsp_uninit(&pcb_live_scripts); + rnd_event_unbind_allcookie(lvs_cookie); + rnd_hid_menu_unload(rnd_gui, lvs_cookie); +} + Index: tags/2.3.0/src_plugins/script/live_script.h =================================================================== --- tags/2.3.0/src_plugins/script/live_script.h (nonexistent) +++ tags/2.3.0/src_plugins/script/live_script.h (revision 33253) @@ -0,0 +1,6 @@ +extern const char pcb_acts_LiveScript[]; +extern const char pcb_acth_LiveScript[]; +fgw_error_t pcb_act_LiveScript(fgw_arg_t *res, int argc, fgw_arg_t *argv); + +void pcb_live_script_init(void); +void pcb_live_script_uninit(void); Index: tags/2.3.0/src_plugins/script/perma.c =================================================================== --- tags/2.3.0/src_plugins/script/perma.c (nonexistent) +++ tags/2.3.0/src_plugins/script/perma.c (revision 33253) @@ -0,0 +1,140 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * This module, debug, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +#include +#include + +static const char *guess_lang(const char *ext); + +static int perma_load(const char *dir, const char *id, const char *path_in, const char *lang) +{ + char spath[RND_PATH_MAX]; + const char *path; + + if (!rnd_is_path_abs(path_in)) { + path = spath; + rnd_snprintf(spath, sizeof(spath), "%s%c%s", dir, RND_DIR_SEPARATOR_C, path_in); + } + else + path = path_in; + + return pcb_script_load(id, path, lang); +} + +static void perma_script_load_conf(const char *dir) +{ + char path[RND_PATH_MAX], *errmsg; + lht_doc_t *doc; + lht_node_t *n, *npath, *nlang; + FILE *f; + long succ = 0; + + rnd_snprintf(path, sizeof(path), "%s%c%s", dir, RND_DIR_SEPARATOR_C, "scripts.lht"); + f = rnd_fopen(NULL, path, "r"); + if (f == NULL) + return; /* non-existing or unreadable file is no error */ + doc = lht_dom_load_stream(f, path, &errmsg); + fclose(f); + + if (doc == NULL) { + rnd_message(RND_MSG_ERROR, "Failed to parse script config '%s':\n'%s'\n", path, errmsg); + goto end; + } + + n = doc->root; + if ((n->type != LHT_LIST) || (strcmp(n->name, "pcb-rnd-perma-script-v1") != 0)) { + rnd_message(RND_MSG_ERROR, "Failed to load script config '%s':\nroot node is not li:pcb-rnd-perma-script-v1\n", path); + goto end; + } + + for(n = n->data.list.first; n != NULL; n = n->next) { + const char *id = n->name, *path_in, *lang = NULL; + if (n->type != LHT_HASH) { + rnd_message(RND_MSG_ERROR, "ignoring non-hash child '%s' in '%s'\n", n->name, path); + continue; + } + + npath = lht_dom_hash_get(n, "path"); + if ((npath == NULL) || (npath->type != LHT_TEXT)) { + rnd_message(RND_MSG_ERROR, "ignoring '%s' in '%s': no path\n", n->name, path); + continue; + } + path_in = npath->data.text.value; + + nlang = lht_dom_hash_get(n, "lang"); + if (nlang != NULL) { + if (npath->type != LHT_TEXT) { + rnd_message(RND_MSG_ERROR, "ignoring '%s' in '%s': invalid lang node type\n", n->name, path); + continue; + } + lang = nlang->data.text.value; + } + else { /* guess from path */ + const char *tmp = strrchr(path_in, '.'); + if (tmp == NULL) { + rnd_message(RND_MSG_ERROR, "ignoring '%s' in '%s': no lang specified and file name is not suitable for guessing\n", n->name, path); + continue; + } + lang = guess_lang(tmp+1); + } + + if (perma_load(dir, id, path_in, lang) == 0) + succ++; + else + rnd_message(RND_MSG_ERROR, "failed to load script '%s' in '%s'\n", n->name, path); + } + + rnd_message(RND_MSG_INFO, "Loaded %ld scripts from '%s'\n", succ, path); + + end:; + lht_dom_uninit(doc); +} + +static void perma_script_init(void) +{ + static int inited = 0; + + if (inited) return; + + perma_script_load_conf(rnd_conf_userdir_path); + perma_script_load_conf(rnd_conf_sysdir_path); + + inited = 1; +} + +static void script_mainloop_perma_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (rnd_hid_in_main_loop) + perma_script_init(); +} + Index: tags/2.3.0/src_plugins/script/script-menu.lht =================================================================== --- tags/2.3.0/src_plugins/script/script-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/script/script-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@scripts { + li:submenu { + ha:Open live script dialog... = { action = LiveScript(new) } + } + } + } +} Index: tags/2.3.0/src_plugins/script/script.c =================================================================== --- tags/2.3.0/src_plugins/script/script.c (nonexistent) +++ tags/2.3.0/src_plugins/script/script.c (revision 33253) @@ -0,0 +1,469 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This module, debug, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "globalconst.h" + +#include "script.h" + +#ifndef RND_HAVE_SYS_FUNGW +int pplg_init_fungw_fawk(void); +int pplg_uninit_fungw_fawk(void); +#endif + +typedef struct { + char *id, *fn, *lang; + pup_plugin_t *pup; + fgw_obj_t *obj; +} script_t; + +static htsp_t scripts; /* ID->script_t */ + +static pup_context_t script_pup; + +#include "c_script.c" +#include +#include + +/* dir name under dotdir for saving script persistency data */ +#define SCRIPT_PERS "script_pers" + +/* allow only 1 megabyte of script persistency to be loaded */ +#define PERS_MAX_SIZE 1024*1024 + +const char *pcb_script_pup_paths[] = { + "/usr/local/lib/puplug", + "/usr/lib/puplug", + NULL +}; + +static int script_save_preunload(script_t *s, const char *data) +{ + FILE *f; + gds_t fn; + + gds_init(&fn); + gds_append_str(&fn, rnd_conf.rc.path.home); + gds_append(&fn, RND_DIR_SEPARATOR_C); + gds_append_str(&fn, DOT_PCB_RND); + rnd_mkdir(NULL, fn.array, 0755); + + gds_append(&fn, RND_DIR_SEPARATOR_C); + gds_append_str(&fn, SCRIPT_PERS); + rnd_mkdir(NULL, fn.array, 0750); + + gds_append(&fn, RND_DIR_SEPARATOR_C); + gds_append_str(&fn, s->obj->name); + + f = rnd_fopen(NULL, fn.array, "w"); + if (f != NULL) { + gds_uninit(&fn); + fputs(data, f); + fclose(f); + return 0; + } + + gds_uninit(&fn); + return -1; +} + +/* auto-unregister from any central infra the script may have regitered in using + the standard script cookie */ +static void script_unreg(const char *cookie) +{ + rnd_hid_menu_unload(rnd_gui, cookie); +} + +/* unload a script, free all memory and remove it from all lists/hashes. + If preunload is not NULL, it's the unload reason the script's own + preunload() function is called and its return is saved. */ +static void script_free(script_t *s, const char *preunload, const char *cookie) +{ + if ((preunload != NULL) && (s->obj != NULL)) { + fgw_func_t *f; + fgw_arg_t res, argv[2]; + + f = fgw_func_lookup(s->obj, "preunload"); + if (f != NULL) { + argv[0].type = FGW_FUNC; + argv[0].val.argv0.func = f; + argv[0].val.argv0.user_call_ctx = NULL; + argv[1].type = FGW_STR; + argv[1].val.cstr = preunload; + res.type = FGW_INVALID; + if (f->func(&res, 2, argv) == 0) { + if ((fgw_arg_conv(&rnd_fgw, &res, FGW_STR) == 0) && (res.val.str != NULL) && (*res.val.str != '\0')) + script_save_preunload(s, res.val.str); + } + fgw_arg_free(&rnd_fgw, &res); + } + } + + if (cookie != NULL) + script_unreg(cookie); + + if (s->obj != NULL) + fgw_obj_unreg(&rnd_fgw, s->obj); +#ifdef RND_HAVE_SYS_FUNGW + if (s->pup != NULL) + pup_unload(&script_pup, s->pup, NULL); +#endif + free(s->id); + free(s->fn); + free(s); +} + +static void script_unload_entry(htsp_entry_t *e, const char *preunload, const char *cookie) +{ + script_t *s = (script_t *)e->value; + script_free(s, preunload, cookie); + e->key = NULL; + htsp_delentry(&scripts, e); +} + +static const char *script_persistency_id = NULL; +static int script_persistency(fgw_arg_t *res, const char *cmd) +{ + char *fn; + + if (script_persistency_id == NULL) { + rnd_message(RND_MSG_ERROR, "ScriptPersistency may be called only from the init part of a script\n"); + goto err; + } + + fn = rnd_concat(rnd_conf.rc.path.home, RND_DIR_SEPARATOR_S, DOT_PCB_RND, RND_DIR_SEPARATOR_S, SCRIPT_PERS, RND_DIR_SEPARATOR_S, script_persistency_id, NULL); + + if (strcmp(cmd, "remove") == 0) { + RND_ACT_IRES(rnd_remove(NULL, fn)); + goto succ; + } + + if (strcmp(cmd, "read") == 0) { + FILE *f; + long fsize = rnd_file_size(NULL, fn); + char *data; + + if ((fsize < 0) || (fsize > PERS_MAX_SIZE)) + goto err; + + data = malloc(fsize+1); + if (data == NULL) + goto err; + + f = rnd_fopen(NULL, fn, "r"); + if (f == NULL) { + free(data); + goto err; + } + + if (fread(data, 1, fsize, f) != fsize) { + free(data); + fclose(f); + goto err; + } + + fclose(f); + data[fsize] = '\0'; + res->type = FGW_STR | FGW_DYN; + res->val.str = data; + goto succ; + } + + rnd_message(RND_MSG_ERROR, "Unknown command for ScriptPersistency\n"); + + err:; + RND_ACT_IRES(-1); + return 0; + + succ: + free(fn); + return 0; /* assume IRES is set already */ +} + +static char *script_gen_cookie(const char *force_id) +{ + if (force_id == NULL) { + if (script_persistency_id == NULL) { + rnd_message(RND_MSG_ERROR, "ScriptCookie called from outside of script init, can not generate the cookie\n"); + return NULL; + } + force_id = script_persistency_id; + } + return rnd_concat("script::fungw::", force_id, NULL); +} + +int pcb_script_unload(const char *id, const char *preunload) +{ + char *cookie; + htsp_entry_t *e = htsp_getentry(&scripts, id); + if (e == NULL) + return -1; + + cookie = script_gen_cookie(id); + script_unload_entry(e, preunload, cookie); + free(cookie); + return 0; +} + +static char *script_fn(const char *fn) +{ + if (*fn != '~') + return rnd_strdup(fn); + return rnd_strdup_printf("%s%c%s", rnd_conf.rc.path.home, RND_DIR_SEPARATOR_C, fn+1); +} + +int pcb_script_load(const char *id, const char *fn, const char *lang) +{ + pup_plugin_t *pup; + script_t *s; + const char *old_id; + + if (htsp_has(&scripts, id)) { + rnd_message(RND_MSG_ERROR, "Can not load script %s from file %s: ID already in use\n", id, fn); + return -1; + } + + if (lang == NULL) { +TODO(": guess") + rnd_message(RND_MSG_ERROR, "Can not load script %s from file %s: failed to guess language from file name\n", id, fn); + return -1; + } + + if (strcmp(lang, "c") != 0) { +#ifdef RND_HAVE_SYS_FUNGW + const char *engname = lang; + char name[RND_PATH_MAX]; + int st; + + TODO("move this to fungw"); + if (strcmp(engname, "fbas") == 0) engname = "fawk"; + else if (strcmp(engname, "fpas") == 0) engname = "fawk"; + + rnd_snprintf(name, sizeof(name), "fungw_%s", engname); + + old_id = script_persistency_id; + script_persistency_id = id; + pup = pup_load(&script_pup, pcb_script_pup_paths, name, 0, &st); + script_persistency_id = old_id; + if (pup == NULL) { + rnd_message(RND_MSG_ERROR, "Can not load script engine %s for language %s\n", name, lang); + return -1; + } +#endif + } + else { + lang = "pcb_rnd_c"; + pup = NULL; + } + + s = calloc(1, sizeof(script_t)); + s->pup = pup; + s->id = rnd_strdup(id); + s->fn = script_fn(fn); + s->lang = rnd_strdup(lang); + + old_id = script_persistency_id; + script_persistency_id = id; + s->obj = fgw_obj_new(&rnd_fgw, s->id, s->lang, s->fn, NULL); + script_persistency_id = old_id; + + if (s->obj == NULL) { + script_free(s, NULL, NULL); + rnd_message(RND_MSG_ERROR, "Failed to parse/execute %s script from file %s\n", id, fn); + return -1; + } + + htsp_set(&scripts, s->id, s); + return 0; +} + +static int script_reload(const char *id) +{ + int ret; + char *fn, *lang, *cookie; + script_t *s; + htsp_entry_t *e = htsp_getentry(&scripts, id); + + if (e == NULL) + return -1; + + s = e->value; + fn = rnd_strdup(s->fn); + lang = rnd_strdup(s->lang); + + cookie = script_gen_cookie(id); + script_unload_entry(e, "reload", cookie); + free(cookie); + + ret = pcb_script_load(id, fn, lang); + free(fn); + free(lang); + return ret; +} + +void script_list(const char *pat) +{ + htsp_entry_t *e; + re_se_t *r = NULL; + + if ((pat != NULL) && (*pat != '\0')) + r = re_se_comp(pat); + + for(e = htsp_first(&scripts); e; e = htsp_next(&scripts, e)) { + script_t *s = (script_t *)e->value; + if ((r == NULL) || (re_se_exec(r, s->id)) || (re_se_exec(r, s->fn)) || (re_se_exec(r, s->lang))) + rnd_message(RND_MSG_INFO, "id=%s fn=%s lang=%s\n", s->id, s->fn, s->lang); + } + + if (r != NULL) + re_se_free(r); +} + +static void oneliner_boilerplate(FILE *f, const char *lang, int pre) +{ + if (strcmp(lang, "mawk") == 0) { + if (pre) + fputs("BEGIN {\n", f); + else + fputs("}\n", f); + } + else if (strcmp(lang, "fawk") == 0) { + if (pre) + fputs("function main(ARGS) {\n", f); + else + fputs("}\n", f); + } + else if (strcmp(lang, "fpas") == 0) { + if (pre) + fputs("function main(ARGS);\nbegin\n", f); + else + fputs("end;\n", f); + } + else if (strcmp(lang, "fbas") == 0) { + if (!pre) + fputs("\n", f); + } +} + +int script_oneliner(const char *lang, const char *src) +{ + FILE *f; + char *fn; + int res = 0; + + fn = rnd_tempfile_name_new("oneliner"); + f = rnd_fopen(NULL, fn, "w"); + if (f == NULL) { + rnd_tempfile_unlink(fn); + rnd_message(RND_MSG_ERROR, "script oneliner: can't open temp file for write\n"); + return -1; + } + oneliner_boilerplate(f, lang, 1); + fputs(src, f); + fputs("\n", f); + oneliner_boilerplate(f, lang, 0); + fclose(f); + + if (pcb_script_load("__oneliner", fn, lang) != 0) { + rnd_message(RND_MSG_ERROR, "script oneliner: can't load/parse the script\n"); + res = -1; + } + pcb_script_unload("__oneliner", NULL); + + rnd_tempfile_unlink(fn); + return res; +} + +#include "timer.c" +#include "perma.c" +#include "script_act.c" + +char *script_cookie = "script plugin"; + +int pplg_check_ver_script(int ver_needed) { return 0; } + +void pplg_uninit_script(void) +{ + htsp_entry_t *e; + + pcb_live_script_uninit(); + rnd_remove_actions_by_cookie(script_cookie); + for(e = htsp_first(&scripts); e; e = htsp_next(&scripts, e)) { + script_t *script = e->value; + char *cookie = script_gen_cookie(script->id); + script_unload_entry(e, "unload", cookie); + free(cookie); + } + + htsp_uninit(&scripts); + pup_uninit(&script_pup); + +#ifndef RND_HAVE_SYS_FUNGW + pplg_uninit_fungw_fawk(); +#endif + + rnd_event_unbind_allcookie(script_cookie); +} + +int pplg_init_script(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(script_action_list, script_cookie); + +#ifndef RND_HAVE_SYS_FUNGW + pplg_init_fungw_fawk(); +#endif + + pcb_c_script_init(); + htsp_init(&scripts, strhash, strkeyeq); + pup_init(&script_pup); + pcb_live_script_init(); + if (rnd_hid_in_main_loop) + perma_script_init(); + else + rnd_event_bind(RND_EVENT_MAINLOOP_CHANGE, script_mainloop_perma_ev, NULL, script_cookie); + rnd_event_bind(RND_EVENT_GUI_INIT, script_timer_gui_init_ev, NULL, script_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/script/script.h =================================================================== --- tags/2.3.0/src_plugins/script/script.h (nonexistent) +++ tags/2.3.0/src_plugins/script/script.h (revision 33253) @@ -0,0 +1,3 @@ +extern const char *pcb_script_pup_paths[]; +extern int pcb_script_load(const char *id, const char *fn, const char *lang); +extern int pcb_script_unload(const char *id, const char *preunload); Index: tags/2.3.0/src_plugins/script/script.pup =================================================================== --- tags/2.3.0/src_plugins/script/script.pup (nonexistent) +++ tags/2.3.0/src_plugins/script/script.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short fungw turing complete scripting +$long Load and execute scripts written in any language supported by fungw +$package (core) +$state works +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/script/script_act.c =================================================================== --- tags/2.3.0/src_plugins/script/script_act.c (nonexistent) +++ tags/2.3.0/src_plugins/script/script_act.c (revision 33253) @@ -0,0 +1,546 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018,2019 Tibor 'Igor2' Palinkas + * + * This module, debug, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include +#include +#include +#include "live_script.h" + + +TODO("This should be in fungw") +static const char *guess_lang(const char *ext) +{ + const char **s, *tr[] = { + "awk", "mawk", + "bas", "fbas", + "pas", "fpas", +#ifdef RND_HAVE_SYS_FUNGW + "ruby", "mruby", + "py", "python", + "js", "duktape", + "javascript", "duktape", + "stt", "estutter", +#endif + NULL, NULL + }; + + /* translate short name to long name */ + for(s = tr; *s != NULL; s += 2) { + if (strcmp(*s, ext) == 0) { + s++; + return *s; + } + } + return ext; +} + +/*** dialog box ***/ +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int active; /* already open - allow only one instance */ + + int wslist; /* list of scripts */ + int walist; /* list of actions */ +} script_dlg_t; + +script_dlg_t script_dlg; + +static void script_dlg_s2d_act(script_dlg_t *ctx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[2]; + htsp_entry_t *e; + script_t *sc; + + attr = &ctx->dlg[ctx->walist]; + tree = attr->wdata; + + /* remove existing items */ + for(r = gdl_first(&tree->rows); r != NULL; r = gdl_first(&tree->rows)) + rnd_dad_tree_remove(attr, r); + + r = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wslist]); + if (r == NULL) + return; + + sc = htsp_get(&scripts, r->cell[0]); + if (sc == NULL) + return; + + /* add all actions */ + cell[1] = NULL; + for(e = htsp_first(&sc->obj->func_tbl); e; e = htsp_next(&sc->obj->func_tbl, e)) { + cell[0] = rnd_strdup(e->key); + rnd_dad_tree_append(attr, NULL, cell); + } +} + + +static void script_dlg_s2d(script_dlg_t *ctx) +{ + rnd_hid_attribute_t *attr; + rnd_hid_tree_t *tree; + rnd_hid_row_t *r; + char *cell[4], *cursor_path = NULL; + htsp_entry_t *e; + + attr = &ctx->dlg[ctx->wslist]; + tree = attr->wdata; + + /* remember cursor */ + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + + /* remove existing items */ + for(r = gdl_first(&tree->rows); r != NULL; r = gdl_first(&tree->rows)) + rnd_dad_tree_remove(attr, r); + + /* add all items */ + cell[3] = NULL; + for(e = htsp_first(&scripts); e; e = htsp_next(&scripts, e)) { + script_t *s = (script_t *)e->value; + cell[0] = rnd_strdup(s->id); + cell[1] = rnd_strdup(s->lang); + cell[2] = rnd_strdup(s->fn); + rnd_dad_tree_append(attr, NULL, cell); + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wslist, &hv); + free(cursor_path); + } + script_dlg_s2d_act(ctx); +} + +void script_dlg_update(void) +{ + if (script_dlg.active) + script_dlg_s2d(&script_dlg); +} + +static void script_dlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + script_dlg_t *ctx = caller_data; + RND_DAD_FREE(ctx->dlg); + memset(ctx, 0, sizeof(script_dlg_t)); /* reset all states to the initial - includes ctx->active = 0; */ +} + +static void btn_unload_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + script_dlg_t *ctx = caller_data; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wslist]); + if (row == NULL) + return; + + pcb_script_unload(row->cell[0], "unload"); + script_dlg_s2d(ctx); +} + +static void btn_reload_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + script_dlg_t *ctx = caller_data; + rnd_hid_row_t *row = rnd_dad_tree_get_selected(&ctx->dlg[ctx->wslist]); + if (row == NULL) + return; + + script_reload(row->cell[0]); + script_dlg_s2d(ctx); +} + +static void slist_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + script_dlg_s2d_act((script_dlg_t *)caller_data); +} + +static void btn_load_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + script_dlg_t *ctx = caller_data; + int failed; + char *tmp, *fn = rnd_gui->fileselect(rnd_gui, "script to load", "Select a script file to load", NULL, NULL, NULL, "script", RND_HID_FSD_READ, NULL); + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", -1}, {"ok", 0}, {NULL, 0}}; + typedef struct { + RND_DAD_DECL_NOINIT(dlg) + int wid, wlang; + } idlang_t; + idlang_t idlang; + + if (fn == NULL) + return; + + memset(&idlang, 0, sizeof(idlang)); + RND_DAD_BEGIN_VBOX(idlang.dlg); + RND_DAD_BEGIN_HBOX(idlang.dlg); + RND_DAD_LABEL(idlang.dlg, "ID:"); + RND_DAD_STRING(idlang.dlg); + idlang.wid = RND_DAD_CURRENT(idlang.dlg); + tmp = strrchr(fn, RND_DIR_SEPARATOR_C); + if (tmp != NULL) { + tmp++; + idlang.dlg[idlang.wid].val.str = tmp = rnd_strdup(tmp); + tmp = strchr(tmp, '.'); + if (tmp != NULL) + *tmp = '\0'; + } + RND_DAD_END(idlang.dlg); + RND_DAD_BEGIN_HBOX(idlang.dlg); + RND_DAD_LABEL(idlang.dlg, "language:"); + RND_DAD_STRING(idlang.dlg); + idlang.wlang = RND_DAD_CURRENT(idlang.dlg); + tmp = strrchr(fn, '.'); + if (tmp != NULL) + idlang.dlg[idlang.wlang].val.str = rnd_strdup(guess_lang(tmp+1)); + RND_DAD_END(idlang.dlg); + RND_DAD_BUTTON_CLOSES(idlang.dlg, clbtn); + RND_DAD_END(idlang.dlg); + + + RND_DAD_AUTORUN("script_load", idlang.dlg, "load script", NULL, failed); + + if ((!failed) && (pcb_script_load(idlang.dlg[idlang.wid].val.str, fn, idlang.dlg[idlang.wlang].val.str) == 0)) + script_dlg_s2d(ctx); + + RND_DAD_FREE(idlang.dlg); +} + +static void script_dlg_open(void) +{ + static const char *hdr[] = {"ID", "language", "file", NULL}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + if (script_dlg.active) + return; /* do not open another */ + + RND_DAD_BEGIN_VBOX(script_dlg.dlg); + RND_DAD_COMPFLAG(script_dlg.dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_HPANE(script_dlg.dlg); + RND_DAD_COMPFLAG(script_dlg.dlg, RND_HATF_EXPFILL); + /* left side */ + RND_DAD_BEGIN_VBOX(script_dlg.dlg); + RND_DAD_COMPFLAG(script_dlg.dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(script_dlg.dlg, 3, 0, hdr); + RND_DAD_COMPFLAG(script_dlg.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + script_dlg.wslist = RND_DAD_CURRENT(script_dlg.dlg); + RND_DAD_CHANGE_CB(script_dlg.dlg, slist_cb); + RND_DAD_BEGIN_HBOX(script_dlg.dlg); + RND_DAD_BUTTON(script_dlg.dlg, "Unload"); + RND_DAD_HELP(script_dlg.dlg, "Unload the currently selected script"); + RND_DAD_CHANGE_CB(script_dlg.dlg, btn_unload_cb); + RND_DAD_BUTTON(script_dlg.dlg, "Reload"); + RND_DAD_HELP(script_dlg.dlg, "Reload the currently selected script\n(useful if the script has changed)"); + RND_DAD_CHANGE_CB(script_dlg.dlg, btn_reload_cb); + RND_DAD_BUTTON(script_dlg.dlg, "Load..."); + RND_DAD_HELP(script_dlg.dlg, "Load a new script from disk"); + RND_DAD_CHANGE_CB(script_dlg.dlg, btn_load_cb); + RND_DAD_END(script_dlg.dlg); + RND_DAD_END(script_dlg.dlg); + + /* right side */ + RND_DAD_BEGIN_VBOX(script_dlg.dlg); + RND_DAD_COMPFLAG(script_dlg.dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(script_dlg.dlg, "Actions:"); + RND_DAD_TREE(script_dlg.dlg, 1, 0, NULL); + RND_DAD_COMPFLAG(script_dlg.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL); + script_dlg.walist = RND_DAD_CURRENT(script_dlg.dlg); + RND_DAD_END(script_dlg.dlg); + RND_DAD_END(script_dlg.dlg); + RND_DAD_BUTTON_CLOSES(script_dlg.dlg, clbtn); + RND_DAD_END(script_dlg.dlg); + + /* set up the context */ + script_dlg.active = 1; + + RND_DAD_NEW("scripts", script_dlg.dlg, "pcb-rnd Scripts", &script_dlg, rnd_false, script_dlg_close_cb); + script_dlg_s2d(&script_dlg); +} + +/*** actions ***/ + +static int script_id_invalid(const char *id) +{ + for(; *id != '\0'; id++) + if (!isalnum(*id) && (*id != '_')) + return 1; + return 0; +} + +#define ID_VALIDATE(id, act) \ +do { \ + if (script_id_invalid(id)) { \ + rnd_message(RND_MSG_ERROR, #act ": Invalid script ID '%s' (must contain only alphanumeric characters and underscores)\n", id); \ + return FGW_ERR_ARG_CONV; \ + } \ +} while(0) + +static const char pcb_acth_LoadScript[] = "Load a fungw script"; +static const char pcb_acts_LoadScript[] = "LoadScript(id, filename, [language])"; +/* DOC: loadscript.html */ +static fgw_error_t pcb_act_LoadScript(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *id, *fn, *lang = NULL; + RND_ACT_CONVARG(1, FGW_STR, LoadScript, id = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, LoadScript, fn = argv[2].val.str); + RND_ACT_MAY_CONVARG(3, FGW_STR, LoadScript, lang = argv[3].val.str); + + ID_VALIDATE(id, LoadScript); + + RND_ACT_IRES(pcb_script_load(id, fn, lang)); + script_dlg_update(); + return 0; +} + +static const char pcb_acth_UnloadScript[] = "Unload a fungw script"; +static const char pcb_acts_UnloadScript[] = "UnloadScript(id)"; +/* DOC: unloadscript.html */ +static fgw_error_t pcb_act_UnloadScript(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *id = NULL; + RND_ACT_CONVARG(1, FGW_STR, UnloadScript, id = argv[1].val.str); + + ID_VALIDATE(id, UnloadScript); + + RND_ACT_IRES(pcb_script_unload(id, "unload")); + return 0; +} + +static const char pcb_acth_ReloadScript[] = "Reload a fungw script"; +static const char pcb_acts_ReloadScript[] = "ReloadScript(id)"; +/* DOC: reloadscript.html */ +static fgw_error_t pcb_act_ReloadScript(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *id = NULL; + RND_ACT_CONVARG(1, FGW_STR, UnloadScript, id = argv[1].val.str); + + ID_VALIDATE(id, ReloadScript); + + RND_ACT_IRES(script_reload(id)); + script_dlg_update(); + return 0; +} + +static const char pcb_acth_ScriptPersistency[] = "Read or remove script persistency data savd on preunload"; +static const char pcb_acts_ScriptPersistency[] = "ScriptPersistency(read|remove)"; +/* DOC: scriptpersistency.html */ +static fgw_error_t pcb_act_ScriptPersistency(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *cmd = NULL; + RND_ACT_CONVARG(1, FGW_STR, ScriptPersistency, cmd = argv[1].val.str); + return script_persistency(res, cmd); +} + +static const char pcb_acth_ListScripts[] = "List fungw scripts, optionally filtered wiht regex pat."; +static const char pcb_acts_ListScripts[] = "ListScripts([pat])"; +/* DOC: listscripts.html */ +static fgw_error_t pcb_act_ListScripts(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *pat = NULL; + RND_ACT_MAY_CONVARG(1, FGW_STR, ListScripts, pat = argv[1].val.str); + + script_list(pat); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acth_BrowseScripts[] = "Present a dialog box for browsing scripts"; +static const char pcb_acts_BrowseScripts[] = "BrowseScripts()"; +static fgw_error_t pcb_act_BrowseScripts(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + script_dlg_open(); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acth_ScriptCookie[] = "Return a cookie specific to the current script instance during script initialization"; +static const char pcb_acts_ScriptCookie[] = "ScriptCookie()"; +/* DOC: scriptcookie.html */ +static fgw_error_t pcb_act_ScriptCookie(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + res->type = FGW_STR | FGW_DYN; + res->val.str = script_gen_cookie(NULL); + if (res->val.str == NULL) + return -1; + return 0; +} + +static const char pcb_acth_Oneliner[] = "Execute a script one-liner using a specific language"; +static const char pcb_acts_Oneliner[] = "Oneliner(lang, script)"; +/* DOC: onliner.html */ +static fgw_error_t pcb_act_Oneliner(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *first = NULL, *lang = argv[0].val.func->name, *scr = NULL; + + if (strcmp(lang, "oneliner") == 0) { + /* call to oneliner(lang, script) */ + RND_ACT_CONVARG(1, FGW_STR, Oneliner, lang = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_STR, Oneliner, scr = argv[2].val.str); + } + else if (strcmp(lang, "/exit") == 0) { + RND_ACT_IRES(rnd_cli_leave()); + return 0; + } + else { + /* call to lang(script) */ + RND_ACT_MAY_CONVARG(1, FGW_STR, Oneliner, scr = argv[1].val.str); + } + + RND_ACT_MAY_CONVARG(1, FGW_STR, Oneliner, first = argv[1].val.str); + if (first != NULL) { + if (*first == '/') { + if (rnd_strcasecmp(scr, "/exit") == 0) { + RND_ACT_IRES(rnd_cli_leave()); + return 0; + } + RND_ACT_IRES(-1); /* ignore /click, /tab and others for now */ + return 0; + } + } + + lang = guess_lang(lang); + + if (scr == NULL) { + RND_ACT_IRES(rnd_cli_enter(lang, lang)); + return 0; + } + + if (rnd_strcasecmp(scr, "/exit") == 0) { + RND_ACT_IRES(rnd_cli_leave()); + return 0; + } + + RND_ACT_IRES(script_oneliner(lang, scr)); + return 0; +} + +static const char pcb_acth_ActionString[] = "Execute a pcb-rnd action parsing a string; syntac: \"action(arg,arg,arg)\""; +static const char pcb_acts_ActionString[] = "ActionString(action)"; +static fgw_error_t pcb_act_ActionString(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *act; + RND_ACT_CONVARG(1, FGW_STR, ActionString, act = argv[1].val.str); + return rnd_parse_command_res(RND_ACT_HIDLIB, res, act, 1); +} + + +static const char pcb_acth_pcb_math1[] = "Single-argument math functions"; +static const char pcb_acts_pcb_math1[] = "pcb_MATHFUNC(val)"; +static fgw_error_t pcb_act_pcb_math1(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *actname = argv[0].val.func->name; + double a; + + RND_ACT_CONVARG(1, FGW_DOUBLE, pcb_math1, a = argv[1].val.nat_double); + res->type = FGW_DOUBLE; + switch(actname[4]) { + case 'a': + switch(actname[5]) { + case 's': res->val.nat_double = asin(a); return 0; + case 'c': res->val.nat_double = acos(a); return 0; + case 't': res->val.nat_double = atan(a); return 0; + } + break; + case 's': + switch(actname[5]) { + case 'i': res->val.nat_double = sin(a); return 0; + case 'q': res->val.nat_double = sqrt(a); return 0; + } + break; + case 'c': res->val.nat_double = cos(a); return 0; + case 't': res->val.nat_double = tan(a); return 0; + } + return FGW_ERR_ARG_CONV; +} + +static const char pcb_acth_pcb_math2[] = "Two-argument math functions"; +static const char pcb_acts_pcb_math2[] = "pcb_MATHFUNC(a,b)"; +static fgw_error_t pcb_act_pcb_math2(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *actname = argv[0].val.func->name; + double a, b; + + RND_ACT_CONVARG(1, FGW_DOUBLE, pcb_math2, a = argv[1].val.nat_double); + RND_ACT_CONVARG(2, FGW_DOUBLE, pcb_math2, b = argv[2].val.nat_double); + res->type = FGW_DOUBLE; + switch(actname[4]) { + case 'a': res->val.nat_double = atan2(a, b); return 0; + } + return FGW_ERR_ARG_CONV; +} + + +static rnd_action_t script_action_list[] = { + {"LoadScript", pcb_act_LoadScript, pcb_acth_LoadScript, pcb_acts_LoadScript}, + {"UnloadScript", pcb_act_UnloadScript, pcb_acth_UnloadScript, pcb_acts_UnloadScript}, + {"ReloadScript", pcb_act_ReloadScript, pcb_acth_ReloadScript, pcb_acts_ReloadScript}, + {"ScriptPersistency", pcb_act_ScriptPersistency, pcb_acth_ScriptPersistency, pcb_acts_ScriptPersistency}, + {"ListScripts", pcb_act_ListScripts, pcb_acth_ListScripts, pcb_acts_ListScripts}, + {"BrowseScripts", pcb_act_BrowseScripts, pcb_acth_BrowseScripts, pcb_acts_BrowseScripts}, + {"AddTimer", pcb_act_AddTimer, pcb_acth_AddTimer, pcb_acts_AddTimer}, + {"ScriptCookie", pcb_act_ScriptCookie, pcb_acth_ScriptCookie, pcb_acts_ScriptCookie}, + {"LiveScript", pcb_act_LiveScript, pcb_acth_LiveScript, pcb_acts_LiveScript}, + + /* script shorthands */ + {"fawk", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"fpas", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"pas", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"fbas", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"bas", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, +#ifdef RND_HAVE_SYS_FUNGW + {"awk", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"mawk", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"lua", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"tcl", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"javascript", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"js", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"stt", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"estutter", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"perl", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"ruby", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"mruby", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"py", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"python", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, +#endif + {"Oneliner", pcb_act_Oneliner, pcb_acth_Oneliner, pcb_acts_Oneliner}, + {"ActionString", pcb_act_ActionString, pcb_acth_ActionString, pcb_acts_ActionString}, + + /* math */ + {"pcb_sin", pcb_act_pcb_math1, NULL, NULL}, + {"pcb_cos", pcb_act_pcb_math1, NULL, NULL}, + {"pcb_asin", pcb_act_pcb_math1, NULL, NULL}, + {"pcb_acos", pcb_act_pcb_math1, NULL, NULL}, + {"pcb_atan", pcb_act_pcb_math1, NULL, NULL}, + {"pcb_tan", pcb_act_pcb_math1, NULL, NULL}, + {"pcb_sqrt", pcb_act_pcb_math1, NULL, NULL}, + + {"pcb_atan2", pcb_act_pcb_math2, NULL, NULL} +}; Index: tags/2.3.0/src_plugins/script/timer.c =================================================================== --- tags/2.3.0/src_plugins/script/timer.c (nonexistent) +++ tags/2.3.0/src_plugins/script/timer.c (revision 33253) @@ -0,0 +1,163 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 Tibor 'Igor2' Palinkas + * + * This module, debug, was written and is Copyright (C) 2016 by Tibor Palinkas + * this module is also subject to the GNU GPL as described below + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include + +typedef struct { + double next, period; + long count; + char *user_data; + char aname[1]; +} script_timer_t; + +vtp0_t timers; +int timer_running = 0, want_timer = 0; + +static void start_timer(void); +static void timer_cb(rnd_hidval_t hv) +{ + long n, len; + double now; + + len = vtp0_len(&timers); + if (len == 0) { + timer_running = 0; + return; /* don't even restart the timer if we are not waiting for anything */ + } + + now = rnd_dtime(); + + /* we could do something clever here, e.g. sort timers by ->next but + in reality there will be so few timers at any given time that it's + probably not worth the effort */ + for(n = len-1; n >= 0; n--) { + script_timer_t *t = timers.array[n]; + fgw_func_t *f; + fgw_arg_t res, argv[4]; + + if (t->next <= now) { + t->next += t->period; + + f = fgw_func_lookup(&rnd_fgw, t->aname); + if (f == NULL) + goto remove; + argv[0].type = FGW_FUNC; + argv[0].val.argv0.func = f; + argv[0].val.argv0.user_call_ctx = NULL; + argv[1].type = FGW_DOUBLE; + argv[1].val.nat_double = now; + argv[2].type = FGW_LONG; + argv[2].val.nat_long = t->count; + if (t->user_data != NULL) { + argv[3].type = FGW_STR; + argv[3].val.str = t->user_data; + } + else { + argv[3].type = FGW_STR; + argv[3].val.str = ""; + } + + res.type = FGW_INVALID; + if (rnd_actionv_(f, &res, 4, argv) != 0) + goto remove; + fgw_arg_conv(&rnd_fgw, &res, FGW_INT); + if ((res.type != FGW_INT) || (res.val.nat_int != 0)) /* action requested timer removal */ + goto remove; + + if (t->count > 0) { + t->count--; + if (t->count == 0) { + remove:; + vtp0_remove(&timers, n, 1); + free(t->user_data); + free(t); + } + } + } + } + + start_timer(); +} + +static void start_timer(void) +{ + static rnd_hidval_t hv; + if (!rnd_gui->gui) { + want_timer = 1; + return; + } + timer_running = 1; + rnd_gui->add_timer(rnd_gui, timer_cb, 100, hv); +} + +static void script_timer_gui_init_ev(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (want_timer && !timer_running) /* script created a timer before gui init */ + start_timer(); +} + +static const char pcb_acth_AddTimer[] = "Add a new timer"; +static const char pcb_acts_AddTimer[] = "AddTimer(action, period, [repeat], [userdata])"; +/* DOC: addtimer.html */ +static fgw_error_t pcb_act_AddTimer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *act, *user_data = NULL; + double period; + int count = 1, len; + char fn[RND_ACTION_NAME_MAX]; + script_timer_t *t; + + RND_ACT_CONVARG(1, FGW_STR, AddTimer, act = argv[1].val.str); + RND_ACT_CONVARG(2, FGW_DOUBLE, AddTimer, period = argv[2].val.nat_double); + RND_ACT_MAY_CONVARG(3, FGW_INT, AddTimer, count = argv[3].val.nat_int); + RND_ACT_MAY_CONVARG(4, FGW_STR, AddTimer, user_data = argv[4].val.str); + + rnd_aname(fn, act); + len = strlen(fn); + t = malloc(sizeof(script_timer_t) + len); + t->next = rnd_dtime() + period; + t->period = period; + t->count = count; + strcpy(t->aname, fn); + if (user_data != NULL) + t->user_data = rnd_strdup(user_data); + else + t->user_data = NULL; + + vtp0_append(&timers, t); + + if (!timer_running) + start_timer(); + + RND_ACT_IRES(0); + return 0; +} + Index: tags/2.3.0/src_plugins/serpentine/Makefile =================================================================== --- tags/2.3.0/src_plugins/serpentine/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/serpentine/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_serpentine + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/serpentine/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/serpentine/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/serpentine/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {serpentine} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/serpentine/serpentine.o +@] +put /local/pcb/mod/CONF {$(PLUGDIR)/serpentine/serpentine_conf.h} + +switch /local/pcb/serpentine/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/serpentine/serpentine.c =================================================================== --- tags/2.3.0/src_plugins/serpentine/serpentine.c (nonexistent) +++ tags/2.3.0/src_plugins/serpentine/serpentine.c (revision 33253) @@ -0,0 +1,466 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 Adrian Purser + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "conf_core.h" + +#include + +#include "crosshair.h" +#include "board.h" +#include "data.h" +#include "data_it.h" +#include +#include "search.h" +#include +#include +#include "flag_str.h" +#include "undo.h" +#include "find.h" +#include "draw.h" +#include "draw_wireframe.h" +#include +#include +#include +#include "serpentine_conf.h" +#include "layer.h" +#include "route.h" + +typedef struct { + rnd_point_t start; + rnd_point_t end; + double amplitude; + double minimum_amplitude; + double nx,ny; /* Normal of host line */ + double lx,ly; /* Vector along the line */ + rnd_coord_t length; /* Length of serpentine section */ + rnd_coord_t section_length; /* Length of the line section that hosts the serpentine */ + rnd_coord_t total_length; /* Total length of the line including the serpentine */ +} serpentine_info_t; + +conf_serpentine_t conf_serpentine; +static const char *serpentine_cookie = "serpentine plugin"; + +static double +point_on_line( rnd_coord_t X, rnd_coord_t Y, + rnd_coord_t X1, rnd_coord_t Y1, + rnd_coord_t X2, rnd_coord_t Y2, + rnd_coord_t * OutX, + rnd_coord_t * OutY ) +{ + const double abx = (double)X2 - (double)X1; + const double aby = (double)Y2 - (double)Y1; + const double apx = (double)X - (double)X1; + const double apy = (double)Y - (double)Y1; + const double ab2 = (abx*abx) + (aby*aby); + const double apab = (apx * abx) + (apy * aby); + const double t = apab / ab2; + + if(OutX != NULL) *OutX = X1 + (rnd_coord_t)(abx * t); + if(OutY != NULL) *OutY = Y1 + (rnd_coord_t)(aby * t); + + return t; +} + +static void +draw_serpentine_ui(serpentine_info_t * p_info) +{ + const double amplitude = (p_info->amplitude < p_info->minimum_amplitude ? p_info->minimum_amplitude : p_info->amplitude); + const rnd_coord_t nx = (rnd_coord_t)(p_info->nx * p_info->amplitude); + const rnd_coord_t ny = (rnd_coord_t)(p_info->ny * p_info->amplitude); + const rnd_coord_t x1 = p_info->start.X + nx; + const rnd_coord_t y1 = p_info->start.Y + ny; + const rnd_coord_t x2 = p_info->end.X + nx; + const rnd_coord_t y2 = p_info->end.Y + ny; + + rnd_render->set_color(pcb_crosshair.GC, "#808080" /*conf_core.appearance.color.attached*/ ); + rnd_render->draw_line(pcb_crosshair.GC, p_info->start.X, p_info->start.Y, p_info->end.X, p_info->end.Y ); + rnd_render->draw_line(pcb_crosshair.GC, p_info->start.X, p_info->start.Y, x1, y1 ); + rnd_render->draw_line(pcb_crosshair.GC, p_info->end.X, p_info->end.Y, x2, y2 ); + rnd_render->draw_line(pcb_crosshair.GC, x1, y1, x2, y2 ); +} + +int +serpentine_calculate_route( pcb_route_t * route, + const pcb_line_t * line, + const rnd_point_t * point1, + const rnd_point_t * point2, + const rnd_coord_t pitch, + serpentine_info_t * p_info ) +{ + rnd_coord_t sx,sy,ex,ey; + double angle_n,angle_l; + rnd_coord_t amplitude = 0; + const double radius = pitch/2; + const double min_amplitude = (2.0*radius); + int count = 0; + double sind,cosd,sinn,cosn; + + rnd_point_t start,end; + + /* Project the start and end points onto the line */ + double t0 = point_on_line(point1->X,point1->Y,line->Point1.X,line->Point1.Y,line->Point2.X,line->Point2.Y,&sx,&sy); + double t1 = point_on_line(point2->X,point2->Y,line->Point1.X,line->Point1.Y,line->Point2.X,line->Point2.Y,&ex,&ey); + double nx = point2->X - ex; + double ny = point2->Y - ey; + double lx = ex-sx; + double ly = ey-sy; + double ld,lnx,lny; + double nd,nnx,nny; + double side; + + /* If the start or end point is outside of the line then abort the route creation */ + if( (t0 == t1) || (t0 < 0.0) || (t0 > 1.0) || (t1 < 0.0) || (t1 > 1.0) ) + return -1; + + ld = sqrt(lx*lx + ly*ly); + lnx = lx/ld; + lny = ly/ld; + nd = sqrt(nx*nx + ny*ny); + count = ld/(pitch*2); + + nnx = (double)nx/nd; + nny = (double)ny/nd; + + /* If the end point is closest to the start of the line then swap the start + * and end points so that we are always going in the correct direction + */ + if(t1 < t0) { + rnd_coord_t t; + ex = sx; + ey = sy; + sx += count * pitch * 2 * lnx; + sy += count * pitch * 2 * lny; + lnx = -lnx; + lny = -lny; + } + + side = 0 - ((lnx * nny) - (lny * nnx)); + start.X = sx; + start.Y = sy; + end.X = ex; + end.Y = ey; + + angle_n = (0.0-(atan2(ny, nx) / RND_M180)); + angle_l = (0.0-(atan2(ly, lx) / RND_M180)); + + /* Calculate Amplitude */ + amplitude = nd; + if(amplitude < min_amplitude) + amplitude = 0.0; + + /* Create the route */ + if(count > 0) { + int i; + const double lpx = pitch * lnx; /* Pitch Vector X */ + const double lpy = pitch * lny; /* Pitch Vector Y */ + double nax = 0.0; + double nay = 0.0; + double last_amplitude = 0.0; + rnd_point_t startpos; + rnd_point_t endpos; + + route->start_point = route->end_point = line->Point1; + route->thickness = line->Thickness; + route->clearance = line->Clearance; + route->start_layer = route->end_layer = pcb_layer_id(PCB->Data,line->parent.layer); + route->PCB = PCB; + route->flags = line->Flags; + + for(i=0;iThickness/2) ? 0.0 : amplitude - (line->Thickness/2)); + const rnd_coord_t of = (pitch * 2 * i)+pitch; + const rnd_coord_t px = start.X + (lnx * of); + const rnd_coord_t py = start.Y + (lny * of); + + /* TODO: Enforce DRC */ + + nax = (amp - (radius * 2.0)) * nnx; /* Line Segment Vector X */ + nay = (amp - (radius * 2.0)) * nny; /* Line Segment Vector Y */ + + if(last_amplitude == 0.0) { + if(amp == 0.0) + continue; + + startpos.X = route->end_point.X; + startpos.Y = route->end_point.Y; + endpos.X = start.X + (lpx * 2.0 * (double)i); + endpos.Y = start.Y + (lpy * 2.0 * (double)i); + pcb_route_add_line(route,&startpos,&endpos,route->start_layer); + + startpos.X = (px-lpx) + (nnx * radius); + startpos.Y = (py-lpy) + (nny * radius); + pcb_route_add_arc(route,&startpos,angle_n,90*side,radius,route->start_layer); + } + else { + startpos.X = route->end_point.X; + startpos.Y = route->end_point.Y; + endpos.X = startpos.X - nax; + endpos.Y = startpos.Y - nay; + pcb_route_add_line(route,&startpos,&endpos,route->start_layer); + + startpos.X = (px-lpx) + (nnx * radius); + startpos.Y = (py-lpy) + (nny * radius); + + if(amp == 0.0) { + pcb_route_add_arc(route,&startpos,angle_n - (90.0 * side),90.0*side,radius,route->start_layer); + last_amplitude = amp; + continue; + } + else + pcb_route_add_arc(route,&startpos,angle_n - (90.0 * side),180.0*side,radius,route->start_layer); + } + + startpos.X = route->end_point.X; + startpos.Y = route->end_point.Y; + endpos.X = startpos.X + nax; + endpos.Y = startpos.Y + nay; + pcb_route_add_line(route,&startpos,&endpos,route->start_layer); + + startpos.X = px + (nnx * (amp-radius)); + startpos.Y = py + (nny * (amp-radius)); + pcb_route_add_arc(route,&startpos,angle_n + (side*270),(-180)*side,radius,route->start_layer); + + last_amplitude = amp; + } + + if(last_amplitude > 0.0) { + const rnd_coord_t of = (pitch * 2 * count)+pitch; + const rnd_coord_t px = start.X + (lnx * of); + const rnd_coord_t py = start.Y + (lny * of); + startpos.X = route->end_point.X; + startpos.Y = route->end_point.Y; + endpos.X = startpos.X - nax; + endpos.Y = startpos.Y - nay; + pcb_route_add_line(route,&startpos,&endpos,route->start_layer); + startpos.X = (px-lpx) + (nnx * radius); + startpos.Y = (py-lpy) + (nny * radius); + pcb_route_add_arc(route,&startpos,angle_n - (90.0 * side),90.0*side,radius,route->start_layer); + } + + /* Add a line from the end of the serpentine to the end of the original line. */ + pcb_route_add_line(route,&route->end_point,&line->Point2,route->start_layer); + } + + if(p_info != NULL) { + p_info->start.X = sx; + p_info->start.Y = sy; + p_info->end.X = ex; + p_info->end.Y = ey; + p_info->amplitude = amplitude; + p_info->minimum_amplitude = min_amplitude; + p_info->nx = nnx; + p_info->ny = nny; + p_info->lx = lx; + p_info->ly = ly; + } + + return 0; +} + +/*** Serpentine Tool ***/ + +static void tool_serpentine_init(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +static void tool_serpentine_uninit(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + pcb_crosshair_attached_clean(&PCB->hidlib); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +static void tool_serpentine_notify_mode(rnd_hidlib_t *hl) +{ + int type; + pcb_any_obj_t *term_obj; + + switch (pcb_crosshair.AttachedObject.State) { + case PCB_CH_STATE_FIRST: + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = pcb_search_screen(hl->tool_x, hl->tool_y, PCB_OBJ_LINE, + &pcb_crosshair.AttachedObject.Ptr1, &pcb_crosshair.AttachedObject.Ptr2, &pcb_crosshair.AttachedObject.Ptr3); + /* TODO: check if an object is on the current layer */ + if (pcb_crosshair.AttachedObject.Type == PCB_OBJ_LINE) { + pcb_line_t * p_line = (pcb_line_t *)pcb_crosshair.AttachedObject.Ptr2; + + double t = point_on_line( hl->tool_x,hl->tool_y, + p_line->Point1.X,p_line->Point1.Y, + p_line->Point2.X,p_line->Point2.Y, + &pcb_crosshair.AttachedObject.X, + &pcb_crosshair.AttachedObject.Y ); + + if((t >= 0.0) && (t <= 1.0)) + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_SECOND; + } + else + rnd_message(RND_MSG_WARNING, "Serpentines can be only drawn onto a line\n"); + break; + + case PCB_CH_STATE_SECOND: + { + double pitch_mult = conf_serpentine.plugins.serpentine.pitch; + pcb_route_t route; + pcb_line_t * p_line = (pcb_line_t *)pcb_crosshair.AttachedObject.Ptr2; + rnd_point_t point1; + rnd_point_t point2; + point1.X = pcb_crosshair.AttachedObject.X; + point1.Y = pcb_crosshair.AttachedObject.Y; + point2.X = pcb_crosshair.AttachedObject.tx; + point2.Y = pcb_crosshair.AttachedObject.ty; + + if(pitch_mult < 1.0) + pitch_mult = 1.0; + + pcb_route_init(&route); + if(serpentine_calculate_route(&route,p_line, &point1, &point2, pitch_mult * p_line->Thickness, NULL ) == 0) { + pcb_route_apply_to_line(&route, (pcb_layer_t *)pcb_crosshair.AttachedObject.Ptr1, p_line); + } + pcb_route_destroy(&route); + pcb_undo_inc_serial(); + } + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + break; + + case PCB_CH_STATE_THIRD: + break; + + default: /* all following points */ + break; + } +} + +static void tool_serpentine_adjust_attached_objects(void) +{ + pcb_crosshair.AttachedObject.tx = pcb_crosshair.X; + pcb_crosshair.AttachedObject.ty = pcb_crosshair.Y; +} + +static void tool_serpentine_draw_attached(void) +{ + switch (pcb_crosshair.AttachedObject.State) { + case PCB_CH_STATE_SECOND: + { + double pitch_mult = conf_serpentine.plugins.serpentine.pitch; + pcb_route_t route; + serpentine_info_t info; + pcb_line_t * p_line = (pcb_line_t *)pcb_crosshair.AttachedObject.Ptr2; + rnd_point_t point1; + rnd_point_t point2; + point1.X = pcb_crosshair.AttachedObject.X; + point1.Y = pcb_crosshair.AttachedObject.Y; + point2.X = pcb_crosshair.AttachedObject.tx; + point2.Y = pcb_crosshair.AttachedObject.ty; + + if(pitch_mult < 1.0) + pitch_mult = 1.0; + + pcb_route_init(&route); + if(serpentine_calculate_route(&route,p_line, &point1, &point2, pitch_mult * p_line->Thickness, &info ) == 0) { + pcb_route_draw(&route, pcb_crosshair.GC); + if (conf_core.editor.show_drc) + pcb_route_draw_drc(&route,pcb_crosshair.GC); + pcb_route_destroy(&route); + + draw_serpentine_ui(&info); + } + } + break; + + default : + break; + } +} + +rnd_bool tool_serpentine_undo_act() +{ + /* don't allow undo in the middle of an operation */ + if (pcb_crosshair.AttachedObject.State != PCB_CH_STATE_FIRST) + return rnd_false; + return rnd_true; +} + +static rnd_tool_t tool_serpentine = { + "serpentine", "experimental", + NULL, 100, NULL, RND_TOOL_CURSOR_NAMED(NULL), 0, + tool_serpentine_init, + tool_serpentine_uninit, + tool_serpentine_notify_mode, + NULL, + tool_serpentine_adjust_attached_objects, + tool_serpentine_draw_attached, + tool_serpentine_undo_act, + NULL, + NULL, /* escape */ + + rnd_false +}; + + + +/*** Actions ***/ + +static const char pcb_acts_serpentine[] = "serpentine()"; +static const char pcb_acth_serpentine[] = "Tool for drawing serpentines"; +fgw_error_t pcb_act_serpentine(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_tool_select_by_name(&PCB->hidlib, "serpentine"); + RND_ACT_IRES(0); + return 0; +} + + +rnd_action_t serpentine_action_list[] = { + {"Serpentine", pcb_act_serpentine, pcb_acth_serpentine, pcb_acts_serpentine} +}; + +int pplg_check_ver_serpentine(int ver_needed) { return 0; } + +void pplg_uninit_serpentine(void) +{ + rnd_remove_actions_by_cookie(serpentine_cookie); + rnd_tool_unreg_by_cookie(serpentine_cookie); + rnd_conf_unreg_fields("plugins/serpentine/"); +} + +int pplg_init_serpentine(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(serpentine_action_list, serpentine_cookie) +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_serpentine, field,isarray,type_name,cpath,cname,desc,flags); +#include "serpentine_conf_fields.h" + + rnd_tool_reg(&tool_serpentine, serpentine_cookie); + + return 0; +} + Index: tags/2.3.0/src_plugins/serpentine/serpentine.pup =================================================================== --- tags/2.3.0/src_plugins/serpentine/serpentine.pup (nonexistent) +++ tags/2.3.0/src_plugins/serpentine/serpentine.pup (revision 33253) @@ -0,0 +1,8 @@ +$class feature +$short Serpentine creation +$long Create serpentines on existing lines. +$state WIP +#$package auto +default disable-all +autoload 1 + Index: tags/2.3.0/src_plugins/serpentine/serpentine_conf.h =================================================================== --- tags/2.3.0/src_plugins/serpentine/serpentine_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/serpentine/serpentine_conf.h (revision 33253) @@ -0,0 +1,17 @@ +#ifndef PCB_SERPENTINE_CONF_H +#define PCB_SERPENTINE_CONF_H + +#include + +typedef struct { + const struct plugins { + const struct serpentine { + RND_CFT_REAL pitch; /* This value multiplied by the line width gives the serpentine pitch */ + RND_CFT_BOOLEAN show_length; /* If true, show the length gained by adding the serpentine to an existing line */ + } serpentine; + } plugins; +} conf_serpentine_t; + +extern conf_serpentine_t conf_serpentine; + +#endif Index: tags/2.3.0/src_plugins/shand_cmd/Makefile =================================================================== --- tags/2.3.0/src_plugins/shand_cmd/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/shand_cmd/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_shand_cmd + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/shand_cmd/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/shand_cmd/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/shand_cmd/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {shand_cmd} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/shand_cmd/command.o @] + +switch /local/pcb/shand_cmd/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/shand_cmd/command.c =================================================================== --- tags/2.3.0/src_plugins/shand_cmd/command.c (nonexistent) +++ tags/2.3.0/src_plugins/shand_cmd/command.c (revision 33253) @@ -0,0 +1,227 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996, 2005 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include + +#include "board.h" +#include "build_run.h" +#include "buffer.h" +#include "command.h" +#include "data.h" +#include +#include +#include "plug_io.h" +#include +#include +#include +#include +#include + +static const char pcb_acts_Help[] = "h"; +static const char pcb_acth_Help[] = "Print a help message for commands."; +static fgw_error_t pcb_act_Help(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_message(RND_MSG_INFO, + "following shorthand commands are supported:\n" + " h display this help message\n" + " l [file] load layout\n" + " le [file] load element to buffer\n" + " m [file] load layout to buffer (merge)\n" + " q quits the application\n" + " q! quits without save warning\n" + " rn [file] read in a net-list file\n" + " s [file] save layout\n" + " w [file] save layout\n" + " wq [file] save layout and quit\n"); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_LoadLayout[] = "l [name] [format]"; +static const char pcb_acth_LoadLayout[] = "Loads layout data."; +/* DOC: l.html */ +static fgw_error_t pcb_act_LoadLayout(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *filename, *format = NULL; + + RND_ACT_CONVARG(1, FGW_STR, LoadLayout, filename = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, LoadLayout, format = argv[2].val.str); + + if (!PCB->Changed || (rnd_hid_message_box(RND_ACT_HIDLIB, "warning", "Load data lose", "OK to override layout data?", "cancel", 0, "ok", 1, NULL) == 1)) + pcb_load_pcb(filename, format, rnd_true, 0); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_LoadElementToBuffer[] = "le [name]"; +static const char pcb_acth_LoadElementToBuffer[] = "Loads an element (subcircuit, footprint) into the current buffer."; +/* DOC: le.html */ +static fgw_error_t pcb_act_LoadElementToBuffer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *filename; + + RND_ACT_CONVARG(1, FGW_STR, LoadElementToBuffer, filename = argv[1].val.str); + + if (pcb_buffer_load_footprint(PCB_PASTEBUFFER, filename, NULL)) + rnd_tool_select_by_name(&PCB->hidlib, "buffer"); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_LoadLayoutToBuffer[] = "m [name]"; +static const char pcb_acth_LoadLayoutToBuffer[] = "Loads a layout into the current buffer."; +/* DOC: m.html */ +static fgw_error_t pcb_act_LoadLayoutToBuffer(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *filename, *format = NULL; + + RND_ACT_CONVARG(1, FGW_STR, LoadLayoutToBuffer, filename = argv[1].val.str); + RND_ACT_MAY_CONVARG(2, FGW_STR, LoadLayoutToBuffer, format = argv[2].val.str); + + if (pcb_buffer_load_layout(PCB, PCB_PASTEBUFFER, filename, format)) + rnd_tool_select_by_name(&PCB->hidlib, "buffer"); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_Quit[] = "q"; +static const char pcb_acth_Quit[] = "Quits the application after confirming."; +/* DOC: q.html */ +static fgw_error_t pcb_act_Quit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + if (!PCB->Changed || (rnd_hid_message_box(RND_ACT_HIDLIB, "warning", "Close: lose data", "OK to lose data?", "cancel", 0, "ok", 1, NULL) == 1)) + pcb_quit_app(); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_ReallyQuit[] = "q!"; +static const char pcb_acth_ReallyQuit[] = "Quits the application without confirming."; +/* DOC: q.html */ +static fgw_error_t pcb_act_ReallyQuit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_quit_app(); + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_LoadNetlist[] = "rn [name]"; +static const char pcb_acth_LoadNetlist[] = "Reads netlist."; +/* DOC: rn.html */ +static fgw_error_t pcb_act_LoadNetlist(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *filename; + + RND_ACT_CONVARG(1, FGW_STR, LoadNetlist, filename = argv[1].val.str); + + if (PCB->Netlistname) + free(PCB->Netlistname); + PCB->Netlistname = rnd_strdup_strip_wspace(filename); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_SaveLayout[] = "s [name]\nw [name]"; +static const char pcb_acth_SaveLayout[] = "Saves layout data."; +/* DOC: s.html w.html */ +static fgw_error_t pcb_act_SaveLayout(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *filename = NULL; + + RND_ACT_MAY_CONVARG(1, FGW_STR, SaveLayout, filename = argv[1].val.str); + + if (filename == NULL) { + if (PCB->hidlib.filename) { + if (pcb_save_pcb(PCB->hidlib.filename, NULL) == 0) + pcb_board_set_changed_flag(PCB, rnd_false); + } + else + rnd_message(RND_MSG_ERROR, "No filename to save to yet\n"); + } + else { + if (pcb_save_pcb(filename, NULL) == 0) { + pcb_board_set_changed_flag(PCB, rnd_false); + free(PCB->hidlib.filename); + PCB->hidlib.filename = rnd_strdup(filename); + rnd_event(&PCB->hidlib, RND_EVENT_BOARD_FN_CHANGED, NULL); + } + } + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_SaveLayoutAndQuit[] = "wq"; +static const char pcb_acth_SaveLayoutAndQuit[] = "Saves the layout data and quits."; +/* DOC: wq.html */ +static fgw_error_t pcb_act_SaveLayoutAndQuit(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + if (RND_ACT_CALL_C(RND_ACT_HIDLIB, pcb_act_SaveLayout, res, argc, argv) == 0) + return pcb_act_Quit(res, argc, argv); + + RND_ACT_IRES(1); + return 0; +} + +rnd_action_t shand_cmd_action_list[] = { + {"h", pcb_act_Help, pcb_acth_Help, pcb_acts_Help}, + {"l", pcb_act_LoadLayout, pcb_acth_LoadLayout, pcb_acts_LoadLayout}, + {"le", pcb_act_LoadElementToBuffer, pcb_acth_LoadElementToBuffer, pcb_acts_LoadElementToBuffer}, + {"m", pcb_act_LoadLayoutToBuffer, pcb_acth_LoadLayoutToBuffer, pcb_acts_LoadLayoutToBuffer}, + {"q", pcb_act_Quit, pcb_acth_Quit, pcb_acts_Quit}, + {"q!", pcb_act_ReallyQuit, pcb_acth_ReallyQuit, pcb_acts_ReallyQuit}, + {"rn", pcb_act_LoadNetlist, pcb_acth_LoadNetlist, pcb_acts_LoadNetlist}, + {"s", pcb_act_SaveLayout, pcb_acth_SaveLayout, pcb_acts_SaveLayout}, + {"w", pcb_act_SaveLayout, pcb_acth_SaveLayout, pcb_acts_SaveLayout}, + {"wq", pcb_act_SaveLayoutAndQuit, pcb_acth_SaveLayoutAndQuit, pcb_acts_SaveLayoutAndQuit} +}; + +static const char *shand_cmd_cookie = "shand_cmd plugin"; + +int pplg_check_ver_shand_cmd(int ver_needed) { return 0; } + +void pplg_uninit_shand_cmd(void) +{ + rnd_remove_actions_by_cookie(shand_cmd_cookie); +} + +int pplg_init_shand_cmd(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(shand_cmd_action_list, shand_cmd_cookie) + return 0; +} Index: tags/2.3.0/src_plugins/shand_cmd/command.h =================================================================== --- tags/2.3.0/src_plugins/shand_cmd/command.h (nonexistent) +++ tags/2.3.0/src_plugins/shand_cmd/command.h (revision 33253) @@ -0,0 +1,37 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 1994,1995,1996 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + */ + +#ifndef PCB_COMMAND_H +#define PCB_COMMAND_H + +#include "config.h" + +void ExecuteUserCommand(char *); +void CallActionProc(char *action, char **arg, int argc); + +#endif Index: tags/2.3.0/src_plugins/shand_cmd/shand_cmd.pup =================================================================== --- tags/2.3.0/src_plugins/shand_cmd/shand_cmd.pup (nonexistent) +++ tags/2.3.0/src_plugins/shand_cmd/shand_cmd.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short command shorthands +$long vi-like command shorthands (1..3 character long commands) +$state works +$package extra +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/shape/Makefile =================================================================== --- tags/2.3.0/src_plugins/shape/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/shape/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_shape + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/shape/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/shape/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/shape/Plug.tmpasm (revision 33253) @@ -0,0 +1,12 @@ +put /local/pcb/mod {shape} +put /local/pcb/mod/MENUFILE {shape-menu.lht} +put /local/pcb/mod/MENUVAR {shape_menu} +append /local/pcb/mod/OBJS [@ + $(PLUGDIR)/shape/shape.o +@] + +switch /local/pcb/shape/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/shape/shape-menu.lht =================================================================== --- tags/2.3.0/src_plugins/shape/shape-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/shape/shape-menu.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-v1 { + li:anchored { + ha:@feature_plugins { + li:submenu { + ha:Shape generator (interactive) = { action=shape() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/shape/shape.c =================================================================== --- tags/2.3.0/src_plugins/shape/shape.c (nonexistent) +++ tags/2.3.0/src_plugins/shape/shape.c (revision 33253) @@ -0,0 +1,646 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "shape.h" + +#include +#include + +#include "board.h" +#include "buffer.h" +#include +#include "conf_core.h" +#include "data.h" +#include +#include "event.h" +#include "layer.h" +#include +#include "obj_poly.h" +#include "obj_poly_draw.h" +#include "rotate.h" +#include +#include +#include "menu_internal.c" + +const char *pcb_shape_corner_name[] = {"Rn", "Ch", "Sq", NULL}; + +const char *pcb_shape_cookie = "shape plugin"; +static pcb_layer_t pcb_shape_current_layer_; +pcb_layer_t *pcb_shape_current_layer = &pcb_shape_current_layer_; + +static pcb_poly_t *regpoly(pcb_layer_t *layer, int corners, rnd_coord_t rx, rnd_coord_t ry, double rot_deg, rnd_coord_t cx, rnd_coord_t cy) +{ + int n, flags = PCB_FLAG_CLEARPOLY; + double cosra, sinra, a, da = 2*M_PI / (double)corners; + pcb_poly_t *p; + + if (corners < 3) + return NULL; + + if ((rx < 10) || (ry < 10)) + return NULL; + + if ((rot_deg >= 360.0) || (rot_deg <= -360.0)) + rot_deg = fmod(rot_deg, 360.0); + + if (conf_core.editor.full_poly) + flags |= PCB_FLAG_FULLPOLY; + if (conf_core.editor.clear_polypoly) + flags |= PCB_FLAG_CLEARPOLYPOLY; + + p = pcb_poly_new(layer, 2 * conf_core.design.clearance, pcb_flag_make(flags)); + if (p == NULL) + return NULL; + + if (rot_deg != 0.0) { + cosra = cos(rot_deg / RND_RAD_TO_DEG); + sinra = sin(rot_deg / RND_RAD_TO_DEG); + } + + for(n = 0,a = 0; n < corners; n++,a+=da) { + rnd_coord_t x, y; + x = rnd_round(cos(a) * (double)rx + (double)cx); + y = rnd_round(sin(a) * (double)ry + (double)cy); + if (rot_deg != 0.0) + rnd_rotate(&x, &y, cx, cy, cosra, sinra); + pcb_poly_point_new(p, x, y); + } + + pcb_add_poly_on_layer(layer, p); + + return p; +} + +static void elarc90(pcb_poly_t *p, rnd_coord_t ccx, rnd_coord_t ccy, rnd_coord_t cx, rnd_coord_t cy, rnd_coord_t sx, rnd_coord_t sy, rnd_coord_t ex, rnd_coord_t ey, rnd_coord_t rx, rnd_coord_t ry, double sa, int segs, int need_rot, double cosra, double sinra, rnd_coord_t rotcx, rnd_coord_t rotcy, pcb_shape_corner_t style) +{ + rnd_coord_t lx, ly; + double da = (M_PI/2.0/((double)segs-1)); + int n; + + if (style == PCB_CORN_SQUARE) { + /* add original corner point */ + pcb_poly_point_new(p, ccx, ccy); + return; + } + + /* add exact start point */ + if (need_rot) + rnd_rotate(&sx, &sy, rotcx, rotcy, cosra, sinra); + pcb_poly_point_new(p, sx, sy); + lx = sx; + ly = sy; + + if (style == PCB_CORN_ROUND) { + /* add approximated ellipse points */ + segs -= 2; + for(n = 0,sa+=da; n < segs; n++,sa+=da) { + rnd_coord_t x, y; + x = rnd_round((double)cx + cos(sa) * (double)rx); + y = rnd_round((double)cy - sin(sa) * (double)ry); + if (need_rot) + rnd_rotate(&x, &y, rotcx, rotcy, cosra, sinra); + if ((x != lx) || (y != ly)) + pcb_poly_point_new(p, x, y); + lx = x; + ly = y; + } + } + + /* add exact end point */ + if (need_rot) + rnd_rotate(&ex, &ey, rotcx, rotcy, cosra, sinra); + if ((ex != lx) || (ey != ly)) + pcb_poly_point_new(p, ex, ey); +} + +#define CORNER(outx, outy, rect_signx, rect_signy, rsignx, rsigny) \ + outx = rnd_round((double)cx + rect_signx * (double)w/2 + rsignx*rx); \ + outy = rnd_round((double)cy + rect_signy * (double)h/2 + rsigny*ry); +pcb_poly_t *pcb_genpoly_roundrect(pcb_layer_t *layer, rnd_coord_t w, rnd_coord_t h, rnd_coord_t rx, rnd_coord_t ry, double rot_deg, rnd_coord_t cx, rnd_coord_t cy, pcb_shape_corner_t corner[4], double roundres) +{ + pcb_poly_t *p; + rnd_coord_t maxr = (w < h ? w : h) / 2, x, y, ex, ey, acx, acy, ccx, ccy; + int segs, need_rot, flags = PCB_FLAG_CLEARPOLY; + double cosra, sinra; + + if ((w <= 10) || (h <= 10)) + return NULL; + + if ((rx > maxr) || (ry > maxr)) + return NULL; + + if (rot_deg != 0.0) { + cosra = cos(rot_deg / RND_RAD_TO_DEG); + sinra = sin(rot_deg / RND_RAD_TO_DEG); + need_rot = 1; + } + else + need_rot = 0; + + segs = sqrt((double)(rx+ry) / (double)RND_MM_TO_COORD(0.1)); + if (segs < 3) segs = 3; + if (segs > 15) segs = 15; + + segs = rnd_round((double)segs * roundres); + + p = pcb_poly_new(layer, 2 * conf_core.design.clearance, pcb_flag_make(flags)); + if (p == NULL) + return NULL; + + /* top right */ + CORNER( x, y, +1, -1, 0, +1); /* start */ + CORNER(acx, acy, +1, -1, -1, +1); /* center */ + CORNER( ex, ey, +1, -1, -1, 0); /* end */ + CORNER(ccx, ccy, +1, -1, 0, 0); /* corner point */ + elarc90(p, ccx, ccy, acx, acy, x, y, ex, ey, rx, ry, 0, segs, need_rot, cosra, sinra, cx, cy, corner[1]); + + /* top left */ + CORNER( x, y, -1, -1, +1, 0); /* start */ + CORNER(acx, acy, -1, -1, +1, +1); /* center */ + CORNER( ex, ey, -1, -1, 0, +1); /* end */ + CORNER(ccx, ccy, -1, -1, 0, 0); /* corner point */ + elarc90(p, ccx, ccy, acx, acy, x, y, ex, ey, rx, ry, M_PI/2.0, segs, need_rot, cosra, sinra, cx, cy, corner[0]); + + /* bottom left */ + CORNER( x, y, -1, +1, 0, -1); /* start */ + CORNER(acx, acy, -1, +1, +1, -1); /* center */ + CORNER( ex, ey, -1, +1, +1, 0); /* end */ + CORNER(ccx, ccy, -1, +1, 0, 0); /* corner point */ + elarc90(p, ccx, ccy, acx, acy, x, y, ex, ey, rx, ry, M_PI, segs, need_rot, cosra, sinra, cx, cy, corner[2]); + + /* bottom right*/ + CORNER( x, y, +1, +1, -1, 0); /* start */ + CORNER(acx, acy, +1, +1, -1, -1); /* center */ + CORNER( ex, ey, +1, +1, 0, -1); /* end */ + CORNER(ccx, ccy, +1, +1, 0, 0); /* corner point */ + elarc90(p, ccx, ccy, acx, acy, x, y, ex, ey, rx, ry, M_PI*3.0/2.0, segs, need_rot, cosra, sinra, cx, cy, corner[3]); + + pcb_add_poly_on_layer(layer, p); + + return p; +} +#undef CORNER + +void pcb_shape_roundrect(pcb_pstk_shape_t *shape, rnd_coord_t width, rnd_coord_t height, double roundness) +{ + pcb_pstk_poly_t *dst = &shape->data.poly; + pcb_poly_t *p; + pcb_layer_t *layer; + static pcb_data_t data = {0}; + int inited = 0, n; + rnd_coord_t rr, minor = MIN(width, height); + pcb_shape_corner_t corner[4] = { PCB_CORN_ROUND, PCB_CORN_ROUND, PCB_CORN_ROUND, PCB_CORN_ROUND}; + + + if (!inited) { + pcb_data_init(&data); + data.LayerN = 1; + layer = &data.Layer[0]; + memset(layer, 0, sizeof(pcb_layer_t)); + layer->parent.data = &data; + layer->parent_type = PCB_PARENT_DATA; + inited = 1; + } + else + layer = &data.Layer[0]; + + rr = rnd_round(minor * roundness); + p = pcb_genpoly_roundrect(layer, width, height, rr, rr, 0, 0, 0, corner, 4.0); + pcb_pstk_shape_alloc_poly(dst, p->PointN); + shape->shape = PCB_PSSH_POLY; + + for(n = 0; n < p->PointN; n++) { + dst->x[n] = p->Points[n].X; + dst->y[n] = p->Points[n].Y; + } + pcb_poly_free_fields(p); + free(p); +} + + +static pcb_poly_t *any_poly_place(pcb_data_t *data, pcb_layer_t *layer, pcb_poly_t *p) +{ + if (p == NULL) + return NULL; + + pcb_poly_init_clip(PCB->Data, PCB_CURRLAYER(PCB), p); + pcb_poly_invalidate_draw(PCB_CURRLAYER(PCB), p); + + if (data != PCB->Data) { + pcb_buffer_clear(PCB, PCB_PASTEBUFFER); + pcb_copy_obj_to_buffer(PCB, data, PCB->Data, PCB_OBJ_POLY, PCB_CURRLAYER(PCB), p, p); + rnd_r_delete_entry(PCB_CURRLAYER(PCB)->polygon_tree, (rnd_box_t *)p); + pcb_poly_free_fields(p); + pcb_poly_free(p); + rnd_tool_select_by_name(&PCB->hidlib, "buffer"); + } + return p; +} + +static pcb_poly_t *regpoly_place(pcb_data_t *data, pcb_layer_t *layer, int corners, rnd_coord_t rx, rnd_coord_t ry, double rot_deg, rnd_coord_t cx, rnd_coord_t cy) +{ + pcb_poly_t *p; + + if (layer == pcb_shape_current_layer) + layer = PCB_CURRLAYER(PCB); + + p = regpoly(layer, corners, rx, ry, rot_deg, cx, cy); + return any_poly_place(data, layer, p); +} + +static pcb_poly_t *roundrect_place(pcb_data_t *data, pcb_layer_t *layer, rnd_coord_t w, rnd_coord_t h, rnd_coord_t rx, rnd_coord_t ry, double rot_deg, rnd_coord_t cx, rnd_coord_t cy, pcb_shape_corner_t corner[4], double roundres) +{ + pcb_poly_t *p; + + if (layer == pcb_shape_current_layer) + layer = PCB_CURRLAYER(PCB); + + p = pcb_genpoly_roundrect(layer, w, h, rx, ry, rot_deg, cx, cy, corner, roundres); + return any_poly_place(data, layer, p); +} + +static pcb_line_t *circle_place(pcb_data_t *data, pcb_layer_t *layer, rnd_coord_t dia, rnd_coord_t cx, rnd_coord_t cy) +{ + int flags = 0; + pcb_line_t *l; + + if (layer == pcb_shape_current_layer) + layer = PCB_CURRLAYER(PCB); + + if (conf_core.editor.clear_line) + flags |= PCB_FLAG_CLEARLINE; + + l = pcb_line_new(layer, cx, cy, cx, cy, dia, conf_core.design.clearance*2, pcb_flag_make(flags)); + if (l != NULL) { + if ((conf_core.editor.clear_line) && (data == PCB->Data)) + pcb_poly_clear_from_poly(data, PCB_OBJ_LINE, layer, l); + + if (data != PCB->Data) { + pcb_buffer_clear(PCB, PCB_PASTEBUFFER); + pcb_copy_obj_to_buffer(PCB, data, PCB->Data, PCB_OBJ_LINE, PCB_CURRLAYER(PCB), l, l); + rnd_r_delete_entry(PCB_CURRLAYER(PCB)->line_tree, (rnd_box_t *)l); + pcb_line_free(l); + rnd_tool_select_by_name(&PCB->hidlib, "buffer"); + } + } + return l; +} + +static int get_where(const char *arg, pcb_data_t **data, rnd_coord_t *x, rnd_coord_t *y, rnd_bool *have_coords) +{ + const char *dst; + char *end; + int a = 0; + rnd_bool succ; + + dst = arg; + if (rnd_strncasecmp(dst, "buffer", 6) == 0) { + *data = PCB_PASTEBUFFER->Data; + dst += 6; + a = 1; + } + else + *data = PCB->Data; + + end = strchr(dst, ';'); + if (end != NULL) { + char *sx, *sy, *tmp; + int offs = end - dst; + *have_coords = rnd_true; + a = 1; + + tmp = rnd_strdup(dst); + tmp[offs] = '\0'; + sx = tmp; + sy = tmp + offs + 1; + *x = rnd_get_value(sx, NULL, NULL, &succ); + if (succ) + *y = rnd_get_value(sy, NULL, NULL, &succ); + free(tmp); + if (!succ) { + rnd_message(RND_MSG_ERROR, "regpoly(): invalid center coords '%s'\n", dst); + return -1; + } + } + return a; +} + +static rnd_bool parse2coords(const char *arg, rnd_coord_t *rx, rnd_coord_t *ry) +{ + const char *dst; + char *end; + rnd_bool succ; + + if (arg == NULL) + return rnd_false; + + dst = arg; + end = strchr(dst, ';'); + if (end != NULL) { + char *sx, *sy, *tmp = rnd_strdup(dst); + int offs = end - dst; + tmp[offs] = '\0'; + sx = tmp; + sy = tmp + offs + 1; + *rx = rnd_get_value(sx, NULL, NULL, &succ); + if (succ) + *ry = rnd_get_value(sy, NULL, NULL, &succ); + free(tmp); + } + else + *rx = *ry = rnd_get_value(dst, NULL, NULL, &succ); + return succ; +} + +static const char pcb_acts_regpoly[] = "regpoly([where,] corners, radius [,rotation])"; +static const char pcb_acth_regpoly[] = "Generate regular polygon. Where is x;y and radius is either r or rx;ry. Rotation is in degrees."; +fgw_error_t pcb_act_regpoly(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *args[6]; + double rot = 0; + rnd_coord_t x = 0, y = 0, rx, ry = 0; + rnd_bool succ, have_coords = rnd_false; + int corners = 0, a, n; + pcb_data_t *data; + char *end; + + if (argc < 3) { + rnd_message(RND_MSG_ERROR, "regpoly() needs at least two parameters\n"); + RND_ACT_IRES(-1); + return 0; + } + if (argc > 5) { + rnd_message(RND_MSG_ERROR, "regpoly(): too many arguments\n"); + RND_ACT_IRES(-1); + return 0; + } + + memset(args, 0, sizeof(args)); + for(n = 1; n < argc; n++) + RND_ACT_MAY_CONVARG(n, FGW_STR, regpoly, args[n-1] = argv[n].val.str); + + a = get_where(args[0], &data, &x, &y, &have_coords); + if (a < 0) { + RND_ACT_IRES(-1); + return 0; + } + + corners = strtol(args[a], &end, 10); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "regpoly(): invalid number of corners '%s'\n", args[a]); + RND_ACT_IRES(-1); + return 0; + } + a++; + + /* convert radii */ + succ = parse2coords(args[a], &rx, &ry); + if (!succ) { + rnd_message(RND_MSG_ERROR, "regpoly(): invalid radius '%s'\n", args[a]); + RND_ACT_IRES(-1); + return 0; + } + a++; + + if (a < argc-1) { + rot = strtod(args[a], &end); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "regpoly(): invalid rotation '%s'\n", args[a]); + RND_ACT_IRES(-1); + return 0; + } + } + + if ((data == PCB->Data) && (!have_coords)) + rnd_hid_get_coords("Click on the center of the polygon", &x, &y, 0); + + if (regpoly_place(data, PCB_CURRLAYER(PCB), corners, rx, ry, rot, x, y) == NULL) + rnd_message(RND_MSG_ERROR, "regpoly(): failed to create the polygon\n"); + + RND_ACT_IRES(0); + return 0; +} + + +static const char pcb_acts_roundrect[] = "roundrect([where,] width[;height] [,rx[;ry] [,rotation [,cornstyle [,roundness]]]])"; +static const char pcb_acth_roundrect[] = "Generate a rectangle with round corners"; +fgw_error_t pcb_act_roundrect(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *args[8]; + int n, a; + pcb_data_t *data; + rnd_bool succ, have_coords = rnd_false; + rnd_coord_t x = 0, y = 0, w, h, rx, ry; + double rot = 0.0, roundres = 1.0; + char *end; + pcb_shape_corner_t corner[4] = { PCB_CORN_ROUND, PCB_CORN_ROUND, PCB_CORN_ROUND, PCB_CORN_ROUND}; + + if (argc < 2) { + rnd_message(RND_MSG_ERROR, "roundrect() needs at least one parameters\n"); + RND_ACT_IRES(-1); + return 0; + } + if (argc > 8) { + rnd_message(RND_MSG_ERROR, "roundrect(): too many arguments\n"); + RND_ACT_IRES(-1); + return 0; + } + + memset(args, 0, sizeof(args)); + for(n = 1; n < argc; n++) + RND_ACT_MAY_CONVARG(n, FGW_STR, regpoly, args[n-1] = argv[n].val.str); + + if (argc > 2) { + a = get_where(args[0], &data, &x, &y, &have_coords); + if (a < 0) { + RND_ACT_IRES(-1); + return 0; + } + } + else { + a = 0; + data = PCB->Data; + have_coords = 1; + rnd_hid_get_coords("Click on the center of the rectangle", &x, &y, 0); + } + + /* convert width;height */ + succ = parse2coords(args[a], &w, &h); + if (!succ) { + rnd_message(RND_MSG_ERROR, "roundrect(): invalid width or height '%s'\n", args[a]); + RND_ACT_IRES(-1); + return 0; + } + a++; + + /* convert radii */ + if (a < argc-1) { + succ = parse2coords(args[a], &rx, &ry); + if (!succ) { + rnd_message(RND_MSG_ERROR, "roundrect(): invalid width or height '%s'\n", args[a]); + RND_ACT_IRES(-1); + return 0; + } + a++; + } + else + rx = ry = (w+h)/16; /* 1/8 of average w & h */ + + if (a < argc-1) { + rot = strtod(args[a], &end); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "roundrect(): invalid rotation '%s'\n", args[a]); + RND_ACT_IRES(-1); + return 0; + } + a++; + } + + if (a < argc-1) { + const char *s; + int n; + for(n = 0, s = args[a]; (n < 4) && (*s != '\0'); s++,n++) { + switch(*s) { + case 'r': case 'R': corner[n] = PCB_CORN_ROUND; break; + case 'q': case 'Q': corner[n] = PCB_CORN_SQUARE; break; + case 'c': case 'C': corner[n] = PCB_CORN_CHAMF; break; + default: + rnd_message(RND_MSG_ERROR, "roundrect(): invalid corner style character '%c' - has to eb r for round, q for square or c for chamfed", *s); + RND_ACT_IRES(-1); + return 0; + } + } + a++; + } + + if (a < argc-1) { + roundres = strtod(args[a], &end); + if (*end != '\0') { + rnd_message(RND_MSG_ERROR, "roundrect(): roundness '%s'\n", args[a]); + RND_ACT_IRES(-1); + return 0; + } + if (roundres < 0.1) + roundres = 0.1; + if (roundres > 5) + roundres = 5; + a++; + } + + if ((data == PCB->Data) && (!have_coords)) + rnd_hid_get_coords("Click on the center of the polygon", &x, &y, 0); + + if (roundrect_place(data, PCB_CURRLAYER(PCB), w, h, rx, ry, rot, x, y, corner, roundres) == NULL) + rnd_message(RND_MSG_ERROR, "roundrect(): failed to create the polygon\n"); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_circle[] = "circle([where,] diameter)"; +static const char pcb_acth_circle[] = "Generate a filled circle (zero length round cap line)"; +fgw_error_t pcb_act_circle(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *args[6]; + int n, a; + pcb_data_t *data; + rnd_bool succ, have_coords = rnd_false; + rnd_coord_t x = 0, y = 0, dia; + + if (argc < 2) { + rnd_message(RND_MSG_ERROR, "circle() needs at least one parameters (diameter)\n"); + RND_ACT_IRES(-1); + return 0; + } + if (argc > 3) { + rnd_message(RND_MSG_ERROR, "circle(): too many arguments\n"); + RND_ACT_IRES(-1); + return 0; + } + + memset(args, 0, sizeof(args)); + for(n = 1; n < argc; n++) + RND_ACT_MAY_CONVARG(n, FGW_STR, circle, args[n-1] = argv[n].val.str); + + a = get_where(args[0], &data, &x, &y, &have_coords); + if (a < 0) { + RND_ACT_IRES(-1); + return 0; + } + + dia = rnd_get_value(args[a], NULL, NULL, &succ); + if (!succ) { + rnd_message(RND_MSG_ERROR, "circle(): failed to convert dia: invalid coord (%s)\n", args[a]); + RND_ACT_IRES(1); + return 0; + } + + if ((dia < 1) || (dia > (PCB->hidlib.size_x + PCB->hidlib.size_y)/4)) { + rnd_message(RND_MSG_ERROR, "circle(): invalid diameter\n"); + RND_ACT_IRES(1); + return 0; + } + + if ((data == PCB->Data) && (!have_coords)) + rnd_hid_get_coords("Click on the center of the circle", &x, &y, 0); + + if (circle_place(PCB->Data, PCB_CURRLAYER(PCB), dia, x, y) == NULL) + rnd_message(RND_MSG_ERROR, "circle(): failed to create the polygon\n"); + + RND_ACT_IRES(0); + return 0; +} + +#include "shape_dialog.c" + +rnd_action_t shape_action_list[] = { + {"regpoly", pcb_act_regpoly, pcb_acth_regpoly, pcb_acts_regpoly}, + {"roundrect", pcb_act_roundrect, pcb_acth_roundrect, pcb_acts_roundrect}, + {"circle", pcb_act_circle, pcb_acth_circle, pcb_acts_circle}, + {"shape", pcb_act_shape, pcb_acth_shape, pcb_acts_shape} +}; + +int pplg_check_ver_shape(int ver_needed) { return 0; } + +void pplg_uninit_shape(void) +{ + rnd_hid_menu_unload(rnd_gui, pcb_shape_cookie); + rnd_event_unbind_allcookie(pcb_shape_cookie); + rnd_remove_actions_by_cookie(pcb_shape_cookie); +} + +int pplg_init_shape(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(shape_action_list, pcb_shape_cookie) + + rnd_event_bind(PCB_EVENT_LAYERVIS_CHANGED, shape_layer_chg, NULL, pcb_shape_cookie); + + rnd_hid_menu_load(rnd_gui, NULL, pcb_shape_cookie, 175, NULL, 0, shape_menu, "plugin: shape"); + return 0; +} Index: tags/2.3.0/src_plugins/shape/shape.h =================================================================== --- tags/2.3.0/src_plugins/shape/shape.h (nonexistent) +++ tags/2.3.0/src_plugins/shape/shape.h (revision 33253) @@ -0,0 +1,53 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ +#ifndef PCB_SHAPE_H +#define PCB_SHAPE_H + +#include "board.h" +#include "data.h" +#include "layer.h" +#include + +/* special layer: when used, the shape is always placed on the current layer */ +extern pcb_layer_t *pcb_shape_current_layer; + +void pcb_shape_dialog(pcb_board_t *pcb, pcb_data_t *data, pcb_layer_t *layer, rnd_bool modal); + +typedef enum { + PCB_CORN_ROUND, + PCB_CORN_CHAMF, + PCB_CORN_SQUARE +} pcb_shape_corner_t; +extern const char *pcb_shape_corner_name[]; + +pcb_poly_t *pcb_genpoly_roundrect(pcb_layer_t *layer, rnd_coord_t w, rnd_coord_t h, rnd_coord_t rx, rnd_coord_t ry, double rot_deg, rnd_coord_t cx, rnd_coord_t cy, pcb_shape_corner_t corner[4], double roundres); + +/* shorthand rounded rectangle: rounding radius is roundness * smaller_size */ +void pcb_shape_roundrect(pcb_pstk_shape_t *shape, rnd_coord_t width, rnd_coord_t height, double roundness); + +#endif + + Index: tags/2.3.0/src_plugins/shape/shape.pup =================================================================== --- tags/2.3.0/src_plugins/shape/shape.pup (nonexistent) +++ tags/2.3.0/src_plugins/shape/shape.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short generate regular shapes +$long Generate objects of regular shape (regular polygons, circle, round rect) +$state works +$package (core) +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/shape/shape_dialog.c =================================================================== --- tags/2.3.0/src_plugins/shape/shape_dialog.c (nonexistent) +++ tags/2.3.0/src_plugins/shape/shape_dialog.c (revision 33253) @@ -0,0 +1,406 @@ +#include + +typedef struct { + RND_DAD_DECL_NOINIT(dlg) + pcb_board_t *pcb; + pcb_data_t *data; + pcb_layer_t *layer; + pcb_any_obj_t *obj; + + /* tab management */ + int tab; + + /* regpoly */ + int prx, pry, corners, pcx, pcy, prot, pell; + + /* roundrect */ + int w, h, rrect, rcx, rcy, rx, ry, rres, rrot, rell, corner[4]; + + /* circle */ + int dia, ccx, ccy; + +} ctx_t; + +/* Last open non-modal shape dialog */ +static ctx_t *shape_active = NULL; + +static void shp_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + ctx_t *shp = caller_data; + + if (shp == shape_active) + shape_active = NULL; + + RND_DAD_FREE(shp->dlg); + free(shp); +} + +static void del_obj(ctx_t *shp) +{ + if (shp->obj != NULL) { +/* pcb_remove_object(shp->obj->type, shp->layer, shp->obj, shp->obj);*/ + shp->obj = NULL; + } +} + +static void shp_chg_regpoly(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + ctx_t *shp = caller_data; + + /* elliptical logics */ + if (!shp->dlg[shp->pell].val.lng) { + rnd_gui->attr_dlg_widget_state(hid_ctx, shp->pry, rnd_false); + RND_DAD_SET_VALUE(hid_ctx, shp->pry, crd, shp->dlg[shp->prx].val.crd); + } + else + rnd_gui->attr_dlg_widget_state(hid_ctx, shp->pry, rnd_true); + + del_obj(shp); + shp->obj = (pcb_any_obj_t *)regpoly_place( + shp->data, shp->layer, shp->dlg[shp->corners].val.lng, + shp->dlg[shp->prx].val.crd, shp->dlg[shp->pry].val.crd, + shp->dlg[shp->prot].val.dbl, + shp->dlg[shp->pcx].val.crd, shp->dlg[shp->pcy].val.crd); +} + +static void shp_chg_roundrect(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + ctx_t *shp = caller_data; + pcb_shape_corner_t corner[4]; + int n; + + /* elliptical logics */ + if (!shp->dlg[shp->rell].val.lng) { + rnd_gui->attr_dlg_widget_state(hid_ctx, shp->ry, rnd_false); + RND_DAD_SET_VALUE(hid_ctx, shp->ry, crd, shp->dlg[shp->rx].val.crd); + } + else + rnd_gui->attr_dlg_widget_state(hid_ctx, shp->ry, rnd_true); + + /* rectangular logics */ + if (!shp->dlg[shp->rrect].val.lng) { + rnd_gui->attr_dlg_widget_state(hid_ctx, shp->h, rnd_false); + RND_DAD_SET_VALUE(hid_ctx, shp->h, crd, shp->dlg[shp->w].val.crd); + } + else + rnd_gui->attr_dlg_widget_state(hid_ctx, shp->h, rnd_true); + + for(n = 0; n < 4; n++) + corner[n] = shp->dlg[shp->corner[n]].val.lng; + + del_obj(shp); + shp->obj = (pcb_any_obj_t *)roundrect_place( + shp->data, shp->layer, + shp->dlg[shp->w].val.crd, shp->dlg[shp->h].val.crd, + shp->dlg[shp->rx].val.crd, shp->dlg[shp->ry].val.crd, + shp->dlg[shp->rrot].val.dbl, + shp->dlg[shp->rcx].val.crd, shp->dlg[shp->rcy].val.crd, + corner, shp->dlg[shp->rres].val.dbl); +} + +static void shp_chg_circle(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + ctx_t *shp = caller_data; + rnd_coord_t dia = shp->dlg[shp->dia].val.crd; + + if ((dia < 1) || (dia > (PCB->hidlib.size_x + PCB->hidlib.size_y)/4)) { + rnd_message(RND_MSG_ERROR, "Invalid diameter.\n"); + return; + } + + shp->obj = (pcb_any_obj_t *)circle_place( + shp->data, shp->layer, + dia, + shp->dlg[shp->ccx].val.crd, shp->dlg[shp->ccy].val.crd); +} + + +static void shape_layer_chg(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + void *hid_ctx; + int tab; + + if (shape_active == NULL) + return; + + hid_ctx = shape_active->dlg_hid_ctx; + tab = shape_active->dlg[shape_active->tab].val.lng; + switch(tab) { + case 0: shp_chg_regpoly(hid_ctx, shape_active, NULL); break; + case 1: shp_chg_roundrect(hid_ctx, shape_active, NULL); break; + case 2: shp_chg_circle(hid_ctx, shape_active, NULL); break; + } +} + +static void shp_chg_tab(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + shape_layer_chg(NULL, NULL, 0, NULL); +} + +void pcb_shape_dialog(pcb_board_t *pcb, pcb_data_t *data, pcb_layer_t *layer, rnd_bool modal) +{ + ctx_t *shp = calloc(sizeof(ctx_t), 1); + rnd_coord_t mm2 = RND_MM_TO_COORD(2); + rnd_coord_t maxr = RND_MM_TO_COORD(1000); + const char *tabs[] = {"Regular polygon", "Round rectangle", "Filled circle", NULL}; + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + + shp->pcb = pcb; + shp->data = data; + shp->layer = layer; + + RND_DAD_BEGIN_VBOX(shp->dlg); + RND_DAD_COMPFLAG(shp->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_TABBED(shp->dlg, tabs); + shp->tab = RND_DAD_CURRENT(shp->dlg); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_tab); + + /* regpoly tab */ + RND_DAD_BEGIN_VBOX(shp->dlg); + RND_DAD_LABEL(shp->dlg, "Generate regular polygon"); + RND_DAD_BEGIN_TABLE(shp->dlg, 2); + RND_DAD_LABEL(shp->dlg, "Number of corners"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_INTEGER(shp->dlg); + shp->corners = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINVAL(shp->dlg, 3); + RND_DAD_MAXVAL(shp->dlg, 64); + RND_DAD_DEFAULT_NUM(shp->dlg, 8); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_regpoly); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, "Shape radius"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->prx = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_DEFAULT_NUM(shp->dlg, mm2); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_regpoly); + RND_DAD_LABEL(shp->dlg, "x (horizontal)"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, ""); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->pry = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_DEFAULT_NUM(shp->dlg, mm2); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_regpoly); + RND_DAD_LABEL(shp->dlg, "y (vertical)"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, ""); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_BOOL(shp->dlg); + shp->pell = RND_DAD_CURRENT(shp->dlg); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_regpoly); + RND_DAD_LABEL(shp->dlg, "elliptical"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, "Rotation angle:"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_REAL(shp->dlg); + shp->prot = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINVAL(shp->dlg, -360); + RND_DAD_MAXVAL(shp->dlg, 360); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_regpoly); + RND_DAD_LABEL(shp->dlg, "deg"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, "Center offset"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->pcx = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_regpoly); + RND_DAD_LABEL(shp->dlg, "x (horizontal)"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, ""); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->pcy = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_regpoly); + RND_DAD_LABEL(shp->dlg, "y (vertical)"); + RND_DAD_END(shp->dlg); + RND_DAD_END(shp->dlg); + + RND_DAD_END(shp->dlg); + + /* roundrect tab */ + RND_DAD_BEGIN_VBOX(shp->dlg); + RND_DAD_LABEL(shp->dlg, "Generate rectange with rounded corners"); + RND_DAD_BEGIN_TABLE(shp->dlg, 2); + + RND_DAD_LABEL(shp->dlg, "Rectangle size"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->w = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_DEFAULT_NUM(shp->dlg, mm2); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_LABEL(shp->dlg, "width (horizontal)"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, ""); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->h = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_DEFAULT_NUM(shp->dlg, mm2); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_LABEL(shp->dlg, "height (vertical)"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, ""); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_BOOL(shp->dlg); + shp->rrect = RND_DAD_CURRENT(shp->dlg); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_LABEL(shp->dlg, "rectangular"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, "Rounding radius"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->rx = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_DEFAULT_NUM(shp->dlg, mm2/10); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_LABEL(shp->dlg, "x (horizontal)"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, ""); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->ry = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_DEFAULT_NUM(shp->dlg, mm2/10); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_LABEL(shp->dlg, "y (vertical)"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, ""); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_BOOL(shp->dlg); + shp->rell = RND_DAD_CURRENT(shp->dlg); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_LABEL(shp->dlg, "elliptical"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, "Arc resolution factor:"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_REAL(shp->dlg); + shp->rres = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINVAL(shp->dlg, 0.1); + RND_DAD_MAXVAL(shp->dlg, 5); + RND_DAD_DEFAULT_NUM(shp->dlg, 1); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, "Rotation angle:"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_REAL(shp->dlg); + shp->rrot = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINVAL(shp->dlg, -360); + RND_DAD_MAXVAL(shp->dlg, 360); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_LABEL(shp->dlg, "deg"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, "Center offset"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->rcx = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_LABEL(shp->dlg, "x (horizontal)"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, ""); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->rcy = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_LABEL(shp->dlg, "y (vertical)"); + RND_DAD_END(shp->dlg); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, "Corner style:"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_BEGIN_TABLE(shp->dlg, 2); + RND_DAD_ENUM(shp->dlg, pcb_shape_corner_name); + shp->corner[0] = RND_DAD_CURRENT(shp->dlg); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_ENUM(shp->dlg, pcb_shape_corner_name); + shp->corner[1] = RND_DAD_CURRENT(shp->dlg); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_ENUM(shp->dlg, pcb_shape_corner_name); + shp->corner[2] = RND_DAD_CURRENT(shp->dlg); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_ENUM(shp->dlg, pcb_shape_corner_name); + shp->corner[3] = RND_DAD_CURRENT(shp->dlg); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_roundrect); + RND_DAD_END(shp->dlg); + RND_DAD_END(shp->dlg); + RND_DAD_END(shp->dlg); + + /* circle tab */ + RND_DAD_BEGIN_VBOX(shp->dlg); + RND_DAD_LABEL(shp->dlg, "Generate filled circle"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_LABEL(shp->dlg, "Diameter:"); + RND_DAD_COORD(shp->dlg); + shp->dia = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_DEFAULT_NUM(shp->dlg, mm2); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_circle); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, "Center offset"); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->ccx = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_circle); + RND_DAD_LABEL(shp->dlg, "x (horizontal)"); + RND_DAD_END(shp->dlg); + + RND_DAD_LABEL(shp->dlg, ""); + RND_DAD_BEGIN_HBOX(shp->dlg); + RND_DAD_COORD(shp->dlg); + shp->ccy = RND_DAD_CURRENT(shp->dlg); + RND_DAD_MINMAX(shp->dlg, 0, maxr); + RND_DAD_CHANGE_CB(shp->dlg, shp_chg_circle); + RND_DAD_LABEL(shp->dlg, "y (vertical)"); + RND_DAD_END(shp->dlg); + RND_DAD_END(shp->dlg); + RND_DAD_END(shp->dlg); + RND_DAD_BUTTON_CLOSES(shp->dlg, clbtn); + RND_DAD_END(shp->dlg); + + RND_DAD_NEW("shape", shp->dlg, "dlg_shape", shp, modal, shp_close_cb); + RND_DAD_SET_VALUE(shp->dlg_hid_ctx, shp->dia, crd, RND_MM_TO_COORD(25.4)); /* suppress a runtime warning on invalid dia (zero) */ + shp_chg_circle(shp->dlg_hid_ctx, shp, NULL); + shp_chg_roundrect(shp->dlg_hid_ctx, shp, NULL); + shp_chg_regpoly(shp->dlg_hid_ctx, shp, NULL); /* has to be the last */ + if (modal) { + RND_DAD_RUN(shp->dlg); + RND_DAD_FREE(shp->dlg); + } + else + shape_active = shp; +} + + +static const char pcb_acts_shape[] = "shape()"; +static const char pcb_acth_shape[] = "Interactive shape generator."; +fgw_error_t pcb_act_shape(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + pcb_shape_dialog(PCB, PCB_PASTEBUFFER->Data, pcb_shape_current_layer, rnd_false); + RND_ACT_IRES(0); + return 0; +} + Index: tags/2.3.0/src_plugins/sketch_route/Makefile =================================================================== --- tags/2.3.0/src_plugins/sketch_route/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_sketch_route + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/sketch_route/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/sketch_route/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/Plug.tmpasm (revision 33253) @@ -0,0 +1,19 @@ +put /local/pcb/mod {sketch_route} +append /local/pcb/mod/OBJS [@ + $(PLUGDIR)/sketch_route/sketch_route.o + $(PLUGDIR)/sketch_route/wire.o + $(PLUGDIR)/sketch_route/ewire.o + $(PLUGDIR)/sketch_route/ewire_point.o + $(PLUGDIR)/sketch_route/spoke.o + $(PLUGDIR)/sketch_route/pointdata.o + $(SRC_3RD_DIR)/libcdtr/cdt.o + $(SRC_3RD_DIR)/libcdtr/edge.o + $(SRC_3RD_DIR)/libcdtr/point.o + $(SRC_3RD_DIR)/libcdtr/triangle.o +@] + +switch /local/pcb/sketch_route/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/sketch_route/ewire.c =================================================================== --- tags/2.3.0/src_plugins/sketch_route/ewire.c (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/ewire.c (revision 33253) @@ -0,0 +1,71 @@ +#include + +#define GVT_DONT_UNDEF +#include "ewire.h" + +void ewire_init(ewire_t *ew) +{ + vtewire_point_init(&ew->points); +} + +void ewire_uninit(ewire_t *ew) +{ + vtewire_point_uninit(&ew->points); +} + +void ewire_append_point(ewire_t *ew, spoke_t *sp, side_t side, int sp_slot, wirelist_node_t *w_node) +{ + ewire_insert_point(ew, ew->points.used-1, sp, side, sp_slot, w_node); +} + +void ewire_insert_point(ewire_t *ew, int after_i, spoke_t *sp, side_t side, int sp_slot, wirelist_node_t *w_node) +{ + ewire_point_t *ewp = vtewire_point_alloc_append(&ew->points, 1); + ewp->sp = sp; + ewp->side = side; + ewp->sp_slot = sp_slot; + ewp->w_node = w_node; +} + +void ewire_remove_point(ewire_t *ew, int i) +{ + vtewire_point_remove(&ew->points, i, 1); +} + +ewire_point_t *ewire_get_point(ewire_t *ew, int i) +{ + assert(i < vtewire_point_len(&ew->points)); + return &ew->points.array[i]; +} + +ewire_point_t *ewire_get_point_at_slot(ewire_t *ew, spoke_t *sp, int slot_num) +{ + int i; + for (i = 0; i < vtewire_point_len(&ew->points); i++) { + if (ew->points.array[i].sp == sp && ew->points.array[i].sp_slot == slot_num) + return &ew->points.array[i]; + } + return NULL; +} + +size_t ewire_length(ewire_t *ew) +{ + return vtewire_point_len(&ew->points); +} + +int GVT(constructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem) +{ + *elem = malloc(sizeof(**elem)); + if (*elem == NULL) + return 1; + ewire_init(*elem); + return 0; +} + +void GVT(destructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem) +{ + ewire_uninit(*elem); + free(*elem); +} + +#include Index: tags/2.3.0/src_plugins/sketch_route/ewire.h =================================================================== --- tags/2.3.0/src_plugins/sketch_route/ewire.h (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/ewire.h (revision 33253) @@ -0,0 +1,64 @@ +#ifndef EWIRE_H +#define EWIRE_H + +#include +#include + +#include "config.h" +#include "sktypedefs.h" +#ifdef GVT_DONT_UNDEF + #undef GVT_DONT_UNDEF + #include "ewire_point.h" + #define GVT_DONT_UNDEF +#else + #include "ewire_point.h" +#endif + +typedef struct { + vtewire_point_t points; + wire_t *wire; +} ewire_t; + +typedef ewire_t* ewire_ptr_t; + +void ewire_init(ewire_t *ew); +void ewire_uninit(ewire_t *ew); +void ewire_append_point(ewire_t *ew, spoke_t *sp, side_t side, int sp_slot, wirelist_node_t *w_node); +void ewire_insert_point(ewire_t *ew, int after_i, spoke_t *sp, side_t side, int sp_slot, wirelist_node_t *w_node); +void ewire_remove_point(ewire_t *ew, int i); + +ewire_point_t *ewire_get_point(ewire_t *ew, int i); +ewire_point_t *ewire_get_point_at_slot(ewire_t *ew, spoke_t *sp, int slot_num); + +size_t ewire_length(ewire_t *ew); + + +/* ewire ptr Vector */ +#define GVT(x) vtewire_ ## x +#define GVT_ELEM_TYPE ewire_ptr_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 +#define GVT_ELEM_CONSTRUCTOR +#define GVT_ELEM_DESTRUCTOR +#define GVT_ELEM_COPY + +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +int GVT(constructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem); +void GVT(destructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem); +#include + +#define VTEWIRE_FOREACH(_loop_item_, _vt_) do { \ + int _i_; \ + for (_i_ = 0; _i_ < vtewire_len(_vt_); _i_++) { \ + ewire_t *_loop_item_ = (_vt_)->array[_i_]; + +#define VTEWIRE_FOREACH_END() \ + } \ +} while(0) + +#endif Index: tags/2.3.0/src_plugins/sketch_route/ewire_point.c =================================================================== --- tags/2.3.0/src_plugins/sketch_route/ewire_point.c (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/ewire_point.c (revision 33253) @@ -0,0 +1,4 @@ +#define GVT_DONT_UNDEF +#include "ewire_point.h" + +#include Index: tags/2.3.0/src_plugins/sketch_route/ewire_point.h =================================================================== --- tags/2.3.0/src_plugins/sketch_route/ewire_point.h (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/ewire_point.h (revision 33253) @@ -0,0 +1,40 @@ +#ifndef EWIRE_POINT_H +#define EWIRE_POINT_H + +#include +#include + +#include "sktypedefs.h" + +typedef struct{ + spoke_t *sp; /* set this to cdt point in case of terminal (side = SIDE_TERM) */ + side_t side; + int sp_slot; + wirelist_node_t *w_node; +} ewire_point_t; + + +/* ewire_point Vector */ +#define GVT(x) vtewire_point_ ## x +#define GVT_ELEM_TYPE ewire_point_t +#define GVT_SIZE_TYPE size_t +#define GVT_DOUBLING_THRS 256 +#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 + +#define VTEWIRE_POINT_FOREACH(_loop_item_, _vt_) do { \ + int _i_; \ + for (_i_ = 0; _i_ < vtewire_point_len(_vt_); _i_++) { \ + ewire_point_t *_loop_item_ = &(_vt_)->array[_i_]; + +#define VTEWIRE_POINT_FOREACH_END() \ + } \ +} while(0) + +#endif Index: tags/2.3.0/src_plugins/sketch_route/pointdata.c =================================================================== --- tags/2.3.0/src_plugins/sketch_route/pointdata.c (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/pointdata.c (revision 33253) @@ -0,0 +1,33 @@ +#include +#include "pointdata.h" +#include "wire.h" + +void pointdata_create(point_t *p, pcb_any_obj_t *obj) +{ + pointdata_t *pd; + int i; + + assert(p->data == NULL); + p->data = calloc(1, sizeof(pointdata_t)); + pd = p->data; + pd->obj = obj; + + for (i = 0; i < 4; i++) + spoke_init(&pd->spoke[i], i, p); +} + +void pointdata_free(point_t *p) +{ + pointdata_t *pd = p->data; + int i; + + if (pd != NULL) { + wirelist_free(pd->terminal_wires); + wirelist_free(pd->uturn_wires); + wirelist_free(pd->attached_wires[0]); + wirelist_free(pd->attached_wires[1]); + for (i = 0; i < 4; i++) + spoke_uninit(&pd->spoke[i]); + free(pd); + } +} Index: tags/2.3.0/src_plugins/sketch_route/pointdata.h =================================================================== --- tags/2.3.0/src_plugins/sketch_route/pointdata.h (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/pointdata.h (revision 33253) @@ -0,0 +1,24 @@ +#ifndef POINTDATA_H +#define POINTDATA_H + +#include "sktypedefs.h" +#include "spoke.h" + +struct pointdata_s { + pcb_any_obj_t *obj; + /* these wirelists are ordered outside-to-inside */ + /* two lists are used in corner case: when two subsequent wire segments are collinear and + * wires are attached both on the left and on the right side of the point */ + /* uturn wirelist is used when a wire turns back at a point */ + wirelist_node_t *attached_wires[2]; + wirelist_node_t *uturn_wires; + wirelist_node_t *terminal_wires; + /* spokes provide sufficient spacing of wires from objects; + * there are 4 spokes for each of the directions: 45, 135, 225, 315 deg */ + spoke_t spoke[4]; +}; + +void pointdata_create(point_t *p, pcb_any_obj_t *obj); +void pointdata_free(point_t *p); + +#endif Index: tags/2.3.0/src_plugins/sketch_route/sketch_route.c =================================================================== --- tags/2.3.0/src_plugins/sketch_route/sketch_route.c (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/sketch_route.c (revision 33253) @@ -0,0 +1,1199 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2018 Wojciech Krutnik + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* Literature: + * [1] C E Leiserson and F M Maley. 1985. Algorithms for routing and testing routability of planar VLSI layouts. + * In Proceedings of the seventeenth annual ACM symposium on Theory of computing (STOC '85). + * ACM, New York, NY, USA, 69-78. DOI=http://dx.doi.org/10.1145/22145.22153 + */ + +#include "config.h" + +#include +#include +#include "board.h" +#include "conf_core.h" +#include "data.h" +#include "event.h" +#include "list_common.h" +#include "obj_line_list.h" +#include "obj_pstk.h" +#include "obj_pstk_inlines.h" +#include "obj_subc_parent.h" +#include +#include "search.h" +#include +#include "layer_ui.h" +#include "netlist.h" + +#include "sktypedefs.h" +#include "wire.h" +#include "ewire.h" +#include "ewire_point.h" +#include "pointdata.h" +#include "spoke.h" +#include +#include +#include +#include + +#define SK_DEBUG + + +const char *pcb_sketch_route_cookie = "sketch_route plugin"; + + +typedef struct { + cdt_t *cdt; + htpp_t terminals; /* key - terminal object; value - cdt point */ + vtwire_t wires; + vtewire_t ewires; + rnd_rtree_t *spoke_tree; + pcb_layer_t *ui_layer_cdt; + pcb_layer_t *ui_layer_erbs; +} sketch_t; + +static htip_t sketches; +static rnd_bool_t show_spokes = rnd_true; /* TODO: make this a config node */ +static rnd_bool_t check_net = rnd_false; /* TODO: make this a config node */ + + +static point_t *sketch_get_point_at_terminal(sketch_t *sk, pcb_any_obj_t *term) +{ + return htpp_getentry(&sk->terminals, term)->value; +} + +static void sketch_update_cdt_layer(sketch_t *sk) +{ + pcb_layer_t *l = sk->ui_layer_cdt; + + list_map0(&l->Line, pcb_line_t, pcb_line_free); + if (l->line_tree) + rnd_r_destroy_tree(&l->line_tree); + VTEDGE_FOREACH(e, &sk->cdt->edges) + pcb_line_new(l, e->endp[0]->pos.x, -e->endp[0]->pos.y, e->endp[1]->pos.x, -e->endp[1]->pos.y, 1, 0, pcb_no_flags()); + VTEDGE_FOREACH_END(); +} + +static void sketch_update_erbs_layer(sketch_t *sk) +{ + pcb_layer_t *l = sk->ui_layer_erbs; + rnd_coord_t px, py, qx, qy; + int i; + + list_map0(&l->Line, pcb_line_t, pcb_line_free); + if (l->line_tree) + rnd_r_destroy_tree(&l->line_tree); + + VTEWIRE_FOREACH(ew, &sk->ewires) + ewire_point_t *ewp = &ew->points.array[0]; + px = ((point_t *)ewp->sp)->pos.x; + py = -((point_t *)ewp->sp)->pos.y; + for (i = 1; i < vtewire_point_len(&ew->points) - 1; i++) { + ewp = &ew->points.array[i]; + spoke_pos_at_slot(ewp->sp, ewp->sp_slot, &qx, &qy); + pcb_line_new(l, px, py, qx, qy, ew->wire->thickness, ew->wire->clearance, pcb_no_flags()); + px = qx; + py = qy; + } + ewp = &ew->points.array[i]; + qx = ((point_t *)ewp->sp)->pos.x; + qy = -((point_t *)ewp->sp)->pos.y; + pcb_line_new(l, px, py, qx, qy, ew->wire->thickness, ew->wire->clearance, pcb_no_flags()); + VTEWIRE_FOREACH_END(); + + if (show_spokes) { + VTPOINT_FOREACH(p, &sk->cdt->points) + pointdata_t *pd = p->data; + if (pd != NULL) { + px = p->pos.x; + py = -p->pos.y; + for (i = 0; i < 4; i++) { + spoke_pos_at_end(&pd->spoke[i], 0, &qx, &qy); + pcb_line_new(l, px, py, qx, qy, 1, 0, pcb_no_flags()); + } + } + VTPOINT_FOREACH_END(); + } +} + +static void sketch_validate_erbs(sketch_t *sk, ewire_t *ew) +{ + /* TODO: check ew spokes against not supported ewires conflicts */ + /* TODO: check ewires segments, supported by ew spokes, against other spokes conflicts */ +} + +static ewire_t *sketch_insert_ewire(sketch_t *sk, wire_t *w) +{ + int i, j; + ewire_t *new_ew; + + new_ew = *vtewire_alloc_append(&sk->ewires, 1); + new_ew->wire = w; + ewire_append_point(new_ew, (spoke_t *) w->points[0].p, SIDE_TERM, 0, w->points[0].wire_node); + +#ifdef SK_DEBUG + printf("\ninserting ERBS wire:\n"); +#endif + + if (w->point_num == 2) { + ewire_append_point(new_ew, (spoke_t *) w->points[1].p, SIDE_TERM, 0, w->points[1].wire_node); + return new_ew; + } + else { + spoke_t *curr_sp, *next_sp; + point_t prev_p, curr_p, next_p; + + for (i = 0; i < w->point_num-1; i++) { + wire_point_t *curr_wp = &w->points[i]; + wire_point_t *next_wp = &w->points[i+1]; + pointdata_t *curr_pd = (pointdata_t *) curr_wp->p->data; + pointdata_t *next_pd = (pointdata_t *) next_wp->p->data; + int curr_sp_slot_num = wire_point_position(curr_wp); + point_t curr_sp_p[4], next_sp_p[4]; + int repeat_cnt; + +#ifdef SK_DEBUG + rnd_printf(" wire point %d at (%mm, %mm); ", i, curr_wp->p->pos.x, -curr_wp->p->pos.y); +#endif + + for (j = 0; j < 4; j++) { + spoke_pos_at_wire_point(&curr_pd->spoke[j], curr_wp, &curr_sp_p[j].pos.x, &curr_sp_p[j].pos.y); + curr_sp_p[j].pos.y = -curr_sp_p[j].pos.y; + spoke_pos_at_wire_point(&next_pd->spoke[j], next_wp, &next_sp_p[j].pos.x, &next_sp_p[j].pos.y); + next_sp_p[j].pos.y = -next_sp_p[j].pos.y; + } + + if (i == 0) + curr_p = *curr_wp->p; + if (i == w->point_num-2) + next_p = *next_wp->p; + + repeat_cnt = 0; +repeat_current_point: + + /* 1. find destination spoke */ + if (i < w->point_num-2) { /* start terminal - spoke, or spoke - spoke */ + point_t *p; + spoke_dir_t next_sp_dir; + + /* select the leftmost spoke, if point is on the right and vice-versa */ + p = &next_sp_p[0]; + next_sp_dir = 0; + for (j = 1; j < 4; j++) { + if (ORIENT(next_wp->side == SIDE_LEFT, &curr_p, p, &next_sp_p[j])) { + p = &next_sp_p[j]; + next_sp_dir = j; + } + /* check collinear case and select the closer spoke */ + if (ORIENT_COLLINEAR(&curr_p, p, &next_sp_p[j])) { + next_sp_dir = DIST2(&curr_p, p) < DIST2(&curr_p, &next_sp_p[j]) ? next_sp_dir : j; + p = &next_sp_p[next_sp_dir]; + } + } + next_sp = &next_pd->spoke[next_sp_dir]; + next_p = next_sp_p[next_sp_dir]; + } + +#ifdef SK_DEBUG + rnd_printf("dest spoke (dir %d) at (%mm, %mm); ", next_sp->dir, next_p.pos.x, -next_p.pos.y); +#endif + + /* 2. check if the ewire should be attached to any of the remaining spokes at the current point */ + if (i > 0) { /* spoke - spoke, or spoke - end terminal */ + point_t *p; + spoke_dir_t curr_sp_dir; + + /* if point is on the left, select the rightmost spoke (if there is any) and vice-versa */ + p = NULL; + for (j = 0; j < 4; j++) { + if (j == curr_sp->dir) + continue; + if (p == NULL) { + if(ORIENT(curr_wp->side == SIDE_LEFT, &curr_p, &next_p, &curr_sp_p[j])) { + p = &curr_sp_p[j]; + curr_sp_dir = j; + } + } + else { + if(ORIENT(curr_wp->side == SIDE_LEFT, &curr_p, p, &curr_sp_p[j])) { + p = &curr_sp_p[j]; + curr_sp_dir = j; + } + } + } + if (p != NULL) { + /* don't attach to the current point's spoke if spoke of the next point is closer */ + if (DIST2(&curr_p, &next_p) < DIST2(&curr_p, p)) { + printf("necessary\n"); /* (not sure if this check is necessary) */ + } + else { + ewire_append_point(new_ew, curr_sp, curr_wp->side, curr_sp_slot_num, curr_wp->wire_node); + spoke_insert_wire_at_slot(curr_sp, curr_sp_slot_num, new_ew); + curr_sp = &curr_pd->spoke[curr_sp_dir]; + prev_p = curr_p; + curr_p = *p; +#ifdef SK_DEBUG + rnd_printf("found obstructing spoke (dir %d) at (%mm, %mm); ", curr_sp->dir, curr_p.pos.x, -curr_p.pos.y); +#endif + if (++repeat_cnt == 4) + break; + goto repeat_current_point; + } + } + } + + /* 3. insert point if two subsequent segments are not concave */ + /* TODO: concavity detection should propagate through the previous points, when one is found; + * maybe it could be done only in sketch_validate_erbs */ + if (i > 0) { + /* if point is on the left, check if the next point is on the right of the previous segment */ + if (!ORIENT(curr_wp->side == SIDE_LEFT, &prev_p, &curr_p, &next_p)) { + ewire_append_point(new_ew, curr_sp, curr_wp->side, curr_sp_slot_num, curr_wp->wire_node); + spoke_insert_wire_at_slot(curr_sp, curr_sp_slot_num, new_ew); + } + else { +#ifdef SK_DEBUG + rnd_printf("found concavity, skip; "); +#endif + } + } + + curr_sp = next_sp; + prev_p = curr_p; + curr_p = next_p; +#ifdef SK_DEBUG + rnd_printf("\n"); +#endif + } + + ewire_append_point(new_ew, (spoke_t *) w->points[w->point_num-1].p, SIDE_TERM, 0, w->points[w->point_num-1].wire_node); + return new_ew; + } +} + +static rnd_bool sketch_check_path(point_t *from_p, edge_t *from_e, edge_t *to_e, point_t *to_p) +{ + /* TODO */ + return rnd_true; +} + +#ifdef SK_DEBUG +static void wire_print(wire_t *w, const char *tab) +{ + int i; + for (i = 0; i < w->point_num; i++) + rnd_printf("%sP%i: (%mm,%mm) %s\n", tab, i, w->points[i].p->pos.x, -w->points[i].p->pos.y, + w->points[i].side == SIDE_LEFT ? "LEFT" : w->points[i].side == SIDE_RIGHT ? "RIGHT" : "TERM"); +} +#endif + +static wire_t *sketch_find_shortest_path(wire_t *corridor) +{ + /* the algorithm is described in [1] */ + static wire_t left; + wire_t right; + int i, b; + + assert(corridor->points[0].side == SIDE_TERM && corridor->points[corridor->point_num-1].side == SIDE_TERM); + + wire_init(&left); + wire_init(&right); + wire_push_point(&left, corridor->points[0].p, SIDE_TERM); + wire_push_point(&right, corridor->points[0].p, SIDE_TERM); + +#ifdef SK_DEBUG + printf("finding path through corridor:\n"); + wire_print(corridor, ""); +#endif + + for (i = 1, b = 1; i < corridor->point_num; i++) { + point_t *p = corridor->points[i].p; + int side = corridor->points[i].side; + +#ifdef SK_DEBUG + printf("\ncorridor point %i\n", i); + printf("left points:\n"); + wire_print(&left, "\t"); + printf("right points:\n"); + wire_print(&right, "\t"); +#endif + + if (side & SIDE_LEFT) { + while (left.point_num > b + && ORIENT_CW(left.points[left.point_num-2].p, left.points[left.point_num-1].p, p)) { + wire_pop_point(&left); +#ifdef SK_DEBUG + printf("\tpop left point\n"); +#endif + } + + while (right.point_num > b + && !ORIENT_CCW(right.points[b-1].p, right.points[b].p, p)) { + wire_push_point(&left, right.points[b].p, right.points[b].side); + b++; +#ifdef SK_DEBUG + printf("\tswitch to right (b=%i)\n", b); +#endif + } + + wire_push_point(&left, p, side); + } + else { + while (right.point_num > b + && ORIENT_CCW(right.points[right.point_num-2].p, right.points[right.point_num-1].p, p)) { + wire_pop_point(&right); +#ifdef SK_DEBUG + printf("\tpop right point\n"); +#endif + } + + while (left.point_num > b + && !ORIENT_CW(left.points[b-1].p, left.points[b].p, p)) { + wire_push_point(&right, left.points[b].p, left.points[b].side); + b++; +#ifdef SK_DEBUG + printf("\tswitch to left (b=%i)\n", b); +#endif + } + + wire_push_point(&right, p, side); + } + } + +#ifdef SK_DEBUG + printf("\npath:\n"); + wire_print(&left, "\t"); +#endif + + wire_uninit(&right); + return &left; +} + +#define check_wires(wlist) do { \ + WIRELIST_FOREACH(w, (wlist)); \ + (void) w; \ + if (wire_is_node_connected_with_point(_node_, wp->p)) \ + n++; \ + WIRELIST_FOREACH_END(); \ +} while(0) + +static int count_all_wires_coming_from_adjacent_point(pointdata_t *adj_pd, wire_point_t *wp) +{ + int n = 0; + check_wires(adj_pd->attached_wires[0]); + check_wires(adj_pd->attached_wires[1]); + check_wires(adj_pd->terminal_wires); + return n; +} + +static int count_wires_coming_from_previous_point(wire_point_t *prev_wp, wire_point_t *wp, int list_num) +{ + wirelist_node_t *prev_list, *prev_list_term, *prev_list_uturn; + int n; + + prev_list = ((pointdata_t *) prev_wp->p->data)->attached_wires[list_num]; + prev_list_term = ((pointdata_t *) prev_wp->p->data)->terminal_wires; + prev_list_uturn = ((pointdata_t *) prev_wp->p->data)->uturn_wires; + + if (prev_wp->side == wp->side) { /* case 1: the wire was on the same side at the previous point */ + n = wirelist_get_index(prev_list, prev_wp->wire_node); + if (n == -1) /* wire was U-turned at the previous point */ + n = wirelist_length(prev_list) + wirelist_get_index(prev_list_uturn, prev_wp->wire_node); + } + else if (prev_wp->side == SIDE_TERM) /* case 2: previous point was a terminal */ + n = wirelist_length(prev_list) + wirelist_length(prev_list_uturn); + else { /* case 3: the wire was on an other side of the previous point */ + int temp; + n = wirelist_length(prev_list); + check_wires(prev_list_uturn); + check_wires(prev_list_term); + temp = wirelist_get_index(prev_list_uturn, prev_wp->wire_node); + if (temp >= 0) /* wire coming from previous U-turn */ + n += (wirelist_length(prev_wp->wire_node) - 1); + else { + check_wires(prev_list_uturn); + n += (wirelist_length(prev_wp->wire_node) - 1); + } + } + return n; +} + +static int count_uturn_wires_coming_from_previous_point(wire_point_t *prev_wp, wire_point_t *wp, int list_num) +{ + wirelist_node_t *list_uturn, *prev_list, *prev_list2, *prev_list_uturn; + wirelist_node_t *prev_outer_node, *curr_outer_node; + int i; + + list_uturn = ((pointdata_t *) wp->p->data)->uturn_wires; + prev_list = ((pointdata_t *) prev_wp->p->data)->attached_wires[list_num]; + prev_list2 = ((pointdata_t *) prev_wp->p->data)->attached_wires[list_num^1]; + prev_list_uturn = ((pointdata_t *) prev_wp->p->data)->uturn_wires; + + if (prev_wp->side == wp->side) { /* case 1: the wire was on the same side at the previous point */ + i = wirelist_get_index(prev_list, prev_wp->wire_node); + assert(i != -1); + if (i == 0) + return 0; + prev_outer_node = wirelist_nth(prev_list, i-1); + i = wire_node_index_at_connected_point(prev_outer_node, wp->p); + assert(i != -1); + curr_outer_node = prev_outer_node->item->points[i].wire_node; + return wirelist_get_index(list_uturn, curr_outer_node) + 1; + } + else { + if (prev_wp->side == SIDE_TERM) { /* case 2: previous point was a terminal */ + prev_outer_node = wirelist_last(prev_list_uturn); + if (prev_outer_node == NULL) { /* no uturn wires at the previous point */ + prev_outer_node = wirelist_last(prev_list); + if (prev_outer_node == NULL) /* no outer wires at the previous point at all */ + return 0; + } + /* TODO: the result of this func can be ambiguous, so this need a deeper consideration + * (connected point in case of uturns is both the previous and the next point) */ + i = wire_node_index_at_connected_point(prev_outer_node, wp->p); + assert(i != -1); + curr_outer_node = prev_outer_node->item->points[i].wire_node; + return wirelist_get_index(list_uturn, curr_outer_node) + 1; + } + else { /* case 3: the wire was on an other side of the previous point */ + prev_outer_node = prev_wp->wire_node->next; + if (prev_outer_node == NULL) { /* no inner wires at the previous point */ + prev_outer_node = wirelist_last(prev_list2); + if (prev_outer_node == NULL) /* no wires at the previous point from the other side */ + return 0; + } + /* TODO: uturn wires from the previous point, that may go to the current point, are _not_ taken into account */ + i = wire_node_index_at_connected_point(prev_outer_node, wp->p); + if(i == -1) + return 0; + curr_outer_node = prev_outer_node->item->points[i].wire_node; + return wirelist_get_index(list_uturn, curr_outer_node) + 1; + } + } +} +#undef check_wires + +static void insert_wire_at_point(wire_point_t *wp, wire_t *w, wirelist_node_t **list, int n) +{ + assert(n >= -1); + if (n == -1) { + *list = wirelist_prepend(*list, &w); + wp->wire_node = *list; + } + else + wp->wire_node = wirelist_insert_after_nth(*list, n, &w); +} + +static wire_t *sketch_insert_wire(sketch_t *sk, wire_t *wire) +{ + wire_t *new_w; + int i; + + new_w = *vtwire_alloc_append(&sk->wires, 1); + wire_copy(new_w, wire); + +#ifdef SK_DEBUG + printf("\ninserting wire into sketch:\n"); +#endif + + assert(new_w->point_num >= 2); + for (i = 0; i < new_w->point_num; i++) { + wire_point_t *wp = &new_w->points[i]; + wire_point_t *prev_wp; + wire_point_t *next_wp; + pointdata_t *pd = wp->p->data; + pointdata_t *prev_pd; + + assert(pd != NULL); + + if (i > 0) { + prev_wp = &new_w->points[i-1]; + prev_pd = prev_wp->p->data; + } + if (i < new_w->point_num - 1) + next_wp = &new_w->points[i+1]; + +#ifdef SK_DEBUG + rnd_printf(" add point at (%mm, %mm); ", wp->p->pos.x, -wp->p->pos.y, + wirelist_length(pd->terminal_wires) - 1); +#endif + + if (i == 0) { /* first point */ + assert(wp->side == SIDE_TERM); + cdt_insert_constrained_edge(sk->cdt, wp->p, next_wp->p); + insert_wire_at_point(wp, new_w, &pd->terminal_wires, -1); +#ifdef SK_DEBUG + rnd_printf("start terminal; %d other wires connected\n", wirelist_length(pd->terminal_wires) - 1); +#endif + } + else if (i == new_w->point_num - 1) { /* last point */ + assert(wp->side == SIDE_TERM); + insert_wire_at_point(wp, new_w, &pd->terminal_wires, -1); +#ifdef SK_DEBUG + rnd_printf("end terminal; %d other wires connected\n", wirelist_length(pd->terminal_wires) - 1); +#endif + } + else { /* middle point */ + assert(wp->side != SIDE_TERM); + + cdt_insert_constrained_edge(sk->cdt, wp->p, next_wp->p); + + if (ORIENT_COLLINEAR(prev_wp->p, wp->p, next_wp->p)) { /* collinear case */ + edge_t *prev_e = get_edge_from_points(prev_wp->p, wp->p); + edge_t *e = get_edge_from_points(wp->p, next_wp->p); + int list_num, n; + + if (prev_e != e) { /* 3 subsequent points collinear */ + assert(prev_e->endp[1] == e->endp[0] || prev_e->endp[0] == e->endp[1]); + list_num = ((prev_e->endp[1] == wp->p) ^ (wp->side == SIDE_RIGHT) ? 1 : 0); + + /* check if there was a wire, already attached to this point, that doesn't go through the same points + * as the new wire and is on the opposite wirelist at this point */ + if (pd->attached_wires[list_num^1] != NULL + && !wire_is_coincident_at_node(pd->attached_wires[list_num^1], prev_wp->p, next_wp->p)) { + assert(pd->attached_wires[list_num] == NULL); + pd->attached_wires[list_num] = pd->attached_wires[list_num^1]; + pd->attached_wires[list_num^1] = NULL; + } + + /* find node to insert the new wire in the attached wirelist: + * - determine index of the last wire attached to the previous point + * before the new wire as n (-1 if no wires attached to the previous point) + * - insert the new wire in the current point's wirelist after n-th position */ + n = -1; + n += count_wires_coming_from_previous_point(prev_wp, wp, list_num); + insert_wire_at_point(wp, new_w, &pd->attached_wires[list_num], n); +#ifdef SK_DEBUG + rnd_printf("collinear; list_num=%d; n=%d; attached pos=%d; attached len=%d\n", list_num, n, + wirelist_length(wp->wire_node)-1, wirelist_length(pd->attached_wires[list_num])); +#endif + } + else { /* U-turn */ + /* this list_num is related to the previous point, not the current one + * (and is not used for selecting list to store the wire; only to determine uturn list index) */ + if (prev_wp->side != SIDE_TERM) { + list_num = ((e->endp[1] == wp->p) ^ (prev_wp->side == SIDE_RIGHT) ? 1 : 0); + list_num = prev_pd->attached_wires[list_num] == NULL ? list_num^1 : list_num; + } + else /* except if previous point was a terminal */ + list_num = ((e->endp[1] == wp->p) ^ (wp->side == SIDE_RIGHT) ? 1 : 0); + + /* find node to insert the new wire in the U-turn wirelist: + * - determine index of the wire in the previous attached wirelist + * - subtract wires from the current attached wirelist; + * the result is the position in current U-turn wirelist */ + n = -1; + n += count_uturn_wires_coming_from_previous_point(prev_wp, wp, list_num); + insert_wire_at_point(wp, new_w, &pd->uturn_wires, n); +#ifdef SK_DEBUG + rnd_printf("uturn; list_num=%d; n=%d; uturn pos=%d; uturn len=%d\n", list_num, n, + wirelist_length(wp->wire_node)-1, wirelist_length(pd->uturn_wires)); +#endif + } + } + else { /* not collinear case */ + int list_num, n; + + list_num = pd->attached_wires[1] != NULL ? 1 : 0; + assert(pd->attached_wires[list_num^1] == NULL); + + /* find node to insert the new wire in the attached wirelist: + * - find point's adjacent edges which have greater angle between subsequent segments + * than the new wire's edge (ie. are placed externally) + * - count wires at all these edges and proper wires at the new wire's edge as n + * - insert the new wire in the current point's wirelist after n-th position */ + n = -1; + EDGELIST_FOREACH(e, wp->p->adj_edges) + point_t *adj_p = EDGE_OTHER_POINT(e, wp->p); + if (e->is_constrained + && (wp->side == SIDE_RIGHT ? ORIENT_CCW(prev_wp->p, wp->p, adj_p) : ORIENT_CW(prev_wp->p, wp->p, adj_p))) { + pointdata_t *adj_pd = adj_p->data; + assert(adj_pd != NULL); + n += count_all_wires_coming_from_adjacent_point(adj_pd, wp); + } + EDGELIST_FOREACH_END(); + n += count_wires_coming_from_previous_point(prev_wp, wp, list_num); + insert_wire_at_point(wp, new_w, &pd->attached_wires[list_num], n); +#ifdef SK_DEBUG + rnd_printf("list_num=%d; n=%d, attached pos=%d; attached len=%d\n", list_num, n, + wirelist_length(wp->wire_node)-1, wirelist_length(pd->attached_wires[list_num])); +#endif + } + } + } + return new_w; +} + +struct search_info { + pcb_layer_t *layer; + sketch_t *sk; +}; + +static rnd_r_dir_t r_search_cb(const rnd_box_t *box, void *cl) +{ + pcb_any_obj_t *obj = (pcb_any_obj_t *) box; + struct search_info *i = (struct search_info *) cl; + point_t *point; + + if (obj->type == PCB_OBJ_PSTK) { + pcb_pstk_t *pstk = (pcb_pstk_t *) obj; + if (pcb_pstk_shape_at(PCB, pstk, i->layer) == NULL) + return RND_R_DIR_NOT_FOUND; + point = cdt_insert_point(i->sk->cdt, pstk->x, -pstk->y); + pointdata_create(point, obj); + } + /* temporary: if a non-padstack obj is _not_ a terminal, then don't triangulate it */ + /* long term (for non-terminal objects): + * - lines should be triangulated on their endpoints and constrained + * - polygons should be triangulated on vertices and edges constrained + * - texts - same as polygons for their bbox + * - arcs - same as polygons for their bbox */ + else if (obj->term != NULL) { + coord_t cx, cy; + pcb_obj_center(obj, &cx, &cy); + point = cdt_insert_point(i->sk->cdt, cx, -cy); + pointdata_create(point, obj); + } + + if (obj->term != NULL) { + pcb_subc_t *subc = pcb_obj_parent_subc(obj); + if (subc != NULL && subc->refdes != NULL) + htpp_insert(&i->sk->terminals, obj, point); + } + + return RND_R_DIR_FOUND_CONTINUE; +} + +static void sketch_create_for_layer(sketch_t *sk, pcb_layer_t *layer) +{ + rnd_box_t bbox; + struct search_info info; + char name[256]; + + sk->cdt = malloc(sizeof(cdt_t)); + cdt_init(sk->cdt, 0, 0, PCB->hidlib.size_x, -PCB->hidlib.size_y); + htpp_init(&sk->terminals, ptrhash, ptrkeyeq); + sk->wires.elem_constructor = vtwire_constructor; + sk->wires.elem_destructor = vtwire_destructor; + sk->wires.elem_copy = NULL; + vtwire_init(&sk->wires); + sk->ewires.elem_constructor = vtewire_constructor; + sk->ewires.elem_destructor = vtewire_destructor; + sk->ewires.elem_copy = NULL; + vtewire_init(&sk->ewires); + + sk->spoke_tree = rnd_r_create_tree(); + + bbox.X1 = 0; bbox.Y1 = 0; bbox.X2 = PCB->hidlib.size_x; bbox.Y2 = PCB->hidlib.size_y; + info.layer = layer; + info.sk = sk; + rnd_r_search(PCB->Data->padstack_tree, &bbox, NULL, r_search_cb, &info, NULL); + rnd_r_search(layer->line_tree, &bbox, NULL, r_search_cb, &info, NULL); + rnd_r_search(layer->text_tree, &bbox, NULL, r_search_cb, &info, NULL); + rnd_r_search(layer->polygon_tree, &bbox, NULL, r_search_cb, &info, NULL); + rnd_r_search(layer->arc_tree, &bbox, NULL, r_search_cb, &info, NULL); + + rnd_snprintf(name, sizeof(name), "%s: CDT", layer->name); + sk->ui_layer_cdt = pcb_uilayer_alloc(pcb_sketch_route_cookie, name, &layer->meta.real.color); + sk->ui_layer_cdt->meta.real.vis = rnd_false; + sketch_update_cdt_layer(sk); + + rnd_snprintf(name, sizeof(name), "%s: ERBS", layer->name); + sk->ui_layer_erbs = pcb_uilayer_alloc(pcb_sketch_route_cookie, name, &layer->meta.real.color); + sketch_update_erbs_layer(sk); + rnd_event(&PCB->hidlib, PCB_EVENT_LAYERS_CHANGED, NULL); +} + +static sketch_t *sketch_alloc() +{ + sketch_t *new_sk; + new_sk = calloc(1, sizeof(sketch_t)); + return new_sk; +} + +static void sketch_uninit(sketch_t *sk) +{ + if (sk->cdt != NULL) { + VTPOINT_FOREACH(p, &sk->cdt->points) + pointdata_free(p); + VTPOINT_FOREACH_END(); + cdt_free(sk->cdt); + free(sk->cdt); + sk->cdt = NULL; + } + vtwire_uninit(&sk->wires); + vtewire_uninit(&sk->ewires); + htpp_uninit(&sk->terminals); + rnd_r_destroy_tree(&sk->spoke_tree); + pcb_uilayer_free(sk->ui_layer_cdt); + pcb_uilayer_free(sk->ui_layer_erbs); +} + + +static sketch_t *sketches_get_sketch_at_layer(pcb_layer_t *layer) +{ + return htip_getentry(&sketches, pcb_layer_id(PCB->Data, layer))->value; +} + +static void sketches_init() +{ + rnd_layer_id_t lid[PCB_MAX_LAYER]; + int i, num; + + num = pcb_layer_list(PCB, PCB_LYT_COPPER, lid, PCB_MAX_LAYER); + htip_init(&sketches, longhash, longkeyeq); + for (i = 0; i < num; i++) { + sketch_t *sk = sketch_alloc(); + sketch_create_for_layer(sk, pcb_get_layer(PCB->Data, lid[i])); + htip_insert(&sketches, lid[i], sk); + } +} + +static void sketches_uninit() +{ + htip_entry_t *e; + + for (e = htip_first(&sketches); e; e = htip_next(&sketches, e)) { + sketch_uninit(e->value); + free(e->value); + htip_delentry(&sketches, e); + } + htip_uninit(&sketches); +} + + +/*** sketch line tool ***/ +static void tool_skline_adjust_attached_objects(rnd_hidlib_t *hl); + +struct { + pcb_any_obj_t *start_term; + pcb_net_t *net; + vtp0_t lines; + point_t *start_p; + edgelist_node_t *visited_edges; + triangle_t *current_t; + wire_t corridor; + sketch_t *sketch; +} attached_path = {0}; + +static pcb_attached_line_t *attached_path_new_line() +{ + pcb_attached_line_t *new_l = calloc(1, sizeof(pcb_attached_line_t)); + vtp0_append(&attached_path.lines, new_l); + return new_l; +} + +static void attached_path_next_line() +{ + int last = vtp0_len(&attached_path.lines) - 1; + pcb_attached_line_t *next_l = attached_path_new_line(); + if (last >= 0) + next_l->Point1 = ((pcb_attached_line_t *) attached_path.lines.array[last])->Point2; + tool_skline_adjust_attached_objects(&PCB->hidlib); +} + +static rnd_bool attached_path_init(pcb_layer_t *layer, pcb_any_obj_t *start_term) +{ + pcb_attached_line_t *start_l; + pcb_net_term_t *term; + + term = pcb_net_find_by_obj(&PCB->netlist[PCB_NETLIST_EDITED], start_term); + + attached_path.sketch = sketches_get_sketch_at_layer(layer); + attached_path.start_term = start_term; + attached_path.net = term != NULL ? term->parent.net : NULL; + if (check_net && attached_path.net == NULL) + return rnd_false; + + vtp0_init(&attached_path.lines); + start_l = attached_path_new_line(); + pcb_obj_center(start_term, &start_l->Point1.X, &start_l->Point1.Y); + tool_skline_adjust_attached_objects(&PCB->hidlib); + + attached_path.start_p = sketch_get_point_at_terminal(attached_path.sketch, start_term); + attached_path.current_t = NULL; + attached_path.visited_edges = NULL; + wire_init(&attached_path.corridor); + wire_push_point(&attached_path.corridor, attached_path.start_p, SIDE_TERM); + + return rnd_true; +} + +static void attached_path_uninit() +{ + int i; + for (i = 0; i < vtp0_len(&attached_path.lines); i++) + free(attached_path.lines.array[i]); + vtp0_uninit(&attached_path.lines); + edgelist_free(attached_path.visited_edges); + attached_path.visited_edges = NULL; + wire_uninit(&attached_path.corridor); +} + +static rnd_bool line_intersects_edge(pcb_attached_line_t *line, edge_t *edge) +{ + point_t p, q; + p.pos.x = line->Point1.X; + p.pos.y = -line->Point1.Y; + q.pos.x = line->Point2.X; + q.pos.y = -line->Point2.Y; + return LINES_INTERSECT(&p, &q, edge->endp[0], edge->endp[1]); +} + +static rnd_bool attached_path_next_point(point_t *end_p) +{ + int last = vtp0_len(&attached_path.lines) - 1; + pcb_attached_line_t *attached_line = attached_path.lines.array[last]; + edge_t *entrance_e = NULL; + wire_t corridor_ops; + int i; + + wire_init(&corridor_ops); +#define RETURN(r) do { \ + wire_uninit(&corridor_ops); \ + return (r); \ +} while (0) + + /* move along the attached line to find intersecting triangles which form a corridor */ + while(1) { + if (attached_path.current_t == NULL) { /* we haven't left the first triangle yet */ + TRIANGLELIST_FOREACH(t, attached_path.start_p->adj_triangles) + for (i = 0; i < 3; i++) + if (t->e[i]->endp[0] != attached_path.start_p && t->e[i]->endp[1] != attached_path.start_p + && t->e[i] != entrance_e && line_intersects_edge(attached_line, t->e[i])) { + if (sketch_check_path(attached_path.start_p, NULL, t->e[i], NULL) == rnd_false) + RETURN(rnd_false); + attached_path.current_t = t->adj_t[i]; + wire_push_point(&corridor_ops, t->p[i], SIDE_RIGHT); + wire_push_point(&corridor_ops, t->p[(i+1)%3], SIDE_LEFT); + entrance_e = t->e[i]; + attached_path.visited_edges = edgelist_prepend(attached_path.visited_edges, &entrance_e); + goto next_triangle; + } + TRIANGLELIST_FOREACH_END(); + } + else { /* next triangle in the corridor */ + triangle_t *t = attached_path.current_t; + for (i = 0; i < 3; i++) { + if (t->e[i] != entrance_e && line_intersects_edge(attached_line, t->e[i])) { + edge_t *last_entrance_e = attached_path.visited_edges->item; + entrance_e = t->e[i]; + attached_path.current_t = t->adj_t[i]; + if (t->e[i] != last_entrance_e) { /* going forward */ + if (sketch_check_path(NULL, attached_path.visited_edges->item, t->e[i], NULL) == rnd_false) + RETURN(rnd_false); + wire_push_point(&corridor_ops, + t->p[t->e[(i+2)%3] == last_entrance_e ? (i+1)%3 : i], + t->e[(i+1)%3] == last_entrance_e ? SIDE_RIGHT : SIDE_LEFT); + attached_path.visited_edges = edgelist_prepend(attached_path.visited_edges, &entrance_e); + goto next_triangle; + } + else { /* going backward */ + attached_path.visited_edges = edgelist_remove_front(attached_path.visited_edges); + wire_push_point(&corridor_ops, NULL, 0); /* NULL means to remove point */ + if (attached_path.visited_edges == NULL) { /* came back to the first triangle */ + wire_push_point(&corridor_ops, NULL, 0); + attached_path.current_t = NULL; + } + goto next_triangle; + } + } + } + } + break; +next_triangle: + continue; + } + + if (end_p != NULL) { /* connecting to the last point? */ + if (attached_path.visited_edges == NULL) { + if (sketch_check_path(attached_path.start_p, NULL, NULL, end_p) == rnd_false) + RETURN(rnd_false); + } + else if (sketch_check_path(NULL, attached_path.visited_edges->item, NULL, end_p) == rnd_false) + RETURN(rnd_false); + wire_push_point(&corridor_ops, end_p, SIDE_TERM); + } + + /* apply evaluated points additions/removals */ + for (i = 0; i < corridor_ops.point_num; i++) { + if (corridor_ops.points[i].p != NULL) + wire_push_point(&attached_path.corridor, corridor_ops.points[i].p, corridor_ops.points[i].side); + else + wire_pop_point(&attached_path.corridor); + } + + /* remove unwanted points which could be encountered around the end point */ + if (end_p != NULL) { + int i, n = 0; + wire_pop_point(&attached_path.corridor); /* temporarily remove the end point */ + EDGELIST_FOREACH(e, attached_path.visited_edges) + if (e->endp[0] == end_p || e->endp[1] == end_p) + n++; else break; + EDGELIST_FOREACH_END(); + for (i = 0; i < n; i++) + wire_pop_point(&attached_path.corridor); + if (attached_path.corridor.points[attached_path.corridor.point_num - 1].p == end_p) + wire_pop_point(&attached_path.corridor); + wire_push_point(&attached_path.corridor, end_p, SIDE_TERM); + } + + attached_path_next_line(); + return rnd_true; +#undef RETURN +} + +static rnd_bool attached_path_finish(pcb_any_obj_t *end_term) +{ + rnd_bool net_valid = rnd_false; + + if (check_net) { + if(end_term != attached_path.start_term) { + if (pcb_net_term_get_by_obj(attached_path.net, end_term) != NULL) + net_valid = rnd_true; + } + } + else + net_valid = rnd_true; + + if (net_valid) { + point_t *end_p; + wire_t *path, *new_wire; + + end_p = sketch_get_point_at_terminal(attached_path.sketch, end_term); + if (attached_path_next_point(end_p) == rnd_false) + return rnd_false; + + path = sketch_find_shortest_path(&attached_path.corridor); + path->thickness = conf_core.design.line_thickness; + path->clearance = conf_core.design.clearance; + new_wire = sketch_insert_wire(attached_path.sketch, path); + sketch_insert_ewire(attached_path.sketch, new_wire); + sketch_update_cdt_layer(attached_path.sketch); + sketch_update_erbs_layer(attached_path.sketch); + wire_uninit(path); + return rnd_true; + } + + return rnd_false; +} + +static void tool_skline_init(void) +{ + if (htip_length(&sketches) == 0) + sketches_init(); +} + +static void tool_skline_uninit(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + attached_path_uninit(); + pcb_crosshair_attached_clean(&PCB->hidlib); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +static void tool_skline_notify_mode(rnd_hidlib_t *hl) +{ + int type; + void *ptr1, *ptr2, *ptr3; + pcb_any_obj_t *term_obj; + + switch (pcb_crosshair.AttachedObject.State) { + case PCB_CH_STATE_FIRST: + type = pcb_search_screen(hl->tool_x, hl->tool_y, PCB_OBJ_CLASS_TERM, &ptr1, &ptr2, &ptr3); + /* TODO: check if an object is on the current layer */ + if (type != PCB_OBJ_VOID) { + term_obj = ptr2; + if (term_obj->term != NULL + && ((type == PCB_OBJ_PSTK && pcb_pstk_shape_at(PCB, (pcb_pstk_t *) term_obj, PCB_CURRLAYER(PCB)) != NULL) + || type != PCB_OBJ_PSTK) + && attached_path_init(PCB_CURRLAYER(PCB), term_obj)) { + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_LINE; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_SECOND; + } + else + rnd_message(RND_MSG_WARNING, "Sketch lines can be only drawn from a terminal\n"); + } + break; + + case PCB_CH_STATE_SECOND: + type = pcb_search_screen(hl->tool_x, hl->tool_y, PCB_OBJ_CLASS_TERM, &ptr1, &ptr2, &ptr3); + /* TODO: check if an object is on the current layer */ + if (type != PCB_OBJ_VOID) { + term_obj = ptr2; + if (term_obj->term != NULL + && ((type == PCB_OBJ_PSTK && pcb_pstk_shape_at(PCB, (pcb_pstk_t *) term_obj, PCB_CURRLAYER(PCB)) != NULL) + || type != PCB_OBJ_PSTK)) { + if (attached_path_finish(term_obj) == rnd_true) { + attached_path_uninit(); + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + } else { + rnd_message(RND_MSG_WARNING, "Cannot finish placing wire at this terminal\n"); + rnd_message(RND_MSG_WARNING, "(the terminal does not belong to the routed net or is the starting terminal)\n"); + } + break; + } + } + if (attached_path_next_point(NULL) == rnd_false) + rnd_message(RND_MSG_WARNING, "Cannot route the wire this way\n"); + + break; + } +} + +static void tool_skline_adjust_attached_objects(rnd_hidlib_t *hl) +{ + int last = vtp0_len(&attached_path.lines) - 1; + if (last >= 0) { + ((pcb_attached_line_t *) attached_path.lines.array[last])->Point2.X = pcb_crosshair.X; + ((pcb_attached_line_t *) attached_path.lines.array[last])->Point2.Y = pcb_crosshair.Y; + } +} + +static void tool_skline_draw_attached(rnd_hidlib_t *hl) +{ + int i; + if (pcb_crosshair.AttachedObject.Type != PCB_OBJ_VOID) { + for (i = 0; i < vtp0_len(&attached_path.lines); i++) { + rnd_point_t *p1 = &((pcb_attached_line_t *) attached_path.lines.array[i])->Point1; + rnd_point_t *p2 = &((pcb_attached_line_t *) attached_path.lines.array[i])->Point2; + rnd_render->draw_line(pcb_crosshair.GC, p1->X, p1->Y, p2->X, p2->Y); + } + } +} + +rnd_bool tool_skline_undo_act(rnd_hidlib_t *hl) +{ + /* TODO */ + return rnd_false; +} + +/* XPM */ +static const char *skroute_xpm[] = { +"21 21 3 1", +" c None", +". c #000000", +"+ c #6EA5D7", +" ", +" ", +" + + ", +" +........+ ", +" .+ +. ", +" . .+ ", +" . +.+", +" . + ", +" . ", +" +. ", +" +.+ ", +" + ", +" ... . . ... .....", +". . . . . . . ", +". . . . . . ", +" .. . . ... . ", +" .. .. . . . ", +" . . . . . . ", +". . . . . . . ", +" ... . . . . . ", +" "}; + +static rnd_tool_t tool_skline = { + "skline", "convert a free-hand sketch of a route to traces", + NULL, 100, skroute_xpm, RND_TOOL_CURSOR_NAMED(NULL), RND_TLF_AUTO_TOOLBAR, + tool_skline_init, + tool_skline_uninit, + tool_skline_notify_mode, + NULL, + tool_skline_adjust_attached_objects, + tool_skline_draw_attached, + tool_skline_undo_act, + NULL, + NULL, /* escape */ + + rnd_false +}; + + +/*** actions ***/ +static const char pcb_acts_skretriangulate[] = "skretriangulate()"; +static const char pcb_acth_skretriangulate[] = "Reconstruct CDT on all layer groups"; +fgw_error_t pcb_act_skretriangulate(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + sketches_uninit(); + sketches_init(); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_skline[] = "skline()"; +static const char pcb_acth_skline[] = "Tool for drawing sketch lines"; +fgw_error_t pcb_act_skline(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_tool_select_by_name(&PCB->hidlib, "skline"); + + RND_ACT_IRES(0); + return 0; +} + +static const char pcb_acts_sktransform[] = "sktransform(rect|oct|alldir)"; +static const char pcb_acth_sktransform[] = "Transform sketch to geometrical wiring"; +fgw_error_t pcb_act_sktransform(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + /* TODO */ + RND_ACT_IRES(0); + return 0; +} + +rnd_action_t sketch_route_action_list[] = { + {"skretriangulate", pcb_act_skretriangulate, pcb_acth_skretriangulate, pcb_acts_skretriangulate}, + {"skline", pcb_act_skline, pcb_acth_skline, pcb_acts_skline}, + {"sktransform", pcb_act_sktransform, pcb_acth_sktransform, pcb_acts_sktransform} +}; + +int pplg_check_ver_sketch_route(int ver_needed) { return 0; } + +void pplg_uninit_sketch_route(void) +{ + rnd_remove_actions_by_cookie(pcb_sketch_route_cookie); + rnd_tool_unreg_by_cookie(pcb_sketch_route_cookie); /* should be done before pcb_tool_uninit, somehow */ + sketches_uninit(); +} + +int pplg_init_sketch_route(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(sketch_route_action_list, pcb_sketch_route_cookie) + + rnd_tool_reg(&tool_skline, pcb_sketch_route_cookie); + + return 0; +} Index: tags/2.3.0/src_plugins/sketch_route/sketch_route.pup =================================================================== --- tags/2.3.0/src_plugins/sketch_route/sketch_route.pup (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/sketch_route.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short assisted semi-auto-routing +$long TODO +$state dead +#$package auto +default disable-all +autoload 1 Index: tags/2.3.0/src_plugins/sketch_route/sktypedefs.h =================================================================== --- tags/2.3.0/src_plugins/sketch_route/sktypedefs.h (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/sktypedefs.h (revision 33253) @@ -0,0 +1,16 @@ +#ifndef SKTYPEDEFS_H +#define SKTYPEDEFS_H + +typedef enum { + SIDE_LEFT = (1<<0), + SIDE_RIGHT = (1<<1), + SIDE_TERM = (1<<1)|(1<<0) +} side_t; + +typedef struct spoke_s spoke_t; +typedef struct pointdata_s pointdata_t; +typedef struct wire_s wire_t; +typedef struct wire_point_s wire_point_t; +typedef struct wirelist_node_s wirelist_node_t; + +#endif Index: tags/2.3.0/src_plugins/sketch_route/spoke.c =================================================================== --- tags/2.3.0/src_plugins/sketch_route/spoke.c (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/spoke.c (revision 33253) @@ -0,0 +1,141 @@ +#include "config.h" +#include "conf_core.h" + +#include "spoke.h" +#include "pointdata.h" +#include "wire.h" + + +void spoke_init(spoke_t *sp, spoke_dir_t dir, point_t *p) +{ + vtp0_init(&sp->slots); + sp->dir = dir; + sp->p = p; + /* TODO: + spoke_bbox(sp); + rnd_r_insert_entry(spoke_tree, sp); + */ +} + +void spoke_uninit(spoke_t *sp) +{ + /* TODO: + rnd_r_delete_entry(spoke_tree, &pd->spokes[i]); + */ + vtp0_uninit(&sp->slots); +} + +static void spoke_pos(spoke_t *sp, rnd_coord_t spacing, rnd_coord_t *x, rnd_coord_t *y) +{ + rnd_box_t *obj_bbox = &((pointdata_t *) sp->p->data)->obj->bbox_naked; + rnd_coord_t half_obj_w, half_obj_h; + + half_obj_w = (obj_bbox->X2 - obj_bbox->X1 + 1) / 2; + half_obj_h = (obj_bbox->Y2 - obj_bbox->Y1 + 1) / 2; + + switch(sp->dir) { + case SPOKE_DIR_1PI4: + *x = sp->p->pos.x + half_obj_w + spacing; + *y = (-sp->p->pos.y) - half_obj_h - spacing; + break; + case SPOKE_DIR_3PI4: + *x = sp->p->pos.x - half_obj_w - spacing; + *y = (-sp->p->pos.y) - half_obj_h - spacing; + break; + case SPOKE_DIR_5PI4: + *x = sp->p->pos.x - half_obj_w - spacing; + *y = (-sp->p->pos.y) + half_obj_h + spacing; + break; + case SPOKE_DIR_7PI4: + *x = sp->p->pos.x + half_obj_w + spacing; + *y = (-sp->p->pos.y) + half_obj_h + spacing; + break; + } +} + +void spoke_pos_at_wire_point(spoke_t *sp, wire_point_t *wp, rnd_coord_t *x, rnd_coord_t *y) +{ + pointdata_t *pd = wp->p->data; + wirelist_node_t *w_node = wp->wire_node; + rnd_coord_t spacing; + + assert(w_node != NULL); + + spacing = (w_node->item->thickness + 1)/2; + spacing += conf_core.design.bloat; + w_node = w_node->next; + if (wirelist_get_index(pd->uturn_wires, w_node) != -1) { + WIRELIST_FOREACH(w, wp->wire_node) + spacing += w->thickness; + spacing += conf_core.design.bloat; + WIRELIST_FOREACH_END(); + } + else { + WIRELIST_FOREACH(w, w_node) + spacing += w->thickness; + spacing += conf_core.design.bloat; + WIRELIST_FOREACH_END(); + WIRELIST_FOREACH(w, pd->uturn_wires) + spacing += w->thickness; + spacing += conf_core.design.bloat; + WIRELIST_FOREACH_END(); + } + + spoke_pos(sp, spacing, x, y); +} + +void spoke_pos_at_slot(spoke_t *sp, int slot, rnd_coord_t *x, rnd_coord_t *y) +{ + rnd_coord_t spacing = 0; + int i; + + assert(slot < vtp0_len(&sp->slots)); + + for (i = 0; i < slot; i++) { + spacing += conf_core.design.bloat; + spacing += ((ewire_t *) (sp->slots.array[i]))->wire->thickness; + } + spacing += conf_core.design.bloat; + spacing += (((ewire_t *) (sp->slots.array[slot]))->wire->thickness + 1)/2; + + spoke_pos(sp, spacing, x, y); +} + +void spoke_pos_at_end(spoke_t *sp, rnd_coord_t bloat, rnd_coord_t *x, rnd_coord_t *y) +{ + rnd_coord_t spacing = 0; + int i; + + if (vtp0_len(&sp->slots) > 0) { + for (i = 0; i < vtp0_len(&sp->slots) - 1; i++) { + spacing += conf_core.design.bloat; + spacing += ((ewire_t *) (sp->slots.array[i]))->wire->thickness; + } + if (bloat < 0) + spacing += (((ewire_t *) (sp->slots.array[vtp0_len(&sp->slots) - 1]))->wire->thickness + 1)/2; + else + spacing += ((ewire_t *) (sp->slots.array[vtp0_len(&sp->slots) - 1]))->wire->thickness; + } + + if (bloat >= 0) { + spacing += conf_core.design.bloat; + spacing += bloat; + } + + spoke_pos(sp, spacing, x, y); +} + +void spoke_insert_wire_at_slot(spoke_t *sp, int slot_num, ewire_t *ew) +{ + if (vtp0_in_bound(&sp->slots, slot_num) && sp->slots.array[slot_num] != NULL) { + int i; + /* move all slots, starting from the slot_num, one step outside */ + for (i = slot_num; i < vtp0_len(&sp->slots); i++) { + ewire_point_t *ewp = ewire_get_point_at_slot(sp->slots.array[i], sp, i); + assert(ewp != NULL); + ewp->sp_slot = i + 1; + } + vtp0_alloc_insert(&sp->slots, slot_num, 1); + } + vtp0_set(&sp->slots, slot_num, ew); +} Index: tags/2.3.0/src_plugins/sketch_route/spoke.h =================================================================== --- tags/2.3.0/src_plugins/sketch_route/spoke.h (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/spoke.h (revision 33253) @@ -0,0 +1,36 @@ +#ifndef SPOKE_H +#define SPOKE_H + +#include "sktypedefs.h" +#include "obj_common.h" +#include "ewire.h" +#include + +#include + + +typedef enum { + SPOKE_DIR_1PI4 = 0, + SPOKE_DIR_3PI4 = 1, + SPOKE_DIR_5PI4 = 2, + SPOKE_DIR_7PI4 = 3 +} spoke_dir_t; + +struct spoke_s { + spoke_dir_t dir; + rnd_box_t bbox; + vtp0_t slots; + point_t *p; +}; + + +void spoke_init(spoke_t *sp, spoke_dir_t dir, point_t *p); +void spoke_uninit(spoke_t *sp); + +void spoke_pos_at_wire_point(spoke_t *sp, wire_point_t *wp, rnd_coord_t *x, rnd_coord_t *y); +void spoke_pos_at_slot(spoke_t *sp, int slot, rnd_coord_t *x, rnd_coord_t *y); +void spoke_pos_at_end(spoke_t *sp, rnd_coord_t bloat, rnd_coord_t *x, rnd_coord_t *y); + +void spoke_insert_wire_at_slot(spoke_t *sp, int slot_num, ewire_t *ew); + +#endif Index: tags/2.3.0/src_plugins/sketch_route/wire.c =================================================================== --- tags/2.3.0/src_plugins/sketch_route/wire.c (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/wire.c (revision 33253) @@ -0,0 +1,115 @@ +#include +#include "pointdata.h" + +#define GVT_DONT_UNDEF +#define LST_DONT_UNDEF +#include "wire.h" + +#define WIRE_POINTS_STEP 10 + +void wire_init(wire_t *w) +{ + w->point_num = 0; + w->point_max = WIRE_POINTS_STEP; + w->points = malloc(WIRE_POINTS_STEP*sizeof(wire_point_t)); +} + +void wire_uninit(wire_t *w) +{ + free(w->points); +} + +void wire_push_point(wire_t *w, point_t *p, int side) +{ + w->points[w->point_num].p = p; + w->points[w->point_num].side = side; + if (++w->point_num >= w->point_max) { + w->point_max += WIRE_POINTS_STEP; + w->points = realloc(w->points, w->point_max*sizeof(wire_point_t)); + } +} + +void wire_pop_point(wire_t *w) +{ + if(w->point_num > 0) + w->point_num--; +} + +void wire_copy(wire_t *dst, wire_t *src) +{ + wire_point_t *temp = dst->points; + memcpy(dst, src, sizeof(wire_point_t)); + dst->points = temp; + dst->points = realloc(dst->points, src->point_max*sizeof(wire_point_t)); + memcpy(dst->points, src->points, src->point_num*sizeof(wire_point_t)); +} + +int wire_node_index(wire_t *w, wirelist_node_t *node) +{ + int i; + for (i = 0; i < w->point_num; i++) { + if (w->points[i].wire_node == node) + return i; + } + return -1; +} + +int wire_node_index_at_connected_point(wirelist_node_t *node, point_t *p) +{ + wire_t *w = node->item; + int i = wire_node_index(w, node); + if (i == -1) + return -1; + if (i == 0) + return w->points[1].p == p ? 1 : -1; + if (i == w->point_num - 1) + return w->points[w->point_num - 2].p == p ? (w->point_num - 2) : -1; + return (w->points[i - 1].p == p) ? i - 1 + : (w->points[i + 1].p == p) ? i + 1 : -1; +} + +int wire_is_node_connected_with_point(wirelist_node_t *node, point_t *p) +{ + return wire_node_index_at_connected_point(node, p) != -1; +} + +int wire_is_coincident_at_node(wirelist_node_t *node, point_t *p1, point_t *p2) +{ + wire_t *w = node->item; + int i = wire_node_index(w, node); + assert(i != -1 && i != 0 && i != w->point_num - 1); + return (w->points[i - 1].p == p1 && w->points[i + 1].p == p2) + || (w->points[i + 1].p == p1 && w->points[i - 1].p == p2); +} + +int wire_point_position(wire_point_t *wp) +{ + pointdata_t *pd = wp->p->data; + if (wirelist_get_index(pd->uturn_wires, wp->wire_node) != -1) + return wirelist_length(wp->wire_node) - 1; + else + return wirelist_length(wp->wire_node) + wirelist_length(pd->uturn_wires) - 1; +} + +static int LST(compare_func)(LST_ITEM_T *a, LST_ITEM_T *b) +{ + return *a == *b; +} + +int GVT(constructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem) +{ + *elem = malloc(sizeof(**elem)); + if (*elem == NULL) + return 1; + wire_init(*elem); + return 0; +} + +void GVT(destructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem) +{ + wire_uninit(*elem); + free(*elem); +} + +#include +#include Index: tags/2.3.0/src_plugins/sketch_route/wire.h =================================================================== --- tags/2.3.0/src_plugins/sketch_route/wire.h (nonexistent) +++ tags/2.3.0/src_plugins/sketch_route/wire.h (revision 33253) @@ -0,0 +1,93 @@ +#ifndef WIRE_H +#define WIRE_H + +#include +#include + +#include "config.h" +#include +#include "sktypedefs.h" + + +struct wire_point_s { + point_t *p; + side_t side; + wirelist_node_t *wire_node; +}; + +struct wire_s { + int point_num; + int point_max; + wire_point_t *points; + rnd_coord_t thickness; + rnd_coord_t clearance; +}; + +typedef wire_t* wire_ptr_t; + +void wire_init(wire_t *w); +void wire_uninit(wire_t *w); +void wire_push_point(wire_t *w, point_t *p, int side); +void wire_pop_point(wire_t *w); +void wire_copy(wire_t *dst, wire_t *src); + +int wire_node_index(wire_t *w, wirelist_node_t *node); +int wire_node_index_at_connected_point(wirelist_node_t *node, point_t *p); +int wire_is_node_connected_with_point(wirelist_node_t *node, point_t *p); +int wire_is_coincident_at_node(wirelist_node_t *node, point_t *p1, point_t *p2); +int wire_point_position(wire_point_t *wp); /* counting from the inside */ + + +/* List */ +#define LST(x) wirelist_ ## x +#define LST_ITEM_T wire_ptr_t +#define LST_DONT_TYPEDEF_NODE + +#include + +#ifndef LST_DONT_UNDEF + #undef LST + #undef LST_ITEM_T + #undef LST_DONT_TYPEDEF_NODE +#endif + +#define WIRELIST_FOREACH(_loop_item_, _list_) do { \ + wirelist_node_t *_node_ = _list_; \ + while (_node_ != NULL) { \ + wire_t *_loop_item_ = _node_->item; + +#define WIRELIST_FOREACH_END() \ + _node_ = _node_->next; \ + } \ +} while(0) + + +/* Vector */ +#define GVT(x) vtwire_ ## x +#define GVT_ELEM_TYPE wire_ptr_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 +#define GVT_ELEM_CONSTRUCTOR +#define GVT_ELEM_DESTRUCTOR +#define GVT_ELEM_COPY + +#include +#define GVT_REALLOC(vect, ptr, size) realloc(ptr, size) +#define GVT_FREE(vect, ptr) free(ptr) +int GVT(constructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem); +void GVT(destructor)(GVT(t) *vect, GVT_ELEM_TYPE *elem); +#include + +#define VTWIRE_FOREACH(_loop_item_, _vt_) do { \ + int _i_; \ + for (_i_ = 0; _i_ < vtwire_len(_vt_); _i_++) { \ + wire_t *_loop_item_ = (_vt_)->array[_i_]; + +#define VTWIRE_FOREACH_END() \ + } \ +} while(0) + +#endif Index: tags/2.3.0/src_plugins/smartdisperse/Makefile =================================================================== --- tags/2.3.0/src_plugins/smartdisperse/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/smartdisperse/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_smartdisperse + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/smartdisperse/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/smartdisperse/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/smartdisperse/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {smartdisperse} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/smartdisperse/smartdisperse.o @] + +switch /local/pcb/smartdisperse/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/smartdisperse/smartdisperse.c =================================================================== --- tags/2.3.0/src_plugins/smartdisperse/smartdisperse.c (nonexistent) +++ tags/2.3.0/src_plugins/smartdisperse/smartdisperse.c (revision 33253) @@ -0,0 +1,245 @@ +/* + * Smartdisperse plug-in for PCB. + * + * Copyright (C) 2007 Ben Jackson based on + * teardrops.c by Copyright (C) 2006 DJ Delorie as well + * as the original action.c, and autoplace.c. + * + * Licensed under the terms of the GNU General Public + * License, version 2 or later. + * + * Ported to pcb-rnd by Tibor 'Igor2' Palinkas in 2016. + * Upgraded to subc by Tibor 'Igor2' Palinkas in 2017. + * Upgraded to the new netlist API by Tibor 'Igor2' Palinkas in 2019. + * + */ + +#include +#include + +#include + +#include "config.h" +#include "board.h" +#include "data.h" +#include +#include +#include "undo.h" +#include "netlist.h" +#include +#include "move.h" +#include "draw.h" +#include +#include +#include "obj_subc.h" +#include "obj_subc_parent.h" +#include "obj_term.h" +#include "funchash_core.h" + +#define GAP 10000 +static rnd_coord_t minx; +static rnd_coord_t miny; +static rnd_coord_t maxx; +static rnd_coord_t maxy; + +/* the same for subcircuits + Must initialize statics above before calling for the first time. + This was taken almost entirely from pcb_act_DisperseElements, with cleanup */ +static void place_subc(pcb_subc_t *sc) +{ + rnd_coord_t dx, dy, ox = 0, oy = 0; + + pcb_subc_get_origin(sc, &ox, &oy); + + /* figure out how much to move the subcircuit */ + dx = minx - sc->BoundingBox.X1; + dy = miny - sc->BoundingBox.Y1; + + /* snap to the grid */ + dx -= (ox + dx) % PCB->hidlib.grid; + dx += PCB->hidlib.grid; + dy -= (oy + dy) % PCB->hidlib.grid; + dy += PCB->hidlib.grid; + + /* and add one grid size so we make sure we always space by GAP or more */ + dx += PCB->hidlib.grid; + + /* Figure out if this row has room. If not, start a new row */ + if (minx != GAP && GAP + sc->BoundingBox.X2 + dx > PCB->hidlib.size_x) { + miny = maxy + GAP; + minx = GAP; + place_subc(sc); /* recurse can't loop, now minx==GAP */ + return; + } + + pcb_subc_move(sc, dx, dy, 1); + pcb_undo_add_obj_to_move(PCB_OBJ_SUBC, NULL, NULL, sc, dx, dy); + + /* keep track of how tall this row is */ + minx += sc->BoundingBox.X2 - sc->BoundingBox.X1 + GAP; + if (maxy < sc->BoundingBox.Y2) + maxy = sc->BoundingBox.Y2; +} + + +/* Return true if term1,term2 would be the best order, else term2,term1, based on pad loc. */ +static int padorder(pcb_subc_t *parent1, pcb_any_obj_t *term1, pcb_subc_t *parent2, pcb_any_obj_t *term2) +{ + rnd_coord_t x1, x2; + + x1 = term1->BoundingBox.X1 - (parent1->BoundingBox.X1 + parent1->BoundingBox.X2) / 2; + x2 = term2->BoundingBox.X1 - (parent2->BoundingBox.X1 + parent2->BoundingBox.X2) / 2; + + return (x1 > 0) && (x2 < 0); +} + +#define IS_IN_SUBC(CONN) (pcb_obj_parent_subc((CONN)->obj) != NULL) + +#define set_visited(obj) htpi_set(&visited, ((void *)(obj)), 1) +#define is_visited(obj) htpi_has(&visited, ((void *)(obj))) + +static const char pcb_acts_smartdisperse[] = "SmartDisperse([All|Selected])"; +static const char pcb_acth_smartdisperse[] = "Disperse subcircuits into clusters, by netlist connections"; +/* DOC: smartdisperse.html */ +static fgw_error_t pcb_act_smartdisperse(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + int op = -2; + pcb_netlist_t *nl = &PCB->netlist[PCB_NETLIST_EDITED]; + htpi_t visited; + int all; + htsp_entry_t *e; + + RND_ACT_MAY_CONVARG(1, FGW_KEYWORD, smartdisperse, op = fgw_keyword(&argv[1])); + + switch(op) { + case -2: + case F_All: all = 1; break; + case F_Selected: all = 0; break; + default: + RND_ACT_FAIL(smartdisperse); + } + + if (nl->used == 0) { + rnd_message(RND_MSG_ERROR, "Can't use SmartDisperse because no netlist is loaded.\n"); + RND_ACT_IRES(1); + return 0; + } + + /* remember which subcircuits we finish with */ + htpi_init(&visited, ptrhash, ptrkeyeq); + + PCB_SUBC_LOOP(PCB->Data); + { + if (!(all || PCB_FLAG_TEST(PCB_FLAG_SELECTED, subc))) + set_visited(subc); + } + PCB_END_LOOP; + + /* initialize variables for place() */ + minx = GAP; + miny = GAP; + maxx = GAP; + maxy = GAP; + + /* Pick nets with two connections. This is the start of a more + * elaborate algorithm to walk serial nets, but the datastructures + * are too gross so I'm going with the 80% solution. */ + for(e = htsp_first(nl); e != NULL; e = htsp_next(nl, e)) { + pcb_net_t *net = e->value; + pcb_net_term_t *t1, *t2; + pcb_any_obj_t *to1, *to2; + pcb_subc_t *ea, *eb; + + if (pcb_termlist_length(&net->conns) != 2) + continue; + + t1 = pcb_termlist_first(&net->conns); + t2 = pcb_termlist_next(t1); + to1 = pcb_term_find_name(PCB, PCB->Data, PCB_LYT_COPPER, t1->refdes, t1->term, NULL, NULL); + to2 = pcb_term_find_name(PCB, PCB->Data, PCB_LYT_COPPER, t2->refdes, t2->term, NULL, NULL); + + if ((to1 == NULL) || (to2 == NULL)) + continue; + + ea = pcb_obj_parent_subc(to1); + eb = pcb_obj_parent_subc(to2); + + /* place this pair if possible */ + if (is_visited(ea) || is_visited(eb)) + continue; + set_visited(ea); + set_visited(eb); + + /* a weak attempt to get the linked pads side-by-side */ + if (padorder(ea, to1, eb, to2)) { + place_subc(ea); + place_subc(eb); + } + else { + place_subc(eb); + place_subc(ea); + } + } + + /* Place larger nets, still grouping by net */ + for(e = htsp_first(nl); e != NULL; e = htsp_next(nl, e)) { + pcb_net_term_t *t; + pcb_net_t *net = e->value; + + for(t = pcb_termlist_first(&net->conns); t != NULL; t = pcb_termlist_next(t)) { + pcb_subc_t *parent; + pcb_any_obj_t *to; + + to = pcb_term_find_name(PCB, PCB->Data, PCB_LYT_COPPER, t->refdes, t->term, NULL, NULL); + if (to == NULL) + continue; + + parent = pcb_obj_parent_subc(to); + if (parent == NULL) + continue; + + /* place this one if needed */ + if (is_visited(parent)) + continue; + set_visited(parent); + place_subc(parent); + } + } + + /* Place up anything else */ + PCB_SUBC_LOOP(PCB->Data); + { + if (!is_visited(subc)) + place_subc(subc); + } + PCB_END_LOOP; + + htpi_uninit(&visited); + + pcb_undo_inc_serial(); + rnd_hid_redraw(PCB); + pcb_board_set_changed_flag(PCB, 1); + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t smartdisperse_action_list[] = { + {"smartdisperse", pcb_act_smartdisperse, pcb_acth_smartdisperse, pcb_acts_smartdisperse} +}; + +char *smartdisperse_cookie = "smartdisperse plugin"; + +int pplg_check_ver_smartdisperse(int ver_needed) { return 0; } + +void pplg_uninit_smartdisperse(void) +{ + rnd_remove_actions_by_cookie(smartdisperse_cookie); +} + +int pplg_init_smartdisperse(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(smartdisperse_action_list, smartdisperse_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/smartdisperse/smartdisperse.pup =================================================================== --- tags/2.3.0/src_plugins/smartdisperse/smartdisperse.pup (nonexistent) +++ tags/2.3.0/src_plugins/smartdisperse/smartdisperse.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short netlist based dispenser +$long Improve the initial dispersion of subcircuits by choosing an order based on the netlist, rather than the arbitrary subcircuit order. This isn't the same as a global autoplace, it's more of a linear autoplace. It might make some useful local groupings. For example, you should not have to chase all over the board to find the resistor that goes with a given LED. +$state works +$package auto +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/teardrops/Makefile =================================================================== --- tags/2.3.0/src_plugins/teardrops/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/teardrops/Makefile (revision 33253) @@ -0,0 +1,5 @@ +all: + cd ../../src && $(MAKE) mod_teardrops + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/teardrops/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/teardrops/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/teardrops/Plug.tmpasm (revision 33253) @@ -0,0 +1,8 @@ +put /local/pcb/mod {teardrops} +put /local/pcb/mod/OBJS [@ $(PLUGDIR)/teardrops/teardrops.o @] + +switch /local/pcb/teardrops/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/teardrops/teardrops.c =================================================================== --- tags/2.3.0/src_plugins/teardrops/teardrops.c (nonexistent) +++ tags/2.3.0/src_plugins/teardrops/teardrops.c (revision 33253) @@ -0,0 +1,287 @@ +/* + * Teardrops plug-in for PCB. + * + * Copyright (C) 2006 DJ Delorie + * + * Licensed under the terms of the GNU General Public + * License, version 2 or later. + * + * Ported to pcb-rnd by Tibor 'Igor2' Palinkas in 2016. + * Updated to new data model by Tibor 'Igor2' Palinkas in 2018. + * + * Original source: http://www.delorie.com/pcb/teardrops/ +*/ + +#include +#include + +#include "config.h" +#include +#include "board.h" +#include "data.h" +#include +#include +#include "undo.h" +#include +#include +#include "obj_pstk_inlines.h" + +#define MIN_LINE_LENGTH 700 +#define MAX_DISTANCE 700 + +#define MIN_LINE_LENGTH2 ((double)MIN_LINE_LENGTH*(double)MIN_LINE_LENGTH) +#define MAX_DISTANCE2 ((double)MAX_DISTANCE*(double)MAX_DISTANCE) + +static pcb_pstk_t *pstk; +static int layer; +static rnd_coord_t px, py; +static rnd_coord_t thickness; + +static int new_arcs = 0; + +static rnd_r_dir_t check_line_callback(const rnd_box_t * box, void *cl) +{ + pcb_layer_t *lay = &PCB->Data->Layer[layer]; + pcb_line_t *l = (pcb_line_t *) box; + int x1, x2, y1, y2; + double a, b, c, x, r, t; + double dx, dy, len; + double ax, ay, lx, ly, theta; + double ldist, adist, radius; + double vx, vy, vr, vl; + int delta, aoffset, count; + pcb_arc_t *arc; + + fprintf(stderr, "...Line ((%.6f, %.6f), (%.6f, %.6f)): ", + RND_COORD_TO_MM(l->Point1.X), RND_COORD_TO_MM(l->Point1.Y), RND_COORD_TO_MM(l->Point2.X), RND_COORD_TO_MM(l->Point2.Y)); + + /* if our line is to short ignore it */ + if (rnd_distance2(l->Point1.X, l->Point1.Y, l->Point2.X, l->Point2.Y) < MIN_LINE_LENGTH2) { + fprintf(stderr, "not within max line length\n"); + return 1; + } + + fprintf(stderr, "......Point (%.6f, %.6f): ", RND_COORD_TO_MM(px), RND_COORD_TO_MM(py)); + + if (rnd_distance2(l->Point1.X, l->Point1.Y, px, py) < MAX_DISTANCE2) { + x1 = l->Point1.X; + y1 = l->Point1.Y; + x2 = l->Point2.X; + y2 = l->Point2.Y; + } + else if (rnd_distance(l->Point2.X, l->Point2.Y, px, py) < MAX_DISTANCE2) { + x1 = l->Point2.X; + y1 = l->Point2.Y; + x2 = l->Point1.X; + y2 = l->Point1.Y; + } + else { + fprintf(stderr, "not within max distance\n"); + return 1; + } + + /* r = pin->Thickness / 2.0; */ + r = thickness / 2.0; + t = l->Thickness / 2.0; + + if (t > r) { + fprintf(stderr, "t > r: t = %3.6f, r = %3.6f\n", RND_COORD_TO_MM(t), RND_COORD_TO_MM(r)); + return 1; + } + + a = 1; + b = 4 * t - 2 * r; + c = 2 * t * t - r * r; + + x = (-b + sqrt(b * b - 4 * a * c)) / (2 * a); + + len = sqrt(((double) x2 - x1) * (x2 - x1) + ((double) y2 - y1) * (y2 - y1)); + + if (len > (x + t)) { + adist = ldist = x + t; + radius = x + t; + delta = 45; + + if (radius < r || radius < t) { + fprintf(stderr, + "(radius < r || radius < t): radius = %3.6f, r = %3.6f, t = %3.6f\n", + RND_COORD_TO_MM(radius), RND_COORD_TO_MM(r), RND_COORD_TO_MM(t)); + return 1; + } + } + else if (len > r + t) { + /* special "short teardrop" code */ + + x = (len * len - r * r + t * t) / (2 * (r - t)); + ldist = len; + adist = x + t; + radius = x + t; + delta = atan2(len, x + t) * 180.0 / M_PI; + } + else + return 1; + + dx = ((double) x2 - x1) / len; + dy = ((double) y2 - y1) / len; + theta = atan2(y2 - y1, x1 - x2) * 180.0 / M_PI; + + lx = px + dx * ldist; + ly = py + dy * ldist; + + /* We need one up front to determine how many segments it will take to fill. */ + ax = lx - dy * adist; + ay = ly + dx * adist; + vl = sqrt(r * r - t * t); + vx = px + dx * vl; + vy = py + dy * vl; + vx -= dy * t; + vy += dx * t; + vr = sqrt((ax - vx) * (ax - vx) + (ay - vy) * (ay - vy)); + + aoffset = 0; + count = 0; + do { + if (++count > 5) { + fprintf(stderr, "......a %d,%d v %d,%d adist %g radius %g vr %g\n", + (int) ax, (int) ay, (int) vx, (int) vy, adist, radius, vr); + printf("a %d,%d v %d,%d adist %g radius %g vr %g\n", (int) ax, (int) ay, (int) vx, (int) vy, adist, radius, vr); + return 1; + } + + ax = lx - dy * adist; + ay = ly + dx * adist; + + arc = pcb_arc_new(lay, (int) ax, (int) ay, (int) radius, + (int) radius, (int) theta + 90 + aoffset, delta - aoffset, l->Thickness, l->Clearance, l->Flags, rnd_true); + if (arc) + pcb_undo_add_obj_to_create(PCB_OBJ_ARC, lay, arc, arc); + + ax = lx + dy * (x + t); + ay = ly - dx * (x + t); + + arc = pcb_arc_new(lay, (int) ax, (int) ay, (int) radius, + (int) radius, (int) theta - 90 - aoffset, -delta + aoffset, l->Thickness, l->Clearance, l->Flags, rnd_true); + if (arc) + pcb_undo_add_obj_to_create(PCB_OBJ_ARC, lay, arc, arc); + + radius += t * 1.9; + aoffset = acos((double) adist / radius) * 180.0 / M_PI; + + new_arcs++; + } while (vr > radius - t); + + fprintf(stderr, "done arc'ing\n"); + return 1; +} + +static void check_pstk(pcb_pstk_t *ps) +{ + pstk = ps; + + for (layer = 0; layer < pcb_max_layer(PCB); layer++) { + pcb_layer_t *l = &(PCB->Data->Layer[layer]); + pcb_pstk_shape_t *shp, tmpshp; + rnd_box_t spot; + int n; + double mindist; + + if (!(pcb_layer_flags(PCB, layer) & PCB_LYT_COPPER)) + continue; + + shp = pcb_pstk_shape_at(PCB, ps, l); + if (shp == NULL) + continue; + + retry:; + switch(shp->shape) { + case PCB_PSSH_POLY: + /* Simplistic approach on polygons; works only on the simplest cases + How this could be handled better: list the 1 or 2 polygon edges + that cross the incoming line's sides and do the teardrops there; + but there are corner cases lurking: what if the next edges out + from the 1..2 edges are curving back? */ + px = py = 0; + for(n = 0; n < shp->data.poly.len; n++) { + px += shp->data.poly.x[n]; + py += shp->data.poly.y[n]; + } + px /= shp->data.poly.len; + py /= shp->data.poly.len; + + mindist = RND_MM_TO_COORD(8); + mindist *= mindist; + for(n = 0; n < shp->data.poly.len; n++) { + double dist = rnd_distance2(px, py, shp->data.poly.x[n], shp->data.poly.y[n]); + if (dist < mindist) + mindist = dist; + } + thickness = sqrt(mindist)*1.4; + px += ps->x; + py += ps->y; + break; + + case PCB_PSSH_LINE: + thickness = shp->data.line.thickness; + px = ps->x + (shp->data.line.x1 + shp->data.line.x2)/2; + py = ps->y + (shp->data.line.y1 + shp->data.line.y2)/2; + break; + + case PCB_PSSH_CIRC: + thickness = shp->data.circ.dia; + px = ps->x + shp->data.circ.x; + py = ps->y + shp->data.circ.y; + break; + + case PCB_PSSH_HSHADOW: + shp = pcb_pstk_hshadow_shape(ps, shp, &tmpshp); + if (shp != NULL) + goto retry; + continue; + } + + spot.X1 = px - 10; + spot.Y1 = py - 10; + spot.X2 = px + 10; + spot.Y2 = py + 10; + + rnd_r_search(l->line_tree, &spot, NULL, check_line_callback, l, NULL); + } +} + +static fgw_error_t pcb_act_teardrops(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_box_t *b; + rnd_rtree_it_t it; + new_arcs = 0; + + for(b = rnd_r_first(PCB->Data->padstack_tree, &it); b != NULL; b = rnd_r_next(&it)) + check_pstk((pcb_pstk_t *)b); + + rnd_gui->invalidate_all(rnd_gui); + + if (new_arcs) + pcb_undo_inc_serial(); + + RND_ACT_IRES(0); + return 0; +} + +static rnd_action_t teardrops_action_list[] = { + {"Teardrops", pcb_act_teardrops, NULL, NULL} +}; + +char *teardrops_cookie = "teardrops plugin"; + +int pplg_check_ver_teardrops(int ver_needed) { return 0; } + +void pplg_uninit_teardrops(void) +{ + rnd_remove_actions_by_cookie(teardrops_cookie); +} + +int pplg_init_teardrops(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(teardrops_action_list, teardrops_cookie); + return 0; +} Index: tags/2.3.0/src_plugins/teardrops/teardrops.pup =================================================================== --- tags/2.3.0/src_plugins/teardrops/teardrops.pup (nonexistent) +++ tags/2.3.0/src_plugins/teardrops/teardrops.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short draw teardrops on pins +$long Draw teardrops on pins. +$state works +$package extra +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/tool_std/Makefile =================================================================== --- tags/2.3.0/src_plugins/tool_std/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_tool_std + + +clean: + rm *.o *.so 2>/dev/null ; true Index: tags/2.3.0/src_plugins/tool_std/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/tool_std/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/Plug.tmpasm (revision 33253) @@ -0,0 +1,26 @@ +put /local/pcb/mod {tool_std} +put /local/pcb/mod/OBJS [@ + $(PLUGDIR)/tool_std/tool_std.o + $(PLUGDIR)/tool_std/tool_arc.o + $(PLUGDIR)/tool_std/tool_arrow.o + $(PLUGDIR)/tool_std/tool_buffer.o + $(PLUGDIR)/tool_std/tool_copy.o + $(PLUGDIR)/tool_std/tool_insert.o + $(PLUGDIR)/tool_std/tool_line.o + $(PLUGDIR)/tool_std/tool_lock.o + $(PLUGDIR)/tool_std/tool_move.o + $(PLUGDIR)/tool_std/tool_poly.o + $(PLUGDIR)/tool_std/tool_polyhole.o + $(PLUGDIR)/tool_std/tool_rectangle.o + $(PLUGDIR)/tool_std/tool_remove.o + $(PLUGDIR)/tool_std/tool_rotate.o + $(PLUGDIR)/tool_std/tool_text.o + $(PLUGDIR)/tool_std/tool_thermal.o + $(PLUGDIR)/tool_std/tool_via.o +@] + +switch /local/pcb/tool_std/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/tool_std/tool_arc.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_arc.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_arc.c (revision 33253) @@ -0,0 +1,248 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" + +#include "conf_core.h" +#include + +#include "board.h" +#include "crosshair.h" +#include "data.h" +#include "draw.h" +#include "draw_wireframe.h" +#include "search.h" +#include +#include "undo.h" + +#include "obj_arc_draw.h" + + +void pcb_tool_arc_init(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + if (rnd_tool_prev_id == pcb_crosshair.tool_line && pcb_crosshair.AttachedLine.State != PCB_CH_STATE_FIRST) { + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_FIRST; + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_SECOND; + pcb_crosshair.AttachedBox.Point1.X = pcb_crosshair.AttachedBox.Point2.X = pcb_crosshair.AttachedLine.Point1.X; + pcb_crosshair.AttachedBox.Point1.Y = pcb_crosshair.AttachedBox.Point2.Y = pcb_crosshair.AttachedLine.Point1.Y; + rnd_tool_adjust_attached(NULL); + } + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +void pcb_tool_arc_uninit(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + pcb_added_lines = 0; + if (rnd_tool_next_id != pcb_crosshair.tool_line) { + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; + if (!pcb_marked.user_placed) + pcb_crosshair_set_local_ref(0, 0, rnd_false); + } + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +void pcb_tool_arc_notify_mode(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + + switch (pcb_crosshair.AttachedBox.State) { + case PCB_CH_STATE_FIRST: + pcb_crosshair.AttachedBox.Point1.X = pcb_crosshair.AttachedBox.Point2.X = hl->tool_x; + pcb_crosshair.AttachedBox.Point1.Y = pcb_crosshair.AttachedBox.Point2.Y = hl->tool_y; + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_SECOND; + break; + + case PCB_CH_STATE_SECOND: + case PCB_CH_STATE_THIRD: + { + pcb_arc_t *arc; + rnd_coord_t wx, wy; + rnd_angle_t sa, dir; + wx = hl->tool_x - pcb_crosshair.AttachedBox.Point1.X; + wy = hl->tool_y - pcb_crosshair.AttachedBox.Point1.Y; +rnd_trace("arc: %mm %mm wh %mm %mm\n", hl->tool_x, hl->tool_y, wx, wy); + if (RND_XOR(pcb_crosshair.AttachedBox.otherway, coord_abs(wy) > coord_abs(wx))) { + pcb_crosshair.AttachedBox.Point2.X = pcb_crosshair.AttachedBox.Point1.X + coord_abs(wy) * RND_SGNZ(wx); + sa = (wx >= 0) ? 0 : 180; + dir = (RND_SGNZ(wx) == RND_SGNZ(wy)) ? 90 : -90; + } + else { + pcb_crosshair.AttachedBox.Point2.Y = pcb_crosshair.AttachedBox.Point1.Y + coord_abs(wx) * RND_SGNZ(wy); + sa = (wy >= 0) ? -90 : 90; + dir = (RND_SGNZ(wx) == RND_SGNZ(wy)) ? -90 : 90; + wy = wx; + } + if (coord_abs(wy) > 0 && (arc = pcb_arc_new(pcb_loose_subc_layer(pcb, PCB_CURRLAYER(pcb), rnd_true), + pcb_crosshair.AttachedBox.Point2.X, + pcb_crosshair.AttachedBox.Point2.Y, + coord_abs(wy), + coord_abs(wy), + sa, + dir, + conf_core.design.line_thickness, + 2 * conf_core.design.clearance, + pcb_flag_make(conf_core.editor.clear_line ? PCB_FLAG_CLEARLINE : 0), rnd_true))) { + pcb_obj_add_attribs((pcb_any_obj_t *)arc, pcb->pen_attr, NULL); + pcb_arc_get_end(arc, 1, &pcb_crosshair.AttachedBox.Point2.X, &pcb_crosshair.AttachedBox.Point2.Y); + pcb_crosshair.AttachedBox.Point1.X = pcb_crosshair.AttachedBox.Point2.X; + pcb_crosshair.AttachedBox.Point1.Y = pcb_crosshair.AttachedBox.Point2.Y; + pcb_undo_add_obj_to_create(PCB_OBJ_ARC, PCB_CURRLAYER(pcb), arc, arc); + pcb_undo_inc_serial(); + pcb_added_lines++; + pcb_arc_invalidate_draw(PCB_CURRLAYER(pcb), arc); + pcb_subc_as_board_update(pcb); + pcb_draw(); + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_THIRD; + } + break; + } + } +} + +void pcb_tool_arc_adjust_attached_objects(rnd_hidlib_t *hl) +{ + pcb_crosshair.AttachedBox.otherway = rnd_gui->shift_is_pressed(rnd_gui); +} + +void pcb_tool_arc_draw_attached(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + + if (pcb_crosshair.AttachedBox.State != PCB_CH_STATE_FIRST) { + pcb_xordraw_attached_arc(conf_core.design.line_thickness); + if (conf_core.editor.show_drc) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + pcb_xordraw_attached_arc(conf_core.design.line_thickness + 2 * (conf_core.design.clearance + 1)); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } + } + else { + /* Draw a circle (0 length line) to show where the arc will start when placed */ + if(PCB_CURRLAYER(pcb)) + rnd_render->set_color(pcb_crosshair.GC, &PCB_CURRLAYER(pcb)->meta.real.color); + + pcb_draw_wireframe_line(pcb_crosshair.GC, + pcb_crosshair.X, pcb_crosshair.Y, + pcb_crosshair.X, pcb_crosshair.Y, + conf_core.design.line_thickness, 0); + + if(conf_core.editor.show_drc) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + pcb_draw_wireframe_line(pcb_crosshair.GC, + pcb_crosshair.X, pcb_crosshair.Y, + pcb_crosshair.X, pcb_crosshair.Y, + conf_core.design.line_thickness + (2 * conf_core.design.clearance), 0); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } + } + +} + +rnd_bool pcb_tool_arc_undo_act(rnd_hidlib_t *hl) +{ + if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_SECOND) { + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); + return rnd_false; + } + if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_THIRD) { + void *ptr1, *ptr2, *ptr3; + /* guaranteed to succeed */ + pcb_search_obj_by_location(PCB_OBJ_ARC, &ptr1, &ptr2, &ptr3, + pcb_crosshair.AttachedBox.Point1.X, pcb_crosshair.AttachedBox.Point1.Y, 0); + pcb_arc_get_end((pcb_arc_t *) ptr2, 0, &pcb_crosshair.AttachedBox.Point2.X, &pcb_crosshair.AttachedBox.Point2.Y); + pcb_crosshair.AttachedBox.Point1.X = pcb_crosshair.AttachedBox.Point2.X; + pcb_crosshair.AttachedBox.Point1.Y = pcb_crosshair.AttachedBox.Point2.Y; + rnd_tool_adjust_attached(hl); + if (--pcb_added_lines == 0) + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_SECOND; + } + return rnd_true; +} + +void pcb_tool_arc_escape(rnd_hidlib_t *hl) +{ + if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_FIRST) + rnd_tool_select_by_name(hl, "arrow"); + else + rnd_tool_select_by_name(hl, "arc"); +} + +/* XPM */ +static const char *arc_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"ooooo.ooooooooooooooo", +"ooooo.ooooooooooooooo", +"ooooo.ooooooooooooooo", +"ooooo.ooooooooooooooo", +"oooooo.oooooooooooooo", +"oooooo.oooooooooooooo", +"ooooooo.ooooooooooooo", +"ooooooo..oooooooooooo", +"oooooooo..ooooooooooo", +"oooooooooo..ooooooooo", +"oooooooooooo....ooooo", +"ooooooooooooooooooooo", +"ooo oooo oooo oo", +"oo o ooo ooo oo ooo o", +"oo o ooo ooo oo ooo o", +"o ooo oo ooo ooooo", +"o oo ooooo ooooo", +"o ooo oo o oooo ooooo", +"o ooo oo oo ooo ooo o", +"o ooo oo ooo ooo oo", +"ooooooooooooooooooooo" +}; + +rnd_tool_t pcb_tool_arc = { + "arc", NULL, NULL, 100, arc_icon, RND_TOOL_CURSOR_NAMED("question_arrow"), 0, + pcb_tool_arc_init, + pcb_tool_arc_uninit, + pcb_tool_arc_notify_mode, + NULL, + pcb_tool_arc_adjust_attached_objects, + pcb_tool_arc_draw_attached, + pcb_tool_arc_undo_act, + NULL, + pcb_tool_arc_escape, + + 0 +}; Index: tags/2.3.0/src_plugins/tool_std/tool_arc.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_arc.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_arc.h (revision 33253) @@ -0,0 +1,8 @@ +extern rnd_tool_t pcb_tool_arc; + +void pcb_tool_arc_init(void); +void pcb_tool_arc_uninit(void); +void pcb_tool_arc_notify_mode(rnd_hidlib_t *hl); +void pcb_tool_arc_adjust_attached_objects(rnd_hidlib_t *hl); +void pcb_tool_arc_draw_attached(rnd_hidlib_t *hl); +rnd_bool pcb_tool_arc_undo_act(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_arrow.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_arrow.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_arrow.c (revision 33253) @@ -0,0 +1,296 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" +#include "conf_core.h" + +#include "board.h" +#include "buffer.h" +#include "crosshair.h" +#include "data.h" +#include +#include "remove.h" +#include "move.h" +#include "search.h" +#include "select.h" +#include +#include "undo.h" +#include "extobj.h" +#include "tool_logic.h" + + +void pcb_tool_arrow_uninit(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + pcb_crosshair_attached_clean(&PCB->hidlib); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +/* Called some time after the click if there was a release but no second click + a.k.a. finalize single click (some things are already done in pcb_press_mode + at the initial click event) */ +static void click_timer_cb(rnd_hidval_t hv) +{ + rnd_hidlib_t *hl = hv.ptr; + pcb_board_t *pcb = hv.ptr; + + if (hl->tool_click) { + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + hl->tool_click = rnd_false; + if (pcb_crosshair_note.Moving && !rnd_gui->shift_is_pressed(rnd_gui)) { + hl->tool_grabbed.status = rnd_true; + pcb_crosshair_note.Buffer = conf_core.editor.buffer_number; + pcb_buffer_set_number(PCB_MAX_BUFFER - 1); + pcb_buffer_clear(pcb, PCB_PASTEBUFFER); + pcb_buffer_add_selected(pcb, PCB_PASTEBUFFER, hl->tool_x, hl->tool_y, rnd_true, rnd_true); + pcb_undo_save_serial(); + pcb_remove_selected(PCB_OP_NO_SUBC_PART); + rnd_tool_save(hl); + rnd_tool_is_saved = rnd_true; + rnd_tool_select_by_name(hl, "buffer"); + } + else if (hl->tool_hit && !rnd_gui->shift_is_pressed(rnd_gui)) { + rnd_box_t box; + + hl->tool_grabbed.status = rnd_true; + rnd_tool_save(hl); + rnd_tool_is_saved = rnd_true; + rnd_tool_select_by_name(hl, rnd_gui->control_is_pressed(rnd_gui)? "copy" : "move"); + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Ptr1 = pcb_crosshair_note.ptr1; + pcb_crosshair.AttachedObject.Ptr2 = pcb_crosshair_note.ptr2; + pcb_crosshair.AttachedObject.Ptr3 = pcb_crosshair_note.ptr3; + pcb_crosshair.AttachedObject.Type = hl->tool_hit; + + if (pcb_crosshair.drags != NULL) { + free(pcb_crosshair.drags); + pcb_crosshair.drags = NULL; + } + pcb_crosshair.dragx = hl->tool_x; + pcb_crosshair.dragy = hl->tool_y; + box.X1 = hl->tool_x + PCB_SLOP * rnd_pixel_slop; + box.X2 = hl->tool_x - PCB_SLOP * rnd_pixel_slop; + box.Y1 = hl->tool_y + PCB_SLOP * rnd_pixel_slop; + box.Y2 = hl->tool_y - PCB_SLOP * rnd_pixel_slop; + pcb_crosshair.drags = pcb_list_block(pcb, &box, &pcb_crosshair.drags_len); + pcb_crosshair.drags_current = 0; + pcb_tool_attach_for_copy(hl, hl->tool_x, hl->tool_y, rnd_true); + } + else { + rnd_box_t box; + + hl->tool_hit = 0; + pcb_crosshair_note.Moving = rnd_false; + pcb_undo_save_serial(); + box.X1 = -RND_MAX_COORD; + box.Y1 = -RND_MAX_COORD; + box.X2 = RND_MAX_COORD; + box.Y2 = RND_MAX_COORD; + /* unselect first if shift key not down */ + if (!rnd_gui->shift_is_pressed(rnd_gui) && pcb_select_block(pcb, &box, rnd_false, rnd_false, rnd_false)) + pcb_board_set_changed_flag(PCB, rnd_true); + pcb_tool_notify_block(); + pcb_crosshair.AttachedBox.Point1.X = hl->tool_x; + pcb_crosshair.AttachedBox.Point1.Y = hl->tool_y; + } + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); + } + + if (pcb_crosshair.extobj_edit != NULL) { + pcb_extobj_float_geo(pcb_crosshair.extobj_edit); + rnd_gui->invalidate_all(rnd_gui); + } +} + +static int pcb_tool_arrow_notify_mode_(rnd_hidlib_t *hl, int type, void *ptr1, void *ptr2, void *ptr3) +{ + int otype = type; + + if (otype == PCB_OBJ_ARC_POINT) { /* ignore arc endpoints if arc radius is 0 (so arc center is grabbed) */ + pcb_arc_t *arc = (pcb_arc_t *)ptr2; + if ((arc->Width == 0) && (arc->Height == 0)) + return 0; + } + if (!hl->tool_hit && (type & PCB_MOVE_TYPES) && !PCB_FLAG_TEST(PCB_FLAG_LOCK, (pcb_any_obj_t *) ptr2)) { + hl->tool_hit = type; + pcb_crosshair_note.ptr1 = ptr1; + pcb_crosshair_note.ptr2 = ptr2; + pcb_crosshair_note.ptr3 = ptr3; + pcb_crosshair.AttachedObject.tx = hl->tool_x; + pcb_crosshair.AttachedObject.ty = hl->tool_y; + } + if (!pcb_crosshair_note.Moving && (type & (PCB_SELECT_TYPES | PCB_LOOSE_SUBC(PCB))) && PCB_FLAG_TEST(PCB_FLAG_SELECTED, (pcb_any_obj_t *) ptr2)) { + pcb_crosshair_note.Moving = rnd_true; + /* remember where the user clicked to start this op */ + pcb_crosshair.AttachedObject.tx = pcb_crosshair.AttachedObject.X = hl->tool_x; + pcb_crosshair.AttachedObject.ty = pcb_crosshair.AttachedObject.Y = hl->tool_y; + } + if ((hl->tool_hit && pcb_crosshair_note.Moving) || type == PCB_OBJ_VOID) + return 1; + + return 0; +} + +void pcb_tool_arrow_notify_mode(rnd_hidlib_t *hl) +{ + void *ptr1, *ptr2, *ptr3; + int type; + int test; + rnd_hidval_t hv; + + hl->tool_click = rnd_true; + /* do something after click time */ + hv.ptr = hl; + rnd_gui->add_timer(rnd_gui, click_timer_cb, conf_core.editor.click_time, hv); + + /* see if we clicked on something already selected + * (pcb_crosshair_note.Moving) or clicked on a MOVE_TYPE + * (hl->tool_hit) + */ + for (test = (PCB_SELECT_TYPES | PCB_MOVE_TYPES | PCB_OBJ_FLOATER | PCB_LOOSE_SUBC(PCB)) & ~PCB_OBJ_RAT; test; test &= ~type) { + /* grab object/point (e.g. line endpoint) for edit */ + type = pcb_search_screen(hl->tool_x, hl->tool_y, test, &ptr1, &ptr2, &ptr3); + if (pcb_tool_arrow_notify_mode_(hl, type, ptr1, ptr2, ptr3)) + return; + } +} + +void pcb_tool_arrow_release_mode(rnd_hidlib_t *hl) +{ + rnd_box_t box; + pcb_board_t *pcb = (pcb_board_t *)hl; + + if (hl->tool_click) { + rnd_box_t box; + + box.X1 = -RND_MAX_COORD; + box.Y1 = -RND_MAX_COORD; + box.X2 = RND_MAX_COORD; + box.Y2 = RND_MAX_COORD; + + hl->tool_click = rnd_false; /* inhibit timer action */ + pcb_undo_save_serial(); + /* unselect first if shift key not down */ + if (!rnd_gui->shift_is_pressed(rnd_gui)) { + if (pcb_select_block(pcb, &box, rnd_false, rnd_false, rnd_false)) + pcb_board_set_changed_flag(pcb, rnd_true); + if (pcb_crosshair_note.Moving) { + pcb_crosshair_note.Moving = 0; + hl->tool_hit = 0; + return; + } + } + /* Restore the SN so that if we select something the deselect/select combo + gets the same SN. */ + pcb_undo_restore_serial(); + if (pcb_select_object(PCB)) + pcb_board_set_changed_flag(pcb, rnd_true); + else + pcb_undo_inc_serial(); /* We didn't select anything new, so, the deselection should get its own SN. */ + hl->tool_hit = 0; + pcb_crosshair_note.Moving = 0; + } + else if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_SECOND) { + box.X1 = pcb_crosshair.AttachedBox.Point1.X; + box.Y1 = pcb_crosshair.AttachedBox.Point1.Y; + box.X2 = pcb_crosshair.AttachedBox.Point2.X; + box.Y2 = pcb_crosshair.AttachedBox.Point2.Y; + + pcb_undo_restore_serial(); + if (pcb_select_block(pcb, &box, rnd_true, rnd_true, rnd_false)) { + pcb_board_set_changed_flag(pcb, rnd_true); + pcb_undo_inc_serial(); + } + else if (pcb_bumped) + pcb_undo_inc_serial(); + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; + } +} + +void pcb_tool_arrow_adjust_attached_objects(rnd_hidlib_t *hl) +{ + if (pcb_crosshair.AttachedBox.State) { + pcb_crosshair.AttachedBox.Point2.X = pcb_crosshair.X; + pcb_crosshair.AttachedBox.Point2.Y = pcb_crosshair.Y; + } +} + +/* 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" +}; + +rnd_tool_t pcb_tool_arrow = { + "arrow", NULL, NULL, 10, arrow_icon, RND_TOOL_CURSOR_NAMED("left_ptr"), 0, + NULL, + pcb_tool_arrow_uninit, + pcb_tool_arrow_notify_mode, + pcb_tool_arrow_release_mode, + pcb_tool_arrow_adjust_attached_objects, + NULL, + NULL, + NULL, + NULL, /* escape */ + + PCB_TLF_RAT | PCB_TLF_EDIT +}; Index: tags/2.3.0/src_plugins/tool_std/tool_arrow.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_arrow.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_arrow.h (revision 33253) @@ -0,0 +1,6 @@ +extern rnd_tool_t pcb_tool_arrow; + +void pcb_tool_arrow_uninit(void); +void pcb_tool_arrow_notify_mode(rnd_hidlib_t *hl); +void pcb_tool_arrow_release_mode(rnd_hidlib_t *hl); +void pcb_tool_arrow_adjust_attached_objects(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_buffer.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_buffer.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_buffer.c (revision 33253) @@ -0,0 +1,151 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" +#include "conf_core.h" + +#include "board.h" +#include "buffer.h" +#include +#include "data.h" +#include +#include +#include "search.h" +#include +#include "undo.h" + +void pcb_tool_buffer_init(void) +{ +} + +void pcb_tool_buffer_uninit(void) +{ +} + +static void pcb_tool_buffer_notify_mode_(rnd_hidlib_t *hl, rnd_bool keep_ids) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + + if (rnd_gui->shift_is_pressed(rnd_gui)) { + rnd_actionva(hl, "ReplaceFootprint", "object", "@buffer", "", NULL); + return; + } + + if (pcb_buffer_copy_to_layout(pcb, pcb_crosshair.AttachedObject.tx, pcb_crosshair.AttachedObject.ty, keep_ids)) { + pcb_board_set_changed_flag(pcb, rnd_true); + rnd_gui->invalidate_all(rnd_gui); + } +} + +void pcb_tool_buffer_notify_mode(rnd_hidlib_t *hl) +{ + pcb_tool_buffer_notify_mode_(hl, rnd_false); +} + +void pcb_tool_buffer_release_mode(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + + if (pcb_crosshair_note.Moving) { /* release of a drag&drop move of selected objects */ + pcb_undo_restore_serial(); + /* NOTE: can not keep ids: TODO27: + 1. select an object, id #9 + 2. drag&drop move + 3. drag&drop move it again (still selected) + 4. when undo, the removebuffer will have 2 objects with the same id #9! + */ + pcb_tool_buffer_notify_mode_(hl, rnd_false); + pcb_buffer_clear(pcb, PCB_PASTEBUFFER); + pcb_buffer_set_number(pcb_crosshair_note.Buffer); + pcb_crosshair_note.Moving = rnd_false; + hl->tool_hit = 0; + } +} + +void pcb_tool_buffer_adjust_attached_objects(rnd_hidlib_t *hl) +{ + pcb_crosshair.AttachedObject.tx = pcb_crosshair.X; + pcb_crosshair.AttachedObject.ty = pcb_crosshair.Y; +} + +void pcb_tool_buffer_draw_attached(rnd_hidlib_t *hl) +{ + pcb_xordraw_buffer(PCB_PASTEBUFFER); +} + +/* XPM */ +static const char *buf_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #7A8584", +"o c None", +/* pixels */ +"oooooooo oo ooooooo", +"oooooo.. o o ..ooooo", +"oooooooo oooo ooooooo", +"oooooo.. oooo ..ooooo", +"oooooooo oooo ooooooo", +"oooooo.. oooo ..ooooo", +"oooooooo oooo ooooooo", +"oooooo.. oooo ..ooooo", +"oooooooo oooo ooooooo", +"oooooo.. oooo ..ooooo", +"oooooooo ooooooo", +"ooooooooooooooooooooo", +"oo oo ooo o o", +"ooo ooo o ooo o ooooo", +"ooo ooo o ooo o ooooo", +"ooo ooo o ooo o oo", +"ooo oo ooo o ooooo", +"ooo ooo o ooo o ooooo", +"ooo ooo o ooo o ooooo", +"oo ooo oo ooooo", +"ooooooooooooooooooooo" +}; + +rnd_tool_t pcb_tool_buffer = { + "buffer", NULL, NULL, 100, buf_icon, RND_TOOL_CURSOR_NAMED("hand"), 0, + pcb_tool_buffer_init, + pcb_tool_buffer_uninit, + pcb_tool_buffer_notify_mode, + pcb_tool_buffer_release_mode, + pcb_tool_buffer_adjust_attached_objects, + pcb_tool_buffer_draw_attached, + NULL, + NULL, + NULL, /* escape */ + + 0 +}; Index: tags/2.3.0/src_plugins/tool_std/tool_buffer.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_buffer.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_buffer.h (revision 33253) @@ -0,0 +1,7 @@ +extern rnd_tool_t pcb_tool_buffer; + +void pcb_tool_buffer_init(void); +void pcb_tool_buffer_uninit(void); +void pcb_tool_buffer_notify_mode(rnd_hidlib_t *hl); +void pcb_tool_buffer_release_mode(rnd_hidlib_t *hl); +void pcb_tool_buffer_draw_attached(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_copy.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_copy.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_copy.c (revision 33253) @@ -0,0 +1,138 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" + +#include "board.h" +#include "move.h" +#include "crosshair.h" +#include "search.h" +#include "tool_logic.h" +#include + +void pcb_tool_copy_uninit(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + pcb_crosshair_attached_clean(&PCB->hidlib); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); + pcb_crosshair.extobj_edit = NULL; +} + +void pcb_tool_copy_notify_mode(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + + switch (pcb_crosshair.AttachedObject.State) { + /* first notify, lookup object */ + case PCB_CH_STATE_FIRST: + { + int types = PCB_COPY_TYPES; + + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = + pcb_search_screen(hl->tool_x, hl->tool_y, types, + &pcb_crosshair.AttachedObject.Ptr1, &pcb_crosshair.AttachedObject.Ptr2, &pcb_crosshair.AttachedObject.Ptr3); + if (pcb_crosshair.AttachedObject.Type != PCB_OBJ_VOID) { + pcb_tool_attach_for_copy(hl, hl->tool_x, hl->tool_y, rnd_false); + } + break; + } + + /* second notify, move or copy object */ + case PCB_CH_STATE_SECOND: + + if ((pcb->is_footprint) && (pcb_crosshair.AttachedObject.Type == PCB_OBJ_SUBC)) { + rnd_message(RND_MSG_WARNING, "Can not copy subcircuit in the footprint edit mode\n"); + } + else { + pcb_copy_obj(pcb_crosshair.AttachedObject.Type, + pcb_crosshair.AttachedObject.Ptr1, + pcb_crosshair.AttachedObject.Ptr2, + pcb_crosshair.AttachedObject.Ptr3, pcb_crosshair.AttachedObject.tx - pcb_crosshair.AttachedObject.X, pcb_crosshair.AttachedObject.ty - pcb_crosshair.AttachedObject.Y); + pcb_subc_as_board_update(PCB); + pcb_board_set_changed_flag(pcb, rnd_true); + } + + /* reset identifiers */ + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + pcb_crosshair.extobj_edit = NULL; + break; + } +} + +void pcb_tool_copy_release_mode(rnd_hidlib_t *hl) +{ + if (hl->tool_hit) { + pcb_tool_copy_notify_mode(hl); + hl->tool_hit = 0; + } +} + +void pcb_tool_copy_adjust_attached_objects(rnd_hidlib_t *hl) +{ + pcb_crosshair.AttachedObject.tx = pcb_crosshair.X; + pcb_crosshair.AttachedObject.ty = pcb_crosshair.Y; +} + +void pcb_tool_copy_draw_attached(rnd_hidlib_t *hl) +{ + pcb_xordraw_movecopy(rnd_gui->control_is_pressed(rnd_gui)); +} + +rnd_bool pcb_tool_copy_undo_act(rnd_hidlib_t *hl) +{ + /* don't allow undo in the middle of an operation */ + if (pcb_crosshair.AttachedObject.State != PCB_CH_STATE_FIRST) + return rnd_false; + return rnd_true; +} + +rnd_tool_t pcb_tool_copy = { + "copy", NULL, NULL, 100, NULL, RND_TOOL_CURSOR_NAMED("crosshair"), 0, + NULL, + pcb_tool_copy_uninit, + pcb_tool_copy_notify_mode, + pcb_tool_copy_release_mode, + pcb_tool_copy_adjust_attached_objects, + pcb_tool_copy_draw_attached, + pcb_tool_copy_undo_act, + NULL, + NULL, /* escape */ + + 0 +}; Index: tags/2.3.0/src_plugins/tool_std/tool_copy.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_copy.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_copy.h (revision 33253) @@ -0,0 +1,7 @@ +extern rnd_tool_t pcb_tool_copy; + +void pcb_tool_copy_uninit(void); +void pcb_tool_copy_notify_mode(rnd_hidlib_t *hl); +void pcb_tool_copy_release_mode(rnd_hidlib_t *hl); +void pcb_tool_copy_draw_attached(rnd_hidlib_t *hl); +rnd_bool pcb_tool_copy_undo_act(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_insert.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_insert.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_insert.c (revision 33253) @@ -0,0 +1,204 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" + +#include "board.h" +#include "crosshair.h" +#include "insert.h" +#include "polygon.h" +#include "search.h" +#include "tool_logic.h" +#include + + +static struct { + pcb_poly_t *poly; + pcb_line_t line; +} fake; + +static rnd_point_t InsertedPoint; +static rnd_cardinal_t polyIndex = 0; + + +void pcb_tool_insert_uninit(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + pcb_crosshair_attached_clean(&PCB->hidlib); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + pcb_crosshair.extobj_edit = NULL; + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +void pcb_tool_insert_notify_mode(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + switch (pcb_crosshair.AttachedObject.State) { + /* first notify, lookup object */ + case PCB_CH_STATE_FIRST: + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = + pcb_search_screen_maybe_selector(hl->tool_x, hl->tool_y, PCB_INSERT_TYPES, + &pcb_crosshair.AttachedObject.Ptr1, &pcb_crosshair.AttachedObject.Ptr2, &pcb_crosshair.AttachedObject.Ptr3); + + if (pcb_crosshair.AttachedObject.Type != PCB_OBJ_VOID) { + pcb_any_obj_t *obj = (pcb_any_obj_t *)pcb_crosshair.AttachedObject.Ptr2; + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, obj)) { + rnd_message(RND_MSG_WARNING, "Sorry, %s object is locked\n", pcb_obj_type_name(obj->type)); + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.extobj_edit = NULL; + break; + } + else { + /* get starting point of nearest segment */ + if (pcb_crosshair.AttachedObject.Type == PCB_OBJ_POLY) { + fake.poly = (pcb_poly_t *) pcb_crosshair.AttachedObject.Ptr2; + polyIndex = pcb_poly_get_lowest_distance_point(fake.poly, hl->tool_x, hl->tool_y); + fake.line.Point1 = fake.poly->Points[polyIndex]; + fake.line.Point2 = fake.poly->Points[pcb_poly_contour_prev_point(fake.poly, polyIndex)]; + pcb_crosshair.AttachedObject.Ptr2 = &fake.line; + + } + { + InsertedPoint = *pcb_adjust_insert_point(); + pcb_crosshair_set_local_ref(InsertedPoint.X, InsertedPoint.Y, rnd_true); + if (pcb_crosshair.AttachedObject.Type == PCB_OBJ_POLY) + pcb_insert_point_in_object(PCB_OBJ_POLY, + pcb_crosshair.AttachedObject.Ptr1, fake.poly, + &polyIndex, InsertedPoint.X, InsertedPoint.Y, rnd_false, rnd_false); + else + pcb_insert_point_in_object(pcb_crosshair.AttachedObject.Type, + pcb_crosshair.AttachedObject.Ptr1, + pcb_crosshair.AttachedObject.Ptr2, &polyIndex, InsertedPoint.X, InsertedPoint.Y, rnd_false, rnd_false); + pcb_board_set_changed_flag(pcb, rnd_true); + + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + pcb_crosshair.extobj_edit = NULL; + } + } + } + break; + + /* second notify, insert new point into object */ + case PCB_CH_STATE_SECOND: + pcb_crosshair_attached_clean(hl); + if (pcb_crosshair.AttachedObject.Type == PCB_OBJ_POLY) + pcb_insert_point_in_object(PCB_OBJ_POLY, + pcb_crosshair.AttachedObject.Ptr1, fake.poly, + &polyIndex, InsertedPoint.X, InsertedPoint.Y, rnd_false, rnd_false); + else + pcb_insert_point_in_object(pcb_crosshair.AttachedObject.Type, + pcb_crosshair.AttachedObject.Ptr1, + pcb_crosshair.AttachedObject.Ptr2, &polyIndex, InsertedPoint.X, InsertedPoint.Y, rnd_false, rnd_false); + pcb_board_set_changed_flag(pcb, rnd_true); + + /* reset identifiers */ + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + pcb_crosshair.extobj_edit = NULL; + break; + } +} + +void pcb_tool_insert_adjust_attached_objects(rnd_hidlib_t *hl) +{ + rnd_point_t *pnt; + pnt = pcb_adjust_insert_point(); + if (pnt) + InsertedPoint = *pnt; +} + +void pcb_tool_insert_draw_attached(rnd_hidlib_t *hl) +{ + pcb_xordraw_insert_pt_obj(); +} + +rnd_bool pcb_tool_insert_undo_act(rnd_hidlib_t *hl) +{ + /* don't allow undo in the middle of an operation */ + if (pcb_crosshair.AttachedObject.State != PCB_CH_STATE_FIRST) + return rnd_false; + return rnd_true; +} + +/* XPM */ +static const char *ins_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"oooooo...oooooooooooo", +"ooooo.ooo.ooooooooooo", +"ooooo.o.o.ooooooooooo", +"oooooo....ooooooooooo", +"ooooooooooooooooooooo", +"oooo ooooo oooooooo", +"ooooooooooooooooooooo", +"oo...ooooooooooo...oo", +"o.oo..ooooooooo.ooo.o", +"o.o o...........o o.o", +"o.ooo.ooooooooo.ooo.o", +"oo...ooooooooooo...oo", +"ooooooooooooooooooooo", +"ooo o ooo oo ooo", +"oooo oo ooo o ooooooo", +"oooo oo oo o ooooooo", +"oooo oo o o oo oooo", +"oooo oo oo ooooo ooo", +"oooo oo ooo ooooo ooo", +"oooo oo ooo ooooo ooo", +"ooo o ooo o oooo" +}; + +rnd_tool_t pcb_tool_insert = { + "insert", NULL, NULL, 100, ins_icon, RND_TOOL_CURSOR_NAMED("dotbox"), 0, + NULL, + pcb_tool_insert_uninit, + pcb_tool_insert_notify_mode, + NULL, + pcb_tool_insert_adjust_attached_objects, + pcb_tool_insert_draw_attached, + pcb_tool_insert_undo_act, + NULL, + NULL, /* escape */ + + PCB_TLF_EDIT +}; Index: tags/2.3.0/src_plugins/tool_std/tool_insert.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_insert.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_insert.h (revision 33253) @@ -0,0 +1,7 @@ +extern rnd_tool_t pcb_tool_insert; + +void pcb_tool_insert_uninit(void); +void pcb_tool_insert_notify_mode(rnd_hidlib_t *hl); +void pcb_tool_insert_adjust_attached_objects(rnd_hidlib_t *hl); +void pcb_tool_insert_draw_attached(rnd_hidlib_t *hl); +rnd_bool pcb_tool_insert_undo_act(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_line.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_line.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_line.c (revision 33253) @@ -0,0 +1,538 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" + +#include "conf_core.h" +#include + +#include "board.h" +#include "crosshair.h" +#include "data.h" +#include "draw.h" +#include "draw_wireframe.h" +#include "find.h" +#include "obj_line.h" +#include "obj_subc.h" +#include "search.h" +#include +#include "undo.h" +#include "netlist.h" +#include "tool_logic.h" + +#include "obj_line_draw.h" +#include "obj_pstk_draw.h" +#include "obj_rat_draw.h" +#include "route_draw.h" + +TODO("pstk: remove this when via is removed and the padstack is created from style directly") +#include "src_plugins/lib_compat_help/pstk_compat.h" + +static pcb_layer_t *last_layer; + + +void pcb_tool_line_init(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + if (rnd_tool_prev_id == pcb_crosshair.tool_arc && pcb_crosshair.AttachedBox.State != PCB_CH_STATE_FIRST) { + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_SECOND; + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X = pcb_crosshair.AttachedBox.Point1.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y = pcb_crosshair.AttachedBox.Point1.Y; + rnd_tool_adjust_attached(NULL); + } + else { + if (conf_core.editor.auto_drc) { + if (pcb_data_clear_flag(PCB->Data, PCB_FLAG_FOUND, 1, 1) > 0) { + pcb_undo_inc_serial(); + pcb_draw(); + } + } + } + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +void pcb_tool_line_uninit(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + pcb_added_lines = 0; + pcb_route_reset(&pcb_crosshair.Route); + if (rnd_tool_next_id != pcb_crosshair.tool_arc) { + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_FIRST; + if (!pcb_marked.user_placed) + pcb_crosshair_set_local_ref(0, 0, rnd_false); + } + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +/* creates points of a line (when clicked) */ +static void notify_line(rnd_hidlib_t *hl) +{ + int type = PCB_OBJ_VOID; + void *ptr1, *ptr2, *ptr3; + pcb_board_t *pcb = (pcb_board_t *)hl; + + if ((!pcb_marked.status || conf_core.editor.local_ref) && !pcb_marked.user_placed) + pcb_crosshair_set_local_ref(pcb_crosshair.X, pcb_crosshair.Y, rnd_true); + switch (pcb_crosshair.AttachedLine.State) { + case PCB_CH_STATE_FIRST: /* first point */ + if (pcb->RatDraw) { + /* prefer light terminal but also check for heavy terminals */ + if ((type = pcb_search_screen(pcb_crosshair.X, pcb_crosshair.Y, PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART, &ptr1, &ptr2, &ptr3)) == PCB_OBJ_VOID) + type = pcb_search_screen(pcb_crosshair.X, pcb_crosshair.Y, PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_SUBC_PART, &ptr1, &ptr2, &ptr3); + /* but make sure it is a terminal, not a via or plain object */ + if ((type == PCB_OBJ_VOID) || (((pcb_any_obj_t *)ptr2)->term == NULL)) { + rnd_gui->beep(rnd_gui); + break; + } + } + if (conf_core.editor.auto_drc) { + pcb_find_t fctx; + if (type == PCB_OBJ_VOID) + type = pcb_search_screen(pcb_crosshair.X, pcb_crosshair.Y, PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART, &ptr1, &ptr2, &ptr3); + memset(&fctx, 0, sizeof(fctx)); + fctx.flag_set = PCB_FLAG_FOUND; + fctx.flag_chg_undoable = 1; + pcb_find_from_xy(&fctx, pcb->Data, pcb_crosshair.X, pcb_crosshair.Y); + pcb_find_free(&fctx); + } + if (type == PCB_OBJ_PSTK) { + pcb_pstk_t *pstk = (pcb_pstk_t *)ptr2; + pcb_crosshair.AttachedLine.Point1.X = pstk->x; + pcb_crosshair.AttachedLine.Point1.Y = pstk->y; + } + else { + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X = pcb_crosshair.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y = pcb_crosshair.Y; + } + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_SECOND; + break; + + case PCB_CH_STATE_SECOND: + /* fall through to third state too */ + last_layer = PCB_CURRLAYER(pcb); + default: /* all following points */ + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_THIRD; + break; + } +} + +void pcb_tool_line_notify_mode(rnd_hidlib_t *hl) +{ + void *ptr1, *ptr2, *ptr3; + pcb_board_t *pcb = (pcb_board_t *)hl; + + /* do update of position */ + notify_line(hl); + if (pcb_crosshair.AttachedLine.State != PCB_CH_STATE_THIRD) + return; + /* Remove anchor if clicking on start point; + * this means we can't paint 0 length lines + * which could be used for square SMD pads. + * Instead use a very small delta, or change + * the file after saving. + */ + if (pcb_crosshair.X == pcb_crosshair.AttachedLine.Point1.X && pcb_crosshair.Y == pcb_crosshair.AttachedLine.Point1.Y) { + rnd_tool_select_by_name(hl, "line"); + return; + } + + if (pcb->RatDraw) { + pcb_rat_t *line = pcb_net_create_by_rat_coords(pcb, pcb_crosshair.AttachedLine.Point1.X, pcb_crosshair.AttachedLine.Point1.Y, pcb_crosshair.AttachedLine.Point2.X, pcb_crosshair.AttachedLine.Point2.Y, 1); + + if (line != NULL) { + pcb_added_lines++; + pcb_undo_add_obj_to_create(PCB_OBJ_RAT, line, line, line); + pcb_undo_inc_serial(); + pcb_rat_invalidate_draw(line); + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y; + pcb_draw(); + } + return; + } + else if(pcb_crosshair.Route.size > 0) + { + pcb_pstk_t *ps = NULL; + + /* place a via if vias are visible, the layer is + in a new group since the last line and there + isn't a pin already here */ +TODO("pstk #21: do not work in comp mode, use a pstk proto - scconfig also has TODO #21, fix it there too") + if (conf_core.editor.auto_via && pcb->pstk_on + && pcb_layer_get_group_(PCB_CURRLAYER(pcb)) != pcb_layer_get_group_(last_layer) + && pcb_search_obj_by_location(PCB_OBJ_CLASS_PIN, &ptr1, &ptr2, &ptr3, + pcb_crosshair.AttachedLine.Point1.X, + pcb_crosshair.AttachedLine.Point1.Y, + conf_core.design.via_thickness / 2) == + PCB_OBJ_VOID + && (pcb_layer_flags_(PCB_CURRLAYER(pcb)) & PCB_LYT_COPPER) + && (pcb_layer_flags_(last_layer) & PCB_LYT_COPPER) + && (!pcb->is_footprint) + && ((ps = pcb_pstk_new_compat_via(pcb->Data, -1, + pcb_crosshair.AttachedLine.Point1.X, + pcb_crosshair.AttachedLine.Point1.Y, + conf_core.design.via_drilling_hole, conf_core.design.via_thickness, conf_core.design.clearance, + 0, PCB_PSTK_COMPAT_ROUND, rnd_true)) != NULL)) { + pcb_obj_add_attribs((pcb_any_obj_t *)ps, pcb->pen_attr, NULL); + pcb_undo_add_obj_to_create(PCB_OBJ_PSTK, ps, ps, ps); + } + + /* Add the route to the design */ + pcb_route_apply(&pcb_crosshair.Route); + + /* move to new start point */ + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.Route.end_point.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.Route.end_point.Y; + pcb_crosshair.AttachedLine.Point2.X = pcb_crosshair.Route.end_point.X; + pcb_crosshair.AttachedLine.Point2.Y = pcb_crosshair.Route.end_point.Y; + + /* automatic swap of line refraction after each click - should work only if refraction is in effect (no ortho, no alldir) */ + if (conf_core.editor.swap_start_direction && (conf_core.editor.line_refraction != 0) && !conf_core.editor.all_direction_lines) + rnd_conf_setf(RND_CFR_DESIGN,"editor/line_refraction", -1, "%d",conf_core.editor.line_refraction ^ 3); + + if (conf_core.editor.orthogonal_moves) { + /* set the mark to the new starting point so ortho works as expected and we can draw a perpendicular line from here */ + hl->tool_grabbed.X = pcb_crosshair.Route.end_point.X; + hl->tool_grabbed.Y = pcb_crosshair.Route.end_point.Y; + hl->tool_grabbed.status = rnd_true; + } + + if (ps) + pcb_pstk_invalidate_draw(ps); + + pcb_draw(); + pcb_undo_inc_serial(); + last_layer = PCB_CURRLAYER(pcb); + } + else + /* create line if both ends are determined && length != 0 */ + { + pcb_line_t *line; + int maybe_found_flag; + + if (conf_core.editor.line_refraction + && pcb_crosshair.AttachedLine.Point1.X == + pcb_crosshair.AttachedLine.Point2.X + && pcb_crosshair.AttachedLine.Point1.Y == + pcb_crosshair.AttachedLine.Point2.Y + && (pcb_crosshair.AttachedLine.Point2.X != hl->tool_x || pcb_crosshair.AttachedLine.Point2.Y != hl->tool_y)) { + /* We will only need to paint the second line segment. + Since we only check for vias on the first segment, + swap them so the non-empty segment is the first segment. */ + pcb_crosshair.AttachedLine.Point2.X = hl->tool_x; + pcb_crosshair.AttachedLine.Point2.Y = hl->tool_y; + } + + if (conf_core.editor.auto_drc + && (pcb_layer_flags_(PCB_CURRLAYER(pcb)) & PCB_LYT_COPPER)) + maybe_found_flag = PCB_FLAG_FOUND; + else + maybe_found_flag = 0; + + if ((pcb_crosshair.AttachedLine.Point1.X != + pcb_crosshair.AttachedLine.Point2.X || pcb_crosshair.AttachedLine.Point1.Y != pcb_crosshair.AttachedLine.Point2.Y) + && (line = + pcb_line_new_merge(pcb_loose_subc_layer(pcb, PCB_CURRLAYER(pcb), rnd_true), + pcb_crosshair.AttachedLine.Point1.X, + pcb_crosshair.AttachedLine.Point1.Y, + pcb_crosshair.AttachedLine.Point2.X, + pcb_crosshair.AttachedLine.Point2.Y, + conf_core.design.line_thickness, + 2 * conf_core.design.clearance, + pcb_flag_make(maybe_found_flag | + (conf_core.editor.clear_line ? PCB_FLAG_CLEARLINE : 0)))) != NULL) { + pcb_pstk_t *ps = NULL; + + pcb_added_lines++; + pcb_obj_add_attribs((pcb_any_obj_t *)line, pcb->pen_attr, NULL); + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, PCB_CURRLAYER(pcb), line, line); + pcb_line_invalidate_draw(PCB_CURRLAYER(pcb), line); + /* place a via if vias are visible, the layer is + in a new group since the last line and there + isn't a pin already here */ +TODO("pstk #21: do not work in comp mode, use a pstk proto - scconfig also has TODO #21, fix it there too") + if (pcb->pstk_on + && pcb_layer_get_group_(PCB_CURRLAYER(pcb)) != pcb_layer_get_group_(last_layer) + && (pcb_layer_flags_(PCB_CURRLAYER(pcb)) & PCB_LYT_COPPER) + && (pcb_layer_flags_(last_layer) & PCB_LYT_COPPER) + && (!pcb->is_footprint) + && pcb_search_obj_by_location(PCB_OBJ_CLASS_PIN, &ptr1, &ptr2, &ptr3, + pcb_crosshair.AttachedLine.Point1.X, + pcb_crosshair.AttachedLine.Point1.Y, + conf_core.design.via_thickness / 2) == PCB_OBJ_VOID + && ((ps = pcb_pstk_new_compat_via(pcb->Data, -1, + pcb_crosshair.AttachedLine.Point1.X, + pcb_crosshair.AttachedLine.Point1.Y, + conf_core.design.via_drilling_hole, conf_core.design.via_thickness, conf_core.design.clearance, + 0, PCB_PSTK_COMPAT_ROUND, rnd_true)) != NULL)) { + pcb_obj_add_attribs((pcb_any_obj_t *)ps, pcb->pen_attr, NULL); + pcb_undo_add_obj_to_create(PCB_OBJ_PSTK, ps, ps, ps); + pcb_pstk_invalidate_draw(ps); + } + /* copy the coordinates */ + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y; + pcb_undo_inc_serial(); + last_layer = PCB_CURRLAYER(pcb); + pcb_subc_as_board_update(PCB); + } + if (conf_core.editor.line_refraction && (hl->tool_x != pcb_crosshair.AttachedLine.Point2.X || hl->tool_y != pcb_crosshair.AttachedLine.Point2.Y) + && (line = + pcb_line_new_merge(pcb_loose_subc_layer(pcb, PCB_CURRLAYER(pcb), rnd_true), + pcb_crosshair.AttachedLine.Point2.X, + pcb_crosshair.AttachedLine.Point2.Y, + hl->tool_x, hl->tool_y, + conf_core.design.line_thickness, + 2 * conf_core.design.clearance, + pcb_flag_make((conf_core.editor.auto_drc ? PCB_FLAG_FOUND : 0) | + (conf_core.editor.clear_line ? PCB_FLAG_CLEARLINE : 0)))) != NULL) { + pcb_added_lines++; + pcb_obj_add_attribs((pcb_any_obj_t *)line, pcb->pen_attr, NULL); + pcb_undo_add_obj_to_create(PCB_OBJ_LINE, PCB_CURRLAYER(pcb), line, line); + pcb_undo_inc_serial(); + pcb_line_invalidate_draw(PCB_CURRLAYER(pcb), line); + /* move to new start point */ + pcb_crosshair.AttachedLine.Point1.X = hl->tool_x; + pcb_crosshair.AttachedLine.Point1.Y = hl->tool_y; + pcb_crosshair.AttachedLine.Point2.X = hl->tool_x; + pcb_crosshair.AttachedLine.Point2.Y = hl->tool_y; + + + if (conf_core.editor.swap_start_direction) { + rnd_conf_setf(RND_CFR_DESIGN,"editor/line_refraction", -1, "%d",conf_core.editor.line_refraction ^ 3); + } + pcb_subc_as_board_update(PCB); + } + if (conf_core.editor.orthogonal_moves) { + /* set the mark to the new starting point so ortho works as expected and we can draw a perpendicular line from here */ + pcb_marked.X = hl->tool_x; + pcb_marked.Y = hl->tool_y; + } + pcb_draw(); + } +} + +void pcb_tool_line_adjust_attached_objects(rnd_hidlib_t *hl) +{ + /* don't draw outline when ctrl key is pressed */ + if (rnd_gui->control_is_pressed(rnd_gui)) { + pcb_crosshair.AttachedLine.draw = rnd_false; + } + else { + pcb_crosshair.AttachedLine.draw = rnd_true; + pcb_line_adjust_attached(); + } +} + +void pcb_tool_line_draw_attached(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + + if (pcb->RatDraw) { + /* draw only if starting point exists and the line has length */ + if (pcb_crosshair.AttachedLine.State != PCB_CH_STATE_FIRST && pcb_crosshair.AttachedLine.draw) + pcb_draw_wireframe_line(pcb_crosshair.GC, + pcb_crosshair.AttachedLine.Point1.X, pcb_crosshair.AttachedLine.Point1.Y, + pcb_crosshair.AttachedLine.Point2.X, pcb_crosshair.AttachedLine.Point2.Y, + 10, 0); + } + else if (pcb_crosshair.Route.size > 0) { + pcb_route_draw(&pcb_crosshair.Route,pcb_crosshair.GC); + if (conf_core.editor.show_drc) + pcb_route_draw_drc(&pcb_crosshair.Route,pcb_crosshair.GC); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } + else { + /* Draw a circle (0 length line) to show where the line will be placed */ + if (PCB_CURRLAYER(pcb)) + rnd_render->set_color(pcb_crosshair.GC, &PCB_CURRLAYER(pcb)->meta.real.color); + + pcb_draw_wireframe_line(pcb_crosshair.GC, + pcb_crosshair.X, pcb_crosshair.Y, + pcb_crosshair.X, pcb_crosshair.Y, + conf_core.design.line_thickness,0 ); + + if (conf_core.editor.show_drc) { + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + pcb_draw_wireframe_line(pcb_crosshair.GC, + pcb_crosshair.X, pcb_crosshair.Y, + pcb_crosshair.X, pcb_crosshair.Y, + conf_core.design.line_thickness + (2 * conf_core.design.clearance), 0); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } + } +} + +rnd_bool pcb_tool_line_undo_act(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + + if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_SECOND) { + if (conf_core.editor.auto_drc) + pcb_undo(rnd_true); /* undo the connection find */ + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_FIRST; + pcb_route_reset(&pcb_crosshair.Route); + if (!pcb_marked.user_placed) + pcb_crosshair_set_local_ref(0, 0, rnd_false); + return rnd_false; + } + if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_THIRD) { + int type; + void *ptr1, *ptr3, *ptrtmp; + pcb_line_t *ptr2; + ptrtmp = &pcb_crosshair.AttachedLine; /* a workaround for the line undo bug */ + /* this search is guaranteed to succeed */ + pcb_search_obj_by_location(PCB_OBJ_LINE | PCB_OBJ_RAT, &ptr1, + &ptrtmp, &ptr3, pcb_crosshair.AttachedLine.Point1.X, pcb_crosshair.AttachedLine.Point1.Y, 0); + ptr2 = (pcb_line_t *) ptrtmp; + + /* save both ends of line */ + pcb_crosshair.AttachedLine.Point2.X = ptr2->Point1.X; + pcb_crosshair.AttachedLine.Point2.Y = ptr2->Point1.Y; + if ((type = pcb_undo(rnd_true)) == 0) + pcb_board_set_changed_flag(pcb, rnd_true); + /* check that the undo was of the right type */ + if ((type & PCB_UNDO_CREATE) == 0) { + /* wrong undo type, restore anchor points */ + pcb_crosshair.AttachedLine.Point2.X = pcb_crosshair.AttachedLine.Point1.X; + pcb_crosshair.AttachedLine.Point2.Y = pcb_crosshair.AttachedLine.Point1.Y; + return rnd_false; + } + /* move to new anchor */ + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y; + /* check if an intermediate point was removed */ + if (type & PCB_UNDO_REMOVE) { + /* this search should find the restored line */ + pcb_search_obj_by_location(PCB_OBJ_LINE | PCB_OBJ_RAT, &ptr1, &ptrtmp, &ptr3, pcb_crosshair.AttachedLine.Point2.X, pcb_crosshair.AttachedLine.Point2.Y, 0); + ptr2 = (pcb_line_t *) ptrtmp; + if (conf_core.editor.auto_drc) { + /* undo loses PCB_FLAG_FOUND */ + PCB_FLAG_SET(PCB_FLAG_FOUND, ptr2); + pcb_line_invalidate_draw(PCB_CURRLAYER(pcb), ptr2); + } + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X = ptr2->Point2.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y = ptr2->Point2.Y; + } + pcb_crosshair_grid_fit(pcb, pcb_crosshair.X, pcb_crosshair.Y); + rnd_tool_adjust_attached(hl); + if (--pcb_added_lines == 0) { + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_SECOND; + last_layer = PCB_CURRLAYER(pcb); + } + else { + /* this search is guaranteed to succeed too */ + pcb_search_obj_by_location(PCB_OBJ_LINE | PCB_OBJ_RAT, &ptr1, &ptrtmp, &ptr3, pcb_crosshair.AttachedLine.Point1.X, pcb_crosshair.AttachedLine.Point1.Y, 0); + ptr2 = (pcb_line_t *) ptrtmp; + last_layer = (pcb_layer_t *) ptr1; + } + return rnd_false; + } + return rnd_true; +} + +rnd_bool pcb_tool_line_redo_act(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + + if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_SECOND) + return rnd_false; + if (pcb_redo(rnd_true)) { + pcb_board_set_changed_flag(pcb, rnd_true); + if (pcb_crosshair.AttachedLine.State != PCB_CH_STATE_FIRST) { + pcb_line_t *line = linelist_last(&PCB_CURRLAYER(pcb)->Line); + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X = line->Point2.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y = line->Point2.Y; + pcb_added_lines++; + } + } + return rnd_false; +} + +void pcb_tool_line_escape(rnd_hidlib_t *hl) +{ + if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_FIRST) + rnd_tool_select_by_name(hl, "arrow"); + else + rnd_tool_select_by_name(hl, "line"); +} + +/* XPM */ +static const char *line_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c #000000", +". c #7A8584", +"X c #6EA5D7", +"O c None", +/* pixels */ +"OOOOOOOOOOOOOOOOOOOOO", +"OO...OOOOOOOOOOOOOOOO", +"O.OOO.OOOOOOOOOOOOOOO", +"O.OXXXOOOOOOOOOOOOOOO", +"O.OOO.XXXOOOOOOOOOOOO", +"OO...OOOOXXXOOOO...OO", +"OOOOOOOOOOOOXXX.OOO.O", +"OOOOOOOOOOOOOOOXXXO.O", +"OOOOOOOOOOOOOOO.OOO.O", +"OOOOOOOOOOOOOOOO...OO", +"OOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOO", +" OOOO O OOOO O O", +" OOOOO OO OOO O OOOO", +" OOOOO OO O OO O OOOO", +" OOOOO OO O OO O OOOO", +" OOOOO OO OO O O OO", +" OOOOO OO OO O O OOOO", +" OOOOO OO OOO O OOOO", +" O O OOOO O O", +"OOOOOOOOOOOOOOOOOOOOO" +}; + + +rnd_tool_t pcb_tool_line = { + "line", NULL, NULL, 100, line_icon, RND_TOOL_CURSOR_NAMED("pencil"), 0, + pcb_tool_line_init, + pcb_tool_line_uninit, + pcb_tool_line_notify_mode, + NULL, + pcb_tool_line_adjust_attached_objects, + pcb_tool_line_draw_attached, + pcb_tool_line_undo_act, + pcb_tool_line_redo_act, + pcb_tool_line_escape, + + PCB_TLF_RAT +}; Index: tags/2.3.0/src_plugins/tool_std/tool_line.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_line.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_line.h (revision 33253) @@ -0,0 +1,9 @@ +extern rnd_tool_t pcb_tool_line; + +void pcb_tool_line_init(void); +void pcb_tool_line_uninit(void); +void pcb_tool_line_notify_mode(rnd_hidlib_t *hl); +void pcb_tool_line_adjust_attached_objects(rnd_hidlib_t *hl); +void pcb_tool_line_draw_attached(rnd_hidlib_t *hl); +rnd_bool pcb_tool_line_undo_act(rnd_hidlib_t *hl); +rnd_bool pcb_tool_line_redo_act(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_lock.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_lock.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_lock.c (revision 33253) @@ -0,0 +1,139 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" + +#include "board.h" +#include "change.h" +#include "data.h" +#include "draw.h" +#include +#include "search.h" +#include +#include "tool_logic.h" +#include "tool_lock.h" + +#define PCB_OBJ_CLASS_LOCK (PCB_OBJ_PSTK | PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_SUBC | PCB_OBJ_TEXT | PCB_OBJ_LOCKED) + +void pcb_tool_lock_notify_mode(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + void *ptr1, *ptr2, *ptr3; + int type; + + type = pcb_search_screen_maybe_selector(hl->tool_x, hl->tool_y, PCB_OBJ_CLASS_LOCK, &ptr1, &ptr2, &ptr3); + + if (type == PCB_OBJ_SUBC) { + pcb_subc_t *subc = (pcb_subc_t *)ptr2; + pcb_flag_change(pcb, PCB_CHGFLG_TOGGLE, PCB_FLAG_LOCK, PCB_OBJ_SUBC, ptr1, ptr2, ptr3); + pcb_board_set_changed_flag(pcb, rnd_true); + pcb_undo_inc_serial(); + + DrawSubc(subc); + pcb_draw(); + rnd_actionva(hl, "Report", "Subc", "log", NULL); + } + else if (type != PCB_OBJ_VOID) { + pcb_text_t *thing = (pcb_text_t *) ptr3; + PCB_FLAG_TOGGLE(PCB_FLAG_LOCK, thing); + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, thing) + && PCB_FLAG_TEST(PCB_FLAG_SELECTED, thing)) { + /* this is not un-doable since LOCK isn't */ + PCB_FLAG_CLEAR(PCB_FLAG_SELECTED, thing); + pcb_undo_inc_serial(); + pcb_draw_obj((pcb_any_obj_t *)ptr2); + pcb_draw(); + pcb_board_set_changed_flag(pcb, rnd_true); + } + rnd_actionva(hl, "Report", "Object", "log", NULL); + } +} + +/* XPM */ +static const char *lock_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 2 1", +" c black", +"X c None", +/* pixels */ +"XXXXXXXX XXXXXXXX", +"XXXXXXX XXX XXXXXXX", +"XXXXXXX XXXXX XXXXXXX", +"XXXXXX XXXXX XXXXXX", +"XXXXXX XXXXXXX XXXXXX", +"XXXXXX XXXXXXX XXXXXX", +"XXXX XXXX", +"XXXX XXXXXXXXXXX XXXX", +"XXXX XXXX", +"XXXX XXXXXXXXXXX XXXX", +"XXXX XXXX", +"XXXX XXXXXXXXXXX XXXX", +"XXXX XXXX", +"XXXXXXXXXXXXXXXXXXXXX", +"XX XXXX XXX X XX XX", +"XX XXX XX X XXX XX XX", +"XX XXX XX X XXX X XXX", +"XX XXX XX X XXX XXXX", +"XX XXX XX X XXX X XXX", +"XX XXX XX X XXX XX XX", +"XX XX XXX X XX XX" +}; + +#define lockIcon_width 16 +#define lockIcon_height 16 +static unsigned char lockIcon_bits[] = { + 0x00, 0x00, 0xe0, 0x07, 0x30, 0x0c, 0x10, 0x08, 0x18, 0x18, 0x08, 0x10, + 0x08, 0x00, 0xfc, 0x3f, 0x04, 0x20, 0xfc, 0x3f, 0x04, 0x20, 0xfc, 0x3f, + 0x04, 0x20, 0xfc, 0x3f, 0x04, 0x20, 0xfc, 0x3f}; +#define lockMask_width 16 +#define lockMask_height 16 +static unsigned char lockMask_bits[] = { + 0xf0, 0x0f, 0xf0, 0x0f, 0xf8, 0x1f, 0x38, 0x1c, 0x1c, 0x3c, 0x1c, 0x38, + 0x1c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, + 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f}; + +rnd_tool_t pcb_tool_lock = { + "lock", NULL, NULL, 100, lock_icon, RND_TOOL_CURSOR_XBM(lockIcon_bits, lockMask_bits), 0, + NULL, + NULL, + pcb_tool_lock_notify_mode, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* escape */ + + PCB_TLF_RAT +}; Index: tags/2.3.0/src_plugins/tool_std/tool_lock.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_lock.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_lock.h (revision 33253) @@ -0,0 +1,3 @@ +extern rnd_tool_t pcb_tool_lock; + +void pcb_tool_lock_notify_mode(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_move.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_move.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_move.c (revision 33253) @@ -0,0 +1,178 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" + +#include "board.h" +#include "move.h" +#include "crosshair.h" +#include "search.h" +#include "tool_logic.h" +#include +#include "extobj.h" +#include "obj_gfx.h" +#include "undo.h" + +void pcb_tool_move_uninit(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + pcb_crosshair_attached_clean(&PCB->hidlib); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); + pcb_crosshair.extobj_edit = NULL; +} + +void pcb_tool_move_notify_mode(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + rnd_coord_t dx, dy; + + switch (pcb_crosshair.AttachedObject.State) { + /* first notify, lookup object */ + case PCB_CH_STATE_FIRST: + { + int types = PCB_MOVE_TYPES; + + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = + pcb_search_screen(hl->tool_x, hl->tool_y, types, + &pcb_crosshair.AttachedObject.Ptr1, &pcb_crosshair.AttachedObject.Ptr2, &pcb_crosshair.AttachedObject.Ptr3); + if (pcb_crosshair.AttachedObject.Type != PCB_OBJ_VOID) { + pcb_any_obj_t *obj = (pcb_any_obj_t *)pcb_crosshair.AttachedObject.Ptr2; + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, obj)) { + rnd_message(RND_MSG_WARNING, "Sorry, %s object is locked\n", pcb_obj_type_name(obj->type)); + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.extobj_edit = NULL; + } + else + pcb_tool_attach_for_copy(hl, hl->tool_x, hl->tool_y, rnd_true); + } + break; + } + + /* second notify, move object */ + case PCB_CH_STATE_SECOND: + dx = pcb_crosshair.AttachedObject.tx - pcb_crosshair.AttachedObject.X; + dy = pcb_crosshair.AttachedObject.ty - pcb_crosshair.AttachedObject.Y; + if (pcb_crosshair.AttachedObject.Type == PCB_OBJ_GFX_POINT) { + pcb_gfx_t *gfx = pcb_crosshair.AttachedObject.Ptr2; + rnd_point_t *point = (rnd_point_t *)pcb_crosshair.AttachedObject.Ptr3; + int point_idx = point - gfx->corner; + pcb_gfx_resize_move_corner(gfx, point_idx, dx, dy, 1); + } + else if ((dx != 0) || (dy != 0)) { + pcb_any_obj_t *newo; + + if ((pcb_crosshair.AttachedObject.Type == PCB_OBJ_POLY_POINT) && pcb_crosshair.edit_poly_point_extra.active) { + int n; + + /* when modifier was pressed during the moving of a polygon point: + angle-keeping move; this is really just moving 3 points in a batch */ + pcb_undo_freeze_serial(); + newo = pcb_move_obj_and_rubberband(pcb_crosshair.AttachedObject.Type, pcb_crosshair.AttachedObject.Ptr1, pcb_crosshair.AttachedObject.Ptr2, pcb_crosshair.AttachedObject.Ptr3, dx, dy); + pcb_extobj_float_geo(newo); + for(n = 0; n < 2; n++) { + newo = pcb_move_obj_and_rubberband(PCB_OBJ_POLY_POINT, pcb_crosshair.AttachedObject.Ptr1, pcb_crosshair.AttachedObject.Ptr2, pcb_crosshair.edit_poly_point_extra.point[n], pcb_crosshair.edit_poly_point_extra.dx[n], pcb_crosshair.edit_poly_point_extra.dy[n]); + pcb_extobj_float_geo(newo); + } + pcb_undo_unfreeze_serial(); + } + else { + newo = pcb_move_obj_and_rubberband(pcb_crosshair.AttachedObject.Type, pcb_crosshair.AttachedObject.Ptr1, pcb_crosshair.AttachedObject.Ptr2, pcb_crosshair.AttachedObject.Ptr3, dx, dy); + pcb_extobj_float_pre(newo); + pcb_extobj_float_geo(newo); + } + + if (!pcb_marked.user_placed) + pcb_crosshair_set_local_ref(0, 0, rnd_false); + pcb_subc_as_board_update(PCB); + pcb_board_set_changed_flag(pcb, rnd_true); + } + else if (pcb_crosshair.extobj_edit != NULL) + pcb_extobj_float_geo(pcb_crosshair.extobj_edit); + + /* reset identifiers */ + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_FIRST; + pcb_crosshair.extobj_edit = NULL; + break; + } +} + +void pcb_tool_move_release_mode(rnd_hidlib_t *hl) +{ + if (hl->tool_hit) { + pcb_line_mod_merge_inhibit_inc((pcb_board_t *)hl); + pcb_tool_move_notify_mode(hl); + hl->tool_hit = 0; + pcb_line_mod_merge_inhibit_dec((pcb_board_t *)hl); + } +} + +void pcb_tool_move_adjust_attached_objects(rnd_hidlib_t *hl) +{ + pcb_crosshair.AttachedObject.tx = pcb_crosshair.X; + pcb_crosshair.AttachedObject.ty = pcb_crosshair.Y; +} + +void pcb_tool_move_draw_attached(rnd_hidlib_t *hl) +{ + pcb_xordraw_movecopy(rnd_gui->control_is_pressed(rnd_gui)); +} + +rnd_bool pcb_tool_move_undo_act(rnd_hidlib_t *hl) +{ + /* don't allow undo in the middle of an operation */ + if (pcb_crosshair.AttachedObject.State != PCB_CH_STATE_FIRST) + return rnd_false; + return rnd_true; +} + +rnd_tool_t pcb_tool_move = { + "move", NULL, NULL, 100, NULL, RND_TOOL_CURSOR_NAMED("crosshair"), 0, + NULL, + pcb_tool_move_uninit, + pcb_tool_move_notify_mode, + pcb_tool_move_release_mode, + pcb_tool_move_adjust_attached_objects, + pcb_tool_move_draw_attached, + pcb_tool_move_undo_act, + NULL, + NULL, /* escape */ + + 0 +}; Index: tags/2.3.0/src_plugins/tool_std/tool_move.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_move.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_move.h (revision 33253) @@ -0,0 +1,7 @@ +extern rnd_tool_t pcb_tool_move; + +void pcb_tool_move_uninit(void); +void pcb_tool_move_notify_mode(rnd_hidlib_t *hl); +void pcb_tool_move_release_mode(rnd_hidlib_t *hl); +void pcb_tool_move_draw_attached(rnd_hidlib_t *hl); +rnd_bool pcb_tool_move_undo_act(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_poly.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_poly.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_poly.c (revision 33253) @@ -0,0 +1,202 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" +#include "conf_core.h" + +#include "board.h" +#include "crosshair.h" +#include +#include "polygon.h" +#include + + +void pcb_tool_poly_uninit(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + pcb_crosshair.AttachedPolygon.PointN = 0; + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_FIRST; + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +void pcb_tool_poly_notify_mode(rnd_hidlib_t *hl) +{ + rnd_point_t *points = pcb_crosshair.AttachedPolygon.Points; + rnd_cardinal_t n = pcb_crosshair.AttachedPolygon.PointN; + + /* do update of position */ + if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_FIRST) { + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X = pcb_crosshair.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y = pcb_crosshair.Y; + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_THIRD; + pcb_crosshair.AttachedPolygon_pts = 0; + } + + /* check if this is the last point of a polygon */ + if (n >= 3 && points[0].X == pcb_crosshair.AttachedLine.Point2.X && points[0].Y == pcb_crosshair.AttachedLine.Point2.Y) { + rnd_actionva(hl, "Polygon", "Close", NULL); + return; + } + + /* Someone clicking twice on the same point ('doubleclick'): close polygon */ + if (n >= 3 && points[n - 1].X == pcb_crosshair.AttachedLine.Point2.X && points[n - 1].Y == pcb_crosshair.AttachedLine.Point2.Y) { + rnd_actionva(hl, "Polygon", "Close", NULL); + return; + } + + /* create new point if it's the first one or if it's + * different to the last one + */ + if (!n || points[n - 1].X != pcb_crosshair.AttachedLine.Point2.X || points[n - 1].Y != pcb_crosshair.AttachedLine.Point2.Y) { + pcb_poly_point_new(&pcb_crosshair.AttachedPolygon, pcb_crosshair.AttachedLine.Point2.X, pcb_crosshair.AttachedLine.Point2.Y); + pcb_crosshair.AttachedPolygon_pts = pcb_crosshair.AttachedPolygon.PointN; + + /* copy the coordinates */ + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y; + } + + if (conf_core.editor.orthogonal_moves) { + /* set the mark to the new starting point so ortho works */ + hl->tool_grabbed.X = hl->tool_x; + hl->tool_grabbed.Y = hl->tool_y; + hl->tool_grabbed.status = rnd_true; + } +} + +void pcb_tool_poly_adjust_attached_objects(rnd_hidlib_t *hl) +{ + pcb_attached_line_t *line = &pcb_crosshair.AttachedLine; + + if (rnd_gui->control_is_pressed(rnd_gui)) { + line->draw = rnd_false; + return; + } + else + line->draw = rnd_true; + if (conf_core.editor.all_direction_lines) { + line->Point2.X = pcb_crosshair.X; + line->Point2.Y = pcb_crosshair.Y; + return; + } + + pcb_line_45(line); +} + +void pcb_tool_poly_draw_attached(rnd_hidlib_t *hl) +{ + /* draw only if starting point is set */ + if (pcb_crosshair.AttachedLine.State != PCB_CH_STATE_FIRST) + rnd_render->draw_line(pcb_crosshair.GC, + pcb_crosshair.AttachedLine.Point1.X, + pcb_crosshair.AttachedLine.Point1.Y, pcb_crosshair.AttachedLine.Point2.X, pcb_crosshair.AttachedLine.Point2.Y); + + /* draw attached polygon only if in polygon or polygon_hole tool */ + if (pcb_crosshair.AttachedPolygon.PointN > 1) { + pcb_xordraw_poly(&pcb_crosshair.AttachedPolygon, 0, 0, 1); + } +} + +rnd_bool pcb_tool_poly_undo_act(rnd_hidlib_t *hl) +{ + if (pcb_crosshair.AttachedPolygon.PointN) { + pcb_polygon_go_to_prev_point(); + return rnd_false; + } + return rnd_true; +} + +rnd_bool pcb_tool_poly_redo_act(rnd_hidlib_t *hl) +{ + if (pcb_crosshair.AttachedPolygon.PointN) { + pcb_polygon_go_to_next_point(); + return rnd_false; + } + else + return rnd_true; +} + +void pcb_tool_poly_escape(rnd_hidlib_t *hl) +{ + if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_FIRST) + rnd_tool_select_by_name(hl, "arrow"); + else + rnd_tool_select_by_name(hl, "poly"); +} + +/* XPM */ +static const char *poly_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c black", +". c #6EA5D7", +"o c None", +/* pixels */ +"ooooooooooo.ooooooooo", +"oooooooooo..ooooooooo", +"ooooooooo...ooooooooo", +"oooooooo....ooooooooo", +"ooooooo.....ooooooooo", +"oooooo.......oooooooo", +"ooooo.........ooooooo", +"oooo...........oooooo", +"oooo............ooooo", +"oooo.............oooo", +"oooo..............ooo", +"ooooooooooooooooooooo", +"o ooo oo oo ooo ", +"o ooo o ooo o oo ooo ", +"o ooo o ooo o ooo o o", +"o oo ooo o oooo oo", +"o ooooo ooo o oooo oo", +"o ooooo ooo o oooo oo", +"o ooooo ooo o oooo oo", +"o oooooo oo o oo", +"ooooooooooooooooooooo" +}; + +rnd_tool_t pcb_tool_poly = { + "poly", NULL, NULL, 100, poly_icon, RND_TOOL_CURSOR_NAMED("up_arrow"), 0, + NULL, + pcb_tool_poly_uninit, + pcb_tool_poly_notify_mode, + NULL, + pcb_tool_poly_adjust_attached_objects, + pcb_tool_poly_draw_attached, + pcb_tool_poly_undo_act, + pcb_tool_poly_redo_act, + pcb_tool_poly_escape, + + 0 +}; Index: tags/2.3.0/src_plugins/tool_std/tool_poly.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_poly.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_poly.h (revision 33253) @@ -0,0 +1,8 @@ +extern rnd_tool_t pcb_tool_poly; + +void pcb_tool_poly_uninit(void); +void pcb_tool_poly_notify_mode(rnd_hidlib_t *hl); +void pcb_tool_poly_adjust_attached_objects(rnd_hidlib_t *hl); +void pcb_tool_poly_draw_attached(rnd_hidlib_t *hl); +rnd_bool pcb_tool_poly_undo_act(rnd_hidlib_t *hl); +rnd_bool pcb_tool_poly_redo_act(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_polyhole.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_polyhole.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_polyhole.c (revision 33253) @@ -0,0 +1,233 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" +#include "conf_core.h" + +#include "board.h" +#include "crosshair.h" +#include +#include "polygon.h" +#include "search.h" +#include + + +void pcb_tool_polyhole_uninit(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + pcb_crosshair.AttachedPolygon.PointN = 0; + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_FIRST; + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +void pcb_tool_polyhole_notify_mode(rnd_hidlib_t *hl) +{ + switch (pcb_crosshair.AttachedObject.State) { + /* first notify, lookup object */ + case PCB_CH_STATE_FIRST: + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedPolygon_pts = 0; + pcb_crosshair.AttachedObject.Type = + pcb_search_screen_maybe_selector(hl->tool_x, hl->tool_y, PCB_OBJ_POLY, + &pcb_crosshair.AttachedObject.Ptr1, &pcb_crosshair.AttachedObject.Ptr2, &pcb_crosshair.AttachedObject.Ptr3); + + if (pcb_crosshair.AttachedObject.Type == PCB_OBJ_VOID) { + rnd_message(RND_MSG_WARNING, "The first point of a polygon hole must be on a polygon.\n"); + break; /* don't start doing anything if clicket out of polys */ + } + + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, (pcb_poly_t *)pcb_crosshair.AttachedObject.Ptr2)) { + rnd_message(RND_MSG_WARNING, "Sorry, poly object is locked\n"); + pcb_crosshair_attached_clean(hl); + pcb_crosshair.AttachedObject.Type = PCB_OBJ_VOID; + pcb_crosshair.extobj_edit = NULL; + break; + } + else + pcb_crosshair.AttachedObject.State = PCB_CH_STATE_SECOND; + /* fall thru: first click is also the first point of the poly hole */ + + /* second notify, insert new point into object */ + case PCB_CH_STATE_SECOND: + { + rnd_point_t *points = pcb_crosshair.AttachedPolygon.Points; + rnd_cardinal_t n = pcb_crosshair.AttachedPolygon.PointN; + + /* do update of position */ + if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_FIRST) { + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X = pcb_crosshair.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y = pcb_crosshair.Y; + pcb_crosshair.AttachedLine.State = PCB_CH_STATE_THIRD; + } + + if (conf_core.editor.orthogonal_moves) { + /* set the mark to the new starting point so ortho works */ + hl->tool_grabbed.X = hl->tool_x; + hl->tool_grabbed.Y = hl->tool_y; + hl->tool_grabbed.status = rnd_true; + } + + /* check if this is the last point of a polygon */ + if (n >= 3 && points[0].X == pcb_crosshair.AttachedLine.Point2.X && points[0].Y == pcb_crosshair.AttachedLine.Point2.Y) { + rnd_actionva(hl, "Polygon", "CloseHole", NULL); + break; + } + + /* Someone clicking twice on the same point ('doubleclick'): close polygon hole */ + if (n >= 3 && points[n - 1].X == pcb_crosshair.AttachedLine.Point2.X && points[n - 1].Y == pcb_crosshair.AttachedLine.Point2.Y) { + rnd_actionva(hl, "Polygon", "CloseHole", NULL); + break; + } + + /* create new point if it's the first one or if it's + * different to the last one + */ + if (!n || points[n - 1].X != pcb_crosshair.AttachedLine.Point2.X || points[n - 1].Y != pcb_crosshair.AttachedLine.Point2.Y) { + pcb_poly_point_new(&pcb_crosshair.AttachedPolygon, + pcb_crosshair.AttachedLine.Point2.X, pcb_crosshair.AttachedLine.Point2.Y); + pcb_crosshair.AttachedPolygon_pts = pcb_crosshair.AttachedPolygon.PointN; + + /* copy the coordinates */ + pcb_crosshair.AttachedLine.Point1.X = pcb_crosshair.AttachedLine.Point2.X; + pcb_crosshair.AttachedLine.Point1.Y = pcb_crosshair.AttachedLine.Point2.Y; + } + break; + } + } +} + +void pcb_tool_polyhole_adjust_attached_objects(rnd_hidlib_t *hl) +{ + pcb_attached_line_t *line = &pcb_crosshair.AttachedLine; + + if (rnd_gui->control_is_pressed(rnd_gui)) { + line->draw = rnd_false; + return; + } + else + line->draw = rnd_true; + if (conf_core.editor.all_direction_lines) { + line->Point2.X = pcb_crosshair.X; + line->Point2.Y = pcb_crosshair.Y; + return; + } + + pcb_line_45(line); +} + +void pcb_tool_polyhole_draw_attached(rnd_hidlib_t *hl) +{ + /* draw only if starting point is set */ + if (pcb_crosshair.AttachedLine.State != PCB_CH_STATE_FIRST) + rnd_render->draw_line(pcb_crosshair.GC, + pcb_crosshair.AttachedLine.Point1.X, + pcb_crosshair.AttachedLine.Point1.Y, pcb_crosshair.AttachedLine.Point2.X, pcb_crosshair.AttachedLine.Point2.Y); + + /* draw attached polygon only if in polygon or polygon_hole tool */ + if (pcb_crosshair.AttachedPolygon.PointN > 1) { + pcb_xordraw_poly(&pcb_crosshair.AttachedPolygon, 0, 0, 1); + } +} + +rnd_bool pcb_tool_polyhole_undo_act(rnd_hidlib_t *hl) +{ + if (pcb_crosshair.AttachedPolygon.PointN) { + pcb_polygon_go_to_prev_point(); + return rnd_false; + } + return rnd_true; +} + +rnd_bool pcb_tool_polyhole_redo_act(rnd_hidlib_t *hl) +{ + if (pcb_crosshair.AttachedPolygon.PointN) { + pcb_polygon_go_to_next_point(); + return rnd_false; + } + else + return rnd_true; +} + +void pcb_tool_polyhole_escape(rnd_hidlib_t *hl) +{ + if (pcb_crosshair.AttachedLine.State == PCB_CH_STATE_FIRST) + rnd_tool_select_by_name(hl, "arrow"); + else + rnd_tool_select_by_name(hl, "polyhole"); +} + +/* XPM */ +static const char * polyhole_icon[] = { +"21 21 3 1", +" c None", +". c #6EA5D7", +"+ c #000000", +" .. ", +" ... ", +" ..... ", +" ....... ", +" ......... ", +" ....+++++... ", +" ....+ +.... ", +" ...+ +..... ", +" ...++++++...... ", +" ................ ", +" ................. ", +" ", +" + + ++ + +++ ", +" + + + + + + ", +" + + + + + + ", +" ++++ + + + +++ ", +" + + + + + + ", +" + + + + + + ", +" + + + + + + ", +" + + ++ +++ +++ ", +" " +}; + + +rnd_tool_t pcb_tool_polyhole = { + "polyhole", NULL, NULL, 100, polyhole_icon, RND_TOOL_CURSOR_NAMED("up_arrow"), 0, + NULL, + pcb_tool_polyhole_uninit, + pcb_tool_polyhole_notify_mode, + NULL, + pcb_tool_polyhole_adjust_attached_objects, + pcb_tool_polyhole_draw_attached, + pcb_tool_polyhole_undo_act, + pcb_tool_polyhole_redo_act, + pcb_tool_polyhole_escape, + + 0 +}; Index: tags/2.3.0/src_plugins/tool_std/tool_polyhole.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_polyhole.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_polyhole.h (revision 33253) @@ -0,0 +1,8 @@ +extern rnd_tool_t pcb_tool_polyhole; + +void pcb_tool_polyhole_uninit(void); +void pcb_tool_polyhole_notify_mode(rnd_hidlib_t *hl); +void pcb_tool_polyhole_adjust_attached_objects(rnd_hidlib_t *hl); +void pcb_tool_polyhole_draw_attached(rnd_hidlib_t *hl); +rnd_bool pcb_tool_polyhole_undo_act(rnd_hidlib_t *hl); +rnd_bool pcb_tool_polyhole_redo_act(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_rectangle.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_rectangle.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_rectangle.c (revision 33253) @@ -0,0 +1,171 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" +#include "conf_core.h" + +#include "board.h" +#include "crosshair.h" +#include "data.h" +#include "draw.h" +#include "tool_logic.h" +#include +#include "undo.h" + +#include "obj_poly_draw.h" + + +void pcb_tool_rectangle_uninit(void) +{ + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_false); + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; + rnd_hid_notify_crosshair_change(&PCB->hidlib, rnd_true); +} + +void pcb_tool_rectangle_notify_mode(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + + /* do update of position */ + pcb_tool_notify_block(); + + /* create rectangle if both corners are determined + * and width, height are != 0 + */ + if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_THIRD && + pcb_crosshair.AttachedBox.Point1.X != pcb_crosshair.AttachedBox.Point2.X && + pcb_crosshair.AttachedBox.Point1.Y != pcb_crosshair.AttachedBox.Point2.Y) { + pcb_poly_t *polygon; + pcb_layer_t *layer = pcb_loose_subc_layer(pcb, PCB_CURRLAYER(pcb), rnd_true); + + int flags = PCB_FLAG_CLEARPOLY; + if (conf_core.editor.full_poly) + flags |= PCB_FLAG_FULLPOLY; + if (conf_core.editor.clear_polypoly) + flags |= PCB_FLAG_CLEARPOLYPOLY; + if ((polygon = pcb_poly_new_from_rectangle(layer, + pcb_crosshair.AttachedBox.Point1.X, + pcb_crosshair.AttachedBox.Point1.Y, + pcb_crosshair.AttachedBox.Point2.X, + pcb_crosshair.AttachedBox.Point2.Y, + 2 * conf_core.design.clearance, + pcb_flag_make(flags))) != NULL) { + pcb_obj_add_attribs((pcb_any_obj_t *)polygon, pcb->pen_attr, NULL); + pcb_undo_add_obj_to_create(PCB_OBJ_POLY, layer, polygon, polygon); + pcb_undo_inc_serial(); + pcb_poly_invalidate_draw(layer, polygon); + pcb_draw(); + } + + /* reset state to 'first corner' */ + pcb_crosshair.AttachedBox.State = PCB_CH_STATE_FIRST; + pcb_subc_as_board_update(PCB); + } +} + +void pcb_tool_rectangle_adjust_attached_objects(rnd_hidlib_t *hl) +{ + switch (pcb_crosshair.AttachedBox.State) { + case PCB_CH_STATE_SECOND: /* one corner is selected */ + { + /* update coordinates */ + pcb_crosshair.AttachedBox.Point2.X = pcb_crosshair.X; + pcb_crosshair.AttachedBox.Point2.Y = pcb_crosshair.Y; + break; + } + } +} + +rnd_bool pcb_tool_rectangle_anydo_act(rnd_hidlib_t *hl) +{ + /* don't allow undo in the middle of an operation */ + if (pcb_crosshair.AttachedBox.State != PCB_CH_STATE_FIRST) + return rnd_false; + return rnd_true; +} + +void pcb_tool_rectangle_escape(rnd_hidlib_t *hl) +{ + if (pcb_crosshair.AttachedBox.State == PCB_CH_STATE_FIRST) + rnd_tool_select_by_name(hl, "arrow"); + else + rnd_tool_select_by_name(hl, "rectangle"); +} + +/* XPM */ +static const char *rect_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c black", +". c #6EA5D7", +"o c None", +/* pixels */ +"ooooooooooooooooooooo", +"oo..................o", +"oo..................o", +"oo..................o", +"oo..................o", +"oo..................o", +"oo..................o", +"oo..................o", +"oo..................o", +"oo..................o", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"o oo oo oo ", +"o oo o oooo oo ooo oo", +"o oo o oooo oooooo oo", +"o oo oooo oooooo oo", +"o o oo oo oooooo oo", +"o oo o oooo oooooo oo", +"o oo o oooo oo ooo oo", +"o oo o oo oooo oo", +"ooooooooooooooooooooo" +}; + + +rnd_tool_t pcb_tool_rectangle = { + "rectangle", NULL, NULL, 100, rect_icon, RND_TOOL_CURSOR_NAMED("ul_angle"), 0, + NULL, + pcb_tool_rectangle_uninit, + pcb_tool_rectangle_notify_mode, + NULL, + pcb_tool_rectangle_adjust_attached_objects, + NULL, + pcb_tool_rectangle_anydo_act, + pcb_tool_rectangle_anydo_act, + pcb_tool_rectangle_escape, + + 0 +}; Index: tags/2.3.0/src_plugins/tool_std/tool_rectangle.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_rectangle.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_rectangle.h (revision 33253) @@ -0,0 +1,6 @@ +extern rnd_tool_t pcb_tool_rectangle; + +void pcb_tool_rectangle_uninit(void); +void pcb_tool_rectangle_notify_mode(rnd_hidlib_t *hl); +void pcb_tool_rectangle_adjust_attached_objects(rnd_hidlib_t *hl); +rnd_bool pcb_tool_rectangle_undo_act(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_remove.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_remove.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_remove.c (revision 33253) @@ -0,0 +1,132 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" + +#include "board.h" +#include +#include +#include "undo.h" +#include "remove.h" +#include "search.h" +#include "obj_rat.h" +#include +#include "crosshair.h" +#include "tool_logic.h" + + +void pcb_tool_remove_notify_mode(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + void *ptr1, *ptr2, *ptr3; + pcb_any_obj_t *obj; + int type; + + if ((type = pcb_search_screen_maybe_selector(hl->tool_x, hl->tool_y, PCB_REMOVE_TYPES | PCB_LOOSE_SUBC(PCB) | PCB_OBJ_FLOATER, &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) { + obj = (pcb_any_obj_t *)ptr2; + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, obj)) { + rnd_message(RND_MSG_WARNING, "Sorry, %s object is locked\n", pcb_obj_type_name(obj->type)); + return; + } + + if (type == PCB_OBJ_SUBC) { + if(pcb->is_footprint) { + rnd_message(RND_MSG_WARNING, "Can not remove the subcircuit being edited in the footprint edit mode\n"); + return; + } + } + + obj = ptr2; + pcb_rat_update_obj_removed(pcb, obj); + + /* preserve original parent over the board layer pcb_search_screen operated on - + this is essential for undo: it needs to put back the object to the original + layer (e.g. inside a subc) instead of on the board layer */ + if (obj->parent_type == PCB_PARENT_LAYER) + ptr1 = obj->parent.layer; + else if (obj->parent_type == PCB_PARENT_DATA) + ptr1 = obj->parent.data; + + pcb_remove_object(type, ptr1, ptr2, ptr3); + pcb_undo_inc_serial(); + pcb_subc_as_board_update(PCB); + pcb_board_set_changed_flag(pcb, rnd_true); + } +} + +/* XPM */ +static const char *del_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c black", +". c gray100", +"X c None", +/* pixels */ +"XXX XXXXXXXXXXXX XXXX", +"XXXX XXX XXX XXXXX", +"XXXXX X X XXXXXX", +"XXXXXX XX XX XXXXXXX", +"XXXXX XX XX XXXXXX", +"XXXXX XXXXXX", +"XXXXXX XXXXXXX", +"XXXXXXX XX XXXXXXXX", +"XXXXXXX XX XXXXXXXXX", +"XXXXXX X XX XXXXXXXX", +"XXXX XX X XXXXXX", +"XX XXXXX XXXX XXXX", +"XXXXXXXXXXXXXXXXXXXXX", +"XX XX X XXXXX", +"XXX XXX X XXXXX XXXXX", +"XXX XXX X XXXXX XXXXX", +"XXX XXX X XXXXX XXXXX", +"XXX XXX X XX XXXXX", +"XXX XXX X XXXXX XXXXX", +"XXX XXX X XXXXX XXXXX", +"XX XX X X" +}; + +rnd_tool_t pcb_tool_remove = { + "remove", NULL, NULL, 100, del_icon, RND_TOOL_CURSOR_NAMED("pirate"), 0, + NULL, + NULL, + pcb_tool_remove_notify_mode, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* escape */ + + PCB_TLF_RAT | PCB_TLF_EDIT +}; Index: tags/2.3.0/src_plugins/tool_std/tool_remove.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_remove.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_remove.h (revision 33253) @@ -0,0 +1,3 @@ +extern rnd_tool_t pcb_tool_remove; + +void pcb_tool_remove_notify_mode(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_rotate.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_rotate.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_rotate.c (revision 33253) @@ -0,0 +1,112 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include "board.h" +#include "rotate.h" +#include +#include "crosshair.h" +#include "tool_logic.h" + + +void pcb_tool_rotate_notify_mode(rnd_hidlib_t *hl) +{ + pcb_screen_obj_rotate90((pcb_board_t *)hl, hl->tool_x, hl->tool_y, + rnd_gui->shift_is_pressed(rnd_gui) ? (conf_core.editor.show_solder_side ? 1 : 3) : (conf_core.editor.show_solder_side ? 3 : 1)); + pcb_subc_as_board_update(PCB); +} + +/* XPM */ +static const char *rot_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 4 1", +" c black", +". c #6EA5D7", +"X c gray100", +"o c None", +/* pixels */ +"ooooooooooo.ooooooooo", +"oooooooooo..ooooooooo", +"ooooooooo....oooooooo", +"oooooooooo..o.ooooooo", +"ooooooooooo.oo.oooooo", +"oooooooooooooo.oooooo", +"oooooooooooooo.oooooo", +"oooooooooooooo.oooooo", +"oooooooooooooo.oooooo", +"ooooooooooooo.ooooooo", +"oooooooooooo.oooooooo", +"oooooooooo..ooooooooo", +"ooooooooooooooooooooo", +"ooo ooo oo o", +"ooo ooo o ooo ooo ooo", +"ooo ooo o ooo ooo ooo", +"ooo oo ooo ooo ooo", +"ooo ooo ooo ooo ooo", +"ooo o oo ooo ooo ooo", +"ooo oo o ooo ooo ooo", +"ooo ooo oo oooo ooo" +}; + +#define rotateIcon_width 16 +#define rotateIcon_height 16 +static unsigned char rotateIcon_bits[] = { + 0xf0, 0x03, 0xf8, 0x87, 0x0c, 0xcc, 0x06, 0xf8, 0x03, 0xb0, 0x01, 0x98, + 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x19, 0x80, 0x0d, 0xc0, + 0x1f, 0x60, 0x3b, 0x30, 0xe1, 0x3f, 0xc0, 0x0f}; + +#define rotateMask_width 16 +#define rotateMask_height 16 +static unsigned char rotateMask_bits[] = { + 0xf0, 0x03, 0xf8, 0x87, 0x0c, 0xcc, 0x06, 0xf8, 0x03, 0xf0, 0x01, 0xf8, + 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x1f, 0x80, 0x0f, 0xc0, + 0x1f, 0x60, 0x3b, 0x30, 0xe1, 0x3f, 0xc0, 0x0f}; + +rnd_tool_t pcb_tool_rotate = { + "rotate", NULL, NULL, 100, rot_icon, RND_TOOL_CURSOR_XBM(rotateIcon_bits, rotateMask_bits), 0, + NULL, + NULL, + pcb_tool_rotate_notify_mode, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* escape */ + + PCB_TLF_EDIT +}; Index: tags/2.3.0/src_plugins/tool_std/tool_rotate.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_rotate.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_rotate.h (revision 33253) @@ -0,0 +1,3 @@ +extern rnd_tool_t pcb_tool_rotate; + +void pcb_tool_rotate_notify_mode(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_std.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_std.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_std.c (revision 33253) @@ -0,0 +1,82 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include "crosshair.h" + +#include "tool_arc.h" +#include "tool_arrow.h" +#include "tool_buffer.h" +#include "tool_copy.h" +#include "tool_insert.h" +#include "tool_line.h" +#include "tool_lock.h" +#include "tool_move.h" +#include "tool_poly.h" +#include "tool_polyhole.h" +#include "tool_rectangle.h" +#include "tool_remove.h" +#include "tool_rotate.h" +#include "tool_text.h" +#include "tool_thermal.h" +#include "tool_via.h" + +static const char pcb_tool_std_cookie[] = "tool_std"; + +int pplg_check_ver_tool_std(int ver_needed) { return 0; } + +void pplg_uninit_tool_std(void) +{ + rnd_tool_unreg_by_cookie(pcb_tool_std_cookie); +} + +int pplg_init_tool_std(void) +{ + RND_API_CHK_VER; + + pcb_crosshair.tool_arc = rnd_tool_reg(&pcb_tool_arc, pcb_tool_std_cookie); + pcb_crosshair.tool_arrow = rnd_tool_reg(&pcb_tool_arrow, pcb_tool_std_cookie); + rnd_tool_reg(&pcb_tool_buffer, pcb_tool_std_cookie); + rnd_tool_reg(&pcb_tool_copy, pcb_tool_std_cookie); + rnd_tool_reg(&pcb_tool_insert, pcb_tool_std_cookie); + pcb_crosshair.tool_line = rnd_tool_reg(&pcb_tool_line, pcb_tool_std_cookie); + rnd_tool_reg(&pcb_tool_lock, pcb_tool_std_cookie); + pcb_crosshair.tool_move = rnd_tool_reg(&pcb_tool_move, pcb_tool_std_cookie); + pcb_crosshair.tool_poly = rnd_tool_reg(&pcb_tool_poly, pcb_tool_std_cookie); + pcb_crosshair.tool_poly_hole = rnd_tool_reg(&pcb_tool_polyhole, pcb_tool_std_cookie); + rnd_tool_reg(&pcb_tool_rectangle, pcb_tool_std_cookie); + rnd_tool_reg(&pcb_tool_remove, pcb_tool_std_cookie); + rnd_tool_reg(&pcb_tool_rotate, pcb_tool_std_cookie); + rnd_tool_reg(&pcb_tool_text, pcb_tool_std_cookie); + rnd_tool_reg(&pcb_tool_thermal, pcb_tool_std_cookie); + rnd_tool_reg(&pcb_tool_via, pcb_tool_std_cookie); + + return 0; +} Index: tags/2.3.0/src_plugins/tool_std/tool_std.pup =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_std.pup (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_std.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short standard tools +$long The basic set of PCB drawing tools +$state works +$package (core) +default buildin +autoload 1 Index: tags/2.3.0/src_plugins/tool_std/tool_text.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_text.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_text.c (revision 33253) @@ -0,0 +1,139 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" +#include "conf_core.h" + +#include "board.h" +#include "data.h" +#include "draw.h" +#include +#include +#include "undo.h" + +#include "obj_text_draw.h" + + +void pcb_tool_text_notify_mode(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + char *string; + + if ((string = rnd_hid_prompt_for(hl, "Enter text:", "", "text")) != NULL) { + if (strlen(string) > 0) { + pcb_text_t *text; + int flag = PCB_FLAG_CLEARLINE; + + if (pcb_layer_flags(pcb, PCB_CURRLID(pcb)) & PCB_LYT_BOTTOM) + flag |= PCB_FLAG_ONSOLDER; + if ((text = pcb_text_new(pcb_loose_subc_layer(pcb, PCB_CURRLAYER(pcb), rnd_true), pcb_font(pcb, conf_core.design.text_font_id, 1), hl->tool_x, + hl->tool_y, 0, conf_core.design.text_scale, conf_core.design.text_thickness, string, pcb_flag_make(flag))) != NULL) { + pcb_obj_add_attribs((pcb_any_obj_t *)text, pcb->pen_attr, NULL); + pcb_undo_add_obj_to_create(PCB_OBJ_TEXT, PCB_CURRLAYER(pcb), text, text); + pcb_undo_inc_serial(); + pcb_text_invalidate_draw(PCB_CURRLAYER(pcb), text); + pcb_subc_as_board_update(PCB); + pcb_draw(); + } + } + free(string); + } +} + +void pcb_tool_text_draw_attached(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + pcb_text_t text = {0}; + int flag = PCB_FLAG_CLEARLINE; + + if (pcb_layer_flags(pcb, PCB_CURRLID(pcb)) & PCB_LYT_BOTTOM) + flag |= PCB_FLAG_ONSOLDER; + + text.X = pcb_crosshair.X; + text.Y = pcb_crosshair.Y; + text.Flags = pcb_flag_make(flag); + text.Scale = conf_core.design.text_scale; + text.thickness = conf_core.design.text_thickness; + text.TextString = "A"; + text.fid = conf_core.design.text_font_id; + pcb_text_draw_xor(&text,0,0,1); + +} + +/* XPM */ +static const char *text_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"oo.ooo.ooo.ooo.ooo.oo", +"o.o.o.o.o.o.o.o.o.o.o", +"oo.ooo.ooo.ooo.ooo.oo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +" o o ooo o ", +"oo ooo ooo ooo ooo oo", +"oo ooo oooo o oooo oo", +"oo ooo ooooo ooooo oo", +"oo ooo ooo o oooo oo", +"oo ooo ooo ooo ooo oo", +"oo ooo ooo ooo ooo oo", +"oo ooo o ooo ooo oo", +"ooooooooooooooooooooo" +}; + +rnd_tool_t pcb_tool_text = { + "text", NULL, NULL, 100, text_icon, RND_TOOL_CURSOR_NAMED("xterm"), 0, + NULL, + NULL, + pcb_tool_text_notify_mode, + NULL, + NULL, + pcb_tool_text_draw_attached, + NULL, + NULL, + NULL, /* escape */ + + 0 +}; + Index: tags/2.3.0/src_plugins/tool_std/tool_text.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_text.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_text.h (revision 33253) @@ -0,0 +1,3 @@ +extern rnd_tool_t pcb_tool_text; + +void pcb_tool_text_notify_mode(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/tool_std/tool_thermal.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_thermal.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_thermal.c (revision 33253) @@ -0,0 +1,167 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" + +#include "board.h" +#include "change.h" +#include "data.h" +#include +#include +#include "obj_pstk.h" +#include "search.h" +#include "thermal.h" +#include + +void pcb_tool_thermal_on_obj(pcb_any_obj_t *obj, unsigned long lid) +{ + unsigned char *th, newth = 0; + unsigned char cycle[] = { + PCB_THERMAL_ON | PCB_THERMAL_ROUND | PCB_THERMAL_DIAGONAL, /* default start shape */ + PCB_THERMAL_ON | PCB_THERMAL_ROUND, + PCB_THERMAL_ON | PCB_THERMAL_SHARP | PCB_THERMAL_DIAGONAL, + PCB_THERMAL_ON | PCB_THERMAL_SHARP, + PCB_THERMAL_ON | PCB_THERMAL_SOLID, + PCB_THERMAL_ON | PCB_THERMAL_NOSHAPE + }; + int cycles = sizeof(cycle) / sizeof(cycle[0]); + + th = pcb_obj_common_get_thermal(obj, lid, 1); + if (rnd_gui->shift_is_pressed(rnd_gui)) { + int n, curr = -1; + /* cycle through the variants to find the current one */ + for(n = 0; n < cycles; n++) { + if (*th == cycle[n]) { + curr = n; + break; + } + } + + /* bump current pattern to the next or set it up */ + if (curr >= 0) { + curr++; + if (curr >= cycles) + curr = 0; + } + else + curr = 0; + + newth = cycle[curr]; + } + else { + if ((th != NULL) && (*th != 0)) + newth = *th ^ PCB_THERMAL_ON; /* existing thermal, toggle */ + else + newth = cycle[0]; /* new thermal, use default */ + } + + pcb_chg_obj_thermal(obj->type, obj, obj, obj, newth, lid); +} + + +void pcb_tool_thermal_notify_mode(rnd_hidlib_t *hl) +{ + void *ptr1, *ptr2, *ptr3; + int type, locked = 0; + + if (((type = pcb_search_screen_maybe_selector(hl->tool_x, hl->tool_y, PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART, &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) + && !PCB_FLAG_TEST(PCB_FLAG_HOLE, (pcb_any_obj_t *) ptr3)) { + if (type == PCB_OBJ_PSTK) { + if (!PCB_FLAG_TEST(PCB_FLAG_LOCK, (pcb_any_obj_t *)ptr2)) { + pcb_tool_thermal_on_obj(ptr2, PCB_CURRLID(pcb)); + return; + } + else + locked = 1; + } + } + if (((type = pcb_search_screen_maybe_selector(hl->tool_x, hl->tool_y, PCB_OBJ_CLASS_REAL & ~PCB_OBJ_PSTK, &ptr1, &ptr2, &ptr3)) != PCB_OBJ_VOID) + && !PCB_FLAG_TEST(PCB_FLAG_HOLE, (pcb_any_obj_t *) ptr3)) { + if (!PCB_FLAG_TEST(PCB_FLAG_LOCK, (pcb_any_obj_t *)ptr2)) { + pcb_tool_thermal_on_obj(ptr2, PCB_CURRLID(pcb)); + return; + } + else + locked = 1; + } + + if (locked) + rnd_message(RND_MSG_ERROR, "The only available target object is locked %d\n", PCB_FLAG_TEST(PCB_FLAG_LOCK, (pcb_any_obj_t *)ptr2)); +} + +/* XPM */ +static const char *thrm_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #6EA5D7", +"o c None", +/* pixels */ +"ooooooooooooooooooooo", +"oooo ooooooooo oooooo", +"ooooo ooooooo ooooooo", +"oooooo o...o oooooooo", +"ooooooo ooo ooooooooo", +"oooooo.ooooo.oooooooo", +"oooooo.ooooo.oooooooo", +"oooooo.ooooo.oooooooo", +"ooooooo ooo ooooooooo", +"oooooo o...o oooooooo", +"ooooo ooooooo ooooooo", +"oooo ooooooooo oooooo", +"ooooooooooooooooooooo", +" o oo o oo ooo ", +"oo ooo oo o oo o o ", +"oo ooo oo o oo o o o ", +"oo ooo oo o oo o o ", +"oo ooo o o oo ooo ", +"oo ooo oo o oo o ooo ", +"oo ooo oo o oo o ooo ", +"oo ooo oo o oo o ooo " +}; + +rnd_tool_t pcb_tool_thermal = { + "thermal", NULL, NULL, 100, thrm_icon, RND_TOOL_CURSOR_NAMED("iron_cross"), 0, + NULL, + NULL, + pcb_tool_thermal_notify_mode, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* escape */ + + 0 +}; Index: tags/2.3.0/src_plugins/tool_std/tool_thermal.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_thermal.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_thermal.h (revision 33253) @@ -0,0 +1,6 @@ +extern rnd_tool_t pcb_tool_thermal; + +void pcb_tool_thermal_notify_mode(rnd_hidlib_t *hl); + +/* direct call: cycle through thermal modes on a padstack - provided for tool_via.h */ +void pcb_tool_thermal_on_obj(pcb_any_obj_t *ps, unsigned long lid); Index: tags/2.3.0/src_plugins/tool_std/tool_via.c =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_via.c (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_via.c (revision 33253) @@ -0,0 +1,151 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton + * Copyright (C) 2017,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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + * + * + * Old contact info: + * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA + * haceaton@aplcomm.jhuapl.edu + * + */ + +#include "config.h" + +#include "conf_core.h" +#include + +#include "board.h" +#include "change.h" +#include +#include "data.h" +#include "draw.h" +#include +#include "tool_thermal.h" +#include "undo.h" + +#include "obj_pstk_draw.h" + +TODO("padstack: remove this when via is removed and the padstack is created from style directly") +#include "src_plugins/lib_compat_help/pstk_compat.h" + +void pcb_tool_via_notify_mode(rnd_hidlib_t *hl) +{ + pcb_board_t *pcb = (pcb_board_t *)hl; + + if (!pcb->pstk_on) { + rnd_message(RND_MSG_WARNING, "You must turn via visibility on before\nyou can place vias\n"); + return; + } + + if (conf_core.design.via_drilling_hole >= conf_core.design.via_thickness) { + rnd_message(RND_MSG_ERROR, "Can't place via: invalid via geometry (hole too large for via size)\n"); + return; + } + +TODO("pstk #21: do not work in comp mode, use a pstk proto - scconfig also has TODO #21, fix it there too") + { + pcb_pstk_t *ps = pcb_pstk_new_compat_via(pcb->Data, -1, hl->tool_x, hl->tool_y, + conf_core.design.via_drilling_hole, conf_core.design.via_thickness, conf_core.design.clearance, + 0, PCB_PSTK_COMPAT_ROUND, rnd_true); + if (ps == NULL) + return; + + pcb_obj_add_attribs((pcb_any_obj_t *)ps, pcb->pen_attr, NULL); + pcb_undo_add_obj_to_create(PCB_OBJ_PSTK, ps, ps, ps); + + if (rnd_gui->shift_is_pressed(rnd_gui)) + pcb_tool_thermal_on_obj((pcb_any_obj_t *)ps, PCB_CURRLID(pcb)); + + pcb_undo_inc_serial(); + pcb_pstk_invalidate_draw(ps); + pcb_draw(); + } +} + +static void xor_draw_fake_via(rnd_coord_t x, rnd_coord_t y, rnd_coord_t dia, rnd_coord_t clearance) +{ + rnd_coord_t r = (dia/2)+clearance; + rnd_render->draw_arc(pcb_crosshair.GC, x, y, r, r, 0, 360); +} + + +void pcb_tool_via_draw_attached(rnd_hidlib_t *hl) +{ +TODO("pstk: replace this when route style has a prototype") + xor_draw_fake_via(pcb_crosshair.X, pcb_crosshair.Y, conf_core.design.via_thickness, 0); + if (conf_core.editor.show_drc) { + /* XXX: Naughty cheat - use the mask to draw DRC clearance! */ + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.drc); + xor_draw_fake_via(pcb_crosshair.X, pcb_crosshair.Y, conf_core.design.via_thickness, conf_core.design.clearance); + rnd_render->set_color(pcb_crosshair.GC, &conf_core.appearance.color.attached); + } +} + +/* XPM */ +static const char *via_icon[] = { +/* columns rows colors chars-per-pixel */ +"21 21 3 1", +" c #000000", +". c #7A8584", +"o c None", +/* pixels */ +"ooooooooooooooooooooo", +"ooooooooo...ooooooooo", +"oooooooo.....oooooooo", +"ooooooo..ooo..ooooooo", +"oooooo..ooooo..oooooo", +"oooooo..ooooo..oooooo", +"oooooo..ooooo..oooooo", +"ooooooo..ooo..ooooooo", +"oooooooo.....oooooooo", +"ooooooooo...ooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooooooooooooooooooooo", +"ooo ooo o ooo ooooo", +"ooo ooo oo ooo o oooo", +"ooo ooo oo oo ooo ooo", +"oooo o ooo oo ooo ooo", +"oooo o ooo oo ooo", +"oooo o ooo oo ooo ooo", +"ooooo ooo o ooo ooo", +"ooooooooooooooooooooo" +}; + +rnd_tool_t pcb_tool_via = { + "via", NULL, NULL, 100, via_icon, RND_TOOL_CURSOR_NAMED(NULL), 0, + NULL, + NULL, + pcb_tool_via_notify_mode, + NULL, + NULL, + pcb_tool_via_draw_attached, + NULL, + NULL, + NULL, /* escape */ + + 0 +}; Index: tags/2.3.0/src_plugins/tool_std/tool_via.h =================================================================== --- tags/2.3.0/src_plugins/tool_std/tool_via.h (nonexistent) +++ tags/2.3.0/src_plugins/tool_std/tool_via.h (revision 33253) @@ -0,0 +1,4 @@ +extern rnd_tool_t pcb_tool_via; + +void pcb_tool_via_notify_mode(rnd_hidlib_t *hl); +void pcb_tool_via_draw_attached(rnd_hidlib_t *hl); Index: tags/2.3.0/src_plugins/vendordrill/Makefile =================================================================== --- tags/2.3.0/src_plugins/vendordrill/Makefile (nonexistent) +++ tags/2.3.0/src_plugins/vendordrill/Makefile (revision 33253) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_vendordrill + +clean: + rm *.o *.so 2>/dev/null ; true + Index: tags/2.3.0/src_plugins/vendordrill/Plug.tmpasm =================================================================== --- tags/2.3.0/src_plugins/vendordrill/Plug.tmpasm (nonexistent) +++ tags/2.3.0/src_plugins/vendordrill/Plug.tmpasm (revision 33253) @@ -0,0 +1,11 @@ +put /local/pcb/mod {vendordrill} +append /local/pcb/mod/OBJS [@ $(PLUGDIR)/vendordrill/vendor.o @] +put /local/pcb/mod/CONF {$(PLUGDIR)/vendordrill/vendor_conf.h} +put /local/pcb/mod/MENUFILE {vendor-menu.lht} +put /local/pcb/mod/MENUVAR {vendor_menu} + +switch /local/pcb/vendordrill/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end Index: tags/2.3.0/src_plugins/vendordrill/vendor-menu.lht =================================================================== --- tags/2.3.0/src_plugins/vendordrill/vendor-menu.lht (nonexistent) +++ tags/2.3.0/src_plugins/vendordrill/vendor-menu.lht (revision 33253) @@ -0,0 +1,23 @@ +ha:rnd-menu-v1 { + li:main_menu { + ha:Mode = { + li:submenu { + ha:Vendor drill mapping = { checked=plugins/vendor/enable; action=conf(toggle, plugins/vendor/enable, design) } + } + } + + ha:Connects = { + li:submenu { + ha:Apply vendor drill mapping = { action=ApplyVendor() } + } + } + } + + li:anchored { + ha:@import_geo { + li:submenu { + ha:Load vendor resource file = { action=LoadVendorFrom() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/src_plugins/vendordrill/vendor.c =================================================================== --- tags/2.3.0/src_plugins/vendordrill/vendor.c (nonexistent) +++ tags/2.3.0/src_plugins/vendordrill/vendor.c (revision 33253) @@ -0,0 +1,680 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * (this file is based on PCB, interactive printed circuit board design) + * Copyright (C) 2004, 2007 Dan McMahill + * Copyright (C) 2018 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" +#include "conf_core.h" + +#include +#include +#include +#include +#include + +#include + +#include "change.h" +#include "board.h" +#include "data.h" +#include "draw.h" +#include +#include "undo.h" +#include +#include +#include +#include +#include "vendor_conf.h" +#include +#include "obj_pstk_inlines.h" +#include "event.h" +#include +#include + +#include "menu_internal.c" + +conf_vendor_t conf_vendor; + +static void add_to_drills(char *); +static void apply_vendor_map(void); +static void process_skips(lht_node_t *); +static rnd_bool rematch(const char *, const char *); +static void vendor_free_all(void); +rnd_coord_t vendorDrillMap(rnd_coord_t in); + + +/* list of vendor drills and a count of them */ +static rnd_coord_t *vendor_drills = NULL; +static int n_vendor_drills = 0; + +static int cached_drill = -1; +static int cached_map = -1; + +/* lists of elements to ignore */ +static char **ignore_refdes = NULL; +static int n_refdes = 0; +static char **ignore_value = NULL; +static int n_value = 0; +static char **ignore_descr = NULL; +static int n_descr = 0; + +/* vendor name */ +static char *vendor_name = NULL; + +/* resource file to PCB units scale factor */ +static double sf; + + +/* type of drill mapping */ +#define CLOSEST 1 +#define ROUND_UP 0 +static int rounding_method = ROUND_UP; + +#define FREE(x) if((x) != NULL) { free (x) ; (x) = NULL; } + +/* load a board metadata into conf_core */ +static void load_meta_coord(const char *path, rnd_coord_t crd) +{ + char tmp[128]; + rnd_sprintf(tmp, "%$mm", crd); + rnd_conf_set(RND_CFR_DESIGN, path, -1, tmp, RND_POL_OVERWRITE); +} + +static rnd_bool vendorIsSubcMappable(pcb_subc_t *subc); + + +static const char apply_vendor_syntax[] = "ApplyVendor()"; +static const char apply_vendor_help[] = "Applies the currently loaded vendor drill table to the current design."; +/* DOC: applyvendor.html */ +fgw_error_t pcb_act_ApplyVendor(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + rnd_hid_busy(PCB, 1); + apply_vendor_map(); + rnd_hid_busy(PCB, 0); + RND_ACT_IRES(0); + return 0; +} + +static const char unload_vendor_syntax[] = "UnloadVendor()"; +static const char unload_vendor_help[] = "Unloads the current vendor drill mapping table."; +fgw_error_t pcb_act_UnloadVendor(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + cached_drill = -1; + + vendor_free_all(); + RND_ACT_IRES(0); + return 0; +} + + +static const char pcb_acts_LoadVendorFrom[] = "LoadVendorFrom(filename)"; +static const char pcb_acth_LoadVendorFrom[] = "Loads the specified vendor lihata file."; +/* DOC: loadvendorfrom.html */ +fgw_error_t pcb_act_LoadVendorFrom(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + const char *fname = NULL; + static char *default_file = NULL; + const char *sval; + lht_doc_t *doc; + lht_node_t *drlres; + rnd_bool free_fname = rnd_false; + + cached_drill = -1; + + RND_ACT_MAY_CONVARG(1, FGW_STR, LoadVendorFrom, fname = argv[1].val.str); + + if (!fname || !*fname) { + fname = rnd_gui->fileselect(rnd_gui, "Load Vendor Resource File...", + "Picks a vendor resource file to load.\n" + "This file can contain drc settings for a\n" + "particular vendor as well as a list of\n" + "predefined drills which are allowed.", default_file, ".res", NULL, "vendor", RND_HID_FSD_READ, NULL); + if (fname == NULL) { + RND_ACT_IRES(1); + return 0; + } + + free_fname = rnd_true; + + free(default_file); + default_file = NULL; + + if (fname && *fname) + default_file = rnd_strdup(fname); + } + + vendor_free_all(); + + /* load the resource file */ + doc = rnd_hid_cfg_load_lht(&PCB->hidlib, fname); + if (doc == NULL) { + rnd_message(RND_MSG_ERROR, "Could not load vendor resource file \"%s\"\n", fname); + RND_ACT_IRES(1); + return 0; + } + + /* figure out the vendor name, if specified */ + vendor_name = (char *) RND_UNKNOWN(rnd_hid_cfg_text_value(doc, "vendor")); + + /* figure out the units, if specified */ + sval = rnd_hid_cfg_text_value(doc, "/units"); + if (sval == NULL) { + sf = RND_MIL_TO_COORD(1); + } + else if ((RND_NSTRCMP(sval, "mil") == 0) || (RND_NSTRCMP(sval, "mils") == 0)) { + sf = RND_MIL_TO_COORD(1); + } + else if ((RND_NSTRCMP(sval, "inch") == 0) || (RND_NSTRCMP(sval, "inches") == 0)) { + sf = RND_INCH_TO_COORD(1); + } + else if (RND_NSTRCMP(sval, "mm") == 0) { + sf = RND_MM_TO_COORD(1); + } + else { + rnd_message(RND_MSG_ERROR, "\"%s\" is not a supported units. Defaulting to inch\n", sval); + sf = RND_INCH_TO_COORD(1); + } + + /* default to ROUND_UP */ + rounding_method = ROUND_UP; + sval = rnd_hid_cfg_text_value(doc, "/round"); + if (sval != NULL) { + if (RND_NSTRCMP(sval, "up") == 0) { + rounding_method = ROUND_UP; + } + else if (RND_NSTRCMP(sval, "nearest") == 0) { + rounding_method = CLOSEST; + } + else { + rnd_message(RND_MSG_ERROR, "\"%s\" is not a valid rounding type. Defaulting to up\n", sval); + rounding_method = ROUND_UP; + } + } + + process_skips(lht_tree_path(doc, "/", "/skips", 1, NULL)); + + /* extract the drillmap resource */ + drlres = lht_tree_path(doc, "/", "/drillmap", 1, NULL); + if (drlres != NULL) { + if (drlres->type == LHT_LIST) { + lht_node_t *n; + for(n = drlres->data.list.first; n != NULL; n = n->next) { + if (n->type != LHT_TEXT) + rnd_hid_cfg_error(n, "Broken drillmap: /drillmap should contain text children only\n"); + else + add_to_drills(n->data.text.value); + } + } + else + rnd_message(RND_MSG_ERROR, "Broken drillmap: /drillmap should be a list\n"); + } + else + rnd_message(RND_MSG_ERROR, "No drillmap resource found\n"); + + sval = rnd_hid_cfg_text_value(doc, "/drc/copper_space"); + if (sval != NULL) { + load_meta_coord("design/bloat", floor(sf * atof(sval) + 0.5)); + rnd_message(RND_MSG_INFO, "Set DRC minimum copper spacing to %ml mils\n", conf_core.design.bloat); + } + + sval = rnd_hid_cfg_text_value(doc, "/drc/copper_overlap"); + if (sval != NULL) { + load_meta_coord("design/shrink", floor(sf * atof(sval) + 0.5)); + rnd_message(RND_MSG_INFO, "Set DRC minimum copper overlap to %ml mils\n", conf_core.design.shrink); + } + + sval = rnd_hid_cfg_text_value(doc, "/drc/copper_width"); + if (sval != NULL) { + load_meta_coord("design/min_wid", floor(sf * atof(sval) + 0.5)); + rnd_message(RND_MSG_INFO, "Set DRC minimum copper spacing to %ml mils\n", conf_core.design.min_wid); + } + + sval = rnd_hid_cfg_text_value(doc, "/drc/silk_width"); + if (sval != NULL) { + load_meta_coord("design/min_slk", floor(sf * atof(sval) + 0.5)); + rnd_message(RND_MSG_INFO, "Set DRC minimum silk width to %ml mils\n", conf_core.design.min_slk); + } + + sval = rnd_hid_cfg_text_value(doc, "/drc/min_drill"); + if (sval != NULL) { + load_meta_coord("design/min_drill", floor(sf * atof(sval) + 0.5)); + rnd_message(RND_MSG_INFO, "Set DRC minimum drill diameter to %ml mils\n", conf_core.design.min_drill); + } + + sval = rnd_hid_cfg_text_value(doc, "/drc/min_ring"); + if (sval != NULL) { + load_meta_coord("design/min_ring", floor(sf * atof(sval) + 0.5)); + rnd_message(RND_MSG_INFO, "Set DRC minimum annular ring to %ml mils\n", conf_core.design.min_ring); + } + + rnd_message(RND_MSG_INFO, "Loaded %d vendor drills from %s\n", n_vendor_drills, fname); + rnd_message(RND_MSG_INFO, "Loaded %d RefDes skips, %d Value skips, %d Descr skips\n", n_refdes, n_value, n_descr); + + rnd_conf_set(RND_CFR_DESIGN, "plugins/vendor/enable", -1, "0", RND_POL_OVERWRITE); + + apply_vendor_map(); + if (free_fname) + free((char*)fname); + lht_dom_uninit(doc); + RND_ACT_IRES(0); + return 0; +} + +static int apply_vendor_pstk1(pcb_pstk_t *pstk, rnd_cardinal_t *tot) +{ + pcb_pstk_proto_t *proto = pcb_pstk_get_proto(pstk); + rnd_coord_t target; + int res = 0; + + if ((proto == NULL) || (proto->hdia == 0)) return 0; + (*tot)++; + if (PCB_FLAG_TEST(PCB_FLAG_LOCK, pstk)) return 0; + + target = vendorDrillMap(proto->hdia); + if (proto->hdia != target) { + if (pcb_chg_obj_2nd_size(PCB_OBJ_PSTK, pstk, pstk, pstk, target, rnd_true, rnd_false)) + res = 1; + else { + rnd_message(RND_MSG_WARNING, + "Padstack at %ml, %ml not changed. Possible reasons:\n" + "\t- pad size too small\n" + "\t- new size would be too large or too small\n", pstk->x, pstk->y); + } + } + return res; +} + +static rnd_cardinal_t apply_vendor_pstk(pcb_data_t *data, rnd_cardinal_t *tot) +{ + gdl_iterator_t it; + pcb_pstk_t *pstk; + rnd_cardinal_t changed = 0; + + padstacklist_foreach(&data->padstack, &it, pstk) + if (apply_vendor_pstk1(pstk, tot)) + changed++; + return changed; +} + +static void apply_vendor_map(void) +{ + int i; + rnd_cardinal_t changed = 0, tot = 0; + rnd_bool state; + + state = conf_vendor.plugins.vendor.enable; + + /* enable mapping */ + rnd_conf_force_set_bool(conf_vendor.plugins.vendor.enable, 1); + + /* If we have loaded vendor drills, then apply them to the design */ + if (n_vendor_drills > 0) { + + /* global padsatcks (e.g. vias) */ + changed += apply_vendor_pstk(PCB->Data, &tot); + + PCB_SUBC_LOOP(PCB->Data); + { + if (vendorIsSubcMappable(subc)) + changed += apply_vendor_pstk(subc->data, &tot); + } + PCB_END_LOOP; + + rnd_message(RND_MSG_INFO, "Updated %ld drill sizes out of %ld total\n", (long)changed, (long)tot); + + /* Update the current Via */ + if (conf_core.design.via_drilling_hole != vendorDrillMap(conf_core.design.via_drilling_hole)) { + changed++; + rnd_conf_setf(RND_CFR_DESIGN, "design/via_drilling_hole", -1, "%$mm", vendorDrillMap(conf_core.design.via_drilling_hole)); + rnd_message(RND_MSG_INFO, "Adjusted active via hole size to be %ml mils\n", conf_core.design.via_drilling_hole); + } + + /* and update the vias for the various routing styles */ + for (i = 0; i < vtroutestyle_len(&PCB->RouteStyle); i++) { + if (PCB->RouteStyle.array[i].Hole != vendorDrillMap(PCB->RouteStyle.array[i].Hole)) { + changed++; + PCB->RouteStyle.array[i].Hole = vendorDrillMap(PCB->RouteStyle.array[i].Hole); + rnd_message(RND_MSG_INFO, + "Adjusted %s routing style hole size to be %ml mils\n", + PCB->RouteStyle.array[i].name, PCB->RouteStyle.array[i].Hole); + if (PCB->RouteStyle.array[i].Diameter < PCB->RouteStyle.array[i].Hole + PCB_MIN_PINORVIACOPPER) { + PCB->RouteStyle.array[i].Diameter = PCB->RouteStyle.array[i].Hole + PCB_MIN_PINORVIACOPPER; + rnd_message(RND_MSG_INFO, + "Increased %s routing style via diameter to %ml mils\n", + PCB->RouteStyle.array[i].name, PCB->RouteStyle.array[i].Diameter); + } + } + } + + /* + * if we've changed anything, indicate that we need to save the + * file, redraw things, and make sure we can undo. + */ + if (changed) { + pcb_board_set_changed_flag(PCB, rnd_true); + rnd_hid_redraw(PCB); + pcb_undo_inc_serial(); + } + } + + /* restore mapping on/off */ + rnd_conf_force_set_bool(conf_vendor.plugins.vendor.enable, state); +} + +/* for a given drill size, find the closest vendor drill size */ +rnd_coord_t vendorDrillMap(rnd_coord_t in) +{ + int i, min, max; + + if (in == cached_drill) + return cached_map; + cached_drill = in; + + /* skip the mapping if we don't have a vendor drill table */ + if ((n_vendor_drills == 0) || (vendor_drills == NULL) + || (!conf_vendor.plugins.vendor.enable)) { + cached_map = in; + return in; + } + + /* are we smaller than the smallest drill? */ + if (in <= vendor_drills[0]) { + cached_map = vendor_drills[0]; + return vendor_drills[0]; + } + + /* are we larger than the largest drill? */ + if (in > vendor_drills[n_vendor_drills - 1]) { + rnd_message(RND_MSG_ERROR, "Vendor drill list does not contain a drill >= %ml mil\n" + "Using %ml mil instead.\n", in, vendor_drills[n_vendor_drills - 1]); + cached_map = vendor_drills[n_vendor_drills - 1]; + return vendor_drills[n_vendor_drills - 1]; + } + + /* figure out which 2 drills are closest in size */ + min = 0; + max = n_vendor_drills - 1; + while (max - min > 1) { + i = (max + min) / 2; + if (in > vendor_drills[i]) + min = i; + else + max = i; + } + i = max; + + /* now round per the rounding mode */ + if (rounding_method == CLOSEST) { + /* find the closest drill size */ + if ((in - vendor_drills[i - 1]) > (vendor_drills[i] - in)) { + cached_map = vendor_drills[i]; + return vendor_drills[i]; + } + else { + cached_map = vendor_drills[i - 1]; + return vendor_drills[i - 1]; + } + } + else { + /* always round up */ + cached_map = vendor_drills[i]; + return vendor_drills[i]; + } + +} + +/* add a drill size to the vendor drill list */ +static void add_to_drills(char *sval) +{ + double tmpd; + int val; + int k, j; + + /* increment the count and make sure we have memory */ + n_vendor_drills++; + if ((vendor_drills = (int *) realloc(vendor_drills, n_vendor_drills * sizeof(int))) == NULL) { + fprintf(stderr, "realloc() failed to allocate %ld bytes\n", (unsigned long) n_vendor_drills * sizeof(int)); + return; + } + + /* string to a value with the units scale factor in place */ + tmpd = atof(sval); + val = floor(sf * tmpd + 0.5); + + /* + * We keep the array of vendor drills sorted to make it easier to + * do the rounding later. The algorithm used here is not so efficient, + * but we're not dealing with much in the way of data. + */ + + /* figure out where to insert the value to keep the array sorted. */ + k = 0; + while ((k < n_vendor_drills - 1) && (vendor_drills[k] < val)) + k++; + + if (k == n_vendor_drills - 1) { + vendor_drills[n_vendor_drills - 1] = val; + } + else { + /* move up the existing drills to make room */ + for (j = n_vendor_drills - 1; j > k; j--) { + vendor_drills[j] = vendor_drills[j - 1]; + } + + vendor_drills[k] = val; + } +} + +/* deal with the "skip" subresource */ +static void process_skips(lht_node_t *res) +{ + char *sval; + int *cnt; + char ***lst = NULL; + lht_node_t *n; + + if (res == NULL) + return; + + if (res->type != LHT_LIST) + rnd_hid_cfg_error(res, "skips must be a list.\n"); + + for(n = res->data.list.first; n != NULL; n = n->next) { + if (n->type == LHT_TEXT) { + if (RND_NSTRCMP(n->name, "refdes") == 0) { + cnt = &n_refdes; + lst = &ignore_refdes; + } + else if (RND_NSTRCMP(n->name, "value") == 0) { + cnt = &n_value; + lst = &ignore_value; + } + else if (RND_NSTRCMP(n->name, "descr") == 0) { + cnt = &n_descr; + lst = &ignore_descr; + } + else { + rnd_hid_cfg_error(n, "invalid skip name; must be one of refdes, value, descr"); + continue; + } + /* add the entry to the appropriate list */ + sval = n->data.text.value; + (*cnt)++; + if ((*lst = (char **) realloc(*lst, (*cnt) * sizeof(char *))) == NULL) { + fprintf(stderr, "realloc() failed\n"); + exit(-1); + } + (*lst)[*cnt - 1] = rnd_strdup(sval); + } + else + rnd_hid_cfg_error(n, "invalid skip type; must be text"); + } +} + +static rnd_bool vendorIsSubcMappable(pcb_subc_t *subc) +{ + int i; + int noskip; + + if (!conf_vendor.plugins.vendor.enable) + return rnd_false; + +TODO(": these 3 loops should be wrapped in a single loop that iterates over attribute keys") + noskip = 1; + for (i = 0; i < n_refdes; i++) { + if ((RND_NSTRCMP(RND_UNKNOWN(subc->refdes), ignore_refdes[i]) == 0) + || rematch(ignore_refdes[i], RND_UNKNOWN(subc->refdes))) { + rnd_message(RND_MSG_INFO, "Vendor mapping skipped because refdes = %s matches %s\n", RND_UNKNOWN(subc->refdes), ignore_refdes[i]); + noskip = 0; + } + } + if (noskip) { + const char *vl = pcb_attribute_get(&subc->Attributes, "value"); + for (i = 0; i < n_value; i++) { + if ((RND_NSTRCMP(RND_UNKNOWN(vl), ignore_value[i]) == 0) + || rematch(ignore_value[i], RND_UNKNOWN(vl))) { + rnd_message(RND_MSG_INFO, "Vendor mapping skipped because value = %s matches %s\n", RND_UNKNOWN(vl), ignore_value[i]); + noskip = 0; + } + } + } + + if (noskip) { + const char *fp = pcb_attribute_get(&subc->Attributes, "footprint"); + for (i = 0; i < n_descr; i++) { + if ((RND_NSTRCMP(RND_UNKNOWN(fp), ignore_descr[i]) == 0) + || rematch(ignore_descr[i], RND_UNKNOWN(fp))) { + rnd_message(RND_MSG_INFO, + "Vendor mapping skipped because descr = %s matches %s\n", + RND_UNKNOWN(fp), ignore_descr[i]); + noskip = 0; + } + } + } + + if (noskip && PCB_FLAG_TEST(PCB_FLAG_LOCK, subc)) { + rnd_message(RND_MSG_INFO, "Vendor mapping skipped because element %s is locked\n", RND_UNKNOWN(subc->refdes)); + noskip = 0; + } + + if (noskip) + return rnd_true; + else + return rnd_false; +} + +static rnd_bool rematch(const char *re, const char *s) +{ + int result; + re_sei_t *regex; + + /* compile the regular expression */ + regex = re_sei_comp(re); + if (re_sei_errno(regex) != 0) { + rnd_message(RND_MSG_ERROR, "regexp error: %s\n", re_error_str(re_sei_errno(regex))); + re_sei_free(regex); + return rnd_false; + } + + result = re_sei_exec(regex, s); + re_sei_free(regex); + + if (result != 0) + return rnd_true; + else + return rnd_false; +} + +static const char *vendor_cookie = "vendor drill mapping"; + +rnd_action_t vendor_action_list[] = { + {"ApplyVendor", pcb_act_ApplyVendor, apply_vendor_help, apply_vendor_syntax}, + {"UnloadVendor", pcb_act_UnloadVendor, unload_vendor_help, unload_vendor_syntax}, + {"LoadVendorFrom", pcb_act_LoadVendorFrom, pcb_acth_LoadVendorFrom, pcb_acts_LoadVendorFrom} +}; + +static char **vendor_free_vect(char **lst, int *len) +{ + if (lst != NULL) { + int n; + for(n = 0; n < *len; n++) + if (lst[n] != NULL) + free(lst[n]); + free(lst); + } + *len = 0; + return NULL; +} + +static void vendor_free_all(void) +{ + ignore_refdes = vendor_free_vect(ignore_refdes, &n_refdes); + ignore_value = vendor_free_vect(ignore_value, &n_value); + ignore_descr = vendor_free_vect(ignore_descr, &n_descr); + if (vendor_drills != NULL) { + free(vendor_drills); + vendor_drills = NULL; + n_vendor_drills = 0; + } + cached_drill = -1; +} + +/* Tune newly placed padstacks */ +static void vendor_new_pstk(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pcb_pstk_t *ps; + rnd_cardinal_t dummy; + + if ((argc < 2) || (argv[1].type != RND_EVARG_PTR)) + return; + + ps = argv[1].d.p; + apply_vendor_pstk1(ps, &dummy); +} + +int pplg_check_ver_vendordrill(int ver_needed) { return 0; } + +void pplg_uninit_vendordrill(void) +{ + rnd_event_unbind_allcookie(vendor_cookie); + rnd_remove_actions_by_cookie(vendor_cookie); + vendor_free_all(); + rnd_conf_unreg_fields("plugins/vendor/"); + rnd_hid_menu_unload(rnd_gui, vendor_cookie); +} + +int pplg_init_vendordrill(void) +{ + RND_API_CHK_VER; +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_vendor, field,isarray,type_name,cpath,cname,desc,flags); +#include "vendor_conf_fields.h" + + rnd_event_bind(PCB_EVENT_NEW_PSTK, vendor_new_pstk, NULL, vendor_cookie); + RND_REGISTER_ACTIONS(vendor_action_list, vendor_cookie) + rnd_hid_menu_load(rnd_gui, NULL, vendor_cookie, 110, NULL, 0, vendor_menu, "plugin: vendor drill mapping"); + return 0; +} Index: tags/2.3.0/src_plugins/vendordrill/vendor.example.lht =================================================================== --- tags/2.3.0/src_plugins/vendordrill/vendor.example.lht (nonexistent) +++ tags/2.3.0/src_plugins/vendordrill/vendor.example.lht (revision 33253) @@ -0,0 +1,51 @@ +ha:vendor_drill_map { + # Optional name of the vendor + vendor = Vendor Name + + # units for dimensions in this file. + # Allowed values: mil/inch/mm + units = mil + + # When mapping drill sizes, select the nearest size + # or always round up. Allowed values: up/nearest + round = up + + # drill table + li:drillmap = { + # The list of vendor drill sizes. Units are as specified + # above. + 20 + 28 + 35 + 38 + 42 + 52 + 59.5 + 86 + 125 + 152 + } + + # optional section for skipping mapping of certain elements + # based on reference designator, value, or description + # this is useful for critical parts where you may not + # want to change the drill size. Note that the strings + # are regular expressions. + li:skips = { + refdes = {^J3$} # Skip J3. + refdes = {J3} # Skip anything with J3 as part of the refdes. + refdes = {^U[1-3]$} # Skip U1, U2, U3 + refdes = {^X.*} # Skip anything starting with X. + value = {^JOHNSTECH_.*} # Skip all Johnstech footprints based on the value of a part. + descr = {^AMP_MICTOR_767054_1$} # Skip based on the description. + } + + # If specified, this section will change the current DRC + # settings for the design. Units are as specified above. + ha:drc = { + copper_space = 7 + copper_width = 7 + silk_width = 10 + copper_overlap = 4 + } +} Index: tags/2.3.0/src_plugins/vendordrill/vendor_conf.h =================================================================== --- tags/2.3.0/src_plugins/vendordrill/vendor_conf.h (nonexistent) +++ tags/2.3.0/src_plugins/vendordrill/vendor_conf.h (revision 33253) @@ -0,0 +1,14 @@ +#ifndef PCB_VENDOR_CONF_H +#define PCB_VENDOR_CONF_H + +#include + +typedef struct { + const struct { + const struct { + RND_CFT_BOOLEAN enable; /* Enable vendor mapping */ + } vendor; + } plugins; +} conf_vendor_t; + +#endif Index: tags/2.3.0/src_plugins/vendordrill/vendordrill.pup =================================================================== --- tags/2.3.0/src_plugins/vendordrill/vendordrill.pup (nonexistent) +++ tags/2.3.0/src_plugins/vendordrill/vendordrill.pup (revision 33253) @@ -0,0 +1,7 @@ +$class feature +$short vendor drill mapping +$long Vendor drill mapping. +$state works +$package extra +default buildin +autoload 1 Index: tags/2.3.0/tests/Makefile =================================================================== --- tags/2.3.0/tests/Makefile (nonexistent) +++ tags/2.3.0/tests/Makefile (revision 33253) @@ -0,0 +1,34 @@ +test: + cd RTT && $(MAKE) all && $(MAKE) test + cd pcbflags && $(MAKE) all && $(MAKE) test + cd conf && $(MAKE) all && $(MAKE) test + cd strflags && $(MAKE) all && $(MAKE) test + cd pcb-printf && $(MAKE) all && $(MAKE) test + cd uniq_name && $(MAKE) all && $(MAKE) test + cd propedit && $(MAKE) all && $(MAKE) test + cd remote && $(MAKE) all && $(MAKE) test + cd drc_pstk_hbrk && $(MAKE) all && $(MAKE) test +# cd gsch2pcb-rnd && $(MAKE) all && $(MAKE) test + cd drc_query && $(MAKE) test + cd query && $(MAKE) test + cd menu && $(MAKE) test + @echo " " + @echo "+-------------------------------------------------+" + @echo "+ All tests passed, pcb-rnd is safe to install. +" + @echo "+-------------------------------------------------+" + +clean: + cd RTT && $(MAKE) clean + cd pcbflags && $(MAKE) clean + cd conf && $(MAKE) clean + cd strflags && $(MAKE) clean + cd pcb-printf && $(MAKE) clean + cd uniq_name && $(MAKE) clean + cd propedit && $(MAKE) clean + cd remote && $(MAKE) clean + cd drc_pstk_hbrk && $(MAKE) clean +# cd gsch2pcb-rnd && $(MAKE) clean + cd drc_query && $(MAKE) clean + cd query && $(MAKE) clean + cd menu && $(MAKE) clean + Index: tags/2.3.0/tests/RTT/Export.sh =================================================================== --- tags/2.3.0/tests/RTT/Export.sh (nonexistent) +++ tags/2.3.0/tests/RTT/Export.sh (revision 33253) @@ -0,0 +1,363 @@ +#!/bin/sh + +TRUNK=../.. + +all=0 +valg=0 +libdir=`pwd` +global_args="-c rc/library_search_paths=lib -c rc/export_basename=1 -c design/fab_author=TEST -c rc/quiet=1 -c rc/default_pcb_file={} -c rc/default_font_file=$libdir/default_font" +test_announce=0 +verbose=0 +CONVERT=convert +COMPARE=compare + +if test -z "$pcb_rnd_bin" +then +# running from source + pcb_rnd_cd="$TRUNK/src" + pcb_rnd_bin="./pcb-rnd" +fi + +fmt_args="" + +# portable sed -i implementation with temp files +sedi() +{ + local sc n + sc=$1 + shift 1 + for n in "$@" + do + sed "$sc" < "$n" > "$n.sedi" && mv "$n.sedi" "$n" + done +} + +# Execute pcb-rnd, optionally from trunk/src/, optionally wrapped in valgrind +run_pcb_rnd() +{ + ( + if test ! -z "$pcb_rnd_cd" + then + cd "$pcb_rnd_cd" + fi + $valgr $pcb_rnd_bin "$@" + ) +} + +need_convert() +{ + if test -z "`$CONVERT 2>/dev/null | grep ImageMagick`" -o -z "`$COMPARE 2>/dev/null | grep ImageMagick`" + then + echo "WARNING: ImageMagick convert(1) or compare(1) not found - bitmap compare will be skipped." + CONVERT="" + fi +} + +set_fmt_args() +{ + case "$fmt" in + bboard) need_convert; ext=.bbrd.png ;; + nelma) ext=.nelma.em ;; + bom) ext=.bom ;; + dsn) ext=.dsn ;; + gcode) ext=.gcode;; + IPC-D-356) ext=.net;; + ps) + ext=.ps + fmt_args="-c plugins/draw_fab/omit_date=1" + ;; + eps) + ext=.eps +# fmt_args="-c plugins/draw_fab/omit_date=1" + ;; + XY) ext=.xy ;; + openscad) + ext=.scad + fmt_args="--silk" + ;; + png) + need_convert + fmt_args="--dpi 1200" + ext=.png + ;; + gerber) + fmt_args="--cross-sect -c plugins/draw_fab/omit_date=1" +# multifile: do not set ext + ;; + excellon) + ext="" + ;; + remote) + ext=.remote + ;; + svg) + ext=.svg + ;; + fidocadj) + ext=.fcd + ;; + esac +} + +move_out() +{ + local raw_out="$1" final_out="$2" n + +# remove variable sections + case "$fmt" in + dsn) sedi 's/[(]host_version[^)]*[)]/(host_version "")/g' $raw_out ;; + bom|XY) sedi "s/^# Date:.*$/# Date: /" $raw_out ;; + IPC-D-356) + sedi ' + s/^C File created on .*$/C File created on / + s/^C IPC-D-356 Netlist generated by.*$/C IPC-D-356 Netlist generated by / + ' $raw_out ;; + nelma) + sedi 's@/[*] Made with PCB Nelma export HID [*]/.*@/* banner */@g' $raw_out ;; + gerber) + sedi ' + s/^G04 CreationDate:.*$/G04 CreationDate: / + s/^G04 Creator:.*$/G04 Creator: / + ' $raw_out.*.gbr +# do not save or compare the csect yet + rm $raw_out.*csect*.gbr + ;; + ps) + sedi ' + s@%%CreationDate:.*@%%CreationDate: date@ + s@%%Creator:.*@%%Creator: pcb-rnd@ + s@%%Version:.*@%%Version: ver@ + s@^[(]Created on.*@(Created on date@ + ' $raw_out + ;; + gcode) + for n in `ls $raw_out.*.cnc 2>/dev/null` + do + awk ' + /^[(] / && (NR < 5) { next } # skip date + { print $0 } + ' $n > $n.tmp + mv $n.tmp $n + done + esac + +# move the output file(s) to their final subdir (for multifile formats) and/or +# compress them (for large text files) + case "$fmt" in + bboard) + mv ${raw_out%%.bbrd.png}.png $final_out + ;; + gerber) + mkdir -p $final_out.gbr + mv $raw_out.*.gbr $final_out.gbr + ;; + excellon) + mkdir -p $final_out.exc + mv $raw_out.*.cnc $final_out.exc 2>/dev/null + ;; + nelma) + mv $raw_out $final_out + # do not test the pngs for now + rm -f ${raw_out%%.em}*.png + ;; + remote|ps) + gzip $raw_out + mv $raw_out.gz $final_out.gz + ;; + gcode) + mkdir -p $final_out + files=`ls $raw_out.*.cnc 2>/dev/null` + if test ! -z "$files" + then + mv $files $final_out + rm -f ${raw_out%%.gcode}.*.png + fi + ;; + *) + # common, single file output + if test -f "$raw_out" + then + mv $raw_out $final_out + fi + ;; + esac +} + +cmp_fmt() +{ + local ref="$1" out="$2" n bn otmp + case "$fmt" in + png) + if test ! -z "$CONVERT" + then + bn=`basename $out` + res=`$COMPARE "$ref" "$out" -metric AE diff/$bn 2>&1` + case "$res" in + *widths*) + otmp=$out.599.png + $CONVERT -crop 599x599+0x0 $out $otmp + res=`$COMPARE "$ref" "$otmp" -metric AE diff/$bn 2>&1` + ;; + esac + test "$res" -lt 8 && rm diff/$bn + test "$res" -lt 8 + fi + ;; + bboard) + if test ! -z "$CONVERT" + then + bn=`basename $out` + res=`$COMPARE "$ref" "$out" -metric AE diff/$bn 2>&1` + test "$res" -lt 8 && rm diff/$bn + test "$res" -lt 8 + fi + ;; + gerber) + for n in `ls $ref.gbr/*.gbr 2>/dev/null` + do + bn=`basename $n` + diff -u "$n" "$out.gbr/$bn" + done + ;; + excellon) + for n in `ls $ref.exc/*.cnc 2>/dev/null` + do + bn=`basename $n` + diff -u "$n" "$out.exc/$bn" + done + ;; + ps) + zcat "$ref.gz" > "$ref" + zcat "$out.gz" > "$out" + diff -u "$ref" "$out" && rm "$ref" "$out" + ;; + *) + # simple text files: byte-to-byte match required + diff -u "$ref" "$out" + ;; + esac +} + +# Remove known, expected error messages +stderr_filter() +{ + local common="Couldn't find default.pcb\|No preferred unit format info available for\|has no font information, using default font\|Log produced after failed export\|Exporting empty board\|[*][*][*] Exporting:\|^.pcb-rnd:stderr.[ \t]*$\|Warning: footprint library list" + case "$fmt" in + gerber) grep -v "Can't export polygon as G85 slot\|please use lines for slotting\|$common" ;; + excellon) grep -v "Excellon: can not export [a-z]* (some features may be missing from the export)\|$common" ;; + svg) grep -v "Can't draw elliptical arc on svg\|$common";; + *) grep -v "$common";; + esac +} + +run_test() +{ + local ffn fn="$1" valgr res res2 + + if test "$valg" -gt 0 + then + export valgr="valgrind -v --leak-check=full --show-leak-kinds=all --log-file=`pwd`/$fn.vlog" + fi + + if test "$verbose" -gt 0 + then + echo "=== Test: $fmt $fn ===" + fi + + # run and save stderr in file res2 and stdout in variable res + res2=`mktemp` + ffn="`pwd`/$fn" + res=`run_pcb_rnd -x "$fmt" $global_args $fmt_args "$ffn" 2>$res2` + + # special case error: empty design is not exported; skip the file + if test ! -z "$res" + then + case "$res" in + *"export empty board"*) rm $res2; return 0 ;; + esac + fi + + # print error messages to the log + sed "s/^/[pcb-rnd:stderr] /" < $res2 | stderr_filter >&2 + rm $res2 + + base=${fn%%.pcb} + base=${base%%.lht} + ref_fn=ref/$base$ext + fmt_fn=$base$ext + out_fn=out/$base$ext + + move_out "$fmt_fn" "$out_fn" + cmp_fmt "$ref_fn" "$out_fn" +} + +while test $# -gt 0 +do + case "$1" + in + --list) + run_pcb_rnd -x -list- + exit 0;; + -t) test_announce=1;; + -f|-x) fmt=$2; shift 1;; + -b) pcb_rnd_bin=$2; shift 1;; + -a) all=1;; + -V) valg=1;; + -v) verbose=1;; + *) + if test -z "$fn" + then + fn="$1" + else + echo "unknown switch $1; try --help" >&2 + exit 1 + fi + ;; + esac + shift 1 +done + +if test -z "$fmt" +then + echo "need a format" >&2 +fi + +set_fmt_args + +if test "$test_announce" -gt 0 +then + echo -n "$fmt: ... " +fi + +bad="" +if test "$all" -gt 0 +then + for n in `ls *.lht *.pcb 2>/dev/null` + do + case $n in + *Proto.lht) continue;; + *Proto.pcb) continue;; + *default.lht) continue;; + *default.pcb) continue;; + *) run_test "$n" || bad="$bad $n" ;; + esac + done +else + run_test "$fn" || bad="$bad $n" +fi + +if test ! -z "$bad" +then + if test "$verbose" -gt 0 + then + echo "$fmt: ... BROKEN: $bad" + else + echo "$fmt: ... BROKEN" + fi + exit 1 +else + echo "ok" + exit 0 +fi + + Property changes on: tags/2.3.0/tests/RTT/Export.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/RTT/Makefile =================================================================== --- tags/2.3.0/tests/RTT/Makefile (nonexistent) +++ tags/2.3.0/tests/RTT/Makefile (revision 33253) @@ -0,0 +1,10 @@ +all: + +ROOT=../.. +include $(ROOT)/Makefile.conf + +test: + @./Test_export.sh && echo "*** export: QC PASS ***" + +clean: + $(SCCBOX) rm -f out/*/* out/* diff/* Index: tags/2.3.0/tests/RTT/Proto.pcb =================================================================== --- tags/2.3.0/tests/RTT/Proto.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/Proto.pcb (revision 33253) @@ -0,0 +1,43 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/README =================================================================== --- tags/2.3.0/tests/RTT/README (nonexistent) +++ tags/2.3.0/tests/RTT/README (revision 33253) @@ -0,0 +1,3 @@ +This directory contains a set of round-trip-test designs. Each design +demonstrates a feature, as purely as possible. The purpose is to use these +as test cases for automatic mapping of file format compatibility (TODO). Index: tags/2.3.0/tests/RTT/RTT_kicad_legacy_summary.txt =================================================================== --- tags/2.3.0/tests/RTT/RTT_kicad_legacy_summary.txt (nonexistent) +++ tags/2.3.0/tests/RTT/RTT_kicad_legacy_summary.txt (revision 33253) @@ -0,0 +1,17 @@ +feature supported partial_support unsupported reason test_case +round pins Y X X universal, lossless x +octagonal pins X Y X gEDA native, no kicad support, export as round x +rectangular SMD Y X X gEDA native, kicad native support x +copper arcs X Y X converted to lines on export x +copper line Y X X universal, lossless x +silk line Y X X universal, lossless x +silk arc X Y X kicad supports multiples of 90 degrees only x +silk circle Y X X universal, lossless x +element value, name X Y X gEDA does not store text label locations x +layout modules/footprints Y X X geometry preserved x +track netlist X X Y gEDA does not store netlist for tracks x +via X Y X kicad uses polygonal zones to manage via thermal properties within it x +copper pours X Y X kicad applies pullback to margins of polygonal zones x +polygon windows X X Y yet to be implemented x +text labels X Y X font kerning, placement not exact x + Index: tags/2.3.0/tests/RTT/RTT_kicad_summary.txt =================================================================== --- tags/2.3.0/tests/RTT/RTT_kicad_summary.txt (nonexistent) +++ tags/2.3.0/tests/RTT/RTT_kicad_summary.txt (revision 33253) @@ -0,0 +1,26 @@ +feature supported partial_support unsupported reason test_case +round pins Y X X universal x +octagonal pins X Y X gEDA native, no kicad support, export as round x +rectangular SMD Y X X gEDA native, kicad native support x +trapezoidal SMD X Y X converted to rectangular on import x +rounded corner SMD X Y X converted to rectangular on import x +copper arcs X Y X converted to lines on export x +copper line Y X X universal, lossless x +track clearance X Y X per track clearance not preserved x +silk line Y X X universal, lossless x +silk arc X Y X kicad supports multiples of 90deg only x +silk circle Y X X universal, lossless x +element value, name X Y X gEDA does not store text label locations x +layout modules/footprints Y X X geometry preserved x +track netlist X X Y gEDA does not store netlist for tracks x +rat lines X X Y kicad does not have an equivalent x +via X Y X kicad uses polygonal zones to manage thermal properties within it x +copper pours X Y X kicad applied pullback to margins of polygonal zones x +polygon windows X X Y yet to be implemented x +text labels X Y X font kerning, placement not exact x +text style X X Y italic, bold, unsupported on import x +text size X Y X font size, kerning, placement not exact x +text clearline flag X X Y no kicad equivalent x +font data X X Y font symbol not preserved on export x +layer naming X Y X non standard kicad layer names are not preserved layer_outline.pcb +layer order Y X X layer order preserved, but names may not be x Index: tags/2.3.0/tests/RTT/Remote_dump.sh =================================================================== --- tags/2.3.0/tests/RTT/Remote_dump.sh (nonexistent) +++ tags/2.3.0/tests/RTT/Remote_dump.sh (revision 33253) @@ -0,0 +1,12 @@ +#!/bin/sh +# dump remote HID communication + +echo ' + MakeGC(1) + Ready() + MakeGC(2) + MakeGC(3) + MakeGC(4) +' | pcb-rnd --gui remote $1 | grep -v "^[A-Z]:" > out/${1%%.pcb}.remote +rm -f out/${1%%.pcb}.remote.gz +gzip out/${1%%.pcb}.remote Property changes on: tags/2.3.0/tests/RTT/Remote_dump.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/RTT/Rtt.sh =================================================================== --- tags/2.3.0/tests/RTT/Rtt.sh (nonexistent) +++ tags/2.3.0/tests/RTT/Rtt.sh (revision 33253) @@ -0,0 +1,16 @@ +#!/bin/sh + +# local wrapper around pcb-rtrip so it all can be executed from the source +# tree, without installation + +TRUNK=../.. +pcb_rnd_bin="$TRUNK/src/pcb-rnd" +RTRIP="$TRUNK/util/devhelpers/pcb-rtrip" + +( + . $RTRIP + if test -f core + then + mv core "$fn.core" + fi +) 2>&1 | grep -v "PCBChanged\|readres=-1\|No PCB loaded\|has no font information, using default font\|WARNING.*is not uninited\|but first saves\|WARNING.*left registered\|gpmi dirs:" Property changes on: tags/2.3.0/tests/RTT/Rtt.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/RTT/Rtt_all.sh =================================================================== --- tags/2.3.0/tests/RTT/Rtt_all.sh (nonexistent) +++ tags/2.3.0/tests/RTT/Rtt_all.sh (revision 33253) @@ -0,0 +1,16 @@ +#!/bin/sh + +ulimit -c unlimited +rm core +all=`ls *.pcb | grep -v "[.]new[.]pcb$\|[.]orig[.]pcb$\|^[.]"` +num_all=`echo "$all" | wc -l` + +cnt=0 +for n in $all +do + cnt=$(($cnt+1)) + echo "----------------------$n" + echo "----------------------$n $cnt/$num_all" >&2 + ./Rtt.sh $n "$@" +done > All.log + Property changes on: tags/2.3.0/tests/RTT/Rtt_all.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/RTT/Test_export.sh =================================================================== --- tags/2.3.0/tests/RTT/Test_export.sh (nonexistent) +++ tags/2.3.0/tests/RTT/Test_export.sh (revision 33253) @@ -0,0 +1,49 @@ +#!/bin/sh + +# Run the export test on all formats that have refs _and_ are supported +# by our current pcb-rnd executable + +tester="./Export.sh -t -a" + +# disabled until the rewrite: +#IPC-D-356 +# disabled until figuring the rotation: +#dsn +want=' +bom +eps +ps +XY 2>/dev/null +png +gerber +svg 2>/dev/null +' + +have=`./Export.sh --list` + +export fail=0 +echo "$want" | while read fmt args +do + if test ! -z "$fmt" + then + have_=`echo "$have"|grep "^$fmt$"` + if test ! -z "$have_" + then + eval "$tester -f $fmt $args" + if test "$?" -ne "0" + then + fail=1 + fi + else + echo "$fmt: SKIP (plugin not enabled)" + fi + fi + + # the only way to set the return value of the while() + if test "$fail" -ne "0" + then + false + else + true + fi +done Property changes on: tags/2.3.0/tests/RTT/Test_export.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/RTT/Vailidation.txt =================================================================== --- tags/2.3.0/tests/RTT/Vailidation.txt (nonexistent) +++ tags/2.3.0/tests/RTT/Vailidation.txt (revision 33253) @@ -0,0 +1,111 @@ + Validation state of references +# +# Each line is a file from ref/, in the following format: +# The first word is the file name, relative to ref/ +# The second word is either "good" or "bad" +# The third word is the revision number the output file had at the moment of +# check (the "Last Changed Revision line in 'svn info ref/filename') +# The rest of the line is a real short summary on whaty's broken, if the +# second column was "bad". +# +# There's no particular order of lines. If you recheck a file, edit the exiting +# line, each ref file should have only one line in this file. If you are doing +# checks, please insert new lines somewhere in the list, preferrably not at the +# end, so we can avoid svn conflicts in concurrent edits. +# +# Test method: open the .pcb file with pcb-rnd, open the ref/ file with +# the appropriate viewer, look at them side by side and decide if the reference +# output fully matches the input, in all relevant details. What relevent +# details are can be file format specific. +# + +Proto.bom good r5452 +coord_rounding.bom good r5652 +elem_pads.bom good r5652 +elem_pads_ds.bom good r5652 +elem_pins.bom good r5652 +elem_sides_smd.bom good r5652 +elem_sides_trh.bom good r5652 +arc_f_clear.bom good r6630 +arc_normal.bom good r6630 +arc_offpage.bom good r6630 +arc_sizes.bom good r6630 +arc_angles.bom good r6630 +arc_sizes.svg broken r6023 ellipticals not handled +arc_angles.png good r6630 +arc_f_clear.png bad r6630 +arc_normal.png good r6630 +arc_offpage.png good r6630 +arc_sizes.png good r6630 +coord_rounding.png good r6630 +clearance.png bad r6630 missing pcb & text file?! +elem_pads_ds.png good r6630 +elem_pads.png good r6630 +elem_pins.png good r6630 +elem_sides_smd.png good r6630 +elem_sides_trh.png good r6630 +layer_copper.png good r6630 +layer_outline.png good r6630 +layer_spc.png good r6630 +line_f_clear.png good r6630 +line_normal.png good r6630 +line_offpage.png good r6630 +line_overlap1.png good r6630 +line_overlap2.png good r6630 +line_overlap3.png good r6630 +line_overlap4.png good r6630 +line_zerolen.png good r6630 +netlist.png good r6630 +netlist_ba.png good r6630 +poly_hole.png good r6630 +poly_rect.png good r6630 +poly_triangle.png good r6630 +Proto.png good r6731 +rat.png good r6731 +text_rot.png good r6731 +text_scale.png good r6731 +text_sides.png good r6731 +thermal_last.png good r6731 +thermal_layer.png good r6731 +arc_angles.eps bad r13746 geometry is okay, outline layer missing +arc_f_clear.eps bad r13746 geometry is okay, outline layer missing +arc_normal.eps bad r13746 geometry is okay, outline layer missing +arc_offpage.eps bad r13746 geometry is okay, outline layer missing +arc_sizes.eps bad r13746 totally broken arc corner cases +comp1.eps bad r13746 missing line, see bug_files/eps_comp1.png +elem_pads.eps bad r13746 suspected pad placement rounding error, see bug_files/eps_elem_pads.png +elem_pads_ds.eps bad r13746 geometry is okay, outline layer missing +coord_rounding.dsn good r17050 +elem_pads.dsn good r17050 +elem_pins.dsn good r17050 +elem_sides_smd.dsn good r17050 +elem_sides_trh.dsn good r17050 +layer_copper.dsn good r17050 +line_overlap1.dsn good r17050 +line_overlap2.dsn good r17050 +line_overlap3.dsn good r17050 +line_overlap4.dsn good r17050 (poly missing) +netlist_ba.dsn good r17050 +netlist.dsn good r17050 +padrot.dsn good r17050 +line_f_clear.dsn good r17050 (poly missing) +line_normal.dsn good r17050 (poly missing) +arc_angles.dsn good r17050 (arc missing) +arc_f_clear.dsn good r17050 (arc missing) +arc_normal.dsn good r17050 (arc missing) +arc_offpage.dsn good r17050 (arc missing) +arc_sizes.dsn good r17050 (arc missing) +layer_outline.dsn good r17050 +layer_silk.dsn good r17050 (silk objects not exported) +layer_spc.dsn good r17050 +poly_hole.dsn good r17050 (polys missing) +poly_rect.dsn good r17050 (polys missing) +poly_triangle.dsn good r17050 (polys missing) +rat.dsn good r17050 +text_rot.dsn good r17050 (text missing) +text_scale.dsn good r17050 (text missing) +text_sides.dsn good r17050 (text missing) +thermal_layer.dsn bad r17050 missing padstack via +comp1.dsn bad r17050 missing padstack via +padstack.dsn bad r17050 missing padstack via +elem_pads_ds.dsn bad r17050 geo okay, but square in freerouting, rounded on pcb-rnd Index: tags/2.3.0/tests/RTT/Viscomp =================================================================== --- tags/2.3.0/tests/RTT/Viscomp (nonexistent) +++ tags/2.3.0/tests/RTT/Viscomp (revision 33253) @@ -0,0 +1,29 @@ +#!/bin/sh + +if test ! -f out/$1 +then + echo "Need an output file name, e.g. arc_angles.ps" >&2 + exit 1 +fi + +name=`echo $1 | sed "s/[.][^.]*$//"` + + +mkdir -p diff + +echo "convert ref..." +convert -density 200 ref/$1 diff/ref_$name.png + +echo "convert out..." +convert -density 200 out/$1 diff/out_$name.png + +echo "diff:" + +for n in diff/ref_$name*.png +do + m=`echo "$n" | sed "s/ref_/out_/"` + d=`echo "$n" | sed "s/ref_/diff_/"` + res=`compare "$n" "$m" -metric AE $d 2>&1` + echo " $n \"$res\"" + test "$res" -lt 8 && rm $d $n $m +done Property changes on: tags/2.3.0/tests/RTT/Viscomp ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/RTT/arc_angles.pcb =================================================================== --- tags/2.3.0/tests/RTT/arc_angles.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/arc_angles.pcb (revision 33253) @@ -0,0 +1,46 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["arcs with different strange angles" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 635000nm 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Layer(1 "comp1") +( + Arc[100mil 100mil 50mil 50mil 254000nm 1016000nm 0 750 ""] + Arc[300mil 100mil 50mil 50mil 254000nm 1016000nm 0 0 ""] + Arc[400mil 100mil 50mil 50mil 254000nm 1016000nm 0 -750 ""] +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/arc_f_clear.pcb =================================================================== --- tags/2.3.0/tests/RTT/arc_f_clear.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/arc_f_clear.pcb (revision 33253) @@ -0,0 +1,51 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Arc with clearline flag" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Layer(1 "comp1") +( + Arc[5080000nm 5715000nm 3175000nm 3175000nm 254000nm 1016000nm 0 90 "clearline"] + Arc[4445000nm 5715000nm 2540000nm 2540000nm 508000nm 1016000nm -10 -80 ""] + Arc[7620000nm 6985000nm 635000nm 635000nm 254000nm 1016000nm 0 300 "clearline"] + Arc[6350000nm 5715000nm 3175000nm 3175000nm 762000nm 1016000nm -70 -90 ""] + Polygon("clearpoly") + ( + [635000nm 3810000nm] [12065000nm 3810000nm] [12065000nm 12065000nm] [635000nm 12065000nm] + ) +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/arc_normal.pcb =================================================================== --- tags/2.3.0/tests/RTT/arc_normal.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/arc_normal.pcb (revision 33253) @@ -0,0 +1,47 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Arcs with different sizes, normal cases" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 635000nm 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Layer(1 "comp1") +( + Arc[5080000nm 5715000nm 3175000nm 3175000nm 254000nm 1016000nm 0 90 ""] + Arc[4445000nm 5715000nm 2540000nm 2540000nm 508000nm 1016000nm -10 -80 ""] + Arc[7620000nm 6985000nm 635000nm 635000nm 254000nm 1016000nm 0 300 ""] + Arc[6350000nm 5715000nm 3175000nm 3175000nm 762000nm 1016000nm -70 -90 ""] +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/arc_offpage.pcb =================================================================== --- tags/2.3.0/tests/RTT/arc_offpage.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/arc_offpage.pcb (revision 33253) @@ -0,0 +1,44 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Arcs with some parts off the page" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 635000nm 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Layer(1 "comp1") +( + Arc[50mil 50mil 100mil 100mil 254000nm 1016000nm 0 230 ""] +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/arc_sizes.pcb =================================================================== --- tags/2.3.0/tests/RTT/arc_sizes.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/arc_sizes.pcb (revision 33253) @@ -0,0 +1,47 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["arcs with different strange sizes" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 635000nm 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Layer(1 "comp1") +( + Arc[100mil 200mil 0mil 50mil 254000nm 1016000nm 0 90 ""] + Arc[200mil 200mil 50mil 0mil 254000nm 1016000nm 0 90 ""] + Arc[300mil 200mil 0mil 0mil 254000nm 1016000nm 0 90 ""] + +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/comp1.pcb =================================================================== --- tags/2.3.0/tests/RTT/comp1.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/comp1.pcb (revision 33253) @@ -0,0 +1,358 @@ +ha:pcb-rnd-board-v2 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:style1 { + diameter = 1.999995mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:style2 { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999997mm + clearance = 20.0mil + } + ha:style3 { + diameter = 3.500119mm + thickness = 80.0mil + hole = 1.199895mm + clearance = 25.0mil + } + ha:style4 { + diameter = 64.0mil + thickness = 100.0mil + hole = 31.5mil + clearance = 100.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 500.0mil + y = 500.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 0.0 + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + + li:objects { + ha:via.31 { + x=250.0mil; y=75.0mil; hole=0.999998mm; mask=0.0; thickness=2.199894mm; clearance=40.0mil; + ha:flags { + via=1 + } + } + } + li:layers { + + ha:comp1 { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:line.38 { + x1=25.0mil; y1=150.0mil; x2=475.0mil; y2=150.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + } + + ha:solder1 { + lid=1 + group=10 + ha:combining { } + visible=1 + + li:objects { + ha:line.41 { + x1=25.0mil; y1=125.0mil; x2=475.0mil; y2=125.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + } + + ha:com2 { + lid=2 + group=3 + ha:combining { } + visible=1 + } + + ha:solder2 { + lid=3 + group=10 + ha:combining { } + visible=1 + } + + ha:inner1 { + lid=4 + group=5 + ha:combining { } + visible=1 + } + + ha:inner2 { + lid=5 + group=7 + ha:combining { } + visible=1 + } + + ha:outline { + lid=6 + group=9 + ha:combining { } + visible=1 + } + + ha:silk { + lid=7 + group=12 + ha:combining { auto=1; } + visible=1 + } + + ha:silk { + lid=8 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:polygon.5 { + li:geometry { + ta:contour { + { 25.0mil; 25.0mil } + { 175.0mil; 25.0mil } + { 175.0mil; 175.0mil } + { 25.0mil; 175.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.21 { + li:geometry { + ta:contour { + { 200.0mil; 25.0mil } + { 475.0mil; 25.0mil } + { 475.0mil; 475.0mil } + { 200.0mil; 475.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + } + + ha:neg { + lid=9 + group=1 + ha:combining { sub=1; } + visible=1 + + li:objects { + ha:line.10 { + x1=100.0mil; y1=250.0mil; x2=100.0mil; y2=125.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.32 { + x=0.0; y=0.0; width=75.0mil; height=75.0mil; astart=90; adelta=90; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.26 { + li:geometry { + ta:contour { + { 225.0mil; 50.0mil } + { 450.0mil; 50.0mil } + { 450.0mil; 450.0mil } + { 225.0mil; 450.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + } + + ha:pos { + lid=10 + group=1 + ha:combining { } + visible=1 + + li:objects { + ha:line.13 { + x1=100.0mil; y1=225.0mil; x2=100.0mil; y2=125.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + } + } + } + + ha:netlists { + li:input { + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { } + } + ha:1 { + name = top_silk + ha:type { silk=1; top=1; } + li:layers { 8; 9; 10; } + } + ha:2 { + name = top_mask + ha:type { top=1; mask=1; } + li:layers { } + } + ha:3 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 4; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_6 + } + ha:7 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 5; } + } + ha:8 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_8 + } + ha:9 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 6; } + } + 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 { } + } + 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 { } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + line_thickness = 20.00 mil + groups = {1,3,c:2,4,s:5:6:7} + via_thickness = 86.61 mil + via_drilling_hole = 39.37 mil + clearance = 20.00 mil + } + ha:editor { + live_routing = false + snap_pin = true + draw_grid = true + swap_start_direction = false + full_poly = false + clear_line = true + show_number = false + auto_drc = false + all_direction_lines = false + lock_names = false + unique_names = false + only_names = false + hide_names = false + orthogonal_moves = false + thin_draw = false + rubber_band_mode = false + name_on_pcb = true + thin_draw_poly = false + check_planes = false + description = false + local_ref = false + show_drc = false + grid_unit = mil + } + ha:plugins { + ha:mincut { + enable = false + } + } + } + } +} Index: tags/2.3.0/tests/RTT/coord_rounding.pcb =================================================================== --- tags/2.3.0/tests/RTT/coord_rounding.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/coord_rounding.pcb (revision 33253) @@ -0,0 +1,45 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["odd coordinates to check rounding errors" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[1270000nm 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Layer(1 "comp1") +( + Line[6000000nm 6100000nm 6110000nm 6111000nm 1mm 1mm ""] + Line[6111100nm 6111110nm 6111111nm 6111000nm 1mm 1mm ""] +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/default_font =================================================================== --- tags/2.3.0/tests/RTT/default_font (nonexistent) +++ tags/2.3.0/tests/RTT/default_font (revision 33253) @@ -0,0 +1,309 @@ +# Minimal symbol set: space, 1..9, A..Z +Symbol(' ' 18) +( +) +Symbol('1' 12) +( + SymbolLine( 0 8 8 0 8) + SymbolLine( 8 0 8 40 8) + SymbolLine( 0 40 15 40 8) +) +Symbol('2' 12) +( + SymbolLine(0 5 5 0 8) + SymbolLine(5 0 20 0 8) + SymbolLine(20 0 25 5 8) + SymbolLine(25 5 25 15 8) + SymbolLine(0 40 25 15 8) + SymbolLine(0 40 25 40 8) +) +Symbol('3' 12) +( + SymbolLine( 0 5 5 0 8) + SymbolLine( 5 0 15 0 8) + SymbolLine(15 0 20 5 8) + SymbolLine(15 40 20 35 8) + SymbolLine( 5 40 15 40 8) + SymbolLine( 0 35 5 40 8) + + SymbolLine( 5 18 15 18 8) + SymbolLine(20 5 20 13 8) + SymbolLine(20 23 20 35 8) + SymbolLine(20 23 15 18 8) + SymbolLine(20 13 15 18 8) +) +Symbol('4' 12) +( + SymbolLine(0 25 20 0 8) + SymbolLine(0 25 25 25 8) + SymbolLine(20 0 20 40 8) +) +Symbol('5' 12) +( + SymbolLine(0 0 20 0 8) + SymbolLine(0 0 0 20 8) + SymbolLine(0 20 5 15 8) + SymbolLine(5 15 15 15 8) + SymbolLine(15 15 20 20 8) + SymbolLine(20 20 20 35 8) + SymbolLine(15 40 20 35 8) + SymbolLine(5 40 15 40 8) + SymbolLine(0 35 5 40 8) +) +Symbol('6' 12) +( + SymbolLine(15 0 20 5 8) + SymbolLine( 5 0 15 0 8) + SymbolLine( 0 5 5 0 8) + SymbolLine( 0 5 0 35 8) + SymbolLine( 0 35 5 40 8) + SymbolLine(15 18 20 23 8) + SymbolLine( 0 18 15 18 8) + SymbolLine( 5 40 15 40 8) + SymbolLine(15 40 20 35 8) + SymbolLine(20 23 20 35 8) +) +Symbol('7' 12) +( + SymbolLine( 5 40 25 0 8) + SymbolLine( 0 0 25 0 8) +) +Symbol('8' 12) +( + SymbolLine( 0 35 5 40 8) + SymbolLine( 0 27 0 35 8) + SymbolLine( 0 27 7 20 8) + SymbolLine( 7 20 13 20 8) + SymbolLine(13 20 20 27 8) + SymbolLine(20 27 20 35 8) + SymbolLine(15 40 20 35 8) + SymbolLine( 5 40 15 40 8) + SymbolLine( 0 13 7 20 8) + SymbolLine( 0 5 0 13 8) + SymbolLine( 0 5 5 0 8) + SymbolLine( 5 0 15 0 8) + SymbolLine(15 0 20 5 8) + SymbolLine(20 5 20 13 8) + SymbolLine(13 20 20 13 8) +) +Symbol('9' 12) +( + SymbolLine(5 40 20 20 8) + SymbolLine(20 5 20 20 8) + SymbolLine(15 0 20 5 8) + SymbolLine(5 0 15 0 8) + SymbolLine(0 5 5 0 8) + SymbolLine(0 5 0 15 8) + SymbolLine(0 15 5 20 8) + SymbolLine(5 20 20 20 8) +) +Symbol('A' 12) +( + SymbolLine( 0 10 0 40 8) + SymbolLine( 0 10 7 0 8) + SymbolLine( 7 0 18 0 8) + SymbolLine(18 0 25 10 8) + SymbolLine(25 10 25 40 8) + SymbolLine( 0 20 25 20 8) +) +Symbol('B' 12) +( + SymbolLine( 0 40 20 40 8) + SymbolLine(20 40 25 35 8) + SymbolLine(25 23 25 35 8) + SymbolLine(20 18 25 23 8) + SymbolLine( 5 18 20 18 8) + SymbolLine( 5 0 5 40 8) + SymbolLine( 0 0 20 0 8) + SymbolLine(20 0 25 5 8) + SymbolLine(25 5 25 13 8) + SymbolLine(20 18 25 13 8) +) +Symbol('C' 12) +( + SymbolLine(7 40 20 40 8) + SymbolLine(0 33 7 40 8) + SymbolLine(0 7 0 33 8) + SymbolLine(0 7 7 0 8) + SymbolLine(7 0 20 0 8) +) +Symbol('D' 12) +( + SymbolLine( 5 0 5 40 8) + SymbolLine(18 0 25 7 8) + SymbolLine(25 7 25 33 8) + SymbolLine(18 40 25 33 8) + SymbolLine( 0 40 18 40 8) + SymbolLine( 0 0 18 0 8) +) +Symbol('E' 12) +( + SymbolLine(0 18 15 18 8) + SymbolLine(0 40 20 40 8) + SymbolLine(0 0 0 40 8) + SymbolLine(0 0 20 0 8) +) +Symbol('F' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 0 20 0 8) + SymbolLine(0 18 15 18 8) +) +Symbol('G' 12) +( + SymbolLine(20 0 25 5 8) + SymbolLine(5 0 20 0 8) + SymbolLine(0 5 5 0 8) + SymbolLine(0 5 0 35 8) + SymbolLine(0 35 5 40 8) + SymbolLine(5 40 20 40 8) + SymbolLine(20 40 25 35 8) + SymbolLine(25 25 25 35 8) + SymbolLine(20 20 25 25 8) + SymbolLine(10 20 20 20 8) +) +Symbol('H' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(25 0 25 40 8) + SymbolLine(0 20 25 20 8) +) +Symbol('I' 12) +( + SymbolLine(0 0 10 0 8) + SymbolLine(5 0 5 40 8) + SymbolLine(0 40 10 40 8) +) +Symbol('J' 12) +( + SymbolLine( 7 0 15 0 8) + SymbolLine(15 0 15 35 8) + SymbolLine(10 40 15 35 8) + SymbolLine( 5 40 10 40 8) + SymbolLine( 0 35 5 40 8) + SymbolLine( 0 35 0 30 8) +) +Symbol('K' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 20 20 0 8) + SymbolLine(0 20 20 40 8) +) +Symbol('L' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 40 20 40 8) +) +Symbol('M' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 0 15 20 8) + SymbolLine(15 20 30 0 8) + SymbolLine(30 0 30 40 8) +) +Symbol('N' 12) +( + SymbolLine(0 0 0 40 8) + SymbolLine(0 0 25 40 8) + SymbolLine(25 0 25 40 8) +) +Symbol('O' 12) +( + SymbolLine(0 5 0 35 8) + SymbolLine(0 5 5 0 8) + SymbolLine(5 0 15 0 8) + SymbolLine(15 0 20 5 8) + SymbolLine(20 5 20 35 8) + SymbolLine(15 40 20 35 8) + SymbolLine(5 40 15 40 8) + SymbolLine(0 35 5 40 8) +) +Symbol('P' 12) +( + SymbolLine(5 0 5 40 8) + SymbolLine(0 0 20 0 8) + SymbolLine(20 0 25 5 8) + SymbolLine(25 5 25 15 8) + SymbolLine(20 20 25 15 8) + SymbolLine(5 20 20 20 8) +) +Symbol('Q' 12) +( + SymbolLine( 0 5 0 35 8) + SymbolLine( 0 5 5 0 8) + SymbolLine( 5 0 15 0 8) + SymbolLine(15 0 20 5 8) + SymbolLine(20 5 20 30 8) + SymbolLine(10 40 20 30 8) + SymbolLine( 5 40 10 40 8) + SymbolLine( 0 35 5 40 8) + SymbolLine(10 25 20 40 8) +) +Symbol('R' 12) +( + SymbolLine( 0 0 20 0 8) + SymbolLine(20 0 25 5 8) + SymbolLine(25 5 25 15 8) + SymbolLine(20 20 25 15 8) + SymbolLine( 5 20 20 20 8) + SymbolLine( 5 0 5 40 8) + SymbolLine(13 20 25 40 8) +) +Symbol('S' 12) +( + SymbolLine(20 0 25 5 8) + SymbolLine(5 0 20 0 8) + SymbolLine(0 5 5 0 8) + SymbolLine(0 5 0 15 8) + SymbolLine(0 15 5 20 8) + SymbolLine(5 20 20 20 8) + SymbolLine(20 20 25 25 8) + SymbolLine(25 25 25 35 8) + SymbolLine(20 40 25 35 8) + SymbolLine(5 40 20 40 8) + SymbolLine(0 35 5 40 8) +) +Symbol('T' 12) +( + SymbolLine(0 0 20 0 8) + SymbolLine(10 0 10 40 8) +) +Symbol('U' 12) +( + SymbolLine(0 0 0 35 8) + SymbolLine(0 35 5 40 8) + SymbolLine(5 40 15 40 8) + SymbolLine(15 40 20 35 8) + SymbolLine(20 0 20 35 8) +) +Symbol('V' 12) +( + SymbolLine( 0 0 10 40 8) + SymbolLine(10 40 20 0 8) +) +Symbol('W' 12) +( + SymbolLine( 0 0 0 20 8) + SymbolLine( 0 20 5 40 8) + SymbolLine( 5 40 15 20 8) + SymbolLine(15 20 25 40 8) + SymbolLine(25 40 30 20 8) + SymbolLine(30 20 30 0 8) +) +Symbol('X' 12) +( + SymbolLine( 0 40 25 0 8) + SymbolLine( 0 0 25 40 8) +) +Symbol('Y' 12) +( + SymbolLine( 0 0 10 20 8) + SymbolLine(10 20 20 0 8) + SymbolLine(10 20 10 40 8) +) +Symbol('Z' 12) +( + SymbolLine( 0 0 25 0 8) + SymbolLine( 0 40 25 0 8) + SymbolLine( 0 40 25 40 8) +) Index: tags/2.3.0/tests/RTT/elem_pads.pcb =================================================================== --- tags/2.3.0/tests/RTT/elem_pads.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/elem_pads.pcb (revision 33253) @@ -0,0 +1,68 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["pads with different geometry" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") + +Element["" "Standard SMT resistor, capacitor etc" "R1" "1206" 6350000nm 2540000nm -800100nm 1104900nm 0 100 ""] +( + Pad[-1499870nm -299974nm -1499870nm 299974nm 1299972nm 508000nm 1452372nm "1" "1" "square"] + Pad[1499870nm -299974nm 1499870nm 299974nm 1299972nm 508000nm 1452372nm "2" "2" "square"] + ElementLine [-599948nm -949960nm 599948nm -949960nm 203200nm] + ElementLine [-599948nm 949960nm 599948nm 949960nm 203200nm] + + ) + +Element["" "SMT transistor, 5 pins" "U1" "SOT325" 5689600nm 9525000nm 25400nm 1016000nm 0 100 ""] +( + Pad[0 -254000nm 0 254000nm 381000nm 762000nm 533400nm "1" "1" "square,edge2"] + Pad[1295400nm -254000nm 1295400nm 254000nm 381000nm 762000nm 533400nm "2" "2" "square,edge2"] + Pad[1295400nm -2032000nm 1295400nm -1524000nm 381000nm 762000nm 533400nm "3" "3" "square"] + Pad[660400nm -2032000nm 660400nm -1524000nm 381000nm 762000nm 533400nm "4" "4" "square"] + Pad[0 -2032000nm 0 -1524000nm 381000nm 762000nm 533400nm "5" "5" "square"] + ElementLine [-355600nm -2387600nm -355600nm 635000nm 254000nm] + ElementLine [-355600nm 635000nm 1676400nm 635000nm 254000nm] + ElementLine [1676400nm 635000nm 1676400nm -2387600nm 254000nm] + ElementLine [1676400nm -2387600nm -355600nm -2387600nm 254000nm] + + ) +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/elem_pads_ds.pcb =================================================================== --- tags/2.3.0/tests/RTT/elem_pads_ds.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/elem_pads_ds.pcb (revision 33253) @@ -0,0 +1,365 @@ +# release: pcb-rnd 1.1.3 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["element with pads on both sides" 50000 50000] + +Grid[2500 0 0 1] +Cursor[0 10000 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,1000,7874,3150,2000:style2,2000,8661,3937,2000:style3,8000,13780,4724,2500:style4,10000,6400,3150,10000"] + +Symbol[' ' 1800] +( +) +Symbol['1' 1200] +( + SymbolLine[0 800 800 0 800] + SymbolLine[800 0 800 4000 800] + SymbolLine[0 4000 1500 4000 800] +) +Symbol['2' 1200] +( + SymbolLine[0 500 500 0 800] + SymbolLine[500 0 2000 0 800] + SymbolLine[2000 0 2500 500 800] + SymbolLine[2500 500 2500 1500 800] + SymbolLine[0 4000 2500 1500 800] + SymbolLine[0 4000 2500 4000 800] +) +Symbol['3' 1200] +( + SymbolLine[0 500 500 0 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[1500 0 2000 500 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[500 1800 1500 1800 800] + SymbolLine[2000 500 2000 1300 800] + SymbolLine[2000 2300 2000 3500 800] + SymbolLine[2000 2300 1500 1800 800] + SymbolLine[2000 1300 1500 1800 800] +) +Symbol['4' 1200] +( + SymbolLine[0 2500 2000 0 800] + SymbolLine[0 2500 2500 2500 800] + SymbolLine[2000 0 2000 4000 800] +) +Symbol['5' 1200] +( + SymbolLine[0 0 2000 0 800] + SymbolLine[0 0 0 2000 800] + SymbolLine[0 2000 500 1500 800] + SymbolLine[500 1500 1500 1500 800] + SymbolLine[1500 1500 2000 2000 800] + SymbolLine[2000 2000 2000 3500 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[0 3500 500 4000 800] +) +Symbol['6' 1200] +( + SymbolLine[1500 0 2000 500 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[0 500 500 0 800] + SymbolLine[0 500 0 3500 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[1500 1800 2000 2300 800] + SymbolLine[0 1800 1500 1800 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[2000 2300 2000 3500 800] +) +Symbol['7' 1200] +( + SymbolLine[500 4000 2500 0 800] + SymbolLine[0 0 2500 0 800] +) +Symbol['8' 1200] +( + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 2700 0 3500 800] + SymbolLine[0 2700 700 2000 800] + SymbolLine[700 2000 1300 2000 800] + SymbolLine[1300 2000 2000 2700 800] + SymbolLine[2000 2700 2000 3500 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[0 1300 700 2000 800] + SymbolLine[0 500 0 1300 800] + SymbolLine[0 500 500 0 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[1500 0 2000 500 800] + SymbolLine[2000 500 2000 1300 800] + SymbolLine[1300 2000 2000 1300 800] +) +Symbol['9' 1200] +( + SymbolLine[500 4000 2000 2000 800] + SymbolLine[2000 500 2000 2000 800] + SymbolLine[1500 0 2000 500 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[0 500 500 0 800] + SymbolLine[0 500 0 1500 800] + SymbolLine[0 1500 500 2000 800] + SymbolLine[500 2000 2000 2000 800] +) +Symbol['A' 1200] +( + SymbolLine[0 1000 0 4000 800] + SymbolLine[0 1000 700 0 800] + SymbolLine[700 0 1800 0 800] + SymbolLine[1800 0 2500 1000 800] + SymbolLine[2500 1000 2500 4000 800] + SymbolLine[0 2000 2500 2000 800] +) +Symbol['B' 1200] +( + SymbolLine[0 4000 2000 4000 800] + SymbolLine[2000 4000 2500 3500 800] + SymbolLine[2500 2300 2500 3500 800] + SymbolLine[2000 1800 2500 2300 800] + SymbolLine[500 1800 2000 1800 800] + SymbolLine[500 0 500 4000 800] + SymbolLine[0 0 2000 0 800] + SymbolLine[2000 0 2500 500 800] + SymbolLine[2500 500 2500 1300 800] + SymbolLine[2000 1800 2500 1300 800] +) +Symbol['C' 1200] +( + SymbolLine[700 4000 2000 4000 800] + SymbolLine[0 3300 700 4000 800] + SymbolLine[0 700 0 3300 800] + SymbolLine[0 700 700 0 800] + SymbolLine[700 0 2000 0 800] +) +Symbol['D' 1200] +( + SymbolLine[500 0 500 4000 800] + SymbolLine[1800 0 2500 700 800] + SymbolLine[2500 700 2500 3300 800] + SymbolLine[1800 4000 2500 3300 800] + SymbolLine[0 4000 1800 4000 800] + SymbolLine[0 0 1800 0 800] +) +Symbol['E' 1200] +( + SymbolLine[0 1800 1500 1800 800] + SymbolLine[0 4000 2000 4000 800] + SymbolLine[0 0 0 4000 800] + SymbolLine[0 0 2000 0 800] +) +Symbol['F' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[0 0 2000 0 800] + SymbolLine[0 1800 1500 1800 800] +) +Symbol['G' 1200] +( + SymbolLine[2000 0 2500 500 800] + SymbolLine[500 0 2000 0 800] + SymbolLine[0 500 500 0 800] + SymbolLine[0 500 0 3500 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[2000 4000 2500 3500 800] + SymbolLine[2500 2500 2500 3500 800] + SymbolLine[2000 2000 2500 2500 800] + SymbolLine[1000 2000 2000 2000 800] +) +Symbol['H' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[2500 0 2500 4000 800] + SymbolLine[0 2000 2500 2000 800] +) +Symbol['I' 1200] +( + SymbolLine[0 0 1000 0 800] + SymbolLine[500 0 500 4000 800] + SymbolLine[0 4000 1000 4000 800] +) +Symbol['J' 1200] +( + SymbolLine[700 0 1500 0 800] + SymbolLine[1500 0 1500 3500 800] + SymbolLine[1000 4000 1500 3500 800] + SymbolLine[500 4000 1000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 3500 0 3000 800] +) +Symbol['K' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[0 2000 2000 0 800] + SymbolLine[0 2000 2000 4000 800] +) +Symbol['L' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[0 4000 2000 4000 800] +) +Symbol['M' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[0 0 1500 2000 800] + SymbolLine[1500 2000 3000 0 800] + SymbolLine[3000 0 3000 4000 800] +) +Symbol['N' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[0 0 2500 4000 800] + SymbolLine[2500 0 2500 4000 800] +) +Symbol['O' 1200] +( + SymbolLine[0 500 0 3500 800] + SymbolLine[0 500 500 0 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[1500 0 2000 500 800] + SymbolLine[2000 500 2000 3500 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[0 3500 500 4000 800] +) +Symbol['P' 1200] +( + SymbolLine[500 0 500 4000 800] + SymbolLine[0 0 2000 0 800] + SymbolLine[2000 0 2500 500 800] + SymbolLine[2500 500 2500 1500 800] + SymbolLine[2000 2000 2500 1500 800] + SymbolLine[500 2000 2000 2000 800] +) +Symbol['Q' 1200] +( + SymbolLine[0 500 0 3500 800] + SymbolLine[0 500 500 0 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[1500 0 2000 500 800] + SymbolLine[2000 500 2000 3000 800] + SymbolLine[1000 4000 2000 3000 800] + SymbolLine[500 4000 1000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[1000 2500 2000 4000 800] +) +Symbol['R' 1200] +( + SymbolLine[0 0 2000 0 800] + SymbolLine[2000 0 2500 500 800] + SymbolLine[2500 500 2500 1500 800] + SymbolLine[2000 2000 2500 1500 800] + SymbolLine[500 2000 2000 2000 800] + SymbolLine[500 0 500 4000 800] + SymbolLine[1300 2000 2500 4000 800] +) +Symbol['S' 1200] +( + SymbolLine[2000 0 2500 500 800] + SymbolLine[500 0 2000 0 800] + SymbolLine[0 500 500 0 800] + SymbolLine[0 500 0 1500 800] + SymbolLine[0 1500 500 2000 800] + SymbolLine[500 2000 2000 2000 800] + SymbolLine[2000 2000 2500 2500 800] + SymbolLine[2500 2500 2500 3500 800] + SymbolLine[2000 4000 2500 3500 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[0 3500 500 4000 800] +) +Symbol['T' 1200] +( + SymbolLine[0 0 2000 0 800] + SymbolLine[1000 0 1000 4000 800] +) +Symbol['U' 1200] +( + SymbolLine[0 0 0 3500 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[2000 0 2000 3500 800] +) +Symbol['V' 1200] +( + SymbolLine[0 0 1000 4000 800] + SymbolLine[1000 4000 2000 0 800] +) +Symbol['W' 1200] +( + SymbolLine[0 0 0 2000 800] + SymbolLine[0 2000 500 4000 800] + SymbolLine[500 4000 1500 2000 800] + SymbolLine[1500 2000 2500 4000 800] + SymbolLine[2500 4000 3000 2000 800] + SymbolLine[3000 2000 3000 0 800] +) +Symbol['X' 1200] +( + SymbolLine[0 4000 2500 0 800] + SymbolLine[0 0 2500 4000 800] +) +Symbol['Y' 1200] +( + SymbolLine[0 0 1000 2000 800] + SymbolLine[1000 2000 2000 0 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol['Z' 1200] +( + SymbolLine[0 0 2500 0 800] + SymbolLine[0 4000 2500 0 800] + SymbolLine[0 4000 2500 4000 800] +) +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") +Attribute("PCB::loader" "geda/pcb - mainline (centimils)") +Attribute("PCB::conf::editor/show_solder_side" "0") +Attribute("PCB::conf::editor/buffer_number" "0") +Attribute("PCB::conf::editor/view/flip_x" "0") +Attribute("PCB::conf::editor/view/flip_y" "0") + +Element["" "" "E1" "" 17500 15000 0 -7500 0 100 ""] +( + Pad[0 0 7500 0 1000 4000 5000 "" "1" ""] + Pad[10000 2500 10000 10000 1000 4000 5000 "" "2" "onsolder,edge2"] + ElementLine [0 0 0 10000 1000] + + ) +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/elem_pins.pcb =================================================================== --- tags/2.3.0/tests/RTT/elem_pins.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/elem_pins.pcb (revision 33253) @@ -0,0 +1,71 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["pins with different shapes" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 1905000nm 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") + +Element["" "dip(2)" "U1" "2*300" 1905000nm 3175000nm 0 -2540000nm 0 100 ""] +( + Pin[0 0 2032000nm 1270000nm 2184400nm 999998nm "" "1" "square,edge2"] + Pin[7620000nm 0 2032000nm 1270000nm 2184400nm 999998nm "" "2" "edge2"] + ElementLine [-1270000nm -1270000nm -1270000nm 1270000nm 254000nm] + ElementLine [8890000nm 1270000nm -1270000nm 1270000nm 254000nm] + ElementLine [8890000nm 1270000nm 8890000nm -1270000nm 254000nm] + ElementLine [-1270000nm -1270000nm 2540000nm -1270000nm 254000nm] + ElementLine [5080000nm -1270000nm 8890000nm -1270000nm 254000nm] + ElementArc [3810000nm -1270000nm 1270000nm 1270000nm 0 180 254000nm] + + ) + +Element["" "dip(2)" "U2" "2*300" 1905000nm 8255000nm 0 -2540000nm 0 100 ""] +( + Pin[0 0 2032000nm 1270000nm 2184400nm 999998nm "" "1" "square,edge2,shape(2)"] + Pin[7620000nm 0 2032000nm 1270000nm 2184400nm 999998nm "" "2" "square,edge2,shape(12)"] + ElementLine [-1270000nm -1270000nm -1270000nm 1270000nm 254000nm] + ElementLine [8890000nm 1270000nm -1270000nm 1270000nm 254000nm] + ElementLine [8890000nm 1270000nm 8890000nm -1270000nm 254000nm] + ElementLine [-1270000nm -1270000nm 2540000nm -1270000nm 254000nm] + ElementLine [5080000nm -1270000nm 8890000nm -1270000nm 254000nm] + ElementArc [3810000nm -1270000nm 1270000nm 1270000nm 0 180 254000nm] + + ) +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/elem_sides_smd.pcb =================================================================== --- tags/2.3.0/tests/RTT/elem_sides_smd.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/elem_sides_smd.pcb (revision 33253) @@ -0,0 +1,63 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["smd elements on both sides" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") + +Element["" "Standard SMT resistor, capacitor etc" "R1" "1206" 5715000nm 3175000nm 3009900nm -800100nm 0 100 ""] +( + Pad[-1499870nm -299974nm -1499870nm 299974nm 1299972nm 508000nm 1452372nm "1" "1" "square"] + Pad[1499870nm -299974nm 1499870nm 299974nm 1299972nm 508000nm 1452372nm "2" "2" "square"] + ElementLine [-599948nm -949960nm 599948nm -949960nm 203200nm] + ElementLine [-599948nm 949960nm 599948nm 949960nm 203200nm] + + ) + +Element["onsolder" "Standard SMT resistor, capacitor etc" "R2" "1206" 5715000nm 8890000nm 3009900nm 800100nm 0 100 "auto"] +( + Pad[-1499870nm 299974nm -1499870nm -299974nm 1299972nm 508000nm 1452372nm "1" "1" "onsolder,square"] + Pad[1499870nm 299974nm 1499870nm -299974nm 1299972nm 508000nm 1452372nm "2" "2" "onsolder,square"] + ElementLine [-599948nm 949960nm 599948nm 949960nm 203200nm] + ElementLine [-599948nm -949960nm 599948nm -949960nm 203200nm] + + ) +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/elem_sides_trh.pcb =================================================================== --- tags/2.3.0/tests/RTT/elem_sides_trh.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/elem_sides_trh.pcb (revision 33253) @@ -0,0 +1,71 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["thru-hole elements on both sides" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") + +Element["" "dip(2)" "U1" "2*300" 2540000nm 3810000nm 0 -2540000nm 0 100 ""] +( + Pin[0 0 2032000nm 1270000nm 2184400nm 999998nm "" "1" "square,edge2"] + Pin[7620000nm 0 2032000nm 1270000nm 2184400nm 999998nm "" "2" "edge2"] + ElementLine [-1270000nm -1270000nm -1270000nm 1270000nm 254000nm] + ElementLine [8890000nm 1270000nm -1270000nm 1270000nm 254000nm] + ElementLine [8890000nm 1270000nm 8890000nm -1270000nm 254000nm] + ElementLine [-1270000nm -1270000nm 2540000nm -1270000nm 254000nm] + ElementLine [5080000nm -1270000nm 8890000nm -1270000nm 254000nm] + ElementArc [3810000nm -1270000nm 1270000nm 1270000nm 0 180 254000nm] + + ) + +Element["onsolder" "dip(2)" "U2" "2*300" 2540000nm 8890000nm 0 2540000nm 0 100 "auto"] +( + Pin[0 0 2032000nm 1270000nm 2184400nm 999998nm "" "1" "square,edge2"] + Pin[7620000nm 0 2032000nm 1270000nm 2184400nm 999998nm "" "2" "edge2"] + ElementLine [-1270000nm 1270000nm -1270000nm -1270000nm 254000nm] + ElementLine [8890000nm -1270000nm -1270000nm -1270000nm 254000nm] + ElementLine [8890000nm -1270000nm 8890000nm 1270000nm 254000nm] + ElementLine [-1270000nm 1270000nm 2540000nm 1270000nm 254000nm] + ElementLine [5080000nm 1270000nm 8890000nm 1270000nm 254000nm] + ElementArc [3810000nm 1270000nm 1270000nm 1270000nm -0 -180 254000nm] + + ) +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/flag_colors.lht =================================================================== --- tags/2.3.0/tests/RTT/flag_colors.lht (nonexistent) +++ tags/2.3.0/tests/RTT/flag_colors.lht (revision 33253) @@ -0,0 +1,1424 @@ +ha:pcb-rnd-board-v6 { + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 650.0mil + y = 625.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + ha:layer_stack { + li:groups { + ha:0 { + ha:type { + top = 1 + paste = 1 + } + li:layers { + 9 + } + name = top_paste + } + ha:1 { + ha:type { + silk = 1 + top = 1 + } + li:layers { + 8 + } + name = top_silk + } + ha:2 { + ha:type { + top = 1 + mask = 1 + } + li:layers { + 10 + } + name = top_mask + } + ha:3 { + ha:type { + copper = 1 + top = 1 + } + li:layers { + 0 + 2 + } + name = top_copper + } + ha:4 { + ha:attributes { + thickness = {0.7375mm } + } + ha:type { + substrate = 1 + intern = 1 + } + li:layers { + } + name = grp_4 + } + ha:5 { + ha:type { + copper = 1 + intern = 1 + } + li:layers { + 5 + } + name = Intern + } + ha:6 { + ha:attributes { + thickness = {0.125mm } + } + ha:type { + substrate = 1 + intern = 1 + } + li:layers { + } + name = grp_6 + } + ha:7 { + ha:type { + copper = 1 + intern = 1 + } + li:layers { + 4 + } + name = Intern + } + ha:8 { + ha:attributes { + thickness = {0.7375mm } + } + ha:type { + substrate = 1 + intern = 1 + } + li:layers { + } + name = grp_8 + } + ha:9 { + purpose = uroute + ha:type { + boundary = 1 + } + li:layers { + 6 + } + name = global_outline + } + ha:10 { + ha:type { + bottom = 1 + copper = 1 + } + li:layers { + 1 + 3 + } + name = bottom_copper + } + ha:11 { + ha:type { + bottom = 1 + mask = 1 + } + li:layers { + 11 + } + name = bottom_mask + } + ha:12 { + ha:type { + silk = 1 + bottom = 1 + } + li:layers { + 7 + } + name = bottom_silk + } + ha:13 { + ha:type { + bottom = 1 + paste = 1 + } + li:layers { + 12 + } + name = bottom_paste + } + ha:14 { + purpose = proute + ha:type { + mech = 1 + } + li:layers { + 13 + } + name = pmech + } + ha:15 { + purpose = uroute + ha:type { + mech = 1 + } + li:layers { + 14 + } + name = umech + } + ha:16 { + ha:attributes { + init-invis = 1 + } + purpose = assy + ha:type { + top = 1 + doc = 1 + } + li:layers { + 15 + } + name = top_assy + } + ha:17 { + ha:attributes { + init-invis = 1 + } + purpose = assy + ha:type { + bottom = 1 + doc = 1 + } + li:layers { + 16 + } + name = bot_assy + } + ha:18 { + ha:attributes { + init-invis = 1 + } + purpose = fab + ha:type { + top = 1 + doc = 1 + } + li:layers { + 17 + } + name = fab + } + } + } + + 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 + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + } + ha:editor { + wireframe_draw = true + thin_draw = false + check_planes = false + buffer_number = 0 + } + } + } + ha:data { + li:padstack_prototypes { + ha:ps_proto_v6.0 { + htop = 0 + hdia = 31.5mil + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.0mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.0mm + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.0mm + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + } + hbottom = 0 + hplated = 1 + } + } + li:objects { + ha:padstack_ref.95 { + smirror = 0 + proto = 0 + xmirror = 0 + x = 100.0mil + rot = 0.000000 + y = 100.0mil + li:thermal { + } + ha:flags { + clearline = 1 + found = 1 + } + clearance = 20.0mil + } + ha:padstack_ref.96 { + smirror = 0 + proto = 0 + xmirror = 0 + x = 250.0mil + rot = 0.000000 + y = 100.0mil + li:thermal { + } + ha:flags { + clearline = 1 + selected=1 + } + clearance = 20.0mil + } + ha:padstack_ref.97 { + smirror = 0 + proto = 0 + xmirror = 0 + x = 100.0mil + rot = 0.000000 + y = 225.0mil + li:thermal { + } + ha:flags { + clearline = 1 + } + clearance = 20.0mil + } + ha:padstack_ref.173 { + proto=0; x=250.0mil; y=225.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:subc.274 { + ha:attributes { + footprint=0402 Standard SMT resistor, capacitor etc + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.326136mm + -0.425958mm + -0.326136mm + -0.425958mm + -0.326136mm + 0.425958mm + 0.326136mm + 0.425958mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.288 { + proto=0; x=5.315204mm; y=575.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + found=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.289 { + proto=0; x=240.74mil; y=575.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:text.275 { + string=%a.parent.refdes%; x=193.5mil; y=543.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.276 { + x1=225.0mil; y1=575.0mil; x2=225.0mil; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.279 { + x1=225.0mil; y1=575.0mil; x2=225.0mil; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.282 { + x1=225.0mil; y1=575.0mil; x2=6.715mm; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.285 { + x1=225.0mil; y1=575.0mil; x2=225.0mil; y2=15.605mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = xK4LY0258SGWTnYfnvwAAAAB + } + ha:subc.291 { + ha:attributes { + footprint=0402 Standard SMT resistor, capacitor etc + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.326136mm + -0.425958mm + -0.326136mm + -0.425958mm + -0.326136mm + 0.425958mm + 0.326136mm + 0.425958mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.305 { + proto=0; x=7.855204mm; y=575.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + selected=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.306 { + proto=0; x=340.74mil; y=575.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:text.292 { + string=%a.parent.refdes%; x=293.5mil; y=543.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.293 { + x1=325.0mil; y1=575.0mil; x2=325.0mil; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.296 { + x1=325.0mil; y1=575.0mil; x2=325.0mil; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.299 { + x1=325.0mil; y1=575.0mil; x2=9.255mm; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.302 { + x1=325.0mil; y1=575.0mil; x2=325.0mil; y2=15.605mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = xK4LY0258SGWTnYfnvwAAAAB + } + ha:subc.308 { + ha:attributes { + footprint=0402 Standard SMT resistor, capacitor etc + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.326136mm + -0.425958mm + -0.326136mm + -0.425958mm + -0.326136mm + 0.425958mm + 0.326136mm + 0.425958mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.322 { + proto=0; x=10.395204mm; y=575.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + warn=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.323 { + proto=0; x=440.74mil; y=575.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:text.309 { + string=%a.parent.refdes%; x=393.5mil; y=543.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.310 { + x1=425.0mil; y1=575.0mil; x2=425.0mil; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.313 { + x1=425.0mil; y1=575.0mil; x2=425.0mil; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.316 { + x1=425.0mil; y1=575.0mil; x2=11.795mm; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.319 { + x1=425.0mil; y1=575.0mil; x2=425.0mil; y2=15.605mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = xK4LY0258SGWTnYfnvwAAAAB + } + ha:subc.325 { + ha:attributes { + footprint=0402 Standard SMT resistor, capacitor etc + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.326136mm + -0.425958mm + -0.326136mm + -0.425958mm + -0.326136mm + 0.425958mm + 0.326136mm + 0.425958mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.339 { + proto=0; x=12.935204mm; y=575.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.340 { + proto=0; x=540.74mil; y=575.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:text.326 { + string=%a.parent.refdes%; x=493.5mil; y=543.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.327 { + x1=525.0mil; y1=575.0mil; x2=525.0mil; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.330 { + x1=525.0mil; y1=575.0mil; x2=525.0mil; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.333 { + x1=525.0mil; y1=575.0mil; x2=14.335mm; y2=575.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.336 { + x1=525.0mil; y1=575.0mil; x2=525.0mil; y2=15.605mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = xK4LY0258SGWTnYfnvwAAAAB + } + } + li:layers { + ha:top-sig { + lid = 0 + li:objects { + ha:line.98 { + clearance = 40.0mil + y2 = 225.0mil + thickness = 10.0mil + x1 = 175.0mil + x2 = 250.0mil + ha:flags { + clearline = 1 + } + y1 = 225.0mil + } + ha:line.101 { + clearance = 40.0mil + y2 = 200.0mil + thickness = 10.0mil + x1 = 250.0mil + x2 = 275.0mil + ha:flags { + clearline = 1 + } + y1 = 225.0mil + } + ha:line.104 { + clearance = 40.0mil + y2 = 175.0mil + thickness = 10.0mil + x1 = 275.0mil + x2 = 275.0mil + ha:flags { + clearline = 1 + } + y1 = 200.0mil + } + ha:line.122 { + clearance = 40.0mil + y2 = 25.0mil + thickness = 10.0mil + x1 = 350.0mil + x2 = 550.0mil + ha:flags { + clearline = 1 + found=1 + } + y1 = 25.0mil + } + ha:line.125 { + clearance = 40.0mil + y2 = 75.0mil + thickness = 10.0mil + x1 = 350.0mil + x2 = 550.0mil + ha:flags { + clearline = 1 + selected=1 + } + y1 = 75.0mil + } + ha:line.128 { + clearance = 40.0mil + y2 = 125.0mil + thickness = 10.0mil + x1 = 350.0mil + x2 = 550.0mil + ha:flags { + clearline = 1 + } + y1 = 125.0mil + } + ha:line.220 { + x1=350.0mil; y1=175.0mil; x2=550.0mil; y2=175.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.131 { + astart = 0 + thickness = 10.0mil + width = 75.0mil + height = 75.0mil + x = 425.0mil + y = 275.0mil + adelta = -90 + ha:flags { + clearline = 1 + found=1 + } + clearance = 40.0mil + } + ha:arc.149 { + x=475.0mil; y=275.0mil; width=75.0mil; height=75.0mil; astart=0; adelta=-90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + selected=1 + } + } + ha:arc.150 { + x=525.0mil; y=275.0mil; width=75.0mil; height=75.0mil; astart=0; adelta=-90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.151 { + x=575.0mil; y=275.0mil; width=75.0mil; height=75.0mil; astart=0; adelta=-90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.111 { + li:geometry { + ta:contour { + { 25.0mil; 25.0mil } + { 325.0mil; 25.0mil } + { 325.0mil; 275.0mil } + { 25.0mil; 275.0mil } + } + } + ha:flags { + clearpoly = 1 + } + clearance = 40.0mil + } + ha:polygon.174 { clearance=40.0mil; + li:geometry { + ta:contour { + { 250.0mil; 325.0mil } + { 300.0mil; 325.0mil } + { 300.0mil; 525.0mil } + { 250.0mil; 525.0mil } + } + } + + ha:flags { + clearpoly=1 + found=1 + } + } + ha:polygon.184 { clearance=40.0mil; + li:geometry { + ta:contour { + { 325.0mil; 325.0mil } + { 375.0mil; 325.0mil } + { 375.0mil; 525.0mil } + { 325.0mil; 525.0mil } + } + } + + ha:flags { + clearpoly=1 + selected=1 + } + } + ha:polygon.189 { clearance=40.0mil; + li:geometry { + ta:contour { + { 400.0mil; 325.0mil } + { 450.0mil; 325.0mil } + { 450.0mil; 525.0mil } + { 400.0mil; 525.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.194 { clearance=40.0mil; + li:geometry { + ta:contour { + { 475.0mil; 325.0mil } + { 525.0mil; 325.0mil } + { 525.0mil; 525.0mil } + { 475.0mil; 525.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:text.168 { + string=TEST; x=50.0mil; y=300.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + found=1 + } + rot = 0.000000 + } + ha:text.170 { + string=TEST; x=50.0mil; y=375.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + selected=1 + } + rot = 0.000000 + } + ha:text.171 { + string=TEST; x=50.0mil; y=450.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.172 { + string=TEST; x=50.0mil; y=525.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#8b2323} + group = 3 + ha:combining { + } + } + ha:bottom-sig { + lid = 1 + li:objects { + } + color = {#3a5fcd} + group = 10 + ha:combining { + } + } + ha:top-gnd { + lid = 2 + li:objects { + } + color = {#104e8b} + group = 3 + ha:combining { + } + } + ha:bottom-gnd { + lid = 3 + li:objects { + } + color = {#cd3700} + group = 10 + ha:combining { + } + } + ha:int-sig2 { + lid = 4 + li:objects { + } + color = {#548b54} + group = 7 + ha:combining { + } + } + ha:int-sig1 { + lid = 5 + li:objects { + } + color = {#8b7355} + group = 5 + ha:combining { + } + } + ha:outline { + lid = 6 + li:objects { + } + color = {#00868b} + group = 9 + ha:combining { + } + } + ha:bottom-silk { + lid = 7 + li:objects { + } + color = {#000000} + group = 12 + ha:combining { + auto = 1 + } + } + ha:top-silk { + lid = 8 + li:objects { + } + color = {#000000} + group = 1 + ha:combining { + auto = 1 + } + } + ha:top-paste { + lid = 9 + li:objects { + } + color = {#cd00cd} + group = 0 + ha:combining { + auto = 1 + } + } + ha:top-mask { + lid = 10 + li:objects { + } + color = {#ff0000} + group = 2 + ha:combining { + sub = 1 + auto = 1 + } + } + ha:bottom-mask { + lid = 11 + li:objects { + } + color = {#ff0000} + group = 11 + ha:combining { + sub = 1 + auto = 1 + } + } + ha:bottom-paste { + lid = 12 + li:objects { + } + color = {#cd00cd} + group = 13 + ha:combining { + auto = 1 + } + } + ha:slot-plated { + lid = 13 + li:objects { + } + color = {#8b7355} + group = 14 + ha:combining { + auto = 1 + } + } + ha:slot-unplated { + lid = 14 + li:objects { + } + color = {#00868b} + group = 15 + ha:combining { + auto = 1 + } + } + ha:top-assy { + lid = 15 + li:objects { + } + color = {#444444} + group = 16 + ha:combining { + } + } + ha:bot-assy { + lid = 16 + li:objects { + } + color = {#444444} + group = 17 + ha:combining { + } + } + ha:fab { + lid = 17 + li:objects { + } + color = {#222222} + group = 18 + ha:combining { + auto = 1 + } + } + } + } +} Index: tags/2.3.0/tests/RTT/layer_copper.pcb =================================================================== --- tags/2.3.0/tests/RTT/layer_copper.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/layer_copper.pcb (revision 33253) @@ -0,0 +1,48 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["one line per each type of copper layer" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") +Layer(1 "comp1") +( + Line[1270000nm 1905000nm 1270000nm 8890000nm 254000nm 1016000nm "clearline"] +) +Layer(2 "solder1") +( + Line[1905000nm 1905000nm 10160000nm 1905000nm 254000nm 1016000nm "clearline"] +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( + Line[2540000nm 3810000nm 8255000nm 9525000nm 254000nm 1016000nm "clearline"] +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/layer_outline.pcb =================================================================== --- tags/2.3.0/tests/RTT/layer_outline.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/layer_outline.pcb (revision 33253) @@ -0,0 +1,48 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["outline layer triangle" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( + Line[1905000nm 2540000nm 1905000nm 10160000nm 254000nm 1016000nm "clearline"] + Line[1905000nm 10160000nm 9525000nm 10160000nm 254000nm 1016000nm "clearline"] + Line[9525000nm 10160000nm 1905000nm 2540000nm 254000nm 1016000nm "clearline"] +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/layer_silk.pcb =================================================================== --- tags/2.3.0/tests/RTT/layer_silk.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/layer_silk.pcb (revision 33253) @@ -0,0 +1,47 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["one line on each silk layer" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( + Line[1905000nm 10795000nm 7620000nm 5080000nm 254000nm 1016000nm "clearline"] +) +Layer(9 "silk") +( + Line[1270000nm 1270000nm 1270000nm 10795000nm 254000nm 1016000nm "clearline"] +) Index: tags/2.3.0/tests/RTT/layer_spc.pcb =================================================================== --- tags/2.3.0/tests/RTT/layer_spc.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/layer_spc.pcb (revision 33253) @@ -0,0 +1,43 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["space (and other dangerous characters) in layer name" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Layer(1 "component 1") +( +) +Layer(2 "solder 1") +( +) +Layer(3 " ") +( +) +Layer(4 "solder{2}") +( +) +Layer(5 "inner(1)") +( +) +Layer(6 "inner/2") +( +) +Layer(7 "out:line") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/lib/README =================================================================== --- tags/2.3.0/tests/RTT/lib/README (nonexistent) +++ tags/2.3.0/tests/RTT/lib/README (revision 33253) @@ -0,0 +1,3 @@ +dummy library dir with no footprints - configuring this the only lib dir +cuts back test time to about 66% because pcb-rnd doesn't need to map +the library for each test. Index: tags/2.3.0/tests/RTT/line_f_clear.pcb =================================================================== --- tags/2.3.0/tests/RTT/line_f_clear.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/line_f_clear.pcb (revision 33253) @@ -0,0 +1,51 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Clear and no-clear lines" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Layer(1 "comp1") +( + Line[3175000nm 6350000nm 10160000nm 6350000nm 381000nm 609602nm "clearline"] + Line[6350000nm 3175000nm 6350000nm 9525000nm 254000nm 2133600nm "clearline"] + Line[6350000nm 6350000nm 10160000nm 5080000nm 508000nm 1016000nm ""] + Line[6350000nm 6350000nm 3810000nm 3810000nm 127000nm 1016000nm ""] + Polygon("clearpoly") + ( + [635000nm 635000nm] [12065000nm 635000nm] [12065000nm 12065000nm] [635000nm 12065000nm] + ) +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/line_normal.pcb =================================================================== --- tags/2.3.0/tests/RTT/line_normal.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/line_normal.pcb (revision 33253) @@ -0,0 +1,47 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Normal lines at different size and angle" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[1270000nm 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Layer(1 "comp1") +( + Line[3175000nm 6350000nm 10160000nm 6350000nm 381000nm 1016000nm ""] + Line[6350000nm 3175000nm 6350000nm 9525000nm 254000nm 1016000nm ""] + Line[6350000nm 6350000nm 10160000nm 5080000nm 508000nm 1016000nm ""] + Line[6350000nm 6350000nm 3810000nm 3810000nm 127000nm 1016000nm ""] +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/line_offpage.pcb =================================================================== --- tags/2.3.0/tests/RTT/line_offpage.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/line_offpage.pcb (revision 33253) @@ -0,0 +1,44 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["A single line that extends beyond board boundary" 500.0mil 500.0mil] + +Grid[25.0mil 0.0 0.0 1] +Cursor[0.0 50.0mil 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[12.0mil 9.0mil 10.0mil 7.0mil 15.0mil 10.0mil] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,10.0mil,78.7399606mil,31.5mil,20.0mil:style2,20.0mil,86.61mil,39.3699606mil,20.0mil:style3,80.0mil,137.7999606mil,47.2399606mil,25.0mil:style4,100.0mil,64.0mil,31.5mil,100.0mil"] + +Layer(1 "comp1") +( + Line[100mil 200mil 600mil 200mil 254000nm 1016000nm ""] +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/line_overlap1.pcb =================================================================== --- tags/2.3.0/tests/RTT/line_overlap1.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/line_overlap1.pcb (revision 33253) @@ -0,0 +1,45 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Two lines partially overlapping" 500.0mil 500.0mil] + +Grid[25.0mil 0.0 0.0 1] +Cursor[50.0mil 0.0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[12.0mil 9.0mil 10.0mil 7.0mil 15.0mil 10.0mil] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,10.0mil,78.7399606mil,31.5mil,20.0mil:style2,20.0mil,86.61mil,39.3699606mil,20.0mil:style3,80.0mil,137.7999606mil,47.2399606mil,25.0mil:style4,100.0mil,64.0mil,31.5mil,100.0mil"] + +Layer(1 "comp1") +( + Line[200mil 200mil 250mil 200mil 381000nm 1016000nm ""] + Line[220mil 200mil 300mil 200mil 381000nm 1016000nm ""] +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/line_overlap2.pcb =================================================================== --- tags/2.3.0/tests/RTT/line_overlap2.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/line_overlap2.pcb (revision 33253) @@ -0,0 +1,45 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Two lines, one over the other, full cover" 500.0mil 500.0mil] + +Grid[25.0mil 0.0 0.0 1] +Cursor[50.0mil 0.0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[12.0mil 9.0mil 10.0mil 7.0mil 15.0mil 10.0mil] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,10.0mil,78.7399606mil,31.5mil,20.0mil:style2,20.0mil,86.61mil,39.3699606mil,20.0mil:style3,80.0mil,137.7999606mil,47.2399606mil,25.0mil:style4,100.0mil,64.0mil,31.5mil,100.0mil"] + +Layer(1 "comp1") +( + Line[200mil 200mil 350mil 200mil 381000nm 1016000nm ""] + Line[220mil 200mil 300mil 200mil 381000nm 1016000nm ""] +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/line_overlap3.pcb =================================================================== --- tags/2.3.0/tests/RTT/line_overlap3.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/line_overlap3.pcb (revision 33253) @@ -0,0 +1,45 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Full overlap: the same line twice" 500.0mil 500.0mil] + +Grid[25.0mil 0.0 0.0 1] +Cursor[50.0mil 0.0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[12.0mil 9.0mil 10.0mil 7.0mil 15.0mil 10.0mil] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,10.0mil,78.7399606mil,31.5mil,20.0mil:style2,20.0mil,86.61mil,39.3699606mil,20.0mil:style3,80.0mil,137.7999606mil,47.2399606mil,25.0mil:style4,100.0mil,64.0mil,31.5mil,100.0mil"] + +Layer(1 "comp1") +( + Line[200mil 200mil 350mil 200mil 381000nm 1016000nm ""] + Line[200mil 200mil 350mil 200mil 381000nm 1016000nm ""] +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/line_overlap4.pcb =================================================================== --- tags/2.3.0/tests/RTT/line_overlap4.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/line_overlap4.pcb (revision 33253) @@ -0,0 +1,49 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Full overlap: the same line twice with different settings" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[635000nm 635000nm 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999994nm,800100nm,508000nm:style2,508000nm,2199894nm,999996nm,508000nm:style3,2032000nm,3500118nm,1199894nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Layer(1 "comp1") +( + Line[5080000nm 5080000nm 8890000nm 5080000nm 127000nm 1016000nm "clearline"] + Line[5080000nm 5080000nm 8890000nm 5080000nm 381000nm 1016000nm ""] + Polygon("clearpoly") + ( + [3810000nm 3810000nm] [7620000nm 3810000nm] [7620000nm 8255000nm] [3810000nm 8255000nm] + ) +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/line_zerolen.pcb =================================================================== --- tags/2.3.0/tests/RTT/line_zerolen.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/line_zerolen.pcb (revision 33253) @@ -0,0 +1,44 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["A single zero length line" 500.0mil 500.0mil] + +Grid[25.0mil 0.0 0.0 1] +Cursor[50.0mil 0.0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[12.0mil 9.0mil 10.0mil 7.0mil 15.0mil 10.0mil] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,10.0mil,78.7399606mil,31.5mil,20.0mil:style2,20.0mil,86.61mil,39.3699606mil,20.0mil:style3,80.0mil,137.7999606mil,47.2399606mil,25.0mil:style4,100.0mil,64.0mil,31.5mil,100.0mil"] + +Layer(1 "comp1") +( + Line[200mil 200mil 200mil 200mil 381000nm 1016000nm ""] +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/mech.lht =================================================================== --- tags/2.3.0/tests/RTT/mech.lht (nonexistent) +++ tags/2.3.0/tests/RTT/mech.lht (revision 33253) @@ -0,0 +1,817 @@ +ha:pcb-rnd-board-v6 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:style1 { + diameter = 1.999995mm + text_scale = 0 + text_thick = 0.0 + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:style2 { + diameter = 2.199894mm + text_scale = 0 + text_thick = 0.0 + thickness = 20.0mil + hole = 0.999997mm + clearance = 20.0mil + } + ha:style3 { + diameter = 3.500119mm + text_scale = 0 + text_thick = 0.0 + thickness = 80.0mil + hole = 1.199895mm + clearance = 25.0mil + } + ha:style4 { + diameter = 64.0mil + text_scale = 0 + text_thick = 0.0 + thickness = 100.0mil + hole = 31.5mil + clearance = 100.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 500.0mil + y = 500.0mil + } + ha:grid { + spacing = 10.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=-5.0mil; y1=0.0; x2=5.0mil; y2=0.0; thickness=10.0mil; square=0; } + ha:combining { auto=1; } + ha:layer_mask { + mech = 1 + } + clearance=40.0mil + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + li:ps_poly { + -15.0mil + -10.0mil + 25.0mil + -10.0mil + 25.0mil + 10.0mil + -15.0mil + 10.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=40.0mil + li:ps_poly { + -15.0mil + -20.0mil + 15.0mil + -20.0mil + 15.0mil + 20.0mil + -15.0mil + 20.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=40.0mil + li:ps_poly { + -25.0mil + -10.0mil + 15.0mil + -10.0mil + 15.0mil + 10.0mil + -25.0mil + 10.0mil + } + } + } + } + + ha:ps_proto_v6.1 { + hdia=0.0; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=-5.0mil; y1=0.0; x2=5.0mil; y2=0.0; thickness=10.0mil; square=0; } + ha:combining { auto=1; } + ha:layer_mask { + mech = 1 + } + clearance=40.0mil + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + li:ps_poly { + -15.0mil + -10.0mil + 25.0mil + -10.0mil + 25.0mil + 10.0mil + -15.0mil + 10.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=40.0mil + li:ps_poly { + -15.0mil + -20.0mil + 15.0mil + -20.0mil + 15.0mil + 20.0mil + -15.0mil + 20.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=40.0mil + li:ps_poly { + -25.0mil + -10.0mil + 15.0mil + -10.0mil + 15.0mil + 10.0mil + -25.0mil + 10.0mil + } + } + } + } + + + ha:ps_proto_v6.2 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=20.0mil + li:ps_poly { + -15.0mil + -10.0mil + 25.0mil + -10.0mil + 25.0mil + 10.0mil + -15.0mil + 10.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=20.0mil + li:ps_poly { + -15.0mil + -20.0mil + 15.0mil + -20.0mil + 15.0mil + 20.0mil + -15.0mil + 20.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=20.0mil + li:ps_poly { + -25.0mil + -10.0mil + 15.0mil + -10.0mil + 15.0mil + 10.0mil + -25.0mil + 10.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + mech = 1 + } + clearance=40.0mil + li:ps_poly { + 0.0 + -5.0mil + -10.0mil + 5.0mil + 10.0mil + 5.0mil + } + } + } + } + + ha:ps_proto_v6.3 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=10.0mil; } + ha:combining { auto=1; } + ha:layer_mask { + mech = 1 + } + clearance=40.0mil + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=20.0mil + li:ps_poly { + -15.0mil + -10.0mil + 25.0mil + -10.0mil + 25.0mil + 10.0mil + -15.0mil + 10.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=20.0mil + li:ps_poly { + -15.0mil + -20.0mil + 15.0mil + -20.0mil + 15.0mil + 20.0mil + -15.0mil + 20.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=20.0mil + li:ps_poly { + -25.0mil + -10.0mil + 15.0mil + -10.0mil + 15.0mil + 10.0mil + -25.0mil + 10.0mil + } + } + } + } + unused = 1 + unused = 1 + ha:ps_proto_v6.6 { + hdia=10.0mil; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=-10.0mil; y1=0.0; x2=10.0mil; y2=0.0; thickness=20.0mil; square=0; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + } + + ha:ps_shape_v4 { + ha:ps_line { x1=0.0; y1=10.0mil; x2=0.0; y2=-10.0mil; thickness=20.0mil; square=0; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=40.0mil + } + + ha:ps_shape_v4 { + ha:ps_line { x1=-10.0mil; y1=-10.0mil; x2=10.0mil; y2=10.0mil; thickness=20.0mil; square=0; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=40.0mil + } + } + } + + ha:ps_proto_v6.7 { + hdia=10.0mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=-10.0mil; y1=0.0; x2=10.0mil; y2=0.0; thickness=20.0mil; square=0; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=20.0mil + } + + ha:ps_shape_v4 { + ha:ps_line { x1=0.0; y1=10.0mil; x2=0.0; y2=-10.0mil; thickness=20.0mil; square=0; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=20.0mil + } + + ha:ps_shape_v4 { + ha:ps_line { x1=-10.0mil; y1=-10.0mil; x2=10.0mil; y2=10.0mil; thickness=20.0mil; square=0; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=20.0mil + } + } + } + } + + li:objects { + ha:padstack_ref.117 { + proto=0; x=140.0mil; y=50.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.140 { + proto=1; x=220.0mil; y=50.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.332 { + proto=6; x=140.0mil; y=110.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.361 { + proto=7; x=220.0mil; y=110.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.542 { + proto=2; x=150.0mil; y=330.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.543 { + proto=3; x=230.0mil; y=330.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + li:layers { + + ha:comp1 { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:polygon.372 { clearance=40.0mil; + li:geometry { + ta:contour { + { 120.0mil; 160.0mil } + { 170.0mil; 160.0mil } + { 170.0mil; 200.0mil } + { 120.0mil; 200.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.402 { clearance=40.0mil; + li:geometry { + ta:contour { + { 200.0mil; 160.0mil } + { 250.0mil; 160.0mil } + { 250.0mil; 200.0mil } + { 200.0mil; 200.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#8b2323} + } + + ha:solder1 { + lid=1 + group=10 + ha:combining { } + + li:objects { + ha:polygon.382 { clearance=40.0mil; + li:geometry { + ta:contour { + { 120.0mil; 160.0mil } + { 170.0mil; 160.0mil } + { 170.0mil; 200.0mil } + { 120.0mil; 200.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.407 { clearance=40.0mil; + li:geometry { + ta:contour { + { 200.0mil; 160.0mil } + { 250.0mil; 160.0mil } + { 250.0mil; 200.0mil } + { 200.0mil; 200.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#3a5fcd} + } + + ha:com2 { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + color = {#104e8b} + } + + ha:solder2 { + lid=3 + group=10 + ha:combining { } + + li:objects { + } + color = {#cd3700} + } + + ha:inner1 { + lid=4 + group=5 + ha:combining { } + + li:objects { + ha:polygon.377 { clearance=40.0mil; + li:geometry { + ta:contour { + { 120.0mil; 160.0mil } + { 170.0mil; 160.0mil } + { 170.0mil; 200.0mil } + { 120.0mil; 200.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.412 { clearance=40.0mil; + li:geometry { + ta:contour { + { 200.0mil; 160.0mil } + { 250.0mil; 160.0mil } + { 250.0mil; 200.0mil } + { 200.0mil; 200.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#548b54} + } + + ha:silk { + lid=5 + group=12 + ha:combining { auto=1; } + + li:objects { + } + color = {#000000} + } + + ha:silk { + lid=6 + group=1 + ha:combining { auto=1; } + + li:objects { + } + color = {#000000} + } + + ha:top-paste { + lid=7 + group=0 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + ha:top-mask { + lid=8 + group=2 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-mask { + lid=9 + group=11 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-paste { + lid=10 + group=13 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + ha:uroute { + lid=11 + group=8 + ha:combining { auto=1; } + + li:objects { + ha:line.417 { + x1=130.0mil; y1=180.0mil; x2=160.0mil; y2=180.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#ff8b54} + } + + ha:proute { + lid=12 + group=9 + ha:combining { auto=1; } + + li:objects { + ha:line.420 { + x1=210.0mil; y1=180.0mil; x2=240.0mil; y2=180.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#008b54} + } + } + } + + + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { 7; } + } + ha:1 { + name = top_silk + ha:type { silk=1; top=1; } + li:layers { 6; } + } + ha:2 { + name = top_mask + ha:type { top=1; mask=1; } + li:layers { 8; } + } + 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 { 4; } + } + ha:6 { + name = grp_6 + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:7 { + name = grp_8 + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:8 { + name = global-mech + ha:type { mech=1; } + li:layers { 11; } + purpose = uroute + } + ha:9 { + name = global-mech + ha:type { mech=1; } + li:layers { 12; } + purpose = proute + } + 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 { 9; } + } + ha:12 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 5; } + } + ha:13 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 10; } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.0mil + min_drill = 15.0mil + text_scale = 100 + via_thickness = 78.74 mil + via_drilling_hole = 31.50 mil + min_slk = 7.0mil + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 9.0mil + poly_isle_area = 199999999.999200 + min_wid = 10.0mil + bloat = 12.0mil + clearance = 20.00 mil + } + ha:editor { + grid_unit = mil + grids_idx = 3 + grid = 10.00 mil + buffer_number = 0 + } + } + } + +} Index: tags/2.3.0/tests/RTT/netlist.pcb =================================================================== --- tags/2.3.0/tests/RTT/netlist.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/netlist.pcb (revision 33253) @@ -0,0 +1,74 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["board with minimal netlist" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 3810000nm 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") + +Element["" "dip(4)" "U1" "4*300" 2540000nm 4445000nm 0 -2540000nm 0 100 ""] +( + Pin[0 0 2032000nm 1270000nm 2184400nm 999998nm "" "1" "square,edge2"] + Pin[7620000nm 0 2032000nm 1270000nm 2184400nm 999998nm "" "4" "edge2"] + Pin[0 2540000nm 2032000nm 1270000nm 2184400nm 999998nm "" "2" "edge2"] + Pin[7620000nm 2540000nm 2032000nm 1270000nm 2184400nm 999998nm "" "3" "edge2"] + ElementLine [-1270000nm -1270000nm -1270000nm 3810000nm 254000nm] + ElementLine [8890000nm 3810000nm -1270000nm 3810000nm 254000nm] + ElementLine [8890000nm 3810000nm 8890000nm -1270000nm 254000nm] + ElementLine [-1270000nm -1270000nm 2540000nm -1270000nm 254000nm] + ElementLine [5080000nm -1270000nm 8890000nm -1270000nm 254000nm] + ElementArc [3810000nm -1270000nm 1270000nm 1270000nm 0 180 254000nm] + + ) +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) + +NetList() +( + Net("foo" "(unknown)") + ( + Connect("U1-1") + Connect("U1-3") + ) + Net("bar" "(unknown)") + ( + Connect("U1-2") + Connect("U1-4") + ) +) Index: tags/2.3.0/tests/RTT/netlist_ba.pcb =================================================================== --- tags/2.3.0/tests/RTT/netlist_ba.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/netlist_ba.pcb (revision 33253) @@ -0,0 +1,81 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["board with minimal netlist and some back-annotation changes" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 3810000nm 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") + +Element["" "dip(4)" "U1" "4*300" 2540000nm 4445000nm 0 -2540000nm 0 100 ""] +( + Pin[0 0 2032000nm 1270000nm 2184400nm 999998nm "" "1" "square,edge2"] + Pin[7620000nm 0 2032000nm 1270000nm 2184400nm 999998nm "" "4" "edge2"] + Pin[0 2540000nm 2032000nm 1270000nm 2184400nm 999998nm "" "2" "edge2"] + Pin[7620000nm 2540000nm 2032000nm 1270000nm 2184400nm 999998nm "" "3" "edge2"] + ElementLine [-1270000nm -1270000nm -1270000nm 3810000nm 254000nm] + ElementLine [8890000nm 3810000nm -1270000nm 3810000nm 254000nm] + ElementLine [8890000nm 3810000nm 8890000nm -1270000nm 254000nm] + ElementLine [-1270000nm -1270000nm 2540000nm -1270000nm 254000nm] + ElementLine [5080000nm -1270000nm 8890000nm -1270000nm 254000nm] + ElementArc [3810000nm -1270000nm 1270000nm 1270000nm 0 180 254000nm] + + ) +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) + +NetList() +( + Net("foo" "(unknown)") + ( + Connect("U1-1") + Connect("U1-3") + ) + Net("bar" "(unknown)") + ( + Connect("U1-2") + Connect("U1-4") + ) +) + +NetListPatch() +( + del_conn("U1-1" "foo") + add_conn("U1-1" "bar") + change_attrib("bar" "impedance" "50 ohm") +) Index: tags/2.3.0/tests/RTT/padrot.pcb =================================================================== --- tags/2.3.0/tests/RTT/padrot.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/padrot.pcb (revision 33253) @@ -0,0 +1,127 @@ +# release: pcb-rnd 1.2.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Rotated round cap and square pads" 50000 50000] + +Grid[500 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:5:6:7:2,4,s") +Styles["style1,1000,7874,3150,2000:style2,2000,8661,3937,2000:style3,8000,13780,4724,2500:style4,10000,6400,3150,10000"] + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::loader" "geda/pcb - mainline (centimils)") +Attribute("PCB::conf::editor/draw_grid" "true") +Attribute("PCB::conf::editor/grid" "5.00 mil") + +Element["" "" "R1" "" 5000 5000 -3500 -3500 0 55 ""] +( + Pad[0 0 7500 0 1000 4000 5000 "" "1" ""] + ElementLine [-2500 2500 10000 2500 500] + ElementLine [10000 2500 10000 -2500 500] + ElementLine [10000 -2500 -2500 -2500 500] + ElementLine [-2500 2500 -2500 -2500 500] + + ) + +Element["" "" "R3" "" 5000 20000 3000 3250 1 65 ""] +( + Pad[0 -7500 0 0 1000 4000 5000 "" "1" ""] + ElementLine [2500 -10000 2500 2500 500] + ElementLine [-2500 -10000 2500 -10000 500] + ElementLine [-2500 -10000 -2500 2500 500] + ElementLine [-2500 2500 2500 2500 500] + + ) + +Element["" "" "R2" "" 20000 5000 11250 -2500 0 100 ""] +( + Pad[0 0 7500 0 1000 4000 5000 "" "1" "square"] + ElementLine [-2500 2500 10000 2500 500] + ElementLine [10000 -2500 10000 2500 500] + ElementLine [-2500 -2500 10000 -2500 500] + ElementLine [-2500 -2500 -2500 2500 500] + + ) + +Element["" "" "R6" "" 5000 27500 2000 11500 3 100 ""] +( + Pad[0 0 0 7500 1000 4000 5000 "" "1" "square"] + ElementLine [-2500 -2500 -2500 10000 500] + ElementLine [-2500 10000 2500 10000 500] + ElementLine [2500 -2500 2500 10000 500] + ElementLine [-2500 -2500 2500 -2500 500] + + ) + +Element["" "" "R4" "" 12500 15000 1500 -500 1 60 ""] +( + Pad[0 0 5303 5303 1000 4000 5000 "" "1" ""] + ElementLine [-3536 0 5303 8839 500] + ElementLine [5303 8839 8839 5303 500] + ElementLine [0 -3536 8839 5303 500] + ElementLine [-3536 0 0 -3536 500] + + ) + +Element["" "" "R5" "" 22500 15000 13000 -1500 3 100 ""] +( + Pad[0 0 5303 5303 1000 4000 5000 "" "1" "square"] + ElementLine [-3536 0 5303 8839 500] + ElementLine [5303 8839 8839 5303 500] + ElementLine [0 -3536 8839 5303 500] + ElementLine [-3536 0 0 -3536 500] + + ) + +Element["" "" "R7" "" 12500 30000 7000 6500 3 100 ""] +( + Pad[0 0 6943 2836 1000 4000 5000 "" "1" ""] + ElementLine [-3260 1369 8312 6096 500] + ElementLine [8312 6096 10203 1467 500] + ElementLine [-1369 -3260 10203 1467 500] + ElementLine [-3260 1369 -1369 -3260 500] + + ) + +Element["" "" "R8" "" 27500 30000 6000 7500 3 100 ""] +( + Pad[0 0 6943 2836 1000 4000 5000 "" "1" "square"] + ElementLine [-3260 1369 8312 6096 500] + ElementLine [8312 6096 10203 1467 500] + ElementLine [-1369 -3260 10203 1467 500] + ElementLine [-3260 1369 -1369 -3260 500] + + ) +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/padstack.lht =================================================================== --- tags/2.3.0/tests/RTT/padstack.lht (nonexistent) +++ tags/2.3.0/tests/RTT/padstack.lht (revision 33253) @@ -0,0 +1,552 @@ +ha:pcb-rnd-board-v4 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:style1 { + diameter = 1.999995mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:style2 { + diameter = 2.199894mm + thickness = 20.0mil + hole = 0.999997mm + clearance = 20.0mil + } + ha:style3 { + diameter = 3.500119mm + thickness = 80.0mil + hole = 1.199895mm + clearance = 25.0mil + } + ha:style4 { + diameter = 64.0mil + thickness = 100.0mil + hole = 31.5mil + clearance = 100.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 500.0mil + y = 500.0mil + isle_area_nm2 = 199999999.999200 + } + ha:cursor { + zoom = 0.000000 + x = 0.0 + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + ha:ps_proto_v4.0 { + htop = 0 + li:shape { + ha:ps_shape_v4 { + clearance = 40.0mil + ha:ps_line { + y2 = 0.0 + thickness = 10.0mil + x1 = 75.0mil + x2 = -1270.0um + square = 0 + y1 = 0.0 + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 40.0mil + ha:ps_line { + y2 = -1905.0um + thickness = 20.0mil + x1 = 0.0 + x2 = 0.0 + square = 0 + y1 = 50.0mil + } + ha:layer_mask { + top = 1 + paste = 1 + } + ha:combining { + auto=1; } + } + ha:ps_shape_v4 { + clearance = 40.0mil + li:ps_poly { + -1270.0um + -1270.0um + -1270.0um + 50.0mil + 50.0mil + 25.0mil + 50.0mil + -1270.0um + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 1.999996mm + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + } + hdia = 31.5mil + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v4.1 { + htop = 0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.199894mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.199894mm + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.199894mm + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + } + hdia = 0.999998mm + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v4.2 { + htop = 0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.326894mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.326894mm + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + } + hdia = 0.999998mm + hbottom = -1 + hplated = 1 + } + ha:ps_proto_v4.3 { + htop = 2 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.453894mm + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.453894mm + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + } + hdia = 0.999998mm + hbottom = 0 + hplated = 1 + } + ha:ps_proto_v4.4 { + htop = 0 + li:shape { + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.580894mm + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.580894mm + } + ha:layer_mask { + bottom = 1 + copper = 1 + } + ha:combining { + } + } + ha:ps_shape_v4 { + clearance = 0.0 + ha:ps_circ { + x = 0.0 + y = 0.0 + dia = 2.580894mm + } + ha:layer_mask { + copper = 1 + intern = 1 + } + ha:combining { + } + } + } + hdia = 0.999998mm + hbottom = 0 + hplated = 1 + } + } + + li:objects { + ha:padstack_ref.60 { + proto = 0 + xmirror = 0 + x = 75.0mil + rot = 0.000000 + y = 100.0mil + li:thermal { + } + ha:flags ={ clearline=1 + }; clearance = 20.0mil + } + ha:padstack_ref.62 { + proto = 1 + xmirror = 0 + x = 375.0mil + rot = 0.000000 + y = 100.0mil + li:thermal { + } + ha:flags ={ clearline=1 + }; clearance = 20.0mil + } + ha:padstack_ref.63 { + proto = 2 + xmirror = 0 + x = 75.0mil + rot = 0.000000 + y = 325.0mil + li:thermal { + } + ha:flags ={ clearline=1 + }; clearance = 20.0mil + } + ha:padstack_ref.64 { + proto = 3 + xmirror = 0 + x = 225.0mil + rot = 0.000000 + y = 325.0mil + li:thermal { + } + ha:flags ={ clearline=1 + }; clearance = 20.0mil + } + } + li:layers { + + ha:comp1 { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:solder1 { + lid=1 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:com2 { + lid=2 + group=3 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:solder2 { + lid=3 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:inner1 { + lid=4 + group=5 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:inner2 { + lid=5 + group=7 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:outline { + lid=6 + group=9 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:silk { + lid=7 + group=12 + ha:combining { auto=1; } + visible=1 + + li:objects { + } + } + + ha:silk { + lid=8 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + } + } + + ha:topmask { + lid=9 + group=2 + ha:combining { sub=1; auto=1; } + visible=0 + + li:objects { + } + } + + ha:toppaste { + lid=10 + group=0 + ha:combining { auto=1; } + visible=0 + + li:objects { + ha:line.42 { + x1=100.0mil; y1=150.0mil; x2=100.0mil; y2=25.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + } + } + } + + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { 10;} + } + 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 { 9;} + } + ha:3 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; 2; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 4; } + } + ha:6 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_6 + } + ha:7 { + name = Intern + ha:type { copper=1; intern=1; } + li:layers { 5; } + } + ha:8 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_8 + } + ha:9 { + name = global outline + ha:type { outline=1; intern=1; } + li:layers { 6; } + } + 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 { } + } + 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 { } + } + } + } +} Index: tags/2.3.0/tests/RTT/poly_hole.pcb =================================================================== --- tags/2.3.0/tests/RTT/poly_hole.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/poly_hole.pcb (revision 33253) @@ -0,0 +1,385 @@ +# release: pcb-rnd 1.2.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20100606] + +PCB["Polygons with holes" 50000 50000] + +Grid[2500 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,alldirection,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,1000,7874,3150,2000:style2,2000,8661,3937,2000:style3,8000,13780,4724,2500:style4,10000,6400,3150,10000"] + +Symbol[' ' 1800] +( +) +Symbol['1' 1200] +( + SymbolLine[0 800 800 0 800] + SymbolLine[800 0 800 4000 800] + SymbolLine[0 4000 1500 4000 800] +) +Symbol['2' 1200] +( + SymbolLine[0 500 500 0 800] + SymbolLine[500 0 2000 0 800] + SymbolLine[2000 0 2500 500 800] + SymbolLine[2500 500 2500 1500 800] + SymbolLine[0 4000 2500 1500 800] + SymbolLine[0 4000 2500 4000 800] +) +Symbol['3' 1200] +( + SymbolLine[0 500 500 0 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[1500 0 2000 500 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[500 1800 1500 1800 800] + SymbolLine[2000 500 2000 1300 800] + SymbolLine[2000 2300 2000 3500 800] + SymbolLine[2000 2300 1500 1800 800] + SymbolLine[2000 1300 1500 1800 800] +) +Symbol['4' 1200] +( + SymbolLine[0 2500 2000 0 800] + SymbolLine[0 2500 2500 2500 800] + SymbolLine[2000 0 2000 4000 800] +) +Symbol['5' 1200] +( + SymbolLine[0 0 2000 0 800] + SymbolLine[0 0 0 2000 800] + SymbolLine[0 2000 500 1500 800] + SymbolLine[500 1500 1500 1500 800] + SymbolLine[1500 1500 2000 2000 800] + SymbolLine[2000 2000 2000 3500 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[0 3500 500 4000 800] +) +Symbol['6' 1200] +( + SymbolLine[1500 0 2000 500 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[0 500 500 0 800] + SymbolLine[0 500 0 3500 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[1500 1800 2000 2300 800] + SymbolLine[0 1800 1500 1800 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[2000 2300 2000 3500 800] +) +Symbol['7' 1200] +( + SymbolLine[500 4000 2500 0 800] + SymbolLine[0 0 2500 0 800] +) +Symbol['8' 1200] +( + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 2700 0 3500 800] + SymbolLine[0 2700 700 2000 800] + SymbolLine[700 2000 1300 2000 800] + SymbolLine[1300 2000 2000 2700 800] + SymbolLine[2000 2700 2000 3500 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[0 1300 700 2000 800] + SymbolLine[0 500 0 1300 800] + SymbolLine[0 500 500 0 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[1500 0 2000 500 800] + SymbolLine[2000 500 2000 1300 800] + SymbolLine[1300 2000 2000 1300 800] +) +Symbol['9' 1200] +( + SymbolLine[500 4000 2000 2000 800] + SymbolLine[2000 500 2000 2000 800] + SymbolLine[1500 0 2000 500 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[0 500 500 0 800] + SymbolLine[0 500 0 1500 800] + SymbolLine[0 1500 500 2000 800] + SymbolLine[500 2000 2000 2000 800] +) +Symbol['A' 1200] +( + SymbolLine[0 1000 0 4000 800] + SymbolLine[0 1000 700 0 800] + SymbolLine[700 0 1800 0 800] + SymbolLine[1800 0 2500 1000 800] + SymbolLine[2500 1000 2500 4000 800] + SymbolLine[0 2000 2500 2000 800] +) +Symbol['B' 1200] +( + SymbolLine[0 4000 2000 4000 800] + SymbolLine[2000 4000 2500 3500 800] + SymbolLine[2500 2300 2500 3500 800] + SymbolLine[2000 1800 2500 2300 800] + SymbolLine[500 1800 2000 1800 800] + SymbolLine[500 0 500 4000 800] + SymbolLine[0 0 2000 0 800] + SymbolLine[2000 0 2500 500 800] + SymbolLine[2500 500 2500 1300 800] + SymbolLine[2000 1800 2500 1300 800] +) +Symbol['C' 1200] +( + SymbolLine[700 4000 2000 4000 800] + SymbolLine[0 3300 700 4000 800] + SymbolLine[0 700 0 3300 800] + SymbolLine[0 700 700 0 800] + SymbolLine[700 0 2000 0 800] +) +Symbol['D' 1200] +( + SymbolLine[500 0 500 4000 800] + SymbolLine[1800 0 2500 700 800] + SymbolLine[2500 700 2500 3300 800] + SymbolLine[1800 4000 2500 3300 800] + SymbolLine[0 4000 1800 4000 800] + SymbolLine[0 0 1800 0 800] +) +Symbol['E' 1200] +( + SymbolLine[0 1800 1500 1800 800] + SymbolLine[0 4000 2000 4000 800] + SymbolLine[0 0 0 4000 800] + SymbolLine[0 0 2000 0 800] +) +Symbol['F' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[0 0 2000 0 800] + SymbolLine[0 1800 1500 1800 800] +) +Symbol['G' 1200] +( + SymbolLine[2000 0 2500 500 800] + SymbolLine[500 0 2000 0 800] + SymbolLine[0 500 500 0 800] + SymbolLine[0 500 0 3500 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[2000 4000 2500 3500 800] + SymbolLine[2500 2500 2500 3500 800] + SymbolLine[2000 2000 2500 2500 800] + SymbolLine[1000 2000 2000 2000 800] +) +Symbol['H' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[2500 0 2500 4000 800] + SymbolLine[0 2000 2500 2000 800] +) +Symbol['I' 1200] +( + SymbolLine[0 0 1000 0 800] + SymbolLine[500 0 500 4000 800] + SymbolLine[0 4000 1000 4000 800] +) +Symbol['J' 1200] +( + SymbolLine[700 0 1500 0 800] + SymbolLine[1500 0 1500 3500 800] + SymbolLine[1000 4000 1500 3500 800] + SymbolLine[500 4000 1000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 3500 0 3000 800] +) +Symbol['K' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[0 2000 2000 0 800] + SymbolLine[0 2000 2000 4000 800] +) +Symbol['L' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[0 4000 2000 4000 800] +) +Symbol['M' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[0 0 1500 2000 800] + SymbolLine[1500 2000 3000 0 800] + SymbolLine[3000 0 3000 4000 800] +) +Symbol['N' 1200] +( + SymbolLine[0 0 0 4000 800] + SymbolLine[0 0 2500 4000 800] + SymbolLine[2500 0 2500 4000 800] +) +Symbol['O' 1200] +( + SymbolLine[0 500 0 3500 800] + SymbolLine[0 500 500 0 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[1500 0 2000 500 800] + SymbolLine[2000 500 2000 3500 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[0 3500 500 4000 800] +) +Symbol['P' 1200] +( + SymbolLine[500 0 500 4000 800] + SymbolLine[0 0 2000 0 800] + SymbolLine[2000 0 2500 500 800] + SymbolLine[2500 500 2500 1500 800] + SymbolLine[2000 2000 2500 1500 800] + SymbolLine[500 2000 2000 2000 800] +) +Symbol['Q' 1200] +( + SymbolLine[0 500 0 3500 800] + SymbolLine[0 500 500 0 800] + SymbolLine[500 0 1500 0 800] + SymbolLine[1500 0 2000 500 800] + SymbolLine[2000 500 2000 3000 800] + SymbolLine[1000 4000 2000 3000 800] + SymbolLine[500 4000 1000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[1000 2500 2000 4000 800] +) +Symbol['R' 1200] +( + SymbolLine[0 0 2000 0 800] + SymbolLine[2000 0 2500 500 800] + SymbolLine[2500 500 2500 1500 800] + SymbolLine[2000 2000 2500 1500 800] + SymbolLine[500 2000 2000 2000 800] + SymbolLine[500 0 500 4000 800] + SymbolLine[1300 2000 2500 4000 800] +) +Symbol['S' 1200] +( + SymbolLine[2000 0 2500 500 800] + SymbolLine[500 0 2000 0 800] + SymbolLine[0 500 500 0 800] + SymbolLine[0 500 0 1500 800] + SymbolLine[0 1500 500 2000 800] + SymbolLine[500 2000 2000 2000 800] + SymbolLine[2000 2000 2500 2500 800] + SymbolLine[2500 2500 2500 3500 800] + SymbolLine[2000 4000 2500 3500 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[0 3500 500 4000 800] +) +Symbol['T' 1200] +( + SymbolLine[0 0 2000 0 800] + SymbolLine[1000 0 1000 4000 800] +) +Symbol['U' 1200] +( + SymbolLine[0 0 0 3500 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[500 4000 1500 4000 800] + SymbolLine[1500 4000 2000 3500 800] + SymbolLine[2000 0 2000 3500 800] +) +Symbol['V' 1200] +( + SymbolLine[0 0 1000 4000 800] + SymbolLine[1000 4000 2000 0 800] +) +Symbol['W' 1200] +( + SymbolLine[0 0 0 2000 800] + SymbolLine[0 2000 500 4000 800] + SymbolLine[500 4000 1500 2000 800] + SymbolLine[1500 2000 2500 4000 800] + SymbolLine[2500 4000 3000 2000 800] + SymbolLine[3000 2000 3000 0 800] +) +Symbol['X' 1200] +( + SymbolLine[0 4000 2500 0 800] + SymbolLine[0 0 2500 4000 800] +) +Symbol['Y' 1200] +( + SymbolLine[0 0 1000 2000 800] + SymbolLine[1000 2000 2000 0 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol['Z' 1200] +( + SymbolLine[0 0 2500 0 800] + SymbolLine[0 4000 2500 0 800] + SymbolLine[0 4000 2500 4000 800] +) +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") +Attribute("PCB::loader" "geda/pcb - mainline (centimils)") +Layer(1 "comp1") +( + Polygon("clearpoly") + ( + [2500 2500] [12500 2500] [2500 12500] + Hole ( + [5000 5000] [5000 7500] [7500 5000] + ) + ) + Polygon("clearpoly") + ( + [2500 15000] [15000 2500] [15000 15000] + Hole ( + [7500 12500] [12500 12500] [12500 10000] [10000 10000] + ) + ) + Polygon("clearpoly") + ( + [17500 15000] [30000 2500] [42500 15000] + Hole ( + [27500 7500] [27500 12500] [32500 12500] [32500 7500] + ) + ) + Polygon("clearpoly") + ( + [2500 17500] [30000 20000] [5000 35000] + Hole ( + [15000 22500] [15000 25000] [17500 25000] [17500 22500] + ) + Hole ( + [7500 22500] [7500 27500] [10000 30000] [12500 27500] [12500 25000] + [10000 22500] + ) + ) +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/poly_rect.pcb =================================================================== --- tags/2.3.0/tests/RTT/poly_rect.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/poly_rect.pcb (revision 33253) @@ -0,0 +1,59 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Normal rectangular polygons" 500.0mil 500.0mil] + +Grid[25.0mil 0.0 0.0 1] +Cursor[0.0 150.0mil 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[12.0mil 9.0mil 10.0mil 7.0mil 15.0mil 10.0mil] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,10.0mil,78.7399606mil,31.5mil,20.0mil:style2,20.0mil,86.61mil,39.3699606mil,20.0mil:style3,80.0mil,137.7999606mil,47.2399606mil,25.0mil:style4,100.0mil,64.0mil,31.5mil,100.0mil"] + +Layer(1 "comp1") +( + Polygon("") + ( + [1270000nm 635000nm] [1905000nm 635000nm] [1905000nm 11430000nm] [1270000nm 11430000nm] + ) + Polygon("") + ( + [3175000nm 635000nm] [12065000nm 635000nm] [12065000nm 1270000nm] [3175000nm 1270000nm] + ) + Polygon("") + ( + [10795000nm 10795000nm] [11430000nm 10795000nm] [11430000nm 11430000nm] [10795000nm 11430000nm] + ) + Polygon("") + ( + [3175000nm 1905000nm] [10160000nm 1905000nm] [10160000nm 11430000nm] [3175000nm 11430000nm] + ) +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/poly_triangle.pcb =================================================================== --- tags/2.3.0/tests/RTT/poly_triangle.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/poly_triangle.pcb (revision 33253) @@ -0,0 +1,59 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["Normal triangular polygons" 500.0mil 500.0mil] + +Grid[25.0mil 0.0 0.0 1] +Cursor[25.0mil 0.0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[12.0mil 9.0mil 10.0mil 7.0mil 15.0mil 10.0mil] +Flags("nameonpcb,alldirection,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,10.0mil,78.7399606mil,31.5mil,20.0mil:style2,20.0mil,86.61mil,39.3699606mil,20.0mil:style3,80.0mil,137.7999606mil,47.2399606mil,25.0mil:style4,100.0mil,64.0mil,31.5mil,100.0mil"] + +Layer(1 "comp1") +( + Polygon("clearpoly") + ( + [635000nm 635000nm] [635000nm 3175000nm] [3175000nm 635000nm] + ) + Polygon("clearpoly") + ( + [635000nm 3810000nm] [3810000nm 635000nm] [3810000nm 3810000nm] + ) + Polygon("clearpoly") + ( + [4445000nm 3810000nm] [7620000nm 635000nm] [10795000nm 3810000nm] + ) + Polygon("clearpoly") + ( + [635000nm 4445000nm] [1270000nm 8890000nm] [7620000nm 5080000nm] + ) +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/rat.pcb =================================================================== --- tags/2.3.0/tests/RTT/rat.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/rat.pcb (revision 33253) @@ -0,0 +1,46 @@ +# release: pcb-rnd 1.1.0 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["a rat line" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Rat[10000000nm 10000000nm 1 20000000nm 20000000nm 1 ""] + + +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/ref/arc_angles.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: arcs with different strange angles - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/arc_angles.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb arcs with different strange angles + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/arc_angles.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.eps (revision 33253) @@ -0,0 +1,37 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: arc_angles.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.01000 setlinewidth +1 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.000000 750.000000 -0.05000 0.05000 0.10000 0.10000 0.200000 a +0.000000 0.000000 -0.05000 0.05000 0.30000 0.10000 0.200000 a +-750.000000 0.000000 -0.05000 0.05000 0.40000 0.10000 0.200000 a +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/arc_angles.exc/arc_angles.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.exc/arc_angles.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.exc/arc_angles.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/arc_angles.exc/arc_angles.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.exc/arc_angles.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.exc/arc_angles.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/arc_angles.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/arc_angles.gbr/arc_angles.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.gbr/arc_angles.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.gbr/arc_angles.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: arcs with different strange angles, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_angles.gbr/arc_angles.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.gbr/arc_angles.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.gbr/arc_angles.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1837 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: arcs with different strange angles, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X258800D02*X263300D01* +Y104000D01* +X258800D01* +Y110000D01* +G37* +G36* +X264200D02*X268700D01* +Y104000D01* +X264200D01* +Y110000D01* +G37* +G36* +X269600D02*X274100D01* +Y104000D01* +X269600D01* +Y110000D01* +G37* +G36* +X275000D02*X279500D01* +Y104000D01* +X275000D01* +Y110000D01* +G37* +G36* +X283100D02*X287600D01* +Y104000D01* +X283100D01* +Y110000D01* +G37* +G36* +X288500D02*X293000D01* +Y104000D01* +X288500D01* +Y110000D01* +G37* +G36* +X293900D02*X298400D01* +Y104000D01* +X293900D01* +Y110000D01* +G37* +G36* +X299300D02*X303800D01* +Y104000D01* +X299300D01* +Y110000D01* +G37* +G36* +X304700D02*X309200D01* +Y104000D01* +X304700D01* +Y110000D01* +G37* +G36* +X310100D02*X314600D01* +Y104000D01* +X310100D01* +Y110000D01* +G37* +G36* +X315500D02*X320000D01* +Y104000D01* +X315500D01* +Y110000D01* +G37* +G36* +X320900D02*X325400D01* +Y104000D01* +X320900D01* +Y110000D01* +G37* +G36* +X326300D02*X330800D01* +Y104000D01* +X326300D01* +Y110000D01* +G37* +G36* +X334400D02*X338900D01* +Y104000D01* +X334400D01* +Y110000D01* +G37* +G36* +X339800D02*X344300D01* +Y104000D01* +X339800D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X356000D02*X360500D01* +Y104000D01* +X356000D01* +Y110000D01* +G37* +G36* +X361400D02*X365900D01* +Y104000D01* +X361400D01* +Y110000D01* +G37* +G36* +X366800D02*X371300D01* +Y104000D01* +X366800D01* +Y110000D01* +G37* +G36* +X374900D02*X379400D01* +Y104000D01* +X374900D01* +Y110000D01* +G37* +G36* +X380300D02*X384800D01* +Y104000D01* +X380300D01* +Y110000D01* +G37* +G36* +X385700D02*X390200D01* +Y104000D01* +X385700D01* +Y110000D01* +G37* +G36* +X391100D02*X395600D01* +Y104000D01* +X391100D01* +Y110000D01* +G37* +G36* +X396500D02*X401000D01* +Y104000D01* +X396500D01* +Y110000D01* +G37* +G36* +X401900D02*X406400D01* +Y104000D01* +X401900D01* +Y110000D01* +G37* +G36* +X410000D02*X414500D01* +Y104000D01* +X410000D01* +Y110000D01* +G37* +G54D13*X418100D02*Y104000D01* +Y110000D02*X421100D01* +X418100Y107300D02*X420350D01* +G54D14*G36* +X422900Y110000D02*X427400D01* +Y104000D01* +X422900D01* +Y110000D01* +G37* +G36* +X428300D02*X432800D01* +Y104000D01* +X428300D01* +Y110000D01* +G37* +G36* +X433700D02*X438200D01* +Y104000D01* +X433700D01* +Y110000D01* +G37* +G36* +X439100D02*X443600D01* +Y104000D01* +X439100D01* +Y110000D01* +G37* +G36* +X444500D02*X449000D01* +Y104000D01* +X444500D01* +Y110000D01* +G37* +G36* +X449900D02*X454400D01* +Y104000D01* +X449900D01* +Y110000D01* +G37* +G36* +X455300D02*X459800D01* +Y104000D01* +X455300D01* +Y110000D01* +G37* +G36* +X460700D02*X465200D01* +Y104000D01* +X460700D01* +Y110000D01* +G37* +G36* +X466100D02*X470600D01* +Y104000D01* +X466100D01* +Y110000D01* +G37* +G36* +X471500D02*X476000D01* +Y104000D01* +X471500D01* +Y110000D01* +G37* +G54D13*X480350D02*Y104000D01* +X482300Y110000D02*X483350Y108950D01* +Y105050D01* +X482300Y104000D02*X483350Y105050D01* +X479600Y104000D02*X482300D01* +X479600Y110000D02*X482300D01* +G54D14*G36* +X485150D02*X489650D01* +Y104000D01* +X485150D01* +Y110000D01* +G37* +G36* +X490550D02*X495050D01* +Y104000D01* +X490550D01* +Y110000D01* +G37* +G36* +X495950D02*X500450D01* +Y104000D01* +X495950D01* +Y110000D01* +G37* +G36* +X501350D02*X505850D01* +Y104000D01* +X501350D01* +Y110000D01* +G37* +G36* +X506750D02*X511250D01* +Y104000D01* +X506750D01* +Y110000D01* +G37* +G36* +X512150D02*X516650D01* +Y104000D01* +X512150D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_angles.gbr/arc_angles.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.gbr/arc_angles.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.gbr/arc_angles.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,18 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: arcs with different strange angles, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0100*% +G54D11*X5000Y40000D02*G75*G03X15000Y40000I5000J0D01*G01* +G75*G03X5000Y40000I-5000J0D01*G01* +X25000Y40000D03* +X35000D02*G75*G02X45000Y40000I5000J0D01*G01* +G75*G02X35000Y40000I-5000J0D01*G01* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_angles.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/arc_angles.net =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB arcs with different strange angles +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/arc_angles.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_angles.png =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_angles.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_angles.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.png.text (revision 33253) @@ -0,0 +1,22 @@ +r6630 + +right circle +132 pixels (110 mil) horizontally +132 pixels (110 mil) vertically +13 pixels (10.833 mil) wall thickness + +left circle +132 pixels (110 mil) horizontally +132 pixels (100 mil) vertically +13 pixels (10.833 mil) wall thickness + +central dot +13 pixel (10.833 mil) diameter + +air gap between right circle and central dot +107 pixels (89.166 mil) + +air gap between left circle and central dot +108 pixels (90 mil) + + Index: tags/2.3.0/tests/RTT/ref/arc_angles.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_angles.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_angles.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_angles.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_angles.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_angles.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_angles.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.svg (revision 33253) @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/arc_angles.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_angles.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_angles.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: arcs with different strange angles - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Arc with clearline flag - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb Arc with clearline flag + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.eps (revision 33253) @@ -0,0 +1,222 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: arc_f_clear.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.47500 0.15000 moveto +0.47500 0.47500 lineto +0.29999 0.47500 lineto +0.29999 0.32505 lineto +0.30000 0.32505 lineto +0.30436 0.32486 lineto +0.30869 0.32429 lineto +0.31295 0.32334 lineto +0.31712 0.32203 lineto +0.32115 0.32036 lineto +0.32502 0.31834 lineto +0.32871 0.31600 lineto +0.33217 0.31334 lineto +0.33539 0.31039 lineto +0.33834 0.30717 lineto +0.34100 0.30371 lineto +0.34334 0.30002 lineto +0.34536 0.29615 lineto +0.34703 0.29212 lineto +0.34834 0.28795 lineto +0.34929 0.28369 lineto +0.34986 0.27936 lineto +0.35005 0.27500 lineto +0.34986 0.27064 lineto +0.34929 0.26631 lineto +0.34834 0.26205 lineto +0.34703 0.25788 lineto +0.34536 0.25385 lineto +0.34334 0.24998 lineto +0.34100 0.24629 lineto +0.33834 0.24283 lineto +0.33539 0.23961 lineto +0.33217 0.23666 lineto +0.32871 0.23400 lineto +0.32502 0.23166 lineto +0.32115 0.22964 lineto +0.31712 0.22797 lineto +0.31295 0.22666 lineto +0.30869 0.22571 lineto +0.30436 0.22514 lineto +0.30000 0.22495 lineto +0.29999 0.22495 lineto +0.29999 0.15000 lineto +fill +0.29999 0.15000 moveto +0.29999 0.22495 lineto +0.29564 0.22514 lineto +0.29131 0.22571 lineto +0.28705 0.22666 lineto +0.28288 0.22797 lineto +0.27885 0.22964 lineto +0.27667 0.23078 lineto +0.27612 0.23101 lineto +0.27548 0.23140 lineto +0.27498 0.23166 lineto +0.27500 0.23169 lineto +0.27276 0.23306 lineto +0.26977 0.23562 lineto +0.26721 0.23861 lineto +0.26516 0.24196 lineto +0.26365 0.24560 lineto +0.26273 0.24943 lineto +0.26242 0.25335 lineto +0.26243 0.25339 lineto +0.26026 0.25471 lineto +0.25727 0.25727 lineto +0.25471 0.26026 lineto +0.25266 0.26362 lineto +0.25115 0.26725 lineto +0.25023 0.27108 lineto +0.24992 0.27500 lineto +0.25005 0.27668 lineto +0.25014 0.27936 lineto +0.25071 0.28369 lineto +0.25166 0.28795 lineto +0.25297 0.29212 lineto +0.25464 0.29615 lineto +0.25666 0.30002 lineto +0.25900 0.30371 lineto +0.26166 0.30717 lineto +0.26461 0.31039 lineto +0.26783 0.31334 lineto +0.27129 0.31600 lineto +0.27498 0.31834 lineto +0.27885 0.32036 lineto +0.28288 0.32203 lineto +0.28705 0.32334 lineto +0.29131 0.32429 lineto +0.29564 0.32486 lineto +0.29999 0.32505 lineto +0.29999 0.47500 lineto +0.13759 0.47500 lineto +0.13759 0.36151 lineto +0.14865 0.36609 lineto +0.16114 0.37003 lineto +0.17393 0.37286 lineto +0.18691 0.37457 lineto +0.20000 0.37514 lineto +0.20394 0.37486 lineto +0.20778 0.37394 lineto +0.21143 0.37243 lineto +0.21480 0.37037 lineto +0.21780 0.36780 lineto +0.22037 0.36480 lineto +0.22243 0.36143 lineto +0.22394 0.35778 lineto +0.22486 0.35394 lineto +0.22517 0.35000 lineto +0.22486 0.34606 lineto +0.22394 0.34222 lineto +0.22243 0.33857 lineto +0.22037 0.33520 lineto +0.21780 0.33220 lineto +0.21480 0.32963 lineto +0.21143 0.32757 lineto +0.20778 0.32606 lineto +0.20394 0.32514 lineto +0.20000 0.32490 lineto +0.19128 0.32462 lineto +0.18264 0.32348 lineto +0.17412 0.32159 lineto +0.16580 0.31897 lineto +0.15774 0.31563 lineto +0.15000 0.31160 lineto +0.14264 0.30692 lineto +0.13759 0.30304 lineto +0.13759 0.15000 lineto +fill +0.13759 0.15000 moveto +0.13759 0.30304 lineto +0.13572 0.30160 lineto +0.12929 0.29571 lineto +0.12340 0.28928 lineto +0.11808 0.28236 lineto +0.11340 0.27500 lineto +0.10937 0.26726 lineto +0.10603 0.25920 lineto +0.10341 0.25088 lineto +0.10152 0.24236 lineto +0.10038 0.23372 lineto +0.10000 0.22500 lineto +0.09977 0.22108 lineto +0.09885 0.21725 lineto +0.09734 0.21362 lineto +0.09529 0.21026 lineto +0.09273 0.20727 lineto +0.08974 0.20471 lineto +0.08638 0.20266 lineto +0.08275 0.20115 lineto +0.07892 0.20023 lineto +0.07500 0.19992 lineto +0.07108 0.20023 lineto +0.06725 0.20115 lineto +0.06362 0.20266 lineto +0.06026 0.20471 lineto +0.05727 0.20727 lineto +0.05471 0.21026 lineto +0.05266 0.21362 lineto +0.05115 0.21725 lineto +0.05023 0.22108 lineto +0.05000 0.22500 lineto +0.05043 0.23809 lineto +0.05214 0.25107 lineto +0.05497 0.26386 lineto +0.05891 0.27635 lineto +0.06392 0.28845 lineto +0.06997 0.30007 lineto +0.07701 0.31112 lineto +0.08498 0.32151 lineto +0.09383 0.33117 lineto +0.10349 0.34002 lineto +0.11388 0.34799 lineto +0.12493 0.35503 lineto +0.13655 0.36108 lineto +0.13759 0.36151 lineto +0.13759 0.47500 lineto +0.02500 0.47500 lineto +0.02500 0.15000 lineto +fill +0.01000 setlinewidth +1 setlinecap +0.000000 90.000000 -0.12500 0.12500 0.20000 0.22500 0.080000 a +0.02000 setlinewidth +-90.000000 -10.000000 -0.10000 0.10000 0.17500 0.22500 0.200000 a +0.01000 setlinewidth +0.000000 300.000000 -0.02500 0.02500 0.30000 0.27500 0.400000 a +0.03000 setlinewidth +-160.000000 -70.000000 -0.12500 0.12500 0.25000 0.22500 0.240000 a +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.exc/arc_f_clear.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.exc/arc_f_clear.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.exc/arc_f_clear.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.exc/arc_f_clear.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.exc/arc_f_clear.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.exc/arc_f_clear.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.fcd (revision 33253) @@ -0,0 +1,2 @@ +[FIDOCAD] +PP 5 30 95 30 95 95 5 95 5 30 2 Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.gbr/arc_f_clear.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.gbr/arc_f_clear.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.gbr/arc_f_clear.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Arc with clearline flag, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD15C,0.0100*% +G54D15*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.gbr/arc_f_clear.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.gbr/arc_f_clear.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.gbr/arc_f_clear.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1777 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Arc with clearline flag, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD18C,0.0100*% +%ADD17C,0.0001*% +%ADD16C,0.0060*% +G54D16*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D17*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D16*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D17*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D16*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D17*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D16*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D17*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D16*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D17*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D16*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D17*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D18*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D16*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D17*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D16*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D17*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D16*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D17*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D16*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D17*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D16*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D17*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D16*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D17*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D16*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D17*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D16*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D17*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D16*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D17*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D16*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D17*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D16*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D17*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D16*X234500Y108500D02*Y104000D01* +Y108500D02*X235550Y110000D01* +X237200D01* +X238250Y108500D01* +Y104000D01* +X234500Y107000D02*X238250D01* +G54D17*G36* +X240050Y110000D02*X244550D01* +Y104000D01* +X240050D01* +Y110000D01* +G37* +G36* +X245450D02*X249950D01* +Y104000D01* +X245450D01* +Y110000D01* +G37* +G36* +X253550D02*X258050D01* +Y104000D01* +X253550D01* +Y110000D01* +G37* +G36* +X258950D02*X263450D01* +Y104000D01* +X258950D01* +Y110000D01* +G37* +G36* +X264350D02*X268850D01* +Y104000D01* +X264350D01* +Y110000D01* +G37* +G36* +X269750D02*X274250D01* +Y104000D01* +X269750D01* +Y110000D01* +G37* +G36* +X277850D02*X282350D01* +Y104000D01* +X277850D01* +Y110000D01* +G37* +G36* +X283250D02*X287750D01* +Y104000D01* +X283250D01* +Y110000D01* +G37* +G36* +X288650D02*X293150D01* +Y104000D01* +X288650D01* +Y110000D01* +G37* +G36* +X294050D02*X298550D01* +Y104000D01* +X294050D01* +Y110000D01* +G37* +G36* +X299450D02*X303950D01* +Y104000D01* +X299450D01* +Y110000D01* +G37* +G36* +X304850D02*X309350D01* +Y104000D01* +X304850D01* +Y110000D01* +G37* +G36* +X310250D02*X314750D01* +Y104000D01* +X310250D01* +Y110000D01* +G37* +G36* +X315650D02*X320150D01* +Y104000D01* +X315650D01* +Y110000D01* +G37* +G36* +X321050D02*X325550D01* +Y104000D01* +X321050D01* +Y110000D01* +G37* +G36* +X329150D02*X333650D01* +Y104000D01* +X329150D01* +Y110000D01* +G37* +G36* +X334550D02*X339050D01* +Y104000D01* +X334550D01* +Y110000D01* +G37* +G36* +X339950D02*X344450D01* +Y104000D01* +X339950D01* +Y110000D01* +G37* +G36* +X345350D02*X349850D01* +Y104000D01* +X345350D01* +Y110000D01* +G37* +G36* +X353450D02*X357950D01* +Y104000D01* +X353450D01* +Y110000D01* +G37* +G54D16*X361550D02*Y104000D01* +Y110000D02*X364550D01* +X361550Y107300D02*X363800D01* +G54D17*G36* +X366350Y110000D02*X370850D01* +Y104000D01* +X366350D01* +Y110000D01* +G37* +G36* +X371750D02*X376250D01* +Y104000D01* +X371750D01* +Y110000D01* +G37* +G36* +X377150D02*X381650D01* +Y104000D01* +X377150D01* +Y110000D01* +G37* +G36* +X382550D02*X387050D01* +Y104000D01* +X382550D01* +Y110000D01* +G37* +G36* +X387950D02*X392450D01* +Y104000D01* +X387950D01* +Y110000D01* +G37* +G36* +X393350D02*X397850D01* +Y104000D01* +X393350D01* +Y110000D01* +G37* +G36* +X398750D02*X403250D01* +Y104000D01* +X398750D01* +Y110000D01* +G37* +G36* +X404150D02*X408650D01* +Y104000D01* +X404150D01* +Y110000D01* +G37* +G36* +X409550D02*X414050D01* +Y104000D01* +X409550D01* +Y110000D01* +G37* +G36* +X414950D02*X419450D01* +Y104000D01* +X414950D01* +Y110000D01* +G37* +G54D16*X423800D02*Y104000D01* +X425750Y110000D02*X426800Y108950D01* +Y105050D01* +X425750Y104000D02*X426800Y105050D01* +X423050Y104000D02*X425750D01* +X423050Y110000D02*X425750D01* +G54D17*G36* +X428600D02*X433100D01* +Y104000D01* +X428600D01* +Y110000D01* +G37* +G36* +X434000D02*X438500D01* +Y104000D01* +X434000D01* +Y110000D01* +G37* +G36* +X439400D02*X443900D01* +Y104000D01* +X439400D01* +Y110000D01* +G37* +G36* +X444800D02*X449300D01* +Y104000D01* +X444800D01* +Y110000D01* +G37* +G36* +X450200D02*X454700D01* +Y104000D01* +X450200D01* +Y110000D01* +G37* +G36* +X455600D02*X460100D01* +Y104000D01* +X455600D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.gbr/arc_f_clear.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.gbr/arc_f_clear.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.gbr/arc_f_clear.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,203 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Arc with clearline flag, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD14C,0.0300*% +%ADD13C,0.0200*% +%ADD12C,0.0100*% +%ADD11C,0.0001*% +G54D11*G36* +X47500Y35000D02*Y2500D01* +X29999D01* +Y17495D01* +X30000Y17495D01* +X30436Y17514D01* +X30869Y17571D01* +X31295Y17666D01* +X31712Y17797D01* +X32115Y17964D01* +X32502Y18166D01* +X32871Y18400D01* +X33217Y18666D01* +X33539Y18961D01* +X33834Y19283D01* +X34100Y19629D01* +X34334Y19998D01* +X34536Y20385D01* +X34703Y20788D01* +X34834Y21205D01* +X34929Y21631D01* +X34986Y22064D01* +X35005Y22500D01* +X34986Y22936D01* +X34929Y23369D01* +X34834Y23795D01* +X34703Y24212D01* +X34536Y24615D01* +X34334Y25002D01* +X34100Y25371D01* +X33834Y25717D01* +X33539Y26039D01* +X33217Y26334D01* +X32871Y26600D01* +X32502Y26834D01* +X32115Y27036D01* +X31712Y27203D01* +X31295Y27334D01* +X30869Y27429D01* +X30436Y27486D01* +X30000Y27505D01* +X29999Y27505D01* +Y35000D01* +X47500D01* +G37* +G36* +X29999D02*Y27505D01* +X29564Y27486D01* +X29131Y27429D01* +X28705Y27334D01* +X28288Y27203D01* +X27885Y27036D01* +X27667Y26922D01* +X27612Y26899D01* +X27548Y26860D01* +X27498Y26834D01* +X27500Y26831D01* +X27276Y26694D01* +X26977Y26438D01* +X26721Y26139D01* +X26516Y25804D01* +X26365Y25440D01* +X26273Y25057D01* +X26242Y24665D01* +X26243Y24661D01* +X26026Y24529D01* +X25727Y24273D01* +X25471Y23974D01* +X25266Y23638D01* +X25115Y23275D01* +X25023Y22892D01* +X24992Y22500D01* +X25005Y22332D01* +X25014Y22064D01* +X25071Y21631D01* +X25166Y21205D01* +X25297Y20788D01* +X25464Y20385D01* +X25666Y19998D01* +X25900Y19629D01* +X26166Y19283D01* +X26461Y18961D01* +X26783Y18666D01* +X27129Y18400D01* +X27498Y18166D01* +X27885Y17964D01* +X28288Y17797D01* +X28705Y17666D01* +X29131Y17571D01* +X29564Y17514D01* +X29999Y17495D01* +Y2500D01* +X13759D01* +Y13849D01* +X14865Y13391D01* +X16114Y12997D01* +X17393Y12714D01* +X18691Y12543D01* +X20000Y12486D01* +X20394Y12514D01* +X20778Y12606D01* +X21143Y12757D01* +X21480Y12963D01* +X21780Y13220D01* +X22037Y13520D01* +X22243Y13857D01* +X22394Y14222D01* +X22486Y14606D01* +X22517Y15000D01* +X22486Y15394D01* +X22394Y15778D01* +X22243Y16143D01* +X22037Y16480D01* +X21780Y16780D01* +X21480Y17037D01* +X21143Y17243D01* +X20778Y17394D01* +X20394Y17486D01* +X20000Y17510D01* +X19128Y17538D01* +X18264Y17652D01* +X17412Y17841D01* +X16580Y18103D01* +X15774Y18437D01* +X15000Y18840D01* +X14264Y19308D01* +X13759Y19696D01* +Y35000D01* +X29999D01* +G37* +G36* +X13759D02*Y19696D01* +X13572Y19840D01* +X12929Y20429D01* +X12340Y21072D01* +X11808Y21764D01* +X11340Y22500D01* +X10937Y23274D01* +X10603Y24080D01* +X10341Y24912D01* +X10152Y25764D01* +X10038Y26628D01* +X10000Y27500D01* +X9977Y27892D01* +X9885Y28275D01* +X9734Y28638D01* +X9529Y28974D01* +X9273Y29273D01* +X8974Y29529D01* +X8638Y29734D01* +X8275Y29885D01* +X7892Y29977D01* +X7500Y30008D01* +X7108Y29977D01* +X6725Y29885D01* +X6362Y29734D01* +X6026Y29529D01* +X5727Y29273D01* +X5471Y28974D01* +X5266Y28638D01* +X5115Y28275D01* +X5023Y27892D01* +X5000Y27500D01* +X5043Y26191D01* +X5214Y24893D01* +X5497Y23614D01* +X5891Y22365D01* +X6392Y21155D01* +X6997Y19993D01* +X7701Y18888D01* +X8498Y17849D01* +X9383Y16883D01* +X10349Y15998D01* +X11388Y15201D01* +X12493Y14497D01* +X13655Y13892D01* +X13759Y13849D01* +Y2500D01* +X2500D01* +Y35000D01* +X13759D01* +G37* +G54D12*X7500Y27500D02*G75*G03X20000Y15000I12500J0D01*G01* +G54D13*X7652Y29236D02*G75*G02X17500Y37500I9848J-1736D01*G01* +G54D12*X27500Y22500D02*G75*G03X32500Y22500I2500J0D01*G01* +G75*G03X28750Y24665I-2500J0D01*G01* +G54D14*X20725Y39246D02*G75*G02X36746Y31775I4275J-11746D01*G01* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.net =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Arc with clearline flag +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.png =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_f_clear.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.png.text (revision 33253) @@ -0,0 +1,25 @@ +r6630 + +polygone +width 541 pixels (450.833 mil) +height 391 pixels (324.833 mil) +---- +small near circle completely in polygon +width 13 pixels (10.833 mils) +clearance on the left 23 pixels (19.166 mil) +clearance on the right 24 pixels (20 mil) +clearance on the top 24 pixels (20 mil) +clearance on the bottom 24 pixels (20 mil) + +longer arc completely in polygon +line width 13 pixels(10.833 mil) +width 162 pixels (135 mil) +height 162 pixels (135 mil) +clearance on the bottom right end 24 pixels (20 mil) +clearance on the top right end 23 pixels (19.166 mil) +clearance on the end right end 24 pixels (20 mil) +clearance on the right top end 23 pixels (19.333 mil) +clearance on the left top end 23 pixels (19.166 mil) + + + Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_f_clear.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_f_clear.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.svg (revision 33253) @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/arc_f_clear.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_f_clear.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_f_clear.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Arc with clearline flag - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/arc_normal.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Arcs with different sizes, normal cases - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/arc_normal.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb Arcs with different sizes, normal cases + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/arc_normal.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.eps (revision 33253) @@ -0,0 +1,41 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: arc_normal.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.01000 setlinewidth +1 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.000000 90.000000 -0.12500 0.12500 0.20000 0.22500 0.080000 a +0.02000 setlinewidth +-90.000000 -10.000000 -0.10000 0.10000 0.17500 0.22500 0.200000 a +0.01000 setlinewidth +0.000000 300.000000 -0.02500 0.02500 0.30000 0.27500 0.400000 a +0.03000 setlinewidth +-160.000000 -70.000000 -0.12500 0.12500 0.25000 0.22500 0.240000 a +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/arc_normal.exc/arc_normal.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.exc/arc_normal.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.exc/arc_normal.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/arc_normal.exc/arc_normal.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.exc/arc_normal.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.exc/arc_normal.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/arc_normal.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/arc_normal.gbr/arc_normal.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.gbr/arc_normal.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.gbr/arc_normal.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Arcs with different sizes, normal cases, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD14C,0.0100*% +G54D14*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_normal.gbr/arc_normal.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.gbr/arc_normal.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.gbr/arc_normal.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1861 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Arcs with different sizes, normal cases, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD17C,0.0100*% +%ADD16C,0.0001*% +%ADD15C,0.0060*% +G54D15*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D16*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D15*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D16*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D15*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D16*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D15*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D16*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D15*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D16*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D15*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D16*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D17*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D15*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D16*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D15*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D16*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D15*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D16*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D15*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D16*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D15*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D16*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D15*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D16*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D15*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D16*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D15*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D16*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D15*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D16*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D15*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D16*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D15*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D16*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D15*X234500Y108500D02*Y104000D01* +Y108500D02*X235550Y110000D01* +X237200D01* +X238250Y108500D01* +Y104000D01* +X234500Y107000D02*X238250D01* +G54D16*G36* +X240050Y110000D02*X244550D01* +Y104000D01* +X240050D01* +Y110000D01* +G37* +G36* +X245450D02*X249950D01* +Y104000D01* +X245450D01* +Y110000D01* +G37* +G36* +X250850D02*X255350D01* +Y104000D01* +X250850D01* +Y110000D01* +G37* +G36* +X258950D02*X263450D01* +Y104000D01* +X258950D01* +Y110000D01* +G37* +G36* +X264350D02*X268850D01* +Y104000D01* +X264350D01* +Y110000D01* +G37* +G36* +X269750D02*X274250D01* +Y104000D01* +X269750D01* +Y110000D01* +G37* +G36* +X275150D02*X279650D01* +Y104000D01* +X275150D01* +Y110000D01* +G37* +G36* +X283250D02*X287750D01* +Y104000D01* +X283250D01* +Y110000D01* +G37* +G36* +X288650D02*X293150D01* +Y104000D01* +X288650D01* +Y110000D01* +G37* +G36* +X294050D02*X298550D01* +Y104000D01* +X294050D01* +Y110000D01* +G37* +G36* +X299450D02*X303950D01* +Y104000D01* +X299450D01* +Y110000D01* +G37* +G36* +X304850D02*X309350D01* +Y104000D01* +X304850D01* +Y110000D01* +G37* +G36* +X310250D02*X314750D01* +Y104000D01* +X310250D01* +Y110000D01* +G37* +G36* +X315650D02*X320150D01* +Y104000D01* +X315650D01* +Y110000D01* +G37* +G36* +X321050D02*X325550D01* +Y104000D01* +X321050D01* +Y110000D01* +G37* +G36* +X326450D02*X330950D01* +Y104000D01* +X326450D01* +Y110000D01* +G37* +G36* +X334550D02*X339050D01* +Y104000D01* +X334550D01* +Y110000D01* +G37* +G36* +X339950D02*X344450D01* +Y104000D01* +X339950D01* +Y110000D01* +G37* +G36* +X345350D02*X349850D01* +Y104000D01* +X345350D01* +Y110000D01* +G37* +G36* +X350750D02*X355250D01* +Y104000D01* +X350750D01* +Y110000D01* +G37* +G36* +X356150D02*X360650D01* +Y104000D01* +X356150D01* +Y110000D01* +G37* +G36* +X361550D02*X366050D01* +Y104000D01* +X361550D01* +Y110000D01* +G37* +G36* +X369650D02*X374150D01* +Y104000D01* +X369650D01* +Y110000D01* +G37* +G36* +X375050D02*X379550D01* +Y104000D01* +X375050D01* +Y110000D01* +G37* +G36* +X380450D02*X384950D01* +Y104000D01* +X380450D01* +Y110000D01* +G37* +G36* +X385850D02*X390350D01* +Y104000D01* +X385850D01* +Y110000D01* +G37* +G36* +X391250D02*X395750D01* +Y104000D01* +X391250D01* +Y110000D01* +G37* +G36* +X396650D02*X401150D01* +Y104000D01* +X396650D01* +Y110000D01* +G37* +G36* +X404750D02*X409250D01* +Y104000D01* +X404750D01* +Y110000D01* +G37* +G36* +X410150D02*X414650D01* +Y104000D01* +X410150D01* +Y110000D01* +G37* +G36* +X415550D02*X420050D01* +Y104000D01* +X415550D01* +Y110000D01* +G37* +G36* +X420950D02*X425450D01* +Y104000D01* +X420950D01* +Y110000D01* +G37* +G36* +X426350D02*X430850D01* +Y104000D01* +X426350D01* +Y110000D01* +G37* +G36* +X434450D02*X438950D01* +Y104000D01* +X434450D01* +Y110000D01* +G37* +G54D15*X442550D02*Y104000D01* +Y110000D02*X445550D01* +X442550Y107300D02*X444800D01* +G54D16*G36* +X447350Y110000D02*X451850D01* +Y104000D01* +X447350D01* +Y110000D01* +G37* +G36* +X452750D02*X457250D01* +Y104000D01* +X452750D01* +Y110000D01* +G37* +G36* +X458150D02*X462650D01* +Y104000D01* +X458150D01* +Y110000D01* +G37* +G36* +X463550D02*X468050D01* +Y104000D01* +X463550D01* +Y110000D01* +G37* +G36* +X468950D02*X473450D01* +Y104000D01* +X468950D01* +Y110000D01* +G37* +G36* +X474350D02*X478850D01* +Y104000D01* +X474350D01* +Y110000D01* +G37* +G36* +X479750D02*X484250D01* +Y104000D01* +X479750D01* +Y110000D01* +G37* +G36* +X485150D02*X489650D01* +Y104000D01* +X485150D01* +Y110000D01* +G37* +G36* +X490550D02*X495050D01* +Y104000D01* +X490550D01* +Y110000D01* +G37* +G36* +X495950D02*X500450D01* +Y104000D01* +X495950D01* +Y110000D01* +G37* +G54D15*X504800D02*Y104000D01* +X506750Y110000D02*X507800Y108950D01* +Y105050D01* +X506750Y104000D02*X507800Y105050D01* +X504050Y104000D02*X506750D01* +X504050Y110000D02*X506750D01* +G54D16*G36* +X509600D02*X514100D01* +Y104000D01* +X509600D01* +Y110000D01* +G37* +G36* +X515000D02*X519500D01* +Y104000D01* +X515000D01* +Y110000D01* +G37* +G36* +X520400D02*X524900D01* +Y104000D01* +X520400D01* +Y110000D01* +G37* +G36* +X525800D02*X530300D01* +Y104000D01* +X525800D01* +Y110000D01* +G37* +G36* +X531200D02*X535700D01* +Y104000D01* +X531200D01* +Y110000D01* +G37* +G36* +X536600D02*X541100D01* +Y104000D01* +X536600D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_normal.gbr/arc_normal.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.gbr/arc_normal.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.gbr/arc_normal.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,20 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Arcs with different sizes, normal cases, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD13C,0.0300*% +%ADD12C,0.0200*% +%ADD11C,0.0100*% +G54D11*X7500Y27500D02*G75*G03X20000Y15000I12500J0D01*G01* +G54D12*X7652Y29236D02*G75*G02X17500Y37500I9848J-1736D01*G01* +G54D11*X27500Y22500D02*G75*G03X32500Y22500I2500J0D01*G01* +G75*G03X28750Y24665I-2500J0D01*G01* +G54D13*X20725Y39246D02*G75*G02X36746Y31775I4275J-11746D01*G01* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_normal.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/arc_normal.net =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Arcs with different sizes, normal cases +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/arc_normal.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_normal.png =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_normal.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_normal.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.png.text (revision 33253) @@ -0,0 +1,22 @@ +r6630 + +top left arc +25 pixel line width (20.833 mil) +124 pixels tall (103.333 mil) +142 pixesl wide (118.333 mil) + +top right arc +37 pixel line width (30.833 mil) +227 pixels wide (189.166 mil) +135 pixels tall (112.5 mil) + +lower left arc +13 pixel line width (10.833 mil) +162 pixels wide (135 mil) +162 pixels tall + +lower right arc +13 pixel line width (10.833 mil) +72 pixels diameter (60 mil) + + Index: tags/2.3.0/tests/RTT/ref/arc_normal.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_normal.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_normal.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_normal.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_normal.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_normal.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_normal.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.svg (revision 33253) @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/arc_normal.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_normal.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_normal.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Arcs with different sizes, normal cases - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/arc_offpage.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Arcs with some parts off the page - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/arc_offpage.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb Arcs with some parts off the page + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/arc_offpage.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.eps (revision 33253) @@ -0,0 +1,35 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: arc_offpage.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.01000 setlinewidth +1 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.000000 230.000000 -0.10000 0.10000 0.05000 0.05000 0.100000 a +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/arc_offpage.exc/arc_offpage.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.exc/arc_offpage.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.exc/arc_offpage.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/arc_offpage.exc/arc_offpage.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.exc/arc_offpage.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.exc/arc_offpage.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/arc_offpage.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/arc_offpage.gbr/arc_offpage.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.gbr/arc_offpage.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.gbr/arc_offpage.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Arcs with some parts off the page, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_offpage.gbr/arc_offpage.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.gbr/arc_offpage.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.gbr/arc_offpage.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1819 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Arcs with some parts off the page, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D13*X234500Y108500D02*Y104000D01* +Y108500D02*X235550Y110000D01* +X237200D01* +X238250Y108500D01* +Y104000D01* +X234500Y107000D02*X238250D01* +G54D14*G36* +X240050Y110000D02*X244550D01* +Y104000D01* +X240050D01* +Y110000D01* +G37* +G36* +X245450D02*X249950D01* +Y104000D01* +X245450D01* +Y110000D01* +G37* +G36* +X250850D02*X255350D01* +Y104000D01* +X250850D01* +Y110000D01* +G37* +G36* +X258950D02*X263450D01* +Y104000D01* +X258950D01* +Y110000D01* +G37* +G36* +X264350D02*X268850D01* +Y104000D01* +X264350D01* +Y110000D01* +G37* +G36* +X269750D02*X274250D01* +Y104000D01* +X269750D01* +Y110000D01* +G37* +G36* +X275150D02*X279650D01* +Y104000D01* +X275150D01* +Y110000D01* +G37* +G36* +X283250D02*X287750D01* +Y104000D01* +X283250D01* +Y110000D01* +G37* +G36* +X288650D02*X293150D01* +Y104000D01* +X288650D01* +Y110000D01* +G37* +G36* +X294050D02*X298550D01* +Y104000D01* +X294050D01* +Y110000D01* +G37* +G36* +X299450D02*X303950D01* +Y104000D01* +X299450D01* +Y110000D01* +G37* +G36* +X307550D02*X312050D01* +Y104000D01* +X307550D01* +Y110000D01* +G37* +G36* +X312950D02*X317450D01* +Y104000D01* +X312950D01* +Y110000D01* +G37* +G36* +X318350D02*X322850D01* +Y104000D01* +X318350D01* +Y110000D01* +G37* +G36* +X323750D02*X328250D01* +Y104000D01* +X323750D01* +Y110000D01* +G37* +G36* +X329150D02*X333650D01* +Y104000D01* +X329150D01* +Y110000D01* +G37* +G36* +X337250D02*X341750D01* +Y104000D01* +X337250D01* +Y110000D01* +G37* +G36* +X342650D02*X347150D01* +Y104000D01* +X342650D01* +Y110000D01* +G37* +G36* +X348050D02*X352550D01* +Y104000D01* +X348050D01* +Y110000D01* +G37* +G36* +X356150D02*X360650D01* +Y104000D01* +X356150D01* +Y110000D01* +G37* +G36* +X361550D02*X366050D01* +Y104000D01* +X361550D01* +Y110000D01* +G37* +G36* +X366950D02*X371450D01* +Y104000D01* +X366950D01* +Y110000D01* +G37* +G36* +X375050D02*X379550D01* +Y104000D01* +X375050D01* +Y110000D01* +G37* +G36* +X380450D02*X384950D01* +Y104000D01* +X380450D01* +Y110000D01* +G37* +G36* +X385850D02*X390350D01* +Y104000D01* +X385850D01* +Y110000D01* +G37* +G36* +X391250D02*X395750D01* +Y104000D01* +X391250D01* +Y110000D01* +G37* +G36* +X399350D02*X403850D01* +Y104000D01* +X399350D01* +Y110000D01* +G37* +G54D13*X407450D02*Y104000D01* +Y110000D02*X410450D01* +X407450Y107300D02*X409700D01* +G54D14*G36* +X412250Y110000D02*X416750D01* +Y104000D01* +X412250D01* +Y110000D01* +G37* +G36* +X417650D02*X422150D01* +Y104000D01* +X417650D01* +Y110000D01* +G37* +G36* +X423050D02*X427550D01* +Y104000D01* +X423050D01* +Y110000D01* +G37* +G36* +X428450D02*X432950D01* +Y104000D01* +X428450D01* +Y110000D01* +G37* +G36* +X433850D02*X438350D01* +Y104000D01* +X433850D01* +Y110000D01* +G37* +G36* +X439250D02*X443750D01* +Y104000D01* +X439250D01* +Y110000D01* +G37* +G36* +X444650D02*X449150D01* +Y104000D01* +X444650D01* +Y110000D01* +G37* +G36* +X450050D02*X454550D01* +Y104000D01* +X450050D01* +Y110000D01* +G37* +G36* +X455450D02*X459950D01* +Y104000D01* +X455450D01* +Y110000D01* +G37* +G36* +X460850D02*X465350D01* +Y104000D01* +X460850D01* +Y110000D01* +G37* +G54D13*X469700D02*Y104000D01* +X471650Y110000D02*X472700Y108950D01* +Y105050D01* +X471650Y104000D02*X472700Y105050D01* +X468950Y104000D02*X471650D01* +X468950Y110000D02*X471650D01* +G54D14*G36* +X474500D02*X479000D01* +Y104000D01* +X474500D01* +Y110000D01* +G37* +G36* +X479900D02*X484400D01* +Y104000D01* +X479900D01* +Y110000D01* +G37* +G36* +X485300D02*X489800D01* +Y104000D01* +X485300D01* +Y110000D01* +G37* +G36* +X490700D02*X495200D01* +Y104000D01* +X490700D01* +Y110000D01* +G37* +G36* +X496100D02*X500600D01* +Y104000D01* +X496100D01* +Y110000D01* +G37* +G36* +X501500D02*X506000D01* +Y104000D01* +X501500D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_offpage.gbr/arc_offpage.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.gbr/arc_offpage.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.gbr/arc_offpage.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,15 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Arcs with some parts off the page, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0100*% +G54D11*X-5000Y45000D02*G75*G03X15000Y45000I10000J0D01*G01* +Y45000D02*G75*G03X11428Y52660I-10000J0D01*G01* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_offpage.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/arc_offpage.net =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Arcs with some parts off the page +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/arc_offpage.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_offpage.png =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_offpage.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_offpage.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.png.text (revision 33253) @@ -0,0 +1,10 @@ +r6630 + +arc +13 pixel line width (10.833 mil) +180 pixels wide [measured from inside corner] (15.000 mil) +186 pixels tall (154.167 mil) +179 pixels wide [measured from inside corner] (14.917 mil) +186 pixels wide (154.167 mil) + + Index: tags/2.3.0/tests/RTT/ref/arc_offpage.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_offpage.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_offpage.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_offpage.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_offpage.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_offpage.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_offpage.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.svg (revision 33253) @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/arc_offpage.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_offpage.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_offpage.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Arcs with some parts off the page - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/arc_sizes.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: arcs with different strange sizes - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/arc_sizes.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb arcs with different strange sizes + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/arc_sizes.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.eps (revision 33253) @@ -0,0 +1,37 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: arc_sizes.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.01000 setlinewidth +1 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.000000 90.000000 0.00000 0.05000 0.10000 0.20000 2540000000.000000 a +0.000000 90.000000 -0.05000 0.00000 0.20000 0.20000 0.200000 a +0.30000 0.20000 0.00500 c +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/arc_sizes.exc/arc_sizes.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.exc/arc_sizes.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.exc/arc_sizes.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/arc_sizes.exc/arc_sizes.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.exc/arc_sizes.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.exc/arc_sizes.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/arc_sizes.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/arc_sizes.gbr/arc_sizes.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.gbr/arc_sizes.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.gbr/arc_sizes.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: arcs with different strange sizes, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_sizes.gbr/arc_sizes.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.gbr/arc_sizes.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.gbr/arc_sizes.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1831 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: arcs with different strange sizes, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X258800D02*X263300D01* +Y104000D01* +X258800D01* +Y110000D01* +G37* +G36* +X264200D02*X268700D01* +Y104000D01* +X264200D01* +Y110000D01* +G37* +G36* +X269600D02*X274100D01* +Y104000D01* +X269600D01* +Y110000D01* +G37* +G36* +X275000D02*X279500D01* +Y104000D01* +X275000D01* +Y110000D01* +G37* +G36* +X283100D02*X287600D01* +Y104000D01* +X283100D01* +Y110000D01* +G37* +G36* +X288500D02*X293000D01* +Y104000D01* +X288500D01* +Y110000D01* +G37* +G36* +X293900D02*X298400D01* +Y104000D01* +X293900D01* +Y110000D01* +G37* +G36* +X299300D02*X303800D01* +Y104000D01* +X299300D01* +Y110000D01* +G37* +G36* +X304700D02*X309200D01* +Y104000D01* +X304700D01* +Y110000D01* +G37* +G36* +X310100D02*X314600D01* +Y104000D01* +X310100D01* +Y110000D01* +G37* +G36* +X315500D02*X320000D01* +Y104000D01* +X315500D01* +Y110000D01* +G37* +G36* +X320900D02*X325400D01* +Y104000D01* +X320900D01* +Y110000D01* +G37* +G36* +X326300D02*X330800D01* +Y104000D01* +X326300D01* +Y110000D01* +G37* +G36* +X334400D02*X338900D01* +Y104000D01* +X334400D01* +Y110000D01* +G37* +G36* +X339800D02*X344300D01* +Y104000D01* +X339800D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X356000D02*X360500D01* +Y104000D01* +X356000D01* +Y110000D01* +G37* +G36* +X361400D02*X365900D01* +Y104000D01* +X361400D01* +Y110000D01* +G37* +G36* +X366800D02*X371300D01* +Y104000D01* +X366800D01* +Y110000D01* +G37* +G36* +X374900D02*X379400D01* +Y104000D01* +X374900D01* +Y110000D01* +G37* +G36* +X380300D02*X384800D01* +Y104000D01* +X380300D01* +Y110000D01* +G37* +G36* +X385700D02*X390200D01* +Y104000D01* +X385700D01* +Y110000D01* +G37* +G36* +X391100D02*X395600D01* +Y104000D01* +X391100D01* +Y110000D01* +G37* +G36* +X396500D02*X401000D01* +Y104000D01* +X396500D01* +Y110000D01* +G37* +G36* +X404600D02*X409100D01* +Y104000D01* +X404600D01* +Y110000D01* +G37* +G54D13*X412700D02*Y104000D01* +Y110000D02*X415700D01* +X412700Y107300D02*X414950D01* +G54D14*G36* +X417500Y110000D02*X422000D01* +Y104000D01* +X417500D01* +Y110000D01* +G37* +G36* +X422900D02*X427400D01* +Y104000D01* +X422900D01* +Y110000D01* +G37* +G36* +X428300D02*X432800D01* +Y104000D01* +X428300D01* +Y110000D01* +G37* +G36* +X433700D02*X438200D01* +Y104000D01* +X433700D01* +Y110000D01* +G37* +G36* +X439100D02*X443600D01* +Y104000D01* +X439100D01* +Y110000D01* +G37* +G36* +X444500D02*X449000D01* +Y104000D01* +X444500D01* +Y110000D01* +G37* +G36* +X449900D02*X454400D01* +Y104000D01* +X449900D01* +Y110000D01* +G37* +G36* +X455300D02*X459800D01* +Y104000D01* +X455300D01* +Y110000D01* +G37* +G36* +X460700D02*X465200D01* +Y104000D01* +X460700D01* +Y110000D01* +G37* +G36* +X466100D02*X470600D01* +Y104000D01* +X466100D01* +Y110000D01* +G37* +G54D13*X474950D02*Y104000D01* +X476900Y110000D02*X477950Y108950D01* +Y105050D01* +X476900Y104000D02*X477950Y105050D01* +X474200Y104000D02*X476900D01* +X474200Y110000D02*X476900D01* +G54D14*G36* +X479750D02*X484250D01* +Y104000D01* +X479750D01* +Y110000D01* +G37* +G36* +X485150D02*X489650D01* +Y104000D01* +X485150D01* +Y110000D01* +G37* +G36* +X490550D02*X495050D01* +Y104000D01* +X490550D01* +Y110000D01* +G37* +G36* +X495950D02*X500450D01* +Y104000D01* +X495950D01* +Y110000D01* +G37* +G36* +X501350D02*X505850D01* +Y104000D01* +X501350D01* +Y110000D01* +G37* +G36* +X506750D02*X511250D01* +Y104000D01* +X506750D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_sizes.gbr/arc_sizes.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.gbr/arc_sizes.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.gbr/arc_sizes.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,52 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: arcs with different strange sizes, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0100*% +G54D11*X10000Y30000D02*Y29587D01* +Y29177D01* +Y28773D01* +Y28377D01* +Y27992D01* +Y27620D01* +Y27265D01* +Y26929D01* +Y26614D01* +Y26321D01* +Y26054D01* +Y25814D01* +Y25603D01* +Y25421D01* +Y25271D01* +Y25153D01* +Y25068D01* +Y25017D01* +Y25000D01* +X15000Y30000D02*X15017D01* +X15068D01* +X15153D01* +X15271D01* +X15421D01* +X15603D01* +X15814D01* +X16054D01* +X16321D01* +X16614D01* +X16929D01* +X17265D01* +X17620D01* +X17992D01* +X18376D01* +X18773D01* +X19177D01* +X19587D01* +X20000D01* +X30000D02*G75*G03X30000Y30000I0J0D01*G01* +M02* Index: tags/2.3.0/tests/RTT/ref/arc_sizes.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/arc_sizes.net =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB arcs with different strange sizes +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/arc_sizes.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_sizes.png =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_sizes.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_sizes.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.png.text (revision 33253) @@ -0,0 +1,18 @@ +r6630 + +weird dot thing in the far right +12 pixels across (10) +12 pixels tall (10) + +weird dot to line (horizontal) 108 pixels + +horizontal line +72 pixels long (60) +12 pixels wide (10) + +vertical line +72 pixels long (60) +12 pixels wide (12) + +(mils) + Index: tags/2.3.0/tests/RTT/ref/arc_sizes.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_sizes.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_sizes.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_sizes.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/arc_sizes.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/arc_sizes.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/arc_sizes.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.svg (revision 33253) @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/arc_sizes.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/arc_sizes.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/arc_sizes.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: arcs with different strange sizes - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/comp1.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: (unknown) - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/comp1.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.dsn (revision 33253) @@ -0,0 +1,57 @@ +(pcb notnamed + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 31 + (place 31 6.350000 10.795000 front 0 (PN 0)) + ) + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 0.508000 0.635000 8.890000 12.065000 8.890000) + (type protect)) + (wire (path 10__bottom_copper 0.508000 0.635000 9.525000 12.065000 9.525000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/comp1.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.eps (revision 33253) @@ -0,0 +1,93 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: comp1.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.02000 setlinewidth +1 setlinecap +0.227451 0.372549 0.803922 setrgbcolor +0.02500 0.12500 0.47500 0.12500 t +0.627451 0.627451 0.627451 setrgbcolor +0.25000 0.07500 0.04331 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.25000 0.07500 0.01968 c +% Layer group5 group 5 drill 0 mask 0 +0.00000 setlinewidth +0.627451 0.627451 0.627451 setrgbcolor +0.25000 0.07500 0.04331 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.25000 0.07500 0.01968 c +% Layer group7 group 7 drill 0 mask 0 +0.00000 setlinewidth +0.627451 0.627451 0.627451 setrgbcolor +0.25000 0.07500 0.04331 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.25000 0.07500 0.01968 c +% Layer top group 3 drill 0 mask 0 +0.02000 setlinewidth +0.545098 0.137255 0.137255 setrgbcolor +0.02500 0.15000 0.47500 0.15000 t +0.439216 0.439216 0.439216 setrgbcolor +0.25000 0.07500 0.04331 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.25000 0.07500 0.01968 c +% Layer topsilk group 1 drill 0 mask 0 +gsave +0 0 0 setrgbcolor +0.17500 0.02500 moveto +0.17500 0.17500 lineto +0.02500 0.17500 lineto +0.02500 0.02500 lineto +fill +0.47500 0.02500 moveto +0.47500 0.47500 lineto +0.20000 0.47500 lineto +0.20000 0.02500 lineto +fill +1 1 1 setrgbcolor +0.45000 0.05000 moveto +0.45000 0.45000 lineto +0.22500 0.45000 lineto +0.22500 0.05000 lineto +fill +0.08000 setlinewidth +0.06000 0.25000 moveto 0.10000 0.12500 0.04000 -180 0 arc +0.10000 0.25000 0.04000 0 180 arc +nclip +0.02000 setlinewidth +90.000000 180.000000 -0.07500 0.07500 0.00000 0.00000 0.266667 a +0 0 0 setrgbcolor +0.10000 0.22500 0.10000 0.12500 t +grestore +gsave +% Layer plated-drill group -1 drill 1 mask 0 +0.00000 setlinewidth +1 1 1 setrgbcolor +0.25000 0.07500 0.01968 c +grestore +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/comp1.exc/comp1.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.exc/comp1.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.exc/comp1.plated.cnc (revision 33253) @@ -0,0 +1,8 @@ +M48 +INCH +T11C0.039 +% +T11 +G05 +X002500Y004250 +M30 Index: tags/2.3.0/tests/RTT/ref/comp1.exc/comp1.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.exc/comp1.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.exc/comp1.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/comp1.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.fcd (revision 33253) @@ -0,0 +1,9 @@ +[FIDOCAD] +PL 5 30 95 30 4 2 +PL 5 25 95 25 4 1 +PP 5 5 35 5 35 35 5 35 5 5 3 +PP 40 5 95 5 95 95 40 95 40 5 3 +PL 20 50 20 25 16 3 +PP 45 10 90 10 90 90 45 90 45 10 3 +PL 20 45 20 25 4 3 +pa 50 1517 17 8 0 Index: tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 5 for group 10 layer_idx 1 * +G04 Title: (unknown), bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD20C,0.0394*% +%ADD19C,0.0866*% +%ADD18C,0.0200*% +G54D18*X2500Y37500D02*X47500D01* +G54D19*X25000Y42500D03* +G54D20*M02* Index: tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.global.virtual.pdrill.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.global.virtual.pdrill.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.global.virtual.pdrill.none.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 7 for group -1 layer_idx 268435462 * +G04 Title: (unknown), * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_VIRTUAL_PDRILL_NONE*% +%ADD24C,0.0394*% +G54D24*X25000Y42500D03* +M02* Index: tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.intern.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.intern.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.intern.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 8 for group 9 layer_idx 6 * +G04 Title: (unknown), global outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_BOUNDARY_UROUTE_9*% +%ADD25C,0.0100*% +G54D25*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.intern.copper.none.5.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.intern.copper.none.5.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.intern.copper.none.5.gbr (revision 33253) @@ -0,0 +1,15 @@ +G04 start of page 3 for group 5 layer_idx 4 * +G04 Title: (unknown), Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_5*% +%ADD15C,0.0394*% +%ADD14C,0.0866*% +G54D14*X25000Y42500D03* +G54D15*M02* Index: tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.intern.copper.none.7.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.intern.copper.none.7.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.intern.copper.none.7.gbr (revision 33253) @@ -0,0 +1,15 @@ +G04 start of page 4 for group 7 layer_idx 5 * +G04 Title: (unknown), Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_7*% +%ADD17C,0.0394*% +%ADD16C,0.0866*% +G54D16*X25000Y42500D03* +G54D17*M02* Index: tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1770 @@ +G04 start of page 9 for group -1 layer_idx 268435461 * +G04 Title: (unknown), * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD29C,0.0100*% +%ADD28C,0.0001*% +%ADD27C,0.0060*% +%ADD26C,0.0080*% +G54D26*X25000Y42500D02*Y40900D01* +Y42500D02*X26387Y43300D01* +X25000Y42500D02*X23613Y43300D01* +X15000Y106250D02*Y104650D01* +Y106250D02*X16387Y107050D01* +X15000Y106250D02*X13613Y107050D01* +G54D27*X135000Y110000D02*X136500Y107000D01* +X138000Y110000D01* +X136500Y107000D02*Y104000D01* +X139800Y107300D02*X142050D01* +X139800Y104000D02*X142800D01* +X139800Y110000D02*Y104000D01* +Y110000D02*X142800D01* +X147600D02*X148350Y109250D01* +X145350Y110000D02*X147600D01* +X144600Y109250D02*X145350Y110000D01* +X144600Y109250D02*Y107750D01* +X145350Y107000D01* +X147600D01* +X148350Y106250D01* +Y104750D01* +X147600Y104000D02*X148350Y104750D01* +X145350Y104000D02*X147600D01* +X144600Y104750D02*X145350Y104000D01* +X98000Y108800D02*X99200Y110000D01* +Y104000D01* +X98000D02*X100250D01* +G54D28*G36* +X45000Y110000D02*X49500D01* +Y104000D01* +X45000D01* +Y110000D01* +G37* +G36* +X50400D02*X54900D01* +Y104000D01* +X50400D01* +Y110000D01* +G37* +G36* +X55800D02*X60300D01* +Y104000D01* +X55800D01* +Y110000D01* +G37* +G54D27*X61200Y109250D02*X61950Y110000D01* +X63450D01* +X64200Y109250D01* +X63450Y104000D02*X64200Y104750D01* +X61950Y104000D02*X63450D01* +X61200Y104750D02*X61950Y104000D01* +Y107300D02*X63450D01* +X64200Y109250D02*Y108050D01* +Y106550D02*Y104750D01* +Y106550D02*X63450Y107300D01* +X64200Y108050D02*X63450Y107300D01* +X66750Y104000D02*X69000Y107000D01* +Y109250D02*Y107000D01* +X68250Y110000D02*X69000Y109250D01* +X66750Y110000D02*X68250D01* +X66000Y109250D02*X66750Y110000D01* +X66000Y109250D02*Y107750D01* +X66750Y107000D01* +X69000D01* +X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D28*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D27*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D28*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D27*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D28*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D27*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D28*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D27*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D28*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D27*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D28*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G54D27*X48000Y138800D02*X49200Y140000D01* +Y134000D01* +X48000D02*X50250D01* +G54D28*G36* +X54750Y140000D02*X59250D01* +Y134000D01* +X54750D01* +Y140000D01* +G37* +G36* +X60150D02*X64650D01* +Y134000D01* +X60150D01* +Y140000D01* +G37* +G36* +X65550D02*X70050D01* +Y134000D01* +X65550D01* +Y140000D01* +G37* +G36* +X70950D02*X75450D01* +Y134000D01* +X70950D01* +Y140000D01* +G37* +G36* +X76350D02*X80850D01* +Y134000D01* +X76350D01* +Y140000D01* +G37* +G36* +X81750D02*X86250D01* +Y134000D01* +X81750D01* +Y140000D01* +G37* +G36* +X87150D02*X91650D01* +Y134000D01* +X87150D01* +Y140000D01* +G37* +G36* +X92550D02*X97050D01* +Y134000D01* +X92550D01* +Y140000D01* +G37* +G36* +X97950D02*X102450D01* +Y134000D01* +X97950D01* +Y140000D01* +G37* +G36* +X106050D02*X110550D01* +Y134000D01* +X106050D01* +Y140000D01* +G37* +G36* +X111450D02*X115950D01* +Y134000D01* +X111450D01* +Y140000D01* +G37* +G36* +X116850D02*X121350D01* +Y134000D01* +X116850D01* +Y140000D01* +G37* +G36* +X122250D02*X126750D01* +Y134000D01* +X122250D01* +Y140000D01* +G37* +G36* +X127650D02*X132150D01* +Y134000D01* +X127650D01* +Y140000D01* +G37* +G36* +X135750D02*X140250D01* +Y134000D01* +X135750D01* +Y140000D01* +G37* +G36* +X141150D02*X145650D01* +Y134000D01* +X141150D01* +Y140000D01* +G37* +G36* +X146550D02*X151050D01* +Y134000D01* +X146550D01* +Y140000D01* +G37* +G36* +X151950D02*X156450D01* +Y134000D01* +X151950D01* +Y140000D01* +G37* +G36* +X157350D02*X161850D01* +Y134000D01* +X157350D01* +Y140000D01* +G37* +G36* +X165450D02*X169950D01* +Y134000D01* +X165450D01* +Y140000D01* +G37* +G36* +X170850D02*X175350D01* +Y134000D01* +X170850D01* +Y140000D01* +G37* +G36* +X176250D02*X180750D01* +Y134000D01* +X176250D01* +Y140000D01* +G37* +G36* +X181650D02*X186150D01* +Y134000D01* +X181650D01* +Y140000D01* +G37* +G36* +X189750D02*X194250D01* +Y134000D01* +X189750D01* +Y140000D01* +G37* +G36* +X195150D02*X199650D01* +Y134000D01* +X195150D01* +Y140000D01* +G37* +G36* +X203250D02*X207750D01* +Y134000D01* +X203250D01* +Y140000D01* +G37* +G36* +X208650D02*X213150D01* +Y134000D01* +X208650D01* +Y140000D01* +G37* +G36* +X214050D02*X218550D01* +Y134000D01* +X214050D01* +Y140000D01* +G37* +G36* +X219450D02*X223950D01* +Y134000D01* +X219450D01* +Y140000D01* +G37* +G36* +X227550D02*X232050D01* +Y134000D01* +X227550D01* +Y140000D01* +G37* +G36* +X232950D02*X237450D01* +Y134000D01* +X232950D01* +Y140000D01* +G37* +G36* +X238350D02*X242850D01* +Y134000D01* +X238350D01* +Y140000D01* +G37* +G36* +X243750D02*X248250D01* +Y134000D01* +X243750D01* +Y140000D01* +G37* +G36* +X249150D02*X253650D01* +Y134000D01* +X249150D01* +Y140000D01* +G37* +G36* +X254550D02*X259050D01* +Y134000D01* +X254550D01* +Y140000D01* +G37* +G36* +X259950D02*X264450D01* +Y134000D01* +X259950D01* +Y140000D01* +G37* +G54D27*X268050Y138800D02*X269250Y140000D01* +Y134000D01* +X268050D02*X270300D01* +G54D28*G36* +X274800Y140000D02*X279300D01* +Y134000D01* +X274800D01* +Y140000D01* +G37* +G36* +X280200D02*X284700D01* +Y134000D01* +X280200D01* +Y140000D01* +G37* +G36* +X285600D02*X290100D01* +Y134000D01* +X285600D01* +Y140000D01* +G37* +G36* +X291000D02*X295500D01* +Y134000D01* +X291000D01* +Y140000D01* +G37* +G36* +X296400D02*X300900D01* +Y134000D01* +X296400D01* +Y140000D01* +G37* +G36* +X304500D02*X309000D01* +Y134000D01* +X304500D01* +Y140000D01* +G37* +G36* +X309900D02*X314400D01* +Y134000D01* +X309900D01* +Y140000D01* +G37* +G36* +X315300D02*X319800D01* +Y134000D01* +X315300D01* +Y140000D01* +G37* +G36* +X320700D02*X325200D01* +Y134000D01* +X320700D01* +Y140000D01* +G37* +G36* +X326100D02*X330600D01* +Y134000D01* +X326100D01* +Y140000D01* +G37* +G54D29*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D27*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D28*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D27*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D28*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D27*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D28*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D27*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D28*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D27*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D28*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D27*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D28*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D27*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D28*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D27*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D28*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D27*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D28*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D27*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D28*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D27*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D28*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X256100D02*X260600D01* +Y104000D01* +X256100D01* +Y110000D01* +G37* +G36* +X261500D02*X266000D01* +Y104000D01* +X261500D01* +Y110000D01* +G37* +G36* +X266900D02*X271400D01* +Y104000D01* +X266900D01* +Y110000D01* +G37* +G36* +X272300D02*X276800D01* +Y104000D01* +X272300D01* +Y110000D01* +G37* +G36* +X277700D02*X282200D01* +Y104000D01* +X277700D01* +Y110000D01* +G37* +G36* +X285800D02*X290300D01* +Y104000D01* +X285800D01* +Y110000D01* +G37* +G54D27*X293900D02*Y104000D01* +Y110000D02*X296900D01* +X293900Y107300D02*X296150D01* +G54D28*G36* +X298700Y110000D02*X303200D01* +Y104000D01* +X298700D01* +Y110000D01* +G37* +G36* +X304100D02*X308600D01* +Y104000D01* +X304100D01* +Y110000D01* +G37* +G36* +X309500D02*X314000D01* +Y104000D01* +X309500D01* +Y110000D01* +G37* +G36* +X314900D02*X319400D01* +Y104000D01* +X314900D01* +Y110000D01* +G37* +G36* +X320300D02*X324800D01* +Y104000D01* +X320300D01* +Y110000D01* +G37* +G36* +X325700D02*X330200D01* +Y104000D01* +X325700D01* +Y110000D01* +G37* +G36* +X331100D02*X335600D01* +Y104000D01* +X331100D01* +Y110000D01* +G37* +G36* +X336500D02*X341000D01* +Y104000D01* +X336500D01* +Y110000D01* +G37* +G36* +X341900D02*X346400D01* +Y104000D01* +X341900D01* +Y110000D01* +G37* +G36* +X347300D02*X351800D01* +Y104000D01* +X347300D01* +Y110000D01* +G37* +G54D27*X356150D02*Y104000D01* +X358100Y110000D02*X359150Y108950D01* +Y105050D01* +X358100Y104000D02*X359150Y105050D01* +X355400Y104000D02*X358100D01* +X355400Y110000D02*X358100D01* +G54D28*G36* +X360950D02*X365450D01* +Y104000D01* +X360950D01* +Y110000D01* +G37* +G36* +X366350D02*X370850D01* +Y104000D01* +X366350D01* +Y110000D01* +G37* +G36* +X371750D02*X376250D01* +Y104000D01* +X371750D01* +Y110000D01* +G37* +G36* +X377150D02*X381650D01* +Y104000D01* +X377150D01* +Y110000D01* +G37* +G36* +X382550D02*X387050D01* +Y104000D01* +X382550D01* +Y110000D01* +G37* +G36* +X387950D02*X392450D01* +Y104000D01* +X387950D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: (unknown), top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD13C,0.0394*% +%ADD12C,0.0866*% +%ADD11C,0.0200*% +G54D11*X2500Y35000D02*X47500D01* +G54D12*X25000Y42500D03* +G54D13*M02* Index: tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.gbr/comp1.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,38 @@ +G04 start of page 6 for group 1 layer_idx 8 * +G04 Title: (unknown), top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD23C,0.0200*% +%ADD22C,0.0800*% +%ADD21C,0.0001*% +G54D21*G36* +X17500Y47500D02*Y32500D01* +X2500D01* +Y47500D01* +X17500D01* +G37* +G36* +X47500D02*Y2500D01* +X20000D01* +Y47500D01* +X47500D01* +G37* +%LPC*% +G36* +X45000Y45000D02*Y5000D01* +X22500D01* +Y45000D01* +X45000D01* +G37* +G54D22*X10000Y25000D02*Y37500D01* +G54D23*X0Y42500D02*G75*G03X7500Y50000I0J7500D01*G01* +%LPD*% +X10000Y27500D02*Y37500D01* +M02* Index: tags/2.3.0/tests/RTT/ref/comp1.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.nelma.em (revision 33253) @@ -0,0 +1,75 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} +layer substrate-11 { + height = 20 + z-order = 11 + material = "composite" +} +layer bottom { + height = 1 + z-order = 12 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top", + "substrate-11", + "bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/comp1.net =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.net (revision 33253) @@ -0,0 +1,13 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB comp1.pcb +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +317N/C VIA - D0393PA00X+002500Y+004250X0866Y0000R000 S3 +999 Index: tags/2.3.0/tests/RTT/ref/comp1.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/comp1.png =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/comp1.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/comp1.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/comp1.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/comp1.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/comp1.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.svg (revision 33253) @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/comp1.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/comp1.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/comp1.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: (unknown) - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/coord_rounding.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: odd coordinates to check rounding errors - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/coord_rounding.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.dsn (revision 33253) @@ -0,0 +1,54 @@ +(pcb odd coordinates to check rounding errors + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 1.000000 6.000000 6.600000 6.110000 6.589000) + (type protect)) + (wire (path 3__top_copper 1.000000 6.111100 6.588890 6.111111 6.589000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/coord_rounding.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.eps (revision 33253) @@ -0,0 +1,36 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: coord_rounding.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.03937 setlinewidth +1 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.23622 0.24016 0.24055 0.24059 t +0.24059 0.24059 0.24059 0.24059 t +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/coord_rounding.exc/coord_rounding.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.exc/coord_rounding.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.exc/coord_rounding.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/coord_rounding.exc/coord_rounding.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.exc/coord_rounding.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.exc/coord_rounding.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/coord_rounding.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.fcd (revision 33253) @@ -0,0 +1,3 @@ +[FIDOCAD] +PL 47 48 48 48 8 2 +PL 48 48 48 48 8 2 Index: tags/2.3.0/tests/RTT/ref/coord_rounding.gbr/coord_rounding.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.gbr/coord_rounding.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.gbr/coord_rounding.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: odd coordinates to check rounding errors, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/coord_rounding.gbr/coord_rounding.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.gbr/coord_rounding.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.gbr/coord_rounding.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1867 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: odd coordinates to check rounding errors, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X253400D02*X257900D01* +Y104000D01* +X253400D01* +Y110000D01* +G37* +G36* +X258800D02*X263300D01* +Y104000D01* +X258800D01* +Y110000D01* +G37* +G36* +X264200D02*X268700D01* +Y104000D01* +X264200D01* +Y110000D01* +G37* +G36* +X269600D02*X274100D01* +Y104000D01* +X269600D01* +Y110000D01* +G37* +G36* +X275000D02*X279500D01* +Y104000D01* +X275000D01* +Y110000D01* +G37* +G36* +X280400D02*X284900D01* +Y104000D01* +X280400D01* +Y110000D01* +G37* +G36* +X285800D02*X290300D01* +Y104000D01* +X285800D01* +Y110000D01* +G37* +G36* +X291200D02*X295700D01* +Y104000D01* +X291200D01* +Y110000D01* +G37* +G36* +X296600D02*X301100D01* +Y104000D01* +X296600D01* +Y110000D01* +G37* +G36* +X302000D02*X306500D01* +Y104000D01* +X302000D01* +Y110000D01* +G37* +G36* +X307400D02*X311900D01* +Y104000D01* +X307400D01* +Y110000D01* +G37* +G36* +X315500D02*X320000D01* +Y104000D01* +X315500D01* +Y110000D01* +G37* +G36* +X320900D02*X325400D01* +Y104000D01* +X320900D01* +Y110000D01* +G37* +G36* +X329000D02*X333500D01* +Y104000D01* +X329000D01* +Y110000D01* +G37* +G36* +X334400D02*X338900D01* +Y104000D01* +X334400D01* +Y110000D01* +G37* +G36* +X339800D02*X344300D01* +Y104000D01* +X339800D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X358700D02*X363200D01* +Y104000D01* +X358700D01* +Y110000D01* +G37* +G36* +X364100D02*X368600D01* +Y104000D01* +X364100D01* +Y110000D01* +G37* +G36* +X369500D02*X374000D01* +Y104000D01* +X369500D01* +Y110000D01* +G37* +G36* +X374900D02*X379400D01* +Y104000D01* +X374900D01* +Y110000D01* +G37* +G36* +X380300D02*X384800D01* +Y104000D01* +X380300D01* +Y110000D01* +G37* +G36* +X385700D02*X390200D01* +Y104000D01* +X385700D01* +Y110000D01* +G37* +G36* +X391100D02*X395600D01* +Y104000D01* +X391100D01* +Y110000D01* +G37* +G36* +X396500D02*X401000D01* +Y104000D01* +X396500D01* +Y110000D01* +G37* +G36* +X404600D02*X409100D01* +Y104000D01* +X404600D01* +Y110000D01* +G37* +G36* +X410000D02*X414500D01* +Y104000D01* +X410000D01* +Y110000D01* +G37* +G36* +X415400D02*X419900D01* +Y104000D01* +X415400D01* +Y110000D01* +G37* +G36* +X420800D02*X425300D01* +Y104000D01* +X420800D01* +Y110000D01* +G37* +G36* +X426200D02*X430700D01* +Y104000D01* +X426200D01* +Y110000D01* +G37* +G36* +X431600D02*X436100D01* +Y104000D01* +X431600D01* +Y110000D01* +G37* +G36* +X439700D02*X444200D01* +Y104000D01* +X439700D01* +Y110000D01* +G37* +G54D13*X447800D02*Y104000D01* +Y110000D02*X450800D01* +X447800Y107300D02*X450050D01* +G54D14*G36* +X452600Y110000D02*X457100D01* +Y104000D01* +X452600D01* +Y110000D01* +G37* +G36* +X458000D02*X462500D01* +Y104000D01* +X458000D01* +Y110000D01* +G37* +G36* +X463400D02*X467900D01* +Y104000D01* +X463400D01* +Y110000D01* +G37* +G36* +X468800D02*X473300D01* +Y104000D01* +X468800D01* +Y110000D01* +G37* +G36* +X474200D02*X478700D01* +Y104000D01* +X474200D01* +Y110000D01* +G37* +G36* +X479600D02*X484100D01* +Y104000D01* +X479600D01* +Y110000D01* +G37* +G36* +X485000D02*X489500D01* +Y104000D01* +X485000D01* +Y110000D01* +G37* +G36* +X490400D02*X494900D01* +Y104000D01* +X490400D01* +Y110000D01* +G37* +G36* +X495800D02*X500300D01* +Y104000D01* +X495800D01* +Y110000D01* +G37* +G36* +X501200D02*X505700D01* +Y104000D01* +X501200D01* +Y110000D01* +G37* +G54D13*X510050D02*Y104000D01* +X512000Y110000D02*X513050Y108950D01* +Y105050D01* +X512000Y104000D02*X513050Y105050D01* +X509300Y104000D02*X512000D01* +X509300Y110000D02*X512000D01* +G54D14*G36* +X514850D02*X519350D01* +Y104000D01* +X514850D01* +Y110000D01* +G37* +G36* +X520250D02*X524750D01* +Y104000D01* +X520250D01* +Y110000D01* +G37* +G36* +X525650D02*X530150D01* +Y104000D01* +X525650D01* +Y110000D01* +G37* +G36* +X531050D02*X535550D01* +Y104000D01* +X531050D01* +Y110000D01* +G37* +G36* +X536450D02*X540950D01* +Y104000D01* +X536450D01* +Y110000D01* +G37* +G36* +X541850D02*X546350D01* +Y104000D01* +X541850D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/coord_rounding.gbr/coord_rounding.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.gbr/coord_rounding.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.gbr/coord_rounding.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,15 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: odd coordinates to check rounding errors, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0394*% +G54D11*X23622Y25984D02*X24055Y25941D01* +X24059Y25941D02*X24059Y25941D01* +M02* Index: tags/2.3.0/tests/RTT/ref/coord_rounding.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/coord_rounding.net =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB odd coordinates to check rounding errors +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/coord_rounding.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/coord_rounding.png =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/coord_rounding.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/coord_rounding.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.png.text (revision 33253) @@ -0,0 +1,6 @@ +r6630 + +weird dot thing +48 pixels (40) tall +53 pixels (44.167) wide + Index: tags/2.3.0/tests/RTT/ref/coord_rounding.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/coord_rounding.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/coord_rounding.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/coord_rounding.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/coord_rounding.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/coord_rounding.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/coord_rounding.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.svg (revision 33253) @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/coord_rounding.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/coord_rounding.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/coord_rounding.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: odd coordinates to check rounding errors - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/elem_pads.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.bom (revision 33253) @@ -0,0 +1,9 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: pads with different geometry - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +1,"Standard SMT resistor, capacitor etc","1206",R1 +1,"SMT transistor, 5 pins","SOT325",U1 Index: tags/2.3.0/tests/RTT/ref/elem_pads.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.dsn (revision 33253) @@ -0,0 +1,130 @@ +(pcb pads with different geometry + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 5 + (place "R1" 6.350000 10.160000 front 0 (PN 0)) + ) + (component 27 + (place "U1" 5.689600 3.175000 front 0 (PN 0)) + ) + ) + (library + (image 5 + (pin Pstk_shape_7 "1" -1.499870 0.000000) + (pin Pstk_shape_8 "2" 1.499870 0.000000) + ) + (image 27 + (pin Pstk_shape_29 "1" 0.000000 0.000000) + (pin Pstk_shape_30 "2" 1.295400 0.000000) + (pin Pstk_shape_31 "3" 1.295400 1.778000) + (pin Pstk_shape_32 "4" 0.660400 1.778000) + (pin Pstk_shape_33 "5" 0.000000 1.778000) + ) + (padstack Pstk_shape_7 + (shape + (polygon "3__top_copper" 0 + 0.649986 0.949960 -0.649986 0.949960 -0.649986 -0.949960 + 0.649986 -0.949960 + ) + ) + (attach off) + ) + (padstack Pstk_shape_8 + (shape + (polygon "3__top_copper" 0 + 0.649986 0.949960 -0.649986 0.949960 -0.649986 -0.949960 + 0.649986 -0.949960 + ) + ) + (attach off) + ) + (padstack Pstk_shape_29 + (shape + (polygon "3__top_copper" 0 + 0.190500 0.444500 -0.190500 0.444500 -0.190500 -0.444500 + 0.190500 -0.444500 + ) + ) + (attach off) + ) + (padstack Pstk_shape_30 + (shape + (polygon "3__top_copper" 0 + 0.190500 0.444500 -0.190500 0.444500 -0.190500 -0.444500 + 0.190500 -0.444500 + ) + ) + (attach off) + ) + (padstack Pstk_shape_31 + (shape + (polygon "3__top_copper" 0 + 0.190500 0.444500 -0.190500 0.444500 -0.190500 -0.444500 + 0.190500 -0.444500 + ) + ) + (attach off) + ) + (padstack Pstk_shape_32 + (shape + (polygon "3__top_copper" 0 + 0.190500 0.444500 -0.190500 0.444500 -0.190500 -0.444500 + 0.190500 -0.444500 + ) + ) + (attach off) + ) + (padstack Pstk_shape_33 + (shape + (polygon "3__top_copper" 0 + 0.190500 0.444500 -0.190500 0.444500 -0.190500 -0.444500 + 0.190500 -0.444500 + ) + ) + (attach off) + ) + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/elem_pads.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.eps (revision 33253) @@ -0,0 +1,97 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: elem_pads.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +1 setlinecap +0.25098 0.25098 0.25098 setrgbcolor +0.21654 0.06260 moveto +0.16536 0.06260 lineto +0.16536 0.13740 lineto +0.21654 0.13740 lineto +fill +0.33464 0.06260 moveto +0.28346 0.06260 lineto +0.28346 0.13740 lineto +0.33464 0.13740 lineto +fill +0.25750 0.28750 moveto +0.24250 0.28750 lineto +0.24250 0.32250 lineto +0.25750 0.32250 lineto +fill +0.23150 0.35750 moveto +0.21650 0.35750 lineto +0.21650 0.39250 lineto +0.23150 0.39250 lineto +fill +0.28250 0.35750 moveto +0.26750 0.35750 lineto +0.26750 0.39250 lineto +0.28250 0.39250 lineto +fill +0.28250 0.28750 moveto +0.26750 0.28750 lineto +0.26750 0.32250 lineto +0.28250 0.32250 lineto +fill +0.23150 0.28750 moveto +0.21650 0.28750 lineto +0.21650 0.32250 lineto +0.23150 0.32250 lineto +fill +% Layer topsilk group 1 drill 0 mask 0 +0.00800 setlinewidth +0 0 0 setrgbcolor +0.22638 0.06260 0.27362 0.06260 t +0.22638 0.13740 0.27362 0.13740 t +0.01000 setlinewidth +0.21000 0.28100 0.21000 0.40000 t +0.21000 0.40000 0.29000 0.40000 t +0.29000 0.40000 0.29000 0.28100 t +0.29000 0.28100 0.21000 0.28100 t +0.00700 setlinewidth +0.21850 0.14350 0.23850 0.14350 t +0.23850 0.14350 0.24350 0.14850 t +0.24350 0.14850 0.24350 0.15850 t +0.23850 0.16350 0.24350 0.15850 t +0.22350 0.16350 0.23850 0.16350 t +0.22350 0.14350 0.22350 0.18350 t +0.23150 0.16350 0.24350 0.18350 t +0.25550 0.15150 0.26350 0.14350 t +0.26350 0.14350 0.26350 0.18350 t +0.25550 0.18350 0.27050 0.18350 t +0.22500 0.41500 0.22500 0.45000 t +0.22500 0.45000 0.23000 0.45500 t +0.23000 0.45500 0.24000 0.45500 t +0.24000 0.45500 0.24500 0.45000 t +0.24500 0.41500 0.24500 0.45000 t +0.25700 0.42300 0.26500 0.41500 t +0.26500 0.41500 0.26500 0.45500 t +0.25700 0.45500 0.27200 0.45500 t +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/elem_pads.exc/elem_pads.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.exc/elem_pads.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.exc/elem_pads.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/elem_pads.exc/elem_pads.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.exc/elem_pads.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.exc/elem_pads.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/elem_pads.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 6 for group 9 layer_idx 6 * +G04 Title: pads with different geometry, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD17C,0.0100*% +G54D17*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1807 @@ +G04 start of page 7 for group -1 layer_idx 268435461 * +G04 Title: pads with different geometry, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD20C,0.0100*% +%ADD19C,0.0001*% +%ADD18C,0.0060*% +G54D18*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D19*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D18*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D19*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D18*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D19*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D18*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D19*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D18*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D19*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D18*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D19*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D20*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D18*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D19*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D18*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D19*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D18*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D19*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D18*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D19*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D18*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D19*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D18*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D19*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D18*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D19*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D18*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D19*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D18*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D19*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D18*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D19*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D18*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D19*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X258800D02*X263300D01* +Y104000D01* +X258800D01* +Y110000D01* +G37* +G36* +X264200D02*X268700D01* +Y104000D01* +X264200D01* +Y110000D01* +G37* +G36* +X269600D02*X274100D01* +Y104000D01* +X269600D01* +Y110000D01* +G37* +G36* +X275000D02*X279500D01* +Y104000D01* +X275000D01* +Y110000D01* +G37* +G36* +X283100D02*X287600D01* +Y104000D01* +X283100D01* +Y110000D01* +G37* +G36* +X288500D02*X293000D01* +Y104000D01* +X288500D01* +Y110000D01* +G37* +G36* +X293900D02*X298400D01* +Y104000D01* +X293900D01* +Y110000D01* +G37* +G36* +X299300D02*X303800D01* +Y104000D01* +X299300D01* +Y110000D01* +G37* +G36* +X304700D02*X309200D01* +Y104000D01* +X304700D01* +Y110000D01* +G37* +G36* +X310100D02*X314600D01* +Y104000D01* +X310100D01* +Y110000D01* +G37* +G36* +X315500D02*X320000D01* +Y104000D01* +X315500D01* +Y110000D01* +G37* +G36* +X320900D02*X325400D01* +Y104000D01* +X320900D01* +Y110000D01* +G37* +G36* +X326300D02*X330800D01* +Y104000D01* +X326300D01* +Y110000D01* +G37* +G36* +X334400D02*X338900D01* +Y104000D01* +X334400D01* +Y110000D01* +G37* +G36* +X339800D02*X344300D01* +Y104000D01* +X339800D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X356000D02*X360500D01* +Y104000D01* +X356000D01* +Y110000D01* +G37* +G36* +X361400D02*X365900D01* +Y104000D01* +X361400D01* +Y110000D01* +G37* +G36* +X366800D02*X371300D01* +Y104000D01* +X366800D01* +Y110000D01* +G37* +G36* +X372200D02*X376700D01* +Y104000D01* +X372200D01* +Y110000D01* +G37* +G36* +X380300D02*X384800D01* +Y104000D01* +X380300D01* +Y110000D01* +G37* +G54D18*X388400D02*Y104000D01* +Y110000D02*X391400D01* +X388400Y107300D02*X390650D01* +G54D19*G36* +X393200Y110000D02*X397700D01* +Y104000D01* +X393200D01* +Y110000D01* +G37* +G36* +X398600D02*X403100D01* +Y104000D01* +X398600D01* +Y110000D01* +G37* +G36* +X404000D02*X408500D01* +Y104000D01* +X404000D01* +Y110000D01* +G37* +G36* +X409400D02*X413900D01* +Y104000D01* +X409400D01* +Y110000D01* +G37* +G36* +X414800D02*X419300D01* +Y104000D01* +X414800D01* +Y110000D01* +G37* +G36* +X420200D02*X424700D01* +Y104000D01* +X420200D01* +Y110000D01* +G37* +G36* +X425600D02*X430100D01* +Y104000D01* +X425600D01* +Y110000D01* +G37* +G36* +X431000D02*X435500D01* +Y104000D01* +X431000D01* +Y110000D01* +G37* +G36* +X436400D02*X440900D01* +Y104000D01* +X436400D01* +Y110000D01* +G37* +G36* +X441800D02*X446300D01* +Y104000D01* +X441800D01* +Y110000D01* +G37* +G54D18*X450650D02*Y104000D01* +X452600Y110000D02*X453650Y108950D01* +Y105050D01* +X452600Y104000D02*X453650Y105050D01* +X449900Y104000D02*X452600D01* +X449900Y110000D02*X452600D01* +G54D19*G36* +X455450D02*X459950D01* +Y104000D01* +X455450D01* +Y110000D01* +G37* +G36* +X460850D02*X465350D01* +Y104000D01* +X460850D01* +Y110000D01* +G37* +G36* +X466250D02*X470750D01* +Y104000D01* +X466250D01* +Y110000D01* +G37* +G36* +X471650D02*X476150D01* +Y104000D01* +X471650D01* +Y110000D01* +G37* +G36* +X477050D02*X481550D01* +Y104000D01* +X477050D01* +Y110000D01* +G37* +G36* +X482450D02*X486950D01* +Y104000D01* +X482450D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,55 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: pads with different geometry, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0001*% +G54D11*G36* +X21654Y43740D02*X16536D01* +Y36260D01* +X21654D01* +Y43740D01* +G37* +G36* +X33464D02*X28346D01* +Y36260D01* +X33464D01* +Y43740D01* +G37* +G36* +X25750Y21250D02*X24250D01* +Y17750D01* +X25750D01* +Y21250D01* +G37* +G36* +X23150Y14250D02*X21650D01* +Y10750D01* +X23150D01* +Y14250D01* +G37* +G36* +X28250D02*X26750D01* +Y10750D01* +X28250D01* +Y14250D01* +G37* +G36* +Y21250D02*X26750D01* +Y17750D01* +X28250D01* +Y21250D01* +G37* +G36* +X23150D02*X21650D01* +Y17750D01* +X23150D01* +Y21250D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.mask.none.2.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.mask.none.2.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.mask.none.2.gbr (revision 33253) @@ -0,0 +1,55 @@ +G04 start of page 3 for group 2 layer_idx 9 * +G04 Title: pads with different geometry, top_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_MASK_NONE_2*% +%ADD12C,0.0001*% +G54D12*G36* +X21954Y44040D02*X16236D01* +Y35960D01* +X21954D01* +Y44040D01* +G37* +G36* +X33764D02*X28046D01* +Y35960D01* +X33764D01* +Y44040D01* +G37* +G36* +X26050Y21550D02*X23950D01* +Y17450D01* +X26050D01* +Y21550D01* +G37* +G36* +X23450Y14550D02*X21350D01* +Y10450D01* +X23450D01* +Y14550D01* +G37* +G36* +X28550D02*X26450D01* +Y10450D01* +X28550D01* +Y14550D01* +G37* +G36* +Y21550D02*X26450D01* +Y17450D01* +X28550D01* +Y21550D01* +G37* +G36* +X23450D02*X21350D01* +Y17450D01* +X23450D01* +Y21550D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.paste.none.0.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.paste.none.0.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.paste.none.0.gbr (revision 33253) @@ -0,0 +1,55 @@ +G04 start of page 5 for group 0 layer_idx 11 * +G04 Title: pads with different geometry, top_paste * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_PASTE_NONE_0*% +%ADD16C,0.0001*% +G54D16*G36* +X21654Y43740D02*X16536D01* +Y36260D01* +X21654D01* +Y43740D01* +G37* +G36* +X33464D02*X28346D01* +Y36260D01* +X33464D01* +Y43740D01* +G37* +G36* +X25750Y21250D02*X24250D01* +Y17750D01* +X25750D01* +Y21250D01* +G37* +G36* +X23150Y14250D02*X21650D01* +Y10750D01* +X23150D01* +Y14250D01* +G37* +G36* +X28250D02*X26750D01* +Y10750D01* +X28250D01* +Y14250D01* +G37* +G36* +Y21250D02*X26750D01* +Y17750D01* +X28250D01* +Y21250D01* +G37* +G36* +X23150D02*X21650D01* +Y17750D01* +X23150D01* +Y21250D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.gbr/elem_pads.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,39 @@ +G04 start of page 4 for group 1 layer_idx 8 * +G04 Title: pads with different geometry, top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD15C,0.0070*% +%ADD14C,0.0100*% +%ADD13C,0.0080*% +G54D13*X22638Y43740D02*X27362D01* +X22638Y36260D02*X27362D01* +G54D14*X21000Y21900D02*Y10000D01* +X29000D01* +Y21900D01* +X21000D01* +G54D15*X21850Y35650D02*X23850D01* +X24350Y35150D01* +Y34150D01* +X23850Y33650D02*X24350Y34150D01* +X22350Y33650D02*X23850D01* +X22350Y35650D02*Y31650D01* +X23150Y33650D02*X24350Y31650D01* +X25550Y34850D02*X26350Y35650D01* +Y31650D01* +X25550D02*X27050D01* +X22500Y8500D02*Y5000D01* +X23000Y4500D01* +X24000D01* +X24500Y5000D01* +Y8500D02*Y5000D01* +X25700Y7700D02*X26500Y8500D01* +Y4500D01* +X25700D02*X27200D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/elem_pads.net =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.net (revision 33253) @@ -0,0 +1,19 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB pads with different geometry +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +327N/C R1 -1 A01X+001909Y+004000X0511Y0748R000 S1 +327N/C R1 -2 A01X+003090Y+004000X0511Y0748R000 S1 +327N/C U1 -1 A01X+002240Y+001250X0150Y0350R000 S1 +327N/C U1 -2 A01X+002750Y+001250X0150Y0350R000 S1 +327N/C U1 -3 A01X+002750Y+001950X0150Y0350R000 S1 +327N/C U1 -4 A01X+002500Y+001950X0150Y0350R000 S1 +327N/C U1 -5 A01X+002240Y+001950X0150Y0350R000 S1 +999 Index: tags/2.3.0/tests/RTT/ref/elem_pads.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_pads.png =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_pads.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_pads.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.png.text (revision 33253) @@ -0,0 +1,13 @@ +r6630 + +R1 pads +61 x 89 pixels (50.833 x 74.167) +distance between pads 81 pixels (67.5) + +U1 pads +18 x 42 pixels (15 x 35) +pad 5 upper to nearest silk screen corner 2 x 2 pixels (1.667 x 1.667) +pad 5 distance to pad 4 is 13 pixels (10.833) + +(mil) + Index: tags/2.3.0/tests/RTT/ref/elem_pads.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_pads.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_pads.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_pads.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_pads.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_pads.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_pads.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.svg (revision 33253) @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/elem_pads.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads.xy (revision 33253) @@ -0,0 +1,10 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: pads with different geometry - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- +R1,"Standard SMT resistor, capacitor etc","1206",250.00,400.00,0,top +U1,"SMT transistor, 5 pins","SOT325",249.60,167.00,90,top Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.bom (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: element with pads on both sides - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +1,"(unknown)","(unknown)",E1 Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.dsn (revision 33253) @@ -0,0 +1,75 @@ +(pcb element with pads on both sides + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 5 + (place "E1" 4.445000 8.890000 front 0 (PN 0)) + ) + ) + (library + (image 5 + (pin Pstk_shape_7 "1" 0.952500 0.000000) + (pin Pstk_shape_8 "2" 2.540000 -1.587500) + ) + (padstack Pstk_shape_7 + (shape + (polygon "3__top_copper" 0 + -1.079500 -0.127000 -1.079500 0.127000 1.079500 0.127000 + 1.079500 -0.127000 + ) + ) + (attach off) + ) + (padstack Pstk_shape_8 + (shape + (polygon "10__bottom_copper" 0 + -0.127000 1.079500 0.127000 1.079500 0.127000 -1.079500 + -0.127000 -1.079500 + ) + ) + (attach off) + ) + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.eps (revision 33253) @@ -0,0 +1,47 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: elem_pads_ds.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.01000 setlinewidth +1 setlinecap +0.439216 0.439216 0.439216 setrgbcolor +0.27500 0.17500 0.27500 0.25000 t +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.25098 0.25098 0.25098 setrgbcolor +0.17500 0.15000 0.25000 0.15000 t +% Layer topsilk group 1 drill 0 mask 0 +0 0 0 setrgbcolor +0.17500 0.15000 0.17500 0.25000 t +0.00700 setlinewidth +0.17500 0.09300 0.19000 0.09300 t +0.17500 0.11500 0.19500 0.11500 t +0.17500 0.07500 0.17500 0.11500 t +0.17500 0.07500 0.19500 0.07500 t +0.20700 0.08300 0.21500 0.07500 t +0.21500 0.07500 0.21500 0.11500 t +0.20700 0.11500 0.22200 0.11500 t +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.exc/elem_pads_ds.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.exc/elem_pads_ds.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.exc/elem_pads_ds.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.exc/elem_pads_ds.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.exc/elem_pads_ds.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.exc/elem_pads_ds.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 3 for group 10 layer_idx 1 * +G04 Title: element with pads on both sides, bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD12C,0.0100*% +G54D12*X27500Y32500D02*Y25000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.bottom.mask.none.11.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.bottom.mask.none.11.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.bottom.mask.none.11.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 5 for group 11 layer_idx 10 * +G04 Title: element with pads on both sides, bottom_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_MASK_NONE_11*% +%ADD14C,0.0500*% +G54D14*X27500Y32500D02*Y25000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.bottom.paste.none.13.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.bottom.paste.none.13.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.bottom.paste.none.13.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 8 for group 13 layer_idx 12 * +G04 Title: element with pads on both sides, bottom_paste * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_PASTE_NONE_13*% +%ADD18C,0.0100*% +G54D18*X27500Y32500D02*Y25000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 9 for group 9 layer_idx 6 * +G04 Title: element with pads on both sides, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD19C,0.0100*% +G54D19*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1813 @@ +G04 start of page 10 for group -1 layer_idx 268435461 * +G04 Title: element with pads on both sides, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD22C,0.0100*% +%ADD21C,0.0001*% +%ADD20C,0.0060*% +G54D20*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D21*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D20*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D21*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D20*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D21*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D20*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D21*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D20*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D21*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D20*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D21*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D22*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D20*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D21*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D20*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D21*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D20*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D21*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D20*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D21*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D20*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D21*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D20*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D21*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D20*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D21*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D20*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D21*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D20*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D21*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D20*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D21*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D20*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D21*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X256100D02*X260600D01* +Y104000D01* +X256100D01* +Y110000D01* +G37* +G36* +X261500D02*X266000D01* +Y104000D01* +X261500D01* +Y110000D01* +G37* +G36* +X266900D02*X271400D01* +Y104000D01* +X266900D01* +Y110000D01* +G37* +G36* +X275000D02*X279500D01* +Y104000D01* +X275000D01* +Y110000D01* +G37* +G36* +X280400D02*X284900D01* +Y104000D01* +X280400D01* +Y110000D01* +G37* +G36* +X285800D02*X290300D01* +Y104000D01* +X285800D01* +Y110000D01* +G37* +G36* +X291200D02*X295700D01* +Y104000D01* +X291200D01* +Y110000D01* +G37* +G36* +X299300D02*X303800D01* +Y104000D01* +X299300D01* +Y110000D01* +G37* +G36* +X304700D02*X309200D01* +Y104000D01* +X304700D01* +Y110000D01* +G37* +G36* +X310100D02*X314600D01* +Y104000D01* +X310100D01* +Y110000D01* +G37* +G36* +X315500D02*X320000D01* +Y104000D01* +X315500D01* +Y110000D01* +G37* +G36* +X323600D02*X328100D01* +Y104000D01* +X323600D01* +Y110000D01* +G37* +G36* +X329000D02*X333500D01* +Y104000D01* +X329000D01* +Y110000D01* +G37* +G36* +X337100D02*X341600D01* +Y104000D01* +X337100D01* +Y110000D01* +G37* +G36* +X342500D02*X347000D01* +Y104000D01* +X342500D01* +Y110000D01* +G37* +G36* +X347900D02*X352400D01* +Y104000D01* +X347900D01* +Y110000D01* +G37* +G36* +X353300D02*X357800D01* +Y104000D01* +X353300D01* +Y110000D01* +G37* +G36* +X361400D02*X365900D01* +Y104000D01* +X361400D01* +Y110000D01* +G37* +G36* +X366800D02*X371300D01* +Y104000D01* +X366800D01* +Y110000D01* +G37* +G36* +X372200D02*X376700D01* +Y104000D01* +X372200D01* +Y110000D01* +G37* +G36* +X377600D02*X382100D01* +Y104000D01* +X377600D01* +Y110000D01* +G37* +G36* +X383000D02*X387500D01* +Y104000D01* +X383000D01* +Y110000D01* +G37* +G36* +X391100D02*X395600D01* +Y104000D01* +X391100D01* +Y110000D01* +G37* +G54D20*X399200D02*Y104000D01* +Y110000D02*X402200D01* +X399200Y107300D02*X401450D01* +G54D21*G36* +X404000Y110000D02*X408500D01* +Y104000D01* +X404000D01* +Y110000D01* +G37* +G36* +X409400D02*X413900D01* +Y104000D01* +X409400D01* +Y110000D01* +G37* +G36* +X414800D02*X419300D01* +Y104000D01* +X414800D01* +Y110000D01* +G37* +G36* +X420200D02*X424700D01* +Y104000D01* +X420200D01* +Y110000D01* +G37* +G36* +X425600D02*X430100D01* +Y104000D01* +X425600D01* +Y110000D01* +G37* +G36* +X431000D02*X435500D01* +Y104000D01* +X431000D01* +Y110000D01* +G37* +G36* +X436400D02*X440900D01* +Y104000D01* +X436400D01* +Y110000D01* +G37* +G36* +X441800D02*X446300D01* +Y104000D01* +X441800D01* +Y110000D01* +G37* +G36* +X447200D02*X451700D01* +Y104000D01* +X447200D01* +Y110000D01* +G37* +G36* +X452600D02*X457100D01* +Y104000D01* +X452600D01* +Y110000D01* +G37* +G54D20*X461450D02*Y104000D01* +X463400Y110000D02*X464450Y108950D01* +Y105050D01* +X463400Y104000D02*X464450Y105050D01* +X460700Y104000D02*X463400D01* +X460700Y110000D02*X463400D01* +G54D21*G36* +X466250D02*X470750D01* +Y104000D01* +X466250D01* +Y110000D01* +G37* +G36* +X471650D02*X476150D01* +Y104000D01* +X471650D01* +Y110000D01* +G37* +G36* +X477050D02*X481550D01* +Y104000D01* +X477050D01* +Y110000D01* +G37* +G36* +X482450D02*X486950D01* +Y104000D01* +X482450D01* +Y110000D01* +G37* +G36* +X487850D02*X492350D01* +Y104000D01* +X487850D01* +Y110000D01* +G37* +G36* +X493250D02*X497750D01* +Y104000D01* +X493250D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: element with pads on both sides, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0100*% +G54D11*X17500Y35000D02*X25000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.mask.none.2.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.mask.none.2.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.mask.none.2.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 4 for group 2 layer_idx 9 * +G04 Title: element with pads on both sides, top_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_MASK_NONE_2*% +%ADD13C,0.0500*% +G54D13*X17500Y35000D02*X25000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.paste.none.0.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.paste.none.0.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.paste.none.0.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 7 for group 0 layer_idx 11 * +G04 Title: element with pads on both sides, top_paste * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_PASTE_NONE_0*% +%ADD17C,0.0100*% +G54D17*X17500Y35000D02*X25000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.gbr/elem_pads_ds.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,22 @@ +G04 start of page 6 for group 1 layer_idx 8 * +G04 Title: element with pads on both sides, top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD16C,0.0070*% +%ADD15C,0.0100*% +G54D15*X17500Y35000D02*Y25000D01* +G54D16*Y40700D02*X19000D01* +X17500Y38500D02*X19500D01* +X17500Y42500D02*Y38500D01* +Y42500D02*X19500D01* +X20700Y41700D02*X21500Y42500D01* +Y38500D01* +X20700D02*X22200D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.nelma.em (revision 33253) @@ -0,0 +1,75 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} +layer substrate-11 { + height = 20 + z-order = 11 + material = "composite" +} +layer bottom { + height = 1 + z-order = 12 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top", + "substrate-11", + "bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.net =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.net (revision 33253) @@ -0,0 +1,14 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB element with pads on both sides +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +327N/C E1 -1 A01X+002125Y+003500X0850Y0100R000 S1 +327N/C E1 -2 A02X+002750Y+002875X0100Y0850R000 S2 +999 Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.png =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_pads_ds.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.png.text (revision 33253) @@ -0,0 +1,14 @@ +r6630 + +E1 +2 pads 1 silk line + text (E1) + +silk line 132 pixels (110) long 12 pixels (10) wide + +copper pads 102 pixels (85) long 12 pixels (10) wide + +pad 1 shares it's terminus with the silk line + +pad 2's highest point is 114 x 18 pixels (95 x 15) over from the inside corner of pad 1 & the silk line + +pad 2's lenght 102 pixels (85) width 12 pixels (10) Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_pads_ds.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_pads_ds.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.svg (revision 33253) @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/elem_pads_ds.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pads_ds.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pads_ds.xy (revision 33253) @@ -0,0 +1,9 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: element with pads on both sides - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- +E1,"(unknown)","(unknown)",243.75,318.75,0,top Index: tags/2.3.0/tests/RTT/ref/elem_pins.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.bom (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: pins with different shapes - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +2,"dip(2)","2*300",U1 U2 Index: tags/2.3.0/tests/RTT/ref/elem_pins.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.dsn (revision 33253) @@ -0,0 +1,144 @@ +(pcb pins with different shapes + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 5 + (place "U1" 1.905000 9.525000 front 0 (PN 0)) + ) + (component 37 + (place "U2" 1.905000 4.445000 front 0 (PN 0)) + ) + ) + (library + (image 5 + (pin Pstk_shape_7 "1" 0.000000 0.000000) + (pin Pstk_shape_8 "2" 7.620000 0.000000) + ) + (image 37 + (pin Pstk_shape_39 "1" 0.000000 0.000000) + (pin Pstk_shape_40 "2" 7.620000 0.000000) + ) + (padstack Pstk_shape_7 + (shape + (polygon "3__top_copper" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "5__Intern" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "7__Intern" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "10__bottom_copper" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + ) + (attach off) + ) + (padstack Pstk_shape_8 + (shape + (circle "3__top_copper" 2.032000) + (circle "5__Intern" 2.032000) + (circle "7__Intern" 2.032000) + (circle "10__bottom_copper" 2.032000) + ) + (attach off) + ) + (padstack Pstk_shape_39 + (shape + (polygon "3__top_copper" 0 + 2.032000 0.420841 0.841682 1.016000 -0.420841 1.016000 + -1.016000 0.420841 -1.016000 -0.420841 -0.420841 -1.016000 + 0.841682 -1.016000 2.032000 -0.420841 + ) + (polygon "5__Intern" 0 + 2.032000 0.420841 0.841682 1.016000 -0.420841 1.016000 + -1.016000 0.420841 -1.016000 -0.420841 -0.420841 -1.016000 + 0.841682 -1.016000 2.032000 -0.420841 + ) + (polygon "7__Intern" 0 + 2.032000 0.420841 0.841682 1.016000 -0.420841 1.016000 + -1.016000 0.420841 -1.016000 -0.420841 -0.420841 -1.016000 + 0.841682 -1.016000 2.032000 -0.420841 + ) + (polygon "10__bottom_copper" 0 + 2.032000 0.420841 0.841682 1.016000 -0.420841 1.016000 + -1.016000 0.420841 -1.016000 -0.420841 -0.420841 -1.016000 + 0.841682 -1.016000 2.032000 -0.420841 + ) + ) + (attach off) + ) + (padstack Pstk_shape_40 + (shape + (polygon "3__top_copper" 0 + 2.032000 0.841682 0.841682 2.032000 -0.841682 2.032000 + -2.032000 0.841682 -2.032000 -0.420841 -0.841682 -1.016000 + 0.841682 -1.016000 2.032000 -0.420841 + ) + (polygon "5__Intern" 0 + 2.032000 0.841682 0.841682 2.032000 -0.841682 2.032000 + -2.032000 0.841682 -2.032000 -0.420841 -0.841682 -1.016000 + 0.841682 -1.016000 2.032000 -0.420841 + ) + (polygon "7__Intern" 0 + 2.032000 0.841682 0.841682 2.032000 -0.841682 2.032000 + -2.032000 0.841682 -2.032000 -0.420841 -0.841682 -1.016000 + 0.841682 -1.016000 2.032000 -0.420841 + ) + (polygon "10__bottom_copper" 0 + 2.032000 0.841682 0.841682 2.032000 -0.841682 2.032000 + -2.032000 0.841682 -2.032000 -0.420841 -0.841682 -1.016000 + 0.841682 -1.016000 2.032000 -0.420841 + ) + ) + (attach off) + ) + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/elem_pins.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.eps (revision 33253) @@ -0,0 +1,201 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: elem_pins.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.00000 setlinewidth +1 setlinecap +0.439216 0.439216 0.439216 setrgbcolor +0.03500 0.08500 moveto +0.11500 0.08500 lineto +0.11500 0.16500 lineto +0.03500 0.16500 lineto +fill +0.37500 0.12500 0.04000 c +0.15500 0.30843 moveto +0.10814 0.28500 lineto +0.05843 0.28500 lineto +0.03500 0.30843 lineto +0.03500 0.34157 lineto +0.05843 0.36500 lineto +0.10814 0.36500 lineto +0.15500 0.34157 lineto +fill +0.45500 0.29186 moveto +0.40814 0.24500 lineto +0.34186 0.24500 lineto +0.29500 0.29186 lineto +0.29500 0.34157 lineto +0.34186 0.36500 lineto +0.40814 0.36500 lineto +0.45500 0.34157 lineto +fill +0.00000 setlinewidth +1 1 1 setrgbcolor +0.07500 0.12500 0.01968 c +0.37500 0.12500 0.01968 c +0.07500 0.32500 0.01968 c +0.37500 0.32500 0.01968 c +% Layer group5 group 5 drill 0 mask 0 +0.00000 setlinewidth +0.439216 0.439216 0.439216 setrgbcolor +0.03500 0.08500 moveto +0.11500 0.08500 lineto +0.11500 0.16500 lineto +0.03500 0.16500 lineto +fill +0.37500 0.12500 0.04000 c +0.15500 0.30843 moveto +0.10814 0.28500 lineto +0.05843 0.28500 lineto +0.03500 0.30843 lineto +0.03500 0.34157 lineto +0.05843 0.36500 lineto +0.10814 0.36500 lineto +0.15500 0.34157 lineto +fill +0.45500 0.29186 moveto +0.40814 0.24500 lineto +0.34186 0.24500 lineto +0.29500 0.29186 lineto +0.29500 0.34157 lineto +0.34186 0.36500 lineto +0.40814 0.36500 lineto +0.45500 0.34157 lineto +fill +0.00000 setlinewidth +1 1 1 setrgbcolor +0.07500 0.12500 0.01968 c +0.37500 0.12500 0.01968 c +0.07500 0.32500 0.01968 c +0.37500 0.32500 0.01968 c +% Layer group7 group 7 drill 0 mask 0 +0.00000 setlinewidth +0.439216 0.439216 0.439216 setrgbcolor +0.03500 0.08500 moveto +0.11500 0.08500 lineto +0.11500 0.16500 lineto +0.03500 0.16500 lineto +fill +0.37500 0.12500 0.04000 c +0.15500 0.30843 moveto +0.10814 0.28500 lineto +0.05843 0.28500 lineto +0.03500 0.30843 lineto +0.03500 0.34157 lineto +0.05843 0.36500 lineto +0.10814 0.36500 lineto +0.15500 0.34157 lineto +fill +0.45500 0.29186 moveto +0.40814 0.24500 lineto +0.34186 0.24500 lineto +0.29500 0.29186 lineto +0.29500 0.34157 lineto +0.34186 0.36500 lineto +0.40814 0.36500 lineto +0.45500 0.34157 lineto +fill +0.00000 setlinewidth +1 1 1 setrgbcolor +0.07500 0.12500 0.01968 c +0.37500 0.12500 0.01968 c +0.07500 0.32500 0.01968 c +0.37500 0.32500 0.01968 c +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +0.25098 0.25098 0.25098 setrgbcolor +0.03500 0.08500 moveto +0.11500 0.08500 lineto +0.11500 0.16500 lineto +0.03500 0.16500 lineto +fill +0.37500 0.12500 0.04000 c +0.15500 0.30843 moveto +0.10814 0.28500 lineto +0.05843 0.28500 lineto +0.03500 0.30843 lineto +0.03500 0.34157 lineto +0.05843 0.36500 lineto +0.10814 0.36500 lineto +0.15500 0.34157 lineto +fill +0.45500 0.29186 moveto +0.40814 0.24500 lineto +0.34186 0.24500 lineto +0.29500 0.29186 lineto +0.29500 0.34157 lineto +0.34186 0.36500 lineto +0.40814 0.36500 lineto +0.45500 0.34157 lineto +fill +0.00000 setlinewidth +1 1 1 setrgbcolor +0.07500 0.12500 0.01968 c +0.37500 0.12500 0.01968 c +0.07500 0.32500 0.01968 c +0.37500 0.32500 0.01968 c +% Layer topsilk group 1 drill 0 mask 0 +0.01000 setlinewidth +0 0 0 setrgbcolor +0.02500 0.07500 0.02500 0.17500 t +0.02500 0.07500 0.17500 0.07500 t +0.02500 0.27500 0.17500 0.27500 t +0.02500 0.27500 0.02500 0.37500 t +0.42500 0.37500 0.02500 0.37500 t +0.42500 0.37500 0.42500 0.27500 t +0.27500 0.27500 0.42500 0.27500 t +0.42500 0.17500 0.02500 0.17500 t +0.42500 0.17500 0.42500 0.07500 t +0.27500 0.07500 0.42500 0.07500 t +0.000000 180.000000 -0.05000 0.05000 0.22500 0.07500 0.200000 a +0.000000 180.000000 -0.05000 0.05000 0.22500 0.27500 0.200000 a +0.00700 setlinewidth +0.07500 0.02500 0.07500 0.06000 t +0.07500 0.06000 0.08000 0.06500 t +0.08000 0.06500 0.09000 0.06500 t +0.09000 0.06500 0.09500 0.06000 t +0.09500 0.02500 0.09500 0.06000 t +0.10700 0.03300 0.11500 0.02500 t +0.11500 0.02500 0.11500 0.06500 t +0.10700 0.06500 0.12200 0.06500 t +0.07500 0.22500 0.07500 0.26000 t +0.07500 0.26000 0.08000 0.26500 t +0.08000 0.26500 0.09000 0.26500 t +0.09000 0.26500 0.09500 0.26000 t +0.09500 0.22500 0.09500 0.26000 t +0.10700 0.23000 0.11200 0.22500 t +0.11200 0.22500 0.12700 0.22500 t +0.12700 0.22500 0.13200 0.23000 t +0.13200 0.23000 0.13200 0.24000 t +0.10700 0.26500 0.13200 0.24000 t +0.10700 0.26500 0.13200 0.26500 t +% Layer plated-drill group -1 drill 1 mask 0 +0.00000 setlinewidth +1 1 1 setrgbcolor +0.07500 0.12500 0.01968 c +0.37500 0.12500 0.01968 c +0.07500 0.32500 0.01968 c +0.37500 0.32500 0.01968 c +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/elem_pins.exc/elem_pins.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.exc/elem_pins.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.exc/elem_pins.plated.cnc (revision 33253) @@ -0,0 +1,11 @@ +M48 +INCH +T11C0.039 +% +T11 +G05 +X000750Y003750 +X003750Y003750 +X000750Y001750 +X003750Y001750 +M30 Index: tags/2.3.0/tests/RTT/ref/elem_pins.exc/elem_pins.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.exc/elem_pins.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.exc/elem_pins.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/elem_pins.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,42 @@ +G04 start of page 5 for group 10 layer_idx 1 * +G04 Title: pins with different shapes, bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD22C,0.0394*% +%ADD21C,0.0800*% +%ADD20C,0.0001*% +G54D20*G36* +X3500Y41500D02*X11500D01* +Y33500D01* +X3500D01* +Y41500D01* +G37* +G54D21*X37500Y37500D03* +G54D20*G36* +X15500Y19157D02*X10814Y21500D01* +X5843D01* +X3500Y19157D01* +Y15843D01* +X5843Y13500D01* +X10814D01* +X15500Y15843D01* +Y19157D01* +G37* +G36* +X45500Y20814D02*X40814Y25500D01* +X34186D01* +X29500Y20814D01* +Y15843D01* +X34186Y13500D01* +X40814D01* +X45500Y15843D01* +Y20814D01* +G37* +G54D22*M02* Index: tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.bottom.mask.none.11.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.bottom.mask.none.11.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.bottom.mask.none.11.gbr (revision 33253) @@ -0,0 +1,41 @@ +G04 start of page 7 for group 11 layer_idx 10 * +G04 Title: pins with different shapes, bottom_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_MASK_NONE_11*% +%ADD26C,0.0860*% +%ADD25C,0.0001*% +G54D25*G36* +X3200Y41800D02*X11800D01* +Y33200D01* +X3200D01* +Y41800D01* +G37* +G54D26*X37500Y37500D03* +G54D25*G36* +X16100Y19281D02*X11062Y21800D01* +X5719D01* +X3200Y19281D01* +Y15719D01* +X5719Y13200D01* +X11062D01* +X16100Y15719D01* +Y19281D01* +G37* +G36* +X46100Y21062D02*X41062Y26100D01* +X33938D01* +X28900Y21062D01* +Y15719D01* +X33938Y13200D01* +X41062D01* +X46100Y15719D01* +Y21062D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 10 for group 9 layer_idx 6 * +G04 Title: pins with different shapes, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD30C,0.0100*% +G54D30*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.global.virtual.pdrill.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.global.virtual.pdrill.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.global.virtual.pdrill.none.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 9 for group -1 layer_idx 268435462 * +G04 Title: pins with different shapes, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_VIRTUAL_PDRILL_NONE*% +%ADD29C,0.0394*% +G54D29*X7500Y37500D03* +X37500D03* +X7500Y17500D03* +X37500D03* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.intern.copper.none.5.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.intern.copper.none.5.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.intern.copper.none.5.gbr (revision 33253) @@ -0,0 +1,42 @@ +G04 start of page 3 for group 5 layer_idx 4 * +G04 Title: pins with different shapes, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_5*% +%ADD16C,0.0394*% +%ADD15C,0.0800*% +%ADD14C,0.0001*% +G54D14*G36* +X3500Y41500D02*X11500D01* +Y33500D01* +X3500D01* +Y41500D01* +G37* +G54D15*X37500Y37500D03* +G54D14*G36* +X15500Y19157D02*X10814Y21500D01* +X5843D01* +X3500Y19157D01* +Y15843D01* +X5843Y13500D01* +X10814D01* +X15500Y15843D01* +Y19157D01* +G37* +G36* +X45500Y20814D02*X40814Y25500D01* +X34186D01* +X29500Y20814D01* +Y15843D01* +X34186Y13500D01* +X40814D01* +X45500Y15843D01* +Y20814D01* +G37* +G54D16*M02* Index: tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.intern.copper.none.7.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.intern.copper.none.7.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.intern.copper.none.7.gbr (revision 33253) @@ -0,0 +1,42 @@ +G04 start of page 4 for group 7 layer_idx 5 * +G04 Title: pins with different shapes, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_7*% +%ADD19C,0.0394*% +%ADD18C,0.0800*% +%ADD17C,0.0001*% +G54D17*G36* +X3500Y41500D02*X11500D01* +Y33500D01* +X3500D01* +Y41500D01* +G37* +G54D18*X37500Y37500D03* +G54D17*G36* +X15500Y19157D02*X10814Y21500D01* +X5843D01* +X3500Y19157D01* +Y15843D01* +X5843Y13500D01* +X10814D01* +X15500Y15843D01* +Y19157D01* +G37* +G36* +X45500Y20814D02*X40814Y25500D01* +X34186D01* +X29500Y20814D01* +Y15843D01* +X34186Y13500D01* +X40814D01* +X45500Y15843D01* +Y20814D01* +G37* +G54D19*M02* Index: tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1863 @@ +G04 start of page 11 for group -1 layer_idx 268435461 * +G04 Title: pins with different shapes, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD34C,0.0100*% +%ADD33C,0.0001*% +%ADD32C,0.0060*% +%ADD31C,0.0080*% +G54D31*X7500Y37500D02*Y35900D01* +Y37500D02*X8887Y38300D01* +X7500Y37500D02*X6113Y38300D01* +X37500Y37500D02*Y35900D01* +Y37500D02*X38887Y38300D01* +X37500Y37500D02*X36113Y38300D01* +X7500Y17500D02*Y15900D01* +Y17500D02*X8887Y18300D01* +X7500Y17500D02*X6113Y18300D01* +X37500Y17500D02*Y15900D01* +Y17500D02*X38887Y18300D01* +X37500Y17500D02*X36113Y18300D01* +X15000Y106250D02*Y104650D01* +Y106250D02*X16387Y107050D01* +X15000Y106250D02*X13613Y107050D01* +G54D32*X135000Y110000D02*X136500Y107000D01* +X138000Y110000D01* +X136500Y107000D02*Y104000D01* +X139800Y107300D02*X142050D01* +X139800Y104000D02*X142800D01* +X139800Y110000D02*Y104000D01* +Y110000D02*X142800D01* +X147600D02*X148350Y109250D01* +X145350Y110000D02*X147600D01* +X144600Y109250D02*X145350Y110000D01* +X144600Y109250D02*Y107750D01* +X145350Y107000D01* +X147600D01* +X148350Y106250D01* +Y104750D01* +X147600Y104000D02*X148350Y104750D01* +X145350Y104000D02*X147600D01* +X144600Y104750D02*X145350Y104000D01* +X98000Y106250D02*X101000Y110000D01* +X98000Y106250D02*X101750D01* +X101000Y110000D02*Y104000D01* +G54D33*G36* +X45000Y110000D02*X49500D01* +Y104000D01* +X45000D01* +Y110000D01* +G37* +G36* +X50400D02*X54900D01* +Y104000D01* +X50400D01* +Y110000D01* +G37* +G36* +X55800D02*X60300D01* +Y104000D01* +X55800D01* +Y110000D01* +G37* +G54D32*X61200Y109250D02*X61950Y110000D01* +X63450D01* +X64200Y109250D01* +X63450Y104000D02*X64200Y104750D01* +X61950Y104000D02*X63450D01* +X61200Y104750D02*X61950Y104000D01* +Y107300D02*X63450D01* +X64200Y109250D02*Y108050D01* +Y106550D02*Y104750D01* +Y106550D02*X63450Y107300D01* +X64200Y108050D02*X63450Y107300D01* +X66750Y104000D02*X69000Y107000D01* +Y109250D02*Y107000D01* +X68250Y110000D02*X69000Y109250D01* +X66750Y110000D02*X68250D01* +X66000Y109250D02*X66750Y110000D01* +X66000Y109250D02*Y107750D01* +X66750Y107000D01* +X69000D01* +X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D33*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D32*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D33*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D32*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D33*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D32*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D33*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D32*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D33*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D32*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D33*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G54D32*X48000Y138800D02*X49200Y140000D01* +Y134000D01* +X48000D02*X50250D01* +G54D33*G36* +X54750Y140000D02*X59250D01* +Y134000D01* +X54750D01* +Y140000D01* +G37* +G36* +X60150D02*X64650D01* +Y134000D01* +X60150D01* +Y140000D01* +G37* +G36* +X65550D02*X70050D01* +Y134000D01* +X65550D01* +Y140000D01* +G37* +G36* +X70950D02*X75450D01* +Y134000D01* +X70950D01* +Y140000D01* +G37* +G36* +X76350D02*X80850D01* +Y134000D01* +X76350D01* +Y140000D01* +G37* +G36* +X81750D02*X86250D01* +Y134000D01* +X81750D01* +Y140000D01* +G37* +G36* +X87150D02*X91650D01* +Y134000D01* +X87150D01* +Y140000D01* +G37* +G36* +X92550D02*X97050D01* +Y134000D01* +X92550D01* +Y140000D01* +G37* +G36* +X97950D02*X102450D01* +Y134000D01* +X97950D01* +Y140000D01* +G37* +G36* +X106050D02*X110550D01* +Y134000D01* +X106050D01* +Y140000D01* +G37* +G36* +X111450D02*X115950D01* +Y134000D01* +X111450D01* +Y140000D01* +G37* +G36* +X116850D02*X121350D01* +Y134000D01* +X116850D01* +Y140000D01* +G37* +G36* +X122250D02*X126750D01* +Y134000D01* +X122250D01* +Y140000D01* +G37* +G36* +X127650D02*X132150D01* +Y134000D01* +X127650D01* +Y140000D01* +G37* +G36* +X135750D02*X140250D01* +Y134000D01* +X135750D01* +Y140000D01* +G37* +G36* +X141150D02*X145650D01* +Y134000D01* +X141150D01* +Y140000D01* +G37* +G36* +X146550D02*X151050D01* +Y134000D01* +X146550D01* +Y140000D01* +G37* +G36* +X151950D02*X156450D01* +Y134000D01* +X151950D01* +Y140000D01* +G37* +G36* +X157350D02*X161850D01* +Y134000D01* +X157350D01* +Y140000D01* +G37* +G36* +X165450D02*X169950D01* +Y134000D01* +X165450D01* +Y140000D01* +G37* +G36* +X170850D02*X175350D01* +Y134000D01* +X170850D01* +Y140000D01* +G37* +G36* +X176250D02*X180750D01* +Y134000D01* +X176250D01* +Y140000D01* +G37* +G36* +X181650D02*X186150D01* +Y134000D01* +X181650D01* +Y140000D01* +G37* +G36* +X189750D02*X194250D01* +Y134000D01* +X189750D01* +Y140000D01* +G37* +G36* +X195150D02*X199650D01* +Y134000D01* +X195150D01* +Y140000D01* +G37* +G36* +X203250D02*X207750D01* +Y134000D01* +X203250D01* +Y140000D01* +G37* +G36* +X208650D02*X213150D01* +Y134000D01* +X208650D01* +Y140000D01* +G37* +G36* +X214050D02*X218550D01* +Y134000D01* +X214050D01* +Y140000D01* +G37* +G36* +X219450D02*X223950D01* +Y134000D01* +X219450D01* +Y140000D01* +G37* +G36* +X227550D02*X232050D01* +Y134000D01* +X227550D01* +Y140000D01* +G37* +G36* +X232950D02*X237450D01* +Y134000D01* +X232950D01* +Y140000D01* +G37* +G36* +X238350D02*X242850D01* +Y134000D01* +X238350D01* +Y140000D01* +G37* +G36* +X243750D02*X248250D01* +Y134000D01* +X243750D01* +Y140000D01* +G37* +G36* +X249150D02*X253650D01* +Y134000D01* +X249150D01* +Y140000D01* +G37* +G36* +X254550D02*X259050D01* +Y134000D01* +X254550D01* +Y140000D01* +G37* +G36* +X259950D02*X264450D01* +Y134000D01* +X259950D01* +Y140000D01* +G37* +G54D32*X268050Y136250D02*X271050Y140000D01* +X268050Y136250D02*X271800D01* +X271050Y140000D02*Y134000D01* +G54D33*G36* +X276300Y140000D02*X280800D01* +Y134000D01* +X276300D01* +Y140000D01* +G37* +G36* +X281700D02*X286200D01* +Y134000D01* +X281700D01* +Y140000D01* +G37* +G36* +X287100D02*X291600D01* +Y134000D01* +X287100D01* +Y140000D01* +G37* +G36* +X292500D02*X297000D01* +Y134000D01* +X292500D01* +Y140000D01* +G37* +G36* +X297900D02*X302400D01* +Y134000D01* +X297900D01* +Y140000D01* +G37* +G36* +X306000D02*X310500D01* +Y134000D01* +X306000D01* +Y140000D01* +G37* +G36* +X311400D02*X315900D01* +Y134000D01* +X311400D01* +Y140000D01* +G37* +G36* +X316800D02*X321300D01* +Y134000D01* +X316800D01* +Y140000D01* +G37* +G36* +X322200D02*X326700D01* +Y134000D01* +X322200D01* +Y140000D01* +G37* +G36* +X327600D02*X332100D01* +Y134000D01* +X327600D01* +Y140000D01* +G37* +G54D34*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D32*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D33*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D32*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D33*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D32*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D33*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D32*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D33*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D32*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D33*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D32*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D33*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D32*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D33*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D32*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D33*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D32*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D33*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D32*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D33*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D32*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D33*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X258800D02*X263300D01* +Y104000D01* +X258800D01* +Y110000D01* +G37* +G36* +X264200D02*X268700D01* +Y104000D01* +X264200D01* +Y110000D01* +G37* +G36* +X269600D02*X274100D01* +Y104000D01* +X269600D01* +Y110000D01* +G37* +G36* +X275000D02*X279500D01* +Y104000D01* +X275000D01* +Y110000D01* +G37* +G36* +X283100D02*X287600D01* +Y104000D01* +X283100D01* +Y110000D01* +G37* +G36* +X288500D02*X293000D01* +Y104000D01* +X288500D01* +Y110000D01* +G37* +G36* +X293900D02*X298400D01* +Y104000D01* +X293900D01* +Y110000D01* +G37* +G36* +X299300D02*X303800D01* +Y104000D01* +X299300D01* +Y110000D01* +G37* +G36* +X304700D02*X309200D01* +Y104000D01* +X304700D01* +Y110000D01* +G37* +G36* +X310100D02*X314600D01* +Y104000D01* +X310100D01* +Y110000D01* +G37* +G36* +X315500D02*X320000D01* +Y104000D01* +X315500D01* +Y110000D01* +G37* +G36* +X320900D02*X325400D01* +Y104000D01* +X320900D01* +Y110000D01* +G37* +G36* +X326300D02*X330800D01* +Y104000D01* +X326300D01* +Y110000D01* +G37* +G36* +X334400D02*X338900D01* +Y104000D01* +X334400D01* +Y110000D01* +G37* +G36* +X339800D02*X344300D01* +Y104000D01* +X339800D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X356000D02*X360500D01* +Y104000D01* +X356000D01* +Y110000D01* +G37* +G36* +X361400D02*X365900D01* +Y104000D01* +X361400D01* +Y110000D01* +G37* +G36* +X369500D02*X374000D01* +Y104000D01* +X369500D01* +Y110000D01* +G37* +G54D32*X377600D02*Y104000D01* +Y110000D02*X380600D01* +X377600Y107300D02*X379850D01* +G54D33*G36* +X382400Y110000D02*X386900D01* +Y104000D01* +X382400D01* +Y110000D01* +G37* +G36* +X387800D02*X392300D01* +Y104000D01* +X387800D01* +Y110000D01* +G37* +G36* +X393200D02*X397700D01* +Y104000D01* +X393200D01* +Y110000D01* +G37* +G36* +X398600D02*X403100D01* +Y104000D01* +X398600D01* +Y110000D01* +G37* +G36* +X404000D02*X408500D01* +Y104000D01* +X404000D01* +Y110000D01* +G37* +G36* +X409400D02*X413900D01* +Y104000D01* +X409400D01* +Y110000D01* +G37* +G36* +X414800D02*X419300D01* +Y104000D01* +X414800D01* +Y110000D01* +G37* +G36* +X420200D02*X424700D01* +Y104000D01* +X420200D01* +Y110000D01* +G37* +G36* +X425600D02*X430100D01* +Y104000D01* +X425600D01* +Y110000D01* +G37* +G36* +X431000D02*X435500D01* +Y104000D01* +X431000D01* +Y110000D01* +G37* +G54D32*X439850D02*Y104000D01* +X441800Y110000D02*X442850Y108950D01* +Y105050D01* +X441800Y104000D02*X442850Y105050D01* +X439100Y104000D02*X441800D01* +X439100Y110000D02*X441800D01* +G54D33*G36* +X444650D02*X449150D01* +Y104000D01* +X444650D01* +Y110000D01* +G37* +G36* +X450050D02*X454550D01* +Y104000D01* +X450050D01* +Y110000D01* +G37* +G36* +X455450D02*X459950D01* +Y104000D01* +X455450D01* +Y110000D01* +G37* +G36* +X460850D02*X465350D01* +Y104000D01* +X460850D01* +Y110000D01* +G37* +G36* +X466250D02*X470750D01* +Y104000D01* +X466250D01* +Y110000D01* +G37* +G36* +X471650D02*X476150D01* +Y104000D01* +X471650D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,42 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: pins with different shapes, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD13C,0.0394*% +%ADD12C,0.0800*% +%ADD11C,0.0001*% +G54D11*G36* +X3500Y41500D02*X11500D01* +Y33500D01* +X3500D01* +Y41500D01* +G37* +G54D12*X37500Y37500D03* +G54D11*G36* +X15500Y19157D02*X10814Y21500D01* +X5843D01* +X3500Y19157D01* +Y15843D01* +X5843Y13500D01* +X10814D01* +X15500Y15843D01* +Y19157D01* +G37* +G36* +X45500Y20814D02*X40814Y25500D01* +X34186D01* +X29500Y20814D01* +Y15843D01* +X34186Y13500D01* +X40814D01* +X45500Y15843D01* +Y20814D01* +G37* +G54D13*M02* Index: tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.top.mask.none.2.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.top.mask.none.2.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.top.mask.none.2.gbr (revision 33253) @@ -0,0 +1,41 @@ +G04 start of page 6 for group 2 layer_idx 9 * +G04 Title: pins with different shapes, top_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_MASK_NONE_2*% +%ADD24C,0.0860*% +%ADD23C,0.0001*% +G54D23*G36* +X3200Y41800D02*X11800D01* +Y33200D01* +X3200D01* +Y41800D01* +G37* +G54D24*X37500Y37500D03* +G54D23*G36* +X16100Y19281D02*X11062Y21800D01* +X5719D01* +X3200Y19281D01* +Y15719D01* +X5719Y13200D01* +X11062D01* +X16100Y15719D01* +Y19281D01* +G37* +G36* +X46100Y21062D02*X41062Y26100D01* +X33938D01* +X28900Y21062D01* +Y15719D01* +X33938Y13200D01* +X41062D01* +X46100Y15719D01* +Y21062D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.gbr/elem_pins.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,45 @@ +G04 start of page 8 for group 1 layer_idx 8 * +G04 Title: pins with different shapes, top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD28C,0.0070*% +%ADD27C,0.0100*% +G54D27*X2500Y42500D02*Y32500D01* +Y42500D02*X17500D01* +X2500Y22500D02*X17500D01* +X2500D02*Y12500D01* +X42500D02*X2500D01* +X42500D02*Y22500D01* +X27500D02*X42500D01* +Y32500D02*X2500D01* +X42500D02*Y42500D01* +X27500D02*X42500D01* +X17500D02*G75*G03X27500Y42500I5000J0D01*G01* +X17500Y22500D02*G75*G03X27500Y22500I5000J0D01*G01* +G54D28*X7500Y47500D02*Y44000D01* +X8000Y43500D01* +X9000D01* +X9500Y44000D01* +Y47500D02*Y44000D01* +X10700Y46700D02*X11500Y47500D01* +Y43500D01* +X10700D02*X12200D01* +X7500Y27500D02*Y24000D01* +X8000Y23500D01* +X9000D01* +X9500Y24000D01* +Y27500D02*Y24000D01* +X10700Y27000D02*X11200Y27500D01* +X12700D01* +X13200Y27000D01* +Y26000D01* +X10700Y23500D02*X13200Y26000D01* +X10700Y23500D02*X13200D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_pins.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.nelma.em (revision 33253) @@ -0,0 +1,51 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/elem_pins.net =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.net (revision 33253) @@ -0,0 +1,16 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB pins with different shapes +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +317N/C U1 -1 D0393PA00X+000750Y+003750X0800Y0800R000 S0 +317N/C U1 -2 D0393PA00X+003750Y+003750X0800Y0000R000 S0 +317N/C U2 -1 D0393PA00X+000750Y+001750X0800Y0800R000 S0 +317N/C U2 -2 D0393PA00X+003750Y+001750X0800Y0800R000 S0 +999 Index: tags/2.3.0/tests/RTT/ref/elem_pins.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_pins.png =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_pins.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_pins.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.png.text (revision 33253) @@ -0,0 +1,17 @@ +r6630 + +U1 +6 x 6 pixel (5x5) distance from silk inside top corner to pin 1 +pin 1 dimensions 96 x 96 pixels (80x80) +pin 2 97 pixel circle (80.808) +pin 1 to pin 2 distance 264 pixels (303.333) +pin 2 hole 47 pixels (39.167) + +U2 +pin 1 extremes 97 pixels (80.833) tall 145 wide (120.833) +pin 2 extremes 145 pixels (120.833) tall 193 pixels (160.833) wide +pin 1 to pin 2 distance 167 pixels (139.166) +pin 1 to pin 2 vertical offset 0 pixels + +(mil) + Index: tags/2.3.0/tests/RTT/ref/elem_pins.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_pins.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_pins.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_pins.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_pins.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_pins.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_pins.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.svg (revision 33253) @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/elem_pins.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_pins.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_pins.xy (revision 33253) @@ -0,0 +1,10 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: pins with different shapes - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- +U1,"dip(2)","2*300",225.00,375.00,0,top +U2,"dip(2)","2*300",225.00,175.00,0,top Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.bom (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: smd elements on both sides - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +2,"Standard SMT resistor, capacitor etc","1206",R1 R2 Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.dsn (revision 33253) @@ -0,0 +1,100 @@ +(pcb smd elements on both sides + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 5 + (place "R1" 5.715000 9.525000 front 0 (PN 0)) + ) + (component 27 + (place "R2" 5.715000 3.810000 back 0 (PN 0)) + ) + ) + (library + (image 5 + (pin Pstk_shape_7 "1" -1.499870 0.000000) + (pin Pstk_shape_8 "2" 1.499870 0.000000) + ) + (image 27 + (pin Pstk_shape_29 "1" 1.499870 0.000000) + (pin Pstk_shape_30 "2" -1.499870 0.000000) + ) + (padstack Pstk_shape_7 + (shape + (polygon "3__top_copper" 0 + 0.649986 0.949960 -0.649986 0.949960 -0.649986 -0.949960 + 0.649986 -0.949960 + ) + ) + (attach off) + ) + (padstack Pstk_shape_8 + (shape + (polygon "3__top_copper" 0 + 0.649986 0.949960 -0.649986 0.949960 -0.649986 -0.949960 + 0.649986 -0.949960 + ) + ) + (attach off) + ) + (padstack Pstk_shape_29 + (shape + (polygon "10__bottom_copper" 0 + 0.649986 0.949960 -0.649986 0.949960 -0.649986 -0.949960 + 0.649986 -0.949960 + ) + ) + (attach off) + ) + (padstack Pstk_shape_30 + (shape + (polygon "10__bottom_copper" 0 + 0.649986 0.949960 -0.649986 0.949960 -0.649986 -0.949960 + 0.649986 -0.949960 + ) + ) + (attach off) + ) + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.eps (revision 33253) @@ -0,0 +1,70 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: elem_sides_smd.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.00000 setlinewidth +1 setlinecap +0.439216 0.439216 0.439216 setrgbcolor +0.14036 0.38740 moveto +0.19154 0.38740 lineto +0.19154 0.31260 lineto +0.14036 0.31260 lineto +fill +0.25846 0.38740 moveto +0.30964 0.38740 lineto +0.30964 0.31260 lineto +0.25846 0.31260 lineto +fill +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.25098 0.25098 0.25098 setrgbcolor +0.19154 0.08760 moveto +0.14036 0.08760 lineto +0.14036 0.16240 lineto +0.19154 0.16240 lineto +fill +0.30964 0.08760 moveto +0.25846 0.08760 lineto +0.25846 0.16240 lineto +0.30964 0.16240 lineto +fill +% Layer topsilk group 1 drill 0 mask 0 +0.00800 setlinewidth +0 0 0 setrgbcolor +0.20138 0.08760 0.24862 0.08760 t +0.20138 0.16240 0.24862 0.16240 t +0.00700 setlinewidth +0.34350 0.09350 0.36350 0.09350 t +0.36350 0.09350 0.36850 0.09850 t +0.36850 0.09850 0.36850 0.10850 t +0.36350 0.11350 0.36850 0.10850 t +0.34850 0.11350 0.36350 0.11350 t +0.34850 0.09350 0.34850 0.13350 t +0.35650 0.11350 0.36850 0.13350 t +0.38050 0.10150 0.38850 0.09350 t +0.38850 0.09350 0.38850 0.13350 t +0.38050 0.13350 0.39550 0.13350 t +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.exc/elem_sides_smd.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.exc/elem_sides_smd.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.exc/elem_sides_smd.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.exc/elem_sides_smd.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.exc/elem_sides_smd.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.exc/elem_sides_smd.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,25 @@ +G04 start of page 4 for group 10 layer_idx 1 * +G04 Title: smd elements on both sides, bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD14C,0.0001*% +G54D14*G36* +X14036Y11260D02*X19154D01* +Y18740D01* +X14036D01* +Y11260D01* +G37* +G36* +X25846D02*X30964D01* +Y18740D01* +X25846D01* +Y11260D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.mask.none.11.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.mask.none.11.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.mask.none.11.gbr (revision 33253) @@ -0,0 +1,25 @@ +G04 start of page 6 for group 11 layer_idx 10 * +G04 Title: smd elements on both sides, bottom_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_MASK_NONE_11*% +%ADD16C,0.0001*% +G54D16*G36* +X13736Y10960D02*X19454D01* +Y19040D01* +X13736D01* +Y10960D01* +G37* +G36* +X25546D02*X31264D01* +Y19040D01* +X25546D01* +Y10960D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.paste.none.13.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.paste.none.13.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.paste.none.13.gbr (revision 33253) @@ -0,0 +1,25 @@ +G04 start of page 9 for group 13 layer_idx 12 * +G04 Title: smd elements on both sides, bottom_paste * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_PASTE_NONE_13*% +%ADD20C,0.0001*% +G54D20*G36* +X14036Y11260D02*X19154D01* +Y18740D01* +X14036D01* +Y11260D01* +G37* +G36* +X25846D02*X30964D01* +Y18740D01* +X25846D01* +Y11260D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.silk.none.12.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.silk.none.12.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.bottom.silk.none.12.gbr (revision 33253) @@ -0,0 +1,29 @@ +G04 start of page 2 for group 12 layer_idx 7 * +G04 Title: smd elements on both sides, bottom_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_SILK_NONE_12*% +%ADD12C,0.0070*% +%ADD11C,0.0080*% +G54D11*X20138Y11260D02*X24862D01* +X20138Y18740D02*X24862D01* +G54D12*X34350Y11850D02*X36350D01* +X36850Y12350D01* +Y13350D01* +X36350Y13850D02*X36850Y13350D01* +X34850Y13850D02*X36350D01* +X34850Y11850D02*Y15850D01* +X35650Y13850D02*X36850Y15850D01* +X38050Y12350D02*X38550Y11850D01* +X40050D01* +X40550Y12350D01* +Y13350D01* +X38050Y15850D02*X40550Y13350D01* +X38050Y15850D02*X40550D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 10 for group 9 layer_idx 6 * +G04 Title: smd elements on both sides, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD21C,0.0100*% +G54D21*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1789 @@ +G04 start of page 11 for group -1 layer_idx 268435461 * +G04 Title: smd elements on both sides, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD24C,0.0100*% +%ADD23C,0.0001*% +%ADD22C,0.0060*% +G54D22*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D23*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D22*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D23*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D22*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D23*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D22*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D23*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D22*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D23*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D22*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D23*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D24*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D22*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D23*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D22*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D23*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D22*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D23*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D22*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D23*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D22*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D23*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D22*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D23*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D22*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D23*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D22*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D23*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D22*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D23*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D22*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D23*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D22*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D23*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X253400D02*X257900D01* +Y104000D01* +X253400D01* +Y110000D01* +G37* +G36* +X258800D02*X263300D01* +Y104000D01* +X258800D01* +Y110000D01* +G37* +G36* +X264200D02*X268700D01* +Y104000D01* +X264200D01* +Y110000D01* +G37* +G36* +X269600D02*X274100D01* +Y104000D01* +X269600D01* +Y110000D01* +G37* +G36* +X275000D02*X279500D01* +Y104000D01* +X275000D01* +Y110000D01* +G37* +G36* +X280400D02*X284900D01* +Y104000D01* +X280400D01* +Y110000D01* +G37* +G36* +X285800D02*X290300D01* +Y104000D01* +X285800D01* +Y110000D01* +G37* +G36* +X291200D02*X295700D01* +Y104000D01* +X291200D01* +Y110000D01* +G37* +G36* +X299300D02*X303800D01* +Y104000D01* +X299300D01* +Y110000D01* +G37* +G36* +X304700D02*X309200D01* +Y104000D01* +X304700D01* +Y110000D01* +G37* +G36* +X312800D02*X317300D01* +Y104000D01* +X312800D01* +Y110000D01* +G37* +G36* +X318200D02*X322700D01* +Y104000D01* +X318200D01* +Y110000D01* +G37* +G36* +X323600D02*X328100D01* +Y104000D01* +X323600D01* +Y110000D01* +G37* +G36* +X329000D02*X333500D01* +Y104000D01* +X329000D01* +Y110000D01* +G37* +G36* +X337100D02*X341600D01* +Y104000D01* +X337100D01* +Y110000D01* +G37* +G36* +X342500D02*X347000D01* +Y104000D01* +X342500D01* +Y110000D01* +G37* +G36* +X347900D02*X352400D01* +Y104000D01* +X347900D01* +Y110000D01* +G37* +G36* +X353300D02*X357800D01* +Y104000D01* +X353300D01* +Y110000D01* +G37* +G36* +X358700D02*X363200D01* +Y104000D01* +X358700D01* +Y110000D01* +G37* +G36* +X366800D02*X371300D01* +Y104000D01* +X366800D01* +Y110000D01* +G37* +G54D22*X374900D02*Y104000D01* +Y110000D02*X377900D01* +X374900Y107300D02*X377150D01* +G54D23*G36* +X379700Y110000D02*X384200D01* +Y104000D01* +X379700D01* +Y110000D01* +G37* +G36* +X385100D02*X389600D01* +Y104000D01* +X385100D01* +Y110000D01* +G37* +G36* +X390500D02*X395000D01* +Y104000D01* +X390500D01* +Y110000D01* +G37* +G36* +X395900D02*X400400D01* +Y104000D01* +X395900D01* +Y110000D01* +G37* +G36* +X401300D02*X405800D01* +Y104000D01* +X401300D01* +Y110000D01* +G37* +G36* +X406700D02*X411200D01* +Y104000D01* +X406700D01* +Y110000D01* +G37* +G36* +X412100D02*X416600D01* +Y104000D01* +X412100D01* +Y110000D01* +G37* +G36* +X417500D02*X422000D01* +Y104000D01* +X417500D01* +Y110000D01* +G37* +G36* +X422900D02*X427400D01* +Y104000D01* +X422900D01* +Y110000D01* +G37* +G36* +X428300D02*X432800D01* +Y104000D01* +X428300D01* +Y110000D01* +G37* +G54D22*X437150D02*Y104000D01* +X439100Y110000D02*X440150Y108950D01* +Y105050D01* +X439100Y104000D02*X440150Y105050D01* +X436400Y104000D02*X439100D01* +X436400Y110000D02*X439100D01* +G54D23*G36* +X441950D02*X446450D01* +Y104000D01* +X441950D01* +Y110000D01* +G37* +G36* +X447350D02*X451850D01* +Y104000D01* +X447350D01* +Y110000D01* +G37* +G36* +X452750D02*X457250D01* +Y104000D01* +X452750D01* +Y110000D01* +G37* +G36* +X458150D02*X462650D01* +Y104000D01* +X458150D01* +Y110000D01* +G37* +G36* +X463550D02*X468050D01* +Y104000D01* +X463550D01* +Y110000D01* +G37* +G36* +X468950D02*X473450D01* +Y104000D01* +X468950D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,25 @@ +G04 start of page 3 for group 3 layer_idx 0 * +G04 Title: smd elements on both sides, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD13C,0.0001*% +G54D13*G36* +X19154Y41240D02*X14036D01* +Y33760D01* +X19154D01* +Y41240D01* +G37* +G36* +X30964D02*X25846D01* +Y33760D01* +X30964D01* +Y41240D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.mask.none.2.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.mask.none.2.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.mask.none.2.gbr (revision 33253) @@ -0,0 +1,25 @@ +G04 start of page 5 for group 2 layer_idx 9 * +G04 Title: smd elements on both sides, top_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_MASK_NONE_2*% +%ADD15C,0.0001*% +G54D15*G36* +X19454Y41540D02*X13736D01* +Y33460D01* +X19454D01* +Y41540D01* +G37* +G36* +X31264D02*X25546D01* +Y33460D01* +X31264D01* +Y41540D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.paste.none.0.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.paste.none.0.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.paste.none.0.gbr (revision 33253) @@ -0,0 +1,25 @@ +G04 start of page 8 for group 0 layer_idx 11 * +G04 Title: smd elements on both sides, top_paste * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_PASTE_NONE_0*% +%ADD19C,0.0001*% +G54D19*G36* +X19154Y41240D02*X14036D01* +Y33760D01* +X19154D01* +Y41240D01* +G37* +G36* +X30964D02*X25846D01* +Y33760D01* +X30964D01* +Y41240D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.gbr/elem_sides_smd.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,26 @@ +G04 start of page 7 for group 1 layer_idx 8 * +G04 Title: smd elements on both sides, top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD18C,0.0070*% +%ADD17C,0.0080*% +G54D17*X20138Y41240D02*X24862D01* +X20138Y33760D02*X24862D01* +G54D18*X34350Y40650D02*X36350D01* +X36850Y40150D01* +Y39150D01* +X36350Y38650D02*X36850Y39150D01* +X34850Y38650D02*X36350D01* +X34850Y40650D02*Y36650D01* +X35650Y38650D02*X36850Y36650D01* +X38050Y39850D02*X38850Y40650D01* +Y36650D01* +X38050D02*X39550D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.nelma.em (revision 33253) @@ -0,0 +1,75 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} +layer substrate-11 { + height = 20 + z-order = 11 + material = "composite" +} +layer bottom { + height = 1 + z-order = 12 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top", + "substrate-11", + "bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.net =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.net (revision 33253) @@ -0,0 +1,16 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB smd elements on both sides +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +327N/C R1 -1 A01X+001659Y+003750X0511Y0748R000 S1 +327N/C R1 -2 A01X+002840Y+003750X0511Y0748R000 S1 +327N/C R2 -1 A02X+001659Y+001500X0511Y0748R000 S2 +327N/C R2 -2 A02X+002840Y+001500X0511Y0748R000 S2 +999 Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.png =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_sides_smd.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.png.text (revision 33253) @@ -0,0 +1,10 @@ +R1 +pad1 61 x 89 pixels (50.833x74.167) +pad2 61 x 89 pixels +pad1 to pad2 81 pixels (67.5) + +R2 - on the bottom +pad1 61 x 89 pixels +pad2 61 x 89 pixels + +(mils) Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_sides_smd.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_sides_smd.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.svg (revision 33253) @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/elem_sides_smd.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_smd.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_smd.xy (revision 33253) @@ -0,0 +1,10 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: smd elements on both sides - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- +R1,"Standard SMT resistor, capacitor etc","1206",225.00,375.00,0,top +R2,"Standard SMT resistor, capacitor etc","1206",225.00,150.00,180,bottom Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.bom (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: thru-hole elements on both sides - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +2,"dip(2)","2*300",U1 U2 Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.dsn (revision 33253) @@ -0,0 +1,124 @@ +(pcb thru-hole elements on both sides + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 5 + (place "U1" 2.540000 8.890000 front 0 (PN 0)) + ) + (component 37 + (place "U2" 2.540000 3.810000 back 0 (PN 0)) + ) + ) + (library + (image 5 + (pin Pstk_shape_7 "1" 0.000000 0.000000) + (pin Pstk_shape_8 "2" 7.620000 0.000000) + ) + (image 37 + (pin Pstk_shape_39 "1" 0.000000 0.000000) + (pin Pstk_shape_40 "2" -7.620000 0.000000) + ) + (padstack Pstk_shape_7 + (shape + (polygon "3__top_copper" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "5__Intern" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "7__Intern" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "10__bottom_copper" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + ) + (attach off) + ) + (padstack Pstk_shape_8 + (shape + (circle "3__top_copper" 2.032000) + (circle "5__Intern" 2.032000) + (circle "7__Intern" 2.032000) + (circle "10__bottom_copper" 2.032000) + ) + (attach off) + ) + (padstack Pstk_shape_39 + (shape + (polygon "3__top_copper" 0 + 1.016000 -1.016000 -1.016000 -1.016000 -1.016000 1.016000 + 1.016000 1.016000 + ) + (polygon "5__Intern" 0 + 1.016000 -1.016000 -1.016000 -1.016000 -1.016000 1.016000 + 1.016000 1.016000 + ) + (polygon "7__Intern" 0 + 1.016000 -1.016000 -1.016000 -1.016000 -1.016000 1.016000 + 1.016000 1.016000 + ) + (polygon "10__bottom_copper" 0 + 1.016000 -1.016000 -1.016000 -1.016000 -1.016000 1.016000 + 1.016000 1.016000 + ) + ) + (attach off) + ) + (padstack Pstk_shape_40 + (shape + (circle "3__top_copper" 2.032000) + (circle "5__Intern" 2.032000) + (circle "7__Intern" 2.032000) + (circle "10__bottom_copper" 2.032000) + ) + (attach off) + ) + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.eps (revision 33253) @@ -0,0 +1,136 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: elem_sides_trh.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.00000 setlinewidth +1 setlinecap +0.439216 0.439216 0.439216 setrgbcolor +0.06000 0.11000 moveto +0.14000 0.11000 lineto +0.14000 0.19000 lineto +0.06000 0.19000 lineto +fill +0.40000 0.15000 0.04000 c +0.06000 0.31000 moveto +0.14000 0.31000 lineto +0.14000 0.39000 lineto +0.06000 0.39000 lineto +fill +0.40000 0.35000 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.15000 0.01968 c +0.40000 0.15000 0.01968 c +0.10000 0.35000 0.01968 c +0.40000 0.35000 0.01968 c +% Layer group5 group 5 drill 0 mask 0 +0.00000 setlinewidth +0.439216 0.439216 0.439216 setrgbcolor +0.06000 0.11000 moveto +0.14000 0.11000 lineto +0.14000 0.19000 lineto +0.06000 0.19000 lineto +fill +0.40000 0.15000 0.04000 c +0.06000 0.31000 moveto +0.14000 0.31000 lineto +0.14000 0.39000 lineto +0.06000 0.39000 lineto +fill +0.40000 0.35000 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.15000 0.01968 c +0.40000 0.15000 0.01968 c +0.10000 0.35000 0.01968 c +0.40000 0.35000 0.01968 c +% Layer group7 group 7 drill 0 mask 0 +0.00000 setlinewidth +0.439216 0.439216 0.439216 setrgbcolor +0.06000 0.11000 moveto +0.14000 0.11000 lineto +0.14000 0.19000 lineto +0.06000 0.19000 lineto +fill +0.40000 0.15000 0.04000 c +0.06000 0.31000 moveto +0.14000 0.31000 lineto +0.14000 0.39000 lineto +0.06000 0.39000 lineto +fill +0.40000 0.35000 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.15000 0.01968 c +0.40000 0.15000 0.01968 c +0.10000 0.35000 0.01968 c +0.40000 0.35000 0.01968 c +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +0.25098 0.25098 0.25098 setrgbcolor +0.06000 0.11000 moveto +0.14000 0.11000 lineto +0.14000 0.19000 lineto +0.06000 0.19000 lineto +fill +0.40000 0.15000 0.04000 c +0.06000 0.31000 moveto +0.14000 0.31000 lineto +0.14000 0.39000 lineto +0.06000 0.39000 lineto +fill +0.40000 0.35000 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.15000 0.01968 c +0.40000 0.15000 0.01968 c +0.10000 0.35000 0.01968 c +0.40000 0.35000 0.01968 c +% Layer topsilk group 1 drill 0 mask 0 +0.01000 setlinewidth +0 0 0 setrgbcolor +0.05000 0.10000 0.05000 0.20000 t +0.45000 0.20000 0.05000 0.20000 t +0.45000 0.20000 0.45000 0.10000 t +0.05000 0.10000 0.20000 0.10000 t +0.30000 0.10000 0.45000 0.10000 t +0.000000 180.000000 -0.05000 0.05000 0.25000 0.10000 0.200000 a +0.00700 setlinewidth +0.10000 0.05000 0.10000 0.08500 t +0.10000 0.08500 0.10500 0.09000 t +0.10500 0.09000 0.11500 0.09000 t +0.11500 0.09000 0.12000 0.08500 t +0.12000 0.05000 0.12000 0.08500 t +0.13200 0.05800 0.14000 0.05000 t +0.14000 0.05000 0.14000 0.09000 t +0.13200 0.09000 0.14700 0.09000 t +% Layer plated-drill group -1 drill 1 mask 0 +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.15000 0.01968 c +0.40000 0.15000 0.01968 c +0.10000 0.35000 0.01968 c +0.40000 0.35000 0.01968 c +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.exc/elem_sides_trh.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.exc/elem_sides_trh.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.exc/elem_sides_trh.plated.cnc (revision 33253) @@ -0,0 +1,11 @@ +M48 +INCH +T11C0.039 +% +T11 +G05 +X001000Y003500 +X004000Y003500 +X001000Y001500 +X004000Y001500 +M30 Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.exc/elem_sides_trh.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.exc/elem_sides_trh.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.exc/elem_sides_trh.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,29 @@ +G04 start of page 6 for group 10 layer_idx 1 * +G04 Title: thru-hole elements on both sides, bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD24C,0.0394*% +%ADD23C,0.0800*% +%ADD22C,0.0001*% +G54D22*G36* +X6000Y39000D02*X14000D01* +Y31000D01* +X6000D01* +Y39000D01* +G37* +G54D23*X40000Y35000D03* +G54D22*G36* +X6000Y19000D02*X14000D01* +Y11000D01* +X6000D01* +Y19000D01* +G37* +G54D23*X40000Y15000D03* +G54D24*M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.bottom.mask.none.11.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.bottom.mask.none.11.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.bottom.mask.none.11.gbr (revision 33253) @@ -0,0 +1,28 @@ +G04 start of page 8 for group 11 layer_idx 10 * +G04 Title: thru-hole elements on both sides, bottom_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_MASK_NONE_11*% +%ADD28C,0.0860*% +%ADD27C,0.0001*% +G54D27*G36* +X5700Y39300D02*X14300D01* +Y30700D01* +X5700D01* +Y39300D01* +G37* +G54D28*X40000Y35000D03* +G54D27*G36* +X5700Y19300D02*X14300D01* +Y10700D01* +X5700D01* +Y19300D01* +G37* +G54D28*X40000Y15000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.bottom.silk.none.12.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.bottom.silk.none.12.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.bottom.silk.none.12.gbr (revision 33253) @@ -0,0 +1,31 @@ +G04 start of page 2 for group 12 layer_idx 7 * +G04 Title: thru-hole elements on both sides, bottom_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_SILK_NONE_12*% +%ADD12C,0.0070*% +%ADD11C,0.0100*% +G54D11*X5000Y10000D02*Y20000D01* +X45000D02*X5000D01* +X45000D02*Y10000D01* +X5000D02*X20000D01* +X30000D02*X45000D01* +X20000D02*G75*G02X30000Y10000I5000J0D01*G01* +G54D12*X10000Y5000D02*Y8500D01* +X10500Y9000D01* +X11500D01* +X12000Y8500D01* +Y5000D02*Y8500D01* +X13200Y5500D02*X13700Y5000D01* +X15200D01* +X15700Y5500D01* +Y6500D01* +X13200Y9000D02*X15700Y6500D01* +X13200Y9000D02*X15700D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 11 for group 9 layer_idx 6 * +G04 Title: thru-hole elements on both sides, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD32C,0.0100*% +G54D32*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.global.virtual.pdrill.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.global.virtual.pdrill.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.global.virtual.pdrill.none.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 10 for group -1 layer_idx 268435462 * +G04 Title: thru-hole elements on both sides, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_VIRTUAL_PDRILL_NONE*% +%ADD31C,0.0394*% +G54D31*X10000Y35000D03* +X40000D03* +X10000Y15000D03* +X40000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.intern.copper.none.5.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.intern.copper.none.5.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.intern.copper.none.5.gbr (revision 33253) @@ -0,0 +1,29 @@ +G04 start of page 4 for group 5 layer_idx 4 * +G04 Title: thru-hole elements on both sides, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_5*% +%ADD18C,0.0394*% +%ADD17C,0.0800*% +%ADD16C,0.0001*% +G54D16*G36* +X6000Y39000D02*X14000D01* +Y31000D01* +X6000D01* +Y39000D01* +G37* +G54D17*X40000Y35000D03* +G54D16*G36* +X6000Y19000D02*X14000D01* +Y11000D01* +X6000D01* +Y19000D01* +G37* +G54D17*X40000Y15000D03* +G54D18*M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.intern.copper.none.7.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.intern.copper.none.7.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.intern.copper.none.7.gbr (revision 33253) @@ -0,0 +1,29 @@ +G04 start of page 5 for group 7 layer_idx 5 * +G04 Title: thru-hole elements on both sides, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_7*% +%ADD21C,0.0394*% +%ADD20C,0.0800*% +%ADD19C,0.0001*% +G54D19*G36* +X6000Y39000D02*X14000D01* +Y31000D01* +X6000D01* +Y39000D01* +G37* +G54D20*X40000Y35000D03* +G54D19*G36* +X6000Y19000D02*X14000D01* +Y11000D01* +X6000D01* +Y19000D01* +G37* +G54D20*X40000Y15000D03* +G54D21*M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1893 @@ +G04 start of page 12 for group -1 layer_idx 268435461 * +G04 Title: thru-hole elements on both sides, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD36C,0.0100*% +%ADD35C,0.0001*% +%ADD34C,0.0060*% +%ADD33C,0.0080*% +G54D33*X10000Y35000D02*Y33400D01* +Y35000D02*X11387Y35800D01* +X10000Y35000D02*X8613Y35800D01* +X40000Y35000D02*Y33400D01* +Y35000D02*X41387Y35800D01* +X40000Y35000D02*X38613Y35800D01* +X10000Y15000D02*Y13400D01* +Y15000D02*X11387Y15800D01* +X10000Y15000D02*X8613Y15800D01* +X40000Y15000D02*Y13400D01* +Y15000D02*X41387Y15800D01* +X40000Y15000D02*X38613Y15800D01* +X15000Y106250D02*Y104650D01* +Y106250D02*X16387Y107050D01* +X15000Y106250D02*X13613Y107050D01* +G54D34*X135000Y110000D02*X136500Y107000D01* +X138000Y110000D01* +X136500Y107000D02*Y104000D01* +X139800Y107300D02*X142050D01* +X139800Y104000D02*X142800D01* +X139800Y110000D02*Y104000D01* +Y110000D02*X142800D01* +X147600D02*X148350Y109250D01* +X145350Y110000D02*X147600D01* +X144600Y109250D02*X145350Y110000D01* +X144600Y109250D02*Y107750D01* +X145350Y107000D01* +X147600D01* +X148350Y106250D01* +Y104750D01* +X147600Y104000D02*X148350Y104750D01* +X145350Y104000D02*X147600D01* +X144600Y104750D02*X145350Y104000D01* +X98000Y106250D02*X101000Y110000D01* +X98000Y106250D02*X101750D01* +X101000Y110000D02*Y104000D01* +G54D35*G36* +X45000Y110000D02*X49500D01* +Y104000D01* +X45000D01* +Y110000D01* +G37* +G36* +X50400D02*X54900D01* +Y104000D01* +X50400D01* +Y110000D01* +G37* +G36* +X55800D02*X60300D01* +Y104000D01* +X55800D01* +Y110000D01* +G37* +G54D34*X61200Y109250D02*X61950Y110000D01* +X63450D01* +X64200Y109250D01* +X63450Y104000D02*X64200Y104750D01* +X61950Y104000D02*X63450D01* +X61200Y104750D02*X61950Y104000D01* +Y107300D02*X63450D01* +X64200Y109250D02*Y108050D01* +Y106550D02*Y104750D01* +Y106550D02*X63450Y107300D01* +X64200Y108050D02*X63450Y107300D01* +X66750Y104000D02*X69000Y107000D01* +Y109250D02*Y107000D01* +X68250Y110000D02*X69000Y109250D01* +X66750Y110000D02*X68250D01* +X66000Y109250D02*X66750Y110000D01* +X66000Y109250D02*Y107750D01* +X66750Y107000D01* +X69000D01* +X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D35*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D34*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D35*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D34*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D35*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D34*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D35*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D34*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D35*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D34*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D35*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G54D34*X48000Y138800D02*X49200Y140000D01* +Y134000D01* +X48000D02*X50250D01* +G54D35*G36* +X54750Y140000D02*X59250D01* +Y134000D01* +X54750D01* +Y140000D01* +G37* +G36* +X60150D02*X64650D01* +Y134000D01* +X60150D01* +Y140000D01* +G37* +G36* +X65550D02*X70050D01* +Y134000D01* +X65550D01* +Y140000D01* +G37* +G36* +X70950D02*X75450D01* +Y134000D01* +X70950D01* +Y140000D01* +G37* +G36* +X76350D02*X80850D01* +Y134000D01* +X76350D01* +Y140000D01* +G37* +G36* +X81750D02*X86250D01* +Y134000D01* +X81750D01* +Y140000D01* +G37* +G36* +X87150D02*X91650D01* +Y134000D01* +X87150D01* +Y140000D01* +G37* +G36* +X92550D02*X97050D01* +Y134000D01* +X92550D01* +Y140000D01* +G37* +G36* +X97950D02*X102450D01* +Y134000D01* +X97950D01* +Y140000D01* +G37* +G36* +X106050D02*X110550D01* +Y134000D01* +X106050D01* +Y140000D01* +G37* +G36* +X111450D02*X115950D01* +Y134000D01* +X111450D01* +Y140000D01* +G37* +G36* +X116850D02*X121350D01* +Y134000D01* +X116850D01* +Y140000D01* +G37* +G36* +X122250D02*X126750D01* +Y134000D01* +X122250D01* +Y140000D01* +G37* +G36* +X127650D02*X132150D01* +Y134000D01* +X127650D01* +Y140000D01* +G37* +G36* +X135750D02*X140250D01* +Y134000D01* +X135750D01* +Y140000D01* +G37* +G36* +X141150D02*X145650D01* +Y134000D01* +X141150D01* +Y140000D01* +G37* +G36* +X146550D02*X151050D01* +Y134000D01* +X146550D01* +Y140000D01* +G37* +G36* +X151950D02*X156450D01* +Y134000D01* +X151950D01* +Y140000D01* +G37* +G36* +X157350D02*X161850D01* +Y134000D01* +X157350D01* +Y140000D01* +G37* +G36* +X165450D02*X169950D01* +Y134000D01* +X165450D01* +Y140000D01* +G37* +G36* +X170850D02*X175350D01* +Y134000D01* +X170850D01* +Y140000D01* +G37* +G36* +X176250D02*X180750D01* +Y134000D01* +X176250D01* +Y140000D01* +G37* +G36* +X181650D02*X186150D01* +Y134000D01* +X181650D01* +Y140000D01* +G37* +G36* +X189750D02*X194250D01* +Y134000D01* +X189750D01* +Y140000D01* +G37* +G36* +X195150D02*X199650D01* +Y134000D01* +X195150D01* +Y140000D01* +G37* +G36* +X203250D02*X207750D01* +Y134000D01* +X203250D01* +Y140000D01* +G37* +G36* +X208650D02*X213150D01* +Y134000D01* +X208650D01* +Y140000D01* +G37* +G36* +X214050D02*X218550D01* +Y134000D01* +X214050D01* +Y140000D01* +G37* +G36* +X219450D02*X223950D01* +Y134000D01* +X219450D01* +Y140000D01* +G37* +G36* +X227550D02*X232050D01* +Y134000D01* +X227550D01* +Y140000D01* +G37* +G36* +X232950D02*X237450D01* +Y134000D01* +X232950D01* +Y140000D01* +G37* +G36* +X238350D02*X242850D01* +Y134000D01* +X238350D01* +Y140000D01* +G37* +G36* +X243750D02*X248250D01* +Y134000D01* +X243750D01* +Y140000D01* +G37* +G36* +X249150D02*X253650D01* +Y134000D01* +X249150D01* +Y140000D01* +G37* +G36* +X254550D02*X259050D01* +Y134000D01* +X254550D01* +Y140000D01* +G37* +G36* +X259950D02*X264450D01* +Y134000D01* +X259950D01* +Y140000D01* +G37* +G54D34*X268050Y136250D02*X271050Y140000D01* +X268050Y136250D02*X271800D01* +X271050Y140000D02*Y134000D01* +G54D35*G36* +X276300Y140000D02*X280800D01* +Y134000D01* +X276300D01* +Y140000D01* +G37* +G36* +X281700D02*X286200D01* +Y134000D01* +X281700D01* +Y140000D01* +G37* +G36* +X287100D02*X291600D01* +Y134000D01* +X287100D01* +Y140000D01* +G37* +G36* +X292500D02*X297000D01* +Y134000D01* +X292500D01* +Y140000D01* +G37* +G36* +X297900D02*X302400D01* +Y134000D01* +X297900D01* +Y140000D01* +G37* +G36* +X306000D02*X310500D01* +Y134000D01* +X306000D01* +Y140000D01* +G37* +G36* +X311400D02*X315900D01* +Y134000D01* +X311400D01* +Y140000D01* +G37* +G36* +X316800D02*X321300D01* +Y134000D01* +X316800D01* +Y140000D01* +G37* +G36* +X322200D02*X326700D01* +Y134000D01* +X322200D01* +Y140000D01* +G37* +G36* +X327600D02*X332100D01* +Y134000D01* +X327600D01* +Y140000D01* +G37* +G54D36*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D34*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D35*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D34*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D35*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D34*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D35*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D34*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D35*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D34*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D35*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D34*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D35*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D34*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D35*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D34*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D35*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D34*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D35*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D34*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D35*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D34*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D35*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X256100D02*X260600D01* +Y104000D01* +X256100D01* +Y110000D01* +G37* +G36* +X261500D02*X266000D01* +Y104000D01* +X261500D01* +Y110000D01* +G37* +G36* +X266900D02*X271400D01* +Y104000D01* +X266900D01* +Y110000D01* +G37* +G36* +X272300D02*X276800D01* +Y104000D01* +X272300D01* +Y110000D01* +G37* +G36* +X277700D02*X282200D01* +Y104000D01* +X277700D01* +Y110000D01* +G37* +G36* +X285800D02*X290300D01* +Y104000D01* +X285800D01* +Y110000D01* +G37* +G36* +X291200D02*X295700D01* +Y104000D01* +X291200D01* +Y110000D01* +G37* +G36* +X296600D02*X301100D01* +Y104000D01* +X296600D01* +Y110000D01* +G37* +G36* +X302000D02*X306500D01* +Y104000D01* +X302000D01* +Y110000D01* +G37* +G36* +X307400D02*X311900D01* +Y104000D01* +X307400D01* +Y110000D01* +G37* +G36* +X312800D02*X317300D01* +Y104000D01* +X312800D01* +Y110000D01* +G37* +G36* +X318200D02*X322700D01* +Y104000D01* +X318200D01* +Y110000D01* +G37* +G36* +X323600D02*X328100D01* +Y104000D01* +X323600D01* +Y110000D01* +G37* +G36* +X331700D02*X336200D01* +Y104000D01* +X331700D01* +Y110000D01* +G37* +G36* +X337100D02*X341600D01* +Y104000D01* +X337100D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X356000D02*X360500D01* +Y104000D01* +X356000D01* +Y110000D01* +G37* +G36* +X361400D02*X365900D01* +Y104000D01* +X361400D01* +Y110000D01* +G37* +G36* +X369500D02*X374000D01* +Y104000D01* +X369500D01* +Y110000D01* +G37* +G36* +X374900D02*X379400D01* +Y104000D01* +X374900D01* +Y110000D01* +G37* +G36* +X380300D02*X384800D01* +Y104000D01* +X380300D01* +Y110000D01* +G37* +G36* +X385700D02*X390200D01* +Y104000D01* +X385700D01* +Y110000D01* +G37* +G36* +X391100D02*X395600D01* +Y104000D01* +X391100D01* +Y110000D01* +G37* +G36* +X399200D02*X403700D01* +Y104000D01* +X399200D01* +Y110000D01* +G37* +G54D34*X407300D02*Y104000D01* +Y110000D02*X410300D01* +X407300Y107300D02*X409550D01* +G54D35*G36* +X412100Y110000D02*X416600D01* +Y104000D01* +X412100D01* +Y110000D01* +G37* +G36* +X417500D02*X422000D01* +Y104000D01* +X417500D01* +Y110000D01* +G37* +G36* +X422900D02*X427400D01* +Y104000D01* +X422900D01* +Y110000D01* +G37* +G36* +X428300D02*X432800D01* +Y104000D01* +X428300D01* +Y110000D01* +G37* +G36* +X433700D02*X438200D01* +Y104000D01* +X433700D01* +Y110000D01* +G37* +G36* +X439100D02*X443600D01* +Y104000D01* +X439100D01* +Y110000D01* +G37* +G36* +X444500D02*X449000D01* +Y104000D01* +X444500D01* +Y110000D01* +G37* +G36* +X449900D02*X454400D01* +Y104000D01* +X449900D01* +Y110000D01* +G37* +G36* +X455300D02*X459800D01* +Y104000D01* +X455300D01* +Y110000D01* +G37* +G36* +X460700D02*X465200D01* +Y104000D01* +X460700D01* +Y110000D01* +G37* +G54D34*X469550D02*Y104000D01* +X471500Y110000D02*X472550Y108950D01* +Y105050D01* +X471500Y104000D02*X472550Y105050D01* +X468800Y104000D02*X471500D01* +X468800Y110000D02*X471500D01* +G54D35*G36* +X474350D02*X478850D01* +Y104000D01* +X474350D01* +Y110000D01* +G37* +G36* +X479750D02*X484250D01* +Y104000D01* +X479750D01* +Y110000D01* +G37* +G36* +X485150D02*X489650D01* +Y104000D01* +X485150D01* +Y110000D01* +G37* +G36* +X490550D02*X495050D01* +Y104000D01* +X490550D01* +Y110000D01* +G37* +G36* +X495950D02*X500450D01* +Y104000D01* +X495950D01* +Y110000D01* +G37* +G36* +X501350D02*X505850D01* +Y104000D01* +X501350D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,29 @@ +G04 start of page 3 for group 3 layer_idx 0 * +G04 Title: thru-hole elements on both sides, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD15C,0.0394*% +%ADD14C,0.0800*% +%ADD13C,0.0001*% +G54D13*G36* +X6000Y39000D02*X14000D01* +Y31000D01* +X6000D01* +Y39000D01* +G37* +G54D14*X40000Y35000D03* +G54D13*G36* +X6000Y19000D02*X14000D01* +Y11000D01* +X6000D01* +Y19000D01* +G37* +G54D14*X40000Y15000D03* +G54D15*M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.top.mask.none.2.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.top.mask.none.2.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.top.mask.none.2.gbr (revision 33253) @@ -0,0 +1,28 @@ +G04 start of page 7 for group 2 layer_idx 9 * +G04 Title: thru-hole elements on both sides, top_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_MASK_NONE_2*% +%ADD26C,0.0860*% +%ADD25C,0.0001*% +G54D25*G36* +X5700Y39300D02*X14300D01* +Y30700D01* +X5700D01* +Y39300D01* +G37* +G54D26*X40000Y35000D03* +G54D25*G36* +X5700Y19300D02*X14300D01* +Y10700D01* +X5700D01* +Y19300D01* +G37* +G54D26*X40000Y15000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.gbr/elem_sides_trh.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,28 @@ +G04 start of page 9 for group 1 layer_idx 8 * +G04 Title: thru-hole elements on both sides, top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD30C,0.0070*% +%ADD29C,0.0100*% +G54D29*X5000Y40000D02*Y30000D01* +X45000D02*X5000D01* +X45000D02*Y40000D01* +X5000D02*X20000D01* +X30000D02*X45000D01* +X20000D02*G75*G03X30000Y40000I5000J0D01*G01* +G54D30*X10000Y45000D02*Y41500D01* +X10500Y41000D01* +X11500D01* +X12000Y41500D01* +Y45000D02*Y41500D01* +X13200Y44200D02*X14000Y45000D01* +Y41000D01* +X13200D02*X14700D01* +M02* Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.nelma.em (revision 33253) @@ -0,0 +1,51 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.net =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.net (revision 33253) @@ -0,0 +1,16 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB thru-hole elements on both sides +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +317N/C U1 -1 D0393PA00X+001000Y+003500X0800Y0800R000 S0 +317N/C U1 -2 D0393PA00X+004000Y+003500X0800Y0000R000 S0 +317N/C U2 -1 D0393PA00X+001000Y+001500X0800Y0800R000 S0 +317N/C U2 -2 D0393PA00X+004000Y+001500X0800Y0000R000 S0 +999 Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.png =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_sides_trh.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.png.text (revision 33253) @@ -0,0 +1,17 @@ +r6630 + +U1 +6 x 6 pixel (5x5) distance from silk inside top corner to pin 1 +pin 1 dimensions 96 x 96 pixels (80x80) +pin 2 97 pixel diameter circle (80.833) +pin 1 to pin 2 distance 264 pixels (220) + +U2 +pin 1 is 144 pixels (120) down from U1 Pin 1 +pin 1 is 96 x 96 pixels (80x80) +pin 2 is an 97 pixel circle (80.833) +pin 1 to pin 2 distance 264 pixels (220) + + +(mil) + Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_sides_trh.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/elem_sides_trh.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.svg (revision 33253) @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/elem_sides_trh.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/elem_sides_trh.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/elem_sides_trh.xy (revision 33253) @@ -0,0 +1,10 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: thru-hole elements on both sides - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- +U1,"dip(2)","2*300",250.00,350.00,0,top +U2,"dip(2)","2*300",250.00,150.00,180,bottom Index: tags/2.3.0/tests/RTT/ref/flag_colors.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.bom (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: (unknown) - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +4,"0402 Standard SMT resistor, capacitor etc","(unknown)",(unknown) (unknown) (unknown) (unknown) Index: tags/2.3.0/tests/RTT/ref/flag_colors.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.dsn (revision 33253) @@ -0,0 +1,176 @@ +(pcb notnamed + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 16.510000 15.875000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 274 + (place "null" 5.715000 1.270000 front 0 (PN 0)) + ) + (component 291 + (place "null" 8.255000 1.270000 front 0 (PN 0)) + ) + (component 308 + (place "null" 10.795000 1.270000 front 0 (PN 0)) + ) + (component 325 + (place "null" 13.335000 1.270000 front 0 (PN 0)) + ) + (component 95 + (place 95 2.540000 13.335000 front 0 (PN 0)) + ) + (component 96 + (place 96 6.350000 13.335000 front 0 (PN 0)) + ) + (component 97 + (place 97 2.540000 10.160000 front 0 (PN 0)) + ) + (component 173 + (place 173 6.350000 10.160000 front 0 (PN 0)) + ) + ) + (library + (image 274 + (pin Pstk_shape_288 "1" -0.399796 0.000000) + (pin Pstk_shape_289 "2" 0.399796 0.000000) + ) + (image 291 + (pin Pstk_shape_305 "1" -0.399796 0.000000) + (pin Pstk_shape_306 "2" 0.399796 0.000000) + ) + (image 308 + (pin Pstk_shape_322 "1" -0.399796 0.000000) + (pin Pstk_shape_323 "2" 0.399796 0.000000) + ) + (image 325 + (pin Pstk_shape_339 "1" -0.399796 0.000000) + (pin Pstk_shape_340 "2" 0.399796 0.000000) + ) + (padstack Pstk_shape_288 + (shape + (polygon "3__top_copper" 0 + 0.249936 0.349758 -0.249936 0.349758 -0.249936 -0.349758 + 0.249936 -0.349758 + ) + ) + (attach off) + ) + (padstack Pstk_shape_289 + (shape + (polygon "3__top_copper" 0 + 0.249936 0.349758 -0.249936 0.349758 -0.249936 -0.349758 + 0.249936 -0.349758 + ) + ) + (attach off) + ) + (padstack Pstk_shape_305 + (shape + (polygon "3__top_copper" 0 + 0.249936 0.349758 -0.249936 0.349758 -0.249936 -0.349758 + 0.249936 -0.349758 + ) + ) + (attach off) + ) + (padstack Pstk_shape_306 + (shape + (polygon "3__top_copper" 0 + 0.249936 0.349758 -0.249936 0.349758 -0.249936 -0.349758 + 0.249936 -0.349758 + ) + ) + (attach off) + ) + (padstack Pstk_shape_322 + (shape + (polygon "3__top_copper" 0 + 0.249936 0.349758 -0.249936 0.349758 -0.249936 -0.349758 + 0.249936 -0.349758 + ) + ) + (attach off) + ) + (padstack Pstk_shape_323 + (shape + (polygon "3__top_copper" 0 + 0.249936 0.349758 -0.249936 0.349758 -0.249936 -0.349758 + 0.249936 -0.349758 + ) + ) + (attach off) + ) + (padstack Pstk_shape_339 + (shape + (polygon "3__top_copper" 0 + 0.249936 0.349758 -0.249936 0.349758 -0.249936 -0.349758 + 0.249936 -0.349758 + ) + ) + (attach off) + ) + (padstack Pstk_shape_340 + (shape + (polygon "3__top_copper" 0 + 0.249936 0.349758 -0.249936 0.349758 -0.249936 -0.349758 + 0.249936 -0.349758 + ) + ) + (attach off) + ) + ) + (network + (class pcb_rnd_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 0.254000 4.445000 10.160000 6.350000 10.160000) + (type protect)) + (wire (path 3__top_copper 0.254000 6.350000 10.160000 6.985000 10.795000) + (type protect)) + (wire (path 3__top_copper 0.254000 6.985000 10.795000 6.985000 11.430000) + (type protect)) + (wire (path 3__top_copper 0.254000 8.890000 15.240000 13.970000 15.240000) + (type protect)) + (wire (path 3__top_copper 0.254000 8.890000 13.970000 13.970000 13.970000) + (type protect)) + (wire (path 3__top_copper 0.254000 8.890000 12.700000 13.970000 12.700000) + (type protect)) + (wire (path 3__top_copper 0.254000 8.890000 11.430000 13.970000 11.430000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/flag_colors.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.eps (revision 33253) @@ -0,0 +1,471 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 47.800000 46.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: flag_colors.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.62500 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.63500 lineto 0.66000 0.63500 lineto 0.66000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.00000 setlinewidth +1 setlinecap +0.627451 0.627451 0.627451 setrgbcolor +0.10000 0.10000 0.03937 c +0.25000 0.10000 0.03937 c +0.10000 0.22500 0.03937 c +0.25000 0.22500 0.03937 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +0.25000 0.10000 0.01575 c +0.10000 0.22500 0.01575 c +0.25000 0.22500 0.01575 c +% Layer group5 group 5 drill 0 mask 0 +0.00000 setlinewidth +0.627451 0.627451 0.627451 setrgbcolor +0.10000 0.10000 0.03937 c +0.25000 0.10000 0.03937 c +0.10000 0.22500 0.03937 c +0.25000 0.22500 0.03937 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +0.25000 0.10000 0.01575 c +0.10000 0.22500 0.01575 c +0.25000 0.22500 0.01575 c +% Layer group7 group 7 drill 0 mask 0 +0.00000 setlinewidth +0.627451 0.627451 0.627451 setrgbcolor +0.10000 0.10000 0.03937 c +0.25000 0.10000 0.03937 c +0.10000 0.22500 0.03937 c +0.25000 0.22500 0.03937 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +0.25000 0.10000 0.01575 c +0.10000 0.22500 0.01575 c +0.25000 0.22500 0.01575 c +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.17108 0.20023 moveto +0.16725 0.20115 lineto +0.16362 0.20266 lineto +0.16026 0.20471 lineto +0.15727 0.20727 lineto +0.15690 0.20770 lineto +0.15664 0.20660 lineto +0.15306 0.19796 lineto +0.14818 0.19000 lineto +0.14211 0.18289 lineto +0.13500 0.17682 lineto +0.12704 0.17194 lineto +0.11840 0.16836 lineto +0.10932 0.16618 lineto +0.10000 0.16545 lineto +0.09991 0.16545 lineto +0.09991 0.15955 lineto +0.10000 0.15955 lineto +0.10932 0.15882 lineto +0.11840 0.15664 lineto +0.12704 0.15306 lineto +0.13500 0.14818 lineto +0.14211 0.14211 lineto +0.14818 0.13500 lineto +0.15306 0.12704 lineto +0.15664 0.11840 lineto +0.15882 0.10932 lineto +0.15937 0.10000 lineto +0.15882 0.09068 lineto +0.15664 0.08160 lineto +0.15306 0.07296 lineto +0.14818 0.06500 lineto +0.14211 0.05789 lineto +0.13500 0.05182 lineto +0.12704 0.04694 lineto +0.11840 0.04336 lineto +0.10932 0.04118 lineto +0.10000 0.04045 lineto +0.09991 0.04045 lineto +0.09991 0.02500 lineto +0.32492 0.02500 lineto +0.32500 0.02598 lineto +0.32500 0.07402 lineto +0.32492 0.07500 lineto +0.32500 0.07598 lineto +0.32500 0.12402 lineto +0.32492 0.12500 lineto +0.32500 0.12598 lineto +0.32500 0.17402 lineto +0.32492 0.17500 lineto +0.32500 0.17598 lineto +0.32500 0.27282 lineto +0.32490 0.27500 lineto +0.28203 0.27500 lineto +0.28500 0.27318 lineto +0.29211 0.26711 lineto +0.29818 0.26000 lineto +0.30306 0.25204 lineto +0.30664 0.24340 lineto +0.30882 0.23432 lineto +0.30937 0.22500 lineto +0.30882 0.21568 lineto +0.30664 0.20660 lineto +0.30306 0.19796 lineto +0.30000 0.19297 lineto +0.30000 0.17500 lineto +0.29977 0.17108 lineto +0.29885 0.16725 lineto +0.29734 0.16362 lineto +0.29529 0.16026 lineto +0.29273 0.15727 lineto +0.28974 0.15471 lineto +0.28638 0.15266 lineto +0.28275 0.15115 lineto +0.28089 0.15070 lineto +0.28500 0.14818 lineto +0.29211 0.14211 lineto +0.29818 0.13500 lineto +0.30306 0.12704 lineto +0.30664 0.11840 lineto +0.30882 0.10932 lineto +0.30937 0.10000 lineto +0.30882 0.09068 lineto +0.30664 0.08160 lineto +0.30306 0.07296 lineto +0.29818 0.06500 lineto +0.29211 0.05789 lineto +0.28500 0.05182 lineto +0.27704 0.04694 lineto +0.26840 0.04336 lineto +0.25932 0.04118 lineto +0.25000 0.04045 lineto +0.24068 0.04118 lineto +0.23160 0.04336 lineto +0.22296 0.04694 lineto +0.21500 0.05182 lineto +0.20789 0.05789 lineto +0.20182 0.06500 lineto +0.19694 0.07296 lineto +0.19336 0.08160 lineto +0.19118 0.09068 lineto +0.19045 0.10000 lineto +0.19118 0.10932 lineto +0.19336 0.11840 lineto +0.19694 0.12704 lineto +0.20182 0.13500 lineto +0.20789 0.14211 lineto +0.21500 0.14818 lineto +0.22296 0.15306 lineto +0.23160 0.15664 lineto +0.24068 0.15882 lineto +0.25000 0.15955 lineto +0.25570 0.15910 lineto +0.25471 0.16026 lineto +0.25266 0.16362 lineto +0.25184 0.16559 lineto +0.25000 0.16545 lineto +0.24068 0.16618 lineto +0.23160 0.16836 lineto +0.22296 0.17194 lineto +0.21500 0.17682 lineto +0.20789 0.18289 lineto +0.20182 0.19000 lineto +0.19694 0.19796 lineto +0.19609 0.20000 lineto +0.17500 0.20000 lineto +fill +0.09068 0.16618 moveto +0.08160 0.16836 lineto +0.07296 0.17194 lineto +0.06500 0.17682 lineto +0.05789 0.18289 lineto +0.05182 0.19000 lineto +0.04694 0.19796 lineto +0.04336 0.20660 lineto +0.04118 0.21568 lineto +0.04045 0.22500 lineto +0.04118 0.23432 lineto +0.04336 0.24340 lineto +0.04694 0.25204 lineto +0.05182 0.26000 lineto +0.05789 0.26711 lineto +0.06500 0.27318 lineto +0.06797 0.27500 lineto +0.02500 0.27500 lineto +0.02500 0.02500 lineto +0.09991 0.02500 lineto +0.09991 0.04045 lineto +0.09068 0.04118 lineto +0.08160 0.04336 lineto +0.07296 0.04694 lineto +0.06500 0.05182 lineto +0.05789 0.05789 lineto +0.05182 0.06500 lineto +0.04694 0.07296 lineto +0.04336 0.08160 lineto +0.04118 0.09068 lineto +0.04045 0.10000 lineto +0.04118 0.10932 lineto +0.04336 0.11840 lineto +0.04694 0.12704 lineto +0.05182 0.13500 lineto +0.05789 0.14211 lineto +0.06500 0.14818 lineto +0.07296 0.15306 lineto +0.08160 0.15664 lineto +0.09068 0.15882 lineto +0.09991 0.15955 lineto +0.09991 0.16545 lineto +fill +0.30000 0.32500 moveto +0.30000 0.52500 lineto +0.25000 0.52500 lineto +0.25000 0.32500 lineto +fill +0.37500 0.32500 moveto +0.37500 0.52500 lineto +0.32500 0.52500 lineto +0.32500 0.32500 lineto +fill +0.45000 0.32500 moveto +0.45000 0.52500 lineto +0.40000 0.52500 lineto +0.40000 0.32500 lineto +fill +0.52500 0.32500 moveto +0.52500 0.52500 lineto +0.47500 0.52500 lineto +0.47500 0.32500 lineto +fill +0.01000 setlinewidth +1 setlinecap +0.17500 0.22500 0.25000 0.22500 t +0.25000 0.22500 0.27500 0.20000 t +0.27500 0.20000 0.27500 0.17500 t +0.35000 0.02500 0.55000 0.02500 t +0.35000 0.17500 0.55000 0.17500 t +0.35000 0.07500 0.55000 0.07500 t +0.35000 0.12500 0.55000 0.12500 t +-90.000000 0.000000 -0.07500 0.07500 0.42500 0.27500 0.133333 a +-90.000000 0.000000 -0.07500 0.07500 0.47500 0.27500 0.133333 a +-90.000000 0.000000 -0.07500 0.07500 0.52500 0.27500 0.133333 a +-90.000000 0.000000 -0.07500 0.07500 0.57500 0.27500 0.133333 a +0.05000 0.30000 0.07000 0.30000 t +0.06000 0.30000 0.06000 0.34000 t +0.08200 0.31800 0.09700 0.31800 t +0.08200 0.34000 0.10200 0.34000 t +0.08200 0.30000 0.08200 0.34000 t +0.08200 0.30000 0.10200 0.30000 t +0.13400 0.30000 0.13900 0.30500 t +0.11900 0.30000 0.13400 0.30000 t +0.11400 0.30500 0.11900 0.30000 t +0.11400 0.30500 0.11400 0.31500 t +0.11400 0.31500 0.11900 0.32000 t +0.11900 0.32000 0.13400 0.32000 t +0.13400 0.32000 0.13900 0.32500 t +0.13900 0.32500 0.13900 0.33500 t +0.13400 0.34000 0.13900 0.33500 t +0.11900 0.34000 0.13400 0.34000 t +0.11400 0.33500 0.11900 0.34000 t +0.15100 0.30000 0.17100 0.30000 t +0.16100 0.30000 0.16100 0.34000 t +0.05000 0.37500 0.07000 0.37500 t +0.06000 0.37500 0.06000 0.41500 t +0.08200 0.39300 0.09700 0.39300 t +0.08200 0.41500 0.10200 0.41500 t +0.08200 0.37500 0.08200 0.41500 t +0.08200 0.37500 0.10200 0.37500 t +0.13400 0.37500 0.13900 0.38000 t +0.11900 0.37500 0.13400 0.37500 t +0.11400 0.38000 0.11900 0.37500 t +0.11400 0.38000 0.11400 0.39000 t +0.11400 0.39000 0.11900 0.39500 t +0.11900 0.39500 0.13400 0.39500 t +0.13400 0.39500 0.13900 0.40000 t +0.13900 0.40000 0.13900 0.41000 t +0.13400 0.41500 0.13900 0.41000 t +0.11900 0.41500 0.13400 0.41500 t +0.11400 0.41000 0.11900 0.41500 t +0.15100 0.37500 0.17100 0.37500 t +0.16100 0.37500 0.16100 0.41500 t +0.05000 0.45000 0.07000 0.45000 t +0.06000 0.45000 0.06000 0.49000 t +0.08200 0.46800 0.09700 0.46800 t +0.08200 0.49000 0.10200 0.49000 t +0.08200 0.45000 0.08200 0.49000 t +0.08200 0.45000 0.10200 0.45000 t +0.13400 0.45000 0.13900 0.45500 t +0.11900 0.45000 0.13400 0.45000 t +0.11400 0.45500 0.11900 0.45000 t +0.11400 0.45500 0.11400 0.46500 t +0.11400 0.46500 0.11900 0.47000 t +0.11900 0.47000 0.13400 0.47000 t +0.13400 0.47000 0.13900 0.47500 t +0.13900 0.47500 0.13900 0.48500 t +0.13400 0.49000 0.13900 0.48500 t +0.11900 0.49000 0.13400 0.49000 t +0.11400 0.48500 0.11900 0.49000 t +0.15100 0.45000 0.17100 0.45000 t +0.16100 0.45000 0.16100 0.49000 t +0.05000 0.52500 0.07000 0.52500 t +0.06000 0.52500 0.06000 0.56500 t +0.08200 0.54300 0.09700 0.54300 t +0.08200 0.56500 0.10200 0.56500 t +0.08200 0.52500 0.08200 0.56500 t +0.08200 0.52500 0.10200 0.52500 t +0.13400 0.52500 0.13900 0.53000 t +0.11900 0.52500 0.13400 0.52500 t +0.11400 0.53000 0.11900 0.52500 t +0.11400 0.53000 0.11400 0.54000 t +0.11400 0.54000 0.11900 0.54500 t +0.11900 0.54500 0.13400 0.54500 t +0.13400 0.54500 0.13900 0.55000 t +0.13900 0.55000 0.13900 0.56000 t +0.13400 0.56500 0.13900 0.56000 t +0.11900 0.56500 0.13400 0.56500 t +0.11400 0.56000 0.11900 0.56500 t +0.15100 0.52500 0.17100 0.52500 t +0.16100 0.52500 0.16100 0.56500 t +0.627451 0.627451 0.627451 setrgbcolor +0.10000 0.10000 0.03937 c +0.25000 0.10000 0.03937 c +0.10000 0.22500 0.03937 c +0.25000 0.22500 0.03937 c +0.439216 0.439216 0.439216 setrgbcolor +0.21910 0.56123 moveto +0.19942 0.56123 lineto +0.19942 0.58877 lineto +0.21910 0.58877 lineto +fill +0.25058 0.56123 moveto +0.23090 0.56123 lineto +0.23090 0.58877 lineto +0.25058 0.58877 lineto +fill +0.31910 0.56123 moveto +0.29942 0.56123 lineto +0.29942 0.58877 lineto +0.31910 0.58877 lineto +fill +0.35058 0.56123 moveto +0.33090 0.56123 lineto +0.33090 0.58877 lineto +0.35058 0.58877 lineto +fill +0.41910 0.56123 moveto +0.39942 0.56123 lineto +0.39942 0.58877 lineto +0.41910 0.58877 lineto +fill +0.45058 0.56123 moveto +0.43090 0.56123 lineto +0.43090 0.58877 lineto +0.45058 0.58877 lineto +fill +0.51910 0.56123 moveto +0.49942 0.56123 lineto +0.49942 0.58877 lineto +0.51910 0.58877 lineto +fill +0.55058 0.56123 moveto +0.53090 0.56123 lineto +0.53090 0.58877 lineto +0.55058 0.58877 lineto +fill +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +0.25000 0.10000 0.01575 c +0.10000 0.22500 0.01575 c +0.25000 0.22500 0.01575 c +% Layer topsilk group 1 drill 0 mask 0 +0.01000 setlinewidth +0 0 0 setrgbcolor +0.19350 0.54350 moveto +0.22350 0.54350 lineto +0.22350 0.58350 lineto +0.19350 0.58350 lineto +fill +0.22950 0.54350 moveto +0.25950 0.54350 lineto +0.25950 0.58350 lineto +0.22950 0.58350 lineto +fill +0.26550 0.54350 moveto +0.29550 0.54350 lineto +0.29550 0.58350 lineto +0.26550 0.58350 lineto +fill +0.29350 0.54350 moveto +0.32350 0.54350 lineto +0.32350 0.58350 lineto +0.29350 0.58350 lineto +fill +0.32950 0.54350 moveto +0.35950 0.54350 lineto +0.35950 0.58350 lineto +0.32950 0.58350 lineto +fill +0.36550 0.54350 moveto +0.39550 0.54350 lineto +0.39550 0.58350 lineto +0.36550 0.58350 lineto +fill +0.39350 0.54350 moveto +0.42350 0.54350 lineto +0.42350 0.58350 lineto +0.39350 0.58350 lineto +fill +0.42950 0.54350 moveto +0.45950 0.54350 lineto +0.45950 0.58350 lineto +0.42950 0.58350 lineto +fill +0.46550 0.54350 moveto +0.49550 0.54350 lineto +0.49550 0.58350 lineto +0.46550 0.58350 lineto +fill +0.49350 0.54350 moveto +0.52350 0.54350 lineto +0.52350 0.58350 lineto +0.49350 0.58350 lineto +fill +0.52950 0.54350 moveto +0.55950 0.54350 lineto +0.55950 0.58350 lineto +0.52950 0.58350 lineto +fill +0.56550 0.54350 moveto +0.59550 0.54350 lineto +0.59550 0.58350 lineto +0.56550 0.58350 lineto +fill +% Layer plated-drill group -1 drill 1 mask 0 +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +0.25000 0.10000 0.01575 c +0.10000 0.22500 0.01575 c +0.25000 0.22500 0.01575 c +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,18 @@ +G04 start of page 5 for group 10 layer_idx 1 * +G04 Title: (unknown), bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 65000 62500 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD20C,0.0315*% +%ADD19C,0.0787*% +G54D19*X10000Y52500D03* +X25000D03* +X10000Y40000D03* +X25000D03* +G54D20*M02* Index: tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 10 for group 9 layer_idx 6 * +G04 Title: (unknown), global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 65000 62500 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD25C,0.0100*% +G54D25*X0Y62500D02*Y0D01* +Y62500D02*X65000D01* +X0Y0D02*X65000D01* +Y62500D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.global.virtual.pdrill.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.global.virtual.pdrill.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.global.virtual.pdrill.none.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 8 for group -1 layer_idx 268435462 * +G04 Title: (unknown), * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 65000 62500 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_VIRTUAL_PDRILL_NONE*% +%ADD23C,0.0315*% +G54D23*X10000Y52500D03* +X25000D03* +X10000Y40000D03* +X25000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.intern.copper.none.5.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.intern.copper.none.5.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.intern.copper.none.5.gbr (revision 33253) @@ -0,0 +1,18 @@ +G04 start of page 3 for group 5 layer_idx 5 * +G04 Title: (unknown), Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 65000 62500 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_5*% +%ADD16C,0.0315*% +%ADD15C,0.0787*% +G54D15*X10000Y52500D03* +X25000D03* +X10000Y40000D03* +X25000D03* +G54D16*M02* Index: tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.intern.copper.none.7.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.intern.copper.none.7.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.intern.copper.none.7.gbr (revision 33253) @@ -0,0 +1,18 @@ +G04 start of page 4 for group 7 layer_idx 4 * +G04 Title: (unknown), Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 65000 62500 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_7*% +%ADD18C,0.0315*% +%ADD17C,0.0787*% +G54D17*X10000Y52500D03* +X25000D03* +X10000Y40000D03* +X25000D03* +G54D18*M02* Index: tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,351 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: (unknown), top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 65000 62500 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD14C,0.0315*% +%ADD13C,0.0787*% +%ADD12C,0.0100*% +%ADD11C,0.0001*% +G54D11*G36* +X17108Y42477D02*X16725Y42385D01* +X16362Y42234D01* +X16026Y42029D01* +X15727Y41773D01* +X15690Y41730D01* +X15664Y41840D01* +X15306Y42704D01* +X14818Y43500D01* +X14211Y44211D01* +X13500Y44818D01* +X12704Y45306D01* +X11840Y45664D01* +X10932Y45882D01* +X10000Y45955D01* +X9991Y45955D01* +Y46545D01* +X10000Y46545D01* +X10932Y46618D01* +X11840Y46836D01* +X12704Y47194D01* +X13500Y47682D01* +X14211Y48289D01* +X14818Y49000D01* +X15306Y49796D01* +X15664Y50660D01* +X15882Y51568D01* +X15937Y52500D01* +X15882Y53432D01* +X15664Y54340D01* +X15306Y55204D01* +X14818Y56000D01* +X14211Y56711D01* +X13500Y57318D01* +X12704Y57806D01* +X11840Y58164D01* +X10932Y58382D01* +X10000Y58455D01* +X9991Y58455D01* +Y60000D01* +X32492D01* +X32500Y59902D01* +Y55098D01* +X32492Y55000D01* +X32500Y54902D01* +Y50098D01* +X32492Y50000D01* +X32500Y49902D01* +Y45098D01* +X32492Y45000D01* +X32500Y44902D01* +Y35218D01* +X32490Y35000D01* +X28203D01* +X28500Y35182D01* +X29211Y35789D01* +X29818Y36500D01* +X30306Y37296D01* +X30664Y38160D01* +X30882Y39068D01* +X30937Y40000D01* +X30882Y40932D01* +X30664Y41840D01* +X30306Y42704D01* +X30000Y43203D01* +Y45000D01* +X29977Y45392D01* +X29885Y45775D01* +X29734Y46138D01* +X29529Y46474D01* +X29273Y46773D01* +X28974Y47029D01* +X28638Y47234D01* +X28275Y47385D01* +X28089Y47430D01* +X28500Y47682D01* +X29211Y48289D01* +X29818Y49000D01* +X30306Y49796D01* +X30664Y50660D01* +X30882Y51568D01* +X30937Y52500D01* +X30882Y53432D01* +X30664Y54340D01* +X30306Y55204D01* +X29818Y56000D01* +X29211Y56711D01* +X28500Y57318D01* +X27704Y57806D01* +X26840Y58164D01* +X25932Y58382D01* +X25000Y58455D01* +X24068Y58382D01* +X23160Y58164D01* +X22296Y57806D01* +X21500Y57318D01* +X20789Y56711D01* +X20182Y56000D01* +X19694Y55204D01* +X19336Y54340D01* +X19118Y53432D01* +X19045Y52500D01* +X19118Y51568D01* +X19336Y50660D01* +X19694Y49796D01* +X20182Y49000D01* +X20789Y48289D01* +X21500Y47682D01* +X22296Y47194D01* +X23160Y46836D01* +X24068Y46618D01* +X25000Y46545D01* +X25570Y46590D01* +X25471Y46474D01* +X25266Y46138D01* +X25184Y45941D01* +X25000Y45955D01* +X24068Y45882D01* +X23160Y45664D01* +X22296Y45306D01* +X21500Y44818D01* +X20789Y44211D01* +X20182Y43500D01* +X19694Y42704D01* +X19609Y42500D01* +X17500D01* +X17108Y42477D01* +G37* +G36* +X9068Y45882D02*X8160Y45664D01* +X7296Y45306D01* +X6500Y44818D01* +X5789Y44211D01* +X5182Y43500D01* +X4694Y42704D01* +X4336Y41840D01* +X4118Y40932D01* +X4045Y40000D01* +X4118Y39068D01* +X4336Y38160D01* +X4694Y37296D01* +X5182Y36500D01* +X5789Y35789D01* +X6500Y35182D01* +X6797Y35000D01* +X2500D01* +Y60000D01* +X9991D01* +Y58455D01* +X9068Y58382D01* +X8160Y58164D01* +X7296Y57806D01* +X6500Y57318D01* +X5789Y56711D01* +X5182Y56000D01* +X4694Y55204D01* +X4336Y54340D01* +X4118Y53432D01* +X4045Y52500D01* +X4118Y51568D01* +X4336Y50660D01* +X4694Y49796D01* +X5182Y49000D01* +X5789Y48289D01* +X6500Y47682D01* +X7296Y47194D01* +X8160Y46836D01* +X9068Y46618D01* +X9991Y46545D01* +Y45955D01* +X9068Y45882D01* +G37* +G36* +X30000Y30000D02*Y10000D01* +X25000D01* +Y30000D01* +X30000D01* +G37* +G36* +X37500D02*Y10000D01* +X32500D01* +Y30000D01* +X37500D01* +G37* +G36* +X45000D02*Y10000D01* +X40000D01* +Y30000D01* +X45000D01* +G37* +G36* +X52500D02*Y10000D01* +X47500D01* +Y30000D01* +X52500D01* +G37* +G54D12*X17500Y40000D02*X25000D01* +X27500Y42500D01* +Y45000D01* +X35000Y60000D02*X55000D01* +X35000Y45000D02*X55000D01* +X35000Y55000D02*X55000D01* +X35000Y50000D02*X55000D01* +X35000Y35000D02*G75*G02X42500Y42500I7500J0D01*G01* +X40000Y35000D02*G75*G02X47500Y42500I7500J0D01*G01* +X45000Y35000D02*G75*G02X52500Y42500I7500J0D01*G01* +X50000Y35000D02*G75*G02X57500Y42500I7500J0D01*G01* +X5000Y32500D02*X7000D01* +X6000D02*Y28500D01* +X8200Y30700D02*X9700D01* +X8200Y28500D02*X10200D01* +X8200Y32500D02*Y28500D01* +Y32500D02*X10200D01* +X13400D02*X13900Y32000D01* +X11900Y32500D02*X13400D01* +X11400Y32000D02*X11900Y32500D01* +X11400Y32000D02*Y31000D01* +X11900Y30500D01* +X13400D01* +X13900Y30000D01* +Y29000D01* +X13400Y28500D02*X13900Y29000D01* +X11900Y28500D02*X13400D01* +X11400Y29000D02*X11900Y28500D01* +X15100Y32500D02*X17100D01* +X16100D02*Y28500D01* +X5000Y25000D02*X7000D01* +X6000D02*Y21000D01* +X8200Y23200D02*X9700D01* +X8200Y21000D02*X10200D01* +X8200Y25000D02*Y21000D01* +Y25000D02*X10200D01* +X13400D02*X13900Y24500D01* +X11900Y25000D02*X13400D01* +X11400Y24500D02*X11900Y25000D01* +X11400Y24500D02*Y23500D01* +X11900Y23000D01* +X13400D01* +X13900Y22500D01* +Y21500D01* +X13400Y21000D02*X13900Y21500D01* +X11900Y21000D02*X13400D01* +X11400Y21500D02*X11900Y21000D01* +X15100Y25000D02*X17100D01* +X16100D02*Y21000D01* +X5000Y17500D02*X7000D01* +X6000D02*Y13500D01* +X8200Y15700D02*X9700D01* +X8200Y13500D02*X10200D01* +X8200Y17500D02*Y13500D01* +Y17500D02*X10200D01* +X13400D02*X13900Y17000D01* +X11900Y17500D02*X13400D01* +X11400Y17000D02*X11900Y17500D01* +X11400Y17000D02*Y16000D01* +X11900Y15500D01* +X13400D01* +X13900Y15000D01* +Y14000D01* +X13400Y13500D02*X13900Y14000D01* +X11900Y13500D02*X13400D01* +X11400Y14000D02*X11900Y13500D01* +X15100Y17500D02*X17100D01* +X16100D02*Y13500D01* +X5000Y10000D02*X7000D01* +X6000D02*Y6000D01* +X8200Y8200D02*X9700D01* +X8200Y6000D02*X10200D01* +X8200Y10000D02*Y6000D01* +Y10000D02*X10200D01* +X13400D02*X13900Y9500D01* +X11900Y10000D02*X13400D01* +X11400Y9500D02*X11900Y10000D01* +X11400Y9500D02*Y8500D01* +X11900Y8000D01* +X13400D01* +X13900Y7500D01* +Y6500D01* +X13400Y6000D02*X13900Y6500D01* +X11900Y6000D02*X13400D01* +X11400Y6500D02*X11900Y6000D01* +X15100Y10000D02*X17100D01* +X16100D02*Y6000D01* +G54D13*X10000Y52500D03* +X25000D03* +X10000Y40000D03* +X25000D03* +G54D11*G36* +X21910Y6377D02*X19942D01* +Y3623D01* +X21910D01* +Y6377D01* +G37* +G36* +X25058D02*X23090D01* +Y3623D01* +X25058D01* +Y6377D01* +G37* +G36* +X31910D02*X29942D01* +Y3623D01* +X31910D01* +Y6377D01* +G37* +G36* +X35058D02*X33090D01* +Y3623D01* +X35058D01* +Y6377D01* +G37* +G36* +X41910D02*X39942D01* +Y3623D01* +X41910D01* +Y6377D01* +G37* +G36* +X45058D02*X43090D01* +Y3623D01* +X45058D01* +Y6377D01* +G37* +G36* +X51910D02*X49942D01* +Y3623D01* +X51910D01* +Y6377D01* +G37* +G36* +X55058D02*X53090D01* +Y3623D01* +X55058D01* +Y6377D01* +G37* +G54D14*M02* Index: tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.mask.none.2.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.mask.none.2.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.mask.none.2.gbr (revision 33253) @@ -0,0 +1,61 @@ +G04 start of page 6 for group 2 layer_idx 10 * +G04 Title: (unknown), top_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 65000 62500 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_MASK_NONE_2*% +%ADD21C,0.0001*% +G54D21*G36* +X22210Y6677D02*X19642D01* +Y3323D01* +X22210D01* +Y6677D01* +G37* +G36* +X25358D02*X22790D01* +Y3323D01* +X25358D01* +Y6677D01* +G37* +G36* +X32210D02*X29642D01* +Y3323D01* +X32210D01* +Y6677D01* +G37* +G36* +X35358D02*X32790D01* +Y3323D01* +X35358D01* +Y6677D01* +G37* +G36* +X42210D02*X39642D01* +Y3323D01* +X42210D01* +Y6677D01* +G37* +G36* +X45358D02*X42790D01* +Y3323D01* +X45358D01* +Y6677D01* +G37* +G36* +X52210D02*X49642D01* +Y3323D01* +X52210D01* +Y6677D01* +G37* +G36* +X55358D02*X52790D01* +Y3323D01* +X55358D01* +Y6677D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.paste.none.0.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.paste.none.0.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.paste.none.0.gbr (revision 33253) @@ -0,0 +1,61 @@ +G04 start of page 9 for group 0 layer_idx 9 * +G04 Title: (unknown), top_paste * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 65000 62500 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_PASTE_NONE_0*% +%ADD24C,0.0001*% +G54D24*G36* +X21910Y6377D02*X19942D01* +Y3623D01* +X21910D01* +Y6377D01* +G37* +G36* +X25058D02*X23090D01* +Y3623D01* +X25058D01* +Y6377D01* +G37* +G36* +X31910D02*X29942D01* +Y3623D01* +X31910D01* +Y6377D01* +G37* +G36* +X35058D02*X33090D01* +Y3623D01* +X35058D01* +Y6377D01* +G37* +G36* +X41910D02*X39942D01* +Y3623D01* +X41910D01* +Y6377D01* +G37* +G36* +X45058D02*X43090D01* +Y3623D01* +X45058D01* +Y6377D01* +G37* +G36* +X51910D02*X49942D01* +Y3623D01* +X51910D01* +Y6377D01* +G37* +G36* +X55058D02*X53090D01* +Y3623D01* +X55058D01* +Y6377D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.gbr/flag_colors.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,85 @@ +G04 start of page 7 for group 1 layer_idx 8 * +G04 Title: (unknown), top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 65000 62500 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD22C,0.0001*% +G54D22*G36* +X19350Y8150D02*X22350D01* +Y4150D01* +X19350D01* +Y8150D01* +G37* +G36* +X22950D02*X25950D01* +Y4150D01* +X22950D01* +Y8150D01* +G37* +G36* +X26550D02*X29550D01* +Y4150D01* +X26550D01* +Y8150D01* +G37* +G36* +X29350D02*X32350D01* +Y4150D01* +X29350D01* +Y8150D01* +G37* +G36* +X32950D02*X35950D01* +Y4150D01* +X32950D01* +Y8150D01* +G37* +G36* +X36550D02*X39550D01* +Y4150D01* +X36550D01* +Y8150D01* +G37* +G36* +X39350D02*X42350D01* +Y4150D01* +X39350D01* +Y8150D01* +G37* +G36* +X42950D02*X45950D01* +Y4150D01* +X42950D01* +Y8150D01* +G37* +G36* +X46550D02*X49550D01* +Y4150D01* +X46550D01* +Y8150D01* +G37* +G36* +X49350D02*X52350D01* +Y4150D01* +X49350D01* +Y8150D01* +G37* +G36* +X52950D02*X55950D01* +Y4150D01* +X52950D01* +Y8150D01* +G37* +G36* +X56550D02*X59550D01* +Y4150D01* +X56550D01* +Y8150D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/flag_colors.net =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.net (revision 33253) @@ -0,0 +1,21 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB /home/igor2/C/pcb-rnd/trunk/tests/RTT/flag_colors.lht +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +327N/C -1 A01X+002093Y+000500X0197Y0275R000 S3 +327N/C -2 A01X+002407Y+000500X0197Y0275R000 S3 +327N/C -1 A01X+003093Y+000500X0197Y0275R000 S3 +327N/C -2 A01X+003407Y+000500X0197Y0275R000 S3 +327N/C -1 A01X+004093Y+000500X0197Y0275R000 S3 +327N/C -2 A01X+004407Y+000500X0197Y0275R000 S3 +327N/C -1 A01X+005093Y+000500X0197Y0275R000 S3 +327N/C -2 A01X+005407Y+000500X0197Y0275R000 S3 +999 + Index: tags/2.3.0/tests/RTT/ref/flag_colors.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/flag_colors.png =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/flag_colors.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/flag_colors.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/flag_colors.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/flag_colors.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/flag_colors.scad =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.scad (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.scad (revision 33253) @@ -0,0 +1,364 @@ +// Round cap line +module pcb_line_rc(x1, y1, length, angle, width, thick) { + translate([x1,y1,0]) { + rotate([0,0,angle]) { + translate([length/2, 0, 0]) + cube([length, width, thick], center=true); + cylinder(r=width/2, h=thick, center=true, $fn=30); + translate([length, 0, 0]) + cylinder(r=width/2, h=thick, center=true, $fn=30); + } + } +} +// Square cap line +module pcb_line_sc(x1, y1, length, angle, width, thick) { + translate([x1,y1,0]) { + rotate([0,0,angle]) { + translate([length/2, 0, 0]) + cube([length + width, width, thick], center=true); + } + } +} +// filled rectangle +module pcb_fill_rect(x1, y1, x2, y2, angle, thick) { + translate([(x1+x2)/2,(y1+y2)/2,0]) + rotate([0,0,angle]) + cube([x2-x1, y2-y1, thick], center=true); +} +// filled polygon +module pcb_fill_poly(coords, thick) { + linear_extrude(height=thick) + polygon(coords); +} +// filled circle +module pcb_fcirc(x1, y1, radius, thick) { + translate([x1,y1,0]) + cylinder(r=radius, h=thick, center=true, $fn=30); +} +module pcb_outline() { + polygon([ + [0.0000,15.8750],[16.5100,15.8750],[16.5100,0.0000],[0.0000,0.0000] + ]); +} +module layer_bottom_silk_pos_1() { + color([0,0,0]) + translate([0,0,-0.833000]) { + } +} + +module layer_group_bottom_silk() { + layer_bottom_silk_pos_1(); +} + +module layer_bottom_copper_pos_2() { + color([1,0.4,0.2]) + translate([0,0,-0.811000]) { + pcb_fcirc(2.5400, 13.3350, 1.0000, 0.010000); + pcb_fcirc(6.3500, 13.3350, 1.0000, 0.010000); + pcb_fcirc(2.5400, 10.1600, 1.0000, 0.010000); + pcb_fcirc(6.3500, 10.1600, 1.0000, 0.010000); + pcb_fcirc(2.5400, 13.3350, 0.4001, 0.010000); + pcb_fcirc(6.3500, 13.3350, 0.4001, 0.010000); + pcb_fcirc(2.5400, 10.1600, 0.4001, 0.010000); + pcb_fcirc(6.3500, 10.1600, 0.4001, 0.010000); + } +} + +module layer_group_bottom_copper() { + layer_bottom_copper_pos_2(); +} + +module layer_top_copper_pos_3() { + color([1,0.4,0.2]) + translate([0,0,0.811000]) { + pcb_fill_poly([[4.3454,10.7891],[4.2482,10.7658],[4.1558,10.7275],[4.0706,10.6753],[3.9946,10.6104],[3.9853,10.5995],[3.9786,10.6274],[3.8878,10.8467],[3.7638,11.0491],[3.6096,11.2296],[3.4291,11.3838],[3.2267,11.5078],[3.0074,11.5986],[2.7766,11.6540],[2.5400,11.6727],[2.5377,11.6725],[2.5377,11.8225],[2.5400,11.8223],[2.7766,11.8410],[3.0074,11.8964],[3.2267,11.9872],[3.4291,12.1112],[3.6096,12.2654],[3.7638,12.4459],[3.8878,12.6483],[3.9786,12.8676],[4.0340,13.0984],[4.0480,13.3350],[4.0340,13.5716],[3.9786,13.8024],[3.8878,14.0217],[3.7638,14.2241],[3.6096,14.4046],[3.4291,14.5588],[3.2267,14.6828],[3.0074,14.7736],[2.7766,14.8290],[2.5400,14.8477],[2.5377,14.8475],[2.5377,15.2400],[8.2530,15.2400],[8.2550,15.2151],[8.2550,13.9949],[8.2530,13.9700],[8.2550,13.9451],[8.2550,12.7249],[8.2530,12.7000],[8.2550,12.6751],[8.2550,11.4549],[8.2530,11.4300],[8.2550,11.4051],[8.2550,8.9454],[8.2526,8.8900],[7.1637,8.8900],[7.2391,8.9362],[7.4196,9.0904],[7.5738,9.2709],[7.6978,9.4733],[7.7886,9.6926],[7.8440,9.9234],[7.8580,10.1600],[7.8440,10.3966],[7.7886,10.6274],[7.6978,10.8467],[7.6200,10.9737],[7.6200,11.4300],[7.6141,11.5296],[7.5908,11.6268],[7.5525,11.7192],[7.5003,11.8044],[7.4354,11.8804],[7.3594,11.9453],[7.2742,11.9975],[7.1818,12.0358],[7.1345,12.0471],[7.2391,12.1112],[7.4196,12.2654],[7.5738,12.4459],[7.6978,12.6483],[7.7886,12.8676],[7.8440,13.0984],[7.8580,13.3350],[7.8440,13.5716],[7.7886,13.8024],[7.6978,14.0217],[7.5738,14.2241],[7.4196,14.4046],[7.2391,14.5588],[7.0367,14.6828],[6.8174,14.7736],[6.5866,14.8290],[6.3500,14.8477],[6.1134,14.8290],[5.8826,14.7736],[5.6633,14.6828],[5.4609,14.5588],[5.2804,14.4046],[5.1262,14.2241],[5.0022,14.0217],[4.9114,13.8024],[4.8560,13.5716],[4.8373,13.3350],[4.8560,13.0984],[4.9114,12.8676],[5.0022,12.6483],[5.1262,12.4459],[5.2804,12.2654],[5.4609,12.1112],[5.6633,11.9872],[5.8826,11.8964],[6.1134,11.8410],[6.3500,11.8223],[6.4948,11.8337],[6.4697,11.8044],[6.4175,11.7192],[6.3967,11.6690],[6.3500,11.6727],[6.1134,11.6540],[5.8826,11.5986],[5.6633,11.5078],[5.4609,11.3838],[5.2804,11.2296],[5.1262,11.0491],[5.0022,10.8467],[4.9808,10.7950],[4.4450,10.7950]], 0.010000); + pcb_fill_poly([[2.3034,11.6540],[2.0726,11.5986],[1.8533,11.5078],[1.6509,11.3838],[1.4704,11.2296],[1.3162,11.0491],[1.1922,10.8467],[1.1014,10.6274],[1.0460,10.3966],[1.0273,10.1600],[1.0460,9.9234],[1.1014,9.6926],[1.1922,9.4733],[1.3162,9.2709],[1.4704,9.0904],[1.6509,8.9362],[1.7263,8.8900],[0.6350,8.8900],[0.6350,15.2400],[2.5377,15.2400],[2.5377,14.8475],[2.3034,14.8290],[2.0726,14.7736],[1.8533,14.6828],[1.6509,14.5588],[1.4704,14.4046],[1.3162,14.2241],[1.1922,14.0217],[1.1014,13.8024],[1.0460,13.5716],[1.0273,13.3350],[1.0460,13.0984],[1.1014,12.8676],[1.1922,12.6483],[1.3162,12.4459],[1.4704,12.2654],[1.6509,12.1112],[1.8533,11.9872],[2.0726,11.8964],[2.3034,11.8410],[2.5377,11.8225],[2.5377,11.6725]], 0.010000); + pcb_fill_poly([[7.6200,7.6200],[7.6200,2.5400],[6.3500,2.5400],[6.3500,7.6200]], 0.010000); + pcb_fill_poly([[9.5250,7.6200],[9.5250,2.5400],[8.2550,2.5400],[8.2550,7.6200]], 0.010000); + pcb_fill_poly([[11.4300,7.6200],[11.4300,2.5400],[10.1600,2.5400],[10.1600,7.6200]], 0.010000); + pcb_fill_poly([[13.3350,7.6200],[13.3350,2.5400],[12.0650,2.5400],[12.0650,7.6200]], 0.010000); + pcb_line_rc(4.4450, 10.1600, 1.9050, 0.000000, 0.2540, 0.010000); + pcb_line_rc(6.3500, 10.1600, 0.8980, 45.000000, 0.2540, 0.010000); + pcb_line_rc(6.9850, 10.7950, 0.6350, 90.000000, 0.2540, 0.010000); + pcb_line_rc(8.8900, 15.2400, 5.0800, 0.000000, 0.2540, 0.010000); + pcb_line_rc(8.8900, 13.9700, 5.0800, 0.000000, 0.2540, 0.010000); + pcb_line_rc(8.8900, 12.7000, 5.0800, 0.000000, 0.2540, 0.010000); + pcb_line_rc(8.8900, 11.4300, 5.0800, 0.000000, 0.2540, 0.010000); + // line-approx arc 0.000000 .. -90.000000 by -10.000000 + pcb_line_rc(8.8900, 8.8900, 0.3321, 85.000043, 0.2540, 0.010000); + pcb_line_rc(8.9189, 9.2208, 0.3321, 75.000073, 0.2540, 0.010000); + pcb_line_rc(9.0049, 9.5415, 0.3321, 64.999962, 0.2540, 0.010000); + pcb_line_rc(9.1452, 9.8425, 0.3321, 55.000022, 0.2540, 0.010000); + pcb_line_rc(9.3357, 10.1145, 0.3321, 45.000000, 0.2540, 0.010000); + pcb_line_rc(9.5705, 10.3493, 0.3321, 34.999978, 0.2540, 0.010000); + pcb_line_rc(9.8425, 10.5398, 0.3321, 25.000038, 0.2540, 0.010000); + pcb_line_rc(10.1435, 10.6801, 0.3321, 14.999927, 0.2540, 0.010000); + pcb_line_rc(10.4642, 10.7661, 0.3321, 4.999957, 0.2540, 0.010000); + // line-approx arc 0.000000 .. -90.000000 by -10.000000 + pcb_line_rc(10.1600, 8.8900, 0.3321, 85.000043, 0.2540, 0.010000); + pcb_line_rc(10.1889, 9.2208, 0.3321, 75.000073, 0.2540, 0.010000); + pcb_line_rc(10.2749, 9.5415, 0.3321, 64.999962, 0.2540, 0.010000); + pcb_line_rc(10.4152, 9.8425, 0.3321, 55.000022, 0.2540, 0.010000); + pcb_line_rc(10.6057, 10.1145, 0.3321, 45.000000, 0.2540, 0.010000); + pcb_line_rc(10.8405, 10.3493, 0.3321, 34.999978, 0.2540, 0.010000); + pcb_line_rc(11.1125, 10.5398, 0.3321, 25.000038, 0.2540, 0.010000); + pcb_line_rc(11.4135, 10.6801, 0.3321, 14.999927, 0.2540, 0.010000); + pcb_line_rc(11.7342, 10.7661, 0.3321, 4.999957, 0.2540, 0.010000); + // line-approx arc 0.000000 .. -90.000000 by -10.000000 + pcb_line_rc(11.4300, 8.8900, 0.3321, 85.000043, 0.2540, 0.010000); + pcb_line_rc(11.4589, 9.2208, 0.3321, 75.000073, 0.2540, 0.010000); + pcb_line_rc(11.5449, 9.5415, 0.3321, 64.999962, 0.2540, 0.010000); + pcb_line_rc(11.6852, 9.8425, 0.3321, 55.000022, 0.2540, 0.010000); + pcb_line_rc(11.8757, 10.1145, 0.3321, 45.000000, 0.2540, 0.010000); + pcb_line_rc(12.1105, 10.3493, 0.3321, 34.999978, 0.2540, 0.010000); + pcb_line_rc(12.3825, 10.5398, 0.3321, 25.000038, 0.2540, 0.010000); + pcb_line_rc(12.6835, 10.6801, 0.3321, 14.999927, 0.2540, 0.010000); + pcb_line_rc(13.0042, 10.7661, 0.3321, 4.999957, 0.2540, 0.010000); + // line-approx arc 0.000000 .. -90.000000 by -10.000000 + pcb_line_rc(12.7000, 8.8900, 0.3321, 85.000043, 0.2540, 0.010000); + pcb_line_rc(12.7289, 9.2208, 0.3321, 75.000073, 0.2540, 0.010000); + pcb_line_rc(12.8149, 9.5415, 0.3321, 64.999962, 0.2540, 0.010000); + pcb_line_rc(12.9552, 9.8425, 0.3321, 55.000022, 0.2540, 0.010000); + pcb_line_rc(13.1457, 10.1145, 0.3321, 45.000000, 0.2540, 0.010000); + pcb_line_rc(13.3805, 10.3493, 0.3321, 34.999978, 0.2540, 0.010000); + pcb_line_rc(13.6525, 10.5398, 0.3321, 25.000038, 0.2540, 0.010000); + pcb_line_rc(13.9535, 10.6801, 0.3321, 14.999927, 0.2540, 0.010000); + pcb_line_rc(14.2742, 10.7661, 0.3321, 4.999957, 0.2540, 0.010000); + pcb_line_rc(1.2700, 8.2550, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(1.5240, 8.2550, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 7.7978, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 7.2390, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 8.2550, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 8.2550, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 8.2550, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 8.2550, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 8.1280, 0.1796, 45.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 8.1280, 0.2540, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 7.8740, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 7.7470, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 7.7470, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.5306, 7.6200, 0.2540, -90.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 7.2390, 0.1796, 45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 7.2390, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 7.3660, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.8354, 8.2550, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(4.0894, 8.2550, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_line_rc(1.2700, 6.3500, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(1.5240, 6.3500, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 5.8928, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 5.3340, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 6.3500, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 6.3500, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 6.3500, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 6.3500, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 6.2230, 0.1796, 45.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 6.2230, 0.2540, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 5.9690, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 5.8420, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 5.8420, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.5306, 5.7150, 0.2540, -90.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 5.3340, 0.1796, 45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 5.3340, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 5.4610, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.8354, 6.3500, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(4.0894, 6.3500, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_line_rc(1.2700, 4.4450, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(1.5240, 4.4450, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 3.9878, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 3.4290, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 4.4450, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 4.4450, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 4.4450, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 4.4450, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 4.3180, 0.1796, 45.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 4.3180, 0.2540, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 4.0640, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 3.9370, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 3.9370, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.5306, 3.8100, 0.2540, -90.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 3.4290, 0.1796, 45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 3.4290, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 3.5560, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.8354, 4.4450, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(4.0894, 4.4450, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_line_rc(1.2700, 2.5400, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(1.5240, 2.5400, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 2.0828, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 1.5240, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 2.5400, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.0828, 2.5400, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 2.5400, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 2.5400, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 2.4130, 0.1796, 45.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 2.4130, 0.2540, -90.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 2.1590, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 2.0320, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 2.0320, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.5306, 1.9050, 0.2540, -90.000000, 0.2540, 0.010000); + pcb_line_rc(3.4036, 1.5240, 0.1796, 45.000000, 0.2540, 0.010000); + pcb_line_rc(3.0226, 1.5240, 0.3810, 0.000000, 0.2540, 0.010000); + pcb_line_rc(2.8956, 1.6510, 0.1796, -45.000000, 0.2540, 0.010000); + pcb_line_rc(3.8354, 2.5400, 0.5080, 0.000000, 0.2540, 0.010000); + pcb_line_rc(4.0894, 2.5400, 1.0160, -90.000000, 0.2540, 0.010000); + pcb_fcirc(2.5400, 13.3350, 1.0000, 0.010000); + pcb_fcirc(6.3500, 13.3350, 1.0000, 0.010000); + pcb_fcirc(2.5400, 10.1600, 1.0000, 0.010000); + pcb_fcirc(6.3500, 10.1600, 1.0000, 0.010000); + pcb_fill_poly([[5.5651,1.6198],[5.0653,1.6198],[5.0653,0.9202],[5.5651,0.9202]], 0.010000); + pcb_fill_poly([[6.3647,1.6198],[5.8649,1.6198],[5.8649,0.9202],[6.3647,0.9202]], 0.010000); + pcb_fill_poly([[8.1051,1.6198],[7.6053,1.6198],[7.6053,0.9202],[8.1051,0.9202]], 0.010000); + pcb_fill_poly([[8.9047,1.6198],[8.4049,1.6198],[8.4049,0.9202],[8.9047,0.9202]], 0.010000); + pcb_fill_poly([[10.6451,1.6198],[10.1453,1.6198],[10.1453,0.9202],[10.6451,0.9202]], 0.010000); + pcb_fill_poly([[11.4447,1.6198],[10.9449,1.6198],[10.9449,0.9202],[11.4447,0.9202]], 0.010000); + pcb_fill_poly([[13.1851,1.6198],[12.6853,1.6198],[12.6853,0.9202],[13.1851,0.9202]], 0.010000); + pcb_fill_poly([[13.9847,1.6198],[13.4849,1.6198],[13.4849,0.9202],[13.9847,0.9202]], 0.010000); + pcb_fcirc(2.5400, 13.3350, 0.4001, 0.010000); + pcb_fcirc(6.3500, 13.3350, 0.4001, 0.010000); + pcb_fcirc(2.5400, 10.1600, 0.4001, 0.010000); + pcb_fcirc(6.3500, 10.1600, 0.4001, 0.010000); + } +} + +module layer_top_copper_pos_4() { + color([1,0.4,0.2]) + translate([0,0,0.811000]) { + } +} + +module layer_group_top_copper() { + layer_top_copper_pos_3(); + layer_top_copper_pos_4(); +} + +module layer_top_mask_pos_5() { + color([0,0.7,0,0.5]) + translate([0,0,0.822000]) { + pcb_fill_rect(0.0000, 0.0000, 16.5100, 15.8750, 0.000000, 0.010000); + } +} + +module layer_top_mask_neg_6() { + color([0,0.7,0,0.5]) + translate([0,0,0.812000]) { + pcb_fill_poly([[5.6413,1.6960],[4.9891,1.6960],[4.9891,0.8440],[5.6413,0.8440]], 1.020000); + pcb_fill_poly([[6.4409,1.6960],[5.7887,1.6960],[5.7887,0.8440],[6.4409,0.8440]], 1.020000); + pcb_fill_poly([[8.1813,1.6960],[7.5291,1.6960],[7.5291,0.8440],[8.1813,0.8440]], 1.020000); + pcb_fill_poly([[8.9809,1.6960],[8.3287,1.6960],[8.3287,0.8440],[8.9809,0.8440]], 1.020000); + pcb_fill_poly([[10.7213,1.6960],[10.0691,1.6960],[10.0691,0.8440],[10.7213,0.8440]], 1.020000); + pcb_fill_poly([[11.5209,1.6960],[10.8687,1.6960],[10.8687,0.8440],[11.5209,0.8440]], 1.020000); + pcb_fill_poly([[13.2613,1.6960],[12.6091,1.6960],[12.6091,0.8440],[13.2613,0.8440]], 1.020000); + pcb_fill_poly([[14.0609,1.6960],[13.4087,1.6960],[13.4087,0.8440],[14.0609,0.8440]], 1.020000); + } +} + +module layer_top_mask_pos_7() { + color([0,0.7,0,0.5]) + translate([0,0,0.822000]) { + } +} + +module layer_group_top_mask() { + union() { + difference() { + layer_top_mask_pos_5(); + layer_top_mask_neg_6(); +} + layer_top_mask_pos_7(); +} +} + +module layer_bottom_mask_pos_8() { + color([0,0.7,0,0.5]) + translate([0,0,-0.822000]) { + pcb_fill_rect(0.0000, 0.0000, 16.5100, 15.8750, 0.000000, 0.010000); + } +} + +module layer_bottom_mask_neg_9() { + color([0,0.7,0,0.5]) + translate([0,0,-0.832000]) { + } +} + +module layer_bottom_mask_pos_10() { + color([0,0.7,0,0.5]) + translate([0,0,-0.822000]) { + } +} + +module layer_group_bottom_mask() { + union() { + difference() { + layer_bottom_mask_pos_8(); + layer_bottom_mask_neg_9(); +} + layer_bottom_mask_pos_10(); +} +} + +module layer_top_silk_pos_11() { + color([0,0,0]) + translate([0,0,0.833000]) { + pcb_fill_poly([[4.9149,2.0701],[5.6769,2.0701],[5.6769,1.0541],[4.9149,1.0541]], 0.010000); + pcb_fill_poly([[5.8293,2.0701],[6.5913,2.0701],[6.5913,1.0541],[5.8293,1.0541]], 0.010000); + pcb_fill_poly([[6.7437,2.0701],[7.5057,2.0701],[7.5057,1.0541],[6.7437,1.0541]], 0.010000); + pcb_fill_poly([[7.4549,2.0701],[8.2169,2.0701],[8.2169,1.0541],[7.4549,1.0541]], 0.010000); + pcb_fill_poly([[8.3693,2.0701],[9.1313,2.0701],[9.1313,1.0541],[8.3693,1.0541]], 0.010000); + pcb_fill_poly([[9.2837,2.0701],[10.0457,2.0701],[10.0457,1.0541],[9.2837,1.0541]], 0.010000); + pcb_fill_poly([[9.9949,2.0701],[10.7569,2.0701],[10.7569,1.0541],[9.9949,1.0541]], 0.010000); + pcb_fill_poly([[10.9093,2.0701],[11.6713,2.0701],[11.6713,1.0541],[10.9093,1.0541]], 0.010000); + pcb_fill_poly([[11.8237,2.0701],[12.5857,2.0701],[12.5857,1.0541],[11.8237,1.0541]], 0.010000); + pcb_fill_poly([[12.5349,2.0701],[13.2969,2.0701],[13.2969,1.0541],[12.5349,1.0541]], 0.010000); + pcb_fill_poly([[13.4493,2.0701],[14.2113,2.0701],[14.2113,1.0541],[13.4493,1.0541]], 0.010000); + pcb_fill_poly([[14.3637,2.0701],[15.1257,2.0701],[15.1257,1.0541],[14.3637,1.0541]], 0.010000); + } +} + +module layer_top_silk_pos_12() { + color([0,0,0]) + translate([0,0,0.833000]) { + } +} + +module layer_group_top_silk() { + layer_top_silk_pos_11(); + layer_top_silk_pos_12(); +} + +module pcb_drill() { + translate([2.5400,13.3350,0]) + cylinder(r=0.4001, h=4, center=true, $fn=30); + translate([6.3500,13.3350,0]) + cylinder(r=0.4001, h=4, center=true, $fn=30); + translate([2.5400,10.1600,0]) + cylinder(r=0.4001, h=4, center=true, $fn=30); + translate([6.3500,10.1600,0]) + cylinder(r=0.4001, h=4, center=true, $fn=30); +} +module pcb_board_main() { + translate ([0, 0, -0.8]) + linear_extrude(height=1.6) + pcb_outline(); + layer_group_bottom_silk(); + layer_group_bottom_copper(); + layer_group_top_copper(); + layer_group_top_mask(); + layer_group_bottom_mask(); + layer_group_top_silk(); +} + +module pcb_board() { + intersection() { + translate ([0, 0, -4]) + linear_extrude(height=8) + pcb_outline(); + union() { + difference() { + pcb_board_main(); + pcb_drill(); + } + } + } +} + +pcb_board(); Index: tags/2.3.0/tests/RTT/ref/flag_colors.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.svg (revision 33253) @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/flag_colors.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/flag_colors.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/flag_colors.xy (revision 33253) @@ -0,0 +1,12 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: (unknown) - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- +(unknown),"0402 Standard SMT resistor, capacitor etc","(unknown)",225.00,50.00,0,top +(unknown),"0402 Standard SMT resistor, capacitor etc","(unknown)",325.00,50.00,0,top +(unknown),"0402 Standard SMT resistor, capacitor etc","(unknown)",425.00,50.00,0,top +(unknown),"0402 Standard SMT resistor, capacitor etc","(unknown)",525.00,50.00,0,top Index: tags/2.3.0/tests/RTT/ref/layer_copper.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: one line per each type of copper layer - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/layer_copper.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.dsn (revision 33253) @@ -0,0 +1,56 @@ +(pcb one line per each type of copper layer + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 0.254000 1.270000 10.795000 1.270000 3.810000) + (type protect)) + (wire (path 5__Intern 0.254000 2.540000 8.890000 8.255000 3.175000) + (type protect)) + (wire (path 10__bottom_copper 0.254000 1.905000 10.795000 10.160000 10.795000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/layer_copper.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.eps (revision 33253) @@ -0,0 +1,39 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: layer_copper.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.01000 setlinewidth +1 setlinecap +0.227451 0.372549 0.803922 setrgbcolor +0.07500 0.07500 0.40000 0.07500 t +% Layer group5 group 5 drill 0 mask 0 +0.329412 0.545098 0.329412 setrgbcolor +0.10000 0.15000 0.32500 0.37500 t +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.545098 0.137255 0.137255 setrgbcolor +0.05000 0.07500 0.05000 0.35000 t +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/layer_copper.exc/layer_copper.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.exc/layer_copper.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.exc/layer_copper.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/layer_copper.exc/layer_copper.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.exc/layer_copper.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.exc/layer_copper.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/layer_copper.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.fcd (revision 33253) @@ -0,0 +1,4 @@ +[FIDOCAD] +PL 10 15 10 70 2 2 +PL 15 15 80 15 2 1 +PL 20 30 65 75 2 4 Index: tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 4 for group 10 layer_idx 1 * +G04 Title: one line per each type of copper layer, bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD13C,0.0100*% +G54D13*X7500Y42500D02*X40000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 5 for group 9 layer_idx 6 * +G04 Title: one line per each type of copper layer, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD14C,0.0100*% +G54D14*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.intern.copper.none.5.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.intern.copper.none.5.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.intern.copper.none.5.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 3 for group 5 layer_idx 4 * +G04 Title: one line per each type of copper layer, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_5*% +%ADD12C,0.0100*% +G54D12*X10000Y35000D02*X32500Y12500D01* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1843 @@ +G04 start of page 6 for group -1 layer_idx 268435461 * +G04 Title: one line per each type of copper layer, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD17C,0.0100*% +%ADD16C,0.0001*% +%ADD15C,0.0060*% +G54D15*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D16*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D15*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D16*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D15*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D16*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D15*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D16*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D15*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D16*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D15*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D16*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D17*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D15*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D16*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D15*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D16*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D15*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D16*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D15*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D16*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D15*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D16*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D15*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D16*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D15*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D16*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D15*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D16*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D15*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D16*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D15*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D16*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D15*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D16*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X253400D02*X257900D01* +Y104000D01* +X253400D01* +Y110000D01* +G37* +G36* +X258800D02*X263300D01* +Y104000D01* +X258800D01* +Y110000D01* +G37* +G36* +X264200D02*X268700D01* +Y104000D01* +X264200D01* +Y110000D01* +G37* +G36* +X269600D02*X274100D01* +Y104000D01* +X269600D01* +Y110000D01* +G37* +G36* +X277700D02*X282200D01* +Y104000D01* +X277700D01* +Y110000D01* +G37* +G36* +X283100D02*X287600D01* +Y104000D01* +X283100D01* +Y110000D01* +G37* +G36* +X288500D02*X293000D01* +Y104000D01* +X288500D01* +Y110000D01* +G37* +G36* +X296600D02*X301100D01* +Y104000D01* +X296600D01* +Y110000D01* +G37* +G36* +X302000D02*X306500D01* +Y104000D01* +X302000D01* +Y110000D01* +G37* +G36* +X307400D02*X311900D01* +Y104000D01* +X307400D01* +Y110000D01* +G37* +G36* +X312800D02*X317300D01* +Y104000D01* +X312800D01* +Y110000D01* +G37* +G36* +X320900D02*X325400D01* +Y104000D01* +X320900D01* +Y110000D01* +G37* +G36* +X326300D02*X330800D01* +Y104000D01* +X326300D01* +Y110000D01* +G37* +G36* +X331700D02*X336200D01* +Y104000D01* +X331700D01* +Y110000D01* +G37* +G36* +X337100D02*X341600D01* +Y104000D01* +X337100D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X358700D02*X363200D01* +Y104000D01* +X358700D01* +Y110000D01* +G37* +G36* +X364100D02*X368600D01* +Y104000D01* +X364100D01* +Y110000D01* +G37* +G36* +X369500D02*X374000D01* +Y104000D01* +X369500D01* +Y110000D01* +G37* +G36* +X374900D02*X379400D01* +Y104000D01* +X374900D01* +Y110000D01* +G37* +G36* +X380300D02*X384800D01* +Y104000D01* +X380300D01* +Y110000D01* +G37* +G36* +X385700D02*X390200D01* +Y104000D01* +X385700D01* +Y110000D01* +G37* +G36* +X393800D02*X398300D01* +Y104000D01* +X393800D01* +Y110000D01* +G37* +G36* +X399200D02*X403700D01* +Y104000D01* +X399200D01* +Y110000D01* +G37* +G36* +X404600D02*X409100D01* +Y104000D01* +X404600D01* +Y110000D01* +G37* +G36* +X410000D02*X414500D01* +Y104000D01* +X410000D01* +Y110000D01* +G37* +G36* +X415400D02*X419900D01* +Y104000D01* +X415400D01* +Y110000D01* +G37* +G36* +X423500D02*X428000D01* +Y104000D01* +X423500D01* +Y110000D01* +G37* +G54D15*X431600D02*Y104000D01* +Y110000D02*X434600D01* +X431600Y107300D02*X433850D01* +G54D16*G36* +X436400Y110000D02*X440900D01* +Y104000D01* +X436400D01* +Y110000D01* +G37* +G36* +X441800D02*X446300D01* +Y104000D01* +X441800D01* +Y110000D01* +G37* +G36* +X447200D02*X451700D01* +Y104000D01* +X447200D01* +Y110000D01* +G37* +G36* +X452600D02*X457100D01* +Y104000D01* +X452600D01* +Y110000D01* +G37* +G36* +X458000D02*X462500D01* +Y104000D01* +X458000D01* +Y110000D01* +G37* +G36* +X463400D02*X467900D01* +Y104000D01* +X463400D01* +Y110000D01* +G37* +G36* +X468800D02*X473300D01* +Y104000D01* +X468800D01* +Y110000D01* +G37* +G36* +X474200D02*X478700D01* +Y104000D01* +X474200D01* +Y110000D01* +G37* +G36* +X479600D02*X484100D01* +Y104000D01* +X479600D01* +Y110000D01* +G37* +G36* +X485000D02*X489500D01* +Y104000D01* +X485000D01* +Y110000D01* +G37* +G54D15*X493850D02*Y104000D01* +X495800Y110000D02*X496850Y108950D01* +Y105050D01* +X495800Y104000D02*X496850Y105050D01* +X493100Y104000D02*X495800D01* +X493100Y110000D02*X495800D01* +G54D16*G36* +X498650D02*X503150D01* +Y104000D01* +X498650D01* +Y110000D01* +G37* +G36* +X504050D02*X508550D01* +Y104000D01* +X504050D01* +Y110000D01* +G37* +G36* +X509450D02*X513950D01* +Y104000D01* +X509450D01* +Y110000D01* +G37* +G36* +X514850D02*X519350D01* +Y104000D01* +X514850D01* +Y110000D01* +G37* +G36* +X520250D02*X524750D01* +Y104000D01* +X520250D01* +Y110000D01* +G37* +G36* +X525650D02*X530150D01* +Y104000D01* +X525650D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.gbr/layer_copper.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: one line per each type of copper layer, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0100*% +G54D11*X5000Y42500D02*Y15000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_copper.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.nelma.em (revision 33253) @@ -0,0 +1,90 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} +layer substrate-11 { + height = 20 + z-order = 11 + material = "composite" +} +layer group-1 { + height = 1 + z-order = 12 + material = "air" + objects = { + + } +} +layer substrate-13 { + height = 20 + z-order = 13 + material = "composite" +} +layer bottom { + height = 1 + z-order = 14 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top", + "substrate-11", + "group-1", + "substrate-13", + "bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/layer_copper.net =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB one line per each type of copper layer +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/layer_copper.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_copper.png =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_copper.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_copper.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.png.text (revision 33253) @@ -0,0 +1,11 @@ +r6630 + +3 lines each on a different layer + +highest point on red to highest point on green +60 x 90 pixels (50x75) + +highest point on red to "nose" (left side) of blue +24 x 6 pixels (20x5) + +(mils) Index: tags/2.3.0/tests/RTT/ref/layer_copper.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_copper.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_copper.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_copper.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_copper.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_copper.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_copper.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.svg (revision 33253) @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/layer_copper.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_copper.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_copper.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: one line per each type of copper layer - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/layer_outline.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: outline layer triangle - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/layer_outline.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb outline layer triangle + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/layer_outline.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.eps (revision 33253) @@ -0,0 +1,39 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: layer_outline.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +% Layer topsilk group 1 drill 0 mask 0 +% Layer outline group 9 drill 0 mask 0 +0.01000 setlinewidth +1 setlinecap +0 0.52549 0.545098 setrgbcolor +0.07500 0.10000 0.07500 0.40000 t +0.07500 0.40000 0.37500 0.40000 t +0.37500 0.40000 0.07500 0.10000 t +% Layer outline group 9 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/layer_outline.exc/layer_outline.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.exc/layer_outline.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.exc/layer_outline.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/layer_outline.exc/layer_outline.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.exc/layer_outline.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.exc/layer_outline.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/layer_outline.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.fcd (revision 33253) @@ -0,0 +1,4 @@ +[FIDOCAD] +PL 15 20 15 80 2 6 +PL 15 80 75 80 2 6 +PL 75 80 15 20 2 6 Index: tags/2.3.0/tests/RTT/ref/layer_outline.gbr/layer_outline.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.gbr/layer_outline.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.gbr/layer_outline.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,16 @@ +G04 start of page 2 for group 9 layer_idx 6 * +G04 Title: outline layer triangle, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD11C,0.0100*% +G54D11*X7500Y40000D02*Y10000D01* +X37500D01* +X7500Y40000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_outline.gbr/layer_outline.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.gbr/layer_outline.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.gbr/layer_outline.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1145 @@ +G04 start of page 3 for group -1 layer_idx 268435461 * +G04 Title: outline layer triangle, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD14C,0.0100*% +%ADD13C,0.0001*% +%ADD12C,0.0060*% +G54D12*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D13*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D12*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D13*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D12*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D13*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D12*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D13*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D12*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D13*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D12*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D13*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D14*X7500Y40000D02*Y10000D01* +X37500D01* +X7500Y40000D01* +G54D12*X12775Y-8000D02*X15775D01* +X16525Y-7250D01* +Y-5450D02*Y-7250D01* +X15775Y-4700D02*X16525Y-5450D01* +X13525Y-4700D02*X15775D01* +X13525Y-2000D02*Y-8000D01* +X12775Y-2000D02*X15775D01* +X16525Y-2750D01* +Y-3950D01* +X15775Y-4700D02*X16525Y-3950D01* +G54D13*G36* +X18325Y-2000D02*X22825D01* +Y-8000D01* +X18325D01* +Y-2000D01* +G37* +G36* +X23725D02*X28225D01* +Y-8000D01* +X23725D01* +Y-2000D01* +G37* +G36* +X29125D02*X33625D01* +Y-8000D01* +X29125D01* +Y-2000D01* +G37* +G36* +X34525D02*X39025D01* +Y-8000D01* +X34525D01* +Y-2000D01* +G37* +G36* +X42625D02*X47125D01* +Y-8000D01* +X42625D01* +Y-2000D01* +G37* +G36* +X48025D02*X52525D01* +Y-8000D01* +X48025D01* +Y-2000D01* +G37* +G36* +X53425D02*X57925D01* +Y-8000D01* +X53425D01* +Y-2000D01* +G37* +G36* +X58825D02*X63325D01* +Y-8000D01* +X58825D01* +Y-2000D01* +G37* +G36* +X64225D02*X68725D01* +Y-8000D01* +X64225D01* +Y-2000D01* +G37* +G36* +X69625D02*X74125D01* +Y-8000D01* +X69625D01* +Y-2000D01* +G37* +G36* +X75025D02*X79525D01* +Y-8000D01* +X75025D01* +Y-2000D01* +G37* +G36* +X83125D02*X87625D01* +Y-8000D01* +X83125D01* +Y-2000D01* +G37* +G36* +X88525D02*X93025D01* +Y-8000D01* +X88525D01* +Y-2000D01* +G37* +G36* +X96625D02*X101125D01* +Y-8000D01* +X96625D01* +Y-2000D01* +G37* +G36* +X102025D02*X106525D01* +Y-8000D01* +X102025D01* +Y-2000D01* +G37* +G36* +X107425D02*X111925D01* +Y-8000D01* +X107425D01* +Y-2000D01* +G37* +G36* +X115525D02*X120025D01* +Y-8000D01* +X115525D01* +Y-2000D01* +G37* +G36* +X120925D02*X125425D01* +Y-8000D01* +X120925D01* +Y-2000D01* +G37* +G36* +X126325D02*X130825D01* +Y-8000D01* +X126325D01* +Y-2000D01* +G37* +G36* +X131725D02*X136225D01* +Y-8000D01* +X131725D01* +Y-2000D01* +G37* +G36* +X137125D02*X141625D01* +Y-8000D01* +X137125D01* +Y-2000D01* +G37* +G36* +X142525D02*X147025D01* +Y-8000D01* +X142525D01* +Y-2000D01* +G37* +G36* +X147925D02*X152425D01* +Y-8000D01* +X147925D01* +Y-2000D01* +G37* +G36* +X153325D02*X157825D01* +Y-8000D01* +X153325D01* +Y-2000D01* +G37* +G36* +X158725D02*X163225D01* +Y-8000D01* +X158725D01* +Y-2000D01* +G37* +G36* +X164125D02*X168625D01* +Y-8000D01* +X164125D01* +Y-2000D01* +G37* +G36* +X172225D02*X176725D01* +Y-8000D01* +X172225D01* +Y-2000D01* +G37* +G36* +X177625D02*X182125D01* +Y-8000D01* +X177625D01* +Y-2000D01* +G37* +G36* +X185725D02*X190225D01* +Y-8000D01* +X185725D01* +Y-2000D01* +G37* +G36* +X191125D02*X195625D01* +Y-8000D01* +X191125D01* +Y-2000D01* +G37* +G36* +X196525D02*X201025D01* +Y-8000D01* +X196525D01* +Y-2000D01* +G37* +G36* +X201925D02*X206425D01* +Y-8000D01* +X201925D01* +Y-2000D01* +G37* +G36* +X210025D02*X214525D01* +Y-8000D01* +X210025D01* +Y-2000D01* +G37* +G36* +X215425D02*X219925D01* +Y-8000D01* +X215425D01* +Y-2000D01* +G37* +G36* +X220825D02*X225325D01* +Y-8000D01* +X220825D01* +Y-2000D01* +G37* +G36* +X226225D02*X230725D01* +Y-8000D01* +X226225D01* +Y-2000D01* +G37* +G54D12*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D13*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D12*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D13*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D12*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D13*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X256100D02*X260600D01* +Y104000D01* +X256100D01* +Y110000D01* +G37* +G36* +X261500D02*X266000D01* +Y104000D01* +X261500D01* +Y110000D01* +G37* +G36* +X266900D02*X271400D01* +Y104000D01* +X266900D01* +Y110000D01* +G37* +G36* +X275000D02*X279500D01* +Y104000D01* +X275000D01* +Y110000D01* +G37* +G36* +X280400D02*X284900D01* +Y104000D01* +X280400D01* +Y110000D01* +G37* +G36* +X285800D02*X290300D01* +Y104000D01* +X285800D01* +Y110000D01* +G37* +G36* +X291200D02*X295700D01* +Y104000D01* +X291200D01* +Y110000D01* +G37* +G36* +X296600D02*X301100D01* +Y104000D01* +X296600D01* +Y110000D01* +G37* +G36* +X304700D02*X309200D01* +Y104000D01* +X304700D01* +Y110000D01* +G37* +G36* +X310100D02*X314600D01* +Y104000D01* +X310100D01* +Y110000D01* +G37* +G36* +X315500D02*X320000D01* +Y104000D01* +X315500D01* +Y110000D01* +G37* +G36* +X320900D02*X325400D01* +Y104000D01* +X320900D01* +Y110000D01* +G37* +G36* +X326300D02*X330800D01* +Y104000D01* +X326300D01* +Y110000D01* +G37* +G36* +X331700D02*X336200D01* +Y104000D01* +X331700D01* +Y110000D01* +G37* +G36* +X337100D02*X341600D01* +Y104000D01* +X337100D01* +Y110000D01* +G37* +G36* +X342500D02*X347000D01* +Y104000D01* +X342500D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G54D12*X358700D02*Y104000D01* +Y110000D02*X361700D01* +X358700Y107300D02*X360950D01* +G54D13*G36* +X363500Y110000D02*X368000D01* +Y104000D01* +X363500D01* +Y110000D01* +G37* +G36* +X368900D02*X373400D01* +Y104000D01* +X368900D01* +Y110000D01* +G37* +G36* +X374300D02*X378800D01* +Y104000D01* +X374300D01* +Y110000D01* +G37* +G36* +X379700D02*X384200D01* +Y104000D01* +X379700D01* +Y110000D01* +G37* +G36* +X385100D02*X389600D01* +Y104000D01* +X385100D01* +Y110000D01* +G37* +G36* +X390500D02*X395000D01* +Y104000D01* +X390500D01* +Y110000D01* +G37* +G36* +X395900D02*X400400D01* +Y104000D01* +X395900D01* +Y110000D01* +G37* +G36* +X401300D02*X405800D01* +Y104000D01* +X401300D01* +Y110000D01* +G37* +G36* +X406700D02*X411200D01* +Y104000D01* +X406700D01* +Y110000D01* +G37* +G36* +X412100D02*X416600D01* +Y104000D01* +X412100D01* +Y110000D01* +G37* +G54D12*X420950D02*Y104000D01* +X422900Y110000D02*X423950Y108950D01* +Y105050D01* +X422900Y104000D02*X423950Y105050D01* +X420200Y104000D02*X422900D01* +X420200Y110000D02*X422900D01* +G54D13*G36* +X425750D02*X430250D01* +Y104000D01* +X425750D01* +Y110000D01* +G37* +G36* +X431150D02*X435650D01* +Y104000D01* +X431150D01* +Y110000D01* +G37* +G36* +X436550D02*X441050D01* +Y104000D01* +X436550D01* +Y110000D01* +G37* +G36* +X441950D02*X446450D01* +Y104000D01* +X441950D01* +Y110000D01* +G37* +G36* +X447350D02*X451850D01* +Y104000D01* +X447350D01* +Y110000D01* +G37* +G36* +X452750D02*X457250D01* +Y104000D01* +X452750D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_outline.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer outline { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "outline" + } +} Index: tags/2.3.0/tests/RTT/ref/layer_outline.net =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB outline layer triangle +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/layer_outline.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_outline.png =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_outline.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_outline.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.png.text (revision 33253) @@ -0,0 +1,6 @@ +triangle +base 372 x h 372 (pixels) (310 x 310 mil) measured to the outside of the line +line thickness is 12 pixels (10mils) + +so the actual triangle dimensions are 300 x 300 mil + Index: tags/2.3.0/tests/RTT/ref/layer_outline.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_outline.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_outline.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_outline.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_outline.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_outline.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_outline.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.svg (revision 33253) @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/layer_outline.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_outline.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_outline.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: outline layer triangle - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/layer_silk.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: one line on each silk layer - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/layer_silk.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb one line on each silk layer + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/layer_silk.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.eps (revision 33253) @@ -0,0 +1,35 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: layer_silk.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +% Layer topsilk group 1 drill 0 mask 0 +0.01000 setlinewidth +1 setlinecap +0 0 0 setrgbcolor +0.05000 0.05000 0.05000 0.42500 t +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/layer_silk.exc/layer_silk.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.exc/layer_silk.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.exc/layer_silk.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/layer_silk.exc/layer_silk.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.exc/layer_silk.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.exc/layer_silk.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/layer_silk.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.fcd (revision 33253) @@ -0,0 +1,3 @@ +[FIDOCAD] +PL 15 85 60 40 2 3 +PL 10 10 10 85 2 3 Index: tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.bottom.silk.none.12.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.bottom.silk.none.12.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.bottom.silk.none.12.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 2 for group 12 layer_idx 7 * +G04 Title: one line on each silk layer, bottom_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_SILK_NONE_12*% +%ADD11C,0.0100*% +G54D11*X7500Y7500D02*X30000Y30000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 4 for group 9 layer_idx 6 * +G04 Title: one line on each silk layer, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD13C,0.0100*% +G54D13*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1789 @@ +G04 start of page 5 for group -1 layer_idx 268435461 * +G04 Title: one line on each silk layer, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD16C,0.0100*% +%ADD15C,0.0001*% +%ADD14C,0.0060*% +G54D14*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D15*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D14*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D15*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D14*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D15*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D14*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D15*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D14*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D15*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D14*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D15*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D16*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D14*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D15*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D14*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D15*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D14*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D15*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D14*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D15*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D14*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D15*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D14*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D15*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D14*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D15*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D14*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D15*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D14*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D15*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D14*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D15*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D14*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D15*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X253400D02*X257900D01* +Y104000D01* +X253400D01* +Y110000D01* +G37* +G36* +X258800D02*X263300D01* +Y104000D01* +X258800D01* +Y110000D01* +G37* +G36* +X264200D02*X268700D01* +Y104000D01* +X264200D01* +Y110000D01* +G37* +G36* +X269600D02*X274100D01* +Y104000D01* +X269600D01* +Y110000D01* +G37* +G36* +X277700D02*X282200D01* +Y104000D01* +X277700D01* +Y110000D01* +G37* +G36* +X283100D02*X287600D01* +Y104000D01* +X283100D01* +Y110000D01* +G37* +G36* +X291200D02*X295700D01* +Y104000D01* +X291200D01* +Y110000D01* +G37* +G36* +X296600D02*X301100D01* +Y104000D01* +X296600D01* +Y110000D01* +G37* +G36* +X302000D02*X306500D01* +Y104000D01* +X302000D01* +Y110000D01* +G37* +G36* +X307400D02*X311900D01* +Y104000D01* +X307400D01* +Y110000D01* +G37* +G36* +X315500D02*X320000D01* +Y104000D01* +X315500D01* +Y110000D01* +G37* +G36* +X320900D02*X325400D01* +Y104000D01* +X320900D01* +Y110000D01* +G37* +G36* +X326300D02*X330800D01* +Y104000D01* +X326300D01* +Y110000D01* +G37* +G36* +X331700D02*X336200D01* +Y104000D01* +X331700D01* +Y110000D01* +G37* +G36* +X339800D02*X344300D01* +Y104000D01* +X339800D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X356000D02*X360500D01* +Y104000D01* +X356000D01* +Y110000D01* +G37* +G36* +X361400D02*X365900D01* +Y104000D01* +X361400D01* +Y110000D01* +G37* +G36* +X369500D02*X374000D01* +Y104000D01* +X369500D01* +Y110000D01* +G37* +G54D14*X377600D02*Y104000D01* +Y110000D02*X380600D01* +X377600Y107300D02*X379850D01* +G54D15*G36* +X382400Y110000D02*X386900D01* +Y104000D01* +X382400D01* +Y110000D01* +G37* +G36* +X387800D02*X392300D01* +Y104000D01* +X387800D01* +Y110000D01* +G37* +G36* +X393200D02*X397700D01* +Y104000D01* +X393200D01* +Y110000D01* +G37* +G36* +X398600D02*X403100D01* +Y104000D01* +X398600D01* +Y110000D01* +G37* +G36* +X404000D02*X408500D01* +Y104000D01* +X404000D01* +Y110000D01* +G37* +G36* +X409400D02*X413900D01* +Y104000D01* +X409400D01* +Y110000D01* +G37* +G36* +X414800D02*X419300D01* +Y104000D01* +X414800D01* +Y110000D01* +G37* +G36* +X420200D02*X424700D01* +Y104000D01* +X420200D01* +Y110000D01* +G37* +G36* +X425600D02*X430100D01* +Y104000D01* +X425600D01* +Y110000D01* +G37* +G36* +X431000D02*X435500D01* +Y104000D01* +X431000D01* +Y110000D01* +G37* +G54D14*X439850D02*Y104000D01* +X441800Y110000D02*X442850Y108950D01* +Y105050D01* +X441800Y104000D02*X442850Y105050D01* +X439100Y104000D02*X441800D01* +X439100Y110000D02*X441800D01* +G54D15*G36* +X444650D02*X449150D01* +Y104000D01* +X444650D01* +Y110000D01* +G37* +G36* +X450050D02*X454550D01* +Y104000D01* +X450050D01* +Y110000D01* +G37* +G36* +X455450D02*X459950D01* +Y104000D01* +X455450D01* +Y110000D01* +G37* +G36* +X460850D02*X465350D01* +Y104000D01* +X460850D01* +Y110000D01* +G37* +G36* +X466250D02*X470750D01* +Y104000D01* +X466250D01* +Y110000D01* +G37* +G36* +X471650D02*X476150D01* +Y104000D01* +X471650D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.gbr/layer_silk.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 3 for group 1 layer_idx 8 * +G04 Title: one line on each silk layer, top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD12C,0.0100*% +G54D12*X5000Y45000D02*Y7500D01* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_silk.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.nelma.em (revision 33253) @@ -0,0 +1,51 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/layer_silk.net =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB one line on each silk layer +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/layer_silk.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_silk.png =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_silk.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_silk.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.png.text (revision 33253) @@ -0,0 +1,8 @@ +r6630 + +line +width 12 pixels (10) +length 462 pixels (385) + +(mil) + Index: tags/2.3.0/tests/RTT/ref/layer_silk.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_silk.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_silk.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_silk.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_silk.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_silk.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_silk.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.svg (revision 33253) @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/layer_silk.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_silk.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_silk.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: one line on each silk layer - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/layer_spc.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: space (and other dangerous characters) in layer name - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/layer_spc.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.dsn (revision 33253) @@ -0,0 +1,57 @@ +(pcb space (and other dangerous characters) in layer name + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "gEDA pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "component 1" + (type signal) + ) + (layer "inner(1)" + (type signal) + ) + (layer "inner/2" + (type signal) + ) + (layer "out:line" + (type signal) + ) + (layer "solder 1" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + (padstack via_685800_381000 + (shape (circle signal 0.685800)) + (attach off) + ) + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/layer_spc.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.eps (revision 33253) @@ -0,0 +1,32 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: layer_spc.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 13 drill 0 mask 0 +% Layer bottom group 11 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer group9 group 9 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/layer_spc.exc/layer_spc.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.exc/layer_spc.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.exc/layer_spc.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/layer_spc.exc/layer_spc.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.exc/layer_spc.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.exc/layer_spc.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/layer_spc.gbr/layer_spc.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.gbr/layer_spc.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.gbr/layer_spc.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1927 @@ +G04 start of page 2 for group -1 layer_idx 268435461 * +G04 Title: space (and other dangerous characters) in layer name, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD13C,0.0100*% +%ADD12C,0.0001*% +%ADD11C,0.0060*% +G54D11*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D12*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D11*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D12*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D11*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D12*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D11*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D12*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D11*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D12*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D11*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D12*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D13*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D11*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D12*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D11*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D12*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D11*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D12*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D11*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D12*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D11*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D12*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D11*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D12*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D11*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D12*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D11*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D12*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D11*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D12*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D11*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D12*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D11*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D12*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X256100D02*X260600D01* +Y104000D01* +X256100D01* +Y110000D01* +G37* +G36* +X264200D02*X268700D01* +Y104000D01* +X264200D01* +Y110000D01* +G37* +G36* +X269600D02*X274100D01* +Y104000D01* +X269600D01* +Y110000D01* +G37* +G36* +X275000D02*X279500D01* +Y104000D01* +X275000D01* +Y110000D01* +G37* +G36* +X280400D02*X284900D01* +Y104000D01* +X280400D01* +Y110000D01* +G37* +G36* +X288500D02*X293000D01* +Y104000D01* +X288500D01* +Y110000D01* +G37* +G36* +X293900D02*X298400D01* +Y104000D01* +X293900D01* +Y110000D01* +G37* +G36* +X299300D02*X303800D01* +Y104000D01* +X299300D01* +Y110000D01* +G37* +G36* +X304700D02*X309200D01* +Y104000D01* +X304700D01* +Y110000D01* +G37* +G36* +X310100D02*X314600D01* +Y104000D01* +X310100D01* +Y110000D01* +G37* +G36* +X318200D02*X322700D01* +Y104000D01* +X318200D01* +Y110000D01* +G37* +G36* +X323600D02*X328100D01* +Y104000D01* +X323600D01* +Y110000D01* +G37* +G36* +X329000D02*X333500D01* +Y104000D01* +X329000D01* +Y110000D01* +G37* +G36* +X334400D02*X338900D01* +Y104000D01* +X334400D01* +Y110000D01* +G37* +G36* +X339800D02*X344300D01* +Y104000D01* +X339800D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X356000D02*X360500D01* +Y104000D01* +X356000D01* +Y110000D01* +G37* +G36* +X361400D02*X365900D01* +Y104000D01* +X361400D01* +Y110000D01* +G37* +G36* +X369500D02*X374000D01* +Y104000D01* +X369500D01* +Y110000D01* +G37* +G36* +X374900D02*X379400D01* +Y104000D01* +X374900D01* +Y110000D01* +G37* +G36* +X380300D02*X384800D01* +Y104000D01* +X380300D01* +Y110000D01* +G37* +G36* +X385700D02*X390200D01* +Y104000D01* +X385700D01* +Y110000D01* +G37* +G36* +X391100D02*X395600D01* +Y104000D01* +X391100D01* +Y110000D01* +G37* +G36* +X396500D02*X401000D01* +Y104000D01* +X396500D01* +Y110000D01* +G37* +G36* +X401900D02*X406400D01* +Y104000D01* +X401900D01* +Y110000D01* +G37* +G36* +X407300D02*X411800D01* +Y104000D01* +X407300D01* +Y110000D01* +G37* +G36* +X412700D02*X417200D01* +Y104000D01* +X412700D01* +Y110000D01* +G37* +G36* +X418100D02*X422600D01* +Y104000D01* +X418100D01* +Y110000D01* +G37* +G36* +X423500D02*X428000D01* +Y104000D01* +X423500D01* +Y110000D01* +G37* +G36* +X431600D02*X436100D01* +Y104000D01* +X431600D01* +Y110000D01* +G37* +G36* +X437000D02*X441500D01* +Y104000D01* +X437000D01* +Y110000D01* +G37* +G36* +X445100D02*X449600D01* +Y104000D01* +X445100D01* +Y110000D01* +G37* +G36* +X450500D02*X455000D01* +Y104000D01* +X450500D01* +Y110000D01* +G37* +G36* +X455900D02*X460400D01* +Y104000D01* +X455900D01* +Y110000D01* +G37* +G36* +X461300D02*X465800D01* +Y104000D01* +X461300D01* +Y110000D01* +G37* +G36* +X466700D02*X471200D01* +Y104000D01* +X466700D01* +Y110000D01* +G37* +G36* +X474800D02*X479300D01* +Y104000D01* +X474800D01* +Y110000D01* +G37* +G36* +X480200D02*X484700D01* +Y104000D01* +X480200D01* +Y110000D01* +G37* +G36* +X485600D02*X490100D01* +Y104000D01* +X485600D01* +Y110000D01* +G37* +G36* +X491000D02*X495500D01* +Y104000D01* +X491000D01* +Y110000D01* +G37* +G36* +X499100D02*X503600D01* +Y104000D01* +X499100D01* +Y110000D01* +G37* +G54D11*X507200D02*Y104000D01* +Y110000D02*X510200D01* +X507200Y107300D02*X509450D01* +G54D12*G36* +X512000Y110000D02*X516500D01* +Y104000D01* +X512000D01* +Y110000D01* +G37* +G36* +X517400D02*X521900D01* +Y104000D01* +X517400D01* +Y110000D01* +G37* +G36* +X522800D02*X527300D01* +Y104000D01* +X522800D01* +Y110000D01* +G37* +G36* +X528200D02*X532700D01* +Y104000D01* +X528200D01* +Y110000D01* +G37* +G36* +X533600D02*X538100D01* +Y104000D01* +X533600D01* +Y110000D01* +G37* +G36* +X539000D02*X543500D01* +Y104000D01* +X539000D01* +Y110000D01* +G37* +G36* +X544400D02*X548900D01* +Y104000D01* +X544400D01* +Y110000D01* +G37* +G36* +X549800D02*X554300D01* +Y104000D01* +X549800D01* +Y110000D01* +G37* +G36* +X555200D02*X559700D01* +Y104000D01* +X555200D01* +Y110000D01* +G37* +G36* +X560600D02*X565100D01* +Y104000D01* +X560600D01* +Y110000D01* +G37* +G54D11*X569450D02*Y104000D01* +X571400Y110000D02*X572450Y108950D01* +Y105050D01* +X571400Y104000D02*X572450Y105050D01* +X568700Y104000D02*X571400D01* +X568700Y110000D02*X571400D01* +G54D12*G36* +X574250D02*X578750D01* +Y104000D01* +X574250D01* +Y110000D01* +G37* +G36* +X579650D02*X584150D01* +Y104000D01* +X579650D01* +Y110000D01* +G37* +G36* +X585050D02*X589550D01* +Y104000D01* +X585050D01* +Y110000D01* +G37* +G36* +X590450D02*X594950D01* +Y104000D01* +X590450D01* +Y110000D01* +G37* +G36* +X595850D02*X600350D01* +Y104000D01* +X595850D01* +Y110000D01* +G37* +G36* +X601250D02*X605750D01* +Y104000D01* +X601250D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/layer_spc.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.nelma.em (revision 33253) @@ -0,0 +1,51 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/layer_spc.net =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB space (and other dangerous characters) in layer name +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/layer_spc.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_spc.png =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_spc.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_spc.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.png.text (revision 33253) @@ -0,0 +1,4 @@ +empty page 600 x 600 pixels (500 x 500) + +(mil) + Index: tags/2.3.0/tests/RTT/ref/layer_spc.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_spc.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_spc.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_spc.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/layer_spc.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/layer_spc.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/layer_spc.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.svg (revision 33253) @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/layer_spc.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/layer_spc.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/layer_spc.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: space (and other dangerous characters) in layer name - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_f_clear.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Clear and no-clear lines - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_f_clear.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.dsn (revision 33253) @@ -0,0 +1,58 @@ +(pcb Clear and no-clear lines + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 0.381000 3.175000 6.350000 10.160000 6.350000) + (type protect)) + (wire (path 3__top_copper 0.254000 6.350000 9.525000 6.350000 3.175000) + (type protect)) + (wire (path 3__top_copper 0.508000 6.350000 6.350000 10.160000 7.620000) + (type protect)) + (wire (path 3__top_copper 0.127000 6.350000 6.350000 3.810000 8.890000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/line_f_clear.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.eps (revision 33253) @@ -0,0 +1,145 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: line_f_clear.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.47500 0.02500 moveto +0.47500 0.47500 lineto +0.26250 0.47500 lineto +0.26250 0.42033 lineto +0.26457 0.41984 lineto +0.27140 0.41701 lineto +0.27771 0.41314 lineto +0.28334 0.40834 lineto +0.28814 0.40271 lineto +0.29201 0.39640 lineto +0.29484 0.38957 lineto +0.29656 0.38238 lineto +0.29700 0.37500 lineto +0.29700 0.26950 lineto +0.40000 0.26950 lineto +0.40306 0.26932 lineto +0.40604 0.26860 lineto +0.40888 0.26743 lineto +0.41150 0.26582 lineto +0.41383 0.26383 lineto +0.41582 0.26150 lineto +0.41743 0.25888 lineto +0.41860 0.25604 lineto +0.41932 0.25306 lineto +0.41956 0.25000 lineto +0.41932 0.24694 lineto +0.41860 0.24396 lineto +0.41743 0.24112 lineto +0.41582 0.23850 lineto +0.41383 0.23617 lineto +0.41150 0.23418 lineto +0.40888 0.23257 lineto +0.40604 0.23140 lineto +0.40306 0.23068 lineto +0.40000 0.23050 lineto +0.29700 0.23050 lineto +0.29700 0.12500 lineto +0.29656 0.11762 lineto +0.29484 0.11043 lineto +0.29201 0.10360 lineto +0.28814 0.09729 lineto +0.28334 0.09166 lineto +0.27771 0.08686 lineto +0.27140 0.08299 lineto +0.26457 0.08016 lineto +0.26250 0.07967 lineto +0.26250 0.02500 lineto +fill +0.26250 0.02500 moveto +0.26250 0.07967 lineto +0.25738 0.07844 lineto +0.25000 0.07786 lineto +0.24262 0.07844 lineto +0.23543 0.08016 lineto +0.22860 0.08299 lineto +0.22229 0.08686 lineto +0.21666 0.09166 lineto +0.21186 0.09729 lineto +0.20799 0.10360 lineto +0.20516 0.11043 lineto +0.20344 0.11762 lineto +0.20300 0.12500 lineto +0.20300 0.23050 lineto +0.12500 0.23050 lineto +0.12194 0.23068 lineto +0.11896 0.23140 lineto +0.11612 0.23257 lineto +0.11350 0.23418 lineto +0.11117 0.23617 lineto +0.10918 0.23850 lineto +0.10757 0.24112 lineto +0.10640 0.24396 lineto +0.10568 0.24694 lineto +0.10544 0.25000 lineto +0.10568 0.25306 lineto +0.10640 0.25604 lineto +0.10757 0.25888 lineto +0.10918 0.26150 lineto +0.11117 0.26383 lineto +0.11350 0.26582 lineto +0.11612 0.26743 lineto +0.11896 0.26860 lineto +0.12194 0.26932 lineto +0.12500 0.26950 lineto +0.20300 0.26950 lineto +0.20300 0.37500 lineto +0.20344 0.38238 lineto +0.20516 0.38957 lineto +0.20799 0.39640 lineto +0.21186 0.40271 lineto +0.21666 0.40834 lineto +0.22229 0.41314 lineto +0.22860 0.41701 lineto +0.23543 0.41984 lineto +0.24262 0.42156 lineto +0.25000 0.42214 lineto +0.25738 0.42156 lineto +0.26250 0.42033 lineto +0.26250 0.47500 lineto +0.02500 0.47500 lineto +0.02500 0.02500 lineto +fill +0.01500 setlinewidth +1 setlinecap +0.12500 0.25000 0.40000 0.25000 t +0.01000 setlinewidth +0.25000 0.12500 0.25000 0.37500 t +0.02000 setlinewidth +0.25000 0.25000 0.40000 0.20000 t +0.00500 setlinewidth +0.25000 0.25000 0.15000 0.15000 t +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/line_f_clear.exc/line_f_clear.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.exc/line_f_clear.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.exc/line_f_clear.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_f_clear.exc/line_f_clear.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.exc/line_f_clear.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.exc/line_f_clear.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_f_clear.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.fcd (revision 33253) @@ -0,0 +1,6 @@ +[FIDOCAD] +PL 25 50 80 50 3 2 +PL 50 25 50 75 2 2 +PL 50 50 80 40 4 2 +PL 50 50 30 30 1 2 +PP 5 5 95 5 95 95 5 95 5 5 2 Index: tags/2.3.0/tests/RTT/ref/line_f_clear.gbr/line_f_clear.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.gbr/line_f_clear.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.gbr/line_f_clear.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Clear and no-clear lines, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD16C,0.0100*% +G54D16*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_f_clear.gbr/line_f_clear.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.gbr/line_f_clear.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.gbr/line_f_clear.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1782 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Clear and no-clear lines, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD19C,0.0100*% +%ADD18C,0.0001*% +%ADD17C,0.0060*% +G54D17*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D18*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D17*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D18*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D17*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D18*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D17*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D18*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D17*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D18*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D17*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D18*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D19*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D17*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D18*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D17*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D18*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D17*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D18*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D17*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D18*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D17*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D18*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D17*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D18*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D17*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D18*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D17*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D18*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D17*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D18*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D17*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D18*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D17*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D18*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D17*X235550Y104000D02*X237500D01* +X234500Y105050D02*X235550Y104000D01* +X234500Y108950D02*Y105050D01* +Y108950D02*X235550Y110000D01* +X237500D01* +G54D18*G36* +X239300D02*X243800D01* +Y104000D01* +X239300D01* +Y110000D01* +G37* +G36* +X244700D02*X249200D01* +Y104000D01* +X244700D01* +Y110000D01* +G37* +G36* +X250100D02*X254600D01* +Y104000D01* +X250100D01* +Y110000D01* +G37* +G36* +X255500D02*X260000D01* +Y104000D01* +X255500D01* +Y110000D01* +G37* +G36* +X263600D02*X268100D01* +Y104000D01* +X263600D01* +Y110000D01* +G37* +G36* +X269000D02*X273500D01* +Y104000D01* +X269000D01* +Y110000D01* +G37* +G36* +X274400D02*X278900D01* +Y104000D01* +X274400D01* +Y110000D01* +G37* +G36* +X282500D02*X287000D01* +Y104000D01* +X282500D01* +Y110000D01* +G37* +G36* +X287900D02*X292400D01* +Y104000D01* +X287900D01* +Y110000D01* +G37* +G36* +X293300D02*X297800D01* +Y104000D01* +X293300D01* +Y110000D01* +G37* +G36* +X298700D02*X303200D01* +Y104000D01* +X298700D01* +Y110000D01* +G37* +G36* +X304100D02*X308600D01* +Y104000D01* +X304100D01* +Y110000D01* +G37* +G36* +X309500D02*X314000D01* +Y104000D01* +X309500D01* +Y110000D01* +G37* +G36* +X314900D02*X319400D01* +Y104000D01* +X314900D01* +Y110000D01* +G37* +G36* +X320300D02*X324800D01* +Y104000D01* +X320300D01* +Y110000D01* +G37* +G36* +X328400D02*X332900D01* +Y104000D01* +X328400D01* +Y110000D01* +G37* +G36* +X333800D02*X338300D01* +Y104000D01* +X333800D01* +Y110000D01* +G37* +G36* +X339200D02*X343700D01* +Y104000D01* +X339200D01* +Y110000D01* +G37* +G36* +X344600D02*X349100D01* +Y104000D01* +X344600D01* +Y110000D01* +G37* +G36* +X350000D02*X354500D01* +Y104000D01* +X350000D01* +Y110000D01* +G37* +G36* +X358100D02*X362600D01* +Y104000D01* +X358100D01* +Y110000D01* +G37* +G54D17*X366200D02*Y104000D01* +Y110000D02*X369200D01* +X366200Y107300D02*X368450D01* +G54D18*G36* +X371000Y110000D02*X375500D01* +Y104000D01* +X371000D01* +Y110000D01* +G37* +G36* +X376400D02*X380900D01* +Y104000D01* +X376400D01* +Y110000D01* +G37* +G36* +X381800D02*X386300D01* +Y104000D01* +X381800D01* +Y110000D01* +G37* +G36* +X387200D02*X391700D01* +Y104000D01* +X387200D01* +Y110000D01* +G37* +G36* +X392600D02*X397100D01* +Y104000D01* +X392600D01* +Y110000D01* +G37* +G36* +X398000D02*X402500D01* +Y104000D01* +X398000D01* +Y110000D01* +G37* +G36* +X403400D02*X407900D01* +Y104000D01* +X403400D01* +Y110000D01* +G37* +G36* +X408800D02*X413300D01* +Y104000D01* +X408800D01* +Y110000D01* +G37* +G36* +X414200D02*X418700D01* +Y104000D01* +X414200D01* +Y110000D01* +G37* +G36* +X419600D02*X424100D01* +Y104000D01* +X419600D01* +Y110000D01* +G37* +G54D17*X428450D02*Y104000D01* +X430400Y110000D02*X431450Y108950D01* +Y105050D01* +X430400Y104000D02*X431450Y105050D01* +X427700Y104000D02*X430400D01* +X427700Y110000D02*X430400D01* +G54D18*G36* +X433250D02*X437750D01* +Y104000D01* +X433250D01* +Y110000D01* +G37* +G36* +X438650D02*X443150D01* +Y104000D01* +X438650D01* +Y110000D01* +G37* +G36* +X444050D02*X448550D01* +Y104000D01* +X444050D01* +Y110000D01* +G37* +G36* +X449450D02*X453950D01* +Y104000D01* +X449450D01* +Y110000D01* +G37* +G36* +X454850D02*X459350D01* +Y104000D01* +X454850D01* +Y110000D01* +G37* +G36* +X460250D02*X464750D01* +Y104000D01* +X460250D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/line_f_clear.gbr/line_f_clear.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.gbr/line_f_clear.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.gbr/line_f_clear.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,125 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Clear and no-clear lines, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD15C,0.0050*% +%ADD14C,0.0200*% +%ADD13C,0.0100*% +%ADD12C,0.0150*% +%ADD11C,0.0001*% +G54D11*G36* +X47500Y47500D02*Y2500D01* +X26250D01* +Y7967D01* +X26457Y8016D01* +X27140Y8299D01* +X27771Y8686D01* +X28334Y9166D01* +X28814Y9729D01* +X29201Y10360D01* +X29484Y11043D01* +X29656Y11762D01* +X29700Y12500D01* +Y23050D01* +X40000D01* +X40306Y23068D01* +X40604Y23140D01* +X40888Y23257D01* +X41150Y23418D01* +X41383Y23617D01* +X41582Y23850D01* +X41743Y24112D01* +X41860Y24396D01* +X41932Y24694D01* +X41956Y25000D01* +X41932Y25306D01* +X41860Y25604D01* +X41743Y25888D01* +X41582Y26150D01* +X41383Y26383D01* +X41150Y26582D01* +X40888Y26743D01* +X40604Y26860D01* +X40306Y26932D01* +X40000Y26950D01* +X29700D01* +Y37500D01* +X29656Y38238D01* +X29484Y38957D01* +X29201Y39640D01* +X28814Y40271D01* +X28334Y40834D01* +X27771Y41314D01* +X27140Y41701D01* +X26457Y41984D01* +X26250Y42033D01* +Y47500D01* +X47500D01* +G37* +G36* +X26250D02*Y42033D01* +X25738Y42156D01* +X25000Y42214D01* +X24262Y42156D01* +X23543Y41984D01* +X22860Y41701D01* +X22229Y41314D01* +X21666Y40834D01* +X21186Y40271D01* +X20799Y39640D01* +X20516Y38957D01* +X20344Y38238D01* +X20300Y37500D01* +Y26950D01* +X12500D01* +X12194Y26932D01* +X11896Y26860D01* +X11612Y26743D01* +X11350Y26582D01* +X11117Y26383D01* +X10918Y26150D01* +X10757Y25888D01* +X10640Y25604D01* +X10568Y25306D01* +X10544Y25000D01* +X10568Y24694D01* +X10640Y24396D01* +X10757Y24112D01* +X10918Y23850D01* +X11117Y23617D01* +X11350Y23418D01* +X11612Y23257D01* +X11896Y23140D01* +X12194Y23068D01* +X12500Y23050D01* +X20300D01* +Y12500D01* +X20344Y11762D01* +X20516Y11043D01* +X20799Y10360D01* +X21186Y9729D01* +X21666Y9166D01* +X22229Y8686D01* +X22860Y8299D01* +X23543Y8016D01* +X24262Y7844D01* +X25000Y7786D01* +X25738Y7844D01* +X26250Y7967D01* +Y2500D01* +X2500D01* +Y47500D01* +X26250D01* +G37* +G54D12*X12500Y25000D02*X40000D01* +G54D13*X25000Y37500D02*Y12500D01* +G54D14*Y25000D02*X40000Y30000D01* +G54D15*X25000Y25000D02*X15000Y35000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_f_clear.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/line_f_clear.net =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Clear and no-clear lines +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/line_f_clear.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_f_clear.png =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_f_clear.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_f_clear.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.png.text (revision 33253) @@ -0,0 +1,24 @@ +r6630 + +rectangle +width 541 pixels (450.833) +height 541 pixels (450.833) + +veritcal line +width 12 pixels (10) +length 312 pixels (260) +clearance 49/50 pixels (left/right) (40.833/41.667) + +horizontal line +width 18 pixels (15) +length 348 pixels (290) +clearance 14/14 pixels (top/bottom) (11.666/12.5) + +left diangonal line +45 degrees + +right diagonal line +18 degrees + +(mil) + Index: tags/2.3.0/tests/RTT/ref/line_f_clear.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_f_clear.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_f_clear.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_f_clear.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_f_clear.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_f_clear.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_f_clear.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.svg (revision 33253) @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/line_f_clear.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/line_f_clear.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_f_clear.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Clear and no-clear lines - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_normal.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Normal lines at different size and angle - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_normal.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.dsn (revision 33253) @@ -0,0 +1,58 @@ +(pcb Normal lines at different size and angle + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 0.381000 3.175000 6.350000 10.160000 6.350000) + (type protect)) + (wire (path 3__top_copper 0.254000 6.350000 9.525000 6.350000 3.175000) + (type protect)) + (wire (path 3__top_copper 0.508000 6.350000 6.350000 10.160000 7.620000) + (type protect)) + (wire (path 3__top_copper 0.127000 6.350000 6.350000 3.810000 8.890000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/line_normal.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.eps (revision 33253) @@ -0,0 +1,41 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: line_normal.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.01500 setlinewidth +1 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.12500 0.25000 0.40000 0.25000 t +0.01000 setlinewidth +0.25000 0.12500 0.25000 0.37500 t +0.02000 setlinewidth +0.25000 0.25000 0.40000 0.20000 t +0.00500 setlinewidth +0.25000 0.25000 0.15000 0.15000 t +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/line_normal.exc/line_normal.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.exc/line_normal.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.exc/line_normal.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_normal.exc/line_normal.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.exc/line_normal.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.exc/line_normal.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_normal.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.fcd (revision 33253) @@ -0,0 +1,5 @@ +[FIDOCAD] +PL 25 50 80 50 3 2 +PL 50 25 50 75 2 2 +PL 50 50 80 40 4 2 +PL 50 50 30 30 1 2 Index: tags/2.3.0/tests/RTT/ref/line_normal.gbr/line_normal.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.gbr/line_normal.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.gbr/line_normal.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Normal lines at different size and angle, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD15C,0.0100*% +G54D15*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_normal.gbr/line_normal.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.gbr/line_normal.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.gbr/line_normal.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1858 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Normal lines at different size and angle, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD18C,0.0100*% +%ADD17C,0.0001*% +%ADD16C,0.0060*% +G54D16*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D17*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D16*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D17*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D16*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D17*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D16*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D17*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D16*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D17*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D16*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D17*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D18*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D16*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D17*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D16*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D17*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D16*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D17*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D16*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D17*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D16*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D17*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D16*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D17*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D16*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D17*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D16*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D17*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D16*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D17*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D16*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D17*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D16*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D17*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D16*X234500D02*Y104000D01* +Y110000D02*X238250Y104000D01* +Y110000D02*Y104000D01* +G54D17*G36* +X240050Y110000D02*X244550D01* +Y104000D01* +X240050D01* +Y110000D01* +G37* +G36* +X245450D02*X249950D01* +Y104000D01* +X245450D01* +Y110000D01* +G37* +G36* +X250850D02*X255350D01* +Y104000D01* +X250850D01* +Y110000D01* +G37* +G36* +X256250D02*X260750D01* +Y104000D01* +X256250D01* +Y110000D01* +G37* +G36* +X261650D02*X266150D01* +Y104000D01* +X261650D01* +Y110000D01* +G37* +G36* +X269750D02*X274250D01* +Y104000D01* +X269750D01* +Y110000D01* +G37* +G36* +X275150D02*X279650D01* +Y104000D01* +X275150D01* +Y110000D01* +G37* +G36* +X280550D02*X285050D01* +Y104000D01* +X280550D01* +Y110000D01* +G37* +G36* +X285950D02*X290450D01* +Y104000D01* +X285950D01* +Y110000D01* +G37* +G36* +X291350D02*X295850D01* +Y104000D01* +X291350D01* +Y110000D01* +G37* +G36* +X299450D02*X303950D01* +Y104000D01* +X299450D01* +Y110000D01* +G37* +G36* +X304850D02*X309350D01* +Y104000D01* +X304850D01* +Y110000D01* +G37* +G36* +X312950D02*X317450D01* +Y104000D01* +X312950D01* +Y110000D01* +G37* +G36* +X318350D02*X322850D01* +Y104000D01* +X318350D01* +Y110000D01* +G37* +G36* +X323750D02*X328250D01* +Y104000D01* +X323750D01* +Y110000D01* +G37* +G36* +X329150D02*X333650D01* +Y104000D01* +X329150D01* +Y110000D01* +G37* +G36* +X334550D02*X339050D01* +Y104000D01* +X334550D01* +Y110000D01* +G37* +G36* +X339950D02*X344450D01* +Y104000D01* +X339950D01* +Y110000D01* +G37* +G36* +X345350D02*X349850D01* +Y104000D01* +X345350D01* +Y110000D01* +G37* +G36* +X350750D02*X355250D01* +Y104000D01* +X350750D01* +Y110000D01* +G37* +G36* +X356150D02*X360650D01* +Y104000D01* +X356150D01* +Y110000D01* +G37* +G36* +X364250D02*X368750D01* +Y104000D01* +X364250D01* +Y110000D01* +G37* +G36* +X369650D02*X374150D01* +Y104000D01* +X369650D01* +Y110000D01* +G37* +G36* +X375050D02*X379550D01* +Y104000D01* +X375050D01* +Y110000D01* +G37* +G36* +X380450D02*X384950D01* +Y104000D01* +X380450D01* +Y110000D01* +G37* +G36* +X388550D02*X393050D01* +Y104000D01* +X388550D01* +Y110000D01* +G37* +G36* +X393950D02*X398450D01* +Y104000D01* +X393950D01* +Y110000D01* +G37* +G36* +X399350D02*X403850D01* +Y104000D01* +X399350D01* +Y110000D01* +G37* +G36* +X407450D02*X411950D01* +Y104000D01* +X407450D01* +Y110000D01* +G37* +G36* +X412850D02*X417350D01* +Y104000D01* +X412850D01* +Y110000D01* +G37* +G36* +X418250D02*X422750D01* +Y104000D01* +X418250D01* +Y110000D01* +G37* +G36* +X423650D02*X428150D01* +Y104000D01* +X423650D01* +Y110000D01* +G37* +G36* +X429050D02*X433550D01* +Y104000D01* +X429050D01* +Y110000D01* +G37* +G36* +X437150D02*X441650D01* +Y104000D01* +X437150D01* +Y110000D01* +G37* +G54D16*X445250D02*Y104000D01* +Y110000D02*X448250D01* +X445250Y107300D02*X447500D01* +G54D17*G36* +X450050Y110000D02*X454550D01* +Y104000D01* +X450050D01* +Y110000D01* +G37* +G36* +X455450D02*X459950D01* +Y104000D01* +X455450D01* +Y110000D01* +G37* +G36* +X460850D02*X465350D01* +Y104000D01* +X460850D01* +Y110000D01* +G37* +G36* +X466250D02*X470750D01* +Y104000D01* +X466250D01* +Y110000D01* +G37* +G36* +X471650D02*X476150D01* +Y104000D01* +X471650D01* +Y110000D01* +G37* +G36* +X477050D02*X481550D01* +Y104000D01* +X477050D01* +Y110000D01* +G37* +G36* +X482450D02*X486950D01* +Y104000D01* +X482450D01* +Y110000D01* +G37* +G36* +X487850D02*X492350D01* +Y104000D01* +X487850D01* +Y110000D01* +G37* +G36* +X493250D02*X497750D01* +Y104000D01* +X493250D01* +Y110000D01* +G37* +G36* +X498650D02*X503150D01* +Y104000D01* +X498650D01* +Y110000D01* +G37* +G54D16*X507500D02*Y104000D01* +X509450Y110000D02*X510500Y108950D01* +Y105050D01* +X509450Y104000D02*X510500Y105050D01* +X506750Y104000D02*X509450D01* +X506750Y110000D02*X509450D01* +G54D17*G36* +X512300D02*X516800D01* +Y104000D01* +X512300D01* +Y110000D01* +G37* +G36* +X517700D02*X522200D01* +Y104000D01* +X517700D01* +Y110000D01* +G37* +G36* +X523100D02*X527600D01* +Y104000D01* +X523100D01* +Y110000D01* +G37* +G36* +X528500D02*X533000D01* +Y104000D01* +X528500D01* +Y110000D01* +G37* +G36* +X533900D02*X538400D01* +Y104000D01* +X533900D01* +Y110000D01* +G37* +G36* +X539300D02*X543800D01* +Y104000D01* +X539300D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/line_normal.gbr/line_normal.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.gbr/line_normal.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.gbr/line_normal.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,20 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Normal lines at different size and angle, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD14C,0.0050*% +%ADD13C,0.0200*% +%ADD12C,0.0100*% +%ADD11C,0.0150*% +G54D11*X12500Y25000D02*X40000D01* +G54D12*X25000Y37500D02*Y12500D01* +G54D13*Y25000D02*X40000Y30000D01* +G54D14*X25000Y25000D02*X15000Y35000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_normal.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/line_normal.net =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Normal lines at different size and angle +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/line_normal.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_normal.png =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_normal.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_normal.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.png.text (revision 33253) @@ -0,0 +1,13 @@ +horizontal line +348 pixels (290) +18 pixel thickness (15) + +vertical line +312 pixels long (260) +12 pixel thickness (10) + +fine diagonal line +7.07 pixels (5.892) + +thick diagonal line +unsure of readings Index: tags/2.3.0/tests/RTT/ref/line_normal.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_normal.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_normal.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_normal.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_normal.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_normal.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_normal.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.svg (revision 33253) @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/line_normal.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/line_normal.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_normal.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Normal lines at different size and angle - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_offpage.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: A single line that extends beyond board boundary - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_offpage.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.dsn (revision 33253) @@ -0,0 +1,52 @@ +(pcb A single line that extends beyond board boundary + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 0.254000 2.540000 7.620000 15.240000 7.620000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/line_offpage.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.eps (revision 33253) @@ -0,0 +1,35 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: line_offpage.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.01000 setlinewidth +1 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.10000 0.20000 0.60000 0.20000 t +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/line_offpage.exc/line_offpage.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.exc/line_offpage.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.exc/line_offpage.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_offpage.exc/line_offpage.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.exc/line_offpage.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.exc/line_offpage.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_offpage.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.fcd (revision 33253) @@ -0,0 +1,2 @@ +[FIDOCAD] +PL 20 40 120 40 2 2 Index: tags/2.3.0/tests/RTT/ref/line_offpage.gbr/line_offpage.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.gbr/line_offpage.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.gbr/line_offpage.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: A single line that extends beyond board boundary, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_offpage.gbr/line_offpage.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.gbr/line_offpage.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.gbr/line_offpage.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1903 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: A single line that extends beyond board boundary, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D13*X234500Y108500D02*Y104000D01* +Y108500D02*X235550Y110000D01* +X237200D01* +X238250Y108500D01* +Y104000D01* +X234500Y107000D02*X238250D01* +G54D14*G36* +X242750Y110000D02*X247250D01* +Y104000D01* +X242750D01* +Y110000D01* +G37* +G36* +X248150D02*X252650D01* +Y104000D01* +X248150D01* +Y110000D01* +G37* +G36* +X253550D02*X258050D01* +Y104000D01* +X253550D01* +Y110000D01* +G37* +G36* +X258950D02*X263450D01* +Y104000D01* +X258950D01* +Y110000D01* +G37* +G36* +X264350D02*X268850D01* +Y104000D01* +X264350D01* +Y110000D01* +G37* +G36* +X269750D02*X274250D01* +Y104000D01* +X269750D01* +Y110000D01* +G37* +G36* +X277850D02*X282350D01* +Y104000D01* +X277850D01* +Y110000D01* +G37* +G36* +X283250D02*X287750D01* +Y104000D01* +X283250D01* +Y110000D01* +G37* +G36* +X288650D02*X293150D01* +Y104000D01* +X288650D01* +Y110000D01* +G37* +G36* +X294050D02*X298550D01* +Y104000D01* +X294050D01* +Y110000D01* +G37* +G36* +X302150D02*X306650D01* +Y104000D01* +X302150D01* +Y110000D01* +G37* +G36* +X307550D02*X312050D01* +Y104000D01* +X307550D01* +Y110000D01* +G37* +G36* +X312950D02*X317450D01* +Y104000D01* +X312950D01* +Y110000D01* +G37* +G36* +X318350D02*X322850D01* +Y104000D01* +X318350D01* +Y110000D01* +G37* +G36* +X326450D02*X330950D01* +Y104000D01* +X326450D01* +Y110000D01* +G37* +G36* +X331850D02*X336350D01* +Y104000D01* +X331850D01* +Y110000D01* +G37* +G36* +X337250D02*X341750D01* +Y104000D01* +X337250D01* +Y110000D01* +G37* +G36* +X342650D02*X347150D01* +Y104000D01* +X342650D01* +Y110000D01* +G37* +G36* +X348050D02*X352550D01* +Y104000D01* +X348050D01* +Y110000D01* +G37* +G36* +X353450D02*X357950D01* +Y104000D01* +X353450D01* +Y110000D01* +G37* +G36* +X358850D02*X363350D01* +Y104000D01* +X358850D01* +Y110000D01* +G37* +G36* +X366950D02*X371450D01* +Y104000D01* +X366950D01* +Y110000D01* +G37* +G36* +X372350D02*X376850D01* +Y104000D01* +X372350D01* +Y110000D01* +G37* +G36* +X377750D02*X382250D01* +Y104000D01* +X377750D01* +Y110000D01* +G37* +G36* +X383150D02*X387650D01* +Y104000D01* +X383150D01* +Y110000D01* +G37* +G36* +X388550D02*X393050D01* +Y104000D01* +X388550D01* +Y110000D01* +G37* +G36* +X393950D02*X398450D01* +Y104000D01* +X393950D01* +Y110000D01* +G37* +G36* +X402050D02*X406550D01* +Y104000D01* +X402050D01* +Y110000D01* +G37* +G36* +X407450D02*X411950D01* +Y104000D01* +X407450D01* +Y110000D01* +G37* +G36* +X412850D02*X417350D01* +Y104000D01* +X412850D01* +Y110000D01* +G37* +G36* +X418250D02*X422750D01* +Y104000D01* +X418250D01* +Y110000D01* +G37* +G36* +X423650D02*X428150D01* +Y104000D01* +X423650D01* +Y110000D01* +G37* +G36* +X431750D02*X436250D01* +Y104000D01* +X431750D01* +Y110000D01* +G37* +G36* +X437150D02*X441650D01* +Y104000D01* +X437150D01* +Y110000D01* +G37* +G36* +X442550D02*X447050D01* +Y104000D01* +X442550D01* +Y110000D01* +G37* +G36* +X447950D02*X452450D01* +Y104000D01* +X447950D01* +Y110000D01* +G37* +G36* +X453350D02*X457850D01* +Y104000D01* +X453350D01* +Y110000D01* +G37* +G36* +X458750D02*X463250D01* +Y104000D01* +X458750D01* +Y110000D01* +G37* +G36* +X464150D02*X468650D01* +Y104000D01* +X464150D01* +Y110000D01* +G37* +G36* +X469550D02*X474050D01* +Y104000D01* +X469550D01* +Y110000D01* +G37* +G36* +X477650D02*X482150D01* +Y104000D01* +X477650D01* +Y110000D01* +G37* +G54D13*X485750D02*Y104000D01* +Y110000D02*X488750D01* +X485750Y107300D02*X488000D01* +G54D14*G36* +X490550Y110000D02*X495050D01* +Y104000D01* +X490550D01* +Y110000D01* +G37* +G36* +X495950D02*X500450D01* +Y104000D01* +X495950D01* +Y110000D01* +G37* +G36* +X501350D02*X505850D01* +Y104000D01* +X501350D01* +Y110000D01* +G37* +G36* +X506750D02*X511250D01* +Y104000D01* +X506750D01* +Y110000D01* +G37* +G36* +X512150D02*X516650D01* +Y104000D01* +X512150D01* +Y110000D01* +G37* +G36* +X517550D02*X522050D01* +Y104000D01* +X517550D01* +Y110000D01* +G37* +G36* +X522950D02*X527450D01* +Y104000D01* +X522950D01* +Y110000D01* +G37* +G36* +X528350D02*X532850D01* +Y104000D01* +X528350D01* +Y110000D01* +G37* +G36* +X533750D02*X538250D01* +Y104000D01* +X533750D01* +Y110000D01* +G37* +G36* +X539150D02*X543650D01* +Y104000D01* +X539150D01* +Y110000D01* +G37* +G54D13*X548000D02*Y104000D01* +X549950Y110000D02*X551000Y108950D01* +Y105050D01* +X549950Y104000D02*X551000Y105050D01* +X547250Y104000D02*X549950D01* +X547250Y110000D02*X549950D01* +G54D14*G36* +X552800D02*X557300D01* +Y104000D01* +X552800D01* +Y110000D01* +G37* +G36* +X558200D02*X562700D01* +Y104000D01* +X558200D01* +Y110000D01* +G37* +G36* +X563600D02*X568100D01* +Y104000D01* +X563600D01* +Y110000D01* +G37* +G36* +X569000D02*X573500D01* +Y104000D01* +X569000D01* +Y110000D01* +G37* +G36* +X574400D02*X578900D01* +Y104000D01* +X574400D01* +Y110000D01* +G37* +G36* +X579800D02*X584300D01* +Y104000D01* +X579800D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/line_offpage.gbr/line_offpage.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.gbr/line_offpage.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.gbr/line_offpage.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: A single line that extends beyond board boundary, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0100*% +G54D11*X10000Y30000D02*X60000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_offpage.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/line_offpage.net =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB A single line that extends beyond board boundary +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/line_offpage.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_offpage.png =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_offpage.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_offpage.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.png.text (revision 33253) @@ -0,0 +1,5 @@ +12 pixel line (10) +486 pixel [guessing middle of outline] on the page (more off) (405) (this is a pain to measure in gimp because of the edge issues) +480 pixels if you remove the outline wall thickness (400) +(mil) + Index: tags/2.3.0/tests/RTT/ref/line_offpage.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_offpage.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_offpage.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_offpage.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_offpage.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_offpage.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_offpage.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.svg (revision 33253) @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/line_offpage.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/line_offpage.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_offpage.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: A single line that extends beyond board boundary - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_overlap1.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Two lines partially overlapping - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_overlap1.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.dsn (revision 33253) @@ -0,0 +1,54 @@ +(pcb Two lines partially overlapping + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 0.381000 5.080000 7.620000 6.350000 7.620000) + (type protect)) + (wire (path 3__top_copper 0.381000 5.588000 7.620000 7.620000 7.620000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/line_overlap1.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.eps (revision 33253) @@ -0,0 +1,36 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: line_overlap1.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.01500 setlinewidth +1 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.20000 0.20000 0.25000 0.20000 t +0.22000 0.20000 0.30000 0.20000 t +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/line_overlap1.exc/line_overlap1.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.exc/line_overlap1.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.exc/line_overlap1.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_overlap1.exc/line_overlap1.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.exc/line_overlap1.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.exc/line_overlap1.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_overlap1.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.fcd (revision 33253) @@ -0,0 +1,3 @@ +[FIDOCAD] +PL 40 40 50 40 3 2 +PL 44 40 60 40 3 2 Index: tags/2.3.0/tests/RTT/ref/line_overlap1.gbr/line_overlap1.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.gbr/line_overlap1.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.gbr/line_overlap1.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Two lines partially overlapping, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap1.gbr/line_overlap1.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.gbr/line_overlap1.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.gbr/line_overlap1.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1821 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Two lines partially overlapping, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D13*X234500D02*X237500D01* +X236000D02*Y104000D01* +G54D14*G36* +X239300Y110000D02*X243800D01* +Y104000D01* +X239300D01* +Y110000D01* +G37* +G36* +X244700D02*X249200D01* +Y104000D01* +X244700D01* +Y110000D01* +G37* +G36* +X252800D02*X257300D01* +Y104000D01* +X252800D01* +Y110000D01* +G37* +G36* +X258200D02*X262700D01* +Y104000D01* +X258200D01* +Y110000D01* +G37* +G36* +X263600D02*X268100D01* +Y104000D01* +X263600D01* +Y110000D01* +G37* +G36* +X269000D02*X273500D01* +Y104000D01* +X269000D01* +Y110000D01* +G37* +G36* +X274400D02*X278900D01* +Y104000D01* +X274400D01* +Y110000D01* +G37* +G36* +X282500D02*X287000D01* +Y104000D01* +X282500D01* +Y110000D01* +G37* +G36* +X287900D02*X292400D01* +Y104000D01* +X287900D01* +Y110000D01* +G37* +G36* +X293300D02*X297800D01* +Y104000D01* +X293300D01* +Y110000D01* +G37* +G36* +X298700D02*X303200D01* +Y104000D01* +X298700D01* +Y110000D01* +G37* +G36* +X304100D02*X308600D01* +Y104000D01* +X304100D01* +Y110000D01* +G37* +G36* +X309500D02*X314000D01* +Y104000D01* +X309500D01* +Y110000D01* +G37* +G36* +X314900D02*X319400D01* +Y104000D01* +X314900D01* +Y110000D01* +G37* +G36* +X320300D02*X324800D01* +Y104000D01* +X320300D01* +Y110000D01* +G37* +G36* +X325700D02*X330200D01* +Y104000D01* +X325700D01* +Y110000D01* +G37* +G36* +X333800D02*X338300D01* +Y104000D01* +X333800D01* +Y110000D01* +G37* +G36* +X339200D02*X343700D01* +Y104000D01* +X339200D01* +Y110000D01* +G37* +G36* +X344600D02*X349100D01* +Y104000D01* +X344600D01* +Y110000D01* +G37* +G36* +X350000D02*X354500D01* +Y104000D01* +X350000D01* +Y110000D01* +G37* +G36* +X355400D02*X359900D01* +Y104000D01* +X355400D01* +Y110000D01* +G37* +G36* +X360800D02*X365300D01* +Y104000D01* +X360800D01* +Y110000D01* +G37* +G36* +X366200D02*X370700D01* +Y104000D01* +X366200D01* +Y110000D01* +G37* +G36* +X371600D02*X376100D01* +Y104000D01* +X371600D01* +Y110000D01* +G37* +G36* +X377000D02*X381500D01* +Y104000D01* +X377000D01* +Y110000D01* +G37* +G36* +X382400D02*X386900D01* +Y104000D01* +X382400D01* +Y110000D01* +G37* +G36* +X387800D02*X392300D01* +Y104000D01* +X387800D01* +Y110000D01* +G37* +G36* +X395900D02*X400400D01* +Y104000D01* +X395900D01* +Y110000D01* +G37* +G54D13*X404000D02*Y104000D01* +Y110000D02*X407000D01* +X404000Y107300D02*X406250D01* +G54D14*G36* +X408800Y110000D02*X413300D01* +Y104000D01* +X408800D01* +Y110000D01* +G37* +G36* +X414200D02*X418700D01* +Y104000D01* +X414200D01* +Y110000D01* +G37* +G36* +X419600D02*X424100D01* +Y104000D01* +X419600D01* +Y110000D01* +G37* +G36* +X425000D02*X429500D01* +Y104000D01* +X425000D01* +Y110000D01* +G37* +G36* +X430400D02*X434900D01* +Y104000D01* +X430400D01* +Y110000D01* +G37* +G36* +X435800D02*X440300D01* +Y104000D01* +X435800D01* +Y110000D01* +G37* +G36* +X441200D02*X445700D01* +Y104000D01* +X441200D01* +Y110000D01* +G37* +G36* +X446600D02*X451100D01* +Y104000D01* +X446600D01* +Y110000D01* +G37* +G36* +X452000D02*X456500D01* +Y104000D01* +X452000D01* +Y110000D01* +G37* +G36* +X457400D02*X461900D01* +Y104000D01* +X457400D01* +Y110000D01* +G37* +G54D13*X466250D02*Y104000D01* +X468200Y110000D02*X469250Y108950D01* +Y105050D01* +X468200Y104000D02*X469250Y105050D01* +X465500Y104000D02*X468200D01* +X465500Y110000D02*X468200D01* +G54D14*G36* +X471050D02*X475550D01* +Y104000D01* +X471050D01* +Y110000D01* +G37* +G36* +X476450D02*X480950D01* +Y104000D01* +X476450D01* +Y110000D01* +G37* +G36* +X481850D02*X486350D01* +Y104000D01* +X481850D01* +Y110000D01* +G37* +G36* +X487250D02*X491750D01* +Y104000D01* +X487250D01* +Y110000D01* +G37* +G36* +X492650D02*X497150D01* +Y104000D01* +X492650D01* +Y110000D01* +G37* +G36* +X498050D02*X502550D01* +Y104000D01* +X498050D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap1.gbr/line_overlap1.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.gbr/line_overlap1.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.gbr/line_overlap1.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,15 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Two lines partially overlapping, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0150*% +G54D11*X20000Y30000D02*X25000D01* +X22000D02*X30000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap1.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/line_overlap1.net =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Two lines partially overlapping +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/line_overlap1.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap1.png =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap1.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap1.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.png.text (revision 33253) @@ -0,0 +1,8 @@ +r6630 + +18 pixel width (15) +138 pixel length (115) + +(it is actually 2 traces that should export as 1) + +(mil) Index: tags/2.3.0/tests/RTT/ref/line_overlap1.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap1.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap1.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap1.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap1.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap1.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap1.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.svg (revision 33253) @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/line_overlap1.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap1.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap1.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Two lines partially overlapping - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_overlap2.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Two lines, one over the other, full cover - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_overlap2.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.dsn (revision 33253) @@ -0,0 +1,54 @@ +(pcb Two lines, one over the other, full cover + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 0.381000 5.080000 7.620000 8.890000 7.620000) + (type protect)) + (wire (path 3__top_copper 0.381000 5.588000 7.620000 7.620000 7.620000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/line_overlap2.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.eps (revision 33253) @@ -0,0 +1,36 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: line_overlap2.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.01500 setlinewidth +1 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.20000 0.20000 0.35000 0.20000 t +0.22000 0.20000 0.30000 0.20000 t +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/line_overlap2.exc/line_overlap2.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.exc/line_overlap2.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.exc/line_overlap2.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_overlap2.exc/line_overlap2.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.exc/line_overlap2.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.exc/line_overlap2.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_overlap2.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.fcd (revision 33253) @@ -0,0 +1,3 @@ +[FIDOCAD] +PL 40 40 70 40 3 2 +PL 44 40 60 40 3 2 Index: tags/2.3.0/tests/RTT/ref/line_overlap2.gbr/line_overlap2.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.gbr/line_overlap2.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.gbr/line_overlap2.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Two lines, one over the other, full cover, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap2.gbr/line_overlap2.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.gbr/line_overlap2.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.gbr/line_overlap2.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1857 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Two lines, one over the other, full cover, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D13*X234500D02*X237500D01* +X236000D02*Y104000D01* +G54D14*G36* +X239300Y110000D02*X243800D01* +Y104000D01* +X239300D01* +Y110000D01* +G37* +G36* +X244700D02*X249200D01* +Y104000D01* +X244700D01* +Y110000D01* +G37* +G36* +X252800D02*X257300D01* +Y104000D01* +X252800D01* +Y110000D01* +G37* +G36* +X258200D02*X262700D01* +Y104000D01* +X258200D01* +Y110000D01* +G37* +G36* +X263600D02*X268100D01* +Y104000D01* +X263600D01* +Y110000D01* +G37* +G36* +X269000D02*X273500D01* +Y104000D01* +X269000D01* +Y110000D01* +G37* +G36* +X274400D02*X278900D01* +Y104000D01* +X274400D01* +Y110000D01* +G37* +G36* +X279800D02*X284300D01* +Y104000D01* +X279800D01* +Y110000D01* +G37* +G36* +X287900D02*X292400D01* +Y104000D01* +X287900D01* +Y110000D01* +G37* +G36* +X293300D02*X297800D01* +Y104000D01* +X293300D01* +Y110000D01* +G37* +G36* +X298700D02*X303200D01* +Y104000D01* +X298700D01* +Y110000D01* +G37* +G36* +X306800D02*X311300D01* +Y104000D01* +X306800D01* +Y110000D01* +G37* +G36* +X312200D02*X316700D01* +Y104000D01* +X312200D01* +Y110000D01* +G37* +G36* +X317600D02*X322100D01* +Y104000D01* +X317600D01* +Y110000D01* +G37* +G36* +X323000D02*X327500D01* +Y104000D01* +X323000D01* +Y110000D01* +G37* +G36* +X331100D02*X335600D01* +Y104000D01* +X331100D01* +Y110000D01* +G37* +G36* +X336500D02*X341000D01* +Y104000D01* +X336500D01* +Y110000D01* +G37* +G36* +X341900D02*X346400D01* +Y104000D01* +X341900D01* +Y110000D01* +G37* +G36* +X350000D02*X354500D01* +Y104000D01* +X350000D01* +Y110000D01* +G37* +G36* +X355400D02*X359900D01* +Y104000D01* +X355400D01* +Y110000D01* +G37* +G36* +X360800D02*X365300D01* +Y104000D01* +X360800D01* +Y110000D01* +G37* +G36* +X366200D02*X370700D01* +Y104000D01* +X366200D01* +Y110000D01* +G37* +G36* +X371600D02*X376100D01* +Y104000D01* +X371600D01* +Y110000D01* +G37* +G36* +X377000D02*X381500D01* +Y104000D01* +X377000D01* +Y110000D01* +G37* +G36* +X385100D02*X389600D01* +Y104000D01* +X385100D01* +Y110000D01* +G37* +G36* +X390500D02*X395000D01* +Y104000D01* +X390500D01* +Y110000D01* +G37* +G36* +X395900D02*X400400D01* +Y104000D01* +X395900D01* +Y110000D01* +G37* +G36* +X401300D02*X405800D01* +Y104000D01* +X401300D01* +Y110000D01* +G37* +G36* +X409400D02*X413900D01* +Y104000D01* +X409400D01* +Y110000D01* +G37* +G36* +X414800D02*X419300D01* +Y104000D01* +X414800D01* +Y110000D01* +G37* +G36* +X420200D02*X424700D01* +Y104000D01* +X420200D01* +Y110000D01* +G37* +G36* +X425600D02*X430100D01* +Y104000D01* +X425600D01* +Y110000D01* +G37* +G36* +X431000D02*X435500D01* +Y104000D01* +X431000D01* +Y110000D01* +G37* +G36* +X439100D02*X443600D01* +Y104000D01* +X439100D01* +Y110000D01* +G37* +G54D13*X447200D02*Y104000D01* +Y110000D02*X450200D01* +X447200Y107300D02*X449450D01* +G54D14*G36* +X452000Y110000D02*X456500D01* +Y104000D01* +X452000D01* +Y110000D01* +G37* +G36* +X457400D02*X461900D01* +Y104000D01* +X457400D01* +Y110000D01* +G37* +G36* +X462800D02*X467300D01* +Y104000D01* +X462800D01* +Y110000D01* +G37* +G36* +X468200D02*X472700D01* +Y104000D01* +X468200D01* +Y110000D01* +G37* +G36* +X473600D02*X478100D01* +Y104000D01* +X473600D01* +Y110000D01* +G37* +G36* +X479000D02*X483500D01* +Y104000D01* +X479000D01* +Y110000D01* +G37* +G36* +X484400D02*X488900D01* +Y104000D01* +X484400D01* +Y110000D01* +G37* +G36* +X489800D02*X494300D01* +Y104000D01* +X489800D01* +Y110000D01* +G37* +G36* +X495200D02*X499700D01* +Y104000D01* +X495200D01* +Y110000D01* +G37* +G36* +X500600D02*X505100D01* +Y104000D01* +X500600D01* +Y110000D01* +G37* +G54D13*X509450D02*Y104000D01* +X511400Y110000D02*X512450Y108950D01* +Y105050D01* +X511400Y104000D02*X512450Y105050D01* +X508700Y104000D02*X511400D01* +X508700Y110000D02*X511400D01* +G54D14*G36* +X514250D02*X518750D01* +Y104000D01* +X514250D01* +Y110000D01* +G37* +G36* +X519650D02*X524150D01* +Y104000D01* +X519650D01* +Y110000D01* +G37* +G36* +X525050D02*X529550D01* +Y104000D01* +X525050D01* +Y110000D01* +G37* +G36* +X530450D02*X534950D01* +Y104000D01* +X530450D01* +Y110000D01* +G37* +G36* +X535850D02*X540350D01* +Y104000D01* +X535850D01* +Y110000D01* +G37* +G36* +X541250D02*X545750D01* +Y104000D01* +X541250D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap2.gbr/line_overlap2.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.gbr/line_overlap2.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.gbr/line_overlap2.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,15 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Two lines, one over the other, full cover, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0150*% +G54D11*X20000Y30000D02*X35000D01* +X22000D02*X30000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap2.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/line_overlap2.net =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Two lines, one over the other, full cover +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/line_overlap2.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap2.png =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap2.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap2.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.png.text (revision 33253) @@ -0,0 +1,6 @@ +r6630 + +18 pixel width (15) +198 pixel length (165) + +(it is actually 3 traces that should export as 1) Index: tags/2.3.0/tests/RTT/ref/line_overlap2.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap2.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap2.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap2.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap2.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap2.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap2.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.svg (revision 33253) @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/line_overlap2.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap2.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap2.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Two lines, one over the other, full cover - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_overlap3.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Full overlap: the same line twice - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_overlap3.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.dsn (revision 33253) @@ -0,0 +1,54 @@ +(pcb Full overlap: the same line twice + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 0.381000 5.080000 7.620000 8.890000 7.620000) + (type protect)) + (wire (path 3__top_copper 0.381000 5.080000 7.620000 8.890000 7.620000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/line_overlap3.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.eps (revision 33253) @@ -0,0 +1,36 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: line_overlap3.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.01500 setlinewidth +1 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.20000 0.20000 0.35000 0.20000 t +0.20000 0.20000 0.35000 0.20000 t +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/line_overlap3.exc/line_overlap3.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.exc/line_overlap3.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.exc/line_overlap3.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_overlap3.exc/line_overlap3.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.exc/line_overlap3.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.exc/line_overlap3.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_overlap3.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.fcd (revision 33253) @@ -0,0 +1,3 @@ +[FIDOCAD] +PL 40 40 70 40 3 2 +PL 40 40 70 40 3 2 Index: tags/2.3.0/tests/RTT/ref/line_overlap3.gbr/line_overlap3.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.gbr/line_overlap3.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.gbr/line_overlap3.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Full overlap: the same line twice, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap3.gbr/line_overlap3.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.gbr/line_overlap3.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.gbr/line_overlap3.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1822 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Full overlap: the same line twice, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D13*X234500D02*Y104000D01* +Y110000D02*X237500D01* +X234500Y107300D02*X236750D01* +G54D14*G36* +X239300Y110000D02*X243800D01* +Y104000D01* +X239300D01* +Y110000D01* +G37* +G36* +X244700D02*X249200D01* +Y104000D01* +X244700D01* +Y110000D01* +G37* +G36* +X250100D02*X254600D01* +Y104000D01* +X250100D01* +Y110000D01* +G37* +G36* +X258200D02*X262700D01* +Y104000D01* +X258200D01* +Y110000D01* +G37* +G36* +X263600D02*X268100D01* +Y104000D01* +X263600D01* +Y110000D01* +G37* +G36* +X269000D02*X273500D01* +Y104000D01* +X269000D01* +Y110000D01* +G37* +G36* +X274400D02*X278900D01* +Y104000D01* +X274400D01* +Y110000D01* +G37* +G36* +X279800D02*X284300D01* +Y104000D01* +X279800D01* +Y110000D01* +G37* +G36* +X285200D02*X289700D01* +Y104000D01* +X285200D01* +Y110000D01* +G37* +G36* +X290600D02*X295100D01* +Y104000D01* +X290600D01* +Y110000D01* +G37* +G36* +X296000D02*X300500D01* +Y104000D01* +X296000D01* +Y110000D01* +G37* +G36* +X304100D02*X308600D01* +Y104000D01* +X304100D01* +Y110000D01* +G37* +G36* +X309500D02*X314000D01* +Y104000D01* +X309500D01* +Y110000D01* +G37* +G36* +X314900D02*X319400D01* +Y104000D01* +X314900D01* +Y110000D01* +G37* +G36* +X323000D02*X327500D01* +Y104000D01* +X323000D01* +Y110000D01* +G37* +G36* +X328400D02*X332900D01* +Y104000D01* +X328400D01* +Y110000D01* +G37* +G36* +X333800D02*X338300D01* +Y104000D01* +X333800D01* +Y110000D01* +G37* +G36* +X339200D02*X343700D01* +Y104000D01* +X339200D01* +Y110000D01* +G37* +G36* +X347300D02*X351800D01* +Y104000D01* +X347300D01* +Y110000D01* +G37* +G36* +X352700D02*X357200D01* +Y104000D01* +X352700D01* +Y110000D01* +G37* +G36* +X358100D02*X362600D01* +Y104000D01* +X358100D01* +Y110000D01* +G37* +G36* +X363500D02*X368000D01* +Y104000D01* +X363500D01* +Y110000D01* +G37* +G36* +X371600D02*X376100D01* +Y104000D01* +X371600D01* +Y110000D01* +G37* +G36* +X377000D02*X381500D01* +Y104000D01* +X377000D01* +Y110000D01* +G37* +G36* +X382400D02*X386900D01* +Y104000D01* +X382400D01* +Y110000D01* +G37* +G36* +X387800D02*X392300D01* +Y104000D01* +X387800D01* +Y110000D01* +G37* +G36* +X393200D02*X397700D01* +Y104000D01* +X393200D01* +Y110000D01* +G37* +G36* +X401300D02*X405800D01* +Y104000D01* +X401300D01* +Y110000D01* +G37* +G54D13*X409400D02*Y104000D01* +Y110000D02*X412400D01* +X409400Y107300D02*X411650D01* +G54D14*G36* +X414200Y110000D02*X418700D01* +Y104000D01* +X414200D01* +Y110000D01* +G37* +G36* +X419600D02*X424100D01* +Y104000D01* +X419600D01* +Y110000D01* +G37* +G36* +X425000D02*X429500D01* +Y104000D01* +X425000D01* +Y110000D01* +G37* +G36* +X430400D02*X434900D01* +Y104000D01* +X430400D01* +Y110000D01* +G37* +G36* +X435800D02*X440300D01* +Y104000D01* +X435800D01* +Y110000D01* +G37* +G36* +X441200D02*X445700D01* +Y104000D01* +X441200D01* +Y110000D01* +G37* +G36* +X446600D02*X451100D01* +Y104000D01* +X446600D01* +Y110000D01* +G37* +G36* +X452000D02*X456500D01* +Y104000D01* +X452000D01* +Y110000D01* +G37* +G36* +X457400D02*X461900D01* +Y104000D01* +X457400D01* +Y110000D01* +G37* +G36* +X462800D02*X467300D01* +Y104000D01* +X462800D01* +Y110000D01* +G37* +G54D13*X471650D02*Y104000D01* +X473600Y110000D02*X474650Y108950D01* +Y105050D01* +X473600Y104000D02*X474650Y105050D01* +X470900Y104000D02*X473600D01* +X470900Y110000D02*X473600D01* +G54D14*G36* +X476450D02*X480950D01* +Y104000D01* +X476450D01* +Y110000D01* +G37* +G36* +X481850D02*X486350D01* +Y104000D01* +X481850D01* +Y110000D01* +G37* +G36* +X487250D02*X491750D01* +Y104000D01* +X487250D01* +Y110000D01* +G37* +G36* +X492650D02*X497150D01* +Y104000D01* +X492650D01* +Y110000D01* +G37* +G36* +X498050D02*X502550D01* +Y104000D01* +X498050D01* +Y110000D01* +G37* +G36* +X503450D02*X507950D01* +Y104000D01* +X503450D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap3.gbr/line_overlap3.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.gbr/line_overlap3.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.gbr/line_overlap3.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,15 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Full overlap: the same line twice, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0150*% +G54D11*X20000Y30000D02*X35000D01* +X20000D02*X35000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap3.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/line_overlap3.net =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Full overlap: the same line twice +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/line_overlap3.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap3.png =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap3.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap3.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.png.text (revision 33253) @@ -0,0 +1,5 @@ +18 pixel width (15) +198 pixel length (165) + +(mil) + Index: tags/2.3.0/tests/RTT/ref/line_overlap3.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap3.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap3.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap3.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap3.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap3.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap3.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.svg (revision 33253) @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/line_overlap3.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap3.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap3.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Full overlap: the same line twice - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_overlap4.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Full overlap: the same line twice with different settings - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_overlap4.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.dsn (revision 33253) @@ -0,0 +1,54 @@ +(pcb Full overlap: the same line twice with different settings + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 0.127000 5.080000 7.620000 8.890000 7.620000) + (type protect)) + (wire (path 3__top_copper 0.381000 5.080000 7.620000 8.890000 7.620000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/line_overlap4.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.eps (revision 33253) @@ -0,0 +1,67 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: line_overlap4.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.30000 0.15000 moveto +0.30000 0.17750 lineto +0.20000 0.17750 lineto +0.19647 0.17771 lineto +0.19303 0.17854 lineto +0.18975 0.17989 lineto +0.18673 0.18174 lineto +0.18404 0.18404 lineto +0.18174 0.18673 lineto +0.17989 0.18975 lineto +0.17854 0.19303 lineto +0.17771 0.19647 lineto +0.17743 0.20000 lineto +0.17771 0.20353 lineto +0.17854 0.20697 lineto +0.17989 0.21025 lineto +0.18174 0.21327 lineto +0.18404 0.21596 lineto +0.18673 0.21826 lineto +0.18975 0.22011 lineto +0.19303 0.22146 lineto +0.19647 0.22229 lineto +0.20000 0.22250 lineto +0.30000 0.22250 lineto +0.30000 0.32500 lineto +0.15000 0.32500 lineto +0.15000 0.15000 lineto +fill +0.00500 setlinewidth +1 setlinecap +0.20000 0.20000 0.35000 0.20000 t +0.01500 setlinewidth +0.20000 0.20000 0.35000 0.20000 t +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/line_overlap4.exc/line_overlap4.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.exc/line_overlap4.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.exc/line_overlap4.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_overlap4.exc/line_overlap4.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.exc/line_overlap4.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.exc/line_overlap4.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_overlap4.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.fcd (revision 33253) @@ -0,0 +1,4 @@ +[FIDOCAD] +PL 40 40 70 40 1 2 +PL 40 40 70 40 3 2 +PP 30 30 60 30 60 36 40 36 39 36 39 36 38 36 37 36 37 37 36 37 36 38 36 39 36 39 35 40 36 41 36 41 36 42 36 43 37 43 37 44 38 44 39 44 39 44 40 45 60 45 60 65 30 65 30 30 2 Index: tags/2.3.0/tests/RTT/ref/line_overlap4.gbr/line_overlap4.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.gbr/line_overlap4.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.gbr/line_overlap4.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Full overlap: the same line twice with different settings, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD14C,0.0100*% +G54D14*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap4.gbr/line_overlap4.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.gbr/line_overlap4.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.gbr/line_overlap4.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1948 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Full overlap: the same line twice with different settings, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD17C,0.0100*% +%ADD16C,0.0001*% +%ADD15C,0.0060*% +G54D15*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D16*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D15*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D16*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D15*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D16*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D15*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D16*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D15*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D16*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D15*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D16*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D17*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D15*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D16*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D15*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D16*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D15*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D16*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D15*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D16*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D15*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D16*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D15*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D16*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D15*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D16*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D15*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D16*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D15*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D16*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D15*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D16*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D15*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D16*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D15*X234500D02*Y104000D01* +Y110000D02*X237500D01* +X234500Y107300D02*X236750D01* +G54D16*G36* +X239300Y110000D02*X243800D01* +Y104000D01* +X239300D01* +Y110000D01* +G37* +G36* +X244700D02*X249200D01* +Y104000D01* +X244700D01* +Y110000D01* +G37* +G36* +X250100D02*X254600D01* +Y104000D01* +X250100D01* +Y110000D01* +G37* +G36* +X258200D02*X262700D01* +Y104000D01* +X258200D01* +Y110000D01* +G37* +G36* +X263600D02*X268100D01* +Y104000D01* +X263600D01* +Y110000D01* +G37* +G36* +X269000D02*X273500D01* +Y104000D01* +X269000D01* +Y110000D01* +G37* +G36* +X274400D02*X278900D01* +Y104000D01* +X274400D01* +Y110000D01* +G37* +G36* +X279800D02*X284300D01* +Y104000D01* +X279800D01* +Y110000D01* +G37* +G36* +X285200D02*X289700D01* +Y104000D01* +X285200D01* +Y110000D01* +G37* +G36* +X290600D02*X295100D01* +Y104000D01* +X290600D01* +Y110000D01* +G37* +G36* +X296000D02*X300500D01* +Y104000D01* +X296000D01* +Y110000D01* +G37* +G36* +X304100D02*X308600D01* +Y104000D01* +X304100D01* +Y110000D01* +G37* +G36* +X309500D02*X314000D01* +Y104000D01* +X309500D01* +Y110000D01* +G37* +G36* +X314900D02*X319400D01* +Y104000D01* +X314900D01* +Y110000D01* +G37* +G36* +X323000D02*X327500D01* +Y104000D01* +X323000D01* +Y110000D01* +G37* +G36* +X328400D02*X332900D01* +Y104000D01* +X328400D01* +Y110000D01* +G37* +G36* +X333800D02*X338300D01* +Y104000D01* +X333800D01* +Y110000D01* +G37* +G36* +X339200D02*X343700D01* +Y104000D01* +X339200D01* +Y110000D01* +G37* +G36* +X347300D02*X351800D01* +Y104000D01* +X347300D01* +Y110000D01* +G37* +G36* +X352700D02*X357200D01* +Y104000D01* +X352700D01* +Y110000D01* +G37* +G36* +X358100D02*X362600D01* +Y104000D01* +X358100D01* +Y110000D01* +G37* +G36* +X363500D02*X368000D01* +Y104000D01* +X363500D01* +Y110000D01* +G37* +G36* +X371600D02*X376100D01* +Y104000D01* +X371600D01* +Y110000D01* +G37* +G36* +X377000D02*X381500D01* +Y104000D01* +X377000D01* +Y110000D01* +G37* +G36* +X382400D02*X386900D01* +Y104000D01* +X382400D01* +Y110000D01* +G37* +G36* +X387800D02*X392300D01* +Y104000D01* +X387800D01* +Y110000D01* +G37* +G36* +X393200D02*X397700D01* +Y104000D01* +X393200D01* +Y110000D01* +G37* +G36* +X401300D02*X405800D01* +Y104000D01* +X401300D01* +Y110000D01* +G37* +G36* +X406700D02*X411200D01* +Y104000D01* +X406700D01* +Y110000D01* +G37* +G36* +X412100D02*X416600D01* +Y104000D01* +X412100D01* +Y110000D01* +G37* +G36* +X417500D02*X422000D01* +Y104000D01* +X417500D01* +Y110000D01* +G37* +G36* +X425600D02*X430100D01* +Y104000D01* +X425600D01* +Y110000D01* +G37* +G36* +X431000D02*X435500D01* +Y104000D01* +X431000D01* +Y110000D01* +G37* +G36* +X436400D02*X440900D01* +Y104000D01* +X436400D01* +Y110000D01* +G37* +G36* +X441800D02*X446300D01* +Y104000D01* +X441800D01* +Y110000D01* +G37* +G36* +X447200D02*X451700D01* +Y104000D01* +X447200D01* +Y110000D01* +G37* +G36* +X452600D02*X457100D01* +Y104000D01* +X452600D01* +Y110000D01* +G37* +G36* +X458000D02*X462500D01* +Y104000D01* +X458000D01* +Y110000D01* +G37* +G36* +X463400D02*X467900D01* +Y104000D01* +X463400D01* +Y110000D01* +G37* +G36* +X468800D02*X473300D01* +Y104000D01* +X468800D01* +Y110000D01* +G37* +G36* +X476900D02*X481400D01* +Y104000D01* +X476900D01* +Y110000D01* +G37* +G36* +X482300D02*X486800D01* +Y104000D01* +X482300D01* +Y110000D01* +G37* +G36* +X487700D02*X492200D01* +Y104000D01* +X487700D01* +Y110000D01* +G37* +G36* +X493100D02*X497600D01* +Y104000D01* +X493100D01* +Y110000D01* +G37* +G36* +X498500D02*X503000D01* +Y104000D01* +X498500D01* +Y110000D01* +G37* +G36* +X503900D02*X508400D01* +Y104000D01* +X503900D01* +Y110000D01* +G37* +G36* +X509300D02*X513800D01* +Y104000D01* +X509300D01* +Y110000D01* +G37* +G36* +X514700D02*X519200D01* +Y104000D01* +X514700D01* +Y110000D01* +G37* +G36* +X522800D02*X527300D01* +Y104000D01* +X522800D01* +Y110000D01* +G37* +G54D15*X530900D02*Y104000D01* +Y110000D02*X533900D01* +X530900Y107300D02*X533150D01* +G54D16*G36* +X535700Y110000D02*X540200D01* +Y104000D01* +X535700D01* +Y110000D01* +G37* +G36* +X541100D02*X545600D01* +Y104000D01* +X541100D01* +Y110000D01* +G37* +G36* +X546500D02*X551000D01* +Y104000D01* +X546500D01* +Y110000D01* +G37* +G36* +X551900D02*X556400D01* +Y104000D01* +X551900D01* +Y110000D01* +G37* +G36* +X557300D02*X561800D01* +Y104000D01* +X557300D01* +Y110000D01* +G37* +G36* +X562700D02*X567200D01* +Y104000D01* +X562700D01* +Y110000D01* +G37* +G36* +X568100D02*X572600D01* +Y104000D01* +X568100D01* +Y110000D01* +G37* +G36* +X573500D02*X578000D01* +Y104000D01* +X573500D01* +Y110000D01* +G37* +G36* +X578900D02*X583400D01* +Y104000D01* +X578900D01* +Y110000D01* +G37* +G36* +X584300D02*X588800D01* +Y104000D01* +X584300D01* +Y110000D01* +G37* +G54D15*X593150D02*Y104000D01* +X595100Y110000D02*X596150Y108950D01* +Y105050D01* +X595100Y104000D02*X596150Y105050D01* +X592400Y104000D02*X595100D01* +X592400Y110000D02*X595100D01* +G54D16*G36* +X597950D02*X602450D01* +Y104000D01* +X597950D01* +Y110000D01* +G37* +G36* +X603350D02*X607850D01* +Y104000D01* +X603350D01* +Y110000D01* +G37* +G36* +X608750D02*X613250D01* +Y104000D01* +X608750D01* +Y110000D01* +G37* +G36* +X614150D02*X618650D01* +Y104000D01* +X614150D01* +Y110000D01* +G37* +G36* +X619550D02*X624050D01* +Y104000D01* +X619550D01* +Y110000D01* +G37* +G36* +X624950D02*X629450D01* +Y104000D01* +X624950D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap4.gbr/line_overlap4.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.gbr/line_overlap4.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.gbr/line_overlap4.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,46 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Full overlap: the same line twice with different settings, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD13C,0.0150*% +%ADD12C,0.0050*% +%ADD11C,0.0001*% +G54D11*G36* +X30000Y35000D02*Y32250D01* +X20000D01* +X19647Y32229D01* +X19303Y32146D01* +X18975Y32011D01* +X18673Y31826D01* +X18404Y31596D01* +X18174Y31327D01* +X17989Y31025D01* +X17854Y30697D01* +X17771Y30353D01* +X17743Y30000D01* +X17771Y29647D01* +X17854Y29303D01* +X17989Y28975D01* +X18174Y28673D01* +X18404Y28404D01* +X18673Y28174D01* +X18975Y27989D01* +X19303Y27854D01* +X19647Y27771D01* +X20000Y27750D01* +X30000D01* +Y17500D01* +X15000D01* +Y35000D01* +X30000D01* +G37* +G54D12*X20000Y30000D02*X35000D01* +G54D13*X20000D02*X35000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_overlap4.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/line_overlap4.net =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Full overlap: the same line twice with different settings +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/line_overlap4.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap4.png =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap4.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap4.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.png.text (revision 33253) @@ -0,0 +1,6 @@ +18 pixel width (15) +198 pixel length (165) +18 pixel clearance (15) + +in a poly +181 x 211 pixels (150.833 x 175.833) Index: tags/2.3.0/tests/RTT/ref/line_overlap4.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap4.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap4.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap4.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_overlap4.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_overlap4.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_overlap4.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.svg (revision 33253) @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/line_overlap4.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/line_overlap4.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_overlap4.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Full overlap: the same line twice with different settings - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_zerolen.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: A single zero length line - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/line_zerolen.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.dsn (revision 33253) @@ -0,0 +1,52 @@ +(pcb A single zero length line + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + (wire (path 3__top_copper 0.381000 5.080000 7.620000 5.080000 7.620000) + (type protect)) + + ) +) Index: tags/2.3.0/tests/RTT/ref/line_zerolen.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.eps (revision 33253) @@ -0,0 +1,35 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: line_zerolen.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.01500 setlinewidth +1 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.20000 0.20000 0.00750 c +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/line_zerolen.exc/line_zerolen.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.exc/line_zerolen.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.exc/line_zerolen.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_zerolen.exc/line_zerolen.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.exc/line_zerolen.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.exc/line_zerolen.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/line_zerolen.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.fcd (revision 33253) @@ -0,0 +1,2 @@ +[FIDOCAD] +PL 40 40 40 40 3 2 Index: tags/2.3.0/tests/RTT/ref/line_zerolen.gbr/line_zerolen.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.gbr/line_zerolen.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.gbr/line_zerolen.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: A single zero length line, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/line_zerolen.gbr/line_zerolen.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.gbr/line_zerolen.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.gbr/line_zerolen.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1783 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: A single zero length line, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D13*X234500Y108500D02*Y104000D01* +Y108500D02*X235550Y110000D01* +X237200D01* +X238250Y108500D01* +Y104000D01* +X234500Y107000D02*X238250D01* +G54D14*G36* +X242750Y110000D02*X247250D01* +Y104000D01* +X242750D01* +Y110000D01* +G37* +G36* +X248150D02*X252650D01* +Y104000D01* +X248150D01* +Y110000D01* +G37* +G36* +X253550D02*X258050D01* +Y104000D01* +X253550D01* +Y110000D01* +G37* +G36* +X258950D02*X263450D01* +Y104000D01* +X258950D01* +Y110000D01* +G37* +G36* +X264350D02*X268850D01* +Y104000D01* +X264350D01* +Y110000D01* +G37* +G36* +X269750D02*X274250D01* +Y104000D01* +X269750D01* +Y110000D01* +G37* +G36* +X277850D02*X282350D01* +Y104000D01* +X277850D01* +Y110000D01* +G37* +G36* +X283250D02*X287750D01* +Y104000D01* +X283250D01* +Y110000D01* +G37* +G36* +X288650D02*X293150D01* +Y104000D01* +X288650D01* +Y110000D01* +G37* +G36* +X294050D02*X298550D01* +Y104000D01* +X294050D01* +Y110000D01* +G37* +G36* +X302150D02*X306650D01* +Y104000D01* +X302150D01* +Y110000D01* +G37* +G36* +X307550D02*X312050D01* +Y104000D01* +X307550D01* +Y110000D01* +G37* +G36* +X312950D02*X317450D01* +Y104000D01* +X312950D01* +Y110000D01* +G37* +G36* +X318350D02*X322850D01* +Y104000D01* +X318350D01* +Y110000D01* +G37* +G36* +X323750D02*X328250D01* +Y104000D01* +X323750D01* +Y110000D01* +G37* +G36* +X329150D02*X333650D01* +Y104000D01* +X329150D01* +Y110000D01* +G37* +G36* +X337250D02*X341750D01* +Y104000D01* +X337250D01* +Y110000D01* +G37* +G36* +X342650D02*X347150D01* +Y104000D01* +X342650D01* +Y110000D01* +G37* +G36* +X348050D02*X352550D01* +Y104000D01* +X348050D01* +Y110000D01* +G37* +G36* +X353450D02*X357950D01* +Y104000D01* +X353450D01* +Y110000D01* +G37* +G36* +X361550D02*X366050D01* +Y104000D01* +X361550D01* +Y110000D01* +G37* +G54D13*X369650D02*Y104000D01* +Y110000D02*X372650D01* +X369650Y107300D02*X371900D01* +G54D14*G36* +X374450Y110000D02*X378950D01* +Y104000D01* +X374450D01* +Y110000D01* +G37* +G36* +X379850D02*X384350D01* +Y104000D01* +X379850D01* +Y110000D01* +G37* +G36* +X385250D02*X389750D01* +Y104000D01* +X385250D01* +Y110000D01* +G37* +G36* +X390650D02*X395150D01* +Y104000D01* +X390650D01* +Y110000D01* +G37* +G36* +X396050D02*X400550D01* +Y104000D01* +X396050D01* +Y110000D01* +G37* +G36* +X401450D02*X405950D01* +Y104000D01* +X401450D01* +Y110000D01* +G37* +G36* +X406850D02*X411350D01* +Y104000D01* +X406850D01* +Y110000D01* +G37* +G36* +X412250D02*X416750D01* +Y104000D01* +X412250D01* +Y110000D01* +G37* +G36* +X417650D02*X422150D01* +Y104000D01* +X417650D01* +Y110000D01* +G37* +G36* +X423050D02*X427550D01* +Y104000D01* +X423050D01* +Y110000D01* +G37* +G54D13*X431900D02*Y104000D01* +X433850Y110000D02*X434900Y108950D01* +Y105050D01* +X433850Y104000D02*X434900Y105050D01* +X431150Y104000D02*X433850D01* +X431150Y110000D02*X433850D01* +G54D14*G36* +X436700D02*X441200D01* +Y104000D01* +X436700D01* +Y110000D01* +G37* +G36* +X442100D02*X446600D01* +Y104000D01* +X442100D01* +Y110000D01* +G37* +G36* +X447500D02*X452000D01* +Y104000D01* +X447500D01* +Y110000D01* +G37* +G36* +X452900D02*X457400D01* +Y104000D01* +X452900D01* +Y110000D01* +G37* +G36* +X458300D02*X462800D01* +Y104000D01* +X458300D01* +Y110000D01* +G37* +G36* +X463700D02*X468200D01* +Y104000D01* +X463700D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/line_zerolen.gbr/line_zerolen.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.gbr/line_zerolen.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.gbr/line_zerolen.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: A single zero length line, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0150*% +G54D11*X20000Y30000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/line_zerolen.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/line_zerolen.net =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB A single zero length line +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/line_zerolen.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_zerolen.png =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_zerolen.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_zerolen.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.png.text (revision 33253) @@ -0,0 +1 @@ +19 pixel (15.833) diameter point made of a trace with zero length Index: tags/2.3.0/tests/RTT/ref/line_zerolen.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_zerolen.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_zerolen.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_zerolen.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/line_zerolen.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/line_zerolen.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/line_zerolen.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.svg (revision 33253) @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/line_zerolen.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/line_zerolen.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/line_zerolen.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: A single zero length line - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/mech.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: (unknown) - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/mech.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.dsn (revision 33253) @@ -0,0 +1,65 @@ +(pcb notnamed + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 117 + (place 117 3.556000 11.430000 front 0 (PN 0)) + ) + (component 140 + (place 140 5.588000 11.430000 front 0 (PN 0)) + ) + (component 332 + (place 332 3.556000 9.906000 front 0 (PN 0)) + ) + (component 361 + (place 361 5.588000 9.906000 front 0 (PN 0)) + ) + (component 542 + (place 542 3.810000 4.318000 front 0 (PN 0)) + ) + (component 543 + (place 543 5.842000 4.318000 front 0 (PN 0)) + ) + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/mech.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.eps (revision 33253) @@ -0,0 +1,202 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: mech.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.227451 0.372549 0.803922 setrgbcolor +0.17000 0.16000 moveto +0.17000 0.20000 lineto +0.12000 0.20000 lineto +0.12000 0.16000 lineto +fill +0.25000 0.16000 moveto +0.25000 0.20000 lineto +0.20000 0.20000 lineto +0.20000 0.16000 lineto +fill +1 setlinecap +0.627451 0.627451 0.627451 setrgbcolor +0.12500 0.03000 moveto +0.15500 0.03000 lineto +0.15500 0.07000 lineto +0.12500 0.07000 lineto +fill +0.20500 0.03000 moveto +0.23500 0.03000 lineto +0.23500 0.07000 lineto +0.20500 0.07000 lineto +fill +0.02000 setlinewidth +0.14000 0.12000 0.14000 0.10000 t +0.22000 0.12000 0.22000 0.10000 t +0.13500 0.31000 moveto +0.16500 0.31000 lineto +0.16500 0.35000 lineto +0.13500 0.35000 lineto +fill +0.21500 0.31000 moveto +0.24500 0.31000 lineto +0.24500 0.35000 lineto +0.21500 0.35000 lineto +fill +0.00000 setlinewidth +1 1 1 setrgbcolor +0.14000 0.11000 0.00500 c +0.22000 0.11000 0.00500 c +0.01000 setlinewidth +0.13500 0.05000 0.14500 0.05000 t +0.21500 0.05000 0.22500 0.05000 t +0.15000 0.32500 moveto +0.14000 0.33500 lineto +0.16000 0.33500 lineto +fill +0.23000 0.33000 0.00500 c +% Layer group5 group 5 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.329412 0.545098 0.329412 setrgbcolor +0.17000 0.16000 moveto +0.17000 0.20000 lineto +0.12000 0.20000 lineto +0.12000 0.16000 lineto +fill +0.25000 0.16000 moveto +0.25000 0.20000 lineto +0.20000 0.20000 lineto +0.20000 0.16000 lineto +fill +1 setlinecap +0.627451 0.627451 0.627451 setrgbcolor +0.11500 0.04000 moveto +0.15500 0.04000 lineto +0.15500 0.06000 lineto +0.11500 0.06000 lineto +fill +0.19500 0.04000 moveto +0.23500 0.04000 lineto +0.23500 0.06000 lineto +0.19500 0.06000 lineto +fill +0.02000 setlinewidth +0.13000 0.10000 0.15000 0.12000 t +0.21000 0.10000 0.23000 0.12000 t +0.12500 0.32000 moveto +0.16500 0.32000 lineto +0.16500 0.34000 lineto +0.12500 0.34000 lineto +fill +0.20500 0.32000 moveto +0.24500 0.32000 lineto +0.24500 0.34000 lineto +0.20500 0.34000 lineto +fill +0.00000 setlinewidth +1 1 1 setrgbcolor +0.14000 0.11000 0.00500 c +0.22000 0.11000 0.00500 c +0.01000 setlinewidth +0.13500 0.05000 0.14500 0.05000 t +0.21500 0.05000 0.22500 0.05000 t +0.15000 0.32500 moveto +0.14000 0.33500 lineto +0.16000 0.33500 lineto +fill +0.23000 0.33000 0.00500 c +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.17000 0.16000 moveto +0.17000 0.20000 lineto +0.12000 0.20000 lineto +0.12000 0.16000 lineto +fill +0.25000 0.16000 moveto +0.25000 0.20000 lineto +0.20000 0.20000 lineto +0.20000 0.16000 lineto +fill +1 setlinecap +0.439216 0.439216 0.439216 setrgbcolor +0.12500 0.04000 moveto +0.16500 0.04000 lineto +0.16500 0.06000 lineto +0.12500 0.06000 lineto +fill +0.20500 0.04000 moveto +0.24500 0.04000 lineto +0.24500 0.06000 lineto +0.20500 0.06000 lineto +fill +0.02000 setlinewidth +0.13000 0.11000 0.15000 0.11000 t +0.21000 0.11000 0.23000 0.11000 t +0.13500 0.32000 moveto +0.17500 0.32000 lineto +0.17500 0.34000 lineto +0.13500 0.34000 lineto +fill +0.21500 0.32000 moveto +0.25500 0.32000 lineto +0.25500 0.34000 lineto +0.21500 0.34000 lineto +fill +0.00000 setlinewidth +1 1 1 setrgbcolor +0.14000 0.11000 0.00500 c +0.22000 0.11000 0.00500 c +0.01000 setlinewidth +0.13500 0.05000 0.14500 0.05000 t +0.21500 0.05000 0.22500 0.05000 t +0.15000 0.32500 moveto +0.14000 0.33500 lineto +0.16000 0.33500 lineto +fill +0.23000 0.33000 0.00500 c +% Layer topsilk group 1 drill 0 mask 0 +% Layer plated-drill group -1 drill 1 mask 0 +0.00000 setlinewidth +0.22000 0.11000 0.00500 c +% Layer unplated-drill group -1 drill 1 mask 0 +0.14000 0.11000 0.00500 c +% Layer group8 group 8 drill 0 mask 0 +0.01000 setlinewidth +1 0.545098 0.329412 setrgbcolor +0.13000 0.18000 0.16000 0.18000 t +% Layer group9 group 9 drill 0 mask 0 +0 0.545098 0.329412 setrgbcolor +0.21000 0.18000 0.24000 0.18000 t +% Layer group8 group 8 drill 0 mask 0 +1 1 1 setrgbcolor +0.13500 0.05000 0.14500 0.05000 t +0.15000 0.32500 moveto +0.14000 0.33500 lineto +0.16000 0.33500 lineto +fill +0.23000 0.33000 0.00500 c +% Layer group9 group 9 drill 0 mask 0 +0.21500 0.05000 0.22500 0.05000 t +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/mech.exc/mech.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.exc/mech.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.exc/mech.plated.cnc (revision 33253) @@ -0,0 +1,16 @@ +M48 +INCH +T11C0.010 +% +T11 +G05 +X002200Y003900 +G00X002100Y003200 +M15 +G01X002400Y003200 +M17 +G00X002150Y004500 +M15 +G01X002250Y004500 +M17 +M30 Index: tags/2.3.0/tests/RTT/ref/mech.exc/mech.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.exc/mech.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.exc/mech.unplated.cnc (revision 33253) @@ -0,0 +1,17 @@ +M48 +INCH +T12C0.010 +% +T12 +G05 +X001400Y003900 +X002300Y001700 +G00X001300Y003200 +M15 +G01X001600Y003200 +M17 +G00X001350Y004500 +M15 +G01X001450Y004500 +M17 +M30 Index: tags/2.3.0/tests/RTT/ref/mech.gbr/mech.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.gbr/mech.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.gbr/mech.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,53 @@ +G04 start of page 4 for group 10 layer_idx 1 * +G04 Title: (unknown), bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD19C,0.0100*% +%ADD18C,0.0200*% +%ADD17C,0.0001*% +G54D17*G36* +X17000Y34000D02*Y30000D01* +X12000D01* +Y34000D01* +X17000D01* +G37* +G36* +X25000D02*Y30000D01* +X20000D01* +Y34000D01* +X25000D01* +G37* +G36* +X12500Y47000D02*X15500D01* +Y43000D01* +X12500D01* +Y47000D01* +G37* +G36* +X20500D02*X23500D01* +Y43000D01* +X20500D01* +Y47000D01* +G37* +G54D18*X14000Y38000D02*Y40000D01* +X22000Y38000D02*Y40000D01* +G54D17*G36* +X13500Y19000D02*X16500D01* +Y15000D01* +X13500D01* +Y19000D01* +G37* +G36* +X21500D02*X24500D01* +Y15000D01* +X21500D01* +Y19000D01* +G37* +G54D19*M02* Index: tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.mech.proute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.mech.proute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.mech.proute.9.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 10 for group 9 layer_idx 12 * +G04 Title: (unknown), global-mech * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_MECH_PROUTE_9*% +%ADD26C,0.0100*% +G54D26*X21500Y45000D02*X22500D01* +M02* Index: tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.mech.uroute.8.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.mech.uroute.8.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.mech.uroute.8.gbr (revision 33253) @@ -0,0 +1,21 @@ +G04 start of page 9 for group 8 layer_idx 11 * +G04 Title: (unknown), global-mech * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_MECH_UROUTE_8*% +%ADD25C,0.0001*% +%ADD24C,0.0100*% +G54D24*X13500Y45000D02*X14500D01* +G54D25*G36* +X15000Y17500D02*X14000Y16500D01* +X16000D01* +X15000Y17500D01* +G37* +G54D24*X23000Y17000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.virtual.pdrill.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.virtual.pdrill.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.virtual.pdrill.none.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 5 for group -1 layer_idx 268435462 * +G04 Title: (unknown), * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_VIRTUAL_PDRILL_NONE*% +%ADD20C,0.0100*% +G54D20*X22000Y39000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.virtual.udrill.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.virtual.udrill.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.gbr/mech.global.virtual.udrill.none.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 6 for group -1 layer_idx 268435463 * +G04 Title: (unknown), * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_VIRTUAL_UDRILL_NONE*% +%ADD21C,0.0100*% +G54D21*X14000Y39000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/mech.gbr/mech.intern.copper.none.5.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.gbr/mech.intern.copper.none.5.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.gbr/mech.intern.copper.none.5.gbr (revision 33253) @@ -0,0 +1,53 @@ +G04 start of page 3 for group 5 layer_idx 4 * +G04 Title: (unknown), Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_5*% +%ADD16C,0.0100*% +%ADD15C,0.0200*% +%ADD14C,0.0001*% +G54D14*G36* +X17000Y34000D02*Y30000D01* +X12000D01* +Y34000D01* +X17000D01* +G37* +G36* +X25000D02*Y30000D01* +X20000D01* +Y34000D01* +X25000D01* +G37* +G36* +X11500Y46000D02*X15500D01* +Y44000D01* +X11500D01* +Y46000D01* +G37* +G36* +X19500D02*X23500D01* +Y44000D01* +X19500D01* +Y46000D01* +G37* +G54D15*X13000Y40000D02*X15000Y38000D01* +X21000Y40000D02*X23000Y38000D01* +G54D14*G36* +X12500Y18000D02*X16500D01* +Y16000D01* +X12500D01* +Y18000D01* +G37* +G36* +X20500D02*X24500D01* +Y16000D01* +X20500D01* +Y18000D01* +G37* +G54D16*M02* Index: tags/2.3.0/tests/RTT/ref/mech.gbr/mech.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.gbr/mech.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.gbr/mech.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1175 @@ +G04 start of page 11 for group -1 layer_idx 268435461 * +G04 Title: (unknown), * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD30C,0.0100*% +%ADD29C,0.0001*% +%ADD28C,0.0060*% +%ADD27C,0.0080*% +G54D27*X14000Y39000D02*Y37400D01* +Y39000D02*X15387Y39800D01* +X14000Y39000D02*X12613Y39800D01* +X22000Y40600D02*Y37400D01* +X20400Y39000D02*X23600D01* +X15000Y92850D02*Y89650D01* +X13400Y91250D02*X16600D01* +G54D28*X135000Y95000D02*X136500Y92000D01* +X138000Y95000D01* +X136500Y92000D02*Y89000D01* +X139800Y92300D02*X142050D01* +X139800Y89000D02*X142800D01* +X139800Y95000D02*Y89000D01* +Y95000D02*X142800D01* +X147600D02*X148350Y94250D01* +X145350Y95000D02*X147600D01* +X144600Y94250D02*X145350Y95000D01* +X144600Y94250D02*Y92750D01* +X145350Y92000D01* +X147600D01* +X148350Y91250D01* +Y89750D01* +X147600Y89000D02*X148350Y89750D01* +X145350Y89000D02*X147600D01* +X144600Y89750D02*X145350Y89000D01* +X98000Y93800D02*X99200Y95000D01* +Y89000D01* +X98000D02*X100250D01* +X15000Y106250D02*Y104650D01* +Y106250D02*X16387Y107050D01* +X15000Y106250D02*X13613Y107050D01* +X140000Y110000D02*Y104000D01* +Y110000D02*X143750Y104000D01* +Y110000D02*Y104000D01* +X145550Y109250D02*Y104750D01* +Y109250D02*X146300Y110000D01* +X147800D01* +X148550Y109250D01* +Y104750D01* +X147800Y104000D02*X148550Y104750D01* +X146300Y104000D02*X147800D01* +X145550Y104750D02*X146300Y104000D01* +X98000Y108800D02*X99200Y110000D01* +Y104000D01* +X98000D02*X100250D01* +G54D29*G36* +X45000Y110000D02*X49500D01* +Y104000D01* +X45000D01* +Y110000D01* +G37* +G36* +X50400D02*X54900D01* +Y104000D01* +X50400D01* +Y110000D01* +G37* +G36* +X55800D02*X60300D01* +Y104000D01* +X55800D01* +Y110000D01* +G37* +G54D28*X61200Y108800D02*X62400Y110000D01* +Y104000D01* +X61200D02*X63450D01* +G54D29*G36* +X65250Y110000D02*X69750D01* +Y104000D01* +X65250D01* +Y110000D01* +G37* +G36* +X45000Y95000D02*X49500D01* +Y89000D01* +X45000D01* +Y95000D01* +G37* +G36* +X50400D02*X54900D01* +Y89000D01* +X50400D01* +Y95000D01* +G37* +G36* +X55800D02*X60300D01* +Y89000D01* +X55800D01* +Y95000D01* +G37* +G54D28*X61200Y93800D02*X62400Y95000D01* +Y89000D01* +X61200D02*X63450D01* +G54D29*G36* +X65250Y95000D02*X69750D01* +Y89000D01* +X65250D01* +Y95000D01* +G37* +G54D28*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D29*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D28*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D29*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D28*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D29*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D28*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D29*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D28*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D29*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D28*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D29*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G54D28*X48000Y138800D02*X49200Y140000D01* +Y134000D01* +X48000D02*X50250D01* +G54D29*G36* +X54750Y140000D02*X59250D01* +Y134000D01* +X54750D01* +Y140000D01* +G37* +G36* +X60150D02*X64650D01* +Y134000D01* +X60150D01* +Y140000D01* +G37* +G36* +X65550D02*X70050D01* +Y134000D01* +X65550D01* +Y140000D01* +G37* +G36* +X70950D02*X75450D01* +Y134000D01* +X70950D01* +Y140000D01* +G37* +G36* +X76350D02*X80850D01* +Y134000D01* +X76350D01* +Y140000D01* +G37* +G36* +X81750D02*X86250D01* +Y134000D01* +X81750D01* +Y140000D01* +G37* +G36* +X87150D02*X91650D01* +Y134000D01* +X87150D01* +Y140000D01* +G37* +G36* +X92550D02*X97050D01* +Y134000D01* +X92550D01* +Y140000D01* +G37* +G36* +X97950D02*X102450D01* +Y134000D01* +X97950D01* +Y140000D01* +G37* +G36* +X106050D02*X110550D01* +Y134000D01* +X106050D01* +Y140000D01* +G37* +G36* +X111450D02*X115950D01* +Y134000D01* +X111450D01* +Y140000D01* +G37* +G36* +X116850D02*X121350D01* +Y134000D01* +X116850D01* +Y140000D01* +G37* +G36* +X122250D02*X126750D01* +Y134000D01* +X122250D01* +Y140000D01* +G37* +G36* +X127650D02*X132150D01* +Y134000D01* +X127650D01* +Y140000D01* +G37* +G36* +X135750D02*X140250D01* +Y134000D01* +X135750D01* +Y140000D01* +G37* +G36* +X141150D02*X145650D01* +Y134000D01* +X141150D01* +Y140000D01* +G37* +G36* +X146550D02*X151050D01* +Y134000D01* +X146550D01* +Y140000D01* +G37* +G36* +X151950D02*X156450D01* +Y134000D01* +X151950D01* +Y140000D01* +G37* +G36* +X157350D02*X161850D01* +Y134000D01* +X157350D01* +Y140000D01* +G37* +G36* +X165450D02*X169950D01* +Y134000D01* +X165450D01* +Y140000D01* +G37* +G36* +X170850D02*X175350D01* +Y134000D01* +X170850D01* +Y140000D01* +G37* +G36* +X176250D02*X180750D01* +Y134000D01* +X176250D01* +Y140000D01* +G37* +G36* +X181650D02*X186150D01* +Y134000D01* +X181650D01* +Y140000D01* +G37* +G36* +X189750D02*X194250D01* +Y134000D01* +X189750D01* +Y140000D01* +G37* +G36* +X195150D02*X199650D01* +Y134000D01* +X195150D01* +Y140000D01* +G37* +G36* +X203250D02*X207750D01* +Y134000D01* +X203250D01* +Y140000D01* +G37* +G36* +X208650D02*X213150D01* +Y134000D01* +X208650D01* +Y140000D01* +G37* +G36* +X214050D02*X218550D01* +Y134000D01* +X214050D01* +Y140000D01* +G37* +G36* +X219450D02*X223950D01* +Y134000D01* +X219450D01* +Y140000D01* +G37* +G36* +X227550D02*X232050D01* +Y134000D01* +X227550D01* +Y140000D01* +G37* +G36* +X232950D02*X237450D01* +Y134000D01* +X232950D01* +Y140000D01* +G37* +G36* +X238350D02*X242850D01* +Y134000D01* +X238350D01* +Y140000D01* +G37* +G36* +X243750D02*X248250D01* +Y134000D01* +X243750D01* +Y140000D01* +G37* +G36* +X249150D02*X253650D01* +Y134000D01* +X249150D01* +Y140000D01* +G37* +G36* +X254550D02*X259050D01* +Y134000D01* +X254550D01* +Y140000D01* +G37* +G36* +X259950D02*X264450D01* +Y134000D01* +X259950D01* +Y140000D01* +G37* +G54D28*X268050Y139250D02*X268800Y140000D01* +X271050D01* +X271800Y139250D01* +Y137750D01* +X268050Y134000D02*X271800Y137750D01* +X268050Y134000D02*X271800D01* +G54D29*G36* +X276300Y140000D02*X280800D01* +Y134000D01* +X276300D01* +Y140000D01* +G37* +G36* +X281700D02*X286200D01* +Y134000D01* +X281700D01* +Y140000D01* +G37* +G36* +X287100D02*X291600D01* +Y134000D01* +X287100D01* +Y140000D01* +G37* +G36* +X292500D02*X297000D01* +Y134000D01* +X292500D01* +Y140000D01* +G37* +G36* +X297900D02*X302400D01* +Y134000D01* +X297900D01* +Y140000D01* +G37* +G36* +X306000D02*X310500D01* +Y134000D01* +X306000D01* +Y140000D01* +G37* +G36* +X311400D02*X315900D01* +Y134000D01* +X311400D01* +Y140000D01* +G37* +G36* +X316800D02*X321300D01* +Y134000D01* +X316800D01* +Y140000D01* +G37* +G36* +X322200D02*X326700D01* +Y134000D01* +X322200D01* +Y140000D01* +G37* +G36* +X327600D02*X332100D01* +Y134000D01* +X327600D01* +Y140000D01* +G37* +G54D30*X13000Y32000D02*X16000D01* +G54D28*X12775Y-8000D02*X15775D01* +X16525Y-7250D01* +Y-5450D02*Y-7250D01* +X15775Y-4700D02*X16525Y-5450D01* +X13525Y-4700D02*X15775D01* +X13525Y-2000D02*Y-8000D01* +X12775Y-2000D02*X15775D01* +X16525Y-2750D01* +Y-3950D01* +X15775Y-4700D02*X16525Y-3950D01* +G54D29*G36* +X18325Y-2000D02*X22825D01* +Y-8000D01* +X18325D01* +Y-2000D01* +G37* +G36* +X23725D02*X28225D01* +Y-8000D01* +X23725D01* +Y-2000D01* +G37* +G36* +X29125D02*X33625D01* +Y-8000D01* +X29125D01* +Y-2000D01* +G37* +G36* +X34525D02*X39025D01* +Y-8000D01* +X34525D01* +Y-2000D01* +G37* +G36* +X42625D02*X47125D01* +Y-8000D01* +X42625D01* +Y-2000D01* +G37* +G36* +X48025D02*X52525D01* +Y-8000D01* +X48025D01* +Y-2000D01* +G37* +G36* +X53425D02*X57925D01* +Y-8000D01* +X53425D01* +Y-2000D01* +G37* +G36* +X58825D02*X63325D01* +Y-8000D01* +X58825D01* +Y-2000D01* +G37* +G36* +X64225D02*X68725D01* +Y-8000D01* +X64225D01* +Y-2000D01* +G37* +G36* +X69625D02*X74125D01* +Y-8000D01* +X69625D01* +Y-2000D01* +G37* +G36* +X75025D02*X79525D01* +Y-8000D01* +X75025D01* +Y-2000D01* +G37* +G36* +X83125D02*X87625D01* +Y-8000D01* +X83125D01* +Y-2000D01* +G37* +G36* +X88525D02*X93025D01* +Y-8000D01* +X88525D01* +Y-2000D01* +G37* +G36* +X96625D02*X101125D01* +Y-8000D01* +X96625D01* +Y-2000D01* +G37* +G36* +X102025D02*X106525D01* +Y-8000D01* +X102025D01* +Y-2000D01* +G37* +G36* +X107425D02*X111925D01* +Y-8000D01* +X107425D01* +Y-2000D01* +G37* +G36* +X115525D02*X120025D01* +Y-8000D01* +X115525D01* +Y-2000D01* +G37* +G36* +X120925D02*X125425D01* +Y-8000D01* +X120925D01* +Y-2000D01* +G37* +G36* +X126325D02*X130825D01* +Y-8000D01* +X126325D01* +Y-2000D01* +G37* +G36* +X131725D02*X136225D01* +Y-8000D01* +X131725D01* +Y-2000D01* +G37* +G36* +X137125D02*X141625D01* +Y-8000D01* +X137125D01* +Y-2000D01* +G37* +G36* +X142525D02*X147025D01* +Y-8000D01* +X142525D01* +Y-2000D01* +G37* +G36* +X147925D02*X152425D01* +Y-8000D01* +X147925D01* +Y-2000D01* +G37* +G36* +X153325D02*X157825D01* +Y-8000D01* +X153325D01* +Y-2000D01* +G37* +G36* +X158725D02*X163225D01* +Y-8000D01* +X158725D01* +Y-2000D01* +G37* +G36* +X164125D02*X168625D01* +Y-8000D01* +X164125D01* +Y-2000D01* +G37* +G36* +X172225D02*X176725D01* +Y-8000D01* +X172225D01* +Y-2000D01* +G37* +G36* +X177625D02*X182125D01* +Y-8000D01* +X177625D01* +Y-2000D01* +G37* +G36* +X185725D02*X190225D01* +Y-8000D01* +X185725D01* +Y-2000D01* +G37* +G36* +X191125D02*X195625D01* +Y-8000D01* +X191125D01* +Y-2000D01* +G37* +G36* +X196525D02*X201025D01* +Y-8000D01* +X196525D01* +Y-2000D01* +G37* +G36* +X201925D02*X206425D01* +Y-8000D01* +X201925D01* +Y-2000D01* +G37* +G36* +X210025D02*X214525D01* +Y-8000D01* +X210025D01* +Y-2000D01* +G37* +G36* +X215425D02*X219925D01* +Y-8000D01* +X215425D01* +Y-2000D01* +G37* +G36* +X220825D02*X225325D01* +Y-8000D01* +X220825D01* +Y-2000D01* +G37* +G36* +X226225D02*X230725D01* +Y-8000D01* +X226225D01* +Y-2000D01* +G37* +G54D30*X21000Y32000D02*X24000D01* +G54D28*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D29*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D28*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D29*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D28*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D29*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X256100D02*X260600D01* +Y104000D01* +X256100D01* +Y110000D01* +G37* +G36* +X261500D02*X266000D01* +Y104000D01* +X261500D01* +Y110000D01* +G37* +G36* +X266900D02*X271400D01* +Y104000D01* +X266900D01* +Y110000D01* +G37* +G36* +X272300D02*X276800D01* +Y104000D01* +X272300D01* +Y110000D01* +G37* +G36* +X277700D02*X282200D01* +Y104000D01* +X277700D01* +Y110000D01* +G37* +G36* +X285800D02*X290300D01* +Y104000D01* +X285800D01* +Y110000D01* +G37* +G54D28*X293900D02*Y104000D01* +Y110000D02*X296900D01* +X293900Y107300D02*X296150D01* +G54D29*G36* +X298700Y110000D02*X303200D01* +Y104000D01* +X298700D01* +Y110000D01* +G37* +G36* +X304100D02*X308600D01* +Y104000D01* +X304100D01* +Y110000D01* +G37* +G36* +X309500D02*X314000D01* +Y104000D01* +X309500D01* +Y110000D01* +G37* +G36* +X314900D02*X319400D01* +Y104000D01* +X314900D01* +Y110000D01* +G37* +G36* +X320300D02*X324800D01* +Y104000D01* +X320300D01* +Y110000D01* +G37* +G36* +X325700D02*X330200D01* +Y104000D01* +X325700D01* +Y110000D01* +G37* +G36* +X331100D02*X335600D01* +Y104000D01* +X331100D01* +Y110000D01* +G37* +G36* +X336500D02*X341000D01* +Y104000D01* +X336500D01* +Y110000D01* +G37* +G36* +X341900D02*X346400D01* +Y104000D01* +X341900D01* +Y110000D01* +G37* +G36* +X347300D02*X351800D01* +Y104000D01* +X347300D01* +Y110000D01* +G37* +G54D28*X356150D02*Y104000D01* +X358100Y110000D02*X359150Y108950D01* +Y105050D01* +X358100Y104000D02*X359150Y105050D01* +X355400Y104000D02*X358100D01* +X355400Y110000D02*X358100D01* +G54D29*G36* +X360950D02*X365450D01* +Y104000D01* +X360950D01* +Y110000D01* +G37* +G36* +X366350D02*X370850D01* +Y104000D01* +X366350D01* +Y110000D01* +G37* +G36* +X371750D02*X376250D01* +Y104000D01* +X371750D01* +Y110000D01* +G37* +G36* +X377150D02*X381650D01* +Y104000D01* +X377150D01* +Y110000D01* +G37* +G36* +X382550D02*X387050D01* +Y104000D01* +X382550D01* +Y110000D01* +G37* +G36* +X387950D02*X392450D01* +Y104000D01* +X387950D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/mech.gbr/mech.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.gbr/mech.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.gbr/mech.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,53 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: (unknown), top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD13C,0.0100*% +%ADD12C,0.0200*% +%ADD11C,0.0001*% +G54D11*G36* +X17000Y34000D02*Y30000D01* +X12000D01* +Y34000D01* +X17000D01* +G37* +G36* +X25000D02*Y30000D01* +X20000D01* +Y34000D01* +X25000D01* +G37* +G36* +X12500Y46000D02*X16500D01* +Y44000D01* +X12500D01* +Y46000D01* +G37* +G36* +X20500D02*X24500D01* +Y44000D01* +X20500D01* +Y46000D01* +G37* +G54D12*X13000Y39000D02*X15000D01* +X21000D02*X23000D01* +G54D11*G36* +X13500Y18000D02*X17500D01* +Y16000D01* +X13500D01* +Y18000D01* +G37* +G36* +X21500D02*X25500D01* +Y16000D01* +X21500D01* +Y18000D01* +G37* +G54D13*M02* Index: tags/2.3.0/tests/RTT/ref/mech.net =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.net (revision 33253) @@ -0,0 +1,13 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB /home/igor2/C/pcb-rnd/trunk/tests/RTT/mech.lht +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 + Index: tags/2.3.0/tests/RTT/ref/mech.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/mech.png =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/mech.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/mech.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/mech.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/mech.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/mech.scad =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.scad (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.scad (revision 33253) @@ -0,0 +1,267 @@ +// Round cap line +module pcb_line_rc(x1, y1, length, angle, width, thick) { + translate([x1,y1,0]) { + rotate([0,0,angle]) { + translate([length/2, 0, 0]) + cube([length, width, thick], center=true); + cylinder(r=width/2, h=thick, center=true, $fn=30); + translate([length, 0, 0]) + cylinder(r=width/2, h=thick, center=true, $fn=30); + } + } +} +// Square cap line +module pcb_line_sc(x1, y1, length, angle, width, thick) { + translate([x1,y1,0]) { + rotate([0,0,angle]) { + translate([length/2, 0, 0]) + cube([length + width, width, thick], center=true); + } + } +} +// filled rectangle +module pcb_fill_rect(x1, y1, x2, y2, angle, thick) { + translate([(x1+x2)/2,(y1+y2)/2,0]) + rotate([0,0,angle]) + cube([x2-x1, y2-y1, thick], center=true); +} +// filled polygon +module pcb_fill_poly(coords, thick) { + linear_extrude(height=thick) + polygon(coords); +} +// filled circle +module pcb_fcirc(x1, y1, radius, thick) { + translate([x1,y1,0]) + cylinder(r=radius, h=thick, center=true, $fn=30); +} +module pcb_outline() { + polygon([ + [0.0000,12.7000],[12.7000,12.7000],[12.7000,0.0000],[0.0000,0.0000] + ]); +} +module layer_bottom_silk_pos_1() { + color([0,0,0]) + translate([0,0,-0.833000]) { + } +} + +module layer_group_bottom_silk() { + layer_bottom_silk_pos_1(); +} + +module layer_bottom_copper_pos_2() { + color([1,0.4,0.2]) + translate([0,0,-0.811000]) { + pcb_fill_poly([[3.0480,8.6360],[4.3180,8.6360],[4.3180,7.6200],[3.0480,7.6200]], 0.010000); + pcb_fill_poly([[5.0800,8.6360],[6.3500,8.6360],[6.3500,7.6200],[5.0800,7.6200]], 0.010000); + pcb_fill_poly([[3.1750,11.9380],[3.9370,11.9380],[3.9370,10.9220],[3.1750,10.9220]], 0.010000); + pcb_fill_poly([[5.2070,11.9380],[5.9690,11.9380],[5.9690,10.9220],[5.2070,10.9220]], 0.010000); + pcb_line_rc(3.5560, 9.6520, 0.5080, 90.000000, 0.5080, 0.010000); + pcb_line_rc(5.5880, 9.6520, 0.5080, 90.000000, 0.5080, 0.010000); + pcb_fill_poly([[3.4290,4.8260],[4.1910,4.8260],[4.1910,3.8100],[3.4290,3.8100]], 0.010000); + pcb_fill_poly([[5.4610,4.8260],[6.2230,4.8260],[6.2230,3.8100],[5.4610,3.8100]], 0.010000); + pcb_fcirc(3.5560, 9.9060, 0.1270, 0.010000); + // line-approx arc 20.000000 .. 310.000000 by 10.000000 + pcb_line_rc(3.4516, 9.8680, 0.0194, -65.001333, 0.0000, 0.010000); + pcb_line_rc(3.4598, 9.8504, 0.0194, -54.998045, 0.0000, 0.010000); + pcb_line_rc(3.4709, 9.8346, 0.0194, -45.000000, 0.0000, 0.010000); + pcb_line_rc(3.4846, 9.8209, 0.0194, -35.001955, 0.0000, 0.010000); + pcb_line_rc(3.5004, 9.8098, 0.0194, -24.998667, 0.0000, 0.010000); + pcb_line_rc(3.5180, 9.8016, 0.0194, -14.999059, 0.0000, 0.010000); + pcb_line_rc(3.5367, 9.7966, 0.0194, -5.002155, 0.0000, 0.010000); + pcb_line_rc(3.5560, 9.7949, 0.0194, 5.002413, 0.0000, 0.010000); + pcb_line_rc(3.5753, 9.7966, 0.0194, 14.999059, 0.0000, 0.010000); + pcb_line_rc(3.5940, 9.8016, 0.0194, 24.998667, 0.0000, 0.010000); + pcb_line_rc(3.6116, 9.8098, 0.0194, 35.001955, 0.0000, 0.010000); + pcb_line_rc(3.6274, 9.8209, 0.0194, 45.000000, 0.0000, 0.010000); + pcb_line_rc(3.6411, 9.8346, 0.0194, 54.998045, 0.0000, 0.010000); + pcb_line_rc(3.6522, 9.8504, 0.0194, 65.001333, 0.0000, 0.010000); + pcb_line_rc(3.6604, 9.8680, 0.0194, 75.000941, 0.0000, 0.010000); + pcb_line_rc(3.6654, 9.8867, 0.0194, 84.997587, 0.0000, 0.010000); + pcb_line_rc(3.6671, 9.9060, 0.0194, 95.002155, 0.0000, 0.010000); + pcb_line_rc(3.6654, 9.9253, 0.0194, 104.999059, 0.0000, 0.010000); + pcb_line_rc(3.6604, 9.9440, 0.0194, 114.998667, 0.0000, 0.010000); + pcb_line_rc(3.6522, 9.9616, 0.0194, 125.001955, 0.0000, 0.010000); + pcb_line_rc(3.6411, 9.9774, 0.0194, 135.000000, 0.0000, 0.010000); + pcb_line_rc(3.6274, 9.9911, 0.0194, 144.998045, 0.0000, 0.010000); + pcb_line_rc(3.6116, 10.0022, 0.0194, 155.001333, 0.0000, 0.010000); + pcb_line_rc(3.5940, 10.0104, 0.0194, 165.000941, 0.0000, 0.010000); + pcb_line_rc(3.5753, 10.0154, 0.0194, 175.000534, 0.0000, 0.010000); + pcb_line_rc(3.5560, 10.0171, 0.0194, -175.000792, 0.0000, 0.010000); + pcb_line_rc(3.5367, 10.0154, 0.0194, -165.000941, 0.0000, 0.010000); + pcb_line_rc(3.5180, 10.0104, 0.0194, -155.001333, 0.0000, 0.010000); + pcb_line_rc(3.5004, 10.0022, 0.0194, -144.998045, 0.0000, 0.010000); + pcb_fcirc(5.5880, 9.9060, 0.1270, 0.010000); + } +} + +module layer_group_bottom_copper() { + layer_bottom_copper_pos_2(); +} + +module layer_top_copper_pos_3() { + color([1,0.4,0.2]) + translate([0,0,0.811000]) { + pcb_fill_poly([[3.0480,8.6360],[4.3180,8.6360],[4.3180,7.6200],[3.0480,7.6200]], 0.010000); + pcb_fill_poly([[5.0800,8.6360],[6.3500,8.6360],[6.3500,7.6200],[5.0800,7.6200]], 0.010000); + pcb_fill_poly([[3.1750,11.6840],[4.1910,11.6840],[4.1910,11.1760],[3.1750,11.1760]], 0.010000); + pcb_fill_poly([[5.2070,11.6840],[6.2230,11.6840],[6.2230,11.1760],[5.2070,11.1760]], 0.010000); + pcb_line_rc(3.3020, 9.9060, 0.5080, 0.000000, 0.5080, 0.010000); + pcb_line_rc(5.3340, 9.9060, 0.5080, 0.000000, 0.5080, 0.010000); + pcb_fill_poly([[3.4290,4.5720],[4.4450,4.5720],[4.4450,4.0640],[3.4290,4.0640]], 0.010000); + pcb_fill_poly([[5.4610,4.5720],[6.4770,4.5720],[6.4770,4.0640],[5.4610,4.0640]], 0.010000); + pcb_fcirc(3.5560, 9.9060, 0.1270, 0.010000); + // line-approx arc 20.000000 .. 310.000000 by 10.000000 + pcb_line_rc(3.4516, 9.8680, 0.0194, -65.001333, 0.0000, 0.010000); + pcb_line_rc(3.4598, 9.8504, 0.0194, -54.998045, 0.0000, 0.010000); + pcb_line_rc(3.4709, 9.8346, 0.0194, -45.000000, 0.0000, 0.010000); + pcb_line_rc(3.4846, 9.8209, 0.0194, -35.001955, 0.0000, 0.010000); + pcb_line_rc(3.5004, 9.8098, 0.0194, -24.998667, 0.0000, 0.010000); + pcb_line_rc(3.5180, 9.8016, 0.0194, -14.999059, 0.0000, 0.010000); + pcb_line_rc(3.5367, 9.7966, 0.0194, -5.002155, 0.0000, 0.010000); + pcb_line_rc(3.5560, 9.7949, 0.0194, 5.002413, 0.0000, 0.010000); + pcb_line_rc(3.5753, 9.7966, 0.0194, 14.999059, 0.0000, 0.010000); + pcb_line_rc(3.5940, 9.8016, 0.0194, 24.998667, 0.0000, 0.010000); + pcb_line_rc(3.6116, 9.8098, 0.0194, 35.001955, 0.0000, 0.010000); + pcb_line_rc(3.6274, 9.8209, 0.0194, 45.000000, 0.0000, 0.010000); + pcb_line_rc(3.6411, 9.8346, 0.0194, 54.998045, 0.0000, 0.010000); + pcb_line_rc(3.6522, 9.8504, 0.0194, 65.001333, 0.0000, 0.010000); + pcb_line_rc(3.6604, 9.8680, 0.0194, 75.000941, 0.0000, 0.010000); + pcb_line_rc(3.6654, 9.8867, 0.0194, 84.997587, 0.0000, 0.010000); + pcb_line_rc(3.6671, 9.9060, 0.0194, 95.002155, 0.0000, 0.010000); + pcb_line_rc(3.6654, 9.9253, 0.0194, 104.999059, 0.0000, 0.010000); + pcb_line_rc(3.6604, 9.9440, 0.0194, 114.998667, 0.0000, 0.010000); + pcb_line_rc(3.6522, 9.9616, 0.0194, 125.001955, 0.0000, 0.010000); + pcb_line_rc(3.6411, 9.9774, 0.0194, 135.000000, 0.0000, 0.010000); + pcb_line_rc(3.6274, 9.9911, 0.0194, 144.998045, 0.0000, 0.010000); + pcb_line_rc(3.6116, 10.0022, 0.0194, 155.001333, 0.0000, 0.010000); + pcb_line_rc(3.5940, 10.0104, 0.0194, 165.000941, 0.0000, 0.010000); + pcb_line_rc(3.5753, 10.0154, 0.0194, 175.000534, 0.0000, 0.010000); + pcb_line_rc(3.5560, 10.0171, 0.0194, -175.000792, 0.0000, 0.010000); + pcb_line_rc(3.5367, 10.0154, 0.0194, -165.000941, 0.0000, 0.010000); + pcb_line_rc(3.5180, 10.0104, 0.0194, -155.001333, 0.0000, 0.010000); + pcb_line_rc(3.5004, 10.0022, 0.0194, -144.998045, 0.0000, 0.010000); + pcb_fcirc(5.5880, 9.9060, 0.1270, 0.010000); + } +} + +module layer_top_copper_pos_4() { + color([1,0.4,0.2]) + translate([0,0,0.811000]) { + } +} + +module layer_group_top_copper() { + layer_top_copper_pos_3(); + layer_top_copper_pos_4(); +} + +module layer_top_mask_pos_5() { + color([0,0.7,0,0.5]) + translate([0,0,0.822000]) { + pcb_fill_rect(0.0000, 0.0000, 12.7000, 12.7000, 0.000000, 0.010000); + } +} + +module layer_top_mask_neg_6() { + color([0,0.7,0,0.5]) + translate([0,0,0.812000]) { + } +} + +module layer_top_mask_pos_7() { + color([0,0.7,0,0.5]) + translate([0,0,0.822000]) { + } +} + +module layer_group_top_mask() { + union() { + difference() { + layer_top_mask_pos_5(); + layer_top_mask_neg_6(); +} + layer_top_mask_pos_7(); +} +} + +module layer_bottom_mask_pos_8() { + color([0,0.7,0,0.5]) + translate([0,0,-0.822000]) { + pcb_fill_rect(0.0000, 0.0000, 12.7000, 12.7000, 0.000000, 0.010000); + } +} + +module layer_bottom_mask_neg_9() { + color([0,0.7,0,0.5]) + translate([0,0,-0.832000]) { + } +} + +module layer_bottom_mask_pos_10() { + color([0,0.7,0,0.5]) + translate([0,0,-0.822000]) { + } +} + +module layer_group_bottom_mask() { + union() { + difference() { + layer_bottom_mask_pos_8(); + layer_bottom_mask_neg_9(); +} + layer_bottom_mask_pos_10(); +} +} + +module layer_top_silk_pos_11() { + color([0,0,0]) + translate([0,0,0.833000]) { + } +} + +module layer_top_silk_pos_12() { + color([0,0,0]) + translate([0,0,0.833000]) { + } +} + +module layer_group_top_silk() { + layer_top_silk_pos_11(); + layer_top_silk_pos_12(); +} + +module pcb_drill() { + translate([3.5560,9.9060,0]) + cylinder(r=0.1270, h=4, center=true, $fn=30); + translate([5.5880,9.9060,0]) + cylinder(r=0.1270, h=4, center=true, $fn=30); +} +module pcb_board_main() { + translate ([0, 0, -0.8]) + linear_extrude(height=1.6) + pcb_outline(); + layer_group_bottom_silk(); + layer_group_bottom_copper(); + layer_group_top_copper(); + layer_group_top_mask(); + layer_group_bottom_mask(); + layer_group_top_silk(); +} + +module pcb_board() { + intersection() { + translate ([0, 0, -4]) + linear_extrude(height=8) + pcb_outline(); + union() { + difference() { + pcb_board_main(); + pcb_drill(); + } + } + } +} + +pcb_board(); Index: tags/2.3.0/tests/RTT/ref/mech.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.svg (revision 33253) @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/mech.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/mech.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/mech.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: (unknown) - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/netlist.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.bom (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: board with minimal netlist - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +1,"dip(4)","4*300",U1 Index: tags/2.3.0/tests/RTT/ref/netlist.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.dsn (revision 33253) @@ -0,0 +1,113 @@ +(pcb board with minimal netlist + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 5 + (place "U1" 2.540000 8.255000 front 0 (PN 0)) + ) + ) + (library + (image 5 + (pin Pstk_shape_7 "1" 0.000000 0.000000) + (pin Pstk_shape_8 "4" 7.620000 0.000000) + (pin Pstk_shape_9 "2" 0.000000 -2.540000) + (pin Pstk_shape_10 "3" 7.620000 -2.540000) + ) + (padstack Pstk_shape_7 + (shape + (polygon "3__top_copper" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "5__Intern" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "7__Intern" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "10__bottom_copper" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + ) + (attach off) + ) + (padstack Pstk_shape_8 + (shape + (circle "3__top_copper" 2.032000) + (circle "5__Intern" 2.032000) + (circle "7__Intern" 2.032000) + (circle "10__bottom_copper" 2.032000) + ) + (attach off) + ) + (padstack Pstk_shape_9 + (shape + (circle "3__top_copper" 2.032000) + (circle "5__Intern" 2.032000) + (circle "7__Intern" 2.032000) + (circle "10__bottom_copper" 2.032000) + ) + (attach off) + ) + (padstack Pstk_shape_10 + (shape + (circle "3__top_copper" 2.032000) + (circle "5__Intern" 2.032000) + (circle "7__Intern" 2.032000) + (circle "10__bottom_copper" 2.032000) + ) + (attach off) + ) + ) + (network + (net "bar" + (pins "U1"-"2" "U1"-"4") + ) + (net "foo" + (pins "U1"-"1" "U1"-"3") + ) + (class geda_default "bar" "foo" + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/netlist.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.eps (revision 33253) @@ -0,0 +1,120 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: netlist.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.00000 setlinewidth +1 setlinecap +0.439216 0.439216 0.439216 setrgbcolor +0.06000 0.13500 moveto +0.14000 0.13500 lineto +0.14000 0.21500 lineto +0.06000 0.21500 lineto +fill +0.40000 0.17500 0.04000 c +0.10000 0.27500 0.04000 c +0.40000 0.27500 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.17500 0.01968 c +0.40000 0.17500 0.01968 c +0.10000 0.27500 0.01968 c +0.40000 0.27500 0.01968 c +% Layer group5 group 5 drill 0 mask 0 +0.00000 setlinewidth +0.439216 0.439216 0.439216 setrgbcolor +0.06000 0.13500 moveto +0.14000 0.13500 lineto +0.14000 0.21500 lineto +0.06000 0.21500 lineto +fill +0.40000 0.17500 0.04000 c +0.10000 0.27500 0.04000 c +0.40000 0.27500 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.17500 0.01968 c +0.40000 0.17500 0.01968 c +0.10000 0.27500 0.01968 c +0.40000 0.27500 0.01968 c +% Layer group7 group 7 drill 0 mask 0 +0.00000 setlinewidth +0.439216 0.439216 0.439216 setrgbcolor +0.06000 0.13500 moveto +0.14000 0.13500 lineto +0.14000 0.21500 lineto +0.06000 0.21500 lineto +fill +0.40000 0.17500 0.04000 c +0.10000 0.27500 0.04000 c +0.40000 0.27500 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.17500 0.01968 c +0.40000 0.17500 0.01968 c +0.10000 0.27500 0.01968 c +0.40000 0.27500 0.01968 c +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +0.25098 0.25098 0.25098 setrgbcolor +0.06000 0.13500 moveto +0.14000 0.13500 lineto +0.14000 0.21500 lineto +0.06000 0.21500 lineto +fill +0.40000 0.17500 0.04000 c +0.10000 0.27500 0.04000 c +0.40000 0.27500 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.17500 0.01968 c +0.40000 0.17500 0.01968 c +0.10000 0.27500 0.01968 c +0.40000 0.27500 0.01968 c +% Layer topsilk group 1 drill 0 mask 0 +0.01000 setlinewidth +0 0 0 setrgbcolor +0.05000 0.12500 0.05000 0.32500 t +0.45000 0.32500 0.05000 0.32500 t +0.45000 0.32500 0.45000 0.12500 t +0.05000 0.12500 0.20000 0.12500 t +0.30000 0.12500 0.45000 0.12500 t +0.000000 180.000000 -0.05000 0.05000 0.25000 0.12500 0.200000 a +0.00700 setlinewidth +0.10000 0.07500 0.10000 0.11000 t +0.10000 0.11000 0.10500 0.11500 t +0.10500 0.11500 0.11500 0.11500 t +0.11500 0.11500 0.12000 0.11000 t +0.12000 0.07500 0.12000 0.11000 t +0.13200 0.08300 0.14000 0.07500 t +0.14000 0.07500 0.14000 0.11500 t +0.13200 0.11500 0.14700 0.11500 t +% Layer plated-drill group -1 drill 1 mask 0 +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.17500 0.01968 c +0.40000 0.17500 0.01968 c +0.10000 0.27500 0.01968 c +0.40000 0.27500 0.01968 c +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/netlist.exc/netlist.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.exc/netlist.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.exc/netlist.plated.cnc (revision 33253) @@ -0,0 +1,11 @@ +M48 +INCH +T11C0.039 +% +T11 +G05 +X001000Y003250 +X004000Y003250 +X001000Y002250 +X004000Y002250 +M30 Index: tags/2.3.0/tests/RTT/ref/netlist.exc/netlist.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.exc/netlist.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.exc/netlist.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/netlist.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,24 @@ +G04 start of page 5 for group 10 layer_idx 1 * +G04 Title: board with minimal netlist, bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD22C,0.0394*% +%ADD21C,0.0800*% +%ADD20C,0.0001*% +G54D20*G36* +X6000Y36500D02*X14000D01* +Y28500D01* +X6000D01* +Y36500D01* +G37* +G54D21*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +G54D22*M02* Index: tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.bottom.mask.none.11.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.bottom.mask.none.11.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.bottom.mask.none.11.gbr (revision 33253) @@ -0,0 +1,23 @@ +G04 start of page 7 for group 11 layer_idx 10 * +G04 Title: board with minimal netlist, bottom_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_MASK_NONE_11*% +%ADD26C,0.0860*% +%ADD25C,0.0001*% +G54D25*G36* +X5700Y36800D02*X14300D01* +Y28200D01* +X5700D01* +Y36800D01* +G37* +G54D26*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 10 for group 9 layer_idx 6 * +G04 Title: board with minimal netlist, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD30C,0.0100*% +G54D30*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.global.virtual.pdrill.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.global.virtual.pdrill.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.global.virtual.pdrill.none.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 9 for group -1 layer_idx 268435462 * +G04 Title: board with minimal netlist, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_VIRTUAL_PDRILL_NONE*% +%ADD29C,0.0394*% +G54D29*X10000Y32500D03* +X40000D03* +X10000Y22500D03* +X40000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.intern.copper.none.5.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.intern.copper.none.5.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.intern.copper.none.5.gbr (revision 33253) @@ -0,0 +1,24 @@ +G04 start of page 3 for group 5 layer_idx 4 * +G04 Title: board with minimal netlist, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_5*% +%ADD16C,0.0394*% +%ADD15C,0.0800*% +%ADD14C,0.0001*% +G54D14*G36* +X6000Y36500D02*X14000D01* +Y28500D01* +X6000D01* +Y36500D01* +G37* +G54D15*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +G54D16*M02* Index: tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.intern.copper.none.7.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.intern.copper.none.7.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.intern.copper.none.7.gbr (revision 33253) @@ -0,0 +1,24 @@ +G04 start of page 4 for group 7 layer_idx 5 * +G04 Title: board with minimal netlist, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_7*% +%ADD19C,0.0394*% +%ADD18C,0.0800*% +%ADD17C,0.0001*% +G54D17*G36* +X6000Y36500D02*X14000D01* +Y28500D01* +X6000D01* +Y36500D01* +G37* +G54D18*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +G54D19*M02* Index: tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1863 @@ +G04 start of page 11 for group -1 layer_idx 268435461 * +G04 Title: board with minimal netlist, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD34C,0.0100*% +%ADD33C,0.0001*% +%ADD32C,0.0060*% +%ADD31C,0.0080*% +G54D31*X10000Y32500D02*Y30900D01* +Y32500D02*X11387Y33300D01* +X10000Y32500D02*X8613Y33300D01* +X40000Y32500D02*Y30900D01* +Y32500D02*X41387Y33300D01* +X40000Y32500D02*X38613Y33300D01* +X10000Y22500D02*Y20900D01* +Y22500D02*X11387Y23300D01* +X10000Y22500D02*X8613Y23300D01* +X40000Y22500D02*Y20900D01* +Y22500D02*X41387Y23300D01* +X40000Y22500D02*X38613Y23300D01* +X15000Y106250D02*Y104650D01* +Y106250D02*X16387Y107050D01* +X15000Y106250D02*X13613Y107050D01* +G54D32*X135000Y110000D02*X136500Y107000D01* +X138000Y110000D01* +X136500Y107000D02*Y104000D01* +X139800Y107300D02*X142050D01* +X139800Y104000D02*X142800D01* +X139800Y110000D02*Y104000D01* +Y110000D02*X142800D01* +X147600D02*X148350Y109250D01* +X145350Y110000D02*X147600D01* +X144600Y109250D02*X145350Y110000D01* +X144600Y109250D02*Y107750D01* +X145350Y107000D01* +X147600D01* +X148350Y106250D01* +Y104750D01* +X147600Y104000D02*X148350Y104750D01* +X145350Y104000D02*X147600D01* +X144600Y104750D02*X145350Y104000D01* +X98000Y106250D02*X101000Y110000D01* +X98000Y106250D02*X101750D01* +X101000Y110000D02*Y104000D01* +G54D33*G36* +X45000Y110000D02*X49500D01* +Y104000D01* +X45000D01* +Y110000D01* +G37* +G36* +X50400D02*X54900D01* +Y104000D01* +X50400D01* +Y110000D01* +G37* +G36* +X55800D02*X60300D01* +Y104000D01* +X55800D01* +Y110000D01* +G37* +G54D32*X61200Y109250D02*X61950Y110000D01* +X63450D01* +X64200Y109250D01* +X63450Y104000D02*X64200Y104750D01* +X61950Y104000D02*X63450D01* +X61200Y104750D02*X61950Y104000D01* +Y107300D02*X63450D01* +X64200Y109250D02*Y108050D01* +Y106550D02*Y104750D01* +Y106550D02*X63450Y107300D01* +X64200Y108050D02*X63450Y107300D01* +X66750Y104000D02*X69000Y107000D01* +Y109250D02*Y107000D01* +X68250Y110000D02*X69000Y109250D01* +X66750Y110000D02*X68250D01* +X66000Y109250D02*X66750Y110000D01* +X66000Y109250D02*Y107750D01* +X66750Y107000D01* +X69000D01* +X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D33*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D32*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D33*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D32*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D33*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D32*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D33*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D32*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D33*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D32*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D33*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G54D32*X48000Y138800D02*X49200Y140000D01* +Y134000D01* +X48000D02*X50250D01* +G54D33*G36* +X54750Y140000D02*X59250D01* +Y134000D01* +X54750D01* +Y140000D01* +G37* +G36* +X60150D02*X64650D01* +Y134000D01* +X60150D01* +Y140000D01* +G37* +G36* +X65550D02*X70050D01* +Y134000D01* +X65550D01* +Y140000D01* +G37* +G36* +X70950D02*X75450D01* +Y134000D01* +X70950D01* +Y140000D01* +G37* +G36* +X76350D02*X80850D01* +Y134000D01* +X76350D01* +Y140000D01* +G37* +G36* +X81750D02*X86250D01* +Y134000D01* +X81750D01* +Y140000D01* +G37* +G36* +X87150D02*X91650D01* +Y134000D01* +X87150D01* +Y140000D01* +G37* +G36* +X92550D02*X97050D01* +Y134000D01* +X92550D01* +Y140000D01* +G37* +G36* +X97950D02*X102450D01* +Y134000D01* +X97950D01* +Y140000D01* +G37* +G36* +X106050D02*X110550D01* +Y134000D01* +X106050D01* +Y140000D01* +G37* +G36* +X111450D02*X115950D01* +Y134000D01* +X111450D01* +Y140000D01* +G37* +G36* +X116850D02*X121350D01* +Y134000D01* +X116850D01* +Y140000D01* +G37* +G36* +X122250D02*X126750D01* +Y134000D01* +X122250D01* +Y140000D01* +G37* +G36* +X127650D02*X132150D01* +Y134000D01* +X127650D01* +Y140000D01* +G37* +G36* +X135750D02*X140250D01* +Y134000D01* +X135750D01* +Y140000D01* +G37* +G36* +X141150D02*X145650D01* +Y134000D01* +X141150D01* +Y140000D01* +G37* +G36* +X146550D02*X151050D01* +Y134000D01* +X146550D01* +Y140000D01* +G37* +G36* +X151950D02*X156450D01* +Y134000D01* +X151950D01* +Y140000D01* +G37* +G36* +X157350D02*X161850D01* +Y134000D01* +X157350D01* +Y140000D01* +G37* +G36* +X165450D02*X169950D01* +Y134000D01* +X165450D01* +Y140000D01* +G37* +G36* +X170850D02*X175350D01* +Y134000D01* +X170850D01* +Y140000D01* +G37* +G36* +X176250D02*X180750D01* +Y134000D01* +X176250D01* +Y140000D01* +G37* +G36* +X181650D02*X186150D01* +Y134000D01* +X181650D01* +Y140000D01* +G37* +G36* +X189750D02*X194250D01* +Y134000D01* +X189750D01* +Y140000D01* +G37* +G36* +X195150D02*X199650D01* +Y134000D01* +X195150D01* +Y140000D01* +G37* +G36* +X203250D02*X207750D01* +Y134000D01* +X203250D01* +Y140000D01* +G37* +G36* +X208650D02*X213150D01* +Y134000D01* +X208650D01* +Y140000D01* +G37* +G36* +X214050D02*X218550D01* +Y134000D01* +X214050D01* +Y140000D01* +G37* +G36* +X219450D02*X223950D01* +Y134000D01* +X219450D01* +Y140000D01* +G37* +G36* +X227550D02*X232050D01* +Y134000D01* +X227550D01* +Y140000D01* +G37* +G36* +X232950D02*X237450D01* +Y134000D01* +X232950D01* +Y140000D01* +G37* +G36* +X238350D02*X242850D01* +Y134000D01* +X238350D01* +Y140000D01* +G37* +G36* +X243750D02*X248250D01* +Y134000D01* +X243750D01* +Y140000D01* +G37* +G36* +X249150D02*X253650D01* +Y134000D01* +X249150D01* +Y140000D01* +G37* +G36* +X254550D02*X259050D01* +Y134000D01* +X254550D01* +Y140000D01* +G37* +G36* +X259950D02*X264450D01* +Y134000D01* +X259950D01* +Y140000D01* +G37* +G54D32*X268050Y136250D02*X271050Y140000D01* +X268050Y136250D02*X271800D01* +X271050Y140000D02*Y134000D01* +G54D33*G36* +X276300Y140000D02*X280800D01* +Y134000D01* +X276300D01* +Y140000D01* +G37* +G36* +X281700D02*X286200D01* +Y134000D01* +X281700D01* +Y140000D01* +G37* +G36* +X287100D02*X291600D01* +Y134000D01* +X287100D01* +Y140000D01* +G37* +G36* +X292500D02*X297000D01* +Y134000D01* +X292500D01* +Y140000D01* +G37* +G36* +X297900D02*X302400D01* +Y134000D01* +X297900D01* +Y140000D01* +G37* +G36* +X306000D02*X310500D01* +Y134000D01* +X306000D01* +Y140000D01* +G37* +G36* +X311400D02*X315900D01* +Y134000D01* +X311400D01* +Y140000D01* +G37* +G36* +X316800D02*X321300D01* +Y134000D01* +X316800D01* +Y140000D01* +G37* +G36* +X322200D02*X326700D01* +Y134000D01* +X322200D01* +Y140000D01* +G37* +G36* +X327600D02*X332100D01* +Y134000D01* +X327600D01* +Y140000D01* +G37* +G54D34*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D32*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D33*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D32*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D33*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D32*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D33*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D32*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D33*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D32*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D33*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D32*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D33*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D32*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D33*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D32*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D33*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D32*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D33*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D32*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D33*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D32*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D33*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X256100D02*X260600D01* +Y104000D01* +X256100D01* +Y110000D01* +G37* +G36* +X264200D02*X268700D01* +Y104000D01* +X264200D01* +Y110000D01* +G37* +G36* +X269600D02*X274100D01* +Y104000D01* +X269600D01* +Y110000D01* +G37* +G36* +X275000D02*X279500D01* +Y104000D01* +X275000D01* +Y110000D01* +G37* +G36* +X280400D02*X284900D01* +Y104000D01* +X280400D01* +Y110000D01* +G37* +G36* +X288500D02*X293000D01* +Y104000D01* +X288500D01* +Y110000D01* +G37* +G36* +X293900D02*X298400D01* +Y104000D01* +X293900D01* +Y110000D01* +G37* +G36* +X299300D02*X303800D01* +Y104000D01* +X299300D01* +Y110000D01* +G37* +G36* +X304700D02*X309200D01* +Y104000D01* +X304700D01* +Y110000D01* +G37* +G36* +X310100D02*X314600D01* +Y104000D01* +X310100D01* +Y110000D01* +G37* +G36* +X315500D02*X320000D01* +Y104000D01* +X315500D01* +Y110000D01* +G37* +G36* +X320900D02*X325400D01* +Y104000D01* +X320900D01* +Y110000D01* +G37* +G36* +X329000D02*X333500D01* +Y104000D01* +X329000D01* +Y110000D01* +G37* +G36* +X334400D02*X338900D01* +Y104000D01* +X334400D01* +Y110000D01* +G37* +G36* +X339800D02*X344300D01* +Y104000D01* +X339800D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X356000D02*X360500D01* +Y104000D01* +X356000D01* +Y110000D01* +G37* +G36* +X361400D02*X365900D01* +Y104000D01* +X361400D01* +Y110000D01* +G37* +G36* +X369500D02*X374000D01* +Y104000D01* +X369500D01* +Y110000D01* +G37* +G54D32*X377600D02*Y104000D01* +Y110000D02*X380600D01* +X377600Y107300D02*X379850D01* +G54D33*G36* +X382400Y110000D02*X386900D01* +Y104000D01* +X382400D01* +Y110000D01* +G37* +G36* +X387800D02*X392300D01* +Y104000D01* +X387800D01* +Y110000D01* +G37* +G36* +X393200D02*X397700D01* +Y104000D01* +X393200D01* +Y110000D01* +G37* +G36* +X398600D02*X403100D01* +Y104000D01* +X398600D01* +Y110000D01* +G37* +G36* +X404000D02*X408500D01* +Y104000D01* +X404000D01* +Y110000D01* +G37* +G36* +X409400D02*X413900D01* +Y104000D01* +X409400D01* +Y110000D01* +G37* +G36* +X414800D02*X419300D01* +Y104000D01* +X414800D01* +Y110000D01* +G37* +G36* +X420200D02*X424700D01* +Y104000D01* +X420200D01* +Y110000D01* +G37* +G36* +X425600D02*X430100D01* +Y104000D01* +X425600D01* +Y110000D01* +G37* +G36* +X431000D02*X435500D01* +Y104000D01* +X431000D01* +Y110000D01* +G37* +G54D32*X439850D02*Y104000D01* +X441800Y110000D02*X442850Y108950D01* +Y105050D01* +X441800Y104000D02*X442850Y105050D01* +X439100Y104000D02*X441800D01* +X439100Y110000D02*X441800D01* +G54D33*G36* +X444650D02*X449150D01* +Y104000D01* +X444650D01* +Y110000D01* +G37* +G36* +X450050D02*X454550D01* +Y104000D01* +X450050D01* +Y110000D01* +G37* +G36* +X455450D02*X459950D01* +Y104000D01* +X455450D01* +Y110000D01* +G37* +G36* +X460850D02*X465350D01* +Y104000D01* +X460850D01* +Y110000D01* +G37* +G36* +X466250D02*X470750D01* +Y104000D01* +X466250D01* +Y110000D01* +G37* +G36* +X471650D02*X476150D01* +Y104000D01* +X471650D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,24 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: board with minimal netlist, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD13C,0.0394*% +%ADD12C,0.0800*% +%ADD11C,0.0001*% +G54D11*G36* +X6000Y36500D02*X14000D01* +Y28500D01* +X6000D01* +Y36500D01* +G37* +G54D12*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +G54D13*M02* Index: tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.top.mask.none.2.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.top.mask.none.2.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.top.mask.none.2.gbr (revision 33253) @@ -0,0 +1,23 @@ +G04 start of page 6 for group 2 layer_idx 9 * +G04 Title: board with minimal netlist, top_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_MASK_NONE_2*% +%ADD24C,0.0860*% +%ADD23C,0.0001*% +G54D23*G36* +X5700Y36800D02*X14300D01* +Y28200D01* +X5700D01* +Y36800D01* +G37* +G54D24*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.gbr/netlist.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,28 @@ +G04 start of page 8 for group 1 layer_idx 8 * +G04 Title: board with minimal netlist, top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD28C,0.0070*% +%ADD27C,0.0100*% +G54D27*X5000Y37500D02*Y17500D01* +X45000D02*X5000D01* +X45000D02*Y37500D01* +X5000D02*X20000D01* +X30000D02*X45000D01* +X20000D02*G75*G03X30000Y37500I5000J0D01*G01* +G54D28*X10000Y42500D02*Y39000D01* +X10500Y38500D01* +X11500D01* +X12000Y39000D01* +Y42500D02*Y39000D01* +X13200Y41700D02*X14000Y42500D01* +Y38500D01* +X13200D02*X14700D01* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.nelma.em (revision 33253) @@ -0,0 +1,61 @@ +/* banner */ + */ +/* **** Nets **** */ + +net bar { + objects = { + + } +} +net foo { + objects = { + + } +} + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/netlist.net =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.net (revision 33253) @@ -0,0 +1,16 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB board with minimal netlist +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +317foo U1 -1 D0393PA00X+001000Y+003250X0800Y0800R000 S0 +317bar U1 -4 D0393PA00X+004000Y+003250X0800Y0000R000 S0 +317bar U1 -2 D0393PA00X+001000Y+002250X0800Y0000R000 S0 +317foo U1 -3 D0393PA00X+004000Y+002250X0800Y0000R000 S0 +999 Index: tags/2.3.0/tests/RTT/ref/netlist.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/netlist.png =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/netlist.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/netlist.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.png.text (revision 33253) @@ -0,0 +1,15 @@ +r6630 + +One component U1 + +U1 (4pin dip) +Silk line thickness 12 pix (10) +Inside silk screen corner to Pin1 top corner 6 x 6 pix (5 x 5 mil) +Pin1 96 x 96 pix (80 x 80) +Pin1 hole 47 pix (39.166) in diameter +Pin2 to Pin1 distance 24 pix (20) +Pin2 97 pix (80.833) circle +Pin2 to Pin3 distance 263 pix (219.166) +Pin2 hole 47 pix (39.166) in diameter + + Index: tags/2.3.0/tests/RTT/ref/netlist.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/netlist.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/netlist.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/netlist.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/netlist.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/netlist.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/netlist.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.svg (revision 33253) @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/netlist.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist.xy (revision 33253) @@ -0,0 +1,9 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: board with minimal netlist - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- +U1,"dip(4)","4*300",250.00,275.00,0,top Index: tags/2.3.0/tests/RTT/ref/netlist_ba.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.bom (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: board with minimal netlist and some back-annotation changes - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +1,"dip(4)","4*300",U1 Index: tags/2.3.0/tests/RTT/ref/netlist_ba.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.dsn (revision 33253) @@ -0,0 +1,113 @@ +(pcb board with minimal netlist and some back-annotation changes + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 5 + (place "U1" 2.540000 8.255000 front 0 (PN 0)) + ) + ) + (library + (image 5 + (pin Pstk_shape_7 "1" 0.000000 0.000000) + (pin Pstk_shape_8 "4" 7.620000 0.000000) + (pin Pstk_shape_9 "2" 0.000000 -2.540000) + (pin Pstk_shape_10 "3" 7.620000 -2.540000) + ) + (padstack Pstk_shape_7 + (shape + (polygon "3__top_copper" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "5__Intern" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "7__Intern" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + (polygon "10__bottom_copper" 0 + -1.016000 1.016000 1.016000 1.016000 1.016000 -1.016000 + -1.016000 -1.016000 + ) + ) + (attach off) + ) + (padstack Pstk_shape_8 + (shape + (circle "3__top_copper" 2.032000) + (circle "5__Intern" 2.032000) + (circle "7__Intern" 2.032000) + (circle "10__bottom_copper" 2.032000) + ) + (attach off) + ) + (padstack Pstk_shape_9 + (shape + (circle "3__top_copper" 2.032000) + (circle "5__Intern" 2.032000) + (circle "7__Intern" 2.032000) + (circle "10__bottom_copper" 2.032000) + ) + (attach off) + ) + (padstack Pstk_shape_10 + (shape + (circle "3__top_copper" 2.032000) + (circle "5__Intern" 2.032000) + (circle "7__Intern" 2.032000) + (circle "10__bottom_copper" 2.032000) + ) + (attach off) + ) + ) + (network + (net "bar" + (pins "U1"-"2" "U1"-"4" "U1"-"1") + ) + (net "foo" + (pins "U1"-"3") + ) + (class geda_default "bar" "foo" + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/netlist_ba.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.eps (revision 33253) @@ -0,0 +1,120 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: netlist_ba.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.00000 setlinewidth +1 setlinecap +0.439216 0.439216 0.439216 setrgbcolor +0.06000 0.13500 moveto +0.14000 0.13500 lineto +0.14000 0.21500 lineto +0.06000 0.21500 lineto +fill +0.40000 0.17500 0.04000 c +0.10000 0.27500 0.04000 c +0.40000 0.27500 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.17500 0.01968 c +0.40000 0.17500 0.01968 c +0.10000 0.27500 0.01968 c +0.40000 0.27500 0.01968 c +% Layer group5 group 5 drill 0 mask 0 +0.00000 setlinewidth +0.439216 0.439216 0.439216 setrgbcolor +0.06000 0.13500 moveto +0.14000 0.13500 lineto +0.14000 0.21500 lineto +0.06000 0.21500 lineto +fill +0.40000 0.17500 0.04000 c +0.10000 0.27500 0.04000 c +0.40000 0.27500 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.17500 0.01968 c +0.40000 0.17500 0.01968 c +0.10000 0.27500 0.01968 c +0.40000 0.27500 0.01968 c +% Layer group7 group 7 drill 0 mask 0 +0.00000 setlinewidth +0.439216 0.439216 0.439216 setrgbcolor +0.06000 0.13500 moveto +0.14000 0.13500 lineto +0.14000 0.21500 lineto +0.06000 0.21500 lineto +fill +0.40000 0.17500 0.04000 c +0.10000 0.27500 0.04000 c +0.40000 0.27500 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.17500 0.01968 c +0.40000 0.17500 0.01968 c +0.10000 0.27500 0.01968 c +0.40000 0.27500 0.01968 c +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +0.25098 0.25098 0.25098 setrgbcolor +0.06000 0.13500 moveto +0.14000 0.13500 lineto +0.14000 0.21500 lineto +0.06000 0.21500 lineto +fill +0.40000 0.17500 0.04000 c +0.10000 0.27500 0.04000 c +0.40000 0.27500 0.04000 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.17500 0.01968 c +0.40000 0.17500 0.01968 c +0.10000 0.27500 0.01968 c +0.40000 0.27500 0.01968 c +% Layer topsilk group 1 drill 0 mask 0 +0.01000 setlinewidth +0 0 0 setrgbcolor +0.05000 0.12500 0.05000 0.32500 t +0.45000 0.32500 0.05000 0.32500 t +0.45000 0.32500 0.45000 0.12500 t +0.05000 0.12500 0.20000 0.12500 t +0.30000 0.12500 0.45000 0.12500 t +0.000000 180.000000 -0.05000 0.05000 0.25000 0.12500 0.200000 a +0.00700 setlinewidth +0.10000 0.07500 0.10000 0.11000 t +0.10000 0.11000 0.10500 0.11500 t +0.10500 0.11500 0.11500 0.11500 t +0.11500 0.11500 0.12000 0.11000 t +0.12000 0.07500 0.12000 0.11000 t +0.13200 0.08300 0.14000 0.07500 t +0.14000 0.07500 0.14000 0.11500 t +0.13200 0.11500 0.14700 0.11500 t +% Layer plated-drill group -1 drill 1 mask 0 +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.17500 0.01968 c +0.40000 0.17500 0.01968 c +0.10000 0.27500 0.01968 c +0.40000 0.27500 0.01968 c +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/netlist_ba.exc/netlist_ba.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.exc/netlist_ba.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.exc/netlist_ba.plated.cnc (revision 33253) @@ -0,0 +1,11 @@ +M48 +INCH +T11C0.039 +% +T11 +G05 +X001000Y003250 +X004000Y003250 +X001000Y002250 +X004000Y002250 +M30 Index: tags/2.3.0/tests/RTT/ref/netlist_ba.exc/netlist_ba.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.exc/netlist_ba.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.exc/netlist_ba.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/netlist_ba.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,24 @@ +G04 start of page 5 for group 10 layer_idx 1 * +G04 Title: board with minimal netlist and some back-annotation changes, bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD22C,0.0394*% +%ADD21C,0.0800*% +%ADD20C,0.0001*% +G54D20*G36* +X6000Y36500D02*X14000D01* +Y28500D01* +X6000D01* +Y36500D01* +G37* +G54D21*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +G54D22*M02* Index: tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.bottom.mask.none.11.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.bottom.mask.none.11.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.bottom.mask.none.11.gbr (revision 33253) @@ -0,0 +1,23 @@ +G04 start of page 7 for group 11 layer_idx 10 * +G04 Title: board with minimal netlist and some back-annotation changes, bottom_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_MASK_NONE_11*% +%ADD26C,0.0860*% +%ADD25C,0.0001*% +G54D25*G36* +X5700Y36800D02*X14300D01* +Y28200D01* +X5700D01* +Y36800D01* +G37* +G54D26*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 10 for group 9 layer_idx 6 * +G04 Title: board with minimal netlist and some back-annotation changes, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD30C,0.0100*% +G54D30*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.global.virtual.pdrill.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.global.virtual.pdrill.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.global.virtual.pdrill.none.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 9 for group -1 layer_idx 268435462 * +G04 Title: board with minimal netlist and some back-annotation changes, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_VIRTUAL_PDRILL_NONE*% +%ADD29C,0.0394*% +G54D29*X10000Y32500D03* +X40000D03* +X10000Y22500D03* +X40000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.intern.copper.none.5.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.intern.copper.none.5.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.intern.copper.none.5.gbr (revision 33253) @@ -0,0 +1,24 @@ +G04 start of page 3 for group 5 layer_idx 4 * +G04 Title: board with minimal netlist and some back-annotation changes, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_5*% +%ADD16C,0.0394*% +%ADD15C,0.0800*% +%ADD14C,0.0001*% +G54D14*G36* +X6000Y36500D02*X14000D01* +Y28500D01* +X6000D01* +Y36500D01* +G37* +G54D15*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +G54D16*M02* Index: tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.intern.copper.none.7.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.intern.copper.none.7.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.intern.copper.none.7.gbr (revision 33253) @@ -0,0 +1,24 @@ +G04 start of page 4 for group 7 layer_idx 5 * +G04 Title: board with minimal netlist and some back-annotation changes, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_7*% +%ADD19C,0.0394*% +%ADD18C,0.0800*% +%ADD17C,0.0001*% +G54D17*G36* +X6000Y36500D02*X14000D01* +Y28500D01* +X6000D01* +Y36500D01* +G37* +G54D18*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +G54D19*M02* Index: tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,2037 @@ +G04 start of page 11 for group -1 layer_idx 268435461 * +G04 Title: board with minimal netlist and some back-annotation changes, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD34C,0.0100*% +%ADD33C,0.0001*% +%ADD32C,0.0060*% +%ADD31C,0.0080*% +G54D31*X10000Y32500D02*Y30900D01* +Y32500D02*X11387Y33300D01* +X10000Y32500D02*X8613Y33300D01* +X40000Y32500D02*Y30900D01* +Y32500D02*X41387Y33300D01* +X40000Y32500D02*X38613Y33300D01* +X10000Y22500D02*Y20900D01* +Y22500D02*X11387Y23300D01* +X10000Y22500D02*X8613Y23300D01* +X40000Y22500D02*Y20900D01* +Y22500D02*X41387Y23300D01* +X40000Y22500D02*X38613Y23300D01* +X15000Y106250D02*Y104650D01* +Y106250D02*X16387Y107050D01* +X15000Y106250D02*X13613Y107050D01* +G54D32*X135000Y110000D02*X136500Y107000D01* +X138000Y110000D01* +X136500Y107000D02*Y104000D01* +X139800Y107300D02*X142050D01* +X139800Y104000D02*X142800D01* +X139800Y110000D02*Y104000D01* +Y110000D02*X142800D01* +X147600D02*X148350Y109250D01* +X145350Y110000D02*X147600D01* +X144600Y109250D02*X145350Y110000D01* +X144600Y109250D02*Y107750D01* +X145350Y107000D01* +X147600D01* +X148350Y106250D01* +Y104750D01* +X147600Y104000D02*X148350Y104750D01* +X145350Y104000D02*X147600D01* +X144600Y104750D02*X145350Y104000D01* +X98000Y106250D02*X101000Y110000D01* +X98000Y106250D02*X101750D01* +X101000Y110000D02*Y104000D01* +G54D33*G36* +X45000Y110000D02*X49500D01* +Y104000D01* +X45000D01* +Y110000D01* +G37* +G36* +X50400D02*X54900D01* +Y104000D01* +X50400D01* +Y110000D01* +G37* +G36* +X55800D02*X60300D01* +Y104000D01* +X55800D01* +Y110000D01* +G37* +G54D32*X61200Y109250D02*X61950Y110000D01* +X63450D01* +X64200Y109250D01* +X63450Y104000D02*X64200Y104750D01* +X61950Y104000D02*X63450D01* +X61200Y104750D02*X61950Y104000D01* +Y107300D02*X63450D01* +X64200Y109250D02*Y108050D01* +Y106550D02*Y104750D01* +Y106550D02*X63450Y107300D01* +X64200Y108050D02*X63450Y107300D01* +X66750Y104000D02*X69000Y107000D01* +Y109250D02*Y107000D01* +X68250Y110000D02*X69000Y109250D01* +X66750Y110000D02*X68250D01* +X66000Y109250D02*X66750Y110000D01* +X66000Y109250D02*Y107750D01* +X66750Y107000D01* +X69000D01* +X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D33*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D32*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D33*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D32*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D33*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D32*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D33*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D32*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D33*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D32*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D33*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G54D32*X48000Y138800D02*X49200Y140000D01* +Y134000D01* +X48000D02*X50250D01* +G54D33*G36* +X54750Y140000D02*X59250D01* +Y134000D01* +X54750D01* +Y140000D01* +G37* +G36* +X60150D02*X64650D01* +Y134000D01* +X60150D01* +Y140000D01* +G37* +G36* +X65550D02*X70050D01* +Y134000D01* +X65550D01* +Y140000D01* +G37* +G36* +X70950D02*X75450D01* +Y134000D01* +X70950D01* +Y140000D01* +G37* +G36* +X76350D02*X80850D01* +Y134000D01* +X76350D01* +Y140000D01* +G37* +G36* +X81750D02*X86250D01* +Y134000D01* +X81750D01* +Y140000D01* +G37* +G36* +X87150D02*X91650D01* +Y134000D01* +X87150D01* +Y140000D01* +G37* +G36* +X92550D02*X97050D01* +Y134000D01* +X92550D01* +Y140000D01* +G37* +G36* +X97950D02*X102450D01* +Y134000D01* +X97950D01* +Y140000D01* +G37* +G36* +X106050D02*X110550D01* +Y134000D01* +X106050D01* +Y140000D01* +G37* +G36* +X111450D02*X115950D01* +Y134000D01* +X111450D01* +Y140000D01* +G37* +G36* +X116850D02*X121350D01* +Y134000D01* +X116850D01* +Y140000D01* +G37* +G36* +X122250D02*X126750D01* +Y134000D01* +X122250D01* +Y140000D01* +G37* +G36* +X127650D02*X132150D01* +Y134000D01* +X127650D01* +Y140000D01* +G37* +G36* +X135750D02*X140250D01* +Y134000D01* +X135750D01* +Y140000D01* +G37* +G36* +X141150D02*X145650D01* +Y134000D01* +X141150D01* +Y140000D01* +G37* +G36* +X146550D02*X151050D01* +Y134000D01* +X146550D01* +Y140000D01* +G37* +G36* +X151950D02*X156450D01* +Y134000D01* +X151950D01* +Y140000D01* +G37* +G36* +X157350D02*X161850D01* +Y134000D01* +X157350D01* +Y140000D01* +G37* +G36* +X165450D02*X169950D01* +Y134000D01* +X165450D01* +Y140000D01* +G37* +G36* +X170850D02*X175350D01* +Y134000D01* +X170850D01* +Y140000D01* +G37* +G36* +X176250D02*X180750D01* +Y134000D01* +X176250D01* +Y140000D01* +G37* +G36* +X181650D02*X186150D01* +Y134000D01* +X181650D01* +Y140000D01* +G37* +G36* +X189750D02*X194250D01* +Y134000D01* +X189750D01* +Y140000D01* +G37* +G36* +X195150D02*X199650D01* +Y134000D01* +X195150D01* +Y140000D01* +G37* +G36* +X203250D02*X207750D01* +Y134000D01* +X203250D01* +Y140000D01* +G37* +G36* +X208650D02*X213150D01* +Y134000D01* +X208650D01* +Y140000D01* +G37* +G36* +X214050D02*X218550D01* +Y134000D01* +X214050D01* +Y140000D01* +G37* +G36* +X219450D02*X223950D01* +Y134000D01* +X219450D01* +Y140000D01* +G37* +G36* +X227550D02*X232050D01* +Y134000D01* +X227550D01* +Y140000D01* +G37* +G36* +X232950D02*X237450D01* +Y134000D01* +X232950D01* +Y140000D01* +G37* +G36* +X238350D02*X242850D01* +Y134000D01* +X238350D01* +Y140000D01* +G37* +G36* +X243750D02*X248250D01* +Y134000D01* +X243750D01* +Y140000D01* +G37* +G36* +X249150D02*X253650D01* +Y134000D01* +X249150D01* +Y140000D01* +G37* +G36* +X254550D02*X259050D01* +Y134000D01* +X254550D01* +Y140000D01* +G37* +G36* +X259950D02*X264450D01* +Y134000D01* +X259950D01* +Y140000D01* +G37* +G54D32*X268050Y136250D02*X271050Y140000D01* +X268050Y136250D02*X271800D01* +X271050Y140000D02*Y134000D01* +G54D33*G36* +X276300Y140000D02*X280800D01* +Y134000D01* +X276300D01* +Y140000D01* +G37* +G36* +X281700D02*X286200D01* +Y134000D01* +X281700D01* +Y140000D01* +G37* +G36* +X287100D02*X291600D01* +Y134000D01* +X287100D01* +Y140000D01* +G37* +G36* +X292500D02*X297000D01* +Y134000D01* +X292500D01* +Y140000D01* +G37* +G36* +X297900D02*X302400D01* +Y134000D01* +X297900D01* +Y140000D01* +G37* +G36* +X306000D02*X310500D01* +Y134000D01* +X306000D01* +Y140000D01* +G37* +G36* +X311400D02*X315900D01* +Y134000D01* +X311400D01* +Y140000D01* +G37* +G36* +X316800D02*X321300D01* +Y134000D01* +X316800D01* +Y140000D01* +G37* +G36* +X322200D02*X326700D01* +Y134000D01* +X322200D01* +Y140000D01* +G37* +G36* +X327600D02*X332100D01* +Y134000D01* +X327600D01* +Y140000D01* +G37* +G54D34*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D32*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D33*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D32*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D33*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D32*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D33*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D32*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D33*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D32*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D33*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D32*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D33*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D32*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D33*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D32*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D33*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D32*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D33*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D32*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D33*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D32*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D33*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X256100D02*X260600D01* +Y104000D01* +X256100D01* +Y110000D01* +G37* +G36* +X264200D02*X268700D01* +Y104000D01* +X264200D01* +Y110000D01* +G37* +G36* +X269600D02*X274100D01* +Y104000D01* +X269600D01* +Y110000D01* +G37* +G36* +X275000D02*X279500D01* +Y104000D01* +X275000D01* +Y110000D01* +G37* +G36* +X280400D02*X284900D01* +Y104000D01* +X280400D01* +Y110000D01* +G37* +G36* +X288500D02*X293000D01* +Y104000D01* +X288500D01* +Y110000D01* +G37* +G36* +X293900D02*X298400D01* +Y104000D01* +X293900D01* +Y110000D01* +G37* +G36* +X299300D02*X303800D01* +Y104000D01* +X299300D01* +Y110000D01* +G37* +G36* +X304700D02*X309200D01* +Y104000D01* +X304700D01* +Y110000D01* +G37* +G36* +X310100D02*X314600D01* +Y104000D01* +X310100D01* +Y110000D01* +G37* +G36* +X315500D02*X320000D01* +Y104000D01* +X315500D01* +Y110000D01* +G37* +G36* +X320900D02*X325400D01* +Y104000D01* +X320900D01* +Y110000D01* +G37* +G36* +X329000D02*X333500D01* +Y104000D01* +X329000D01* +Y110000D01* +G37* +G36* +X334400D02*X338900D01* +Y104000D01* +X334400D01* +Y110000D01* +G37* +G36* +X339800D02*X344300D01* +Y104000D01* +X339800D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X356000D02*X360500D01* +Y104000D01* +X356000D01* +Y110000D01* +G37* +G36* +X361400D02*X365900D01* +Y104000D01* +X361400D01* +Y110000D01* +G37* +G36* +X369500D02*X374000D01* +Y104000D01* +X369500D01* +Y110000D01* +G37* +G36* +X374900D02*X379400D01* +Y104000D01* +X374900D01* +Y110000D01* +G37* +G36* +X380300D02*X384800D01* +Y104000D01* +X380300D01* +Y110000D01* +G37* +G36* +X388400D02*X392900D01* +Y104000D01* +X388400D01* +Y110000D01* +G37* +G36* +X393800D02*X398300D01* +Y104000D01* +X393800D01* +Y110000D01* +G37* +G36* +X399200D02*X403700D01* +Y104000D01* +X399200D01* +Y110000D01* +G37* +G36* +X404600D02*X409100D01* +Y104000D01* +X404600D01* +Y110000D01* +G37* +G36* +X412700D02*X417200D01* +Y104000D01* +X412700D01* +Y110000D01* +G37* +G36* +X418100D02*X422600D01* +Y104000D01* +X418100D01* +Y110000D01* +G37* +G36* +X423500D02*X428000D01* +Y104000D01* +X423500D01* +Y110000D01* +G37* +G36* +X428900D02*X433400D01* +Y104000D01* +X428900D01* +Y110000D01* +G37* +G36* +X434300D02*X438800D01* +Y104000D01* +X434300D01* +Y110000D01* +G37* +G36* +X439700D02*X444200D01* +Y104000D01* +X439700D01* +Y110000D01* +G37* +G36* +X445100D02*X449600D01* +Y104000D01* +X445100D01* +Y110000D01* +G37* +G36* +X450500D02*X455000D01* +Y104000D01* +X450500D01* +Y110000D01* +G37* +G36* +X455900D02*X460400D01* +Y104000D01* +X455900D01* +Y110000D01* +G37* +G36* +X461300D02*X465800D01* +Y104000D01* +X461300D01* +Y110000D01* +G37* +G36* +X466700D02*X471200D01* +Y104000D01* +X466700D01* +Y110000D01* +G37* +G36* +X472100D02*X476600D01* +Y104000D01* +X472100D01* +Y110000D01* +G37* +G36* +X477500D02*X482000D01* +Y104000D01* +X477500D01* +Y110000D01* +G37* +G36* +X482900D02*X487400D01* +Y104000D01* +X482900D01* +Y110000D01* +G37* +G36* +X488300D02*X492800D01* +Y104000D01* +X488300D01* +Y110000D01* +G37* +G36* +X496400D02*X500900D01* +Y104000D01* +X496400D01* +Y110000D01* +G37* +G36* +X501800D02*X506300D01* +Y104000D01* +X501800D01* +Y110000D01* +G37* +G36* +X507200D02*X511700D01* +Y104000D01* +X507200D01* +Y110000D01* +G37* +G36* +X512600D02*X517100D01* +Y104000D01* +X512600D01* +Y110000D01* +G37* +G36* +X518000D02*X522500D01* +Y104000D01* +X518000D01* +Y110000D01* +G37* +G36* +X523400D02*X527900D01* +Y104000D01* +X523400D01* +Y110000D01* +G37* +G36* +X528800D02*X533300D01* +Y104000D01* +X528800D01* +Y110000D01* +G37* +G36* +X536900D02*X541400D01* +Y104000D01* +X536900D01* +Y110000D01* +G37* +G54D32*X545000D02*Y104000D01* +Y110000D02*X548000D01* +X545000Y107300D02*X547250D01* +G54D33*G36* +X549800Y110000D02*X554300D01* +Y104000D01* +X549800D01* +Y110000D01* +G37* +G36* +X555200D02*X559700D01* +Y104000D01* +X555200D01* +Y110000D01* +G37* +G36* +X560600D02*X565100D01* +Y104000D01* +X560600D01* +Y110000D01* +G37* +G36* +X566000D02*X570500D01* +Y104000D01* +X566000D01* +Y110000D01* +G37* +G36* +X571400D02*X575900D01* +Y104000D01* +X571400D01* +Y110000D01* +G37* +G36* +X576800D02*X581300D01* +Y104000D01* +X576800D01* +Y110000D01* +G37* +G36* +X582200D02*X586700D01* +Y104000D01* +X582200D01* +Y110000D01* +G37* +G36* +X587600D02*X592100D01* +Y104000D01* +X587600D01* +Y110000D01* +G37* +G36* +X593000D02*X597500D01* +Y104000D01* +X593000D01* +Y110000D01* +G37* +G36* +X598400D02*X602900D01* +Y104000D01* +X598400D01* +Y110000D01* +G37* +G54D32*X607250D02*Y104000D01* +X609200Y110000D02*X610250Y108950D01* +Y105050D01* +X609200Y104000D02*X610250Y105050D01* +X606500Y104000D02*X609200D01* +X606500Y110000D02*X609200D01* +G54D33*G36* +X612050D02*X616550D01* +Y104000D01* +X612050D01* +Y110000D01* +G37* +G36* +X617450D02*X621950D01* +Y104000D01* +X617450D01* +Y110000D01* +G37* +G36* +X622850D02*X627350D01* +Y104000D01* +X622850D01* +Y110000D01* +G37* +G36* +X628250D02*X632750D01* +Y104000D01* +X628250D01* +Y110000D01* +G37* +G36* +X633650D02*X638150D01* +Y104000D01* +X633650D01* +Y110000D01* +G37* +G36* +X639050D02*X643550D01* +Y104000D01* +X639050D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,24 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: board with minimal netlist and some back-annotation changes, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD13C,0.0394*% +%ADD12C,0.0800*% +%ADD11C,0.0001*% +G54D11*G36* +X6000Y36500D02*X14000D01* +Y28500D01* +X6000D01* +Y36500D01* +G37* +G54D12*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +G54D13*M02* Index: tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.top.mask.none.2.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.top.mask.none.2.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.top.mask.none.2.gbr (revision 33253) @@ -0,0 +1,23 @@ +G04 start of page 6 for group 2 layer_idx 9 * +G04 Title: board with minimal netlist and some back-annotation changes, top_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_MASK_NONE_2*% +%ADD24C,0.0860*% +%ADD23C,0.0001*% +G54D23*G36* +X5700Y36800D02*X14300D01* +Y28200D01* +X5700D01* +Y36800D01* +G37* +G54D24*X40000Y32500D03* +X10000Y22500D03* +X40000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.gbr/netlist_ba.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,28 @@ +G04 start of page 8 for group 1 layer_idx 8 * +G04 Title: board with minimal netlist and some back-annotation changes, top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD28C,0.0070*% +%ADD27C,0.0100*% +G54D27*X5000Y37500D02*Y17500D01* +X45000D02*X5000D01* +X45000D02*Y37500D01* +X5000D02*X20000D01* +X30000D02*X45000D01* +X20000D02*G75*G03X30000Y37500I5000J0D01*G01* +G54D28*X10000Y42500D02*Y39000D01* +X10500Y38500D01* +X11500D01* +X12000Y39000D01* +Y42500D02*Y39000D01* +X13200Y41700D02*X14000Y42500D01* +Y38500D01* +X13200D02*X14700D01* +M02* Index: tags/2.3.0/tests/RTT/ref/netlist_ba.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.nelma.em (revision 33253) @@ -0,0 +1,61 @@ +/* banner */ + */ +/* **** Nets **** */ + +net bar { + objects = { + + } +} +net foo { + objects = { + + } +} + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/netlist_ba.net =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.net (revision 33253) @@ -0,0 +1,16 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB board with minimal netlist and some back-annotation changes +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +317bar U1 -1 D0393PA00X+001000Y+003250X0800Y0800R000 S0 +317bar U1 -4 D0393PA00X+004000Y+003250X0800Y0000R000 S0 +317bar U1 -2 D0393PA00X+001000Y+002250X0800Y0000R000 S0 +317foo U1 -3 D0393PA00X+004000Y+002250X0800Y0000R000 S0 +999 Index: tags/2.3.0/tests/RTT/ref/netlist_ba.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/netlist_ba.png =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/netlist_ba.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/netlist_ba.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.png.text (revision 33253) @@ -0,0 +1,15 @@ +r6630 + +One component U1 + +U1 (4pin dip) +Silk line thickness 12 pix (10) +Inside silk screen corner to Pin1 top corner 6 x 6 pix (5 x 5 mil) +Pin1 96 x 96 pix (80 x 80) +Pin1 hole 47 pix (39.166) in diameter +Pin2 to Pin1 distance 24 pix (20) +Pin2 97 pix (80.833) circle +Pin2 to Pin3 distance 263 pix (219.166) +Pin2 hole 47 pix (39.166) in diameter + + Index: tags/2.3.0/tests/RTT/ref/netlist_ba.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/netlist_ba.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/netlist_ba.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/netlist_ba.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/netlist_ba.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/netlist_ba.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/netlist_ba.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.svg (revision 33253) @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/netlist_ba.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/netlist_ba.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/netlist_ba.xy (revision 33253) @@ -0,0 +1,9 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: board with minimal netlist and some back-annotation changes - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- +U1,"dip(4)","4*300",250.00,275.00,0,top Index: tags/2.3.0/tests/RTT/ref/padrot.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.bom (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Rotated round cap and square pads - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +8,"(unknown)","(unknown)",R1 R3 R2 R6 R4 R5 R7 R8 Index: tags/2.3.0/tests/RTT/ref/padrot.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.dsn (revision 33253) @@ -0,0 +1,170 @@ +(pcb Rotated round cap and square pads + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 5 + (place "R1" 1.270000 11.430000 front 0 (PN 0)) + ) + (component 32 + (place "R3" 1.270000 7.620000 front 0 (PN 0)) + ) + (component 59 + (place "R2" 5.080000 11.430000 front 0 (PN 0)) + ) + (component 86 + (place "R6" 1.270000 5.715000 front 0 (PN 0)) + ) + (component 113 + (place "R4" 3.175000 8.890000 front 0 (PN 0)) + ) + (component 140 + (place "R5" 5.715000 8.890000 front 0 (PN 0)) + ) + (component 167 + (place "R7" 3.175000 5.080000 front 0 (PN 0)) + ) + (component 194 + (place "R8" 6.985000 5.080000 front 0 (PN 0)) + ) + ) + (library + (image 5 + (pin Pstk_shape_7 "1" 0.952500 0.000000) + ) + (image 32 + (pin Pstk_shape_34 "1" 0.000000 0.952500) + ) + (image 59 + (pin Pstk_shape_61 "1" 0.952500 0.000000) + ) + (image 86 + (pin Pstk_shape_88 "1" 0.000000 -0.952500) + ) + (image 113 + (pin Pstk_shape_115 "1" 0.673481 -0.673481) + ) + (image 140 + (pin Pstk_shape_142 "1" 0.673481 -0.673481) + ) + (image 167 + (pin Pstk_shape_169 "1" 0.881761 -0.360172) + ) + (image 194 + (pin Pstk_shape_196 "1" 0.881761 -0.360172) + ) + (padstack Pstk_shape_7 + (shape + (polygon "3__top_copper" 0 + -1.079500 -0.127000 -1.079500 0.127000 1.079500 0.127000 + 1.079500 -0.127000 + ) + ) + (attach off) + ) + (padstack Pstk_shape_34 + (shape + (polygon "3__top_copper" 0 + -0.127000 1.079500 0.127000 1.079500 0.127000 -1.079500 + -0.127000 -1.079500 + ) + ) + (attach off) + ) + (padstack Pstk_shape_61 + (shape + (polygon "3__top_copper" 0 + -1.079499 0.126999 -1.079499 -0.126999 1.079499 -0.126999 + 1.079499 0.126999 + ) + ) + (attach off) + ) + (padstack Pstk_shape_88 + (shape + (polygon "3__top_copper" 0 + 0.126999 1.079499 -0.126999 1.079499 -0.126999 -1.079499 + 0.126999 -1.079499 + ) + ) + (attach off) + ) + (padstack Pstk_shape_115 + (shape + (polygon "3__top_copper" 0 + -0.853086 0.673481 -0.673481 0.853086 0.853086 -0.673481 + 0.673481 -0.853086 + ) + ) + (attach off) + ) + (padstack Pstk_shape_142 + (shape + (polygon "3__top_copper" 0 + -0.673481 0.853085 -0.853085 0.673481 0.673481 -0.853085 + 0.853085 -0.673481 + ) + ) + (attach off) + ) + (padstack Pstk_shape_169 + (shape + (polygon "3__top_copper" 0 + -1.047355 0.290626 -0.951307 0.525766 1.047355 -0.290626 + 0.951307 -0.525766 + ) + ) + (attach off) + ) + (padstack Pstk_shape_196 + (shape + (polygon "3__top_copper" 0 + -0.951308 0.525765 -1.047354 0.290625 0.951308 -0.525765 + 1.047354 -0.290625 + ) + ) + (attach off) + ) + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/padrot.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.eps (revision 33253) @@ -0,0 +1,208 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: padrot.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.01000 setlinewidth +1 setlinecap +0.25098 0.25098 0.25098 setrgbcolor +0.05000 0.05000 0.12500 0.05000 t +0.05000 0.12500 0.05000 0.20000 t +0.19500 0.04500 moveto +0.19500 0.05500 lineto +0.28000 0.05500 lineto +0.28000 0.04500 lineto +fill +0.05500 0.27000 moveto +0.04500 0.27000 lineto +0.04500 0.35500 lineto +0.05500 0.35500 lineto +fill +0.12500 0.15000 0.17803 0.20303 t +0.22500 0.14293 moveto +0.21793 0.15000 lineto +0.27803 0.21010 lineto +0.28510 0.20303 lineto +fill +0.12500 0.30000 0.19443 0.32836 t +0.27226 0.29348 moveto +0.26848 0.30274 lineto +0.34717 0.33488 lineto +0.35095 0.32562 lineto +fill +% Layer topsilk group 1 drill 0 mask 0 +0.00500 setlinewidth +0 0 0 setrgbcolor +0.02500 0.07500 0.15000 0.07500 t +0.15000 0.07500 0.15000 0.02500 t +0.15000 0.02500 0.02500 0.02500 t +0.02500 0.07500 0.02500 0.02500 t +0.07500 0.10000 0.07500 0.22500 t +0.02500 0.10000 0.07500 0.10000 t +0.02500 0.10000 0.02500 0.22500 t +0.02500 0.22500 0.07500 0.22500 t +0.02500 0.25000 0.02500 0.37500 t +0.02500 0.37500 0.07500 0.37500 t +0.07500 0.25000 0.07500 0.37500 t +0.02500 0.25000 0.07500 0.25000 t +0.17500 0.07500 0.30000 0.07500 t +0.30000 0.02500 0.30000 0.07500 t +0.17500 0.02500 0.30000 0.02500 t +0.17500 0.02500 0.17500 0.07500 t +0.12500 0.11464 0.21339 0.20303 t +0.08964 0.15000 0.12500 0.11464 t +0.08964 0.15000 0.17803 0.23839 t +0.17803 0.23839 0.21339 0.20303 t +0.18964 0.15000 0.27803 0.23839 t +0.27803 0.23839 0.31339 0.20303 t +0.22500 0.11464 0.31339 0.20303 t +0.18964 0.15000 0.22500 0.11464 t +0.09240 0.31369 0.20812 0.36096 t +0.11131 0.26740 0.22703 0.31467 t +0.09240 0.31369 0.11131 0.26740 t +0.20812 0.36096 0.22703 0.31467 t +0.24240 0.31369 0.35812 0.36096 t +0.35812 0.36096 0.37703 0.31467 t +0.26131 0.26740 0.37703 0.31467 t +0.24240 0.31369 0.26131 0.26740 t +0.00700 setlinewidth +0.01500 0.01500 0.02600 0.01500 t +0.02600 0.01500 0.02875 0.01775 t +0.02875 0.01775 0.02875 0.02325 t +0.02600 0.02600 0.02875 0.02325 t +0.01775 0.02600 0.02600 0.02600 t +0.01775 0.01500 0.01775 0.03700 t +0.02215 0.02600 0.02875 0.03700 t +0.03535 0.01940 0.03975 0.01500 t +0.03975 0.01500 0.03975 0.03700 t +0.03535 0.03700 0.04360 0.03700 t +0.08000 0.23250 0.08000 0.21950 t +0.08000 0.21950 0.08325 0.21625 t +0.08325 0.21625 0.08975 0.21625 t +0.09300 0.21950 0.08975 0.21625 t +0.09300 0.22925 0.09300 0.21950 t +0.08000 0.22925 0.10600 0.22925 t +0.09300 0.22405 0.10600 0.21625 t +0.08325 0.20845 0.08000 0.20520 t +0.08000 0.20520 0.08000 0.19870 t +0.08000 0.19870 0.08325 0.19545 t +0.10600 0.19870 0.10275 0.19545 t +0.10600 0.20520 0.10600 0.19870 t +0.10275 0.20845 0.10600 0.20520 t +0.09170 0.20520 0.09170 0.19870 t +0.08325 0.19545 0.08845 0.19545 t +0.09495 0.19545 0.10275 0.19545 t +0.09495 0.19545 0.09170 0.19870 t +0.08845 0.19545 0.09170 0.19870 t +0.14000 0.14500 0.14000 0.13300 t +0.14000 0.13300 0.14300 0.13000 t +0.14300 0.13000 0.14900 0.13000 t +0.15200 0.13300 0.14900 0.13000 t +0.15200 0.14200 0.15200 0.13300 t +0.14000 0.14200 0.16400 0.14200 t +0.15200 0.13720 0.16400 0.13000 t +0.15500 0.12280 0.14000 0.11080 t +0.15500 0.12280 0.15500 0.10780 t +0.14000 0.11080 0.16400 0.11080 t +0.31250 0.02500 0.33250 0.02500 t +0.33250 0.02500 0.33750 0.03000 t +0.33750 0.03000 0.33750 0.04000 t +0.33250 0.04500 0.33750 0.04000 t +0.31750 0.04500 0.33250 0.04500 t +0.31750 0.02500 0.31750 0.06500 t +0.32550 0.04500 0.33750 0.06500 t +0.34950 0.03000 0.35450 0.02500 t +0.35450 0.02500 0.36950 0.02500 t +0.36950 0.02500 0.37450 0.03000 t +0.37450 0.03000 0.37450 0.04000 t +0.34950 0.06500 0.37450 0.04000 t +0.34950 0.06500 0.37450 0.06500 t +0.07000 0.39000 0.07000 0.41000 t +0.07000 0.41000 0.06500 0.41500 t +0.06500 0.41500 0.05500 0.41500 t +0.05000 0.41000 0.05500 0.41500 t +0.05000 0.39500 0.05000 0.41000 t +0.07000 0.39500 0.03000 0.39500 t +0.05000 0.40300 0.03000 0.41500 t +0.07000 0.44200 0.06500 0.44700 t +0.07000 0.43200 0.07000 0.44200 t +0.06500 0.42700 0.07000 0.43200 t +0.06500 0.42700 0.03500 0.42700 t +0.03500 0.42700 0.03000 0.43200 t +0.05200 0.44200 0.04700 0.44700 t +0.05200 0.42700 0.05200 0.44200 t +0.03000 0.43200 0.03000 0.44200 t +0.03000 0.44200 0.03500 0.44700 t +0.04700 0.44700 0.03500 0.44700 t +0.35500 0.13500 0.35500 0.15500 t +0.35500 0.15500 0.35000 0.16000 t +0.35000 0.16000 0.34000 0.16000 t +0.33500 0.15500 0.34000 0.16000 t +0.33500 0.14000 0.33500 0.15500 t +0.35500 0.14000 0.31500 0.14000 t +0.33500 0.14800 0.31500 0.16000 t +0.35500 0.17200 0.35500 0.19200 t +0.35500 0.17200 0.33500 0.17200 t +0.33500 0.17200 0.34000 0.17700 t +0.34000 0.17700 0.34000 0.18700 t +0.34000 0.18700 0.33500 0.19200 t +0.33500 0.19200 0.32000 0.19200 t +0.31500 0.18700 0.32000 0.19200 t +0.31500 0.17700 0.31500 0.18700 t +0.32000 0.17200 0.31500 0.17700 t +0.19500 0.36500 0.19500 0.38500 t +0.19500 0.38500 0.19000 0.39000 t +0.19000 0.39000 0.18000 0.39000 t +0.17500 0.38500 0.18000 0.39000 t +0.17500 0.37000 0.17500 0.38500 t +0.19500 0.37000 0.15500 0.37000 t +0.17500 0.37800 0.15500 0.39000 t +0.15500 0.40700 0.19500 0.42700 t +0.19500 0.40200 0.19500 0.42700 t +0.33500 0.37500 0.33500 0.39500 t +0.33500 0.39500 0.33000 0.40000 t +0.33000 0.40000 0.32000 0.40000 t +0.31500 0.39500 0.32000 0.40000 t +0.31500 0.38000 0.31500 0.39500 t +0.33500 0.38000 0.29500 0.38000 t +0.31500 0.38800 0.29500 0.40000 t +0.30000 0.41200 0.29500 0.41700 t +0.30800 0.41200 0.30000 0.41200 t +0.30800 0.41200 0.31500 0.41900 t +0.31500 0.41900 0.31500 0.42500 t +0.31500 0.42500 0.30800 0.43200 t +0.30800 0.43200 0.30000 0.43200 t +0.29500 0.42700 0.30000 0.43200 t +0.29500 0.41700 0.29500 0.42700 t +0.32200 0.41200 0.31500 0.41900 t +0.33000 0.41200 0.32200 0.41200 t +0.33000 0.41200 0.33500 0.41700 t +0.33500 0.41700 0.33500 0.42700 t +0.33500 0.42700 0.33000 0.43200 t +0.33000 0.43200 0.32200 0.43200 t +0.31500 0.42500 0.32200 0.43200 t +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/padrot.exc/padrot.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.exc/padrot.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.exc/padrot.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/padrot.exc/padrot.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.exc/padrot.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.exc/padrot.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/padrot.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.fcd (revision 33253) @@ -0,0 +1 @@ +[FIDOCAD] Index: tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 6 for group 9 layer_idx 6 * +G04 Title: Rotated round cap and square pads, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD19C,0.0100*% +G54D19*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1826 @@ +G04 start of page 7 for group -1 layer_idx 268435461 * +G04 Title: Rotated round cap and square pads, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD22C,0.0100*% +%ADD21C,0.0001*% +%ADD20C,0.0060*% +G54D20*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D21*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D20*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D21*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D20*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D21*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D20*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D21*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D20*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D21*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D20*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D21*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D22*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D20*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D21*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D20*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D21*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D20*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D21*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D20*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D21*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D20*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D21*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D20*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D21*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D20*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D21*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D20*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D21*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D20*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D21*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D20*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D21*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D20*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D21*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D20*X234500D02*X237500D01* +X238250Y109250D01* +Y107750D01* +X237500Y107000D02*X238250Y107750D01* +X235250Y107000D02*X237500D01* +X235250Y110000D02*Y104000D01* +X236450Y107000D02*X238250Y104000D01* +G54D21*G36* +X240050Y110000D02*X244550D01* +Y104000D01* +X240050D01* +Y110000D01* +G37* +G36* +X245450D02*X249950D01* +Y104000D01* +X245450D01* +Y110000D01* +G37* +G36* +X250850D02*X255350D01* +Y104000D01* +X250850D01* +Y110000D01* +G37* +G36* +X256250D02*X260750D01* +Y104000D01* +X256250D01* +Y110000D01* +G37* +G36* +X261650D02*X266150D01* +Y104000D01* +X261650D01* +Y110000D01* +G37* +G36* +X267050D02*X271550D01* +Y104000D01* +X267050D01* +Y110000D01* +G37* +G36* +X275150D02*X279650D01* +Y104000D01* +X275150D01* +Y110000D01* +G37* +G36* +X280550D02*X285050D01* +Y104000D01* +X280550D01* +Y110000D01* +G37* +G36* +X285950D02*X290450D01* +Y104000D01* +X285950D01* +Y110000D01* +G37* +G36* +X291350D02*X295850D01* +Y104000D01* +X291350D01* +Y110000D01* +G37* +G36* +X296750D02*X301250D01* +Y104000D01* +X296750D01* +Y110000D01* +G37* +G36* +X304850D02*X309350D01* +Y104000D01* +X304850D01* +Y110000D01* +G37* +G36* +X310250D02*X314750D01* +Y104000D01* +X310250D01* +Y110000D01* +G37* +G36* +X315650D02*X320150D01* +Y104000D01* +X315650D01* +Y110000D01* +G37* +G36* +X323750D02*X328250D01* +Y104000D01* +X323750D01* +Y110000D01* +G37* +G36* +X329150D02*X333650D01* +Y104000D01* +X329150D01* +Y110000D01* +G37* +G36* +X334550D02*X339050D01* +Y104000D01* +X334550D01* +Y110000D01* +G37* +G36* +X342650D02*X347150D01* +Y104000D01* +X342650D01* +Y110000D01* +G37* +G36* +X348050D02*X352550D01* +Y104000D01* +X348050D01* +Y110000D01* +G37* +G36* +X353450D02*X357950D01* +Y104000D01* +X353450D01* +Y110000D01* +G37* +G36* +X358850D02*X363350D01* +Y104000D01* +X358850D01* +Y110000D01* +G37* +G36* +X364250D02*X368750D01* +Y104000D01* +X364250D01* +Y110000D01* +G37* +G36* +X369650D02*X374150D01* +Y104000D01* +X369650D01* +Y110000D01* +G37* +G36* +X377750D02*X382250D01* +Y104000D01* +X377750D01* +Y110000D01* +G37* +G36* +X383150D02*X387650D01* +Y104000D01* +X383150D01* +Y110000D01* +G37* +G36* +X388550D02*X393050D01* +Y104000D01* +X388550D01* +Y110000D01* +G37* +G36* +X393950D02*X398450D01* +Y104000D01* +X393950D01* +Y110000D01* +G37* +G36* +X402050D02*X406550D01* +Y104000D01* +X402050D01* +Y110000D01* +G37* +G54D20*X410150D02*Y104000D01* +Y110000D02*X413150D01* +X410150Y107300D02*X412400D01* +G54D21*G36* +X414950Y110000D02*X419450D01* +Y104000D01* +X414950D01* +Y110000D01* +G37* +G36* +X420350D02*X424850D01* +Y104000D01* +X420350D01* +Y110000D01* +G37* +G36* +X425750D02*X430250D01* +Y104000D01* +X425750D01* +Y110000D01* +G37* +G36* +X431150D02*X435650D01* +Y104000D01* +X431150D01* +Y110000D01* +G37* +G36* +X436550D02*X441050D01* +Y104000D01* +X436550D01* +Y110000D01* +G37* +G36* +X441950D02*X446450D01* +Y104000D01* +X441950D01* +Y110000D01* +G37* +G36* +X447350D02*X451850D01* +Y104000D01* +X447350D01* +Y110000D01* +G37* +G36* +X452750D02*X457250D01* +Y104000D01* +X452750D01* +Y110000D01* +G37* +G36* +X458150D02*X462650D01* +Y104000D01* +X458150D01* +Y110000D01* +G37* +G36* +X463550D02*X468050D01* +Y104000D01* +X463550D01* +Y110000D01* +G37* +G54D20*X472400D02*Y104000D01* +X474350Y110000D02*X475400Y108950D01* +Y105050D01* +X474350Y104000D02*X475400Y105050D01* +X471650Y104000D02*X474350D01* +X471650Y110000D02*X474350D01* +G54D21*G36* +X477200D02*X481700D01* +Y104000D01* +X477200D01* +Y110000D01* +G37* +G36* +X482600D02*X487100D01* +Y104000D01* +X482600D01* +Y110000D01* +G37* +G36* +X488000D02*X492500D01* +Y104000D01* +X488000D01* +Y110000D01* +G37* +G36* +X493400D02*X497900D01* +Y104000D01* +X493400D01* +Y110000D01* +G37* +G36* +X498800D02*X503300D01* +Y104000D01* +X498800D01* +Y110000D01* +G37* +G36* +X504200D02*X508700D01* +Y104000D01* +X504200D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,42 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Rotated round cap and square pads, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD12C,0.0001*% +%ADD11C,0.0100*% +G54D11*X5000Y45000D02*X12500D01* +X5000Y37500D02*Y30000D01* +G54D12*G36* +X19500Y45500D02*Y44500D01* +X28000D01* +Y45500D01* +X19500D01* +G37* +G36* +X5500Y23000D02*X4500D01* +Y14500D01* +X5500D01* +Y23000D01* +G37* +G54D11*X12500Y35000D02*X17803Y29697D01* +G54D12*G36* +X22500Y35707D02*X21793Y35000D01* +X27803Y28990D01* +X28510Y29697D01* +X22500Y35707D01* +G37* +G54D11*X12500Y20000D02*X19443Y17164D01* +G54D12*G36* +X27226Y20652D02*X26848Y19726D01* +X34717Y16512D01* +X35095Y17438D01* +X27226Y20652D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.mask.none.2.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.mask.none.2.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.mask.none.2.gbr (revision 33253) @@ -0,0 +1,42 @@ +G04 start of page 3 for group 2 layer_idx 9 * +G04 Title: Rotated round cap and square pads, top_mask * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_MASK_NONE_2*% +%ADD14C,0.0001*% +%ADD13C,0.0500*% +G54D13*X5000Y45000D02*X12500D01* +X5000Y37500D02*Y30000D01* +G54D14*G36* +X17500Y47500D02*Y42500D01* +X30000D01* +Y47500D01* +X17500D01* +G37* +G36* +X7500Y25000D02*X2500D01* +Y12500D01* +X7500D01* +Y25000D01* +G37* +G54D13*X12500Y35000D02*X17803Y29697D01* +G54D14*G36* +X22500Y38536D02*X18964Y35000D01* +X27803Y26161D01* +X31339Y29697D01* +X22500Y38536D01* +G37* +G54D13*X12500Y20000D02*X19443Y17164D01* +G54D14*G36* +X26131Y23260D02*X24240Y18631D01* +X35812Y13904D01* +X37703Y18533D01* +X26131Y23260D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.paste.none.0.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.paste.none.0.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.paste.none.0.gbr (revision 33253) @@ -0,0 +1,42 @@ +G04 start of page 5 for group 0 layer_idx 11 * +G04 Title: Rotated round cap and square pads, top_paste * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_PASTE_NONE_0*% +%ADD18C,0.0001*% +%ADD17C,0.0100*% +G54D17*X5000Y45000D02*X12500D01* +X5000Y37500D02*Y30000D01* +G54D18*G36* +X19500Y45500D02*Y44500D01* +X28000D01* +Y45500D01* +X19500D01* +G37* +G36* +X5500Y23000D02*X4500D01* +Y14500D01* +X5500D01* +Y23000D01* +G37* +G54D17*X12500Y35000D02*X17803Y29697D01* +G54D18*G36* +X22500Y35707D02*X21793Y35000D01* +X27803Y28990D01* +X28510Y29697D01* +X22500Y35707D01* +G37* +G54D17*X12500Y20000D02*X19443Y17164D01* +G54D18*G36* +X27226Y20652D02*X26848Y19726D01* +X34717Y16512D01* +X35095Y17438D01* +X27226Y20652D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.gbr/padrot.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,161 @@ +G04 start of page 4 for group 1 layer_idx 8 * +G04 Title: Rotated round cap and square pads, top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD16C,0.0070*% +%ADD15C,0.0050*% +G54D15*X2500Y42500D02*X15000D01* +Y47500D01* +X2500D01* +Y42500D02*Y47500D01* +X7500Y40000D02*Y27500D01* +X2500Y40000D02*X7500D01* +X2500D02*Y27500D01* +X7500D01* +X2500Y25000D02*Y12500D01* +X7500D01* +Y25000D02*Y12500D01* +X2500Y25000D02*X7500D01* +X17500Y42500D02*X30000D01* +Y47500D02*Y42500D01* +X17500Y47500D02*X30000D01* +X17500D02*Y42500D01* +X12500Y38536D02*X21339Y29697D01* +X8964Y35000D02*X12500Y38536D01* +X8964Y35000D02*X17803Y26161D01* +X21339Y29697D01* +X18964Y35000D02*X27803Y26161D01* +X31339Y29697D01* +X22500Y38536D02*X31339Y29697D01* +X18964Y35000D02*X22500Y38536D01* +X9240Y18631D02*X20812Y13904D01* +X11131Y23260D02*X22703Y18533D01* +X9240Y18631D02*X11131Y23260D01* +X20812Y13904D02*X22703Y18533D01* +X24240Y18631D02*X35812Y13904D01* +X37703Y18533D01* +X26131Y23260D02*X37703Y18533D01* +X24240Y18631D02*X26131Y23260D01* +G54D16*X1500Y48500D02*X2600D01* +X2875Y48225D01* +Y47675D01* +X2600Y47400D02*X2875Y47675D01* +X1775Y47400D02*X2600D01* +X1775Y48500D02*Y46300D01* +X2215Y47400D02*X2875Y46300D01* +X3535Y48060D02*X3975Y48500D01* +Y46300D01* +X3535D02*X4360D01* +X8000Y26750D02*Y28050D01* +X8325Y28375D01* +X8975D01* +X9300Y28050D02*X8975Y28375D01* +X9300Y27075D02*Y28050D01* +X8000Y27075D02*X10600D01* +X9300Y27595D02*X10600Y28375D01* +X8325Y29155D02*X8000Y29480D01* +Y30130D01* +X8325Y30455D01* +X10600Y30130D02*X10275Y30455D01* +X10600Y29480D02*Y30130D01* +X10275Y29155D02*X10600Y29480D01* +X9170D02*Y30130D01* +X8325Y30455D02*X8845D01* +X9495D02*X10275D01* +X9495D02*X9170Y30130D01* +X8845Y30455D02*X9170Y30130D01* +X14000Y35500D02*Y36700D01* +X14300Y37000D01* +X14900D01* +X15200Y36700D02*X14900Y37000D01* +X15200Y35800D02*Y36700D01* +X14000Y35800D02*X16400D01* +X15200Y36280D02*X16400Y37000D01* +X15500Y37720D02*X14000Y38920D01* +X15500Y37720D02*Y39220D01* +X14000Y38920D02*X16400D01* +X31250Y47500D02*X33250D01* +X33750Y47000D01* +Y46000D01* +X33250Y45500D02*X33750Y46000D01* +X31750Y45500D02*X33250D01* +X31750Y47500D02*Y43500D01* +X32550Y45500D02*X33750Y43500D01* +X34950Y47000D02*X35450Y47500D01* +X36950D01* +X37450Y47000D01* +Y46000D01* +X34950Y43500D02*X37450Y46000D01* +X34950Y43500D02*X37450D01* +X7000Y11000D02*Y9000D01* +X6500Y8500D01* +X5500D01* +X5000Y9000D02*X5500Y8500D01* +X5000Y10500D02*Y9000D01* +X7000Y10500D02*X3000D01* +X5000Y9700D02*X3000Y8500D01* +X7000Y5800D02*X6500Y5300D01* +X7000Y6800D02*Y5800D01* +X6500Y7300D02*X7000Y6800D01* +X6500Y7300D02*X3500D01* +X3000Y6800D01* +X5200Y5800D02*X4700Y5300D01* +X5200Y7300D02*Y5800D01* +X3000Y6800D02*Y5800D01* +X3500Y5300D01* +X4700D02*X3500D01* +X35500Y36500D02*Y34500D01* +X35000Y34000D01* +X34000D01* +X33500Y34500D02*X34000Y34000D01* +X33500Y36000D02*Y34500D01* +X35500Y36000D02*X31500D01* +X33500Y35200D02*X31500Y34000D01* +X35500Y32800D02*Y30800D01* +Y32800D02*X33500D01* +X34000Y32300D01* +Y31300D01* +X33500Y30800D01* +X32000D01* +X31500Y31300D02*X32000Y30800D01* +X31500Y32300D02*Y31300D01* +X32000Y32800D02*X31500Y32300D01* +X19500Y13500D02*Y11500D01* +X19000Y11000D01* +X18000D01* +X17500Y11500D02*X18000Y11000D01* +X17500Y13000D02*Y11500D01* +X19500Y13000D02*X15500D01* +X17500Y12200D02*X15500Y11000D01* +Y9300D02*X19500Y7300D01* +Y9800D02*Y7300D01* +X33500Y12500D02*Y10500D01* +X33000Y10000D01* +X32000D01* +X31500Y10500D02*X32000Y10000D01* +X31500Y12000D02*Y10500D01* +X33500Y12000D02*X29500D01* +X31500Y11200D02*X29500Y10000D01* +X30000Y8800D02*X29500Y8300D01* +X30800Y8800D02*X30000D01* +X30800D02*X31500Y8100D01* +Y7500D01* +X30800Y6800D01* +X30000D01* +X29500Y7300D02*X30000Y6800D01* +X29500Y8300D02*Y7300D01* +X32200Y8800D02*X31500Y8100D01* +X33000Y8800D02*X32200D01* +X33000D02*X33500Y8300D01* +Y7300D01* +X33000Y6800D01* +X32200D01* +X31500Y7500D02*X32200Y6800D01* +M02* Index: tags/2.3.0/tests/RTT/ref/padrot.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/padrot.net =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.net (revision 33253) @@ -0,0 +1,20 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Rotated round cap and square pads +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +327N/C R1 -1 A01X+000875Y+004500X0850Y0100R000 S1 +327N/C R3 -1 A01X+000500Y+003375X0100Y0850R000 S1 +327N/C R2 -1 A01X+002375Y+004500X0850Y0100R000 S1 +327N/C R6 -1 A01X+000500Y+001875X0100Y0850R000 S1 +327N/C R4 -1 A01X+001515Y+003234X0630Y0630R000 S1 +327N/C R5 -1 A01X+002515Y+003234X0630Y0630R000 S1 +327N/C R7 -1 A01X+001597Y+001858X0794Y0383R000 S1 +327N/C R8 -1 A01X+003097Y+001858X0794Y0383R000 S1 +999 Index: tags/2.3.0/tests/RTT/ref/padrot.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/padrot.png =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/padrot.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/padrot.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/padrot.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/padrot.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/padrot.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.svg (revision 33253) @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/padrot.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/padrot.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padrot.xy (revision 33253) @@ -0,0 +1,16 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Rotated round cap and square pads - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- +R1,"(unknown)","(unknown)",87.50,450.00,0,top +R3,"(unknown)","(unknown)",50.00,337.50,0,top +R2,"(unknown)","(unknown)",237.50,450.00,0,top +R6,"(unknown)","(unknown)",50.00,187.50,0,top +R4,"(unknown)","(unknown)",151.51,323.49,0,top +R5,"(unknown)","(unknown)",251.51,323.49,0,top +R7,"(unknown)","(unknown)",159.72,185.82,0,top +R8,"(unknown)","(unknown)",309.71,185.82,0,top Index: tags/2.3.0/tests/RTT/ref/padstack.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: (unknown) - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/padstack.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.dsn (revision 33253) @@ -0,0 +1,62 @@ +(pcb notnamed + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 60 + (place 60 1.905000 10.160000 front 0 (PN 0)) + ) + (component 62 + (place 62 9.525000 10.160000 front 0 (PN 0)) + ) + (component 63 + (place 63 1.905000 4.445000 front 0 (PN 0)) + ) + (component 64 + (place 64 5.715000 4.445000 front 0 (PN 0)) + ) + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/padstack.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.eps (revision 33253) @@ -0,0 +1,79 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: padstack.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.01000 setlinewidth +1 setlinecap +0.627451 0.627451 0.627451 setrgbcolor +0.15000 0.10000 0.02500 0.10000 t +0.37500 0.10000 0.04331 c +0.22500 0.32500 0.04831 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.07500 0.10000 0.01575 c +0.37500 0.10000 0.01968 c +0.22500 0.32500 0.01968 c +% Layer group5 group 5 drill 0 mask 0 +0.00000 setlinewidth +0.627451 0.627451 0.627451 setrgbcolor +0.07500 0.10000 0.03937 c +0.37500 0.10000 0.04331 c +0.07500 0.32500 0.04580 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.07500 0.10000 0.01575 c +0.37500 0.10000 0.01968 c +0.07500 0.32500 0.01968 c +% Layer group7 group 7 drill 0 mask 0 +0.00000 setlinewidth +0.627451 0.627451 0.627451 setrgbcolor +0.07500 0.10000 0.03937 c +0.37500 0.10000 0.04331 c +0.22500 0.32500 0.04831 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.07500 0.10000 0.01575 c +0.37500 0.10000 0.01968 c +0.22500 0.32500 0.01968 c +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +0.439216 0.439216 0.439216 setrgbcolor +0.02500 0.05000 moveto +0.02500 0.15000 lineto +0.12500 0.12500 lineto +0.12500 0.05000 lineto +fill +0.37500 0.10000 0.04331 c +0.07500 0.32500 0.04580 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.07500 0.10000 0.01575 c +0.37500 0.10000 0.01968 c +0.07500 0.32500 0.01968 c +% Layer topsilk group 1 drill 0 mask 0 +% Layer plated-drill group -1 drill 1 mask 0 +0.07500 0.10000 0.01575 c +0.37500 0.10000 0.01968 c +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/padstack.exc/padstack.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.exc/padstack.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.exc/padstack.plated.cnc (revision 33253) @@ -0,0 +1,11 @@ +M48 +INCH +T12C0.039 +T11C0.032 +% +T11 +G05 +X000750Y004000 +T12 +X003750Y004000 +M30 Index: tags/2.3.0/tests/RTT/ref/padstack.exc/padstack.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.exc/padstack.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.exc/padstack.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/padstack.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.fcd (revision 33253) @@ -0,0 +1,3 @@ +[FIDOCAD] +PL 20 30 20 5 4 8 +pa 75 20 17 17 8 0 Index: tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,20 @@ +G04 start of page 5 for group 10 layer_idx 1 * +G04 Title: (unknown), bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD30C,0.0394*% +%ADD29C,0.0315*% +%ADD28C,0.0966*% +%ADD27C,0.0866*% +%ADD26C,0.0100*% +G54D26*X15000Y40000D02*X2500D01* +G54D27*X37500D03* +G54D28*X22500Y17500D03* +G54D29*G54D30*M02* Index: tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.global.virtual.pdrill.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.global.virtual.pdrill.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.global.virtual.pdrill.none.gbr (revision 33253) @@ -0,0 +1,16 @@ +G04 start of page 6 for group -1 layer_idx 268435462 * +G04 Title: (unknown), * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_VIRTUAL_PDRILL_NONE*% +%ADD32C,0.0394*% +%ADD31C,0.0315*% +G54D31*X7500Y40000D03* +G54D32*X37500D03* +M02* Index: tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.intern.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.intern.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.intern.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 8 for group 9 layer_idx 6 * +G04 Title: (unknown), global outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_BOUNDARY_UROUTE_9*% +%ADD34C,0.0100*% +G54D34*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.intern.copper.none.5.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.intern.copper.none.5.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.intern.copper.none.5.gbr (revision 33253) @@ -0,0 +1,20 @@ +G04 start of page 3 for group 5 layer_idx 4 * +G04 Title: (unknown), Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_5*% +%ADD20C,0.0394*% +%ADD19C,0.0315*% +%ADD18C,0.0916*% +%ADD17C,0.0866*% +%ADD16C,0.0787*% +G54D16*X7500Y40000D03* +G54D17*X37500D03* +G54D18*X7500Y17500D03* +G54D19*G54D20*M02* Index: tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.intern.copper.none.7.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.intern.copper.none.7.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.intern.copper.none.7.gbr (revision 33253) @@ -0,0 +1,20 @@ +G04 start of page 4 for group 7 layer_idx 5 * +G04 Title: (unknown), Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_7*% +%ADD25C,0.0394*% +%ADD24C,0.0315*% +%ADD23C,0.0966*% +%ADD22C,0.0866*% +%ADD21C,0.0787*% +G54D21*X7500Y40000D03* +G54D22*X37500D03* +G54D23*X22500Y17500D03* +G54D24*G54D25*M02* Index: tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1845 @@ +G04 start of page 9 for group -1 layer_idx 268435461 * +G04 Title: (unknown), * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD38C,0.0100*% +%ADD37C,0.0001*% +%ADD36C,0.0060*% +%ADD35C,0.0080*% +G54D35*X37500Y41600D02*Y38400D01* +X35900Y40000D02*X39100D01* +X7500Y19100D02*Y15900D01* +X5900Y17500D02*X9100D01* +X22500Y19100D02*Y15900D01* +X20900Y17500D02*X24100D01* +X15000Y92850D02*Y89650D01* +X13400Y91250D02*X16600D01* +G54D36*X135000Y95000D02*X136500Y92000D01* +X138000Y95000D01* +X136500Y92000D02*Y89000D01* +X139800Y92300D02*X142050D01* +X139800Y89000D02*X142800D01* +X139800Y95000D02*Y89000D01* +Y95000D02*X142800D01* +X147600D02*X148350Y94250D01* +X145350Y95000D02*X147600D01* +X144600Y94250D02*X145350Y95000D01* +X144600Y94250D02*Y92750D01* +X145350Y92000D01* +X147600D01* +X148350Y91250D01* +Y89750D01* +X147600Y89000D02*X148350Y89750D01* +X145350Y89000D02*X147600D01* +X144600Y89750D02*X145350Y89000D01* +X98000Y94250D02*X98750Y95000D01* +X100250D01* +X101000Y94250D01* +X100250Y89000D02*X101000Y89750D01* +X98750Y89000D02*X100250D01* +X98000Y89750D02*X98750Y89000D01* +Y92300D02*X100250D01* +X101000Y94250D02*Y93050D01* +Y91550D02*Y89750D01* +Y91550D02*X100250Y92300D01* +X101000Y93050D02*X100250Y92300D01* +G54D37*G36* +X45000Y95000D02*X49500D01* +Y89000D01* +X45000D01* +Y95000D01* +G37* +G36* +X50400D02*X54900D01* +Y89000D01* +X50400D01* +Y95000D01* +G37* +G36* +X55800D02*X60300D01* +Y89000D01* +X55800D01* +Y95000D01* +G37* +G54D36*X61200Y94250D02*X61950Y95000D01* +X63450D01* +X64200Y94250D01* +X63450Y89000D02*X64200Y89750D01* +X61950Y89000D02*X63450D01* +X61200Y89750D02*X61950Y89000D01* +Y92300D02*X63450D01* +X64200Y94250D02*Y93050D01* +Y91550D02*Y89750D01* +Y91550D02*X63450Y92300D01* +X64200Y93050D02*X63450Y92300D01* +X66750Y89000D02*X69000Y92000D01* +Y94250D02*Y92000D01* +X68250Y95000D02*X69000Y94250D01* +X66750Y95000D02*X68250D01* +X66000Y94250D02*X66750Y95000D01* +X66000Y94250D02*Y92750D01* +X66750Y92000D01* +X69000D01* +X7500Y40000D02*Y38400D01* +Y40000D02*X8887Y40800D01* +X7500Y40000D02*X6113Y40800D01* +X15000Y106250D02*Y104650D01* +Y106250D02*X16387Y107050D01* +X15000Y106250D02*X13613Y107050D01* +X135000Y110000D02*X136500Y107000D01* +X138000Y110000D01* +X136500Y107000D02*Y104000D01* +X139800Y107300D02*X142050D01* +X139800Y104000D02*X142800D01* +X139800Y110000D02*Y104000D01* +Y110000D02*X142800D01* +X147600D02*X148350Y109250D01* +X145350Y110000D02*X147600D01* +X144600Y109250D02*X145350Y110000D01* +X144600Y109250D02*Y107750D01* +X145350Y107000D01* +X147600D01* +X148350Y106250D01* +Y104750D01* +X147600Y104000D02*X148350Y104750D01* +X145350Y104000D02*X147600D01* +X144600Y104750D02*X145350Y104000D01* +X98000Y108800D02*X99200Y110000D01* +Y104000D01* +X98000D02*X100250D01* +G54D37*G36* +X45000Y110000D02*X49500D01* +Y104000D01* +X45000D01* +Y110000D01* +G37* +G36* +X50400D02*X54900D01* +Y104000D01* +X50400D01* +Y110000D01* +G37* +G36* +X55800D02*X60300D01* +Y104000D01* +X55800D01* +Y110000D01* +G37* +G54D36*X61200Y109250D02*X61950Y110000D01* +X63450D01* +X64200Y109250D01* +X63450Y104000D02*X64200Y104750D01* +X61950Y104000D02*X63450D01* +X61200Y104750D02*X61950Y104000D01* +Y107300D02*X63450D01* +X64200Y109250D02*Y108050D01* +Y106550D02*Y104750D01* +Y106550D02*X63450Y107300D01* +X64200Y108050D02*X63450Y107300D01* +X66000Y109250D02*X66750Y110000D01* +X69000D01* +X69750Y109250D01* +Y107750D01* +X66000Y104000D02*X69750Y107750D01* +X66000Y104000D02*X69750D01* +X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D37*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D36*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D37*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D36*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D37*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D36*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D37*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D36*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D37*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D36*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D37*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G54D36*X48000Y139250D02*X48750Y140000D01* +X51000D01* +X51750Y139250D01* +Y137750D01* +X48000Y134000D02*X51750Y137750D01* +X48000Y134000D02*X51750D01* +G54D37*G36* +X56250Y140000D02*X60750D01* +Y134000D01* +X56250D01* +Y140000D01* +G37* +G36* +X61650D02*X66150D01* +Y134000D01* +X61650D01* +Y140000D01* +G37* +G36* +X67050D02*X71550D01* +Y134000D01* +X67050D01* +Y140000D01* +G37* +G36* +X72450D02*X76950D01* +Y134000D01* +X72450D01* +Y140000D01* +G37* +G36* +X77850D02*X82350D01* +Y134000D01* +X77850D01* +Y140000D01* +G37* +G36* +X83250D02*X87750D01* +Y134000D01* +X83250D01* +Y140000D01* +G37* +G36* +X88650D02*X93150D01* +Y134000D01* +X88650D01* +Y140000D01* +G37* +G36* +X94050D02*X98550D01* +Y134000D01* +X94050D01* +Y140000D01* +G37* +G36* +X99450D02*X103950D01* +Y134000D01* +X99450D01* +Y140000D01* +G37* +G36* +X107550D02*X112050D01* +Y134000D01* +X107550D01* +Y140000D01* +G37* +G36* +X112950D02*X117450D01* +Y134000D01* +X112950D01* +Y140000D01* +G37* +G36* +X118350D02*X122850D01* +Y134000D01* +X118350D01* +Y140000D01* +G37* +G36* +X123750D02*X128250D01* +Y134000D01* +X123750D01* +Y140000D01* +G37* +G36* +X129150D02*X133650D01* +Y134000D01* +X129150D01* +Y140000D01* +G37* +G36* +X137250D02*X141750D01* +Y134000D01* +X137250D01* +Y140000D01* +G37* +G36* +X142650D02*X147150D01* +Y134000D01* +X142650D01* +Y140000D01* +G37* +G36* +X148050D02*X152550D01* +Y134000D01* +X148050D01* +Y140000D01* +G37* +G36* +X153450D02*X157950D01* +Y134000D01* +X153450D01* +Y140000D01* +G37* +G36* +X158850D02*X163350D01* +Y134000D01* +X158850D01* +Y140000D01* +G37* +G36* +X166950D02*X171450D01* +Y134000D01* +X166950D01* +Y140000D01* +G37* +G36* +X172350D02*X176850D01* +Y134000D01* +X172350D01* +Y140000D01* +G37* +G36* +X177750D02*X182250D01* +Y134000D01* +X177750D01* +Y140000D01* +G37* +G36* +X183150D02*X187650D01* +Y134000D01* +X183150D01* +Y140000D01* +G37* +G36* +X191250D02*X195750D01* +Y134000D01* +X191250D01* +Y140000D01* +G37* +G36* +X196650D02*X201150D01* +Y134000D01* +X196650D01* +Y140000D01* +G37* +G36* +X204750D02*X209250D01* +Y134000D01* +X204750D01* +Y140000D01* +G37* +G36* +X210150D02*X214650D01* +Y134000D01* +X210150D01* +Y140000D01* +G37* +G36* +X215550D02*X220050D01* +Y134000D01* +X215550D01* +Y140000D01* +G37* +G36* +X220950D02*X225450D01* +Y134000D01* +X220950D01* +Y140000D01* +G37* +G36* +X229050D02*X233550D01* +Y134000D01* +X229050D01* +Y140000D01* +G37* +G36* +X234450D02*X238950D01* +Y134000D01* +X234450D01* +Y140000D01* +G37* +G36* +X239850D02*X244350D01* +Y134000D01* +X239850D01* +Y140000D01* +G37* +G36* +X245250D02*X249750D01* +Y134000D01* +X245250D01* +Y140000D01* +G37* +G36* +X250650D02*X255150D01* +Y134000D01* +X250650D01* +Y140000D01* +G37* +G36* +X256050D02*X260550D01* +Y134000D01* +X256050D01* +Y140000D01* +G37* +G36* +X261450D02*X265950D01* +Y134000D01* +X261450D01* +Y140000D01* +G37* +G54D36*X269550Y136250D02*X272550Y140000D01* +X269550Y136250D02*X273300D01* +X272550Y140000D02*Y134000D01* +G54D37*G36* +X277800Y140000D02*X282300D01* +Y134000D01* +X277800D01* +Y140000D01* +G37* +G36* +X283200D02*X287700D01* +Y134000D01* +X283200D01* +Y140000D01* +G37* +G36* +X288600D02*X293100D01* +Y134000D01* +X288600D01* +Y140000D01* +G37* +G36* +X294000D02*X298500D01* +Y134000D01* +X294000D01* +Y140000D01* +G37* +G36* +X299400D02*X303900D01* +Y134000D01* +X299400D01* +Y140000D01* +G37* +G36* +X307500D02*X312000D01* +Y134000D01* +X307500D01* +Y140000D01* +G37* +G36* +X312900D02*X317400D01* +Y134000D01* +X312900D01* +Y140000D01* +G37* +G36* +X318300D02*X322800D01* +Y134000D01* +X318300D01* +Y140000D01* +G37* +G36* +X323700D02*X328200D01* +Y134000D01* +X323700D01* +Y140000D01* +G37* +G36* +X329100D02*X333600D01* +Y134000D01* +X329100D01* +Y140000D01* +G37* +G54D38*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D36*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D37*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D36*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D37*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D36*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D37*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D36*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D37*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D36*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D37*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D36*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D37*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D36*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D37*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D36*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D37*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D36*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D37*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D36*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D37*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D36*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D37*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X256100D02*X260600D01* +Y104000D01* +X256100D01* +Y110000D01* +G37* +G36* +X261500D02*X266000D01* +Y104000D01* +X261500D01* +Y110000D01* +G37* +G36* +X266900D02*X271400D01* +Y104000D01* +X266900D01* +Y110000D01* +G37* +G36* +X272300D02*X276800D01* +Y104000D01* +X272300D01* +Y110000D01* +G37* +G36* +X277700D02*X282200D01* +Y104000D01* +X277700D01* +Y110000D01* +G37* +G36* +X285800D02*X290300D01* +Y104000D01* +X285800D01* +Y110000D01* +G37* +G54D36*X293900D02*Y104000D01* +Y110000D02*X296900D01* +X293900Y107300D02*X296150D01* +G54D37*G36* +X298700Y110000D02*X303200D01* +Y104000D01* +X298700D01* +Y110000D01* +G37* +G36* +X304100D02*X308600D01* +Y104000D01* +X304100D01* +Y110000D01* +G37* +G36* +X309500D02*X314000D01* +Y104000D01* +X309500D01* +Y110000D01* +G37* +G36* +X314900D02*X319400D01* +Y104000D01* +X314900D01* +Y110000D01* +G37* +G36* +X320300D02*X324800D01* +Y104000D01* +X320300D01* +Y110000D01* +G37* +G36* +X325700D02*X330200D01* +Y104000D01* +X325700D01* +Y110000D01* +G37* +G36* +X331100D02*X335600D01* +Y104000D01* +X331100D01* +Y110000D01* +G37* +G36* +X336500D02*X341000D01* +Y104000D01* +X336500D01* +Y110000D01* +G37* +G36* +X341900D02*X346400D01* +Y104000D01* +X341900D01* +Y110000D01* +G37* +G36* +X347300D02*X351800D01* +Y104000D01* +X347300D01* +Y110000D01* +G37* +G54D36*X356150D02*Y104000D01* +X358100Y110000D02*X359150Y108950D01* +Y105050D01* +X358100Y104000D02*X359150Y105050D01* +X355400Y104000D02*X358100D01* +X355400Y110000D02*X358100D01* +G54D37*G36* +X360950D02*X365450D01* +Y104000D01* +X360950D01* +Y110000D01* +G37* +G36* +X366350D02*X370850D01* +Y104000D01* +X366350D01* +Y110000D01* +G37* +G36* +X371750D02*X376250D01* +Y104000D01* +X371750D01* +Y110000D01* +G37* +G36* +X377150D02*X381650D01* +Y104000D01* +X377150D01* +Y110000D01* +G37* +G36* +X382550D02*X387050D01* +Y104000D01* +X382550D01* +Y110000D01* +G37* +G36* +X387950D02*X392450D01* +Y104000D01* +X387950D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,25 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: (unknown), top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD15C,0.0394*% +%ADD14C,0.0315*% +%ADD13C,0.0916*% +%ADD12C,0.0866*% +%ADD11C,0.0001*% +G54D11*G36* +X2500Y45000D02*Y35000D01* +X12500Y37500D01* +Y45000D01* +X2500D01* +G37* +G54D12*X37500Y40000D03* +G54D13*X7500Y17500D03* +G54D14*G54D15*M02* Index: tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.top.paste.none.0.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.top.paste.none.0.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.gbr/padstack.top.paste.none.0.gbr (revision 33253) @@ -0,0 +1,15 @@ +G04 start of page 7 for group 0 layer_idx 10 * +G04 Title: (unknown), top_paste * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_PASTE_NONE_0*% +%ADD33C,0.0200*% +G54D33*X7500Y35000D02*Y47500D01* +X10000Y35000D02*Y47500D01* +M02* Index: tags/2.3.0/tests/RTT/ref/padstack.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.nelma.em (revision 33253) @@ -0,0 +1,105 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} +layer substrate-11 { + height = 20 + z-order = 11 + material = "composite" +} +layer group-1 { + height = 1 + z-order = 12 + material = "air" + objects = { + + } +} +layer substrate-13 { + height = 20 + z-order = 13 + material = "composite" +} +layer group-1 { + height = 1 + z-order = 14 + material = "air" + objects = { + + } +} +layer substrate-15 { + height = 20 + z-order = 15 + material = "composite" +} +layer bottom { + height = 1 + z-order = 16 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top", + "substrate-11", + "group-1", + "substrate-13", + "group-1", + "substrate-15", + "bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/padstack.net =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB padstack.lht +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/padstack.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/padstack.png =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/padstack.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/padstack.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/padstack.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/padstack.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/padstack.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.svg (revision 33253) @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/padstack.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/padstack.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/padstack.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: (unknown) - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/poly_hole.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Polygons with holes - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/poly_hole.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb Polygons with holes + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/poly_hole.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.eps (revision 33253) @@ -0,0 +1,112 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: poly_hole.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.12500 0.02500 moveto +0.06250 0.08750 lineto +0.06250 0.06250 lineto +0.07500 0.05000 lineto +0.06250 0.05000 lineto +0.06250 0.02500 lineto +fill +0.06250 0.02500 moveto +0.06250 0.05000 lineto +0.05000 0.05000 lineto +0.05000 0.07500 lineto +0.06250 0.06250 lineto +0.06250 0.08750 lineto +0.02500 0.12500 lineto +0.02500 0.02500 lineto +fill +0.15000 0.02500 moveto +0.15000 0.15000 lineto +0.10000 0.15000 lineto +0.10000 0.12500 lineto +0.12500 0.12500 lineto +0.12500 0.10000 lineto +0.10000 0.10000 lineto +0.10000 0.07500 lineto +fill +0.10000 0.07500 moveto +0.10000 0.10000 lineto +0.07500 0.12500 lineto +0.10000 0.12500 lineto +0.10000 0.15000 lineto +0.02500 0.15000 lineto +fill +0.42500 0.15000 moveto +0.30000 0.15000 lineto +0.30000 0.12500 lineto +0.32500 0.12500 lineto +0.32500 0.07500 lineto +0.30000 0.07500 lineto +0.30000 0.02500 lineto +fill +0.30000 0.02500 moveto +0.30000 0.07500 lineto +0.27500 0.07500 lineto +0.27500 0.12500 lineto +0.30000 0.12500 lineto +0.30000 0.15000 lineto +0.17500 0.15000 lineto +fill +0.30000 0.20000 moveto +0.16250 0.28250 lineto +0.16250 0.25000 lineto +0.17500 0.25000 lineto +0.17500 0.22500 lineto +0.16250 0.22500 lineto +0.16250 0.18750 lineto +fill +0.16250 0.18750 moveto +0.16250 0.22500 lineto +0.15000 0.22500 lineto +0.15000 0.25000 lineto +0.16250 0.25000 lineto +0.16250 0.28250 lineto +0.10000 0.32000 lineto +0.10000 0.30000 lineto +0.12500 0.27500 lineto +0.12500 0.25000 lineto +0.10000 0.22500 lineto +0.10000 0.18182 lineto +fill +0.10000 0.18182 moveto +0.10000 0.22500 lineto +0.07500 0.22500 lineto +0.07500 0.27500 lineto +0.10000 0.30000 lineto +0.10000 0.32000 lineto +0.05000 0.35000 lineto +0.02500 0.17500 lineto +fill +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/poly_hole.exc/poly_hole.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.exc/poly_hole.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.exc/poly_hole.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/poly_hole.exc/poly_hole.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.exc/poly_hole.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.exc/poly_hole.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/poly_hole.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.fcd (revision 33253) @@ -0,0 +1,5 @@ +[FIDOCAD] +PP 5 5 25 5 5 25 5 5 2 +PP 5 30 30 5 30 30 5 30 2 +PP 35 30 60 5 85 30 35 30 2 +PP 5 35 60 40 10 70 5 35 2 Index: tags/2.3.0/tests/RTT/ref/poly_hole.gbr/poly_hole.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.gbr/poly_hole.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.gbr/poly_hole.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Polygons with holes, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/poly_hole.gbr/poly_hole.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.gbr/poly_hole.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.gbr/poly_hole.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1759 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Polygons with holes, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D13*X235250D02*Y104000D01* +X234500Y110000D02*X237500D01* +X238250Y109250D01* +Y107750D01* +X237500Y107000D02*X238250Y107750D01* +X235250Y107000D02*X237500D01* +G54D14*G36* +X240050Y110000D02*X244550D01* +Y104000D01* +X240050D01* +Y110000D01* +G37* +G36* +X245450D02*X249950D01* +Y104000D01* +X245450D01* +Y110000D01* +G37* +G36* +X250850D02*X255350D01* +Y104000D01* +X250850D01* +Y110000D01* +G37* +G36* +X256250D02*X260750D01* +Y104000D01* +X256250D01* +Y110000D01* +G37* +G36* +X261650D02*X266150D01* +Y104000D01* +X261650D01* +Y110000D01* +G37* +G36* +X267050D02*X271550D01* +Y104000D01* +X267050D01* +Y110000D01* +G37* +G36* +X272450D02*X276950D01* +Y104000D01* +X272450D01* +Y110000D01* +G37* +G36* +X280550D02*X285050D01* +Y104000D01* +X280550D01* +Y110000D01* +G37* +G36* +X285950D02*X290450D01* +Y104000D01* +X285950D01* +Y110000D01* +G37* +G36* +X291350D02*X295850D01* +Y104000D01* +X291350D01* +Y110000D01* +G37* +G36* +X296750D02*X301250D01* +Y104000D01* +X296750D01* +Y110000D01* +G37* +G36* +X304850D02*X309350D01* +Y104000D01* +X304850D01* +Y110000D01* +G37* +G36* +X310250D02*X314750D01* +Y104000D01* +X310250D01* +Y110000D01* +G37* +G36* +X315650D02*X320150D01* +Y104000D01* +X315650D01* +Y110000D01* +G37* +G36* +X321050D02*X325550D01* +Y104000D01* +X321050D01* +Y110000D01* +G37* +G36* +X326450D02*X330950D01* +Y104000D01* +X326450D01* +Y110000D01* +G37* +G36* +X334550D02*X339050D01* +Y104000D01* +X334550D01* +Y110000D01* +G37* +G54D13*X342650D02*Y104000D01* +Y110000D02*X345650D01* +X342650Y107300D02*X344900D01* +G54D14*G36* +X347450Y110000D02*X351950D01* +Y104000D01* +X347450D01* +Y110000D01* +G37* +G36* +X352850D02*X357350D01* +Y104000D01* +X352850D01* +Y110000D01* +G37* +G36* +X358250D02*X362750D01* +Y104000D01* +X358250D01* +Y110000D01* +G37* +G36* +X363650D02*X368150D01* +Y104000D01* +X363650D01* +Y110000D01* +G37* +G36* +X369050D02*X373550D01* +Y104000D01* +X369050D01* +Y110000D01* +G37* +G36* +X374450D02*X378950D01* +Y104000D01* +X374450D01* +Y110000D01* +G37* +G36* +X379850D02*X384350D01* +Y104000D01* +X379850D01* +Y110000D01* +G37* +G36* +X385250D02*X389750D01* +Y104000D01* +X385250D01* +Y110000D01* +G37* +G36* +X390650D02*X395150D01* +Y104000D01* +X390650D01* +Y110000D01* +G37* +G36* +X396050D02*X400550D01* +Y104000D01* +X396050D01* +Y110000D01* +G37* +G54D13*X404900D02*Y104000D01* +X406850Y110000D02*X407900Y108950D01* +Y105050D01* +X406850Y104000D02*X407900Y105050D01* +X404150Y104000D02*X406850D01* +X404150Y110000D02*X406850D01* +G54D14*G36* +X409700D02*X414200D01* +Y104000D01* +X409700D01* +Y110000D01* +G37* +G36* +X415100D02*X419600D01* +Y104000D01* +X415100D01* +Y110000D01* +G37* +G36* +X420500D02*X425000D01* +Y104000D01* +X420500D01* +Y110000D01* +G37* +G36* +X425900D02*X430400D01* +Y104000D01* +X425900D01* +Y110000D01* +G37* +G36* +X431300D02*X435800D01* +Y104000D01* +X431300D01* +Y110000D01* +G37* +G36* +X436700D02*X441200D01* +Y104000D01* +X436700D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/poly_hole.gbr/poly_hole.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.gbr/poly_hole.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.gbr/poly_hole.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,100 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Polygons with holes, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0001*% +G54D11*G36* +X12500Y47500D02*X6250Y41250D01* +Y43750D01* +X7500Y45000D01* +X6250D01* +Y47500D01* +X12500D01* +G37* +G36* +X6250D02*Y45000D01* +X5000D01* +Y42500D01* +X6250Y43750D01* +Y41250D01* +X2500Y37500D01* +Y47500D01* +X6250D01* +G37* +G36* +X15000D02*Y35000D01* +X10000D01* +Y37500D01* +X12500D01* +Y40000D01* +X10000D01* +Y42500D01* +X15000Y47500D01* +G37* +G36* +X10000Y42500D02*Y40000D01* +X7500Y37500D01* +X10000D01* +Y35000D01* +X2500D01* +X10000Y42500D01* +G37* +G36* +X42500Y35000D02*X30000D01* +Y37500D01* +X32500D01* +Y42500D01* +X30000D01* +Y47500D01* +X42500Y35000D01* +G37* +G36* +X30000Y47500D02*Y42500D01* +X27500D01* +Y37500D01* +X30000D01* +Y35000D01* +X17500D01* +X30000Y47500D01* +G37* +G36* +Y30000D02*X16250Y21750D01* +Y25000D01* +X17500D01* +Y27500D01* +X16250D01* +Y31250D01* +X30000Y30000D01* +G37* +G36* +X16250Y31250D02*Y27500D01* +X15000D01* +Y25000D01* +X16250D01* +Y21750D01* +X10000Y18000D01* +Y20000D01* +X12500Y22500D01* +Y25000D01* +X10000Y27500D01* +Y31818D01* +X16250Y31250D01* +G37* +G36* +X10000Y31818D02*Y27500D01* +X7500D01* +Y22500D01* +X10000Y20000D01* +Y18000D01* +X5000Y15000D01* +X2500Y32500D01* +X10000Y31818D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/poly_hole.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/poly_hole.net =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Polygons with holes +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/poly_hole.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/poly_hole.png =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/poly_hole.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/poly_hole.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.png.text (revision 33253) @@ -0,0 +1,18 @@ +r6630 + +500 x 500 mil outline + +upper left triangle +Top left corner to top left cutout corner 30 pixels down 31 pixels over +cutout 29 pixels (24.166) wide +cutout 29 pixels (24.166) high + +upper right triangle +bottom right corner to bottom right on cutout 31 x 31 pixels +cutout 59 pixels (49.167) wide <- this is not a measurement error. we count the edge pixel +cutout 30 pixels (25) high + +far right piramid +cutout 59 x 60 (49.166 x 50) pixels +cutout located 60 (50) pixels down from the apex + Index: tags/2.3.0/tests/RTT/ref/poly_hole.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/poly_hole.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/poly_hole.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/poly_hole.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/poly_hole.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/poly_hole.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/poly_hole.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.svg (revision 33253) @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/poly_hole.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_hole.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_hole.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Polygons with holes - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/poly_rect.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Normal rectangular polygons - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/poly_rect.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb Normal rectangular polygons + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/poly_rect.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.eps (revision 33253) @@ -0,0 +1,54 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: poly_rect.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.07500 0.02500 moveto +0.07500 0.45000 lineto +0.05000 0.45000 lineto +0.05000 0.02500 lineto +fill +0.47500 0.02500 moveto +0.47500 0.05000 lineto +0.12500 0.05000 lineto +0.12500 0.02500 lineto +fill +0.45000 0.42500 moveto +0.45000 0.45000 lineto +0.42500 0.45000 lineto +0.42500 0.42500 lineto +fill +0.40000 0.07500 moveto +0.40000 0.45000 lineto +0.12500 0.45000 lineto +0.12500 0.07500 lineto +fill +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/poly_rect.exc/poly_rect.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.exc/poly_rect.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.exc/poly_rect.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/poly_rect.exc/poly_rect.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.exc/poly_rect.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.exc/poly_rect.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/poly_rect.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.fcd (revision 33253) @@ -0,0 +1,5 @@ +[FIDOCAD] +PP 10 5 15 5 15 90 10 90 10 5 2 +PP 25 5 95 5 95 10 25 10 25 5 2 +PP 85 85 90 85 90 90 85 90 85 85 2 +PP 25 15 80 15 80 90 25 90 25 15 2 Index: tags/2.3.0/tests/RTT/ref/poly_rect.gbr/poly_rect.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.gbr/poly_rect.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.gbr/poly_rect.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Normal rectangular polygons, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/poly_rect.gbr/poly_rect.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.gbr/poly_rect.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.gbr/poly_rect.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1804 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Normal rectangular polygons, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D13*X234500D02*Y104000D01* +Y110000D02*X238250Y104000D01* +Y110000D02*Y104000D01* +G54D14*G36* +X240050Y110000D02*X244550D01* +Y104000D01* +X240050D01* +Y110000D01* +G37* +G36* +X245450D02*X249950D01* +Y104000D01* +X245450D01* +Y110000D01* +G37* +G36* +X250850D02*X255350D01* +Y104000D01* +X250850D01* +Y110000D01* +G37* +G36* +X256250D02*X260750D01* +Y104000D01* +X256250D01* +Y110000D01* +G37* +G36* +X261650D02*X266150D01* +Y104000D01* +X261650D01* +Y110000D01* +G37* +G36* +X269750D02*X274250D01* +Y104000D01* +X269750D01* +Y110000D01* +G37* +G36* +X275150D02*X279650D01* +Y104000D01* +X275150D01* +Y110000D01* +G37* +G36* +X280550D02*X285050D01* +Y104000D01* +X280550D01* +Y110000D01* +G37* +G36* +X285950D02*X290450D01* +Y104000D01* +X285950D01* +Y110000D01* +G37* +G36* +X291350D02*X295850D01* +Y104000D01* +X291350D01* +Y110000D01* +G37* +G36* +X296750D02*X301250D01* +Y104000D01* +X296750D01* +Y110000D01* +G37* +G36* +X302150D02*X306650D01* +Y104000D01* +X302150D01* +Y110000D01* +G37* +G36* +X307550D02*X312050D01* +Y104000D01* +X307550D01* +Y110000D01* +G37* +G36* +X312950D02*X317450D01* +Y104000D01* +X312950D01* +Y110000D01* +G37* +G36* +X318350D02*X322850D01* +Y104000D01* +X318350D01* +Y110000D01* +G37* +G36* +X323750D02*X328250D01* +Y104000D01* +X323750D01* +Y110000D01* +G37* +G36* +X331850D02*X336350D01* +Y104000D01* +X331850D01* +Y110000D01* +G37* +G36* +X337250D02*X341750D01* +Y104000D01* +X337250D01* +Y110000D01* +G37* +G36* +X342650D02*X347150D01* +Y104000D01* +X342650D01* +Y110000D01* +G37* +G36* +X348050D02*X352550D01* +Y104000D01* +X348050D01* +Y110000D01* +G37* +G36* +X353450D02*X357950D01* +Y104000D01* +X353450D01* +Y110000D01* +G37* +G36* +X358850D02*X363350D01* +Y104000D01* +X358850D01* +Y110000D01* +G37* +G36* +X364250D02*X368750D01* +Y104000D01* +X364250D01* +Y110000D01* +G37* +G36* +X369650D02*X374150D01* +Y104000D01* +X369650D01* +Y110000D01* +G37* +G36* +X377750D02*X382250D01* +Y104000D01* +X377750D01* +Y110000D01* +G37* +G54D13*X385850D02*Y104000D01* +Y110000D02*X388850D01* +X385850Y107300D02*X388100D01* +G54D14*G36* +X390650Y110000D02*X395150D01* +Y104000D01* +X390650D01* +Y110000D01* +G37* +G36* +X396050D02*X400550D01* +Y104000D01* +X396050D01* +Y110000D01* +G37* +G36* +X401450D02*X405950D01* +Y104000D01* +X401450D01* +Y110000D01* +G37* +G36* +X406850D02*X411350D01* +Y104000D01* +X406850D01* +Y110000D01* +G37* +G36* +X412250D02*X416750D01* +Y104000D01* +X412250D01* +Y110000D01* +G37* +G36* +X417650D02*X422150D01* +Y104000D01* +X417650D01* +Y110000D01* +G37* +G36* +X423050D02*X427550D01* +Y104000D01* +X423050D01* +Y110000D01* +G37* +G36* +X428450D02*X432950D01* +Y104000D01* +X428450D01* +Y110000D01* +G37* +G36* +X433850D02*X438350D01* +Y104000D01* +X433850D01* +Y110000D01* +G37* +G36* +X439250D02*X443750D01* +Y104000D01* +X439250D01* +Y110000D01* +G37* +G54D13*X448100D02*Y104000D01* +X450050Y110000D02*X451100Y108950D01* +Y105050D01* +X450050Y104000D02*X451100Y105050D01* +X447350Y104000D02*X450050D01* +X447350Y110000D02*X450050D01* +G54D14*G36* +X452900D02*X457400D01* +Y104000D01* +X452900D01* +Y110000D01* +G37* +G36* +X458300D02*X462800D01* +Y104000D01* +X458300D01* +Y110000D01* +G37* +G36* +X463700D02*X468200D01* +Y104000D01* +X463700D01* +Y110000D01* +G37* +G36* +X469100D02*X473600D01* +Y104000D01* +X469100D01* +Y110000D01* +G37* +G36* +X474500D02*X479000D01* +Y104000D01* +X474500D01* +Y110000D01* +G37* +G36* +X479900D02*X484400D01* +Y104000D01* +X479900D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/poly_rect.gbr/poly_rect.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.gbr/poly_rect.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.gbr/poly_rect.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,37 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Normal rectangular polygons, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0001*% +G54D11*G36* +X7500Y47500D02*Y5000D01* +X5000D01* +Y47500D01* +X7500D01* +G37* +G36* +X47500D02*Y45000D01* +X12500D01* +Y47500D01* +X47500D01* +G37* +G36* +X45000Y7500D02*Y5000D01* +X42500D01* +Y7500D01* +X45000D01* +G37* +G36* +X40000Y42500D02*Y5000D01* +X12500D01* +Y42500D01* +X40000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/poly_rect.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/poly_rect.net =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Normal rectangular polygons +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/poly_rect.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/poly_rect.png =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/poly_rect.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/poly_rect.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.png.text (revision 33253) @@ -0,0 +1,17 @@ +r6630 + +outline 500 x 500 mils + +vertical polygon +31 x 511 pixels (25.833 x 425.833) + +horizontal polygon +421 x 31 pixels (350.833 x 25.833) + +giant middle polygon +331 x 451 pixels (275.833 x 375.833) + +smallest polygon (bottom right) +31 x 31 pixels (25.833 x 25.833) + + Index: tags/2.3.0/tests/RTT/ref/poly_rect.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/poly_rect.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/poly_rect.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/poly_rect.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/poly_rect.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/poly_rect.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/poly_rect.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.svg (revision 33253) @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/poly_rect.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_rect.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_rect.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Normal rectangular polygons - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/poly_triangle.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: Normal triangular polygons - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/poly_triangle.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb Normal triangular polygons + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/poly_triangle.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.eps (revision 33253) @@ -0,0 +1,50 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: poly_triangle.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.545098 0.137255 0.137255 setrgbcolor +0.12500 0.02500 moveto +0.02500 0.12500 lineto +0.02500 0.02500 lineto +fill +0.15000 0.02500 moveto +0.15000 0.15000 lineto +0.02500 0.15000 lineto +fill +0.30000 0.02500 moveto +0.42500 0.15000 lineto +0.17500 0.15000 lineto +fill +0.30000 0.20000 moveto +0.05000 0.35000 lineto +0.02500 0.17500 lineto +fill +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/poly_triangle.exc/poly_triangle.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.exc/poly_triangle.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.exc/poly_triangle.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/poly_triangle.exc/poly_triangle.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.exc/poly_triangle.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.exc/poly_triangle.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/poly_triangle.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.fcd (revision 33253) @@ -0,0 +1,5 @@ +[FIDOCAD] +PP 5 5 25 5 5 25 5 5 2 +PP 5 30 30 5 30 30 5 30 2 +PP 35 30 60 5 85 30 35 30 2 +PP 5 35 60 40 10 70 5 35 2 Index: tags/2.3.0/tests/RTT/ref/poly_triangle.gbr/poly_triangle.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.gbr/poly_triangle.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.gbr/poly_triangle.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: Normal triangular polygons, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/poly_triangle.gbr/poly_triangle.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.gbr/poly_triangle.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.gbr/poly_triangle.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1798 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: Normal triangular polygons, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD15C,0.0100*% +%ADD14C,0.0001*% +%ADD13C,0.0060*% +G54D13*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D14*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D13*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D14*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D13*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D14*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D13*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D14*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D13*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D14*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D13*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D14*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D14*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D13*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D14*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D13*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D14*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D13*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D14*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D13*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D14*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D13*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D14*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D13*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D14*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D13*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D14*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D13*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D14*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D13*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D13*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D14*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G54D13*X234500D02*Y104000D01* +Y110000D02*X238250Y104000D01* +Y110000D02*Y104000D01* +G54D14*G36* +X240050Y110000D02*X244550D01* +Y104000D01* +X240050D01* +Y110000D01* +G37* +G36* +X245450D02*X249950D01* +Y104000D01* +X245450D01* +Y110000D01* +G37* +G36* +X250850D02*X255350D01* +Y104000D01* +X250850D01* +Y110000D01* +G37* +G36* +X256250D02*X260750D01* +Y104000D01* +X256250D01* +Y110000D01* +G37* +G36* +X261650D02*X266150D01* +Y104000D01* +X261650D01* +Y110000D01* +G37* +G36* +X269750D02*X274250D01* +Y104000D01* +X269750D01* +Y110000D01* +G37* +G36* +X275150D02*X279650D01* +Y104000D01* +X275150D01* +Y110000D01* +G37* +G36* +X280550D02*X285050D01* +Y104000D01* +X280550D01* +Y110000D01* +G37* +G36* +X285950D02*X290450D01* +Y104000D01* +X285950D01* +Y110000D01* +G37* +G36* +X291350D02*X295850D01* +Y104000D01* +X291350D01* +Y110000D01* +G37* +G36* +X296750D02*X301250D01* +Y104000D01* +X296750D01* +Y110000D01* +G37* +G36* +X302150D02*X306650D01* +Y104000D01* +X302150D01* +Y110000D01* +G37* +G36* +X307550D02*X312050D01* +Y104000D01* +X307550D01* +Y110000D01* +G37* +G36* +X312950D02*X317450D01* +Y104000D01* +X312950D01* +Y110000D01* +G37* +G36* +X318350D02*X322850D01* +Y104000D01* +X318350D01* +Y110000D01* +G37* +G36* +X326450D02*X330950D01* +Y104000D01* +X326450D01* +Y110000D01* +G37* +G36* +X331850D02*X336350D01* +Y104000D01* +X331850D01* +Y110000D01* +G37* +G36* +X337250D02*X341750D01* +Y104000D01* +X337250D01* +Y110000D01* +G37* +G36* +X342650D02*X347150D01* +Y104000D01* +X342650D01* +Y110000D01* +G37* +G36* +X348050D02*X352550D01* +Y104000D01* +X348050D01* +Y110000D01* +G37* +G36* +X353450D02*X357950D01* +Y104000D01* +X353450D01* +Y110000D01* +G37* +G36* +X358850D02*X363350D01* +Y104000D01* +X358850D01* +Y110000D01* +G37* +G36* +X364250D02*X368750D01* +Y104000D01* +X364250D01* +Y110000D01* +G37* +G36* +X372350D02*X376850D01* +Y104000D01* +X372350D01* +Y110000D01* +G37* +G54D13*X380450D02*Y104000D01* +Y110000D02*X383450D01* +X380450Y107300D02*X382700D01* +G54D14*G36* +X385250Y110000D02*X389750D01* +Y104000D01* +X385250D01* +Y110000D01* +G37* +G36* +X390650D02*X395150D01* +Y104000D01* +X390650D01* +Y110000D01* +G37* +G36* +X396050D02*X400550D01* +Y104000D01* +X396050D01* +Y110000D01* +G37* +G36* +X401450D02*X405950D01* +Y104000D01* +X401450D01* +Y110000D01* +G37* +G36* +X406850D02*X411350D01* +Y104000D01* +X406850D01* +Y110000D01* +G37* +G36* +X412250D02*X416750D01* +Y104000D01* +X412250D01* +Y110000D01* +G37* +G36* +X417650D02*X422150D01* +Y104000D01* +X417650D01* +Y110000D01* +G37* +G36* +X423050D02*X427550D01* +Y104000D01* +X423050D01* +Y110000D01* +G37* +G36* +X428450D02*X432950D01* +Y104000D01* +X428450D01* +Y110000D01* +G37* +G36* +X433850D02*X438350D01* +Y104000D01* +X433850D01* +Y110000D01* +G37* +G54D13*X442700D02*Y104000D01* +X444650Y110000D02*X445700Y108950D01* +Y105050D01* +X444650Y104000D02*X445700Y105050D01* +X441950Y104000D02*X444650D01* +X441950Y110000D02*X444650D01* +G54D14*G36* +X447500D02*X452000D01* +Y104000D01* +X447500D01* +Y110000D01* +G37* +G36* +X452900D02*X457400D01* +Y104000D01* +X452900D01* +Y110000D01* +G37* +G36* +X458300D02*X462800D01* +Y104000D01* +X458300D01* +Y110000D01* +G37* +G36* +X463700D02*X468200D01* +Y104000D01* +X463700D01* +Y110000D01* +G37* +G36* +X469100D02*X473600D01* +Y104000D01* +X469100D01* +Y110000D01* +G37* +G36* +X474500D02*X479000D01* +Y104000D01* +X474500D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/poly_triangle.gbr/poly_triangle.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.gbr/poly_triangle.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.gbr/poly_triangle.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,33 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: Normal triangular polygons, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD11C,0.0001*% +G54D11*G36* +X12500Y47500D02*X2500Y37500D01* +Y47500D01* +X12500D01* +G37* +G36* +X15000D02*Y35000D01* +X2500D01* +X15000Y47500D01* +G37* +G36* +X30000D02*X42500Y35000D01* +X17500D01* +X30000Y47500D01* +G37* +G36* +Y30000D02*X5000Y15000D01* +X2500Y32500D01* +X30000Y30000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/poly_triangle.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.nelma.em (revision 33253) @@ -0,0 +1,60 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top" + } +} Index: tags/2.3.0/tests/RTT/ref/poly_triangle.net =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB Normal triangular polygons +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/poly_triangle.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/poly_triangle.png =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/poly_triangle.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/poly_triangle.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.png.text (revision 33253) @@ -0,0 +1,33 @@ +r6630 + +upper left triangle +121 pixels (100.833) wide +121 pixels (100.83) tall + +gap from lower left triangle to upper left triangle +29 pixels (24.166) horizontally +29 pixels (24.166) vertically + +lower left triangle +151 pixels (125.833) wide +151 pixels (125.833) tall + +gap from lower left triangle to far right piramid +29 pixels (24.166) + +far right piramid +151 pixels (125.833) height +301 pixels (250.833) base + +bottom triangle +331 pixels (275.833) across +211 pixels (175.833) up +top edge +332.4 pixels (277) long 5.18 degrees +side edge +213.1 pixels (177.5833) long 91.91 degrees +bottom edge +351.2 pixels (292.666) long 31.02 degrees + +(mil) + Index: tags/2.3.0/tests/RTT/ref/poly_triangle.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/poly_triangle.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/poly_triangle.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/poly_triangle.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/poly_triangle.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/poly_triangle.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/poly_triangle.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.svg (revision 33253) @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/poly_triangle.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/poly_triangle.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/poly_triangle.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: Normal triangular polygons - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/rat.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: a rat line - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/rat.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.dsn (revision 33253) @@ -0,0 +1,54 @@ +(pcb a rat line + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "gEDA pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "comp1" + (type signal) + ) + (layer "inner1" + (type signal) + ) + (layer "inner2" + (type signal) + ) + (layer "solder1" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + (padstack via_685800_381000 + (shape (circle signal 0.685800)) + (attach off) + ) + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/rat.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.eps (revision 33253) @@ -0,0 +1,31 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: rat.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +% Layer topsilk group 1 drill 0 mask 0 +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/rat.exc/rat.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.exc/rat.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.exc/rat.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/rat.exc/rat.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.exc/rat.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.exc/rat.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/rat.gbr/rat.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.gbr/rat.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.gbr/rat.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 2 for group 9 layer_idx 6 * +G04 Title: a rat line, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD11C,0.0100*% +G54D11*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/rat.gbr/rat.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.gbr/rat.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.gbr/rat.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1705 @@ +G04 start of page 3 for group -1 layer_idx 268435461 * +G04 Title: a rat line, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD14C,0.0100*% +%ADD13C,0.0001*% +%ADD12C,0.0060*% +G54D12*X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D13*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D12*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D13*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D12*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D13*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D12*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D13*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D12*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D13*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D12*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D13*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G36* +X48000D02*X52500D01* +Y134000D01* +X48000D01* +Y140000D01* +G37* +G36* +X56100D02*X60600D01* +Y134000D01* +X56100D01* +Y140000D01* +G37* +G36* +X61500D02*X66000D01* +Y134000D01* +X61500D01* +Y140000D01* +G37* +G36* +X66900D02*X71400D01* +Y134000D01* +X66900D01* +Y140000D01* +G37* +G36* +X72300D02*X76800D01* +Y134000D01* +X72300D01* +Y140000D01* +G37* +G36* +X77700D02*X82200D01* +Y134000D01* +X77700D01* +Y140000D01* +G37* +G36* +X83100D02*X87600D01* +Y134000D01* +X83100D01* +Y140000D01* +G37* +G36* +X88500D02*X93000D01* +Y134000D01* +X88500D01* +Y140000D01* +G37* +G36* +X93900D02*X98400D01* +Y134000D01* +X93900D01* +Y140000D01* +G37* +G36* +X99300D02*X103800D01* +Y134000D01* +X99300D01* +Y140000D01* +G37* +G36* +X107400D02*X111900D01* +Y134000D01* +X107400D01* +Y140000D01* +G37* +G36* +X112800D02*X117300D01* +Y134000D01* +X112800D01* +Y140000D01* +G37* +G36* +X118200D02*X122700D01* +Y134000D01* +X118200D01* +Y140000D01* +G37* +G36* +X123600D02*X128100D01* +Y134000D01* +X123600D01* +Y140000D01* +G37* +G36* +X129000D02*X133500D01* +Y134000D01* +X129000D01* +Y140000D01* +G37* +G36* +X137100D02*X141600D01* +Y134000D01* +X137100D01* +Y140000D01* +G37* +G36* +X142500D02*X147000D01* +Y134000D01* +X142500D01* +Y140000D01* +G37* +G36* +X147900D02*X152400D01* +Y134000D01* +X147900D01* +Y140000D01* +G37* +G36* +X153300D02*X157800D01* +Y134000D01* +X153300D01* +Y140000D01* +G37* +G36* +X158700D02*X163200D01* +Y134000D01* +X158700D01* +Y140000D01* +G37* +G36* +X166800D02*X171300D01* +Y134000D01* +X166800D01* +Y140000D01* +G37* +G36* +X172200D02*X176700D01* +Y134000D01* +X172200D01* +Y140000D01* +G37* +G36* +X177600D02*X182100D01* +Y134000D01* +X177600D01* +Y140000D01* +G37* +G36* +X183000D02*X187500D01* +Y134000D01* +X183000D01* +Y140000D01* +G37* +G36* +X191100D02*X195600D01* +Y134000D01* +X191100D01* +Y140000D01* +G37* +G36* +X196500D02*X201000D01* +Y134000D01* +X196500D01* +Y140000D01* +G37* +G36* +X204600D02*X209100D01* +Y134000D01* +X204600D01* +Y140000D01* +G37* +G36* +X210000D02*X214500D01* +Y134000D01* +X210000D01* +Y140000D01* +G37* +G36* +X215400D02*X219900D01* +Y134000D01* +X215400D01* +Y140000D01* +G37* +G36* +X220800D02*X225300D01* +Y134000D01* +X220800D01* +Y140000D01* +G37* +G36* +X228900D02*X233400D01* +Y134000D01* +X228900D01* +Y140000D01* +G37* +G36* +X234300D02*X238800D01* +Y134000D01* +X234300D01* +Y140000D01* +G37* +G36* +X239700D02*X244200D01* +Y134000D01* +X239700D01* +Y140000D01* +G37* +G36* +X245100D02*X249600D01* +Y134000D01* +X245100D01* +Y140000D01* +G37* +G36* +X250500D02*X255000D01* +Y134000D01* +X250500D01* +Y140000D01* +G37* +G36* +X255900D02*X260400D01* +Y134000D01* +X255900D01* +Y140000D01* +G37* +G36* +X261300D02*X265800D01* +Y134000D01* +X261300D01* +Y140000D01* +G37* +G36* +X269400D02*X273900D01* +Y134000D01* +X269400D01* +Y140000D01* +G37* +G36* +X277500D02*X282000D01* +Y134000D01* +X277500D01* +Y140000D01* +G37* +G36* +X282900D02*X287400D01* +Y134000D01* +X282900D01* +Y140000D01* +G37* +G36* +X288300D02*X292800D01* +Y134000D01* +X288300D01* +Y140000D01* +G37* +G36* +X293700D02*X298200D01* +Y134000D01* +X293700D01* +Y140000D01* +G37* +G36* +X299100D02*X303600D01* +Y134000D01* +X299100D01* +Y140000D01* +G37* +G36* +X307200D02*X311700D01* +Y134000D01* +X307200D01* +Y140000D01* +G37* +G36* +X312600D02*X317100D01* +Y134000D01* +X312600D01* +Y140000D01* +G37* +G36* +X318000D02*X322500D01* +Y134000D01* +X318000D01* +Y140000D01* +G37* +G36* +X323400D02*X327900D01* +Y134000D01* +X323400D01* +Y140000D01* +G37* +G36* +X328800D02*X333300D01* +Y134000D01* +X328800D01* +Y140000D01* +G37* +G54D14*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D12*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D13*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D12*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D13*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D12*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D13*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D12*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D13*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D12*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D13*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D12*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D13*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D12*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D13*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D12*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D13*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D12*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D13*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D12*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D13*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D12*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D13*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X242600D02*X247100D01* +Y104000D01* +X242600D01* +Y110000D01* +G37* +G36* +X248000D02*X252500D01* +Y104000D01* +X248000D01* +Y110000D01* +G37* +G36* +X253400D02*X257900D01* +Y104000D01* +X253400D01* +Y110000D01* +G37* +G36* +X261500D02*X266000D01* +Y104000D01* +X261500D01* +Y110000D01* +G37* +G36* +X266900D02*X271400D01* +Y104000D01* +X266900D01* +Y110000D01* +G37* +G36* +X272300D02*X276800D01* +Y104000D01* +X272300D01* +Y110000D01* +G37* +G36* +X277700D02*X282200D01* +Y104000D01* +X277700D01* +Y110000D01* +G37* +G36* +X285800D02*X290300D01* +Y104000D01* +X285800D01* +Y110000D01* +G37* +G54D12*X293900D02*Y104000D01* +Y110000D02*X296900D01* +X293900Y107300D02*X296150D01* +G54D13*G36* +X298700Y110000D02*X303200D01* +Y104000D01* +X298700D01* +Y110000D01* +G37* +G36* +X304100D02*X308600D01* +Y104000D01* +X304100D01* +Y110000D01* +G37* +G36* +X309500D02*X314000D01* +Y104000D01* +X309500D01* +Y110000D01* +G37* +G36* +X314900D02*X319400D01* +Y104000D01* +X314900D01* +Y110000D01* +G37* +G36* +X320300D02*X324800D01* +Y104000D01* +X320300D01* +Y110000D01* +G37* +G36* +X325700D02*X330200D01* +Y104000D01* +X325700D01* +Y110000D01* +G37* +G36* +X331100D02*X335600D01* +Y104000D01* +X331100D01* +Y110000D01* +G37* +G36* +X336500D02*X341000D01* +Y104000D01* +X336500D01* +Y110000D01* +G37* +G36* +X341900D02*X346400D01* +Y104000D01* +X341900D01* +Y110000D01* +G37* +G36* +X347300D02*X351800D01* +Y104000D01* +X347300D01* +Y110000D01* +G37* +G54D12*X356150D02*Y104000D01* +X358100Y110000D02*X359150Y108950D01* +Y105050D01* +X358100Y104000D02*X359150Y105050D01* +X355400Y104000D02*X358100D01* +X355400Y110000D02*X358100D01* +G54D13*G36* +X360950D02*X365450D01* +Y104000D01* +X360950D01* +Y110000D01* +G37* +G36* +X366350D02*X370850D01* +Y104000D01* +X366350D01* +Y110000D01* +G37* +G36* +X371750D02*X376250D01* +Y104000D01* +X371750D01* +Y110000D01* +G37* +G36* +X377150D02*X381650D01* +Y104000D01* +X377150D01* +Y110000D01* +G37* +G36* +X382550D02*X387050D01* +Y104000D01* +X382550D01* +Y110000D01* +G37* +G36* +X387950D02*X392450D01* +Y104000D01* +X387950D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/rat.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.nelma.em (revision 33253) @@ -0,0 +1,51 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/rat.net =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB a rat line +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/rat.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/rat.png =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/rat.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/rat.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.png.text (revision 33253) @@ -0,0 +1,6 @@ +r6731 + +outline thickness 6 x 7 pixels (top/left) (5/5.833) + +outline (inside lines) 587 x 589 pixels (489.167 x 490.833) + Index: tags/2.3.0/tests/RTT/ref/rat.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/rat.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/rat.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/rat.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/rat.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/rat.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/rat.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.svg (revision 33253) @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/rat.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/rat.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/rat.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: a rat line - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/text_rot.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: text rotations - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/text_rot.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb text rotations + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/text_rot.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.eps (revision 33253) @@ -0,0 +1,81 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: text_rot.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +% Layer topsilk group 1 drill 0 mask 0 +0.00700 setlinewidth +1 setlinecap +0 0 0 setrgbcolor +0.22500 0.16000 0.22500 0.19000 t +0.22500 0.16000 0.23200 0.15000 t +0.23200 0.15000 0.24300 0.15000 t +0.24300 0.15000 0.25000 0.16000 t +0.25000 0.16000 0.25000 0.19000 t +0.22500 0.17000 0.25000 0.17000 t +0.26200 0.15800 0.27000 0.15000 t +0.27000 0.15000 0.27000 0.19000 t +0.26200 0.19000 0.27700 0.19000 t +0.16000 0.27500 0.19000 0.27500 t +0.16000 0.27500 0.15000 0.26800 t +0.15000 0.26800 0.15000 0.25700 t +0.15000 0.25700 0.16000 0.25000 t +0.16000 0.25000 0.19000 0.25000 t +0.17000 0.27500 0.17000 0.25000 t +0.15500 0.23800 0.15000 0.23300 t +0.15000 0.23300 0.15000 0.21800 t +0.15000 0.21800 0.15500 0.21300 t +0.15500 0.21300 0.16500 0.21300 t +0.19000 0.23800 0.16500 0.21300 t +0.19000 0.23800 0.19000 0.21300 t +0.27500 0.34000 0.27500 0.31000 t +0.27500 0.34000 0.26800 0.35000 t +0.26800 0.35000 0.25700 0.35000 t +0.25700 0.35000 0.25000 0.34000 t +0.25000 0.34000 0.25000 0.31000 t +0.27500 0.33000 0.25000 0.33000 t +0.23800 0.34500 0.23300 0.35000 t +0.23300 0.35000 0.22300 0.35000 t +0.22300 0.35000 0.21800 0.34500 t +0.22300 0.31000 0.21800 0.31500 t +0.23300 0.31000 0.22300 0.31000 t +0.23800 0.31500 0.23300 0.31000 t +0.23300 0.33200 0.22300 0.33200 t +0.21800 0.34500 0.21800 0.33700 t +0.21800 0.32700 0.21800 0.31500 t +0.21800 0.32700 0.22300 0.33200 t +0.21800 0.33700 0.22300 0.33200 t +0.34000 0.22500 0.31000 0.22500 t +0.34000 0.22500 0.35000 0.23200 t +0.35000 0.23200 0.35000 0.24300 t +0.35000 0.24300 0.34000 0.25000 t +0.34000 0.25000 0.31000 0.25000 t +0.33000 0.22500 0.33000 0.25000 t +0.32500 0.26200 0.35000 0.28200 t +0.32500 0.26200 0.32500 0.28700 t +0.35000 0.28200 0.31000 0.28200 t +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/text_rot.exc/text_rot.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.exc/text_rot.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.exc/text_rot.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/text_rot.exc/text_rot.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.exc/text_rot.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.exc/text_rot.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/text_rot.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.fcd (revision 33253) @@ -0,0 +1,5 @@ +[FIDOCAD] +TY 45 30 7 5 0 1 3 * A1 +TY 30 55 7 5 90 1 3 * A2 +TY 55 70 7 5 180 1 3 * A3 +TY 70 45 7 5 270 1 3 * A4 Index: tags/2.3.0/tests/RTT/ref/text_rot.gbr/text_rot.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.gbr/text_rot.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.gbr/text_rot.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: text rotations, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD12C,0.0100*% +G54D12*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/text_rot.gbr/text_rot.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.gbr/text_rot.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.gbr/text_rot.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1974 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: text rotations, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD16C,0.0060*% +%ADD15C,0.0100*% +%ADD14C,0.0080*% +%ADD13C,0.0001*% +G54D13*G36* +X0Y125000D02*X3750D01* +Y117500D01* +X0D01* +Y125000D01* +G37* +G36* +X4500D02*X8250D01* +Y117500D01* +X4500D01* +Y125000D01* +G37* +G36* +X9000D02*X12750D01* +Y117500D01* +X9000D01* +Y125000D01* +G37* +G36* +X13500D02*X17250D01* +Y117500D01* +X13500D01* +Y125000D01* +G37* +G36* +X18000D02*X21750D01* +Y117500D01* +X18000D01* +Y125000D01* +G37* +G36* +X22500D02*X26250D01* +Y117500D01* +X22500D01* +Y125000D01* +G37* +G54D14*X0Y116500D03* +G54D13*G36* +X41000Y125000D02*X44750D01* +Y117500D01* +X41000D01* +Y125000D01* +G37* +G36* +X45500D02*X49250D01* +Y117500D01* +X45500D01* +Y125000D01* +G37* +G36* +X50000D02*X53750D01* +Y117500D01* +X50000D01* +Y125000D01* +G37* +G36* +X54500D02*X58250D01* +Y117500D01* +X54500D01* +Y125000D01* +G37* +G36* +X59000D02*X62750D01* +Y117500D01* +X59000D01* +Y125000D01* +G37* +G36* +X63500D02*X67250D01* +Y117500D01* +X63500D01* +Y125000D01* +G37* +G36* +X68000D02*X71750D01* +Y117500D01* +X68000D01* +Y125000D01* +G37* +G36* +X72500D02*X76250D01* +Y117500D01* +X72500D01* +Y125000D01* +G37* +G36* +X77000D02*X80750D01* +Y117500D01* +X77000D01* +Y125000D01* +G37* +G36* +X81500D02*X85250D01* +Y117500D01* +X81500D01* +Y125000D01* +G37* +G36* +X86000D02*X89750D01* +Y117500D01* +X86000D01* +Y125000D01* +G37* +G36* +X90500D02*X94250D01* +Y117500D01* +X90500D01* +Y125000D01* +G37* +G54D14*X41000Y116500D03* +G54D13*G36* +X95000Y125000D02*X98750D01* +Y117500D01* +X95000D01* +Y125000D01* +G37* +G36* +X99500D02*X103250D01* +Y117500D01* +X99500D01* +Y125000D01* +G37* +G36* +X104000D02*X107750D01* +Y117500D01* +X104000D01* +Y125000D01* +G37* +G36* +X108500D02*X112250D01* +Y117500D01* +X108500D01* +Y125000D01* +G37* +G36* +X113000D02*X116750D01* +Y117500D01* +X113000D01* +Y125000D01* +G37* +G54D14*X95000Y116500D03* +G54D13*G36* +X130000Y125000D02*X133750D01* +Y117500D01* +X130000D01* +Y125000D01* +G37* +G36* +X134500D02*X138250D01* +Y117500D01* +X134500D01* +Y125000D01* +G37* +G36* +X139000D02*X142750D01* +Y117500D01* +X139000D01* +Y125000D01* +G37* +G36* +X143500D02*X147250D01* +Y117500D01* +X143500D01* +Y125000D01* +G37* +G36* +X148000D02*X151750D01* +Y117500D01* +X148000D01* +Y125000D01* +G37* +G36* +X152500D02*X156250D01* +Y117500D01* +X152500D01* +Y125000D01* +G37* +G36* +X157000D02*X160750D01* +Y117500D01* +X157000D01* +Y125000D01* +G37* +G54D14*X130000Y116500D03* +G54D13*G36* +X0Y140000D02*X3750D01* +Y132500D01* +X0D01* +Y140000D01* +G37* +G36* +X4500D02*X8250D01* +Y132500D01* +X4500D01* +Y140000D01* +G37* +G36* +X9000D02*X12750D01* +Y132500D01* +X9000D01* +Y140000D01* +G37* +G36* +X13500D02*X17250D01* +Y132500D01* +X13500D01* +Y140000D01* +G37* +G36* +X18000D02*X21750D01* +Y132500D01* +X18000D01* +Y140000D01* +G37* +G36* +X22500D02*X26250D01* +Y132500D01* +X22500D01* +Y140000D01* +G37* +G36* +X27000D02*X30750D01* +Y132500D01* +X27000D01* +Y140000D01* +G37* +G36* +X31500D02*X35250D01* +Y132500D01* +X31500D01* +Y140000D01* +G37* +G36* +X36000D02*X39750D01* +Y132500D01* +X36000D01* +Y140000D01* +G37* +G36* +X40500D02*X44250D01* +Y132500D01* +X40500D01* +Y140000D01* +G37* +G36* +X45000D02*X48750D01* +Y132500D01* +X45000D01* +Y140000D01* +G37* +G36* +X49500D02*X53250D01* +Y132500D01* +X49500D01* +Y140000D01* +G37* +G36* +X54000D02*X57750D01* +Y132500D01* +X54000D01* +Y140000D01* +G37* +G36* +X58500D02*X62250D01* +Y132500D01* +X58500D01* +Y140000D01* +G37* +G36* +X63000D02*X66750D01* +Y132500D01* +X63000D01* +Y140000D01* +G37* +G36* +X67500D02*X71250D01* +Y132500D01* +X67500D01* +Y140000D01* +G37* +G36* +X72000D02*X75750D01* +Y132500D01* +X72000D01* +Y140000D01* +G37* +G36* +X76500D02*X80250D01* +Y132500D01* +X76500D01* +Y140000D01* +G37* +G36* +X81000D02*X84750D01* +Y132500D01* +X81000D01* +Y140000D01* +G37* +G36* +X85500D02*X89250D01* +Y132500D01* +X85500D01* +Y140000D01* +G37* +G36* +X90000D02*X93750D01* +Y132500D01* +X90000D01* +Y140000D01* +G37* +G36* +X94500D02*X98250D01* +Y132500D01* +X94500D01* +Y140000D01* +G37* +G36* +X99000D02*X102750D01* +Y132500D01* +X99000D01* +Y140000D01* +G37* +G36* +X103500D02*X107250D01* +Y132500D01* +X103500D01* +Y140000D01* +G37* +G36* +X108000D02*X111750D01* +Y132500D01* +X108000D01* +Y140000D01* +G37* +G36* +X112500D02*X116250D01* +Y132500D01* +X112500D01* +Y140000D01* +G37* +G36* +X117000D02*X120750D01* +Y132500D01* +X117000D01* +Y140000D01* +G37* +G36* +X121500D02*X125250D01* +Y132500D01* +X121500D01* +Y140000D01* +G37* +G36* +X126000D02*X129750D01* +Y132500D01* +X126000D01* +Y140000D01* +G37* +G36* +X130500D02*X134250D01* +Y132500D01* +X130500D01* +Y140000D01* +G37* +G36* +X135000D02*X138750D01* +Y132500D01* +X135000D01* +Y140000D01* +G37* +G36* +X139500D02*X143250D01* +Y132500D01* +X139500D01* +Y140000D01* +G37* +G36* +X144000D02*X147750D01* +Y132500D01* +X144000D01* +Y140000D01* +G37* +G36* +X148500D02*X152250D01* +Y132500D01* +X148500D01* +Y140000D01* +G37* +G36* +X153000D02*X156750D01* +Y132500D01* +X153000D01* +Y140000D01* +G37* +G36* +X157500D02*X161250D01* +Y132500D01* +X157500D01* +Y140000D01* +G37* +G36* +X162000D02*X165750D01* +Y132500D01* +X162000D01* +Y140000D01* +G37* +G36* +X166500D02*X170250D01* +Y132500D01* +X166500D01* +Y140000D01* +G37* +G36* +X171000D02*X174750D01* +Y132500D01* +X171000D01* +Y140000D01* +G37* +G36* +X175500D02*X179250D01* +Y132500D01* +X175500D01* +Y140000D01* +G37* +G36* +X180000D02*X183750D01* +Y132500D01* +X180000D01* +Y140000D01* +G37* +G36* +X184500D02*X188250D01* +Y132500D01* +X184500D01* +Y140000D01* +G37* +G36* +X189000D02*X192750D01* +Y132500D01* +X189000D01* +Y140000D01* +G37* +G36* +X193500D02*X197250D01* +Y132500D01* +X193500D01* +Y140000D01* +G37* +G36* +X198000D02*X201750D01* +Y132500D01* +X198000D01* +Y140000D01* +G37* +G36* +X202500D02*X206250D01* +Y132500D01* +X202500D01* +Y140000D01* +G37* +G36* +X207000D02*X210750D01* +Y132500D01* +X207000D01* +Y140000D01* +G37* +G36* +X211500D02*X215250D01* +Y132500D01* +X211500D01* +Y140000D01* +G37* +G36* +X216000D02*X219750D01* +Y132500D01* +X216000D01* +Y140000D01* +G37* +G36* +X220500D02*X224250D01* +Y132500D01* +X220500D01* +Y140000D01* +G37* +G36* +X225000D02*X228750D01* +Y132500D01* +X225000D01* +Y140000D01* +G37* +G36* +X229500D02*X233250D01* +Y132500D01* +X229500D01* +Y140000D01* +G37* +G36* +X234000D02*X237750D01* +Y132500D01* +X234000D01* +Y140000D01* +G37* +G36* +X238500D02*X242250D01* +Y132500D01* +X238500D01* +Y140000D01* +G37* +G36* +X243000D02*X246750D01* +Y132500D01* +X243000D01* +Y140000D01* +G37* +G36* +X247500D02*X251250D01* +Y132500D01* +X247500D01* +Y140000D01* +G37* +G36* +X252000D02*X255750D01* +Y132500D01* +X252000D01* +Y140000D01* +G37* +G36* +X256500D02*X260250D01* +Y132500D01* +X256500D01* +Y140000D01* +G37* +G36* +X261000D02*X264750D01* +Y132500D01* +X261000D01* +Y140000D01* +G37* +G36* +X265500D02*X269250D01* +Y132500D01* +X265500D01* +Y140000D01* +G37* +G36* +X270000D02*X273750D01* +Y132500D01* +X270000D01* +Y140000D01* +G37* +G36* +X274500D02*X278250D01* +Y132500D01* +X274500D01* +Y140000D01* +G37* +G36* +X279000D02*X282750D01* +Y132500D01* +X279000D01* +Y140000D01* +G37* +G36* +X283500D02*X287250D01* +Y132500D01* +X283500D01* +Y140000D01* +G37* +G36* +X288000D02*X291750D01* +Y132500D01* +X288000D01* +Y140000D01* +G37* +G36* +X292500D02*X296250D01* +Y132500D01* +X292500D01* +Y140000D01* +G37* +G36* +X297000D02*X300750D01* +Y132500D01* +X297000D01* +Y140000D01* +G37* +G36* +X301500D02*X305250D01* +Y132500D01* +X301500D01* +Y140000D01* +G37* +G54D15*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D13*G36* +X200000Y65000D02*X203750D01* +Y57500D01* +X200000D01* +Y65000D01* +G37* +G36* +X204500D02*X208250D01* +Y57500D01* +X204500D01* +Y65000D01* +G37* +G36* +X209000D02*X212750D01* +Y57500D01* +X209000D01* +Y65000D01* +G37* +G36* +X213500D02*X217250D01* +Y57500D01* +X213500D01* +Y65000D01* +G37* +G36* +X218000D02*X221750D01* +Y57500D01* +X218000D01* +Y65000D01* +G37* +G36* +X222500D02*X226250D01* +Y57500D01* +X222500D01* +Y65000D01* +G37* +G36* +X227000D02*X230750D01* +Y57500D01* +X227000D01* +Y65000D01* +G37* +G36* +X231500D02*X235250D01* +Y57500D01* +X231500D01* +Y65000D01* +G37* +G36* +X236000D02*X239750D01* +Y57500D01* +X236000D01* +Y65000D01* +G37* +G36* +X240500D02*X244250D01* +Y57500D01* +X240500D01* +Y65000D01* +G37* +G36* +X245000D02*X248750D01* +Y57500D01* +X245000D01* +Y65000D01* +G37* +G36* +X249500D02*X253250D01* +Y57500D01* +X249500D01* +Y65000D01* +G37* +G36* +X254000D02*X257750D01* +Y57500D01* +X254000D01* +Y65000D01* +G37* +G36* +X258500D02*X262250D01* +Y57500D01* +X258500D01* +Y65000D01* +G37* +G36* +X263000D02*X266750D01* +Y57500D01* +X263000D01* +Y65000D01* +G37* +G36* +X267500D02*X271250D01* +Y57500D01* +X267500D01* +Y65000D01* +G37* +G36* +X272000D02*X275750D01* +Y57500D01* +X272000D01* +Y65000D01* +G37* +G36* +X276500D02*X280250D01* +Y57500D01* +X276500D01* +Y65000D01* +G37* +G36* +X281000D02*X284750D01* +Y57500D01* +X281000D01* +Y65000D01* +G37* +G36* +X285500D02*X289250D01* +Y57500D01* +X285500D01* +Y65000D01* +G37* +G36* +X290000D02*X293750D01* +Y57500D01* +X290000D01* +Y65000D01* +G37* +G36* +X294500D02*X298250D01* +Y57500D01* +X294500D01* +Y65000D01* +G37* +G36* +X299000D02*X302750D01* +Y57500D01* +X299000D01* +Y65000D01* +G37* +G36* +X303500D02*X307250D01* +Y57500D01* +X303500D01* +Y65000D01* +G37* +G36* +X308000D02*X311750D01* +Y57500D01* +X308000D01* +Y65000D01* +G37* +G36* +X312500D02*X316250D01* +Y57500D01* +X312500D01* +Y65000D01* +G37* +G36* +X317000D02*X320750D01* +Y57500D01* +X317000D01* +Y65000D01* +G37* +G36* +X321500D02*X325250D01* +Y57500D01* +X321500D01* +Y65000D01* +G37* +G36* +X326000D02*X329750D01* +Y57500D01* +X326000D01* +Y65000D01* +G37* +G36* +X330500D02*X334250D01* +Y57500D01* +X330500D01* +Y65000D01* +G37* +G36* +X335000D02*X338750D01* +Y57500D01* +X335000D01* +Y65000D01* +G37* +G36* +X339500D02*X343250D01* +Y57500D01* +X339500D01* +Y65000D01* +G37* +G36* +X344000D02*X347750D01* +Y57500D01* +X344000D01* +Y65000D01* +G37* +G36* +X348500D02*X352250D01* +Y57500D01* +X348500D01* +Y65000D01* +G37* +G36* +X353000D02*X356750D01* +Y57500D01* +X353000D01* +Y65000D01* +G37* +G36* +X357500D02*X361250D01* +Y57500D01* +X357500D01* +Y65000D01* +G37* +G36* +X362000D02*X365750D01* +Y57500D01* +X362000D01* +Y65000D01* +G37* +G36* +X366500D02*X370250D01* +Y57500D01* +X366500D01* +Y65000D01* +G37* +G36* +X371000D02*X374750D01* +Y57500D01* +X371000D01* +Y65000D01* +G37* +G36* +X375500D02*X379250D01* +Y57500D01* +X375500D01* +Y65000D01* +G37* +G36* +X380000D02*X383750D01* +Y57500D01* +X380000D01* +Y65000D01* +G37* +G36* +X384500D02*X388250D01* +Y57500D01* +X384500D01* +Y65000D01* +G37* +G36* +X389000D02*X392750D01* +Y57500D01* +X389000D01* +Y65000D01* +G37* +G36* +X393500D02*X397250D01* +Y57500D01* +X393500D01* +Y65000D01* +G37* +G36* +X398000D02*X401750D01* +Y57500D01* +X398000D01* +Y65000D01* +G37* +G36* +X402500D02*X406250D01* +Y57500D01* +X402500D01* +Y65000D01* +G37* +G36* +X407000D02*X410750D01* +Y57500D01* +X407000D01* +Y65000D01* +G37* +G36* +X411500D02*X415250D01* +Y57500D01* +X411500D01* +Y65000D01* +G37* +G36* +X416000D02*X419750D01* +Y57500D01* +X416000D01* +Y65000D01* +G37* +G36* +X420500D02*X424250D01* +Y57500D01* +X420500D01* +Y65000D01* +G37* +G36* +X425000D02*X428750D01* +Y57500D01* +X425000D01* +Y65000D01* +G37* +G36* +X429500D02*X433250D01* +Y57500D01* +X429500D01* +Y65000D01* +G37* +G36* +X434000D02*X437750D01* +Y57500D01* +X434000D01* +Y65000D01* +G37* +G36* +X438500D02*X442250D01* +Y57500D01* +X438500D01* +Y65000D01* +G37* +G36* +X443000D02*X446750D01* +Y57500D01* +X443000D01* +Y65000D01* +G37* +G36* +X447500D02*X451250D01* +Y57500D01* +X447500D01* +Y65000D01* +G37* +G36* +X452000D02*X455750D01* +Y57500D01* +X452000D01* +Y65000D01* +G37* +G36* +X456500D02*X460250D01* +Y57500D01* +X456500D01* +Y65000D01* +G37* +G36* +X461000D02*X464750D01* +Y57500D01* +X461000D01* +Y65000D01* +G37* +G36* +X465500D02*X469250D01* +Y57500D01* +X465500D01* +Y65000D01* +G37* +G36* +X470000D02*X473750D01* +Y57500D01* +X470000D01* +Y65000D01* +G37* +G36* +X474500D02*X478250D01* +Y57500D01* +X474500D01* +Y65000D01* +G37* +G36* +X25000Y-2000D02*X28750D01* +Y-9500D01* +X25000D01* +Y-2000D01* +G37* +G36* +X29500D02*X33250D01* +Y-9500D01* +X29500D01* +Y-2000D01* +G37* +G36* +X34000D02*X37750D01* +Y-9500D01* +X34000D01* +Y-2000D01* +G37* +G36* +X38500D02*X42250D01* +Y-9500D01* +X38500D01* +Y-2000D01* +G37* +G36* +X43000D02*X46750D01* +Y-9500D01* +X43000D01* +Y-2000D01* +G37* +G36* +X47500D02*X51250D01* +Y-9500D01* +X47500D01* +Y-2000D01* +G37* +G36* +X52000D02*X55750D01* +Y-9500D01* +X52000D01* +Y-2000D01* +G37* +G36* +X56500D02*X60250D01* +Y-9500D01* +X56500D01* +Y-2000D01* +G37* +G36* +X61000D02*X64750D01* +Y-9500D01* +X61000D01* +Y-2000D01* +G37* +G36* +X65500D02*X69250D01* +Y-9500D01* +X65500D01* +Y-2000D01* +G37* +G36* +X70000D02*X73750D01* +Y-9500D01* +X70000D01* +Y-2000D01* +G37* +G36* +X74500D02*X78250D01* +Y-9500D01* +X74500D01* +Y-2000D01* +G37* +G36* +X79000D02*X82750D01* +Y-9500D01* +X79000D01* +Y-2000D01* +G37* +G36* +X83500D02*X87250D01* +Y-9500D01* +X83500D01* +Y-2000D01* +G37* +G36* +X88000D02*X91750D01* +Y-9500D01* +X88000D01* +Y-2000D01* +G37* +G36* +X92500D02*X96250D01* +Y-9500D01* +X92500D01* +Y-2000D01* +G37* +G36* +X97000D02*X100750D01* +Y-9500D01* +X97000D01* +Y-2000D01* +G37* +G36* +X101500D02*X105250D01* +Y-9500D01* +X101500D01* +Y-2000D01* +G37* +G36* +X106000D02*X109750D01* +Y-9500D01* +X106000D01* +Y-2000D01* +G37* +G36* +X110500D02*X114250D01* +Y-9500D01* +X110500D01* +Y-2000D01* +G37* +G36* +X115000D02*X118750D01* +Y-9500D01* +X115000D01* +Y-2000D01* +G37* +G36* +X119500D02*X123250D01* +Y-9500D01* +X119500D01* +Y-2000D01* +G37* +G36* +X124000D02*X127750D01* +Y-9500D01* +X124000D01* +Y-2000D01* +G37* +G36* +X128500D02*X132250D01* +Y-9500D01* +X128500D01* +Y-2000D01* +G37* +G36* +X133000D02*X136750D01* +Y-9500D01* +X133000D01* +Y-2000D01* +G37* +G36* +X137500D02*X141250D01* +Y-9500D01* +X137500D01* +Y-2000D01* +G37* +G36* +X142000D02*X145750D01* +Y-9500D01* +X142000D01* +Y-2000D01* +G37* +G36* +X146500D02*X150250D01* +Y-9500D01* +X146500D01* +Y-2000D01* +G37* +G36* +X151000D02*X154750D01* +Y-9500D01* +X151000D01* +Y-2000D01* +G37* +G36* +X155500D02*X159250D01* +Y-9500D01* +X155500D01* +Y-2000D01* +G37* +G36* +X160000D02*X163750D01* +Y-9500D01* +X160000D01* +Y-2000D01* +G37* +G36* +X164500D02*X168250D01* +Y-9500D01* +X164500D01* +Y-2000D01* +G37* +G36* +X169000D02*X172750D01* +Y-9500D01* +X169000D01* +Y-2000D01* +G37* +G36* +X173500D02*X177250D01* +Y-9500D01* +X173500D01* +Y-2000D01* +G37* +G36* +X178000D02*X181750D01* +Y-9500D01* +X178000D01* +Y-2000D01* +G37* +G36* +X182500D02*X186250D01* +Y-9500D01* +X182500D01* +Y-2000D01* +G37* +G36* +X187000D02*X190750D01* +Y-9500D01* +X187000D01* +Y-2000D01* +G37* +G36* +X191500D02*X195250D01* +Y-9500D01* +X191500D01* +Y-2000D01* +G37* +G36* +X196000D02*X199750D01* +Y-9500D01* +X196000D01* +Y-2000D01* +G37* +G36* +X200500D02*X204250D01* +Y-9500D01* +X200500D01* +Y-2000D01* +G37* +G36* +X205000D02*X208750D01* +Y-9500D01* +X205000D01* +Y-2000D01* +G37* +G36* +X209500D02*X213250D01* +Y-9500D01* +X209500D01* +Y-2000D01* +G37* +G36* +X214000D02*X217750D01* +Y-9500D01* +X214000D01* +Y-2000D01* +G37* +G36* +X218500D02*X222250D01* +Y-9500D01* +X218500D01* +Y-2000D01* +G37* +G36* +X223000D02*X226750D01* +Y-9500D01* +X223000D01* +Y-2000D01* +G37* +G36* +X227500D02*X231250D01* +Y-9500D01* +X227500D01* +Y-2000D01* +G37* +G36* +X232000D02*X235750D01* +Y-9500D01* +X232000D01* +Y-2000D01* +G37* +G36* +X236500D02*X240250D01* +Y-9500D01* +X236500D01* +Y-2000D01* +G37* +G36* +X241000D02*X244750D01* +Y-9500D01* +X241000D01* +Y-2000D01* +G37* +G36* +X245500D02*X249250D01* +Y-9500D01* +X245500D01* +Y-2000D01* +G37* +G36* +X250000D02*X253750D01* +Y-9500D01* +X250000D01* +Y-2000D01* +G37* +G36* +X254500D02*X258250D01* +Y-9500D01* +X254500D01* +Y-2000D01* +G37* +G36* +X259000D02*X262750D01* +Y-9500D01* +X259000D01* +Y-2000D01* +G37* +G36* +X263500D02*X267250D01* +Y-9500D01* +X263500D01* +Y-2000D01* +G37* +G36* +X268000D02*X271750D01* +Y-9500D01* +X268000D01* +Y-2000D01* +G37* +G36* +X272500D02*X276250D01* +Y-9500D01* +X272500D01* +Y-2000D01* +G37* +G36* +X277000D02*X280750D01* +Y-9500D01* +X277000D01* +Y-2000D01* +G37* +G36* +X281500D02*X285250D01* +Y-9500D01* +X281500D01* +Y-2000D01* +G37* +G36* +X286000D02*X289750D01* +Y-9500D01* +X286000D01* +Y-2000D01* +G37* +G36* +X290500D02*X294250D01* +Y-9500D01* +X290500D01* +Y-2000D01* +G37* +G36* +X295000D02*X298750D01* +Y-9500D01* +X295000D01* +Y-2000D01* +G37* +G36* +X299500D02*X303250D01* +Y-9500D01* +X299500D01* +Y-2000D01* +G37* +G36* +X304000D02*X307750D01* +Y-9500D01* +X304000D01* +Y-2000D01* +G37* +G36* +X308500D02*X312250D01* +Y-9500D01* +X308500D01* +Y-2000D01* +G37* +G36* +X313000D02*X316750D01* +Y-9500D01* +X313000D01* +Y-2000D01* +G37* +G36* +X317500D02*X321250D01* +Y-9500D01* +X317500D01* +Y-2000D01* +G37* +G36* +X322000D02*X325750D01* +Y-9500D01* +X322000D01* +Y-2000D01* +G37* +G36* +X326500D02*X330250D01* +Y-9500D01* +X326500D01* +Y-2000D01* +G37* +G36* +X331000D02*X334750D01* +Y-9500D01* +X331000D01* +Y-2000D01* +G37* +G36* +X335500D02*X339250D01* +Y-9500D01* +X335500D01* +Y-2000D01* +G37* +G36* +X340000D02*X343750D01* +Y-9500D01* +X340000D01* +Y-2000D01* +G37* +G36* +X344500D02*X348250D01* +Y-9500D01* +X344500D01* +Y-2000D01* +G37* +G36* +X349000D02*X352750D01* +Y-9500D01* +X349000D01* +Y-2000D01* +G37* +G36* +X353500D02*X357250D01* +Y-9500D01* +X353500D01* +Y-2000D01* +G37* +G36* +X358000D02*X361750D01* +Y-9500D01* +X358000D01* +Y-2000D01* +G37* +G36* +X362500D02*X366250D01* +Y-9500D01* +X362500D01* +Y-2000D01* +G37* +G36* +X367000D02*X370750D01* +Y-9500D01* +X367000D01* +Y-2000D01* +G37* +G36* +X371500D02*X375250D01* +Y-9500D01* +X371500D01* +Y-2000D01* +G37* +G36* +X376000D02*X379750D01* +Y-9500D01* +X376000D01* +Y-2000D01* +G37* +G36* +X380500D02*X384250D01* +Y-9500D01* +X380500D01* +Y-2000D01* +G37* +G36* +X385000D02*X388750D01* +Y-9500D01* +X385000D01* +Y-2000D01* +G37* +G36* +X389500D02*X393250D01* +Y-9500D01* +X389500D01* +Y-2000D01* +G37* +G36* +X394000D02*X397750D01* +Y-9500D01* +X394000D01* +Y-2000D01* +G37* +G36* +X398500D02*X402250D01* +Y-9500D01* +X398500D01* +Y-2000D01* +G37* +G36* +X403000D02*X406751D01* +Y-9500D01* +X403000D01* +Y-2000D01* +G37* +G36* +X407501D02*X411251D01* +Y-9500D01* +X407501D01* +Y-2000D01* +G37* +G36* +X412001D02*X415751D01* +Y-9500D01* +X412001D01* +Y-2000D01* +G37* +G36* +X416501D02*X420251D01* +Y-9500D01* +X416501D01* +Y-2000D01* +G37* +G36* +X421001D02*X424751D01* +Y-9500D01* +X421001D01* +Y-2000D01* +G37* +G36* +X425501D02*X429251D01* +Y-9500D01* +X425501D01* +Y-2000D01* +G37* +G36* +X430001D02*X433751D01* +Y-9500D01* +X430001D01* +Y-2000D01* +G37* +G36* +X434501D02*X438251D01* +Y-9500D01* +X434501D01* +Y-2000D01* +G37* +G36* +X439001D02*X442751D01* +Y-9500D01* +X439001D01* +Y-2000D01* +G37* +G36* +X443501D02*X447251D01* +Y-9500D01* +X443501D01* +Y-2000D01* +G37* +G36* +X448001D02*X451751D01* +Y-9500D01* +X448001D01* +Y-2000D01* +G37* +G36* +X452501D02*X456251D01* +Y-9500D01* +X452501D01* +Y-2000D01* +G37* +G36* +X457001D02*X460751D01* +Y-9500D01* +X457001D01* +Y-2000D01* +G37* +G36* +X461501D02*X465251D01* +Y-9500D01* +X461501D01* +Y-2000D01* +G37* +G36* +X200000Y80000D02*X203750D01* +Y72500D01* +X200000D01* +Y80000D01* +G37* +G36* +X204500D02*X208250D01* +Y72500D01* +X204500D01* +Y80000D01* +G37* +G36* +X209000D02*X212750D01* +Y72500D01* +X209000D01* +Y80000D01* +G37* +G36* +X213500D02*X217250D01* +Y72500D01* +X213500D01* +Y80000D01* +G37* +G36* +X218000D02*X221750D01* +Y72500D01* +X218000D01* +Y80000D01* +G37* +G36* +X222500D02*X226250D01* +Y72500D01* +X222500D01* +Y80000D01* +G37* +G36* +X227000D02*X230750D01* +Y72500D01* +X227000D01* +Y80000D01* +G37* +G36* +X231500D02*X235250D01* +Y72500D01* +X231500D01* +Y80000D01* +G37* +G36* +X236000D02*X239750D01* +Y72500D01* +X236000D01* +Y80000D01* +G37* +G36* +X240500D02*X244250D01* +Y72500D01* +X240500D01* +Y80000D01* +G37* +G36* +X245000D02*X248750D01* +Y72500D01* +X245000D01* +Y80000D01* +G37* +G36* +X249500D02*X253250D01* +Y72500D01* +X249500D01* +Y80000D01* +G37* +G54D16*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D13*G36* +X205550Y95000D02*X209300D01* +Y87500D01* +X205550D01* +Y95000D01* +G37* +G36* +X210050D02*X213800D01* +Y87500D01* +X210050D01* +Y95000D01* +G37* +G36* +X214550D02*X218300D01* +Y87500D01* +X214550D01* +Y95000D01* +G37* +G36* +X219050D02*X222800D01* +Y87500D01* +X219050D01* +Y95000D01* +G37* +G36* +X223550D02*X227300D01* +Y87500D01* +X223550D01* +Y95000D01* +G37* +G36* +X228050D02*X231800D01* +Y87500D01* +X228050D01* +Y95000D01* +G37* +G36* +X232550D02*X236300D01* +Y87500D01* +X232550D01* +Y95000D01* +G37* +G36* +X237050D02*X240800D01* +Y87500D01* +X237050D01* +Y95000D01* +G37* +G36* +X241550D02*X245300D01* +Y87500D01* +X241550D01* +Y95000D01* +G37* +G36* +X246050D02*X249800D01* +Y87500D01* +X246050D01* +Y95000D01* +G37* +G36* +X250550D02*X254300D01* +Y87500D01* +X250550D01* +Y95000D01* +G37* +G36* +X200000Y110000D02*X203750D01* +Y102500D01* +X200000D01* +Y110000D01* +G37* +G36* +X204500D02*X208250D01* +Y102500D01* +X204500D01* +Y110000D01* +G37* +G36* +X209000D02*X212750D01* +Y102500D01* +X209000D01* +Y110000D01* +G37* +G36* +X213500D02*X217250D01* +Y102500D01* +X213500D01* +Y110000D01* +G37* +G36* +X218000D02*X221750D01* +Y102500D01* +X218000D01* +Y110000D01* +G37* +G36* +X222500D02*X226250D01* +Y102500D01* +X222500D01* +Y110000D01* +G37* +G36* +X227000D02*X230750D01* +Y102500D01* +X227000D01* +Y110000D01* +G37* +G36* +X231500D02*X235250D01* +Y102500D01* +X231500D01* +Y110000D01* +G37* +G36* +X236000D02*X239750D01* +Y102500D01* +X236000D01* +Y110000D01* +G37* +G36* +X240500D02*X244250D01* +Y102500D01* +X240500D01* +Y110000D01* +G37* +G36* +X245000D02*X248750D01* +Y102500D01* +X245000D01* +Y110000D01* +G37* +G36* +X249500D02*X253250D01* +Y102500D01* +X249500D01* +Y110000D01* +G37* +G36* +X254000D02*X257750D01* +Y102500D01* +X254000D01* +Y110000D01* +G37* +G36* +X258500D02*X262250D01* +Y102500D01* +X258500D01* +Y110000D01* +G37* +G36* +X263000D02*X266750D01* +Y102500D01* +X263000D01* +Y110000D01* +G37* +G36* +X267500D02*X271250D01* +Y102500D01* +X267500D01* +Y110000D01* +G37* +G36* +X272000D02*X275750D01* +Y102500D01* +X272000D01* +Y110000D01* +G37* +G36* +X276500D02*X280250D01* +Y102500D01* +X276500D01* +Y110000D01* +G37* +G36* +X281000D02*X284750D01* +Y102500D01* +X281000D01* +Y110000D01* +G37* +G36* +X285500D02*X289250D01* +Y102500D01* +X285500D01* +Y110000D01* +G37* +G36* +X290000D02*X293750D01* +Y102500D01* +X290000D01* +Y110000D01* +G37* +G36* +X294500D02*X298250D01* +Y102500D01* +X294500D01* +Y110000D01* +G37* +G36* +X299000D02*X302750D01* +Y102500D01* +X299000D01* +Y110000D01* +G37* +G36* +X303500D02*X307250D01* +Y102500D01* +X303500D01* +Y110000D01* +G37* +G36* +X308000D02*X311750D01* +Y102500D01* +X308000D01* +Y110000D01* +G37* +G36* +X312500D02*X316250D01* +Y102500D01* +X312500D01* +Y110000D01* +G37* +G36* +X317000D02*X320750D01* +Y102500D01* +X317000D01* +Y110000D01* +G37* +G36* +X321500D02*X325250D01* +Y102500D01* +X321500D01* +Y110000D01* +G37* +G36* +X326000D02*X329750D01* +Y102500D01* +X326000D01* +Y110000D01* +G37* +G36* +X330500D02*X334250D01* +Y102500D01* +X330500D01* +Y110000D01* +G37* +G36* +X335000D02*X338750D01* +Y102500D01* +X335000D01* +Y110000D01* +G37* +G36* +X339500D02*X343250D01* +Y102500D01* +X339500D01* +Y110000D01* +G37* +G36* +X344000D02*X347750D01* +Y102500D01* +X344000D01* +Y110000D01* +G37* +G36* +X348500D02*X352250D01* +Y102500D01* +X348500D01* +Y110000D01* +G37* +G36* +X353000D02*X356750D01* +Y102500D01* +X353000D01* +Y110000D01* +G37* +G36* +X357500D02*X361250D01* +Y102500D01* +X357500D01* +Y110000D01* +G37* +G36* +X362000D02*X365750D01* +Y102500D01* +X362000D01* +Y110000D01* +G37* +G36* +X366500D02*X370250D01* +Y102500D01* +X366500D01* +Y110000D01* +G37* +G36* +X371000D02*X374750D01* +Y102500D01* +X371000D01* +Y110000D01* +G37* +G36* +X375500D02*X379250D01* +Y102500D01* +X375500D01* +Y110000D01* +G37* +G36* +X380000D02*X383750D01* +Y102500D01* +X380000D01* +Y110000D01* +G37* +G36* +X384500D02*X388250D01* +Y102500D01* +X384500D01* +Y110000D01* +G37* +G36* +X389000D02*X392750D01* +Y102500D01* +X389000D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/text_rot.gbr/text_rot.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.gbr/text_rot.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.gbr/text_rot.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,60 @@ +G04 start of page 2 for group 1 layer_idx 8 * +G04 Title: text rotations, top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD11C,0.0070*% +G54D11*X22500Y34000D02*Y31000D01* +Y34000D02*X23200Y35000D01* +X24300D01* +X25000Y34000D01* +Y31000D01* +X22500Y33000D02*X25000D01* +X26200Y34200D02*X27000Y35000D01* +Y31000D01* +X26200D02*X27700D01* +X16000Y22500D02*X19000D01* +X16000D02*X15000Y23200D01* +Y24300D01* +X16000Y25000D01* +X19000D01* +X17000Y22500D02*Y25000D01* +X15500Y26200D02*X15000Y26700D01* +Y28200D01* +X15500Y28700D01* +X16500D01* +X19000Y26200D02*X16500Y28700D01* +X19000Y26200D02*Y28700D01* +X27500Y16000D02*Y19000D01* +Y16000D02*X26800Y15000D01* +X25700D01* +X25000Y16000D01* +Y19000D01* +X27500Y17000D02*X25000D01* +X23800Y15500D02*X23300Y15000D01* +X22300D01* +X21800Y15500D01* +X22300Y19000D02*X21800Y18500D01* +X23300Y19000D02*X22300D01* +X23800Y18500D02*X23300Y19000D01* +Y16800D02*X22300D01* +X21800Y15500D02*Y16300D01* +Y17300D02*Y18500D01* +Y17300D02*X22300Y16800D01* +X21800Y16300D02*X22300Y16800D01* +X34000Y27500D02*X31000D01* +X34000D02*X35000Y26800D01* +Y25700D01* +X34000Y25000D01* +X31000D01* +X33000Y27500D02*Y25000D01* +X32500Y23800D02*X35000Y21800D01* +X32500Y23800D02*Y21300D01* +X35000Y21800D02*X31000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/text_rot.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.nelma.em (revision 33253) @@ -0,0 +1,51 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/text_rot.net =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB text rotations +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/text_rot.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/text_rot.png =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/text_rot.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/text_rot.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.png.text (revision 33253) @@ -0,0 +1,13 @@ +r6731 + +A's are all 8 pixels thick +1 8 (6.67) pixels thick +2 8 pixels thick +3 8 pixels thick +4 8 pixels thick + +All text is spaced @ 6 pixels (5) + +136 pixels (113.333) from under A2 to under A4 +136 pixels from under A1 to under A3 + Index: tags/2.3.0/tests/RTT/ref/text_rot.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/text_rot.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/text_rot.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/text_rot.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/text_rot.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/text_rot.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/text_rot.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.svg (revision 33253) @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/text_rot.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/text_rot.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_rot.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: text rotations - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/text_scale.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: text sizes (scales) - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/text_scale.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb text sizes (scales) + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/text_scale.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.eps (revision 33253) @@ -0,0 +1,73 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: text_scale.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +% Layer topsilk group 1 drill 0 mask 0 +0.00700 setlinewidth +1 setlinecap +0 0 0 setrgbcolor +0.05000 0.03500 0.05000 0.06500 t +0.05000 0.03500 0.05700 0.02500 t +0.05700 0.02500 0.06800 0.02500 t +0.06800 0.02500 0.07500 0.03500 t +0.07500 0.03500 0.07500 0.06500 t +0.05000 0.04500 0.07500 0.04500 t +0.08700 0.03300 0.09500 0.02500 t +0.09500 0.02500 0.09500 0.06500 t +0.08700 0.06500 0.10200 0.06500 t +0.05000 0.20100 0.05000 0.20400 t +0.05000 0.20100 0.05070 0.20000 t +0.05070 0.20000 0.05180 0.20000 t +0.05180 0.20000 0.05250 0.20100 t +0.05250 0.20100 0.05250 0.20400 t +0.05000 0.20200 0.05250 0.20200 t +0.05370 0.20050 0.05420 0.20000 t +0.05420 0.20000 0.05570 0.20000 t +0.05570 0.20000 0.05620 0.20050 t +0.05620 0.20050 0.05620 0.20150 t +0.05370 0.20400 0.05620 0.20150 t +0.05370 0.20400 0.05620 0.20400 t +0.01280 setlinewidth +0.05000 0.33200 0.05000 0.42800 t +0.05000 0.33200 0.07240 0.30000 t +0.07240 0.30000 0.10760 0.30000 t +0.10760 0.30000 0.13000 0.33200 t +0.13000 0.33200 0.13000 0.42800 t +0.05000 0.36400 0.13000 0.36400 t +0.16840 0.31600 0.18440 0.30000 t +0.18440 0.30000 0.21640 0.30000 t +0.21640 0.30000 0.23240 0.31600 t +0.21640 0.42800 0.23240 0.41200 t +0.18440 0.42800 0.21640 0.42800 t +0.16840 0.41200 0.18440 0.42800 t +0.18440 0.35760 0.21640 0.35760 t +0.23240 0.31600 0.23240 0.34160 t +0.23240 0.37360 0.23240 0.41200 t +0.23240 0.37360 0.21640 0.35760 t +0.23240 0.34160 0.21640 0.35760 t +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/text_scale.exc/text_scale.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.exc/text_scale.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.exc/text_scale.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/text_scale.exc/text_scale.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.exc/text_scale.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.exc/text_scale.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/text_scale.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.fcd (revision 33253) @@ -0,0 +1,4 @@ +[FIDOCAD] +TY 10 5 7 5 0 1 3 * A1 +TY 10 40 1 1 0 1 3 * A2 +TY 10 60 21 17 0 1 3 * A3 Index: tags/2.3.0/tests/RTT/ref/text_scale.gbr/text_scale.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.gbr/text_scale.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.gbr/text_scale.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 9 layer_idx 6 * +G04 Title: text sizes (scales), global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD13C,0.0100*% +G54D13*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/text_scale.gbr/text_scale.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.gbr/text_scale.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.gbr/text_scale.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,2004 @@ +G04 start of page 4 for group -1 layer_idx 268435461 * +G04 Title: text sizes (scales), * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD17C,0.0060*% +%ADD16C,0.0100*% +%ADD15C,0.0080*% +%ADD14C,0.0001*% +G54D14*G36* +X0Y125000D02*X3750D01* +Y117500D01* +X0D01* +Y125000D01* +G37* +G36* +X4500D02*X8250D01* +Y117500D01* +X4500D01* +Y125000D01* +G37* +G36* +X9000D02*X12750D01* +Y117500D01* +X9000D01* +Y125000D01* +G37* +G36* +X13500D02*X17250D01* +Y117500D01* +X13500D01* +Y125000D01* +G37* +G36* +X18000D02*X21750D01* +Y117500D01* +X18000D01* +Y125000D01* +G37* +G36* +X22500D02*X26250D01* +Y117500D01* +X22500D01* +Y125000D01* +G37* +G54D15*X0Y116500D03* +G54D14*G36* +X41000Y125000D02*X44750D01* +Y117500D01* +X41000D01* +Y125000D01* +G37* +G36* +X45500D02*X49250D01* +Y117500D01* +X45500D01* +Y125000D01* +G37* +G36* +X50000D02*X53750D01* +Y117500D01* +X50000D01* +Y125000D01* +G37* +G36* +X54500D02*X58250D01* +Y117500D01* +X54500D01* +Y125000D01* +G37* +G36* +X59000D02*X62750D01* +Y117500D01* +X59000D01* +Y125000D01* +G37* +G36* +X63500D02*X67250D01* +Y117500D01* +X63500D01* +Y125000D01* +G37* +G36* +X68000D02*X71750D01* +Y117500D01* +X68000D01* +Y125000D01* +G37* +G36* +X72500D02*X76250D01* +Y117500D01* +X72500D01* +Y125000D01* +G37* +G36* +X77000D02*X80750D01* +Y117500D01* +X77000D01* +Y125000D01* +G37* +G36* +X81500D02*X85250D01* +Y117500D01* +X81500D01* +Y125000D01* +G37* +G36* +X86000D02*X89750D01* +Y117500D01* +X86000D01* +Y125000D01* +G37* +G36* +X90500D02*X94250D01* +Y117500D01* +X90500D01* +Y125000D01* +G37* +G54D15*X41000Y116500D03* +G54D14*G36* +X95000Y125000D02*X98750D01* +Y117500D01* +X95000D01* +Y125000D01* +G37* +G36* +X99500D02*X103250D01* +Y117500D01* +X99500D01* +Y125000D01* +G37* +G36* +X104000D02*X107750D01* +Y117500D01* +X104000D01* +Y125000D01* +G37* +G36* +X108500D02*X112250D01* +Y117500D01* +X108500D01* +Y125000D01* +G37* +G36* +X113000D02*X116750D01* +Y117500D01* +X113000D01* +Y125000D01* +G37* +G54D15*X95000Y116500D03* +G54D14*G36* +X130000Y125000D02*X133750D01* +Y117500D01* +X130000D01* +Y125000D01* +G37* +G36* +X134500D02*X138250D01* +Y117500D01* +X134500D01* +Y125000D01* +G37* +G36* +X139000D02*X142750D01* +Y117500D01* +X139000D01* +Y125000D01* +G37* +G36* +X143500D02*X147250D01* +Y117500D01* +X143500D01* +Y125000D01* +G37* +G36* +X148000D02*X151750D01* +Y117500D01* +X148000D01* +Y125000D01* +G37* +G36* +X152500D02*X156250D01* +Y117500D01* +X152500D01* +Y125000D01* +G37* +G36* +X157000D02*X160750D01* +Y117500D01* +X157000D01* +Y125000D01* +G37* +G54D15*X130000Y116500D03* +G54D14*G36* +X0Y140000D02*X3750D01* +Y132500D01* +X0D01* +Y140000D01* +G37* +G36* +X4500D02*X8250D01* +Y132500D01* +X4500D01* +Y140000D01* +G37* +G36* +X9000D02*X12750D01* +Y132500D01* +X9000D01* +Y140000D01* +G37* +G36* +X13500D02*X17250D01* +Y132500D01* +X13500D01* +Y140000D01* +G37* +G36* +X18000D02*X21750D01* +Y132500D01* +X18000D01* +Y140000D01* +G37* +G36* +X22500D02*X26250D01* +Y132500D01* +X22500D01* +Y140000D01* +G37* +G36* +X27000D02*X30750D01* +Y132500D01* +X27000D01* +Y140000D01* +G37* +G36* +X31500D02*X35250D01* +Y132500D01* +X31500D01* +Y140000D01* +G37* +G36* +X36000D02*X39750D01* +Y132500D01* +X36000D01* +Y140000D01* +G37* +G36* +X40500D02*X44250D01* +Y132500D01* +X40500D01* +Y140000D01* +G37* +G36* +X45000D02*X48750D01* +Y132500D01* +X45000D01* +Y140000D01* +G37* +G36* +X49500D02*X53250D01* +Y132500D01* +X49500D01* +Y140000D01* +G37* +G36* +X54000D02*X57750D01* +Y132500D01* +X54000D01* +Y140000D01* +G37* +G36* +X58500D02*X62250D01* +Y132500D01* +X58500D01* +Y140000D01* +G37* +G36* +X63000D02*X66750D01* +Y132500D01* +X63000D01* +Y140000D01* +G37* +G36* +X67500D02*X71250D01* +Y132500D01* +X67500D01* +Y140000D01* +G37* +G36* +X72000D02*X75750D01* +Y132500D01* +X72000D01* +Y140000D01* +G37* +G36* +X76500D02*X80250D01* +Y132500D01* +X76500D01* +Y140000D01* +G37* +G36* +X81000D02*X84750D01* +Y132500D01* +X81000D01* +Y140000D01* +G37* +G36* +X85500D02*X89250D01* +Y132500D01* +X85500D01* +Y140000D01* +G37* +G36* +X90000D02*X93750D01* +Y132500D01* +X90000D01* +Y140000D01* +G37* +G36* +X94500D02*X98250D01* +Y132500D01* +X94500D01* +Y140000D01* +G37* +G36* +X99000D02*X102750D01* +Y132500D01* +X99000D01* +Y140000D01* +G37* +G36* +X103500D02*X107250D01* +Y132500D01* +X103500D01* +Y140000D01* +G37* +G36* +X108000D02*X111750D01* +Y132500D01* +X108000D01* +Y140000D01* +G37* +G36* +X112500D02*X116250D01* +Y132500D01* +X112500D01* +Y140000D01* +G37* +G36* +X117000D02*X120750D01* +Y132500D01* +X117000D01* +Y140000D01* +G37* +G36* +X121500D02*X125250D01* +Y132500D01* +X121500D01* +Y140000D01* +G37* +G36* +X126000D02*X129750D01* +Y132500D01* +X126000D01* +Y140000D01* +G37* +G36* +X130500D02*X134250D01* +Y132500D01* +X130500D01* +Y140000D01* +G37* +G36* +X135000D02*X138750D01* +Y132500D01* +X135000D01* +Y140000D01* +G37* +G36* +X139500D02*X143250D01* +Y132500D01* +X139500D01* +Y140000D01* +G37* +G36* +X144000D02*X147750D01* +Y132500D01* +X144000D01* +Y140000D01* +G37* +G36* +X148500D02*X152250D01* +Y132500D01* +X148500D01* +Y140000D01* +G37* +G36* +X153000D02*X156750D01* +Y132500D01* +X153000D01* +Y140000D01* +G37* +G36* +X157500D02*X161250D01* +Y132500D01* +X157500D01* +Y140000D01* +G37* +G36* +X162000D02*X165750D01* +Y132500D01* +X162000D01* +Y140000D01* +G37* +G36* +X166500D02*X170250D01* +Y132500D01* +X166500D01* +Y140000D01* +G37* +G36* +X171000D02*X174750D01* +Y132500D01* +X171000D01* +Y140000D01* +G37* +G36* +X175500D02*X179250D01* +Y132500D01* +X175500D01* +Y140000D01* +G37* +G36* +X180000D02*X183750D01* +Y132500D01* +X180000D01* +Y140000D01* +G37* +G36* +X184500D02*X188250D01* +Y132500D01* +X184500D01* +Y140000D01* +G37* +G36* +X189000D02*X192750D01* +Y132500D01* +X189000D01* +Y140000D01* +G37* +G36* +X193500D02*X197250D01* +Y132500D01* +X193500D01* +Y140000D01* +G37* +G36* +X198000D02*X201750D01* +Y132500D01* +X198000D01* +Y140000D01* +G37* +G36* +X202500D02*X206250D01* +Y132500D01* +X202500D01* +Y140000D01* +G37* +G36* +X207000D02*X210750D01* +Y132500D01* +X207000D01* +Y140000D01* +G37* +G36* +X211500D02*X215250D01* +Y132500D01* +X211500D01* +Y140000D01* +G37* +G36* +X216000D02*X219750D01* +Y132500D01* +X216000D01* +Y140000D01* +G37* +G36* +X220500D02*X224250D01* +Y132500D01* +X220500D01* +Y140000D01* +G37* +G36* +X225000D02*X228750D01* +Y132500D01* +X225000D01* +Y140000D01* +G37* +G36* +X229500D02*X233250D01* +Y132500D01* +X229500D01* +Y140000D01* +G37* +G36* +X234000D02*X237750D01* +Y132500D01* +X234000D01* +Y140000D01* +G37* +G36* +X238500D02*X242250D01* +Y132500D01* +X238500D01* +Y140000D01* +G37* +G36* +X243000D02*X246750D01* +Y132500D01* +X243000D01* +Y140000D01* +G37* +G36* +X247500D02*X251250D01* +Y132500D01* +X247500D01* +Y140000D01* +G37* +G36* +X252000D02*X255750D01* +Y132500D01* +X252000D01* +Y140000D01* +G37* +G36* +X256500D02*X260250D01* +Y132500D01* +X256500D01* +Y140000D01* +G37* +G36* +X261000D02*X264750D01* +Y132500D01* +X261000D01* +Y140000D01* +G37* +G36* +X265500D02*X269250D01* +Y132500D01* +X265500D01* +Y140000D01* +G37* +G36* +X270000D02*X273750D01* +Y132500D01* +X270000D01* +Y140000D01* +G37* +G36* +X274500D02*X278250D01* +Y132500D01* +X274500D01* +Y140000D01* +G37* +G36* +X279000D02*X282750D01* +Y132500D01* +X279000D01* +Y140000D01* +G37* +G36* +X283500D02*X287250D01* +Y132500D01* +X283500D01* +Y140000D01* +G37* +G36* +X288000D02*X291750D01* +Y132500D01* +X288000D01* +Y140000D01* +G37* +G36* +X292500D02*X296250D01* +Y132500D01* +X292500D01* +Y140000D01* +G37* +G36* +X297000D02*X300750D01* +Y132500D01* +X297000D01* +Y140000D01* +G37* +G36* +X301500D02*X305250D01* +Y132500D01* +X301500D01* +Y140000D01* +G37* +G54D16*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D14*G36* +X200000Y65000D02*X203750D01* +Y57500D01* +X200000D01* +Y65000D01* +G37* +G36* +X204500D02*X208250D01* +Y57500D01* +X204500D01* +Y65000D01* +G37* +G36* +X209000D02*X212750D01* +Y57500D01* +X209000D01* +Y65000D01* +G37* +G36* +X213500D02*X217250D01* +Y57500D01* +X213500D01* +Y65000D01* +G37* +G36* +X218000D02*X221750D01* +Y57500D01* +X218000D01* +Y65000D01* +G37* +G36* +X222500D02*X226250D01* +Y57500D01* +X222500D01* +Y65000D01* +G37* +G36* +X227000D02*X230750D01* +Y57500D01* +X227000D01* +Y65000D01* +G37* +G36* +X231500D02*X235250D01* +Y57500D01* +X231500D01* +Y65000D01* +G37* +G36* +X236000D02*X239750D01* +Y57500D01* +X236000D01* +Y65000D01* +G37* +G36* +X240500D02*X244250D01* +Y57500D01* +X240500D01* +Y65000D01* +G37* +G36* +X245000D02*X248750D01* +Y57500D01* +X245000D01* +Y65000D01* +G37* +G36* +X249500D02*X253250D01* +Y57500D01* +X249500D01* +Y65000D01* +G37* +G36* +X254000D02*X257750D01* +Y57500D01* +X254000D01* +Y65000D01* +G37* +G36* +X258500D02*X262250D01* +Y57500D01* +X258500D01* +Y65000D01* +G37* +G36* +X263000D02*X266750D01* +Y57500D01* +X263000D01* +Y65000D01* +G37* +G36* +X267500D02*X271250D01* +Y57500D01* +X267500D01* +Y65000D01* +G37* +G36* +X272000D02*X275750D01* +Y57500D01* +X272000D01* +Y65000D01* +G37* +G36* +X276500D02*X280250D01* +Y57500D01* +X276500D01* +Y65000D01* +G37* +G36* +X281000D02*X284750D01* +Y57500D01* +X281000D01* +Y65000D01* +G37* +G36* +X285500D02*X289250D01* +Y57500D01* +X285500D01* +Y65000D01* +G37* +G36* +X290000D02*X293750D01* +Y57500D01* +X290000D01* +Y65000D01* +G37* +G36* +X294500D02*X298250D01* +Y57500D01* +X294500D01* +Y65000D01* +G37* +G36* +X299000D02*X302750D01* +Y57500D01* +X299000D01* +Y65000D01* +G37* +G36* +X303500D02*X307250D01* +Y57500D01* +X303500D01* +Y65000D01* +G37* +G36* +X308000D02*X311750D01* +Y57500D01* +X308000D01* +Y65000D01* +G37* +G36* +X312500D02*X316250D01* +Y57500D01* +X312500D01* +Y65000D01* +G37* +G36* +X317000D02*X320750D01* +Y57500D01* +X317000D01* +Y65000D01* +G37* +G36* +X321500D02*X325250D01* +Y57500D01* +X321500D01* +Y65000D01* +G37* +G36* +X326000D02*X329750D01* +Y57500D01* +X326000D01* +Y65000D01* +G37* +G36* +X330500D02*X334250D01* +Y57500D01* +X330500D01* +Y65000D01* +G37* +G36* +X335000D02*X338750D01* +Y57500D01* +X335000D01* +Y65000D01* +G37* +G36* +X339500D02*X343250D01* +Y57500D01* +X339500D01* +Y65000D01* +G37* +G36* +X344000D02*X347750D01* +Y57500D01* +X344000D01* +Y65000D01* +G37* +G36* +X348500D02*X352250D01* +Y57500D01* +X348500D01* +Y65000D01* +G37* +G36* +X353000D02*X356750D01* +Y57500D01* +X353000D01* +Y65000D01* +G37* +G36* +X357500D02*X361250D01* +Y57500D01* +X357500D01* +Y65000D01* +G37* +G36* +X362000D02*X365750D01* +Y57500D01* +X362000D01* +Y65000D01* +G37* +G36* +X366500D02*X370250D01* +Y57500D01* +X366500D01* +Y65000D01* +G37* +G36* +X371000D02*X374750D01* +Y57500D01* +X371000D01* +Y65000D01* +G37* +G36* +X375500D02*X379250D01* +Y57500D01* +X375500D01* +Y65000D01* +G37* +G36* +X380000D02*X383750D01* +Y57500D01* +X380000D01* +Y65000D01* +G37* +G36* +X384500D02*X388250D01* +Y57500D01* +X384500D01* +Y65000D01* +G37* +G36* +X389000D02*X392750D01* +Y57500D01* +X389000D01* +Y65000D01* +G37* +G36* +X393500D02*X397250D01* +Y57500D01* +X393500D01* +Y65000D01* +G37* +G36* +X398000D02*X401750D01* +Y57500D01* +X398000D01* +Y65000D01* +G37* +G36* +X402500D02*X406250D01* +Y57500D01* +X402500D01* +Y65000D01* +G37* +G36* +X407000D02*X410750D01* +Y57500D01* +X407000D01* +Y65000D01* +G37* +G36* +X411500D02*X415250D01* +Y57500D01* +X411500D01* +Y65000D01* +G37* +G36* +X416000D02*X419750D01* +Y57500D01* +X416000D01* +Y65000D01* +G37* +G36* +X420500D02*X424250D01* +Y57500D01* +X420500D01* +Y65000D01* +G37* +G36* +X425000D02*X428750D01* +Y57500D01* +X425000D01* +Y65000D01* +G37* +G36* +X429500D02*X433250D01* +Y57500D01* +X429500D01* +Y65000D01* +G37* +G36* +X434000D02*X437750D01* +Y57500D01* +X434000D01* +Y65000D01* +G37* +G36* +X438500D02*X442250D01* +Y57500D01* +X438500D01* +Y65000D01* +G37* +G36* +X443000D02*X446750D01* +Y57500D01* +X443000D01* +Y65000D01* +G37* +G36* +X447500D02*X451250D01* +Y57500D01* +X447500D01* +Y65000D01* +G37* +G36* +X452000D02*X455750D01* +Y57500D01* +X452000D01* +Y65000D01* +G37* +G36* +X456500D02*X460250D01* +Y57500D01* +X456500D01* +Y65000D01* +G37* +G36* +X461000D02*X464750D01* +Y57500D01* +X461000D01* +Y65000D01* +G37* +G36* +X465500D02*X469250D01* +Y57500D01* +X465500D01* +Y65000D01* +G37* +G36* +X470000D02*X473750D01* +Y57500D01* +X470000D01* +Y65000D01* +G37* +G36* +X474500D02*X478250D01* +Y57500D01* +X474500D01* +Y65000D01* +G37* +G36* +X25000Y-2000D02*X28750D01* +Y-9500D01* +X25000D01* +Y-2000D01* +G37* +G36* +X29500D02*X33250D01* +Y-9500D01* +X29500D01* +Y-2000D01* +G37* +G36* +X34000D02*X37750D01* +Y-9500D01* +X34000D01* +Y-2000D01* +G37* +G36* +X38500D02*X42250D01* +Y-9500D01* +X38500D01* +Y-2000D01* +G37* +G36* +X43000D02*X46750D01* +Y-9500D01* +X43000D01* +Y-2000D01* +G37* +G36* +X47500D02*X51250D01* +Y-9500D01* +X47500D01* +Y-2000D01* +G37* +G36* +X52000D02*X55750D01* +Y-9500D01* +X52000D01* +Y-2000D01* +G37* +G36* +X56500D02*X60250D01* +Y-9500D01* +X56500D01* +Y-2000D01* +G37* +G36* +X61000D02*X64750D01* +Y-9500D01* +X61000D01* +Y-2000D01* +G37* +G36* +X65500D02*X69250D01* +Y-9500D01* +X65500D01* +Y-2000D01* +G37* +G36* +X70000D02*X73750D01* +Y-9500D01* +X70000D01* +Y-2000D01* +G37* +G36* +X74500D02*X78250D01* +Y-9500D01* +X74500D01* +Y-2000D01* +G37* +G36* +X79000D02*X82750D01* +Y-9500D01* +X79000D01* +Y-2000D01* +G37* +G36* +X83500D02*X87250D01* +Y-9500D01* +X83500D01* +Y-2000D01* +G37* +G36* +X88000D02*X91750D01* +Y-9500D01* +X88000D01* +Y-2000D01* +G37* +G36* +X92500D02*X96250D01* +Y-9500D01* +X92500D01* +Y-2000D01* +G37* +G36* +X97000D02*X100750D01* +Y-9500D01* +X97000D01* +Y-2000D01* +G37* +G36* +X101500D02*X105250D01* +Y-9500D01* +X101500D01* +Y-2000D01* +G37* +G36* +X106000D02*X109750D01* +Y-9500D01* +X106000D01* +Y-2000D01* +G37* +G36* +X110500D02*X114250D01* +Y-9500D01* +X110500D01* +Y-2000D01* +G37* +G36* +X115000D02*X118750D01* +Y-9500D01* +X115000D01* +Y-2000D01* +G37* +G36* +X119500D02*X123250D01* +Y-9500D01* +X119500D01* +Y-2000D01* +G37* +G36* +X124000D02*X127750D01* +Y-9500D01* +X124000D01* +Y-2000D01* +G37* +G36* +X128500D02*X132250D01* +Y-9500D01* +X128500D01* +Y-2000D01* +G37* +G36* +X133000D02*X136750D01* +Y-9500D01* +X133000D01* +Y-2000D01* +G37* +G36* +X137500D02*X141250D01* +Y-9500D01* +X137500D01* +Y-2000D01* +G37* +G36* +X142000D02*X145750D01* +Y-9500D01* +X142000D01* +Y-2000D01* +G37* +G36* +X146500D02*X150250D01* +Y-9500D01* +X146500D01* +Y-2000D01* +G37* +G36* +X151000D02*X154750D01* +Y-9500D01* +X151000D01* +Y-2000D01* +G37* +G36* +X155500D02*X159250D01* +Y-9500D01* +X155500D01* +Y-2000D01* +G37* +G36* +X160000D02*X163750D01* +Y-9500D01* +X160000D01* +Y-2000D01* +G37* +G36* +X164500D02*X168250D01* +Y-9500D01* +X164500D01* +Y-2000D01* +G37* +G36* +X169000D02*X172750D01* +Y-9500D01* +X169000D01* +Y-2000D01* +G37* +G36* +X173500D02*X177250D01* +Y-9500D01* +X173500D01* +Y-2000D01* +G37* +G36* +X178000D02*X181750D01* +Y-9500D01* +X178000D01* +Y-2000D01* +G37* +G36* +X182500D02*X186250D01* +Y-9500D01* +X182500D01* +Y-2000D01* +G37* +G36* +X187000D02*X190750D01* +Y-9500D01* +X187000D01* +Y-2000D01* +G37* +G36* +X191500D02*X195250D01* +Y-9500D01* +X191500D01* +Y-2000D01* +G37* +G36* +X196000D02*X199750D01* +Y-9500D01* +X196000D01* +Y-2000D01* +G37* +G36* +X200500D02*X204250D01* +Y-9500D01* +X200500D01* +Y-2000D01* +G37* +G36* +X205000D02*X208750D01* +Y-9500D01* +X205000D01* +Y-2000D01* +G37* +G36* +X209500D02*X213250D01* +Y-9500D01* +X209500D01* +Y-2000D01* +G37* +G36* +X214000D02*X217750D01* +Y-9500D01* +X214000D01* +Y-2000D01* +G37* +G36* +X218500D02*X222250D01* +Y-9500D01* +X218500D01* +Y-2000D01* +G37* +G36* +X223000D02*X226750D01* +Y-9500D01* +X223000D01* +Y-2000D01* +G37* +G36* +X227500D02*X231250D01* +Y-9500D01* +X227500D01* +Y-2000D01* +G37* +G36* +X232000D02*X235750D01* +Y-9500D01* +X232000D01* +Y-2000D01* +G37* +G36* +X236500D02*X240250D01* +Y-9500D01* +X236500D01* +Y-2000D01* +G37* +G36* +X241000D02*X244750D01* +Y-9500D01* +X241000D01* +Y-2000D01* +G37* +G36* +X245500D02*X249250D01* +Y-9500D01* +X245500D01* +Y-2000D01* +G37* +G36* +X250000D02*X253750D01* +Y-9500D01* +X250000D01* +Y-2000D01* +G37* +G36* +X254500D02*X258250D01* +Y-9500D01* +X254500D01* +Y-2000D01* +G37* +G36* +X259000D02*X262750D01* +Y-9500D01* +X259000D01* +Y-2000D01* +G37* +G36* +X263500D02*X267250D01* +Y-9500D01* +X263500D01* +Y-2000D01* +G37* +G36* +X268000D02*X271750D01* +Y-9500D01* +X268000D01* +Y-2000D01* +G37* +G36* +X272500D02*X276250D01* +Y-9500D01* +X272500D01* +Y-2000D01* +G37* +G36* +X277000D02*X280750D01* +Y-9500D01* +X277000D01* +Y-2000D01* +G37* +G36* +X281500D02*X285250D01* +Y-9500D01* +X281500D01* +Y-2000D01* +G37* +G36* +X286000D02*X289750D01* +Y-9500D01* +X286000D01* +Y-2000D01* +G37* +G36* +X290500D02*X294250D01* +Y-9500D01* +X290500D01* +Y-2000D01* +G37* +G36* +X295000D02*X298750D01* +Y-9500D01* +X295000D01* +Y-2000D01* +G37* +G36* +X299500D02*X303250D01* +Y-9500D01* +X299500D01* +Y-2000D01* +G37* +G36* +X304000D02*X307750D01* +Y-9500D01* +X304000D01* +Y-2000D01* +G37* +G36* +X308500D02*X312250D01* +Y-9500D01* +X308500D01* +Y-2000D01* +G37* +G36* +X313000D02*X316750D01* +Y-9500D01* +X313000D01* +Y-2000D01* +G37* +G36* +X317500D02*X321250D01* +Y-9500D01* +X317500D01* +Y-2000D01* +G37* +G36* +X322000D02*X325750D01* +Y-9500D01* +X322000D01* +Y-2000D01* +G37* +G36* +X326500D02*X330250D01* +Y-9500D01* +X326500D01* +Y-2000D01* +G37* +G36* +X331000D02*X334750D01* +Y-9500D01* +X331000D01* +Y-2000D01* +G37* +G36* +X335500D02*X339250D01* +Y-9500D01* +X335500D01* +Y-2000D01* +G37* +G36* +X340000D02*X343750D01* +Y-9500D01* +X340000D01* +Y-2000D01* +G37* +G36* +X344500D02*X348250D01* +Y-9500D01* +X344500D01* +Y-2000D01* +G37* +G36* +X349000D02*X352750D01* +Y-9500D01* +X349000D01* +Y-2000D01* +G37* +G36* +X353500D02*X357250D01* +Y-9500D01* +X353500D01* +Y-2000D01* +G37* +G36* +X358000D02*X361750D01* +Y-9500D01* +X358000D01* +Y-2000D01* +G37* +G36* +X362500D02*X366250D01* +Y-9500D01* +X362500D01* +Y-2000D01* +G37* +G36* +X367000D02*X370750D01* +Y-9500D01* +X367000D01* +Y-2000D01* +G37* +G36* +X371500D02*X375250D01* +Y-9500D01* +X371500D01* +Y-2000D01* +G37* +G36* +X376000D02*X379750D01* +Y-9500D01* +X376000D01* +Y-2000D01* +G37* +G36* +X380500D02*X384250D01* +Y-9500D01* +X380500D01* +Y-2000D01* +G37* +G36* +X385000D02*X388750D01* +Y-9500D01* +X385000D01* +Y-2000D01* +G37* +G36* +X389500D02*X393250D01* +Y-9500D01* +X389500D01* +Y-2000D01* +G37* +G36* +X394000D02*X397750D01* +Y-9500D01* +X394000D01* +Y-2000D01* +G37* +G36* +X398500D02*X402250D01* +Y-9500D01* +X398500D01* +Y-2000D01* +G37* +G36* +X403000D02*X406751D01* +Y-9500D01* +X403000D01* +Y-2000D01* +G37* +G36* +X407501D02*X411251D01* +Y-9500D01* +X407501D01* +Y-2000D01* +G37* +G36* +X412001D02*X415751D01* +Y-9500D01* +X412001D01* +Y-2000D01* +G37* +G36* +X416501D02*X420251D01* +Y-9500D01* +X416501D01* +Y-2000D01* +G37* +G36* +X421001D02*X424751D01* +Y-9500D01* +X421001D01* +Y-2000D01* +G37* +G36* +X425501D02*X429251D01* +Y-9500D01* +X425501D01* +Y-2000D01* +G37* +G36* +X430001D02*X433751D01* +Y-9500D01* +X430001D01* +Y-2000D01* +G37* +G36* +X434501D02*X438251D01* +Y-9500D01* +X434501D01* +Y-2000D01* +G37* +G36* +X439001D02*X442751D01* +Y-9500D01* +X439001D01* +Y-2000D01* +G37* +G36* +X443501D02*X447251D01* +Y-9500D01* +X443501D01* +Y-2000D01* +G37* +G36* +X448001D02*X451751D01* +Y-9500D01* +X448001D01* +Y-2000D01* +G37* +G36* +X452501D02*X456251D01* +Y-9500D01* +X452501D01* +Y-2000D01* +G37* +G36* +X457001D02*X460751D01* +Y-9500D01* +X457001D01* +Y-2000D01* +G37* +G36* +X461501D02*X465251D01* +Y-9500D01* +X461501D01* +Y-2000D01* +G37* +G36* +X200000Y80000D02*X203750D01* +Y72500D01* +X200000D01* +Y80000D01* +G37* +G36* +X204500D02*X208250D01* +Y72500D01* +X204500D01* +Y80000D01* +G37* +G36* +X209000D02*X212750D01* +Y72500D01* +X209000D01* +Y80000D01* +G37* +G36* +X213500D02*X217250D01* +Y72500D01* +X213500D01* +Y80000D01* +G37* +G36* +X218000D02*X221750D01* +Y72500D01* +X218000D01* +Y80000D01* +G37* +G36* +X222500D02*X226250D01* +Y72500D01* +X222500D01* +Y80000D01* +G37* +G36* +X227000D02*X230750D01* +Y72500D01* +X227000D01* +Y80000D01* +G37* +G36* +X231500D02*X235250D01* +Y72500D01* +X231500D01* +Y80000D01* +G37* +G36* +X236000D02*X239750D01* +Y72500D01* +X236000D01* +Y80000D01* +G37* +G36* +X240500D02*X244250D01* +Y72500D01* +X240500D01* +Y80000D01* +G37* +G36* +X245000D02*X248750D01* +Y72500D01* +X245000D01* +Y80000D01* +G37* +G36* +X249500D02*X253250D01* +Y72500D01* +X249500D01* +Y80000D01* +G37* +G54D17*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X209300D01* +Y87500D01* +X205550D01* +Y95000D01* +G37* +G36* +X210050D02*X213800D01* +Y87500D01* +X210050D01* +Y95000D01* +G37* +G36* +X214550D02*X218300D01* +Y87500D01* +X214550D01* +Y95000D01* +G37* +G36* +X219050D02*X222800D01* +Y87500D01* +X219050D01* +Y95000D01* +G37* +G36* +X223550D02*X227300D01* +Y87500D01* +X223550D01* +Y95000D01* +G37* +G36* +X228050D02*X231800D01* +Y87500D01* +X228050D01* +Y95000D01* +G37* +G36* +X232550D02*X236300D01* +Y87500D01* +X232550D01* +Y95000D01* +G37* +G36* +X237050D02*X240800D01* +Y87500D01* +X237050D01* +Y95000D01* +G37* +G36* +X241550D02*X245300D01* +Y87500D01* +X241550D01* +Y95000D01* +G37* +G36* +X246050D02*X249800D01* +Y87500D01* +X246050D01* +Y95000D01* +G37* +G36* +X250550D02*X254300D01* +Y87500D01* +X250550D01* +Y95000D01* +G37* +G36* +X200000Y110000D02*X203750D01* +Y102500D01* +X200000D01* +Y110000D01* +G37* +G36* +X204500D02*X208250D01* +Y102500D01* +X204500D01* +Y110000D01* +G37* +G36* +X209000D02*X212750D01* +Y102500D01* +X209000D01* +Y110000D01* +G37* +G36* +X213500D02*X217250D01* +Y102500D01* +X213500D01* +Y110000D01* +G37* +G36* +X218000D02*X221750D01* +Y102500D01* +X218000D01* +Y110000D01* +G37* +G36* +X222500D02*X226250D01* +Y102500D01* +X222500D01* +Y110000D01* +G37* +G36* +X227000D02*X230750D01* +Y102500D01* +X227000D01* +Y110000D01* +G37* +G36* +X231500D02*X235250D01* +Y102500D01* +X231500D01* +Y110000D01* +G37* +G36* +X236000D02*X239750D01* +Y102500D01* +X236000D01* +Y110000D01* +G37* +G36* +X240500D02*X244250D01* +Y102500D01* +X240500D01* +Y110000D01* +G37* +G36* +X245000D02*X248750D01* +Y102500D01* +X245000D01* +Y110000D01* +G37* +G36* +X249500D02*X253250D01* +Y102500D01* +X249500D01* +Y110000D01* +G37* +G36* +X254000D02*X257750D01* +Y102500D01* +X254000D01* +Y110000D01* +G37* +G36* +X258500D02*X262250D01* +Y102500D01* +X258500D01* +Y110000D01* +G37* +G36* +X263000D02*X266750D01* +Y102500D01* +X263000D01* +Y110000D01* +G37* +G36* +X267500D02*X271250D01* +Y102500D01* +X267500D01* +Y110000D01* +G37* +G36* +X272000D02*X275750D01* +Y102500D01* +X272000D01* +Y110000D01* +G37* +G36* +X276500D02*X280250D01* +Y102500D01* +X276500D01* +Y110000D01* +G37* +G36* +X281000D02*X284750D01* +Y102500D01* +X281000D01* +Y110000D01* +G37* +G36* +X285500D02*X289250D01* +Y102500D01* +X285500D01* +Y110000D01* +G37* +G36* +X290000D02*X293750D01* +Y102500D01* +X290000D01* +Y110000D01* +G37* +G36* +X294500D02*X298250D01* +Y102500D01* +X294500D01* +Y110000D01* +G37* +G36* +X299000D02*X302750D01* +Y102500D01* +X299000D01* +Y110000D01* +G37* +G36* +X303500D02*X307250D01* +Y102500D01* +X303500D01* +Y110000D01* +G37* +G36* +X308000D02*X311750D01* +Y102500D01* +X308000D01* +Y110000D01* +G37* +G36* +X312500D02*X316250D01* +Y102500D01* +X312500D01* +Y110000D01* +G37* +G36* +X317000D02*X320750D01* +Y102500D01* +X317000D01* +Y110000D01* +G37* +G36* +X321500D02*X325250D01* +Y102500D01* +X321500D01* +Y110000D01* +G37* +G36* +X326000D02*X329750D01* +Y102500D01* +X326000D01* +Y110000D01* +G37* +G36* +X330500D02*X334250D01* +Y102500D01* +X330500D01* +Y110000D01* +G37* +G36* +X335000D02*X338750D01* +Y102500D01* +X335000D01* +Y110000D01* +G37* +G36* +X339500D02*X343250D01* +Y102500D01* +X339500D01* +Y110000D01* +G37* +G36* +X344000D02*X347750D01* +Y102500D01* +X344000D01* +Y110000D01* +G37* +G36* +X348500D02*X352250D01* +Y102500D01* +X348500D01* +Y110000D01* +G37* +G36* +X353000D02*X356750D01* +Y102500D01* +X353000D01* +Y110000D01* +G37* +G36* +X357500D02*X361250D01* +Y102500D01* +X357500D01* +Y110000D01* +G37* +G36* +X362000D02*X365750D01* +Y102500D01* +X362000D01* +Y110000D01* +G37* +G36* +X366500D02*X370250D01* +Y102500D01* +X366500D01* +Y110000D01* +G37* +G36* +X371000D02*X374750D01* +Y102500D01* +X371000D01* +Y110000D01* +G37* +G36* +X375500D02*X379250D01* +Y102500D01* +X375500D01* +Y110000D01* +G37* +G36* +X380000D02*X383750D01* +Y102500D01* +X380000D01* +Y110000D01* +G37* +G36* +X384500D02*X388250D01* +Y102500D01* +X384500D01* +Y110000D01* +G37* +G36* +X389000D02*X392750D01* +Y102500D01* +X389000D01* +Y110000D01* +G37* +G36* +X393500D02*X397250D01* +Y102500D01* +X393500D01* +Y110000D01* +G37* +G36* +X398000D02*X401750D01* +Y102500D01* +X398000D01* +Y110000D01* +G37* +G36* +X402500D02*X406250D01* +Y102500D01* +X402500D01* +Y110000D01* +G37* +G36* +X407000D02*X410750D01* +Y102500D01* +X407000D01* +Y110000D01* +G37* +G36* +X411500D02*X415250D01* +Y102500D01* +X411500D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/text_scale.gbr/text_scale.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.gbr/text_scale.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.gbr/text_scale.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,52 @@ +G04 start of page 2 for group 1 layer_idx 8 * +G04 Title: text sizes (scales), top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD12C,0.0128*% +%ADD11C,0.0070*% +G54D11*X5000Y46500D02*Y43500D01* +Y46500D02*X5700Y47500D01* +X6800D01* +X7500Y46500D01* +Y43500D01* +X5000Y45500D02*X7500D01* +X8700Y46700D02*X9500Y47500D01* +Y43500D01* +X8700D02*X10200D01* +X5000Y29900D02*Y29600D01* +Y29900D02*X5070Y30000D01* +X5180D01* +X5250Y29900D01* +Y29600D01* +X5000Y29800D02*X5250D01* +X5370Y29950D02*X5420Y30000D01* +X5570D01* +X5620Y29950D01* +Y29850D01* +X5370Y29600D02*X5620Y29850D01* +X5370Y29600D02*X5620D01* +G54D12*X5000Y16800D02*Y7200D01* +Y16800D02*X7240Y20000D01* +X10760D01* +X13000Y16800D01* +Y7200D01* +X5000Y13600D02*X13000D01* +X16840Y18400D02*X18440Y20000D01* +X21640D01* +X23240Y18400D01* +X21640Y7200D02*X23240Y8800D01* +X18440Y7200D02*X21640D01* +X16840Y8800D02*X18440Y7200D01* +Y14240D02*X21640D01* +X23240Y18400D02*Y15840D01* +Y12640D02*Y8800D01* +Y12640D02*X21640Y14240D01* +X23240Y15840D02*X21640Y14240D01* +M02* Index: tags/2.3.0/tests/RTT/ref/text_scale.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.nelma.em (revision 33253) @@ -0,0 +1,51 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/text_scale.net =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB text sizes (scales) +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/text_scale.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/text_scale.png =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/text_scale.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/text_scale.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.png.text (revision 33253) @@ -0,0 +1,23 @@ + +top text A1 +A line width 8 (6.666) pixels +A width 38 pixels (31.666) +A height 56 pixels (46.666) +1 line width 8 pixels (6.666) +1 width 26 pixels (21.666) +1 height 56 pixels (46.666) + +gap from A to 1 is 6 pixels (5) + +dot thing in the page +13 pixels (10.833) tall +15 pixels (12.5) wide + +bottom text A3 +A line width 15 pixels (12.5) +A width 111 pixels (92.5) +A height 169 pixels (140.833) +3 line width 15 pixels (12.5) +3 width 92 pixels (75.833) +3 height 169 pixels (140.833) + Index: tags/2.3.0/tests/RTT/ref/text_scale.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/text_scale.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/text_scale.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/text_scale.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/text_scale.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/text_scale.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/text_scale.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.svg (revision 33253) @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/text_scale.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/text_scale.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_scale.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: text sizes (scales) - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/text_sides.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: text on both sides - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/text_sides.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.dsn (revision 33253) @@ -0,0 +1,50 @@ +(pcb text on both sides + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/text_sides.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.eps (revision 33253) @@ -0,0 +1,43 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: text_sides.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +% Layer group5 group 5 drill 0 mask 0 +% Layer group7 group 7 drill 0 mask 0 +% Layer top group 3 drill 0 mask 0 +% Layer topsilk group 1 drill 0 mask 0 +0.00700 setlinewidth +1 setlinecap +0 0 0 setrgbcolor +0.22500 0.18500 0.22500 0.21500 t +0.22500 0.18500 0.23200 0.17500 t +0.23200 0.17500 0.24300 0.17500 t +0.24300 0.17500 0.25000 0.18500 t +0.25000 0.18500 0.25000 0.21500 t +0.22500 0.19500 0.25000 0.19500 t +0.26200 0.18300 0.27000 0.17500 t +0.27000 0.17500 0.27000 0.21500 t +0.26200 0.21500 0.27700 0.21500 t +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/text_sides.exc/text_sides.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.exc/text_sides.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.exc/text_sides.plated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/text_sides.exc/text_sides.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.exc/text_sides.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.exc/text_sides.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/text_sides.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.fcd (revision 33253) @@ -0,0 +1,3 @@ +[FIDOCAD] +TY 45 60 7 5 0 1 3 * A2 +TY 45 35 7 5 0 1 3 * A1 Index: tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.bottom.silk.none.12.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.bottom.silk.none.12.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.bottom.silk.none.12.gbr (revision 33253) @@ -0,0 +1,25 @@ +G04 start of page 2 for group 12 layer_idx 7 * +G04 Title: text on both sides, bottom_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_SILK_NONE_12*% +%ADD11C,0.0070*% +G54D11*X22500Y21000D02*Y24000D01* +Y21000D02*X23200Y20000D01* +X24300D01* +X25000Y21000D01* +Y24000D01* +X22500Y22000D02*X25000D01* +X26200Y20500D02*X26700Y20000D01* +X28200D01* +X28700Y20500D01* +Y21500D01* +X26200Y24000D02*X28700Y21500D01* +X26200Y24000D02*X28700D01* +M02* Index: tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 4 for group 9 layer_idx 6 * +G04 Title: text on both sides, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD13C,0.0100*% +G54D13*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1998 @@ +G04 start of page 5 for group -1 layer_idx 268435461 * +G04 Title: text on both sides, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD17C,0.0060*% +%ADD16C,0.0100*% +%ADD15C,0.0080*% +%ADD14C,0.0001*% +G54D14*G36* +X0Y125000D02*X3750D01* +Y117500D01* +X0D01* +Y125000D01* +G37* +G36* +X4500D02*X8250D01* +Y117500D01* +X4500D01* +Y125000D01* +G37* +G36* +X9000D02*X12750D01* +Y117500D01* +X9000D01* +Y125000D01* +G37* +G36* +X13500D02*X17250D01* +Y117500D01* +X13500D01* +Y125000D01* +G37* +G36* +X18000D02*X21750D01* +Y117500D01* +X18000D01* +Y125000D01* +G37* +G36* +X22500D02*X26250D01* +Y117500D01* +X22500D01* +Y125000D01* +G37* +G54D15*X0Y116500D03* +G54D14*G36* +X41000Y125000D02*X44750D01* +Y117500D01* +X41000D01* +Y125000D01* +G37* +G36* +X45500D02*X49250D01* +Y117500D01* +X45500D01* +Y125000D01* +G37* +G36* +X50000D02*X53750D01* +Y117500D01* +X50000D01* +Y125000D01* +G37* +G36* +X54500D02*X58250D01* +Y117500D01* +X54500D01* +Y125000D01* +G37* +G36* +X59000D02*X62750D01* +Y117500D01* +X59000D01* +Y125000D01* +G37* +G36* +X63500D02*X67250D01* +Y117500D01* +X63500D01* +Y125000D01* +G37* +G36* +X68000D02*X71750D01* +Y117500D01* +X68000D01* +Y125000D01* +G37* +G36* +X72500D02*X76250D01* +Y117500D01* +X72500D01* +Y125000D01* +G37* +G36* +X77000D02*X80750D01* +Y117500D01* +X77000D01* +Y125000D01* +G37* +G36* +X81500D02*X85250D01* +Y117500D01* +X81500D01* +Y125000D01* +G37* +G36* +X86000D02*X89750D01* +Y117500D01* +X86000D01* +Y125000D01* +G37* +G36* +X90500D02*X94250D01* +Y117500D01* +X90500D01* +Y125000D01* +G37* +G54D15*X41000Y116500D03* +G54D14*G36* +X95000Y125000D02*X98750D01* +Y117500D01* +X95000D01* +Y125000D01* +G37* +G36* +X99500D02*X103250D01* +Y117500D01* +X99500D01* +Y125000D01* +G37* +G36* +X104000D02*X107750D01* +Y117500D01* +X104000D01* +Y125000D01* +G37* +G36* +X108500D02*X112250D01* +Y117500D01* +X108500D01* +Y125000D01* +G37* +G36* +X113000D02*X116750D01* +Y117500D01* +X113000D01* +Y125000D01* +G37* +G54D15*X95000Y116500D03* +G54D14*G36* +X130000Y125000D02*X133750D01* +Y117500D01* +X130000D01* +Y125000D01* +G37* +G36* +X134500D02*X138250D01* +Y117500D01* +X134500D01* +Y125000D01* +G37* +G36* +X139000D02*X142750D01* +Y117500D01* +X139000D01* +Y125000D01* +G37* +G36* +X143500D02*X147250D01* +Y117500D01* +X143500D01* +Y125000D01* +G37* +G36* +X148000D02*X151750D01* +Y117500D01* +X148000D01* +Y125000D01* +G37* +G36* +X152500D02*X156250D01* +Y117500D01* +X152500D01* +Y125000D01* +G37* +G36* +X157000D02*X160750D01* +Y117500D01* +X157000D01* +Y125000D01* +G37* +G54D15*X130000Y116500D03* +G54D14*G36* +X0Y140000D02*X3750D01* +Y132500D01* +X0D01* +Y140000D01* +G37* +G36* +X4500D02*X8250D01* +Y132500D01* +X4500D01* +Y140000D01* +G37* +G36* +X9000D02*X12750D01* +Y132500D01* +X9000D01* +Y140000D01* +G37* +G36* +X13500D02*X17250D01* +Y132500D01* +X13500D01* +Y140000D01* +G37* +G36* +X18000D02*X21750D01* +Y132500D01* +X18000D01* +Y140000D01* +G37* +G36* +X22500D02*X26250D01* +Y132500D01* +X22500D01* +Y140000D01* +G37* +G36* +X27000D02*X30750D01* +Y132500D01* +X27000D01* +Y140000D01* +G37* +G36* +X31500D02*X35250D01* +Y132500D01* +X31500D01* +Y140000D01* +G37* +G36* +X36000D02*X39750D01* +Y132500D01* +X36000D01* +Y140000D01* +G37* +G36* +X40500D02*X44250D01* +Y132500D01* +X40500D01* +Y140000D01* +G37* +G36* +X45000D02*X48750D01* +Y132500D01* +X45000D01* +Y140000D01* +G37* +G36* +X49500D02*X53250D01* +Y132500D01* +X49500D01* +Y140000D01* +G37* +G36* +X54000D02*X57750D01* +Y132500D01* +X54000D01* +Y140000D01* +G37* +G36* +X58500D02*X62250D01* +Y132500D01* +X58500D01* +Y140000D01* +G37* +G36* +X63000D02*X66750D01* +Y132500D01* +X63000D01* +Y140000D01* +G37* +G36* +X67500D02*X71250D01* +Y132500D01* +X67500D01* +Y140000D01* +G37* +G36* +X72000D02*X75750D01* +Y132500D01* +X72000D01* +Y140000D01* +G37* +G36* +X76500D02*X80250D01* +Y132500D01* +X76500D01* +Y140000D01* +G37* +G36* +X81000D02*X84750D01* +Y132500D01* +X81000D01* +Y140000D01* +G37* +G36* +X85500D02*X89250D01* +Y132500D01* +X85500D01* +Y140000D01* +G37* +G36* +X90000D02*X93750D01* +Y132500D01* +X90000D01* +Y140000D01* +G37* +G36* +X94500D02*X98250D01* +Y132500D01* +X94500D01* +Y140000D01* +G37* +G36* +X99000D02*X102750D01* +Y132500D01* +X99000D01* +Y140000D01* +G37* +G36* +X103500D02*X107250D01* +Y132500D01* +X103500D01* +Y140000D01* +G37* +G36* +X108000D02*X111750D01* +Y132500D01* +X108000D01* +Y140000D01* +G37* +G36* +X112500D02*X116250D01* +Y132500D01* +X112500D01* +Y140000D01* +G37* +G36* +X117000D02*X120750D01* +Y132500D01* +X117000D01* +Y140000D01* +G37* +G36* +X121500D02*X125250D01* +Y132500D01* +X121500D01* +Y140000D01* +G37* +G36* +X126000D02*X129750D01* +Y132500D01* +X126000D01* +Y140000D01* +G37* +G36* +X130500D02*X134250D01* +Y132500D01* +X130500D01* +Y140000D01* +G37* +G36* +X135000D02*X138750D01* +Y132500D01* +X135000D01* +Y140000D01* +G37* +G36* +X139500D02*X143250D01* +Y132500D01* +X139500D01* +Y140000D01* +G37* +G36* +X144000D02*X147750D01* +Y132500D01* +X144000D01* +Y140000D01* +G37* +G36* +X148500D02*X152250D01* +Y132500D01* +X148500D01* +Y140000D01* +G37* +G36* +X153000D02*X156750D01* +Y132500D01* +X153000D01* +Y140000D01* +G37* +G36* +X157500D02*X161250D01* +Y132500D01* +X157500D01* +Y140000D01* +G37* +G36* +X162000D02*X165750D01* +Y132500D01* +X162000D01* +Y140000D01* +G37* +G36* +X166500D02*X170250D01* +Y132500D01* +X166500D01* +Y140000D01* +G37* +G36* +X171000D02*X174750D01* +Y132500D01* +X171000D01* +Y140000D01* +G37* +G36* +X175500D02*X179250D01* +Y132500D01* +X175500D01* +Y140000D01* +G37* +G36* +X180000D02*X183750D01* +Y132500D01* +X180000D01* +Y140000D01* +G37* +G36* +X184500D02*X188250D01* +Y132500D01* +X184500D01* +Y140000D01* +G37* +G36* +X189000D02*X192750D01* +Y132500D01* +X189000D01* +Y140000D01* +G37* +G36* +X193500D02*X197250D01* +Y132500D01* +X193500D01* +Y140000D01* +G37* +G36* +X198000D02*X201750D01* +Y132500D01* +X198000D01* +Y140000D01* +G37* +G36* +X202500D02*X206250D01* +Y132500D01* +X202500D01* +Y140000D01* +G37* +G36* +X207000D02*X210750D01* +Y132500D01* +X207000D01* +Y140000D01* +G37* +G36* +X211500D02*X215250D01* +Y132500D01* +X211500D01* +Y140000D01* +G37* +G36* +X216000D02*X219750D01* +Y132500D01* +X216000D01* +Y140000D01* +G37* +G36* +X220500D02*X224250D01* +Y132500D01* +X220500D01* +Y140000D01* +G37* +G36* +X225000D02*X228750D01* +Y132500D01* +X225000D01* +Y140000D01* +G37* +G36* +X229500D02*X233250D01* +Y132500D01* +X229500D01* +Y140000D01* +G37* +G36* +X234000D02*X237750D01* +Y132500D01* +X234000D01* +Y140000D01* +G37* +G36* +X238500D02*X242250D01* +Y132500D01* +X238500D01* +Y140000D01* +G37* +G36* +X243000D02*X246750D01* +Y132500D01* +X243000D01* +Y140000D01* +G37* +G36* +X247500D02*X251250D01* +Y132500D01* +X247500D01* +Y140000D01* +G37* +G36* +X252000D02*X255750D01* +Y132500D01* +X252000D01* +Y140000D01* +G37* +G36* +X256500D02*X260250D01* +Y132500D01* +X256500D01* +Y140000D01* +G37* +G36* +X261000D02*X264750D01* +Y132500D01* +X261000D01* +Y140000D01* +G37* +G36* +X265500D02*X269250D01* +Y132500D01* +X265500D01* +Y140000D01* +G37* +G36* +X270000D02*X273750D01* +Y132500D01* +X270000D01* +Y140000D01* +G37* +G36* +X274500D02*X278250D01* +Y132500D01* +X274500D01* +Y140000D01* +G37* +G36* +X279000D02*X282750D01* +Y132500D01* +X279000D01* +Y140000D01* +G37* +G36* +X283500D02*X287250D01* +Y132500D01* +X283500D01* +Y140000D01* +G37* +G36* +X288000D02*X291750D01* +Y132500D01* +X288000D01* +Y140000D01* +G37* +G36* +X292500D02*X296250D01* +Y132500D01* +X292500D01* +Y140000D01* +G37* +G36* +X297000D02*X300750D01* +Y132500D01* +X297000D01* +Y140000D01* +G37* +G36* +X301500D02*X305250D01* +Y132500D01* +X301500D01* +Y140000D01* +G37* +G54D16*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D14*G36* +X200000Y65000D02*X203750D01* +Y57500D01* +X200000D01* +Y65000D01* +G37* +G36* +X204500D02*X208250D01* +Y57500D01* +X204500D01* +Y65000D01* +G37* +G36* +X209000D02*X212750D01* +Y57500D01* +X209000D01* +Y65000D01* +G37* +G36* +X213500D02*X217250D01* +Y57500D01* +X213500D01* +Y65000D01* +G37* +G36* +X218000D02*X221750D01* +Y57500D01* +X218000D01* +Y65000D01* +G37* +G36* +X222500D02*X226250D01* +Y57500D01* +X222500D01* +Y65000D01* +G37* +G36* +X227000D02*X230750D01* +Y57500D01* +X227000D01* +Y65000D01* +G37* +G36* +X231500D02*X235250D01* +Y57500D01* +X231500D01* +Y65000D01* +G37* +G36* +X236000D02*X239750D01* +Y57500D01* +X236000D01* +Y65000D01* +G37* +G36* +X240500D02*X244250D01* +Y57500D01* +X240500D01* +Y65000D01* +G37* +G36* +X245000D02*X248750D01* +Y57500D01* +X245000D01* +Y65000D01* +G37* +G36* +X249500D02*X253250D01* +Y57500D01* +X249500D01* +Y65000D01* +G37* +G36* +X254000D02*X257750D01* +Y57500D01* +X254000D01* +Y65000D01* +G37* +G36* +X258500D02*X262250D01* +Y57500D01* +X258500D01* +Y65000D01* +G37* +G36* +X263000D02*X266750D01* +Y57500D01* +X263000D01* +Y65000D01* +G37* +G36* +X267500D02*X271250D01* +Y57500D01* +X267500D01* +Y65000D01* +G37* +G36* +X272000D02*X275750D01* +Y57500D01* +X272000D01* +Y65000D01* +G37* +G36* +X276500D02*X280250D01* +Y57500D01* +X276500D01* +Y65000D01* +G37* +G36* +X281000D02*X284750D01* +Y57500D01* +X281000D01* +Y65000D01* +G37* +G36* +X285500D02*X289250D01* +Y57500D01* +X285500D01* +Y65000D01* +G37* +G36* +X290000D02*X293750D01* +Y57500D01* +X290000D01* +Y65000D01* +G37* +G36* +X294500D02*X298250D01* +Y57500D01* +X294500D01* +Y65000D01* +G37* +G36* +X299000D02*X302750D01* +Y57500D01* +X299000D01* +Y65000D01* +G37* +G36* +X303500D02*X307250D01* +Y57500D01* +X303500D01* +Y65000D01* +G37* +G36* +X308000D02*X311750D01* +Y57500D01* +X308000D01* +Y65000D01* +G37* +G36* +X312500D02*X316250D01* +Y57500D01* +X312500D01* +Y65000D01* +G37* +G36* +X317000D02*X320750D01* +Y57500D01* +X317000D01* +Y65000D01* +G37* +G36* +X321500D02*X325250D01* +Y57500D01* +X321500D01* +Y65000D01* +G37* +G36* +X326000D02*X329750D01* +Y57500D01* +X326000D01* +Y65000D01* +G37* +G36* +X330500D02*X334250D01* +Y57500D01* +X330500D01* +Y65000D01* +G37* +G36* +X335000D02*X338750D01* +Y57500D01* +X335000D01* +Y65000D01* +G37* +G36* +X339500D02*X343250D01* +Y57500D01* +X339500D01* +Y65000D01* +G37* +G36* +X344000D02*X347750D01* +Y57500D01* +X344000D01* +Y65000D01* +G37* +G36* +X348500D02*X352250D01* +Y57500D01* +X348500D01* +Y65000D01* +G37* +G36* +X353000D02*X356750D01* +Y57500D01* +X353000D01* +Y65000D01* +G37* +G36* +X357500D02*X361250D01* +Y57500D01* +X357500D01* +Y65000D01* +G37* +G36* +X362000D02*X365750D01* +Y57500D01* +X362000D01* +Y65000D01* +G37* +G36* +X366500D02*X370250D01* +Y57500D01* +X366500D01* +Y65000D01* +G37* +G36* +X371000D02*X374750D01* +Y57500D01* +X371000D01* +Y65000D01* +G37* +G36* +X375500D02*X379250D01* +Y57500D01* +X375500D01* +Y65000D01* +G37* +G36* +X380000D02*X383750D01* +Y57500D01* +X380000D01* +Y65000D01* +G37* +G36* +X384500D02*X388250D01* +Y57500D01* +X384500D01* +Y65000D01* +G37* +G36* +X389000D02*X392750D01* +Y57500D01* +X389000D01* +Y65000D01* +G37* +G36* +X393500D02*X397250D01* +Y57500D01* +X393500D01* +Y65000D01* +G37* +G36* +X398000D02*X401750D01* +Y57500D01* +X398000D01* +Y65000D01* +G37* +G36* +X402500D02*X406250D01* +Y57500D01* +X402500D01* +Y65000D01* +G37* +G36* +X407000D02*X410750D01* +Y57500D01* +X407000D01* +Y65000D01* +G37* +G36* +X411500D02*X415250D01* +Y57500D01* +X411500D01* +Y65000D01* +G37* +G36* +X416000D02*X419750D01* +Y57500D01* +X416000D01* +Y65000D01* +G37* +G36* +X420500D02*X424250D01* +Y57500D01* +X420500D01* +Y65000D01* +G37* +G36* +X425000D02*X428750D01* +Y57500D01* +X425000D01* +Y65000D01* +G37* +G36* +X429500D02*X433250D01* +Y57500D01* +X429500D01* +Y65000D01* +G37* +G36* +X434000D02*X437750D01* +Y57500D01* +X434000D01* +Y65000D01* +G37* +G36* +X438500D02*X442250D01* +Y57500D01* +X438500D01* +Y65000D01* +G37* +G36* +X443000D02*X446750D01* +Y57500D01* +X443000D01* +Y65000D01* +G37* +G36* +X447500D02*X451250D01* +Y57500D01* +X447500D01* +Y65000D01* +G37* +G36* +X452000D02*X455750D01* +Y57500D01* +X452000D01* +Y65000D01* +G37* +G36* +X456500D02*X460250D01* +Y57500D01* +X456500D01* +Y65000D01* +G37* +G36* +X461000D02*X464750D01* +Y57500D01* +X461000D01* +Y65000D01* +G37* +G36* +X465500D02*X469250D01* +Y57500D01* +X465500D01* +Y65000D01* +G37* +G36* +X470000D02*X473750D01* +Y57500D01* +X470000D01* +Y65000D01* +G37* +G36* +X474500D02*X478250D01* +Y57500D01* +X474500D01* +Y65000D01* +G37* +G36* +X25000Y-2000D02*X28750D01* +Y-9500D01* +X25000D01* +Y-2000D01* +G37* +G36* +X29500D02*X33250D01* +Y-9500D01* +X29500D01* +Y-2000D01* +G37* +G36* +X34000D02*X37750D01* +Y-9500D01* +X34000D01* +Y-2000D01* +G37* +G36* +X38500D02*X42250D01* +Y-9500D01* +X38500D01* +Y-2000D01* +G37* +G36* +X43000D02*X46750D01* +Y-9500D01* +X43000D01* +Y-2000D01* +G37* +G36* +X47500D02*X51250D01* +Y-9500D01* +X47500D01* +Y-2000D01* +G37* +G36* +X52000D02*X55750D01* +Y-9500D01* +X52000D01* +Y-2000D01* +G37* +G36* +X56500D02*X60250D01* +Y-9500D01* +X56500D01* +Y-2000D01* +G37* +G36* +X61000D02*X64750D01* +Y-9500D01* +X61000D01* +Y-2000D01* +G37* +G36* +X65500D02*X69250D01* +Y-9500D01* +X65500D01* +Y-2000D01* +G37* +G36* +X70000D02*X73750D01* +Y-9500D01* +X70000D01* +Y-2000D01* +G37* +G36* +X74500D02*X78250D01* +Y-9500D01* +X74500D01* +Y-2000D01* +G37* +G36* +X79000D02*X82750D01* +Y-9500D01* +X79000D01* +Y-2000D01* +G37* +G36* +X83500D02*X87250D01* +Y-9500D01* +X83500D01* +Y-2000D01* +G37* +G36* +X88000D02*X91750D01* +Y-9500D01* +X88000D01* +Y-2000D01* +G37* +G36* +X92500D02*X96250D01* +Y-9500D01* +X92500D01* +Y-2000D01* +G37* +G36* +X97000D02*X100750D01* +Y-9500D01* +X97000D01* +Y-2000D01* +G37* +G36* +X101500D02*X105250D01* +Y-9500D01* +X101500D01* +Y-2000D01* +G37* +G36* +X106000D02*X109750D01* +Y-9500D01* +X106000D01* +Y-2000D01* +G37* +G36* +X110500D02*X114250D01* +Y-9500D01* +X110500D01* +Y-2000D01* +G37* +G36* +X115000D02*X118750D01* +Y-9500D01* +X115000D01* +Y-2000D01* +G37* +G36* +X119500D02*X123250D01* +Y-9500D01* +X119500D01* +Y-2000D01* +G37* +G36* +X124000D02*X127750D01* +Y-9500D01* +X124000D01* +Y-2000D01* +G37* +G36* +X128500D02*X132250D01* +Y-9500D01* +X128500D01* +Y-2000D01* +G37* +G36* +X133000D02*X136750D01* +Y-9500D01* +X133000D01* +Y-2000D01* +G37* +G36* +X137500D02*X141250D01* +Y-9500D01* +X137500D01* +Y-2000D01* +G37* +G36* +X142000D02*X145750D01* +Y-9500D01* +X142000D01* +Y-2000D01* +G37* +G36* +X146500D02*X150250D01* +Y-9500D01* +X146500D01* +Y-2000D01* +G37* +G36* +X151000D02*X154750D01* +Y-9500D01* +X151000D01* +Y-2000D01* +G37* +G36* +X155500D02*X159250D01* +Y-9500D01* +X155500D01* +Y-2000D01* +G37* +G36* +X160000D02*X163750D01* +Y-9500D01* +X160000D01* +Y-2000D01* +G37* +G36* +X164500D02*X168250D01* +Y-9500D01* +X164500D01* +Y-2000D01* +G37* +G36* +X169000D02*X172750D01* +Y-9500D01* +X169000D01* +Y-2000D01* +G37* +G36* +X173500D02*X177250D01* +Y-9500D01* +X173500D01* +Y-2000D01* +G37* +G36* +X178000D02*X181750D01* +Y-9500D01* +X178000D01* +Y-2000D01* +G37* +G36* +X182500D02*X186250D01* +Y-9500D01* +X182500D01* +Y-2000D01* +G37* +G36* +X187000D02*X190750D01* +Y-9500D01* +X187000D01* +Y-2000D01* +G37* +G36* +X191500D02*X195250D01* +Y-9500D01* +X191500D01* +Y-2000D01* +G37* +G36* +X196000D02*X199750D01* +Y-9500D01* +X196000D01* +Y-2000D01* +G37* +G36* +X200500D02*X204250D01* +Y-9500D01* +X200500D01* +Y-2000D01* +G37* +G36* +X205000D02*X208750D01* +Y-9500D01* +X205000D01* +Y-2000D01* +G37* +G36* +X209500D02*X213250D01* +Y-9500D01* +X209500D01* +Y-2000D01* +G37* +G36* +X214000D02*X217750D01* +Y-9500D01* +X214000D01* +Y-2000D01* +G37* +G36* +X218500D02*X222250D01* +Y-9500D01* +X218500D01* +Y-2000D01* +G37* +G36* +X223000D02*X226750D01* +Y-9500D01* +X223000D01* +Y-2000D01* +G37* +G36* +X227500D02*X231250D01* +Y-9500D01* +X227500D01* +Y-2000D01* +G37* +G36* +X232000D02*X235750D01* +Y-9500D01* +X232000D01* +Y-2000D01* +G37* +G36* +X236500D02*X240250D01* +Y-9500D01* +X236500D01* +Y-2000D01* +G37* +G36* +X241000D02*X244750D01* +Y-9500D01* +X241000D01* +Y-2000D01* +G37* +G36* +X245500D02*X249250D01* +Y-9500D01* +X245500D01* +Y-2000D01* +G37* +G36* +X250000D02*X253750D01* +Y-9500D01* +X250000D01* +Y-2000D01* +G37* +G36* +X254500D02*X258250D01* +Y-9500D01* +X254500D01* +Y-2000D01* +G37* +G36* +X259000D02*X262750D01* +Y-9500D01* +X259000D01* +Y-2000D01* +G37* +G36* +X263500D02*X267250D01* +Y-9500D01* +X263500D01* +Y-2000D01* +G37* +G36* +X268000D02*X271750D01* +Y-9500D01* +X268000D01* +Y-2000D01* +G37* +G36* +X272500D02*X276250D01* +Y-9500D01* +X272500D01* +Y-2000D01* +G37* +G36* +X277000D02*X280750D01* +Y-9500D01* +X277000D01* +Y-2000D01* +G37* +G36* +X281500D02*X285250D01* +Y-9500D01* +X281500D01* +Y-2000D01* +G37* +G36* +X286000D02*X289750D01* +Y-9500D01* +X286000D01* +Y-2000D01* +G37* +G36* +X290500D02*X294250D01* +Y-9500D01* +X290500D01* +Y-2000D01* +G37* +G36* +X295000D02*X298750D01* +Y-9500D01* +X295000D01* +Y-2000D01* +G37* +G36* +X299500D02*X303250D01* +Y-9500D01* +X299500D01* +Y-2000D01* +G37* +G36* +X304000D02*X307750D01* +Y-9500D01* +X304000D01* +Y-2000D01* +G37* +G36* +X308500D02*X312250D01* +Y-9500D01* +X308500D01* +Y-2000D01* +G37* +G36* +X313000D02*X316750D01* +Y-9500D01* +X313000D01* +Y-2000D01* +G37* +G36* +X317500D02*X321250D01* +Y-9500D01* +X317500D01* +Y-2000D01* +G37* +G36* +X322000D02*X325750D01* +Y-9500D01* +X322000D01* +Y-2000D01* +G37* +G36* +X326500D02*X330250D01* +Y-9500D01* +X326500D01* +Y-2000D01* +G37* +G36* +X331000D02*X334750D01* +Y-9500D01* +X331000D01* +Y-2000D01* +G37* +G36* +X335500D02*X339250D01* +Y-9500D01* +X335500D01* +Y-2000D01* +G37* +G36* +X340000D02*X343750D01* +Y-9500D01* +X340000D01* +Y-2000D01* +G37* +G36* +X344500D02*X348250D01* +Y-9500D01* +X344500D01* +Y-2000D01* +G37* +G36* +X349000D02*X352750D01* +Y-9500D01* +X349000D01* +Y-2000D01* +G37* +G36* +X353500D02*X357250D01* +Y-9500D01* +X353500D01* +Y-2000D01* +G37* +G36* +X358000D02*X361750D01* +Y-9500D01* +X358000D01* +Y-2000D01* +G37* +G36* +X362500D02*X366250D01* +Y-9500D01* +X362500D01* +Y-2000D01* +G37* +G36* +X367000D02*X370750D01* +Y-9500D01* +X367000D01* +Y-2000D01* +G37* +G36* +X371500D02*X375250D01* +Y-9500D01* +X371500D01* +Y-2000D01* +G37* +G36* +X376000D02*X379750D01* +Y-9500D01* +X376000D01* +Y-2000D01* +G37* +G36* +X380500D02*X384250D01* +Y-9500D01* +X380500D01* +Y-2000D01* +G37* +G36* +X385000D02*X388750D01* +Y-9500D01* +X385000D01* +Y-2000D01* +G37* +G36* +X389500D02*X393250D01* +Y-9500D01* +X389500D01* +Y-2000D01* +G37* +G36* +X394000D02*X397750D01* +Y-9500D01* +X394000D01* +Y-2000D01* +G37* +G36* +X398500D02*X402250D01* +Y-9500D01* +X398500D01* +Y-2000D01* +G37* +G36* +X403000D02*X406751D01* +Y-9500D01* +X403000D01* +Y-2000D01* +G37* +G36* +X407501D02*X411251D01* +Y-9500D01* +X407501D01* +Y-2000D01* +G37* +G36* +X412001D02*X415751D01* +Y-9500D01* +X412001D01* +Y-2000D01* +G37* +G36* +X416501D02*X420251D01* +Y-9500D01* +X416501D01* +Y-2000D01* +G37* +G36* +X421001D02*X424751D01* +Y-9500D01* +X421001D01* +Y-2000D01* +G37* +G36* +X425501D02*X429251D01* +Y-9500D01* +X425501D01* +Y-2000D01* +G37* +G36* +X430001D02*X433751D01* +Y-9500D01* +X430001D01* +Y-2000D01* +G37* +G36* +X434501D02*X438251D01* +Y-9500D01* +X434501D01* +Y-2000D01* +G37* +G36* +X439001D02*X442751D01* +Y-9500D01* +X439001D01* +Y-2000D01* +G37* +G36* +X443501D02*X447251D01* +Y-9500D01* +X443501D01* +Y-2000D01* +G37* +G36* +X448001D02*X451751D01* +Y-9500D01* +X448001D01* +Y-2000D01* +G37* +G36* +X452501D02*X456251D01* +Y-9500D01* +X452501D01* +Y-2000D01* +G37* +G36* +X457001D02*X460751D01* +Y-9500D01* +X457001D01* +Y-2000D01* +G37* +G36* +X461501D02*X465251D01* +Y-9500D01* +X461501D01* +Y-2000D01* +G37* +G36* +X200000Y80000D02*X203750D01* +Y72500D01* +X200000D01* +Y80000D01* +G37* +G36* +X204500D02*X208250D01* +Y72500D01* +X204500D01* +Y80000D01* +G37* +G36* +X209000D02*X212750D01* +Y72500D01* +X209000D01* +Y80000D01* +G37* +G36* +X213500D02*X217250D01* +Y72500D01* +X213500D01* +Y80000D01* +G37* +G36* +X218000D02*X221750D01* +Y72500D01* +X218000D01* +Y80000D01* +G37* +G36* +X222500D02*X226250D01* +Y72500D01* +X222500D01* +Y80000D01* +G37* +G36* +X227000D02*X230750D01* +Y72500D01* +X227000D01* +Y80000D01* +G37* +G36* +X231500D02*X235250D01* +Y72500D01* +X231500D01* +Y80000D01* +G37* +G36* +X236000D02*X239750D01* +Y72500D01* +X236000D01* +Y80000D01* +G37* +G36* +X240500D02*X244250D01* +Y72500D01* +X240500D01* +Y80000D01* +G37* +G36* +X245000D02*X248750D01* +Y72500D01* +X245000D01* +Y80000D01* +G37* +G36* +X249500D02*X253250D01* +Y72500D01* +X249500D01* +Y80000D01* +G37* +G54D17*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D14*G36* +X205550Y95000D02*X209300D01* +Y87500D01* +X205550D01* +Y95000D01* +G37* +G36* +X210050D02*X213800D01* +Y87500D01* +X210050D01* +Y95000D01* +G37* +G36* +X214550D02*X218300D01* +Y87500D01* +X214550D01* +Y95000D01* +G37* +G36* +X219050D02*X222800D01* +Y87500D01* +X219050D01* +Y95000D01* +G37* +G36* +X223550D02*X227300D01* +Y87500D01* +X223550D01* +Y95000D01* +G37* +G36* +X228050D02*X231800D01* +Y87500D01* +X228050D01* +Y95000D01* +G37* +G36* +X232550D02*X236300D01* +Y87500D01* +X232550D01* +Y95000D01* +G37* +G36* +X237050D02*X240800D01* +Y87500D01* +X237050D01* +Y95000D01* +G37* +G36* +X241550D02*X245300D01* +Y87500D01* +X241550D01* +Y95000D01* +G37* +G36* +X246050D02*X249800D01* +Y87500D01* +X246050D01* +Y95000D01* +G37* +G36* +X250550D02*X254300D01* +Y87500D01* +X250550D01* +Y95000D01* +G37* +G36* +X200000Y110000D02*X203750D01* +Y102500D01* +X200000D01* +Y110000D01* +G37* +G36* +X204500D02*X208250D01* +Y102500D01* +X204500D01* +Y110000D01* +G37* +G36* +X209000D02*X212750D01* +Y102500D01* +X209000D01* +Y110000D01* +G37* +G36* +X213500D02*X217250D01* +Y102500D01* +X213500D01* +Y110000D01* +G37* +G36* +X218000D02*X221750D01* +Y102500D01* +X218000D01* +Y110000D01* +G37* +G36* +X222500D02*X226250D01* +Y102500D01* +X222500D01* +Y110000D01* +G37* +G36* +X227000D02*X230750D01* +Y102500D01* +X227000D01* +Y110000D01* +G37* +G36* +X231500D02*X235250D01* +Y102500D01* +X231500D01* +Y110000D01* +G37* +G36* +X236000D02*X239750D01* +Y102500D01* +X236000D01* +Y110000D01* +G37* +G36* +X240500D02*X244250D01* +Y102500D01* +X240500D01* +Y110000D01* +G37* +G36* +X245000D02*X248750D01* +Y102500D01* +X245000D01* +Y110000D01* +G37* +G36* +X249500D02*X253250D01* +Y102500D01* +X249500D01* +Y110000D01* +G37* +G36* +X254000D02*X257750D01* +Y102500D01* +X254000D01* +Y110000D01* +G37* +G36* +X258500D02*X262250D01* +Y102500D01* +X258500D01* +Y110000D01* +G37* +G36* +X263000D02*X266750D01* +Y102500D01* +X263000D01* +Y110000D01* +G37* +G36* +X267500D02*X271250D01* +Y102500D01* +X267500D01* +Y110000D01* +G37* +G36* +X272000D02*X275750D01* +Y102500D01* +X272000D01* +Y110000D01* +G37* +G36* +X276500D02*X280250D01* +Y102500D01* +X276500D01* +Y110000D01* +G37* +G36* +X281000D02*X284750D01* +Y102500D01* +X281000D01* +Y110000D01* +G37* +G36* +X285500D02*X289250D01* +Y102500D01* +X285500D01* +Y110000D01* +G37* +G36* +X290000D02*X293750D01* +Y102500D01* +X290000D01* +Y110000D01* +G37* +G36* +X294500D02*X298250D01* +Y102500D01* +X294500D01* +Y110000D01* +G37* +G36* +X299000D02*X302750D01* +Y102500D01* +X299000D01* +Y110000D01* +G37* +G36* +X303500D02*X307250D01* +Y102500D01* +X303500D01* +Y110000D01* +G37* +G36* +X308000D02*X311750D01* +Y102500D01* +X308000D01* +Y110000D01* +G37* +G36* +X312500D02*X316250D01* +Y102500D01* +X312500D01* +Y110000D01* +G37* +G36* +X317000D02*X320750D01* +Y102500D01* +X317000D01* +Y110000D01* +G37* +G36* +X321500D02*X325250D01* +Y102500D01* +X321500D01* +Y110000D01* +G37* +G36* +X326000D02*X329750D01* +Y102500D01* +X326000D01* +Y110000D01* +G37* +G36* +X330500D02*X334250D01* +Y102500D01* +X330500D01* +Y110000D01* +G37* +G36* +X335000D02*X338750D01* +Y102500D01* +X335000D01* +Y110000D01* +G37* +G36* +X339500D02*X343250D01* +Y102500D01* +X339500D01* +Y110000D01* +G37* +G36* +X344000D02*X347750D01* +Y102500D01* +X344000D01* +Y110000D01* +G37* +G36* +X348500D02*X352250D01* +Y102500D01* +X348500D01* +Y110000D01* +G37* +G36* +X353000D02*X356750D01* +Y102500D01* +X353000D01* +Y110000D01* +G37* +G36* +X357500D02*X361250D01* +Y102500D01* +X357500D01* +Y110000D01* +G37* +G36* +X362000D02*X365750D01* +Y102500D01* +X362000D01* +Y110000D01* +G37* +G36* +X366500D02*X370250D01* +Y102500D01* +X366500D01* +Y110000D01* +G37* +G36* +X371000D02*X374750D01* +Y102500D01* +X371000D01* +Y110000D01* +G37* +G36* +X375500D02*X379250D01* +Y102500D01* +X375500D01* +Y110000D01* +G37* +G36* +X380000D02*X383750D01* +Y102500D01* +X380000D01* +Y110000D01* +G37* +G36* +X384500D02*X388250D01* +Y102500D01* +X384500D01* +Y110000D01* +G37* +G36* +X389000D02*X392750D01* +Y102500D01* +X389000D01* +Y110000D01* +G37* +G36* +X393500D02*X397250D01* +Y102500D01* +X393500D01* +Y110000D01* +G37* +G36* +X398000D02*X401750D01* +Y102500D01* +X398000D01* +Y110000D01* +G37* +G36* +X402500D02*X406250D01* +Y102500D01* +X402500D01* +Y110000D01* +G37* +G36* +X407000D02*X410750D01* +Y102500D01* +X407000D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.top.silk.none.1.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.top.silk.none.1.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.gbr/text_sides.top.silk.none.1.gbr (revision 33253) @@ -0,0 +1,22 @@ +G04 start of page 3 for group 1 layer_idx 8 * +G04 Title: text on both sides, top_silk * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_SILK_NONE_1*% +%ADD12C,0.0070*% +G54D12*X22500Y31500D02*Y28500D01* +Y31500D02*X23200Y32500D01* +X24300D01* +X25000Y31500D01* +Y28500D01* +X22500Y30500D02*X25000D01* +X26200Y31700D02*X27000Y32500D01* +Y28500D01* +X26200D02*X27700D01* +M02* Index: tags/2.3.0/tests/RTT/ref/text_sides.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.nelma.em (revision 33253) @@ -0,0 +1,51 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/text_sides.net =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.net (revision 33253) @@ -0,0 +1,12 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB text on both sides +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +999 Index: tags/2.3.0/tests/RTT/ref/text_sides.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/text_sides.png =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/text_sides.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/text_sides.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.png.text (revision 33253) @@ -0,0 +1,8 @@ +r6731 + +??? between the bottom of A1 and bottom of A2 +(underside text is missing in png file!) + +all text is 8 pixels thick (6.666) + +(mil) Index: tags/2.3.0/tests/RTT/ref/text_sides.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/text_sides.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/text_sides.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/text_sides.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/text_sides.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/text_sides.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/text_sides.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.svg (revision 33253) @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/text_sides.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/text_sides.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/text_sides.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: text on both sides - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/thermal_last.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/thermal_last.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.dsn (revision 33253) @@ -0,0 +1,53 @@ +(pcb thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 5 + (place 5 2.540000 10.160000 front 0 (PN 0)) + ) + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/thermal_last.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.eps (revision 33253) @@ -0,0 +1,206 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: thermal_last.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.00000 setlinewidth +1 setlinecap +0.627451 0.627451 0.627451 setrgbcolor +0.10000 0.10000 0.03937 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +% Layer group5 group 5 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.329412 0.545098 0.329412 setrgbcolor +0.12500 0.02500 moveto +0.12500 0.04609 lineto +0.11840 0.04336 lineto +0.10932 0.04118 lineto +0.10000 0.04045 lineto +0.09068 0.04118 lineto +0.08160 0.04336 lineto +0.07296 0.04694 lineto +0.06560 0.05145 lineto +0.08014 0.06600 lineto +0.08207 0.06481 lineto +0.08780 0.06244 lineto +0.09382 0.06099 lineto +0.10000 0.06051 lineto +0.10618 0.06099 lineto +0.11220 0.06244 lineto +0.11793 0.06481 lineto +0.11986 0.06600 lineto +0.12500 0.06086 lineto +0.12500 0.12500 lineto +0.06086 0.12500 lineto +0.06600 0.11986 lineto +0.06481 0.11793 lineto +0.06244 0.11220 lineto +0.06099 0.10618 lineto +0.06051 0.10000 lineto +0.06099 0.09382 lineto +0.06244 0.08780 lineto +0.06481 0.08207 lineto +0.06600 0.08014 lineto +0.05145 0.06560 lineto +0.04694 0.07296 lineto +0.04336 0.08160 lineto +0.04118 0.09068 lineto +0.04045 0.10000 lineto +0.04118 0.10932 lineto +0.04336 0.11840 lineto +0.04609 0.12500 lineto +0.02500 0.12500 lineto +0.02500 0.02500 lineto +fill +1 setlinecap +0.627451 0.627451 0.627451 setrgbcolor +0.10000 0.10000 0.03937 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +% Layer group7 group 7 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.545098 0.45098 0.333333 setrgbcolor +0.13830 0.07500 moveto +0.13826 0.07504 lineto +0.13732 0.07630 lineto +0.13658 0.07770 lineto +0.13608 0.07920 lineto +0.13581 0.08076 lineto +0.13579 0.08234 lineto +0.13602 0.08390 lineto +0.13652 0.08540 lineto +0.13778 0.08892 lineto +0.13866 0.09256 lineto +0.13919 0.09626 lineto +0.13937 0.10000 lineto +0.13919 0.10374 lineto +0.13866 0.10744 lineto +0.13778 0.11108 lineto +0.13656 0.11461 lineto +0.13606 0.11611 lineto +0.13583 0.11766 lineto +0.13585 0.11924 lineto +0.13612 0.12079 lineto +0.13662 0.12228 lineto +0.13736 0.12367 lineto +0.13830 0.12493 lineto +0.13942 0.12603 lineto +0.14071 0.12694 lineto +0.14212 0.12764 lineto +0.14362 0.12811 lineto +0.14518 0.12833 lineto +0.14675 0.12832 lineto +0.14831 0.12805 lineto +0.14980 0.12754 lineto +0.15119 0.12681 lineto +0.15245 0.12587 lineto +0.15355 0.12475 lineto +0.15446 0.12346 lineto +0.15513 0.12204 lineto +0.15704 0.11672 lineto +0.15837 0.11123 lineto +0.15917 0.10564 lineto +0.15944 0.10000 lineto +0.15917 0.09436 lineto +0.15837 0.08877 lineto +0.15704 0.08328 lineto +0.15519 0.07794 lineto +0.15450 0.07652 lineto +0.15358 0.07523 lineto +0.15336 0.07500 lineto +0.17500 0.07500 lineto +0.17500 0.17500 lineto +0.07500 0.17500 lineto +0.07500 0.15330 lineto +0.07525 0.15355 lineto +0.07654 0.15446 lineto +0.07796 0.15513 lineto +0.08328 0.15704 lineto +0.08877 0.15837 lineto +0.09436 0.15917 lineto +0.10000 0.15944 lineto +0.10564 0.15917 lineto +0.11123 0.15837 lineto +0.11672 0.15704 lineto +0.12206 0.15519 lineto +0.12348 0.15450 lineto +0.12477 0.15358 lineto +0.12591 0.15248 lineto +0.12685 0.15121 lineto +0.12759 0.14981 lineto +0.12809 0.14832 lineto +0.12836 0.14676 lineto +0.12838 0.14518 lineto +0.12815 0.14361 lineto +0.12768 0.14210 lineto +0.12698 0.14069 lineto +0.12607 0.13939 lineto +0.12496 0.13826 lineto +0.12370 0.13732 lineto +0.12230 0.13658 lineto +0.12080 0.13608 lineto +0.11924 0.13581 lineto +0.11766 0.13579 lineto +0.11610 0.13602 lineto +0.11460 0.13652 lineto +0.11108 0.13778 lineto +0.10744 0.13866 lineto +0.10374 0.13919 lineto +0.10000 0.13937 lineto +0.09626 0.13919 lineto +0.09256 0.13866 lineto +0.08892 0.13778 lineto +0.08539 0.13656 lineto +0.08389 0.13606 lineto +0.08234 0.13583 lineto +0.08076 0.13585 lineto +0.07921 0.13612 lineto +0.07772 0.13662 lineto +0.07633 0.13736 lineto +0.07507 0.13830 lineto +0.07500 0.13836 lineto +0.07500 0.07500 lineto +fill +1 setlinecap +0.627451 0.627451 0.627451 setrgbcolor +0.10000 0.10000 0.03937 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +0.439216 0.439216 0.439216 setrgbcolor +0.10000 0.10000 0.03937 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +% Layer topsilk group 1 drill 0 mask 0 +% Layer plated-drill group -1 drill 1 mask 0 +0.10000 0.10000 0.01575 c +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/thermal_last.exc/thermal_last.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.exc/thermal_last.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.exc/thermal_last.plated.cnc (revision 33253) @@ -0,0 +1,8 @@ +M48 +INCH +T11C0.032 +% +T11 +G05 +X001000Y004000 +M30 Index: tags/2.3.0/tests/RTT/ref/thermal_last.exc/thermal_last.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.exc/thermal_last.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.exc/thermal_last.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/thermal_last.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.fcd (revision 33253) @@ -0,0 +1,4 @@ +[FIDOCAD] +PP 5 5 25 5 25 9 24 9 22 8 20 8 18 8 16 9 15 9 13 10 16 13 16 13 18 12 19 12 20 12 21 12 22 12 24 13 24 13 25 12 25 25 12 25 13 24 13 24 12 22 12 21 12 20 12 19 12 18 13 16 13 16 10 13 9 15 9 16 8 18 8 20 8 22 9 24 9 25 5 25 5 5 4 +PP 15 15 28 15 28 15 27 15 27 16 27 16 27 16 27 16 27 17 27 17 28 18 28 19 28 19 28 20 28 21 28 21 28 22 27 23 27 23 27 24 27 24 27 24 27 24 27 25 28 25 28 25 28 25 28 26 29 26 29 26 29 26 30 26 30 26 30 25 30 25 31 25 31 25 31 24 31 23 32 22 32 21 32 20 32 19 32 18 31 17 31 16 31 15 31 15 31 15 35 15 35 35 15 35 15 31 15 31 15 31 16 31 17 31 18 32 19 32 20 32 21 32 22 32 23 31 24 31 25 31 25 31 25 30 25 30 26 30 26 30 26 29 26 29 26 29 26 28 25 28 25 28 25 28 25 27 24 27 24 27 24 27 24 27 23 27 23 27 22 28 21 28 21 28 20 28 19 28 19 28 18 28 17 27 17 27 16 27 16 27 16 27 16 27 15 27 15 28 15 28 15 15 5 +pa 20 20 16 16 6 0 Index: tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,15 @@ +G04 start of page 5 for group 10 layer_idx 1 * +G04 Title: thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals, bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD20C,0.0315*% +%ADD19C,0.0787*% +G54D19*X10000Y40000D03* +G54D20*M02* Index: tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 7 for group 9 layer_idx 6 * +G04 Title: thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD22C,0.0100*% +G54D22*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.global.virtual.pdrill.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.global.virtual.pdrill.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.global.virtual.pdrill.none.gbr (revision 33253) @@ -0,0 +1,14 @@ +G04 start of page 6 for group -1 layer_idx 268435462 * +G04 Title: thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_VIRTUAL_PDRILL_NONE*% +%ADD21C,0.0315*% +G54D21*X10000Y40000D03* +M02* Index: tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.intern.copper.none.5.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.intern.copper.none.5.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.intern.copper.none.5.gbr (revision 33253) @@ -0,0 +1,58 @@ +G04 start of page 3 for group 5 layer_idx 4 * +G04 Title: thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_5*% +%ADD15C,0.0315*% +%ADD14C,0.0787*% +%ADD13C,0.0001*% +G54D13*G36* +X12500Y47500D02*Y45391D01* +X11840Y45664D01* +X10932Y45882D01* +X10000Y45955D01* +X9068Y45882D01* +X8160Y45664D01* +X7296Y45306D01* +X6560Y44855D01* +X8014Y43400D01* +X8207Y43519D01* +X8780Y43756D01* +X9382Y43901D01* +X10000Y43949D01* +X10618Y43901D01* +X11220Y43756D01* +X11793Y43519D01* +X11986Y43400D01* +X12500Y43914D01* +Y37500D01* +X6086D01* +X6600Y38014D01* +X6481Y38207D01* +X6244Y38780D01* +X6099Y39382D01* +X6051Y40000D01* +X6099Y40618D01* +X6244Y41220D01* +X6481Y41793D01* +X6600Y41986D01* +X5145Y43440D01* +X4694Y42704D01* +X4336Y41840D01* +X4118Y40932D01* +X4045Y40000D01* +X4118Y39068D01* +X4336Y38160D01* +X4609Y37500D01* +X2500D01* +Y47500D01* +X12500D01* +G37* +G54D14*X10000Y40000D03* +G54D15*M02* Index: tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.intern.copper.none.7.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.intern.copper.none.7.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.intern.copper.none.7.gbr (revision 33253) @@ -0,0 +1,118 @@ +G04 start of page 4 for group 7 layer_idx 5 * +G04 Title: thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_7*% +%ADD18C,0.0315*% +%ADD17C,0.0787*% +%ADD16C,0.0001*% +G54D16*G36* +X13830Y42500D02*X13826Y42496D01* +X13732Y42370D01* +X13658Y42230D01* +X13608Y42080D01* +X13581Y41924D01* +X13579Y41766D01* +X13602Y41610D01* +X13652Y41460D01* +X13778Y41108D01* +X13866Y40744D01* +X13919Y40374D01* +X13937Y40000D01* +X13919Y39626D01* +X13866Y39256D01* +X13778Y38892D01* +X13656Y38539D01* +X13606Y38389D01* +X13583Y38234D01* +X13585Y38076D01* +X13612Y37921D01* +X13662Y37772D01* +X13736Y37633D01* +X13830Y37507D01* +X13942Y37397D01* +X14071Y37306D01* +X14212Y37236D01* +X14362Y37189D01* +X14518Y37167D01* +X14675Y37168D01* +X14831Y37195D01* +X14980Y37246D01* +X15119Y37319D01* +X15245Y37413D01* +X15355Y37525D01* +X15446Y37654D01* +X15513Y37796D01* +X15704Y38328D01* +X15837Y38877D01* +X15917Y39436D01* +X15944Y40000D01* +X15917Y40564D01* +X15837Y41123D01* +X15704Y41672D01* +X15519Y42206D01* +X15450Y42348D01* +X15358Y42477D01* +X15336Y42500D01* +X17500D01* +Y32500D01* +X7500D01* +Y34670D01* +X7525Y34645D01* +X7654Y34554D01* +X7796Y34487D01* +X8328Y34296D01* +X8877Y34163D01* +X9436Y34083D01* +X10000Y34056D01* +X10564Y34083D01* +X11123Y34163D01* +X11672Y34296D01* +X12206Y34481D01* +X12348Y34550D01* +X12477Y34642D01* +X12591Y34752D01* +X12685Y34879D01* +X12759Y35019D01* +X12809Y35168D01* +X12836Y35324D01* +X12838Y35482D01* +X12815Y35639D01* +X12768Y35790D01* +X12698Y35931D01* +X12607Y36061D01* +X12496Y36174D01* +X12370Y36268D01* +X12230Y36342D01* +X12080Y36392D01* +X11924Y36419D01* +X11766Y36421D01* +X11610Y36398D01* +X11460Y36348D01* +X11108Y36222D01* +X10744Y36134D01* +X10374Y36081D01* +X10000Y36063D01* +X9626Y36081D01* +X9256Y36134D01* +X8892Y36222D01* +X8539Y36344D01* +X8389Y36394D01* +X8234Y36417D01* +X8076Y36415D01* +X7921Y36388D01* +X7772Y36338D01* +X7633Y36264D01* +X7507Y36170D01* +X7500Y36164D01* +Y42500D01* +X13830D01* +G37* +G54D17*X10000Y40000D03* +G54D18*M02* Index: tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,2155 @@ +G04 start of page 8 for group -1 layer_idx 268435461 * +G04 Title: thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD26C,0.0100*% +%ADD25C,0.0075*% +%ADD24C,0.0060*% +%ADD23C,0.0080*% +G54D23*X10000Y40000D02*Y38400D01* +Y40000D02*X11387Y40800D01* +X10000Y40000D02*X8613Y40800D01* +X15000Y106250D02*Y104650D01* +Y106250D02*X16387Y107050D01* +X15000Y106250D02*X13613Y107050D01* +G54D24*X135000Y108500D02*X136500Y105500D01* +X138000Y108500D01* +X136500Y105500D02*Y102500D01* +X139800Y105800D02*X142050D01* +X139800Y102500D02*X142800D01* +X139800Y108500D02*Y102500D01* +Y108500D02*X142800D01* +X147600D02*X148350Y107750D01* +X145350Y108500D02*X147600D01* +X144600Y107750D02*X145350Y108500D01* +X144600Y107750D02*Y106250D01* +X145350Y105500D01* +X147600D01* +X148350Y104750D01* +Y103250D01* +X147600Y102500D02*X148350Y103250D01* +X145350Y102500D02*X147600D01* +X144600Y103250D02*X145350Y102500D01* +X98000Y107300D02*X99200Y108500D01* +Y102500D01* +X98000D02*X100250D01* +X45000Y103250D02*X45750Y102500D01* +X45000Y107750D02*Y103250D01* +Y107750D02*X45750Y108500D01* +X47250D01* +X48000Y107750D01* +Y103250D01* +X47250Y102500D02*X48000Y103250D01* +X45750Y102500D02*X47250D01* +X45000Y104000D02*X48000Y107000D01* +X49800Y102500D02*X50550D01* +X52350Y103250D02*X53100Y102500D01* +X52350Y107750D02*Y103250D01* +Y107750D02*X53100Y108500D01* +X54600D01* +X55350Y107750D01* +Y103250D01* +X54600Y102500D02*X55350Y103250D01* +X53100Y102500D02*X54600D01* +X52350Y104000D02*X55350Y107000D01* +X57150Y107750D02*X57900Y108500D01* +X59400D01* +X60150Y107750D01* +X59400Y102500D02*X60150Y103250D01* +X57900Y102500D02*X59400D01* +X57150Y103250D02*X57900Y102500D01* +Y105800D02*X59400D01* +X60150Y107750D02*Y106550D01* +Y105050D02*Y103250D01* +Y105050D02*X59400Y105800D01* +X60150Y106550D02*X59400Y105800D01* +X61950Y107750D02*X62700Y108500D01* +X64950D01* +X65700Y107750D01* +Y106250D01* +X61950Y102500D02*X65700Y106250D01* +X61950Y102500D02*X65700D01* +X3000Y123500D02*X3750Y122750D01* +X750Y123500D02*X3000D01* +X0Y122750D02*X750Y123500D01* +X0Y122750D02*Y121250D01* +X750Y120500D01* +X3000D01* +X3750Y119750D01* +Y118250D01* +X3000Y117500D02*X3750Y118250D01* +X750Y117500D02*X3000D01* +X0Y118250D02*X750Y117500D01* +X5550Y120500D02*Y118250D01* +X6300Y117500D01* +X8550Y120500D02*Y116000D01* +X7800Y115250D02*X8550Y116000D01* +X6300Y115250D02*X7800D01* +X5550Y116000D02*X6300Y115250D01* +Y117500D02*X7800D01* +X8550Y118250D01* +X11100Y119750D02*Y117500D01* +Y119750D02*X11850Y120500D01* +X12600D01* +X13350Y119750D01* +Y117500D01* +Y119750D02*X14100Y120500D01* +X14850D01* +X15600Y119750D01* +Y117500D01* +X10350Y120500D02*X11100Y119750D01* +X17400Y123500D02*Y117500D01* +Y118250D02*X18150Y117500D01* +X19650D01* +X20400Y118250D01* +Y119750D02*Y118250D01* +X19650Y120500D02*X20400Y119750D01* +X18150Y120500D02*X19650D01* +X17400Y119750D02*X18150Y120500D01* +X22200Y119750D02*Y118250D01* +Y119750D02*X22950Y120500D01* +X24450D01* +X25200Y119750D01* +Y118250D01* +X24450Y117500D02*X25200Y118250D01* +X22950Y117500D02*X24450D01* +X22200Y118250D02*X22950Y117500D01* +X27000Y123500D02*Y118250D01* +X27750Y117500D01* +X0Y114250D02*X29250D01* +X41750Y123500D02*Y117500D01* +X43700Y123500D02*X44750Y122450D01* +Y118550D01* +X43700Y117500D02*X44750Y118550D01* +X41000Y117500D02*X43700D01* +X41000Y123500D02*X43700D01* +G54D25*X46550Y122000D02*Y121850D01* +G54D24*Y119750D02*Y117500D01* +X50300Y120500D02*X51050Y119750D01* +X48800Y120500D02*X50300D01* +X48050Y119750D02*X48800Y120500D01* +X48050Y119750D02*Y118250D01* +X48800Y117500D01* +X51050Y120500D02*Y118250D01* +X51800Y117500D01* +X48800D02*X50300D01* +X51050Y118250D01* +X54350Y119750D02*Y117500D01* +Y119750D02*X55100Y120500D01* +X55850D01* +X56600Y119750D01* +Y117500D01* +Y119750D02*X57350Y120500D01* +X58100D01* +X58850Y119750D01* +Y117500D01* +X53600Y120500D02*X54350Y119750D01* +X60650Y117500D02*X61400D01* +X65900Y118250D02*X66650Y117500D01* +X65900Y122750D02*X66650Y123500D01* +X65900Y122750D02*Y118250D01* +X68450Y123500D02*X69950D01* +X69200D02*Y117500D01* +X68450D02*X69950D01* +X72500Y119750D02*Y117500D01* +Y119750D02*X73250Y120500D01* +X74000D01* +X74750Y119750D01* +Y117500D01* +X71750Y120500D02*X72500Y119750D01* +X77300Y120500D02*X79550D01* +X76550Y119750D02*X77300Y120500D01* +X76550Y119750D02*Y118250D01* +X77300Y117500D01* +X79550D01* +X81350Y123500D02*Y117500D01* +Y119750D02*X82100Y120500D01* +X83600D01* +X84350Y119750D01* +Y117500D01* +X86150Y123500D02*X86900Y122750D01* +Y118250D01* +X86150Y117500D02*X86900Y118250D01* +X41000Y114250D02*X88700D01* +X96050Y117500D02*X98000D01* +X95000Y118550D02*X96050Y117500D01* +X95000Y122450D02*Y118550D01* +Y122450D02*X96050Y123500D01* +X98000D01* +X99800Y119750D02*Y118250D01* +Y119750D02*X100550Y120500D01* +X102050D01* +X102800Y119750D01* +Y118250D01* +X102050Y117500D02*X102800Y118250D01* +X100550Y117500D02*X102050D01* +X99800Y118250D02*X100550Y117500D01* +X104600Y120500D02*Y118250D01* +X105350Y117500D01* +X106850D01* +X107600Y118250D01* +Y120500D02*Y118250D01* +X110150Y119750D02*Y117500D01* +Y119750D02*X110900Y120500D01* +X111650D01* +X112400Y119750D01* +Y117500D01* +X109400Y120500D02*X110150Y119750D01* +X114950Y123500D02*Y118250D01* +X115700Y117500D01* +X114200Y121250D02*X115700D01* +X95000Y114250D02*X117200D01* +X130750Y123500D02*Y117500D01* +X130000Y123500D02*X133000D01* +X133750Y122750D01* +Y121250D01* +X133000Y120500D02*X133750Y121250D01* +X130750Y120500D02*X133000D01* +X135550Y123500D02*Y118250D01* +X136300Y117500D01* +X140050Y120500D02*X140800Y119750D01* +X138550Y120500D02*X140050D01* +X137800Y119750D02*X138550Y120500D01* +X137800Y119750D02*Y118250D01* +X138550Y117500D01* +X140800Y120500D02*Y118250D01* +X141550Y117500D01* +X138550D02*X140050D01* +X140800Y118250D01* +X144100Y123500D02*Y118250D01* +X144850Y117500D01* +X143350Y121250D02*X144850D01* +X147100Y117500D02*X149350D01* +X146350Y118250D02*X147100Y117500D01* +X146350Y119750D02*Y118250D01* +Y119750D02*X147100Y120500D01* +X148600D01* +X149350Y119750D01* +X146350Y119000D02*X149350D01* +Y119750D01* +X154150Y123500D02*Y117500D01* +X153400D02*X154150Y118250D01* +X151900Y117500D02*X153400D01* +X151150Y118250D02*X151900Y117500D01* +X151150Y119750D02*Y118250D01* +Y119750D02*X151900Y120500D01* +X153400D01* +X154150Y119750D01* +X157450Y120500D02*Y119750D01* +Y118250D02*Y117500D01* +X155950Y122750D02*Y122000D01* +Y122750D02*X156700Y123500D01* +X158200D01* +X158950Y122750D01* +Y122000D01* +X157450Y120500D02*X158950Y122000D01* +X130000Y114250D02*X160750D01* +X0Y138500D02*X3000D01* +X1500D02*Y132500D01* +X4800Y138500D02*Y132500D01* +Y134750D02*X5550Y135500D01* +X7050D01* +X7800Y134750D01* +Y132500D01* +X10350D02*X12600D01* +X9600Y133250D02*X10350Y132500D01* +X9600Y134750D02*Y133250D01* +Y134750D02*X10350Y135500D01* +X11850D01* +X12600Y134750D01* +X9600Y134000D02*X12600D01* +Y134750D01* +X15150D02*Y132500D01* +Y134750D02*X15900Y135500D01* +X17400D01* +X14400D02*X15150Y134750D01* +X19950Y132500D02*X22200D01* +X19200Y133250D02*X19950Y132500D01* +X19200Y134750D02*Y133250D01* +Y134750D02*X19950Y135500D01* +X21450D01* +X22200Y134750D01* +X19200Y134000D02*X22200D01* +Y134750D01* +X28950Y135500D02*X29700Y134750D01* +X27450Y135500D02*X28950D01* +X26700Y134750D02*X27450Y135500D01* +X26700Y134750D02*Y133250D01* +X27450Y132500D01* +X29700Y135500D02*Y133250D01* +X30450Y132500D01* +X27450D02*X28950D01* +X29700Y133250D01* +X33000Y134750D02*Y132500D01* +Y134750D02*X33750Y135500D01* +X35250D01* +X32250D02*X33000Y134750D01* +X37800Y132500D02*X40050D01* +X37050Y133250D02*X37800Y132500D01* +X37050Y134750D02*Y133250D01* +Y134750D02*X37800Y135500D01* +X39300D01* +X40050Y134750D01* +X37050Y134000D02*X40050D01* +Y134750D01* +X44550Y137300D02*X45750Y138500D01* +Y132500D01* +X44550D02*X46800D01* +X54300Y138500D02*Y132500D01* +X53550D02*X54300Y133250D01* +X52050Y132500D02*X53550D01* +X51300Y133250D02*X52050Y132500D01* +X51300Y134750D02*Y133250D01* +Y134750D02*X52050Y135500D01* +X53550D01* +X54300Y134750D01* +G54D25*X56100Y137000D02*Y136850D01* +G54D24*Y134750D02*Y132500D01* +X58350Y137750D02*Y132500D01* +Y137750D02*X59100Y138500D01* +X59850D01* +X57600Y135500D02*X59100D01* +X62100Y137750D02*Y132500D01* +Y137750D02*X62850Y138500D01* +X63600D01* +X61350Y135500D02*X62850D01* +X65850Y132500D02*X68100D01* +X65100Y133250D02*X65850Y132500D01* +X65100Y134750D02*Y133250D01* +Y134750D02*X65850Y135500D01* +X67350D01* +X68100Y134750D01* +X65100Y134000D02*X68100D01* +Y134750D01* +X70650D02*Y132500D01* +Y134750D02*X71400Y135500D01* +X72900D01* +X69900D02*X70650Y134750D01* +X75450Y132500D02*X77700D01* +X74700Y133250D02*X75450Y132500D01* +X74700Y134750D02*Y133250D01* +Y134750D02*X75450Y135500D01* +X76950D01* +X77700Y134750D01* +X74700Y134000D02*X77700D01* +Y134750D01* +X80250D02*Y132500D01* +Y134750D02*X81000Y135500D01* +X81750D01* +X82500Y134750D01* +Y132500D01* +X79500Y135500D02*X80250Y134750D01* +X85050Y138500D02*Y133250D01* +X85800Y132500D01* +X84300Y136250D02*X85800D01* +X93000Y138500D02*Y132500D01* +X92250D02*X93000Y133250D01* +X90750Y132500D02*X92250D01* +X90000Y133250D02*X90750Y132500D01* +X90000Y134750D02*Y133250D01* +Y134750D02*X90750Y135500D01* +X92250D01* +X93000Y134750D01* +X95550D02*Y132500D01* +Y134750D02*X96300Y135500D01* +X97800D01* +X94800D02*X95550Y134750D01* +G54D25*X99600Y137000D02*Y136850D01* +G54D24*Y134750D02*Y132500D01* +X101100Y138500D02*Y133250D01* +X101850Y132500D01* +X103350Y138500D02*Y133250D01* +X104100Y132500D01* +X109050D02*X111300D01* +X112050Y133250D01* +X111300Y134000D02*X112050Y133250D01* +X109050Y134000D02*X111300D01* +X108300Y134750D02*X109050Y134000D01* +X108300Y134750D02*X109050Y135500D01* +X111300D01* +X112050Y134750D01* +X108300Y133250D02*X109050Y132500D01* +G54D25*X113850Y137000D02*Y136850D01* +G54D24*Y134750D02*Y132500D01* +X115350Y135500D02*X118350D01* +X115350Y132500D02*X118350Y135500D01* +X115350Y132500D02*X118350D01* +X120900D02*X123150D01* +X120150Y133250D02*X120900Y132500D01* +X120150Y134750D02*Y133250D01* +Y134750D02*X120900Y135500D01* +X122400D01* +X123150Y134750D01* +X120150Y134000D02*X123150D01* +Y134750D01* +X125700Y132500D02*X127950D01* +X128700Y133250D01* +X127950Y134000D02*X128700Y133250D01* +X125700Y134000D02*X127950D01* +X124950Y134750D02*X125700Y134000D01* +X124950Y134750D02*X125700Y135500D01* +X127950D01* +X128700Y134750D01* +X124950Y133250D02*X125700Y132500D01* +X133200Y135500D02*Y133250D01* +X133950Y132500D01* +X135450D01* +X136200Y133250D01* +Y135500D02*Y133250D01* +X138750Y132500D02*X141000D01* +X141750Y133250D01* +X141000Y134000D02*X141750Y133250D01* +X138750Y134000D02*X141000D01* +X138000Y134750D02*X138750Y134000D01* +X138000Y134750D02*X138750Y135500D01* +X141000D01* +X141750Y134750D01* +X138000Y133250D02*X138750Y132500D01* +X144300D02*X146550D01* +X143550Y133250D02*X144300Y132500D01* +X143550Y134750D02*Y133250D01* +Y134750D02*X144300Y135500D01* +X145800D01* +X146550Y134750D01* +X143550Y134000D02*X146550D01* +Y134750D01* +X151350Y138500D02*Y132500D01* +X150600D02*X151350Y133250D01* +X149100Y132500D02*X150600D01* +X148350Y133250D02*X149100Y132500D01* +X148350Y134750D02*Y133250D01* +Y134750D02*X149100Y135500D01* +X150600D01* +X151350Y134750D01* +G54D25*X155850Y137000D02*Y136850D01* +G54D24*Y134750D02*Y132500D01* +X158100Y134750D02*Y132500D01* +Y134750D02*X158850Y135500D01* +X159600D01* +X160350Y134750D01* +Y132500D01* +X157350Y135500D02*X158100Y134750D01* +X165600Y138500D02*Y133250D01* +X166350Y132500D01* +X164850Y136250D02*X166350D01* +X167850Y138500D02*Y132500D01* +Y134750D02*X168600Y135500D01* +X170100D01* +X170850Y134750D01* +Y132500D01* +G54D25*X172650Y137000D02*Y136850D01* +G54D24*Y134750D02*Y132500D01* +X174900D02*X177150D01* +X177900Y133250D01* +X177150Y134000D02*X177900Y133250D01* +X174900Y134000D02*X177150D01* +X174150Y134750D02*X174900Y134000D01* +X174150Y134750D02*X174900Y135500D01* +X177150D01* +X177900Y134750D01* +X174150Y133250D02*X174900Y132500D01* +X182400Y138500D02*Y133250D01* +X183150Y132500D01* +X186900Y135500D02*X187650Y134750D01* +X185400Y135500D02*X186900D01* +X184650Y134750D02*X185400Y135500D01* +X184650Y134750D02*Y133250D01* +X185400Y132500D01* +X187650Y135500D02*Y133250D01* +X188400Y132500D01* +X185400D02*X186900D01* +X187650Y133250D01* +X190200Y135500D02*Y133250D01* +X190950Y132500D01* +X193200Y135500D02*Y131000D01* +X192450Y130250D02*X193200Y131000D01* +X190950Y130250D02*X192450D01* +X190200Y131000D02*X190950Y130250D01* +Y132500D02*X192450D01* +X193200Y133250D01* +X195000Y134750D02*Y133250D01* +Y134750D02*X195750Y135500D01* +X197250D01* +X198000Y134750D01* +Y133250D01* +X197250Y132500D02*X198000Y133250D01* +X195750Y132500D02*X197250D01* +X195000Y133250D02*X195750Y132500D01* +X199800Y135500D02*Y133250D01* +X200550Y132500D01* +X202050D01* +X202800Y133250D01* +Y135500D02*Y133250D01* +X205350Y138500D02*Y133250D01* +X206100Y132500D01* +X204600Y136250D02*X206100D01* +X207600Y131000D02*X209100Y132500D01* +X213600Y137300D02*X214800Y138500D01* +Y132500D01* +X213600D02*X215850D01* +X220350Y138500D02*Y132500D01* +Y134750D02*X221100Y135500D01* +X222600D01* +X223350Y134750D01* +Y132500D01* +X225150Y134750D02*Y133250D01* +Y134750D02*X225900Y135500D01* +X227400D01* +X228150Y134750D01* +Y133250D01* +X227400Y132500D02*X228150Y133250D01* +X225900Y132500D02*X227400D01* +X225150Y133250D02*X225900Y132500D01* +X229950Y138500D02*Y133250D01* +X230700Y132500D01* +X232950D02*X235200D01* +X232200Y133250D02*X232950Y132500D01* +X232200Y134750D02*Y133250D01* +Y134750D02*X232950Y135500D01* +X234450D01* +X235200Y134750D01* +X232200Y134000D02*X235200D01* +Y134750D01* +X237750Y132500D02*X240000D01* +X240750Y133250D01* +X240000Y134000D02*X240750Y133250D01* +X237750Y134000D02*X240000D01* +X237000Y134750D02*X237750Y134000D01* +X237000Y134750D02*X237750Y135500D01* +X240000D01* +X240750Y134750D01* +X237000Y133250D02*X237750Y132500D01* +X246000Y138500D02*Y133250D01* +X246750Y132500D01* +X245250Y136250D02*X246750D01* +X248250Y134750D02*Y133250D01* +Y134750D02*X249000Y135500D01* +X250500D01* +X251250Y134750D01* +Y133250D01* +X250500Y132500D02*X251250Y133250D01* +X249000Y132500D02*X250500D01* +X248250Y133250D02*X249000Y132500D01* +X253800Y138500D02*Y133250D01* +X254550Y132500D01* +X253050Y136250D02*X254550D01* +X258300Y135500D02*X259050Y134750D01* +X256800Y135500D02*X258300D01* +X256050Y134750D02*X256800Y135500D01* +X256050Y134750D02*Y133250D01* +X256800Y132500D01* +X259050Y135500D02*Y133250D01* +X259800Y132500D01* +X256800D02*X258300D01* +X259050Y133250D01* +X261600Y138500D02*Y133250D01* +X262350Y132500D01* +G54D26*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D24*X200000Y63500D02*Y57500D01* +Y63500D02*X202250Y60500D01* +X204500Y63500D01* +Y57500D01* +X208550Y60500D02*X209300Y59750D01* +X207050Y60500D02*X208550D01* +X206300Y59750D02*X207050Y60500D01* +X206300Y59750D02*Y58250D01* +X207050Y57500D01* +X209300Y60500D02*Y58250D01* +X210050Y57500D01* +X207050D02*X208550D01* +X209300Y58250D01* +X211850Y60500D02*X214850Y57500D01* +X211850D02*X214850Y60500D01* +G54D25*X216650Y62000D02*Y61850D01* +G54D24*Y59750D02*Y57500D01* +X218900Y59750D02*Y57500D01* +Y59750D02*X219650Y60500D01* +X220400D01* +X221150Y59750D01* +Y57500D01* +Y59750D02*X221900Y60500D01* +X222650D01* +X223400Y59750D01* +Y57500D01* +X218150Y60500D02*X218900Y59750D01* +X225200Y60500D02*Y58250D01* +X225950Y57500D01* +X227450D01* +X228200Y58250D01* +Y60500D02*Y58250D01* +X230750Y59750D02*Y57500D01* +Y59750D02*X231500Y60500D01* +X232250D01* +X233000Y59750D01* +Y57500D01* +Y59750D02*X233750Y60500D01* +X234500D01* +X235250Y59750D01* +Y57500D01* +X230000Y60500D02*X230750Y59750D01* +X240500Y63500D02*Y57500D01* +X242450Y63500D02*X243500Y62450D01* +Y58550D01* +X242450Y57500D02*X243500Y58550D01* +X239750Y57500D02*X242450D01* +X239750Y63500D02*X242450D01* +G54D25*X245300Y62000D02*Y61850D01* +G54D24*Y59750D02*Y57500D01* +X247550Y59750D02*Y57500D01* +Y59750D02*X248300Y60500D01* +X249050D01* +X249800Y59750D01* +Y57500D01* +Y59750D02*X250550Y60500D01* +X251300D01* +X252050Y59750D01* +Y57500D01* +X246800Y60500D02*X247550Y59750D01* +X254600Y57500D02*X256850D01* +X253850Y58250D02*X254600Y57500D01* +X253850Y59750D02*Y58250D01* +Y59750D02*X254600Y60500D01* +X256100D01* +X256850Y59750D01* +X253850Y59000D02*X256850D01* +Y59750D01* +X259400D02*Y57500D01* +Y59750D02*X260150Y60500D01* +X260900D01* +X261650Y59750D01* +Y57500D01* +X258650Y60500D02*X259400Y59750D01* +X264200Y57500D02*X266450D01* +X267200Y58250D01* +X266450Y59000D02*X267200Y58250D01* +X264200Y59000D02*X266450D01* +X263450Y59750D02*X264200Y59000D01* +X263450Y59750D02*X264200Y60500D01* +X266450D01* +X267200Y59750D01* +X263450Y58250D02*X264200Y57500D01* +G54D25*X269000Y62000D02*Y61850D01* +G54D24*Y59750D02*Y57500D01* +X270500Y59750D02*Y58250D01* +Y59750D02*X271250Y60500D01* +X272750D01* +X273500Y59750D01* +Y58250D01* +X272750Y57500D02*X273500Y58250D01* +X271250Y57500D02*X272750D01* +X270500Y58250D02*X271250Y57500D01* +X276050Y59750D02*Y57500D01* +Y59750D02*X276800Y60500D01* +X277550D01* +X278300Y59750D01* +Y57500D01* +X275300Y60500D02*X276050Y59750D01* +X280850Y57500D02*X283100D01* +X283850Y58250D01* +X283100Y59000D02*X283850Y58250D01* +X280850Y59000D02*X283100D01* +X280100Y59750D02*X280850Y59000D01* +X280100Y59750D02*X280850Y60500D01* +X283100D01* +X283850Y59750D01* +X280100Y58250D02*X280850Y57500D01* +X285650Y61250D02*X286400D01* +X285650Y59750D02*X286400D01* +X290900Y63500D02*X293900D01* +X290900D02*Y60500D01* +X291650Y61250D01* +X293150D01* +X293900Y60500D01* +Y58250D01* +X293150Y57500D02*X293900Y58250D01* +X291650Y57500D02*X293150D01* +X290900Y58250D02*X291650Y57500D01* +X295700Y58250D02*X296450Y57500D01* +X295700Y62750D02*Y58250D01* +Y62750D02*X296450Y63500D01* +X297950D01* +X298700Y62750D01* +Y58250D01* +X297950Y57500D02*X298700Y58250D01* +X296450Y57500D02*X297950D01* +X295700Y59000D02*X298700Y62000D01* +X300500Y58250D02*X301250Y57500D01* +X300500Y62750D02*Y58250D01* +Y62750D02*X301250Y63500D01* +X302750D01* +X303500Y62750D01* +Y58250D01* +X302750Y57500D02*X303500Y58250D01* +X301250Y57500D02*X302750D01* +X300500Y59000D02*X303500Y62000D01* +X305300Y57500D02*X306050D01* +X307850Y58250D02*X308600Y57500D01* +X307850Y62750D02*Y58250D01* +Y62750D02*X308600Y63500D01* +X310100D01* +X310850Y62750D01* +Y58250D01* +X310100Y57500D02*X310850Y58250D01* +X308600Y57500D02*X310100D01* +X307850Y59000D02*X310850Y62000D01* +X312650Y58250D02*X313400Y57500D01* +X312650Y62750D02*Y58250D01* +Y62750D02*X313400Y63500D01* +X314900D01* +X315650Y62750D01* +Y58250D01* +X314900Y57500D02*X315650Y58250D01* +X313400Y57500D02*X314900D01* +X312650Y59000D02*X315650Y62000D01* +X317450Y58250D02*X318200Y57500D01* +X317450Y62750D02*Y58250D01* +Y62750D02*X318200Y63500D01* +X319700D01* +X320450Y62750D01* +Y58250D01* +X319700Y57500D02*X320450Y58250D01* +X318200Y57500D02*X319700D01* +X317450Y59000D02*X320450Y62000D01* +X322250Y58250D02*X323000Y57500D01* +X322250Y62750D02*Y58250D01* +Y62750D02*X323000Y63500D01* +X324500D01* +X325250Y62750D01* +Y58250D01* +X324500Y57500D02*X325250Y58250D01* +X323000Y57500D02*X324500D01* +X322250Y59000D02*X325250Y62000D01* +X327050Y58250D02*X327800Y57500D01* +X327050Y62750D02*Y58250D01* +Y62750D02*X327800Y63500D01* +X329300D01* +X330050Y62750D01* +Y58250D01* +X329300Y57500D02*X330050Y58250D01* +X327800Y57500D02*X329300D01* +X327050Y59000D02*X330050Y62000D01* +X331850Y58250D02*X332600Y57500D01* +X331850Y62750D02*Y58250D01* +Y62750D02*X332600Y63500D01* +X334100D01* +X334850Y62750D01* +Y58250D01* +X334100Y57500D02*X334850Y58250D01* +X332600Y57500D02*X334100D01* +X331850Y59000D02*X334850Y62000D01* +X340100Y59750D02*Y57500D01* +Y59750D02*X340850Y60500D01* +X341600D01* +X342350Y59750D01* +Y57500D01* +Y59750D02*X343100Y60500D01* +X343850D01* +X344600Y59750D01* +Y57500D01* +X339350Y60500D02*X340100Y59750D01* +G54D25*X346400Y62000D02*Y61850D01* +G54D24*Y59750D02*Y57500D01* +X347900Y63500D02*Y58250D01* +X348650Y57500D01* +X350900D02*X353150D01* +X353900Y58250D01* +X353150Y59000D02*X353900Y58250D01* +X350900Y59000D02*X353150D01* +X350150Y59750D02*X350900Y59000D01* +X350150Y59750D02*X350900Y60500D01* +X353150D01* +X353900Y59750D01* +X350150Y58250D02*X350900Y57500D01* +X358400Y60500D02*Y58250D01* +X359150Y57500D01* +X359900D01* +X360650Y58250D01* +Y60500D02*Y58250D01* +X361400Y57500D01* +X362150D01* +X362900Y58250D01* +Y60500D02*Y58250D01* +G54D25*X364700Y62000D02*Y61850D01* +G54D24*Y59750D02*Y57500D01* +X369200Y63500D02*Y57500D01* +X368450D02*X369200Y58250D01* +X366950Y57500D02*X368450D01* +X366200Y58250D02*X366950Y57500D01* +X366200Y59750D02*Y58250D01* +Y59750D02*X366950Y60500D01* +X368450D01* +X369200Y59750D01* +X371750Y57500D02*X374000D01* +X371000Y58250D02*X371750Y57500D01* +X371000Y59750D02*Y58250D01* +Y59750D02*X371750Y60500D01* +X373250D01* +X374000Y59750D01* +X371000Y59000D02*X374000D01* +Y59750D01* +X375800Y56000D02*X377300Y57500D01* +X381800Y63500D02*X384800D01* +X381800D02*Y60500D01* +X382550Y61250D01* +X384050D01* +X384800Y60500D01* +Y58250D01* +X384050Y57500D02*X384800Y58250D01* +X382550Y57500D02*X384050D01* +X381800Y58250D02*X382550Y57500D01* +X386600Y58250D02*X387350Y57500D01* +X386600Y62750D02*Y58250D01* +Y62750D02*X387350Y63500D01* +X388850D01* +X389600Y62750D01* +Y58250D01* +X388850Y57500D02*X389600Y58250D01* +X387350Y57500D02*X388850D01* +X386600Y59000D02*X389600Y62000D01* +X391400Y58250D02*X392150Y57500D01* +X391400Y62750D02*Y58250D01* +Y62750D02*X392150Y63500D01* +X393650D01* +X394400Y62750D01* +Y58250D01* +X393650Y57500D02*X394400Y58250D01* +X392150Y57500D02*X393650D01* +X391400Y59000D02*X394400Y62000D01* +X396200Y57500D02*X396950D01* +X398750Y58250D02*X399500Y57500D01* +X398750Y62750D02*Y58250D01* +Y62750D02*X399500Y63500D01* +X401000D01* +X401750Y62750D01* +Y58250D01* +X401000Y57500D02*X401750Y58250D01* +X399500Y57500D02*X401000D01* +X398750Y59000D02*X401750Y62000D01* +X403550Y58250D02*X404300Y57500D01* +X403550Y62750D02*Y58250D01* +Y62750D02*X404300Y63500D01* +X405800D01* +X406550Y62750D01* +Y58250D01* +X405800Y57500D02*X406550Y58250D01* +X404300Y57500D02*X405800D01* +X403550Y59000D02*X406550Y62000D01* +X408350Y58250D02*X409100Y57500D01* +X408350Y62750D02*Y58250D01* +Y62750D02*X409100Y63500D01* +X410600D01* +X411350Y62750D01* +Y58250D01* +X410600Y57500D02*X411350Y58250D01* +X409100Y57500D02*X410600D01* +X408350Y59000D02*X411350Y62000D01* +X413150Y58250D02*X413900Y57500D01* +X413150Y62750D02*Y58250D01* +Y62750D02*X413900Y63500D01* +X415400D01* +X416150Y62750D01* +Y58250D01* +X415400Y57500D02*X416150Y58250D01* +X413900Y57500D02*X415400D01* +X413150Y59000D02*X416150Y62000D01* +X417950Y58250D02*X418700Y57500D01* +X417950Y62750D02*Y58250D01* +Y62750D02*X418700Y63500D01* +X420200D01* +X420950Y62750D01* +Y58250D01* +X420200Y57500D02*X420950Y58250D01* +X418700Y57500D02*X420200D01* +X417950Y59000D02*X420950Y62000D01* +X422750Y58250D02*X423500Y57500D01* +X422750Y62750D02*Y58250D01* +Y62750D02*X423500Y63500D01* +X425000D01* +X425750Y62750D01* +Y58250D01* +X425000Y57500D02*X425750Y58250D01* +X423500Y57500D02*X425000D01* +X422750Y59000D02*X425750Y62000D01* +X431000Y59750D02*Y57500D01* +Y59750D02*X431750Y60500D01* +X432500D01* +X433250Y59750D01* +Y57500D01* +Y59750D02*X434000Y60500D01* +X434750D01* +X435500Y59750D01* +Y57500D01* +X430250Y60500D02*X431000Y59750D01* +G54D25*X437300Y62000D02*Y61850D01* +G54D24*Y59750D02*Y57500D01* +X438800Y63500D02*Y58250D01* +X439550Y57500D01* +X441800D02*X444050D01* +X444800Y58250D01* +X444050Y59000D02*X444800Y58250D01* +X441800Y59000D02*X444050D01* +X441050Y59750D02*X441800Y59000D01* +X441050Y59750D02*X441800Y60500D01* +X444050D01* +X444800Y59750D01* +X441050Y58250D02*X441800Y57500D01* +X449300Y63500D02*Y57500D01* +Y59750D02*X450050Y60500D01* +X451550D01* +X452300Y59750D01* +Y57500D01* +G54D25*X454100Y62000D02*Y61850D01* +G54D24*Y59750D02*Y57500D01* +X457850Y60500D02*X458600Y59750D01* +X456350Y60500D02*X457850D01* +X455600Y59750D02*X456350Y60500D01* +X455600Y59750D02*Y58250D01* +X456350Y57500D01* +X457850D01* +X458600Y58250D01* +X455600Y56000D02*X456350Y55250D01* +X457850D01* +X458600Y56000D01* +Y60500D02*Y56000D01* +X460400Y63500D02*Y57500D01* +Y59750D02*X461150Y60500D01* +X462650D01* +X463400Y59750D01* +Y57500D01* +X0Y-9500D02*X3000D01* +X3750Y-8750D01* +Y-6950D02*Y-8750D01* +X3000Y-6200D02*X3750Y-6950D01* +X750Y-6200D02*X3000D01* +X750Y-3500D02*Y-9500D01* +X0Y-3500D02*X3000D01* +X3750Y-4250D01* +Y-5450D01* +X3000Y-6200D02*X3750Y-5450D01* +X5550Y-7250D02*Y-8750D01* +Y-7250D02*X6300Y-6500D01* +X7800D01* +X8550Y-7250D01* +Y-8750D01* +X7800Y-9500D02*X8550Y-8750D01* +X6300Y-9500D02*X7800D01* +X5550Y-8750D02*X6300Y-9500D01* +X12600Y-6500D02*X13350Y-7250D01* +X11100Y-6500D02*X12600D01* +X10350Y-7250D02*X11100Y-6500D01* +X10350Y-7250D02*Y-8750D01* +X11100Y-9500D01* +X13350Y-6500D02*Y-8750D01* +X14100Y-9500D01* +X11100D02*X12600D01* +X13350Y-8750D01* +X16650Y-7250D02*Y-9500D01* +Y-7250D02*X17400Y-6500D01* +X18900D01* +X15900D02*X16650Y-7250D01* +X23700Y-3500D02*Y-9500D01* +X22950D02*X23700Y-8750D01* +X21450Y-9500D02*X22950D01* +X20700Y-8750D02*X21450Y-9500D01* +X20700Y-7250D02*Y-8750D01* +Y-7250D02*X21450Y-6500D01* +X22950D01* +X23700Y-7250D01* +X28200D02*Y-8750D01* +Y-7250D02*X28950Y-6500D01* +X30450D01* +X31200Y-7250D01* +Y-8750D01* +X30450Y-9500D02*X31200Y-8750D01* +X28950Y-9500D02*X30450D01* +X28200Y-8750D02*X28950Y-9500D01* +X33000Y-6500D02*Y-8750D01* +X33750Y-9500D01* +X35250D01* +X36000Y-8750D01* +Y-6500D02*Y-8750D01* +X38550Y-3500D02*Y-8750D01* +X39300Y-9500D01* +X37800Y-5750D02*X39300D01* +X40800Y-3500D02*Y-8750D01* +X41550Y-9500D01* +G54D25*X43050Y-5000D02*Y-5150D01* +G54D24*Y-7250D02*Y-9500D01* +X45300Y-7250D02*Y-9500D01* +Y-7250D02*X46050Y-6500D01* +X46800D01* +X47550Y-7250D01* +Y-9500D01* +X44550Y-6500D02*X45300Y-7250D01* +X50100Y-9500D02*X52350D01* +X49350Y-8750D02*X50100Y-9500D01* +X49350Y-7250D02*Y-8750D01* +Y-7250D02*X50100Y-6500D01* +X51600D01* +X52350Y-7250D01* +X49350Y-8000D02*X52350D01* +Y-7250D01* +G54D25*X56850Y-5000D02*Y-5150D01* +G54D24*Y-7250D02*Y-9500D01* +X59100D02*X61350D01* +X62100Y-8750D01* +X61350Y-8000D02*X62100Y-8750D01* +X59100Y-8000D02*X61350D01* +X58350Y-7250D02*X59100Y-8000D01* +X58350Y-7250D02*X59100Y-6500D01* +X61350D01* +X62100Y-7250D01* +X58350Y-8750D02*X59100Y-9500D01* +X67350Y-3500D02*Y-8750D01* +X68100Y-9500D01* +X66600Y-5750D02*X68100D01* +X69600Y-3500D02*Y-9500D01* +Y-7250D02*X70350Y-6500D01* +X71850D01* +X72600Y-7250D01* +Y-9500D01* +X75150D02*X77400D01* +X74400Y-8750D02*X75150Y-9500D01* +X74400Y-7250D02*Y-8750D01* +Y-7250D02*X75150Y-6500D01* +X76650D01* +X77400Y-7250D01* +X74400Y-8000D02*X77400D01* +Y-7250D01* +X82650Y-6500D02*X84900D01* +X81900Y-7250D02*X82650Y-6500D01* +X81900Y-7250D02*Y-8750D01* +X82650Y-9500D01* +X84900D01* +X87450D02*X89700D01* +X86700Y-8750D02*X87450Y-9500D01* +X86700Y-7250D02*Y-8750D01* +Y-7250D02*X87450Y-6500D01* +X88950D01* +X89700Y-7250D01* +X86700Y-8000D02*X89700D01* +Y-7250D01* +X92250D02*Y-9500D01* +Y-7250D02*X93000Y-6500D01* +X93750D01* +X94500Y-7250D01* +Y-9500D01* +X91500Y-6500D02*X92250Y-7250D01* +X97050Y-3500D02*Y-8750D01* +X97800Y-9500D01* +X96300Y-5750D02*X97800D01* +X100050Y-9500D02*X102300D01* +X99300Y-8750D02*X100050Y-9500D01* +X99300Y-7250D02*Y-8750D01* +Y-7250D02*X100050Y-6500D01* +X101550D01* +X102300Y-7250D01* +X99300Y-8000D02*X102300D01* +Y-7250D01* +X104850D02*Y-9500D01* +Y-7250D02*X105600Y-6500D01* +X107100D01* +X104100D02*X104850Y-7250D01* +X108900Y-3500D02*Y-8750D01* +X109650Y-9500D01* +G54D25*X111150Y-5000D02*Y-5150D01* +G54D24*Y-7250D02*Y-9500D01* +X113400Y-7250D02*Y-9500D01* +Y-7250D02*X114150Y-6500D01* +X114900D01* +X115650Y-7250D01* +Y-9500D01* +X112650Y-6500D02*X113400Y-7250D01* +X118200Y-9500D02*X120450D01* +X117450Y-8750D02*X118200Y-9500D01* +X117450Y-7250D02*Y-8750D01* +Y-7250D02*X118200Y-6500D01* +X119700D01* +X120450Y-7250D01* +X117450Y-8000D02*X120450D01* +Y-7250D01* +X124950D02*Y-8750D01* +Y-7250D02*X125700Y-6500D01* +X127200D01* +X127950Y-7250D01* +Y-8750D01* +X127200Y-9500D02*X127950Y-8750D01* +X125700Y-9500D02*X127200D01* +X124950Y-8750D02*X125700Y-9500D01* +X130500Y-4250D02*Y-9500D01* +Y-4250D02*X131250Y-3500D01* +X132000D01* +X129750Y-6500D02*X131250D01* +X136950Y-3500D02*Y-8750D01* +X137700Y-9500D01* +X136200Y-5750D02*X137700D01* +X139200Y-3500D02*Y-9500D01* +Y-7250D02*X139950Y-6500D01* +X141450D01* +X142200Y-7250D01* +Y-9500D01* +G54D25*X144000Y-5000D02*Y-5150D01* +G54D24*Y-7250D02*Y-9500D01* +X146250D02*X148500D01* +X149250Y-8750D01* +X148500Y-8000D02*X149250Y-8750D01* +X146250Y-8000D02*X148500D01* +X145500Y-7250D02*X146250Y-8000D01* +X145500Y-7250D02*X146250Y-6500D01* +X148500D01* +X149250Y-7250D01* +X145500Y-8750D02*X146250Y-9500D01* +X153750Y-8750D02*X154500Y-9500D01* +X153750Y-7550D02*Y-8750D01* +Y-7550D02*X154800Y-6500D01* +X155700D01* +X156750Y-7550D01* +Y-8750D01* +X156000Y-9500D02*X156750Y-8750D01* +X154500Y-9500D02*X156000D01* +X153750Y-5450D02*X154800Y-6500D01* +X153750Y-4250D02*Y-5450D01* +Y-4250D02*X154500Y-3500D01* +X156000D01* +X156750Y-4250D01* +Y-5450D01* +X155700Y-6500D02*X156750Y-5450D01* +X158550Y-9500D02*X159300D01* +X161100Y-8750D02*X161850Y-9500D01* +X161100Y-4250D02*Y-8750D01* +Y-4250D02*X161850Y-3500D01* +X163350D01* +X164100Y-4250D01* +Y-8750D01* +X163350Y-9500D02*X164100Y-8750D01* +X161850Y-9500D02*X163350D01* +X161100Y-8000D02*X164100Y-5000D01* +X165900Y-8750D02*X166650Y-9500D01* +X165900Y-4250D02*Y-8750D01* +Y-4250D02*X166650Y-3500D01* +X168150D01* +X168900Y-4250D01* +Y-8750D01* +X168150Y-9500D02*X168900Y-8750D01* +X166650Y-9500D02*X168150D01* +X165900Y-8000D02*X168900Y-5000D01* +X170700Y-8750D02*X171450Y-9500D01* +X170700Y-4250D02*Y-8750D01* +Y-4250D02*X171450Y-3500D01* +X172950D01* +X173700Y-4250D01* +Y-8750D01* +X172950Y-9500D02*X173700Y-8750D01* +X171450Y-9500D02*X172950D01* +X170700Y-8000D02*X173700Y-5000D01* +X175500Y-8750D02*X176250Y-9500D01* +X175500Y-4250D02*Y-8750D01* +Y-4250D02*X176250Y-3500D01* +X177750D01* +X178500Y-4250D01* +Y-8750D01* +X177750Y-9500D02*X178500Y-8750D01* +X176250Y-9500D02*X177750D01* +X175500Y-8000D02*X178500Y-5000D01* +X180300Y-8750D02*X181050Y-9500D01* +X180300Y-4250D02*Y-8750D01* +Y-4250D02*X181050Y-3500D01* +X182550D01* +X183300Y-4250D01* +Y-8750D01* +X182550Y-9500D02*X183300Y-8750D01* +X181050Y-9500D02*X182550D01* +X180300Y-8000D02*X183300Y-5000D01* +X185100Y-8750D02*X185850Y-9500D01* +X185100Y-4250D02*Y-8750D01* +Y-4250D02*X185850Y-3500D01* +X187350D01* +X188100Y-4250D01* +Y-8750D01* +X187350Y-9500D02*X188100Y-8750D01* +X185850Y-9500D02*X187350D01* +X185100Y-8000D02*X188100Y-5000D01* +X193350Y-7250D02*Y-9500D01* +Y-7250D02*X194100Y-6500D01* +X194850D01* +X195600Y-7250D01* +Y-9500D01* +Y-7250D02*X196350Y-6500D01* +X197100D01* +X197850Y-7250D01* +Y-9500D01* +X192600Y-6500D02*X193350Y-7250D01* +G54D25*X199650Y-5000D02*Y-5150D01* +G54D24*Y-7250D02*Y-9500D01* +X201150Y-3500D02*Y-8750D01* +X201900Y-9500D01* +X206850Y-7250D02*Y-9500D01* +Y-7250D02*X207600Y-6500D01* +X209100D01* +X206100D02*X206850Y-7250D01* +X211650Y-9500D02*X213900D01* +X210900Y-8750D02*X211650Y-9500D01* +X210900Y-7250D02*Y-8750D01* +Y-7250D02*X211650Y-6500D01* +X213150D01* +X213900Y-7250D01* +X210900Y-8000D02*X213900D01* +Y-7250D01* +X216450Y-6500D02*X218700D01* +X215700Y-7250D02*X216450Y-6500D01* +X215700Y-7250D02*Y-8750D01* +X216450Y-9500D01* +X218700D01* +X221250Y-3500D02*Y-8750D01* +X222000Y-9500D01* +X220500Y-5750D02*X222000D01* +X225750Y-6500D02*X226500Y-7250D01* +X224250Y-6500D02*X225750D01* +X223500Y-7250D02*X224250Y-6500D01* +X223500Y-7250D02*Y-8750D01* +X224250Y-9500D01* +X226500Y-6500D02*Y-8750D01* +X227250Y-9500D01* +X224250D02*X225750D01* +X226500Y-8750D01* +X229800Y-7250D02*Y-9500D01* +Y-7250D02*X230550Y-6500D01* +X231300D01* +X232050Y-7250D01* +Y-9500D01* +X229050Y-6500D02*X229800Y-7250D01* +X236100Y-6500D02*X236850Y-7250D01* +X234600Y-6500D02*X236100D01* +X233850Y-7250D02*X234600Y-6500D01* +X233850Y-7250D02*Y-8750D01* +X234600Y-9500D01* +X236100D01* +X236850Y-8750D01* +X233850Y-11000D02*X234600Y-11750D01* +X236100D01* +X236850Y-11000D01* +Y-6500D02*Y-11000D01* +X238650Y-3500D02*Y-8750D01* +X239400Y-9500D01* +X241650D02*X243900D01* +X240900Y-8750D02*X241650Y-9500D01* +X240900Y-7250D02*Y-8750D01* +Y-7250D02*X241650Y-6500D01* +X243150D01* +X243900Y-7250D01* +X240900Y-8000D02*X243900D01* +Y-7250D01* +X248400Y-6500D02*X251400D01* +X255900Y-8750D02*X256650Y-9500D01* +X255900Y-4250D02*Y-8750D01* +Y-4250D02*X256650Y-3500D01* +X258150D01* +X258900Y-4250D01* +Y-8750D01* +X258150Y-9500D02*X258900Y-8750D01* +X256650Y-9500D02*X258150D01* +X255900Y-8000D02*X258900Y-5000D01* +X260700Y-11000D02*X262200Y-9500D01* +X264000Y-8750D02*X264750Y-9500D01* +X264000Y-4250D02*Y-8750D01* +Y-4250D02*X264750Y-3500D01* +X266250D01* +X267000Y-4250D01* +Y-8750D01* +X266250Y-9500D02*X267000Y-8750D01* +X264750Y-9500D02*X266250D01* +X264000Y-8000D02*X267000Y-5000D01* +X272250Y-3500D02*Y-8750D01* +X273000Y-9500D01* +X271500Y-5750D02*X273000D01* +X274500Y-7250D02*Y-8750D01* +Y-7250D02*X275250Y-6500D01* +X276750D01* +X277500Y-7250D01* +Y-8750D01* +X276750Y-9500D02*X277500Y-8750D01* +X275250Y-9500D02*X276750D01* +X274500Y-8750D02*X275250Y-9500D01* +X282000Y-3500D02*X285000D01* +X282000D02*Y-6500D01* +X282750Y-5750D01* +X284250D01* +X285000Y-6500D01* +Y-8750D01* +X284250Y-9500D02*X285000Y-8750D01* +X282750Y-9500D02*X284250D01* +X282000Y-8750D02*X282750Y-9500D01* +X286800Y-8750D02*X287550Y-9500D01* +X286800Y-4250D02*Y-8750D01* +Y-4250D02*X287550Y-3500D01* +X289050D01* +X289800Y-4250D01* +Y-8750D01* +X289050Y-9500D02*X289800Y-8750D01* +X287550Y-9500D02*X289050D01* +X286800Y-8000D02*X289800Y-5000D01* +X291600Y-8750D02*X292350Y-9500D01* +X291600Y-4250D02*Y-8750D01* +Y-4250D02*X292350Y-3500D01* +X293850D01* +X294600Y-4250D01* +Y-8750D01* +X293850Y-9500D02*X294600Y-8750D01* +X292350Y-9500D02*X293850D01* +X291600Y-8000D02*X294600Y-5000D01* +X296400Y-9500D02*X297150D01* +X298950Y-8750D02*X299700Y-9500D01* +X298950Y-4250D02*Y-8750D01* +Y-4250D02*X299700Y-3500D01* +X301200D01* +X301950Y-4250D01* +Y-8750D01* +X301200Y-9500D02*X301950Y-8750D01* +X299700Y-9500D02*X301200D01* +X298950Y-8000D02*X301950Y-5000D01* +X303750Y-8750D02*X304500Y-9500D01* +X303750Y-4250D02*Y-8750D01* +Y-4250D02*X304500Y-3500D01* +X306000D01* +X306750Y-4250D01* +Y-8750D01* +X306000Y-9500D02*X306750Y-8750D01* +X304500Y-9500D02*X306000D01* +X303750Y-8000D02*X306750Y-5000D01* +X308550Y-8750D02*X309300Y-9500D01* +X308550Y-4250D02*Y-8750D01* +Y-4250D02*X309300Y-3500D01* +X310800D01* +X311550Y-4250D01* +Y-8750D01* +X310800Y-9500D02*X311550Y-8750D01* +X309300Y-9500D02*X310800D01* +X308550Y-8000D02*X311550Y-5000D01* +X313350Y-8750D02*X314100Y-9500D01* +X313350Y-4250D02*Y-8750D01* +Y-4250D02*X314100Y-3500D01* +X315600D01* +X316350Y-4250D01* +Y-8750D01* +X315600Y-9500D02*X316350Y-8750D01* +X314100Y-9500D02*X315600D01* +X313350Y-8000D02*X316350Y-5000D01* +X318150Y-8750D02*X318900Y-9500D01* +X318150Y-4250D02*Y-8750D01* +Y-4250D02*X318900Y-3500D01* +X320400D01* +X321150Y-4250D01* +Y-8750D01* +X320400Y-9500D02*X321150Y-8750D01* +X318900Y-9500D02*X320400D01* +X318150Y-8000D02*X321150Y-5000D01* +X322950Y-8750D02*X323700Y-9500D01* +X322950Y-4250D02*Y-8750D01* +Y-4250D02*X323700Y-3500D01* +X325200D01* +X325950Y-4250D01* +Y-8750D01* +X325200Y-9500D02*X325950Y-8750D01* +X323700Y-9500D02*X325200D01* +X322950Y-8000D02*X325950Y-5000D01* +X327750Y-11000D02*X329250Y-9500D01* +X331050Y-3500D02*X334050D01* +X331050D02*Y-6500D01* +X331800Y-5750D01* +X333300D01* +X334050Y-6500D01* +Y-8750D01* +X333300Y-9500D02*X334050Y-8750D01* +X331800Y-9500D02*X333300D01* +X331050Y-8750D02*X331800Y-9500D01* +X335850Y-8750D02*X336600Y-9500D01* +X335850Y-4250D02*Y-8750D01* +Y-4250D02*X336600Y-3500D01* +X338100D01* +X338850Y-4250D01* +Y-8750D01* +X338100Y-9500D02*X338850Y-8750D01* +X336600Y-9500D02*X338100D01* +X335850Y-8000D02*X338850Y-5000D01* +X340650Y-8750D02*X341400Y-9500D01* +X340650Y-4250D02*Y-8750D01* +Y-4250D02*X341400Y-3500D01* +X342900D01* +X343650Y-4250D01* +Y-8750D01* +X342900Y-9500D02*X343650Y-8750D01* +X341400Y-9500D02*X342900D01* +X340650Y-8000D02*X343650Y-5000D01* +X345450Y-9500D02*X346200D01* +X348000Y-8750D02*X348750Y-9500D01* +X348000Y-4250D02*Y-8750D01* +Y-4250D02*X348750Y-3500D01* +X350250D01* +X351000Y-4250D01* +Y-8750D01* +X350250Y-9500D02*X351000Y-8750D01* +X348750Y-9500D02*X350250D01* +X348000Y-8000D02*X351000Y-5000D01* +X352800Y-8750D02*X353550Y-9500D01* +X352800Y-4250D02*Y-8750D01* +Y-4250D02*X353550Y-3500D01* +X355050D01* +X355800Y-4250D01* +Y-8750D01* +X355050Y-9500D02*X355800Y-8750D01* +X353550Y-9500D02*X355050D01* +X352800Y-8000D02*X355800Y-5000D01* +X357600Y-8750D02*X358350Y-9500D01* +X357600Y-4250D02*Y-8750D01* +Y-4250D02*X358350Y-3500D01* +X359850D01* +X360600Y-4250D01* +Y-8750D01* +X359850Y-9500D02*X360600Y-8750D01* +X358350Y-9500D02*X359850D01* +X357600Y-8000D02*X360600Y-5000D01* +X362400Y-8750D02*X363150Y-9500D01* +X362400Y-4250D02*Y-8750D01* +Y-4250D02*X363150Y-3500D01* +X364650D01* +X365400Y-4250D01* +Y-8750D01* +X364650Y-9500D02*X365400Y-8750D01* +X363150Y-9500D02*X364650D01* +X362400Y-8000D02*X365400Y-5000D01* +X367200Y-8750D02*X367950Y-9500D01* +X367200Y-4250D02*Y-8750D01* +Y-4250D02*X367950Y-3500D01* +X369450D01* +X370200Y-4250D01* +Y-8750D01* +X369450Y-9500D02*X370200Y-8750D01* +X367950Y-9500D02*X369450D01* +X367200Y-8000D02*X370200Y-5000D01* +X372000Y-8750D02*X372750Y-9500D01* +X372000Y-4250D02*Y-8750D01* +Y-4250D02*X372750Y-3500D01* +X374250D01* +X375000Y-4250D01* +Y-8750D01* +X374250Y-9500D02*X375000Y-8750D01* +X372750Y-9500D02*X374250D01* +X372000Y-8000D02*X375000Y-5000D01* +X380250Y-7250D02*Y-9500D01* +Y-7250D02*X381000Y-6500D01* +X381750D01* +X382500Y-7250D01* +Y-9500D01* +Y-7250D02*X383250Y-6500D01* +X384000D01* +X384750Y-7250D01* +Y-9500D01* +X379500Y-6500D02*X380250Y-7250D01* +G54D25*X386550Y-5000D02*Y-5150D01* +G54D24*Y-7250D02*Y-9500D01* +X388050Y-3500D02*Y-8750D01* +X388800Y-9500D01* +X391050D02*X393300D01* +X394050Y-8750D01* +X393300Y-8000D02*X394050Y-8750D01* +X391050Y-8000D02*X393300D01* +X390300Y-7250D02*X391050Y-8000D01* +X390300Y-7250D02*X391050Y-6500D01* +X393300D01* +X394050Y-7250D01* +X390300Y-8750D02*X391050Y-9500D01* +X200750Y78500D02*Y72500D01* +X202700Y78500D02*X203750Y77450D01* +Y73550D01* +X202700Y72500D02*X203750Y73550D01* +X200000Y72500D02*X202700D01* +X200000Y78500D02*X202700D01* +X207800Y75500D02*X208550Y74750D01* +X206300Y75500D02*X207800D01* +X205550Y74750D02*X206300Y75500D01* +X205550Y74750D02*Y73250D01* +X206300Y72500D01* +X208550Y75500D02*Y73250D01* +X209300Y72500D01* +X206300D02*X207800D01* +X208550Y73250D01* +X211850Y78500D02*Y73250D01* +X212600Y72500D01* +X211100Y76250D02*X212600D01* +X214850Y72500D02*X217100D01* +X214100Y73250D02*X214850Y72500D01* +X214100Y74750D02*Y73250D01* +Y74750D02*X214850Y75500D01* +X216350D01* +X217100Y74750D01* +X214100Y74000D02*X217100D01* +Y74750D01* +X218900Y76250D02*X219650D01* +X218900Y74750D02*X219650D01* +X224150Y75500D02*X225650Y77000D01* +X224150Y75500D02*X225650Y74000D01* +X230450Y78500D02*Y72500D01* +X229700D02*X230450Y73250D01* +X228200Y72500D02*X229700D01* +X227450Y73250D02*X228200Y72500D01* +X227450Y74750D02*Y73250D01* +Y74750D02*X228200Y75500D01* +X229700D01* +X230450Y74750D01* +X234500Y75500D02*X235250Y74750D01* +X233000Y75500D02*X234500D01* +X232250Y74750D02*X233000Y75500D01* +X232250Y74750D02*Y73250D01* +X233000Y72500D01* +X235250Y75500D02*Y73250D01* +X236000Y72500D01* +X233000D02*X234500D01* +X235250Y73250D01* +X238550Y78500D02*Y73250D01* +X239300Y72500D01* +X237800Y76250D02*X239300D01* +X241550Y72500D02*X243800D01* +X240800Y73250D02*X241550Y72500D01* +X240800Y74750D02*Y73250D01* +Y74750D02*X241550Y75500D01* +X243050D01* +X243800Y74750D01* +X240800Y74000D02*X243800D01* +Y74750D01* +X245600Y77000D02*X247100Y75500D01* +X245600Y74000D02*X247100Y75500D01* +X200000Y92000D02*Y87500D01* +Y92000D02*X201050Y93500D01* +X202700D01* +X203750Y92000D01* +Y87500D01* +X200000Y90500D02*X203750D01* +X205550D02*Y88250D01* +X206300Y87500D01* +X207800D01* +X208550Y88250D01* +Y90500D02*Y88250D01* +X211100Y93500D02*Y88250D01* +X211850Y87500D01* +X210350Y91250D02*X211850D01* +X213350Y93500D02*Y87500D01* +Y89750D02*X214100Y90500D01* +X215600D01* +X216350Y89750D01* +Y87500D01* +X218150Y89750D02*Y88250D01* +Y89750D02*X218900Y90500D01* +X220400D01* +X221150Y89750D01* +Y88250D01* +X220400Y87500D02*X221150Y88250D01* +X218900Y87500D02*X220400D01* +X218150Y88250D02*X218900Y87500D01* +X223700Y89750D02*Y87500D01* +Y89750D02*X224450Y90500D01* +X225950D01* +X222950D02*X223700Y89750D01* +X227750Y91250D02*X228500D01* +X227750Y89750D02*X228500D01* +X233000Y93500D02*X236000D01* +X234500D02*Y87500D01* +X237800Y90800D02*X240050D01* +X237800Y87500D02*X240800D01* +X237800Y93500D02*Y87500D01* +Y93500D02*X240800D01* +X245600D02*X246350Y92750D01* +X243350Y93500D02*X245600D01* +X242600Y92750D02*X243350Y93500D01* +X242600Y92750D02*Y91250D01* +X243350Y90500D01* +X245600D01* +X246350Y89750D01* +Y88250D01* +X245600Y87500D02*X246350Y88250D01* +X243350Y87500D02*X245600D01* +X242600Y88250D02*X243350Y87500D01* +X248150Y93500D02*X251150D01* +X249650D02*Y87500D01* +X200000Y108500D02*X203000D01* +X201500D02*Y102500D01* +G54D25*X204800Y107000D02*Y106850D01* +G54D24*Y104750D02*Y102500D01* +X207050Y108500D02*Y103250D01* +X207800Y102500D01* +X206300Y106250D02*X207800D01* +X209300Y108500D02*Y103250D01* +X210050Y102500D01* +X212300D02*X214550D01* +X211550Y103250D02*X212300Y102500D01* +X211550Y104750D02*Y103250D01* +Y104750D02*X212300Y105500D01* +X213800D01* +X214550Y104750D01* +X211550Y104000D02*X214550D01* +Y104750D01* +X216350Y106250D02*X217100D01* +X216350Y104750D02*X217100D01* +X222350Y108500D02*Y103250D01* +X223100Y102500D01* +X221600Y106250D02*X223100D01* +X224600Y108500D02*Y102500D01* +Y104750D02*X225350Y105500D01* +X226850D01* +X227600Y104750D01* +Y102500D01* +X230150D02*X232400D01* +X229400Y103250D02*X230150Y102500D01* +X229400Y104750D02*Y103250D01* +Y104750D02*X230150Y105500D01* +X231650D01* +X232400Y104750D01* +X229400Y104000D02*X232400D01* +Y104750D01* +X234950D02*Y102500D01* +Y104750D02*X235700Y105500D01* +X237200D01* +X234200D02*X234950Y104750D01* +X239750D02*Y102500D01* +Y104750D02*X240500Y105500D01* +X241250D01* +X242000Y104750D01* +Y102500D01* +Y104750D02*X242750Y105500D01* +X243500D01* +X244250Y104750D01* +Y102500D01* +X239000Y105500D02*X239750Y104750D01* +X248300Y105500D02*X249050Y104750D01* +X246800Y105500D02*X248300D01* +X246050Y104750D02*X246800Y105500D01* +X246050Y104750D02*Y103250D01* +X246800Y102500D01* +X249050Y105500D02*Y103250D01* +X249800Y102500D01* +X246800D02*X248300D01* +X249050Y103250D01* +X251600Y108500D02*Y103250D01* +X252350Y102500D01* +X254600D02*X256850D01* +X257600Y103250D01* +X256850Y104000D02*X257600Y103250D01* +X254600Y104000D02*X256850D01* +X253850Y104750D02*X254600Y104000D01* +X253850Y104750D02*X254600Y105500D01* +X256850D01* +X257600Y104750D01* +X253850Y103250D02*X254600Y102500D01* +X262100Y104750D02*Y103250D01* +Y104750D02*X262850Y105500D01* +X264350D01* +X265100Y104750D01* +Y103250D01* +X264350Y102500D02*X265100Y103250D01* +X262850Y102500D02*X264350D01* +X262100Y103250D02*X262850Y102500D01* +X267650Y104750D02*Y102500D01* +Y104750D02*X268400Y105500D01* +X269150D01* +X269900Y104750D01* +Y102500D01* +X266900Y105500D02*X267650Y104750D01* +X275150Y108500D02*Y103250D01* +X275900Y102500D01* +X274400Y106250D02*X275900D01* +X277400Y108500D02*Y102500D01* +Y104750D02*X278150Y105500D01* +X279650D01* +X280400Y104750D01* +Y102500D01* +X282950D02*X285200D01* +X282200Y103250D02*X282950Y102500D01* +X282200Y104750D02*Y103250D01* +Y104750D02*X282950Y105500D01* +X284450D01* +X285200Y104750D01* +X282200Y104000D02*X285200D01* +Y104750D01* +X289700Y108500D02*Y103250D01* +X290450Y102500D01* +X294200Y105500D02*X294950Y104750D01* +X292700Y105500D02*X294200D01* +X291950Y104750D02*X292700Y105500D01* +X291950Y104750D02*Y103250D01* +X292700Y102500D01* +X294950Y105500D02*Y103250D01* +X295700Y102500D01* +X292700D02*X294200D01* +X294950Y103250D01* +X298250Y102500D02*X300500D01* +X301250Y103250D01* +X300500Y104000D02*X301250Y103250D01* +X298250Y104000D02*X300500D01* +X297500Y104750D02*X298250Y104000D01* +X297500Y104750D02*X298250Y105500D01* +X300500D01* +X301250Y104750D01* +X297500Y103250D02*X298250Y102500D01* +X303800Y108500D02*Y103250D01* +X304550Y102500D01* +X303050Y106250D02*X304550D01* +X308750Y107750D02*X309500Y108500D01* +X311750D01* +X312500Y107750D01* +Y106250D01* +X308750Y102500D02*X312500Y106250D01* +X308750Y102500D02*X312500D01* +X317000Y108500D02*Y103250D01* +X317750Y102500D01* +X321500Y105500D02*X322250Y104750D01* +X320000Y105500D02*X321500D01* +X319250Y104750D02*X320000Y105500D01* +X319250Y104750D02*Y103250D01* +X320000Y102500D01* +X322250Y105500D02*Y103250D01* +X323000Y102500D01* +X320000D02*X321500D01* +X322250Y103250D01* +X324800Y105500D02*Y103250D01* +X325550Y102500D01* +X327800Y105500D02*Y101000D01* +X327050Y100250D02*X327800Y101000D01* +X325550Y100250D02*X327050D01* +X324800Y101000D02*X325550Y100250D01* +Y102500D02*X327050D01* +X327800Y103250D01* +X330350Y102500D02*X332600D01* +X329600Y103250D02*X330350Y102500D01* +X329600Y104750D02*Y103250D01* +Y104750D02*X330350Y105500D01* +X331850D01* +X332600Y104750D01* +X329600Y104000D02*X332600D01* +Y104750D01* +X335150D02*Y102500D01* +Y104750D02*X335900Y105500D01* +X337400D01* +X334400D02*X335150Y104750D01* +X339950Y102500D02*X342200D01* +X342950Y103250D01* +X342200Y104000D02*X342950Y103250D01* +X339950Y104000D02*X342200D01* +X339200Y104750D02*X339950Y104000D01* +X339200Y104750D02*X339950Y105500D01* +X342200D01* +X342950Y104750D01* +X339200Y103250D02*X339950Y102500D01* +X347450Y105500D02*X350450D01* +X355700D02*X357950D01* +X354950Y104750D02*X355700Y105500D01* +X354950Y104750D02*Y103250D01* +X355700Y102500D01* +X357950D01* +X362000Y105500D02*X362750Y104750D01* +X360500Y105500D02*X362000D01* +X359750Y104750D02*X360500Y105500D01* +X359750Y104750D02*Y103250D01* +X360500Y102500D01* +X362750Y105500D02*Y103250D01* +X363500Y102500D01* +X360500D02*X362000D01* +X362750Y103250D01* +X366050Y108500D02*Y103250D01* +X366800Y102500D01* +X365300Y106250D02*X366800D01* +X369050Y105500D02*X371300D01* +X368300Y104750D02*X369050Y105500D01* +X368300Y104750D02*Y103250D01* +X369050Y102500D01* +X371300D01* +X373100Y108500D02*Y102500D01* +Y104750D02*X373850Y105500D01* +X375350D01* +X376100Y104750D01* +Y102500D01* +X380600Y104750D02*Y103250D01* +Y104750D02*X381350Y105500D01* +X382850D01* +X383600Y104750D01* +Y103250D01* +X382850Y102500D02*X383600Y103250D01* +X381350Y102500D02*X382850D01* +X380600Y103250D02*X381350Y102500D01* +X386150Y107750D02*Y102500D01* +Y107750D02*X386900Y108500D01* +X387650D01* +X385400Y105500D02*X386900D01* +X389900Y107750D02*Y102500D01* +Y107750D02*X390650Y108500D01* +X391400D01* +X389150Y105500D02*X390650D01* +X392900D02*X395900D01* +X397700Y108500D02*Y102500D01* +Y103250D02*X398450Y102500D01* +X399950D01* +X400700Y103250D01* +Y104750D02*Y103250D01* +X399950Y105500D02*X400700Y104750D01* +X398450Y105500D02*X399950D01* +X397700Y104750D02*X398450Y105500D01* +X402500D02*Y103250D01* +X403250Y102500D01* +X405500Y105500D02*Y101000D01* +X404750Y100250D02*X405500Y101000D01* +X403250Y100250D02*X404750D01* +X402500Y101000D02*X403250Y100250D01* +Y102500D02*X404750D01* +X405500Y103250D01* +X407300Y105500D02*X410300D01* +X412100Y104750D02*Y103250D01* +Y104750D02*X412850Y105500D01* +X414350D01* +X415100Y104750D01* +Y103250D01* +X414350Y102500D02*X415100Y103250D01* +X412850Y102500D02*X414350D01* +X412100Y103250D02*X412850Y102500D01* +X417650Y104750D02*Y102500D01* +Y104750D02*X418400Y105500D01* +X419150D01* +X419900Y104750D01* +Y102500D01* +X416900Y105500D02*X417650Y104750D01* +X422450Y102500D02*X424700D01* +X421700Y103250D02*X422450Y102500D01* +X421700Y104750D02*Y103250D01* +Y104750D02*X422450Y105500D01* +X423950D01* +X424700Y104750D01* +X421700Y104000D02*X424700D01* +Y104750D01* +X429200Y108500D02*Y102500D01* +Y103250D02*X429950Y102500D01* +X431450D01* +X432200Y103250D01* +Y104750D02*Y103250D01* +X431450Y105500D02*X432200Y104750D01* +X429950Y105500D02*X431450D01* +X429200Y104750D02*X429950Y105500D01* +X434000D02*Y103250D01* +X434750Y102500D01* +X436250D01* +X437000Y103250D01* +Y105500D02*Y103250D01* +X441050Y105500D02*X441800Y104750D01* +X439550Y105500D02*X441050D01* +X438800Y104750D02*X439550Y105500D01* +X438800Y104750D02*Y103250D01* +X439550Y102500D01* +X441050D01* +X441800Y103250D01* +X438800Y101000D02*X439550Y100250D01* +X441050D01* +X441800Y101000D01* +Y105500D02*Y101000D01* +X444350Y102500D02*X446600D01* +X447350Y103250D01* +X446600Y104000D02*X447350Y103250D01* +X444350Y104000D02*X446600D01* +X443600Y104750D02*X444350Y104000D01* +X443600Y104750D02*X444350Y105500D01* +X446600D01* +X447350Y104750D01* +X443600Y103250D02*X444350Y102500D01* +X454850Y108500D02*Y102500D01* +X454100D02*X454850Y103250D01* +X452600Y102500D02*X454100D01* +X451850Y103250D02*X452600Y102500D01* +X451850Y104750D02*Y103250D01* +Y104750D02*X452600Y105500D01* +X454100D01* +X454850Y104750D01* +X456650Y105500D02*Y103250D01* +X457400Y102500D01* +X458900D01* +X459650Y103250D01* +Y105500D02*Y103250D01* +X462200Y102500D02*X464450D01* +X461450Y103250D02*X462200Y102500D01* +X461450Y104750D02*Y103250D01* +Y104750D02*X462200Y105500D01* +X463700D01* +X464450Y104750D01* +X461450Y104000D02*X464450D01* +Y104750D01* +X469700Y108500D02*Y103250D01* +X470450Y102500D01* +X468950Y106250D02*X470450D01* +X471950Y104750D02*Y103250D01* +Y104750D02*X472700Y105500D01* +X474200D01* +X474950Y104750D01* +Y103250D01* +X474200Y102500D02*X474950Y103250D01* +X472700Y102500D02*X474200D01* +X471950Y103250D02*X472700Y102500D01* +X480200Y108500D02*Y103250D01* +X480950Y102500D01* +X479450Y106250D02*X480950D01* +X482450Y108500D02*Y102500D01* +Y104750D02*X483200Y105500D01* +X484700D01* +X485450Y104750D01* +Y102500D01* +X488000D02*X490250D01* +X487250Y103250D02*X488000Y102500D01* +X487250Y104750D02*Y103250D01* +Y104750D02*X488000Y105500D01* +X489500D01* +X490250Y104750D01* +X487250Y104000D02*X490250D01* +Y104750D01* +X494750Y103250D02*X495500Y102500D01* +X494750Y107750D02*Y103250D01* +Y107750D02*X495500Y108500D01* +X497000D01* +X497750Y107750D01* +Y103250D01* +X497000Y102500D02*X497750Y103250D01* +X495500Y102500D02*X497000D01* +X494750Y104000D02*X497750Y107000D01* +X499550Y105500D02*X502550D01* +X504350Y108500D02*Y102500D01* +Y103250D02*X505100Y102500D01* +X506600D01* +X507350Y103250D01* +Y104750D02*Y103250D01* +X506600Y105500D02*X507350Y104750D01* +X505100Y105500D02*X506600D01* +X504350Y104750D02*X505100Y105500D01* +X511400D02*X512150Y104750D01* +X509900Y105500D02*X511400D01* +X509150Y104750D02*X509900Y105500D01* +X509150Y104750D02*Y103250D01* +X509900Y102500D01* +X512150Y105500D02*Y103250D01* +X512900Y102500D01* +X509900D02*X511400D01* +X512150Y103250D01* +X515450Y102500D02*X517700D01* +X518450Y103250D01* +X517700Y104000D02*X518450Y103250D01* +X515450Y104000D02*X517700D01* +X514700Y104750D02*X515450Y104000D01* +X514700Y104750D02*X515450Y105500D01* +X517700D01* +X518450Y104750D01* +X514700Y103250D02*X515450Y102500D01* +X521000D02*X523250D01* +X520250Y103250D02*X521000Y102500D01* +X520250Y104750D02*Y103250D01* +Y104750D02*X521000Y105500D01* +X522500D01* +X523250Y104750D01* +X520250Y104000D02*X523250D01* +Y104750D01* +G54D25*X527750Y107000D02*Y106850D01* +G54D24*Y104750D02*Y102500D01* +X530000Y104750D02*Y102500D01* +Y104750D02*X530750Y105500D01* +X531500D01* +X532250Y104750D01* +Y102500D01* +X529250Y105500D02*X530000Y104750D01* +X537050Y108500D02*Y102500D01* +X536300D02*X537050Y103250D01* +X534800Y102500D02*X536300D01* +X534050Y103250D02*X534800Y102500D01* +X534050Y104750D02*Y103250D01* +Y104750D02*X534800Y105500D01* +X536300D01* +X537050Y104750D01* +X539600Y102500D02*X541850D01* +X538850Y103250D02*X539600Y102500D01* +X538850Y104750D02*Y103250D01* +Y104750D02*X539600Y105500D01* +X541100D01* +X541850Y104750D01* +X538850Y104000D02*X541850D01* +Y104750D01* +X543650Y105500D02*X546650Y102500D01* +X543650D02*X546650Y105500D01* +X551150Y104750D02*Y103250D01* +Y104750D02*X551900Y105500D01* +X553400D01* +X554150Y104750D01* +Y103250D01* +X553400Y102500D02*X554150Y103250D01* +X551900Y102500D02*X553400D01* +X551150Y103250D02*X551900Y102500D01* +X556700Y107750D02*Y102500D01* +Y107750D02*X557450Y108500D01* +X558200D01* +X555950Y105500D02*X557450D01* +X563150Y108500D02*Y103250D01* +X563900Y102500D01* +X562400Y106250D02*X563900D01* +X565400Y108500D02*Y102500D01* +Y104750D02*X566150Y105500D01* +X567650D01* +X568400Y104750D01* +Y102500D01* +X570950D02*X573200D01* +X570200Y103250D02*X570950Y102500D01* +X570200Y104750D02*Y103250D01* +Y104750D02*X570950Y105500D01* +X572450D01* +X573200Y104750D01* +X570200Y104000D02*X573200D01* +Y104750D01* +X575750D02*Y102500D01* +Y104750D02*X576500Y105500D01* +X578000D01* +X575000D02*X575750Y104750D01* +X580550D02*Y102500D01* +Y104750D02*X581300Y105500D01* +X582050D01* +X582800Y104750D01* +Y102500D01* +Y104750D02*X583550Y105500D01* +X584300D01* +X585050Y104750D01* +Y102500D01* +X579800Y105500D02*X580550Y104750D01* +X589100Y105500D02*X589850Y104750D01* +X587600Y105500D02*X589100D01* +X586850Y104750D02*X587600Y105500D01* +X586850Y104750D02*Y103250D01* +X587600Y102500D01* +X589850Y105500D02*Y103250D01* +X590600Y102500D01* +X587600D02*X589100D01* +X589850Y103250D01* +X592400Y108500D02*Y103250D01* +X593150Y102500D01* +X595400D02*X597650D01* +X598400Y103250D01* +X597650Y104000D02*X598400Y103250D01* +X595400Y104000D02*X597650D01* +X594650Y104750D02*X595400Y104000D01* +X594650Y104750D02*X595400Y105500D01* +X597650D01* +X598400Y104750D01* +X594650Y103250D02*X595400Y102500D01* +X602900Y105500D02*X605900D01* +X610400Y108500D02*Y102500D01* +Y108500D02*X613400D01* +X610400Y105800D02*X612650D01* +X617450Y105500D02*X618200Y104750D01* +X615950Y105500D02*X617450D01* +X615200Y104750D02*X615950Y105500D01* +X615200Y104750D02*Y103250D01* +X615950Y102500D01* +X618200Y105500D02*Y103250D01* +X618950Y102500D01* +X615950D02*X617450D01* +X618200Y103250D01* +X620750Y108500D02*Y102500D01* +Y103250D02*X621500Y102500D01* +X623000D01* +X623750Y103250D01* +Y104750D02*Y103250D01* +X623000Y105500D02*X623750Y104750D01* +X621500Y105500D02*X623000D01* +X620750Y104750D02*X621500Y105500D01* +X626300Y104750D02*Y102500D01* +Y104750D02*X627050Y105500D01* +X628550D01* +X625550D02*X626300Y104750D01* +G54D25*X630350Y107000D02*Y106850D01* +G54D24*Y104750D02*Y102500D01* +X632601Y105500D02*X634851D01* +X631851Y104750D02*X632601Y105500D01* +X631851Y104750D02*Y103250D01* +X632601Y102500D01* +X634851D01* +X638901Y105500D02*X639651Y104750D01* +X637401Y105500D02*X638901D01* +X636651Y104750D02*X637401Y105500D01* +X636651Y104750D02*Y103250D01* +X637401Y102500D01* +X639651Y105500D02*Y103250D01* +X640401Y102500D01* +X637401D02*X638901D01* +X639651Y103250D01* +X642951Y108500D02*Y103250D01* +X643701Y102500D01* +X642201Y106250D02*X643701D01* +G54D25*X645201Y107000D02*Y106850D01* +G54D24*Y104750D02*Y102500D01* +X646701Y104750D02*Y103250D01* +Y104750D02*X647451Y105500D01* +X648951D01* +X649701Y104750D01* +Y103250D01* +X648951Y102500D02*X649701Y103250D01* +X647451Y102500D02*X648951D01* +X646701Y103250D02*X647451Y102500D01* +X652251Y104750D02*Y102500D01* +Y104750D02*X653001Y105500D01* +X653751D01* +X654501Y104750D01* +Y102500D01* +X651501Y105500D02*X652251Y104750D01* +X659751Y108500D02*Y102500D01* +X661701Y108500D02*X662751Y107450D01* +Y103550D01* +X661701Y102500D02*X662751Y103550D01* +X659001Y102500D02*X661701D01* +X659001Y108500D02*X661701D01* +X665301Y104750D02*Y102500D01* +Y104750D02*X666051Y105500D01* +X667551D01* +X664551D02*X665301Y104750D01* +X671601Y105500D02*X672351Y104750D01* +X670101Y105500D02*X671601D01* +X669351Y104750D02*X670101Y105500D01* +X669351Y104750D02*Y103250D01* +X670101Y102500D01* +X672351Y105500D02*Y103250D01* +X673101Y102500D01* +X670101D02*X671601D01* +X672351Y103250D01* +X674901Y105500D02*Y103250D01* +X675651Y102500D01* +X676401D01* +X677151Y103250D01* +Y105500D02*Y103250D01* +X677901Y102500D01* +X678651D01* +X679401Y103250D01* +Y105500D02*Y103250D01* +G54D25*X681201Y107000D02*Y106850D01* +G54D24*Y104750D02*Y102500D01* +X683451Y104750D02*Y102500D01* +Y104750D02*X684201Y105500D01* +X684951D01* +X685701Y104750D01* +Y102500D01* +X682701Y105500D02*X683451Y104750D01* +X689751Y105500D02*X690501Y104750D01* +X688251Y105500D02*X689751D01* +X687501Y104750D02*X688251Y105500D01* +X687501Y104750D02*Y103250D01* +X688251Y102500D01* +X689751D01* +X690501Y103250D01* +X687501Y101000D02*X688251Y100250D01* +X689751D01* +X690501Y101000D01* +Y105500D02*Y101000D01* +M02* Index: tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.gbr/thermal_last.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,15 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD12C,0.0315*% +%ADD11C,0.0787*% +G54D11*X10000Y40000D03* +G54D12*M02* Index: tags/2.3.0/tests/RTT/ref/thermal_last.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.nelma.em (revision 33253) @@ -0,0 +1,75 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer group-1 { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} +layer substrate-11 { + height = 20 + z-order = 11 + material = "composite" +} +layer group-1 { + height = 1 + z-order = 12 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "group-1", + "substrate-11", + "group-1" + } +} Index: tags/2.3.0/tests/RTT/ref/thermal_last.net =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.net (revision 33253) @@ -0,0 +1,13 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +317N/C VIA - D0315PA00X+001000Y+004000X0787Y0000R000 S3 +999 Index: tags/2.3.0/tests/RTT/ref/thermal_last.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/thermal_last.png =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/thermal_last.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/thermal_last.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.png.text (revision 33253) @@ -0,0 +1,10 @@ +r6731 + +121 x 121 pixels (100.833 x 100.833) for both polygons + +via copper width 95 pixels (79.166) +Via drill width 39 pixels (32.5) +clearance 23 pixels (19.166) + + + Index: tags/2.3.0/tests/RTT/ref/thermal_last.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/thermal_last.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/thermal_last.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/thermal_last.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/thermal_last.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/thermal_last.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/thermal_last.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.svg (revision 33253) @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/thermal_last.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_last.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_last.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/thermal_layer.bom =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.bom (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.bom (revision 33253) @@ -0,0 +1,7 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: +# Author: TEST +# Title: thermals vs. multiple layer polygons - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/ref/thermal_layer.dsn =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.dsn (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.dsn (revision 33253) @@ -0,0 +1,62 @@ +(pcb thermals vs. multiple layer polygons + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "pcb-rnd") + (host_version "") + ) + (resolution mm 1000000) + (structure + (layer "3__top_copper" + (type signal) + ) + (layer "5__Intern" + (type signal) + ) + (layer "7__Intern" + (type signal) + ) + (layer "10__bottom_copper" + (type signal) + ) + (boundary + (rect pcb 0.0 0.0 12.700000 12.700000) + ) + (via via_685800_381000) + (rule + (width 0.2032) + (clear 0.2032) + (clear 0.2032 (type wire_area)) + (clear 0.2032 (type via_smd via_pin)) + (clear 0.2032 (type smd_smd)) + (clear 0.2032 (type default_smd)) + ) + ) + (placement + (component 5 + (place 5 2.540000 10.160000 front 0 (PN 0)) + ) + (component 6 + (place 6 6.985000 10.160000 front 0 (PN 0)) + ) + (component 7 + (place 7 2.540000 5.715000 front 0 (PN 0)) + ) + (component 8 + (place 8 6.985000 5.715000 front 0 (PN 0)) + ) + ) + (library + ) + (network + (class geda_default + (circuit + (use_via via_685800_381000) + ) + (rule (width 0.203200)) + ) + ) + (wiring + + ) +) Index: tags/2.3.0/tests/RTT/ref/thermal_layer.eps =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.eps (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.eps (revision 33253) @@ -0,0 +1,427 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 0 0 37.000000 37.000000 +%%Pages: 1 +save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def +%%EndProlog +%%Page: 1 1 +%%BeginDocument: thermal_layer.eps + +72 72 scale +1 dup neg scale +1 dup scale +0.00000 -0.50000 translate +/nclip { -0.01000 -0.01000 moveto -0.01000 0.51000 lineto 0.51000 0.51000 lineto 0.51000 -0.01000 lineto -0.01000 -0.01000 lineto eoclip newpath } def +/t { moveto lineto stroke } bind def +/tc { moveto lineto strokepath nclip } bind def +/r { /y2 exch def /x2 exch def /y1 exch def /x1 exch def + x1 y1 moveto x1 y2 lineto x2 y2 lineto x2 y1 lineto closepath fill } bind def +/c { 0 360 arc fill } bind def +/cc { 0 360 arc nclip } bind def +/a { gsave setlinewidth translate scale 0 0 1 5 3 roll arc stroke grestore} bind def +% Layer bottomsilk group 12 drill 0 mask 0 +% Layer bottom group 10 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.227451 0.372549 0.803922 setrgbcolor +0.13914 0.07500 moveto +0.13400 0.08014 lineto +0.13519 0.08207 lineto +0.13756 0.08780 lineto +0.13901 0.09382 lineto +0.13937 0.10000 lineto +0.13901 0.10618 lineto +0.13756 0.11220 lineto +0.13519 0.11793 lineto +0.13400 0.11986 lineto +0.14855 0.13440 lineto +0.15306 0.12704 lineto +0.15664 0.11840 lineto +0.15882 0.10932 lineto +0.15937 0.10000 lineto +0.15882 0.09068 lineto +0.15664 0.08160 lineto +0.15391 0.07500 lineto +0.17500 0.07500 lineto +0.17500 0.17500 lineto +0.07500 0.17500 lineto +0.07500 0.15391 lineto +0.08160 0.15664 lineto +0.09068 0.15882 lineto +0.10000 0.15955 lineto +0.10932 0.15882 lineto +0.11840 0.15664 lineto +0.12704 0.15306 lineto +0.13440 0.14855 lineto +0.11986 0.13400 lineto +0.11793 0.13519 lineto +0.11220 0.13756 lineto +0.10618 0.13901 lineto +0.10000 0.13949 lineto +0.09382 0.13901 lineto +0.08780 0.13756 lineto +0.08207 0.13519 lineto +0.08014 0.13400 lineto +0.07500 0.13914 lineto +0.07500 0.07500 lineto +fill +0.17500 0.25000 moveto +0.17500 0.35000 lineto +0.07500 0.35000 lineto +0.07500 0.25000 lineto +fill +1 setlinecap +0.627451 0.627451 0.627451 setrgbcolor +0.10000 0.10000 0.03937 c +0.27500 0.10000 0.03937 c +0.10000 0.27500 0.03937 c +0.27500 0.27500 0.03937 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +0.27500 0.10000 0.01575 c +0.10000 0.27500 0.01575 c +0.27500 0.27500 0.01575 c +% Layer group5 group 5 drill 0 mask 0 +0.00000 setlinewidth +0.627451 0.627451 0.627451 setrgbcolor +0.10000 0.10000 0.03937 c +0.27500 0.10000 0.03937 c +0.10000 0.27500 0.03937 c +0.27500 0.27500 0.03937 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +0.27500 0.10000 0.01575 c +0.10000 0.27500 0.01575 c +0.27500 0.27500 0.01575 c +% Layer group7 group 7 drill 0 mask 0 +0.00000 setlinewidth +0.627451 0.627451 0.627451 setrgbcolor +0.10000 0.10000 0.03937 c +0.27500 0.10000 0.03937 c +0.10000 0.27500 0.03937 c +0.27500 0.27500 0.03937 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +0.27500 0.10000 0.01575 c +0.10000 0.27500 0.01575 c +0.27500 0.27500 0.01575 c +% Layer top group 3 drill 0 mask 0 +0.00000 setlinewidth +2 setlinecap +0.0627451 0.305882 0.545098 setrgbcolor +0.31414 0.07500 moveto +0.30900 0.08014 lineto +0.31019 0.08207 lineto +0.31256 0.08780 lineto +0.31401 0.09382 lineto +0.31437 0.10000 lineto +0.31401 0.10618 lineto +0.31256 0.11220 lineto +0.31019 0.11793 lineto +0.30900 0.11986 lineto +0.32355 0.13440 lineto +0.32806 0.12704 lineto +0.33164 0.11840 lineto +0.33382 0.10932 lineto +0.33437 0.10000 lineto +0.33382 0.09068 lineto +0.33164 0.08160 lineto +0.32891 0.07500 lineto +0.35000 0.07500 lineto +0.35000 0.17500 lineto +0.25000 0.17500 lineto +0.25000 0.15391 lineto +0.25660 0.15664 lineto +0.26568 0.15882 lineto +0.27500 0.15955 lineto +0.28432 0.15882 lineto +0.29340 0.15664 lineto +0.30204 0.15306 lineto +0.30940 0.14855 lineto +0.29486 0.13400 lineto +0.29293 0.13519 lineto +0.28720 0.13756 lineto +0.28118 0.13901 lineto +0.27500 0.13949 lineto +0.26882 0.13901 lineto +0.26280 0.13756 lineto +0.25707 0.13519 lineto +0.25514 0.13400 lineto +0.25000 0.13914 lineto +0.25000 0.07500 lineto +fill +0.35000 0.25000 moveto +0.35000 0.35000 lineto +0.25000 0.35000 lineto +0.25000 0.25000 lineto +fill +0.545098 0.137255 0.137255 setrgbcolor +0.12500 0.02500 moveto +0.12500 0.04670 lineto +0.12475 0.04645 lineto +0.12346 0.04554 lineto +0.12204 0.04487 lineto +0.11672 0.04296 lineto +0.11123 0.04163 lineto +0.10564 0.04083 lineto +0.10000 0.04056 lineto +0.09436 0.04083 lineto +0.08877 0.04163 lineto +0.08328 0.04296 lineto +0.07794 0.04481 lineto +0.07652 0.04550 lineto +0.07523 0.04642 lineto +0.07409 0.04752 lineto +0.07315 0.04879 lineto +0.07241 0.05019 lineto +0.07191 0.05168 lineto +0.07164 0.05324 lineto +0.07162 0.05482 lineto +0.07185 0.05639 lineto +0.07232 0.05790 lineto +0.07302 0.05931 lineto +0.07393 0.06061 lineto +0.07504 0.06174 lineto +0.07630 0.06268 lineto +0.07770 0.06342 lineto +0.07920 0.06392 lineto +0.08076 0.06419 lineto +0.08234 0.06421 lineto +0.08390 0.06398 lineto +0.08540 0.06348 lineto +0.08892 0.06222 lineto +0.09256 0.06134 lineto +0.09626 0.06081 lineto +0.10000 0.06063 lineto +0.10374 0.06081 lineto +0.10744 0.06134 lineto +0.11108 0.06222 lineto +0.11461 0.06344 lineto +0.11611 0.06394 lineto +0.11766 0.06417 lineto +0.11924 0.06415 lineto +0.12079 0.06388 lineto +0.12228 0.06338 lineto +0.12367 0.06264 lineto +0.12493 0.06170 lineto +0.12500 0.06164 lineto +0.12500 0.12500 lineto +0.06170 0.12500 lineto +0.06174 0.12496 lineto +0.06268 0.12370 lineto +0.06342 0.12230 lineto +0.06392 0.12080 lineto +0.06419 0.11924 lineto +0.06421 0.11766 lineto +0.06398 0.11610 lineto +0.06348 0.11460 lineto +0.06222 0.11108 lineto +0.06134 0.10744 lineto +0.06081 0.10374 lineto +0.06063 0.10000 lineto +0.06081 0.09626 lineto +0.06134 0.09256 lineto +0.06222 0.08892 lineto +0.06344 0.08539 lineto +0.06394 0.08389 lineto +0.06417 0.08234 lineto +0.06415 0.08076 lineto +0.06388 0.07921 lineto +0.06338 0.07772 lineto +0.06264 0.07633 lineto +0.06170 0.07507 lineto +0.06058 0.07397 lineto +0.05929 0.07306 lineto +0.05788 0.07236 lineto +0.05638 0.07189 lineto +0.05482 0.07167 lineto +0.05325 0.07168 lineto +0.05169 0.07195 lineto +0.05020 0.07246 lineto +0.04881 0.07319 lineto +0.04755 0.07413 lineto +0.04645 0.07525 lineto +0.04554 0.07654 lineto +0.04487 0.07796 lineto +0.04296 0.08328 lineto +0.04163 0.08877 lineto +0.04083 0.09436 lineto +0.04056 0.10000 lineto +0.04083 0.10564 lineto +0.04163 0.11123 lineto +0.04296 0.11672 lineto +0.04481 0.12206 lineto +0.04550 0.12348 lineto +0.04642 0.12477 lineto +0.04664 0.12500 lineto +0.02500 0.12500 lineto +0.02500 0.02500 lineto +fill +0.30000 0.02500 moveto +0.30000 0.04670 lineto +0.29975 0.04645 lineto +0.29846 0.04554 lineto +0.29704 0.04487 lineto +0.29172 0.04296 lineto +0.28623 0.04163 lineto +0.28064 0.04083 lineto +0.27500 0.04056 lineto +0.26936 0.04083 lineto +0.26377 0.04163 lineto +0.25828 0.04296 lineto +0.25294 0.04481 lineto +0.25152 0.04550 lineto +0.25023 0.04642 lineto +0.24909 0.04752 lineto +0.24815 0.04879 lineto +0.24741 0.05019 lineto +0.24691 0.05168 lineto +0.24664 0.05324 lineto +0.24662 0.05482 lineto +0.24685 0.05639 lineto +0.24732 0.05790 lineto +0.24802 0.05931 lineto +0.24893 0.06061 lineto +0.25004 0.06174 lineto +0.25130 0.06268 lineto +0.25270 0.06342 lineto +0.25420 0.06392 lineto +0.25576 0.06419 lineto +0.25734 0.06421 lineto +0.25890 0.06398 lineto +0.26040 0.06348 lineto +0.26392 0.06222 lineto +0.26756 0.06134 lineto +0.27126 0.06081 lineto +0.27500 0.06063 lineto +0.27874 0.06081 lineto +0.28244 0.06134 lineto +0.28608 0.06222 lineto +0.28961 0.06344 lineto +0.29111 0.06394 lineto +0.29266 0.06417 lineto +0.29424 0.06415 lineto +0.29579 0.06388 lineto +0.29728 0.06338 lineto +0.29867 0.06264 lineto +0.29993 0.06170 lineto +0.30000 0.06164 lineto +0.30000 0.12500 lineto +0.23670 0.12500 lineto +0.23674 0.12496 lineto +0.23768 0.12370 lineto +0.23842 0.12230 lineto +0.23892 0.12080 lineto +0.23919 0.11924 lineto +0.23921 0.11766 lineto +0.23898 0.11610 lineto +0.23848 0.11460 lineto +0.23722 0.11108 lineto +0.23634 0.10744 lineto +0.23581 0.10374 lineto +0.23563 0.10000 lineto +0.23581 0.09626 lineto +0.23634 0.09256 lineto +0.23722 0.08892 lineto +0.23844 0.08539 lineto +0.23894 0.08389 lineto +0.23917 0.08234 lineto +0.23915 0.08076 lineto +0.23888 0.07921 lineto +0.23838 0.07772 lineto +0.23764 0.07633 lineto +0.23670 0.07507 lineto +0.23558 0.07397 lineto +0.23429 0.07306 lineto +0.23288 0.07236 lineto +0.23138 0.07189 lineto +0.22982 0.07167 lineto +0.22825 0.07168 lineto +0.22669 0.07195 lineto +0.22520 0.07246 lineto +0.22381 0.07319 lineto +0.22255 0.07413 lineto +0.22145 0.07525 lineto +0.22054 0.07654 lineto +0.21987 0.07796 lineto +0.21796 0.08328 lineto +0.21663 0.08877 lineto +0.21583 0.09436 lineto +0.21556 0.10000 lineto +0.21583 0.10564 lineto +0.21663 0.11123 lineto +0.21796 0.11672 lineto +0.21981 0.12206 lineto +0.22050 0.12348 lineto +0.22142 0.12477 lineto +0.22164 0.12500 lineto +0.20000 0.12500 lineto +0.20000 0.02500 lineto +fill +0.12500 0.20000 moveto +0.12500 0.22109 lineto +0.11840 0.21836 lineto +0.10932 0.21618 lineto +0.10000 0.21545 lineto +0.09068 0.21618 lineto +0.08160 0.21836 lineto +0.07296 0.22194 lineto +0.06500 0.22682 lineto +0.05789 0.23289 lineto +0.05182 0.24000 lineto +0.04694 0.24796 lineto +0.04336 0.25660 lineto +0.04118 0.26568 lineto +0.04045 0.27500 lineto +0.04118 0.28432 lineto +0.04336 0.29340 lineto +0.04609 0.30000 lineto +0.02500 0.30000 lineto +0.02500 0.20000 lineto +fill +0.30000 0.20000 moveto +0.30000 0.22109 lineto +0.29340 0.21836 lineto +0.28432 0.21618 lineto +0.27500 0.21545 lineto +0.26568 0.21618 lineto +0.25660 0.21836 lineto +0.24796 0.22194 lineto +0.24000 0.22682 lineto +0.23289 0.23289 lineto +0.22682 0.24000 lineto +0.22194 0.24796 lineto +0.21836 0.25660 lineto +0.21618 0.26568 lineto +0.21545 0.27500 lineto +0.21618 0.28432 lineto +0.21836 0.29340 lineto +0.22109 0.30000 lineto +0.20000 0.30000 lineto +0.20000 0.20000 lineto +fill +1 setlinecap +0.439216 0.439216 0.439216 setrgbcolor +0.10000 0.10000 0.03937 c +0.27500 0.10000 0.03937 c +0.10000 0.27500 0.03937 c +0.27500 0.27500 0.03937 c +0.00000 setlinewidth +1 1 1 setrgbcolor +0.10000 0.10000 0.01575 c +0.27500 0.10000 0.01575 c +0.10000 0.27500 0.01575 c +0.27500 0.27500 0.01575 c +% Layer topsilk group 1 drill 0 mask 0 +% Layer plated-drill group -1 drill 1 mask 0 +0.10000 0.10000 0.01575 c +0.27500 0.10000 0.01575 c +0.10000 0.27500 0.01575 c +0.27500 0.27500 0.01575 c +showpage +%%EndDocument +%%Trailer +cleartomark countdictstack exch sub { end } repeat restore +%%EOF Index: tags/2.3.0/tests/RTT/ref/thermal_layer.exc/thermal_layer.plated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.exc/thermal_layer.plated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.exc/thermal_layer.plated.cnc (revision 33253) @@ -0,0 +1,11 @@ +M48 +INCH +T11C0.032 +% +T11 +G05 +X001000Y004000 +X002750Y004000 +X001000Y002250 +X002750Y002250 +M30 Index: tags/2.3.0/tests/RTT/ref/thermal_layer.exc/thermal_layer.unplated.cnc =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.exc/thermal_layer.unplated.cnc (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.exc/thermal_layer.unplated.cnc (revision 33253) @@ -0,0 +1 @@ +M30 Index: tags/2.3.0/tests/RTT/ref/thermal_layer.fcd =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.fcd (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.fcd (revision 33253) @@ -0,0 +1,13 @@ +[FIDOCAD] +PP 5 5 25 5 25 9 25 9 25 9 24 9 23 9 22 8 21 8 20 8 19 8 18 8 17 9 16 9 15 9 15 9 15 10 15 10 14 10 14 10 14 11 14 11 14 11 14 12 15 12 15 12 15 12 15 13 16 13 16 13 16 13 16 13 17 13 17 13 18 12 19 12 19 12 20 12 21 12 21 12 22 12 23 13 23 13 24 13 24 13 24 13 24 13 25 13 25 12 25 12 25 25 12 25 12 25 13 25 13 24 13 24 13 24 13 24 13 23 13 23 12 22 12 21 12 21 12 20 12 19 12 19 12 18 13 17 13 17 13 16 13 16 13 16 13 16 13 15 12 15 12 15 12 15 12 14 11 14 11 14 11 14 10 14 10 14 10 15 10 15 9 15 9 15 9 16 9 17 8 18 8 19 8 20 8 21 8 22 9 23 9 24 9 25 9 25 9 25 5 25 5 5 2 +PP 40 5 60 5 60 9 60 9 60 9 59 9 58 9 57 8 56 8 55 8 54 8 53 8 52 9 51 9 50 9 50 9 50 10 50 10 49 10 49 10 49 11 49 11 49 11 49 12 50 12 50 12 50 12 50 13 51 13 51 13 51 13 51 13 52 13 52 13 53 12 54 12 54 12 55 12 56 12 56 12 57 12 58 13 58 13 59 13 59 13 59 13 59 13 60 13 60 12 60 12 60 25 47 25 47 25 48 25 48 24 48 24 48 24 48 24 48 23 48 23 47 22 47 21 47 21 47 20 47 19 47 19 47 18 48 17 48 17 48 16 48 16 48 16 48 16 48 15 47 15 47 15 47 15 47 14 46 14 46 14 46 14 45 14 45 14 45 15 45 15 44 15 44 15 44 16 44 17 43 18 43 19 43 20 43 21 43 22 44 23 44 24 44 25 44 25 44 25 40 25 40 5 2 +PP 5 40 25 40 25 44 24 44 22 43 20 43 18 43 16 44 15 44 13 45 12 47 10 48 9 50 9 51 8 53 8 55 8 57 9 59 9 60 5 60 5 40 2 +PP 40 40 60 40 60 44 59 44 57 43 55 43 53 43 51 44 50 44 48 45 47 47 45 48 44 50 44 51 43 53 43 55 43 57 44 59 44 60 40 60 40 40 2 +PP 15 15 28 15 27 16 27 16 28 18 28 19 28 20 28 21 28 22 27 24 27 24 30 27 31 25 31 24 32 22 32 20 32 18 31 16 31 15 35 15 35 35 15 35 15 31 16 31 18 32 20 32 22 32 24 31 25 31 27 30 24 27 24 27 22 28 21 28 20 28 19 28 18 28 16 27 16 27 15 28 15 15 1 +PP 15 50 35 50 35 70 15 70 15 50 1 +PP 50 15 63 15 62 16 62 16 63 18 63 19 63 20 63 21 63 22 62 24 62 24 65 27 66 25 66 24 67 22 67 20 67 18 66 16 66 15 70 15 70 35 50 35 50 31 51 31 53 32 55 32 57 32 59 31 60 31 62 30 59 27 59 27 57 28 56 28 55 28 54 28 53 28 51 27 51 27 50 28 50 15 2 +PP 50 50 70 50 70 70 50 70 50 50 2 +pa 20 20 16 16 6 0 +pa 55 20 16 16 6 0 +pa 20 55 16 16 6 0 +pa 55 55 16 16 6 0 Index: tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.bottom.copper.none.10.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.bottom.copper.none.10.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.bottom.copper.none.10.gbr (revision 33253) @@ -0,0 +1,67 @@ +G04 start of page 5 for group 10 layer_idx 1 * +G04 Title: thermals vs. multiple layer polygons, bottom_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM_COPPER_NONE_10*% +%ADD20C,0.0315*% +%ADD19C,0.0787*% +%ADD18C,0.0001*% +G54D18*G36* +X13914Y42500D02*X13400Y41986D01* +X13519Y41793D01* +X13756Y41220D01* +X13901Y40618D01* +X13937Y40000D01* +X13901Y39382D01* +X13756Y38780D01* +X13519Y38207D01* +X13400Y38014D01* +X14855Y36560D01* +X15306Y37296D01* +X15664Y38160D01* +X15882Y39068D01* +X15937Y40000D01* +X15882Y40932D01* +X15664Y41840D01* +X15391Y42500D01* +X17500D01* +Y32500D01* +X7500D01* +Y34609D01* +X8160Y34336D01* +X9068Y34118D01* +X10000Y34045D01* +X10932Y34118D01* +X11840Y34336D01* +X12704Y34694D01* +X13440Y35145D01* +X11986Y36600D01* +X11793Y36481D01* +X11220Y36244D01* +X10618Y36099D01* +X10000Y36051D01* +X9382Y36099D01* +X8780Y36244D01* +X8207Y36481D01* +X8014Y36600D01* +X7500Y36086D01* +Y42500D01* +X13914D01* +G37* +G36* +X17500Y25000D02*Y15000D01* +X7500D01* +Y25000D01* +X17500D01* +G37* +G54D19*X10000Y40000D03* +X27500D03* +X10000Y22500D03* +X27500D03* +G54D20*M02* Index: tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.global.boundary.uroute.9.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.global.boundary.uroute.9.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.global.boundary.uroute.9.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 7 for group 9 layer_idx 6 * +G04 Title: thermals vs. multiple layer polygons, global_outline * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_BOUNDARY_UROUTE_9*% +%ADD22C,0.0100*% +G54D22*X0Y50000D02*Y0D01* +Y50000D02*X50000D01* +X0Y0D02*X50000D01* +Y50000D02*Y0D01* +M02* Index: tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.global.virtual.pdrill.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.global.virtual.pdrill.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.global.virtual.pdrill.none.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 6 for group -1 layer_idx 268435462 * +G04 Title: thermals vs. multiple layer polygons, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGLOBAL_VIRTUAL_PDRILL_NONE*% +%ADD21C,0.0315*% +G54D21*X10000Y40000D03* +X27500D03* +X10000Y22500D03* +X27500D03* +M02* Index: tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.intern.copper.none.5.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.intern.copper.none.5.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.intern.copper.none.5.gbr (revision 33253) @@ -0,0 +1,18 @@ +G04 start of page 3 for group 5 layer_idx 4 * +G04 Title: thermals vs. multiple layer polygons, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_5*% +%ADD15C,0.0315*% +%ADD14C,0.0787*% +G54D14*X10000Y40000D03* +X27500D03* +X10000Y22500D03* +X27500D03* +G54D15*M02* Index: tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.intern.copper.none.7.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.intern.copper.none.7.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.intern.copper.none.7.gbr (revision 33253) @@ -0,0 +1,18 @@ +G04 start of page 4 for group 7 layer_idx 5 * +G04 Title: thermals vs. multiple layer polygons, Intern * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNINTERN_COPPER_NONE_7*% +%ADD17C,0.0315*% +%ADD16C,0.0787*% +G54D16*X10000Y40000D03* +X27500D03* +X10000Y22500D03* +X27500D03* +G54D17*M02* Index: tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.logical.virtual.fab.none.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.logical.virtual.fab.none.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.logical.virtual.fab.none.gbr (revision 33253) @@ -0,0 +1,1915 @@ +G04 start of page 8 for group -1 layer_idx 268435461 * +G04 Title: thermals vs. multiple layer polygons, * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNLOGICAL_VIRTUAL_FAB_NONE*% +%ADD26C,0.0100*% +%ADD25C,0.0001*% +%ADD24C,0.0060*% +%ADD23C,0.0080*% +G54D23*X10000Y40000D02*Y38400D01* +Y40000D02*X11387Y40800D01* +X10000Y40000D02*X8613Y40800D01* +X27500Y40000D02*Y38400D01* +Y40000D02*X28887Y40800D01* +X27500Y40000D02*X26113Y40800D01* +X10000Y22500D02*Y20900D01* +Y22500D02*X11387Y23300D01* +X10000Y22500D02*X8613Y23300D01* +X27500Y22500D02*Y20900D01* +Y22500D02*X28887Y23300D01* +X27500Y22500D02*X26113Y23300D01* +X15000Y106250D02*Y104650D01* +Y106250D02*X16387Y107050D01* +X15000Y106250D02*X13613Y107050D01* +G54D24*X135000Y110000D02*X136500Y107000D01* +X138000Y110000D01* +X136500Y107000D02*Y104000D01* +X139800Y107300D02*X142050D01* +X139800Y104000D02*X142800D01* +X139800Y110000D02*Y104000D01* +Y110000D02*X142800D01* +X147600D02*X148350Y109250D01* +X145350Y110000D02*X147600D01* +X144600Y109250D02*X145350Y110000D01* +X144600Y109250D02*Y107750D01* +X145350Y107000D01* +X147600D01* +X148350Y106250D01* +Y104750D01* +X147600Y104000D02*X148350Y104750D01* +X145350Y104000D02*X147600D01* +X144600Y104750D02*X145350Y104000D01* +X98000Y106250D02*X101000Y110000D01* +X98000Y106250D02*X101750D01* +X101000Y110000D02*Y104000D01* +G54D25*G36* +X45000Y110000D02*X49500D01* +Y104000D01* +X45000D01* +Y110000D01* +G37* +G36* +X50400D02*X54900D01* +Y104000D01* +X50400D01* +Y110000D01* +G37* +G36* +X55800D02*X60300D01* +Y104000D01* +X55800D01* +Y110000D01* +G37* +G54D24*X61200Y109250D02*X61950Y110000D01* +X63450D01* +X64200Y109250D01* +X63450Y104000D02*X64200Y104750D01* +X61950Y104000D02*X63450D01* +X61200Y104750D02*X61950Y104000D01* +Y107300D02*X63450D01* +X64200Y109250D02*Y108050D01* +Y106550D02*Y104750D01* +Y106550D02*X63450Y107300D01* +X64200Y108050D02*X63450Y107300D01* +X66000Y109250D02*X66750Y110000D01* +X69000D01* +X69750Y109250D01* +Y107750D01* +X66000Y104000D02*X69750Y107750D01* +X66000Y104000D02*X69750D01* +X3000Y125000D02*X3750Y124250D01* +X750Y125000D02*X3000D01* +X0Y124250D02*X750Y125000D01* +X0Y124250D02*Y122750D01* +X750Y122000D01* +X3000D01* +X3750Y121250D01* +Y119750D01* +X3000Y119000D02*X3750Y119750D01* +X750Y119000D02*X3000D01* +X0Y119750D02*X750Y119000D01* +G54D25*G36* +X5550Y125000D02*X10050D01* +Y119000D01* +X5550D01* +Y125000D01* +G37* +G36* +X10950D02*X15450D01* +Y119000D01* +X10950D01* +Y125000D01* +G37* +G36* +X16350D02*X20850D01* +Y119000D01* +X16350D01* +Y125000D01* +G37* +G36* +X21750D02*X26250D01* +Y119000D01* +X21750D01* +Y125000D01* +G37* +G36* +X27150D02*X31650D01* +Y119000D01* +X27150D01* +Y125000D01* +G37* +G54D24*X0Y118000D02*X5550D01* +X41750Y125000D02*Y119000D01* +X43700Y125000D02*X44750Y123950D01* +Y120050D01* +X43700Y119000D02*X44750Y120050D01* +X41000Y119000D02*X43700D01* +X41000Y125000D02*X43700D01* +G54D25*G36* +X46550D02*X51050D01* +Y119000D01* +X46550D01* +Y125000D01* +G37* +G36* +X51950D02*X56450D01* +Y119000D01* +X51950D01* +Y125000D01* +G37* +G36* +X57350D02*X61850D01* +Y119000D01* +X57350D01* +Y125000D01* +G37* +G36* +X62750D02*X67250D01* +Y119000D01* +X62750D01* +Y125000D01* +G37* +G36* +X70850D02*X75350D01* +Y119000D01* +X70850D01* +Y125000D01* +G37* +G54D24*X76250D02*X77750D01* +X77000D02*Y119000D01* +X76250D02*X77750D01* +G54D25*G36* +X79550Y125000D02*X84050D01* +Y119000D01* +X79550D01* +Y125000D01* +G37* +G36* +X84950D02*X89450D01* +Y119000D01* +X84950D01* +Y125000D01* +G37* +G36* +X90350D02*X94850D01* +Y119000D01* +X90350D01* +Y125000D01* +G37* +G36* +X95750D02*X100250D01* +Y119000D01* +X95750D01* +Y125000D01* +G37* +G54D24*X41000Y118000D02*X52550D01* +X96050Y119000D02*X98000D01* +X95000Y120050D02*X96050Y119000D01* +X95000Y123950D02*Y120050D01* +Y123950D02*X96050Y125000D01* +X98000D01* +G54D25*G36* +X99800D02*X104300D01* +Y119000D01* +X99800D01* +Y125000D01* +G37* +G36* +X105200D02*X109700D01* +Y119000D01* +X105200D01* +Y125000D01* +G37* +G36* +X110600D02*X115100D01* +Y119000D01* +X110600D01* +Y125000D01* +G37* +G36* +X116000D02*X120500D01* +Y119000D01* +X116000D01* +Y125000D01* +G37* +G54D24*X95000Y118000D02*X99800D01* +X130750Y125000D02*Y119000D01* +X130000Y125000D02*X133000D01* +X133750Y124250D01* +Y122750D01* +X133000Y122000D02*X133750Y122750D01* +X130750Y122000D02*X133000D01* +G54D25*G36* +X135550Y125000D02*X140050D01* +Y119000D01* +X135550D01* +Y125000D01* +G37* +G36* +X140950D02*X145450D01* +Y119000D01* +X140950D01* +Y125000D01* +G37* +G36* +X146350D02*X150850D01* +Y119000D01* +X146350D01* +Y125000D01* +G37* +G36* +X151750D02*X156250D01* +Y119000D01* +X151750D01* +Y125000D01* +G37* +G36* +X157150D02*X161650D01* +Y119000D01* +X157150D01* +Y125000D01* +G37* +G36* +X162550D02*X167050D01* +Y119000D01* +X162550D01* +Y125000D01* +G37* +G54D24*X130000Y118000D02*X135550D01* +X0Y140000D02*X3000D01* +X1500D02*Y134000D01* +G54D25*G36* +X4800Y140000D02*X9300D01* +Y134000D01* +X4800D01* +Y140000D01* +G37* +G36* +X10200D02*X14700D01* +Y134000D01* +X10200D01* +Y140000D01* +G37* +G36* +X15600D02*X20100D01* +Y134000D01* +X15600D01* +Y140000D01* +G37* +G36* +X21000D02*X25500D01* +Y134000D01* +X21000D01* +Y140000D01* +G37* +G36* +X29100D02*X33600D01* +Y134000D01* +X29100D01* +Y140000D01* +G37* +G36* +X34500D02*X39000D01* +Y134000D01* +X34500D01* +Y140000D01* +G37* +G36* +X39900D02*X44400D01* +Y134000D01* +X39900D01* +Y140000D01* +G37* +G54D24*X48000Y138800D02*X49200Y140000D01* +Y134000D01* +X48000D02*X50250D01* +G54D25*G36* +X54750Y140000D02*X59250D01* +Y134000D01* +X54750D01* +Y140000D01* +G37* +G36* +X60150D02*X64650D01* +Y134000D01* +X60150D01* +Y140000D01* +G37* +G36* +X65550D02*X70050D01* +Y134000D01* +X65550D01* +Y140000D01* +G37* +G36* +X70950D02*X75450D01* +Y134000D01* +X70950D01* +Y140000D01* +G37* +G36* +X76350D02*X80850D01* +Y134000D01* +X76350D01* +Y140000D01* +G37* +G36* +X81750D02*X86250D01* +Y134000D01* +X81750D01* +Y140000D01* +G37* +G36* +X87150D02*X91650D01* +Y134000D01* +X87150D01* +Y140000D01* +G37* +G36* +X92550D02*X97050D01* +Y134000D01* +X92550D01* +Y140000D01* +G37* +G36* +X97950D02*X102450D01* +Y134000D01* +X97950D01* +Y140000D01* +G37* +G36* +X106050D02*X110550D01* +Y134000D01* +X106050D01* +Y140000D01* +G37* +G36* +X111450D02*X115950D01* +Y134000D01* +X111450D01* +Y140000D01* +G37* +G36* +X116850D02*X121350D01* +Y134000D01* +X116850D01* +Y140000D01* +G37* +G36* +X122250D02*X126750D01* +Y134000D01* +X122250D01* +Y140000D01* +G37* +G36* +X127650D02*X132150D01* +Y134000D01* +X127650D01* +Y140000D01* +G37* +G36* +X135750D02*X140250D01* +Y134000D01* +X135750D01* +Y140000D01* +G37* +G36* +X141150D02*X145650D01* +Y134000D01* +X141150D01* +Y140000D01* +G37* +G36* +X146550D02*X151050D01* +Y134000D01* +X146550D01* +Y140000D01* +G37* +G36* +X151950D02*X156450D01* +Y134000D01* +X151950D01* +Y140000D01* +G37* +G36* +X157350D02*X161850D01* +Y134000D01* +X157350D01* +Y140000D01* +G37* +G36* +X165450D02*X169950D01* +Y134000D01* +X165450D01* +Y140000D01* +G37* +G36* +X170850D02*X175350D01* +Y134000D01* +X170850D01* +Y140000D01* +G37* +G36* +X176250D02*X180750D01* +Y134000D01* +X176250D01* +Y140000D01* +G37* +G36* +X181650D02*X186150D01* +Y134000D01* +X181650D01* +Y140000D01* +G37* +G36* +X189750D02*X194250D01* +Y134000D01* +X189750D01* +Y140000D01* +G37* +G36* +X195150D02*X199650D01* +Y134000D01* +X195150D01* +Y140000D01* +G37* +G36* +X203250D02*X207750D01* +Y134000D01* +X203250D01* +Y140000D01* +G37* +G36* +X208650D02*X213150D01* +Y134000D01* +X208650D01* +Y140000D01* +G37* +G36* +X214050D02*X218550D01* +Y134000D01* +X214050D01* +Y140000D01* +G37* +G36* +X219450D02*X223950D01* +Y134000D01* +X219450D01* +Y140000D01* +G37* +G36* +X227550D02*X232050D01* +Y134000D01* +X227550D01* +Y140000D01* +G37* +G36* +X232950D02*X237450D01* +Y134000D01* +X232950D01* +Y140000D01* +G37* +G36* +X238350D02*X242850D01* +Y134000D01* +X238350D01* +Y140000D01* +G37* +G36* +X243750D02*X248250D01* +Y134000D01* +X243750D01* +Y140000D01* +G37* +G36* +X249150D02*X253650D01* +Y134000D01* +X249150D01* +Y140000D01* +G37* +G36* +X254550D02*X259050D01* +Y134000D01* +X254550D01* +Y140000D01* +G37* +G36* +X259950D02*X264450D01* +Y134000D01* +X259950D01* +Y140000D01* +G37* +G54D24*X268050Y136250D02*X271050Y140000D01* +X268050Y136250D02*X271800D01* +X271050Y140000D02*Y134000D01* +G54D25*G36* +X276300Y140000D02*X280800D01* +Y134000D01* +X276300D01* +Y140000D01* +G37* +G36* +X281700D02*X286200D01* +Y134000D01* +X281700D01* +Y140000D01* +G37* +G36* +X287100D02*X291600D01* +Y134000D01* +X287100D01* +Y140000D01* +G37* +G36* +X292500D02*X297000D01* +Y134000D01* +X292500D01* +Y140000D01* +G37* +G36* +X297900D02*X302400D01* +Y134000D01* +X297900D01* +Y140000D01* +G37* +G36* +X306000D02*X310500D01* +Y134000D01* +X306000D01* +Y140000D01* +G37* +G36* +X311400D02*X315900D01* +Y134000D01* +X311400D01* +Y140000D01* +G37* +G36* +X316800D02*X321300D01* +Y134000D01* +X316800D01* +Y140000D01* +G37* +G36* +X322200D02*X326700D01* +Y134000D01* +X322200D01* +Y140000D01* +G37* +G36* +X327600D02*X332100D01* +Y134000D01* +X327600D01* +Y140000D01* +G37* +G54D26*X0Y50000D02*X50000D01* +X0D02*Y0D01* +X50000Y50000D02*Y0D01* +X0D02*X50000D01* +G54D24*X200000Y65000D02*Y59000D01* +Y65000D02*X202250Y62000D01* +X204500Y65000D01* +Y59000D01* +G54D25*G36* +X206300Y65000D02*X210800D01* +Y59000D01* +X206300D01* +Y65000D01* +G37* +G36* +X211700D02*X216200D01* +Y59000D01* +X211700D01* +Y65000D01* +G37* +G36* +X217100D02*X221600D01* +Y59000D01* +X217100D01* +Y65000D01* +G37* +G36* +X222500D02*X227000D01* +Y59000D01* +X222500D01* +Y65000D01* +G37* +G36* +X227900D02*X232400D01* +Y59000D01* +X227900D01* +Y65000D01* +G37* +G36* +X233300D02*X237800D01* +Y59000D01* +X233300D01* +Y65000D01* +G37* +G54D24*X242150D02*Y59000D01* +X244100Y65000D02*X245150Y63950D01* +Y60050D01* +X244100Y59000D02*X245150Y60050D01* +X241400Y59000D02*X244100D01* +X241400Y65000D02*X244100D01* +G54D25*G36* +X246950D02*X251450D01* +Y59000D01* +X246950D01* +Y65000D01* +G37* +G36* +X252350D02*X256850D01* +Y59000D01* +X252350D01* +Y65000D01* +G37* +G36* +X257750D02*X262250D01* +Y59000D01* +X257750D01* +Y65000D01* +G37* +G36* +X263150D02*X267650D01* +Y59000D01* +X263150D01* +Y65000D01* +G37* +G36* +X268550D02*X273050D01* +Y59000D01* +X268550D01* +Y65000D01* +G37* +G36* +X273950D02*X278450D01* +Y59000D01* +X273950D01* +Y65000D01* +G37* +G36* +X279350D02*X283850D01* +Y59000D01* +X279350D01* +Y65000D01* +G37* +G36* +X284750D02*X289250D01* +Y59000D01* +X284750D01* +Y65000D01* +G37* +G36* +X290150D02*X294650D01* +Y59000D01* +X290150D01* +Y65000D01* +G37* +G36* +X295550D02*X300050D01* +Y59000D01* +X295550D01* +Y65000D01* +G37* +G54D24*X303650D02*X306650D01* +X303650D02*Y62000D01* +X304400Y62750D01* +X305900D01* +X306650Y62000D01* +Y59750D01* +X305900Y59000D02*X306650Y59750D01* +X304400Y59000D02*X305900D01* +X303650Y59750D02*X304400Y59000D01* +G54D25*G36* +X308450Y65000D02*X312950D01* +Y59000D01* +X308450D01* +Y65000D01* +G37* +G36* +X313850D02*X318350D01* +Y59000D01* +X313850D01* +Y65000D01* +G37* +G36* +X319250D02*X323750D01* +Y59000D01* +X319250D01* +Y65000D01* +G37* +G36* +X324650D02*X329150D01* +Y59000D01* +X324650D01* +Y65000D01* +G37* +G36* +X330050D02*X334550D01* +Y59000D01* +X330050D01* +Y65000D01* +G37* +G36* +X335450D02*X339950D01* +Y59000D01* +X335450D01* +Y65000D01* +G37* +G36* +X340850D02*X345350D01* +Y59000D01* +X340850D01* +Y65000D01* +G37* +G36* +X346250D02*X350750D01* +Y59000D01* +X346250D01* +Y65000D01* +G37* +G36* +X351650D02*X356150D01* +Y59000D01* +X351650D01* +Y65000D01* +G37* +G36* +X359750D02*X364250D01* +Y59000D01* +X359750D01* +Y65000D01* +G37* +G36* +X365150D02*X369650D01* +Y59000D01* +X365150D01* +Y65000D01* +G37* +G36* +X370550D02*X375050D01* +Y59000D01* +X370550D01* +Y65000D01* +G37* +G36* +X375950D02*X380450D01* +Y59000D01* +X375950D01* +Y65000D01* +G37* +G36* +X384050D02*X388550D01* +Y59000D01* +X384050D01* +Y65000D01* +G37* +G36* +X389450D02*X393950D01* +Y59000D01* +X389450D01* +Y65000D01* +G37* +G36* +X394850D02*X399350D01* +Y59000D01* +X394850D01* +Y65000D01* +G37* +G36* +X400250D02*X404750D01* +Y59000D01* +X400250D01* +Y65000D01* +G37* +G36* +X405650D02*X410150D01* +Y59000D01* +X405650D01* +Y65000D01* +G37* +G54D24*X413750D02*X416750D01* +X413750D02*Y62000D01* +X414500Y62750D01* +X416000D01* +X416750Y62000D01* +Y59750D01* +X416000Y59000D02*X416750Y59750D01* +X414500Y59000D02*X416000D01* +X413750Y59750D02*X414500Y59000D01* +G54D25*G36* +X418550Y65000D02*X423050D01* +Y59000D01* +X418550D01* +Y65000D01* +G37* +G36* +X423950D02*X428450D01* +Y59000D01* +X423950D01* +Y65000D01* +G37* +G36* +X429350D02*X433850D01* +Y59000D01* +X429350D01* +Y65000D01* +G37* +G36* +X434750D02*X439250D01* +Y59000D01* +X434750D01* +Y65000D01* +G37* +G36* +X440150D02*X444650D01* +Y59000D01* +X440150D01* +Y65000D01* +G37* +G36* +X445550D02*X450050D01* +Y59000D01* +X445550D01* +Y65000D01* +G37* +G36* +X450950D02*X455450D01* +Y59000D01* +X450950D01* +Y65000D01* +G37* +G36* +X456350D02*X460850D01* +Y59000D01* +X456350D01* +Y65000D01* +G37* +G36* +X461750D02*X466250D01* +Y59000D01* +X461750D01* +Y65000D01* +G37* +G36* +X469850D02*X474350D01* +Y59000D01* +X469850D01* +Y65000D01* +G37* +G36* +X475250D02*X479750D01* +Y59000D01* +X475250D01* +Y65000D01* +G37* +G36* +X480650D02*X485150D01* +Y59000D01* +X480650D01* +Y65000D01* +G37* +G36* +X486050D02*X490550D01* +Y59000D01* +X486050D01* +Y65000D01* +G37* +G36* +X494150D02*X498650D01* +Y59000D01* +X494150D01* +Y65000D01* +G37* +G36* +X499550D02*X504050D01* +Y59000D01* +X499550D01* +Y65000D01* +G37* +G36* +X504950D02*X509450D01* +Y59000D01* +X504950D01* +Y65000D01* +G37* +G36* +X510350D02*X514850D01* +Y59000D01* +X510350D01* +Y65000D01* +G37* +G54D24*X0Y-8000D02*X3000D01* +X3750Y-7250D01* +Y-5450D02*Y-7250D01* +X3000Y-4700D02*X3750Y-5450D01* +X750Y-4700D02*X3000D01* +X750Y-2000D02*Y-8000D01* +X0Y-2000D02*X3000D01* +X3750Y-2750D01* +Y-3950D01* +X3000Y-4700D02*X3750Y-3950D01* +G54D25*G36* +X5550Y-2000D02*X10050D01* +Y-8000D01* +X5550D01* +Y-2000D01* +G37* +G36* +X10950D02*X15450D01* +Y-8000D01* +X10950D01* +Y-2000D01* +G37* +G36* +X16350D02*X20850D01* +Y-8000D01* +X16350D01* +Y-2000D01* +G37* +G36* +X21750D02*X26250D01* +Y-8000D01* +X21750D01* +Y-2000D01* +G37* +G36* +X29850D02*X34350D01* +Y-8000D01* +X29850D01* +Y-2000D01* +G37* +G36* +X35250D02*X39750D01* +Y-8000D01* +X35250D01* +Y-2000D01* +G37* +G36* +X40650D02*X45150D01* +Y-8000D01* +X40650D01* +Y-2000D01* +G37* +G36* +X46050D02*X50550D01* +Y-8000D01* +X46050D01* +Y-2000D01* +G37* +G36* +X51450D02*X55950D01* +Y-8000D01* +X51450D01* +Y-2000D01* +G37* +G36* +X56850D02*X61350D01* +Y-8000D01* +X56850D01* +Y-2000D01* +G37* +G36* +X62250D02*X66750D01* +Y-8000D01* +X62250D01* +Y-2000D01* +G37* +G36* +X70350D02*X74850D01* +Y-8000D01* +X70350D01* +Y-2000D01* +G37* +G36* +X75750D02*X80250D01* +Y-8000D01* +X75750D01* +Y-2000D01* +G37* +G36* +X83850D02*X88350D01* +Y-8000D01* +X83850D01* +Y-2000D01* +G37* +G36* +X89250D02*X93750D01* +Y-8000D01* +X89250D01* +Y-2000D01* +G37* +G36* +X94650D02*X99150D01* +Y-8000D01* +X94650D01* +Y-2000D01* +G37* +G36* +X102750D02*X107250D01* +Y-8000D01* +X102750D01* +Y-2000D01* +G37* +G36* +X108150D02*X112650D01* +Y-8000D01* +X108150D01* +Y-2000D01* +G37* +G36* +X113550D02*X118050D01* +Y-8000D01* +X113550D01* +Y-2000D01* +G37* +G36* +X118950D02*X123450D01* +Y-8000D01* +X118950D01* +Y-2000D01* +G37* +G36* +X124350D02*X128850D01* +Y-8000D01* +X124350D01* +Y-2000D01* +G37* +G36* +X129750D02*X134250D01* +Y-8000D01* +X129750D01* +Y-2000D01* +G37* +G36* +X135150D02*X139650D01* +Y-8000D01* +X135150D01* +Y-2000D01* +G37* +G36* +X140550D02*X145050D01* +Y-8000D01* +X140550D01* +Y-2000D01* +G37* +G36* +X145950D02*X150450D01* +Y-8000D01* +X145950D01* +Y-2000D01* +G37* +G36* +X151350D02*X155850D01* +Y-8000D01* +X151350D01* +Y-2000D01* +G37* +G36* +X159450D02*X163950D01* +Y-8000D01* +X159450D01* +Y-2000D01* +G37* +G36* +X164850D02*X169350D01* +Y-8000D01* +X164850D01* +Y-2000D01* +G37* +G36* +X172950D02*X177450D01* +Y-8000D01* +X172950D01* +Y-2000D01* +G37* +G36* +X178350D02*X182850D01* +Y-8000D01* +X178350D01* +Y-2000D01* +G37* +G36* +X183750D02*X188250D01* +Y-8000D01* +X183750D01* +Y-2000D01* +G37* +G36* +X189150D02*X193650D01* +Y-8000D01* +X189150D01* +Y-2000D01* +G37* +G54D24*X197250Y-7250D02*X198000Y-8000D01* +X197250Y-6050D02*Y-7250D01* +Y-6050D02*X198300Y-5000D01* +X199200D01* +X200250Y-6050D01* +Y-7250D01* +X199500Y-8000D02*X200250Y-7250D01* +X198000Y-8000D02*X199500D01* +X197250Y-3950D02*X198300Y-5000D01* +X197250Y-2750D02*Y-3950D01* +Y-2750D02*X198000Y-2000D01* +X199500D01* +X200250Y-2750D01* +Y-3950D01* +X199200Y-5000D02*X200250Y-3950D01* +G54D25*G36* +X202050Y-2000D02*X206550D01* +Y-8000D01* +X202050D01* +Y-2000D01* +G37* +G36* +X207450D02*X211950D01* +Y-8000D01* +X207450D01* +Y-2000D01* +G37* +G36* +X212850D02*X217350D01* +Y-8000D01* +X212850D01* +Y-2000D01* +G37* +G36* +X218250D02*X222750D01* +Y-8000D01* +X218250D01* +Y-2000D01* +G37* +G36* +X223650D02*X228150D01* +Y-8000D01* +X223650D01* +Y-2000D01* +G37* +G36* +X229050D02*X233550D01* +Y-8000D01* +X229050D01* +Y-2000D01* +G37* +G36* +X234450D02*X238950D01* +Y-8000D01* +X234450D01* +Y-2000D01* +G37* +G36* +X242550D02*X247050D01* +Y-8000D01* +X242550D01* +Y-2000D01* +G37* +G36* +X247950D02*X252450D01* +Y-8000D01* +X247950D01* +Y-2000D01* +G37* +G36* +X253350D02*X257850D01* +Y-8000D01* +X253350D01* +Y-2000D01* +G37* +G36* +X261450D02*X265950D01* +Y-8000D01* +X261450D01* +Y-2000D01* +G37* +G36* +X266850D02*X271350D01* +Y-8000D01* +X266850D01* +Y-2000D01* +G37* +G36* +X272250D02*X276750D01* +Y-8000D01* +X272250D01* +Y-2000D01* +G37* +G36* +X277650D02*X282150D01* +Y-8000D01* +X277650D01* +Y-2000D01* +G37* +G36* +X283050D02*X287550D01* +Y-8000D01* +X283050D01* +Y-2000D01* +G37* +G36* +X288450D02*X292950D01* +Y-8000D01* +X288450D01* +Y-2000D01* +G37* +G36* +X293850D02*X298350D01* +Y-8000D01* +X293850D01* +Y-2000D01* +G37* +G36* +X299250D02*X303750D01* +Y-8000D01* +X299250D01* +Y-2000D01* +G37* +G36* +X304650D02*X309150D01* +Y-8000D01* +X304650D01* +Y-2000D01* +G37* +G36* +X312750D02*X317250D01* +Y-8000D01* +X312750D01* +Y-2000D01* +G37* +G36* +X320850D02*X325350D01* +Y-8000D01* +X320850D01* +Y-2000D01* +G37* +G36* +X326250D02*X330750D01* +Y-8000D01* +X326250D01* +Y-2000D01* +G37* +G36* +X331650D02*X336150D01* +Y-8000D01* +X331650D01* +Y-2000D01* +G37* +G36* +X339750D02*X344250D01* +Y-8000D01* +X339750D01* +Y-2000D01* +G37* +G36* +X345150D02*X349650D01* +Y-8000D01* +X345150D01* +Y-2000D01* +G37* +G54D24*X353250D02*X356250D01* +X353250D02*Y-5000D01* +X354000Y-4250D01* +X355500D01* +X356250Y-5000D01* +Y-7250D01* +X355500Y-8000D02*X356250Y-7250D01* +X354000Y-8000D02*X355500D01* +X353250Y-7250D02*X354000Y-8000D01* +G54D25*G36* +X358050Y-2000D02*X362550D01* +Y-8000D01* +X358050D01* +Y-2000D01* +G37* +G36* +X363450D02*X367950D01* +Y-8000D01* +X363450D01* +Y-2000D01* +G37* +G36* +X368850D02*X373350D01* +Y-8000D01* +X368850D01* +Y-2000D01* +G37* +G36* +X374250D02*X378750D01* +Y-8000D01* +X374250D01* +Y-2000D01* +G37* +G36* +X379650D02*X384150D01* +Y-8000D01* +X379650D01* +Y-2000D01* +G37* +G36* +X385050D02*X389550D01* +Y-8000D01* +X385050D01* +Y-2000D01* +G37* +G36* +X390450D02*X394950D01* +Y-8000D01* +X390450D01* +Y-2000D01* +G37* +G36* +X395850D02*X400350D01* +Y-8000D01* +X395850D01* +Y-2000D01* +G37* +G36* +X401250D02*X405750D01* +Y-8000D01* +X401250D01* +Y-2000D01* +G37* +G36* +X406650D02*X411150D01* +Y-8000D01* +X406650D01* +Y-2000D01* +G37* +G54D24*X412050D02*X415050D01* +X412050D02*Y-5000D01* +X412800Y-4250D01* +X414300D01* +X415050Y-5000D01* +Y-7250D01* +X414300Y-8000D02*X415050Y-7250D01* +X412800Y-8000D02*X414300D01* +X412050Y-7250D02*X412800Y-8000D01* +G54D25*G36* +X416850Y-2000D02*X421350D01* +Y-8000D01* +X416850D01* +Y-2000D01* +G37* +G36* +X422250D02*X426750D01* +Y-8000D01* +X422250D01* +Y-2000D01* +G37* +G36* +X427650D02*X432150D01* +Y-8000D01* +X427650D01* +Y-2000D01* +G37* +G36* +X433050D02*X437550D01* +Y-8000D01* +X433050D01* +Y-2000D01* +G37* +G36* +X438450D02*X442950D01* +Y-8000D01* +X438450D01* +Y-2000D01* +G37* +G36* +X443850D02*X448350D01* +Y-8000D01* +X443850D01* +Y-2000D01* +G37* +G36* +X449250D02*X453750D01* +Y-8000D01* +X449250D01* +Y-2000D01* +G37* +G36* +X454650D02*X459150D01* +Y-8000D01* +X454650D01* +Y-2000D01* +G37* +G36* +X460050D02*X464550D01* +Y-8000D01* +X460050D01* +Y-2000D01* +G37* +G36* +X468150D02*X472650D01* +Y-8000D01* +X468150D01* +Y-2000D01* +G37* +G36* +X473550D02*X478050D01* +Y-8000D01* +X473550D01* +Y-2000D01* +G37* +G36* +X478950D02*X483450D01* +Y-8000D01* +X478950D01* +Y-2000D01* +G37* +G36* +X484350D02*X488850D01* +Y-8000D01* +X484350D01* +Y-2000D01* +G37* +G54D24*X200750Y80000D02*Y74000D01* +X202700Y80000D02*X203750Y78950D01* +Y75050D01* +X202700Y74000D02*X203750Y75050D01* +X200000Y74000D02*X202700D01* +X200000Y80000D02*X202700D01* +G54D25*G36* +X205550D02*X210050D01* +Y74000D01* +X205550D01* +Y80000D01* +G37* +G36* +X210950D02*X215450D01* +Y74000D01* +X210950D01* +Y80000D01* +G37* +G36* +X216350D02*X220850D01* +Y74000D01* +X216350D01* +Y80000D01* +G37* +G36* +X221750D02*X226250D01* +Y74000D01* +X221750D01* +Y80000D01* +G37* +G36* +X229850D02*X234350D01* +Y74000D01* +X229850D01* +Y80000D01* +G37* +G36* +X235250D02*X239750D01* +Y74000D01* +X235250D01* +Y80000D01* +G37* +G36* +X240650D02*X245150D01* +Y74000D01* +X240650D01* +Y80000D01* +G37* +G36* +X246050D02*X250550D01* +Y74000D01* +X246050D01* +Y80000D01* +G37* +G36* +X251450D02*X255950D01* +Y74000D01* +X251450D01* +Y80000D01* +G37* +G36* +X256850D02*X261350D01* +Y74000D01* +X256850D01* +Y80000D01* +G37* +G54D24*X200000Y93500D02*Y89000D01* +Y93500D02*X201050Y95000D01* +X202700D01* +X203750Y93500D01* +Y89000D01* +X200000Y92000D02*X203750D01* +G54D25*G36* +X205550Y95000D02*X210050D01* +Y89000D01* +X205550D01* +Y95000D01* +G37* +G36* +X210950D02*X215450D01* +Y89000D01* +X210950D01* +Y95000D01* +G37* +G36* +X216350D02*X220850D01* +Y89000D01* +X216350D01* +Y95000D01* +G37* +G36* +X221750D02*X226250D01* +Y89000D01* +X221750D01* +Y95000D01* +G37* +G36* +X227150D02*X231650D01* +Y89000D01* +X227150D01* +Y95000D01* +G37* +G36* +X232550D02*X237050D01* +Y89000D01* +X232550D01* +Y95000D01* +G37* +G54D24*X240650D02*X243650D01* +X242150D02*Y89000D01* +X245450Y92300D02*X247700D01* +X245450Y89000D02*X248450D01* +X245450Y95000D02*Y89000D01* +Y95000D02*X248450D01* +X253250D02*X254000Y94250D01* +X251000Y95000D02*X253250D01* +X250250Y94250D02*X251000Y95000D01* +X250250Y94250D02*Y92750D01* +X251000Y92000D01* +X253250D01* +X254000Y91250D01* +Y89750D01* +X253250Y89000D02*X254000Y89750D01* +X251000Y89000D02*X253250D01* +X250250Y89750D02*X251000Y89000D01* +X255800Y95000D02*X258800D01* +X257300D02*Y89000D01* +X200000Y110000D02*X203000D01* +X201500D02*Y104000D01* +G54D25*G36* +X204800Y110000D02*X209300D01* +Y104000D01* +X204800D01* +Y110000D01* +G37* +G36* +X210200D02*X214700D01* +Y104000D01* +X210200D01* +Y110000D01* +G37* +G36* +X215600D02*X220100D01* +Y104000D01* +X215600D01* +Y110000D01* +G37* +G36* +X221000D02*X225500D01* +Y104000D01* +X221000D01* +Y110000D01* +G37* +G36* +X226400D02*X230900D01* +Y104000D01* +X226400D01* +Y110000D01* +G37* +G36* +X234500D02*X239000D01* +Y104000D01* +X234500D01* +Y110000D01* +G37* +G36* +X239900D02*X244400D01* +Y104000D01* +X239900D01* +Y110000D01* +G37* +G36* +X245300D02*X249800D01* +Y104000D01* +X245300D01* +Y110000D01* +G37* +G36* +X250700D02*X255200D01* +Y104000D01* +X250700D01* +Y110000D01* +G37* +G36* +X256100D02*X260600D01* +Y104000D01* +X256100D01* +Y110000D01* +G37* +G36* +X261500D02*X266000D01* +Y104000D01* +X261500D01* +Y110000D01* +G37* +G36* +X266900D02*X271400D01* +Y104000D01* +X266900D01* +Y110000D01* +G37* +G36* +X272300D02*X276800D01* +Y104000D01* +X272300D01* +Y110000D01* +G37* +G36* +X280400D02*X284900D01* +Y104000D01* +X280400D01* +Y110000D01* +G37* +G36* +X285800D02*X290300D01* +Y104000D01* +X285800D01* +Y110000D01* +G37* +G36* +X291200D02*X295700D01* +Y104000D01* +X291200D01* +Y110000D01* +G37* +G36* +X299300D02*X303800D01* +Y104000D01* +X299300D01* +Y110000D01* +G37* +G36* +X304700D02*X309200D01* +Y104000D01* +X304700D01* +Y110000D01* +G37* +G36* +X310100D02*X314600D01* +Y104000D01* +X310100D01* +Y110000D01* +G37* +G36* +X315500D02*X320000D01* +Y104000D01* +X315500D01* +Y110000D01* +G37* +G36* +X320900D02*X325400D01* +Y104000D01* +X320900D01* +Y110000D01* +G37* +G36* +X326300D02*X330800D01* +Y104000D01* +X326300D01* +Y110000D01* +G37* +G36* +X331700D02*X336200D01* +Y104000D01* +X331700D01* +Y110000D01* +G37* +G36* +X337100D02*X341600D01* +Y104000D01* +X337100D01* +Y110000D01* +G37* +G36* +X345200D02*X349700D01* +Y104000D01* +X345200D01* +Y110000D01* +G37* +G36* +X350600D02*X355100D01* +Y104000D01* +X350600D01* +Y110000D01* +G37* +G36* +X356000D02*X360500D01* +Y104000D01* +X356000D01* +Y110000D01* +G37* +G36* +X361400D02*X365900D01* +Y104000D01* +X361400D01* +Y110000D01* +G37* +G36* +X366800D02*X371300D01* +Y104000D01* +X366800D01* +Y110000D01* +G37* +G36* +X374900D02*X379400D01* +Y104000D01* +X374900D01* +Y110000D01* +G37* +G36* +X380300D02*X384800D01* +Y104000D01* +X380300D01* +Y110000D01* +G37* +G36* +X385700D02*X390200D01* +Y104000D01* +X385700D01* +Y110000D01* +G37* +G36* +X391100D02*X395600D01* +Y104000D01* +X391100D01* +Y110000D01* +G37* +G36* +X396500D02*X401000D01* +Y104000D01* +X396500D01* +Y110000D01* +G37* +G36* +X401900D02*X406400D01* +Y104000D01* +X401900D01* +Y110000D01* +G37* +G36* +X407300D02*X411800D01* +Y104000D01* +X407300D01* +Y110000D01* +G37* +G36* +X412700D02*X417200D01* +Y104000D01* +X412700D01* +Y110000D01* +G37* +G36* +X420800D02*X425300D01* +Y104000D01* +X420800D01* +Y110000D01* +G37* +G54D24*X428900D02*Y104000D01* +Y110000D02*X431900D01* +X428900Y107300D02*X431150D01* +G54D25*G36* +X433700Y110000D02*X438200D01* +Y104000D01* +X433700D01* +Y110000D01* +G37* +G36* +X439100D02*X443600D01* +Y104000D01* +X439100D01* +Y110000D01* +G37* +G36* +X444500D02*X449000D01* +Y104000D01* +X444500D01* +Y110000D01* +G37* +G36* +X449900D02*X454400D01* +Y104000D01* +X449900D01* +Y110000D01* +G37* +G36* +X455300D02*X459800D01* +Y104000D01* +X455300D01* +Y110000D01* +G37* +G36* +X460700D02*X465200D01* +Y104000D01* +X460700D01* +Y110000D01* +G37* +G36* +X466100D02*X470600D01* +Y104000D01* +X466100D01* +Y110000D01* +G37* +G36* +X471500D02*X476000D01* +Y104000D01* +X471500D01* +Y110000D01* +G37* +G36* +X476900D02*X481400D01* +Y104000D01* +X476900D01* +Y110000D01* +G37* +G36* +X482300D02*X486800D01* +Y104000D01* +X482300D01* +Y110000D01* +G37* +G54D24*X491150D02*Y104000D01* +X493100Y110000D02*X494150Y108950D01* +Y105050D01* +X493100Y104000D02*X494150Y105050D01* +X490400Y104000D02*X493100D01* +X490400Y110000D02*X493100D01* +G54D25*G36* +X495950D02*X500450D01* +Y104000D01* +X495950D01* +Y110000D01* +G37* +G36* +X501350D02*X505850D01* +Y104000D01* +X501350D01* +Y110000D01* +G37* +G36* +X506750D02*X511250D01* +Y104000D01* +X506750D01* +Y110000D01* +G37* +G36* +X512150D02*X516650D01* +Y104000D01* +X512150D01* +Y110000D01* +G37* +G36* +X517550D02*X522050D01* +Y104000D01* +X517550D01* +Y110000D01* +G37* +G36* +X522950D02*X527450D01* +Y104000D01* +X522950D01* +Y110000D01* +G37* +M02* Index: tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.top.copper.none.3.gbr =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.top.copper.none.3.gbr (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.gbr/thermal_layer.top.copper.none.3.gbr (revision 33253) @@ -0,0 +1,315 @@ +G04 start of page 2 for group 3 layer_idx 0 * +G04 Title: thermals vs. multiple layer polygons, top_copper * +G04 Creator: +G04 CreationDate: +G04 For: TEST * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 50000 50000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP_COPPER_NONE_3*% +%ADD13C,0.0315*% +%ADD12C,0.0787*% +%ADD11C,0.0001*% +G54D11*G36* +X31414Y42500D02*X30900Y41986D01* +X31019Y41793D01* +X31256Y41220D01* +X31401Y40618D01* +X31437Y40000D01* +X31401Y39382D01* +X31256Y38780D01* +X31019Y38207D01* +X30900Y38014D01* +X32355Y36560D01* +X32806Y37296D01* +X33164Y38160D01* +X33382Y39068D01* +X33437Y40000D01* +X33382Y40932D01* +X33164Y41840D01* +X32891Y42500D01* +X35000D01* +Y32500D01* +X25000D01* +Y34609D01* +X25660Y34336D01* +X26568Y34118D01* +X27500Y34045D01* +X28432Y34118D01* +X29340Y34336D01* +X30204Y34694D01* +X30940Y35145D01* +X29486Y36600D01* +X29293Y36481D01* +X28720Y36244D01* +X28118Y36099D01* +X27500Y36051D01* +X26882Y36099D01* +X26280Y36244D01* +X25707Y36481D01* +X25514Y36600D01* +X25000Y36086D01* +Y42500D01* +X31414D01* +G37* +G36* +X35000Y25000D02*Y15000D01* +X25000D01* +Y25000D01* +X35000D01* +G37* +G36* +X12500Y47500D02*Y45330D01* +X12475Y45355D01* +X12346Y45446D01* +X12204Y45513D01* +X11672Y45704D01* +X11123Y45837D01* +X10564Y45917D01* +X10000Y45944D01* +X9436Y45917D01* +X8877Y45837D01* +X8328Y45704D01* +X7794Y45519D01* +X7652Y45450D01* +X7523Y45358D01* +X7409Y45248D01* +X7315Y45121D01* +X7241Y44981D01* +X7191Y44832D01* +X7164Y44676D01* +X7162Y44518D01* +X7185Y44361D01* +X7232Y44210D01* +X7302Y44069D01* +X7393Y43939D01* +X7504Y43826D01* +X7630Y43732D01* +X7770Y43658D01* +X7920Y43608D01* +X8076Y43581D01* +X8234Y43579D01* +X8390Y43602D01* +X8540Y43652D01* +X8892Y43778D01* +X9256Y43866D01* +X9626Y43919D01* +X10000Y43937D01* +X10374Y43919D01* +X10744Y43866D01* +X11108Y43778D01* +X11461Y43656D01* +X11611Y43606D01* +X11766Y43583D01* +X11924Y43585D01* +X12079Y43612D01* +X12228Y43662D01* +X12367Y43736D01* +X12493Y43830D01* +X12500Y43836D01* +Y37500D01* +X6170D01* +X6174Y37504D01* +X6268Y37630D01* +X6342Y37770D01* +X6392Y37920D01* +X6419Y38076D01* +X6421Y38234D01* +X6398Y38390D01* +X6348Y38540D01* +X6222Y38892D01* +X6134Y39256D01* +X6081Y39626D01* +X6063Y40000D01* +X6081Y40374D01* +X6134Y40744D01* +X6222Y41108D01* +X6344Y41461D01* +X6394Y41611D01* +X6417Y41766D01* +X6415Y41924D01* +X6388Y42079D01* +X6338Y42228D01* +X6264Y42367D01* +X6170Y42493D01* +X6058Y42603D01* +X5929Y42694D01* +X5788Y42764D01* +X5638Y42811D01* +X5482Y42833D01* +X5325Y42832D01* +X5169Y42805D01* +X5020Y42754D01* +X4881Y42681D01* +X4755Y42587D01* +X4645Y42475D01* +X4554Y42346D01* +X4487Y42204D01* +X4296Y41672D01* +X4163Y41123D01* +X4083Y40564D01* +X4056Y40000D01* +X4083Y39436D01* +X4163Y38877D01* +X4296Y38328D01* +X4481Y37794D01* +X4550Y37652D01* +X4642Y37523D01* +X4664Y37500D01* +X2500D01* +Y47500D01* +X12500D01* +G37* +G36* +X30000D02*Y45330D01* +X29975Y45355D01* +X29846Y45446D01* +X29704Y45513D01* +X29172Y45704D01* +X28623Y45837D01* +X28064Y45917D01* +X27500Y45944D01* +X26936Y45917D01* +X26377Y45837D01* +X25828Y45704D01* +X25294Y45519D01* +X25152Y45450D01* +X25023Y45358D01* +X24909Y45248D01* +X24815Y45121D01* +X24741Y44981D01* +X24691Y44832D01* +X24664Y44676D01* +X24662Y44518D01* +X24685Y44361D01* +X24732Y44210D01* +X24802Y44069D01* +X24893Y43939D01* +X25004Y43826D01* +X25130Y43732D01* +X25270Y43658D01* +X25420Y43608D01* +X25576Y43581D01* +X25734Y43579D01* +X25890Y43602D01* +X26040Y43652D01* +X26392Y43778D01* +X26756Y43866D01* +X27126Y43919D01* +X27500Y43937D01* +X27874Y43919D01* +X28244Y43866D01* +X28608Y43778D01* +X28961Y43656D01* +X29111Y43606D01* +X29266Y43583D01* +X29424Y43585D01* +X29579Y43612D01* +X29728Y43662D01* +X29867Y43736D01* +X29993Y43830D01* +X30000Y43836D01* +Y37500D01* +X23670D01* +X23674Y37504D01* +X23768Y37630D01* +X23842Y37770D01* +X23892Y37920D01* +X23919Y38076D01* +X23921Y38234D01* +X23898Y38390D01* +X23848Y38540D01* +X23722Y38892D01* +X23634Y39256D01* +X23581Y39626D01* +X23563Y40000D01* +X23581Y40374D01* +X23634Y40744D01* +X23722Y41108D01* +X23844Y41461D01* +X23894Y41611D01* +X23917Y41766D01* +X23915Y41924D01* +X23888Y42079D01* +X23838Y42228D01* +X23764Y42367D01* +X23670Y42493D01* +X23558Y42603D01* +X23429Y42694D01* +X23288Y42764D01* +X23138Y42811D01* +X22982Y42833D01* +X22825Y42832D01* +X22669Y42805D01* +X22520Y42754D01* +X22381Y42681D01* +X22255Y42587D01* +X22145Y42475D01* +X22054Y42346D01* +X21987Y42204D01* +X21796Y41672D01* +X21663Y41123D01* +X21583Y40564D01* +X21556Y40000D01* +X21583Y39436D01* +X21663Y38877D01* +X21796Y38328D01* +X21981Y37794D01* +X22050Y37652D01* +X22142Y37523D01* +X22164Y37500D01* +X20000D01* +Y47500D01* +X30000D01* +G37* +G36* +X12500Y30000D02*Y27891D01* +X11840Y28164D01* +X10932Y28382D01* +X10000Y28455D01* +X9068Y28382D01* +X8160Y28164D01* +X7296Y27806D01* +X6500Y27318D01* +X5789Y26711D01* +X5182Y26000D01* +X4694Y25204D01* +X4336Y24340D01* +X4118Y23432D01* +X4045Y22500D01* +X4118Y21568D01* +X4336Y20660D01* +X4609Y20000D01* +X2500D01* +Y30000D01* +X12500D01* +G37* +G36* +X30000D02*Y27891D01* +X29340Y28164D01* +X28432Y28382D01* +X27500Y28455D01* +X26568Y28382D01* +X25660Y28164D01* +X24796Y27806D01* +X24000Y27318D01* +X23289Y26711D01* +X22682Y26000D01* +X22194Y25204D01* +X21836Y24340D01* +X21618Y23432D01* +X21545Y22500D01* +X21618Y21568D01* +X21836Y20660D01* +X22109Y20000D01* +X20000D01* +Y30000D01* +X30000D01* +G37* +G54D12*X10000Y40000D03* +X27500D03* +X10000Y22500D03* +X27500D03* +G54D13*M02* Index: tags/2.3.0/tests/RTT/ref/thermal_layer.nelma.em =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.nelma.em (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.nelma.em (revision 33253) @@ -0,0 +1,75 @@ +/* banner */ + */ +/* **** Nets **** */ + + +/* **** Objects **** */ + + +/* **** Layers **** */ + +layer air-top { + height = 40 + z-order = 1 + material = "air" +} +layer air-bottom { + height = 40 + z-order = 1000 + material = "air" +} +layer top { + height = 1 + z-order = 10 + material = "air" + objects = { + + } +} +layer substrate-11 { + height = 20 + z-order = 11 + material = "composite" +} +layer bottom { + height = 1 + z-order = 12 + material = "air" + objects = { + + } +} + +/* **** Materials **** */ + +material copper { + type = "metal" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material air { + type = "dielectric" + permittivity = 8.850000e-12 + conductivity = 0.0 + permeability = 0.0 +} +material composite { + type = "dielectric" + permittivity = 3.540000e-11 + conductivity = 0.0 + permeability = 0.0 +} + +/* **** Space **** */ + +space pcb { + step = { 2.540000e-04, 2.540000e-04, 1.000000e-04 } + layers = { + "air-top", + "air-bottom", + "top", + "substrate-11", + "bottom" + } +} Index: tags/2.3.0/tests/RTT/ref/thermal_layer.net =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.net (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.net (revision 33253) @@ -0,0 +1,16 @@ +C IPC-D-356 Netlist generated by +C +C File created on +C +P JOB thermals vs. multiple layer polygons +P CODE 00 +P UNITS CUST 0 +P DIM N +P VER IPC-D-356 +P IMAGE PRIMARY +C +317N/C VIA - D0315PA00X+001000Y+004000X0787Y0000R000 S3 +317N/C VIA - D0315PA00X+002750Y+004000X0787Y0000R000 S3 +317N/C VIA - D0315PA00X+001000Y+002250X0787Y0000R000 S3 +317N/C VIA - D0315PA00X+002750Y+002250X0787Y0000R000 S3 +999 Index: tags/2.3.0/tests/RTT/ref/thermal_layer.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/thermal_layer.png =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.png (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.png (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/thermal_layer.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/thermal_layer.png.text =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.png.text (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.png.text (revision 33253) @@ -0,0 +1,10 @@ +r6731 + +each red polygon is 121x121 pixels (100.833 x 100.833) +each blue polygon is 121x121 pixels (100.833 x 100.833) + +clearance 23 pixels (19.167) +copper width 95 pixels (79.166) +drill width 39 pixels (32.5) + +lower two vias are cleared with only 23 pixels (19.166) Index: tags/2.3.0/tests/RTT/ref/thermal_layer.ps.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/thermal_layer.ps.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.ps.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.ps.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/thermal_layer.ps.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/thermal_layer.remote.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/RTT/ref/thermal_layer.remote.gz =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.remote.gz (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.remote.gz (revision 33253) Property changes on: tags/2.3.0/tests/RTT/ref/thermal_layer.remote.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/RTT/ref/thermal_layer.svg =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.svg (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.svg (revision 33253) @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/RTT/ref/thermal_layer.xy =================================================================== --- tags/2.3.0/tests/RTT/ref/thermal_layer.xy (nonexistent) +++ tags/2.3.0/tests/RTT/ref/thermal_layer.xy (revision 33253) @@ -0,0 +1,8 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: +# Author: TEST +# Title: thermals vs. multiple layer polygons - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mil. rotation in degrees. +# -------------------------------------------- Index: tags/2.3.0/tests/RTT/text_rot.pcb =================================================================== --- tags/2.3.0/tests/RTT/text_rot.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/text_rot.pcb (revision 33253) @@ -0,0 +1,95 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["text rotations" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Symbol['A' 304800nm] +( + SymbolLine[0 508000nm 0 1270000nm 203200nm] + SymbolLine[0 508000nm 177800nm 254000nm 203200nm] + SymbolLine[177800nm 254000nm 457200nm 254000nm 203200nm] + SymbolLine[457200nm 254000nm 635000nm 508000nm 203200nm] + SymbolLine[635000nm 508000nm 635000nm 1270000nm 203200nm] + SymbolLine[0 762000nm 635000nm 762000nm 203200nm] +) +Symbol['1' 304800nm] +( + SymbolLine[0 457200nm 203200nm 254000nm 203200nm] + SymbolLine[203200nm 254000nm 203200nm 1270000nm 203200nm] + SymbolLine[0 1270000nm 381000nm 1270000nm 203200nm] +) +Symbol['2' 304800nm] +( + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 508000nm 254000nm 203200nm] + SymbolLine[508000nm 254000nm 635000nm 381000nm 203200nm] + SymbolLine[635000nm 381000nm 635000nm 635000nm 203200nm] + SymbolLine[0 1270000nm 635000nm 635000nm 203200nm] + SymbolLine[0 1270000nm 635000nm 1270000nm 203200nm] +) +Symbol['3' 304800nm] +( + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[381000nm 254000nm 508000nm 381000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 711200nm 381000nm 711200nm 203200nm] + SymbolLine[508000nm 381000nm 508000nm 584200nm 203200nm] + SymbolLine[508000nm 838200nm 508000nm 1143000nm 203200nm] + SymbolLine[508000nm 838200nm 381000nm 711200nm 203200nm] + SymbolLine[508000nm 584200nm 381000nm 711200nm 203200nm] +) +Symbol['4' 304800nm] +( + SymbolLine[0 889000nm 508000nm 254000nm 203200nm] + SymbolLine[0 889000nm 635000nm 889000nm 203200nm] + SymbolLine[508000nm 254000nm 508000nm 1270000nm 203200nm] +) + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") + +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( + Text[5715000nm 3810000nm 0 100 "A1" "clearline"] + Text[3810000nm 6985000nm 1 100 "A2" "clearline"] + Text[6985000nm 8890000nm 2 100 "A3" "clearline"] + Text[8890000nm 5715000nm 3 100 "A4" "clearline"] +) Index: tags/2.3.0/tests/RTT/text_scale.pcb =================================================================== --- tags/2.3.0/tests/RTT/text_scale.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/text_scale.pcb (revision 33253) @@ -0,0 +1,87 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["text sizes (scales)" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Symbol['A' 304800nm] +( + SymbolLine[0 508000nm 0 1270000nm 203200nm] + SymbolLine[0 508000nm 177800nm 254000nm 203200nm] + SymbolLine[177800nm 254000nm 457200nm 254000nm 203200nm] + SymbolLine[457200nm 254000nm 635000nm 508000nm 203200nm] + SymbolLine[635000nm 508000nm 635000nm 1270000nm 203200nm] + SymbolLine[0 762000nm 635000nm 762000nm 203200nm] +) +Symbol['1' 304800nm] +( + SymbolLine[0 457200nm 203200nm 254000nm 203200nm] + SymbolLine[203200nm 254000nm 203200nm 1270000nm 203200nm] + SymbolLine[0 1270000nm 381000nm 1270000nm 203200nm] +) +Symbol['2' 304800nm] +( + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 508000nm 254000nm 203200nm] + SymbolLine[508000nm 254000nm 635000nm 381000nm 203200nm] + SymbolLine[635000nm 381000nm 635000nm 635000nm 203200nm] + SymbolLine[0 1270000nm 635000nm 635000nm 203200nm] + SymbolLine[0 1270000nm 635000nm 1270000nm 203200nm] +) +Symbol['3' 304800nm] +( + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[381000nm 254000nm 508000nm 381000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 711200nm 381000nm 711200nm 203200nm] + SymbolLine[508000nm 381000nm 508000nm 584200nm 203200nm] + SymbolLine[508000nm 838200nm 508000nm 1143000nm 203200nm] + SymbolLine[508000nm 838200nm 381000nm 711200nm 203200nm] + SymbolLine[508000nm 584200nm 381000nm 711200nm 203200nm] +) + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( + Text[1270000nm 635000nm 0 100 "A1" "clearline"] + Text[1270000nm 5080000nm 0 10 "A2" "clearline"] + Text[1270000nm 7620000nm 0 320 "A3" "clearline"] +) Index: tags/2.3.0/tests/RTT/text_sides.pcb =================================================================== --- tags/2.3.0/tests/RTT/text_sides.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/text_sides.pcb (revision 33253) @@ -0,0 +1,74 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["text on both sides" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[1905000nm 635000nm 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + + +Symbol['A' 304800nm] +( + SymbolLine[0 508000nm 0 1270000nm 203200nm] + SymbolLine[0 508000nm 177800nm 254000nm 203200nm] + SymbolLine[177800nm 254000nm 457200nm 254000nm 203200nm] + SymbolLine[457200nm 254000nm 635000nm 508000nm 203200nm] + SymbolLine[635000nm 508000nm 635000nm 1270000nm 203200nm] + SymbolLine[0 762000nm 635000nm 762000nm 203200nm] +) +Symbol['1' 304800nm] +( + SymbolLine[0 457200nm 203200nm 254000nm 203200nm] + SymbolLine[203200nm 254000nm 203200nm 1270000nm 203200nm] + SymbolLine[0 1270000nm 381000nm 1270000nm 203200nm] +) +Symbol['2' 304800nm] +( + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 508000nm 254000nm 203200nm] + SymbolLine[508000nm 254000nm 635000nm 381000nm 203200nm] + SymbolLine[635000nm 381000nm 635000nm 635000nm 203200nm] + SymbolLine[0 1270000nm 635000nm 635000nm 203200nm] + SymbolLine[0 1270000nm 635000nm 1270000nm 203200nm] +) + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") + +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( + Text[5715000nm 7620000nm 0 100 "A2" "clearline,onsolder"] +) +Layer(9 "silk") +( + Text[5715000nm 4445000nm 0 100 "A1" "clearline"] +) Index: tags/2.3.0/tests/RTT/thermal_last.pcb =================================================================== --- tags/2.3.0/tests/RTT/thermal_last.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/thermal_last.pcb (revision 33253) @@ -0,0 +1,826 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["thermals on the last 2 layers - catch off-by-one bugs due to the 0-base index of thermals" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Symbol[' ' 457200nm] +( +) +Symbol['!' 304800nm] +( + SymbolLine[0 1143000nm 0 1270000nm 203200nm] + SymbolLine[0 254000nm 0 889000nm 203200nm] +) +Symbol['"' 304800nm] +( + SymbolLine[0 254000nm 0 508000nm 203200nm] + SymbolLine[254000nm 254000nm 254000nm 508000nm 203200nm] +) +Symbol['#' 304800nm] +( + SymbolLine[0 889000nm 508000nm 889000nm 203200nm] + SymbolLine[0 635000nm 508000nm 635000nm 203200nm] + SymbolLine[381000nm 508000nm 381000nm 1016000nm 203200nm] + SymbolLine[127000nm 508000nm 127000nm 1016000nm 203200nm] +) +Symbol['$' 304800nm] +( + SymbolLine[381000nm 381000nm 508000nm 508000nm 203200nm] + SymbolLine[127000nm 381000nm 381000nm 381000nm 203200nm] + SymbolLine[0 508000nm 127000nm 381000nm 203200nm] + SymbolLine[0 508000nm 0 635000nm 203200nm] + SymbolLine[0 635000nm 127000nm 762000nm 203200nm] + SymbolLine[127000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[508000nm 889000nm 508000nm 1016000nm 203200nm] + SymbolLine[381000nm 1143000nm 508000nm 1016000nm 203200nm] + SymbolLine[127000nm 1143000nm 381000nm 1143000nm 203200nm] + SymbolLine[0 1016000nm 127000nm 1143000nm 203200nm] + SymbolLine[254000nm 254000nm 254000nm 1270000nm 203200nm] +) +Symbol['%' 304800nm] +( + SymbolLine[0 381000nm 0 508000nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 254000nm 254000nm 203200nm] + SymbolLine[254000nm 254000nm 381000nm 381000nm 203200nm] + SymbolLine[381000nm 381000nm 381000nm 508000nm 203200nm] + SymbolLine[254000nm 635000nm 381000nm 508000nm 203200nm] + SymbolLine[127000nm 635000nm 254000nm 635000nm 203200nm] + SymbolLine[0 508000nm 127000nm 635000nm 203200nm] + SymbolLine[0 1270000nm 1016000nm 254000nm 203200nm] + SymbolLine[889000nm 1270000nm 1016000nm 1143000nm 203200nm] + SymbolLine[1016000nm 1016000nm 1016000nm 1143000nm 203200nm] + SymbolLine[889000nm 889000nm 1016000nm 1016000nm 203200nm] + SymbolLine[762000nm 889000nm 889000nm 889000nm 203200nm] + SymbolLine[635000nm 1016000nm 762000nm 889000nm 203200nm] + SymbolLine[635000nm 1016000nm 635000nm 1143000nm 203200nm] + SymbolLine[635000nm 1143000nm 762000nm 1270000nm 203200nm] + SymbolLine[762000nm 1270000nm 889000nm 1270000nm 203200nm] +) +Symbol['&' 304800nm] +( + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 381000nm 0 635000nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[0 889000nm 381000nm 508000nm 203200nm] + SymbolLine[127000nm 1270000nm 254000nm 1270000nm 203200nm] + SymbolLine[254000nm 1270000nm 508000nm 1016000nm 203200nm] + SymbolLine[0 635000nm 635000nm 1270000nm 203200nm] + SymbolLine[127000nm 254000nm 254000nm 254000nm 203200nm] + SymbolLine[254000nm 254000nm 381000nm 381000nm 203200nm] + SymbolLine[381000nm 381000nm 381000nm 508000nm 203200nm] + SymbolLine[0 889000nm 0 1143000nm 203200nm] +) +Symbol[''' 304800nm] +( + SymbolLine[0 508000nm 254000nm 254000nm 203200nm] +) +Symbol['(' 304800nm] +( + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[0 381000nm 0 1143000nm 203200nm] +) +Symbol[')' 304800nm] +( + SymbolLine[0 254000nm 127000nm 381000nm 203200nm] + SymbolLine[127000nm 381000nm 127000nm 1143000nm 203200nm] + SymbolLine[0 1270000nm 127000nm 1143000nm 203200nm] +) +Symbol['*' 304800nm] +( + SymbolLine[0 508000nm 508000nm 1016000nm 203200nm] + SymbolLine[0 1016000nm 508000nm 508000nm 203200nm] + SymbolLine[0 762000nm 508000nm 762000nm 203200nm] + SymbolLine[254000nm 508000nm 254000nm 1016000nm 203200nm] +) +Symbol['+' 304800nm] +( + SymbolLine[0 762000nm 508000nm 762000nm 203200nm] + SymbolLine[254000nm 508000nm 254000nm 1016000nm 203200nm] +) +Symbol[',' 304800nm] +( + SymbolLine[0 1524000nm 254000nm 1270000nm 203200nm] +) +Symbol['-' 304800nm] +( + SymbolLine[0 762000nm 508000nm 762000nm 203200nm] +) +Symbol['.' 304800nm] +( + SymbolLine[0 1270000nm 127000nm 1270000nm 203200nm] +) +Symbol['/' 304800nm] +( + SymbolLine[0 1143000nm 762000nm 381000nm 203200nm] +) +Symbol['0' 304800nm] +( + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 381000nm 0 1143000nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[381000nm 254000nm 508000nm 381000nm 203200nm] + SymbolLine[508000nm 381000nm 508000nm 1143000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[0 1016000nm 508000nm 508000nm 203200nm] +) +Symbol['1' 304800nm] +( + SymbolLine[0 457200nm 203200nm 254000nm 203200nm] + SymbolLine[203200nm 254000nm 203200nm 1270000nm 203200nm] + SymbolLine[0 1270000nm 381000nm 1270000nm 203200nm] +) +Symbol['2' 304800nm] +( + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 508000nm 254000nm 203200nm] + SymbolLine[508000nm 254000nm 635000nm 381000nm 203200nm] + SymbolLine[635000nm 381000nm 635000nm 635000nm 203200nm] + SymbolLine[0 1270000nm 635000nm 635000nm 203200nm] + SymbolLine[0 1270000nm 635000nm 1270000nm 203200nm] +) +Symbol['3' 304800nm] +( + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[381000nm 254000nm 508000nm 381000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 711200nm 381000nm 711200nm 203200nm] + SymbolLine[508000nm 381000nm 508000nm 584200nm 203200nm] + SymbolLine[508000nm 838200nm 508000nm 1143000nm 203200nm] + SymbolLine[508000nm 838200nm 381000nm 711200nm 203200nm] + SymbolLine[508000nm 584200nm 381000nm 711200nm 203200nm] +) +Symbol['4' 304800nm] +( + SymbolLine[0 889000nm 508000nm 254000nm 203200nm] + SymbolLine[0 889000nm 635000nm 889000nm 203200nm] + SymbolLine[508000nm 254000nm 508000nm 1270000nm 203200nm] +) +Symbol['5' 304800nm] +( + SymbolLine[0 254000nm 508000nm 254000nm 203200nm] + SymbolLine[0 254000nm 0 762000nm 203200nm] + SymbolLine[0 762000nm 127000nm 635000nm 203200nm] + SymbolLine[127000nm 635000nm 381000nm 635000nm 203200nm] + SymbolLine[381000nm 635000nm 508000nm 762000nm 203200nm] + SymbolLine[508000nm 762000nm 508000nm 1143000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] +) +Symbol['6' 304800nm] +( + SymbolLine[381000nm 254000nm 508000nm 381000nm 203200nm] + SymbolLine[127000nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[0 381000nm 0 1143000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[381000nm 711200nm 508000nm 838200nm 203200nm] + SymbolLine[0 711200nm 381000nm 711200nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[508000nm 838200nm 508000nm 1143000nm 203200nm] +) +Symbol['7' 304800nm] +( + SymbolLine[127000nm 1270000nm 635000nm 254000nm 203200nm] + SymbolLine[0 254000nm 635000nm 254000nm 203200nm] +) +Symbol['8' 304800nm] +( + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 939800nm 0 1143000nm 203200nm] + SymbolLine[0 939800nm 177800nm 762000nm 203200nm] + SymbolLine[177800nm 762000nm 330200nm 762000nm 203200nm] + SymbolLine[330200nm 762000nm 508000nm 939800nm 203200nm] + SymbolLine[508000nm 939800nm 508000nm 1143000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[0 584200nm 177800nm 762000nm 203200nm] + SymbolLine[0 381000nm 0 584200nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[381000nm 254000nm 508000nm 381000nm 203200nm] + SymbolLine[508000nm 381000nm 508000nm 584200nm 203200nm] + SymbolLine[330200nm 762000nm 508000nm 584200nm 203200nm] +) +Symbol['9' 304800nm] +( + SymbolLine[127000nm 1270000nm 508000nm 762000nm 203200nm] + SymbolLine[508000nm 381000nm 508000nm 762000nm 203200nm] + SymbolLine[381000nm 254000nm 508000nm 381000nm 203200nm] + SymbolLine[127000nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[0 381000nm 0 635000nm 203200nm] + SymbolLine[0 635000nm 127000nm 762000nm 203200nm] + SymbolLine[127000nm 762000nm 508000nm 762000nm 203200nm] +) +Symbol[':' 304800nm] +( + SymbolLine[0 635000nm 127000nm 635000nm 203200nm] + SymbolLine[0 889000nm 127000nm 889000nm 203200nm] +) +Symbol[';' 304800nm] +( + SymbolLine[0 1270000nm 254000nm 1016000nm 203200nm] + SymbolLine[254000nm 635000nm 254000nm 762000nm 203200nm] +) +Symbol['<' 304800nm] +( + SymbolLine[0 762000nm 254000nm 508000nm 203200nm] + SymbolLine[0 762000nm 254000nm 1016000nm 203200nm] +) +Symbol['=' 304800nm] +( + SymbolLine[0 635000nm 508000nm 635000nm 203200nm] + SymbolLine[0 889000nm 508000nm 889000nm 203200nm] +) +Symbol['>' 304800nm] +( + SymbolLine[0 508000nm 254000nm 762000nm 203200nm] + SymbolLine[0 1016000nm 254000nm 762000nm 203200nm] +) +Symbol['?' 304800nm] +( + SymbolLine[254000nm 762000nm 254000nm 889000nm 203200nm] + SymbolLine[254000nm 1143000nm 254000nm 1270000nm 203200nm] + SymbolLine[0 381000nm 0 508000nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[381000nm 254000nm 508000nm 381000nm 203200nm] + SymbolLine[508000nm 381000nm 508000nm 508000nm 203200nm] + SymbolLine[254000nm 762000nm 508000nm 508000nm 203200nm] +) +Symbol['@' 304800nm] +( + SymbolLine[0 254000nm 0 1016000nm 203200nm] + SymbolLine[0 1016000nm 254000nm 1270000nm 203200nm] + SymbolLine[254000nm 1270000nm 1016000nm 1270000nm 203200nm] + SymbolLine[1270000nm 889000nm 1270000nm 254000nm 203200nm] + SymbolLine[1270000nm 254000nm 1016000nm 0 203200nm] + SymbolLine[1016000nm 0 254000nm 0 203200nm] + SymbolLine[254000nm 0 0 254000nm 203200nm] + SymbolLine[381000nm 508000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[508000nm 889000nm 762000nm 889000nm 203200nm] + SymbolLine[762000nm 889000nm 889000nm 762000nm 203200nm] + SymbolLine[889000nm 762000nm 1016000nm 889000nm 203200nm] + SymbolLine[889000nm 762000nm 889000nm 381000nm 203200nm] + SymbolLine[889000nm 508000nm 762000nm 381000nm 203200nm] + SymbolLine[508000nm 381000nm 762000nm 381000nm 203200nm] + SymbolLine[508000nm 381000nm 381000nm 508000nm 203200nm] + SymbolLine[1016000nm 889000nm 1270000nm 889000nm 203200nm] +) +Symbol['A' 304800nm] +( + SymbolLine[0 508000nm 0 1270000nm 203200nm] + SymbolLine[0 508000nm 177800nm 254000nm 203200nm] + SymbolLine[177800nm 254000nm 457200nm 254000nm 203200nm] + SymbolLine[457200nm 254000nm 635000nm 508000nm 203200nm] + SymbolLine[635000nm 508000nm 635000nm 1270000nm 203200nm] + SymbolLine[0 762000nm 635000nm 762000nm 203200nm] +) +Symbol['B' 304800nm] +( + SymbolLine[0 1270000nm 508000nm 1270000nm 203200nm] + SymbolLine[508000nm 1270000nm 635000nm 1143000nm 203200nm] + SymbolLine[635000nm 838200nm 635000nm 1143000nm 203200nm] + SymbolLine[508000nm 711200nm 635000nm 838200nm 203200nm] + SymbolLine[127000nm 711200nm 508000nm 711200nm 203200nm] + SymbolLine[127000nm 254000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 254000nm 508000nm 254000nm 203200nm] + SymbolLine[508000nm 254000nm 635000nm 381000nm 203200nm] + SymbolLine[635000nm 381000nm 635000nm 584200nm 203200nm] + SymbolLine[508000nm 711200nm 635000nm 584200nm 203200nm] +) +Symbol['C' 304800nm] +( + SymbolLine[177800nm 1270000nm 508000nm 1270000nm 203200nm] + SymbolLine[0 1092200nm 177800nm 1270000nm 203200nm] + SymbolLine[0 431800nm 0 1092200nm 203200nm] + SymbolLine[0 431800nm 177800nm 254000nm 203200nm] + SymbolLine[177800nm 254000nm 508000nm 254000nm 203200nm] +) +Symbol['D' 304800nm] +( + SymbolLine[127000nm 254000nm 127000nm 1270000nm 203200nm] + SymbolLine[457200nm 254000nm 635000nm 431800nm 203200nm] + SymbolLine[635000nm 431800nm 635000nm 1092200nm 203200nm] + SymbolLine[457200nm 1270000nm 635000nm 1092200nm 203200nm] + SymbolLine[0 1270000nm 457200nm 1270000nm 203200nm] + SymbolLine[0 254000nm 457200nm 254000nm 203200nm] +) +Symbol['E' 304800nm] +( + SymbolLine[0 711200nm 381000nm 711200nm 203200nm] + SymbolLine[0 1270000nm 508000nm 1270000nm 203200nm] + SymbolLine[0 254000nm 0 1270000nm 203200nm] + SymbolLine[0 254000nm 508000nm 254000nm 203200nm] +) +Symbol['F' 304800nm] +( + SymbolLine[0 254000nm 0 1270000nm 203200nm] + SymbolLine[0 254000nm 508000nm 254000nm 203200nm] + SymbolLine[0 711200nm 381000nm 711200nm 203200nm] +) +Symbol['G' 304800nm] +( + SymbolLine[508000nm 254000nm 635000nm 381000nm 203200nm] + SymbolLine[127000nm 254000nm 508000nm 254000nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[0 381000nm 0 1143000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 1270000nm 508000nm 1270000nm 203200nm] + SymbolLine[508000nm 1270000nm 635000nm 1143000nm 203200nm] + SymbolLine[635000nm 889000nm 635000nm 1143000nm 203200nm] + SymbolLine[508000nm 762000nm 635000nm 889000nm 203200nm] + SymbolLine[254000nm 762000nm 508000nm 762000nm 203200nm] +) +Symbol['H' 304800nm] +( + SymbolLine[0 254000nm 0 1270000nm 203200nm] + SymbolLine[635000nm 254000nm 635000nm 1270000nm 203200nm] + SymbolLine[0 762000nm 635000nm 762000nm 203200nm] +) +Symbol['I' 304800nm] +( + SymbolLine[0 254000nm 254000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 1270000nm 254000nm 1270000nm 203200nm] +) +Symbol['J' 304800nm] +( + SymbolLine[177800nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[381000nm 254000nm 381000nm 1143000nm 203200nm] + SymbolLine[254000nm 1270000nm 381000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 254000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 0 1016000nm 203200nm] +) +Symbol['K' 304800nm] +( + SymbolLine[0 254000nm 0 1270000nm 203200nm] + SymbolLine[0 762000nm 508000nm 254000nm 203200nm] + SymbolLine[0 762000nm 508000nm 1270000nm 203200nm] +) +Symbol['L' 304800nm] +( + SymbolLine[0 254000nm 0 1270000nm 203200nm] + SymbolLine[0 1270000nm 508000nm 1270000nm 203200nm] +) +Symbol['M' 304800nm] +( + SymbolLine[0 254000nm 0 1270000nm 203200nm] + SymbolLine[0 254000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 762000nm 254000nm 203200nm] + SymbolLine[762000nm 254000nm 762000nm 1270000nm 203200nm] +) +Symbol['N' 304800nm] +( + SymbolLine[0 254000nm 0 1270000nm 203200nm] + SymbolLine[0 254000nm 635000nm 1270000nm 203200nm] + SymbolLine[635000nm 254000nm 635000nm 1270000nm 203200nm] +) +Symbol['O' 304800nm] +( + SymbolLine[0 381000nm 0 1143000nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[381000nm 254000nm 508000nm 381000nm 203200nm] + SymbolLine[508000nm 381000nm 508000nm 1143000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] +) +Symbol['P' 304800nm] +( + SymbolLine[127000nm 254000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 254000nm 508000nm 254000nm 203200nm] + SymbolLine[508000nm 254000nm 635000nm 381000nm 203200nm] + SymbolLine[635000nm 381000nm 635000nm 635000nm 203200nm] + SymbolLine[508000nm 762000nm 635000nm 635000nm 203200nm] + SymbolLine[127000nm 762000nm 508000nm 762000nm 203200nm] +) +Symbol['Q' 304800nm] +( + SymbolLine[0 381000nm 0 1143000nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[381000nm 254000nm 508000nm 381000nm 203200nm] + SymbolLine[508000nm 381000nm 508000nm 1016000nm 203200nm] + SymbolLine[254000nm 1270000nm 508000nm 1016000nm 203200nm] + SymbolLine[127000nm 1270000nm 254000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[254000nm 889000nm 508000nm 1270000nm 203200nm] +) +Symbol['R' 304800nm] +( + SymbolLine[0 254000nm 508000nm 254000nm 203200nm] + SymbolLine[508000nm 254000nm 635000nm 381000nm 203200nm] + SymbolLine[635000nm 381000nm 635000nm 635000nm 203200nm] + SymbolLine[508000nm 762000nm 635000nm 635000nm 203200nm] + SymbolLine[127000nm 762000nm 508000nm 762000nm 203200nm] + SymbolLine[127000nm 254000nm 127000nm 1270000nm 203200nm] + SymbolLine[330200nm 762000nm 635000nm 1270000nm 203200nm] +) +Symbol['S' 304800nm] +( + SymbolLine[508000nm 254000nm 635000nm 381000nm 203200nm] + SymbolLine[127000nm 254000nm 508000nm 254000nm 203200nm] + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[0 381000nm 0 635000nm 203200nm] + SymbolLine[0 635000nm 127000nm 762000nm 203200nm] + SymbolLine[127000nm 762000nm 508000nm 762000nm 203200nm] + SymbolLine[508000nm 762000nm 635000nm 889000nm 203200nm] + SymbolLine[635000nm 889000nm 635000nm 1143000nm 203200nm] + SymbolLine[508000nm 1270000nm 635000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 508000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] +) +Symbol['T' 304800nm] +( + SymbolLine[0 254000nm 508000nm 254000nm 203200nm] + SymbolLine[254000nm 254000nm 254000nm 1270000nm 203200nm] +) +Symbol['U' 304800nm] +( + SymbolLine[0 254000nm 0 1143000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[508000nm 254000nm 508000nm 1143000nm 203200nm] +) +Symbol['V' 304800nm] +( + SymbolLine[0 254000nm 254000nm 1270000nm 203200nm] + SymbolLine[254000nm 1270000nm 508000nm 254000nm 203200nm] +) +Symbol['W' 304800nm] +( + SymbolLine[0 254000nm 0 762000nm 203200nm] + SymbolLine[0 762000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 635000nm 1270000nm 203200nm] + SymbolLine[635000nm 1270000nm 762000nm 762000nm 203200nm] + SymbolLine[762000nm 762000nm 762000nm 254000nm 203200nm] +) +Symbol['X' 304800nm] +( + SymbolLine[0 1270000nm 635000nm 254000nm 203200nm] + SymbolLine[0 254000nm 635000nm 1270000nm 203200nm] +) +Symbol['Y' 304800nm] +( + SymbolLine[0 254000nm 254000nm 762000nm 203200nm] + SymbolLine[254000nm 762000nm 508000nm 254000nm 203200nm] + SymbolLine[254000nm 762000nm 254000nm 1270000nm 203200nm] +) +Symbol['Z' 304800nm] +( + SymbolLine[0 254000nm 635000nm 254000nm 203200nm] + SymbolLine[0 1270000nm 635000nm 254000nm 203200nm] + SymbolLine[0 1270000nm 635000nm 1270000nm 203200nm] +) +Symbol['[' 304800nm] +( + SymbolLine[0 254000nm 127000nm 254000nm 203200nm] + SymbolLine[0 254000nm 0 1270000nm 203200nm] + SymbolLine[0 1270000nm 127000nm 1270000nm 203200nm] +) +Symbol['\' 304800nm] +( + SymbolLine[0 381000nm 762000nm 1143000nm 203200nm] +) +Symbol[']' 304800nm] +( + SymbolLine[0 254000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 1270000nm 127000nm 1270000nm 203200nm] +) +Symbol['^' 304800nm] +( + SymbolLine[0 381000nm 127000nm 254000nm 203200nm] + SymbolLine[127000nm 254000nm 254000nm 381000nm 203200nm] +) +Symbol['_' 304800nm] +( + SymbolLine[0 1270000nm 508000nm 1270000nm 203200nm] +) +Symbol['a' 304800nm] +( + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[127000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] + SymbolLine[0 889000nm 0 1143000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[508000nm 762000nm 508000nm 1143000nm 203200nm] + SymbolLine[508000nm 1143000nm 635000nm 1270000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] +) +Symbol['b' 304800nm] +( + SymbolLine[0 254000nm 0 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[508000nm 889000nm 508000nm 1143000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[127000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] +) +Symbol['c' 304800nm] +( + SymbolLine[127000nm 762000nm 508000nm 762000nm 203200nm] + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] + SymbolLine[0 889000nm 0 1143000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 1270000nm 508000nm 1270000nm 203200nm] +) +Symbol['d' 304800nm] +( + SymbolLine[508000nm 254000nm 508000nm 1270000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 889000nm 0 1143000nm 203200nm] + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] + SymbolLine[127000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] +) +Symbol['e' 304800nm] +( + SymbolLine[127000nm 1270000nm 508000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[0 889000nm 0 1143000nm 203200nm] + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] + SymbolLine[127000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[0 1016000nm 508000nm 1016000nm 203200nm] + SymbolLine[508000nm 1016000nm 508000nm 889000nm 203200nm] +) +Symbol['f' 254000nm] +( + SymbolLine[127000nm 381000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 381000nm 254000nm 254000nm 203200nm] + SymbolLine[254000nm 254000nm 381000nm 254000nm 203200nm] + SymbolLine[0 762000nm 254000nm 762000nm 203200nm] +) +Symbol['g' 304800nm] +( + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[127000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] + SymbolLine[0 889000nm 0 1143000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[0 1524000nm 127000nm 1651000nm 203200nm] + SymbolLine[127000nm 1651000nm 381000nm 1651000nm 203200nm] + SymbolLine[381000nm 1651000nm 508000nm 1524000nm 203200nm] + SymbolLine[508000nm 762000nm 508000nm 1524000nm 203200nm] +) +Symbol['h' 304800nm] +( + SymbolLine[0 254000nm 0 1270000nm 203200nm] + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] + SymbolLine[127000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[508000nm 889000nm 508000nm 1270000nm 203200nm] +) +Symbol['i' 254000nm] +( + SymbolLine[0 508000nm 0 533400nm 254000nm] + SymbolLine[0 889000nm 0 1270000nm 203200nm] +) +Symbol['j' 254000nm] +( + SymbolLine[127000nm 508000nm 127000nm 533400nm 254000nm] + SymbolLine[127000nm 889000nm 127000nm 1524000nm 203200nm] + SymbolLine[0 1651000nm 127000nm 1524000nm 203200nm] +) +Symbol['k' 304800nm] +( + SymbolLine[0 254000nm 0 1270000nm 203200nm] + SymbolLine[0 889000nm 381000nm 1270000nm 203200nm] + SymbolLine[0 889000nm 254000nm 635000nm 203200nm] +) +Symbol['l' 254000nm] +( + SymbolLine[0 254000nm 0 1143000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] +) +Symbol['m' 304800nm] +( + SymbolLine[127000nm 889000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 889000nm 254000nm 762000nm 203200nm] + SymbolLine[254000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[508000nm 889000nm 508000nm 1270000nm 203200nm] + SymbolLine[508000nm 889000nm 635000nm 762000nm 203200nm] + SymbolLine[635000nm 762000nm 762000nm 762000nm 203200nm] + SymbolLine[762000nm 762000nm 889000nm 889000nm 203200nm] + SymbolLine[889000nm 889000nm 889000nm 1270000nm 203200nm] + SymbolLine[0 762000nm 127000nm 889000nm 203200nm] +) +Symbol['n' 304800nm] +( + SymbolLine[127000nm 889000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 889000nm 254000nm 762000nm 203200nm] + SymbolLine[254000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[508000nm 889000nm 508000nm 1270000nm 203200nm] + SymbolLine[0 762000nm 127000nm 889000nm 203200nm] +) +Symbol['o' 304800nm] +( + SymbolLine[0 889000nm 0 1143000nm 203200nm] + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] + SymbolLine[127000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[508000nm 889000nm 508000nm 1143000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] +) +Symbol['p' 304800nm] +( + SymbolLine[127000nm 889000nm 127000nm 1651000nm 203200nm] + SymbolLine[0 762000nm 127000nm 889000nm 203200nm] + SymbolLine[127000nm 889000nm 254000nm 762000nm 203200nm] + SymbolLine[254000nm 762000nm 508000nm 762000nm 203200nm] + SymbolLine[508000nm 762000nm 635000nm 889000nm 203200nm] + SymbolLine[635000nm 889000nm 635000nm 1143000nm 203200nm] + SymbolLine[508000nm 1270000nm 635000nm 1143000nm 203200nm] + SymbolLine[254000nm 1270000nm 508000nm 1270000nm 203200nm] + SymbolLine[127000nm 1143000nm 254000nm 1270000nm 203200nm] +) +Symbol['q' 304800nm] +( + SymbolLine[508000nm 889000nm 508000nm 1651000nm 203200nm] + SymbolLine[381000nm 762000nm 508000nm 889000nm 203200nm] + SymbolLine[127000nm 762000nm 381000nm 762000nm 203200nm] + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] + SymbolLine[0 889000nm 0 1143000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] +) +Symbol['r' 304800nm] +( + SymbolLine[127000nm 889000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 889000nm 254000nm 762000nm 203200nm] + SymbolLine[254000nm 762000nm 508000nm 762000nm 203200nm] + SymbolLine[0 762000nm 127000nm 889000nm 203200nm] +) +Symbol['s' 304800nm] +( + SymbolLine[127000nm 1270000nm 508000nm 1270000nm 203200nm] + SymbolLine[508000nm 1270000nm 635000nm 1143000nm 203200nm] + SymbolLine[508000nm 1016000nm 635000nm 1143000nm 203200nm] + SymbolLine[127000nm 1016000nm 508000nm 1016000nm 203200nm] + SymbolLine[0 889000nm 127000nm 1016000nm 203200nm] + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] + SymbolLine[127000nm 762000nm 508000nm 762000nm 203200nm] + SymbolLine[508000nm 762000nm 635000nm 889000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] +) +Symbol['t' 254000nm] +( + SymbolLine[127000nm 254000nm 127000nm 1143000nm 203200nm] + SymbolLine[127000nm 1143000nm 254000nm 1270000nm 203200nm] + SymbolLine[0 635000nm 254000nm 635000nm 203200nm] +) +Symbol['u' 304800nm] +( + SymbolLine[0 762000nm 0 1143000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] + SymbolLine[508000nm 762000nm 508000nm 1143000nm 203200nm] +) +Symbol['v' 304800nm] +( + SymbolLine[0 762000nm 254000nm 1270000nm 203200nm] + SymbolLine[508000nm 762000nm 254000nm 1270000nm 203200nm] +) +Symbol['w' 304800nm] +( + SymbolLine[0 762000nm 0 1143000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[127000nm 1270000nm 254000nm 1270000nm 203200nm] + SymbolLine[254000nm 1270000nm 381000nm 1143000nm 203200nm] + SymbolLine[381000nm 762000nm 381000nm 1143000nm 203200nm] + SymbolLine[381000nm 1143000nm 508000nm 1270000nm 203200nm] + SymbolLine[508000nm 1270000nm 635000nm 1270000nm 203200nm] + SymbolLine[635000nm 1270000nm 762000nm 1143000nm 203200nm] + SymbolLine[762000nm 762000nm 762000nm 1143000nm 203200nm] +) +Symbol['x' 304800nm] +( + SymbolLine[0 762000nm 508000nm 1270000nm 203200nm] + SymbolLine[0 1270000nm 508000nm 762000nm 203200nm] +) +Symbol['y' 304800nm] +( + SymbolLine[0 762000nm 0 1143000nm 203200nm] + SymbolLine[0 1143000nm 127000nm 1270000nm 203200nm] + SymbolLine[508000nm 762000nm 508000nm 1524000nm 203200nm] + SymbolLine[381000nm 1651000nm 508000nm 1524000nm 203200nm] + SymbolLine[127000nm 1651000nm 381000nm 1651000nm 203200nm] + SymbolLine[0 1524000nm 127000nm 1651000nm 203200nm] + SymbolLine[127000nm 1270000nm 381000nm 1270000nm 203200nm] + SymbolLine[381000nm 1270000nm 508000nm 1143000nm 203200nm] +) +Symbol['z' 304800nm] +( + SymbolLine[0 762000nm 508000nm 762000nm 203200nm] + SymbolLine[0 1270000nm 508000nm 762000nm 203200nm] + SymbolLine[0 1270000nm 508000nm 1270000nm 203200nm] +) +Symbol['{' 304800nm] +( + SymbolLine[127000nm 381000nm 254000nm 254000nm 203200nm] + SymbolLine[127000nm 381000nm 127000nm 635000nm 203200nm] + SymbolLine[0 762000nm 127000nm 635000nm 203200nm] + SymbolLine[0 762000nm 127000nm 889000nm 203200nm] + SymbolLine[127000nm 889000nm 127000nm 1143000nm 203200nm] + SymbolLine[127000nm 1143000nm 254000nm 1270000nm 203200nm] +) +Symbol['|' 304800nm] +( + SymbolLine[0 254000nm 0 1270000nm 203200nm] +) +Symbol['}' 304800nm] +( + SymbolLine[0 254000nm 127000nm 381000nm 203200nm] + SymbolLine[127000nm 381000nm 127000nm 635000nm 203200nm] + SymbolLine[127000nm 635000nm 254000nm 762000nm 203200nm] + SymbolLine[127000nm 889000nm 254000nm 762000nm 203200nm] + SymbolLine[127000nm 889000nm 127000nm 1143000nm 203200nm] + SymbolLine[0 1270000nm 127000nm 1143000nm 203200nm] +) +Symbol['~' 304800nm] +( + SymbolLine[0 889000nm 127000nm 762000nm 203200nm] + SymbolLine[127000nm 762000nm 254000nm 762000nm 203200nm] + SymbolLine[254000nm 762000nm 381000nm 889000nm 203200nm] + SymbolLine[381000nm 889000nm 508000nm 889000nm 203200nm] + SymbolLine[508000nm 889000nm 635000nm 762000nm 203200nm] +) +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") +Via[2540000nm 2540000nm 1999995nm 1016000nm 0 800100nm "" "thermal(4,5X)"] +Layer(1 "comp1") +( +) +Layer(2 "solder1") +( +) +Layer(3 "com2") +( +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( + Polygon("clearpoly") + ( + [635000nm 635000nm] [3175000nm 635000nm] [3175000nm 3175000nm] [635000nm 3175000nm] + ) +) +Layer(6 "inner2") +( + Polygon("clearpoly") + ( + [1905000nm 1905000nm] [4445000nm 1905000nm] [4445000nm 4445000nm] [1905000nm 4445000nm] + ) +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/thermal_layer.pcb =================================================================== --- tags/2.3.0/tests/RTT/thermal_layer.pcb (nonexistent) +++ tags/2.3.0/tests/RTT/thermal_layer.pcb (revision 33253) @@ -0,0 +1,81 @@ +# release: pcb-rnd 1.1.1 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["thermals vs. multiple layer polygons" 12700000nm 12700000nm] + +Grid[635000nm 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[304800nm 228600nm 254000nm 177800nm 381000nm 254000nm] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,c:2,4,s:5:6:7") +Styles["style1,254000nm,1999995nm,800100nm,508000nm:style2,508000nm,2199894nm,999997nm,508000nm:style3,2032000nm,3500119nm,1199895nm,635000nm:style4,2540000nm,1625600nm,800100nm,2540000nm"] + +Attribute("PCB::grid::unit" "mil") +Attribute("PCB::conf::editor/draw_grid" "true") +Via[2540000nm 2540000nm 1999995nm 1016000nm 0 800100nm "" "thermal(0X,1)"] +Via[6985000nm 2540000nm 1999995nm 1016000nm 0 800100nm "" "thermal(0X,2)"] +Via[2540000nm 6985000nm 1999995nm 1016000nm 0 800100nm "" "thermal(1S)"] +Via[6985000nm 6985000nm 1999995nm 1016000nm 0 800100nm "" "thermal(2S)"] +Layer(1 "comp1") +( + Polygon("clearpoly") + ( + [635000nm 635000nm] [3175000nm 635000nm] [3175000nm 3175000nm] [635000nm 3175000nm] + ) + Polygon("clearpoly") + ( + [5080000nm 635000nm] [7620000nm 635000nm] [7620000nm 3175000nm] [5080000nm 3175000nm] + ) + Polygon("clearpoly") + ( + [635000nm 5080000nm] [3175000nm 5080000nm] [3175000nm 7620000nm] [635000nm 7620000nm] + ) + Polygon("clearpoly") + ( + [5080000nm 5080000nm] [7620000nm 5080000nm] [7620000nm 7620000nm] [5080000nm 7620000nm] + ) +) +Layer(2 "solder1") +( + Polygon("clearpoly") + ( + [1905000nm 1905000nm] [4445000nm 1905000nm] [4445000nm 4445000nm] [1905000nm 4445000nm] + ) + Polygon("clearpoly") + ( + [1905000nm 6350000nm] [4445000nm 6350000nm] [4445000nm 8890000nm] [1905000nm 8890000nm] + ) +) +Layer(3 "com2") +( + Polygon("clearpoly") + ( + [6350000nm 1905000nm] [8890000nm 1905000nm] [8890000nm 4445000nm] [6350000nm 4445000nm] + ) + Polygon("clearpoly") + ( + [6350000nm 6350000nm] [8890000nm 6350000nm] [8890000nm 8890000nm] [6350000nm 8890000nm] + ) +) +Layer(4 "solder2") +( +) +Layer(5 "inner1") +( +) +Layer(6 "inner2") +( +) +Layer(7 "outline") +( +) +Layer(8 "silk") +( +) +Layer(9 "silk") +( +) Index: tags/2.3.0/tests/RTT/valid_info/Proto.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/Proto.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/Proto.pcb.text (revision 33253) @@ -0,0 +1,5 @@ +6731 + +500 x 500 mils outline +inside the outline 490 x 490 mils +no other content Index: tags/2.3.0/tests/RTT/valid_info/README =================================================================== --- tags/2.3.0/tests/RTT/valid_info/README (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/README (revision 33253) @@ -0,0 +1,4 @@ +This directory contains information that may help manual validation of +the sample files. + +*.text -> specific distances measured on screen in pcb-rnd Index: tags/2.3.0/tests/RTT/valid_info/arc_angles.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/arc_angles.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/arc_angles.pcb.text (revision 33253) @@ -0,0 +1,19 @@ + +right circle +110mils h +110mils v +~10mils thick + +left circle +110 mils h +110 mils v (measurement problem) +~10mils thick + +central dot +~10mils + +air gap between right circle and central dot +90mils + +air gap between left circle and central dot +90mils Index: tags/2.3.0/tests/RTT/valid_info/arc_f_clear.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/arc_f_clear.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/arc_f_clear.pcb.text (revision 33253) @@ -0,0 +1,22 @@ +polygone +width 450mils +height 325mils + +small near circle completely in polygon +line width 10mils +width 60mils +clearance on the left ~20mils +clearance on the right ~20.05mils +clearance on the top ~20.05mils +clearance on the bottom 20.05mils + +longer arc completely in polygon +line width ~135mils +width 135mils +height +clearance on the bottom right end ~20.2mils +clearance on the top right end +clearance on the end right end +clearance on the right top end ~20.05mils +clearance on the left top end 20mils + Index: tags/2.3.0/tests/RTT/valid_info/arc_normal.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/arc_normal.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/arc_normal.pcb.text (revision 33253) @@ -0,0 +1,25 @@ +outline 500 x 500 mils + +upper left arc +102.60 mils tall +118.50 mils wide +20 mil thickness + +upper right arc +190.20 mils wide +112.20 mils tall +30mils thick + +lower left arc +135 mils tall +135 mils wide +10mils thick + +lower right arc (near circle) +10mils thick +about 60mils tall +about 60mils wide (duh) + + + + Index: tags/2.3.0/tests/RTT/valid_info/arc_offpage.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/arc_offpage.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/arc_offpage.pcb.text (revision 33253) @@ -0,0 +1,5 @@ +arc +10mil line width +155mil tall +155mil pixels wide + Index: tags/2.3.0/tests/RTT/valid_info/arc_sizes.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/arc_sizes.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/arc_sizes.pcb.text (revision 33253) @@ -0,0 +1,17 @@ + +weird dot thing in the far right +10mil across +10mil tall + +weird dot to line (horizontal) 108 pixels + +horizontal line +60mil long +10mil wide + +vertical line +10mil long +60mil wide + + + Index: tags/2.3.0/tests/RTT/valid_info/coord_rounding.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/coord_rounding.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/coord_rounding.pcb.text (revision 33253) @@ -0,0 +1,6 @@ + +weird dot thing +39.8 mil tall +43.75 mil wide + + Index: tags/2.3.0/tests/RTT/valid_info/elem_pads.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/elem_pads.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/elem_pads.pcb.text (revision 33253) @@ -0,0 +1,9 @@ +R1 pads +51.20 x 74.80 mils (approximately) + +U1 pads +15 x 35 mils +pad 5 upper to nearest silk screen corner 1.5 x 1.5 mils +pad 5 distance to pad 4 is 11 mils + + Index: tags/2.3.0/tests/RTT/valid_info/elem_pads_ds.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/elem_pads_ds.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/elem_pads_ds.pcb.text (revision 33253) @@ -0,0 +1,10 @@ +E1 +2 pads 1 silk line + text (E1) + +silk line 110 mils long 10 mils wide + +copper pads 85 mils long 10 mils wide + +pad 1 shares it's terminus with the silk line + +pad 2's highest point is 95 x 15 mils over from the inside corner of pad 1 & the silk line Index: tags/2.3.0/tests/RTT/valid_info/elem_pins.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/elem_pins.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/elem_pins.pcb.text (revision 33253) @@ -0,0 +1,11 @@ +U1 +5 x 5 mils distance from silk inside top corner to pin 1 +pin 1 dimensions 80 x 80 mils +pin 2 80 mil circle +pin 1 to pin 2 distance 220 mils + +U2 +pin 1 extremes 80 mils tall 120 mils wide +pin 2 extremes 120 mills tall 160 mils wide +pin 1 to pin 2 distance 140 mils +pin 1 to pin 2 vertical offset 0 mils Index: tags/2.3.0/tests/RTT/valid_info/elem_sides_smd.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/elem_sides_smd.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/elem_sides_smd.pcb.text (revision 33253) @@ -0,0 +1,7 @@ +R1 +pad1 51.20 mils x 74.80 mils approximately +pad2 51.20 mils x 74.80 mils approximately + +R2 - on the bottom +pad1 51.20 mils x 74.80 mils approximately +pad2 51.20 mils x 74.80 mils approximately Index: tags/2.3.0/tests/RTT/valid_info/elem_sides_trh.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/elem_sides_trh.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/elem_sides_trh.pcb.text (revision 33253) @@ -0,0 +1,14 @@ +r6630 + +U1 +5 x 5 mils distance from silk inside top corner to pin 1 +pin 1 dimensions 80 x 80 mils +pin 2 80 mil circle +pin 1 to pin 2 distance 220 mils + +U2 +pin 1 is 120 mils down from U1 Pin 1 +pin 1 is 80 x 80 mils +pin 2 is an 80 mil circle +pin 1 to pin 2 distance 220 mils + Index: tags/2.3.0/tests/RTT/valid_info/layer_copper.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/layer_copper.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/layer_copper.pcb.text (revision 33253) @@ -0,0 +1,7 @@ +3 lines each on a different layer + +highest point on red to highest point on green +50 x 75 + +highest point on red to "nose" (left side) of blue +20 x 5 Index: tags/2.3.0/tests/RTT/valid_info/layer_outline.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/layer_outline.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/layer_outline.pcb.text (revision 33253) @@ -0,0 +1,4 @@ +board outline +right triangle +300 mils tall +300 mils wide Index: tags/2.3.0/tests/RTT/valid_info/layer_silk.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/layer_silk.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/layer_silk.pcb.text (revision 33253) @@ -0,0 +1,5 @@ + +line +width 10mils +length 385 mils + Index: tags/2.3.0/tests/RTT/valid_info/layer_spc.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/layer_spc.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/layer_spc.pcb.text (revision 33253) @@ -0,0 +1,2 @@ + +This is blank. It should be 500 mils by 500 mils Index: tags/2.3.0/tests/RTT/valid_info/line_f_clear.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/line_f_clear.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/line_f_clear.pcb.text (revision 33253) @@ -0,0 +1,20 @@ +rectangle +width +height + +veritcal line +width 10mils +length 260mils +clearance 42/42 mils (left/right) + +horizontal line +width ~15mils +length 290mils +clearance 12/12 mils (top/bottom) + +left diangonal line +45 degrees + +right diagonal line +? degrees + Index: tags/2.3.0/tests/RTT/valid_info/line_normal.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/line_normal.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/line_normal.pcb.text (revision 33253) @@ -0,0 +1,13 @@ +horizontal line +290 mils +15 mil thickness + +vertical line +260 mils +10 mil thickness + +fine diagonal line +5 mils + +thick diagonal line +20 mils Index: tags/2.3.0/tests/RTT/valid_info/line_offpage.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/line_offpage.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/line_offpage.pcb.text (revision 33253) @@ -0,0 +1,3 @@ +10 mil line +405 mils on the page (more off) + Index: tags/2.3.0/tests/RTT/valid_info/line_overlap1.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/line_overlap1.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/line_overlap1.pcb.text (revision 33253) @@ -0,0 +1,4 @@ +15 mil width +115 mil length + +(it is actually 2 traces that should export as 1) Index: tags/2.3.0/tests/RTT/valid_info/line_overlap2.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/line_overlap2.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/line_overlap2.pcb.text (revision 33253) @@ -0,0 +1,4 @@ +15 mil width +165 mil length + +(it is actually 3 traces that should export as 1) Index: tags/2.3.0/tests/RTT/valid_info/line_overlap3.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/line_overlap3.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/line_overlap3.pcb.text (revision 33253) @@ -0,0 +1,3 @@ +15 mil width +165 mil length + Index: tags/2.3.0/tests/RTT/valid_info/line_overlap4.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/line_overlap4.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/line_overlap4.pcb.text (revision 33253) @@ -0,0 +1,6 @@ +15 mil width +165 mil length +15 mil clearance + +in a poly +150 x 175 mils Index: tags/2.3.0/tests/RTT/valid_info/line_zerolen.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/line_zerolen.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/line_zerolen.pcb.text (revision 33253) @@ -0,0 +1 @@ +15 mil diameter point made of a trace with zero length Index: tags/2.3.0/tests/RTT/valid_info/netlist.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/netlist.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/netlist.pcb.text (revision 33253) @@ -0,0 +1,8 @@ +U1 +Inside silk screen corner to Pin1 top corner 5 x 5 milsooo +Pin1 80 x 80 mils +Pin1 hole 39.40 mils in diameter +Pin2 to Pin1 distance 20 mils +Pin2 80 mil circle +Pin2 to Pin3 distance 220 mils +Pin2 hole 39.40 mils in diameter Index: tags/2.3.0/tests/RTT/valid_info/netlist_ba.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/netlist_ba.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/netlist_ba.pcb.text (revision 33253) @@ -0,0 +1,8 @@ +U1 +Inside silk screen corner to Pin1 top corner 5 x 5 milsooo +Pin1 80 x 80 mils +Pin1 hole 39.40 mils in diameter +Pin2 to Pin1 distance 20 mils +Pin2 80 mil circle +Pin2 to Pin3 distance 220 mils +Pin2 hole 39.40 mils in diameter Index: tags/2.3.0/tests/RTT/valid_info/poly_hole.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/poly_hole.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/poly_hole.pcb.text (revision 33253) @@ -0,0 +1,20 @@ +r6630 + +500 x 500 mil outline + +upper left triangle +Top left corner to top left cutout corner 25 mils down 25 mils over +cutout 25 mils wide +cutout 25 mils high + +upper right triangle +bottom right corner to bottom right on cutout 25 x 25 mils +cutout 50mils wide +cutout 25 mils high + +far right piramid +cutout 50mils x 50mils +cutout located 50mils down from the apex + + + Index: tags/2.3.0/tests/RTT/valid_info/poly_rect.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/poly_rect.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/poly_rect.pcb.text (revision 33253) @@ -0,0 +1,17 @@ + +outline 500 x 500 mils + +vertical polygon +25 x 425 mils + +horizontal polygon +350 x 25 mils + +giant middle polygon +275 x 375 mils + +smallest polygon (bottom right) +25 x 25 mils + + + Index: tags/2.3.0/tests/RTT/valid_info/poly_triangle.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/poly_triangle.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/poly_triangle.pcb.text (revision 33253) @@ -0,0 +1,31 @@ + +upper left triangle +100 mils wide +100 mils tall + +gap from lower left triangle to upper left triangle +25 mils horizontally +25 mils vertically + +lower left triangle +125 mils wide +125 mils tall + +gap from lower left triangle to far right piramid +25 mils + +far right piramid +125 mils height +250 mils base + +bottom triangle +275 mils across +175 mils up +top edge +276.13 mils long __ degrees +side edge +176.78 mils long __ degrees +bottom edge +291.55 mils long __ degrees + + Index: tags/2.3.0/tests/RTT/valid_info/text_rot.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/text_rot.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/text_rot.pcb.text (revision 33253) @@ -0,0 +1,14 @@ +layout is 500mils by 500mils + +A's are all 7mils thick +1 7 mils thick +2 7 mils thick +3 7 mils thick +4 7 mils thick + +All text is spaced @ 5 mils + +113 mils from under A2 to under A4 +113 mils from under A1 to under A3 + + Index: tags/2.3.0/tests/RTT/valid_info/text_scale.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/text_scale.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/text_scale.pcb.text (revision 33253) @@ -0,0 +1,26 @@ +top text A1 +A line width 7 mils +A width 32 +A height 47 +1 line width 7 +1 width 22 +1 height 47 + +gap from A to 1 is 5 mils + +dot thing in the page + tall 11 + wide 13.2 + +bottom text A3 +A line width 12.8 +A width 92.8 +A height 140.8 +3 line width 12.8 +3 width 76.8 +3 height 140.8 +A to 3 is 25.6 + +all measurements in mils + + Index: tags/2.3.0/tests/RTT/valid_info/text_sides.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/text_sides.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/text_sides.pcb.text (revision 33253) @@ -0,0 +1,5 @@ +layout 500 x 500 mils + +38 mils between the bottom of A1 and bottom of A2 + +all text is 7 mils thick Index: tags/2.3.0/tests/RTT/valid_info/thermal_last.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/thermal_last.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/thermal_last.pcb.text (revision 33253) @@ -0,0 +1,8 @@ +500 x 500 mil outline + +100 mil x 100 mil for both polygons + +via copper width 78.74 mils +Via drill width 31.50 mils +annulus 23.62 mils +clearance 20 mils Index: tags/2.3.0/tests/RTT/valid_info/thermal_layer.pcb.text =================================================================== --- tags/2.3.0/tests/RTT/valid_info/thermal_layer.pcb.text (nonexistent) +++ tags/2.3.0/tests/RTT/valid_info/thermal_layer.pcb.text (revision 33253) @@ -0,0 +1,8 @@ +500 x 500 mil outline + +each red polygon is 100x100 mils +each blue polygon is 100x100 mils + +clearance should be exactly 20.00mils +copper width 78.74 mils +drill width 31.50 mils Index: tags/2.3.0/tests/action/padstack.lht =================================================================== --- tags/2.3.0/tests/action/padstack.lht (nonexistent) +++ tags/2.3.0/tests/action/padstack.lht (revision 33253) @@ -0,0 +1,440 @@ +ha:pcb-rnd-board-v4 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 2.0mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1.0mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 127.0mm + y = 127.0mm + isle_area_nm2 = 200000000.000000 + } + ha:cursor { + zoom = 1.000000 + x = 0.0 + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + ha:ps_proto_v4 { + htop = 0 + group = 1 + hdia = 31.5mil + li:shape { + ha:ps_shape_v4 { + clearance = 40.0mil + li:ps_poly { + 125.0mil + 125.0mil + -3175.0um + 125.0mil + 0.0 + -8890.0um + } + ha:layer_mask { + copper = 1 + top = 1 + } + ha:combining { + } + } + } + hbottom = 0 + hplated = 1 + } + } + + li:objects { + ha:padstack_ref.21 { + proto = 0 + li:thermal { + } + x = 400.0mil + y = 600.0mil + } + ha:padstack_ref.22 { + proto = 0 + li:thermal { + } + x = 800.0mil + y = 600.0mil + } + ha:padstack_ref.23 { + proto = 0 + li:thermal { + } + x = 30.48mm + y = 600.0mil + } + ha:padstack_ref.24 { + proto = 0 + li:thermal { + } + x = 1.6in + y = 600.0mil + } + ha:padstack_ref.25 { + proto = 0 + li:thermal { + } + x = 2.0in + y = 600.0mil + } + ha:padstack_ref.26 { + proto = 0 + li:thermal { + } + x = 60.96mm + y = 600.0mil + } + ha:padstack_ref.27 { + proto = 0 + li:thermal { + } + x = 2.8in + y = 600.0mil + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:line.28 { + x1=200.0mil; y1=375.0mil; x2=375.0mil; y2=375.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.31 { + x1=800.0mil; y1=225.0mil; x2=800.0mil; y2=225.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.40 { + x1=29.21mm; y1=425.0mil; x2=29.21mm; y2=425.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.43 { + x1=36.83mm; y1=250.0mil; x2=1.725in; y2=250.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.46 { + x1=47.625mm; y1=425.0mil; x2=51.435mm; y2=650.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.49 { + x1=175.0mil; y1=375.0mil; x2=175.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.52 { + x1=175.0mil; y1=75.0mil; x2=74.93mm; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.55 { + x1=800.0mil; y1=200.0mil; x2=800.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.58 { + x1=1.125in; y1=400.0mil; x2=1.125in; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.61 { + x1=37.465mm; y1=250.0mil; x2=37.465mm; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.64 { + x1=47.625mm; y1=425.0mil; x2=47.625mm; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.67 { + x1=56.515mm; y1=425.0mil; x2=2.55in; y2=425.0mil; thickness=80.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + ha:line.73 { + x1=2.25in; y1=425.0mil; x2=2.25in; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.76 { + x1=2.8in; y1=25.0mil; x2=2.8in; y2=1.125in; thickness=265.0mil; clearance=50.0mil; + ha:flags { + clearline=1 + } + } + } + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:bottom-gnd { + lid=3 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:int-sig2 { + lid=4 + group=7 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:int-sig1 { + lid=5 + group=5 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:outline { + lid=6 + group=9 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:bottom-silk { + lid=7 + group=12 + ha:combining { auto=1; } + visible=1 + + li:objects { + } + } + + ha:top-silk { + lid=8 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:text.79 { + string=line touching padstack; x=975.0mil; y=800.0mil; scale=175; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + } + + ha:top-paste { + lid=9 + group=0 + ha:combining { auto=1; } + visible=0 + + li:objects { + } + } + + ha:top-mask { + lid=10 + group=2 + ha:combining { sub=1; auto=1; } + visible=0 + + li:objects { + } + } + + ha:bottom-mask { + lid=11 + group=11 + ha:combining { sub=1; auto=1; } + visible=0 + + li:objects { + } + } + + ha:bottom-paste { + lid=12 + group=13 + ha:combining { auto=1; } + visible=0 + + li:objects { + } + } + } + } + + 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 { outline=1; intern=1; } + li:layers { 6; } + } + 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; } + } + } + } +} Index: tags/2.3.0/tests/action/padstack2.lht =================================================================== --- tags/2.3.0/tests/action/padstack2.lht (nonexistent) +++ tags/2.3.0/tests/action/padstack2.lht (revision 33253) @@ -0,0 +1,673 @@ +ha:pcb-rnd-board-v4 { + + ha:attributes { + {PCB::grid::unit}=mil + } + + li:styles { + ha:Signal { + diameter = 2.0mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1.0mm + clearance = 20.0mil + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 600.0mil + y = 600.0mil + isle_area_nm2 = 200000000.000000 + } + ha:cursor { + zoom = 1.000000 + x = 0.0 + y = 0.0 + } + ha:drc { + min_drill = 15.0mil + min_ring = 10.0mil + bloat = 12.0mil + shrink = 9.0mil + min_width = 10.0mil + min_silk = 7.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v4.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=0.0; y1=-952.5um; x2=0.0; y2=37.5mil; thickness=25.0mil; square=0; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + } + } + } + + ha:ps_proto_v4.1 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + li:ps_poly { + -0.001um + -952.501um + -635.001um + 0.952499mm + 0.634999mm + 0.952499mm + } + } + } + } + + ha:ps_proto_v4.2 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=35.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + } + } + } + } + + li:objects { + ha:padstack_ref.34 { + proto=0; x=75.0mil; y=100.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.44 { + proto=0; x=150.0mil; y=100.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.45 { + proto=0; x=225.0mil; y=100.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.47 { + proto=1; x=150.0mil; y=185.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.49 { + proto=0; x=75.0mil; y=199.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.51 { + proto=2; x=226.0mil; y=167.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.53 { + proto=1; x=325.0mil; y=100.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.54 { + proto=1; x=425.0mil; y=100.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.65 { + proto=1; x=328.0mil; y=174.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.67 { + proto=2; x=395.0mil; y=154.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.69 { + proto=2; x=509.0mil; y=84.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.70 { + proto=2; x=502.0mil; y=118.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.149 { + proto=0; x=75.0mil; y=375.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.150 { + proto=0; x=150.0mil; y=375.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.151 { + proto=0; x=225.0mil; y=375.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.153 { + proto=0; x=59.0mil; y=470.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.154 { + proto=2; x=202.0mil; y=433.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.155 { + proto=1; x=325.0mil; y=375.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.156 { + proto=1; x=425.0mil; y=375.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.157 { + proto=1; x=294.0mil; y=434.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.158 { + proto=2; x=392.0mil; y=378.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.159 { + proto=2; x=509.0mil; y=359.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.160 { + proto=2; x=481.0mil; y=381.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.162 { + proto=1; x=131.0mil; y=434.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + visible=1 + + li:objects { + ha:line.37 { + x1=25.0mil; y1=550.0mil; x2=25.0mil; y2=25.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.40 { + x1=25.0mil; y1=25.0mil; x2=525.0mil; y2=25.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.74 { + x1=75.0mil; y1=25.0mil; x2=75.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.77 { + x1=150.0mil; y1=25.0mil; x2=150.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.80 { + x1=225.0mil; y1=25.0mil; x2=225.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.86 { + x1=325.0mil; y1=25.0mil; x2=325.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.89 { + x1=425.0mil; y1=25.0mil; x2=425.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.92 { + x1=500.0mil; y1=25.0mil; x2=500.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.128 { + x1=25.0mil; y1=300.0mil; x2=525.0mil; y2=300.0mil; thickness=20.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.131 { + x1=75.0mil; y1=300.0mil; x2=75.0mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.134 { + x1=150.0mil; y1=300.0mil; x2=150.0mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.137 { + x1=225.0mil; y1=300.0mil; x2=225.0mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.140 { + x1=325.0mil; y1=300.0mil; x2=325.0mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.143 { + x1=425.0mil; y1=300.0mil; x2=425.0mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.146 { + x1=500.0mil; y1=300.0mil; x2=500.0mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:bottom-gnd { + lid=3 + group=10 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:int-sig2 { + lid=4 + group=7 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:int-sig1 { + lid=5 + group=5 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:outline { + lid=6 + group=9 + ha:combining { } + visible=1 + + li:objects { + } + } + + ha:bottom-silk { + lid=7 + group=12 + ha:combining { auto=1; } + visible=1 + + li:objects { + } + } + + ha:top-silk { + lid=8 + group=1 + ha:combining { auto=1; } + visible=1 + + li:objects { + ha:text.167 { + string=overlap; x=425.0mil; y=175.0mil; scale=45; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + ha:text.169 { + string=no overlap; x=375.0mil; y=425.0mil; scale=45; fid=0; direction=0; + ha:flags { + clearline=1 + } + } + } + } + + ha:top-paste { + lid=9 + group=0 + ha:combining { auto=1; } + visible=0 + + li:objects { + } + } + + ha:top-mask { + lid=10 + group=2 + ha:combining { sub=1; auto=1; } + visible=0 + + li:objects { + } + } + + ha:bottom-mask { + lid=11 + group=11 + ha:combining { sub=1; auto=1; } + visible=0 + + li:objects { + } + } + + ha:bottom-paste { + lid=12 + group=13 + ha:combining { auto=1; } + visible=0 + + li:objects { + } + } + } + } + + 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 { outline=1; intern=1; } + li:layers { 6; } + } + 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; } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 10.00 mil + clearance = 20.00 mil + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 7.00 mil + max_height = 600.00 mil + line_thickness = 10.00 mil + shrink = 9.00 mil + poly_isle_area = 200000000.000000 + max_width = 600.00 mil + min_wid = 10.00 mil + bloat = 12.00 mil + min_drill = 15.00 mil + } + ha:editor { + grid_unit = mil + all_direction_lines = false + buffer_number = 0 + grid = 25.00 mil + } + } + } +} Index: tags/2.3.0/tests/base64/Makefile =================================================================== --- tags/2.3.0/tests/base64/Makefile (nonexistent) +++ tags/2.3.0/tests/base64/Makefile (revision 33253) @@ -0,0 +1,8 @@ +ROOT=../.. +LIBRND=$(ROOT)/src/librnd/core + +CFLAGS = -Wall -g -I$(ROOT)/src + +main: main.o $(LIBRND)/base64.o + +main.o: main.c Index: tags/2.3.0/tests/base64/main.c =================================================================== --- tags/2.3.0/tests/base64/main.c (nonexistent) +++ tags/2.3.0/tests/base64/main.c (revision 33253) @@ -0,0 +1,58 @@ +#include +#include + +#include + +int verbose = 0; + +int encode(const char *str) +{ + size_t ilen, olen, len; + char bin[512]; + unsigned char plain[256]; + + memset(plain, '#', sizeof(plain)); + + ilen = strlen(str); + len = rnd_base64_bin2str(bin, sizeof(bin), (unsigned char *)str, ilen); + if (len >= 0) { + bin[len] = '\0'; + if (verbose) printf("'%s'/%ld -> '%s'/%ld\n", str, (long)ilen, bin, (long)len); + olen = rnd_base64_str2bin(plain, sizeof(plain), bin, len); + if (olen >= 0) { + plain[olen] = '\0'; + if (verbose) printf(" -> '%s'/%ld\n", plain, (long)olen); + } + } + + if ((strcmp((char *)plain, str) != 0) || (ilen != olen)) + return -1; + return 0; +} + +int main() +{ + int err = 0; + + err |= encode("Man"); + + +/* Example from wikipedia: +20 any carnal pleasure. 28 YW55IGNhcm5hbCBwbGVhc3VyZS4= 1 +19 any carnal pleasure 28 YW55IGNhcm5hbCBwbGVhc3VyZQ== 2 +18 any carnal pleasur 24 YW55IGNhcm5hbCBwbGVhc3Vy 0 +17 any carnal pleasu 24 YW55IGNhcm5hbCBwbGVhc3U= 1 +16 any carnal pleas 24 YW55IGNhcm5hbCBwbGVhcw== 2 +*/ + + err |= encode("any carnal pleasure."); + err |= encode("any carnal pleasure"); + err |= encode("any carnal pleasur"); + err |= encode("any carnal pleasu"); + err |= encode("any carnal pleas"); + + if (err != 0) + fprintf(stderr, "ERROR: base64 test failed\n"); + + return err; +} Index: tags/2.3.0/tests/cam/Makefile =================================================================== --- tags/2.3.0/tests/cam/Makefile (nonexistent) +++ tags/2.3.0/tests/cam/Makefile (revision 33253) @@ -0,0 +1,7 @@ +all: + +test: + ./test.sh test + +clean: + ./test.sh clean Index: tags/2.3.0/tests/cam/grp_name/.top_pate.svg =================================================================== --- tags/2.3.0/tests/cam/grp_name/.top_pate.svg (nonexistent) +++ tags/2.3.0/tests/cam/grp_name/.top_pate.svg (revision 33253) @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: tags/2.3.0/tests/cam/grp_name/cam.conf =================================================================== --- tags/2.3.0/tests/cam/grp_name/cam.conf (nonexistent) +++ tags/2.3.0/tests/cam/grp_name/cam.conf (revision 33253) @@ -0,0 +1,30 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:cam { + li:jobs { + test { + desc export all layer groups by name + plugin svg + write %base%.top_paste.svg=@top_paste + write %base%.top_silk.svg=@top_silk + write %base%.top_mask.svg=@top_mask + write %base%.top_copper.svg=@top_copper + write %base%.intern.svg=@Intern + write %base%.global_outline.svg=@global_outline + write %base%.bottom_copper.svg=@bottom_copper + write %base%.bottom_mask.svg=@bottom_mask + write %base%.bottom_silk.svg=@bottom_silk + write %base%.bottom_paste.svg=@bottom_paste + write %base%.pmech.svg=@pmech + write %base%.umech.svg=@umech + write %base%.top_assy.svg=@top_assy + write %base%.bot_assy.svg=@bot_assy +# too big: write %base%.fab.svg=@fab + write %base%.invis.svg=@invisible + } + } + } + } + } +} Index: tags/2.3.0/tests/cam/grp_name/ref.tar.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/cam/grp_name/ref.tar.gz =================================================================== --- tags/2.3.0/tests/cam/grp_name/ref.tar.gz (nonexistent) +++ tags/2.3.0/tests/cam/grp_name/ref.tar.gz (revision 33253) Property changes on: tags/2.3.0/tests/cam/grp_name/ref.tar.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/cam/layers.lht =================================================================== --- tags/2.3.0/tests/cam/layers.lht (nonexistent) +++ tags/2.3.0/tests/cam/layers.lht (revision 33253) @@ -0,0 +1,789 @@ +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 = 550.0mil + y = 2.25in + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.1 { + hdia=1.0mm; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.2mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.2mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.2mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.2 { + hdia=47.24mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=137.8mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=137.8mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=137.8mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.23 { + proto=0; x=100.0mil; y=49.53mm; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.24 { + proto=1; x=200.0mil; y=49.53mm; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.25 { + proto=2; x=400.0mil; y=49.53mm; rot=0.000000; xmirror=0; smirror=0; clearance=25.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:subc.51 { + ha:attributes { + footprint=1206 Standard SMT resistor, capacitor etc + refdes=R1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.726186mm + -1.02616mm + -0.726186mm + -1.02616mm + -0.726186mm + 1.02616mm + 0.726186mm + 1.02616mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.71 { + proto=0; x=3.58013mm; y=54.61mm; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.72 { + proto=0; x=259.05mil; y=54.61mm; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.52 { + x1=4.480052mm; y1=2.1126in; x2=223.62mil; y2=2.1126in; thickness=8.0mil; clearance=0.0; + } + ha:line.55 { + x1=4.480052mm; y1=2.1874in; x2=223.62mil; y2=2.1874in; thickness=8.0mil; clearance=0.0; + } + ha:text.58 { + string=%a.parent.refdes%; x=342.12mil; y=2.1311in; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.59 { + x1=200.0mil; y1=54.61mm; x2=200.0mil; y2=54.61mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.62 { + x1=200.0mil; y1=54.61mm; x2=200.0mil; y2=54.61mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.65 { + x1=200.0mil; y1=54.61mm; x2=6.08mm; y2=54.61mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.68 { + x1=200.0mil; y1=54.61mm; x2=200.0mil; y2=55.61mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = pjaLj8tSfYLVqy1mjLYAAAAB + } + ha:rat.85 { + x1=3.58013mm; y1=54.61mm; lgrp1=3; x2=259.05mil; y2=54.61mm; lgrp2=3; + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:text.10 { + string=topcop; x=100.0mil; y=350.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:text.13 { + string=botcop; x=100.0mil; y=750.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + onsolder=1 + } + rot = 0.000000 + } + } + color = {#3a5fcd} + } + + ha:int-sig2 { + lid=2 + group=7 + ha:combining { } + + li:objects { + ha:text.12 { + string=icop2; x=100.0mil; y=550.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#548b54} + } + + ha:int-sig1 { + lid=3 + group=5 + ha:combining { } + + li:objects { + ha:text.11 { + string=icop1; x=100.0mil; y=450.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#8b7355} + } + + ha:outline { + lid=4 + group=9 + ha:combining { } + + li:objects { + ha:text.17 { + string=bnd; x=100.0mil; y=29.21mm; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#00868b} + } + + ha:bottom-silk { + lid=5 + group=12 + ha:combining { auto=1; } + + li:objects { + ha:text.15 { + string=botslk; x=100.0mil; y=950.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + onsolder=1 + } + rot = 0.000000 + } + } + color = {#000000} + } + + ha:top-silk { + lid=6 + group=1 + ha:combining { auto=1; } + + li:objects { + ha:text.8 { + string=topslk; x=100.0mil; y=150.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#000000} + } + + ha:top-paste { + lid=7 + group=0 + ha:combining { auto=1; } + + li:objects { + ha:text.7 { + string=toppst; x=100.0mil; y=50.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#cd00cd} + } + + ha:top-mask { + lid=8 + group=2 + ha:combining { sub=1; auto=1; } + + li:objects { + ha:text.9 { + string=topmsk; x=100.0mil; y=250.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#ff0000} + } + + ha:bottom-mask { + lid=9 + group=11 + ha:combining { sub=1; auto=1; } + + li:objects { + ha:text.14 { + string=botmsk; x=100.0mil; y=850.0mil; scale=100; fid=0; + ha:flags { + clearline=1 + onsolder=1 + } + rot = 0.000000 + } + } + color = {#ff0000} + } + + ha:bottom-paste { + lid=10 + group=13 + ha:combining { auto=1; } + + li:objects { + ha:text.16 { + string=botpst; x=100.0mil; y=26.67mm; scale=100; fid=0; + ha:flags { + clearline=1 + onsolder=1 + } + rot = 0.000000 + } + } + color = {#cd00cd} + } + + ha:slot-plated { + lid=11 + group=14 + ha:combining { auto=1; } + + li:objects { + ha:text.18 { + string=pslt; x=100.0mil; y=31.75mm; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#8b7355} + } + + ha:slot-unplated { + lid=12 + group=15 + ha:combining { auto=1; } + + li:objects { + ha:text.19 { + string=uslt; x=100.0mil; y=1.35in; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#00868b} + } + + ha:top-assy { + lid=13 + group=16 + ha:combining { } + + li:objects { + ha:text.20 { + string=topasy; x=100.0mil; y=36.83mm; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#444444} + } + + ha:bot-assy { + lid=14 + group=17 + ha:combining { } + + li:objects { + ha:text.21 { + string=botasy; x=100.0mil; y=1.65in; scale=100; fid=0; + ha:flags { + clearline=1 + onsolder=1 + } + rot = 0.000000 + } + } + color = {#444444} + } + + ha:fab { + lid=15 + group=18 + ha:combining { auto=1; } + + li:objects { + ha:text.22 { + string=fab; x=100.0mil; y=44.45mm; scale=100; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + } + color = {#222222} + } + } + } + + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { 7; } + } + ha:1 { + name = top_silk + ha:type { silk=1; top=1; } + li:layers { 6; } + } + ha:2 { + name = top_mask + ha:type { top=1; mask=1; } + li:layers { 8; } + } + ha:3 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; } + } + 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 { 3; } + } + 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 { 2; } + } + ha:8 { + name = grp_8 + ha:type { substrate=1; intern=1; } + li:layers { } + } + ha:9 { + name = global_outline + ha:type { boundary=1; } + li:layers { 4; } + purpose = uroute + } + ha:10 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; } + } + ha:11 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 9; } + } + ha:12 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 5; } + } + ha:13 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 10; } + } + ha:14 { + name = pmech + ha:type { mech=1; } + li:layers { 11; } + purpose = proute + } + ha:15 { + name = umech + ha:type { mech=1; } + li:layers { 12; } + purpose = uroute + } + ha:16 { + name = top_assy + ha:type { top=1; doc=1; } + li:layers { 13; } + ha:attributes { + init-invis=1 + } + purpose = assy + } + ha:17 { + name = bot_assy + ha:type { bottom=1; doc=1; } + li:layers { 14; } + ha:attributes { + init-invis=1 + } + purpose = assy + } + ha:18 { + name = fab + ha:type { top=1; doc=1; } + li:layers { 15; } + ha:attributes { + init-invis=1 + } + purpose = fab + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + text_scale = 100 + via_thickness = 137.80 mil + via_drilling_hole = 47.24 mil + text_thickness = 0 + line_thickness = 80.00 mil + clearance = 25.00 mil + } + ha:editor { + ha:view { + flip_y = 0 + } + wireframe_draw = false + show_solder_side = 0 + grids_idx = 4 + grid = 25.00 mil + } + } + } + ha:netlists { + + li:netlist_patch { + ha:add_conn { net=pcbrnd1; term=R1-1; } + ha:add_conn { net=pcbrnd1; term=R1-2; } + } + } +} Index: tags/2.3.0/tests/cam/offs/cam.conf =================================================================== --- tags/2.3.0/tests/cam/offs/cam.conf (nonexistent) +++ tags/2.3.0/tests/cam/offs/cam.conf (revision 33253) @@ -0,0 +1,18 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:cam { + li:jobs { + test { + desc export all layer groups by type-location (and sometimes purpose) + plugin svg + write %base%.copper_p1.svg=copper:+1 + write %base%.copper_p2.svg=copper:+2 + write %base%.copper_m2.svg=copper:-2 + write %base%.copper_m1.svg=copper:-1 + } + } + } + } + } +} Index: tags/2.3.0/tests/cam/offs/ref.tar.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/cam/offs/ref.tar.gz =================================================================== --- tags/2.3.0/tests/cam/offs/ref.tar.gz (nonexistent) +++ tags/2.3.0/tests/cam/offs/ref.tar.gz (revision 33253) Property changes on: tags/2.3.0/tests/cam/offs/ref.tar.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/cam/test.sh =================================================================== --- tags/2.3.0/tests/cam/test.sh (nonexistent) +++ tags/2.3.0/tests/cam/test.sh (revision 33253) @@ -0,0 +1,47 @@ +#!/bin/sh +#DBG=cdb + +TESTS="grp_name type offs" + +do_test() +{ + local testcase="$1" refs r o + $DBG pcb-rnd -C $testcase/cam.conf -x cam test --outfile $testcase/out layers.lht + + ( + cd $testcase + refs=`ls ref.*.svg 2>/dev/null` + if test -z "$refs" + then + tar -zxf ref.tar.gz + fi + for r in ref.*.svg + do + o=out.${r#ref.} + diff -u $r $o + done + ) +} + +do_clean() +{ + local testcase="$1" + rm -f $testcase/ref.*.svg $testcase/out.*.svg +} + +cmd="$1" +shift 1 + +tests="$@" +if test -z "$tests" +then + tests=$TESTS +fi + +for n in $tests +do + case "$cmd" in + test) do_test $n ;; + clean) do_clean $n ;; + esac +done Property changes on: tags/2.3.0/tests/cam/test.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/cam/type/cam.conf =================================================================== --- tags/2.3.0/tests/cam/type/cam.conf (nonexistent) +++ tags/2.3.0/tests/cam/type/cam.conf (revision 33253) @@ -0,0 +1,28 @@ +li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:cam { + li:jobs { + test { + desc export all layer groups by type-location (and sometimes purpose) + plugin svg + write %base%.top_paste.svg=top-paste + write %base%.top_silk.svg=top-silk + write %base%.top_mask.svg=top-mask + write %base%.top_copper.svg=top-copper + write %base%.intern.svg=intern-copper + write %base%.global_outline.svg=boundary + write %base%.bottom_copper.svg=bottom-copper + write %base%.bottom_mask.svg=bottom-mask + write %base%.bottom_silk.svg=bottom-silk + write %base%.bottom_paste.svg=bottom-paste + write %base%.pmech.svg=mech(purpose=proute) + write %base%.umech.svg=mech(purpose=uroute) + write %base%.top_assy.svg=top-doc(purpose=assy) + write %base%.bot_assy.svg=bottom-doc(purpose=assy) + } + } + } + } + } +} Index: tags/2.3.0/tests/cam/type/ref.tar.gz =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/cam/type/ref.tar.gz =================================================================== --- tags/2.3.0/tests/cam/type/ref.tar.gz (nonexistent) +++ tags/2.3.0/tests/cam/type/ref.tar.gz (revision 33253) Property changes on: tags/2.3.0/tests/cam/type/ref.tar.gz ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/conf/Makefile =================================================================== --- tags/2.3.0/tests/conf/Makefile (nonexistent) +++ tags/2.3.0/tests/conf/Makefile (revision 33253) @@ -0,0 +1,50 @@ +ROOT=../.. +include $(ROOT)/src_3rd/librnd/core/librnd.mak +include $(ROOT)/Makefile.conf + +CFLAGS = $(PCB_RND_C89FLAGS) -I../.. -I../../src_3rd -I../../src $(CFLAGS_LIBRND_FUNGW) +LDLIBS = -lm $(LDFLAGS_LIBRND_FUNGW) + +LIB_HIDLIB=\ + ../../src/librnd-hid.a \ + ../../src/librnd-3rd.a + +#LIBGENHT=\ +# ../../src_3rd/genht/hash.o \ +# ../../src_3rd/genht/htsp.o \ +# ../../src_3rd/genht/htsi.o \ +# ../../src_3rd/genht/htpp.o \ +# ../../src_3rd/genht/htpi.o \ + +LIB_PCBRND_OBJS=\ + ../../src_plugins/diag/diag_conf.o \ + ../../src/conf_core.o \ + ../../src/conf_internal.o + +DEPH = \ + ../../src_3rd/librnd/core/conf.h \ + ../../src_3rd/librnd/core/conf_hid.h \ + ../../src_3rd/librnd/core/compat_misc.h \ + ../../src/conf_core.h \ + ../../src_plugins/diag/diag_conf.h \ + +OBJS = conftest.o help.o + +all: conftest + +conftest: $(OBJS) $(LIB_HIDLIB) $(LIB_PCBRND_OBJS) $(LIBGENHT) + $(CC) $(LDFLAGS) $(OBJS) $(LIB_PCBRND_OBJS) $(LIB_HIDLIB) $(LIBGENHT) $(LDLIBS) -o conftest + +conftest.o: conftest.c $(DEPH) + $(CC) $(CFLAGS) -c conftest.c -o conftest.o + +help.o: help.c + +$(LIB_HIDLIB): + cd ../../src && make + +test: + cd tests && $(MAKE) all + +clean: + -$(SCCBOX) rm -f conftest tests/*.out ../../src_plugins/diag/diag_conf.o $(OBJS) Index: tags/2.3.0/tests/conf/conftest.c =================================================================== --- tags/2.3.0/tests/conf/conftest.c (nonexistent) +++ tags/2.3.0/tests/conf/conftest.c (revision 33253) @@ -0,0 +1,409 @@ +#include +#include +#include +#include "config.h" +#include +#include +#include +#include +#include +#include "conf_core.h" +#include "src_plugins/diag/diag_conf.h" + +int lineno = 0; +int global_notify = 0; +rnd_conf_hid_id_t hid_id; +const char *hid_cookie = "conftest cookie"; +rnd_hid_t *rnd_gui = NULL; +const char *rnd_hidlib_default_embedded_menu = ""; +const char *rnd_menu_file_paths[] = { "./", "~/.pcb-rnd/", PCBSHAREDIR "/", NULL }; +const char *rnd_menu_name_fmt = "pcb-menu-%s.lht"; + +#define CONF_USER_DIR "~/" DOT_PCB_RND +const char *rnd_conf_userdir_path = CONF_USER_DIR; +const char *rnd_pcphl_conf_user_path = CONF_USER_DIR "/pcb-conf.lht"; +const char *rnd_conf_sysdir_path = PCBSHAREDIR; +const char *rnd_conf_sys_path = PCBSHAREDIR "/pcb-conf.lht"; + +void pcbhl_conf_postproc(void) +{ +} + +const char *pcb_board_get_filename(void) +{ + return "dummy_brd.lht"; +} + +const char *pcb_board_get_name(void) +{ + return "dummy_brd"; +} + +int rnd_file_loaded_set_at(const char *catname, const char *name, const char *path, const char *desc) +{ + return 0; +} + +int rnd_file_loaded_del_at(const char *catname, const char *name) +{ + return 0; +} + + +void watch_pre(rnd_conf_native_t *cfg, int idx) +{ + printf("watch_pre: '%s' old value\n", cfg->hash_path); +} + +void watch_post(rnd_conf_native_t *cfg, int idx) +{ + printf("watch_post: '%s' new value\n", cfg->hash_path); +} + +void notify_pre(rnd_conf_native_t *cfg, int idx) +{ + if (global_notify) + printf("notify_pre: '%s' old value\n", cfg->hash_path); +} + +void notify_post(rnd_conf_native_t *cfg, int idx) +{ + if (global_notify) + printf("notify_post: '%s' new value\n", cfg->hash_path); +} + +rnd_conf_hid_callbacks_t watch_cbs = {watch_pre, watch_post, NULL, NULL}; +rnd_conf_hid_callbacks_t global_cbs = {notify_pre, notify_post, NULL, NULL}; + + +extern lht_doc_t *pcb_conf_main_root[]; +void cmd_dump(char *arg) +{ + if (arg == NULL) { + rnd_message(RND_MSG_ERROR, "Need an arg: native or lihata"); + return; + } + if (strncmp(arg, "native", 6) == 0) { + arg+=7; + while(isspace(*arg)) arg++; + conf_dump(stdout, "", 1, arg); + } + else if (strncmp(arg, "lihata", 6) == 0) { + rnd_conf_role_t role; + arg+=7; + while(isspace(*arg)) arg++; + role = rnd_conf_role_parse(arg); + if (role == RND_CFR_invalid) { + rnd_message(RND_MSG_ERROR, "Invalid role: '%s'", arg); + return; + } + if (pcb_conf_main_root[role] != NULL) + lht_dom_export(pcb_conf_main_root[role]->root, stdout, ""); + else + printf("\n"); + } + else + rnd_message(RND_MSG_ERROR, "Invalid dump mode: '%s'", arg); +} + +void cmd_print(char *arg) +{ + rnd_conf_native_t *node; + gds_t s; + + if (arg == NULL) { + rnd_message(RND_MSG_ERROR, "Need an arg: a native path"); + return; + } + node = rnd_conf_get_field(arg); + if (node == NULL) { + rnd_message(RND_MSG_ERROR, "No such path: '%s'", arg); + return; + } + gds_init(&s); + rnd_conf_print_native((rnd_conf_pfn)rnd_append_printf, &s, NULL, 0, node); + printf("%s='%s'\n", node->hash_path, s.array); + gds_uninit(&s); +} + +void cmd_load(char *arg, int is_text) +{ + char *fn; + rnd_conf_role_t role ; + + if (arg == NULL) { + help:; + rnd_message(RND_MSG_ERROR, "Need 2 args: role and %s", (is_text ? "lihata text" : "file name")); + return; + } + + if (*arg == '*') { + rnd_conf_load_all(NULL, NULL); + return; + } + + fn = strchr(arg, ' '); + if (fn == NULL) + goto help; + *fn = '\0'; + fn++; + while(isspace(*fn)) fn++; + + role = rnd_conf_role_parse(arg); + if (role == RND_CFR_invalid) { + rnd_message(RND_MSG_ERROR, "Invalid role: '%s'", arg); + return; + } + printf("Result: %d\n", rnd_conf_load_as(role, fn, is_text)); + rnd_conf_update(NULL, -1); +} + +rnd_conf_policy_t current_policy = RND_POL_OVERWRITE; +rnd_conf_role_t current_role = RND_CFR_DESIGN; + +void cmd_policy(char *arg) +{ + rnd_conf_policy_t np = rnd_conf_policy_parse(arg); + if (np == RND_POL_invalid) + rnd_message(RND_MSG_ERROR, "Invalid/unknown policy: '%s'", arg); + else + current_policy = np; +} + +void cmd_role(char *arg) +{ + rnd_conf_role_t nr = rnd_conf_role_parse(arg); + if (nr == RND_CFR_invalid) + rnd_message(RND_MSG_ERROR, "Invalid/unknown role: '%s'", arg); + else + current_role = nr; +} + +void cmd_chprio(char *arg) +{ + char *end; + int np = strtol(arg == NULL ? "" : arg, &end, 10); + lht_node_t *first; + + if ((*end != '\0') || (np < 0)) { + rnd_message(RND_MSG_ERROR, "Invalid integer prio: '%s'", arg); + return; + } + first = rnd_conf_lht_get_first(current_role, 0); + if (first != NULL) { + char tmp[128]; + char *end; + end = strchr(first->name, '-'); + if (end != NULL) + *end = '\0'; + sprintf(tmp, "%s-%d", first->name, np); + free(first->name); + first->name = rnd_strdup(tmp); + rnd_conf_update(NULL, -1); + } +} + +void cmd_chpolicy(char *arg) +{ + rnd_conf_policy_t np; + lht_node_t *first; + + if (arg == NULL) { + rnd_message(RND_MSG_ERROR, "need a policy", arg); + return; + } + np = rnd_conf_policy_parse(arg); + if (np == RND_POL_invalid) { + rnd_message(RND_MSG_ERROR, "Invalid integer policy: '%s'", arg); + return; + } + + first = rnd_conf_lht_get_first(current_role, 0); + if (first != NULL) { + char tmp[128]; + char *end; + end = strchr(first->name, '-'); + if (end != NULL) { + sprintf(tmp, "%s%s", arg, end); + free(first->name); + first->name = rnd_strdup(tmp); + } + else { + free(first->name); + first->name = rnd_strdup(arg); + } + rnd_conf_update(NULL, -1); + } +} + +void cmd_set(char *arg) +{ + char *path, *val; + int res; + + path = arg; + val = strpbrk(path, " \t="); + if (val == NULL) { + rnd_message(RND_MSG_ERROR, "set needs a value"); + return; + } + *val = '\0'; + val++; + while(isspace(*val) || (*val == '=')) val++; + + res = rnd_conf_set(current_role, path, -1, val, current_policy); + if (res != 0) + printf("set error: %d\n", res); +} + +void cmd_watch(char *arg, int add) +{ + rnd_conf_native_t *n = rnd_conf_get_field(arg); + if (n == NULL) { + rnd_message(RND_MSG_ERROR, "unknown path"); + return; + } + rnd_conf_hid_set_cb(n, hid_id, (add ? &watch_cbs : NULL)); +} + +void cmd_notify(char *arg) +{ + if (arg != NULL) { + if (strcmp(arg, "on") == 0) + global_notify = 1; + else if (strcmp(arg, "off") == 0) + global_notify = 0; + } + printf("Notify is %s\n", global_notify ? "on" : "off"); +} + +void cmd_echo(char *arg) +{ + if (arg != NULL) + printf("%s\n", arg); +} + +void cmd_reset(char *arg) +{ + if (arg == NULL) { + rnd_conf_reset(current_role, ""); + } + else if (*arg == '*') { + int n; + for(n = 0; n < RND_CFR_max_real; n++) + rnd_conf_reset(n, ""); + } + else { + rnd_conf_role_t role = rnd_conf_role_parse(arg); + if (role == RND_CFR_invalid) { + rnd_message(RND_MSG_ERROR, "Invalid role: '%s'", arg); + return; + } + rnd_conf_reset(role, ""); + } + rnd_conf_update(NULL, -1); +} + +extern void cmd_help(char *arg); + + +char line[8192]; + +/* returns 1 if there's more to read */ +int getline_cont(FILE *f) +{ + char *end = line + strlen(line) - 1; + int offs = 0, cont; + + if (feof(f)) + return 0; + + do { + int remain = sizeof(line)-offs; + assert(remain > 0); + cont = 0; + if (fgets(line+offs, remain, f)) { + char *start = line+offs; + int len = strlen(start); + lineno++; + end = start + len - 1; + while((end >= start) && ((*end == '\n') || (*end == '\r'))) { + *end = '\0'; + end--; + } + if ((end >= start) && (*end == '\\')) { + cont = 1; + *end = '\n'; + } + offs += len-1; + } + else { + if (offs == 0) + return 0; + } + } while(cont); + return 1; +} + +int main() +{ + + hid_id = rnd_conf_hid_reg(hid_cookie, &global_cbs); + + rnd_conf_init(); + conf_core_init(); + rnd_hidlib_conf_init(); + rnd_conf_reset(RND_CFR_SYSTEM, "
"); + rnd_conf_reset(RND_CFR_USER, "
"); + + while(getline_cont(stdin)) { + char *arg, *cmd = line; + while(isspace(*cmd)) cmd++; + if ((*cmd == '#') || (*cmd == '\0')) + continue; + arg = strpbrk(cmd, " \t"); + if (arg != NULL) { + *arg = '\0'; + arg++; + while(isspace(*arg)) arg++; + } + + if (strcmp(cmd, "dump") == 0) + cmd_dump(arg); + else if (strcmp(cmd, "print") == 0) + cmd_print(arg); + else if (strcmp(cmd, "load") == 0) + cmd_load(arg, 0); + else if (strcmp(cmd, "paste") == 0) + cmd_load(arg, 1); + else if (strcmp(cmd, "reset") == 0) + cmd_reset(arg); + else if (strcmp(cmd, "set") == 0) + cmd_set(arg); + else if (strcmp(cmd, "policy") == 0) + cmd_policy(arg); + else if (strcmp(cmd, "chprio") == 0) + cmd_chprio(arg); + else if (strcmp(cmd, "chpolicy") == 0) + cmd_chpolicy(arg); + else if (strcmp(cmd, "role") == 0) + cmd_role(arg); + else if (strcmp(cmd, "watch") == 0) + cmd_watch(arg, 1); + else if (strcmp(cmd, "unwatch") == 0) + cmd_watch(arg, 0); + else if (strcmp(cmd, "notify") == 0) + cmd_notify(arg); + else if (strcmp(cmd, "echo") == 0) + cmd_echo(arg); + else if (strcmp(cmd, "help") == 0) + cmd_help(arg); + else + rnd_message(RND_MSG_ERROR, "unknown command '%s'", cmd); + } + + conf_core_uninit_pre(); + rnd_conf_hid_unreg(hid_cookie); + rnd_conf_uninit(); + return 0; +} Index: tags/2.3.0/tests/conf/help.c =================================================================== --- tags/2.3.0/tests/conf/help.c (nonexistent) +++ tags/2.3.0/tests/conf/help.c (revision 33253) @@ -0,0 +1,90 @@ +#include +#include +#include + +static const char *help[] = { + "dump", "native", + "Dump all settings as ended up in the native database after the last merge/udpate.", + + "dump", "lihata role", + "Dump all in-memory lihata settings of a given role. For roles, see: help roles", + + "load", "role filename", + "Load a lihata file as role", + + "load", "*", + "Load all roles from disk - the same way as it happens on a normal pcb-rnd startup.", + + "paste", "role lhttxt", + "Paste in-line lihata document lhttxt as role, like if it was loaded from a file", + + "policy", "pol", + "Change current set-policy to pol. This only affects whether a set command inserts, appends or overwrites list-type settings. For valid policies, see: help policies", + + "role", "rol", + "Change current set-policy to rol. This only affects the destination of subsequent set commands. For valid roles, see: help roles", + + "chprio", "prio", + "Change the priority of the first confroot of the current role's in-memory lihata document to prio and merge. Prio is an integer value.", + + "chpolicy", "pol", + "Change the policy of the first confroot of the current role's in-memory lihata document to pol and merge. Pol is a policy, see: help policies", + + "set", "path value", + "Call rnd_conf_set() on a given path with the given value, using the current set-role and the current set-policy. See also: help role; help policy.", + + "watch", "path", + "Announce changes of a given path. See also: help unwatch", + + "unwatch", "path", + "Stop announcing changes of a given path. See also: help watch", + + "notify", "on", + "Turn on global notification on config changes.", + + "notify", "off", + "Turn off global notification on config changes.", + + "echo", "text...", + "Print multi-word text.", + + "reset", "role", + "Reset (make empty) the in-memory lihata document of role; see also: help roles", + + "reset", "*", + "Reset (make empty) all in-memory lihata documents", + +/* misc */ + "roles", NULL, + "Valid roles: system, defaultpcb, user, env, project, design, cli", + + "policies", NULL, + "Valid policies: prepend, append, overwrite", + + NULL, NULL, NULL +}; + +void cmd_help(char *arg) +{ + const char **s; + + printf("\n"); + + if (arg == NULL) { + const char *last = ""; + printf("Try help topic. Available topics:\n"); + for(s = help; s[2] != NULL; s+=3) { + if (strcmp(last, s[0]) != 0) + printf(" %s\n", s[0]); + last = s[0]; + } + return; + } + + for(s = help; s[2] != NULL; s+=3) { + if (strcmp(arg, s[0]) == 0) { + printf("%s %s\n", s[0], (s[1] == NULL ? "" : s[1])); + printf("%s\n\n", s[2]); + } + } +} Index: tags/2.3.0/tests/conf/tests/Makefile =================================================================== --- tags/2.3.0/tests/conf/tests/Makefile (nonexistent) +++ tags/2.3.0/tests/conf/tests/Makefile (revision 33253) @@ -0,0 +1,23 @@ +TESTS = \ + list_merge.diff \ + list_set.diff \ + arr_merge.diff \ + arr_set.diff \ + scalar.diff + +.SUFFIXES: .ref .test .out .diff .REF + +all: $(TESTS) + @echo "conf: *** QC PASS ***" + +.test.out: + @../conftest < $*.test >$*.out + +.test.REF: + @../conftest < $*.test >$*.ref + @echo $*.ref generated, please validate the content + +.out.diff: + @diff -u $*.ref $*.out + + Index: tags/2.3.0/tests/conf/tests/arr_merge.ref =================================================================== --- tags/2.3.0/tests/conf/tests/arr_merge.ref (nonexistent) +++ tags/2.3.0/tests/conf/tests/arr_merge.ref (revision 33253) @@ -0,0 +1,31 @@ +=== initial state: empty === + I appearance/color/layer[] = +=== import 3 levels === +Result: 0 + I appearance/color/layer[0] = #000001 <> conf_rev=4 + I appearance/color/layer[1] = #000002 <> conf_rev=4 +Result: 0 + I appearance/color/layer[0] = #000101 <> conf_rev=8 + I appearance/color/layer[1] = #000102 <> conf_rev=8 +Result: 0 + I appearance/color/layer[0] = #000201 <> conf_rev=12 + I appearance/color/layer[1] = #000201 <> conf_rev=12 +=== change policy: design->prepend (2, 1) === + I appearance/color/layer[0] = #000201 <> conf_rev=16 + I appearance/color/layer[1] = #000201 <> conf_rev=16 + I appearance/color/layer[2] = #000101 <> conf_rev=16 + I appearance/color/layer[3] = #000102 <> conf_rev=16 +=== change policy: user->append (2, 0, 1) === + I appearance/color/layer[0] = #000201 <> conf_rev=20 + I appearance/color/layer[1] = #000201 <> conf_rev=20 + I appearance/color/layer[2] = #000001 <> conf_rev=20 + I appearance/color/layer[3] = #000002 <> conf_rev=20 + I appearance/color/layer[4] = #000101 <> conf_rev=20 + I appearance/color/layer[5] = #000102 <> conf_rev=20 +=== change policy: design->append (0, 1, 2) === + I appearance/color/layer[0] = #000001 <> conf_rev=24 + I appearance/color/layer[1] = #000002 <> conf_rev=24 + I appearance/color/layer[2] = #000101 <> conf_rev=24 + I appearance/color/layer[3] = #000102 <> conf_rev=24 + I appearance/color/layer[4] = #000201 <> conf_rev=24 + I appearance/color/layer[5] = #000201 <> conf_rev=24 Index: tags/2.3.0/tests/conf/tests/arr_merge.test =================================================================== --- tags/2.3.0/tests/conf/tests/arr_merge.test (nonexistent) +++ tags/2.3.0/tests/conf/tests/arr_merge.test (revision 33253) @@ -0,0 +1,55 @@ +echo === initial state: empty === +reset * +dump native appearance/color/layer + +echo === import 3 levels === +paste system \ + li:pcb-rnd-conf-v1 { \ + ha:overwrite { \ + ha:appearance { \ + ha:color { \ + li:layer = {{#000001}; {#000002};} \ + } \ + } \ + } \ + } +dump native appearance/color/layer + +paste user \ + li:pcb-rnd-conf-v1 { \ + ha:overwrite { \ + ha:appearance { \ + ha:color { \ + li:layer = {{#000101}; {#000102};} \ + } \ + } \ + } \ + } +dump native appearance/color/layer + +paste design \ + li:pcb-rnd-conf-v1 { \ + ha:overwrite { \ + ha:appearance { \ + ha:color { \ + li:layer = {{#000201}; {#000201};} \ + } \ + } \ + } \ + } +dump native appearance/color/layer + +echo === change policy: design->prepend (2, 1) === +role design +chpolicy prepend +dump native appearance/color/layer + +echo === change policy: user->append (2, 0, 1) === +role user +chpolicy append +dump native appearance/color/layer + +echo === change policy: design->append (0, 1, 2) === +role design +chpolicy append +dump native appearance/color/layer Index: tags/2.3.0/tests/conf/tests/arr_set.ref =================================================================== --- tags/2.3.0/tests/conf/tests/arr_set.ref (nonexistent) +++ tags/2.3.0/tests/conf/tests/arr_set.ref (revision 33253) @@ -0,0 +1,37 @@ +=== initial state: empty === + I appearance/color/layer[] = +=== append two items === + I appearance/color/layer[0] = #000001 <:0>> conf_rev=4 + I appearance/color/layer[0] = #000001 <:0>> conf_rev=5 + I appearance/color/layer[1] = #000002 <:0>> conf_rev=5 +=== prepend two items === + I appearance/color/layer[0] = #000003 <:0>> conf_rev=6 + I appearance/color/layer[1] = #000001 <:0>> conf_rev=6 + I appearance/color/layer[2] = #000002 <:0>> conf_rev=6 + I appearance/color/layer[0] = #000004 <:0>> conf_rev=7 + I appearance/color/layer[1] = #000003 <:0>> conf_rev=7 + I appearance/color/layer[2] = #000001 <:0>> conf_rev=7 + I appearance/color/layer[3] = #000002 <:0>> conf_rev=7 +=== overwrite item === + I appearance/color/layer[0] = #000004 <:0>> conf_rev=12 + I appearance/color/layer[1] = #000005 <:0>> conf_rev=12 + I appearance/color/layer[2] = #000001 <:0>> conf_rev=12 + I appearance/color/layer[3] = #000002 <:0>> conf_rev=12 + I appearance/color/layer[0] = #000004 <:0>> conf_rev=13 + I appearance/color/layer[1] = #000005 <:0>> conf_rev=13 + I appearance/color/layer[2] = #000001 <:0>> conf_rev=13 + I appearance/color/layer[3] = #000002 <:0>> conf_rev=13 + I appearance/color/layer[4] = #000006 <:0>> conf_rev=13 + I appearance/color/layer[0] = #000004 <:0>> conf_rev=14 + I appearance/color/layer[1] = #000005 <:0>> conf_rev=14 + I appearance/color/layer[2] = #000001 <:0>> conf_rev=14 + I appearance/color/layer[3] = #000002 <:0>> conf_rev=14 + I appearance/color/layer[4] = #000006 <:0>> conf_rev=14 + I appearance/color/layer[5] = <> conf_rev=14 + I appearance/color/layer[6] = <> conf_rev=14 + I appearance/color/layer[7] = #000007 <:0>> conf_rev=14 +=== overwrite array === + I appearance/color/layer[0] = #000008 <:0>> conf_rev=19 + I appearance/color/layer[1] = #000003 <:0>> conf_rev=19 + I appearance/color/layer[2] = #000001 <:0>> conf_rev=19 + I appearance/color/layer[3] = #000002 <:0>> conf_rev=19 Index: tags/2.3.0/tests/conf/tests/arr_set.test =================================================================== --- tags/2.3.0/tests/conf/tests/arr_set.test (nonexistent) +++ tags/2.3.0/tests/conf/tests/arr_set.test (revision 33253) @@ -0,0 +1,44 @@ +role design + +echo === initial state: empty === +reset * +dump native appearance/color/layer + +echo === append two items === +policy append + +set appearance/color/layer #000001 +dump native appearance/color/layer + +set appearance/color/layer #000002 +dump native appearance/color/layer + +echo === prepend two items === +policy prepend + +set appearance/color/layer #000003 +dump native appearance/color/layer + +set appearance/color/layer #000004 +dump native appearance/color/layer + +echo === overwrite item === +policy overwrite +chprio 710 + +set appearance/color/layer[1] #000005 +dump native appearance/color/layer + +set appearance/color/layer[4] #000006 +dump native appearance/color/layer + +set appearance/color/layer[7] #000007 +dump native appearance/color/layer + + +echo === overwrite array === +policy overwrite +chprio 720 + +set appearance/color/layer #000008 +dump native appearance/color/layer Index: tags/2.3.0/tests/conf/tests/list_merge.ref =================================================================== --- tags/2.3.0/tests/conf/tests/list_merge.ref (nonexistent) +++ tags/2.3.0/tests/conf/tests/list_merge.ref (revision 33253) @@ -0,0 +1,13 @@ +=== initial state: empty === + I rc/library_search_paths = <> conf_rev=0 +=== import 3 levels === +Result: 0 + I rc/library_search_paths = {sys1 <>;sys2 <>;} <> conf_rev=4 +Result: 0 + I rc/library_search_paths = {user1 <>;user2 <>;} <> conf_rev=8 +Result: 0 + I rc/library_search_paths = {design1 <>;design2 <>;} <> conf_rev=12 +=== change policies === + I rc/library_search_paths = {design1 <>;design2 <>;user1 <>;user2 <>;} <> conf_rev=16 + I rc/library_search_paths = {design1 <>;design2 <>;sys1 <>;sys2 <>;user1 <>;user2 <>;} <> conf_rev=20 + I rc/library_search_paths = {sys1 <>;sys2 <>;user1 <>;user2 <>;design1 <>;design2 <>;} <> conf_rev=24 Index: tags/2.3.0/tests/conf/tests/list_merge.test =================================================================== --- tags/2.3.0/tests/conf/tests/list_merge.test (nonexistent) +++ tags/2.3.0/tests/conf/tests/list_merge.test (revision 33253) @@ -0,0 +1,47 @@ +echo === initial state: empty === +reset * +dump native rc/library_search_paths + +echo === import 3 levels === +paste system \ + li:pcb-rnd-conf-v1 { \ + ha:overwrite { \ + ha:rc { \ + li:library_search_paths = { sys1; sys2 } \ + } \ + } \ + } +dump native rc/library_search_paths + +paste user \ + li:pcb-rnd-conf-v1 { \ + ha:overwrite { \ + ha:rc { \ + li:library_search_paths = { user1; user2 } \ + } \ + } \ + } +dump native rc/library_search_paths + +paste design \ + li:pcb-rnd-conf-v1 { \ + ha:overwrite { \ + ha:rc { \ + li:library_search_paths = { design1; design2 } \ + } \ + } \ + } +dump native rc/library_search_paths + +echo === change policies === +role design +chpolicy prepend +dump native rc/library_search_paths + +role user +chpolicy append +dump native rc/library_search_paths + +role design +chpolicy append +dump native rc/library_search_paths Index: tags/2.3.0/tests/conf/tests/list_set.ref =================================================================== --- tags/2.3.0/tests/conf/tests/list_set.ref (nonexistent) +++ tags/2.3.0/tests/conf/tests/list_set.ref (revision 33253) @@ -0,0 +1,10 @@ +=== initial state: empty === + I rc/library_search_paths = <> conf_rev=0 +=== append two items === + I rc/library_search_paths = {foo <:0>>;} <> conf_rev=4 + I rc/library_search_paths = {foo <:0>>;bar <:0>>;} <> conf_rev=5 +=== prepend two items === + I rc/library_search_paths = {pre1 <:0>>;foo <:0>>;bar <:0>>;} <> conf_rev=6 + I rc/library_search_paths = {pre2 <:0>>;pre1 <:0>>;foo <:0>>;bar <:0>>;} <> conf_rev=7 +=== overwrite === + I rc/library_search_paths = {new <:0>>;} <> conf_rev=12 Index: tags/2.3.0/tests/conf/tests/list_set.test =================================================================== --- tags/2.3.0/tests/conf/tests/list_set.test (nonexistent) +++ tags/2.3.0/tests/conf/tests/list_set.test (revision 33253) @@ -0,0 +1,31 @@ +role design + +echo === initial state: empty === +reset * +dump native rc/library_search_paths + +echo === append two items === +policy append + +set rc/library_search_paths foo +dump native rc/library_search_paths + +set rc/library_search_paths bar +dump native rc/library_search_paths + +echo === prepend two items === +policy prepend + +set rc/library_search_paths pre1 +dump native rc/library_search_paths + +set rc/library_search_paths pre2 +dump native rc/library_search_paths + +echo === overwrite === +policy overwrite +chprio 710 +# NOTE: have to raise priority because previous prepend and append subtrees also remain in the tree + +set rc/library_search_paths new +dump native rc/library_search_paths Index: tags/2.3.0/tests/conf/tests/scalar.ref =================================================================== --- tags/2.3.0/tests/conf/tests/scalar.ref (nonexistent) +++ tags/2.3.0/tests/conf/tests/scalar.ref (revision 33253) @@ -0,0 +1,11 @@ +=== initial state === + I rc/backup_name = <> conf_rev=0 +=== setting new values on higher prio should change the final render === + I rc/backup_name = from_user <:0>> conf_rev=0 + I rc/backup_name = from_design <:0>> conf_rev=1 + I rc/backup_name = from_cli <:0>> conf_rev=2 +=== setting new values on lower prio should NOT change the final render === + I rc/backup_name = from_cli <:0>> conf_rev=3 + I rc/backup_name = from_cli <:0>> conf_rev=4 +=== change prio to reorder === + I rc/backup_name = from_design2 <:0>> conf_rev=5 Index: tags/2.3.0/tests/conf/tests/scalar.test =================================================================== --- tags/2.3.0/tests/conf/tests/scalar.test (nonexistent) +++ tags/2.3.0/tests/conf/tests/scalar.test (revision 33253) @@ -0,0 +1,29 @@ +echo === initial state === +dump native rc/backup_name + +echo === setting new values on higher prio should change the final render === +role user +set rc/backup_name from_user +dump native rc/backup_name + +role design +set rc/backup_name from_design +dump native rc/backup_name + +role cli +set rc/backup_name from_cli +dump native rc/backup_name + +echo === setting new values on lower prio should NOT change the final render === +role user +set rc/backup_name from_user2 +dump native rc/backup_name + +role design +set rc/backup_name from_design2 +dump native rc/backup_name + +echo === change prio to reorder === +role cli +chprio 1 +dump native rc/backup_name Index: tags/2.3.0/tests/drc_pstk_hbrk/Makefile =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/Makefile (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/Makefile (revision 33253) @@ -0,0 +1,9 @@ +all: + +test: + ./tester + +clean: + +distclean: + Index: tags/2.3.0/tests/drc_pstk_hbrk/README =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/README (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/README (revision 33253) @@ -0,0 +1,97 @@ +Test files for pcb_pstk_shape_hole_break() and DRC + +1. Polygon + - polygon.lht +single rectangle on top layer copper, with a hole. + Expected: No DRC violation + Status : OK + + - polygon_violation.lht +single rectangle on top layer copper, with a hole. + Expected: DRC violation + Status : OK, error detected + + - polygon_mask.lht +top layer mask only, with a hole. + Expected: No DRC violation + Status : OK + + - polygon_mask_violation.lht +top layer mask only, with a hole. + Expected: No DRC violation + Status : OK, no error, because no rule set for this. + TODO : Provide a mechanism to detect Soldermask rules (min. width, gap, clearance to drills...) + + - polygon_paste.lht +top layer paste only, with a hole. + Expected: No DRC violation + Status : OK + + - polygon_paste_violation.lht +top layer paste only, with a hole. + Expected: No DRC violation (because no rule set for this) + Status : OK, no error + + +2. Filled circle + - circle.lht +single circle on top layer copper, with a hole. + Expected: No DRC violation + Status : OK + + - circle_violation.lht +single circle on top layer copper, with a hole. + Expected: DRC violation + Status : KO: no error detected, which is wrong + + - circle_mask.lht +top layer mask only, with a hole. + Expected: No DRC violation + Status : OK + + - circle_mask_violation.lht +top layer mask only, with a hole. + Expected: No DRC violation + Status : OK, no error, because no rule set for this. + + - circle_paste.lht +top layer paste only, with a hole. + Expected: No DRC violation + Status : OK + + - circle_paste_violation.lht +top layer paste only, with a hole. + Expected: No DRC violation + Status : OK, no error, because no rule set for this. + + +3. (round cap) line + - line.lht +single line on top layer copper, with a hole. + Expected: No DRC violation + Status : OK + + - line_violation.lht +single line on top layer copper, with a hole. + Expected: DRC violation + Status : OK: error detected + + - line_mask.lht +single line on top mask only, with a hole. + Expected: No DRC violation + Status : OK + + - line_mask_violation.lht +single line on top mask only, with a hole. + Expected: No DRC violation + Status : OK, no error, because no rule set for this. + + - line_paste.lht +single line on top paste only, with a hole. + Expected: No DRC violation + Status : OK + + - line_paste_violation.lht +single line on top paste only, with a hole. + Expected: No DRC violation + Status : OK, no error, because no rule set for this. Index: tags/2.3.0/tests/drc_pstk_hbrk/circle.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/circle.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/circle.lht (revision 33253) @@ -0,0 +1,271 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=1.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=20.0mil + } + } + } + unused = 1 + } + + li:objects { + ha:padstack_ref.18 { + proto=0; x=5.0mm; y=3.0mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/circle_mask.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/circle_mask.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/circle_mask.lht (revision 33253) @@ -0,0 +1,271 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=1.0mm; } + ha:combining { sub=1; auto=1;} + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=20.0mil + } + } + } + unused = 1 + } + + li:objects { + ha:padstack_ref.18 { + proto=0; x=5.0mm; y=3.0mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/circle_mask_violation.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/circle_mask_violation.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/circle_mask_violation.lht (revision 33253) @@ -0,0 +1,270 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.3mm; y=0.0; dia=1.0mm; } + ha:combining { sub=1; auto=1;} + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=20.0mil + } + } + } + } + + li:objects { + ha:padstack_ref.22 { + proto=0; x=4.7mm; y=3.0mm; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/circle_paste.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/circle_paste.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/circle_paste.lht (revision 33253) @@ -0,0 +1,271 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=1.0mm; } + ha:combining { auto=1;} + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=20.0mil + } + } + } + unused = 1 + } + + li:objects { + ha:padstack_ref.18 { + proto=0; x=5.0mm; y=3.0mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/circle_paste_violation.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/circle_paste_violation.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/circle_paste_violation.lht (revision 33253) @@ -0,0 +1,270 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.3mm; y=0.0; dia=1.0mm; } + ha:combining { auto=1;} + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=20.0mil + } + } + } + } + + li:objects { + ha:padstack_ref.22 { + proto=0; x=4.7mm; y=3.0mm; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/circle_violation.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/circle_violation.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/circle_violation.lht (revision 33253) @@ -0,0 +1,270 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.3mm; y=0.0; dia=1.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=20.0mil + } + } + } + } + + li:objects { + ha:padstack_ref.22 { + proto=0; x=4.7mm; y=3.0mm; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/line.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/line.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/line.lht (revision 33253) @@ -0,0 +1,273 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + unused = 1 + ha:ps_proto_v6.1 { + hdia=0.4mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=-1.0mm; y1=0.0; x2=1.0mm; y2=0.0; thickness=1.2mm; square=0; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=1.0mm + } + } + } + + unused = 1 + } + + li:objects { + ha:padstack_ref.23 { + proto=1; x=6.0mm; y=3.0mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/line_mask.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/line_mask.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/line_mask.lht (revision 33253) @@ -0,0 +1,274 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + unused = 1 + ha:ps_proto_v6.1 { + hdia=0.4mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=-1.0mm; y1=0.0; x2=1.0mm; y2=0.0; thickness=1.2mm; square=0; } + ha:combining { sub=1; auto=1;} + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=1.0mm + } + } + } + + unused = 1 + } + + li:objects { + ha:padstack_ref.23 { + proto=1; x=6.0mm; y=3.0mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + selected=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/line_mask_violation.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/line_mask_violation.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/line_mask_violation.lht (revision 33253) @@ -0,0 +1,272 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=-1.0mm; y1=0.4mm; x2=1.0mm; y2=0.4mm; thickness=1.2mm; square=0; } + ha:combining { sub=1; auto=1;} + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.5mm + } + } + } + unused = 1 + unused = 1 + } + + li:objects { + ha:padstack_ref.28 { + proto=0; x=6.0mm; y=2.6mm; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + selected=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/line_paste.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/line_paste.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/line_paste.lht (revision 33253) @@ -0,0 +1,274 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + unused = 1 + ha:ps_proto_v6.1 { + hdia=0.4mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=-1.0mm; y1=0.0; x2=1.0mm; y2=0.0; thickness=1.2mm; square=0; } + ha:combining { auto=1;} + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=1.0mm + } + } + } + + unused = 1 + } + + li:objects { + ha:padstack_ref.23 { + proto=1; x=6.0mm; y=3.0mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + selected=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/line_paste_violation.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/line_paste_violation.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/line_paste_violation.lht (revision 33253) @@ -0,0 +1,272 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=-1.0mm; y1=0.4mm; x2=1.0mm; y2=0.4mm; thickness=1.2mm; square=0; } + ha:combining { auto=1;} + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.5mm + } + } + } + unused = 1 + unused = 1 + } + + li:objects { + ha:padstack_ref.28 { + proto=0; x=6.0mm; y=2.6mm; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + selected=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/line_violation.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/line_violation.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/line_violation.lht (revision 33253) @@ -0,0 +1,280 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + ha:line.24 { + x1=5.0mm; y1=3.0mm; x2=7.0mm; y2=3.0mm; thickness=1.2mm; clearance=0.5mm; + ha:flags { + clearline=1 + selected=1 + } + } + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_line { x1=-1.0mm; y1=0.4mm; x2=1.0mm; y2=0.4mm; thickness=1.2mm; square=0; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.5mm + } + } + } + unused = 1 + unused = 1 + } + + li:objects { + ha:padstack_ref.28 { + proto=0; x=6.0mm; y=2.6mm; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/polygon.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/polygon.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/polygon.lht (revision 33253) @@ -0,0 +1,280 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + li:ps_poly { + -0.5mm + -0.5mm + 1.8mm + -0.5mm + 1.8mm + 0.5mm + -0.5mm + 0.5mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.12 { + proto=0; x=5.2mm; y=2.5mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + selected=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/polygon_mask.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/polygon_mask.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/polygon_mask.lht (revision 33253) @@ -0,0 +1,280 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1;} + ha:layer_mask { + mask = 1 + top = 1 + } + clearance=40.0mil + li:ps_poly { + -0.5mm + -0.5mm + 1.8mm + -0.5mm + 1.8mm + 0.5mm + -0.5mm + 0.5mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.12 { + proto=0; x=5.2mm; y=2.5mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + selected=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/polygon_mask_violation.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/polygon_mask_violation.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/polygon_mask_violation.lht (revision 33253) @@ -0,0 +1,280 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1;} + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=40.0mil + li:ps_poly { + -0.2mm + -0.5mm + 1.8mm + -0.5mm + 1.8mm + 0.5mm + -0.2mm + 0.5mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.12 { + proto=0; x=5.2mm; y=2.5mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + selected=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/polygon_paste.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/polygon_paste.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/polygon_paste.lht (revision 33253) @@ -0,0 +1,279 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { auto=1;} + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=40.0mil + li:ps_poly { + -0.5mm + -0.5mm + 1.8mm + -0.5mm + 1.8mm + 0.5mm + -0.5mm + 0.5mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.12 { + proto=0; x=5.2mm; y=2.5mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/polygon_paste_violation.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/polygon_paste_violation.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/polygon_paste_violation.lht (revision 33253) @@ -0,0 +1,279 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { auto=1;} + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=40.0mil + li:ps_poly { + -0.2mm + -0.5mm + 1.8mm + -0.5mm + 1.8mm + 0.5mm + -0.2mm + 0.5mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.12 { + proto=0; x=5.2mm; y=2.5mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/polygon_violation.lht =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/polygon_violation.lht (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/polygon_violation.lht (revision 33253) @@ -0,0 +1,280 @@ +# pcb-rnd official 2-layer default board + +ha:pcb-rnd-board-v6 { + li:styles { + ha:Signal { + diameter = 2mm + thickness = 10.0mil + hole = 31.5mil + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Power { + diameter = 2.2mm + thickness = 20.0mil + hole = 1mm + clearance = 20.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Fat { + diameter = 137.8mil + thickness = 80.0mil + hole = 47.24mil + clearance = 25.0mil + text_scale = 0 + text_thick = 0.0 + } + ha:Sig-tight { + diameter = 64.0mil + thickness = 10.0mil + hole = 31.5mil + clearance = 12.0mil + text_scale = 0 + text_thick = 0.0 + } + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 20.0mm; y = 10.0mm + } + ha:grid { + spacing = 0.1mm + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:layers { + ha:top-sig { lid=0; group=3; + li:objects { + } + color = {#8b2323} + ha:combining { + } + } + ha:bottom-sig { lid=1; group=6; + li:objects { + } + color = {#3a5fcd} + ha:combining { + } + } + ha:top-gnd { lid=2; group=3; + li:objects { + } + color = {#104e8b} + ha:combining { + } + } + ha:bottom-gnd { lid=3; group=6; + li:objects { + } + color = {#cd3700} + ha:combining { + } + } + ha:top-vcc { lid=4; group=3; + li:objects { + } + color = {#548b54} + ha:combining { + } + } + ha:bottom-vcc { lid=5; group=6; + li:objects { + } + color = {#8b7355} + ha:combining { + } + } + ha:outline { lid=6; group=5; + li:objects { + } + color = {#00868b} + ha:combining { + } + } + ha:bottom-silk { lid=7; group=8; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + ha:top-silk { lid=8; group=1; ha:combining { auto=1; } + li:objects { + } + color = {#cdd0f1} +} + 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=7; ha:combining { sub=1; auto=1; } + li:objects { + } + color = {#ff0000} +} + ha:bottom-paste { lid=12; group=9; ha:combining { auto=1; } + li:objects { + } + color = {#cd00cd} +} + ha:slot-plated { lid=13; group=10; ha:combining { auto=1; } + li:objects { + } + color = {#8b7355} +} + ha:slot-unplated { lid=14; group=11; ha:combining { auto=1; } + li:objects { + } + color = {#00868b} +} + } + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.3mm; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + li:ps_poly { + -0.2mm + -0.5mm + 1.8mm + -0.5mm + 1.8mm + 0.5mm + -0.2mm + 0.5mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.12 { + proto=0; x=5.2mm; y=2.5mm; rot=0.000000; xmirror=0; smirror=0; clearance=0.5mm; + ha:flags { + clearline=1 + selected=1 + } + + li:thermal { + } + } + } + } + + 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; 4; } + } + ha:4 { + ha:type { substrate=1; intern=1; } + li:layers { } + name = grp_4 + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + purpose = uroute + li:layers { 6; } + } + ha:6 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; 3; 5; } + } + ha:7 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 11; } + } + ha:8 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 7; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 12; } + } + ha:10 { + name = pmech + ha:type { mech=1; } + purpose = proute + li:layers { 13; } + } + ha:11 { + name = umech + ha:type { mech=1; } + purpose = uroute + li:layers { 14; } + } + } + } + ha:attributes { + {PCB::grid::unit}=mm + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring = 200.00 um + min_drill = 200.00 um + text_scale = 100 + via_thickness = 2.0000 mm + via_drilling_hole = 31.50 mil + min_slk = 0.15000000 mm + text_thickness = 0 + line_thickness = 10.00 mil + shrink = 0.25000000 mm + poly_isle_area = 200000000.0 + min_wid = 0.20000000 mm + bloat = 0.20000000 mm + clearance = 20.00 mil + } + ha:editor { + grid_unit = mm + buffer_number = 0 + grids_idx = 9 + grid = 100.00 um + } + } + } +} Index: tags/2.3.0/tests/drc_pstk_hbrk/tester =================================================================== --- tags/2.3.0/tests/drc_pstk_hbrk/tester (nonexistent) +++ tags/2.3.0/tests/drc_pstk_hbrk/tester (revision 33253) @@ -0,0 +1,57 @@ +#!/bin/sh + +# Run pcb-rnd on each test case and check if drc found errors where it should +# and does not find anything where it shouldn't. Run with -v to print each case. + +verbose=0 + +do_test() +{ +echo ' +drc() +' | pcb-rnd --gui batch "$1" 2>/dev/null | grep -i broken +} + +should_break() +{ + if test -z "$res" + then + echo "ERR: $fn: DRC did not find an error" + else + if test $verbose -gt 0 + then + echo "OK: $fn: DRC error" + fi + fi +} + +should_pass() +{ + if test ! -z "$res" + then + echo "ERR: $fn: DRC found a non-existing error" + else + if test $verbose -gt 0 + then + echo "OK: $fn: DRC clean" + fi + fi +} + +### main ### + +if test "$1" = "-v" +then + verbose=1 +fi + +for fn in *.lht +do + res=`do_test "$fn"` + case "$fn" in + *_mask_violation*) should_pass ;; + *_paste_violation*) should_pass ;; + *_violation*) should_break ;; + *) should_pass ;; + esac +done Property changes on: tags/2.3.0/tests/drc_pstk_hbrk/tester ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/drc_query/Makefile =================================================================== --- tags/2.3.0/tests/drc_query/Makefile (nonexistent) +++ tags/2.3.0/tests/drc_query/Makefile (revision 33253) @@ -0,0 +1,57 @@ +ROOT=../.. + +SRC=$(ROOT)/src +TDIR=../tests/drc_query +FLT=$(TDIR)/drc_filter.sh +PCBRND=./pcb-rnd +GLOBARGS=-c rc/library_search_paths=../tests/RTT/lib -c rc/quiet=1 -c editor/drc_inclusive_bbox=1 + +TESTS = \ +thickness.diff overlap.diff netint.diff dwg_area.diff fullpoly.diff \ +zone_clr.diff + +test: $(TESTS) + +all: + +thickness.diff: thickness.out + @diff -u thickness.ref thickness.out && rm thickness.out + +thickness.out: FORCE + @cd $(SRC) && echo "drc()" | $(PCBRND) $(GLOBARGS) $(TDIR)/thickness.lht --gui batch | $(FLT) > $(TDIR)/thickness.out + +overlap.diff: overlap.out + @diff -u overlap.ref overlap.out && rm overlap.out + +overlap.out: FORCE + @cd $(SRC) && echo "drc()" | $(PCBRND) $(GLOBARGS) $(TDIR)/overlap.lht --gui batch | $(FLT) > $(TDIR)/overlap.out + +netint.diff: netint.out + @diff -u netint.ref netint.out && rm netint.out + +netint.out: FORCE + @cd $(SRC) && echo "drc()" | $(PCBRND) $(GLOBARGS) $(TDIR)/netint.lht --gui batch | $(FLT) > $(TDIR)/netint.out + +dwg_area.diff: dwg_area.out + @diff -u dwg_area.ref dwg_area.out && rm dwg_area.out + +dwg_area.out: FORCE + @cd $(SRC) && echo "drc()" | $(PCBRND) $(GLOBARGS) $(TDIR)/dwg_area.lht --gui batch | $(FLT) > $(TDIR)/dwg_area.out + +fullpoly.diff: fullpoly.out + @diff -u fullpoly.ref fullpoly.out && rm fullpoly.out + +fullpoly.out: FORCE + @cd $(SRC) && echo "drc()" | $(PCBRND) $(GLOBARGS) $(TDIR)/fullpoly.lht --gui batch | $(FLT) > $(TDIR)/fullpoly.out + +zone_clr.diff: zone_clr.out + @diff -u zone_clr.ref zone_clr.out && rm zone_clr.out + +zone_clr.out: FORCE + @cd $(SRC) && echo "drc()" | $(PCBRND) $(GLOBARGS) $(TDIR)/zone_clr.lht --gui batch | $(FLT) > $(TDIR)/zone_clr.out + +clean: + @echo "a" > dummy.out + rm *.out + +FORCE: Index: tags/2.3.0/tests/drc_query/drc_filter.sh =================================================================== --- tags/2.3.0/tests/drc_query/drc_filter.sh (nonexistent) +++ tags/2.3.0/tests/drc_query/drc_filter.sh (revision 33253) @@ -0,0 +1,88 @@ +#!/bin/sh + +# make drc output comparable (remove dependency on order of reports) + +awk ' + +BEGIN { + shift = 10000 + tn = 0; +} + +function append(line) +{ + if (text == "") + text = line + else + text = text "\n" line +} + +function fin() +{ + if (text != "") { + TEXT[tn] = text; + HASH[tn] = hash+1; + tn++; + text = ""; + hash = 0; + } +} + +function print_best( n,best,bestn) +{ + best = 0 + for(n = 0; n < tn; n++) { + if (TEXT[n] == "") + continue; + if (HASH[n] > best) { + best = HASH[n] + bestn = n + } + } + + if (bestn == "") + return 0; + + print TEXT[bestn] + TEXT[bestn] = "" + return 1; +} + +function print_all() +{ + while(print_best()); +} + +#1: object beyond drawing area: Objects located outside of the drawing area +/^[0-9]+:/ { + line=$0; + sub("^[0-9]+:", "x:", line); + if (!(line in ID)) { + ids++; + ID[line] = ids; + } + hash = ID[line] * shift * shift; + append(line); + next +} + +#within (112.40, -106.35, 237.60, -43.65) mil +/^within/ { + line=$0; + sub(".*[(]", "", line); + split(line, C, "[,]"); + + hash += C[1] * shift + C[2] +} + +{ append($0); } + +/^$/ { fin() } + +END { + fin(); + print_all(); +} + + +' Property changes on: tags/2.3.0/tests/drc_query/drc_filter.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/drc_query/dwg_area.lht =================================================================== --- tags/2.3.0/tests/drc_query/dwg_area.lht (nonexistent) +++ tags/2.3.0/tests/drc_query/dwg_area.lht (revision 33253) @@ -0,0 +1,110 @@ +ha:pcb-rnd-board-v6 { + + li:styles { + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 375.0mil + y = 150.0mil + } + ha:grid { + spacing = 25.0mil + } + } + + ha:data { + li:padstack_prototypes { + } + + li:objects { + } + li:layers { + + ha:top-sig { + lid=0 + group=0 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftt} + {pcb-rnd::key::select}={l; t} + } + + li:objects { + ha:line.5 { + x1=150.0mil; y1=-75.0mil; x2=200.0mil; y2=-75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.11 { + x1=-175.0mil; y1=75.0mil; x2=-125.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.14 { + x1=150.0mil; y1=225.0mil; x2=200.0mil; y2=225.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.17 { + x1=525.0mil; y1=75.0mil; x2=575.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.23 { + x1=0.0; y1=0.0; x2=50.0mil; y2=0.0; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.26 { + x1=325.0mil; y1=150.0mil; x2=375.0mil; y2=150.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.29 { + x1=0.0; y1=150.0mil; x2=50.0mil; y2=150.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.32 { + x1=325.0mil; y1=0.0; x2=375.0mil; y2=0.0; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + } + ha:plugins { + ha:drc_orig { + disable = 1 + } + } + } + } +} Index: tags/2.3.0/tests/drc_query/dwg_area.ref =================================================================== --- tags/2.3.0/tests/drc_query/dwg_area.ref (nonexistent) +++ tags/2.3.0/tests/drc_query/dwg_area.ref (revision 33253) @@ -0,0 +1,16 @@ +x: object beyond drawing area: Objects located outside of the drawing area +within (487.40, 43.65, 612.60, 106.35) mil +Objects may be omitted from exports or may be outside of the board contour. + +x: object beyond drawing area: Objects located outside of the drawing area +within (112.40, 193.65, 237.60, 256.35) mil +Objects may be omitted from exports or may be outside of the board contour. + +x: object beyond drawing area: Objects located outside of the drawing area +within (112.40, -106.35, 237.60, -43.65) mil +Objects may be omitted from exports or may be outside of the board contour. + +x: object beyond drawing area: Objects located outside of the drawing area +within (-212.60, 43.65, -87.40, 106.35) mil +Objects may be omitted from exports or may be outside of the board contour. + Index: tags/2.3.0/tests/drc_query/fullpoly.lht =================================================================== --- tags/2.3.0/tests/drc_query/fullpoly.lht (nonexistent) +++ tags/2.3.0/tests/drc_query/fullpoly.lht (revision 33253) @@ -0,0 +1,148 @@ +ha:pcb-rnd-board-v6 { + + li:styles { + } + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 500.0mil + y = 500.0mil + } + ha:grid { + spacing = 25.0mil + offs_y = 0.0 + offs_x = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + } + + li:objects { + } + li:layers { + + ha:top-sig { + lid=0 + group=0 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftt} + {pcb-rnd::key::select}={l; t} + } + + li:objects { + ha:line.54 { + x1=0.0; y1=75.0mil; x2=175.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.65 { + x1=250.0mil; y1=75.0mil; x2=425.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.105 { + x1=75.0mil; y1=325.0mil; x2=100.0mil; y2=325.0mil; thickness=10.0mil; clearance=200.0mil; + ha:flags { + clearline=1 + } + } + ha:line.108 { + x1=325.0mil; y1=325.0mil; x2=350.0mil; y2=325.0mil; thickness=10.0mil; clearance=200.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.49 { clearance=40.0mil; + li:geometry { + ta:contour { + { 25.0mil; 25.0mil } + { 150.0mil; 25.0mil } + { 150.0mil; 150.0mil } + { 25.0mil; 150.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.68 { clearance=40.0mil; + li:geometry { + ta:contour { + { 275.0mil; 25.0mil } + { 400.0mil; 25.0mil } + { 400.0mil; 150.0mil } + { 275.0mil; 150.0mil } + } + } + + ha:flags { + fullpoly=1 + clearpoly=1 + } + } + ha:polygon.111 { clearance=40.0mil; + li:geometry { + ta:contour { + { 25.0mil; 275.0mil } + { 150.0mil; 275.0mil } + { 150.0mil; 400.0mil } + { 25.0mil; 400.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.116 { clearance=40.0mil; + li:geometry { + ta:contour { + { 275.0mil; 275.0mil } + { 400.0mil; 275.0mil } + { 400.0mil; 400.0mil } + { 275.0mil; 400.0mil } + } + } + + ha:flags { + fullpoly=1 + clearpoly=1 + } + } + } + color = {#8b2323} + } + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + } + ha:plugins { + ha:drc_orig { + disable = 1 + } + } + ha:editor { + } + } + } +} Index: tags/2.3.0/tests/drc_query/fullpoly.ref =================================================================== --- tags/2.3.0/tests/drc_query/fullpoly.ref (nonexistent) +++ tags/2.3.0/tests/drc_query/fullpoly.ref (revision 33253) @@ -0,0 +1,6 @@ +W: Polygon #111 cleared out of existence near (2.2225 mm, 8.5725 mm) +W: Polygon #116 cleared out of existence near (8.5725 mm, 8.5725 mm) +x: fullpoly: Multi-island polygon with the fullpoly flag +within (259.38, 9.38, 415.63, 165.63) mil +Polygon with the fullpoly flag set is cut into multiple islands + Index: tags/2.3.0/tests/drc_query/netint.lht =================================================================== --- tags/2.3.0/tests/drc_query/netint.lht (nonexistent) +++ tags/2.3.0/tests/drc_query/netint.lht (revision 33253) @@ -0,0 +1,601 @@ +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:meta { + ha:size { + thermal_scale = 0.500000 + x = 150.0mil + y = 350.0mil + } + ha:grid { + spacing = 25mil + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.1 { + hdia=1.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.36 { + ha:attributes { + footprint=0402 Standard SMT resistor, capacitor etc + refdes=R1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.326136mm + -0.425958mm + -0.326136mm + -0.425958mm + -0.326136mm + 0.425958mm + 0.326136mm + 0.425958mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.50 { + proto=0; x=1.505204mm; y=50.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.51 { + proto=0; x=2.304796mm; y=50.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.38 { + x1=75.0mil; y1=50.0mil; x2=75.0mil; y2=50.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.41 { + x1=75.0mil; y1=50.0mil; x2=75.0mil; y2=50.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.44 { + x1=75.0mil; y1=50.0mil; x2=2.905mm; y2=50.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.47 { + x1=75.0mil; y1=50.0mil; x2=75.0mil; y2=2.27mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = xK4LY0258SGWTnYfnvwAAAAB + } + ha:subc.77 { + ha:attributes { + footprint=0402 Standard SMT resistor, capacitor etc + refdes=R2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.326136mm + -0.425958mm + -0.326136mm + -0.425958mm + -0.326136mm + 0.425958mm + 0.326136mm + 0.425958mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.90 { + proto=0; x=1.505204mm; y=300.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.91 { + proto=0; x=2.304796mm; y=300.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.78 { + x1=75.0mil; y1=300.0mil; x2=75.0mil; y2=300.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.81 { + x1=75.0mil; y1=300.0mil; x2=75.0mil; y2=300.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.84 { + x1=75.0mil; y1=300.0mil; x2=2.905mm; y2=300.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.87 { + x1=75.0mil; y1=300.0mil; x2=75.0mil; y2=8.62mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = xK4LY0258SGWTnYfnvwAAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=2 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftt} + {pcb-rnd::key::select}={l; t} + } + + li:objects { + ha:line.98 { + x1=1.505204mm; y1=300.0mil; x2=1.505204mm; y2=5.315204mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.101 { + x1=1.505204mm; y1=5.315204mm; x2=50.0mil; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.107 { + x1=50.0mil; y1=150.0mil; x2=1.505204mm; y2=140.74mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.110 { + x1=1.505204mm; y1=140.74mil; x2=1.505204mm; y2=50.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.113 { + x1=2.304796mm; y1=300.0mil; x2=2.304796mm; y2=50.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.116 { + x1=50.0mil; y1=150.0mil; x2=50.0mil; y2=190.8mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.119 { + x1=2.304796mm; y1=3.00482mm; x2=1.78562mm; y2=3.00482mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=7 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftb} + {pcb-rnd::key::select}={l; b} + } + + li:objects { + } + color = {#3a5fcd} + } + + ha:outline { + lid=2 + group=6 + ha:combining { } + + li:objects { + } + color = {#00868b} + } + + ha:top-paste { + lid=3 + group=0 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + ha:top-mask { + lid=4 + group=1 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-mask { + lid=5 + group=8 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-paste { + lid=6 + group=9 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + } + } + + ha:netlists { + li:netlist_patch { + ha:add_conn { net=N1; term=R2-1; } + ha:add_conn { net=N1; term=R1-1; } + ha:add_conn { net=N2; term=R1-2; } + ha:add_conn { net=N2; term=R2-2; } + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { 3; } + } + ha:1 { + name = top_mask + ha:type { top=1; mask=1; } + li:layers { 4; } + } + ha:2 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; } + } + ha:3 { + name = grp_4 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:4 { + name = grp_6 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.125mm } + } + } + ha:5 { + name = grp_8 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:6 { + name = global_outline + ha:type { boundary=1; } + li:layers { 2; } + purpose = uroute + } + ha:7 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; } + } + ha:8 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 5; } + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 6; } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring=0mil + } + ha:plugins { + ha:drc_orig { + disable = 1 + } + } + } + } +} Index: tags/2.3.0/tests/drc_query/netint.ref =================================================================== --- tags/2.3.0/tests/drc_query/netint.ref (nonexistent) +++ tags/2.3.0/tests/drc_query/netint.ref (revision 33253) @@ -0,0 +1,12 @@ +x: shorted nets: net too close to other net +within (23.98, 7.31, 126.02, 183.43) mil +insufficient clearance between an object of the network and objects of other networks + +x: shorted nets: net too close to other net +within (23.98, 7.31, 126.02, 183.43) mil +insufficient clearance between an object of the network and objects of other networks + +x: broken net: insufficient overlap +within (17.50, 111.25, 91.76, 248.01) mil +the overlap between two objects in the net is insufficient and can lead to broken network during board fabrication + Index: tags/2.3.0/tests/drc_query/overlap.lht =================================================================== --- tags/2.3.0/tests/drc_query/overlap.lht (nonexistent) +++ tags/2.3.0/tests/drc_query/overlap.lht (revision 33253) @@ -0,0 +1,469 @@ +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 = 150.0mil + y = 350.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + + ha:ps_proto_v6.1 { + hdia=1.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=64.0mil; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.5 { + proto=0; x=125.0mil; y=125.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=12.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.6 { + proto=0; x=75.0mil; y=175.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=12.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.7 { + proto=0; x=75.0mil; y=200.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=12.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.8 { + proto=1; x=75.0mil; y=300.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=12.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:subc.36 { + ha:attributes { + footprint=0402 Standard SMT resistor, capacitor etc + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.326136mm + -0.425958mm + -0.326136mm + -0.425958mm + -0.326136mm + 0.425958mm + 0.326136mm + 0.425958mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.249936mm + -0.349758mm + -0.249936mm + -0.349758mm + -0.249936mm + 0.349758mm + 0.249936mm + 0.349758mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.50 { + proto=0; x=1.505204mm; y=50.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.51 { + proto=0; x=2.304796mm; y=50.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.38 { + x1=75.0mil; y1=50.0mil; x2=75.0mil; y2=50.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.41 { + x1=75.0mil; y1=50.0mil; x2=75.0mil; y2=50.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.44 { + x1=75.0mil; y1=50.0mil; x2=2.905mm; y2=50.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.47 { + x1=75.0mil; y1=50.0mil; x2=75.0mil; y2=2.27mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = xK4LY0258SGWTnYfnvwAAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=2 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftt} + {pcb-rnd::key::select}={l; t} + } + + li:objects { + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=7 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftb} + {pcb-rnd::key::select}={l; b} + } + + li:objects { + } + color = {#3a5fcd} + } + + ha:outline { + lid=2 + group=6 + ha:combining { } + + li:objects { + } + color = {#00868b} + } + + ha:top-paste { + lid=3 + group=0 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + ha:top-mask { + lid=4 + group=1 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-mask { + lid=5 + group=8 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:bottom-paste { + lid=6 + group=9 + ha:combining { auto=1; } + + li:objects { + } + color = {#cd00cd} + } + + } + } + + ha:layer_stack { + li:groups { + ha:0 { + name = top_paste + ha:type { top=1; paste=1; } + li:layers { 3; } + } + ha:1 { + name = top_mask + ha:type { top=1; mask=1; } + li:layers { 4; } + } + ha:2 { + name = top_copper + ha:type { top=1; copper=1; } + li:layers { 0; } + } + ha:3 { + name = grp_4 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:4 { + name = grp_6 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.125mm } + } + } + ha:5 { + name = grp_8 + ha:type { intern=1; substrate=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:6 { + name = global_outline + ha:type { boundary=1; } + li:layers { 2;} + purpose = uroute + } + ha:7 { + name = bottom_copper + ha:type { copper=1; bottom=1; } + li:layers { 1; } + } + ha:8 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 5;} + } + ha:9 { + name = bottom_paste + ha:type { bottom=1; paste=1; } + li:layers { 6; } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + min_ring=0mil + } + ha:plugins { + ha:drc_orig { + disable=1 + } + } + } + } +} Index: tags/2.3.0/tests/drc_query/overlap.ref =================================================================== --- tags/2.3.0/tests/drc_query/overlap.ref (nonexistent) +++ tags/2.3.0/tests/drc_query/overlap.ref (revision 33253) @@ -0,0 +1,12 @@ +x: pair hole: overlapping holes +within (20.00, 116.88, 130.00, 258.13) mil +required value 31.50 mil +measured value 25.00 mil +padstack holes overlap + +x: single hole: hole too small +within (20.00, 245.00, 130.00, 355.00) mil +required value 15.00 mil +measured value 1.50 mil +padstack hole diameter is too small + Index: tags/2.3.0/tests/drc_query/thickness.lht =================================================================== --- tags/2.3.0/tests/drc_query/thickness.lht (nonexistent) +++ tags/2.3.0/tests/drc_query/thickness.lht (revision 33253) @@ -0,0 +1,291 @@ +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 = 40.005mm + y = 600.0mil + } + 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=1 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftt} + {pcb-rnd::key::select}={l; t} + } + + li:objects { + ha:line.5 { + x1=75.0mil; y1=75.0mil; x2=75.0mil; y2=250.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.15 { + x1=75.0mil; y1=375.0mil; x2=75.0mil; y2=550.0mil; thickness=9.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.8 { + x=325.0mil; y=250.0mil; width=150.0mil; height=150.0mil; astart=-90.000000; adelta=90.000000; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.18 { + x=325.0mil; y=550.0mil; width=150.0mil; height=150.0mil; astart=-90.000000; adelta=90.000000; thickness=9.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:text.9 { + string=Hello!; x=400.0mil; y=125.0mil; scale=200; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.19 { + string=Hello!; x=400.0mil; y=425.0mil; scale=200; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + thickness = 9.0mil + } + } + color = {#8b2323} + } + + ha:outline { + lid=1 + group=5 + ha:combining { } + + li:objects { + } + color = {#00868b} + } + + ha:bottom-silk { + lid=2 + group=7 + ha:combining { auto=1; } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftx} + {pcb-rnd::key::select}={l; x} + } + + li:objects { + } + color = {#000000} + } + + ha:top-silk { + lid=3 + group=0 + ha:combining { auto=1; } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shifts} + {pcb-rnd::key::select}={l; s} + } + + li:objects { + ha:line.30 { + x1=925.0mil; y1=75.0mil; x2=925.0mil; y2=250.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.33 { + x1=925.0mil; y1=375.0mil; x2=925.0mil; y2=550.0mil; thickness=6.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.36 { + x=1.175in; y=250.0mil; width=150.0mil; height=150.0mil; astart=-90.000000; adelta=90.000000; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.37 { + x=1.175in; y=550.0mil; width=150.0mil; height=150.0mil; astart=-90.000000; adelta=90.000000; thickness=6.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:text.38 { + string=Hello!; x=31.75mm; y=125.0mil; scale=200; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + } + ha:text.39 { + string=Hello!; x=31.75mm; y=425.0mil; scale=200; fid=0; + ha:flags { + clearline=1 + } + rot = 0.000000 + thickness = 6.0mil + } + } + color = {#000000} + } + + ha:bottom-mask { + lid=4 + group=6 + ha:combining { sub=1; auto=1; } + + li:objects { + } + color = {#ff0000} + } + + ha:fab { + lid=5 + group=8 + ha:combining { auto=1; } + + li:objects { + } + color = {#222222} + } + } + } + + ha:layer_stack { + li:groups { + ha:0 { + name = top_silk + ha:type { top=1; silk=1; } + li:layers { 3; } + } + ha:1 { + name = top_copper + ha:type { top=1; copper=1; } + li:layers { 0; } + } + ha:2 { + name = grp_4 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:3 { + name = grp_6 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.125mm } + } + } + ha:4 { + name = grp_8 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + li:layers { 1; } + purpose = uroute + } + ha:6 { + name = bottom_mask + ha:type { bottom=1; mask=1; } + li:layers { 4;} + } + ha:7 { + name = bottom_silk + ha:type { silk=1; bottom=1; } + li:layers { 2; } + } + ha:8 { + name = fab + ha:type { top=1; doc=1; } + li:layers { 5;} + ha:attributes { + init-invis=1 + } + purpose = fab + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:design { + text_font_id = 0 + min_wid = 10mil + min_slk = 7mil + } + ha:plugins { + ha:drc_orig { + disable=1 + } + } + } + } +} Index: tags/2.3.0/tests/drc_query/thickness.ref =================================================================== --- tags/2.3.0/tests/drc_query/thickness.ref (nonexistent) +++ tags/2.3.0/tests/drc_query/thickness.ref (revision 33253) @@ -0,0 +1,36 @@ +x: thin silk: silk object too thin +within (1196.00, 413.75, 1566.00, 556.25) mil +required value 7.00 mil +measured value 6.00 mil +Silk object thickness is below the required value. Silk objects too thin may disappear during board fabrication. + +x: thin silk: silk object too thin +within (976.92, 351.93, 1223.08, 598.08) mil +required value 7.00 mil +measured value 6.00 mil +Silk object thickness is below the required value. Silk objects too thin may disappear during board fabrication. + +x: thin silk: silk object too thin +within (896.16, 324.29, 953.84, 600.71) mil +required value 7.00 mil +measured value 6.00 mil +Silk object thickness is below the required value. Silk objects too thin may disappear during board fabrication. + +x: thin copper: copper object too thin +within (346.00, 413.75, 716.00, 556.25) mil +required value 10.00 mil +measured value 9.00 mil +Copper object thickness is below the required value. Copper objects too thin may break or peel off during board fabriaction. + +x: thin copper: copper object too thin +within (125.01, 350.01, 374.99, 599.99) mil +required value 10.00 mil +measured value 9.00 mil +Copper object thickness is below the required value. Copper objects too thin may break or peel off during board fabriaction. + +x: thin copper: copper object too thin +within (44.28, 322.41, 105.72, 602.59) mil +required value 10.00 mil +measured value 9.00 mil +Copper object thickness is below the required value. Copper objects too thin may break or peel off during board fabriaction. + Index: tags/2.3.0/tests/drc_query/zone_clr.lht =================================================================== --- tags/2.3.0/tests/drc_query/zone_clr.lht (nonexistent) +++ tags/2.3.0/tests/drc_query/zone_clr.lht (revision 33253) @@ -0,0 +1,799 @@ +ha:pcb-rnd-board-v7 { + + ha:meta { + ha:size { + x = 725.0mil + y = 700.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.436 { + proto=0; x=475.0mil; y=500.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:subc.48 { + ha:attributes { + footprint=1206 Standard SMT resistor, capacitor etc + refdes=R1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.726186mm + -1.02616mm + -0.726186mm + -1.02616mm + -0.726186mm + 1.02616mm + 0.726186mm + 1.02616mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.68 { + proto=0; x=90.95mil; y=425.0mil; rot=90.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.69 { + proto=0; x=90.95mil; y=7.79526mm; rot=90.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.49 { + x1=1.36017mm; y1=9.895078mm; x2=1.36017mm; y2=8.695182mm; thickness=8.0mil; clearance=0.0; + } + ha:line.52 { + x1=3.26009mm; y1=9.895078mm; x2=3.26009mm; y2=8.695182mm; thickness=8.0mil; clearance=0.0; + } + ha:text.55 { + string=%a.parent.refdes%; x=43.5mil; y=581.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 90.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.56 { + x1=90.95mil; y1=9.29513mm; x2=90.95mil; y2=9.29513mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.59 { + x1=90.95mil; y1=9.29513mm; x2=90.95mil; y2=9.29513mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.62 { + x1=90.95mil; y1=9.29513mm; x2=90.95mil; y2=8.29513mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.65 { + x1=90.95mil; y1=9.29513mm; x2=3.31013mm; y2=9.29513mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = pjaLj8tSfYLVqy1mjLYAAAAB + } + ha:subc.71 { + ha:attributes { + footprint=1206 Standard SMT resistor, capacitor etc + refdes=R2 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=0.0 + li:ps_poly { + 0.726186mm + -1.02616mm + -0.726186mm + -1.02616mm + -0.726186mm + 1.02616mm + 0.726186mm + 1.02616mm + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=0.0 + li:ps_poly { + 0.649986mm + -0.94996mm + -0.649986mm + -0.94996mm + -0.649986mm + 0.94996mm + 0.649986mm + 0.94996mm + } + } + } + } + } + + li:objects { + ha:padstack_ref.91 { + proto=0; x=640.95mil; y=425.0mil; rot=90.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + name=1 + } + } + ha:padstack_ref.92 { + proto=0; x=640.95mil; y=7.79526mm; rot=90.000000; xmirror=0; smirror=0; clearance=10.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=2 + name=2 + } + } + } + li:layers { + + ha:top-silk { + lid=0 + ha:combining { } + + li:objects { + ha:line.72 { + x1=15.33017mm; y1=9.895078mm; x2=15.33017mm; y2=8.695182mm; thickness=8.0mil; clearance=0.0; + } + ha:line.75 { + x1=678.35mil; y1=9.895078mm; x2=678.35mil; y2=8.695182mm; thickness=8.0mil; clearance=0.0; + } + ha:text.78 { + string=%a.parent.refdes%; x=618.5mil; y=581.5mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 90.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + + ha:subc-aux { + lid=1 + ha:combining { } + + li:objects { + ha:line.79 { + x1=640.95mil; y1=9.29513mm; x2=640.95mil; y2=9.29513mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=pnp-origin + } + } + ha:line.82 { + x1=640.95mil; y1=9.29513mm; x2=640.95mil; y2=9.29513mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.85 { + x1=640.95mil; y1=9.29513mm; x2=640.95mil; y2=8.29513mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.88 { + x1=640.95mil; y1=9.29513mm; x2=17.28013mm; y2=9.29513mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + } + } + uid = pjaLj8tSfYLVqy1mjLYAAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=1 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftt} + {pcb-rnd::key::select}={l; t} + } + + li:objects { + ha:line.174 { + x1=90.95mil; y1=7.79526mm; x2=90.95mil; y2=234.05mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.177 { + x1=90.95mil; y1=234.05mil; x2=125.0mil; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.180 { + x1=125.0mil; y1=200.0mil; x2=225.0mil; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.183 { + x1=225.0mil; y1=200.0mil; x2=225.0mil; y2=8.06196mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.186 { + x1=225.0mil; y1=325.0mil; x2=275.0mil; y2=325.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.189 { + x1=274.8mil; y1=8.05688mm; x2=274.8mil; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.192 { + x1=275.0mil; y1=200.0mil; x2=400.0mil; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.195 { + x1=400.0mil; y1=200.0mil; x2=400.0mil; y2=8.07466mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.198 { + x1=400.0mil; y1=325.0mil; x2=450.0mil; y2=325.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.201 { + x1=449.3mil; y1=8.04926mm; x2=449.3mil; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.204 { + x1=450.0mil; y1=200.0mil; x2=625.0mil; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.207 { + x1=625.0mil; y1=200.0mil; x2=625.0mil; y2=7.39013mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.210 { + x1=625.0mil; y1=7.39013mm; x2=640.95mil; y2=7.79526mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.213 { + x1=90.95mil; y1=425.0mil; x2=90.95mil; y2=12.47013mm; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.216 { + x1=90.95mil; y1=12.47013mm; x2=100.0mil; y2=500.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.219 { + x1=100.0mil; y1=500.0mil; x2=225.0mil; y2=500.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.222 { + x1=225.0mil; y1=500.0mil; x2=225.0mil; y2=357.6mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.225 { + x1=225.0mil; y1=350.0mil; x2=275.0mil; y2=350.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.228 { + x1=274.8mil; y1=358.0mil; x2=274.8mil; y2=500.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.231 { + x1=275.0mil; y1=500.0mil; x2=400.0mil; y2=500.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.237 { + x1=400.0mil; y1=400.0mil; x2=450.0mil; y2=400.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.240 { + x1=450.0mil; y1=400.0mil; x2=450.0mil; y2=500.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.243 { + x1=450.0mil; y1=500.0mil; x2=650.0mil; y2=500.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.246 { + x1=650.0mil; y1=500.0mil; x2=650.0mil; y2=434.05mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.249 { + x1=650.0mil; y1=434.05mil; x2=640.95mil; y2=425.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.345 { + x1=400.0mil; y1=500.0mil; x2=400.0mil; y2=400.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.440 { + x1=500.0mil; y1=500.0mil; x2=500.0mil; y2=225.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.549 { + x1=425.0mil; y1=400.0mil; x2=425.0mil; y2=340.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=7 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftb} + {pcb-rnd::key::select}={l; b} + } + + li:objects { + ha:line.443 { + x1=475.0mil; y1=500.0mil; x2=425.0mil; y2=500.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.446 { + x1=425.0mil; y1=500.0mil; x2=400.0mil; y2=500.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.449 { + x1=350.0mil; y1=450.0mil; x2=350.0mil; y2=225.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.452 { + x1=400.0mil; y1=500.0mil; x2=350.0mil; y2=450.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#3a5fcd} + } + + ha:outline { + lid=2 + group=5 + ha:combining { } + + li:objects { + } + color = {#00868b} + } + + ha:top-silk { + lid=3 + group=0 + ha:combining { auto=1; } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shifts} + {pcb-rnd::key::select}={l; s} + } + + li:objects { + } + color = {#000000} + } + + ha:zone-clr { + lid=4 + group=6 + ha:combining { } + + li:objects { + ha:polygon.253 { clearance=40.0mil; + li:geometry { + ta:contour { + { 175.0mil; 125.0mil } + { 325.0mil; 125.0mil } + { 325.0mil; 575.0mil } + { 175.0mil; 575.0mil } + } + } + + ha:flags { + clearpoly=1 + } + + ha:attributes { + min_copper_clearance=8mil + } + } + ha:polygon.258 { clearance=40.0mil; + li:geometry { + ta:contour { + { 350.0mil; 125.0mil } + { 500.0mil; 125.0mil } + { 500.0mil; 575.0mil } + { 350.0mil; 575.0mil } + } + } + + ha:flags { + clearpoly=1 + } + + ha:attributes { + min_copper_clearance=20mil + } + } + } + color = {#104e8b} + } + } + } + + ha:netlists { + li:netlist_patch { + ha:add_conn { net=pcbrnd1; term=R1-2; } + ha:add_conn { net=pcbrnd1; term=R2-2; } + ha:add_conn { net=pcbrnd2; term=R1-1; } + ha:add_conn { net=pcbrnd2; term=R2-1; } + } + } + ha:layer_stack { + li:groups { + ha:0 { + name = top_silk + ha:type { top=1; silk=1; } + li:layers { 3; } + } + ha:1 { + name = top_copper + ha:type { top=1; copper=1; } + li:layers { 0; } + } + ha:2 { + name = grp_4 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:3 { + name = grp_6 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.125mm } + } + } + ha:4 { + name = grp_8 + ha:type { substrate=1; intern=1; } + li:layers { } + ha:attributes { + thickness={0.7375mm } + } + } + ha:5 { + name = global_outline + ha:type { boundary=1; } + li:layers { 2;} + purpose = uroute + } + ha:6 { + name = zones + ha:type { doc=1; } + li:layers { 4;} + purpose = zone + } + ha:7 { + name = bottom_copper + ha:type { bottom=1; copper=1; } + li:layers { 1; } + } + } + } + li:pcb-rnd-conf-v1 { + ha:overwrite { + ha:plugins { + ha:drc_query { + li:rules { + ha:zone_clr { + type = shorted nets + title = net too close to other net (zone) + desc = insufficient clearance between an object of the network and objects of other networks + query = { +rule zone_clr +let Z ((@.type == POLYGON) && (@.layer.purpose == "zone") && (@.a.min_copper_clearance)) thus @ +let A (@.type == PSTK) || (@.layer.type == COPPER) +let B A +assert (A.IID < B.IID) && (overlap(A, Z) || overlap(B, Z)) && (A.netname != B.netname) && intersect(A, B, Z.a.min_copper_clearance) thus violation(DRCGRP1, A, DRCGRP2, B, DRCEXPECT, Z.a.min_copper_clearance) + } + } + } + } + } + ha:design { + text_font_id = 0 + } + ha:editor { + wireframe_draw = false + line_refraction = 1 + grids_idx = 4 + grid = 25.00 mil + } + } + } + ha:pixmaps { + } +} Index: tags/2.3.0/tests/drc_query/zone_clr.ref =================================================================== --- tags/2.3.0/tests/drc_query/zone_clr.ref (nonexistent) +++ tags/2.3.0/tests/drc_query/zone_clr.ref (revision 33253) @@ -0,0 +1,10 @@ +x: shorted nets: net too close to other net (zone) +within (396.78, 131.15, 678.22, 568.85) mil +required value 20mil +insufficient clearance between an object of the network and objects of other networks + +x: shorted nets: net too close to other net (zone) +within (362.40, 284.28, 487.60, 440.72) mil +required value 20mil +insufficient clearance between an object of the network and objects of other networks + Index: tags/2.3.0/tests/find/mask.lht =================================================================== --- tags/2.3.0/tests/find/mask.lht (nonexistent) +++ tags/2.3.0/tests/find/mask.lht (revision 33253) @@ -0,0 +1,390 @@ +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 = 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 = 250.0mil + y = 150.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + li:ps_poly { + -25.0mil + -25.0mil + 25.0mil + -25.0mil + 25.0mil + 25.0mil + -25.0mil + 25.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=40.0mil + li:ps_poly { + -28.0mil + -28.0mil + 28.0mil + -28.0mil + 28.0mil + 28.0mil + -28.0mil + 28.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=40.0mil + li:ps_poly { + -25.0mil + -25.0mil + 25.0mil + -25.0mil + 25.0mil + 25.0mil + -25.0mil + 25.0mil + } + } + } + } + } + + li:objects { + ha:padstack_ref.21 { + proto=0; x=75.0mil; y=75.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.23 { + proto=0; x=175.0mil; y=75.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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 { + ha:line.24 { + x1=75.0mil; y1=75.0mil; x2=175.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + 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/2.3.0/tests/find/paste.lht =================================================================== --- tags/2.3.0/tests/find/paste.lht (nonexistent) +++ tags/2.3.0/tests/find/paste.lht (revision 33253) @@ -0,0 +1,389 @@ +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 = 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 = 250.0mil + y = 150.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=0.0; hplated=0; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=40.0mil + li:ps_poly { + -25.0mil + -25.0mil + 25.0mil + -25.0mil + 25.0mil + 25.0mil + -25.0mil + 25.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { sub=1; auto=1; } + ha:layer_mask { + top = 1 + mask = 1 + } + clearance=40.0mil + li:ps_poly { + -28.0mil + -28.0mil + 28.0mil + -28.0mil + 28.0mil + 28.0mil + -28.0mil + 28.0mil + } + } + + ha:ps_shape_v4 { + ha:combining { auto=1; } + ha:layer_mask { + top = 1 + paste = 1 + } + clearance=40.0mil + li:ps_poly { + -25.0mil + -25.0mil + 25.0mil + -25.0mil + 25.0mil + 25.0mil + -25.0mil + 25.0mil + } + } + } + } + } + + li:objects { + ha:padstack_ref.21 { + proto=0; x=75.0mil; y=75.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + ha:padstack_ref.23 { + proto=0; x=175.0mil; y=75.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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 { + ha:line.30 { + x1=75.0mil; y1=75.0mil; x2=175.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + 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/2.3.0/tests/gsch2pcb-rnd/Makefile =================================================================== --- tags/2.3.0/tests/gsch2pcb-rnd/Makefile (nonexistent) +++ tags/2.3.0/tests/gsch2pcb-rnd/Makefile (revision 33253) @@ -0,0 +1,12 @@ +all: + cd simple && $(MAKE) all + +test: + cd simple && $(MAKE) test + @echo "gsch2pcb-rnd: *** QC PASS ***" + +clean: + cd simple && $(MAKE) clean + +distclean: + cd simple && $(MAKE) distclean Index: tags/2.3.0/tests/gsch2pcb-rnd/Makefile.common =================================================================== --- tags/2.3.0/tests/gsch2pcb-rnd/Makefile.common (nonexistent) +++ tags/2.3.0/tests/gsch2pcb-rnd/Makefile.common (revision 33253) @@ -0,0 +1,9 @@ +CONF = \ + -c rc/library_search_paths+=$(TRUNK)/pcblib \ + -c rc/default_pcb_file=$(TRUNK)/src/default.pcb + +GSCH2PCB = $(TRUNK)/util/gsch2pcb-rnd/gsch2pcb-rnd + +DIFF = diff -u + +FORCE: Index: tags/2.3.0/tests/gsch2pcb-rnd/simple/Makefile =================================================================== --- tags/2.3.0/tests/gsch2pcb-rnd/simple/Makefile (nonexistent) +++ tags/2.3.0/tests/gsch2pcb-rnd/simple/Makefile (revision 33253) @@ -0,0 +1,12 @@ +TRUNK=../../.. +all: + +include ../Makefile.common + +test: FORCE + @make clean + @$(GSCH2PCB) -m import $(CONF) main.sch > main.log + @$(DIFF) main.cmd.ref main.cmd + +clean: + @rm main.pcb main.cmd main.log 2>/dev/null; true \ No newline at end of file Index: tags/2.3.0/tests/gsch2pcb-rnd/simple/main.cmd.ref =================================================================== --- tags/2.3.0/tests/gsch2pcb-rnd/simple/main.cmd.ref (nonexistent) +++ tags/2.3.0/tests/gsch2pcb-rnd/simple/main.cmd.ref (revision 33253) @@ -0,0 +1,68 @@ +Netlist(Freeze) +Netlist(Clear) +Netlist(Add,unnamed_net2,C3-2) +Netlist(Add,unnamed_net2,CONN2-1) +Netlist(Add,unnamed_net2,U1-3) +Netlist(Add,GND,C3-1) +Netlist(Add,GND,CONN2-2) +Netlist(Add,GND,CONN1-2) +Netlist(Add,GND,C1-2) +Netlist(Add,GND,C2-1) +Netlist(Add,GND,U1-2) +Netlist(Add,unnamed_net1,C2-2) +Netlist(Add,unnamed_net1,C1-1) +Netlist(Add,unnamed_net1,CONN1-1) +Netlist(Add,unnamed_net1,U1-1) +Netlist(Sort) +Netlist(Thaw) +ElementList(Start) +ElementList(Need,"C3","1206","unknown") +ElementSetAttr("C3","device","CAPACITOR") +ElementSetAttr("C3","manufacturer","unknown") +ElementSetAttr("C3","manufacturer_part_number","unknown") +ElementSetAttr("C3","vendor","unknown") +ElementSetAttr("C3","vendor_part_number","unknown") +ChangePinName("C3", 2, "2") +ChangePinName("C3", 1, "1") +ElementList(Need,"CONN2","connector(1,2)","unknown") +ElementSetAttr("CONN2","device","CONNECTOR_2") +ElementSetAttr("CONN2","manufacturer","unknown") +ElementSetAttr("CONN2","manufacturer_part_number","unknown") +ElementSetAttr("CONN2","vendor","unknown") +ElementSetAttr("CONN2","vendor_part_number","unknown") +ChangePinName("CONN2", 2, "2") +ChangePinName("CONN2", 1, "1") +ElementList(Need,"CONN1","connector(1,2)","unknown") +ElementSetAttr("CONN1","device","CONNECTOR_2") +ElementSetAttr("CONN1","manufacturer","unknown") +ElementSetAttr("CONN1","manufacturer_part_number","unknown") +ElementSetAttr("CONN1","vendor","unknown") +ElementSetAttr("CONN1","vendor_part_number","unknown") +ChangePinName("CONN1", 2, "2") +ChangePinName("CONN1", 1, "1") +ElementList(Need,"C1","TANT_A","unknown") +ElementSetAttr("C1","device","POLARIZED_CAPACITOR") +ElementSetAttr("C1","manufacturer","unknown") +ElementSetAttr("C1","manufacturer_part_number","unknown") +ElementSetAttr("C1","vendor","unknown") +ElementSetAttr("C1","vendor_part_number","unknown") +ChangePinName("C1", 2, "-") +ChangePinName("C1", 1, "+") +ElementList(Need,"C2","1206","unknown") +ElementSetAttr("C2","device","CAPACITOR") +ElementSetAttr("C2","manufacturer","unknown") +ElementSetAttr("C2","manufacturer_part_number","unknown") +ElementSetAttr("C2","vendor","unknown") +ElementSetAttr("C2","vendor_part_number","unknown") +ChangePinName("C2", 2, "2") +ChangePinName("C2", 1, "1") +ElementList(Need,"U1","TO220","unknown") +ElementSetAttr("U1","device","7805") +ElementSetAttr("U1","manufacturer","unknown") +ElementSetAttr("U1","manufacturer_part_number","unknown") +ElementSetAttr("U1","vendor","unknown") +ElementSetAttr("U1","vendor_part_number","unknown") +ChangePinName("U1", 3, "3") +ChangePinName("U1", 2, "2") +ChangePinName("U1", 1, "1") +ElementList(Done) Index: tags/2.3.0/tests/gsch2pcb-rnd/simple/main.out.ref =================================================================== --- tags/2.3.0/tests/gsch2pcb-rnd/simple/main.out.ref (nonexistent) +++ tags/2.3.0/tests/gsch2pcb-rnd/simple/main.out.ref (revision 33253) @@ -0,0 +1,20 @@ + ../../../src/default.pcb -> 0 + +---------------------------------- +Done processing. Work performed: +6 file elements added to main.pcb. + +Next step: +1. Run pcb on your file main.pcb. + You will find all your footprints in a bundle ready for you to place + or disperse with "Select -> Disperse all elements" in PCB. + +2. From within PCB, select "File -> Load netlist file" and select + main.net to load the netlist. + +3. From within PCB, enter + + :ExecuteFile(main.cmd) + + to propagate the pin names of all footprints to the layout. + Index: tags/2.3.0/tests/gsch2pcb-rnd/simple/main.sch =================================================================== --- tags/2.3.0/tests/gsch2pcb-rnd/simple/main.sch (nonexistent) +++ tags/2.3.0/tests/gsch2pcb-rnd/simple/main.sch (revision 33253) @@ -0,0 +1,80 @@ +v 20130925 2 +C 27800 50500 1 0 0 lm7805-1.sym +{ +T 29400 51800 5 10 0 0 0 0 1 +device=7805 +T 29200 51500 5 10 1 1 0 6 1 +refdes=U1 +T 28100 51500 5 10 1 1 0 0 1 +footprint=TO220 +} +C 27700 50000 1 90 0 capacitor-1.sym +{ +T 27000 50200 5 10 0 0 90 0 1 +device=CAPACITOR +T 27800 50600 5 10 1 1 90 0 1 +refdes=C2 +T 26800 50200 5 10 0 0 90 0 1 +symversion=0.1 +T 27800 49900 5 10 1 1 90 0 1 +footprint=1206 +} +C 26500 50900 1 270 0 capacitor-2.sym +{ +T 27200 50700 5 10 0 0 270 0 1 +device=POLARIZED_CAPACITOR +T 26400 49700 5 10 1 1 90 0 1 +refdes=C1 +T 27400 50700 5 10 0 0 270 0 1 +symversion=0.1 +T 26400 50100 5 10 1 1 90 0 1 +footprint=TANT_A +} +C 25700 50300 1 0 1 connector2-2.sym +{ +T 25000 51600 5 10 1 1 0 0 1 +refdes=CONN1 +T 25400 51550 5 10 0 0 0 6 1 +device=CONNECTOR_2 +T 25400 51750 5 10 0 0 0 6 1 +footprint=connector(1,2) +} +N 25700 51100 27800 51100 4 +C 31700 50300 1 0 0 connector2-2.sym +{ +T 32400 51600 5 10 1 1 0 6 1 +refdes=CONN2 +T 32000 51550 5 10 0 0 0 0 1 +device=CONNECTOR_2 +T 32000 51750 5 10 0 0 0 0 1 +footprint=connector(1,2) +} +N 31700 51100 29400 51100 4 +C 30100 50000 1 90 0 capacitor-1.sym +{ +T 29400 50200 5 10 0 0 90 0 1 +device=CAPACITOR +T 30200 50600 5 10 1 1 90 0 1 +refdes=C3 +T 29200 50200 5 10 0 0 90 0 1 +symversion=0.1 +T 30200 49900 5 10 1 1 90 0 1 +footprint=1206 +} +N 25700 50700 26000 50700 4 +N 26000 50700 26000 49300 4 +N 31700 50700 31500 50700 4 +N 31500 50700 31500 49300 4 +N 26700 50900 26700 51100 4 +N 27500 50900 27500 51100 4 +N 29900 50900 29900 51100 4 +N 28600 50500 28600 49300 4 +C 28500 49000 1 0 0 gnd-1.sym +C 29800 49000 1 0 0 gnd-1.sym +C 31400 49000 1 0 0 gnd-1.sym +C 27400 49000 1 0 0 gnd-1.sym +C 26600 49000 1 0 0 gnd-1.sym +C 25900 49000 1 0 0 gnd-1.sym +N 26700 49300 26700 50000 4 +N 27500 49300 27500 50000 4 +N 29900 49300 29900 50000 4 Index: tags/2.3.0/tests/io_bxl/Makefile =================================================================== --- tags/2.3.0/tests/io_bxl/Makefile (nonexistent) +++ tags/2.3.0/tests/io_bxl/Makefile (revision 33253) @@ -0,0 +1,15 @@ +ROOT=../.. +PLG=$(ROOT)/src_plugins/io_bxl +#TODO: pick up config cflags and ldflags +CFLAGS = -g -Wall -I$(PLG) -I$(ROOT)/src -I$(ROOT)/src_3rd -I$(ROOT) +LDFLAGS = -lm + +test_parse: test_parse.o glue.o $(PLG)/bxl_lex.o $(PLG)/bxl_gram.o $(ROOT)/src/librnd-hid.a $(ROOT)/src/librnd-3rd.a + +#$(PLG)/bxl_lex.c $(PLG)/bxl_lex.h: $(PLG)/bxl_lex.ul $(PLG)/bxl_gram.h $(PLG)/bxl.h +# ureglex -l $(PLG)/bxl_lex.ul -c $(PLG)/bxl_lex.c -h $(PLG)/bxl_lex.h + +#$(PLG)/bxl_gram.c $(PLG)/bxl_gram.h: $(PLG)/bxl_gram.y +# byaccic -v $(PLG)/bxl_gram.desc -o $(PLG)/bxl_gram.c -H $(PLG)/bxl_gram.h $(PLG)/bxl_gram.y + +test_parse.o: $(PLG)/bxl_gram.h $(PLG)/bxl_lex.h Index: tags/2.3.0/tests/io_bxl/glue.c =================================================================== --- tags/2.3.0/tests/io_bxl/glue.c (nonexistent) +++ tags/2.3.0/tests/io_bxl/glue.c (revision 33253) @@ -0,0 +1,36 @@ +#include "bxl.h" + +rnd_coord_t pcb_bxl_coord_x(rnd_coord_t c) { return c; } +rnd_coord_t pcb_bxl_coord_y(rnd_coord_t c) { return -c; } + +void pcb_bxl_pattern_begin(pcb_bxl_ctx_t *ctx, const char *name) {} +void pcb_bxl_pattern_end(pcb_bxl_ctx_t *ctx) {} +void pcb_bxl_reset(pcb_bxl_ctx_t *ctx) {} +void pcb_bxl_reset_pattern(pcb_bxl_ctx_t *ctx) {} +void pcb_bxl_set_layer(pcb_bxl_ctx_t *ctx, const char *layer_name) {} +void pcb_bxl_set_justify(pcb_bxl_ctx_t *ctx, const char *str) {} +void pcb_bxl_add_line(pcb_bxl_ctx_t *ctx) {} +void pcb_bxl_add_arc(pcb_bxl_ctx_t *ctx) {} +void pcb_bxl_add_text(pcb_bxl_ctx_t *ctx) {} +void pcb_bxl_set_text_str(pcb_bxl_ctx_t *ctx, char *str) { free(str); } +void pcb_bxl_poly_begin(pcb_bxl_ctx_t *ctx) {} +void pcb_bxl_poly_end(pcb_bxl_ctx_t *ctx) {} +void pcb_bxl_poly_add_vertex(pcb_bxl_ctx_t *ctx, rnd_coord_t x, rnd_coord_t y) {} +void pcb_bxl_add_property(pcb_bxl_ctx_t *ctx, pcb_any_obj_t *obj, const char *keyval) {} +void pcb_bxl_set_attr_val(pcb_bxl_ctx_t *ctx, char *key, char *val) { free(key); free(val); } + +static pcb_bxl_test_style_t dummy_ts; +void pcb_bxl_text_style_begin(pcb_bxl_ctx_t *ctx, char *name) { free(name); ctx->state.text_style = &dummy_ts; } +void pcb_bxl_text_style_end(pcb_bxl_ctx_t *ctx) {} +void pcb_bxl_set_text_style(pcb_bxl_ctx_t *ctx, const char *name) {} + + +void pcb_bxl_padstack_begin(pcb_bxl_ctx_t *ctx, char *name) { free(name); } +void pcb_bxl_padstack_end(pcb_bxl_ctx_t *ctx) { } +void pcb_bxl_padstack_begin_shape(pcb_bxl_ctx_t *ctx, const char *name) {} +void pcb_bxl_padstack_end_shape(pcb_bxl_ctx_t *ctx) {} + + +void pcb_bxl_pad_begin(pcb_bxl_ctx_t *ctx) {} +void pcb_bxl_pad_end(pcb_bxl_ctx_t *ctx) { free(ctx->state.pin_name); } +void pcb_bxl_pad_set_style(pcb_bxl_ctx_t *ctx, const char *pstkname) { } Index: tags/2.3.0/tests/io_bxl/test_parse.c =================================================================== --- tags/2.3.0/tests/io_bxl/test_parse.c (nonexistent) +++ tags/2.3.0/tests/io_bxl/test_parse.c (revision 33253) @@ -0,0 +1,74 @@ +#include +#include + +#include "bxl.h" +#include "bxl_lex.h" +#include "bxl_gram.h" + +int verbose = 0; + +void pcb_bxl_error(pcb_bxl_ctx_t *ctx, pcb_bxl_STYPE tok, const char *s) +{ + fprintf(stderr, "(ignored) %s at %ld:%ld\n", s, tok.line, tok.first_col); +} + + +int main(int argc, char *argv[]) +{ + int chr, bad = 0; + pcb_bxl_ureglex_t lctx; + pcb_bxl_yyctx_t yyctx; + pcb_bxl_ctx_t bctx; + pcb_bxl_STYPE lval; + + pcb_bxl_lex_init(&lctx, pcb_bxl_rules); + pcb_bxl_parse_init(&yyctx); + + while((chr = fgetc(stdin)) > 0) { + int res = pcb_bxl_lex_char(&lctx, &lval, chr); + if (res == UREGLEX_MORE) + continue; + if (res >= 0) { + pcb_bxl_res_t yres; + + printf("token: %d ", res); + lval.line = lctx.loc_line[0]; + lval.first_col = lctx.loc_col[0]; + yres = pcb_bxl_parse(&yyctx, &bctx, res, &lval); + if ((bctx.in_error) && ((res == T_ID) || (res == T_QSTR))) + free(lval.un.s); + + printf("yres=%d\n", yres); + if (yres != 0) { + printf("Stopped at %ld:%ld\n", lval.line, lval.first_col); + bad = 1; + break; + } + } + if ((res >= 0) && verbose) { + int n; + printf("TOKEN: rule %d\n", res); + for(n = 0; n < lctx.num_rules; n++) { + ureglex_t *s = &lctx.state[n]; + printf(" %sres=%d", res == n ? "*" : " ", s->exec_state); + if (s->exec_state > 0) { + printf(" '%s' '%s'", s->bopat[0], s->eopat[0]); + printf(" at %ld:%ld\n", lctx.loc_line[0], lctx.loc_col[0]); + } + else + printf("\n"); + } +/* printf(" buf=%d/'%s'\n", ctx.buff_used, ctx.buff);*/ + } + else if (res < 0) + printf("ERROR %d\n", res); + pcb_bxl_lex_reset(&lctx); + } + + if (bad) + printf("Parse failed.\n"); + + pcb_bxl_parse(&yyctx, &bctx, 0, &lval); + + return 0; +} Index: tags/2.3.0/tests/menu/Makefile =================================================================== --- tags/2.3.0/tests/menu/Makefile (nonexistent) +++ tags/2.3.0/tests/menu/Makefile (revision 33253) @@ -0,0 +1,17 @@ +all: + +test: + @./test_patch.sh insert.lht 'MenuPatch(load, test, "insert.lht");' > insert.out + @diff insert.ref insert.out + @./test_patch.sh change.lht 'MenuPatch(load, test, "change.lht");' > change.out + @diff change.ref change.out + @./test_patch.sh remove.lht 'MenuPatch(load, test, "remove.lht");' > remove.out + @diff remove.ref remove.out + @./test_patch.sh overwrite_m.lht 'MenuPatch(load, test, "overwrite_m.lht");' > overwrite_m.out + @diff overwrite_m.ref overwrite_m.out + @./test_patch.sh overwrite_p.lht 'MenuPatch(load, test, "overwrite_p.lht");' > overwrite_p.out + @diff overwrite_p.ref overwrite_p.out + @./test_patch.sh new_submenu.lht 'MenuPatch(load, test, "new_submenu.lht");' > new_submenu.out + @diff new_submenu.ref new_submenu.out + +clean: Index: tags/2.3.0/tests/menu/change.lht =================================================================== --- tags/2.3.0/tests/menu/change.lht (nonexistent) +++ tags/2.3.0/tests/menu/change.lht (revision 33253) @@ -0,0 +1,9 @@ +ha:rnd-menu-patch-v1 { + prio=400 + li:patch { + ha:overwrite_menu_props { + path = /main_menu/File/Revert + ha:props { a={f;shiftr};} + } + } +} Index: tags/2.3.0/tests/menu/change.ref =================================================================== --- tags/2.3.0/tests/menu/change.ref (nonexistent) +++ tags/2.3.0/tests/menu/change.ref (revision 33253) @@ -0,0 +1,7 @@ + ha:Revert { +- action = Load(Revert,none) ++ a = {f;shiftr} + tip = {Revert to the layout stored on disk } +- a = {f;r} ++ action = Load(Revert,none) + } Index: tags/2.3.0/tests/menu/insert.lht =================================================================== --- tags/2.3.0/tests/menu/insert.lht (nonexistent) +++ tags/2.3.0/tests/menu/insert.lht (revision 33253) @@ -0,0 +1,17 @@ +ha:rnd-menu-v1 { + li:main_menu { + ha:File = { + li:submenu { + ha:hello = { checked=foo; action=bar } + } + } + } + + li:anchored { + ha:@testanchor { + li:submenu { + ha:hallo = { action=foobar() } + } + } + } +} \ No newline at end of file Index: tags/2.3.0/tests/menu/insert.ref =================================================================== --- tags/2.3.0/tests/menu/insert.ref (nonexistent) +++ tags/2.3.0/tests/menu/insert.ref (revision 33253) @@ -0,0 +1,11 @@ + END ++ ha:hello { ++ checked = foo ++ action = {bar } ++ } + } + @testanchor ++ ha:hallo { ++ action = {foobar() } ++ } + ha:POST { Index: tags/2.3.0/tests/menu/new_submenu.lht =================================================================== --- tags/2.3.0/tests/menu/new_submenu.lht (nonexistent) +++ tags/2.3.0/tests/menu/new_submenu.lht (revision 33253) @@ -0,0 +1,15 @@ +ha:rnd-menu-v1 { + li:main_menu { + ha:File { + li:submenu { + ha:demo { + li:submenu { + ha:hello = { a={h;h}; action=message(hello) } + ha:world = { a={h;w}; action=message(world) } + } + } + } + } + } +} + Index: tags/2.3.0/tests/menu/new_submenu.ref =================================================================== --- tags/2.3.0/tests/menu/new_submenu.ref (nonexistent) +++ tags/2.3.0/tests/menu/new_submenu.ref (revision 33253) @@ -0,0 +1,14 @@ + END ++ ha:demo { ++ li:submenu { ++ ha:hello { ++ a = {h;h} ++ action = {message(hello) } ++ } ++ ha:world { ++ a = {h;w} ++ action = {message(world) } ++ } ++ } ++ } + } Index: tags/2.3.0/tests/menu/overwrite_m.lht =================================================================== --- tags/2.3.0/tests/menu/overwrite_m.lht (nonexistent) +++ tags/2.3.0/tests/menu/overwrite_m.lht (revision 33253) @@ -0,0 +1,10 @@ +ha:rnd-menu-v1 { + li:main_menu { + ha:File { + li:submenu { + ha:Revert = { action=message(ERROR, "revert is too dangerous!") } + } + } + } +} + Index: tags/2.3.0/tests/menu/overwrite_m.ref =================================================================== --- tags/2.3.0/tests/menu/overwrite_m.ref (nonexistent) +++ tags/2.3.0/tests/menu/overwrite_m.ref (revision 33253) @@ -0,0 +1,7 @@ + ha:Revert { +- action = Load(Revert,none) +- tip = {Revert to the layout stored on disk } + a = {f;r} ++ tip = {Revert to the layout stored on disk } ++ action = {Load(Revert,none)message(ERROR, "revert is too dangerous!") } + } Index: tags/2.3.0/tests/menu/overwrite_p.lht =================================================================== --- tags/2.3.0/tests/menu/overwrite_p.lht (nonexistent) +++ tags/2.3.0/tests/menu/overwrite_p.lht (revision 33253) @@ -0,0 +1,15 @@ +ha:rnd-menu-v1 { + li:main_menu { + ha:File { + li:submenu { + ha:Revert { + li:submenu { + ha:hello = { a={h;h}; action=message(hello) } + ha:world = { a={h;w}; action=message(world) } + } + } + } + } + } +} + Index: tags/2.3.0/tests/menu/overwrite_p.ref =================================================================== --- tags/2.3.0/tests/menu/overwrite_p.ref (nonexistent) +++ tags/2.3.0/tests/menu/overwrite_p.ref (revision 33253) @@ -0,0 +1,15 @@ + ha:Revert { +- action = Load(Revert,none) +- tip = {Revert to the layout stored on disk } +- a = {f;r} ++ li:submenu { ++ ha:hello { ++ a = {h;h} ++ action = {message(hello) } ++ } ++ ha:world { ++ a = {h;w} ++ action = {message(world) } ++ } ++ } + } Index: tags/2.3.0/tests/menu/pcb-menu-base.lht =================================================================== --- tags/2.3.0/tests/menu/pcb-menu-base.lht (nonexistent) +++ tags/2.3.0/tests/menu/pcb-menu-base.lht (revision 33253) @@ -0,0 +1,194 @@ +# minimal menu file for testing menu patches + +ha:rnd-menu-v1 { + li:mouse { + li:left { + li:press = { Tool(Press) } + li:press-shift = { Tool(Press) } + li:press-ctrl = { Tool(Save); Tool(arrow); Tool(Restore); Tool(Press) } + li:release = { Tool(Release) } + li:release-shift = { Tool(Release) } + li:release-ctrl = { Tool(Release) } + } + li:middle { + li:press = { Pan(1) } + li:release = { Pan(0) } + } + li:right { + li:press = { Tool(Stroke) } + li:release = { Tool(Release); Popup(popup-obj, obj-type) } + li:shift-release = { Popup(popup-obj-misc) } + } + 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) } + } + } + + li:toolbar_static { + ha:via {tip={place a via on the board}} + ha:line {tip={draw a line segment (trace) on the board}} + ha:arc {tip={draw an arc segment (trace) on the board}} + ha:text {tip={draw text on the board}} + ha:rectangle {tip={draw a rectangular polygon on the board}} + ha:poly {tip={draw a polygon on the board}} + ha:polyhole {tip={cut out a hole from existing polygons on the board}} + ha:buffer {tip={paste the current buffer on the board}} + ha:remove {tip={remove an object from the board}} + ha:rotate {tip={rotate an object on the board}} + ha:insert {tip={insert a point in a trace or polygon contour}} + ha:thermal {tip={change thermal connectivity of a pin or via}} + ha:arrow {tip={switch to arrow mode}} + ha:lock {tip={lock or unlock objects on the board}} + } + + li:main_menu { + + ha:File { + li:submenu { + ha:Start New Layout = { li:a={{f;n}; {Ctrln};}; action=New() } + ha:Revert = { a={f;r}; action=Load(Revert,none); tip=Revert to the layout stored on disk } + - + ha:Load layout... = { li:a={{f;o};{f;l};} action=Load(Layout); tip=Load a layout from a file } + - + ha:Save Layout = { li:a={{f;s}; {Ctrls};}; action=Save(Layout); tip=Saves current layout } + ha:Save Layout As... = { li:a={{f;a}; {Shift Ctrls};}; action=Save(LayoutAs); tip=Saves current layout into a new file } + - + END + } + } + + ha:Stock-Anchors { + li:submenu { + + ha:layerkeys { + li:submenu { + ha:pre {} + te:@layerkeys + ha:post {} + } + } + + ha:layerpick { + li:submenu { + ha:pre {} + te:@layerpick + ha:post {} + } + } + + ha:layerview { + li:submenu { + ha:pre {} + te:@layerview + ha:post {} + } + } + + ha:grid { + li:submenu { + ha:pre {} + te:@grid + ha:post {} + } + } + + ha:routestyles { + li:submenu { + ha:pre {} + te:@routestyles + ha:post {} + } + } + + ha:import { + li:submenu { + ha:pre {} + te:@import_top + - + te:@import_sch + - + te:@import_geo + ha:post {} + } + } + + ha:autoroute { + li:submenu { + ha:pre {} + te:@autoroute + ha:post {} + } + } + + ha:scripts { + li:submenu { + ha:pre {} + te:@scripts + ha:post {} + } + } + + ha:feature_plugins { + li:submenu { + ha:pre {} + te:@feature_plugins + ha:post {} + } + } + + ha:indications { + li:submenu { + ha:pre {} + te:@indications + ha:post {} + } + } + + ha:indications { + li:submenu { + ha:pre {} + te:@indications + ha:post {} + } + } + } + } + + + ha:Test-Anchors { + li:submenu { + ha:indications { + li:submenu { + ha:PRE {} + te:@testanchor + ha:POST {} + } + } + } + } + + } # main menu + + li:popups { +# context sensitive right click: popup per object type under the cursor + + ha:popup-obj-line { + li:submenu { + ha:Edit properties { action=propedit(object) } + ha:Edit flags... { action=FlagEdit() } + ha:Set Same Style { action=SetSame() } + - + ha:Remove line { li:action={Tool(Save); Tool(remove); Tool(Press); Tool(Restore)} } + ha:Copy to buffer { li:action={Unselect(All); Select(object); PasteBuffer(Clear); PasteBuffer(AddSelected); Unselect(All); Tool(buffer) } } + ha:Move to current layer { action=MoveToCurrentLayer(object) } + } + } + } # popups +} # root Index: tags/2.3.0/tests/menu/remove.lht =================================================================== --- tags/2.3.0/tests/menu/remove.lht (nonexistent) +++ tags/2.3.0/tests/menu/remove.lht (revision 33253) @@ -0,0 +1,8 @@ +ha:rnd-menu-patch-v1 { + prio=400 + li:patch { + ha:remove_menu { + path = /main_menu/File/Revert + } + } +} Index: tags/2.3.0/tests/menu/remove.ref =================================================================== --- tags/2.3.0/tests/menu/remove.ref (nonexistent) +++ tags/2.3.0/tests/menu/remove.ref (revision 33253) @@ -0,0 +1,7 @@ + } +- ha:Revert { +- action = Load(Revert,none) +- tip = {Revert to the layout stored on disk } +- a = {f;r} +- } + - Index: tags/2.3.0/tests/menu/test_patch.sh =================================================================== --- tags/2.3.0/tests/menu/test_patch.sh (nonexistent) +++ tags/2.3.0/tests/menu/test_patch.sh (revision 33253) @@ -0,0 +1,30 @@ +#!/bin/sh + +SRC=../../src +CFG="-c rc/library_search_paths=dummy_lib -c rc/quiet=1" + +# call: +# insert.lht 'MenuPatch(load, test, "insert.lht");' + +rm d0.lht d1.lht >/dev/null 2>&1 + +cp pcb-menu-base.lht $1 $SRC +( +cd $SRC +mkdir dummy_lib +echo ' + MenuDebug(force-enable); + MenuDebug(save, "d0.lht"); +'$2' + MenuDebug(save, "d1.lht"); +' | ./pcb-rnd $CFG -c rc/menu_file=base --gui batch 2>&1 | grep -v "^menu debug" +rmdir dummy_lib +) + +mv $SRC/d0.lht . +mv $SRC/d1.lht . +rm $SRC/pcb-menu-base.lht $SRC/$1 + +diff -U1 d0.lht d1.lht | grep "^[ +-][^+-]" + +rm d0.lht d1.lht >/dev/null 2>&1 Property changes on: tags/2.3.0/tests/menu/test_patch.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/netlist2/rat_arc_arc.lht =================================================================== --- tags/2.3.0/tests/netlist2/rat_arc_arc.lht (nonexistent) +++ tags/2.3.0/tests/netlist2/rat_arc_arc.lht (revision 33253) @@ -0,0 +1,596 @@ +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 = 800.0mil + y = 800.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.100 { + ha:attributes { + refdes=U0 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.55 { + proto=0; x=100.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.21 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.24 { + x1=100.0mil; y1=325.0mil; x2=3.54mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.27 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.30 { + string=%a.parent.refdes%; x=50.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + ha:subc.101 { + ha:attributes { + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.56 { + proto=0; x=725.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.47 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.50 { + x1=725.0mil; y1=325.0mil; x2=19.415mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.53 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.56 { + string=%a.parent.refdes%; x=675.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:arc.114 { + x=100.0mil; y=100.0mil; width=225.0mil; height=225.0mil; astart=90; adelta=90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.115 { + x=725.0mil; y=150.0mil; width=175.0mil; height=175.0mil; astart=90; adelta=-90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:input { + ha:net1 { + li:conn { U0-1; U1-1; } + } + } + } + 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/2.3.0/tests/netlist2/rat_arc_pstk.lht =================================================================== --- tags/2.3.0/tests/netlist2/rat_arc_pstk.lht (nonexistent) +++ tags/2.3.0/tests/netlist2/rat_arc_pstk.lht (revision 33253) @@ -0,0 +1,590 @@ +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 = 800.0mil + y = 800.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.100 { + ha:attributes { + refdes=U0 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.55 { + proto=0; x=100.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.21 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.24 { + x1=100.0mil; y1=325.0mil; x2=3.54mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.27 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.30 { + string=%a.parent.refdes%; x=50.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + ha:subc.101 { + ha:attributes { + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.56 { + proto=0; x=725.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.47 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.50 { + x1=725.0mil; y1=325.0mil; x2=19.415mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.53 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.56 { + string=%a.parent.refdes%; x=675.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:arc.114 { + x=100.0mil; y=75.0mil; width=250.0mil; height=250.0mil; astart=90; adelta=90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:input { + ha:net1 { + li:conn { U0-1; U1-1; } + } + } + } + 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/2.3.0/tests/netlist2/rat_line_arc.lht =================================================================== --- tags/2.3.0/tests/netlist2/rat_line_arc.lht (nonexistent) +++ tags/2.3.0/tests/netlist2/rat_line_arc.lht (revision 33253) @@ -0,0 +1,596 @@ +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 = 800.0mil + y = 800.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.100 { + ha:attributes { + refdes=U0 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.55 { + proto=0; x=100.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.21 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.24 { + x1=100.0mil; y1=325.0mil; x2=3.54mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.27 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.30 { + string=%a.parent.refdes%; x=50.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + ha:subc.101 { + ha:attributes { + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.56 { + proto=0; x=725.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.47 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.50 { + x1=725.0mil; y1=325.0mil; x2=19.415mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.53 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.56 { + string=%a.parent.refdes%; x=675.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:line.130 { + x1=100.0mil; y1=325.0mil; x2=375.0mil; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:arc.115 { + x=725.0mil; y=150.0mil; width=175.0mil; height=175.0mil; astart=90; adelta=-90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:input { + ha:net1 { + li:conn { U0-1; U1-1; } + } + } + } + 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/2.3.0/tests/netlist2/rat_line_line.lht =================================================================== --- tags/2.3.0/tests/netlist2/rat_line_line.lht (nonexistent) +++ tags/2.3.0/tests/netlist2/rat_line_line.lht (revision 33253) @@ -0,0 +1,596 @@ +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 = 800.0mil + y = 800.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.100 { + ha:attributes { + refdes=U0 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.55 { + proto=0; x=100.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.21 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.24 { + x1=100.0mil; y1=325.0mil; x2=3.54mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.27 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.30 { + string=%a.parent.refdes%; x=50.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + ha:subc.101 { + ha:attributes { + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.56 { + proto=0; x=725.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.47 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.50 { + x1=725.0mil; y1=325.0mil; x2=19.415mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.53 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.56 { + string=%a.parent.refdes%; x=675.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:line.114 { + x1=100.0mil; y1=325.0mil; x2=525.0mil; y2=225.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:line.158 { + x1=725.0mil; y1=325.0mil; x2=575.0mil; y2=125.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:input { + ha:net1 { + li:conn { U0-1; U1-1; } + } + } + } + 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/2.3.0/tests/netlist2/rat_line_poly.lht =================================================================== --- tags/2.3.0/tests/netlist2/rat_line_poly.lht (nonexistent) +++ tags/2.3.0/tests/netlist2/rat_line_poly.lht (revision 33253) @@ -0,0 +1,609 @@ +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 = 800.0mil + y = 800.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.100 { + ha:attributes { + refdes=U0 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.55 { + proto=0; x=100.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.21 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.24 { + x1=100.0mil; y1=325.0mil; x2=3.54mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.27 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.30 { + string=%a.parent.refdes%; x=50.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + ha:subc.101 { + ha:attributes { + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.56 { + proto=0; x=725.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:0 { + on + diag + round + noshape + } + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.47 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.50 { + x1=725.0mil; y1=325.0mil; x2=19.415mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.53 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.56 { + string=%a.parent.refdes%; x=675.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:line.130 { + x1=100.0mil; y1=325.0mil; x2=375.0mil; y2=200.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.147 { clearance=40.0mil; + li:geometry { + ta:contour { + { 775.0mil; 400.0mil } + { 450.0mil; 400.0mil } + { 775.0mil; 200.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:input { + ha:net1 { + li:conn { U0-1; U1-1; } + } + } + } + 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/2.3.0/tests/netlist2/rat_line_pstk.lht =================================================================== --- tags/2.3.0/tests/netlist2/rat_line_pstk.lht (nonexistent) +++ tags/2.3.0/tests/netlist2/rat_line_pstk.lht (revision 33253) @@ -0,0 +1,590 @@ +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 = 800.0mil + y = 800.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.100 { + ha:attributes { + refdes=U0 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.55 { + proto=0; x=100.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.21 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.24 { + x1=100.0mil; y1=325.0mil; x2=3.54mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.27 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.30 { + string=%a.parent.refdes%; x=50.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + ha:subc.101 { + ha:attributes { + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.56 { + proto=0; x=725.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.47 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.50 { + x1=725.0mil; y1=325.0mil; x2=19.415mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.53 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.56 { + string=%a.parent.refdes%; x=675.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:line.114 { + x1=100.0mil; y1=325.0mil; x2=525.0mil; y2=225.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:input { + ha:net1 { + li:conn { U0-1; U1-1; } + } + } + } + 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/2.3.0/tests/netlist2/rat_poly_arc.lht =================================================================== --- tags/2.3.0/tests/netlist2/rat_poly_arc.lht (nonexistent) +++ tags/2.3.0/tests/netlist2/rat_poly_arc.lht (revision 33253) @@ -0,0 +1,609 @@ +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 = 800.0mil + y = 800.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.100 { + ha:attributes { + refdes=U0 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.55 { + proto=0; x=100.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:0 { + on + diag + round + noshape + } + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.21 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.24 { + x1=100.0mil; y1=325.0mil; x2=3.54mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.27 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.30 { + string=%a.parent.refdes%; x=50.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + ha:subc.101 { + ha:attributes { + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.56 { + proto=0; x=725.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.47 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.50 { + x1=725.0mil; y1=325.0mil; x2=19.415mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.53 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.56 { + string=%a.parent.refdes%; x=675.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:arc.132 { + x=725.0mil; y=500.0mil; width=175.0mil; height=175.0mil; astart=-90; adelta=90; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + ha:polygon.114 { clearance=40.0mil; + li:geometry { + ta:contour { + { 50.0mil; 375.0mil } + { 500.0mil; 375.0mil } + { 50.0mil; 250.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:input { + ha:net1 { + li:conn { U0-1; U1-1; } + } + } + } + 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/2.3.0/tests/netlist2/rat_poly_poly.lht =================================================================== --- tags/2.3.0/tests/netlist2/rat_poly_poly.lht (nonexistent) +++ tags/2.3.0/tests/netlist2/rat_poly_poly.lht (revision 33253) @@ -0,0 +1,622 @@ +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 = 800.0mil + y = 800.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.100 { + ha:attributes { + refdes=U0 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.55 { + proto=0; x=100.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:0 { + on + diag + round + noshape + } + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.21 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.24 { + x1=100.0mil; y1=325.0mil; x2=3.54mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.27 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.30 { + string=%a.parent.refdes%; x=50.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + ha:subc.101 { + ha:attributes { + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.56 { + proto=0; x=725.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:0 { + on + diag + round + noshape + } + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.47 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.50 { + x1=725.0mil; y1=325.0mil; x2=19.415mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.53 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.56 { + string=%a.parent.refdes%; x=675.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:polygon.114 { clearance=40.0mil; + li:geometry { + ta:contour { + { 50.0mil; 375.0mil } + { 500.0mil; 375.0mil } + { 50.0mil; 250.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + ha:polygon.132 { clearance=40.0mil; + li:geometry { + ta:contour { + { 775.0mil; 375.0mil } + { 450.0mil; 275.0mil } + { 775.0mil; 200.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:input { + ha:net1 { + li:conn { U0-1; U1-1; } + } + } + } + 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/2.3.0/tests/netlist2/rat_poly_poly2.lht =================================================================== --- tags/2.3.0/tests/netlist2/rat_poly_poly2.lht (nonexistent) +++ tags/2.3.0/tests/netlist2/rat_poly_poly2.lht (revision 33253) @@ -0,0 +1,621 @@ +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 = 800.0mil + y = 800.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.100 { + ha:attributes { + refdes=U0 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.55 { + proto=0; x=375.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:0 { + diag + round + noshape + } + li:2 { + on + diag + round + noshape + } + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.21 { + x1=375.0mil; y1=325.0mil; x2=375.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.24 { + x1=375.0mil; y1=325.0mil; x2=10.525mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.27 { + x1=375.0mil; y1=325.0mil; x2=375.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.30 { + string=%a.parent.refdes%; x=325.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + ha:subc.101 { + ha:attributes { + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.56 { + proto=0; x=725.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:0 { + on + diag + round + noshape + } + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.47 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.50 { + x1=725.0mil; y1=325.0mil; x2=19.415mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.53 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.56 { + string=%a.parent.refdes%; x=675.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:polygon.162 { clearance=40.0mil; + li:geometry { + ta:contour { + { 25.0mil; 50.0mil } + { 775.0mil; 50.0mil } + { 775.0mil; 625.0mil } + { 25.0mil; 625.0mil } + } + ta:hole { + { 125.0mil; 150.0mil } + { 125.0mil; 575.0mil } + { 600.0mil; 575.0mil } + { 600.0mil; 150.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:input { + ha:net1 { + li:conn { U0-1; U1-1; } + } + } + } + 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/2.3.0/tests/netlist2/rat_poly_pstk.lht =================================================================== --- tags/2.3.0/tests/netlist2/rat_poly_pstk.lht (nonexistent) +++ tags/2.3.0/tests/netlist2/rat_poly_pstk.lht (revision 33253) @@ -0,0 +1,603 @@ +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 = 800.0mil + y = 800.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.100 { + ha:attributes { + refdes=U0 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.55 { + proto=0; x=100.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + li:0 { + on + diag + round + noshape + } + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.21 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.24 { + x1=100.0mil; y1=325.0mil; x2=3.54mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.27 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.30 { + string=%a.parent.refdes%; x=50.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + ha:subc.101 { + ha:attributes { + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.56 { + proto=0; x=725.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.47 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.50 { + x1=725.0mil; y1=325.0mil; x2=19.415mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.53 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.56 { + string=%a.parent.refdes%; x=675.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + ha:polygon.114 { clearance=40.0mil; + li:geometry { + ta:contour { + { 50.0mil; 375.0mil } + { 500.0mil; 375.0mil } + { 50.0mil; 250.0mil } + } + } + + ha:flags { + clearpoly=1 + } + } + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:input { + ha:net1 { + li:conn { U0-1; U1-1; } + } + } + } + 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/2.3.0/tests/netlist2/rat_pstk_pstk.lht =================================================================== --- tags/2.3.0/tests/netlist2/rat_pstk_pstk.lht (nonexistent) +++ tags/2.3.0/tests/netlist2/rat_pstk_pstk.lht (revision 33253) @@ -0,0 +1,584 @@ +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 = 800.0mil + y = 800.0mil + } + ha:grid { + spacing = 25.0mil + offs_x = 0.0 + offs_y = 0.0 + } + } + + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:subc.100 { + ha:attributes { + refdes=U0 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.55 { + proto=0; x=100.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.21 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=origin + } + } + ha:line.24 { + x1=100.0mil; y1=325.0mil; x2=3.54mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=x + } + } + ha:line.27 { + x1=100.0mil; y1=325.0mil; x2=100.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:flags { + selected=1 + } + + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.30 { + string=%a.parent.refdes%; x=50.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + ha:subc.101 { + ha:attributes { + refdes=U1 + } + ha:data { + li:padstack_prototypes { + + ha:ps_proto_v6.0 { + hdia=31.5mil; hplated=1; htop=0; hbottom=0; + li:shape { + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + top = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + bottom = 1 + copper = 1 + } + clearance=0.0 + } + + ha:ps_shape_v4 { + ha:ps_circ { x=0.0; y=0.0; dia=2.0mm; } + ha:combining { } + ha:layer_mask { + copper = 1 + intern = 1 + } + clearance=0.0 + } + } + } + } + + li:objects { + ha:padstack_ref.56 { + proto=0; x=725.0mil; y=325.0mil; rot=0.000000; xmirror=0; smirror=0; clearance=20.0mil; + ha:flags { + clearline=1 + } + + li:thermal { + } + + ha:attributes { + term=1 + } + } + } + li:layers { + + ha:subc-aux { + lid=0 + ha:combining { } + + li:objects { + ha:line.47 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=origin + } + } + ha:line.50 { + x1=725.0mil; y1=325.0mil; x2=19.415mm; y2=325.0mil; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=x + } + } + ha:line.53 { + x1=725.0mil; y1=325.0mil; x2=725.0mil; y2=9.255mm; thickness=0.1mm; clearance=0.0; + ha:attributes { + subc-role=y + } + } + } + ha:type { + top = 1 + misc = 1 + virtual = 1 + } + } + + ha:top-silk { + lid=1 + ha:combining { } + + li:objects { + ha:text.56 { + string=%a.parent.refdes%; x=675.0mil; y=400.0mil; scale=100; fid=0; + ha:flags { + dyntext=1 + floater=1 + } + rot = 0.000000 + } + } + ha:type { + silk = 1 + top = 1 + } + } + } + } + uid = EwibItjsh9q72bL63V0AAAAB + } + } + li:layers { + + ha:top-sig { + lid=0 + group=3 + ha:combining { } + + li:objects { + } + color = {#8b2323} + } + + ha:bottom-sig { + lid=1 + group=10 + ha:combining { } + + li:objects { + } + color = {#3a5fcd} + } + + ha:top-gnd { + lid=2 + group=3 + ha:combining { } + + li:objects { + } + 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:netlists { + li:input { + ha:net1 { + li:conn { U0-1; U1-1; } + } + } + } + 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/2.3.0/tests/orig/README.txt =================================================================== --- tags/2.3.0/tests/orig/README.txt (nonexistent) +++ tags/2.3.0/tests/orig/README.txt (revision 33253) @@ -0,0 +1,108 @@ +This is the old test suite inherited from mainline. + +Please read this file before making any modifications to the test suite. + +********************************************************************** +********************************************************************** +* Overview +********************************************************************** +********************************************************************** + +The test suite is based on a shell script, 'run_tests.sh', which +calls pcb to export various test case layouts to different output +formats. The tests to be run are defined in the file 'tests.list'. +The 'tests.list' file defines the export command line options passed +to pcb, the name of the input .pcb file, and the names and file types +for the expected output files. + +After a particular test is run, the output files are compared against +a set of "golden" files which are in the golden/ subdirectory. +ALL CHANGES TO THE GOLDEN FILES MUST BE HAND VERIFIED. This point +can not be emphasized too much. + +While this testsuite is clearly not comprehensive (the GUI is totally +left out of the testing for example), it is still better than nothing +and can help detect newly introduced bugs. + +********************************************************************** +********************************************************************** +* Running an existing test +********************************************************************** +********************************************************************** + +To run all of the tests defined in tests.list run: + + ./run_tests.sh + +To only run a specific test or tests, then simply list them by name +on the command line like: + + ./run_tests.sh test_one test_two ... + +********************************************************************** +********************************************************************** +* Updating existing "golden" files +********************************************************************** +********************************************************************** + +./run_tests.sh --regen + +will regenerate the golden file for . If you are generating +ASCII output such as BOMs or RS-274X files, then use the diff(3) program +to examine all differences. If you are generating a graphics file +such as a PNG, then I suggest saving off a copy and using ImageMagick +to look for the differences visually. The run_tests.sh script has +examples of comparing .png files. Make sure the changes are only +the expected ones and then check the new files back into svn. Do +not blindly update these files as that defeats the purpose of the tests. + +********************************************************************** +********************************************************************** +* Adding New Tests +********************************************************************** +********************************************************************** + +---------------------------------------------------------------------- +Create input files +---------------------------------------------------------------------- + +Create a *small* layout input file and put it in the inputs/ +directory. The goal is to have a file which tests one particular aspect +of the capabilities of pcb. + +---------------------------------------------------------------------- +Add to tests.list +---------------------------------------------------------------------- + +Add an entry to the tests.list file for your new tests. Use existing +entries as an example. + +---------------------------------------------------------------------- +Generate the reference files +---------------------------------------------------------------------- + +Generate the reference files for your new tests using the following + +./run_tests.sh --regen + +where is the name of your new test from tests.list. If you +are adding multiple tests, then you can list them all on the same +command line. + +*IMPORTANT* +Verify that the generated .png files for your new tests are correct. These +files will have been placed in the golden/ subdirectory. + +---------------------------------------------------------------------- +Update Makefile.am's +---------------------------------------------------------------------- + +Update inputs/Makefile.am and golden/Makefile.am to include your new +files. If you added new Makefile.am's then be sure to also update +configure.ac at the top level of the source tree. + +---------------------------------------------------------------------- +Add the new files to svn +---------------------------------------------------------------------- + + Index: tags/2.3.0/tests/orig/golden/hid_bom1/bom_general.bom =================================================================== --- tags/2.3.0/tests/orig/golden/hid_bom1/bom_general.bom (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_bom1/bom_general.bom (revision 33253) @@ -0,0 +1,10 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: Wed Jun 24 21:42:21 2009 UTC +# Author: Dan McMahill +# Title: Basic BOM/XY Test - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +8,"Standard SMT resistor, capacitor etc","RESC3216N",R90_TOP R180_TOP R270_TOP R0_TOP R270_BOT R180_BOT R90_BOT R0_BOT +8,"Dual in-line package, narrow (300 mil)","DIP8",UDIP90_TOP UDIP180_TOP UDIP270_TOP UDIP0_TOP UDIP270_BOT UDIP180_BOT UDIP90_BOT UDIP0_BOT +8,"Small outline package, narrow (150mil)","SO8",USO90_TOP USO180_TOP USO270_TOP USO0_TOP USO270_BOT USO180_BOT USO90_BOT USO0_BOT Index: tags/2.3.0/tests/orig/golden/hid_bom2/test.bom =================================================================== --- tags/2.3.0/tests/orig/golden/hid_bom2/test.bom (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_bom2/test.bom (revision 33253) @@ -0,0 +1,10 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: Wed Jun 24 21:42:22 2009 UTC +# Author: Dan McMahill +# Title: Basic BOM/XY Test - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +8,"Standard SMT resistor, capacitor etc","RESC3216N",R90_TOP R180_TOP R270_TOP R0_TOP R270_BOT R180_BOT R90_BOT R0_BOT +8,"Dual in-line package, narrow (300 mil)","DIP8",UDIP90_TOP UDIP180_TOP UDIP270_TOP UDIP0_TOP UDIP270_BOT UDIP180_BOT UDIP90_BOT UDIP0_BOT +8,"Small outline package, narrow (150mil)","SO8",USO90_TOP USO180_TOP USO270_TOP USO0_TOP USO270_BOT USO180_BOT USO90_BOT USO0_BOT Index: tags/2.3.0/tests/orig/golden/hid_bom3/bom_general.bom =================================================================== --- tags/2.3.0/tests/orig/golden/hid_bom3/bom_general.bom (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_bom3/bom_general.bom (revision 33253) @@ -0,0 +1,10 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: Wed Jun 24 21:42:22 2009 UTC +# Author: Dan McMahill +# Title: Basic BOM/XY Test - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +8,"Standard SMT resistor, capacitor etc","RESC3216N",R90_TOP R180_TOP R270_TOP R0_TOP R270_BOT R180_BOT R90_BOT R0_BOT +8,"Dual in-line package, narrow (300 mil)","DIP8",UDIP90_TOP UDIP180_TOP UDIP270_TOP UDIP0_TOP UDIP270_BOT UDIP180_BOT UDIP90_BOT UDIP0_BOT +8,"Small outline package, narrow (150mil)","SO8",USO90_TOP USO180_TOP USO270_TOP USO0_TOP USO270_BOT USO180_BOT USO90_BOT USO0_BOT Index: tags/2.3.0/tests/orig/golden/hid_bom4/bom_general.bom =================================================================== --- tags/2.3.0/tests/orig/golden/hid_bom4/bom_general.bom (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_bom4/bom_general.bom (revision 33253) @@ -0,0 +1,10 @@ +# $Id$ +# PcbBOM Version 1.0 +# Date: Wed Jun 24 21:42:23 2009 UTC +# Author: Dan McMahill +# Title: Basic BOM/XY Test - PCB BOM +# Quantity, Description, Value, RefDes +# -------------------------------------------- +8,"Standard SMT resistor, capacitor etc","RESC3216N",R90_TOP R180_TOP R270_TOP R0_TOP R270_BOT R180_BOT R90_BOT R0_BOT +8,"Dual in-line package, narrow (300 mil)","DIP8",UDIP90_TOP UDIP180_TOP UDIP270_TOP UDIP0_TOP UDIP270_BOT UDIP180_BOT UDIP90_BOT UDIP0_BOT +8,"Small outline package, narrow (150mil)","SO8",USO90_TOP USO180_TOP USO270_TOP USO0_TOP USO270_BOT USO180_BOT USO90_BOT USO0_BOT Index: tags/2.3.0/tests/orig/golden/hid_gcode1/gcode_oneline.gcode.bottom.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode1/gcode_oneline.gcode.bottom.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode1/gcode_oneline.gcode.bottom.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:31:54 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X27.770667 Y13.546667 (start point) +G1 Z#101 +G1 X27.559000 Y13.462000 +G1 X27.305000 Y13.292667 +G1 X7.450667 Y13.292667 +G1 X7.196667 Y13.081000 +G1 X6.985000 Y12.827000 +G1 X6.985000 Y12.530667 +G1 X7.196667 Y12.276667 +G1 X7.450667 Y12.065000 +G1 X27.305000 Y12.065000 +G1 X27.643667 Y11.853333 +G1 X28.194000 Y11.853333 +G1 X28.532667 Y12.065000 +G1 X28.744333 Y12.403667 +G1 X28.744333 Y12.954000 +G1 X28.532667 Y13.292667 +G1 X28.194000 Y13.504333 +G1 X27.770667 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode1/gcode_oneline.gcode.drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode1/gcode_oneline.gcode.drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode1/gcode_oneline.gcode.drill.cnc (revision 33253) @@ -0,0 +1,12 @@ +(Created by G-code exporter) +(drill file: 1 drills) +( Tue Mar 9 17:31:54 2010 ) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-2.000000 (drill depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G81 X27.940000 Y12.700000 Z#101 R#100 +M5 M9 M2 +(end, total distance 0.00mm = 0.00in) Index: tags/2.3.0/tests/orig/golden/hid_gcode1/gcode_oneline.gcode.top.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode1/gcode_oneline.gcode.top.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode1/gcode_oneline.gcode.top.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:31:51 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X22.733000 Y13.546667 (start point) +G1 Z#101 +G1 X22.521333 Y13.462000 +G1 X22.267333 Y13.292667 +G1 X2.413000 Y13.292667 +G1 X2.159000 Y13.081000 +G1 X1.947333 Y12.827000 +G1 X1.947333 Y12.530667 +G1 X2.159000 Y12.276667 +G1 X2.413000 Y12.065000 +G1 X22.267333 Y12.065000 +G1 X22.606000 Y11.853333 +G1 X23.156333 Y11.853333 +G1 X23.495000 Y12.065000 +G1 X23.706667 Y12.403667 +G1 X23.706667 Y12.954000 +G1 X23.495000 Y13.292667 +G1 X23.156333 Y13.504333 +G1 X22.733000 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode10/gcode_oneline.gcode.bottom.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode10/gcode_oneline.gcode.bottom.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode10/gcode_oneline.gcode.bottom.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:45:32 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=0.002000 (safe Z) +#101=-0.000050 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X27.770667 Y13.462000 (start point) +G1 Z#101 +G1 X27.516667 Y13.335000 +G1 X27.347333 Y13.208000 +G1 X7.408333 Y13.165667 +G1 X7.112000 Y12.869333 +G1 X7.112000 Y12.488333 +G1 X7.408333 Y12.192000 +G1 X27.347333 Y12.149667 +G1 X27.643667 Y11.938000 +G1 X27.940000 Y11.895667 +G1 X28.278667 Y11.980333 +G1 X28.532667 Y12.192000 +G1 X28.702000 Y12.530667 +G1 X28.702000 Y12.827000 +G1 X28.532667 Y13.165667 +G1 X28.321000 Y13.335000 +G1 X28.024667 Y13.462000 +G1 X27.770667 Y13.462000 +G0 Z#100 +(polygon end, distance 44.84) +(end, total distance 44.84mm = 1.77in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode10/gcode_oneline.gcode.drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode10/gcode_oneline.gcode.drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode10/gcode_oneline.gcode.drill.cnc (revision 33253) @@ -0,0 +1,12 @@ +(Created by G-code exporter) +(drill file: 1 drills) +( Tue Mar 9 17:45:32 2010 ) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=0.002000 (safe Z) +#101=-0.002000 (drill depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G81 X27.940000 Y12.700000 Z#101 R#100 +M5 M9 M2 +(end, total distance 0.00mm = 0.00in) Index: tags/2.3.0/tests/orig/golden/hid_gcode10/gcode_oneline.gcode.top.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode10/gcode_oneline.gcode.top.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode10/gcode_oneline.gcode.top.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:45:28 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=0.002000 (safe Z) +#101=-0.000050 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X22.733000 Y13.462000 (start point) +G1 Z#101 +G1 X22.479000 Y13.335000 +G1 X22.309667 Y13.208000 +G1 X2.370667 Y13.165667 +G1 X2.074333 Y12.869333 +G1 X2.074333 Y12.488333 +G1 X2.370667 Y12.192000 +G1 X22.309667 Y12.149667 +G1 X22.606000 Y11.938000 +G1 X22.902333 Y11.895667 +G1 X23.241000 Y11.980333 +G1 X23.495000 Y12.192000 +G1 X23.664333 Y12.530667 +G1 X23.664333 Y12.827000 +G1 X23.495000 Y13.165667 +G1 X23.283333 Y13.335000 +G1 X22.987000 Y13.462000 +G1 X22.733000 Y13.462000 +G0 Z#100 +(polygon end, distance 44.84) +(end, total distance 44.84mm = 1.77in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode11/gcode_oneline.gcode.bottom.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode11/gcode_oneline.gcode.bottom.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode11/gcode_oneline.gcode.bottom.cnc (revision 33253) @@ -0,0 +1,49 @@ +(Created by G-code exporter) +( Tue Mar 9 17:45:55 2010 ) +(600 dpi) +(Unit: inch) +(Board size: 2.00x1.00 inches) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G20 G90 G64 P0.003 M3 S3000 M7 F1 +G0 Z#100 +(polygon 1) +G0 X1.085000 Y0.630000 (start point) +G1 Z#101 +G1 X1.063333 Y0.625000 +G1 X1.055000 Y0.621667 +G1 X0.276667 Y0.618333 +G1 X0.251667 Y0.610000 +G1 X0.230000 Y0.598333 +G1 X0.200000 Y0.568333 +G1 X0.188333 Y0.546667 +G1 X0.180000 Y0.521667 +G1 X0.180000 Y0.476667 +G1 X0.188333 Y0.451667 +G1 X0.200000 Y0.430000 +G1 X0.230000 Y0.400000 +G1 X0.251667 Y0.388333 +G1 X0.276667 Y0.380000 +G1 X1.055000 Y0.376667 +G1 X1.068333 Y0.371667 +G1 X1.093333 Y0.368333 +G1 X1.121667 Y0.370000 +G1 X1.140000 Y0.375000 +G1 X1.171667 Y0.390000 +G1 X1.191667 Y0.406667 +G1 X1.208333 Y0.426667 +G1 X1.223333 Y0.458333 +G1 X1.228333 Y0.478333 +G1 X1.228333 Y0.520000 +G1 X1.223333 Y0.540000 +G1 X1.208333 Y0.571667 +G1 X1.191667 Y0.591667 +G1 X1.171667 Y0.608333 +G1 X1.140000 Y0.623333 +G1 X1.121667 Y0.628333 +G1 X1.085000 Y0.630000 +G0 Z#100 +(polygon end, distance 2.39) +(end, total distance 60.74mm = 2.39in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode11/gcode_oneline.gcode.drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode11/gcode_oneline.gcode.drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode11/gcode_oneline.gcode.drill.cnc (revision 33253) @@ -0,0 +1,12 @@ +(Created by G-code exporter) +(drill file: 1 drills) +( Tue Mar 9 17:45:55 2010 ) +(Unit: inch) +(Board size: 2.00x1.00 inches) +#100=2.000000 (safe Z) +#101=-2.000000 (drill depth) +(---------------------------------) +G17 G20 G90 G64 P0.003 M3 S3000 M7 F1 +G81 X1.100000 Y0.500000 Z#101 R#100 +M5 M9 M2 +(end, total distance 0.00mm = 0.00in) Index: tags/2.3.0/tests/orig/golden/hid_gcode11/gcode_oneline.gcode.top.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode11/gcode_oneline.gcode.top.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode11/gcode_oneline.gcode.top.cnc (revision 33253) @@ -0,0 +1,45 @@ +(Created by G-code exporter) +( Tue Mar 9 17:45:43 2010 ) +(600 dpi) +(Unit: inch) +(Board size: 2.00x1.00 inches) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G20 G90 G64 P0.003 M3 S3000 M7 F1 +G0 Z#100 +(polygon 1) +G0 X0.886667 Y0.630000 (start point) +G1 Z#101 +G1 X0.865000 Y0.625000 +G1 X0.856667 Y0.621667 +G1 X0.078333 Y0.618333 +G1 X0.053333 Y0.610000 +G1 X0.031667 Y0.598333 +G1 X0.000000 Y0.566667 +G1 X0.000000 Y0.431667 +G1 X0.031667 Y0.400000 +G1 X0.053333 Y0.388333 +G1 X0.078333 Y0.380000 +G1 X0.856667 Y0.376667 +G1 X0.870000 Y0.371667 +G1 X0.895000 Y0.368333 +G1 X0.923333 Y0.370000 +G1 X0.941667 Y0.375000 +G1 X0.973333 Y0.390000 +G1 X0.993333 Y0.406667 +G1 X1.010000 Y0.426667 +G1 X1.025000 Y0.458333 +G1 X1.030000 Y0.478333 +G1 X1.030000 Y0.520000 +G1 X1.025000 Y0.540000 +G1 X1.010000 Y0.571667 +G1 X0.993333 Y0.591667 +G1 X0.973333 Y0.608333 +G1 X0.941667 Y0.623333 +G1 X0.923333 Y0.628333 +G1 X0.886667 Y0.630000 +G0 Z#100 +(polygon end, distance 2.38) +(end, total distance 60.56mm = 2.38in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode2/out.bottom.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode2/out.bottom.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode2/out.bottom.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:35:19 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X27.770667 Y13.546667 (start point) +G1 Z#101 +G1 X27.559000 Y13.462000 +G1 X27.305000 Y13.292667 +G1 X7.450667 Y13.292667 +G1 X7.196667 Y13.081000 +G1 X6.985000 Y12.827000 +G1 X6.985000 Y12.530667 +G1 X7.196667 Y12.276667 +G1 X7.450667 Y12.065000 +G1 X27.305000 Y12.065000 +G1 X27.643667 Y11.853333 +G1 X28.194000 Y11.853333 +G1 X28.532667 Y12.065000 +G1 X28.744333 Y12.403667 +G1 X28.744333 Y12.954000 +G1 X28.532667 Y13.292667 +G1 X28.194000 Y13.504333 +G1 X27.770667 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode2/out.drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode2/out.drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode2/out.drill.cnc (revision 33253) @@ -0,0 +1,12 @@ +(Created by G-code exporter) +(drill file: 1 drills) +( Tue Mar 9 17:35:19 2010 ) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-2.000000 (drill depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G81 X27.940000 Y12.700000 Z#101 R#100 +M5 M9 M2 +(end, total distance 0.00mm = 0.00in) Index: tags/2.3.0/tests/orig/golden/hid_gcode2/out.top.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode2/out.top.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode2/out.top.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:35:16 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X22.733000 Y13.546667 (start point) +G1 Z#101 +G1 X22.521333 Y13.462000 +G1 X22.267333 Y13.292667 +G1 X2.413000 Y13.292667 +G1 X2.159000 Y13.081000 +G1 X1.947333 Y12.827000 +G1 X1.947333 Y12.530667 +G1 X2.159000 Y12.276667 +G1 X2.413000 Y12.065000 +G1 X22.267333 Y12.065000 +G1 X22.606000 Y11.853333 +G1 X23.156333 Y11.853333 +G1 X23.495000 Y12.065000 +G1 X23.706667 Y12.403667 +G1 X23.706667 Y12.954000 +G1 X23.495000 Y13.292667 +G1 X23.156333 Y13.504333 +G1 X22.733000 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode3/gcode_oneline.gcode.bottom.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode3/gcode_oneline.gcode.bottom.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode3/gcode_oneline.gcode.bottom.cnc (revision 33253) @@ -0,0 +1,40 @@ +(Created by G-code exporter) +( Tue Mar 9 17:36:04 2010 ) +(1200 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X27.813000 Y13.546667 (start point) +G1 Z#101 +G1 X27.664833 Y13.504333 +G1 X27.453167 Y13.398500 +G1 X27.326167 Y13.292667 +G1 X7.535333 Y13.292667 +G1 X7.323667 Y13.229167 +G1 X7.069667 Y12.975167 +G1 X7.006167 Y12.763500 +G1 X7.006167 Y12.615333 +G1 X7.069667 Y12.403667 +G1 X7.323667 Y12.149667 +G1 X7.535333 Y12.086167 +G1 X27.326167 Y12.086167 +G1 X27.495500 Y11.959167 +G1 X27.728333 Y11.853333 +G1 X28.130500 Y11.853333 +G1 X28.448000 Y12.001500 +G1 X28.638500 Y12.213167 +G1 X28.765500 Y12.488333 +G1 X28.765500 Y12.890500 +G1 X28.638500 Y13.165667 +G1 X28.448000 Y13.377333 +G1 X28.130500 Y13.525500 +G1 X27.813000 Y13.546667 +G0 Z#100 +(polygon end, distance 45.35) +(end, total distance 45.35mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode3/gcode_oneline.gcode.drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode3/gcode_oneline.gcode.drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode3/gcode_oneline.gcode.drill.cnc (revision 33253) @@ -0,0 +1,12 @@ +(Created by G-code exporter) +(drill file: 1 drills) +( Tue Mar 9 17:36:04 2010 ) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-2.000000 (drill depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G81 X27.940000 Y12.700000 Z#101 R#100 +M5 M9 M2 +(end, total distance 0.00mm = 0.00in) Index: tags/2.3.0/tests/orig/golden/hid_gcode3/gcode_oneline.gcode.top.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode3/gcode_oneline.gcode.top.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode3/gcode_oneline.gcode.top.cnc (revision 33253) @@ -0,0 +1,40 @@ +(Created by G-code exporter) +( Tue Mar 9 17:35:46 2010 ) +(1200 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X22.754167 Y13.546667 (start point) +G1 Z#101 +G1 X22.606000 Y13.504333 +G1 X22.394333 Y13.398500 +G1 X22.267333 Y13.292667 +G1 X2.476500 Y13.292667 +G1 X2.264833 Y13.229167 +G1 X2.010833 Y12.975167 +G1 X1.947333 Y12.763500 +G1 X1.947333 Y12.615333 +G1 X2.010833 Y12.403667 +G1 X2.264833 Y12.149667 +G1 X2.476500 Y12.086167 +G1 X22.267333 Y12.086167 +G1 X22.436667 Y11.959167 +G1 X22.669500 Y11.853333 +G1 X23.071667 Y11.853333 +G1 X23.389167 Y12.001500 +G1 X23.579667 Y12.213167 +G1 X23.706667 Y12.488333 +G1 X23.706667 Y12.890500 +G1 X23.579667 Y13.165667 +G1 X23.389167 Y13.377333 +G1 X23.071667 Y13.525500 +G1 X22.754167 Y13.546667 +G0 Z#100 +(polygon end, distance 45.35) +(end, total distance 45.35mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode4/gcode_oneline.gcode.bottom.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode4/gcode_oneline.gcode.bottom.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode4/gcode_oneline.gcode.bottom.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:36:12 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=5.000000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X27.770667 Y13.546667 (start point) +G1 Z#101 +G1 X27.559000 Y13.462000 +G1 X27.305000 Y13.292667 +G1 X7.450667 Y13.292667 +G1 X7.196667 Y13.081000 +G1 X6.985000 Y12.827000 +G1 X6.985000 Y12.530667 +G1 X7.196667 Y12.276667 +G1 X7.450667 Y12.065000 +G1 X27.305000 Y12.065000 +G1 X27.643667 Y11.853333 +G1 X28.194000 Y11.853333 +G1 X28.532667 Y12.065000 +G1 X28.744333 Y12.403667 +G1 X28.744333 Y12.954000 +G1 X28.532667 Y13.292667 +G1 X28.194000 Y13.504333 +G1 X27.770667 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode4/gcode_oneline.gcode.drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode4/gcode_oneline.gcode.drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode4/gcode_oneline.gcode.drill.cnc (revision 33253) @@ -0,0 +1,12 @@ +(Created by G-code exporter) +(drill file: 1 drills) +( Tue Mar 9 17:36:12 2010 ) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-2.000000 (drill depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G81 X27.940000 Y12.700000 Z#101 R#100 +M5 M9 M2 +(end, total distance 0.00mm = 0.00in) Index: tags/2.3.0/tests/orig/golden/hid_gcode4/gcode_oneline.gcode.top.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode4/gcode_oneline.gcode.top.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode4/gcode_oneline.gcode.top.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:36:08 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=5.000000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X22.733000 Y13.546667 (start point) +G1 Z#101 +G1 X22.521333 Y13.462000 +G1 X22.267333 Y13.292667 +G1 X2.413000 Y13.292667 +G1 X2.159000 Y13.081000 +G1 X1.947333 Y12.827000 +G1 X1.947333 Y12.530667 +G1 X2.159000 Y12.276667 +G1 X2.413000 Y12.065000 +G1 X22.267333 Y12.065000 +G1 X22.606000 Y11.853333 +G1 X23.156333 Y11.853333 +G1 X23.495000 Y12.065000 +G1 X23.706667 Y12.403667 +G1 X23.706667 Y12.954000 +G1 X23.495000 Y13.292667 +G1 X23.156333 Y13.504333 +G1 X22.733000 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode5/gcode_oneline.gcode.bottom.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode5/gcode_oneline.gcode.bottom.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode5/gcode_oneline.gcode.bottom.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 18:06:42 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=10.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X27.770667 Y13.546667 (start point) +G1 Z#101 +G1 X27.559000 Y13.462000 +G1 X27.305000 Y13.292667 +G1 X7.450667 Y13.292667 +G1 X7.196667 Y13.081000 +G1 X6.985000 Y12.827000 +G1 X6.985000 Y12.530667 +G1 X7.196667 Y12.276667 +G1 X7.450667 Y12.065000 +G1 X27.305000 Y12.065000 +G1 X27.643667 Y11.853333 +G1 X28.194000 Y11.853333 +G1 X28.532667 Y12.065000 +G1 X28.744333 Y12.403667 +G1 X28.744333 Y12.954000 +G1 X28.532667 Y13.292667 +G1 X28.194000 Y13.504333 +G1 X27.770667 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode5/gcode_oneline.gcode.drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode5/gcode_oneline.gcode.drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode5/gcode_oneline.gcode.drill.cnc (revision 33253) @@ -0,0 +1,12 @@ +(Created by G-code exporter) +(drill file: 1 drills) +( Tue Mar 9 18:06:42 2010 ) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=10.000000 (safe Z) +#101=-2.000000 (drill depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G81 X27.940000 Y12.700000 Z#101 R#100 +M5 M9 M2 +(end, total distance 0.00mm = 0.00in) Index: tags/2.3.0/tests/orig/golden/hid_gcode5/gcode_oneline.gcode.top.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode5/gcode_oneline.gcode.top.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode5/gcode_oneline.gcode.top.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 18:06:40 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=10.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X22.733000 Y13.546667 (start point) +G1 Z#101 +G1 X22.521333 Y13.462000 +G1 X22.267333 Y13.292667 +G1 X2.413000 Y13.292667 +G1 X2.159000 Y13.081000 +G1 X1.947333 Y12.827000 +G1 X1.947333 Y12.530667 +G1 X2.159000 Y12.276667 +G1 X2.413000 Y12.065000 +G1 X22.267333 Y12.065000 +G1 X22.606000 Y11.853333 +G1 X23.156333 Y11.853333 +G1 X23.495000 Y12.065000 +G1 X23.706667 Y12.403667 +G1 X23.706667 Y12.954000 +G1 X23.495000 Y13.292667 +G1 X23.156333 Y13.504333 +G1 X22.733000 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode6/gcode_oneline.gcode.bottom.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode6/gcode_oneline.gcode.bottom.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode6/gcode_oneline.gcode.bottom.cnc (revision 33253) @@ -0,0 +1,43 @@ +(Created by G-code exporter) +( Tue Mar 9 17:45:05 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X0.000000 Y25.400000 (start point) +G1 Z#101 +G1 X0.000000 Y0.000000 +G1 X37.295667 Y0.000000 +G1 X38.057667 Y0.635000 +G1 X39.073667 Y1.524000 +G1 X39.962667 Y2.540000 +G1 X40.597667 Y3.302000 +G1 X41.486667 Y4.656667 +G1 X41.952333 Y5.503333 +G1 X42.418000 Y6.477000 +G1 X42.883667 Y7.704667 +G1 X43.264667 Y9.017000 +G1 X43.518667 Y10.329333 +G1 X43.645667 Y11.514667 +G1 X43.645667 Y13.843000 +G1 X43.518667 Y15.028333 +G1 X43.264667 Y16.340667 +G1 X42.883667 Y17.653000 +G1 X42.418000 Y18.880667 +G1 X41.952333 Y19.854333 +G1 X41.486667 Y20.701000 +G1 X40.597667 Y22.055667 +G1 X39.962667 Y22.817667 +G1 X39.073667 Y23.833667 +G1 X38.057667 Y24.722667 +G1 X37.253333 Y25.400000 +G1 X0.000000 Y25.400000 +G0 Z#100 +(polygon end, distance 129.45) +(end, total distance 129.45mm = 5.10in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode6/gcode_oneline.gcode.drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode6/gcode_oneline.gcode.drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode6/gcode_oneline.gcode.drill.cnc (revision 33253) @@ -0,0 +1,12 @@ +(Created by G-code exporter) +(drill file: 1 drills) +( Tue Mar 9 17:45:05 2010 ) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-2.000000 (drill depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G81 X27.940000 Y12.700000 Z#101 R#100 +M5 M9 M2 +(end, total distance 0.00mm = 0.00in) Index: tags/2.3.0/tests/orig/golden/hid_gcode6/gcode_oneline.gcode.top.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode6/gcode_oneline.gcode.top.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode6/gcode_oneline.gcode.top.cnc (revision 33253) @@ -0,0 +1,43 @@ +(Created by G-code exporter) +( Tue Mar 9 17:39:31 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X0.000000 Y25.400000 (start point) +G1 Z#101 +G1 X0.000000 Y0.000000 +G1 X32.258000 Y0.000000 +G1 X33.020000 Y0.635000 +G1 X34.036000 Y1.524000 +G1 X34.925000 Y2.540000 +G1 X35.560000 Y3.302000 +G1 X36.449000 Y4.656667 +G1 X36.914667 Y5.503333 +G1 X37.380333 Y6.477000 +G1 X37.846000 Y7.704667 +G1 X38.227000 Y9.017000 +G1 X38.481000 Y10.329333 +G1 X38.608000 Y11.514667 +G1 X38.608000 Y13.843000 +G1 X38.481000 Y15.028333 +G1 X38.227000 Y16.340667 +G1 X37.846000 Y17.653000 +G1 X37.380333 Y18.880667 +G1 X36.914667 Y19.854333 +G1 X36.449000 Y20.701000 +G1 X35.560000 Y22.055667 +G1 X34.925000 Y22.817667 +G1 X34.036000 Y23.833667 +G1 X33.020000 Y24.722667 +G1 X32.215667 Y25.400000 +G1 X0.000000 Y25.400000 +G0 Z#100 +(polygon end, distance 119.38) +(end, total distance 119.38mm = 4.70in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode7/gcode_oneline.gcode.bottom.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode7/gcode_oneline.gcode.bottom.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode7/gcode_oneline.gcode.bottom.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:45:12 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X27.770667 Y13.546667 (start point) +G1 Z#101 +G1 X27.559000 Y13.462000 +G1 X27.305000 Y13.292667 +G1 X7.450667 Y13.292667 +G1 X7.196667 Y13.081000 +G1 X6.985000 Y12.827000 +G1 X6.985000 Y12.530667 +G1 X7.196667 Y12.276667 +G1 X7.450667 Y12.065000 +G1 X27.305000 Y12.065000 +G1 X27.643667 Y11.853333 +G1 X28.194000 Y11.853333 +G1 X28.532667 Y12.065000 +G1 X28.744333 Y12.403667 +G1 X28.744333 Y12.954000 +G1 X28.532667 Y13.292667 +G1 X28.194000 Y13.504333 +G1 X27.770667 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode7/gcode_oneline.gcode.drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode7/gcode_oneline.gcode.drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode7/gcode_oneline.gcode.drill.cnc (revision 33253) @@ -0,0 +1,12 @@ +(Created by G-code exporter) +(drill file: 1 drills) +( Tue Mar 9 17:45:12 2010 ) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=70.000000 (drill depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G81 X27.940000 Y12.700000 Z#101 R#100 +M5 M9 M2 +(end, total distance 0.00mm = 0.00in) Index: tags/2.3.0/tests/orig/golden/hid_gcode7/gcode_oneline.gcode.top.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode7/gcode_oneline.gcode.top.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode7/gcode_oneline.gcode.top.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:45:08 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X22.733000 Y13.546667 (start point) +G1 Z#101 +G1 X22.521333 Y13.462000 +G1 X22.267333 Y13.292667 +G1 X2.413000 Y13.292667 +G1 X2.159000 Y13.081000 +G1 X1.947333 Y12.827000 +G1 X1.947333 Y12.530667 +G1 X2.159000 Y12.276667 +G1 X2.413000 Y12.065000 +G1 X22.267333 Y12.065000 +G1 X22.606000 Y11.853333 +G1 X23.156333 Y11.853333 +G1 X23.495000 Y12.065000 +G1 X23.706667 Y12.403667 +G1 X23.706667 Y12.954000 +G1 X23.495000 Y13.292667 +G1 X23.156333 Y13.504333 +G1 X22.733000 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode8/gcode_oneline.gcode.bottom.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode8/gcode_oneline.gcode.bottom.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode8/gcode_oneline.gcode.bottom.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:45:19 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X27.770667 Y13.546667 (start point) +G1 Z#101 +G1 X27.559000 Y13.462000 +G1 X27.305000 Y13.292667 +G1 X7.450667 Y13.292667 +G1 X7.196667 Y13.081000 +G1 X6.985000 Y12.827000 +G1 X6.985000 Y12.530667 +G1 X7.196667 Y12.276667 +G1 X7.450667 Y12.065000 +G1 X27.305000 Y12.065000 +G1 X27.643667 Y11.853333 +G1 X28.194000 Y11.853333 +G1 X28.532667 Y12.065000 +G1 X28.744333 Y12.403667 +G1 X28.744333 Y12.954000 +G1 X28.532667 Y13.292667 +G1 X28.194000 Y13.504333 +G1 X27.770667 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode8/gcode_oneline.gcode.drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode8/gcode_oneline.gcode.drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode8/gcode_oneline.gcode.drill.cnc (revision 33253) @@ -0,0 +1,12 @@ +(Created by G-code exporter) +(drill file: 1 drills) +( Tue Mar 9 17:45:19 2010 ) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-2.000000 (drill depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G81 X27.940000 Y12.700000 Z#101 R#100 +M5 M9 M2 +(end, total distance 0.00mm = 0.00in) Index: tags/2.3.0/tests/orig/golden/hid_gcode8/gcode_oneline.gcode.top.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode8/gcode_oneline.gcode.top.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode8/gcode_oneline.gcode.top.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:45:16 2010 ) +(600 dpi) +(Unit: mm) +(Board size: 50.80x25.40 mm) +#100=2.000000 (safe Z) +#101=-0.050000 (cutting depth) +(---------------------------------) +G17 G21 G90 G64 P0.003 M3 S3000 M7 F25 +G0 Z#100 +(polygon 1) +G0 X22.733000 Y13.546667 (start point) +G1 Z#101 +G1 X22.521333 Y13.462000 +G1 X22.267333 Y13.292667 +G1 X2.413000 Y13.292667 +G1 X2.159000 Y13.081000 +G1 X1.947333 Y12.827000 +G1 X1.947333 Y12.530667 +G1 X2.159000 Y12.276667 +G1 X2.413000 Y12.065000 +G1 X22.267333 Y12.065000 +G1 X22.606000 Y11.853333 +G1 X23.156333 Y11.853333 +G1 X23.495000 Y12.065000 +G1 X23.706667 Y12.403667 +G1 X23.706667 Y12.954000 +G1 X23.495000 Y13.292667 +G1 X23.156333 Y13.504333 +G1 X22.733000 Y13.546667 +G0 Z#100 +(polygon end, distance 45.38) +(end, total distance 45.38mm = 1.79in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode9/gcode_oneline.gcode.bottom.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode9/gcode_oneline.gcode.bottom.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode9/gcode_oneline.gcode.bottom.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:45:25 2010 ) +(600 dpi) +(Unit: inch) +(Board size: 2.00x1.00 inches) +#100=0.002000 (safe Z) +#101=-0.000050 (cutting depth) +(---------------------------------) +G17 G20 G90 G64 P0.003 M3 S3000 M7 F1 +G0 Z#100 +(polygon 1) +G0 X1.093333 Y0.530000 (start point) +G1 Z#101 +G1 X1.083333 Y0.525000 +G1 X1.076667 Y0.520000 +G1 X0.291667 Y0.518333 +G1 X0.280000 Y0.506667 +G1 X0.280000 Y0.491667 +G1 X0.291667 Y0.480000 +G1 X1.076667 Y0.478333 +G1 X1.088333 Y0.470000 +G1 X1.100000 Y0.468333 +G1 X1.113333 Y0.471667 +G1 X1.123333 Y0.480000 +G1 X1.130000 Y0.493333 +G1 X1.130000 Y0.505000 +G1 X1.123333 Y0.518333 +G1 X1.115000 Y0.525000 +G1 X1.103333 Y0.530000 +G1 X1.093333 Y0.530000 +G0 Z#100 +(polygon end, distance 1.77) +(end, total distance 44.84mm = 1.77in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gcode9/gcode_oneline.gcode.drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode9/gcode_oneline.gcode.drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode9/gcode_oneline.gcode.drill.cnc (revision 33253) @@ -0,0 +1,12 @@ +(Created by G-code exporter) +(drill file: 1 drills) +( Tue Mar 9 17:45:25 2010 ) +(Unit: inch) +(Board size: 2.00x1.00 inches) +#100=0.002000 (safe Z) +#101=-0.002000 (drill depth) +(---------------------------------) +G17 G20 G90 G64 P0.003 M3 S3000 M7 F1 +G81 X1.100000 Y0.500000 Z#101 R#100 +M5 M9 M2 +(end, total distance 0.00mm = 0.00in) Index: tags/2.3.0/tests/orig/golden/hid_gcode9/gcode_oneline.gcode.top.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gcode9/gcode_oneline.gcode.top.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gcode9/gcode_oneline.gcode.top.cnc (revision 33253) @@ -0,0 +1,34 @@ +(Created by G-code exporter) +( Tue Mar 9 17:45:22 2010 ) +(600 dpi) +(Unit: inch) +(Board size: 2.00x1.00 inches) +#100=0.002000 (safe Z) +#101=-0.000050 (cutting depth) +(---------------------------------) +G17 G20 G90 G64 P0.003 M3 S3000 M7 F1 +G0 Z#100 +(polygon 1) +G0 X0.895000 Y0.530000 (start point) +G1 Z#101 +G1 X0.885000 Y0.525000 +G1 X0.878333 Y0.520000 +G1 X0.093333 Y0.518333 +G1 X0.081667 Y0.506667 +G1 X0.081667 Y0.491667 +G1 X0.093333 Y0.480000 +G1 X0.878333 Y0.478333 +G1 X0.890000 Y0.470000 +G1 X0.901667 Y0.468333 +G1 X0.915000 Y0.471667 +G1 X0.925000 Y0.480000 +G1 X0.931667 Y0.493333 +G1 X0.931667 Y0.505000 +G1 X0.925000 Y0.518333 +G1 X0.916667 Y0.525000 +G1 X0.905000 Y0.530000 +G1 X0.895000 Y0.530000 +G0 Z#100 +(polygon end, distance 1.77) +(end, total distance 44.84mm = 1.77in) +M5 M9 M2 Index: tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.bottom.gbr =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.bottom.gbr (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.bottom.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 1 idx 1 * +G04 Title: Basic Single Trace RS274-X Test, solder * +G04 Creator: pcb 1.99y * +G04 CreationDate: Wed Jun 24 21:42:24 2009 UTC * +G04 For: dan * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 200000 100000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBACK*% +%ADD11C,0.0400*% +%ADD12C,0.0600*% +%ADD13C,0.0350*% +G54D11*X170000Y50000D02*X90000D01* +G54D12*D03* +G54D13*M02* Index: tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.fab.gbr =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.fab.gbr (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.fab.gbr (revision 33253) @@ -0,0 +1,1734 @@ +G04 start of page 5 for group -3984 idx -3984 * +G04 Title: Basic Single Trace RS274-X Test, fab * +G04 Creator: pcb 1.99y * +G04 CreationDate: Wed Jun 24 21:42:24 2009 UTC * +G04 For: dan * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 200000 100000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNFAB*% +%ADD14C,0.0080*% +%ADD15C,0.0060*% +%ADD16C,0.0100*% +G54D14*X90000Y50000D02*Y48400D01* +Y50000D02*X91386Y50800D01* +X90000Y50000D02*X88614Y50800D01* +X15000Y156250D02*Y154650D01* +Y156250D02*X16386Y157050D01* +X15000Y156250D02*X13614Y157050D01* +G54D15*X135000Y158500D02*Y157750D01* +X136500Y156250D01* +X138000Y157750D01* +Y158500D02*Y157750D01* +X136500Y156250D02*Y152500D01* +X139801Y155500D02*X142051D01* +X139801Y152500D02*X142801D01* +X139801Y158500D02*Y152500D01* +Y158500D02*X142801D01* +X147603D02*X148353Y157750D01* +X145353Y158500D02*X147603D01* +X144603Y157750D02*X145353Y158500D01* +X144603Y157750D02*Y156250D01* +X145353Y155500D01* +X147603D01* +X148353Y154750D01* +Y153250D01* +X147603Y152500D02*X148353Y153250D01* +X145353Y152500D02*X147603D01* +X144603Y153250D02*X145353Y152500D01* +X135000Y149249D02*X150154D01* +X98750Y152500D02*X100250D01* +X99500Y158500D02*Y152500D01* +X98000Y157000D02*X99500Y158500D01* +X98000Y149249D02*X102051D01* +X45000Y153250D02*X45750Y152500D01* +X45000Y157750D02*Y153250D01* +Y157750D02*X45750Y158500D01* +X47250D01* +X48000Y157750D01* +Y153250D01* +X47250Y152500D02*X48000Y153250D01* +X45750Y152500D02*X47250D01* +X45000Y154000D02*X48000Y157000D01* +X49801Y152500D02*X50551D01* +X52353Y153250D02*X53103Y152500D01* +X52353Y157750D02*Y153250D01* +Y157750D02*X53103Y158500D01* +X54603D01* +X55353Y157750D01* +Y153250D01* +X54603Y152500D02*X55353Y153250D01* +X53103Y152500D02*X54603D01* +X52353Y154000D02*X55353Y157000D01* +X57154Y157750D02*X57904Y158500D01* +X59404D01* +X60154Y157750D01* +Y153250D01* +X59404Y152500D02*X60154Y153250D01* +X57904Y152500D02*X59404D01* +X57154Y153250D02*X57904Y152500D01* +Y155500D02*X60154D01* +X61956Y158500D02*X64956D01* +X61956D02*Y155500D01* +X62706Y156250D01* +X64206D01* +X64956Y155500D01* +Y153250D01* +X64206Y152500D02*X64956Y153250D01* +X62706Y152500D02*X64206D01* +X61956Y153250D02*X62706Y152500D01* +X45000Y149249D02*X66757D01* +X3000Y173500D02*X3750Y172750D01* +X750Y173500D02*X3000D01* +X0Y172750D02*X750Y173500D01* +X0Y172750D02*Y171250D01* +X750Y170500D01* +X3000D01* +X3750Y169750D01* +Y168250D01* +X3000Y167500D02*X3750Y168250D01* +X750Y167500D02*X3000D01* +X0Y168250D02*X750Y167500D01* +X5551Y170500D02*Y168250D01* +X6301Y167500D01* +X8551Y170500D02*Y166000D01* +X7801Y165250D02*X8551Y166000D01* +X6301Y165250D02*X7801D01* +X5551Y166000D02*X6301Y165250D01* +Y167500D02*X7801D01* +X8551Y168250D01* +X11103Y169750D02*Y167500D01* +Y169750D02*X11853Y170500D01* +X12603D01* +X13353Y169750D01* +Y167500D01* +Y169750D02*X14103Y170500D01* +X14853D01* +X15603Y169750D01* +Y167500D01* +X10353Y170500D02*X11103Y169750D01* +X17404Y173500D02*Y167500D01* +Y168250D02*X18154Y167500D01* +X19654D01* +X20404Y168250D01* +Y169750D02*Y168250D01* +X19654Y170500D02*X20404Y169750D01* +X18154Y170500D02*X19654D01* +X17404Y169750D02*X18154Y170500D01* +X22206Y169750D02*Y168250D01* +Y169750D02*X22956Y170500D01* +X24456D01* +X25206Y169750D01* +Y168250D01* +X24456Y167500D02*X25206Y168250D01* +X22956Y167500D02*X24456D01* +X22206Y168250D02*X22956Y167500D01* +X27007Y173500D02*Y168250D01* +X27757Y167500D01* +X41750Y173500D02*Y167500D01* +X44000Y173500D02*X44750Y172750D01* +Y168250D01* +X44000Y167500D02*X44750Y168250D01* +X41000Y167500D02*X44000D01* +X41000Y173500D02*X44000D01* +X46551Y172000D02*Y171250D01* +Y169750D02*Y167500D01* +X50303Y170500D02*X51053Y169750D01* +X48803Y170500D02*X50303D01* +X48053Y169750D02*X48803Y170500D01* +X48053Y169750D02*Y168250D01* +X48803Y167500D01* +X51053Y170500D02*Y168250D01* +X51803Y167500D01* +X48803D02*X50303D01* +X51053Y168250D01* +X54354Y169750D02*Y167500D01* +Y169750D02*X55104Y170500D01* +X55854D01* +X56604Y169750D01* +Y167500D01* +Y169750D02*X57354Y170500D01* +X58104D01* +X58854Y169750D01* +Y167500D01* +X53604Y170500D02*X54354Y169750D01* +X60656Y167500D02*X61406D01* +X65907Y168250D02*X66657Y167500D01* +X65907Y172750D02*X66657Y173500D01* +X65907Y172750D02*Y168250D01* +X68459Y173500D02*X69959D01* +X69209D02*Y167500D01* +X68459D02*X69959D01* +X72510Y169750D02*Y167500D01* +Y169750D02*X73260Y170500D01* +X74010D01* +X74760Y169750D01* +Y167500D01* +X71760Y170500D02*X72510Y169750D01* +X77312Y170500D02*X79562D01* +X76562Y169750D02*X77312Y170500D01* +X76562Y169750D02*Y168250D01* +X77312Y167500D01* +X79562D01* +X81363Y173500D02*Y167500D01* +Y169750D02*X82113Y170500D01* +X83613D01* +X84363Y169750D01* +Y167500D01* +X86165Y173500D02*X86915Y172750D01* +Y168250D01* +X86165Y167500D02*X86915Y168250D01* +X95750Y167500D02*X98000D01* +X95000Y168250D02*X95750Y167500D01* +X95000Y172750D02*Y168250D01* +Y172750D02*X95750Y173500D01* +X98000D01* +X99801Y169750D02*Y168250D01* +Y169750D02*X100551Y170500D01* +X102051D01* +X102801Y169750D01* +Y168250D01* +X102051Y167500D02*X102801Y168250D01* +X100551Y167500D02*X102051D01* +X99801Y168250D02*X100551Y167500D01* +X104603Y170500D02*Y168250D01* +X105353Y167500D01* +X106853D01* +X107603Y168250D01* +Y170500D02*Y168250D01* +X110154Y169750D02*Y167500D01* +Y169750D02*X110904Y170500D01* +X111654D01* +X112404Y169750D01* +Y167500D01* +X109404Y170500D02*X110154Y169750D01* +X114956Y173500D02*Y168250D01* +X115706Y167500D01* +X114206Y171250D02*X115706D01* +X130750Y173500D02*Y167500D01* +X130000Y173500D02*X133000D01* +X133750Y172750D01* +Y171250D01* +X133000Y170500D02*X133750Y171250D01* +X130750Y170500D02*X133000D01* +X135551Y173500D02*Y168250D01* +X136301Y167500D01* +X140053Y170500D02*X140803Y169750D01* +X138553Y170500D02*X140053D01* +X137803Y169750D02*X138553Y170500D01* +X137803Y169750D02*Y168250D01* +X138553Y167500D01* +X140803Y170500D02*Y168250D01* +X141553Y167500D01* +X138553D02*X140053D01* +X140803Y168250D01* +X144104Y173500D02*Y168250D01* +X144854Y167500D01* +X143354Y171250D02*X144854D01* +X147106Y167500D02*X149356D01* +X146356Y168250D02*X147106Y167500D01* +X146356Y169750D02*Y168250D01* +Y169750D02*X147106Y170500D01* +X148606D01* +X149356Y169750D01* +X146356Y169000D02*X149356D01* +Y169750D02*Y169000D01* +X154157Y173500D02*Y167500D01* +X153407D02*X154157Y168250D01* +X151907Y167500D02*X153407D01* +X151157Y168250D02*X151907Y167500D01* +X151157Y169750D02*Y168250D01* +Y169750D02*X151907Y170500D01* +X153407D01* +X154157Y169750D01* +X157459Y170500D02*Y169750D01* +Y168250D02*Y167500D01* +X155959Y172750D02*Y172000D01* +Y172750D02*X156709Y173500D01* +X158209D01* +X158959Y172750D01* +Y172000D01* +X157459Y170500D02*X158959Y172000D01* +X0Y188500D02*X3000D01* +X1500D02*Y182500D01* +X4801Y188500D02*Y182500D01* +Y184750D02*X5551Y185500D01* +X7051D01* +X7801Y184750D01* +Y182500D01* +X10353D02*X12603D01* +X9603Y183250D02*X10353Y182500D01* +X9603Y184750D02*Y183250D01* +Y184750D02*X10353Y185500D01* +X11853D01* +X12603Y184750D01* +X9603Y184000D02*X12603D01* +Y184750D02*Y184000D01* +X15154Y184750D02*Y182500D01* +Y184750D02*X15904Y185500D01* +X17404D01* +X14404D02*X15154Y184750D01* +X19956Y182500D02*X22206D01* +X19206Y183250D02*X19956Y182500D01* +X19206Y184750D02*Y183250D01* +Y184750D02*X19956Y185500D01* +X21456D01* +X22206Y184750D01* +X19206Y184000D02*X22206D01* +Y184750D02*Y184000D01* +X28957Y185500D02*X29707Y184750D01* +X27457Y185500D02*X28957D01* +X26707Y184750D02*X27457Y185500D01* +X26707Y184750D02*Y183250D01* +X27457Y182500D01* +X29707Y185500D02*Y183250D01* +X30457Y182500D01* +X27457D02*X28957D01* +X29707Y183250D01* +X33009Y184750D02*Y182500D01* +Y184750D02*X33759Y185500D01* +X35259D01* +X32259D02*X33009Y184750D01* +X37810Y182500D02*X40060D01* +X37060Y183250D02*X37810Y182500D01* +X37060Y184750D02*Y183250D01* +Y184750D02*X37810Y185500D01* +X39310D01* +X40060Y184750D01* +X37060Y184000D02*X40060D01* +Y184750D02*Y184000D01* +X45312Y182500D02*X46812D01* +X46062Y188500D02*Y182500D01* +X44562Y187000D02*X46062Y188500D01* +X54313D02*Y182500D01* +X53563D02*X54313Y183250D01* +X52063Y182500D02*X53563D01* +X51313Y183250D02*X52063Y182500D01* +X51313Y184750D02*Y183250D01* +Y184750D02*X52063Y185500D01* +X53563D01* +X54313Y184750D01* +X56115Y187000D02*Y186250D01* +Y184750D02*Y182500D01* +X58366Y187750D02*Y182500D01* +Y187750D02*X59116Y188500D01* +X59866D01* +X57616Y185500D02*X59116D01* +X62118Y187750D02*Y182500D01* +Y187750D02*X62868Y188500D01* +X63618D01* +X61368Y185500D02*X62868D01* +X65869Y182500D02*X68119D01* +X65119Y183250D02*X65869Y182500D01* +X65119Y184750D02*Y183250D01* +Y184750D02*X65869Y185500D01* +X67369D01* +X68119Y184750D01* +X65119Y184000D02*X68119D01* +Y184750D02*Y184000D01* +X70671Y184750D02*Y182500D01* +Y184750D02*X71421Y185500D01* +X72921D01* +X69921D02*X70671Y184750D01* +X75472Y182500D02*X77722D01* +X74722Y183250D02*X75472Y182500D01* +X74722Y184750D02*Y183250D01* +Y184750D02*X75472Y185500D01* +X76972D01* +X77722Y184750D01* +X74722Y184000D02*X77722D01* +Y184750D02*Y184000D01* +X80274Y184750D02*Y182500D01* +Y184750D02*X81024Y185500D01* +X81774D01* +X82524Y184750D01* +Y182500D01* +X79524Y185500D02*X80274Y184750D01* +X85075Y188500D02*Y183250D01* +X85825Y182500D01* +X84325Y186250D02*X85825D01* +X93027Y188500D02*Y182500D01* +X92277D02*X93027Y183250D01* +X90777Y182500D02*X92277D01* +X90027Y183250D02*X90777Y182500D01* +X90027Y184750D02*Y183250D01* +Y184750D02*X90777Y185500D01* +X92277D01* +X93027Y184750D01* +X95578D02*Y182500D01* +Y184750D02*X96328Y185500D01* +X97828D01* +X94828D02*X95578Y184750D01* +X99630Y187000D02*Y186250D01* +Y184750D02*Y182500D01* +X101131Y188500D02*Y183250D01* +X101881Y182500D01* +X103383Y188500D02*Y183250D01* +X104133Y182500D01* +X109084D02*X111334D01* +X112084Y183250D01* +X111334Y184000D02*X112084Y183250D01* +X109084Y184000D02*X111334D01* +X108334Y184750D02*X109084Y184000D01* +X108334Y184750D02*X109084Y185500D01* +X111334D01* +X112084Y184750D01* +X108334Y183250D02*X109084Y182500D01* +X113886Y187000D02*Y186250D01* +Y184750D02*Y182500D01* +X115387Y185500D02*X118387D01* +X115387Y182500D02*X118387Y185500D01* +X115387Y182500D02*X118387D01* +X120939D02*X123189D01* +X120189Y183250D02*X120939Y182500D01* +X120189Y184750D02*Y183250D01* +Y184750D02*X120939Y185500D01* +X122439D01* +X123189Y184750D01* +X120189Y184000D02*X123189D01* +Y184750D02*Y184000D01* +X125740Y182500D02*X127990D01* +X128740Y183250D01* +X127990Y184000D02*X128740Y183250D01* +X125740Y184000D02*X127990D01* +X124990Y184750D02*X125740Y184000D01* +X124990Y184750D02*X125740Y185500D01* +X127990D01* +X128740Y184750D01* +X124990Y183250D02*X125740Y182500D01* +X133242Y185500D02*Y183250D01* +X133992Y182500D01* +X135492D01* +X136242Y183250D01* +Y185500D02*Y183250D01* +X138793Y182500D02*X141043D01* +X141793Y183250D01* +X141043Y184000D02*X141793Y183250D01* +X138793Y184000D02*X141043D01* +X138043Y184750D02*X138793Y184000D01* +X138043Y184750D02*X138793Y185500D01* +X141043D01* +X141793Y184750D01* +X138043Y183250D02*X138793Y182500D01* +X144345D02*X146595D01* +X143595Y183250D02*X144345Y182500D01* +X143595Y184750D02*Y183250D01* +Y184750D02*X144345Y185500D01* +X145845D01* +X146595Y184750D01* +X143595Y184000D02*X146595D01* +Y184750D02*Y184000D01* +X151396Y188500D02*Y182500D01* +X150646D02*X151396Y183250D01* +X149146Y182500D02*X150646D01* +X148396Y183250D02*X149146Y182500D01* +X148396Y184750D02*Y183250D01* +Y184750D02*X149146Y185500D01* +X150646D01* +X151396Y184750D01* +X155898Y187000D02*Y186250D01* +Y184750D02*Y182500D01* +X158149Y184750D02*Y182500D01* +Y184750D02*X158899Y185500D01* +X159649D01* +X160399Y184750D01* +Y182500D01* +X157399Y185500D02*X158149Y184750D01* +X165651Y188500D02*Y183250D01* +X166401Y182500D01* +X164901Y186250D02*X166401D01* +X167902Y188500D02*Y182500D01* +Y184750D02*X168652Y185500D01* +X170152D01* +X170902Y184750D01* +Y182500D01* +X172704Y187000D02*Y186250D01* +Y184750D02*Y182500D01* +X174955D02*X177205D01* +X177955Y183250D01* +X177205Y184000D02*X177955Y183250D01* +X174955Y184000D02*X177205D01* +X174205Y184750D02*X174955Y184000D01* +X174205Y184750D02*X174955Y185500D01* +X177205D01* +X177955Y184750D01* +X174205Y183250D02*X174955Y182500D01* +X182457Y188500D02*Y183250D01* +X183207Y182500D01* +X186958Y185500D02*X187708Y184750D01* +X185458Y185500D02*X186958D01* +X184708Y184750D02*X185458Y185500D01* +X184708Y184750D02*Y183250D01* +X185458Y182500D01* +X187708Y185500D02*Y183250D01* +X188458Y182500D01* +X185458D02*X186958D01* +X187708Y183250D01* +X190260Y185500D02*Y183250D01* +X191010Y182500D01* +X193260Y185500D02*Y181000D01* +X192510Y180250D02*X193260Y181000D01* +X191010Y180250D02*X192510D01* +X190260Y181000D02*X191010Y180250D01* +Y182500D02*X192510D01* +X193260Y183250D01* +X195061Y184750D02*Y183250D01* +Y184750D02*X195811Y185500D01* +X197311D01* +X198061Y184750D01* +Y183250D01* +X197311Y182500D02*X198061Y183250D01* +X195811Y182500D02*X197311D01* +X195061Y183250D02*X195811Y182500D01* +X199863Y185500D02*Y183250D01* +X200613Y182500D01* +X202113D01* +X202863Y183250D01* +Y185500D02*Y183250D01* +X205414Y188500D02*Y183250D01* +X206164Y182500D01* +X204664Y186250D02*X206164D01* +X207666Y181000D02*X209166Y182500D01* +X214417D02*X215917D01* +X215167Y188500D02*Y182500D01* +X213667Y187000D02*X215167Y188500D01* +X220419D02*Y182500D01* +Y184750D02*X221169Y185500D01* +X222669D01* +X223419Y184750D01* +Y182500D01* +X225220Y184750D02*Y183250D01* +Y184750D02*X225970Y185500D01* +X227470D01* +X228220Y184750D01* +Y183250D01* +X227470Y182500D02*X228220Y183250D01* +X225970Y182500D02*X227470D01* +X225220Y183250D02*X225970Y182500D01* +X230022Y188500D02*Y183250D01* +X230772Y182500D01* +X233023D02*X235273D01* +X232273Y183250D02*X233023Y182500D01* +X232273Y184750D02*Y183250D01* +Y184750D02*X233023Y185500D01* +X234523D01* +X235273Y184750D01* +X232273Y184000D02*X235273D01* +Y184750D02*Y184000D01* +X237825Y182500D02*X240075D01* +X240825Y183250D01* +X240075Y184000D02*X240825Y183250D01* +X237825Y184000D02*X240075D01* +X237075Y184750D02*X237825Y184000D01* +X237075Y184750D02*X237825Y185500D01* +X240075D01* +X240825Y184750D01* +X237075Y183250D02*X237825Y182500D01* +X246076Y188500D02*Y183250D01* +X246826Y182500D01* +X245326Y186250D02*X246826D01* +X248328Y184750D02*Y183250D01* +Y184750D02*X249078Y185500D01* +X250578D01* +X251328Y184750D01* +Y183250D01* +X250578Y182500D02*X251328Y183250D01* +X249078Y182500D02*X250578D01* +X248328Y183250D02*X249078Y182500D01* +X253879Y188500D02*Y183250D01* +X254629Y182500D01* +X253129Y186250D02*X254629D01* +X258381Y185500D02*X259131Y184750D01* +X256881Y185500D02*X258381D01* +X256131Y184750D02*X256881Y185500D01* +X256131Y184750D02*Y183250D01* +X256881Y182500D01* +X259131Y185500D02*Y183250D01* +X259881Y182500D01* +X256881D02*X258381D01* +X259131Y183250D01* +X261682Y188500D02*Y183250D01* +X262432Y182500D01* +G54D16*X0Y100000D02*X200000D01* +X0D02*Y0D01* +X200000Y100000D02*Y0D01* +X0D02*X200000D01* +G54D15*Y113500D02*Y107500D01* +Y113500D02*X202250Y111250D01* +X204500Y113500D01* +Y107500D01* +X208551Y110500D02*X209301Y109750D01* +X207051Y110500D02*X208551D01* +X206301Y109750D02*X207051Y110500D01* +X206301Y109750D02*Y108250D01* +X207051Y107500D01* +X209301Y110500D02*Y108250D01* +X210051Y107500D01* +X207051D02*X208551D01* +X209301Y108250D01* +X211853Y110500D02*X214853Y107500D01* +X211853D02*X214853Y110500D01* +X216654Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X218906Y109750D02*Y107500D01* +Y109750D02*X219656Y110500D01* +X220406D01* +X221156Y109750D01* +Y107500D01* +Y109750D02*X221906Y110500D01* +X222656D01* +X223406Y109750D01* +Y107500D01* +X218156Y110500D02*X218906Y109750D01* +X225207Y110500D02*Y108250D01* +X225957Y107500D01* +X227457D01* +X228207Y108250D01* +Y110500D02*Y108250D01* +X230759Y109750D02*Y107500D01* +Y109750D02*X231509Y110500D01* +X232259D01* +X233009Y109750D01* +Y107500D01* +Y109750D02*X233759Y110500D01* +X234509D01* +X235259Y109750D01* +Y107500D01* +X230009Y110500D02*X230759Y109750D01* +X240510Y113500D02*Y107500D01* +X242760Y113500D02*X243510Y112750D01* +Y108250D01* +X242760Y107500D02*X243510Y108250D01* +X239760Y107500D02*X242760D01* +X239760Y113500D02*X242760D01* +X245312Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X247563Y109750D02*Y107500D01* +Y109750D02*X248313Y110500D01* +X249063D01* +X249813Y109750D01* +Y107500D01* +Y109750D02*X250563Y110500D01* +X251313D01* +X252063Y109750D01* +Y107500D01* +X246813Y110500D02*X247563Y109750D01* +X254615Y107500D02*X256865D01* +X253865Y108250D02*X254615Y107500D01* +X253865Y109750D02*Y108250D01* +Y109750D02*X254615Y110500D01* +X256115D01* +X256865Y109750D01* +X253865Y109000D02*X256865D01* +Y109750D02*Y109000D01* +X259416Y109750D02*Y107500D01* +Y109750D02*X260166Y110500D01* +X260916D01* +X261666Y109750D01* +Y107500D01* +X258666Y110500D02*X259416Y109750D01* +X264218Y107500D02*X266468D01* +X267218Y108250D01* +X266468Y109000D02*X267218Y108250D01* +X264218Y109000D02*X266468D01* +X263468Y109750D02*X264218Y109000D01* +X263468Y109750D02*X264218Y110500D01* +X266468D01* +X267218Y109750D01* +X263468Y108250D02*X264218Y107500D01* +X269019Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X270521Y109750D02*Y108250D01* +Y109750D02*X271271Y110500D01* +X272771D01* +X273521Y109750D01* +Y108250D01* +X272771Y107500D02*X273521Y108250D01* +X271271Y107500D02*X272771D01* +X270521Y108250D02*X271271Y107500D01* +X276072Y109750D02*Y107500D01* +Y109750D02*X276822Y110500D01* +X277572D01* +X278322Y109750D01* +Y107500D01* +X275322Y110500D02*X276072Y109750D01* +X280874Y107500D02*X283124D01* +X283874Y108250D01* +X283124Y109000D02*X283874Y108250D01* +X280874Y109000D02*X283124D01* +X280124Y109750D02*X280874Y109000D01* +X280124Y109750D02*X280874Y110500D01* +X283124D01* +X283874Y109750D01* +X280124Y108250D02*X280874Y107500D01* +X285675Y111250D02*X286425D01* +X285675Y109750D02*X286425D01* +X290927Y112750D02*X291677Y113500D01* +X293927D01* +X294677Y112750D01* +Y111250D01* +X290927Y107500D02*X294677Y111250D01* +X290927Y107500D02*X294677D01* +X296478Y108250D02*X297228Y107500D01* +X296478Y112750D02*Y108250D01* +Y112750D02*X297228Y113500D01* +X298728D01* +X299478Y112750D01* +Y108250D01* +X298728Y107500D02*X299478Y108250D01* +X297228Y107500D02*X298728D01* +X296478Y109000D02*X299478Y112000D01* +X301280Y108250D02*X302030Y107500D01* +X301280Y112750D02*Y108250D01* +Y112750D02*X302030Y113500D01* +X303530D01* +X304280Y112750D01* +Y108250D01* +X303530Y107500D02*X304280Y108250D01* +X302030Y107500D02*X303530D01* +X301280Y109000D02*X304280Y112000D01* +X306081Y108250D02*X306831Y107500D01* +X306081Y112750D02*Y108250D01* +Y112750D02*X306831Y113500D01* +X308331D01* +X309081Y112750D01* +Y108250D01* +X308331Y107500D02*X309081Y108250D01* +X306831Y107500D02*X308331D01* +X306081Y109000D02*X309081Y112000D01* +X314333Y109750D02*Y107500D01* +Y109750D02*X315083Y110500D01* +X315833D01* +X316583Y109750D01* +Y107500D01* +Y109750D02*X317333Y110500D01* +X318083D01* +X318833Y109750D01* +Y107500D01* +X313583Y110500D02*X314333Y109750D01* +X320634Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X322136Y113500D02*Y108250D01* +X322886Y107500D01* +X325137D02*X327387D01* +X328137Y108250D01* +X327387Y109000D02*X328137Y108250D01* +X325137Y109000D02*X327387D01* +X324387Y109750D02*X325137Y109000D01* +X324387Y109750D02*X325137Y110500D01* +X327387D01* +X328137Y109750D01* +X324387Y108250D02*X325137Y107500D01* +X332639Y110500D02*Y108250D01* +X333389Y107500D01* +X334139D01* +X334889Y108250D01* +Y110500D02*Y108250D01* +X335639Y107500D01* +X336389D01* +X337139Y108250D01* +Y110500D02*Y108250D01* +X338940Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X343442Y113500D02*Y107500D01* +X342692D02*X343442Y108250D01* +X341192Y107500D02*X342692D01* +X340442Y108250D02*X341192Y107500D01* +X340442Y109750D02*Y108250D01* +Y109750D02*X341192Y110500D01* +X342692D01* +X343442Y109750D01* +X345993Y107500D02*X348243D01* +X345243Y108250D02*X345993Y107500D01* +X345243Y109750D02*Y108250D01* +Y109750D02*X345993Y110500D01* +X347493D01* +X348243Y109750D01* +X345243Y109000D02*X348243D01* +Y109750D02*Y109000D01* +X350045Y106000D02*X351545Y107500D01* +X356796D02*X358296D01* +X357546Y113500D02*Y107500D01* +X356046Y112000D02*X357546Y113500D01* +X360098Y108250D02*X360848Y107500D01* +X360098Y112750D02*Y108250D01* +Y112750D02*X360848Y113500D01* +X362348D01* +X363098Y112750D01* +Y108250D01* +X362348Y107500D02*X363098Y108250D01* +X360848Y107500D02*X362348D01* +X360098Y109000D02*X363098Y112000D01* +X364899Y108250D02*X365649Y107500D01* +X364899Y112750D02*Y108250D01* +Y112750D02*X365649Y113500D01* +X367149D01* +X367899Y112750D01* +Y108250D01* +X367149Y107500D02*X367899Y108250D01* +X365649Y107500D02*X367149D01* +X364899Y109000D02*X367899Y112000D01* +X369701Y108250D02*X370451Y107500D01* +X369701Y112750D02*Y108250D01* +Y112750D02*X370451Y113500D01* +X371951D01* +X372701Y112750D01* +Y108250D01* +X371951Y107500D02*X372701Y108250D01* +X370451Y107500D02*X371951D01* +X369701Y109000D02*X372701Y112000D01* +X377952Y109750D02*Y107500D01* +Y109750D02*X378702Y110500D01* +X379452D01* +X380202Y109750D01* +Y107500D01* +Y109750D02*X380952Y110500D01* +X381702D01* +X382452Y109750D01* +Y107500D01* +X377202Y110500D02*X377952Y109750D01* +X384254Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X385755Y113500D02*Y108250D01* +X386505Y107500D01* +X388757D02*X391007D01* +X391757Y108250D01* +X391007Y109000D02*X391757Y108250D01* +X388757Y109000D02*X391007D01* +X388007Y109750D02*X388757Y109000D01* +X388007Y109750D02*X388757Y110500D01* +X391007D01* +X391757Y109750D01* +X388007Y108250D02*X388757Y107500D01* +X396258Y113500D02*Y107500D01* +Y109750D02*X397008Y110500D01* +X398508D01* +X399258Y109750D01* +Y107500D01* +X401060Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X404811Y110500D02*X405561Y109750D01* +X403311Y110500D02*X404811D01* +X402561Y109750D02*X403311Y110500D01* +X402561Y109750D02*Y108250D01* +X403311Y107500D01* +X404811D01* +X405561Y108250D01* +X402561Y106000D02*X403311Y105250D01* +X404811D01* +X405561Y106000D01* +Y110500D02*Y106000D01* +X407363Y113500D02*Y107500D01* +Y109750D02*X408113Y110500D01* +X409613D01* +X410363Y109750D01* +Y107500D01* +X0Y-9500D02*X3000D01* +X3750Y-8750D01* +Y-7250D02*Y-8750D01* +X3000Y-6500D02*X3750Y-7250D01* +X750Y-6500D02*X3000D01* +X750Y-3500D02*Y-9500D01* +X0Y-3500D02*X3000D01* +X3750Y-4250D01* +Y-5750D01* +X3000Y-6500D02*X3750Y-5750D01* +X5551Y-7250D02*Y-8750D01* +Y-7250D02*X6301Y-6500D01* +X7801D01* +X8551Y-7250D01* +Y-8750D01* +X7801Y-9500D02*X8551Y-8750D01* +X6301Y-9500D02*X7801D01* +X5551Y-8750D02*X6301Y-9500D01* +X12603Y-6500D02*X13353Y-7250D01* +X11103Y-6500D02*X12603D01* +X10353Y-7250D02*X11103Y-6500D01* +X10353Y-7250D02*Y-8750D01* +X11103Y-9500D01* +X13353Y-6500D02*Y-8750D01* +X14103Y-9500D01* +X11103D02*X12603D01* +X13353Y-8750D01* +X16654Y-7250D02*Y-9500D01* +Y-7250D02*X17404Y-6500D01* +X18904D01* +X15904D02*X16654Y-7250D01* +X23706Y-3500D02*Y-9500D01* +X22956D02*X23706Y-8750D01* +X21456Y-9500D02*X22956D01* +X20706Y-8750D02*X21456Y-9500D01* +X20706Y-7250D02*Y-8750D01* +Y-7250D02*X21456Y-6500D01* +X22956D01* +X23706Y-7250D01* +X28207D02*Y-8750D01* +Y-7250D02*X28957Y-6500D01* +X30457D01* +X31207Y-7250D01* +Y-8750D01* +X30457Y-9500D02*X31207Y-8750D01* +X28957Y-9500D02*X30457D01* +X28207Y-8750D02*X28957Y-9500D01* +X33009Y-6500D02*Y-8750D01* +X33759Y-9500D01* +X35259D01* +X36009Y-8750D01* +Y-6500D02*Y-8750D01* +X38560Y-3500D02*Y-8750D01* +X39310Y-9500D01* +X37810Y-5750D02*X39310D01* +X40812Y-3500D02*Y-8750D01* +X41562Y-9500D01* +X43063Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X45315Y-7250D02*Y-9500D01* +Y-7250D02*X46065Y-6500D01* +X46815D01* +X47565Y-7250D01* +Y-9500D01* +X44565Y-6500D02*X45315Y-7250D01* +X50116Y-9500D02*X52366D01* +X49366Y-8750D02*X50116Y-9500D01* +X49366Y-7250D02*Y-8750D01* +Y-7250D02*X50116Y-6500D01* +X51616D01* +X52366Y-7250D01* +X49366Y-8000D02*X52366D01* +Y-7250D02*Y-8000D01* +X56868Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X59119D02*X61369D01* +X62119Y-8750D01* +X61369Y-8000D02*X62119Y-8750D01* +X59119Y-8000D02*X61369D01* +X58369Y-7250D02*X59119Y-8000D01* +X58369Y-7250D02*X59119Y-6500D01* +X61369D01* +X62119Y-7250D01* +X58369Y-8750D02*X59119Y-9500D01* +X67371Y-3500D02*Y-8750D01* +X68121Y-9500D01* +X66621Y-5750D02*X68121D01* +X69622Y-3500D02*Y-9500D01* +Y-7250D02*X70372Y-6500D01* +X71872D01* +X72622Y-7250D01* +Y-9500D01* +X75174D02*X77424D01* +X74424Y-8750D02*X75174Y-9500D01* +X74424Y-7250D02*Y-8750D01* +Y-7250D02*X75174Y-6500D01* +X76674D01* +X77424Y-7250D01* +X74424Y-8000D02*X77424D01* +Y-7250D02*Y-8000D01* +X82675Y-6500D02*X84925D01* +X81925Y-7250D02*X82675Y-6500D01* +X81925Y-7250D02*Y-8750D01* +X82675Y-9500D01* +X84925D01* +X87477D02*X89727D01* +X86727Y-8750D02*X87477Y-9500D01* +X86727Y-7250D02*Y-8750D01* +Y-7250D02*X87477Y-6500D01* +X88977D01* +X89727Y-7250D01* +X86727Y-8000D02*X89727D01* +Y-7250D02*Y-8000D01* +X92278Y-7250D02*Y-9500D01* +Y-7250D02*X93028Y-6500D01* +X93778D01* +X94528Y-7250D01* +Y-9500D01* +X91528Y-6500D02*X92278Y-7250D01* +X97080Y-3500D02*Y-8750D01* +X97830Y-9500D01* +X96330Y-5750D02*X97830D01* +X100081Y-9500D02*X102331D01* +X99331Y-8750D02*X100081Y-9500D01* +X99331Y-7250D02*Y-8750D01* +Y-7250D02*X100081Y-6500D01* +X101581D01* +X102331Y-7250D01* +X99331Y-8000D02*X102331D01* +Y-7250D02*Y-8000D01* +X104883Y-7250D02*Y-9500D01* +Y-7250D02*X105633Y-6500D01* +X107133D01* +X104133D02*X104883Y-7250D01* +X108934Y-3500D02*Y-8750D01* +X109684Y-9500D01* +X111186Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X113437Y-7250D02*Y-9500D01* +Y-7250D02*X114187Y-6500D01* +X114937D01* +X115687Y-7250D01* +Y-9500D01* +X112687Y-6500D02*X113437Y-7250D01* +X118239Y-9500D02*X120489D01* +X117489Y-8750D02*X118239Y-9500D01* +X117489Y-7250D02*Y-8750D01* +Y-7250D02*X118239Y-6500D01* +X119739D01* +X120489Y-7250D01* +X117489Y-8000D02*X120489D01* +Y-7250D02*Y-8000D01* +X124990Y-7250D02*Y-8750D01* +Y-7250D02*X125740Y-6500D01* +X127240D01* +X127990Y-7250D01* +Y-8750D01* +X127240Y-9500D02*X127990Y-8750D01* +X125740Y-9500D02*X127240D01* +X124990Y-8750D02*X125740Y-9500D01* +X130542Y-4250D02*Y-9500D01* +Y-4250D02*X131292Y-3500D01* +X132042D01* +X129792Y-6500D02*X131292D01* +X136993Y-3500D02*Y-8750D01* +X137743Y-9500D01* +X136243Y-5750D02*X137743D01* +X139245Y-3500D02*Y-9500D01* +Y-7250D02*X139995Y-6500D01* +X141495D01* +X142245Y-7250D01* +Y-9500D01* +X144046Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X146298D02*X148548D01* +X149298Y-8750D01* +X148548Y-8000D02*X149298Y-8750D01* +X146298Y-8000D02*X148548D01* +X145548Y-7250D02*X146298Y-8000D01* +X145548Y-7250D02*X146298Y-6500D01* +X148548D01* +X149298Y-7250D01* +X145548Y-8750D02*X146298Y-9500D01* +X154549D02*X156049D01* +X155299Y-3500D02*Y-9500D01* +X153799Y-5000D02*X155299Y-3500D01* +X157851Y-8750D02*X158601Y-9500D01* +X157851Y-4250D02*Y-8750D01* +Y-4250D02*X158601Y-3500D01* +X160101D01* +X160851Y-4250D01* +Y-8750D01* +X160101Y-9500D02*X160851Y-8750D01* +X158601Y-9500D02*X160101D01* +X157851Y-8000D02*X160851Y-5000D01* +X166102Y-7250D02*Y-9500D01* +Y-7250D02*X166852Y-6500D01* +X167602D01* +X168352Y-7250D01* +Y-9500D01* +Y-7250D02*X169102Y-6500D01* +X169852D01* +X170602Y-7250D01* +Y-9500D01* +X165352Y-6500D02*X166102Y-7250D01* +X172404Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X173905Y-3500D02*Y-8750D01* +X174655Y-9500D01* +X179607Y-7250D02*Y-9500D01* +Y-7250D02*X180357Y-6500D01* +X181857D01* +X178857D02*X179607Y-7250D01* +X184408Y-9500D02*X186658D01* +X183658Y-8750D02*X184408Y-9500D01* +X183658Y-7250D02*Y-8750D01* +Y-7250D02*X184408Y-6500D01* +X185908D01* +X186658Y-7250D01* +X183658Y-8000D02*X186658D01* +Y-7250D02*Y-8000D01* +X189210Y-6500D02*X191460D01* +X188460Y-7250D02*X189210Y-6500D01* +X188460Y-7250D02*Y-8750D01* +X189210Y-9500D01* +X191460D01* +X194011Y-3500D02*Y-8750D01* +X194761Y-9500D01* +X193261Y-5750D02*X194761D01* +X198513Y-6500D02*X199263Y-7250D01* +X197013Y-6500D02*X198513D01* +X196263Y-7250D02*X197013Y-6500D01* +X196263Y-7250D02*Y-8750D01* +X197013Y-9500D01* +X199263Y-6500D02*Y-8750D01* +X200013Y-9500D01* +X197013D02*X198513D01* +X199263Y-8750D01* +X202564Y-7250D02*Y-9500D01* +Y-7250D02*X203314Y-6500D01* +X204064D01* +X204814Y-7250D01* +Y-9500D01* +X201814Y-6500D02*X202564Y-7250D01* +X208866Y-6500D02*X209616Y-7250D01* +X207366Y-6500D02*X208866D01* +X206616Y-7250D02*X207366Y-6500D01* +X206616Y-7250D02*Y-8750D01* +X207366Y-9500D01* +X208866D01* +X209616Y-8750D01* +X206616Y-11000D02*X207366Y-11750D01* +X208866D01* +X209616Y-11000D01* +Y-6500D02*Y-11000D01* +X211417Y-3500D02*Y-8750D01* +X212167Y-9500D01* +X214419D02*X216669D01* +X213669Y-8750D02*X214419Y-9500D01* +X213669Y-7250D02*Y-8750D01* +Y-7250D02*X214419Y-6500D01* +X215919D01* +X216669Y-7250D01* +X213669Y-8000D02*X216669D01* +Y-7250D02*Y-8000D01* +X221170Y-6500D02*X224170D01* +X228672Y-8750D02*X229422Y-9500D01* +X228672Y-4250D02*Y-8750D01* +Y-4250D02*X229422Y-3500D01* +X230922D01* +X231672Y-4250D01* +Y-8750D01* +X230922Y-9500D02*X231672Y-8750D01* +X229422Y-9500D02*X230922D01* +X228672Y-8000D02*X231672Y-5000D01* +X233473Y-11000D02*X234973Y-9500D01* +X236775Y-8750D02*X237525Y-9500D01* +X236775Y-4250D02*Y-8750D01* +Y-4250D02*X237525Y-3500D01* +X239025D01* +X239775Y-4250D01* +Y-8750D01* +X239025Y-9500D02*X239775Y-8750D01* +X237525Y-9500D02*X239025D01* +X236775Y-8000D02*X239775Y-5000D01* +X245026Y-3500D02*Y-8750D01* +X245776Y-9500D01* +X244276Y-5750D02*X245776D01* +X247278Y-7250D02*Y-8750D01* +Y-7250D02*X248028Y-6500D01* +X249528D01* +X250278Y-7250D01* +Y-8750D01* +X249528Y-9500D02*X250278Y-8750D01* +X248028Y-9500D02*X249528D01* +X247278Y-8750D02*X248028Y-9500D01* +X254779Y-4250D02*X255529Y-3500D01* +X257779D01* +X258529Y-4250D01* +Y-5750D01* +X254779Y-9500D02*X258529Y-5750D01* +X254779Y-9500D02*X258529D01* +X260331Y-8750D02*X261081Y-9500D01* +X260331Y-4250D02*Y-8750D01* +Y-4250D02*X261081Y-3500D01* +X262581D01* +X263331Y-4250D01* +Y-8750D01* +X262581Y-9500D02*X263331Y-8750D01* +X261081Y-9500D02*X262581D01* +X260331Y-8000D02*X263331Y-5000D01* +X265132Y-8750D02*X265882Y-9500D01* +X265132Y-4250D02*Y-8750D01* +Y-4250D02*X265882Y-3500D01* +X267382D01* +X268132Y-4250D01* +Y-8750D01* +X267382Y-9500D02*X268132Y-8750D01* +X265882Y-9500D02*X267382D01* +X265132Y-8000D02*X268132Y-5000D01* +X269934Y-8750D02*X270684Y-9500D01* +X269934Y-4250D02*Y-8750D01* +Y-4250D02*X270684Y-3500D01* +X272184D01* +X272934Y-4250D01* +Y-8750D01* +X272184Y-9500D02*X272934Y-8750D01* +X270684Y-9500D02*X272184D01* +X269934Y-8000D02*X272934Y-5000D01* +X274735Y-11000D02*X276235Y-9500D01* +X278787D02*X280287D01* +X279537Y-3500D02*Y-9500D01* +X278037Y-5000D02*X279537Y-3500D01* +X282088Y-8750D02*X282838Y-9500D01* +X282088Y-4250D02*Y-8750D01* +Y-4250D02*X282838Y-3500D01* +X284338D01* +X285088Y-4250D01* +Y-8750D01* +X284338Y-9500D02*X285088Y-8750D01* +X282838Y-9500D02*X284338D01* +X282088Y-8000D02*X285088Y-5000D01* +X286890Y-8750D02*X287640Y-9500D01* +X286890Y-4250D02*Y-8750D01* +Y-4250D02*X287640Y-3500D01* +X289140D01* +X289890Y-4250D01* +Y-8750D01* +X289140Y-9500D02*X289890Y-8750D01* +X287640Y-9500D02*X289140D01* +X286890Y-8000D02*X289890Y-5000D01* +X291691Y-8750D02*X292441Y-9500D01* +X291691Y-4250D02*Y-8750D01* +Y-4250D02*X292441Y-3500D01* +X293941D01* +X294691Y-4250D01* +Y-8750D01* +X293941Y-9500D02*X294691Y-8750D01* +X292441Y-9500D02*X293941D01* +X291691Y-8000D02*X294691Y-5000D01* +X299943Y-7250D02*Y-9500D01* +Y-7250D02*X300693Y-6500D01* +X301443D01* +X302193Y-7250D01* +Y-9500D01* +Y-7250D02*X302943Y-6500D01* +X303693D01* +X304443Y-7250D01* +Y-9500D01* +X299193Y-6500D02*X299943Y-7250D01* +X306244Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X307746Y-3500D02*Y-8750D01* +X308496Y-9500D01* +X310747D02*X312997D01* +X313747Y-8750D01* +X312997Y-8000D02*X313747Y-8750D01* +X310747Y-8000D02*X312997D01* +X309997Y-7250D02*X310747Y-8000D01* +X309997Y-7250D02*X310747Y-6500D01* +X312997D01* +X313747Y-7250D01* +X309997Y-8750D02*X310747Y-9500D01* +X200750Y128500D02*Y122500D01* +X203000Y128500D02*X203750Y127750D01* +Y123250D01* +X203000Y122500D02*X203750Y123250D01* +X200000Y122500D02*X203000D01* +X200000Y128500D02*X203000D01* +X207801Y125500D02*X208551Y124750D01* +X206301Y125500D02*X207801D01* +X205551Y124750D02*X206301Y125500D01* +X205551Y124750D02*Y123250D01* +X206301Y122500D01* +X208551Y125500D02*Y123250D01* +X209301Y122500D01* +X206301D02*X207801D01* +X208551Y123250D01* +X211853Y128500D02*Y123250D01* +X212603Y122500D01* +X211103Y126250D02*X212603D01* +X214854Y122500D02*X217104D01* +X214104Y123250D02*X214854Y122500D01* +X214104Y124750D02*Y123250D01* +Y124750D02*X214854Y125500D01* +X216354D01* +X217104Y124750D01* +X214104Y124000D02*X217104D01* +Y124750D02*Y124000D01* +X218906Y126250D02*X219656D01* +X218906Y124750D02*X219656D01* +X224157Y128500D02*Y122500D01* +X226407Y124750D01* +X228657Y122500D01* +Y128500D02*Y122500D01* +X231209D02*X233459D01* +X230459Y123250D02*X231209Y122500D01* +X230459Y124750D02*Y123250D01* +Y124750D02*X231209Y125500D01* +X232709D01* +X233459Y124750D01* +X230459Y124000D02*X233459D01* +Y124750D02*Y124000D01* +X238260Y128500D02*Y122500D01* +X237510D02*X238260Y123250D01* +X236010Y122500D02*X237510D01* +X235260Y123250D02*X236010Y122500D01* +X235260Y124750D02*Y123250D01* +Y124750D02*X236010Y125500D01* +X237510D01* +X238260Y124750D01* +X242762Y128500D02*X245012D01* +Y123250D01* +X244262Y122500D02*X245012Y123250D01* +X243512Y122500D02*X244262D01* +X242762Y123250D02*X243512Y122500D01* +X246813Y125500D02*Y123250D01* +X247563Y122500D01* +X249063D01* +X249813Y123250D01* +Y125500D02*Y123250D01* +X252365Y124750D02*Y122500D01* +Y124750D02*X253115Y125500D01* +X253865D01* +X254615Y124750D01* +Y122500D01* +X251615Y125500D02*X252365Y124750D01* +X259116Y127750D02*X259866Y128500D01* +X262116D01* +X262866Y127750D01* +Y126250D01* +X259116Y122500D02*X262866Y126250D01* +X259116Y122500D02*X262866D01* +X264668Y125500D02*X267668Y128500D01* +X264668Y125500D02*X268418D01* +X267668Y128500D02*Y122500D01* +X272919Y127750D02*X273669Y128500D01* +X275919D01* +X276669Y127750D01* +Y126250D01* +X272919Y122500D02*X276669Y126250D01* +X272919Y122500D02*X276669D01* +X279221D02*X280721D01* +X279971Y128500D02*Y122500D01* +X278471Y127000D02*X279971Y128500D01* +X282522Y126250D02*X283272D01* +X282522Y124750D02*X283272D01* +X285074Y125500D02*X288074Y128500D01* +X285074Y125500D02*X288824D01* +X288074Y128500D02*Y122500D01* +X290625Y127750D02*X291375Y128500D01* +X293625D01* +X294375Y127750D01* +Y126250D01* +X290625Y122500D02*X294375Y126250D01* +X290625Y122500D02*X294375D01* +X296177Y126250D02*X296927D01* +X296177Y124750D02*X296927D01* +X298728Y127750D02*X299478Y128500D01* +X301728D01* +X302478Y127750D01* +Y126250D01* +X298728Y122500D02*X302478Y126250D01* +X298728Y122500D02*X302478D01* +X304280Y125500D02*X307280Y128500D01* +X304280Y125500D02*X308030D01* +X307280Y128500D02*Y122500D01* +X312531Y127750D02*X313281Y128500D01* +X315531D01* +X316281Y127750D01* +Y126250D01* +X312531Y122500D02*X316281Y126250D01* +X312531Y122500D02*X316281D01* +X318083Y123250D02*X318833Y122500D01* +X318083Y127750D02*Y123250D01* +Y127750D02*X318833Y128500D01* +X320333D01* +X321083Y127750D01* +Y123250D01* +X320333Y122500D02*X321083Y123250D01* +X318833Y122500D02*X320333D01* +X318083Y124000D02*X321083Y127000D01* +X322884Y123250D02*X323634Y122500D01* +X322884Y127750D02*Y123250D01* +Y127750D02*X323634Y128500D01* +X325134D01* +X325884Y127750D01* +Y123250D01* +X325134Y122500D02*X325884Y123250D01* +X323634Y122500D02*X325134D01* +X322884Y124000D02*X325884Y127000D01* +X327686Y122500D02*X330686Y125500D01* +Y127750D02*Y125500D01* +X329936Y128500D02*X330686Y127750D01* +X328436Y128500D02*X329936D01* +X327686Y127750D02*X328436Y128500D01* +X327686Y127750D02*Y126250D01* +X328436Y125500D01* +X330686D01* +X335187Y128500D02*Y123250D01* +X335937Y122500D01* +X337437D01* +X338187Y123250D01* +Y128500D02*Y123250D01* +X339989Y128500D02*X342989D01* +X341489D02*Y122500D01* +X345540D02*X347790D01* +X344790Y123250D02*X345540Y122500D01* +X344790Y127750D02*Y123250D01* +Y127750D02*X345540Y128500D01* +X347790D01* +X200000Y142750D02*Y137500D01* +Y142750D02*X200750Y143500D01* +X203000D01* +X203750Y142750D01* +Y137500D01* +X200000Y140500D02*X203750D01* +X205551D02*Y138250D01* +X206301Y137500D01* +X207801D01* +X208551Y138250D01* +Y140500D02*Y138250D01* +X211103Y143500D02*Y138250D01* +X211853Y137500D01* +X210353Y141250D02*X211853D01* +X213354Y143500D02*Y137500D01* +Y139750D02*X214104Y140500D01* +X215604D01* +X216354Y139750D01* +Y137500D01* +X218156Y139750D02*Y138250D01* +Y139750D02*X218906Y140500D01* +X220406D01* +X221156Y139750D01* +Y138250D01* +X220406Y137500D02*X221156Y138250D01* +X218906Y137500D02*X220406D01* +X218156Y138250D02*X218906Y137500D01* +X223707Y139750D02*Y137500D01* +Y139750D02*X224457Y140500D01* +X225957D01* +X222957D02*X223707Y139750D01* +X227759Y141250D02*X228509D01* +X227759Y139750D02*X228509D01* +X233760Y143500D02*Y137500D01* +X236010Y143500D02*X236760Y142750D01* +Y138250D01* +X236010Y137500D02*X236760Y138250D01* +X233010Y137500D02*X236010D01* +X233010Y143500D02*X236010D01* +X240812Y140500D02*X241562Y139750D01* +X239312Y140500D02*X240812D01* +X238562Y139750D02*X239312Y140500D01* +X238562Y139750D02*Y138250D01* +X239312Y137500D01* +X241562Y140500D02*Y138250D01* +X242312Y137500D01* +X239312D02*X240812D01* +X241562Y138250D01* +X244863Y139750D02*Y137500D01* +Y139750D02*X245613Y140500D01* +X246363D01* +X247113Y139750D01* +Y137500D01* +X244113Y140500D02*X244863Y139750D01* +X251615Y143500D02*Y137500D01* +Y143500D02*X253865Y141250D01* +X256115Y143500D01* +Y137500D01* +X258666Y140500D02*X260916D01* +X257916Y139750D02*X258666Y140500D01* +X257916Y139750D02*Y138250D01* +X258666Y137500D01* +X260916D01* +X262718Y143500D02*Y137500D01* +Y143500D02*X264968Y141250D01* +X267218Y143500D01* +Y137500D01* +X271269Y140500D02*X272019Y139750D01* +X269769Y140500D02*X271269D01* +X269019Y139750D02*X269769Y140500D01* +X269019Y139750D02*Y138250D01* +X269769Y137500D01* +X272019Y140500D02*Y138250D01* +X272769Y137500D01* +X269769D02*X271269D01* +X272019Y138250D01* +X274571Y143500D02*Y137500D01* +Y139750D02*X275321Y140500D01* +X276821D01* +X277571Y139750D01* +Y137500D01* +X279372Y142000D02*Y141250D01* +Y139750D02*Y137500D01* +X280874Y143500D02*Y138250D01* +X281624Y137500D01* +X283125Y143500D02*Y138250D01* +X283875Y137500D01* +X200000Y158500D02*X203000D01* +X201500D02*Y152500D01* +X204801Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X207053Y158500D02*Y153250D01* +X207803Y152500D01* +X206303Y156250D02*X207803D01* +X209304Y158500D02*Y153250D01* +X210054Y152500D01* +X212306D02*X214556D01* +X211556Y153250D02*X212306Y152500D01* +X211556Y154750D02*Y153250D01* +Y154750D02*X212306Y155500D01* +X213806D01* +X214556Y154750D01* +X211556Y154000D02*X214556D01* +Y154750D02*Y154000D01* +X216357Y156250D02*X217107D01* +X216357Y154750D02*X217107D01* +X221609Y152500D02*X224609D01* +X225359Y153250D01* +Y154750D02*Y153250D01* +X224609Y155500D02*X225359Y154750D01* +X222359Y155500D02*X224609D01* +X222359Y158500D02*Y152500D01* +X221609Y158500D02*X224609D01* +X225359Y157750D01* +Y156250D01* +X224609Y155500D02*X225359Y156250D01* +X229410Y155500D02*X230160Y154750D01* +X227910Y155500D02*X229410D01* +X227160Y154750D02*X227910Y155500D01* +X227160Y154750D02*Y153250D01* +X227910Y152500D01* +X230160Y155500D02*Y153250D01* +X230910Y152500D01* +X227910D02*X229410D01* +X230160Y153250D01* +X233462Y152500D02*X235712D01* +X236462Y153250D01* +X235712Y154000D02*X236462Y153250D01* +X233462Y154000D02*X235712D01* +X232712Y154750D02*X233462Y154000D01* +X232712Y154750D02*X233462Y155500D01* +X235712D01* +X236462Y154750D01* +X232712Y153250D02*X233462Y152500D01* +X238263Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X240515Y155500D02*X242765D01* +X239765Y154750D02*X240515Y155500D01* +X239765Y154750D02*Y153250D01* +X240515Y152500D01* +X242765D01* +X250266Y158500D02*X251016Y157750D01* +X248016Y158500D02*X250266D01* +X247266Y157750D02*X248016Y158500D01* +X247266Y157750D02*Y156250D01* +X248016Y155500D01* +X250266D01* +X251016Y154750D01* +Y153250D01* +X250266Y152500D02*X251016Y153250D01* +X248016Y152500D02*X250266D01* +X247266Y153250D02*X248016Y152500D01* +X252818Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X255069Y154750D02*Y152500D01* +Y154750D02*X255819Y155500D01* +X256569D01* +X257319Y154750D01* +Y152500D01* +X254319Y155500D02*X255069Y154750D01* +X261371Y155500D02*X262121Y154750D01* +X259871Y155500D02*X261371D01* +X259121Y154750D02*X259871Y155500D01* +X259121Y154750D02*Y153250D01* +X259871Y152500D01* +X261371D01* +X262121Y153250D01* +X259121Y151000D02*X259871Y150250D01* +X261371D01* +X262121Y151000D01* +Y155500D02*Y151000D01* +X263922Y158500D02*Y153250D01* +X264672Y152500D01* +X266924D02*X269174D01* +X266174Y153250D02*X266924Y152500D01* +X266174Y154750D02*Y153250D01* +Y154750D02*X266924Y155500D01* +X268424D01* +X269174Y154750D01* +X266174Y154000D02*X269174D01* +Y154750D02*Y154000D01* +X273675Y158500D02*X276675D01* +X275175D02*Y152500D01* +X279227Y154750D02*Y152500D01* +Y154750D02*X279977Y155500D01* +X281477D01* +X278477D02*X279227Y154750D01* +X285528Y155500D02*X286278Y154750D01* +X284028Y155500D02*X285528D01* +X283278Y154750D02*X284028Y155500D01* +X283278Y154750D02*Y153250D01* +X284028Y152500D01* +X286278Y155500D02*Y153250D01* +X287028Y152500D01* +X284028D02*X285528D01* +X286278Y153250D01* +X289580Y155500D02*X291830D01* +X288830Y154750D02*X289580Y155500D01* +X288830Y154750D02*Y153250D01* +X289580Y152500D01* +X291830D01* +X294381D02*X296631D01* +X293631Y153250D02*X294381Y152500D01* +X293631Y154750D02*Y153250D01* +Y154750D02*X294381Y155500D01* +X295881D01* +X296631Y154750D01* +X293631Y154000D02*X296631D01* +Y154750D02*Y154000D01* +X301133Y158500D02*X304133D01* +X304883Y157750D01* +Y156250D01* +X304133Y155500D02*X304883Y156250D01* +X301883Y155500D02*X304133D01* +X301883Y158500D02*Y152500D01* +Y155500D02*X304883Y152500D01* +X309684Y158500D02*X310434Y157750D01* +X307434Y158500D02*X309684D01* +X306684Y157750D02*X307434Y158500D01* +X306684Y157750D02*Y156250D01* +X307434Y155500D01* +X309684D01* +X310434Y154750D01* +Y153250D01* +X309684Y152500D02*X310434Y153250D01* +X307434Y152500D02*X309684D01* +X306684Y153250D02*X307434Y152500D01* +X312236Y157750D02*X312986Y158500D01* +X315236D01* +X315986Y157750D01* +Y156250D01* +X312236Y152500D02*X315986Y156250D01* +X312236Y152500D02*X315986D01* +X317787D02*X321537Y156250D01* +Y158500D02*Y156250D01* +X317787Y158500D02*X321537D01* +X323339Y155500D02*X326339Y158500D01* +X323339Y155500D02*X327089D01* +X326339Y158500D02*Y152500D01* +X328890Y155500D02*X331890D01* +X333692Y158500D02*Y157750D01* +X337442Y154000D01* +Y152500D01* +X333692Y154000D02*Y152500D01* +Y154000D02*X337442Y157750D01* +Y158500D02*Y157750D01* +X341943Y158500D02*X344943D01* +X343443D02*Y152500D01* +X347495D02*X349745D01* +X346745Y153250D02*X347495Y152500D01* +X346745Y154750D02*Y153250D01* +Y154750D02*X347495Y155500D01* +X348995D01* +X349745Y154750D01* +X346745Y154000D02*X349745D01* +Y154750D02*Y154000D01* +X352296Y152500D02*X354546D01* +X355296Y153250D01* +X354546Y154000D02*X355296Y153250D01* +X352296Y154000D02*X354546D01* +X351546Y154750D02*X352296Y154000D01* +X351546Y154750D02*X352296Y155500D01* +X354546D01* +X355296Y154750D01* +X351546Y153250D02*X352296Y152500D01* +X357848Y158500D02*Y153250D01* +X358598Y152500D01* +X357098Y156250D02*X358598D01* +X362799Y155500D02*X365799D01* +X370301Y158500D02*Y152500D01* +Y158500D02*X373301D01* +X370301Y155500D02*X372551D01* +X377352D02*X378102Y154750D01* +X375852Y155500D02*X377352D01* +X375102Y154750D02*X375852Y155500D01* +X375102Y154750D02*Y153250D01* +X375852Y152500D01* +X378102Y155500D02*Y153250D01* +X378852Y152500D01* +X375852D02*X377352D01* +X378102Y153250D01* +X380654Y158500D02*Y152500D01* +Y153250D02*X381404Y152500D01* +X382904D01* +X383654Y153250D01* +Y154750D02*Y153250D01* +X382904Y155500D02*X383654Y154750D01* +X381404Y155500D02*X382904D01* +X380654Y154750D02*X381404Y155500D01* +X386205Y154750D02*Y152500D01* +Y154750D02*X386955Y155500D01* +X388455D01* +X385455D02*X386205Y154750D01* +X390257Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X392508Y155500D02*X394758D01* +X391758Y154750D02*X392508Y155500D01* +X391758Y154750D02*Y153250D01* +X392508Y152500D01* +X394758D01* +X398810Y155500D02*X399560Y154750D01* +X397310Y155500D02*X398810D01* +X396560Y154750D02*X397310Y155500D01* +X396560Y154750D02*Y153250D01* +X397310Y152500D01* +X399560Y155500D02*Y153250D01* +X400310Y152500D01* +X397310D02*X398810D01* +X399560Y153250D01* +X402861Y158500D02*Y153250D01* +X403611Y152500D01* +X402111Y156250D02*X403611D01* +X405113Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X406614Y154750D02*Y153250D01* +Y154750D02*X407364Y155500D01* +X408864D01* +X409614Y154750D01* +Y153250D01* +X408864Y152500D02*X409614Y153250D01* +X407364Y152500D02*X408864D01* +X406614Y153250D02*X407364Y152500D01* +X412166Y154750D02*Y152500D01* +Y154750D02*X412916Y155500D01* +X413666D01* +X414416Y154750D01* +Y152500D01* +X411416Y155500D02*X412166Y154750D01* +X419667Y158500D02*Y152500D01* +X421917Y158500D02*X422667Y157750D01* +Y153250D01* +X421917Y152500D02*X422667Y153250D01* +X418917Y152500D02*X421917D01* +X418917Y158500D02*X421917D01* +X425219Y154750D02*Y152500D01* +Y154750D02*X425969Y155500D01* +X427469D01* +X424469D02*X425219Y154750D01* +X431520Y155500D02*X432270Y154750D01* +X430020Y155500D02*X431520D01* +X429270Y154750D02*X430020Y155500D01* +X429270Y154750D02*Y153250D01* +X430020Y152500D01* +X432270Y155500D02*Y153250D01* +X433020Y152500D01* +X430020D02*X431520D01* +X432270Y153250D01* +X434822Y155500D02*Y153250D01* +X435572Y152500D01* +X436322D01* +X437072Y153250D01* +Y155500D02*Y153250D01* +X437822Y152500D01* +X438572D01* +X439322Y153250D01* +Y155500D02*Y153250D01* +X441123Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X443375Y154750D02*Y152500D01* +Y154750D02*X444125Y155500D01* +X444875D01* +X445625Y154750D01* +Y152500D01* +X442625Y155500D02*X443375Y154750D01* +X449676Y155500D02*X450426Y154750D01* +X448176Y155500D02*X449676D01* +X447426Y154750D02*X448176Y155500D01* +X447426Y154750D02*Y153250D01* +X448176Y152500D01* +X449676D01* +X450426Y153250D01* +X447426Y151000D02*X448176Y150250D01* +X449676D01* +X450426Y151000D01* +Y155500D02*Y151000D01* +M02* Index: tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.plated-drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.plated-drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.plated-drill.cnc (revision 33253) @@ -0,0 +1,7 @@ +M48 +INCH +T13C0.035 +% +T13 +X009000Y005000 +M30 Index: tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.top.gbr =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.top.gbr (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber1/gerber_oneline.top.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 2 for group 0 idx 0 * +G04 Title: Basic Single Trace RS274-X Test, component * +G04 Creator: pcb 1.99y * +G04 CreationDate: Wed Jun 24 21:42:24 2009 UTC * +G04 For: dan * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 200000 100000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNFRONT*% +%ADD11C,0.0400*% +%ADD12C,0.0600*% +%ADD13C,0.0350*% +G54D11*X10000Y50000D02*X90000D01* +G54D12*D03* +G54D13*M02* Index: tags/2.3.0/tests/orig/golden/hid_gerber2/out.bottom.gbr =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber2/out.bottom.gbr (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber2/out.bottom.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 3 for group 1 idx 1 * +G04 Title: Basic Single Trace RS274-X Test, solder * +G04 Creator: pcb 1.99y * +G04 CreationDate: Wed Jun 24 22:05:35 2009 UTC * +G04 For: dan * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 200000 100000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBACK*% +%ADD11C,0.0400*% +%ADD12C,0.0600*% +%ADD13C,0.0350*% +G54D11*X170000Y50000D02*X90000D01* +G54D12*D03* +G54D13*M02* Index: tags/2.3.0/tests/orig/golden/hid_gerber2/out.fab.gbr =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber2/out.fab.gbr (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber2/out.fab.gbr (revision 33253) @@ -0,0 +1,1754 @@ +G04 start of page 5 for group -3984 idx -3984 * +G04 Title: Basic Single Trace RS274-X Test, fab * +G04 Creator: pcb 1.99y * +G04 CreationDate: Wed Jun 24 22:05:35 2009 UTC * +G04 For: dan * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 200000 100000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNFAB*% +%ADD14C,0.0080*% +%ADD15C,0.0060*% +%ADD16C,0.0100*% +G54D14*X90000Y50000D02*Y48400D01* +Y50000D02*X91386Y50800D01* +X90000Y50000D02*X88614Y50800D01* +X15000Y156250D02*Y154650D01* +Y156250D02*X16386Y157050D01* +X15000Y156250D02*X13614Y157050D01* +G54D15*X135000Y158500D02*Y157750D01* +X136500Y156250D01* +X138000Y157750D01* +Y158500D02*Y157750D01* +X136500Y156250D02*Y152500D01* +X139801Y155500D02*X142051D01* +X139801Y152500D02*X142801D01* +X139801Y158500D02*Y152500D01* +Y158500D02*X142801D01* +X147603D02*X148353Y157750D01* +X145353Y158500D02*X147603D01* +X144603Y157750D02*X145353Y158500D01* +X144603Y157750D02*Y156250D01* +X145353Y155500D01* +X147603D01* +X148353Y154750D01* +Y153250D01* +X147603Y152500D02*X148353Y153250D01* +X145353Y152500D02*X147603D01* +X144603Y153250D02*X145353Y152500D01* +X135000Y149249D02*X150154D01* +X98750Y152500D02*X100250D01* +X99500Y158500D02*Y152500D01* +X98000Y157000D02*X99500Y158500D01* +X98000Y149249D02*X102051D01* +X45000Y153250D02*X45750Y152500D01* +X45000Y157750D02*Y153250D01* +Y157750D02*X45750Y158500D01* +X47250D01* +X48000Y157750D01* +Y153250D01* +X47250Y152500D02*X48000Y153250D01* +X45750Y152500D02*X47250D01* +X45000Y154000D02*X48000Y157000D01* +X49801Y152500D02*X50551D01* +X52353Y153250D02*X53103Y152500D01* +X52353Y157750D02*Y153250D01* +Y157750D02*X53103Y158500D01* +X54603D01* +X55353Y157750D01* +Y153250D01* +X54603Y152500D02*X55353Y153250D01* +X53103Y152500D02*X54603D01* +X52353Y154000D02*X55353Y157000D01* +X57154Y157750D02*X57904Y158500D01* +X59404D01* +X60154Y157750D01* +Y153250D01* +X59404Y152500D02*X60154Y153250D01* +X57904Y152500D02*X59404D01* +X57154Y153250D02*X57904Y152500D01* +Y155500D02*X60154D01* +X61956Y158500D02*X64956D01* +X61956D02*Y155500D01* +X62706Y156250D01* +X64206D01* +X64956Y155500D01* +Y153250D01* +X64206Y152500D02*X64956Y153250D01* +X62706Y152500D02*X64206D01* +X61956Y153250D02*X62706Y152500D01* +X45000Y149249D02*X66757D01* +X3000Y173500D02*X3750Y172750D01* +X750Y173500D02*X3000D01* +X0Y172750D02*X750Y173500D01* +X0Y172750D02*Y171250D01* +X750Y170500D01* +X3000D01* +X3750Y169750D01* +Y168250D01* +X3000Y167500D02*X3750Y168250D01* +X750Y167500D02*X3000D01* +X0Y168250D02*X750Y167500D01* +X5551Y170500D02*Y168250D01* +X6301Y167500D01* +X8551Y170500D02*Y166000D01* +X7801Y165250D02*X8551Y166000D01* +X6301Y165250D02*X7801D01* +X5551Y166000D02*X6301Y165250D01* +Y167500D02*X7801D01* +X8551Y168250D01* +X11103Y169750D02*Y167500D01* +Y169750D02*X11853Y170500D01* +X12603D01* +X13353Y169750D01* +Y167500D01* +Y169750D02*X14103Y170500D01* +X14853D01* +X15603Y169750D01* +Y167500D01* +X10353Y170500D02*X11103Y169750D01* +X17404Y173500D02*Y167500D01* +Y168250D02*X18154Y167500D01* +X19654D01* +X20404Y168250D01* +Y169750D02*Y168250D01* +X19654Y170500D02*X20404Y169750D01* +X18154Y170500D02*X19654D01* +X17404Y169750D02*X18154Y170500D01* +X22206Y169750D02*Y168250D01* +Y169750D02*X22956Y170500D01* +X24456D01* +X25206Y169750D01* +Y168250D01* +X24456Y167500D02*X25206Y168250D01* +X22956Y167500D02*X24456D01* +X22206Y168250D02*X22956Y167500D01* +X27007Y173500D02*Y168250D01* +X27757Y167500D01* +X41750Y173500D02*Y167500D01* +X44000Y173500D02*X44750Y172750D01* +Y168250D01* +X44000Y167500D02*X44750Y168250D01* +X41000Y167500D02*X44000D01* +X41000Y173500D02*X44000D01* +X46551Y172000D02*Y171250D01* +Y169750D02*Y167500D01* +X50303Y170500D02*X51053Y169750D01* +X48803Y170500D02*X50303D01* +X48053Y169750D02*X48803Y170500D01* +X48053Y169750D02*Y168250D01* +X48803Y167500D01* +X51053Y170500D02*Y168250D01* +X51803Y167500D01* +X48803D02*X50303D01* +X51053Y168250D01* +X54354Y169750D02*Y167500D01* +Y169750D02*X55104Y170500D01* +X55854D01* +X56604Y169750D01* +Y167500D01* +Y169750D02*X57354Y170500D01* +X58104D01* +X58854Y169750D01* +Y167500D01* +X53604Y170500D02*X54354Y169750D01* +X60656Y167500D02*X61406D01* +X65907Y168250D02*X66657Y167500D01* +X65907Y172750D02*X66657Y173500D01* +X65907Y172750D02*Y168250D01* +X68459Y173500D02*X69959D01* +X69209D02*Y167500D01* +X68459D02*X69959D01* +X72510Y169750D02*Y167500D01* +Y169750D02*X73260Y170500D01* +X74010D01* +X74760Y169750D01* +Y167500D01* +X71760Y170500D02*X72510Y169750D01* +X77312Y170500D02*X79562D01* +X76562Y169750D02*X77312Y170500D01* +X76562Y169750D02*Y168250D01* +X77312Y167500D01* +X79562D01* +X81363Y173500D02*Y167500D01* +Y169750D02*X82113Y170500D01* +X83613D01* +X84363Y169750D01* +Y167500D01* +X86165Y173500D02*X86915Y172750D01* +Y168250D01* +X86165Y167500D02*X86915Y168250D01* +X95750Y167500D02*X98000D01* +X95000Y168250D02*X95750Y167500D01* +X95000Y172750D02*Y168250D01* +Y172750D02*X95750Y173500D01* +X98000D01* +X99801Y169750D02*Y168250D01* +Y169750D02*X100551Y170500D01* +X102051D01* +X102801Y169750D01* +Y168250D01* +X102051Y167500D02*X102801Y168250D01* +X100551Y167500D02*X102051D01* +X99801Y168250D02*X100551Y167500D01* +X104603Y170500D02*Y168250D01* +X105353Y167500D01* +X106853D01* +X107603Y168250D01* +Y170500D02*Y168250D01* +X110154Y169750D02*Y167500D01* +Y169750D02*X110904Y170500D01* +X111654D01* +X112404Y169750D01* +Y167500D01* +X109404Y170500D02*X110154Y169750D01* +X114956Y173500D02*Y168250D01* +X115706Y167500D01* +X114206Y171250D02*X115706D01* +X130750Y173500D02*Y167500D01* +X130000Y173500D02*X133000D01* +X133750Y172750D01* +Y171250D01* +X133000Y170500D02*X133750Y171250D01* +X130750Y170500D02*X133000D01* +X135551Y173500D02*Y168250D01* +X136301Y167500D01* +X140053Y170500D02*X140803Y169750D01* +X138553Y170500D02*X140053D01* +X137803Y169750D02*X138553Y170500D01* +X137803Y169750D02*Y168250D01* +X138553Y167500D01* +X140803Y170500D02*Y168250D01* +X141553Y167500D01* +X138553D02*X140053D01* +X140803Y168250D01* +X144104Y173500D02*Y168250D01* +X144854Y167500D01* +X143354Y171250D02*X144854D01* +X147106Y167500D02*X149356D01* +X146356Y168250D02*X147106Y167500D01* +X146356Y169750D02*Y168250D01* +Y169750D02*X147106Y170500D01* +X148606D01* +X149356Y169750D01* +X146356Y169000D02*X149356D01* +Y169750D02*Y169000D01* +X154157Y173500D02*Y167500D01* +X153407D02*X154157Y168250D01* +X151907Y167500D02*X153407D01* +X151157Y168250D02*X151907Y167500D01* +X151157Y169750D02*Y168250D01* +Y169750D02*X151907Y170500D01* +X153407D01* +X154157Y169750D01* +X157459Y170500D02*Y169750D01* +Y168250D02*Y167500D01* +X155959Y172750D02*Y172000D01* +Y172750D02*X156709Y173500D01* +X158209D01* +X158959Y172750D01* +Y172000D01* +X157459Y170500D02*X158959Y172000D01* +X0Y188500D02*X3000D01* +X1500D02*Y182500D01* +X4801Y188500D02*Y182500D01* +Y184750D02*X5551Y185500D01* +X7051D01* +X7801Y184750D01* +Y182500D01* +X10353D02*X12603D01* +X9603Y183250D02*X10353Y182500D01* +X9603Y184750D02*Y183250D01* +Y184750D02*X10353Y185500D01* +X11853D01* +X12603Y184750D01* +X9603Y184000D02*X12603D01* +Y184750D02*Y184000D01* +X15154Y184750D02*Y182500D01* +Y184750D02*X15904Y185500D01* +X17404D01* +X14404D02*X15154Y184750D01* +X19956Y182500D02*X22206D01* +X19206Y183250D02*X19956Y182500D01* +X19206Y184750D02*Y183250D01* +Y184750D02*X19956Y185500D01* +X21456D01* +X22206Y184750D01* +X19206Y184000D02*X22206D01* +Y184750D02*Y184000D01* +X28957Y185500D02*X29707Y184750D01* +X27457Y185500D02*X28957D01* +X26707Y184750D02*X27457Y185500D01* +X26707Y184750D02*Y183250D01* +X27457Y182500D01* +X29707Y185500D02*Y183250D01* +X30457Y182500D01* +X27457D02*X28957D01* +X29707Y183250D01* +X33009Y184750D02*Y182500D01* +Y184750D02*X33759Y185500D01* +X35259D01* +X32259D02*X33009Y184750D01* +X37810Y182500D02*X40060D01* +X37060Y183250D02*X37810Y182500D01* +X37060Y184750D02*Y183250D01* +Y184750D02*X37810Y185500D01* +X39310D01* +X40060Y184750D01* +X37060Y184000D02*X40060D01* +Y184750D02*Y184000D01* +X45312Y182500D02*X46812D01* +X46062Y188500D02*Y182500D01* +X44562Y187000D02*X46062Y188500D01* +X54313D02*Y182500D01* +X53563D02*X54313Y183250D01* +X52063Y182500D02*X53563D01* +X51313Y183250D02*X52063Y182500D01* +X51313Y184750D02*Y183250D01* +Y184750D02*X52063Y185500D01* +X53563D01* +X54313Y184750D01* +X56115Y187000D02*Y186250D01* +Y184750D02*Y182500D01* +X58366Y187750D02*Y182500D01* +Y187750D02*X59116Y188500D01* +X59866D01* +X57616Y185500D02*X59116D01* +X62118Y187750D02*Y182500D01* +Y187750D02*X62868Y188500D01* +X63618D01* +X61368Y185500D02*X62868D01* +X65869Y182500D02*X68119D01* +X65119Y183250D02*X65869Y182500D01* +X65119Y184750D02*Y183250D01* +Y184750D02*X65869Y185500D01* +X67369D01* +X68119Y184750D01* +X65119Y184000D02*X68119D01* +Y184750D02*Y184000D01* +X70671Y184750D02*Y182500D01* +Y184750D02*X71421Y185500D01* +X72921D01* +X69921D02*X70671Y184750D01* +X75472Y182500D02*X77722D01* +X74722Y183250D02*X75472Y182500D01* +X74722Y184750D02*Y183250D01* +Y184750D02*X75472Y185500D01* +X76972D01* +X77722Y184750D01* +X74722Y184000D02*X77722D01* +Y184750D02*Y184000D01* +X80274Y184750D02*Y182500D01* +Y184750D02*X81024Y185500D01* +X81774D01* +X82524Y184750D01* +Y182500D01* +X79524Y185500D02*X80274Y184750D01* +X85075Y188500D02*Y183250D01* +X85825Y182500D01* +X84325Y186250D02*X85825D01* +X93027Y188500D02*Y182500D01* +X92277D02*X93027Y183250D01* +X90777Y182500D02*X92277D01* +X90027Y183250D02*X90777Y182500D01* +X90027Y184750D02*Y183250D01* +Y184750D02*X90777Y185500D01* +X92277D01* +X93027Y184750D01* +X95578D02*Y182500D01* +Y184750D02*X96328Y185500D01* +X97828D01* +X94828D02*X95578Y184750D01* +X99630Y187000D02*Y186250D01* +Y184750D02*Y182500D01* +X101131Y188500D02*Y183250D01* +X101881Y182500D01* +X103383Y188500D02*Y183250D01* +X104133Y182500D01* +X109084D02*X111334D01* +X112084Y183250D01* +X111334Y184000D02*X112084Y183250D01* +X109084Y184000D02*X111334D01* +X108334Y184750D02*X109084Y184000D01* +X108334Y184750D02*X109084Y185500D01* +X111334D01* +X112084Y184750D01* +X108334Y183250D02*X109084Y182500D01* +X113886Y187000D02*Y186250D01* +Y184750D02*Y182500D01* +X115387Y185500D02*X118387D01* +X115387Y182500D02*X118387Y185500D01* +X115387Y182500D02*X118387D01* +X120939D02*X123189D01* +X120189Y183250D02*X120939Y182500D01* +X120189Y184750D02*Y183250D01* +Y184750D02*X120939Y185500D01* +X122439D01* +X123189Y184750D01* +X120189Y184000D02*X123189D01* +Y184750D02*Y184000D01* +X125740Y182500D02*X127990D01* +X128740Y183250D01* +X127990Y184000D02*X128740Y183250D01* +X125740Y184000D02*X127990D01* +X124990Y184750D02*X125740Y184000D01* +X124990Y184750D02*X125740Y185500D01* +X127990D01* +X128740Y184750D01* +X124990Y183250D02*X125740Y182500D01* +X133242Y185500D02*Y183250D01* +X133992Y182500D01* +X135492D01* +X136242Y183250D01* +Y185500D02*Y183250D01* +X138793Y182500D02*X141043D01* +X141793Y183250D01* +X141043Y184000D02*X141793Y183250D01* +X138793Y184000D02*X141043D01* +X138043Y184750D02*X138793Y184000D01* +X138043Y184750D02*X138793Y185500D01* +X141043D01* +X141793Y184750D01* +X138043Y183250D02*X138793Y182500D01* +X144345D02*X146595D01* +X143595Y183250D02*X144345Y182500D01* +X143595Y184750D02*Y183250D01* +Y184750D02*X144345Y185500D01* +X145845D01* +X146595Y184750D01* +X143595Y184000D02*X146595D01* +Y184750D02*Y184000D01* +X151396Y188500D02*Y182500D01* +X150646D02*X151396Y183250D01* +X149146Y182500D02*X150646D01* +X148396Y183250D02*X149146Y182500D01* +X148396Y184750D02*Y183250D01* +Y184750D02*X149146Y185500D01* +X150646D01* +X151396Y184750D01* +X155898Y187000D02*Y186250D01* +Y184750D02*Y182500D01* +X158149Y184750D02*Y182500D01* +Y184750D02*X158899Y185500D01* +X159649D01* +X160399Y184750D01* +Y182500D01* +X157399Y185500D02*X158149Y184750D01* +X165651Y188500D02*Y183250D01* +X166401Y182500D01* +X164901Y186250D02*X166401D01* +X167902Y188500D02*Y182500D01* +Y184750D02*X168652Y185500D01* +X170152D01* +X170902Y184750D01* +Y182500D01* +X172704Y187000D02*Y186250D01* +Y184750D02*Y182500D01* +X174955D02*X177205D01* +X177955Y183250D01* +X177205Y184000D02*X177955Y183250D01* +X174955Y184000D02*X177205D01* +X174205Y184750D02*X174955Y184000D01* +X174205Y184750D02*X174955Y185500D01* +X177205D01* +X177955Y184750D01* +X174205Y183250D02*X174955Y182500D01* +X182457Y188500D02*Y183250D01* +X183207Y182500D01* +X186958Y185500D02*X187708Y184750D01* +X185458Y185500D02*X186958D01* +X184708Y184750D02*X185458Y185500D01* +X184708Y184750D02*Y183250D01* +X185458Y182500D01* +X187708Y185500D02*Y183250D01* +X188458Y182500D01* +X185458D02*X186958D01* +X187708Y183250D01* +X190260Y185500D02*Y183250D01* +X191010Y182500D01* +X193260Y185500D02*Y181000D01* +X192510Y180250D02*X193260Y181000D01* +X191010Y180250D02*X192510D01* +X190260Y181000D02*X191010Y180250D01* +Y182500D02*X192510D01* +X193260Y183250D01* +X195061Y184750D02*Y183250D01* +Y184750D02*X195811Y185500D01* +X197311D01* +X198061Y184750D01* +Y183250D01* +X197311Y182500D02*X198061Y183250D01* +X195811Y182500D02*X197311D01* +X195061Y183250D02*X195811Y182500D01* +X199863Y185500D02*Y183250D01* +X200613Y182500D01* +X202113D01* +X202863Y183250D01* +Y185500D02*Y183250D01* +X205414Y188500D02*Y183250D01* +X206164Y182500D01* +X204664Y186250D02*X206164D01* +X207666Y181000D02*X209166Y182500D01* +X214417D02*X215917D01* +X215167Y188500D02*Y182500D01* +X213667Y187000D02*X215167Y188500D01* +X220419D02*Y182500D01* +Y184750D02*X221169Y185500D01* +X222669D01* +X223419Y184750D01* +Y182500D01* +X225220Y184750D02*Y183250D01* +Y184750D02*X225970Y185500D01* +X227470D01* +X228220Y184750D01* +Y183250D01* +X227470Y182500D02*X228220Y183250D01* +X225970Y182500D02*X227470D01* +X225220Y183250D02*X225970Y182500D01* +X230022Y188500D02*Y183250D01* +X230772Y182500D01* +X233023D02*X235273D01* +X232273Y183250D02*X233023Y182500D01* +X232273Y184750D02*Y183250D01* +Y184750D02*X233023Y185500D01* +X234523D01* +X235273Y184750D01* +X232273Y184000D02*X235273D01* +Y184750D02*Y184000D01* +X237825Y182500D02*X240075D01* +X240825Y183250D01* +X240075Y184000D02*X240825Y183250D01* +X237825Y184000D02*X240075D01* +X237075Y184750D02*X237825Y184000D01* +X237075Y184750D02*X237825Y185500D01* +X240075D01* +X240825Y184750D01* +X237075Y183250D02*X237825Y182500D01* +X246076Y188500D02*Y183250D01* +X246826Y182500D01* +X245326Y186250D02*X246826D01* +X248328Y184750D02*Y183250D01* +Y184750D02*X249078Y185500D01* +X250578D01* +X251328Y184750D01* +Y183250D01* +X250578Y182500D02*X251328Y183250D01* +X249078Y182500D02*X250578D01* +X248328Y183250D02*X249078Y182500D01* +X253879Y188500D02*Y183250D01* +X254629Y182500D01* +X253129Y186250D02*X254629D01* +X258381Y185500D02*X259131Y184750D01* +X256881Y185500D02*X258381D01* +X256131Y184750D02*X256881Y185500D01* +X256131Y184750D02*Y183250D01* +X256881Y182500D01* +X259131Y185500D02*Y183250D01* +X259881Y182500D01* +X256881D02*X258381D01* +X259131Y183250D01* +X261682Y188500D02*Y183250D01* +X262432Y182500D01* +G54D16*X0Y100000D02*X200000D01* +X0D02*Y0D01* +X200000Y100000D02*Y0D01* +X0D02*X200000D01* +G54D15*Y113500D02*Y107500D01* +Y113500D02*X202250Y111250D01* +X204500Y113500D01* +Y107500D01* +X208551Y110500D02*X209301Y109750D01* +X207051Y110500D02*X208551D01* +X206301Y109750D02*X207051Y110500D01* +X206301Y109750D02*Y108250D01* +X207051Y107500D01* +X209301Y110500D02*Y108250D01* +X210051Y107500D01* +X207051D02*X208551D01* +X209301Y108250D01* +X211853Y110500D02*X214853Y107500D01* +X211853D02*X214853Y110500D01* +X216654Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X218906Y109750D02*Y107500D01* +Y109750D02*X219656Y110500D01* +X220406D01* +X221156Y109750D01* +Y107500D01* +Y109750D02*X221906Y110500D01* +X222656D01* +X223406Y109750D01* +Y107500D01* +X218156Y110500D02*X218906Y109750D01* +X225207Y110500D02*Y108250D01* +X225957Y107500D01* +X227457D01* +X228207Y108250D01* +Y110500D02*Y108250D01* +X230759Y109750D02*Y107500D01* +Y109750D02*X231509Y110500D01* +X232259D01* +X233009Y109750D01* +Y107500D01* +Y109750D02*X233759Y110500D01* +X234509D01* +X235259Y109750D01* +Y107500D01* +X230009Y110500D02*X230759Y109750D01* +X240510Y113500D02*Y107500D01* +X242760Y113500D02*X243510Y112750D01* +Y108250D01* +X242760Y107500D02*X243510Y108250D01* +X239760Y107500D02*X242760D01* +X239760Y113500D02*X242760D01* +X245312Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X247563Y109750D02*Y107500D01* +Y109750D02*X248313Y110500D01* +X249063D01* +X249813Y109750D01* +Y107500D01* +Y109750D02*X250563Y110500D01* +X251313D01* +X252063Y109750D01* +Y107500D01* +X246813Y110500D02*X247563Y109750D01* +X254615Y107500D02*X256865D01* +X253865Y108250D02*X254615Y107500D01* +X253865Y109750D02*Y108250D01* +Y109750D02*X254615Y110500D01* +X256115D01* +X256865Y109750D01* +X253865Y109000D02*X256865D01* +Y109750D02*Y109000D01* +X259416Y109750D02*Y107500D01* +Y109750D02*X260166Y110500D01* +X260916D01* +X261666Y109750D01* +Y107500D01* +X258666Y110500D02*X259416Y109750D01* +X264218Y107500D02*X266468D01* +X267218Y108250D01* +X266468Y109000D02*X267218Y108250D01* +X264218Y109000D02*X266468D01* +X263468Y109750D02*X264218Y109000D01* +X263468Y109750D02*X264218Y110500D01* +X266468D01* +X267218Y109750D01* +X263468Y108250D02*X264218Y107500D01* +X269019Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X270521Y109750D02*Y108250D01* +Y109750D02*X271271Y110500D01* +X272771D01* +X273521Y109750D01* +Y108250D01* +X272771Y107500D02*X273521Y108250D01* +X271271Y107500D02*X272771D01* +X270521Y108250D02*X271271Y107500D01* +X276072Y109750D02*Y107500D01* +Y109750D02*X276822Y110500D01* +X277572D01* +X278322Y109750D01* +Y107500D01* +X275322Y110500D02*X276072Y109750D01* +X280874Y107500D02*X283124D01* +X283874Y108250D01* +X283124Y109000D02*X283874Y108250D01* +X280874Y109000D02*X283124D01* +X280124Y109750D02*X280874Y109000D01* +X280124Y109750D02*X280874Y110500D01* +X283124D01* +X283874Y109750D01* +X280124Y108250D02*X280874Y107500D01* +X285675Y111250D02*X286425D01* +X285675Y109750D02*X286425D01* +X290927Y112750D02*X291677Y113500D01* +X293927D01* +X294677Y112750D01* +Y111250D01* +X290927Y107500D02*X294677Y111250D01* +X290927Y107500D02*X294677D01* +X296478Y108250D02*X297228Y107500D01* +X296478Y112750D02*Y108250D01* +Y112750D02*X297228Y113500D01* +X298728D01* +X299478Y112750D01* +Y108250D01* +X298728Y107500D02*X299478Y108250D01* +X297228Y107500D02*X298728D01* +X296478Y109000D02*X299478Y112000D01* +X301280Y108250D02*X302030Y107500D01* +X301280Y112750D02*Y108250D01* +Y112750D02*X302030Y113500D01* +X303530D01* +X304280Y112750D01* +Y108250D01* +X303530Y107500D02*X304280Y108250D01* +X302030Y107500D02*X303530D01* +X301280Y109000D02*X304280Y112000D01* +X306081Y108250D02*X306831Y107500D01* +X306081Y112750D02*Y108250D01* +Y112750D02*X306831Y113500D01* +X308331D01* +X309081Y112750D01* +Y108250D01* +X308331Y107500D02*X309081Y108250D01* +X306831Y107500D02*X308331D01* +X306081Y109000D02*X309081Y112000D01* +X314333Y109750D02*Y107500D01* +Y109750D02*X315083Y110500D01* +X315833D01* +X316583Y109750D01* +Y107500D01* +Y109750D02*X317333Y110500D01* +X318083D01* +X318833Y109750D01* +Y107500D01* +X313583Y110500D02*X314333Y109750D01* +X320634Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X322136Y113500D02*Y108250D01* +X322886Y107500D01* +X325137D02*X327387D01* +X328137Y108250D01* +X327387Y109000D02*X328137Y108250D01* +X325137Y109000D02*X327387D01* +X324387Y109750D02*X325137Y109000D01* +X324387Y109750D02*X325137Y110500D01* +X327387D01* +X328137Y109750D01* +X324387Y108250D02*X325137Y107500D01* +X332639Y110500D02*Y108250D01* +X333389Y107500D01* +X334139D01* +X334889Y108250D01* +Y110500D02*Y108250D01* +X335639Y107500D01* +X336389D01* +X337139Y108250D01* +Y110500D02*Y108250D01* +X338940Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X343442Y113500D02*Y107500D01* +X342692D02*X343442Y108250D01* +X341192Y107500D02*X342692D01* +X340442Y108250D02*X341192Y107500D01* +X340442Y109750D02*Y108250D01* +Y109750D02*X341192Y110500D01* +X342692D01* +X343442Y109750D01* +X345993Y107500D02*X348243D01* +X345243Y108250D02*X345993Y107500D01* +X345243Y109750D02*Y108250D01* +Y109750D02*X345993Y110500D01* +X347493D01* +X348243Y109750D01* +X345243Y109000D02*X348243D01* +Y109750D02*Y109000D01* +X350045Y106000D02*X351545Y107500D01* +X356796D02*X358296D01* +X357546Y113500D02*Y107500D01* +X356046Y112000D02*X357546Y113500D01* +X360098Y108250D02*X360848Y107500D01* +X360098Y112750D02*Y108250D01* +Y112750D02*X360848Y113500D01* +X362348D01* +X363098Y112750D01* +Y108250D01* +X362348Y107500D02*X363098Y108250D01* +X360848Y107500D02*X362348D01* +X360098Y109000D02*X363098Y112000D01* +X364899Y108250D02*X365649Y107500D01* +X364899Y112750D02*Y108250D01* +Y112750D02*X365649Y113500D01* +X367149D01* +X367899Y112750D01* +Y108250D01* +X367149Y107500D02*X367899Y108250D01* +X365649Y107500D02*X367149D01* +X364899Y109000D02*X367899Y112000D01* +X369701Y108250D02*X370451Y107500D01* +X369701Y112750D02*Y108250D01* +Y112750D02*X370451Y113500D01* +X371951D01* +X372701Y112750D01* +Y108250D01* +X371951Y107500D02*X372701Y108250D01* +X370451Y107500D02*X371951D01* +X369701Y109000D02*X372701Y112000D01* +X377952Y109750D02*Y107500D01* +Y109750D02*X378702Y110500D01* +X379452D01* +X380202Y109750D01* +Y107500D01* +Y109750D02*X380952Y110500D01* +X381702D01* +X382452Y109750D01* +Y107500D01* +X377202Y110500D02*X377952Y109750D01* +X384254Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X385755Y113500D02*Y108250D01* +X386505Y107500D01* +X388757D02*X391007D01* +X391757Y108250D01* +X391007Y109000D02*X391757Y108250D01* +X388757Y109000D02*X391007D01* +X388007Y109750D02*X388757Y109000D01* +X388007Y109750D02*X388757Y110500D01* +X391007D01* +X391757Y109750D01* +X388007Y108250D02*X388757Y107500D01* +X396258Y113500D02*Y107500D01* +Y109750D02*X397008Y110500D01* +X398508D01* +X399258Y109750D01* +Y107500D01* +X401060Y112000D02*Y111250D01* +Y109750D02*Y107500D01* +X404811Y110500D02*X405561Y109750D01* +X403311Y110500D02*X404811D01* +X402561Y109750D02*X403311Y110500D01* +X402561Y109750D02*Y108250D01* +X403311Y107500D01* +X404811D01* +X405561Y108250D01* +X402561Y106000D02*X403311Y105250D01* +X404811D01* +X405561Y106000D01* +Y110500D02*Y106000D01* +X407363Y113500D02*Y107500D01* +Y109750D02*X408113Y110500D01* +X409613D01* +X410363Y109750D01* +Y107500D01* +X0Y-9500D02*X3000D01* +X3750Y-8750D01* +Y-7250D02*Y-8750D01* +X3000Y-6500D02*X3750Y-7250D01* +X750Y-6500D02*X3000D01* +X750Y-3500D02*Y-9500D01* +X0Y-3500D02*X3000D01* +X3750Y-4250D01* +Y-5750D01* +X3000Y-6500D02*X3750Y-5750D01* +X5551Y-7250D02*Y-8750D01* +Y-7250D02*X6301Y-6500D01* +X7801D01* +X8551Y-7250D01* +Y-8750D01* +X7801Y-9500D02*X8551Y-8750D01* +X6301Y-9500D02*X7801D01* +X5551Y-8750D02*X6301Y-9500D01* +X12603Y-6500D02*X13353Y-7250D01* +X11103Y-6500D02*X12603D01* +X10353Y-7250D02*X11103Y-6500D01* +X10353Y-7250D02*Y-8750D01* +X11103Y-9500D01* +X13353Y-6500D02*Y-8750D01* +X14103Y-9500D01* +X11103D02*X12603D01* +X13353Y-8750D01* +X16654Y-7250D02*Y-9500D01* +Y-7250D02*X17404Y-6500D01* +X18904D01* +X15904D02*X16654Y-7250D01* +X23706Y-3500D02*Y-9500D01* +X22956D02*X23706Y-8750D01* +X21456Y-9500D02*X22956D01* +X20706Y-8750D02*X21456Y-9500D01* +X20706Y-7250D02*Y-8750D01* +Y-7250D02*X21456Y-6500D01* +X22956D01* +X23706Y-7250D01* +X28207D02*Y-8750D01* +Y-7250D02*X28957Y-6500D01* +X30457D01* +X31207Y-7250D01* +Y-8750D01* +X30457Y-9500D02*X31207Y-8750D01* +X28957Y-9500D02*X30457D01* +X28207Y-8750D02*X28957Y-9500D01* +X33009Y-6500D02*Y-8750D01* +X33759Y-9500D01* +X35259D01* +X36009Y-8750D01* +Y-6500D02*Y-8750D01* +X38560Y-3500D02*Y-8750D01* +X39310Y-9500D01* +X37810Y-5750D02*X39310D01* +X40812Y-3500D02*Y-8750D01* +X41562Y-9500D01* +X43063Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X45315Y-7250D02*Y-9500D01* +Y-7250D02*X46065Y-6500D01* +X46815D01* +X47565Y-7250D01* +Y-9500D01* +X44565Y-6500D02*X45315Y-7250D01* +X50116Y-9500D02*X52366D01* +X49366Y-8750D02*X50116Y-9500D01* +X49366Y-7250D02*Y-8750D01* +Y-7250D02*X50116Y-6500D01* +X51616D01* +X52366Y-7250D01* +X49366Y-8000D02*X52366D01* +Y-7250D02*Y-8000D01* +X56868Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X59119D02*X61369D01* +X62119Y-8750D01* +X61369Y-8000D02*X62119Y-8750D01* +X59119Y-8000D02*X61369D01* +X58369Y-7250D02*X59119Y-8000D01* +X58369Y-7250D02*X59119Y-6500D01* +X61369D01* +X62119Y-7250D01* +X58369Y-8750D02*X59119Y-9500D01* +X67371Y-3500D02*Y-8750D01* +X68121Y-9500D01* +X66621Y-5750D02*X68121D01* +X69622Y-3500D02*Y-9500D01* +Y-7250D02*X70372Y-6500D01* +X71872D01* +X72622Y-7250D01* +Y-9500D01* +X75174D02*X77424D01* +X74424Y-8750D02*X75174Y-9500D01* +X74424Y-7250D02*Y-8750D01* +Y-7250D02*X75174Y-6500D01* +X76674D01* +X77424Y-7250D01* +X74424Y-8000D02*X77424D01* +Y-7250D02*Y-8000D01* +X82675Y-6500D02*X84925D01* +X81925Y-7250D02*X82675Y-6500D01* +X81925Y-7250D02*Y-8750D01* +X82675Y-9500D01* +X84925D01* +X87477D02*X89727D01* +X86727Y-8750D02*X87477Y-9500D01* +X86727Y-7250D02*Y-8750D01* +Y-7250D02*X87477Y-6500D01* +X88977D01* +X89727Y-7250D01* +X86727Y-8000D02*X89727D01* +Y-7250D02*Y-8000D01* +X92278Y-7250D02*Y-9500D01* +Y-7250D02*X93028Y-6500D01* +X93778D01* +X94528Y-7250D01* +Y-9500D01* +X91528Y-6500D02*X92278Y-7250D01* +X97080Y-3500D02*Y-8750D01* +X97830Y-9500D01* +X96330Y-5750D02*X97830D01* +X100081Y-9500D02*X102331D01* +X99331Y-8750D02*X100081Y-9500D01* +X99331Y-7250D02*Y-8750D01* +Y-7250D02*X100081Y-6500D01* +X101581D01* +X102331Y-7250D01* +X99331Y-8000D02*X102331D01* +Y-7250D02*Y-8000D01* +X104883Y-7250D02*Y-9500D01* +Y-7250D02*X105633Y-6500D01* +X107133D01* +X104133D02*X104883Y-7250D01* +X108934Y-3500D02*Y-8750D01* +X109684Y-9500D01* +X111186Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X113437Y-7250D02*Y-9500D01* +Y-7250D02*X114187Y-6500D01* +X114937D01* +X115687Y-7250D01* +Y-9500D01* +X112687Y-6500D02*X113437Y-7250D01* +X118239Y-9500D02*X120489D01* +X117489Y-8750D02*X118239Y-9500D01* +X117489Y-7250D02*Y-8750D01* +Y-7250D02*X118239Y-6500D01* +X119739D01* +X120489Y-7250D01* +X117489Y-8000D02*X120489D01* +Y-7250D02*Y-8000D01* +X124990Y-7250D02*Y-8750D01* +Y-7250D02*X125740Y-6500D01* +X127240D01* +X127990Y-7250D01* +Y-8750D01* +X127240Y-9500D02*X127990Y-8750D01* +X125740Y-9500D02*X127240D01* +X124990Y-8750D02*X125740Y-9500D01* +X130542Y-4250D02*Y-9500D01* +Y-4250D02*X131292Y-3500D01* +X132042D01* +X129792Y-6500D02*X131292D01* +X136993Y-3500D02*Y-8750D01* +X137743Y-9500D01* +X136243Y-5750D02*X137743D01* +X139245Y-3500D02*Y-9500D01* +Y-7250D02*X139995Y-6500D01* +X141495D01* +X142245Y-7250D01* +Y-9500D01* +X144046Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X146298D02*X148548D01* +X149298Y-8750D01* +X148548Y-8000D02*X149298Y-8750D01* +X146298Y-8000D02*X148548D01* +X145548Y-7250D02*X146298Y-8000D01* +X145548Y-7250D02*X146298Y-6500D01* +X148548D01* +X149298Y-7250D01* +X145548Y-8750D02*X146298Y-9500D01* +X154549D02*X156049D01* +X155299Y-3500D02*Y-9500D01* +X153799Y-5000D02*X155299Y-3500D01* +X157851Y-8750D02*X158601Y-9500D01* +X157851Y-4250D02*Y-8750D01* +Y-4250D02*X158601Y-3500D01* +X160101D01* +X160851Y-4250D01* +Y-8750D01* +X160101Y-9500D02*X160851Y-8750D01* +X158601Y-9500D02*X160101D01* +X157851Y-8000D02*X160851Y-5000D01* +X166102Y-7250D02*Y-9500D01* +Y-7250D02*X166852Y-6500D01* +X167602D01* +X168352Y-7250D01* +Y-9500D01* +Y-7250D02*X169102Y-6500D01* +X169852D01* +X170602Y-7250D01* +Y-9500D01* +X165352Y-6500D02*X166102Y-7250D01* +X172404Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X173905Y-3500D02*Y-8750D01* +X174655Y-9500D01* +X179607Y-7250D02*Y-9500D01* +Y-7250D02*X180357Y-6500D01* +X181857D01* +X178857D02*X179607Y-7250D01* +X184408Y-9500D02*X186658D01* +X183658Y-8750D02*X184408Y-9500D01* +X183658Y-7250D02*Y-8750D01* +Y-7250D02*X184408Y-6500D01* +X185908D01* +X186658Y-7250D01* +X183658Y-8000D02*X186658D01* +Y-7250D02*Y-8000D01* +X189210Y-6500D02*X191460D01* +X188460Y-7250D02*X189210Y-6500D01* +X188460Y-7250D02*Y-8750D01* +X189210Y-9500D01* +X191460D01* +X194011Y-3500D02*Y-8750D01* +X194761Y-9500D01* +X193261Y-5750D02*X194761D01* +X198513Y-6500D02*X199263Y-7250D01* +X197013Y-6500D02*X198513D01* +X196263Y-7250D02*X197013Y-6500D01* +X196263Y-7250D02*Y-8750D01* +X197013Y-9500D01* +X199263Y-6500D02*Y-8750D01* +X200013Y-9500D01* +X197013D02*X198513D01* +X199263Y-8750D01* +X202564Y-7250D02*Y-9500D01* +Y-7250D02*X203314Y-6500D01* +X204064D01* +X204814Y-7250D01* +Y-9500D01* +X201814Y-6500D02*X202564Y-7250D01* +X208866Y-6500D02*X209616Y-7250D01* +X207366Y-6500D02*X208866D01* +X206616Y-7250D02*X207366Y-6500D01* +X206616Y-7250D02*Y-8750D01* +X207366Y-9500D01* +X208866D01* +X209616Y-8750D01* +X206616Y-11000D02*X207366Y-11750D01* +X208866D01* +X209616Y-11000D01* +Y-6500D02*Y-11000D01* +X211417Y-3500D02*Y-8750D01* +X212167Y-9500D01* +X214419D02*X216669D01* +X213669Y-8750D02*X214419Y-9500D01* +X213669Y-7250D02*Y-8750D01* +Y-7250D02*X214419Y-6500D01* +X215919D01* +X216669Y-7250D01* +X213669Y-8000D02*X216669D01* +Y-7250D02*Y-8000D01* +X221170Y-6500D02*X224170D01* +X228672Y-8750D02*X229422Y-9500D01* +X228672Y-4250D02*Y-8750D01* +Y-4250D02*X229422Y-3500D01* +X230922D01* +X231672Y-4250D01* +Y-8750D01* +X230922Y-9500D02*X231672Y-8750D01* +X229422Y-9500D02*X230922D01* +X228672Y-8000D02*X231672Y-5000D01* +X233473Y-11000D02*X234973Y-9500D01* +X236775Y-8750D02*X237525Y-9500D01* +X236775Y-4250D02*Y-8750D01* +Y-4250D02*X237525Y-3500D01* +X239025D01* +X239775Y-4250D01* +Y-8750D01* +X239025Y-9500D02*X239775Y-8750D01* +X237525Y-9500D02*X239025D01* +X236775Y-8000D02*X239775Y-5000D01* +X245026Y-3500D02*Y-8750D01* +X245776Y-9500D01* +X244276Y-5750D02*X245776D01* +X247278Y-7250D02*Y-8750D01* +Y-7250D02*X248028Y-6500D01* +X249528D01* +X250278Y-7250D01* +Y-8750D01* +X249528Y-9500D02*X250278Y-8750D01* +X248028Y-9500D02*X249528D01* +X247278Y-8750D02*X248028Y-9500D01* +X254779Y-4250D02*X255529Y-3500D01* +X257779D01* +X258529Y-4250D01* +Y-5750D01* +X254779Y-9500D02*X258529Y-5750D01* +X254779Y-9500D02*X258529D01* +X260331Y-8750D02*X261081Y-9500D01* +X260331Y-4250D02*Y-8750D01* +Y-4250D02*X261081Y-3500D01* +X262581D01* +X263331Y-4250D01* +Y-8750D01* +X262581Y-9500D02*X263331Y-8750D01* +X261081Y-9500D02*X262581D01* +X260331Y-8000D02*X263331Y-5000D01* +X265132Y-8750D02*X265882Y-9500D01* +X265132Y-4250D02*Y-8750D01* +Y-4250D02*X265882Y-3500D01* +X267382D01* +X268132Y-4250D01* +Y-8750D01* +X267382Y-9500D02*X268132Y-8750D01* +X265882Y-9500D02*X267382D01* +X265132Y-8000D02*X268132Y-5000D01* +X269934Y-8750D02*X270684Y-9500D01* +X269934Y-4250D02*Y-8750D01* +Y-4250D02*X270684Y-3500D01* +X272184D01* +X272934Y-4250D01* +Y-8750D01* +X272184Y-9500D02*X272934Y-8750D01* +X270684Y-9500D02*X272184D01* +X269934Y-8000D02*X272934Y-5000D01* +X274735Y-11000D02*X276235Y-9500D01* +X278787D02*X280287D01* +X279537Y-3500D02*Y-9500D01* +X278037Y-5000D02*X279537Y-3500D01* +X282088Y-8750D02*X282838Y-9500D01* +X282088Y-4250D02*Y-8750D01* +Y-4250D02*X282838Y-3500D01* +X284338D01* +X285088Y-4250D01* +Y-8750D01* +X284338Y-9500D02*X285088Y-8750D01* +X282838Y-9500D02*X284338D01* +X282088Y-8000D02*X285088Y-5000D01* +X286890Y-8750D02*X287640Y-9500D01* +X286890Y-4250D02*Y-8750D01* +Y-4250D02*X287640Y-3500D01* +X289140D01* +X289890Y-4250D01* +Y-8750D01* +X289140Y-9500D02*X289890Y-8750D01* +X287640Y-9500D02*X289140D01* +X286890Y-8000D02*X289890Y-5000D01* +X291691Y-8750D02*X292441Y-9500D01* +X291691Y-4250D02*Y-8750D01* +Y-4250D02*X292441Y-3500D01* +X293941D01* +X294691Y-4250D01* +Y-8750D01* +X293941Y-9500D02*X294691Y-8750D01* +X292441Y-9500D02*X293941D01* +X291691Y-8000D02*X294691Y-5000D01* +X299943Y-7250D02*Y-9500D01* +Y-7250D02*X300693Y-6500D01* +X301443D01* +X302193Y-7250D01* +Y-9500D01* +Y-7250D02*X302943Y-6500D01* +X303693D01* +X304443Y-7250D01* +Y-9500D01* +X299193Y-6500D02*X299943Y-7250D01* +X306244Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X307746Y-3500D02*Y-8750D01* +X308496Y-9500D01* +X310747D02*X312997D01* +X313747Y-8750D01* +X312997Y-8000D02*X313747Y-8750D01* +X310747Y-8000D02*X312997D01* +X309997Y-7250D02*X310747Y-8000D01* +X309997Y-7250D02*X310747Y-6500D01* +X312997D01* +X313747Y-7250D01* +X309997Y-8750D02*X310747Y-9500D01* +X200750Y128500D02*Y122500D01* +X203000Y128500D02*X203750Y127750D01* +Y123250D01* +X203000Y122500D02*X203750Y123250D01* +X200000Y122500D02*X203000D01* +X200000Y128500D02*X203000D01* +X207801Y125500D02*X208551Y124750D01* +X206301Y125500D02*X207801D01* +X205551Y124750D02*X206301Y125500D01* +X205551Y124750D02*Y123250D01* +X206301Y122500D01* +X208551Y125500D02*Y123250D01* +X209301Y122500D01* +X206301D02*X207801D01* +X208551Y123250D01* +X211853Y128500D02*Y123250D01* +X212603Y122500D01* +X211103Y126250D02*X212603D01* +X214854Y122500D02*X217104D01* +X214104Y123250D02*X214854Y122500D01* +X214104Y124750D02*Y123250D01* +Y124750D02*X214854Y125500D01* +X216354D01* +X217104Y124750D01* +X214104Y124000D02*X217104D01* +Y124750D02*Y124000D01* +X218906Y126250D02*X219656D01* +X218906Y124750D02*X219656D01* +X224157Y128500D02*Y122500D01* +X226407Y124750D01* +X228657Y122500D01* +Y128500D02*Y122500D01* +X231209D02*X233459D01* +X230459Y123250D02*X231209Y122500D01* +X230459Y124750D02*Y123250D01* +Y124750D02*X231209Y125500D01* +X232709D01* +X233459Y124750D01* +X230459Y124000D02*X233459D01* +Y124750D02*Y124000D01* +X238260Y128500D02*Y122500D01* +X237510D02*X238260Y123250D01* +X236010Y122500D02*X237510D01* +X235260Y123250D02*X236010Y122500D01* +X235260Y124750D02*Y123250D01* +Y124750D02*X236010Y125500D01* +X237510D01* +X238260Y124750D01* +X242762Y128500D02*X245012D01* +Y123250D01* +X244262Y122500D02*X245012Y123250D01* +X243512Y122500D02*X244262D01* +X242762Y123250D02*X243512Y122500D01* +X246813Y125500D02*Y123250D01* +X247563Y122500D01* +X249063D01* +X249813Y123250D01* +Y125500D02*Y123250D01* +X252365Y124750D02*Y122500D01* +Y124750D02*X253115Y125500D01* +X253865D01* +X254615Y124750D01* +Y122500D01* +X251615Y125500D02*X252365Y124750D01* +X259116Y127750D02*X259866Y128500D01* +X262116D01* +X262866Y127750D01* +Y126250D01* +X259116Y122500D02*X262866Y126250D01* +X259116Y122500D02*X262866D01* +X264668Y125500D02*X267668Y128500D01* +X264668Y125500D02*X268418D01* +X267668Y128500D02*Y122500D01* +X272919Y127750D02*X273669Y128500D01* +X275919D01* +X276669Y127750D01* +Y126250D01* +X272919Y122500D02*X276669Y126250D01* +X272919Y122500D02*X276669D01* +X278471Y127750D02*X279221Y128500D01* +X281471D01* +X282221Y127750D01* +Y126250D01* +X278471Y122500D02*X282221Y126250D01* +X278471Y122500D02*X282221D01* +X284022Y126250D02*X284772D01* +X284022Y124750D02*X284772D01* +X286574Y123250D02*X287324Y122500D01* +X286574Y127750D02*Y123250D01* +Y127750D02*X287324Y128500D01* +X288824D01* +X289574Y127750D01* +Y123250D01* +X288824Y122500D02*X289574Y123250D01* +X287324Y122500D02*X288824D01* +X286574Y124000D02*X289574Y127000D01* +X291375Y128500D02*X294375D01* +X291375D02*Y125500D01* +X292125Y126250D01* +X293625D01* +X294375Y125500D01* +Y123250D01* +X293625Y122500D02*X294375Y123250D01* +X292125Y122500D02*X293625D01* +X291375Y123250D02*X292125Y122500D01* +X296177Y126250D02*X296927D01* +X296177Y124750D02*X296927D01* +X298728Y127750D02*X299478Y128500D01* +X300978D01* +X301728Y127750D01* +Y123250D01* +X300978Y122500D02*X301728Y123250D01* +X299478Y122500D02*X300978D01* +X298728Y123250D02*X299478Y122500D01* +Y125500D02*X301728D01* +X303530Y128500D02*X306530D01* +X303530D02*Y125500D01* +X304280Y126250D01* +X305780D01* +X306530Y125500D01* +Y123250D01* +X305780Y122500D02*X306530Y123250D01* +X304280Y122500D02*X305780D01* +X303530Y123250D02*X304280Y122500D01* +X311031Y127750D02*X311781Y128500D01* +X314031D01* +X314781Y127750D01* +Y126250D01* +X311031Y122500D02*X314781Y126250D01* +X311031Y122500D02*X314781D01* +X316583Y123250D02*X317333Y122500D01* +X316583Y127750D02*Y123250D01* +Y127750D02*X317333Y128500D01* +X318833D01* +X319583Y127750D01* +Y123250D01* +X318833Y122500D02*X319583Y123250D01* +X317333Y122500D02*X318833D01* +X316583Y124000D02*X319583Y127000D01* +X321384Y123250D02*X322134Y122500D01* +X321384Y127750D02*Y123250D01* +Y127750D02*X322134Y128500D01* +X323634D01* +X324384Y127750D01* +Y123250D01* +X323634Y122500D02*X324384Y123250D01* +X322134Y122500D02*X323634D01* +X321384Y124000D02*X324384Y127000D01* +X326186Y122500D02*X329186Y125500D01* +Y127750D02*Y125500D01* +X328436Y128500D02*X329186Y127750D01* +X326936Y128500D02*X328436D01* +X326186Y127750D02*X326936Y128500D01* +X326186Y127750D02*Y126250D01* +X326936Y125500D01* +X329186D01* +X333687Y128500D02*Y123250D01* +X334437Y122500D01* +X335937D01* +X336687Y123250D01* +Y128500D02*Y123250D01* +X338489Y128500D02*X341489D01* +X339989D02*Y122500D01* +X344040D02*X346290D01* +X343290Y123250D02*X344040Y122500D01* +X343290Y127750D02*Y123250D01* +Y127750D02*X344040Y128500D01* +X346290D01* +X200000Y142750D02*Y137500D01* +Y142750D02*X200750Y143500D01* +X203000D01* +X203750Y142750D01* +Y137500D01* +X200000Y140500D02*X203750D01* +X205551D02*Y138250D01* +X206301Y137500D01* +X207801D01* +X208551Y138250D01* +Y140500D02*Y138250D01* +X211103Y143500D02*Y138250D01* +X211853Y137500D01* +X210353Y141250D02*X211853D01* +X213354Y143500D02*Y137500D01* +Y139750D02*X214104Y140500D01* +X215604D01* +X216354Y139750D01* +Y137500D01* +X218156Y139750D02*Y138250D01* +Y139750D02*X218906Y140500D01* +X220406D01* +X221156Y139750D01* +Y138250D01* +X220406Y137500D02*X221156Y138250D01* +X218906Y137500D02*X220406D01* +X218156Y138250D02*X218906Y137500D01* +X223707Y139750D02*Y137500D01* +Y139750D02*X224457Y140500D01* +X225957D01* +X222957D02*X223707Y139750D01* +X227759Y141250D02*X228509D01* +X227759Y139750D02*X228509D01* +X233760Y143500D02*Y137500D01* +X236010Y143500D02*X236760Y142750D01* +Y138250D01* +X236010Y137500D02*X236760Y138250D01* +X233010Y137500D02*X236010D01* +X233010Y143500D02*X236010D01* +X240812Y140500D02*X241562Y139750D01* +X239312Y140500D02*X240812D01* +X238562Y139750D02*X239312Y140500D01* +X238562Y139750D02*Y138250D01* +X239312Y137500D01* +X241562Y140500D02*Y138250D01* +X242312Y137500D01* +X239312D02*X240812D01* +X241562Y138250D01* +X244863Y139750D02*Y137500D01* +Y139750D02*X245613Y140500D01* +X246363D01* +X247113Y139750D01* +Y137500D01* +X244113Y140500D02*X244863Y139750D01* +X251615Y143500D02*Y137500D01* +Y143500D02*X253865Y141250D01* +X256115Y143500D01* +Y137500D01* +X258666Y140500D02*X260916D01* +X257916Y139750D02*X258666Y140500D01* +X257916Y139750D02*Y138250D01* +X258666Y137500D01* +X260916D01* +X262718Y143500D02*Y137500D01* +Y143500D02*X264968Y141250D01* +X267218Y143500D01* +Y137500D01* +X271269Y140500D02*X272019Y139750D01* +X269769Y140500D02*X271269D01* +X269019Y139750D02*X269769Y140500D01* +X269019Y139750D02*Y138250D01* +X269769Y137500D01* +X272019Y140500D02*Y138250D01* +X272769Y137500D01* +X269769D02*X271269D01* +X272019Y138250D01* +X274571Y143500D02*Y137500D01* +Y139750D02*X275321Y140500D01* +X276821D01* +X277571Y139750D01* +Y137500D01* +X279372Y142000D02*Y141250D01* +Y139750D02*Y137500D01* +X280874Y143500D02*Y138250D01* +X281624Y137500D01* +X283125Y143500D02*Y138250D01* +X283875Y137500D01* +X200000Y158500D02*X203000D01* +X201500D02*Y152500D01* +X204801Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X207053Y158500D02*Y153250D01* +X207803Y152500D01* +X206303Y156250D02*X207803D01* +X209304Y158500D02*Y153250D01* +X210054Y152500D01* +X212306D02*X214556D01* +X211556Y153250D02*X212306Y152500D01* +X211556Y154750D02*Y153250D01* +Y154750D02*X212306Y155500D01* +X213806D01* +X214556Y154750D01* +X211556Y154000D02*X214556D01* +Y154750D02*Y154000D01* +X216357Y156250D02*X217107D01* +X216357Y154750D02*X217107D01* +X221609Y152500D02*X224609D01* +X225359Y153250D01* +Y154750D02*Y153250D01* +X224609Y155500D02*X225359Y154750D01* +X222359Y155500D02*X224609D01* +X222359Y158500D02*Y152500D01* +X221609Y158500D02*X224609D01* +X225359Y157750D01* +Y156250D01* +X224609Y155500D02*X225359Y156250D01* +X229410Y155500D02*X230160Y154750D01* +X227910Y155500D02*X229410D01* +X227160Y154750D02*X227910Y155500D01* +X227160Y154750D02*Y153250D01* +X227910Y152500D01* +X230160Y155500D02*Y153250D01* +X230910Y152500D01* +X227910D02*X229410D01* +X230160Y153250D01* +X233462Y152500D02*X235712D01* +X236462Y153250D01* +X235712Y154000D02*X236462Y153250D01* +X233462Y154000D02*X235712D01* +X232712Y154750D02*X233462Y154000D01* +X232712Y154750D02*X233462Y155500D01* +X235712D01* +X236462Y154750D01* +X232712Y153250D02*X233462Y152500D01* +X238263Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X240515Y155500D02*X242765D01* +X239765Y154750D02*X240515Y155500D01* +X239765Y154750D02*Y153250D01* +X240515Y152500D01* +X242765D01* +X250266Y158500D02*X251016Y157750D01* +X248016Y158500D02*X250266D01* +X247266Y157750D02*X248016Y158500D01* +X247266Y157750D02*Y156250D01* +X248016Y155500D01* +X250266D01* +X251016Y154750D01* +Y153250D01* +X250266Y152500D02*X251016Y153250D01* +X248016Y152500D02*X250266D01* +X247266Y153250D02*X248016Y152500D01* +X252818Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X255069Y154750D02*Y152500D01* +Y154750D02*X255819Y155500D01* +X256569D01* +X257319Y154750D01* +Y152500D01* +X254319Y155500D02*X255069Y154750D01* +X261371Y155500D02*X262121Y154750D01* +X259871Y155500D02*X261371D01* +X259121Y154750D02*X259871Y155500D01* +X259121Y154750D02*Y153250D01* +X259871Y152500D01* +X261371D01* +X262121Y153250D01* +X259121Y151000D02*X259871Y150250D01* +X261371D01* +X262121Y151000D01* +Y155500D02*Y151000D01* +X263922Y158500D02*Y153250D01* +X264672Y152500D01* +X266924D02*X269174D01* +X266174Y153250D02*X266924Y152500D01* +X266174Y154750D02*Y153250D01* +Y154750D02*X266924Y155500D01* +X268424D01* +X269174Y154750D01* +X266174Y154000D02*X269174D01* +Y154750D02*Y154000D01* +X273675Y158500D02*X276675D01* +X275175D02*Y152500D01* +X279227Y154750D02*Y152500D01* +Y154750D02*X279977Y155500D01* +X281477D01* +X278477D02*X279227Y154750D01* +X285528Y155500D02*X286278Y154750D01* +X284028Y155500D02*X285528D01* +X283278Y154750D02*X284028Y155500D01* +X283278Y154750D02*Y153250D01* +X284028Y152500D01* +X286278Y155500D02*Y153250D01* +X287028Y152500D01* +X284028D02*X285528D01* +X286278Y153250D01* +X289580Y155500D02*X291830D01* +X288830Y154750D02*X289580Y155500D01* +X288830Y154750D02*Y153250D01* +X289580Y152500D01* +X291830D01* +X294381D02*X296631D01* +X293631Y153250D02*X294381Y152500D01* +X293631Y154750D02*Y153250D01* +Y154750D02*X294381Y155500D01* +X295881D01* +X296631Y154750D01* +X293631Y154000D02*X296631D01* +Y154750D02*Y154000D01* +X301133Y158500D02*X304133D01* +X304883Y157750D01* +Y156250D01* +X304133Y155500D02*X304883Y156250D01* +X301883Y155500D02*X304133D01* +X301883Y158500D02*Y152500D01* +Y155500D02*X304883Y152500D01* +X309684Y158500D02*X310434Y157750D01* +X307434Y158500D02*X309684D01* +X306684Y157750D02*X307434Y158500D01* +X306684Y157750D02*Y156250D01* +X307434Y155500D01* +X309684D01* +X310434Y154750D01* +Y153250D01* +X309684Y152500D02*X310434Y153250D01* +X307434Y152500D02*X309684D01* +X306684Y153250D02*X307434Y152500D01* +X312236Y157750D02*X312986Y158500D01* +X315236D01* +X315986Y157750D01* +Y156250D01* +X312236Y152500D02*X315986Y156250D01* +X312236Y152500D02*X315986D01* +X317787D02*X321537Y156250D01* +Y158500D02*Y156250D01* +X317787Y158500D02*X321537D01* +X323339Y155500D02*X326339Y158500D01* +X323339Y155500D02*X327089D01* +X326339Y158500D02*Y152500D01* +X328890Y155500D02*X331890D01* +X333692Y158500D02*Y157750D01* +X337442Y154000D01* +Y152500D01* +X333692Y154000D02*Y152500D01* +Y154000D02*X337442Y157750D01* +Y158500D02*Y157750D01* +X341943Y158500D02*X344943D01* +X343443D02*Y152500D01* +X347495D02*X349745D01* +X346745Y153250D02*X347495Y152500D01* +X346745Y154750D02*Y153250D01* +Y154750D02*X347495Y155500D01* +X348995D01* +X349745Y154750D01* +X346745Y154000D02*X349745D01* +Y154750D02*Y154000D01* +X352296Y152500D02*X354546D01* +X355296Y153250D01* +X354546Y154000D02*X355296Y153250D01* +X352296Y154000D02*X354546D01* +X351546Y154750D02*X352296Y154000D01* +X351546Y154750D02*X352296Y155500D01* +X354546D01* +X355296Y154750D01* +X351546Y153250D02*X352296Y152500D01* +X357848Y158500D02*Y153250D01* +X358598Y152500D01* +X357098Y156250D02*X358598D01* +X362799Y155500D02*X365799D01* +X370301Y158500D02*Y152500D01* +Y158500D02*X373301D01* +X370301Y155500D02*X372551D01* +X377352D02*X378102Y154750D01* +X375852Y155500D02*X377352D01* +X375102Y154750D02*X375852Y155500D01* +X375102Y154750D02*Y153250D01* +X375852Y152500D01* +X378102Y155500D02*Y153250D01* +X378852Y152500D01* +X375852D02*X377352D01* +X378102Y153250D01* +X380654Y158500D02*Y152500D01* +Y153250D02*X381404Y152500D01* +X382904D01* +X383654Y153250D01* +Y154750D02*Y153250D01* +X382904Y155500D02*X383654Y154750D01* +X381404Y155500D02*X382904D01* +X380654Y154750D02*X381404Y155500D01* +X386205Y154750D02*Y152500D01* +Y154750D02*X386955Y155500D01* +X388455D01* +X385455D02*X386205Y154750D01* +X390257Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X392508Y155500D02*X394758D01* +X391758Y154750D02*X392508Y155500D01* +X391758Y154750D02*Y153250D01* +X392508Y152500D01* +X394758D01* +X398810Y155500D02*X399560Y154750D01* +X397310Y155500D02*X398810D01* +X396560Y154750D02*X397310Y155500D01* +X396560Y154750D02*Y153250D01* +X397310Y152500D01* +X399560Y155500D02*Y153250D01* +X400310Y152500D01* +X397310D02*X398810D01* +X399560Y153250D01* +X402861Y158500D02*Y153250D01* +X403611Y152500D01* +X402111Y156250D02*X403611D01* +X405113Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X406614Y154750D02*Y153250D01* +Y154750D02*X407364Y155500D01* +X408864D01* +X409614Y154750D01* +Y153250D01* +X408864Y152500D02*X409614Y153250D01* +X407364Y152500D02*X408864D01* +X406614Y153250D02*X407364Y152500D01* +X412166Y154750D02*Y152500D01* +Y154750D02*X412916Y155500D01* +X413666D01* +X414416Y154750D01* +Y152500D01* +X411416Y155500D02*X412166Y154750D01* +X419667Y158500D02*Y152500D01* +X421917Y158500D02*X422667Y157750D01* +Y153250D01* +X421917Y152500D02*X422667Y153250D01* +X418917Y152500D02*X421917D01* +X418917Y158500D02*X421917D01* +X425219Y154750D02*Y152500D01* +Y154750D02*X425969Y155500D01* +X427469D01* +X424469D02*X425219Y154750D01* +X431520Y155500D02*X432270Y154750D01* +X430020Y155500D02*X431520D01* +X429270Y154750D02*X430020Y155500D01* +X429270Y154750D02*Y153250D01* +X430020Y152500D01* +X432270Y155500D02*Y153250D01* +X433020Y152500D01* +X430020D02*X431520D01* +X432270Y153250D01* +X434822Y155500D02*Y153250D01* +X435572Y152500D01* +X436322D01* +X437072Y153250D01* +Y155500D02*Y153250D01* +X437822Y152500D01* +X438572D01* +X439322Y153250D01* +Y155500D02*Y153250D01* +X441123Y157000D02*Y156250D01* +Y154750D02*Y152500D01* +X443375Y154750D02*Y152500D01* +Y154750D02*X444125Y155500D01* +X444875D01* +X445625Y154750D01* +Y152500D01* +X442625Y155500D02*X443375Y154750D01* +X449676Y155500D02*X450426Y154750D01* +X448176Y155500D02*X449676D01* +X447426Y154750D02*X448176Y155500D01* +X447426Y154750D02*Y153250D01* +X448176Y152500D01* +X449676D01* +X450426Y153250D01* +X447426Y151000D02*X448176Y150250D01* +X449676D01* +X450426Y151000D01* +Y155500D02*Y151000D01* +M02* Index: tags/2.3.0/tests/orig/golden/hid_gerber2/out.plated-drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber2/out.plated-drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber2/out.plated-drill.cnc (revision 33253) @@ -0,0 +1,7 @@ +M48 +INCH +T13C0.035 +% +T13 +X009000Y005000 +M30 Index: tags/2.3.0/tests/orig/golden/hid_gerber2/out.top.gbr =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber2/out.top.gbr (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber2/out.top.gbr (revision 33253) @@ -0,0 +1,17 @@ +G04 start of page 2 for group 0 idx 0 * +G04 Title: Basic Single Trace RS274-X Test, component * +G04 Creator: pcb 1.99y * +G04 CreationDate: Wed Jun 24 22:05:35 2009 UTC * +G04 For: dan * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 200000 100000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNFRONT*% +%ADD11C,0.0400*% +%ADD12C,0.0600*% +%ADD13C,0.0350*% +G54D11*X10000Y50000D02*X90000D01* +G54D12*D03* +G54D13*M02* Index: tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.bottom.gbr =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.bottom.gbr (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.bottom.gbr (revision 33253) @@ -0,0 +1,23 @@ +G04 start of page 5 for group 5 idx 5 * +G04 Title: (unknown), bottom * +G04 Creator: pcb 1.99z * +G04 CreationDate: Fri Jun 17 03:18:51 2011 UTC * +G04 For: apoelstra * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 3000000 2000000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNBOTTOM*% +%ADD32C,0.2500*% +%ADD31C,0.5000*% +%ADD30C,1.0000*% +%ADD29C,0.6500*% +%ADD28C,0.7500*% +G54D28*X600000Y450000D03* +G54D29*Y290000D03* +G54D30*X450000Y600000D03* +X600000D03* +G54D29*X450000Y290000D03* +G54D28*Y450000D03* +G54D31*G54D32*G54D31*G54D32*G54D31*M02* Index: tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.fab.gbr =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.fab.gbr (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.fab.gbr (revision 33253) @@ -0,0 +1,2025 @@ +G04 start of page 7 for group -3984 idx -3984 * +G04 Title: (unknown), fab * +G04 Creator: pcb 1.99z * +G04 CreationDate: Fri Jun 17 03:18:51 2011 UTC * +G04 For: apoelstra * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 3000000 2000000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNFAB*% +%ADD37C,0.0100*% +%ADD36C,0.0060*% +%ADD35C,0.0080*% +G54D35*X600000Y451600D02*Y448400D01* +X598400Y450000D02*X601600D01* +X450000Y601600D02*Y598400D01* +X448400Y600000D02*X451600D01* +X600000Y601600D02*Y598400D01* +X598400Y600000D02*X601600D01* +X450000Y451600D02*Y448400D01* +X448400Y450000D02*X451600D01* +X15000Y2042850D02*Y2039650D01* +X13400Y2041250D02*X16600D01* +G54D36*X135000Y2043500D02*Y2042750D01* +X136500Y2041250D01* +X138000Y2042750D01* +Y2043500D02*Y2042750D01* +X136500Y2041250D02*Y2037500D01* +X139801Y2040500D02*X142051D01* +X139801Y2037500D02*X142801D01* +X139801Y2043500D02*Y2037500D01* +Y2043500D02*X142801D01* +X147603D02*X148353Y2042750D01* +X145353Y2043500D02*X147603D01* +X144603Y2042750D02*X145353Y2043500D01* +X144603Y2042750D02*Y2041250D01* +X145353Y2040500D01* +X147603D01* +X148353Y2039750D01* +Y2038250D01* +X147603Y2037500D02*X148353Y2038250D01* +X145353Y2037500D02*X147603D01* +X144603Y2038250D02*X145353Y2037500D01* +X135000Y2034249D02*X150154D01* +X98000Y2040500D02*X101000Y2043500D01* +X98000Y2040500D02*X101750D01* +X101000Y2043500D02*Y2037500D01* +X98000Y2034249D02*X103551D01* +X45000Y2038250D02*X45750Y2037500D01* +X45000Y2042750D02*Y2038250D01* +Y2042750D02*X45750Y2043500D01* +X47250D01* +X48000Y2042750D01* +Y2038250D01* +X47250Y2037500D02*X48000Y2038250D01* +X45750Y2037500D02*X47250D01* +X45000Y2039000D02*X48000Y2042000D01* +X49801Y2037500D02*X50551D01* +X52353Y2043500D02*X55353D01* +X52353D02*Y2040500D01* +X53103Y2041250D01* +X54603D01* +X55353Y2040500D01* +Y2038250D01* +X54603Y2037500D02*X55353Y2038250D01* +X53103Y2037500D02*X54603D01* +X52353Y2038250D02*X53103Y2037500D01* +X57154Y2038250D02*X57904Y2037500D01* +X57154Y2042750D02*Y2038250D01* +Y2042750D02*X57904Y2043500D01* +X59404D01* +X60154Y2042750D01* +Y2038250D01* +X59404Y2037500D02*X60154Y2038250D01* +X57904Y2037500D02*X59404D01* +X57154Y2039000D02*X60154Y2042000D01* +X61956Y2038250D02*X62706Y2037500D01* +X61956Y2042750D02*Y2038250D01* +Y2042750D02*X62706Y2043500D01* +X64206D01* +X64956Y2042750D01* +Y2038250D01* +X64206Y2037500D02*X64956Y2038250D01* +X62706Y2037500D02*X64206D01* +X61956Y2039000D02*X64956Y2042000D01* +X45000Y2034249D02*X66757D01* +X600000Y290000D02*Y288400D01* +Y290000D02*X601386Y290800D01* +X600000Y290000D02*X598614Y290800D01* +X450000Y290000D02*Y288400D01* +Y290000D02*X451386Y290800D01* +X450000Y290000D02*X448614Y290800D01* +X15000Y2056250D02*Y2054650D01* +Y2056250D02*X16386Y2057050D01* +X15000Y2056250D02*X13614Y2057050D01* +X135000Y2058500D02*Y2057750D01* +X136500Y2056250D01* +X138000Y2057750D01* +Y2058500D02*Y2057750D01* +X136500Y2056250D02*Y2052500D01* +X139801Y2055500D02*X142051D01* +X139801Y2052500D02*X142801D01* +X139801Y2058500D02*Y2052500D01* +Y2058500D02*X142801D01* +X147603D02*X148353Y2057750D01* +X145353Y2058500D02*X147603D01* +X144603Y2057750D02*X145353Y2058500D01* +X144603Y2057750D02*Y2056250D01* +X145353Y2055500D01* +X147603D01* +X148353Y2054750D01* +Y2053250D01* +X147603Y2052500D02*X148353Y2053250D01* +X145353Y2052500D02*X147603D01* +X144603Y2053250D02*X145353Y2052500D01* +X135000Y2049249D02*X150154D01* +X98000Y2057750D02*X98750Y2058500D01* +X101000D01* +X101750Y2057750D01* +Y2056250D01* +X98000Y2052500D02*X101750Y2056250D01* +X98000Y2052500D02*X101750D01* +X98000Y2049249D02*X103551D01* +X45000Y2053250D02*X45750Y2052500D01* +X45000Y2057750D02*Y2053250D01* +Y2057750D02*X45750Y2058500D01* +X47250D01* +X48000Y2057750D01* +Y2053250D01* +X47250Y2052500D02*X48000Y2053250D01* +X45750Y2052500D02*X47250D01* +X45000Y2054000D02*X48000Y2057000D01* +X49801Y2052500D02*X50551D01* +X52353Y2057750D02*X53103Y2058500D01* +X55353D01* +X56103Y2057750D01* +Y2056250D01* +X52353Y2052500D02*X56103Y2056250D01* +X52353Y2052500D02*X56103D01* +X57904Y2058500D02*X60904D01* +X57904D02*Y2055500D01* +X58654Y2056250D01* +X60154D01* +X60904Y2055500D01* +Y2053250D01* +X60154Y2052500D02*X60904Y2053250D01* +X58654Y2052500D02*X60154D01* +X57904Y2053250D02*X58654Y2052500D01* +X62706Y2053250D02*X63456Y2052500D01* +X62706Y2057750D02*Y2053250D01* +Y2057750D02*X63456Y2058500D01* +X64956D01* +X65706Y2057750D01* +Y2053250D01* +X64956Y2052500D02*X65706Y2053250D01* +X63456Y2052500D02*X64956D01* +X62706Y2054000D02*X65706Y2057000D01* +X45000Y2049249D02*X67507D01* +X3000Y2073500D02*X3750Y2072750D01* +X750Y2073500D02*X3000D01* +X0Y2072750D02*X750Y2073500D01* +X0Y2072750D02*Y2071250D01* +X750Y2070500D01* +X3000D01* +X3750Y2069750D01* +Y2068250D01* +X3000Y2067500D02*X3750Y2068250D01* +X750Y2067500D02*X3000D01* +X0Y2068250D02*X750Y2067500D01* +X5551Y2070500D02*Y2068250D01* +X6301Y2067500D01* +X8551Y2070500D02*Y2066000D01* +X7801Y2065250D02*X8551Y2066000D01* +X6301Y2065250D02*X7801D01* +X5551Y2066000D02*X6301Y2065250D01* +Y2067500D02*X7801D01* +X8551Y2068250D01* +X11103Y2069750D02*Y2067500D01* +Y2069750D02*X11853Y2070500D01* +X12603D01* +X13353Y2069750D01* +Y2067500D01* +Y2069750D02*X14103Y2070500D01* +X14853D01* +X15603Y2069750D01* +Y2067500D01* +X10353Y2070500D02*X11103Y2069750D01* +X17404Y2073500D02*Y2067500D01* +Y2068250D02*X18154Y2067500D01* +X19654D01* +X20404Y2068250D01* +Y2069750D02*Y2068250D01* +X19654Y2070500D02*X20404Y2069750D01* +X18154Y2070500D02*X19654D01* +X17404Y2069750D02*X18154Y2070500D01* +X22206Y2069750D02*Y2068250D01* +Y2069750D02*X22956Y2070500D01* +X24456D01* +X25206Y2069750D01* +Y2068250D01* +X24456Y2067500D02*X25206Y2068250D01* +X22956Y2067500D02*X24456D01* +X22206Y2068250D02*X22956Y2067500D01* +X27007Y2073500D02*Y2068250D01* +X27757Y2067500D01* +X41750Y2073500D02*Y2067500D01* +X44000Y2073500D02*X44750Y2072750D01* +Y2068250D01* +X44000Y2067500D02*X44750Y2068250D01* +X41000Y2067500D02*X44000D01* +X41000Y2073500D02*X44000D01* +X46551Y2072000D02*Y2071250D01* +Y2069750D02*Y2067500D01* +X50303Y2070500D02*X51053Y2069750D01* +X48803Y2070500D02*X50303D01* +X48053Y2069750D02*X48803Y2070500D01* +X48053Y2069750D02*Y2068250D01* +X48803Y2067500D01* +X51053Y2070500D02*Y2068250D01* +X51803Y2067500D01* +X48803D02*X50303D01* +X51053Y2068250D01* +X54354Y2069750D02*Y2067500D01* +Y2069750D02*X55104Y2070500D01* +X55854D01* +X56604Y2069750D01* +Y2067500D01* +Y2069750D02*X57354Y2070500D01* +X58104D01* +X58854Y2069750D01* +Y2067500D01* +X53604Y2070500D02*X54354Y2069750D01* +X60656Y2067500D02*X61406D01* +X65907Y2068250D02*X66657Y2067500D01* +X65907Y2072750D02*X66657Y2073500D01* +X65907Y2072750D02*Y2068250D01* +X68459Y2073500D02*X69959D01* +X69209D02*Y2067500D01* +X68459D02*X69959D01* +X72510Y2069750D02*Y2067500D01* +Y2069750D02*X73260Y2070500D01* +X74010D01* +X74760Y2069750D01* +Y2067500D01* +X71760Y2070500D02*X72510Y2069750D01* +X77312Y2070500D02*X79562D01* +X76562Y2069750D02*X77312Y2070500D01* +X76562Y2069750D02*Y2068250D01* +X77312Y2067500D01* +X79562D01* +X81363Y2073500D02*Y2067500D01* +Y2069750D02*X82113Y2070500D01* +X83613D01* +X84363Y2069750D01* +Y2067500D01* +X86165Y2073500D02*X86915Y2072750D01* +Y2068250D01* +X86165Y2067500D02*X86915Y2068250D01* +X95750Y2067500D02*X98000D01* +X95000Y2068250D02*X95750Y2067500D01* +X95000Y2072750D02*Y2068250D01* +Y2072750D02*X95750Y2073500D01* +X98000D01* +X99801Y2069750D02*Y2068250D01* +Y2069750D02*X100551Y2070500D01* +X102051D01* +X102801Y2069750D01* +Y2068250D01* +X102051Y2067500D02*X102801Y2068250D01* +X100551Y2067500D02*X102051D01* +X99801Y2068250D02*X100551Y2067500D01* +X104603Y2070500D02*Y2068250D01* +X105353Y2067500D01* +X106853D01* +X107603Y2068250D01* +Y2070500D02*Y2068250D01* +X110154Y2069750D02*Y2067500D01* +Y2069750D02*X110904Y2070500D01* +X111654D01* +X112404Y2069750D01* +Y2067500D01* +X109404Y2070500D02*X110154Y2069750D01* +X114956Y2073500D02*Y2068250D01* +X115706Y2067500D01* +X114206Y2071250D02*X115706D01* +X130750Y2073500D02*Y2067500D01* +X130000Y2073500D02*X133000D01* +X133750Y2072750D01* +Y2071250D01* +X133000Y2070500D02*X133750Y2071250D01* +X130750Y2070500D02*X133000D01* +X135551Y2073500D02*Y2068250D01* +X136301Y2067500D01* +X140053Y2070500D02*X140803Y2069750D01* +X138553Y2070500D02*X140053D01* +X137803Y2069750D02*X138553Y2070500D01* +X137803Y2069750D02*Y2068250D01* +X138553Y2067500D01* +X140803Y2070500D02*Y2068250D01* +X141553Y2067500D01* +X138553D02*X140053D01* +X140803Y2068250D01* +X144104Y2073500D02*Y2068250D01* +X144854Y2067500D01* +X143354Y2071250D02*X144854D01* +X147106Y2067500D02*X149356D01* +X146356Y2068250D02*X147106Y2067500D01* +X146356Y2069750D02*Y2068250D01* +Y2069750D02*X147106Y2070500D01* +X148606D01* +X149356Y2069750D01* +X146356Y2069000D02*X149356D01* +Y2069750D02*Y2069000D01* +X154157Y2073500D02*Y2067500D01* +X153407D02*X154157Y2068250D01* +X151907Y2067500D02*X153407D01* +X151157Y2068250D02*X151907Y2067500D01* +X151157Y2069750D02*Y2068250D01* +Y2069750D02*X151907Y2070500D01* +X153407D01* +X154157Y2069750D01* +X157459Y2070500D02*Y2069750D01* +Y2068250D02*Y2067500D01* +X155959Y2072750D02*Y2072000D01* +Y2072750D02*X156709Y2073500D01* +X158209D01* +X158959Y2072750D01* +Y2072000D01* +X157459Y2070500D02*X158959Y2072000D01* +X0Y2088500D02*X3000D01* +X1500D02*Y2082500D01* +X4801Y2088500D02*Y2082500D01* +Y2084750D02*X5551Y2085500D01* +X7051D01* +X7801Y2084750D01* +Y2082500D01* +X10353D02*X12603D01* +X9603Y2083250D02*X10353Y2082500D01* +X9603Y2084750D02*Y2083250D01* +Y2084750D02*X10353Y2085500D01* +X11853D01* +X12603Y2084750D01* +X9603Y2084000D02*X12603D01* +Y2084750D02*Y2084000D01* +X15154Y2084750D02*Y2082500D01* +Y2084750D02*X15904Y2085500D01* +X17404D01* +X14404D02*X15154Y2084750D01* +X19956Y2082500D02*X22206D01* +X19206Y2083250D02*X19956Y2082500D01* +X19206Y2084750D02*Y2083250D01* +Y2084750D02*X19956Y2085500D01* +X21456D01* +X22206Y2084750D01* +X19206Y2084000D02*X22206D01* +Y2084750D02*Y2084000D01* +X28957Y2085500D02*X29707Y2084750D01* +X27457Y2085500D02*X28957D01* +X26707Y2084750D02*X27457Y2085500D01* +X26707Y2084750D02*Y2083250D01* +X27457Y2082500D01* +X29707Y2085500D02*Y2083250D01* +X30457Y2082500D01* +X27457D02*X28957D01* +X29707Y2083250D01* +X33009Y2084750D02*Y2082500D01* +Y2084750D02*X33759Y2085500D01* +X35259D01* +X32259D02*X33009Y2084750D01* +X37810Y2082500D02*X40060D01* +X37060Y2083250D02*X37810Y2082500D01* +X37060Y2084750D02*Y2083250D01* +Y2084750D02*X37810Y2085500D01* +X39310D01* +X40060Y2084750D01* +X37060Y2084000D02*X40060D01* +Y2084750D02*Y2084000D01* +X44562Y2087750D02*X45312Y2088500D01* +X47562D01* +X48312Y2087750D01* +Y2086250D01* +X44562Y2082500D02*X48312Y2086250D01* +X44562Y2082500D02*X48312D01* +X55813Y2088500D02*Y2082500D01* +X55063D02*X55813Y2083250D01* +X53563Y2082500D02*X55063D01* +X52813Y2083250D02*X53563Y2082500D01* +X52813Y2084750D02*Y2083250D01* +Y2084750D02*X53563Y2085500D01* +X55063D01* +X55813Y2084750D01* +X57615Y2087000D02*Y2086250D01* +Y2084750D02*Y2082500D01* +X59866Y2087750D02*Y2082500D01* +Y2087750D02*X60616Y2088500D01* +X61366D01* +X59116Y2085500D02*X60616D01* +X63618Y2087750D02*Y2082500D01* +Y2087750D02*X64368Y2088500D01* +X65118D01* +X62868Y2085500D02*X64368D01* +X67369Y2082500D02*X69619D01* +X66619Y2083250D02*X67369Y2082500D01* +X66619Y2084750D02*Y2083250D01* +Y2084750D02*X67369Y2085500D01* +X68869D01* +X69619Y2084750D01* +X66619Y2084000D02*X69619D01* +Y2084750D02*Y2084000D01* +X72171Y2084750D02*Y2082500D01* +Y2084750D02*X72921Y2085500D01* +X74421D01* +X71421D02*X72171Y2084750D01* +X76972Y2082500D02*X79222D01* +X76222Y2083250D02*X76972Y2082500D01* +X76222Y2084750D02*Y2083250D01* +Y2084750D02*X76972Y2085500D01* +X78472D01* +X79222Y2084750D01* +X76222Y2084000D02*X79222D01* +Y2084750D02*Y2084000D01* +X81774Y2084750D02*Y2082500D01* +Y2084750D02*X82524Y2085500D01* +X83274D01* +X84024Y2084750D01* +Y2082500D01* +X81024Y2085500D02*X81774Y2084750D01* +X86575Y2088500D02*Y2083250D01* +X87325Y2082500D01* +X85825Y2086250D02*X87325D01* +X94527Y2088500D02*Y2082500D01* +X93777D02*X94527Y2083250D01* +X92277Y2082500D02*X93777D01* +X91527Y2083250D02*X92277Y2082500D01* +X91527Y2084750D02*Y2083250D01* +Y2084750D02*X92277Y2085500D01* +X93777D01* +X94527Y2084750D01* +X97078D02*Y2082500D01* +Y2084750D02*X97828Y2085500D01* +X99328D01* +X96328D02*X97078Y2084750D01* +X101130Y2087000D02*Y2086250D01* +Y2084750D02*Y2082500D01* +X102631Y2088500D02*Y2083250D01* +X103381Y2082500D01* +X104883Y2088500D02*Y2083250D01* +X105633Y2082500D01* +X110584D02*X112834D01* +X113584Y2083250D01* +X112834Y2084000D02*X113584Y2083250D01* +X110584Y2084000D02*X112834D01* +X109834Y2084750D02*X110584Y2084000D01* +X109834Y2084750D02*X110584Y2085500D01* +X112834D01* +X113584Y2084750D01* +X109834Y2083250D02*X110584Y2082500D01* +X115386Y2087000D02*Y2086250D01* +Y2084750D02*Y2082500D01* +X116887Y2085500D02*X119887D01* +X116887Y2082500D02*X119887Y2085500D01* +X116887Y2082500D02*X119887D01* +X122439D02*X124689D01* +X121689Y2083250D02*X122439Y2082500D01* +X121689Y2084750D02*Y2083250D01* +Y2084750D02*X122439Y2085500D01* +X123939D01* +X124689Y2084750D01* +X121689Y2084000D02*X124689D01* +Y2084750D02*Y2084000D01* +X127240Y2082500D02*X129490D01* +X130240Y2083250D01* +X129490Y2084000D02*X130240Y2083250D01* +X127240Y2084000D02*X129490D01* +X126490Y2084750D02*X127240Y2084000D01* +X126490Y2084750D02*X127240Y2085500D01* +X129490D01* +X130240Y2084750D01* +X126490Y2083250D02*X127240Y2082500D01* +X134742Y2085500D02*Y2083250D01* +X135492Y2082500D01* +X136992D01* +X137742Y2083250D01* +Y2085500D02*Y2083250D01* +X140293Y2082500D02*X142543D01* +X143293Y2083250D01* +X142543Y2084000D02*X143293Y2083250D01* +X140293Y2084000D02*X142543D01* +X139543Y2084750D02*X140293Y2084000D01* +X139543Y2084750D02*X140293Y2085500D01* +X142543D01* +X143293Y2084750D01* +X139543Y2083250D02*X140293Y2082500D01* +X145845D02*X148095D01* +X145095Y2083250D02*X145845Y2082500D01* +X145095Y2084750D02*Y2083250D01* +Y2084750D02*X145845Y2085500D01* +X147345D01* +X148095Y2084750D01* +X145095Y2084000D02*X148095D01* +Y2084750D02*Y2084000D01* +X152896Y2088500D02*Y2082500D01* +X152146D02*X152896Y2083250D01* +X150646Y2082500D02*X152146D01* +X149896Y2083250D02*X150646Y2082500D01* +X149896Y2084750D02*Y2083250D01* +Y2084750D02*X150646Y2085500D01* +X152146D01* +X152896Y2084750D01* +X157398Y2087000D02*Y2086250D01* +Y2084750D02*Y2082500D01* +X159649Y2084750D02*Y2082500D01* +Y2084750D02*X160399Y2085500D01* +X161149D01* +X161899Y2084750D01* +Y2082500D01* +X158899Y2085500D02*X159649Y2084750D01* +X167151Y2088500D02*Y2083250D01* +X167901Y2082500D01* +X166401Y2086250D02*X167901D01* +X169402Y2088500D02*Y2082500D01* +Y2084750D02*X170152Y2085500D01* +X171652D01* +X172402Y2084750D01* +Y2082500D01* +X174204Y2087000D02*Y2086250D01* +Y2084750D02*Y2082500D01* +X176455D02*X178705D01* +X179455Y2083250D01* +X178705Y2084000D02*X179455Y2083250D01* +X176455Y2084000D02*X178705D01* +X175705Y2084750D02*X176455Y2084000D01* +X175705Y2084750D02*X176455Y2085500D01* +X178705D01* +X179455Y2084750D01* +X175705Y2083250D02*X176455Y2082500D01* +X183957Y2088500D02*Y2083250D01* +X184707Y2082500D01* +X188458Y2085500D02*X189208Y2084750D01* +X186958Y2085500D02*X188458D01* +X186208Y2084750D02*X186958Y2085500D01* +X186208Y2084750D02*Y2083250D01* +X186958Y2082500D01* +X189208Y2085500D02*Y2083250D01* +X189958Y2082500D01* +X186958D02*X188458D01* +X189208Y2083250D01* +X191760Y2085500D02*Y2083250D01* +X192510Y2082500D01* +X194760Y2085500D02*Y2081000D01* +X194010Y2080250D02*X194760Y2081000D01* +X192510Y2080250D02*X194010D01* +X191760Y2081000D02*X192510Y2080250D01* +Y2082500D02*X194010D01* +X194760Y2083250D01* +X196561Y2084750D02*Y2083250D01* +Y2084750D02*X197311Y2085500D01* +X198811D01* +X199561Y2084750D01* +Y2083250D01* +X198811Y2082500D02*X199561Y2083250D01* +X197311Y2082500D02*X198811D01* +X196561Y2083250D02*X197311Y2082500D01* +X201363Y2085500D02*Y2083250D01* +X202113Y2082500D01* +X203613D01* +X204363Y2083250D01* +Y2085500D02*Y2083250D01* +X206914Y2088500D02*Y2083250D01* +X207664Y2082500D01* +X206164Y2086250D02*X207664D01* +X209166Y2081000D02*X210666Y2082500D01* +X217417Y2088500D02*X218167Y2087750D01* +X215917Y2088500D02*X217417D01* +X215167Y2087750D02*X215917Y2088500D01* +X215167Y2087750D02*Y2083250D01* +X215917Y2082500D01* +X217417Y2085500D02*X218167Y2084750D01* +X215167Y2085500D02*X217417D01* +X215917Y2082500D02*X217417D01* +X218167Y2083250D01* +Y2084750D02*Y2083250D01* +X222669Y2088500D02*Y2082500D01* +Y2084750D02*X223419Y2085500D01* +X224919D01* +X225669Y2084750D01* +Y2082500D01* +X227470Y2084750D02*Y2083250D01* +Y2084750D02*X228220Y2085500D01* +X229720D01* +X230470Y2084750D01* +Y2083250D01* +X229720Y2082500D02*X230470Y2083250D01* +X228220Y2082500D02*X229720D01* +X227470Y2083250D02*X228220Y2082500D01* +X232272Y2088500D02*Y2083250D01* +X233022Y2082500D01* +X235273D02*X237523D01* +X234523Y2083250D02*X235273Y2082500D01* +X234523Y2084750D02*Y2083250D01* +Y2084750D02*X235273Y2085500D01* +X236773D01* +X237523Y2084750D01* +X234523Y2084000D02*X237523D01* +Y2084750D02*Y2084000D01* +X240075Y2082500D02*X242325D01* +X243075Y2083250D01* +X242325Y2084000D02*X243075Y2083250D01* +X240075Y2084000D02*X242325D01* +X239325Y2084750D02*X240075Y2084000D01* +X239325Y2084750D02*X240075Y2085500D01* +X242325D01* +X243075Y2084750D01* +X239325Y2083250D02*X240075Y2082500D01* +X248326Y2088500D02*Y2083250D01* +X249076Y2082500D01* +X247576Y2086250D02*X249076D01* +X250578Y2084750D02*Y2083250D01* +Y2084750D02*X251328Y2085500D01* +X252828D01* +X253578Y2084750D01* +Y2083250D01* +X252828Y2082500D02*X253578Y2083250D01* +X251328Y2082500D02*X252828D01* +X250578Y2083250D02*X251328Y2082500D01* +X256129Y2088500D02*Y2083250D01* +X256879Y2082500D01* +X255379Y2086250D02*X256879D01* +X260631Y2085500D02*X261381Y2084750D01* +X259131Y2085500D02*X260631D01* +X258381Y2084750D02*X259131Y2085500D01* +X258381Y2084750D02*Y2083250D01* +X259131Y2082500D01* +X261381Y2085500D02*Y2083250D01* +X262131Y2082500D01* +X259131D02*X260631D01* +X261381Y2083250D01* +X263932Y2088500D02*Y2083250D01* +X264682Y2082500D01* +G54D37*X0Y2000000D02*X3000000D01* +X0D02*Y0D01* +X3000000Y2000000D02*Y0D01* +X0D02*X3000000D01* +G54D36*X200000Y2013500D02*Y2007500D01* +Y2013500D02*X202250Y2011250D01* +X204500Y2013500D01* +Y2007500D01* +X208551Y2010500D02*X209301Y2009750D01* +X207051Y2010500D02*X208551D01* +X206301Y2009750D02*X207051Y2010500D01* +X206301Y2009750D02*Y2008250D01* +X207051Y2007500D01* +X209301Y2010500D02*Y2008250D01* +X210051Y2007500D01* +X207051D02*X208551D01* +X209301Y2008250D01* +X211853Y2010500D02*X214853Y2007500D01* +X211853D02*X214853Y2010500D01* +X216654Y2012000D02*Y2011250D01* +Y2009750D02*Y2007500D01* +X218906Y2009750D02*Y2007500D01* +Y2009750D02*X219656Y2010500D01* +X220406D01* +X221156Y2009750D01* +Y2007500D01* +Y2009750D02*X221906Y2010500D01* +X222656D01* +X223406Y2009750D01* +Y2007500D01* +X218156Y2010500D02*X218906Y2009750D01* +X225207Y2010500D02*Y2008250D01* +X225957Y2007500D01* +X227457D01* +X228207Y2008250D01* +Y2010500D02*Y2008250D01* +X230759Y2009750D02*Y2007500D01* +Y2009750D02*X231509Y2010500D01* +X232259D01* +X233009Y2009750D01* +Y2007500D01* +Y2009750D02*X233759Y2010500D01* +X234509D01* +X235259Y2009750D01* +Y2007500D01* +X230009Y2010500D02*X230759Y2009750D01* +X240510Y2013500D02*Y2007500D01* +X242760Y2013500D02*X243510Y2012750D01* +Y2008250D01* +X242760Y2007500D02*X243510Y2008250D01* +X239760Y2007500D02*X242760D01* +X239760Y2013500D02*X242760D01* +X245312Y2012000D02*Y2011250D01* +Y2009750D02*Y2007500D01* +X247563Y2009750D02*Y2007500D01* +Y2009750D02*X248313Y2010500D01* +X249063D01* +X249813Y2009750D01* +Y2007500D01* +Y2009750D02*X250563Y2010500D01* +X251313D01* +X252063Y2009750D01* +Y2007500D01* +X246813Y2010500D02*X247563Y2009750D01* +X254615Y2007500D02*X256865D01* +X253865Y2008250D02*X254615Y2007500D01* +X253865Y2009750D02*Y2008250D01* +Y2009750D02*X254615Y2010500D01* +X256115D01* +X256865Y2009750D01* +X253865Y2009000D02*X256865D01* +Y2009750D02*Y2009000D01* +X259416Y2009750D02*Y2007500D01* +Y2009750D02*X260166Y2010500D01* +X260916D01* +X261666Y2009750D01* +Y2007500D01* +X258666Y2010500D02*X259416Y2009750D01* +X264218Y2007500D02*X266468D01* +X267218Y2008250D01* +X266468Y2009000D02*X267218Y2008250D01* +X264218Y2009000D02*X266468D01* +X263468Y2009750D02*X264218Y2009000D01* +X263468Y2009750D02*X264218Y2010500D01* +X266468D01* +X267218Y2009750D01* +X263468Y2008250D02*X264218Y2007500D01* +X269019Y2012000D02*Y2011250D01* +Y2009750D02*Y2007500D01* +X270521Y2009750D02*Y2008250D01* +Y2009750D02*X271271Y2010500D01* +X272771D01* +X273521Y2009750D01* +Y2008250D01* +X272771Y2007500D02*X273521Y2008250D01* +X271271Y2007500D02*X272771D01* +X270521Y2008250D02*X271271Y2007500D01* +X276072Y2009750D02*Y2007500D01* +Y2009750D02*X276822Y2010500D01* +X277572D01* +X278322Y2009750D01* +Y2007500D01* +X275322Y2010500D02*X276072Y2009750D01* +X280874Y2007500D02*X283124D01* +X283874Y2008250D01* +X283124Y2009000D02*X283874Y2008250D01* +X280874Y2009000D02*X283124D01* +X280124Y2009750D02*X280874Y2009000D01* +X280124Y2009750D02*X280874Y2010500D01* +X283124D01* +X283874Y2009750D01* +X280124Y2008250D02*X280874Y2007500D01* +X285675Y2011250D02*X286425D01* +X285675Y2009750D02*X286425D01* +X290927Y2012750D02*X291677Y2013500D01* +X293177D01* +X293927Y2012750D01* +Y2008250D01* +X293177Y2007500D02*X293927Y2008250D01* +X291677Y2007500D02*X293177D01* +X290927Y2008250D02*X291677Y2007500D01* +Y2010500D02*X293927D01* +X295728Y2008250D02*X296478Y2007500D01* +X295728Y2012750D02*Y2008250D01* +Y2012750D02*X296478Y2013500D01* +X297978D01* +X298728Y2012750D01* +Y2008250D01* +X297978Y2007500D02*X298728Y2008250D01* +X296478Y2007500D02*X297978D01* +X295728Y2009000D02*X298728Y2012000D01* +X300530Y2008250D02*X301280Y2007500D01* +X300530Y2012750D02*Y2008250D01* +Y2012750D02*X301280Y2013500D01* +X302780D01* +X303530Y2012750D01* +Y2008250D01* +X302780Y2007500D02*X303530Y2008250D01* +X301280Y2007500D02*X302780D01* +X300530Y2009000D02*X303530Y2012000D01* +X305331Y2008250D02*X306081Y2007500D01* +X305331Y2012750D02*Y2008250D01* +Y2012750D02*X306081Y2013500D01* +X307581D01* +X308331Y2012750D01* +Y2008250D01* +X307581Y2007500D02*X308331Y2008250D01* +X306081Y2007500D02*X307581D01* +X305331Y2009000D02*X308331Y2012000D01* +X310133Y2008250D02*X310883Y2007500D01* +X310133Y2012750D02*Y2008250D01* +Y2012750D02*X310883Y2013500D01* +X312383D01* +X313133Y2012750D01* +Y2008250D01* +X312383Y2007500D02*X313133Y2008250D01* +X310883Y2007500D02*X312383D01* +X310133Y2009000D02*X313133Y2012000D01* +X314934Y2007500D02*X315684D01* +X317486Y2008250D02*X318236Y2007500D01* +X317486Y2012750D02*Y2008250D01* +Y2012750D02*X318236Y2013500D01* +X319736D01* +X320486Y2012750D01* +Y2008250D01* +X319736Y2007500D02*X320486Y2008250D01* +X318236Y2007500D02*X319736D01* +X317486Y2009000D02*X320486Y2012000D01* +X322287Y2008250D02*X323037Y2007500D01* +X322287Y2012750D02*Y2008250D01* +Y2012750D02*X323037Y2013500D01* +X324537D01* +X325287Y2012750D01* +Y2008250D01* +X324537Y2007500D02*X325287Y2008250D01* +X323037Y2007500D02*X324537D01* +X322287Y2009000D02*X325287Y2012000D01* +X327089Y2008250D02*X327839Y2007500D01* +X327089Y2012750D02*Y2008250D01* +Y2012750D02*X327839Y2013500D01* +X329339D01* +X330089Y2012750D01* +Y2008250D01* +X329339Y2007500D02*X330089Y2008250D01* +X327839Y2007500D02*X329339D01* +X327089Y2009000D02*X330089Y2012000D01* +X331890Y2008250D02*X332640Y2007500D01* +X331890Y2012750D02*Y2008250D01* +Y2012750D02*X332640Y2013500D01* +X334140D01* +X334890Y2012750D01* +Y2008250D01* +X334140Y2007500D02*X334890Y2008250D01* +X332640Y2007500D02*X334140D01* +X331890Y2009000D02*X334890Y2012000D01* +X336692Y2008250D02*X337442Y2007500D01* +X336692Y2012750D02*Y2008250D01* +Y2012750D02*X337442Y2013500D01* +X338942D01* +X339692Y2012750D01* +Y2008250D01* +X338942Y2007500D02*X339692Y2008250D01* +X337442Y2007500D02*X338942D01* +X336692Y2009000D02*X339692Y2012000D01* +X341493Y2008250D02*X342243Y2007500D01* +X341493Y2012750D02*Y2008250D01* +Y2012750D02*X342243Y2013500D01* +X343743D01* +X344493Y2012750D01* +Y2008250D01* +X343743Y2007500D02*X344493Y2008250D01* +X342243Y2007500D02*X343743D01* +X341493Y2009000D02*X344493Y2012000D01* +X349745Y2009750D02*Y2007500D01* +Y2009750D02*X350495Y2010500D01* +X351245D01* +X351995Y2009750D01* +Y2007500D01* +Y2009750D02*X352745Y2010500D01* +X353495D01* +X354245Y2009750D01* +Y2007500D01* +X348995Y2010500D02*X349745Y2009750D01* +X356046Y2012000D02*Y2011250D01* +Y2009750D02*Y2007500D01* +X357548Y2013500D02*Y2008250D01* +X358298Y2007500D01* +X360549D02*X362799D01* +X363549Y2008250D01* +X362799Y2009000D02*X363549Y2008250D01* +X360549Y2009000D02*X362799D01* +X359799Y2009750D02*X360549Y2009000D01* +X359799Y2009750D02*X360549Y2010500D01* +X362799D01* +X363549Y2009750D01* +X359799Y2008250D02*X360549Y2007500D01* +X368051Y2010500D02*Y2008250D01* +X368801Y2007500D01* +X369551D01* +X370301Y2008250D01* +Y2010500D02*Y2008250D01* +X371051Y2007500D01* +X371801D01* +X372551Y2008250D01* +Y2010500D02*Y2008250D01* +X374352Y2012000D02*Y2011250D01* +Y2009750D02*Y2007500D01* +X378854Y2013500D02*Y2007500D01* +X378104D02*X378854Y2008250D01* +X376604Y2007500D02*X378104D01* +X375854Y2008250D02*X376604Y2007500D01* +X375854Y2009750D02*Y2008250D01* +Y2009750D02*X376604Y2010500D01* +X378104D01* +X378854Y2009750D01* +X381405Y2007500D02*X383655D01* +X380655Y2008250D02*X381405Y2007500D01* +X380655Y2009750D02*Y2008250D01* +Y2009750D02*X381405Y2010500D01* +X382905D01* +X383655Y2009750D01* +X380655Y2009000D02*X383655D01* +Y2009750D02*Y2009000D01* +X385457Y2006000D02*X386957Y2007500D01* +X391458Y2012750D02*X392208Y2013500D01* +X394458D01* +X395208Y2012750D01* +Y2011250D01* +X391458Y2007500D02*X395208Y2011250D01* +X391458Y2007500D02*X395208D01* +X397010Y2008250D02*X397760Y2007500D01* +X397010Y2012750D02*Y2008250D01* +Y2012750D02*X397760Y2013500D01* +X399260D01* +X400010Y2012750D01* +Y2008250D01* +X399260Y2007500D02*X400010Y2008250D01* +X397760Y2007500D02*X399260D01* +X397010Y2009000D02*X400010Y2012000D01* +X401811Y2008250D02*X402561Y2007500D01* +X401811Y2012750D02*Y2008250D01* +Y2012750D02*X402561Y2013500D01* +X404061D01* +X404811Y2012750D01* +Y2008250D01* +X404061Y2007500D02*X404811Y2008250D01* +X402561Y2007500D02*X404061D01* +X401811Y2009000D02*X404811Y2012000D01* +X406613Y2008250D02*X407363Y2007500D01* +X406613Y2012750D02*Y2008250D01* +Y2012750D02*X407363Y2013500D01* +X408863D01* +X409613Y2012750D01* +Y2008250D01* +X408863Y2007500D02*X409613Y2008250D01* +X407363Y2007500D02*X408863D01* +X406613Y2009000D02*X409613Y2012000D01* +X411414Y2008250D02*X412164Y2007500D01* +X411414Y2012750D02*Y2008250D01* +Y2012750D02*X412164Y2013500D01* +X413664D01* +X414414Y2012750D01* +Y2008250D01* +X413664Y2007500D02*X414414Y2008250D01* +X412164Y2007500D02*X413664D01* +X411414Y2009000D02*X414414Y2012000D01* +X416216Y2007500D02*X416966D01* +X418767Y2008250D02*X419517Y2007500D01* +X418767Y2012750D02*Y2008250D01* +Y2012750D02*X419517Y2013500D01* +X421017D01* +X421767Y2012750D01* +Y2008250D01* +X421017Y2007500D02*X421767Y2008250D01* +X419517Y2007500D02*X421017D01* +X418767Y2009000D02*X421767Y2012000D01* +X423569Y2008250D02*X424319Y2007500D01* +X423569Y2012750D02*Y2008250D01* +Y2012750D02*X424319Y2013500D01* +X425819D01* +X426569Y2012750D01* +Y2008250D01* +X425819Y2007500D02*X426569Y2008250D01* +X424319Y2007500D02*X425819D01* +X423569Y2009000D02*X426569Y2012000D01* +X428370Y2008250D02*X429120Y2007500D01* +X428370Y2012750D02*Y2008250D01* +Y2012750D02*X429120Y2013500D01* +X430620D01* +X431370Y2012750D01* +Y2008250D01* +X430620Y2007500D02*X431370Y2008250D01* +X429120Y2007500D02*X430620D01* +X428370Y2009000D02*X431370Y2012000D01* +X433172Y2008250D02*X433922Y2007500D01* +X433172Y2012750D02*Y2008250D01* +Y2012750D02*X433922Y2013500D01* +X435422D01* +X436172Y2012750D01* +Y2008250D01* +X435422Y2007500D02*X436172Y2008250D01* +X433922Y2007500D02*X435422D01* +X433172Y2009000D02*X436172Y2012000D01* +X437973Y2008250D02*X438723Y2007500D01* +X437973Y2012750D02*Y2008250D01* +Y2012750D02*X438723Y2013500D01* +X440223D01* +X440973Y2012750D01* +Y2008250D01* +X440223Y2007500D02*X440973Y2008250D01* +X438723Y2007500D02*X440223D01* +X437973Y2009000D02*X440973Y2012000D01* +X442775Y2008250D02*X443525Y2007500D01* +X442775Y2012750D02*Y2008250D01* +Y2012750D02*X443525Y2013500D01* +X445025D01* +X445775Y2012750D01* +Y2008250D01* +X445025Y2007500D02*X445775Y2008250D01* +X443525Y2007500D02*X445025D01* +X442775Y2009000D02*X445775Y2012000D01* +X451026Y2009750D02*Y2007500D01* +Y2009750D02*X451776Y2010500D01* +X452526D01* +X453276Y2009750D01* +Y2007500D01* +Y2009750D02*X454026Y2010500D01* +X454776D01* +X455526Y2009750D01* +Y2007500D01* +X450276Y2010500D02*X451026Y2009750D01* +X457328Y2012000D02*Y2011250D01* +Y2009750D02*Y2007500D01* +X458829Y2013500D02*Y2008250D01* +X459579Y2007500D01* +X461831D02*X464081D01* +X464831Y2008250D01* +X464081Y2009000D02*X464831Y2008250D01* +X461831Y2009000D02*X464081D01* +X461081Y2009750D02*X461831Y2009000D01* +X461081Y2009750D02*X461831Y2010500D01* +X464081D01* +X464831Y2009750D01* +X461081Y2008250D02*X461831Y2007500D01* +X469332Y2013500D02*Y2007500D01* +Y2009750D02*X470082Y2010500D01* +X471582D01* +X472332Y2009750D01* +Y2007500D01* +X474134Y2012000D02*Y2011250D01* +Y2009750D02*Y2007500D01* +X477885Y2010500D02*X478635Y2009750D01* +X476385Y2010500D02*X477885D01* +X475635Y2009750D02*X476385Y2010500D01* +X475635Y2009750D02*Y2008250D01* +X476385Y2007500D01* +X477885D01* +X478635Y2008250D01* +X475635Y2006000D02*X476385Y2005250D01* +X477885D01* +X478635Y2006000D01* +Y2010500D02*Y2006000D01* +X480437Y2013500D02*Y2007500D01* +Y2009750D02*X481187Y2010500D01* +X482687D01* +X483437Y2009750D01* +Y2007500D01* +X1292034Y-9500D02*X1295034D01* +X1295784Y-8750D01* +Y-7250D02*Y-8750D01* +X1295034Y-6500D02*X1295784Y-7250D01* +X1292784Y-6500D02*X1295034D01* +X1292784Y-3500D02*Y-9500D01* +X1292034Y-3500D02*X1295034D01* +X1295784Y-4250D01* +Y-5750D01* +X1295034Y-6500D02*X1295784Y-5750D01* +X1297585Y-7250D02*Y-8750D01* +Y-7250D02*X1298335Y-6500D01* +X1299835D01* +X1300585Y-7250D01* +Y-8750D01* +X1299835Y-9500D02*X1300585Y-8750D01* +X1298335Y-9500D02*X1299835D01* +X1297585Y-8750D02*X1298335Y-9500D01* +X1304637Y-6500D02*X1305387Y-7250D01* +X1303137Y-6500D02*X1304637D01* +X1302387Y-7250D02*X1303137Y-6500D01* +X1302387Y-7250D02*Y-8750D01* +X1303137Y-9500D01* +X1305387Y-6500D02*Y-8750D01* +X1306137Y-9500D01* +X1303137D02*X1304637D01* +X1305387Y-8750D01* +X1308688Y-7250D02*Y-9500D01* +Y-7250D02*X1309438Y-6500D01* +X1310938D01* +X1307938D02*X1308688Y-7250D01* +X1315740Y-3500D02*Y-9500D01* +X1314990D02*X1315740Y-8750D01* +X1313490Y-9500D02*X1314990D01* +X1312740Y-8750D02*X1313490Y-9500D01* +X1312740Y-7250D02*Y-8750D01* +Y-7250D02*X1313490Y-6500D01* +X1314990D01* +X1315740Y-7250D01* +X1320241D02*Y-8750D01* +Y-7250D02*X1320991Y-6500D01* +X1322491D01* +X1323241Y-7250D01* +Y-8750D01* +X1322491Y-9500D02*X1323241Y-8750D01* +X1320991Y-9500D02*X1322491D01* +X1320241Y-8750D02*X1320991Y-9500D01* +X1325043Y-6500D02*Y-8750D01* +X1325793Y-9500D01* +X1327293D01* +X1328043Y-8750D01* +Y-6500D02*Y-8750D01* +X1330594Y-3500D02*Y-8750D01* +X1331344Y-9500D01* +X1329844Y-5750D02*X1331344D01* +X1332846Y-3500D02*Y-8750D01* +X1333596Y-9500D01* +X1335097Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X1337349Y-7250D02*Y-9500D01* +Y-7250D02*X1338099Y-6500D01* +X1338849D01* +X1339599Y-7250D01* +Y-9500D01* +X1336599Y-6500D02*X1337349Y-7250D01* +X1342150Y-9500D02*X1344400D01* +X1341400Y-8750D02*X1342150Y-9500D01* +X1341400Y-7250D02*Y-8750D01* +Y-7250D02*X1342150Y-6500D01* +X1343650D01* +X1344400Y-7250D01* +X1341400Y-8000D02*X1344400D01* +Y-7250D02*Y-8000D01* +X1348902Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X1351153D02*X1353403D01* +X1354153Y-8750D01* +X1353403Y-8000D02*X1354153Y-8750D01* +X1351153Y-8000D02*X1353403D01* +X1350403Y-7250D02*X1351153Y-8000D01* +X1350403Y-7250D02*X1351153Y-6500D01* +X1353403D01* +X1354153Y-7250D01* +X1350403Y-8750D02*X1351153Y-9500D01* +X1359405Y-3500D02*Y-8750D01* +X1360155Y-9500D01* +X1358655Y-5750D02*X1360155D01* +X1361656Y-3500D02*Y-9500D01* +Y-7250D02*X1362406Y-6500D01* +X1363906D01* +X1364656Y-7250D01* +Y-9500D01* +X1367208D02*X1369458D01* +X1366458Y-8750D02*X1367208Y-9500D01* +X1366458Y-7250D02*Y-8750D01* +Y-7250D02*X1367208Y-6500D01* +X1368708D01* +X1369458Y-7250D01* +X1366458Y-8000D02*X1369458D01* +Y-7250D02*Y-8000D01* +X1374709Y-6500D02*X1376959D01* +X1373959Y-7250D02*X1374709Y-6500D01* +X1373959Y-7250D02*Y-8750D01* +X1374709Y-9500D01* +X1376959D01* +X1379511D02*X1381761D01* +X1378761Y-8750D02*X1379511Y-9500D01* +X1378761Y-7250D02*Y-8750D01* +Y-7250D02*X1379511Y-6500D01* +X1381011D01* +X1381761Y-7250D01* +X1378761Y-8000D02*X1381761D01* +Y-7250D02*Y-8000D01* +X1384312Y-7250D02*Y-9500D01* +Y-7250D02*X1385062Y-6500D01* +X1385812D01* +X1386562Y-7250D01* +Y-9500D01* +X1383562Y-6500D02*X1384312Y-7250D01* +X1389114Y-3500D02*Y-8750D01* +X1389864Y-9500D01* +X1388364Y-5750D02*X1389864D01* +X1392115Y-9500D02*X1394365D01* +X1391365Y-8750D02*X1392115Y-9500D01* +X1391365Y-7250D02*Y-8750D01* +Y-7250D02*X1392115Y-6500D01* +X1393615D01* +X1394365Y-7250D01* +X1391365Y-8000D02*X1394365D01* +Y-7250D02*Y-8000D01* +X1396917Y-7250D02*Y-9500D01* +Y-7250D02*X1397667Y-6500D01* +X1399167D01* +X1396167D02*X1396917Y-7250D01* +X1400968Y-3500D02*Y-8750D01* +X1401718Y-9500D01* +X1403220Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X1405471Y-7250D02*Y-9500D01* +Y-7250D02*X1406221Y-6500D01* +X1406971D01* +X1407721Y-7250D01* +Y-9500D01* +X1404721Y-6500D02*X1405471Y-7250D01* +X1410273Y-9500D02*X1412523D01* +X1409523Y-8750D02*X1410273Y-9500D01* +X1409523Y-7250D02*Y-8750D01* +Y-7250D02*X1410273Y-6500D01* +X1411773D01* +X1412523Y-7250D01* +X1409523Y-8000D02*X1412523D01* +Y-7250D02*Y-8000D01* +X1417024Y-7250D02*Y-8750D01* +Y-7250D02*X1417774Y-6500D01* +X1419274D01* +X1420024Y-7250D01* +Y-8750D01* +X1419274Y-9500D02*X1420024Y-8750D01* +X1417774Y-9500D02*X1419274D01* +X1417024Y-8750D02*X1417774Y-9500D01* +X1422576Y-4250D02*Y-9500D01* +Y-4250D02*X1423326Y-3500D01* +X1424076D01* +X1421826Y-6500D02*X1423326D01* +X1429027Y-3500D02*Y-8750D01* +X1429777Y-9500D01* +X1428277Y-5750D02*X1429777D01* +X1431279Y-3500D02*Y-9500D01* +Y-7250D02*X1432029Y-6500D01* +X1433529D01* +X1434279Y-7250D01* +Y-9500D01* +X1436080Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X1438332D02*X1440582D01* +X1441332Y-8750D01* +X1440582Y-8000D02*X1441332Y-8750D01* +X1438332Y-8000D02*X1440582D01* +X1437582Y-7250D02*X1438332Y-8000D01* +X1437582Y-7250D02*X1438332Y-6500D01* +X1440582D01* +X1441332Y-7250D01* +X1437582Y-8750D02*X1438332Y-9500D01* +X1445833Y-8750D02*X1446583Y-9500D01* +X1445833Y-7250D02*Y-8750D01* +Y-7250D02*X1446583Y-6500D01* +X1448083D01* +X1448833Y-7250D01* +Y-8750D01* +X1448083Y-9500D02*X1448833Y-8750D01* +X1446583Y-9500D02*X1448083D01* +X1445833Y-5750D02*X1446583Y-6500D01* +X1445833Y-4250D02*Y-5750D01* +Y-4250D02*X1446583Y-3500D01* +X1448083D01* +X1448833Y-4250D01* +Y-5750D01* +X1448083Y-6500D02*X1448833Y-5750D01* +X1450635Y-9500D02*X1451385D01* +X1453186Y-8750D02*X1453936Y-9500D01* +X1453186Y-4250D02*Y-8750D01* +Y-4250D02*X1453936Y-3500D01* +X1455436D01* +X1456186Y-4250D01* +Y-8750D01* +X1455436Y-9500D02*X1456186Y-8750D01* +X1453936Y-9500D02*X1455436D01* +X1453186Y-8000D02*X1456186Y-5000D01* +X1457988Y-8750D02*X1458738Y-9500D01* +X1457988Y-4250D02*Y-8750D01* +Y-4250D02*X1458738Y-3500D01* +X1460238D01* +X1460988Y-4250D01* +Y-8750D01* +X1460238Y-9500D02*X1460988Y-8750D01* +X1458738Y-9500D02*X1460238D01* +X1457988Y-8000D02*X1460988Y-5000D01* +X1462789Y-8750D02*X1463539Y-9500D01* +X1462789Y-4250D02*Y-8750D01* +Y-4250D02*X1463539Y-3500D01* +X1465039D01* +X1465789Y-4250D01* +Y-8750D01* +X1465039Y-9500D02*X1465789Y-8750D01* +X1463539Y-9500D02*X1465039D01* +X1462789Y-8000D02*X1465789Y-5000D01* +X1467591Y-8750D02*X1468341Y-9500D01* +X1467591Y-4250D02*Y-8750D01* +Y-4250D02*X1468341Y-3500D01* +X1469841D01* +X1470591Y-4250D01* +Y-8750D01* +X1469841Y-9500D02*X1470591Y-8750D01* +X1468341Y-9500D02*X1469841D01* +X1467591Y-8000D02*X1470591Y-5000D01* +X1472392Y-8750D02*X1473142Y-9500D01* +X1472392Y-4250D02*Y-8750D01* +Y-4250D02*X1473142Y-3500D01* +X1474642D01* +X1475392Y-4250D01* +Y-8750D01* +X1474642Y-9500D02*X1475392Y-8750D01* +X1473142Y-9500D02*X1474642D01* +X1472392Y-8000D02*X1475392Y-5000D01* +X1477194Y-8750D02*X1477944Y-9500D01* +X1477194Y-4250D02*Y-8750D01* +Y-4250D02*X1477944Y-3500D01* +X1479444D01* +X1480194Y-4250D01* +Y-8750D01* +X1479444Y-9500D02*X1480194Y-8750D01* +X1477944Y-9500D02*X1479444D01* +X1477194Y-8000D02*X1480194Y-5000D01* +X1485445Y-7250D02*Y-9500D01* +Y-7250D02*X1486195Y-6500D01* +X1486945D01* +X1487695Y-7250D01* +Y-9500D01* +Y-7250D02*X1488445Y-6500D01* +X1489195D01* +X1489945Y-7250D01* +Y-9500D01* +X1484695Y-6500D02*X1485445Y-7250D01* +X1491747Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X1493248Y-3500D02*Y-8750D01* +X1493998Y-9500D01* +X1498950Y-7250D02*Y-9500D01* +Y-7250D02*X1499700Y-6500D01* +X1501200D01* +X1498200D02*X1498950Y-7250D01* +X1503751Y-9500D02*X1506001D01* +X1503001Y-8750D02*X1503751Y-9500D01* +X1503001Y-7250D02*Y-8750D01* +Y-7250D02*X1503751Y-6500D01* +X1505251D01* +X1506001Y-7250D01* +X1503001Y-8000D02*X1506001D01* +Y-7250D02*Y-8000D01* +X1508553Y-6500D02*X1510803D01* +X1507803Y-7250D02*X1508553Y-6500D01* +X1507803Y-7250D02*Y-8750D01* +X1508553Y-9500D01* +X1510803D01* +X1513354Y-3500D02*Y-8750D01* +X1514104Y-9500D01* +X1512604Y-5750D02*X1514104D01* +X1517856Y-6500D02*X1518606Y-7250D01* +X1516356Y-6500D02*X1517856D01* +X1515606Y-7250D02*X1516356Y-6500D01* +X1515606Y-7250D02*Y-8750D01* +X1516356Y-9500D01* +X1518606Y-6500D02*Y-8750D01* +X1519356Y-9500D01* +X1516356D02*X1517856D01* +X1518606Y-8750D01* +X1521907Y-7250D02*Y-9500D01* +Y-7250D02*X1522657Y-6500D01* +X1523407D01* +X1524157Y-7250D01* +Y-9500D01* +X1521157Y-6500D02*X1521907Y-7250D01* +X1528209Y-6500D02*X1528959Y-7250D01* +X1526709Y-6500D02*X1528209D01* +X1525959Y-7250D02*X1526709Y-6500D01* +X1525959Y-7250D02*Y-8750D01* +X1526709Y-9500D01* +X1528209D01* +X1528959Y-8750D01* +X1525959Y-11000D02*X1526709Y-11750D01* +X1528209D01* +X1528959Y-11000D01* +Y-6500D02*Y-11000D01* +X1530760Y-3500D02*Y-8750D01* +X1531510Y-9500D01* +X1533762D02*X1536012D01* +X1533012Y-8750D02*X1533762Y-9500D01* +X1533012Y-7250D02*Y-8750D01* +Y-7250D02*X1533762Y-6500D01* +X1535262D01* +X1536012Y-7250D01* +X1533012Y-8000D02*X1536012D01* +Y-7250D02*Y-8000D01* +X1540513Y-6500D02*X1543513D01* +X1548015Y-8750D02*X1548765Y-9500D01* +X1548015Y-4250D02*Y-8750D01* +Y-4250D02*X1548765Y-3500D01* +X1550265D01* +X1551015Y-4250D01* +Y-8750D01* +X1550265Y-9500D02*X1551015Y-8750D01* +X1548765Y-9500D02*X1550265D01* +X1548015Y-8000D02*X1551015Y-5000D01* +X1552816Y-11000D02*X1554316Y-9500D01* +X1556118Y-8750D02*X1556868Y-9500D01* +X1556118Y-4250D02*Y-8750D01* +Y-4250D02*X1556868Y-3500D01* +X1558368D01* +X1559118Y-4250D01* +Y-8750D01* +X1558368Y-9500D02*X1559118Y-8750D01* +X1556868Y-9500D02*X1558368D01* +X1556118Y-8000D02*X1559118Y-5000D01* +X1564369Y-3500D02*Y-8750D01* +X1565119Y-9500D01* +X1563619Y-5750D02*X1565119D01* +X1566621Y-7250D02*Y-8750D01* +Y-7250D02*X1567371Y-6500D01* +X1568871D01* +X1569621Y-7250D01* +Y-8750D01* +X1568871Y-9500D02*X1569621Y-8750D01* +X1567371Y-9500D02*X1568871D01* +X1566621Y-8750D02*X1567371Y-9500D01* +X1574122Y-4250D02*X1574872Y-3500D01* +X1576372D01* +X1577122Y-4250D01* +Y-8750D01* +X1576372Y-9500D02*X1577122Y-8750D01* +X1574872Y-9500D02*X1576372D01* +X1574122Y-8750D02*X1574872Y-9500D01* +Y-6500D02*X1577122D01* +X1578924Y-8750D02*X1579674Y-9500D01* +X1578924Y-4250D02*Y-8750D01* +Y-4250D02*X1579674Y-3500D01* +X1581174D01* +X1581924Y-4250D01* +Y-8750D01* +X1581174Y-9500D02*X1581924Y-8750D01* +X1579674Y-9500D02*X1581174D01* +X1578924Y-8000D02*X1581924Y-5000D01* +X1583725Y-8750D02*X1584475Y-9500D01* +X1583725Y-4250D02*Y-8750D01* +Y-4250D02*X1584475Y-3500D01* +X1585975D01* +X1586725Y-4250D01* +Y-8750D01* +X1585975Y-9500D02*X1586725Y-8750D01* +X1584475Y-9500D02*X1585975D01* +X1583725Y-8000D02*X1586725Y-5000D01* +X1588527Y-8750D02*X1589277Y-9500D01* +X1588527Y-4250D02*Y-8750D01* +Y-4250D02*X1589277Y-3500D01* +X1590777D01* +X1591527Y-4250D01* +Y-8750D01* +X1590777Y-9500D02*X1591527Y-8750D01* +X1589277Y-9500D02*X1590777D01* +X1588527Y-8000D02*X1591527Y-5000D01* +X1593328Y-8750D02*X1594078Y-9500D01* +X1593328Y-4250D02*Y-8750D01* +Y-4250D02*X1594078Y-3500D01* +X1595578D01* +X1596328Y-4250D01* +Y-8750D01* +X1595578Y-9500D02*X1596328Y-8750D01* +X1594078Y-9500D02*X1595578D01* +X1593328Y-8000D02*X1596328Y-5000D01* +X1598130Y-9500D02*X1598880D01* +X1600681Y-8750D02*X1601431Y-9500D01* +X1600681Y-4250D02*Y-8750D01* +Y-4250D02*X1601431Y-3500D01* +X1602931D01* +X1603681Y-4250D01* +Y-8750D01* +X1602931Y-9500D02*X1603681Y-8750D01* +X1601431Y-9500D02*X1602931D01* +X1600681Y-8000D02*X1603681Y-5000D01* +X1605483Y-8750D02*X1606233Y-9500D01* +X1605483Y-4250D02*Y-8750D01* +Y-4250D02*X1606233Y-3500D01* +X1607733D01* +X1608483Y-4250D01* +Y-8750D01* +X1607733Y-9500D02*X1608483Y-8750D01* +X1606233Y-9500D02*X1607733D01* +X1605483Y-8000D02*X1608483Y-5000D01* +X1610284Y-8750D02*X1611034Y-9500D01* +X1610284Y-4250D02*Y-8750D01* +Y-4250D02*X1611034Y-3500D01* +X1612534D01* +X1613284Y-4250D01* +Y-8750D01* +X1612534Y-9500D02*X1613284Y-8750D01* +X1611034Y-9500D02*X1612534D01* +X1610284Y-8000D02*X1613284Y-5000D01* +X1615086Y-8750D02*X1615836Y-9500D01* +X1615086Y-4250D02*Y-8750D01* +Y-4250D02*X1615836Y-3500D01* +X1617336D01* +X1618086Y-4250D01* +Y-8750D01* +X1617336Y-9500D02*X1618086Y-8750D01* +X1615836Y-9500D02*X1617336D01* +X1615086Y-8000D02*X1618086Y-5000D01* +X1619887Y-8750D02*X1620637Y-9500D01* +X1619887Y-4250D02*Y-8750D01* +Y-4250D02*X1620637Y-3500D01* +X1622137D01* +X1622887Y-4250D01* +Y-8750D01* +X1622137Y-9500D02*X1622887Y-8750D01* +X1620637Y-9500D02*X1622137D01* +X1619887Y-8000D02*X1622887Y-5000D01* +X1624689Y-8750D02*X1625439Y-9500D01* +X1624689Y-4250D02*Y-8750D01* +Y-4250D02*X1625439Y-3500D01* +X1626939D01* +X1627689Y-4250D01* +Y-8750D01* +X1626939Y-9500D02*X1627689Y-8750D01* +X1625439Y-9500D02*X1626939D01* +X1624689Y-8000D02*X1627689Y-5000D01* +X1629490Y-11000D02*X1630990Y-9500D01* +X1632792Y-4250D02*X1633542Y-3500D01* +X1635792D01* +X1636542Y-4250D01* +Y-5750D01* +X1632792Y-9500D02*X1636542Y-5750D01* +X1632792Y-9500D02*X1636542D01* +X1638343Y-8750D02*X1639093Y-9500D01* +X1638343Y-4250D02*Y-8750D01* +Y-4250D02*X1639093Y-3500D01* +X1640593D01* +X1641343Y-4250D01* +Y-8750D01* +X1640593Y-9500D02*X1641343Y-8750D01* +X1639093Y-9500D02*X1640593D01* +X1638343Y-8000D02*X1641343Y-5000D01* +X1643145Y-8750D02*X1643895Y-9500D01* +X1643145Y-4250D02*Y-8750D01* +Y-4250D02*X1643895Y-3500D01* +X1645395D01* +X1646145Y-4250D01* +Y-8750D01* +X1645395Y-9500D02*X1646145Y-8750D01* +X1643895Y-9500D02*X1645395D01* +X1643145Y-8000D02*X1646145Y-5000D01* +X1647946Y-8750D02*X1648696Y-9500D01* +X1647946Y-4250D02*Y-8750D01* +Y-4250D02*X1648696Y-3500D01* +X1650196D01* +X1650946Y-4250D01* +Y-8750D01* +X1650196Y-9500D02*X1650946Y-8750D01* +X1648696Y-9500D02*X1650196D01* +X1647946Y-8000D02*X1650946Y-5000D01* +X1652748Y-8750D02*X1653498Y-9500D01* +X1652748Y-4250D02*Y-8750D01* +Y-4250D02*X1653498Y-3500D01* +X1654998D01* +X1655748Y-4250D01* +Y-8750D01* +X1654998Y-9500D02*X1655748Y-8750D01* +X1653498Y-9500D02*X1654998D01* +X1652748Y-8000D02*X1655748Y-5000D01* +X1657549Y-9500D02*X1658299D01* +X1660101Y-8750D02*X1660851Y-9500D01* +X1660101Y-4250D02*Y-8750D01* +Y-4250D02*X1660851Y-3500D01* +X1662351D01* +X1663101Y-4250D01* +Y-8750D01* +X1662351Y-9500D02*X1663101Y-8750D01* +X1660851Y-9500D02*X1662351D01* +X1660101Y-8000D02*X1663101Y-5000D01* +X1664902Y-8750D02*X1665652Y-9500D01* +X1664902Y-4250D02*Y-8750D01* +Y-4250D02*X1665652Y-3500D01* +X1667152D01* +X1667902Y-4250D01* +Y-8750D01* +X1667152Y-9500D02*X1667902Y-8750D01* +X1665652Y-9500D02*X1667152D01* +X1664902Y-8000D02*X1667902Y-5000D01* +X1669704Y-8750D02*X1670454Y-9500D01* +X1669704Y-4250D02*Y-8750D01* +Y-4250D02*X1670454Y-3500D01* +X1671954D01* +X1672704Y-4250D01* +Y-8750D01* +X1671954Y-9500D02*X1672704Y-8750D01* +X1670454Y-9500D02*X1671954D01* +X1669704Y-8000D02*X1672704Y-5000D01* +X1674505Y-8750D02*X1675255Y-9500D01* +X1674505Y-4250D02*Y-8750D01* +Y-4250D02*X1675255Y-3500D01* +X1676755D01* +X1677505Y-4250D01* +Y-8750D01* +X1676755Y-9500D02*X1677505Y-8750D01* +X1675255Y-9500D02*X1676755D01* +X1674505Y-8000D02*X1677505Y-5000D01* +X1679307Y-8750D02*X1680057Y-9500D01* +X1679307Y-4250D02*Y-8750D01* +Y-4250D02*X1680057Y-3500D01* +X1681557D01* +X1682307Y-4250D01* +Y-8750D01* +X1681557Y-9500D02*X1682307Y-8750D01* +X1680057Y-9500D02*X1681557D01* +X1679307Y-8000D02*X1682307Y-5000D01* +X1684108Y-8750D02*X1684858Y-9500D01* +X1684108Y-4250D02*Y-8750D01* +Y-4250D02*X1684858Y-3500D01* +X1686358D01* +X1687108Y-4250D01* +Y-8750D01* +X1686358Y-9500D02*X1687108Y-8750D01* +X1684858Y-9500D02*X1686358D01* +X1684108Y-8000D02*X1687108Y-5000D01* +X1692360Y-7250D02*Y-9500D01* +Y-7250D02*X1693110Y-6500D01* +X1693860D01* +X1694610Y-7250D01* +Y-9500D01* +Y-7250D02*X1695360Y-6500D01* +X1696110D01* +X1696860Y-7250D01* +Y-9500D01* +X1691610Y-6500D02*X1692360Y-7250D01* +X1698661Y-5000D02*Y-5750D01* +Y-7250D02*Y-9500D01* +X1700163Y-3500D02*Y-8750D01* +X1700913Y-9500D01* +X1703164D02*X1705414D01* +X1706164Y-8750D01* +X1705414Y-8000D02*X1706164Y-8750D01* +X1703164Y-8000D02*X1705414D01* +X1702414Y-7250D02*X1703164Y-8000D01* +X1702414Y-7250D02*X1703164Y-6500D01* +X1705414D01* +X1706164Y-7250D01* +X1702414Y-8750D02*X1703164Y-9500D01* +X200750Y2028500D02*Y2022500D01* +X203000Y2028500D02*X203750Y2027750D01* +Y2023250D01* +X203000Y2022500D02*X203750Y2023250D01* +X200000Y2022500D02*X203000D01* +X200000Y2028500D02*X203000D01* +X207801Y2025500D02*X208551Y2024750D01* +X206301Y2025500D02*X207801D01* +X205551Y2024750D02*X206301Y2025500D01* +X205551Y2024750D02*Y2023250D01* +X206301Y2022500D01* +X208551Y2025500D02*Y2023250D01* +X209301Y2022500D01* +X206301D02*X207801D01* +X208551Y2023250D01* +X211853Y2028500D02*Y2023250D01* +X212603Y2022500D01* +X211103Y2026250D02*X212603D01* +X214854Y2022500D02*X217104D01* +X214104Y2023250D02*X214854Y2022500D01* +X214104Y2024750D02*Y2023250D01* +Y2024750D02*X214854Y2025500D01* +X216354D01* +X217104Y2024750D01* +X214104Y2024000D02*X217104D01* +Y2024750D02*Y2024000D01* +X218906Y2026250D02*X219656D01* +X218906Y2024750D02*X219656D01* +X224157Y2028500D02*Y2022500D01* +Y2028500D02*X227157D01* +X224157Y2025500D02*X226407D01* +X229709Y2024750D02*Y2022500D01* +Y2024750D02*X230459Y2025500D01* +X231959D01* +X228959D02*X229709Y2024750D01* +X233760Y2027000D02*Y2026250D01* +Y2024750D02*Y2022500D01* +X237962Y2028500D02*X240212D01* +Y2023250D01* +X239462Y2022500D02*X240212Y2023250D01* +X238712Y2022500D02*X239462D01* +X237962Y2023250D02*X238712Y2022500D01* +X242013Y2025500D02*Y2023250D01* +X242763Y2022500D01* +X244263D01* +X245013Y2023250D01* +Y2025500D02*Y2023250D01* +X247565Y2024750D02*Y2022500D01* +Y2024750D02*X248315Y2025500D01* +X249065D01* +X249815Y2024750D01* +Y2022500D01* +X246815Y2025500D02*X247565Y2024750D01* +X255066Y2022500D02*X256566D01* +X255816Y2028500D02*Y2022500D01* +X254316Y2027000D02*X255816Y2028500D01* +X258368Y2022500D02*X262118Y2026250D01* +Y2028500D02*Y2026250D01* +X258368Y2028500D02*X262118D01* +X266619Y2023250D02*X267369Y2022500D01* +X266619Y2027750D02*Y2023250D01* +Y2027750D02*X267369Y2028500D01* +X268869D01* +X269619Y2027750D01* +Y2023250D01* +X268869Y2022500D02*X269619Y2023250D01* +X267369Y2022500D02*X268869D01* +X266619Y2024000D02*X269619Y2027000D01* +X271421Y2027750D02*X272171Y2028500D01* +X273671D01* +X274421Y2027750D01* +Y2023250D01* +X273671Y2022500D02*X274421Y2023250D01* +X272171Y2022500D02*X273671D01* +X271421Y2023250D02*X272171Y2022500D01* +Y2025500D02*X274421D01* +X276222Y2026250D02*X276972D01* +X276222Y2024750D02*X276972D01* +X279524Y2022500D02*X281024D01* +X280274Y2028500D02*Y2022500D01* +X278774Y2027000D02*X280274Y2028500D01* +X282825Y2023250D02*X283575Y2022500D01* +X282825Y2024750D02*Y2023250D01* +Y2024750D02*X283575Y2025500D01* +X285075D01* +X285825Y2024750D01* +Y2023250D01* +X285075Y2022500D02*X285825Y2023250D01* +X283575Y2022500D02*X285075D01* +X282825Y2026250D02*X283575Y2025500D01* +X282825Y2027750D02*Y2026250D01* +Y2027750D02*X283575Y2028500D01* +X285075D01* +X285825Y2027750D01* +Y2026250D01* +X285075Y2025500D02*X285825Y2026250D01* +X287627D02*X288377D01* +X287627Y2024750D02*X288377D01* +X290178Y2028500D02*X293178D01* +X290178D02*Y2025500D01* +X290928Y2026250D01* +X292428D01* +X293178Y2025500D01* +Y2023250D01* +X292428Y2022500D02*X293178Y2023250D01* +X290928Y2022500D02*X292428D01* +X290178Y2023250D02*X290928Y2022500D01* +X295730D02*X297230D01* +X296480Y2028500D02*Y2022500D01* +X294980Y2027000D02*X296480Y2028500D01* +X301731Y2027750D02*X302481Y2028500D01* +X304731D01* +X305481Y2027750D01* +Y2026250D01* +X301731Y2022500D02*X305481Y2026250D01* +X301731Y2022500D02*X305481D01* +X307283Y2023250D02*X308033Y2022500D01* +X307283Y2027750D02*Y2023250D01* +Y2027750D02*X308033Y2028500D01* +X309533D01* +X310283Y2027750D01* +Y2023250D01* +X309533Y2022500D02*X310283Y2023250D01* +X308033Y2022500D02*X309533D01* +X307283Y2024000D02*X310283Y2027000D01* +X312834Y2022500D02*X314334D01* +X313584Y2028500D02*Y2022500D01* +X312084Y2027000D02*X313584Y2028500D01* +X316886Y2022500D02*X318386D01* +X317636Y2028500D02*Y2022500D01* +X316136Y2027000D02*X317636Y2028500D01* +X322887D02*Y2023250D01* +X323637Y2022500D01* +X325137D01* +X325887Y2023250D01* +Y2028500D02*Y2023250D01* +X327689Y2028500D02*X330689D01* +X329189D02*Y2022500D01* +X333240D02*X335490D01* +X332490Y2023250D02*X333240Y2022500D01* +X332490Y2027750D02*Y2023250D01* +Y2027750D02*X333240Y2028500D01* +X335490D01* +X200000Y2042750D02*Y2037500D01* +Y2042750D02*X200750Y2043500D01* +X203000D01* +X203750Y2042750D01* +Y2037500D01* +X200000Y2040500D02*X203750D01* +X205551D02*Y2038250D01* +X206301Y2037500D01* +X207801D01* +X208551Y2038250D01* +Y2040500D02*Y2038250D01* +X211103Y2043500D02*Y2038250D01* +X211853Y2037500D01* +X210353Y2041250D02*X211853D01* +X213354Y2043500D02*Y2037500D01* +Y2039750D02*X214104Y2040500D01* +X215604D01* +X216354Y2039750D01* +Y2037500D01* +X218156Y2039750D02*Y2038250D01* +Y2039750D02*X218906Y2040500D01* +X220406D01* +X221156Y2039750D01* +Y2038250D01* +X220406Y2037500D02*X221156Y2038250D01* +X218906Y2037500D02*X220406D01* +X218156Y2038250D02*X218906Y2037500D01* +X223707Y2039750D02*Y2037500D01* +Y2039750D02*X224457Y2040500D01* +X225957D01* +X222957D02*X223707Y2039750D01* +X227759Y2041250D02*X228509D01* +X227759Y2039750D02*X228509D01* +X233010Y2043500D02*Y2037500D01* +Y2043500D02*X236010D01* +X233010Y2040500D02*X235260D01* +X240062D02*X240812Y2039750D01* +X238562Y2040500D02*X240062D01* +X237812Y2039750D02*X238562Y2040500D01* +X237812Y2039750D02*Y2038250D01* +X238562Y2037500D01* +X240812Y2040500D02*Y2038250D01* +X241562Y2037500D01* +X238562D02*X240062D01* +X240812Y2038250D01* +X243363Y2043500D02*Y2037500D01* +Y2038250D02*X244113Y2037500D01* +X245613D01* +X246363Y2038250D01* +Y2039750D02*Y2038250D01* +X245613Y2040500D02*X246363Y2039750D01* +X244113Y2040500D02*X245613D01* +X243363Y2039750D02*X244113Y2040500D01* +X248165Y2037500D02*X251165D01* +X252966Y2042750D02*Y2037500D01* +Y2042750D02*X253716Y2043500D01* +X255966D01* +X256716Y2042750D01* +Y2037500D01* +X252966Y2040500D02*X256716D01* +X258518D02*Y2038250D01* +X259268Y2037500D01* +X260768D01* +X261518Y2038250D01* +Y2040500D02*Y2038250D01* +X264069Y2043500D02*Y2038250D01* +X264819Y2037500D01* +X263319Y2041250D02*X264819D01* +X266321Y2043500D02*Y2037500D01* +Y2039750D02*X267071Y2040500D01* +X268571D01* +X269321Y2039750D01* +Y2037500D01* +X271122Y2039750D02*Y2038250D01* +Y2039750D02*X271872Y2040500D01* +X273372D01* +X274122Y2039750D01* +Y2038250D01* +X273372Y2037500D02*X274122Y2038250D01* +X271872Y2037500D02*X273372D01* +X271122Y2038250D02*X271872Y2037500D01* +X276674Y2039750D02*Y2037500D01* +Y2039750D02*X277424Y2040500D01* +X278924D01* +X275924D02*X276674Y2039750D01* +X200000Y2058500D02*X203000D01* +X201500D02*Y2052500D01* +X204801Y2057000D02*Y2056250D01* +Y2054750D02*Y2052500D01* +X207053Y2058500D02*Y2053250D01* +X207803Y2052500D01* +X206303Y2056250D02*X207803D01* +X209304Y2058500D02*Y2053250D01* +X210054Y2052500D01* +X212306D02*X214556D01* +X211556Y2053250D02*X212306Y2052500D01* +X211556Y2054750D02*Y2053250D01* +Y2054750D02*X212306Y2055500D01* +X213806D01* +X214556Y2054750D01* +X211556Y2054000D02*X214556D01* +Y2054750D02*Y2054000D01* +X216357Y2056250D02*X217107D01* +X216357Y2054750D02*X217107D01* +X221609Y2053250D02*X222359Y2052500D01* +X221609Y2057750D02*X222359Y2058500D01* +X221609Y2057750D02*Y2053250D01* +X224160Y2055500D02*Y2053250D01* +X224910Y2052500D01* +X226410D01* +X227160Y2053250D01* +Y2055500D02*Y2053250D01* +X229712Y2054750D02*Y2052500D01* +Y2054750D02*X230462Y2055500D01* +X231212D01* +X231962Y2054750D01* +Y2052500D01* +X228962Y2055500D02*X229712Y2054750D01* +X233763Y2058500D02*Y2052500D01* +Y2054750D02*X236013Y2052500D01* +X233763Y2054750D02*X235263Y2056250D01* +X238565Y2054750D02*Y2052500D01* +Y2054750D02*X239315Y2055500D01* +X240065D01* +X240815Y2054750D01* +Y2052500D01* +X237815Y2055500D02*X238565Y2054750D01* +X242616D02*Y2053250D01* +Y2054750D02*X243366Y2055500D01* +X244866D01* +X245616Y2054750D01* +Y2053250D01* +X244866Y2052500D02*X245616Y2053250D01* +X243366Y2052500D02*X244866D01* +X242616Y2053250D02*X243366Y2052500D01* +X247418Y2055500D02*Y2053250D01* +X248168Y2052500D01* +X248918D01* +X249668Y2053250D01* +Y2055500D02*Y2053250D01* +X250418Y2052500D01* +X251168D01* +X251918Y2053250D01* +Y2055500D02*Y2053250D01* +X254469Y2054750D02*Y2052500D01* +Y2054750D02*X255219Y2055500D01* +X255969D01* +X256719Y2054750D01* +Y2052500D01* +X253719Y2055500D02*X254469Y2054750D01* +X258521Y2058500D02*X259271Y2057750D01* +Y2053250D01* +X258521Y2052500D02*X259271Y2053250D01* +X263772Y2055500D02*X266772D01* +X271274Y2058500D02*Y2052500D01* +Y2058500D02*X274274D01* +X271274Y2055500D02*X273524D01* +X278325D02*X279075Y2054750D01* +X276825Y2055500D02*X278325D01* +X276075Y2054750D02*X276825Y2055500D01* +X276075Y2054750D02*Y2053250D01* +X276825Y2052500D01* +X279075Y2055500D02*Y2053250D01* +X279825Y2052500D01* +X276825D02*X278325D01* +X279075Y2053250D01* +X281627Y2058500D02*Y2052500D01* +Y2053250D02*X282377Y2052500D01* +X283877D01* +X284627Y2053250D01* +Y2054750D02*Y2053250D01* +X283877Y2055500D02*X284627Y2054750D01* +X282377Y2055500D02*X283877D01* +X281627Y2054750D02*X282377Y2055500D01* +X287178Y2054750D02*Y2052500D01* +Y2054750D02*X287928Y2055500D01* +X289428D01* +X286428D02*X287178Y2054750D01* +X291230Y2057000D02*Y2056250D01* +Y2054750D02*Y2052500D01* +X293481Y2055500D02*X295731D01* +X292731Y2054750D02*X293481Y2055500D01* +X292731Y2054750D02*Y2053250D01* +X293481Y2052500D01* +X295731D01* +X299783Y2055500D02*X300533Y2054750D01* +X298283Y2055500D02*X299783D01* +X297533Y2054750D02*X298283Y2055500D01* +X297533Y2054750D02*Y2053250D01* +X298283Y2052500D01* +X300533Y2055500D02*Y2053250D01* +X301283Y2052500D01* +X298283D02*X299783D01* +X300533Y2053250D01* +X303834Y2058500D02*Y2053250D01* +X304584Y2052500D01* +X303084Y2056250D02*X304584D01* +X306086Y2057000D02*Y2056250D01* +Y2054750D02*Y2052500D01* +X307587Y2054750D02*Y2053250D01* +Y2054750D02*X308337Y2055500D01* +X309837D01* +X310587Y2054750D01* +Y2053250D01* +X309837Y2052500D02*X310587Y2053250D01* +X308337Y2052500D02*X309837D01* +X307587Y2053250D02*X308337Y2052500D01* +X313139Y2054750D02*Y2052500D01* +Y2054750D02*X313889Y2055500D01* +X314639D01* +X315389Y2054750D01* +Y2052500D01* +X312389Y2055500D02*X313139Y2054750D01* +X320640Y2058500D02*Y2052500D01* +X322890Y2058500D02*X323640Y2057750D01* +Y2053250D01* +X322890Y2052500D02*X323640Y2053250D01* +X319890Y2052500D02*X322890D01* +X319890Y2058500D02*X322890D01* +X326192Y2054750D02*Y2052500D01* +Y2054750D02*X326942Y2055500D01* +X328442D01* +X325442D02*X326192Y2054750D01* +X332493Y2055500D02*X333243Y2054750D01* +X330993Y2055500D02*X332493D01* +X330243Y2054750D02*X330993Y2055500D01* +X330243Y2054750D02*Y2053250D01* +X330993Y2052500D01* +X333243Y2055500D02*Y2053250D01* +X333993Y2052500D01* +X330993D02*X332493D01* +X333243Y2053250D01* +X335795Y2055500D02*Y2053250D01* +X336545Y2052500D01* +X337295D01* +X338045Y2053250D01* +Y2055500D02*Y2053250D01* +X338795Y2052500D01* +X339545D01* +X340295Y2053250D01* +Y2055500D02*Y2053250D01* +X342096Y2057000D02*Y2056250D01* +Y2054750D02*Y2052500D01* +X344348Y2054750D02*Y2052500D01* +Y2054750D02*X345098Y2055500D01* +X345848D01* +X346598Y2054750D01* +Y2052500D01* +X343598Y2055500D02*X344348Y2054750D01* +X350649Y2055500D02*X351399Y2054750D01* +X349149Y2055500D02*X350649D01* +X348399Y2054750D02*X349149Y2055500D01* +X348399Y2054750D02*Y2053250D01* +X349149Y2052500D01* +X350649D01* +X351399Y2053250D01* +X348399Y2051000D02*X349149Y2050250D01* +X350649D01* +X351399Y2051000D01* +Y2055500D02*Y2051000D01* +M02* Index: tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.group11.gbr =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.group11.gbr (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.group11.gbr (revision 33253) @@ -0,0 +1,48 @@ +G04 start of page 4 for group 4 idx 4 * +G04 Title: (unknown), power * +G04 Creator: pcb 1.99z * +G04 CreationDate: Fri Jun 17 03:18:51 2011 UTC * +G04 For: apoelstra * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 3000000 2000000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGROUP4*% +%ADD27C,0.5000*% +%ADD26C,1.0000*% +%ADD25C,0.6500*% +%ADD24C,0.7500*% +%ADD23C,0.2500*% +G54D23*X1300000Y630000D02*X1302367Y604884D01* +X1309462Y579867D01* +X1321255Y555048D01* +X1337700Y530525D01* +X1358732Y506394D01* +X1384268Y482751D01* +X1414207Y459689D01* +X1448431Y437299D01* +X1486806Y415670D01* +X1529179Y394886D01* +X1575384Y375031D01* +X1625237Y356182D01* +X1678543Y338413D01* +X1735091Y321795D01* +X1794657Y306394D01* +X1857007Y292269D01* +X1921895Y279478D01* +X1989064Y268070D01* +X2058250Y258090D01* +X2129179Y249578D01* +X2201572Y242567D01* +X2275142Y237086D01* +X2349600Y233155D01* +X2424651Y230790D01* +X2499999Y230000D01* +G54D24*X600000Y450000D03* +G54D25*Y290000D03* +G54D26*X450000Y600000D03* +X600000D03* +G54D25*X450000Y290000D03* +G54D24*Y450000D03* +G54D27*G54D23*G54D27*G54D23*G54D27*M02* Index: tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.group5.gbr =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.group5.gbr (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.group5.gbr (revision 33253) @@ -0,0 +1,28 @@ +G04 start of page 3 for group 1 idx 1 * +G04 Title: (unknown), ground * +G04 Creator: pcb 1.99z * +G04 CreationDate: Fri Jun 17 03:18:51 2011 UTC * +G04 For: apoelstra * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 3000000 2000000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNGROUP1*% +%ADD22C,0.6500*% +%ADD21C,0.7500*% +%ADD20C,1.0000*% +%ADD19C,0.5000*% +%ADD18C,0.2500*% +%ADD17C,0.1000*% +G54D17*X1497000Y1791000D02*G75*G03X2430000Y858000I933000J0D01*G01* +G54D18*X1861000Y1776000D02*G75*G02X2415000Y1222000I0J-554000D01*G01* +G54D19*X1845000Y1608000D02*G75*G02X2203000Y1250000I0J-358000D01*G01* +G54D20*X1845000Y1455000D02*G75*G02X2029000Y1271000I0J-184000D01*G01* +G54D21*X600000Y450000D03* +G54D22*Y290000D03* +G54D20*X450000Y600000D03* +X600000D03* +G54D22*X450000Y290000D03* +G54D21*Y450000D03* +G54D19*G54D18*G54D19*G54D18*G54D19*M02* Index: tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.plated-drill.cnc =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.plated-drill.cnc (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.plated-drill.cnc (revision 33253) @@ -0,0 +1,14 @@ +M48 +INCH +T37C0.250 +T36C0.500 +% +T37 +X060000Y029000 +X045000Y029000 +T36 +X060000Y045000 +X045000Y060000 +X060000Y060000 +X045000Y045000 +M30 Index: tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.top.gbr =================================================================== --- tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.top.gbr (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_gerber3/arcs.top.gbr (revision 33253) @@ -0,0 +1,28 @@ +G04 start of page 2 for group 0 idx 0 * +G04 Title: (unknown), top * +G04 Creator: pcb 1.99z * +G04 CreationDate: Fri Jun 17 03:18:51 2011 UTC * +G04 For: apoelstra * +G04 Format: Gerber/RS-274X * +G04 PCB-Dimensions: 3000000 2000000 * +G04 PCB-Coordinate-Origin: lower left * +%MOIN*% +%FSLAX25Y25*% +%LNTOP*% +%ADD16C,0.2500*% +%ADD15C,0.5000*% +%ADD14C,1.0000*% +%ADD13C,0.6500*% +%ADD12C,0.7500*% +%ADD11C,0.0100*% +G54D11*X1266000Y1791000D02*G75*G02X775000Y1300000I-491000J0D01*G01* +X772000Y1303000D02*G75*G03X286000Y817000I0J-486000D01*G01* +X285999D02*G75*G03X772000Y1303000I0J486000D01*G01* +X775000Y1300000D02*G75*G02X1266000Y1791000I491000J0D01*G01* +G54D12*X600000Y450000D03* +G54D13*Y290000D03* +G54D14*X450000Y600000D03* +X600000D03* +G54D13*X450000Y290000D03* +G54D12*Y450000D03* +G54D15*G54D16*G54D15*G54D16*G54D15*M02* Index: tags/2.3.0/tests/orig/golden/hid_png1/gerber_oneline.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/orig/golden/hid_png1/gerber_oneline.png =================================================================== --- tags/2.3.0/tests/orig/golden/hid_png1/gerber_oneline.png (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_png1/gerber_oneline.png (revision 33253) Property changes on: tags/2.3.0/tests/orig/golden/hid_png1/gerber_oneline.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/orig/golden/hid_png2/myfile.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/orig/golden/hid_png2/myfile.png =================================================================== --- tags/2.3.0/tests/orig/golden/hid_png2/myfile.png (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_png2/myfile.png (revision 33253) Property changes on: tags/2.3.0/tests/orig/golden/hid_png2/myfile.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/orig/golden/hid_png3/gerber_oneline.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: tags/2.3.0/tests/orig/golden/hid_png3/gerber_oneline.png =================================================================== --- tags/2.3.0/tests/orig/golden/hid_png3/gerber_oneline.png (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_png3/gerber_oneline.png (revision 33253) Property changes on: tags/2.3.0/tests/orig/golden/hid_png3/gerber_oneline.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: tags/2.3.0/tests/orig/golden/hid_xy1/bom_general.xy =================================================================== --- tags/2.3.0/tests/orig/golden/hid_xy1/bom_general.xy (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_xy1/bom_general.xy (revision 33253) @@ -0,0 +1,32 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: Wed Jun 24 21:42:21 2009 UTC +# Author: Dan McMahill +# Title: Basic BOM/XY Test - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mils. rotation in degrees. +# -------------------------------------------- +R90_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",1700.00,4300.00,90,top +R180_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",1300.00,4300.00,180,top +R270_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",1000.00,4300.00,270,top +R0_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",600.00,4300.00,0,top +UDIP90_TOP,"Dual in-line package, narrow (300 mil)","DIP8",2650.00,1450.00,180,top +UDIP180_TOP,"Dual in-line package, narrow (300 mil)","DIP8",1950.00,1450.00,270,top +UDIP270_TOP,"Dual in-line package, narrow (300 mil)","DIP8",1250.00,1450.00,0,top +UDIP0_TOP,"Dual in-line package, narrow (300 mil)","DIP8",550.00,1450.00,90,top +USO90_TOP,"Small outline package, narrow (150mil)","SO8",1700.00,3200.00,180,top +USO180_TOP,"Small outline package, narrow (150mil)","SO8",1300.00,3200.00,270,top +USO270_TOP,"Small outline package, narrow (150mil)","SO8",1000.00,3200.00,0,top +USO0_TOP,"Small outline package, narrow (150mil)","SO8",600.00,3200.00,90,top +UDIP270_BOT,"Dual in-line package, narrow (300 mil)","DIP8",2650.00,650.00,270,bottom +UDIP180_BOT,"Dual in-line package, narrow (300 mil)","DIP8",1950.00,650.00,180,bottom +UDIP90_BOT,"Dual in-line package, narrow (300 mil)","DIP8",1250.00,650.00,90,bottom +UDIP0_BOT,"Dual in-line package, narrow (300 mil)","DIP8",550.00,650.00,0,bottom +USO270_BOT,"Small outline package, narrow (150mil)","SO8",1700.00,2600.00,270,bottom +USO180_BOT,"Small outline package, narrow (150mil)","SO8",1300.00,2600.00,180,bottom +USO90_BOT,"Small outline package, narrow (150mil)","SO8",1000.00,2600.00,90,bottom +USO0_BOT,"Small outline package, narrow (150mil)","SO8",600.00,2600.00,0,bottom +R270_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",1700.00,3900.00,270,bottom +R180_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",1300.00,3900.00,180,bottom +R90_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",1000.00,3900.00,90,bottom +R0_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",600.00,3900.00,0,bottom Index: tags/2.3.0/tests/orig/golden/hid_xy2/bom_general.xy =================================================================== --- tags/2.3.0/tests/orig/golden/hid_xy2/bom_general.xy (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_xy2/bom_general.xy (revision 33253) @@ -0,0 +1,32 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: Wed Jun 24 21:42:22 2009 UTC +# Author: Dan McMahill +# Title: Basic BOM/XY Test - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mils. rotation in degrees. +# -------------------------------------------- +R90_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",1700.00,4300.00,90,top +R180_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",1300.00,4300.00,180,top +R270_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",1000.00,4300.00,270,top +R0_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",600.00,4300.00,0,top +UDIP90_TOP,"Dual in-line package, narrow (300 mil)","DIP8",2650.00,1450.00,180,top +UDIP180_TOP,"Dual in-line package, narrow (300 mil)","DIP8",1950.00,1450.00,270,top +UDIP270_TOP,"Dual in-line package, narrow (300 mil)","DIP8",1250.00,1450.00,0,top +UDIP0_TOP,"Dual in-line package, narrow (300 mil)","DIP8",550.00,1450.00,90,top +USO90_TOP,"Small outline package, narrow (150mil)","SO8",1700.00,3200.00,180,top +USO180_TOP,"Small outline package, narrow (150mil)","SO8",1300.00,3200.00,270,top +USO270_TOP,"Small outline package, narrow (150mil)","SO8",1000.00,3200.00,0,top +USO0_TOP,"Small outline package, narrow (150mil)","SO8",600.00,3200.00,90,top +UDIP270_BOT,"Dual in-line package, narrow (300 mil)","DIP8",2650.00,650.00,270,bottom +UDIP180_BOT,"Dual in-line package, narrow (300 mil)","DIP8",1950.00,650.00,180,bottom +UDIP90_BOT,"Dual in-line package, narrow (300 mil)","DIP8",1250.00,650.00,90,bottom +UDIP0_BOT,"Dual in-line package, narrow (300 mil)","DIP8",550.00,650.00,0,bottom +USO270_BOT,"Small outline package, narrow (150mil)","SO8",1700.00,2600.00,270,bottom +USO180_BOT,"Small outline package, narrow (150mil)","SO8",1300.00,2600.00,180,bottom +USO90_BOT,"Small outline package, narrow (150mil)","SO8",1000.00,2600.00,90,bottom +USO0_BOT,"Small outline package, narrow (150mil)","SO8",600.00,2600.00,0,bottom +R270_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",1700.00,3900.00,270,bottom +R180_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",1300.00,3900.00,180,bottom +R90_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",1000.00,3900.00,90,bottom +R0_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",600.00,3900.00,0,bottom Index: tags/2.3.0/tests/orig/golden/hid_xy3/test.xy =================================================================== --- tags/2.3.0/tests/orig/golden/hid_xy3/test.xy (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_xy3/test.xy (revision 33253) @@ -0,0 +1,32 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: Wed Jun 24 21:42:22 2009 UTC +# Author: Dan McMahill +# Title: Basic BOM/XY Test - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mils. rotation in degrees. +# -------------------------------------------- +R90_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",1700.00,4300.00,90,top +R180_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",1300.00,4300.00,180,top +R270_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",1000.00,4300.00,270,top +R0_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",600.00,4300.00,0,top +UDIP90_TOP,"Dual in-line package, narrow (300 mil)","DIP8",2650.00,1450.00,180,top +UDIP180_TOP,"Dual in-line package, narrow (300 mil)","DIP8",1950.00,1450.00,270,top +UDIP270_TOP,"Dual in-line package, narrow (300 mil)","DIP8",1250.00,1450.00,0,top +UDIP0_TOP,"Dual in-line package, narrow (300 mil)","DIP8",550.00,1450.00,90,top +USO90_TOP,"Small outline package, narrow (150mil)","SO8",1700.00,3200.00,180,top +USO180_TOP,"Small outline package, narrow (150mil)","SO8",1300.00,3200.00,270,top +USO270_TOP,"Small outline package, narrow (150mil)","SO8",1000.00,3200.00,0,top +USO0_TOP,"Small outline package, narrow (150mil)","SO8",600.00,3200.00,90,top +UDIP270_BOT,"Dual in-line package, narrow (300 mil)","DIP8",2650.00,650.00,270,bottom +UDIP180_BOT,"Dual in-line package, narrow (300 mil)","DIP8",1950.00,650.00,180,bottom +UDIP90_BOT,"Dual in-line package, narrow (300 mil)","DIP8",1250.00,650.00,90,bottom +UDIP0_BOT,"Dual in-line package, narrow (300 mil)","DIP8",550.00,650.00,0,bottom +USO270_BOT,"Small outline package, narrow (150mil)","SO8",1700.00,2600.00,270,bottom +USO180_BOT,"Small outline package, narrow (150mil)","SO8",1300.00,2600.00,180,bottom +USO90_BOT,"Small outline package, narrow (150mil)","SO8",1000.00,2600.00,90,bottom +USO0_BOT,"Small outline package, narrow (150mil)","SO8",600.00,2600.00,0,bottom +R270_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",1700.00,3900.00,270,bottom +R180_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",1300.00,3900.00,180,bottom +R90_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",1000.00,3900.00,90,bottom +R0_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",600.00,3900.00,0,bottom Index: tags/2.3.0/tests/orig/golden/hid_xy4/bom_general.xy =================================================================== --- tags/2.3.0/tests/orig/golden/hid_xy4/bom_general.xy (nonexistent) +++ tags/2.3.0/tests/orig/golden/hid_xy4/bom_general.xy (revision 33253) @@ -0,0 +1,32 @@ +# $Id$ +# PcbXY Version 1.0 +# Date: Wed Jun 24 21:42:23 2009 UTC +# Author: Dan McMahill +# Title: Basic BOM/XY Test - PCB X-Y +# RefDes, Description, Value, X, Y, rotation, top/bottom +# X,Y in mm. rotation in degrees. +# -------------------------------------------- +R90_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",43.18,109.22,90,top +R180_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",33.02,109.22,180,top +R270_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",25.40,109.22,270,top +R0_TOP,"Standard SMT resistor, capacitor etc","RESC3216N",15.24,109.22,0,top +UDIP90_TOP,"Dual in-line package, narrow (300 mil)","DIP8",67.31,36.83,180,top +UDIP180_TOP,"Dual in-line package, narrow (300 mil)","DIP8",49.53,36.83,270,top +UDIP270_TOP,"Dual in-line package, narrow (300 mil)","DIP8",31.75,36.83,0,top +UDIP0_TOP,"Dual in-line package, narrow (300 mil)","DIP8",13.97,36.83,90,top +USO90_TOP,"Small outline package, narrow (150mil)","SO8",43.18,81.28,180,top +USO180_TOP,"Small outline package, narrow (150mil)","SO8",33.02,81.28,270,top +USO270_TOP,"Small outline package, narrow (150mil)","SO8",25.40,81.28,0,top +USO0_TOP,"Small outline package, narrow (150mil)","SO8",15.24,81.28,90,top +UDIP270_BOT,"Dual in-line package, narrow (300 mil)","DIP8",67.31,16.51,270,bottom +UDIP180_BOT,"Dual in-line package, narrow (300 mil)","DIP8",49.53,16.51,180,bottom +UDIP90_BOT,"Dual in-line package, narrow (300 mil)","DIP8",31.75,16.51,90,bottom +UDIP0_BOT,"Dual in-line package, narrow (300 mil)","DIP8",13.97,16.51,0,bottom +USO270_BOT,"Small outline package, narrow (150mil)","SO8",43.18,66.04,270,bottom +USO180_BOT,"Small outline package, narrow (150mil)","SO8",33.02,66.04,180,bottom +USO90_BOT,"Small outline package, narrow (150mil)","SO8",25.40,66.04,90,bottom +USO0_BOT,"Small outline package, narrow (150mil)","SO8",15.24,66.04,0,bottom +R270_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",43.18,99.06,270,bottom +R180_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",33.02,99.06,180,bottom +R90_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",25.40,99.06,90,bottom +R0_BOT,"Standard SMT resistor, capacitor etc","RESC3216N",15.24,99.06,0,bottom Index: tags/2.3.0/tests/orig/inputs/bom_general.pcb =================================================================== --- tags/2.3.0/tests/orig/inputs/bom_general.pcb (nonexistent) +++ tags/2.3.0/tests/orig/inputs/bom_general.pcb (revision 33253) @@ -0,0 +1,1211 @@ +# release: pcb 1.99y + +# To read pcb files, the pcb version (or the cvs source date) must be >= the file version +FileVersion[20070407] + +PCB["Basic BOM/XY Test" 600000 500000] + +Grid[10000.000000 0 0 1] +Cursor[0 500000 0.000000] +PolyArea[200000000.000000] +Thermal[0.500000] +DRC[1000 1000 1000 1000 1500 1000] +Flags("nameonpcb,uniquename,clearnew,snappin") +Groups("1,c:2,s:3:4:5:6:7:8") +Styles["Signal,1000,3600,2000,1000:Power,2500,6000,3500,1000:Fat,4000,6000,3500,1000:Skinny,600,2402,1181,600"] + +Symbol(' ' 18) +( +) +Symbol('!' 12) +( + SymbolLine(0 45 0 50 8) + SymbolLine(0 10 0 35 8) +) +Symbol('"' 12) +( + SymbolLine(0 10 0 20 8) + SymbolLine(10 10 10 20 8) +) +Symbol('#' 12) +( + SymbolLine(0 35 20 35 8) + SymbolLine(0 25 20 25 8) + SymbolLine(15 20 15 40 8) + SymbolLine(5 20 5 40 8) +) +Symbol('$' 12) +( + SymbolLine(15 15 20 20 8) + SymbolLine(5 15 15 15 8) + SymbolLine(0 20 5 15 8) + SymbolLine(0 20 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 40 8) + SymbolLine(15 45 20 40 8) + SymbolLine(5 45 15 45 8) + SymbolLine(0 40 5 45 8) + SymbolLine(10 10 10 50 8) +) +Symbol('%' 12) +( + SymbolLine(0 15 0 20 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 10 10 8) + SymbolLine(10 10 15 15 8) + SymbolLine(15 15 15 20 8) + SymbolLine(10 25 15 20 8) + SymbolLine(5 25 10 25 8) + SymbolLine(0 20 5 25 8) + SymbolLine(0 50 40 10 8) + SymbolLine(35 50 40 45 8) + SymbolLine(40 40 40 45 8) + SymbolLine(35 35 40 40 8) + SymbolLine(30 35 35 35 8) + SymbolLine(25 40 30 35 8) + SymbolLine(25 40 25 45 8) + SymbolLine(25 45 30 50 8) + SymbolLine(30 50 35 50 8) +) +Symbol('&' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 35 15 20 8) + SymbolLine(5 50 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(0 25 25 50 8) + SymbolLine(5 10 10 10 8) + SymbolLine(10 10 15 15 8) + SymbolLine(15 15 15 20 8) + SymbolLine(0 35 0 45 8) +) +Symbol(''' 12) +( + SymbolLine(0 20 10 10 8) +) +Symbol('(' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) +) +Symbol(')' 12) +( + SymbolLine(0 10 5 15 8) + SymbolLine(5 15 5 45 8) + SymbolLine(0 50 5 45 8) +) +Symbol('*' 12) +( + SymbolLine(0 20 20 40 8) + SymbolLine(0 40 20 20 8) + SymbolLine(0 30 20 30 8) + SymbolLine(10 20 10 40 8) +) +Symbol('+' 12) +( + SymbolLine(0 30 20 30 8) + SymbolLine(10 20 10 40 8) +) +Symbol(',' 12) +( + SymbolLine(0 60 10 50 8) +) +Symbol('-' 12) +( + SymbolLine(0 30 20 30 8) +) +Symbol('.' 12) +( + SymbolLine(0 50 5 50 8) +) +Symbol('/' 12) +( + SymbolLine(0 45 30 15 8) +) +Symbol('0' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 40 20 20 8) +) +Symbol('1' 12) +( + SymbolLine(5 50 15 50 8) + SymbolLine(10 10 10 50 8) + SymbolLine(0 20 10 10 8) +) +Symbol('2' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(0 50 25 25 8) + SymbolLine(0 50 25 50 8) +) +Symbol('3' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 30 20 30 8) +) +Symbol('4' 12) +( + SymbolLine(0 30 20 10 8) + SymbolLine(0 30 25 30 8) + SymbolLine(20 10 20 50 8) +) +Symbol('5' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(0 10 0 30 8) + SymbolLine(0 30 5 25 8) + SymbolLine(5 25 15 25 8) + SymbolLine(15 25 20 30 8) + SymbolLine(20 30 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('6' 12) +( + SymbolLine(15 10 20 15 8) + SymbolLine(5 10 15 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(15 30 20 35 8) + SymbolLine(0 30 15 30 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 35 20 45 8) +) +Symbol('7' 12) +( + SymbolLine(0 50 25 25 8) + SymbolLine(25 10 25 25 8) + SymbolLine(0 10 25 10 8) +) +Symbol('8' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 25 5 30 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 25 8) + SymbolLine(15 30 20 25 8) +) +Symbol('9' 12) +( + SymbolLine(0 50 20 30 8) + SymbolLine(20 15 20 30 8) + SymbolLine(15 10 20 15 8) + SymbolLine(5 10 15 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 20 30 8) +) +Symbol(':' 12) +( + SymbolLine(0 25 5 25 8) + SymbolLine(0 35 5 35 8) +) +Symbol(';' 12) +( + SymbolLine(0 50 10 40 8) + SymbolLine(10 25 10 30 8) +) +Symbol('<' 12) +( + SymbolLine(0 30 10 20 8) + SymbolLine(0 30 10 40 8) +) +Symbol('=' 12) +( + SymbolLine(0 25 20 25 8) + SymbolLine(0 35 20 35 8) +) +Symbol('>' 12) +( + SymbolLine(0 20 10 30 8) + SymbolLine(0 40 10 30 8) +) +Symbol('?' 12) +( + SymbolLine(10 30 10 35 8) + SymbolLine(10 45 10 50 8) + SymbolLine(0 15 0 20 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 20 8) + SymbolLine(10 30 20 20 8) +) +Symbol('@' 12) +( + SymbolLine(0 10 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 40 50 8) + SymbolLine(50 35 50 10 8) + SymbolLine(50 10 40 0 8) + SymbolLine(40 0 10 0 8) + SymbolLine(10 0 0 10 8) + SymbolLine(15 20 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 30 35 8) + SymbolLine(30 35 35 30 8) + SymbolLine(35 30 40 35 8) + SymbolLine(35 30 35 15 8) + SymbolLine(35 20 30 15 8) + SymbolLine(20 15 30 15 8) + SymbolLine(20 15 15 20 8) + SymbolLine(40 35 50 35 8) +) +Symbol('A' 12) +( + SymbolLine(0 15 0 50 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 50 8) + SymbolLine(0 30 25 30 8) +) +Symbol('B' 12) +( + SymbolLine(0 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 30 25 35 8) + SymbolLine(5 30 20 30 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) +) +Symbol('C' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) +) +Symbol('D' 12) +( + SymbolLine(5 10 5 50 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(0 50 20 50 8) + SymbolLine(0 10 20 10 8) +) +Symbol('E' 12) +( + SymbolLine(0 30 15 30 8) + SymbolLine(0 50 20 50 8) + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 20 10 8) +) +Symbol('F' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(0 30 15 30 8) +) +Symbol('G' 12) +( + SymbolLine(20 10 25 15 8) + SymbolLine(5 10 20 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 30 25 35 8) + SymbolLine(10 30 20 30 8) +) +Symbol('H' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(25 10 25 50 8) + SymbolLine(0 30 25 30 8) +) +Symbol('I' 12) +( + SymbolLine(0 10 10 10 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 50 10 50 8) +) +Symbol('J' 12) +( + SymbolLine(0 10 15 10 8) + SymbolLine(15 10 15 45 8) + SymbolLine(10 50 15 45 8) + SymbolLine(5 50 10 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('K' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 30 20 10 8) + SymbolLine(0 30 20 50 8) +) +Symbol('L' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 20 50 8) +) +Symbol('M' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 15 25 8) + SymbolLine(15 25 30 10 8) + SymbolLine(30 10 30 50 8) +) +Symbol('N' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 25 40 8) + SymbolLine(25 10 25 50 8) +) +Symbol('O' 12) +( + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('P' 12) +( + SymbolLine(5 10 5 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) + SymbolLine(5 30 20 30 8) +) +Symbol('Q' 12) +( + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(10 40 20 50 8) +) +Symbol('R' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) + SymbolLine(5 30 20 30 8) + SymbolLine(5 10 5 50 8) + SymbolLine(5 30 25 50 8) +) +Symbol('S' 12) +( + SymbolLine(20 10 25 15 8) + SymbolLine(5 10 20 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('T' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(10 10 10 50 8) +) +Symbol('U' 12) +( + SymbolLine(0 10 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 10 20 45 8) +) +Symbol('V' 12) +( + SymbolLine(0 10 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(20 10 20 40 8) +) +Symbol('W' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 15 35 8) + SymbolLine(15 35 30 50 8) + SymbolLine(30 10 30 50 8) +) +Symbol('X' 12) +( + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 25 40 8) + SymbolLine(25 40 25 50 8) + SymbolLine(0 40 0 50 8) + SymbolLine(0 40 25 15 8) + SymbolLine(25 10 25 15 8) +) +Symbol('Y' 12) +( + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 10 25 8) + SymbolLine(10 25 20 15 8) + SymbolLine(20 10 20 15 8) + SymbolLine(10 25 10 50 8) +) +Symbol('Z' 12) +( + SymbolLine(0 10 25 10 8) + SymbolLine(25 10 25 15 8) + SymbolLine(0 40 25 15 8) + SymbolLine(0 40 0 50 8) + SymbolLine(0 50 25 50 8) +) +Symbol('[' 12) +( + SymbolLine(0 10 5 10 8) + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 5 50 8) +) +Symbol('\' 12) +( + SymbolLine(0 15 30 45 8) +) +Symbol(']' 12) +( + SymbolLine(0 10 5 10 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 50 5 50 8) +) +Symbol('^' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 10 15 8) +) +Symbol('_' 12) +( + SymbolLine(0 50 20 50 8) +) +Symbol('a' 12) +( + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(20 30 20 45 8) + SymbolLine(20 45 25 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('b' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) +) +Symbol('c' 12) +( + SymbolLine(5 30 20 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 20 50 8) +) +Symbol('d' 12) +( + SymbolLine(20 10 20 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) +) +Symbol('e' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(0 40 20 40 8) + SymbolLine(20 40 20 35 8) +) +Symbol('f' 10) +( + SymbolLine(5 15 5 50 8) + SymbolLine(5 15 10 10 8) + SymbolLine(10 10 15 10 8) + SymbolLine(0 30 10 30 8) +) +Symbol('g' 12) +( + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(0 60 5 65 8) + SymbolLine(5 65 15 65 8) + SymbolLine(15 65 20 60 8) + SymbolLine(20 30 20 60 8) +) +Symbol('h' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) +) +Symbol('i' 10) +( + SymbolLine(0 20 0 25 8) + SymbolLine(0 35 0 50 8) +) +Symbol('j' 10) +( + SymbolLine(5 20 5 25 8) + SymbolLine(5 35 5 60 8) + SymbolLine(0 65 5 60 8) +) +Symbol('k' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 35 15 50 8) + SymbolLine(0 35 10 25 8) +) +Symbol('l' 10) +( + SymbolLine(0 10 0 45 8) + SymbolLine(0 45 5 50 8) +) +Symbol('m' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) + SymbolLine(20 35 25 30 8) + SymbolLine(25 30 30 30 8) + SymbolLine(30 30 35 35 8) + SymbolLine(35 35 35 50 8) + SymbolLine(0 30 5 35 8) +) +Symbol('n' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) + SymbolLine(0 30 5 35 8) +) +Symbol('o' 12) +( + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('p' 12) +( + SymbolLine(5 35 5 65 8) + SymbolLine(0 30 5 35 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(10 50 20 50 8) + SymbolLine(5 45 10 50 8) +) +Symbol('q' 12) +( + SymbolLine(20 35 20 65 8) + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('r' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 20 30 8) + SymbolLine(0 30 5 35 8) +) +Symbol('s' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(20 40 25 45 8) + SymbolLine(5 40 20 40 8) + SymbolLine(0 35 5 40 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(0 45 5 50 8) +) +Symbol('t' 10) +( + SymbolLine(5 10 5 45 8) + SymbolLine(5 45 10 50 8) + SymbolLine(0 25 10 25 8) +) +Symbol('u' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 30 20 45 8) +) +Symbol('v' 12) +( + SymbolLine(0 30 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(20 30 20 40 8) +) +Symbol('w' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 10 50 8) + SymbolLine(10 50 15 45 8) + SymbolLine(15 30 15 45 8) + SymbolLine(15 45 20 50 8) + SymbolLine(20 50 25 50 8) + SymbolLine(25 50 30 45 8) + SymbolLine(30 30 30 45 8) +) +Symbol('x' 12) +( + SymbolLine(0 30 20 50 8) + SymbolLine(0 50 20 30 8) +) +Symbol('y' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(20 30 20 60 8) + SymbolLine(15 65 20 60 8) + SymbolLine(5 65 15 65 8) + SymbolLine(0 60 5 65 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('z' 12) +( + SymbolLine(0 30 20 30 8) + SymbolLine(0 50 20 30 8) + SymbolLine(0 50 20 50 8) +) +Symbol('{' 12) +( + SymbolLine(5 15 10 10 8) + SymbolLine(5 15 5 25 8) + SymbolLine(0 30 5 25 8) + SymbolLine(0 30 5 35 8) + SymbolLine(5 35 5 45 8) + SymbolLine(5 45 10 50 8) +) +Symbol('|' 12) +( + SymbolLine(0 10 0 50 8) +) +Symbol('}' 12) +( + SymbolLine(0 10 5 15 8) + SymbolLine(5 15 5 25 8) + SymbolLine(5 25 10 30 8) + SymbolLine(5 35 10 30 8) + SymbolLine(5 35 5 45 8) + SymbolLine(0 50 5 45 8) +) +Symbol('~' 12) +( + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 10 30 8) + SymbolLine(10 30 15 35 8) + SymbolLine(15 35 20 35 8) + SymbolLine(20 35 25 30 8) +) + +Element["onsolder" "Standard SMT resistor, capacitor etc" "R0_BOT" "RESC3216N" 60000 110000 -13150 13150 0 100 "auto"] +( + Pad[-5905 -984 -5905 984 5118 2000 5718 "1" "1" "onsolder,square"] + Pad[5905 -984 5905 984 5118 2000 5718 "2" "2" "onsolder,square"] + ElementLine [-1968 -3543 1968 -3543 800] + ElementLine [-1968 3543 1968 3543 800] + + ) + +Element["onsolder" "Standard SMT resistor, capacitor etc" "R90_BOT" "RESC3216N" 100000 110000 -13150 -13150 1 100 "auto"] +( + Pad[-984 -5905 984 -5905 5118 2000 5718 "1" "1" "onsolder,square"] + Pad[-984 5905 984 5905 5118 2000 5718 "2" "2" "onsolder,square"] + ElementLine [3543 1968 3543 -1968 800] + ElementLine [-3543 1968 -3543 -1968 800] + + ) + +Element["onsolder" "Standard SMT resistor, capacitor etc" "R180_BOT" "RESC3216N" 130000 110000 13150 6850 2 100 "auto"] +( + Pad[5905 -984 5905 984 5118 2000 5718 "1" "1" "onsolder,square"] + Pad[-5905 -984 -5905 984 5118 2000 5718 "2" "2" "onsolder,square"] + ElementLine [-1968 3543 1968 3543 800] + ElementLine [-1968 -3543 1968 -3543 800] + + ) + +Element["onsolder" "Standard SMT resistor, capacitor etc" "R270_BOT" "RESC3216N" 170000 110000 -6850 13150 3 100 "auto"] +( + Pad[-984 5905 984 5905 5118 2000 5718 "1" "1" "onsolder,square"] + Pad[-984 -5905 984 -5905 5118 2000 5718 "2" "2" "onsolder,square"] + ElementLine [-3543 1968 -3543 -1968 800] + ElementLine [3543 1968 3543 -1968 800] + + ) + +Element["onsolder" "Small outline package, narrow (150mil)" "USO0_BOT" "SO8" 60000 240000 -17500 13500 0 100 "auto"] +( + Pad[-13500 7500 -7000 7500 2000 1000 3000 "1" "1" "onsolder,square"] + Pad[-13500 2500 -7000 2500 2000 1000 3000 "2" "2" "onsolder,square"] + Pad[-13500 -2500 -7000 -2500 2000 1000 3000 "3" "3" "onsolder,square"] + Pad[-13500 -7500 -7000 -7500 2000 1000 3000 "4" "4" "onsolder,square"] + Pad[7000 -7500 13500 -7500 2000 1000 3000 "5" "5" "onsolder,square,edge2"] + Pad[7000 -2500 13500 -2500 2000 1000 3000 "6" "6" "onsolder,square,edge2"] + Pad[7000 2500 13500 2500 2000 1000 3000 "7" "7" "onsolder,square,edge2"] + Pad[7000 7500 13500 7500 2000 1000 3000 "8" "8" "onsolder,square,edge2"] + ElementLine [15500 9500 2500 9500 1000] + ElementLine [-15500 9500 -2500 9500 1000] + ElementLine [15500 -9500 15500 9500 1000] + ElementLine [-15500 -9500 15500 -9500 1000] + ElementLine [-15500 9500 -15500 -9500 1000] + ElementArc [0 9500 2500 2500 180 180 1000] + + ) + +Element["onsolder" "Small outline package, narrow (150mil)" "USO90_BOT" "SO8" 100000 240000 -21500 -3000 1 100 "auto"] +( + Pad[-7500 -13500 -7500 -7000 2000 1000 3000 "1" "1" "onsolder,square"] + Pad[-2500 -13500 -2500 -7000 2000 1000 3000 "2" "2" "onsolder,square"] + Pad[2500 -13500 2500 -7000 2000 1000 3000 "3" "3" "onsolder,square"] + Pad[7500 -13500 7500 -7000 2000 1000 3000 "4" "4" "onsolder,square"] + Pad[7500 7000 7500 13500 2000 1000 3000 "5" "5" "onsolder,square,edge2"] + Pad[2500 7000 2500 13500 2000 1000 3000 "6" "6" "onsolder,square,edge2"] + Pad[-2500 7000 -2500 13500 2000 1000 3000 "7" "7" "onsolder,square,edge2"] + Pad[-7500 7000 -7500 13500 2000 1000 3000 "8" "8" "onsolder,square,edge2"] + ElementLine [-9500 15500 -9500 2500 1000] + ElementLine [-9500 -2500 -9500 -15500 1000] + ElementLine [-9500 15500 9500 15500 1000] + ElementLine [9500 15500 9500 -15500 1000] + ElementLine [-9500 -15500 9500 -15500 1000] + ElementArc [-9500 0 2500 2500 90 180 1000] + + ) + +Element["onsolder" "Small outline package, narrow (150mil)" "USO180_BOT" "SO8" 130000 240000 22000 -16000 2 100 "auto"] +( + Pad[7000 -7500 13500 -7500 2000 1000 3000 "1" "1" "onsolder,square,edge2"] + Pad[7000 -2500 13500 -2500 2000 1000 3000 "2" "2" "onsolder,square,edge2"] + Pad[7000 2500 13500 2500 2000 1000 3000 "3" "3" "onsolder,square,edge2"] + Pad[7000 7500 13500 7500 2000 1000 3000 "4" "4" "onsolder,square,edge2"] + Pad[-13500 7500 -7000 7500 2000 1000 3000 "5" "5" "onsolder,square"] + Pad[-13500 2500 -7000 2500 2000 1000 3000 "6" "6" "onsolder,square"] + Pad[-13500 -2500 -7000 -2500 2000 1000 3000 "7" "7" "onsolder,square"] + Pad[-13500 -7500 -7000 -7500 2000 1000 3000 "8" "8" "onsolder,square"] + ElementLine [-15500 -9500 -2500 -9500 1000] + ElementLine [2500 -9500 15500 -9500 1000] + ElementLine [-15500 9500 -15500 -9500 1000] + ElementLine [-15500 9500 15500 9500 1000] + ElementLine [15500 9500 15500 -9500 1000] + ElementArc [0 -9500 2500 2500 0 180 1000] + + ) + +Element["onsolder" "Small outline package, narrow (150mil)" "USO270_BOT" "SO8" 170000 240000 24000 18000 3 100 "auto"] +( + Pad[7500 7000 7500 13500 2000 1000 3000 "1" "1" "onsolder,square,edge2"] + Pad[2500 7000 2500 13500 2000 1000 3000 "2" "2" "onsolder,square,edge2"] + Pad[-2500 7000 -2500 13500 2000 1000 3000 "3" "3" "onsolder,square,edge2"] + Pad[-7500 7000 -7500 13500 2000 1000 3000 "4" "4" "onsolder,square,edge2"] + Pad[-7500 -13500 -7500 -7000 2000 1000 3000 "5" "5" "onsolder,square"] + Pad[-2500 -13500 -2500 -7000 2000 1000 3000 "6" "6" "onsolder,square"] + Pad[2500 -13500 2500 -7000 2000 1000 3000 "7" "7" "onsolder,square"] + Pad[7500 -13500 7500 -7000 2000 1000 3000 "8" "8" "onsolder,square"] + ElementLine [9500 -2500 9500 -15500 1000] + ElementLine [9500 15500 9500 2500 1000] + ElementLine [-9500 -15500 9500 -15500 1000] + ElementLine [-9500 15500 -9500 -15500 1000] + ElementLine [-9500 15500 9500 15500 1000] + ElementArc [9500 0 2500 2500 270 180 1000] + + ) + +Element["onsolder" "Dual in-line package, narrow (300 mil)" "UDIP0_BOT" "DIP8" 40000 450000 17000 -5000 3 100 "auto"] +( + Pin[0 0 6000 3000 6600 2800 "1" "1" "square"] + Pin[0 -10000 6000 3000 6600 2800 "2" "2" ""] + Pin[0 -20000 6000 3000 6600 2800 "3" "3" ""] + Pin[0 -30000 6000 3000 6600 2800 "4" "4" ""] + Pin[30000 -30000 6000 3000 6600 2800 "5" "5" ""] + Pin[30000 -20000 6000 3000 6600 2800 "6" "6" ""] + Pin[30000 -10000 6000 3000 6600 2800 "7" "7" ""] + Pin[30000 0 6000 3000 6600 2800 "8" "8" ""] + ElementLine [20000 5000 35000 5000 1000] + ElementLine [-5000 5000 10000 5000 1000] + ElementLine [35000 -35000 35000 5000 1000] + ElementLine [-5000 -35000 35000 -35000 1000] + ElementLine [-5000 5000 -5000 -35000 1000] + ElementArc [15000 5000 5000 5000 180 180 1000] + + ) + +Element["onsolder" "Dual in-line package, narrow (300 mil)" "UDIP90_BOT" "DIP8" 110000 420000 5000 17000 0 100 "auto"] +( + Pin[0 0 6000 3000 6600 2800 "1" "1" "square"] + Pin[10000 0 6000 3000 6600 2800 "2" "2" ""] + Pin[20000 0 6000 3000 6600 2800 "3" "3" ""] + Pin[30000 0 6000 3000 6600 2800 "4" "4" ""] + Pin[30000 30000 6000 3000 6600 2800 "5" "5" ""] + Pin[20000 30000 6000 3000 6600 2800 "6" "6" ""] + Pin[10000 30000 6000 3000 6600 2800 "7" "7" ""] + Pin[0 30000 6000 3000 6600 2800 "8" "8" ""] + ElementLine [-5000 35000 -5000 20000 1000] + ElementLine [-5000 10000 -5000 -5000 1000] + ElementLine [-5000 35000 35000 35000 1000] + ElementLine [35000 35000 35000 -5000 1000] + ElementLine [-5000 -5000 35000 -5000 1000] + ElementArc [-5000 15000 5000 5000 90 180 1000] + + ) + +Element["onsolder" "Dual in-line package, narrow (300 mil)" "UDIP180_BOT" "DIP8" 210000 420000 -17000 5000 1 100 "auto"] +( + Pin[0 0 6000 3000 6600 2800 "1" "1" "square"] + Pin[0 10000 6000 3000 6600 2800 "2" "2" ""] + Pin[0 20000 6000 3000 6600 2800 "3" "3" ""] + Pin[0 30000 6000 3000 6600 2800 "4" "4" ""] + Pin[-30000 30000 6000 3000 6600 2800 "5" "5" ""] + Pin[-30000 20000 6000 3000 6600 2800 "6" "6" ""] + Pin[-30000 10000 6000 3000 6600 2800 "7" "7" ""] + Pin[-30000 0 6000 3000 6600 2800 "8" "8" ""] + ElementLine [-35000 -5000 -20000 -5000 1000] + ElementLine [-10000 -5000 5000 -5000 1000] + ElementLine [-35000 35000 -35000 -5000 1000] + ElementLine [-35000 35000 5000 35000 1000] + ElementLine [5000 35000 5000 -5000 1000] + ElementArc [-15000 -5000 5000 5000 0 180 1000] + + ) + +Element["onsolder" "Dual in-line package, narrow (300 mil)" "UDIP270_BOT" "DIP8" 280000 450000 -5000 -17000 2 100 "auto"] +( + Pin[0 0 6000 3000 6600 2800 "1" "1" "square"] + Pin[-10000 0 6000 3000 6600 2800 "2" "2" ""] + Pin[-20000 0 6000 3000 6600 2800 "3" "3" ""] + Pin[-30000 0 6000 3000 6600 2800 "4" "4" ""] + Pin[-30000 -30000 6000 3000 6600 2800 "5" "5" ""] + Pin[-20000 -30000 6000 3000 6600 2800 "6" "6" ""] + Pin[-10000 -30000 6000 3000 6600 2800 "7" "7" ""] + Pin[0 -30000 6000 3000 6600 2800 "8" "8" ""] + ElementLine [5000 -20000 5000 -35000 1000] + ElementLine [5000 5000 5000 -10000 1000] + ElementLine [-35000 -35000 5000 -35000 1000] + ElementLine [-35000 5000 -35000 -35000 1000] + ElementLine [-35000 5000 5000 5000 1000] + ElementArc [5000 -15000 5000 5000 270 180 1000] + + ) + +Element["" "Small outline package, narrow (150mil)" "USO0_TOP" "SO8" 60000 180000 -16000 -22500 0 100 ""] +( + Pad[-13500 -7500 -7000 -7500 2000 1000 3000 "1" "1" "square"] + Pad[-13500 -2500 -7000 -2500 2000 1000 3000 "2" "2" "square"] + Pad[-13500 2500 -7000 2500 2000 1000 3000 "3" "3" "square"] + Pad[-13500 7500 -7000 7500 2000 1000 3000 "4" "4" "square"] + Pad[7000 7500 13500 7500 2000 1000 3000 "5" "5" "square,edge2"] + Pad[7000 2500 13500 2500 2000 1000 3000 "6" "6" "square,edge2"] + Pad[7000 -2500 13500 -2500 2000 1000 3000 "7" "7" "square,edge2"] + Pad[7000 -7500 13500 -7500 2000 1000 3000 "8" "8" "square,edge2"] + ElementLine [15500 -9500 2500 -9500 1000] + ElementLine [-15500 -9500 -2500 -9500 1000] + ElementLine [15500 9500 15500 -9500 1000] + ElementLine [-15500 9500 15500 9500 1000] + ElementLine [-15500 -9500 -15500 9500 1000] + ElementArc [0 -9500 2500 2500 0 180 1000] + + ) + +Element["" "Small outline package, narrow (150mil)" "USO270_TOP" "SO8" 100000 180000 -16000 22000 1 100 ""] +( + Pad[-7500 7000 -7500 13500 2000 1000 3000 "1" "1" "square,edge2"] + Pad[-2500 7000 -2500 13500 2000 1000 3000 "2" "2" "square,edge2"] + Pad[2500 7000 2500 13500 2000 1000 3000 "3" "3" "square,edge2"] + Pad[7500 7000 7500 13500 2000 1000 3000 "4" "4" "square,edge2"] + Pad[7500 -13500 7500 -7000 2000 1000 3000 "5" "5" "square"] + Pad[2500 -13500 2500 -7000 2000 1000 3000 "6" "6" "square"] + Pad[-2500 -13500 -2500 -7000 2000 1000 3000 "7" "7" "square"] + Pad[-7500 -13500 -7500 -7000 2000 1000 3000 "8" "8" "square"] + ElementLine [-9500 -15500 -9500 -2500 1000] + ElementLine [-9500 2500 -9500 15500 1000] + ElementLine [-9500 -15500 9500 -15500 1000] + ElementLine [9500 -15500 9500 15500 1000] + ElementLine [-9500 15500 9500 15500 1000] + ElementArc [-9500 0 2500 2500 90 180 1000] + + ) + +Element["" "Small outline package, narrow (150mil)" "USO180_TOP" "SO8" 130000 180000 9000 17000 2 100 ""] +( + Pad[7000 7500 13500 7500 2000 1000 3000 "1" "1" "square,edge2"] + Pad[7000 2500 13500 2500 2000 1000 3000 "2" "2" "square,edge2"] + Pad[7000 -2500 13500 -2500 2000 1000 3000 "3" "3" "square,edge2"] + Pad[7000 -7500 13500 -7500 2000 1000 3000 "4" "4" "square,edge2"] + Pad[-13500 -7500 -7000 -7500 2000 1000 3000 "5" "5" "square"] + Pad[-13500 -2500 -7000 -2500 2000 1000 3000 "6" "6" "square"] + Pad[-13500 2500 -7000 2500 2000 1000 3000 "7" "7" "square"] + Pad[-13500 7500 -7000 7500 2000 1000 3000 "8" "8" "square"] + ElementLine [-15500 9500 -2500 9500 1000] + ElementLine [2500 9500 15500 9500 1000] + ElementLine [-15500 -9500 -15500 9500 1000] + ElementLine [-15500 -9500 15500 -9500 1000] + ElementLine [15500 -9500 15500 9500 1000] + ElementArc [0 9500 2500 2500 180 180 1000] + + ) + +Element["" "Small outline package, narrow (150mil)" "USO90_TOP" "SO8" 170000 180000 15500 -13500 3 100 ""] +( + Pad[7500 -13500 7500 -7000 2000 1000 3000 "1" "1" "square"] + Pad[2500 -13500 2500 -7000 2000 1000 3000 "2" "2" "square"] + Pad[-2500 -13500 -2500 -7000 2000 1000 3000 "3" "3" "square"] + Pad[-7500 -13500 -7500 -7000 2000 1000 3000 "4" "4" "square"] + Pad[-7500 7000 -7500 13500 2000 1000 3000 "5" "5" "square,edge2"] + Pad[-2500 7000 -2500 13500 2000 1000 3000 "6" "6" "square,edge2"] + Pad[2500 7000 2500 13500 2000 1000 3000 "7" "7" "square,edge2"] + Pad[7500 7000 7500 13500 2000 1000 3000 "8" "8" "square,edge2"] + ElementLine [9500 2500 9500 15500 1000] + ElementLine [9500 -15500 9500 -2500 1000] + ElementLine [-9500 15500 9500 15500 1000] + ElementLine [-9500 -15500 -9500 15500 1000] + ElementLine [-9500 -15500 9500 -15500 1000] + ElementArc [9500 0 2500 2500 270 180 1000] + + ) + +Element["" "Dual in-line package, narrow (300 mil)" "UDIP0_TOP" "DIP8" 40000 340000 17000 -35000 3 100 ""] +( + Pin[0 0 6000 3000 6600 2800 "1" "1" "square"] + Pin[0 10000 6000 3000 6600 2800 "2" "2" ""] + Pin[0 20000 6000 3000 6600 2800 "3" "3" ""] + Pin[0 30000 6000 3000 6600 2800 "4" "4" ""] + Pin[30000 30000 6000 3000 6600 2800 "5" "5" ""] + Pin[30000 20000 6000 3000 6600 2800 "6" "6" ""] + Pin[30000 10000 6000 3000 6600 2800 "7" "7" ""] + Pin[30000 0 6000 3000 6600 2800 "8" "8" ""] + ElementLine [20000 -5000 35000 -5000 1000] + ElementLine [-5000 -5000 10000 -5000 1000] + ElementLine [35000 35000 35000 -5000 1000] + ElementLine [-5000 35000 35000 35000 1000] + ElementLine [-5000 -5000 -5000 35000 1000] + ElementArc [15000 -5000 5000 5000 0 180 1000] + + ) + +Element["" "Dual in-line package, narrow (300 mil)" "UDIP270_TOP" "DIP8" 110000 370000 5000 -17000 0 100 ""] +( + Pin[0 0 6000 3000 6600 2800 "1" "1" "square"] + Pin[10000 0 6000 3000 6600 2800 "2" "2" ""] + Pin[20000 0 6000 3000 6600 2800 "3" "3" ""] + Pin[30000 0 6000 3000 6600 2800 "4" "4" ""] + Pin[30000 -30000 6000 3000 6600 2800 "5" "5" ""] + Pin[20000 -30000 6000 3000 6600 2800 "6" "6" ""] + Pin[10000 -30000 6000 3000 6600 2800 "7" "7" ""] + Pin[0 -30000 6000 3000 6600 2800 "8" "8" ""] + ElementLine [-5000 -35000 -5000 -20000 1000] + ElementLine [-5000 -10000 -5000 5000 1000] + ElementLine [-5000 -35000 35000 -35000 1000] + ElementLine [35000 -35000 35000 5000 1000] + ElementLine [-5000 5000 35000 5000 1000] + ElementArc [-5000 -15000 5000 5000 90 180 1000] + + ) + +Element["" "Dual in-line package, narrow (300 mil)" "UDIP180_TOP" "DIP8" 210000 370000 -17000 -5000 1 100 ""] +( + Pin[0 0 6000 3000 6600 2800 "1" "1" "square"] + Pin[0 -10000 6000 3000 6600 2800 "2" "2" ""] + Pin[0 -20000 6000 3000 6600 2800 "3" "3" ""] + Pin[0 -30000 6000 3000 6600 2800 "4" "4" ""] + Pin[-30000 -30000 6000 3000 6600 2800 "5" "5" ""] + Pin[-30000 -20000 6000 3000 6600 2800 "6" "6" ""] + Pin[-30000 -10000 6000 3000 6600 2800 "7" "7" ""] + Pin[-30000 0 6000 3000 6600 2800 "8" "8" ""] + ElementLine [-35000 5000 -20000 5000 1000] + ElementLine [-10000 5000 5000 5000 1000] + ElementLine [-35000 -35000 -35000 5000 1000] + ElementLine [-35000 -35000 5000 -35000 1000] + ElementLine [5000 -35000 5000 5000 1000] + ElementArc [-15000 5000 5000 5000 180 180 1000] + + ) + +Element["" "Dual in-line package, narrow (300 mil)" "UDIP90_TOP" "DIP8" 280000 340000 -5000 17000 2 100 ""] +( + Pin[0 0 6000 3000 6600 2800 "1" "1" "square"] + Pin[-10000 0 6000 3000 6600 2800 "2" "2" ""] + Pin[-20000 0 6000 3000 6600 2800 "3" "3" ""] + Pin[-30000 0 6000 3000 6600 2800 "4" "4" ""] + Pin[-30000 30000 6000 3000 6600 2800 "5" "5" ""] + Pin[-20000 30000 6000 3000 6600 2800 "6" "6" ""] + Pin[-10000 30000 6000 3000 6600 2800 "7" "7" ""] + Pin[0 30000 6000 3000 6600 2800 "8" "8" ""] + ElementLine [5000 20000 5000 35000 1000] + ElementLine [5000 -5000 5000 10000 1000] + ElementLine [-35000 35000 5000 35000 1000] + ElementLine [-35000 -5000 -35000 35000 1000] + ElementLine [-35000 -5000 5000 -5000 1000] + ElementArc [5000 15000 5000 5000 270 180 1000] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R0_TOP" "RESC3216N" 60000 70000 -11960 -10150 0 100 ""] +( + Pad[-5905 -984 -5905 984 5118 2000 5718 "1" "1" "square"] + Pad[5905 -984 5905 984 5118 2000 5718 "2" "2" "square"] + ElementLine [-1968 3543 1968 3543 800] + ElementLine [-1968 -3543 1968 -3543 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R270_TOP" "RESC3216N" 100000 70000 -13150 13150 1 100 ""] +( + Pad[-984 5905 984 5905 5118 2000 5718 "1" "1" "square"] + Pad[-984 -5905 984 -5905 5118 2000 5718 "2" "2" "square"] + ElementLine [3543 -1968 3543 1968 800] + ElementLine [-3543 -1968 -3543 1968 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R180_TOP" "RESC3216N" 130000 70000 13150 13150 2 100 ""] +( + Pad[5905 -984 5905 984 5118 2000 5718 "1" "1" "square"] + Pad[-5905 -984 -5905 984 5118 2000 5718 "2" "2" "square"] + ElementLine [-1968 -3543 1968 -3543 800] + ElementLine [-1968 3543 1968 3543 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "R90_TOP" "RESC3216N" 170000 70000 15261 -7039 3 100 ""] +( + Pad[-984 -5905 984 -5905 5118 2000 5718 "1" "1" "square"] + Pad[-984 5905 984 5905 5118 2000 5718 "2" "2" "square"] + ElementLine [-3543 -1968 -3543 1968 800] + ElementLine [3543 -1968 3543 1968 800] + + ) +Layer(1 "component") +( +) +Layer(2 "solder") +( +) +Layer(3 "GND") +( +) +Layer(4 "power") +( +) +Layer(5 "signal1") +( +) +Layer(6 "signal2") +( +) +Layer(7 "signal3") +( +) +Layer(8 "signal4") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( + Text[270000 80000 0 100 "2-pin surface mount elements" ""] + Text[270000 90000 0 100 "0/90/180/270 degree rotations" ""] + Text[270000 100000 0 100 "both sides ofthe board" ""] + Text[270000 190000 0 100 "multi-pin surface mount elements" ""] + Text[270000 200000 0 100 "0/90/180/270 degree rotations" ""] + Text[270000 210000 0 100 "both sides ofthe board" ""] + Text[310000 380000 0 100 "multi-pin leaded elements" "selected"] + Text[310000 390000 0 100 "0/90/180/270 degree rotations" ""] + Text[310000 400000 0 100 "both sides ofthe board" ""] +) Index: tags/2.3.0/tests/orig/inputs/gcode_oneline.pcb =================================================================== --- tags/2.3.0/tests/orig/inputs/gcode_oneline.pcb (nonexistent) +++ tags/2.3.0/tests/orig/inputs/gcode_oneline.pcb (revision 33253) @@ -0,0 +1,829 @@ +# release: pcb 1.99y + +# To read pcb files, the pcb version (or the cvs source date) must be >= the file version +FileVersion[20070407] + +PCB["Basic Single Trace RS274-X Test" 200000 100000] + +Grid[10000.000000 0 0 1] +Cursor[0 500000 0.000000] +PolyArea[200000000.000000] +Thermal[0.500000] +DRC[1000 1000 1000 1000 1500 1000] +Flags("nameonpcb,uniquename,clearnew,snappin") +Groups("1,c:2,s:3:4:5:6:7:8") +Styles["Signal,1000,3600,2000,1000:Power,2500,6000,3500,1000:Fat,4000,6000,3500,1000:Skinny,600,2402,1181,600"] + +Symbol(' ' 18) +( +) +Symbol('!' 12) +( + SymbolLine(0 45 0 50 8) + SymbolLine(0 10 0 35 8) +) +Symbol('"' 12) +( + SymbolLine(0 10 0 20 8) + SymbolLine(10 10 10 20 8) +) +Symbol('#' 12) +( + SymbolLine(0 35 20 35 8) + SymbolLine(0 25 20 25 8) + SymbolLine(15 20 15 40 8) + SymbolLine(5 20 5 40 8) +) +Symbol('$' 12) +( + SymbolLine(15 15 20 20 8) + SymbolLine(5 15 15 15 8) + SymbolLine(0 20 5 15 8) + SymbolLine(0 20 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 40 8) + SymbolLine(15 45 20 40 8) + SymbolLine(5 45 15 45 8) + SymbolLine(0 40 5 45 8) + SymbolLine(10 10 10 50 8) +) +Symbol('%' 12) +( + SymbolLine(0 15 0 20 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 10 10 8) + SymbolLine(10 10 15 15 8) + SymbolLine(15 15 15 20 8) + SymbolLine(10 25 15 20 8) + SymbolLine(5 25 10 25 8) + SymbolLine(0 20 5 25 8) + SymbolLine(0 50 40 10 8) + SymbolLine(35 50 40 45 8) + SymbolLine(40 40 40 45 8) + SymbolLine(35 35 40 40 8) + SymbolLine(30 35 35 35 8) + SymbolLine(25 40 30 35 8) + SymbolLine(25 40 25 45 8) + SymbolLine(25 45 30 50 8) + SymbolLine(30 50 35 50 8) +) +Symbol('&' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 35 15 20 8) + SymbolLine(5 50 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(0 25 25 50 8) + SymbolLine(5 10 10 10 8) + SymbolLine(10 10 15 15 8) + SymbolLine(15 15 15 20 8) + SymbolLine(0 35 0 45 8) +) +Symbol(''' 12) +( + SymbolLine(0 20 10 10 8) +) +Symbol('(' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) +) +Symbol(')' 12) +( + SymbolLine(0 10 5 15 8) + SymbolLine(5 15 5 45 8) + SymbolLine(0 50 5 45 8) +) +Symbol('*' 12) +( + SymbolLine(0 20 20 40 8) + SymbolLine(0 40 20 20 8) + SymbolLine(0 30 20 30 8) + SymbolLine(10 20 10 40 8) +) +Symbol('+' 12) +( + SymbolLine(0 30 20 30 8) + SymbolLine(10 20 10 40 8) +) +Symbol(',' 12) +( + SymbolLine(0 60 10 50 8) +) +Symbol('-' 12) +( + SymbolLine(0 30 20 30 8) +) +Symbol('.' 12) +( + SymbolLine(0 50 5 50 8) +) +Symbol('/' 12) +( + SymbolLine(0 45 30 15 8) +) +Symbol('0' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 40 20 20 8) +) +Symbol('1' 12) +( + SymbolLine(5 50 15 50 8) + SymbolLine(10 10 10 50 8) + SymbolLine(0 20 10 10 8) +) +Symbol('2' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(0 50 25 25 8) + SymbolLine(0 50 25 50 8) +) +Symbol('3' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 30 20 30 8) +) +Symbol('4' 12) +( + SymbolLine(0 30 20 10 8) + SymbolLine(0 30 25 30 8) + SymbolLine(20 10 20 50 8) +) +Symbol('5' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(0 10 0 30 8) + SymbolLine(0 30 5 25 8) + SymbolLine(5 25 15 25 8) + SymbolLine(15 25 20 30 8) + SymbolLine(20 30 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('6' 12) +( + SymbolLine(15 10 20 15 8) + SymbolLine(5 10 15 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(15 30 20 35 8) + SymbolLine(0 30 15 30 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 35 20 45 8) +) +Symbol('7' 12) +( + SymbolLine(0 50 25 25 8) + SymbolLine(25 10 25 25 8) + SymbolLine(0 10 25 10 8) +) +Symbol('8' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 25 5 30 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 25 8) + SymbolLine(15 30 20 25 8) +) +Symbol('9' 12) +( + SymbolLine(0 50 20 30 8) + SymbolLine(20 15 20 30 8) + SymbolLine(15 10 20 15 8) + SymbolLine(5 10 15 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 20 30 8) +) +Symbol(':' 12) +( + SymbolLine(0 25 5 25 8) + SymbolLine(0 35 5 35 8) +) +Symbol(';' 12) +( + SymbolLine(0 50 10 40 8) + SymbolLine(10 25 10 30 8) +) +Symbol('<' 12) +( + SymbolLine(0 30 10 20 8) + SymbolLine(0 30 10 40 8) +) +Symbol('=' 12) +( + SymbolLine(0 25 20 25 8) + SymbolLine(0 35 20 35 8) +) +Symbol('>' 12) +( + SymbolLine(0 20 10 30 8) + SymbolLine(0 40 10 30 8) +) +Symbol('?' 12) +( + SymbolLine(10 30 10 35 8) + SymbolLine(10 45 10 50 8) + SymbolLine(0 15 0 20 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 20 8) + SymbolLine(10 30 20 20 8) +) +Symbol('@' 12) +( + SymbolLine(0 10 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 40 50 8) + SymbolLine(50 35 50 10 8) + SymbolLine(50 10 40 0 8) + SymbolLine(40 0 10 0 8) + SymbolLine(10 0 0 10 8) + SymbolLine(15 20 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 30 35 8) + SymbolLine(30 35 35 30 8) + SymbolLine(35 30 40 35 8) + SymbolLine(35 30 35 15 8) + SymbolLine(35 20 30 15 8) + SymbolLine(20 15 30 15 8) + SymbolLine(20 15 15 20 8) + SymbolLine(40 35 50 35 8) +) +Symbol('A' 12) +( + SymbolLine(0 15 0 50 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 50 8) + SymbolLine(0 30 25 30 8) +) +Symbol('B' 12) +( + SymbolLine(0 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 30 25 35 8) + SymbolLine(5 30 20 30 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) +) +Symbol('C' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) +) +Symbol('D' 12) +( + SymbolLine(5 10 5 50 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(0 50 20 50 8) + SymbolLine(0 10 20 10 8) +) +Symbol('E' 12) +( + SymbolLine(0 30 15 30 8) + SymbolLine(0 50 20 50 8) + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 20 10 8) +) +Symbol('F' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(0 30 15 30 8) +) +Symbol('G' 12) +( + SymbolLine(20 10 25 15 8) + SymbolLine(5 10 20 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 30 25 35 8) + SymbolLine(10 30 20 30 8) +) +Symbol('H' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(25 10 25 50 8) + SymbolLine(0 30 25 30 8) +) +Symbol('I' 12) +( + SymbolLine(0 10 10 10 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 50 10 50 8) +) +Symbol('J' 12) +( + SymbolLine(0 10 15 10 8) + SymbolLine(15 10 15 45 8) + SymbolLine(10 50 15 45 8) + SymbolLine(5 50 10 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('K' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 30 20 10 8) + SymbolLine(0 30 20 50 8) +) +Symbol('L' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 20 50 8) +) +Symbol('M' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 15 25 8) + SymbolLine(15 25 30 10 8) + SymbolLine(30 10 30 50 8) +) +Symbol('N' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 25 40 8) + SymbolLine(25 10 25 50 8) +) +Symbol('O' 12) +( + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('P' 12) +( + SymbolLine(5 10 5 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) + SymbolLine(5 30 20 30 8) +) +Symbol('Q' 12) +( + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(10 40 20 50 8) +) +Symbol('R' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) + SymbolLine(5 30 20 30 8) + SymbolLine(5 10 5 50 8) + SymbolLine(5 30 25 50 8) +) +Symbol('S' 12) +( + SymbolLine(20 10 25 15 8) + SymbolLine(5 10 20 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('T' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(10 10 10 50 8) +) +Symbol('U' 12) +( + SymbolLine(0 10 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 10 20 45 8) +) +Symbol('V' 12) +( + SymbolLine(0 10 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(20 10 20 40 8) +) +Symbol('W' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 15 35 8) + SymbolLine(15 35 30 50 8) + SymbolLine(30 10 30 50 8) +) +Symbol('X' 12) +( + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 25 40 8) + SymbolLine(25 40 25 50 8) + SymbolLine(0 40 0 50 8) + SymbolLine(0 40 25 15 8) + SymbolLine(25 10 25 15 8) +) +Symbol('Y' 12) +( + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 10 25 8) + SymbolLine(10 25 20 15 8) + SymbolLine(20 10 20 15 8) + SymbolLine(10 25 10 50 8) +) +Symbol('Z' 12) +( + SymbolLine(0 10 25 10 8) + SymbolLine(25 10 25 15 8) + SymbolLine(0 40 25 15 8) + SymbolLine(0 40 0 50 8) + SymbolLine(0 50 25 50 8) +) +Symbol('[' 12) +( + SymbolLine(0 10 5 10 8) + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 5 50 8) +) +Symbol('\' 12) +( + SymbolLine(0 15 30 45 8) +) +Symbol(']' 12) +( + SymbolLine(0 10 5 10 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 50 5 50 8) +) +Symbol('^' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 10 15 8) +) +Symbol('_' 12) +( + SymbolLine(0 50 20 50 8) +) +Symbol('a' 12) +( + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(20 30 20 45 8) + SymbolLine(20 45 25 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('b' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) +) +Symbol('c' 12) +( + SymbolLine(5 30 20 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 20 50 8) +) +Symbol('d' 12) +( + SymbolLine(20 10 20 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) +) +Symbol('e' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(0 40 20 40 8) + SymbolLine(20 40 20 35 8) +) +Symbol('f' 10) +( + SymbolLine(5 15 5 50 8) + SymbolLine(5 15 10 10 8) + SymbolLine(10 10 15 10 8) + SymbolLine(0 30 10 30 8) +) +Symbol('g' 12) +( + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(0 60 5 65 8) + SymbolLine(5 65 15 65 8) + SymbolLine(15 65 20 60 8) + SymbolLine(20 30 20 60 8) +) +Symbol('h' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) +) +Symbol('i' 10) +( + SymbolLine(0 20 0 25 8) + SymbolLine(0 35 0 50 8) +) +Symbol('j' 10) +( + SymbolLine(5 20 5 25 8) + SymbolLine(5 35 5 60 8) + SymbolLine(0 65 5 60 8) +) +Symbol('k' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 35 15 50 8) + SymbolLine(0 35 10 25 8) +) +Symbol('l' 10) +( + SymbolLine(0 10 0 45 8) + SymbolLine(0 45 5 50 8) +) +Symbol('m' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) + SymbolLine(20 35 25 30 8) + SymbolLine(25 30 30 30 8) + SymbolLine(30 30 35 35 8) + SymbolLine(35 35 35 50 8) + SymbolLine(0 30 5 35 8) +) +Symbol('n' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) + SymbolLine(0 30 5 35 8) +) +Symbol('o' 12) +( + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('p' 12) +( + SymbolLine(5 35 5 65 8) + SymbolLine(0 30 5 35 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(10 50 20 50 8) + SymbolLine(5 45 10 50 8) +) +Symbol('q' 12) +( + SymbolLine(20 35 20 65 8) + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('r' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 20 30 8) + SymbolLine(0 30 5 35 8) +) +Symbol('s' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(20 40 25 45 8) + SymbolLine(5 40 20 40 8) + SymbolLine(0 35 5 40 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(0 45 5 50 8) +) +Symbol('t' 10) +( + SymbolLine(5 10 5 45 8) + SymbolLine(5 45 10 50 8) + SymbolLine(0 25 10 25 8) +) +Symbol('u' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 30 20 45 8) +) +Symbol('v' 12) +( + SymbolLine(0 30 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(20 30 20 40 8) +) +Symbol('w' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 10 50 8) + SymbolLine(10 50 15 45 8) + SymbolLine(15 30 15 45 8) + SymbolLine(15 45 20 50 8) + SymbolLine(20 50 25 50 8) + SymbolLine(25 50 30 45 8) + SymbolLine(30 30 30 45 8) +) +Symbol('x' 12) +( + SymbolLine(0 30 20 50 8) + SymbolLine(0 50 20 30 8) +) +Symbol('y' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(20 30 20 60 8) + SymbolLine(15 65 20 60 8) + SymbolLine(5 65 15 65 8) + SymbolLine(0 60 5 65 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('z' 12) +( + SymbolLine(0 30 20 30 8) + SymbolLine(0 50 20 30 8) + SymbolLine(0 50 20 50 8) +) +Symbol('{' 12) +( + SymbolLine(5 15 10 10 8) + SymbolLine(5 15 5 25 8) + SymbolLine(0 30 5 25 8) + SymbolLine(0 30 5 35 8) + SymbolLine(5 35 5 45 8) + SymbolLine(5 45 10 50 8) +) +Symbol('|' 12) +( + SymbolLine(0 10 0 50 8) +) +Symbol('}' 12) +( + SymbolLine(0 10 5 15 8) + SymbolLine(5 15 5 25 8) + SymbolLine(5 25 10 30 8) + SymbolLine(5 35 10 30 8) + SymbolLine(5 35 5 45 8) + SymbolLine(0 50 5 45 8) +) +Symbol('~' 12) +( + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 10 30 8) + SymbolLine(10 30 15 35 8) + SymbolLine(15 35 20 35 8) + SymbolLine(20 35 25 30 8) +) +Via[90000 50000 6000 2000 0 3500 "" ""] +Layer(1 "component") +( + Line[10000 50000 90000 50000 4000 2000 "clearline"] +) +Layer(2 "solder") +( + Line[170000 50000 90000 50000 4000 2000 "clearline"] +) +Layer(3 "GND") +( +) +Layer(4 "power") +( +) +Layer(5 "signal1") +( +) +Layer(6 "signal2") +( +) +Layer(7 "signal3") +( +) +Layer(8 "signal4") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) Index: tags/2.3.0/tests/orig/inputs/gerber_arcs.pcb =================================================================== --- tags/2.3.0/tests/orig/inputs/gerber_arcs.pcb (nonexistent) +++ tags/2.3.0/tests/orig/inputs/gerber_arcs.pcb (revision 33253) @@ -0,0 +1,844 @@ +# release: pcb 20100929 +# date: Thu Jun 16 20:10:40 2011 +# user: username () +# host: titanic.lan + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20100606] + +PCB["" 3000000 2000000] + +Grid[10000.000000 0 0 0] +Cursor[0 0 0.000000] +PolyArea[200000000.000000] +Thermal[0.500000] +DRC[14941 14941 14941 14941 22411 14941] +Flags("nameonpcb,uniquename,clearnew,snappin") +Groups("1,c:2:3:4:5:6,s:7:8") +Styles["Signal,1000,3600,2000,1000:Power,50000,65000,25000,1000:Fat,4000,6000,3500,1000:Skinny,600,2402,1181,600"] + +Symbol(' ' 18) +( +) +Symbol('!' 12) +( + SymbolLine(0 45 0 50 8) + SymbolLine(0 10 0 35 8) +) +Symbol('"' 12) +( + SymbolLine(0 10 0 20 8) + SymbolLine(10 10 10 20 8) +) +Symbol('#' 12) +( + SymbolLine(0 35 20 35 8) + SymbolLine(0 25 20 25 8) + SymbolLine(15 20 15 40 8) + SymbolLine(5 20 5 40 8) +) +Symbol('$' 12) +( + SymbolLine(15 15 20 20 8) + SymbolLine(5 15 15 15 8) + SymbolLine(0 20 5 15 8) + SymbolLine(0 20 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 40 8) + SymbolLine(15 45 20 40 8) + SymbolLine(5 45 15 45 8) + SymbolLine(0 40 5 45 8) + SymbolLine(10 10 10 50 8) +) +Symbol('%' 12) +( + SymbolLine(0 15 0 20 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 10 10 8) + SymbolLine(10 10 15 15 8) + SymbolLine(15 15 15 20 8) + SymbolLine(10 25 15 20 8) + SymbolLine(5 25 10 25 8) + SymbolLine(0 20 5 25 8) + SymbolLine(0 50 40 10 8) + SymbolLine(35 50 40 45 8) + SymbolLine(40 40 40 45 8) + SymbolLine(35 35 40 40 8) + SymbolLine(30 35 35 35 8) + SymbolLine(25 40 30 35 8) + SymbolLine(25 40 25 45 8) + SymbolLine(25 45 30 50 8) + SymbolLine(30 50 35 50 8) +) +Symbol('&' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 35 15 20 8) + SymbolLine(5 50 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(0 25 25 50 8) + SymbolLine(5 10 10 10 8) + SymbolLine(10 10 15 15 8) + SymbolLine(15 15 15 20 8) + SymbolLine(0 35 0 45 8) +) +Symbol(''' 12) +( + SymbolLine(0 20 10 10 8) +) +Symbol('(' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) +) +Symbol(')' 12) +( + SymbolLine(0 10 5 15 8) + SymbolLine(5 15 5 45 8) + SymbolLine(0 50 5 45 8) +) +Symbol('*' 12) +( + SymbolLine(0 20 20 40 8) + SymbolLine(0 40 20 20 8) + SymbolLine(0 30 20 30 8) + SymbolLine(10 20 10 40 8) +) +Symbol('+' 12) +( + SymbolLine(0 30 20 30 8) + SymbolLine(10 20 10 40 8) +) +Symbol(',' 12) +( + SymbolLine(0 60 10 50 8) +) +Symbol('-' 12) +( + SymbolLine(0 30 20 30 8) +) +Symbol('.' 12) +( + SymbolLine(0 50 5 50 8) +) +Symbol('/' 12) +( + SymbolLine(0 45 30 15 8) +) +Symbol('0' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 40 20 20 8) +) +Symbol('1' 12) +( + SymbolLine(5 50 15 50 8) + SymbolLine(10 10 10 50 8) + SymbolLine(0 20 10 10 8) +) +Symbol('2' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(0 50 25 25 8) + SymbolLine(0 50 25 50 8) +) +Symbol('3' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 30 20 30 8) +) +Symbol('4' 12) +( + SymbolLine(0 30 20 10 8) + SymbolLine(0 30 25 30 8) + SymbolLine(20 10 20 50 8) +) +Symbol('5' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(0 10 0 30 8) + SymbolLine(0 30 5 25 8) + SymbolLine(5 25 15 25 8) + SymbolLine(15 25 20 30 8) + SymbolLine(20 30 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('6' 12) +( + SymbolLine(15 10 20 15 8) + SymbolLine(5 10 15 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(15 30 20 35 8) + SymbolLine(0 30 15 30 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 35 20 45 8) +) +Symbol('7' 12) +( + SymbolLine(0 50 25 25 8) + SymbolLine(25 10 25 25 8) + SymbolLine(0 10 25 10 8) +) +Symbol('8' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 25 5 30 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 25 8) + SymbolLine(15 30 20 25 8) +) +Symbol('9' 12) +( + SymbolLine(0 50 20 30 8) + SymbolLine(20 15 20 30 8) + SymbolLine(15 10 20 15 8) + SymbolLine(5 10 15 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 20 30 8) +) +Symbol(':' 12) +( + SymbolLine(0 25 5 25 8) + SymbolLine(0 35 5 35 8) +) +Symbol(';' 12) +( + SymbolLine(0 50 10 40 8) + SymbolLine(10 25 10 30 8) +) +Symbol('<' 12) +( + SymbolLine(0 30 10 20 8) + SymbolLine(0 30 10 40 8) +) +Symbol('=' 12) +( + SymbolLine(0 25 20 25 8) + SymbolLine(0 35 20 35 8) +) +Symbol('>' 12) +( + SymbolLine(0 20 10 30 8) + SymbolLine(0 40 10 30 8) +) +Symbol('?' 12) +( + SymbolLine(10 30 10 35 8) + SymbolLine(10 45 10 50 8) + SymbolLine(0 15 0 20 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 20 8) + SymbolLine(10 30 20 20 8) +) +Symbol('@' 12) +( + SymbolLine(0 10 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 40 50 8) + SymbolLine(50 35 50 10 8) + SymbolLine(50 10 40 0 8) + SymbolLine(40 0 10 0 8) + SymbolLine(10 0 0 10 8) + SymbolLine(15 20 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 30 35 8) + SymbolLine(30 35 35 30 8) + SymbolLine(35 30 40 35 8) + SymbolLine(35 30 35 15 8) + SymbolLine(35 20 30 15 8) + SymbolLine(20 15 30 15 8) + SymbolLine(20 15 15 20 8) + SymbolLine(40 35 50 35 8) +) +Symbol('A' 12) +( + SymbolLine(0 15 0 50 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 50 8) + SymbolLine(0 30 25 30 8) +) +Symbol('B' 12) +( + SymbolLine(0 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 30 25 35 8) + SymbolLine(5 30 20 30 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) +) +Symbol('C' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) +) +Symbol('D' 12) +( + SymbolLine(5 10 5 50 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(0 50 20 50 8) + SymbolLine(0 10 20 10 8) +) +Symbol('E' 12) +( + SymbolLine(0 30 15 30 8) + SymbolLine(0 50 20 50 8) + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 20 10 8) +) +Symbol('F' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(0 30 15 30 8) +) +Symbol('G' 12) +( + SymbolLine(20 10 25 15 8) + SymbolLine(5 10 20 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 30 25 35 8) + SymbolLine(10 30 20 30 8) +) +Symbol('H' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(25 10 25 50 8) + SymbolLine(0 30 25 30 8) +) +Symbol('I' 12) +( + SymbolLine(0 10 10 10 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 50 10 50 8) +) +Symbol('J' 12) +( + SymbolLine(0 10 15 10 8) + SymbolLine(15 10 15 45 8) + SymbolLine(10 50 15 45 8) + SymbolLine(5 50 10 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('K' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 30 20 10 8) + SymbolLine(0 30 20 50 8) +) +Symbol('L' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 20 50 8) +) +Symbol('M' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 15 25 8) + SymbolLine(15 25 30 10 8) + SymbolLine(30 10 30 50 8) +) +Symbol('N' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 25 40 8) + SymbolLine(25 10 25 50 8) +) +Symbol('O' 12) +( + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('P' 12) +( + SymbolLine(5 10 5 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) + SymbolLine(5 30 20 30 8) +) +Symbol('Q' 12) +( + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(10 40 20 50 8) +) +Symbol('R' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) + SymbolLine(5 30 20 30 8) + SymbolLine(5 10 5 50 8) + SymbolLine(5 30 25 50 8) +) +Symbol('S' 12) +( + SymbolLine(20 10 25 15 8) + SymbolLine(5 10 20 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('T' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(10 10 10 50 8) +) +Symbol('U' 12) +( + SymbolLine(0 10 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 10 20 45 8) +) +Symbol('V' 12) +( + SymbolLine(0 10 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(20 10 20 40 8) +) +Symbol('W' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 15 35 8) + SymbolLine(15 35 30 50 8) + SymbolLine(30 10 30 50 8) +) +Symbol('X' 12) +( + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 25 40 8) + SymbolLine(25 40 25 50 8) + SymbolLine(0 40 0 50 8) + SymbolLine(0 40 25 15 8) + SymbolLine(25 10 25 15 8) +) +Symbol('Y' 12) +( + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 10 25 8) + SymbolLine(10 25 20 15 8) + SymbolLine(20 10 20 15 8) + SymbolLine(10 25 10 50 8) +) +Symbol('Z' 12) +( + SymbolLine(0 10 25 10 8) + SymbolLine(25 10 25 15 8) + SymbolLine(0 40 25 15 8) + SymbolLine(0 40 0 50 8) + SymbolLine(0 50 25 50 8) +) +Symbol('[' 12) +( + SymbolLine(0 10 5 10 8) + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 5 50 8) +) +Symbol('\' 12) +( + SymbolLine(0 15 30 45 8) +) +Symbol(']' 12) +( + SymbolLine(0 10 5 10 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 50 5 50 8) +) +Symbol('^' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 10 15 8) +) +Symbol('_' 12) +( + SymbolLine(0 50 20 50 8) +) +Symbol('a' 12) +( + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(20 30 20 45 8) + SymbolLine(20 45 25 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('b' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) +) +Symbol('c' 12) +( + SymbolLine(5 30 20 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 20 50 8) +) +Symbol('d' 12) +( + SymbolLine(20 10 20 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) +) +Symbol('e' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(0 40 20 40 8) + SymbolLine(20 40 20 35 8) +) +Symbol('f' 10) +( + SymbolLine(5 15 5 50 8) + SymbolLine(5 15 10 10 8) + SymbolLine(10 10 15 10 8) + SymbolLine(0 30 10 30 8) +) +Symbol('g' 12) +( + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(0 60 5 65 8) + SymbolLine(5 65 15 65 8) + SymbolLine(15 65 20 60 8) + SymbolLine(20 30 20 60 8) +) +Symbol('h' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) +) +Symbol('i' 10) +( + SymbolLine(0 20 0 25 8) + SymbolLine(0 35 0 50 8) +) +Symbol('j' 10) +( + SymbolLine(5 20 5 25 8) + SymbolLine(5 35 5 60 8) + SymbolLine(0 65 5 60 8) +) +Symbol('k' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 35 15 50 8) + SymbolLine(0 35 10 25 8) +) +Symbol('l' 10) +( + SymbolLine(0 10 0 45 8) + SymbolLine(0 45 5 50 8) +) +Symbol('m' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) + SymbolLine(20 35 25 30 8) + SymbolLine(25 30 30 30 8) + SymbolLine(30 30 35 35 8) + SymbolLine(35 35 35 50 8) + SymbolLine(0 30 5 35 8) +) +Symbol('n' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) + SymbolLine(0 30 5 35 8) +) +Symbol('o' 12) +( + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('p' 12) +( + SymbolLine(5 35 5 65 8) + SymbolLine(0 30 5 35 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(10 50 20 50 8) + SymbolLine(5 45 10 50 8) +) +Symbol('q' 12) +( + SymbolLine(20 35 20 65 8) + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('r' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 20 30 8) + SymbolLine(0 30 5 35 8) +) +Symbol('s' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(20 40 25 45 8) + SymbolLine(5 40 20 40 8) + SymbolLine(0 35 5 40 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(0 45 5 50 8) +) +Symbol('t' 10) +( + SymbolLine(5 10 5 45 8) + SymbolLine(5 45 10 50 8) + SymbolLine(0 25 10 25 8) +) +Symbol('u' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 30 20 45 8) +) +Symbol('v' 12) +( + SymbolLine(0 30 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(20 30 20 40 8) +) +Symbol('w' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 10 50 8) + SymbolLine(10 50 15 45 8) + SymbolLine(15 30 15 45 8) + SymbolLine(15 45 20 50 8) + SymbolLine(20 50 25 50 8) + SymbolLine(25 50 30 45 8) + SymbolLine(30 30 30 45 8) +) +Symbol('x' 12) +( + SymbolLine(0 30 20 50 8) + SymbolLine(0 50 20 30 8) +) +Symbol('y' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(20 30 20 60 8) + SymbolLine(15 65 20 60 8) + SymbolLine(5 65 15 65 8) + SymbolLine(0 60 5 65 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('z' 12) +( + SymbolLine(0 30 20 30 8) + SymbolLine(0 50 20 30 8) + SymbolLine(0 50 20 50 8) +) +Symbol('{' 12) +( + SymbolLine(5 15 10 10 8) + SymbolLine(5 15 5 25 8) + SymbolLine(0 30 5 25 8) + SymbolLine(0 30 5 35 8) + SymbolLine(5 35 5 45 8) + SymbolLine(5 45 10 50 8) +) +Symbol('|' 12) +( + SymbolLine(0 10 0 50 8) +) +Symbol('}' 12) +( + SymbolLine(0 10 5 15 8) + SymbolLine(5 15 5 25 8) + SymbolLine(5 25 10 30 8) + SymbolLine(5 35 10 30 8) + SymbolLine(5 35 5 45 8) + SymbolLine(0 50 5 45 8) +) +Symbol('~' 12) +( + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 10 30 8) + SymbolLine(10 30 15 35 8) + SymbolLine(15 35 20 35 8) + SymbolLine(20 35 25 30 8) +) +Via[600000 1550000 75000 2000 0 50000 "" ""] +Via[600000 1710000 65000 2000 0 25000 "" ""] +Via[450000 1400000 100000 2000 0 50000 "" ""] +Via[600000 1400000 100000 2000 0 50000 "" ""] +Via[450000 1710000 65000 2000 0 25000 "" ""] +Via[450000 1550000 75000 2000 0 50000 "" ""] +Layer(1 "top") +( + Arc[775000 209000 491000 491000 1000 2000 180 -90 "clearline"] + Arc[772000 1183000 486000 486000 1000 2000 -90 90 "clearline"] + Arc[286000 697000 486000 486000 1000 2000 90 90 "clearline"] + Arc[1266000 700000 491000 491000 1000 2000 0 -90 "clearline"] +) +Layer(2 "ground") +( + Arc[2430000 209000 933000 933000 10000 2000 0 90 "clearline"] + Arc[1861000 778000 554000 554000 25000 2000 -90 -90 "clearline"] + Arc[1845000 750000 358000 358000 50000 2000 -90 -90 "clearline"] + Arc[1845000 729000 184000 184000 100000 2000 -90 -90 "clearline"] +) +Layer(3 "signal2") +( +) +Layer(4 "signal3") +( +) +Layer(5 "power") +( + Arc[2500000 1370000 1200000 400000 25000 1000 0 90 "clearline"] +) +Layer(6 "bottom") +( +) +Layer(7 "outline") +( +) +Layer(8 "spare") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) Index: tags/2.3.0/tests/orig/inputs/gerber_oneline.pcb =================================================================== --- tags/2.3.0/tests/orig/inputs/gerber_oneline.pcb (nonexistent) +++ tags/2.3.0/tests/orig/inputs/gerber_oneline.pcb (revision 33253) @@ -0,0 +1,829 @@ +# release: pcb 1.99y + +# To read pcb files, the pcb version (or the cvs source date) must be >= the file version +FileVersion[20070407] + +PCB["Basic Single Trace RS274-X Test" 200000 100000] + +Grid[10000.000000 0 0 1] +Cursor[0 500000 0.000000] +PolyArea[200000000.000000] +Thermal[0.500000] +DRC[1000 1000 1000 1000 1500 1000] +Flags("nameonpcb,uniquename,clearnew,snappin") +Groups("1,c:2,s:3:4:5:6:7:8") +Styles["Signal,1000,3600,2000,1000:Power,2500,6000,3500,1000:Fat,4000,6000,3500,1000:Skinny,600,2402,1181,600"] + +Symbol(' ' 18) +( +) +Symbol('!' 12) +( + SymbolLine(0 45 0 50 8) + SymbolLine(0 10 0 35 8) +) +Symbol('"' 12) +( + SymbolLine(0 10 0 20 8) + SymbolLine(10 10 10 20 8) +) +Symbol('#' 12) +( + SymbolLine(0 35 20 35 8) + SymbolLine(0 25 20 25 8) + SymbolLine(15 20 15 40 8) + SymbolLine(5 20 5 40 8) +) +Symbol('$' 12) +( + SymbolLine(15 15 20 20 8) + SymbolLine(5 15 15 15 8) + SymbolLine(0 20 5 15 8) + SymbolLine(0 20 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 40 8) + SymbolLine(15 45 20 40 8) + SymbolLine(5 45 15 45 8) + SymbolLine(0 40 5 45 8) + SymbolLine(10 10 10 50 8) +) +Symbol('%' 12) +( + SymbolLine(0 15 0 20 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 10 10 8) + SymbolLine(10 10 15 15 8) + SymbolLine(15 15 15 20 8) + SymbolLine(10 25 15 20 8) + SymbolLine(5 25 10 25 8) + SymbolLine(0 20 5 25 8) + SymbolLine(0 50 40 10 8) + SymbolLine(35 50 40 45 8) + SymbolLine(40 40 40 45 8) + SymbolLine(35 35 40 40 8) + SymbolLine(30 35 35 35 8) + SymbolLine(25 40 30 35 8) + SymbolLine(25 40 25 45 8) + SymbolLine(25 45 30 50 8) + SymbolLine(30 50 35 50 8) +) +Symbol('&' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 35 15 20 8) + SymbolLine(5 50 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(0 25 25 50 8) + SymbolLine(5 10 10 10 8) + SymbolLine(10 10 15 15 8) + SymbolLine(15 15 15 20 8) + SymbolLine(0 35 0 45 8) +) +Symbol(''' 12) +( + SymbolLine(0 20 10 10 8) +) +Symbol('(' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) +) +Symbol(')' 12) +( + SymbolLine(0 10 5 15 8) + SymbolLine(5 15 5 45 8) + SymbolLine(0 50 5 45 8) +) +Symbol('*' 12) +( + SymbolLine(0 20 20 40 8) + SymbolLine(0 40 20 20 8) + SymbolLine(0 30 20 30 8) + SymbolLine(10 20 10 40 8) +) +Symbol('+' 12) +( + SymbolLine(0 30 20 30 8) + SymbolLine(10 20 10 40 8) +) +Symbol(',' 12) +( + SymbolLine(0 60 10 50 8) +) +Symbol('-' 12) +( + SymbolLine(0 30 20 30 8) +) +Symbol('.' 12) +( + SymbolLine(0 50 5 50 8) +) +Symbol('/' 12) +( + SymbolLine(0 45 30 15 8) +) +Symbol('0' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 40 20 20 8) +) +Symbol('1' 12) +( + SymbolLine(5 50 15 50 8) + SymbolLine(10 10 10 50 8) + SymbolLine(0 20 10 10 8) +) +Symbol('2' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(0 50 25 25 8) + SymbolLine(0 50 25 50 8) +) +Symbol('3' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 30 20 30 8) +) +Symbol('4' 12) +( + SymbolLine(0 30 20 10 8) + SymbolLine(0 30 25 30 8) + SymbolLine(20 10 20 50 8) +) +Symbol('5' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(0 10 0 30 8) + SymbolLine(0 30 5 25 8) + SymbolLine(5 25 15 25 8) + SymbolLine(15 25 20 30 8) + SymbolLine(20 30 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('6' 12) +( + SymbolLine(15 10 20 15 8) + SymbolLine(5 10 15 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(15 30 20 35 8) + SymbolLine(0 30 15 30 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 35 20 45 8) +) +Symbol('7' 12) +( + SymbolLine(0 50 25 25 8) + SymbolLine(25 10 25 25 8) + SymbolLine(0 10 25 10 8) +) +Symbol('8' 12) +( + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 25 5 30 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 25 8) + SymbolLine(15 30 20 25 8) +) +Symbol('9' 12) +( + SymbolLine(0 50 20 30 8) + SymbolLine(20 15 20 30 8) + SymbolLine(15 10 20 15 8) + SymbolLine(5 10 15 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 20 30 8) +) +Symbol(':' 12) +( + SymbolLine(0 25 5 25 8) + SymbolLine(0 35 5 35 8) +) +Symbol(';' 12) +( + SymbolLine(0 50 10 40 8) + SymbolLine(10 25 10 30 8) +) +Symbol('<' 12) +( + SymbolLine(0 30 10 20 8) + SymbolLine(0 30 10 40 8) +) +Symbol('=' 12) +( + SymbolLine(0 25 20 25 8) + SymbolLine(0 35 20 35 8) +) +Symbol('>' 12) +( + SymbolLine(0 20 10 30 8) + SymbolLine(0 40 10 30 8) +) +Symbol('?' 12) +( + SymbolLine(10 30 10 35 8) + SymbolLine(10 45 10 50 8) + SymbolLine(0 15 0 20 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 20 8) + SymbolLine(10 30 20 20 8) +) +Symbol('@' 12) +( + SymbolLine(0 10 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 40 50 8) + SymbolLine(50 35 50 10 8) + SymbolLine(50 10 40 0 8) + SymbolLine(40 0 10 0 8) + SymbolLine(10 0 0 10 8) + SymbolLine(15 20 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 30 35 8) + SymbolLine(30 35 35 30 8) + SymbolLine(35 30 40 35 8) + SymbolLine(35 30 35 15 8) + SymbolLine(35 20 30 15 8) + SymbolLine(20 15 30 15 8) + SymbolLine(20 15 15 20 8) + SymbolLine(40 35 50 35 8) +) +Symbol('A' 12) +( + SymbolLine(0 15 0 50 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 50 8) + SymbolLine(0 30 25 30 8) +) +Symbol('B' 12) +( + SymbolLine(0 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 30 25 35 8) + SymbolLine(5 30 20 30 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) +) +Symbol('C' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 20 10 8) +) +Symbol('D' 12) +( + SymbolLine(5 10 5 50 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(0 50 20 50 8) + SymbolLine(0 10 20 10 8) +) +Symbol('E' 12) +( + SymbolLine(0 30 15 30 8) + SymbolLine(0 50 20 50 8) + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 20 10 8) +) +Symbol('F' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(0 30 15 30 8) +) +Symbol('G' 12) +( + SymbolLine(20 10 25 15 8) + SymbolLine(5 10 20 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 30 25 35 8) + SymbolLine(10 30 20 30 8) +) +Symbol('H' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(25 10 25 50 8) + SymbolLine(0 30 25 30 8) +) +Symbol('I' 12) +( + SymbolLine(0 10 10 10 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 50 10 50 8) +) +Symbol('J' 12) +( + SymbolLine(0 10 15 10 8) + SymbolLine(15 10 15 45 8) + SymbolLine(10 50 15 45 8) + SymbolLine(5 50 10 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('K' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 30 20 10 8) + SymbolLine(0 30 20 50 8) +) +Symbol('L' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 20 50 8) +) +Symbol('M' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 15 25 8) + SymbolLine(15 25 30 10 8) + SymbolLine(30 10 30 50 8) +) +Symbol('N' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 25 40 8) + SymbolLine(25 10 25 50 8) +) +Symbol('O' 12) +( + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('P' 12) +( + SymbolLine(5 10 5 50 8) + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) + SymbolLine(5 30 20 30 8) +) +Symbol('Q' 12) +( + SymbolLine(0 15 0 45 8) + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 15 10 8) + SymbolLine(15 10 20 15 8) + SymbolLine(20 15 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(10 40 20 50 8) +) +Symbol('R' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(20 10 25 15 8) + SymbolLine(25 15 25 25 8) + SymbolLine(20 30 25 25 8) + SymbolLine(5 30 20 30 8) + SymbolLine(5 10 5 50 8) + SymbolLine(5 30 25 50 8) +) +Symbol('S' 12) +( + SymbolLine(20 10 25 15 8) + SymbolLine(5 10 20 10 8) + SymbolLine(0 15 5 10 8) + SymbolLine(0 15 0 25 8) + SymbolLine(0 25 5 30 8) + SymbolLine(5 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('T' 12) +( + SymbolLine(0 10 20 10 8) + SymbolLine(10 10 10 50 8) +) +Symbol('U' 12) +( + SymbolLine(0 10 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 10 20 45 8) +) +Symbol('V' 12) +( + SymbolLine(0 10 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(20 10 20 40 8) +) +Symbol('W' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 15 35 8) + SymbolLine(15 35 30 50 8) + SymbolLine(30 10 30 50 8) +) +Symbol('X' 12) +( + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 25 40 8) + SymbolLine(25 40 25 50 8) + SymbolLine(0 40 0 50 8) + SymbolLine(0 40 25 15 8) + SymbolLine(25 10 25 15 8) +) +Symbol('Y' 12) +( + SymbolLine(0 10 0 15 8) + SymbolLine(0 15 10 25 8) + SymbolLine(10 25 20 15 8) + SymbolLine(20 10 20 15 8) + SymbolLine(10 25 10 50 8) +) +Symbol('Z' 12) +( + SymbolLine(0 10 25 10 8) + SymbolLine(25 10 25 15 8) + SymbolLine(0 40 25 15 8) + SymbolLine(0 40 0 50 8) + SymbolLine(0 50 25 50 8) +) +Symbol('[' 12) +( + SymbolLine(0 10 5 10 8) + SymbolLine(0 10 0 50 8) + SymbolLine(0 50 5 50 8) +) +Symbol('\' 12) +( + SymbolLine(0 15 30 45 8) +) +Symbol(']' 12) +( + SymbolLine(0 10 5 10 8) + SymbolLine(5 10 5 50 8) + SymbolLine(0 50 5 50 8) +) +Symbol('^' 12) +( + SymbolLine(0 15 5 10 8) + SymbolLine(5 10 10 15 8) +) +Symbol('_' 12) +( + SymbolLine(0 50 20 50 8) +) +Symbol('a' 12) +( + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(20 30 20 45 8) + SymbolLine(20 45 25 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('b' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) +) +Symbol('c' 12) +( + SymbolLine(5 30 20 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 20 50 8) +) +Symbol('d' 12) +( + SymbolLine(20 10 20 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) +) +Symbol('e' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(0 45 5 50 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(0 40 20 40 8) + SymbolLine(20 40 20 35 8) +) +Symbol('f' 10) +( + SymbolLine(5 15 5 50 8) + SymbolLine(5 15 10 10 8) + SymbolLine(10 10 15 10 8) + SymbolLine(0 30 10 30 8) +) +Symbol('g' 12) +( + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(0 60 5 65 8) + SymbolLine(5 65 15 65 8) + SymbolLine(15 65 20 60 8) + SymbolLine(20 30 20 60 8) +) +Symbol('h' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) +) +Symbol('i' 10) +( + SymbolLine(0 20 0 25 8) + SymbolLine(0 35 0 50 8) +) +Symbol('j' 10) +( + SymbolLine(5 20 5 25 8) + SymbolLine(5 35 5 60 8) + SymbolLine(0 65 5 60 8) +) +Symbol('k' 12) +( + SymbolLine(0 10 0 50 8) + SymbolLine(0 35 15 50 8) + SymbolLine(0 35 10 25 8) +) +Symbol('l' 10) +( + SymbolLine(0 10 0 45 8) + SymbolLine(0 45 5 50 8) +) +Symbol('m' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) + SymbolLine(20 35 25 30 8) + SymbolLine(25 30 30 30 8) + SymbolLine(30 30 35 35 8) + SymbolLine(35 35 35 50 8) + SymbolLine(0 30 5 35 8) +) +Symbol('n' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 50 8) + SymbolLine(0 30 5 35 8) +) +Symbol('o' 12) +( + SymbolLine(0 35 0 45 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 15 30 8) + SymbolLine(15 30 20 35 8) + SymbolLine(20 35 20 45 8) + SymbolLine(15 50 20 45 8) + SymbolLine(5 50 15 50 8) + SymbolLine(0 45 5 50 8) +) +Symbol('p' 12) +( + SymbolLine(5 35 5 65 8) + SymbolLine(0 30 5 35 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(25 35 25 45 8) + SymbolLine(20 50 25 45 8) + SymbolLine(10 50 20 50 8) + SymbolLine(5 45 10 50 8) +) +Symbol('q' 12) +( + SymbolLine(20 35 20 65 8) + SymbolLine(15 30 20 35 8) + SymbolLine(5 30 15 30 8) + SymbolLine(0 35 5 30 8) + SymbolLine(0 35 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('r' 12) +( + SymbolLine(5 35 5 50 8) + SymbolLine(5 35 10 30 8) + SymbolLine(10 30 20 30 8) + SymbolLine(0 30 5 35 8) +) +Symbol('s' 12) +( + SymbolLine(5 50 20 50 8) + SymbolLine(20 50 25 45 8) + SymbolLine(20 40 25 45 8) + SymbolLine(5 40 20 40 8) + SymbolLine(0 35 5 40 8) + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 20 30 8) + SymbolLine(20 30 25 35 8) + SymbolLine(0 45 5 50 8) +) +Symbol('t' 10) +( + SymbolLine(5 10 5 45 8) + SymbolLine(5 45 10 50 8) + SymbolLine(0 25 10 25 8) +) +Symbol('u' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) + SymbolLine(20 30 20 45 8) +) +Symbol('v' 12) +( + SymbolLine(0 30 0 40 8) + SymbolLine(0 40 10 50 8) + SymbolLine(10 50 20 40 8) + SymbolLine(20 30 20 40 8) +) +Symbol('w' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(5 50 10 50 8) + SymbolLine(10 50 15 45 8) + SymbolLine(15 30 15 45 8) + SymbolLine(15 45 20 50 8) + SymbolLine(20 50 25 50 8) + SymbolLine(25 50 30 45 8) + SymbolLine(30 30 30 45 8) +) +Symbol('x' 12) +( + SymbolLine(0 30 20 50 8) + SymbolLine(0 50 20 30 8) +) +Symbol('y' 12) +( + SymbolLine(0 30 0 45 8) + SymbolLine(0 45 5 50 8) + SymbolLine(20 30 20 60 8) + SymbolLine(15 65 20 60 8) + SymbolLine(5 65 15 65 8) + SymbolLine(0 60 5 65 8) + SymbolLine(5 50 15 50 8) + SymbolLine(15 50 20 45 8) +) +Symbol('z' 12) +( + SymbolLine(0 30 20 30 8) + SymbolLine(0 50 20 30 8) + SymbolLine(0 50 20 50 8) +) +Symbol('{' 12) +( + SymbolLine(5 15 10 10 8) + SymbolLine(5 15 5 25 8) + SymbolLine(0 30 5 25 8) + SymbolLine(0 30 5 35 8) + SymbolLine(5 35 5 45 8) + SymbolLine(5 45 10 50 8) +) +Symbol('|' 12) +( + SymbolLine(0 10 0 50 8) +) +Symbol('}' 12) +( + SymbolLine(0 10 5 15 8) + SymbolLine(5 15 5 25 8) + SymbolLine(5 25 10 30 8) + SymbolLine(5 35 10 30 8) + SymbolLine(5 35 5 45 8) + SymbolLine(0 50 5 45 8) +) +Symbol('~' 12) +( + SymbolLine(0 35 5 30 8) + SymbolLine(5 30 10 30 8) + SymbolLine(10 30 15 35 8) + SymbolLine(15 35 20 35 8) + SymbolLine(20 35 25 30 8) +) +Via[90000 50000 6000 2000 0 3500 "" ""] +Layer(1 "component") +( + Line[10000 50000 90000 50000 4000 2000 "clearline"] +) +Layer(2 "solder") +( + Line[170000 50000 90000 50000 4000 2000 "clearline"] +) +Layer(3 "GND") +( +) +Layer(4 "power") +( +) +Layer(5 "signal1") +( +) +Layer(6 "signal2") +( +) +Layer(7 "signal3") +( +) +Layer(8 "signal4") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) Index: tags/2.3.0/tests/orig/run_tests.sh =================================================================== --- tags/2.3.0/tests/orig/run_tests.sh (nonexistent) +++ tags/2.3.0/tests/orig/run_tests.sh (revision 33253) @@ -0,0 +1,677 @@ +#!/bin/sh +# +# $Id: run_tests.sh,v 1.8 2009/02/17 00:42:31 danmc Exp $ +# +# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2009, 2010 Dan McMahill + +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation +# +# 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. +# All rights reserved. +# +# This code was derived from code written by Dan McMahill as part of the +# latex-mk testsuite. The original code was covered by a BSD license +# but the copyright holder (Dan McMahill) has re-released the code under +# the GPL. + +if test -z `which gerbv` +then + echo "Please install gerbv before running the tests." >&2 + exit 1 +fi + +if test -z `which convert` +then + echo "Please install imagemagick before running the tests." >&2 + exit 1 +fi + +magic_test_skip=${PCB_MAGIC_TEST_SKIP:-no} + +if test "x${magic_test_skip}" = "xyes" ; then + cat << EOF + +The environment variable PCB_MAGIC_TEST_SKIP is set to yes. +This causes the testsuite to skip all tests and report no errors. +This is used for certain debugging *only*. The primary use is to +allow testing of the 'distcheck' target without including the effects +of the testsuite. The reason this is useful is that due to minor differences +in library versions and perhaps roundoff in different CPU's, the testsuite +may falsely report failures on some systems. These reported failures +prevent using 'distcheck' for verifying the rest of the build system. +These comments only apply to the tests which try to compare image files +like PNG files. + +EOF + + exit 0 +fi + +regen=no + +usage() { +cat < : Specifies that should be used for the + reference files. + +LIMITATIONS + +- The GUI interface is not checked via the regression testsuite. + +- Currently actions are also not exercised + +EOF +} + +show_sep() { + echo "----------------------------------------------------------------------" +} + +########################################################################## +# +# debug print out +# + +do_debug=no +debug() { + if test $do_debug = yes ; then + cat < $f2 +} + +# top level function to compare BOM output +compare_bom() { + f1="$1" + f2="$2" + compare_check "compare_bom" "$f1" "$f2" || return 1 + + # an example BOM file is: + + # # $Id$ + # # PcbBOM Version 1.0 + # # Date: Wed Jun 17 14:41:43 2009 UTC + # # Author: Dan McMahill + # # Title: Basic BOM/XY Test - PCB BOM + # # Quantity, Description, Value, RefDes + # # -------------------------------------------- + # 8,"Standard SMT resistor, capacitor etc","RESC3216N",R90_TOP R180_TOP R270_TOP R0_TOP R270_BOT R180_BOT R90_BOT R0_BOT + # 8,"Dual in-line package, narrow (300 mil)","DIP8",UDIP90_TOP UDIP180_TOP UDIP270_TOP UDIP0_TOP UDIP270_BOT UDIP180_BOT UDIP90_BOT UDIP0_BOT + # 8,"Small outline package, narrow (150mil)","SO8",USO90_TOP USO180_TOP USO270_TOP USO0_TOP USO270_BOT USO180_BOT USO90_BOT USO0_BOT + + # For comparison, we need to ignore changes in the Date and Author lines. + cf1=${tmpd}/`basename $f1` + cf2=${tmpd}/`basename $f2` + + normalize_bom $f1 $cf1 + normalize_bom $f2 $cf2 + run_diff $cf1 $cf2 || test_failed=yes +} + +########################################################################## +# +# X-Y (centroid) comparison routines +# + +# used to remove things like creation date from BOM files +normalize_xy() { + f1="$1" + f2="$2" + $AWK ' + /^# Date:/ {print "# Date: today"; next} + /^# Author:/ {print "# Author: PCB"; next} + {print}' \ + $f1 > $f2 +} + +compare_xy() { + f1="$1" + f2="$2" + compare_check "compare_xy" "$f1" "$f2" || return 1 + normalize_xy "$f1" "$cf1" + normalize_xy "$f2" "$cf2" + run_diff "$cf1" "$cf2" || test_failed=yes +} + +########################################################################## +# +# GCODE comparison routines +# + +# used to remove things like creation date from gcode files +normalize_gcode() { + f1="$1" + f2="$2" + $AWK ' + d == 1 {gsub(/ .* /, "Creation Date and Time"); d = 0;} + /^\(Created by G-code exporter\)/ {d=1} + {print}' \ + $f1 > $f2 +} + +compare_gcode() { + f1="$1" + f2="$2" + compare_check "compare_gcode" "$f1" "$f2" || return 1 + + # For comparison, we need to ignore changes in the Date and Author lines. + cf1=${tmpd}/`basename $f1` + cf2=${tmpd}/`basename $f2` + + normalize_gcode $f1 $cf1 + normalize_gcode $f2 $cf2 + run_diff "$cf1" "$cf2" || test_failed=yes +} + +########################################################################## +# +# RS274-X and Excellon comparison +# + +compare_rs274x() { + f1="$1" + f2="$2" + compare_check "compare_rs274x" "$f1" "$f2" || return 1 + + # use gerbv to export our reference RS274-X file and our generated + # RS274-X file to png. Then we'll use ImageMagick to see + # if there are any differences in the resulting files + pngdir=${rundir}/png + mkdir -p ${pngdir} + nb=`basename $f1` + png1=${pngdir}/${nb}-ref.png + png2=${pngdir}/${nb}-out.png + + debug "${GERBV} ${GERBV_DEFAULT_FLAGS} --output=${png1} ${f1}" + ${GERBV} ${GERBV_DEFAULT_FLAGS} --output=${png1} ${f1} + + debug "${GERBV} ${GERBV_DEFAULT_FLAGS} --output=${png2} ${f2}" + ${GERBV} ${GERBV_DEFAULT_FLAGS} --output=${png2} ${f2} + + compare_image ${png1} ${png2} + +} + +compare_cnc() { + compare_rs274x $* +} + +########################################################################## +# +# GIF/JPEG/PNG comparison routines +# + +compare_image() { + f1="$1" + f2="$2" + compare_check "compare_image" "$f1" "$f2" || return 1 + + # now see if the image files are the same + debug "${IM_COMPARE} -metric MAE ${f1} ${f2} null:" + same=`${IM_COMPARE} -metric MAE ${f1} ${f2} null: 2>&1 | \ + ${AWK} '{if($1 == 0){print "yes"} else {print "no"}}'` + debug "compare_image(): same = $same" + + if test "$same" != yes ; then + test_failed=yes + echo "FAILED: See ${errdir}" + mkdir -p ${errdir} + ${IM_COMPARE} ${f1} ${f2} ${errdir}/compare.png + ${IM_COMPOSITE} ${f1} ${f2} -compose difference ${errdir}/composite.png + ${IM_CONVERT} ${f1} ${f2} -compose difference -composite -colorspace gray ${errdir}/gray.png + cat > ${errdir}/animate.sh << EOF +#!/bin/sh +${IM_CONVERT} -label "%f" ${f1} ${f2} miff:- | \ +${IM_MONTAGE} - -geometry +0+0 -tile 1x1 miff:- | \ +${IM_ANIMATE} -delay 0.5 -loop 0 - +EOF + chmod a+x ${errdir}/animate.sh + fi +} + +########################################################################## +# +# The main program loop +# + +for t in $all_tests ; do + show_sep + echo "Test: $t" + + tot=`expr $tot + 1` + + ###################################################################### + # + # extract the details for the test + # + + pcb_flags="${PCB_DEFAULT_FLAGS}" + + rundir="${OUTDIR}/${t}" + refdir="${REFDIR}/${t}" + errdir=${rundir}/mismatch + + # test_name | layout file(s) | [export hid name] | [optional arguments to pcb] | [mismatch] + # | output files + name=`grep "^[ \t]*${t}[ \t]*|" $TESTLIST | $AWK 'BEGIN{FS="|"} {print $1}'` + files=`grep "^[ \t]*${t}[ \t]*|" $TESTLIST | $AWK 'BEGIN{FS="|"} {print $2}'` + hid=`grep "^[ \t]*${t}[ \t]*|" $TESTLIST | $AWK 'BEGIN{FS="|"} {gsub(/[ \t]*/, ""); print $3}'` + args=`grep "^[ \t]*${t}[ \t]*|" $TESTLIST | $AWK 'BEGIN{FS="|"} {print $4}'` + mismatch=`grep "^[ \t]*${t}[ \t]*|" $TESTLIST | $AWK 'BEGIN{FS="|"} {if($5 == "mismatch"){print "yes"}else{print "no"}}'` + out_files=`grep "^[ \t]*${t}[ \t]*|" $TESTLIST | $AWK 'BEGIN{FS="|"} {print $6}'` + + if test "X${name}" = "X" ; then + echo "ERROR: Specified test ${t} does not appear to exist" + skip=`expr $skip + 1` + continue + fi + + if test "X${args}" != "X" ; then + pcb_flags="${args}" + fi + + ###################################################################### + # + # Set up the run directory + # + + test -d ${rundir} && rm -fr ${rundir} + mkdir -p ${rundir} + if test $? -ne 0 ; then + echo "$0: Could not create run directory ${rundir}" + skip=`expr $skip + 1` + continue + fi + + + ###################################################################### + # + # check to see if the files we need exist and copy them to the run + # directory + # + + missing_files=no + path_files="" + for f in $files ; do + if test ! -f ${INDIR}/${f} ; then + echo "ERROR: File $f specified as part of the $t test does not exist" + missing_files=yes + else + path_files="${path_files} ${INDIR}/${f}" + cp "${INDIR}/${f}" "${rundir}" + fi + done + + if test "$missing_files" = "yes" ; then + echo "${t} had missing input files. Skipping test" + skip=`expr $skip + 1` + continue + fi + + ###################################################################### + # + # run PCB + # + + echo "cd ${rundir} && ${PCB} -x ${hid} ${pcb_flags} ${files}" + (cd ${rundir} && ${PCB} -x ${hid} ${pcb_flags} ${files}) + pcb_rc=$? + + if test $pcb_rc -ne 0 ; then + echo "${PCB} returned ${pcb_rc}. This is a failure." + fail=`expr $fail + 1` + continue + fi + + # and clean up the input files we'd copied over + for f in $files ; do + rm -f ${rundir}/${f} + done + + ###################################################################### + # + # check the result + # + + if test "X$regen" = "Xyes" ; then + echo "Regenerated ${t}" + else + # compare the result to our reference file + test_failed=no + test_skipped=no + for f in $out_files ; do + debug "processing $f" + # break apart type:fn into the type and file name + type=`echo $f | sed 's;:.*;;g'` + fn=`echo $f | sed 's;.*:;;g'` + + case $type in + # BOM HID + bom) + compare_bom ${refdir}/${fn} ${rundir}/${fn} + ;; + + xy) + compare_xy ${refdir}/${fn} ${rundir}/${fn} + ;; + + # GCODE HID + gcode) + compare_gcode ${refdir}/${fn} ${rundir}/${fn} + ;; + + # GERBER HID + cnc) + compare_cnc ${refdir}/${fn} ${rundir}/${fn} + ;; + + gbx) + compare_rs274x ${refdir}/${fn} ${rundir}/${fn} + ;; + + # PNG HID + gif) + compare_image ${refdir}/${fn} ${rundir}/${fn} + ;; + + jpg) + compare_image ${refdir}/${fn} ${rundir}/${fn} + ;; + + png) + compare_image ${refdir}/${fn} ${rundir}/${fn} + ;; + + # unknown + *) + echo "internal error: $type is not a known file type" + exit 1 + ;; + esac + + done + + + if test $test_failed = yes ; then + echo "FAIL" + fail=`expr $fail + 1` + elif test $test_skipped = yes ; then + echo "SKIPPED" + skip=`expr $skip + 1` + else + echo "PASSED" + pass=`expr $pass + 1` + fi + + fi + +done + +show_sep +echo "Passed $pass, failed $fail, skipped $skip out of $tot tests." + +rc=0 +if test $pass -ne $tot ; then + rc=1 +fi + +exit $rc + Property changes on: tags/2.3.0/tests/orig/run_tests.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/orig/tests.list =================================================================== --- tags/2.3.0/tests/orig/tests.list (nonexistent) +++ tags/2.3.0/tests/orig/tests.list (revision 33253) @@ -0,0 +1,173 @@ +# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2009, 2010 Dan McMahill +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation +# +# 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. +# All rights reserved. +# +# This code was derived from code written by Dan McMahill as part of the +# latex-mk testsuite. The original code was covered by a BSD license +# but the copyright holder is releasing the version for pcb under the GPL. +# +# +# Format: +# +# test_name | layout file(s) | [export hid name] | [optional arguments to pcb] | [mismatch] +# | output file(s) +# +# test_name - a single string with no spaces, tabs, *, +, ? (i.e. any "special" +# characters) that identifies the test. +# +# layout file(s) - a list of layout files. Files listed are relative to +# the $(top_srcdir)/tests/inputs directory. +# +# [export hid name] - the name of the export HID to use. This is used both for +# running pcb as well as determining how we process the output +# +# [optional arguments to pcb] - a list of additional arguments to be passed to pcb. +# This is where one would specify additional options which are specific to a particular +# export HID. +# +# [mismatch] If specified as "mismatch" (no quotes), then the result +# should *not* match the reference. This can be thought of as a test +# on the testsuite to make sure we can properly detect when a change has +# occurred. +# +# output file(s) - a list of output files and their associated types. For +# example: +# bom:bom_general.bom xy:test.txt +# specifies that "bom_general.bom" is created and it is a bill of materials file +# and that "test.txt" is created and it is a centroid (X-Y) file. +# +# File types grouped by which HID produces them are: +# +# BOM +# +# bom -- PCB bill of materials file +# xy -- PCB centroid file +# +# GCODE +# +# gcode -- G-Code file. Note that these typically have .cnc as the +# extension but we're already using the 'cnc' type for +# Excellon drill files. +# +# GERBER +# +# cnc -- Excellon drill file +# gbx -- RS274-X (Gerber) file +# +# PNG +# +# gif -- GIF file +# jpg -- JPEG file +# png -- Portable network graphics (PNG) file +# +###################################################################### +# --------------------------------------------- +# BOM export HID +# --------------------------------------------- +###################################################################### +# +# options: +# --bomfile BOM output file +# --xyfile XY output file +# --xy-in-mm XY dimensions in mm instead of mils +# +# +# Produces a bill of materials (BOM) file and a centroid (XY) file +# +hid_bom1 | bom_general.pcb | bom | | | bom:bom_general.bom +hid_bom2 | bom_general.pcb | bom | --bomfile test.bom | | bom:test.bom +hid_bom3 | bom_general.pcb | bom | | | bom:bom_general.bom +hid_bom4 | bom_general.pcb | bom | | | bom:bom_general.bom + +hid_xy1 | bom_general.pcb | XY | | | xy:bom_general.xy +hid_xy2 | bom_general.pcb | XY | | | xy:bom_general.xy +hid_xy3 | bom_general.pcb | XY | --xyfile test.xy | | xy:test.xy +hid_xy4 | bom_general.pcb | XY | --xy-in-mm | | xy:bom_general.xy + + + +###################################################################### +# --------------------------------------------- +# Gcode export HID +# --------------------------------------------- +###################################################################### +# +# options: +# --basename File name prefix +# --dpi Resolution of intermediate image (pixels/inch). +# --mill depth Milling depth. +# --safe Z Safe Z for traverse move. +# --tool radius Milling tool radius compensation. +# --drill depth Drilling depth. +# --measurement unit Measurement unit +# +hid_gcode1 | gcode_oneline.pcb | gcode | | | gcode:gcode_oneline.gcode.top.cnc gcode:gcode_oneline.gcode.bottom.cnc gcode:gcode_oneline.gcode.drill.cnc +hid_gcode2 | gcode_oneline.pcb | gcode | --basename out | | gcode:out.top.cnc gcode:out.bottom.cnc gcode:out.drill.cnc +hid_gcode3 | gcode_oneline.pcb | gcode | --dpi 1200 | | gcode:gcode_oneline.gcode.top.cnc gcode:gcode_oneline.gcode.bottom.cnc gcode:gcode_oneline.gcode.drill.cnc +hid_gcode4 | gcode_oneline.pcb | gcode | --mill-depth 5 | | gcode:gcode_oneline.gcode.top.cnc gcode:gcode_oneline.gcode.bottom.cnc gcode:gcode_oneline.gcode.drill.cnc +hid_gcode5 | gcode_oneline.pcb | gcode | --safe-Z 10 | | gcode:gcode_oneline.gcode.top.cnc gcode:gcode_oneline.gcode.bottom.cnc gcode:gcode_oneline.gcode.drill.cnc +hid_gcode6 | gcode_oneline.pcb | gcode | --tool-radius 15 | | gcode:gcode_oneline.gcode.top.cnc gcode:gcode_oneline.gcode.bottom.cnc gcode:gcode_oneline.gcode.drill.cnc +hid_gcode7 | gcode_oneline.pcb | gcode | --drill-depth 70 | | gcode:gcode_oneline.gcode.top.cnc gcode:gcode_oneline.gcode.bottom.cnc gcode:gcode_oneline.gcode.drill.cnc +hid_gcode8 | gcode_oneline.pcb | gcode | --measurement-unit mm | | gcode:gcode_oneline.gcode.top.cnc gcode:gcode_oneline.gcode.bottom.cnc gcode:gcode_oneline.gcode.drill.cnc +hid_gcode9 | gcode_oneline.pcb | gcode | --measurement-unit mil | | gcode:gcode_oneline.gcode.top.cnc gcode:gcode_oneline.gcode.bottom.cnc gcode:gcode_oneline.gcode.drill.cnc +hid_gcode10 | gcode_oneline.pcb | gcode | --measurement-unit um | | gcode:gcode_oneline.gcode.top.cnc gcode:gcode_oneline.gcode.bottom.cnc gcode:gcode_oneline.gcode.drill.cnc +hid_gcode11 | gcode_oneline.pcb | gcode | --measurement-unit inch | | gcode:gcode_oneline.gcode.top.cnc gcode:gcode_oneline.gcode.bottom.cnc gcode:gcode_oneline.gcode.drill.cnc +# +###################################################################### +# --------------------------------------------- +# Gerber export HID +# --------------------------------------------- +###################################################################### +# +# options: +# --gerberfile Basename for output file +# +# Produces RS274-X (a.k.a. gerber) photo plot files and Excellon drill files +# +# we can't include gbx:gerber_oneline.fab.gbr yet because it has a name and a date stamp +hid_gerber1 | gerber_oneline.pcb | gerber | | | gbx:gerber_oneline.bottom.gbr gbx:gerber_oneline.top.gbr cnc:gerber_oneline.plated-drill.cnc +hid_gerber2 | gerber_oneline.pcb | gerber | --gerberfile out | | gbx:out.bottom.gbr gbx:out.top.gbr cnc:out.plated-drill.cnc +hid_gerber3 | gerber_arcs.pcb | gerber | --gerberfile arcs | | gbx:arcs.top.gbr gbx:arcs.group11.gbr gbx:arcs.group5.gbr cnc:arcs.plated-drill.cnc +# + + +###################################################################### +# --------------------------------------------- +# PNG export HID +# --------------------------------------------- +###################################################################### +# +# options: +# --outfile Graphics output file +# --dpi Scale factor (pixels/inch). 0 to scale to fix specified size +# --x-max Maximum width (pixels). 0 to not constrain. +# --y-max Maximum height (pixels). 0 to not constrain. +# --xy-max Maximum width and height (pixels). 0 to not constrain. +# --as-shown Export layers as shown on screen +# --monochrome Convert to monochrome +# --only-visible Limit the bounds of the PNG file to the visible items +# --use-alpha Make the bottomground and any holes transparent +# --format Graphics file format +# --photo-mode Photo-realistic mode +# --photo-flip-x Show reverse side of the board, left-right flip +# --photo-flip-y Show reverse side of the board, up-down flip +# +# Produces GIF/JPEG/PNG (image) files +# +hid_png1 | gerber_oneline.pcb | png | | | png:gerber_oneline.png +hid_png2 | gerber_oneline.pcb | png | --outfile myfile.png | | png:myfile.png +#hid_png3 | gerber_oneline.pcb | png | --dpi 300 | | png:gerber_oneline.png +# + Index: tags/2.3.0/tests/pcb-printf/Makefile =================================================================== --- tags/2.3.0/tests/pcb-printf/Makefile (nonexistent) +++ tags/2.3.0/tests/pcb-printf/Makefile (revision 33253) @@ -0,0 +1,62 @@ +TRUNK = ../.. + +all: tester tester_spd prcli prclimq + +ROOT=../.. +include $(ROOT)/Makefile.conf + +SRC=$(TRUNK)/src +SRC_3RD=$(TRUNK)/src_3rd +LIBRND=$(SRC_3RD)/librnd +CFLAGS_OP = -O3 +CFLAGS = $(PCB_RND_C89FLAGS) -I$(TRUNK) -I$(SRC) -I$(TRUNK)/src_3rd -I$(TRUNK)/src_3rd/liblihata +LDLIBS = -lm + +GDS= $(TRUNK)/src_3rd/genvector/gds_char.o +LIBPCB_BASE= $(LIBRND)/core/unit.o $(LIBRND)/core/compat_misc.o + + +test: tester.diff + @echo "pcb-printf: *** QC PASS ***" + @rm tester.stdout ; true + +prcli: prcli.o $(LIBRND)/core/rnd_printf.o $(LIBRND)/core/misc_util.o $(LIBPCB_BASE) $(GDS) + $(CC) $(LDFLAGS) -o prcli prcli.o $(LIBRND)/core/rnd_printf.o $(LIBRND)/core/misc_util.o $(LIBPCB_BASE) $(GDS) $(LDLIBS) + +prclimq: prclimq.o $(LIBRND)/core/rnd_printf.o $(LIBRND)/core/misc_util.o $(LIBPCB_BASE) $(GDS) + $(CC) $(LDFLAGS) -o prclimq prclimq.o $(LIBRND)/core/rnd_printf.o $(LIBRND)/core/misc_util.o $(LIBPCB_BASE) $(GDS) $(LDLIBS) + +prcli.o: prcli.c + $(CC) -c $(CFLAGS) prcli.c -o prcli.o + +prclimq.o: prclimq.c + $(CC) -c $(CFLAGS) prclimq.c -o prclimq.o + +tester: tester.o $(LIBRND)/core/rnd_printf.o $(LIBPCB_BASE) $(GDS) + $(CC) $(LDFLAGS) -o tester tester.o $(LIBRND)/core/rnd_printf.o $(LIBPCB_BASE) $(GDS) $(LDLIBS) + +tester_spd: tester_spd.o $(LIBRND)/core/rnd_printf_spd.o $(LIBPCB_BASE) $(GDS) + $(CC) $(LDFLAGS) -o tester_spd tester_spd.o $(LIBRND)/core/rnd_printf_spd.o $(LIBPCB_BASE) $(GDS) $(LDLIBS) + +tester.o: tester.c + $(CC) -c $(CFLAGS) -o $@ tester.c + +tester_spd.o: tester.c + $(CC) -c $(CFLAGS_OP) -DSPEED $(CFLAGS) -o $@ tester.c + +tester.stdout: tester + ./tester > tester.stdout + +tester.diff: tester.stdout + diff -u tester.ref tester.stdout + +$(LIBRND)/core/rnd_printf.o: $(LIBRND)/core/rnd_printf.c $(LIBRND)/core/rnd_printf.h + +$(LIBRND)/core/unit.o: $(LIBRND)/core/unit.c $(LIBRND)/core/unit.h + +$(LIBRND)/core/rnd_printf_spd.o: $(LIBRND)/core/rnd_printf.c $(LIBRND)/core/rnd_printf.h + $(CC) -c $(CFLAGS_OP) -DSPEED $(CFLAGS) -o $@ $(LIBRND)/core/rnd_printf.c + +clean: + -$(SCCBOX) rm -f tester tester.o prcli prcli.o tester_spd tester_spd.o prclimq prclimq.o $(LIBRND)/core/rnd_printf_spd.o + Index: tags/2.3.0/tests/pcb-printf/prcli.c =================================================================== --- tags/2.3.0/tests/pcb-printf/prcli.c (nonexistent) +++ tags/2.3.0/tests/pcb-printf/prcli.c (revision 33253) @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + const char *fmt = argv[1]; + rnd_coord_t crd; + int n; + + setlocale(LC_ALL, "C"); + + rnd_printf_slot[0] = "%mr"; + + for(n = 2; n < argc; n++) { + rnd_bool success; + double val = rnd_get_value_ex(argv[n], NULL, NULL, NULL, "", &success); + if (!success) { + fprintf(stderr, "Unable to convert '%s' to rnd_coord_t\n", argv[n]); + return 1; + } + crd = val; + } + + rnd_fprintf(stdout, fmt, crd, 70000, 70000, 70000, 70000); + + printf("\n"); + + return 0; +} Index: tags/2.3.0/tests/pcb-printf/prclimq.c =================================================================== --- tags/2.3.0/tests/pcb-printf/prclimq.c (nonexistent) +++ tags/2.3.0/tests/pcb-printf/prclimq.c (revision 33253) @@ -0,0 +1,14 @@ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + rnd_printf_slot[0] = "%{ ()}mq"; + setlocale(LC_ALL, "C"); + rnd_fprintf(stdout, argv[1], argv[2]); + printf("\n"); + return 0; +} Index: tags/2.3.0/tests/pcb-printf/tester.c =================================================================== --- tags/2.3.0/tests/pcb-printf/tester.c (nonexistent) +++ tags/2.3.0/tests/pcb-printf/tester.c (revision 33253) @@ -0,0 +1,74 @@ +#include +#include +#include "config.h" +#include + +#ifdef SPEED + char buff[8192]; + int pc = 0; +# define NUMREP 4000 +# define PCB_PRINTF(fmt, ...) \ + do { \ + pc++; \ + rnd_snprintf(buff, sizeof(buff), fmt, __VA_ARGS__); \ + } while(0) +#else +# define NUMREP 1 +# define PCB_PRINTF rnd_printf +#endif + +int main() +{ + rnd_coord_t c[] = {0, 1, 1024, 1024*1024, 1024*1024*1024}; + char *fmt[] = { + "%mI", "%mm", "%mM", "%ml", "%mL", "%ms", "%mS", "%md", "%mD", "%m3", "%mr", + "%$mI", "%$mm", "%$mM", "%$ml", "%$mL", "%$ms", "%$mS", "%$md", "%$mD", "%$m3", "%$mr", + NULL }; + char **f; + int n, rep; + + setlocale(LC_ALL, "C"); + + for(rep = 0; rep < NUMREP; rep++) { + for(n = 0; n < sizeof(c) / sizeof(c[0]); n++) { +#ifndef SPEED + printf("---------------\n"); +#endif + /* common format strings */ + for(f = fmt; *f != NULL; f++) { + char fmt_tmp[32]; + sprintf(fmt_tmp, "%s=%s\n", (*f)+1, *f); + PCB_PRINTF(fmt_tmp, c[n], c[n], c[n]); + } + + /* special: custom argument list */ + PCB_PRINTF("m*=%m* mil\n", "mil", c[n]); + PCB_PRINTF("m*=%m* mm\n", "mm", c[n]); + + PCB_PRINTF("ma=%ma\n", 1.1234); + PCB_PRINTF("ma=%ma\n", 130.1234); + PCB_PRINTF("ma=%ma\n", 555.1234); + + PCB_PRINTF("m+=%m+%mS mil\n", RND_UNIT_ALLOW_MIL, c[n]); + PCB_PRINTF("m+=%m+%mS mm\n", RND_UNIT_ALLOW_MM, c[n]); + PCB_PRINTF("m+=%m+%mS m\n", RND_UNIT_ALLOW_M, c[n]); + PCB_PRINTF("m+=%m+%mS mm or m\n", RND_UNIT_ALLOW_MM | RND_UNIT_ALLOW_M, c[n]); + } +#ifndef SPEED + printf("---------------\n"); +#endif + PCB_PRINTF("mf=%.08mf\n", (double)1.2345); + } + +#ifdef SPEED + { + double spent = (double)clock() / (double)CLOCKS_PER_SEC; + printf("total number of rnd_printf calls: %d\n", pc); + printf("total number of CPU seconds spent: %.4f\n", spent); + printf("Average prints per second: %.4f\n", (double)pc/spent); + } +#endif + return 0; +} + + Index: tags/2.3.0/tests/pcb-printf/tester.ref =================================================================== --- tags/2.3.0/tests/pcb-printf/tester.ref (nonexistent) +++ tags/2.3.0/tests/pcb-printf/tester.ref (revision 33253) @@ -0,0 +1,162 @@ +--------------- +mI=0 +mm=0.0000 +mM=0 +ml=0.00 +mL=0 +ms=0.0000 +mS=0 +md=(0.0000, 0.0000) +mD=(0, 0) +m3=(0, 0, 0) +mr=0 +$mI=0 +$mm=0.0000 +$mM=0 +$ml=0.00 +$mL=0 +$ms=0.0000 +$mS=0 +$md=(0.0000, 0.0000) mm +$mD=(0, 0) nm +$m3=(0, 0, 0) nm +$mr=0 +m*=0.00 mil +m*=0.0000 mm +ma=1.123400 +ma=130.123400 +ma=555.123400 +m+=0.00 mil +m+=0.0000 mm +m+=0.00000 m +m+=0.0000 mm or m +--------------- +mI=1 +mm=0.0000 +mM=1 +ml=0.00 +mL=0 +ms=0.0000 +mS=1 +md=(0.0000, 0.0000) +mD=(1, 1) +m3=(1, 1, 1) +mr=0 +$mI=1 +$mm=0.0000 mm +$mM=1 nm +$ml=0.00 mil +$mL=0 cmil +$ms=0.0000 mm +$mS=1 nm +$md=(0.0000, 0.0000) mm +$mD=(1, 1) nm +$m3=(1, 1, 1) nm +$mr=0 +m*=0.00 mil +m*=0.0000 mm +ma=1.123400 +ma=130.123400 +ma=555.123400 +m+=0.00 mil +m+=0.0000 mm +m+=0.00000 m +m+=0.0000 mm or m +--------------- +mI=1024 +mm=0.0010 +mM=1.02 +ml=0.04 +mL=4 +ms=0.0010 +mS=1.02 +md=(0.0010, 0.0010) +mD=(1.02, 1.02) +m3=(1.02, 1.02, 1.02) +mr=4 +$mI=1024 +$mm=0.0010 mm +$mM=1.02 um +$ml=0.04 mil +$mL=4 cmil +$ms=0.0010 mm +$mS=1.02 um +$md=(0.0010, 0.0010) mm +$mD=(1.02, 1.02) um +$m3=(1.02, 1.02, 1.02) um +$mr=4 +m*=0.04 mil +m*=0.0010 mm +ma=1.123400 +ma=130.123400 +ma=555.123400 +m+=0.04 mil +m+=0.0010 mm +m+=0.00000 m +m+=0.0010 mm or m +--------------- +mI=1048576 +mm=1.0486 +mM=1.0486 +ml=41.28 +mL=41.28 +ms=1.0486 +mS=1.0486 +md=(1.0486, 1.0486) +mD=(1.0486, 1.0486) +m3=(1.0486, 1.0486, 1.0486) +mr=4128 +$mI=1048576 +$mm=1.0486 mm +$mM=1.0486 mm +$ml=41.28 mil +$mL=41.28 mil +$ms=1.0486 mm +$mS=1.0486 mm +$md=(1.0486, 1.0486) mm +$mD=(1.0486, 1.0486) mm +$m3=(1.0486, 1.0486, 1.0486) mm +$mr=4128 +m*=41.28 mil +m*=1.0486 mm +ma=1.123400 +ma=130.123400 +ma=555.123400 +m+=41.28 mil +m+=1.0486 mm +m+=0.00105 m +m+=1.0486 mm or m +--------------- +mI=1073741824 +mm=1073.7418 +mM=1.07374 +ml=42273.30 +mL=42.27330 +ms=1073.7418 +mS=1.07374 +md=(1073.7418, 1073.7418) +mD=(1.07374, 1.07374) +m3=(1.07374, 1.07374, 1.07374) +mr=4227330 +$mI=1073741824 +$mm=1073.7418 mm +$mM=1.07374 m +$ml=42273.30 mil +$mL=42.27330 in +$ms=1073.7418 mm +$mS=1.07374 m +$md=(1073.7418, 1073.7418) mm +$mD=(1.07374, 1.07374) m +$m3=(1.07374, 1.07374, 1.07374) m +$mr=4227330 +m*=42273.30 mil +m*=1073.7418 mm +ma=1.123400 +ma=130.123400 +ma=555.123400 +m+=42273.30 mil +m+=1073.7418 mm +m+=1.07374 m +m+=1.07374 mm or m +--------------- +mf=1.2345 Index: tags/2.3.0/tests/pcbflags/Makefile =================================================================== --- tags/2.3.0/tests/pcbflags/Makefile (nonexistent) +++ tags/2.3.0/tests/pcbflags/Makefile (revision 33253) @@ -0,0 +1,12 @@ +all: + +ROOT=../.. +include $(ROOT)/Makefile.conf + +test: + @./test.sh && echo "pcbflags: *** QC PASS ***" + +clean: + mv vanilla.pcb vanilla.save + -$(SCCBOX) rm -f *.pcb *.log + mv vanilla.save vanilla.pcb Index: tags/2.3.0/tests/pcbflags/readme.txt =================================================================== --- tags/2.3.0/tests/pcbflags/readme.txt (nonexistent) +++ tags/2.3.0/tests/pcbflags/readme.txt (revision 33253) @@ -0,0 +1,2 @@ +Test whether chaning design configuration flags one by one result in saving +the right pcb flags in the original file format. Index: tags/2.3.0/tests/pcbflags/test.sh =================================================================== --- tags/2.3.0/tests/pcbflags/test.sh (nonexistent) +++ tags/2.3.0/tests/pcbflags/test.sh (revision 33253) @@ -0,0 +1,99 @@ +#!/bin/sh +src_dir=../../src +pwd=`pwd` + +# $1 must be a .pcb file name +run_pcb() +{ + local fn + if test ! -z "$1" + then + fn="$pwd/$1" + shift 1 + fi + ( + cd "$src_dir" + if test -z "$fn" + then + ./pcb-rnd --gui batch "$@" + else + ./pcb-rnd --gui batch "$fn" "$@" + fi + ) +} + + +test_flag() +{ + local name="`basename $1`" newf expect="Flags(\"$3\")" res + if test -z "$name" + then + name="0" + fi + rm $name 2>/dev/null + echo " +conf(set, $1, $2, design) +SaveTo(LayoutAs, $pwd/$name.pcb) +dumpconf(lihata,design) +" | run_pcb vanilla.pcb >$name.log 2>&1 + newf=`grep ^Flags $name.pcb` + test "$newf" = "$expect" + res=$? + if test $res != 0 + then + echo "$1 save broken: expected '$expect' got '$newf'" + return 1 + fi + + + echo "###### load test" >> $name.log + echo " +conf(reset, system) +conf(reset, project) +LoadFrom(Layout, $pwd/$name.pcb) +SaveTo(LayoutAs, $pwd/$name.2.pcb) +dumpconf(lihata,design) +" | run_pcb >>$name.log 2>&1 + + newf=`grep ^Flags $name.2.pcb` + test "$newf" = "$expect" + res=$? + if test $res != 0 + then + echo "$1 load broken: expected '$expect' got '$newf'" + return 1 + fi + + return 0 +} + +diag=`cd "$src_dir" && ./pcb-rnd --dump-plugins | grep diag` +if test -z "$diag" +then + echo "pcbflags: can't run tests because the diag plugin is not compiled." + exit 0 +fi + + +test_flag "plugins/mincut/enable" "true" "enablemincut" +test_flag "editor/show_number" "true" "shownumber" +test_flag "editor/show_drc" "true" "showdrc" +test_flag "editor/rubber_band_mode" "true" "rubberband" +test_flag "editor/auto_drc" "true" "autodrc" +test_flag "editor/all_direction_lines" "true" "alldirection" +test_flag "editor/swap_start_direction" "true" "swapstartdir" +test_flag "editor/unique_names" "true" "uniquename" +test_flag "editor/clear_line" "true" "clearnew" +test_flag "editor/full_poly" "true" "newfullpoly" +test_flag "editor/snap_pin" "true" "snappin" +test_flag "editor/orthogonal_moves" "true" "orthomove" +test_flag "editor/live_routing" "true" "liveroute" +test_flag "editor/only_names" "true" "onlynames" +test_flag "editor/lock_names" "true" "locknames" +test_flag "editor/hide_names" "true" "hidenames" +test_flag "editor/thin_draw" "true" "thindraw" +test_flag "editor/thin_draw_poly" "true" "thindrawpoly" +test_flag "editor/local_ref" "true" "localref" +test_flag "editor/check_planes" "true" "checkplanes" +test_flag "editor/description" "true" "description" +test_flag "editor/name_on_pcb" "true" "nameonpcb" Property changes on: tags/2.3.0/tests/pcbflags/test.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/pcbflags/vanilla.pcb =================================================================== --- tags/2.3.0/tests/pcbflags/vanilla.pcb (nonexistent) +++ tags/2.3.0/tests/pcbflags/vanilla.pcb (revision 33253) @@ -0,0 +1,21 @@ +# release: pcb-rnd 1.0.7 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 600000 500000] + +Grid[2500.0 0 0 1] +Cursor[282500 172500 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("") +Groups("1,c:2,s") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,20000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] +Layer(1 "c") +( +) +Layer(2 "s") +( +) Index: tags/2.3.0/tests/propedit/Makefile =================================================================== --- tags/2.3.0/tests/propedit/Makefile (nonexistent) +++ tags/2.3.0/tests/propedit/Makefile (revision 33253) @@ -0,0 +1,44 @@ +all: tester + +ROOT=../.. +include $(ROOT)/Makefile.conf + +PED=$(ROOT)/src_plugins/propedit +LHT=$(ROOT)/src_3rd +SRC=$(ROOT)/src +SRC_3RD=$(ROOT)/src_3rd +LIBRND=$(SRC_3RD)/librnd + +CFLAGS = $(PCB_RND_C89FLAGS) -I$(PED) -I$(LHT) -I$(SRC) -I$(ROOT) -I$(ROOT)/src_3rd +LDLIBS = -lm +LIB_OBJS = \ + $(LHT)/genht/htsp.o \ + $(LHT)/genht/hash.o \ + $(LIBRND)/core/compat_misc.o \ + $(LIBRND)/core/misc_util.o \ + $(LIBRND)/core/rnd_printf.o \ + $(LIBRND)/core/unit.o \ + $(ROOT)/src_3rd/genvector/gds_char.o + +OBJS = tester.o $(PED)/props.o + + +test: tester.diff + @echo "propedit: *** QC PASS ***" + @rm tester.out + +tester: $(OBJS) $(LIB_OBJS) + $(CC) $(LDFLAGS) -o tester $(OBJS) $(LIB_OBJS) $(LDLIBS) + +tester.o: tester.c $(PED)/props.h + +$(PED)/props.o: $(PED)/props.c $(PED)/props.h + +tester.diff: tester.ref tester.out + @diff -u tester.ref tester.out + +tester.out: tester + ./tester > tester.out + +clean: + -$(SCCBOX) rm -f tester.out tester $(OBJS) Index: tags/2.3.0/tests/propedit/tester.c =================================================================== --- tags/2.3.0/tests/propedit/tester.c (nonexistent) +++ tags/2.3.0/tests/propedit/tester.c (revision 33253) @@ -0,0 +1,141 @@ +#include +#include +#include "props.h" + +void *rnd_gui = NULL; + +int pcb_propsel_set(const char *prop, const char *value) +{ + return 0; +} + +int pcb_propsel_del(const char *key) +{ + return 0; +} + +void pcb_propsel_map_core(htsp_t *props) +{ +} + + + +static void print_val(pcb_prop_type_t type, pcb_propval_t val) +{ + switch(type) { + case PCB_PROPT_STRING: printf("%s", val.string); break; + case PCB_PROPT_COORD: printf("%d", val.coord); break; + case PCB_PROPT_ANGLE: printf("%f", val.angle); break; + case PCB_PROPT_DOUBLE: printf("%f", val.d); break; + case PCB_PROPT_INT: printf("%d", val.i); break; + default: printf(" ???"); + } +} + +static void print_all(htsp_t *props) +{ + htsp_entry_t *pe; + for (pe = htsp_first(props); pe; pe = htsp_next(props, pe)) { + htprop_entry_t *e; + pcb_props_t *p = pe->value; + printf("%s [%s]\n", pe->key, pcb_props_type_name(p->type)); + for (e = htprop_first(&p->values); e; e = htprop_next(&p->values, e)) { + printf(" "); + print_val(p->type, e->key); + printf(" (%lu)\n", e->value); + } + } +} + +static pcb_props_t *print_stat(pcb_propedit_t *ctx, const char *name, int all) +{ + pcb_propval_t most_common, min, max, avg; + pcb_props_t *p; + int res; + + p = pcb_props_get(ctx, name); + if (p == NULL) + return NULL; + + if (all) + res = pcb_props_stat(ctx, p, &most_common, &min, &max, &avg); + else + res = pcb_props_stat(ctx, p, &most_common, NULL, NULL, NULL); + + if (res != 0) + return NULL; + + printf("Stats %s:", name); + printf(" common: "); print_val(p->type, most_common); + if (all) { + printf(" min: "); print_val(p->type, min); + printf(" max: "); print_val(p->type, max); + printf(" avg: "); print_val(p->type, avg); + } + printf("\n"); + + return p; +} + +int main() +{ + pcb_propedit_t ctx; + pcb_propval_t v; + + pcb_props_init(&ctx, NULL); + + /* --- add a few items properly - should work --- */ + + /* coord */ + v.coord = 42; assert(pcb_props_add(&ctx, "crd", PCB_PROPT_COORD, v) != NULL); + v.coord = 10; assert(pcb_props_add(&ctx, "crd", PCB_PROPT_COORD, v) != NULL); + v.coord = 42; assert(pcb_props_add(&ctx, "crd", PCB_PROPT_COORD, v) != NULL); + v.coord = 42; assert(pcb_props_add(&ctx, "crd", PCB_PROPT_COORD, v) != NULL); + + /* int */ + v.i = 42; assert(pcb_props_add(&ctx, "num", PCB_PROPT_INT, v) != NULL); + v.i = 10; assert(pcb_props_add(&ctx, "num", PCB_PROPT_INT, v) != NULL); + v.i = 42; assert(pcb_props_add(&ctx, "num", PCB_PROPT_INT, v) != NULL); + v.i = 42; assert(pcb_props_add(&ctx, "num", PCB_PROPT_INT, v) != NULL); + + /* angle */ + v.angle = 42.0; assert(pcb_props_add(&ctx, "ang", PCB_PROPT_ANGLE, v) != NULL); + v.angle = 10.5; assert(pcb_props_add(&ctx, "ang", PCB_PROPT_ANGLE, v) != NULL); + v.angle = 42.0; assert(pcb_props_add(&ctx, "ang", PCB_PROPT_ANGLE, v) != NULL); + v.angle = 42.0; assert(pcb_props_add(&ctx, "ang", PCB_PROPT_ANGLE, v) != NULL); + + /* double */ + v.d = 42.0; assert(pcb_props_add(&ctx, "dbl", PCB_PROPT_DOUBLE, v) != NULL); + v.d = 10.5; assert(pcb_props_add(&ctx, "dbl", PCB_PROPT_DOUBLE, v) != NULL); + v.d = 42.0; assert(pcb_props_add(&ctx, "dbl", PCB_PROPT_DOUBLE, v) != NULL); + v.d = 42.0; assert(pcb_props_add(&ctx, "dbl", PCB_PROPT_DOUBLE, v) != NULL); + + /* string */ + v.string = "foo"; assert(pcb_props_add(&ctx, "str", PCB_PROPT_STRING, v) != NULL); + v.string = "bar"; assert(pcb_props_add(&ctx, "str", PCB_PROPT_STRING, v) != NULL); + v.string = "BAZ"; assert(pcb_props_add(&ctx, "str", PCB_PROPT_STRING, v) != NULL); + v.string = "foo"; assert(pcb_props_add(&ctx, "str", PCB_PROPT_STRING, v) != NULL); + v.string = "foo"; assert(pcb_props_add(&ctx, "str", PCB_PROPT_STRING, v) != NULL); + + /* --- add a items with the wrong type - should fail --- */ + v.i = 42; assert(pcb_props_add(&ctx, "crd", PCB_PROPT_INT, v) == NULL); + v.i = 42; assert(pcb_props_add(&ctx, "crd", 1234, v) == NULL); + v.i = 42; assert(pcb_props_add(&ctx, "ang", 1234, v) == NULL); + + print_all(&ctx.props); + + /* --- get some stats --- */ + + /* these should work */ + assert(print_stat(&ctx, "crd", 1) != NULL); + assert(print_stat(&ctx, "num", 1) != NULL); + assert(print_stat(&ctx, "ang", 1) != NULL); + assert(print_stat(&ctx, "dbl", 1) != NULL); + assert(print_stat(&ctx, "str", 0) != NULL); + + /* these should fail */ + assert(print_stat(&ctx, "str", 1) == NULL); + assert(print_stat(&ctx, "HAH", 1) == NULL); + + return 0; +} Index: tags/2.3.0/tests/propedit/tester.ref =================================================================== --- tags/2.3.0/tests/propedit/tester.ref (nonexistent) +++ tags/2.3.0/tests/propedit/tester.ref (revision 33253) @@ -0,0 +1,21 @@ +num [int] + 42 (3) + 10 (1) +ang [angle] + 42.000000 (3) + 10.500000 (1) +str [string] + foo (3) + bar (1) + BAZ (1) +crd [coord] + 42 (3) + 10 (1) +dbl [double] + 42.000000 (3) + 10.500000 (1) +Stats crd: common: 42 min: 10 max: 42 avg: 34 +Stats num: common: 42 min: 10 max: 42 avg: 34 +Stats ang: common: 42.000000 min: 10.500000 max: 42.000000 avg: 34.125000 +Stats dbl: common: 42.000000 min: 10.500000 max: 42.000000 avg: 34.125000 +Stats str: common: foo Index: tags/2.3.0/tests/query/1obj.lht =================================================================== --- tags/2.3.0/tests/query/1obj.lht (nonexistent) +++ tags/2.3.0/tests/query/1obj.lht (revision 33253) @@ -0,0 +1,55 @@ +ha:pcb-rnd-board-v6 { + + ha:meta { + ha:size { + thermal_scale = 0.500000 + x = 375.0mil + y = 150.0mil + } + ha:grid { + spacing = 25.0mil + } + } + + ha:data { + li:padstack_prototypes { + } + + li:objects { + } + li:layers { + + ha:top-sig { + lid=0 + group=0 + ha:combining { } + + ha:attributes { + {pcb-rnd::key::vis}={l; Shiftt} + {pcb-rnd::key::select}={l; t} + } + + li:objects { + ha:line.5 { + x1=75.0mil; y1=75.0mil; x2=300.0mil; y2=75.0mil; thickness=10.0mil; clearance=40.0mil; + ha:flags { + clearline=1 + } + } + } + color = {#8b2323} + } + + } + } + + ha:layer_stack { + li:groups { + ha:0 { + name = top_copper + ha:type { copper=1; top=1; } + li:layers { 0; } + } + } + } +} Index: tags/2.3.0/tests/query/Makefile =================================================================== --- tags/2.3.0/tests/query/Makefile (nonexistent) +++ tags/2.3.0/tests/query/Makefile (revision 33253) @@ -0,0 +1,37 @@ +ROOT=../.. + +SRC=$(ROOT)/src +TDIR=../tests/query +PCBRND=./pcb-rnd +GLOBARGS=-c rc/library_search_paths=../tests/RTT/lib -c rc/quiet=1 + +TESTS = \ + action.diff getconf.diff getconf2.diff + +test: $(TESTS) + +all: + +action.diff: action.out + @diff -u action.ref action.out && rm action.out + +action.out: FORCE + @cd $(SRC) && echo 'query(eval, "action(\"message\", \"hello\", @.x)")' | $(PCBRND) $(GLOBARGS) $(TDIR)/1obj.lht --gui batch > $(TDIR)/action.out + +getconf.diff: getconf.out + @diff -u getconf.ref getconf.out && rm getconf.out + +getconf.out: FORCE + @cd $(SRC) && echo 'query(eval, "@ thus getconf(\"editor/grid_unit\")")' | $(PCBRND) $(GLOBARGS) $(TDIR)/1obj.lht --gui batch > $(TDIR)/getconf.out + +getconf2.diff: getconf2.out + @diff -u getconf2.ref getconf2.out && rm getconf2.out + +getconf2.out: FORCE + @cd $(SRC) && echo 'query(eval, "@ thus $$min_drill")' | $(PCBRND) $(GLOBARGS) $(TDIR)/1obj.lht --gui batch > $(TDIR)/getconf2.out + +clean: + @echo "a" > dummy.out + rm *.out + +FORCE: Index: tags/2.3.0/tests/query/action.ref =================================================================== --- tags/2.3.0/tests/query/action.ref (nonexistent) +++ tags/2.3.0/tests/query/action.ref (revision 33253) @@ -0,0 +1,5 @@ +Script eval: 'action("message", "hello", @.x)' scope='' +I: hello +I: + false +eval statistics: true=0 false=1 errors=0 Index: tags/2.3.0/tests/query/getconf.ref =================================================================== --- tags/2.3.0/tests/query/getconf.ref (nonexistent) +++ tags/2.3.0/tests/query/getconf.ref (revision 33253) @@ -0,0 +1,3 @@ +Script eval: '@ thus getconf("editor/grid_unit")' scope='' + "mil" +eval statistics: true=1 false=0 errors=0 Index: tags/2.3.0/tests/query/getconf2.ref =================================================================== --- tags/2.3.0/tests/query/getconf2.ref (nonexistent) +++ tags/2.3.0/tests/query/getconf2.ref (revision 33253) @@ -0,0 +1,3 @@ +Script eval: '@ thus $min_drill' scope='' + true (381000=15.00000000 mil) +eval statistics: true=1 false=0 errors=0 Index: tags/2.3.0/tests/remote/Makefile =================================================================== --- tags/2.3.0/tests/remote/Makefile (nonexistent) +++ tags/2.3.0/tests/remote/Makefile (revision 33253) @@ -0,0 +1,18 @@ +all: test_parse + +ROOT=../.. +include $(ROOT)/Makefile.conf +REM=$(ROOT)/src_3rd/librnd/plugins/hid_remote +CFLAGS = $(PCB_RND_C89FLAGS) -g -I$(REM) -I$(ROOT)/src -I$(ROOT)/src_3rd -I$(ROOT) + + +test_parse: test_parse.o + $(CC) $(LDFLAGS) -o test_parse test_parse.o $(LDLIBS) + +test_parse.o: test_parse.c $(REM)/proto_lowcommon.h $(REM)/proto_lowparse.h $(REM)/proto_lowdbg.h + +test: + @./test_all.sh + +clean: + -$(SCCBOX) rm -f test_parse test_parse.o Index: tags/2.3.0/tests/remote/bin.msg =================================================================== --- tags/2.3.0/tests/remote/bin.msg (nonexistent) +++ tags/2.3.0/tests/remote/bin.msg (revision 33253) @@ -0,0 +1,6 @@ +cmd{B=1 C=ab D=123} +empty{A= A= A=} +nasty{D={} + D= #=} + + Index: tags/2.3.0/tests/remote/bin.ref =================================================================== --- tags/2.3.0/tests/remote/bin.ref (nonexistent) +++ tags/2.3.0/tests/remote/bin.ref (revision 33253) @@ -0,0 +1,18 @@ +msg 'cmd' + list (bin): + str (bin): 1/'1' + str (bin): 2/'ab' + str (bin): 3/'123' + +msg 'empty' + list (bin): + str (bin): 0/'(null)' + str (bin): 0/'(null)' + str (bin): 0/'(null)' + +msg 'nasty' + list (bin): + str (bin): 3/'{} +' + str (bin): 3/' #=' + Index: tags/2.3.0/tests/remote/lists.msg =================================================================== --- tags/2.3.0/tests/remote/lists.msg (nonexistent) +++ tags/2.3.0/tests/remote/lists.msg (revision 33253) @@ -0,0 +1 @@ +bar((A B)(1 2 3){B=a B=b {C=11 C=12}}) Index: tags/2.3.0/tests/remote/lists.ref =================================================================== --- tags/2.3.0/tests/remote/lists.ref (nonexistent) +++ tags/2.3.0/tests/remote/lists.ref (revision 33253) @@ -0,0 +1,16 @@ +msg 'bar' + list (text): + list (text): + str (text): 1/'A' + str (text): 1/'B' + list (text): + str (text): 1/'1' + str (text): 1/'2' + str (text): 1/'3' + list (bin): + str (bin): 1/'a' + str (bin): 1/'b' + list (bin): + str (bin): 2/'11' + str (bin): 2/'12' + Index: tags/2.3.0/tests/remote/simple.msg =================================================================== --- tags/2.3.0/tests/remote/simple.msg (nonexistent) +++ tags/2.3.0/tests/remote/simple.msg (revision 33253) @@ -0,0 +1,2 @@ +foo() +bar{} Index: tags/2.3.0/tests/remote/simple.ref =================================================================== --- tags/2.3.0/tests/remote/simple.ref (nonexistent) +++ tags/2.3.0/tests/remote/simple.ref (revision 33253) @@ -0,0 +1,6 @@ +msg 'foo' + list (text): + +msg 'bar' + list (bin): + Index: tags/2.3.0/tests/remote/test_all.sh =================================================================== --- tags/2.3.0/tests/remote/test_all.sh (nonexistent) +++ tags/2.3.0/tests/remote/test_all.sh (revision 33253) @@ -0,0 +1,23 @@ +#!/bin/sh +fail=0 +all=0 +for ref in *.ref +do + bn=${ref%%.ref} + ./test_parse < $bn.msg > $bn.out + diff -u $bn.ref $bn.out + if test $? = 0 + then + rm $bn.out + else + fail=$(($fail+1)) + fi + all=$(($all+1)) +done + +if test $fail = 0 +then + echo "remote: *** QC PASS ***" +else + echo "remote: FAIL: $fail of $all" +fi Property changes on: tags/2.3.0/tests/remote/test_all.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/tests/remote/test_parse.c =================================================================== --- tags/2.3.0/tests/remote/test_parse.c (nonexistent) +++ tags/2.3.0/tests/remote/test_parse.c (revision 33253) @@ -0,0 +1,41 @@ +#include +#include +#include "proto_lowcommon.h" +#include "proto_lowparse.h" +#include "proto_lowdbg.h" + +int main() +{ + int line = 1, col = 1; + proto_ctx_t pctx; + + memset(&pctx, 0, sizeof(pctx)); + + for(;;) { + parse_res_t res; + int c = getchar(); + if (c == EOF) + return -1; + if (c == '\n') { + col = 1; + line++; + } + else + col++; + res = parse_char(&pctx, c); + switch(res) { + case PRES_ERR: + printf("parse error at %d:%d\n", line, col); + return 1; + case PRES_GOT_MSG: + printf("msg '%s'\n", pctx.pcmd); + proto_node_print(pctx.targ, 1); + printf("\n"); + proto_node_free(pctx.targ); + break; + case PRES_PROCEED: + break; + } + } + return 0; +} Index: tags/2.3.0/tests/remote/text.msg =================================================================== --- tags/2.3.0/tests/remote/text.msg (nonexistent) +++ tags/2.3.0/tests/remote/text.msg (revision 33253) @@ -0,0 +1 @@ +cmd(a e _ # foo bar) Index: tags/2.3.0/tests/remote/text.ref =================================================================== --- tags/2.3.0/tests/remote/text.ref (nonexistent) +++ tags/2.3.0/tests/remote/text.ref (revision 33253) @@ -0,0 +1,9 @@ +msg 'cmd' + list (text): + str (text): 1/'a' + str (text): 1/'e' + str (text): 1/'_' + str (text): 1/'#' + str (text): 3/'foo' + str (text): 3/'bar' + Index: tags/2.3.0/tests/strflags/Makefile =================================================================== --- tags/2.3.0/tests/strflags/Makefile (nonexistent) +++ tags/2.3.0/tests/strflags/Makefile (revision 33253) @@ -0,0 +1,32 @@ +include ../../Makefile.conf + +TRUNK=../.. +IO=$(TRUNK)/src_plugins/io_pcb +CFLAGS = $(PCB_RND_C89FLAGS) -O3 -I$(TRUNK) -I$(TRUNK)/src -I$(IO) -I$(TRUNK)/src_3rd +LDLIBS = -lm +GDS= $(TRUNK)/src_3rd/genvector/gds_char.o + +all: tester + +ROOT=../.. +include $(ROOT)/Makefile.conf + +test: tester.diff + @echo "strflags: *** QC PASS ***" + @rm tester.stdout + +tester: tester.o $(GDS) + $(CC) $(LDFLAGS) -o tester tester.o $(GDS) $(LDLIBS) + +tester.o: tester.c + $(CC) -c $(CFLAGS) -o $@ tester.c + +tester.stdout: tester + ./tester > tester.stdout + +tester.diff: tester.stdout + diff -u tester.ref tester.stdout + +clean: + -$(SCCBOX) rm -f tester tester.o + Index: tags/2.3.0/tests/strflags/tester.c =================================================================== --- tags/2.3.0/tests/strflags/tester.c (nonexistent) +++ tags/2.3.0/tests/strflags/tester.c (revision 33253) @@ -0,0 +1,157 @@ +/* + * COPYRIGHT + * + * PCB, interactive printed circuit board design + * Copyright (C) 2005 DJ Delorie + * + * 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 addresses for paper mail and Email: + * DJ Delorie, 334 North Road, Deerfield NH 03037-1110, USA + * dj@delorie.com + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#define FLAG_TEST +#include "flag_str.c" +#include "flag.c" +#include + +static void dump_flag(pcb_flag_t * f) +{ + int l; + printf("F:%08x T:[", f->f); + for (l = 0; l < (PCB_MAX_LAYER + 7) / 8; l++) + printf(" %02x", f->t[l]); + printf("]"); +} + +int main() +{ + time_t now; + int i; + int errors = 0, count = 0; + + time(&now); + srandom((unsigned int) now + getpid()); + + grow_layer_list(0); + for (i = 0; i < 16; i++) { + int j; + char *p; + if (i != 1 && i != 4 && i != 5 && i != 9) + set_layer_list(i, 1); + else + set_layer_list(i, 0); + p = print_layer_list(); + printf("%2d : %20s =", i, p); + parse_layer_list(p + 1, 0); + for (j = 0; j < num_layers; j++) + printf(" %d", layers[j]); + printf("\n"); + } + + while (count < 1000000) { + FlagHolder fh; + char *str; + pcb_flag_t new_flags; + int i; + int otype; + unsigned char intconn; + + otype = PCB_OBJ_ANY; + fh.Flags = empty_flags; + for (i = 0; i < RND_ENTRIES(pcb_object_flagbits); i++) { + if (PCB_FLAG_TEST(pcb_object_flagbits[i].mask, &fh)) + continue; + if ((otype & pcb_object_flagbits[i].object_types) == 0) + continue; + if ((random() & 4) == 0) + continue; + + otype &= pcb_object_flagbits[i].object_types; + PCB_FLAG_SET(pcb_object_flagbits[i].mask, &fh); + } + + if (otype & PCB_OBJ_CLASS_PIN) + for (i = 0; i < PCB_MAX_LAYER; i++) + if (random() & 4) + PCB_FLAG_THERM_ASSIGN(i, 3, &fh); + + str = pcb_strflg_f2s(fh.Flags, otype, &intconn, 0); + new_flags = pcb_strflg_s2f(str, 0, &intconn, 0); + + count++; + if (PCB_FLAG_EQ(fh.Flags, new_flags)) + continue; + dump_flag(&fh.Flags); + printf(" "); + dump_flag(&new_flags); + printf("\n"); + if (++errors == 5) + goto bad; + } + + while (count < 1000000) { + FlagHolder fh; + char *str; + pcb_flag_t new_flags; + int i; + int otype; + + otype = PCB_OBJ_ANY; + fh.Flags = empty_flags; + for (i = 0; i < RND_ENTRIES(pcb_flagbits); i++) { + if (PCB_FLAG_TEST(pcb_flagbits[i].mask, &fh)) + continue; + if ((random() & 4) == 0) + continue; + + otype &= pcb_flagbits[i].object_types; + PCB_FLAG_SET(pcb_flagbits[i].mask, &fh); + } + + str = pcb_strflg_board_f2s(fh.Flags); + new_flags = pcb_strflg_board_s2f(str, 0); + + count++; + if (PCB_FLAG_EQ(fh.Flags, new_flags)) + continue; + + dump_flag(&fh.Flags); + printf(" "); + dump_flag(&new_flags); + printf("\n"); + + if (++errors == 5) + goto bad; + } + printf("%d out of %d failed\n", errors, count); + return errors; + + bad:; + printf("%d out of %d FAILED\n", errors, count); + return errors; +} + Index: tags/2.3.0/tests/strflags/tester.ref =================================================================== --- tags/2.3.0/tests/strflags/tester.ref (nonexistent) +++ tags/2.3.0/tests/strflags/tester.ref (revision 33253) @@ -0,0 +1,17 @@ + 0 : (0) = 1 + 1 : (0) = 1 + 2 : (0,2) = 1 0 1 + 3 : (0,2,3) = 1 0 1 1 + 4 : (0,2,3) = 1 0 1 1 + 5 : (0,2,3) = 1 0 1 1 + 6 : (0,2,3,6) = 1 0 1 1 0 0 1 + 7 : (0,2,3,6,7) = 1 0 1 1 0 0 1 1 + 8 : (0,2,3,6-8) = 1 0 1 1 0 0 1 1 1 + 9 : (0,2,3,6-8) = 1 0 1 1 0 0 1 1 1 +10 : (0,2,3,6-8,10) = 1 0 1 1 0 0 1 1 1 0 1 +11 : (0,2,3,6-8,10,11) = 1 0 1 1 0 0 1 1 1 0 1 1 +12 : (0,2,3,6-8,10-12) = 1 0 1 1 0 0 1 1 1 0 1 1 1 +13 : (0,2,3,6-8,10-13) = 1 0 1 1 0 0 1 1 1 0 1 1 1 1 +14 : (0,2,3,6-8,10-14) = 1 0 1 1 0 0 1 1 1 0 1 1 1 1 1 +15 : (0,2,3,6-8,10-15) = 1 0 1 1 0 0 1 1 1 0 1 1 1 1 1 1 +0 out of 1000000 failed Index: tags/2.3.0/tests/uniq_name/Makefile =================================================================== --- tags/2.3.0/tests/uniq_name/Makefile (nonexistent) +++ tags/2.3.0/tests/uniq_name/Makefile (revision 33253) @@ -0,0 +1,34 @@ +all: tester + +ROOT=../.. +include $(ROOT)/Makefile.conf + +UNM=$(ROOT)/src_plugins/io_kicad +LHT=$(ROOT)/src_3rd +SRC=$(ROOT)/src +SRC_3RD=$(ROOT)/src_3rd +LIBRND=$(SRC_3RD)/librnd +CFLAGS = $(PCB_RND_C89FLAGS) -I$(UNM) -I$(LHT) -I$(SRC) -I$(ROOT) +LDLIBS = -lm +LIB_OBJS=$(LHT)/genht/htsp.o $(LHT)/genht/hash.o $(LIBRND)/core/compat_misc.o $(LHT)/genvector/gds_char.o + + +test: tester.diff + @echo "uniq_name: *** QC PASS ***" + @rm tester.out + +tester: tester.o $(UNM)/uniq_name.o $(LIB_OBJS) + $(CC) $(LDFLAGS) -o tester tester.o $(UNM)/uniq_name.o $(LIB_OBJS) $(LDLIBS) + +tester.o: tester.c $(UNM)/uniq_name.h + +$(UNM)/uniq_name.o: $(UNM)/uniq_name.c $(UNM)/uniq_name.h + +tester.diff: tester.ref tester.out + @diff -u tester.ref tester.out + +tester.out: tester + ./tester > tester.out + +clean: + -$(SCCBOX) rm -f tester.out tester tester.o Index: tags/2.3.0/tests/uniq_name/tester.c =================================================================== --- tags/2.3.0/tests/uniq_name/tester.c (nonexistent) +++ tags/2.3.0/tests/uniq_name/tester.c (revision 33253) @@ -0,0 +1,64 @@ +#include +#include "uniq_name.h" + +int main() +{ + unm_t group1; + + /* Initialize the group with defaults */ + unm_init(&group1); + + printf("'%s'\n", unm_name(&group1, "foo", (void *)0x01)); + printf("'%s'\n", unm_name(&group1, "bar", (void *)0x42)); + printf("'%s'\n", unm_name(&group1, "bar", (void *)0x66)); + printf("'%s'\n", unm_name(&group1, "baz", NULL)); + + /* test forced collision */ + printf("'%s'\n", unm_name(&group1, "forced", NULL)); + printf("'%s'\n", unm_name(&group1, "forced_dup1", NULL)); + printf("'%s'\n", unm_name(&group1, "forced_dup2", NULL)); + printf("'%s'\n", unm_name(&group1, "forced", NULL)); /* this would end up as forced_dup3 */ + printf("'%s'\n", unm_name(&group1, "forced", NULL)); /* ... _dup4 */ + + /* test global dup ctr */ + printf("'%s'\n", unm_name(&group1, "foo", NULL)); /* ... _dup5 */ + + /* unknown name gets named */ + printf("'%s'\n", unm_name(&group1, NULL, NULL)); /* this is the first unnamed item, so it won't get a suffix */ + printf("'%s'\n", unm_name(&group1, NULL, NULL)); /* gets suffixed because of the collision */ + + /* empty name is like unknown name too */ + printf("'%s'\n", unm_name(&group1, "", NULL)); + + + /* Optional: change configuration, even on the fly: */ + group1.unnamed = "anonymous"; + group1.suffix_sep = "::"; + + /* Note: it is safe to reset the counter - worst case the collision loop + will run some more before it finds a free name, but there won't be + a collision */ + group1.ctr = 0; + + /* Adding three more unnamed items will demonstrate how the new config settings take effect */ + printf("'%s'\n", unm_name(&group1, NULL, NULL)); + printf("'%s'\n", unm_name(&group1, NULL, NULL)); + printf("'%s'\n", unm_name(&group1, NULL, NULL)); + + /* Optional: iterate over all items once more, e.g. to generate an index + Warning: order is not guaranteed. */ + { + htsp_entry_t *e; + for (e = htsp_first(&group1.seen); e; e = htsp_next(&group1.seen, e)) { + printf("name='%s' user_data='", e->key); + if (e->value == NULL) + printf("(nil)'\n"); + else + printf("%p'\n", e->value); + } + } + + /* Release all memory */ + unm_uninit(&group1); + return 0; +} Index: tags/2.3.0/tests/uniq_name/tester.ref =================================================================== --- tags/2.3.0/tests/uniq_name/tester.ref (nonexistent) +++ tags/2.3.0/tests/uniq_name/tester.ref (revision 33253) @@ -0,0 +1,32 @@ +'foo' +'bar' +'bar_dup0' +'baz' +'forced' +'forced_dup1' +'forced_dup2' +'forced_dup3' +'forced_dup4' +'foo_dup5' +'unnamed' +'unnamed_dup6' +'unnamed_dup7' +'anonymous' +'anonymous::0' +'anonymous::1' +name='forced_dup1' user_data='(nil)' +name='forced_dup2' user_data='(nil)' +name='forced_dup3' user_data='(nil)' +name='forced_dup4' user_data='(nil)' +name='foo' user_data='0x1' +name='baz' user_data='(nil)' +name='bar_dup0' user_data='0x66' +name='unnamed_dup6' user_data='(nil)' +name='forced' user_data='(nil)' +name='unnamed_dup7' user_data='(nil)' +name='unnamed' user_data='(nil)' +name='anonymous' user_data='(nil)' +name='anonymous::0' user_data='(nil)' +name='anonymous::1' user_data='(nil)' +name='bar' user_data='0x42' +name='foo_dup5' user_data='(nil)' Index: tags/2.3.0/util/Makefile =================================================================== --- tags/2.3.0/util/Makefile (nonexistent) +++ tags/2.3.0/util/Makefile (revision 33253) @@ -0,0 +1,41 @@ +# plain old hand crafted Makefile +ROOT=.. + +all: + cd gsch2pcb-rnd && $(MAKE) all + cd bxl2txt && $(MAKE) all + +include $(ROOT)/Makefile.conf + +clean: + cd gsch2pcb-rnd && $(MAKE) clean + cd bxl2txt && $(MAKE) clean + +distclean: + cd gsch2pcb-rnd && $(MAKE) distclean + cd bxl2txt && $(MAKE) distclean + +install_all: + $(SCCBOX) mkdir -p "$(BINDIR)" "$(LIBDIR)" + $(SCCBOX) $(HOW) "fp2preview" "$(BINDIR)/fp2preview" + $(SCCBOX) $(HOW) "fp2subc" "$(BINDIR)/fp2subc" + $(SCCBOX) $(HOW) "pcb-prj2lht" "$(BINDIR)/pcb-prj2lht" + $(SCCBOX) $(HOW) "pcb-rnd-svg" "$(BINDIR)/pcb-rnd-svg" + $(SCCBOX) $(HOW) "gnet-pcbrndfwd.scm" "$(LIBDIR)/gnet-pcbrndfwd.scm" + $(SCCBOX) $(HOW) "gnet-pcbrndfwd_elem.scm" "$(LIBDIR)/gnet-pcbrndfwd_elem.scm" + +install: + $(MAKE) install_all HOW="install -f" + cd gsch2pcb-rnd && $(MAKE) install + cd bxl2txt && $(MAKE) install + +linstall: + $(MAKE) install_all HOW="linstall -f" + cd gsch2pcb-rnd && $(MAKE) linstall + cd bxl2txt && $(MAKE) linstall + +uninstall: + $(MAKE) install_all HOW="uninstall" + cd gsch2pcb-rnd && $(MAKE) uninstall + cd bxl2txt && $(MAKE) uninstall + Index: tags/2.3.0/util/README =================================================================== --- tags/2.3.0/util/README (nonexistent) +++ tags/2.3.0/util/README (revision 33253) @@ -0,0 +1,3 @@ +Programs and scripts that are not integral part of the pcb executable. + +These are typically used as standalone utilities along with pcb-rnd. Index: tags/2.3.0/util/bisecter/bisecter =================================================================== --- tags/2.3.0/util/bisecter/bisecter (nonexistent) +++ tags/2.3.0/util/bisecter/bisecter (revision 33253) @@ -0,0 +1,339 @@ +#!/bin/sh +# +# bisecter - cached svn bisection +# 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. +# +# http://repo.hu/projects/pcb-rnd +# + +if test -z "$CONF" +then + CONF="./bisecter.conf" +fi + +if test ! -f "$CONF" +then + echo "Can't find the config file $CONF; please copy bisect.conf.in to $CONF and edit" >&2 + exit 1 +fi + +. $CONF +mkdir -p "$cache" + +wlog() +{ + echo "$*" +} + +svn_list_externs() +{ + svn --xml stat "$1" | awk ' + BEGIN { q="\"" } + function strip(s) { + sub("^[^=]*=" q, "", s) + sub(q ".*$", "", s) + return s + } + /[<]entry/ { state=1 } + (state == 1) && /path=\"/ { path=strip($0) } + (state == 1) && /wc-status/ { state = 2 } + (state == 2) && /item=\"/ { item=strip($0) } + /[<]\/entry/ { + if ((item == "external") && (path != "")) + print path + item="" + path="" + state = 0 + } + ' +} + +svn_get_date() +{ + svn info "$1" | awk ' + /Last Changed Date:/ { + print $4, $5 + } + ' +} + +svn_get_rev() +{ + svn info "$1" | awk ' + /Last Changed Rev:/ { + print $4 + } + ' +} + +svn_co() +{ + local rev=$1 dt e + svn checkout $url@$rev "$tmp/$rev" + dt=`svn_get_date "$tmp/$rev"` + for e in `svn_list_externs "$tmp/$rev"` + do + svn up $e -r "{$dt}" + done +} + +svn_cleanup() +{ + local rev=$1 + rm -rf "$tmp/$rev" +} + +cache_save() +{ + local rev=$1 exebn + exebn=`basename $exe` + + cp "$tmp/$rev/$exe" "$cache/$exebn.$rev" + if test ! -z "$cache_strip" + then + eval $cache_strip "$cache/$exebn.$rev" $redir + fi + + if test ! -z "$cache_compress" + then + eval $cache_compress "$cache/$exebn.$rev" $redir + fi +} + +cache_build() +{ + local rev=$1 save=$2 redir=">>log.$1 2>&1" exebn + + (echo -n "#########################################"; date) >> log.$1 + + wlog "Checkout r$1" + eval "svn_co $rev $redir" + + wlog "Compile r$1" + eval "(cd \"$tmp/$rev\" && ./configure $confopts && make) $redir" + + if test ! -f "$tmp/$rev/$exe" + then + echo '#!/bin/sh + echo Sorry, revision '$rev' can not be compiled.' > "$tmp/$rev/$exe" + chmod +x "$tmp/$rev/$exe" + fi + + if test "0$save" -gt 0 + then + exebn=`basename $exe` + cp "$tmp/$rev/$exe" "./$exebn.$rev" + fi + + wlog "Cache save r$1" + cache_save "$rev" + + wlog "Cleanup r$1" + eval svn_cleanup $rev $redir + + mv log.$1 $cache + if test ! -z "$cache_compress" + then + $cache_compress "$cache/log.$1" + fi +} + +cache_get() +{ + local rev=$1 exebn + + exebn=`basename $exe` + + if test -f "$cache/$exebn.$rev$cache_compsuffix" + then + echo "Retrieving $exebn.$rev from cache..." + cp $cache/$exebn.$rev$cache_compsuffix . + if test ! -z "$cache_decompress" + then + $cache_decompress "$exebn.$rev$cache_compsuffix" + fi + else + cache_build $rev 1 + fi +} + +run() +{ + local rev=$1 exebn + + shift 1 + exebn=`basename $exe` + + cache_get $rev + ./$exebn.$rev \ + -c "rc/default_font_file=" \ + -c "rc/default_pcb_file=" \ + "$@" + rm $exebn.$rev +} + +bisect() +{ + local first="$1" last="$2" + + if test -z "$first" + then + first=$first_rev + fi + + if test -z "$last" + then + last=`svn_get_rev $url` + fi + + gawk -v "first=$first" -v "last=$last" ' + BEGIN { + print "Bisecting between " first " and " last ", inclusive" + print "Usage:" + print " Type \"rev good\" or \"rev bad\"" + print " (rev is the revision number you ran; can be omitted when the)" + print " it is the revision that the script last offered)" + print "" + last_good=first + first_bad=last + offer() + } + + function offer() { + if (last_good+1 == first_bad) { + print "" + print "-------- Result --------" + print "last_good=" last_good " first_bad=" first_bad + exit 0 + } + offered=int((last_good+first_bad)/2) + tries=int(log(first_bad-last_good)/log(2) + 0.5) + print "" + print "(last_good=" last_good " first_bad=" first_bad " in about " tries " tries)" + print "Next rev to test: " offered + printf "> " + fflush() + } + + { + rev=$1 + if (rev != int(rev)) { + rev = offered + res = tolower($1) + } + else + res=tolower($2) + if (rev <= last_good) { + print "rev error " rev ": too low" + flush + next + } + if (rev > first_bad) { + print "rev error " rev ": too high" + flush + next + } + + if (res == "good") + last_good = rev + else if (res == "bad") + first_bad = rev + else { + print "Syntax error " $2 ": please say good or bad" + flush + next + } + + offer() + } + ' +} + +near() +{ + local rev=$1 exebn + exebn=`basename $exe` + ls $cache/$exebn.* | gawk -v "front=$cache/$exebn." -v "rev=$rev" ' + BEGIN { + fl=length(front) + rev=int(rev) + } + { + r = substr($0, fl+1) + sub("[.].*$", "", r) + r = int(r) + print r + } + ' | sort -n | gawk -v "rev=$rev" ' + { + r=$0 + if (r == rev) { + print r + found = 1 + exit + } + if (r > rev) { + print last, r + found = 1 + exit + } + last = r + } + END { + if (!found) + print last + } + ' +} + +help() +{ + echo "bisecter - support bisecting by cached executables" + echo "" + echo "Usage: ./bisecter command [args]" + echo "Commands:" + echo " build rev force check out and build rev" + echo " get rev get the executable of rev in CWD (build if needed)" + echo " co rev safely check out rev in tmp, but do not compile" + echo " run rev [args] get rev and run it with args" + echo " near rev print revisions present in the cache that are close to rev" + echo " bisect [st end] bisect suggestions, optionally between revisions st and end" + echo " help this help screen" + echo "" +} + +cmd="$1" +if test -z "$cmd" +then + help + exit 1 +fi + +shift 1 + +case "$cmd" +in + build) cache_build "$@" ;; + get) cache_get "$@" ;; + co|checkout) svn_co "$@" && echo "checked out to $tmp/$rev/$1" ;; + run) run "$@" ;; + bisect) bisect "$@" ;; + near) near "$@" ;; + *) help ;; +esac + + Property changes on: tags/2.3.0/util/bisecter/bisecter ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/bisecter/bisecter.conf.in =================================================================== --- tags/2.3.0/util/bisecter/bisecter.conf.in (nonexistent) +++ tags/2.3.0/util/bisecter/bisecter.conf.in (revision 33253) @@ -0,0 +1,29 @@ +# where to do test compilations +tmp=/tmp/bisecter + +# where to cache executables +cache=./cache + +# command to use for stripping executables for the cache +cache_strip=strip + +# how to compress executables for the cache +cache_compress="xz -9" + +# how to decompress executables for the cache +cache_decompress="xz -d" + +# suffix the compressor appends +cache_compsuffix=".xz" + +# url to use +url=svn://svn.repo.hu/pcb-rnd/trunk + +# relative path of the executabe from url +exe=src/pcb-rnd + +# ./configure options +confopts="--debug --all=buildin --disable-acompnet" + +# first rev that's safe to test +first_rev=3800 Index: tags/2.3.0/util/build_ps.sh =================================================================== --- tags/2.3.0/util/build_ps.sh (nonexistent) +++ tags/2.3.0/util/build_ps.sh (revision 33253) @@ -0,0 +1,94 @@ +#!/bin/sh + +# convert an ordered list of html documents into ps, using .png versions of +# .svg images, inserting a page break between any two files. + +autotoc() +{ +awk ' + function inclev(level ,n,s) { + NUM[level]++ + for(n = level+1; n < 9; n++) + NUM[n] = "" + + for(n = 1; n <= level; n++) + s = s NUM[n] "." + return s + } + + /]*[>]")) { + h=substr($0, RSTART, RLENGTH) + + level=h + sub("..", "", level) + sub("[^0-9].*$", "", level) + + if (h ~ "autotoc=.yes.") { + sect=inclev(level) + print substr($0, 0, RSTART+RLENGTH-1), sect, substr($0, RSTART+RLENGTH) + next + } + else { + num=substr($0, RSTART+RLENGTH) + sub("^[ ]*", "", num) + sub("[ ].*$", "", num) + v = split(num, A, "[.]") + if (A[1] == int(A[1])) { + # learn number + if (A[v] == "") + v-- + if (v != level) { + print "WARNING: wrong section numbering (expected h" v " got h" level "): " $0 > "/dev/stderr" + } + for(n = 1; n <= v; n++) + NUM[n] = A[n] + for(n = v+1; n < 9; n++) + NUM[n] = "" + } + else { + print "WARNING: unnumbered section", $0 > "/dev/stderr" + } + } + } + + { print $0 } +' +} + +### main ### + +(for n in "$@" +do + bn1=`dirname $n` + for svg in `ls $bn1/*.svg 2>/dev/null` + do + png=${svg%%.svg}.png + if test ! -f $png + then + echo "Converting $svg to $png..." >&2 + convert $svg $png + fi + done + if test -f "$n" + then + case "$n" in + *.html) + echo ""; + sed "$HTML2PS_SED;s/\.svg/.png/g;s@src=\"@src=\"$bn1/@g" "$n" + ;; + *.png|*.svg) ;; + *) + echo "
" + echo "

$n:" + echo "

"
+				cat $n
+				echo "
" + echo "
" + esac + fi +done) | autotoc | tee HTML2PS.html | html2ps $HTML2PS_OPTS --colour + +echo html2ps $HTML2PS_OPTS --colour >&2 Property changes on: tags/2.3.0/util/build_ps.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/bxl2txt/Makefile.in =================================================================== --- tags/2.3.0/util/bxl2txt/Makefile.in (nonexistent) +++ tags/2.3.0/util/bxl2txt/Makefile.in (revision 33253) @@ -0,0 +1,52 @@ +print [@### Autogenerated by ./configure, DO NOT EDIT ### + +ROOT=../.. +PLUGDIR=$(ROOT)/src_plugins +LIBRND=$(ROOT)/src_3rd/librnd +PLUG=$(PLUGDIR)/io_bxl +CFLAGS = @/local/pcb/c89flags@ @/local/pcb/CFLAGS@ -I$(PLUG) -I$(ROOT) -I$(ROOT)/src -I$(ROOT)/src_3rd +LDFLAGS = @/local/pcb/LDFLAGS@ +CC=@cc/cc@ + +include $(LIBRND)/core/librnd.mak + +all: bxl2txt$(LIBRND_EXE) txt2bxl$(LIBRND_EXE) + +include ../../Makefile.conf + +bxl2txt$(LIBRND_EXE): bxl2txt.o bxl_decode.o + $(CC) -o bxl2txt$(LIBRND_EXE) $(LDFLAGS) bxl2txt.o bxl_decode.o + +txt2bxl$(LIBRND_EXE): txt2bxl.o bxl_decode.o + $(CC) -o txt2bxl$(LIBRND_EXE) $(LDFLAGS) txt2bxl.o bxl_decode.o + +txt2bxl.o: txt2bxl.c $(PLUG)/bxl_decode.h + $(CC) -c $(CFLAGS) txt2bxl.c -o txt2bxl.o + +bxl2txt.o: bxl2txt.c $(PLUG)/bxl_decode.h + $(CC) -c $(CFLAGS) bxl2txt.c -o bxl2txt.o + +bxl_decode.o: $(PLUG)/bxl_decode.c $(PLUG)/bxl_decode.h + $(CC) -c $(CFLAGS) $(PLUG)/bxl_decode.c -o bxl_decode.o + +install_all: + $(SCCBOX) mkdir -p "$(BINDIR)" + $(SCCBOX) $(HOW) "bxl2txt$(LIBRND_EXE)" "$(BINDIR)/bxl2txt$(LIBRND_EXE)" + $(SCCBOX) $(HOW) "txt2bxl$(LIBRND_EXE)" "$(BINDIR)/txt2bxl$(LIBRND_EXE)" + +install: + $(MAKE) install_all HOW="install" + +linstall: + $(MAKE) install_all HOW="linstall -f" + +uninstall: + $(MAKE) install_all HOW="uninstall" + +clean: + $(SCCBOX) rm -f -q bxl2txt.o txt2bxl.o bxl_decode.o bxl2txt$(LIBRND_EXE) txt2bxl$(LIBRND_EXE) + +distclean: clean + $(SCCBOX) rm -f -q Makefile + +@] Index: tags/2.3.0/util/bxl2txt/bxl2txt.c =================================================================== --- tags/2.3.0/util/bxl2txt/bxl2txt.c (nonexistent) +++ tags/2.3.0/util/bxl2txt/bxl2txt.c (revision 33253) @@ -0,0 +1,55 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * BXL IO plugin - file format read, parser + * pcb-rnd Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* test program: read bxl on stdin, unpack to stdout */ + +#include +#include "bxl_decode.h" + +int main() +{ + hdecode_t ctx; + int inch; + + pcb_bxl_decode_init(&ctx); + + while((inch = fgetc(stdin)) != EOF) { + int n, len; + len = pcb_bxl_decode_char(&ctx, inch); +/* for(n = 0; n < len; n++) + printf("%c %d\n", ctx.out[n], ctx.out[n]);*/ + for(n = 0; n < len; n++) + printf("%c", ctx.out[n]); + } + +/*fprintf(stderr, "plain len=%lu %lu\n", ctx.plain_len, ctx.ipos);*/ +/*fprintf(stderr, "pool used: %d\n", ctx.tree->pool_used);*/ + + return 0; +} Index: tags/2.3.0/util/bxl2txt/txt2bxl.c =================================================================== --- tags/2.3.0/util/bxl2txt/txt2bxl.c (nonexistent) +++ tags/2.3.0/util/bxl2txt/txt2bxl.c (revision 33253) @@ -0,0 +1,69 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * + * BXL IO plugin - file format write, encoder + * pcb-rnd Copyright (C) 2020 Tibor 'Igor2' Palinkas + * (Supported by NLnet NGI0 PET Fund in 2020) + * + * 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/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +/* test program: read plain text on stdin, encode to bxl to the named file */ + +#include +#include "bxl_decode.h" + +void out(FILE *f, hdecode_t *ctx, int len) +{ + int n; + for(n = 0; n < len; n++) + fputc(ctx->out[n], f); +} + +int main(int argc, char *argv[]) +{ + hdecode_t ctx; + int inch, len, fd; + FILE *f; + + if (argc < 2) { + fprintf(stderr, "Need an output file name\n"); + return 1; + } + + f = fopen(argv[1], "wb"); + if (f == NULL) { + fprintf(stderr, "Failed to open %s for write\n", argv[1]); + return 1; + } + + pcb_bxl_encode_init(&ctx); + + while((inch = fgetc(stdin)) != EOF) + out(f, &ctx, pcb_bxl_encode_char(&ctx, inch)); + out(f, &ctx, pcb_bxl_encode_eof(&ctx)); + + fseek(f, 0, SEEK_SET); + out(f, &ctx, pcb_bxl_encode_len(&ctx)); + + return 0; +} Index: tags/2.3.0/util/cgi_common.sh =================================================================== --- tags/2.3.0/util/cgi_common.sh (nonexistent) +++ tags/2.3.0/util/cgi_common.sh (revision 33253) @@ -0,0 +1,120 @@ +#!/bin/sh + +# shell lib + +url_decode() +{ +awk ' + function cd(n) + { + chr=sprintf("%c", n); + if (chr == "&") + chr = "\\&" + code="%" sprintf("%02x", n); + CODE[tolower(code)] = chr; + CODE[toupper(code)] = chr; + } + + BEGIN { + for(n = 1; n < 256; n++) + cd(n); + } + + { + tmp = $0; + gsub("[+]", " ", tmp); + for(c in CODE) { + gsub(c, CODE[c], tmp) + } + print tmp + } +' +} + +error() +{ + echo "Content-type: text/plain" + echo "" + echo "Error: $*" + exit 0 +} + +radio() +{ + local chk + if test "$3" = "$2" + then + chk=" checked=\"true\"" + fi + echo "" +} + +checked() +{ + if test ! -z "$1" + then + echo " checked=\"true\"" + fi +} + +fix_ltgt() +{ + sed "s//\>/g" +} + +cgi_png() +{ + local fptmp + echo "#$fp_full#" > /tmp/L13 + echo "Content-type: image/png" + echo "" + cparm="" + if test ! -z "$QS_mm" + then + cparm="$cparm --mm" + fi + if test ! -z "$QS_grid" + then + cparm="$cparm --grid-unit $QS_grid" + fi + if test ! -z "$QS_annotation" + then + annot=$QS_annotation + fi + if test ! -z "$QS_photo" + then + cparm="$cparm --photo" + fi + if test ! -z "$QS_dimvalue" + then + annot="$annot:dimvalue" + fi + if test ! -z "$QS_dimname" + then + annot="$annot:dimname" + fi + if test ! -z "$QS_pins" + then + annot="$annot:pins" + fi + if test ! -z "$QS_background" + then + annot="$annot:background" + fi + case "$QS_thumb" + in + 1) animarg="-x 64 -y 48" ;; + 2) animarg="-x 128 -y 96" ;; + 3) animarg="-x 192 -y 144" ;; + *) animarg="" ;; + esac + if test ! -z "$annot" + then + cparm="$cparm --annotation $annot" + fi + + fptmp=`mktemp` + $fp2preview --outfile $fptmp $cparm "$fp_full" >/dev/null 2>&1 + cat $fptmp + rm $fptmp +} Index: tags/2.3.0/util/devhelpers/404.sh =================================================================== --- tags/2.3.0/util/devhelpers/404.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/404.sh (revision 33253) @@ -0,0 +1,24 @@ +#!/bin/sh + +# search the official web page for broken links + +echo "Collecting the log..." >&2 +wget --spider -o 404.raw.log -r -p http://repo.hu/projects/pcb-rnd + +echo "Evaluatng the log..." >&2 +awk ' + function report() { + print url + rerorted = 1 + } + + /^--/ { + url=$0 + sub("--.*-- *", "", url) + sub("^[(]try[^)]*[)] *", "", url) + } + /^$/ { url = ""; reported = 0 } + (reported) { next } + /response.*404/ { report() } + /broken link/ { report() } +' < 404.raw.log | tee 404.log Property changes on: tags/2.3.0/util/devhelpers/404.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/awk_on_formats.sh =================================================================== --- tags/2.3.0/util/devhelpers/awk_on_formats.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/awk_on_formats.sh (revision 33253) @@ -0,0 +1,86 @@ +# shell lib + +# Read and parse all pups, make an array of file formats of +# FMTS[import|export, type] then read stdin and execute the awk +# script specified in $1 on it +awk_on_formats() +{ +(for n in $ROOT/src_plugins/*/*.pup +do + echo "@@@ $n" + cat $n +done +echo "@@@@@@" +cat +) | awk ' + +BEGIN { + osep = "
" + types="board footprint netlist image misc" +} + +($1 == "@@@") { + mode = 1 + plugin=$n + sub(".*/", "", plugin) + sub("\.pup", "", plugin) + fmt = plugin + sub("io_", "", fmt) + sub("import_", "", fmt) + sub("export_", "", fmt) + next +} + +($1 == "@@@@@@") { + mode = 2 + next +} + +function add(name, dir ,type,lname) +{ + lname = tolower(name) +# DO NOT FORGET TO UDPATE types IN BEGIN ^^^ + if (name ~ "netlist") + type = "netlist" + else if (lname ~ "schematic") + type = "netlist" + else if (lname ~ "footprint") + type = "footprint" + else if (lname ~ "kicad.*module") + type = "footprint" + else if (lname ~ "board") + type = "board" + else if (lname ~ "render") + type = "image" + else if (lname ~ "pixmap") + type = "image" + else if (lname ~ "bitmap") + type = "image" + else if (lname ~ "graphic") + type = "image" + else + type = "misc" +# DO NOT FORGET TO UDPATE types IN BEGIN ^^^ + + if (FMTS[dir, type] == "") + FMTS[dir, type] = name + else + FMTS[dir, type] = FMTS[dir, type] osep name +} + +(mode == 1) && ($1 == "$fmt-feature-r") { + $1="" + add($0, "import") + next +} + +(mode == 1) && ($1 == "$fmt-feature-w") { + $1="" + add($0, "export") + next +} + +(mode != 2) { next } +'"$1" + +} Index: tags/2.3.0/util/devhelpers/chlog.sh =================================================================== --- tags/2.3.0/util/devhelpers/chlog.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/chlog.sh (revision 33253) @@ -0,0 +1,2 @@ +#!/bin/sh +svn log -r$1:HEAD | grep -v "^\(-*$\|r[0-9]\+\)" Property changes on: tags/2.3.0/util/devhelpers/chlog.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/chlog_sort.sh =================================================================== --- tags/2.3.0/util/devhelpers/chlog_sort.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/chlog_sort.sh (revision 33253) @@ -0,0 +1,37 @@ +#!/bin/sh + +# read the outpot of chlog.sh and split it per topic and save the lines +# into changelog-formatted files + +awk ' + BEGIN { + IGNORE["todo"]=1 + IGNORE["devlog"]=1 + IGNORE["bugreport"]=1 + IGNORE["blog_queue"]=1 + } + + ($1 ~ "^[[][^]]*\]$") { + tag=tolower($1) + sub("[[]", "", tag) + sub("\]", "", tag) + + if (tag in IGNORE) + next + + $1="" + line=$0 + sub("^[ \t]*", " ", line) + if (!(tag in SEEN)) { + print " [" tag "]" > "CHG." tag + SEEN[tag]++ + } + print line > "CHG." tag + next + } + { + line=$0 + sub("^[ \t]*", " ", line) + print line > "CHG.MISC" + } +' Property changes on: tags/2.3.0/util/devhelpers/chlog_sort.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/comment_hunt.sh =================================================================== --- tags/2.3.0/util/devhelpers/comment_hunt.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/comment_hunt.sh (revision 33253) @@ -0,0 +1,34 @@ +#!/bin/sh + +# Hunt for comments that are longer than $1 in all file names specified after +# $1. Useful for detecting documentation that should be migrated from code to +# doc/ + +hunt() +{ +awk -v "THR=$1" -v "fn=$2" ' +(open) { comment = comment $0 "\n"; cnt++ } + +/\/[*]/ && (!open) { + open=1 + cnt=1 + comment=$0 "\n" +} + +/[*]\// && (open) { + if ((cnt > THR) && (!(comment ~ "MERCHANTABILITY"))) + print fn "::" cnt "::" comment + open=0 + cnt=0 + comment="" +} + +' < $2 +} + +THR=$1 +shift 1 +for n in $* +do + hunt $THR $n +done Property changes on: tags/2.3.0/util/devhelpers/comment_hunt.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/copyright_miss.sh =================================================================== --- tags/2.3.0/util/devhelpers/copyright_miss.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/copyright_miss.sh (revision 33253) @@ -0,0 +1,8 @@ +#!/bin/sh + +# This file is placed in the Public Domain. + +# Print the path of source files that may miss the copyright banner among +# with their length in line + +find . -name '*.[chly]' -exec sh -c 'grep "^ [*] Copyright [(]C[)]" {} >/dev/null || wc -l "{}"' \; Property changes on: tags/2.3.0/util/devhelpers/copyright_miss.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/deblist.sh =================================================================== --- tags/2.3.0/util/devhelpers/deblist.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/deblist.sh (revision 33253) @@ -0,0 +1,69 @@ +#!/bin/sh + +# Process the debian/control file and produce a html table that explains +# the purpose of each package + +echo ' + + + + pcb-rnd - Debian package list + + + + + + + + + + +

pcb-rnd - Debian package list

+ +
name internal dependencies description +' + +awk ' +function out() +{ + if (pkg == "") + return + print "
" pkg "" deps "" desc + pkg="" + deps="" + desc="" + para=0 +} + +/^Package:/ { + out(); + pkg=$2 + para=0 +} +#Depends: ${misc:Depends}, ${shlibs:Depends}, pcb-rnd-core, pcb-rnd-gtk +/^Depends:/ { + deps=$0 + sub("Depends: *", "", deps) + gsub("[$][{][^}]*[}],?", "", deps) +} + +/^ [.]/ { + if (para > 0) + desc = desc "

" + para++ + next +} + +(para > 0) { + desc = desc " " $0 +} + +END { + out() +} +' + + +echo ' +

+' \ No newline at end of file Property changes on: tags/2.3.0/util/devhelpers/deblist.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/font2c.sh =================================================================== --- tags/2.3.0/util/devhelpers/font2c.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/font2c.sh (revision 33253) @@ -0,0 +1,96 @@ +#!/bin/sh +# font2c - convert a pcb font to simplified embedded font structs for pcb-rnd +# Copyright (C) 2016 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. +# +# http://repo.hu/projects/pcb-rnd + +awk ' + +BEGIN { + minx = 100000 + miny = 100000 + maxx = 0 + maxy = 0 + print "/* This file is autogenerated by font2c.sh - DO NOT EDIT */" + print "" + print "/* Internal copy of the default font; used when no font file is found */" + print "" +} + +function bump(x, y) +{ + if (x < minx) minx = x + if (y < miny) miny = y + if (x > maxx) maxx = x + if (y > maxy) maxy = y +} + +/Symbol[(]/ { + sym=substr($0, 9, 1) + ADV[sym]=int(substr($0, 11, length($0))) + NLINE[sym] = 0 +} + +/SymbolLine[(]/ { + sub("[ \t]*SymbolLine[(]", "", $0) + X1[sym, NLINE[sym]] = int($1) + Y1[sym, NLINE[sym]] = int($2) + X2[sym, NLINE[sym]] = int($3) + Y2[sym, NLINE[sym]] = int($4) + TH[sym, NLINE[sym]] = int($5) + bump(int($1), int($2)) + bump(int($3), int($4)) + NLINE[sym]++ +} + +END { + for(n = 0; n < 128; n++) { + c = sprintf("%c", n) + if (c in ADV) { + if ((n > 32) && !(c ~ "[{}()]")) + annot = " /* " c " */" + else + annot = "" + print "static embf_line_t embf_line_" n "[] = {" annot + for(l = 0; l < NLINE[c]; l++) + print " {" X1[c, l] ", " Y1[c, l] ",\t\t" X2[c, l] ", " Y2[c, l] ",\t\t" TH[c, l] "}" ((l < NLINE[c]-1) ? "," : "") + if (NLINE[c] == 0) + print " {0,0,0,0}" + print "};" + }; + } + + print "/***************************************************************/" + print "static int embf_minx = " minx ";" + print "static int embf_miny = " miny ";" + print "static int embf_maxx = " maxx ";" + print "static int embf_maxy = " maxy ";" + + print "static embf_font_t embf_font[] = {" + for(n = 0; n < 128; n++) { + c = sprintf("%c", n) + comma = ((n < 127) ? "," : "") + if (c in ADV) { + print " {" ADV[c] ", embf_line_" n ", " NLINE[c] "}" comma + } + else { + print " {0, NULL, 0}" comma + } + } + print "};" +} +' Property changes on: tags/2.3.0/util/devhelpers/font2c.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/inc_valid.sh =================================================================== --- tags/2.3.0/util/devhelpers/inc_valid.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/inc_valid.sh (revision 33253) @@ -0,0 +1,56 @@ +#!/bin/sh +# inc_weed_out - check whether a source file has valid #includes for pcb-rnd +# Copyright (C) 2016 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. +# +# http://repo.hu/projects/pcb-rnd + +# include validation: +# - in .c files config.h must be included +# - warn for duplicate #includes + +# Usage: +# 1. compile the whole project so that all dependencies of the target file are compiled +# 2. inc_valid.sh foo.c +# 3. check the output, fix #includes +# 4. compile by hand to check +# +# NOTE: conditional code also requires manual examination + +# set up file names +fn_c=$1 + +# comment one #include (index is $1, save output in $2, print the #include line to stdout) +valid() +{ + awk -v "fn=$1" ' + /^#[ \t]*include/ { + SEEN[$2]++ + } + END { + for(h in SEEN) + if (SEEN[h] > 1) + print "W " fn ": multiple include of " h + if ((fn ~ "[.]c$") && (! ("\"config.h\"" in SEEN))) + print "E " fn ": missing config.h" + } + ' < "$1" +} + +for n in "$@" +do + valid "$n" +done Property changes on: tags/2.3.0/util/devhelpers/inc_valid.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/inc_weed_out.sh =================================================================== --- tags/2.3.0/util/devhelpers/inc_weed_out.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/inc_weed_out.sh (revision 33253) @@ -0,0 +1,94 @@ +#!/bin/sh +# inc_weed_out - list #includes that can be removed without introducing warnings +# Copyright (C) 2016 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. +# +# http://repo.hu/projects/pcb-rnd + +# include weed-out: attempt to compile an object with each #include lines +# commented out one by one; if commenting an #include doesn't change compiler +# warnings, that include is potentially unneeded. + +# Usage: +# 1. compile the whole project so that all dependencies of the target file are compiled +# 2. inc_weed_out.sh foo.c +# 3. check the output, remove #includes +# 4. compile by hand to check +# +# NOTE: the script runs 'make foo.o' - your local Makefile needs to be able +# to compile foo.o +# NOTE: sometimes disabling multiple #includes have different effect than +# disabling them one by one - always check manually. +# NOTE: conditional code also requires manual examination - the script may +# find an #include can be removed with the current settings but the +# same include may be needed with different ./configure settings + +# set up file names +fn_c=$1 +fn_o=${1%.c}.o +fn_c_backup=$fn_c.inc_weed_out +fn_refo=$1.refo +fn_tmpo=$1.tmpo + +# comment one #include (index is $1, save output in $2, print the #include line to stdout) +weed_out() +{ + awk -v "target=$1" -v "outf=$2" ' + /^#[ \t]*include/ { + count++ + if (count == target) { + print "/*" $0 "*/" > outf + print $0 + found=1 + next + } + } + { print $0 > outf } + END { + exit(found!=1) + } + ' +} + +# make a backup +cp $fn_c $fn_c_backup + +# generate initial/reference warning text +touch $fn_c +make $fn_o >/dev/null 2>$fn_refo + +# loop over #include indices +cnt=1 +while true +do + # comment out the next #include or break if there's no more + name=`weed_out $cnt < $fn_c_backup $fn_c` + if test -z "$name" + then + break + fi + + # test compile to see if we got new warnings compared to the reference + make $fn_o 2>$fn_tmpo >/dev/null + diff $fn_refo $fn_tmpo >/dev/null && echo REMOVE: $fn_c $cnt $name + + # start over + cnt=$(($cnt+1)) +done + +# clean up +mv $fn_c_backup $fn_c +rm $fn_refo $fn_tmpo Property changes on: tags/2.3.0/util/devhelpers/inc_weed_out.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/list_dialogs.sh =================================================================== --- tags/2.3.0/util/devhelpers/list_dialogs.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/list_dialogs.sh (revision 33253) @@ -0,0 +1,34 @@ +#!/bin/sh + +# assumes running from the source tree + +trunk=$(dirname $0)/../.. + +grep PCB_DAD_NEW $trunk/src/*.c $trunk/src_plugins/*/*.c | awk ' + ($1 ~ "TEMPLATE") { next } + { + file=$1 + name=$0 + sub(":$", "", file) + sub(".*src/", "src/", file) + sub(".*src_plugins/", "src_plugins/", file) + sub(".*PCB_DAD_NEW[^(]*[(]", "", name) + title=name + if (name ~ "^\"") { + sub("\"", "", name) + sub("\".*", "", name) + } + else + name = "" + + sub("[^,]*,[^,]*, *", "", title) + if (title ~ "^\"") { + sub("\"", "", title) + sub("\".*", "", title) + } + else + title = "" + + print name "\t" title "\t" file + } +' Property changes on: tags/2.3.0/util/devhelpers/list_dialogs.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/param_all.sh =================================================================== --- tags/2.3.0/util/devhelpers/param_all.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/param_all.sh (revision 33253) @@ -0,0 +1,105 @@ +#!/bin/sh + +# Generate and render parametric footprints with variations of parameters +# for testing + +fp="$1" +shift 1 +args="$@" + +$fp --help | awk -F "[: \t]+" -v fp=$fp -v "args=$args" ' +BEGIN { order = 0 } + +/#@@param/ { PARAMS[$2]++ } + +/#@@param/ { ORDER[order++] = $2 } +/#@@dim/ { TYPE[$2] = "dim" } + +/#@@enum/ { + TYPE[$2] = "enum" + if (ENUM[$2] == "") + ENUM[$2] = $3 + else + ENUM[$2] = ENUM[$2] "," $3 +} + +function build(param, value, PV,p,s,cmd,fn) +{ + for(p in ARG) + PV[p] = ARG[p] + + if (param != "") + PV[param] = value + + for(o = 0; o < order; o++) { + p = ORDER[o] + if ((p == "") || !(p in PV)) + continue + if (s == "") + s = p "=" PV[p] + else + s = s "," p "=" PV[p] + } + + + fn = s + gsub("[^A-Za-z0-9-]", "_", fn) + fn = fp "_" fn ".lht" + system(fp " " q s q ">" fn) + + close(cmd) + cmd="pcb-rnd --hid batch" + print "LoadFrom(Layout, " fn ")" | cmd + print "autocrop" | cmd + print "export(png, --dpi, 1200)" | cmd + close(cmd) +} + +function permute(param ,n,v,E) +{ + if (TYPE[param] == "enum") { + v = split(ENUM[param], E, ",") + for(n = 1; n <= v; n++) { + build(param, E[n]) + } + } + if (TYPE[param] == "dim") { + if (param in ARG) { + build(param, ARG[param]) + build(param, ARG[param]*2) + build(param, ARG[param]*4) + } + else { + if ((param ~ "clearance") || (param ~ "mask") || (param ~ "paste")) { + # skip + } + else if ((param ~ "drill") || (param ~ "thickness")) { + build(param, "0.2mm") + build(param, "0.4mm") + build(param, "0.8mm") + } + else { + build(param, "2mm") + build(param, "4mm") + build(param, "8mm") + } + } + } +} + +END { + v = split(args, A, ",[ \t]*") + for(n = 1; n <= v; n++) { + split(A[n], B, "[=]") + ARG[B[1]] = B[2] + } + for(p in PARAMS) + permute(p) +} + +' + + + + + Property changes on: tags/2.3.0/util/devhelpers/param_all.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/pcb-rtrip =================================================================== --- tags/2.3.0/util/devhelpers/pcb-rtrip (nonexistent) +++ tags/2.3.0/util/devhelpers/pcb-rtrip (revision 33253) @@ -0,0 +1,122 @@ +#!/bin/sh +# pcb-rtrip - load-save-load round trip tester +# Copyright (C) 2016 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. +# +# http://repo.hu/projects/pcb-rnd + +pcb_rtrip() +{ + rm -f "$fn.new.pcb" + + if test ! -z "$remtgt" + then + rm -f "$fn.trgt.$ext" + fi + +echo ' +SaveTo(LayoutAs, '$fn'.orig.pcb, pcb) +LoadFrom(Layout, '$fn'.orig.pcb) +SaveTo(LayoutAs, '$fn'.trgt.'$ext', '$fmt') +LoadFrom(Layout, '$fn'.trgt.'$ext', '$fmt') +SaveTo(LayoutAs, '$fn'.new.pcb, pcb) +' | $valg $pcb_rnd_bin --gui batch "$fn" + + if test -f "$fn.orig.pcb" -a -f "$fn.new.pcb" + then + diff -u "$fn.orig.pcb" "$fn.new.pcb" + else + if test ! -f "$fn.orig.pcb" + then + echo "Failed to load $fn" + else + echo "Failed to load $fn.trgt.$ext" + fi + fi +} + +set_ext() +{ + case "$fmt" + in + lihata) ext="lht";; + pcb) ext="pcb";; + *) ext="$fmt";; + esac +} + +help() +{ + echo "pcb-rtrip - load-save-load round trip tester" + echo "" + echo "Load a board, save it (*.orig.pcb), load it, save it in the target" + echo "format (*.trgt.*), load it again and save it (*.new.pcb). Calculate" + echo "the diff between *.orig.pcb and *.new.pcb; if load-save-load round trip" + echo "of a target format is lossles, the diff is empty." + echo "" + echo "Invocation: $0 [-f fmt] [input.pcb]" + echo "Switches:" + echo " -f fmt format (e.g. lihata)" + echo " -r remove target before overwrite" + echo " -b bin run bin instead of \"pcb-rnd\"" + echo " -V wrap the binary in valgrind" + echo "" +} + + +# defaults +fmt="lihata" +fn="" +remtgt="" +if test -z "$pcb_rnd_bin" +then + pcb_rnd_bin="pcb-rnd" +fi +valg="" + +while test $# -gt 0 +do + case "$1" + in + --help) help "$0"; exit 0;; + -f) fmt=$2; shift 1;; + -b) pcb_rnd_bin=$2; shift 1;; + -V) valg="valgrind -v";; + -r) remtgt=1;; + *) + if test -z "$fn" + then + fn="$1" + else + echo "unknown switch $1; try --help" >&2 + exit 1 + fi + ;; + -*) echo "unknown switch $1; try --help" >&2; exit 1;; + esac + shift 1 +done + +if test -z "$fn" +then + echo "no fn" + exit 1 + fn="pcb-rtrip.pcb" + cat >$fn +fi + +set_ext +pcb_rtrip Property changes on: tags/2.3.0/util/devhelpers/pcb-rtrip ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/plug_dep_test.sh =================================================================== --- tags/2.3.0/util/devhelpers/plug_dep_test.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/plug_dep_test.sh (revision 33253) @@ -0,0 +1,118 @@ +#!/bin/sh +# plug_dep_test - detect missing plugin-plugin dependencies +# 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. +# +# http://repo.hu/projects/pcb-rnd +# + +# tip: installing ccache will speed this up a lot! + +tmp="/tmp/pcb-rnd-pdt" +URL="svn://repo.hu/pcb-rnd/trunk" +conf="--debug" +make_paral="-j8" +#make_silent="-s" + + +# compile pcb-rnd, appending the compilation details to the log +# $1 is why we are compiling +compile() +{ + make $make_paral $make_silent >> PDT.$1.log 2>&1 +} + +# create a new checkout or update an existing checkout +checkout() +{ + mkdir -p "$tmp" + cd "$tmp" + svn checkout "$URL" + cd trunk +} + +# clean up the checkout directory, just in case it is an existing checkout +cleanup_checkout() +{ + make clean + make distclean + rm scconfig/config.cache.golden +} + +# reference compilation: core only, no plugin enabled +ref_compile() +{ +# create the golden scconig cache that will speed up further compilation + ./configure $conf --all=disable 2>&1 | tee PDT._ref.log + grep -v "^/local/\|^/tmpasm/" scconfig/config.cache > scconfig/config.cache.golden + +# reference compilation + compile _ref +} + + +# print all plugin names (newline separated list) +list_plugs() +{ +awk ' +/^[^#]/ { + plg=$0 + sub("/Plug.tmpasm.*", "", plg) + sub(".*/", "", plg) + print plg +} +' < src_plugins/plugins_ALL.tmpasm +} + +# configure with only one plugin builtin and everything else disabled +# if there is compilation error, it's likely a broken dependency (linker +# error on another plugin that is now disabled) +test_plug_() +{ + rm src/*.a src/*.o src_plugins/*/*.o util/*.o util/*/*.o > PDT.$1.log 2>&1 + ./configure $conf --import=config.cache.golden --all=disable --buildin-$1 >> PDT.$1.log 2>&1 && \ + compile $1 +} + +# test one plugin and print the result +test_plug() +{ + echo -n "$1: " + test_plug_ $1 + if test $? = 0 + then + echo "ok" + else + echo "BROKEN, see PDT.$1.log" + fi +} + +test_all_plugins() +{ + cd "$tmp/trunk" + plugs=`list_plugs` + for plug in $plugs + do + test_plug $plug + done +} + +### main ### + +checkout +cleanup_checkout +ref_compile +test_all_plugins Property changes on: tags/2.3.0/util/devhelpers/plug_dep_test.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/rename.sh =================================================================== --- tags/2.3.0/util/devhelpers/rename.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/rename.sh (revision 33253) @@ -0,0 +1,5 @@ +#!/bin/sh + +find . -name '*.[chly]' -exec sed -i "$@" {} \; +find . -name 'config.h.in' -exec sed -i "$@" {} \; + Property changes on: tags/2.3.0/util/devhelpers/rename.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/renamea.sh =================================================================== --- tags/2.3.0/util/devhelpers/renamea.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/renamea.sh (revision 33253) @@ -0,0 +1,10 @@ +#!/bin/sh +echo "Renaming action $1" >&2 + +na=`echo $1 | sed "s/^Action//"` +lc=`echo $na | tr "[A-Z]" "[a-z]"` + +./renameo.sh "$1" "pcb_act_$na" +./renameo.sh "${lc}_help" "pcb_acth_$na" +./renameo.sh "${lc}_syntax" "pcb_acts_$na" +./rename.sh "s/\\([^a-zA-Z0-9_]\\)AFAIL[(]${lc}[)]/\\1PCB_ACT_FAIL($na)/g" Property changes on: tags/2.3.0/util/devhelpers/renamea.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/renamef.sh =================================================================== --- tags/2.3.0/util/devhelpers/renamef.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/renamef.sh (revision 33253) @@ -0,0 +1,8 @@ +#!/bin/sh + +# Rename a function and log + +./rename.sh "s/\\([^a-zA-Z0-9_>.]\\)${1}[ \t]*[(]/\\1$2(/g" +./rename.sh "s/^${1}[ \t]*[(]/$2(/g" + +#echo "#define $1 $2" >> src/librnd/pcb_compat.h Property changes on: tags/2.3.0/util/devhelpers/renamef.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/renameo.sh =================================================================== --- tags/2.3.0/util/devhelpers/renameo.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/renameo.sh (revision 33253) @@ -0,0 +1,9 @@ +#!/bin/sh + +./rename.sh " + s/\\([^a-zA-Z0-9_]\\)${1}\\([^a-zA-Z0-9_]\\)/\\1$2\\2/g; + s/^${1}\\([^a-zA-Z0-9_]\\)/$2\\1/g; + s/\\([^a-zA-Z0-9_]\\)${1}$/\\1$2/g; +" + +echo "$1 -> $2" >> doc/developer/renames Property changes on: tags/2.3.0/util/devhelpers/renameo.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/subst/README =================================================================== --- tags/2.3.0/util/devhelpers/subst/README (nonexistent) +++ tags/2.3.0/util/devhelpers/subst/README (revision 33253) @@ -0,0 +1,3 @@ +Scripts to convert mainline code to pcb-rnd after the namespace cleanups in +trunk/ + Index: tags/2.3.0/util/devhelpers/subst/subst_const.sh =================================================================== --- tags/2.3.0/util/devhelpers/subst/subst_const.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/subst/subst_const.sh (revision 33253) @@ -0,0 +1,25 @@ +#!/bin/sh +for n in `find . -name "*.[chly]"` +do +sed ' +{ + +s/COORD_TO_MIL/PCB_COORD_TO_MIL/g +s/MIL_TO_COORD/PCB_MIL_TO_COORD/g +s/COORD_TO_MM/PCB_COORD_TO_MM/g +s/MM_TO_COORD/PCB_MM_TO_COORD/g +s/COORD_TO_INCH/PCB_COORD_TO_INCH/g +s/INCH_TO_COORD/PCB_INCH_TO_COORD/g + +s/RAD_TO_DEG/PCB_RAD_TO_DEG/g +s/TAN_22_5_DEGREE_2/PCB_TAN_22_5_DEGREE_2/g +s/COS_22_5_DEGREE/PCB_COS_22_5_DEGREE/g +s/TAN_30_DEGREE/PCB_TAN_30_DEGREE/g +s/TAN_60_DEGREE/PCB_TAN_60_DEGREE/g +s/LN_2_OVER_2/PCB_LN_2_OVER_2/g +s/UNSCALE_TEXT/PCB_UNSCALE_TEXT/g +s/SCALE_TEXT/PCB_SCALE_TEXT/g +s/M180/PCB_M180/g +} +' -i $n +done Property changes on: tags/2.3.0/util/devhelpers/subst/subst_const.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/subst/subst_flags.sh =================================================================== --- tags/2.3.0/util/devhelpers/subst/subst_flags.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/subst/subst_flags.sh (revision 33253) @@ -0,0 +1,38 @@ +#!/bin/sh +for n in `find . -name "*.[chly]"` +do +sed ' +{ +s/NOPASTEFLAG/PCB_FLAG_NOPASTE/g +s/PININPOLYFLAG/PCB_FLAG_PININPOLY/g +s/CLEARPOLYFLAG/PCB_FLAG_CLEARPOLY/g +s/HIDENAMEFLAG/PCB_FLAG_HIDENAME/g +s/DISPLAYNAMEFLAG/PCB_FLAG_DISPLAYNAME/g +s/CLEARLINEFLAG/PCB_FLAG_CLEARLINE/g +s/FULLPOLYFLAG/PCB_FLAG_FULLPOLY/g +s/SELECTEDFLAG/PCB_FLAG_SELECTED/g +s/ONSOLDERFLAG/PCB_FLAG_ONSOLDER/g +s/SQUAREFLAG/PCB_FLAG_SQUARE/g +s/RUBBERENDFLAG/PCB_FLAG_RUBBEREND/g +s/USETHERMALFLAG/PCB_FLAG_USETHERMAL/g +s/ONSILKFLAG/PCB_FLAG_ONSILK/g +s/OCTAGONFLAG/PCB_FLAG_OCTAGON/g +s/LOCKFLAG/PCB_FLAG_LOCK/g +s/EDGE2FLAG/PCB_FLAG_EDGE2/g +s/VISITFLAG/PCB_FLAG_VISIT/g +s/NONETLISTFLAG/PCB_FLAG_NONETLIST/g +s/MINCUTFLAG/PCB_FLAG_MINCUT/g +s/ONPOINTFLAG/PCB_FLAG_ONPOINT/g +s/NOCOPY_FLAGS/PCB_FLAG_NOCOPY/g +s/FOUNDFLAG/PCB_FLAG_FOUND/g +s/HOLEFLAG/PCB_FLAG_HOLE/g +s/AUTOFLAG/PCB_FLAG_AUTO/g +s/WARNFLAG/PCB_FLAG_WARN/g +s/RATFLAG/PCB_FLAG_RAT/g +s/PINFLAG/PCB_FLAG_PIN/g +s/VIAFLAG/PCB_FLAG_VIA/g +s/DRCFLAG/PCB_FLAG_DRC/g +s/NOFLAG/PCB_FLAG_NO/g +} +' -i $n +done Property changes on: tags/2.3.0/util/devhelpers/subst/subst_flags.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/subst/subst_mode.sh =================================================================== --- tags/2.3.0/util/devhelpers/subst/subst_mode.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/subst/subst_mode.sh (revision 33253) @@ -0,0 +1,27 @@ +#!/bin/sh +for n in `find . -name "*.[chly]"` +do +sed ' +{ + s/RECTANGLE_MODE/PCB_MODE_RECTANGLE/g + s/POLYGON_MODE/PCB_MODE_POLYGON/g + s/PASTEBUFFER_MODE/PCB_MODE_PASTE_BUFFER/g + s/ROTATE_MODE/PCB_MODE_ROTATE/g + s/REMOVE_MODE/PCB_MODE_REMOVE/g + s/INSERTPOINT_MODE/PCB_MODE_INSERT_POINT/g + s/RUBBERBANDMOVE_MODE/PCB_MODE_RUBBERBAND_MOVE/g + s/THERMAL_MODE/PCB_MODE_THERMAL/g + s/ARROW_MODE/PCB_MODE_ARROW/g + s/LOCK_MODE/PCB_MODE_LOCK/g + s/POLYGONHOLE_MODE/PCB_MODE_POLYGON_HOLE/g + s/ARC_MODE/PCB_MODE_ARC/g + s/PAN_MODE/PCB_MODE_PAN/g + s/MOVE_MODE/PCB_MODE_MOVE/g + s/COPY_MODE/PCB_MODE_COPY/g + s/TEXT_MODE/PCB_MODE_TEXT/g + s/NO_MODE/PCB_MODE_NO/g + s/VIA_MODE/PCB_MODE_VIA/g + s/LINE_MODE/PCB_MODE_LINE/g +} +' -i $n +done Property changes on: tags/2.3.0/util/devhelpers/subst/subst_mode.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/subst/subst_objtype.sh =================================================================== --- tags/2.3.0/util/devhelpers/subst/subst_objtype.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/subst/subst_objtype.sh (revision 33253) @@ -0,0 +1,30 @@ +#!/bin/sh +for n in `find . -name *.[chly]` +do +sed ' +{ +s/PIN_TYPES/PCB_TYPEMASK_PIN/g; +s/LOCK_TYPES/PCB_TYPEMASK_LOCK/g; +s/ALL_TYPES/PCB_TYPEMASK_ALL/g; + +s/RATLINE_TYPE/PCB_TYPE_RATLINE/g; +s/ELEMENTNAME_TYPE/PCB_TYPE_ELEMENT_NAME/g; +s/POLYGONPOINT_TYPE/PCB_TYPE_POLYGON_POINT/g; +s/LINEPOINT_TYPE/PCB_TYPE_LINE_POINT/g; +s/ELEMENTLINE_TYPE/PCB_TYPE_ELEMENT_LINE/g; +s/ELEMENTARC_TYPE/PCB_TYPE_ELEMENT_ARC/g; + +s/NO_TYPE/PCB_TYPE_NONE/g; +s/VIA_TYPE/PCB_TYPE_VIA/g; +s/ELEMENT_TYPE/PCB_TYPE_ELEMENT/g; +s/LINE_TYPE/PCB_TYPE_LINE/g; +s/POLYGON_TYPE/PCB_TYPE_POLYGON/g; +s/TEXT_TYPE/PCB_TYPE_TEXT/g; +s/PIN_TYPE/PCB_TYPE_PIN/g; +s/PAD_TYPE/PCB_TYPE_PAD/g; +s/ARC_TYPE/PCB_TYPE_ARC/g; +s/LOCKED_TYPE/PCB_TYPE_LOCKED/g; +s/NET_TYPE/PCB_TYPE_NET/g; +} +' -i $n +done Property changes on: tags/2.3.0/util/devhelpers/subst/subst_objtype.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/devhelpers/todo.sh =================================================================== --- tags/2.3.0/util/devhelpers/todo.sh (nonexistent) +++ tags/2.3.0/util/devhelpers/todo.sh (revision 33253) @@ -0,0 +1,3 @@ +#!/bin/sh +files=`find ../.. -name *.[chly]` +grep "^[ \t]*TODO[(]" $files Property changes on: tags/2.3.0/util/devhelpers/todo.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/fp2preview =================================================================== --- tags/2.3.0/util/fp2preview (nonexistent) +++ tags/2.3.0/util/fp2preview (revision 33253) @@ -0,0 +1,274 @@ +#!/bin/sh +# fp2preview - convert a library footprint to preview image +# Copyright (C) 2015,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. +# +# http://repo.hu/projects/pcb-rnd + + +# depends on the diag and the autocrop plugins + +photo=0 +grid_unit="mil" +dpi=600 +outfile=fp2preview.png + +annotation=pins + +while test $# -gt 0 +do + case "$1" in + --outfile) outfile="$2"; shift 1;; + --dpi) dpi="$2"; shift 1;; + --photo|p) photo=1;; + --grid-unit|g) grid_unit="$2"; shift 1;; + --mm) grid_unit="mm";; + --annotation) annotation="$2"; shift 1;; + *) + if test ! -z "$fp" + then + echo "only one footprint name is accepted; got: '$fp' and '$1'" >&1 + exit 1 + else + fp="$1" + fi + esac + shift 1 +done + +rfp=`realpath $fp` + +echo ' + DumpLibFootprint("'$fp'", origin, bbox); +' | pcb-rnd --gui batch | awk -v "fp=$rfp" -v grid_unit=$grid_unit -v "outfile=$outfile" -v "dpi=$dpi" -v "annotation=$annotation" -v "photo=$photo" ' + +BEGIN { + q="\"" + dim_arrow_len = 0.7 + if (annotation ~ "pins") + enable_pinnum = 1 + if (annotation ~ "dimname") + enable_dim_name = 1 + if (annotation ~ "dimvalue") + enable_dim_value = 1 + dims = 0 +} + + +/^[ \t]*#dimension/ { + if ((enable_dim_name) || (enable_dim_value)) { + DIM[dims, "x1"] = $2*0.0254 + DIM[dims, "y1"] = $3*0.0254 + DIM[dims, "x2"] = $4*0.0254 + DIM[dims, "y2"] = $5*0.0254 + DIM[dims, "dist"] = $6*0.0254 + DIM[dims, "name"] = $7 + DIM[dims, "val"] = $8 + dims++ + } +} + +/^ error/ { exit(1) } +/^ bbox mm/ { bbx1 = $4; bby1 = $5; bbx2 = $6; bby2 = $7; } +/^ origin mm/ { ox = $4; oy = $5; } + +function line(layer, X1, Y1, X2, Y2, Thickness, Clearance, Flags) +{ + if (Clearance == "") Clearance = 0; + if (Thickness == "") Thickness = 1; + print "LineNew(noundo, pcb, " layer "," X1 "mm," Y1 "mm," X2 "mm," Y2 "mm," Thickness "," Clearance "mm," q "clearline" q ")" +} + +function text(layer, x, y, rot, scale, thickness, text_string) +{ + print "TextNew(noundo, pcb, " layer ", 0, " x "mm," y "mm," rot "," scale "," thickness "," q text_string q ", clearline)" +} + +function unit_txt(s) +{ + if ((s < 0.001) && (s > -0.001)) + return "0 " grid_unit + if (grid_unit == "mil") + return sprintf("%.2f mil", s/0.0254) + else + return sprintf("%.2f mm", s) +} + + +function annot(x, y, txt, rot, elev, hcenter ,sx,sy) +{ + sx = length(txt)*0.5 + sy = 1.2 + if (rot) + text("#0", x-sy, y-sx/2, 90, 70, 1, txt) + else + text("#0", x-sx/2, y-sy, 0, 70, 1, txt) +} + +function dimension(x1, y1, x2, y2, dist, name, value ,vx,vy,nx,ny,X1,Y1,X2,Y2,len,alen,awidth,tmp, ang,negdist,cx,cy,dx,dy,D) +{ + alen = dim_arrow_len + + vx = x2-x1 + vy = y2-y1 + len = vx*vx+vy*vy + if (len == 0) + return + len = sqrt(len) + vx = vx/len + vy = vy/len + nx = vy + ny = -vx + + if (dist ~ "^[@]") { + cx = (x1+x2)/2 + cy = (y1+y2)/2 + sub("@", "", dist) + split(dist, D, ";") + nx = D[1] - cx + ny = D[2] - cy + + X1 = x1+nx + Y1 = y1+ny + X2 = x2+nx + Y2 = y2+ny + + dist = nx*nx+ny*ny + if (dist > 0) + dist = sqrt(dist) + + nx /= dist + ny /= dist + } + else { + if (dist < 0) { + tmp = x1 + x1 = x2 + x2 = tmp + tmp = y1 + y1 = y2 + y2 = tmp + dist = -dist + + vx = -vx + vy = -vy + nx = -nx + ny = -ny + } + + X1 = x1+nx*dist + Y1 = y1+ny*dist + X2 = x2+nx*dist + Y2 = y2+ny*dist + } + + + if (alen > len/4) + alen=len/4 + + awidth=alen/6 + + ang = atan2(vx, vy) + + + line("#0", x1, y1, X1+nx*awidth, Y1+ny*awidth, "0.1mm") + line("#0", x2, y2, X2+nx*awidth, Y2+ny*awidth, "0.1mm") + line("#0", X1, Y1, X2, Y2, "0.1mm") + +#arrowheads + line("#0", X1, Y1, X1+vx*alen+nx*awidth, Y1+vy*alen+ny*awidth, "0.1mm") + line("#0", X1, Y1, X1+vx*alen-nx*awidth, Y1+vy*alen-ny*awidth, "0.1mm") + line("#0", X2, Y2, X2-vx*alen+nx*awidth, Y2-vy*alen+ny*awidth, "0.1mm") + line("#0", X2, Y2, X2-vx*alen-nx*awidth, Y2-vy*alen-ny*awidth, "0.1mm") + + if (enable_dim_value) { + if (value == "") + value = len + else if (value == "!") + value = "" + if (value != "") + value = unit_txt(value) + } + else + value = "" + + if (!enable_dim_name) + name = "" + + if ((name != "") && (value != "")) + name = name "=|" value + else if ((value != "") && (name == "")) + name = value + + if (name != "") { + if (ang < 0) + ang = -ang + if ((ang < 3.1415*3/4) && (ang > 3.1415*1/4)) + annot((X1+X2)/2, (Y1+Y2)/2, name, 0, awidth*1.1,0) + else + annot((X1+X2)/2, (Y1+Y2)/2, name, 1, awidth*1.1,0) + } +} + +END { + if (grid_unit == "mil") + grid = 2.54; + else + grid = 1; + + margin = grid*2 + + print "LoadFrom(SubcToBuffer, " q fp q ")" + print "PasteBuffer(ToLayout, " (-1*bbx1+ox)+margin ", " (-1*bby1+oy)+margin ", mm)" + + # draw the grid + x1 = (ox-bbx1-margin) - int((ox-bbx1-margin)) * grid + y1 = (oy-bby1-margin) - int((oy-bby1-margin)) * grid + for(y = y1; y < bby2-bby1+margin*1.5; y +=grid) { + to=bbx2-bbx1+margin*1.5 + line("#1", x1, y, to, y); + text("#1", to+0.75, y-0.75, 0, 70, 1, unit_txt(y+bby1-oy-margin)) + } + + for(x = x1; x < bbx2-bbx1+margin*1.5; x +=grid) { + line("#1", x, y1, x, bby2-bby1+margin*1.5); + text("#1", x-0.75, to+5, 90, 70, 1, unit_txt(x+bbx1-ox-margin)) + } + + dx = -bbx1+margin + dy = -bby1+margin + + for(n = 0; n < dims; n++) { + dimension(DIM[n, "x1"]+dx, DIM[n, "y1"]+dy, DIM[n, "x2"]+dx, DIM[n, "y2"]+dy, DIM[n, "dist"], DIM[n, "name"], DIM[n, "val"]); + } + + if (enable_pinnum) { + print "query(select, \"@.type==SUBC||@.type==PSTK\")" + print "propset(selection, p/flags/termname, 1)" + print "query(unselect, @)" + } + + if (photo) { + photo = "--photo-mode, " + } + else + photo = "" + print "autocrop()" + print "Export(png, --dpi, " dpi ", --as-shown, " photo " --outfile, " q outfile q ")" + print "Save(LayoutAs, \"A.lht\")" +} + +' | pcb-rnd --gui batch Property changes on: tags/2.3.0/util/fp2preview ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/fp2subc =================================================================== --- tags/2.3.0/util/fp2subc (nonexistent) +++ tags/2.3.0/util/fp2subc (revision 33253) @@ -0,0 +1,129 @@ +#!/bin/sh +# fp2subc - convert old pcb footprints to subcircuit +# 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. +# +# http://repo.hu/projects/pcb-rnd + + +conv_custom_fp() +{ +local in_fp out_subc +in_fp=`realpath $1` +out_subc="$2" +echo ' +LoadFrom(ElementToBuffer, "'$in_fp'") +PasteBuffer(Restore) +PasteBuffer(ToLayout, 0, 0) + +# convert to subc +Select(All) +PasteBuffer(ConvertSubc) + +# save +SaveTo(PasteBuffer, "'$out_subc'", "lihata board v4") +' | $dbg "$pcb_rnd" $conf --gui batch +} + +conv_lib_fp() +{ +echo ' +LoadFootprint("'$1'") +PasteBuffer(Restore) +PasteBuffer(ToLayout, 0, 0) + +# convert to subc +Select(All) +PasteBuffer(ConvertSubc) + +# save +SaveTo(PasteBuffer, "'$2'") +' | $dbg "$pcb_rnd" $conf --gui batch +} + +help() +{ + echo "fp2subc - convert old pcb footprints to subcircuit" + echo "fp2subc [-l] [-c key=val] [-p path] fp [subc]" + echo " -l fp is not a file path, use the normal library search for fp" + echo " --lib same as -l" + echo " -p path specify the full path of the pcb-rnd executable to use" + echo " --pcb-rnd same as -p" + echo " -d path specify the the debugger to wrap pcb-rnd in (e.g. valgrind)" + echo " --debugger same as -d" + echo " -c key=val pass on a configuration setting to pcb-rnd" + echo " fp the path or library name of the footprint" + echo " subc the path of the output subc file" + echo "" +} + +lib=0 +in_fp="" +out_subc="" +pcb_rnd=pcb-rnd +dbg="" +conf="" +while test $# -gt 0 +do + cmd="$1" + shift 1 + case "$cmd" in + -d|--debugger) dbg="$1"; shift 1;; + -p|--pcb-rnd) pcb_rnd="$1"; shift 1;; + -c) conf="$conf -c $1"; shift 1;; + -l|--lib) lib=1 ;; + -h|--help) help; exit 0;; + *) + if test -z "$in_fp" + then + in_fp="$cmd" + else + if test -z "$out_subc" + then + out_subc="$out_subc" + else + echo "fp2subc error: can't use 3 filenames" >&2 + exit 1 + fi + fi + ;; + esac +done + +if test -z "$in_fp" +then + echo "fp2subc error: need at least an input file name" + exit 1 +fi + +if test -z "$out_subc" +then + if test $lib -eq 0 + then + out_subc=`echo "$in_fp" | sed "s/.fp$//;s/$/.subc.lht/"` + else + out_subc=`echo "$in_fp" | sed "s/[^A-Za-z0-9_.-]*//g;s/.fp$//;s/$/.subc.lht/"` + fi + echo "fp2subc: saving subcircuit in $out_subc" +fi + + +if test $lib -eq 0 +then + conv_custom_fp "$in_fp" "$out_subc" +else + conv_lib_fp "$in_fp" "$out_subc" +fi Property changes on: tags/2.3.0/util/fp2subc ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/gnet-pcbrndfwd.scm =================================================================== --- tags/2.3.0/util/gnet-pcbrndfwd.scm (nonexistent) +++ tags/2.3.0/util/gnet-pcbrndfwd.scm (revision 33253) @@ -0,0 +1,125 @@ +;;; gEDA - GPL Electronic Design Automation +;;; gnetlist - gEDA Netlist +;;; Copyright (C) 1998-2008 Ales Hvezda +;;; Copyright (C) 1998-2008 gEDA Contributors (see ChangeLog for details) +;;; +;;; 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. + +;; PCB forward annotation script + +(use-modules (ice-9 regex)) +(use-modules (ice-9 format)) + +;; This is a list of attributes which are propogated to the pcb +;; elements. Note that refdes, value, and footprint need not be +;; listed here. +(define pcbrndfwd:element-attrs + '("device" + "manufacturer" + "manufacturer_part_number" + "vendor" + "vendor_part_number" + )) + +(define (pcbrndfwd:quote-string s) + (string-append "\"" + (regexp-substitute/global #f "\"" s 'pre "\\\"" 'post) + "\"") + ) + +(define (pcbrndfwd:pinfmt pin) + (format #f "~a-~a" (car pin) (car (cdr pin))) + ) + +(define (pcbrndfwd:each-pin net pins port) + (if (not (null? pins)) + (let ((pin (car pins))) + (format port "Netlist(Add,~a,~a)~%" net (pcbrndfwd:pinfmt pin)) + (pcbrndfwd:each-pin net (cdr pins) port)))) + +(define (pcbrndfwd:each-net netnames port) + (if (not (null? netnames)) + (let ((netname (car netnames))) + (pcbrndfwd:each-pin netname (gnetlist:get-all-connections netname) port) + (pcbrndfwd:each-net (cdr netnames) port)))) + +(define (pcbrndfwd:each-attr refdes attrs port) + (if (not (null? attrs)) + (let ((attr (car attrs))) + (format port "ElementSetAttr(~a,~a,~a)~%" + (pcbrndfwd:quote-string refdes) + (pcbrndfwd:quote-string attr) + (pcbrndfwd:quote-string (gnetlist:get-package-attribute refdes attr))) + (pcbrndfwd:each-attr refdes (cdr attrs) port)))) + +;; write out the pins for a particular component +(define pcbrndfwd:component_pins + (lambda (port package pins) + (if (and (not (null? package)) (not (null? pins))) + (begin + (let ( + (pin (car pins)) + (label #f) + (pinnum #f) + ) + (display "ChangePinName(" port) + (display (pcbrndfwd:quote-string package) port) + (display ", " port) + + (set! pinnum (gnetlist:get-attribute-by-pinnumber package pin "pinnumber")) + + (display pinnum port) + (display ", " port) + + (set! label (gnetlist:get-attribute-by-pinnumber package pin "pinlabel")) + (if (string=? label "unknown") + (set! label pinnum) + ) + (display (pcbrndfwd:quote-string label) port) + (display ")\n" port) + ) + (pcbrndfwd:component_pins port package (cdr pins)) + ) + ) + ) + ) + +(define (pcbrndfwd:each-element elements port) + (if (not (null? elements)) + (let* ((refdes (car elements)) + (value (gnetlist:get-package-attribute refdes "value")) + (footprint (gnetlist:get-package-attribute refdes "footprint")) + ) + + (format port "ElementList(Need,~a,~a,~a)~%" + (pcbrndfwd:quote-string refdes) + (pcbrndfwd:quote-string footprint) + (pcbrndfwd:quote-string value)) + (pcbrndfwd:each-attr refdes pcbrndfwd:element-attrs port) + (pcbrndfwd:component_pins port refdes (gnetlist:get-pins refdes)) + + (pcbrndfwd:each-element (cdr elements) port)))) + +(define (pcbrndfwd output-filename) + (let ((port (open-output-file output-filename))) + (format port "Netlist(Freeze)\n") + (format port "Netlist(Clear)\n") + (pcbrndfwd:each-net (gnetlist:get-all-unique-nets "dummy") port) + (format port "Netlist(Sort)\n") + (format port "Netlist(Thaw)\n") + (format port "ElementList(Start)\n") + (pcbrndfwd:each-element packages port) + (format port "ElementList(Done)\n") + (close-output-port port))) Index: tags/2.3.0/util/gnet-pcbrndfwd_elem.scm =================================================================== --- tags/2.3.0/util/gnet-pcbrndfwd_elem.scm (nonexistent) +++ tags/2.3.0/util/gnet-pcbrndfwd_elem.scm (revision 33253) @@ -0,0 +1,107 @@ +;;; gEDA - GPL Electronic Design Automation +;;; gnetlist - gEDA Netlist +;;; Copyright (C) 1998-2008 Ales Hvezda +;;; Copyright (C) 1998-2008 gEDA Contributors (see ChangeLog for details) +;;; +;;; 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. + +;; PCB forward annotation script; +;; modified version of pcbrndfwd: do not do the net list, only elements, +;; this way nets can be imported in the traditional netlist-way + +(use-modules (ice-9 regex)) +(use-modules (ice-9 format)) + +;; This is a list of attributes which are propogated to the pcb +;; elements. Note that refdes, value, and footprint need not be +;; listed here. +(define pcbrndfwd:element-attrs + '("device" + "manufacturer" + "manufacturer_part_number" + "vendor" + "vendor_part_number" + )) + +(define (pcbrndfwd:quote-string s) + (string-append "\"" + (regexp-substitute/global #f "\"" s 'pre "\\\"" 'post) + "\"") + ) + + +(define (pcbrndfwd:each-attr refdes attrs port) + (if (not (null? attrs)) + (let ((attr (car attrs))) + (format port "ElementSetAttr(~a,~a,~a)~%" + (pcbrndfwd:quote-string refdes) + (pcbrndfwd:quote-string attr) + (pcbrndfwd:quote-string (gnetlist:get-package-attribute refdes attr))) + (pcbrndfwd:each-attr refdes (cdr attrs) port)))) + +;; write out the pins for a particular component +(define pcbrndfwd:component_pins + (lambda (port package pins) + (if (and (not (null? package)) (not (null? pins))) + (begin + (let ( + (pin (car pins)) + (label #f) + (pinnum #f) + ) + (display "ChangePinName(" port) + (display (pcbrndfwd:quote-string package) port) + (display ", " port) + + (set! pinnum (gnetlist:get-attribute-by-pinnumber package pin "pinnumber")) + + (display pinnum port) + (display ", " port) + + (set! label (gnetlist:get-attribute-by-pinnumber package pin "pinlabel")) + (if (string=? label "unknown") + (set! label pinnum) + ) + (display (pcbrndfwd:quote-string label) port) + (display ")\n" port) + ) + (pcbrndfwd:component_pins port package (cdr pins)) + ) + ) + ) + ) + +(define (pcbrndfwd:each-element elements port) + (if (not (null? elements)) + (let* ((refdes (car elements)) + (value (gnetlist:get-package-attribute refdes "value")) + (footprint (gnetlist:get-package-attribute refdes "footprint")) + ) + + (format port "ElementList(Need,~a,~a,~a)~%" + (pcbrndfwd:quote-string refdes) + (pcbrndfwd:quote-string footprint) + (pcbrndfwd:quote-string value)) + (pcbrndfwd:each-attr refdes pcbrndfwd:element-attrs port) + (pcbrndfwd:component_pins port refdes (gnetlist:get-pins refdes)) + + (pcbrndfwd:each-element (cdr elements) port)))) + +(define (pcbrndfwd_elem output-filename) + (let ((port (open-output-file output-filename))) + (format port "ElementList(Start)\n") + (pcbrndfwd:each-element packages port) + (format port "ElementList(Done)\n") + (close-output-port port))) Index: tags/2.3.0/util/gsch2pcb-rnd/Makefile.in =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/Makefile.in (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/Makefile.in (revision 33253) @@ -0,0 +1,119 @@ +put /local/pcb/CFLAGS cc/cflags +append /local/pcb/CFLAGS {-I../.. -I../../src_3rd -I../../src -I../../src_3rd/liblihata -DSCMDIR="\\"$(LIBDIR_INSTALLED)\\""} +append /local/pcb/LDFLAGS cc/ldflags +append /local/pcb/LDFLAGS ?/target/libs/ldl +include {../src_3rd/librnd/scconfig/template/debug.tmpasm} + +print [@ +ROOT=../.. +PLUGDIR=../../src_plugins +LIBRND=../../src_3rd/librnd + +include $(LIBRND)/core/librnd.mak + +CFLAGS=@/local/pcb/c89flags@ @/local/pcb/CFLAGS@ $(CFLAGS_LIBRND_FUNGW) +LDFLAGS=-lm @/local/pcb/LDFLAGS@ $(LDFLAGS_LIBRND_FUNGW) +CC=@cc/cc@ +LIB_HIDLIB=\ + $(ROOT)/src/librnd-hid.a \ + $(ROOT)/src/librnd-3rd.a +@] + +print [@ +LISTOBJ=../../src_3rd/genlist/genadlist.o ../../src_3rd/genlist/genlistalloc.o +QPARSE=../../src_3rd/qparse/qparse.o +@] + +put /local/pcb/tmpasm/buildin {../src_plugins/Buildin.tmpasm} +put /local/pcb/tmpasm/plugin {../src_plugins/Plugin.tmpasm} +put /local/pcb/tmpasm/disable {../src_plugins/Disable.tmpasm} + +put /local/pcb/RULES {} +put /local/pcb/OBJS {} +put /local/pcb/LDFLAGS {} +put /local/pcb/CFLAGS {} +put /local/pcb/buildin_init_code {} +put /local/pcb/buildin_init_extern {} + +uniq /local/pcb/OBJS + +print [@ + + +FP_OBJS = @/local/pcb/OBJS@ ../../src/plug_footprint.o +CONF_OBJS = ../../src/vtlibrary.o $(LIBRND)/core/compat_fs.o $(LIBRND)/core/paths.o $(LIBRND)/core/conf.o ../../src/conf_core.o $(LIBRND)/core/hid_cfg.o $(LIBRND)/core/hidlib_conf.o $(LIBRND)/core/misc_util.o $(LIBRND)/core/unit.o ../../src/conf_internal.o $(LIBRND)/core/list_conf.o $(LIBRND)/core/conf_hid.o $(LIBRND)/core/rnd_printf.o $(LIBRND)/core/compat_misc.o $(LIBRND)/core/safe_fs.o +FP_LDFLAGS = @/local/pcb/LDFLAGS@ +FP_CFLAGS = @/local/pcb/CFLAGS@ +OBJS = \ + gsch2pcb.o \ + help.o \ + netlister.o \ + run.o \ + glue.o \ + method_import.o + +all: + $(MAKE) revcheck + $(MAKE) gsch2pcb-rnd$(LIBRND_EXE) + +revcheck: + cd ../../scconfig && ./revtest Rev.stamp < Rev.tab + +gsch2pcb-rnd$(LIBRND_EXE): $(OBJS) $(CONF_OBJS) $(HASHOBJ) $(LISTOBJ) $(QPARSE) $(FP_OBJS) $(LIB_HIDLIB) + $(CC) $(OBJS) $(CONF_OBJS) $(FP_OBJS) $(HASHOBJ) $(LISTOBJ) $(QPARSE) $(LIB_HIDLIB) -o gsch2pcb-rnd$(LIBRND_EXE) $(LDFLAGS) $(FP_LDFLAGS) + +gsch2pcb.o: gsch2pcb.c ../../config.h + $(CC) -c $(CFLAGS) $(FP_CFLAGS) gsch2pcb.c -o gsch2pcb.o + +# TODO: this should be the base lib only +# run the Makefile in src for the common objects: +$(HASHOBJ) $(QPARSE) \ +../../src_3rd/genvector/gds_char.o ../../src_3rd/genvector/vtp0.o \ +../../src_3rd/genvector/vts0.o ../../src_3rd/genadlist/genlist.o \ +../../src_3rd/genlist/genlistalloc.o: + cd ../../src && $(MAKE) util_deps + +$(ROOT)/src/librnd-hid.a: + cd $(ROOT)/src && make librnd-hid.a + +$(ROOT)/src/librnd-3rd.a: + cd $(ROOT)/src && make librnd-3rd.a + +##### module rules begin ##### +@/local/pcb/RULES@ +##### module rules end ##### +@] + +# generate explicit rules for .c -> .o +put /local/comp/OBJS /local/pcb/OBJS +include {../src_3rd/librnd/scconfig/template/compile.tmpasm} + +print [@ + +gsch2pcb.o: gsch2pcb_rnd_conf_fields.h + +gsch2pcb_rnd_conf_fields.h: gsch2pcb_rnd_conf.h + AWK=@/host/fstools/awk@ ../../scconfig/gen_conf.sh < gsch2pcb_rnd_conf.h > gsch2pcb_rnd_conf_fields.h + +install_all: + $(SCCBOX) mkdir -p "$(BINDIR)" "$(LIBDIR)" + $(SCCBOX) $(HOW) "gsch2pcb-rnd$(LIBRND_EXE)" "$(BINDIR)/gsch2pcb-rnd$(LIBRND_EXE)" + $(SCCBOX) $(HOW) "gnet-gsch2pcb-rnd.scm" "$(LIBDIR)/gnet-gsch2pcb-rnd.scm" + +install: + $(MAKE) install_all HOW="install" + +linstall: + $(MAKE) install_all HOW="linstall -f" + +uninstall: + $(MAKE) install_all HOW="uninstall" + +clean: + $(SCCBOX) rm -f -q gsch2pcb-rnd$(LIBRND_EXE) $(OBJS) gsch2pcb_rnd_conf_fields.h + +distclean: clean + +include $(ROOT)/Makefile.conf + +@] Index: tags/2.3.0/util/gsch2pcb-rnd/glue.c =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/glue.c (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/glue.c (revision 33253) @@ -0,0 +1,40 @@ +/* gsch2pcb-rnd + * (C) 2015..2016, Tibor 'Igor2' Palinkas + * + * This program is free software which I release under the GNU General Public + * License. You may redistribute and/or modify this program under the terms + * of that 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. Version 2 is in the + * COPYRIGHT file in the top level directory of this distribution. + * + * To get a copy of the GNU General Puplic License, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include "config.h" +#include +#include +#include +#include +#include +#include "gsch2pcb_rnd_conf.h" +#include + +/* glue for pcb-rnd core */ + +const char *rnd_menu_file_paths[4]; +const char *rnd_menu_name_fmt = "pcb-menu-%s.lht"; + +const char *rnd_hidlib_default_embedded_menu = ""; + +void rnd_hidlib_crosshair_move_to(rnd_hidlib_t *hl, rnd_coord_t abs_x, rnd_coord_t abs_y, int mouse_mot) { } + + Index: tags/2.3.0/util/gsch2pcb-rnd/gnet-gsch2pcb-rnd.scm =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/gnet-gsch2pcb-rnd.scm (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/gnet-gsch2pcb-rnd.scm (revision 33253) @@ -0,0 +1,56 @@ +;;; -*-scheme-*- +;;; + +;;; gEDA - GPL Electronic Design Automation +;;; gnetlist - gEDA Netlist +;;; Copyright (C) 1998-2010 Ales Hvezda +;;; +;;; 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 02111-1301 USA. + +;; gsch2pcb format (based on PCBboard format by JM Routoure & Stefan Petersen) +;; Bill Wilson billw@wt.net +;; 6/17/2003 + +;; Simplified (thrown out m4 support) specially for Igor2 by vzh + +;; Splits a string with space separated words and returns a list +;; of the words (still as strings). +(define (gsch2pcb-rnd:split-to-list the-string) + (filter! + (lambda (x) (not (string=? "" x))) + (string-split the-string #\space))) + +;; Write the footprint for the package `refdes' to `port'. +(define (gsch2pcb-rnd:write-value-footprint refdes port) + + (let ((value (gnetlist:get-package-attribute refdes "value")) + (footprint (gsch2pcb-rnd:split-to-list + (gnetlist:get-package-attribute refdes "footprint")))) + + (format port "PKG(~A,~A,~A)\n" (string-join footprint " ") refdes value))) + +;; Write the footprints for all the refdes' in `lst'. +(define (gsch2pcb-rnd:write-value-footprints port lst) + (for-each (lambda (x) (gsch2pcb-rnd:write-value-footprint x port)) lst)) + + +(define (gsch2pcb-rnd output-filename) + (begin +;; (set-current-output-port (gnetlist:output-port output-filename)) + (set-current-output-port (open-output-file output-filename)) + + ;; don't use m4 + (gsch2pcb-rnd:write-value-footprints (current-output-port) packages))) Index: tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb.c =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb.c (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb.c (revision 33253) @@ -0,0 +1,501 @@ +/* gsch2pcb-rnd + * + * Original version: Bill Wilson billw@wt.net + * rnd-version: (C) 2015..2016,2020 Tibor 'Igor2' Palinkas + * + * This program is free software which I release under the GNU General Public + * License. You may redistribute and/or modify this program under the terms + * of that 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. Version 2 is in the + * COPYRIGHT file in the top level directory of this distribution. + * + * To get a copy of the GNU General Puplic License, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + * Retrieved from the official git (2015.07.15) + + Behavior different from the original: + - use getenv() instead of g_getenv(): on windows this won't do recursive variable expansion + - use rnd-specific .scm + - use pcb-rnd's conf system + - use rnd_popen() instead of glib's spawn (stderr is always printed to stderr) + */ + +#include "config.h" + +#define LOCAL_PROJECT_FILE "project.lht" + +#include +#include +#include +#include "../src/plug_footprint.h" +#include +#include "../src/conf_core.h" +#include +#include "../src_3rd/qparse/qparse.h" +#include "../config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "method.h" +#include "help.h" +#include "gsch2pcb_rnd_conf.h" +#include "gsch2pcb.h" +#include "method_import.h" + +static const char *want_method_default = "import"; + +#define CONF_USER_DIR "~/" DOT_PCB_RND +const char *rnd_conf_userdir_path; +const char *rnd_pcphl_conf_user_path; +const char *rnd_conf_sysdir_path; +const char *rnd_conf_sys_path; + +gdl_list_t pcb_element_list; /* initialized to 0 */ +gadl_list_t schematics, extra_gnetlist_arg_list, extra_gnetlist_list; + +int n_deleted, n_added_ef, n_fixed, n_PKG_removed_new, + n_PKG_removed_old, n_preserved, n_changed_value, n_not_found, + n_unknown, n_none, n_empty; + +int bak_done, need_PKG_purge; + +conf_gsch2pcb_rnd_t conf_g2pr; + +method_t *methods = NULL, *current_method; + +void method_register(method_t *method) +{ + method->next = methods; + methods = method; +} + +method_t *method_find(const char *name) +{ + method_t *m; + for(m = methods; m != NULL; m = m->next) + if (strcmp(m->name, name) == 0) + return m; + return NULL; +} + +/* Return a pointer to the suffix if inp ends in that suffix */ +static const char *loc_str_has_suffix(const char *inp, const char *suffix, int suff_len) +{ + int len = strlen(inp); + if ((len >= suff_len) && (strcmp(inp + len - suff_len, suffix) == 0)) + return inp + len - suff_len; + return NULL; +} + +char *fix_spaces(char * str) +{ + char *s; + + if (!str) + return NULL; + for (s = str; *s; ++s) + if (*s == ' ' || *s == '\t') + *s = '_'; + return str; +} + +static void add_schematic(const char *sch) +{ + char **n; + n = gadl_new(&schematics); + *n = rnd_strdup(sch); + gadl_append(&schematics, n); + if (!conf_g2pr.utils.gsch2pcb_rnd.sch_basename) { + const char *suff = loc_str_has_suffix(sch, ".sch", 4); + if (suff != NULL) { + char *tmp = rnd_strndup(sch, suff - sch); + rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/sch_basename", -1, tmp, RND_POL_OVERWRITE); + free(tmp); + } + } +} + +static void add_multiple_schematics(const char * sch) +{ + /* parse the string using shell semantics */ + int count; + char **args; + char *tmp = rnd_strdup(sch); + + count = qparse(tmp, &args); + free(tmp); + if (count > 0) { + int i; + for (i = 0; i < count; ++i) + if (*args[i] != '\0') + add_schematic(args[i]); + qparse_free(count, &args); + } + else { + fprintf(stderr, "invalid `schematics' option: %s\n", sch); + } +} + +static int parse_config(char * config, char * arg) +{ + char *s; + + /* remove trailing white space otherwise strange things can happen */ + if ((arg != NULL) && (strlen(arg) >= 1)) { + s = arg + strlen(arg) - 1; + while ((*s == ' ' || *s == '\t') && (s != arg)) + s--; + s++; + *s = '\0'; + } + if (conf_g2pr.utils.gsch2pcb_rnd.verbose) + printf(" %s \"%s\"\n", config, arg ? arg : ""); + + if (!strcmp(config, "remove-unfound") || !strcmp(config, "r")) { + /* This is default behavior set in header section */ + rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/remove_unfound_elements", -1, "1", RND_POL_OVERWRITE); + return 0; + } + if (!strcmp(config, "keep-unfound") || !strcmp(config, "k")) { + rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/remove_unfound_elements", -1, "0", RND_POL_OVERWRITE); + return 0; + } + if (!strcmp(config, "quiet") || !strcmp(config, "q")) { + rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/quiet_mode", -1, "1", RND_POL_OVERWRITE); + return 0; + } + if (!strcmp(config, "preserve") || !strcmp(config, "p")) { + rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/preserve", -1, "1", RND_POL_OVERWRITE); + return 0; + } + if (!strcmp(config, "elements-shell") || !strcmp(config, "s")) + rnd_conf_set(RND_CFR_CLI, "rc/library_shell", -1, arg, RND_POL_OVERWRITE); + else if (!strcmp(config, "elements-dir") || !strcmp(config, "d")) { + static int warned = 0; + if (!warned) { + rnd_message(RND_MSG_WARNING, "WARNING: using elements-dir from %s - this overrides the normal pcb-rnd configured library search paths\n", config); + warned = 1; + } + rnd_conf_set(RND_CFR_CLI, "rc/library_search_paths", -1, arg, RND_POL_PREPEND); + } + else if (!strcmp(config, "output-name") || !strcmp(config, "o")) + rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/sch_basename", -1, arg, RND_POL_OVERWRITE); + else if (!strcmp(config, "default-pcb") || !strcmp(config, "P")) + rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/default_pcb", -1, arg, RND_POL_OVERWRITE); + else if (!strcmp(config, "schematics")) + add_multiple_schematics(arg); + else if (!strcmp(config, "gnetlist")) { + char **n; + n = gadl_new(&extra_gnetlist_list); + *n = rnd_strdup(arg); + gadl_append(&extra_gnetlist_list, n); + } + else if (!strcmp(config, "empty-footprint")) + rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/empty_footprint_name", -1, arg, RND_POL_OVERWRITE); + else + return -1; + + return 1; +} + +static void load_project(char * path) +{ + FILE *f; + char *s, buf[1024], config[32], arg[768]; + int n; + + f = rnd_fopen(NULL, path, "r"); + if (!f) + return; + + /* check if we have a lihata project file or config file by looking at the first 16 non-comments */ + for(n = 0; n < 16;) { + if (fgets(buf, sizeof(buf), f) == NULL) + break; + s = buf; + while(isspace(*s)) s++; + if ((*s == '#') || (*s == '\r') || (*s == '\n') || (*s == '\0')) + continue; + /* look for known lihata roots */ + if (strncmp(s, "ha:geda-project-v1", 18) == 0) + goto lihata_prj; + if (strncmp(s, "li:pcb-rnd-conf-v1", 18) == 0) + goto lihata_prj; + n++; + } + + rewind(f); + + if (conf_g2pr.utils.gsch2pcb_rnd.verbose) + printf("Reading project file: %s\n", path); + while (fgets(buf, sizeof(buf), f)) { + for (s = buf; *s == ' ' || *s == '\t' || *s == '\n'; ++s); + if (!*s || *s == '#' || *s == '/' || *s == ';') + continue; + arg[0] = '\0'; + sscanf(s, "%31s %767[^\n]", config, arg); + parse_config(config, arg); + } + fclose(f); + return; + +lihata_prj:; + fclose(f); + if (rnd_conf_load_as(RND_CFR_PROJECT, path, 0) != 0) { + rnd_message(RND_MSG_ERROR, "Failed to parse project file %s.\n", path); + exit(1); + } + rnd_conf_update(NULL, -1); /* because of our new project file */ +} + +static void load_extra_project_files(void) +{ + char *path; + static int done = FALSE; + + if (done) + return; + + load_project("/etc/gsch2pcb"); + load_project("/usr/local/etc/gsch2pcb"); + + path = rnd_concat(rnd_conf.rc.path.home, RND_DIR_SEPARATOR_S, ".gEDA", RND_DIR_SEPARATOR_S, "gsch2pcb", NULL); + load_project(path); + free(path); + + done = TRUE; +} + +int have_cli_project_file = 0; +int have_cli_schematics = 0; +static void get_args(int argc, char ** argv) +{ + char *opt, *arg; + int i, r; + + for (i = 1; i < argc; ++i) { + opt = argv[i]; + arg = argv[i + 1]; + if (*opt == '-') { + ++opt; + if (*opt == '-') + ++opt; + if (!strcmp(opt, "version") || !strcmp(opt, "V")) { + printf("gsch2pcb-rnd %s\n", GSCH2PCB_RND_VERSION); + exit(0); + } + else if (!strcmp(opt, "verbose") || !strcmp(opt, "v")) { + char tmp[64]; + sprintf(tmp, "%ld", conf_g2pr.utils.gsch2pcb_rnd.verbose + 1); + rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/verbose", -1, tmp, RND_POL_OVERWRITE); + continue; + } + else if (!strcmp(opt, "m") || !strcmp(opt, "method")) { + if (method_find(arg) == NULL) { + rnd_message(RND_MSG_ERROR, "Error: can't use unknown method '%s'; try --help\n", arg); + exit(1); + } + rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/method", -1, arg, RND_POL_OVERWRITE); + i++; + continue; + } + else if (!strcmp(opt, "c") || !strcmp(opt, "conf")) { + const char *stmp; + if (rnd_conf_set_from_cli(NULL, arg, NULL, &stmp) != 0) { + fprintf(stderr, "Error: failed to set config %s: %s\n", arg, stmp); + exit(1); + } + i++; + continue; + } + else if (!strcmp(opt, "fix-elements")) { + rnd_conf_set(RND_CFR_CLI, "utils/gsch2pcb_rnd/fix_elements", -1, "1", RND_POL_OVERWRITE); + continue; + } + else if (!strcmp(opt, "gnetlist-arg")) { + char **n; + n = gadl_new(&extra_gnetlist_arg_list); + *n = rnd_strdup(arg); + gadl_append(&extra_gnetlist_arg_list, n); + i++; + continue; + } + else if (!strcmp(opt, "help") || !strcmp(opt, "h")) + usage(); + else if (i < argc && ((r = parse_config(opt, (i < argc - 1) ? arg : NULL)) + >= 0) + ) { + i += r; + continue; + } + printf("gsch2pcb: bad or incomplete arg: %s\n", argv[i]); + usage(); + } + else { + if (loc_str_has_suffix(argv[i], ".sch", 4) == NULL) { + if (have_cli_project_file) { + rnd_message(RND_MSG_ERROR, "ERROR: multiple project files specified on the command line (last one: %s). Either use multiple schematics or a single project file. Try %s --help\n", argv[i], argv[0]); + exit(1); + } + load_extra_project_files(); + load_project(argv[i]); + have_cli_project_file = 1; + } + else { + add_schematic(argv[i]); + have_cli_schematics = 1; + } + } + } +} + +void free_strlist(gadl_list_t *lst) +{ + char **s; + + while((s = gadl_first(lst)) != NULL) { + char *str = *s; + gadl_free(s); + free(str); + } +} + +void require_gnetlist_backend(const char *dir, const char *backend) +{ + char *path = rnd_strdup_printf("%s/gnet-%s.scm", dir, backend); + if (!rnd_file_readable(path)) + rnd_message(RND_MSG_WARNING, "WARNING: %s is not found, gnetlist will probably fail; please check your pcb-rnd installation!\n", path); + free(path); +} + + +const char *local_project_pcb_name = NULL; + +/************************ main ***********************/ +int main(int argc, char ** argv) +{ + const char *want_method; + + method_import_register(); + + rnd_conf_userdir_path = CONF_USER_DIR; + rnd_pcphl_conf_user_path = rnd_concat(CONF_USER_DIR, "/pcb-conf.lht", NULL); + rnd_conf_sysdir_path = PCBCONFDIR; + rnd_conf_sys_path = rnd_concat(PCBCONFDIR, "/pcb-conf.lht", NULL); + rnd_menu_file_paths[0] = "./"; + rnd_menu_file_paths[1] = "~/.pcb-rnd/"; + rnd_menu_file_paths[2] = rnd_concat(PCBCONFDIR, "/", NULL); + rnd_menu_file_paths[3] = NULL; + + rnd_file_loaded_init(); + rnd_conf_init(); + conf_core_init(); + rnd_hidlib_conf_init(); + + gadl_list_init(&schematics, sizeof(char *), NULL, NULL); + gadl_list_init(&extra_gnetlist_arg_list, sizeof(char *), NULL, NULL); + gadl_list_init(&extra_gnetlist_list, sizeof(char *), NULL, NULL); + +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_g2pr, field,isarray,type_name,cpath,cname,desc,flags); +#include "gsch2pcb_rnd_conf_fields.h" + + get_args(argc, argv); + + rnd_conf_load_all(NULL, NULL); + rnd_conf_update(NULL, -1); + + load_extra_project_files(); + rnd_conf_update(NULL, -1); /* because of CLI changes */ + + if (!have_cli_project_file && !have_cli_schematics) { + if (!rnd_file_readable(LOCAL_PROJECT_FILE)) { + rnd_message(RND_MSG_ERROR, "Don't know what to do: no project or schematics given, no local project file %s found. Try %s --help\n", LOCAL_PROJECT_FILE, argv[0]); + exit(1); + } + if (rnd_conf_load_as(RND_CFR_PROJECT, LOCAL_PROJECT_FILE, 0) != 0) { + rnd_message(RND_MSG_ERROR, "Failed to load project file %s. Try %s --help\n", LOCAL_PROJECT_FILE, argv[0]); + exit(1); + } + rnd_conf_update(NULL, -1); /* because of our new project file */ + } + else if ((local_project_pcb_name != NULL) && (!have_cli_project_file)) + rnd_conf_load_project(NULL, local_project_pcb_name); + + if (!have_cli_schematics) { /* load all schematics from the project file unless we have schematics from the cli */ + rnd_conf_native_t *nat = rnd_conf_get_field("utils/gsch2pcb_rnd/schematics"); + if (nat != NULL) { + rnd_conf_listitem_t *ci; + for (ci = rnd_conflist_first(nat->val.list); ci != NULL; ci = rnd_conflist_next(ci)) { + const char *p = ci->val.string[0]; + if (ci->type != RND_CFN_STRING) + continue; + add_schematic(p); + } + } + else { + rnd_message(RND_MSG_ERROR, "No schematics specified on the cli or in project files. Try %s --help\n", argv[0]); + exit(1); + } + } + + if (gadl_length(&schematics) == 0) { + rnd_message(RND_MSG_ERROR, "No schematics specified on the cli; can't find any in the project files/configs either. Try %s --help\n", argv[0]); + exit(1); + } + + rnd_conf_update(NULL, -1); /* because of the project file */ + + want_method = conf_g2pr.utils.gsch2pcb_rnd.method; + if (want_method == NULL) { + method_t *m; + for(m = methods; m != NULL; m = m->next) { + if (m->not_by_guess) + continue; + if (m->guess_out_name()) { + current_method = m; + break; + } + } + if (current_method == NULL) { + want_method = want_method_default; + if (!conf_g2pr.utils.gsch2pcb_rnd.quiet_mode) + rnd_message(RND_MSG_WARNING, "Warning: method not specified for a project (that has no board or project file yet); defaulting to -m %s. This warning is harmless if you are running gsch2pcb-rnd for the first time on this project and you are fine with this method.", want_method); + } + } + + if (current_method == NULL) { + current_method = method_find(want_method); + if (current_method == NULL) { + rnd_message(RND_MSG_ERROR, "Error: can't find method %s\n", want_method); + exit(1); + } + } + + current_method->init(); + rnd_conf_update(NULL, -1); + + + current_method->go(); /* the traditional, "parse element and edit the pcb file" approach */ + + current_method->uninit(); + + rnd_conf_uninit(); + + free_strlist(&schematics); + free_strlist(&extra_gnetlist_arg_list); + free_strlist(&extra_gnetlist_list); + + return 0; +} Index: tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb.h =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb.h (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb.h (revision 33253) @@ -0,0 +1,47 @@ +#include "../src_3rd/genlist/gendlist.h" +#include "../src_3rd/genlist/genadlist.h" + +#define TRUE 1 +#define FALSE 0 + +#define GSCH2PCB_RND_VERSION "2.0.0" + +#define DEFAULT_PCB_INC "pcb.inc" + +#define SEP_STRING "--------\n" + +typedef struct { + char *refdes, *value, *description, *changed_description, *changed_value; + char *flags, *tail; + char *x, *y; + char *pkg_name_fix; + char res_char; + + gdl_elem_t all_elems; + + unsigned still_exists:1; + unsigned new_format:1; + unsigned hi_res_format:1; + unsigned quoted_flags:1; + unsigned omit_PKG:1; + unsigned nonetlist:1; +} PcbElement; + +typedef struct { + char *part_number, *element_name; +} ElementMap; + +extern gdl_list_t pcb_element_list; +extern gadl_list_t schematics, extra_gnetlist_arg_list, extra_gnetlist_list; + +extern int n_deleted, n_added_ef, n_fixed, n_PKG_removed_new, + n_PKG_removed_old, n_preserved, n_changed_value, n_not_found, + n_unknown, n_none, n_empty; + +extern int bak_done, need_PKG_purge; + +extern const char *local_project_pcb_name; /* file name of the design from which the local project file name shall be derived */ + +char *fix_spaces(char * str); +void require_gnetlist_backend(const char *dir, const char *backend); + Index: tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_rnd_conf.h =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_rnd_conf.h (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_rnd_conf.h (revision 33253) @@ -0,0 +1,24 @@ +#ifndef PCB_MINCUT_CONF_H +#define PCB_MINCUT_CONF_H + +#include + +typedef struct { + const struct utils { + const struct gsch2pcb_rnd { + RND_CFT_BOOLEAN remove_unfound_elements; /* = TRUE */ + RND_CFT_BOOLEAN quiet_mode; /* = FALSE */ + RND_CFT_INTEGER verbose; + RND_CFT_BOOLEAN preserve; + RND_CFT_BOOLEAN fix_elements; + RND_CFT_STRING sch_basename; + RND_CFT_STRING default_pcb; /* override default pcb with a given file */ + RND_CFT_STRING empty_footprint_name; + RND_CFT_STRING method; + RND_CFT_LIST schematics; /* use these schematics as input */ + } gsch2pcb_rnd; + } utils; +} conf_gsch2pcb_rnd_t; + +extern conf_gsch2pcb_rnd_t conf_g2pr; +#endif Index: tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/Makefile =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/Makefile (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/Makefile (revision 33253) @@ -0,0 +1,17 @@ +names = c1 c2 c3 +schematics = $(names:%=%.sch) +netlists = $(names:%=%.net) +goldens = $(names:%=golden/%.net) +diffs = $(names:%=%.diff) + +.PHONY: all clean $(netlists) +all: $(diffs) + +$(diffs): %.diff: %.net golden/%.net + diff $^ > $@ + +$(netlists): %.net: %.sch + gnetlist -g gsch2pcb-rnd -o $@ -m ../gnet-gsch2pcb-rnd.scm $< + +clean: + -rm -rf $(diffs) $(netlists) Index: tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/c1.sch =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/c1.sch (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/c1.sch (revision 33253) @@ -0,0 +1,13 @@ +v 20130925 2 +C 18400 56000 1 0 0 connector3-2.sym +{ +T 19100 57700 5 10 1 1 0 6 1 +refdes=CONN1 +T 18700 57650 5 10 0 0 0 0 1 +device=CONNECTOR_3 +T 18700 57850 5 10 0 0 0 0 1 +footprint=CONNECTOR 3 1 +} +N 18400 57200 17800 57200 4 +N 17800 56400 17800 57200 4 +N 17800 56400 18400 56400 4 Index: tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/c2.sch =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/c2.sch (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/c2.sch (revision 33253) @@ -0,0 +1,15 @@ +v 20130925 2 +C 18400 56000 1 0 0 connector3-2.sym +{ +T 19100 57700 5 10 1 1 0 6 1 +refdes=CONN1 +T 18700 57650 5 10 0 0 0 0 1 +device=CONNECTOR_3 +T 18700 57850 5 10 0 0 0 0 1 +footprint=CONNECTOR 3 1 +T 19300 56200 5 10 1 0 90 0 1 +value=val123 +} +N 18400 57200 17800 57200 4 +N 17800 56400 17800 57200 4 +N 17800 56400 18400 56400 4 Index: tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/c3.sch =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/c3.sch (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/c3.sch (revision 33253) @@ -0,0 +1,15 @@ +v 20130925 2 +C 18400 56000 1 0 0 connector3-2.sym +{ +T 19100 57700 5 10 1 1 0 6 1 +refdes=CONN1 +T 18700 57650 5 10 0 0 0 0 1 +device=CONNECTOR_3 +T 18700 57850 5 10 0 0 0 0 1 +footprint=CONNECTOR(3, 1, silkmark=external) +T 19300 56200 5 10 1 0 90 0 1 +value=val123 +} +N 18400 57200 17800 57200 4 +N 17800 56400 17800 57200 4 +N 17800 56400 18400 56400 4 Index: tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/golden/c1.net =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/golden/c1.net (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/golden/c1.net (revision 33253) @@ -0,0 +1 @@ +PKG(CONNECTOR 3 1,CONN1,unknown) Index: tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/golden/c2.net =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/golden/c2.net (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/golden/c2.net (revision 33253) @@ -0,0 +1 @@ +PKG(CONNECTOR 3 1,CONN1,val123) Index: tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/golden/c3.net =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/golden/c3.net (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/gsch2pcb_scm/golden/c3.net (revision 33253) @@ -0,0 +1 @@ +PKG(CONNECTOR(3, 1, silkmark=external),CONN1,val123) Index: tags/2.3.0/util/gsch2pcb-rnd/help.c =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/help.c (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/help.c (revision 33253) @@ -0,0 +1,156 @@ +/* gsch2pcb-rnd + * + * Original version: Bill Wilson billw@wt.net + * rnd-version: (C) 2015..2016, Tibor 'Igor2' Palinkas + * + * This program is free software which I release under the GNU General Public + * License. You may redistribute and/or modify this program under the terms + * of that 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. Version 2 is in the + * COPYRIGHT file in the top level directory of this distribution. + * + * To get a copy of the GNU General Puplic License, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + * Retrieved from the official git (2015.07.15) + + Behavior different from the original: + - use getenv() instead of g_getenv(): on windows this won't do recursive variable expansion + - use rnd-specific .scm + - use rnd_popen() instead of glib's spawn (stderr is always printed to stderr) + */ +#include "config.h" +#include "method.h" +#include +#include + + +extern char *pcb_file_name, *pcb_new_file_name, *bak_file_name, *pins_file_name, *net_file_name; + +static char *usage_string0a = + "usage: gsch2pcb-rnd [options] {project | foo.sch [foo1.sch ...]}\n" + "\n" + "Generate a PCB annotation file from a set of gschem schematics.\n" + " gnetlist -g PCB is run to generate foo.net from the schematics.\n" "\n"; +/* TODO */ +/* " gnetlist -g gsch2pcb is run to get PCB elements which\n" + " match schematic footprints. For schematic footprints which don't match\n" + " any PCB layout elements, search a set of file element directories in\n" + " an attempt to find matching PCB file elements.\n"*/ +static char *usage_string0b = + " Output to foo.cmd if it doesn't exist.\n" + " The annotation command file (to be run by the user from pcb-rnd) contains:.\n" + " If any elements with a non-empty element name on the board\n" + " have no matching schematic component, then remove those elements from\n" + " the board unless it's marked nonetlist. Load and palce the footprints\n" + " for new elements; replace elements in-place if their footprint changed;" + " update attributes, value and other metadata in-place." + "\n"; +static char *usage_string0c = + " gnetlist -g pcbpins is run to get a PCB actions file which will rename all\n" + " of the pins in a .pcb file to match pin names from the schematic.\n" + "\n" + " \"project\" is a file (not ending in .sch) containing a list of\n" + " schematics to process and some options. A schematics line is like:\n" + " schematics foo1.sch foo2.sch ...\n" + " Options in a project file are like command line args without the \"-\":\n" + " output-name myproject\n" + "\n" + "options (may be included in a project file):\n"; +static char *usage_string0d = + " -d, --elements-dir D Search D for PCB file elements. These defaults\n" + " are searched if they exist. See the default\n" + " search paths at the end of this text." + " -c, --elements-dir-clr Clear the elements dir. Useful before a series\n" + " if -d's to flush defaults.\n" + " -m, --method M Use method M for the import. See available\n" + " methods below.\n"; +static char *usage_string0e = + " -s, --elements-shell S Use S as a prefix for running parametric footrint\n" + " generators. It is useful on systems where popen()\n" + " doesn't do the right thing or the process should\n" + " be wrapped. Example -s \"/bin/sh -c\"\n" + " -P, --default-pcb Change the default PCB file's name; this file is\n" + " inserted on top of the *.new.pcb generated, for\n" + " PCB default settings\n"; +static char *usage_string0f = + " -o, --output-name N Use output file names N.net, N.pcb, and N.new.pcb\n" + " instead of foo.net, ... where foo is the basename\n" + " of the first command line .sch file.\n" + " -r, --remove-unfound Don't include references to unfound elements in\n" + " the generated .pcb files. Use if you want PCB to\n" + " be able to load the (incomplete) .pcb file.\n" + " This is the default behavior.\n"; +static char *usage_string0g = + " -k, --keep-unfound Keep include references to unfound elements in\n" + " the generated .pcb files. Use if you want to hand\n" + " edit or otherwise preprocess the generated .pcb file\n" + " before running pcb.\n"; +static char *usage_string0h = + " -p, --preserve Preserve elements in PCB files which are not found\n" + " in the schematics. Note that elements with an empty\n" + " element name (schematic refdes) are never deleted,\n" + " so you really shouldn't need this option.\n"; +static char *usage_string0i = + " -q, --quiet Don't tell the user what to do next after running\n" + " gsch2pcb-rnd.\n" "\n"; + +static char *usage_string1a = + " --gnetlist backend A convenience run of extra gnetlist -g commands.\n" + " Example: gnetlist partslist3\n" + " Creates: myproject.partslist3\n" + " --empty-footprint name See the project.sample file.\n" + "\n"; +static char *usage_string1b = + "options (not recognized in a project file):\n" + " --gnetlist-arg arg Allows additional arguments to be passed to gnetlist.\n" + " --fix-elements If a schematic component footprint is not equal\n" + " to its PCB element Description, update the\n" + " Description instead of replacing the element.\n" + " Do this the first time gsch2pcb-rnd is used with\n" + " PCB files originally created with gschem2pcb.\n"; +static char *usage_string1c = + " -v, --verbose Use -v -v for additional file element debugging.\n" + " -V, --version\n\n" + "environment variables:\n" + " GNETLIST If set, this specifies the name of the gnetlist program\n" + " to execute.\n" + "\n"; + +static char *usage_string_foot = + "Additional Resources:\n" + "\n" + " pcb-rnd homepage: http://repo.hu/projects/pcb-rnd\n" + " gnetlist user guide: http://wiki.geda-project.org/geda:gnetlist_ug\n" + " gEDA homepage: http://www.geda-project.org\n" + "\n"; + + +void usage(void) +{ + method_t *m; + printf("%s", usage_string0a); + printf("%s", usage_string0b); + printf("%s", usage_string0c); + printf("%s", usage_string0d); + printf("%s", usage_string0e); + printf("%s", usage_string0f); + printf("%s", usage_string0g); + printf("%s", usage_string0h); + printf("%s", usage_string0i); + printf("%s", usage_string1a); + printf("%s", usage_string1b); + printf("%s", usage_string1c); + + printf("\nMethods available:\n"); + for(m = methods; m != NULL; m = m->next) + printf(" %-12s %s\n", m->name, m->desc); + printf("\n"); + printf("%s", usage_string_foot); + exit(0); +} Index: tags/2.3.0/util/gsch2pcb-rnd/help.h =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/help.h (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/help.h (revision 33253) @@ -0,0 +1 @@ +void usage(void); Index: tags/2.3.0/util/gsch2pcb-rnd/method.h =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/method.h (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/method.h (revision 33253) @@ -0,0 +1,16 @@ +typedef struct method_s method_t; + +struct method_s { + const char *name; + const char *desc; + void (*init)(void); + void (*go)(void); + void (*uninit)(void); + int (*guess_out_name)(void); /* returns 1 if the output file of the format exists for the current project */ + int not_by_guess; /* if non-zero, never try to use this method automatically, guessing from file names or anything else */ + method_t *next; +}; + +extern method_t *methods; + +void method_register(method_t *fmt); Index: tags/2.3.0/util/gsch2pcb-rnd/method_import.c =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/method_import.c (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/method_import.c (revision 33253) @@ -0,0 +1,150 @@ +/* gsch2pcb-rnd + * + * Original version: Bill Wilson billw@wt.net + * rnd-version: (C) 2015..2016,2020 Tibor 'Igor2' Palinkas + * + * This program is free software which I release under the GNU General Public + * License. You may redistribute and/or modify this program under the terms + * of that 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. Version 2 is in the + * COPYRIGHT file in the top level directory of this distribution. + * + * To get a copy of the GNU General Puplic License, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include "config.h" +#include "gsch2pcb.h" +#include "gsch2pcb_rnd_conf.h" +#include "method_import.h" +#include "run.h" +#include "netlister.h" +#include "method.h" +#include +#include "../src/conf_core.h" +#include +#include +#include +#include + +char *cmd_file_name; +char *pcb_file_name; +char *net_file_name; + +static void method_import_init(void) +{ + pcb_file_name = rnd_concat(conf_g2pr.utils.gsch2pcb_rnd.sch_basename, ".pcb", NULL); + cmd_file_name = rnd_concat(conf_g2pr.utils.gsch2pcb_rnd.sch_basename, ".cmd", NULL); + net_file_name = rnd_concat(conf_g2pr.utils.gsch2pcb_rnd.sch_basename, ".net", NULL); + local_project_pcb_name = pcb_file_name; +} + +static void import_go(int sep_net) +{ + char *verbose_str = NULL; + const char *gnetlist, *backend; + + gnetlist = gnetlist_name(); + if (!conf_g2pr.utils.gsch2pcb_rnd.verbose) + verbose_str = "-q"; + + backend = sep_net ? "pcbrndfwd_elem" : "pcbrndfwd"; + require_gnetlist_backend(SCMDIR, backend); + if (!build_and_run_command("%s %s -L %s -g %s -o %s %L %L", gnetlist, verbose_str, PCBLIBDIR, backend, cmd_file_name, &extra_gnetlist_arg_list, &schematics)) { + fprintf(stderr, "Failed to run gnetlist with backend %s to generate the elements\n", backend); + exit(1); + } + + if (sep_net) { + if (!build_and_run_command("%s %s -L %s -g PCB -o %s %L %L", gnetlist, verbose_str, PCBLIBDIR, net_file_name, &extra_gnetlist_arg_list, &schematics)) { + fprintf(stderr, "Failed to run gnetlist net file\n"); + exit(1); + } + } + + if (conf_g2pr.utils.gsch2pcb_rnd.quiet_mode) + return; + + /* Tell user what to do next */ + printf("\nNext step:\n"); + printf("1. Run pcb-rnd on your board file (or on an empty board if it's the first time).\n"); + printf("2. From within pcb-rnd, enter\n\n"); + printf(" :ExecuteFile(%s)\n\n", cmd_file_name); + + if (sep_net) { + printf(" (this will update the elements)\n\n"); + printf("3. From within pcb-rnd, select \"File -> Load netlist file\" and select \n"); + printf(" %s to load the updated netlist.\n\n", net_file_name); + } + else + printf(" (this will update the elements and the netlist)\n\n"); +} + +static void method_import_go() +{ + import_go(0); +} + +static void method_import_sep_go() +{ + import_go(1); +} + + +static int method_import_guess_out_name(void) +{ + int res; + char *name; + + name = rnd_concat(conf_g2pr.utils.gsch2pcb_rnd.sch_basename, ".lht", NULL); + res = rnd_file_readable(name); + free(name); + if (!res) { + name = rnd_concat(conf_g2pr.utils.gsch2pcb_rnd.sch_basename, ".pcb.lht", NULL); + res = rnd_file_readable(name); + free(name); + } + return res; +} + +static void method_import_uninit(void) +{ + if (pcb_file_name != NULL) + free(pcb_file_name); + if (cmd_file_name != NULL) + free(cmd_file_name); + if (net_file_name != NULL) + free(net_file_name); +} + +static method_t method_import; +static method_t method_import_sep; + +void method_import_register(void) +{ + method_import.name = "import"; + method_import.desc = "import schematics (pure action script)"; + method_import.init = method_import_init; + method_import.go = method_import_go; + method_import.uninit = method_import_uninit; + method_import.guess_out_name = method_import_guess_out_name; + method_import.not_by_guess = 0; + method_register(&method_import); + + method_import_sep.name = "importsep"; + method_import_sep.desc = "import schematics (separate action script and netlist)"; + method_import_sep.init = method_import_init; + method_import_sep.go = method_import_sep_go; + method_import_sep.uninit = method_import_uninit; + method_import_sep.guess_out_name = method_import_guess_out_name; + method_import_sep.not_by_guess = 1; + method_register(&method_import_sep); +} Index: tags/2.3.0/util/gsch2pcb-rnd/method_import.h =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/method_import.h (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/method_import.h (revision 33253) @@ -0,0 +1 @@ +void method_import_register(void); Index: tags/2.3.0/util/gsch2pcb-rnd/netlister.c =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/netlister.c (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/netlister.c (revision 33253) @@ -0,0 +1,111 @@ +/* gsch2pcb-rnd + * + * Original version: Bill Wilson billw@wt.net + * rnd-version: (C) 2015..2016, Tibor 'Igor2' Palinkas + * + * This program is free software which I release under the GNU General Public + * License. You may redistribute and/or modify this program under the terms + * of that 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. Version 2 is in the + * COPYRIGHT file in the top level directory of this distribution. + * + * To get a copy of the GNU General Puplic License, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +/*#include */ +#include +#include +#include +#include "../src/plug_footprint.h" +#include +#include +#include "../src/conf_core.h" +#include "../config.h" +#include +#include "gsch2pcb_rnd_conf.h" +#include "gsch2pcb.h" +#include +#include "run.h" + +const char *gnetlist_name(void) +{ + const char *gnetlist; + /* Allow the user to specify a full path or a different name for + * the gnetlist command. Especially useful if multiple copies + * are installed at once. + */ + gnetlist = getenv("GNETLIST"); + if (gnetlist == NULL) + gnetlist = "gnetlist"; + return gnetlist; +} + +int run_gnetlist(const char *pins_file, const char *net_file, const char *pcb_file, const char * basename, const gadl_list_t *largs) +{ + struct stat st; + time_t mtime; + const char *gnetlist; + gadl_iterator_t it; + char **sp; + char *verbose_str = NULL; + + gnetlist = gnetlist_name(); + + if (!conf_g2pr.utils.gsch2pcb_rnd.verbose) + verbose_str = "-q"; + + + if (!build_and_run_command("%s %s -g pcbpins -o %s %L %L", gnetlist, verbose_str, pins_file, &extra_gnetlist_arg_list, largs)) + return FALSE; + + if (!build_and_run_command("%s %s -g PCB -o %s %L %L", gnetlist, verbose_str, net_file, &extra_gnetlist_arg_list, largs)) + return FALSE; + + mtime = (stat(pcb_file, &st) == 0) ? st.st_mtime : 0; + + require_gnetlist_backend(SCMDIR, "gsch2pcb-rnd"); + + if (!build_and_run_command("%s %s -L " SCMDIR " -g gsch2pcb-rnd -o %s %L %L", + gnetlist, verbose_str, pcb_file, &extra_gnetlist_arg_list, largs)) { + if (stat(pcb_file, &st) != 0 || mtime == st.st_mtime) { + fprintf(stderr, "gsch2pcb: gnetlist command failed, `%s' not updated\n", pcb_file); + return FALSE; + } + return FALSE; + } + + gadl_foreach(&extra_gnetlist_list, &it, sp) { + const char *s = *sp; + const char *s2 = strstr(s, " -o "); + char *out_file; + char *backend; + if (!s2) { + out_file = rnd_concat(basename, ".", s, NULL); + backend = rnd_strdup(s); + } + else { + out_file = rnd_strdup(s2 + 4); + backend = rnd_strndup(s, s2 - s); + } + + if (!build_and_run_command("%s %s -g %s -o %s %L %L", + gnetlist, verbose_str, backend, out_file, &extra_gnetlist_arg_list, largs)) + return FALSE; + free(out_file); + free(backend); + } + + return TRUE; +} Index: tags/2.3.0/util/gsch2pcb-rnd/netlister.h =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/netlister.h (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/netlister.h (revision 33253) @@ -0,0 +1,11 @@ +/* Run gnetlist to generate a netlist and a PCB board file. gnetlist + * has exit status of 0 even if it's given an invalid arg, so do some + * stat() hoops to decide if gnetlist successfully generated the PCB + * board file (only gnetlist >= 20030901 recognizes -m). + */ +int run_gnetlist(const char *pins_file, const char *net_file, const char *pcb_file, const char * basename, const gadl_list_t *largs); + + +/* Return the name of gnetlist that should be executed */ +const char *gnetlist_name(void); + Index: tags/2.3.0/util/gsch2pcb-rnd/run.c =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/run.c (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/run.c (revision 33253) @@ -0,0 +1,134 @@ +/* gsch2pcb-rnd + * + * Original version: Bill Wilson billw@wt.net + * rnd-version: (C) 2015..2016, Tibor 'Igor2' Palinkas + * + * This program is free software which I release under the GNU General Public + * License. You may redistribute and/or modify this program under the terms + * of that 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. Version 2 is in the + * COPYRIGHT file in the top level directory of this distribution. + * + * To get a copy of the GNU General Puplic License, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include +#include +#include "gsch2pcb.h" +#include "../src_3rd/genvector/vts0.h" +#include +#include +#include "gsch2pcb_rnd_conf.h" + + +int build_and_run_command(const char * format_, ...) +{ + va_list vargs; + int result = FALSE; + vts0_t args; + char *format, *s, *start; + + /* Translate the format string; args elements point to const char *'s + within a copy of the format string. The format string is copied so + that these parts can be terminated by overwriting whitepsace with \0 */ + va_start(vargs, format_); + format = rnd_strdup(format_); + vts0_init(&args); + for(s = start = format; *s != '\0'; s++) { + /* if word separator is reached, save the previous word */ + if (isspace(s[0])) { + if (start == s) { /* empty word - skip */ + start++; + continue; + } + *s = '\0'; + vts0_append(&args, start); + start = s+1; + continue; + } + + /* check if current word is a format */ + if ((s == start) && (s[0] == '%') && (s[1] != '\0') && ((s[2] == '\0') || isspace(s[2]))) { + switch(s[1]) { + case 'L': /* append contents of char * gadl_list_t */ + { + gadl_list_t *list = va_arg(vargs, gadl_list_t *); + gadl_iterator_t it; + char **s; + gadl_foreach(list, &it, s) { + vts0_append(&args, *s); + } + } + start = s+2; + s++; + continue; + case 's': + { + char *arg = va_arg(vargs, char *); + if (arg != NULL) + vts0_append(&args, arg); + start = s+2; + s++; + } + continue; + } + } + } + va_end(vargs); + + if (args.used > 0) { + int i, l; + char *cmd, *end, line[1024]; + FILE *f; + + l = 0; + for (i = 0; i < args.used; i++) + l += strlen(args.array[i]) + 3; + + end = cmd = malloc(l+1); + for (i = 0; i < args.used; i++) { + l = strlen(args.array[i]); + *end = '"'; end++; + memcpy(end, args.array[i], l); + end += l; + *end = '"'; end++; + *end = ' '; end++; + } + end--; + *end = '\0'; + + /* we have something in the list, build & call command */ + if (conf_g2pr.utils.gsch2pcb_rnd.verbose) { + printf("Running command:\n\t%s\n", cmd); + printf("%s", SEP_STRING); + } + + f = rnd_popen(NULL, cmd, "r"); + while(fgets(line, sizeof(line), f) != NULL) { + if (conf_g2pr.utils.gsch2pcb_rnd.verbose) + fputs(line, stdout); + } + + if (rnd_pclose(f) == 0) + result = TRUE; + else + fprintf(stderr, "Failed to execute external program\n"); + free(cmd); + + if (conf_g2pr.utils.gsch2pcb_rnd.verbose) + printf("\n%s", SEP_STRING); + } + + free(format); + vts0_uninit(&args); + return result; +} Index: tags/2.3.0/util/gsch2pcb-rnd/run.h =================================================================== --- tags/2.3.0/util/gsch2pcb-rnd/run.h (nonexistent) +++ tags/2.3.0/util/gsch2pcb-rnd/run.h (revision 33253) @@ -0,0 +1,13 @@ +/** + * Build and run a command. No redirection or error handling is + * done. Format string is split on whitespace. Specifiers %l and %s + * are replaced with contents of positional args. To be recognized, + * specifiers must be separated from other arguments in the format by + * whitespace. + * - %L expects a gadl_list_t vith char * payload, contents used as separate arguments + * - %s expects a char*, contents used as a single argument (omitted if NULL) + * @param[in] format used to specify command to be executed + * @param[in] ... positional parameters + */ +int build_and_run_command(const char * format_, ...); + Index: tags/2.3.0/util/keylist.sh =================================================================== --- tags/2.3.0/util/keylist.sh (nonexistent) +++ tags/2.3.0/util/keylist.sh (revision 33253) @@ -0,0 +1,375 @@ +#!/bin/sh +# keylist - list hotkey->actions found in .lht files in a html table +# Copyright (C) 2015..2016, 2018 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. +# +# http://repo.hu/projects/pcb-rnd + +AWK=awk + +export LANG=C + +need_lht() +{ + echo "lhtflat not found. Please install lihata to run this script. The" >&2 + echo "svn extern in src_3rd/ is not enough, this script requires a full" >&2 + echo "installation from svn://repo.hu/lihata/trunk" >&2 + exit 1 +} + +# make sure lhtflat is installed +echo "" | lhtflat || need_lht + + +if test -z "$*" +then + echo "" + echo "$0: Generate a html table from pcb menu lht files." + echo "Usage: $0 file1 [file2 [file3 ... [fileN]]]" + echo "" + exit +else + cmd="html" + while test $# -gt 0 + do + case "$1" in + --html) cmd="html";; + --boxed) cmd="boxed";; + --lst) cmd="lst";; + --dot) cmd="dot"; nodenames=$2; shift 1;; + *) res_files="$res_files $1" ;; + esac + shift 1 + done +fi + +extract_from_lht() +{ + lhtflat | $AWK -F '[\t]' -v "fn=$1" ' + +#data text //main_menu/1::Edit/submenu/11::Edit name of/submenu/1::pin on layout/a Shift Ctrln +#data text //main_menu/1::Edit/submenu/11::Edit name of/submenu/1::pin on layout/action ChangeName(Object, Number) + + { + tmp = $3 + if ($3 ~ "/a/[0-9]*::$") { + # li:a = {} + sub("/[0-9]*::$", "", tmp) + } + parent=tmp + sub("/[^/]*$","", parent) + node=tmp + sub("^.*/","", node) + } + + + (($1 == "data") && ($2 == "text")) { + # simple text node: accel key + if (node == "a") { + seq=$0 + sub("[^\t]*[\t]*[^\t]*[\t]*[^\t]*[\t]*", "", seq) + gsub(" ", "", seq) + v = split(tolower(seq), S, "[;]") + ktmp = "" + for(n = 1; n <= v; n++) { + if (S[n] ~ "") + split(S[n], K, "") + else + split(S[n], K, "") + if (K[1] != "") { + mods = "" + if (K[1] ~ "alt") mods = mods "-alt" + if (K[1] ~ "ctrl") mods = mods "-ctrl" + if (K[1] ~ "shift") mods = mods "-shift" + } + else + mods = "" + if (ktmp == "") + ktmp = K[2] mods + else + ktmp = ktmp ";" K[2] mods + } + if (KEY[parent] == "") + KEY[parent] = ktmp + else + KEY[parent] = KEY[parent] SUBSEP ktmp + } + + # simple text node: action + if (node == "action") + ACTION[parent] = $4 + + # list item: action + if ($3 ~ "/action/[0-9]+::$") { + parent = $3 + sub("/action/[^/]*$", "", parent) + if (ACTION[parent] != "") + ACTION[parent] = ACTION[parent] ";" $4 + else + ACTION[parent] = $4 + } + } + + END { + for(n in KEY) { + menuname = n + sub(".*::", "", menuname) + v = split(KEY[n], K, "[" SUBSEP "]") + for(i = 1; i <= v; i++) + print K[i] "\t" fn "\t" ACTION[n] "\t" menuname + } + } + ' +} + +# convert a "key src action" to a html table with rowspans for base keys +gen_html() +{ + $AWK -F '[\t]' ' + BEGIN { + CLR[0] = "#FFFFFF" + CLR[1] = "#DDFFFF" + key_combos = 0 + } + function to_base_key(combo) + { + sub("-.*", "", combo) + return combo + } + + function to_mods(combo) + { + if (!(combo ~ ".-")) + return "" + sub("^[^-]*[-]", "", combo) + return combo + } + + { + k = $1 + if (last != k) { + LIST[key_combos++] = k +# ROWSPAN[to_base_key(k)]++ + } + ACTION[$2, k] = $3 + MENUNAME[$2, k] = $4 + HIDS[$2]++ + last = k + + v = split(k, K, ";") + p = "" + for(n = 1; n <= v; n++) { + p = p K[n] ";" + if (($2, p) in PREFIX) { + err = err "
" $2 ": " k " vs. " p + ERR[$2, p]++ + ERR[$2, k]++ + } + } + p = k ";" + PREFIX[$2, p]++ + } + + function cleanup(s) + { + gsub("\260", "\\°", s) + gsub("\\\\37777777660", "\\°", s) + gsub("\\\\057", "/", s) + return s + } + + END { + q="\"" + print "" + print "" + print "" + print "" + print "\t" + print "\t Key to action bindings " + print "" + print "" + print "" + print "" + print "" + print "

Key to action bindings

" + print "" + printf("" + + kv = split(key, K, ";") + keystr = "" + ind="" + for(kn = 1; kn <= kv; kn++) { + if (kn > 1) + keystr = keystr "
" + keystr = keystr ind K[kn] + ind = ind " " + } + + + print "
key") + colspan = 2 + for(h in HIDS) { + printf(" %s", h) + colspan++ + } + print "" + for(n = 0; n < key_combos; n++) { + clr_cnt++ + key = LIST[n] + print "
" cleanup(keystr) + for(h in HIDS) { + mn = cleanup(MENUNAME[h, key]) + act = cleanup(ACTION[h, key]) + if ((act == "") && (mn == "")) + act = " " + else { + gsub(");", "); ", act) + if (mn != "") + act = "" mn "" "
" act + } + print "
", act + if ((h, key) in ERR) + print "
Error: key prefix collision" + } + last_base = base + } + print "
" + print err + print "" + } + ' +} + +gen_list() +{ + local n + for n in $res_files + do + extract_from_lht "`basename $n`" < $n + done | sort +} + +# load node names and generate a dot drawing of the multikey bindings +gen_dot() +{ + $AWK -v "names=$nodenames" ' + BEGIN { + q="\"" + print "digraph keytree {" + print "rankdir=LR" + print "ranksep=0.2" + while((getline < names) == 1) { + path=$1 + $1="" + desc = $0 + node(path, desc, "shape=box") + } + close(names) + FS="[\t]" + } + + function arrow_(curr) + { + if (!(curr in ARROW_SEEN)) { + print curr + ARROW_SEEN[curr]=1 + } + } + + function arrow(path ,n,v,P,last,curr) + { + sub("^[/;_]", "", path) + sub("[/;_]$", "", path) + v = split(path, P, "[/;_]") + +# curr = "root -> " q P[1] q +# arrow_(curr) + last = P[1] + for(n = 2; n <= v; n++) { + curr = q last q "->" q last "_" P[n] q + arrow_(curr) + last = last "_" P[n] + } + } + + function cleanup(s) + { + gsub("\260", "\\°", s) + gsub("\\\\37777777660", "\\°", s) + gsub("\\\\057", "/", s) + return s + } + + function node(path, desc, shape, orig) + { + orig=path + desc=cleanup(desc) + sub("^[/_;]", "", orig) + sub("[/_;]$", "", orig) + gsub("[/_;]", " ", orig) + sub("^[/;]", "", path) + sub("[/;]$", "", path) + gsub("[/;]", "_", path) + gsub("[\"]", "", desc) + print q path q " [label=" q "{" orig "} \\n" desc q " " shape "]" + arrow(path) + } + + (($1 ~ "^[a-z]$") || ($1 ~ "^[a-z];[a-z];") || ($1 ~ "^[a-z];[a-z]$")) { + node($1, $4, "") + } + + END { + print "}" + } + ' +} + +gen_boxed_html() +{ + $AWK -F '[\t]' ' + /^[a-z][;]/ { + key=substr($0, 1, 1) + TBL[key] = TBL[key] "\n
" $1 "" $4 + } + END { + print "" + print "

pcb-rnd 2.x.x keys - cheat sheet

" + for(n = 0; n < 26; n++) { + key = sprintf("%c", 97+n) + print "
" + print TBL[key] + print "
" + print "" + } + } + ' +} + +case "$cmd" in + html) gen_list | gen_html ;; + boxed) gen_list | gen_boxed_html ;; + dot) gen_list | gen_dot ;; + lst) gen_list ;; +esac + Property changes on: tags/2.3.0/util/keylist.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/menu2svg.sh =================================================================== --- tags/2.3.0/util/menu2svg.sh (nonexistent) +++ tags/2.3.0/util/menu2svg.sh (revision 33253) @@ -0,0 +1,147 @@ +#!/bin/sh +# menu2svg - visualize a menu file using graphviz +# 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. +# +# http://repo.hu/projects/pcb-rnd + +fn="$1" +if test -z $fn +then + fn="../src/pcb-menu-gtk.lht" +fi + +lhtflat < $fn | tee LHT | awk -F "[\t]" ' +!($3 ~ "^//main_menu/") { next } + +{ + menu_path = $3 + sub("//main_menu/", "", menu_path) + gsub("/submenu", "", menu_path) + gsub("[0-9]+::", "", menu_path) +} + +(($1 == "open") && ($2 == "hash")) { + if (current != "") + print current + current = menu_path +} + +(($1 == "data") && ($2 == "text") && (current != "")) { + if ($3 ~ "/a$") { + PROPS["key"] = $4 + sub("<[Kk]ey>", " ", PROPS["key"]) + } + else if ($3 ~ "/action$") { + PROPS["act"] = $4 + } + + +} + +(($1 == "close") && (current != "")) { + print current "\t" PROPS["key"] "\t" PROPS["act"] + current = "" + delete PROPS +} +' | tee Menu.flat | awk -F "[\t]" ' +BEGIN { + q = "\"" + print "digraph menu {" + print "rankdir=LR;" +# print "ranksep=4;" + print "node [shape=record];" + + reg_node("/") +} + +function reg_node(path) +{ + last_id++ + PATH2ID[path] = last_id + ID2PATH[last_id] = path +} + +function add_ch(parent, child) +{ + if (NUM_CH[parent] == "") + NUM_CH[parent] = 0 + if (IS_CH[parent, child]) + return + IS_CH[parent, child] = 1 + CH[parent, NUM_CH[parent]] = child + + NUM_CH[parent]++ +} + +{ + path=$1 + KEY[path] = $2 + ACT[path] = $3 + reg_node(path) + while(path ~ "/") { + parent = path + sub("/[^/]*$", "", parent) + add_ch(parent, path) + path = parent + } + add_ch("/", path) +} + +function gen_menus(parent ,n,child,short,chp) +{ + short=parent + sub(".*/", "", short) + if (!(parent in PATH2ID)) + reg_node(parent) + printf " m" PATH2ID[parent] " [label=\" [[" short "]]" + for(n = 0; n < NUM_CH[parent]; n++) { + child=CH[parent, n] + short=child + sub(".*/", "", short) + printf("| %s", PATH2ID[child], short) + } + print "\"]" + + for(n = 0; n < NUM_CH[parent]; n++) { + child=CH[parent, n] + if (NUM_CH[child] > 0) { + chp = gen_menus(child) + print " m" PATH2ID[parent] ":m" PATH2ID[child] " -> " chp ":menu" + } + } + + return "m" PATH2ID[parent] +} + + +END { + for(n = 0; n < NUM_CH["/"]; n++) { + child=CH["/", n] + curr = gen_menus(child) + if (last != NULL) { + print "tmp" n " [shape=point]" + print last ":menu -> tmp" n " [weight=10000 arrowhead=none]" + print "tmp" n " -> " curr ":menu [weight=10000 arrowhead=none]" + } + last = curr + } + print "}" +} +' > Menu.dot + +dot -Tsvg Menu.dot > Menu.svg + Property changes on: tags/2.3.0/util/menu2svg.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/pcb-prj2lht =================================================================== --- tags/2.3.0/util/pcb-prj2lht (nonexistent) +++ tags/2.3.0/util/pcb-prj2lht (revision 33253) @@ -0,0 +1,158 @@ +#!/bin/sh +# pcb-prj2lht - convert an old gsch2pcb project file to geda project lht +# Copyright (C) 2016 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. +# +# http://repo.hu/projects/pcb-rnd + +# Convert and old gsch2pcb-rnd project file to the new, multi-program +# geda project lihata file format. + +prj2lht() { + awk ' + BEGIN { + INDENT["elements-dir"] = " " + INDENT["schematics"] = " " + } + + function lht_quote(s) { + if (s ~ "[^a-zA-Z0-9_.-]") + return "{" s "}" + return s + } + + function parse() { + name = $1 + $1="" + CFG[name] = $0 + sub("^[ \t]*", "", CFG[name]) + } + + function list_add(key, val) { + CFG[key] = CFG[key] INDENT[key] lht_quote(val) "\n" + } + + function list_add_split(key, val ,n,v,T) { + v = split(val, T, "[ \t]+") + for(n = 1; n <= v; n++) + if (T[n] != "") + list_add(key, T[n]) + } + + function qparse( tmp,name) { + name = $1 + $1="" + tmp=$0 + sub("^[ \t]*", "", tmp) + while(match(tmp, "\"[^\"]*\"")) { + list_add_split(name, substr(tmp, 1, RSTART-1)) + list_add(name, substr(tmp, RSTART+1, RLENGTH-2)) + tmp = substr(tmp, RSTART+RLENGTH, length(tmp)) + } + # leftover after the last quote + list_add_split(name, tmp) + } + + ($1 == "elements-dir") { qparse() } + ($1 == "elements-shell") { parse() } + ($1 == "schematics") { qparse() } + ($1 == "output-name") { parse() } + ($1 == "remove-unfound") { CFG["remove-unfound"] = 1 } + ($1 == "keep-unfound") { CFG["remove-unfound"] = 0 } + ($1 == "quiet") { CFG[$1] = 1 } + ($1 == "preserve") { CFG[$1] = 1 } + ($1 == "default-pcb") { parse() } + ($1 == "gnetlist") { parse() } + ($1 == "enpty-footprint") { parse() } + + function print_val(cfgkey, outkey) { + if (cfgkey in CFG) + print " " outkey " = " lht_quote(CFG[cfgkey]) + } + + END { + print "ha:geda-project-v1 {" + print " li:pcb-rnd-conf-v1 {" + + print " ha:overwrite {" + print " ha:utils {" + print " ha:gsch2pcb_rnd {" + print_val("remove-unfound", "remove_unfound_elements") + print_val("quiet", "quiet_mode") + print_val("preserve", "preserve") + print_val("output-name", "sch_basename") + print_val("default-pcb", "default_pcb") + print_val("gnetlist", "gnetlist") + print_val("empty-footprint", "empty_footprint_name") + if ("schematics" in CFG) { + print " li:schematics {" + printf("%s", CFG["schematics"]) + print " }" + } + print " }" + print " }" + print " ha:rc {" + print_val("elements-shell", "library_shell") + print " }" + print " }" + + if ("elements-dir" in CFG) { + print " ha:prepend {" + print " ha:rc {" + print " li:library_search_paths {" + printf("%s", CFG["elements-dir"]) + print " }" + print " }" + print " }" + } + + print " }" + print "}" + } + ' +} + +help() +{ + echo "pcb-prj2lht - convert a gsch2pcb project file to pcb-rnd lihata project file" + echo "" + echo "Invocation: pcb-prj2lht [something.prj]" + echo "" + echo "If the project file is specified, a new file is created with the .prj" + echo "part replaced with .lht. If no file name specified, read the project" + echo "on STDIN and write the result to STDOUT." + echo "" +} + +########## main ########## + +if test "$1" = "--help" +then + help + exit +fi + +if test $# -gt 0 +then + for n in "$@" + do + out=${n%%.prj}.lht + prj2lht < $n > $out || echo "Failed to convert $n to $out" >&2 + done +else + # stdio operation + prj2lht +fi Property changes on: tags/2.3.0/util/pcb-prj2lht ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/pcb-rnd-svg =================================================================== --- tags/2.3.0/util/pcb-rnd-svg (nonexistent) +++ tags/2.3.0/util/pcb-rnd-svg (revision 33253) @@ -0,0 +1,235 @@ +#!/bin/sh + +# sort objects within groups of a pcb-rnd generated svg so diff will return +# zero difference if only order of objects differ +# file is loaded on stdin, written to stdout +svg_sort() +{ + + awk ' + BEGIN { + sort = "sort" + } + + /^<.g>/ { + close(sort); + ingrp=0; + print $0; + next; + } + + (ingrp) { print $0 | sort; next } + + /^ $t1 + svg_sort < "$2" > $t2 + + diff -u $t1 $t2 + res=$? + + rm $t1 $t2 + return $res +} + +# calculate the diff between two pcb-rnd loadable board files +# board file names are $1 and $2, diff is written on stdout +brd_diff() +{ + local s1=`mktemp` s2=`mktemp` res + + pcb-rnd -x svg --outfile "$s1" "$1" + pcb-rnd -x svg --outfile "$s2" "$2" + if test $? -ne 0 + then + echo "Failed to render board." >&2 + rm $s1 $s2 + exit 1 + fi + + svg_diff $s1 $s2 + res=$? + + rm $s1 $s2 + return $res +} + +# Compare pcb-rnd generated svg file $1 to $2, generate a visual difference +# file using $1 as canvas. Output written to stdout +svg_vis_comp() +{ + local td=`mktemp` + svg_diff "$@" > $td + awk -v "diff=$td" ' + /^", " opacity=\"0.25\">", line); + $0=line + } + /^<.svg/ { + print ""; + getline line < diff; + getline line < diff; + while(getline line < diff) { + color=""; + if (line ~ "^[+]") color = "red"; + else if (line ~ "^[-]") color = "blue"; + if (color != "") { + sub("^.", "", line); + sub("stroke=", "stroke=\"" color "\" old_stroke=", line); + sub("fill=", "fill=\"" color "\" old_fill=", line); + print line; + } + } + print "" + } + + { print $0 } + + ' < $1 +} + +# Compare pcb-rnd loadable board file $1 to $2, generate a visual difference +# file using $1's svg render as canvas. Output written to stdout +brd_vis_comp() +{ + local s1=`mktemp` s2=`mktemp` + + pcb-rnd -x svg --outfile "$s1" "$1" && pcb-rnd -x svg --outfile "$s2" "$2" + if test $? -ne 0 + then + rm $s1 $s2 + echo "Failed to render board." >&2 + exit 1 + fi + + svg_vis_comp $s1 $s2 + + rm $s1 $s2 +} + +pcb_rnd_test() +{ + local fn d res=0 + for fn in "$@" + do + pcb-rnd -x svg --outfile "$fn.svg" "$fn" + if test -f "$fn.ref.gz" -a ! -f "$fn.ref" + then + gzip -d -k "$fn.ref.gz" + del="$fn.ref" + else + del="" + fi + if test -f "$fn.ref" + then + d=`svg_diff "$fn.ref" "$fn.svg"` + if test ! -z "$d" + then + echo "*** $fn" + echo "$d" + svg_vis_comp "$fn.ref" "$fn.svg" > "$fn.diff.svg" + res=1 + else + rm "$fn.svg" + fi + else + echo "No ref svg available for $fn" >&2 + fi + if test ! -z "$del" + then + rm "$del" + fi + done + + return $res +} + +pcb_rnd_test_all() +{ + local d res r + + for d in "$@" + do + find "$d" -name '*.ref' -o -name '*.ref.gz' + done | sort | uniq | while read fn + do + r=${fn%%.gz} + pcb_rnd_test ${r%%.ref} + if test ! $? -ne 0 + then + res=1 + fi + done + return $res +} + +gen_ref() +{ + local fn + for fn in "$@" + do + pcb-rnd -x svg --outfile $fn.ref $fn + gzip -9 $fn.ref + done +} + +help() +{ +echo 'pcb-rnd-svg - compare pcb-rnd svg renders +Syntax: pcb-rnd-svg command [args] +Commands available: + +svg-sort reads a pcb-rnd generated svg on stdin, prints sorted svg +svg-diff s1 s2 sort pcb-rnd generated svgs s1 and s2 and print diff s1 s2 +diff b1 b2 run pcb-rnd on b1 and b2 and print svg diff b1 b2 +svg-vis-comp s1 s2 generate a visual comparison of s1 and s2, diffs highlighted +vis-comp b1 b2 visual comparison svg of boards b1 and b2, diffs highlighted +test brd run pcb-rnd on brd and compare the resulting svg to brd.ref +test-all dir run test on all boards with a ref available under dir +gen-ref filenames run on each board file and generate the reference svg + +' +} + + + +### MAIN ### + +if test $# -lt 1 +then + help + exit 1 +fi + +cmd="$1" +shift 1 +case "$cmd" in + svg-sort|--svg-sort) svg_sort "$@" ;; + svg-diff|--svg-diff) svg_diff "$@" ;; + diff|--diff) brd_diff "$@" ;; + svg-vis-comp|--svg-vis-comp) svg_vis_comp "$@" ;; + vis-comp|--vis-comp) brd_vis_comp "$@" ;; + test|--test) pcb_rnd_test "$@" ;; + gen-ref|--gen-ref) gen_ref "$@" ;; + test-all|--test-all) + if test -z "$*" + then + pcb_rnd_test_all "." + else + pcb_rnd_test_all "$@" + fi + ;; + help) help "$@";; + *) echo "Unknown command $cmd; try --help" >&2; exit 1 ;; +esac Property changes on: tags/2.3.0/util/pcb-rnd-svg ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/pcblib-map/Makefile =================================================================== --- tags/2.3.0/util/pcblib-map/Makefile (nonexistent) +++ tags/2.3.0/util/pcblib-map/Makefile (revision 33253) @@ -0,0 +1,16 @@ +OUT = map.html conn.html parametric.html smd2.html smd3.html smdN.html \ + trh2.html trh3.html trhN.html cache + +all: $(OUT) + +map.html map.png: map.pcb + ./imgmap_page.sh map + +%.html %.png: %.pcb + ./imgmap_fp.sh $* + +cache: + ./cache.sh > cache + +clean: + rm $(OUT) Index: tags/2.3.0/util/pcblib-map/cache.sh =================================================================== --- tags/2.3.0/util/pcblib-map/cache.sh (nonexistent) +++ tags/2.3.0/util/pcblib-map/cache.sh (revision 33253) @@ -0,0 +1,51 @@ +#!/bin/sh + +digest() +{ + local fn bn + fn=$1 + + bn=${fn#./} + + if test -d "$fn" + then + echo "D $bn" + return + fi + + prm=`grep "@@purpose" $fn` + if test -z "$prm" + then + tags=`awk ' + /^##/ { + tag=$0 + sub("^##","", tag) + printf " %s", tag + } + ' < $fn` + echo "S $bn $tags" + else + tags=`awk ' + /^@@tag/ { + tag=$0 + sub("^@@tag *","", tag) + printf " %s", tag + } + ' < $fn` + echo "P $bn $tags" + fi + +} + +( +cd ../../pcblib +for n in `find .` +do + case $n in + *.svn*) ;; + .) ;; + *) + digest $n + esac +done +) Property changes on: tags/2.3.0/util/pcblib-map/cache.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/pcblib-map/conn.pcb =================================================================== --- tags/2.3.0/util/pcblib-map/conn.pcb (nonexistent) +++ tags/2.3.0/util/pcblib-map/conn.pcb (revision 33253) @@ -0,0 +1,1342 @@ +# release: pcb 20110918 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 270000 500000] + +Grid[10000.0 0 0 1] +Cursor[0 30000 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Symbol[' ' 1800] +( +) +Symbol['!' 1200] +( + SymbolLine[0 4500 0 5000 800] + SymbolLine[0 1000 0 3500 800] +) +Symbol['"' 1200] +( + SymbolLine[0 1000 0 2000 800] + SymbolLine[1000 1000 1000 2000 800] +) +Symbol['#' 1200] +( + SymbolLine[0 3500 2000 3500 800] + SymbolLine[0 2500 2000 2500 800] + SymbolLine[1500 2000 1500 4000 800] + SymbolLine[500 2000 500 4000 800] +) +Symbol['$' 1200] +( + SymbolLine[1500 1500 2000 2000 800] + SymbolLine[500 1500 1500 1500 800] + SymbolLine[0 2000 500 1500 800] + SymbolLine[0 2000 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4000 800] + SymbolLine[1500 4500 2000 4000 800] + SymbolLine[500 4500 1500 4500 800] + SymbolLine[0 4000 500 4500 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['%' 1200] +( + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[1000 2500 1500 2000 800] + SymbolLine[500 2500 1000 2500 800] + SymbolLine[0 2000 500 2500 800] + SymbolLine[0 5000 4000 1000 800] + SymbolLine[3500 5000 4000 4500 800] + SymbolLine[4000 4000 4000 4500 800] + SymbolLine[3500 3500 4000 4000 800] + SymbolLine[3000 3500 3500 3500 800] + SymbolLine[2500 4000 3000 3500 800] + SymbolLine[2500 4000 2500 4500 800] + SymbolLine[2500 4500 3000 5000 800] + SymbolLine[3000 5000 3500 5000 800] +) +Symbol['&' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 3500 1500 2000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[0 2500 2500 5000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[0 3500 0 4500 800] +) +Symbol[''' 1200] +( + SymbolLine[0 2000 1000 1000 800] +) +Symbol['(' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] +) +Symbol[')' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['*' 1200] +( + SymbolLine[0 2000 2000 4000 800] + SymbolLine[0 4000 2000 2000 800] + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol['+' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol[',' 1200] +( + SymbolLine[0 6000 1000 5000 800] +) +Symbol['-' 1200] +( + SymbolLine[0 3000 2000 3000 800] +) +Symbol['.' 1200] +( + SymbolLine[0 5000 500 5000 800] +) +Symbol['/' 1200] +( + SymbolLine[0 4500 3000 1500 800] +) +Symbol['0' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4000 2000 2000 800] +) +Symbol['1' 1200] +( + SymbolLine[0 1800 800 1000 800] + SymbolLine[800 1000 800 5000 800] + SymbolLine[0 5000 1500 5000 800] +) +Symbol['2' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[0 5000 2500 2500 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['3' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 2800 1500 2800 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[2000 3300 2000 4500 800] + SymbolLine[2000 3300 1500 2800 800] + SymbolLine[2000 2300 1500 2800 800] +) +Symbol['4' 1200] +( + SymbolLine[0 3500 2000 1000 800] + SymbolLine[0 3500 2500 3500 800] + SymbolLine[2000 1000 2000 5000 800] +) +Symbol['5' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[500 2500 1500 2500 800] + SymbolLine[1500 2500 2000 3000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['6' 1200] +( + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1500 2800 2000 3300 800] + SymbolLine[0 2800 1500 2800 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3300 2000 4500 800] +) +Symbol['7' 1200] +( + SymbolLine[500 5000 2500 1000 800] + SymbolLine[0 1000 2500 1000 800] +) +Symbol['8' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3700 0 4500 800] + SymbolLine[0 3700 700 3000 800] + SymbolLine[700 3000 1300 3000 800] + SymbolLine[1300 3000 2000 3700 800] + SymbolLine[2000 3700 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 2300 700 3000 800] + SymbolLine[0 1500 0 2300 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[1300 3000 2000 2300 800] +) +Symbol['9' 1200] +( + SymbolLine[500 5000 2000 3000 800] + SymbolLine[2000 1500 2000 3000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol[':' 1200] +( + SymbolLine[0 2500 500 2500 800] + SymbolLine[0 3500 500 3500 800] +) +Symbol[';' 1200] +( + SymbolLine[0 5000 1000 4000 800] + SymbolLine[1000 2500 1000 3000 800] +) +Symbol['<' 1200] +( + SymbolLine[0 3000 1000 2000 800] + SymbolLine[0 3000 1000 4000 800] +) +Symbol['=' 1200] +( + SymbolLine[0 2500 2000 2500 800] + SymbolLine[0 3500 2000 3500 800] +) +Symbol['>' 1200] +( + SymbolLine[0 2000 1000 3000 800] + SymbolLine[0 4000 1000 3000 800] +) +Symbol['?' 1200] +( + SymbolLine[1000 3000 1000 3500 800] + SymbolLine[1000 4500 1000 5000 800] + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2000 800] + SymbolLine[1000 3000 2000 2000 800] +) +Symbol['@' 1200] +( + SymbolLine[0 1000 0 4000 800] + SymbolLine[0 4000 1000 5000 800] + SymbolLine[1000 5000 4000 5000 800] + SymbolLine[5000 3500 5000 1000 800] + SymbolLine[5000 1000 4000 0 800] + SymbolLine[4000 0 1000 0 800] + SymbolLine[1000 0 0 1000 800] + SymbolLine[1500 2000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 3000 3500 800] + SymbolLine[3000 3500 3500 3000 800] + SymbolLine[3500 3000 4000 3500 800] + SymbolLine[3500 3000 3500 1500 800] + SymbolLine[3500 2000 3000 1500 800] + SymbolLine[2000 1500 3000 1500 800] + SymbolLine[2000 1500 1500 2000 800] + SymbolLine[4000 3500 5000 3500 800] +) +Symbol['A' 1200] +( + SymbolLine[0 2000 0 5000 800] + SymbolLine[0 2000 700 1000 800] + SymbolLine[700 1000 1800 1000 800] + SymbolLine[1800 1000 2500 2000 800] + SymbolLine[2500 2000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['B' 1200] +( + SymbolLine[0 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3300 2500 4500 800] + SymbolLine[2000 2800 2500 3300 800] + SymbolLine[500 2800 2000 2800 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2300 800] + SymbolLine[2000 2800 2500 2300 800] +) +Symbol['C' 1200] +( + SymbolLine[700 5000 2000 5000 800] + SymbolLine[0 4300 700 5000 800] + SymbolLine[0 1700 0 4300 800] + SymbolLine[0 1700 700 1000 800] + SymbolLine[700 1000 2000 1000 800] +) +Symbol['D' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[1800 1000 2500 1700 800] + SymbolLine[2500 1700 2500 4300 800] + SymbolLine[1800 5000 2500 4300 800] + SymbolLine[0 5000 1800 5000 800] + SymbolLine[0 1000 1800 1000 800] +) +Symbol['E' 1200] +( + SymbolLine[0 2800 1500 2800 800] + SymbolLine[0 5000 2000 5000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] +) +Symbol['F' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 2800 1500 2800 800] +) +Symbol['G' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[1000 3000 2000 3000 800] +) +Symbol['H' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[2500 1000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['I' 1200] +( + SymbolLine[0 1000 1000 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 1000 5000 800] +) +Symbol['J' 1200] +( + SymbolLine[700 1000 1500 1000 800] + SymbolLine[1500 1000 1500 4500 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 4500 0 4000 800] +) +Symbol['K' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3000 2000 1000 800] + SymbolLine[0 3000 2000 5000 800] +) +Symbol['L' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['M' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 1500 3000 800] + SymbolLine[1500 3000 3000 1000 800] + SymbolLine[3000 1000 3000 5000 800] +) +Symbol['N' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2500 5000 800] + SymbolLine[2500 1000 2500 5000 800] +) +Symbol['O' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['P' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol['Q' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1000 3500 2000 5000 800] +) +Symbol['R' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[1300 3000 2500 5000 800] +) +Symbol['S' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['T' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['U' 1200] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 1000 2000 4500 800] +) +Symbol['V' 1200] +( + SymbolLine[0 1000 1000 5000 800] + SymbolLine[1000 5000 2000 1000 800] +) +Symbol['W' 1200] +( + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 5000 800] + SymbolLine[500 5000 1500 3000 800] + SymbolLine[1500 3000 2500 5000 800] + SymbolLine[2500 5000 3000 3000 800] + SymbolLine[3000 3000 3000 1000 800] +) +Symbol['X' 1200] +( + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 1000 2500 5000 800] +) +Symbol['Y' 1200] +( + SymbolLine[0 1000 1000 3000 800] + SymbolLine[1000 3000 2000 1000 800] + SymbolLine[1000 3000 1000 5000 800] +) +Symbol['Z' 1200] +( + SymbolLine[0 1000 2500 1000 800] + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['[' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['\' 1200] +( + SymbolLine[0 1500 3000 4500 800] +) +Symbol[']' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['^' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1500 800] +) +Symbol['_' 1200] +( + SymbolLine[0 5000 2000 5000 800] +) +Symbol['a' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[2000 4500 2500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['b' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] +) +Symbol['c' 1200] +( + SymbolLine[500 3000 2000 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] +) +Symbol['d' 1200] +( + SymbolLine[2000 1000 2000 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] +) +Symbol['e' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[0 4000 2000 4000 800] + SymbolLine[2000 4000 2000 3500 800] +) +Symbol['f' 1000] +( + SymbolLine[500 1500 500 5000 800] + SymbolLine[500 1500 1000 1000 800] + SymbolLine[1000 1000 1500 1000 800] + SymbolLine[0 3000 1000 3000 800] +) +Symbol['g' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[2000 3000 2000 6000 800] +) +Symbol['h' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] +) +Symbol['i' 1000] +( + SymbolLine[0 2000 0 2100 1000] + SymbolLine[0 3500 0 5000 800] +) +Symbol['j' 1000] +( + SymbolLine[500 2000 500 2100 1000] + SymbolLine[500 3500 500 6000 800] + SymbolLine[0 6500 500 6000 800] +) +Symbol['k' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 1500 5000 800] + SymbolLine[0 3500 1000 2500 800] +) +Symbol['l' 1000] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['m' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[2000 3500 2500 3000 800] + SymbolLine[2500 3000 3000 3000 800] + SymbolLine[3000 3000 3500 3500 800] + SymbolLine[3500 3500 3500 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['n' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['o' 1200] +( + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['p' 1200] +( + SymbolLine[500 3500 500 6500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[1000 5000 2000 5000 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['q' 1200] +( + SymbolLine[2000 3500 2000 6500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['r' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['s' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2000 4000 2500 4500 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['t' 1000] +( + SymbolLine[500 1000 500 4500 800] + SymbolLine[500 4500 1000 5000 800] + SymbolLine[0 2500 1000 2500 800] +) +Symbol['u' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3000 2000 4500 800] +) +Symbol['v' 1200] +( + SymbolLine[0 3000 1000 5000 800] + SymbolLine[2000 3000 1000 5000 800] +) +Symbol['w' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[1500 3000 1500 4500 800] + SymbolLine[1500 4500 2000 5000 800] + SymbolLine[2000 5000 2500 5000 800] + SymbolLine[2500 5000 3000 4500 800] + SymbolLine[3000 3000 3000 4500 800] +) +Symbol['x' 1200] +( + SymbolLine[0 3000 2000 5000 800] + SymbolLine[0 5000 2000 3000 800] +) +Symbol['y' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 6000 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['z' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[0 5000 2000 3000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['{' 1200] +( + SymbolLine[500 1500 1000 1000 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['|' 1200] +( + SymbolLine[0 1000 0 5000 800] +) +Symbol['}' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[500 2500 1000 3000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['~' 1200] +( + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1000 3000 800] + SymbolLine[1000 3000 1500 3500 800] + SymbolLine[1500 3500 2000 3500 800] + SymbolLine[2000 3500 2500 3000 800] +) +Attribute("PCB::grid::unit" "mil") +Via[270000 500000 7874 4000 0 3150 "" ""] + +Element["" "DSUB connector, female/male" "" "DB15F" 20000 50000 5600 0 3 150 ""] +( + Pin[0 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[0 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[0 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[0 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[0 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[0 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[0 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[0 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[11200 5400 6000 3000 6600 3500 "9" "9" ""] + Pin[11200 16200 6000 3000 6600 3500 "10" "10" ""] + Pin[11200 27000 6000 3000 6600 3500 "11" "11" ""] + Pin[11200 37800 6000 3000 6600 3500 "12" "12" ""] + Pin[11200 48600 6000 3000 6600 3500 "13" "13" ""] + Pin[11200 59400 6000 3000 6600 3500 "14" "14" ""] + Pin[11200 70200 6000 3000 6600 3500 "15" "15" ""] + Pin[5600 102600 25000 3000 25600 12500 "C1" "16" ""] + Pin[5600 -27000 25000 3000 25600 12500 "C2" "17" ""] + ElementLine [39100 114600 42100 114600 1000] + ElementLine [39100 -39000 39100 114600 1000] + ElementLine [39100 -39000 42100 -39000 1000] + ElementLine [42100 -39000 42100 114600 1000] + ElementLine [39100 108600 42100 108600 1000] + ElementLine [39100 96600 42100 96600 1000] + ElementLine [39100 -33000 42100 -33000 1000] + ElementLine [39100 -21000 42100 -21000 1000] + ElementLine [28600 91600 39100 91600 2000] + ElementLine [28600 -16000 28600 91600 2000] + ElementLine [28600 -16000 39100 -16000 2000] + ElementLine [39100 -16000 39100 91600 1000] + ElementLine [4000 0 28600 0 2000] + ElementLine [4000 10800 28600 10800 2000] + ElementLine [4000 21600 28600 21600 2000] + ElementLine [4000 32400 28600 32400 2000] + ElementLine [4000 43200 28600 43200 2000] + ElementLine [4000 54000 28600 54000 2000] + ElementLine [4000 64800 28600 64800 2000] + ElementLine [4000 75600 28600 75600 2000] + ElementLine [15200 5400 28600 5400 2000] + ElementLine [15200 16200 28600 16200 2000] + ElementLine [15200 27000 28600 27000 2000] + ElementLine [15200 37800 28600 37800 2000] + ElementLine [15200 48600 28600 48600 2000] + ElementLine [15200 59400 28600 59400 2000] + ElementLine [15200 70200 28600 70200 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB15M" 110000 50000 -5000 75600 1 150 ""] +( + Pin[600 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[600 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[600 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[600 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[600 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[600 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[600 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[600 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[-10600 5400 6000 3000 6600 3500 "9" "9" ""] + Pin[-10600 16200 6000 3000 6600 3500 "10" "10" ""] + Pin[-10600 27000 6000 3000 6600 3500 "11" "11" ""] + Pin[-10600 37800 6000 3000 6600 3500 "12" "12" ""] + Pin[-10600 48600 6000 3000 6600 3500 "13" "13" ""] + Pin[-10600 59400 6000 3000 6600 3500 "14" "14" ""] + Pin[-10600 70200 6000 3000 6600 3500 "15" "15" ""] + Pin[-5000 -27000 25000 3000 25600 12500 "C1" "16" ""] + Pin[-5000 102600 25000 3000 25600 12500 "C2" "17" ""] + ElementLine [-41500 -39000 -38500 -39000 1000] + ElementLine [-38500 -39000 -38500 114600 1000] + ElementLine [-38500 114600 -41500 114600 1000] + ElementLine [-41500 114600 -41500 -39000 1000] + ElementLine [-41500 -33000 -38500 -33000 1000] + ElementLine [-41500 -21000 -38500 -21000 1000] + ElementLine [-41500 108600 -38500 108600 1000] + ElementLine [-41500 96600 -38500 96600 1000] + ElementLine [-38500 -16000 -28000 -16000 2000] + ElementLine [-28000 -16000 -28000 91600 2000] + ElementLine [-28000 91600 -38500 91600 2000] + ElementLine [-38500 91600 -38500 -16000 1000] + ElementLine [-3400 0 -28000 0 2000] + ElementLine [-3400 10800 -28000 10800 2000] + ElementLine [-3400 21600 -28000 21600 2000] + ElementLine [-3400 32400 -28000 32400 2000] + ElementLine [-3400 43200 -28000 43200 2000] + ElementLine [-3400 54000 -28000 54000 2000] + ElementLine [-3400 64800 -28000 64800 2000] + ElementLine [-3400 75600 -28000 75600 2000] + ElementLine [-14600 5400 -28000 5400 2000] + ElementLine [-14600 16200 -28000 16200 2000] + ElementLine [-14600 27000 -28000 27000 2000] + ElementLine [-14600 37800 -28000 37800 2000] + ElementLine [-14600 48600 -28000 48600 2000] + ElementLine [-14600 59400 -28000 59400 2000] + ElementLine [-14600 70200 -28000 70200 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB25F" 160000 50000 5600 0 3 150 ""] +( + Pin[0 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[0 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[0 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[0 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[0 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[0 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[0 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[0 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[0 86400 6000 3000 6600 3500 "9" "9" ""] + Pin[0 97200 6000 3000 6600 3500 "10" "10" ""] + Pin[0 108000 6000 3000 6600 3500 "11" "11" ""] + Pin[0 118800 6000 3000 6600 3500 "12" "12" ""] + Pin[0 129600 6000 3000 6600 3500 "13" "13" ""] + Pin[11200 5400 6000 3000 6600 3500 "14" "14" ""] + Pin[11200 16200 6000 3000 6600 3500 "15" "15" ""] + Pin[11200 27000 6000 3000 6600 3500 "16" "16" ""] + Pin[11200 37800 6000 3000 6600 3500 "17" "17" ""] + Pin[11200 48600 6000 3000 6600 3500 "18" "18" ""] + Pin[11200 59400 6000 3000 6600 3500 "19" "19" ""] + Pin[11200 70200 6000 3000 6600 3500 "20" "20" ""] + Pin[11200 81000 6000 3000 6600 3500 "21" "21" ""] + Pin[11200 91800 6000 3000 6600 3500 "22" "22" ""] + Pin[11200 102600 6000 3000 6600 3500 "23" "23" ""] + Pin[11200 113400 6000 3000 6600 3500 "24" "24" ""] + Pin[11200 124200 6000 3000 6600 3500 "25" "25" ""] + Pin[5600 156600 25000 3000 25600 12500 "C1" "26" ""] + Pin[5600 -27000 25000 3000 25600 12500 "C2" "27" ""] + ElementLine [39100 168600 42100 168600 1000] + ElementLine [39100 -39000 39100 168600 1000] + ElementLine [39100 -39000 42100 -39000 1000] + ElementLine [42100 -39000 42100 168600 1000] + ElementLine [39100 162600 42100 162600 1000] + ElementLine [39100 150600 42100 150600 1000] + ElementLine [39100 -33000 42100 -33000 1000] + ElementLine [39100 -21000 42100 -21000 1000] + ElementLine [28600 145600 39100 145600 2000] + ElementLine [28600 -16000 28600 145600 2000] + ElementLine [28600 -16000 39100 -16000 2000] + ElementLine [39100 -16000 39100 145600 1000] + ElementLine [4000 0 28600 0 2000] + ElementLine [4000 10800 28600 10800 2000] + ElementLine [4000 21600 28600 21600 2000] + ElementLine [4000 32400 28600 32400 2000] + ElementLine [4000 43200 28600 43200 2000] + ElementLine [4000 54000 28600 54000 2000] + ElementLine [4000 64800 28600 64800 2000] + ElementLine [4000 75600 28600 75600 2000] + ElementLine [4000 86400 28600 86400 2000] + ElementLine [4000 97200 28600 97200 2000] + ElementLine [4000 108000 28600 108000 2000] + ElementLine [4000 118800 28600 118800 2000] + ElementLine [4000 129600 28600 129600 2000] + ElementLine [15200 5400 28600 5400 2000] + ElementLine [15200 16200 28600 16200 2000] + ElementLine [15200 27000 28600 27000 2000] + ElementLine [15200 37800 28600 37800 2000] + ElementLine [15200 48600 28600 48600 2000] + ElementLine [15200 59400 28600 59400 2000] + ElementLine [15200 70200 28600 70200 2000] + ElementLine [15200 81000 28600 81000 2000] + ElementLine [15200 91800 28600 91800 2000] + ElementLine [15200 102600 28600 102600 2000] + ElementLine [15200 113400 28600 113400 2000] + ElementLine [15200 124200 28600 124200 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB25M" 250000 50000 -5000 129600 1 150 ""] +( + Pin[600 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[600 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[600 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[600 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[600 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[600 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[600 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[600 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[600 86400 6000 3000 6600 3500 "9" "9" ""] + Pin[600 97200 6000 3000 6600 3500 "10" "10" ""] + Pin[600 108000 6000 3000 6600 3500 "11" "11" ""] + Pin[600 118800 6000 3000 6600 3500 "12" "12" ""] + Pin[600 129600 6000 3000 6600 3500 "13" "13" ""] + Pin[-10600 5400 6000 3000 6600 3500 "14" "14" ""] + Pin[-10600 16200 6000 3000 6600 3500 "15" "15" ""] + Pin[-10600 27000 6000 3000 6600 3500 "16" "16" ""] + Pin[-10600 37800 6000 3000 6600 3500 "17" "17" ""] + Pin[-10600 48600 6000 3000 6600 3500 "18" "18" ""] + Pin[-10600 59400 6000 3000 6600 3500 "19" "19" ""] + Pin[-10600 70200 6000 3000 6600 3500 "20" "20" ""] + Pin[-10600 81000 6000 3000 6600 3500 "21" "21" ""] + Pin[-10600 91800 6000 3000 6600 3500 "22" "22" ""] + Pin[-10600 102600 6000 3000 6600 3500 "23" "23" ""] + Pin[-10600 113400 6000 3000 6600 3500 "24" "24" ""] + Pin[-10600 124200 6000 3000 6600 3500 "25" "25" ""] + Pin[-5000 -27000 25000 3000 25600 12500 "C1" "26" ""] + Pin[-5000 156600 25000 3000 25600 12500 "C2" "27" ""] + ElementLine [-41500 -39000 -38500 -39000 1000] + ElementLine [-38500 -39000 -38500 168600 1000] + ElementLine [-38500 168600 -41500 168600 1000] + ElementLine [-41500 168600 -41500 -39000 1000] + ElementLine [-41500 -33000 -38500 -33000 1000] + ElementLine [-41500 -21000 -38500 -21000 1000] + ElementLine [-41500 162600 -38500 162600 1000] + ElementLine [-41500 150600 -38500 150600 1000] + ElementLine [-38500 -16000 -28000 -16000 2000] + ElementLine [-28000 -16000 -28000 145600 2000] + ElementLine [-28000 145600 -38500 145600 2000] + ElementLine [-38500 145600 -38500 -16000 1000] + ElementLine [-3400 0 -28000 0 2000] + ElementLine [-3400 10800 -28000 10800 2000] + ElementLine [-3400 21600 -28000 21600 2000] + ElementLine [-3400 32400 -28000 32400 2000] + ElementLine [-3400 43200 -28000 43200 2000] + ElementLine [-3400 54000 -28000 54000 2000] + ElementLine [-3400 64800 -28000 64800 2000] + ElementLine [-3400 75600 -28000 75600 2000] + ElementLine [-3400 86400 -28000 86400 2000] + ElementLine [-3400 97200 -28000 97200 2000] + ElementLine [-3400 108000 -28000 108000 2000] + ElementLine [-3400 118800 -28000 118800 2000] + ElementLine [-3400 129600 -28000 129600 2000] + ElementLine [-14600 5400 -28000 5400 2000] + ElementLine [-14600 16200 -28000 16200 2000] + ElementLine [-14600 27000 -28000 27000 2000] + ElementLine [-14600 37800 -28000 37800 2000] + ElementLine [-14600 48600 -28000 48600 2000] + ElementLine [-14600 59400 -28000 59400 2000] + ElementLine [-14600 70200 -28000 70200 2000] + ElementLine [-14600 81000 -28000 81000 2000] + ElementLine [-14600 91800 -28000 91800 2000] + ElementLine [-14600 102600 -28000 102600 2000] + ElementLine [-14600 113400 -28000 113400 2000] + ElementLine [-14600 124200 -28000 124200 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB37F" 20000 260000 5600 0 3 150 ""] +( + Pin[0 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[0 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[0 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[0 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[0 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[0 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[0 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[0 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[0 86400 6000 3000 6600 3500 "9" "9" ""] + Pin[0 97200 6000 3000 6600 3500 "10" "10" ""] + Pin[0 108000 6000 3000 6600 3500 "11" "11" ""] + Pin[0 118800 6000 3000 6600 3500 "12" "12" ""] + Pin[0 129600 6000 3000 6600 3500 "13" "13" ""] + Pin[0 140400 6000 3000 6600 3500 "14" "14" ""] + Pin[0 151200 6000 3000 6600 3500 "15" "15" ""] + Pin[0 162000 6000 3000 6600 3500 "16" "16" ""] + Pin[0 172800 6000 3000 6600 3500 "17" "17" ""] + Pin[0 183600 6000 3000 6600 3500 "18" "18" ""] + Pin[0 194400 6000 3000 6600 3500 "19" "19" ""] + Pin[11200 5400 6000 3000 6600 3500 "20" "20" ""] + Pin[11200 16200 6000 3000 6600 3500 "21" "21" ""] + Pin[11200 27000 6000 3000 6600 3500 "22" "22" ""] + Pin[11200 37800 6000 3000 6600 3500 "23" "23" ""] + Pin[11200 48600 6000 3000 6600 3500 "24" "24" ""] + Pin[11200 59400 6000 3000 6600 3500 "25" "25" ""] + Pin[11200 70200 6000 3000 6600 3500 "26" "26" ""] + Pin[11200 81000 6000 3000 6600 3500 "27" "27" ""] + Pin[11200 91800 6000 3000 6600 3500 "28" "28" ""] + Pin[11200 102600 6000 3000 6600 3500 "29" "29" ""] + Pin[11200 113400 6000 3000 6600 3500 "30" "30" ""] + Pin[11200 124200 6000 3000 6600 3500 "31" "31" ""] + Pin[11200 135000 6000 3000 6600 3500 "32" "32" ""] + Pin[11200 145800 6000 3000 6600 3500 "33" "33" ""] + Pin[11200 156600 6000 3000 6600 3500 "34" "34" ""] + Pin[11200 167400 6000 3000 6600 3500 "35" "35" ""] + Pin[11200 178200 6000 3000 6600 3500 "36" "36" ""] + Pin[11200 189000 6000 3000 6600 3500 "37" "37" ""] + Pin[5600 221400 25000 3000 25600 12500 "C1" "38" ""] + Pin[5600 -27000 25000 3000 25600 12500 "C2" "39" ""] + ElementLine [39100 233400 42100 233400 1000] + ElementLine [39100 -39000 39100 233400 1000] + ElementLine [39100 -39000 42100 -39000 1000] + ElementLine [42100 -39000 42100 233400 1000] + ElementLine [39100 227400 42100 227400 1000] + ElementLine [39100 215400 42100 215400 1000] + ElementLine [39100 -33000 42100 -33000 1000] + ElementLine [39100 -21000 42100 -21000 1000] + ElementLine [28600 210400 39100 210400 2000] + ElementLine [28600 -16000 28600 210400 2000] + ElementLine [28600 -16000 39100 -16000 2000] + ElementLine [39100 -16000 39100 210400 1000] + ElementLine [4000 0 28600 0 2000] + ElementLine [4000 10800 28600 10800 2000] + ElementLine [4000 21600 28600 21600 2000] + ElementLine [4000 32400 28600 32400 2000] + ElementLine [4000 43200 28600 43200 2000] + ElementLine [4000 54000 28600 54000 2000] + ElementLine [4000 64800 28600 64800 2000] + ElementLine [4000 75600 28600 75600 2000] + ElementLine [4000 86400 28600 86400 2000] + ElementLine [4000 97200 28600 97200 2000] + ElementLine [4000 108000 28600 108000 2000] + ElementLine [4000 118800 28600 118800 2000] + ElementLine [4000 129600 28600 129600 2000] + ElementLine [4000 140400 28600 140400 2000] + ElementLine [4000 151200 28600 151200 2000] + ElementLine [4000 162000 28600 162000 2000] + ElementLine [4000 172800 28600 172800 2000] + ElementLine [4000 183600 28600 183600 2000] + ElementLine [4000 194400 28600 194400 2000] + ElementLine [15200 5400 28600 5400 2000] + ElementLine [15200 16200 28600 16200 2000] + ElementLine [15200 27000 28600 27000 2000] + ElementLine [15200 37800 28600 37800 2000] + ElementLine [15200 48600 28600 48600 2000] + ElementLine [15200 59400 28600 59400 2000] + ElementLine [15200 70200 28600 70200 2000] + ElementLine [15200 81000 28600 81000 2000] + ElementLine [15200 91800 28600 91800 2000] + ElementLine [15200 102600 28600 102600 2000] + ElementLine [15200 113400 28600 113400 2000] + ElementLine [15200 124200 28600 124200 2000] + ElementLine [15200 135000 28600 135000 2000] + ElementLine [15200 145800 28600 145800 2000] + ElementLine [15200 156600 28600 156600 2000] + ElementLine [15200 167400 28600 167400 2000] + ElementLine [15200 178200 28600 178200 2000] + ElementLine [15200 189000 28600 189000 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB37M" 110000 260000 -5000 194400 1 150 ""] +( + Pin[600 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[600 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[600 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[600 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[600 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[600 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[600 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[600 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[600 86400 6000 3000 6600 3500 "9" "9" ""] + Pin[600 97200 6000 3000 6600 3500 "10" "10" ""] + Pin[600 108000 6000 3000 6600 3500 "11" "11" ""] + Pin[600 118800 6000 3000 6600 3500 "12" "12" ""] + Pin[600 129600 6000 3000 6600 3500 "13" "13" ""] + Pin[600 140400 6000 3000 6600 3500 "14" "14" ""] + Pin[600 151200 6000 3000 6600 3500 "15" "15" ""] + Pin[600 162000 6000 3000 6600 3500 "16" "16" ""] + Pin[600 172800 6000 3000 6600 3500 "17" "17" ""] + Pin[600 183600 6000 3000 6600 3500 "18" "18" ""] + Pin[600 194400 6000 3000 6600 3500 "19" "19" ""] + Pin[-10600 5400 6000 3000 6600 3500 "20" "20" ""] + Pin[-10600 16200 6000 3000 6600 3500 "21" "21" ""] + Pin[-10600 27000 6000 3000 6600 3500 "22" "22" ""] + Pin[-10600 37800 6000 3000 6600 3500 "23" "23" ""] + Pin[-10600 48600 6000 3000 6600 3500 "24" "24" ""] + Pin[-10600 59400 6000 3000 6600 3500 "25" "25" ""] + Pin[-10600 70200 6000 3000 6600 3500 "26" "26" ""] + Pin[-10600 81000 6000 3000 6600 3500 "27" "27" ""] + Pin[-10600 91800 6000 3000 6600 3500 "28" "28" ""] + Pin[-10600 102600 6000 3000 6600 3500 "29" "29" ""] + Pin[-10600 113400 6000 3000 6600 3500 "30" "30" ""] + Pin[-10600 124200 6000 3000 6600 3500 "31" "31" ""] + Pin[-10600 135000 6000 3000 6600 3500 "32" "32" ""] + Pin[-10600 145800 6000 3000 6600 3500 "33" "33" ""] + Pin[-10600 156600 6000 3000 6600 3500 "34" "34" ""] + Pin[-10600 167400 6000 3000 6600 3500 "35" "35" ""] + Pin[-10600 178200 6000 3000 6600 3500 "36" "36" ""] + Pin[-10600 189000 6000 3000 6600 3500 "37" "37" ""] + Pin[-5000 -27000 25000 3000 25600 12500 "C1" "38" ""] + Pin[-5000 221400 25000 3000 25600 12500 "C2" "39" ""] + ElementLine [-41500 -39000 -38500 -39000 1000] + ElementLine [-38500 -39000 -38500 233400 1000] + ElementLine [-38500 233400 -41500 233400 1000] + ElementLine [-41500 233400 -41500 -39000 1000] + ElementLine [-41500 -33000 -38500 -33000 1000] + ElementLine [-41500 -21000 -38500 -21000 1000] + ElementLine [-41500 227400 -38500 227400 1000] + ElementLine [-41500 215400 -38500 215400 1000] + ElementLine [-38500 -16000 -28000 -16000 2000] + ElementLine [-28000 -16000 -28000 210400 2000] + ElementLine [-28000 210400 -38500 210400 2000] + ElementLine [-38500 210400 -38500 -16000 1000] + ElementLine [-3400 0 -28000 0 2000] + ElementLine [-3400 10800 -28000 10800 2000] + ElementLine [-3400 21600 -28000 21600 2000] + ElementLine [-3400 32400 -28000 32400 2000] + ElementLine [-3400 43200 -28000 43200 2000] + ElementLine [-3400 54000 -28000 54000 2000] + ElementLine [-3400 64800 -28000 64800 2000] + ElementLine [-3400 75600 -28000 75600 2000] + ElementLine [-3400 86400 -28000 86400 2000] + ElementLine [-3400 97200 -28000 97200 2000] + ElementLine [-3400 108000 -28000 108000 2000] + ElementLine [-3400 118800 -28000 118800 2000] + ElementLine [-3400 129600 -28000 129600 2000] + ElementLine [-3400 140400 -28000 140400 2000] + ElementLine [-3400 151200 -28000 151200 2000] + ElementLine [-3400 162000 -28000 162000 2000] + ElementLine [-3400 172800 -28000 172800 2000] + ElementLine [-3400 183600 -28000 183600 2000] + ElementLine [-3400 194400 -28000 194400 2000] + ElementLine [-14600 5400 -28000 5400 2000] + ElementLine [-14600 16200 -28000 16200 2000] + ElementLine [-14600 27000 -28000 27000 2000] + ElementLine [-14600 37800 -28000 37800 2000] + ElementLine [-14600 48600 -28000 48600 2000] + ElementLine [-14600 59400 -28000 59400 2000] + ElementLine [-14600 70200 -28000 70200 2000] + ElementLine [-14600 81000 -28000 81000 2000] + ElementLine [-14600 91800 -28000 91800 2000] + ElementLine [-14600 102600 -28000 102600 2000] + ElementLine [-14600 113400 -28000 113400 2000] + ElementLine [-14600 124200 -28000 124200 2000] + ElementLine [-14600 135000 -28000 135000 2000] + ElementLine [-14600 145800 -28000 145800 2000] + ElementLine [-14600 156600 -28000 156600 2000] + ElementLine [-14600 167400 -28000 167400 2000] + ElementLine [-14600 178200 -28000 178200 2000] + ElementLine [-14600 189000 -28000 189000 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB9F" 160000 290000 5600 0 3 150 ""] +( + Pin[0 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[0 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[0 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[0 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[0 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[11200 5400 6000 3000 6600 3500 "6" "6" ""] + Pin[11200 16200 6000 3000 6600 3500 "7" "7" ""] + Pin[11200 27000 6000 3000 6600 3500 "8" "8" ""] + Pin[11200 37800 6000 3000 6600 3500 "9" "9" ""] + Pin[5600 70200 25000 3000 25600 12500 "C1" "10" ""] + Pin[5600 -27000 25000 3000 25600 12500 "C2" "11" ""] + ElementLine [39100 82200 42100 82200 1000] + ElementLine [39100 -39000 39100 82200 1000] + ElementLine [39100 -39000 42100 -39000 1000] + ElementLine [42100 -39000 42100 82200 1000] + ElementLine [39100 76200 42100 76200 1000] + ElementLine [39100 64200 42100 64200 1000] + ElementLine [39100 -33000 42100 -33000 1000] + ElementLine [39100 -21000 42100 -21000 1000] + ElementLine [28600 59200 39100 59200 2000] + ElementLine [28600 -16000 28600 59200 2000] + ElementLine [28600 -16000 39100 -16000 2000] + ElementLine [39100 -16000 39100 59200 1000] + ElementLine [4000 0 28600 0 2000] + ElementLine [4000 10800 28600 10800 2000] + ElementLine [4000 21600 28600 21600 2000] + ElementLine [4000 32400 28600 32400 2000] + ElementLine [4000 43200 28600 43200 2000] + ElementLine [15200 5400 28600 5400 2000] + ElementLine [15200 16200 28600 16200 2000] + ElementLine [15200 27000 28600 27000 2000] + ElementLine [15200 37800 28600 37800 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB9M" 250000 290000 -5000 43200 1 150 ""] +( + Pin[600 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[600 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[600 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[600 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[600 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[-10600 5400 6000 3000 6600 3500 "6" "6" ""] + Pin[-10600 16200 6000 3000 6600 3500 "7" "7" ""] + Pin[-10600 27000 6000 3000 6600 3500 "8" "8" ""] + Pin[-10600 37800 6000 3000 6600 3500 "9" "9" ""] + Pin[-5000 -27000 25000 3000 25600 12500 "C1" "10" ""] + Pin[-5000 70200 25000 3000 25600 12500 "C2" "11" ""] + ElementLine [-41500 -39000 -38500 -39000 1000] + ElementLine [-38500 -39000 -38500 82200 1000] + ElementLine [-38500 82200 -41500 82200 1000] + ElementLine [-41500 82200 -41500 -39000 1000] + ElementLine [-41500 -33000 -38500 -33000 1000] + ElementLine [-41500 -21000 -38500 -21000 1000] + ElementLine [-41500 76200 -38500 76200 1000] + ElementLine [-41500 64200 -38500 64200 1000] + ElementLine [-38500 -16000 -28000 -16000 2000] + ElementLine [-28000 -16000 -28000 59200 2000] + ElementLine [-28000 59200 -38500 59200 2000] + ElementLine [-38500 59200 -38500 -16000 1000] + ElementLine [-3400 0 -28000 0 2000] + ElementLine [-3400 10800 -28000 10800 2000] + ElementLine [-3400 21600 -28000 21600 2000] + ElementLine [-3400 32400 -28000 32400 2000] + ElementLine [-3400 43200 -28000 43200 2000] + ElementLine [-14600 5400 -28000 5400 2000] + ElementLine [-14600 16200 -28000 16200 2000] + ElementLine [-14600 27000 -28000 27000 2000] + ElementLine [-14600 37800 -28000 37800 2000] + + ) + +Element["" "right angle BNC" "" "BNC_LAY" 150000 440000 20000 0 3 100 ""] +( + Pin[0 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[0 -10000 6000 3000 6600 3500 "2" "2" ""] + Pin[20000 -20000 10000 3000 10600 8100 "m1" "3" ""] + Pin[20000 20000 10000 3000 10600 8100 "m2" "4" ""] + ElementLine [-6000 -29000 49000 -29000 1000] + ElementLine [49000 -29000 49000 29000 1000] + ElementLine [49000 29000 -6000 29000 1000] + ElementLine [-6000 29000 -6000 -29000 1000] + + ) + +Element["" "" "" "pwrjack" 240000 470000 0 0 0 100 ""] +( + Pin[0 0 19685 2000 20285 11811 "" "2" ""] + Pin[0 -27559 19685 2000 20285 11811 "" "1" ""] + Pin[-17717 -13779 19685 2000 20285 11811 "" "3" ""] + ElementLine [-17717 -55118 -17717 0 1000] + ElementLine [-17717 0 17716 0 1000] + ElementLine [17716 0 17716 -55118 1000] + ElementLine [17716 -55118 -17717 -55118 1000] + ElementLine [-17717 -43307 17716 -43307 1000] + + ) +Layer(1 "component") +( +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) Index: tags/2.3.0/util/pcblib-map/imgmap_fp.sh =================================================================== --- tags/2.3.0/util/pcblib-map/imgmap_fp.sh (nonexistent) +++ tags/2.3.0/util/pcblib-map/imgmap_fp.sh (revision 33253) @@ -0,0 +1,127 @@ +#!/bin/sh +pcb=$1.pcb + +pcb -x png --dpi 300 --photo-mode $pcb +png=$1.png +html=$1.html + +png_dims=`file $png | awk -F "[,]" '{ sub("x", " ", $2); print $2}'` + + + +awk -v "png_dims=$png_dims" -v "png_url=$png" ' +BEGIN { + q = "\"" + sub("^ *", "", png_dims) + sub(" *$", "", png_dims) + split(png_dims, A, " +") + png_sx = A[1] + png_sy = A[2] + ne = 0 +} + +function bump(idx, x, y) +{ + if ((E[idx, "minx"] == "") || (x < E[idx, "minx"])) + E[idx, "minx"] = x + if ((E[idx, "maxx"] == "") || (x > E[idx, "maxx"])) + E[idx, "maxx"] = x + if ((E[idx, "miny"] == "") || (y < E[idx, "miny"])) + E[idx, "miny"] = y + if ((E[idx, "maxy"] == "") || (y > E[idx, "maxy"])) + E[idx, "maxy"] = y +} + +# Element["" "rcy(150, bar-sign)" "C1" "acy150" 22500 95000 -2000 -4500 1 100 ""] +/^Element *[[]/ { + coords=$0 + sub("Element *[[]", "", coords) + for(n = 1; n <= 4; n++) { + match(coords, "[\"][^\"]*[\"]") + P[n] = substr(coords, RSTART+1, RLENGTH-2) + sub("[\"][^\"]*[\"]", "", coords) + } + split(coords, A, " ") + E[ne, "cmd"] = P[2] + E[ne, "cx"] = A[1] + E[ne, "cy"] = A[2] + E[ne, "file"] = P[4] + ne++ + next +} + +#ElementLine [-11811 -13006 -11811 -11250 3937] +/^[ \t]*ElementLine *[[]/ { + sub("ElementLine *[[]", "", $0) + bump(ne-1, $1, $2) + bump(ne-1, $3, $4) + next +} + +#ElementArc [-11811 -13006 -11811 -11250 3937] +/^[ \t]*ElementArc *[[]/ { + sub("ElementArc *[[]", "", $0) + x = $1 + y = $2 + rx = $3 + ry = $4 + bump(ne-1, x-rx, y-ry) + bump(ne-1, x+rx, y+ry) + next +} + +#Via[260000 120000 7874 4000 0 3150 "" ""] +/^[ \t]*Via *[[]/ { + sub("Via *[[]", "", $0) + pcb_sx = $1 + pcb_sy = $2 + next +} + + +END { + scale_x = png_sx/pcb_sx + scale_y = png_sy/pcb_sy + print "" + print "" + print "" + for(n = 0; n < ne; n++) { +# print E[n, "minx"], E[n, "maxx"], E[n, "miny"], E[n, "maxy"] + x1 = int((E[n, "minx"] + E[n, "cx"]) * scale_x) + x2 = int((E[n, "maxx"] + E[n, "cx"]) * scale_x) + y1 = int((E[n, "miny"] + E[n, "cy"]) * scale_y) + y2 = int((E[n, "maxy"] + E[n, "cy"]) * scale_y) + if (x1 < 0) + x1 = 0 + if (y1 < 0) + y1 = 0 + if (x1 > x2) { + tmp = x1 + x1 = x2 + x2 = tmp + } + if (y1 > y2) { + tmp = y1 + y1 = y2 + y2 = tmp + } + x1 -= 5 + y1 -= 5 + x2 += 5 + y2 += 5 +# print n, x1, y1, x2, y2, E[n, "cmd"] + cmd = E[n, "cmd"] + if (cmd ~ "^[^ ]*[(]") + url="http://igor2.repo.hu/cgi-bin/pcblib-param.cgi?cmd=" cmd + else + url="http://igor2.repo.hu/cgi-bin/pcblib-static.cgi?fp=" E[n, "file"] + gsub(" ", "+", url) + print " q E[n, " + } + print "" + print "" +} + +' < $pcb > $html + + Property changes on: tags/2.3.0/util/pcblib-map/imgmap_fp.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/pcblib-map/imgmap_page.sh =================================================================== --- tags/2.3.0/util/pcblib-map/imgmap_page.sh (nonexistent) +++ tags/2.3.0/util/pcblib-map/imgmap_page.sh (revision 33253) @@ -0,0 +1,131 @@ +#!/bin/sh +pcb=$1.pcb + +pcb -x png --dpi 100 --photo-mode $pcb +png=$1.png + +png_dims=`file $png | awk -F "[,]" '{ sub("x", " ", $2); print $2}'` + +awk -v "png_dims=$png_dims" -v "png_url=$png" ' +BEGIN { + q = "\"" + sub("^ *", "", png_dims) + sub(" *$", "", png_dims) + split(png_dims, A, " +") + png_sx = A[1] + png_sy = A[2] + ne = 0 + te = 0 +} + + +# Polygon("clearpoly") +# ( +# [5000 2500] [277500 2500] [277500 547500] [5000 547500] +# ) + +function bump(idx, x, y) +{ + if ((E[idx, "minx"] == "") || (x < E[idx, "minx"])) + E[idx, "minx"] = x + if ((E[idx, "maxx"] == "") || (x > E[idx, "maxx"])) + E[idx, "maxx"] = x + if ((E[idx, "miny"] == "") || (y < E[idx, "miny"])) + E[idx, "miny"] = y + if ((E[idx, "maxy"] == "") || (y > E[idx, "maxy"])) + E[idx, "maxy"] = y +} + +/^[ \t]*Polygon[(]/ { + getline + getline + gsub("[[\\]]", "", $0) + for(n = 1; n < NF; n+=2) + bump(ne, $n, $(n+1)) + ne++ + next +} + +# Text[296338 119704 0 670 "PARAMETRIC" "clearline"] +/^[ \t]*Text[[]/ { + sub("^[ \t]*Text[[]", "", $0) + T[te, "x"] = $1 + T[te, "y"] = $2 + T[te, "text"] = $5 + gsub("[\"]", "", T[te, "text"]) + te++ + next +} + +#Via[260000 120000 7874 4000 0 3150 "" ""] +/^[ \t]*Via *[[]/ { + sub("Via *[[]", "", $0) + pcb_sx = $1 + pcb_sy = $2 + next +} + + +END { + scale_x = png_sx/pcb_sx + scale_y = png_sy/pcb_sy + + print "" + print "" + print "" + for(n = 0; n < ne; n++) { + x1=(E[n, "minx"] + E[n, "cx"]) + x2=(E[n, "maxx"] + E[n, "cx"]) + y1=(E[n, "miny"] + E[n, "cy"]) + y2=(E[n, "maxy"] + E[n, "cy"]) + t = "" + + + for(i = 0; i < te; i++) { + x=T[i, "x"] + y=T[i, "y"] + if ((x>=x1) && (x<=x2) && (y>=y1) && (y<=y2)) { + t = i + break; + } + } +# print n, x1, y1, x2, y2, "|", t, T[t, "x"], T[t, "y"], T[t, "text"] > "/dev/stderr" + + x1 = int(x1 * scale_x) + x2 = int(x2 * scale_x) + y1 = int(y1 * scale_y) + y2 = int(y2 * scale_y) + if (x1 < 0) + x1 = 0 + if (y1 < 0) + y1 = 0 + if (x1 > x2) { + tmp = x1 + x1 = x2 + x2 = tmp + } + if (y1 > y2) { + tmp = y1 + y1 = y2 + y2 = tmp + } + x1 -= 5 + y1 -= 5 + x2 += 5 + y2 += 5 + if (x1 < 0) + x1 = 0 + if (y1 < 0) + y1 = 0 + url="http://igor2.repo.hu/tmp/pcblib/" tolower(T[t, "text"]) ".html" + gsub(" ", "+", url) + print " q T[t, " + T[t, "text"] = "-" + } + print "" + print "" +} + +' < $pcb > map.html + + Property changes on: tags/2.3.0/util/pcblib-map/imgmap_page.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/pcblib-map/map.pcb =================================================================== --- tags/2.3.0/util/pcblib-map/map.pcb (nonexistent) +++ tags/2.3.0/util/pcblib-map/map.pcb (revision 33253) @@ -0,0 +1,2737 @@ +# release: pcb 20110918 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 540000 1120030] + +Grid[2500.0 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Symbol[' ' 1800] +( +) +Symbol['!' 1200] +( + SymbolLine[0 4500 0 5000 800] + SymbolLine[0 1000 0 3500 800] +) +Symbol['"' 1200] +( + SymbolLine[0 1000 0 2000 800] + SymbolLine[1000 1000 1000 2000 800] +) +Symbol['#' 1200] +( + SymbolLine[0 3500 2000 3500 800] + SymbolLine[0 2500 2000 2500 800] + SymbolLine[1500 2000 1500 4000 800] + SymbolLine[500 2000 500 4000 800] +) +Symbol['$' 1200] +( + SymbolLine[1500 1500 2000 2000 800] + SymbolLine[500 1500 1500 1500 800] + SymbolLine[0 2000 500 1500 800] + SymbolLine[0 2000 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4000 800] + SymbolLine[1500 4500 2000 4000 800] + SymbolLine[500 4500 1500 4500 800] + SymbolLine[0 4000 500 4500 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['%' 1200] +( + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[1000 2500 1500 2000 800] + SymbolLine[500 2500 1000 2500 800] + SymbolLine[0 2000 500 2500 800] + SymbolLine[0 5000 4000 1000 800] + SymbolLine[3500 5000 4000 4500 800] + SymbolLine[4000 4000 4000 4500 800] + SymbolLine[3500 3500 4000 4000 800] + SymbolLine[3000 3500 3500 3500 800] + SymbolLine[2500 4000 3000 3500 800] + SymbolLine[2500 4000 2500 4500 800] + SymbolLine[2500 4500 3000 5000 800] + SymbolLine[3000 5000 3500 5000 800] +) +Symbol['&' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 3500 1500 2000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[0 2500 2500 5000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[0 3500 0 4500 800] +) +Symbol[''' 1200] +( + SymbolLine[0 2000 1000 1000 800] +) +Symbol['(' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] +) +Symbol[')' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['*' 1200] +( + SymbolLine[0 2000 2000 4000 800] + SymbolLine[0 4000 2000 2000 800] + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol['+' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol[',' 1200] +( + SymbolLine[0 6000 1000 5000 800] +) +Symbol['-' 1200] +( + SymbolLine[0 3000 2000 3000 800] +) +Symbol['.' 1200] +( + SymbolLine[0 5000 500 5000 800] +) +Symbol['/' 1200] +( + SymbolLine[0 4500 3000 1500 800] +) +Symbol['0' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4000 2000 2000 800] +) +Symbol['1' 1200] +( + SymbolLine[0 1800 800 1000 800] + SymbolLine[800 1000 800 5000 800] + SymbolLine[0 5000 1500 5000 800] +) +Symbol['2' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[0 5000 2500 2500 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['3' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 2800 1500 2800 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[2000 3300 2000 4500 800] + SymbolLine[2000 3300 1500 2800 800] + SymbolLine[2000 2300 1500 2800 800] +) +Symbol['4' 1200] +( + SymbolLine[0 3500 2000 1000 800] + SymbolLine[0 3500 2500 3500 800] + SymbolLine[2000 1000 2000 5000 800] +) +Symbol['5' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[500 2500 1500 2500 800] + SymbolLine[1500 2500 2000 3000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['6' 1200] +( + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1500 2800 2000 3300 800] + SymbolLine[0 2800 1500 2800 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3300 2000 4500 800] +) +Symbol['7' 1200] +( + SymbolLine[500 5000 2500 1000 800] + SymbolLine[0 1000 2500 1000 800] +) +Symbol['8' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3700 0 4500 800] + SymbolLine[0 3700 700 3000 800] + SymbolLine[700 3000 1300 3000 800] + SymbolLine[1300 3000 2000 3700 800] + SymbolLine[2000 3700 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 2300 700 3000 800] + SymbolLine[0 1500 0 2300 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[1300 3000 2000 2300 800] +) +Symbol['9' 1200] +( + SymbolLine[500 5000 2000 3000 800] + SymbolLine[2000 1500 2000 3000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol[':' 1200] +( + SymbolLine[0 2500 500 2500 800] + SymbolLine[0 3500 500 3500 800] +) +Symbol[';' 1200] +( + SymbolLine[0 5000 1000 4000 800] + SymbolLine[1000 2500 1000 3000 800] +) +Symbol['<' 1200] +( + SymbolLine[0 3000 1000 2000 800] + SymbolLine[0 3000 1000 4000 800] +) +Symbol['=' 1200] +( + SymbolLine[0 2500 2000 2500 800] + SymbolLine[0 3500 2000 3500 800] +) +Symbol['>' 1200] +( + SymbolLine[0 2000 1000 3000 800] + SymbolLine[0 4000 1000 3000 800] +) +Symbol['?' 1200] +( + SymbolLine[1000 3000 1000 3500 800] + SymbolLine[1000 4500 1000 5000 800] + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2000 800] + SymbolLine[1000 3000 2000 2000 800] +) +Symbol['@' 1200] +( + SymbolLine[0 1000 0 4000 800] + SymbolLine[0 4000 1000 5000 800] + SymbolLine[1000 5000 4000 5000 800] + SymbolLine[5000 3500 5000 1000 800] + SymbolLine[5000 1000 4000 0 800] + SymbolLine[4000 0 1000 0 800] + SymbolLine[1000 0 0 1000 800] + SymbolLine[1500 2000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 3000 3500 800] + SymbolLine[3000 3500 3500 3000 800] + SymbolLine[3500 3000 4000 3500 800] + SymbolLine[3500 3000 3500 1500 800] + SymbolLine[3500 2000 3000 1500 800] + SymbolLine[2000 1500 3000 1500 800] + SymbolLine[2000 1500 1500 2000 800] + SymbolLine[4000 3500 5000 3500 800] +) +Symbol['A' 1200] +( + SymbolLine[0 2000 0 5000 800] + SymbolLine[0 2000 700 1000 800] + SymbolLine[700 1000 1800 1000 800] + SymbolLine[1800 1000 2500 2000 800] + SymbolLine[2500 2000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['B' 1200] +( + SymbolLine[0 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3300 2500 4500 800] + SymbolLine[2000 2800 2500 3300 800] + SymbolLine[500 2800 2000 2800 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2300 800] + SymbolLine[2000 2800 2500 2300 800] +) +Symbol['C' 1200] +( + SymbolLine[700 5000 2000 5000 800] + SymbolLine[0 4300 700 5000 800] + SymbolLine[0 1700 0 4300 800] + SymbolLine[0 1700 700 1000 800] + SymbolLine[700 1000 2000 1000 800] +) +Symbol['D' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[1800 1000 2500 1700 800] + SymbolLine[2500 1700 2500 4300 800] + SymbolLine[1800 5000 2500 4300 800] + SymbolLine[0 5000 1800 5000 800] + SymbolLine[0 1000 1800 1000 800] +) +Symbol['E' 1200] +( + SymbolLine[0 2800 1500 2800 800] + SymbolLine[0 5000 2000 5000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] +) +Symbol['F' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 2800 1500 2800 800] +) +Symbol['G' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[1000 3000 2000 3000 800] +) +Symbol['H' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[2500 1000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['I' 1200] +( + SymbolLine[0 1000 1000 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 1000 5000 800] +) +Symbol['J' 1200] +( + SymbolLine[700 1000 1500 1000 800] + SymbolLine[1500 1000 1500 4500 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 4500 0 4000 800] +) +Symbol['K' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3000 2000 1000 800] + SymbolLine[0 3000 2000 5000 800] +) +Symbol['L' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['M' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 1500 3000 800] + SymbolLine[1500 3000 3000 1000 800] + SymbolLine[3000 1000 3000 5000 800] +) +Symbol['N' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2500 5000 800] + SymbolLine[2500 1000 2500 5000 800] +) +Symbol['O' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['P' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol['Q' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1000 3500 2000 5000 800] +) +Symbol['R' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[1300 3000 2500 5000 800] +) +Symbol['S' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['T' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['U' 1200] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 1000 2000 4500 800] +) +Symbol['V' 1200] +( + SymbolLine[0 1000 1000 5000 800] + SymbolLine[1000 5000 2000 1000 800] +) +Symbol['W' 1200] +( + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 5000 800] + SymbolLine[500 5000 1500 3000 800] + SymbolLine[1500 3000 2500 5000 800] + SymbolLine[2500 5000 3000 3000 800] + SymbolLine[3000 3000 3000 1000 800] +) +Symbol['X' 1200] +( + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 1000 2500 5000 800] +) +Symbol['Y' 1200] +( + SymbolLine[0 1000 1000 3000 800] + SymbolLine[1000 3000 2000 1000 800] + SymbolLine[1000 3000 1000 5000 800] +) +Symbol['Z' 1200] +( + SymbolLine[0 1000 2500 1000 800] + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['[' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['\' 1200] +( + SymbolLine[0 1500 3000 4500 800] +) +Symbol[']' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['^' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1500 800] +) +Symbol['_' 1200] +( + SymbolLine[0 5000 2000 5000 800] +) +Symbol['a' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[2000 4500 2500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['b' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] +) +Symbol['c' 1200] +( + SymbolLine[500 3000 2000 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] +) +Symbol['d' 1200] +( + SymbolLine[2000 1000 2000 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] +) +Symbol['e' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[0 4000 2000 4000 800] + SymbolLine[2000 4000 2000 3500 800] +) +Symbol['f' 1000] +( + SymbolLine[500 1500 500 5000 800] + SymbolLine[500 1500 1000 1000 800] + SymbolLine[1000 1000 1500 1000 800] + SymbolLine[0 3000 1000 3000 800] +) +Symbol['g' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[2000 3000 2000 6000 800] +) +Symbol['h' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] +) +Symbol['i' 1000] +( + SymbolLine[0 2000 0 2100 1000] + SymbolLine[0 3500 0 5000 800] +) +Symbol['j' 1000] +( + SymbolLine[500 2000 500 2100 1000] + SymbolLine[500 3500 500 6000 800] + SymbolLine[0 6500 500 6000 800] +) +Symbol['k' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 1500 5000 800] + SymbolLine[0 3500 1000 2500 800] +) +Symbol['l' 1000] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['m' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[2000 3500 2500 3000 800] + SymbolLine[2500 3000 3000 3000 800] + SymbolLine[3000 3000 3500 3500 800] + SymbolLine[3500 3500 3500 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['n' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['o' 1200] +( + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['p' 1200] +( + SymbolLine[500 3500 500 6500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[1000 5000 2000 5000 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['q' 1200] +( + SymbolLine[2000 3500 2000 6500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['r' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['s' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2000 4000 2500 4500 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['t' 1000] +( + SymbolLine[500 1000 500 4500 800] + SymbolLine[500 4500 1000 5000 800] + SymbolLine[0 2500 1000 2500 800] +) +Symbol['u' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3000 2000 4500 800] +) +Symbol['v' 1200] +( + SymbolLine[0 3000 1000 5000 800] + SymbolLine[2000 3000 1000 5000 800] +) +Symbol['w' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[1500 3000 1500 4500 800] + SymbolLine[1500 4500 2000 5000 800] + SymbolLine[2000 5000 2500 5000 800] + SymbolLine[2500 5000 3000 4500 800] + SymbolLine[3000 3000 3000 4500 800] +) +Symbol['x' 1200] +( + SymbolLine[0 3000 2000 5000 800] + SymbolLine[0 5000 2000 3000 800] +) +Symbol['y' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 6000 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['z' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[0 5000 2000 3000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['{' 1200] +( + SymbolLine[500 1500 1000 1000 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['|' 1200] +( + SymbolLine[0 1000 0 5000 800] +) +Symbol['}' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[500 2500 1000 3000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['~' 1200] +( + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1000 3000 800] + SymbolLine[1000 3000 1500 3500 800] + SymbolLine[1500 3500 2000 3500 800] + SymbolLine[2000 3500 2500 3000 800] +) +Attribute("PCB::grid::unit" "mil") +Via[540000 1120000 7874 4000 0 3150 "" ""] + +Element["" "DSUB connector, female/male" "" "DB15F" 30000 50000 5600 0 3 150 ""] +( + Pin[0 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[0 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[0 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[0 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[0 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[0 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[0 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[0 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[11200 5400 6000 3000 6600 3500 "9" "9" ""] + Pin[11200 16200 6000 3000 6600 3500 "10" "10" ""] + Pin[11200 27000 6000 3000 6600 3500 "11" "11" ""] + Pin[11200 37800 6000 3000 6600 3500 "12" "12" ""] + Pin[11200 48600 6000 3000 6600 3500 "13" "13" ""] + Pin[11200 59400 6000 3000 6600 3500 "14" "14" ""] + Pin[11200 70200 6000 3000 6600 3500 "15" "15" ""] + Pin[5600 102600 25000 3000 25600 12500 "C1" "16" ""] + Pin[5600 -27000 25000 3000 25600 12500 "C2" "17" ""] + ElementLine [39100 114600 42100 114600 1000] + ElementLine [39100 -39000 39100 114600 1000] + ElementLine [39100 -39000 42100 -39000 1000] + ElementLine [42100 -39000 42100 114600 1000] + ElementLine [39100 108600 42100 108600 1000] + ElementLine [39100 96600 42100 96600 1000] + ElementLine [39100 -33000 42100 -33000 1000] + ElementLine [39100 -21000 42100 -21000 1000] + ElementLine [28600 91600 39100 91600 2000] + ElementLine [28600 -16000 28600 91600 2000] + ElementLine [28600 -16000 39100 -16000 2000] + ElementLine [39100 -16000 39100 91600 1000] + ElementLine [4000 0 28600 0 2000] + ElementLine [4000 10800 28600 10800 2000] + ElementLine [4000 21600 28600 21600 2000] + ElementLine [4000 32400 28600 32400 2000] + ElementLine [4000 43200 28600 43200 2000] + ElementLine [4000 54000 28600 54000 2000] + ElementLine [4000 64800 28600 64800 2000] + ElementLine [4000 75600 28600 75600 2000] + ElementLine [15200 5400 28600 5400 2000] + ElementLine [15200 16200 28600 16200 2000] + ElementLine [15200 27000 28600 27000 2000] + ElementLine [15200 37800 28600 37800 2000] + ElementLine [15200 48600 28600 48600 2000] + ElementLine [15200 59400 28600 59400 2000] + ElementLine [15200 70200 28600 70200 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB15M" 120000 50000 -5000 75600 1 150 ""] +( + Pin[600 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[600 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[600 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[600 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[600 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[600 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[600 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[600 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[-10600 5400 6000 3000 6600 3500 "9" "9" ""] + Pin[-10600 16200 6000 3000 6600 3500 "10" "10" ""] + Pin[-10600 27000 6000 3000 6600 3500 "11" "11" ""] + Pin[-10600 37800 6000 3000 6600 3500 "12" "12" ""] + Pin[-10600 48600 6000 3000 6600 3500 "13" "13" ""] + Pin[-10600 59400 6000 3000 6600 3500 "14" "14" ""] + Pin[-10600 70200 6000 3000 6600 3500 "15" "15" ""] + Pin[-5000 -27000 25000 3000 25600 12500 "C1" "16" ""] + Pin[-5000 102600 25000 3000 25600 12500 "C2" "17" ""] + ElementLine [-41500 -39000 -38500 -39000 1000] + ElementLine [-38500 -39000 -38500 114600 1000] + ElementLine [-38500 114600 -41500 114600 1000] + ElementLine [-41500 114600 -41500 -39000 1000] + ElementLine [-41500 -33000 -38500 -33000 1000] + ElementLine [-41500 -21000 -38500 -21000 1000] + ElementLine [-41500 108600 -38500 108600 1000] + ElementLine [-41500 96600 -38500 96600 1000] + ElementLine [-38500 -16000 -28000 -16000 2000] + ElementLine [-28000 -16000 -28000 91600 2000] + ElementLine [-28000 91600 -38500 91600 2000] + ElementLine [-38500 91600 -38500 -16000 1000] + ElementLine [-3400 0 -28000 0 2000] + ElementLine [-3400 10800 -28000 10800 2000] + ElementLine [-3400 21600 -28000 21600 2000] + ElementLine [-3400 32400 -28000 32400 2000] + ElementLine [-3400 43200 -28000 43200 2000] + ElementLine [-3400 54000 -28000 54000 2000] + ElementLine [-3400 64800 -28000 64800 2000] + ElementLine [-3400 75600 -28000 75600 2000] + ElementLine [-14600 5400 -28000 5400 2000] + ElementLine [-14600 16200 -28000 16200 2000] + ElementLine [-14600 27000 -28000 27000 2000] + ElementLine [-14600 37800 -28000 37800 2000] + ElementLine [-14600 48600 -28000 48600 2000] + ElementLine [-14600 59400 -28000 59400 2000] + ElementLine [-14600 70200 -28000 70200 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB25F" 170000 50000 5600 0 3 150 ""] +( + Pin[0 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[0 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[0 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[0 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[0 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[0 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[0 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[0 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[0 86400 6000 3000 6600 3500 "9" "9" ""] + Pin[0 97200 6000 3000 6600 3500 "10" "10" ""] + Pin[0 108000 6000 3000 6600 3500 "11" "11" ""] + Pin[0 118800 6000 3000 6600 3500 "12" "12" ""] + Pin[0 129600 6000 3000 6600 3500 "13" "13" ""] + Pin[11200 5400 6000 3000 6600 3500 "14" "14" ""] + Pin[11200 16200 6000 3000 6600 3500 "15" "15" ""] + Pin[11200 27000 6000 3000 6600 3500 "16" "16" ""] + Pin[11200 37800 6000 3000 6600 3500 "17" "17" ""] + Pin[11200 48600 6000 3000 6600 3500 "18" "18" ""] + Pin[11200 59400 6000 3000 6600 3500 "19" "19" ""] + Pin[11200 70200 6000 3000 6600 3500 "20" "20" ""] + Pin[11200 81000 6000 3000 6600 3500 "21" "21" ""] + Pin[11200 91800 6000 3000 6600 3500 "22" "22" ""] + Pin[11200 102600 6000 3000 6600 3500 "23" "23" ""] + Pin[11200 113400 6000 3000 6600 3500 "24" "24" ""] + Pin[11200 124200 6000 3000 6600 3500 "25" "25" ""] + Pin[5600 156600 25000 3000 25600 12500 "C1" "26" ""] + Pin[5600 -27000 25000 3000 25600 12500 "C2" "27" ""] + ElementLine [39100 168600 42100 168600 1000] + ElementLine [39100 -39000 39100 168600 1000] + ElementLine [39100 -39000 42100 -39000 1000] + ElementLine [42100 -39000 42100 168600 1000] + ElementLine [39100 162600 42100 162600 1000] + ElementLine [39100 150600 42100 150600 1000] + ElementLine [39100 -33000 42100 -33000 1000] + ElementLine [39100 -21000 42100 -21000 1000] + ElementLine [28600 145600 39100 145600 2000] + ElementLine [28600 -16000 28600 145600 2000] + ElementLine [28600 -16000 39100 -16000 2000] + ElementLine [39100 -16000 39100 145600 1000] + ElementLine [4000 0 28600 0 2000] + ElementLine [4000 10800 28600 10800 2000] + ElementLine [4000 21600 28600 21600 2000] + ElementLine [4000 32400 28600 32400 2000] + ElementLine [4000 43200 28600 43200 2000] + ElementLine [4000 54000 28600 54000 2000] + ElementLine [4000 64800 28600 64800 2000] + ElementLine [4000 75600 28600 75600 2000] + ElementLine [4000 86400 28600 86400 2000] + ElementLine [4000 97200 28600 97200 2000] + ElementLine [4000 108000 28600 108000 2000] + ElementLine [4000 118800 28600 118800 2000] + ElementLine [4000 129600 28600 129600 2000] + ElementLine [15200 5400 28600 5400 2000] + ElementLine [15200 16200 28600 16200 2000] + ElementLine [15200 27000 28600 27000 2000] + ElementLine [15200 37800 28600 37800 2000] + ElementLine [15200 48600 28600 48600 2000] + ElementLine [15200 59400 28600 59400 2000] + ElementLine [15200 70200 28600 70200 2000] + ElementLine [15200 81000 28600 81000 2000] + ElementLine [15200 91800 28600 91800 2000] + ElementLine [15200 102600 28600 102600 2000] + ElementLine [15200 113400 28600 113400 2000] + ElementLine [15200 124200 28600 124200 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB25M" 260000 50000 -5000 129600 1 150 ""] +( + Pin[600 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[600 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[600 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[600 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[600 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[600 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[600 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[600 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[600 86400 6000 3000 6600 3500 "9" "9" ""] + Pin[600 97200 6000 3000 6600 3500 "10" "10" ""] + Pin[600 108000 6000 3000 6600 3500 "11" "11" ""] + Pin[600 118800 6000 3000 6600 3500 "12" "12" ""] + Pin[600 129600 6000 3000 6600 3500 "13" "13" ""] + Pin[-10600 5400 6000 3000 6600 3500 "14" "14" ""] + Pin[-10600 16200 6000 3000 6600 3500 "15" "15" ""] + Pin[-10600 27000 6000 3000 6600 3500 "16" "16" ""] + Pin[-10600 37800 6000 3000 6600 3500 "17" "17" ""] + Pin[-10600 48600 6000 3000 6600 3500 "18" "18" ""] + Pin[-10600 59400 6000 3000 6600 3500 "19" "19" ""] + Pin[-10600 70200 6000 3000 6600 3500 "20" "20" ""] + Pin[-10600 81000 6000 3000 6600 3500 "21" "21" ""] + Pin[-10600 91800 6000 3000 6600 3500 "22" "22" ""] + Pin[-10600 102600 6000 3000 6600 3500 "23" "23" ""] + Pin[-10600 113400 6000 3000 6600 3500 "24" "24" ""] + Pin[-10600 124200 6000 3000 6600 3500 "25" "25" ""] + Pin[-5000 -27000 25000 3000 25600 12500 "C1" "26" ""] + Pin[-5000 156600 25000 3000 25600 12500 "C2" "27" ""] + ElementLine [-41500 -39000 -38500 -39000 1000] + ElementLine [-38500 -39000 -38500 168600 1000] + ElementLine [-38500 168600 -41500 168600 1000] + ElementLine [-41500 168600 -41500 -39000 1000] + ElementLine [-41500 -33000 -38500 -33000 1000] + ElementLine [-41500 -21000 -38500 -21000 1000] + ElementLine [-41500 162600 -38500 162600 1000] + ElementLine [-41500 150600 -38500 150600 1000] + ElementLine [-38500 -16000 -28000 -16000 2000] + ElementLine [-28000 -16000 -28000 145600 2000] + ElementLine [-28000 145600 -38500 145600 2000] + ElementLine [-38500 145600 -38500 -16000 1000] + ElementLine [-3400 0 -28000 0 2000] + ElementLine [-3400 10800 -28000 10800 2000] + ElementLine [-3400 21600 -28000 21600 2000] + ElementLine [-3400 32400 -28000 32400 2000] + ElementLine [-3400 43200 -28000 43200 2000] + ElementLine [-3400 54000 -28000 54000 2000] + ElementLine [-3400 64800 -28000 64800 2000] + ElementLine [-3400 75600 -28000 75600 2000] + ElementLine [-3400 86400 -28000 86400 2000] + ElementLine [-3400 97200 -28000 97200 2000] + ElementLine [-3400 108000 -28000 108000 2000] + ElementLine [-3400 118800 -28000 118800 2000] + ElementLine [-3400 129600 -28000 129600 2000] + ElementLine [-14600 5400 -28000 5400 2000] + ElementLine [-14600 16200 -28000 16200 2000] + ElementLine [-14600 27000 -28000 27000 2000] + ElementLine [-14600 37800 -28000 37800 2000] + ElementLine [-14600 48600 -28000 48600 2000] + ElementLine [-14600 59400 -28000 59400 2000] + ElementLine [-14600 70200 -28000 70200 2000] + ElementLine [-14600 81000 -28000 81000 2000] + ElementLine [-14600 91800 -28000 91800 2000] + ElementLine [-14600 102600 -28000 102600 2000] + ElementLine [-14600 113400 -28000 113400 2000] + ElementLine [-14600 124200 -28000 124200 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB37F" 30000 260000 5600 0 3 150 ""] +( + Pin[0 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[0 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[0 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[0 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[0 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[0 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[0 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[0 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[0 86400 6000 3000 6600 3500 "9" "9" ""] + Pin[0 97200 6000 3000 6600 3500 "10" "10" ""] + Pin[0 108000 6000 3000 6600 3500 "11" "11" ""] + Pin[0 118800 6000 3000 6600 3500 "12" "12" ""] + Pin[0 129600 6000 3000 6600 3500 "13" "13" ""] + Pin[0 140400 6000 3000 6600 3500 "14" "14" ""] + Pin[0 151200 6000 3000 6600 3500 "15" "15" ""] + Pin[0 162000 6000 3000 6600 3500 "16" "16" ""] + Pin[0 172800 6000 3000 6600 3500 "17" "17" ""] + Pin[0 183600 6000 3000 6600 3500 "18" "18" ""] + Pin[0 194400 6000 3000 6600 3500 "19" "19" ""] + Pin[11200 5400 6000 3000 6600 3500 "20" "20" ""] + Pin[11200 16200 6000 3000 6600 3500 "21" "21" ""] + Pin[11200 27000 6000 3000 6600 3500 "22" "22" ""] + Pin[11200 37800 6000 3000 6600 3500 "23" "23" ""] + Pin[11200 48600 6000 3000 6600 3500 "24" "24" ""] + Pin[11200 59400 6000 3000 6600 3500 "25" "25" ""] + Pin[11200 70200 6000 3000 6600 3500 "26" "26" ""] + Pin[11200 81000 6000 3000 6600 3500 "27" "27" ""] + Pin[11200 91800 6000 3000 6600 3500 "28" "28" ""] + Pin[11200 102600 6000 3000 6600 3500 "29" "29" ""] + Pin[11200 113400 6000 3000 6600 3500 "30" "30" ""] + Pin[11200 124200 6000 3000 6600 3500 "31" "31" ""] + Pin[11200 135000 6000 3000 6600 3500 "32" "32" ""] + Pin[11200 145800 6000 3000 6600 3500 "33" "33" ""] + Pin[11200 156600 6000 3000 6600 3500 "34" "34" ""] + Pin[11200 167400 6000 3000 6600 3500 "35" "35" ""] + Pin[11200 178200 6000 3000 6600 3500 "36" "36" ""] + Pin[11200 189000 6000 3000 6600 3500 "37" "37" ""] + Pin[5600 221400 25000 3000 25600 12500 "C1" "38" ""] + Pin[5600 -27000 25000 3000 25600 12500 "C2" "39" ""] + ElementLine [39100 233400 42100 233400 1000] + ElementLine [39100 -39000 39100 233400 1000] + ElementLine [39100 -39000 42100 -39000 1000] + ElementLine [42100 -39000 42100 233400 1000] + ElementLine [39100 227400 42100 227400 1000] + ElementLine [39100 215400 42100 215400 1000] + ElementLine [39100 -33000 42100 -33000 1000] + ElementLine [39100 -21000 42100 -21000 1000] + ElementLine [28600 210400 39100 210400 2000] + ElementLine [28600 -16000 28600 210400 2000] + ElementLine [28600 -16000 39100 -16000 2000] + ElementLine [39100 -16000 39100 210400 1000] + ElementLine [4000 0 28600 0 2000] + ElementLine [4000 10800 28600 10800 2000] + ElementLine [4000 21600 28600 21600 2000] + ElementLine [4000 32400 28600 32400 2000] + ElementLine [4000 43200 28600 43200 2000] + ElementLine [4000 54000 28600 54000 2000] + ElementLine [4000 64800 28600 64800 2000] + ElementLine [4000 75600 28600 75600 2000] + ElementLine [4000 86400 28600 86400 2000] + ElementLine [4000 97200 28600 97200 2000] + ElementLine [4000 108000 28600 108000 2000] + ElementLine [4000 118800 28600 118800 2000] + ElementLine [4000 129600 28600 129600 2000] + ElementLine [4000 140400 28600 140400 2000] + ElementLine [4000 151200 28600 151200 2000] + ElementLine [4000 162000 28600 162000 2000] + ElementLine [4000 172800 28600 172800 2000] + ElementLine [4000 183600 28600 183600 2000] + ElementLine [4000 194400 28600 194400 2000] + ElementLine [15200 5400 28600 5400 2000] + ElementLine [15200 16200 28600 16200 2000] + ElementLine [15200 27000 28600 27000 2000] + ElementLine [15200 37800 28600 37800 2000] + ElementLine [15200 48600 28600 48600 2000] + ElementLine [15200 59400 28600 59400 2000] + ElementLine [15200 70200 28600 70200 2000] + ElementLine [15200 81000 28600 81000 2000] + ElementLine [15200 91800 28600 91800 2000] + ElementLine [15200 102600 28600 102600 2000] + ElementLine [15200 113400 28600 113400 2000] + ElementLine [15200 124200 28600 124200 2000] + ElementLine [15200 135000 28600 135000 2000] + ElementLine [15200 145800 28600 145800 2000] + ElementLine [15200 156600 28600 156600 2000] + ElementLine [15200 167400 28600 167400 2000] + ElementLine [15200 178200 28600 178200 2000] + ElementLine [15200 189000 28600 189000 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB37M" 120000 260000 -5000 194400 1 150 ""] +( + Pin[600 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[600 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[600 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[600 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[600 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[600 54000 6000 3000 6600 3500 "6" "6" ""] + Pin[600 64800 6000 3000 6600 3500 "7" "7" ""] + Pin[600 75600 6000 3000 6600 3500 "8" "8" ""] + Pin[600 86400 6000 3000 6600 3500 "9" "9" ""] + Pin[600 97200 6000 3000 6600 3500 "10" "10" ""] + Pin[600 108000 6000 3000 6600 3500 "11" "11" ""] + Pin[600 118800 6000 3000 6600 3500 "12" "12" ""] + Pin[600 129600 6000 3000 6600 3500 "13" "13" ""] + Pin[600 140400 6000 3000 6600 3500 "14" "14" ""] + Pin[600 151200 6000 3000 6600 3500 "15" "15" ""] + Pin[600 162000 6000 3000 6600 3500 "16" "16" ""] + Pin[600 172800 6000 3000 6600 3500 "17" "17" ""] + Pin[600 183600 6000 3000 6600 3500 "18" "18" ""] + Pin[600 194400 6000 3000 6600 3500 "19" "19" ""] + Pin[-10600 5400 6000 3000 6600 3500 "20" "20" ""] + Pin[-10600 16200 6000 3000 6600 3500 "21" "21" ""] + Pin[-10600 27000 6000 3000 6600 3500 "22" "22" ""] + Pin[-10600 37800 6000 3000 6600 3500 "23" "23" ""] + Pin[-10600 48600 6000 3000 6600 3500 "24" "24" ""] + Pin[-10600 59400 6000 3000 6600 3500 "25" "25" ""] + Pin[-10600 70200 6000 3000 6600 3500 "26" "26" ""] + Pin[-10600 81000 6000 3000 6600 3500 "27" "27" ""] + Pin[-10600 91800 6000 3000 6600 3500 "28" "28" ""] + Pin[-10600 102600 6000 3000 6600 3500 "29" "29" ""] + Pin[-10600 113400 6000 3000 6600 3500 "30" "30" ""] + Pin[-10600 124200 6000 3000 6600 3500 "31" "31" ""] + Pin[-10600 135000 6000 3000 6600 3500 "32" "32" ""] + Pin[-10600 145800 6000 3000 6600 3500 "33" "33" ""] + Pin[-10600 156600 6000 3000 6600 3500 "34" "34" ""] + Pin[-10600 167400 6000 3000 6600 3500 "35" "35" ""] + Pin[-10600 178200 6000 3000 6600 3500 "36" "36" ""] + Pin[-10600 189000 6000 3000 6600 3500 "37" "37" ""] + Pin[-5000 -27000 25000 3000 25600 12500 "C1" "38" ""] + Pin[-5000 221400 25000 3000 25600 12500 "C2" "39" ""] + ElementLine [-41500 -39000 -38500 -39000 1000] + ElementLine [-38500 -39000 -38500 233400 1000] + ElementLine [-38500 233400 -41500 233400 1000] + ElementLine [-41500 233400 -41500 -39000 1000] + ElementLine [-41500 -33000 -38500 -33000 1000] + ElementLine [-41500 -21000 -38500 -21000 1000] + ElementLine [-41500 227400 -38500 227400 1000] + ElementLine [-41500 215400 -38500 215400 1000] + ElementLine [-38500 -16000 -28000 -16000 2000] + ElementLine [-28000 -16000 -28000 210400 2000] + ElementLine [-28000 210400 -38500 210400 2000] + ElementLine [-38500 210400 -38500 -16000 1000] + ElementLine [-3400 0 -28000 0 2000] + ElementLine [-3400 10800 -28000 10800 2000] + ElementLine [-3400 21600 -28000 21600 2000] + ElementLine [-3400 32400 -28000 32400 2000] + ElementLine [-3400 43200 -28000 43200 2000] + ElementLine [-3400 54000 -28000 54000 2000] + ElementLine [-3400 64800 -28000 64800 2000] + ElementLine [-3400 75600 -28000 75600 2000] + ElementLine [-3400 86400 -28000 86400 2000] + ElementLine [-3400 97200 -28000 97200 2000] + ElementLine [-3400 108000 -28000 108000 2000] + ElementLine [-3400 118800 -28000 118800 2000] + ElementLine [-3400 129600 -28000 129600 2000] + ElementLine [-3400 140400 -28000 140400 2000] + ElementLine [-3400 151200 -28000 151200 2000] + ElementLine [-3400 162000 -28000 162000 2000] + ElementLine [-3400 172800 -28000 172800 2000] + ElementLine [-3400 183600 -28000 183600 2000] + ElementLine [-3400 194400 -28000 194400 2000] + ElementLine [-14600 5400 -28000 5400 2000] + ElementLine [-14600 16200 -28000 16200 2000] + ElementLine [-14600 27000 -28000 27000 2000] + ElementLine [-14600 37800 -28000 37800 2000] + ElementLine [-14600 48600 -28000 48600 2000] + ElementLine [-14600 59400 -28000 59400 2000] + ElementLine [-14600 70200 -28000 70200 2000] + ElementLine [-14600 81000 -28000 81000 2000] + ElementLine [-14600 91800 -28000 91800 2000] + ElementLine [-14600 102600 -28000 102600 2000] + ElementLine [-14600 113400 -28000 113400 2000] + ElementLine [-14600 124200 -28000 124200 2000] + ElementLine [-14600 135000 -28000 135000 2000] + ElementLine [-14600 145800 -28000 145800 2000] + ElementLine [-14600 156600 -28000 156600 2000] + ElementLine [-14600 167400 -28000 167400 2000] + ElementLine [-14600 178200 -28000 178200 2000] + ElementLine [-14600 189000 -28000 189000 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB9F" 170000 290000 5600 0 3 150 ""] +( + Pin[0 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[0 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[0 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[0 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[0 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[11200 5400 6000 3000 6600 3500 "6" "6" ""] + Pin[11200 16200 6000 3000 6600 3500 "7" "7" ""] + Pin[11200 27000 6000 3000 6600 3500 "8" "8" ""] + Pin[11200 37800 6000 3000 6600 3500 "9" "9" ""] + Pin[5600 70200 25000 3000 25600 12500 "C1" "10" ""] + Pin[5600 -27000 25000 3000 25600 12500 "C2" "11" ""] + ElementLine [39100 82200 42100 82200 1000] + ElementLine [39100 -39000 39100 82200 1000] + ElementLine [39100 -39000 42100 -39000 1000] + ElementLine [42100 -39000 42100 82200 1000] + ElementLine [39100 76200 42100 76200 1000] + ElementLine [39100 64200 42100 64200 1000] + ElementLine [39100 -33000 42100 -33000 1000] + ElementLine [39100 -21000 42100 -21000 1000] + ElementLine [28600 59200 39100 59200 2000] + ElementLine [28600 -16000 28600 59200 2000] + ElementLine [28600 -16000 39100 -16000 2000] + ElementLine [39100 -16000 39100 59200 1000] + ElementLine [4000 0 28600 0 2000] + ElementLine [4000 10800 28600 10800 2000] + ElementLine [4000 21600 28600 21600 2000] + ElementLine [4000 32400 28600 32400 2000] + ElementLine [4000 43200 28600 43200 2000] + ElementLine [15200 5400 28600 5400 2000] + ElementLine [15200 16200 28600 16200 2000] + ElementLine [15200 27000 28600 27000 2000] + ElementLine [15200 37800 28600 37800 2000] + + ) + +Element["" "DSUB connector, female/male" "" "DB9M" 260000 290000 -5000 43200 1 150 ""] +( + Pin[600 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[600 10800 6000 3000 6600 3500 "2" "2" ""] + Pin[600 21600 6000 3000 6600 3500 "3" "3" ""] + Pin[600 32400 6000 3000 6600 3500 "4" "4" ""] + Pin[600 43200 6000 3000 6600 3500 "5" "5" ""] + Pin[-10600 5400 6000 3000 6600 3500 "6" "6" ""] + Pin[-10600 16200 6000 3000 6600 3500 "7" "7" ""] + Pin[-10600 27000 6000 3000 6600 3500 "8" "8" ""] + Pin[-10600 37800 6000 3000 6600 3500 "9" "9" ""] + Pin[-5000 -27000 25000 3000 25600 12500 "C1" "10" ""] + Pin[-5000 70200 25000 3000 25600 12500 "C2" "11" ""] + ElementLine [-41500 -39000 -38500 -39000 1000] + ElementLine [-38500 -39000 -38500 82200 1000] + ElementLine [-38500 82200 -41500 82200 1000] + ElementLine [-41500 82200 -41500 -39000 1000] + ElementLine [-41500 -33000 -38500 -33000 1000] + ElementLine [-41500 -21000 -38500 -21000 1000] + ElementLine [-41500 76200 -38500 76200 1000] + ElementLine [-41500 64200 -38500 64200 1000] + ElementLine [-38500 -16000 -28000 -16000 2000] + ElementLine [-28000 -16000 -28000 59200 2000] + ElementLine [-28000 59200 -38500 59200 2000] + ElementLine [-38500 59200 -38500 -16000 1000] + ElementLine [-3400 0 -28000 0 2000] + ElementLine [-3400 10800 -28000 10800 2000] + ElementLine [-3400 21600 -28000 21600 2000] + ElementLine [-3400 32400 -28000 32400 2000] + ElementLine [-3400 43200 -28000 43200 2000] + ElementLine [-14600 5400 -28000 5400 2000] + ElementLine [-14600 16200 -28000 16200 2000] + ElementLine [-14600 27000 -28000 27000 2000] + ElementLine [-14600 37800 -28000 37800 2000] + + ) + +Element["" "right angle BNC" "" "BNC_LAY" 152500 442500 20000 0 3 100 ""] +( + Pin[0 0 6000 3000 6600 3500 "1" "1" "square"] + Pin[0 -10000 6000 3000 6600 3500 "2" "2" ""] + Pin[20000 -20000 10000 3000 10600 8100 "m1" "3" ""] + Pin[20000 20000 10000 3000 10600 8100 "m2" "4" ""] + ElementLine [-6000 -29000 49000 -29000 1000] + ElementLine [49000 -29000 49000 29000 1000] + ElementLine [49000 29000 -6000 29000 1000] + ElementLine [-6000 29000 -6000 -29000 1000] + + ) + +Element["" "rcy(150, bar-sign)" "C1" "acy150" 302500 95000 -2000 -4500 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -15000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -28500 0 -24500 1000] + ElementLine [0 9500 0 13500 1000] + ElementLine [-2000 11500 2000 11500 1000] + ElementLine [7874 -17883 7874 -11250 3937] + ElementLine [-7874 -17883 -7874 -11250 3937] + ElementLine [9842 -16040 9842 -11250 3937] + ElementLine [-9842 -16040 -9842 -11250 3937] + ElementLine [11811 -13006 11811 -11250 3937] + ElementLine [-11811 -13006 -11811 -11250 3937] + ElementArc [0 -7500 15000 15000 90 360 1000] + + ) + +Element["" "so(8)" "" "8*250" 337500 82500 -10000 0 1 100 ""] +( + Pad[-7500 7000 -7500 13500 2000 1000 3000 "" "1" "square,edge2"] + Pad[-7500 -13500 -7500 -7000 2000 1000 3000 "" "8" "square"] + Pad[-2500 7000 -2500 13500 2000 1000 3000 "" "2" "square,edge2"] + Pad[-2500 -13500 -2500 -7000 2000 1000 3000 "" "7" "square"] + Pad[2500 7000 2500 13500 2000 1000 3000 "" "3" "square,edge2"] + Pad[2500 -13500 2500 -7000 2000 1000 3000 "" "6" "square"] + Pad[7500 7000 7500 13500 2000 1000 3000 "" "4" "square,edge2"] + Pad[7500 -13500 7500 -7000 2000 1000 3000 "" "5" "square"] + ElementLine [-10000 16000 10000 16000 1000] + ElementLine [10000 -16000 10000 16000 1000] + ElementLine [-10000 -16000 10000 -16000 1000] + ElementLine [-10000 2500 -10000 16000 1000] + ElementLine [-10000 -16000 -10000 -2500 1000] + ElementArc [-10000 0 2500 2500 90 180 1000] + + ) + +Element["" "dip(4)" "" "4*300" 365000 102500 -10000 0 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "4" ""] + Pin[10000 0 8000 5000 8600 3937 "" "2" ""] + Pin[10000 -30000 8000 5000 8600 3937 "" "3" ""] + ElementLine [-5000 5000 15000 5000 1000] + ElementLine [15000 -35000 15000 5000 1000] + ElementLine [-5000 -35000 15000 -35000 1000] + ElementLine [-5000 -10000 -5000 5000 1000] + ElementLine [-5000 -35000 -5000 -20000 1000] + ElementArc [-5000 -15000 5000 5000 90 180 1000] + + ) + +Element["" "tssop(8)" "" "8*6.4mm" 397500 82500 -10000 0 1 100 ""] +( + Pad[-3838 10236 -3838 14173 1771 1000 3000 "" "1" "square,edge2"] + Pad[-3838 -14173 -3838 -10236 1771 1000 3000 "" "8" "square"] + Pad[-1278 10236 -1278 14173 1771 1000 3000 "" "2" "square,edge2"] + Pad[-1278 -14173 -1278 -10236 1771 1000 3000 "" "7" "square"] + Pad[1280 10236 1280 14173 1771 1000 3000 "" "3" "square,edge2"] + Pad[1280 -14173 1280 -10236 1771 1000 3000 "" "6" "square"] + Pad[3839 10236 3839 14173 1771 1000 3000 "" "4" "square,edge2"] + Pad[3839 -14173 3839 -10236 1771 1000 3000 "" "5" "square"] + ElementLine [-6038 15973 6039 15973 1000] + ElementLine [6039 -15973 6039 15973 1000] + ElementLine [-6038 -15973 6039 -15973 1000] + ElementLine [-6038 2500 -6038 15973 1000] + ElementLine [-6038 -15973 -6038 -2500 1000] + ElementArc [-6038 0 2500 2500 90 180 1000] + + ) + +Element["" "connector(2,3)" "" "2*3" 422500 72500 0 -10000 0 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 10000 8000 5000 8600 3937 "" "2" ""] + Pin[0 20000 8000 5000 8600 3937 "" "3" ""] + Pin[10000 0 8000 5000 8600 3937 "" "4" ""] + Pin[10000 10000 8000 5000 8600 3937 "" "5" ""] + Pin[10000 20000 8000 5000 8600 3937 "" "6" ""] + ElementLine [-5000 -5000 -5000 25000 1000] + ElementLine [-5000 -5000 15000 -5000 1000] + ElementLine [15000 25000 -5000 25000 1000] + ElementLine [15000 25000 15000 -5000 1000] + ElementLine [-5000 5000 5000 5000 1000] + ElementLine [5000 -5000 5000 5000 1000] + + ) + +Element["" "connector(2,3,eshift=x)" "" "2*3" 455000 72500 0 -10000 0 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 10000 8000 5000 8600 3937 "" "2" ""] + Pin[0 20000 8000 5000 8600 3937 "" "3" ""] + Pin[10000 5000 8000 5000 8600 3937 "" "4" ""] + Pin[10000 15000 8000 5000 8600 3937 "" "5" ""] + Pin[10000 25000 8000 5000 8600 3937 "" "6" ""] + ElementLine [-5000 -5000 -5000 30000 1000] + ElementLine [-5000 -5000 15000 -5000 1000] + ElementLine [15000 30000 -5000 30000 1000] + ElementLine [15000 30000 15000 -5000 1000] + ElementLine [-5000 5000 5000 5000 1000] + ElementLine [5000 -5000 5000 5000 1000] + + ) + +Element["" "connector(2,3,eshift=x,etrunc=1)" "" "2*3" 487500 72500 0 -10000 0 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 10000 8000 5000 8600 3937 "" "2" ""] + Pin[0 20000 8000 5000 8600 3937 "" "3" ""] + Pin[10000 5000 8000 5000 8600 3937 "" "4" ""] + Pin[10000 15000 8000 5000 8600 3937 "" "5" ""] + ElementLine [-5000 -5000 -5000 25000 1000] + ElementLine [-5000 -5000 15000 -5000 1000] + ElementLine [15000 25000 -5000 25000 1000] + ElementLine [15000 25000 15000 -5000 1000] + ElementLine [-5000 5000 5000 5000 1000] + ElementLine [5000 -5000 5000 5000 1000] + + ) + +Element["" "acy(300)" "" "acy300" 300000 50000 -12000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-2500 -22500 -2500 -7500 1000] + ElementLine [2500 -22500 2500 -7500 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + + ) + +Element["" "acy(300, endcap)" "" "acy300" 320000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [2500 -20625 2500 -9375 1000] + ElementLine [2500 -9375 3000 -9166 1000] + ElementLine [2500 -20625 3000 -20833 1000] + ElementLine [-2500 -20625 -2500 -9375 1000] + ElementLine [-2500 -9375 -3000 -9166 1000] + ElementLine [-2500 -20625 -3000 -20833 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-3000 -9166 -3000 -8000 1000] + ElementLine [3000 -9166 3000 -8000 1000] + ElementLine [-3000 -22000 -3000 -20833 1000] + ElementLine [3000 -22000 3000 -20833 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + ElementArc [-2500 -8000 500 500 0 90 1000] + ElementArc [2500 -8000 500 500 90 90 1000] + ElementArc [-2500 -22000 500 500 270 90 1000] + ElementArc [2500 -22000 500 500 180 90 1000] + + ) + +Element["" "acy(300, coil, dot)" "" "acy300" 340000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementArc [0 -9375 1875 1875 270 180 1000] + ElementArc [0 -13125 1875 1875 270 180 1000] + ElementArc [0 -16875 1875 1875 270 180 1000] + ElementArc [0 -20625 1875 1875 270 180 1000] + ElementArc [-1250 -5500 666 666 90 360 1000] + + ) + +Element["" "acy(300, pol=bar)" "" "acy300" 360000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-2500 -22500 -2500 -7500 1000] + ElementLine [2500 -22500 2500 -7500 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + ElementLine [-2500 -6500 2500 -6500 1000] + ElementLine [-2500 -8500 -2500 -6500 1000] + ElementLine [2500 -8500 2500 -6500 1000] + ElementLine [-2500 -8500 2500 -8500 1000] + + ) + +Element["" "acy(300, wiper=aarrow)" "" "acy300" 380000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 9000 5000 9600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-2500 -22500 -2500 -7500 1000] + ElementLine [2500 -22500 2500 -7500 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + ElementLine [5000 -12500 -8000 -17500 1000] + ElementLine [-8000 -17500 -6492 -15848 1000] + ElementLine [-8000 -17500 -5774 -17715 1000] + ElementLine [-5774 -17715 -6492 -15848 1000] + + ) + +Element["" "acy(300, wiper=parrow)" "" "acy300" 400000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-2500 -22500 -2500 -7500 1000] + ElementLine [2500 -22500 2500 -7500 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + ElementLine [-8000 -15000 -2500 -15000 1000] + ElementLine [-2500 -15000 -4500 -16000 1000] + ElementLine [-2500 -15000 -4500 -14000 1000] + ElementLine [-4500 -16000 -4500 -14000 1000] + + ) + +Element["" "acy(300, wiper=looparrow)" "" "acy300" 420000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-2500 -22500 -2500 -7500 1000] + ElementLine [2500 -22500 2500 -7500 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + ElementLine [-8000 -15000 -2500 -15000 1000] + ElementLine [-2500 -15000 -4500 -16000 1000] + ElementLine [-2500 -15000 -4500 -14000 1000] + ElementLine [-4500 -16000 -4500 -14000 1000] + ElementLine [-8000 -24375 -8000 -15000 1000] + ElementLine [-8000 -24375 0 -24375 1000] + + ) + +Element["" "acy(300, zigzag)" "" "acy300" 440000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [0 -7500 -2500 -8750 1000] + ElementLine [-2500 -8750 2500 -11250 1000] + ElementLine [2500 -11250 0 -12500 1000] + ElementLine [0 -12500 -2500 -13750 1000] + ElementLine [-2500 -13750 2500 -16250 1000] + ElementLine [2500 -16250 0 -17500 1000] + ElementLine [0 -17500 -2500 -18750 1000] + ElementLine [-2500 -18750 2500 -21250 1000] + ElementLine [2500 -21250 0 -22500 1000] + + ) + +Element["" "acy(300, core)" "" "acy300" 460000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-4875 -22500 -4875 -7500 1000] + ElementArc [0 -9375 1875 1875 270 180 1000] + ElementArc [0 -13125 1875 1875 270 180 1000] + ElementArc [0 -16875 1875 1875 270 180 1000] + ElementArc [0 -20625 1875 1875 270 180 1000] + + ) + +Element["" "acy(200, standing, pol=sign, dia=100)" "" "acy200" 520000 90000 -2000 -6000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -20000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -5000 0 0 1000] + ElementLine [0 -20000 0 -15000 1000] + ElementLine [0 -20000 0 0 1000] + ElementLine [2200 -6100 2200 -4100 1000] + ElementLine [2200 -15900 2200 -13900 1000] + ElementLine [1200 -14900 3200 -14900 1000] + ElementArc [0 0 10000 10000 90 360 1000] + + ) + +Element["" "alf(300,schottky)" "" "acy300" 480000 50000 -5000 -22000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -10000 0 0 1000] + ElementLine [0 -30000 0 -20000 1000] + ElementLine [-5000 -20000 5000 -20000 1000] + ElementLine [-5000 -20000 0 -10000 1000] + ElementLine [5000 -20000 0 -10000 1000] + ElementLine [-3500 -10000 3500 -10000 1000] + ElementArc [-3500 -11500 1500 1500 270 180 1000] + ElementArc [3500 -8500 1500 1500 90 180 1000] + + ) + +Element["" "alf(300,tunnel)" "" "acy300" 500000 50000 -5000 -22000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -10000 0 0 1000] + ElementLine [0 -30000 0 -20000 1000] + ElementLine [-5000 -20000 5000 -20000 1000] + ElementLine [-5000 -20000 0 -10000 1000] + ElementLine [5000 -20000 0 -10000 1000] + ElementLine [-5000 -10000 5000 -10000 1000] + ElementLine [5000 -11500 5000 -10000 1000] + ElementLine [-5000 -11500 -5000 -10000 1000] + + ) + +Element["" "alf(300,zener)" "" "acy300" 520000 50000 -5000 -22000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -10000 0 0 1000] + ElementLine [0 -30000 0 -20000 1000] + ElementLine [-5000 -20000 5000 -20000 1000] + ElementLine [-5000 -20000 0 -10000 1000] + ElementLine [5000 -20000 0 -10000 1000] + ElementLine [-5000 -10000 5000 -10000 1000] + ElementLine [5000 -10000 5000 -8500 1000] + ElementLine [-5000 -11500 -5000 -10000 1000] + + ) + +Element["" "SMT transistor, 3 pins" "" "SC70_3" 315000 420000 9300 -9400 3 100 ""] +( + Pad[0 -300 0 300 2900 3000 3500 "1" "1" "square,edge2"] + Pad[5100 -300 5100 300 2900 3000 3500 "2" "2" "square,edge2"] + Pad[2600 -7300 2600 -6700 2900 3000 3500 "3" "3" "square"] + ElementLine [-2100 -9400 -2100 2500 1000] + ElementLine [-2100 2500 7300 2500 1000] + ElementLine [7300 2500 7300 -9400 1000] + ElementLine [7300 -9400 -2100 -9400 1000] + + ) + +Element["" "SMT transistor, 3 pins" "" "SC90" 330000 420000 7600 -7800 3 100 ""] +( + Pad[0 -200 0 200 2400 3000 3000 "1" "1" "square,edge2"] + Pad[3900 -200 3900 200 2400 3000 3000 "2" "2" "square,edge2"] + Pad[1900 -6100 1900 -5700 2400 3000 3000 "3" "3" "square"] + ElementLine [-1700 -7800 -1700 2000 1000] + ElementLine [-1700 2000 5600 2000 1000] + ElementLine [5600 2000 5600 -7800 1000] + ElementLine [5600 -7800 -1700 -7800 1000] + + ) + +Element["" "SMT transistor, 3 pins" "" "SOT23" 311100 453200 12300 -11000 3 100 ""] +( + Pad[0 -300 0 300 3400 3000 4000 "1" "1" "square,edge2"] + Pad[7800 -300 7800 300 3400 3000 4000 "2" "2" "square,edge2"] + Pad[3900 -8500 3900 -7900 3400 3000 4000 "3" "3" "square"] + ElementLine [-2500 -11000 -2500 2900 1000] + ElementLine [-2500 2900 10300 2900 1000] + ElementLine [10300 2900 10300 -11000 1000] + ElementLine [10300 -11000 -2500 -11000 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOT23D" 311100 473200 12300 -11000 3 100 ""] +( + Pad[0 -300 0 300 3400 3000 4000 "2" "2" "square,edge2"] + Pad[7800 -300 7800 300 3400 3000 4000 "3" "3" "square,edge2"] + Pad[3900 -8500 3900 -7900 3400 3000 4000 "1" "1" "square"] + ElementLine [-2500 -11000 -2500 2900 1000] + ElementLine [-2500 2900 10300 2900 1000] + ElementLine [10300 2900 10300 -11000 1000] + ElementLine [10300 -11000 -2500 -11000 1000] + + ) + +Element["" "SMT transistor, 3 pins" "" "SOT323" 332400 452000 9300 -9400 3 100 ""] +( + Pad[0 -300 0 300 2900 3000 3500 "1" "1" "square,edge2"] + Pad[5100 -300 5100 300 2900 3000 3500 "2" "2" "square,edge2"] + Pad[2600 -7300 2600 -6700 2900 3000 3500 "3" "3" "square"] + ElementLine [-2100 -9400 -2100 2500 1000] + ElementLine [-2100 2500 7300 2500 1000] + ElementLine [7300 2500 7300 -9400 1000] + ElementLine [7300 -9400 -2100 -9400 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOT323D" 332400 472000 9300 -9400 3 100 ""] +( + Pad[0 -300 0 300 2900 3000 3500 "2" "2" "square,edge2"] + Pad[5100 -300 5100 300 2900 3000 3500 "3" "3" "square,edge2"] + Pad[2600 -7300 2600 -6700 2900 3000 3500 "1" "1" "square"] + ElementLine [-2100 -9400 -2100 2500 1000] + ElementLine [-2100 2500 7300 2500 1000] + ElementLine [7300 2500 7300 -9400 1000] + ElementLine [7300 -9400 -2100 -9400 1000] + + ) + +Element["" "SMT transistor, 4 pins" "" "SC70_4" 415000 435000 9300 -9400 3 100 ""] +( + Pad[300 0 600 0 2900 3000 3500 "1" "1" "square"] + Pad[5100 -300 5100 300 2900 3000 3500 "2" "2" "square,edge2"] + Pad[5100 -7300 5100 -6700 2900 3000 3500 "3" "3" "square"] + Pad[0 -7300 0 -6700 2900 3000 3500 "4" "4" "square"] + ElementLine [-2100 -9400 -2100 2500 1000] + ElementLine [-2100 2500 7300 2500 1000] + ElementLine [7300 2500 7300 -9400 1000] + ElementLine [7300 -9400 -2100 -9400 1000] + + ) + +Element["" "Pressure transducer" "" "MPAK" 485000 480000 20300 -49700 3 100 ""] +( + Pad[0 -2800 0 2800 3100 3000 3700 "1" "1" "square,edge2"] + Pad[5000 -2800 5000 2800 3100 3000 3700 "2" "2" "square,edge2"] + Pad[10000 -2800 10000 2800 3100 3000 3700 "3" "3" "square,edge2"] + Pad[15000 -2800 15000 2800 3100 3000 3700 "4" "4" "square,edge2"] + Pad[3800 -43700 11200 -43700 8700 3000 9300 "5" "5" "square"] + ElementLine [-3200 -49700 -3200 6100 1000] + ElementLine [-3200 6100 18300 6100 1000] + ElementLine [18300 6100 18300 -49700 1000] + ElementLine [18300 -49700 -3200 -49700 1000] + + ) + +Element["" "SMT transistor, 4 pins" "" "SOT143" 430000 435000 11900 -11000 3 100 ""] +( + Pad[300 0 600 0 3400 3000 4000 "1" "1" "square"] + Pad[7400 -300 7400 300 3400 3000 4000 "2" "2" "square,edge2"] + Pad[7400 -8500 7400 -7900 3400 3000 4000 "3" "3" "square"] + Pad[0 -8500 0 -7900 3400 3000 4000 "4" "4" "square"] + ElementLine [-2500 -11000 -2500 2900 1000] + ElementLine [-2500 2900 9900 2900 1000] + ElementLine [9900 2900 9900 -11000 1000] + ElementLine [9900 -11000 -2500 -11000 1000] + + ) + +Element["" "SMT transistor, 4 pins" "" "SOT223" 450000 480000 25300 -32900 3 100 ""] +( + Pad[0 -3300 0 3300 5600 3000 6200 "1" "1" "square,edge2"] + Pad[9000 -3300 9000 3300 5600 3000 6200 "2" "2" "square,edge2"] + Pad[18100 -3300 18100 3300 5600 3000 6200 "3" "3" "square,edge2"] + Pad[4500 -24400 13500 -24400 12200 3000 12800 "4" "4" "square"] + ElementLine [-5200 -32900 -5200 8500 1000] + ElementLine [-5200 8500 23300 8500 1000] + ElementLine [23300 8500 23300 -32900 1000] + ElementLine [23300 -32900 -5200 -32900 1000] + + ) + +Element["" "SMT transistor, 5 pins" "" "SOT25" 445000 435000 11800 -11000 3 100 ""] +( + Pad[0 -800 0 800 2400 3000 3000 "1" "1" "square,edge2"] + Pad[7800 -800 7800 800 2400 3000 3000 "2" "2" "square,edge2"] + Pad[7800 -9000 7800 -7400 2400 3000 3000 "3" "3" "square"] + Pad[3900 -9000 3900 -7400 2400 3000 3000 "4" "4" "square"] + Pad[0 -9000 0 -7400 2400 3000 3000 "5" "5" "square"] + ElementLine [-2000 -11000 -2000 2900 1000] + ElementLine [-2000 2900 9800 2900 1000] + ElementLine [9800 2900 9800 -11000 1000] + ElementLine [9800 -11000 -2000 -11000 1000] + + ) + +Element["" "SMT transistor, 6 pins" "" "SOT26" 461100 435000 11800 -11000 3 100 ""] +( + Pad[0 -800 0 800 2400 3000 3000 "1" "1" "square,edge2"] + Pad[3900 -800 3900 800 2400 3000 3000 "2" "2" "square,edge2"] + Pad[7800 -800 7800 800 2400 3000 3000 "3" "3" "square,edge2"] + Pad[7800 -9000 7800 -7400 2400 3000 3000 "4" "4" "square"] + Pad[3900 -9000 3900 -7400 2400 3000 3000 "5" "5" "square"] + Pad[0 -9000 0 -7400 2400 3000 3000 "6" "6" "square"] + ElementLine [-2000 -11000 -2000 2900 1000] + ElementLine [-2000 2900 9800 2900 1000] + ElementLine [9800 2900 9800 -11000 1000] + ElementLine [9800 -11000 -2000 -11000 1000] + + ) + +Element["" "SMT transistor, 5 pins" "" "SOT325" 419900 485000 8600 -9400 3 100 ""] +( + Pad[0 -1000 0 1000 1500 3000 2100 "1" "1" "square,edge2"] + Pad[5100 -1000 5100 1000 1500 3000 2100 "2" "2" "square,edge2"] + Pad[5100 -8000 5100 -6000 1500 3000 2100 "3" "3" "square"] + Pad[2600 -8000 2600 -6000 1500 3000 2100 "4" "4" "square"] + Pad[0 -8000 0 -6000 1500 3000 2100 "5" "5" "square"] + ElementLine [-1400 -9400 -1400 2500 1000] + ElementLine [-1400 2500 6600 2500 1000] + ElementLine [6600 2500 6600 -9400 1000] + ElementLine [6600 -9400 -1400 -9400 1000] + + ) + +Element["" "SMT transistor, 6 pins" "" "SOT326" 432400 485000 8600 -9400 3 100 ""] +( + Pad[0 -1000 0 1000 1500 3000 2100 "1" "1" "square,edge2"] + Pad[2600 -1000 2600 1000 1500 3000 2100 "2" "2" "square,edge2"] + Pad[5100 -1000 5100 1000 1500 3000 2100 "3" "3" "square,edge2"] + Pad[5100 -8000 5100 -6000 1500 3000 2100 "4" "4" "square"] + Pad[2600 -8000 2600 -6000 1500 3000 2100 "5" "5" "square"] + Pad[0 -8000 0 -6000 1500 3000 2100 "6" "6" "square"] + ElementLine [-1400 -9400 -1400 2500 1000] + ElementLine [-1400 2500 6600 2500 1000] + ElementLine [6600 2500 6600 -9400 1000] + ElementLine [6600 -9400 -1400 -9400 1000] + + ) + +Element["" "SMT transistor, 4 pins" "" "SOT89" 418900 465000 17300 -16400 3 100 ""] +( + Pad[0 -1200 0 1200 3700 3000 4300 "1" "1" "square,edge2"] + Pad[6100 -1200 6100 1200 3700 3000 4300 "2" "2" "square,edge2"] + Pad[12200 -1200 12200 1200 3700 3000 4300 "3" "3" "square,edge2"] + Pad[3100 -12200 9100 -12200 6100 3000 6700 "4" "4" "square"] + ElementLine [-3000 -16400 -3000 4300 1000] + ElementLine [-3000 4300 15300 4300 1000] + ElementLine [15300 4300 15300 -16400 1000] + ElementLine [15300 -16400 -3000 -16400 1000] + + ) + +Element["" "Crystals" "" "HC49U_3" 30000 620000 -15100 12100 1 100 ""] +( + Pin[0 0 6000 3000 6600 3200 "1" "1" "square"] + Pin[0 -9600 6000 3000 6600 3200 "2" "2" ""] + Pin[0 -19200 6000 3000 6600 3200 "3" "3" ""] + ElementLine [-9100 -22300 -9100 3000 2000] + ElementLine [9200 -22300 9200 3000 2000] + ElementArc [0 -22300 9100 9100 180 180 2000] + ElementArc [0 3000 9100 9100 0 180 2000] + + ) + +Element["" "Crystals" "" "HC49U_3H" 110000 620000 -67500 12100 1 100 ""] +( + Pin[0 0 6000 3000 6600 3200 "1" "1" "square,edge2"] + Pin[0 -9600 6000 3000 6600 3200 "2" "2" "edge2"] + Pin[0 -19200 6000 3000 6600 3200 "3" "3" "edge2"] + ElementLine [-61500 -31400 -61500 12100 2000] + ElementLine [-61500 -31400 -10000 -31400 2000] + ElementLine [-10000 -31400 -10000 12100 2000] + ElementLine [-61500 12100 -10000 12100 2000] + + ) + +Element["" "Transistor" "" "TO126" 140000 790000 -2000 -12000 1 100 ""] +( + Pin[1000 0 8000 3000 8600 5200 "1" "1" "square"] + Pin[10000 0 8000 3000 8600 5200 "2" "2" ""] + Pin[19000 0 8000 3000 8600 5200 "3" "3" ""] + Pin[10000 -43000 13000 3000 13600 11000 "4" "4" ""] + ElementLine [0 -10000 0 0 3000] + ElementLine [10000 -10000 10000 0 3000] + ElementLine [20000 -10000 20000 0 3000] + ElementLine [-5000 -10000 25000 -10000 2000] + ElementLine [25000 -53000 25000 -10000 2000] + ElementLine [-5000 -53000 25000 -53000 2000] + ElementLine [-5000 -53000 -5000 -10000 2000] + + ) + +Element["" "Transistor" "" "TO126S" 199000 790000 -2000 -12000 1 100 ""] +( + Pin[1000 0 8000 3000 8600 5200 "1" "1" "square"] + Pin[10000 10000 8000 3000 8600 5200 "2" "2" ""] + Pin[19000 0 8000 3000 8600 5200 "3" "3" ""] + Pin[10000 -43000 13000 3000 13600 11000 "4" "4" ""] + ElementLine [0 -10000 0 0 3000] + ElementLine [10000 -10000 10000 10000 3000] + ElementLine [20000 -10000 20000 0 3000] + ElementLine [-5000 -10000 25000 -10000 2000] + ElementLine [25000 -53000 25000 -10000 2000] + ElementLine [-5000 -53000 25000 -53000 2000] + ElementLine [-5000 -53000 -5000 -10000 2000] + + ) + +Element["" "Transistor" "" "TO126SW" 40000 680000 7000 -17000 1 100 ""] +( + Pin[0 -1000 8000 3000 8600 5200 "1" "1" "square"] + Pin[10000 -10000 8000 3000 8600 5200 "2" "2" ""] + Pin[0 -19000 8000 3000 8600 5200 "3" "3" ""] + ElementLine [5000 -10000 10000 -10000 3000] + ElementLine [-5000 -25000 -5000 5000 2000] + ElementLine [-5000 -25000 5000 -25000 2000] + ElementLine [5000 -25000 5000 5000 2000] + ElementLine [-5000 5000 5000 5000 2000] + ElementLine [-5000 -5000 5000 -5000 1000] + ElementLine [-5000 -15000 5000 -15000 1000] + + ) + +Element["" "Transistor" "" "TO126W" 70000 680000 7000 4000 1 100 ""] +( + Pin[0 -1000 8000 3000 8600 5200 "1" "1" "square"] + Pin[0 -10000 8000 3000 8600 5200 "2" "2" ""] + Pin[0 -19000 8000 3000 8600 5200 "3" "3" ""] + ElementLine [-5000 -25000 -5000 5000 2000] + ElementLine [-5000 -25000 5000 -25000 2000] + ElementLine [5000 -25000 5000 5000 2000] + ElementLine [-5000 5000 5000 5000 2000] + + ) + +Element["" "Transistor" "" "TO18" 165000 600000 6000 7000 0 100 ""] +( + Pin[0 -5000 5500 3000 6100 3500 "1" "1" ""] + Pin[-5000 0 5500 3000 6100 3500 "2" "2" ""] + Pin[0 5000 5500 3000 6100 3500 "3" "3" ""] + ElementLine [6700 -7900 9400 -10600 1000] + ElementLine [7300 -7300 10000 -10000 1000] + ElementLine [7900 -6700 10600 -9400 1000] + ElementLine [9400 -10600 10600 -9400 1000] + ElementArc [0 0 9800 9800 0 360 1000] + + ) + +Element["" "diode in TO220" "" "TO218" 224000 691900 -21000 -58700 0 100 ""] +( + Pin[-14000 0 10000 3000 10600 6000 "1" "1" "square"] + Pin[-14000 -21900 10000 3000 10600 6000 "2" "2" ""] + Pin[-14000 -43800 10000 3000 10600 6000 "3" "3" ""] + ElementLine [-26000 8800 -6000 8800 2000] + ElementLine [-6000 -52700 -6000 8800 2000] + ElementLine [-26000 -52700 -6000 -52700 2000] + ElementLine [-26000 -52700 -26000 8800 2000] + ElementLine [-21000 -52700 -21000 8800 1000] + ElementLine [-26000 -14400 -21000 -14400 1000] + ElementLine [-26000 -29400 -21000 -29400 1000] + + ) + +Element["" "Transistor" "" "TO220" 90000 790000 -15000 -23000 1 100 ""] +( + Pin[-10000 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[0 0 9000 3000 9600 6000 "2" "2" ""] + Pin[10000 0 9000 3000 9600 6000 "3" "3" ""] + Pin[0 -67000 15000 3000 15600 13000 "4" "4" ""] + ElementLine [-10000 -18000 -10000 0 3000] + ElementLine [0 -18000 0 0 3000] + ElementLine [10000 -18000 10000 0 3000] + ElementLine [-20000 -18000 20000 -18000 2000] + ElementLine [20000 -55500 20000 -18000 2000] + ElementLine [-20000 -55500 20000 -55500 2000] + ElementLine [-20000 -55500 -20000 -18000 2000] + ElementLine [-20000 -55500 20000 -55500 2000] + ElementLine [20000 -68000 20000 -55500 2000] + ElementLine [18500 -68000 20000 -68000 2000] + ElementLine [18500 -75000 18500 -68000 2000] + ElementLine [18500 -75000 20000 -75000 2000] + ElementLine [20000 -79000 20000 -75000 2000] + ElementLine [-20000 -79000 20000 -79000 2000] + ElementLine [-20000 -79000 -20000 -75000 2000] + ElementLine [-20000 -75000 -18500 -75000 2000] + ElementLine [-18500 -75000 -18500 -68000 2000] + ElementLine [-20000 -68000 -18500 -68000 2000] + ElementLine [-20000 -68000 -20000 -55500 2000] + + ) + +Element["" "Transistor" "" "TO220S" 30000 790000 -15000 -23000 1 100 ""] +( + Pin[-10000 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[0 10000 9000 3000 9600 6000 "2" "2" ""] + Pin[10000 0 9000 3000 9600 6000 "3" "3" ""] + Pin[0 -67000 15000 3000 15600 13000 "4" "4" ""] + ElementLine [-10000 -18000 -10000 0 3000] + ElementLine [0 -18000 0 10000 3000] + ElementLine [10000 -18000 10000 0 3000] + ElementLine [-20000 -18000 20000 -18000 2000] + ElementLine [20000 -55500 20000 -18000 2000] + ElementLine [-20000 -55500 20000 -55500 2000] + ElementLine [-20000 -55500 -20000 -18000 2000] + ElementLine [-20000 -55500 20000 -55500 2000] + ElementLine [20000 -68000 20000 -55500 2000] + ElementLine [18500 -68000 20000 -68000 2000] + ElementLine [18500 -75000 18500 -68000 2000] + ElementLine [18500 -75000 20000 -75000 2000] + ElementLine [20000 -79000 20000 -75000 2000] + ElementLine [-20000 -79000 20000 -79000 2000] + ElementLine [-20000 -79000 -20000 -75000 2000] + ElementLine [-20000 -75000 -18500 -75000 2000] + ElementLine [-18500 -75000 -18500 -68000 2000] + ElementLine [-20000 -68000 -18500 -68000 2000] + ElementLine [-20000 -68000 -20000 -55500 2000] + + ) + +Element["" "Transistor" "" "TO220SW" 130000 680000 -19000 10000 1 100 ""] +( + Pin[0 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[10000 -10000 9000 3000 9600 6000 "2" "2" ""] + Pin[0 -20000 9000 3000 9600 6000 "3" "3" ""] + ElementLine [-12000 -30000 -12000 10000 2000] + ElementLine [-12000 -30000 6000 -30000 2000] + ElementLine [6000 -30000 6000 10000 2000] + ElementLine [-12000 10000 6000 10000 2000] + ElementLine [-12000 -30000 -12000 10000 2000] + ElementLine [-12000 -30000 -6000 -30000 2000] + ElementLine [-6000 -30000 -6000 10000 2000] + ElementLine [-12000 10000 -6000 10000 2000] + ElementLine [-12000 -3000 -6000 -3000 1000] + ElementLine [-12000 -17000 -6000 -17000 1000] + ElementLine [6000 -10000 10000 -10000 3000] + + ) + +Element["" "Transistor" "" "TO220W" 100000 680000 -19000 10000 1 100 ""] +( + Pin[0 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[0 -10000 9000 3000 9600 6000 "2" "2" ""] + Pin[0 -20000 9000 3000 9600 6000 "3" "3" ""] + ElementLine [-12000 -30000 -12000 10000 2000] + ElementLine [-12000 -30000 6000 -30000 2000] + ElementLine [6000 -30000 6000 10000 2000] + ElementLine [-12000 10000 6000 10000 2000] + ElementLine [-12000 -30000 -12000 10000 2000] + ElementLine [-12000 -30000 -6000 -30000 2000] + ElementLine [-6000 -30000 -6000 10000 2000] + ElementLine [-12000 10000 -6000 10000 2000] + ElementLine [-12000 -3000 -6000 -3000 1000] + ElementLine [-12000 -17000 -6000 -17000 1000] + + ) + +Element["" "diode in TO220" "" "TO247" 184000 691900 -22000 -59400 0 100 ""] +( + Pin[-14000 0 10000 3000 10600 6000 "1" "1" "square"] + Pin[-14000 -21900 10000 3000 10600 6000 "2" "2" ""] + Pin[-14000 -43800 10000 3000 10600 6000 "3" "3" ""] + ElementLine [-27000 9600 -6000 9600 2000] + ElementLine [-6000 -53400 -6000 9600 2000] + ElementLine [-27000 -53400 -6000 -53400 2000] + ElementLine [-27000 -53400 -27000 9600 2000] + ElementLine [-22000 -53400 -22000 9600 1000] + ElementLine [-27000 -14400 -22000 -14400 1000] + ElementLine [-27000 -29400 -22000 -29400 1000] + + ) + +Element["" "diode in TO220" "" "TO251" 19000 679000 -9000 -28300 0 100 ""] +( + Pin[-9000 0 7000 3000 7600 4000 "1" "1" "square"] + Pin[-9000 -9000 7000 3000 7600 4000 "2" "2" ""] + Pin[-9000 -18000 7000 3000 7600 4000 "3" "3" ""] + ElementLine [-14000 4200 -4000 4200 2000] + ElementLine [-4000 -22300 -4000 4200 2000] + ElementLine [-14000 -22300 -4000 -22300 2000] + ElementLine [-14000 -22300 -14000 4200 2000] + ElementLine [-9000 -22300 -9000 4200 1000] + ElementLine [-14000 -1500 -9000 -1500 1000] + ElementLine [-14000 -16500 -9000 -16500 1000] + + ) + +Element["" "diode in TO220" "" "TO264" 264000 691900 -22000 -67900 0 100 ""] +( + Pin[-14000 0 10000 3000 10600 6000 "1" "1" "square"] + Pin[-14000 -21900 10000 3000 10600 6000 "2" "2" ""] + Pin[-14000 -43800 10000 3000 10600 6000 "3" "3" ""] + ElementLine [-27000 18100 -6000 18100 2000] + ElementLine [-6000 -61900 -6000 18100 2000] + ElementLine [-27000 -61900 -6000 -61900 2000] + ElementLine [-27000 -61900 -27000 18100 2000] + ElementLine [-22000 -61900 -22000 18100 1000] + ElementLine [-27000 -14400 -22000 -14400 1000] + ElementLine [-27000 -29400 -22000 -29400 1000] + + ) + +Element["" "Transistor" "" "TO39" 210000 600000 6000 7000 0 100 ""] +( + Pin[0 -10000 5500 3000 6100 3500 "1" "1" "square"] + Pin[-10000 0 5500 3000 6100 3500 "2" "2" ""] + Pin[0 10000 5500 3000 6100 3500 "3" "3" ""] + ElementLine [12700 -13900 14800 -16000 1000] + ElementLine [13300 -13300 15400 -15400 1000] + ElementLine [13900 -12700 16000 -14800 1000] + ElementLine [16000 -14800 14800 -16000 1000] + ElementArc [0 0 18300 18300 0 360 1000] + + ) + +Element["" "Transistor" "" "TO92" 250000 610000 -13000 -1000 1 100 ""] +( + Pin[0 -20000 7200 3000 7800 4200 "1" "1" "square"] + Pin[0 -10000 7200 3000 7800 4200 "2" "2" ""] + Pin[0 0 7200 3000 7800 4200 "3" "3" ""] + ElementLine [-7000 -17000 -7000 -3000 1000] + ElementArc [0 -10000 10000 10000 45 270 1000] + + ) + +Element["" "diode in TO220" "" "TO247_2" 360000 1050000 59400 -22000 3 100 ""] +( + Pin[0 -14000 10000 3000 10600 6000 "1" "1" "square,edge2"] + Pin[43800 -14000 10000 3000 10600 6000 "2" "2" "edge2"] + ElementLine [-9600 -27000 -9600 -6000 2000] + ElementLine [-9600 -6000 53400 -6000 2000] + ElementLine [53400 -6000 53400 -27000 2000] + ElementLine [53400 -27000 -9600 -27000 2000] + ElementLine [-9600 -22000 53400 -22000 1000] + ElementLine [14400 -27000 14400 -22000 1000] + ElementLine [29400 -27000 29400 -22000 1000] + + ) + +Element["" "diode in TO220" "" "TO220ACSTAND" 300000 1052000 36000 -17000 3 100 ""] +( + Pin[0 -12000 8000 3000 8600 4000 "1" "1" "square,edge2"] + Pin[20000 -12000 8000 3000 8600 4000 "2" "2" "edge2"] + ElementLine [-10000 -22000 -10000 -4000 2000] + ElementLine [-10000 -4000 30000 -4000 2000] + ElementLine [30000 -4000 30000 -22000 2000] + ElementLine [30000 -22000 -10000 -22000 2000] + ElementLine [-10000 -17000 30000 -17000 1000] + ElementLine [2500 -22000 2500 -17000 1000] + ElementLine [17500 -22000 17500 -17000 1000] + + ) + +Element["" "LED, size in mm (pin 1 is +, 2 is -)" "" "LED5" 200000 1035000 7000 -10000 1 100 ""] +( + Pin[0 5000 6500 3000 7100 4300 "1" "1" "square"] + Pin[0 -5000 6500 3000 7100 4300 "2" "2" ""] + ElementArc [0 0 11800 11800 90 360 1000] + ElementArc [0 0 13800 13800 90 360 1000] + + ) + +Element["" "LED, size in mm (pin 1 is +, 2 is -)" "" "LED3" 160000 1035000 7000 -10000 1 100 ""] +( + Pin[0 5000 6500 3000 7100 4300 "1" "1" "square"] + Pin[0 -5000 6500 3000 7100 4300 "2" "2" ""] + ElementArc [0 0 5900 5900 135 90 1000] + ElementArc [0 0 5900 5900 315 90 1000] + ElementArc [0 0 7900 7900 135 90 1000] + ElementArc [0 0 7900 7900 315 90 1000] + + ) + +Element["" "Crystals" "" "HC51UH" 420000 980000 -103500 13600 1 100 ""] +( + Pin[0 0 8000 3000 8600 4000 "1" "1" "square,edge2"] + Pin[0 -48500 8000 3000 8600 4000 "2" "2" "edge2"] + ElementLine [-97500 -62100 -97500 13600 2000] + ElementLine [-97500 -62100 -20000 -62100 2000] + ElementLine [-20000 -62100 -20000 13600 2000] + ElementLine [-97500 13600 -20000 13600 2000] + + ) + +Element["" "Crystals" "" "HC51U" 220000 978500 -23600 13600 1 100 ""] +( + Pin[0 0 8000 3000 8600 4000 "1" "1" "square"] + Pin[0 -48500 8000 3000 8600 4000 "2" "2" ""] + ElementLine [-17600 -44500 -17600 -4000 2000] + ElementLine [17600 -44500 17600 -4000 2000] + ElementArc [0 -44500 17600 17600 180 180 2000] + ElementArc [0 -4000 17600 17600 0 180 2000] + + ) + +Element["" "Crystals" "" "HC49UH" 310000 960000 -67500 12100 1 100 ""] +( + Pin[0 0 6000 3000 6600 3200 "1" "1" "square,edge2"] + Pin[0 -19200 6000 3000 6600 3200 "2" "2" "edge2"] + ElementLine [-61500 -31400 -61500 12100 2000] + ElementLine [-61500 -31400 -10000 -31400 2000] + ElementLine [-10000 -31400 -10000 12100 2000] + ElementLine [-61500 12100 -10000 12100 2000] + + ) + +Element["" "Crystals" "" "HC49U" 180000 949200 -15100 12100 1 100 ""] +( + Pin[0 0 6000 3000 6600 3200 "1" "1" "square"] + Pin[0 -19200 6000 3000 6600 3200 "2" "2" ""] + ElementLine [-9100 -22300 -9100 3000 2000] + ElementLine [9200 -22300 9200 3000 2000] + ElementArc [0 -22300 9100 9100 180 180 2000] + ElementArc [0 3000 9100 9100 0 180 2000] + + ) + +Element["" "Crystals" "" "HC49" 150000 950000 -11000 5000 1 100 ""] +( + Pin[0 0 6000 3000 6600 2800 "1" "1" "square"] + Pin[0 -20000 6000 3000 6600 2800 "2" "2" ""] + ElementLine [-5000 -20000 -5000 0 2000] + ElementLine [5000 -20000 5000 0 2000] + ElementArc [0 -20000 5000 5000 180 180 2000] + ElementArc [0 0 5000 5000 0 180 2000] + + ) + +Element["" "" "" "" 245000 467500 0 0 0 100 ""] +( + Pin[0 0 19685 2000 20285 11811 "" "2" ""] + Pin[0 -27559 19685 2000 20285 11811 "" "1" ""] + Pin[-17717 -13779 19685 2000 20285 11811 "" "3" ""] + ElementLine [-17717 -55118 -17717 0 1000] + ElementLine [-17717 0 17716 0 1000] + ElementLine [17716 0 17716 -55118 1000] + ElementLine [17716 -55118 -17717 -55118 1000] + ElementLine [-17717 -43307 17716 -43307 1000] + + ) + +Element["" "Power IC, as in MULTIWATT15" "" "HEPTAWATT" 441400 635000 -19900 -41500 0 100 ""] +( + Pin[6100 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[-13900 -5000 9000 3000 9600 6000 "2" "2" ""] + Pin[6100 -10000 9000 3000 9600 6000 "3" "3" ""] + Pin[-13900 -15000 9000 3000 9600 6000 "4" "4" ""] + Pin[6100 -20000 9000 3000 9600 6000 "5" "5" ""] + Pin[-13900 -25000 9000 3000 9600 6000 "6" "6" ""] + Pin[6100 -30000 9000 3000 9600 6000 "7" "7" ""] + ElementLine [-24900 5400 -6000 5400 2000] + ElementLine [-6000 -35500 -6000 5400 2000] + ElementLine [-24900 -35500 -6000 -35500 2000] + ElementLine [-24900 -35500 -24900 5400 2000] + ElementLine [-19900 -35500 -19900 5400 1000] + ElementLine [-24900 -7500 -19900 -7500 1000] + ElementLine [-24900 -22500 -19900 -22500 1000] + + ) + +Element["" "Power IC, as in MULTIWATT15" "" "MULTIWATT11" 317500 628000 79500 -21000 3 100 ""] +( + Pin[0 12000 9000 3000 9600 6000 "1" "1" "square,edge2"] + Pin[6700 -8000 9000 3000 9600 6000 "2" "2" "edge2"] + Pin[13400 12000 9000 3000 9600 6000 "3" "3" "edge2"] + Pin[20100 -8000 9000 3000 9600 6000 "4" "4" "edge2"] + Pin[26800 12000 9000 3000 9600 6000 "5" "5" "edge2"] + Pin[33500 -8000 9000 3000 9600 6000 "6" "6" "edge2"] + Pin[40200 12000 9000 3000 9600 6000 "7" "7" "edge2"] + Pin[46900 -8000 9000 3000 9600 6000 "8" "8" "edge2"] + Pin[53600 12000 9000 3000 9600 6000 "9" "9" "edge2"] + Pin[60300 -8000 9000 3000 9600 6000 "10" "10" "edge2"] + Pin[67000 12000 9000 3000 9600 6000 "11" "11" "edge2"] + ElementLine [-6500 -26000 -6500 -6000 2000] + ElementLine [-6500 -6000 73500 -6000 2000] + ElementLine [73500 -6000 73500 -26000 2000] + ElementLine [73500 -26000 -6500 -26000 2000] + ElementLine [-6500 -21000 73500 -21000 1000] + ElementLine [26000 -26000 26000 -21000 1000] + ElementLine [41000 -26000 41000 -21000 1000] + + ) + +Element["" "Power IC, as in MULTIWATT15" "" "MULTIWATT15" 317500 688000 81000 -21000 3 100 ""] +( + Pin[0 12000 9000 3000 9600 6000 "1" "1" "square,edge2"] + Pin[5000 -8000 9000 3000 9600 6000 "2" "2" "edge2"] + Pin[10000 12000 9000 3000 9600 6000 "3" "3" "edge2"] + Pin[15000 -8000 9000 3000 9600 6000 "4" "4" "edge2"] + Pin[20000 12000 9000 3000 9600 6000 "5" "5" "edge2"] + Pin[25000 -8000 9000 3000 9600 6000 "6" "6" "edge2"] + Pin[30000 12000 9000 3000 9600 6000 "7" "7" "edge2"] + Pin[35000 -8000 9000 3000 9600 6000 "8" "8" "edge2"] + Pin[40000 12000 9000 3000 9600 6000 "9" "9" "edge2"] + Pin[45000 -8000 9000 3000 9600 6000 "10" "10" "edge2"] + Pin[50000 12000 9000 3000 9600 6000 "11" "11" "edge2"] + Pin[55000 -8000 9000 3000 9600 6000 "12" "12" "edge2"] + Pin[60000 12000 9000 3000 9600 6000 "13" "13" "edge2"] + Pin[65000 -8000 9000 3000 9600 6000 "14" "14" "edge2"] + Pin[70000 12000 9000 3000 9600 6000 "15" "15" "edge2"] + ElementLine [-5000 -26000 -5000 -6000 2000] + ElementLine [-5000 -6000 75000 -6000 2000] + ElementLine [75000 -6000 75000 -26000 2000] + ElementLine [75000 -26000 -5000 -26000 2000] + ElementLine [-5000 -21000 75000 -21000 1000] + ElementLine [27500 -26000 27500 -21000 1000] + ElementLine [42500 -26000 42500 -21000 1000] + + ) + +Element["" "Power IC, as in MULTIWATT15" "" "MULTIWATT8" 317500 754500 81000 -21000 3 100 ""] +( + Pin[0 -14500 9000 3000 9600 6000 "1" "1" "square,edge2"] + Pin[10000 -14500 9000 3000 9600 6000 "2" "2" "edge2"] + Pin[20000 -14500 9000 3000 9600 6000 "3" "3" "edge2"] + Pin[30000 -14500 9000 3000 9600 6000 "4" "4" "edge2"] + Pin[40000 -14500 9000 3000 9600 6000 "5" "5" "edge2"] + Pin[50000 -14500 9000 3000 9600 6000 "6" "6" "edge2"] + Pin[60000 -14500 9000 3000 9600 6000 "7" "7" "edge2"] + Pin[70000 -14500 9000 3000 9600 6000 "8" "8" "edge2"] + ElementLine [-5000 -26000 -5000 -6000 2000] + ElementLine [-5000 -6000 75000 -6000 2000] + ElementLine [75000 -6000 75000 -26000 2000] + ElementLine [75000 -26000 -5000 -26000 2000] + ElementLine [-5000 -21000 75000 -21000 1000] + ElementLine [27500 -26000 27500 -21000 1000] + ElementLine [42500 -26000 42500 -21000 1000] + + ) + +Element["" "Crystal oscillator" "" "OSC14" 427500 700000 20000 -17000 0 100 ""] +( + Pin[0 0 5000 3000 5600 2800 "NC" "1" "edge2"] + Pin[60000 0 5000 3000 5600 2800 "GND" "2" "edge2"] + Pin[60000 -30000 5000 3000 5600 2800 "CLK" "3" "edge2"] + Pin[0 -30000 5000 3000 5600 2800 "VCC" "4" "edge2"] + ElementLine [-9500 -30000 -9500 9500 1000] + ElementLine [0 -39500 60000 -39500 1000] + ElementLine [69500 -30000 69500 0 1000] + ElementLine [-9500 9500 60000 9500 1000] + ElementLine [-4000 -30000 -4000 0 1000] + ElementLine [0 -34000 60000 -34000 1000] + ElementLine [64000 -30000 64000 0 1000] + ElementLine [0 4000 60000 4000 1000] + ElementArc [0 -30000 9500 9500 270 90 1000] + ElementArc [60000 -30000 9500 9500 180 90 1000] + ElementArc [60000 0 9500 9500 90 90 1000] + ElementArc [0 -30000 4000 4000 270 90 1000] + ElementArc [60000 -30000 4000 4000 180 90 1000] + ElementArc [60000 0 4000 4000 90 90 1000] + ElementArc [0 0 4000 4000 0 90 1000] + + ) + +Element["" "Power IC, as in MULTIWATT15" "" "PENTAWATT" 494700 636700 -19900 -39900 0 100 ""] +( + Pin[8500 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[-7200 -6700 9000 3000 9600 6000 "2" "2" ""] + Pin[8500 -13400 9000 3000 9600 6000 "3" "3" ""] + Pin[-7200 -20100 9000 3000 9600 6000 "4" "4" ""] + Pin[8500 -26800 9000 3000 9600 6000 "5" "5" ""] + ElementLine [-24900 7000 -6000 7000 2000] + ElementLine [-6000 -33900 -6000 7000 2000] + ElementLine [-24900 -33900 -6000 -33900 2000] + ElementLine [-24900 -33900 -24900 7000 2000] + ElementLine [-19900 -33900 -19900 7000 1000] + ElementLine [-24900 -5900 -19900 -5900 1000] + ElementLine [-24900 -20900 -19900 -20900 1000] + + ) + +Element["" "" "" "" 457500 740000 -12500 -9000 0 100 ""] +( + Pin[13091 9000 9000 5000 9600 3937 "" "4" "edge2,intconn(2)"] + Pin[-12500 9000 9000 5000 9600 3937 "" "3" "edge2,intconn(2)"] + Pin[13091 -9000 9000 5000 9600 3937 "" "2" "edge2,intconn(1)"] + Pin[-12500 -9000 9000 5000 9600 3937 "" "1" "edge2,intconn(1)"] + ElementLine [12181 11736 12181 -11886 787] + ElementLine [-11441 11736 12181 11736 787] + ElementLine [-11441 -11886 -11441 11736 787] + ElementLine [-11441 -11886 12181 -11886 787] + ElementArc [7815 -8031 2756 2756 90 90 787] + ElementArc [7815 -8031 2756 2756 0 90 787] + ElementArc [7815 -8031 2756 2756 270 90 787] + ElementArc [7815 -8031 2756 2756 180 90 787] + ElementArc [7815 7717 2756 2756 0 90 787] + ElementArc [7815 7717 2756 2756 270 90 787] + ElementArc [7815 7717 2756 2756 180 90 787] + ElementArc [7815 7717 2756 2756 90 90 787] + ElementArc [-7933 7717 2756 2756 270 90 787] + ElementArc [-7933 7717 2756 2756 180 90 787] + ElementArc [-7933 7717 2756 2756 90 90 787] + ElementArc [-7933 7717 2756 2756 0 90 787] + ElementArc [-7933 -8031 2756 2756 180 90 787] + ElementArc [-7933 -8031 2756 2756 90 90 787] + ElementArc [-7933 -8031 2756 2756 0 90 787] + ElementArc [-7933 -8031 2756 2756 270 90 787] + ElementArc [-59 -157 6693 6693 270 90 787] + ElementArc [-59 -157 6693 6693 180 90 787] + ElementArc [-59 -157 6693 6693 90 90 787] + ElementArc [-59 -157 6693 6693 0 90 787] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "01005" 330000 195000 -3150 3150 1 100 ""] +( + Pad[-19 807 19 807 984 2000 1584 "1" "1" "square"] + Pad[-19 -807 19 -807 984 2000 1584 "2" "2" "square"] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "0201" 335000 195000 -3150 3150 1 100 ""] +( + Pad[0 1181 0 1181 1574 2000 2174 "1" "1" "square"] + Pad[0 -1181 0 -1181 1574 2000 2174 "2" "2" "square"] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "0402" 340000 195000 -3150 3150 1 100 ""] +( + Pad[-393 1574 393 1574 1968 2000 2568 "1" "1" "square"] + Pad[-393 -1574 393 -1574 1968 2000 2568 "2" "2" "square"] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "0603" 350000 195000 -3150 3150 1 100 ""] +( + Pad[-492 2559 492 2559 2952 2000 3552 "1" "1" "square"] + Pad[-492 -2559 492 -2559 2952 2000 3552 "2" "2" "square"] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "0805" 360000 195000 -3150 3150 1 100 ""] +( + Pad[-393 3543 393 3543 5118 2000 5718 "1" "1" "square"] + Pad[-393 -3543 393 -3543 5118 2000 5718 "2" "2" "square"] + ElementLine [-2755 -393 -2755 393 800] + ElementLine [2755 -393 2755 393 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "1008" 375000 195000 -3150 3150 1 100 ""] +( + Pad[-2362 5118 2362 5118 4330 2000 4930 "1" "1" "square"] + Pad[-2362 -5118 2362 -5118 4330 2000 4930 "2" "2" "square"] + ElementLine [-4527 -1377 -4527 1377 800] + ElementLine [4527 -1377 4527 1377 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "1206" 390000 195000 -3150 3150 1 100 ""] +( + Pad[-1181 5905 1181 5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "2" "2" "square"] + ElementLine [-3740 -2362 -3740 2362 800] + ElementLine [3740 -2362 3740 2362 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "1210" 405000 195000 -3150 3150 1 100 ""] +( + Pad[-2755 5905 2755 5905 5118 2000 5718 "1" "1" "square"] + Pad[-2755 -5905 2755 -5905 5118 2000 5718 "2" "2" "square"] + ElementLine [-5314 -1968 -5314 1968 800] + ElementLine [5314 -1968 5314 1968 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "1806" 335000 220000 -3150 3150 1 100 ""] +( + Pad[-3543 7874 3543 7874 6299 2000 6899 "1" "1" "square"] + Pad[-3543 -7874 3543 -7874 6299 2000 6899 "2" "2" "square"] + ElementLine [-6692 -3149 -6692 3149 800] + ElementLine [6692 -3149 6692 3149 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "1825" 360000 220000 -3150 3150 1 100 ""] +( + Pad[-10236 7874 10236 7874 6299 2000 6899 "1" "1" "square"] + Pad[-10236 -7874 10236 -7874 6299 2000 6899 "2" "2" "square"] + ElementLine [-13385 -3149 -13385 3149 800] + ElementLine [13385 -3149 13385 3149 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "2706" 395000 220000 -17900 0 1 100 ""] +( + Pad[10800 -300 10800 300 7800 2000 8400 "1" "1" "square"] + Pad[-10800 -300 -10800 300 7800 2000 8400 "2" "2" "square"] + ElementLine [15900 -5400 15900 5400 1000] + ElementLine [-15900 -5400 15900 -5400 1000] + ElementLine [-15900 -5400 -15900 5400 1000] + ElementLine [-15900 5400 15900 5400 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "DO214" 470000 270000 0 22100 2 100 ""] +( + Pad[-1900 -10600 1900 -10600 14000 2000 14600 "1" "1" "square"] + Pad[-1900 10600 1900 10600 14000 2000 14600 "2" "2" "square"] + ElementLine [-8900 -21100 8900 -21100 2000] + ElementLine [-8900 -21100 -11400 -14100 1000] + ElementLine [-11400 -14100 -11400 20100 1000] + ElementLine [-11400 20100 11400 20100 1000] + ElementLine [11400 -14100 11400 20100 1000] + ElementLine [11400 -14100 8900 -21100 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "DO214AB" 470000 320000 0 22700 2 100 ""] +( + Pad[-2000 -10900 2000 -10900 14500 2000 15100 "1" "1" "square"] + Pad[-2000 10900 2000 10900 14500 2000 15100 "2" "2" "square"] + ElementLine [-9200 -21700 9200 -21700 2000] + ElementLine [-9200 -21700 -11800 -14500 1000] + ElementLine [-11800 -14500 -11800 20700 1000] + ElementLine [-11800 20700 11800 20700 1000] + ElementLine [11800 -14500 11800 20700 1000] + ElementLine [11800 -14500 9200 -21700 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD106A" 425000 265000 0 16600 2 100 ""] +( + Pad[-1700 -7600 1700 -7600 10200 2000 10800 "1" "1" "square"] + Pad[-1700 7600 1700 7600 10200 2000 10800 "2" "2" "square"] + ElementLine [-6800 -15600 6800 -15600 2000] + ElementLine [-6800 -15600 -8700 -10500 1000] + ElementLine [-8700 -10500 -8700 14600 1000] + ElementLine [-8700 14600 8700 14600 1000] + ElementLine [8700 -10500 8700 14600 1000] + ElementLine [8700 -10500 6800 -15600 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD110" 335000 265000 0 8300 2 100 ""] +( + Pad[-1500 -2900 1500 -2900 4600 2000 5200 "1" "1" "square"] + Pad[-1500 2900 1500 2900 4600 2000 5200 "2" "2" "square"] + ElementLine [-3800 -7300 3800 -7300 2000] + ElementLine [-3800 -7300 -4900 -5000 1000] + ElementLine [-4900 -5000 -4900 6300 1000] + ElementLine [-4900 6300 4900 6300 1000] + ElementLine [4900 -5000 4900 6300 1000] + ElementLine [4900 -5000 3800 -7300 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD123" 380000 265000 0 12000 2 100 ""] +( + Pad[-600 -5500 600 -5500 6900 2000 7500 "1" "1" "square"] + Pad[-600 5500 600 5500 6900 2000 7500 "2" "2" "square"] + ElementLine [-4000 -11000 4000 -11000 2000] + ElementLine [-4000 -11000 -5100 -7600 1000] + ElementLine [-5100 -7600 -5100 10000 1000] + ElementLine [-5100 10000 5100 10000 1000] + ElementLine [5100 -7600 5100 10000 1000] + ElementLine [5100 -7600 4000 -11000 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD323" 350000 265000 0 9300 2 100 ""] +( + Pad[-1000 -3700 1000 -3700 5100 2000 5700 "1" "1" "square"] + Pad[-1000 3700 1000 3700 5100 2000 5700 "2" "2" "square"] + ElementLine [-3500 -8300 3500 -8300 2000] + ElementLine [-3500 -8300 -4500 -5800 1000] + ElementLine [-4500 -5800 -4500 7300 1000] + ElementLine [-4500 7300 4500 7300 1000] + ElementLine [4500 -5800 4500 7300 1000] + ElementLine [4500 -5800 3500 -8300 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD80" 365000 265000 0 11600 2 100 ""] +( + Pad[-1600 -5800 1600 -5800 5300 2000 5900 "1" "1" "square"] + Pad[-1600 5800 1600 5800 5300 2000 5900 "2" "2" "square"] + ElementLine [-4300 -10600 4300 -10600 2000] + ElementLine [-4300 -10600 -5500 -8000 1000] + ElementLine [-5500 -8000 -5500 9600 1000] + ElementLine [-5500 9600 5500 9600 1000] + ElementLine [5500 -8000 5500 9600 1000] + ElementLine [5500 -8000 4300 -10600 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD87" 400000 265000 0 12400 2 100 ""] +( + Pad[-2600 -5800 2600 -5800 6100 2000 6700 "1" "1" "square"] + Pad[-2600 5800 2600 5800 6100 2000 6700 "2" "2" "square"] + ElementLine [-5700 -11400 5700 -11400 2000] + ElementLine [-5700 -11400 -7300 -8400 1000] + ElementLine [-7300 -8400 -7300 10400 1000] + ElementLine [-7300 10400 7300 10400 1000] + ElementLine [7300 -8400 7300 10400 1000] + ElementLine [7300 -8400 5700 -11400 1000] + + ) + +Element["" "Tantalum SMT capacitor (pin 1 is +)" "" "TANT_A" 430000 325000 0 10600 2 100 ""] +( + Pad[-1800 -5000 1800 -5000 4900 2000 5500 "1" "1" "square"] + Pad[-1800 5000 1800 5000 4900 2000 5500 "2" "2" "square"] + ElementLine [-4300 -9600 4300 -9600 2000] + ElementLine [-4300 -9600 -5500 -7200 1000] + ElementLine [-5500 -7200 -5500 8600 1000] + ElementLine [-5500 8600 5500 8600 1000] + ElementLine [5500 -7200 5500 8600 1000] + ElementLine [5500 -7200 4300 -9600 1000] + + ) + +Element["" "Tantalum SMT capacitor (pin 1 is +)" "" "TANT_B" 405000 325000 0 13200 2 100 ""] +( + Pad[-4100 -5500 4100 -5500 7100 2000 7700 "1" "1" "square"] + Pad[-4100 5500 4100 5500 7100 2000 7700 "2" "2" "square"] + ElementLine [-7700 -12200 7700 -12200 2000] + ElementLine [-7700 -12200 -9900 -8700 1000] + ElementLine [-9900 -8700 -9900 11200 1000] + ElementLine [-9900 11200 9900 11200 1000] + ElementLine [9900 -8700 9900 11200 1000] + ElementLine [9900 -8700 7700 -12200 1000] + + ) + +Element["" "Tantalum SMT capacitor (pin 1 is +)" "" "TANT_C" 375000 320000 0 18800 2 100 ""] +( + Pad[-3900 -9400 3900 -9400 9700 2000 10300 "1" "1" "square"] + Pad[-3900 9400 3900 9400 9700 2000 10300 "2" "2" "square"] + ElementLine [-8700 -17800 8700 -17800 2000] + ElementLine [-8700 -17800 -11200 -13000 1000] + ElementLine [-11200 -13000 -11200 16800 1000] + ElementLine [-11200 16800 11200 16800 1000] + ElementLine [11200 -13000 11200 16800 1000] + ElementLine [11200 -13000 8700 -17800 1000] + + ) + +Element["" "Tantalum SMT capacitor (pin 1 is +)" "" "TANT_D" 343500 316500 0 22900 2 100 ""] +( + Pad[-5600 -11500 5600 -11500 12300 2000 12900 "1" "1" "square"] + Pad[-5600 11500 5600 11500 12300 2000 12900 "2" "2" "square"] + ElementLine [-11700 -21900 11700 -21900 2000] + ElementLine [-11700 -21900 -15000 -15800 1000] + ElementLine [-15000 -15800 -15000 20900 1000] + ElementLine [-15000 20900 15000 20900 1000] + ElementLine [15000 -15800 15000 20900 1000] + ElementLine [15000 -15800 11700 -21900 1000] + + ) + +Element["" "" "" "" 455000 207500 12913 3720 1 70 ""] +( + Pad[-984 -7087 984 -7087 5118 5000 7618 "" "1" "square"] + Pad[-984 7087 984 7087 5118 5000 7618 "" "2" "square"] + ElementLine [-3150 -3937 -3150 3937 787] + ElementLine [3150 -3937 3150 3937 787] + + ) +Layer(1 "component") +( + Line[280000 400000 540000 400000 8000 5000 "clearline"] + Line[280000 0 280000 870000 8000 5000 "clearline"] + Line[0 550000 540000 550000 8000 5000 "clearline"] + Line[390000 550000 390000 400000 8000 5000 "clearline"] + Line[280000 160000 540000 160000 8000 5000 "clearline"] + Line[540000 0 540000 1120000 8000 5000 "clearline"] + Line[0 1120000 0 0 8000 5000 "clearline"] + Line[0 0 540000 0 8000 5000 "clearline"] + Line[540000 870000 0 870000 8000 5000 "clearline"] + Line[540000 1120000 0 1120000 8000 5000 "clearline"] + Text[296338 119704 0 670 "PARAMETRIC" "clearline"] + Text[108838 502204 0 670 "CONN" "clearline"] + Text[366338 349704 0 670 "SMD2" "clearline"] + Text[286338 499704 0 670 "SMD3" "clearline"] + Text[416338 499704 0 670 "SMDN" "clearline"] + Text[86338 819704 0 670 "TRH3" "clearline"] + Text[376338 809704 0 670 "TRHN" "clearline"] + Text[256338 1069704 0 670 "TRH2" "clearline"] +) +Layer(2 "solder") +( + Polygon("clearpoly") + ( + [5000 2500] [277500 2500] [277500 547500] [5000 547500] + ) + Polygon("clearpoly") + ( + [282500 2500] [537500 2500] [537500 157500] [282500 157500] + ) + Polygon("clearpoly") + ( + [282500 162500] [537500 162500] [537500 397500] [282500 397500] + ) + Polygon("clearpoly") + ( + [282500 402500] [387500 402500] [387500 547500] [282500 547500] + ) + Polygon("clearpoly") + ( + [392500 402500] [537500 402500] [537500 547500] [392500 547500] + ) + Polygon("clearpoly") + ( + [2500 552500] [277500 552500] [277500 867500] [2500 867500] + ) + Polygon("clearpoly") + ( + [282500 552500] [537500 552500] [537500 867500] [282500 867500] + ) + Polygon("clearpoly") + ( + [2500 872500] [540000 872500] [540000 1120000] [2500 1120000] + ) +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( + Line[305000 430000 360000 430000 1000 4000 "clearline"] + Line[0 640000 150000 640000 1000 4000 "clearline"] + Line[150000 640000 150000 570000 1000 4000 "clearline"] + Line[260000 1010000 260000 1060000 1000 4000 "clearline"] + Line[130000 1010000 460000 1010000 1000 4000 "clearline"] + Line[325000 240000 495000 240000 1000 4000 "clearline"] + Line[325000 285000 455000 285000 1000 4000 "clearline"] + Line[420000 185000 420000 240000 1000 4000 "clearline"] + Line[455000 240000 455000 345000 1000 4000 "clearline"] + Text[340000 410000 0 200 "SC" "clearline"] + Text[345000 465000 1 200 "SOT" "clearline"] + Text[130000 600000 0 200 "HC" "clearline"] + Text[250000 760000 0 200 "TO" "clearline"] + Text[430000 1030000 0 200 "TO" "clearline"] + Text[230000 1030000 0 200 "LED" "clearline"] + Text[440000 950000 0 200 "HC" "clearline"] + Text[440000 330000 1 200 "TANT" "clearline"] + Text[440000 275000 1 200 "SOD" "clearline"] + Text[482500 300000 1 200 "DO" "clearline"] + Text[437500 222500 0 200 "minimelf" "clearline"] +) Index: tags/2.3.0/util/pcblib-map/parametric.pcb =================================================================== --- tags/2.3.0/util/pcblib-map/parametric.pcb (nonexistent) +++ tags/2.3.0/util/pcblib-map/parametric.pcb (revision 33253) @@ -0,0 +1,1153 @@ +# release: pcb 20110918 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 260000 120000] + +Grid[10000.0 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin,onlynames") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Symbol[' ' 1800] +( +) +Symbol['!' 1200] +( + SymbolLine[0 4500 0 5000 800] + SymbolLine[0 1000 0 3500 800] +) +Symbol['"' 1200] +( + SymbolLine[0 1000 0 2000 800] + SymbolLine[1000 1000 1000 2000 800] +) +Symbol['#' 1200] +( + SymbolLine[0 3500 2000 3500 800] + SymbolLine[0 2500 2000 2500 800] + SymbolLine[1500 2000 1500 4000 800] + SymbolLine[500 2000 500 4000 800] +) +Symbol['$' 1200] +( + SymbolLine[1500 1500 2000 2000 800] + SymbolLine[500 1500 1500 1500 800] + SymbolLine[0 2000 500 1500 800] + SymbolLine[0 2000 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4000 800] + SymbolLine[1500 4500 2000 4000 800] + SymbolLine[500 4500 1500 4500 800] + SymbolLine[0 4000 500 4500 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['%' 1200] +( + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[1000 2500 1500 2000 800] + SymbolLine[500 2500 1000 2500 800] + SymbolLine[0 2000 500 2500 800] + SymbolLine[0 5000 4000 1000 800] + SymbolLine[3500 5000 4000 4500 800] + SymbolLine[4000 4000 4000 4500 800] + SymbolLine[3500 3500 4000 4000 800] + SymbolLine[3000 3500 3500 3500 800] + SymbolLine[2500 4000 3000 3500 800] + SymbolLine[2500 4000 2500 4500 800] + SymbolLine[2500 4500 3000 5000 800] + SymbolLine[3000 5000 3500 5000 800] +) +Symbol['&' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 3500 1500 2000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[0 2500 2500 5000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[0 3500 0 4500 800] +) +Symbol[''' 1200] +( + SymbolLine[0 2000 1000 1000 800] +) +Symbol['(' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] +) +Symbol[')' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['*' 1200] +( + SymbolLine[0 2000 2000 4000 800] + SymbolLine[0 4000 2000 2000 800] + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol['+' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol[',' 1200] +( + SymbolLine[0 6000 1000 5000 800] +) +Symbol['-' 1200] +( + SymbolLine[0 3000 2000 3000 800] +) +Symbol['.' 1200] +( + SymbolLine[0 5000 500 5000 800] +) +Symbol['/' 1200] +( + SymbolLine[0 4500 3000 1500 800] +) +Symbol['0' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4000 2000 2000 800] +) +Symbol['1' 1200] +( + SymbolLine[0 1800 800 1000 800] + SymbolLine[800 1000 800 5000 800] + SymbolLine[0 5000 1500 5000 800] +) +Symbol['2' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[0 5000 2500 2500 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['3' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 2800 1500 2800 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[2000 3300 2000 4500 800] + SymbolLine[2000 3300 1500 2800 800] + SymbolLine[2000 2300 1500 2800 800] +) +Symbol['4' 1200] +( + SymbolLine[0 3500 2000 1000 800] + SymbolLine[0 3500 2500 3500 800] + SymbolLine[2000 1000 2000 5000 800] +) +Symbol['5' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[500 2500 1500 2500 800] + SymbolLine[1500 2500 2000 3000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['6' 1200] +( + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1500 2800 2000 3300 800] + SymbolLine[0 2800 1500 2800 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3300 2000 4500 800] +) +Symbol['7' 1200] +( + SymbolLine[500 5000 2500 1000 800] + SymbolLine[0 1000 2500 1000 800] +) +Symbol['8' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3700 0 4500 800] + SymbolLine[0 3700 700 3000 800] + SymbolLine[700 3000 1300 3000 800] + SymbolLine[1300 3000 2000 3700 800] + SymbolLine[2000 3700 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 2300 700 3000 800] + SymbolLine[0 1500 0 2300 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[1300 3000 2000 2300 800] +) +Symbol['9' 1200] +( + SymbolLine[500 5000 2000 3000 800] + SymbolLine[2000 1500 2000 3000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol[':' 1200] +( + SymbolLine[0 2500 500 2500 800] + SymbolLine[0 3500 500 3500 800] +) +Symbol[';' 1200] +( + SymbolLine[0 5000 1000 4000 800] + SymbolLine[1000 2500 1000 3000 800] +) +Symbol['<' 1200] +( + SymbolLine[0 3000 1000 2000 800] + SymbolLine[0 3000 1000 4000 800] +) +Symbol['=' 1200] +( + SymbolLine[0 2500 2000 2500 800] + SymbolLine[0 3500 2000 3500 800] +) +Symbol['>' 1200] +( + SymbolLine[0 2000 1000 3000 800] + SymbolLine[0 4000 1000 3000 800] +) +Symbol['?' 1200] +( + SymbolLine[1000 3000 1000 3500 800] + SymbolLine[1000 4500 1000 5000 800] + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2000 800] + SymbolLine[1000 3000 2000 2000 800] +) +Symbol['@' 1200] +( + SymbolLine[0 1000 0 4000 800] + SymbolLine[0 4000 1000 5000 800] + SymbolLine[1000 5000 4000 5000 800] + SymbolLine[5000 3500 5000 1000 800] + SymbolLine[5000 1000 4000 0 800] + SymbolLine[4000 0 1000 0 800] + SymbolLine[1000 0 0 1000 800] + SymbolLine[1500 2000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 3000 3500 800] + SymbolLine[3000 3500 3500 3000 800] + SymbolLine[3500 3000 4000 3500 800] + SymbolLine[3500 3000 3500 1500 800] + SymbolLine[3500 2000 3000 1500 800] + SymbolLine[2000 1500 3000 1500 800] + SymbolLine[2000 1500 1500 2000 800] + SymbolLine[4000 3500 5000 3500 800] +) +Symbol['A' 1200] +( + SymbolLine[0 2000 0 5000 800] + SymbolLine[0 2000 700 1000 800] + SymbolLine[700 1000 1800 1000 800] + SymbolLine[1800 1000 2500 2000 800] + SymbolLine[2500 2000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['B' 1200] +( + SymbolLine[0 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3300 2500 4500 800] + SymbolLine[2000 2800 2500 3300 800] + SymbolLine[500 2800 2000 2800 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2300 800] + SymbolLine[2000 2800 2500 2300 800] +) +Symbol['C' 1200] +( + SymbolLine[700 5000 2000 5000 800] + SymbolLine[0 4300 700 5000 800] + SymbolLine[0 1700 0 4300 800] + SymbolLine[0 1700 700 1000 800] + SymbolLine[700 1000 2000 1000 800] +) +Symbol['D' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[1800 1000 2500 1700 800] + SymbolLine[2500 1700 2500 4300 800] + SymbolLine[1800 5000 2500 4300 800] + SymbolLine[0 5000 1800 5000 800] + SymbolLine[0 1000 1800 1000 800] +) +Symbol['E' 1200] +( + SymbolLine[0 2800 1500 2800 800] + SymbolLine[0 5000 2000 5000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] +) +Symbol['F' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 2800 1500 2800 800] +) +Symbol['G' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[1000 3000 2000 3000 800] +) +Symbol['H' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[2500 1000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['I' 1200] +( + SymbolLine[0 1000 1000 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 1000 5000 800] +) +Symbol['J' 1200] +( + SymbolLine[700 1000 1500 1000 800] + SymbolLine[1500 1000 1500 4500 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 4500 0 4000 800] +) +Symbol['K' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3000 2000 1000 800] + SymbolLine[0 3000 2000 5000 800] +) +Symbol['L' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['M' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 1500 3000 800] + SymbolLine[1500 3000 3000 1000 800] + SymbolLine[3000 1000 3000 5000 800] +) +Symbol['N' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2500 5000 800] + SymbolLine[2500 1000 2500 5000 800] +) +Symbol['O' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['P' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol['Q' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1000 3500 2000 5000 800] +) +Symbol['R' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[1300 3000 2500 5000 800] +) +Symbol['S' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['T' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['U' 1200] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 1000 2000 4500 800] +) +Symbol['V' 1200] +( + SymbolLine[0 1000 1000 5000 800] + SymbolLine[1000 5000 2000 1000 800] +) +Symbol['W' 1200] +( + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 5000 800] + SymbolLine[500 5000 1500 3000 800] + SymbolLine[1500 3000 2500 5000 800] + SymbolLine[2500 5000 3000 3000 800] + SymbolLine[3000 3000 3000 1000 800] +) +Symbol['X' 1200] +( + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 1000 2500 5000 800] +) +Symbol['Y' 1200] +( + SymbolLine[0 1000 1000 3000 800] + SymbolLine[1000 3000 2000 1000 800] + SymbolLine[1000 3000 1000 5000 800] +) +Symbol['Z' 1200] +( + SymbolLine[0 1000 2500 1000 800] + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['[' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['\' 1200] +( + SymbolLine[0 1500 3000 4500 800] +) +Symbol[']' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['^' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1500 800] +) +Symbol['_' 1200] +( + SymbolLine[0 5000 2000 5000 800] +) +Symbol['a' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[2000 4500 2500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['b' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] +) +Symbol['c' 1200] +( + SymbolLine[500 3000 2000 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] +) +Symbol['d' 1200] +( + SymbolLine[2000 1000 2000 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] +) +Symbol['e' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[0 4000 2000 4000 800] + SymbolLine[2000 4000 2000 3500 800] +) +Symbol['f' 1000] +( + SymbolLine[500 1500 500 5000 800] + SymbolLine[500 1500 1000 1000 800] + SymbolLine[1000 1000 1500 1000 800] + SymbolLine[0 3000 1000 3000 800] +) +Symbol['g' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[2000 3000 2000 6000 800] +) +Symbol['h' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] +) +Symbol['i' 1000] +( + SymbolLine[0 2000 0 2100 1000] + SymbolLine[0 3500 0 5000 800] +) +Symbol['j' 1000] +( + SymbolLine[500 2000 500 2100 1000] + SymbolLine[500 3500 500 6000 800] + SymbolLine[0 6500 500 6000 800] +) +Symbol['k' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 1500 5000 800] + SymbolLine[0 3500 1000 2500 800] +) +Symbol['l' 1000] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['m' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[2000 3500 2500 3000 800] + SymbolLine[2500 3000 3000 3000 800] + SymbolLine[3000 3000 3500 3500 800] + SymbolLine[3500 3500 3500 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['n' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['o' 1200] +( + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['p' 1200] +( + SymbolLine[500 3500 500 6500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[1000 5000 2000 5000 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['q' 1200] +( + SymbolLine[2000 3500 2000 6500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['r' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['s' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2000 4000 2500 4500 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['t' 1000] +( + SymbolLine[500 1000 500 4500 800] + SymbolLine[500 4500 1000 5000 800] + SymbolLine[0 2500 1000 2500 800] +) +Symbol['u' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3000 2000 4500 800] +) +Symbol['v' 1200] +( + SymbolLine[0 3000 1000 5000 800] + SymbolLine[2000 3000 1000 5000 800] +) +Symbol['w' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[1500 3000 1500 4500 800] + SymbolLine[1500 4500 2000 5000 800] + SymbolLine[2000 5000 2500 5000 800] + SymbolLine[2500 5000 3000 4500 800] + SymbolLine[3000 3000 3000 4500 800] +) +Symbol['x' 1200] +( + SymbolLine[0 3000 2000 5000 800] + SymbolLine[0 5000 2000 3000 800] +) +Symbol['y' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 6000 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['z' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[0 5000 2000 3000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['{' 1200] +( + SymbolLine[500 1500 1000 1000 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['|' 1200] +( + SymbolLine[0 1000 0 5000 800] +) +Symbol['}' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[500 2500 1000 3000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['~' 1200] +( + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1000 3000 800] + SymbolLine[1000 3000 1500 3500 800] + SymbolLine[1500 3500 2000 3500 800] + SymbolLine[2000 3500 2500 3000 800] +) +Attribute("PCB::grid::unit" "mil") +Via[260000 120000 7874 4000 0 3150 "" ""] + +Element["" "rcy(150, bar-sign)" "C1" "acy150" 22500 95000 -2000 -4500 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -15000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -28500 0 -24500 1000] + ElementLine [0 9500 0 13500 1000] + ElementLine [-2000 11500 2000 11500 1000] + ElementLine [7874 -17883 7874 -11250 3937] + ElementLine [-7874 -17883 -7874 -11250 3937] + ElementLine [9842 -16040 9842 -11250 3937] + ElementLine [-9842 -16040 -9842 -11250 3937] + ElementLine [11811 -13006 11811 -11250 3937] + ElementLine [-11811 -13006 -11811 -11250 3937] + ElementArc [0 -7500 15000 15000 90 360 1000] + + ) + +Element["" "so(8)" "" "8*250" 57500 82500 -10000 0 1 100 ""] +( + Pad[-7500 7000 -7500 13500 2000 1000 3000 "" "1" "square,edge2"] + Pad[-7500 -13500 -7500 -7000 2000 1000 3000 "" "8" "square"] + Pad[-2500 7000 -2500 13500 2000 1000 3000 "" "2" "square,edge2"] + Pad[-2500 -13500 -2500 -7000 2000 1000 3000 "" "7" "square"] + Pad[2500 7000 2500 13500 2000 1000 3000 "" "3" "square,edge2"] + Pad[2500 -13500 2500 -7000 2000 1000 3000 "" "6" "square"] + Pad[7500 7000 7500 13500 2000 1000 3000 "" "4" "square,edge2"] + Pad[7500 -13500 7500 -7000 2000 1000 3000 "" "5" "square"] + ElementLine [-10000 16000 10000 16000 1000] + ElementLine [10000 -16000 10000 16000 1000] + ElementLine [-10000 -16000 10000 -16000 1000] + ElementLine [-10000 2500 -10000 16000 1000] + ElementLine [-10000 -16000 -10000 -2500 1000] + ElementArc [-10000 0 2500 2500 90 180 1000] + + ) + +Element["" "dip(4)" "" "4*300" 85000 102500 -10000 0 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "4" ""] + Pin[10000 0 8000 5000 8600 3937 "" "2" ""] + Pin[10000 -30000 8000 5000 8600 3937 "" "3" ""] + ElementLine [-5000 5000 15000 5000 1000] + ElementLine [15000 -35000 15000 5000 1000] + ElementLine [-5000 -35000 15000 -35000 1000] + ElementLine [-5000 -10000 -5000 5000 1000] + ElementLine [-5000 -35000 -5000 -20000 1000] + ElementArc [-5000 -15000 5000 5000 90 180 1000] + + ) + +Element["" "tssop(8)" "" "8*6.4mm" 117500 82500 -10000 0 1 100 ""] +( + Pad[-3838 10236 -3838 14173 1771 1000 3000 "" "1" "square,edge2"] + Pad[-3838 -14173 -3838 -10236 1771 1000 3000 "" "8" "square"] + Pad[-1278 10236 -1278 14173 1771 1000 3000 "" "2" "square,edge2"] + Pad[-1278 -14173 -1278 -10236 1771 1000 3000 "" "7" "square"] + Pad[1280 10236 1280 14173 1771 1000 3000 "" "3" "square,edge2"] + Pad[1280 -14173 1280 -10236 1771 1000 3000 "" "6" "square"] + Pad[3839 10236 3839 14173 1771 1000 3000 "" "4" "square,edge2"] + Pad[3839 -14173 3839 -10236 1771 1000 3000 "" "5" "square"] + ElementLine [-6038 15973 6039 15973 1000] + ElementLine [6039 -15973 6039 15973 1000] + ElementLine [-6038 -15973 6039 -15973 1000] + ElementLine [-6038 2500 -6038 15973 1000] + ElementLine [-6038 -15973 -6038 -2500 1000] + ElementArc [-6038 0 2500 2500 90 180 1000] + + ) + +Element["" "connector(2,3)" "" "2*3" 142500 72500 0 -10000 0 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 10000 8000 5000 8600 3937 "" "2" ""] + Pin[0 20000 8000 5000 8600 3937 "" "3" ""] + Pin[10000 0 8000 5000 8600 3937 "" "4" ""] + Pin[10000 10000 8000 5000 8600 3937 "" "5" ""] + Pin[10000 20000 8000 5000 8600 3937 "" "6" ""] + ElementLine [-5000 -5000 -5000 25000 1000] + ElementLine [-5000 -5000 15000 -5000 1000] + ElementLine [15000 25000 -5000 25000 1000] + ElementLine [15000 25000 15000 -5000 1000] + ElementLine [-5000 5000 5000 5000 1000] + ElementLine [5000 -5000 5000 5000 1000] + + ) + +Element["" "connector(2,3,eshift=x)" "" "2*3" 175000 72500 0 -10000 0 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 10000 8000 5000 8600 3937 "" "2" ""] + Pin[0 20000 8000 5000 8600 3937 "" "3" ""] + Pin[10000 5000 8000 5000 8600 3937 "" "4" ""] + Pin[10000 15000 8000 5000 8600 3937 "" "5" ""] + Pin[10000 25000 8000 5000 8600 3937 "" "6" ""] + ElementLine [-5000 -5000 -5000 30000 1000] + ElementLine [-5000 -5000 15000 -5000 1000] + ElementLine [15000 30000 -5000 30000 1000] + ElementLine [15000 30000 15000 -5000 1000] + ElementLine [-5000 5000 5000 5000 1000] + ElementLine [5000 -5000 5000 5000 1000] + + ) + +Element["" "connector(2,3,eshift=x,etrunc=1)" "" "2*3" 207500 72500 0 -10000 0 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 10000 8000 5000 8600 3937 "" "2" ""] + Pin[0 20000 8000 5000 8600 3937 "" "3" ""] + Pin[10000 5000 8000 5000 8600 3937 "" "4" ""] + Pin[10000 15000 8000 5000 8600 3937 "" "5" ""] + ElementLine [-5000 -5000 -5000 25000 1000] + ElementLine [-5000 -5000 15000 -5000 1000] + ElementLine [15000 25000 -5000 25000 1000] + ElementLine [15000 25000 15000 -5000 1000] + ElementLine [-5000 5000 5000 5000 1000] + ElementLine [5000 -5000 5000 5000 1000] + + ) + +Element["" "acy(300)" "" "acy300" 20000 50000 -12000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-2500 -22500 -2500 -7500 1000] + ElementLine [2500 -22500 2500 -7500 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + + ) + +Element["" "acy(300, endcap)" "" "acy300" 40000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [2500 -20625 2500 -9375 1000] + ElementLine [2500 -9375 3000 -9166 1000] + ElementLine [2500 -20625 3000 -20833 1000] + ElementLine [-2500 -20625 -2500 -9375 1000] + ElementLine [-2500 -9375 -3000 -9166 1000] + ElementLine [-2500 -20625 -3000 -20833 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-3000 -9166 -3000 -8000 1000] + ElementLine [3000 -9166 3000 -8000 1000] + ElementLine [-3000 -22000 -3000 -20833 1000] + ElementLine [3000 -22000 3000 -20833 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + ElementArc [-2500 -8000 500 500 0 90 1000] + ElementArc [2500 -8000 500 500 90 90 1000] + ElementArc [-2500 -22000 500 500 270 90 1000] + ElementArc [2500 -22000 500 500 180 90 1000] + + ) + +Element["" "acy(300, coil, dot)" "" "acy300" 60000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementArc [0 -9375 1875 1875 270 180 1000] + ElementArc [0 -13125 1875 1875 270 180 1000] + ElementArc [0 -16875 1875 1875 270 180 1000] + ElementArc [0 -20625 1875 1875 270 180 1000] + ElementArc [-1250 -5500 666 666 90 360 1000] + + ) + +Element["" "acy(300, pol=bar)" "" "acy300" 80000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-2500 -22500 -2500 -7500 1000] + ElementLine [2500 -22500 2500 -7500 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + ElementLine [-2500 -6500 2500 -6500 1000] + ElementLine [-2500 -8500 -2500 -6500 1000] + ElementLine [2500 -8500 2500 -6500 1000] + ElementLine [-2500 -8500 2500 -8500 1000] + + ) + +Element["" "acy(300, wiper=aarrow)" "" "acy300" 100000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-2500 -22500 -2500 -7500 1000] + ElementLine [2500 -22500 2500 -7500 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + ElementLine [5000 -12500 -8000 -17500 1000] + ElementLine [-8000 -17500 -6492 -15848 1000] + ElementLine [-8000 -17500 -5774 -17715 1000] + ElementLine [-5774 -17715 -6492 -15848 1000] + + ) + +Element["" "acy(300, wiper=parrow)" "" "acy300" 120000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-2500 -22500 -2500 -7500 1000] + ElementLine [2500 -22500 2500 -7500 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + ElementLine [-8000 -15000 -2500 -15000 1000] + ElementLine [-2500 -15000 -4500 -16000 1000] + ElementLine [-2500 -15000 -4500 -14000 1000] + ElementLine [-4500 -16000 -4500 -14000 1000] + + ) + +Element["" "acy(300, wiper=looparrow)" "" "acy300" 140000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-2500 -7500 2500 -7500 1000] + ElementLine [-2500 -22500 -2500 -7500 1000] + ElementLine [2500 -22500 2500 -7500 1000] + ElementLine [-2500 -22500 2500 -22500 1000] + ElementLine [-8000 -15000 -2500 -15000 1000] + ElementLine [-2500 -15000 -4500 -16000 1000] + ElementLine [-2500 -15000 -4500 -14000 1000] + ElementLine [-4500 -16000 -4500 -14000 1000] + ElementLine [-8000 -24375 -8000 -15000 1000] + ElementLine [-8000 -24375 0 -24375 1000] + + ) + +Element["" "acy(300, zigzag)" "" "acy300" 160000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [0 -7500 -2500 -8750 1000] + ElementLine [-2500 -8750 2500 -11250 1000] + ElementLine [2500 -11250 0 -12500 1000] + ElementLine [0 -12500 -2500 -13750 1000] + ElementLine [-2500 -13750 2500 -16250 1000] + ElementLine [2500 -16250 0 -17500 1000] + ElementLine [0 -17500 -2500 -18750 1000] + ElementLine [-2500 -18750 2500 -21250 1000] + ElementLine [2500 -21250 0 -22500 1000] + + ) + +Element["" "acy(300, core)" "" "acy300" 180000 50000 -2000 -9000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -7500 0 0 1000] + ElementLine [0 -30000 0 -22500 1000] + ElementLine [-4875 -22500 -4875 -7500 1000] + ElementArc [0 -9375 1875 1875 270 180 1000] + ElementArc [0 -13125 1875 1875 270 180 1000] + ElementArc [0 -16875 1875 1875 270 180 1000] + ElementArc [0 -20625 1875 1875 270 180 1000] + + ) + +Element["" "acy(200, standing, pol=sign, dia=100)" "" "acy200" 240000 90000 -2000 -6000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -20000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -5000 0 0 1000] + ElementLine [0 -20000 0 -15000 1000] + ElementLine [0 -20000 0 0 1000] + ElementLine [2200 -6100 2200 -4100 1000] + ElementLine [2200 -15900 2200 -13900 1000] + ElementLine [1200 -14900 3200 -14900 1000] + ElementArc [0 0 10000 10000 90 360 1000] + + ) + +Element["" "alf(300,schottky)" "" "acy300" 200000 50000 -5000 -22000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -10000 0 0 1000] + ElementLine [0 -30000 0 -20000 1000] + ElementLine [-5000 -20000 5000 -20000 1000] + ElementLine [-5000 -20000 0 -10000 1000] + ElementLine [5000 -20000 0 -10000 1000] + ElementLine [-3500 -10000 3500 -10000 1000] + ElementArc [-3500 -11500 1500 1500 270 180 1000] + ElementArc [3500 -8500 1500 1500 90 180 1000] + + ) + +Element["" "alf(300,tunnel)" "" "acy300" 220000 50000 -5000 -22000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -10000 0 0 1000] + ElementLine [0 -30000 0 -20000 1000] + ElementLine [-5000 -20000 5000 -20000 1000] + ElementLine [-5000 -20000 0 -10000 1000] + ElementLine [5000 -20000 0 -10000 1000] + ElementLine [-5000 -10000 5000 -10000 1000] + ElementLine [5000 -11500 5000 -10000 1000] + ElementLine [-5000 -11500 -5000 -10000 1000] + + ) + +Element["" "alf(300,zener)" "" "acy300" 240000 50000 -5000 -22000 1 100 ""] +( + Pin[0 0 8000 5000 8600 3937 "" "1" "square"] + Pin[0 -30000 8000 5000 8600 3937 "" "2" ""] + ElementLine [0 -10000 0 0 1000] + ElementLine [0 -30000 0 -20000 1000] + ElementLine [-5000 -20000 5000 -20000 1000] + ElementLine [-5000 -20000 0 -10000 1000] + ElementLine [5000 -20000 0 -10000 1000] + ElementLine [-5000 -10000 5000 -10000 1000] + ElementLine [5000 -10000 5000 -8500 1000] + ElementLine [-5000 -11500 -5000 -10000 1000] + + ) +Layer(1 "component") +( +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) Index: tags/2.3.0/util/pcblib-map/smd2.pcb =================================================================== --- tags/2.3.0/util/pcblib-map/smd2.pcb (nonexistent) +++ tags/2.3.0/util/pcblib-map/smd2.pcb (revision 33253) @@ -0,0 +1,1086 @@ +# release: pcb 20110918 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 170000 160000] + +Grid[2500.0 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Symbol[' ' 1800] +( +) +Symbol['!' 1200] +( + SymbolLine[0 4500 0 5000 800] + SymbolLine[0 1000 0 3500 800] +) +Symbol['"' 1200] +( + SymbolLine[0 1000 0 2000 800] + SymbolLine[1000 1000 1000 2000 800] +) +Symbol['#' 1200] +( + SymbolLine[0 3500 2000 3500 800] + SymbolLine[0 2500 2000 2500 800] + SymbolLine[1500 2000 1500 4000 800] + SymbolLine[500 2000 500 4000 800] +) +Symbol['$' 1200] +( + SymbolLine[1500 1500 2000 2000 800] + SymbolLine[500 1500 1500 1500 800] + SymbolLine[0 2000 500 1500 800] + SymbolLine[0 2000 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4000 800] + SymbolLine[1500 4500 2000 4000 800] + SymbolLine[500 4500 1500 4500 800] + SymbolLine[0 4000 500 4500 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['%' 1200] +( + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[1000 2500 1500 2000 800] + SymbolLine[500 2500 1000 2500 800] + SymbolLine[0 2000 500 2500 800] + SymbolLine[0 5000 4000 1000 800] + SymbolLine[3500 5000 4000 4500 800] + SymbolLine[4000 4000 4000 4500 800] + SymbolLine[3500 3500 4000 4000 800] + SymbolLine[3000 3500 3500 3500 800] + SymbolLine[2500 4000 3000 3500 800] + SymbolLine[2500 4000 2500 4500 800] + SymbolLine[2500 4500 3000 5000 800] + SymbolLine[3000 5000 3500 5000 800] +) +Symbol['&' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 3500 1500 2000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[0 2500 2500 5000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[0 3500 0 4500 800] +) +Symbol[''' 1200] +( + SymbolLine[0 2000 1000 1000 800] +) +Symbol['(' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] +) +Symbol[')' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['*' 1200] +( + SymbolLine[0 2000 2000 4000 800] + SymbolLine[0 4000 2000 2000 800] + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol['+' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol[',' 1200] +( + SymbolLine[0 6000 1000 5000 800] +) +Symbol['-' 1200] +( + SymbolLine[0 3000 2000 3000 800] +) +Symbol['.' 1200] +( + SymbolLine[0 5000 500 5000 800] +) +Symbol['/' 1200] +( + SymbolLine[0 4500 3000 1500 800] +) +Symbol['0' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4000 2000 2000 800] +) +Symbol['1' 1200] +( + SymbolLine[0 1800 800 1000 800] + SymbolLine[800 1000 800 5000 800] + SymbolLine[0 5000 1500 5000 800] +) +Symbol['2' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[0 5000 2500 2500 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['3' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 2800 1500 2800 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[2000 3300 2000 4500 800] + SymbolLine[2000 3300 1500 2800 800] + SymbolLine[2000 2300 1500 2800 800] +) +Symbol['4' 1200] +( + SymbolLine[0 3500 2000 1000 800] + SymbolLine[0 3500 2500 3500 800] + SymbolLine[2000 1000 2000 5000 800] +) +Symbol['5' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[500 2500 1500 2500 800] + SymbolLine[1500 2500 2000 3000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['6' 1200] +( + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1500 2800 2000 3300 800] + SymbolLine[0 2800 1500 2800 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3300 2000 4500 800] +) +Symbol['7' 1200] +( + SymbolLine[500 5000 2500 1000 800] + SymbolLine[0 1000 2500 1000 800] +) +Symbol['8' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3700 0 4500 800] + SymbolLine[0 3700 700 3000 800] + SymbolLine[700 3000 1300 3000 800] + SymbolLine[1300 3000 2000 3700 800] + SymbolLine[2000 3700 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 2300 700 3000 800] + SymbolLine[0 1500 0 2300 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[1300 3000 2000 2300 800] +) +Symbol['9' 1200] +( + SymbolLine[500 5000 2000 3000 800] + SymbolLine[2000 1500 2000 3000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol[':' 1200] +( + SymbolLine[0 2500 500 2500 800] + SymbolLine[0 3500 500 3500 800] +) +Symbol[';' 1200] +( + SymbolLine[0 5000 1000 4000 800] + SymbolLine[1000 2500 1000 3000 800] +) +Symbol['<' 1200] +( + SymbolLine[0 3000 1000 2000 800] + SymbolLine[0 3000 1000 4000 800] +) +Symbol['=' 1200] +( + SymbolLine[0 2500 2000 2500 800] + SymbolLine[0 3500 2000 3500 800] +) +Symbol['>' 1200] +( + SymbolLine[0 2000 1000 3000 800] + SymbolLine[0 4000 1000 3000 800] +) +Symbol['?' 1200] +( + SymbolLine[1000 3000 1000 3500 800] + SymbolLine[1000 4500 1000 5000 800] + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2000 800] + SymbolLine[1000 3000 2000 2000 800] +) +Symbol['@' 1200] +( + SymbolLine[0 1000 0 4000 800] + SymbolLine[0 4000 1000 5000 800] + SymbolLine[1000 5000 4000 5000 800] + SymbolLine[5000 3500 5000 1000 800] + SymbolLine[5000 1000 4000 0 800] + SymbolLine[4000 0 1000 0 800] + SymbolLine[1000 0 0 1000 800] + SymbolLine[1500 2000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 3000 3500 800] + SymbolLine[3000 3500 3500 3000 800] + SymbolLine[3500 3000 4000 3500 800] + SymbolLine[3500 3000 3500 1500 800] + SymbolLine[3500 2000 3000 1500 800] + SymbolLine[2000 1500 3000 1500 800] + SymbolLine[2000 1500 1500 2000 800] + SymbolLine[4000 3500 5000 3500 800] +) +Symbol['A' 1200] +( + SymbolLine[0 2000 0 5000 800] + SymbolLine[0 2000 700 1000 800] + SymbolLine[700 1000 1800 1000 800] + SymbolLine[1800 1000 2500 2000 800] + SymbolLine[2500 2000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['B' 1200] +( + SymbolLine[0 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3300 2500 4500 800] + SymbolLine[2000 2800 2500 3300 800] + SymbolLine[500 2800 2000 2800 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2300 800] + SymbolLine[2000 2800 2500 2300 800] +) +Symbol['C' 1200] +( + SymbolLine[700 5000 2000 5000 800] + SymbolLine[0 4300 700 5000 800] + SymbolLine[0 1700 0 4300 800] + SymbolLine[0 1700 700 1000 800] + SymbolLine[700 1000 2000 1000 800] +) +Symbol['D' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[1800 1000 2500 1700 800] + SymbolLine[2500 1700 2500 4300 800] + SymbolLine[1800 5000 2500 4300 800] + SymbolLine[0 5000 1800 5000 800] + SymbolLine[0 1000 1800 1000 800] +) +Symbol['E' 1200] +( + SymbolLine[0 2800 1500 2800 800] + SymbolLine[0 5000 2000 5000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] +) +Symbol['F' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 2800 1500 2800 800] +) +Symbol['G' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[1000 3000 2000 3000 800] +) +Symbol['H' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[2500 1000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['I' 1200] +( + SymbolLine[0 1000 1000 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 1000 5000 800] +) +Symbol['J' 1200] +( + SymbolLine[700 1000 1500 1000 800] + SymbolLine[1500 1000 1500 4500 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 4500 0 4000 800] +) +Symbol['K' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3000 2000 1000 800] + SymbolLine[0 3000 2000 5000 800] +) +Symbol['L' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['M' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 1500 3000 800] + SymbolLine[1500 3000 3000 1000 800] + SymbolLine[3000 1000 3000 5000 800] +) +Symbol['N' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2500 5000 800] + SymbolLine[2500 1000 2500 5000 800] +) +Symbol['O' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['P' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol['Q' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1000 3500 2000 5000 800] +) +Symbol['R' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[1300 3000 2500 5000 800] +) +Symbol['S' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['T' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['U' 1200] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 1000 2000 4500 800] +) +Symbol['V' 1200] +( + SymbolLine[0 1000 1000 5000 800] + SymbolLine[1000 5000 2000 1000 800] +) +Symbol['W' 1200] +( + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 5000 800] + SymbolLine[500 5000 1500 3000 800] + SymbolLine[1500 3000 2500 5000 800] + SymbolLine[2500 5000 3000 3000 800] + SymbolLine[3000 3000 3000 1000 800] +) +Symbol['X' 1200] +( + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 1000 2500 5000 800] +) +Symbol['Y' 1200] +( + SymbolLine[0 1000 1000 3000 800] + SymbolLine[1000 3000 2000 1000 800] + SymbolLine[1000 3000 1000 5000 800] +) +Symbol['Z' 1200] +( + SymbolLine[0 1000 2500 1000 800] + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['[' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['\' 1200] +( + SymbolLine[0 1500 3000 4500 800] +) +Symbol[']' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['^' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1500 800] +) +Symbol['_' 1200] +( + SymbolLine[0 5000 2000 5000 800] +) +Symbol['a' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[2000 4500 2500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['b' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] +) +Symbol['c' 1200] +( + SymbolLine[500 3000 2000 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] +) +Symbol['d' 1200] +( + SymbolLine[2000 1000 2000 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] +) +Symbol['e' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[0 4000 2000 4000 800] + SymbolLine[2000 4000 2000 3500 800] +) +Symbol['f' 1000] +( + SymbolLine[500 1500 500 5000 800] + SymbolLine[500 1500 1000 1000 800] + SymbolLine[1000 1000 1500 1000 800] + SymbolLine[0 3000 1000 3000 800] +) +Symbol['g' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[2000 3000 2000 6000 800] +) +Symbol['h' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] +) +Symbol['i' 1000] +( + SymbolLine[0 2000 0 2100 1000] + SymbolLine[0 3500 0 5000 800] +) +Symbol['j' 1000] +( + SymbolLine[500 2000 500 2100 1000] + SymbolLine[500 3500 500 6000 800] + SymbolLine[0 6500 500 6000 800] +) +Symbol['k' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 1500 5000 800] + SymbolLine[0 3500 1000 2500 800] +) +Symbol['l' 1000] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['m' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[2000 3500 2500 3000 800] + SymbolLine[2500 3000 3000 3000 800] + SymbolLine[3000 3000 3500 3500 800] + SymbolLine[3500 3500 3500 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['n' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['o' 1200] +( + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['p' 1200] +( + SymbolLine[500 3500 500 6500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[1000 5000 2000 5000 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['q' 1200] +( + SymbolLine[2000 3500 2000 6500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['r' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['s' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2000 4000 2500 4500 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['t' 1000] +( + SymbolLine[500 1000 500 4500 800] + SymbolLine[500 4500 1000 5000 800] + SymbolLine[0 2500 1000 2500 800] +) +Symbol['u' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3000 2000 4500 800] +) +Symbol['v' 1200] +( + SymbolLine[0 3000 1000 5000 800] + SymbolLine[2000 3000 1000 5000 800] +) +Symbol['w' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[1500 3000 1500 4500 800] + SymbolLine[1500 4500 2000 5000 800] + SymbolLine[2000 5000 2500 5000 800] + SymbolLine[2500 5000 3000 4500 800] + SymbolLine[3000 3000 3000 4500 800] +) +Symbol['x' 1200] +( + SymbolLine[0 3000 2000 5000 800] + SymbolLine[0 5000 2000 3000 800] +) +Symbol['y' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 6000 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['z' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[0 5000 2000 3000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['{' 1200] +( + SymbolLine[500 1500 1000 1000 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['|' 1200] +( + SymbolLine[0 1000 0 5000 800] +) +Symbol['}' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[500 2500 1000 3000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['~' 1200] +( + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1000 3000 800] + SymbolLine[1000 3000 1500 3500 800] + SymbolLine[1500 3500 2000 3500 800] + SymbolLine[2000 3500 2500 3000 800] +) +Attribute("PCB::grid::unit" "mil") +Via[170000 160000 7874 4000 0 3150 "" ""] + +Element["" "Standard SMT resistor, capacitor etc" "" "01005" 5000 10000 -3150 3150 1 100 ""] +( + Pad[-19 807 19 807 984 2000 1584 "1" "1" "square"] + Pad[-19 -807 19 -807 984 2000 1584 "2" "2" "square"] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "0201" 10000 10000 -3150 3150 1 100 ""] +( + Pad[0 1181 0 1181 1574 2000 2174 "1" "1" "square"] + Pad[0 -1181 0 -1181 1574 2000 2174 "2" "2" "square"] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "0402" 15000 10000 -3150 3150 1 100 ""] +( + Pad[-393 1574 393 1574 1968 2000 2568 "1" "1" "square"] + Pad[-393 -1574 393 -1574 1968 2000 2568 "2" "2" "square"] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "0603" 25000 10000 -3150 3150 1 100 ""] +( + Pad[-492 2559 492 2559 2952 2000 3552 "1" "1" "square"] + Pad[-492 -2559 492 -2559 2952 2000 3552 "2" "2" "square"] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "0805" 35000 10000 -3150 3150 1 100 ""] +( + Pad[-393 3543 393 3543 5118 2000 5718 "1" "1" "square"] + Pad[-393 -3543 393 -3543 5118 2000 5718 "2" "2" "square"] + ElementLine [-2755 -393 -2755 393 800] + ElementLine [2755 -393 2755 393 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "1008" 50000 10000 -3150 3150 1 100 ""] +( + Pad[-2362 5118 2362 5118 4330 2000 4930 "1" "1" "square"] + Pad[-2362 -5118 2362 -5118 4330 2000 4930 "2" "2" "square"] + ElementLine [-4527 -1377 -4527 1377 800] + ElementLine [4527 -1377 4527 1377 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "1206" 65000 10000 -3150 3150 1 100 ""] +( + Pad[-1181 5905 1181 5905 5118 2000 5718 "1" "1" "square"] + Pad[-1181 -5905 1181 -5905 5118 2000 5718 "2" "2" "square"] + ElementLine [-3740 -2362 -3740 2362 800] + ElementLine [3740 -2362 3740 2362 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "1210" 80000 10000 -3150 3150 1 100 ""] +( + Pad[-2755 5905 2755 5905 5118 2000 5718 "1" "1" "square"] + Pad[-2755 -5905 2755 -5905 5118 2000 5718 "2" "2" "square"] + ElementLine [-5314 -1968 -5314 1968 800] + ElementLine [5314 -1968 5314 1968 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "1806" 10000 35000 -3150 3150 1 100 ""] +( + Pad[-3543 7874 3543 7874 6299 2000 6899 "1" "1" "square"] + Pad[-3543 -7874 3543 -7874 6299 2000 6899 "2" "2" "square"] + ElementLine [-6692 -3149 -6692 3149 800] + ElementLine [6692 -3149 6692 3149 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "1825" 35000 35000 -3150 3150 1 100 ""] +( + Pad[-10236 7874 10236 7874 6299 2000 6899 "1" "1" "square"] + Pad[-10236 -7874 10236 -7874 6299 2000 6899 "2" "2" "square"] + ElementLine [-13385 -3149 -13385 3149 800] + ElementLine [13385 -3149 13385 3149 800] + + ) + +Element["" "Standard SMT resistor, capacitor etc" "" "2706" 70000 35000 -17900 0 1 100 ""] +( + Pad[10800 -300 10800 300 7800 2000 8400 "1" "1" "square"] + Pad[-10800 -300 -10800 300 7800 2000 8400 "2" "2" "square"] + ElementLine [15900 -5400 15900 5400 1000] + ElementLine [-15900 -5400 15900 -5400 1000] + ElementLine [-15900 -5400 -15900 5400 1000] + ElementLine [-15900 5400 15900 5400 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "DO214" 145000 85000 0 22100 2 100 ""] +( + Pad[-1900 -10600 1900 -10600 14000 2000 14600 "1" "1" "square"] + Pad[-1900 10600 1900 10600 14000 2000 14600 "2" "2" "square"] + ElementLine [-8900 -21100 8900 -21100 2000] + ElementLine [-8900 -21100 -11400 -14100 1000] + ElementLine [-11400 -14100 -11400 20100 1000] + ElementLine [-11400 20100 11400 20100 1000] + ElementLine [11400 -14100 11400 20100 1000] + ElementLine [11400 -14100 8900 -21100 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "DO214AB" 145000 135000 0 22700 2 100 ""] +( + Pad[-2000 -10900 2000 -10900 14500 2000 15100 "1" "1" "square"] + Pad[-2000 10900 2000 10900 14500 2000 15100 "2" "2" "square"] + ElementLine [-9200 -21700 9200 -21700 2000] + ElementLine [-9200 -21700 -11800 -14500 1000] + ElementLine [-11800 -14500 -11800 20700 1000] + ElementLine [-11800 20700 11800 20700 1000] + ElementLine [11800 -14500 11800 20700 1000] + ElementLine [11800 -14500 9200 -21700 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD106A" 100000 80000 0 16600 2 100 ""] +( + Pad[-1700 -7600 1700 -7600 10200 2000 10800 "1" "1" "square"] + Pad[-1700 7600 1700 7600 10200 2000 10800 "2" "2" "square"] + ElementLine [-6800 -15600 6800 -15600 2000] + ElementLine [-6800 -15600 -8700 -10500 1000] + ElementLine [-8700 -10500 -8700 14600 1000] + ElementLine [-8700 14600 8700 14600 1000] + ElementLine [8700 -10500 8700 14600 1000] + ElementLine [8700 -10500 6800 -15600 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD110" 10000 80000 0 8300 2 100 ""] +( + Pad[-1500 -2900 1500 -2900 4600 2000 5200 "1" "1" "square"] + Pad[-1500 2900 1500 2900 4600 2000 5200 "2" "2" "square"] + ElementLine [-3800 -7300 3800 -7300 2000] + ElementLine [-3800 -7300 -4900 -5000 1000] + ElementLine [-4900 -5000 -4900 6300 1000] + ElementLine [-4900 6300 4900 6300 1000] + ElementLine [4900 -5000 4900 6300 1000] + ElementLine [4900 -5000 3800 -7300 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD123" 55000 80000 0 12000 2 100 ""] +( + Pad[-600 -5500 600 -5500 6900 2000 7500 "1" "1" "square"] + Pad[-600 5500 600 5500 6900 2000 7500 "2" "2" "square"] + ElementLine [-4000 -11000 4000 -11000 2000] + ElementLine [-4000 -11000 -5100 -7600 1000] + ElementLine [-5100 -7600 -5100 10000 1000] + ElementLine [-5100 10000 5100 10000 1000] + ElementLine [5100 -7600 5100 10000 1000] + ElementLine [5100 -7600 4000 -11000 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD323" 25000 80000 0 9300 2 100 ""] +( + Pad[-1000 -3700 1000 -3700 5100 2000 5700 "1" "1" "square"] + Pad[-1000 3700 1000 3700 5100 2000 5700 "2" "2" "square"] + ElementLine [-3500 -8300 3500 -8300 2000] + ElementLine [-3500 -8300 -4500 -5800 1000] + ElementLine [-4500 -5800 -4500 7300 1000] + ElementLine [-4500 7300 4500 7300 1000] + ElementLine [4500 -5800 4500 7300 1000] + ElementLine [4500 -5800 3500 -8300 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD80" 40000 80000 0 11600 2 100 ""] +( + Pad[-1600 -5800 1600 -5800 5300 2000 5900 "1" "1" "square"] + Pad[-1600 5800 1600 5800 5300 2000 5900 "2" "2" "square"] + ElementLine [-4300 -10600 4300 -10600 2000] + ElementLine [-4300 -10600 -5500 -8000 1000] + ElementLine [-5500 -8000 -5500 9600 1000] + ElementLine [-5500 9600 5500 9600 1000] + ElementLine [5500 -8000 5500 9600 1000] + ElementLine [5500 -8000 4300 -10600 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOD87" 75000 80000 0 12400 2 100 ""] +( + Pad[-2600 -5800 2600 -5800 6100 2000 6700 "1" "1" "square"] + Pad[-2600 5800 2600 5800 6100 2000 6700 "2" "2" "square"] + ElementLine [-5700 -11400 5700 -11400 2000] + ElementLine [-5700 -11400 -7300 -8400 1000] + ElementLine [-7300 -8400 -7300 10400 1000] + ElementLine [-7300 10400 7300 10400 1000] + ElementLine [7300 -8400 7300 10400 1000] + ElementLine [7300 -8400 5700 -11400 1000] + + ) + +Element["" "Tantalum SMT capacitor (pin 1 is +)" "" "TANT_A" 105000 140000 0 10600 2 100 ""] +( + Pad[-1800 -5000 1800 -5000 4900 2000 5500 "1" "1" "square"] + Pad[-1800 5000 1800 5000 4900 2000 5500 "2" "2" "square"] + ElementLine [-4300 -9600 4300 -9600 2000] + ElementLine [-4300 -9600 -5500 -7200 1000] + ElementLine [-5500 -7200 -5500 8600 1000] + ElementLine [-5500 8600 5500 8600 1000] + ElementLine [5500 -7200 5500 8600 1000] + ElementLine [5500 -7200 4300 -9600 1000] + + ) + +Element["" "Tantalum SMT capacitor (pin 1 is +)" "" "TANT_B" 80000 140000 0 13200 2 100 ""] +( + Pad[-4100 -5500 4100 -5500 7100 2000 7700 "1" "1" "square"] + Pad[-4100 5500 4100 5500 7100 2000 7700 "2" "2" "square"] + ElementLine [-7700 -12200 7700 -12200 2000] + ElementLine [-7700 -12200 -9900 -8700 1000] + ElementLine [-9900 -8700 -9900 11200 1000] + ElementLine [-9900 11200 9900 11200 1000] + ElementLine [9900 -8700 9900 11200 1000] + ElementLine [9900 -8700 7700 -12200 1000] + + ) + +Element["" "Tantalum SMT capacitor (pin 1 is +)" "" "TANT_C" 50000 135000 0 18800 2 100 ""] +( + Pad[-3900 -9400 3900 -9400 9700 2000 10300 "1" "1" "square"] + Pad[-3900 9400 3900 9400 9700 2000 10300 "2" "2" "square"] + ElementLine [-8700 -17800 8700 -17800 2000] + ElementLine [-8700 -17800 -11200 -13000 1000] + ElementLine [-11200 -13000 -11200 16800 1000] + ElementLine [-11200 16800 11200 16800 1000] + ElementLine [11200 -13000 11200 16800 1000] + ElementLine [11200 -13000 8700 -17800 1000] + + ) + +Element["" "Tantalum SMT capacitor (pin 1 is +)" "" "TANT_D" 18500 131500 0 22900 2 100 ""] +( + Pad[-5600 -11500 5600 -11500 12300 2000 12900 "1" "1" "square"] + Pad[-5600 11500 5600 11500 12300 2000 12900 "2" "2" "square"] + ElementLine [-11700 -21900 11700 -21900 2000] + ElementLine [-11700 -21900 -15000 -15800 1000] + ElementLine [-15000 -15800 -15000 20900 1000] + ElementLine [-15000 20900 15000 20900 1000] + ElementLine [15000 -15800 15000 20900 1000] + ElementLine [15000 -15800 11700 -21900 1000] + + ) + +Element["" "" "" "" 130000 22500 12913 3720 1 70 ""] +( + Pad[-984 -7087 984 -7087 5118 5000 7618 "" "1" "square"] + Pad[-984 7087 984 7087 5118 5000 7618 "" "2" "square"] + ElementLine [-3150 -3937 -3150 3937 787] + ElementLine [3150 -3937 3150 3937 787] + + ) +Layer(1 "component") +( +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( + Line[0 55000 170000 55000 1000 4000 "clearline"] + Line[0 100000 130000 100000 1000 4000 "clearline"] + Line[95000 0 95000 55000 1000 4000 "clearline"] + Line[130000 55000 130000 160000 1000 4000 "clearline"] + Text[115000 145000 1 200 "TANT" "clearline"] + Text[115000 90000 1 200 "SOD" "clearline"] + Text[157500 115000 1 200 "DO" "clearline"] + Text[112500 37500 0 200 "minimelf" "clearline"] +) Index: tags/2.3.0/util/pcblib-map/smd3.pcb =================================================================== --- tags/2.3.0/util/pcblib-map/smd3.pcb (nonexistent) +++ tags/2.3.0/util/pcblib-map/smd3.pcb (revision 33253) @@ -0,0 +1,895 @@ +# release: pcb 20110918 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 55000 75000] + +Grid[5000.0 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Symbol[' ' 1800] +( +) +Symbol['!' 1200] +( + SymbolLine[0 4500 0 5000 800] + SymbolLine[0 1000 0 3500 800] +) +Symbol['"' 1200] +( + SymbolLine[0 1000 0 2000 800] + SymbolLine[1000 1000 1000 2000 800] +) +Symbol['#' 1200] +( + SymbolLine[0 3500 2000 3500 800] + SymbolLine[0 2500 2000 2500 800] + SymbolLine[1500 2000 1500 4000 800] + SymbolLine[500 2000 500 4000 800] +) +Symbol['$' 1200] +( + SymbolLine[1500 1500 2000 2000 800] + SymbolLine[500 1500 1500 1500 800] + SymbolLine[0 2000 500 1500 800] + SymbolLine[0 2000 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4000 800] + SymbolLine[1500 4500 2000 4000 800] + SymbolLine[500 4500 1500 4500 800] + SymbolLine[0 4000 500 4500 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['%' 1200] +( + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[1000 2500 1500 2000 800] + SymbolLine[500 2500 1000 2500 800] + SymbolLine[0 2000 500 2500 800] + SymbolLine[0 5000 4000 1000 800] + SymbolLine[3500 5000 4000 4500 800] + SymbolLine[4000 4000 4000 4500 800] + SymbolLine[3500 3500 4000 4000 800] + SymbolLine[3000 3500 3500 3500 800] + SymbolLine[2500 4000 3000 3500 800] + SymbolLine[2500 4000 2500 4500 800] + SymbolLine[2500 4500 3000 5000 800] + SymbolLine[3000 5000 3500 5000 800] +) +Symbol['&' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 3500 1500 2000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[0 2500 2500 5000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[0 3500 0 4500 800] +) +Symbol[''' 1200] +( + SymbolLine[0 2000 1000 1000 800] +) +Symbol['(' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] +) +Symbol[')' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['*' 1200] +( + SymbolLine[0 2000 2000 4000 800] + SymbolLine[0 4000 2000 2000 800] + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol['+' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol[',' 1200] +( + SymbolLine[0 6000 1000 5000 800] +) +Symbol['-' 1200] +( + SymbolLine[0 3000 2000 3000 800] +) +Symbol['.' 1200] +( + SymbolLine[0 5000 500 5000 800] +) +Symbol['/' 1200] +( + SymbolLine[0 4500 3000 1500 800] +) +Symbol['0' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4000 2000 2000 800] +) +Symbol['1' 1200] +( + SymbolLine[0 1800 800 1000 800] + SymbolLine[800 1000 800 5000 800] + SymbolLine[0 5000 1500 5000 800] +) +Symbol['2' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[0 5000 2500 2500 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['3' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 2800 1500 2800 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[2000 3300 2000 4500 800] + SymbolLine[2000 3300 1500 2800 800] + SymbolLine[2000 2300 1500 2800 800] +) +Symbol['4' 1200] +( + SymbolLine[0 3500 2000 1000 800] + SymbolLine[0 3500 2500 3500 800] + SymbolLine[2000 1000 2000 5000 800] +) +Symbol['5' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[500 2500 1500 2500 800] + SymbolLine[1500 2500 2000 3000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['6' 1200] +( + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1500 2800 2000 3300 800] + SymbolLine[0 2800 1500 2800 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3300 2000 4500 800] +) +Symbol['7' 1200] +( + SymbolLine[500 5000 2500 1000 800] + SymbolLine[0 1000 2500 1000 800] +) +Symbol['8' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3700 0 4500 800] + SymbolLine[0 3700 700 3000 800] + SymbolLine[700 3000 1300 3000 800] + SymbolLine[1300 3000 2000 3700 800] + SymbolLine[2000 3700 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 2300 700 3000 800] + SymbolLine[0 1500 0 2300 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[1300 3000 2000 2300 800] +) +Symbol['9' 1200] +( + SymbolLine[500 5000 2000 3000 800] + SymbolLine[2000 1500 2000 3000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol[':' 1200] +( + SymbolLine[0 2500 500 2500 800] + SymbolLine[0 3500 500 3500 800] +) +Symbol[';' 1200] +( + SymbolLine[0 5000 1000 4000 800] + SymbolLine[1000 2500 1000 3000 800] +) +Symbol['<' 1200] +( + SymbolLine[0 3000 1000 2000 800] + SymbolLine[0 3000 1000 4000 800] +) +Symbol['=' 1200] +( + SymbolLine[0 2500 2000 2500 800] + SymbolLine[0 3500 2000 3500 800] +) +Symbol['>' 1200] +( + SymbolLine[0 2000 1000 3000 800] + SymbolLine[0 4000 1000 3000 800] +) +Symbol['?' 1200] +( + SymbolLine[1000 3000 1000 3500 800] + SymbolLine[1000 4500 1000 5000 800] + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2000 800] + SymbolLine[1000 3000 2000 2000 800] +) +Symbol['@' 1200] +( + SymbolLine[0 1000 0 4000 800] + SymbolLine[0 4000 1000 5000 800] + SymbolLine[1000 5000 4000 5000 800] + SymbolLine[5000 3500 5000 1000 800] + SymbolLine[5000 1000 4000 0 800] + SymbolLine[4000 0 1000 0 800] + SymbolLine[1000 0 0 1000 800] + SymbolLine[1500 2000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 3000 3500 800] + SymbolLine[3000 3500 3500 3000 800] + SymbolLine[3500 3000 4000 3500 800] + SymbolLine[3500 3000 3500 1500 800] + SymbolLine[3500 2000 3000 1500 800] + SymbolLine[2000 1500 3000 1500 800] + SymbolLine[2000 1500 1500 2000 800] + SymbolLine[4000 3500 5000 3500 800] +) +Symbol['A' 1200] +( + SymbolLine[0 2000 0 5000 800] + SymbolLine[0 2000 700 1000 800] + SymbolLine[700 1000 1800 1000 800] + SymbolLine[1800 1000 2500 2000 800] + SymbolLine[2500 2000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['B' 1200] +( + SymbolLine[0 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3300 2500 4500 800] + SymbolLine[2000 2800 2500 3300 800] + SymbolLine[500 2800 2000 2800 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2300 800] + SymbolLine[2000 2800 2500 2300 800] +) +Symbol['C' 1200] +( + SymbolLine[700 5000 2000 5000 800] + SymbolLine[0 4300 700 5000 800] + SymbolLine[0 1700 0 4300 800] + SymbolLine[0 1700 700 1000 800] + SymbolLine[700 1000 2000 1000 800] +) +Symbol['D' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[1800 1000 2500 1700 800] + SymbolLine[2500 1700 2500 4300 800] + SymbolLine[1800 5000 2500 4300 800] + SymbolLine[0 5000 1800 5000 800] + SymbolLine[0 1000 1800 1000 800] +) +Symbol['E' 1200] +( + SymbolLine[0 2800 1500 2800 800] + SymbolLine[0 5000 2000 5000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] +) +Symbol['F' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 2800 1500 2800 800] +) +Symbol['G' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[1000 3000 2000 3000 800] +) +Symbol['H' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[2500 1000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['I' 1200] +( + SymbolLine[0 1000 1000 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 1000 5000 800] +) +Symbol['J' 1200] +( + SymbolLine[700 1000 1500 1000 800] + SymbolLine[1500 1000 1500 4500 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 4500 0 4000 800] +) +Symbol['K' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3000 2000 1000 800] + SymbolLine[0 3000 2000 5000 800] +) +Symbol['L' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['M' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 1500 3000 800] + SymbolLine[1500 3000 3000 1000 800] + SymbolLine[3000 1000 3000 5000 800] +) +Symbol['N' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2500 5000 800] + SymbolLine[2500 1000 2500 5000 800] +) +Symbol['O' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['P' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol['Q' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1000 3500 2000 5000 800] +) +Symbol['R' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[1300 3000 2500 5000 800] +) +Symbol['S' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['T' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['U' 1200] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 1000 2000 4500 800] +) +Symbol['V' 1200] +( + SymbolLine[0 1000 1000 5000 800] + SymbolLine[1000 5000 2000 1000 800] +) +Symbol['W' 1200] +( + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 5000 800] + SymbolLine[500 5000 1500 3000 800] + SymbolLine[1500 3000 2500 5000 800] + SymbolLine[2500 5000 3000 3000 800] + SymbolLine[3000 3000 3000 1000 800] +) +Symbol['X' 1200] +( + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 1000 2500 5000 800] +) +Symbol['Y' 1200] +( + SymbolLine[0 1000 1000 3000 800] + SymbolLine[1000 3000 2000 1000 800] + SymbolLine[1000 3000 1000 5000 800] +) +Symbol['Z' 1200] +( + SymbolLine[0 1000 2500 1000 800] + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['[' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['\' 1200] +( + SymbolLine[0 1500 3000 4500 800] +) +Symbol[']' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['^' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1500 800] +) +Symbol['_' 1200] +( + SymbolLine[0 5000 2000 5000 800] +) +Symbol['a' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[2000 4500 2500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['b' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] +) +Symbol['c' 1200] +( + SymbolLine[500 3000 2000 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] +) +Symbol['d' 1200] +( + SymbolLine[2000 1000 2000 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] +) +Symbol['e' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[0 4000 2000 4000 800] + SymbolLine[2000 4000 2000 3500 800] +) +Symbol['f' 1000] +( + SymbolLine[500 1500 500 5000 800] + SymbolLine[500 1500 1000 1000 800] + SymbolLine[1000 1000 1500 1000 800] + SymbolLine[0 3000 1000 3000 800] +) +Symbol['g' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[2000 3000 2000 6000 800] +) +Symbol['h' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] +) +Symbol['i' 1000] +( + SymbolLine[0 2000 0 2100 1000] + SymbolLine[0 3500 0 5000 800] +) +Symbol['j' 1000] +( + SymbolLine[500 2000 500 2100 1000] + SymbolLine[500 3500 500 6000 800] + SymbolLine[0 6500 500 6000 800] +) +Symbol['k' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 1500 5000 800] + SymbolLine[0 3500 1000 2500 800] +) +Symbol['l' 1000] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['m' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[2000 3500 2500 3000 800] + SymbolLine[2500 3000 3000 3000 800] + SymbolLine[3000 3000 3500 3500 800] + SymbolLine[3500 3500 3500 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['n' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['o' 1200] +( + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['p' 1200] +( + SymbolLine[500 3500 500 6500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[1000 5000 2000 5000 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['q' 1200] +( + SymbolLine[2000 3500 2000 6500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['r' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['s' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2000 4000 2500 4500 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['t' 1000] +( + SymbolLine[500 1000 500 4500 800] + SymbolLine[500 4500 1000 5000 800] + SymbolLine[0 2500 1000 2500 800] +) +Symbol['u' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3000 2000 4500 800] +) +Symbol['v' 1200] +( + SymbolLine[0 3000 1000 5000 800] + SymbolLine[2000 3000 1000 5000 800] +) +Symbol['w' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[1500 3000 1500 4500 800] + SymbolLine[1500 4500 2000 5000 800] + SymbolLine[2000 5000 2500 5000 800] + SymbolLine[2500 5000 3000 4500 800] + SymbolLine[3000 3000 3000 4500 800] +) +Symbol['x' 1200] +( + SymbolLine[0 3000 2000 5000 800] + SymbolLine[0 5000 2000 3000 800] +) +Symbol['y' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 6000 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['z' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[0 5000 2000 3000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['{' 1200] +( + SymbolLine[500 1500 1000 1000 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['|' 1200] +( + SymbolLine[0 1000 0 5000 800] +) +Symbol['}' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[500 2500 1000 3000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['~' 1200] +( + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1000 3000 800] + SymbolLine[1000 3000 1500 3500 800] + SymbolLine[1500 3500 2000 3500 800] + SymbolLine[2000 3500 2500 3000 800] +) +Attribute("PCB::grid::unit" "mil") +Via[55000 75000 7874 4000 0 3150 "" ""] + +Element["" "SMT transistor, 3 pins" "" "SC70_3" 10000 15000 9300 -9400 3 100 ""] +( + Pad[0 -300 0 300 2900 3000 3500 "1" "1" "square,edge2"] + Pad[5100 -300 5100 300 2900 3000 3500 "2" "2" "square,edge2"] + Pad[2600 -7300 2600 -6700 2900 3000 3500 "3" "3" "square"] + ElementLine [-2100 -9400 -2100 2500 1000] + ElementLine [-2100 2500 7300 2500 1000] + ElementLine [7300 2500 7300 -9400 1000] + ElementLine [7300 -9400 -2100 -9400 1000] + + ) + +Element["" "SMT transistor, 3 pins" "" "SC90" 25000 15000 7600 -7800 3 100 ""] +( + Pad[0 -200 0 200 2400 3000 3000 "1" "1" "square,edge2"] + Pad[3900 -200 3900 200 2400 3000 3000 "2" "2" "square,edge2"] + Pad[1900 -6100 1900 -5700 2400 3000 3000 "3" "3" "square"] + ElementLine [-1700 -7800 -1700 2000 1000] + ElementLine [-1700 2000 5600 2000 1000] + ElementLine [5600 2000 5600 -7800 1000] + ElementLine [5600 -7800 -1700 -7800 1000] + + ) + +Element["" "SMT transistor, 3 pins" "" "SOT23" 6100 48200 12300 -11000 3 100 ""] +( + Pad[0 -300 0 300 3400 3000 4000 "1" "1" "square,edge2"] + Pad[7800 -300 7800 300 3400 3000 4000 "2" "2" "square,edge2"] + Pad[3900 -8500 3900 -7900 3400 3000 4000 "3" "3" "square"] + ElementLine [-2500 -11000 -2500 2900 1000] + ElementLine [-2500 2900 10300 2900 1000] + ElementLine [10300 2900 10300 -11000 1000] + ElementLine [10300 -11000 -2500 -11000 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOT23D" 6100 68200 12300 -11000 3 100 ""] +( + Pad[0 -300 0 300 3400 3000 4000 "2" "2" "square,edge2"] + Pad[7800 -300 7800 300 3400 3000 4000 "3" "3" "square,edge2"] + Pad[3900 -8500 3900 -7900 3400 3000 4000 "1" "1" "square"] + ElementLine [-2500 -11000 -2500 2900 1000] + ElementLine [-2500 2900 10300 2900 1000] + ElementLine [10300 2900 10300 -11000 1000] + ElementLine [10300 -11000 -2500 -11000 1000] + + ) + +Element["" "SMT transistor, 3 pins" "" "SOT323" 27400 47000 9300 -9400 3 100 ""] +( + Pad[0 -300 0 300 2900 3000 3500 "1" "1" "square,edge2"] + Pad[5100 -300 5100 300 2900 3000 3500 "2" "2" "square,edge2"] + Pad[2600 -7300 2600 -6700 2900 3000 3500 "3" "3" "square"] + ElementLine [-2100 -9400 -2100 2500 1000] + ElementLine [-2100 2500 7300 2500 1000] + ElementLine [7300 2500 7300 -9400 1000] + ElementLine [7300 -9400 -2100 -9400 1000] + + ) + +Element["" "SMT diode (pin 1 is cathode)" "" "SOT323D" 27400 67000 9300 -9400 3 100 ""] +( + Pad[0 -300 0 300 2900 3000 3500 "2" "2" "square,edge2"] + Pad[5100 -300 5100 300 2900 3000 3500 "3" "3" "square,edge2"] + Pad[2600 -7300 2600 -6700 2900 3000 3500 "1" "1" "square"] + ElementLine [-2100 -9400 -2100 2500 1000] + ElementLine [-2100 2500 7300 2500 1000] + ElementLine [7300 2500 7300 -9400 1000] + ElementLine [7300 -9400 -2100 -9400 1000] + + ) +Layer(1 "component") +( +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( + Line[0 25000 55000 25000 1000 4000 "clearline"] + Text[35000 5000 0 200 "SC" "clearline"] + Text[40000 60000 1 200 "SOT" "clearline"] +) Index: tags/2.3.0/util/pcblib-map/smdN.pcb =================================================================== --- tags/2.3.0/util/pcblib-map/smdN.pcb (nonexistent) +++ tags/2.3.0/util/pcblib-map/smdN.pcb (revision 33253) @@ -0,0 +1,944 @@ +# release: pcb 20110918 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 100000 75000] + +Grid[5000.0 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Symbol[' ' 1800] +( +) +Symbol['!' 1200] +( + SymbolLine[0 4500 0 5000 800] + SymbolLine[0 1000 0 3500 800] +) +Symbol['"' 1200] +( + SymbolLine[0 1000 0 2000 800] + SymbolLine[1000 1000 1000 2000 800] +) +Symbol['#' 1200] +( + SymbolLine[0 3500 2000 3500 800] + SymbolLine[0 2500 2000 2500 800] + SymbolLine[1500 2000 1500 4000 800] + SymbolLine[500 2000 500 4000 800] +) +Symbol['$' 1200] +( + SymbolLine[1500 1500 2000 2000 800] + SymbolLine[500 1500 1500 1500 800] + SymbolLine[0 2000 500 1500 800] + SymbolLine[0 2000 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4000 800] + SymbolLine[1500 4500 2000 4000 800] + SymbolLine[500 4500 1500 4500 800] + SymbolLine[0 4000 500 4500 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['%' 1200] +( + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[1000 2500 1500 2000 800] + SymbolLine[500 2500 1000 2500 800] + SymbolLine[0 2000 500 2500 800] + SymbolLine[0 5000 4000 1000 800] + SymbolLine[3500 5000 4000 4500 800] + SymbolLine[4000 4000 4000 4500 800] + SymbolLine[3500 3500 4000 4000 800] + SymbolLine[3000 3500 3500 3500 800] + SymbolLine[2500 4000 3000 3500 800] + SymbolLine[2500 4000 2500 4500 800] + SymbolLine[2500 4500 3000 5000 800] + SymbolLine[3000 5000 3500 5000 800] +) +Symbol['&' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 3500 1500 2000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[0 2500 2500 5000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[0 3500 0 4500 800] +) +Symbol[''' 1200] +( + SymbolLine[0 2000 1000 1000 800] +) +Symbol['(' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] +) +Symbol[')' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['*' 1200] +( + SymbolLine[0 2000 2000 4000 800] + SymbolLine[0 4000 2000 2000 800] + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol['+' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol[',' 1200] +( + SymbolLine[0 6000 1000 5000 800] +) +Symbol['-' 1200] +( + SymbolLine[0 3000 2000 3000 800] +) +Symbol['.' 1200] +( + SymbolLine[0 5000 500 5000 800] +) +Symbol['/' 1200] +( + SymbolLine[0 4500 3000 1500 800] +) +Symbol['0' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4000 2000 2000 800] +) +Symbol['1' 1200] +( + SymbolLine[0 1800 800 1000 800] + SymbolLine[800 1000 800 5000 800] + SymbolLine[0 5000 1500 5000 800] +) +Symbol['2' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[0 5000 2500 2500 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['3' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 2800 1500 2800 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[2000 3300 2000 4500 800] + SymbolLine[2000 3300 1500 2800 800] + SymbolLine[2000 2300 1500 2800 800] +) +Symbol['4' 1200] +( + SymbolLine[0 3500 2000 1000 800] + SymbolLine[0 3500 2500 3500 800] + SymbolLine[2000 1000 2000 5000 800] +) +Symbol['5' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[500 2500 1500 2500 800] + SymbolLine[1500 2500 2000 3000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['6' 1200] +( + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1500 2800 2000 3300 800] + SymbolLine[0 2800 1500 2800 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3300 2000 4500 800] +) +Symbol['7' 1200] +( + SymbolLine[500 5000 2500 1000 800] + SymbolLine[0 1000 2500 1000 800] +) +Symbol['8' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3700 0 4500 800] + SymbolLine[0 3700 700 3000 800] + SymbolLine[700 3000 1300 3000 800] + SymbolLine[1300 3000 2000 3700 800] + SymbolLine[2000 3700 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 2300 700 3000 800] + SymbolLine[0 1500 0 2300 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[1300 3000 2000 2300 800] +) +Symbol['9' 1200] +( + SymbolLine[500 5000 2000 3000 800] + SymbolLine[2000 1500 2000 3000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol[':' 1200] +( + SymbolLine[0 2500 500 2500 800] + SymbolLine[0 3500 500 3500 800] +) +Symbol[';' 1200] +( + SymbolLine[0 5000 1000 4000 800] + SymbolLine[1000 2500 1000 3000 800] +) +Symbol['<' 1200] +( + SymbolLine[0 3000 1000 2000 800] + SymbolLine[0 3000 1000 4000 800] +) +Symbol['=' 1200] +( + SymbolLine[0 2500 2000 2500 800] + SymbolLine[0 3500 2000 3500 800] +) +Symbol['>' 1200] +( + SymbolLine[0 2000 1000 3000 800] + SymbolLine[0 4000 1000 3000 800] +) +Symbol['?' 1200] +( + SymbolLine[1000 3000 1000 3500 800] + SymbolLine[1000 4500 1000 5000 800] + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2000 800] + SymbolLine[1000 3000 2000 2000 800] +) +Symbol['@' 1200] +( + SymbolLine[0 1000 0 4000 800] + SymbolLine[0 4000 1000 5000 800] + SymbolLine[1000 5000 4000 5000 800] + SymbolLine[5000 3500 5000 1000 800] + SymbolLine[5000 1000 4000 0 800] + SymbolLine[4000 0 1000 0 800] + SymbolLine[1000 0 0 1000 800] + SymbolLine[1500 2000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 3000 3500 800] + SymbolLine[3000 3500 3500 3000 800] + SymbolLine[3500 3000 4000 3500 800] + SymbolLine[3500 3000 3500 1500 800] + SymbolLine[3500 2000 3000 1500 800] + SymbolLine[2000 1500 3000 1500 800] + SymbolLine[2000 1500 1500 2000 800] + SymbolLine[4000 3500 5000 3500 800] +) +Symbol['A' 1200] +( + SymbolLine[0 2000 0 5000 800] + SymbolLine[0 2000 700 1000 800] + SymbolLine[700 1000 1800 1000 800] + SymbolLine[1800 1000 2500 2000 800] + SymbolLine[2500 2000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['B' 1200] +( + SymbolLine[0 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3300 2500 4500 800] + SymbolLine[2000 2800 2500 3300 800] + SymbolLine[500 2800 2000 2800 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2300 800] + SymbolLine[2000 2800 2500 2300 800] +) +Symbol['C' 1200] +( + SymbolLine[700 5000 2000 5000 800] + SymbolLine[0 4300 700 5000 800] + SymbolLine[0 1700 0 4300 800] + SymbolLine[0 1700 700 1000 800] + SymbolLine[700 1000 2000 1000 800] +) +Symbol['D' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[1800 1000 2500 1700 800] + SymbolLine[2500 1700 2500 4300 800] + SymbolLine[1800 5000 2500 4300 800] + SymbolLine[0 5000 1800 5000 800] + SymbolLine[0 1000 1800 1000 800] +) +Symbol['E' 1200] +( + SymbolLine[0 2800 1500 2800 800] + SymbolLine[0 5000 2000 5000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] +) +Symbol['F' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 2800 1500 2800 800] +) +Symbol['G' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[1000 3000 2000 3000 800] +) +Symbol['H' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[2500 1000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['I' 1200] +( + SymbolLine[0 1000 1000 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 1000 5000 800] +) +Symbol['J' 1200] +( + SymbolLine[700 1000 1500 1000 800] + SymbolLine[1500 1000 1500 4500 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 4500 0 4000 800] +) +Symbol['K' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3000 2000 1000 800] + SymbolLine[0 3000 2000 5000 800] +) +Symbol['L' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['M' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 1500 3000 800] + SymbolLine[1500 3000 3000 1000 800] + SymbolLine[3000 1000 3000 5000 800] +) +Symbol['N' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2500 5000 800] + SymbolLine[2500 1000 2500 5000 800] +) +Symbol['O' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['P' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol['Q' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1000 3500 2000 5000 800] +) +Symbol['R' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[1300 3000 2500 5000 800] +) +Symbol['S' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['T' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['U' 1200] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 1000 2000 4500 800] +) +Symbol['V' 1200] +( + SymbolLine[0 1000 1000 5000 800] + SymbolLine[1000 5000 2000 1000 800] +) +Symbol['W' 1200] +( + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 5000 800] + SymbolLine[500 5000 1500 3000 800] + SymbolLine[1500 3000 2500 5000 800] + SymbolLine[2500 5000 3000 3000 800] + SymbolLine[3000 3000 3000 1000 800] +) +Symbol['X' 1200] +( + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 1000 2500 5000 800] +) +Symbol['Y' 1200] +( + SymbolLine[0 1000 1000 3000 800] + SymbolLine[1000 3000 2000 1000 800] + SymbolLine[1000 3000 1000 5000 800] +) +Symbol['Z' 1200] +( + SymbolLine[0 1000 2500 1000 800] + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['[' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['\' 1200] +( + SymbolLine[0 1500 3000 4500 800] +) +Symbol[']' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['^' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1500 800] +) +Symbol['_' 1200] +( + SymbolLine[0 5000 2000 5000 800] +) +Symbol['a' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[2000 4500 2500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['b' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] +) +Symbol['c' 1200] +( + SymbolLine[500 3000 2000 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] +) +Symbol['d' 1200] +( + SymbolLine[2000 1000 2000 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] +) +Symbol['e' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[0 4000 2000 4000 800] + SymbolLine[2000 4000 2000 3500 800] +) +Symbol['f' 1000] +( + SymbolLine[500 1500 500 5000 800] + SymbolLine[500 1500 1000 1000 800] + SymbolLine[1000 1000 1500 1000 800] + SymbolLine[0 3000 1000 3000 800] +) +Symbol['g' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[2000 3000 2000 6000 800] +) +Symbol['h' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] +) +Symbol['i' 1000] +( + SymbolLine[0 2000 0 2100 1000] + SymbolLine[0 3500 0 5000 800] +) +Symbol['j' 1000] +( + SymbolLine[500 2000 500 2100 1000] + SymbolLine[500 3500 500 6000 800] + SymbolLine[0 6500 500 6000 800] +) +Symbol['k' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 1500 5000 800] + SymbolLine[0 3500 1000 2500 800] +) +Symbol['l' 1000] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['m' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[2000 3500 2500 3000 800] + SymbolLine[2500 3000 3000 3000 800] + SymbolLine[3000 3000 3500 3500 800] + SymbolLine[3500 3500 3500 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['n' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['o' 1200] +( + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['p' 1200] +( + SymbolLine[500 3500 500 6500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[1000 5000 2000 5000 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['q' 1200] +( + SymbolLine[2000 3500 2000 6500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['r' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['s' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2000 4000 2500 4500 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['t' 1000] +( + SymbolLine[500 1000 500 4500 800] + SymbolLine[500 4500 1000 5000 800] + SymbolLine[0 2500 1000 2500 800] +) +Symbol['u' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3000 2000 4500 800] +) +Symbol['v' 1200] +( + SymbolLine[0 3000 1000 5000 800] + SymbolLine[2000 3000 1000 5000 800] +) +Symbol['w' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[1500 3000 1500 4500 800] + SymbolLine[1500 4500 2000 5000 800] + SymbolLine[2000 5000 2500 5000 800] + SymbolLine[2500 5000 3000 4500 800] + SymbolLine[3000 3000 3000 4500 800] +) +Symbol['x' 1200] +( + SymbolLine[0 3000 2000 5000 800] + SymbolLine[0 5000 2000 3000 800] +) +Symbol['y' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 6000 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['z' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[0 5000 2000 3000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['{' 1200] +( + SymbolLine[500 1500 1000 1000 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['|' 1200] +( + SymbolLine[0 1000 0 5000 800] +) +Symbol['}' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[500 2500 1000 3000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['~' 1200] +( + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1000 3000 800] + SymbolLine[1000 3000 1500 3500 800] + SymbolLine[1500 3500 2000 3500 800] + SymbolLine[2000 3500 2500 3000 800] +) +Attribute("PCB::grid::unit" "mil") +Via[100000 75000 7874 4000 0 3150 "" ""] + +Element["" "SMT transistor, 4 pins" "" "SC70_4" 5000 15000 9300 -9400 3 100 ""] +( + Pad[300 0 600 0 2900 3000 3500 "1" "1" "square"] + Pad[5100 -300 5100 300 2900 3000 3500 "2" "2" "square,edge2"] + Pad[5100 -7300 5100 -6700 2900 3000 3500 "3" "3" "square"] + Pad[0 -7300 0 -6700 2900 3000 3500 "4" "4" "square"] + ElementLine [-2100 -9400 -2100 2500 1000] + ElementLine [-2100 2500 7300 2500 1000] + ElementLine [7300 2500 7300 -9400 1000] + ElementLine [7300 -9400 -2100 -9400 1000] + + ) + +Element["" "Pressure transducer" "" "MPAK" 75000 60000 20300 -49700 3 100 ""] +( + Pad[0 -2800 0 2800 3100 3000 3700 "1" "1" "square,edge2"] + Pad[5000 -2800 5000 2800 3100 3000 3700 "2" "2" "square,edge2"] + Pad[10000 -2800 10000 2800 3100 3000 3700 "3" "3" "square,edge2"] + Pad[15000 -2800 15000 2800 3100 3000 3700 "4" "4" "square,edge2"] + Pad[3800 -43700 11200 -43700 8700 3000 9300 "5" "5" "square"] + ElementLine [-3200 -49700 -3200 6100 1000] + ElementLine [-3200 6100 18300 6100 1000] + ElementLine [18300 6100 18300 -49700 1000] + ElementLine [18300 -49700 -3200 -49700 1000] + + ) + +Element["" "SMT transistor, 4 pins" "" "SOT143" 20000 15000 11900 -11000 3 100 ""] +( + Pad[300 0 600 0 3400 3000 4000 "1" "1" "square"] + Pad[7400 -300 7400 300 3400 3000 4000 "2" "2" "square,edge2"] + Pad[7400 -8500 7400 -7900 3400 3000 4000 "3" "3" "square"] + Pad[0 -8500 0 -7900 3400 3000 4000 "4" "4" "square"] + ElementLine [-2500 -11000 -2500 2900 1000] + ElementLine [-2500 2900 9900 2900 1000] + ElementLine [9900 2900 9900 -11000 1000] + ElementLine [9900 -11000 -2500 -11000 1000] + + ) + +Element["" "SMT transistor, 4 pins" "" "SOT223" 40000 60000 25300 -32900 3 100 ""] +( + Pad[0 -3300 0 3300 5600 3000 6200 "1" "1" "square,edge2"] + Pad[9000 -3300 9000 3300 5600 3000 6200 "2" "2" "square,edge2"] + Pad[18100 -3300 18100 3300 5600 3000 6200 "3" "3" "square,edge2"] + Pad[4500 -24400 13500 -24400 12200 3000 12800 "4" "4" "square"] + ElementLine [-5200 -32900 -5200 8500 1000] + ElementLine [-5200 8500 23300 8500 1000] + ElementLine [23300 8500 23300 -32900 1000] + ElementLine [23300 -32900 -5200 -32900 1000] + + ) + +Element["" "SMT transistor, 5 pins" "" "SOT25" 35000 15000 11800 -11000 3 100 ""] +( + Pad[0 -800 0 800 2400 3000 3000 "1" "1" "square,edge2"] + Pad[7800 -800 7800 800 2400 3000 3000 "2" "2" "square,edge2"] + Pad[7800 -9000 7800 -7400 2400 3000 3000 "3" "3" "square"] + Pad[3900 -9000 3900 -7400 2400 3000 3000 "4" "4" "square"] + Pad[0 -9000 0 -7400 2400 3000 3000 "5" "5" "square"] + ElementLine [-2000 -11000 -2000 2900 1000] + ElementLine [-2000 2900 9800 2900 1000] + ElementLine [9800 2900 9800 -11000 1000] + ElementLine [9800 -11000 -2000 -11000 1000] + + ) + +Element["" "SMT transistor, 6 pins" "" "SOT26" 51100 15000 11800 -11000 3 100 ""] +( + Pad[0 -800 0 800 2400 3000 3000 "1" "1" "square,edge2"] + Pad[3900 -800 3900 800 2400 3000 3000 "2" "2" "square,edge2"] + Pad[7800 -800 7800 800 2400 3000 3000 "3" "3" "square,edge2"] + Pad[7800 -9000 7800 -7400 2400 3000 3000 "4" "4" "square"] + Pad[3900 -9000 3900 -7400 2400 3000 3000 "5" "5" "square"] + Pad[0 -9000 0 -7400 2400 3000 3000 "6" "6" "square"] + ElementLine [-2000 -11000 -2000 2900 1000] + ElementLine [-2000 2900 9800 2900 1000] + ElementLine [9800 2900 9800 -11000 1000] + ElementLine [9800 -11000 -2000 -11000 1000] + + ) + +Element["" "SMT transistor, 5 pins" "" "SOT325" 9900 65000 8600 -9400 3 100 ""] +( + Pad[0 -1000 0 1000 1500 3000 2100 "1" "1" "square,edge2"] + Pad[5100 -1000 5100 1000 1500 3000 2100 "2" "2" "square,edge2"] + Pad[5100 -8000 5100 -6000 1500 3000 2100 "3" "3" "square"] + Pad[2600 -8000 2600 -6000 1500 3000 2100 "4" "4" "square"] + Pad[0 -8000 0 -6000 1500 3000 2100 "5" "5" "square"] + ElementLine [-1400 -9400 -1400 2500 1000] + ElementLine [-1400 2500 6600 2500 1000] + ElementLine [6600 2500 6600 -9400 1000] + ElementLine [6600 -9400 -1400 -9400 1000] + + ) + +Element["" "SMT transistor, 6 pins" "" "SOT326" 22400 65000 8600 -9400 3 100 ""] +( + Pad[0 -1000 0 1000 1500 3000 2100 "1" "1" "square,edge2"] + Pad[2600 -1000 2600 1000 1500 3000 2100 "2" "2" "square,edge2"] + Pad[5100 -1000 5100 1000 1500 3000 2100 "3" "3" "square,edge2"] + Pad[5100 -8000 5100 -6000 1500 3000 2100 "4" "4" "square"] + Pad[2600 -8000 2600 -6000 1500 3000 2100 "5" "5" "square"] + Pad[0 -8000 0 -6000 1500 3000 2100 "6" "6" "square"] + ElementLine [-1400 -9400 -1400 2500 1000] + ElementLine [-1400 2500 6600 2500 1000] + ElementLine [6600 2500 6600 -9400 1000] + ElementLine [6600 -9400 -1400 -9400 1000] + + ) + +Element["" "SMT transistor, 4 pins" "" "SOT89" 8900 45000 17300 -16400 3 100 ""] +( + Pad[0 -1200 0 1200 3700 3000 4300 "1" "1" "square,edge2"] + Pad[6100 -1200 6100 1200 3700 3000 4300 "2" "2" "square,edge2"] + Pad[12200 -1200 12200 1200 3700 3000 4300 "3" "3" "square,edge2"] + Pad[3100 -12200 9100 -12200 6100 3000 6700 "4" "4" "square"] + ElementLine [-3000 -16400 -3000 4300 1000] + ElementLine [-3000 4300 15300 4300 1000] + ElementLine [15300 4300 15300 -16400 1000] + ElementLine [15300 -16400 -3000 -16400 1000] + + ) +Layer(1 "component") +( +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) Index: tags/2.3.0/util/pcblib-map/trh2.pcb =================================================================== --- tags/2.3.0/util/pcblib-map/trh2.pcb (nonexistent) +++ tags/2.3.0/util/pcblib-map/trh2.pcb (revision 33253) @@ -0,0 +1,928 @@ +# release: pcb 20110918 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 330000 150000] + +Grid[10000.0 0 0 1] +Cursor[10000 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Symbol[' ' 1800] +( +) +Symbol['!' 1200] +( + SymbolLine[0 4500 0 5000 800] + SymbolLine[0 1000 0 3500 800] +) +Symbol['"' 1200] +( + SymbolLine[0 1000 0 2000 800] + SymbolLine[1000 1000 1000 2000 800] +) +Symbol['#' 1200] +( + SymbolLine[0 3500 2000 3500 800] + SymbolLine[0 2500 2000 2500 800] + SymbolLine[1500 2000 1500 4000 800] + SymbolLine[500 2000 500 4000 800] +) +Symbol['$' 1200] +( + SymbolLine[1500 1500 2000 2000 800] + SymbolLine[500 1500 1500 1500 800] + SymbolLine[0 2000 500 1500 800] + SymbolLine[0 2000 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4000 800] + SymbolLine[1500 4500 2000 4000 800] + SymbolLine[500 4500 1500 4500 800] + SymbolLine[0 4000 500 4500 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['%' 1200] +( + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[1000 2500 1500 2000 800] + SymbolLine[500 2500 1000 2500 800] + SymbolLine[0 2000 500 2500 800] + SymbolLine[0 5000 4000 1000 800] + SymbolLine[3500 5000 4000 4500 800] + SymbolLine[4000 4000 4000 4500 800] + SymbolLine[3500 3500 4000 4000 800] + SymbolLine[3000 3500 3500 3500 800] + SymbolLine[2500 4000 3000 3500 800] + SymbolLine[2500 4000 2500 4500 800] + SymbolLine[2500 4500 3000 5000 800] + SymbolLine[3000 5000 3500 5000 800] +) +Symbol['&' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 3500 1500 2000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[0 2500 2500 5000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[0 3500 0 4500 800] +) +Symbol[''' 1200] +( + SymbolLine[0 2000 1000 1000 800] +) +Symbol['(' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] +) +Symbol[')' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['*' 1200] +( + SymbolLine[0 2000 2000 4000 800] + SymbolLine[0 4000 2000 2000 800] + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol['+' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol[',' 1200] +( + SymbolLine[0 6000 1000 5000 800] +) +Symbol['-' 1200] +( + SymbolLine[0 3000 2000 3000 800] +) +Symbol['.' 1200] +( + SymbolLine[0 5000 500 5000 800] +) +Symbol['/' 1200] +( + SymbolLine[0 4500 3000 1500 800] +) +Symbol['0' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4000 2000 2000 800] +) +Symbol['1' 1200] +( + SymbolLine[0 1800 800 1000 800] + SymbolLine[800 1000 800 5000 800] + SymbolLine[0 5000 1500 5000 800] +) +Symbol['2' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[0 5000 2500 2500 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['3' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 2800 1500 2800 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[2000 3300 2000 4500 800] + SymbolLine[2000 3300 1500 2800 800] + SymbolLine[2000 2300 1500 2800 800] +) +Symbol['4' 1200] +( + SymbolLine[0 3500 2000 1000 800] + SymbolLine[0 3500 2500 3500 800] + SymbolLine[2000 1000 2000 5000 800] +) +Symbol['5' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[500 2500 1500 2500 800] + SymbolLine[1500 2500 2000 3000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['6' 1200] +( + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1500 2800 2000 3300 800] + SymbolLine[0 2800 1500 2800 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3300 2000 4500 800] +) +Symbol['7' 1200] +( + SymbolLine[500 5000 2500 1000 800] + SymbolLine[0 1000 2500 1000 800] +) +Symbol['8' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3700 0 4500 800] + SymbolLine[0 3700 700 3000 800] + SymbolLine[700 3000 1300 3000 800] + SymbolLine[1300 3000 2000 3700 800] + SymbolLine[2000 3700 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 2300 700 3000 800] + SymbolLine[0 1500 0 2300 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[1300 3000 2000 2300 800] +) +Symbol['9' 1200] +( + SymbolLine[500 5000 2000 3000 800] + SymbolLine[2000 1500 2000 3000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol[':' 1200] +( + SymbolLine[0 2500 500 2500 800] + SymbolLine[0 3500 500 3500 800] +) +Symbol[';' 1200] +( + SymbolLine[0 5000 1000 4000 800] + SymbolLine[1000 2500 1000 3000 800] +) +Symbol['<' 1200] +( + SymbolLine[0 3000 1000 2000 800] + SymbolLine[0 3000 1000 4000 800] +) +Symbol['=' 1200] +( + SymbolLine[0 2500 2000 2500 800] + SymbolLine[0 3500 2000 3500 800] +) +Symbol['>' 1200] +( + SymbolLine[0 2000 1000 3000 800] + SymbolLine[0 4000 1000 3000 800] +) +Symbol['?' 1200] +( + SymbolLine[1000 3000 1000 3500 800] + SymbolLine[1000 4500 1000 5000 800] + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2000 800] + SymbolLine[1000 3000 2000 2000 800] +) +Symbol['@' 1200] +( + SymbolLine[0 1000 0 4000 800] + SymbolLine[0 4000 1000 5000 800] + SymbolLine[1000 5000 4000 5000 800] + SymbolLine[5000 3500 5000 1000 800] + SymbolLine[5000 1000 4000 0 800] + SymbolLine[4000 0 1000 0 800] + SymbolLine[1000 0 0 1000 800] + SymbolLine[1500 2000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 3000 3500 800] + SymbolLine[3000 3500 3500 3000 800] + SymbolLine[3500 3000 4000 3500 800] + SymbolLine[3500 3000 3500 1500 800] + SymbolLine[3500 2000 3000 1500 800] + SymbolLine[2000 1500 3000 1500 800] + SymbolLine[2000 1500 1500 2000 800] + SymbolLine[4000 3500 5000 3500 800] +) +Symbol['A' 1200] +( + SymbolLine[0 2000 0 5000 800] + SymbolLine[0 2000 700 1000 800] + SymbolLine[700 1000 1800 1000 800] + SymbolLine[1800 1000 2500 2000 800] + SymbolLine[2500 2000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['B' 1200] +( + SymbolLine[0 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3300 2500 4500 800] + SymbolLine[2000 2800 2500 3300 800] + SymbolLine[500 2800 2000 2800 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2300 800] + SymbolLine[2000 2800 2500 2300 800] +) +Symbol['C' 1200] +( + SymbolLine[700 5000 2000 5000 800] + SymbolLine[0 4300 700 5000 800] + SymbolLine[0 1700 0 4300 800] + SymbolLine[0 1700 700 1000 800] + SymbolLine[700 1000 2000 1000 800] +) +Symbol['D' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[1800 1000 2500 1700 800] + SymbolLine[2500 1700 2500 4300 800] + SymbolLine[1800 5000 2500 4300 800] + SymbolLine[0 5000 1800 5000 800] + SymbolLine[0 1000 1800 1000 800] +) +Symbol['E' 1200] +( + SymbolLine[0 2800 1500 2800 800] + SymbolLine[0 5000 2000 5000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] +) +Symbol['F' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 2800 1500 2800 800] +) +Symbol['G' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[1000 3000 2000 3000 800] +) +Symbol['H' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[2500 1000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['I' 1200] +( + SymbolLine[0 1000 1000 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 1000 5000 800] +) +Symbol['J' 1200] +( + SymbolLine[700 1000 1500 1000 800] + SymbolLine[1500 1000 1500 4500 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 4500 0 4000 800] +) +Symbol['K' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3000 2000 1000 800] + SymbolLine[0 3000 2000 5000 800] +) +Symbol['L' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['M' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 1500 3000 800] + SymbolLine[1500 3000 3000 1000 800] + SymbolLine[3000 1000 3000 5000 800] +) +Symbol['N' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2500 5000 800] + SymbolLine[2500 1000 2500 5000 800] +) +Symbol['O' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['P' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol['Q' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1000 3500 2000 5000 800] +) +Symbol['R' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[1300 3000 2500 5000 800] +) +Symbol['S' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['T' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['U' 1200] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 1000 2000 4500 800] +) +Symbol['V' 1200] +( + SymbolLine[0 1000 1000 5000 800] + SymbolLine[1000 5000 2000 1000 800] +) +Symbol['W' 1200] +( + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 5000 800] + SymbolLine[500 5000 1500 3000 800] + SymbolLine[1500 3000 2500 5000 800] + SymbolLine[2500 5000 3000 3000 800] + SymbolLine[3000 3000 3000 1000 800] +) +Symbol['X' 1200] +( + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 1000 2500 5000 800] +) +Symbol['Y' 1200] +( + SymbolLine[0 1000 1000 3000 800] + SymbolLine[1000 3000 2000 1000 800] + SymbolLine[1000 3000 1000 5000 800] +) +Symbol['Z' 1200] +( + SymbolLine[0 1000 2500 1000 800] + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['[' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['\' 1200] +( + SymbolLine[0 1500 3000 4500 800] +) +Symbol[']' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['^' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1500 800] +) +Symbol['_' 1200] +( + SymbolLine[0 5000 2000 5000 800] +) +Symbol['a' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[2000 4500 2500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['b' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] +) +Symbol['c' 1200] +( + SymbolLine[500 3000 2000 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] +) +Symbol['d' 1200] +( + SymbolLine[2000 1000 2000 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] +) +Symbol['e' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[0 4000 2000 4000 800] + SymbolLine[2000 4000 2000 3500 800] +) +Symbol['f' 1000] +( + SymbolLine[500 1500 500 5000 800] + SymbolLine[500 1500 1000 1000 800] + SymbolLine[1000 1000 1500 1000 800] + SymbolLine[0 3000 1000 3000 800] +) +Symbol['g' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[2000 3000 2000 6000 800] +) +Symbol['h' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] +) +Symbol['i' 1000] +( + SymbolLine[0 2000 0 2100 1000] + SymbolLine[0 3500 0 5000 800] +) +Symbol['j' 1000] +( + SymbolLine[500 2000 500 2100 1000] + SymbolLine[500 3500 500 6000 800] + SymbolLine[0 6500 500 6000 800] +) +Symbol['k' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 1500 5000 800] + SymbolLine[0 3500 1000 2500 800] +) +Symbol['l' 1000] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['m' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[2000 3500 2500 3000 800] + SymbolLine[2500 3000 3000 3000 800] + SymbolLine[3000 3000 3500 3500 800] + SymbolLine[3500 3500 3500 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['n' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['o' 1200] +( + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['p' 1200] +( + SymbolLine[500 3500 500 6500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[1000 5000 2000 5000 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['q' 1200] +( + SymbolLine[2000 3500 2000 6500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['r' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['s' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2000 4000 2500 4500 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['t' 1000] +( + SymbolLine[500 1000 500 4500 800] + SymbolLine[500 4500 1000 5000 800] + SymbolLine[0 2500 1000 2500 800] +) +Symbol['u' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3000 2000 4500 800] +) +Symbol['v' 1200] +( + SymbolLine[0 3000 1000 5000 800] + SymbolLine[2000 3000 1000 5000 800] +) +Symbol['w' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[1500 3000 1500 4500 800] + SymbolLine[1500 4500 2000 5000 800] + SymbolLine[2000 5000 2500 5000 800] + SymbolLine[2500 5000 3000 4500 800] + SymbolLine[3000 3000 3000 4500 800] +) +Symbol['x' 1200] +( + SymbolLine[0 3000 2000 5000 800] + SymbolLine[0 5000 2000 3000 800] +) +Symbol['y' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 6000 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['z' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[0 5000 2000 3000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['{' 1200] +( + SymbolLine[500 1500 1000 1000 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['|' 1200] +( + SymbolLine[0 1000 0 5000 800] +) +Symbol['}' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[500 2500 1000 3000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['~' 1200] +( + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1000 3000 800] + SymbolLine[1000 3000 1500 3500 800] + SymbolLine[1500 3500 2000 3500 800] + SymbolLine[2000 3500 2500 3000 800] +) +Attribute("PCB::grid::unit" "mil") +Via[330000 150000 7874 4000 0 3150 "" ""] + +Element["" "Crystals" "" "HC49" 20000 40000 -11000 5000 1 100 ""] +( + Pin[0 0 6000 3000 6600 2800 "1" "1" "square"] + Pin[0 -20000 6000 3000 6600 2800 "2" "2" ""] + ElementLine [-5000 -20000 -5000 0 2000] + ElementLine [5000 -20000 5000 0 2000] + ElementArc [0 -20000 5000 5000 180 180 2000] + ElementArc [0 0 5000 5000 0 180 2000] + + ) + +Element["" "Crystals" "" "HC49U" 50000 39200 -15100 12100 1 100 ""] +( + Pin[0 0 6000 3000 6600 3200 "1" "1" "square"] + Pin[0 -19200 6000 3000 6600 3200 "2" "2" ""] + ElementLine [-9100 -22300 -9100 3000 2000] + ElementLine [9200 -22300 9200 3000 2000] + ElementArc [0 -22300 9100 9100 180 180 2000] + ElementArc [0 3000 9100 9100 0 180 2000] + + ) + +Element["" "Crystals" "" "HC49UH" 180000 50000 -67500 12100 1 100 ""] +( + Pin[0 0 6000 3000 6600 3200 "1" "1" "square,edge2"] + Pin[0 -19200 6000 3000 6600 3200 "2" "2" "edge2"] + ElementLine [-61500 -31400 -61500 12100 2000] + ElementLine [-61500 -31400 -10000 -31400 2000] + ElementLine [-10000 -31400 -10000 12100 2000] + ElementLine [-61500 12100 -10000 12100 2000] + + ) + +Element["" "Crystals" "" "HC51U" 90000 68500 -23600 13600 1 100 ""] +( + Pin[0 0 8000 3000 8600 4000 "1" "1" "square"] + Pin[0 -48500 8000 3000 8600 4000 "2" "2" ""] + ElementLine [-17600 -44500 -17600 -4000 2000] + ElementLine [17600 -44500 17600 -4000 2000] + ElementArc [0 -44500 17600 17600 180 180 2000] + ElementArc [0 -4000 17600 17600 0 180 2000] + + ) + +Element["" "Crystals" "" "HC51UH" 290000 70000 -103500 13600 1 100 ""] +( + Pin[0 0 8000 3000 8600 4000 "1" "1" "square,edge2"] + Pin[0 -48500 8000 3000 8600 4000 "2" "2" "edge2"] + ElementLine [-97500 -62100 -97500 13600 2000] + ElementLine [-97500 -62100 -20000 -62100 2000] + ElementLine [-20000 -62100 -20000 13600 2000] + ElementLine [-97500 13600 -20000 13600 2000] + + ) + +Element["" "LED, size in mm (pin 1 is +, 2 is -)" "" "LED3" 30000 125000 7000 -10000 1 100 ""] +( + Pin[0 5000 6500 3000 7100 4300 "1" "1" "square"] + Pin[0 -5000 6500 3000 7100 4300 "2" "2" ""] + ElementArc [0 0 5900 5900 135 90 1000] + ElementArc [0 0 5900 5900 315 90 1000] + ElementArc [0 0 7900 7900 135 90 1000] + ElementArc [0 0 7900 7900 315 90 1000] + + ) + +Element["" "LED, size in mm (pin 1 is +, 2 is -)" "" "LED5" 70000 125000 7000 -10000 1 100 ""] +( + Pin[0 5000 6500 3000 7100 4300 "1" "1" "square"] + Pin[0 -5000 6500 3000 7100 4300 "2" "2" ""] + ElementArc [0 0 11800 11800 90 360 1000] + ElementArc [0 0 13800 13800 90 360 1000] + + ) + +Element["" "diode in TO220" "" "TO220ACSTAND" 170000 142000 36000 -17000 3 100 ""] +( + Pin[0 -12000 8000 3000 8600 4000 "1" "1" "square,edge2"] + Pin[20000 -12000 8000 3000 8600 4000 "2" "2" "edge2"] + ElementLine [-10000 -22000 -10000 -4000 2000] + ElementLine [-10000 -4000 30000 -4000 2000] + ElementLine [30000 -4000 30000 -22000 2000] + ElementLine [30000 -22000 -10000 -22000 2000] + ElementLine [-10000 -17000 30000 -17000 1000] + ElementLine [2500 -22000 2500 -17000 1000] + ElementLine [17500 -22000 17500 -17000 1000] + + ) + +Element["" "diode in TO220" "" "TO247_2" 230000 140000 59400 -22000 3 100 ""] +( + Pin[0 -14000 10000 3000 10600 6000 "1" "1" "square,edge2"] + Pin[43800 -14000 10000 3000 10600 6000 "2" "2" "edge2"] + ElementLine [-9600 -27000 -9600 -6000 2000] + ElementLine [-9600 -6000 53400 -6000 2000] + ElementLine [53400 -6000 53400 -27000 2000] + ElementLine [53400 -27000 -9600 -27000 2000] + ElementLine [-9600 -22000 53400 -22000 1000] + ElementLine [14400 -27000 14400 -22000 1000] + ElementLine [29400 -27000 29400 -22000 1000] + + ) +Layer(1 "component") +( +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( + Line[0 100000 330000 100000 1000 4000 "clearline"] + Line[130000 100000 130000 150000 1000 4000 "clearline"] + Text[310000 40000 0 200 "HC" "clearline"] + Text[100000 120000 0 200 "LED" "clearline"] + Text[300000 120000 0 200 "TO" "clearline"] +) Index: tags/2.3.0/util/pcblib-map/trh3.pcb =================================================================== --- tags/2.3.0/util/pcblib-map/trh3.pcb (nonexistent) +++ tags/2.3.0/util/pcblib-map/trh3.pcb (revision 33253) @@ -0,0 +1,1096 @@ +# release: pcb 20110918 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 270000 240000] + +Grid[10000.0 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Symbol[' ' 1800] +( +) +Symbol['!' 1200] +( + SymbolLine[0 4500 0 5000 800] + SymbolLine[0 1000 0 3500 800] +) +Symbol['"' 1200] +( + SymbolLine[0 1000 0 2000 800] + SymbolLine[1000 1000 1000 2000 800] +) +Symbol['#' 1200] +( + SymbolLine[0 3500 2000 3500 800] + SymbolLine[0 2500 2000 2500 800] + SymbolLine[1500 2000 1500 4000 800] + SymbolLine[500 2000 500 4000 800] +) +Symbol['$' 1200] +( + SymbolLine[1500 1500 2000 2000 800] + SymbolLine[500 1500 1500 1500 800] + SymbolLine[0 2000 500 1500 800] + SymbolLine[0 2000 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4000 800] + SymbolLine[1500 4500 2000 4000 800] + SymbolLine[500 4500 1500 4500 800] + SymbolLine[0 4000 500 4500 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['%' 1200] +( + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[1000 2500 1500 2000 800] + SymbolLine[500 2500 1000 2500 800] + SymbolLine[0 2000 500 2500 800] + SymbolLine[0 5000 4000 1000 800] + SymbolLine[3500 5000 4000 4500 800] + SymbolLine[4000 4000 4000 4500 800] + SymbolLine[3500 3500 4000 4000 800] + SymbolLine[3000 3500 3500 3500 800] + SymbolLine[2500 4000 3000 3500 800] + SymbolLine[2500 4000 2500 4500 800] + SymbolLine[2500 4500 3000 5000 800] + SymbolLine[3000 5000 3500 5000 800] +) +Symbol['&' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 3500 1500 2000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[0 2500 2500 5000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[0 3500 0 4500 800] +) +Symbol[''' 1200] +( + SymbolLine[0 2000 1000 1000 800] +) +Symbol['(' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] +) +Symbol[')' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['*' 1200] +( + SymbolLine[0 2000 2000 4000 800] + SymbolLine[0 4000 2000 2000 800] + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol['+' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol[',' 1200] +( + SymbolLine[0 6000 1000 5000 800] +) +Symbol['-' 1200] +( + SymbolLine[0 3000 2000 3000 800] +) +Symbol['.' 1200] +( + SymbolLine[0 5000 500 5000 800] +) +Symbol['/' 1200] +( + SymbolLine[0 4500 3000 1500 800] +) +Symbol['0' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4000 2000 2000 800] +) +Symbol['1' 1200] +( + SymbolLine[0 1800 800 1000 800] + SymbolLine[800 1000 800 5000 800] + SymbolLine[0 5000 1500 5000 800] +) +Symbol['2' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[0 5000 2500 2500 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['3' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 2800 1500 2800 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[2000 3300 2000 4500 800] + SymbolLine[2000 3300 1500 2800 800] + SymbolLine[2000 2300 1500 2800 800] +) +Symbol['4' 1200] +( + SymbolLine[0 3500 2000 1000 800] + SymbolLine[0 3500 2500 3500 800] + SymbolLine[2000 1000 2000 5000 800] +) +Symbol['5' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[500 2500 1500 2500 800] + SymbolLine[1500 2500 2000 3000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['6' 1200] +( + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1500 2800 2000 3300 800] + SymbolLine[0 2800 1500 2800 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3300 2000 4500 800] +) +Symbol['7' 1200] +( + SymbolLine[500 5000 2500 1000 800] + SymbolLine[0 1000 2500 1000 800] +) +Symbol['8' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3700 0 4500 800] + SymbolLine[0 3700 700 3000 800] + SymbolLine[700 3000 1300 3000 800] + SymbolLine[1300 3000 2000 3700 800] + SymbolLine[2000 3700 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 2300 700 3000 800] + SymbolLine[0 1500 0 2300 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[1300 3000 2000 2300 800] +) +Symbol['9' 1200] +( + SymbolLine[500 5000 2000 3000 800] + SymbolLine[2000 1500 2000 3000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol[':' 1200] +( + SymbolLine[0 2500 500 2500 800] + SymbolLine[0 3500 500 3500 800] +) +Symbol[';' 1200] +( + SymbolLine[0 5000 1000 4000 800] + SymbolLine[1000 2500 1000 3000 800] +) +Symbol['<' 1200] +( + SymbolLine[0 3000 1000 2000 800] + SymbolLine[0 3000 1000 4000 800] +) +Symbol['=' 1200] +( + SymbolLine[0 2500 2000 2500 800] + SymbolLine[0 3500 2000 3500 800] +) +Symbol['>' 1200] +( + SymbolLine[0 2000 1000 3000 800] + SymbolLine[0 4000 1000 3000 800] +) +Symbol['?' 1200] +( + SymbolLine[1000 3000 1000 3500 800] + SymbolLine[1000 4500 1000 5000 800] + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2000 800] + SymbolLine[1000 3000 2000 2000 800] +) +Symbol['@' 1200] +( + SymbolLine[0 1000 0 4000 800] + SymbolLine[0 4000 1000 5000 800] + SymbolLine[1000 5000 4000 5000 800] + SymbolLine[5000 3500 5000 1000 800] + SymbolLine[5000 1000 4000 0 800] + SymbolLine[4000 0 1000 0 800] + SymbolLine[1000 0 0 1000 800] + SymbolLine[1500 2000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 3000 3500 800] + SymbolLine[3000 3500 3500 3000 800] + SymbolLine[3500 3000 4000 3500 800] + SymbolLine[3500 3000 3500 1500 800] + SymbolLine[3500 2000 3000 1500 800] + SymbolLine[2000 1500 3000 1500 800] + SymbolLine[2000 1500 1500 2000 800] + SymbolLine[4000 3500 5000 3500 800] +) +Symbol['A' 1200] +( + SymbolLine[0 2000 0 5000 800] + SymbolLine[0 2000 700 1000 800] + SymbolLine[700 1000 1800 1000 800] + SymbolLine[1800 1000 2500 2000 800] + SymbolLine[2500 2000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['B' 1200] +( + SymbolLine[0 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3300 2500 4500 800] + SymbolLine[2000 2800 2500 3300 800] + SymbolLine[500 2800 2000 2800 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2300 800] + SymbolLine[2000 2800 2500 2300 800] +) +Symbol['C' 1200] +( + SymbolLine[700 5000 2000 5000 800] + SymbolLine[0 4300 700 5000 800] + SymbolLine[0 1700 0 4300 800] + SymbolLine[0 1700 700 1000 800] + SymbolLine[700 1000 2000 1000 800] +) +Symbol['D' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[1800 1000 2500 1700 800] + SymbolLine[2500 1700 2500 4300 800] + SymbolLine[1800 5000 2500 4300 800] + SymbolLine[0 5000 1800 5000 800] + SymbolLine[0 1000 1800 1000 800] +) +Symbol['E' 1200] +( + SymbolLine[0 2800 1500 2800 800] + SymbolLine[0 5000 2000 5000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] +) +Symbol['F' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 2800 1500 2800 800] +) +Symbol['G' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[1000 3000 2000 3000 800] +) +Symbol['H' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[2500 1000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['I' 1200] +( + SymbolLine[0 1000 1000 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 1000 5000 800] +) +Symbol['J' 1200] +( + SymbolLine[700 1000 1500 1000 800] + SymbolLine[1500 1000 1500 4500 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 4500 0 4000 800] +) +Symbol['K' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3000 2000 1000 800] + SymbolLine[0 3000 2000 5000 800] +) +Symbol['L' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['M' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 1500 3000 800] + SymbolLine[1500 3000 3000 1000 800] + SymbolLine[3000 1000 3000 5000 800] +) +Symbol['N' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2500 5000 800] + SymbolLine[2500 1000 2500 5000 800] +) +Symbol['O' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['P' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol['Q' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1000 3500 2000 5000 800] +) +Symbol['R' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[1300 3000 2500 5000 800] +) +Symbol['S' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['T' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['U' 1200] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 1000 2000 4500 800] +) +Symbol['V' 1200] +( + SymbolLine[0 1000 1000 5000 800] + SymbolLine[1000 5000 2000 1000 800] +) +Symbol['W' 1200] +( + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 5000 800] + SymbolLine[500 5000 1500 3000 800] + SymbolLine[1500 3000 2500 5000 800] + SymbolLine[2500 5000 3000 3000 800] + SymbolLine[3000 3000 3000 1000 800] +) +Symbol['X' 1200] +( + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 1000 2500 5000 800] +) +Symbol['Y' 1200] +( + SymbolLine[0 1000 1000 3000 800] + SymbolLine[1000 3000 2000 1000 800] + SymbolLine[1000 3000 1000 5000 800] +) +Symbol['Z' 1200] +( + SymbolLine[0 1000 2500 1000 800] + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['[' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['\' 1200] +( + SymbolLine[0 1500 3000 4500 800] +) +Symbol[']' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['^' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1500 800] +) +Symbol['_' 1200] +( + SymbolLine[0 5000 2000 5000 800] +) +Symbol['a' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[2000 4500 2500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['b' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] +) +Symbol['c' 1200] +( + SymbolLine[500 3000 2000 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] +) +Symbol['d' 1200] +( + SymbolLine[2000 1000 2000 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] +) +Symbol['e' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[0 4000 2000 4000 800] + SymbolLine[2000 4000 2000 3500 800] +) +Symbol['f' 1000] +( + SymbolLine[500 1500 500 5000 800] + SymbolLine[500 1500 1000 1000 800] + SymbolLine[1000 1000 1500 1000 800] + SymbolLine[0 3000 1000 3000 800] +) +Symbol['g' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[2000 3000 2000 6000 800] +) +Symbol['h' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] +) +Symbol['i' 1000] +( + SymbolLine[0 2000 0 2100 1000] + SymbolLine[0 3500 0 5000 800] +) +Symbol['j' 1000] +( + SymbolLine[500 2000 500 2100 1000] + SymbolLine[500 3500 500 6000 800] + SymbolLine[0 6500 500 6000 800] +) +Symbol['k' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 1500 5000 800] + SymbolLine[0 3500 1000 2500 800] +) +Symbol['l' 1000] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['m' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[2000 3500 2500 3000 800] + SymbolLine[2500 3000 3000 3000 800] + SymbolLine[3000 3000 3500 3500 800] + SymbolLine[3500 3500 3500 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['n' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['o' 1200] +( + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['p' 1200] +( + SymbolLine[500 3500 500 6500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[1000 5000 2000 5000 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['q' 1200] +( + SymbolLine[2000 3500 2000 6500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['r' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['s' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2000 4000 2500 4500 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['t' 1000] +( + SymbolLine[500 1000 500 4500 800] + SymbolLine[500 4500 1000 5000 800] + SymbolLine[0 2500 1000 2500 800] +) +Symbol['u' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3000 2000 4500 800] +) +Symbol['v' 1200] +( + SymbolLine[0 3000 1000 5000 800] + SymbolLine[2000 3000 1000 5000 800] +) +Symbol['w' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[1500 3000 1500 4500 800] + SymbolLine[1500 4500 2000 5000 800] + SymbolLine[2000 5000 2500 5000 800] + SymbolLine[2500 5000 3000 4500 800] + SymbolLine[3000 3000 3000 4500 800] +) +Symbol['x' 1200] +( + SymbolLine[0 3000 2000 5000 800] + SymbolLine[0 5000 2000 3000 800] +) +Symbol['y' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 6000 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['z' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[0 5000 2000 3000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['{' 1200] +( + SymbolLine[500 1500 1000 1000 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['|' 1200] +( + SymbolLine[0 1000 0 5000 800] +) +Symbol['}' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[500 2500 1000 3000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['~' 1200] +( + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1000 3000 800] + SymbolLine[1000 3000 1500 3500 800] + SymbolLine[1500 3500 2000 3500 800] + SymbolLine[2000 3500 2500 3000 800] +) +Attribute("PCB::grid::unit" "mil") +Via[270000 240000 7874 4000 0 3150 "" ""] + +Element["" "Crystals" "" "HC49U_3" 30000 50000 -15100 12100 1 100 ""] +( + Pin[0 0 6000 3000 6600 3200 "1" "1" "square"] + Pin[0 -9600 6000 3000 6600 3200 "2" "2" ""] + Pin[0 -19200 6000 3000 6600 3200 "3" "3" ""] + ElementLine [-9100 -22300 -9100 3000 2000] + ElementLine [9200 -22300 9200 3000 2000] + ElementArc [0 -22300 9100 9100 180 180 2000] + ElementArc [0 3000 9100 9100 0 180 2000] + + ) + +Element["" "Crystals" "" "HC49U_3H" 110000 50000 -67500 12100 1 100 ""] +( + Pin[0 0 6000 3000 6600 3200 "1" "1" "square,edge2"] + Pin[0 -9600 6000 3000 6600 3200 "2" "2" "edge2"] + Pin[0 -19200 6000 3000 6600 3200 "3" "3" "edge2"] + ElementLine [-61500 -31400 -61500 12100 2000] + ElementLine [-61500 -31400 -10000 -31400 2000] + ElementLine [-10000 -31400 -10000 12100 2000] + ElementLine [-61500 12100 -10000 12100 2000] + + ) + +Element["" "Transistor" "" "TO126" 140000 220000 -2000 -12000 1 100 ""] +( + Pin[1000 0 8000 3000 8600 5200 "1" "1" "square"] + Pin[10000 0 8000 3000 8600 5200 "2" "2" ""] + Pin[19000 0 8000 3000 8600 5200 "3" "3" ""] + Pin[10000 -43000 13000 3000 13600 11000 "4" "4" ""] + ElementLine [0 -10000 0 0 3000] + ElementLine [10000 -10000 10000 0 3000] + ElementLine [20000 -10000 20000 0 3000] + ElementLine [-5000 -10000 25000 -10000 2000] + ElementLine [25000 -53000 25000 -10000 2000] + ElementLine [-5000 -53000 25000 -53000 2000] + ElementLine [-5000 -53000 -5000 -10000 2000] + + ) + +Element["" "Transistor" "" "TO126S" 199000 220000 -2000 -12000 1 100 ""] +( + Pin[1000 0 8000 3000 8600 5200 "1" "1" "square"] + Pin[10000 10000 8000 3000 8600 5200 "2" "2" ""] + Pin[19000 0 8000 3000 8600 5200 "3" "3" ""] + Pin[10000 -43000 13000 3000 13600 11000 "4" "4" ""] + ElementLine [0 -10000 0 0 3000] + ElementLine [10000 -10000 10000 10000 3000] + ElementLine [20000 -10000 20000 0 3000] + ElementLine [-5000 -10000 25000 -10000 2000] + ElementLine [25000 -53000 25000 -10000 2000] + ElementLine [-5000 -53000 25000 -53000 2000] + ElementLine [-5000 -53000 -5000 -10000 2000] + + ) + +Element["" "Transistor" "" "TO126SW" 40000 110000 7000 -17000 1 100 ""] +( + Pin[0 -1000 8000 3000 8600 5200 "1" "1" "square"] + Pin[10000 -10000 8000 3000 8600 5200 "2" "2" ""] + Pin[0 -19000 8000 3000 8600 5200 "3" "3" ""] + ElementLine [5000 -10000 10000 -10000 3000] + ElementLine [-5000 -25000 -5000 5000 2000] + ElementLine [-5000 -25000 5000 -25000 2000] + ElementLine [5000 -25000 5000 5000 2000] + ElementLine [-5000 5000 5000 5000 2000] + ElementLine [-5000 -5000 5000 -5000 1000] + ElementLine [-5000 -15000 5000 -15000 1000] + + ) + +Element["" "Transistor" "" "TO126W" 70000 110000 7000 4000 1 100 ""] +( + Pin[0 -1000 8000 3000 8600 5200 "1" "1" "square"] + Pin[0 -10000 8000 3000 8600 5200 "2" "2" ""] + Pin[0 -19000 8000 3000 8600 5200 "3" "3" ""] + ElementLine [-5000 -25000 -5000 5000 2000] + ElementLine [-5000 -25000 5000 -25000 2000] + ElementLine [5000 -25000 5000 5000 2000] + ElementLine [-5000 5000 5000 5000 2000] + + ) + +Element["" "Transistor" "" "TO18" 165000 30000 6000 7000 0 100 ""] +( + Pin[0 -5000 5500 3000 6100 3500 "1" "1" ""] + Pin[-5000 0 5500 3000 6100 3500 "2" "2" ""] + Pin[0 5000 5500 3000 6100 3500 "3" "3" ""] + ElementLine [6700 -7900 9400 -10600 1000] + ElementLine [7300 -7300 10000 -10000 1000] + ElementLine [7900 -6700 10600 -9400 1000] + ElementLine [9400 -10600 10600 -9400 1000] + ElementArc [0 0 9800 9800 0 360 1000] + + ) + +Element["" "diode in TO220" "" "TO218" 224000 121900 -21000 -58700 0 100 ""] +( + Pin[-14000 0 10000 3000 10600 6000 "1" "1" "square"] + Pin[-14000 -21900 10000 3000 10600 6000 "2" "2" ""] + Pin[-14000 -43800 10000 3000 10600 6000 "3" "3" ""] + ElementLine [-26000 8800 -6000 8800 2000] + ElementLine [-6000 -52700 -6000 8800 2000] + ElementLine [-26000 -52700 -6000 -52700 2000] + ElementLine [-26000 -52700 -26000 8800 2000] + ElementLine [-21000 -52700 -21000 8800 1000] + ElementLine [-26000 -14400 -21000 -14400 1000] + ElementLine [-26000 -29400 -21000 -29400 1000] + + ) + +Element["" "Transistor" "" "TO220" 90000 220000 -15000 -23000 1 100 ""] +( + Pin[-10000 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[0 0 9000 3000 9600 6000 "2" "2" ""] + Pin[10000 0 9000 3000 9600 6000 "3" "3" ""] + Pin[0 -67000 15000 3000 15600 13000 "4" "4" ""] + ElementLine [-10000 -18000 -10000 0 3000] + ElementLine [0 -18000 0 0 3000] + ElementLine [10000 -18000 10000 0 3000] + ElementLine [-20000 -18000 20000 -18000 2000] + ElementLine [20000 -55500 20000 -18000 2000] + ElementLine [-20000 -55500 20000 -55500 2000] + ElementLine [-20000 -55500 -20000 -18000 2000] + ElementLine [-20000 -55500 20000 -55500 2000] + ElementLine [20000 -68000 20000 -55500 2000] + ElementLine [18500 -68000 20000 -68000 2000] + ElementLine [18500 -75000 18500 -68000 2000] + ElementLine [18500 -75000 20000 -75000 2000] + ElementLine [20000 -79000 20000 -75000 2000] + ElementLine [-20000 -79000 20000 -79000 2000] + ElementLine [-20000 -79000 -20000 -75000 2000] + ElementLine [-20000 -75000 -18500 -75000 2000] + ElementLine [-18500 -75000 -18500 -68000 2000] + ElementLine [-20000 -68000 -18500 -68000 2000] + ElementLine [-20000 -68000 -20000 -55500 2000] + + ) + +Element["" "Transistor" "" "TO220S" 30000 220000 -15000 -23000 1 100 ""] +( + Pin[-10000 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[0 10000 9000 3000 9600 6000 "2" "2" ""] + Pin[10000 0 9000 3000 9600 6000 "3" "3" ""] + Pin[0 -67000 15000 3000 15600 13000 "4" "4" ""] + ElementLine [-10000 -18000 -10000 0 3000] + ElementLine [0 -18000 0 10000 3000] + ElementLine [10000 -18000 10000 0 3000] + ElementLine [-20000 -18000 20000 -18000 2000] + ElementLine [20000 -55500 20000 -18000 2000] + ElementLine [-20000 -55500 20000 -55500 2000] + ElementLine [-20000 -55500 -20000 -18000 2000] + ElementLine [-20000 -55500 20000 -55500 2000] + ElementLine [20000 -68000 20000 -55500 2000] + ElementLine [18500 -68000 20000 -68000 2000] + ElementLine [18500 -75000 18500 -68000 2000] + ElementLine [18500 -75000 20000 -75000 2000] + ElementLine [20000 -79000 20000 -75000 2000] + ElementLine [-20000 -79000 20000 -79000 2000] + ElementLine [-20000 -79000 -20000 -75000 2000] + ElementLine [-20000 -75000 -18500 -75000 2000] + ElementLine [-18500 -75000 -18500 -68000 2000] + ElementLine [-20000 -68000 -18500 -68000 2000] + ElementLine [-20000 -68000 -20000 -55500 2000] + + ) + +Element["" "Transistor" "" "TO220SW" 130000 110000 -19000 10000 1 100 ""] +( + Pin[0 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[10000 -10000 9000 3000 9600 6000 "2" "2" ""] + Pin[0 -20000 9000 3000 9600 6000 "3" "3" ""] + ElementLine [-12000 -30000 -12000 10000 2000] + ElementLine [-12000 -30000 6000 -30000 2000] + ElementLine [6000 -30000 6000 10000 2000] + ElementLine [-12000 10000 6000 10000 2000] + ElementLine [-12000 -30000 -12000 10000 2000] + ElementLine [-12000 -30000 -6000 -30000 2000] + ElementLine [-6000 -30000 -6000 10000 2000] + ElementLine [-12000 10000 -6000 10000 2000] + ElementLine [-12000 -3000 -6000 -3000 1000] + ElementLine [-12000 -17000 -6000 -17000 1000] + ElementLine [6000 -10000 10000 -10000 3000] + + ) + +Element["" "Transistor" "" "TO220W" 100000 110000 -19000 10000 1 100 ""] +( + Pin[0 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[0 -10000 9000 3000 9600 6000 "2" "2" ""] + Pin[0 -20000 9000 3000 9600 6000 "3" "3" ""] + ElementLine [-12000 -30000 -12000 10000 2000] + ElementLine [-12000 -30000 6000 -30000 2000] + ElementLine [6000 -30000 6000 10000 2000] + ElementLine [-12000 10000 6000 10000 2000] + ElementLine [-12000 -30000 -12000 10000 2000] + ElementLine [-12000 -30000 -6000 -30000 2000] + ElementLine [-6000 -30000 -6000 10000 2000] + ElementLine [-12000 10000 -6000 10000 2000] + ElementLine [-12000 -3000 -6000 -3000 1000] + ElementLine [-12000 -17000 -6000 -17000 1000] + + ) + +Element["" "diode in TO220" "" "TO247" 184000 121900 -22000 -59400 0 100 ""] +( + Pin[-14000 0 10000 3000 10600 6000 "1" "1" "square"] + Pin[-14000 -21900 10000 3000 10600 6000 "2" "2" ""] + Pin[-14000 -43800 10000 3000 10600 6000 "3" "3" ""] + ElementLine [-27000 9600 -6000 9600 2000] + ElementLine [-6000 -53400 -6000 9600 2000] + ElementLine [-27000 -53400 -6000 -53400 2000] + ElementLine [-27000 -53400 -27000 9600 2000] + ElementLine [-22000 -53400 -22000 9600 1000] + ElementLine [-27000 -14400 -22000 -14400 1000] + ElementLine [-27000 -29400 -22000 -29400 1000] + + ) + +Element["" "diode in TO220" "" "TO251" 19000 109000 -9000 -28300 0 100 ""] +( + Pin[-9000 0 7000 3000 7600 4000 "1" "1" "square"] + Pin[-9000 -9000 7000 3000 7600 4000 "2" "2" ""] + Pin[-9000 -18000 7000 3000 7600 4000 "3" "3" ""] + ElementLine [-14000 4200 -4000 4200 2000] + ElementLine [-4000 -22300 -4000 4200 2000] + ElementLine [-14000 -22300 -4000 -22300 2000] + ElementLine [-14000 -22300 -14000 4200 2000] + ElementLine [-9000 -22300 -9000 4200 1000] + ElementLine [-14000 -1500 -9000 -1500 1000] + ElementLine [-14000 -16500 -9000 -16500 1000] + + ) + +Element["" "diode in TO220" "" "TO264" 264000 121900 -22000 -67900 0 100 ""] +( + Pin[-14000 0 10000 3000 10600 6000 "1" "1" "square"] + Pin[-14000 -21900 10000 3000 10600 6000 "2" "2" ""] + Pin[-14000 -43800 10000 3000 10600 6000 "3" "3" ""] + ElementLine [-27000 18100 -6000 18100 2000] + ElementLine [-6000 -61900 -6000 18100 2000] + ElementLine [-27000 -61900 -6000 -61900 2000] + ElementLine [-27000 -61900 -27000 18100 2000] + ElementLine [-22000 -61900 -22000 18100 1000] + ElementLine [-27000 -14400 -22000 -14400 1000] + ElementLine [-27000 -29400 -22000 -29400 1000] + + ) + +Element["" "Transistor" "" "TO39" 210000 30000 6000 7000 0 100 ""] +( + Pin[0 -10000 5500 3000 6100 3500 "1" "1" "square"] + Pin[-10000 0 5500 3000 6100 3500 "2" "2" ""] + Pin[0 10000 5500 3000 6100 3500 "3" "3" ""] + ElementLine [12700 -13900 14800 -16000 1000] + ElementLine [13300 -13300 15400 -15400 1000] + ElementLine [13900 -12700 16000 -14800 1000] + ElementLine [16000 -14800 14800 -16000 1000] + ElementArc [0 0 18300 18300 0 360 1000] + + ) + +Element["" "Transistor" "" "TO92" 250000 40000 -13000 -1000 1 100 ""] +( + Pin[0 -20000 7200 3000 7800 4200 "1" "1" "square"] + Pin[0 -10000 7200 3000 7800 4200 "2" "2" ""] + Pin[0 0 7200 3000 7800 4200 "3" "3" ""] + ElementLine [-7000 -17000 -7000 -3000 1000] + ElementArc [0 -10000 10000 10000 45 270 1000] + + ) +Layer(1 "component") +( +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( + Line[0 70000 150000 70000 1000 4000 "clearline"] + Line[150000 70000 150000 0 1000 4000 "clearline"] + Text[130000 30000 0 200 "HC" "clearline"] + Text[250000 190000 0 200 "TO" "clearline"] +) Index: tags/2.3.0/util/pcblib-map/trhN.pcb =================================================================== --- tags/2.3.0/util/pcblib-map/trhN.pcb (nonexistent) +++ tags/2.3.0/util/pcblib-map/trhN.pcb (revision 33253) @@ -0,0 +1,983 @@ +# release: pcb 20110918 + +# To read pcb files, the pcb version (or the git source date) must be >= the file version +FileVersion[20070407] + +PCB["" 220000 170000] + +Grid[10000.0 0 0 1] +Cursor[0 0 0.000000] +PolyArea[3100.006200] +Thermal[0.500000] +DRC[1200 900 1000 700 1500 1000] +Flags("nameonpcb,clearnew,snappin") +Groups("1,3,4,c:2,5,6,s:7:8") +Styles["Signal,1000,7874,3150,2000:Power,2000,8661,3937,2000:Fat,8000,13780,4724,2500:Sig-tight,1000,6400,3150,1200"] + +Symbol[' ' 1800] +( +) +Symbol['!' 1200] +( + SymbolLine[0 4500 0 5000 800] + SymbolLine[0 1000 0 3500 800] +) +Symbol['"' 1200] +( + SymbolLine[0 1000 0 2000 800] + SymbolLine[1000 1000 1000 2000 800] +) +Symbol['#' 1200] +( + SymbolLine[0 3500 2000 3500 800] + SymbolLine[0 2500 2000 2500 800] + SymbolLine[1500 2000 1500 4000 800] + SymbolLine[500 2000 500 4000 800] +) +Symbol['$' 1200] +( + SymbolLine[1500 1500 2000 2000 800] + SymbolLine[500 1500 1500 1500 800] + SymbolLine[0 2000 500 1500 800] + SymbolLine[0 2000 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4000 800] + SymbolLine[1500 4500 2000 4000 800] + SymbolLine[500 4500 1500 4500 800] + SymbolLine[0 4000 500 4500 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['%' 1200] +( + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[1000 2500 1500 2000 800] + SymbolLine[500 2500 1000 2500 800] + SymbolLine[0 2000 500 2500 800] + SymbolLine[0 5000 4000 1000 800] + SymbolLine[3500 5000 4000 4500 800] + SymbolLine[4000 4000 4000 4500 800] + SymbolLine[3500 3500 4000 4000 800] + SymbolLine[3000 3500 3500 3500 800] + SymbolLine[2500 4000 3000 3500 800] + SymbolLine[2500 4000 2500 4500 800] + SymbolLine[2500 4500 3000 5000 800] + SymbolLine[3000 5000 3500 5000 800] +) +Symbol['&' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 3500 1500 2000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[0 2500 2500 5000 800] + SymbolLine[500 1000 1000 1000 800] + SymbolLine[1000 1000 1500 1500 800] + SymbolLine[1500 1500 1500 2000 800] + SymbolLine[0 3500 0 4500 800] +) +Symbol[''' 1200] +( + SymbolLine[0 2000 1000 1000 800] +) +Symbol['(' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] +) +Symbol[')' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['*' 1200] +( + SymbolLine[0 2000 2000 4000 800] + SymbolLine[0 4000 2000 2000 800] + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol['+' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[1000 2000 1000 4000 800] +) +Symbol[',' 1200] +( + SymbolLine[0 6000 1000 5000 800] +) +Symbol['-' 1200] +( + SymbolLine[0 3000 2000 3000 800] +) +Symbol['.' 1200] +( + SymbolLine[0 5000 500 5000 800] +) +Symbol['/' 1200] +( + SymbolLine[0 4500 3000 1500 800] +) +Symbol['0' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4000 2000 2000 800] +) +Symbol['1' 1200] +( + SymbolLine[0 1800 800 1000 800] + SymbolLine[800 1000 800 5000 800] + SymbolLine[0 5000 1500 5000 800] +) +Symbol['2' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[0 5000 2500 2500 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['3' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 2800 1500 2800 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[2000 3300 2000 4500 800] + SymbolLine[2000 3300 1500 2800 800] + SymbolLine[2000 2300 1500 2800 800] +) +Symbol['4' 1200] +( + SymbolLine[0 3500 2000 1000 800] + SymbolLine[0 3500 2500 3500 800] + SymbolLine[2000 1000 2000 5000 800] +) +Symbol['5' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[500 2500 1500 2500 800] + SymbolLine[1500 2500 2000 3000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['6' 1200] +( + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1500 2800 2000 3300 800] + SymbolLine[0 2800 1500 2800 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3300 2000 4500 800] +) +Symbol['7' 1200] +( + SymbolLine[500 5000 2500 1000 800] + SymbolLine[0 1000 2500 1000 800] +) +Symbol['8' 1200] +( + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3700 0 4500 800] + SymbolLine[0 3700 700 3000 800] + SymbolLine[700 3000 1300 3000 800] + SymbolLine[1300 3000 2000 3700 800] + SymbolLine[2000 3700 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 2300 700 3000 800] + SymbolLine[0 1500 0 2300 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2300 800] + SymbolLine[1300 3000 2000 2300 800] +) +Symbol['9' 1200] +( + SymbolLine[500 5000 2000 3000 800] + SymbolLine[2000 1500 2000 3000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol[':' 1200] +( + SymbolLine[0 2500 500 2500 800] + SymbolLine[0 3500 500 3500 800] +) +Symbol[';' 1200] +( + SymbolLine[0 5000 1000 4000 800] + SymbolLine[1000 2500 1000 3000 800] +) +Symbol['<' 1200] +( + SymbolLine[0 3000 1000 2000 800] + SymbolLine[0 3000 1000 4000 800] +) +Symbol['=' 1200] +( + SymbolLine[0 2500 2000 2500 800] + SymbolLine[0 3500 2000 3500 800] +) +Symbol['>' 1200] +( + SymbolLine[0 2000 1000 3000 800] + SymbolLine[0 4000 1000 3000 800] +) +Symbol['?' 1200] +( + SymbolLine[1000 3000 1000 3500 800] + SymbolLine[1000 4500 1000 5000 800] + SymbolLine[0 1500 0 2000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 2000 800] + SymbolLine[1000 3000 2000 2000 800] +) +Symbol['@' 1200] +( + SymbolLine[0 1000 0 4000 800] + SymbolLine[0 4000 1000 5000 800] + SymbolLine[1000 5000 4000 5000 800] + SymbolLine[5000 3500 5000 1000 800] + SymbolLine[5000 1000 4000 0 800] + SymbolLine[4000 0 1000 0 800] + SymbolLine[1000 0 0 1000 800] + SymbolLine[1500 2000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 3000 3500 800] + SymbolLine[3000 3500 3500 3000 800] + SymbolLine[3500 3000 4000 3500 800] + SymbolLine[3500 3000 3500 1500 800] + SymbolLine[3500 2000 3000 1500 800] + SymbolLine[2000 1500 3000 1500 800] + SymbolLine[2000 1500 1500 2000 800] + SymbolLine[4000 3500 5000 3500 800] +) +Symbol['A' 1200] +( + SymbolLine[0 2000 0 5000 800] + SymbolLine[0 2000 700 1000 800] + SymbolLine[700 1000 1800 1000 800] + SymbolLine[1800 1000 2500 2000 800] + SymbolLine[2500 2000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['B' 1200] +( + SymbolLine[0 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3300 2500 4500 800] + SymbolLine[2000 2800 2500 3300 800] + SymbolLine[500 2800 2000 2800 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2300 800] + SymbolLine[2000 2800 2500 2300 800] +) +Symbol['C' 1200] +( + SymbolLine[700 5000 2000 5000 800] + SymbolLine[0 4300 700 5000 800] + SymbolLine[0 1700 0 4300 800] + SymbolLine[0 1700 700 1000 800] + SymbolLine[700 1000 2000 1000 800] +) +Symbol['D' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[1800 1000 2500 1700 800] + SymbolLine[2500 1700 2500 4300 800] + SymbolLine[1800 5000 2500 4300 800] + SymbolLine[0 5000 1800 5000 800] + SymbolLine[0 1000 1800 1000 800] +) +Symbol['E' 1200] +( + SymbolLine[0 2800 1500 2800 800] + SymbolLine[0 5000 2000 5000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] +) +Symbol['F' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[0 2800 1500 2800 800] +) +Symbol['G' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[1000 3000 2000 3000 800] +) +Symbol['H' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[2500 1000 2500 5000 800] + SymbolLine[0 3000 2500 3000 800] +) +Symbol['I' 1200] +( + SymbolLine[0 1000 1000 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 1000 5000 800] +) +Symbol['J' 1200] +( + SymbolLine[700 1000 1500 1000 800] + SymbolLine[1500 1000 1500 4500 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 4500 0 4000 800] +) +Symbol['K' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3000 2000 1000 800] + SymbolLine[0 3000 2000 5000 800] +) +Symbol['L' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['M' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 1500 3000 800] + SymbolLine[1500 3000 3000 1000 800] + SymbolLine[3000 1000 3000 5000 800] +) +Symbol['N' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 1000 2500 5000 800] + SymbolLine[2500 1000 2500 5000 800] +) +Symbol['O' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['P' 1200] +( + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] +) +Symbol['Q' 1200] +( + SymbolLine[0 1500 0 4500 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1500 1000 800] + SymbolLine[1500 1000 2000 1500 800] + SymbolLine[2000 1500 2000 4000 800] + SymbolLine[1000 5000 2000 4000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[1000 3500 2000 5000 800] +) +Symbol['R' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[2500 1500 2500 2500 800] + SymbolLine[2000 3000 2500 2500 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[1300 3000 2500 5000 800] +) +Symbol['S' 1200] +( + SymbolLine[2000 1000 2500 1500 800] + SymbolLine[500 1000 2000 1000 800] + SymbolLine[0 1500 500 1000 800] + SymbolLine[0 1500 0 2500 800] + SymbolLine[0 2500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['T' 1200] +( + SymbolLine[0 1000 2000 1000 800] + SymbolLine[1000 1000 1000 5000 800] +) +Symbol['U' 1200] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 1000 2000 4500 800] +) +Symbol['V' 1200] +( + SymbolLine[0 1000 1000 5000 800] + SymbolLine[1000 5000 2000 1000 800] +) +Symbol['W' 1200] +( + SymbolLine[0 1000 0 3000 800] + SymbolLine[0 3000 500 5000 800] + SymbolLine[500 5000 1500 3000 800] + SymbolLine[1500 3000 2500 5000 800] + SymbolLine[2500 5000 3000 3000 800] + SymbolLine[3000 3000 3000 1000 800] +) +Symbol['X' 1200] +( + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 1000 2500 5000 800] +) +Symbol['Y' 1200] +( + SymbolLine[0 1000 1000 3000 800] + SymbolLine[1000 3000 2000 1000 800] + SymbolLine[1000 3000 1000 5000 800] +) +Symbol['Z' 1200] +( + SymbolLine[0 1000 2500 1000 800] + SymbolLine[0 5000 2500 1000 800] + SymbolLine[0 5000 2500 5000 800] +) +Symbol['[' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['\' 1200] +( + SymbolLine[0 1500 3000 4500 800] +) +Symbol[']' 1200] +( + SymbolLine[0 1000 500 1000 800] + SymbolLine[500 1000 500 5000 800] + SymbolLine[0 5000 500 5000 800] +) +Symbol['^' 1200] +( + SymbolLine[0 1500 500 1000 800] + SymbolLine[500 1000 1000 1500 800] +) +Symbol['_' 1200] +( + SymbolLine[0 5000 2000 5000 800] +) +Symbol['a' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 4500 800] + SymbolLine[2000 4500 2500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['b' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] +) +Symbol['c' 1200] +( + SymbolLine[500 3000 2000 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 2000 5000 800] +) +Symbol['d' 1200] +( + SymbolLine[2000 1000 2000 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] +) +Symbol['e' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[0 4000 2000 4000 800] + SymbolLine[2000 4000 2000 3500 800] +) +Symbol['f' 1000] +( + SymbolLine[500 1500 500 5000 800] + SymbolLine[500 1500 1000 1000 800] + SymbolLine[1000 1000 1500 1000 800] + SymbolLine[0 3000 1000 3000 800] +) +Symbol['g' 1200] +( + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[2000 3000 2000 6000 800] +) +Symbol['h' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] +) +Symbol['i' 1000] +( + SymbolLine[0 2000 0 2100 1000] + SymbolLine[0 3500 0 5000 800] +) +Symbol['j' 1000] +( + SymbolLine[500 2000 500 2100 1000] + SymbolLine[500 3500 500 6000 800] + SymbolLine[0 6500 500 6000 800] +) +Symbol['k' 1200] +( + SymbolLine[0 1000 0 5000 800] + SymbolLine[0 3500 1500 5000 800] + SymbolLine[0 3500 1000 2500 800] +) +Symbol['l' 1000] +( + SymbolLine[0 1000 0 4500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['m' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[2000 3500 2500 3000 800] + SymbolLine[2500 3000 3000 3000 800] + SymbolLine[3000 3000 3500 3500 800] + SymbolLine[3500 3500 3500 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['n' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 5000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['o' 1200] +( + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[2000 3500 2000 4500 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['p' 1200] +( + SymbolLine[500 3500 500 6500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[2500 3500 2500 4500 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[1000 5000 2000 5000 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['q' 1200] +( + SymbolLine[2000 3500 2000 6500 800] + SymbolLine[1500 3000 2000 3500 800] + SymbolLine[500 3000 1500 3000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[0 3500 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['r' 1200] +( + SymbolLine[500 3500 500 5000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[1000 3000 2000 3000 800] + SymbolLine[0 3000 500 3500 800] +) +Symbol['s' 1200] +( + SymbolLine[500 5000 2000 5000 800] + SymbolLine[2000 5000 2500 4500 800] + SymbolLine[2000 4000 2500 4500 800] + SymbolLine[500 4000 2000 4000 800] + SymbolLine[0 3500 500 4000 800] + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 2000 3000 800] + SymbolLine[2000 3000 2500 3500 800] + SymbolLine[0 4500 500 5000 800] +) +Symbol['t' 1000] +( + SymbolLine[500 1000 500 4500 800] + SymbolLine[500 4500 1000 5000 800] + SymbolLine[0 2500 1000 2500 800] +) +Symbol['u' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] + SymbolLine[2000 3000 2000 4500 800] +) +Symbol['v' 1200] +( + SymbolLine[0 3000 1000 5000 800] + SymbolLine[2000 3000 1000 5000 800] +) +Symbol['w' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[500 5000 1000 5000 800] + SymbolLine[1000 5000 1500 4500 800] + SymbolLine[1500 3000 1500 4500 800] + SymbolLine[1500 4500 2000 5000 800] + SymbolLine[2000 5000 2500 5000 800] + SymbolLine[2500 5000 3000 4500 800] + SymbolLine[3000 3000 3000 4500 800] +) +Symbol['x' 1200] +( + SymbolLine[0 3000 2000 5000 800] + SymbolLine[0 5000 2000 3000 800] +) +Symbol['y' 1200] +( + SymbolLine[0 3000 0 4500 800] + SymbolLine[0 4500 500 5000 800] + SymbolLine[2000 3000 2000 6000 800] + SymbolLine[1500 6500 2000 6000 800] + SymbolLine[500 6500 1500 6500 800] + SymbolLine[0 6000 500 6500 800] + SymbolLine[500 5000 1500 5000 800] + SymbolLine[1500 5000 2000 4500 800] +) +Symbol['z' 1200] +( + SymbolLine[0 3000 2000 3000 800] + SymbolLine[0 5000 2000 3000 800] + SymbolLine[0 5000 2000 5000 800] +) +Symbol['{' 1200] +( + SymbolLine[500 1500 1000 1000 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[0 3000 500 2500 800] + SymbolLine[0 3000 500 3500 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[500 4500 1000 5000 800] +) +Symbol['|' 1200] +( + SymbolLine[0 1000 0 5000 800] +) +Symbol['}' 1200] +( + SymbolLine[0 1000 500 1500 800] + SymbolLine[500 1500 500 2500 800] + SymbolLine[500 2500 1000 3000 800] + SymbolLine[500 3500 1000 3000 800] + SymbolLine[500 3500 500 4500 800] + SymbolLine[0 5000 500 4500 800] +) +Symbol['~' 1200] +( + SymbolLine[0 3500 500 3000 800] + SymbolLine[500 3000 1000 3000 800] + SymbolLine[1000 3000 1500 3500 800] + SymbolLine[1500 3500 2000 3500 800] + SymbolLine[2000 3500 2500 3000 800] +) +Attribute("PCB::grid::unit" "mil") +Via[220000 170000 7874 4000 0 3150 "" ""] + +Element["" "Power IC, as in MULTIWATT15" "" "HEPTAWATT" 143900 45000 -19900 -41500 0 100 ""] +( + Pin[6100 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[-13900 -5000 9000 3000 9600 6000 "2" "2" ""] + Pin[6100 -10000 9000 3000 9600 6000 "3" "3" ""] + Pin[-13900 -15000 9000 3000 9600 6000 "4" "4" ""] + Pin[6100 -20000 9000 3000 9600 6000 "5" "5" ""] + Pin[-13900 -25000 9000 3000 9600 6000 "6" "6" ""] + Pin[6100 -30000 9000 3000 9600 6000 "7" "7" ""] + ElementLine [-24900 5400 -6000 5400 2000] + ElementLine [-6000 -35500 -6000 5400 2000] + ElementLine [-24900 -35500 -6000 -35500 2000] + ElementLine [-24900 -35500 -24900 5400 2000] + ElementLine [-19900 -35500 -19900 5400 1000] + ElementLine [-24900 -7500 -19900 -7500 1000] + ElementLine [-24900 -22500 -19900 -22500 1000] + + ) + +Element["" "Power IC, as in MULTIWATT15" "" "MULTIWATT11" 20000 38000 79500 -21000 3 100 ""] +( + Pin[0 12000 9000 3000 9600 6000 "1" "1" "square,edge2"] + Pin[6700 -8000 9000 3000 9600 6000 "2" "2" "edge2"] + Pin[13400 12000 9000 3000 9600 6000 "3" "3" "edge2"] + Pin[20100 -8000 9000 3000 9600 6000 "4" "4" "edge2"] + Pin[26800 12000 9000 3000 9600 6000 "5" "5" "edge2"] + Pin[33500 -8000 9000 3000 9600 6000 "6" "6" "edge2"] + Pin[40200 12000 9000 3000 9600 6000 "7" "7" "edge2"] + Pin[46900 -8000 9000 3000 9600 6000 "8" "8" "edge2"] + Pin[53600 12000 9000 3000 9600 6000 "9" "9" "edge2"] + Pin[60300 -8000 9000 3000 9600 6000 "10" "10" "edge2"] + Pin[67000 12000 9000 3000 9600 6000 "11" "11" "edge2"] + ElementLine [-6500 -26000 -6500 -6000 2000] + ElementLine [-6500 -6000 73500 -6000 2000] + ElementLine [73500 -6000 73500 -26000 2000] + ElementLine [73500 -26000 -6500 -26000 2000] + ElementLine [-6500 -21000 73500 -21000 1000] + ElementLine [26000 -26000 26000 -21000 1000] + ElementLine [41000 -26000 41000 -21000 1000] + + ) + +Element["" "Power IC, as in MULTIWATT15" "" "MULTIWATT15" 20000 98000 81000 -21000 3 100 ""] +( + Pin[0 12000 9000 3000 9600 6000 "1" "1" "square,edge2"] + Pin[5000 -8000 9000 3000 9600 6000 "2" "2" "edge2"] + Pin[10000 12000 9000 3000 9600 6000 "3" "3" "edge2"] + Pin[15000 -8000 9000 3000 9600 6000 "4" "4" "edge2"] + Pin[20000 12000 9000 3000 9600 6000 "5" "5" "edge2"] + Pin[25000 -8000 9000 3000 9600 6000 "6" "6" "edge2"] + Pin[30000 12000 9000 3000 9600 6000 "7" "7" "edge2"] + Pin[35000 -8000 9000 3000 9600 6000 "8" "8" "edge2"] + Pin[40000 12000 9000 3000 9600 6000 "9" "9" "edge2"] + Pin[45000 -8000 9000 3000 9600 6000 "10" "10" "edge2"] + Pin[50000 12000 9000 3000 9600 6000 "11" "11" "edge2"] + Pin[55000 -8000 9000 3000 9600 6000 "12" "12" "edge2"] + Pin[60000 12000 9000 3000 9600 6000 "13" "13" "edge2"] + Pin[65000 -8000 9000 3000 9600 6000 "14" "14" "edge2"] + Pin[70000 12000 9000 3000 9600 6000 "15" "15" "edge2"] + ElementLine [-5000 -26000 -5000 -6000 2000] + ElementLine [-5000 -6000 75000 -6000 2000] + ElementLine [75000 -6000 75000 -26000 2000] + ElementLine [75000 -26000 -5000 -26000 2000] + ElementLine [-5000 -21000 75000 -21000 1000] + ElementLine [27500 -26000 27500 -21000 1000] + ElementLine [42500 -26000 42500 -21000 1000] + + ) + +Element["" "Power IC, as in MULTIWATT15" "" "MULTIWATT8" 20000 164500 81000 -21000 3 100 ""] +( + Pin[0 -14500 9000 3000 9600 6000 "1" "1" "square,edge2"] + Pin[10000 -14500 9000 3000 9600 6000 "2" "2" "edge2"] + Pin[20000 -14500 9000 3000 9600 6000 "3" "3" "edge2"] + Pin[30000 -14500 9000 3000 9600 6000 "4" "4" "edge2"] + Pin[40000 -14500 9000 3000 9600 6000 "5" "5" "edge2"] + Pin[50000 -14500 9000 3000 9600 6000 "6" "6" "edge2"] + Pin[60000 -14500 9000 3000 9600 6000 "7" "7" "edge2"] + Pin[70000 -14500 9000 3000 9600 6000 "8" "8" "edge2"] + ElementLine [-5000 -26000 -5000 -6000 2000] + ElementLine [-5000 -6000 75000 -6000 2000] + ElementLine [75000 -6000 75000 -26000 2000] + ElementLine [75000 -26000 -5000 -26000 2000] + ElementLine [-5000 -21000 75000 -21000 1000] + ElementLine [27500 -26000 27500 -21000 1000] + ElementLine [42500 -26000 42500 -21000 1000] + + ) + +Element["" "Crystal oscillator" "" "OSC14" 130000 110000 20000 -17000 0 100 ""] +( + Pin[0 0 5000 3000 5600 2800 "NC" "1" "edge2"] + Pin[60000 0 5000 3000 5600 2800 "GND" "2" "edge2"] + Pin[60000 -30000 5000 3000 5600 2800 "CLK" "3" "edge2"] + Pin[0 -30000 5000 3000 5600 2800 "VCC" "4" "edge2"] + ElementLine [-9500 -30000 -9500 9500 1000] + ElementLine [0 -39500 60000 -39500 1000] + ElementLine [69500 -30000 69500 0 1000] + ElementLine [-9500 9500 60000 9500 1000] + ElementLine [-4000 -30000 -4000 0 1000] + ElementLine [0 -34000 60000 -34000 1000] + ElementLine [64000 -30000 64000 0 1000] + ElementLine [0 4000 60000 4000 1000] + ElementArc [0 -30000 9500 9500 270 90 1000] + ElementArc [60000 -30000 9500 9500 180 90 1000] + ElementArc [60000 0 9500 9500 90 90 1000] + ElementArc [0 -30000 4000 4000 270 90 1000] + ElementArc [60000 -30000 4000 4000 180 90 1000] + ElementArc [60000 0 4000 4000 90 90 1000] + ElementArc [0 0 4000 4000 0 90 1000] + + ) + +Element["" "Power IC, as in MULTIWATT15" "" "PENTAWATT" 197200 46700 -19900 -39900 0 100 ""] +( + Pin[8500 0 9000 3000 9600 6000 "1" "1" "square"] + Pin[-7200 -6700 9000 3000 9600 6000 "2" "2" ""] + Pin[8500 -13400 9000 3000 9600 6000 "3" "3" ""] + Pin[-7200 -20100 9000 3000 9600 6000 "4" "4" ""] + Pin[8500 -26800 9000 3000 9600 6000 "5" "5" ""] + ElementLine [-24900 7000 -6000 7000 2000] + ElementLine [-6000 -33900 -6000 7000 2000] + ElementLine [-24900 -33900 -6000 -33900 2000] + ElementLine [-24900 -33900 -24900 7000 2000] + ElementLine [-19900 -33900 -19900 7000 1000] + ElementLine [-24900 -5900 -19900 -5900 1000] + ElementLine [-24900 -20900 -19900 -20900 1000] + + ) + +Element["" "" "" "" 160000 150000 -12500 -9000 0 100 ""] +( + Pin[13091 9000 9000 5000 9600 3937 "" "4" "edge2,intconn(2)"] + Pin[-12500 9000 9000 5000 9600 3937 "" "3" "edge2,intconn(2)"] + Pin[13091 -9000 9000 5000 9600 3937 "" "2" "edge2,intconn(1)"] + Pin[-12500 -9000 9000 5000 9600 3937 "" "1" "edge2,intconn(1)"] + ElementLine [12181 11736 12181 -11886 787] + ElementLine [-11441 11736 12181 11736 787] + ElementLine [-11441 -11886 -11441 11736 787] + ElementLine [-11441 -11886 12181 -11886 787] + ElementArc [7815 -8031 2756 2756 90 90 787] + ElementArc [7815 -8031 2756 2756 0 90 787] + ElementArc [7815 -8031 2756 2756 270 90 787] + ElementArc [7815 -8031 2756 2756 180 90 787] + ElementArc [7815 7717 2756 2756 0 90 787] + ElementArc [7815 7717 2756 2756 270 90 787] + ElementArc [7815 7717 2756 2756 180 90 787] + ElementArc [7815 7717 2756 2756 90 90 787] + ElementArc [-7933 7717 2756 2756 270 90 787] + ElementArc [-7933 7717 2756 2756 180 90 787] + ElementArc [-7933 7717 2756 2756 90 90 787] + ElementArc [-7933 7717 2756 2756 0 90 787] + ElementArc [-7933 -8031 2756 2756 180 90 787] + ElementArc [-7933 -8031 2756 2756 90 90 787] + ElementArc [-7933 -8031 2756 2756 0 90 787] + ElementArc [-7933 -8031 2756 2756 270 90 787] + ElementArc [-59 -157 6693 6693 270 90 787] + ElementArc [-59 -157 6693 6693 180 90 787] + ElementArc [-59 -157 6693 6693 90 90 787] + ElementArc [-59 -157 6693 6693 0 90 787] + + ) +Layer(1 "component") +( +) +Layer(2 "solder") +( +) +Layer(3 "comp-GND") +( +) +Layer(4 "comp-power") +( +) +Layer(5 "sold-GND") +( +) +Layer(6 "sold-power") +( +) +Layer(7 "signal3") +( +) +Layer(8 "outline") +( +) +Layer(9 "silk") +( +) +Layer(10 "silk") +( +) Index: tags/2.3.0/util/pcblib-param.cgi =================================================================== --- tags/2.3.0/util/pcblib-param.cgi (nonexistent) +++ tags/2.3.0/util/pcblib-param.cgi (revision 33253) @@ -0,0 +1,483 @@ +#!/bin/bash + +ulimit -t 5 +ulimit -v 80000 + +export HOME=/tmp +cd /tmp + +# read the config +. /etc/pcblib.cgi.conf +CGI=$CGI_param + +# import the lib +. $pcb_rnd_util/cgi_common.sh + + +gen() +{ + cd $gendir + ./$gen "$fp_params" +} + +help_params() +{ +awk -v "CGI=$CGI" "$@" ' +BEGIN { + prm=0 + q="\"" + fp_base=fp + sub("[(].*", "", fp_base) + thumbsize=1 +} + +function urlencode(s) +{ + gsub("[#]", "%23", s) + return s +} + +function proc_include(fn) +{ + close(fn) + while(getline < fn) + proc_line() + close(fn) +} + +function proc_line() +{ + if (/^[^\"]*@@include/) { + proc_include(gendir $2) + return + } + + if ((match($0, "@@desc") || match($0, "@@params") || match($0, "@@purpose") || match($0, "@@example"))) { + txt=$0 + key=substr($0, RSTART, RLENGTH) + sub(".*" key "[ \t]*", "", txt) + HELP[key] = HELP[key] " " txt + next + } + + if (/@@thumbsize/) { + sub(".*@@thumbsize", "", $0) + if ($1 ~ ":") { + sub("^:", "", $1) + PDATA[$1,"thumbsize"] = $2 + } + else + thumbsize=$1 + return + } + + if (/@@thumbnum/) { + sub(".*@@thumbnum", "", $0) + if ($1 ~ ":") { + sub("^:", "", $1) + PDATA[$1,"thumbnum"] = $2 + } + return + } + + if (/@@param:/) { + sub(".*@@param:", "", $0) + p=$1 + sub(p "[\t ]*", "", $0) + PARAM[prm] = p + PDESC[prm] = $0 + prm++ + return + } + +# build PPROP[paramname,propname], e.g. PPROP[pin_mask, dim]=1 + if (/@@optional:/ || /@@dim:/ || /@@bool:/) { + key = $0 + sub("^.*@@", "", key) + val = key + sub(":.*", "", key) + sub("^[^:]*:", "", val) + PPROP[val,key] = 1 + return + } + +# build PDATA[paramname,propname], e.g. PDATA[pin_mask, default]=123 + if ((/@@default:/) || (/@@preview_args:/)) { + key = $1 + + txt = $0 + txt = substr(txt, length(key)+1, length(txt)) + sub("^[ \t]*", "", txt) + + sub("^.*@@", "", key) + val = key + sub(":.*", "", key) + sub("^[^:]*:", "", val) + PDATA[val,key] = txt + return + } + +# build: +# PDATAK[paramname,n]=key (name of the value) +# PDATAV[paramname,n]=description (of the given value) +# PDATAN[paramname]=n number of parameter values + if (/@@enum:/) { + key = $1 + + txt = $0 + txt = substr(txt, length(key)+1, length(txt)) + sub("^[ \t]*", "", txt) + + sub("^.*@@enum:", "", key) + val = key + sub(":.*", "", key) + sub("^[^:]*:", "", val) + idx = int(PDATAN[key]) + PDATAK[key,idx] = val + PDATAV[key,idx] = txt + PDATAN[key]++ + return + } +} + +{ proc_line() } + +function thumb(prv, gthumbsize, lthumbsize, thumbnum ,lnk,lnk_gen, thumbsize,ann) +{ + if (lthumbsize != "") + thumbsize = lthumbsize + else + thumbsize = gthumbsize + if (!thumbnum) + ann="&annotation=none" + lnk=q CGI "?cmd=" prv "&output=png&grid=none" ann "&thumb=" thumbsize q + lnk_gen=q CGI "?cmd=" prv q + print "" + print "" + print "" +} + +END { + if (header) { + print "" HELP["@@purpose"] "" + print "

" + print HELP["@@desc"] + } + + if (content) + print "

" content "

" + + if ((print_params) && (HELP["@@params"] != "")) + print "

Ordered list (positions): " HELP["@@params"] + + + if (content) { + print "" + print "
name man
dat
ory
description value (bold: default)" + for(p = 0; p < prm; p++) { + name=PARAM[p] + print "
" name + if (PPROP[name, "optional"]) + print "  " + else + print " yes" + print "" PDESC[p] + print "" + vdone=0 + if (PDATAN[name] > 0) { + print "" + for(v = 0; v < PDATAN[name]; v++) { + print "
" + isdef = (PDATA[name, "default"] == PDATAK[name, v]) + if (isdef) + print "" + print PDATAK[name, v] + if (isdef) + print "" + + print "" PDATAV[name, v] + if (PDATA[name, "preview_args"] != "") { + prv= fp_base "(" PDATA[name, "preview_args"] "," name "=" PDATAK[name, v] ")" + print "" + thumb(prv, thumbsize, PDATA[name, "thumbsize"], PDATA[name, "thumbnum"]) + } + } + print "
" + vdone++ + } + if (PPROP[name, "dim"]) { + print "Dimension: a number with an optional unit (mm or mil, default is mil)" + if (PDATA[name, "default"] != "") + print "
Default: " PDATA[name, "default"] "" + vdone++ + } + if (PPROP[name, "bool"]) { + print "Boolean: yes/no, true/false, 1/0" + if (PDATA[name, "default"] != "") + print "; Default: " PDATA[name, "default"] "" + if (PDATA[name, "preview_args"] != "") { + print "
" + print "" + print "
true:" + thumb(fp_base "(" PDATA[name, "preview_args"] "," name "=" 1 ")", thumbsize, PDATA[name, "thumbsize"], PDATA[name, "thumbnum"]) + print "false:" + thumb(fp_base "(" PDATA[name, "preview_args"] "," name "=" 0 ")", thumbsize, PDATA[name, "thumbsize"], PDATA[name, "thumbnum"]) + print "
" + } + } + if (!vdone) + print " " + } + print "
" + } + + if (footer) { + print "

Example

" + print "" + print HELP["@@example"] + print "" + print "" + } +} +' +} + +help() +{ + local incl n + echo " + + +

pcblib-param help for $QS_cmd()

+" + + incl=`tempfile` + + +# generate the table + help_params -v "fp=$QS_cmd" -v "header=1" -v "content=$gen parameters" -v "print_params=1" -v "gendir=$gendir" < $gendir/$gen + +# generate the footer + help_params -v "fp=$QS_cmd" -v "footer=1" -v "gendir=$gendir" < $gendir/$gen 2>/dev/null + +} + +list_gens() +{ + awk -v "CGI=$CGI" ' + BEGIN { + q="\"" + } + /@@purpose/ { + sub(".*@@purpose", "", $0) + PURPOSE[FILENAME] = PURPOSE[FILENAME] $0 + next + } + /@@example/ { + sub(".*@@example", "", $0) + EXAMPLE[FILENAME] = EXAMPLE[FILENAME] $0 + next + } + + /@@params/ { + sub(".*@@params", "", $0) + PARAMS[FILENAME] = PARAMS[FILENAME] $0 + next + } + + function urlencode(s) + { + gsub("[#]", "%23", s) + return s + } + + END { + for(fn in PURPOSE) { + gn=fn + sub(".*/", "", gn) + params=PARAMS[fn] + sub("^[ \t]*", "", params) + sub("[ \t]*$", "", params) + print "
  • " gn "(" params ") - " PURPOSE[fn] + print "- HELP " + } + } + ' $gendir/* +} + +qs=`echo "$QUERY_STRING" | tr "&" "\n"` + +for n in $qs +do + exp="QS_$n" + export $exp +done + +export QS_cmd=`echo "$QS_cmd" | url_decode` + +if test -z "$QS_cmd" +then + export QS_cmd='connector(2,3)' + gen=connector +else + gen=`awk -v "n=$QS_cmd" ' + BEGIN { + sub("[(].*", "", n) + gsub("[^a-zA-Z0-9_]", "", n) + print n + } + '` + + ptmp=`grep "@@purpose" $gendir/$gen` + if test -z "$ptmp" + then + error "Invalid generator \"$gen\" (file)" + fi +fi + + +if test "$QS_output" = "help" +then + echo "Content-type: text/html" + echo "" + help + exit +fi + +fp_params=`echo $QS_cmd | sed "s/.*[(]//;s/[)]//" ` +export fp_full="$gen($fp_params)" +fptext=`gen` +if test ! "$?" = 0 +then + echo "Content-type: text/plain" + echo "" + echo "Error generating the footprint:" + gen 2>&1 | grep -i error + exit +fi + +if test "$QS_output" = "text" +then + echo "Content-type: text/plain" + echo "" + gen + exit +fi + +if test "$QS_output" = "png" +then + cgi_png + exit +fi + +echo "Content-type: text/html" +echo "" + +echo "" +echo "" +echo "

    pcblib-param test page

    " +echo ' + + +
    + +"Do you remember the good old days? When I was +
    young, I said footprint=CONNECTOR 2 13 +
    in gschem and got a 2*13 pin connector in PCB."
    +
    + +
     
      +

    + + + +
    +

    Syntax

    +

    +In pcb-rnd, +automatic footprint generation on the fly is called "parametric +footprints". It is a smaller and more generic infrastructure compared +to the m4 footprints in pcb. The goal was to fix three problems. +

      +
    • 1. Languages: m4 should not be mandatory for footprint generators - the user should be free to choose any language +
    • 2. Simplicity: references to m4 should not be hardwired in pcb, gsch2pcb and gsch2pcb.scm, but footprint generation should be generic, transparent and external +
    • 3. Unambiguity: gsch2pcb should not be guessing whether to use file elements or call a generator. Instead of complex heuristics, there should be a simple, distinct syntax for parametric footprints. +
    +

    +The new syntax is that if a footprint attribute contains parenthesis, it is +a parametric footprint, else it is a file footprint. Parametric footprints +are sort of a function call. The actual syntax is similar to the one in + openscad : +parameters are separated by commas, and they are either positional (value) +or named (name=value). +

    +For example a simple pin-grid +connector has the "prototype" of connector(nx, ny, spacing), where +nx and ny are the number of pins needed in X and Y directions, spacing is +the distance between pin centers, with a default of 100 mil. The following +calls will output the same 2*3 pin, 100 mil footprint: +

      +
    • connector(2, 3) +
    • connector(2, 3, 100) +
    • connector(nx=2, ny=3, spacing=100) +
    • connector(spacing=100, nx=2, ny=3) +
    • connector(ny=3, spacing=100, nx=2) +
    + +
        + +

    Generators available

    +
      +' +list_gens +echo ' +
    +
    +' + + +echo "

    Try it online

    " +echo "source:" + +echo "
    " +echo "" +echo "
      " +echo "
    • draw grid in mm" +echo "
    • draw in \"photo mode\"" +echo "
    • annotate pin names" +echo "
    • annotate dimension names" +echo "
    • annotate dimension values (in grid units)" +#echo "
    • lighten annotataion background" +echo "
    " +echo "

    " +echo "" +echo "

    " + + + +QS_format=${QS_cmd##*_} +QS_cmd_=${QS_cmd%%_*} + +if test ! -z "$QS_cmd" +then +echo "

    Result

    " + echo "

    $QS_cmd

    " + + echo "" + echo "
    " + echo "" + + echo "     " + + echo "" + echo "
    "
    +	echo "$fptext"
    +	echo "
    " + echo "

    Downloads:" + echo "
    footprint file" + echo "

    " +fi + + +echo "" +echo "" Property changes on: tags/2.3.0/util/pcblib-param.cgi ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/pcblib-static.cgi =================================================================== --- tags/2.3.0/util/pcblib-static.cgi (nonexistent) +++ tags/2.3.0/util/pcblib-static.cgi (revision 33253) @@ -0,0 +1,239 @@ +#!/bin/bash + +ulimit -t 5 +ulimit -v 80000 + +export HOME=/tmp +cd /tmp + +# read the config +. /etc/pcblib.cgi.conf +CGI=$CGI_static + +# import the lib +. $pcb_rnd_util/cgi_common.sh + +find_fp() +{ + awk -v "fp=$QS_fp" -v "fpdir=$fpdir" ' + BEGIN { + fp=tolower(fp) + } + ($1 == "S") { + n=tolower($2) + sub("^.*/", "", n) + sub(".fp$", "", n) + sub(".ele$", "", n) + if (n == fp) { + print fpdir $2 + exit + } + } + ' < $sdir/cache +} + +list_fps() +{ + find $fpdir | awk -v "fpdir=$fpdir" -v "CGI=$CGI" ' + /.svn/ { next } + /parametric/ { next } + + { + name=$0 + sub(fpdir, "", name) + if (!(name ~ "/")) + next + dir=name + fn=name + sub("/.*", "", dir) + sub("^[^/]*/", "", fn) + vfn = fn + sub(".fp$", "", vfn) + + LLEN[dir] += length(vfn) + + vfn = "" vfn "" + + if (LLEN[dir] > 8) { + LLEN[dir] = 0 + sep = "
    " + } + else + sep = " " + if (DIR[dir] != "") + DIR[dir] = DIR[dir] sep vfn + else + DIR[dir] = vfn + } + + END { + print "" + print "" + for(n in DIR) + print "" + for(n in DIR) + print "
    " n + print "
    " DIR[n] + print "
    " + } + ' +} + +qs=`echo "$QUERY_STRING" | tr "&" "\n"` + +for n in $qs +do + exp="QS_$n" + export $exp +done + +export QS_cmd=`echo "$QS_cmd" | url_decode` + +if test -z "$QS_fp" +then + export QS_fp='TO220' + gen=connector +fi + +fn=`find_fp` +if test ! "$?" = 0 +then + echo "Content-type: text/plain" + echo "" + echo "Error: couldn't find $QS_fp" + exit +fi + +fptext=`cat $fn` +if test ! "$?" = 0 +then + echo "Content-type: text/plain" + echo "" + echo "Error reading footprint file for $QS_fp $fn" + exit +fi + +if test "$QS_output" = "text" +then + echo "Content-type: text/plain" + echo "" + echo "$fptext" + exit +fi + +if test "$QS_output" = "png" +then + echo "Content-type: image/png" + echo "" + cparm="" + if test ! -z "$QS_mm" + then + cparm="$cparm --mm" + fi + if test ! -z "$QS_photo" + then + cparm="$cparm --photo" + fi + + fptmp=`mktemp` + $fp2preview --outfile $fptmp $cparm "$QS_fp" >/dev/null 2>&1 + cat $fptmp + rm $fptmp + + exit +fi + +echo "Content-type: text/html" +echo "" + +echo "" +echo "" +echo "

    pcblib-static browse page

    " +echo ' + + +
    + +An outburst while looking for a powerjack connector
    +footprint in the stock library:
    +"What on earth is an MSP430F1121 footprint and
    +why do I need it in the default library?!"
    +
    + +
     
      +

    + + + +
    +

    pcblib

    +

    +The default library in pcb-rnd +is called the "pcblib" (lib and newlib are already used by vanilla pcb). +Pcblib content consists of +parametric (generated) footprints +and static footprints ("file elements"). This page queries static footprints. +

    +The goal of pcblib is to ship a minimalistic library of the real essential +parts, targeting small projects and hobbysts. Pcblib assumes users can +grow their own library by downloading footprints from various online sources +(e.g. gedasymbols) or draw their own +as needed. Thus instead of trying to be a complete collection of footprints +ever drawn, it tries to collect the common base so that it is likely that 90% +of pcblib users will use 90% of the footprints in their projects. + +

        + +

    List of static footprints

    +
      +' + + +list_fps + +echo ' +
    +
    +' + + +echo "

    Search and preview

    " + +echo "
    " +echo "name: " +echo "
      " +echo "
    • draw grid in mm" +echo "
    • draw in \"photo mode\"" +echo "
    " +echo "

    " +echo "" +echo "

    " + + + +QS_format=${QS_cmd##*_} +QS_fp_=${QS_cmd%%_*} + +if test ! -z "$QS_fp" +then +echo "

    Result

    " + echo "

    $QS_fp

    " + + echo "" + echo "
    " + echo "" + + echo "     " + + echo "" + echo "
    "
    +	echo "$fptext"
    +	echo "
    " + echo "

    Downloads:" + echo "
    footprint file" + echo "

    " +fi + + +echo "" +echo "" Property changes on: tags/2.3.0/util/pcblib-static.cgi ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/pcblib.cgi.conf =================================================================== --- tags/2.3.0/util/pcblib.cgi.conf (nonexistent) +++ tags/2.3.0/util/pcblib.cgi.conf (revision 33253) @@ -0,0 +1,31 @@ +# shell syntax + +### change these to reflect your installation ### + +# absolute path to the trunk directory of the pcb-rnd checkout from +# svn://repo.hu/pcb-rnd/trunk +pcb_rnd_trunk=/home/igor2/C/pcb-rnd + +# CGI url to use for self-reference when generating html pages; +# this should be a relative URL +CGI_param=/cgi-bin/pcblib-param.cgi +CGI_static=/cgi-bin/pcblib-static.cgi + +# pcblib-static.cgi: absolute path to the map directory that is put +# online (svn://repo.hu/pcb-rnd/trunk/util/pcblib-map) +# NOTE: run make there after the checkout or an update +sdir=/var/www/tmp/pcblib + +### these are less likely to change ### + +# absolute path to util/ under the trunk checkout +pcb_rnd_util=$pcb_rnd_trunk/util + +# absolute path to the footprint generators - has to end with / +gendir=$pcb_rnd_trunk/pcblib/parametric/ + +# absolute path to the root of the static footprint tree - has to end with / +fpdir=$pcb_rnd_trunk/pcblib/ + +# absolute path to the fp2preview script +fp2preview=$pcb_rnd_util/fp2preview Property changes on: tags/2.3.0/util/pcblib.cgi.conf ___________________________________________________________________ Added: svn:mergeinfo ## -0,0 +0,0 ## Index: tags/2.3.0/util/sign/crl_repo.hu.pem =================================================================== --- tags/2.3.0/util/sign/crl_repo.hu.pem (nonexistent) +++ tags/2.3.0/util/sign/crl_repo.hu.pem (revision 33253) @@ -0,0 +1,19 @@ +-----BEGIN X509 CRL----- +MIIDGzCCAQMwDQYJKoZIhvcNAQELBQAwgb0xCzAJBgNVBAYTAkhVMREwDwYDVQQI +EwhCdWRhcGVzdDERMA8GA1UEBxMIQnVkYXBlc3QxEDAOBgNVBAoTB3JlcG8uaHUx +DjAMBgNVBAsTBUlnb3IyMRMwEQYDVQQDEwpyZXBvLmh1IENBMSwwKgYDVQQpEyNy +ZXBvLmh1IHB1YmxpYyBzc2wgYW5kIGZpbGUgc2lnbmluZzEjMCEGCSqGSIb3DQEJ +ARYUa2V5aW5nQGlnb3IyLnJlcG8uaHUXDTIwMDQyMTE1Mzk0M1oXDTIwMDUyMTE1 +Mzk0M1owFDASAgEBFw0yMDA0MjExNTM5NDNaMA0GCSqGSIb3DQEBCwUAA4ICAQDI +m21vna5oUWP+H0S5bH7sGvOa3B5akETXTtieUx2+9+RCGaqnlnGYqHD6kgxNj4ly +w6i8KNAHUFRHZGPis5GwEBkQE45FtQDm9ycQ/DJoR4uZ/wiwUz7iC2jf2D6oaqS5 +8efc2qIjPOc/HIHOcsyE98M6P9ch+XvsXL2dzvE1i/HJ6ETHk1S1rcpBvfP4SyeO +7Me5MTYb5XT8Rxl1xVcKSeji90vMZt+byO3JVyUlzzaAr5bD+2HO+v+MDOAlnfQ1 +y8KW1/v3tztt1YQB4vpqtidE0+jVuIj6nQEvjckKQhoxMnJActPDqmPb+TS+UDhq +QIt6T5ynC1JhqrnowS5C4WwmwQfUZwyDF+rTtPgWoe+XDWiGvo4xyWqMECsESTeX +tuNxBLbfaVlMHE4/10KdjeqtiJbvOXuXoPtkiWF/5+259vT/ZWBy+0KJZL/F1kh7 +hpt9x8S089DBJ7ZoStOAmZQpA5rkklvf4hLpMJwy0mWdOQ/nnHG/LlggOjPDSa2u +roVx7n1RknPuMlQz+YR7xhZ4ftwBNXXGC3qskpkNKu71k8mvvntt+BcFQdC1LTiT +VoNfB+cLW+UL+KawGBogv7gPiMY1NG+OtEzpd4e7quuliyAMsnq6T7AKz+FJMaMd +0Bd7sOPgntpk3gjfPtLa0IyC7CnP3bPdHlr9RrPBFQ== +-----END X509 CRL----- Index: tags/2.3.0/util/sign/rootca_repo.hu_2020.crt =================================================================== --- tags/2.3.0/util/sign/rootca_repo.hu_2020.crt (nonexistent) +++ tags/2.3.0/util/sign/rootca_repo.hu_2020.crt (revision 33253) @@ -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/2.3.0/util/sign/sign.sh =================================================================== --- tags/2.3.0/util/sign/sign.sh (nonexistent) +++ tags/2.3.0/util/sign/sign.sh (revision 33253) @@ -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/2.3.0/util/sign/sign.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: tags/2.3.0/util/sign/verify.sh =================================================================== --- tags/2.3.0/util/sign/verify.sh (nonexistent) +++ tags/2.3.0/util/sign/verify.sh (revision 33253) @@ -0,0 +1,113 @@ +#!/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 +} + +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";; + *) + 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/2.3.0/util/sign/verify.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property